Check in hsqldb 2.0.0

My changes:
 - Copied docs/hypersonic_lic.txt to LICENSE.TXT
 - Created Android.mk

Change-Id: Ib323babdd1057944aa65eaa4e86e89331931b550
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..e749b5e
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := hsqldb-2.0.0
+LOCAL_MODULE_TAGS := optional
+LOCAL_IS_HOST_MODULE := true
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := hsqldb-2.0.0:lib/hsqldb.jar
+
+include $(BUILD_MULTI_PREBUILT)
+
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..1e674ea
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,70 @@
+/*

+ * For work developed by the HSQL Development Group:

+ *

+ * Copyright (c) 2001-2010, The HSQL Development Group

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * Redistributions of source code must retain the above copyright notice, this

+ * list of conditions and the following disclaimer.

+ *

+ * Redistributions in binary form must reproduce the above copyright notice,

+ * this list of conditions and the following disclaimer in the documentation

+ * and/or other materials provided with the distribution.

+ *

+ * Neither the name of the HSQL Development Group nor the names of its

+ * contributors may be used to endorse or promote products derived from this

+ * software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,

+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ *

+ *

+ * For work originally developed by the Hypersonic SQL Group:

+ *

+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * Redistributions of source code must retain the above copyright notice, this

+ * list of conditions and the following disclaimer.

+ *

+ * Redistributions in binary form must reproduce the above copyright notice,

+ * this list of conditions and the following disclaimer in the documentation

+ * and/or other materials provided with the distribution.

+ *

+ * Neither the name of the Hypersonic SQL Group nor the names of its

+ * contributors may be used to endorse or promote products derived from this

+ * software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,

+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This software consists of voluntary contributions made by many individuals

+ * on behalf of the Hypersonic SQL Group.

+ */

+

+

diff --git a/bin/localhost_clientserver.html b/bin/localhost_clientserver.html
new file mode 100644
index 0000000..4168202
--- /dev/null
+++ b/bin/localhost_clientserver.html
@@ -0,0 +1,33 @@
+<html>
+<head><title>HSQL Database Engine</title></head>
+<body bgcolor=#FFFFFF>
+<h2>HSQL Database Engine Client/Server Demo</h2>
+<applet code="org.hsqldb.util.QueryTool" archive="hsqldb.jar" width="460" height="400" codebase="../lib/">
+<param name="database" value="http://localhost">
+</applet>
+
+<h3>Client/server version</h3>
+Currently, the applet is configured to connect to 'http://localhost',
+but this can be changed in the source code of this HTML page:
+The applet parameter 'database' is the path where the applet connects to.
+Close the database and stop the WebServer using the 'SHUTDOWN' command.
+<p>
+<h2>If it does not work</h2>
+On some browsers (Netscape 4.6?), the version compiled for
+JDK 1.2 does not work. In the Java Console (Communicator
+/ Extras / Java Console) you will get something like:
+<p>
+# Verifier error org/hsqldb/jdbcConnection.getTypeMap()Ljava/util/Map
+<p>
+This means the class java.util.Map was not found. In JDK 1.1,
+this class does not exist. When compiled for 1.2, there is
+a reference this class required to conform the JDBC 2.0 interface.
+This class itself is never used, but the reference is required anyway.
+It looks like most verifiers have no problem with this, but some
+have.
+<p>
+The (only) solution for this problem is to recompile (at least the
+client part) for JDK 1.1. You will need to install JDK 1.1 before
+you can do this, then see:
+<p><a href="doc/hsqlBuild.html">Build / How to switch to JDK 1.1</a>
+</body></html>
diff --git a/bin/memorydbmanager.html b/bin/memorydbmanager.html
new file mode 100644
index 0000000..ea688dd
--- /dev/null
+++ b/bin/memorydbmanager.html
@@ -0,0 +1,28 @@
+<html>
+<head><title>HSQL Database Engine</title></head>
+<body bgcolor=#FFFFFF>
+<h2>In-Memory Applet: Database Manager</h2>
+<applet code="org.hsqldb.util.DatabaseManager" archive="hsqldb.jar" width="0" height="0" codebase="../lib/">
+<param name="database" value=".">
+</applet>
+<p>
+In this demo, all data is kept in memory.<br>
+The data will be lost if the program is closed.<br>
+The Database Manager and the database are running<br>
+inside the internet browser.
+<p>
+<h2>If it does not work</h2>
+On some browsers (Netscape 4.6?), the version compiled for
+JDK 1.2 does not work. In the Java Console (Communicator
+/ Extras / Java Console) you will get something like:
+<p>
+# Verifier error org/hsqldb/jdbcConnection.getTypeMap()Ljava/util/Map
+<p> This means the class java.util.Map was not found. In JDK 1.1, this class does 
+  not exist. When compiled for 1.2, there is a reference to this class required 
+  to conform to the JDBC 2.0 interface. This class itself is never used, but the 
+  reference is required anyway. It looks like most verifiers have no problem with 
+  this, but some have. 
+<p> The solution for this problem is to recompile (at least the client part) for 
+  JDK 1.1. You will need to install JDK 1.1 before you can do this, then see: 
+<p><a href="doc/hsqlBuild.html">Build / How to switch to JDK 1.1</a>
+</body></html>
diff --git a/bin/memoryquery.html b/bin/memoryquery.html
new file mode 100644
index 0000000..d478953
--- /dev/null
+++ b/bin/memoryquery.html
@@ -0,0 +1,29 @@
+<html>
+<head><title>HSQL Database Engine</title></head>
+<body bgcolor=#FFFFFF>
+<h2>In-Memory Applet: QueryTool</h2>
+<applet code="org.hsqldb.util.QueryTool" archive="hsqldb.jar" width="460" height="400" codebase="../lib/">
+<param name="database" value=".">
+</applet>
+<p>
+<h2>Description</h2>
+In this demo, all data is kept in memory.<br>
+The data will be lost if the program is closed.<br>
+The QueryTool and the database are running<br>
+inside the internet browser.
+<p>
+<h2>If it does not work</h2>
+On some browsers (Netscape 4.6?), the version compiled for
+JDK 1.2 does not work. In the Java Console (Communicator
+/ Extras / Java Console) you will get something like:
+<p>
+# Verifier error org/hsqldb/jdbcConnection.getTypeMap()Ljava/util/Map
+<p> This means the class java.util.Map was not found. In JDK 1.1, this class does 
+  not exist. When compiled for 1.2, there is a reference to this class required 
+  to conform to the JDBC 2.0 interface. This class itself is never used, but the 
+  reference is required anyway. It looks like most verifiers have no problems 
+  with this, but some have. 
+<p> The solution for this problem is to recompile (at least the client part) for 
+  JDK 1.1. You will need to install JDK 1.1 before you can do this, then see: 
+<p><a href="doc/hsqlBuild.html">Build / How to switch to JDK 1.1</a>
+</body></html>
diff --git a/bin/runManager.bat b/bin/runManager.bat
new file mode 100755
index 0000000..d5d9a6c
--- /dev/null
+++ b/bin/runManager.bat
@@ -0,0 +1,2 @@
+cd ..\data

+@java -classpath ..\lib\hsqldb.jar org.hsqldb.util.DatabaseManager %1 %2 %3 %4 %5 %6 %7 %8 %9

diff --git a/bin/runManagerSwing.bat b/bin/runManagerSwing.bat
new file mode 100755
index 0000000..e79590b
--- /dev/null
+++ b/bin/runManagerSwing.bat
@@ -0,0 +1,2 @@
+cd ..\data

+@java -classpath ..\lib\hsqldb.jar org.hsqldb.util.DatabaseManagerSwing %1 %2 %3 %4 %5 %6 %7 %8 %9

diff --git a/bin/runServer.bat b/bin/runServer.bat
new file mode 100755
index 0000000..9a83ea3
--- /dev/null
+++ b/bin/runServer.bat
@@ -0,0 +1,2 @@
+cd ..\data

+@java -classpath ../lib/hsqldb.jar org.hsqldb.server.Server %1 %2 %3 %4 %5 %6 %7 %8 %9

diff --git a/bin/runUtil.bat b/bin/runUtil.bat
new file mode 100755
index 0000000..be87297
--- /dev/null
+++ b/bin/runUtil.bat
@@ -0,0 +1,2 @@
+cd ..\data

+@java -classpath ..\lib\hsqldb.jar org.hsqldb.util.%1 %2 %3 %4 %5 %6 %7 %8 %9

diff --git a/bin/runWebServer.bat b/bin/runWebServer.bat
new file mode 100755
index 0000000..211bfd7
--- /dev/null
+++ b/bin/runWebServer.bat
@@ -0,0 +1,2 @@
+cd ..\data

+@java -classpath ..\lib\hsqldb.jar org.hsqldb.WebServer %1 %2 %3 %4 %5 %6 %7 %8 %9

diff --git a/bin/servletdemo.html b/bin/servletdemo.html
new file mode 100644
index 0000000..4519832
--- /dev/null
+++ b/bin/servletdemo.html
@@ -0,0 +1,32 @@
+<html>
+<head><title>HSQL Database Engine</title></head>
+<body bgcolor=#FFFFFF>
+<h2>HSQL Database Engine Servlet Demo</h2>
+<applet code="org.hsqldb.util.QueryTool" archive="hsqldb.jar" width="460" height="400" codebase="../lib/">
+<param name="database" value="http://localhost:8080/examples/servlet/hsqlServlet">
+</applet>
+<p>
+In this demo, the DatabaseManager uses the Servlet to access the database. The QueryTool is running inside
+the internet browser as an Applet.
+<p>
+<h2>If it does not work</h2>
+<p>This demo requires a servlet engine to be running and listening to port 8080. The hsqlServlet.java servlet should be installed on the servlet engine in the /examples/servlet/ directory.</p>
+<p>On some browsers (Netscape 4.6?), the version compiled for
+JDK 1.2 does not work. In the Java Console (Communicator
+/ Extras / Java Console) you will get something like:
+</p>
+<p>
+# Verifier error org/hsqldb/jdbcConnection.getTypeMap()Ljava/util/Map
+<p>
+This means the class java.util.Map was not found. In JDK 1.1,
+this class does not exist. When compiled for 1.2, there is
+a reference this class required to conform the JDBC 2.0 interface.
+This class itself is never used, but the reference is required anyway.
+It looks like most verifiers have no problem with this, but some
+have.
+<p>
+The (only) solution for this problem is to recompile (at least the
+client part) for JDK 1.1. You will need to install JDK 1.1 before
+you can do this, then see:
+<p><a href="../doc/build.html">Build / How to switch to JDK 1.1</a>
+</body></html>
diff --git a/build/build-dist.xml b/build/build-dist.xml
new file mode 100644
index 0000000..6fa60c1
--- /dev/null
+++ b/build/build-dist.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0"?>
+<project name="hsqldb-dist" default="dist" basedir="..">
+<!--
+$Id: build-dist.xml 3550 2010-03-19 17:45:16Z unsaved $
+-->
+
+<!--
+     This build file is separate from the main build.xml file specifically
+     because it is not intended for normal end-user or developer usage.
+     It is only for generating full distributable packages of the app.
+     This build file is NOT necessary to build a distributable jar file:
+     that is the purpose of several targets in the main build file.
+
+     PREP:  Before building a public distribution, you must:
+        1: Update property 'hsqldb.version' in file 'build.xml'.
+        2: Execute target 'refresh-verbatim' to update code in our docs.
+        3: Execute target 'update-readme' to substitute updated variables into
+           some doc file(s).
+        4: Commit all of the work above.
+        5: Verify that docs build successfully.
+        6. Make a release tag.
+
+     USAGE:
+         1: Set up your desired build environment (Ant in search path,
+            JAVA_HOME set, etc.).
+         2: Do a Subversion export with the release tag to a NEW directory
+         3: If you don't have a .properties file set up for this purpose
+            already, then make one outside of this work area (so you can
+            archive it and/or re-use it for future distribution builds).
+            IMPORTANT QUIRK:  This file may not use ${} properties in values,
+            since that feature is incompatible with the "-propertyfile"
+            switch that we will use below.
+            This file must set Ant properties "build.label", "build.vendor",
+            "dbimage.path".  (See following section about optional properties).
+         4: Run
+                ant -propertyfile path/to/file.properties -f build-dist.xml
+            from the build directory.
+            If you don't have Ivy in your CLASSPATH, you will be instructed
+            how to satisfy that requirement.
+
+     OPTIONAL ANT PROPERTIS
+         To prevent Internet access for DocBook resources, set properties
+           nsstylebase.url, dbxirng.url, dbcentx.url in file
+           "local-docbook.properties" or "build.properties" (just depends on
+           whether you want to manage them separately from the primary
+           properties).  This decreases document build time by about 70%.
+           These values point to DocBook-privided resources that you should
+           be able to figure out between the property name and the usage of
+           them in the "build-docbook.xml" file.
+         Add settings for build.debug and build.optimize to change the default
+           compilation settings.
+
+     You could just put these settings into "build.properties", drop the
+     "-propertyfile" switch, and things would work correctly.  However, you are
+     advised to use a .properties file external to your export directory for
+     retension purposes.
+
+     You may add or edit some files without them being added to the
+     distribution that you build:  build/build.properties,
+     build/local*.properties, tmp/*, classes/*, dist/*.
+     (But, as just noted, you are advised against making
+     "build/build.properties").
+     If you don't know if something will have an effect on the distribution
+     you are building, then *don't do it*.
+     If you were to add a "todo.txt" file to the main or build directory;
+     or run "ant hsqldbtest", artifacts would be added to the distro.
+ -->
+
+  <import file="build.xml"/>
+
+  <target name="state-check"
+          description="Verifies that the current directory + Ant build env. are acceptable for building a distribution">
+    <available property="_svn.exists" file=".svn"/>
+    <fail if="_svn.exists"
+          message="You need to 'export' the project to build distro"/>
+
+    <condition property="_label.ok">
+      <equals arg1="${hsqldb.version}" arg2="${build.label}"/>
+    </condition>
+    <fail unless="_label.ok">Ant properties 'build.label' and 'hsqldb.version' must be equal.
+I suggest setting the value(s) in an external properties file and using the Ant
+"-propertyfile" switch.</fail>
+    <condition property="_vendor.ok">
+      <equals arg1="${hsqldb.vendor}" arg2="${build.vendor}"/>
+    </condition>
+    <fail unless="_vendor.ok">Ant properties 'build.vendor' and 'hsqldb.vendor' must be equal.
+I suggest setting the value(s) in an external properties file and using the Ant
+"-propertyfile" switch.</fail>
+
+    <copy file="doc-src/readme-template.txt" tofile="tmp/readme-generated.txt"
+          overwrite="true">
+      <filterchain>
+        <expandproperties/>
+        <tokenfilter>
+          <!-- Intention is to strip out all RCS keywords, since their values
+               would cause false positives for our file comparison below.  -->
+          <replaceregex pattern="\$[A-Z][a-z]+: .+? \$" flags="g"/>
+        </tokenfilter>
+      </filterchain>
+    </copy>
+    <copy file="readme.txt" tofile="tmp/readme-svn.txt" overwrite="true">
+      <filterchain>
+        <tokenfilter>
+          <!-- Intention is to strip out all RCS keywords, since their values
+               would cause false positives for our file comparison below.  -->
+          <replaceregex pattern="\$[A-Z][a-z]+: .+? \$" flags="g"/>
+        </tokenfilter>
+      </filterchain>
+    </copy>
+    <condition property="_readme.ok">
+      <filesmatch textfile="true"
+                  file1="tmp/readme-svn.txt" file2="tmp/readme-generated.txt"/>
+    </condition>
+    <fail unless="_readme.ok">The 'readme.txt' file in your Subversion export contains the wrong product
+version.  You should verify this.  If the version is indeed wrong, you should
+abort this export, commit an updated 'readme.txt' from a work area, then retag
+and re-export.</fail>
+  </target>
+
+  <target name="dist"
+          depends="state-check, clean-all, javadoc, gen-docs, hsqldb, sqltool"
+          description="Build joint binary + source distribution packages">
+    <mkdir dir="dist"/>
+    <property name="app.basedir" value="hsqldb-${hsqldb.version}"/>
+    
+    <!-- Enforce platform-independent EOL policies on items that will be
+         packed.  Generated docs and everything under classes/ already
+         have EOLs enforced.
+         To make maintenance easier, please order by srcdir, and put that
+         attribute first.  Much easier to find what you are interested this
+         way.
+    -->
+    <fixcrlf srcdir="."
+             preservelastmodified='true' eol="crlf" includes="*.txt"/>
+    <fixcrlf srcdir="." preservelastmodified='true' eol="lf" includes="*.html"/>
+    <fixcrlf srcdir="bin" preservelastmodified='true' eol="crlf"
+             includes="**/*.txt, **/*.bat, **/*.cmd"/>
+    <fixcrlf srcdir="bin" preservelastmodified='true' eol="lf"
+             encoding="UTF-8" includes="**/*.sh, **/*.bash, **/*.html"/>
+    <fixcrlf srcdir="build" preservelastmodified='true' eol="crlf"
+             includes="**/*.txt, **/*.bat, **/*.cmd"/>
+    <fixcrlf srcdir="build" preservelastmodified='true' eol="lf"
+             encoding="ISO-8859-1" includes="**/*.properties"/>
+    <fixcrlf srcdir="build" preservelastmodified='true' eol="lf"
+             encoding="UTF-8" includes="**/*.xml, **/*.list"/>
+    <!-- Docbook or XSLT adds &#13;s on Windows.  Remove them. -->
+    <replace dir="doc" includes="*/*.html" token="&amp;#13;"/>
+    <fixcrlf srcdir="doc-src" preservelastmodified='true' eol="lf"
+             encoding="ISO-8859-1" includes="**/*.properties"/>
+    <fixcrlf srcdir="doc-src" preservelastmodified='true' eol="crlf"
+             includes="**/*.txt"/>
+    <fixcrlf srcdir="doc-src" preservelastmodified='true' eol="lf"
+             encoding="UTF-8"
+             includes="**/*.cfg, **/*.css, **/*.ent, **/*.java, **/*.rc,
+                       **/*.sql, **/*.xml, **/*.html"/>
+    <fixcrlf srcdir="sample" preservelastmodified='true' eol="lf"
+             encoding="UTF-8" excludes="**/*.txt, **/*.properties"/>
+    <fixcrlf srcdir="sample" preservelastmodified='true' eol="crlf"
+             includes="**/*.txt"/>
+    <fixcrlf srcdir="sample" preservelastmodified='true' eol="lf"
+             encoding="ISO-8859-1" includes="**/*.properties"/>
+    <fixcrlf srcdir="src"
+             preservelastmodified='true' eol="lf" encoding="ISO-8859-1"
+             includes="**/*.properties, **/*.text"/>
+    <fixcrlf srcdir="src" preservelastmodified='true' eol="lf" encoding="UTF-8"
+             includes="**/*.flex, **/*.html, **/*.java"/>
+    <fixcrlf srcdir="stylesheets" preservelastmodified='true' eol="lf"
+             encoding="UTF-8"/>
+    <!-- Exclusing test-src from distros, for now
+    <fixcrlf srcdir="test-src"
+             preservelastmodified='true' eol="lf" encoding="ISO-8859-1"
+             includes="**/*.properties"/>
+    <fixcrlf srcdir="test-src" preservelastmodified='true' eol="lf"
+             encoding="UTF-8"
+             includes="**/*.java, **/*.dtd, **/*.ent, **/*.exp, **/*.inc,
+                       **/*.sql, **/*.src, **/*.xml"/>
+    -->
+
+    <fixcrlf srcdir="testrun" preservelastmodified='true' eol="lf"
+             encoding="UTF-8" includes="**/*.bash"/>
+    <fixcrlf srcdir="testrun" preservelastmodified='true' eol="crlf"
+             includes="**/*.txt"/>
+    <!-- NOTE:  The file testrun/hsqldb/TestSelf.txt has something in it that
+         causes any Ant filter (on UNIX) to corrupt an umlauted character.
+         The problem is not with the umlauted character, but is the side-effect
+         of something else in the file.  I can pull the umlauted "Zürich"
+         string out of that file and put it into its own UTF-8 file, and Ant
+         can filter that just fine. -->
+    <fixcrlf srcdir="testrun"
+             preservelastmodified='true' eol="lf" encoding="UTF-8"
+             includes="**/*.sql, **/*.dsv, **/*.isql, **/*.nsql, **/*.inter"/>
+
+    <mkdir dir="data"/>
+    <zip destfile="dist/${app.basedir}.zip">
+      <zipfileset prefix="${app.basedir}/hsqldb" dir="."
+                  includes="**/*.cmd, **/*.bat, **/*.bash, **/*.sh, **/*.pl,
+                            **/*.php, **/*.init, **/*.py"
+                  filemode="0755"
+                  excludes="**/.*, build/local**, test-src/**
+                            classes/**, dist/**, local*/**, tmp/**"/>
+      <zipfileset prefix="${app.basedir}/hsqldb" dir="."
+                  excludes="**/.*, **/*.cmd, **/*.bat, **/*.bash, **/*.sh,
+                  test-src/**, **/*.pl, **/*.php, **/*.init, **/*.py
+                  build/build.properties, build/local**, build/ivysettings.xml,
+                  classes/**, dist/**, local*/**, tmp/**, doc-src/images/db/**,
+                  build/ivysettings.xml, stylesheets/rng-catalog.xml"/>
+    </zip>
+  </target>
+</project>
diff --git a/build/build-docbook.xml b/build/build-docbook.xml
new file mode 100644
index 0000000..af84396
--- /dev/null
+++ b/build/build-docbook.xml
@@ -0,0 +1,483 @@
+<?xml version="1.0"?>
+<project name="hsqldb-ant-docbook" default="gen-docs"
+         xmlns:ivy="antlib:org.apache.ivy.ant">
+  <!--
+    USAGE
+    Purpose of this build file is to generate Whole HTML, Chunked HTML,
+    and PDF DocBook output documents from DocBook source located under a
+    doc-src subdirectory.
+
+    Must have Ivy v. 2.0 or later in Ant invocation CLASSPATH.
+    We suggest that you change-control a copy if the Ivy jar file in
+    the bootstrap-libs subdirectory, so things will work according to the
+    displayed message below (search below for "bootstrap-libs").
+
+    Normally you will "import" this file into your main Ant build file like
+        <import file="build-docbook.xml"/>
+    or, you can invoke targets in this file directly like
+        ant -f build-docbook.xml...
+
+    OVERRIDING Ant properties used in this file:
+    See inline instructions below for properties that you want to effect
+    only this build file.
+    For more general changes (say you want "javac.debug" to effect your own
+    build file as well as this one), set them however you want in your
+    parent Ant build file (perhaps by loading a "build.properties" or
+    "local.properties" file).
+  -->
+
+  <!-- Since the main HSQLDB build file imports this one, relative property
+       file specifications must be relative to the project root, not build/ -->
+
+  <!-- Put local env property changes in this NON-CHANGE-CONTROLLED file: -->
+  <property file="build/local-docbook.properties"/>
+  <!-- For change-controlled (by your project) ant-docbook-specific props: -->
+  <property file="build/docbook.properties"/>
+
+  <property name="oasis.stylesheet.url"
+            value="http://docbook.sourceforge.net/release/xsl-ns/current"/>
+  <!-- IMPORTANT:  This value must exactly match the network href values in
+       our *.xsl files! -->
+
+  <!-- See
+       http://xml.apache.org/commons/components/resolver/resolver-article.html#ctrlresolver
+       about these xml.catalog.* settings for the Xml Commons resolver.
+       The docs say to use values yes/no for booleans, instead of true/false.
+  -->
+  <property name="xml.catalog.verbosity" value="0"/>
+      <!-- BEWARE:  The verbosity setting seems to not work for some combination
+      of settings.  Haven't figured out what combo, but setting it to 10 has no
+      effect for our particular setup. -->
+  <property name="xml.catalog.files"
+            value="${basedir}/stylesheets/rng-catalog.xml"/>
+  <property name="xml.catalog.prefer" value="public"/>
+  <property name="xml.catalog.allowPI" value="yes"/>
+  <property name="xml.catalog.staticCatalog" value="yes"/>
+  <property name="ivy.dep.file" value="build/ivy.xml"/>
+  <property name="distro.baseurl" value="http://hsqldb.org/doc/2.0"/>
+
+  <property name="docoutput.path" value="doc"/>
+  <property name="javac.debug" value="true"/>
+  <property name="java.threadstacksize" value="1M"/>
+  <!-- TODO:  Once our repository is set up, change the repos.url value here -->
+  <property name="repos.url" value="http://pub.admc.com/lib-repos"/>
+  <property name="dbxirng.url"
+            value="http://www.docbook.org/xml/5.0/rng/docbook.rng"/>
+      <!-- The "xi" variant supports Xinclude -->
+  <property name="html.path" value="stylesheets/html.xsl"/>
+  <property name="chunk.path" value="stylesheets/chunk.xsl"/>
+  <property name="fo.path" value="stylesheets/fo.xsl"/>
+  <!-- Set nsstylebase.url, in your .properties file, to your local filesystem
+       or local http server location for the DocBok style sheets.
+       That makes the XSLT transformations execute much faster than when
+       pulling the sheets from OASIS Internet site.
+       Example transform. times: 34 s. vs. 1:49.
+  -->
+  <property name="nsstylebase.url" value="UNSET_STYLEBASE"/>
+  <!-- Without setting a default value, some error messages could contain the
+       misleading string "${nsstylebase.url}" in cases where user does not set a
+       value and resolution fails (not that there will be a resolution failure,
+       since this setting is optional). -->
+  <property name="dbcentx.url" value="UNSET_STYLEBASE"/>
+  <!-- ditto about the default value -->
+
+  <target name="fetch-images"
+          description="Fetch stock DocBook image files from Internet">
+    <echo>Copy the images directory from the latest stable version of the
+docbook-xsl-ns package to
+'${basedir}/doc-src/images/db'.  docbook-xsl-ns is
+available for download from the DocBook project at
+http://sourceforge.net/packages/docbook.
+We'll do this automatically for you once Ant has a task to transfer
+entire directories of files.</echo>
+  </target>
+
+  <target name="regen-docs"
+          description="Clean and regen project DocBook docs.  N.b this wipes javadocs too!"
+          depends="clean-docs, gen-docs"/>
+
+  <property name="_for.automation.blurb"
+    value="If you want to automate the antcalls and you don't mind using
+Ant-contrib or Antelope, you can use one of their 'for' tasks with a DirSet."/>
+
+  <target name="gen-docs">
+    <fail>You must implement your own "gen-docs" target by editing
+"build-docbook.xml" or overriding it in your own build file which imports
+"build-docbook.xml".
+Your "gen-docs" target must depend on -gen-docs-setup, do an "antcall" of
+"docbook-transform" for each doc.name, then call -gen-docs-complete.
+
+${_for.automation.blurb}</fail>
+  </target>
+
+  <target name="validate-docs">
+    <fail>You must implement your own "validate-docs" target
+by editing "build-docbook.xml" or overriding it in your own build file which
+imports "build-docbook.xml".
+Your "validate-docs" target must do an "antcall" of "validate-doc" for each
+doc.name.
+
+${_for.automation.blurb}</fail>
+  </target>
+
+  <target name="-gen-docs-setup" depends="refresh-verbatim"/>
+
+  <target name="-gen-docs-complete">
+    <!-- This is the highest-maintenance target of this build file.
+         Must update the copy and fixcrlf filesets to copy exactly what
+         needs to go to doc output branch, and enforce EOLs in all text files.
+         The dependsets elsewhere in this file use targetfilesets, not
+         targetfilelists, so shouldn't need maintenance there.
+
+         IMPORTANT:  FOR ALL copys and fixcrlfs, DO NOT USE
+         preservelastmodified, as that will defeat our dependsets.
+
+         Don't do anything with apidocs, since those are handled by
+         javadoc-specific tasks.
+    -->
+
+    <!-- First, just binaries.  We enforce EOLs for all others -->
+    <copy todir="${docoutput.path}">
+      <!-- Fileset pretty simple, since the binaries always need to be
+           served to end users. -->
+      <fileset dir="doc-src"
+               excludes="**/.*, **/*.txt, **/entities/**, apidocs/**,
+                         **/*.xml, **/*.java, **/*.sql, **/*.cfg, **/*.css,
+                         **/*.ent, **/*.rc, **/*.html, **/*.properties"/>
+    </copy>
+
+    <!-- *.txt and *.xml because *.txt are speficially not copied from document
+         base dirs and *.xml not from root or document base dirs,
+         because these files are used for document authorship and management.-->
+    <fixcrlf destdir="${docoutput.path}" eol="crlf"
+             encoding="UTF-8" srcdir="doc-src"
+             includes="verbatim/**/*.txt, images/**/*.txt"
+             excludes="**/.*"/>
+    <fixcrlf destdir="${docoutput.path}" eol="crlf"
+             encoding="UTF-8" srcdir="doc-src"
+             excludes="**/.*, verbatim/**, images/**, **/entities/**,
+                       */*.txt, apidocs/**, readme-template.txt"
+             includes="**/*.txt"/>
+    <fixcrlf destdir="${docoutput.path}" eol="lf"
+             encoding="UTF-8" srcdir="doc-src"
+             includes="verbatim/**/*.xml, images/**/*.xml"
+             excludes="**/.*"/>
+    <fixcrlf destdir="${docoutput.path}" eol="lf"
+             encoding="UTF-8" srcdir="doc-src"
+             excludes="**/.*, verbatim/**, images/**, **/entities/**,
+                       *.xml, */*.xml"
+             includes="**/*.xml"/>
+
+    <!-- All remaining text files -->
+    <fixcrlf destdir="${docoutput.path}" eol="lf"
+             encoding="UTF-8" srcdir="doc-src"
+             excludes="**/.*, **/entities/**, apidocs/**"
+             includes="**/*.java, **/*.sql, **/*.cfg, **/*.css,
+                       **/*.rc, **/*.properties"/>
+    <!-- To allow substitution of ant-variables like ${x} in any of the text
+         files above, just move that file type from the fixcrlf above to the
+         copy below. -->
+    <copy todir="${docoutput.path}">
+      <fileset dir="doc-src" excludes="**/.*, **/entities/**, apidocs/**"
+               includes="**/*.html"/>
+      <filterchain>
+        <expandproperties/>
+        <fixcrlf eol="lf" encoding="UTF-8"/>
+      </filterchain>
+    </copy>
+  </target>
+
+  <target name="docbook-transform" depends="-fop-setup"
+          description="Generate DocBook output for specified source doc">
+    <fail unless="doc.name"
+  message="Ant property 'doc.name' is required by target 'docbook-transform'."/>
+    <available property="_htmlstyle.present" type="file" file="${html.path}"/>
+    <available property="_chunkstyle.present" type="file" file="${chunk.path}"/>
+    <available property="_fostyle.present" type="file" file="${fo.path}"/>
+    <fail unless="_htmlstyle.present"
+          message="DocBook 5 HTML style sheet missing: ${html.path}"/>
+    <fail unless="_chunkstyle.present"
+          message="DocBook 5 Chunk HTML style sheet missing: ${chunk.path}"/>
+    <fail unless="_fostyle.present"
+          message="DocBook 5 FO style sheet missing: ${fo.path}"/>
+
+    <dependset>
+      <srcfileset dir="doc-src" excludes="**/.*, *_lic.txt, readme*, index.html"
+                  includes="*.*, entities/**, images/**, verbatim/**"/>
+          <!-- Remove *_lic.txt from excludes above and below if we add any
+               reference to license files from any of our DocBook documents.
+          -->
+      <targetfileset dir="tmp/doc-work"/>
+      <targetfileset dir="${docoutput.path}"
+             excludes="zaurus/**, apidocs/**, readme*, index.html, *_lic.txt"/>
+    </dependset>
+    <dependset>
+      <srcfileset dir="doc-src/${doc.name}" excludes="**/.*"/>
+      <targetfileset dir="${docoutput.path}/${doc.name}"/>
+      <targetfilelist dir="tmp/doc-work/${doc.name}" files="${doc.name}.fo"/>
+    </dependset>
+    <dependset>
+      <srcfilelist dir="tmp/doc-work/${doc.name}" files="${doc.name}.fo"/>
+      <targetfilelist dir="${docoutput.path}/${doc.name}"
+                      files="${doc.name}.pdf"/>
+    </dependset>
+    <available property="skip.html" type="file" value="transform.skip"
+               file="${docoutput.path}/${doc.name}/${doc.name}.html"/>
+    <available property="skip.chunk" type="file" value="transform.skip"
+               file="${docoutput.path}/${doc.name}/index.html"/>
+    <available property="skip.fo" type="file" value="transform.skip"
+               file="${docoutput.path}/${doc.name}/${doc.name}.fo"/>
+    <available property="skip.pdf" type="file" value="fop.skip"
+               file="${docoutput.path}/${doc.name}/${doc.name}.pdf"/>
+    <property name="skip.html" value="dummy"/>
+    <property name="skip.chuk" value="dummy"/>
+    <property name="skip.pdf" value="dummy"/>
+
+    <antcall target="-transform">
+      <param name="style.path" value="${html.path}"/>
+      <param name="output.base"
+             value="${docoutput.path}/${doc.name}/${doc.name}.html"/>
+      <param name="html.format" value="true"/>
+      <param name="${skip.html}" value="true"/>
+    </antcall>
+    <antcall target="-transform">
+      <param name="style.path" value="${chunk.path}"/>
+      <param name="output.base"
+             value="${docoutput.path}/${doc.name}/dummy.html"/>
+      <param name="html.format" value="true"/>
+      <param name="${skip.chunk}" value="true"/>
+    </antcall>
+    <fixcrlf eol="lf" encoding="UTF-8" srcdir="doc/${doc.name}"
+             includes="*.html"/>  <!-- Make output platform-independent -->
+    <antcall target="-transform">
+      <param name="style.path" value="${fo.path}"/>
+      <param name="output.base" value="tmp/doc-work/${doc.name}/${doc.name}.fo"/>
+      <param name="fop.format" value="true"/>
+      <param name="${skip.fo}" value="true"/>
+    </antcall>
+    <antcall target="-fop">
+      <param name="${skip.pdf}" value="true"/>
+    </antcall>
+  </target>
+
+  <target name="-fop" unless="fop.skip">
+    <fop format="application/pdf" basedir="doc-src/${doc.name}"
+         fofile="tmp/doc-work/${doc.name}/${doc.name}.fo"
+         outfile="${docoutput.path}/${doc.name}/${doc.name}.pdf"/>
+       <!-- basedir tells base location of image files -->
+       <!-- The fop tasks goes out to http://docbook.sourceforge.net to
+            fetch stuff -->
+  </target>
+
+  <target name="-transform" depends="-ivy-setup" unless="transform.skip">
+    <fail unless="distro.baseurl"
+   message="Ant property 'distro.baseurl' is required by target '-transform'."/>
+    <fail unless="doc.name"
+       message="Ant property 'doc.name' is required by target '-transform'."/>
+    <available file="${style.path}" type="file" property="_sheet.present"/>
+    <fail unless="_sheet.present"
+          message="Missing style sheet '${style.path}'"/>
+    <available file="doc-src/${doc.name}/${doc.name}.xml" type="file"
+               property="_srcxml.present"/>
+    <fail unless="_srcxml.present"
+      message="Missing DocBook source document 'doc-src/${doc.name}/${doc.name}.xml'"/>
+
+    <mkdir dir="tmp/doc-work/${doc.name}"/>
+    <echo file="tmp/doc-work/${doc.name}/dynamic.ent">&lt;!--Dynamically generated Entity Values loaded by a catalog for document
+'${doc.name}' --&gt;
+
+&lt;!ENTITY doc_basename "${doc.name}"&gt;
+&lt;!ENTITY distro_baseurl "${distro.baseurl}"&gt;
+</echo>
+
+    <ivy:cachepath conf="xalan" pathid="xalan.cpref"/>
+    <xslt style="${style.path}" basedir="doc-src/${doc.name}"
+          in="doc-src/${doc.name}/${doc.name}.xml"
+          out="${output.base}" classpathref="xalan.cpref">
+      <xmlcatalog classpathref="xalan.cpref" id="cat.ref">
+        <!-- WOULD MUCH PREFER TO DEFINE CATALOG EXTERNALLY.
+        Unfortunately, Ant's xmlcatalog is not seeing Apache's XML resolver.
+          -->
+
+        <!-- IMPORTANT! ***************************************
+             You must define Catalog mappings/replacements used in all of
+             your DocBook source right here, plus those needed in the validation
+             step need a duplicate entry in stylesheets/rng-catalog.xml.
+             Ant's xmlcatalog task is pretty limiting.  No support for prefixes,
+             and external XML Commons Resolver and external catalog files
+             support are broken.
+             IMPORTANT! *************************************** -->
+        <dtd publicId="-//OASIS/ENTITIES DocBook Character Entities V4.5//EN"
+             location="${dbcentx.url}"/>
+        <entity location="${nsstylebase.url}/html/docbook.xsl"
+                publicId="${oasis.stylesheet.url}/html/docbook.xsl"/>
+        <entity location="${nsstylebase.url}/html/chunk.xsl"
+                publicId="${oasis.stylesheet.url}/html/chunk.xsl"/>
+        <entity location="${nsstylebase.url}/fo/docbook.xsl"
+                publicId="${oasis.stylesheet.url}/fo/docbook.xsl"/>
+        <entity location="tmp/doc-work/${doc.name}/dynamic.ent"
+                publicId="-//HSQLDB/ENTITIES/DocSpecificDynamicEntities"/>
+      </xmlcatalog>
+      <!-- There is probably no reason to use if/unless to exclude
+           format-specific or feature-specific settings, since settings
+           that don't apply to a specific stylesheet will just be ignored. -->
+
+      <!-- N.b.:  "use.extensions" turns on all other *.extension properties.
+                  (The boolean *.extension ones, not *.*.extensions).
+                  If you want any off with "use.extensions" on, you must
+                  turn them off individually.
+                  "fop1.extensions" an exception?  See table at
+    http://www.sagehill.net/docbookxsl/InstallingAProcessor.html#SaxonExtensions
+      -->
+      <param name="use.extensions" expression="1"/>
+
+      <param name="admon.graphics" expression="1"/>
+      <param name="admon.graphics.path" expression="../images/db/"/>
+      <param name="admon.graphics.extension" expression=".png"/>
+      <param name="css.decoration" expression="1"/>
+      <param name="annotation.support" expression="1"/>
+      <param name="navig.graphics" expression="1"/>
+      <param name="navig.graphics.path" expression="../images/db/"/>
+      <param name="table.borders.with.css" expression="1"/>
+      <param name="callouts.gaphics" expression="1"/>
+      <param name="callouts.gaphics.path" expression="../images/db/callouts/"/>
+      <param name="graphic.default.extension" expression=".png"/>
+      <param name="callouts.gaphics.extension" expression=".png"/>
+      <param name="html.stylesheet" expression="../docbook.css"
+             if="html.format"/>
+      <param name="shade.verbatim" expression="1" unless="html.format"/>
+      <param name="textdata.default.encoding" expression="ISO-8859-1"/>
+      <param name="use.id.as.filename" expression="1"/>
+      <param name="variablelist.as.table" expression="1"/>
+      <param name="index.on.type" expression="1"/>
+      <param name="body.start.indent" expression="0" if="fop.format"/>
+      <param name="table.cell.border.thickness" expression="1pt"
+             if="fop.format"/>
+      <param name="html.cellspacing" expression="0" if="html.format"/>
+
+      <!-- With this on, formatting is terrible unless column content
+           lengths are symmetical -->
+      <param name="tablecolumns.extension" expression="0"/>
+
+      <!-- Docbook-supplied png nav icons suck -->
+      <param name="navig.graphics.extension" expression=".png"/>
+
+      <!-- "fop.extensions" for old FOP versions -->
+      <param name="fop1.extensions" expression="1" if="fop.format"/>
+
+      <!-- This tells sections shown in single HTML pages, not levels shown in
+           the TOC, which is governed by "toc.section.depth" -->
+      <param name="chunk.section.depth" expression="0"/>
+      <!-- Defaults to 1 -->
+
+      <!--  This has no effect, because the Docbook .xsl files specify the
+            output encoding literally.
+      <param name="chunker.output.encoding" expression="UTF-8"/>
+      -->
+
+      <outputproperty name="encoding" value="UTF-8"/>
+      <outputproperty name="indent" value="yes"/>
+    </xslt>
+  </target>
+
+  <target name="clean-docs" description="Remove all derived doc artifacts">
+    <delete dir="tmp/doc-work"/>
+    <delete includeemptydirs="true">
+      <fileset dir="${docoutput.path}" excludes="zaurus/**"/>
+    </delete>
+  </target>
+
+  <target name="-fop-setup" depends="-ivy-setup">
+    <ivy:cachepath conf="fop" pathid="fop.cpref"/>
+    <taskdef name="fop" classname="org.apache.fop.tools.anttasks.Fop"
+             classpathref="fop.cpref"/>
+  </target>
+
+  <target name="-ivy-setup">
+    <available property="_ivy.present" classname="org.apache.ivy.ant.IvyTask"/>
+    <fail unless="_ivy.present">
+Add Ivy jar file to Ant CLASSPATH.
+
+Obtain a 2.x version of an Apache Ivy jar file (perhaps at
+http://ant.apache.org/ivy/), and run a command like the following, changing the
+jar file path to wherever you have it saved.  For any Bourne shell (incl. Bash):
+
+    export ANT_ARGS; ANT_ARGS='-lib $HOME/ivy-2.1.0.jar -noclasspath'
+
+OR for any CMD-like Windows shell:
+
+    SET ANT_ARGS=-lib "%HOMEDRIVE%%HOMEPATH%/ivy-2.1.0.jar" -noclasspath</fail>
+
+    <available property="_ivysettings.present" file="build/ivysettings.xml"
+               type="file"/>
+    <antcall target="-ensure-ivysettings"/>
+    <ivy:settings/>
+  </target>
+
+  <target name="-ensure-ivysettings" unless="_ivysettings.present">
+    <copy file="build/ivysettings-sample.xml" tofile="build/ivysettings.xml"/>
+    <echo>Just created a local 'ivysettings.xml' file for you.
+Customize this as you wish and/or set Ivy properties (or any other
+docbook-specific local build properties) in a 'local.properties'
+file.</echo>
+  </target>
+
+  <target name="validate-doc" unless="validation.skip"
+          depends="-validation-setup, -ivy-setup"
+          description="Validate specified DocBook source document">
+    <fail unless="doc.name"
+          message="Ant property 'doc.name' is required by target 'validate'."/>
+    <ivy:resolve conf="msv"/>
+      <!-- The resolve downloads and makes the 3rd party libs accessed by
+           our admc-rs-msv jar file through its manifests classpath entry. -->
+    <ivy:cachepath conf="admc-rs-msv" pathid="admc-rs-msv.cpref"/>
+    <pathconvert property="jar.file" refid="admc-rs-msv.cpref"/>
+    <java fork="true" failonerror="true"
+          jar="${jar.file}" dir="doc-src/${doc.name}">
+      <sysproperty key="xml.catalog.verbosity"
+                   value="${xml.catalog.verbosity}"/>
+      <sysproperty key="xml.catalog.files" value="${xml.catalog.files}"/>
+      <sysproperty key="xml.catalog.prefer" value="${xml.catalog.prefer}"/>
+      <sysproperty key="xml.catalog.allowPI" value="${xml.catalog.allowPI}"/>
+      <sysproperty key="xml.catalog.staticCatalog"
+                   value="${xml.catalog.staticCatalog}"/>
+      <jvmarg value="-Xss${java.threadstacksize}"/>
+      <arg value="-v"/>
+      <arg value="${dbxirng.url}"/>
+      <arg value="${doc.name}.xml"/>
+    </java>
+  </target>
+
+  <target name="validation-help" depends="-ivy-setup"
+          description="Display advice about validating files manually">
+    <ivy:resolve conf="msv"/>
+      <!-- The resolve downloads and makes the 3rd party libs accessed by
+           our admc-rs-msv jar file through its manifests classpath entry. -->
+    <ivy:cachepath conf="admc-rs-msv" pathid="admc-rs-msv.cpref"/>
+    <pathconvert property="jar.file" refid="admc-rs-msv.cpref"/>
+    <echo>'cd' to the directory containing the XML source files, and run
+something like
+java -Xss${java.threadstacksize} -Dxml.catalog.files=${xml.catalog.files} -jar ${jar.file} -v ${dbxirng.url} file.xml...
+
+See the XML Commons docs about the Java System Properties to
+use for XML catalog resolution:
+http://xml.apache.org/commons/components/resolver/resolver-article.html#ctrlresolver
+</echo>
+  </target>
+
+  <target name="refresh-verbatim"
+          description="Update files under doc-src/verbatim">
+    <!-- It's good to apply preservelastmodified to stuff under doc-src/,
+         but be very careful if applying it to doc/..., since that could
+         break our dependsets. -->
+    <copy todir="doc-src/verbatim" preservelastmodified="true">
+      <fileset dir=".">
+        <present targetdir="doc-src/verbatim"/>
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="-validation-setup">
+    <fail message="Something is wrong.  '-validation-setup' is abstract"/>
+  </target>
+</project>
diff --git a/build/build.hsqldb.cmd b/build/build.hsqldb.cmd
new file mode 100755
index 0000000..86fc108
--- /dev/null
+++ b/build/build.hsqldb.cmd
@@ -0,0 +1,2 @@
+call setenv.cmd

+ant clean hsqldb

diff --git a/build/build.hsqldbtest.cmd b/build/build.hsqldbtest.cmd
new file mode 100755
index 0000000..8d7b760
--- /dev/null
+++ b/build/build.hsqldbtest.cmd
@@ -0,0 +1,2 @@
+call setenv.cmd

+ant clean hsqldb hsqldbtest

diff --git a/build/build.test.suite.cmd b/build/build.test.suite.cmd
new file mode 100755
index 0000000..855ae16
--- /dev/null
+++ b/build/build.test.suite.cmd
@@ -0,0 +1,2 @@
+call setenv.cmd

+ant -f test.xml clean.test.suite make.test.suite

diff --git a/build/build.xml b/build/build.xml
new file mode 100644
index 0000000..f99aa1b
--- /dev/null
+++ b/build/build.xml
@@ -0,0 +1,1077 @@
+<?xml version="1.0"?>
+<!-- $Id: build.xml 3621 2010-06-04 15:33:36Z fredt $ -->
+<!-- author fredt@users.sourceforge.net 2001 - 2009 -->
+<!-- additional targets 2004-2009: blaine (dot) simpson (at) admc (dot) com -->
+<project name="hsqldb" default="help" basedir="../">
+   <!-- This loads properties in the same exact way as if you ran
+        "ant -Dprop1name=val1 -Dprop2name=val2...", etc.  To use all
+        defaults, you should have no 'build.properties' file.
+        If you don't understand this or want to know about precedence or
+        how to use an Ant properties file, look up an Ant manual or an
+        Ant expert.
+        If you want to know, "Can I set property 'x' in 'build.properties'",
+        rephrase the question to yourself as "Can I run 'ant -Dx=...?"
+        Do not address questions about property file(s) to the
+        hsqldb community. -->
+
+  <!-- TODO:
+        Use multiple class directories (javac dest dirs).
+        Current tactic requires tons of complicated includes and exludes
+        and still often bundles arbitrary extra stuff (determined by what
+        happened to be built previously).
+  -->
+
+   <property file='build/build.properties'/>
+   <property name="hsqldb.version" value="2.0.0"/>
+
+   <tstamp>
+       <format property="_tmpstamp" pattern="yyyy/MM/dd-HH:mm:ss"
+               locale="en"/>
+   </tstamp>
+
+   <property name="build.label" value="private-${_tmpstamp}"/>
+   <property name="build.vendor" value="${user.name}"/>
+   <property name="hsqldb.title" value="HSQLDB"/>
+   <property name="hsqldb.vendor" value="The HSQL Development Group"/>
+   <property name="swsrc" value="tmp/switchedsrc"/>
+   <condition property="switch.inplace">
+     <equals arg1="${swsrc}" arg2="src"/>
+   </condition>
+
+   <!-- It is safe to override these with settings in your own
+        build.properties file. -->
+   <property name="build.debug" value="true"/>
+   <property name="build.optimize" value="false"/>
+   <!-- N.b. Compilation optimization only has effect with JDK 1.1 and 1.2 -->
+
+   <property name="servletapi.lib" value="lib/servlet-2_3-fcs-classfiles.zip"/>
+   <property name="junit38.lib" value="lib/junit.jar"/>
+   <property name='jflex.lib' value='lib/JFlex.jar'/>
+
+   <target name="init"/>
+
+   <target name='explainjars'
+           description="List description of jars that you can build">
+     <echo>Ant version: ${ant.version} </echo>
+     <echo>jar filename    build command   explanation
+--------------  -------------   -----------------------------------
+hsqldb.jar      ant hsqldb      Default distribution jar
+hsqljdbc.jar    ant hsqljdbc    JDBC network client JDBC Driver.
+                                (Can connect to HyperSQL Servers)
+hsqldbmain.jar  ant hsqldbmain  No utility programs
+hsqldbutil.jar  ant hsqldbutil  Utility programs only.  No JDBC
+                                driver.  (Includes SqlTool and
+                                DatabaseManagers)
+hsqldbmin.jar   ant hsqldbmin   No utility or server programs.
+                                (Includes in-process JDBC driver,
+                                but no support for HyperSQL
+                                Servers)
+hsqldbtest.jar  ant hsqldbtest  All, including test classes
+sqltool.jar     ant sqltool     SqlTool app (no JDBC driver)</echo>
+   </target>
+
+   <!-- Deprecated targets.  New naming convention is:
+        Target name is always the same as the desired jar file name, less
+        the ".jar" extension. -->
+   <target name='jar' depends='hsqldb'/>
+   <target name='jarclient' depends='hsqljdbc'/>
+   <target name='jarmain' depends='hsqldbmain'/>
+   <target name='jarmin' depends='hsqldbmin'/>
+   <target name='jartest' depends='hsqldbtest'/>
+   <target name='jarutil' depends='hsqldbutil'/>
+
+   <target name="help" description="Top-level help message">
+     <echo>Ant version: ${ant.version} </echo>
+      <echo>usage:
+   ant -help            Display ant help screen
+   ant -projecthelp     Display all invocable targets
+   ant explainjars      List all targets which build jar files
+   ant ANYTHING ELSE    Run 'ant -projecthelp' for details
+
+examples:
+   ant jar
+   ant clean</echo>
+   </target>
+
+   <target name="-javajsse">
+      <available classname="javax.net.ssl.SSLSession" property="ant.java.hasjsse"/>
+      <echo message="ant.java.hasjsse=${ant.java.hasjsse}" />
+   </target>
+
+   <target name="-set-jvmvars">
+   <!-- Besides this one target taking the place of 4 targets (-javaversionX),
+        this target eliminates the redundancy in those methods by making a
+        single class-existence-test definitively responsible for determining if
+        JVM X is supported.
+        It is sufficient for this purposes if the test classes used are
+        verified to be present in version X and in all newer versions (> X)
+        (i.e. that the class is not removed from some higher JVM). -->
+      <available classname="java.lang.ref.Reference" property="ant.java.iscjava12"/>
+      <available classname="java.lang.ref.Reference" property="ant.java.iscjavamodern"/>
+      <available classname="java.nio.Buffer" property="ant.java.iscjava14"/>
+      <available classname="java.util.EnumSet" property="ant.java.iscjava15"/>
+      <available classname="java.net.IDN" property="ant.java.iscjava16"/>
+   </target>
+
+   <target name="-prepare" depends="init,-set-jvmvars">
+       <mkdir dir="classes" />
+   </target>
+
+   <target name="-prepare-javadoc" depends="init">
+     <delete dir="doc/apidocs"/>
+     <!-- Must be vigilant about cleaning up from previous runs, since this
+          same directory is used for both public API spec, and the full
+          code-base API spec.
+          There is no performance penalty, since the javadoc task regenerates
+          everything each run.
+      -->
+     <copy todir="doc/apidocs">
+       <!-- IMPORTANT:
+            Add a fixcrlf if we add non-binary files to doc-src/apidocs. -->
+       <fileset dir="doc-src/apidocs"/>
+     </copy>
+   </target>
+
+
+   <target name="reinit"
+       description="Just like 'clean' target, except overwrites switched source files to prevent need for a complete re-copy">
+       <!-- Beware this will retain a copy of removed artifcats under src.
+            You must use the real 'clean' target to really purge everything. -->
+       <fail message="Just use 'clean' for inplace-switching setups"
+             if="switch.inplace"/>
+       <delete dir="classes"/>
+       <copy todir='${swsrc}' preservelastmodified='true'>
+           <fileset dir='src' includes='**/*.java'/>
+       </copy>
+   </target>
+
+   <target name="clean" depends="-clean, -clean-switch-branch"
+           description="Delete the /classes and work directories created by ant tasks">
+        <echo message="Use the 'clean-all' target to also purge generated doc and .jar files"/>
+   </target>
+
+   <target name="-clean">
+        <delete dir="classes"/>
+   </target>
+
+   <target name="clean-all" depends="-clean, -clean-switch-branch, clean-docs"
+           description="Same as clean but delete the jar and doc files as well">
+      <delete>
+         <fileset dir="lib" includes="sqltool*.jar, hsql*.jar, testsuite.jar"/>
+      </delete>
+   </target>
+
+    <target name="codeswitcher" depends="-prepare"
+            description="uses +-JAVA2 +-JAVA4 +-JAVA5 +-JAVA6">
+      <javac destdir="classes">
+         <src path="src"/>
+         <include name="org/hsqldb/util/CodeSwitcher.java"/>
+      </javac>
+      <antcall target="-update-switch-branch"/>
+    </target>
+
+    <target name="switchtojava1target" depends="codeswitcher"
+            description="self explanatory">
+      <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+        <arg file="${swsrc}/org/hsqldb/lib/java/JavaSystem.java"/>
+        <arg file="${swsrc}/org/hsqldb/util/DatabaseManager.java"/>
+        <arg file="${swsrc}/org/hsqldb/util/ConnectionDialogCommon.java"/>
+        <arg value="-JAVA2FULL"/>
+      </java>
+    </target>
+
+    <target name="switchoffjava1target" depends="codeswitcher"
+            description="self explanatory">
+      <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+         <arg file="${swsrc}/org/hsqldb/lib/java/JavaSystem.java"/>
+         <arg file="${swsrc}/org/hsqldb/util/DatabaseManager.java"/>
+         <arg file="${swsrc}/org/hsqldb/util/ConnectionDialogCommon.java"/>
+         <arg value="+JAVA2FULL"/>
+       </java>
+    </target>
+
+    <target name="switchtodeprecatedjdbc" depends="codeswitcher"
+            description="self explanatory">
+      <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+        <arg file="${swsrc}/org/hsqldb/jdbc/JDBCCallableStatement.java"/>
+        <arg file="${swsrc}/org/hsqldb/jdbc/JDBCPreparedStatement.java"/>
+        <arg file="${swsrc}/org/hsqldb/jdbc/JDBCResultSet.java"/>
+        <arg value="+DEPRECATEDJDBC"/>
+      </java>
+    </target>
+
+    <target name="switchoffdeprecatedjdbc" depends="codeswitcher"
+            description="self explanatory">
+      <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+        <arg file="${swsrc}/org/hsqldb/jdbc/JDBCCallableStatement.java"/>
+        <arg file="${swsrc}/org/hsqldb/jdbc/JDBCPreparedStatement.java"/>
+        <arg file="${swsrc}/org/hsqldb/jdbc/JDBCResultSet.java"/>
+        <arg value="-DEPRECATEDJDBC"/>
+      </java>
+    </target>
+
+    <!-- If this should not be called externally, rename to -switches
+         and remove the description attribute -->
+    <target name="switches" depends="codeswitcher"
+            description="Execute code switchers, other than for JVM version">
+    </target>
+
+    <target name="switchtojdk12" depends="switches" unless="ant.java.iscjava14"
+            description="self explanatory" if="ant.java.iscjava12">
+      <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+          <arg value="+JAVA2"/>
+          <arg value="-JAVA4"/>
+          <arg value="-JAVA5"/>
+          <arg value="-JAVA6"/>
+          <arg value="--pathlist=jdkcodeswitch.list"/>
+          <arg value="--basedir=../${swsrc}"/>
+          <!-- Since these paths are interpreted by the JVM, not ant,
+               the path must be relative to run dir (build), not the
+               Ant basedir -->
+      </java>
+    </target>
+
+    <target name="switchtojdk14" depends="switches" unless="ant.java.iscjava15"
+            description="self explanatory" if="ant.java.iscjava14">
+      <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+          <arg value="+JAVA2"/>
+          <arg value="+JAVA4"/>
+          <arg value="-JAVA5"/>
+          <arg value="-JAVA6"/>
+          <arg value="--pathlist=jdkcodeswitch.list"/>
+          <arg value="--basedir=../${swsrc}"/>
+          <!-- Since these paths are interpreted by the JVM, not ant,
+               the path must be relative to run dir (build), not the
+               Ant basedir -->
+       </java>
+    </target>
+
+    <target name="switchtojdk15" depends="switches" unless="ant.java.iscjava16"
+      description="self explanatory" if="ant.java.iscjava15">
+      <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+          <arg value="+JAVA2"/>
+          <arg value="+JAVA4"/>
+          <arg value="+JAVA5"/>
+          <arg value="-JAVA6"/>
+          <arg value="--pathlist=jdkcodeswitch.list"/>
+          <arg value="--basedir=../${swsrc}"/>
+          <!-- Since these paths are interpreted by the JVM, not ant,
+               the path must be relative to run dir (build), not the
+               Ant basedir -->
+       </java>
+    </target>
+
+    <target name="switchtojdk16" depends="switches"
+            description="self explanatory" if="ant.java.iscjava16">
+      <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+          <arg value="+JAVA2"/>
+          <arg value="+JAVA4"/>
+          <arg value="+JAVA5"/>
+          <arg value="+JAVA6"/>
+          <arg value="--pathlist=jdkcodeswitch.list"/>
+          <arg value="--basedir=../${swsrc}"/>
+          <!-- Since these paths are interpreted by the JVM, not ant,
+               the path must be relative to run dir (build), not the
+               Ant basedir -->
+       </java>
+    </target>
+
+    <target name="store" description="compiles the /store folder"
+            depends="switchtojdk12,switchtojdk14,
+                     switchtojdk15,switchtojdk16">
+      <javac srcdir="${swsrc}"
+             destdir="classes"
+                 debug="${build.debug}"
+                 optimize="${build.optimize}"
+      >
+         <include name="org/hsqldb/store/**"/>
+      </javac>
+    </target>
+
+    <target name="lib" depends="store"
+            description="compiles the JVM-independent lib classes">
+      <javac srcdir="${swsrc}"
+             destdir="classes"
+                 debug="${build.debug}"
+                 optimize="${build.optimize}"
+      >
+         <exclude name="org/hsqldb/lib/AppendableException.java"/>
+         <exclude name="org/hsqldb/lib/RefCapablePropertyResourceBundle.java"/>
+         <exclude name="org/hsqldb/lib/RefCapableRBInterface.java"/>
+         <exclude name="org/hsqldb/lib/ValidatingResourceBundle.java"/>
+         <exclude name="org/hsqldb/lib/tar/**"/>
+         <include name="org/hsqldb/lib/**"/>
+      </javac>
+    </target>
+
+    <target name="classes" depends="lib,-javajsse"
+            description="compiles JVM-independent non-lib/util/cmdline classes">
+      <available property='_servlet_available' classpath='${servletapi.lib}'
+                 classname='javax.servlet.ServletException'/>
+      <fail unless='_servlet_available'
+            message="Place Jar file for Servlet API at '${servletapi.lib}', or set property 'servletapi.lib'"/>
+      <javac srcdir="${swsrc}"
+             destdir="classes"
+                 debug="${build.debug}"
+                 optimize="${build.optimize}"
+       >
+         <classpath>
+            <pathelement location="${servletapi.lib}"/>
+         </classpath>
+         <include name="*.java"/>
+         <include name="org/hsqldb/*.java"/>
+         <include name="org/hsqldb/dbinfo/*.java"/>
+         <include name="org/hsqldb/index/*.java"/>
+         <include name="org/hsqldb/jdbc/*.java"/>
+         <include name="org/hsqldb/navigator/*.java"/>
+         <include name="org/hsqldb/persist/*.java"/>
+         <include name="org/hsqldb/resources/*.java"/>
+         <include name="org/hsqldb/result/*.java"/>
+         <include name="org/hsqldb/rowio/*.java"/>
+         <include name="org/hsqldb/scriptio/*.java"/>
+         <include name="org/hsqldb/server/*.java"/>
+         <include name="org/hsqldb/store/*.java"/>
+         <include name="org/hsqldb/types/*.java"/>
+         <exclude name="org/hsqldb/server/HsqlSocketFactorySecure.java" unless="ant.java.hasjsse"/>
+         <exclude name="org/hsqldb/jdbc/JDBCArray.java"/>
+         <exclude name="org/hsqldb/jdbc/JDBCBlob.java"/>
+         <exclude name="org/hsqldb/jdbc/JDBCClob.java"/>
+         <exclude name="org/hsqldb/jdbc/JDBCDataSource*.java"/>
+         <exclude name="org/hsqldb/jdbc/JDBCParameterMetaData.java"/>
+         <exclude name="org/hsqldb/jdbc/JDBCSavepoint.java"/>
+<!-- BEGIN JDBC 4-->
+         <exclude name="org/hsqldb/jdbc/JDBCNClob.java"/>
+         <exclude name="org/hsqldb/jdbc/JDBCRowId.java"/>
+         <exclude name="org/hsqldb/jdbc/JDBCSQLXML.java"/>
+<!-- TODO
+         <exclude name="org/hsqldb/jdbc/jdbcConflictingRowImpl.java"/>
+         <exclude name="org/hsqldb/jdbc/jdbcDataSetImpl.java"/>
+         <exclude name="org/hsqldb/jdbc/jdbcDataSetResolverImpl.java"/>
+         <exclude name="org/hsqldb/jdbc/jdbcQueryObjectGeneratorImpl.java"/>
+         <exclude name="org/hsqldb/jdbc/jdbcRowSet.java"/>
+-->
+<!-- end JDBC 4 -->
+         <exclude name="org/hsqldb/persist/NIOLockFile.java"/>
+         <exclude name="org/hsqldb/persist/NIOScaledRAFile.java"/>
+      </javac>
+      <fixcrlf destdir="classes" preservelastmodified='true' eol="lf"
+               encoding="ISO-8859-1" srcdir="src"
+               includes="**/*.properties, **/*.text, **/*.sql"/>
+    </target>
+
+   <target name="classes12" depends="classes" if="ant.java.iscjavamodern"
+           description="compiles 1.2 specific classes">
+      <javac srcdir="${swsrc}"
+             destdir="classes"
+                 debug="${build.debug}"
+                 optimize="${build.optimize}"
+       >
+         <include name="org/hsqldb/jdbc/JDBCArray.java"/>
+         <include name="org/hsqldb/jdbc/JDBCBlob.java"/>
+         <include name="org/hsqldb/jdbc/JDBCClob.java"/>
+      </javac>
+   </target>
+
+   <target name="classes14" depends="classes12" if="ant.java.iscjava14"
+           description="compiles 1.4 specific classes">
+      <javac srcdir="${swsrc}" destdir="classes" debug="${build.debug}"
+                 optimize="${build.optimize}" >
+      <include name="org/hsqldb/jdbc/pool/*.java"/>
+      <include name="org/hsqldb/jdbc/JDBCDataSource*.java"/>
+      <include name="org/hsqldb/jdbc/JDBCParameterMetaData.java"/>
+      <include name="org/hsqldb/jdbc/JDBCSavepoint.java"/>
+      <include name="org/hsqldb/persist/NIOLockFile.java"/>
+      <include name="org/hsqldb/persist/NIOScaledRAFile.java"/>
+      </javac>
+   </target>
+
+   <target name="classes15" depends="classes14" if="ant.java.iscjava15"
+           description="compiles 1.5 specific classes">
+      <javac srcdir="${swsrc}" destdir="classes" debug="${build.debug}"
+                 optimize="${build.optimize}" >
+        <include name="org/hsqldb/lib/AppendableException.java"/>
+        <include name="org/hsqldb/lib/RefCapablePropertyResourceBundle.java"/>
+        <include name="org/hsqldb/lib/RefCapableRBInterface.java"/>
+        <include name="org/hsqldb/lib/ValidatingResourceBundle.java"/>
+        <include name="org/hsqldb/lib/tar/**"/>
+      </javac>
+   </target>
+
+   <target name="classes16" depends="classes15" if="ant.java.iscjava16"
+           description="compiles 1.6 specific classes">
+      <javac srcdir="${swsrc}" destdir="classes" debug="${build.debug}"
+                 optimize="${build.optimize}" >
+         <include name="org/hsqldb/jdbc/JDBCNClob.java"/>
+         <include name="org/hsqldb/jdbc/JDBCRowId.java"/>
+         <include name="org/hsqldb/jdbc/JDBCSQLXML.java"/>
+<!-- TODO
+         <include name="org/hsqldb/jdbc/jdbcConflictingRowImpl.java"/>
+         <include name="org/hsqldb/jdbc/jdbcDataSetImpl.java"/>
+         <include name="org/hsqldb/jdbc/jdbcDataSetResolverImpl.java"/>
+         <include name="org/hsqldb/jdbc/jdbcQueryObjectGeneratorImpl.java"/>
+         <include name="org/hsqldb/jdbc/jdbcRowSet.java"/>
+-->
+      </javac>
+   </target>
+
+   <!-- Don't both use name beginning with - AND supply a 'description'.
+        If this should be externally callable, then remove the leading -
+        and change the following description to a description attribute:
+                                               - blaine
+
+        compiles 1.4-specific test classes
+   -->
+    <target name="-test14" if="ant.java.iscjava14" depends='switches'>
+      <antcall inheritall='true' target='-requireJunit'/>
+      <!-- using antcall instead of depends so that it is not called if the
+           target "if" above is false. -->
+      <javac srcdir="${swsrc}"
+             destdir="classes"
+             debug="${build.debug}"
+             optimize="${build.optimize}"
+             classpath="${junit38.lib}"
+       >
+          <include name="org/hsqldb/test/TestJDBCSavepoints.java"/>
+      </javac>
+   </target>
+
+    <target name="util" depends="lib, -cmdline"
+            description="compiles the util and cmdline folders">
+      <javac srcdir="${swsrc}"
+             destdir="classes"
+             debug="${build.debug}"
+             optimize="${build.optimize}"
+      >
+         <include name="org/hsqldb/util/**"/>
+         <exclude name="org/hsqldb/util/*Swing.java"/>
+         <exclude name="org/hsqldb/util/preprocessor/**"/>
+         <exclude name="org/hsqldb/util/TableSorter.java"/>
+      </javac>
+      <copy todir="classes/org/hsqldb/util" preservelastmodified='true'>
+          <fileset dir="src/org/hsqldb/util" includes='*.gif, *.png'/>
+      </copy>
+    </target>
+
+    <target name="-cmdline" if="ant.java.iscjava15"
+            description="compiles the cmdline classes">
+      <antcall target="-sqlfile-scanner"/>
+      <!-- antcall instead of depends, because we don't want it to be run
+           if the 'if' is false -->
+      <javac srcdir="${swsrc}"
+             destdir="classes"
+             debug="${build.debug}"
+             optimize="${build.optimize}"
+      >
+         <include name="org/hsqldb/cmdline/**"/>
+      </javac>
+    </target>
+
+
+   <target name="swing" depends="util" unless="noswing"
+           description="compiles the swing based classes in the util folder">
+      <javac srcdir="${swsrc}"
+             destdir="classes"
+             debug="${build.debug}"
+             optimize="${build.optimize}"
+       >
+      <include name="org/hsqldb/util/*Swing.java"/>
+      <include name="org/hsqldb/util/TableSorter.java"/>
+      </javac>
+   </target>
+
+   <target name='-requireJunit'>
+      <available property='_junit_available' classpath='${junit38.lib}'
+                 classname='junit.swingui.TestRunner'/>
+      <fail unless='_junit_available'
+            message="Place Jar file for v. 3.8.x of Junit at '${junit38.lib}', or set property 'junit38.lib'"/>
+   </target>
+
+   <target name="scanner-driver" depends="util">
+      <!-- Purposefully no description -->
+      <javac srcdir="${swsrc}"
+             includes="org/hsqldb/test/SqlFileScannerDriver.java"
+             destdir="classes"
+             debug="${build.debug}"
+             optimize="${build.optimize}"
+             />
+   </target>
+
+   <target name="test" depends="-requireJunit, classes16"
+           description="compiles the test package classes">
+         <javac srcdir="${swsrc}"
+             destdir="classes"
+             debug="${build.debug}"
+             optimize="${build.optimize}"
+         >
+         <classpath>
+            <pathelement location="${junit38.lib}"/>
+            <pathelement location="lib/dbunit.jar"/>
+         </classpath>
+         <include name="org/hsqldb/test/**"/>
+         <exclude name="org/hsqldb/test/TestJDBCSavepoints.java"/>
+         <exclude name="org/hsqldb/test/SqlFileScannerDriver.java"/>
+      </javac>
+      <antcall inheritall='true' target='-test14'/>
+   </target>
+
+    <target name="hsqldbtest" depends="test,swing, -prep-license-files"
+            description="Build the hsqldbtest.jar (default plus test classes)">
+        <jar jarfile="lib/hsqldbtest.jar"
+             basedir="classes"
+         >
+         <metainf dir="doc" includes="*_lic.txt"/>
+         <service type="java.sql.Driver" provider="org.hsqldb.jdbc.JDBCDriver"/>
+         <manifest>
+             <attribute name='Specification-Title' value='${hsqldb.title}'/>
+             <attribute name='Specification-Version' value='${hsqldb.version}'/>
+             <attribute name='Specification-Vendor' value='${hsqldb.vendor}'/>
+             <attribute name='Implementation-Title'
+                        value='Test runtime'/>
+             <attribute name='Implementation-Version' value='${build.label}'/>
+             <attribute name='Implementation-Vendor' value='${build.vendor}'/>
+         </manifest>
+         <exclude name="org/hsqldb/jmx/**"/>
+         <exclude name="org/hsqldb/sample/*"/>
+      </jar>
+    </target>
+
+    <!--
+            Sat Nov 19 17:52:33 EST 2005  Blaine changing this description,
+            because I see no Swing classes in hsqldbmain.jar when I build
+            it... why would anybody ever want them in a no-util jar anyways?
+
+            description="Build the hsqldbmain.jar (no utilities) (use ant switch '-Dnoswing=true' to exclude swing classes)">
+    -->
+    <target name="hsqldbmain" depends="classes16, -prep-license-files"
+            description="Build the hsqldbmain.jar (no utilities)">
+        <jar jarfile="lib/hsqldbmain.jar"
+             basedir="classes"
+         >
+         <metainf dir="doc" includes="*_lic.txt"/>
+         <service type="java.sql.Driver" provider="org.hsqldb.jdbc.JDBCDriver"/>
+         <manifest>
+             <attribute name='Specification-Title' value='${hsqldb.title}'/>
+             <attribute name='Specification-Version' value='${hsqldb.version}'/>
+             <attribute name='Specification-Vendor' value='${hsqldb.vendor}'/>
+             <attribute name='Implementation-Title'
+                        value='Runtime without utilities'/>
+             <attribute name='Implementation-Version' value='${build.label}'/>
+             <attribute name='Implementation-Vendor' value='${build.vendor}'/>
+         </manifest>
+         <exclude name="org/hsqldb/jmx/**"/>
+         <exclude name="org/hsqldb/util/**"/>
+         <exclude name="org/hsqldb/cmdline/**"/>
+         <exclude name="org/hsqldb/test/**"/>
+         <exclude name="org/hsqldb/sample/**"/>
+      </jar>
+    </target>
+
+    <target name="hsqldbmin" depends="classes16, -prep-license-files"
+            description="Build the hsqldbmin.jar (no connection pooling or servers)">
+        <jar jarfile="lib/hsqldbmin.jar"
+             basedir="classes"
+         >
+         <metainf dir="doc" includes="*_lic.txt"/>
+         <service type="java.sql.Driver" provider="org.hsqldb.jdbc.JDBCDriver"/>
+         <manifest>
+             <attribute name='Specification-Title' value='${hsqldb.title}'/>
+             <attribute name='Specification-Version' value='${hsqldb.version}'/>
+             <attribute name='Specification-Vendor' value='${hsqldb.vendor}'/>
+             <attribute name='Implementation-Title'
+                 value='Runtime without utilities, connection pooling and servers'/>
+             <attribute name='Implementation-Version' value='${build.label}'/>
+             <attribute name='Implementation-Vendor' value='${build.vendor}'/>
+         </manifest>
+         <!-- Without this, some ANT/Java combinations may get confused and
+              include nothing in the jar -->
+         <include name="**/*"/>
+         <!-- -->
+         <exclude name="org/hsqldb/jdbc/pool/**"/>
+         <exclude name="org/hsqldb/jmx/**"/>
+         <exclude name="org/hsqldb/util/**"/>
+         <exclude name="org/hsqldb/cmdline/**"/>
+         <exclude name="org/hsqldb/test/**"/>
+         <exclude name="org/hsqldb/sample/**"/>
+         <exclude name="**/*.properties"/>
+         <include name="org/hsqldb/resources/sql-error-messages.properties"/>
+         <exclude name="hsqlServlet.class"/>
+         <exclude name="org/hsqldb/Servlet.class"/>
+         <exclude name="org/hsqldb/Server.class"/>
+         <exclude name="org/hsqldb/server/HsqlSocketFactory.class"/>
+         <exclude name="org/hsqldb/server/HsqlSocketFactorySecure.class"/>
+         <exclude name="org/hsqldb/srever/HsqlServerFactory.class"/>
+         <exclude name="org/hsqldb/srever/HsqlServerProperties.class"/>
+         <exclude name="org/hsqldb/server/HsqlSocketRequestHandler.class"/>
+         <exclude name="org/hsqldb/server/HsqlSocketRequestHandlerImpl.class"/>
+         <exclude name="org/hsqldb/server/Server.class"/>
+         <exclude name="org/hsqldb/server/Server$ServerThread.class"/>
+         <exclude name="org/hsqldb/server/ServerConnection.class"/>
+         <exclude name="org/hsqldb/server/ServerConfiguration.class"/>
+         <exclude name="org/hsqldb/server/WebServer.class"/>
+         <exclude name="org/hsqldb/server/WebServerConnection.class"/>
+         <exclude name="org/hsqldb/dbinfo/DatabaseInformationFull.class"/>
+         <exclude name="org/hsqldb/rowio/RowInputLegacy.class"/>
+         <exclude name="org/hsqldb/rowio/RowOutputLegacy.class"/>
+         <exclude name="org/hsqldb/dbinfo/DIProcedureInfo.class"/>
+         <exclude name="org/hsqldb/HSQLClientConnection.class"/>
+         <exclude name="org/hsqldb/HTTPClientConnection.class"/>
+       </jar>
+    </target>
+
+    <target name="hsqldb" depends="classes16, util, swing, -prep-license-files"
+            description="Build the default hsqldb.jar">
+        <jar jarfile="lib/hsqldb.jar"
+             basedir="classes"
+             compress="true"
+         >
+         <metainf dir="doc" includes="*_lic.txt"/>
+         <service type="java.sql.Driver" provider="org.hsqldb.jdbc.JDBCDriver"/>
+         <manifest>
+             <attribute name='Specification-Title' value='${hsqldb.title}'/>
+             <attribute name='Specification-Version' value='${hsqldb.version}'/>
+             <attribute name='Specification-Vendor' value='${hsqldb.vendor}'/>
+             <attribute name='Implementation-Title'
+                        value='Standard runtime'/>
+             <attribute name='Implementation-Version' value='${build.label}'/>
+             <attribute name='Implementation-Vendor' value='${build.vendor}'/>
+             <!-- This attribute is completely ignored unless the user
+                  uses the jar like "java -jar .../hsqldb.jar" -->
+             <attribute name='Main-Class' value='org.hsqldb.util.DatabaseManagerSwing'/>
+         </manifest>
+         <exclude name="org/hsqldb/jmx/**"/>
+         <exclude name="org/hsqldb/util/*Swing.*" if="noswing"/>
+         <exclude name="org/hsqldb/util/*Transfer*"/>
+         <exclude name="org/hsqldb/util/DataAccess*"/>
+         <exclude name="org/hsqldb/util/*Helper*"/>
+         <exclude name="org/hsqldb/util/JDBCTypes.*"/>
+         <exclude name="org/hsqldb/util/SQLStatements.*"/>
+         <exclude name="org/hsqldb/util/QueryTool.*"/>
+         <exclude name="org/hsqldb/util/Zaurus*"/>
+         <exclude name="org/hsqldb/test/*.class"/>
+         <exclude name="org/hsqldb/sample/*.class"/>
+         <exclude name="org/hsqldb/cmdline/**"/>
+      </jar>
+    </target>
+
+    <fileset id='jdbcclasses' dir='classes'
+        includes='
+                  org/hsqldb/error/*,
+                  org/hsqldb/navigator/*,
+                  org/hsqldb/result/*,
+                  org/hsqldb/lib/ArrayUtil*,
+                  org/hsqldb/lib/CountdownInputStream*,
+                  org/hsqldb/lib/HsqlByte*,
+                  org/hsqldb/lib/IntValueHashMap*,
+                  org/hsqldb/lib/InOutUtil*,
+                  org/hsqldb/lib/Iterator*,
+                  org/hsqldb/lib/HsqlHeap*,
+                  org/hsqldb/lib/HsqlArray*,
+                  org/hsqldb/lib/ObjectComparator*,
+                  org/hsqldb/lib/IntKeyHashMap*,
+                  org/hsqldb/lib/Collection*,
+                  org/hsqldb/lib/*List*,
+                  org/hsqldb/lib/Set*,
+                  org/hsqldb/lib/Hash*,
+                  org/hsqldb/lib/HsqlTimer*,
+                  org/hsqldb/lib/StringConverter*,
+                  org/hsqldb/lib/StringInputStream*,
+                  org/hsqldb/lib/java/JavaSystem*,
+                  org/hsqldb/lib/FileAccess*,
+                  org/hsqldb/ClientConnection*,
+                  org/hsqldb/SchemaObject*,
+                  org/hsqldb/Collation*,
+                  org/hsqldb/HsqlNameManager*,
+                  org/hsqldb/SqlInvariants*,
+                  org/hsqldb/Constraint*,
+                  org/hsqldb/TableBase*,
+                  org/hsqldb/Table.*,
+                  org/hsqldb/lib/IntKeyIntValueHashMap*,
+                  org/hsqldb/lib/DataOutputStream*,
+                  org/hsqldb/lib/ReaderInputStream*,
+                  org/hsqldb/Scanner*,
+                  org/hsqldb/lib/StringUtil*,
+                  org/hsqldb/lib/OrderedIntHashSet*,
+                  org/hsqldb/Token*,
+                  org/hsqldb/lib/CharArrayWriter*,
+                  org/hsqldb/resources/sql-state-messages.properties,
+                  org/hsqldb/jdbc/JDBC*,
+                  org/hsqldb/jdbc/Util*,
+                  org/hsqldb/jdbc/pool/*,
+                  org/hsqldb/rowio/RowOutputBase*,
+                  org/hsqldb/rowio/RowInputBase*,
+                  org/hsqldb/rowio/RowOutputBinary*,
+                  org/hsqldb/rowio/RowInputBinary*,
+                  org/hsqldb/rowio/RowOutputInterface*,
+                  org/hsqldb/rowio/RowInputInterface*,
+                  org/hsqldb/persist/HsqlDatabaseProperties*,
+                  org/hsqldb/persist/HsqlProperties*,
+                  org/hsqldb/store/ValuePool*,
+                  org/hsqldb/store/HashIndex*,
+                  org/hsqldb/store/BaseHashMap*,
+                  org/hsqldb/types/*,
+                  org/hsqldb/Column*,
+                  org/hsqldb/DatabaseURL*,
+                  org/hsqldb/HSQLClient*,
+                  org/hsqldb/HsqlDateTime*,
+                  org/hsqldb/HsqlException*,
+                  org/hsqldb/server/HsqlSocketFactory*,
+                  org/hsqldb/HTTPClientConnection*,
+                  org/hsqldb/jdbcDriver*,
+                  org/hsqldb/Row*,
+                  org/hsqldb/SessionInterface*,
+                  org/hsqldb/types/Types*,
+                  org/hsqldb/resources/BundleHandler*,
+                  org/hsqldb/resources/sql-error-messages*
+                  '/>
+
+    <fileset id='utilclasses' dir='classes' includes='
+         org/hsqldb/util/**
+         org/hsqldb/lib/*Log*
+      '/>
+
+    <fileset id='sqltoolclasses' dir='classes'
+      includes='org/hsqldb/cmdline/**/*.class
+                  org/hsqldb/lib/RCData*
+                  org/hsqldb/lib/RefCapablePropertyResourceBundle*
+                  org/hsqldb/lib/RefCapableRBInterface*
+                  org/hsqldb/lib/ValidatingResourceBundle*
+                  org/hsqldb/lib/AppendableException*
+                  org/hsqldb/lib/FileAccess*
+                  org/hsqldb/lib/StringUtil*
+                  org/hsqldb/lib/BasicTextJdkLogFormatter*
+                  org/hsqldb/lib/FrameworkLogger*
+                  org/hsqldb/resources/jdklogging-default.properties
+                  '/>
+    <fileset id='sqltoolres' dir='classes'
+        includes='org/hsqldb/cmdline/**/*.text
+                  org/hsqldb/cmdline/**/*.properties
+                  '/>
+
+    <target name="sqltool" depends="classes15, -cmdline, -prep-license-files"
+            description="Build 'sqltool.jar' file">
+      <fail unless="ant.java.iscjava15"
+            message="Can't build sqltool with JVM less than v. 1.5"/>
+       <jar jarfile="lib/sqltool.jar" compress="true" filesonly="true">
+         <metainf dir="doc" includes="*_lic.txt"/>
+         <manifest>
+             <attribute name='Specification-Title' value='${hsqldb.title}'/>
+             <attribute name='Specification-Version' value='${hsqldb.version}'/>
+             <attribute name='Specification-Vendor' value='${hsqldb.vendor}'/>
+             <attribute name='Implementation-Title' value='SqlTool Client'/>
+             <attribute name='Implementation-Version' value='${build.label}'/>
+             <attribute name='Implementation-Vendor' value='${build.vendor}'/>
+             <attribute name='Main-Class' value='org.hsqldb.cmdline.SqlTool'/>
+             <attribute name='Class-Path'
+              value='hsqldb-2.0.0.jar hsqljdbc-2.0.0.jar hsqldbmain.jar-2.0.0.jar hsqldb.jar hsqljdbc.jar hsqldbmain.jar'/>
+         </manifest>
+         <fileset refid='sqltoolclasses'/>
+         <fileset refid='sqltoolres'/>
+       </jar>
+    </target>
+
+<!-- classes referenced by the org.hsqldb.jdbc package classes -->
+<!-- or the org.hsqldb.jdbcDriver class are included here with some -->
+<!-- ommissions where the calling methods are not actually used -->
+    <target name="hsqljdbc" depends="classes16, -prep-license-files"
+             description="Build the hsqljdbc.jar for network clients">
+        <jar jarfile="lib/hsqljdbc.jar" compress="true">
+         <service type="java.sql.Driver" provider="org.hsqldb.jdbc.JDBCDriver"/>
+         <metainf dir="doc" includes="*_lic.txt"/>
+         <manifest>
+             <attribute name='Specification-Title' value='${hsqldb.title}'/>
+             <attribute name='Specification-Version' value='${hsqldb.version}'/>
+             <attribute name='Specification-Vendor' value='${hsqldb.vendor}'/>
+             <attribute name='Implementation-Title'
+                        value='JDBC client runtime'/>
+             <attribute name='Implementation-Version' value='${build.label}'/>
+             <attribute name='Implementation-Vendor' value='${build.vendor}'/>
+         </manifest>
+          <fileset refid='jdbcclasses'/>
+        </jar>
+    </target>
+
+    <target name="hsqldbutil" depends="util, swing, -prep-license-files"
+            description="Build the utility hsqldbutil.jar">
+        <jar jarfile="lib/hsqldbutil.jar" compress="true">
+         <metainf dir="doc" includes="*_lic.txt"/>
+         <manifest>
+             <attribute name='Specification-Title' value='${hsqldb.title}'/>
+             <attribute name='Specification-Version' value='${hsqldb.version}'/>
+             <attribute name='Specification-Vendor' value='${hsqldb.vendor}'/>
+             <attribute name='Implementation-Title'
+                        value='Utilities runtime, without JDBC driver'/>
+             <attribute name='Implementation-Version' value='${build.label}'/>
+             <attribute name='Implementation-Vendor' value='${build.vendor}'/>
+             <attribute name='Main-Class' value='org.hsqldb.cmdline.SqlTool'/>
+             <attribute name='Class-Path'
+                        value='hsqldb-2.0.0.jar hsqldbmain.jar hsqldb.jar'/>
+         </manifest>
+         <fileset refid='utilclasses'/>
+         <fileset refid='sqltoolclasses'/>
+         <fileset refid='sqltoolres'/>
+      </jar>
+    </target>
+
+    <target name="-doclink-1.6" if="ant.java.iscjava16">
+        <!-- CHANGEME:  use official jdk 1.6 and JEE 5 links
+                        when glassfish/mustang are finalized -->
+        <property name="jse.doc.link"
+                  value="http://java.sun.com/javase/6/docs/api/"/>
+        <property name="jee.doc.link"
+                  value="http://java.sun.com/j2ee/1.4/docs/api/"/>
+    </target>
+
+    <target name="-doclink-1.4"
+            depends="-doclink-1.6"
+            if="ant.java.iscjava14"
+            unless="ant.java.iscjava16">
+        <property name="jse.doc.link"
+                  value="http://java.sun.com/j2se/1.4.2/docs/api/"/>
+        <property name="jee.doc.link"
+                  value="http://java.sun.com/j2ee/1.4/docs/api/"/>
+    </target>
+
+    <target name="-doclink-1.2"
+            depends="-doclink-1.4"
+            if="ant.java.iscjava12"
+            unless="ant.java.iscjava14">
+        <property name="jse.doc.link"
+                  value="http://java.sun.com/j2se/1.3/docs/api/"/>
+        <property name="jee.doc.link"
+                  value="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/"/>
+    </target>
+
+    <target name="javadoc" depends="-prepare-javadoc,-set-jvmvars,-doclink-1.2"
+            description="Create javadoc for the distribution package">
+      <!-- TODO:  Find out why JDBCDriver class is listed twice in the lass
+           list pane, but only when All Classes selected
+           only listed once if jdbc package is selected). -->
+      <javadoc
+           sourcefiles="src/org/hsqldb/jdbc/JDBCDriver.java,
+                        src/org/hsqldb/Trigger.java,
+                        src/org/hsqldb/server/Server.java,
+                        src/org/hsqldb/server/WebServer.java,
+                        src/org/hsqldb/server/ServerAcl.java,
+                        src/org/hsqldb/sample/TriggerSample.java,
+                        src/org/hsqldb/sample/SqlFileEmbedder.java,
+                        src/org/hsqldb/lib/RCData.java,
+                        src/org/hsqldb/lib/tar/DbBackup.java,
+                        src/org/hsqldb/test/TestScriptRunner.java,
+                        src/org/hsqldb/cmdline/SqlFile.java,
+                        src/org/hsqldb/util/MainInvoker.java,
+                        src/org/hsqldb/cmdline/SqlTool.java"
+           destdir="doc/apidocs"
+           stylesheetfile="doc-src/apidocs/javadoc.css"
+           docencoding="UTF-8"
+           charset="UTF-8"
+           author="true"
+           version="false"
+           use="true"
+           public="true"
+           failonerror="true"
+           windowtitle="${hsqldb.title} ${hsqldb.version} API"
+           doctitle="${hsqldb.title} ${hsqldb.version}"
+           bottom="&lt;i&gt;Copyright &#169; 2001 - 2009 HSQL Development Group.&lt;/i&gt;">
+           <classpath>
+             <pathelement location="${servletapi.lib}"/>
+             <pathelement location="${junit38.lib}"/>
+           </classpath>
+           <packageset dir='src'>
+               <include name='org/hsqldb/jdbc'/>
+           </packageset>
+           <link href="${jse.doc.link}"/>
+           <link href="${jee.doc.link}"/>
+           <tag name="todo" enabled="false"/>
+           <tag name="revised" enabled="false"/>
+           <tag name="jboss.xmbean" enabled="false"/>
+           <tag name="jmx.mbean" enabled="false"/>
+           <tag name="jmx.managed-attribute" enabled="false"/>
+           <tag name="jmx.managed-operation" enabled="false"/>
+           <tag name="jmx.managed-operation-parameter" enabled="false"/>
+     </javadoc>
+     <fixcrlf preservelastmodified='true' eol="lf" encoding="UTF-8"
+         srcdir="doc/apidocs" includes="**/*.css, **/*.html, **/package-list"/>
+   </target>
+
+   <target name="javadocdev"
+            depends="-prepare-javadoc,-set-jvmvars,-doclink-1.2"
+            description="Create javadoc for all HSQLDB code-base classes">
+      <javadoc
+           destdir="doc/apidocs"
+           docencoding="UTF-8"
+           stylesheetfile="doc-src/apidocs/javadoc.css"
+           charset="UTF-8"
+           linksource="true"
+           author="true"
+           version="true"
+           use="true"
+           package="true"
+           failonerror="true"
+           windowtitle="${hsqldb.title} ${hsqldb.version} Product Dev. API"
+           doctitle="${hsqldb.title} ${hsqldb.version} Product"
+           bottom="&lt;i&gt;Copyright &#169; 2001 - 2009 HSQL Development Group.&lt;/i&gt;">
+           <fileset dir="src" includes="**/*.java"/>
+           <!-- Fileset is really good for maintenance and control purposes,
+                but it makes the generator produce an incredible amount of
+                output when there are no errors.  The verbose attribute
+                doesn't help at all. -->
+           <classpath>
+             <pathelement path="${java.class.path}"/>
+             <pathelement location="${junit38.lib}"/>
+             <pathelement location="${servletapi.lib}"/>
+           </classpath>
+           <link href="${jse.doc.link}"/>
+           <link href="${jee.doc.link}"/>
+           <tag name="todo"/>
+           <tag name="revised"/>
+           <tag name="jboss.xmbean"/>
+           <tag name="jmx.mbean"/>
+           <tag name="jmx.managed-attribute"/>
+           <tag name="jmx.managed-operation"/>
+           <tag name="jmx.managed-operation-parameter"/>
+     </javadoc>
+     <fixcrlf preservelastmodified='true' eol="lf" encoding="UTF-8"
+         srcdir="doc/apidocs" includes="**/*.css, **/*.html, **/package-list"/>
+   </target>
+
+    <target name="sqlfile-scanner"
+            description="Run JFlex to regenerate SqlFileScanner.java">
+      <delete file="src/org/hsqldb/cmdline/sqltool/SqlFileScanner.java"/>
+      <antcall target="-sqlfile-scanner"/>
+    </target>
+
+    <target name="-sqlfile-scanner">
+      <!-- Prepares SqlFileScanner.java, running Jflex only if needed.
+           Purpose here is to require jflex library only if user modifies
+           the *.flex file.
+      -->
+
+      <!-- We no longer remove SqlFileScanner.java automatically.
+           We can't depend on file timestamps, because Subversion doesn't
+           preserve them, so we must depend on the user to manually remove
+           SqlFileScanner.java if they want it regenerated.
+      <dependset>
+        <srcfilelist dir="src/org/hsqldb/cmdline">
+          <file name="sqltool.flex"/>
+        </srcfilelist>
+        <targetfilelist dir="src/org/hsqldb/cmdline/sqltool">
+          <file name="SqlFileScanner.java"/>
+        </targetfilelist>
+      </dependset>
+      -->
+      <available property="skip.jflex" type="file"
+                 file="src/org/hsqldb/cmdline/sqltool/SqlFileScanner.java"/>
+      <antcall target="-condl-jflex"/>
+      <!-- JFlex will only run if SqlFileScanner.java does not exist -->
+      <copy todir="${swsrc}/org/hsqldb/cmdline/sqltool"
+            file="src/org/hsqldb/cmdline/sqltool/SqlFileScanner.java"/>
+    </target>
+
+    <target name="-init-jflex">
+      <available property='_jflex_available' classpath='${jflex.lib}'
+                 classname='JFlex.anttask.JFlexTask'/>
+      <fail unless='_jflex_available'
+            message="Place JFlex library at '${jflex.lib}', or set property 'jflex.lib' (available from http://sourceforge.net/projects/jflex/)"/>
+      <taskdef classname="JFlex.anttask.JFlexTask" name="jflex"
+               classpath='${jflex.lib}'/>
+     </target>
+
+    <target name="-condl-jflex" unless="skip.jflex">
+      <!-- Only reason for this method is that target dependencies (if/unless)
+      get executed BEFORE the main target -->
+      <antcall target="jflex"/>
+    </target>
+
+    <target name="jflex" depends="-init-jflex">
+        <jflex file="src/org/hsqldb/cmdline/sqltool.flex" destdir="src"/>
+        <!-- A limitation of the jflex task is that you must specify the .flex
+             files individually and explicitly.  No filesets, etc. -->
+    </target>
+
+    <target name="-update-switch-branch" unless="switch.inplace">
+       <mkdir dir='${swsrc}'/>
+       <copy todir='${swsrc}' preservelastmodified='true'>
+           <fileset dir='src' includes='**/*.java'/>
+       </copy>
+    </target>
+
+    <target name="-clean-switch-branch" unless="switch.inplace">
+        <delete dir="${swsrc}"/>
+    </target>
+
+    <target name="update-readme"
+        description="Update the version number in the root readme.txt file">
+      <!-- Want to have this target depended upon by some other target that
+           is always run after changing the version yet before tagging a
+           release.
+           Unfortunately, there is no such target, since somebody could do all
+           testing, then change the version number right before tagging. :(
+           Therefore, instead of automating, we just have the distribution
+           assembly task fail if the readme.txt is not up to date w/ version.
+           (Can't actually change readme.txt when assembling, since tagging
+           must be completed before-hand).
+      -->
+      <copy file="doc-src/readme-template.txt" tofile="readme.txt"
+            overwrite="true">
+        <filterchain> <expandproperties/> </filterchain>
+      </copy>
+    </target>
+
+    <!-- ***********************************************************
+    *************   DOCBOOK v.5 BUILD SYSTEM   *********************
+    *************************************************************-->
+  <!-- See the file doc-src/readme-docauthors.txt for details about out DocBook
+       build system.  -->
+  <import file="build-docbook.xml"/>
+
+  <target name="-prep-images">
+    <fail unless="dbimage.path">Ant property 'dbimage.path' is
+required.  This is normally the "images" subdirectory of a DocBook v.5 NS Style
+Sheet distribution.  The docbook-xsl-ns distro can be downloaded from
+'http://docbook.sourceforge.net/projects/docbook'.  Set property 'dbimage.path'
+to the local path to the images subdirectory (perhaps in file
+'build.properties').</fail>
+    <copy todir="doc-src/images/db">
+      <fileset dir="${dbimage.path}"/>
+    </copy>
+  </target>
+
+  <target name="gen-docs" description="Generate Docbook documents for project"
+          depends="validate-docs, -prep-images, -gen-docs-setup">
+    <antcall target="docbook-transform">
+      <param name="doc.name" value="guide"/>
+    </antcall>
+    <antcall target="docbook-transform">
+      <param name="doc.name" value="util-guide"/>
+    </antcall>
+    <antcall target="-gen-docs-complete"/>
+  </target>
+
+  <target name="validate-docs"
+          description="Validate project DocBook source files using a modified version of Sun's MSV Validator">
+    <antcall target="validate-doc">
+      <param name="doc.name" value="guide"/>
+    </antcall>
+    <antcall target="validate-doc">
+      <param name="doc.name" value="util-guide"/>
+    </antcall>
+  </target>
+
+  <target name="-ensure-catalog" unless="_catalog.present">
+    <copy file="build/rng-catalog-sample.xml"
+          tofile="stylesheets/rng-catalog.xml"/>
+    <echo>Just created a local 'stylesheets/rng-catalog.xml' file for you.
+To speed up XML validations, you should edit this file.</echo>
+  </target>
+
+  <target name="-validation-setup">
+    <available property="_catalog.present" file="stylesheets/rng-catalog.xml"
+               type="file"/>
+    <antcall target="-ensure-catalog"/>
+  </target>
+
+  <target name="-prep-license-files">
+    <fixcrlf destdir="doc" preservelastmodified='true' eol="crlf"
+             srcdir="doc-src" includes="*_lic.txt"/>
+  </target>
+</project>
diff --git a/build/cfdistro.bash b/build/cfdistro.bash
new file mode 100755
index 0000000..0907de0
--- /dev/null
+++ b/build/cfdistro.bash
@@ -0,0 +1,119 @@
+#!/bin/bash -p
+PROGNAME="${0##*/}"
+
+# Copyright (c) 2001-2009, The HSQL Development Group
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of the HSQL Development Group nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script generates a concise listing of differences between two
+# distributions.
+# This script obviously requires Bash.  I don't know whether it works on Cygwin.
+
+# You run this script against two directory branches.
+# If you are starting with two zip distributions, you must extract them first.
+# If you are going to investigate differences, then set up the distribution
+# directories so that the highest directories of interest are peers, like
+#    cd /tmp/me
+#    mkdir cfdir
+#    unzip -q /tmp/hsqldb-x1.zip
+#    mv hsqldb-x1/hsqldb cfdir/x1
+#    unzip -q /tmp/hsqldb-x2.zip
+#    mv hsqldb-x2/hsqldb cfdir/x2
+#    cd cfdir
+#    /path/to/cfdistro.bash x1 x2
+# It is then very easy to view differences between the distributions textually
+# or graphically.  If your file difference report (".../files.diff") contains
+#  < hsqldb/testrun/hsqldb/TestSelf.txt  -rw-r--r-- 1 blaine blaine   52585
+#  > hsqldb/testrun/hsqldb/TestSelf.txt  -rw-r--r-- 1 blaine blaine   52587
+# then you use vim to check encodings and fileformat (EOLs), diff for
+# differences in text, or gvimdiff for diffrences graphically.
+#   gvim */hsqldb/testrun/hsqldb/TestSelf.txt  # Check encoding + fileformat
+#   diff */hsqldb/testrun/hsqldb/TestSelf.txt  # See differences in text
+#   gvimdiff */hsqldb/testrun/hsqldb/TestSelf.txt # See differences graphically
+
+# This script can easily be enhanced to do the extraction and directory setup
+# steps.
+# We purposefully ignore directory and file modification timestamps.
+# Modify the perl regular expressions to include or exclude other items in
+# the "ls -l" listings.
+# The generation timestamps and version labels inside of generated JavaDoc
+# output will make these files differ.  I usually manually compare an index
+# file and an actual class HTML file, then exclude the rest from the summary
+# file with a command like
+#   perl -ni -we 'print unless m:^. doc/apidocs/:;' /tmp/cfdistro-13756/files.diff
+
+shopt -s xpg_echo
+set +u
+
+Failout() {
+    echo "Aborting $PROGNAME:  $*" 1>&2
+    exit 1
+}
+[ -n "$TMPDIR" ] || TMPDIR=/tmp
+WORKDIR="$TMPDIR/${PROGNAME%.*}-$$"
+mkdir "$WORKDIR" || Failout "Failed to make work director '$WORKDIR'"
+
+type -t perl >&- || Failout "'$PROGNAME' requires 'perl' in your search path"
+
+[ $# -ne 2 ] && Failout "SYNTAX:  $PROGNAME dir1/path dir2/path"
+BASE1="$1"; shift
+BASE2="$1"; shift
+
+STARTDIR="$PWD"
+cd "$BASE1" || Failout "Failed to cd to first base dir: $BASE1"
+find * -type d | xargs ls -ld |
+    perl -nwe 'm/(.+?)200\d-\d\d-\d\d \d\d:\d\d\s+(.+)/; print "$2  $1\n";' |
+    sort > $WORKDIR/dirs.1
+find * -type f | xargs ls -ld |
+    perl -nwe 'm/(.+?)200\d-\d\d-\d\d \d\d:\d\d\s+(.+)/; print "$2  $1\n";' |
+    sort > $WORKDIR/files.1
+
+cd "$STARTDIR"
+cd "$BASE2" || Failout "Failed to cd to first base dir: $BASE2"
+find * -type d | xargs ls -ld |
+    perl -nwe 'm/(.+?)200\d-\d\d-\d\d \d\d:\d\d\s+(.+)/; print "$2  $1\n";' |
+    sort > $WORKDIR/dirs.2
+find * -type f | xargs ls -ld |
+    perl -nwe 'm/(.+?)200\d-\d\d-\d\d \d\d:\d\d\s+(.+)/; print "$2  $1\n";' |
+    sort > $WORKDIR/files.2
+
+cd "$STARTDIR"
+cd "$WORKDIR" || Failout "Failed to cd to work dir: $WORKDIR"
+declare -i retval=0
+cmp -s dirs.1 dirs.2 || {
+    ((retval = retval + 1))
+    diff dirs.1 dirs.2 | egrep '^[<>]' > dirs.diff
+    echo "See dir diffs at $WORKDIR/dirs.diff"
+}
+cmp -s files.1 files.2 || {
+    ((retval = retval + 1))
+    diff files.1 files.2 | egrep '^[<>]' > files.diff
+    echo "See dir diffs at $WORKDIR/files.diff"
+}
+
+exit $retval
diff --git a/build/ivy.xml b/build/ivy.xml
new file mode 100644
index 0000000..be04d78
--- /dev/null
+++ b/build/ivy.xml
@@ -0,0 +1,60 @@
+<ivy-module version="2.0">
+  <!-- $Id: ivy.xml 727 2009-01-08 00:19:48Z unsaved $ -->
+  <info organisation="admc" module="docbook"/>
+  <configurations>
+    <conf name="baseconf" visibility="private"/> <!-- basic XML -->
+    <conf name="admc-rs-msv"
+       description="Single Catalog-Resolving Schematron-Capable MSV jar file"/>
+    <conf name="msv" description="Sun MSV" extends="baseconf"/>
+    <conf name="xalan" description="Xalan Xslt" extends="baseconf"/>
+    <conf name="fop" description="FOP"/>
+  </configurations>
+  <dependencies>
+    <dependency name="relames" rev="20060319"
+                transitive="false" conf="msv->default"/>
+    <dependency name="msv" rev="20081113"
+                transitive="false" conf="msv->default"/>
+    <dependency name="relaxngDatatype" rev="20081113"
+                transitive="false" conf="msv->default"/>
+    <dependency name="xsdlib" rev="20081113"
+                transitive="false" conf="msv->default"/>
+    <dependency name="isorelax" rev="20081113"
+                transitive="false" conf="msv->default"/>
+    <dependency name="fop" rev="0.94"
+                transitive="false" conf="fop->default"/>
+    <dependency name="fop-hyph" rev="1.2"
+                transitive="false" conf="fop->default"/>
+    <dependency name="jai_codec" rev="1.1.3"
+                transitive="false" conf="fop->default"/>
+    <dependency name="jai_core" rev="1.1.3"
+                transitive="false" conf="fop->default"/>
+    <dependency name="xmlgraphics-commons" rev="1.2"
+                transitive="false" conf="fop->default"/>
+    <dependency name="avalon-framework" rev="4.2.0"
+                transitive="false" conf="fop->default"/>
+    <dependency name="batik-all" rev="1.6"
+                transitive="false" conf="fop->default"/>
+    <dependency name="commons-io" rev="1.3.1"
+                transitive="false" conf="fop->default"/>
+    <dependency name="commons-logging" rev="1.1.1"
+                transitive="false" conf="fop->default"/>
+    <dependency name="xalan" rev="2.7.1"
+                transitive="false" conf="xalan->default; msv->default"/>
+    <dependency name="serializer" rev="2.7.1"
+                transitive="false" conf="xalan->default"/>
+    <dependency name="docbook-ext-xalan2" rev="1.73.2"
+                transitive="false" conf="xalan->default"/>
+    <dependency name="xml-apis" rev="1.3"
+                transitive="false" conf="baseconf->default"/>
+    <dependency name="xercesImpl" rev="2.9.0"
+                transitive="false" conf="baseconf->default"/>
+    <dependency name="resolver" rev="1.2"
+                transitive="false" conf="msv->default"/>
+    <dependency name="admc-rs-msv" rev="1.0" transitive="false"
+                conf="admc-rs-msv->default; xalan->default"/>
+    <!-- Primary purpose of this jar is for the MSV validator.
+         It is also added to the XSLT CLASSPATH only to add the XInclude
+         settings file to the CLASSPATH.  Needed by Xalan during XSLT.
+    -->
+  </dependencies>
+</ivy-module>
diff --git a/build/ivysettings-sample.xml b/build/ivysettings-sample.xml
new file mode 100644
index 0000000..e6091c0
--- /dev/null
+++ b/build/ivysettings-sample.xml
@@ -0,0 +1,21 @@
+<ivysettings>
+<!--
+$Id: ivysettings-sample.xml 643 2008-12-29 07:08:49Z unsaved $
+
+Edit your copy of this file (named "ivysettings.xml"), or replace it completely.
+This file will work with any directory on any web server which
+holds the plain jar files with names like BASENAME-VERSION.jar.
+-->
+
+  <caches checkUpToDate="false" resolutionCacheDir="${user.home}/.ivycache"
+          ivyPattern="[module]-[revision].xml"
+          defaultCacheDir="${user.home}/.ivycache"
+          repositoryCacheDir="${user.home}/lib-repos"
+          artifactPattern="[artifact]-[revision].[ext]"/>
+  <settings defaultResolver="default"/>
+  <resolvers>
+    <url name="default">
+      <artifact pattern="${repos.url}/[artifact]-[revision].[ext]"/>
+    </url>
+  </resolvers>
+</ivysettings>
diff --git a/build/jdkcodeswitch.list b/build/jdkcodeswitch.list
new file mode 100644
index 0000000..87296c7
--- /dev/null
+++ b/build/jdkcodeswitch.list
@@ -0,0 +1,31 @@
+# Files listed here will be code-switched
+# This eliminates the need for CodeSwitcher to scan all source files.
+
+org/hsqldb/HsqlDateTime.java
+org/hsqldb/lib/tar/TarFileOutputStream.java
+org/hsqldb/lib/tar/TarGenerator.java
+org/hsqldb/lib/tar/TarReader.java
+org/hsqldb/jdbc/JDBCCallableStatement.java
+org/hsqldb/jdbc/JDBCConnection.java
+org/hsqldb/jdbc/JDBCDatabaseMetaData.java
+org/hsqldb/jdbc/JDBCDataSource.java
+org/hsqldb/jdbc/JDBCDriver.java
+org/hsqldb/jdbc/JDBCNClob.java
+org/hsqldb/jdbc/JDBCParameterMetaData.java
+org/hsqldb/jdbc/JDBCPreparedStatement.java
+org/hsqldb/jdbc/JDBCResultSet.java
+org/hsqldb/jdbc/JDBCResultSetMetaData.java
+org/hsqldb/jdbc/JDBCStatement.java
+org/hsqldb/jdbc/Util.java
+org/hsqldb/jdbc/pool/BaseConnectionWrapper.java
+org/hsqldb/jdbc/pool/JDBCConnectionPoolDataSource.java
+org/hsqldb/jdbc/pool/JDBCPooledConnection.java
+org/hsqldb/jdbc/pool/ManagedPoolDataSource.java
+org/hsqldb/jdbc/Util.java
+org/hsqldb/lib/java/JavaSystem.java
+org/hsqldb/lib/SimpleLog.java
+org/hsqldb/lib/StringConverter.java
+org/hsqldb/server/PgType.java
+org/hsqldb/test/TestBug778213.java
+org/hsqldb/util/ConnectionDialogCommon.java
+org/hsqldb/persist/Logger.java
diff --git a/build/rng-catalog-sample.xml b/build/rng-catalog-sample.xml
new file mode 100644
index 0000000..f442456
--- /dev/null
+++ b/build/rng-catalog-sample.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!-- $Id: rng-catalog-sample.xml 826 2009-01-17 05:04:52Z unsaved $ -->
+
+<!-- IMPORTANT:  To set up your build environment, edit the copy of this file
+     at "stylesheets/rng-catalog.xml", not the one at
+     "build/rng-catalog-sample.xml". -->
+
+<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN"
+    "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
+
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public">
+  <public publicId="-//OASIS/ENTITIES DocBook Character Entities V4.5//EN"
+          uri="file:../local/db4-entities/dbcentx.mod"/>
+  <!--  Set the uri value above to match the your local setting of property
+        "dbcentx.url" (perhapse in "local-docbook.properties" or
+        "build.properties").  This will eliminate the Internet dependency and
+        speed up validations.
+        Relative paths must be relative to this file.
+        If the designated hostname or file DOES NOT EXIST, the setting will
+        be ignored.  Make sure to not set to http URL for a host name that
+        does exist, with a wrong path, or the server error message will be
+        parsed!  -->
+</catalog>
diff --git a/build/run.test.suite.cmd b/build/run.test.suite.cmd
new file mode 100755
index 0000000..374aa98
--- /dev/null
+++ b/build/run.test.suite.cmd
@@ -0,0 +1,2 @@
+call setenv.cmd

+ant -f test.xml run.test.suite

diff --git a/build/setenv.cmd b/build/setenv.cmd
new file mode 100755
index 0000000..1a8d12e
--- /dev/null
+++ b/build/setenv.cmd
@@ -0,0 +1,7 @@
+REM basic environment setup

+REM change as needed

+

+set JAVA_HOME=C:\Program Files\Java\jdk1.6.0

+set ANT_HOME=C:\java\lib\ant

+set ANT_OPTS=-Xmx512m

+set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin;%PATH%

diff --git a/build/test.dbmd.convert.properties b/build/test.dbmd.convert.properties
new file mode 100644
index 0000000..8fab5cb
--- /dev/null
+++ b/build/test.dbmd.convert.properties
@@ -0,0 +1,7 @@
+## Note: 
+##
+## Most test.dbmd.convert properties have been moved to /org/hsqldb/resources
+## under the test source folder and are now read using the bundle handler facility.
+##
+## System properties now take precedence, so you can use this file
+## to override the values in the default test.dbmd.convert properties file.
diff --git a/build/test.properties b/build/test.properties
new file mode 100644
index 0000000..bd3cba6
--- /dev/null
+++ b/build/test.properties
@@ -0,0 +1,7 @@
+## Note: 
+##
+## Most test properties have been moved to /org/hsqldb/resources
+## under the test source folder and are now read using the bundle handler facility.
+##
+## System properties now take precedence, so you can use this file
+## to override the values in the default test.properties file.
diff --git a/build/test.xml b/build/test.xml
new file mode 100644
index 0000000..adb4fb5
--- /dev/null
+++ b/build/test.xml
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="hsqldb.test.suite" 
+         default="run.test.suite" 
+         basedir="..">
+
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- B U I L D  T I M E S T A M P                                         -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <tstamp>
+       <format property="_tmpstamp" 
+               pattern="yyyy/MM/dd-hh:mm:ss"
+               locale="en"/>
+   </tstamp>
+
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- U S E R  B U I L D  P R O P E R T I E S  O V E R R I D E S           -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <property file="${basedir}/build/build.properties"/>
+
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- D E F A U L T  B U I L D  P R O P E R T I E S                        -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <property name="test.suite.version" 
+             value="1.9.0"/>
+                 
+   <property name="test.suite.title"
+             value="HSQLDB Test Suite"/>
+             
+   <property name="test.suite.vendor"
+             value="The HSQL Development Group"/>
+   
+   <property name="test.suite.implementation.title"
+             value="JDBC 4 Test Cases and Utilities"/>
+             
+   <property name="test.suite.implementation.label"
+             value="private-${_tmpstamp}"/>
+             
+   <property name="test.suite.implementation.vendor"
+             value="${user.name}"/>
+             
+   <property name="sqltool.jar"
+             value="${basedir}/lib/sqltool.jar" />
+             
+   <property name="hsqldb.jar"
+             value="${basedir}/lib/hsqldb.jar" />
+             
+   <property name="hsqldbtest.jar"
+             value="${basedir}/lib/hsqldbtest.jar" />             
+             
+   <property name="junit.jar"
+             value="${basedir}/lib/junit.jar" />
+             
+   <property name="test.suite.jar"
+             value="${basedir}/lib/testsuite.jar" /> 
+             
+   <property name="test.src.dir"
+             value="${basedir}/test-src" />
+             
+   <property name="test.classes.dir"
+             value="${basedir}/test-classes" />
+             
+   <property name="test.results.dir"
+             value="${basedir}/test-results" />
+   
+   <property name="build.debug"
+             value="true" />
+             
+   <property name="build.optimize"
+             value="false" />
+             
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- B U I L D  C L A S S P A T H                                         -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <path id="test.suite.javac.classpath">
+        <pathelement location="${hsqldb.jar}"/>
+        <pathelement location="${sqltool.jar}"/>
+        <pathelement location="${junit.jar}" />
+   </path>
+   
+   <path id="test.all.classpath">
+        <pathelement location="${hsqldbtest.jar}"/>
+        <pathelement location="${junit.jar}" />
+   </path>   
+
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- S H A R E D  I N I T I A L I Z A T I O N                             -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <target name="-init">
+        <available classname="java.net.IDN" 
+                   property="ant.java.iscjava16"/>
+
+        <fail unless='ant.java.iscjava16'
+              message="JDK must be 1.6 or greater"/> 
+
+        <available file="${hsqldb.jar}" 
+                   type='file' 
+                   property="hsqldb.available"/>
+
+        <fail unless='hsqldb.available'
+              message="'hsqldb.jar' must reside at ${hsqldb.jar}"/>
+
+        <available file="${sqltool.jar}" 
+                   type='file' 
+                   property="sqltool.available"/>
+
+        <fail unless='sqltool.available'
+              message="'sqltool.jar' must reside at ${sqltool.jar}"/>
+
+        <available file="${junit.jar}" 
+                   type='file' 
+                   property="junit.available"/>
+
+        <fail unless='junit.available'
+              message="'junit.jar' must reside at ${junit.jar}"/>
+
+   </target>
+
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- M A K E  T E S T  S U I T E                                          -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <target name="make.test.suite"
+           description="Builds test classes and creates test suite jar"
+           depends="-init">
+      <mkdir dir="${test.classes.dir}"/>
+
+      <!-- Compile Classes -->
+      <javac srcdir="${test.src.dir}"
+             destdir="${test.classes.dir}"
+             debug="${build.debug}"
+             optimize="${build.optimize}"
+       >
+          <classpath refid="test.suite.javac.classpath"/>
+          <exclude name="**/TestWrapperInvocationHandler.java"/>
+          <!-- Temporarily excluding TestWrapperInvocationHandler until have
+               time to figure out how to resolve missing java.sql.* classes -->
+          <include name="**/*.java"/>
+      </javac>
+
+      <!-- Build Jar -->
+      <jar jarfile="${test.suite.jar}"
+           basedir="${test.classes.dir}">
+         <manifest>
+             <attribute name='Specification-Title' 
+                        value='${test.suite.title}'/>
+                        
+             <attribute name='Specification-Version'
+                        value='${test.suite.version}'/>
+                        
+             <attribute name='Specification-Vendor'
+                        value='${test.suite.vendor}'/>
+                        
+             <attribute name='Implementation-Title'
+                        value='${test.suite.implementation.title}'/>
+                        
+             <attribute name='Implementation-Version'
+                        value='${test.suite.implementation.label}'/>
+                        
+             <attribute name='Implementation-Vendor' 
+                        value='${test.suite.implementation.vendor}'/>
+         </manifest>
+         <include name="**/*"/>
+      </jar>
+   </target>
+   
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- R U N  T E S T  S U I T E                                            -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <target name="run.test.suite"
+           description="Runs the test suite and generates test result reports"
+           depends="-init">
+
+      <available file="${test.suite.jar}" 
+                 type='file' 
+                 property="test.suite.jar.available"/>
+                   
+      <fail unless='test.suite.jar.available'
+            message="The test suite jar must reside at ${test.suite.jar}"/>
+
+      <mkdir dir="${test.results.dir}"/> 
+      <mkdir dir="${test.results.dir}/resources"/>
+      <mkdir dir="${test.results.dir}/resources/org"/>
+      <mkdir dir="${test.results.dir}/resources/org/hsqldb"/>
+      <mkdir dir="${test.results.dir}/resources/org/hsqldb/util"/>
+      <mkdir dir="${test.results.dir}/resources/org/hsqldb/util/preprocessor"/>
+
+      <copy todir="${test.results.dir}/resources/org/hsqldb/util/preprocessor">
+           <fileset dir="${test.src.dir}/org/hsqldb/util/preprocessor" 
+                  includes="*.exp"/>
+      </copy>
+      <copy todir="${test.results.dir}/resources/org/hsqldb/util/preprocessor">
+           <fileset dir="${test.src.dir}/org/hsqldb/util/preprocessor" 
+                  includes="*.inc"/>
+      </copy>
+      <copy todir="${test.results.dir}/resources/org/hsqldb/util/preprocessor">
+          <fileset dir="${test.src.dir}/org/hsqldb/util/preprocessor" 
+                   includes="*.src"/>
+      </copy>
+
+      <mkdir dir="${test.results.dir}/resources/org/hsqldb/jdbc"/>
+	  
+      <copy todir="${test.results.dir}/resources/org/hsqldb/jdbc">
+         <fileset dir="${test.src.dir}/org/hsqldb/jdbc"
+                  includes="*.sql"/>
+      </copy>
+	  
+      <mkdir dir="${test.results.dir}/resources/org/hsqldb/jdbc/resources"/>
+      <mkdir dir="${test.results.dir}/resources/org/hsqldb/jdbc/resources/xml"/>      
+
+      <copy todir="${test.results.dir}/resources/org/hsqldb/jdbc/resources/xml">
+         <fileset dir="${test.src.dir}/org/hsqldb/jdbc/resources/xml"
+                  includes="*.*"/>
+      </copy>
+      
+      <mkdir dir="${test.results.dir}/resources/org/hsqldb/jdbc/resources/sql"/>
+      
+      <copy todir="${test.results.dir}/resources/org/hsqldb/jdbc/resources/sql">
+         <fileset dir="${test.src.dir}/org/hsqldb/jdbc/resources/sql"
+                  includes="*.*"/>
+      </copy> 
+
+      <mkdir dir="${test.results.dir}/resources/org/hsqldb/resources"/>	  
+
+      <copy todir="${test.results.dir}/resources/org/hsqldb/resources">
+	     <fileset dir="${test.src.dir}/org/hsqldb/resources" includes="*.*"/>
+      </copy>  
+
+	  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+      <!-- U S E R  T E S T  P R O P E R T I E S                                -->
+	  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+	  <!-- Now using BundleHandler facility as primary properties loader, but   -->
+	  <!-- System properties still work (e.g. on command line -Dfoo=xyz or      --> 
+	  <!-- using Ant to load properties files) and now take  precedence over    -->
+	  <!-- bundle handler resources.                                            -->
+	  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+	  <!-- In this way, the bulk of the standard properties (that will probably -->
+	  <!-- never need to be overriden) stay under the test source folder, hence -->
+      <!-- only specific property overrides need to be placed in the build      -->
+      <!-- folder properties files or on the command line as -Dx=y directives.  -->	  
+	  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+	  <!-- The only (minor) disadvantage of this new scheme is that the bulk of -->
+	  <!-- the test properties will no longer show up in the test report output -->
+	  <!-- as environment settings                                              -->
+	  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+      <property file="${basedir}/build/test.properties"/>
+      <property file="${basedir}/build/test.dbmd.convert.properties"/>
+
+      <!-- Execute JUNIT Tests -->
+      <junit showoutput="true" 
+             fork="false"
+             failureproperty="tests.failed" 
+             errorproperty="tests.failed" >
+          <batchtest todir="${test.results.dir}">
+              <fileset dir="${test.src.dir}" 
+                       includes="**/*Test.java"/>
+          </batchtest>
+          <classpath>
+              <pathelement location="${test.results.dir}/resources"/>
+              <path path="${hsqldb.jar}"/>
+              <path path="${junit.jar}"/>
+              <path path="${test.suite.jar}"/>
+          </classpath>
+          <syspropertyset id="test.suite.system.properties">
+            <propertyref prefix="hsqldb.test.suite."/>
+          </syspropertyset>
+          <formatter type="xml"/>
+      </junit>
+
+      <mkdir dir="${test.results.dir}/reports"/>
+      <mkdir dir="${test.results.dir}/reports/html"/>
+
+      <!-- Generate Test Reports -->
+      <junitreport todir="${test.results.dir}/reports">
+          <fileset dir="${test.results.dir}">
+              <include name="TEST-*.xml"/>
+          </fileset>
+          <report format="frames" 
+                  todir="${test.results.dir}/reports/html"/>
+      </junitreport>
+   </target>
+   
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- R U N  T E S T  A L L                                                -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->   
+   <target name="run.test.all"
+           description="Runs the org.hsqldb.test.TestAll set of tests.">
+       
+      <available file="${hsqldbtest.jar}" 
+                 type='file' 
+                 property="hsqldbtest.jar.available"/>
+                 
+       <java classname="org.hsqldb.test.TestAll" 
+             classpathref="test.all.classpath" 
+             dir="${basedir}/testrun/hsqldb" 
+             fork="true"/>
+   </target>   
+   
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <!-- C L E A N  T E S T  S U I T E                                        -->
+   <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+   <target name="clean.test.suite"
+           description="Deletes compiled classes, test results and suite jar">
+      <delete dir="${test.classes.dir}" />
+      <delete dir="${test.results.dir}" />
+      <delete file="${test.suite.jar}" />
+   </target>
+
+</project>
diff --git a/doc-src/altformats-sect.xml b/doc-src/altformats-sect.xml
new file mode 100644
index 0000000..7d54756
--- /dev/null
+++ b/doc-src/altformats-sect.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!-- This file is included into docbook source files.  -->
+<!-- $Id: altformats-sect.xml 738 2009-01-08 20:19:53Z unsaved $ -->
+
+<!DOCTYPE section [
+  <!ENTITY % dummy24 SYSTEM "entities/global.ent"> %dummy24;
+]>
+
+<section xmlns="http://docbook.org/ns/docbook" version="5.0"
+         xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="altformats-sect">
+  <title>Available formats for this document</title>
+  <simpara>This document is available in several formats.</simpara>
+  <simpara>
+      You may be reading this document right now at &distro_baseurl;, or in
+      a distribution somewhere else.
+      I hereby call the document distribution from which you are reading 
+      this, your <emphasis>current distro</emphasis>.
+  </simpara>
+  <simpara>
+      &distro_baseurl; hosts the latest production versions of all available formats.
+      If you want a different format of the same <emphasis>version</emphasis>
+      of the document you are reading now, then you should try your
+      current distro.
+      If you want the latest production version, you should try &distro_baseurl;.
+  </simpara>
+  <simpara>
+      Sometimes, distributions other than &distro_baseurl; do not host all
+      available formats.
+      So, if you can't access the format that you want in your current
+      distro, you have no choice but to use the newest production version at 
+      &distro_baseurl;.
+  </simpara>
+
+  <para>
+    <table xml:id="altformats-tbl" frame="all" tocentry="1">
+      <title>Available formats of this document</title>
+      <!-- <tgroup cols="3" align="left" colsep="1" rowsep="1"> -->
+      <tgroup cols="3" align="left">
+        <colspec colwidth="3cm"/>
+        <colspec colwidth="4cm"/>
+        <colspec/>
+      <thead><row>
+          <entry>format</entry>
+          <entry>your distro</entry>
+          <entry>at &distro_baseurl;</entry>
+      </row></thead>
+      <tbody>
+      <row>
+          <entry>
+              Chunked HTML
+          </entry><entry>
+              <link xlink:href="index.html"/>
+          </entry><entry>
+          <link xlink:href="&distro_baseurl;/&doc_basename;/"/>
+          </entry>
+      </row><row>
+          <entry>
+              All-in-one HTML
+          </entry><entry>
+              <link xlink:href="&doc_basename;.html"/>
+          </entry><entry>
+        <link xlink:href="&distro_baseurl;/&doc_basename;/&doc_basename;.html"/>
+          </entry>
+      </row><row>
+          <entry>
+              PDF
+          </entry><entry>
+              <link xlink:href="&doc_basename;.pdf"/>
+          </entry><entry>
+          <link xlink:href="&distro_baseurl;/&doc_basename;/&doc_basename;.pdf"/>
+          </entry>
+      </row>
+      </tbody>
+      </tgroup>
+    </table>
+    If you are reading this document now with a standalone PDF reader, the
+    <guilabel>your distro</guilabel> links may not work.
+  </para>
+</section>
diff --git a/doc-src/apidocs/hsqldb.gif b/doc-src/apidocs/hsqldb.gif
new file mode 100644
index 0000000..3585222
--- /dev/null
+++ b/doc-src/apidocs/hsqldb.gif
Binary files differ
diff --git a/doc-src/apidocs/javadoc.css b/doc-src/apidocs/javadoc.css
new file mode 100644
index 0000000..5b3fb93
--- /dev/null
+++ b/doc-src/apidocs/javadoc.css
@@ -0,0 +1,91 @@
+/* Javadoc style sheet */
+
+/* Define colors, fonts and other style attributes here to override the defaults */
+
+/* Page background color, width % */
+body { background-color: #FFFFFF; padding-right: 1em; }
+
+/* Table colors */
+.TableHeadingColor     { background: #CCCCFF } /* Dark mauve */
+.TableSubHeadingColor  { background: #EEEEFF } /* Light mauve */
+.TableRowColor         { background: #FFFFFF } /* White */
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont   { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+.FrameHeadingFont { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+.FrameItemFont    { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+
+/* Example of smaller, sans-serif font in frames */
+/* .FrameItemFont  { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */
+
+/* Navigation bar fonts and colors */
+.NavBarCell1    { background-color: #EEEEFF;}/* Light mauve */
+.NavBarCell1Rev { background-color: #00008B;}/* Dark Blue */
+.NavBarFont1    { font-family: Arial, Helvetica, sans-serif; color: #000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color: #FFFFFF;}
+
+.NavBarCell2    { font-family: Arial, Helvetica, sans-serif; background-color: #FFFFFF;}
+.NavBarCell3    { font-family: Arial, Helvetica, sans-serif; background-color: #FFFFFF;}
+
+.GenericDocumentation { color: #000000; }
+
+DIV.ReleaseSpecificDocumentation { 
+        color:              #006A00;
+        background-color:   #EEEEFF;
+        border:             2px ridge white;
+        padding-top:        5px;
+        padding-right:      10px;
+        padding-bottom:     5px;
+        padding-left:       10px;
+        text-align:         justify;
+}
+
+DIV.ReleaseSpecificDocumentation h3 {
+	margin-top:         0px;
+	margin-left:        0px;
+	margin-right:       0px;
+        padding-top:        14px;
+        padding-right:      0px;
+        padding-bottom:     15px;
+        padding-left:       50px;
+        border-top:         1px dashed rgb(120,172,255);
+	border-bottom:      1px dashed rgb(120,172,255);
+        background:         url(hsqldb.gif) #E6E6FF no-repeat left center;
+}
+
+PRE.JavaCodeExample   { 
+        color:              #000000; 
+        background-color:   #EEEEEE;
+        border:             1px ridge white;
+        padding-top:        1em;
+        padding-right:      1em;
+        padding-bottom:     0em;
+        padding-left:       1em;
+}
+
+.JavaStringLiteral { color: #99006B; }
+.JavaNumericLiteral { color: #780000; }
+.JavaKeyWord       { color: #000099; font-weight: bold; }
+
+PRE.SqlCodeExample   {
+        /*color:              #550022;*/
+        color:              #601030; 
+        background-color:   #EEEEEE; 
+        border:             1px ridge white;
+        font-weight:        bold;
+        padding-top:        1em;
+        padding-right:      1em;
+        padding-bottom:     0em;
+        padding-left:       1em;
+        line-height:        150%;
+}
+
+PRE.GeneralExample   {
+        color:              #000000; 
+        background-color:   #EEEEEE; 
+        border:             1px ridge white;
+        padding-top:        1em;
+        padding-right:      1em;
+        padding-bottom:     0em;
+        padding-left:       1em;
+}
diff --git a/doc-src/branding-frag.xhtml b/doc-src/branding-frag.xhtml
new file mode 100644
index 0000000..5f30c34
--- /dev/null
+++ b/doc-src/branding-frag.xhtml
@@ -0,0 +1,5 @@
+<!-- $Id: branding-frag.xhtml 3510 2010-03-08 17:38:55Z unsaved $ -->
+
+<div class="branding">
+  <img src="../images/hypersql_logo.png"/>
+</div>
diff --git a/doc-src/docbook.css b/doc-src/docbook.css
new file mode 100644
index 0000000..0890083
--- /dev/null
+++ b/doc-src/docbook.css
@@ -0,0 +1,106 @@
+/* COMMENT:  The shared.css stylesheet for the hsqldb/docs directory and elsewhere *?
+/* This material is published under the Copyrights and Licenses listed at */
+/* and in the directory /hsqldb/docs/hsqldb_lic.txt */
+
+a:visited { color: #000080; }
+a:link { color: #0000BB; }
+a:active { color: #0000FF; }
+
+span.guibutton, span.guilabel, span.guimenu, span.guimenuitem, span.guisubmenu {
+    color: #000080;
+    font-family:sans-serif;
+}
+span.guibutton, span.guilabel {
+    font-weight:bold;
+}
+span.guimenu, span.guimenuitem, span.guisubmenu {
+    font-style:italic;
+}
+
+div.caption      { font-size: 80%; }
+
+/********** Admonitions *****************/
+div.tip, div.note {
+    background-color:#FFE4E1;
+    border:2px solid gray;
+}
+div.warning, div.caution, div.important {
+    background-color:#FFE4E1;
+    border:2px solid black;
+}
+/****************************************/
+
+pre.screen         {
+    background-color:#F5F5F5;
+    border:1px solid gray;
+    padding:5px;
+    font-family:monospace;
+}
+
+pre.programlisting {
+    background-color:#F0F8FF;
+    border:1px solid gray;
+    padding:5px;
+    font-family:monospace;
+}
+
+div.variablelist {
+    border:1px solid gray;
+    padding:2px;
+}
+
+span.term {  /* in a variablelist, also in dl dt */
+    font-weight:bold;
+    padding-left:3px; padding-right:3px;
+    color:#000080;
+}
+
+div.itemizedlist ul.disc li {
+    margin-bottom:3px;
+}
+
+h1.title {
+    font-size: 200%; /* Book title */
+    color:#000080;
+}
+h2.subtitle { font-size: 140%; } /* Book subtitle */
+div.chapter h2.title, div.preface h2.title, div.appendix h2.title, div.index h2.title {
+    /* All components */
+    font-size: 170%;
+    font-weight: bold;
+    color: #000080;
+}
+div.chapter h2.subtitle, div.preface h2.subtitle, div.appendix h2.subtitle, div.index h2.subtitle {
+    font-size: 130%;
+}
+div.section h2.title {
+    /* level1 sections */
+    font-size: 150%;
+    font-weight: bold;
+    color: #000080;
+}
+div.section h3.title {
+    /* level2 sections */
+    font-size: 130%;
+    font-weight: bold;
+}
+div.section h4.title {
+    /* level3 sections */
+    font-size: 123%;
+    font-weight: bold;
+}
+div.section h5.title {
+    /* level4 sections */
+    font-size: 116%;
+    font-weight: bold;
+}
+
+span.remark        {
+    background-color:#32cd32;
+    font:normal bold 12px sans-serif;
+    border:2px solid green; padding-left:2px; padding-right:2px;
+}
+
+img { border:0; padding:0; margin:0; }
+
+p.copyright { font-family:sans-serif; }
diff --git a/doc-src/entities/global.ent b/doc-src/entities/global.ent
new file mode 100644
index 0000000..8962206
--- /dev/null
+++ b/doc-src/entities/global.ent
@@ -0,0 +1,26 @@
+<!-- Project-specific entities which should be loaded into every source file -->
+<!-- $Id: global.ent 826 2009-01-17 05:04:52Z unsaved $ -->
+
+<!ENTITY % dummy33 PUBLIC
+           "-//HSQLDB/ENTITIES/DocSpecificDynamicEntities"
+           "validation_only.ent"> %dummy33;
+<!-- validation_only.ent contains dummy values. Catalog-switched by XSLT. -->
+
+<!-- These two settings are used by some of OASIS's multi-language
+     documents.  If you are only using entity files that you have written,
+     you won't need to set these. -->
+<!ENTITY % sgml.features "IGNORE">
+<!ENTITY % xml.features "INCLUDE">
+
+<!ENTITY % dummy31 PUBLIC
+           "-//OASIS/ENTITIES DocBook Character Entities V4.5//EN"
+           "http://www.docbook.org/xml/4.5/dbcentx.mod"> %dummy31;
+<!-- Load a named resource.  Where these are loaded from may be dynamically
+     overridden with "catalogs".
+     Since these entities are needed both for validation and for XSLT
+     transormation, we must specify the overriding value both in our catalog
+     file and in the xmlcatalog element in build.xml.
+     The example here is rather useful, because this pulls in the standard
+     DocBook character entities, and allows to dynamically pull the entities
+     from a http server or a local DocBook installation, for example.
+-->
diff --git a/doc-src/entities/validation_only.ent b/doc-src/entities/validation_only.ent
new file mode 100644
index 0000000..cea6a99
--- /dev/null
+++ b/doc-src/entities/validation_only.ent
@@ -0,0 +1,17 @@
+<!-- $Id: validation_only.ent 826 2009-01-17 05:04:52Z unsaved $ -->
+
+<!-- Dummy value defintions.
+     These settings are fine for GUI editors and Validation, but this file
+     should definitely be overridden with a catalog for generating
+     production-ready output documents.
+
+     The real, document-specific, production values for these entities are set
+     at "tmp/doc-work/<DOCNAME>/dyanamic.ent".
+-->
+
+<!-- These entities are "project global", in that the entities may be used in
+     any document of the project.  The value of doc_basename will certainly vary
+     for each document, and distro_baseurl may. -->
+<!ENTITY doc_basename "doc_basename_DEFAULTVAL">
+<!ENTITY distro_baseurl "distro_baseurl_DEFAULTVAL">
+<!-- distro_baseurl is the canonical download source for the doc -->
diff --git a/doc-src/guide/accesscontrol.xml b/doc-src/guide/accesscontrol.xml
new file mode 100644
index 0000000..0d94c71
--- /dev/null
+++ b/doc-src/guide/accesscontrol.xml
@@ -0,0 +1,669 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="accesscontrol-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="accesscontrol-title">Access Control</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3096 $</releaseinfo>
+
+    <pubdate>$Date: 2009-08-09 17:50:39 +0100 (Sun, 09 Aug 2009) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section>
+    <title>Overview</title>
+
+    <para>Apart from schemas and their object, each HyperSQL catalog has USER
+    and ROLE objects. These objects are collectively called
+    <emphasis>authorizations</emphasis>. Each AUTHORIZATION has some access
+    rights on some of the schemas or the objects they contain. The persistent
+    elements of an SQL environment are database objects</para>
+
+    <para>Each database object has a name. A name is an identifier and is
+    unique within its name-space. Authorizations names follow the rules
+    described below and the case-normal form is stored in the database. When
+    connecting to a database, the user name and password must match the case
+    of the case-normal form.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>identifier definition</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">identifier</emphasis></simpara>
+
+    <simpara><emphasis>definition of identifier</emphasis></simpara>
+
+    <simpara><literal>&lt;identifier&gt; ::= &lt;regular identifier&gt; |
+    &lt;delimited identifier&gt; | &lt;SQL language identifier&gt;
+    </literal></simpara>
+
+    <simpara><literal>&lt;delimited identifier&gt; ::= &lt;double quote&gt;
+    &lt;character sequence&gt; &lt;double quote&gt;</literal></simpara>
+
+    <simpara><literal>&lt;regular identifier&gt; ::= &lt;special character
+    sequence&gt;</literal></simpara>
+
+    <simpara><literal>&lt;SQL language identifier&gt; ::= &lt;special
+    character sequence&gt;</literal></simpara>
+
+    <simpara>A <literal>&lt;delimited identifier&gt;</literal> is a sequence
+    of characters enclosed with double-quote symbols. All characters are
+    allowed in the character sequence.</simpara>
+
+    <simpara>A <literal>&lt;regular identifier&gt;</literal> is a special
+    sequence of characters. It consists of letters, digits and the underscore
+    characters. It must begin with a letter.</simpara>
+
+    <simpara>A <literal>&lt;SQL language identifier&gt;</literal> is similar
+    to <literal>&lt;regular identifier&gt;</literal> but the letters can range
+    only from A-Z in the ASCII character set. This type of identifier is used
+    for names of CHARACTER SET objects.</simpara>
+
+    <simpara>If the character sequence of a delimited identifier is the same
+    as an undelimited identifier, it represents the same identifier. For
+    example "JOHN" is the same identifier as JOHN. In a <literal>&lt;regular
+    identifier&gt;</literal> the case-normal form is considered for
+    comparison. This form consists of the upper-case of equivalent of all the
+    letters.</simpara>
+
+    <simpara>The character sequence length of all identifiers must be between
+    1 and 128 characters.</simpara>
+
+    <simpara>A reserved word is one that is used by the SQL Standard for
+    special purposes. It is similar to a <literal>&lt;regular
+    identifier&gt;</literal> but it cannot be used as an identifier for user
+    objects. If a reserved word is enclosed in double quote characters, it
+    becomes a quoted identifier and can be used for database
+    objects.</simpara>
+  </section>
+
+  <section>
+    <title>Authorizations and Access Control</title>
+
+    <para>In general, ROLE and USER objects simply control access to schema
+    objects. This is the scope of the SQL Standard. However, there are special
+    roles that allow the creation of USER and ROLE objects and also allow some
+    special operations on the database as a whole. These roles are not defined
+    by the Standard, which has left it to implementors to define such roles as
+    they are needed for the particular SQL implementation.</para>
+
+    <para>A ROLE has a name a collection of zero or more other roles, plus
+    some privileges (access rights). A USER has a name and a password. It
+    similarly has a collection of zero or more roles plus some
+    privileges.</para>
+
+    <para>USER objects existed in the SQL-92, but ROLE objects were introduced
+    in SQL:1999. Originally it was intended that USER objects would normally
+    be the same as the operating system USER objects and their authentication
+    would be handled outside the SQL environment. The co-existence of ROLE and
+    USER objects results in complexity. With the addition of ROLE objects,
+    there is no rationale, other than legacy support, for granting privileges
+    to USER objects directly. It is better to create roles and grant
+    privileges to them, then grant the roles to USER objects.</para>
+
+    <para>The Standard effectively defines a special ROLE, named PUBLIC. All
+    authorization have the PUBLIC role, which cannot be removed from them.
+    Therefore any access right assigned to the PUBLIC role applies to all
+    authorizations in the database. For many simple databases, it is adequate
+    to create a single, non-admin user, then assign access rights to the
+    pre-existing PUBLIC role. Access to INFORMATION_SCHEMA views is granted to
+    PUBLIC, therefore these views are accessible to all. However, the contents
+    of each view depends on the ROLE or USER (AUTHORIZATION) that is in force
+    while accessing the view.</para>
+
+    <para>Each schema has a single AUTHORIZATION. This is commonly known as
+    the <emphasis>owner</emphasis> of the schema. All the objects in the
+    schema inherit the schema owner. The schema owner can add objects to the
+    schema, drop them or alter them.</para>
+
+    <para>By default, the objects in a schema can only be accessed by the
+    schema owner. The schema owner can grant access rights on the objects to
+    other users or roles.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>AUTHORIZATION IDENTIFIER</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">authorization
+    identifier</emphasis></simpara>
+
+    <simpara><emphasis>authorization identifier</emphasis></simpara>
+
+    <simpara><literal>&lt;authorization identifier&gt; ::= &lt;role name&gt; |
+    &lt;user name&gt;</literal></simpara>
+
+    <simpara>Authorization identifiers share the same name-space within the
+    database. The same name cannot be used for a USER and a ROLE.</simpara>
+
+    <section>
+      <title>Built-In Roles and Users</title>
+
+      <para>There are some pre-defined roles in each database; some defined by
+      the SQL Standard, some by HyperSQL. These roles can be assigned to users
+      (directly or via other, user-defined roles). In addition, there is the
+      default initial user, SA, created with each new database.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>PUBLIC ROLE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">PUBLIC</emphasis></simpara>
+
+      <simpara><emphasis>the PUBLIC role</emphasis></simpara>
+
+      <simpara>The role that is assigned to all authorizations (roles and
+      users) in the database. This role has access rights to all objects in
+      the INFORMATION_SCHEMA. Any roles or rights granted to this role, are in
+      effect granted to all users of the database.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>_SYSTEM ROLE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">_SYSTEM</emphasis></simpara>
+
+      <simpara><emphasis>the _SYSTEM role</emphasis></simpara>
+
+      <simpara>This role is the authorization for the pre-defined (system)
+      objects in the database, including the INFORMATION_SCHEMA. This role
+      cannot be assigned to any authorization.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DBA ROLE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DBA</emphasis></simpara>
+
+      <simpara><emphasis>the DBA role (HyperSQL-specific)</emphasis></simpara>
+
+      <simpara>This is a special role in HyperSQL. A user that has this role
+      can perform all possible administrative tasks on the database. The DBA
+      role can also act as a proxy for all the roles and users in the
+      database. This means it can do everything the authorization for a schema
+      can do, including dropping the schema or its objects, or granting rights
+      on the schema objects to a grantee.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE_SCHEMA ROLE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE_SCHEMA</emphasis></simpara>
+
+      <simpara><emphasis>the CREATE_SCHEMA role
+      (HyperSQL-specific)</emphasis></simpara>
+
+      <simpara>An authorization that has this role, can create schemas. The
+      DBA authorization has this role and can grant it to other
+      authorizations.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CHANGE_AUTHORIZATION</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CHANGE_AUTHORIZATION</emphasis></simpara>
+
+      <simpara><emphasis>the CHANGE_AUTHORIZATION role
+      (HyperSQL-specific)</emphasis></simpara>
+
+      <simpara>A user that has this role, can change the authorization for the
+      current session to another user. The DBA authorization has this role and
+      can grant it to other authorizations.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SA USER</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SA</emphasis></simpara>
+
+      <simpara><emphasis>the SA user (HyperSQL-specific)</emphasis></simpara>
+
+      <simpara>This user is automatically created with a new database and has
+      the DBA role. Initially, the password for this user is an empty string.
+      After connecting to the new database as this user, it is possible to
+      change the password, create other users and created new schema objects.
+      The SA user can be dropped by another user that has the DBA
+      role.</simpara>
+    </section>
+
+    <section>
+      <title>Access Rights</title>
+
+      <para>By default, the objects in a schema can only be accessed by the
+      schema owner. But the schema owner can grant privileges (access rights)
+      on the objects to other users or roles.</para>
+
+      <para>Things can get far more complex, because the grant of privileges
+      can be made WITH GRANT OPTION. In this case, the role or user that has
+      been granted the privilege can grant the privilege to other roles and
+      users.</para>
+
+      <para>Privileges can also be revoked from users or roles.</para>
+
+      <para>The statements for granting and revoking privileges normally
+      specify which privileges are granted or revoked. However, there is a
+      shortcut, ALL PRIVILEGES, which means all the privileges that the
+      <literal>&lt;grantor&gt;</literal> has on the schema object. The
+      <literal>&lt;grantor&gt;</literal> is normally the CURRENT_USER of the
+      session that issues the statement.</para>
+
+      <para>The user or role that is granted privileges is referred to as
+      <literal>&lt;grantee&gt;</literal> for the granted privileges.</para>
+
+      <simpara><emphasis role="bold">Table</emphasis></simpara>
+
+      <simpara>For tables, including views, privileges can be granted with
+      different degrees of granularity. It is possible to grant a privilege on
+      all columns of a table, or on specific columns of the table.</simpara>
+
+      <simpara>The DELETE privilege applies to the table, rather than its
+      columns. It applies to all DELETE statements.</simpara>
+
+      <simpara>The SELECT, INSERT and UPDATE privileges may apply to all
+      columns or to individual columns. These privileges determine whether the
+      <literal>&lt;grantee&gt;</literal> can execute SQL data statements on
+      the table.</simpara>
+
+      <simpara>The SELECT privilege designates the columns that can be
+      referenced in SELECT statements, as well as the columns that are read in
+      a DELETE or UPDATE statement, including the search condition.</simpara>
+
+      <simpara>The INSERT privilege designates the columns into which explicit
+      values can be inserted. To be able to insert a row into the table, the
+      user must therefore have the INSERT privilege on the table, or at least
+      all the columns that do not have a default value.</simpara>
+
+      <simpara>The UPDATE privilege simply designates the table or the
+      specific columns that can be updated.</simpara>
+
+      <simpara>The REFERENCES privilege allows the
+      <literal>&lt;grantee&gt;</literal> to define a FOREIGN KEY constraint on
+      a different table, which references the table or the specific columns
+      designated for the REFERENCES privilege.</simpara>
+
+      <simpara>The TRIGGER privilege allows adding a trigger to the
+      table.</simpara>
+
+      <simpara><emphasis role="bold">Sequence, Type, Domain, Character Set,
+      Collation, Transliteration,</emphasis></simpara>
+
+      <simpara>For these objects, only USAGE can be granted. The USAGE
+      privilege is needed when object is referenced directly in an SQL
+      statement.</simpara>
+
+      <simpara><emphasis role="bold">Routine</emphasis></simpara>
+
+      <simpara>For routines, including procedures or functions, only EXECUTE
+      privilege can be granted. This privilege is needed when the routine is
+      used directly in an SQL statement.</simpara>
+
+      <simpara><emphasis role="bold">Other Objects</emphasis></simpara>
+
+      <simpara>Other objects such as constraints and assertions are not used
+      directly and there is no grantable privilege that refers to
+      them.</simpara>
+    </section>
+  </section>
+
+  <section>
+    <title xml:id="accesscontrol-statements-title">Statements for
+    Authorization and Access Control</title>
+
+    <para>The statements listed below allow creation and destruction of USER
+    and ROLE objects. The GRANT and REVOKE statements allow roles to be
+    assigned to other roles or to users. The same statements are also used in
+    a different form to assign privileges on schema objects to users and
+    roles.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CREATE USER</primary>
+    </indexterm>
+
+    <simpara xml:id="create_user-sql"><emphasis role="bold">CREATE
+    USER</emphasis></simpara>
+
+    <simpara><emphasis>user definition (HyperSQL)</emphasis></simpara>
+
+    <simpara><literal>&lt;user definition&gt; ::= CREATE USER &lt;user
+    name&gt; PASSWORD &lt;password&gt; [ ADMIN ]</literal></simpara>
+
+    <simpara>Define a new user and its password. <literal>&lt;user
+    name&gt;</literal> is an SQL identifier. If it is double-quoted it is
+    case-sensitive, otherwise it is turned to uppercase.
+    <literal>&lt;password&gt;</literal> is a string enclosed with single quote
+    characters and is case-sensitive. If <literal>ADMIN</literal> is
+    specified, the DBA role is granted to the new user. Only a user with the
+    DBA role can execute this statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DROP USER</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DROP USER</emphasis></simpara>
+
+    <simpara><emphasis>drop user statement (HyperSQL)</emphasis></simpara>
+
+    <simpara><literal>&lt;drop user statement&gt; ::= DROP USER &lt;user
+    name&gt;</literal></simpara>
+
+    <simpara>Drop (destroy) an existing user. If the specified user is the
+    authorization for a schema, the schema is destroyed. Only a user with the
+    DBA role can execute this statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ALTER USER ... SET PASSWORD</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ALTER USER ... SET
+    PASSWORD</emphasis></simpara>
+
+    <simpara><emphasis>set the password for a user
+    (HyperSQL)</emphasis></simpara>
+
+    <simpara><literal>&lt;alter user set password statement&gt; ::= ALTER USER
+    &lt;user name&gt; SET PASSWORD &lt;password&gt;</literal></simpara>
+
+    <simpara>Change the password of an existing user. <literal>&lt;user
+    name&gt;</literal> is an SQL identifier. If it is double-quoted it is
+    case-sensitive, otherwise it is turned to uppercase.
+    <literal>&lt;password&gt;</literal> is a string enclosed with single quote
+    characters and is case-sensitive. Only a user with the DBA role can
+    execute this command.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ALTER USER ... SET INITIAL SCHEMA</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ALTER USER ... SET INITIAL
+    SCHEMA</emphasis></simpara>
+
+    <simpara><emphasis>set the initial schema for a user
+    (HyperSQL)</emphasis></simpara>
+
+    <simpara><literal>&lt;alter user set initial schema statement&gt; ::=
+    ALTER USER &lt;user name&gt; SET INITIAL SCHEMA &lt;schema name&gt; |
+    DEFAULT</literal></simpara>
+
+    <simpara>Change the initial schema for a user. The initial schema is the
+    schema used by default for SQL statements issued during a session. If
+    <literal>DEFAULT</literal> is used, the default initial schema for all
+    users is used as the initial schema for the user. The SET SCHEMA command
+    allows the user to change the schema for the duration of the session. Only
+    a user with the DBA role can execute this statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET PASSWORD</primary>
+    </indexterm>
+
+    <simpara xml:id="set_password-sql"><emphasis role="bold">SET
+    PASSWORD</emphasis></simpara>
+
+    <simpara><emphasis>set password statement (HyperSQL)</emphasis></simpara>
+
+    <simpara><literal>&lt;set password statement&gt; ::= SET PASSWORD
+    &lt;password&gt;</literal></simpara>
+
+    <simpara>Set the password for the current user.
+    <literal>&lt;password&gt;</literal> is a string enclosed with single quote
+    characters and is case-sensitive.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET INITIAL SCHEMA*</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET INITIAL SCHEMA</emphasis></simpara>
+
+    <simpara><emphasis>set the initial schema for the current user
+    (HyperSQL)</emphasis></simpara>
+
+    <simpara><literal>&lt;set initial schema statement&gt; ::= SET INITIAL
+    SCHEMA &lt;schema name&gt; | DEFAULT</literal></simpara>
+
+    <simpara>Change the initial schema for the current user. The initial
+    schema is the schema used by default for SQL statements issued during a
+    session. If <literal>DEFAULT</literal> is used, the default initial schema
+    for all users is used as the initial schema for the current user. The
+    separate SET SCHEMA command allows the user to change the schema for the
+    duration of the session. See also the <link endterm="sessions-title"
+    xlink:arcrole="" xlink:href="#sessions-chapt"></link> chapter.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE DEFAULT INITIAL SCHEMA</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE DEFAULT INITIAL
+    SCHEMA</emphasis></simpara>
+
+    <simpara><emphasis>set the default initial schema for all users
+    (HyperSQL)</emphasis></simpara>
+
+    <simpara><literal>&lt;set database default initial schema statement&gt;
+    ::= SET DATABASE DEFAULT INITIAL SCHEMA &lt;schema
+    name&gt;</literal></simpara>
+
+    <simpara>Sets the initial schema for new users. This schema can later be
+    changed with the <literal>&lt;set initial schema statement&gt;</literal>
+    command.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CREATE ROLE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CREATE ROLE</emphasis></simpara>
+
+    <simpara><emphasis>role definition</emphasis></simpara>
+
+    <simpara><literal>&lt;role definition&gt; ::= CREATE ROLE &lt;role
+    name&gt; [ WITH ADMIN &lt;grantor&gt; ]</literal></simpara>
+
+    <simpara>Defines a new role. Initially the role has no rights, except
+    those of the PUBLIC role. Only a user with the DBA role can execute this
+    command.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DROP ROLE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DROP ROLE</emphasis></simpara>
+
+    <simpara><emphasis>drop role statement</emphasis></simpara>
+
+    <simpara><literal>&lt;drop role statement&gt; ::= DROP ROLE &lt;role
+    name&gt;</literal></simpara>
+
+    <simpara>Drop (destroy) a role. If the specified role is the authorization
+    for a schema, the schema is destroyed. Only a user with the DBA role can
+    execute this statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>GRANTED BY</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">GRANTED BY</emphasis></simpara>
+
+    <simpara><emphasis>grantor determination</emphasis></simpara>
+
+    <simpara><literal>GRANTED BY &lt;grantor&gt;</literal></simpara>
+
+    <simpara><literal>&lt;grantor&gt; ::= CURRENT_USER |
+    CURRENT_ROLE</literal></simpara>
+
+    <simpara>The authorization that is granting or revoking a role or
+    privileges. The optional <literal>GRANTED BY &lt;grantor&gt;</literal>
+    clause can be used in various statements that perform GRANT or REVOKE
+    actions. If the clause is not used, the authorization is CURRENT_USER.
+    Otherwise, it is the specified authorization.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>GRANT privilege</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">GRANT</emphasis></simpara>
+
+    <simpara><emphasis>grant privilege statement</emphasis></simpara>
+
+    <simpara><literal>&lt;grant privilege statement&gt; ::= GRANT
+    &lt;privileges&gt; TO &lt;grantee&gt; [ { &lt;comma&gt; &lt;grantee&gt;
+    }... ] [ WITH GRANT OPTION ] [ GRANTED BY &lt;grantor&gt;
+    ]</literal></simpara>
+
+    <simpara>Assign privileges on schema objects to roles or users. Each
+    <literal>&lt;grantee&gt;</literal> is a role or a user. If <literal>[ WITH
+    GRANT OPTION ]</literal> is specified, then the
+    <literal>&lt;grantee&gt;</literal> can assign the privileges to other
+    <literal>&lt;grantee&gt;</literal> objects.</simpara>
+
+    <simpara><literal>&lt;privileges&gt; ::= &lt;object privileges&gt; ON
+    &lt;object name&gt;</literal></simpara>
+
+    <simpara><literal>&lt;object name&gt; ::= [ TABLE ] &lt;table name&gt; |
+    DOMAIN &lt;domain name&gt; | COLLATION &lt;collation name&gt; | CHARACTER
+    SET &lt;character set name&gt; | TRANSLATION &lt;transliteration name&gt;
+    | TYPE &lt;user-defined type name&gt; | SEQUENCE &lt;sequence generator
+    name&gt; | &lt;specific routine designator&gt; | ROUTINE &lt;routine
+    name&gt; | FUNCTION &lt;function name&gt; | PROCEDURE &lt;procedure
+    name&gt;</literal></simpara>
+
+    <simpara><literal>&lt;object privileges&gt; ::= ALL PRIVILEGES |
+    &lt;action&gt; [ { &lt;comma&gt; &lt;action&gt; }... ]</literal></simpara>
+
+    <simpara><literal>&lt;action&gt; ::= SELECT | SELECT &lt;left paren&gt;
+    &lt;privilege column list&gt; &lt;right paren&gt; | DELETE | INSERT [
+    &lt;left paren&gt; &lt;privilege column list&gt; &lt;right paren&gt; ] |
+    UPDATE [ &lt;left paren&gt; &lt;privilege column list&gt; &lt;right
+    paren&gt; ] | REFERENCES [ &lt;left paren&gt; &lt;privilege column
+    list&gt; &lt;right paren&gt; ] | USAGE | TRIGGER |
+    EXECUTE</literal></simpara>
+
+    <simpara><literal>&lt;privilege column list&gt; ::= &lt;column name
+    list&gt;</literal></simpara>
+
+    <simpara><literal>&lt;grantee&gt; ::= PUBLIC | &lt;authorization
+    identifier&gt;</literal></simpara>
+
+    <simpara>The <literal>&lt;object privileges&gt;</literal> that can be used
+    depend on the type of the <literal>&lt;object name&gt;</literal>. These
+    are discussed in the previous section. For a table, if
+    <literal>&lt;privilege column list&gt;</literal> is not specified, then
+    the privilege is granted on the table, which includes all of its columns
+    and any column that may be added to it in the future. For routines, the
+    name of the routine can be specified in two ways, either as the generic
+    name as the specific name. HyperSQL allows referencing all overloaded
+    versions of a routine at the same time, using its name. This differs from
+    the SQL Standard which requires the use of <literal>&lt;specific routine
+    designator&gt;</literal> to grant privileges separately on each different
+    signature of the routine.</simpara>
+
+    <simpara>Each <literal>&lt;grantee&gt;</literal> is the name of a role or
+    a user. Examples of GRANT statement are given below:</simpara>
+
+    <informalexample>
+      <programlisting>GRANT ALL ON SEQUENCE aSequence TO roleOrUser 
+GRANT SELELCT ON aTable TO roleOrUser  
+GRANT SELECT, UPDATE ON aTABLE TO roleOrUser1, roleOrUser2
+GRANT SELECT(columnA, columnB), UPDATE(columnA, columnB) ON TABLE aTable TO roleOrUser
+GRANT EXECUTE ON SPECIFIC ROUTINE aroutine_1234 TO rolOrUser
+</programlisting>
+    </informalexample>
+
+    <simpara>As mentioned in the general discussion, it is better to define a
+    role for the collection of all the privileges required by an application.
+    This role is then granted to any user. If further changes are made to the
+    privileges of this role, they are automatically reflected in all the users
+    that have the role.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>GRANT role</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">GRANT</emphasis></simpara>
+
+    <simpara><emphasis>grant role statement</emphasis></simpara>
+
+    <simpara><literal>&lt;grant role statement&gt; ::= GRANT &lt;role name&gt;
+    [ { &lt;comma&gt; &lt;role name&gt; }... ] TO &lt;grantee&gt; [ {
+    &lt;comma&gt; &lt;grantee&gt; }... ] [ WITH ADMIN OPTION ] [ GRANTED BY
+    &lt;grantor&gt; ]</literal></simpara>
+
+    <simpara>Assign roles to roles or users. One or more roles can be assigned
+    to one or more <literal>&lt;grantee&gt;</literal> objects. A
+    <literal>&lt;grantee&gt;</literal> is a user or a role. If the <literal>[
+    WITH ADMIN OPTION ]</literal> is specified, then each
+    <literal>&lt;grantee&gt;</literal> can grant the newly assigned roles to
+    other grantees. An example of user and role creation with grants is given
+    below:</simpara>
+
+    <informalexample>
+      <programlisting>CREATE USER appuser
+CREATE ROLE approle
+GRANT approle TO appuser
+GRANT SELECT, UPDATE ON TABLE atable TO approle
+GRANT USAGE ON SEQUENCE asequence to approle
+GRANT EXECUTE ON ROUTINE aroutine TO approle
+</programlisting>
+    </informalexample>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>REVOKE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">REVOKE privilege</emphasis></simpara>
+
+    <simpara><emphasis>revoke statement</emphasis></simpara>
+
+    <simpara><literal>&lt;revoke privilege statement&gt; ::= REVOKE [ GRANT
+    OPTION FOR ] &lt;privileges&gt; FROM &lt;grantee&gt; [ { &lt;comma&gt;
+    &lt;grantee&gt; }... ] [ GRANTED BY &lt;grantor&gt; ] RESTRICT |
+    CASCADE</literal></simpara>
+
+    <simpara>Revoke privileges from a user or role.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>REVOKE ROLE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">REVOKE role</emphasis></simpara>
+
+    <simpara><emphasis>revoke role statement</emphasis></simpara>
+
+    <simpara><literal>&lt;revoke role statement&gt; ::= REVOKE [ ADMIN OPTION
+    FOR ] &lt;role revoked&gt; [ { &lt;comma&gt; &lt;role revoked&gt; }... ]
+    FROM &lt;grantee&gt; [ { &lt;comma&gt; &lt;grantee&gt; }... ] [ GRANTED BY
+    &lt;grantor&gt; ] RESTRICT | CASCADE</literal></simpara>
+
+    <simpara><literal>&lt;role revoked&gt; ::= &lt;role
+    name&gt;</literal></simpara>
+
+    <simpara>Revoke a role from users or roles.</simpara>
+  </section>
+</chapter>
diff --git a/doc-src/guide/building-app.xml b/doc-src/guide/building-app.xml
new file mode 100644
index 0000000..1a7512d
--- /dev/null
+++ b/doc-src/guide/building-app.xml
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: building-app.xml 3556 2010-03-26 23:09:40Z fredt $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<appendix version="5.0" xml:id="building-app"
+          xmlns="http://docbook.org/ns/docbook"
+          xmlns:xlink="http://www.w3.org/1999/xlink"
+          xmlns:xi="http://www.w3.org/2001/XInclude"
+          xmlns:ns5="http://www.w3.org/2000/svg"
+          xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+          xmlns:ns3="http://www.w3.org/1999/xhtml"
+          xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <info>
+    <title xml:id="building-title">Building HyperSQL Jars</title>
+
+    <subtitle>How to build customized or specialized jar files</subtitle>
+
+    <author>
+      <personname><firstname>Fred</firstname>
+      <surname>Toussi</surname></personname>
+
+      <affiliation>
+        <orgname>The HSQL Development Group</orgname>
+      </affiliation>
+    </author>
+
+    <releaseinfo>$Revision: 3556 $</releaseinfo>
+
+    <pubdate>$Date: 2010-03-26 19:09:40 -0400 (Fri, 26 Mar 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>HSQLDB</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>Building</keyword>
+
+      <keyword>Ant</keyword>
+    </keywordset>
+  </info>
+
+  <section>
+    <title>Purpose</title>
+
+    <simpara>From 2.0, the supplied <filename>hsqldb.jar</filename> file is
+    built with Java 1.6. If you want to run with a 1.5 or older JVM, or if you
+    want to use an alternative jar (<filename>hsqldb-min.jar</filename>, etc.)
+    you must build the desired jar with a Java JDK and Ant version
+    1.7.</simpara>
+  </section>
+
+  <section xml:id="building-ant-sect">
+    <title>Building with Apache Ant</title>
+
+    <titleabbrev>Building with Ant</titleabbrev>
+
+    <indexterm significance="preferred">
+      <primary>Ant</primary>
+    </indexterm>
+
+    <simpara>You should use version 1.7.x of Ant (Another Neat Tool) to do
+    builds with HyperSQL.</simpara>
+
+    <section>
+      <title>Obtaining Ant</title>
+
+      <simpara>Ant is a part of the Jakarta/Apache Project.</simpara>
+
+      <itemizedlist>
+        <listitem>
+          <simpara><link xlink:href="http://ant.apache.org">Home of the Apache
+          Ant project</link></simpara>
+        </listitem>
+
+        <listitem>
+          <simpara>The <link
+          xlink:href="http://ant.apache.org/manual/install.html#installing">
+          Installing Ant</link> page of the <link
+          xlink:href="http://ant.apache.org/manual">Ant Manual</link>. Follow
+          the directions for your platform.</simpara>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section>
+      <title>Building Hsqldb with Ant</title>
+
+      <simpara>Once you have unpacked the zip package for hsqldb, under the
+      <filename>/hsqldb</filename> folder, in <filename>/build</filename>
+      there is a <filename>build.xml</filename> file that builds the
+      <filename>hsqldb.jar</filename> with Ant (Ant must be already
+      installed). To use it, change to <filename>/build</filename> then
+      type:</simpara>
+
+      <informalexample>
+        <screen> ant -projecthelp</screen>
+      </informalexample>
+
+      <simpara>This displays the available ant targets, which you can supply
+      as command line arguments to ant. These include</simpara>
+
+      <variablelist>
+        <varlistentry>
+          <term>hsqldb</term>
+
+          <listitem>
+            <simpara>to build the <filename>hsqldb.jar</filename>
+            file</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>explainjars</term>
+
+          <listitem>
+            <simpara>Lists all targets which build jar files, with an
+            explanation of the purposes of the different jars.</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>clean</term>
+
+          <listitem>
+            <simpara>to clean up the /classes directory that is
+            created</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>clean-all</term>
+
+          <listitem>
+            <simpara>to remove the old jar and doc files as well</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>javadoc</term>
+
+          <listitem>
+            <simpara>to build javadoc</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>hsqldbmain</term>
+
+          <listitem>
+            <simpara>to build a smaller jar for HSQLDB that does not contain
+            utilities</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>hsqljdbc</term>
+
+          <listitem>
+            <simpara>to build an extremely small jar containing only the
+            client-side JDBC driver (can connect only to a HyperSQL
+            Server).</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>hsqldbmin</term>
+
+          <listitem>
+            <simpara>to build a small jar that supports
+            <emphasis>in-process</emphasis> catalogs, but neither running nor
+            connecting to HyperSQL Servers.</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>sqltool</term>
+
+          <listitem>
+            <simpara>to build sqltool.jar, which contains only the SqlTool
+            classes.</simpara>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>...</term>
+
+          <listitem>
+            <simpara>Many more targets are available. Run <literal>ant
+            -p</literal> and <literal>ant explainjars</literal>.</simpara>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <simpara>HSQLDB can be built in any combination of two JRE (Java Runtime
+      Environment) versions and many jar file sizes.</simpara>
+
+      <simpara>A jar built with an older JRE is compatible for use with a
+      newer JRE (you can compile with Java 1.5 and run with 1.6). But the
+      newer JDBC capabilities of the JRE will be not be available.</simpara>
+
+      <simpara>The client jar (<filename>hsqljdbc.jar</filename>) contains
+      only the HSQLDB JDBC Driver client. The smallest engine jar
+      (<filename>hsqldbmin.jar</filename>) contains the engine and the HSQLDB
+      JDBC Driver client. The default size (<filename>hsqldb.jar</filename>)
+      also contains server mode support and the utilities. The largest size
+      (<filename>hsqldbtest.jar</filename>)includes some test classes as well.
+      Before building the <filename>hsqldbtest.jar</filename> package, you
+      should download the junit jar from <link
+      xlink:href="http://www.junit.org"></link> and put it in the
+      <filename>/lib</filename> directory, alongside
+      <filename>servlet.jar</filename>, which is included in the .zip
+      package.</simpara>
+
+      <para>If you want your code built for high performance, as opposed to
+      debugging (in the same way that we make our production distributions),
+      make a file named <filename>build.properties</filename> in your build
+      directory with the contents <informalexample>
+          <screen>build.debug: false</screen>
+        </informalexample>The resulting Java binaries will be faster and
+      smaller, at the cost of exception stack traces not identifying source
+      code locations (which can be extremely useful for debugging).</para>
+
+      <simpara>After installing Ant on your system use the following command
+      from the <filename>/build</filename> directory. Just run <literal>ant
+      explainjars</literal> for a concise list of all available jar
+      files.</simpara>
+
+      <informalexample>
+        <screen>ant explainjars</screen>
+      </informalexample>
+
+      <simpara>The command displays a list of different options for building
+      different sizes of the HSQLDB Jar. The default is built using:</simpara>
+
+      <example>
+        <title>Buiding the standard Hsqldb jar file with Ant</title>
+
+        <screen>ant hsqldb</screen>
+      </example>
+
+      <simpara>The Ant method always builds a jar with the JDK that is used by
+      Ant and specified in its JAVA_HOME environment variable.</simpara>
+    </section>
+
+    <section>
+      <title>Building for Older JDKs</title>
+
+      <para>HyperSQL version 2.0 cannot be directly compiled or used with JDK
+      1.4. It may be possible to use the RetroTranslator tool to achieve this.
+      The suggested procedure is as follows: First use Ant with JDK 1.5 and
+      build the jar. Then translate the jar using RetroTranslator with
+      backport (which bundles replacement classes for concurrency control).
+      This translation should cover the concurrency features that are specific
+      to version 1.5 and later.<informalexample>
+          <screen>ant switchtojdk14
+ant hsqldb
+-- translate the jar
+</screen>
+        </informalexample></para>
+    </section>
+  </section>
+
+  <section>
+    <title>Building with IDE's</title>
+
+    <simpara>All HyperSQL source files are supplied ready to compile. There is
+    no complex pre-compile stage. It is therefore possible to compile the
+    sources with an IDE, without using ant. Only if compilation with Java 1.5
+    is required, you should first run the Ant code switcher task before
+    compiling and remove from the source directories a few source files that
+    are specific to Java 6 (these are listed in the build.xml file).</simpara>
+  </section>
+
+  <section>
+    <title>Hsqldb CodeSwitcher</title>
+
+    <simpara>CodeSwitcher is a tool to manage different version of Java source
+    code. It allows to compile HyperSQL for different JDKs. It is something
+    like a precompiler in C but it works directly on the source code and does
+    not create intermediate output or extra files.</simpara>
+
+    <simpara>CodeSwitcher is used internally in the Ant build. You do not have
+    to use it separately to compile HyperSQL.</simpara>
+
+    <simpara>CodeSwitcher reads the source code of a file, removes comments
+    where appropriate and comments out the blocks that are not used for a
+    particular version of the file. This operation is done for all files of a
+    defined directory, and all subdirectories.</simpara>
+
+    <example>
+      <title>Example source code before CodeSwitcher is run</title>
+
+      <programlisting>
+        ...
+
+    //#ifdef JAVA2
+
+        properties.store(out,"hsqldb database");
+
+    //#else
+
+    /*
+
+        properties.save(out,"hsqldb database");
+
+    */
+
+    //#endif
+
+        ...</programlisting>
+    </example>
+
+    <simpara>The next step is to run CodeSwitcher.</simpara>
+
+    <example>
+      <title>CodeSwitcher command line invocation</title>
+
+      <screen>
+    java org.hsqldb.util.CodeSwitcher . -JAVA2</screen>
+    </example>
+
+    <simpara>The '.' means the program works on the current directory (all
+    subdirectories are processed recursively). <literal>-JAVA2</literal> means
+    the code labelled with JAVA2 must be switched off.</simpara>
+
+    <example>
+      <title>Source code after CodeSwitcher processing</title>
+
+      <programlisting>
+        ...
+
+    //#ifdef JAVA2
+
+    /*
+
+        pProperties.store(out,"hsqldb database");
+
+    */
+
+    //#else
+
+        pProperties.save(out,"hsqldb database");
+
+    //#endif
+
+        ...</programlisting>
+    </example>
+
+    <simpara>For detailed information on the command line options run
+    <classname>java org.hsqldb.util.CodeSwitcher</classname>. Usage examples
+    can be found in the build.xml file in the <filename>/build</filename>
+    directory.</simpara>
+  </section>
+
+  <section>
+    <title>Building documentation</title>
+
+    <simpara>The JavaDoc can be built simply by invoking the javadoc
+    target.</simpara>
+
+    <simpara>The two Guides are in DocBook XML source format. To rebuild, run
+    the Ant target <literal>gen-docs</literal>. Instructions will be
+    displayed. See the file <filename>doc-src/readme-docauthors.txt</filename>
+    for tips.</simpara>
+  </section>
+</appendix>
diff --git a/doc-src/guide/builtinfunctions.xml b/doc-src/guide/builtinfunctions.xml
new file mode 100644
index 0000000..c453327
--- /dev/null
+++ b/doc-src/guide/builtinfunctions.xml
@@ -0,0 +1,1918 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="builtinfunctions-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/1999/xhtml"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="builtinfunctions-title">Built In Functions</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+    <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section xml:id="builtin_functions_intro-sect">
+    <title>Overview</title>
+
+    <para>HyperSQL supports a wide range of built-in functions and allows
+    user-defined functions written in SQL and Java languages. User defined
+    functions are covered in a separate chapter. If a built-in function is not
+    available, you can write your own using SQL. Aggregate functions are
+    discussed in chapters that cover SQL in general.</para>
+
+    <para>The built-in functions fall into three groups:</para>
+
+    <para><itemizedlist>
+        <listitem>
+          <para>SQL Standard Functions</para>
+
+          <para>A wide rang of functions defined by SQL/Foundation are
+          supported. SQL/Foundation functions that have no parameter are
+          called without empty parentheses. Functions with multiple parameters
+          often use keywords instead of commas to separate the parameters.
+          Many functions are overloaded. Among these, some have one or more
+          optional parameters that can be omitted, while the return type of
+          some functions is dependent upon the type of one of the parameters.
+          The usage of SQL Standard Functions (where they can be used) is
+          covered more extensively in the <link endterm="dataaccess-title"
+          xlink:href="#dataaccess-chapt"></link> chapter</para>
+        </listitem>
+
+        <listitem>
+          <para>JDBC Open Group CLI Functions</para>
+
+          <para>These functions were defined as an extension to the CLI
+          standard, which is the basis for ODBC and JDBC and supported by many
+          database products. JDBC supports an escape mechanism to specify
+          function calls in SQL statements in a manner that is independent of
+          the function names supported by the target database engine. For
+          example <literal>SELECT {fn DAYOFMONTH (dateColumn)} FROM
+          myTable</literal> can be used in JDBC and is translated to Standard
+          SQL as <literal>SELECT EXTRACT (DAY_OF_MONTH FROM dateColumn) FROM
+          myTable</literal> if a database engine supports the Standard syntax.
+          If a database engine does not support Standard SQL, then the
+          translation will be different. HyperSQL supports all the function
+          names specified in the JDBC specifications as native functions.
+          Therefore, there is no need to use the <literal>{fn FUNC_NAME ( ...
+          ) }</literal> escape with HyperSQL. If a JDBC function is supported
+          by the SQL Standard in a different form, the SQL Standard form is
+          the preferred form to use.</para>
+        </listitem>
+
+        <listitem>
+          <para>HyperSQL Built-In Functions</para>
+
+          <para>Several additional built-in functions are available for some
+          useful operations. Some of these functions return the current
+          setting for the session and the database. The General Functions
+          accept arguments of different types and return values based on
+          comparison between the arguments.</para>
+        </listitem>
+      </itemizedlist></para>
+
+    <para>In the BNF specification used here, words in capital letters are
+    actual tokens. Syntactic elements such as expressions are enclosed in
+    angle brackets. The <literal>&lt;left paren&gt;</literal> and
+    <literal>&lt;right paren&gt;</literal> tokens are represented with the
+    actual symbol. Optional elements are enclosed with square brackets (
+    <literal>&lt;left bracket&gt;</literal> and <literal>&lt;right
+    bracket&gt;</literal> ). Multiple options for a required element are
+    enclosed with braces (<literal> &lt;left brace&gt;</literal> and
+    <literal>&lt;right brace&gt;</literal> )<literal>.</literal> Alternative
+    tokens are separated with the vertical bar ( <literal>&lt;vertical
+    bar&gt;</literal> ). At the end of each function definition, the standard
+    which specifies the function is noted in parentheses as JDBC or HyperSQL,
+    unless the function is in the SQL/Foundation part of the SQL
+    Standard.</para>
+  </section>
+
+  <section xml:id="builtin_functions_string-sect">
+    <title>String and Binary String Functions</title>
+
+    <para>In SQL, there are three kinds of string: character, binary and bit.
+    The units are respectively characters, octets, and bits. Each kind of
+    string can be in different data types. CHAR, VARCHAR and CLOB are the
+    character data types. BINARY, VARBINARY and BLOB are the binary data
+    types. BIT and BIT VARYING are the bit string types. In all string
+    functions, the position of a unit of the string within the whole string is
+    specified from 1 to the length of the whole string. In the BNF,
+    <literal>&lt;char value expr&gt; </literal>indicates any valid SQL
+    expression that evaluates to a character type. Likewise,
+    <literal>&lt;binary value expr&gt; </literal>indicates a binary type
+    and<literal> &lt;num value expr&gt; </literal>indicates a numeric
+    type.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ASCII function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ASCII</emphasis></simpara>
+
+    <para><literal>ASCII ( &lt;char value expr&gt; )</literal></para>
+
+    <para>Returns an INTEGER equal to the ASCII code value of the first
+    character of <literal>&lt;char value expr&gt;</literal>. (JDBC)</para>
+
+    <para><literal>CHAR ( &lt;UNICODE code&gt; ) </literal></para>
+
+    <para>The argument is an INTEGER. Returns a character string containing a
+    single character that has the specified<literal> &lt;UNICODE
+    code&gt;</literal>, which is an integer. ASCII codes are a subset of the
+    allowed values for <literal>&lt;UNICODE code&gt;</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CONCAT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CONCAT</emphasis></simpara>
+
+    <para><literal>CONCAT ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; )</literal></para>
+
+    <para><literal>CONCAT ( &lt;binary value expr 1&gt;, &lt;binary value expr
+    2&gt; )</literal></para>
+
+    <para>The arguments are character strings or binary strings. Returns a
+    string formed by concatenation of the arguments. Equivalent to the SQL
+    concatenation expression <literal>&lt;value expr 1&gt; || &lt;value expr
+    2&gt;</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DIFFERENCE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DIFFERENCE</emphasis></simpara>
+
+    <para><literal>DIFFERENCE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; )</literal></para>
+
+    <para>The arguments are character strings. Converts the arguments into
+    SOUNDEX codes, and returns an INTEGER between 0-4 which indicates how
+    similar the two SOUNDEX value are. If the values are the same, it returns
+    4, if the values have no similarity, it returns 0. In-between values are
+    returned for partial similarity. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>INSERT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">INSERT</emphasis></simpara>
+
+    <para><literal>INSERT ( &lt;char value expr 1&gt;, &lt;offset&gt;,
+    &lt;length&gt;, &lt;char value expr 2&gt; )</literal></para>
+
+    <para>Returns a character string based on <literal>&lt;char value expr
+    1&gt;</literal> in which <literal>&lt;length&gt;</literal> characters have
+    been removed from the <literal>&lt;offset&gt;</literal> position and in
+    their place, the whole <literal>&lt;char value expr 2&gt;</literal> is
+    copied. Equivalent to SQL/Foundation <literal>OVERLAY( &lt;char value
+    expr1&gt; PLACING &lt; char value expr2&gt; FROM &lt;offset&gt; FOR
+    &lt;length&gt; )</literal> . (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>HEXTORAW function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">HEXTORAW</emphasis></simpara>
+
+    <para><literal>HEXTORAW( &lt;char value expr&gt; )</literal></para>
+
+    <para>Returns a BINARY string formed by translation of hexadecimal digits
+    and letters in the &lt;<literal>char value expr&gt;</literal>. Each
+    character of the <literal>&lt;char value expr&gt;</literal> must be a
+    digit or a letter in the A | B | C | D | E | F set. Each byte of the
+    retired binary string is formed by translating two hex digits into one
+    byte. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LCASE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LCASE</emphasis></simpara>
+
+    <para><literal>LCASE ( &lt;char value expr&gt; ) </literal></para>
+
+    <para>Returns a character string that is the lower case version of the
+    <literal>&lt;char value expr&gt;</literal>. Equivalent to SQL/Foundation
+    <literal>LOWER (&lt;char value expr&gt;)</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LEFT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LEFT</emphasis></simpara>
+
+    <para><literal>LEFT ( &lt;char value expr&gt;, &lt;length&gt; )
+    </literal></para>
+
+    <para>Returns a character string consisting of the first
+    <literal>&lt;length&gt;</literal> characters of <literal>&lt;char value
+    expr&gt;</literal>. Equivalent to SQL/Foundation<literal>
+    SUBSTRING(&lt;char value expr&gt; FROM 0 FOR &lt;length&gt;)</literal>.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LENGTH function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LENGTH</emphasis></simpara>
+
+    <para><literal>LENGTH ( &lt;char value expr&gt; ) </literal></para>
+
+    <para>Returns as a BIGINT value the number of characters in
+    <literal>&lt;char value expr&gt;</literal>. Equivalent to SQL/Foundation
+    <literal>CHAR_LENGTH(&lt;char value expr&gt;)</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LOCATE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LOCATE</emphasis></simpara>
+
+    <para><literal>LOCATE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; [ , &lt;offset&gt; ] ) </literal></para>
+
+    <para>Returns as a BIGINT value the starting position of the first
+    occurrence of <literal>&lt;char value expr 1&gt;</literal> within
+    <literal>&lt;char value expr 2&gt;</literal>. If
+    <literal>&lt;offset</literal>&gt; is specified, the search begins with the
+    position indicated by <literal>&lt;offset&gt;</literal>. If the search is
+    not successful, 0 is returned. Equivalent to SQL/Foundation
+    <literal>POSITION(&lt;char value expr 1&gt; IN &lt;char value expr
+    2&gt;)</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LTRIM function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LTRIM</emphasis></simpara>
+
+    <para><literal>LTRIM ( &lt;char value expr&gt; ) </literal></para>
+
+    <para>Returns a character string based on <literal>&lt;char value
+    expr&gt;</literal> with the leading space characters removed. Equivalent
+    to SQL/Foundation <literal>TRIM( LEADING ' ' FROM &lt;char value expr&gt;
+    )</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>RAWTOHEX function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">RAWTOHEX</emphasis></simpara>
+
+    <para><literal>RAWTOHEX( &lt;binary value expr&gt; )</literal></para>
+
+    <para>Returns a character string composed of hexadecimal digits
+    representing the bytes in the <literal>&lt;binary value
+    expr&gt;</literal>. Each byte of the <literal>&lt;binary value
+    expr&gt;</literal> is translated into two hex digits. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>REGEXP_MATCHES function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">REGEXP_MATCHES</emphasis></simpara>
+
+    <para><literal>REGEXP_MATCHES ( &lt;char value expr&gt;, &lt;regular
+    expression&gt; ) </literal></para>
+
+    <para>Returns true if the &lt;char value expr&gt; matches the &lt;regular
+    expression&gt;. The &lt;regular expression&gt; is defined according to
+    Java language rules. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>REPEAT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">REPEAT</emphasis></simpara>
+
+    <para><literal>REPEAT ( &lt;char value expr&gt;, &lt;count&gt; )
+    </literal></para>
+
+    <para>Returns a character string based on<literal> &lt;char value
+    expr&gt;</literal>, repeated <literal>&lt;count&gt;</literal> times.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>REPLACE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">REPLACE</emphasis></simpara>
+
+    <para><literal>REPLACE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt;, &lt;char value expr 3&gt; )</literal></para>
+
+    <para>Returns a character string based on <literal>&lt;char value expr
+    1&gt;</literal> where each occurrence of <literal>&lt;char value expr
+    2&gt;</literal> has been replaced with a copy of <literal>&lt;char value
+    expr 3&gt;</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>REVERSE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">REVERSE</emphasis></simpara>
+
+    <para><literal>REVERSE ( &lt;char value expr&gt; )</literal></para>
+
+    <para>Returns a character string based on <literal>&lt;char value
+    expr&gt;</literal> with characters in the reverse order. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>RIGHT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">RIGHT</emphasis></simpara>
+
+    <para><literal>RIGHT ( &lt;char value expr&gt;, &lt;count&gt; )
+    </literal></para>
+
+    <para>Returns a character string consisting of the last
+    <literal>&lt;count&gt;</literal> characters of <literal>&lt;char value
+    expr&gt;</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>RTRIM function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">RTRIM</emphasis></simpara>
+
+    <para><literal>RTRIM ( &lt;char value expr&gt; ) </literal></para>
+
+    <para>Returns a character string based on <literal>&lt;char value
+    expr&gt;</literal> with the trailing space characters removed. Equivalent
+    to SQL/Foundation <literal>TRIM(TRAILING ' ' FROM &lt;character
+    string&gt;)</literal>. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SOUNDEX function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SOUNDEX</emphasis></simpara>
+
+    <para><literal>SOUNDEX ( &lt;char value expr&gt; ) </literal></para>
+
+    <para>Returns a four character code representing the sound of
+    <literal>&lt;char value expr&gt;</literal>. The US census algorithm is
+    used. For example the soundex value for Washington is W252. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SPACE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SPACE</emphasis></simpara>
+
+    <para><literal>SPACE ( &lt;count&gt; ) </literal></para>
+
+    <para>Returns a character string consisting of <literal>&lt;count&gt;
+    </literal>spaces. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SUBSTR function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SUBSTR</emphasis></simpara>
+
+    <para><literal>{ SUBSTR | SUBSTRING } ( &lt;char value expr&gt;,
+    &lt;offset&gt;, &lt;length&gt; )</literal></para>
+
+    <para>The JDBC version of SQL/Foundation <literal>SUBSTRING</literal>
+    returns a character string that consists of
+    <literal>&lt;length&gt;</literal> characters from <literal>&lt;char value
+    expr&gt; </literal>starting at the <literal>&lt;offset&gt;</literal>
+    position. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>UCASE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">UCASE</emphasis></simpara>
+
+    <para><literal>UCASE ( &lt;char value expr&gt; ) </literal></para>
+
+    <para>Returns a character string that is the lower case version of the
+    <literal>&lt;char value expr&gt;</literal>. Equivalent to SQL/Foundation
+    <literal>UPPER( &lt;char value expr&gt; )</literal> . (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CHARACTER_LENGTH</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CHARACTER_LENGTH</emphasis></simpara>
+
+    <para><literal>{ CHAR_LENGTH | CHARACTER_LENGTH } ( &lt;char value
+    expression&gt; [ USING { CHARACTERS | OCTETS } ] )</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>OCTET_LENGTH function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">OCTET_LENGTH</emphasis></simpara>
+
+    <para><literal>OCTET_LENGTH ( &lt;string value expression&gt;
+    )</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>BIT_LENGTH function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">BIT_LENGTH</emphasis></simpara>
+
+    <para><literal>BIT_LENGTH ( &lt;string value expression&gt;
+    )</literal></para>
+
+    <para>The CHAR_LENGTH or CHARACTER_LENGTH function can be used with
+    character strings, while OCTET_LENGTH can be used with character or binary
+    strings and BIT_LENGTH can be used with character, binary and bit
+    strings.</para>
+
+    <para>All functions return a BIGINT value that measures the length of the
+    string in the given unit. CHAR_LENGTH counts characters, OCTET_LENGTH
+    counts octets and BIT_LENGTH counts bits in the string. For CHAR_LENGTH,
+    if <literal>[ USING OCTETS ] </literal>is specified, the octet count is
+    returned. (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>OVERLAY function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">OVERLAY</emphasis></simpara>
+
+    <para><literal>OVERLAY ( &lt;char value expr 1&gt; PLACING &lt;char value
+    expr 2&gt;</literal></para>
+
+    <para><literal>FROM &lt;start position&gt; [ FOR &lt;string length&gt; ] [
+    USING CHARACTERS ] )</literal></para>
+
+    <para><literal>OVERLAY ( &lt;binary value expr 1&gt; PLACING &lt;binary
+    value expr 2&gt;</literal></para>
+
+    <para><literal>FROM &lt;start position&gt; [ FOR &lt;string length&gt; ]
+    )</literal></para>
+
+    <para>The character version of OVERLAY returns a character string based on
+    <literal>&lt;char value expr 1&gt;</literal> in which <literal>&lt;string
+    length&gt;</literal> characters have been removed from the
+    <literal>&lt;start position&gt;</literal> and in their place, the whole
+    <literal>&lt;char value expr 2&gt;</literal> is copied.</para>
+
+    <para>The binary version of OVERLAY returns a binary string formed in the
+    same manner as the character version. (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>POSITION function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">POSITION</emphasis></simpara>
+
+    <para><literal>POSITION ( &lt;char value expr 1&gt; IN &lt;char value expr
+    2&gt; [ USING CHARACTERS ] )</literal></para>
+
+    <para><literal>POSITION ( &lt;binary value expr 1&gt; IN &lt;binary value
+    expr 2&gt; )</literal></para>
+
+    <para>The character and binary versions of POSITION search the string
+    value of the second argument for the first occurrence of the first
+    argument string. If the search is successful, the position in the string
+    is returned as a BIGINT. Otherwise zero is returned.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SUBSTRING function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SUBSTRING</emphasis></simpara>
+
+    <para><literal>SUBSTRING ( &lt;char value expr&gt; FROM &lt;start
+    position&gt; [ FOR &lt;string length&gt; ] [ USING CHARACTERS ]
+    )</literal></para>
+
+    <para><literal>SUBSTRING ( &lt;binary value expr&gt; FROM &lt;start
+    position&gt; [ FOR &lt;string length&gt; ] )</literal></para>
+
+    <para>The character version of SUBSTRING returns a character string that
+    consists of the characters of the <literal>&lt;char value expr&gt;
+    </literal>from <literal>&lt;start position&gt;</literal>. If the
+    optional<literal> &lt;string length&gt;</literal> is specified, only
+    <literal>&lt;string length&gt; </literal>characters are returned.</para>
+
+    <para>The binary version of SUBSTRING returns a binary string in the same
+    manner. (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TRIM function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TRIM</emphasis></simpara>
+
+    <para><literal>TRIM ([ [ LEADING | TRAILING | BOTH ] [ &lt;trim
+    character&gt; ] FROM ] &lt;char value expr&gt; )</literal></para>
+
+    <para><literal>TRIM ([ [ LEADING | TRAILING | BOTH ] [ &lt;trim octet&gt;
+    ] FROM ] &lt;binary value expr&gt; )</literal></para>
+
+    <para>The character version of TRIM returns a character string based on
+    <literal>&lt;char value expr&gt;</literal>. Consecutive instances of
+    <literal>&lt;trim character&gt; </literal>are removed from the beginning,
+    the end or both ends of the<literal>&lt;char value expr&gt;
+    </literal>depending on the value of the optional first qualifier
+    <literal>[ LEADING | TRAILING | BOTH ]</literal>. If no qualifier is
+    specified, <literal>BOTH </literal>is used as default. If <literal>[
+    &lt;trim character&gt; ]</literal> is not specified, the space character
+    is used as default.</para>
+
+    <para>The binary version of TRIM returns a binary string based on
+    <literal>&lt;binary value expr&gt;</literal>. Consecutive instances of
+    <literal>&lt;trim octet&gt; </literal>are removed in the same manner as in
+    the character version. If<literal> [ &lt;trim octet&gt; ]</literal> is not
+    specified, the 0 octet is used as default. (Foundation)</para>
+  </section>
+
+  <section xml:id="builtin_functions_numeric-sect">
+    <title>Numeric Functions</title>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ABS function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ABS</emphasis></simpara>
+
+    <para><literal>ABS ( &lt;num value expr&gt; | &lt;interval value expr&gt;
+    ) </literal></para>
+
+    <para>Returns the absolute value of the argument as a value of the same
+    type. (JDBC and Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ACOS function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ACOS</emphasis></simpara>
+
+    <para><literal>ACOS ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the arc-cosine of the argument in radians as a value of
+    DOUBLE type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ASIN function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ASIN</emphasis></simpara>
+
+    <para><literal>ASIN ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the arc-sine of the argument in radians as a value of DOUBLE
+    type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ATAN function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ATAN</emphasis></simpara>
+
+    <para><literal>ATAN ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the arc-tangent of the argument in radians as a value of
+    DOUBLE type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ATAN2 function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ATAN2</emphasis></simpara>
+
+    <para><literal>ATAN2 ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    ) </literal></para>
+
+    <para>The <literal>&lt;num value expr 1&gt;</literal> and <literal>&lt;num
+    value expr 2&gt;</literal> express the <varname>x</varname> and
+    <varname>y</varname> coordinates of a point. Returns the angle, in
+    radians, representing the angle coordinate of the point in polar
+    coordinates, as a value of DOUBLE type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CEIL function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CEILING</emphasis></simpara>
+
+    <para><literal>{ CEIL | CEILING } ( &lt;num value expr&gt; )
+    </literal></para>
+
+    <para>Returns the smallest integer greater than or equal to the argument.
+    If the argument is exact numeric then the result is exact numeric with a
+    scale of 0. If the argument is approximate numeric, then the result is of
+    DOUBLE type. (JDBC and Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>BITAND function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">BITAND</emphasis></simpara>
+
+    <para><literal>BITAND ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</literal></para>
+
+    <para><literal>BITAND ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>BITOR function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">BITOR</emphasis></simpara>
+
+    <para><literal>BITOR ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</literal></para>
+
+    <para><literal>BITOR ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>BITXOR function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">BITXOR</emphasis></simpara>
+
+    <para><literal>BITXOR ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</literal></para>
+
+    <para><literal>BITXOR ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</literal></para>
+
+    <para>These three functions perform the bit operations: OR, AND, XOR, on
+    two values. The values are either integer values, or bit strings. The
+    result is an integer value of the same type as the arguments, or a bit
+    string of the same length as the argument. Each bit of the result is
+    formed by performing the operation on corresponding bits of the arguments.
+    (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>COS function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">COS</emphasis></simpara>
+
+    <para><literal>COS ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the cosine of the argument (an angle expressed in radians)
+    as a value of DOUBLE type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>COT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">COT</emphasis></simpara>
+
+    <para><literal>COT ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the cotangent of the argument as a value of DOUBLE type. The
+    <literal>&lt;num value expr&gt;</literal> represents an angle expressed in
+    radians. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DEGREES function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DEGREES</emphasis></simpara>
+
+    <para><literal>DEGREES ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Converts the argument (an angle expressed in<literal>
+    radians</literal>) into degrees and returns the value in the DOUBLE type.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>EXP function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">EXP</emphasis></simpara>
+
+    <para><literal>EXP ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the exponential value of the argument as a value of DOUBLE
+    type. (JDBC and Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>FLOOR function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">FLOOR</emphasis></simpara>
+
+    <para><literal>FLOOR ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the largest integer that is less than or equal to the
+    argument. If the argument is exact numeric then the result is exact
+    numeric with a scale of 0. If the argument is approximate numeric, then
+    the result is of DOUBLE type. (JDBC and Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LN function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LN</emphasis></simpara>
+
+    <para><literal>LN ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the natural logarithm of the argument, as a value of DOUBLE
+    type. (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LOG function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LOG</emphasis></simpara>
+
+    <para><literal>LOG ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the natural logarithm of the argument, as a value of DOUBLE
+    type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LOG10 function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LOG10</emphasis></simpara>
+
+    <para><literal>LOG10 ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the base 10 logarithm of the argument as a value of DOUBLE
+    type. (JDBC)</para>
+
+    <para><literal>MOD ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt; )
+    </literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>MOD function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">MOD</emphasis></simpara>
+
+    <para>Returns the remainder (modulus) of <literal>&lt;num value expr
+    1&gt;</literal> divided by <literal>&lt;num value expr 2&gt;.</literal>
+    The data type of the returned value is the same as the second argument.
+    (JDBC and Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>PI function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">PI</emphasis></simpara>
+
+    <para><literal>PI () </literal></para>
+
+    <para>Returns the constant pi as a value of DOUBLE type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>POWER function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">POWER</emphasis></simpara>
+
+    <para><literal>POWER ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    ) </literal></para>
+
+    <para>Returns the value of <literal>&lt;num value expr 1&gt;</literal>
+    raised to the power of <literal>&lt;int value expr 2&gt;</literal> as a
+    value of DOUBLE type. (JDBC and Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>RADIANS function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">RADIANS</emphasis></simpara>
+
+    <para><literal>RADIANS ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Converts the argument (an angle expressed in<literal>
+    degrees</literal>) into radians and returns the value in the DOUBLE type.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>RAND function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">RAND</emphasis></simpara>
+
+    <para><literal>RAND ( [ &lt;int value expr&gt; ] ) </literal></para>
+
+    <para>Returns a random value in the DOUBLE type. The optional <literal>[
+    &lt;int value expr&gt; ]</literal> is used as seed value. In HyperSQL each
+    session has a separate random number generator. The first call that uses a
+    seed parameter sets the seed for subsequent calls that do not include a
+    parameter. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ROUND function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ROUND</emphasis></simpara>
+
+    <para><literal>ROUND ( &lt;num value expr&gt;, &lt;int value expr&gt; )
+    </literal></para>
+
+    <para>The <literal>&lt;num value expr&gt; </literal>is of the DOUBLE type.
+    The function returns a DOUBLE value which is the value of the argument
+    rounded to <literal>&lt;int value expr&gt;</literal> places right of the
+    decimal point. If <literal>&lt;int value expr&gt;</literal> is negative,
+    the first argument is rounded to <literal>&lt;int value expr&gt;</literal>
+    places to the left of the decimal point. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SIGN function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SIGN</emphasis></simpara>
+
+    <para><literal>SIGN ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns an INTEGER, indicating the sign of the argument. If the
+    argument is negative then -1 is returned. If it is equal to zero then 0 is
+    returned. If the argument is positive then 1 is returned. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SIN function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SIN</emphasis></simpara>
+
+    <para><literal>SIN ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the sine of the argument (an angle expressed in radians) as
+    a value of DOUBLE type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SQRT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SQRT</emphasis></simpara>
+
+    <para><literal>SQRT ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the square root of the argument as a value of DOUBLE type.
+    (JDBC and Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TAN function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TAN</emphasis></simpara>
+
+    <para><literal>TAN ( &lt;num value expr&gt; ) </literal></para>
+
+    <para>Returns the tangent of the argument (an angle expressed in radians)
+    as a value of DOUBLE type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TRUNCATE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TRUNCATE</emphasis></simpara>
+
+    <para><literal>TRUNCATE ( &lt;num value expr&gt;, &lt;int value expr&gt; )
+    </literal></para>
+
+    <para>Returns a value in the same type as <literal>&lt;num value
+    expr&gt;</literal>. The value is rounded by replacing digits with zeros
+    from <literal>&lt;int value expr&gt;</literal> places right of the decimal
+    point to the end. If <literal>&lt;int value expr&gt;</literal> is
+    negative, <literal>ABS( &lt;int value expr&gt; )</literal> digits to left
+    of the decimal point and all digits to the right of the decimal points are
+    replaced with zeros. Results of calling TRUNCATE with 12345.6789 with (-2,
+    0, 2, 4) are (12300.0000, 12345.0000, 12345.6700, 12345.6789).
+    (JDBC)</para>
+  </section>
+
+  <section xml:id="builtin_functions_datetime-sect">
+    <title>Date Time and Interval Functions</title>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TIMEZONE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TIMEZONE</emphasis></simpara>
+
+    <para><literal>TIMEZONE()</literal></para>
+
+    <para>Returns the current time zone for the session. Returns an INTERVAL
+    HOUR TO MINUTE value. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SESSION_TIMEZONE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SESSION_TIMEZONE</emphasis></simpara>
+
+    <para><literal>SESSION_TIMEZONE()</literal></para>
+
+    <para>Returns the default time zone for the current session. Returns an
+    INTERVAL HOUR TO MINUTE value. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DATABASE_TIMEZONE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DATABASE_TIMEZONE</emphasis></simpara>
+
+    <para><literal>DATABASE_TIMEZONE()</literal></para>
+
+    <para>Returns the time zone for the database engine. This is based on
+    where the database server process is located. Returns an INTERVAL HOUR TO
+    MINUTE value. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>EXTRACT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">EXTRACT</emphasis></simpara>
+
+    <para><literal>EXTRACT ( &lt;extract field&gt; FROM &lt;extract source&gt;
+    )</literal></para>
+
+    <para><literal>&lt;extract field&gt; ::= YEAR | MONTH | DAY | HOUR |
+    MINUTE | DAY_OF_WEEK | WEEK_OF_YEAR | QUARTER | DAY_OF_YEAR | DAY_OF_MONTH
+    |</literal></para>
+
+    <para><literal>TIMEZONE_HOUR | TIMEZONE_MINUTE | SECOND |
+    SECONDS_SINCE_MIDNIGHT |</literal></para>
+
+    <para><literal>DAY_NAME | MONTH_NAME</literal></para>
+
+    <para><literal>&lt;extract source&gt; ::= &lt;datatime value expr&gt; |
+    &lt;interval value expr&gt;</literal></para>
+
+    <para>The EXTRACT function returns a field or element of the
+    <literal>&lt;extract source&gt;</literal>. The <literal>&lt;extract
+    source&gt;</literal> is a datetime or interval expression. The type of the
+    return value is BIGINT for most of the<literal> &lt;extract
+    field&gt;</literal> options. The exceptions is <literal>SECOND
+    </literal>where a DECIMAL value is returned which has the same precision
+    as the datetime or interval expression. The field values <literal>DAY_NAME
+    </literal>or<literal> MONTH_NAME </literal>result in a character string.
+    When <literal>MONTH_NAME</literal> is specified, a string in the range
+    January - December is returned. When <literal>DAY_NAME </literal>is
+    specified, a string in the range Sunday -Saturday is returned.</para>
+
+    <para>If the <literal>&lt;extract source&gt;</literal> is <literal>FROM
+    &lt;datatime value expr&gt;</literal>, different groups of
+    <literal>&lt;extract source&gt;</literal> can be used depending on the
+    data type of the expression. The <literal>TIMEZONE_HOUR |
+    TIMEZONE_MINUTE</literal> options are valid only for TIME WITH TIMEZONE
+    and TIMESTAMP WITH TIMEZONE data types. The <literal>HOUR | MINUTE |
+    SECOND | SECONDS_MIDNIGHT</literal> options, are valid for TIME and
+    TIMESTAMP types. The rest of the fields are valid for DATE and TIMESTAMP
+    types.</para>
+
+    <para>If the <literal>&lt;extract source&gt;</literal> is <literal>FROM
+    &lt;interval value expr&gt;</literal>, the <literal>&lt;extract
+    field&gt;</literal> must be one of the fields of the INTERVAL type of the
+    expressions. The <literal>YEAR | MONTH</literal> options may be valid for
+    INTERVAL types based on months. The <literal>DAY | HOUR | MINUTE | SECOND
+    | SECONDS_MIDNIGHT</literal> options may be valid for INTERVAL types based
+    on seconds. For example,<literal> DAY | HOUR | MINUTE</literal> are the
+    only valid fields for the INTERVAL DAY TO MINUTE data type. (Foundation
+    with HyperSQL extensions)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURRENT_DATE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURRENT_DATE</emphasis></simpara>
+
+    <para><literal>CURRENT_DATE</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURRENT_TIME function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURRENT_TIME</emphasis></simpara>
+
+    <para><literal>CURRENT_TIME [ ( &lt;time precision&gt; )
+    ]</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LOCALTIME function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LOCALTIME</emphasis></simpara>
+
+    <para><literal>LOCALTIME [ ( &lt;time precision&gt; ) ]</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURRENT_TIMESTAMP function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURRENT_TIMESTAMP</emphasis></simpara>
+
+    <para><literal>CURRENT_TIMESTAMP [ ( &lt;timestamp precision&gt; )
+    ]</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LOCALTIMESTAMP function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LOCALTIMESTAMP</emphasis></simpara>
+
+    <para><literal>LOCALTIMESTAMP [ ( &lt;timestamp precision&gt; )
+    ]</literal></para>
+
+    <para>These datetime functions return the datetime value representing the
+    moment the function is called. CURRENT_DATE returns a value of DATE type.
+    CURRENT_TIME returns a value of TIME WITH TIME ZONE type. LOCALTIME
+    returns a value of TIME type. CURRENT_TIMESTAMP returns a value of
+    TIMESTAMP WITH TIME ZONE type. LOCALTIMESTAMP returns a value of TIMESTAMP
+    type. If the optional <literal>[ ( &lt;time precision&gt; ) ]</literal>
+    or<literal> [ ( &lt;timestamp precision&gt; ) ]</literal> is used, then
+    the returned value has the specified fraction of the second precision.
+    (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURDATE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURDATE</emphasis></simpara>
+
+    <para><literal>CURDATE ()</literal></para>
+
+    <para>This function is equivalent to<literal> CURRENT_DATE.
+    </literal>(JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURTIME function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURTIME</emphasis></simpara>
+
+    <para><literal>CURTIME ()</literal></para>
+
+    <para>This function is equivalent to<literal> LOCALTIME</literal>.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DAYNAME function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DAYNAME</emphasis></simpara>
+
+    <para><literal>DAYNAME ( &lt;datatime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to<literal> EXTRACT ( DAY_NAME FROM ...
+    ) </literal>Returns a string in the range of Sunday - Saturday.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DAYOFMONTH function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DAYOFMONTH</emphasis></simpara>
+
+    <para><literal>DAYOFMONTH ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to<literal> EXTRACT ( DAY_OF_MONTH FROM
+    ... ) </literal>Returns an integer value in the range of 1-31.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DAYOFWEEK function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DAYOFWEEK</emphasis></simpara>
+
+    <para><literal>DAYOFWEEK ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to <literal>EXTRACT ( DAY_OF_WEEK FROM
+    ... ) </literal>Returns an integer value in the range of 1-7. The first
+    day of the week is Sunday. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DAYOFYEAR function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DAYOFYEAR</emphasis></simpara>
+
+    <para><literal>DAYOFYEAR ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to <literal>EXTRACT ( DAY_OF_YEAR FROM
+    ... ) </literal>Returns an integer value in the range of 1-366.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>HOUR function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">HOUR</emphasis></simpara>
+
+    <para><literal>HOUR ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to <literal>EXTRACT ( HOUR FROM ... )
+    </literal>Returns an integer value in the range of 0-23. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>MINUTE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">MINUTE</emphasis></simpara>
+
+    <para><literal>MINUTE ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to<literal> EXTRACT ( MINUTE FROM ... )
+    </literal>Returns an integer value in the range of 0 - 59. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>MONTH function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">MONTH</emphasis></simpara>
+
+    <para><literal>MONTH ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to <literal>EXTRACT ( MONTH FROM ... )
+    </literal>Returns an integer value in the range of 1-12. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>MONTHNAME function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">MONTHNAME</emphasis></simpara>
+
+    <para><literal>MONTHNAME ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to <literal>EXTRACT ( NAME_OF_MONTH FROM
+    ... ) </literal>Returns a string in the range of January - December.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>NOW function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">NOW</emphasis></simpara>
+
+    <para><literal>NOW ()</literal></para>
+
+    <para>This function is equivalent to
+    <literal>LOCAL_TIMESTAMP.</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>QUARTER function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">QUARTER</emphasis></simpara>
+
+    <para><literal>QUARTER ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to <literal>EXTRACT ( QUARTER FROM ... )
+    </literal>Returns an integer in the range of 1 - 4. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SECOND function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SECOND</emphasis></simpara>
+
+    <para><literal>SECOND ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to <literal>EXTRACT ( SECOND FROM ... )
+    </literal>Returns an integer or decimal in the range of 0 - 59, with the
+    same precision as the &lt;datetime value expr&gt;. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SECONDS_SINCE_MIDNIGHT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SECONDS_SINCE_MIDNIGHT</emphasis></simpara>
+
+    <para><literal>SECONDS_SINCE_MIDNIGHT ( &lt;datetime value expr&gt;
+    )</literal></para>
+
+    <para>This function is equivalent to<literal> EXTRACT (
+    SECONDS_SINCE_MIDNIGHT FROM ... ) </literal>Returns an integer in the
+    range of 0 - 86399. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>WEEK function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">WEEK</emphasis></simpara>
+
+    <para><literal>WEEK ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to<literal> EXTRACT ( WEEK_OF_YEAR FROM
+    ... ) </literal>Returns an integer in the range of 1 - 54. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>YEAR function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">YEAR</emphasis></simpara>
+
+    <para><literal>YEAR ( &lt;datetime value expr&gt; )</literal></para>
+
+    <para>This function is equivalent to<literal> EXTRACT ( YEAR FROM ... )
+    </literal>Returns an integer in the range of 1 - 9999. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TIMESTAMPADD function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TIMESTAMPADD</emphasis></simpara>
+
+    <para><literal>TIMESTAMPADD ( &lt;tsi datetime field&gt;, &lt;numeric
+    value expression&gt;, &lt;datetime value expr&gt;)</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TIMESTAMPDIFF function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TIMESTAMPDIFF</emphasis></simpara>
+
+    <para><literal>TIMESTAMPDIFF ( &lt;tsi datetime field&gt;, &lt;datetime
+    value expr 1&gt;, &lt;datetime value expr 2&gt;)</literal></para>
+
+    <para><literal>&lt;tsi datetime field&gt; ::= SQL_TSI_FRAC_SECOND |
+    SQL_TSI_SECOND | SQL_TSI_MINUTE | SQL_TSI_HOUR | SQL_TSI_DAY |
+    SQL_TSI_WEEK | SQL_TSI_MONTH | SQL_TSI_QUARTER |
+    SQL_TSI_YEAR</literal></para>
+
+    <para>HyperSQL supports full SQL Standard datetime features. It supports
+    adding integers representing units of time directly to datetime values
+    using the arithmetic plus operator. It also supports subtracting one
+    <literal>&lt;datetime value expr&gt;</literal> from another in the given
+    units of days using the minus operator. An example of
+    <literal>&lt;datetime value expr&gt; + &lt;numeric value expression&gt;
+    &lt;datetime field&gt; </literal>is <literal>LOCAL_TIMESTAMP + 5
+    DAY</literal>. An example of <literal>( &lt;datetime value expr&gt; -
+    &lt;numeric value expression&gt; ) &lt;datetime field&gt; </literal>is
+    <literal>(CURRENT_DATE - DATE '2008-08-8') MONTH </literal>which returns
+    the number of calendar months between the two dates.</para>
+
+    <para>The two JDBC functions, <literal>TIMESTAMPADD </literal>and
+    <literal>TIMESTAMPDIFF</literal> perform the same function as above SQL
+    expressions. The field names are keywords and are different from those
+    used in the EXTRACT functions. These names are valid for use only when
+    calling these two functions. The return value for TIMESTAMPADD is of the
+    same type as the datetime argument used. The return type for TIMESTAMPDIFF
+    is always BIGINT, regardless of the type of arguments. The two datetime
+    arguments of TIMESTAMPDIFF should be of the same type. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DATEADD function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DATEADD</emphasis></simpara>
+
+    <para><literal>DATEADD ( &lt;field&gt;, &lt;numeric value expr&gt;,
+    &lt;datetime value expr&gt; )</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DATEDIFF function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DATEDIFF</emphasis></simpara>
+
+    <para><literal>DATEDIFF ( &lt;field&gt;, &lt;datetime value expr 1&gt;,
+    datetime value expr 2&gt; )</literal></para>
+
+    <para><literal>&lt;field&gt; ::= 'yy' | 'mm' | 'dd' | 'hh' | 'mi' | 'ss' |
+    'ms'</literal></para>
+
+    <para>The DATEADD and DATEDIFF functions are alternatives to TIMESTAMPADD
+    and TIMESTAMPDIFF, with fewer available field options. The field names are
+    specified as strings, rather than keywords. The fields translate to YEAR,
+    MONTH, DAY, HOUR, MINUTE, SECOND and MILLISECOND. (HyperSQL}</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TO_CHAR function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TO_CHAR</emphasis></simpara>
+
+    <para><literal>TO_CHAR( &lt;datetime value expr&gt;, &lt;char value
+    expr&gt; )</literal></para>
+
+    <para>This function formats a datetime or numeric value to the format
+    specified by the pattern given in the second argument. The pattern can
+    contain pattern elements from the list given below, plus punctuation and
+    space characters. An example, including the result, is given below:</para>
+
+    <programlisting>TO_CHAR ( TIMESTAMP'2008-02-01 20:30:40', 'YYYY BC MONTH, DAY HH')
+
+2008 AD February, Friday 8
+</programlisting>
+
+    <para>The format is internally translated to a
+    <classname>java.text.SimpleDateFormat</classname> format string. Any
+    character sequences not listed below are included in the Java format
+    string and may cause unexpected results or errors. Therefore unsupported
+    format strings should not be used. The supported format components are as
+    follows:</para>
+
+    <table colsep="1" frame="all" pgwide="0">
+      <title>TO CHAR Values</title>
+
+      <tgroup cols="2">
+        <colspec colwidth="5cm" />
+
+        <colspec />
+
+        <tbody>
+          <row>
+            <entry><literal>BC | B.C. | AD | A.D.</literal></entry>
+
+            <entry>Returns <literal>AD</literal> for common era and
+            <literal>BC</literal> for before common era</entry>
+          </row>
+
+          <row>
+            <entry><literal>RRRR</literal></entry>
+
+            <entry><para>4-digit year</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>YYYY</literal></entry>
+
+            <entry><para>4-digit year</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>IYYY</literal></entry>
+
+            <entry><para>4-digit year</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>YY</literal></entry>
+
+            <entry><para>2 digit year</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>IY</literal></entry>
+
+            <entry><para>2 digit year</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>IYYY</literal></entry>
+
+            <entry><para>4-digit year</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>MM</literal></entry>
+
+            <entry><para>Month (01-12)</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>MON</literal></entry>
+
+            <entry><para>Short three-letter name of month</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>MONTH</literal></entry>
+
+            <entry><para>Name of month</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>WW</literal></entry>
+
+            <entry><para>Week of year (1-53) where week 1 starts on the first
+            day of the year and continues to the seventh day of the
+            year.</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>W</literal></entry>
+
+            <entry><para>Week of month (1-5) where week 1 starts on the first
+            day of the month and ends on the seventh.</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>IW</literal></entry>
+
+            <entry><para>Week of year (1-52 or 1-53) based on the ISO
+            standard.</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>DAY</literal></entry>
+
+            <entry><para>Name of day.</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>DD</literal></entry>
+
+            <entry><para>Day of month (1-31).</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>DDD</literal></entry>
+
+            <entry><para>Day of year (1-366).</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>DY</literal></entry>
+
+            <entry><para>Short three-letter name of day.</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>HH</literal></entry>
+
+            <entry><para>Hour of day (0-11).</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>HH12</literal></entry>
+
+            <entry><para>Hour of day (0-11).</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>HH24</literal></entry>
+
+            <entry><para>Hour of day (0-23).</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>MI</literal></entry>
+
+            <entry><para>Minute (0-59).</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>SS</literal></entry>
+
+            <entry><para>Second (0-59).</para></entry>
+          </row>
+
+          <row>
+            <entry><literal>FF</literal></entry>
+
+            <entry><para>Fractional seconds.</para></entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+  </section>
+
+  <section>
+    <title>Array Functions</title>
+
+    <para>Array functions are specialised functions with ARRAY
+    parameters.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CARDINALITY function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CARDINALITY</emphasis></simpara>
+
+    <para><literal>CARDINALITY( &lt;array value expr&gt; )</literal></para>
+
+    <para>Returns the element count for the given array argument.
+    (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>MAX_CARDINALITY function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">MAX_CARDINALITY</emphasis></simpara>
+
+    <para><literal>MAX_CARDINALITY( &lt;array value expr&gt;
+    )</literal></para>
+
+    <para>Returns the maximum allowed element count for the given array
+    argument. (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TRIM_ARRAY function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TRIM_ARRAY</emphasis></simpara>
+
+    <para><literal>TRIM_ARRAY( &lt;array value expr&gt;, &lt;num value
+    expr&gt; )</literal></para>
+
+    <para>Returns a new array that contains the elements of the
+    <literal>&lt;array value expr&gt;</literal> minus the number of elements
+    specified by the <literal>&lt;num value expr&gt;. </literal>Elements are
+    discarded from the end of the array. (Foundation)</para>
+  </section>
+
+  <section>
+    <title>General Functions</title>
+
+    <para>General functions can take different types of arguments. Some
+    General Functions accept a variable number of arguments.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>COALESCE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">COALESCE</emphasis></simpara>
+
+    <para><literal>COALESCE( &lt;value expr 1&gt;, &lt;value expr 2&gt; [,
+    ...] )</literal></para>
+
+    <para>Returns <literal>&lt;value expr 1&gt;</literal> if it is not null,
+    otherwise returns <literal>&lt;value expr 2&gt;</literal> if not null and
+    so on. The type of both arguments must be comparable. (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CONVERT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CONVERT</emphasis></simpara>
+
+    <para><literal>CONVERT ( &lt;value expr&gt; , &lt;data type&gt;
+    )</literal></para>
+
+    <para><literal>&lt;data type&gt; ::= { SQL_BIGINT | SQL_BINARY | SQL_BIT
+    |SQL_BLOB | SQL_BOOLEAN | SQL_CHAR | SQL_CLOB | SQL_DATE | SQL_DECIMAL |
+    SQL_DATALINK |SQL_DOUBLE | SQL_FLOAT | SQL_INTEGER | SQL_LONGVARBINARY |
+    SQL_LONGNVARCHAR | SQL_LONGVARCHAR | SQL_NCHAR | SQL_NCLOB | SQL_NUMERIC |
+    SQL_NVARCHAR | SQL_REAL | SQL_ROWID | SQL_SQLXML | SQL_SMALLINT | SQL_TIME
+    | SQL_TIMESTAMP | SQL_TINYINT | SQL_VARBINARY | SQL_VARCHAR} [ (
+    &lt;precision, length or scale parameters&gt; ) ]</literal></para>
+
+    <para>The CONVERT function is a JDBC escape function, equivalent to the
+    SQL standard CAST expression. It converts the <literal>&lt;value
+    expr&gt;</literal> into the given <literal>&lt;data type&gt;</literal> and
+    returns the value. The <literal>&lt;data type&gt;</literal> options are
+    synthetic names made by prefixing type names with <literal>SQL_</literal>.
+    Some of the <literal>&lt;data type&gt;</literal> options represent valid
+    SQL types, but some are based on non-standard type names, namely
+    <literal>{ SQL_LONGNVARCHAR | SQL_LONGVARBINARY |SQL_LONGVARCHAR |
+    SQL_TINYINT }</literal>. None of the synthetic names can be used in any
+    other context than the CONVERT function.</para>
+
+    <para>The definition of CONVERT in the JDBC Standard does not allow the
+    precision, scale or length to be specified. This is required by the SQL
+    standard for BINARY, BIT, BLOB, CHAR, CLOB, VARBINARY and VARCHAR types
+    and is often needed for DECIMAL and NUMERIC. Therefore, HyperSQL allows
+    the use of precision, scale or length for the type definition when they
+    are valid for the type definition. HyperSQL also allows the use of real
+    type names (without the <literal>SQL_</literal> prefix). (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DECODE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DECODE</emphasis></simpara>
+
+    <para><literal>DECODE( &lt;value expr main&gt;, &lt;value expr match
+    1&gt;, &lt;value expr result 1&gt; [...,] [, &lt;value expr default&gt;]
+    )</literal></para>
+
+    <para>DECODE takes at least 3 arguments. The <literal>&lt;value expr
+    main&gt;</literal> is compared with <literal>&lt;value expr match
+    1&gt;</literal> and if it matches, <literal>&lt;value expr result
+    1&gt;</literal> is returned. If there are additional pairs of
+    <literal>&lt;value expr match n&gt;</literal> and <literal>&lt;value expr
+    result n&gt;</literal>, comparison is repeated until a match is found the
+    result is returned. If no match is found, the <literal>&lt;value expr
+    default&gt;</literal> is returned if it is specified, otherwise NULL is
+    returned. The type of the return value is a combination of the types of
+    the <literal>&lt;value expr result ... &gt;</literal> arguments.
+    (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>GREATEST function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">GREATEST</emphasis></simpara>
+
+    <para><literal>GREATEST( &lt;value expr 1&gt;, [&lt;value expr ...&gt;,
+    ...] )</literal></para>
+
+    <para>The GREATEST function takes one or more arguments. It compares the
+    arguments with each other and returns the greatest argument. The return
+    type is the combined type of the arguments. Arguments can be of any type,
+    so long as they are comparable. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>IFNULL function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">IFNULL</emphasis></simpara>
+
+    <para><literal>IFNULL( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</literal></para>
+
+    <para>Returns <literal>&lt;value expr 1&gt;</literal> if it is not null,
+    otherwise returns <literal>&lt;value expr 2&gt;</literal>. The type of
+    both arguments must be the same. Equivalent to SQL Standard
+    <literal>COALESCE(&lt;value expr 1&gt;, &lt;value expr 2&gt;)</literal>
+    function. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LEAST function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LEAST</emphasis></simpara>
+
+    <para><literal>LEAST( &lt;value expr 1&gt;, [&lt;value expr ...&gt;, ...]
+    )</literal></para>
+
+    <para>The LEAST function takes one or more arguments. It compares the
+    arguments with each other and returns the smallest argument. The return
+    type is the combined type of the arguments. Arguments can be of any type,
+    so long as they are comparable. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>NULLIF function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">NULLIF</emphasis></simpara>
+
+    <para><literal>NULLIF( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</literal></para>
+
+    <para>Returns <literal>&lt;value expr 1&gt;</literal> if it is not equal
+    to <literal>&lt;value expr 2&gt;</literal>, otherwise returns null. The
+    type of both arguments must be the same. This function is a shorthand for
+    a specific CASE expression. (Foundation)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>NVL function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">NVL</emphasis></simpara>
+
+    <para><literal>NVL( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</literal></para>
+
+    <para>Returns <literal>&lt;value expr 1&gt;</literal> if it is not null,
+    otherwise returns <literal>&lt;value expr 2&gt;</literal>. The type of the
+    return value is the combined type of the two value expressions. For
+    example, if &lt;value expr 1&gt; is an INTEGER column and
+    <literal>&lt;value expr 2&gt;</literal> is a DOUBLE constant, the return
+    type is DOUBLE. This function is the same as IFNULL and COALESCE
+    (HyperSQL)</para>
+  </section>
+
+  <section xml:id="builtin_functions_sysfunc-sect">
+    <title>System Functions</title>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CRYPT_KEY function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CRYPT_KEY</emphasis></simpara>
+
+    <para><literal>CRYPT_KEY( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</literal></para>
+
+    <para>Returns a binary string representation of a cryptography key for the
+    given cipher and cyptography provider. The cipher specification is
+    specified by <literal>&lt;value expr 1&gt;</literal> and the provider by
+    <literal>&lt;value expr 2&gt;</literal>. To use the default provider,
+    specify null for <literal>&lt;value expr 2&gt;</literal>.
+    (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>IDENTITY function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">IDENTITY</emphasis></simpara>
+
+    <para><literal>IDENTITY ()</literal></para>
+
+    <para>Returns the last IDENTITY value inserted into a row by the current
+    session. The statement, CALL IDENTITY() can be made after an INSERT
+    statement that inserts a row into a table with an IDENTITY column. The
+    CALL IDENTITY() statement returns the last IDENTITY value that was
+    inserted into a table by the current session. Each session manages this
+    function call separately and is not affected by inserts in other sessions.
+    The statement can be executed as a direct statement or a prepared
+    statement. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DATABASE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DATABASE</emphasis></simpara>
+
+    <para><literal>DATABASE ()</literal></para>
+
+    <para>Returns the file name (without directory information) of the
+    database. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DATABASE_VERSION function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DATABASE_VERSION</emphasis></simpara>
+
+    <para><literal>DATABASE_VERSION ()</literal></para>
+
+    <para>Returns the full version string for the database engine. For
+    example, 2.0.1. (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>USER function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">USER</emphasis></simpara>
+
+    <para><literal>USER ()</literal></para>
+
+    <para>Equivalent to the SQL function <literal>CURRENT_USER</literal>.
+    (JDBC)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURRENT_USER function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURRENT_USER</emphasis></simpara>
+
+    <para><literal>CURRENT_USER</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURRENT_ROLE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURRENT_ROLE</emphasis></simpara>
+
+    <para><literal>CURRENT_ROLE</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SESSION_USER function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SESSION_USER</emphasis></simpara>
+
+    <para><literal>SESSION_USER</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SYSTEM_USER function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SYSTEM_USER</emphasis></simpara>
+
+    <para><literal>SYSTEM_USER</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURRENT_SCHEMA function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURRENT_SCHEMA</emphasis></simpara>
+
+    <para><literal>CURRENT_SCHEMA</literal></para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CURRENT_CATALOG function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CURRENT_CATALOG</emphasis></simpara>
+
+    <para><literal>CURRENT_CATALOG</literal></para>
+
+    <para>These functions return the named current session attribute. They are
+    all SQL Standard functions.</para>
+
+    <para>The CURRENT_USER is the user that connected to the database, or a
+    user subsequently set by the SET AUTHORIZATION statement.</para>
+
+    <para>SESSION_USER is the same as CURRENT_USER</para>
+
+    <para>SYSTEM_USER is the user that connected to the database. It is not
+    changed with any command until the session is closed.</para>
+
+    <para>CURRENT_SCHEMA is default schema of the user, or a schema
+    subsequently set by the SET SCHEMA command.</para>
+
+    <para>CURRENT_CATALOG is always the same within a given HyperSQL database
+    and indicates the name of the catalog.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ISAUTOCOMMIT function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ISAUTOCOMMIT</emphasis></simpara>
+
+    <para><literal>ISAUTOCOMMIT()</literal></para>
+
+    <para>Returns TRUE if the session is in autocommit mode. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ISREADONLYSESSION function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ISREADONLYSESSION</emphasis></simpara>
+
+    <para><literal>ISREADONLYSESSION()</literal></para>
+
+    <para>Returns TRUE if the session is in read only mode. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ISREADONLYDATABASE function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ISREADONLYDATABASE</emphasis></simpara>
+
+    <para><literal>ISREADONLYDATABASE()</literal></para>
+
+    <para>Returns TRUE if the database is a read only database.
+    (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ISREADONLYDATABASEFILES function</primary>
+    </indexterm>
+
+    <simpara><emphasis
+    role="bold">ISREADONLYDATABASEFILES</emphasis></simpara>
+
+    <para><literal>ISREADONLYDATABASEFILES()</literal></para>
+
+    <para>Returns TRUE if the database is a read-only files database. In this
+    kind of database, it is possible to modify the data, but the changes are
+    not persisted to the database files. (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ISOLATION_LEVEL function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ISOLATION_LEVEL</emphasis></simpara>
+
+    <para><literal>ISOLATION_LEVEL()</literal></para>
+
+    <para>Returns the current transaction isolation level for the session.
+    Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SESSION_ISOLATION_LEVEL function</primary>
+    </indexterm>
+
+    <simpara><emphasis
+    role="bold">SESSION_ISOLATION_LEVEL</emphasis></simpara>
+
+    <para><literal>SESSION_ISOLATION_LEVEL()</literal></para>
+
+    <para>Returns the default transaction isolation level for the current
+    session. Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DATABASE_ISOLATION_LEVEL function</primary>
+    </indexterm>
+
+    <simpara><emphasis
+    role="bold">DATABASE_ISOLATION_LEVEL</emphasis></simpara>
+
+    <para><literal>DATABASE_ISOLATION_LEVEL()</literal></para>
+
+    <para>Returns the default transaction isolation level for the database.
+    Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TRANSACTION_CONTROL function</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TRANSACTION_CONTROL</emphasis></simpara>
+
+    <para><literal>TRANSACTION_CONTROL()</literal></para>
+
+    <para>Returns the current transaction model for the database. Returns
+    LOCKS, MVLOCKS or MVCC as a string. (HyperSQL)</para>
+  </section>
+</chapter>
diff --git a/doc-src/guide/dataaccess.xml b/doc-src/guide/dataaccess.xml
new file mode 100644
index 0000000..51d7240
--- /dev/null
+++ b/doc-src/guide/dataaccess.xml
@@ -0,0 +1,3127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="dataaccess-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/2000/svg"
+         xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="dataaccess-title">Data Access and Change</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+    <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section>
+    <title>Overview</title>
+
+    <para>HyperSQL data access and data change statements are fully compatible
+    with the latest SQL:2008 Standard. There are a few extensions and some
+    relaxation of rules, but these do not affect statements that are written
+    to the Standard syntax. There is full support for classic SQL, as
+    specified by SQL-92, and many enhancements added in later versions of the
+    standard.</para>
+  </section>
+
+  <section>
+    <title>Cursors And Result Sets</title>
+
+    <para>An SQL statement can executed in two ways. One way is to use the
+    <classname>java.sql.Statement</classname> interface. The Statement object
+    can be reused to execute completely different SQL statements.
+    Alternatively a <classname>PreparedStatment</classname> can be used to
+    execute an SQL statement repeatedly, and the statements can be
+    parameterized. Using either form, if the SQL statement is a query
+    expression, a <classname>ResultSet</classname> is returned.</para>
+
+    <para>In SQL, when a query expression (SELECT or similar SQL statement) is
+    executed, an ephemeral table is created. When this table is returned to
+    the application program, it is returned as a result set, which is accessed
+    row-by-row by a cursor. A JDBC <classname>ResultSet</classname> represents
+    an SQL result set and its cursor.</para>
+
+    <para>The minimal definition of a cursor is a list of rows with a position
+    that can move forward. Some cursors also allow the position to move
+    backwards or jump to any position in the list.</para>
+
+    <para>An SQL cursor has several attributes. These attributes depend on the
+    query expression. Some of these attributes can be overridden by specifying
+    qualifiers in the SQL statement or by specifying values for the parameters
+    of the JDBC <classname>Statement</classname> or
+    <classname>PreparedStatement</classname>.</para>
+
+    <section>
+      <title>Columns and Rows</title>
+
+      <para>The columns of the rows of the result set are determined by the
+      query expression. The number of columns and the type and name
+      characteristics of each column are known when the query expression is
+      compiled and before its execution. This metadata information remains
+      constant regardless of changes to the contents of the tables used in the
+      query expression. The metadata for the JDBC
+      <classname>ResultSet</classname> is in the form of a
+      <classname>ResultSetMetaData</classname> object. Various methods of the
+      <classname>ResultSetMetaData</classname> interface return different
+      properties of each column of the
+      <classname>ResultSet</classname>.</para>
+
+      <para>A result set may contain 0 or more rows. The rows are determined
+      by the execution of the query expression.</para>
+
+      <para>The <methodname>setMaxRows(int)</methodname> method of JDBC
+      <classname>Statement</classname> allows limiting the number of rows
+      returned by the statement. This limit is conceptually applied after the
+      result has been built, and the excess rows are discarded.</para>
+    </section>
+
+    <section>
+      <title>Navigation</title>
+
+      <para>A cursor is either scrollable or not. Scrollable cursors allow
+      accessing rows by absolute or relative positioning. No-scroll cursors
+      only allow moving to the next row. The cursor can be optionally declared
+      with the SQL qualifiers SCROLL, or NO SCROLL. The JDBC statement
+      parameter can be specified as: TYPE_FORWARD_ONLY and
+      TYPE_SCROLL_INSENSITIVE. The JDBC type TYPE_SCROLL_SENSITIVE is not
+      supported by HSQLDB.</para>
+
+      <para>The default is NO SCROLL or TYPE_FORWARD_ONLY.</para>
+
+      <para>When a JDBC <classname>ResultSet</classname> is opened, it is
+      positioned before the first row. Using the
+      <methodname>next()</methodname> method the position is moved to the
+      first row. While the <classname>ResultSet</classname> is positioned on a
+      row, various getter methods can be used to access the columns of the
+      row.</para>
+    </section>
+
+    <section>
+      <title>Updatability</title>
+
+      <para>The result returned by some query expressions is updatable. HSQLDB
+      supports core SQL updatability features, plus some enhancements from the
+      SQL optional features.</para>
+
+      <para>A query expression is updatable if it is a SELECT from a single
+      underlying base table (or updatable view) either directly or indirectly.
+      A SELECT statement featuring DISTINCT or GROUP BY or FETCH, LIMIT,
+      OFFSET is not updatable. In an updatable query expression, one or more
+      columns are updatable. An updatable column is a column that can be
+      traced directly to the underlying table. Therefore, columns that contain
+      expressions are not updatable. Examples of updatable query expressions
+      are given below. The view V is updatable when its query expression is
+      updatable. The SELECT statement from this view is also updatable:</para>
+
+      <programlisting>SELECT A, B FROM T WHERE C &gt; 5
+SELECT A, B FROM (SELECT * FROM T WHERE C &gt; 10) AS TT WHERE TT.B &lt;10
+CREATE VIEW V(X,Y) AS SELECT A, B FROM T WHERE C &gt; 0 AND B &lt; 10
+SELECT X FROM V WHERE Y = 5
+</programlisting>
+
+      <para>If a cursor is declared with the SQL qualifier, <literal>FOR
+      UPDATE OF &lt;column name list&gt;</literal>, then only the stated
+      columns in the result set become updatable. If any of the stated columns
+      is not actually updatable, then the cursor declaration will not
+      succeed.</para>
+
+      <para>If the SQL qualifier, FOR UPDATE is used, then all the updatable
+      columns of the result set become updatable.</para>
+
+      <para>If a cursor is declared with FOR READ ONLY, then it is not
+      updatable.</para>
+
+      <para>In HSQLDB, if FOR READ ONLY or FOR UPDATE is not used then all the
+      updatable columns of the result set become updatable. This relaxes the
+      SQL standard rule that in this case limits updatability to only simply
+      updatable SELECT statements (where all columns are updatable).</para>
+
+      <para>In JDBC, CONCUR_READ_ONLY or CONCUR_UPDATABLE can be specified for
+      the <classname>Statement</classname> parameter. CONCUR_UPDATABLE is
+      required if the returning ResultSet is to be updatable. If
+      CONCUR_READ_ONLY, which is the default, is used, then even an updatable
+      ResultSet becomes read-only.</para>
+
+      <para>When a <classname>ResultSet</classname> is updatable, various
+      setter methods can be used to modify the column values. The names of the
+      setter methods begin with "update". After all the updates on a row are
+      done, the <methodname>updateRow()</methodname> method must be called to
+      finalise the row update.</para>
+
+      <para>An updatable <classname>ResultSet</classname> may or may not be
+      insertable-into. In an insertable <classname>ResultSet</classname>, all
+      columns of the result are updatable and any column of the base table
+      that is not in the result must be a generated column or have a default
+      value.</para>
+
+      <para>In the <classname>ResultSet</classname> object, a special
+      pseudo-row, called the insert row, is used to populate values for
+      insertion into the <classname>ResultSet</classname> (and consequently,
+      into the base table). The setter methods must be used on all the
+      columns, followed by a call to
+      <methodname>insertRow()</methodname>.</para>
+
+      <para>Individual rows from all updatable result sets can be deleted one
+      at a time. The <methodname>deleteRow()</methodname> is called when the
+      <classname>ResultSet</classname> is positioned on a row.</para>
+
+      <para>While using an updatable ResultSet to modify data, it is
+      recommended not to change the same data using another ResultSet and not
+      to execute SQL data change statements that modify the same data.</para>
+    </section>
+
+    <section>
+      <title>Sensitivity</title>
+
+      <para>The sensitivity of the cursor relates to visibility of changes
+      made to the data by the same transaction but without using the given
+      cursor. While the result set is open, the same transaction may use
+      statements such as INSERT or UPDATE, and change the data of the tables
+      from which the result set data is derived. A cursor is SENSITIVE if it
+      reflects those changes. It is INSENSITIVE if it ignores such changes. It
+      is ASENSITIVE if behaviour is implementation dependent.</para>
+
+      <para>The SQL default is ASENSITIVE, i.e., implantation
+      dependent.</para>
+
+      <para>In HSQLDB all cursors are INSENSITIVE. They do not reflect changes
+      to the data made by other statements.</para>
+    </section>
+
+    <section>
+      <title>Holdability</title>
+
+      <para>A cursor is holdable if the result set is not automatically closed
+      when the current transaction is committed. Holdability can be specified
+      in the cursor declaration using the SQL qualifiers WITH HOLD or WITHOUT
+      HOLD.</para>
+
+      <para>In JDBC, hodability is specified using either of the following
+      values for the Statement parameter: HOLD_CURSORS_OVER_COMMIT, or
+      CLOSE_CURSORS_AT_COMMIT.</para>
+
+      <para>The SQL default is WITHOUT HOLD.</para>
+
+      <para>The JDBC default for HSQLDB result sets is WITH HOLD for read-only
+      result sets and WITHOUT HOLD for updatable result sets.</para>
+
+      <para>If the holdability of a <classname>ResultSet</classname> is
+      specified in a conflicting manner in the SQL statement and the JDBC
+      <classname>Statement</classname> object, the JDBC setting takes
+      precedence.</para>
+    </section>
+
+    <section>
+      <title>Autocommit</title>
+
+      <para>The autocommit property of a connection is a feature of JDBC and
+      ODBC and is not part of the SQL Standard. In autocommit mode, all
+      transactional statements are followed by an implicit commit. In
+      autocommit mode, all <classname>ResultSet</classname> objects are
+      read-only and holdable.</para>
+    </section>
+
+    <section>
+      <title>JDBC Overview</title>
+
+      <para>The JDBC settings, ResultSet.CONCUR_READONLY and
+      ResultSet.CONCUR_UPDATABLE are the alternatives for read-only or
+      updatability. The default is ResultSet.CONCUR_READONLY.</para>
+
+      <para>The JDBC settings, ResultSet.TYPE_FORWARD_ONLY,
+      ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE are
+      the alternatives for both scrollability (navigation) and sensitivity.
+      HyperSQL does not support ResultSet.TYPE_SCROLL_SENSITIVE. The two other
+      alternatives can be used for both updatable and read-only result
+      sets.</para>
+
+      <para>The JDBC settings ResultSet.CLOSE_CURSORS_AT_COMMIT and
+      ResultSet.HOLD_CURSORS_OVER_COMMIT are the alternatives for the lifetime
+      of the result set. The default is ResultSet.CLOSE_CURSORS_AT_COMMIT. The
+      other setting can only be used for read-only result sets.</para>
+
+      <para>Examples of creating statements for updatable result sets are
+      given below:</para>
+
+      <programlisting>Connection c = newConnection();
+Statement st;
+c.setAutoCommit(false);
+st = c.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
+st = c.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);</programlisting>
+    </section>
+
+    <section>
+      <title>JDBC Parameters</title>
+
+      <para>When a JDBC PreparedStatement or CallableStatement is used with an
+      SQL statement that contains dynamic parameters, the data types of the
+      parameters are resolved and determined by the engine when the statement
+      is prepared. The SQL Standard has detailed rules to determine the data
+      types and imposes limits on the maximum length or precision of the
+      parameter. HyperSQL applies the standard rules with two exceptions for
+      parameters with String and BigDecimal Java types. HyperSQL ignores the
+      limits when the parameter value is set, and only enforces the necessary
+      limits when the PreparedStatement is executed. In all other cases,
+      parameter type limits are checked and enforce when the parameter is
+      set.</para>
+
+      <para>In the example below the setString() calls do not raise an
+      exception, but one of the execute() statements does.</para>
+
+      <programlisting>// table definition: CREATE TABLE T (NAME VARCHAR(12), ...)
+Connection c = newConnection();
+PreparedStatement st = c.prepareStatement("SELECT * FROM T WHERE NAME = ?");
+// type of the parameter is VARCHAR(12), which limits length to 12 characters
+st.setString(1, "Eyjafjallajokull"); // string is longer than type, but no exception is raised here
+set.execute(); // executes with no exception and does not find any rows
+// but if an UPDATE is attempted, an exception is raised
+st = c.prepareStatement("UPDATE T SET NAME = ? WHERE ID = 10");
+st.setString(1, "Eyjafjallajokull"); // string is longer than type, but no exception is raised here
+st.execute(); // exception is thrown when HyperSQL checks the value for update
+
+</programlisting>
+
+      <para>All of the above also applies to setting the values in new and
+      updated rows in updatable ResultSet objects.</para>
+
+      <para>JDBC parameters can be set with any compatible type, as supported
+      by the JDBC specification. For CLOB and BLOB types, you can use streams,
+      or create instances of BLOB or CLOB before assigning them to the
+      parameters. You can even use CLOB or BLOB objects returned from
+      connections to other RDBMS servers. The Connection.createBlob() and
+      createClob() methods can be used to create the new LOBs. For very large
+      LOB's the stream methods are preferable as they use less memory.</para>
+
+      <para>For array parameters, you must use a java.sql.Array object that
+      contains the array elements before assigning to JDBC parameters. The
+      Connection.createArrayOf(...) method can be used to create a new object,
+      or you can use an Array returned from connections to other RDBMS
+      servers.</para>
+    </section>
+
+    <section>
+      <title>JDBC Returned Values</title>
+
+      <para>The methods of the JDBC ResultSet interface can be used to return
+      values and to convert value to different types as supported by the JDBC
+      specification.</para>
+
+      <para>When a CLOB and BLOB object is returned from a ResultSet, no data
+      is transferred until the data is read by various methods of
+      java.sql.CLOB and java.sql.BLOB. Data is streamed in large blocks to
+      avoid excessive memory use.</para>
+
+      <para>Array objects are returned as instances of java.sql.Array.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Syntax Elements</title>
+
+    <para>The syntax elements that can be used in data access and data change
+    statements are described in this section. The SQL Standard has a very
+    extensive set of definitions for these elements. The BNF definitions given
+    here are sometimes simplified.</para>
+
+    <section>
+      <title>Literals</title>
+
+      <para>Literals are used to express constant values. The general type of
+      a literal is known by its format. The specific type is based on
+      conventions.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>unicode escape elements</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">unicode escape
+      elements</emphasis></simpara>
+
+      <simpara><emphasis>unicode escape elements</emphasis></simpara>
+
+      <simpara><literal>&lt;Unicode escape specifier&gt; ::= [ UESCAPE
+      &lt;quote&gt;&lt;Unicode escape character&gt;&lt;quote&gt; ]
+      </literal></simpara>
+
+      <simpara><literal>&lt;Unicode escape value&gt; ::= &lt;Unicode 4 digit
+      escape value&gt; | &lt;Unicode 6 digit escape value&gt; | &lt;Unicode
+      character escape value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;Unicode 4 digit escape value&gt; ::= &lt;Unicode
+      escape
+      character&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;</literal></simpara>
+
+      <simpara><literal>&lt;Unicode 6 digit escape value&gt; ::= &lt;Unicode
+      escape character&gt;&lt;plus sign&gt;
+      &lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;</literal></simpara>
+
+      <simpara><literal>&lt;Unicode character escape value&gt; ::= &lt;Unicode
+      escape character&gt;&lt;Unicode escape character&gt;</literal></simpara>
+
+      <simpara><literal>&lt;Unicode escape character&gt; ::= a single
+      character than a &lt;hexit&gt; (a-f, A-F, 0-9), &lt;plus sign&gt;,
+      &lt;quote&gt;, &lt;double quote&gt;, or &lt;white
+      space&gt;</literal></simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>character literal</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">character literal</emphasis></simpara>
+
+      <simpara><emphasis>character literal</emphasis></simpara>
+
+      <simpara><literal>&lt;character string literal&gt; ::= [
+      &lt;introducer&gt;&lt;character set specification&gt; ] &lt;quote&gt; [
+      &lt;character representation&gt;... ] &lt;quote&gt; [ {
+      &lt;separator&gt; &lt;quote&gt; [ &lt;character representation&gt;... ]
+      &lt;quote&gt; }... ]</literal></simpara>
+
+      <simpara><literal>&lt;introducer&gt; ::=
+      &lt;underscore&gt;</literal></simpara>
+
+      <simpara><literal>&lt;character representation&gt; ::= &lt;nonquote
+      character&gt; | &lt;quote symbol&gt;</literal></simpara>
+
+      <simpara><literal>&lt;nonquote character&gt; ::= any character apart
+      from the quote symbol.</literal></simpara>
+
+      <simpara><literal>&lt;quote symbol&gt; ::=
+      &lt;quote&gt;&lt;quote&gt;</literal></simpara>
+
+      <simpara><literal>&lt;national character string literal&gt; ::= N
+      &lt;quote&gt; [ &lt;character representation&gt;... ] &lt;quote&gt; [ {
+      &lt;separator&gt; &lt;quote&gt; [ &lt;character representation&gt;... ]
+      &lt;quote&gt; }... ]</literal></simpara>
+
+      <simpara><literal>&lt;Unicode character string literal&gt; ::= [
+      &lt;introducer&gt;&lt;character set specification&gt; ]
+      U&lt;ampersand&gt;&lt;quote&gt; [ &lt;Unicode representation&gt;... ]
+      &lt;quote&gt; [ { &lt;separator&gt; &lt;quote&gt; [ &lt;Unicode
+      representation&gt;... ] &lt;quote&gt; }... ] &lt;Unicode escape
+      specifier&gt;</literal></simpara>
+
+      <simpara><literal>&lt;Unicode representation&gt; ::= &lt;character
+      representation&gt; | &lt;Unicode escape value&gt;</literal></simpara>
+
+      <simpara>The type of a character literal is CHARACTER. The length of the
+      string literal is the character length of the type. If the quote
+      character is used in a string, it is represented with two quote
+      characters. Long literals can be divided into multiple quoted strings,
+      separated with a space or end-of-line character.</simpara>
+
+      <simpara>Unicode literals start with U&amp; and can contain ordinary
+      characters and unicode escapes. A unicode escape begins with the
+      backslash ( \ ) character and is followed by four hexadecimal characters
+      which specify the character code.</simpara>
+
+      <simpara>Example of character literals are given below:</simpara>
+
+      <programlisting>'a literal'  ' string seperated'  ' into parts'
+'a string''s literal form with quote character'
+U&amp;'Unicode string with Greek delta \0394 and phi \03a6 letters'
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>binary literal</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">binary literal</emphasis></simpara>
+
+      <simpara><emphasis>binary literal</emphasis></simpara>
+
+      <simpara><literal>&lt;binary string literal&gt; ::= X &lt;quote&gt; [
+      &lt;space&gt;... ] [ { &lt;hexit&gt; [ &lt;space&gt;... ] &lt;hexit&gt;
+      [ &lt;space&gt;... ] }... ] &lt;quote&gt; [ { &lt;separator&gt;
+      &lt;quote&gt; [ &lt;space&gt;... ] [ { &lt;hexit&gt; [ &lt;space&gt;...
+      ] &lt;hexit&gt; [ &lt;space&gt;... ] }... ] &lt;quote&gt; }...
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;hexit&gt; ::= &lt;digit&gt; | A | B | C | D | E |
+      F | a | b | c | d | e | f</literal></simpara>
+
+      <simpara>The type of a binary literal is BINARY. The octect length of
+      the binary literal is the length of the type. Case-insensitive
+      hexadecimal characters are used in the binary string. Each pair of
+      characters in the literal represents a byte in the binary string. Long
+      literals can be divided into multiple quoted strings, separated with a
+      space or end-of-line character.</simpara>
+
+      <programlisting>X'1abACD34' 'Af'</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>bit literal</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">bit literal</emphasis></simpara>
+
+      <simpara><emphasis>bit literal</emphasis></simpara>
+
+      <simpara><literal>&lt;bit string literal&gt; ::= B &lt;quote&gt; [
+      &lt;bit&gt; ... ] &lt;quote&gt; [ { &lt;separator&gt; &lt;quote&gt; [
+      &lt;bit&gt;... ] &lt;quote&gt; }... ]</literal></simpara>
+
+      <simpara><literal>&lt;bit&gt; ::= 0 | 1</literal></simpara>
+
+      <simpara>The type of a binary literal is BIT. The bit length of the bit
+      literal is the length of the type. Digits 0 and 1 are used to represent
+      the bits. Long literals can be divided into multiple quoted strings,
+      separated with a space or end-of-line character.</simpara>
+
+      <programlisting>B'10001001' '00010'</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>numeric literal</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">numeric literal</emphasis></simpara>
+
+      <simpara><emphasis>numeric literal</emphasis></simpara>
+
+      <simpara><literal>&lt;signed numeric literal&gt; ::= [ &lt;sign&gt; ]
+      &lt;unsigned numeric literal&gt;</literal></simpara>
+
+      <simpara><literal>&lt;unsigned numeric literal&gt; ::= &lt;exact numeric
+      literal&gt; | &lt;approximate numeric literal&gt;</literal></simpara>
+
+      <simpara><literal>&lt;exact numeric literal&gt; ::= &lt;unsigned
+      integer&gt; [ &lt;period&gt; [ &lt;unsigned integer&gt; ] ] |
+      &lt;period&gt; &lt;unsigned integer&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sign&gt; ::= &lt;plus sign&gt; | &lt;minus
+      sign&gt;</literal></simpara>
+
+      <simpara><literal>&lt;approximate numeric literal&gt; ::=
+      &lt;mantissa&gt; E &lt;exponent&gt;</literal></simpara>
+
+      <simpara><literal>&lt;mantissa&gt; ::= &lt;exact numeric
+      literal&gt;</literal></simpara>
+
+      <simpara><literal>&lt;exponent&gt; ::= &lt;signed
+      integer&gt;</literal></simpara>
+
+      <simpara><literal>&lt;signed integer&gt; ::= [ &lt;sign&gt; ]
+      &lt;unsigned integer&gt;</literal></simpara>
+
+      <simpara><literal>&lt;unsigned integer&gt; ::=
+      &lt;digit&gt;...</literal></simpara>
+
+      <simpara>The type of an exact numeric literal without a decimal point is
+      INTEGER, BIGINT, or DECIMAL, depending on the value of the literal (the
+      smallest type that can represent the value is the type).</simpara>
+
+      <simpara>The type of an exact numeric literal with a decimal point is
+      DECIMAL. The precision of a decimal literal is the total number of
+      digits of the literal. The scale of the literal is the total number of
+      digits to the right of the decimal point.</simpara>
+
+      <simpara>The type of an approximate numeric literal is DOUBLE. An
+      approximate numeric literal always includes the mantissa and exponent,
+      separated by E.</simpara>
+
+      <programlisting>12
+34.35
++12E-2
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>boolean literal</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">boolean literal</emphasis></simpara>
+
+      <simpara><emphasis>boolean literal</emphasis></simpara>
+
+      <simpara><literal>&lt;boolean literal&gt; ::= TRUE | FALSE |
+      UNKNOWN</literal></simpara>
+
+      <simpara>The boolean literal is one of the specified keywords.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>datetime and interval literal</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">datetime and interval
+      literal</emphasis></simpara>
+
+      <simpara><emphasis>datetime and interval literal</emphasis></simpara>
+
+      <simpara><literal>&lt;datetime literal&gt; ::= &lt;date literal&gt; |
+      &lt;time literal&gt; | &lt;timestamp literal&gt;</literal></simpara>
+
+      <simpara><literal>&lt;date literal&gt; ::= DATE &lt;date
+      string&gt;</literal></simpara>
+
+      <simpara><literal>&lt;time literal&gt; ::= TIME &lt;time
+      string&gt;</literal></simpara>
+
+      <simpara><literal>&lt;timestamp literal&gt; ::= TIMESTAMP &lt;timestamp
+      string&gt;</literal></simpara>
+
+      <simpara><literal>&lt;date string&gt; ::= &lt;quote&gt; &lt;unquoted
+      date string&gt; &lt;quote&gt;</literal></simpara>
+
+      <simpara><literal>&lt;time string&gt; ::= &lt;quote&gt; &lt;unquoted
+      time string&gt; &lt;quote&gt;</literal></simpara>
+
+      <simpara><literal>&lt;timestamp string&gt; ::= &lt;quote&gt;
+      &lt;unquoted timestamp string&gt; &lt;quote&gt;</literal></simpara>
+
+      <simpara><literal>&lt;time zone interval&gt; ::= &lt;sign&gt; &lt;hours
+      value&gt; &lt;colon&gt; &lt;minutes value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;date value&gt; ::= &lt;years value&gt; &lt;minus
+      sign&gt; &lt;months value&gt; &lt;minus sign&gt; &lt;days
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;time value&gt; ::= &lt;hours value&gt;
+      &lt;colon&gt; &lt;minutes value&gt; &lt;colon&gt; &lt;seconds
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval literal&gt; ::= INTERVAL [ &lt;sign&gt; ]
+      &lt;interval string&gt; &lt;interval qualifier&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval string&gt; ::= &lt;quote&gt; &lt;unquoted
+      interval string&gt; &lt;quote&gt;</literal></simpara>
+
+      <simpara><literal>&lt;unquoted date string&gt; ::= &lt;date
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;unquoted time string&gt; ::= &lt;time value&gt; [
+      &lt;time zone interval&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;unquoted timestamp string&gt; ::= &lt;unquoted
+      date string&gt; &lt;space&gt; &lt;unquoted time
+      string&gt;</literal></simpara>
+
+      <simpara><literal>&lt;unquoted interval string&gt; ::= [ &lt;sign&gt; ]
+      { &lt;year-month literal&gt; | &lt;day-time literal&gt;
+      }</literal></simpara>
+
+      <simpara><literal>&lt;year-month literal&gt; ::= &lt;years value&gt; [
+      &lt;minus sign&gt; &lt;months value&gt; ] | &lt;months
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;day-time literal&gt; ::= &lt;day-time interval&gt;
+      | &lt;time interval&gt;</literal></simpara>
+
+      <simpara><literal>&lt;day-time interval&gt; ::= &lt;days value&gt; [
+      &lt;space&gt; &lt;hours value&gt; [ &lt;colon&gt; &lt;minutes value&gt;
+      [ &lt;colon&gt; &lt;seconds value&gt; ] ] ]</literal></simpara>
+
+      <simpara><literal>&lt;time interval&gt; ::= &lt;hours value&gt; [
+      &lt;colon&gt; &lt;minutes value&gt; [ &lt;colon&gt; &lt;seconds
+      value&gt; ] ] | &lt;minutes value&gt; [ &lt;colon&gt; &lt;seconds
+      value&gt; ] | &lt;seconds value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;years value&gt; ::= &lt;datetime
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;months value&gt; ::= &lt;datetime
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;days value&gt; ::= &lt;datetime
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;hours value&gt; ::= &lt;datetime
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;minutes value&gt; ::= &lt;datetime
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;seconds value&gt; ::= &lt;seconds integer
+      value&gt; [ &lt;period&gt; [ &lt;seconds fraction&gt; ]
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;seconds integer value&gt; ::= &lt;unsigned
+      integer&gt;</literal></simpara>
+
+      <simpara><literal>&lt;seconds fraction&gt; ::= &lt;unsigned
+      integer&gt;</literal></simpara>
+
+      <simpara><literal>&lt;datetime value&gt; ::= &lt;unsigned
+      integer&gt;</literal></simpara>
+
+      <simpara>The type of a datetime or interval type is specified in the
+      literal. The fractional second precision is the number of digits in the
+      fractional part of the literal. Details are described in the <link
+      endterm="sqlgeneral-title" xlink:href="#sqlgeneral-chapt"></link>
+      chapter</simpara>
+
+      <programlisting>DATE '2008-08-08'
+TIME '20:08:08'
+TIMESTAMP '2008-08-08 20:08:08.235'
+
+INTERVAL '10' DAY
+INTERVAL -'08:08' MINUTE TO SECOND
+</programlisting>
+    </section>
+
+    <section>
+      <title>References, etc.</title>
+
+      <para>References are identifier chains, which can be a single
+      identifiers or identifiers chains composed of single identifiers chained
+      together with the period symbol.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>identifier chain</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">identifier chain</emphasis></simpara>
+
+      <simpara><emphasis>identifier chain</emphasis></simpara>
+
+      <simpara><literal>&lt;identifier chain&gt; ::= &lt;identifier&gt; [ {
+      &lt;period&gt; &lt;identifier&gt; }... ]</literal></simpara>
+
+      <simpara><literal>&lt;basic identifier chain&gt; ::= &lt;identifier
+      chain&gt;</literal></simpara>
+
+      <simpara>A period-separated chain of identifiers. The identifiers in an
+      identifier chain can refer to database objects in a hierarchy. The
+      possible hierarchies are as follows. In each hierarchy, elements from
+      the start or the end can be missing, but the order of elements cannot be
+      changed.</simpara>
+
+      <simpara>catalog, schema, database object</simpara>
+
+      <simpara>catalog, schema, table, column</simpara>
+
+      <simpara>correlation name, column</simpara>
+
+      <simpara>Examples of identifier chain are given below:</simpara>
+
+      <programlisting>SELECT MYCAT.MYSCHEMA.MYTABLE.MYCOL FROM MYCAT.MYSCHEMA.MYTABLE
+DROP TABLE MYCAT.MYSCHEMA.MYTABLE CASCADE
+ALTER SEQUENCE MYCAT.MYSCHEMA.MYSEQUENCE RESTART WITH 100
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>column reference</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">column reference</emphasis></simpara>
+
+      <simpara><emphasis>column reference</emphasis></simpara>
+
+      <simpara><literal>&lt;column reference&gt; ::= &lt;basic identifier
+      chain&gt; | MODULE &lt;period&gt; &lt;qualified identifier&gt;
+      &lt;period&gt; &lt;column name&gt;</literal></simpara>
+
+      <simpara>Reference a column or a routine variable.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SQL parameter reference</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SQL parameter
+      reference</emphasis></simpara>
+
+      <simpara><emphasis>SQL parameter reference</emphasis></simpara>
+
+      <simpara><literal>&lt;SQL parameter reference&gt; ::= &lt;basic
+      identifier chain&gt;</literal></simpara>
+
+      <simpara>Reference an SQL routine parameter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>contextually typed value specification</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">contextually typed value
+      specification</emphasis></simpara>
+
+      <simpara><emphasis>contextually typed value
+      specification</emphasis></simpara>
+
+      <simpara><literal>&lt;contextually typed value specification&gt; ::=
+      &lt;null specification&gt; | &lt;default
+      specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;null specification&gt; ::=
+      NULL</literal></simpara>
+
+      <simpara><literal>&lt;default specification&gt; ::=
+      DEFAULT</literal></simpara>
+
+      <simpara>Specify a value whose data type or value is inferred from its
+      context. DEFAULT is used for assignments to table columns that have a
+      default value, or to table columns that are generated either as an
+      IDENTITY value or as an expression. NULL can be used only in a context
+      where the type of the value is known. For example, a NULL can be
+      assigned to a column of the table in an INSERT or UPDATE statement,
+      because the type of the column is known. But if NULL is used in a SELECT
+      list, it must be used in a CAST statement.</simpara>
+    </section>
+
+    <section>
+      <title>Value Expression</title>
+
+      <para>Value expression is a general name for all expressions that return
+      a value. Different types of expressions are allowed in different
+      contexts.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>value expression primary</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">value expression
+      primary</emphasis></simpara>
+
+      <simpara><emphasis>value expression primary</emphasis></simpara>
+
+      <simpara><literal>&lt;value expression primary&gt; ::= &lt;parenthesized
+      value expression&gt; | &lt;nonparenthesized value expression
+      primary&gt;</literal></simpara>
+
+      <simpara><literal>&lt;parenthesized value expression&gt; ::= &lt;left
+      paren&gt; &lt;value expression&gt; &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;nonparenthesized value expression primary&gt; ::=
+      &lt;unsigned value specification&gt; | &lt;column reference&gt; |
+      &lt;set function specification&gt; | &lt;scalar subquery&gt; | &lt;case
+      expression&gt; | &lt;cast specification&gt; | &lt;next value
+      expression&gt; | &lt;routine invocation&gt;</literal></simpara>
+
+      <simpara>Specify a value that is syntactically self-delimited.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>value specification</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">value specification</emphasis></simpara>
+
+      <simpara><emphasis>value specification</emphasis></simpara>
+
+      <simpara><literal>&lt;value specification&gt; ::= &lt;literal&gt; |
+      &lt;general value specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;unsigned value specification&gt; ::= &lt;unsigned
+      literal&gt; | &lt;general value specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;target specification&gt; ::= &lt;host parameter
+      specification&gt; | &lt;SQL parameter reference&gt; | &lt;column
+      reference&gt; | &lt;dynamic parameter
+      specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;simple target specification&gt; ::= &lt;host
+      parameter specification&gt; | &lt;SQL parameter reference&gt; |
+      &lt;column reference&gt; | &lt;embedded variable
+      name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;host parameter specification&gt; ::= &lt;host
+      parameter name&gt; [ &lt;indicator parameter&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;dynamic parameter specification&gt; ::=
+      &lt;question mark&gt;</literal></simpara>
+
+      <simpara>Specify one or more values, host parameters, SQL parameters,
+      dynamic parameters, or host variables.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>row value expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">row value expression</emphasis></simpara>
+
+      <simpara><emphasis>row value expression</emphasis></simpara>
+
+      <simpara><literal>&lt;row value expression&gt; ::= &lt;row value special
+      case&gt; | &lt;explicit row value constructor&gt; </literal></simpara>
+
+      <simpara><literal>&lt;row value predicand&gt; ::= &lt;row value special
+      case&gt; | &lt;row value constructor predicand&gt;</literal></simpara>
+
+      <simpara><literal>&lt;row value special case&gt; ::=
+      &lt;nonparenthesized value expression primary&gt;</literal></simpara>
+
+      <simpara><literal>&lt;explicit row value constructor&gt; ::= &lt;left
+      paren&gt; &lt;row value constructor element&gt; &lt;comma&gt; &lt;row
+      value constructor element list&gt; &lt;right paren&gt;
+      |</literal></simpara>
+
+      <simpara><literal> ROW &lt;left paren&gt; &lt;row value constructor
+      element list&gt; &lt;right paren&gt; | &lt;row
+      subquery&gt;</literal></simpara>
+
+      <simpara>Specify a row consisting of one or more elements. A comma
+      separated list of expressions, enclosed in brackets, with the optional
+      keyword ROW. In SQL, a row containing a single element can often be used
+      where a single value is expected.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>set function specification</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">set function
+      specification</emphasis></simpara>
+
+      <simpara><emphasis>set function specification</emphasis></simpara>
+
+      <simpara><literal>&lt;set function specification&gt; ::= &lt;aggregate
+      function&gt; | &lt;grouping operation&gt;</literal></simpara>
+
+      <simpara><literal>&lt;grouping operation&gt; ::= GROUPING &lt;left
+      paren&gt; &lt;column reference&gt; [ { &lt;comma&gt; &lt;column
+      reference&gt; }... ] &lt;right paren&gt;</literal></simpara>
+
+      <simpara>Specify a value derived by the application of a function to an
+      argument. Early releases of HyperSQL 2.0 do not support
+      <literal>&lt;grouping operation&gt;</literal> .</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>COALESCE expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">COALESCE</emphasis></simpara>
+
+      <simpara><emphasis>coalesce expression</emphasis></simpara>
+
+      <simpara><literal>&lt;coalesce expression&gt; := COALESCE &lt;left
+      paren&gt; &lt;value expression&gt; { &lt;comma&gt; &lt;value
+      expression&gt; }... &lt;right paren&gt;</literal></simpara>
+
+      <simpara>Replace null values with another value. The coalesce expression
+      has two or more instances of &lt;value expression&gt;. If the first
+      &lt;value expression&gt; evaluates to a non-null value, it is returned
+      as the result of the coalesce expression. If it is null, the next
+      <literal>&lt;value expression&gt;</literal> is evaluated and if it
+      evaluates to a non-non value, it is returned, and so on.</simpara>
+
+      <simpara>The type of the return value of a COALESCE expression is the
+      aggregate type of the types of all the <literal>&lt;value
+      expression&gt;</literal> instances. Therefore, any value returned is
+      implicitly cast to this type. HyperSQL also features built-in functions
+      with similar functionality.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>NULLIF expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">NULLIF</emphasis></simpara>
+
+      <simpara><emphasis>nullif expression</emphasis></simpara>
+
+      <simpara><literal>&lt;nullif expression&gt; := NULLIF &lt;left paren&gt;
+      &lt;value expression&gt; &lt;comma&gt; &lt;value expression&gt;
+      &lt;right paren&gt;</literal></simpara>
+
+      <simpara>Return NULL if two values are equal. If the result of the first
+      <literal>&lt;value expression&gt;</literal> is not equal to the result
+      of the second, then it is returned, otherwise NULL is returned. The type
+      of the return value is the type of the first <literal>&lt;value
+      expression&gt;</literal>.</simpara>
+
+      <programlisting>SELECT i, NULLIF(n, 'not defined') FROM t</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>case expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CASE</emphasis></simpara>
+
+      <simpara><emphasis>case specification</emphasis></simpara>
+
+      <simpara><literal>&lt;case specification&gt; ::= &lt;simple case&gt; |
+      &lt;searched case&gt;</literal></simpara>
+
+      <simpara><literal>&lt;simple case&gt; ::= CASE &lt;case operand&gt;
+      &lt;simple when clause&gt;... [ &lt;else clause&gt; ]
+      END</literal></simpara>
+
+      <simpara><literal>&lt;searched case&gt; ::= CASE &lt;searched when
+      clause&gt;... [ &lt;else clause&gt; ] END</literal></simpara>
+
+      <simpara><literal>&lt;simple when clause&gt; ::= WHEN &lt;when operand
+      list&gt; THEN &lt;result&gt;</literal></simpara>
+
+      <simpara><literal>&lt;searched when clause&gt; ::= WHEN &lt;search
+      condition&gt; THEN &lt;result&gt;</literal></simpara>
+
+      <simpara><literal>&lt;else clause&gt; ::= ELSE
+      &lt;result&gt;</literal></simpara>
+
+      <simpara><literal>&lt;case operand&gt; ::= &lt;row value predicand&gt; |
+      &lt;overlaps predicate part 1&gt;</literal></simpara>
+
+      <simpara><literal>&lt;when operand list&gt; ::= &lt;when operand&gt; [ {
+      &lt;comma&gt; &lt;when operand&gt; }... ]</literal></simpara>
+
+      <simpara><literal>&lt;when operand&gt; ::= &lt;row value predicand&gt; |
+      &lt;comparison predicate part 2&gt; | &lt;between predicate part 2&gt; |
+      &lt;in predicate part 2&gt; | &lt;character like predicate part 2&gt; |
+      &lt;octet like predicate part 2&gt; | &lt;similar predicate part 2&gt; |
+      &lt;regex like predicate part 2&gt; | &lt;null predicate part 2&gt; |
+      &lt;quantified comparison predicate part 2&gt; | &lt;match predicate
+      part 2&gt; | &lt;overlaps predicate part 2&gt; | &lt;distinct predicate
+      part 2&gt;</literal></simpara>
+
+      <simpara><literal>&lt;result&gt; ::= &lt;result expression&gt; |
+      NULL</literal></simpara>
+
+      <simpara><literal>&lt;result expression&gt; ::= &lt;value
+      expression&gt;</literal></simpara>
+
+      <simpara>Specify a conditional value. The result of a case expression is
+      always a value. All the values introduced with THEN must be of the same
+      type.</simpara>
+
+      <simpara>An (simple) example of the CASE statement is given below. It
+      returns 'Britain', 'Germany', or 'Other country' depending on the value
+      of dialcode'</simpara>
+
+      <programlisting>CASE dialcode WHEN 44 THEN 'Britain' WHEN 49 THEN 'Germany' ELSE 'Other country' END</programlisting>
+
+      <simpara>The case statement can be far more complex and involve several
+      conditions.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CAST</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CAST</emphasis></simpara>
+
+      <simpara><emphasis>cast specification</emphasis></simpara>
+
+      <simpara><literal>&lt;cast specification&gt; ::= CAST &lt;left paren&gt;
+      &lt;cast operand&gt; AS &lt;cast target&gt; &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;cast operand&gt; ::= &lt;value expression&gt; |
+      &lt;implicitly typed value specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;cast target&gt; ::= &lt;domain name&gt; | &lt;data
+      type&gt;</literal></simpara>
+
+      <simpara>Specify a data conversion. Data conversion takes place
+      automatically among variants of a general type. For example numeric
+      values are freely converted from one type to another in
+      expressions.</simpara>
+
+      <simpara>Explicit type conversion is necessary in two cases. One case is
+      to determine the type of a NULL value. The other case is to force
+      conversion for special purposes. Values of data types can be cast to a
+      character type. The exception is BINARY and OTHER types. The result of
+      the cast is the literal expression of the value. Conversely, a value of
+      a character type can be converted to another type if the character value
+      is a literal representation of the value in the target type. Special
+      conversions are possible between numeric and interval types, which are
+      described in the section covering interval types.</simpara>
+
+      <simpara>The examples below show examples of cast with their
+      result:</simpara>
+
+      <programlisting>CAST (NULL AS TIMESTAMP)
+CAST ('   199  ' AS INTEGER) = 199
+CAST ('tRue ' AS BOOLEAN) = TRUE
+CAST (INTERVAL '2' DAY AS INTEGER) = 2
+CAST ('1992-04-21' AS DATE) = DATE '1992-04-21'
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>NEXT VALUE FOR</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">NEXT VALUE FOR</emphasis></simpara>
+
+      <simpara><emphasis>next value expression</emphasis></simpara>
+
+      <simpara><literal>&lt;next value expression&gt; ::= NEXT VALUE FOR
+      &lt;sequence generator name&gt;</literal></simpara>
+
+      <simpara>Return the next value of a sequence generator. This expression
+      can be used as a select list element in queries, or in assignments to
+      table columns in data change statements. If the expression is used more
+      than once in a single row that is being evaluated, the same value is
+      returned for each invocation. After evaluation of the particular row is
+      complete, the sequence generator will return a different value from the
+      old value. The new value is generated by the sequence generator by
+      adding the increment to the last value it generated. In the example
+      below:</simpara>
+
+      <programlisting>INSERT INTO MYTABLE(COL1, COL2) VALUES 2, NEXT VALUE FOR MYSEQUENCE
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>value expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">value expression</emphasis></simpara>
+
+      <simpara><emphasis>value expression</emphasis></simpara>
+
+      <simpara><literal>&lt;value expression&gt; ::= &lt;numeric value
+      expression&gt; | &lt;string value expression&gt; | &lt;datetime value
+      expression&gt; | &lt;interval value expression&gt; | &lt;boolean value
+      expression&gt; | &lt;row value expression&gt;</literal></simpara>
+
+      <simpara>An expression that returns a value. The value can be a single
+      value, or a row consisting more than one value.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>numeric value expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">numeric value
+      expression</emphasis></simpara>
+
+      <simpara><emphasis>numeric value expression</emphasis></simpara>
+
+      <simpara><literal>&lt;numeric value expression&gt; ::= &lt;term&gt; |
+      &lt;numeric value expression&gt; &lt;plus sign&gt; &lt;term&gt; |
+      &lt;numeric value expression&gt; &lt;minus sign&gt;
+      &lt;term&gt;</literal></simpara>
+
+      <simpara><literal>&lt;term&gt; ::= &lt;factor&gt; | &lt;term&gt;
+      &lt;asterisk&gt; &lt;factor&gt; | &lt;term&gt; &lt;solidus&gt;
+      &lt;factor&gt;</literal></simpara>
+
+      <simpara><literal>&lt;factor&gt; ::= [ &lt;sign&gt; ] &lt;numeric
+      primary&gt;</literal></simpara>
+
+      <simpara><literal>&lt;numeric primary&gt; ::= &lt;value expression
+      primary&gt; | &lt;numeric value function&gt;</literal></simpara>
+
+      <simpara>Specify a numeric value. The BNF indicates that
+      <literal>&lt;asterisk&gt;</literal> and
+      <literal>&lt;solidus&gt;</literal> (the operators for multiplication and
+      division) have precedence over <literal>&lt;minus sign&gt;</literal> and
+      <literal>&lt;plus sign&gt;</literal>.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>numeric value function</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">numeric value
+      function</emphasis></simpara>
+
+      <simpara><emphasis>numeric value function</emphasis></simpara>
+
+      <simpara><literal>&lt;numeric value function&gt; ::= &lt;position
+      expression&gt; | &lt;extract expression&gt; | &lt;length expression&gt;
+      ...</literal></simpara>
+
+      <simpara>Specify a function yielding a value of type numeric. The
+      supported numeric value functions are listed and described in the <link
+      endterm="builtinfunctions-title"
+      xlink:href="#builtinfunctions-chapt"></link> chapter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>string value expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">string value
+      expression</emphasis></simpara>
+
+      <simpara><emphasis>string value expression</emphasis></simpara>
+
+      <simpara><literal>&lt;string value expression&gt; ::= &lt;string
+      concatenation&gt; | &lt;string factor&gt;</literal></simpara>
+
+      <simpara><literal>&lt;string factor&gt; ::= &lt;value expression
+      primary&gt; | &lt;string value function&gt;</literal></simpara>
+
+      <simpara><literal>&lt;string concatenation&gt; ::= &lt;string value
+      expression&gt; &lt;concatenation operator&gt; &lt;string
+      factor&gt;</literal></simpara>
+
+      <simpara><literal>&lt;concatenation operator&gt; ::=
+      ||</literal></simpara>
+
+      <simpara>Specify a character string value, a binary string value, or a
+      bit string value. The BNF indicates that a string value expression can
+      be formed by concatenation of two or more <literal>&lt;value expression
+      primary&gt;</literal>. The types of the <literal>&lt;value expression
+      primary&gt;</literal> elements must be compatible, that is, all must be
+      string, or binary or bit string values.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>character value function</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">character value
+      function</emphasis></simpara>
+
+      <simpara><emphasis>string value function</emphasis></simpara>
+
+      <simpara><literal>&lt;string value function&gt; ::=
+      ...</literal></simpara>
+
+      <simpara>Specify a function that returns a character string or binary
+      string. The supported character value functions are listed and described
+      in the <link endterm="builtinfunctions-title"
+      xlink:href="#builtinfunctions-chapt"></link> chapter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>datetime value expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">datetime value
+      expression</emphasis></simpara>
+
+      <simpara><emphasis>datetime value expression</emphasis></simpara>
+
+      <simpara><literal>&lt;datetime value expression&gt; ::= &lt;datetime
+      term&gt; | &lt;interval value expression&gt; &lt;plus sign&gt;
+      &lt;datetime term&gt; | &lt;datetime value expression&gt; &lt;plus
+      sign&gt; &lt;interval term&gt; | &lt;datetime value expression&gt;
+      &lt;minus sign&gt; &lt;interval term&gt;</literal></simpara>
+
+      <simpara><literal>&lt;datetime term&gt; ::= &lt;datetime
+      factor&gt;</literal></simpara>
+
+      <simpara><literal>&lt;datetime factor&gt; ::= &lt;datetime primary&gt; [
+      &lt;time zone&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;datetime primary&gt; ::= &lt;value expression
+      primary&gt; | &lt;datetime value function&gt;</literal></simpara>
+
+      <simpara><literal>&lt;time zone&gt; ::= AT &lt;time zone
+      specifier&gt;</literal></simpara>
+
+      <simpara><literal>&lt;time zone specifier&gt; ::= LOCAL | TIME ZONE
+      &lt;interval primary&gt;</literal></simpara>
+
+      <simpara>Specify a datetime value. Details are described in the <link
+      endterm="sqlgeneral-title" xlink:href="#sqlgeneral-chapt"></link>
+      chapter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>datetime value function</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">datetime value
+      function</emphasis></simpara>
+
+      <simpara><emphasis>datetime value function</emphasis></simpara>
+
+      <simpara><literal>&lt;datetime value function&gt; ::=
+      ...</literal></simpara>
+
+      <simpara>Specify a function that returns a datetime value. The supported
+      datetime value functions are listed and described in the <link
+      endterm="builtinfunctions-title" xlink:arcrole=""
+      xlink:href="#builtinfunctions-chapt"></link> chapter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>interval term</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">interval term</emphasis></simpara>
+
+      <simpara><emphasis>interval value expression</emphasis></simpara>
+
+      <simpara><literal>&lt;interval value expression&gt; ::= &lt;interval
+      term&gt; | &lt;interval value expression 1&gt; &lt;plus sign&gt;
+      &lt;interval term 1&gt; | &lt;interval value expression 1&gt; &lt;minus
+      sign&gt; &lt;interval term 1&gt; | &lt;left paren&gt; &lt;datetime value
+      expression&gt; &lt;minus sign&gt; &lt;datetime term&gt; &lt;right
+      paren&gt; &lt;interval qualifier&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval term&gt; ::= &lt;interval factor&gt; |
+      &lt;interval term 2&gt; &lt;asterisk&gt; &lt;factor&gt; | &lt;interval
+      term 2&gt; &lt;solidus&gt; &lt;factor&gt; | &lt;term&gt;
+      &lt;asterisk&gt; &lt;interval factor&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval factor&gt; ::= [ &lt;sign&gt; ]
+      &lt;interval primary&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval primary&gt; ::= &lt;value expression
+      primary&gt; [ &lt;interval qualifier&gt; ] | &lt;interval value
+      function&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval value expression 1&gt; ::= &lt;interval
+      value expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval term 1&gt; ::= &lt;interval
+      term&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval term 2&gt; ::= &lt;interval
+      term&gt;</literal></simpara>
+
+      <simpara>Specify an interval value. Details are described in the <link
+      endterm="sqlgeneral-title" xlink:href="#sqlgeneral-chapt"></link>
+      chapter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>interval absolute value function</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">interval absolute value
+      function</emphasis></simpara>
+
+      <simpara><emphasis>interval value function</emphasis></simpara>
+
+      <simpara><literal>&lt;interval value function&gt; ::= &lt;interval
+      absolute value function&gt;</literal></simpara>
+
+      <simpara><literal>&lt;interval absolute value function&gt; ::= ABS
+      &lt;left paren&gt; &lt;interval value expression&gt; &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara>Specify a function that returns the absolute value of an
+      interval. If the interval is negative, it is negated, otherwise the
+      original value is returned.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>boolean value expression</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">boolean value
+      expression</emphasis></simpara>
+
+      <simpara><emphasis>boolean value expression</emphasis></simpara>
+
+      <simpara><literal>&lt;boolean value expression&gt; ::= &lt;boolean
+      term&gt; | &lt;boolean value expression&gt; OR &lt;boolean
+      term&gt;</literal></simpara>
+
+      <simpara><literal>&lt;boolean term&gt; ::= &lt;boolean factor&gt; |
+      &lt;boolean term&gt; AND &lt;boolean factor&gt;</literal></simpara>
+
+      <simpara><literal>&lt;boolean factor&gt; ::= [ NOT ] &lt;boolean
+      test&gt;</literal></simpara>
+
+      <simpara><literal>&lt;boolean test&gt; ::= &lt;boolean primary&gt; [ IS
+      [ NOT ] &lt;truth value&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;truth value&gt; ::= TRUE | FALSE |
+      UNKNOWN</literal></simpara>
+
+      <simpara><literal>&lt;boolean primary&gt; ::= &lt;predicate&gt; |
+      &lt;boolean predicand&gt;</literal></simpara>
+
+      <simpara><literal>&lt;boolean predicand&gt; ::= &lt;parenthesized
+      boolean value expression&gt; | &lt;nonparenthesized value expression
+      primary&gt;</literal></simpara>
+
+      <simpara><literal>&lt;parenthesized boolean value expression&gt; ::=
+      &lt;left paren&gt; &lt;boolean value expression&gt; &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara>Specify a boolean value.</simpara>
+    </section>
+
+    <section>
+      <title>Predicates</title>
+
+      <simpara>Predicates are conditions with two sides and evaluate to a
+      boolean value. The left side of the predicate, the <literal>&lt;row
+      value predicand&gt;</literal>, is the common element of all predicates.
+      This element is a generalisation of both <literal>&lt;value
+      expression&gt;</literal>, which is a scalar, and of
+      <literal>&lt;explicit row value constructor&gt;</literal>, which is a
+      row. The two sides of a predicate can be split in CASE statements where
+      the <literal>&lt;row value predicand&gt;</literal> is part of multiple
+      predicates.</simpara>
+
+      <simpara>The number of fields in all <literal>&lt;row value
+      predicand&gt;</literal> used in predicates must be the same and the
+      types of the fields in the same position must be compatible for
+      comparison. If either of these conditions does not hold, an exception is
+      raised. The number of fields in a row is called the
+      <glossterm>degree</glossterm>.</simpara>
+
+      <simpara>In many types of predicates (but not all of them), if the
+      <literal>&lt;row value predicand&gt;</literal> evaluates to NULL, the
+      result of the predicate is UNKNOWN. If the <literal>&lt;row value
+      predicand&gt;</literal> has more than one element, and one or more of
+      the fields evaluate to NULL, the result depends on the particular
+      predicate.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>comparison predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">comparison predicand</emphasis></simpara>
+
+      <simpara><emphasis>comparison predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;comparison predicate&gt; ::= &lt;row value
+      predicand&gt; &lt;comp op&gt; &lt;row value
+      predicand&gt;</literal></simpara>
+
+      <simpara><literal>&lt;comp op&gt; ::= &lt;equals operator&gt; | &lt;not
+      equals operator&gt; | &lt;less than operator&gt; | &lt;greater than
+      operator&gt; | &lt;less than or equals operator&gt; | &lt;greater than
+      or equals operator&gt;</literal></simpara>
+
+      <simpara>Specify a comparison of two row values. If either
+      <literal>&lt;row value predicand&gt;</literal> evaluates to NULL, the
+      result of <literal>&lt;comparison predicate&gt;</literal> is UNKNOWN.
+      Otherwise, the result is TRUE, FALSE or UNKNOWN.</simpara>
+
+      <simpara>If the <glossterm>degree</glossterm> of <literal>&lt;row value
+      predicand&gt;</literal> is larger than one, comparison is performed
+      between each field and the corresponding field in the other
+      <literal>&lt;row value predicand&gt;</literal> from left to right, one
+      by one.</simpara>
+
+      <simpara>When comparing two elements, if either field is NULL then the
+      result is UNKNOWN.</simpara>
+
+      <simpara>For <literal>&lt;equals operator&gt;</literal>, if the result
+      of comparison is TRUE for all field, the result of the predicate is
+      TRUE. If the result of comparison is FALSE for one field, the result of
+      predicate is FALSE. Otherwise the result is UNKNOWN.</simpara>
+
+      <simpara>The <literal>&lt;not equals operator&gt;</literal> is
+      translated to <literal>NOT (&lt;row value predicand&gt; = &lt;row value
+      predicand&gt;)</literal>.</simpara>
+
+      <simpara>The <literal>&lt;less than or equals operator&gt;</literal> is
+      translated to <literal>(&lt;row value predicand&gt; = &lt;row value
+      predicand&gt;) OR (&lt;row value predicand&gt; &lt; &lt;row value
+      predicand&gt;)</literal>. The <literal>&lt;greater than or equals
+      operator&gt;</literal> is translated similarly.</simpara>
+
+      <simpara>For the <literal>&lt;less than operator&gt;</literal> and
+      <literal>&lt;greater than operator&gt;</literal>, if two fields at a
+      given position are equal, then comparison continues to the next field.
+      Otherwise, the result of the last performed comparison is returned as
+      the result of the predicate. This means that if the first field is NULL,
+      the result is always UNKNOWN.</simpara>
+
+      <simpara>The logic that governs NULL values and UNKNOWN result is as
+      follows: Suppose the NULL values were substituted by arbitrary real
+      values. If substitution cannot change the result of the predicate, then
+      the result is TRUE or FALSE, based on the existing non-NULL values,
+      otherwise the result of the predicate is UNKNOWN.</simpara>
+
+      <simpara>The examples of comparison given below use literals, but the
+      literals actually represent the result of evaluation of some
+      expression.</simpara>
+
+      <programlisting>((1, 2, 3, 4) = (1, 2, 3, 4)) IS TRUE
+((1, 2, 3, 4) = (1, 2, 3, 5)) IS FALSE
+((1, 2, 3, 4) &lt; (1, 2, 3, 4)) IS FALSE
+((1, 2, 3, 4) &lt; (1, 2, 3, 5)) IS TRUE
+((NULL, 1, NULL) = (NULL, 1, NULL)) IS UNKNOWN  
+((NULL, 1, NULL) = (NULL, 2, NULL)) IS FALSE  
+((NULL, 1, NULL) &lt;&gt; (NULL, 2, NULL)) IS TRUE  
+((NULL, 1, 2) &lt;all operators&gt; (NULL, 1, 2)) IS UNKNOWN
+((1, NULL, ...) &lt; (1, 2, ...)) IS UNKNOWN  
+((1, NULL, ...) &lt; (2, NULL, ...)) IS TRUE
+((2, NULL, ...) &lt; (1, NULL, ...)) IS FALSE
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>BETWEEN predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">BETWEEN</emphasis></simpara>
+
+      <simpara><emphasis>between predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;between predicate&gt; ::= &lt;row value
+      predicand&gt; &lt;between predicate part 2&gt;</literal></simpara>
+
+      <simpara><literal>&lt;between predicate part 2&gt; ::= [ NOT ] BETWEEN [
+      ASYMMETRIC | SYMMETRIC ] &lt;row value predicand&gt; AND &lt;row value
+      predicand&gt;</literal></simpara>
+
+      <simpara>Specify a range comparison. The default is ASYMMETRIC. The
+      expression <literal>X BETWEEN Y AND Z</literal> is equivalent to
+      <literal>(X &gt;= Y AND X &lt;= Z)</literal>. Therefore if Y &gt; Z, the
+      BETWEEN expression is never true. The expression <literal>X BETWEEN
+      SYMMETRIC Y AND Z</literal> is equivalent to <literal>(X &gt;= Y AND X
+      &lt;= Z) OR (X &gt;= Z AND X &lt;= Y)</literal>. The expression
+      <literal>Z NOT BETWEEN ...</literal> is equivalent to <literal>NOT (Z
+      BETWEEN ...)</literal>. If any of the three <literal>&lt;row value
+      predicand&gt;</literal> evaluates to NULL, the result is
+      UNKNOWN.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>IN predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">IN</emphasis></simpara>
+
+      <simpara><emphasis>in predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;in predicate&gt; ::= &lt;row value predicand&gt; [
+      NOT ] IN &lt;in predicate value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;in predicate value&gt; ::= &lt;table subquery&gt;
+      | &lt;left paren&gt; &lt;in value list&gt; &lt;right paren&gt;
+      </literal></simpara>
+
+      <simpara><literal>| &lt;left paren&gt; UNNEST &lt;left paren&gt;
+      &lt;array value expression&gt; &lt;right paren&gt; &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;in value list&gt; ::= &lt;row value expression&gt;
+      [ { &lt;comma&gt; &lt;row value expression&gt; }...
+      ]</literal></simpara>
+
+      <simpara>Specify a quantified comparison. The expression <literal>X NOT
+      IN Y is</literal> equivalent to <literal>NOT (X IN Y)</literal>. The
+      <literal>( &lt;in value list&gt; )</literal> is converted into a table
+      with one or more rows. The expression <literal>X IN Y</literal> is
+      equivalent to <literal>X = ANY Y</literal>, which is a
+      <literal>&lt;quantified comparison predicate&gt;</literal>.</simpara>
+
+      <simpara>If the <literal>&lt;table subquery&gt;</literal> returns no
+      rows, the result is FALSE. Otherwise the <literal>&lt;row value
+      predicand&gt;</literal> is compared one by one with each row of the
+      <literal>&lt;table subquery&gt;</literal>.</simpara>
+
+      <simpara>If the comparison is TRUE for at least one row, the result is
+      TRUE. If the comparison is FALSE for all rows, the result is FALSE.
+      Otherwise the result is UNKNOWN.</simpara>
+
+      <simpara>HyperSQL supports an extension to the SQL Standard to allow an
+      array to be used in the &lt;in predicate value&gt;. This is intended to
+      be used with prepared statements where a variable length array of values
+      can be used as the parameter value for each call. The example below
+      shows how this is used.</simpara>
+
+      <programlisting>SELECT * from customer where firstname in ( UNNEST(?) )
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>LIKE predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">LIKE</emphasis></simpara>
+
+      <simpara><emphasis>like predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;like predicate&gt; ::= &lt;character like
+      predicate&gt; | &lt;octet like predicate&gt;</literal></simpara>
+
+      <simpara><literal>&lt;character like predicate&gt; ::= &lt;row value
+      predicand&gt; [ NOT ] LIKE &lt;character pattern&gt; [ ESCAPE &lt;escape
+      character&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;character pattern&gt; ::= &lt;character value
+      expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;escape character&gt; ::= &lt;character value
+      expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;octet like predicate&gt; ::= &lt;row value
+      predicand&gt; [ NOT ] LIKE &lt;octet pattern&gt; [ ESCAPE &lt;escape
+      octet&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;octet pattern&gt; ::= &lt;binary value
+      expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;escape octet&gt; ::= &lt;binary value
+      expression&gt;</literal></simpara>
+
+      <simpara>Specify a pattern-match comparison for character or binary
+      strings. The <literal>&lt;row value predicand&gt;</literal> is always a
+      <literal>&lt;string value expression&gt;</literal> of character or
+      binary type. The <literal>&lt;character pattern&gt;</literal> or
+      <literal>&lt;octet pattern&gt;</literal> is a <literal>&lt;string value
+      expression&gt;</literal> in which the underscore and percent characters
+      have special meanings. The underscore means match any one character,
+      while the percent means match a sequence of zero or more characters. The
+      <literal>&lt;escape character&gt;</literal> or <literal>&lt;escape
+      octet&gt;</literal> is also a <literal>&lt;string value
+      expression&gt;</literal> that evaluates to a string of exactly one
+      character length. If the underscore or the percent is required as normal
+      characters in the pattern, the specified <literal>&lt;escape
+      character&gt;</literal> or <literal>&lt;escape octet&gt;</literal> can
+      be used in the pattern before the underscore or the percent. The
+      <literal>&lt;row value predicand&gt;</literal> is compared with the
+      <literal>&lt;character pattern&gt;</literal> and the result of
+      comparison is returned. If any of the expressions in the predicate
+      evaluates to NULL, the result of the predicate is UNKNOWN. The
+      expression <literal>A NOT LIKE B</literal> is equivalent to <literal>NOT
+      (A LIKE B)</literal>. If the length of the escape is not 1 or it is used
+      in the pattern not immediately before an underscore or a percent
+      character, an exception is raised.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>IS NULL predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">IS NULL</emphasis></simpara>
+
+      <simpara><emphasis>null predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;null predicate&gt; ::= &lt;row value predicand&gt;
+      IS [ NOT ] NULL</literal></simpara>
+
+      <simpara>Specify a test for a null value. The expression <literal>X IS
+      NOT NULL</literal> is NOT equivalent to <literal>NOT (X IS
+      NULL)</literal>if the degree of the <literal>&lt;row value
+      predicand&gt;</literal> is larger than 1. The rules are: If all fields
+      are null, <literal>X IS NULL</literal> is TRUE and <literal>X IS NOT
+      NULL</literal> is FALSE. If only some fields are null, both <literal>X
+      IS NULL</literal> and <literal>X IS NOT NULL</literal> are FALSE. If all
+      fields are not null, <literal>X IS NULL</literal> is FALSE and
+      <literal>X IS NOT NULL</literal> is TRUE.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ALL and ANY predicates</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ALL and ANY</emphasis></simpara>
+
+      <simpara><emphasis>quantified comparison predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;quantified comparison predicate&gt; ::= &lt;row
+      value predicand&gt; &lt;comp op&gt; &lt;quantifier&gt; &lt;table
+      subquery&gt;</literal></simpara>
+
+      <simpara><literal>&lt;quantifier&gt; ::= &lt;all&gt; |
+      &lt;some&gt;</literal></simpara>
+
+      <simpara><literal>&lt;all&gt; ::= ALL</literal></simpara>
+
+      <simpara><literal>&lt;some&gt; ::= SOME | ANY</literal></simpara>
+
+      <simpara>Specify a quantified comparison. For a quantified comparison,
+      the <literal>&lt;row value predicand&gt;</literal> is compared one by
+      one with each row of the <literal>&lt;table sub
+      query&gt;</literal>.</simpara>
+
+      <simpara>If the <literal>&lt;table subquery&gt;</literal> returns no
+      rows, then if <literal>ALL</literal> is specified the result is TRUE,
+      but if <literal>SOME</literal> or <literal>ANY</literal> is specified
+      the result is FALSE.</simpara>
+
+      <simpara>If <literal>ALL</literal> is specified, if the comparison is
+      TRUE for all rows, the result of the predicate is TRUE. If the
+      comparison is FALSE for at least one row, the result is FALSE. Otherwise
+      the result is UNKNOWN.</simpara>
+
+      <simpara>If <literal>SOME</literal> or <literal>ANY</literal> is
+      specified, if the comparison is TRUE for at least one row, the result is
+      TRUE. If the comparison is FALSE for all rows, the result is FALSE.
+      Otherwise the result is UNKNOWN. Note that the IN predicate is
+      equivalent to the SOME or ANY predicate using the <literal>&lt;equals
+      operator&gt;</literal>.</simpara>
+
+      <simpara>In the examples below, the date of an invoice is compared to
+      holidays in a given year. In the first example the invoice date must
+      equal one of the holidays, in the second example it must be later than
+      all holidays (later than the last holiday), in the third example it must
+      be on or after some holiday (on or after the first holiday), and in the
+      fourth example, it must be before all holidays (before the first
+      holiday).</simpara>
+
+      <programlisting>invoice_date = SOME (SELECT holiday_date FROM holidays)
+invoice_date &gt; ALL (SELECT holiday_date FROM holidays)
+invoice_date &gt;= ANY (SELECT holiday_date FROM holidays)
+invoice_date &lt; ALL (SELECT holiday_date FROM holidays)
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>EXISTS predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">EXISTS</emphasis></simpara>
+
+      <simpara><emphasis>exists predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;exists predicate&gt; ::= EXISTS &lt;table
+      subquery&gt;</literal></simpara>
+
+      <simpara>Specify a test for a non-empty set. If the evaluation of
+      <literal>&lt;table subquery&gt;</literal> results in one or more rows,
+      then the expression is TRUE, otherwise FALSE.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>UNIQUE predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">UNIQUE</emphasis></simpara>
+
+      <simpara><emphasis>unique predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;unique predicate&gt; ::= UNIQUE &lt;table
+      subquery&gt;</literal></simpara>
+
+      <simpara>Specify a test for the absence of duplicate rows. The result of
+      the test is either TRUE or FALSE (never UNKNOWN). The rows of the
+      <literal>&lt;table subquery&gt;</literal> that contain one or more NULL
+      values are not considered for this test. If the rest of the rows are
+      distinct from each other, the result of the test is TRUE, otherwise it
+      is FALSE. The distinctness of rows X and Y is tested with the predicate
+      <literal>X IS DISTINCT FROM Y</literal>.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>MATCH predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">MATCH</emphasis></simpara>
+
+      <simpara><emphasis>match predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;match predicate&gt; ::= &lt;row value
+      predicand&gt; MATCH [ UNIQUE ] [ SIMPLE | PARTIAL | FULL ] &lt;table
+      subquery&gt;</literal></simpara>
+
+      <simpara>Specify a test for matching rows. The default is MATCH SIMPLE
+      without UNIQUE. The result of the test is either TRUE or FALSE (never
+      UNKNOWN).</simpara>
+
+      <simpara>The interpretation of NULL values is different from other
+      predicates and quite counter-intuitive. If the <literal>&lt;row value
+      predicand&gt;</literal> is NULL, or all of its fields are NULL, the
+      result is TRUE.</simpara>
+
+      <simpara>Otherwise, the <literal>&lt;row value predicand&gt;</literal>
+      is compared with each row of the <literal>&lt;table
+      subquery&gt;</literal>.</simpara>
+
+      <simpara>If SIMPLE is specified, if some field of <literal>&lt;row value
+      predicate&gt;</literal> is NULL, the result is TRUE. Otherwise if
+      <literal>&lt;row value predicate&gt; </literal>is equal to one or more
+      rows of <literal>&lt;table subquery&gt;</literal> the result is TRUE if
+      UNIQUE is not specified, or if UNIQUE is specified and only one row
+      matches. Otherwise the result is FALSE.</simpara>
+
+      <simpara>If PARTIAL is specified, if the non-null values
+      <literal>&lt;row value predicate&gt; </literal>are equal to those in one
+      or more rows of <literal>&lt;table subquery&gt;</literal> the result is
+      TRUE if UNIQUE is not specified, or if UNIQUE is specified and only one
+      row matches. Otherwise the result is FALSE.</simpara>
+
+      <simpara>If FULL is specified, if some field of <literal>&lt;row value
+      predicate&gt;</literal> is NULL, the result is FALSE. Otherwise if
+      <literal>&lt;row value predicate&gt;</literal> is equal to one or more
+      rows of <literal>&lt;table subquery&gt;</literal> the result is TRUE if
+      UNIQUE is not specified, or if UNIQUE is specified and only one row
+      matches.</simpara>
+
+      <simpara>Note that MATCH can also used be used in FOREIGN KEY constraint
+      definitions. The exact meaning is described in the <link
+      endterm="databaseobjects-title"
+      xlink:href="#databaseobjects-chapt"></link> chapter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>OVERLAPS predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">OVERLAPS</emphasis></simpara>
+
+      <simpara><emphasis>overlaps predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;overlaps predicate&gt; ::= &lt;row value
+      predicand&gt; OVERLAPS &lt;row value predicand&gt;</literal></simpara>
+
+      <simpara>Specify a test for an overlap between two datetime periods.
+      Each <literal>&lt;row value predicand&gt;</literal> must have two fields
+      and the fields together represent a datetime period. So the predicates
+      is always in the form <literal>(X1, X2) OVERLAPS (Y1, Y2)</literal>. The
+      first field is always a datetime value, while the second field is either
+      a datetime value or an interval value.</simpara>
+
+      <simpara>If the second value is an interval value, it is replaced with
+      the sum of the datetime value and itself, for example <literal>(X1, X1 +
+      X2) OVERLAPS (Y1, Y1 + Y 2)</literal>.</simpara>
+
+      <simpara>If any of the values is NULL, the result is UNKNOWN.</simpara>
+
+      <simpara>The expression is true if there is there is any overlap between
+      the two datetime periods. In the example below, the period is compared
+      with a week long period ending yesterday.</simpara>
+
+      <programlisting>(startdate, enddate) OVERLAPS (CURRENT_DATE - 7 DAY, CURRENT_DATE - 1 DAY)</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>IS DISTINCT predicate</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">IS DISTINCT</emphasis></simpara>
+
+      <simpara><emphasis>is distinct predicate</emphasis></simpara>
+
+      <simpara><literal>&lt;distinct predicate&gt; ::= &lt;row value
+      predicand&gt; IS [ NOT ] DISTINCT FROM &lt;row value
+      predicand&gt;</literal></simpara>
+
+      <simpara>Specify a test of whether two row values are distinct. The
+      result of the test is either TRUE or FALSE (never UNKNOWN). The
+      <glossterm>degree</glossterm> the two <literal>&lt;row value
+      predicand&gt;</literal> must be the same. Each field of the first
+      <literal>&lt;row value predicand&gt;</literal> is compared to the field
+      of the second <literal>&lt;row value predicand&gt;</literal> at the same
+      position. If one field is NULL and the other is not NULL, or if the
+      elements are NOT equal, then the result of the expression is TRUE. If no
+      comparison result is TRUE, then the result of the predicate is FALSE.
+      The expression <literal>X IS NOT DISTINCT FROM Y</literal> is equivalent
+      to <literal>NOT (X IS DISTINCT FORM Y)</literal>. The following check
+      returns true if startdate is not equal to enddate. It also returns true
+      if either startdate or enddate is NULL. It returns false in other
+      cases.</simpara>
+
+      <programlisting>startdate IS DISTINCT FROM enddate</programlisting>
+    </section>
+
+    <section>
+      <title>Other Syntax Elements</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>search condition</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">search condition</emphasis></simpara>
+
+      <simpara><emphasis>search condition</emphasis></simpara>
+
+      <simpara><literal>&lt;search condition&gt; ::= &lt;boolean value
+      expression&gt;</literal></simpara>
+
+      <simpara>Specify a condition that is TRUE, FALSE, or UNKNOWN. A search
+      condition is often a predicate.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>PATH</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">PATH</emphasis></simpara>
+
+      <simpara><emphasis>path specification</emphasis></simpara>
+
+      <simpara><literal>&lt;path specification&gt; ::= PATH &lt;schema name
+      list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;schema name list&gt; ::= &lt;schema name&gt; [ {
+      &lt;comma&gt; &lt;schema name&gt; }... ]</literal></simpara>
+
+      <simpara>Specify an order for searching for a user-defined SQL-invoked
+      routine. This is not currently supported by HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>routine invocation</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">routine invocation</emphasis></simpara>
+
+      <simpara><emphasis>routine invocation</emphasis></simpara>
+
+      <simpara><literal>&lt;routine invocation&gt; ::= &lt;routine name&gt;
+      &lt;SQL argument list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;routine name&gt; ::= [ &lt;schema name&gt;
+      &lt;period&gt; ] &lt;qualified identifier&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL argument list&gt; ::= &lt;left paren&gt; [
+      &lt;SQL argument&gt; [ { &lt;comma&gt; &lt;SQL argument&gt; }... ] ]
+      &lt;right paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL argument&gt; ::= &lt;value expression&gt; |
+      &lt;target specification&gt;</literal></simpara>
+
+      <simpara>Invoke an SQL-invoked routine. Examples are given in the <link
+      endterm="sqlroutines-title" xlink:href="#sqlroutines-chapt"></link>
+      chapter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>COLLATE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">COLLATE</emphasis></simpara>
+
+      <simpara><emphasis>collate clause</emphasis></simpara>
+
+      <simpara><literal>&lt;collate clause&gt; ::= COLLATE &lt;collation
+      name&gt;</literal></simpara>
+
+      <simpara>Specify a default collation. This is not currently supported by
+      HyperSQL</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CONSTRAINT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CONSTRAINT</emphasis></simpara>
+
+      <simpara><emphasis>constraint name definition</emphasis></simpara>
+
+      <simpara><literal>&lt;constraint name definition&gt; ::= CONSTRAINT
+      &lt;constraint name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;constraint characteristics&gt; ::= &lt;constraint
+      check time&gt; [ [ NOT ] DEFERRABLE ] | [ NOT ] DEFERRABLE [
+      &lt;constraint check time&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;constraint check time&gt; ::= INITIALLY DEFERRED |
+      INITIALLY IMMEDIATE</literal></simpara>
+
+      <simpara>Specify the name of a constraint and its characteristics. This
+      is an optional element of CONSTRAINT definition, not yet supported by
+      HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>aggregate function</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">aggregate function</emphasis></simpara>
+
+      <simpara><emphasis>aggregate function</emphasis></simpara>
+
+      <simpara><literal>&lt;aggregate function&gt; ::= COUNT &lt;left
+      paren&gt; &lt;asterisk&gt; &lt;right paren&gt; [ &lt;filter clause&gt; ]
+      | &lt;general set function&gt; [ &lt;filter clause&gt; ]
+      </literal></simpara>
+
+      <simpara><literal>&lt;general set function&gt; ::= &lt;set function
+      type&gt; &lt;left paren&gt; [ &lt;set quantifier&gt; ] &lt;value
+      expression&gt; &lt;right paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;set function type&gt; ::= &lt;computational
+      operation&gt;</literal></simpara>
+
+      <simpara><literal>&lt;computational operation&gt; ::= AVG | MAX | MIN |
+      SUM | EVERY | ANY | SOME | COUNT | STDDEV_POP | STDDEV_SAMP | VAR_SAMP |
+      VAR_POP</literal></simpara>
+
+      <simpara><literal>&lt;set quantifier&gt; ::= DISTINCT |
+      ALL</literal></simpara>
+
+      <simpara><literal>&lt;filter clause&gt; ::= FILTER &lt;left paren&gt;
+      WHERE &lt;search condition&gt; &lt;right paren&gt;</literal></simpara>
+
+      <simpara>Specify a value computed from a collection of rows. An
+      aggregate function is used exclusively in a <literal>&lt;query
+      specification&gt;</literal> and its use transforms a normal query into
+      an aggregate query returning a single row instead of the group of
+      multiple rows that the original query returns. For example,
+      <literal>SELECT acolumn &lt;table expression&gt;</literal> is a query
+      that returns the value of acolumn for all the rows the satisfy the given
+      condition. But <literal>SELECT MAX(acolumn) &lt;table
+      expression&gt;</literal> returns only one row, containing the largest
+      value in that column. The query <literal>SELECT COUNT(*) &lt;table
+      expression&gt;</literal> returns the count of rows, while
+      <literal>SELECT COUNT(acolumn) &lt;table expression&gt;</literal>
+      returns the count of rows where <literal>acolumn IS NOT
+      NULL</literal>.</simpara>
+
+      <simpara>If the <literal>&lt;table expression&gt;</literal> is a grouped
+      table, the aggregate function returns the result of the
+      <literal>COUNT</literal> or <literal>&lt;computational
+      operation&gt;</literal> for each group. In this case the result has the
+      same number of rows as the original query. For example <literal>SELECT
+      SUM(acolumn) &lt;table expression&gt;</literal> when <literal>&lt;table
+      expression&gt;</literal> has a <literal>GROUP BY</literal> clause,
+      returns the sum of values for <literal>acolumn</literal> in each
+      group.</simpara>
+
+      <simpara>The AVG and SUM operations can be performed on numeric
+      expressions only. AVG returns the average value, while SUM returns the
+      sum of all non-null values. MAX and MIN return the minimum or the
+      maximum value. If all values are NULL, the operations return NULL. The
+      <literal>COUNT(*)</literal> operation returns the count of all values,
+      while <literal>COUNT(&lt;value expression&gt;)</literal> returns the
+      count of non-NULL values.</simpara>
+
+      <simpara>The EVERY, ANY and SOME operations can be performed on boolean
+      expressions only. EVERY returns TRUE if all the values are TRUE,
+      otherwise FALSE. ANY and SOME are the same operation and return TRUE if
+      one of the values is TRUE, otherwise it returns FALSE.</simpara>
+
+      <simpara>The other operations perform the statistical functions
+      STDDEV_POP, STDDEV_SAMP, VAR_SAMP, VAR_POP on numeric values. NULL
+      values are ignored in calculations.</simpara>
+
+      <simpara>User defined aggregate functions can be defined and used
+      instead of the built-in aggregate functions. Syntax and examples are
+      given in the <link endterm="sqlroutines-title"
+      xlink:href="#sqlroutines-chapt"></link> chapter.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>sort specification list</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">sort specification
+      list</emphasis></simpara>
+
+      <simpara><emphasis>sort specification list</emphasis></simpara>
+
+      <simpara><literal>&lt;sort specification list&gt; ::= &lt;value
+      expression&gt; [ASC | DESC] [NULLS FIRST | NULLS
+      LAST]</literal></simpara>
+
+      <simpara>Specify a sort order. A sort operation is performed on the
+      result of a <literal>&lt;query expression&gt;</literal> or
+      <literal>&lt;query specification&gt;</literal> and sorts the result
+      according to one or more <literal>&lt;value expression&gt;</literal>.
+      The <literal>&lt;value expression&gt;</literal> is usually a single
+      column of the result, but in some cases it can be a column of the
+      <literal>&lt;table expression&gt;</literal> that is not used in the
+      select list.</simpara>
+    </section>
+  </section>
+
+  <section>
+    <title>Data Access Statements</title>
+
+    <para>HyperSQL fully supports all of SQL-92 data access statements, plus
+    some additions from SQL:2008. Due to time constraints, the current version
+    of this Guide does not cover the subject fully. You are advised to consult
+    an SQL book such as the recent O'Reilly title "SQL and Relational Theory"
+    by C. J. Date.</para>
+
+    <para>Database queries are data access statements. The most commonly used
+    data access statement is the SELECT statement, but there are other
+    statements that perform a similar role. Data access statements access
+    tables and return result tables. The returned result tables are falsely
+    called result sets, as they are not necessarily sets of rows, but
+    multisets of rows.</para>
+
+    <para>Result tables are formed by performing the following operations on
+    base tables and views. These operations are loosely based on Relational
+    Algebra.</para>
+
+    <para><glossterm>JOIN</glossterm> operations</para>
+
+    <para><glossterm>SET</glossterm> and <glossterm>MULTISET</glossterm>
+    operations</para>
+
+    <para><glossterm>SELECTION</glossterm></para>
+
+    <para><glossterm>PROJECTION</glossterm></para>
+
+    <para><glossterm>COMPUTING</glossterm></para>
+
+    <para><glossterm>COLUMN NAMING</glossterm></para>
+
+    <para><glossterm>GROUPING</glossterm> and
+    <glossterm>AGGREGATION</glossterm></para>
+
+    <para><glossterm>SELECTION AFTER GROUPING OR
+    AGGREGATION</glossterm></para>
+
+    <para><glossterm>SET and MULTISET (COLLECTION)
+    OPERATIONS</glossterm></para>
+
+    <para><glossterm>ORDERING</glossterm></para>
+
+    <para><glossterm>SLICING</glossterm></para>
+
+    <para>Conceptually, the operations are performed one by one in the above
+    order if they apply to the given data access statement. In the example
+    below a simple select statement is made more complex by adding various
+    operations.</para>
+
+    <para><programlisting>CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+/* in the next SELECT, no join is performed and no further operation takes place */
+SELECT * FROM atable
+/* in the next SELECT, selection is performed by the WHERE clause, with no further action */
+SELECT * FROM atable WHERE a + b = c
+/* in the next SELECT, projection is performed after the other operations */
+SELECT d, e, f FROM atable WHERE a + b = c
+/* in the next SELECT, computation is performed after projection */
+SELECT (d + e) / f FROM atable WHERE a + b = c
+/* in the next two SELECT statements, column naming is performed in different ways*/
+SELECT (a + e) / f AS calc, f AS div FROM atable WHERE a + b = c
+SELECT dcol, ecol, fcol FROM atable(acol, bcol, ccol, dcol, ecol, fcol) WHERE acol + bcol = ccol
+/* in the next SELECT, both grouping and aggregation is performed */
+SELECT d, e, SUM(f) FROM atable GROUP BY d, e
+/* in the next SELECT, selection is performed after grouping and aggregation is performed */
+SELECT d, e, SUM(f) FROM atable GROUP BY d, e HAVING SUM(f) &gt; 10
+/* in the next SELECT, a UNION is performed on two selects from the same table */
+SELECT d, e, f FROM atable WHERE d = 3 UNION SELECT a, b, c FROM atable WHERE a = 30
+/* in the next SELECT, ordering is performed */
+SELECT (a + e) / f AS calc, f AS div FROM atable WHERE a + b = c ORDER BY calc DESC, div NULLS LAST
+/* in the next SELECT, slicing is performed after ordering */
+SELECT * FROM atable WHERE a + b = c ORDER BY a FETCH 5 ROWS ONLY
+
+</programlisting>The next sections discuss various types of tables and
+    operations involved in data access statements.</para>
+
+    <section>
+      <title>Table</title>
+
+      <para>In data access statements, a table can be a database table (or
+      view) or an ephemeral table formed for the duration of the query. Some
+      types of table are &lt;table primary&gt; and can participate in joins
+      without the use of extra parentheses. The BNF in the Table Primary
+      section below lists different types of &lt;table primary&gt;:</para>
+
+      <para>Tables can also be formed by specifying the values that are
+      contained in them:</para>
+
+      <simpara><literal>&lt;table value constructor&gt; ::= VALUES &lt;row
+      value expression list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;row value expression list&gt; ::= &lt;table row
+      value expression&gt; [ { &lt;comma&gt; &lt;table row value
+      expression&gt; }... ]</literal></simpara>
+
+      <simpara>In the example below a table with two rows and 3 columns is
+      constructed out of some values:</simpara>
+
+      <programlisting>VALUES (12, 14, null), (10, 11, CURRENT_DATE)</programlisting>
+
+      <simpara>When a table is used directly in a UNION or similar operation,
+      the keyword TABLE is used with the name:</simpara>
+
+      <simpara><literal>&lt;explicit table&gt; ::= TABLE &lt;table or query
+      name&gt;</literal></simpara>
+
+      <simpara>In the examples below, all rows of the two tables are included
+      in the union. The keyword TABLE is used in the first example. The two
+      examples below are equivalent.</simpara>
+
+      <programlisting>TABLE atable UNION TABLE anothertable
+SELECT * FROM atable UNION SELECT * FROM anothertable
+</programlisting>
+    </section>
+
+    <section>
+      <title>Query Specification</title>
+
+      <para>A query specification is a SELECT statement. It is the most common
+      form of <literal>&lt;derived table&gt;</literal> . A <literal>&lt;table
+      expression&gt;</literal> is a base table, a view or any form of allowed
+      derived table. The SELECT statement performs projection, naming,
+      computing or aggregation on the rows of the <literal>&lt;table
+      expression&gt;</literal> .</para>
+
+      <simpara><literal>&lt;query specification&gt; ::= SELECT [ DISTINCT |
+      ALL ] &lt;select list&gt; &lt;table expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;select list&gt; ::= &lt;asterisk&gt; | &lt;select
+      sublist&gt; [ { &lt;comma&gt; &lt;select sublist&gt; }... ]
+      </literal></simpara>
+
+      <simpara><literal>&lt;select sublist&gt; ::= &lt;derived column&gt; |
+      &lt;qualified asterisk&gt; </literal></simpara>
+
+      <simpara><literal>&lt;qualified asterisk&gt; ::= &lt;asterisked
+      identifier chain&gt; &lt;period&gt; &lt;asterisk&gt;</literal></simpara>
+
+      <simpara><literal>&lt;asterisked identifier chain&gt; ::= &lt;asterisked
+      identifier&gt; [ { &lt;period&gt; &lt;asterisked identifier&gt; }... ]
+      </literal></simpara>
+
+      <simpara><literal>&lt;asterisked identifier&gt; ::=
+      &lt;identifier&gt;</literal></simpara>
+
+      <simpara><literal>&lt;derived column&gt; ::= &lt;value expression&gt; [
+      &lt;as clause&gt; ] </literal></simpara>
+
+      <simpara><literal>&lt;as clause&gt; ::= [ AS ] &lt;column name&gt;
+      </literal></simpara>
+
+      <para>The qualifier DISTINCT or ALL apply to the results of the SELECT
+      statement after all other operations have been performed. ALL simply
+      returns the rows, while DISTINCT compares the rows and removes the
+      duplicate ones.</para>
+
+      <para>Projection is performed by the <literal>&lt;select
+      list&gt;</literal>.</para>
+
+      <para>A single <literal>&lt;asterisk&gt;</literal> means all columns of
+      the <literal>&lt;table expression&gt;</literal> are included, in the
+      same order as they appear in the <literal>&lt;table
+      expression&gt;</literal>. An asterisk qualified by a table name means
+      all the columns of the qualifier table name are included.</para>
+
+      <para>A derived column is a <literal>&lt;value expression&gt;</literal>,
+      optionally named with the <literal>&lt;as clause&gt;</literal>. A
+      <literal>&lt;value expression&gt;</literal> can be many things. Common
+      types include: the name of a column in the <literal>&lt;table
+      expression&gt;</literal>; an expression based on different columns or
+      constant values; a function call; an aggregate function; a CASE WHEN
+      expression.</para>
+    </section>
+
+    <section>
+      <title>Table Expression</title>
+
+      <para>A table expression is part of the SELECT statement and consists of
+      the FROM clause with optional other clauses that performs selection (of
+      rows) and grouping from the table(s) in the FROM clause.</para>
+
+      <simpara><literal>&lt;table expression&gt; ::= &lt;from clause&gt; [
+      &lt;where clause&gt; ] [ &lt;group by clause&gt; ] [ &lt;having
+      clause&gt; ]</literal></simpara>
+
+      <para><literal>&lt;from clause&gt; ::= FROM &lt;table reference&gt; [ {
+      &lt;comma&gt; &lt;table reference&gt; }... ]</literal></para>
+
+      <simpara><literal>&lt;table reference&gt; ::= &lt;table primary&gt; |
+      &lt;joined table&gt; </literal></simpara>
+
+      <simpara><literal>&lt;table primary&gt; ::= &lt;table or query name&gt;
+      [ [ AS ] &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived
+      column list&gt; &lt;right paren&gt; ] ] </literal></simpara>
+
+      <simpara><literal>| &lt;derived table&gt; [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] </literal></simpara>
+
+      <simpara><literal>| &lt;lateral derived table&gt; [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] </literal></simpara>
+
+      <simpara><literal>| &lt;collection derived table&gt; [ AS ]
+      &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived column
+      list&gt; &lt;right paren&gt; ] </literal></simpara>
+
+      <simpara><literal>| &lt;table function derived table&gt; [ AS ]
+      &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived column
+      list&gt; &lt;right paren&gt; ] </literal></simpara>
+
+      <simpara><literal>| &lt;parenthesized joined
+      table&gt;</literal></simpara>
+
+      <simpara><literal>&lt;where clause&gt; ::= WHERE &lt;boolean value
+      expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;group by clause&gt; ::= GROUP BY [ &lt;set
+      quantifier&gt; ] &lt;grouping element&gt; [ { &lt;comma&gt; &lt;grouping
+      element&gt; }... ]</literal></simpara>
+
+      <simpara><literal>&lt;having clause&gt; ::= HAVING &lt;boolean value
+      expression&gt;</literal></simpara>
+
+      <para>The <literal>&lt;from clause&gt;</literal> contains one or more
+      <literal>&lt;table reference&gt;</literal> separated by commas. A table
+      reference is often a table or view name or a joined table.</para>
+
+      <para>The <literal>&lt;where clause&gt;</literal> filters the rows of
+      the table in the &lt;from clause&gt; and removes the rows for which the
+      search condition is not TRUE.</para>
+
+      <para>The <literal>&lt;group by clause&gt;</literal> is a comma
+      separated list of columns of the table in the <literal>&lt;from
+      clause&gt;</literal> or expressions based on the columns.</para>
+
+      <para>When a <literal>&lt;group by clause&gt;</literal> is used, only
+      the columns used in the <literal>&lt;group by clause&gt;</literal> or
+      expressions used there, can be used in the <literal>&lt;select
+      list&gt;</literal>, together with any <literal>&lt;aggregate
+      function&gt;</literal> on other columns. A <literal>&lt;group by
+      clause&gt;</literal> compares the rows and groups together the rows that
+      have the same values in the columns of the <literal>&lt;group by
+      clause&gt;</literal>. Then any <literal>&lt;aggregate
+      function&gt;</literal> in the <literal>&lt;select list&gt;</literal> is
+      performed on each group, and for each group, a row is formed that
+      contains the values of the columns of the <literal>&lt;group by
+      clause&gt;</literal> and the values returned from each
+      <literal>&lt;aggregate function&gt;. In the first example below, a
+      simple column reference is used in GROUP BY, while in the second
+      example, an expression is used.</literal><programlisting>CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+SELECT d, e, f FROM atable WHERE a + b = c GROUP BY d, e, f
+SELECT d + e, SUM(f) FROM atable WHERE a + b = c GROUP BY d + e HAVING SUM(f) &gt; 2 AND d + e &gt; 4
+</programlisting></para>
+
+      <para>A <literal>&lt;having clause&gt;</literal> filters the rows of the
+      table that is formed after applying the <literal>&lt;group by
+      clause&gt;</literal> using its search condition. The search condition
+      must be an expression based on the expressions in the GROUP BY list or
+      the aggregate functions used.</para>
+    </section>
+
+    <section>
+      <title>Table Primary</title>
+
+      <para>Table primary refers to different forms of table reference in the
+      FROM clause.</para>
+
+      <para>The simplest form of reference is simply a name. This is the name
+      of a table, a view, a transition table in a trigger definition, or a
+      query name specified in the WITH clause of a query expression.</para>
+
+      <para><literal>&lt;table or query name&gt; ::= &lt;table name&gt; |
+      &lt;transition table name&gt; | &lt;query name&gt;</literal></para>
+
+      <para>A query expression that is enclosed in parentheses and returns
+      from zero to many rows is a <literal>&lt;table subquery&gt;</literal>.
+      In a <literal>&lt;derived table&gt;</literal> the query expression is
+      self contained and cannot reference the columns of other table
+      references.</para>
+
+      <para><literal>&lt;derived table&gt; ::= &lt;table
+      subquery&gt;</literal></para>
+
+      <para><literal>When the word LITERAL is used before a &lt;table
+      subquery&gt;, it means the query expression can reference the columns of
+      other table references that precede it. </literal></para>
+
+      <para><literal>&lt;lateral derived table&gt; ::= LATERAL &lt;table
+      subquery&gt;</literal></para>
+
+      <para>UNNEST is similar to LATERAL, but instead of a query expression,
+      and expression that returns an array is used. This expression is
+      converted into a table which has one column that contains the elements
+      of the array, and, if WITH ORDINALITY is used, a second column that
+      contains the index of each element. The array expression usually
+      contains a reference to a column of the table reference preceding the
+      current table reference.</para>
+
+      <para><literal>&lt;collection derived table&gt; ::= UNNEST &lt;left
+      paren&gt; &lt;array value expression&gt; &lt;right paren&gt; [ WITH
+      ORDINALITY ]</literal></para>
+
+      <para>When TABLE is used in this context, it also converts an array
+      value expression to a table, but this array must be the result of a
+      function call. A function that returns a MULTISET can also be used in
+      this context and each row of the multiset is expanded into a row of the
+      table.</para>
+
+      <para><literal>&lt;table function derived table&gt; ::= TABLE &lt;left
+      paren&gt; &lt;collection value expression&gt; &lt;right
+      paren&gt;</literal></para>
+
+      <para>The column list that is specified for the table reference must
+      contain names that are unique within the list</para>
+
+      <para><literal>&lt;derived column list&gt; ::= &lt;column name
+      list&gt;</literal></para>
+
+      <para><literal>&lt;column name list&gt; ::= &lt;column name&gt; [ {
+      &lt;comma&gt; &lt;column name&gt; }... ] </literal></para>
+
+      <para>A parenthesized joined table is simply a joined table contained in
+      parentheses. Joined tables are discussed below.</para>
+
+      <para><literal>&lt;parenthesized joined table&gt; ::= &lt;left paren&gt;
+      &lt;parenthesized joined table&gt; &lt;right paren&gt; | &lt;left
+      paren&gt; &lt;joined table&gt; &lt;right paren&gt;</literal></para>
+    </section>
+
+    <section>
+      <title>Joined Table</title>
+
+      <para>Joins are operators with two table as the operands, resulting in a
+      third table, called joined table. All join operators are evaluated left
+      to right, therefore, with multiple joins, the table resulting from the
+      first join operator becomes an operand of the next join operator.
+      Parentheses can be used to group sequences of joined tables and change
+      the evaluation order. So if more than two tables are joined together
+      with join operators, the end result is also a joined table. There are
+      different types of join, each producing the result table in a different
+      way.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CROSS JOIN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CROSS JOIN</emphasis></simpara>
+
+      <para>The simplest form of join is CROSS JOIN. The CROSS JOIN of two
+      tables is a table that has all the columns of the first table, followed
+      by all the columns of the second table, in the original order. Each row
+      of the first table is combined with each row of the second table to fill
+      the rows of the new table. If the rows of each table form a set, then
+      the rows of the CROSS JOIN table form the Cartesian product of the rows
+      of the two table operands.</para>
+
+      <para>The CROSS JOIN can be expressed in two forms. The first form is
+      <literal>A CROSS JOIN B</literal>. The second form is <literal>A,
+      B</literal>. This type of join is not generally very useful, as it
+      returns large result tables.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>UNION JOIN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">UNION JOIN</emphasis></simpara>
+
+      <para>The UNION JOIN has limited use in queries. The result table has
+      the same columns as that of CROSS JOIN. Each row of the first table is
+      extended to the right with nulls and added to the new table. Each row of
+      the second table is extended to the left with nulls and added to the new
+      table. The UNION JOIN is expressed as <literal>A UNION JOIN B</literal>.
+      This should not be confused with <literal>A UNION B</literal>, which is
+      a set operation. Union join is for special applications and is not
+      commonly used.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>JOIN with condition</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">JOIN ... ON</emphasis></simpara>
+
+      <para>The condition join is similar to CROSS JOIN, but a condition is
+      tested for each row of the new table and the row is created only if the
+      condition is true. This form of join is expressed as <literal>A JOIN B
+      ON (&lt;search condition&gt;)</literal>.</para>
+
+      <para>Equijoin is a condition join in which the search condition is an
+      equality condition between on or more pairs of columns from the two
+      table. Equijoin is the most commonly used type of join.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>JOIN USING</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">JOIN ... USING</emphasis></simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>NATURAL JOIN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">NATURAL JOIN</emphasis></simpara>
+
+      <para>Joins with USING or NATURAL keywords joins are similar to an
+      equijoin but they cannot be replaced simply with an equijoin. The new
+      table is formed with the specified or implied shared columns of the two
+      tables, followed by the rest of the columns from each table. In NATURAL
+      JOIN, the shared columns are all the column pairs that have the same
+      name in the first and second table. In JOIN USING, only columns names
+      that are specified by the USING clause are shared. The joins are
+      expressed as <literal>A NATURAL JOIN B</literal>, and <literal>A JOIN B
+      USING (&lt;comma separated column name list&gt;)</literal>.</para>
+
+      <para>The columns of the joined table are formed by the following
+      procedures: In JOIN ... USING the shared columns are added to the joined
+      table in the same order as they appear in the column name list. In
+      NATURAL JOIN the shared columns are added to the joined table in the
+      same order as they appear in the first table. In bother forms of join,
+      the non-shared columns of the first table are added in the order they
+      appear in the first table, finally the non-shared columns of the second
+      table are added in the order they appear in the second table.</para>
+
+      <para>The type of each shared column of the joined table is based on the
+      type of the columns in the original tables. If the original types are
+      not exactly the same, the type of the shared column is formed by type
+      aggregation. Type aggregations selects a type that can represent values
+      of both aggregated types. Simple type aggregation picks one of the
+      types. For example SMALLINT and INTEGER, results in INTEGER, or
+      VARCHAR(10) and VARCHAR(20) results in VARCHAR(20). More complex type
+      aggregation inherits properties from both types. For example DECIMAL(8)
+      and DECIMAL (6,2) results in DECIMAL (8,2).</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>OUTER JOIN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">OUTER JOIN</emphasis></simpara>
+
+      <para>LEFT, RIGHT and FULL OUTER JOIN</para>
+
+      <para>The three qualifiers can be added to all types of JOIN apart from
+      CROSS JOIN and UNION JOIN. First the new table is populated with the
+      rows from the original join. If LEFT is specified, all the rows from the
+      first table that did not make it into the new table are extended to the
+      right with nulls and added to the table. If RIGHT is specified, all the
+      rows from the second table that did not make it into the new table are
+      extended to the left with nulls and added to the table. If FULL is
+      specified, the addition of leftover rows is performed from both the
+      first and the second table. These forms are expressed by prefixing the
+      join specification with the given keyword. For example <literal>A LEFT
+      OUTER JOIN B ON (&lt;search condition&gt;)</literal> or <literal>A
+      NATURAL FULL OUTER JOIN B</literal> or <literal>A FULL OUTER JOIN B
+      USING (&lt;comma separated column name list&gt;)</literal>.</para>
+    </section>
+
+    <section>
+      <title>Selection</title>
+
+      <para>Despite the name, selection has nothing to do with the list of
+      columns in a SELECT statement. In fact, it refers to the search
+      condition used to limit the rows that from a result table (selection of
+      rows, not columns). In SQL, simple selection is expressed with a WHERE
+      condition appended to a single table or a joined table. In some cases,
+      this method of selection is the only method available. But when it is
+      possible to perform the selection with join conditions, this is the
+      better method, as it results in a clearer expression of the
+      query.</para>
+    </section>
+
+    <section>
+      <title>Projection</title>
+
+      <para>Projection is selection of the columns from a simple or joined
+      table to form a result table. Explicit projection is performed in the
+      SELECT statement by specifying the select column list. Some form of
+      projection is also performed in JOIN ... USING and NATURAL JOIN.</para>
+
+      <para>The joined table has columns that are formed according to the
+      rules mentioned above. But in many cases, not all the columns are
+      necessary for the intended operation. If the statement is in the form,
+      SELECT * FROM &lt;joined table&gt;, then all the columns of &lt;joined
+      table&gt; are returned. But normally, the columns to be returned are
+      specified after the SELECT keyword, separated from each other with
+      commas.</para>
+    </section>
+
+    <section>
+      <title>Computed Columns</title>
+
+      <para>In the select list, it is possible to use expressions that
+      reference any columns of &lt;joined table&gt;. Each of these expressions
+      forms a computed column. It is computed for each row of the result
+      table, using the values of the columns of the &lt;joined table&gt; for
+      that row.</para>
+    </section>
+
+    <section>
+      <title>Naming</title>
+
+      <para>Naming is used to hide the original names of tables or table
+      columns and to replace them with new names in the scope of the query.
+      Naming is also used for defining names for computed columns.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>naming in joined table</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">Naming in Joined
+      Table</emphasis></simpara>
+
+      <para>Naming is performed by adding a new name after a table's real name
+      and by adding a list of column names after the new table name. Both
+      table naming and column naming are optional, but table naming is
+      required for column naming. The expression <literal>A [AS] X (&lt;comma
+      separated column name list&gt;)</literal> means table A is used in the
+      query expression as table X and its columns are named as in the given
+      list. The original name A, or its original column names, are not visible
+      in the scope of the query. The BNF is given below. The
+      <literal>&lt;correlation name&gt;</literal> can be the same or different
+      from the name of the table. The <literal>&lt;derived column
+      list&gt;</literal> is a comma separated list of column names. The degree
+      of this list must be equal to the degree of the table. The column names
+      in the list must be distinct. They can be the same or different from the
+      names of the table's columns.</para>
+
+      <para><literal>&lt;table or query name&gt; [ [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] ]</literal></para>
+
+      <simpara>In the examples below, the columns of the original tables are
+      named (a, b, c, d, e, f). The two queries are equivalent. In the second
+      query, the table and its columns are renamed and the new names are used
+      in the WHERE clauses:</simpara>
+
+      <programlisting>CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+SELECT d, e, f FROM atable WHERE a + b = c
+SELECT x, y, z FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>naming in select list</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">Naming in Select
+      List</emphasis></simpara>
+
+      <para>Naming in the SELECT list logically takes place after naming in
+      the joined table. The new names for columns are not visible in the
+      immediate query expression or query expression. They become visible in
+      the ORDER BY clause and in the result table that is returned to the
+      user. Or if the query expression is used as a derived table in an
+      enclosing query expression.</para>
+
+      <para>In the example below, the query is on the same table but with
+      column renaming in the Select list. The new names are used in the ORDER
+      BY clause:</para>
+
+      <programlisting>SELECT x + y AS xysum, y + z AS yzsum FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w ORDER BY xysum, yzsum</programlisting>
+
+      <para>If the names <literal>xysum</literal> or <literal>yzsum</literal>
+      are not used, the computed columns cannot be referenced in the ORDER BY
+      list.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>name resolution</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">Name Resolution</emphasis></simpara>
+
+      <simpara>In a joined table, if a column name appears in tables on both
+      sides then any reference to the name must use the table name in order to
+      specify which table is being referred to.</simpara>
+    </section>
+
+    <section>
+      <title>Grouping Operations</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>GROUPING OPERATIONS</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">Grouping Operations</emphasis></simpara>
+
+      <para>Grouping results in the elimination of duplicate rows. A grouping
+      operation is performed after the operations discussed above. A simple
+      form of grouping is performed by the use of DISTINCT after SELECT. This
+      eliminates all the duplicate rows (rows that have the same value in each
+      of their columns when compared to another row). The other form of
+      grouping is performed with the GROUP BY clause. This form is usually
+      used together with aggregation.</para>
+    </section>
+
+    <section>
+      <title>Aggregation</title>
+
+      <para>Aggregation is an operation that computes a single value from the
+      values of a column over several rows. The operation is performed with an
+      aggregate function. The simplest form of aggregation is counting,
+      performed by the COUNT function.</para>
+
+      <para>Other common aggregate functions return the maximum, minimum and
+      average value among the values in different rows.</para>
+    </section>
+
+    <section>
+      <title>Set Operations</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SET OPERATIONS</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">Set and Multiset
+      Operations</emphasis></simpara>
+
+      <para>While join operations generally result in laterally expanded
+      tables, SET and COLLECTION operations are performed on two tables that
+      have the same degree and result in a table of the same degree. The SET
+      operations are UNION, INTERSECT and EXCEPT (difference). When each of
+      these operations is performed on two tables, the collection of rows in
+      each table and in the result is reduced to a set of rows, by eliminating
+      duplicates. The set operations are then performed on the two tables,
+      resulting in the new table which itself is a set of rows. Collection
+      operations are similar but the tables are not reduced to sets before or
+      after the operation and the result is not necessarily a set, but a
+      collection of rows.</para>
+
+      <para>The set operations on two tables A and B are: <literal>A UNION
+      [DISTINCT] B</literal>, <literal>A INTERSECT [DISTINCT] B</literal> and
+      <literal>A EXCEPT [DISTINCT] B</literal>. The result table is formed in
+      the following way: The UNION operation adds all the rows from A and B
+      into the new table, but avoids copying duplicate rows. The INTERSECT
+      operation copies only those rows from each table that also exist in the
+      other table, but avoids copying duplicate rows. The EXCEPT operation
+      copies those rows from the first table which do not exist in the second
+      table, but avoids copying duplicate rows.</para>
+
+      <para>The collection operations are similar to the set operations, but
+      can return duplicate rows. They are <literal>A UNION ALL B</literal>,
+      <literal>A INTERSECT ALL B</literal> and <literal>A EXCEPT ALL
+      B</literal>. The UNION ALL operation adds all the rows from A and B into
+      the new table. The INTERSECT operation copies only those rows from each
+      table that also exist in the other table. If n copies of a rows exists
+      in one table, and m copies in the other table, the number of copies in
+      the result table is the smaller of n and m. The EXCEPT operation copies
+      those rows from the first table which do not exist in the second table.
+      If n copies of a row exist in the first table and m copies in the second
+      table the number of copies in the result table is n-m, or if n &lt; m,
+      then zero.</para>
+    </section>
+
+    <section>
+      <title>Query Expression</title>
+
+      <para>A query expression consists of an optional WITH clause and a query
+      expression body. The WITH clause lists one or more named ephemeral
+      tables that can be referenced in the query expression body.</para>
+
+      <para><literal>&lt;query expression&gt; ::= [ &lt;with clause&gt; ]
+      &lt;query expression body&gt;</literal></para>
+
+      <para><literal>&lt;with clause&gt; ::= WITH &lt;with
+      list&gt;</literal></para>
+
+      <para><literal>&lt;with list&gt; ::= &lt;with list element&gt; [ {
+      &lt;comma&gt; &lt;with list element&gt; }... ] </literal></para>
+
+      <para><literal>&lt;with list element&gt; ::= &lt;query name&gt; [
+      &lt;left paren&gt; &lt;with column list&gt; &lt;right paren&gt; ] AS
+      &lt;left paren&gt; &lt;query expression&gt; &lt;right paren&gt;
+      </literal></para>
+
+      <para><literal>&lt;with column list&gt; ::= &lt;column name
+      list&gt;</literal></para>
+
+      <para>A query expression body refers to a table formed by using UNION
+      and other set operations. The query expression body is evaluated from
+      left to right and the INTERSECT operator has precedence over the UNION
+      and EXCEPT operators. A simplified BNF is given below:</para>
+
+      <simpara><literal>&lt;query expression body&gt; ::= &lt;query term&gt; |
+      &lt;query expression body&gt; UNION | EXCEPT [ ALL | DISTINCT ] [
+      &lt;corresponding spec&gt; ] &lt;query term&gt;</literal></simpara>
+
+      <simpara><literal>&lt;query term&gt; ::= &lt;query primary&gt; |
+      &lt;query term&gt; INTERSECT [ ALL | DISTINCT ] [ &lt;corresponding
+      spec&gt; ] &lt;query term&gt;</literal></simpara>
+
+      <simpara><literal>&lt;query primary&gt; ::= &lt;simple table&gt; |
+      &lt;left paren&gt; &lt;query expression body&gt; [ &lt;order by
+      clause&gt; ] [ &lt;result offset clause&gt; ] [ &lt;fetch first
+      clause&gt; ] &lt;right paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;simple table&gt; ::= &lt;query specification&gt; |
+      &lt;table value constructor&gt; | &lt;explicit table&gt; &lt;explicit
+      table&gt; ::= TABLE &lt;table or query name&gt;</literal></simpara>
+
+      <para><literal>&lt;corresponding spec&gt; ::= CORRESPONDING [ BY
+      &lt;left paren&gt; &lt;column name list&gt; &lt;right paren&gt;
+      ]</literal></para>
+
+      <para>A <literal>&lt;query term&gt;</literal> and a <literal>&lt;query
+      primary&gt;</literal> can be a SELECT statement, an
+      <literal>&lt;explicit table&gt;</literal>, or a <literal>&lt;table value
+      constructor&gt;</literal>.</para>
+
+      <para>The CORRESPONDING clause is optional. If it is not specified, then
+      the <literal>&lt;query term&gt;</literal> and the <literal>&lt;query
+      primary&gt;</literal> must have the same number of columns. If
+      CORRESPONDING is specified, the two sides need not have the same number
+      of columns. If no column list is used with CORRESPONDING, then all the
+      column names that are common in the tables on two sides are used in the
+      order in which they appear in the first table. If a columns list is
+      used, it allows you to select only some columns of the tables on the
+      left and right side to create the new table. In the example below the
+      columns named u and v from the two SELECT statements are used to create
+      the UNION table.</para>
+
+      <para><programlisting>SELECT * FROM atable UNION CORRESPONDING BY (u, v) SELECT * FROM anothertable
+</programlisting>The type of each column of the query expression is determined
+      by combining the types of the corresponding columns from the two
+      participating tables.</para>
+    </section>
+
+    <section>
+      <title>Ordering</title>
+
+      <para>When the rows of the result table have been formed, it is possible
+      to specify the order in which they are returned to the user. The ORDER
+      BY clause is used to specify the columns used for ordering, and whether
+      ascending or descending ordering is used. It can also specify whether
+      NULL values are returned first or last.</para>
+
+      <programlisting>SELECT x + y AS xysum, y + z AS yzsum FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w ORDER BY xysum NULLS LAST, yzsum NULLS FIRST</programlisting>
+
+      <para>The ORDER BY clause specifies one or more <literal>&lt;value
+      expressions&gt;</literal>. The list of rows is sorted according to the
+      first <literal>&lt;value expression&gt;</literal>. When some rows are
+      sorted equal then they are sorted according to the next
+      <literal>&lt;value expression&gt;</literal> and so on.</para>
+
+      <para><literal>&lt;order by clause&gt; ::= ORDER BY &lt;sort
+      specification&gt; [ { &lt;comma&gt; &lt;sort specification&gt; }...
+      ]</literal></para>
+
+      <para><literal>&lt;sort specification&gt; ::= &lt;value expression&gt; [
+      ASC | DESC ] [ NULLS FIRST | NULLS LAST ]</literal></para>
+    </section>
+
+    <section>
+      <title>Slicing</title>
+
+      <para>A different form of limiting the rows can be performed on the
+      result table after it has been formed according to all the other
+      operations (selection, grouping, ordering etc.). This is specified by
+      the FETCH ... ROWS and OFFSET clauses of a SELECT statement. In this
+      form, the specified OFFSET rows are removed from start of the table,
+      then up to the specified FETCH rows are kept and the rest of the rows
+      are discarded.</para>
+
+      <para><literal>&lt;result offset clause&gt; ::= OFFSET &lt;offset row
+      count&gt; { ROW | ROWS } </literal></para>
+
+      <para><literal>&lt;fetch first clause&gt; ::= FETCH { FIRST | NEXT } [
+      &lt;fetch first row count&gt; ] { ROW | ROWS } ONLY</literal></para>
+
+      <para><literal>&lt;limit clause&gt; ::= LIMIT [ &lt;fetch first row
+      count&gt; ]</literal></para>
+
+      <para>A slicing operation takes the result set that has been already
+      processed and ordered. It then discards the specified number of rows
+      from the start of the result set and returns the specified number of
+      rows after the discarded rows.</para>
+
+      <programlisting>SELECT a, b FROM atable WHERE d &lt; 5 ORDER BY absum OFFSET 3 FETCH 2 ROWS ONLY 
+SELECT a, b FROM atable WHERE d &lt; 5 ORDER BY absum OFFSET 3 LIMIT 2 /* alternative keyword */ </programlisting>
+    </section>
+  </section>
+
+  <section>
+    <title>Data Change Statements</title>
+
+    <section>
+      <title>Delete Statement</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DELETE FROM</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DELETE FROM</emphasis></simpara>
+
+      <simpara><emphasis>delete statement: searched</emphasis></simpara>
+
+      <simpara><literal>&lt;delete statement: searched&gt; ::= DELETE FROM
+      &lt;target table&gt; [ [ AS ] &lt;correlation name&gt; ] [ WHERE
+      &lt;search condition&gt; ]</literal></simpara>
+
+      <simpara>Delete rows of a table. The search condition is a
+      <literal>&lt;boolean value expression&gt;</literal> that is evaluated
+      for each row of the table. If the condition is true, the row is deleted.
+      If the condition is not specified, all the rows of the table are
+      deleted. In fact, an implicit SELECT is performed in the form of
+      <literal>SELECT * FROM &lt;target table&gt; [ WHERE &lt;search
+      condition&gt;]</literal> and the selected rows are deleted. When used in
+      JDBC, the number of rows returned by the implicit SELECT is returned as
+      the update count.</simpara>
+
+      <simpara>If there are FOREIGN KEY constraints on other tables that
+      reference the subject table, and the FOREIGN KEY constraints have
+      referential actions, then rows from those other tables that reference
+      the deleted rows are either deleted, or updated, according to the
+      specified referential actions.</simpara>
+
+      <simpara>In the second example below the rows that have the maximum
+      value for column A are deleted;</simpara>
+
+      <programlisting>DELETE FROM T WHERE C &gt; 5
+DELETE FROM T AS TT WHERE TT.A = (SELECT MAX(A) FROM T)
+</programlisting>
+    </section>
+
+    <section>
+      <title>Truncate Statement</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>TRUNCATE TABLE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">TRUNCATE TABLE</emphasis></simpara>
+
+      <simpara><emphasis>truncate table statement</emphasis></simpara>
+
+      <simpara><literal>&lt;truncate table statement&gt; ::= TRUNCATE TABLE
+      &lt;target table&gt; [ &lt;identity column restart option&gt;
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;identity column restart option&gt; ::= CONTINUE
+      IDENTITY | RESTART IDENTITY</literal></simpara>
+
+      <simpara>Delete all rows of a table without firing its triggers. This
+      statement can only be used on base tables (not views). If the table is
+      referenced in a FOREIGN KEY constraint, the statement causes an
+      exception. Triggers defined on the table are not executed with this
+      statement. The default for <literal>&lt;identity column restart
+      option&gt;</literal> is <literal>CONTINUE IDENTITY</literal>. This means
+      no change to the IDENTITY sequence of the table. If <literal>RESTART
+      IDENTITY</literal> is specified, then the sequence is reset to its start
+      value.</simpara>
+
+      <simpara>TRUNCATE is faster than ordinary DELETE. The TRUNCATE statement
+      is an SQL Standard data change statement, therefore it is performed
+      under transaction control and can be rolled back if the connection is
+      not in the auto-commit mode.</simpara>
+    </section>
+
+    <section>
+      <title>Insert Statement</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>INSERT INTO</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">INSERT INTO</emphasis></simpara>
+
+      <simpara><emphasis>insert statement</emphasis></simpara>
+
+      <simpara><literal>&lt;insert statement&gt; ::= INSERT INTO &lt;target
+      table&gt; &lt;insert columns and source&gt;</literal></simpara>
+
+      <simpara><literal>&lt;insert columns and source&gt; ::= &lt;from
+      subquery&gt; | &lt;from constructor&gt; | &lt;from
+      default&gt;</literal></simpara>
+
+      <simpara><literal>&lt;from subquery&gt; ::= [ &lt;left paren&gt;
+      &lt;insert column list&gt; &lt;right paren&gt; ] [ &lt;override
+      clause&gt; ] &lt;query expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;from constructor&gt; ::= [ &lt;left paren&gt;
+      &lt;insert column list&gt; &lt;right paren&gt; ] [ &lt;override
+      clause&gt; ] &lt;contextually typed table value
+      constructor&gt;</literal></simpara>
+
+      <simpara><literal>&lt;override clause&gt; ::= OVERRIDING USER VALUE |
+      OVERRIDING SYSTEM VALUE</literal></simpara>
+
+      <simpara><literal>&lt;from default&gt; ::= DEFAULT
+      VALUES</literal></simpara>
+
+      <simpara><literal>&lt;insert column list&gt; ::= &lt;column name
+      list&gt;</literal></simpara>
+
+      <simpara>Insert new rows in a table. An INSERT statement inserts one or
+      more rows into the table.</simpara>
+
+      <simpara>The special form, <literal>INSERT INTO &lt;target table&gt;
+      DEFAULT VALUES</literal> can be used with tables which have a default
+      value for each column.</simpara>
+
+      <simpara>With the other forms of INSERT, the optional
+      <literal>(&lt;insert column list&gt;)</literal> specifies to which
+      columns of the table the new values are assigned.</simpara>
+
+      <simpara>In one form, the inserted values are from a <literal>&lt;query
+      expression&gt;</literal> and all the rows that are returned by the
+      <literal>&lt;query expression&gt;</literal> are inserted into the table.
+      If the <literal>&lt;query expression&gt;</literal> returns no rows,
+      nothing is inserted.</simpara>
+
+      <simpara>In the other form, a comma separated list of values called
+      <literal>&lt;contextually typed table value constructor&gt;</literal> is
+      used to insert one or more rows into the table. This list is
+      contextually typed, because the keywords NULL and DEFAULT can be used
+      for the values that are assigned to each column of the table. The
+      keyword DEFAULT means the default value of the column and can be used
+      only if the target column has a default value or is an IDENTITY or
+      GENERATED column of the table.</simpara>
+
+      <simpara>The <literal>&lt;override clause&gt;</literal> must be used
+      when a value is explicitly assigned to a column that has been defined as
+      GENERATED ALWAYS AS IDENTITY. The clause, OVERRIDE SYSTEM VALUE means
+      the provided values are used for the insert, while OVERRIDING USER VALUE
+      means the provided values are simply ignored and the values generated by
+      the system are used instead.</simpara>
+
+      <simpara>An array can be inserted into a column of the array type by
+      using literals, by specifying a parameter in a prepared statement or an
+      existing array returned by query expression. The last example below
+      inserts an array.</simpara>
+
+      <simpara>The rows that are inserted into the table are checked against
+      all the constraints that have been declared on the table. The whole
+      INSERT operation fails if any row fails to inserted due to constraint
+      violation. Examples:</simpara>
+
+      <programlisting>INSERT INTO T DEFAULT VALUES /* all columns of T have DEFAULT clauses */
+INSERT INTO T (SELECT * FROM Z) /* table Z has the same columns as table T */
+INSERT INTO T (A,B) VALUES ((1,2),(3,NULL), (DEFAULT,6)) /* three rows are inserted into table T */
+INSERT INTO T VALUES 3, ARRAY['hot','cold']
+</programlisting>
+    </section>
+
+    <section>
+      <title>Update Statement</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>UPDATE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">UPDATE</emphasis></simpara>
+
+      <simpara><emphasis>update statement: searched</emphasis></simpara>
+
+      <simpara><literal>&lt;update statement: searched&gt; ::= UPDATE
+      &lt;target table&gt; [ [ AS ] &lt;correlation name&gt; ] SET &lt;set
+      clause list&gt; [ WHERE &lt;search condition&gt; ]</literal></simpara>
+
+      <simpara>Update rows of a table. An UPDATE statement selects rows from
+      the <literal>&lt;target table&gt;</literal> using an implicit SELECT
+      statement formed in the following manner:</simpara>
+
+      <simpara><literal>SELECT * FROM &lt;target table&gt; [ [ AS ]
+      &lt;correlation name&gt; ] [ WHERE &lt;search condition&gt;
+      ]</literal></simpara>
+
+      <simpara>Then it applies the <literal>SET &lt;set clause
+      list&gt;</literal> expression to each selected row.</simpara>
+
+      <simpara>If the implicit SELECT returns no rows, no update takes place.
+      When used in JDBC, the number of rows returned by the implicit SELECT is
+      returned as the update count.</simpara>
+
+      <simpara>If there are FOREIGN KEY constraints on other tables that
+      reference the subject table, and the FOREIGN KEY constraints have
+      referential actions, then rows from those other tables that reference
+      the updated rows are updated, according to the specified referential
+      actions.</simpara>
+
+      <simpara>The rows that are updated are checked against all the
+      constraints that have been declared on the table. The whole UPDATE
+      operation fails if any row violates any constraint.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>set clause in UPDATE and MERGE statements</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">set clause list</emphasis></simpara>
+
+      <simpara><emphasis>set clause list</emphasis></simpara>
+
+      <simpara><literal>&lt;set clause list&gt; ::= &lt;set clause&gt; [ {
+      &lt;comma&gt; &lt;set clause&gt; }... ]</literal></simpara>
+
+      <simpara><literal>&lt;set clause&gt; ::= &lt;multiple column
+      assignment&gt; | &lt;set target&gt; &lt;equals operator&gt; &lt;update
+      source&gt;</literal></simpara>
+
+      <simpara><literal>&lt;multiple column assignment&gt; ::= &lt;set target
+      list&gt; &lt;equals operator&gt; &lt;assigned
+      row&gt;</literal></simpara>
+
+      <simpara><literal>&lt;set target list&gt; ::= &lt;left paren&gt; &lt;set
+      target&gt; [ { &lt;comma&gt; &lt;set target&gt; }... ] &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;assigned row&gt; ::= &lt;contextually typed row
+      value expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;set target&gt; ::= &lt;column
+      name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;update source&gt; ::= &lt;value expression&gt; |
+      &lt;contextually typed value specification&gt;</literal></simpara>
+
+      <simpara>Specify a list of assignments. This is used in UPDATE, MERGE
+      and SET statements to assign values to a scalar or row target.</simpara>
+
+      <simpara>Apart from setting a whole target to a value, a SET statement
+      can set individual elements of an array to new values. The last example
+      below shows this form of assignment to the array in the column named
+      B.</simpara>
+
+      <simpara>In the examples given below, UPDATE statements with single and
+      multiple assignments are shown. Note in the third example, a SELECT
+      statement is used to provide the update values for columns A and C,
+      while the update value for column B is given separately. The SELECT
+      statement must return exactly one row . In this example the SELECT
+      statement refers to the existing value for column C in its search
+      condition.</simpara>
+
+      <programlisting>UPDATE T SET A = 5 WHERE ...
+UPDATE T SET (A, B) = (1, NULL) WHERE ...
+UPDATE T SET (A, C) = (SELECT X, Y FROM U WHERE Z = C), B = 10 WHERE ...
+UPDATE T SET A = 3, B[3] = 'warm'
+</programlisting>
+    </section>
+
+    <section>
+      <title>Merge Statement</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>MERGE INTO</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">MERGE INTO</emphasis></simpara>
+
+      <simpara><emphasis>merge statement</emphasis></simpara>
+
+      <simpara><literal>&lt;merge statement&gt; ::= MERGE INTO &lt;target
+      table&gt; [ [ AS ] &lt;merge correlation name&gt; ] USING &lt;table
+      reference&gt; ON &lt;search condition&gt; &lt;merge operation
+      specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;merge correlation name&gt; ::= &lt;correlation
+      name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;merge operation specification&gt; ::= &lt;merge
+      when clause&gt;...</literal></simpara>
+
+      <simpara><literal>&lt;merge when clause&gt; ::= &lt;merge when matched
+      clause&gt; | &lt;merge when not matched clause&gt;</literal></simpara>
+
+      <simpara><literal>&lt;merge when matched clause&gt; ::= WHEN MATCHED
+      THEN &lt;merge update specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;merge when not matched clause&gt; ::= WHEN NOT
+      MATCHED THEN &lt;merge insert specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;merge update specification&gt; ::= UPDATE SET
+      &lt;set clause list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;merge insert specification&gt; ::= INSERT [
+      &lt;left paren&gt; &lt;insert column list&gt; &lt;right paren&gt; ] [
+      &lt;override clause&gt; ] VALUES &lt;merge insert value
+      list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;merge insert value list&gt; ::= &lt;left paren&gt;
+      &lt;merge insert value element&gt; [ { &lt;comma&gt; &lt;merge insert
+      value element&gt; }... ] &lt;right paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;merge insert value element&gt; ::= &lt;value
+      expression&gt; | &lt;contextually typed value
+      specification&gt;</literal></simpara>
+
+      <simpara>Update rows, or insert new rows into the <literal>&lt;target
+      table&gt;</literal>. The MERGE statement uses a second table, specified
+      by <literal>&lt;table reference&gt;</literal>, to determine the rows to
+      be updated or inserted. It is possible to use the statement only to
+      update rows or to insert rows, but usually both update and insert are
+      specified.</simpara>
+
+      <simpara>The <literal>&lt;search condition&gt;</literal> matches each
+      row of the <literal>&lt;table reference&gt;</literal> with each row of
+      the <literal>&lt;target table&gt;</literal>. If the two rows match then
+      the UPDATE clause is used to update the matching row of the target
+      table. Those rows of <literal>&lt;table reference&gt;</literal> that
+      have no matching rows are then used to insert new rows into the
+      <literal>&lt;target table&gt;</literal>. Therefore, a MERGE statement
+      can update between 0 and all the rows of the <literal>&lt;target
+      table&gt;</literal> and can insert between 0 and the number of the rows
+      in <literal>&lt;table reference&gt;</literal> into the
+      <literal>&lt;target table&gt;</literal>. If any row in the
+      <literal>&lt;target table&gt;</literal> matches more than one row in
+      <literal>&lt;table reference&gt;</literal> a cardinality error is
+      raised. On the other hand, several rows in the <literal>&lt;target
+      table&gt;</literal> can matches a single row in <literal>&lt;table
+      reference&gt;</literal> without any error. The constraints and
+      referential actions specified on the database tables are enforced the
+      same way as for an update and an insert statement.</simpara>
+
+      <simpara>The MERGE statement can be used with only the WHEN NOT MATCHED
+      clause as a conditional INSERT statement that inserts a row if no
+      existing rows match a condition.</simpara>
+
+      <simpara>In the first example below, the table originally contains two
+      rows for different furniture. The <literal>&lt;table
+      reference&gt;</literal> is the <literal>(VALUES(1, 'conference table'),
+      (14, 'sofa'), (5, 'coffee table'))</literal> expression, which evaluates
+      to a table with 3 rows. When the x value for a row matches an existing
+      row, then the existing row is updated. When the x value does not match,
+      the row is inserted. Therefore one row of table t is updated from
+      'dining table' to 'conference table', and two rows are inserted into
+      table t. The second example uses a SELECT statement as the source of the
+      values for the MERGE.</simpara>
+
+      <simpara>In the third example, a new row in inserted into the table only
+      when the primary key for the new row does not exist. This example uses
+      parameters and should be executed as a JDBC PreparedStatement.</simpara>
+
+      <programlisting>CREATE TABLE t (id INT PRIMARY KEY, description VARCHAR(100))
+INSERT INTO t VALUES (1, 'dining table'), (2, 'deck chair')
+MERGE INTO t USING (VALUES(1, 'conference table'), (14, 'sofa'), (5, 'coffee table')) 
+   AS vals(x,y) ON t.id = vals.x
+   WHEN MATCHED THEN UPDATE SET t.description = vals.y
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, vals.y
+
+MERGE INTO t USING (SELECT * FROM tt WHERE acol = 2) AS vals(x,y) ON t.id = vals.x
+   WHEN MATCHED THEN UPDATE SET t.description = vals.y
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, vals.y
+
+MERGE INTO t USING (VALUES(CAST(? AS INT))) AS vals(x) ON t.id = vals.x
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, ?
+</programlisting>
+    </section>
+  </section>
+</chapter>
diff --git a/doc-src/guide/databaseobjects.xml b/doc-src/guide/databaseobjects.xml
new file mode 100644
index 0000000..3c0a60f
--- /dev/null
+++ b/doc-src/guide/databaseobjects.xml
@@ -0,0 +1,2908 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="databaseobjects-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/2000/svg"
+         xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="databaseobjects-title">Schemas and Database Objects</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3622 $</releaseinfo>
+
+    <pubdate>$Date: 2010-06-04 11:33:51 -0400 (Fri, 04 Jun 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2009 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section>
+    <title>Overview</title>
+
+    <para>The persistent elements of an SQL environment are database objects.
+    The database consists of catalogs plus authorizations.</para>
+
+    <para>A catalog contains schemas, while schemas contain the objects that
+    contain data or govern the data.</para>
+
+    <para>Each catalog contains a special schema called INFORMATION_SCHEMA.
+    This schema is read-only and contains some views and other schema objects.
+    The views contain lists of all the database objects that exist within the
+    catalog, plus all authorizations.</para>
+
+    <para>Each database object has a name. A name is an identifier and is
+    unique within its name-space.</para>
+  </section>
+
+  <section>
+    <title>Schemas and Schema Objects</title>
+
+    <para>In HyperSQL, there is only one catalog per database. The name of the
+    catalog is PUBLIC. You can rename the catalog with the <literal>ALTER
+    CATALOG RENAME TO</literal> statement. All schemas belong the this
+    catalog. The catalog name has no relation to the file name of the
+    database.</para>
+
+    <para>Each database has also an internal "unique" name which is
+    automatically generated when the database is created. This name is used
+    for event logging. You can also change this unique name.</para>
+
+    <para>Schema objects are database objects that contain data or govern or
+    perform operations on data. By definition, each schema object belongs to a
+    specific schema.</para>
+
+    <para>Schema objects can be divided into groups according to their
+    characteristics.</para>
+
+    <itemizedlist>
+      <listitem>
+        <para>Some kinds of schema objects can exist independently from other
+        schema object. Other kinds can exist only as an element of another
+        schema object. These dependent objects are automatically destroyed
+        when the parent object is dropped.</para>
+      </listitem>
+
+      <listitem>
+        <para>Separate name-spaces exists for different kinds of schema
+        object. Some name-spaces are shared between two similar kinds of
+        schema objects.</para>
+      </listitem>
+
+      <listitem>
+        <para>There can be dependencies between various schema objects, as a
+        schema object can include references to other schema objects. These
+        references can cross schema boundaries. Interdependence and cross
+        referencing between schema objects is allowed in some circumstances
+        and disallowed in some others.</para>
+      </listitem>
+
+      <listitem>
+        <para>Schema objects can be destroyed with the DROP statement. If
+        dependent schema objects exist, a DROP statement will succeed only if
+        it has a CASCADE clause. In this case, dependent objects are also
+        destroyed in most cases. In some cases, such as dropping DOMAIN
+        objects, the dependent objects are not destroyed, but modified to
+        remove the dependency.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>A new HyperSQL catalog contains an empty schema called PUBLIC. By
+    default, this schema is the initial schema when a new session is started.
+    New schemas and schema objects can be defined and used in the PUBLIC
+    schema, as well as any new schema that is created by the user. You can
+    rename the PUBLIC schema.</para>
+
+    <para>HyperSQL allows all schemas to be dropped, except the schema that is
+    the default initial schema for new sessions (by default, the PUBLIC
+    schema). For this schema, a DROP SCHEMA ... CASCADE statement will succeed
+    but will result in an empty schema, rather than no schema.</para>
+
+    <para>The statements for setting the initial schema for users are
+    described in the <link endterm="accesscontrol-statements-title" os=""
+    xlink:href="#accesscontrol-chapt"></link> chapter.</para>
+
+    <section>
+      <title>Names and References</title>
+
+      <para>The name of a schema object is an
+      <literal>&lt;identifier&gt;</literal>. The name belongs to the
+      name-space for the particular kind of schema object. The name is unique
+      within its name-space. For example, each schema has a separate
+      name-space for TRIGGER objects.</para>
+
+      <para>In addition to the name-spaces in the schema. Each table has a
+      name-space for the names of its columns.</para>
+
+      <para>Because a schema object is always in a schema and a schema always
+      in a catalog, it is possible, and sometimes necessary, to qualify the
+      name of the schema object that is being referenced in an SQL statement.
+      This is done by forming an &lt;<literal>identifier chain&gt;</literal>.
+      In some contexts, only a simple <literal>&lt;identifier&gt;</literal>
+      can be used and the <literal>&lt;identifier chain&gt;</literal> is
+      prohibited. While in some other contexts, the use of
+      <literal>&lt;identifier chain&gt;</literal> is optional. An identifier
+      chain is formed by qualifying each object with the name of the object
+      that owns its name-space. Therefore a column name is prefixed with a
+      table name, a table name is prefixed with a schema name, and a schema
+      name is prefixed with a catalog name. A fully qualified column name is
+      in the form <literal>&lt;catalog name&gt;.&lt;schema name&gt;.&lt;table
+      name&gt;.&lt;column name&gt;</literal>, likewise, a fully qualified
+      sequence name is in the form <literal>&lt;catalog name&gt;.&lt;schema
+      name&gt;.&lt;sequence name&gt;</literal>.</para>
+
+      <para>HyperSQL extends the SQL standard to allow renaming all database
+      objects. The ALTER ... RENAME TO command has slightly different forms
+      depending on the type of object. If an object is referenced in a VIEW or
+      ROUTINE definition, it is not always possible to rename it.</para>
+    </section>
+
+    <section>
+      <title>Character Sets</title>
+
+      <simpara>A CHARACTER SET is the whole or a subset of the UNICODE
+      character set.</simpara>
+
+      <simpara>A character set name can only be a <literal>&lt;regular
+      identifier&gt;</literal>. There is a separate name-space for character
+      sets.</simpara>
+
+      <simpara>There are several predefined character sets. These character
+      sets belong to INFORMATION_SCHEMA. However, when they are referenced in
+      a statement, no schema prefix can be used in the statement that
+      references them.</simpara>
+
+      <simpara>The following character sets have been specified by the SQL
+      Standard:</simpara>
+
+      <simpara>SQL_TEXT, SQL_IDENTIFIER, SQL_CHARACTER, ASCII_GRAPHIC,
+      GRAPHIC_IRV, ASCII_FULL, ISO8BIT, LATIN1, UTF32, UTF16, UTF8.</simpara>
+
+      <simpara>The ASCII_GRAPHIC is the same as GRAPHIC_IRV and ASCII_FULL is
+      the same as ISO8BIT.</simpara>
+
+      <simpara>Most of the character sets are defined by well-known standards
+      such as UNICODE.</simpara>
+
+      <simpara>The SQL_CHARACTER consists of ASCII letters, digits and the
+      symbols used in the SQL language. The SQL_TEXT, SQL_IDENTIFIER are
+      implementation defined. HyperSQL defines SQL_TEXT as the UNICODE
+      character set and SQL_IDENTIFIER as the UNICODE character set minus the
+      SQL language special characters.</simpara>
+
+      <simpara>The character repertoire of HyperSQL is the UTF16 character
+      set, which covers all possible character sets. If a predefined character
+      set is specified for a table column, then any string stored in the
+      column must contain only characters from the specified character
+      set.</simpara>
+
+      <simpara>Early releases of HyperSQL version 2.0 may not enforce the
+      CHARACTER SET that is specified for a column and may accept any
+      character string.</simpara>
+    </section>
+
+    <section>
+      <title>Collations</title>
+
+      <simpara>A COLLATION is the method used for ordering character strings
+      in ordered sets and to determine equivalence of two character
+      strings.</simpara>
+
+      <simpara>There are several predefined collations. These collations
+      belong to INFORMATION_SCHEMA. However, when they are referenced in a
+      statement, no schema prefix can be used in the statement that references
+      them.</simpara>
+
+      <simpara>There is a separate name-space for collations..</simpara>
+
+      <simpara>Collations for a large number of languages are supported by
+      HyperSQL.</simpara>
+
+      <simpara>Early releases of HyperSQL version 2.0 only support a single
+      collation for the whole database.</simpara>
+    </section>
+
+    <section>
+      <title>Distinct Types</title>
+
+      <simpara>A distinct, user-defined TYPE is simply based on a built-in
+      type. A distinct TYPE is used in table definitions and in CAST
+      statements.</simpara>
+
+      <simpara>Distinct types share a name-space with domains.</simpara>
+    </section>
+
+    <section>
+      <title>Domains</title>
+
+      <simpara>A DOMAIN is a user-defined type, simply based on a built-in
+      type. A DOMAIN can have constraints that limit the values that the
+      DOMAIN can represent. A DOMAIN can be used in table definitions and in
+      CAST statements.</simpara>
+
+      <simpara>Distinct types share a name-space with domains.</simpara>
+    </section>
+
+    <section>
+      <title>Number Sequences</title>
+
+      <simpara>A SEQUENCE object produces INTEGER values in sequence. The
+      SEQUENCE can be referenced in special contexts only within certain SQL
+      statements. For each row where the object is referenced, its value is
+      incremented.</simpara>
+
+      <simpara>There is a separate name-space for SEQUENCE objects.</simpara>
+
+      <simpara>IDENTITY columns are columns of tables which have an internal,
+      unnamed SEQUENCE object.</simpara>
+
+      <simpara>SEQUENCE objects and IDENTITY columns are supported fully
+      according to the latest SQL 2008 Standard syntax.</simpara>
+
+      <simpara><emphasis role="bold">Sequences</emphasis></simpara>
+
+      <para>The SQL:2008 syntax and usage is different from what is supported
+      by many existing database engines. Sequences are created with the
+      <literal>CREATE SEQUENCE</literal> command and their current value can
+      be modified at any time with <literal>ALTER SEQUENCE</literal>. The next
+      value for a sequence is retrieved with the <literal>NEXT VALUE FOR
+      &lt;name&gt;</literal> expression. This expression can be used for
+      inserting and updating table rows.</para>
+
+      <example>
+        <title>inserting the next sequence value into a table row</title>
+
+        <programlisting>INSERT INTO mytable VALUES 2, 'John', NEXT VALUE FOR mysequence;</programlisting>
+      </example>
+
+      <para>You can also use it in select statements. For example, if you want
+      to number the returned rows of a SELECT in sequential order, you can
+      use:</para>
+
+      <example>
+        <title>numbering returned rows of a SELECT in sequential order</title>
+
+        <programlisting>SELECT NEXT VALUE FOR mysequence, col1, col2 FROM mytable WHERE ...</programlisting>
+      </example>
+
+      <para>In version 2.0, the semantics of sequences is exactly as defined
+      by SQL:2008. If you use the same sequence twice in the same row in an
+      INSERT statement, you will get the same value as required by the
+      Standard.</para>
+
+      <para>The correct way to use a sequence value is the NEXT VALUE FOR
+      expression. You can query the SEQUENCES table for the next value that
+      will be returned from any of the defined sequences. The SEQUENCE_NAME
+      column contains the name and the NEXT_VALUE column contains the next
+      value to be returned. Note that this is only for getting information and
+      you should not use the sequence value.</para>
+
+      <simpara><emphasis role="bold">Identity Auto-Increment
+      Columns</emphasis></simpara>
+
+      <para>Each table can contain a single auto-increment column, known as
+      the IDENTITY column. An IDENTITY column is a SMALLINT, INTEGER, BIGINT,
+      DECIMAL or NUMERIC column with its value generated by a sequence
+      generator.</para>
+
+      <para>In HyperSQL 2.0, an IDENTITY column is not by default treated as
+      the primary key for the table (as a result, multi-column primary keys
+      are possible with an IDENTITY column present).</para>
+
+      <para>The SQL standard syntax is used, which allows the initial value
+      and other options to be specified.<programlisting>&lt;colname&gt; [ INTEGER | BIGINT | DECIMAL | NUMERIC ] GENERATED { BY DEFAULT | ALWAYS} AS IDENTITY [( &lt;options&gt; )] [PRIMARY KEY]</programlisting></para>
+
+      <para>When you add a new row to such a table using an <literal>INSERT
+      INTO &lt;tablename&gt; ... </literal>statement, you can use the DEFAULT
+      keyword for the IDENTITY column, which results in an auto-generated
+      value for the column. The <literal>IDENTITY() </literal>function returns
+      the last value inserted into any IDENTITY column by this session. Each
+      session manages this function call separately and is not affected by
+      inserts in other sessions. Use <literal>CALL IDENTITY() </literal>as an
+      SQL statement to retrieve this value. If you want to use the value for a
+      field in a child table, you can use <literal>INSERT INTO
+      &lt;childtable&gt; VALUES (...,IDENTITY(),...);</literal>. Both types of
+      call to<literal> IDENTITY()</literal> must be made before any additional
+      update or insert statements are issued by the session.</para>
+
+      <para>The last inserted IDENTITY value can also be retrieved via JDBC,
+      by specifying the Statement or PreparedStatement object to return the
+      generated value.</para>
+
+      <para>The next IDENTITY value to be used can be changed with following
+      statement. Note that this statement is not used in normal operation and
+      is only for special purposes: <programlisting>ALTER TABLE ALTER COLUMN &lt;column name&gt; RESTART WITH &lt;new value&gt;;</programlisting>For
+      backward compatibility, support has been retained for <literal>CREATE
+      TABLE &lt;tablename&gt;(&lt;colname&gt; IDENTITY, ...)</literal> as a
+      shortcut which defines the column both as an IDENTITY column and a
+      PRIMARY KEY column. Also, for backward compatibility, it is possible to
+      use NULL as the value of an IDENTITY column in an INSERT statement and
+      the value will be generated automatically. You should avoid these
+      compatibility features as they may be removed from future versions of
+      HyperSQL.</para>
+
+      <para>In the following example, the identity value for the first INSERT
+      statement is generated automatically using the DEFAULT keyword. The
+      second INSERT statement uses a call to the IDENTITY() function to
+      populate a row in the child table with the generated identity
+      value.</para>
+
+      <informalexample>
+        <programlisting>CREATE TABLE star (id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 
+   firstname VARCHAR(20),
+   lastname VARCHAR(20))
+CREATE TABLE movies (starid INTEGER, movieid INTEGER PRIMARY KEY, title VARCHAR(40)) 
+INSERT INTO star (id, firstname, lastname) VALUES (DEFAULT, 'Felix', 'the Cat')
+INSERT INTO movies (starid, movieid, title) VALUES (IDENTITY(), 10, 'Felix in Hollywood')
+</programlisting>
+      </informalexample>
+    </section>
+
+    <section>
+      <title>Tables</title>
+
+      <simpara>In the SQL environment, tables are the most essential
+      components, as they hold all persistent data.</simpara>
+
+      <simpara>If TABLE is considered as metadata (i.e. without its actual
+      data) it is called a <emphasis>relation</emphasis> in relational theory.
+      It has one or more columns, with each column having a distinct name and
+      a data type. A table usually has one or more constraints which limit the
+      values that can potentially be stored in the TABLE. These constraints
+      are discussed in the next section.</simpara>
+
+      <simpara>A single column of the table can be defined as IDENTITY. The
+      values stored in this column are auto-generated and are based on an
+      (unnamed) identity sequence.</simpara>
+    </section>
+
+    <section>
+      <title>Views</title>
+
+      <simpara>A VIEW is similar to a TABLE but it does not permanently
+      contain rows of data. A view is defined as a QUERY EXPRESSION, which is
+      often a SELECT statement that references views and tables, but it can
+      also consist of a TABLE CONSTRUCTOR that does not reference any tables
+      or views.</simpara>
+
+      <simpara>A view has many uses:</simpara>
+
+      <itemizedlist>
+        <listitem>
+          <para>Hide the structure and column names of tables. The view can
+          represent one or more tables or views as a separate table. This can
+          include aggregate data, such as sums and averages, from other
+          tables.</para>
+        </listitem>
+
+        <listitem>
+          <para>Allow access to specific rows in a table. For example, allow
+          access to records that were added since a given date, while hiding
+          older records.</para>
+        </listitem>
+
+        <listitem>
+          <para>Allow access to specific columns. For example allow access to
+          columns that contain non-confidential information. Note that this
+          can also be achieved with the GRANT SELECT statement, using
+          column-level privileges</para>
+        </listitem>
+      </itemizedlist>
+
+      <simpara>A VIEW that returns the columns of a single ordinary TABLE may
+      be <glossterm>updatable</glossterm>. Some
+      <glossterm>updatable</glossterm> views are
+      <glossterm>insertable-into</glossterm>. When rows of an updatable view
+      are updated, or new rows are inserted, these changes are reflected in
+      the base table. A VIEW definition may specify that the inserted or
+      updated rows conform to the search condition of the view. This is done
+      with the CHECK OPTION clause.</simpara>
+
+      <simpara>Views share a name-space with tables.</simpara>
+    </section>
+
+    <section>
+      <title>Constraints</title>
+
+      <simpara>A CONSTRAINT is a child schema object and can belong to a
+      DOMAIN or a TABLE. CONSTRAINT objects can be defined without specifying
+      a name. In this case the system generates a name for the new object
+      beginning with "SYS_".</simpara>
+
+      <!-- For some reason, without the quotes, the _ and . do not appear in
+      the HTML output.  Can remove the quotes if this issue is taken care of
+      or disappears.  -blaine -->
+
+      <simpara>In a DOMAIN, CHECK constraints can be defined that limits the
+      value represented by the DOMAIN. These constraints work exactly like a
+      CHECK constraint on a single column of a table as described
+      below.</simpara>
+
+      <simpara>In a TABLE, a constraint takes three basic forms.</simpara>
+
+      <simpara><emphasis role="bold">CHECK</emphasis></simpara>
+
+      <simpara>A CHECK constraint consists of a <literal>&lt;search
+      condition&gt;</literal> that must not be false (can be unknown) for each
+      row of the table. The <literal>&lt;search condition&gt;</literal> can
+      reference all the columns of the current row, and if it contains a
+      <literal>&lt;subquery&gt;</literal>, other tables and views in the
+      database (excluding its own table).</simpara>
+
+      <simpara><emphasis role="bold">NOT NULL</emphasis></simpara>
+
+      <simpara>A simple form of check constraint is the NOT NULL constraint,
+      which applies to a single column.</simpara>
+
+      <simpara><emphasis role="bold">UNIQUE</emphasis></simpara>
+
+      <simpara>A UNIQUE constraint is based on an equality comparison of
+      values of specific columns (taken together) of one row with the same
+      values from each of the other rows. The result of the comparison must
+      never be true (can be false or unknown). If a row of the table has NULL
+      in any of the columns of the constraint, it conforms to the constraint.
+      A unique constraint on multiple columns (c1, c2, c3, ..) means that in
+      no two rows, the sets of values for the columns can be equal unless at
+      lease one of them is NULL. Each single column taken by itself can have
+      repeat values in different rows. The following example satisfies a
+      UNIQUE constraint on the two columns</simpara>
+
+      <example>
+        <title>Column values which satisfy a 2-column UNIQUE
+        constraint</title>
+
+        <simplelist columns="2" type="horiz">
+          <member>1,</member>
+
+          <member>2</member>
+
+          <member>2,</member>
+
+          <member>1</member>
+
+          <member>2,</member>
+
+          <member>2</member>
+
+          <member>NULL,</member>
+
+          <member>1</member>
+
+          <member>NULL,</member>
+
+          <member>1</member>
+
+          <member>1,</member>
+
+          <member>NULL</member>
+
+          <member>NULL,</member>
+
+          <member>NULL</member>
+
+          <member>NULL,</member>
+
+          <member>NULL</member>
+        </simplelist>
+      </example>
+
+      <simpara><emphasis role="bold">PRIMARY KEY</emphasis></simpara>
+
+      <simpara>A PRIMARY KEY constraint is equivalent to a UNIQUE constraint
+      on one or more NOT NULL columns. Only one PRIMARY KEY can be defined in
+      each table.</simpara>
+
+      <simpara><emphasis role="bold">FOREIGN KEY</emphasis></simpara>
+
+      <simpara>A FOREIGN key constraint is based on an equality comparison
+      between values of specific columns (taken together) of each row with the
+      values of the columns of a UNIQUE constraint on another table or the
+      same table. The result of the comparison must never be false (can be
+      unknown). A special form of FOREIGN KEY constraint, based on its CHECK
+      clause, allows the result to be unknown only if the values for all
+      columns are NULL. A FOREIGN key can be declared only if a UNIQUE
+      constraint exists on the referenced columns.</simpara>
+
+      <simpara>Constraints share a name space with assertions.</simpara>
+    </section>
+
+    <section>
+      <title>Assertions</title>
+
+      <para>An ASSERTION is a top-level schema objects. It consists of a
+      <literal>&lt;search condition&gt;</literal> that must not be false (can
+      be unknown).</para>
+
+      <para>Assertions share a name-space with constraints</para>
+    </section>
+
+    <section>
+      <title>Triggers</title>
+
+      <simpara>A TRIGGER is a child schema object that always belongs to a
+      TABLE or a VIEW.</simpara>
+
+      <simpara>Each time a DELETE, UPDATE or INSERT is performed on the table
+      or view, additional actions are taken by the triggers that have been
+      declared on the table or view.</simpara>
+
+      <simpara>Triggers are discussed in detail in chapter <link
+      endterm="triggers-title" os="" xlink:href="#triggers-chapt"></link>
+      .</simpara>
+    </section>
+
+    <section>
+      <title>Routines</title>
+
+      <simpara>Routines are user-defined functions or procedures. The names
+      and usage of functions and procedures are different. FUNCTION is a
+      routine that can be referenced in many types of statements. PROCEDURE is
+      a routine that can be referenced only in a CALL statement.</simpara>
+
+      <simpara>There is a separate name-space for routines.</simpara>
+
+      <simpara>Because of the possibility of overloading, each routine can
+      have more than one name. The name of the routine is the same for all
+      overloaded variants, but each variant has a <glossterm>specific
+      name</glossterm>, different from all other routine names and specific
+      names in the schema. The <glossterm>specific name</glossterm> can be
+      specified in the routine definition statement. Otherwise it is assigned
+      by the engine. The specific name is used only for schema manipulation
+      statements, which need to reference a specific variant of the routine.
+      For example, if a routine has two signatures, each signature has its own
+      <glossterm>specific name</glossterm>. This allows the user to drop one
+      of the signatures while keeping the other.</simpara>
+
+      <simpara>Routines are discussed in detail in chapter <link
+      endterm="sqlroutines-title" os=""
+      xlink:href="#sqlroutines-chapt"></link> .</simpara>
+    </section>
+
+    <section>
+      <title>Indexes</title>
+
+      <para>Indexes are an implementation-defined extension to the SQL
+      Standard. HyperSQL has a dedicated name-space for indexes in each
+      schema.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Statements for Schema Definition and Manipulation</title>
+
+    <simpara>Schemas and schema objects can be created, modified and dropped.
+    The SQL Standard defines a range of statements for this purpose. HyperSQL
+    supports many additional statements, especially for changing the
+    properties of existing schema objects.</simpara>
+
+    <section>
+      <title>Common Elements and Statements</title>
+
+      <simpara>These elements and statements are used for different types of
+      object. They are described here, before the statements that can use
+      them.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>identifier definition</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">identifier</emphasis></simpara>
+
+      <simpara><emphasis>definition of identifier</emphasis></simpara>
+
+      <simpara><literal>&lt;identifier&gt; ::= &lt;regular identifier&gt; |
+      &lt;delimited identifier&gt; | &lt;SQL language identifier&gt;
+      </literal></simpara>
+
+      <simpara><literal>&lt;delimited identifier&gt; ::= &lt;double quote&gt;
+      &lt;character sequence&gt; &lt;double quote&gt;</literal></simpara>
+
+      <simpara><literal>&lt;regular identifier&gt; ::= &lt;special character
+      sequence&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL language identifier&gt; ::= &lt;special
+      character sequence&gt;</literal></simpara>
+
+      <simpara>A <literal>&lt;delimited identifier&gt;</literal> is a sequence
+      of characters enclosed with double-quote symbols. All characters are
+      allowed in the character sequence.</simpara>
+
+      <simpara>A <literal>&lt;regular identifier&gt;</literal> is a special
+      sequence of characters. It consists of letters, digits and the
+      underscore characters. It must begin with a letter.</simpara>
+
+      <simpara>A <literal>&lt;SQL language identifier&gt;</literal> is similar
+      to <literal>&lt;regular identifier&gt;</literal> but the letters can
+      range only from A-Z in the ASCII character set. This type of identifier
+      is used for names of CHARACTER SET objects.</simpara>
+
+      <simpara>If the character sequence of a delimited identifier is the same
+      as an undelimited identifier, it represents the same identifier. For
+      example "JOHN" is the same identifier as JOHN. In a <literal>&lt;regular
+      identifier&gt;</literal> the case-normal form is considered for
+      comparison. This form consists of the upper-case of equivalent of all
+      the letters.</simpara>
+
+      <simpara>The character sequence length of all identifiers must be
+      between 1 and 128 characters.</simpara>
+
+      <simpara>A reserved word is one that is used by the SQL Standard for
+      special purposes. It is similar to a <literal>&lt;regular
+      identifier&gt;</literal> but it cannot be used as an identifier for user
+      objects. If a reserved word is enclosed in double quote characters, it
+      becomes a quoted identifier and can be used for database
+      objects.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CASCADE or RESTRICT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CASCADE or RESTRICT</emphasis></simpara>
+
+      <simpara><emphasis>drop behavior</emphasis></simpara>
+
+      <simpara><literal>&lt;drop behavior&gt; ::= CASCADE |
+      RESTRICT</literal></simpara>
+
+      <simpara>The <literal>&lt;drop behavior&gt;</literal> is a required
+      element of statements that drop a SCHEMA or a schema object. If
+      <literal>&lt;drop behavior&gt;</literal> is not specified then
+      <literal>RESTRICT</literal> is implicit. It determines the effect of the
+      statement if there are other objects in the catalog that reference the
+      SCHEMA or the schema object. If RESTRICT is specified, the statement
+      fails if there are referencing objects. If CASCADE is specified, all the
+      referencing objects are modified or dropped with cascading effect.
+      Whether a referencing object is modified or dropped, depends on the kind
+      of schema object that is dropped.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>IF EXISTS</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">IF EXISTS</emphasis></simpara>
+
+      <simpara><emphasis>drop condition (HyperSQL)</emphasis></simpara>
+
+      <simpara><literal>&lt;if exists clause&gt; ::= IF
+      EXISTS</literal></simpara>
+
+      <simpara>This clause is not part of the SQL standard and is a HyperSQL
+      extension to some commands that drop objects (schemas, tables, views,
+      sequences and indexes). If it is specified, then the statement does not
+      return an error if the drop statement is issued on a non-existent
+      object.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SPECIFIC</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SPECIFIC</emphasis></simpara>
+
+      <simpara><emphasis>specific routine designator</emphasis></simpara>
+
+      <simpara><literal>&lt;specific routine designator&gt; ::= SPECIFIC
+      &lt;routine type&gt; &lt;specific name&gt; </literal></simpara>
+
+      <simpara><literal>&lt;routine type&gt; ::= ROUTINE | FUNCTION |
+      PROCEDURE</literal></simpara>
+
+      <simpara>This clause is used in statements that need to specify one of
+      the multiple versions of an overloaded routine. The
+      <literal>&lt;specific name&gt;</literal> is the one specified in the
+      <literal>&lt;routine definition&gt;</literal> statement.</simpara>
+    </section>
+
+    <section>
+      <title>Renaming Objects</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>RENAME</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">RENAME</emphasis></simpara>
+
+      <simpara><emphasis>rename statement (HyperSQL)</emphasis></simpara>
+
+      <simpara><literal>&lt;rename statement&gt; ::= ALTER &lt;object type&gt;
+      &lt;name&gt; RENAME TO &lt;new name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;object type&gt; ::= CATALOG | SCHEMA | DOMAIN |
+      TYPE | TABLE | CONSTRAINT | INDEX | ROUTINE | SPECIFIC
+      ROUTINE</literal></simpara>
+
+      <simpara><literal>&lt;column rename statement&gt; ::= ALTER TABLE
+      &lt;table name&gt; ALTER COLUMN &lt;name&gt; RENAME TO &lt;new
+      name&gt;</literal></simpara>
+
+      <simpara>This statement is used to rename an existing object. It is not
+      part of the SQL Standard. The specified <literal>&lt;name&gt;</literal>
+      is the existing name, which can be qualified with a schema name, while
+      the <literal>&lt;new name&gt;</literal> is the new name for the
+      object.</simpara>
+    </section>
+
+    <section>
+      <title>Commenting Objects</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>COMMENT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">COMMENT</emphasis></simpara>
+
+      <simpara><emphasis>comment statement (HyperSQL)</emphasis></simpara>
+
+      <simpara><literal>&lt;comment statement&gt; ::= COMMENT ON { TABLE |
+      COLUMN | ROUTINE } &lt;name&gt; IS &lt;character string
+      literal&gt;</literal></simpara>
+
+      <simpara>Adds a comment to the object metadata, which can later be read
+      from an INFORMATION_SCHEMA view. This command is not part of the SQL
+      Standard. The strange syntax is due to compatibility with other database
+      engines that support the statement.<literal> The &lt;name&gt;</literal>
+      is the name of a table, view, column or routine. The name of the column
+      consists of dot-separated<literal> &lt;table name&gt; . &lt;column
+      name&gt;</literal>. The name of the table, view or routine can be a
+      simple name. All names can be qualified with a schema name. If there is
+      alread a comment on the object, the new comment will replace
+      it.</simpara>
+
+      <para>The comments appear in the results returned by JDBC
+      DatabaseMetaData methods, getTables() and getColumns(). The
+      INFORMATION_SCHEMA.SYSTEM_COMMENTS view contains the comments. You can
+      query this view using the schema, table, and column names to retreive
+      the comments.</para>
+    </section>
+
+    <section>
+      <title>Schema Creation</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE SCHEMA</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE SCHEMA</emphasis></simpara>
+
+      <simpara><emphasis>schema definition</emphasis></simpara>
+
+      <para>The CREATE_SCHEMA or DBA role is required in order to create a
+      schema. A schema can be created with or without schema objects. Schema
+      objects can always be added after creating the schema, or existing ones
+      can be dropped. Within the <literal>&lt;schema definition&gt;</literal>
+      statement, all schema object creation takes place inside the newly
+      created schema. Therefore, if a schema name is specified for the schema
+      objects, the name must match that of the new schema. In addition to
+      statements for creating schema objects, the statement can include
+      instances of <literal>&lt;grant statement&gt;</literal> and
+      <literal>&lt;role definition&gt;</literal>. This is a curious aspect of
+      the SQL standard, as these elements do not really belong to schema
+      creation.</para>
+
+      <simpara><literal>&lt;schema definition&gt; ::= CREATE SCHEMA &lt;schema
+      name clause&gt; [ &lt;schema character set specification&gt; ] [
+      &lt;schema element&gt;... ]</literal></simpara>
+
+      <simpara><literal>&lt;schema name clause&gt; ::= &lt;schema name&gt; |
+      AUTHORIZATION &lt;authorization identifier&gt; | &lt;schema name&gt;
+      AUTHORIZATION &lt;authorization identifier&gt;</literal></simpara>
+
+      <para>If the name of the schema is specified simply as
+      <literal>&lt;schema name&gt;</literal>, then the AUTHORIZATION is the
+      current user. Otherwise, the specified <literal>&lt;authorization
+      identifier&gt;</literal> is used as the AUTHORIZATION for the schema. If
+      <literal>&lt;schema name&gt;</literal> is omitted, then the name of the
+      schema is the same as the specified <literal>&lt;authorization
+      identifier&gt;</literal>.</para>
+
+      <simpara><literal>&lt;schema element&gt; ::= &lt;table definition&gt; |
+      &lt;view definition&gt; | &lt;domain definition&gt; | &lt;character set
+      definition&gt; | &lt;collation definition&gt; | &lt;transliteration
+      definition&gt; | &lt;assertion definition&gt; | &lt;trigger
+      definition&gt; | &lt;user-defined type definition&gt; | &lt;user-defined
+      cast definition&gt; | &lt;user-defined ordering definition&gt; |
+      &lt;transform definition&gt; | &lt;schema routine&gt; | &lt;sequence
+      generator definition&gt; | &lt;grant statement&gt; | &lt;role
+      definition&gt;</literal></simpara>
+
+      <simpara>An example of the command is given below. Note that a single
+      semicolon appears at the end, there should be no semicolon between the
+      statements:</simpara>
+
+      <programlisting>    CREATE SCHEMA ACCOUNTS AUTHORIZATION DBA
+        CREATE TABLE AB(A INTEGER, ...)
+        CREATE TABLE CD(C CHAR(10), ...)
+        CREATE VIEW VI AS SELECT ...
+        GRANT SELECT ON AB TO PUBLIC
+        GRANT SELECT ON CD TO JOE;
+</programlisting>
+
+      <simpara>It is not really necessary to create a schema and all its
+      objects as one command. The schema can be created first, and its objects
+      can be created one by one.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP SCHEMA</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP SCHEMA</emphasis></simpara>
+
+      <simpara><emphasis>drop schema statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop schema statement&gt; ::= DROP SCHEMA [ IF
+      EXISTS ] &lt;schema name&gt; [ IF EXISTS ] &lt;drop behavior&gt;
+      </literal></simpara>
+
+      <simpara>This command destroys an existing schema. If <literal>&lt;drop
+      behavior&gt;</literal> is <literal>RESTRICT</literal>, the schema must
+      be empty, otherwise an error is raised. If <literal>CASCADE</literal> is
+      specified, then all the objects contained in the schema are destroyed
+      with a CASCADE option.</simpara>
+    </section>
+
+    <section>
+      <title>Table Creation and Manipulation</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE TABLE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE TABLE</emphasis></simpara>
+
+      <simpara><emphasis>table definition</emphasis></simpara>
+
+      <simpara><literal>&lt;table definition&gt; ::= CREATE [ { &lt;table
+      scope&gt; | &lt;table type&gt; } ] TABLE &lt;table name&gt; &lt;table
+      contents source&gt; [ ON COMMIT { PRESERVE | DELETE } ROWS
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;table scope&gt; ::= { GLOBAL | LOCAL }
+      TEMPORARY</literal></simpara>
+
+      <simpara><literal>&lt;table type&gt; :: = MEMORY |
+      CACHED</literal></simpara>
+
+      <simpara><literal>&lt;table contents source&gt; ::= &lt;table element
+      list&gt; | &lt;as subquery clause&gt;</literal></simpara>
+
+      <simpara><literal>&lt;table element list&gt; ::= &lt;left paren&gt;
+      &lt;table element&gt; [ { &lt;comma&gt; &lt;table element&gt; }... ]
+      &lt;right paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;table element&gt; ::= &lt;column definition&gt; |
+      &lt;table constraint definition&gt; | &lt;like
+      clause&gt;</literal></simpara>
+
+      <simpara><emphasis>like clause</emphasis></simpara>
+
+      <simpara>A <literal>&lt;like clause&gt;</literal> copies all column
+      definitions from another table into the newly created table. Its three
+      options indicate if the <literal>&lt;default clause&gt;</literal>,
+      <literal>&lt;identity column specification&gt;</literal> and
+      <literal>&lt;generation clause&gt;</literal> associated with the column
+      definitions are copied or not. If an option is not specified, it
+      defaults to <literal>EXCLUDING</literal>. The <literal>&lt;generation
+      clause&gt;</literal> refers to columns that are generated by an
+      expression but not to identity columns. All NOT NULL constraints are
+      copied with the original columns, other constraints are not. The
+      <literal>&lt;like clause&gt;</literal> can be used multiple times,
+      allowing the new table to have copies of the column definitions of one
+      or more other tables.</simpara>
+
+      <informalexample>
+        <programlisting>CREATE TABLE t (id INTEGER PRIMARY KEY, LIKE atable INCLUDING DEFAULTS EXCLUDING IDENTITY)
+</programlisting>
+      </informalexample>
+
+      <simpara><literal>&lt;like clause&gt; ::= LIKE &lt;table name&gt; [
+      &lt;like options&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;like options&gt; ::= &lt;like
+      option&gt;...</literal></simpara>
+
+      <simpara><literal>&lt;like option&gt; ::= &lt;identity option&gt; |
+      &lt;column default option&gt; | &lt;generation
+      option&gt;</literal></simpara>
+
+      <simpara><literal>&lt;identity option&gt; ::= INCLUDING IDENTITY |
+      EXCLUDING IDENTITY</literal></simpara>
+
+      <simpara><literal>&lt;column default option&gt; ::= INCLUDING DEFAULTS |
+      EXCLUDING DEFAULTS</literal></simpara>
+
+      <simpara><literal>&lt;generation option&gt; ::= INCLUDING GENERATED |
+      EXCLUDING GENERATED</literal></simpara>
+
+      <simpara><emphasis>as subquery clause</emphasis></simpara>
+
+      <simpara><literal>&lt;as subquery clause&gt; ::= [ &lt;left paren&gt;
+      &lt;column name list&gt; &lt;right paren&gt; ] AS &lt;table subquery&gt;
+      { WITH NO DATA | WITH DATA }</literal></simpara>
+
+      <simpara>An <literal>&lt;as subquery clause&gt;</literal> used in table
+      definition creates a table based on a <literal>&lt;table
+      subquery&gt;</literal>. This kind of table definition is similar to a
+      view definition. If <literal>WITH DATA</literal> is specified, then the
+      new table will contain the rows of data returned by the
+      <literal>&lt;table subquery&gt;</literal>.</simpara>
+
+      <informalexample>
+        <programlisting>CREATE TABLE t (a, b, c) AS (SELECT * FROM atable) WITH DATA
+</programlisting>
+      </informalexample>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>column definition</primary>
+      </indexterm>
+
+      <simpara><emphasis>column definition</emphasis></simpara>
+
+      <simpara>A column definition consists of a <literal>&lt;column
+      name&gt;</literal> and in most cases a <literal>&lt;data
+      type&gt;</literal> or <literal>&lt;domain name&gt;</literal> as minimum.
+      The other elements of <literal>&lt;column definition&gt;</literal> are
+      optional. Each <literal>&lt;column name&gt;</literal> in a table is
+      unique.</simpara>
+
+      <simpara><literal>&lt;column definition&gt; ::= &lt;column name&gt; [
+      &lt;data type or domain name&gt; ] [ &lt;default clause&gt; |
+      &lt;identity column specification&gt; | &lt;generation clause&gt; ] [
+      &lt;column constraint definition&gt;... ] [ &lt;collate clause&gt;
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;data type or domain name&gt; ::= &lt;data type&gt;
+      | &lt;domain name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;column constraint definition&gt; ::= [
+      &lt;constraint name definition&gt; ] &lt;column constraint&gt; [
+      &lt;constraint characteristics&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;column constraint&gt; ::= NOT NULL | &lt;unique
+      specification&gt; | &lt;references specification&gt; | &lt;check
+      constraint definition&gt;</literal></simpara>
+
+      <simpara><literal>&lt;identity column specification&gt; ::= GENERATED {
+      ALWAYS | BY DEFAULT } AS IDENTITY [ &lt;left paren&gt; &lt;common
+      sequence generator options&gt; &lt;right paren&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;generation clause&gt; ::= GENERATED ALWAYS AS
+      &lt;generation expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;generation expression&gt; ::= &lt;left paren&gt;
+      &lt;value expression&gt; &lt;right paren&gt;</literal></simpara>
+
+      <simpara>The <literal>&lt;identity column specification&gt;</literal>
+      can be specified for only a single column of the table.</simpara>
+
+      <simpara>A <literal>&lt;column constraint definition&gt;</literal> is a
+      shortcut for a <literal>&lt;table constraint definition&gt;</literal>. A
+      constraint that is defined in this way is automatically turned into a
+      table constraint. A name is automatically generated for the constraint
+      and assigned to it.</simpara>
+
+      <simpara>The <literal>&lt;identity column specification&gt;</literal> is
+      used for special columns which represent values based on unnamed
+      sequence generators. It is possible to insert a row into the able
+      without specifying a value for the column. The value is then generated
+      by the sequence generators according to its rules. An identity column
+      may or may not be the primary key. Example below:</simpara>
+
+      <informalexample>
+        <programlisting>CREATE TABLE t (id INTEGER GENERATED ALWAYS AS IDENTITY(START WITH 100), name VARCHAR(20) PRIMARY KEY, )
+</programlisting>
+      </informalexample>
+
+      <simpara>The <literal>&lt;generation clause&gt;</literal> is used for
+      special columns which represent values based on the values held in other
+      columns in the same row. The <literal>&lt;value expression&gt;</literal>
+      must reference only other, non-generated, columns of the table in the
+      same row. Therefore, any function used in the expression may not access
+      SQL-data, and no <literal>&lt;query expression&gt;</literal> is allowed.
+      When <literal>&lt;generation clause&gt;</literal> is used,
+      <literal>&lt;data type&gt;</literal> or <literal>&lt;domain
+      name&gt;</literal> may be omitted.</simpara>
+
+      <simpara>A generated column can be part of a foreign key or unique
+      constraints or a column of an index. This capability is the main reason
+      for using generated columns. A generated column may contain a formula
+      that computes a value based on the values of other columns. Fast
+      searches of the computed value can be performed when an index is
+      declared on the generated column. Or the computed values can be declared
+      to be unique, using a UNIQUE constraint on the table.</simpara>
+
+      <simpara>When a row is inserted into a table, or an existing row is
+      updated, no value except DEFAULT can be specified for a generated
+      column. In the example below, data is inserted into the non-generated
+      columns and the generated column will contain 'Felix the Cat' or 'Pink
+      Panther'.</simpara>
+
+      <informalexample>
+        <programlisting>CREATE TABLE t (id INTEGER PRIMARY KEY, 
+   firstname VARCHAR(20),
+   lastname VARCHAR(20), 
+   fullname VARCHAR(40) GENERATED ALWAYS AS (firstname || ' ' || lastname)) 
+INSERT INTO t (id, firstname, lastname) VALUES (1, 'Felix', 'the Cat')
+INSERT INTO t (id, firstname, lastname, fullname) VALUES (2, 'Pink', 'Panther', DEFAULT)
+</programlisting>
+      </informalexample>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DEFAULT clause</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DEFAULT</emphasis></simpara>
+
+      <simpara><emphasis>default clause</emphasis></simpara>
+
+      <simpara>A default clause can be used if GENERATED is not specified. If
+      a column has a <literal>&lt;default clause&gt;</literal> then it is
+      possible to insert a row into the table without specifying a value for
+      the column.</simpara>
+
+      <simpara><literal>&lt;default clause&gt; ::= DEFAULT &lt;default
+      option&gt;</literal></simpara>
+
+      <simpara><literal>&lt;default option&gt; ::= &lt;literal&gt; |
+      &lt;datetime value function&gt; | USER | CURRENT_USER | CURRENT_ROLE |
+      SESSION_USER | SYSTEM_USER | CURRENT_CATALOG | CURRENT_SCHEMA |
+      CURRENT_PATH | NULL</literal></simpara>
+
+      <simpara>The type of the <literal>&lt;default option&gt;</literal> must
+      match the type of the column.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CONSTRAINT name and characteristics</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CONSTRAINT</emphasis></simpara>
+
+      <simpara><emphasis>constraint name and
+      characteristics</emphasis></simpara>
+
+      <simpara><literal>&lt;constraint name definition&gt; ::= CONSTRAINT
+      &lt;constraint name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;constraint characteristics&gt; ::= &lt;constraint
+      check time&gt; [ [ NOT ] DEFERRABLE [ &lt;constraint check time&gt; ]
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;constraint check time&gt; ::= INITIALLY DEFERRED |
+      INITIALLY IMMEDIATE</literal></simpara>
+
+      <simpara>Specify the name of a constraint and its characteristics. By
+      default the constraint is <literal>NOT DEFERRABLE</literal> and
+      <literal>INITIALLY IMMEDIATE</literal>. This means the constraint is
+      enforced as soon as a data change statement is executed. If
+      <literal>INITIALLY DEFERRED</literal> is specified, then the constraint
+      is enforced when the session commits. The characteristics must be
+      compatible. The constraint check time can be changed temporarily for an
+      SQL session. HyperSQL does not support deferring constraint enforcement.
+      This feature of the SQL Standard has been criticised because it allows a
+      session to read uncommitted data that violates database integrity
+      constraints but has not yet been checked.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CONSTRAINT (table constraint)</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CONSTRAINT</emphasis></simpara>
+
+      <simpara><emphasis>table constraint definition</emphasis></simpara>
+
+      <simpara><literal>&lt;table constraint definition&gt; ::= [
+      &lt;constraint name definition&gt; ] &lt;table constraint&gt; [
+      &lt;constraint characteristics&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;table constraint&gt; ::= &lt;unique constraint
+      definition&gt; | &lt;referential constraint definition&gt; | &lt;check
+      constraint definition&gt;</literal></simpara>
+
+      <simpara>Three kinds of constraint can be defined on a table: UNIQUE
+      (including PRIMARY KEY), FOREIGN KEY and CHECK. Each kind has its own
+      rules to limit the values that can be specified for different columns in
+      each row of the table.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>UNIQUE constraint</primary>
+      </indexterm>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>PRIMARY KEY constraint</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">UNIQUE</emphasis></simpara>
+
+      <simpara><emphasis>unique constraint definition</emphasis></simpara>
+
+      <simpara><literal>&lt;unique constraint definition&gt; ::= &lt;unique
+      specification&gt; &lt;left paren&gt; &lt;unique column list&gt;
+      &lt;right paren&gt; | UNIQUE ( VALUE )</literal></simpara>
+
+      <simpara><literal>&lt;unique specification&gt; ::= UNIQUE | PRIMARY
+      KEY</literal></simpara>
+
+      <simpara><literal>&lt;unique column list&gt; ::= &lt;column name
+      list&gt;</literal></simpara>
+
+      <simpara>A unique constraint is specified on a single column or on
+      multiple columns. On each set of columns taken together, only one UNIQUE
+      constraint can be specified. Each column of a PRIMARY KEY constraint has
+      an implicit NOT NULL constraint.</simpara>
+
+      <simpara>If <literal>UNIQUE( VALUE )</literal> is specified, the
+      constraint created on all columns of the table.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>FOREIGN KEY constraint</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">FOREIGN KEY</emphasis></simpara>
+
+      <simpara><emphasis>referential constraint
+      definition</emphasis></simpara>
+
+      <simpara><literal>&lt;referential constraint definition&gt; ::= FOREIGN
+      KEY &lt;left paren&gt; &lt;referencing columns&gt; &lt;right paren&gt;
+      &lt;references specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;references specification&gt; ::= REFERENCES
+      &lt;referenced table and columns&gt; [ MATCH &lt;match type&gt; ] [
+      &lt;referential triggered action&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;match type&gt; ::= FULL | PARTIAL |
+      SIMPLE</literal></simpara>
+
+      <simpara><literal>&lt;referencing columns&gt; ::= &lt;reference column
+      list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;referenced table and columns&gt; ::= &lt;table
+      name&gt; [ &lt;left paren&gt; &lt;reference column list&gt; &lt;right
+      paren&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;reference column list&gt; ::= &lt;column name
+      list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;referential triggered action&gt; ::= &lt;update
+      rule&gt; [ &lt;delete rule&gt; ] | &lt;delete rule&gt; [ &lt;update
+      rule&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;update rule&gt; ::= ON UPDATE &lt;referential
+      action&gt;</literal></simpara>
+
+      <simpara><literal>&lt;delete rule&gt; ::= ON DELETE &lt;referential
+      action&gt;</literal></simpara>
+
+      <simpara><literal>&lt;referential action&gt; ::= CASCADE | SET NULL |
+      SET DEFAULT | RESTRICT | NO ACTION</literal></simpara>
+
+      <simpara>A referential constraint allows links to be established between
+      the rows of two tables. The specified list of <literal>&lt;referencing
+      columns&gt;</literal> corresponds one by one to the columns of the
+      specified list of <literal>&lt;referenced columns&gt;</literal> in
+      another table (or sometimes in the same table). For each row in the
+      table, a row must exist in the referenced table with equivalent values
+      in the two column lists. There must exist a single unique constraint in
+      the referenced table on all the <literal>&lt;referenced
+      columns&gt;</literal>.</simpara>
+
+      <simpara>The <literal>[ MATCH match type ]</literal> clause is optional
+      and has an effect only on multi-column foreign keys and only on rows
+      containing at least a NULL in one of the <literal>&lt;referencing
+      columns&gt;</literal>. If the clause is not specified, MATCH SIMPLE is
+      the default. If <literal>MATCH SIMPLE</literal> is specified, then any
+      NULL means the row can exist (without a corresponding row in the
+      referenced table). If <literal>MATCH FULL</literal> is specified then
+      either all the column values must be NULL or none of them.
+      <literal>MATCH PARTIAL</literal> allows any NULL but the non NULL values
+      must match those of a row in the referenced table. HyperSQL does not
+      support <literal>MATCH PARTIAL</literal>.</simpara>
+
+      <simpara>Referential actions are specified with ON UPDATE and ON DELETE
+      clauses. These actions take place when a row in the referenced table
+      (the parent table) has referencing rows in the referencing table and it
+      is deleted or modified with any SQL statement. The default is NO ACTION.
+      This means the SQL statement that causes the DELETE or UPDATE is
+      terminated with an exception. The RESTRICT option is similar and works
+      exactly the same without deferrable constraints (which are not allowed
+      by HyperSQL). The other three options, CASCADE, SET NULL and SET DEFAULT
+      all allow the DELETE or UPDATE statement to complete. With DELETE
+      statements the CASCADE option results in the referencing rows to be
+      deleted. With UPDATE statements, the changes to the values of the
+      referenced columns are copied to the referencing rows. With both DELETE
+      or UPDATE statement, the SET NULL option results in the columns of the
+      referencing rows to be set to NULL. Similarly, the SET DEFAULT option
+      results in the columns of the referencing rows to be set to their
+      default values.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CHECK constraint</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CHECK</emphasis></simpara>
+
+      <simpara><emphasis>check constraint definition</emphasis></simpara>
+
+      <simpara><literal>&lt;check constraint definition&gt; ::= CHECK &lt;left
+      paren&gt; &lt;search condition&gt; &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara>A CHECK constraint can exist for a TABLE or for a DOMAIN. The
+      <literal>&lt;search condition&gt;</literal> evaluates to an SQL BOOLEAN
+      value for each row of the table. Within the <literal>&lt;search
+      condition&gt;</literal> all columns of the table row can be referenced.
+      For all rows of the table, the <literal>&lt;search
+      condition&gt;</literal> evaluates to TRUE or UNKNOWN. When a new row is
+      inserted, or an existing row is updated, the <literal>&lt;search
+      condition&gt;</literal> is evaluated and if it is FALSE, the insert or
+      update fails.</simpara>
+
+      <simpara>A CHECK constraint for a DOMAIN is similar. In its
+      <literal>&lt;search condition&gt;</literal>, the term VALUE is used to
+      represents the value to which the DOMAIN applies.</simpara>
+
+      <informalexample>
+        <programlisting>CREATE TABLE t (a VARCHAR(20) CHECK (a IS NOT NULL AND CHARACTER_LENGTH(a) &gt; 2))
+</programlisting>
+      </informalexample>
+
+      <simpara>The search condition of a CHECK constraint cannot contain any
+      function that is not deterministic. A check constraint is a data
+      integrity constraint, therefore it must hold with respect to the rest of
+      the data in the database. It cannot use values that are temporal or
+      ephemeral. For example CURRENT_USER is a function that returns different
+      values depending on who is using the database, or CURRENT_DATE changes
+      day-to-day. Some temporal expressions are retrospectively deterministic
+      and are allowed in check constraints. For example, (CHECK VALUE &lt;
+      CURRENT_DATE) is valid, because CURRENT_DATE will not move backwards in
+      time, but (CHECK VALUE &gt; CURRENT_DATE) is not acceptable.</simpara>
+
+      <simpara>If you want to enforce the condition that a date value that is
+      inserted into the database belongs to the future (at the time of
+      insertion), or any similar constraint, then use a TRIGGER with the
+      desired condition.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SET TABLE read-write property</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SET TABLE
+      writeability</emphasis></simpara>
+
+      <simpara><emphasis>set table write property
+      (HyperSQL)</emphasis></simpara>
+
+      <simpara><literal>&lt;set table read only statement&gt; ::= SET TABLE
+      &lt;table name&gt; { READ ONLY | READ WRITE }</literal></simpara>
+
+      <simpara>Set the writeability property of a table. Tables are writable
+      by default. This statement can be used to change the property between
+      <literal>READ ONLY</literal> and <literal>READ WRITE</literal>. This is
+      a feature of HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SET TABLE SOURCE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SET TABLE SOURCE</emphasis></simpara>
+
+      <simpara><emphasis>set table source statement</emphasis></simpara>
+
+      <simpara><literal>&lt;set table source statement&gt; ::= SET TABLE
+      &lt;table name&gt; SOURCE &lt;file and options&gt;
+      [DESC]</literal></simpara>
+
+      <simpara><literal>&lt;file and options&gt;::= &lt;doublequote&gt;
+      &lt;file path&gt; [&lt;semicolon&gt; &lt;property&gt;...]
+      &lt;doublequote&gt; </literal></simpara>
+
+      <simpara>Set the text source for a text table. This statement cannot be
+      used for tables that are not defined as TEXT TABLE.</simpara>
+
+      <variablelist>
+        <title>Supported Properties</title>
+
+        <varlistentry>
+          <term>quoted = { true | false }</term>
+
+          <listitem>
+            <para>default is true. If false, treats double quotes as normal
+            characters</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>all_quoted = { true | false }</term>
+
+          <listitem>
+            <para>default is false. If true, adds double quotes around all
+            fields.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>encoding = &lt;encoding name&gt;</term>
+
+          <listitem>
+            <para>character encoding for text and character fields, for
+            example, encoding=UTF-8</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ignore_first = { true | false }</term>
+
+          <listitem>
+            <para>default is false. If true ignores the first line of the
+            file</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>cache_scale= &lt;numeric value&gt;</term>
+
+          <listitem>
+            <para>exponent to calculate rows of the text file in cache.
+            Default is 8, equivalent to nearly 800 rows</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>cache_size_scale = &lt;numeric value&gt;r</term>
+
+          <listitem>
+            <para>exponent to calculate average size of each row in cache.
+            Default is 8, equivalent to 256 bytes per row.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>fs = &lt;unquoted character&gt;</term>
+
+          <listitem>
+            <para>field separator</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>vs = &lt;unquoted character&gt;</term>
+
+          <listitem>
+            <para>varchar separator</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <variablelist>
+        <title>Special indicators for HyperSQL Text Table separators</title>
+
+        <varlistentry>
+          <term>\semi</term>
+
+          <listitem>
+            <para>semicolon</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\quote</term>
+
+          <listitem>
+            <para>quote</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\space</term>
+
+          <listitem>
+            <para>space character</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\apos</term>
+
+          <listitem>
+            <para>apostrophe</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\n</term>
+
+          <listitem>
+            <para>newline - Used as an end anchor (like $ in regular
+            expressions)</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\r</term>
+
+          <listitem>
+            <para>carriage return</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\t</term>
+
+          <listitem>
+            <para>tab</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\\</term>
+
+          <listitem>
+            <para>backslash</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\u####</term>
+
+          <listitem>
+            <para>a Unicode character specified in hexadecimal</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <simpara>In the example below, the text source of the table is set to
+      "myfile", the field separator to the pipe symbol, and the long varchar
+      separator to the tilde symbol.</simpara>
+
+      <programlisting>    SET TABLE mytable SOURCE 'myfile;fs=|;vs=.;lvs=~'</programlisting>
+
+      <simpara>Only a user with the DBA role can execute this
+      statement.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SET TABLE SOURCE HEADER</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SET TABLE SOURCE
+      HEADER</emphasis></simpara>
+
+      <simpara><emphasis>set table source header
+      statement</emphasis></simpara>
+
+      <simpara><literal>&lt;set table source header statement&gt; ::= SET
+      TABLE &lt;table name&gt; SOURCE HEADER &lt;header
+      string&gt;</literal></simpara>
+
+      <simpara>Set the header for the text source for a text table. If this
+      command is used, the <literal>&lt;header string&gt;</literal> is used as
+      the first line of the source file of the text table. This line is not
+      part of the table data. Only a user with the DBA role can execute this
+      statement.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SET TABLE SOURCE on-off</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SET TABLE SOURCE
+      on-off</emphasis></simpara>
+
+      <simpara><emphasis>set table source on-off
+      statement</emphasis></simpara>
+
+      <simpara><literal>&lt;set table source on-off statement&gt; ::= SET
+      TABLE &lt;table name&gt; SOURCE { ON | OFF } </literal></simpara>
+
+      <simpara>Attach or detach a text table from its text source. This
+      command does not change the properties or the name of the file that is
+      the source of a text table. When OFF is specified, the command detaches
+      the table from its source and closes the file for the source. In this
+      state, it is not possible to read or write to the table. This allows the
+      user to replace the file with a different file, or delete it. When ON is
+      specified, the source file is read. Only a user with the DBA role can
+      execute this statement</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ALTER TABLE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ALTER TABLE</emphasis></simpara>
+
+      <simpara><emphasis>alter table statement</emphasis></simpara>
+
+      <simpara><literal>&lt;alter table statement&gt; ::= ALTER TABLE
+      &lt;table name&gt; &lt;alter table action&gt;</literal></simpara>
+
+      <simpara><literal>&lt;alter table action&gt; ::= &lt;add column
+      definition&gt; | &lt;alter column definition&gt; | &lt;drop column
+      definition&gt; | &lt;add table constraint definition&gt; | &lt;drop
+      table constraint definition&gt;</literal></simpara>
+
+      <simpara>Change the definition of a table. Specific types of this
+      statement are covered below.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ADD COLUMN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ADD COLUMN</emphasis></simpara>
+
+      <simpara><emphasis>add column definition</emphasis></simpara>
+
+      <simpara><literal>&lt;add column definition&gt; ::= ADD [ COLUMN ]
+      &lt;column definition&gt; [ BEFORE &lt;other column name&gt;
+      ]</literal></simpara>
+
+      <simpara>Add a column to an existing table. The <literal>&lt;column
+      definition&gt;</literal> is specified the same way as it is used in
+      <literal>&lt;table definition&gt;</literal>. HyperSQL allows the use of
+      <literal>[ BEFORE &lt;other column name&gt; ]</literal> to specify at
+      which position the new column is added to the table.</simpara>
+
+      <simpara>If the table contains rows, the new column must have a
+      <literal>&lt;default clause&gt;</literal> or use one of the forms of
+      GENERATED. The column values for each row is then filled with the result
+      of the <literal>&lt;default clause&gt;</literal> or the generated
+      value.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ALTER COLUMN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ALTER COLUMN</emphasis></simpara>
+
+      <simpara><emphasis>alter column definition</emphasis></simpara>
+
+      <simpara><literal>&lt;alter column definition&gt; ::= ALTER [ COLUMN ]
+      &lt;column name&gt; &lt;alter column action&gt;</literal></simpara>
+
+      <simpara><literal>&lt;alter column action&gt; ::= &lt;set column default
+      clause&gt; | &lt;drop column default clause&gt; | &lt;alter column data
+      type clause&gt; | &lt;alter identity column specification&gt; |
+      &lt;alter column nullability&gt; | &lt;alter column
+      name&gt;</literal></simpara>
+
+      <simpara>Change a column and its definition. Specific types of this
+      statement are covered below. See also the RENAME statement
+      above.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SET DEFAULT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SET DEFAULT</emphasis></simpara>
+
+      <simpara><emphasis>set column default clause</emphasis></simpara>
+
+      <simpara><literal>&lt;set column default clause&gt; ::= SET &lt;default
+      clause&gt;</literal></simpara>
+
+      <simpara>Set the default clause for a column. This can be used if the
+      column is not defined as GENERATED.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP DEFAULT (table)</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP DEFAULT</emphasis></simpara>
+
+      <simpara><emphasis>drop column default clause</emphasis></simpara>
+
+      <simpara><literal>&lt;drop column default clause&gt; ::= DROP
+      DEFAULT</literal></simpara>
+
+      <simpara>Drop the default clause from a column.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SET DATA TYPE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SET DATA TYPE</emphasis></simpara>
+
+      <simpara><emphasis>alter column data type clause</emphasis></simpara>
+
+      <simpara><literal>&lt;alter column data type clause&gt; ::= SET DATA
+      TYPE &lt;data type&gt;</literal></simpara>
+
+      <simpara>Change the declared type of a column. The (proposed) SQL
+      Standard allows only changes to type properties such as maximum length,
+      precision, or scale, and only changes that cause the property to
+      enlarge. HyperSQL allows changing the type if all the existing values
+      can be cast into the new type without string truncation or loss of
+      significant digits.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>alter identity column</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">alter identity
+      column</emphasis></simpara>
+
+      <simpara><emphasis>alter identity column
+      specification</emphasis></simpara>
+
+      <simpara><literal>&lt;alter identity column specification&gt; ::=
+      &lt;alter identity column option&gt;...</literal></simpara>
+
+      <simpara><literal>&lt;alter identity column option&gt; ::= &lt;alter
+      sequence generator restart option&gt; | SET &lt;basic sequence generator
+      option&gt;</literal></simpara>
+
+      <simpara>Change the properties of an identity column. This command is
+      similar to the commands used for changing the properties of named
+      SEQUENCE objects discussed in this section.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>alter column nullability</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SET NULL</emphasis></simpara>
+
+      <simpara><emphasis>alter column nullability</emphasis></simpara>
+
+      <simpara><literal>&lt;alter column nullability&gt; ::= SET
+      NULL</literal></simpara>
+
+      <simpara>Removes a NOT NULL constraint from a column. This option is
+      specific to HyperSQL</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP COLUMN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP COLUMN</emphasis></simpara>
+
+      <simpara><emphasis>drop column definition</emphasis></simpara>
+
+      <simpara><literal>&lt;drop column definition&gt; ::= DROP [ COLUMN ]
+      &lt;column name&gt; &lt;drop behavior&gt;</literal></simpara>
+
+      <simpara>Destroy a column of a base table. The <literal>&lt;drop
+      behavior&gt;</literal> is either <literal>RESTRICT</literal> or
+      <literal>CASCADE</literal>. If the column is referenced in a table
+      constraint that references other columns as well as this column, or if
+      the column is referenced in a VIEW, or the column is referenced in a
+      TRIGGER, then the statement will fail if <literal>RESTRICT</literal> is
+      specified. If <literal>CASCADE</literal> is specified, then any
+      CONSTRAINT, VIEW or TRIGGER object that references the column is dropped
+      with a cascading effect.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ADD CONSTRAINT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ADD CONSTRAINT</emphasis></simpara>
+
+      <simpara><emphasis>add table constraint definition</emphasis></simpara>
+
+      <simpara><literal>&lt;add table constraint definition&gt; ::= ADD
+      &lt;table constraint definition&gt;</literal></simpara>
+
+      <simpara>Add a constraint to a table. The existing rows of the table
+      must conform to the added constraint, otherwise the statement will not
+      succeed.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP CONSTRAINT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP CONSTRAINT</emphasis></simpara>
+
+      <simpara><emphasis>drop table constraint definition</emphasis></simpara>
+
+      <simpara><literal>&lt;drop table constraint definition&gt; ::= DROP
+      CONSTRAINT &lt;constraint name&gt; &lt;drop
+      behavior&gt;</literal></simpara>
+
+      <simpara>Destroy a constraint on a table. The <literal>&lt;drop
+      behavior&gt;</literal> has an effect only on UNIQUE and PRIMARY KEY
+      constraints. If such a constraint is referenced by a FOREIGN KEY
+      constraint, the FOREIGN KEY constraint will be dropped if
+      <literal>CASCADE</literal> is specified. If the columns of such a
+      constraint are used in a GROUP BY clause in the query expression of a
+      VIEW or another kind of schema object, and a functional dependency
+      relationship exists between these columns and the other columns in that
+      query expression, then the VIEW or other schema object will be dropped
+      when <literal>CASCADE</literal> is specified.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP TABLE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP TABLE</emphasis></simpara>
+
+      <simpara><emphasis>drop table statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop table statement&gt; ::= DROP TABLE [ IF
+      EXISTS ] &lt;table name&gt; [ IF EXISTS ] &lt;drop
+      behavior&gt;</literal></simpara>
+
+      <simpara>Destroy a table. The default drop behaviour is RESTRICT and
+      will cause the statement to fail if there is any view or foreign key
+      constraint that references the table. If <literal>&lt;drop
+      behavior&gt;</literal> is <literal>CASCADE</literal>, it causes all
+      schema objects that reference the table to drop. Referencing views are
+      dropped. In the case of foreign key constraints that reference the
+      table, the constraint is dropped, rather than the TABLE or DOMAIN that
+      contains it.</simpara>
+    </section>
+
+    <section>
+      <title>View Creation and Manipulation</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE VIEW</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE VIEW</emphasis></simpara>
+
+      <simpara><emphasis>view definition</emphasis></simpara>
+
+      <simpara><literal>&lt;view definition&gt; ::= CREATE [ RECURSIVE ] VIEW
+      &lt;table name&gt; &lt;view specification&gt; AS &lt;query
+      expression&gt; [ WITH [ CASCADED | LOCAL ] CHECK OPTION
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;view specification&gt; ::= [ &lt;left paren&gt;
+      &lt;view column list&gt; &lt;right paren&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;view column list&gt; ::= &lt;column name
+      list&gt;</literal></simpara>
+
+      <simpara>Define a view. The <literal>&lt;query expression&gt;</literal>
+      is a SELECT or similar statement. The <literal>&lt;view column
+      list&gt;</literal> is the list of unique names for the columns of the
+      view. The number of columns in the <literal>&lt;view column
+      list&gt;</literal> must match the number of columns returned by the
+      <literal>&lt;query expression&gt;</literal>. If <literal>&lt;view column
+      list&gt;</literal> is not specified, then the columns of the
+      <literal>&lt;query expression&gt;</literal> should have unique names and
+      are used as the names of the view column.</simpara>
+
+      <simpara>Some views are updatable. As covered elsewhere, an updatable
+      view is based on a single table or updatable view. For updatable views,
+      the optional <literal>CHECK OPTION</literal> clause can be specified. If
+      this option is specified, then if a row of the view is updated or a new
+      row is inserted into the view, then it should contain such values that
+      the row would be included in the view after the change. If <literal>WITH
+      CASCADED CHECK OPTION</literal> is specified, then if the
+      <literal>&lt;query expression&gt;</literal> of the view references
+      another view, then the search condition of the underlying view should
+      also be satisfied by the update or insert operation.</simpara>
+
+      <simpara>More on recursive...</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP VIEW</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP VIEW</emphasis></simpara>
+
+      <simpara><emphasis>drop view statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop view statement&gt; ::= DROP VIEW [ IF EXISTS
+      ] &lt;table name&gt; [ IF EXISTS ] &lt;drop
+      behavior&gt;</literal></simpara>
+
+      <simpara>Destroy a view. The <literal>&lt;drop behavior&gt;</literal> is
+      similar to dropping a table.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ALTER view</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ALTER VIEW</emphasis></simpara>
+
+      <simpara><emphasis>alter view statement</emphasis></simpara>
+
+      <simpara><literal>&lt;alter view statement&gt; ::= ALTER VIEW &lt;table
+      name&gt; &lt;view specification&gt; AS &lt;query expression&gt; [ WITH [
+      CASCADED | LOCAL ] CHECK OPTION ]</literal></simpara>
+
+      <simpara>Alter a view. The statement is otherwise identical to CREATE
+      VIEW. The new definition replaces the old. If there are database objects
+      such as routines or views that reference the view, then these objects
+      are recompiled with the new view definition. If the new definition is
+      not compatible, the statement fails.</simpara>
+    </section>
+
+    <section>
+      <title>Domain Creation and Manipulation</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE DOMAIN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE DOMAIN</emphasis></simpara>
+
+      <simpara><emphasis>domain definition</emphasis></simpara>
+
+      <simpara><literal>&lt;domain definition&gt; ::= CREATE DOMAIN &lt;domain
+      name&gt; [ AS ] &lt;predefined type&gt; [ &lt;default clause&gt; ] [
+      &lt;domain constraint&gt;... ] [ &lt;collate clause&gt;
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;domain constraint&gt; ::= [ &lt;constraint name
+      definition&gt; ] &lt;check constraint definition&gt; [ &lt;constraint
+      characteristics&gt; ]</literal></simpara>
+
+      <simpara>Define a domain. Although a DOMAIN is not strictly a type in
+      the SQL Standard, it can be informally considered as a type. A DOMAIN is
+      based on a <literal>&lt;predefined type&gt;</literal>, which is a base
+      type defined by the Standard. It can have a <literal>&lt;default
+      clause&gt;</literal>, similar to a column default clause. It can also
+      have one or more CHECK constraints which limit the values that can be
+      assigned to a column or variable that has the DOMAIN as its
+      type.</simpara>
+
+      <informalexample>
+        <programlisting>CREATE DOMAIN valid_string AS VARCHAR(20) DEFAULT 'NO VALUE' CHECK (value IS NOT NULL AND CHARACTER_LENGTH(value) &gt; 2) 
+</programlisting>
+      </informalexample>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ALTER DOMAIN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ALTER DOMAIN</emphasis></simpara>
+
+      <simpara><emphasis>alter domain statement</emphasis></simpara>
+
+      <simpara><literal>&lt;alter domain statement&gt; ::= ALTER DOMAIN
+      &lt;domain name&gt; &lt;alter domain action&gt;</literal></simpara>
+
+      <simpara><literal>&lt;alter domain action&gt; ::= &lt;set domain default
+      clause&gt; | &lt;drop domain default clause&gt; | &lt;add domain
+      constraint definition&gt; | &lt;drop domain constraint
+      definition&gt;</literal></simpara>
+
+      <simpara>Change a domain and its definition.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SET DOMAIN DEFAULT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SET DEFAULT</emphasis></simpara>
+
+      <simpara><emphasis>set domain default clause</emphasis></simpara>
+
+      <simpara><literal>&lt;set domain default clause&gt; ::= SET &lt;default
+      clause&gt;</literal></simpara>
+
+      <simpara>Set the default value in a domain.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP DOMAIN DEFAULT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP DEFAULT</emphasis></simpara>
+
+      <simpara><emphasis>drop domain default clause</emphasis></simpara>
+
+      <simpara><literal>&lt;drop domain default clause&gt; ::= DROP
+      DEFAULT</literal></simpara>
+
+      <simpara>Remove the default clause of a domain.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ADD DOMAIN CONSTRAINT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ADD CONSTRAINT</emphasis></simpara>
+
+      <simpara><emphasis>add domain constraint definition</emphasis></simpara>
+
+      <simpara><literal>&lt;add domain constraint definition&gt; ::= ADD
+      &lt;domain constraint&gt;</literal></simpara>
+
+      <simpara>Add a constraint to a domain.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP DOMAIN CONSTRAINT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP CONSTRAINT</emphasis></simpara>
+
+      <simpara><emphasis>drop domain constraint
+      definition</emphasis></simpara>
+
+      <simpara><literal>&lt;drop domain constraint definition&gt; ::= DROP
+      CONSTRAINT &lt;constraint name&gt;</literal></simpara>
+
+      <simpara>Destroy a constraint on a domain. If the <literal>&lt;drop
+      behavior&gt;</literal> is <literal>CASCADE</literal>, and the constraint
+      is a UNIQUE constraint which is referenced by a FOREIGN KEY constraint
+      on another table, then the FOREIGN KEY constraint is also
+      dropped.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP DOMAIN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP DOMAIN</emphasis></simpara>
+
+      <simpara><emphasis>drop domain statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop domain statement&gt; ::= DROP DOMAIN
+      &lt;domain name&gt; &lt;drop behavior&gt;</literal></simpara>
+
+      <simpara>Destroy a domain. If <literal>&lt;drop behavior&gt;</literal>
+      is <literal>CASCADE</literal>, it works differently from most other
+      objects. If a table features a column of the specified DOMAIN, the
+      column survives and inherits the DEFAULT CLAUSE, and the CHECK
+      CONSTRAINT of the DOMAIN.</simpara>
+    </section>
+
+    <section>
+      <title>Trigger Creation</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE TRIGGER</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE TRIGGER</emphasis></simpara>
+
+      <simpara><emphasis>trigger definition</emphasis></simpara>
+
+      <simpara><literal>&lt;trigger definition&gt; ::= CREATE TRIGGER
+      &lt;trigger name&gt; &lt;trigger action time&gt; &lt;trigger event&gt;
+      ON &lt;table name&gt; [ REFERENCING &lt;transition table or variable
+      list&gt; ] &lt;triggered action&gt;</literal></simpara>
+
+      <simpara><literal>&lt;trigger action time&gt; ::= BEFORE | AFTER |
+      INSTEAD OF</literal></simpara>
+
+      <simpara><literal>&lt;trigger event&gt; ::= INSERT | DELETE | UPDATE [
+      OF &lt;trigger column list&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;trigger column list&gt; ::= &lt;column name
+      list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;triggered action&gt; ::= [ FOR EACH { ROW |
+      STATEMENT } ] [ &lt;triggered when clause&gt; ] &lt;triggered SQL
+      statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;triggered when clause&gt; ::= WHEN &lt;left
+      paren&gt; &lt;search condition&gt; &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;triggered SQL statement&gt; ::= &lt;SQL procedure
+      statement&gt; | BEGIN ATOMIC { &lt;SQL procedure statement&gt;
+      &lt;semicolon&gt; }... END | [QUEUE &lt;integer literal&gt;] [NOWAIT]
+      CALL &lt;HSQLDB trigger class FQN&gt;</literal></simpara>
+
+      <simpara><literal>&lt;transition table or variable list&gt; ::=
+      &lt;transition table or variable&gt;...</literal></simpara>
+
+      <simpara><literal>&lt;transition table or variable&gt; ::= OLD [ ROW ] [
+      AS ] &lt;old transition variable name&gt; | NEW [ ROW ] [ AS ] &lt;new
+      transition variable name&gt; | OLD TABLE [ AS ] &lt;old transition table
+      name&gt; | NEW TABLE [ AS ] &lt;new transition table
+      name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;old transition table name&gt; ::= &lt;transition
+      table name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;new transition table name&gt; ::= &lt;transition
+      table name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;transition table name&gt; ::=
+      &lt;identifier&gt;</literal></simpara>
+
+      <simpara><literal>&lt;old transition variable name&gt; ::=
+      &lt;correlation name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;new transition variable name&gt; ::=
+      &lt;correlation name&gt;</literal></simpara>
+
+      <simpara>Trigger definition is a relatively complex statement. The
+      combination of <literal>&lt;trigger action time&gt;</literal> and
+      <literal>&lt;trigger event&gt;</literal> determines the type of the
+      trigger. Examples include BEFORE DELETE, AFTER UPDATE, INSTEAD OF
+      INSERT. If the optional <literal>[ OF &lt;trigger column list&gt;
+      ]</literal> is specified for an UPDATE trigger, then the trigger is
+      activated only if one of the columns that is in the <literal>&lt;trigger
+      column list&gt;</literal> is specified in the UPDATE statement that
+      activates the trigger.</simpara>
+
+      <simpara>If a trigger is <literal>FOR EACH ROW</literal>, which is the
+      default option, then the trigger is activated for each row of the table
+      that is affected by the execution of an SQL statement. Otherwise, it is
+      activated once only per statement execution. In the first case, there is
+      a before and after state for each row. For UPDATE triggers, both before
+      and after states exist, representing the row before the update, and
+      after the update. For DELETE, triggers, there is only a before state.
+      For INSERT triggers, there is only an after state. If a trigger is
+      <literal>FOR EACH STATEMENT</literal>, then a transient table is created
+      containing all the rows for the before state and another transient table
+      is created for the after state.</simpara>
+
+      <simpara>The <literal>[ REFERENCING &lt;transition table or variable&gt;
+      ]</literal> is used to give a name to the before and after data row or
+      table. This name can be referenced in the <literal>&lt;SQL procedure
+      statement&gt;</literal> to access the data.</simpara>
+
+      <simpara>The optional <literal>&lt;triggered when clause&gt;</literal>
+      is a search condition, similar to the search condition of a DELETE or
+      UPDATE statement. If the search condition is not TRUE for a row, then
+      the trigger is not activated for that row.</simpara>
+
+      <simpara>The <literal>&lt;SQL procedure statement&gt;</literal> is
+      limited to INSERT, DELETE, UPDATE and MERGE statements.</simpara>
+
+      <simpara>The <literal>&lt;HSQLDB trigger class FQN&gt;</literal> is a
+      delimited identifier that contains the fully qualified name of a Java
+      class that implements the <classname>org.hsqldb.Trigger</classname>
+      interface.</simpara>
+
+      <simpara>Early releases of HyperSQL version 2.0 do not allow the use of
+      OLD TABLE or NEW TABLE in statement level trigger definitions.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP TRIGGER</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP TRIGGER</emphasis></simpara>
+
+      <simpara><emphasis>drop trigger statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop trigger statement&gt; ::= DROP TRIGGER
+      &lt;trigger name&gt;</literal></simpara>
+
+      <simpara>Destroy a trigger.</simpara>
+    </section>
+
+    <section>
+      <title>Routine Creation</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>schema routine</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">schema routine</emphasis></simpara>
+
+      <simpara><emphasis>SQL-invoked routine</emphasis></simpara>
+
+      <simpara><literal>&lt;SQL-invoked routine&gt; ::= &lt;schema
+      routine&gt;</literal></simpara>
+
+      <simpara><literal>&lt;schema routine&gt; ::= &lt;schema procedure&gt; |
+      &lt;schema function&gt;</literal></simpara>
+
+      <simpara><literal>&lt;schema procedure&gt; ::= CREATE &lt;SQL-invoked
+      procedure&gt;</literal></simpara>
+
+      <simpara><literal>&lt;schema function&gt; ::= CREATE &lt;SQL-invoked
+      function&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL-invoked procedure&gt; ::= PROCEDURE &lt;schema
+      qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+      &lt;routine characteristics&gt; &lt;routine body&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL-invoked function&gt; ::= { &lt;function
+      specification&gt; | &lt;method specification designator&gt; }
+      &lt;routine body&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL parameter declaration list&gt; ::= &lt;left
+      paren&gt; [ &lt;SQL parameter declaration&gt; [ { &lt;comma&gt; &lt;SQL
+      parameter declaration&gt; }... ] ] &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL parameter declaration&gt; ::= [ &lt;parameter
+      mode&gt; ] [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt; [
+      RESULT ]</literal></simpara>
+
+      <simpara><literal>&lt;parameter mode&gt; ::= IN | OUT |
+      INOUT</literal></simpara>
+
+      <simpara><literal>&lt;parameter type&gt; ::= &lt;data
+      type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;function specification&gt; ::= FUNCTION &lt;schema
+      qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+      &lt;returns clause&gt; &lt;routine characteristics&gt; [ &lt;dispatch
+      clause&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;method specification designator&gt; ::= SPECIFIC
+      METHOD &lt;specific method name&gt; | [ INSTANCE | STATIC | CONSTRUCTOR
+      ] METHOD &lt;method name&gt; &lt;SQL parameter declaration list&gt; [
+      &lt;returns clause&gt; ] FOR &lt;schema-resolved user-defined type
+      name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;routine characteristics&gt; ::= [ &lt;routine
+      characteristic&gt;... ]</literal></simpara>
+
+      <simpara><literal>&lt;routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | SPECIFIC &lt;specific
+      name&gt; | &lt;deterministic characteristic&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | &lt;savepoint level
+      indication&gt;</literal></simpara>
+
+      <simpara><literal>&lt;savepoint level indication&gt; ::= NEW SAVEPOINT
+      LEVEL | OLD SAVEPOINT LEVEL</literal></simpara>
+
+      <simpara><literal>&lt;returned result sets characteristic&gt; ::=
+      DYNAMIC RESULT SETS &lt;maximum returned result
+      sets&gt;</literal></simpara>
+
+      <simpara><literal>&lt;parameter style clause&gt; ::= PARAMETER STYLE
+      &lt;parameter style&gt;</literal></simpara>
+
+      <simpara><literal>&lt;dispatch clause&gt; ::= STATIC
+      DISPATCH</literal></simpara>
+
+      <simpara><literal>&lt;returns clause&gt; ::= RETURNS &lt;returns
+      type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;returns type&gt; ::= &lt;returns data type&gt; [
+      &lt;result cast&gt; ] | &lt;returns table type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;returns table type&gt; ::= TABLE &lt;table
+      function column list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;table function column list&gt; ::= &lt;left
+      paren&gt; &lt;table function column list element&gt; [ { &lt;comma&gt;
+      &lt;table function column list element&gt; }... ] &lt;right
+      paren&gt;</literal></simpara>
+
+      <simpara><literal>&lt;table function column list element&gt; ::=
+      &lt;column name&gt; &lt;data type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;result cast&gt; ::= CAST FROM &lt;result cast from
+      type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;result cast from type&gt; ::= &lt;data type&gt; [
+      &lt;locator indication&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;returns data type&gt; ::= &lt;data type&gt; [
+      &lt;locator indication&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;routine body&gt; ::= &lt;SQL routine spec&gt; |
+      &lt;external body reference&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL routine spec&gt; ::= [ &lt;rights clause&gt; ]
+      &lt;SQL routine body&gt;</literal></simpara>
+
+      <simpara><literal>&lt;rights clause&gt; ::= SQL SECURITY INVOKER | SQL
+      SECURITY DEFINER</literal></simpara>
+
+      <simpara><literal>&lt;SQL routine body&gt; ::= &lt;SQL procedure
+      statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;external body reference&gt; ::= EXTERNAL [ NAME
+      &lt;external routine name&gt; ] [ &lt;parameter style clause&gt;
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;parameter style&gt; ::= SQL |
+      GENERAL</literal></simpara>
+
+      <simpara><literal>&lt;deterministic characteristic&gt; ::= DETERMINISTIC
+      | NOT DETERMINISTIC</literal></simpara>
+
+      <simpara><literal>&lt;SQL-data access indication&gt; ::= NO SQL |
+      CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA</literal></simpara>
+
+      <simpara><literal>&lt;null-call clause&gt; ::= RETURNS NULL ON NULL
+      INPUT | CALLED ON NULL INPUT</literal></simpara>
+
+      <simpara><literal>&lt;maximum returned result sets&gt; ::= &lt;unsigned
+      integer&gt;</literal></simpara>
+
+      <simpara>Define an SQL-invoked routine.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ALTER routine</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ALTER routine</emphasis></simpara>
+
+      <simpara><emphasis>alter routine statement</emphasis></simpara>
+
+      <simpara><literal>&lt;alter routine statement&gt; ::= ALTER &lt;specific
+      routine designator&gt; &lt;alter routine characteristics&gt; &lt;alter
+      routine behavior&gt;</literal></simpara>
+
+      <simpara><literal>&lt;alter routine characteristics&gt; ::= &lt;alter
+      routine characteristic&gt;...</literal></simpara>
+
+      <simpara><literal>&lt;alter routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | NAME &lt;external routine
+      name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;alter routine behavior&gt; ::=
+      RESTRICT</literal></simpara>
+
+      <simpara>Alter a characteristic of an SQL-invoked routine. Early
+      releases of HyperSQL 2.0 may not support this statement.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP routine</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP</emphasis></simpara>
+
+      <simpara><emphasis>drop routine statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop routine statement&gt; ::= DROP &lt;specific
+      routine designator&gt; &lt;drop behavior&gt;</literal></simpara>
+
+      <simpara>Destroy an SQL-invoked routine.</simpara>
+    </section>
+
+    <section>
+      <title>Sequence Creation</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE SEQUENCE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE SEQUENCE</emphasis></simpara>
+
+      <simpara><emphasis>sequence generator definition</emphasis></simpara>
+
+      <simpara><literal>&lt;sequence generator definition&gt; ::= CREATE
+      SEQUENCE &lt;sequence generator name&gt; [ &lt;sequence generator
+      options&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator options&gt; ::= &lt;sequence
+      generator option&gt; ...</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator option&gt; ::= &lt;sequence
+      generator data type option&gt; | &lt;common sequence generator
+      options&gt;</literal></simpara>
+
+      <simpara><literal>&lt;common sequence generator options&gt; ::=
+      &lt;common sequence generator option&gt; ...</literal></simpara>
+
+      <simpara><literal>&lt;common sequence generator option&gt; ::=
+      &lt;sequence generator start with option&gt; | &lt;basic sequence
+      generator option&gt;</literal></simpara>
+
+      <simpara><literal>&lt;basic sequence generator option&gt; ::=
+      &lt;sequence generator increment by option&gt; | &lt;sequence generator
+      maxvalue option&gt; | &lt;sequence generator minvalue option&gt; |
+      &lt;sequence generator cycle option&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator data type option&gt; ::= AS
+      &lt;data type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator start with option&gt; ::= START
+      WITH &lt;sequence generator start value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator start value&gt; ::= &lt;signed
+      numeric literal&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator increment by option&gt; ::=
+      INCREMENT BY &lt;sequence generator increment&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator increment&gt; ::= &lt;signed
+      numeric literal&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator maxvalue option&gt; ::=
+      MAXVALUE &lt;sequence generator max value&gt; | NO
+      MAXVALUE</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator max value&gt; ::= &lt;signed
+      numeric literal&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator minvalue option&gt; ::=
+      MINVALUE &lt;sequence generator min value&gt; | NO
+      MINVALUE</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator min value&gt; ::= &lt;signed
+      numeric literal&gt;</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator cycle option&gt; ::= CYCLE | NO
+      CYCLE</literal></simpara>
+
+      <simpara>Define a named sequence generator. A SEQUENCE object generates
+      a sequence of integers according to the specified rules. The simple
+      definition without the options defines a sequence of numbers in INTEGER
+      type starting at 1 and incrementing by 1. By default the
+      <literal>CYCLE</literal> property is set and the minimum and maximum
+      limits are the minimum and maximum limits of the type of returned
+      values. There are self-explanatory options for changing various
+      properties of the sequence. The <literal>MAXVALUE</literal> and
+      <literal>MINVALUE</literal> specify the upper and lower limits. If
+      <literal>CYCLE</literal> is specified, after the sequence returns the
+      highest or lowest value in range, the next value will respectively be
+      the lowest or highest value in range. If <literal>NO CYCLE</literal> is
+      specified, the use of the sequence generator results in an error once
+      the limit has been reached.</simpara>
+
+      <simpara>The integer types: SMALLINT, INTEGER, BIGINT, DECIMAL and
+      NUMERIC can be used as the type of the sequence. DECIMAL and NUMERIC
+      types must have a scale of 0 and a precision not exceeding 18.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>ALTER SEQUENCE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">ALTER SEQUENCE</emphasis></simpara>
+
+      <simpara><emphasis>alter sequence generator
+      statement</emphasis></simpara>
+
+      <simpara><literal>&lt;alter sequence generator statement&gt; ::= ALTER
+      SEQUENCE &lt;sequence generator name&gt; &lt;alter sequence generator
+      options&gt;</literal></simpara>
+
+      <simpara><literal>&lt;alter sequence generator options&gt; ::= &lt;alter
+      sequence generator option&gt;...</literal></simpara>
+
+      <simpara><literal>&lt;alter sequence generator option&gt; ::= &lt;alter
+      sequence generator restart option&gt; | &lt;basic sequence generator
+      option&gt;</literal></simpara>
+
+      <simpara><literal>&lt;alter sequence generator restart option&gt; ::=
+      RESTART [ WITH &lt;sequence generator restart value&gt;
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;sequence generator restart value&gt; ::=
+      &lt;signed numeric literal&gt;</literal></simpara>
+
+      <simpara>Change the definition of a named sequence generator. The same
+      options that are used in the definition of the SEQUENCE can be used to
+      alter it. The exception is the option for the start value which is
+      <literal>RESTART WITH</literal> for the ALTER SEQUENCE
+      statement..</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP SEQUENCE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP SEQUENCE</emphasis></simpara>
+
+      <simpara><emphasis>drop sequence generator
+      statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop sequence generator statement&gt; ::= DROP
+      SEQUENCE [ IF EXISTS ] &lt;sequence generator name&gt; [ IF EXISTS ]
+      &lt;drop behavior&gt;</literal></simpara>
+
+      <simpara>Destroy an external sequence generator. If the
+      <literal>&lt;drop behavior&gt;</literal> is <literal>CASCADE</literal>,
+      then all objects that reference the sequence are dropped. These objects
+      can be VIEW, ROUTINE or TRIGGER objects.</simpara>
+
+      <!-- From Foundation chapt. 13 -->
+    </section>
+
+    <section>
+      <title>SQL Procedure Statement</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SQL procedure statement</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SQL procedure
+      statement</emphasis></simpara>
+
+      <simpara><emphasis>SQL procedure statement</emphasis></simpara>
+
+      <simpara>The definition of CREATE TRIGGER and CREATE PROCEDURE
+      statements refers to &lt;SQL procedure statement&gt;. The definition of
+      this element is given below. However, only a subset of these statements
+      are allowed in trigger or routine definition.</simpara>
+
+      <simpara><literal>&lt;SQL procedure statement&gt; ::= &lt;SQL executable
+      statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL executable statement&gt; ::= &lt;SQL schema
+      statement&gt; | &lt;SQL data statement&gt; | &lt;SQL control
+      statement&gt; | &lt;SQL transaction statement&gt; | &lt;SQL connection
+      statement&gt; | &lt;SQL session statement&gt; | &lt;SQL diagnostics
+      statement&gt; | &lt;SQL dynamic statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL schema statement&gt; ::= &lt;SQL schema
+      definition statement&gt; | &lt;SQL schema manipulation
+      statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL schema definition statement&gt; ::= &lt;schema
+      definition&gt; | &lt;table definition&gt; | &lt;view definition&gt; |
+      &lt;SQL-invoked routine&gt; | &lt;grant statement&gt; | &lt;role
+      definition&gt; | &lt;domain definition&gt; | &lt;character set
+      definition&gt; | &lt;collation definition&gt; | &lt;transliteration
+      definition&gt; | &lt;assertion definition&gt; | &lt;trigger
+      definition&gt; | &lt;user-defined type definition&gt; | &lt;user-defined
+      cast definition&gt; | &lt;user-defined ordering definition&gt; |
+      &lt;transform definition&gt; | &lt;sequence generator
+      definition&gt;</literal></simpara>
+
+      <simpara><literal>&lt;SQL schema manipulation statement&gt; ::= &lt;drop
+      schema statement&gt; | &lt;alter table statement&gt; | &lt;drop table
+      statement&gt; | &lt;drop view statement&gt; | &lt;alter routine
+      statement&gt; | &lt;drop routine statement&gt; | &lt;drop user-defined
+      cast statement&gt; | &lt;revoke statement&gt; | &lt;drop role
+      statement&gt; | &lt;alter domain statement&gt; | &lt;drop domain
+      statement&gt; | &lt;drop character set statement&gt; | &lt;drop
+      collation statement&gt; | &lt;drop transliteration statement&gt; |
+      &lt;drop assertion statement&gt; | &lt;drop trigger statement&gt; |
+      &lt;alter type statement&gt; | &lt;drop data type statement&gt; |
+      &lt;alter sequence generator statement&gt; | &lt;drop sequence generator
+      statement&gt;</literal></simpara>
+    </section>
+
+    <section>
+      <title>Other Schema Object Creation</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE INDEX</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE INDEX</emphasis></simpara>
+
+      <simpara><emphasis>create index statement</emphasis></simpara>
+
+      <simpara><literal>&lt;create index statement&gt; ::= CREATE INDEX
+      &lt;index name&gt; ON &lt;table name&gt; &lt;left paren&gt; {&lt;column
+      name&gt; [ASC | DESC]}, ... &lt;left paren&gt;</literal></simpara>
+
+      <simpara>Creates an index on a group of columns of a table. The optional
+      [ASC | DESC] specifies if the column is indexed in the ascending or
+      descending order, but has no effect on how the index is created (it is
+      allowed for compatibility with other database engines). HyperSQL can use
+      all indexes in ascending or descending order as needed.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP INDEX</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP INDEX</emphasis></simpara>
+
+      <simpara><emphasis>drop index statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop index statement&gt; ::= DROP INDEX [ IF
+      EXISTS ] &lt;index name&gt; [ IF EXISTS ]</literal></simpara>
+
+      <simpara>Destroy an index.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE TYPE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE TYPE</emphasis></simpara>
+
+      <simpara><emphasis>user-defined type definition</emphasis></simpara>
+
+      <simpara><literal>&lt;user-defined type definition&gt; ::= CREATE TYPE
+      &lt;user-defined type body&gt;</literal></simpara>
+
+      <simpara><literal>&lt;user-defined type body&gt; ::= &lt;schema-resolved
+      user-defined type name&gt; [ AS &lt;representation&gt;
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;representation&gt; ::= &lt;predefined
+      type&gt;</literal></simpara>
+
+      <simpara>Define a user-defined type. Currently only simple distinct
+      types can be defined without further attributes.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE CAST</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE CAST</emphasis></simpara>
+
+      <simpara><emphasis>user-defined cast definition</emphasis></simpara>
+
+      <simpara><literal>&lt;user-defined cast definition&gt; ::= CREATE CAST
+      &lt;left paren&gt; &lt;source data type&gt; AS &lt;target data type&gt;
+      &lt;right paren&gt; WITH &lt;cast function&gt; [ AS ASSIGNMENT
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;cast function&gt; ::= &lt;specific routine
+      designator&gt;</literal></simpara>
+
+      <simpara><literal>&lt;source data type&gt; ::= &lt;data
+      type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;target data type&gt; ::= &lt;data
+      type&gt;</literal></simpara>
+
+      <simpara>Define a user-defined cast. This feature may be supported in a
+      future versions of HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP CAST</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP CAST</emphasis></simpara>
+
+      <simpara><emphasis>drop user-defined cast statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop user-defined cast statement&gt; ::= DROP CAST
+      &lt;left paren&gt; &lt;source data type&gt; AS &lt;target data type&gt;
+      &lt;right paren&gt; &lt;drop behavior&gt;</literal></simpara>
+
+      <simpara>Destroy a user-defined cast. This feature may be supported in a
+      future versions of HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE CHARACTER SET</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE CHARACTER SET</emphasis></simpara>
+
+      <simpara><emphasis>character set definition</emphasis></simpara>
+
+      <simpara><literal>&lt;character set definition&gt; ::= CREATE CHARACTER
+      SET &lt;character set name&gt; [ AS ] &lt;character set source&gt; [
+      &lt;collate clause&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;character set source&gt; ::= GET &lt;character set
+      specification&gt;</literal></simpara>
+
+      <simpara>Define a character set. A new CHARACTER SET is based on an
+      existing CHARACTER SET. The optional <literal>&lt;collate
+      clause&gt;</literal> specifies the collation to be used, otherwise the
+      collation is inherited from the default collation for the source
+      CHARACTER SET.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP CHARACTER SET</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP CHARACTER SET</emphasis></simpara>
+
+      <simpara><emphasis>drop character set statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop character set statement&gt; ::= DROP
+      CHARACTER SET &lt;character set name&gt;</literal></simpara>
+
+      <simpara>Destroy a character set. If the character set name is
+      referenced in any database object, the command fails. Note that
+      <literal>CASCADE</literal> or <literal>RESTRICT</literal> cannot be
+      specified for this command.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE COLLATION</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE COLLATION</emphasis></simpara>
+
+      <simpara><emphasis>collation definition</emphasis></simpara>
+
+      <simpara><literal>&lt;collation definition&gt; ::= CREATE COLLATION
+      &lt;collation name&gt; FOR &lt;character set specification&gt; FROM
+      &lt;existing collation name&gt; [ &lt;pad characteristic&gt;
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;existing collation name&gt; ::= &lt;collation
+      name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;pad characteristic&gt; ::= NO PAD | PAD
+      SPACE</literal></simpara>
+
+      <simpara>Define a collation. A new collation is based on an existing
+      COLLATION and applies to an existing CHARACTER SET. The <literal>&lt;pad
+      characteristic&gt;</literal> specifies whether strings are padded with
+      spaces for comparison. This feature may be supported in a future
+      versions of HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP COLLATION</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP COLLATION</emphasis></simpara>
+
+      <simpara><emphasis>drop collation statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop collation statement&gt; ::= DROP COLLATION
+      &lt;collation name&gt; &lt;drop behavior&gt;</literal></simpara>
+
+      <simpara>Destroy a collation. If the <literal>&lt;drop
+      behavior&gt;</literal> is <literal>CASCADE</literal>, then all
+      references to the collation revert to the default collation that would
+      be in force if the dropped collation was not specified. This feature may
+      be supported in a future versions of HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE TRANSLATION</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE TRANSLATION</emphasis></simpara>
+
+      <simpara><emphasis>transliteration definition</emphasis></simpara>
+
+      <simpara><literal>&lt;transliteration definition&gt; ::= CREATE
+      TRANSLATION &lt;transliteration name&gt; FOR &lt;source character set
+      specification&gt; TO &lt;target character set specification&gt; FROM
+      &lt;transliteration source&gt;</literal></simpara>
+
+      <simpara><literal>&lt;source character set specification&gt; ::=
+      &lt;character set specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;target character set specification&gt; ::=
+      &lt;character set specification&gt;</literal></simpara>
+
+      <simpara><literal>&lt;transliteration source&gt; ::= &lt;existing
+      transliteration name&gt; | &lt;transliteration
+      routine&gt;</literal></simpara>
+
+      <simpara><literal>&lt;existing transliteration name&gt; ::=
+      &lt;transliteration name&gt; </literal></simpara>
+
+      <simpara><literal>&lt;transliteration routine&gt; ::= &lt;specific
+      routine designator&gt;</literal></simpara>
+
+      <simpara>Define a character transliteration. This feature may be
+      supported in a future versions of HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP TRANSLATION</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP TRANSLATION</emphasis></simpara>
+
+      <simpara><emphasis>drop transliteration statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop transliteration statement&gt; ::= DROP
+      TRANSLATION &lt;transliteration name&gt;</literal></simpara>
+
+      <simpara>Destroy a character transliteration. This feature may be
+      supported in a future versions of HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE ASSERTION</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE ASSERTION</emphasis></simpara>
+
+      <simpara><emphasis>assertion definition</emphasis></simpara>
+
+      <simpara><literal>&lt;assertion definition&gt; ::= CREATE ASSERTION
+      &lt;constraint name&gt; CHECK &lt;left paren&gt; &lt;search
+      condition&gt; &lt;right paren&gt; [ &lt;constraint characteristics&gt;
+      ]</literal></simpara>
+
+      <simpara>Specify an integrity constraint. This feature may be supported
+      in a future versions of HyperSQL.</simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DROP ASSERTION</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DROP ASSERTION</emphasis></simpara>
+
+      <simpara><emphasis>drop assertion statement</emphasis></simpara>
+
+      <simpara><literal>&lt;drop assertion statement&gt; ::= DROP ASSERTION
+      &lt;constraint name&gt; [ &lt;drop behavior&gt; ]</literal></simpara>
+
+      <simpara>Destroy an assertion. This feature may be supported in a future
+      versions of HyperSQL.</simpara>
+    </section>
+  </section>
+
+  <section>
+    <title>The Information Schema</title>
+
+    <para>The Information Schema is a special schema in each catalog. The SQL
+    Standard defines a number of character sets and domains in this schema. In
+    addition, all the implementation-defined collations belong to the
+    Information Schema.</para>
+
+    <para>The SQL Standard defines many views in the Information Schema. These
+    views show the properties of the database objects that currently exist in
+    the database. When a user accesses one these views, only the properties of
+    database objects that the user can access are included.</para>
+
+    <para>HyperSQL supports all the views defined by the Standard, apart from
+    a few views that report on extended user-defined types and other optional
+    features of the Standard that are not supported by HyperSQL.</para>
+
+    <para>HyperSQL also adds some views to the Information Schema. These views
+    are for features that are not reported in any of the views defined by the
+    Standard, or for use by JDBC DatabaseMetaData.</para>
+
+    <section>
+      <title>Predefined Character Sets, Collations and Domains</title>
+
+      <para>The SQL Standard defines a number of character sets and domains in
+      the INFORMATION SCHEMA.</para>
+
+      <para>These domains are used in the INFORMATION SCHEMA views:</para>
+
+      <simpara>CARDINAL_NUMBER, YES_OR_NO, CHARACTER_DATA, SQL_IDENTIFIER,
+      TIME_STAMP</simpara>
+
+      <simpara>All available collations are in the INFORMATION
+      SCHEMA.</simpara>
+    </section>
+
+    <section>
+      <title>Views in INFORMATION SCHEMA</title>
+
+      <para>The following views are defined by the SQL Standard:</para>
+
+      <para>ADMINISTRABLE_ROLE_AUTHORIZATIONS</para>
+
+      <para>APPLICABLE_ROLES</para>
+
+      <para>ASSERTIONS</para>
+
+      <para>AUTHORIZATIONS</para>
+
+      <para>CHARACTER_SETS</para>
+
+      <para>CHECK_CONSTRAINTS</para>
+
+      <para>CHECK_CONSTRAINT_ROUTINE_USAGE</para>
+
+      <para>COLLATIONS</para>
+
+      <para>COLUMNS</para>
+
+      <para>COLUMN_COLUMN_USAGE</para>
+
+      <para>COLUMN_DOMAIN_USAGE</para>
+
+      <para>COLUMN_PRIVILEGES</para>
+
+      <para>COLUMN_UDT_USAGE</para>
+
+      <para>CONSTRAINT_COLUMN_USAGE</para>
+
+      <para>CONSTRAINT_TABLE_USAGE</para>
+
+      <para>DATA_TYPE_PRIVILEGES</para>
+
+      <para>DOMAINS</para>
+
+      <para>DOMAIN_CONSTRAINTS</para>
+
+      <para>ENABLED_ROLES</para>
+
+      <para>INFORMATION_SCHEMA_CATALOG_NAME</para>
+
+      <para>KEY_COLUMN_USAGE</para>
+
+      <para>PARAMETERS</para>
+
+      <para>REFERENTIAL_CONSTRAINTS</para>
+
+      <para>ROLE_AUTHORIZATION_DESCRIPTORS</para>
+
+      <para>ROLE_COLUMN_GRANTS</para>
+
+      <para>ROLE_ROUTINE_GRANTS</para>
+
+      <para>ROLE_TABLE_GRANTS</para>
+
+      <para>ROLE_UDT_GRANTS</para>
+
+      <para>ROLE_USAGE_GRANTS</para>
+
+      <para>ROUTINE_COLUMN_USAGE</para>
+
+      <para>ROUTINE_JAR_USAGE</para>
+
+      <para>ROUTINE_PRIVILEGES</para>
+
+      <para>ROUTINE_ROUTINE_USAGE</para>
+
+      <para>ROUTINE_SEQUENCE_USAGE</para>
+
+      <para>ROUTINE_TABLE_USAGE</para>
+
+      <para>ROUTINES</para>
+
+      <para>SCHEMATA</para>
+
+      <para>SEQUENCES</para>
+
+      <para>SQL_FEATURES</para>
+
+      <para>SQL_IMPLEMENTATION_INFO</para>
+
+      <para>SQL_PACKAGES</para>
+
+      <para>SQL_PARTS</para>
+
+      <para>SQL_SIZING</para>
+
+      <para>SQL_SIZING_PROFILES</para>
+
+      <para>TABLES</para>
+
+      <para>TABLE_CONSTRAINTS</para>
+
+      <para>TABLE_PRIVILEGES</para>
+
+      <para>TRANSLATIONS</para>
+
+      <para>TRIGGERED_UPDATE_COLUMNS</para>
+
+      <para>TRIGGERS</para>
+
+      <para>TRIGGER_COLUMN_USAGE</para>
+
+      <para>TRIGGER_ROUTINE_USAGE</para>
+
+      <para>TRIGGER_SEQUENCE_USAGE</para>
+
+      <para>TRIGGER_TABLE_USAGE</para>
+
+      <para>USAGE_PRIVILEGES</para>
+
+      <para>USER_DEFINED_TYPES</para>
+
+      <para>VIEWS</para>
+
+      <para>VIEW_COLUMN_USAGE</para>
+
+      <para>VIEW_ROUTINE_USAGE</para>
+
+      <para>VIEW_TABLE_USAGE</para>
+
+      <para>The following views are specific to HyperSQL:</para>
+
+      <para>SYSTEM_BESTROWIDENTIFIER</para>
+
+      <para>SYSTEM_CACHEINFO</para>
+
+      <para>SYSTEM_COLUMNS</para>
+
+      <para>SYSTEM_COMMENTS</para>
+
+      <para>SYSTEM_CROSSREFERENCE</para>
+
+      <para>SYSTEM_INDEXINFO</para>
+
+      <para>SYSTEM_PRIMARYKEYS</para>
+
+      <para>SYSTEM_PROCEDURECOLUMNS</para>
+
+      <para>SYSTEM_PROCEDURES</para>
+
+      <para>SYSTEM_PROPERTIES</para>
+
+      <para>SYSTEM_SCHEMAS</para>
+
+      <para>SYSTEM_SEQUENCES</para>
+
+      <para>SYSTEM_SESSIONINFO</para>
+
+      <para>SYSTEM_SESSIONS</para>
+
+      <para>SYSTEM_TABLES</para>
+
+      <para>SYSTEM_TABLETYPES</para>
+
+      <para>SYSTEM_TEXTTABLES</para>
+
+      <para>SYSTEM_TYPEINFO</para>
+
+      <para>SYSTEM_UDTS</para>
+
+      <para>SYSTEM_USERS</para>
+
+      <para>SYSTEM_VERSIONCOLUMNS</para>
+    </section>
+  </section>
+</chapter>
diff --git a/doc-src/guide/dbfiles-app.xml b/doc-src/guide/dbfiles-app.xml
new file mode 100644
index 0000000..9520559
--- /dev/null
+++ b/doc-src/guide/dbfiles-app.xml
@@ -0,0 +1,239 @@
+<!-- $Id: dbfiles-app.xml 847 2009-01-19 22:24:49Z unsaved $ -->
+
+<appendix>
+
+<title>Hsqldb Database Files and Recovery</title>
+<appendixinfo>
+    <releaseinfo>$Revision: 847 $</releaseinfo>
+    <pubdate>$Date: 2009-01-19 17:24:49 -0500 (Mon, 19 Jan 2009) $</pubdate>
+    <keywordset>
+        <keyword>HSQLDB</keyword>
+        <keyword>Data</keyword>
+        <keyword>Files</keyword>
+    </keywordset>
+    <legalnotice><para>
+        This text is based on HypersonicSQL documentation, updated to reflect 
+        the latest version 1.8.0 of HSQLDB.
+    </para></legalnotice>
+</appendixinfo>
+
+<section>
+    <para>
+        The Standalone and Client/Server modes will in most cases use files to 
+        store all data to disk in a persistent and safe way.
+        This document describes the meaning of the files, the states and the 
+        procedures followed by the engine to recover the data.
+    </para> <para>
+        A database named 'test' is used in this description.
+        The database files will be as follows.
+    </para>
+</section>
+
+<variablelist>
+    <title>Database Files</title>
+    <varlistentry><term>test.properties</term><listitem><para>
+        Contains the entry 'modified'.
+        If the entry 'modified' is set to 'yes' then the database is either 
+        running or was not closed correctly (because the close algorithm sets 
+        'modified' to 'no' at the end).
+        </para></listitem>
+    </varlistentry>
+    <varlistentry><term>test.script</term><listitem><para>
+        This file contains the SQL statements that makes up the database up to 
+        the last checkpoint - it is in synch with
+        <filename>test.backup</filename>.
+        </para></listitem>
+    </varlistentry>
+    <varlistentry><term>test.data</term><listitem><para>
+        This file contains the (binary) data records for CACHED tables only.
+        </para></listitem>
+    </varlistentry>
+    <varlistentry><term>test.backup</term><listitem><para>
+        This is compressed file that contains the complete backup of the old 
+        <filename>test.data</filename> file at the time of last checkpoint.
+        </para></listitem>
+    </varlistentry>
+    <varlistentry><term>test.log</term><listitem><para>
+        This file contains the extra SQL statements that have modified the 
+        database since the last checkpoint (something like the 'Redo-log' or 
+        'Transaction-log', but just text).
+        </para><para>
+        In the above list, a checkpoint results from both a CHECKPOINT command 
+        and a SHUTDOWN command.
+        </para></listitem>
+    </varlistentry>
+</variablelist>
+
+<section>
+    <title>States</title>
+    <section>Database is closed correctly</section>
+    <itemizedlist>
+        <title>State after using the command <literal>SHUTDOWN</literal></title>
+        <listitem><para>
+            The <filename>test.data</filename> file is fully updated.
+        </para></listitem> <listitem><para>
+            The <filename>test.backup</filename> contains the compressed 
+            <filename>test.data</filename> file.
+        </para></listitem> <listitem><para>
+            The  <filename>test.script</filename> contains the information in 
+            the database, excluding data for CACHED and TEXT tables. 
+        </para></listitem> <listitem><para>
+            The <filename>test.properties</filename> contains the entry 
+            'modified'  set to 'no'.
+        </para></listitem> <listitem><para>
+            There is no <filename>test.log</filename> file.
+        </para></listitem>
+    </itemizedlist>
+    <section>Database is closed correctly with SHUTDOWN SCRIPT</section>
+    <itemizedlist>
+        <title>State after using the command <literal>SHUTDOWN SCRIPT</literal></title>
+        <listitem><para>
+            The <filename>test.data</filename> file does not exist; all CACHED 
+            table data is in the <filename>test.script</filename> file
+        </para></listitem> <listitem><para>
+            The <filename>test.backup</filename> does not exist.
+        </para></listitem> <listitem><para>
+            The  <filename>test.script</filename> contains the information in 
+            the database, including data for CACHED and TEXT tables.
+        </para></listitem> <listitem><para>
+            The <filename>test.properties</filename> contains the entry 
+            'modified'  set to 'no'.
+        </para></listitem> <listitem><para>
+            There is no <filename>test.log</filename> file.
+        </para></listitem>
+    </itemizedlist>
+    <section>Database is aborted</section>
+    <para>
+        This may happen by sudden power off, Ctrl+C in Windows, but may be 
+        simulated using the command SHUTDOWN IMMEDIATELY.
+    </para>
+    <itemizedlist>
+        <title>Aborted Database state</title>
+        <listitem><para>
+            The <filename>test.properties</filename> still containes 
+            'modified=yes'.
+        </para></listitem> <listitem><para>
+            The <filename>test.script</filename> contains a snapshot of the 
+            database at the last checkpoint and is OK.
+        </para></listitem> <listitem><para>
+            The <filename>test.data</filename> file may be corrupt because the 
+            cache in memory was not written out completely.
+        </para></listitem> <listitem><para>
+            The <filename>test.backup</filename> file contains a snapshot of 
+            <filename>test.data</filename> that corresponds to 
+            <filename>test.script</filename>.
+        </para></listitem> <listitem><para>
+            The  <filename>test.log</filename> file contain all information to 
+            re-do all changes since the snanapshot.
+            As a result of abnormal termination, this file may be partially 
+            corrupt.
+        </para></listitem>
+    </itemizedlist>
+</section>
+
+<section>
+    <title>Procedures</title>
+    <para>
+        The database engine performs the following procedures internally in 
+        different circumstances. 
+    </para>
+    <section><title>Clean Shutdown</title>
+        <procedure>
+            <title>Clean Hsqldb database shutdown</title>
+            <step><para>
+                The <filename>test.data</filename> file is written completely 
+                (all the modified cached table rows are witten out) and closed.
+            </para></step> <step><para>
+                The <filename>test.backup.new</filename> is created (containing 
+                the compressed <filename>test.data</filename> file)
+            </para></step> <step><para>
+                The file <filename>test.script.new</filename> is created using 
+                the information in the database (and thus shrinks because no 
+                UPDATE and DELETE statements; only INSERT).
+            </para></step> <step><para>
+                The entry 'modified' in the properties file is set to 
+                'yes-new-files'
+            </para></step> <step><para>
+                The file <filename>test.script</filename> is deleted
+            </para></step> <step><para>
+                The file <filename>test.script.new</filename> is renamed to 
+                <filename>test.script</filename>
+            </para></step> <step><para>
+                The file <filename>test.backup</filename> is deleted
+            </para></step> <step><para>
+                The file <filename>test.backup.new</filename> is renamed to 
+                <filename>test.backup</filename>
+            </para></step> <step><para>
+                The entry 'modified' in the properties file is set to 'no' 
+            </para></step> <step><para>
+                The file <filename>test.log</filename> is deleted
+            </para></step>
+        </procedure>
+    </section>
+    <section><title>Startup</title>
+        <procedure>
+            <title>Database is opened</title>
+            <step><para>
+                Check if the database files are in use (by checking a special 
+                <filename>test.lck</filename> file).
+            </para></step> <step><para>
+                See if the <filename>test.properties</filename> file exists,
+                otherwise create it.
+            </para></step> <step><para>
+                If the <filename>test.properties</filename> did not exist, then 
+                this is a new database.
+                Create the empty <filename>test.log</filename> to append new 
+                commands.
+            </para></step> <step><para>
+                If it is an existing database, check in the
+                <filename>test.properties</filename> file if 'modified=yes'.
+                This would mean last time it was not closed correctly, and thus 
+                the <filename>test.data</filename> file may be corrupted or 
+                incomplete.
+                In this case the 'REPAIR' algorithm is executed (see below), 
+                before the database is opened normally.
+            </para></step> <step><para>
+                Otherwise, if in the <filename>test.properties</filename> file
+                'modified=yes-new-files', then the (old) 
+                <filename>test.backup</filename> and 
+                <filename>test.script</filename> files are deleted and the new 
+                <filename>test.script.new</filename> file is renamed to 
+                <filename>test.script</filename>.
+                </para></step> <step><para>
+                Open the <filename>test.script</filename> file and execute the 
+                commands.
+            </para></step> <step><para>
+                Create the empty test.log to append new commands.
+            </para></step>
+        </procedure>
+    </section>
+    <section><title>Repair</title>
+        <para>
+            The current <filename>test.data</filename> file is corrupt, but 
+            with the old <filename>test.data</filename> (from the 
+            <filename>test.backup</filename> file and 
+            <filename>test.script</filename>) and the current 
+            <filename>test.log</filename>, the database is made up-to-date.
+            The database engine takes these steps:
+        </para>
+        <procedure>
+            <title>Database Repair</title>
+            <step><para>
+                    Restore the old <filename>test.data</filename> file from 
+                    the backup (uncompress the <filename>test.backup</filename>
+                    and overwrite <filename>test.data</filename>).
+            </para></step><step><para>
+                Execute all commands in the <filename>test.script</filename> 
+                file.
+            </para></step><step><para>
+                Execute all commands in the <filename>test.log</filename> file.
+                If due to corruption, an exception is thrown, the rest of the 
+                lines of command in the <filename>test.log</filename> file are 
+                ignored.
+            </para></step><step><para>
+                Close the database correctly (including a backup).
+            </para></step>
+        </procedure>
+    </section>
+</section>
+</appendix>
diff --git a/doc-src/guide/dbproperties.xml b/doc-src/guide/dbproperties.xml
new file mode 100644
index 0000000..47b552b
--- /dev/null
+++ b/doc-src/guide/dbproperties.xml
@@ -0,0 +1,953 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: dbproperties.xml 3626 2010-06-05 11:49:07Z fredt $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<chapter version="5.0" xml:id="dbproperties-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <title xml:id="dbproperties-title">Properties</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3626 $</releaseinfo>
+
+    <pubdate>$Date: 2010-06-05 07:49:07 -0400 (Sat, 05 Jun 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2002-2009 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section xml:id="dbproperties_connections-sect">
+    <title>Connections</title>
+
+    <para>The normal method of accessing a HyperSQL catalog is via the JDBC
+    Connection interface. An introduction to different methods of providing
+    database services and accessing them can be found in the <link
+    endterm="sqlgeneral-title" xlink:href="#sqlgeneral-chapt"></link> chapter.
+    Details and examples of how to connect via JDBC are provided in our
+    JavaDoc for <classname xlink:href="#JDBCConnection.html-link">
+    JDBCConnection</classname>.</para>
+
+    <para>A uniform method is used to distinguish between different types of
+    connection. The common driver identifier is
+    <literal>jdbc:hsqldb:</literal> followed by a protocol identifier
+    (<literal>mem: file: res: hsql: http: hsqls: https:</literal>) then
+    followed by host and port identifiers in the case of servers, then
+    followed by database identifier. Additional property / value pairs can be
+    appended to the end of the URL, separated with semicolons.</para>
+
+    <table frame="all" pgwide="1" tocentry="1">
+      <title>HyperSQL URL Components</title>
+
+      <tgroup align="left" cols="3">
+        <colspec colname="c1" />
+
+        <colspec colname="c2" />
+
+        <colspec colname="c3" />
+
+        <thead>
+          <row>
+            <entry>Driver and Protocol</entry>
+
+            <entry>Host and Port</entry>
+
+            <entry>Database</entry>
+          </row>
+        </thead>
+
+        <tbody valign="top">
+          <row>
+            <entry><simplelist type="vert">
+                <member><literal>jdbc:hsqldb:mem:</literal></member>
+              </simplelist></entry>
+
+            <entry>not available</entry>
+
+            <entry><simplelist type="vert">
+                <member><literal>accounts</literal></member>
+              </simplelist></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>Lowercase, single-word
+            identifier creates the in-memory database when the first
+            connection is made. Subsequent use of the same Connection URL
+            connects to the existing DB.</para> <para>The old form for the
+            URL, <literal>jdbc:hsqldb:.</literal> creates or connects to the
+            same database as the new form for the URL,
+            <literal>jdbc:hsqldb:mem:.</literal></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><simplelist type="vert">
+                <member><literal>jdbc:hsqldb:file:</literal></member>
+              </simplelist></entry>
+
+            <entry>not available</entry>
+
+            <entry><simplelist type="vert">
+                <member><filename>mydb</filename></member>
+
+                <member><filename>/opt/db/accounts</filename></member>
+
+                <member><filename>C:/data/mydb</filename></member>
+              </simplelist></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>The file path specifies the
+            database file. In the above examples the first one refers to a set
+            of mydb.* files in the directory where the
+            <literal>java</literal>command for running the application was
+            issued. The second and third examples refer to absolute paths on
+            the host machine.</para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><simplelist type="vert">
+                <member><literal>jdbc:hsqldb:res:</literal></member>
+              </simplelist></entry>
+
+            <entry>not available</entry>
+
+            <entry><simplelist type="vert">
+                <member><filename>/adirectory/dbname</filename></member>
+              </simplelist></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1">Database files can be loaded from
+            one of the jars specified as part of the <literal>Java</literal>
+            command the same way as resource files are accessed in Java
+            programs. The <literal>/adirectory</literal> above stands for a
+            directory in one of the jars.</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><simplelist type="vert">
+                <member><literal>jdbc:hsqldb:hsql:</literal></member>
+
+                <member><literal>jdbc:hsqldb:hsqls:</literal></member>
+
+                <member><literal>jdbc:hsqldb:http:</literal></member>
+
+                <member><literal>jdbc:hsqldb:https:</literal></member>
+              </simplelist></entry>
+
+            <entry><simplelist type="vert">
+                <member><literal>//localhost</literal></member>
+
+                <member><literal>//192.0.0.10:9500</literal></member>
+
+                <member><literal>//dbserver.somedomain.com</literal></member>
+              </simplelist></entry>
+
+            <entry><simplelist type="vert">
+                <member><literal>/an_alias</literal></member>
+
+                <member><literal>/enrollments</literal></member>
+
+                <member><literal>/quickdb</literal></member>
+              </simplelist></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>The host and port specify
+            the IP address or host name of the server and an optional port
+            number. The database to connect to is specified by an alias. This
+            alias is a lowercase string defined in the
+            <filename>server.properties</filename> file to refer to an actual
+            database on the file system of the server or a transient,
+            in-memory database on the server. The following example lines in
+            <filename>server.properties</filename> or
+            <filename>webserver.properties</filename> define the database
+            aliases listed above and accessible to clients to refer to
+            different file and in-memory databases.</para> <para>The old form
+            for the server URL, e.g.,
+            <literal>jdbc:hsqldb:hsql//localhost</literal> connects to the
+            same database as the new form for the URL,
+            <literal>jdbc:hsqldb:hsql//localhost/</literal> where the alias is
+            a zero length string.</para></entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <section xml:id="conn_props-sect">
+      <title>Connection properties</title>
+
+      <para>Each JDBC Connection to a database can specify connection
+      properties. The properties <property>user</property> and
+      <property>password</property> are always required. In 2.0 the following
+      optional properties can also be used.</para>
+
+      <para>Connection properties are specified either by establishing the
+      connection via the method call below, or the property can be appended to
+      the full Connection URL.</para>
+
+      <programlisting>    DriverManager.getConnection (String url, Properties info);</programlisting>
+
+      <table frame="all" pgwide="1" tocentry="1">
+        <title>Connection Properties</title>
+
+        <tgroup align="left" cols="3">
+          <colspec colname="c1" colwidth="7cm" />
+
+          <colspec colname="c2" colwidth="1.5cm" />
+
+          <colspec colname="c3" />
+
+          <tbody valign="top">
+            <row>
+              <entry><property>get_column_name</property></entry>
+
+              <entry><literal>true</literal></entry>
+
+              <entry>column name in ResultSet</entry>
+            </row>
+
+            <row>
+              <entry nameend="c3" namest="c1"><para>This property is used for
+              compatibility with other JDBC driver implementations. When true
+              (the default), <methodname>ResultSet.getColumnName(int
+              c)</methodname> returns the underlying column name. This
+              property can be specified differently for different connections
+              to the same database.</para><para>The default is true. When the
+              property is false, the above method returns the same value as
+              <methodname>ResultSet.getColumnLabel(int column)</methodname>
+              Example below:</para><programlisting>    jdbc:hsqldb:hsql://localhost/enrollments;get_column_name=false</programlisting><para>When
+              a ResultSet is used inside a user-defined stored procedure, the
+              default, true, is always used for this property.</para></entry>
+            </row>
+
+            <row>
+              <entry nameend="c3" namest="c1"></entry>
+            </row>
+
+            <row>
+              <entry><property>ifexists</property></entry>
+
+              <entry><literal>false</literal></entry>
+
+              <entry>connect only if database already exists</entry>
+            </row>
+
+            <row>
+              <entry nameend="c3" namest="c1"><para>Has an effect only with
+              <glossterm>mem:</glossterm> and <glossterm>file:</glossterm>
+              database. When true, will not create a new database if one does
+              not already exist for the URL.</para><para>When the property is
+              false (the default), a new <glossterm>mem:</glossterm> or
+              <glossterm>file:</glossterm> database will be created if it does
+              not exist.</para> <para>Setting the property to true is useful
+              when troubleshooting as no database is created if the URL is
+              malformed. Example below:</para> <programlisting>    jdbc:hsqldb:file:enrollments;ifexists=true</programlisting></entry>
+            </row>
+
+            <row>
+              <entry nameend="c3" namest="c1"></entry>
+            </row>
+
+            <row>
+              <entry><property>shutdown</property></entry>
+
+              <entry><literal>false</literal></entry>
+
+              <entry>shut down the database when the last connection is
+              closed</entry>
+            </row>
+
+            <row>
+              <entry nameend="c3" namest="c1"><para>If this property is
+              <literal>true</literal>, when the last connection to a database
+              is closed, the database is automatically shut down. The property
+              takes effect only when the first connection is made to the
+              database. This means the connection that opens the database. It
+              has no effect if used with subsequent connections.</para>
+              <para>This command has two uses. One is for test suites, where
+              connections to the database are made from one JVM context,
+              immediately followed by another context. The other use is for
+              applications where it is not easy to configure the environment
+              to shutdown the database. Examples reported by users include web
+              application servers, where the closing of the last connection
+              coincides with the web app being shut
+              down.</para><programlisting>    jdbc:hsqldb:file:enrollments;shutdown=true</programlisting></entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+
+      <para>In addition, when a connection to an
+      <glossterm>in-process</glossterm> database creates a new database, or
+      opens an existing database (i.e. it is the first connection made to the
+      database by the application), all the user-defined database properties
+      can be specified as URL properties. This can be used to specify
+      properties to enforce more strict SQL adherence, or to change
+      cache_scale or similar properties before the database files are created.
+      However, for new databases, it is recommended to use the SET PROPERTY
+      command for such settings.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Database Properties in Connection URL and Properties</title>
+
+    <para>The database engine has several properties that are listed in the
+    <link endterm="deployment-title" xlink:href="#deployment-chapt"></link>
+    chapter. These properties can be changed via SQL commands after a
+    connection is made to the database. It is possible to specify all of these
+    properties in the connection properties on as part of the URL string when
+    the first connection is made to a new file: or mem: database. This allows
+    the properties to be set without using any SQL commands. The corresponding
+    SQL command is given for each property.</para>
+
+    <para>Management of properties has changed since version 1.8. The old SET
+    PROPERTY does not change a property and is retained to simplify
+    application upgrades.</para>
+
+    <para>In the example URL below, two properties are set for the first
+    connection to a new database. If the properties are used for connection to
+    an existing database, they are ignored.</para>
+
+    <programlisting>    jdbc:hsqldb:file:enrollments;hsqldb.cache_rows=10000;hsqldb.nio_data_file=false</programlisting>
+
+    <para>In the table below, database properties that can be used as part of
+    the URL below are given. For each property that can also be set with an
+    SQL statement, the statement is also given. These statements are described
+    in the <link endterm="deployment-title"
+    xlink:href="#deployment-chapt"></link> chapter.</para>
+
+    <table frame="all" pgwide="1" tocentry="1">
+      <title>Database-specific Property File Properties</title>
+
+      <tgroup align="left" cols="3">
+        <colspec colname="c1" colwidth="6.5cm" />
+
+        <colspec colname="c2" colwidth="1.5cm" />
+
+        <colspec colname="c3" />
+
+        <thead>
+          <row>
+            <entry>Value</entry>
+
+            <entry>Default</entry>
+
+            <entry>Description</entry>
+          </row>
+        </thead>
+
+        <tbody valign="top">
+          <row>
+            <entry><property>check_props</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>checks the validity of the connection properties</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>If the property is true,
+            every database property that is specified on the URL or in
+            connection properties is checked and if it is not used correctly,
+            an error is returned</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>crypt_lobs</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>encryption of lobs</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>If the property is true, the
+            contents of the .lobs file is encrypted as
+            well.</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>crypt_key</property></entry>
+
+            <entry><literal>none</literal></entry>
+
+            <entry>encryption</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>The cipher key for an
+            encrypted database</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>crypt_provider</property></entry>
+
+            <entry><literal>none</literal></entry>
+
+            <entry>encryption</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>The fully-qualified class
+            name of the cryptography provider. This property is not used for
+            the default security provider.</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>crypt_type</property></entry>
+
+            <entry><literal>none</literal></entry>
+
+            <entry>encryption</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>The cipher
+            specification.</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>read_only</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>readonly database</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>This property is a special
+            property that can be added manually to the .properties file, or
+            included in the URL or connection properties. When this property
+            is true, the database becomes
+            readonly.</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry><property>files_read_only</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>readonly files database</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>This property is used
+            similarly to the hsqldb.read_only property. When this property is
+            true, CACHED and TEXT tables are readonly but memory files are
+            not. Any change to the data is not persisted to database
+            files.</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.log_data</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>recovery log</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>This property can be set to
+            false when database recovery in the event of an unexpected crash
+            is not necessary. A database that is used as a temporary cache is
+            an example. Regardless of the value of this property, if there is
+            a proper shutdown of the database, all the change data is
+            stored.</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>sql.enforce_names</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>enforcing SQL keywords</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>This property, when set
+            true, prevents SQL keywords being used for database object names
+            such as columns and tables.</para><para><programlisting>SET DATABASE SQL NAMES { TRUE | FALSE }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>sql.enforce_size</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>trimming and padding string columns.</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>This property is the same as
+            sql.enforce_strict_size</para></entry>
+          </row>
+
+          <row>
+            <entry><property>sql.enforce_strict_size</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>size enforcement and padding string columns</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>Conforms to SQL standards
+            for size and precision of data types. When true, all CHARACTER,
+            VARCHAR, NUMERIC and DECIMAL values that are in a row affected by
+            an INSERT INTO or UPDATE statement are checked against the size
+            specified in the SQL table definition. An exception is thrown if
+            the value is too long. Also all CHARACTER values that are shorter
+            than the specified size are padded with
+            spaces.</para><para><programlisting>SET DATABASE SQL SIZE { TRUE | FALSE }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>sql.enforce_refs</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>enforcing column reference disambiguation</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>This property, when set
+            true, causes an error when an SQL statements contains column
+            references that can be resovled by more than one table name or
+            alias. In effect forces such column references to have a table
+            name or table alias qualifier.</para><para><programlisting>SET DATABASE SQL REFERENCES { TRUE | FALSE }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>runtime.gc_interval</property></entry>
+
+            <entry><literal>0</literal></entry>
+
+            <entry>forced garbage collection</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>This setting forces garbage
+            collection each time a set number of result set row or cache row
+            objects are created. The default, "0" means no garbage collection
+            is forced by the program.</para><para><programlisting>SET DATABASE GC &lt;numeric value&gt;</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.default_table_type</property></entry>
+
+            <entry><literal>memory</literal></entry>
+
+            <entry>type of table created with unqualified CREATE TABLE</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>The CREATE TABLE command
+            results in a MEMORY table by default. Setting the value
+            <emphasis>cached</emphasis> for this property will result in a
+            cached table by default. The qualified forms such as CREATE MEMORY
+            TABLE or CREATE CACHED TABLE are not affected at all by this
+            property.</para><para><programlisting>SET DATABASE DEFAULT TABLE TYPE { CACHED | MEMORY }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.applog</property></entry>
+
+            <entry><literal>0</literal></entry>
+
+            <entry>application logging level</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>The default level 0
+            indicates no logging. Level 1 results in events related to
+            persistence to be logged, including any failures. Level 2
+            indicates all events, including ordinary events. The events are
+            logged in a file ending with
+            ".app.log".</para><para><programlisting>SET DATABASE EVENT LOG LEVEL { 0 | 1 | 2 }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.result_max_memory_rows</property></entry>
+
+            <entry><literal>0</literal></entry>
+
+            <entry>amount of result rows that are kept in memory</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>Sets the maximum number of
+            rows of each result set and other internal temporary table that is
+            held in memory. </para><para><programlisting>SET DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned integer literal&gt;</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.tx</property></entry>
+
+            <entry><literal>locks</literal></entry>
+
+            <entry>database transaction control mode</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>Indicates the transaction
+            control mode for the database. The values, locks, mvlocks and mvcc
+            are allowed.</para><para><programlisting>SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.cache_rows</property></entry>
+
+            <entry><literal>50000</literal></entry>
+
+            <entry>maximum number of rows in memory cache</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>Indicates the maximum number
+            of rows of cached tables that are held in memory.</para><para>The
+            value can range between 100-1,000,000. If the value is set via SET
+            FILES then it becomes effective after the next database SHUTDOWN
+            or CHECKPOINT.</para><para>The property is changed via the
+            <literal>SET FILES CACHE ROWS nnn</literal> SQL
+            command.</para><para><programlisting>SET FILES CACHE ROWS &lt;numeric value&gt;</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.cache_size</property></entry>
+
+            <entry><literal>10000</literal></entry>
+
+            <entry>memory cache size</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>Indicates the total size (in
+            kilobytes) of rows in the memory cache used with cached tables.
+            This size is calculated as the binary size of the rows, for
+            example an INTEGER is 4 bytes. The actual memory size used by the
+            objects is 2 to 4 times this value. This depends on the types of
+            objects in database rows, for example with binary objects the
+            factor is less than 2, with character strings, the factor is just
+            over 2 and with date and timestamp objects the factor is over
+            3.</para><para>The value can range between 100-1,000,000. The
+            default is 10,000, representing 10,000 kilobytes. If the value is
+            set via SET FILES then it becomes effective after the next
+            database SHUTDOWN or CHECKPOINT.</para><para><programlisting>SET FILES CACHE SIZE &lt;numeric value&gt;</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.inc_backup</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>incremental backup of data file</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>During updates, the contents
+            of the .data file are modified. When this property is true, the
+            modified contents are backed up gradually. This causes a marginal
+            slowdown in operations, but allows fast checkpoint and
+            shutdown.</para><para>When the property is false, the .data file
+            is backed up entirely at the time of checkpoint and shutdown. Up
+            to version 1.8, HSQLDB supported only full
+            backup.</para><para><programlisting>SET FILES INCREMENT BACKUP { TRUE | FALSE }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.lock_file</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>use of lock file</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>By default, a lock file is
+            created for each file database that is opened for read and write.
+            This property can be specified with the value false to prevent the
+            lock file from being created. This usage is not recommended but
+            may be desirable when flash type storage is
+            used.</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.log_data</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>logging data change</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>When
+            <literal>false</literal> is specified, no data logging takes
+            place. A checkpoint or shutdown still rewrites the
+            <literal>.script</literal> file and saves the
+            <literal>.backup</literal> file according to the other
+            settings.</para><para><programlisting>SET FILES LOG  { TRUE | FALSE }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.log_size</property></entry>
+
+            <entry><literal>50</literal></entry>
+
+            <entry>size of log when checkpoint is performed</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>The value is the size (in
+            megabytes) that the <literal>.log</literal> file can reach before
+            an automatic checkpoint occurs. A checkpoint rewrites the
+            <literal>.script</literal> file and clears the
+            <literal>.log</literal> file.</para><para><programlisting>SET FILES LOG SIZE &lt;numeric value&gt;</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.nio_data_file</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>use of nio access methods for the .data file</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>When HyperSQL is compiled
+            and run in Java 1.4 or higher, setting this property to
+            <literal>false</literal> will avoid the use of nio access methods,
+            resulting in somewhat reduced speed. If the data file is larger
+            than 256MB when it is first opened, nio access methods are not
+            used. Also, if the file gets larger than the amount of available
+            computer memory that needs to be allocated for nio access, non-nio
+            access methods are used.</para><para>If used before defining any
+            CACHED table, it applies immediately, otherwise it comes into
+            effect after a SHUTDOWN and restart or
+            CHECKPOINT.</para><para><programlisting>SET FILES NIO { TRUE | FALSE }</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.translate_dti_types</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>usage of type codes for advanced type datetime
+            types</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>If the property is true, the
+            datetime WITH TIME ZONE types and INTERVAL types are represented
+            as JDBC datetime types without time zone and the VARCHAR type
+            respectively.</para><para><programlisting>this property cannot be set with an SQL statement</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.write_delay</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>write delay for writing log file entries</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>If the property is true, the
+            default WRITE DELAY property of the database is used, which is
+            1000 milliseconds. If the property is false, the WRITE DELAY is
+            set to 0 seconds. The SQL command for this property allows more
+            precise control over the property.</para><para><programlisting>SET FILES WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds value&gt; MILLIS</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>hsqldb.write_delay_millis</property></entry>
+
+            <entry><literal>1000</literal></entry>
+
+            <entry>write delay for writing log file entries</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>If the property is used, the
+            WRITE DELAY property of the database is set the given value. The
+            SQL command for this property allows the same level of control
+            over the property.</para><para><programlisting>SET FILES WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds value&gt; MILLIS</programlisting></para></entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"></entry>
+          </row>
+
+          <row>
+            <entry><property>textdb.*</property></entry>
+
+            <entry><literal>0</literal></entry>
+
+            <entry>default properties for new text tables</entry>
+          </row>
+
+          <row>
+            <entry nameend="c3" namest="c1"><para>Properties that override the
+            database engine defaults for newly created text tables. Settings
+            in the text table <literal>SET &lt;tablename&gt; SOURCE &lt;source
+            string&gt; </literal>command override both the engine defaults and
+            the database properties defaults. Individual
+            <property>textdb.*</property> properties are listed in the <link
+            endterm="texttables-title" xlink:href="#texttables-chapt"></link>
+            chapter.</para></entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <para>When connecting to an <glossterm>in-process</glossterm> database
+    creates a new database, or opens an existing database (i.e. it is the
+    first connection made to the database by the application), all the
+    user-defined database properties listed in this section can be specified
+    as URL properties.</para>
+
+    <simpara>When HSQLDB is used in OpenOffice.org, some property values will
+    have a different default. The properties and values are:</simpara>
+
+    <simpara>hsqldb.default_table_type=cached hsqldb.cache_rows=25000;
+    hsqldb.cache_size=6000; hsqldb.log_size=10; hsqldb.nio_data_file=false;
+    sql.enforce_strict_size=true</simpara>
+  </section>
+</chapter>
diff --git a/doc-src/guide/deployment.xml b/doc-src/guide/deployment.xml
new file mode 100644
index 0000000..20e582d
--- /dev/null
+++ b/doc-src/guide/deployment.xml
@@ -0,0 +1,1804 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="deployment-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="deployment-title">System Management and Deployment
+  Issues</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3630 $</releaseinfo>
+
+    <pubdate>$Date: 2010-06-06 10:44:27 -0400 (Sun, 06 Jun 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section xml:id="deploymen_modes-sect">
+    <title>Mode of Operation and Tables</title>
+
+    <para>HyperSQL has many modes of operation and features that allow it to
+    be used in very different scenarios. Levels of memory usage, speed and
+    accessibility by different applications are influenced by how HyperSQL is
+    deployed.</para>
+
+    <section>
+      <title>Mode of Operation</title>
+
+      <para>The decision to run HyperSQL as a separate server process or as an
+      <glossterm>in-process</glossterm> database should be based on the
+      following:</para>
+
+      <para><itemizedlist>
+          <listitem>
+            <para>When HyperSQL is run as a server on a separate machine, it
+            is isolated from hardware failures and crashes on the hosts
+            running the application.</para>
+          </listitem>
+
+          <listitem>
+            <para>When HyperSQL is run as a server on the same machine, it is
+            isolated from application crashes and memory leaks.</para>
+          </listitem>
+
+          <listitem>
+            <para>Server connections are slower than
+            <glossterm>in-process</glossterm> connections due to the overhead
+            of streaming the data for each JDBC call.</para>
+          </listitem>
+
+          <listitem>
+            <para>You can reduce client/server traffic using SQL Stored
+            procedures to reduce the number of JDBC execute calls.</para>
+          </listitem>
+
+          <listitem>
+            <para>During development, it is better to use a Server with
+            server.silent=false, which displays the statements sent to the
+            server on the console window.</para>
+          </listitem>
+
+          <listitem>
+            <para>To improve speed of execution for statements that are
+            executed repeatedly, reuse a parameterized PreparedStatement for
+            the lifetime of the connections.</para>
+          </listitem>
+        </itemizedlist></para>
+    </section>
+
+    <section>
+      <title>Tables</title>
+
+      <para>TEXT tables are designed for special applications where the data
+      has to be in an interchangeable format, such as CSV (comma separated
+      values). TEXT tables should not be used for routine storage of
+      data.</para>
+
+      <para>MEMORY tables and CACHED tables are generally used for data
+      storage. The difference between the two is as follows:</para>
+
+      <para><itemizedlist>
+          <listitem>
+            <para>The data for all MEMORY tables is read from the *.script
+            file when the database is started and stored in memory. In
+            contrast the data for cached tables is not read into memory until
+            the table is accessed. Furthermore, only part of the data for each
+            CACHED table is held in memory, allowing tables with more data
+            than can be held in memory.</para>
+          </listitem>
+
+          <listitem>
+            <para>When the database is shutdown in the normal way, all the
+            data for MEMORY tables is written out to the disk. In comparison,
+            the data in CACHED tables that has changed is written out during
+            operation and at shutdown.</para>
+          </listitem>
+
+          <listitem>
+            <para>The size and capacity of the data cache for all the CACHED
+            tables is configurable. This makes it possible to allow all the
+            data in CACHED tables to be cached in memory. In this case, speed
+            of access is good, but slightly slower than MEMORY tables.</para>
+          </listitem>
+
+          <listitem>
+            <para>For normal applications it is recommended that MEMORY tables
+            are used for small amounts of data, leaving CACHED tables for
+            large data sets. For special applications in which speed is
+            paramount and a large amount of free memory is available, MEMORY
+            tables can be used for large tables as well.</para>
+          </listitem>
+        </itemizedlist></para>
+    </section>
+
+    <section>
+      <title>Large Objects</title>
+
+      <para>HyperSQL 2.0 supports dedicated storage and access to BLOB and
+      CLOB objects. These objects can have huge sizes. BLOB or CLOB is
+      specified as the type of a column of the table. Afterwards, rows can be
+      inserted into the table using a PreparedStatement for efficient transfer
+      of large LOB data to the database. In <glossterm>mem:</glossterm>
+      catalogs, CLOB and BLOB data is stored in memory. In
+      <glossterm>file:</glossterm> catalogs, this data is stored in a single
+      separate file which has the extension *.lobs. The size of this file can
+      grow to huge, terabyte figures.</para>
+
+      <para>LOB data should be store in the database using a JDBC
+      PreparedStatement object. The streaming methods send the LOB to the
+      database in one operation as a binary or character stream. Inside the
+      database, the disk space is allocated as needed and the data is saved as
+      it is being received. LOB data should be retrieved from the database
+      using a JDBC ResultSet method. When a streaming method is used to
+      retrieve a LOB, it is retrieved in large chunks in a transparent manner.
+      LOB data can also be stored by calling a JDBC method with String or
+      byte[] argument, but these methods limit the size of the LOB that can be
+      stored or retrieved.</para>
+
+      <para>LOB data is not duplicated in the database when a lob is copied
+      from one table to another. The disk space is reused when a LOB is
+      deleted and is not contained in any table.</para>
+
+      <para>By using a dedicated LOB store, HyperSQL achieves consistently
+      high speeds (usually over 20MB / s) for both storage and retrieval of
+      LOBs.</para>
+
+      <para>The LOB catalog is stored in the database as a memory table.
+      Therefore the amount of JVM memory should be increased when more than
+      tens of thousands of LOBs are stored in the database.</para>
+    </section>
+
+    <section>
+      <title>Deployment context</title>
+
+      <para>The files used for storing HyperSQL database data are all in the
+      same directory. New files are always created and deleted by the database
+      engine. Two simple principles must be observed:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>The Java process running HyperSQL must have full privileges on
+          the directory where the files are stored. This include create and
+          delete privileges.</para>
+        </listitem>
+
+        <listitem>
+          <para>The file system must have enough spare room both for the
+          'permanent' and 'temporary' files. The default maximum size of the
+          *.log file is 50MB. The *.data file can grow to up to 16GB (more if
+          the default has been increased). The .backup file can be up to the
+          size of the *.data file. The *.lobs file can grow to several
+          terabytes. The temporary files created at the time of a SHUTDOWN can
+          be equal in size to the *.script file and the .data file.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section>
+      <title>Readonly Databases</title>
+
+      <para>A <glossterm>file:</glossterm> catalog can be made readonly
+      permanently, or it can be opened as readonly. To make the database
+      readonly, the property, value pair, readonly=true can be added to the
+      .properties file of the database.</para>
+
+      <para>It is also possible to open a normal database as readonly. For
+      this, the property can be included in the URL of the first connection to
+      the database.</para>
+
+      <para>There is another option which allows MEMORY tables to be writable,
+      but without persisting the changes at SHUTDOWN. This option is activated
+      with the property, value pair, files_readonly= true, which can be added
+      to the .properties file of the database, or included in the URL of the
+      first connection to the database. This option is useful for running
+      application tests which operate on a predefined dataset.</para>
+    </section>
+  </section>
+
+  <section xml:id="deployment_mem_disk-sect">
+    <title>Memory and Disk Use</title>
+
+    <indexterm significance="preferred">
+      <primary>memory use</primary>
+    </indexterm>
+
+    <para>Memory used by the program can be thought of as two distinct pools:
+    memory used for table data which is not released unless the data is
+    deleted and memory that can be released or is released automatically,
+    including memory used for caching, building result sets and other internal
+    operations such as storing the information needed for a rollback a
+    transaction.</para>
+
+    <para>Most JVM implementations allocate up to a maximum amount of memory
+    (usually 64 MB by default). This amount is generally not adequate when
+    large memory tables are used, or when the average size of rows in cached
+    tables is larger than a few hundred bytes. The maximum amount of allocated
+    memory can be set on the Java command line that is used for running
+    HyperSQL. For example, with Sun JVM, parameter -Xmx256m increases the
+    amount to 256 MB.</para>
+
+    <section>
+      <title>Table Memory Allocation</title>
+
+      <para>The memory used for a MEMORY table is the sum of memory used by
+      each row. Each MEMORY table row is a Java object that has 2 int or
+      reference variables. It contains an array of objects for the fields in
+      the row. Each field is an object such as <classname>Integer</classname>,
+      <classname>Long</classname>, <classname>String</classname>, etc. In
+      addition each index on the table adds a node object to the row. Each
+      node object has 6 int or reference variables. As a result, a table with
+      just one column of type INTEGER will have four objects per row, with a
+      total of 10 variables of 4 bytes each - currently taking up 80 bytes per
+      row. Beyond this, each extra column in the table adds at least a few
+      bytes to the size of each row.</para>
+    </section>
+
+    <section>
+      <title>Result Set Memory Allocation</title>
+
+      <para>By default, all the rows in the result set are built in memory, so
+      very large result sets may not be possible to build. In server mode
+      databases, by default, the result set memory is released from the server
+      once the database server has returned the result set.
+      <glossterm>in-process</glossterm> databases release the memory when the
+      application program releases the
+      <classname>java.sql.ResultSet</classname> object. Server modes require
+      additional memory for returning result sets, as they convert the full
+      result set into an array of bytes which is then transmitted to the
+      client.</para>
+
+      <para>HyperSQL 2.0 supports disk-based result sets. The commands,
+      <literal>SET SESSION RESULT MEMORY ROWS &lt;integer&gt;</literal> and
+      <literal>SET DATABASE DEFAULT RESULT MEMORY ROWS
+      &lt;integer&gt;</literal> specify a threshold for the number of rows.
+      Results with row counts above the threshold are stored on disk. These
+      settings also apply to temporary tables and subquery tables.</para>
+
+      <para>When the setFetchSize() method of the Statement interface is used
+      to limit the number rows fetched, the whole result is held by the engine
+      and is returned to the JDBC ResultSet in blocks of rows of the specified
+      fetch size. Disk-based result sets slow down the database operations and
+      should be used only when absolutely necessary, perhaps with result sets
+      that are larger than tens of thousands of rows.</para>
+    </section>
+
+    <section>
+      <title>Temporary Memory Use During Operations</title>
+
+      <para>When UPDATE and DELETE queries are performed on CACHED tables, the
+      full set of rows that are affected, including those affected due to ON
+      UPDATE actions, is held in memory for the duration of the operation.
+      This means it may not be possible to perform deletes or updates
+      involving very large numbers of rows of CACHED tables. Such operations
+      should be performed in smaller sets.</para>
+
+      <para>When transactions support is enabled with SET AUTOCOMMIT FALSE,
+      lists of all insert, delete or update operations are stored in memory so
+      that they can be undone when ROLLBACK is issued. For CACHED tables, only
+      the transaction information is held in memory, not the actual rows that
+      have changed. Transactions that span thousands of modification to data
+      will take up a lot of memory until the next COMMIT or ROLLBACK clears
+      the list. Each row modification uses less than 100 bytes until
+      COMMIT.</para>
+
+      <para>When subqueries or views are used in SELECT and other statements,
+      transient tables are created and populated by the engine. If the
+      <literal>SET SESSION RESULT MEMORY ROWS &lt;integer&gt;</literal>
+      statement has been used, these transient tables are stored on disk when
+      they are larger than the threshold.</para>
+    </section>
+
+    <section>
+      <title>Data Cache Memory Allocation</title>
+
+      <para>With CACHED tables, the data is stored on disk and only up to a
+      maximum number of rows are held in memory at any time. The default is up
+      to 50,000 rows. The SET FILES CACHE ROWS command or the
+      <property>hsqldb.cache_rows</property> connection property can be set to
+      alter this amount. As any random subset of the rows in any of the CACHED
+      tables can be held in the cache, the amount of memory needed by cached
+      rows can reach the sum of the rows containing the largest field data.
+      For example if a table with 100,000 rows contains 40,000 rows with 1,000
+      bytes of data in each row and 60,000 rows with 100 bytes in each, the
+      cache can grow to contain 50,000 of the smaller rows, but as explained
+      further, only 10,000 or the large rows.</para>
+
+      <para>An additional property, <property>hsqldb.cache_size</property> is
+      used in conjunction with the <property>hsqldb.cache_rows</property>
+      property. This puts a limit in bytes on the total size of rows that are
+      cached. The default values is 10,000KB. (This is the size of binary
+      images of the rows and indexes. It translates to more actual memory,
+      typically 2-4 times, used for the cache because the data is represented
+      by Java objects.)</para>
+
+      <para>If memory is limited, the <property>hsqldb.cache_rows</property>
+      or <property>hsqldb.cache_size</property> database properties can be
+      reduced. In the example above, if the
+      <property>hsqldb.cache_size</property> is reduced from 10,000 to 5,000,
+      it will allow the number of cached rows to reach 50,000 small rows, but
+      only 5,000 of the larger rows.</para>
+
+      <para>Data for CLOB and BLOB columns is not cached and does not affect
+      the CACHED table memory cache.</para>
+
+      <para>The use of Java nio file access method also increases memory
+      usage. Access with nio improves database update speed and is used by
+      default for data files up to 256 MB. For minimal memory use, nio access
+      should be disabled.</para>
+    </section>
+
+    <section>
+      <title>Object Pool Memory Allocation</title>
+
+      <para>HyperSQL uses a set of fast pools for immutable objects such as
+      Integer, Long and short String objects that are stored in the database.
+      In most circumstances, this reduces the memory footprint still further
+      as fewer copies of the most frequently-used objects are kept in memory.
+      The object pools are shared among all databases in the JVM. The size of
+      each pool can be modified only by altering and recompiling the
+      <literal>org.hsqldb.store.ValuePool</literal> class.</para>
+    </section>
+
+    <section>
+      <title>Lob Memory Usage</title>
+
+      <para>Access to lobs is always performed in chunks, so it is perfectly
+      possible to store and access a CLOB or BLOB that is larger than the JVM
+      memory allocation. Early versions of HyperSQL 2.0 use memory-based
+      tables for the lob catalog (not the data). Therefore it is practical to
+      store about 100,000 individual lobs in the database with the default JVM
+      memory allocation. More lobs can be stored with larger JVM memory
+      allocations. The realistic maximum number of lobs stored in the database
+      is probably about a million. The actual total size of lobs is almost
+      unlimited. We have tested with over 100 GB of lobs without any loss of
+      performance.</para>
+    </section>
+
+    <section>
+      <title>Disk Space</title>
+
+      <para>With file: database, the engine uses the disk for storage of data
+      and any change. For safely, the engine backs up the data internally
+      during operation. Spare space, at least equal to the size of the .data
+      and .script file is needed. The .lobs file is not backed up during
+      operation.</para>
+    </section>
+  </section>
+
+  <section xml:id="deployment_conns-sect">
+    <title>Managing Database Connections</title>
+
+    <para>In all running modes (server or <glossterm>in-process</glossterm>)
+    multiple connections to the database engine are supported.
+    <glossterm>in-process</glossterm> (standalone) mode supports connections
+    from the client in the same Java Virtual Machine, while server modes
+    support connections over the network from several different
+    clients.</para>
+
+    <para>Connection pooling software can be used to connect to the database
+    but it is not generally necessary. Connection pools may be used for the
+    following reasons.</para>
+
+    <itemizedlist>
+      <listitem>
+        <para>To allow new queries to be performed while a time-consuming
+        query is being performed in the background. In HyperSQL, blocking
+        depends on the transaction control model, the isolation level, and the
+        current activity by other sessions.</para>
+      </listitem>
+
+      <listitem>
+        <para>To limit the maximum number of simultaneous connections to the
+        database for performance reasons. With HSQLDB this can be useful if
+        your application is designed in a way that opens and closes
+        connections for each small task. Also, the overall performance may be
+        higher when fewer simultaneous connections are used. If you want to
+        reduce the number of simultaneous sessions, you can use a connection
+        pool with fewer pooled connections.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>An application that is not both multi-threaded and transactional,
+    such as an application for recording user login and logout actions, does
+    not need more than one connection. The connection can stay open
+    indefinitely and reopened only when it is dropped due to network
+    problems.</para>
+
+    <para>When using an <glossterm>in-process</glossterm> database, when the
+    last connection to the database is closed, the database still remains
+    open. An explicit SHUTDOWN command, with or without an argument, is
+    required to close the database. A connection property on the connection
+    URL or in a properties object can be used to shutdown the database when
+    the last connection is closed.</para>
+
+    <para>When using a server database (and to some extent, an
+    <glossterm>in-process</glossterm> database), care must be taken to avoid
+    creating and dropping JDBC Connections too frequently. Failure to observe
+    this will result in poor performance when the application is under heavy
+    load.</para>
+
+    <para>A common error made by users in load-test simulations is to use a
+    single client machine to open and close thousands of connections to a
+    HyperSQL server instance. The connection attempts will fail after a few
+    thousand because of OS restrictions on opening sockets and the delay that
+    is built into the OS in closing them.</para>
+  </section>
+
+  <section>
+    <title>Tweaking the Mode of Operation</title>
+
+    <para>Different modes of operation and settings are used for different
+    purposes. Some scenarios are discussed below:</para>
+
+    <section>
+      <title>Application Development and Testing</title>
+
+      <para>For application unit testing you can use an all-in-memory,
+      in-process database.</para>
+
+      <para>If the tests are all run in one process, then the contents of a
+      <glossterm>mem:</glossterm> database survives between tests. To release
+      the contents you can use the SHUTDOWN command (an SQL command). You can
+      even use multiple <glossterm>mem:</glossterm> databases in your tests
+      and SHUTDOWN each one separately.</para>
+
+      <para>If the tests are in different processes and you want to keep the
+      data between the tests, the best solution is to use a Server instance
+      that has a <glossterm>mem:</glossterm> database. After the tests are
+      done, you can SHUTDOWN this database, which will shutdown the
+      server.</para>
+
+      <para>The Server has an option that allows databases to be created as
+      needed by making a connection (see the Listeners Chapter). This option
+      is useful for testing, as your server is never shut down. Each time you
+      connect to the <glossterm>mem:</glossterm> database that is served by
+      the Server, the database is created if it does not exist (i.e. has been
+      previously shut down).</para>
+
+      <para>If you do not want to run a Server instance, and you need
+      persistence between tests in different processes, then you should use a
+      <glossterm>file:</glossterm> database. You can use the
+      <literal>shutdown=true</literal> connection property to ensure the
+      database is persisted fully after the connections are closed. An
+      alternative option is to use <literal>hsqldb.write_delay=false</literal>
+      connection property, but this is slightly slower than the other
+      option.</para>
+
+      <para>It has been reported that some data access frameworks do not close
+      all their connection to the database after the tests. In such
+      situations, you need to use zero WRITE DELAY if you want the data to
+      persist at the end of the tests</para>
+
+      <para>You may actually want to use a <glossterm>file:</glossterm>
+      database, or a server instance that serves a
+      <glossterm>file:</glossterm> database in preference to a
+      <glossterm>mem:</glossterm> database. As HyperSQL logs the DDL and DML
+      statements in the .log file, this file can be used to check what is
+      being sent to the database. Note that UPDATE statements are represented
+      by a DELETE followed by an INSERT statement. Statements are written out
+      when the connection commits. The write delay also has an effect on how
+      soon the statements are written out.</para>
+
+      <para>Some types of tests start with a database that already contains
+      the tables and data, and perform various operations on it during the
+      tests. You can create and populate the initial database then set the
+      property "files_read_only=true" in the .properties file of the database.
+      The tests can then modify the database, but these modifications are not
+      persisted after the tests have completed.</para>
+    </section>
+
+    <section>
+      <title>Embedded Databases in Desktop Applications</title>
+
+      <para>In this usage, the amount of data change is often limited and
+      there is often a requirement to persist the data immediately. You can
+      use the property <literal>write_delay=false</literal> to force a disk
+      sync after each commit. Before the application is closed, you should
+      perform the SHUTDOWN command to ensure the database is opened instantly
+      when it is next opened.</para>
+    </section>
+
+    <section>
+      <title>Embedded Databases in Server Applications</title>
+
+      <para>This usage involves a server application, such as a web
+      application, connecting to an embedded HyperSQL instance. In this usage,
+      the database is often accessed heavily, therefore performance and
+      latency is a consideration. If the database is updated heavily, the
+      default value of the WRITE DELAY property (1 sec) is often enough, as it
+      is assumed the server or the application does not go down frequently. If
+      it is necessary, you can reduce the WRITE DELAY to a small value (20 ms)
+      without impacting the update speed. If you reduce WRITE DELAY to zero,
+      performance drops to the speed of disk file sync operation.</para>
+
+      <para>Alternatively, a server application can use an all-in-mem database
+      instance for fast access, while sending the data changes to a
+      persistent, disk based instance either periodically or in real
+      time.</para>
+    </section>
+
+    <section>
+      <title>Embedding a Database Listener</title>
+
+      <para>Since you won't be able to access
+      <glossterm>in-process</glossterm> database instances from other
+      processes, you will often want to run a Listener in your server
+      applications with embedded databases. You can do this by starting up a
+      Server or WebServer instance programmatically, but you could also use
+      the class <classname>org.hsqldb.util.MainInvoker</classname> to start up
+      your application and a Server or WebServer without any programming.
+      <example>
+          <title>MainInvoker Example</title>
+
+          <screen>  java -cp path/to/your/app.jar:path/to/hsqldb.jar your.App "" org.hsqldb.server.Server</screen>
+        </example> (Use ; instead of : to delimit classpath elements on
+      Windows). Specify the same <glossterm>in-process</glossterm> JDBC URL to
+      your app and in the <filename>server.properties</filename> file. You can
+      then connect to the database from outside using a JDBC URL like
+      <literal>jdbc:hsqldb:hsql://hostname</literal>.</para>
+
+      <simpara>This tactic can be used to run off-the-shelf server
+      applications with an embedded HyperSQL Server, without doing any
+      coding.</simpara>
+
+      <simpara><classname>MainInvoker</classname> can be used to run any
+      number of Java class main method invocations in a single JVM. See the
+      API spec for <classname xlink:href="#MainInvoker.html-link">
+      MainInvoker</classname> for details on its usage.</simpara>
+    </section>
+
+    <section>
+      <title>Using HyperSQL Without Logging</title>
+
+      <para>All file database that are not readonly, write changes to the .log
+      file. There are scenarios where writing to the .log file can be turned
+      off to improve performance, especially with larger databases. For these
+      applications you can set the property
+      <literal>hsqldb.log_data=false</literal> to disable the recovery log and
+      speed up data change performance. The equivalent SQL command is SET
+      FILES LOG FALSE.</para>
+
+      <para>With this setting, no data is logged, but all the changes to
+      cached tables are written to the .data file. To persist all the data
+      changes up to date, you can use the CHECKPOINT command. If you perform
+      SHUTDOWN, the data is also persisted correctly. If you do not use
+      CHECKPOINT or SHUTDOWN. All the changes are lost and the database
+      reverts to its original state when it is opened.</para>
+
+      <para>Your server applications can use a database as a temporary disk
+      data cache which is not persisted past the lifetime of the application.
+      For this usage, delete the database files when the application
+      ends.</para>
+
+      <para>On some platforms, such as embedded devices which are reliable,
+      this is also a useful option. Your application issues CHECKPOINT to save
+      the changes made so far. This method of use reduces write operations on
+      SSD devices. For this usage, the lock file should also be disabled with
+      the connection property hsqldb.lock_file=false.</para>
+    </section>
+
+    <section>
+      <title>Server Databases</title>
+
+      <para>Running databases in a HyperSQL server is the best overall method
+      of access. As the JVM process is separate from the application, this
+      method is the most reliable as well as the most accessible method of
+      running databases.</para>
+    </section>
+  </section>
+
+  <section xml:id="deployment_upgrade-sect">
+    <title>Upgrading Databases</title>
+
+    <indexterm significance="preferred">
+      <primary>upgrading</primary>
+    </indexterm>
+
+    <para>Any database that is not produced with the release version of
+    HyperSQL 2.0 must be upgraded to this version. Most catalogs created with
+    1.8.x can be upgraded simply by opening with HyperSQL 2. When this is not
+    possible due to errors, the rest of the procedures below should be
+    followed.</para>
+
+    <para>Once a database is upgraded to 2.0, it can no longer be used with
+    previous versions of HyperSQL.</para>
+
+    <para>If your database has been created with version 1.7.x, first upgrade
+    to version 1.8.1 and perform a SHUTDOWN COMPACT with this version. You can
+    then open and upgrade the database with version 2.0.</para>
+
+    <section xml:id="upgrade_via_script-sect">
+      <title xml:id="upgrade_via_script-title">Upgrading From Older
+      Versions</title>
+
+      <para>To upgrade from version 1.8.x with the default TEXT format script
+      files, simply open the database with 2.0. If the version 1.8.x files
+      have database script format set to BINARY or COMPRESSED (ZIPPED) you
+      must issue the SET SCRIPTFORMAT TEXT and SHUTDOWN SCRIPT commands with
+      the old version, then open with the new version of the engine. In most
+      cases the upgrade is successful and complete.</para>
+
+      <para>It is strongly recommended to execute SHUTDOWN COMPACT after an
+      automatic upgrade from previous versions.</para>
+
+      <para>If your database has been created with version 1.7.2 or 1.7.3,
+      first upgrade to version 1.8.1 and perform a SHUTDOWN COMPACT with this
+      version. You can then upgrade the database to version 2.0.</para>
+
+      <para>To upgrade from older version database files (1.7.1 and older)
+      that contain CACHED tables, use the SCRIPT procedure below. In all
+      versions of HyperSQL, the <literal>SCRIPT 'filename'</literal> command
+      (used as an SQL statement) allows you to save a full record of your
+      database, including database object definitions and data, to a file of
+      your choice. You can export a script file using the old version of the
+      database engine and open the script as a database with 2.0.</para>
+
+      <procedure>
+        <title>Upgrade Using the SCRIPT Procedure for Very Old
+        Versions</title>
+
+        <step>
+          <para>Open the original database in the old version of
+          DatabaseManager</para>
+        </step>
+
+        <step>
+          <para>Issue the SCRIPT command, for example <literal>SCRIPT
+          'newversion.script'</literal> to create a script file containing a
+          copy of the database.</para>
+        </step>
+
+        <step>
+          <para>SHUTDOWN this database.</para>
+        </step>
+
+        <step>
+          <para>Copy the original <literal>*.properties</literal> file into
+          <filename>newversion.properties</filename> in the same directory as
+          <filename>newversion.script</filename></para>
+        </step>
+
+        <step>
+          <para>Try to open the new database <filename>newversion</filename>
+          using DatabaseManager of version 1.8.1.</para>
+        </step>
+
+        <step>
+          <para>If there is any inconsistency in the data, the script line
+          number is reported on the console and the opening process is
+          aborted. Edit and correct any problems in the
+          <filename>newversion.script</filename> before attempting to open
+          again. Use the guidelines in the next section (Manual Changes to the
+          <literal>.script</literal> File). Use a programming editor that is
+          capable of handling very large files and does not wrap long lines of
+          text.</para>
+        </step>
+      </procedure>
+    </section>
+
+    <section>
+      <title>Manual Changes to the *.script File</title>
+
+      <para>In HyperSQL 2.0 the full range of ALTER TABLE commands is
+      available to change the data structures and their names. However, if an
+      old database cannot be opened due to data inconsistencies, or it uses
+      index or column names that are not compatible with 2.0, manual editing
+      of the <literal>*.script</literal> file can be performed.</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>Version 2.0 does not accept duplicate names for indexes that
+          were allowed before 1.7.2.</para>
+        </listitem>
+
+        <listitem>
+          <para>Version 2.0 does not accept some table or column names that
+          are SQL reserved keywords without double quoting.</para>
+        </listitem>
+
+        <listitem>
+          <para>Version 2.0 is more strict with check conditions and default
+          values.</para>
+        </listitem>
+      </itemizedlist>
+
+      <para>Other manual changes are also possible. Note that the
+      <literal>*.script</literal> file must be the result of a SHUTDOWN SCRIPT
+      and must contain the full data for the database. The following changes
+      can be applied so long as they do not affect the integrity of existing
+      data.</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>Names of tables, columns and indexes can be changed. These
+          changes must be consistent regarding foreign key constraints.</para>
+        </listitem>
+
+        <listitem>
+          <para><literal>CHECK</literal></para>
+
+          <para>A check constraint can always be removed.</para>
+        </listitem>
+
+        <listitem>
+          <para><literal>NOT NULL</literal></para>
+
+          <para>A not-null constraint can always be removed.</para>
+        </listitem>
+
+        <listitem>
+          <para><literal>PRIMARY KEY</literal></para>
+
+          <para>A primary key constraint can be removed. It cannot be removed
+          if there is a foreign key referencing the column(s).</para>
+        </listitem>
+
+        <listitem>
+          <para><literal>UNIQUE</literal></para>
+
+          <para>A UNIQUE constraint can be removed if there is no foreign key
+          referencing the column(s).</para>
+        </listitem>
+
+        <listitem>
+          <para><literal>FOREIGN KEY</literal></para>
+
+          <para>A FOREIGN KEY constraint can always be removed.</para>
+        </listitem>
+
+        <listitem>
+          <para><literal>COLUMN TYPES</literal></para>
+
+          <para>Some changes to column types are possible. For example an
+          INTEGER column can be changed to BIGINT.</para>
+        </listitem>
+      </itemizedlist>
+
+      <para>After completing the changes and saving the modified
+      <literal>.script</literal> file, you can open the database as
+      normal.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Backward Compatibility Issues</title>
+
+    <para>HyperSQL 2.0 conforms to the SQL Standard better than previous
+    versions and supports more features. For these reasons, there may be some
+    compatibility issues when converting old database, or using applications
+    that were written for version 1.8.x or earlier. Some of the potential
+    issues are listed here.</para>
+
+    <itemizedlist>
+      <listitem>
+        <para>User names and passwords are case-sensitive. Check the .script
+        file of a database for the correct case of user name and password and
+        use this form in the connection properties or on connection
+        URL.</para>
+      </listitem>
+
+      <listitem>
+        <para>Check constraints must conform to the SQL Standard. A check
+        constraint is rejected if it is not deterministic or retrospectively
+        deterministic. When opening an old database, HyperSQL silently drops
+        check constraints that no longer compile. See under check constraints
+        for more detail about what is not allowed.</para>
+      </listitem>
+
+      <listitem>
+        <para>Type declarations in column definition and in cast expressions
+        must have the necessary size parameters.</para>
+      </listitem>
+
+      <listitem>
+        <para>In connection with the above, an old database that did not have
+        the <literal>enforce_strict_size</literal> property, is now converted
+        to version 2.0 with the engine supplying the missing size parameters.
+        For example, a VARCHAR column declaration that has no size, is given a
+        32K size. Check these sizes are adequate for your use, and change the
+        column definition as necessary.</para>
+      </listitem>
+
+      <listitem>
+        <para>Column names in a GROUP BY clause were previously resolved to
+        the column label. They are now resolved to column name first, and if
+        the name does not match, to the column label.</para>
+      </listitem>
+
+      <listitem>
+        <para>If two or more tables in a join contain columns with the same
+        name, the columns cannot be referenced in join and where conditions.
+        Use table names before column names to qualify the references to such
+        columns.</para>
+      </listitem>
+
+      <listitem>
+        <para>Table definitions containing GENERATED BY DEFAULT AS IDENTITY
+        but with no PRIMARY KEY do not automatically create a primary key.
+        Database .script files made with 1.8 are fine, as the PRIMARY KEY
+        clause is always included. But your application program may assume an
+        automatic primary key is created.</para>
+      </listitem>
+
+      <listitem>
+        <para>CREATE ALIAS is now obsolete. Use the new function definition
+        syntax. The <classname>org.hsqldb.Library </classname>class no longer
+        exists. You should use the SQL form of the old library functions. For
+        example, use <literal>LOG(x)</literal> rather than the direct form,
+        <literal>"org.hsqldb.Library.log"(x)</literal>.</para>
+      </listitem>
+
+      <listitem>
+        <para>The names of some commands for changing database and session
+        properties have changed. See the list of statements in this
+        chapter.</para>
+      </listitem>
+    </itemizedlist>
+  </section>
+
+  <section xml:id="deployment_backup-sect">
+    <title>Backing Up Database Catalogs</title>
+
+    <indexterm significance="preferred">
+      <primary>backup</primary>
+    </indexterm>
+
+    <para>The database engine saves the files containing all the data in a
+    file catalog when a shutdown takes place. It automatically recovers from
+    an abnormal termination and preserves the data when the catalog is opened
+    next time. In an ideal operating environment, where there is no OS crash,
+    disk failure, bugs in code, etc. there would be no need regularly to
+    backup a database. This is meant to say, the engine performs the routine
+    shutdown procedure internally, therefore backing up catalogs is an
+    insurance policy against all sorts of misadventure that are not under the
+    control of the database engine.</para>
+
+    <para>The data for each catalog consists of up to 5 files in the same
+    directory with the endings such as <literal>*.properties</literal>,
+    <literal>*.script</literal>, etc., as detailed in previous
+    chapters.</para>
+
+    <simpara>HyperSQL 2.0 includes commands to backup the database files into
+    a single <literal>.tar</literal> or <literal>.tar.gz</literal> file
+    archive. The backup can be performed by a command given in a JDBC session
+    if the target database catalog is running, or on the command-line if the
+    target catalog has been shutdown.</simpara>
+
+    <section>
+      <title>Making Online Backups</title>
+
+      <simpara>To back up a running catalog, obtain a JDBC connection and
+      issue a <literal>BACKUP DATABASE</literal> command in SQL. In its most
+      simple form, the command format below will backup the database as a
+      single <literal>.tar.gz</literal> file to the given directory.</simpara>
+
+      <programlisting>  BACKUP DATABASE TO &lt;directory name&gt; BLOCKING</programlisting>
+
+      <simpara>See the next section under Statements for details about the
+      command and its options. See the sections below about restoring a
+      backup.</simpara>
+    </section>
+
+    <section>
+      <title>Making Offline Backups</title>
+
+      <para>To back up an offline catalog, the catalog must be in shut down
+      state. You will run a Java command like this <example>
+          <title>Offline Backup Example</title>
+
+          <screen>  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --save  \
+  tar/path.tar db/base/path</screen>
+        </example>where <filename>tar/path.tar</filename> is a file path to
+      the <literal>*.tar</literal> or <literal>*.tar.gz</literal> file to be
+      created, and <filename>db/base/path</filename> is the file path to the
+      catalog file base name (in same fashion as in
+      <varname>server.database.*</varname> settings and JDBC URLs with catalog
+      type <glossterm>file:</glossterm>.</para>
+    </section>
+
+    <section>
+      <title>Examining Backups</title>
+
+      <para>You can list the contents of backup tar files with
+      <classname>DbBackup</classname> on your operating system command line,
+      or with any Pax-compliant tar or pax client (this includes GNU tar),
+      <example>
+          <title>Listing a Backup with DbBackup</title>
+
+          <screen>  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --list tar/path.tar</screen>
+        </example>You can also give regular expressions at the end of the
+      command line if you are only interested in some of the file entries in
+      the backup. Note that these are real regular expressions, not shell
+      globbing patterns, so you would use <literal>.+script</literal> to match
+      entries ending in "script", not <literal>*script</literal>.</para>
+
+      <simpara>You can examine the contents of the backup in their entirety by
+      restoring the backup, as explained in the following section, to a
+      temporary directory.</simpara>
+    </section>
+
+    <section>
+      <title>Restoring a Backup</title>
+
+      <para>You use <classname>DbBackup</classname> on your operating system
+      command line to restore a catalog from a backup. <example>
+          <title>Restoring a Backup with DbBackup</title>
+
+          <screen>  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --extract  \
+      tar/path.tar db/dir</screen>
+        </example>where <filename>tar/path.tar</filename> is a file path to
+      the *.tar or *.tar.gz file to be read, and <filename>db/dir</filename>
+      is the target directory to extract the catalog files into. Note that
+      <filename>db/dir</filename> specifies a directory path, without the
+      catalog file base name. The files will be created with the names stored
+      in the tar file (and which you can see as described in the preceding
+      section).</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Encrypted Databases</title>
+
+    <para>HyperSQL supports encrypted databases. Encryption services use the
+    Java Cryptography Extensions (JCE) and uses the ciphers installed with the
+    JRE. HyperSQL itself does not contain any cryptography code.</para>
+
+    <para>Three elements are involved in specifying the encryption method and
+    key. A cipher, together with its configuration is identified by a string
+    which includes the name of the cipher and optional parameters. A provider
+    is the fully qualified class name of the cipher provider. A key is
+    represented as a hexadecimal string.</para>
+
+    <section>
+      <title>Creating and Accessing an Encrypted Database</title>
+
+      <para>First, a key must be created for the desired cipher and
+      configuration. This is done by calling the function CRYPT_KEY(&lt;cipher
+      spec&gt;, &lt;provider&gt;). If the default provider (the built-in JVM
+      ciphers) is used, then NULL should be specified as the provider. The
+      CRYPT_KEY function returns a hexadecimal key. The function call can be
+      made in any HyperSQL database, so long as the provider class is on the
+      classpath. This key can be used to create a new encrypted database.
+      Calls to this function always return different keys, based on a
+      generated random values.</para>
+
+      <para>As an example, a call to CRYPT_KEY('Blowfish', null) returned the
+      string, '604a6105889da65326bf35790a923932'. To create a new database,
+      the URL below is used:</para>
+
+      <para><literal>jdbc:hsqldb:file:&lt;database
+      path&gt;;crypt_key=604a6105889da65326bf35790a923932;crypt_type=blowfish</literal></para>
+
+      <para>The third property name is crypt_provider. This is specified only
+      when the provider is not the default provider.</para>
+
+      <para>HyperSQL works with any symmetric cipher that may be available
+      from the JVM.</para>
+
+      <para>The files that are encrypted include the .script, .data, .backup
+      and .log files. The .lobs file is not encrypted by default. The property
+      crypt_lobs=true must be specified to encrypt the .lobs file.</para>
+    </section>
+
+    <section>
+      <title>Speed Considerations</title>
+
+      <para>General operations on an encrypted database are performed the same
+      as with any database. However, some operations are significantly slower
+      than with the equivalent cleartext database. With MEMORY tables, there
+      is no difference to the speed of SELECT statements, but data change
+      statements are slower. With CACHED tables, the speed of all statements
+      is slower.</para>
+    </section>
+
+    <section>
+      <title>Security Considerations</title>
+
+      <para>Security considerations for encrypted databases have been
+      discussed at length in HSQLDB discussion groups. Development team
+      members have commented that encryption is not a panacea for all security
+      needs. The following issues should be taken into account:</para>
+
+      <para><itemizedlist>
+          <listitem>
+            <para>Encrypted files are relatively safe in transport, but
+            because databases contain many repeated values and words,
+            especially known tokens such as CREATE, INSERT, etc., breaking the
+            encryption of a database may be simpler than an unknown
+            file.</para>
+          </listitem>
+
+          <listitem>
+            <para>Only the files are encrypted, not the memory image. Poking
+            into computer memory, while the database is open, will expose the
+            contents of the database.</para>
+          </listitem>
+
+          <listitem>
+            <para>HyperSQL is open source. Someone who has the key, can
+            compile and use a modified version of the program that saves a
+            full cleartext dump of an encrypted database</para>
+          </listitem>
+        </itemizedlist>Therefore encryption is generally effective only when
+      the users who have access to the crypt key are trusted.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Monitoring Database Operations</title>
+
+    <para>Database operations can be monitored at different levels using
+    internal HyperSQL capabilities or add-ons.</para>
+
+    <section>
+      <title>Statement Level Monitoring</title>
+
+      <para>Statement level monitoring allows you to gather statistics about
+      executed statements. HyperSQL is supported by the monitoring tool JAMon
+      (Java Application Monitor). JAMon is currently developed as the
+      SourceForge project, jamonapi.</para>
+
+      <para>JAMon works at the JDBC level. It can monitor and gather
+      statistics on different types of executed statements or other JDBC
+      calls.</para>
+
+      <para>Early versions of JAMon were developed with HSQLDB and had to be
+      integrated into HSQLDB at code level. The latest versions can be added
+      on as a proxy in a much simpler fashion.</para>
+    </section>
+
+    <section>
+      <title>Internal Event Monitoring</title>
+
+      <para>HyperSQL can log important internal events of the engine. These
+      events occur during the operation of the engine, and are not always
+      coupled with the exact type of statement being executed. Normal events
+      such as opening and closing of files, or errors such as OutOfMemory
+      conditions are examples of logged events.</para>
+
+      <para>HyperSQL supports two methods of logging. One method is specific
+      to the individual database and is managed internally by HyperSQL. The
+      other method is specific to JVM and is managed by a logging
+      framework.</para>
+
+      <para>The internally-generated, individual log for the database can be
+      enabled with the <literal>SET DATABASE EVENT LOG LEVEL</literal>
+      statement, described in the next section. This method of logging is very
+      useful for desktop application deployment, as it provides an ongoing
+      record of database operations.</para>
+
+      <para>HyperSQL also supports log4J and JDK logging. The same event
+      information that is passed to the internal log, is passed to external
+      logging frameworks. These frameworks are configured outside HyperSQL.
+      The log messages include the unique id of the database that generated
+      the message, so it can be identified in a multi-database server
+      context.</para>
+    </section>
+
+    <section>
+      <title>Server Operation Monitoring</title>
+
+      <para>A Server or WebServer instance can be started with the property
+      server.silent=false. This causes all the connections and their executed
+      statements to be printed to stdout as the statements are submitted to
+      the server.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Statements</title>
+
+    <para>System level statements are listed in this section. Statements that
+    begin with SET DATABASE or SET FILES are for properties that have an
+    effect on the normal operation of HyperSQL. The effects of these
+    statements are also discussed in different chapters.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SHUTDOWN</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SHUTDOWN</emphasis></simpara>
+
+    <simpara><emphasis>shutdown statement</emphasis></simpara>
+
+    <simpara><literal>&lt;shutdown statement&gt; ::= SHUTDOWN [IMMEDIATELY |
+    COMPACT | SCRIPT]</literal></simpara>
+
+    <simpara>Shutdown the database. If the optional qualifier is not used, a
+    normal SHUTDOWN is performed. A normal SHUTDOWN ensures all data is saved
+    correctly and the database opens without delay on next use.</simpara>
+
+    <variablelist>
+      <varlistentry>
+        <term>SHUTDOWN IMMEDIATELY</term>
+
+        <listitem>
+          <para>Saves the *.log file and closes the database files. This is
+          the quickest form of shutdown. This command should not be used as
+          the routine method of closing the database, because when the
+          database is accessed next time, it may take a long time to
+          start.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>SHUTDOWN COMPACT</term>
+
+        <listitem>
+          <para>This is similar to normal SHUTDOWN, but reduces the *.data
+          file to its minimum size. It takes longer than normal
+          SHUTDOWN.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>SHUTDOWN SCRIPT</term>
+
+        <listitem>
+          <para>This is similar to SHUTDOWN COMPACT, but it does not rewrite
+          the <literal>*.data</literal> and text table files. After SHUTDOWN
+          SCRIPT, only the <literal>*.script</literal> and
+          <literal>*.properties</literal> files remain. At the next startup,
+          these files are processed and the <literal>*.data</literal> and
+          <literal>*.backup</literal> files are created. This command in
+          effect performs part of the job of SHUTDOWN COMPACT, leaving the
+          other part to be performed automatically at the next startup.</para>
+
+          <para>This command produces a full script of the database which can
+          be edited for special purposes prior to the next startup.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>BACKUP DATABASE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">BACKUP DATABASE</emphasis></simpara>
+
+    <simpara><emphasis>backup database statement</emphasis></simpara>
+
+    <simpara><literal>&lt;backup database statement&gt; ::= BACKUP DATABASE TO
+    &lt;file path&gt; {SCRIPT | [NOT] COMPRESSED} BLOCKING</literal></simpara>
+
+    <simpara>Backup the database to specified <literal>&lt;file
+    path&gt;</literal> for archiving purposes.</simpara>
+
+    <simpara>The <literal>&lt;file path&gt;</literal> can be in two forms. If
+    the <literal>&lt;file path&gt;</literal> ends with a forward slash, it
+    specifies a directory. In this case, an automatic name for the archive is
+    generated that includes the date, time and the base name of the database.
+    The database is backed up to this archive file in the specified directory.
+    If the <literal>&lt;file path&gt;</literal> does not end with a forward
+    slash, it specifies a user-defined file name for the backup archive. The
+    archive is in tar, gzip format depending on whether it is compressed or
+    not.</simpara>
+
+    <simpara>The SCRIPT option is not currently supported. If SCRIPT is
+    specified, the backup will consist of two files, a
+    <literal>*.properties</literal> file and a <literal>*.script</literal>
+    file, which contain all the data and settings of the database. These files
+    are not compressed.</simpara>
+
+    <simpara>If COMPRESSED or NOT COMPRESSED is specified, the backup consists
+    of the current snapshot of database files. During backup, a CHECKPOINT
+    command is silently executed.</simpara>
+
+    <simpara>The qualifier, BLOCKING, means all database operations are
+    suspended during backup.</simpara>
+
+    <simpara>The HyperSQL jar also contains a program that creates an archive
+    of an offline database. It also contains a program to expand an archive
+    into database files. These programs are documented in this chapter under
+    Backing up Database Catalogs.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CHECKPOINT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CHECKPOINT</emphasis></simpara>
+
+    <simpara><emphasis>checkpoint statement</emphasis></simpara>
+
+    <simpara><literal>&lt;checkpoint statement&gt; ::= CHECKPOINT
+    [DEFRAG]</literal></simpara>
+
+    <simpara>Closes the database files, rewrites the script file, deletes the
+    log file and opens the database. If <literal>DEFRAG</literal> is
+    specified, also shrinks the <literal>*.data</literal> file to its minumum
+    size. Only a user with the DBA role can execute this statement.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CRYPT_KEY</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CRYPT_KEY</emphasis></simpara>
+
+    <simpara><emphasis>crypt_key function</emphasis></simpara>
+
+    <simpara><literal>&lt;crypt_key function&gt; ::= CRYPT_KEY ( &lt;cipher
+    spec&gt;, &lt;provider&gt; )</literal></simpara>
+
+    <simpara>The statement, <literal>CALL CRYPT_KEY( &lt;cipher spec&gt;,
+    &lt;provider&gt; )</literal> returns a binary string representing a valid
+    key for the giver cipher and provider. The
+    <literal>&lt;provider&gt;</literal> argument is specified as NULL for the
+    default provider.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SCRIPT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SCRIPT</emphasis></simpara>
+
+    <simpara><emphasis>script statement</emphasis></simpara>
+
+    <simpara><literal>&lt;script statement&gt; ::= SCRIPT [&lt;file
+    name&gt;]</literal></simpara>
+
+    <simpara>Returns a script containing SQL statements that define the
+    database, its users, and its schema objects. If <literal>&lt;file
+    name&gt;</literal> is not specified, the statements are returned in a
+    ResultSet, with each row containing an SQL statement. No data statements
+    are included in this form. The optional file name is a single-quoted
+    string. If <literal>&lt;file name&gt;</literal> is specified, then the
+    script is written to the named file. In this case, all the data in all
+    tables of the database is included in the script as INSERT
+    statements.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES BACKUP INCREMENT</primary>
+    </indexterm>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE COLLATION</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE COLLATION</emphasis></simpara>
+
+    <simpara><emphasis>set database collation statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set database collation statement&gt; ::= SET
+    DATABASE COLLATION &lt;collation name&gt;</literal></simpara>
+
+    <simpara>Each database can have its own collation. Sets the collation from
+    the set of collations supported by HyperSQL. Once this command has been
+    issued, the database can be opened in any JVM and will retain its
+    collation. Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE DEFAULT TABLE TYPE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE DEFAULT TABLE
+    TYPE</emphasis></simpara>
+
+    <simpara><emphasis>set database default table type
+    statement</emphasis><literal> </literal></simpara>
+
+    <simpara><literal>&lt;set database default table type&gt; ::= SET DATABASE
+    DEFAULT TABLE TYPE { CACHED | MEMORY }</literal></simpara>
+
+    <simpara>Sets the type of table created when the next CREATE TABLE
+    statement is executed. The default is MEMORY.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE DEFAULT RESULT MEMORY ROWS</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE DEFAULT RESULT MEMORY
+    ROWS</emphasis></simpara>
+
+    <simpara><emphasis>set database default result memory rows
+    statement</emphasis><literal> </literal></simpara>
+
+    <simpara><literal>&lt;set database default result memory rows&gt; ::= SET
+    DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned integer
+    literal&gt;</literal></simpara>
+
+    <simpara>Sets the maximum number of rows of each result set and other
+    internal temporary table that is held in memory. This setting applies to
+    all sessions. Individual sessions can change the value with the
+    <literal>SET SESSION RESULT MEMORY ROWS</literal> command. The default is
+    0, meaning all result sets are held in memory.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE EVENT LOG LEVEL</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE EVENT LOG
+    LEVEL</emphasis></simpara>
+
+    <simpara><emphasis>set database event log level
+    statement*</emphasis><literal> </literal></simpara>
+
+    <simpara><literal>&lt;set database event log level&gt; ::= SET DATABASE
+    EVENT LOG LEVEL { 0 | 1 | 2 }</literal></simpara>
+
+    <simpara>Sets the amount of information logged in the internal,
+    database-specific event log. Level 0 means no log. Level 1 means only
+    important (error) events. Level 2 means more events, including both
+    important and less important (normal) events. For readonly and
+    <glossterm>mem:</glossterm> databases, if the level is set above 0, the
+    log messages are directed to stderr.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE GC</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE GC</emphasis></simpara>
+
+    <simpara><emphasis>set database gc statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set database gc statement&gt; ::= SET DATABASE GC
+    &lt;unsigned integer literal&gt;</literal></simpara>
+
+    <simpara>An optional property which forces calls to <literal>System.gc()
+    </literal>after the specified number of row operations. The default value
+    for this property is 0, which means no System.gc() calls. Usual values for
+    this property range from 10000 depending on the system and the memory
+    allocation. This property may be useful in some in-process deployments,
+    especially with older JVM implementations.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE SQL SIZE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE SQL SIZE</emphasis></simpara>
+
+    <simpara><emphasis>set database sql size statement</emphasis><literal>
+    </literal></simpara>
+
+    <simpara><literal>&lt;set database sql size statement&gt; ::= SET DATABASE
+    SQL SIZE { TRUE | FALSE }</literal></simpara>
+
+    <simpara>Enable or disable enforcement of column sizes for CHAR and
+    VARCHAR columns. The default is TRUE, meaning table definition must
+    contain <literal>VARCHAR(n)</literal> instead of
+    <literal>VARCHAR</literal>.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE SQL NAMES</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE SQL NAMES</emphasis></simpara>
+
+    <simpara><emphasis>set database sql names statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set database sql names statement&gt; ::= SET
+    DATABASE SQL NAMES { TRUE | FALSE }</literal></simpara>
+
+    <simpara>Enable or disable full enforcement of the rule that prevents SQL
+    keywords being used for database object names such as columns and tables.
+    The default is FALSE, meaning disable.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE SQL REFERENCES</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE SQL
+    REFERENCES</emphasis></simpara>
+
+    <simpara><emphasis>set database sql references
+    statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set database sql references statement&gt; ::= SET
+    DATABASE SQL REFERENCES { TRUE | FALSE }</literal></simpara>
+
+    <simpara>This command can enable or disable full enforcement of the rule
+    that prevents ambiguous column references in SQL statements (usually
+    SELECT statements). A column reference is ambiguous when it is not
+    qualified by a table name or table alias and can refer to more than one
+    column in a JOIN list.</simpara>
+
+    <simpara>The property is FALSE by default. It is better to enable this
+    check while development, to improve the quality and correctness of SQL
+    statements.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET REFERENTIAL INTEGRITY</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE REFERENTIAL
+    INTEGRITY</emphasis></simpara>
+
+    <simpara><emphasis>set database referential integrity
+    statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set database referential integrity statement&gt; ::=
+    SET DATABASE REFERENTIAL INTEGRITY { TRUE | FALSE }</literal></simpara>
+
+    <simpara>This command enables or disables the enforcement of referential
+    integrity constraints (foreign key constraints), check constraints apart
+    from NOT NULL and triggers. By default, referential integrity constraints
+    are checked.</simpara>
+
+    <simpara>The only legitimate use of this statement is before importing
+    large amounts of external data into tables that have existing FOREIGN KEY
+    constraints. After import, the statement must be used again to enable
+    constraint enforcement.</simpara>
+
+    <simpara>If you are not sure the data conforms to the constraints, run
+    queries to verify all rows conform to the FOREIGN KEY constraints and take
+    appropriate actions for the rows that do not conform.</simpara>
+
+    <simpara>A query example to return the rows in a foreign key table that
+    have no parent is given below:</simpara>
+
+    <example>
+      <title>Finding foreign key rows with no parents after a bulk
+      import</title>
+
+      <screen>  SELECT * FROM foreign_key_table LEFT OUTER JOIN primary_key_table 
+    ON foreign_key_table.fk_col = primary_key_table.pk_col WHERE primary_key_table.pk_col IS NULL</screen>
+    </example>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE UNIQUE NAME*</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE UNIQUE
+    NAME</emphasis></simpara>
+
+    <simpara><emphasis>set database unique name</emphasis><literal>
+    </literal></simpara>
+
+    <simpara><literal>&lt;set database unique name statement&gt; ::= SET
+    DATABASE UNIQUE NAME &lt;identifier&gt;</literal></simpara>
+
+    <simpara>Each HyperSQL catalog (database) has an engine-generated internal
+    name. This name is based on the time of creation of the database and is
+    exactly 16 characters. The name is used for in log events sent to external
+    logging frameworks. This name can be changed by an administrator. The new
+    name must be exactly 16 characters long.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE TRANSACTION CONTROL</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE TRANSACTION
+    CONTROL</emphasis></simpara>
+
+    <simpara><emphasis>set database transaction control
+    statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set database transaction control statement&gt; ::=
+    SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC
+    }</literal></simpara>
+
+    <simpara>Set the concurrency control system for the database. It can be
+    issued only when all sessions have been committed or rolled back. This
+    command and its modes is discussed in the <link endterm="sessions-title"
+    xlink:href="#sqlroutines-chapt"></link> chapter.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <simpara><emphasis role="bold">SET FILES BACKUP INCREMENT
+    </emphasis></simpara>
+
+    <simpara><emphasis>set files backup increment
+    statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set database backup increment statement&gt; ::= SET
+    FILES BACKUP INCREMENT { TRUE | FALSE }</literal></simpara>
+
+    <simpara>Older versions of HSQLDB perform a backup of the .data file
+    before its contents are modified and the whole .data file is saved in a
+    compressed form when a CHECKPOINT or SHUTDOWN is performed. This takes a
+    long time when the size of the database exceeds 100 MB or so (on an
+    average 2010 computer, you can expect a backup speed of 20MB / s or
+    more).</simpara>
+
+    <simpara>The alternative is backup in increments, just before some part of
+    the .data file is modified. In this mode, no backup is performed at
+    CHECKPIONT or SHUTDOWN. This mode is preferred for large databases which
+    are opened and closed frequently.</simpara>
+
+    <simpara>The default mode is TRUE. If the old method of backup is
+    preferred, the mode can be set FALSE.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES CACHE ROWS</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES CACHE ROWS</emphasis></simpara>
+
+    <simpara><emphasis>set files cache rows statement</emphasis><literal>
+    </literal></simpara>
+
+    <simpara><literal>&lt;set files cache rows statement&gt; ::= SET FILES
+    CACHE ROWS &lt;unsigned integer literal&gt;</literal></simpara>
+
+    <simpara>Sets the maximum number of rows (of CACHED tables) held in the
+    memory cache.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES CACHE SIZE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES CACHE SIZE</emphasis></simpara>
+
+    <simpara><emphasis>set files cache size statement</emphasis><literal>
+    </literal></simpara>
+
+    <simpara><literal>&lt;set files cache size statement&gt; ::= SET FILES
+    CACHE SIZE &lt;unsigned integer literal&gt;</literal></simpara>
+
+    <simpara>Sets maximum amount of data (of CACHED tables) in kilobytes held
+    in the memory cache.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES DEFRAG</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES DEFRAG</emphasis></simpara>
+
+    <simpara><emphasis>set files defrag statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set files defrag statement&gt; ::= SET FILES DEFRAG
+    &lt;unsigned integer literal&gt;</literal></simpara>
+
+    <simpara>Sets the threshold for performing a DEFRAG during a checkpoint.
+    The <literal>&lt;unsigned integer literal&gt;</literal> is the percentage
+    of abandoned space in the <literal>*.data</literal> file. When a
+    CHECKPOINT is performed either as a result of the <literal>.log</literal>
+    file reaching the limit set by <literal>SET FILES LOG SIZE m</literal>, or
+    by the user issuing a CHECKPOINT command, the amount of space abandoned
+    since the database was opened is checked and if it is larger than
+    specified percentage, a CHECKPOINT DEFRAG is performed instead of a
+    CHECKPOINT.</simpara>
+
+    <simpara>The default is 0, which indicates no DEFRAG. Useful values are
+    between 10 to 50</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES LOG</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES LOG</emphasis></simpara>
+
+    <simpara><emphasis>set files log statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set files log statement&gt; ::= SET FILES LOG { TRUE
+    | FALSE }</literal></simpara>
+
+    <simpara>Sets logging of database operations on or off. Turning logging
+    off is for special usage, such as temporary cache usage.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES LOG SIZE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES LOG SIZE</emphasis></simpara>
+
+    <simpara><emphasis>set files log size statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set files log size statement&gt; ::= SET FILES LOG
+    SIZE &lt;unsigned integer literal&gt;</literal></simpara>
+
+    <simpara>Sets the maximum size in MB of the <literal>*.log</literal> file
+    to the specified value. The default maximum size is 50 MB. If the value is
+    zero, no limit is used for the size of the file. When the size of the file
+    reaches this value, a CHECKPOINT is performed and the the
+    <literal>*.log</literal> file is cleared to size 0.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES BACKUP INCREMENT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES BACKUP
+    INCREMENT</emphasis></simpara>
+
+    <simpara><emphasis>set files backup increment
+    statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set files increment backup statement&gt; ::= SET
+    FILES INCREMENT BACKUP { TRUE | FALSE }</literal></simpara>
+
+    <simpara>This specifies the method for internal backup operation. The
+    default is true.</simpara>
+
+    <simpara>During updates, the contents of the .data file is modified. When
+    this property is true, the modified contents are backed up gradually. This
+    causes a marginal slowdown in operations, but allows fast checkpoint and
+    shutdown with large .data files.</simpara>
+
+    <simpara>When the property is false, the .data file is backed up entirely
+    at the time of checkpoint and shutdown. Up to version 1.8.0, HSQLDB
+    supported only full backup. Version 1.8.1 supports incremental
+    backup.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES NIO</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES NIO</emphasis></simpara>
+
+    <simpara><emphasis>set files nio</emphasis></simpara>
+
+    <simpara><literal>&lt;set files nio statement&gt; ::= SET FILES NIO { TRUE
+    | FALSE }</literal></simpara>
+
+    <simpara>Changes the access method of the .data file. The default is TRUE
+    and uses the Java nio classes to access the file.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES WRITE DELAY</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES WRITE DELAY</emphasis></simpara>
+
+    <simpara><emphasis>set files write delay statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set files write delay statement&gt; ::= SET FILES
+    WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds
+    value&gt; MILLIS}</literal></simpara>
+
+    <para>Set the WRITE DELAY property of the database. The WRITE DELAY
+    controls the frequency of file sync for the log file. When WRITE_DELAY is
+    set to FALSE or 0, the sync takes place immediately at each COMMIT. WRITE
+    DELAY TRUE performs the sync once every 10 seconds (which is the default).
+    A numeric value can be specified instead.</para>
+
+    <para>The purpose of this command is to control the amount of data loss in
+    case of a total system crash. A delay of 1 second means at most the data
+    written to disk during the last second before the crash is lost. All data
+    written prior to this has been synced and should be recoverable.</para>
+
+    <para>A write delay of 0 impacts performance in high load situations, as
+    the engine has to wait for the file system to catch up.</para>
+
+    <para>To avoid this, you can set write delay down to 10
+    milliseconds.</para>
+
+    <para>Each time the SET FILES WRITE DELAY statement is executed with any
+    value, a sync is immediately performed. Only a user with the DBA role can
+    execute this statement.</para>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES SCALE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES SCALE</emphasis></simpara>
+
+    <simpara><emphasis>set files scale</emphasis></simpara>
+
+    <simpara><literal>&lt;set files scale statement&gt; ::= SET FILES SCALE
+    &lt;scale value&gt;</literal></simpara>
+
+    <simpara>Changes the scale factor for the .data file. The default scale is
+    8 and allows 16GB of data storage capacity. The scale can be increased in
+    order to increase the maximum data storage capacity. The scale values 8,
+    16, 32, 64 and 128 are allowed. Scale value 128 allows a maximum capacity
+    of 256GB.</simpara>
+
+    <simpara>This command can be used only when there is no data in CACHED
+    tables.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET FILES LOB SCALE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET FILES LOB SCALE</emphasis></simpara>
+
+    <simpara><emphasis>set files lob scale</emphasis></simpara>
+
+    <simpara><literal>&lt;set files lob scale statement&gt; ::= SET FILES LOB
+    SCALE &lt;scale value&gt;</literal></simpara>
+
+    <simpara>Changes the scale factor for the .lobs file. The scale is
+    interpreted in kilobytes. The default scale is 32 and allows 64TB of lob
+    data storage capacity. The scale can be reduced in order to improve
+    storage efficiency. If the lobs are a lot smaller than 32 kilobytes,
+    reducing the scale will reduce wasted space. The scale values 1, 2, 4, 8,
+    16, 32 are allowed. For example if the average size of lobs is 4
+    kilobytes, the default scale of 32 will result in 28KB wasted space for
+    each lob. Reducing the lob scale to 2 will result in average 1KB wasted
+    space for each lob.</simpara>
+
+    <simpara>This command can be used only when there is no lob in the
+    database.</simpara>
+
+    <simpara>Only a user with the DBA role can execute this
+    statement.</simpara>
+  </section>
+</chapter>
diff --git a/doc-src/guide/filelinks-app.xml b/doc-src/guide/filelinks-app.xml
new file mode 100644
index 0000000..af332f9
--- /dev/null
+++ b/doc-src/guide/filelinks-app.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: filelinks-app.xml 3606 2010-06-01 03:01:20Z unsaved $ -->
+
+<!DOCTYPE book [
+  <!ENTITY % dummy22 SYSTEM "../entities/global.ent"> %dummy22;
+]>
+
+<appendix version="5.0" xmlns="http://docbook.org/ns/docbook"
+          xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <info xml:id="filelinks-app">
+    <title>HyperSQL File Links</title>
+    <subtitle>HyperSQL Files referred to in this Guide</subtitle>
+  </info>
+  <simpara>
+    HyperSQL files referred to in the text may be retrieved from the
+    canonical HyperSQL documentation site, &distro_baseurl;, or from the
+    same location you are reading this page from.
+  </simpara>
+  <note><simpara>
+    If you are reading this document with a standalone PDF reader,
+    only the &distro_baseurl;/... links will function.
+  </simpara></note>
+
+  <itemizedlist>
+    <title>
+      Pairs of local + &distro_baseurl; links for referenced files.
+    </title>
+    <listitem xml:id="JDBCConnection.html-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/org/hsqldb/jdbc/JDBCConnection.html"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/apidocs/org/hsqldb/jdbc/JDBCConnection.html"/>
+      </simpara>
+    </listitem> <listitem xml:id="JDBCDriver.html-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/org/hsqldb/jdbc/JDBCDriver.html"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/apidocs/org/hsqldb/jdbc/JDBCDriver.html"/>
+      </simpara>
+    </listitem> <listitem xml:id="JDBCDatabaseMetaData.html-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html"/>
+      </simpara>
+    </listitem> <listitem xml:id="JDBCResultSet.html-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/org/hsqldb/jdbc/JDBCResultSet.html"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/apidocs/org/hsqldb/jdbc/JDBCResultSet.html"/>
+      </simpara>
+    </listitem> <listitem xml:id="JDBCStatement.html-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/org/hsqldb/jdbc/JDBCStatement.html"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/apidocs/org/hsqldb/jdbc/JDBCStatement.html"/>
+      </simpara>
+    </listitem> <listitem xml:id="JDBCPreparedStatement.html-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html"/>
+      </simpara>
+    </listitem> <listitem xml:id="MainInvoker.html-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/org/hsqldb/util/MainInvoker.html"/>
+      </simpara> <simpara>
+      <link xlink:href="&distro_baseurl;/apidocs/org/hsqldb/util/MainInvoker.html"/>
+      </simpara>
+    </listitem> <listitem xml:id="javadoc-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/index.html"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/apidocs/"/>
+      </simpara>
+    </listitem> <listitem xml:id="Servlet.java-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/src/org/hsqldb/server/Servlet.java"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/src/org/hsqldb/server/Servlet.java"/>
+      </simpara>
+    </listitem> <listitem xml:id="Tokens.java-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/src/org/hsqldb/Tokens.java"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/src/org/hsqldb/Tokens.java"/>
+      </simpara>
+    </listitem> <listitem xml:id="WebServer.java-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/src/org/hsqldb/server/WebServer.java"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/src/org/hsqldb/server/WebServer.java"/>
+      </simpara>
+    </listitem> <listitem xml:id="TestBase.java-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/src/org/hsqldb/test/TestBase.java"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/src/org/hsqldb/test/TestBase.java"/>
+      </simpara>
+    </listitem> <listitem xml:id="Trigger.java-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/src/org/hsqldb/Trigger.java"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/src/org/hsqldb/Trigger.java"/>
+      </simpara>
+    </listitem> <listitem xml:id="TriggerSample.java-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/src/org/hsqldb/sample/TriggerSample.java"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/src/org/hsqldb/test/sample/TriggerSample.java"/>
+      </simpara>
+    </listitem> <listitem xml:id="MainInvoker.java-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/src/org/hsqldb/util/MainInvoker.java"/>
+      </simpara> <simpara>
+      <link xlink:href="&distro_baseurl;/verbatim/src/org/hsqldb/util/MainInvoker.java"/>
+      </simpara>
+    </listitem> <listitem xml:id="hsqldb.cfg-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/hsqldb.cfg"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/hsqldb.cfg"/>
+      </simpara>
+    </listitem> <listitem xml:id="acl.txt-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/acl.txt"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/acl.txt"/>
+      </simpara>
+    </listitem> <listitem xml:id="server.properties-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/server.properties"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/server.properties"/>
+      </simpara>
+    </listitem> <listitem xml:id="sqltool.rc-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/sqltool.rc"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/sqltool.rc"/>
+      </simpara>
+    </listitem> <listitem xml:id="hsqldb.init-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/hsqldb.init"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/hsqldb.init"/>
+      </simpara>
+    </listitem>
+  </itemizedlist>
+</appendix>
diff --git a/doc-src/guide/guide.xml b/doc-src/guide/guide.xml
new file mode 100644
index 0000000..0d3bcaf
--- /dev/null
+++ b/doc-src/guide/guide.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: guide.xml 3601 2010-06-01 00:17:47Z fredt $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<book version="5.0" xml:id="guide" xmlns="http://docbook.org/ns/docbook"
+      xmlns:xlink="http://www.w3.org/1999/xlink"
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      xmlns:ns5="http://www.w3.org/1999/xhtml"
+      xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+      xmlns:ns3="http://www.w3.org/2000/svg"
+      xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <info>
+    <title>HyperSQL User Guide</title>
+
+    <subtitle>HyperSQL Database Engine, aka HSQLDB</subtitle>
+
+    <authorgroup>
+      <editor>
+        <orgname>The HSQL Development Group</orgname>
+      </editor>
+
+      <editor>
+        <personname><firstname>Blaine</firstname>
+        <surname>Simpson</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </editor>
+
+      <editor>
+        <personname><firstname>Fred</firstname>
+        <surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </editor>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+    <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>Database</keyword>
+
+      <keyword>JDBC</keyword>
+
+      <keyword>Java</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2002-2010 The HSQL Development Group. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <preface xml:id="book-pref">
+    <title>Preface</title>
+
+    <para>HSQLDB (HyperSQL DataBase) is a modern relational database manager
+    that conforms closely to the SQL:2008 Standard and JDBC 4 specifications.
+    It supports all core features and many of the optional features of
+    SQL:2008.</para>
+
+    <para>The first versions of HSQLDB were released in 2001. Version 2.0,
+    first released in 2010, includes a complete rewrite of most parts of the
+    database engine.</para>
+
+    <para>This documentation covers HyperSQL version 2.0. This documentation
+    is regularly improved and undated. The latest, updated version can be
+    found at http://hsqldb.org/doc/2.0/</para>
+
+    <para>If you notice any mistakes in this document, or if you have problems
+    with the procedures themselves, please use the HSQLDB support facilities
+    which are listed at http://hsqldb.org/support</para>
+
+    <xi:include href="../altformats-sect.xml" />
+  </preface>
+
+  <xi:include href="running.xml" />
+
+  <xi:include href="sqlgeneral.xml" />
+
+  <xi:include href="sessions.xml" />
+
+  <xi:include href="databaseobjects.xml" />
+
+  <xi:include href="texttables.xml" />
+
+  <xi:include href="accesscontrol.xml" />
+
+  <xi:include href="dataaccess.xml" />
+
+  <xi:include href="sqlroutines.xml" />
+
+  <xi:include href="triggers.xml" />
+
+  <xi:include href="builtinfunctions.xml" />
+
+  <xi:include href="deployment.xml" />
+
+  <xi:include href="dbproperties.xml" />
+
+  <xi:include href="listeners.xml" />
+
+  <xi:include href="unix.xml" />
+
+  <xi:include href="lists-app.xml" />
+
+  <xi:include href="building-app.xml" />
+
+  <xi:include href="openoffice-app.xml" />
+
+  <xi:include href="filelinks-app.xml" />
+
+  <index type="sql" xml:id="sql-ind">
+    <title>SQL Index</title>
+  </index>
+
+  <index xml:id="book-ind">
+    <title>General Index</title>
+  </index>
+</book>
diff --git a/doc-src/guide/listeners.xml b/doc-src/guide/listeners.xml
new file mode 100644
index 0000000..82ec6c2
--- /dev/null
+++ b/doc-src/guide/listeners.xml
@@ -0,0 +1,899 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: listeners.xml 3601 2010-06-01 00:17:47Z fredt $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<chapter version="5.0" xml:id="listeners-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/2000/svg"
+         xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <info>
+    <title xml:id="listeners-title">HyperSQL Network Listeners</title>
+
+    <subtitle>Server, WebServer, and Servlet</subtitle>
+
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname>
+        <surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+    <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>Server</keyword>
+
+      <keyword>Listener</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2002-2009 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section xml:id="listeners-sect">
+    <title>Listeners</title>
+
+    <simpara>As described in the <link endterm="running-title"
+    xlink:href="#running-chapt"></link> chapter, network listeners or servers
+    provide connectivity to catalogs from different JVM processes. The
+    HyperSQL listeners support both ipv4 and ipv6 network
+    addressing.</simpara>
+
+    <section xml:id="listeners_hsqlserver-sect">
+      <title>HyperSQL Server</title>
+
+      <para>This is the preferred way of running a database server and the
+      fastest one. This mode uses the proprietary <glossterm>hsql:</glossterm>
+      communications protocol. The following example of the command for
+      starting the server starts the server with one (default) database with
+      files named "mydb.*" and the public name (alias) of "xdb".</para>
+
+      <informalexample>
+        <screen>    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb</screen>
+      </informalexample>
+
+      <para>Alternatively, a server.properties file can be used for passing
+      the arguments to the server. This file must be located in the directory
+      where the command is issued.</para>
+
+      <screen>    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server</screen>
+
+      <para>The contents of the server.properties file is described in the
+      next section.</para>
+    </section>
+
+    <section xml:id="listeners_httpserver-sect">
+      <title>HyperSQL HTTP Server</title>
+
+      <para>This method of access is used when the computer hosting the
+      database server is restricted to the HTTP protocol. The only reason for
+      using this method of access is restrictions imposed by firewalls on the
+      client or server machines and it should not be used where there are no
+      such restrictions. The HyperSQL HTTP Server is a special web server that
+      allows JDBC clients to connect via HTTP. The server can also act as a
+      small general-purpose web server for static pages.</para>
+
+      <para>To run an HTTP server, replace the main class for the server in
+      the example command line above with the following:</para>
+
+      <informalexample>
+        <screen>    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server</screen>
+      </informalexample>
+
+      <para>The contents of the server.properties file is described in the
+      next section.</para>
+    </section>
+
+    <section xml:id="listeners_servlet-sect">
+      <title>HyperSQL HTTP Servlet</title>
+
+      <para>This method of access also uses the HTTP protocol. It is used when
+      a separate servlet engine (or application server) such as Tomcat or
+      Resin provides access to the database. The Servlet Mode cannot be
+      started independently from the servlet engine. The
+      <filename>Servlet</filename> class, in the HSQLDB jar, should be
+      installed on the application server to provide the connection. The
+      database is specified using an application server property. Refer to the
+      source file <filename xlink:href="#Servlet.java-link">
+      src/org/hsqldb/server/Servlet.java</filename> to see the details.</para>
+
+      <para>Both HTTP Server and Servlet modes can only be accessed using the
+      JDBC driver at the client end. They do not provide a web front end to
+      the database. The Servlet mode can serve only a single database.</para>
+
+      <para>Please note that you do not normally use this mode if you are
+      using the database engine in an application server. In this situation,
+      connections to a catalog are usually made
+      <glossterm>in-process</glossterm>, or using an external HSQL Server
+      instance.</para>
+    </section>
+  </section>
+
+  <section xml:id="listeners_server_props-sect">
+    <title>Server and Web Server Properties</title>
+
+    <para>Properties files for running the servers are not created
+    automatically. You should create your own files that contain
+    <property>server.property</property>=<literal>value</literal> pairs for
+    each property. The <filename>server.properties</filename> or
+    <filename>webserver.properties</filename> files must be located in the
+    directory where the command to run the
+    <classname>org.hsqldb.server.Server</classname> class is issued.</para>
+
+    <para>In all properties files, values are case-sensitive. All values apart
+    from names of files or pages are required in lowercase (e.g.
+    <property>server.silent</property>=<literal>FALSE</literal> will have no
+    effect, but <property>server.silent</property>=<literal>false</literal>
+    will work). Supported properties and their default values (if any) are as
+    follows:</para>
+
+    <table frame="all" pgwide="1" tocentry="1">
+      <title>common server and webserver properties</title>
+
+      <tgroup align="left" cols="3">
+        <colspec colwidth="4cm" />
+
+        <colspec colwidth="4cm" />
+
+        <colspec />
+
+        <thead>
+          <row>
+            <entry>Value</entry>
+
+            <entry>Default</entry>
+
+            <entry>Description</entry>
+          </row>
+        </thead>
+
+        <tbody valign="top">
+          <row>
+            <entry><property>server.database.0</property></entry>
+
+            <entry><literal>file:test</literal></entry>
+
+            <entry>the catalog type, path and file name of the first database
+            file to use</entry>
+          </row>
+
+          <row>
+            <entry><property>server.dbname.0</property></entry>
+
+            <entry><literal>""</literal></entry>
+
+            <entry>lowercase server alias for the first database file</entry>
+          </row>
+
+          <row>
+            <entry><property>server.database.n</property></entry>
+
+            <entry><literal>NO DEFAULT</literal></entry>
+
+            <entry>the catalog type, path and file name of the n'th database
+            file in use</entry>
+          </row>
+
+          <row>
+            <entry><property>server.dbname.n</property></entry>
+
+            <entry><literal>NO DEFAULT</literal></entry>
+
+            <entry>lowercase server alias for the n'th database file</entry>
+          </row>
+
+          <row>
+            <entry><property>server.silent</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>no extensive messages displayed on console</entry>
+          </row>
+
+          <row>
+            <entry><property>server.trace</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>JDBC trace messages displayed on console</entry>
+          </row>
+
+          <row>
+            <entry><property>server.address</property></entry>
+
+            <entry><literal>NO DEFAULT</literal></entry>
+
+            <entry>IP address of server</entry>
+          </row>
+
+          <row>
+            <entry><property>server.tls</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>Whether to encrypt network stream. If this is set to
+            <literal>true</literal>, then in normal situations you will also
+            need to set properties
+            <varname>system.javax.net.ssl.keyStore</varname> and
+            <varname>system.javax.net.ssl.keyStorePassword</varname>, as
+            documented elsewhere. The value of <varname>server.tls</varname>
+            impacts the default value of
+            <varname>server.port</varname>.</entry>
+          </row>
+
+          <row>
+            <entry><property>server.remote_open</property></entry>
+
+            <entry><literal>false</literal></entry>
+
+            <entry>Allows opening a database path remotely when the first
+            connection is made</entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <para>In HyperSQL version 2.0, each server can serve an unlimited number
+    of databases simultaneously. The <property>server.database.0</property>
+    property defines the filename / path whereas the
+    <property>server.dbname.0</property> defines the lowercase alias used by
+    clients to connect to that database. The digit 0 is incremented for the
+    second database and so on. Values for the
+    <property>server.database.n</property> property can use the
+    <glossterm>mem:</glossterm>, <glossterm>file:</glossterm> or
+    <glossterm>res:</glossterm> prefixes and connection properties as
+    discussed under CONNECTIONS. For example, <informalexample>
+        <programlisting>    database.0=mem:temp;sql.enforce_strict_size=true;</programlisting>
+      </informalexample></para>
+
+    <para>Properties or default values specific to
+    <filename>server.properties</filename> are:</para>
+
+    <table frame="all" pgwide="1" tocentry="1">
+      <title>server properties</title>
+
+      <tgroup align="left" cols="3">
+        <colspec colwidth="4cm" />
+
+        <colspec colwidth="4cm" />
+
+        <colspec />
+
+        <thead>
+          <row>
+            <entry>Value</entry>
+
+            <entry>Default</entry>
+
+            <entry>Description</entry>
+          </row>
+        </thead>
+
+        <tbody valign="top">
+          <row>
+            <entry><property>server.port</property></entry>
+
+            <entry><literal>9001 (normal) or 554 (if TLS
+            encrypted)</literal></entry>
+
+            <entry>TCP/IP port used for talking to clients. All databases are
+            served on the same port.</entry>
+          </row>
+
+          <row>
+            <entry><property>server.no_system_exit</property></entry>
+
+            <entry><literal>true</literal></entry>
+
+            <entry>no <literal>System.exit()</literal> call when the database
+            is closed</entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <para>Properties or default values specific to
+    <filename>webserver.properties</filename> are:</para>
+
+    <table frame="all" pgwide="1" tocentry="1">
+      <title>webserver properties</title>
+
+      <tgroup align="left" cols="3">
+        <colspec colwidth="4cm" />
+
+        <colspec colwidth="4cm" />
+
+        <colspec />
+
+        <thead>
+          <row>
+            <entry>Value</entry>
+
+            <entry>Default</entry>
+
+            <entry>Description</entry>
+          </row>
+        </thead>
+
+        <tbody valign="top">
+          <row>
+            <entry><property>server.port</property></entry>
+
+            <entry><literal>80 (normal) or 443 (if TLS
+            encrypted)</literal></entry>
+
+            <entry>TCP/IP port used for talking to clients</entry>
+          </row>
+
+          <row>
+            <entry><property>server.default_page</property></entry>
+
+            <entry><literal>index.html</literal></entry>
+
+            <entry>the default web page for server</entry>
+          </row>
+
+          <row>
+            <entry><property>server.root</property></entry>
+
+            <entry><literal>./</literal></entry>
+
+            <entry>the location of served pages</entry>
+          </row>
+
+          <row>
+            <entry><property>.&lt;extension&gt;</property></entry>
+
+            <entry><literal>NO DEFAULT</literal></entry>
+
+            <entry>multiple entries such as <literal>.html=text/html</literal>
+            define the mime types of the static files served by the web
+            server. See the source for <filename
+            xlink:href="#WebServer.java-link">
+            src/org/hsqldb/server/WebServer.java</filename> for a
+            list.</entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <para>An example of the contents of a
+    <filename>server.properties</filename> file is given below:</para>
+
+    <programlisting>    server.database.0=file:/opt/db/accounts
+    server.dbname.0=accounts
+
+    server.database.1=file:/opt/db/mydb
+    server.dbname.1=enrollments
+
+    server.database.2=mem:adatabase
+    server.dbname.2=quickdb</programlisting>
+
+    <para>In the above example, the <filename>server.properties</filename>
+    file indicates that the server provides access to 3 different databases.
+    Two of the databases are file-based, while the third is all-in-memory. The
+    aliases for the databases that the users connect to are
+    <literal>accounts</literal>, <literal>enrollments</literal> and
+    <literal>quickdb</literal>.</para>
+
+    <para>All the above properties and their values can be specified on the
+    command line to start the server by omitting the
+    <literal>server.</literal> prefix. If a property/value pair is specified
+    on the command line, it overrides the property value specified in the
+    <filename>server.properties</filename> or
+    <filename>webserver.properties</filename> file.</para>
+
+    <note>
+      <para>Upgrading: If you have existing custom properties files, change
+      the values to the new naming convention. Note the use of digits at the
+      end of <property>server.database.n</property> and
+      <property>server.dbname.n</property> properties.</para>
+    </note>
+  </section>
+
+  <section xml:id="listeners_appstart-sect">
+    <title>Starting a Server from your application</title>
+
+    <para>If you want to start the server from within your application, as
+    opposed to the command line or batch files, you should create an instance
+    of Server or Web Server, then assign the properties and start the Server.
+    An working example of this can be found in the <classname
+    xlink:href="#TestBase.java-link"> org.hsqldb.test.TestBase</classname>
+    source. The example below sets the same properties as in the
+    server.properties file example.</para>
+
+    <programlisting>    HsqlProperties p = new HsqlProperties();
+    p.setProperty("server.database.0","file:/opt/db/accounts");
+    p.setProperty("server.dbname.0","an_alias");
+    // set up the rest of properties
+    Server server = new Server();
+    server.setProperties(p);
+    server.setLogWriter(null); // can use custom writer
+    server.setErrWriter(null); // can use custom writer
+    server.start();
+</programlisting>
+
+    <para>The Server object has several alternative methods for setting
+    databases and their public names. The server should be shutdown using the
+    shutdown() method.</para>
+  </section>
+
+  <section>
+    <title>Allowing a Connection to Open a Database</title>
+
+    <para>If the <literal>server.remote_open</literal> property is true, the
+    Server works differently from the normal mode. In this mode, it is not
+    necessary to have any databases listed as server.database.0 etc. in the
+    Server startup properties. If there are databases listed, they are opened
+    as normal. The server does not shutdown when the last database is
+    closed.</para>
+
+    <para>In this mode, a connection can be established to a database that is
+    not open or does not exist. The server will open the database or create
+    it, then return a connection to the database.</para>
+
+    <para>The connection URL must include the path to the database, separated
+    with a semicolon from the alias. In the example below, the database path
+    specified as <literal>file:C:/files/mydatabase</literal> is opened and the
+    database alias <literal>xdb</literal> is assigned to the database. After
+    this, the next connection to the specified alias will connect to the same
+    database.</para>
+
+    <programlisting>Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb;file:C:/files/mydatabase", "SA", "");
+</programlisting>
+
+    <para>The path can be a file: or mem: database.</para>
+  </section>
+
+  <section xml:id="listeners_tls-sect">
+    <info>
+      <title xml:id="tls-sect-title">TLS Encryption</title>
+
+      <subtitle>Listener TLS Support (a. k. a. SSL)</subtitle>
+
+      <authorgroup>
+        <author>
+          <personname><firstname>Blaine</firstname>
+          <surname>Simpson</surname></personname>
+
+          <affiliation>
+            <orgname>The HSQL Development Group</orgname>
+          </affiliation>
+        </author>
+      </authorgroup>
+
+      <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+      <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+      <keywordset>
+        <keyword>HyperSQL</keyword>
+
+        <keyword>HSQLDB</keyword>
+
+        <keyword>TLS</keyword>
+
+        <keyword>SSL</keyword>
+
+        <keyword>JSSE</keyword>
+
+        <keyword>Security</keyword>
+      </keywordset>
+    </info>
+
+    <indexterm>
+      <primary>security</primary>
+    </indexterm>
+
+    <para>This section explains how to encrypt the stream between JDBC network
+    clients and HyperSQL Listeners. If you are running an
+    <glossterm>in-process</glossterm> (non-Listener) setup, this chapter does
+    not apply to you.</para>
+
+    <section>
+      <title>Requirements</title>
+
+      <itemizedlist>
+        <title>Hsqldb TLS Support Requirements</title>
+
+        <listitem>
+          <para>Sun Java 2.x and up. (This is probably possible with IBM's
+          Java, but I don't think anybody has attempted to run HSQLDB with TLS
+          under IBM's Java, and I'm sure that nobody in the HSQLDB Development
+          Group has documented how to set up the environment).</para>
+        </listitem>
+
+        <listitem>
+          <para>If Java 2.x or 3.x, then you will need to <link
+          xlink:href="#jsse-sect">install JSSE</link>. Your server and/or
+          client will start up much slower than that of Java 4.x users.
+          Client-side users will not be able to use the https: JDBC protocol
+          (because the https protocol handler is not implemented in 2.x/3.x
+          Java JSSE; if there is demand, we could work around this).</para>
+        </listitem>
+
+        <listitem>
+          <para>A <link xlink:href="#privatekey-sect">JKS keystore containing
+          a private key</link>, in order to run a Listener.</para>
+        </listitem>
+
+        <listitem>
+          <para>If you are running the listener side, then you'll need to run
+          a HSQLDB Server or WebServer Listener instance. It doesn't matter if
+          the underlying database catalogs are new, and it doesn't matter if
+          you are making a new Listener configuration or encrypting an
+          existing Listener configuration. (You can turn encryption on and off
+          at will).</para>
+        </listitem>
+
+        <listitem>
+          <para>You need a HSQLDB jar file that was built with JSSE present.
+          If you obtained your HSQLDB 1.7.2-or-later distribution from us, you
+          are all set, because we build with Java 1.4 or later (which contains
+          JSSE). If you build your own jar file with Java 1.3, make sure to
+          install JSSE first.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section>
+      <title>Encrypting your JDBC connection</title>
+
+      <para>At this time, only 1-way, server-cert encryption is tested.</para>
+
+      <section>
+        <title>Client-Side</title>
+
+        <para>Just use one of the following protocol prefixes.</para>
+
+        <itemizedlist>
+          <title>Hsqldb TLS URL Prefixes</title>
+
+          <listitem>
+            <para><literal>jdbc:hsqldb:hsqls://</literal></para>
+          </listitem>
+
+          <listitem>
+            <para><literal>jdbc:hsqldb:https://</literal></para>
+          </listitem>
+        </itemizedlist>
+
+        <para>At this time, the latter will only work for clients running with
+        Java 1.4 or later.</para>
+
+        <para>If the listener you wish to connect to is using a certificate
+        approved by your default trust keystore, then there is nothing else to
+        do. If not, then you need to tell Java to "trust" the server cert.
+        (It's a slight over-simplification to say that if the server
+        certificate was purchased, then you are all set; if somebody "signed
+        their own" certificate by self-signing or using a private ca
+        certificate, then you need to set up trust).</para>
+
+        <para>First, you need to obtain the cert (only the "public" part of
+        it). Since this cert is passed to all clients, you could obtain it by
+        writing a Java client that dumps it to file, or perhaps by using
+        <emphasis>openssl s_client</emphasis>. Since in most cases, if you
+        want to trust a non-commercial cert, you probably have access to the
+        server keystore, I'll show an example of how to get what you need from
+        the server-side JKS keystore.</para>
+
+        <para>You may already have an X509 cert for your server. If you have a
+        server keystore, then you can generate a X509 cert like this. <example>
+            <title>Exporting certificate from the server's keystore</title>
+
+            <screen>    keytool -export -keystore server.store -alias existing_alias -file server.cer</screen>
+          </example> In this example, <filename>server.cer</filename> is the
+        X509 certificate that you need for the next step.</para>
+
+        <para>Now, you need to add this cert to one of the system trust
+        keystores or to a keystore of your own. See <link
+        xlink:href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores">
+        the Customizing Stores section in JSSERefGuide.html</link> to see
+        where your system trust keystores are. You can put private keystores
+        anywhere you want to. The following command will add the cert to an
+        existing keystore, or create a new keystore if
+        <filename>client.store</filename> doesn't exist.</para>
+
+        <example>
+          <title>Adding a certificate to the client keystore</title>
+
+          <screen>    keytool -import -trustcacerts -keystore trust.store -alias new_alias -file server.cer</screen>
+        </example>
+
+        <para>If you are making a new keystore, you probably want to start
+        with a copy of your system default keystore which you can find
+        somewhere under your <varname>JAVA_HOME</varname> directory (typically
+        <filename>jre/lib/security/cacerts</filename> for a JDK, but I forget
+        exactly where it is for a JRE).</para>
+
+        <para>Unless your OS can't stop other people from writing to your
+        files, you probably do not want to set a password on the trust
+        keystore.</para>
+
+        <para>If you added the cert to a system trust store, then you are
+        finished. Otherwise you will need to specify your custom trust
+        keystore to your client program. The generic way to set the trust
+        keystore is to set the system property
+        <classname>javax.net.ssl.trustStore</classname> every time that you
+        run your client program. For example <example>
+            <title>Specifying your own trust store to a JDBC client</title>
+
+            <screen>    java -Djavax.net.ssl.trustStore=/home/blaine/trust.store -jar /path/to/hsqldb.jar dest-urlid</screen>
+          </example> This example runs the program <link
+        xlink:href="#unix-chapt">SqlTool</link>. SqlTool has built-in TLS
+        support however, so, for SqlTool you can set
+        <varname>truststore</varname> on a per-urlid basis in the SqlTool
+        configuration file.</para>
+
+        <para>Note: The hostname in your database URL must match the
+        <emphasis>Common Name</emphasis> of the server's certificate exactly.
+        That means that if a site certificate is <literal>admc.com</literal>,
+        you can not use <literal>jdbc:hsqldb:hsqls://localhost</literal> or
+        <literal>jdbc:hsqldb:hsqls://www.admc.com:1100</literal> to connect to
+        it.</para>
+
+        <para>If you want more details on anything, see JSSERefGuide.html on
+        <link
+        xlink:href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html">
+        Sun's site</link>, or in the subdirectory
+        <filename>docs/guide/security/jsse</filename> of your Java SE
+        docs.</para>
+      </section>
+
+      <section>
+        <title>Server-Side, aka Listener-Side</title>
+
+        <simpara>Get yourself a <link xlink:href="#privatekey-sect"> JKS
+        keystore containing a private key</link>. Then set properties
+        <varname>server.tls</varname>,
+        <varname>system.javax.net.ssl.keyStore</varname> and
+        <varname>system.javax.net.ssl.keyStorePassword</varname> in your
+        <filename>server.properties</filename> or
+        <filename>webserver.properties</filename> file. Set
+        <varname>server.tls</varname> to <literal>true</literal>,
+        <varname>system.javax.net.ssl.keyStore</varname> to the path of the
+        private key JKS keystore, and
+        <varname>system.javax.net.ssl.keyStorePassword</varname> to the
+        password (of both the keystore and the private key record-- they must
+        be the same). If you specify relative file path values, they will be
+        resolved relative to the <varname>${user.dir}</varname> when the JRE
+        is started.</simpara>
+
+        <caution xml:id="tlspassword-caution">
+          <para>If you set any password in a .properties (or any other) file,
+          you need to restrict access to the file. On a good operating system,
+          you can do this like so: <informalexample>
+              <screen>    chmod 600 path/to/server.properties</screen>
+            </informalexample></para>
+        </caution>
+
+        <simpara>The values and behavior of the <literal>system.*</literal>
+        settings above match the usage documented for
+        <varname>javax.net.ssl.keyStorePassword</varname> and
+        <varname>javax.net.ssl.keyStore</varname> in the JSSE docs.</simpara>
+
+        <note>
+          <simpara>Before version 2.0, HyperSQL depended on directly setting
+          the corresponding JSSE properties. The new idiom is more secure and
+          easier to manage. If you have an old password in a UNIX init script
+          config file, you should remove it.</simpara>
+        </note>
+      </section>
+    </section>
+
+    <section xml:id="jsse-sect">
+      <title>JSSE</title>
+
+      <para>If you are running Java 4.x or later, then you are all set. Java
+      1.x users, you are on your own (Sun does not provide a JSSE that will
+      work with 1.x). Java 2.x and 3.x users continue...</para>
+
+      <para>Go to <link
+      xlink:href="http://java.sun.com/products/jsse/index-103.html"></link> If
+      you agree to the terms and meet the requirements, download the domestic
+      or global JSSE software. All you need from the software distro is the
+      three jar files. If you have a JDK installation, then move the 3 jar
+      files into the directory <filename>$JAVA_HOME/jre/lib/ext</filename>. If
+      you have a JRE installation, then move the 3 jar files into the
+      directory <filename>$JAVA_HOME/lib/ext</filename>.</para>
+
+      <para>Pretty painless.</para>
+    </section>
+
+    <section xml:id="privatekey-sect">
+      <title>Making a Private-key Keystore</title>
+
+      <para>There are two main ways to do this. Either you can use a
+      certificate signed by a certificate authority, or you can make your own.
+      One thing that you need to know in both cases is, the <emphasis>Common
+      Name</emphasis> of the cert has to be the exact hostname that JDBC
+      clients will use in their database URL.</para>
+
+      <section>
+        <title>CA-Signed Cert</title>
+
+        <para>I'm not going to tell you how to get a CA-signed SSL
+        certificate. That is well documented at many other places.</para>
+
+        <para>Assuming that you have a standard pem-style private key
+        certificate, here's how you can use <link
+        xlink:href="http://www.openssl.org">openssl</link> and the program
+        <classname>DERImport</classname> to get it into a JKS keystore.</para>
+
+        <para>Because I have spent a lot of time on this document already, I
+        am just giving you an example.</para>
+
+        <example>
+          <title>Getting a pem-style private key into a JKS keystore</title>
+
+          <screen>    openssl pkcs8 -topk8 -outform DER -in Xpvk.pem -inform PEM -out Xpvk.pk8 -nocrypt
+
+    openssl x509 -in Xcert.pem -out Xcert.der -outform DER
+
+    java DERImport new.keystore NEWALIAS Xpvk.pk8 Xcert.der</screen>
+        </example>
+
+        <important>
+          <para>Make sure to set the password of the key exactly the same as
+          the password for the keystore!</para>
+        </important>
+
+        <para>You need the program <filename>DERImport.class</filename> of
+        course. Do some internet searches to find
+        <filename>DERImport.java</filename> or
+        <filename>DERImport.class</filename> and download it.</para>
+
+        <para>If DERImport has become difficult to obtain, I can write a
+        program to do the same thing-- just let me know.</para>
+      </section>
+
+      <section>
+        <title>Non-CA-Signed Cert</title>
+
+        <para>Run <literal>man keytool</literal> or see <link
+        xlink:href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore">
+        the Creating a Keystore section of JSSERefGuide.html</link>.</para>
+      </section>
+    </section>
+
+    <section>
+      <title>Automatic Server or WebServer startup on UNIX</title>
+
+      <para>If you are on UNIX and want to automatically start and stop a
+      Server or WebServer running with encryption, set the
+      <varname>system.javax.net.ssl.keyStore</varname> and
+      <varname>system.javax.net.ssl.keyStorePassword</varname> properties as
+      instructed above, and follow the instructions in the <link
+      endterm="unix-title" xlink:href="#unix-chapt"></link> chapter, paying
+      close attention to the TLS-related comments in the template config
+      file.</para>
+
+      <para>If you are using a private server certificate, make sure to also
+      set the trust store filepath for relevant urlids in your RC file, as
+      explained in the sample <link xlink:href="#hsqldb.cfg-link">config
+      file</link>.</para>
+    </section>
+  </section>
+
+  <section xml:id="listeners_acl-sect">
+    <info>
+      <title>Network Access Control</title>
+
+      <subtitle>Aka Server ACLs</subtitle>
+    </info>
+
+    <indexterm>
+      <primary>security</primary>
+    </indexterm>
+
+    <indexterm>
+      <primary>ACL</primary>
+    </indexterm>
+
+    <simpara>JDBC connections will always be denied if the supplied user and
+    password are not found in the target catalog. But an HyperSQL listener can
+    also restrict access at the listener level, even protecting private
+    catalogs which have insecure (or default) passwords. If you have an
+    <glossterm>in-process</glossterm> setup, this section of the Guide doesn't
+    apply to you.</simpara>
+
+    <simpara>Many (in fact, most) distributed database applications don't have
+    application clients connect directly to the database, but instead
+    encapsulate access in a controlling process. For example, a web app will
+    usually access the data source on behalf of users, with end-user web
+    browsers never accessing the database directly. In these cases and others,
+    the security benefits of restricting listener access to specific source
+    addresses is well worth the effort. ACLs work by restricting access
+    according to the source address of the incoming connection request. This
+    is efficient because the database engine never even gets the request until
+    it is approved by the ACL filter code.</simpara>
+
+    <para>The sample file <filename
+    xlink:href="#acl.txt-link">sample/acl.txt</filename> in your HyperSQL
+    distribution explains how to write an ACL file. <programlisting><xi:include
+          href="../verbatim/sample/acl.txt" parse="text" /></programlisting>
+    You put your file wherever it is convenient for you, and specify that path
+    with the property <varname>server.acl</varname> or
+    <varname>webserver.acl</varname> in your
+    <filename>server.properties</filename> or
+    <filename>webserver.properties</filename> file (depending on whether your
+    listener instance is a <classname>Server</classname> or
+    <classname>WebServer</classname>). You can specify the ACL file path with
+    an absolute or relative path. If you use a relative path, it must be
+    relative to the <filename>.properties</filename> file. It's often
+    convenient to name the ACL file <filename>acl.txt</filename>, in the same
+    directory as your <filename>.properties</filename> file and specify the
+    property value as just <filename>acl.txt</filename>. This file name is
+    intuitive, and things will continue to work as expected if you move or
+    copy the entire directory.</para>
+
+    <warning>
+      <simpara>If your <classname>Server</classname> or
+      <classname>WebServer</classname> was started with a
+      <varname>*.acl</varname> property, changes afterwards to the ACL file
+      will be picked up immediately by your listener instance. You are advised
+      to use the procedure below to prevent partial edits or mistakes from
+      crippling your running server.</simpara>
+    </warning>
+
+    <para>When you edit your ACL file, it is both more convenient and more
+    secure to test it as explained here before activating it. You could, of
+    course, test an ACL file by editing it in-place, then trying to connect to
+    your listener with JDBC clients from various source addresses. Besides
+    being mightily laborious and boring, with this method it is very easy to
+    accidentally open access to all source addresses or to deny access to all
+    users until you fix incorrect ACL entries.</para>
+
+    <para>The suggested method of creating or changing ACLs is to work with an
+    inactive file (for new ACL files, just don't enable the
+    <varname>*.acl</varname> property yet; for changing an existing file, just
+    copy it to a temporary file and edit the temporary file). Then use the
+    <classname>ServerAcl</classname> class to test it. <example>
+        <title>Validating and Testing an ACL file</title>
+
+        <screen>    java -cp path/to/hsqldb.jar org.hsqldb.server.ServerAcl path/to/acl.txt</screen>
+      </example> If the specified ACL file fails validation, you will be given
+    details about the problem. Otherwise, the validated rules will be
+    displayed (including the implicit, default deny rules). You then type in
+    host names and addresses, one-per-line. Each name or address is tested as
+    if it were a HyperSQL network client address, using the same exact method
+    that the HyperSQL listener will use. (HyperSQL listeners use this same
+    <classname>ServerAcl</classname> class to test incoming source addresses).
+    <classname>ServerAcl</classname> will report the rule which matches and
+    whether access is denied or allowed to that address.</para>
+
+    <simpara>If you have edited a copy of an existing ACL file (as suggested
+    above), then overwrite your live ACL file with your new, validated ACL
+    file. I.e., copy your temp file over top of your live ACL file.</simpara>
+
+    <simpara><classname>ServerAcl</classname> can be run in the same exact way
+    described above, to troubleshoot runtime access issues. If you use an ACL
+    file and a user or application can't get a connection to the database, you
+    can run <classname>ServerAcl</classname> to quickly and definitively find
+    if the client is being prohibited by an ACL rule.</simpara>
+  </section>
+</chapter>
diff --git a/doc-src/guide/lists-app.xml b/doc-src/guide/lists-app.xml
new file mode 100644
index 0000000..b481e3e
--- /dev/null
+++ b/doc-src/guide/lists-app.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: openoffice-app.xml 847 2009-01-19 22:24:49Z unsaved $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<appendix version="5.0" xml:id="lists-app"
+          xmlns="http://docbook.org/ns/docbook"
+          xmlns:xlink="http://www.w3.org/1999/xlink"
+          xmlns:xi="http://www.w3.org/2001/XInclude"
+          xmlns:ns5="http://www.w3.org/1999/xhtml"
+          xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+          xmlns:ns3="http://www.w3.org/2000/svg"
+          xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <info>
+    <title xml:id="lists-title">Lists of Keywords</title>
+
+    <subtitle>List of SQL Keywords</subtitle>
+
+    <author>
+      <personname><firstname>Fred</firstname>
+      <surname>Toussi</surname></personname>
+
+      <affiliation>
+        <orgname>The HSQL Development Group</orgname>
+      </affiliation>
+    </author>
+
+    <releaseinfo>$Revision: 847 $</releaseinfo>
+
+    <pubdate>$Date: 2009-01-19 22:24:49 +0000 (Mon, 19 Jan 2009) $</pubdate>
+
+    <keywordset>
+      <keyword>HSQLDB</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL Keywords SQL STAT</keyword>
+    </keywordset>
+  </info>
+
+  <section>
+    <title>List of SQL Standard Keywords</title>
+
+    <para>According to the SQL Standard, the SQL Language keywords cannot be
+    used as identifiers (names of database objects such as columns and
+    tables). HyperSQL has two modes of operation, which are selected with the
+    SET DATABASE SQL NAMES { TRUE | FALSE } to allow or disallow the keywords
+    as identifiers. The default mode is FALSE and allows the use of most
+    keywords as identifiers. Even in this mode, keywords cannot be used as
+    USER or ROLE identifiers.</para>
+
+    <simpara>ABS ALL ALLOCATE ALTER AND ANY ARE ARRAY AS ASENSITIVE ASYMMETRIC
+    AT ATOMIC AUTHORIZATION AVG</simpara>
+
+    <simpara>BEGIN BETWEEN BIGINT BINARY BLOB BOOLEAN BOTH BY</simpara>
+
+    <simpara>CALL CALLED CARDINALITY CASCADED CASE CAST CEIL CEILING CHAR
+    CHAR_LENGTH CHARACTER CHARACTER_LENGTH CHECK CLOB CLOSE COALESCE COLLATE
+    COLLECT COLUMN COMMIT COMPARABLE CONDITION CONNECT CONSTRAINT CONVERT CORR
+    CORRESPONDING COUNT COVAR_POP COVAR_SAMP CREATE CROSS CUBE CUME_DIST
+    CURRENT CURRENT_CATALOG CURRENT_DATE CURRENT_DEFAULT_TRANSFORM_GROUP
+    CURRENT_PATH CURRENT_ROLE CURRENT_SCHEMA CURRENT_TIME CURRENT_TIMESTAMP
+    CURRENT_TRANSFORM_GROUP_FOR_TYPE CURRENT_USER CURSOR CYCLE</simpara>
+
+    <simpara>DATE DAY DEALLOCATE DEC DECIMAL DECLARE DEFAULT DELETE DENSE_RANK
+    DEREF DESCRIBE DETERMINISTIC DISCONNECT DISTINCT DO DOUBLE DROP
+    DYNAMIC</simpara>
+
+    <simpara>EACH ELEMENT ELSE ELSEIF END END_EXEC ESCAPE EVERY EXCEPT EXEC
+    EXECUTE EXISTS EXIT EXP EXTERNAL EXTRACT</simpara>
+
+    <simpara>FALSE FETCH FILTER FIRST_VALUE FLOAT FLOOR FOR FOREIGN FREE FROM
+    FULL FUNCTION FUSION</simpara>
+
+    <simpara>GET GLOBAL GRANT GROUP GROUPING</simpara>
+
+    <simpara>HANDLER HAVING HOLD HOUR</simpara>
+
+    <simpara>IDENTITY IN INDICATOR INNER INOUT INSENSITIVE INSERT INT INTEGER
+    INTERSECT INTERSECTION INTERVAL INTO IS ITERATE</simpara>
+
+    <simpara>JOIN</simpara>
+
+    <simpara>LAG</simpara>
+
+    <simpara>LANGUAGE LARGE LAST_VALUE LATERAL LEAD LEADING LEAVE LEFT LIKE
+    LIKE_REGEX LN LOCAL LOCALTIME LOCALTIMESTAMP LOOP LOWER</simpara>
+
+    <simpara>MATCH MAX MAX_CARDINALITY MEMBER MERGE METHOD MIN MINUTE MOD
+    MODIFIES MODULE MONTH MULTISET</simpara>
+
+    <simpara>NATIONAL NATURAL NCHAR NCLOB NEW NO NONE NORMALIZE NOT NTH_VALUE
+    NTILE NULL NULLIF NUMERIC</simpara>
+
+    <simpara>OCCURRENCES_REGEX OCTET_LENGTH OF OFFSET OLD ON ONLY OPEN OR
+    ORDER OUT OUTER OVER OVERLAPS OVERLAY</simpara>
+
+    <simpara>PARAMETER PARTITION PERCENT_RANK PERCENTILE_CONT PERCENTILE_DISC
+    POSITION POSITION_REGEX POWER PRECISION PREPARE PRIMARY
+    PROCEDURE</simpara>
+
+    <simpara>RANGE RANK READS REAL RECURSIVE REF REFERENCES REFERENCING
+    REGR_AVGX REGR_AVGY REGR_COUNT REGR_INTERCEPT REGR_R2 REGR_SLOPE REGR_SXX
+    REGR_SXY REGR_SYY RELEASE REPEAT RESIGNAL RESULT RETURN RETURNS REVOKE
+    RIGHT ROLLBACK ROLLUP ROW ROW_NUMBER ROWS</simpara>
+
+    <simpara>SAVEPOINT SCOPE SCROLL SEARCH SECOND SELECT SENSITIVE
+    SESSION_USER SET SIGNAL SIMILAR SMALLINT SOME SPECIFIC SPECIFICTYPE SQL
+    SQLEXCEPTION SQLSTATE SQLWARNING SQRT STACKED START STATIC STDDEV_POP
+    STDDEV_SAMP SUBMULTISET SUBSTRING SUBSTRING_REGEX SUM SYMMETRIC SYSTEM
+    SYSTEM_USER</simpara>
+
+    <simpara>TABLE TABLESAMPLE THEN TIME TIMESTAMP TIMEZONE_HOUR
+    TIMEZONE_MINUTE TO TRAILING TRANSLATE TRANSLATE_REGEX TRANSLATION TREAT
+    TRIGGER TRIM TRIM_ARRAY TRUE TRUNCATE</simpara>
+
+    <simpara>UESCAPE UNDO UNION UNIQUE UNKNOWN UNNEST UNTIL UPDATE UPPER USER
+    USING</simpara>
+
+    <simpara>VALUE VALUES VAR_POP VAR_SAMP VARBINARY VARCHAR VARYING</simpara>
+
+    <simpara>WHEN WHENEVER WHERE WIDTH_BUCKET WINDOW WITH WITHIN WITHOUT
+    WHILE</simpara>
+
+    <simpara>YEAR</simpara>
+  </section>
+
+  <section>
+    <title>List of SQL Keywords Disallowed as HyperSQL Identifiers</title>
+
+    <para>A subset of SQL Standard keywords cannot be used at all as HyperSQL
+    identifiers. The keywords are as follows:</para>
+
+    <simpara>ADMIN AND ALL ANY AS AT AVG</simpara>
+
+    <simpara>BETWEEN BOTH BY</simpara>
+
+    <simpara>CALL CASE CAST COALESCE CORRESPONDING CONVERT COUNT CREATE
+    CROSS</simpara>
+
+    <simpara>DISTINCT DROP</simpara>
+
+    <simpara>ELSE END EVERY EXISTS EXCEPT</simpara>
+
+    <simpara>FOR FROM FULL</simpara>
+
+    <simpara>GRANT GROUP</simpara>
+
+    <simpara>HAVING</simpara>
+
+    <simpara>IN INNER INTERSECT INTO IS</simpara>
+
+    <simpara>JOIN</simpara>
+
+    <simpara>LEFT LEADING LIKE</simpara>
+
+    <simpara>MAX MIN</simpara>
+
+    <simpara>NATURAL NOT NULLIF</simpara>
+
+    <simpara>ON ORDER OR OUTER</simpara>
+
+    <simpara>PRIMARY</simpara>
+
+    <simpara>REFERENCES RIGHT</simpara>
+
+    <simpara>SELECT SET SOME STDDEV_POP STDDEV_SAMP SUM</simpara>
+
+    <simpara>TABLE THEN TO TRAILING TRIGGER</simpara>
+
+    <simpara>UNION UNIQUE USING</simpara>
+
+    <simpara>VALUES VAR_POP VAR_SAMP</simpara>
+
+    <simpara>WHEN WHERE WITH</simpara>
+  </section>
+</appendix>
diff --git a/doc-src/guide/openoffice-app.xml b/doc-src/guide/openoffice-app.xml
new file mode 100644
index 0000000..1e50fe3
--- /dev/null
+++ b/doc-src/guide/openoffice-app.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: openoffice-app.xml 3498 2010-03-06 17:42:28Z fredt $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<appendix version="5.0" xml:id="openoffice-app"
+          xmlns="http://docbook.org/ns/docbook"
+          xmlns:xlink="http://www.w3.org/1999/xlink"
+          xmlns:xi="http://www.w3.org/2001/XInclude"
+          xmlns:ns5="http://www.w3.org/2000/svg"
+          xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+          xmlns:ns3="http://www.w3.org/1999/xhtml"
+          xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <info>
+    <title xml:id="openoffice-title">HyperSQL with OpenOffice.org</title>
+
+    <subtitle>How to use HyperSQL with OpenOffice.org</subtitle>
+
+    <author>
+      <personname><firstname>Fred</firstname>
+      <surname>Toussi</surname></personname>
+
+      <affiliation>
+        <orgname>The HSQL Development Group</orgname>
+      </affiliation>
+    </author>
+
+    <releaseinfo>$Revision: 3498 $</releaseinfo>
+
+    <pubdate>$Date: 2010-03-06 12:42:28 -0500 (Sat, 06 Mar 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>HSQLDB</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>OpenOffice</keyword>
+
+      <keyword>OpenOfficeOrg</keyword>
+    </keywordset>
+  </info>
+
+  <section>
+    <title>HyperSQL with OpenOffice.org</title>
+
+    <simpara>OpenOffice.org includes HyperSQL and uses it for embedded
+    databases. Our collaboration with OpenOffice.org developers over the last
+    few years has benefited the development and maturity of HyperSQL. Before
+    integration into OOo, HSQLDB was intended solely for application-specific
+    database access. The application developer was expected to resolve any
+    integration issues. Because OpenOffice.org is used by a vast range of
+    users, from schoolchildren to corporate developers, a much higher level of
+    quality assurance has been required and we have achieved it with constant
+    help and feedback from OOo users and developers.</simpara>
+
+    <simpara>Apart from embedded use, you may want to use OpenOffic.org with a
+    HyperSQL server instance. The typical use for this is to allow multiple
+    office users accessing the same database. There is, however, a strong case
+    for using OOo to develop your database schema and application, even if the
+    database is intended for your own application.</simpara>
+  </section>
+
+  <section>
+    <title>Using OpenOffice.org as a Database Tool</title>
+
+    <simpara>OpenOffice.org is a very powerful database front end. If you want
+    to create schemas, edit tables, edit the database contents manually,
+    design and produce well-formatted reports, then OpenOffice.org is probably
+    the best open source tools currently available.</simpara>
+
+    <simpara>To connect from OpenOffice.org to your database, first run a
+    local server instance for the database. This is describes in the Network
+    Listeners chapter of this guide.</simpara>
+
+    <simpara>When you connect from OpenOffice.org, you must specify connection
+    to an external database and use the URL property "default_schema=true".
+    For example, the URL to connect the local database may be like</simpara>
+
+    <programlisting> jdbc;hsqldb:hsql://localhost/mydb;default_schema=true </programlisting>
+
+    <simpara>The only current limitation is that OpenOffice.org only works
+    with the PUBLIC schema. This limitation will hopefully removed in the
+    future versions of OOo.</simpara>
+
+    <simpara>When using of HyperSQL with OOo, you must use the HyperSQL jar
+    that is supplied with OOo. This wil hopefuly be a version 2.0 jar in the
+    future versions of OOo.</simpara>
+  </section>
+
+  <section>
+    <title>Converting .odb files to use with HyperSQL Server</title>
+
+    <simpara>You may already have an OOo database file, which you want to use
+    outside OOo, or as a server database. The file is in fact in the standard
+    ZIP format and contains the normal HyperSQL database files. Just use a
+    utility such as 7Zip to expand the .odb file. In the /db directory, there
+    are files such as .script, .data, etc. Just rename these files into
+    mydb.script, mydb.data, etc. You can now open the mydb database directly
+    with HyperSQL as an embedded database or as a server instance.</simpara>
+  </section>
+</appendix>
diff --git a/doc-src/guide/running.xml b/doc-src/guide/running.xml
new file mode 100644
index 0000000..ce85426
--- /dev/null
+++ b/doc-src/guide/running.xml
@@ -0,0 +1,632 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: running.xml 3601 2010-06-01 00:17:47Z fredt $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<chapter version="5.0" xml:id="running-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns4="http://www.w3.org/1999/xhtml"
+         xmlns:ns3="http://www.w3.org/2000/svg"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <title xml:id="running-title">Running and Using HyperSQL</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+    <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section xml:id="running_jar-sect">
+    <title>The HSQLDB Jar</title>
+
+    <para>The HSQLDB jar package is located in the /lib directory of the ZIP
+    package and contains several components and programs.</para>
+
+    <itemizedlist>
+      <title>Components of the Hsqldb jar package</title>
+
+      <listitem>
+        <para>HyperSQL RDBMS Engine (HSQLDB)</para>
+      </listitem>
+
+      <listitem>
+        <para>HyperSQL JDBC Driver</para>
+      </listitem>
+
+      <listitem>
+        <para>Database Manager (GUI database access tool, with Swing and AWT
+        versions)</para>
+      </listitem>
+
+      <listitem>
+        <para>Sql Tool (command line database access tool)</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>The HyperSQL RDBMS and JDBC Driver provide the core functionality.
+    An additional jar contains Sql Tool (command line database access tool).
+    SqlTool and the DatabaseManagers are general-purpose database tools that
+    can be used with any database engine that has a JDBC driver.</para>
+  </section>
+
+  <section xml:id="running_tools-sect">
+    <title>Running Database Access Tools</title>
+
+    <para>The tools are used for interactive user access to databases,
+    including creation of a database, inserting or modifying data, or querying
+    the database. All tools are run in the normal way for Java programs. In
+    the following example the Swing version of the Database Manager is
+    executed. The <filename>hsqldb.jar</filename> is located in the directory
+    <filename>../lib</filename> relative to the current directory.</para>
+
+    <screen>java -cp ../lib/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing</screen>
+
+    <para>If <filename>hsqldb.jar</filename> is in the current directory, the
+    command would change to:</para>
+
+    <screen>java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing</screen>
+
+    <itemizedlist>
+      <title>Main classes for the Hsqldb tools</title>
+
+      <listitem>
+        <para><classname>org.hsqldb.util.DatabaseManager</classname></para>
+      </listitem>
+
+      <listitem>
+        <para><classname>org.hsqldb.util.DatabaseManagerSwing</classname></para>
+      </listitem>
+    </itemizedlist>
+
+    <para>When a tool is up and running, you can connect to a database (may be
+    a new database) and use SQL commands to access and modify the data.</para>
+
+    <para>Tools can use command line arguments. You can add the command line
+    argument --help to get a list of available arguments for these
+    tools.</para>
+  </section>
+
+  <section xml:id="running_db-sect">
+    <title>A HyperSQL Database</title>
+
+    <para>Each HyperSQL database is called a catalog. There are three types of
+    catalog depending on how the data is stored.</para>
+
+    <itemizedlist>
+      <title>Types of catalog data</title>
+
+      <listitem>
+        <para><glossterm>mem:</glossterm> stored entirely in RAM - without any
+        persistence beyond the JVM process's life</para>
+      </listitem>
+
+      <listitem>
+        <para><glossterm>file:</glossterm> stored in filesystem files</para>
+      </listitem>
+
+      <listitem>
+        <para><glossterm>res:</glossterm> stored in a Java resource, such as a
+        Jar and always read-only</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>All-in-memory, <glossterm>mem:</glossterm> catalogs can be used for
+    test data or as sophisticated caches for an application. These databases
+    do not have any files.</para>
+
+    <para>A <glossterm>file</glossterm>: catalog consists of between 2 to 5
+    files, all named the same but with different extensions, located in the
+    same directory. For example, the database named "test" consists of the
+    following files:</para>
+
+    <itemizedlist>
+      <listitem>
+        <para><filename>test.properties</filename></para>
+      </listitem>
+
+      <listitem>
+        <para><filename>test.script</filename></para>
+      </listitem>
+
+      <listitem>
+        <para><filename>test.log</filename></para>
+      </listitem>
+
+      <listitem>
+        <para><filename>test.data</filename></para>
+      </listitem>
+
+      <listitem>
+        <para><filename>test.backup</filename></para>
+      </listitem>
+
+      <listitem>
+        <para><filename>test.lobs</filename></para>
+      </listitem>
+    </itemizedlist>
+
+    <para>The properties file contains a few settings about the database. The
+    script file contains the definition of tables and other database objects,
+    plus the data for non-cached tables. The log file contains recent changes
+    to the database. The data file contains the data for cached tables and the
+    backup file is a compressed backup of the last known consistent state of
+    the data file. All these files are essential and should never be deleted.
+    For some catalogs, the <filename>test.data</filename> and
+    <filename>test.backup</filename> files will not be present. In addition to
+    those files, a HyperSQL database may link to any formatted text files,
+    such as CSV lists, anywhere on the disk.</para>
+
+    <para>While the "test" catalog is open, a <filename>test.log</filename>
+    file is used to write the changes made to data. This file is removed at a
+    normal SHUTDOWN. Otherwise (with abnormal shutdown) this file is used at
+    the next startup to redo the changes. A <filename>test.lck </filename>file
+    is also used to record the fact that the database is open. This is deleted
+    at a normal SHUTDOWN.</para>
+
+    <note>
+      <para>When the engine closes the database at a shutdown, it creates
+      temporary files with the extension <literal>.new</literal> which it then
+      renames to those listed above. In some circumstances, a
+      <filename>test.data.old</filename> is created and deleted afterwards.
+      These files should not be deleted by the user. At the time of the next
+      startup, all such files will be deleted by the database engine.</para>
+    </note>
+
+    <para>A <glossterm>res:</glossterm> catalog consists of the files for a
+    small, read-only database that can be stored inside a Java resource such
+    as a ZIP or JAR archive and distributed as part of a Java application
+    program.</para>
+  </section>
+
+  <section xml:id="running_inprocess-sect">
+    <title>In-Process Access to Database Catalogs</title>
+
+    <para>In general, JDBC is used for all access to databases. This is done
+    by making a connection to the database, then using various methods of the
+    <classname>java.sql.Connection</classname> object that is returned to
+    access the data. Access to an <glossterm>in-process</glossterm> database
+    is started from JDBC, with the database path specified in the connection
+    URL. For example, if the <glossterm>file: </glossterm>database name is
+    "testdb" and its files are located in the same directory as where the
+    command to run your application was issued, the following code is used for
+    the connection:</para>
+
+    <programlisting>  Connection c = DriverManager.getConnection("jdbc:hsqldb:file:testdb", "SA", "");</programlisting>
+
+    <para>The database file path format can be specified using forward slashes
+    in Windows hosts as well as Linux hosts. So relative paths or paths that
+    refer to the same directory on the same drive can be identical. For
+    example if your database path in Linux is
+    <filename>/opt/db/testdb</filename> and you create an identical directory
+    structure on the <literal>C:</literal> drive of a Windows host, you can
+    use the same URL in both Windows and Linux:</para>
+
+    <programlisting>  Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");</programlisting>
+
+    <para>When using relative paths, these paths will be taken relative to the
+    directory in which the shell command to start the Java Virtual Machine was
+    executed. Refer to the Javadoc for <classname
+    xlink:href="#JDBCConnection.html-link">JDBCConnection</classname> for more
+    details.</para>
+
+    <para>Paths and database names for file databases are treated as
+    case-sensitive when the database is created or the first connection is
+    made to the database. But if a second connection is made to an open
+    database, using a path and name that differs only in case, then the
+    connection is made to the existing open database. This measure is
+    necessary because in Windows the two paths are equivalent.</para>
+
+    <para>A <glossterm>mem:</glossterm> database is specified by the
+    <glossterm>mem:</glossterm> protocol. For <glossterm>mem:</glossterm>
+    databases, the path is simply a name. Several <glossterm>mem:</glossterm>
+    databases can exist at the same time and distinguished by their names. In
+    the example below, the database is called "mymemdb":</para>
+
+    <programlisting>  Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "SA", "");</programlisting>
+
+    <para>A <glossterm>res:</glossterm> database, is specified by the
+    <glossterm>res:</glossterm> protocol. As it is a Java resource, the
+    database path is a Java URL (similar to the path to a class). In the
+    example below, "resdb" is the root name of the database files, which
+    exists in the directory "org/my/path" within the classpath (probably in a
+    Jar). A Java resource is stored in a compressed format and is decompressed
+    in memory when it is used. For this reason, a <glossterm>res:</glossterm>
+    database should not contain large amounts of data and is always
+    read-only.</para>
+
+    <programlisting>  Connection c = DriverManager.getConnection("jdbc:hsqldb:res:org.my.path.resdb", "SA", "");</programlisting>
+
+    <para>The first time <glossterm>in-process</glossterm> connection is made
+    to a database, some general data structures are initialised and a few
+    helper threads are started. After this, creation of connections and calls
+    to JDBC methods of the connections execute as if they are part of the Java
+    application that is making the calls. When the SQL command "SHUTDOWN" is
+    executed, the global structures and helper threads for the database are
+    destroyed.</para>
+
+    <para>Note that only one Java process at a time can make
+    <glossterm>in-process</glossterm> connections to a given
+    <glossterm>file:</glossterm> database. However, if the
+    <glossterm>file:</glossterm> database has been made read-only, or if
+    connections are made to a <glossterm>res:</glossterm> database, then it is
+    possible to make <glossterm>in-process</glossterm> connections from
+    multiple Java processes.</para>
+  </section>
+
+  <section xml:id="running_modes-sect">
+    <title>Listener / Server Modes</title>
+
+    <para>For most applications, <glossterm>in-process</glossterm> access is
+    faster, as the data is not converted and sent over the network. The main
+    drawback is that it is not possible by default to connect to the database
+    from outside your application. As a result you cannot check the contents
+    of the database with external tools such as Database Manager while your
+    application is running.</para>
+
+    <para>Server modes provide the maximum accessibility. The database engine
+    runs in a JVM and opens one or more <glossterm>in-process</glossterm>
+    catalogs. It listens for connections from programs on the same computer or
+    other computers on the network. It translates these connections into
+    <glossterm>in-process</glossterm> connections to the databases.</para>
+
+    <para>Several different programs can connect to the server and retrieve or
+    update information. Applications programs (clients) connect to the server
+    using the HyperSQL JDBC driver. In most server modes, the server can serve
+    an unlimited number of databases that are specified at the time of running
+    the server, or optionally, as a connection request is received.</para>
+
+    <para>A Sever mode is also the prefered mode of running the database
+    during development. It allows you to query the database from a separate
+    database access utility while your application is running.</para>
+
+    <para>There are three server modes, based on the protocol used for
+    communications between the client and server. They are briefly discussed
+    below. More details on servers is provided in the <link
+    endterm="listeners-title" xlink:arcrole=""
+    xlink:href="#listeners-chapt"></link> chapter.</para>
+
+    <section xml:id="running_hsqlserver-sect">
+      <title>HyperSQL HSQL Server</title>
+
+      <para>This is the preferred way of running a database server and the
+      fastest one. A proprietary communications protocol is used for this
+      mode. A command similar to those used for running tools and described
+      above is used for running the server. The following example of the
+      command for starting the server starts the server with one (default)
+      database with files named "mydb.*" and the public name of "xdb". The
+      public name hides the file names from users.</para>
+
+      <informalexample>
+        <screen>  java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb</screen>
+      </informalexample>
+
+      <para>The command line argument <literal>--help</literal> can be used to
+      get a list of available arguments.</para>
+    </section>
+
+    <section xml:id="running_httpserver-sect">
+      <title>HyperSQL HTTP Server</title>
+
+      <para>This method of access is used when the computer hosting the
+      database server is restricted to the HTTP protocol. The only reason for
+      using this method of access is restrictions imposed by firewalls on the
+      client or server machines and it should not be used where there are no
+      such restrictions. The HyperSQL HTTP Server is a special web server that
+      allows JDBC clients to connect via HTTP. The server can also act as a
+      small general-purpose web server for static pages.</para>
+
+      <para>To run an HTTP server, replace the main class for the server in
+      the example command line above with the following:</para>
+
+      <informalexample>
+        <screen>  org.hsqldb.server.WebServer</screen>
+      </informalexample>
+
+      <para>The command line argument <literal>--help</literal> can be used to
+      get a list of available arguments.</para>
+    </section>
+
+    <section xml:id="running_servlet-sect">
+      <title>HyperSQL HTTP Servlet</title>
+
+      <para>This method of access also uses the HTTP protocol. It is used when
+      a separate servlet engine (or application server) such as Tomcat or
+      Resin provides access to the database. The Servlet Mode cannot be
+      started independently from the servlet engine. The
+      <filename>Servlet</filename> class, in the HSQLDB jar, should be
+      installed on the application server to provide the connection. The
+      database is specified using an application server property. Refer to the
+      source file <filename xlink:href="#Servlet.java-link">
+      src/org/hsqldb/server/Servlet.java</filename> to see the details.</para>
+
+      <para>Both HTTP Server and Servlet modes can only be accessed using the
+      JDBC driver at the client end. They do not provide a web front end to
+      the database. The Servlet mode can serve only a single database.</para>
+
+      <para>Please note that you do not normally use this mode if you are
+      using the database engine in an application server. In this situation,
+      connections to a catalog are usually made
+      <glossterm>in-process</glossterm>, or using a separate Server</para>
+    </section>
+
+    <section xml:id="running_connecting-sect">
+      <title>Connecting to a Database Server</title>
+
+      <para>When a HyperSQL server is running, client programs can connect to
+      it using the HSQLDB JDBC Driver contained in
+      <filename>hsqldb.jar</filename>. Full information on how to connect to a
+      server is provided in the Java Documentation for <classname
+      xlink:href="#JDBCConnection.html-link"> JDBCConnection</classname>
+      (located in the <filename>/doc/apidocs</filename> directory of HSQLDB
+      distribution). A common example is connection to the default port (9001)
+      used for the <glossterm>hsql:</glossterm> protocol on the same
+      machine:</para>
+
+      <example>
+        <title>Java code to connect to the local hsql Server</title>
+
+        <programlisting>  try {
+      Class.forName("org.hsqldb.jdbc.JDBCDriver" );
+  } catch (Exception e) {
+      System.err.println("ERROR: failed to load HSQLDB JDBC driver.");
+      e.printStackTrace();
+      return;
+  }
+
+  Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb", "SA", "");</programlisting>
+      </example>
+
+      <para>If the HyperSQL HTTP server is used, the protocol is
+      <glossterm>http:</glossterm> and the URL will be different:</para>
+
+      <example>
+        <title>Java code to connect to the local http Server</title>
+
+        <programlisting>  Connection c = DriverManager.getConnection("jdbc:hsqldb:http://localhost/xdb", "SA", "");</programlisting>
+      </example>
+
+      <para>Note in the above connection URL, there is no mention of the
+      database file, as this was specified when running the server. Instead,
+      the public name defined for dbname.0 is used. Also, see the <link
+      endterm="listeners-title" xlink:href="#listeners-chapt"></link> chapter
+      for the connection URL when there is more than one database per server
+      instance.</para>
+    </section>
+
+    <section xml:id="running_security-sect">
+      <title>Security Considerations</title>
+
+      <indexterm significance="preferred">
+        <primary>security</primary>
+      </indexterm>
+
+      <para>When a HyperSQL server is run, network access should be adequately
+      protected. Source IP addresses may be restricted by use of our <link
+      xlink:href="#listeners_acl-sect">Access Control List feature</link>,
+      network filtering software, firewall software, or standalone firewalls.
+      Only secure passwords should be used-- most importantly, the password
+      for the default system user should be changed from the default empty
+      string. If you are purposefully providing data to the public, then the
+      wide-open public network connection should be used exclusively to access
+      the public data via read-only accounts. (i.e., neither secure data nor
+      privileged accounts should use this connection). These considerations
+      also apply to HyperSQL servers run with the HTTP protocol.</para>
+
+      <para>HyperSQL provides two optional security mechanisms. The <link
+      xlink:href="#listeners_tls-sect">encrypted SSL protocol</link>, and
+      <link xlink:href="#listeners_acl-sect">Access Control Lists</link>. Both
+      mechanisms can be specified when running the Server or WebServer. From
+      the client, the URL's co connect to an SSL server is slightly
+      different:</para>
+
+      <para><example>
+          <title>Java code to connect to the local secure SSL hsql and http
+          Servers</title>
+
+          <programlisting>  Connection c = DriverManager.getConnection("jdbc:hsqldb:hsqls://localhost/xdb", "SA", "");
+  Connection c = DriverManager.getConnection("jdbc:hsqldb:https://localhost/xdb", "SA", "");
+</programlisting>
+        </example>The security features are discussed in detail in the <link
+      endterm="listeners-title" xlink:href="#listeners-chapt">listeners</link>
+      chapter.</para>
+    </section>
+
+    <section xml:id="running_multiple_db-sect">
+      <title>Using Multiple Databases</title>
+
+      <para>A server can provide connections to more than one database. In the
+      examples above, more than one set of database names can be specified on
+      the command line. It is also possible to specify all the databases in a
+      <literal>.properties</literal> file, instead of the command line. These
+      capabilities are covered in the <link endterm="listeners-title"
+      xlink:href="#listeners-chapt"></link> chapter</para>
+    </section>
+  </section>
+
+  <section xml:id="running-data-access-sect">
+    <title>Accessing the Data</title>
+
+    <para>As shown so far, a <classname>java.sql.Connection</classname> object
+    is always used to access the database. But the speed and performance
+    depends on the type of connection.</para>
+
+    <para>Establishing a connection and closing it has some overheads,
+    therefore it is not good practice to create a new connection to perform a
+    small number of operations. A connection should be reused as much as
+    possible and closed only when it is not going to be used again for a long
+    while.</para>
+
+    <para>Reuse is more important for server connections. A server connection
+    uses a TCP port for communications. Each time a connection is made, a port
+    is allocated by the operating system and deallocated after the connection
+    is closed. If many connections are made from a single client, the
+    operating system may not be able to keep up and may refuse the connection
+    attempt.</para>
+
+    <para>A <classname>java.sql.Connection</classname> object has some methods
+    that return further <classname>java.sql.*</classname> objects. All these
+    objects belong to the connection that returned them and are closed when
+    the connection is closed. These objects can be reused, but if they are not
+    needed after performing the operations, they should be closed.</para>
+
+    <para>A <classname>java.sql.DatabaseMetaData</classname> object is used to
+    get metadata for the database.</para>
+
+    <para>A <classname>java.sql.Statement</classname> object is used to
+    execute queries and data change statements. A
+    <classname>java.sql.Statement</classname> can be reused to execute a
+    different statement each time.</para>
+
+    <para>A <classname>java.sql.PreparedStatement</classname> object is used
+    to execute a single statement repeatedly. The SQL statement usually
+    contains parameters, which can be set to new values before each reuse.
+    When a <classname>java.sql.PreparedStatement</classname> object is
+    created, the engine keeps the compiled SQL statement for reuse, until the
+    <classname>java.sql.PreparedStatement</classname> object is closed. As a
+    result, repeated use of a
+    <classname>java.sql.PreparedStatement</classname> is much faster than
+    using a <classname>java.sql.Statement</classname> object.</para>
+
+    <para>A <classname>java.sql.CallableStatement</classname> object is used
+    to execute an SQL CALL statement. The SQL CALL statement may contain
+    parameters, which should be set to new values before each reuse. Similar
+    to <classname>java.sql.PreparedStatement</classname>, the engine keeps the
+    compiled SQL statement for reuse, until the
+    <classname>java.sql.CallableStatement</classname> object is closed.</para>
+
+    <para>A <classname>java.sql.Connection</classname> object also has some
+    methods for transaction control.</para>
+
+    <para>The <methodname>commit()</methodname> method performs a
+    <literal>COMMIT</literal> while the <methodname>rollback()</methodname>
+    method performs a <literal>ROLLBACK</literal> SQL statement.</para>
+
+    <para>The <methodname>setSavepoint(String name)</methodname> method
+    performs a <literal>SAVEPOINT &lt;name&gt;</literal> SQL statement and
+    returns a <classname>java.sql.Savepoint</classname> object. The
+    <methodname>rollback(Savepoint name)</methodname> method performs a
+    <literal>ROLLBACK TO SAVEPOINT &lt;name&gt;</literal> SQL
+    statement.</para>
+
+    <para>The Javadoc for <classname xlink:href="#JDBCConnection.html-link">
+    JDBCConnection</classname>, <classname xlink:href="#JDBCDriver.html-link">
+    JDBCDriver</classname>, <classname
+    xlink:href="#JDBCDatabaseMetaData.html-link">
+    JDBCDatabaseMetadata</classname> <classname
+    xlink:href="#JDBCResultSet.html-link"> JDBCResultSet</classname>,
+    <classname xlink:href="#JDBCStatement.html-link">
+    JDBCStatement</classname>, <classname
+    xlink:href="#JDBCPreparedStatement.html-link">
+    JDBCPreparedStatement</classname> list all the supported JDBC methods
+    together with information that is specific to HSQLDB.</para>
+  </section>
+
+  <section xml:id="running_closing-sect">
+    <title>Closing the Database</title>
+
+    <para>All databases running in different modes can be closed with the
+    SHUTDOWN command, issued as an SQL statement.</para>
+
+    <para>When SHUTDOWN is issued, all active transactions are rolled back.
+    The catalog files are then saved in a form that can be opened quickly the
+    next time the catalog is opened.</para>
+
+    <para>A special form of closing the database is via the SHUTDOWN COMPACT
+    command. This command rewrites the <literal>.data</literal> file that
+    contains the information stored in CACHED tables and compacts it to its
+    minimum size. This command should be issued periodically, especially when
+    lots of inserts, updates or deletes have been performed on the cached
+    tables. Changes to the structure of the database, such as dropping or
+    modifying populated CACHED tables or indexes also create large amounts of
+    unused file space that can be reclaimed using this command.</para>
+
+    <para>Databases are not closed when the last connection to the database is
+    explicitly closed via JDBC. A connection property,
+    <literal>shutdown=true</literal>, can be specified on the first connection
+    to the database (the connection that opens the database) to force a
+    shutdown when the last connection closes.</para>
+
+    <para><example>
+        <title>specifying a connection property to shutdown the database when
+        the last connection is closed</title>
+
+        <programlisting>  Connection c = DriverManager.getConnection(
+          "jdbc:hsqldb:file:/opt/db/testdb;shutdown=true", "SA", "");</programlisting>
+      </example>This feature is useful for running tests, where it may not be
+    practical to shutdown the database after each test. But it is not
+    recommended for application programs.</para>
+  </section>
+
+  <section xml:id="running_newdb-sect">
+    <title>Creating a New Database</title>
+
+    <para>When a server instance is started, or when a connection is made to
+    an <glossterm>in-process</glossterm> database, a new, empty database is
+    created if no database exists at the given path.</para>
+
+    <para>With HyperSQL 2.0 the username and password that are specified for
+    the connection are used for the new database. Both the username and
+    password are case-sensitive. (The exception is the default SA user, which
+    is not case-sensitive). If no username or password is specified, the
+    default SA user and an empty password are used.</para>
+
+    <para>This feature has a side effect that can confuse new users. If a
+    mistake is made in specifying the path for connecting to an existing
+    database, a connection is nevertheless established to a new database. For
+    troubleshooting purposes, you can specify a connection property
+    <property>ifexists</property>=<literal>true</literal> to allow connection
+    to an existing database only and avoid creating a new database. In this
+    case, if the database does not exist, the
+    <methodname>getConnection()</methodname> method will throw an
+    exception.</para>
+
+    <para><example>
+        <title>specifying a connection property to disallow creating a new
+        database</title>
+
+        <programlisting>  Connection c = DriverManager.getConnection(
+          "jdbc:hsqldb:file:/opt/db/testdb;ifexists=true", "SA", "");</programlisting>
+      </example></para>
+
+    <para>A database has many optional properties, described in the <link
+    endterm="deployment-title" xlink:arcrole=""
+    xlink:href="#deployment-chapt"></link> chapter. You can specify most of
+    these properties on the URL or in the connection properties for the first
+    connection that creates the database. See the <link
+    endterm="dbproperties-title" xlink:arcrole=""
+    xlink:href="#deployment-chapt"></link> chapter.</para>
+  </section>
+</chapter>
diff --git a/doc-src/guide/sessions.xml b/doc-src/guide/sessions.xml
new file mode 100644
index 0000000..6387569
--- /dev/null
+++ b/doc-src/guide/sessions.xml
@@ -0,0 +1,992 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="sessions-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns6="http://www.w3.org/1999/xlink"
+         xmlns:ns5="http://www.w3.org/2000/svg"
+         xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="sessions-title">Sessions and Transactions</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+    <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section>
+    <title>Overview</title>
+
+    <para>All SQL statements are executed in sessions. When a connection is
+    established to the database, a session is started. The authorization of
+    the session is the name of the user that started the session. A session
+    has several properties. These properties are set by default at the start
+    according to database settings.</para>
+
+    <para>SQL Statements are generally transactional statements. When a
+    transactional statement is executed, it starts a transaction if no
+    transaction is in progress. If SQL Data is modified during a transaction,
+    the change can be undone with a ROLLBACK statement. When a COMMIT
+    statement is executed, the transaction is ended. If a single statement
+    fails, the transaction is not normally terminated. However, some failures
+    are caused by execution of statements that are in conflict with statements
+    executed in other concurrent sessions. Such failures result in an implicit
+    ROLLBACK, in addition to the exception that is raised.</para>
+
+    <para>Schema definition and manipulation statements are also transactional
+    according to the SQL Standard. HyperSQL 2.0 performs automatic commits
+    before and after the execution of such transactions. Therefore,
+    schema-related statements cannot be rolled back. This is likely to change
+    in future versions.</para>
+
+    <para>Some statements are not transactional. Most of these statements are
+    used to change the properties of the session. These statements begin with
+    the SET keyword.</para>
+
+    <para>If the AUTOCOMMIT property of a session is TRUE, then each
+    transactional statement is followed by an implicit COMMIT.</para>
+
+    <simpara>The default isolation level for a session is READ COMMITTED. This
+    can be changed using the JDBC <classname>java.sql.Connection</classname>
+    object and its <methodname>setTransactionIsolation(int level)</methodname>
+    method. The session can be put in read-only mode using the
+    <methodname>setReadOnly(boolean readOnly)</methodname> method. Both
+    methods can be invoked only after a commit or a rollback, but not during a
+    transaction.</simpara>
+
+    <simpara>The isolation level and / or the readonly mode of a transaction
+    can also be modified using an SQL statement. You can use the statement to
+    change only the isolation mode, only the read-only mode, or both at the
+    same time. This command can be issued only after a commit or
+    rollback.</simpara>
+
+    <simpara><literal>SET TRANSACTION &lt;transaction characteristic&gt; [
+    &lt;comma&gt; &lt;transaction characteristic&gt; ]</literal></simpara>
+
+    <para>Details of the statement is described later in this chapter.</para>
+  </section>
+
+  <section>
+    <title>Session Attributes and Variables</title>
+
+    <para>Each session has several system attributes. A session can also have
+    user-defined session variables.</para>
+
+    <section>
+      <title>Session Attributes</title>
+
+      <para>The system attributes reflect the current mode of operation for
+      the session. These attributes can be accessed with function calls and
+      can be referenced in queries. For example, they can be returned using
+      the <literal>VALUES &lt;attribute function&gt;, ...</literal>
+      statement.</para>
+
+      <para>The named attributes such as CURRENT_USER, CURRENT_SCHEMA, etc.
+      are SQL Standard functions. Other attributes of the session, such as
+      auto-commit or read-only modes can be read using other built-in
+      functions. All these functions are listed in the <link
+      endterm="builtinfunctions-title"
+      ns6:href="#builtinfunctions-chapt"></link> chapter.</para>
+    </section>
+
+    <section>
+      <title>Session Variables</title>
+
+      <para>Session variables are user-defined variables created the same way
+      as the variables for stored procedures and functions. Currently, these
+      variables cannot be used in general SQL statements. They can be assigned
+      to IN, INOUT and OUT parameters of stored procedures. This allows
+      calling stored procedures which have INOUT or OUT arguments and is
+      useful for development and debugging. See the example in the <link
+      endterm="sqlroutines-title" ns6:href="#sqlroutines-chapt"></link>
+      chapter, under Formal Parameters.</para>
+
+      <example>
+        <title>User-defined Session Variables</title>
+
+        <screen>  DECLARE counter INTEGER DEFAULT 3;
+  DECLARE result VARCHAR(20) DEFAULT NULL;
+  SET counter=15;
+  CALL myroutine(counter, result)
+</screen>
+      </example>
+    </section>
+
+    <section>
+      <title>Session Tables</title>
+
+      <para>With necessary access privileges, sessions can access all table,
+      including GLOBAL TEMPORARY tables, that are defined in schemas. Although
+      GLOBAL TEMPORARY tables have a single name and definition which applies
+      to all sessions that use them, the contents of the tables are different
+      for each session. The contents are cleared either at the end of each
+      transaction or when the session is closed.</para>
+
+      <para>Session tables are different because their definition is visible
+      only within the session that defines a table. The definition is dropped
+      when the session is closed. Session tables do not belong to
+      schemas.</para>
+
+      <para><literal>&lt;temporary table declaration&gt; ::= DECLARE LOCAL
+      TEMPORARY TABLE &lt;table name&gt; &lt;table element list&gt; [ ON
+      COMMIT { PRESERVE | DELETE } ROWS ]</literal></para>
+
+      <para>The syntax for declaration is based on the SQL Standard. A session
+      table cannot have FOREIGN KEY constraints, but it can have PRIMARY KEY,
+      UNIQUE or CHECK constraints. A session table definition cannot be
+      modified by adding or removing columns, indexes, etc.</para>
+
+      <para>It is possible to refer to a session table using its name, which
+      takes precedence over a schema table of the same name. To distinguish a
+      session table from schema tables, the pseudo schema name, MODULE can be
+      used. An example is given below:</para>
+
+      <para><example>
+          <title>User-defined Temporary Session Tables</title>
+
+          <screen>  DECLARE LOCAL TEMPORARY TABLE buffer (id INTEGER PRIMARY KEY, textdata VARCHAR(100)) ON COMMIT PRESERVE ROWS
+  INSERT INTO module.buffer SELECT id, firstname || ' ' || lastname FROM customers
+  -- do some more work
+  DROP TABLE module.buffer
+</screen>
+        </example>Session tables can be created inside a transaction.
+      Automatic indexes are created and used on session tables when necessary
+      for a query or other statement. By default, session table data is held
+      in memory. If the session property</para>
+    </section>
+  </section>
+
+  <section xml:id="sqlgeneral_trans_cc-sect">
+    <title>Transactions and Concurrency Control</title>
+
+    <para>HyperSQL 2.0 has been fully redesigned to support different
+    transaction isolation models. It no longer supports the old 1.8.x model
+    with "dirty read". Although it is perfectly possible to add an
+    implementation of the transaction manager that supports the legacy model,
+    we thought this is no longer necessary. The new system allows you to
+    select the transaction isolation model even while the engine is running
+    and choose different isolation modes for different simultaneous
+    sessions.</para>
+
+    <para>HyperSQL 2.0 supports three concurrency control models,
+    two-phase-locking (2PL), which is the default, multiversion concurrency
+    control (MVCC) and a hybrid model, which is 2PL plus multiversion rows.
+    Within each model, it supports some of 4 levels of transaction isolation:
+    READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ and SERIALIZABLE. The
+    isolation level is a property of each SQL session, so different sessions
+    can have different isolation levels. The concurrency control model is a
+    strategy that governs all the sessions and is set for the database, as
+    opposed for individual sessions. In the new implementation, all isolation
+    levels avoid the "dirty read" phenomenon and do not read uncommitted
+    changes made to rows by other transactions.</para>
+
+    <para>HyperSQL is fully multi threaded in all transaction models. Sessions
+    continue to work simultaneously and can fully utilise multi-core
+    processors.</para>
+
+    <para>To change the concurrency control model, the <literal>SET DATABASE
+    TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC }</literal> can be used by a
+    user with the DBA role.</para>
+
+    <section>
+      <title>Two Phase Locking</title>
+
+      <para>The two-phase locking model is the default mode. It is referred to
+      by the keyword, LOCKS. In the 2PL model, each table that is read by a
+      transaction is locked with a shared lock, and each table that is written
+      to is locked with an exclusive lock. If two sessions read and modify
+      different tables then both go through simultaneously. If one session
+      tries to lock a table that has been locked by the other, if both locks
+      are shared locks, it will go ahead. If either of the locks is an
+      exclusive lock, the engine will put the session in wait until the other
+      session commits or rolls back its transaction. In some cases the engine
+      will invalidate the transaction of the current session, if the action
+      would result in deadlock.</para>
+
+      <para>HyperSQL also supports explicit locking of a group of tables for
+      the duration of the current transaction. Use of this command blocks
+      access to the locked tables by other sessions and ensures the current
+      session can complete the intended reads and writes on the locked
+      tables.</para>
+
+      <para>If a table is read-only, it will not be locked by any
+      transaction.</para>
+
+      <para>The READ UNCOMMITTED isolation level can be used in 2PL modes for
+      read-only operations. It is the same as READ COMMITTED plus read
+      only.</para>
+
+      <para>The READ COMMITTED isolation level is the default. It keeps write
+      locks on tables until commit, but releases the read locks after each
+      operation.</para>
+
+      <para>The REPEATABLE READ level is upgraded to SERIALIZABLE. These
+      levels keep both read and write locks on tables until commit.</para>
+
+      <para>It is possible to perform some critical operations at the
+      SERIALIZABLE level, while the rest of the operations are performed at
+      the READ COMMITTED level.</para>
+
+      <para>Note: two phase locking refers to two periods in the life of a
+      transaction. In the first period, locks are acquired, in the second
+      period locks are released. No new lock is acquired after releasing a
+      lock.</para>
+    </section>
+
+    <section>
+      <title>Two Phase Locking with Snapshot Isolation</title>
+
+      <para>This model is referred to as MVLOCKS. It works the same way as
+      normal 2PL as far as updates are concerned.</para>
+
+      <para>SNAPSHOT ISOLATION is a multiversion concurrency strategy which
+      uses the snapshot of the whole database at the time of the start of the
+      transaction. In this model, read only transactions use SNAPSHOT
+      ISOLATION. While other sessions are busy changing the database, the read
+      only session sees a consistent view of the database and can access all
+      the tables even when they are locked by other sessions for
+      updates.</para>
+
+      <para>There are many applications for this mode of operation. In heavily
+      updated data sets, this mode allows uninterrupted read access to the
+      data.</para>
+    </section>
+
+    <section>
+      <title>Lock Contention in 2PL</title>
+
+      <para>When multiple connections are used to access the database, the
+      transaction manager controls their activities. When each transaction
+      performs only reads or writes on a single table, there is no contention.
+      Each transaction waits until it can obtain a lock then performs the
+      operation and commits. All contentions occur when transactions perform
+      reads and writes on more than one table, or perform a read, followed by
+      a write, on the same table.</para>
+
+      <para>For example, when sessions are working at the SERIALIZABLE level,
+      when multiple sessions first read from a table in order to check if a
+      row exists, then insert a row into the same table when it doesn't exist,
+      there will be regular contention. Transaction A reads from the table,
+      then does Transaction B. Now if either Transaction A or B attempts to
+      insert a row, it will have to be terminated as the other transaction
+      holds a shared lock on the table. If instead of two operations, a single
+      MERGE statement is used to perform the read and write, no contention
+      occurs because both locks are obtained at the same time.</para>
+
+      <para>Alternatively, there is the option of obtaining the necessary
+      locks with an explicit LOCK TABLE statement. This statement should be
+      executed before other statements and should include the names of all the
+      tables and the locks needed. After this statement, all the other
+      statements in the transaction can be executed and the transaction
+      committed. The commit will remove all the locks.</para>
+
+      <para>HyperSQL is fully multi threaded. It therefore allows different
+      transactions to execute concurrently so long as they are not modifying
+      the same table.</para>
+    </section>
+
+    <section>
+      <title>MVCC</title>
+
+      <para>In the MVCC model, there are no shared, read locks. Exclusive
+      locks are used on individual rows, but their use is different.
+      Transactions can read and modify the same table simultaneously,
+      generally without waiting for other transactions.</para>
+
+      <para>When transactions are running at READ COMMITTED level, no conflict
+      will normally occur. If a transaction that runs at this level wants to
+      modify a row that has been modified by another uncommitted transaction,
+      then the engine puts the transaction in wait, until the other
+      transaction has committed. The transaction then continues automatically.
+      (Conflict is possible if each transaction is waiting for a different row
+      modified by the other transaction, in which case, one of the
+      transactions is terminated). This isolation level is called READ
+      CONSISTENCY.</para>
+
+      <para>When transactions are running in REPEATABLE READ or SERIALIZABLE
+      isolation levels, conflict is more likely to happen. There is no
+      difference in operation between these two isolation levels. If a
+      transaction that runs at these levels wants to modify a row that has
+      been modified by another uncommitted transaction, the engine will
+      invalidate the current transaction and roll back all its changes. This
+      isolation level is called SNAPSHOT ISOLATION.</para>
+
+      <para>In the MVCC model, READ UNCOMMITTED is promoted to READ COMMITTED,
+      as the new architecture is based on multi-version rows for uncommitted
+      data and more than one version may exist for some rows.</para>
+
+      <para>With MVCC, when a transaction only reads data, then it will go
+      ahead and complete regardless of what other transactions may do. This
+      does not depend on the transaction being read-only or the isolation
+      modes.</para>
+    </section>
+
+    <section>
+      <title>Choosing the Transaction Model</title>
+
+      <para>The SQL Standard defines the isolation levels as modes of
+      operation that avoid the three unwanted phenomena, "dirty read", "fuzzy
+      read" and "phantom row". The "dirty read" phenomenon occurs when a
+      session can read a row that has been changed by another session. The
+      "fuzzy read" phenomenon occurs when a row that was read by a session is
+      modified by another session, then the first session reads the row again.
+      The "phantom row" phenomenon occurs when a session performs an operation
+      that affects several rows, for example, counts the rows or modifies them
+      using a search condition, then another session adds one or more rows
+      that fulfil the same search condition, then the first session performs
+      an operation that relies on the results of its last operation. According
+      to the Standard, the SERIALIZABLE isolation level avoids all three
+      phenomena and also ensures that all the changes performed during a
+      transaction can be considered as a series of uninterrupted changes to
+      the database without any other transaction changing the database at all
+      for the duration of these actions. The changes made by other
+      transactions are considered to occur before the SERIALIZABLE transaction
+      starts, or after it ends. The READ COMMITTED level avoids "dirty read"
+      only, while the REPEATABLE READ level avoids "dirty read" and "fuzzy
+      read", but not "phantom row".</para>
+
+      <para>The Standard allows the engine to return a higher isolation level
+      than requested by the application. HyperSQL promotes a READ UNCOMMITTED
+      request to READ COMMITTED and promotes a REPEATABLE READ request to
+      SERIALIZABLE.</para>
+
+      <para>The MVCC model is not covered directly by the Standard. Research
+      has established that the READ CONSISTENCY level fulfills the
+      requirements of (and is stronger than) the READ COMMITTED level. The
+      SNAPSHOT ISOLATION level is stronger than the READ CONSISTENCY level. It
+      avoids the three anomalies defined by the Standard, and is therefore
+      stronger than the REPEATABLE READ level as defined by the Standard. When
+      operating with the MVCC model, HyperSQL treats a REPEATABLE READ or
+      SERIALIZABLE setting for a transaction as SNAPSHOT ISOLATION.</para>
+
+      <para>All modes can be used with as many simultaneous connections as
+      required. The default 2PL model is fine for applications with a single
+      connection, or applications that do not access the same tables heavily
+      for writes. With multiple simultaneous connections, MVCC can be used for
+      most applications. Both READ CONSISTENCY and SNAPSHOT ISOLATION levels
+      are stronger than the corresponding READ COMMITTED level in the 2PL
+      mode. Some applications require SERIALIZABLE transactions for at least
+      some of their operations. For these applications, one of the 2PL modes
+      can be used. It is possible to switch the concurrency model while the
+      database is operational. Therefore, the model can be changed for the
+      duration of some special operations, such as synchronization with
+      another data source.</para>
+
+      <para>All concurrency models are very fast in operation. When operating
+      mainly on the same tables, the MVCC model may be faster with multiple
+      processors.</para>
+    </section>
+
+    <section>
+      <title>Schema and Database Change</title>
+
+      <para>There are a few SQL statements that must access a consistent state
+      of the database during their executions. These statements, which include
+      CHECKPOINT and BACKUP, put an exclusive lock on all the tables of the
+      database when they start.</para>
+
+      <para>Some schema manipulation statements put an exclusive lock on one
+      or more tables. For example changing the columns of a table locks the
+      table exclusively.</para>
+
+      <para>In the MVCC model, all statements that need an exclusive lock on
+      one or more tables, put an exclusive lock on the database catalog until
+      they complete.</para>
+
+      <para>The effect of these exclusive locks is similar to the execution of
+      data manipulation statements with write locks. The session that is about
+      to execute the schema change statement waits until no other session is
+      holding a lock on any of the objects. At this point it starts its
+      operation and locks the objects to prevents any other session from
+      accessing the locked objects. As soon as the operation is complete, the
+      locks are all removed.</para>
+    </section>
+
+    <section>
+      <title>Simultaneous Access to Tables</title>
+
+      <para>It was mentioned that there is no limit on the number of sessions
+      that can access the tables and all sessions work simultaneously in multi
+      threaded execution. However there are internal resources that are
+      shared. Simultaneous access to these resources reduces the overall
+      efficiency of the system. MEMORY and TEXT tables do not share resources
+      and do not block multi threaded access. With CACHED tables, each write
+      operation blocks the file and its cache until the operation is finished.
+      With CACHED tables, SELECT operations do not block each other, but
+      selecting from different tables and different parts of a large table
+      causes the row cache to be updated frequently and will reduce overall
+      performance.</para>
+
+      <para>The new access pattern is the opposite of the access pattern of
+      version 1.8.x. In the old version, even when 20 sessions are actively
+      reading and writing, only a single session at a time performs an SQL
+      statement completely, before the next session is allowed access. In the
+      new version, while a session is performing a SELECT statement and
+      reading rows of a CACHED table to build a result set, another session
+      may perform an UPDATE statement that reads and writes rows of the same
+      table. The two operations are performed without any conflict, but the
+      row cache is updated more frequently than when one operation is
+      performed after the other operation has finished.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Session and Transaction Control Statements</title>
+
+    <!-- From Foundation chapt. 17 -->
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET AUTOCOMMIT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET AUTOCOMMIT</emphasis></simpara>
+
+    <simpara><emphasis>set autocommit command</emphasis></simpara>
+
+    <simpara><literal>&lt;set autocommit statement&gt; ::= SET AUTOCOMMIT {
+    TRUE | FALSE }</literal></simpara>
+
+    <simpara>When an SQL session is started by creating a JDBC connection, it
+    is in AUTOCOMMIT mode. In this mode, after each SQL statement a COMMIT is
+    performed automatically. This statement changes the mode. It is equivalent
+    to using the <methodname>setAutoCommit( boolean autoCommit)</methodname>
+    method of the JDBC <classname>Connection</classname> object.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>START TRANSACTION</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">START TRANSACTION</emphasis></simpara>
+
+    <simpara><emphasis>start transaction statement</emphasis></simpara>
+
+    <simpara><literal>&lt;start transaction statement&gt; ::= START
+    TRANSACTION [ &lt;transaction characteristics&gt; ]</literal></simpara>
+
+    <simpara>Start an SQL transaction and set its characteristics. All
+    transactional SQL statements start a transaction automatically, therefore
+    using this statement is not necessary. If the statement is called in the
+    middle of a transaction, an exception is thrown.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET DATABASE TRANSACTION CONTROL</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET DATABASE TRANSACTION
+    CONTROL</emphasis></simpara>
+
+    <simpara><emphasis>set database transaction control</emphasis></simpara>
+
+    <simpara><literal>&lt;set database transaction control statement&gt; ::=
+    SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC
+    }</literal></simpara>
+
+    <simpara>Set the concurrency control model for the whole database. It will
+    wait until all sessions have been committed or rolled back. The default is
+    LOCKS.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET TRANSACTION</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET TRANSACTION</emphasis></simpara>
+
+    <simpara><emphasis>set next transaction
+    characteristics</emphasis></simpara>
+
+    <simpara><literal>&lt;set transaction statement&gt; ::= SET [ LOCAL ]
+    TRANSACTION &lt;transaction characteristics&gt;</literal></simpara>
+
+    <simpara>Set the characteristics of the next transaction in the current
+    session. This statement has an effect only on the next transactions and
+    has no effect on the future transactions after the next.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>transaction characteristics</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">transaction
+    characteristics</emphasis></simpara>
+
+    <simpara><emphasis>transaction characteristics</emphasis></simpara>
+
+    <simpara><literal>&lt;transaction characteristics&gt; ::= [
+    &lt;transaction mode&gt; [ { &lt;comma&gt; &lt;transaction mode&gt; }... ]
+    ]</literal></simpara>
+
+    <simpara><literal>&lt;transaction mode&gt; ::= &lt;isolation level&gt; |
+    &lt;transaction access mode&gt; | &lt;diagnostics
+    size&gt;</literal></simpara>
+
+    <simpara><literal>&lt;transaction access mode&gt; ::= READ ONLY | READ
+    WRITE</literal></simpara>
+
+    <simpara><literal>&lt;isolation level&gt; ::= ISOLATION LEVEL &lt;level of
+    isolation&gt;</literal></simpara>
+
+    <simpara><literal>&lt;level of isolation&gt; ::= READ UNCOMMITTED | READ
+    COMMITTED | REPEATABLE READ | SERIALIZABLE</literal></simpara>
+
+    <simpara><literal>&lt;diagnostics size&gt; ::= DIAGNOSTICS SIZE &lt;number
+    of conditions&gt;</literal></simpara>
+
+    <simpara><literal>&lt;number of conditions&gt; ::= &lt;simple value
+    specification&gt;</literal></simpara>
+
+    <simpara>Specify transaction characteristics.</simpara>
+
+    <example>
+      <title>Setting Transaction Characteristics</title>
+
+      <screen>  SET TRANSACTION READ ONLY
+  SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
+  SET TRANSACTION READ WRITE, ISOLATION LEVEL READ COMMITTED
+</screen>
+    </example>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET CONSTRAINTS</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET CONSTRAINTS</emphasis></simpara>
+
+    <simpara><emphasis>set constraints mode statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set constraints mode statement&gt; ::= SET
+    CONSTRAINTS &lt;constraint name list&gt; { DEFERRED | IMMEDIATE
+    }</literal></simpara>
+
+    <simpara><literal>&lt;constraint name list&gt; ::= ALL | &lt;constraint
+    name&gt; [ { &lt;comma&gt; &lt;constraint name&gt; }...
+    ]</literal></simpara>
+
+    <simpara>If the statement is issued during a transaction, it applies to
+    the rest of the current transaction. If the statement is issued when a
+    transaction is not active then it applies only to the next transaction in
+    the current session. HyperSQL does not yet support this feature.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>LOCK TABLE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">LOCK TABLE</emphasis></simpara>
+
+    <simpara><emphasis>lock table statement</emphasis></simpara>
+
+    <simpara><literal>&lt;lock table statement&gt; ::= LOCK TABLE &lt;table
+    name&gt; { READ | WRITE} [, &lt;table name&gt; { READ | WRITE}
+    ...]}</literal></simpara>
+
+    <simpara>In some circumstances, where multiple simultaneous transactions
+    are in progress, it may be necessary to ensure a transaction consisting of
+    several statements is completed, without being terminated due to possible
+    deadlock. When this statement is executed, it waits until it can obtain
+    all the listed locks, then returns. The SQL statements following this
+    statements use the locks already obtained (and obtain new locks if
+    necessary) and can proceed without waiting. All the locks are released
+    when a COMMIT or ROLLBACK statement is issued. Currently, this command
+    does not have any effect when the database transaction control model is
+    MVCC.</simpara>
+
+    <example>
+      <title>Locking Tables</title>
+
+      <screen>  LOCK TABLE table_a WRITE, table_b READ</screen>
+    </example>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SAVEPOINT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SAVEPOINT</emphasis></simpara>
+
+    <simpara><emphasis>savepoint statement</emphasis></simpara>
+
+    <simpara><literal>&lt;savepoint statement&gt; ::= SAVEPOINT &lt;savepoint
+    specifier&gt;</literal></simpara>
+
+    <simpara><literal>&lt;savepoint specifier&gt; ::= &lt;savepoint
+    name&gt;</literal></simpara>
+
+    <simpara>Establish a savepoint. This command is used during an SQL
+    transaction. It establishes a milestone for the current transaction. The
+    SAVEPOINT can be used at a later point in the transaction to rollback the
+    transaction to the milestone.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>RELEASE SAVEPOINT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">RELEASE SAVEPOINT</emphasis></simpara>
+
+    <simpara><emphasis>release savepoint statement</emphasis></simpara>
+
+    <simpara><literal>&lt;release savepoint statement&gt; ::= RELEASE
+    SAVEPOINT &lt;savepoint specifier&gt;</literal></simpara>
+
+    <simpara>Destroy a savepoint. This command is rarely used as it is not
+    very useful. It removes a SAVEPOINT that has already been
+    defined.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>COMMIT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">COMMIT</emphasis></simpara>
+
+    <simpara><emphasis>commit statement</emphasis></simpara>
+
+    <simpara><literal>&lt;commit statement&gt; ::= COMMIT [ WORK ] [ AND [ NO
+    ] CHAIN ]</literal></simpara>
+
+    <simpara>Terminate the current SQL-transaction with commit. This make all
+    the changes to the database permanent.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ROLLBACK</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ROLLBACK</emphasis></simpara>
+
+    <simpara><emphasis>rollback statement</emphasis></simpara>
+
+    <simpara><literal>&lt;rollback statement&gt; ::= ROLLBACK [ WORK ] [ AND [
+    NO ] CHAIN ]</literal></simpara>
+
+    <simpara>Rollback the current SQL transaction and terminate it. The
+    statement rolls back all the actions performed during the transaction. If
+    NO CHAIN is specified, a new SQL transaction is started just after the
+    rollback. The new transaction inherits the properties of the old
+    transaction.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>ROLLBACK TO SAVEPOINT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">ROLLBACK TO SAVEPOINT</emphasis></simpara>
+
+    <simpara><emphasis>rollback statement</emphasis></simpara>
+
+    <simpara><literal>&lt;rollback statement&gt; ::= ROLLBACK [ WORK ] TO
+    SAVEPOINT &lt;savepoint specifier&gt;</literal></simpara>
+
+    <simpara>Rollback part of the current SQL transaction and continue the
+    transaction. The statement rolls back all the actions performed after the
+    specified SAVEPOINT was created. The same effect can be achieved with the
+    <literal>rollback( Savepoint savepoint)</literal> method of the JDBC
+    <classname>Connection</classname> object.</simpara>
+
+    <example>
+      <title>Rollback</title>
+
+      <screen>  -- perform some inserts, deletes, etc.
+  SAVEPOINT A
+  -- perform some inserts, deletes, selects etc.
+  ROLLBACK WORK TO SAVEPOINT A
+  -- all the work after the declaration of SAVEPOINT A is rolled back
+</screen>
+    </example>
+
+    <!-- From Foundation chapt. 18 -->
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DISCONNECT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DISCONNECT</emphasis></simpara>
+
+    <simpara><emphasis>disconnect statement</emphasis></simpara>
+
+    <simpara><literal>&lt;disconnect statement&gt; ::=
+    DISCONNECT</literal></simpara>
+
+    <simpara>Terminate the current SQL session. Closing a JDBC connection has
+    the same effect as this command.</simpara>
+
+    <!-- From Foundation chapt. 19 -->
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET SESSION CHARACTERISTICS</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET SESSION
+    CHARACTERISTICS</emphasis></simpara>
+
+    <simpara><emphasis>set session characteristics
+    statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set session characteristics statement&gt; ::= SET
+    SESSION CHARACTERISTICS AS &lt;session characteristic
+    list&gt;</literal></simpara>
+
+    <simpara><literal>&lt;session characteristic list&gt; ::= &lt;session
+    characteristic&gt; [ { &lt;comma&gt; &lt;session characteristic&gt; }...
+    ]</literal></simpara>
+
+    <simpara><literal>&lt;session characteristic&gt; ::= &lt;session
+    transaction characteristics&gt;</literal></simpara>
+
+    <simpara><literal>&lt;session transaction characteristics&gt; ::=
+    TRANSACTION &lt;transaction mode&gt; [ { &lt;comma&gt; &lt;transaction
+    mode&gt; }... ]</literal></simpara>
+
+    <simpara>Set one or more characteristics for the current SQL-session. This
+    command is used to set the transaction mode for the session. This endures
+    for all transactions until the session is closed or the next use of this
+    command. The current read-only mode can be accessed with the ISREADONLY()
+    function.</simpara>
+
+    <example>
+      <title>Setting Session Characteristics</title>
+
+      <screen>  SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY
+  SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE
+  SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE, ISOLATION LEVEL READ COMMITTED
+</screen>
+    </example>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET SESSION AUTHORIZATION</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET SESSION
+    AUTHORIZATION</emphasis></simpara>
+
+    <simpara><emphasis>set session user identifier
+    statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set session user identifier statement&gt; ::= SET
+    SESSION AUTHORIZATION &lt;value specification&gt;</literal></simpara>
+
+    <simpara>Set the SQL-session user identifier. This statement changes the
+    current user. The user that executes this command must have the
+    CHANGE_AUTHORIZATION role, or the DBA role. After this statement is
+    executed, all SQL statements are executed with the privileges of the new
+    user. The current authorisation can be accessed with the CURRENT_USER and
+    SESSION_USER functions.</simpara>
+
+    <example>
+      <title>Setting Session Authorization</title>
+
+      <screen>  SET SESSION AUTHORIZATION 'FELIX'
+  SET SESSION AUTHORIZATION SESSION_USER
+</screen>
+    </example>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET ROLE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET ROLE</emphasis></simpara>
+
+    <simpara><emphasis>set role statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set role statement&gt; ::= SET ROLE &lt;role
+    specification&gt;</literal></simpara>
+
+    <simpara><literal>&lt;role specification&gt; ::= &lt;value
+    specification&gt; | NONE</literal></simpara>
+
+    <simpara>Set the SQL-session role name and the current role name for the
+    current SQL-session context. The user that executes this command must have
+    the specified role. If NONE is specified, then the previous CURRENT_ROLE
+    is eliminated. The effect of this lasts for the lifetime of the session.
+    The current role can be accessed with the CURRENT_ROLE function.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET TIME ZONE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET TIME ZONE</emphasis></simpara>
+
+    <simpara><emphasis>set local time zone statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set local time zone statement&gt; ::= SET TIME ZONE
+    &lt;set time zone value&gt;</literal></simpara>
+
+    <simpara><literal>&lt;set time zone value&gt; ::= &lt;interval value
+    expression&gt; | LOCAL</literal></simpara>
+
+    <simpara>Set the current default time zone displacement for the current
+    SQL-session. When the session starts, the time zone displacement is set to
+    the time zone of the client. This command changes the time zone
+    displacement. The effect of this lasts for the lifetime of the session. If
+    LOCAL is specified, the time zone displacement reverts to the local time
+    zone of the session.</simpara>
+
+    <example>
+      <title>Setting Session Time Zone</title>
+
+      <screen>    SET TIME ZONE LOCAL
+    SET TIME ZONE INTERVAL '+6:00' HOUR TO MINUTE
+</screen>
+    </example>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET CATALOG</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET CATALOG</emphasis></simpara>
+
+    <simpara><emphasis>set catalog statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set catalog statement&gt; ::= SET &lt;catalog name
+    characteristic&gt;</literal></simpara>
+
+    <simpara><literal>&lt;catalog name characteristic&gt; ::= CATALOG
+    &lt;value specification&gt;</literal></simpara>
+
+    <simpara>Set the default schema name for unqualified names used in SQL
+    statements that are prepared or executed directly in the current sessions.
+    As there is only one catalog in the database, only the name of this
+    catalog can be used. The current catalog can be accessed with the
+    CURRENT_CATALOG function.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET SCHEMA</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET SCHEMA</emphasis></simpara>
+
+    <simpara><emphasis>set schema statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set schema statement&gt; ::= SET &lt;schema name
+    characteristic&gt;</literal></simpara>
+
+    <simpara><literal>&lt;schema name characteristic&gt; ::= SCHEMA &lt;value
+    specification&gt; | &lt;schema name&gt;</literal></simpara>
+
+    <simpara>Set the default schema name for unqualified names used in SQL
+    statements that are prepared or executed directly in the current sessions.
+    The effect of this lasts for the lifetime of the session. The SQL Standard
+    form requires the schema name as a single-quoted string. HyperSQL also
+    allows the use of the identifier for the schema. The current schema can be
+    accessed with the CURRENT_SCHEMA function.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET PATH</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET PATH</emphasis></simpara>
+
+    <simpara><emphasis>set path statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set path statement&gt; ::= SET &lt;SQL-path
+    characteristic&gt;</literal></simpara>
+
+    <simpara><literal>&lt;SQL-path characteristic&gt; ::= PATH &lt;value
+    specification&gt;</literal></simpara>
+
+    <simpara>Set the SQL-path used to determine the subject routine of routine
+    invocations with unqualified routine names used in SQL statements that are
+    prepared or executed directly in the current sessions. The effect of this
+    lasts for the lifetime of the session.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET MAXROWS</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET MAXROWS</emphasis></simpara>
+
+    <simpara><emphasis>set max rows statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set max rows statement&gt; ::= SET MAXROWS
+    &lt;unsigned integer literal&gt;</literal></simpara>
+
+    <simpara>The normal operation of the session has no limit on the number of
+    rows returned from a SELECT statement. This command set the maximum number
+    of rows of the result returned by executing queries.</simpara>
+
+    <simpara>This statement has a similar effect to the
+    <methodname>setMaxRows(int max)</methodname> method of the JDBC
+    <classname>Statement</classname> interface, but it affects the results
+    returned from the next statement execution only. After the execution of
+    the next statement, the MAXROWS limit is removed.</simpara>
+
+    <simpara>Only zero or positive values can be used with this command. The
+    value overrides any value specified with <methodname>setMaxRows(int
+    max)</methodname> method of a JDBC statement. The statement <literal>SET
+    MAXROWS 0</literal> means no limit.</simpara>
+
+    <simpara>It is possible to limit the number of rows returned from SELECT
+    statements with the FETCH &lt;n&gt; ROWS ONLY, or its alternative, LIMIT
+    &lt;n&gt;. Therefore this command is not recommended for general use. The
+    only legitimate use of this command is for checking and testing queries
+    that may return very large numbers of rows.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET SESSION RESULT MEMORY ROWS</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET SESSION RESULT MEMORY
+    ROWS</emphasis></simpara>
+
+    <simpara><emphasis>set session result memory rows
+    statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set session result memory rows statement&gt; ::= SET
+    SESSION RESULT MEMORY ROWS &lt;unsigned integer
+    literal&gt;</literal></simpara>
+
+    <simpara>By default the session uses memory to build result sets, subquery
+    results and temporary tables. This command sets the maximum number of rows
+    of the result (and temporary tables) that should be kept in memory. If the
+    row count of the result or temporary table exceeds the setting, the result
+    is stored on disk. The default is 0, meaning all result sets are held in
+    memory.</simpara>
+
+    <simpara>This statement applies to the current session only. The general
+    database setting is:</simpara>
+
+    <simpara><literal>SET DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned
+    integer literal&gt;</literal></simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SET IGNORECASE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SET IGNORECASE</emphasis></simpara>
+
+    <simpara><emphasis>set ignore case statement</emphasis></simpara>
+
+    <simpara><literal>&lt;set ignore case statement&gt; ::= SET IGNORECASE {
+    TRUE | FALSE }</literal></simpara>
+
+    <simpara>Sets the type used for new VARCHAR table columns. By default,
+    character columns in new databases are case sensitive. If <literal>SET
+    IGNORECASE TRUE</literal> is used, all VARCHAR columns in new tables are
+    set to <literal>VARCHAR_IGNORECASE</literal>. It is possible to specify
+    the <literal>VARCHAR_IGNORECASE</literal> type for the definition of
+    individual columns. So it is possible to have some columns case sensitive
+    and some not, even in the same table. This statement must be switched
+    before creating tables. Existing tables and their data are not
+    affected.</simpara>
+  </section>
+</chapter>
diff --git a/doc-src/guide/sqlgeneral.xml b/doc-src/guide/sqlgeneral.xml
new file mode 100644
index 0000000..e1a94a4
--- /dev/null
+++ b/doc-src/guide/sqlgeneral.xml
@@ -0,0 +1,1632 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: sqlgeneral.xml 3601 2010-06-01 00:17:47Z fredt $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<chapter version="5.0" xml:id="sqlgeneral-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/2000/svg"
+         xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <title xml:id="sqlgeneral-title">SQL Language</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+    <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section xml:id="sqlgeneral_standards-sect">
+    <title>Standards Support</title>
+
+    <para>HyperSQL 2.0 supports the dialect of SQL defined by SQL standards
+    92, 1999, 2003 and 2008. This means where a feature of the standard is
+    supported, e.g. left outer join, the syntax is that specified by the
+    standard text. Almost all syntactic features of SQL-92 up to Advanced
+    Level are supported, as well as SQL:2008 core and many optional features
+    of this standard. Work is in progress for a formal declaration of
+    conformance.</para>
+
+    <para>At the time of this release, HyperSQL supports the widest range of
+    SQL standard features among all open source RDBMS.</para>
+
+    <para>Various chapters of this guide list the supported syntax. When
+    writing or converting existing SQL DDL (Data Definition Language), DML
+    (Data Manipulation Language) or DQL (Data Query Language) statements for
+    HSQLDB, you should consult the supported syntax and modify the statements
+    accordingly. Some statements written for older versions may have to be
+    modified.</para>
+
+    <para>Over 300 words are reserved by the standard and should not be used
+    as table or column names. For example, the word POSITION is reserved as it
+    is a function defined by the Standards with a similar role as
+    <methodname>String.indexOf()</methodname> in Java. HyperSQL does not
+    currently prevent you from using a reserved word if it does not support
+    its use or can distinguish it. For example CUBE is a reserved words that
+    is not currently supported by HyperSQL and is allowed as a table or column
+    name. You should avoid using such names as future versions of HyperSQL are
+    likely to support the reserved words and may reject your table definitions
+    or queries. The full list of SQL reserved words is in the appendix <link
+    endterm="lists-title" xlink:href="#lists-app"></link> .</para>
+
+    <para>If you have to use a reserved keyword as the name of a database
+    object, you can enclose it in double quotes.</para>
+
+    <para>HyperSQL also supports enhancements with keywords and expressions
+    that are not part of the SQL standard. Expressions such as <literal>SELECT
+    TOP 5 FROM ..</literal>, <literal>SELECT LIMIT 0 10 FROM ...</literal> or
+    <literal>DROP TABLE mytable IF EXISTS</literal> are among such
+    constructs.</para>
+
+    <para>Many print books cover SQL Standard syntax and can be consulted. For
+    a well-written basic guide to SQL with examples, you can also consult
+    <link
+    xlink:href="http://www.postgresql.org/files/documentation/books/aw_pgsql/index.html">PostgreSQL:
+    Introduction and Concepts</link> by Bruce Momjian, which is available on
+    the web. Most of the core SQL coverage in the book applies also to
+    HyperSQL. There are some differences in keywords supported by one and not
+    the other engine (OUTER, OID's, etc.) or used differently
+    (IDENTITY/SERIAL, TRIGGER, SEQUENCE, etc.).</para>
+
+    <para>In HyperSQL version 2.0, all features of JDBC4 that apply to the
+    capabilities of HSQLDB are fully supported. The relevant JDBC classes are
+    thoroughly documented with additional clarifications and HyperSQL specific
+    comments. See the <link xlink:href="#javadoc-link">JavaDoc</link> for the
+    <classname>org.hsqldb.jdbc.*</classname> classes.</para>
+  </section>
+
+  <section xml:id="sqlgeneral_tabletypes-sect">
+    <title>SQL Data and Tables</title>
+
+    <para>In an SQL system, all significant data is stored in tables and
+    sequence generators. Therefore, the first step in creating a database is
+    defining the tables and their columns. The SQL standard supports temporary
+    tables, which are for temporary data, and permanent base tables, which are
+    for persistent data.</para>
+
+    <section>
+      <title>Temporary Tables</title>
+
+      <para>TEMPORARY tables are not saved and last only for the lifetime of
+      the Connection object. The contents of each TEMP table is visible only
+      from the Connection that was used to populate it. The definition of TEMP
+      tables conforms to the GLOBAL TEMPORARY type in the SQL standard. The
+      definition of the table persists but each new connections sees its own
+      copy of the table, which is empty at the beginning. When the connection
+      commits, the contents of the table are cleared by default. If the table
+      definition statements includes ON COMMIT PRESERVE ROWS, then the
+      contents are kept when a commit takes place.</para>
+    </section>
+
+    <section>
+      <title>Persistent Tables</title>
+
+      <para>HSQLDB supports the Standard definition of persistent base table,
+      but defines three types according to the way the data is stored. These
+      are MEMORY tables, CACHED tables and TEXT tables.</para>
+
+      <para>Memory tables are the default type when the CREATE TABLE command
+      is used. Their data is held entirely in memory but any change to their
+      structure or contents is written to the <filename>*.log</filename> and
+      <filename>*.script</filename> files. The <filename>*.script</filename>
+      file and the <filename>*.log</filename> file are read the next time the
+      database is opened, and the MEMORY tables are recreated with all their
+      contents. So unlike TEMPORARY tables, MEMORY tables are persistent. When
+      the database is opened, all the data for the memory tables is read and
+      inserted. This process may take a long time if the database is larger
+      than tens of megabytes. When the database is shutdown, all the data is
+      saved. This can also take a long time.</para>
+
+      <para>CACHED tables are created with the CREATE CACHED TABLE command.
+      Only part of their data or indexes is held in memory, allowing large
+      tables that would otherwise take up to several hundred megabytes of
+      memory. Another advantage of cached tables is that the database engine
+      takes less time to start up when a cached table is used for large
+      amounts of data. The disadvantage of cached tables is a reduction in
+      speed. Do not use cached tables if your data set is relatively small. In
+      an application with some small tables and some large ones, it is better
+      to use the default, MEMORY mode for the small tables.</para>
+
+      <para>TEXT tables use a CSV (Comma Separated Value) or other delimited
+      text file as the source of their data. You can specify an existing CSV
+      file, such as a dump from another database or program, as the source of
+      a TEXT table. Alternatively, you can specify an empty file to be filled
+      with data by the database engine. TEXT tables are efficient in memory
+      usage as they cache only part of the text data and all of the indexes.
+      The Text table data source can always be reassigned to a different file
+      if necessary. The commands are needed to set up a TEXT table as detailed
+      in the <link endterm="texttables-title"
+      xlink:href="#texttables-chapt"></link> chapter.</para>
+
+      <para>With all-in-memory databases, both MEMORY table and CACHED table
+      declarations are treated as declarations for non-persistent memory
+      tables. TEXT table declarations are not allowed in these
+      databases.</para>
+
+      <para>The default type of table resulting from future CREATE TABLE
+      statements can be specified with the SQL command:</para>
+
+      <para><programlisting>    SET DATABASE DEFAULT TABLE TYPE { CACHED | MEMORY };</programlisting>The
+      type of an existing table can be changed with the SQL command:</para>
+
+      <para><programlisting>    SET TABLE &lt;table name&gt; TYPE { CACHED | MEMORY };</programlisting>SQL
+      statements access different types of tables uniformly. No change to
+      statements is needed to access different types of table.</para>
+    </section>
+
+    <section>
+      <title>Lob Data</title>
+
+      <para>Lobs are logically stored in columns of tables. Their physical
+      storage is a separate *.lobs file. In version 2.0 this file is created
+      as soon as a BLOB or CLOB is inserted into the database. The file will
+      grow as new lobs are inserted into the database. In version 2.0, the
+      *.lobs file is never deleted even if all lobs are deleted from the
+      database (In this case you can delete the .lobs file after a
+      SHTUDOWN).</para>
+    </section>
+  </section>
+
+  <section xml:id="sqlgeneral_types_ops-sect">
+    <title>Basic Types and Operations</title>
+
+    <para>HyperSQL supports all the types defined by SQL-92, plus BOOLEAN,
+    BINARY and LOB types that were added later to the SQL Standard. It also
+    supports the non-standard OTHER type to store serializable Java
+    objects.</para>
+
+    <para>SQL is a strongly typed language. All data stored in specific
+    columns of tables and other objects (such as sequence generators) have
+    specific types. Each data item conforms to the type limits such as
+    precision and scale for the column. It also conforms to any additional
+    integrity constraints that are defined as CHECK constraints in domains or
+    tables. Types can be explicitly converted using the CAST expression, but
+    in most expressions they are converted automatically.</para>
+
+    <para>Data is returned to the user (or the application program) as a
+    result of executing SQL statements such as query expressions or function
+    calls. All statements are compiled prior to execution and the return type
+    of the data is known after compilation and before execution. Therefore,
+    once a statement is prepared, the data type of each column of the returned
+    result is known, including any precision or scale property. The type does
+    not change when the same query that returned one row, returns many rows as
+    a result of adding more data to the tables.</para>
+
+    <para>Some SQL functions used within SQL statements are polymorphic, but
+    the exact type of the argument and the return value is determined at
+    compile time.</para>
+
+    <para>When a statement is prepared, using a JDBC PreparedStatement object,
+    it is compiled by the engine and the type of the columns of its ResultSet
+    and / or its parameters are accessible through the methods of
+    PreparedStatement.</para>
+
+    <section>
+      <title>Numeric Types</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>NUMERIC types</primary>
+      </indexterm>
+
+      <para>TINYINT, SMALLINT, INTEGER, BIGINT, NUMERIC and DECIMAL (without a
+      decimal point) are the supported integral types. They correspond
+      respectively to <classname>byte</classname>,
+      <classname>short</classname>, <classname>int</classname>,
+      <classname>long</classname>, <classname>BigDecimal</classname> and
+      <classname>BigDecimal</classname> Java types in the range of values that
+      they can represent (NUMERIC and DECIMAL are equivalent). The type
+      TINYINT is an HSQLDB extension to the SQL Standard, while the others
+      conform to the Standard definition. The SQL type dictates the maximum
+      and minimum values that can be held in a field of each type. For example
+      the value range for TINYINT is -128 to +127. The bit precision of
+      TINYINT, SMALLINT, INTEGER and BIGINT is respectively 8, 16, 32 and 64.
+      For NUMERIC and DECIMAL, decimal precision is used.</para>
+
+      <para>DECIMAL and NUMERIC with decimal fractions are mapped to
+      <classname>java.math.BigDecimal</classname> and can have very large
+      numbers of digits. In HyperSQL the two types are equivalent. These
+      types, together with integral types, are called exact numeric
+      types.</para>
+
+      <para>In HyperSQL, REAL, FLOAT, DOUBLE are equivalent and all mapped to
+      <classname>double</classname> in Java. These types are defined by the
+      SQL Standard as approximate numeric types. The bit-precision of all
+      these types is 64 bits.</para>
+
+      <para>The decimal precision and scale of NUMERIC and DECIMAL types can
+      be optionally defined. For example, DECIMAL(10,2) means maximum total
+      number of digits is 10 and there are always 2 digits after the decimal
+      point, while DECIMAL(10) means 10 digits without a decimal point. The
+      bit-precision of FLOAT can also be defined, but in this case, it is
+      ignored and the default bit-precision of 64 is used. The default
+      precision of NUMERIC and DECIMAL (when not defined) is 100.</para>
+
+      <para>Note: If a database has been set to ignore type precision limits
+      with the SET DATABASE SQL SIZE FALSE command, then a type definition of
+      DECIMAL with no precision and scale is treated as DECIMAL(100,10). In
+      normal operation, it is treated as DECIMAL(100).</para>
+
+      <simpara><emphasis role="bold">Integral Types</emphasis></simpara>
+
+      <para>In expressions, TINYINT, SMALLINT, INTEGER, BIGINT, NUMERIC and
+      DECIMAL (without a decimal point) are fully interchangeable, and no data
+      narrowing takes place.</para>
+
+      <para>If the SELECT statement refers to a simple column or function,
+      then the return type is the type corresponding to the column or the
+      return type of the function. For example:</para>
+
+      <informalexample>
+        <programlisting>    CREATE TABLE t(a INTEGER, b BIGINT);
+    SELECT MAX(a), MAX(b) FROM t;</programlisting>
+      </informalexample>
+
+      <para>will return a <classname>ResultSet</classname> where the type of
+      the first column is <classname>java.lang.Integer</classname> and the
+      second column is <classname>java.lang.Long</classname>. However,</para>
+
+      <informalexample>
+        <programlisting>    SELECT MAX(a) + 1, MAX(b) + 1 FROM t;</programlisting>
+      </informalexample>
+
+      <para>will return <classname>java.lang.Long</classname> and
+      <classname>BigDecimal</classname> values, generated as a result of
+      uniform type promotion for all the return values. Note that type
+      promotion to <classname>BigDecimal</classname> ensures the correct value
+      is returned if <literal>MAX(b)</literal> evaluates to
+      <literal>Long.MAX_VALUE</literal>.</para>
+
+      <para>There is no built-in limit on the size of intermediate integral
+      values in expressions. As a result, you should check for the type of the
+      <classname>ResultSet</classname> column and choose an appropriate
+      <methodname>getXXXX()</methodname> method to retrieve it. Alternatively,
+      you can use the <methodname>getObject()</methodname> method, then cast
+      the result to <classname>java.lang.Number</classname> and use the
+      <methodname>intValue()</methodname> or
+      <methodname>longValue()</methodname> methods on the result.</para>
+
+      <para>When the result of an expression is stored in a column of a
+      database table, it has to fit in the target column, otherwise an error
+      is returned. For example when <literal>1234567890123456789012 /
+      12345687901234567890</literal> is evaluated, the result can be stored in
+      any integral type column, even a TINYINT column, as it is a small
+      value.</para>
+
+      <para>In SQL Statements, an integer literal is treated as INTEGER,
+      unless its value does not fit. In this case it is treated as BIGINT or
+      DECIMAL, depending on the value.</para>
+
+      <para>Depending on the types of the operands, the result of the
+      operations is returned in a JDBC <classname>ResultSet</classname> in any
+      of related Java types: <classname>Integer</classname>,
+      <classname>Long</classname> or <classname>BigDecimal</classname>. The
+      <methodname>ResultSet.getXXXX()</methodname> methods can be used to
+      retrieve the values so long as the returned value can be represented by
+      the resulting type. This type is deterministically based on the query,
+      not on the actual rows returned.</para>
+
+      <simpara><emphasis role="bold">Other Numeric Types</emphasis></simpara>
+
+      <para>In SQL statements, number literals with a decimal point are
+      treated as DECIMAL unless they are written with an exponent. Thus
+      <literal>0.2</literal> is considered a DECIMAL value but
+      <literal>0.2E0</literal> is considered a DOUBLE value.</para>
+
+      <para>When an approximate numeric type, REAL, FLOAT or DOUBLE (all
+      synonymous) is part of an expression involving different numeric types,
+      the type of the result is DOUBLE. DECIMAL values can be converted to
+      DOUBLE unless they are beyond the <literal>Double.MIN_VALUE -
+      Double.MAX_VALUE</literal> range. For example, A * B, A / B, A + B, etc.
+      will return a DOUBLE value if either A or B is a DOUBLE.</para>
+
+      <para>Otherwise, when no DOUBLE value exists, if a DECIMAL or NUMERIC
+      value is part an expression, the type of the result is DECIMAL or
+      NUMERIC. Similar to integral values, when the result of an expression is
+      assigned to a table column, the value has to fit in the target column,
+      otherwise an error is returned. This means a small, 4 digit value of
+      DECIMAL type can be assigned to a column of SMALLINT or INTEGER, but a
+      value with 15 digits cannot.</para>
+
+      <para>When a DECIMAL values is multiplied by a DECIMAL or integral type,
+      the resulting scale is the sum of the scales of the two terms. When they
+      are divided, the result is a value with a scale (number of digits to the
+      right of the decimal point) equal to the larger of the scales of the two
+      terms. The precision for both operations is calculated (usually
+      increased) to allow all possible results.</para>
+
+      <para>The distinction between DOUBLE and DECIMAL is important when a
+      division takes place. For example, <literal>10.0/8.0</literal> (DECIMAL)
+      equals <literal>1.2</literal> but <literal>10.0E0/8.0E0</literal>
+      (DOUBLE) equals <literal>1.25</literal>. Without division operations,
+      DECIMAL values represent exact arithmetic.</para>
+
+      <para>REAL, FLOAT and DOUBLE values are all stored in the database as
+      <classname>java.lang.Double</classname> objects. Special values such as
+      NaN and +-Infinity are also stored and supported. These values can be
+      submitted to the database via JDBC
+      <classname>PreparedStatement</classname> methods and are returned in
+      <classname>ResultSet</classname> objects. The result can be retrieved
+      from a <classname>ResultSet</classname> in the required type so long as
+      it can be represented. When
+      <methodname>PreparedStatement.setDouble()</methodname> or
+      <methodname>setFloat()</methodname> is used, the value is treated as a
+      DOUBLE automatically.</para>
+
+      <para>In short,</para>
+
+      <simpara><literal>&lt;numeric type&gt; ::= &lt;exact numeric type&gt; |
+      &lt;approximate numeric type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;exact numeric type&gt; ::= NUMERIC [ &lt;left
+      paren&gt; &lt;precision&gt; [ &lt;comma&gt; &lt;scale&gt; ] &lt;right
+      paren&gt; ] | { DECIMAL | DEC } [ &lt;left paren&gt; &lt;precision&gt; [
+      &lt;comma&gt; &lt;scale&gt; ] &lt;right paren&gt; ] | SMALLINT | INTEGER
+      | INT | BIGINT</literal></simpara>
+
+      <simpara><literal>&lt;approximate numeric type&gt; ::= FLOAT [ &lt;left
+      paren&gt; &lt;precision&gt; &lt;right paren&gt; ] | REAL | DOUBLE
+      PRECISION</literal></simpara>
+
+      <simpara><literal>&lt;precision&gt; ::= &lt;unsigned
+      integer&gt;</literal></simpara>
+
+      <simpara><literal>&lt;scale&gt; ::= &lt;unsigned
+      integer&gt;</literal></simpara>
+    </section>
+
+    <section>
+      <title>Boolean Type</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>BOOLEAN types</primary>
+      </indexterm>
+
+      <para>The BOOLEAN type conforms to the SQL Standard and represents the
+      values <literal>TRUE</literal>, <literal>FALSE</literal> and
+      <literal>UNKNOWN</literal>. This type of column can be initialised with
+      Java boolean values, or with <literal>NULL</literal> for the
+      <literal>UNKNOWN</literal> value.</para>
+
+      <para>The three-value logic is sometimes misunderstood. For example, x
+      IN (1, 2, NULL) does not return true if x is NULL.</para>
+
+      <para>In previous versions of HyperSQL, BIT was simply an alias for
+      BOOLEAN. In version 2.0, BIT is a single-bit bit map.</para>
+
+      <simpara><literal>&lt;boolean type&gt; ::= BOOLEAN</literal></simpara>
+
+      <para>The SQL Standard does not support type conversion to BOOLEAN apart
+      from character strings that consists of boolean literals. Because the
+      BOOLEAN type is relatively new to the Standard, several database
+      products used other types to represent boolean values. For improved
+      compatibility, HyperSQL allows some type conversions to boolean.</para>
+
+      <para>Values of BIT and BIT VARYING types with length 1 can be converted
+      to BOOLEAN. If the bit is set, the result of conversion is the TRUE
+      value, otherwise it is FALSE.</para>
+
+      <para>Values of TINYINT, SMALLINT, INTEGER and BIGINT types can be
+      converted to BOOLEAN. If the value is zero, the result is the FALSE
+      value, otherwise it is TRUE.</para>
+    </section>
+
+    <section>
+      <title>Character String Types</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CHARACTER types</primary>
+      </indexterm>
+
+      <para>The CHARACTER, CHARACTER VARYING and CLOB types are the SQL
+      Standard character string types. CHAR, VARCHAR and CHARACTER LARGE
+      OBJECT are synonyms for these types. HyperSQL also supports LONGVARCHAR
+      as a synonym for VARCHAR. If LONGVARCHAR is used without a length, then
+      a length of 1M is assigned.</para>
+
+      <para>HyperSQL's default character set is Unicode, therefore all
+      possible character strings can be represented by these types.</para>
+
+      <para>The SQL Standard behaviour of the CHARACTER type is a remnant of
+      legacy systems in which character strings are padded with spaces to fill
+      a fixed width. These spaces are sometimes significant while in other
+      cases they are silently discarded. It would be best to avoid the
+      CHARACTER type altogether. With the rest of the types, the strings are
+      not padded when assigned to columns or variables of the given type. The
+      trailing spaces are still considered discardable for all character
+      types. Therefore if a string with trailing spaces is too long to assign
+      to a column or variable of a given length, the spaces beyond the type
+      length are discarded and the assignment succeeds (provided all the
+      characters beyond the type length are spaces).</para>
+
+      <para>The VARCHAR and CLOB types have length limits, but the strings are
+      not padded by the system. Note that if you use a large length for a
+      VARCHAR or CLOB type, no extra space is used in the database. The space
+      used for each stored item is proportional to its actual length.</para>
+
+      <para>If CHARACTER is used without specifying the length, the length
+      defaults to 1. For the CLOB type, the length limit can be defined in
+      units of kilobyte (K, 1024), megabyte (M, 1024 * 1024) or gigabyte (G,
+      1024 * 1024 * 1024), using the <literal>&lt;multiplier&gt;</literal>. If
+      CLOB is used without specifying the length, the length defaults to
+      1M.</para>
+
+      <simpara><literal>&lt;character string type&gt; ::= { CHARACTER | CHAR }
+      [ &lt;left paren&gt; &lt;character length&gt; &lt;right paren&gt; ] | {
+      CHARACTER VARYING | CHAR VARYING | VARCHAR } &lt;left paren&gt;
+      &lt;character length&gt; &lt;right paren&gt; | LONGVARCHAR [ &lt;left
+      paren&gt; &lt;character length&gt; &lt;right paren&gt; ] | &lt;character
+      large object type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;character large object type&gt; ::= { CHARACTER
+      LARGE OBJECT | CHAR LARGE OBJECT | CLOB } [ &lt;left paren&gt;
+      &lt;character large object length&gt; &lt;right paren&gt;
+      ]</literal></simpara>
+
+      <simpara><literal>&lt;character length&gt; ::= &lt;unsigned integer&gt;
+      [ &lt;char length units&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;large object length&gt; ::= &lt;length&gt; [
+      &lt;multiplier&gt; ] | &lt;large object length
+      token&gt;</literal></simpara>
+
+      <simpara><literal>&lt;character large object length&gt; ::= &lt;large
+      object length&gt; [ &lt;char length units&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;large object length token&gt; ::= &lt;digit&gt;...
+      &lt;multiplier&gt;</literal></simpara>
+
+      <simpara><literal>&lt;multiplier&gt; ::= K | M | G </literal></simpara>
+
+      <simpara><literal>&lt;char length units&gt; ::= CHARACTERS |
+      OCTETS</literal></simpara>
+
+      <programlisting>CHAR(10)
+CHARACTER(10)
+VARCHAR(2)
+CHAR VARYING(2)
+CLOB(1000)
+CLOB(30K)
+CHARACTER LARGE OBJECT(1M)
+LONGVARCHAR
+</programlisting>
+    </section>
+
+    <section>
+      <title>Binary String Types</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>BINARY types</primary>
+      </indexterm>
+
+      <para>The BINARY, BINARY VARYING and BLOB types are the SQL Standard
+      binary string types. VARBINARY and BINARY LARGE OBJECT are synonyms for
+      BINARY VARYING and BLOB types. HyperSQL also supports LONGVARBINARY as a
+      synonym for VARBINARY.</para>
+
+      <para>Binary string types are used in a similar way to character string
+      types. There are several built-in functions that are overloaded to
+      support character, binary and bit strings.</para>
+
+      <para>The BINARY type represents a fixed width-string. Each shorter
+      string is padded with zeros to fill the fixed width. Similar to the
+      CHARACTER type, the trailing zeros in the BINARY string are simply
+      discarded in some operations. For the same reason, it is best to avoid
+      this particular type.</para>
+
+      <para>If BINARY is used without specifying the length, the length
+      defaults to 1. For the BLOB type, the length limit can be defined in
+      units of kilobyte (K, 1024), megabyte (M, 1024 * 1024) or gigabyte (G,
+      1024 * 1024 * 1024), using the <literal>&lt;multiplier&gt;</literal>. If
+      BLOB is used without specifying the length, the length defaults to
+      1M.</para>
+
+      <simpara><literal>&lt;binary string type&gt; ::= BINARY [ &lt;left
+      paren&gt; &lt;length&gt; &lt;right paren&gt; ] | { BINARY VARYING |
+      VARBINARY } &lt;left paren&gt; &lt;length&gt; &lt;right paren&gt; |
+      LONGVARBINARY [ &lt;left paren&gt; &lt;length&gt; &lt;right paren&gt; ]
+      | &lt;binary large object string type&gt;</literal></simpara>
+
+      <simpara><literal>&lt;binary large object string type&gt; ::= { BINARY
+      LARGE OBJECT | BLOB } [ &lt;left paren&gt; &lt;large object length&gt;
+      &lt;right paren&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;length&gt; ::= &lt;unsigned
+      integer&gt;</literal></simpara>
+
+      <programlisting>BINARY(10)
+VARBINARY(2)
+BINARY VARYING(2)
+BLOB(1000)
+BLOB(30K)
+BINARY LARGE OBJECT(1M)
+LONGVARBINARY
+</programlisting>
+    </section>
+
+    <section>
+      <title>Bit String Types</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>BIT types</primary>
+      </indexterm>
+
+      <para>The BIT and BIT VARYING types are the supported bit string types.
+      These types were defined by SQL:1999 but were later removed from the
+      Standard. Bit types represent bit maps of given lengths. Each bit is 0
+      or 1. The BIT type represents a fixed width-string. Each shorter string
+      is padded with zeros to fill the fixed with. If BIT is used without
+      specifying the length, the length defaults to 1. The BIT VARYING type
+      has a maximum width and shorter strings are not padded.</para>
+
+      <para>Before the introduction of the BOOLEAN type to the SQL Standard, a
+      sigle-bit string of the type BIT(1) was commonly used. For compatibility
+      with other products that do not conform to, or extend, the SQL Standard,
+      HyperSQL allows values of BIT and BIT VARYING types with length 1 to be
+      converted to and from the BOOLEAN type. BOOLEAN TRUE is considered equal
+      to B'1', BOOLEAN FALSE is considered equal to B'0'.</para>
+
+      <para>For the same reason, numeric values can be assigned to columns and
+      variables of the type BIT(1). For assignment, the numeric value zero is
+      converted to B'0', while all other values are converted to B'1'. For
+      comparison, numeric values 1 is considered equal to B'1' and numeric
+      value zero is considered equal to B'0'.</para>
+
+      <para>It is not allowed to perform other arithmetic or boolean
+      operations involving BIT(1) and BIT VARYING(1). The kid of operations
+      allowed on bit strings are analogous to those allowed on BINARY and
+      CHARACTER strings. Several built-in functions support all three types of
+      string.</para>
+
+      <simpara><literal>&lt;bit string type&gt; ::= BIT [ &lt;left paren&gt;
+      &lt;length&gt; &lt;right paren&gt; ] | BIT VARYING &lt;left paren&gt;
+      &lt;length&gt; &lt;right paren&gt;</literal></simpara>
+
+      <programlisting>BIT
+BIT(10)
+BIT VARYING(2)
+</programlisting>
+    </section>
+
+    <section>
+      <title>Storage and Handling of Java Objects</title>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>OTHER type</primary>
+      </indexterm>
+
+      <para>Any serializable JAVA Object can be inserted directly into a
+      column of type OTHER using any variation of
+      <methodname>PreparedStatement.setObject()</methodname> methods.</para>
+
+      <para>For comparison purposes and in indexes, any two Java Objects are
+      considered equal unless one of them is NULL. You cannot search for a
+      specific object or perform a join on a column of type OTHER.</para>
+
+      <para>Please note that HSQLDB is not an object-relational database. Java
+      Objects can simply be stored internally and no operations should be
+      performed on them other than assignment between columns of type OTHER or
+      tests for NULL. Tests such as <literal>WHERE object1 = object2
+      </literal>do not mean what you might expect, as any non-null object
+      would satisfy such a tests. But <literal>WHERE object1 IS NOT
+      NULL</literal> is perfectly acceptable.</para>
+
+      <para>The engine does not allow normal column values to be assigned to
+      Java Object columns (for example, assigning an INTEGER or STRING to such
+      a column with an SQL statement such as <literal>UPDATE mytable SET
+      objectcol = intcol WHERE ...</literal>).</para>
+
+      <simpara><literal>&lt;java object type&gt; ::= OTHER</literal></simpara>
+    </section>
+
+    <section>
+      <title>Type Length, Precision and Scale</title>
+
+      <para>In older version of HyperSQL, all table column type definitions
+      with a column length, precision or scale qualifier were accepted and
+      ignored. HSQLDB 1.8 enforced correctness but included an option to
+      enforce the length, precision or scale.</para>
+
+      <para>In HyperSQL 2.0, length, precision and scale qualifiers are always
+      enforced. For backward compatibility, when older databases which had the
+      property hsqldb.enforce_strict_size=false are converted to version 2.0,
+      this property is retained. However, this is a temporary measure. You
+      should test your application to ensure the length, precision and scale
+      that is used for column definitions is appropriate for the application
+      data. You can test with the default database setting, which enforces the
+      sizes.</para>
+
+      <para>String types, including all BIT, BINARY and CHAR string types plus
+      CLOB and BLOB, are generally defined with a length. If no length is
+      specified for BIT, BINARY and CHAR, the default length is 1. For CLOB
+      and BLOB an implementation defined length of 1M is used.</para>
+
+      <para>TIME and TIMESTAMP types can be defined with a fractional second
+      precision between 0 and 9. INTERVAL type definition may have precision
+      and, in some cases, fraction second precision. DECIMAL and NUMERIC types
+      may be defined with precision and scale. For all of these types a
+      default precision or scale value is used if one is not specified. The
+      default scale is 0. The default fractional precision for TIME is 0,
+      while it is 6 for TIMESTAMP.</para>
+
+      <para>Values can be converted from one type to another in two different
+      ways: by using explicit CAST expression or by implicit conversion used
+      in assignment, comparison and aggregation.</para>
+
+      <para>String values cannot be assigned to VARCHAR columns if they are
+      longer than the defined type length. For CHARACTER columns, a long
+      string can be assigned (with truncation) only if all the characters
+      after the length are spaces. Shorter strings are padded with the space
+      character when inserted into a CHARACTER column. Similar rules are
+      applied to VARBINARY and BINARY columns. For BINARY columns, the padding
+      and truncation rules are applied with zero bytes, instead of
+      spaces.</para>
+
+      <para>Explicit CAST of a value to a CHARACTER or VARCHAR type will
+      result in forced truncation or padding. So a test such as <literal>CAST
+      (mycol AS VARCHAR(2)) = 'xy'</literal> will find the values beginning
+      with 'xy'. This is the equivalent of <literal>SUBSTRING(mycol FROM 1 FOR
+      2)= 'xy'</literal>.</para>
+
+      <para>For all numeric types, the rules of explicit cast and implicit
+      conversion are the same. If cast or conversion causes any digits to be
+      lost from the fractional part, it can take place. If the non-fractional
+      part of the value cannot be represented in the new type, cast or
+      conversion cannot take place and will result in a data exception.</para>
+
+      <para>There are special rules for DATE, TIME, TIMESTAMP and INTERVAL
+      casts and conversions.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Datetime types</title>
+
+    <para>HSQLDB fully supports datetime and interval types and operations,
+    including all relevant optional features, as specified by the SQL Standard
+    since SQL-92. The two groups of types are complementary.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DATETIME types</primary>
+    </indexterm>
+
+    <para>The DATE type represents a calendar date with YEAR, MONTH and DAY
+    fields.</para>
+
+    <para>The TIME type represents time of day with HOUR, MINUTE and SECOND
+    fields, plus an optional SECOND FRACTION field.</para>
+
+    <para>The TIMESTAMP type represents the combination of DATE and TIME
+    types.</para>
+
+    <para>TIME and TIMESTAMP types can include WITH TIME ZONE or WITHOUT TIME
+    ZONE (the default) qualifiers. They can have fractional second parts. For
+    example, TIME(6) has six fractional digits for the second field.</para>
+
+    <para>If fractional second precision is not specified, it defaults to 0
+    for TIME and to 6 for TIMESTAMP.</para>
+
+    <simpara><literal>&lt;datetime type&gt; ::= DATE | TIME [ &lt;left
+    paren&gt; &lt;time precision&gt; &lt;right paren&gt; ] [ &lt;with or
+    without time zone&gt; ] | TIMESTAMP [ &lt;left paren&gt; &lt;timestamp
+    precision&gt; &lt;right paren&gt; ] [ &lt;with or without time zone&gt;
+    ]</literal></simpara>
+
+    <simpara><literal>&lt;with or without time zone&gt; ::= WITH TIME ZONE |
+    WITHOUT TIME ZONE</literal></simpara>
+
+    <simpara><literal>&lt;time precision&gt; ::= &lt;time fractional seconds
+    precision&gt;</literal></simpara>
+
+    <simpara><literal>&lt;timestamp precision&gt; ::= &lt;time fractional
+    seconds precision&gt;</literal></simpara>
+
+    <simpara><literal>&lt;time fractional seconds precision&gt; ::=
+    &lt;unsigned integer&gt;</literal></simpara>
+
+    <programlisting>DATE
+TIME(6)
+TIMESTAMP(2) WITH TIME ZONE
+</programlisting>
+
+    <para>Examples of the string literals used to represent date time values,
+    some with time zone, some without, are below:</para>
+
+    <programlisting>DATE '2008-08-22'
+TIMESTAMP '2008-08-08 20:08:08'
+TIMESTAMP '2008-08-08 20:08:08+8:00' /* Beijing */
+TIME '20:08:08.034900'
+TIME '20:08:08.034900-8:00' /* US Pacific */</programlisting>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>Time Zone</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">Time Zone</emphasis></simpara>
+
+    <para>DATE values do not take time zones. For example United Nations
+    designates 5 June as World Environment Day, which was observed on DATE
+    '2008-06-05' in different time zones.</para>
+
+    <para>TIME and TIMESTAMP values without time zone, usually have a context
+    that indicates some local time zone. For example, a database for college
+    course timetables usually stores class dates and times without time zones.
+    This works because the location of the college is fixed and the time zone
+    displacement is the same for all the values. Even when the events take
+    place in different time zones, for example international flight times, it
+    is possible to store all the datetime information as references to a
+    single time zone, usually GMT. For some databases it may be useful to
+    store the time zone displacement together with each datetime value. SQL’s
+    TIME WITH TIME ZONE and TIMESTAMP WITH TIME ZONE values include a time
+    zone displacement value.</para>
+
+    <para>The time zone displacement is of the type INTERVAL HOUR TO MINUTE.
+    This data type is described in the next section. The legal values are
+    between '–14:00' and   '+14:00'.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>Datetime Operations</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">Operations on Datetime
+    Types</emphasis></simpara>
+
+    <para>The expression <literal>&lt;datetime expression&gt; AT TIME ZONE
+    &lt;time displacement&gt;</literal> evaluates to a datetime value
+    representing exactly the same point of time in the specified
+    <literal>&lt;time displacement&gt;</literal>. The expression, <literal>AT
+    LOCAL</literal> is equivalent to <literal>AT TIME ZONE &lt;local time
+    displacement&gt;</literal>. If <literal>AT TIME ZONE</literal> is used
+    with a datetime operand of type WITHOUT TIME ZONE, the operand is first
+    converted to a value of type WITH TIME ZONE at the session’s time
+    displacement, then the specified time zone displacement is set for the
+    value. Therefore, in these cases, the final value depends on the time zone
+    of the session in which the statement was used.</para>
+
+    <para>AT TIME ZONE, modifies the field values of the datetime operand.
+    This is done by the following procedure:</para>
+
+    <orderedlist>
+      <listitem>
+        <para>determine the corresponding datetime at UTC.</para>
+      </listitem>
+
+      <listitem>
+        <para>find the datetime value at the given time zone that corresponds
+        with the UTC value from step 1.</para>
+      </listitem>
+    </orderedlist>
+
+    <para>Example a:</para>
+
+    <programlisting>TIME '12:00:00' AT TIME ZONE INTERVAL '1:00' HOUR TO MINUTE
+</programlisting>
+
+    <para>If the session’s time zone displacement is -'8:00', then in step 1,
+    TIME '12:00:00' is converted to UTC, which is TIME '20:00:00+0:00'. In
+    step 2, this value is expressed as TIME '21:00:00+1:00'.</para>
+
+    <para>Example b:</para>
+
+    <programlisting>TIME '12:00:00-5:00' AT TIME ZONE INTERVAL '1:00' HOUR TO MINUTE
+</programlisting>
+
+    <para>Because the operand has a time zone, the result is independent of
+    the session  time zone displacement. Step 1 results in TIME
+    '17:00:00+0:00', and step 2 results in TIME '18:00:00+1:00'</para>
+
+    <para>Note that the operand is not limited to datetime literals used in
+    these examples. Any valid expression that evaluates to a datetime value
+    can be the operand.</para>
+
+    <simpara><emphasis role="bold">Type Conversion</emphasis></simpara>
+
+    <para>CAST is used to for all other conversions. Examples:</para>
+
+    <programlisting>CAST (&lt;value&gt; AS TIME WITHOUT TIME ZONE)
+CAST (&lt;value&gt; AS TIME WITH TIME ZONE)</programlisting>
+
+    <para>In the first example, if <literal>&lt;value&gt;</literal> has a time
+    zone component, it is simply dropped. For example TIME '12:00:00-5:00' is
+    converted to TIME '12:00:00'</para>
+
+    <para>In the second example, if <literal>&lt;value&gt;</literal> has no
+    time zone component, the current time zone displacement of the session is
+    added. For example TIME '12:00:00' is converted to TIME '12:00:00-8:00'
+    when the session time zone displacement is '-8:00'.</para>
+
+    <para>Conversion between DATE and TIMESTAMP is performed by removing the
+    TIME component of a TIMESTAMP value or by setting the hour, minute and
+    second fields to zero. TIMESTAMP '2008-08-08 20:08:08+8:00' becomes DATE
+    '2008-08-08', while DATE '2008-08-22' becomes TIMESTAMP '2008-08-22
+    00:00:00'.</para>
+
+    <para>Conversion between TIME and TIMESTAMP is performed by removing the
+    DATE field values of a TIMESTAMP value or by appending the fields of the
+    TIME value to the fields of the current session date value.</para>
+
+    <simpara><emphasis role="bold">Assignment</emphasis></simpara>
+
+    <para>When a value is assigned to a datetime target, e.g., a value is used
+    to update a row of a table, the type of the value must be the same as the
+    target, but the WITH TIME ZONE or WITHOUT TIME ZONE characteristics can be
+    different. If the types are not the same, an explicit CAST must be used to
+    convert the value into the target type.</para>
+
+    <simpara><emphasis role="bold">Comparison</emphasis></simpara>
+
+    <para>When values WITH TIME ZONE are compared, they are converted to UTC
+    values before comparison. If a value WITH TIME ZONE is compared to another
+    WITHOUT TIME ZONE, then the WITH TIME ZONE value is converted to AT LOCAL,
+    then converted to WITHOUT TIME ZONE before comparison.</para>
+
+    <para>It is not recommended to design applications that rely on
+    comparisons and conversions between TIME values WITH TIME ZONE. The
+    conversions may involve normalisation of the time value, resulting in
+    unexpected results. For example, the expression: BETWEEN(TIME
+    '12:00:00-8:00', TIME '22:00:00-8:00') is converted to BETWEEN(TIME
+    '20:00:00+0:00', TIME '06:00:00+0:00') when it is evaluated in the UTC
+    zone, which is always FALSE.</para>
+
+    <simpara><emphasis role="bold">Functions</emphasis></simpara>
+
+    <para>Several functions return the current session timestamp in different
+    datetime types:</para>
+
+    <informaltable frame="all">
+      <tgroup cols="2">
+        <tbody>
+          <row>
+            <entry><para>CURRENT_DATE</para></entry>
+
+            <entry><para>DATE</para></entry>
+          </row>
+
+          <row>
+            <entry><para>CURRENT_TIME</para></entry>
+
+            <entry><para>TIME WITH TIME ZONE</para></entry>
+          </row>
+
+          <row>
+            <entry><para>CURRENT_TIMESTAMP</para></entry>
+
+            <entry><para>TIMESTAMP WITH TIME ZONE</para></entry>
+          </row>
+
+          <row>
+            <entry><para>LOCALTIME</para></entry>
+
+            <entry><para>TIMESTAMP WITHOUT TIME ZONE</para></entry>
+          </row>
+
+          <row>
+            <entry><para>LOCALTIMESTAMP</para></entry>
+
+            <entry><para>TIMESTAMP WITHOUT TIME ZONE</para></entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </informaltable>
+
+    <simpara><emphasis role="bold">Session Time Zone
+    Displacement</emphasis></simpara>
+
+    <para>When an SQL session is started (with a JDBC connection) the local
+    time zone of the client JVM (including any seasonal time adjustments such
+    as daylight saving time) is used as the session time zone displacement.
+    Note that the SQL session time displacement is not changed when a seasonal
+    time adjustment takes place while the session is open. To change the SQL
+    session time zone displacement use the following commands:</para>
+
+    <simpara><literal>SET TIME ZONE &lt;time
+    displacement&gt;</literal></simpara>
+
+    <simpara><literal>SET TIME ZONE LOCAL</literal></simpara>
+
+    <para>The first command sets the displacement to the given value. The
+    second command restores the original, real time zone displacement of the
+    session.</para>
+
+    <simpara><emphasis role="bold">Datetime Values and
+    Java</emphasis></simpara>
+
+    <para>When datetime values are sent to the database using the
+    <classname>PreparedStatement</classname> or
+    <classname>CallableStatement</classname> interfaces, the Java object is
+    converted to the type of the prepared or callable statement parameter.
+    This type may be DATE, TIME, or TIMESTAMP (with or without time zone). The
+    time zone displacement is the time zone of the JDBC session.</para>
+
+    <para>When datetime values are retrieved from the database using the
+    <literal>ResultSet</literal> interface, there are two representations. The
+    <methodname>getString(…)</methodname> methods of the
+    <classname>ResultSet</classname> interface, return an exact representation
+    of the value in the SQL type as it is stored in the database. This
+    includes the correct number of digits for the fractional second field, and
+    for values with time zone displacement, the time zone displacement.
+    Therefore if TIME '12:00:00' is stored in the database, all users in
+    different time zones will get '12:00:00' when they retrieve the value as a
+    string. The <methodname>getTime(…)</methodname> and
+    <methodname>getTimestamp(…)</methodname> methods of the
+    <classname>ResultSet</classname> interface return Java objects that are
+    corrected for the session time zone. The UTC millisecond value contained
+    the <classname>java.sql.Time</classname> or
+    <classname>java.sql.Timestamp</classname> objects will be adjusted to the
+    time zone of the session, therefore the
+    <methodname>toString()</methodname> method of these objects return the
+    same values in different time zones.</para>
+
+    <para>If you want to store and retrieve UTC values that are independent of
+    any session's time zone, you can use a TIMESTAMP WITH TIME ZONE column.
+    The setTime(...) and setTimestamp(...) methods of the PreparedStatement
+    interface which have a Calendar parameter can be used to assign the
+    values. The time zone of the given Calendar argument is used as the time
+    zone. Conversely, the getTime(...) and getTimestamp(...) methods of the
+    ResultSet interface which have a Calendar parameter can be used with a
+    Calendar argument to retrieve the values.</para>
+
+    <para>JDBC has an unfortunate limitation and does not include type codes
+    for SQL datetime types that have a TIME ZONE property. Therefore, for
+    compatibility with database tools that are limited to the JDBC type codes,
+    HyperSQL reports these types by default as datetime types without TIME
+    ZONE. You can use the URL property
+    <literal>hsqldb.translate_dti_types=false</literal> to override the
+    default behaviour.</para>
+  </section>
+
+  <section>
+    <title>Interval Types</title>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>INTERVAL types</primary>
+    </indexterm>
+
+    <para>Interval types are used to represent differences between date time
+    values. The difference between two date time values can be measured in
+    seconds or in months. For measurements in months, the units YEAR and MONTH
+    are available, while for measurements in seconds, the units DAY, HOUR,
+    MINUTE, SECOND are available. The units can be used individually, or as a
+    range. An interval type can specify the precision of the most significant
+    field and the second fraction digits of the SECOND field (if it has a
+    SECOND field). The default precision is 2. The default second precision is
+    0.</para>
+
+    <simpara><literal>&lt;interval type&gt; ::= INTERVAL &lt;interval
+    qualifier&gt;</literal></simpara>
+
+    <simpara><literal>&lt;interval qualifier&gt; ::= &lt;start field&gt; TO
+    &lt;end field&gt; | &lt;single datetime field&gt;</literal></simpara>
+
+    <simpara><literal>&lt;start field&gt; ::= &lt;non-second primary datetime
+    field&gt; [ &lt;left paren&gt; &lt;interval leading field precision&gt;
+    &lt;right paren&gt; ]</literal></simpara>
+
+    <simpara><literal>&lt;end field&gt; ::= &lt;non-second primary datetime
+    field&gt; | SECOND [ &lt;left paren&gt; &lt;interval fractional seconds
+    precision&gt; &lt;right paren&gt; ]</literal></simpara>
+
+    <simpara><literal>&lt;single datetime field&gt; ::= &lt;non-second primary
+    datetime field&gt; [ &lt;left paren&gt; &lt;interval leading field
+    precision&gt; &lt;right paren&gt; ] | SECOND [ &lt;left paren&gt;
+    &lt;interval leading field precision&gt; [ &lt;comma&gt; &lt;interval
+    fractional seconds precision&gt; ] &lt;right paren&gt;
+    ]</literal></simpara>
+
+    <simpara><literal>&lt;primary datetime field&gt; ::= &lt;non-second
+    primary datetime field&gt; | SECOND</literal></simpara>
+
+    <simpara><literal>&lt;non-second primary datetime field&gt; ::= YEAR |
+    MONTH | DAY | HOUR | MINUTE</literal></simpara>
+
+    <simpara><literal>&lt;interval fractional seconds precision&gt; ::=
+    &lt;unsigned integer&gt;</literal></simpara>
+
+    <simpara><literal>&lt;interval leading field precision&gt; ::=
+    &lt;unsigned integer&gt;</literal></simpara>
+
+    <para>Examples of INTERVAL type definition:</para>
+
+    <programlisting>INTERVAL YEAR TO MONTH
+INTERVAL YEAR(3)
+INTERVAL DAY(4) TO HOUR
+INTERVAL MINUTE(4) TO SECOND(6)
+INTERVAL SECOND(4,6)
+</programlisting>
+
+    <para>The word INTERVAL indicates the general type name. The rest of the
+    definition is called an <literal>&lt;interval qualifier&gt;</literal>.
+    This designation is important, as in most expressions
+    <literal>&lt;interval qualifier&gt;</literal> is used without the word
+    INTERVAL.</para>
+
+    <simpara><emphasis role="bold">Interval Values</emphasis></simpara>
+
+    <para>An interval value can be negative, positive or zero. An interval
+    type has all the datetime fields in the specified range. These fields are
+    similar to those in the TIMESTAMP type. The differences are as
+    follows:</para>
+
+    <para>The first field of an interval value can hold any numeric value up
+    to the specified precision. For example, the hour field in HOUR(2) TO
+    SECOND can hold values above 23 (up to 99). The year and month fields can
+    hold zero (unlike a TIMESTAMP value) and the maximum value of a month
+    field that is not the most significant field, is 11.</para>
+
+    <para>The standard function <literal>ABS(&lt;interval value
+    expression&gt;)</literal> can be used to convert a negative interval value
+    to a positive one.</para>
+
+    <para>The literal representation of interval values consists of the type
+    definition, with a string representing the interval value inserted after
+    the word INTERVAL. Some examples of interval literal below:</para>
+
+    <programlisting>INTERVAL '145 23:12:19.345' DAY(3) TO SECOND(3)
+INTERVAL '3503:12:19.345' HOUR TO SECOND(3) /* equal to the first value */
+INTERVAL '19.345' SECOND(4,3) /* maximum number of digits for the second value is 4, and each value is expressed with three fraction digits. */
+INTERVAL '-23-10' YEAR(2) TO MONTH
+</programlisting>
+
+    <para>Interval values of the types that are based on seconds can be cast
+    into one another. Similarly those that are based on months can be cast
+    into one another. It is not possible to cast or convert a value based on
+    seconds to one based on months, or vice versa.</para>
+
+    <para>When a cast is performed to a type with a smaller least-significant
+    field, nothing is lost from the interval value. Otherwise, the values for
+    the missing least-significant fields are discarded. Examples:</para>
+
+    <programlisting>CAST ( INTERVAL '145 23:12:19' DAY TO SECOND AS INTERVAL DAY TO HOUR ) = INTERVAL '145 23' DAY TO HOUR
+CAST(INTERVAL '145 23' DAY TO HOUR AS INTERVAL DAY TO SECOND) = INTERVAL '145 23:00:00' DAY TO SECOND
+</programlisting>
+
+    <para>A numeric value can be cast to an interval type. In this case the
+    numeric value is first converted to a single-field INTERVAL type with the
+    same field as the least significant field of the target interval type.
+    This value is then converted to the target interval type For example CAST(
+    22 AS INTERVAL YEAR TO MONTH) evaluates to INTERVAL '22' MONTH and then
+    INTERVAL '1 10' YEAR TO MONTH. Note that SQL Standard only supports casts
+    to single-field INTERVAL types, while HyperSQL allows casting to
+    multi-field types as well.</para>
+
+    <para>An interval value can be cast to a numeric type. In this case the
+    interval value is first converted to a single-field INTERVAL type with the
+    same field as the least significant filed of the interval value. The value
+    is then converted to the target type. For example CAST (INTERVAL '1-11'
+    YEAR TO MONTH AS INT) evaluates to INTERVAL '23' MONTH, and then
+    23.</para>
+
+    <para>An interval value can be cast into a character type, which results
+    in an INTERVAL literal. A character value can be cast into an INTERVAL
+    type so long as it is a string with a format compatible with an INTERVAL
+    literal.</para>
+
+    <para>Two interval values can be added or subtracted so long as the types
+    of both are based on the same field, i.e., both are based on MONTH or
+    SECOND. The values are both converted to a single-field interval type with
+    same field as the least-significant field between the two types. After
+    addition or subtraction, the result is converted to an interval type that
+    contains all the fields of the two original types.</para>
+
+    <para>An interval value can be multiplied or divided by a numeric value.
+    Again, the value is converted to a numeric, which is then multiplied or
+    divided, before converting back to the original interval type.</para>
+
+    <para>An interval value is negated by simply prefixing with the minus
+    sign.</para>
+
+    <para>Interval values used in expressions are either typed values,
+    including interval literals, or are interval casts. The expression:
+    <literal>&lt;expression&gt; &lt;interval qualifier&gt;</literal> is a cast
+    of the result of the <literal>&lt;expression&gt;</literal> into the
+    INTERVAL type specified by the <literal>&lt;interval qualifier&gt;. The
+    cast can be formed by adding the keywords and parentheses as follows: CAST
+    ( &lt;expression&gt; AS INTERVAL &lt;interval qualifier&gt;
+    ).</literal></para>
+
+    <para><literal>The examples below feature different forms of expression
+    that represent an interval value, which is then added to the given date
+    literal.</literal></para>
+
+    <programlisting>DATE '2000-01-01' + INTERVAL '1-10' YEAR TO MONTH /* interval literal */
+DATE '2000-01-01' + '1-10' YEAR TO MONTH /* the string '1-10' is cast into INTERVAL YEAR TO MONTH */
+DATE '2000-01-01' + 22 MONTH /* the integer 22 is cast into INTERVAL MONTH, same value as above */
+DATE '2000-01-01' - 22 DAY /* the integer 22 is cast into INTERVAL DAY */
+DATE '2000-01-01' + COL2 /* the type of COL2 must be an INTERVAL type */
+DATE '2000-01-01' + COL2 MONTH /* COL2 may be a number, it is cast into a MONTH interval */
+</programlisting>
+
+    <simpara><emphasis role="bold">Datetime and Interval
+    Operations</emphasis></simpara>
+
+    <para>An interval can be added to or subtracted from a datetime value so
+    long as they have some fields in common. For example, an INTERVAL MONTH
+    cannot be added to a TIME value, while an INTERVAL HOUR TO SECOND can. The
+    interval is first converted to a numeric value, then the value is added
+    to, or subtracted from, the corresponding field of the datetime
+    value.</para>
+
+    <para>If the result of addition or subtraction is beyond the permissible
+    range for the field, the field value is normalised and carried over to the
+    next significant field until all the fields are normalised. For example,
+    adding 20 minutes to TIME '23:50:10' will result successively in
+    '23:70:10', '24:10:10' and finally TIME '00:10:10'. Subtracting 20 minutes
+    from the result is performed as follows: '00:-10:10', '-1:50:10', finally
+    TIME '23:50:10'. Note that if DATE or TIMESTAMP normalisation results in
+    the YEAR field value out of the range (1,1000), then an exception
+    condition is raised.</para>
+
+    <para>If an interval value based on MONTH is added to, or subtracted from
+    a DATE or TIMESTAMP value, the result may have an invalid day (30 or 31)
+    for the given result month. In this case an exception condition is
+    raised.</para>
+
+    <para>The result of subtraction of two datetime expressions is an interval
+    value. The two datetime expressions must be of the same type. The type of
+    the interval value must be specified in the expression, using only the
+    interval field names. The two datetime expressions are enclosed in
+    parentheses, followed by the <literal>&lt;interval qualifier&gt;</literal>
+    fields. In the first example below, COL1 and COL2 are of the same datetime
+    type, and the result is evaluated in INTERVAL YEAR TO MONTH type.</para>
+
+    <programlisting>(COL1 – COL2) YEAR TO MONTH /* the difference between two DATE or two TIEMSTAMP values in years and months */
+(CURRENT_DATE – COL3) DAY /* the number of days between the value of COL3 and the current date */
+(CURRENT_DATE - DATE '2000-01-01') YEAR TO MONTH /* the number of years and months since the beginning of this century */
+CURRENT_DATE - 2 DAY /* the date of the day before yesterday */
+(CURRENT_TIMESTAMP - TIMESTAMP '2009-01-01 00:00:00') DAY(4) TO SECOND(2) /* days to seconds since the given date */
+</programlisting>
+
+    <para>The individual fields of both datetime and interval values can be
+    extracted using the EXTRACT function. The same function can also be used
+    to extract the time zone displacement fields of a datetime value.</para>
+
+    <simpara><literal>EXTRACT ({YEAR | MONTH | DAY | HOUR | MINUTE | SECOND |
+    TIMEZONE_HOUR | TIMEZONE_MINUTE | DAY_OF_WEEK | WEEK_OF_YEAR } FROM
+    {&lt;datetime value&gt; | &lt;interval value&gt;})</literal></simpara>
+
+    <para>The dichotomy between interval types based on seconds, and those
+    based on months, stems from the fact that the different calendar months
+    have different numbers of days. For example, the expression, “nine months
+    and nine days since an event” is not exact when the date of the event is
+    unknown. It can represent a period of around 284 days give or take one.
+    SQL interval values are independent of any start or end dates or times.
+    However, when they are added to or subtracted from certain date or
+    timestamp values, the result may be invalid and cause an exception (e.g.
+    adding one month to January 30 results in February 30, which is
+    invalid).</para>
+
+    <para>JDBC has an unfortunate limitation and does not include type codes
+    for SQL INTERVAL types. Therefore, for compatibility with database tools
+    that are limited to the JDBC type codes, HyperSQL reports these types by
+    default as VARCHAR. You can use the URL property
+    <literal>hsqldb.translate_dti_types=false</literal> to override the
+    default behaviour.</para>
+  </section>
+
+  <section>
+    <title>Arrays</title>
+
+    <para>Array are a powerful feature of SQL:2008 and can help solve many
+    common problems. Arrays should not be used as a substitute for
+    tables.</para>
+
+    <para>HyperSQL supports arrays of values according to the SQL:2008
+    Standard.</para>
+
+    <para>Elements of the array are either NULL, or of the same data type. It
+    is possible to define arrays of all supported types, including the types
+    covered in this chapter and user defined types, except LOB types. An SQL
+    array is one dimensional and is addressed from position 1. An empty array
+    can also be used, which has no element.</para>
+
+    <para>Arrays can be stored in the database, as well as being used as
+    temporary containers of values for simplifying SQL statements. They
+    facilitate data exchange between the SQL engine and the user's
+    application.</para>
+
+    <para>The full range of supported syntax allows array to be created, used
+    in SELECT or other statements, combined with rows of tables and used in
+    routine calls.</para>
+
+    <section>
+      <title>Array Definition</title>
+
+      <para>The type of a table column, a routine parameter, a variable, or
+      the return value of a function can be defined as an array.</para>
+
+      <para><literal>&lt;array type&gt; ::= &lt;data type&gt; ARRAY [ &lt;left
+      bracket or trigraph&gt; &lt;maximum cardinality&gt; &lt;right bracket or
+      trigraph&gt; ]</literal></para>
+
+      <para>The word ARRAY is added to any valid type definition except BLOB
+      and CLOB type definitions. If the optional <literal>&lt;maximum
+      cardinality&gt;</literal> is not used, the default value is 1024. The
+      size of the array cannot be extended beyond maximum cardinality.</para>
+
+      <para>In the example below, the table contains a column of integer
+      arrays and a column of varchar arrays. The VARCHAR array has an explicit
+      maximum size of 10, which means each array can have between 0 and 10
+      elements. The INTEGER array has the default maximum size of 1024. The id
+      column has a default clause with an empty array. The default clause can
+      be defined only as DEFAULT NULL or DEFAULT ARRAY[] and does not allow
+      arrays containing elements.</para>
+
+      <informalexample>
+        <programlisting>CREATE TABLE t (id INT PRIMARY KEY, scores INT ARRAY DEFAULT ARRAY[], names VARCHAR(20) ARRAY[10])</programlisting>
+      </informalexample>
+
+      <para>An array can be constructed from value expressions or a query
+      expression.</para>
+
+      <para><literal>&lt;array value constructor by enumeration&gt; ::= ARRAY
+      &lt;left bracket or trigraph&gt; &lt;array element list&gt; &lt;right
+      bracket or trigraph&gt;</literal></para>
+
+      <para><literal>&lt;array element list&gt; ::= &lt;value expression&gt; [
+      { &lt;comma&gt; &lt;value expression&gt; }... ]</literal></para>
+
+      <para><literal>&lt;array value constructor by query&gt; ::= ARRAY
+      &lt;left paren&gt; &lt;query expression&gt; [ &lt;order by clause&gt; ]
+      &lt;right paren&gt;</literal></para>
+
+      <para>In the examples below, arrays are constructed from values, column
+      references or variables, function calls, or query expressions.</para>
+
+      <informalexample>
+        <programlisting>ARRAY [ 1, 2, 3 ]
+ARRAY [ 'HOT', 'COLD' ]
+ARRAY [ var1, var2, CURRENT_DATE ]
+ARRAY (SELECT lastname FROM namestable ORDER BY id)
+</programlisting>
+      </informalexample>
+
+      <para></para>
+    </section>
+
+    <section>
+      <title>Array Reference</title>
+
+      <para>The most common operations on an array element reference and
+      assignment, which are used when reading or writing an element of the
+      array. Unlike Java and many other languages, arrays are extended if an
+      element is assigned to an index beyond the current length. This can
+      result in gaps containing NULL elements. Array length cannot exceed the
+      maximum cardinality.</para>
+
+      <para>Elements of all arrays, including those that are the result of
+      function calls or other operations can be referenced for reading.</para>
+
+      <para><literal>&lt;array element reference&gt; ::= &lt;array value
+      expression&gt; &lt;left bracket&gt; &lt;numeric value expression&gt;
+      &lt;right bracket&gt;</literal></para>
+
+      <para>Elements of arrays that are table columns or routine variables can
+      be referenced for writing. This is done in a SET statement, either
+      inside an UPDATE statement, or as a separate statement in the case of
+      routine variables, OUT and INOUT parameters.</para>
+
+      <para><literal>&lt;target array element specification&gt; ::= &lt;target
+      array reference&gt; &lt;left bracket or trigraph&gt; &lt;simple value
+      specification&gt; &lt;right bracket or trigraph&gt;</literal></para>
+
+      <para><literal>&lt;target array reference&gt; ::= &lt;SQL parameter
+      reference&gt; | &lt;column reference&gt;</literal></para>
+
+      <para>Note that only simple values or variables are allowed for the
+      array index when an assignment is performed. The examples below
+      demonstrates how elements of the array are referenced in SELECT and an
+      UPDATE statement.</para>
+
+      <para><informalexample>
+          <programlisting>SELECT scores[ranking], names[ranking] FROM t JOIN t1 on (t.id = t1.tid)
+UPDATE t SET scores[2] = 123, names[2] = 'Reds' WHERE id = 10
+</programlisting>
+        </informalexample></para>
+
+      <para></para>
+    </section>
+
+    <section>
+      <title>Array Operations</title>
+
+      <para>Several SQL operations and functions can be used with
+      arrays.</para>
+
+      <para><emphasis>CONCATENATION</emphasis></para>
+
+      <para>Array concatenation is performed similar to string concatenation.
+      All elements of the array on the right are appended to the array on
+      left.</para>
+
+      <para><literal>&lt;array concatenation&gt; ::= &lt;array value
+      expression 1&gt; &lt;concatenation operator&gt; &lt;array value
+      expression 2&gt;</literal></para>
+
+      <para><literal>&lt;concatenation operator&gt; ::= ||</literal></para>
+
+      <para><emphasis>FUNCTIONS</emphasis></para>
+
+      <para>Three functions operate on arrays. Details are described in the
+      <link endterm="builtinfunctions-title"
+      xlink:href="#builtinfunctions-chapt"></link> chapter.</para>
+
+      <para><literal>CARDINALITY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;right paren&gt;</literal></para>
+
+      <para><literal>MAX_CARDINALITY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;right paren&gt;</literal></para>
+
+      <para>Array cardinality and max cardinality are functions that return an
+      integer. CARDINALITY returns the element count, while MAX_CARDINALITY
+      returns the maximum declared cardinality of an array.</para>
+
+      <para><literal>TRIM_ARRAY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;comma&gt; &lt;numeric value expression&gt; &lt;right
+      paren&gt;</literal></para>
+
+      <para>The TRIM_ARRAY function returns a copy of an array with the
+      specified number of elements removed from the end of the array. The
+      <literal>&lt;array value expression&gt;</literal> can be any expression
+      that evaluates to an array.</para>
+
+      <para><emphasis>CAST</emphasis></para>
+
+      <para>An array can be cast into an array of a different type. Each
+      element of the array is cast into the element type of the target array
+      type.</para>
+
+      <para><emphasis>UNNEST</emphasis></para>
+
+      <para>Arrays can be converted into table references with the UNNEST
+      keyword.</para>
+
+      <para><literal>UNNEST(&lt;array value expression&gt;) [ WITH ORDINALITY
+      ]</literal></para>
+
+      <para>The <literal>&lt;array value expression&gt;</literal> can be any
+      expression that evaluates to an array. A table is returned that contains
+      one column when WITH ORDINALITY is not used, or two columns when WITH
+      ORDINALITY is used. The first column contains the elements of the array
+      (including all the nulls). When the table has two columns, the second
+      column contains the ordinal position of the element in the array. When
+      UNNEST is used in the FROM clause of a query, it implies the LATERAL
+      keyword, which means the array that is converted to table can belong to
+      any table that precedes the UNNEST in the FROM clause. This is explained
+      in the <link endterm="dataaccess-title" xlink:arcrole=""
+      xlink:href="#dataaccess-chapt"></link> chapter.</para>
+
+      <para><emphasis>COMPARISON</emphasis></para>
+
+      <para>Arrays can be compared for equality, but they cannot be compared
+      for ordering or ranges. Array expressions are therefore not allowed in
+      an ORDER BY clause, or in a comparison expression such as GREATER THAN.
+      Two arrays are equal if they have the same length and the values at each
+      index position are either equal or both NULL.</para>
+
+      <para><emphasis>USER DEFINED FUNCTIONS and PROCEDURES</emphasis></para>
+
+      <para>Array parameters, variables and return values can be specified in
+      user defined functions and procedures, including aggregate functions. An
+      aggregate function can return an array that contains all the scalar
+      values that have been aggregated. These capabilities allow a wider range
+      of applications to be covered by user defined functions and easier data
+      exchange between the engine and the user's application.</para>
+    </section>
+  </section>
+
+  <section xml:id="sqlgeneral_constr_indexes-sect">
+    <title>Indexes and Query Speed</title>
+
+    <para>HyperSQL supports PRIMARY KEY, UNIQUE and FOREIGN KEY constraints,
+    which can span multiple columns.</para>
+
+    <para>The engine creates indexes internally to support PRIMARY KEY, UNIQUE
+    and FOREIGN KEY constraints: a unique index is created for each PRIMARY
+    KEY or UNIQUE constraint; an ordinary index is created for each FOREIGN
+    KEY constraint.</para>
+
+    <para>HyperSQL allows defining indexes on single or multiple columns. You
+    should not create duplicate user-defined indexes on the same column sets
+    covered by constraints. This would result in unnecessary memory and speed
+    overheads. See the discussion in the <link endterm="deployment-title"
+    xlink:arcrole="" xlink:href="#deployment-chapt"></link> chapter for more
+    information.</para>
+
+    <para>Indexes are crucial for adequate query speed. When range or equality
+    conditions are used e.g. <literal>SELECT ... WHERE acol &gt; 10 AND bcol =
+    0</literal>, an index should exist on one of the columns that has a
+    condition. In this example, the <literal>bcol</literal> column is the best
+    candidate. HyperSQL always uses the best condition and index. If there are
+    two indexes, one on acol, and another on bcol, it will choose the index on
+    bcol.</para>
+
+    <para>Queries always return results whether indexes exist or not, but they
+    return much faster when an index exists. As a rule of thumb, HSQLDB is
+    capable of internal processing of queries at over 100,000 rows per second.
+    Any query that runs into several seconds is clearly accessing thousands of
+    rows. The query should be checked and indexes should be added to the
+    relevant columns of the tables if necessary. The EXPLAIN PLAN
+    &lt;query&gt; statement can be used to see which indexes are used to
+    process the query.</para>
+
+    <para>When executing a DELETE or UPDATE statement, the engine needs to
+    find the rows that are to be deleted or updated. If there is an index on
+    one of the columns in the WHERE clause, it is often possible to start
+    directly from the first candidate row. Otherwise all the rows of the table
+    have to be examined.</para>
+
+    <para>Indexes are even more important in joins between multiple tables.
+    <literal>SELECT ... FROM t1 JOIN t2 ON t1.c1 = t2.c2 </literal> is
+    performed by taking rows of t1 one by one and finding a matching row in
+    t2. If there is no index on t2.c2 then for each row of t1, all the rows of
+    t2 must be checked. Whereas with an index, a matching row can be found in
+    a fraction of the time. If the query also has a condition on t1, e.g.,
+    <literal>SELECT ... FROM t1 JOIN t2 ON t1.c1 = t2.c2 WHERE t1.c3 =
+    4</literal> then an index on t1.c3 would eliminate the need for checking
+    all the rows of t1 one by one, and will reduce query time to less than a
+    millisecond per returned row. So if t1 and t2 each contain 10,000 rows,
+    the query without indexes involves checking 100,000,000 row combinations.
+    With an index on t2.c2, this is reduced to 10,000 row checks and index
+    lookups. With the additional index on t2.c2, only about 4 rows are checked
+    to get the first result row.</para>
+
+    <para>Note that in HSQLDB an index on multiple columns can be used
+    internally as a non-unique index on the first column in the list. For
+    example: <literal>CONSTRAINT name1 UNIQUE (c1, c2, c3); </literal> means
+    there is the equivalent of <literal>CREATE INDEX name2 ON
+    atable(c1);</literal>. So you do not need to specify an extra index if you
+    require one on the first column of the list.</para>
+
+    <para>In HyperSQL 2.0, a multi-column index will speed up queries that
+    contain joins or values on the first n columns of the index. You need NOT
+    declare additional individual indexes on those columns unless you use
+    queries that search only on a subset of the columns. For example, rows of
+    a table that has a PRIMARY KEY or UNIQUE constraint on three columns or
+    simply an ordinary index on those columns can be found efficiently when
+    values for all three columns, or the first two columns, or the first
+    column, are specified in the WHERE clause. For example, <literal>SELECT
+    ... FROM t1 WHERE t1.c1 = 4 AND t1.c2 = 6 AND t1.c3 = 8 </literal>will use
+    an index on <literal>t1(c1,c2,c3)</literal> if it exists.</para>
+
+    <para>A multi-column index will not speed up queries on the second or
+    third column only. The first column must be specified in the JOIN .. ON or
+    WHERE conditions.</para>
+
+    <para>Sometimes query speed depends on the order of the tables in the JOIN
+    .. ON or FROM clauses. For example the second query below should be faster
+    with large tables (provided there is an index on
+    <literal>TB.COL3</literal>). The reason is that <literal>TB.COL3</literal>
+    can be evaluated very quickly if it applies to the first table (and there
+    is an index on <literal>TB.COL3</literal>):</para>
+
+    <informalexample>
+      <programlisting>    (TB is a very large table with only a few rows where TB.COL3 = 4)
+
+    SELECT * FROM TA JOIN TB ON TA.COL1 = TB.COL2 AND TB.COL3 = 4;
+
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 AND TB.COL3 = 4;</programlisting>
+    </informalexample>
+
+    <para>The general rule is to put first the table that has a narrowing
+    condition on one of its columns.</para>
+
+    <para>HyperSQL features automatic, on-the-fly indexes for views and
+    subselects that are used in a query.</para>
+
+    <para>Indexes have no effect on some LIKE conditions.</para>
+
+    <para>Indexes are used for ORDER BY clauses if the same index is used for
+    selection and ordering of rows.</para>
+  </section>
+
+  <section>
+    <title>Query Processing and Optimisation</title>
+
+    <para>HyperSQL does not change the order of tables in a query in order to
+    optimise processing. As mentioned in the previous section, the table that
+    has a narrowing condition should be the first table in the query.</para>
+
+    <para>HyperSQL optimises queries to use indexes, for all types of range
+    and equality conditions, including IS NULL and NOT NULL conditions.
+    Conditions can be in join or WHERE clauses, including all types of
+    joins.</para>
+
+    <para>In addition, HyperSQL will always use an index (if one exists) for
+    IN conditions, whether constants, variable, or subqueries are used on the
+    right hand side of the IN predicate.</para>
+
+    <para>HyperSQL can always use indexes when several conditions are combined
+    with the AND operator, choosing a conditions which can use an index. This
+    now extended to all equality conditions on multiple columns that are part
+    of an index.</para>
+
+    <para>HyperSQL will also use indexes when several conditions are combined
+    with the OR operator and each condition can use an index (each condition
+    may use a different index). For example, if a huge table has two separate
+    columns for first name and last name, and both columns are indexed, a
+    query such as the following example will use the indexes and complete in a
+    short time:</para>
+
+    <informalexample>
+      <programlisting>    (TC is a very large table)
+
+    SELECT * FROM TC WHERE TC.FIRSTNAME = 'John' OR TC.LASTNAME = 'Smith' OR TC.LASTNAME = 'Williams'
+</programlisting>
+    </informalexample>
+
+    <para>HyperSQL optimises simple row count queries in the form of SELECT
+    COUNT(*) FROM &lt;table&gt; and returns the result immediately (this
+    optimisation does not take place in MVCC mode).</para>
+
+    <para>HyperSQL can use an index on a column for SELECT MAX(&lt;column&gt;)
+    FROM &lt;table&gt; and SELECT MIN(&lt;column&gt;) FROM &lt;table&gt;
+    queries. There should be an index on the &lt;column&gt; and the query can
+    have a WHERE condition on the same column. In the example below the
+    maximum value for the TB.COL3 below 1000000 is returned.</para>
+
+    <informalexample>
+      <programlisting>    SELECT MAX(TB.COL3) FROM TB WHERE TB.COL &lt; 1000000
+</programlisting>
+    </informalexample>
+
+    <para>HyperSQL can use an index on an ORDER BY clause if all the columns
+    in ORDER BY are in a single-column or multi-column index (in the exact
+    order). This is important if there is a LIMIT n (or FETCH n ROWS ONLY)
+    clause. In this situation, the use of index allows the query processor to
+    access only the number of rows specified in the LIMIT clause, instead of
+    building the whole result set, which can be huge. This also works for
+    joined tables when the ORDER BY clause is on the columns of the first
+    table in a join. Indexes are used in the same way when ORDER BY ... DESC
+    is specified in the query. Note that unlike other RDBMS, HyperSQL does not
+    create DESC indexes. It can use any index for ORDER BY ... DESC.</para>
+
+    <para>If there is an equality or range condition (e.g. EQUALS, GREATER
+    THAN) condition on the columns specified in the ORDER BY clause, the index
+    is still used. But if the query contains an equality condition on another
+    indexed column in the table, this may take precedence and no index may be
+    used for ORDER BY.</para>
+
+    <para>In the two examples below, the index on TB.COL3 is used and only up
+    to 1000 rows are processed and returned.</para>
+
+    <informalexample>
+      <programlisting>    (TB is a very large table with an index on TB.COL3
+
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 WHERE TB.COL3 &gt; 40000 ORDER BY TB.COL3 LIMIT 1000;
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 WHERE TB.COL3 &gt; 40000 AND TB.COL3 &lt; 100000 ORDER BY TB.COL3 DESC LIMIT 1000;
+</programlisting>
+    </informalexample>
+  </section>
+</chapter>
diff --git a/doc-src/guide/sqlroutines.xml b/doc-src/guide/sqlroutines.xml
new file mode 100644
index 0000000..561e9cd
--- /dev/null
+++ b/doc-src/guide/sqlroutines.xml
@@ -0,0 +1,1611 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="sqlroutines-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns6="http://www.w3.org/1999/xlink"
+         xmlns:ns5="http://www.w3.org/2000/svg"
+         xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="sqlroutines-title">SQL-Invoked Routines</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3643 $</releaseinfo>
+
+    <pubdate>$Date: 2010-06-06 23:04:17 -0400 (Sun, 06 Jun 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <para>SQL-invoked routines are functions and procedures called from SQL.
+  HyperSQL 2.0 supports routines conforming to two parts of the SQL Standard.
+  Routines written in the SQL language are supported in conformance to SQL/PSM
+  (Persistent Stored Modules) specification. Routines written in Java are
+  supported in (loose) conformance to SQL/JRT specification. In addition,
+  HyperSQL’s previous non-standard support for calling Java routines without
+  prior method definition is retained and enhanced in the latest version by
+  extending the SQL/JRT specification.</para>
+
+  <para>HyperSQL also supports user defined aggregate functions written in the
+  SQL language. This feature is an extension to the SQL Standard.</para>
+
+  <para>SQL-invoked routines are schema objects. Naming and referencing
+  follows conventions common to all schema objects. The same routine name can
+  be defined in two different schemas and used with schema-qualified
+  references.</para>
+
+  <para>A routine is either a procedure or a function.</para>
+
+  <para>A function:</para>
+
+  <itemizedlist>
+    <listitem>
+      <para>is defined with CREATE FUNCTION</para>
+    </listitem>
+
+    <listitem>
+      <para>always returns a value</para>
+    </listitem>
+
+    <listitem>
+      <para>does not modify the data in the database</para>
+    </listitem>
+
+    <listitem>
+      <para>is called as part of an SQL statement</para>
+    </listitem>
+
+    <listitem>
+      <para>can have parameters</para>
+    </listitem>
+
+    <listitem>
+      <para>can be polymorphic</para>
+    </listitem>
+  </itemizedlist>
+
+  <para>A procedure:</para>
+
+  <itemizedlist>
+    <listitem>
+      <para>is defined with CREATE PROCEDURE</para>
+    </listitem>
+
+    <listitem>
+      <para>can return one or more values</para>
+    </listitem>
+
+    <listitem>
+      <para>can modify the data in the database</para>
+    </listitem>
+
+    <listitem>
+      <para>is called separately, using the CALL statement</para>
+    </listitem>
+
+    <listitem>
+      <para>can have parameters</para>
+    </listitem>
+
+    <listitem>
+      <para>can be polymorphic</para>
+    </listitem>
+  </itemizedlist>
+
+  <para>Definition of routine signature and characteristics, name resolution
+  and invocation are all implemented uniformly for routines written in SQL or
+  Java.</para>
+
+  <section>
+    <title>SQL Language Routines (PSM)</title>
+
+    <para>The PSM (Persistent Stored Module) specification extends the SQL
+    language to allow definition of both SQL Function and SQL procedure bodies
+    with the same structure and the same control statements (such as
+    conditional and loop statements) with minor exceptions.</para>
+
+    <para>The routine body is a SQL statement. In its simplest form, the body
+    is a single SQL statement. A simple example of a function is given
+    below:</para>
+
+    <programlisting>CREATE FUNCTION an_hour_before (t TIMESTAMP)
+  RETURNS TIMESTAMP
+  RETURN t - 1 HOUR
+
+</programlisting>
+
+    <para>An example of the use of the function in an SQL statement is given
+    below:</para>
+
+    <programlisting>SELECT an_hour_before(event_timestamp) AS notification_timestamp, event_name FROM events;</programlisting>
+
+    <para>A simple example of a procedure is given below:</para>
+
+    <programlisting>CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname VARCHAR(50))
+  MODIFIES SQL DATA
+  INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP)
+
+</programlisting>
+
+    <para>The procedure inserts a row into an existing table with the
+    definition given below:</para>
+
+    <programlisting>CREATE TABLE customers(id INTEGER GENERATED BY DEFAULT AS IDENTITY, firstname VARCHAR(50), lastname VARCHAR(50), added TIMESTAMP);</programlisting>
+
+    <para>An example of the use of the procedure is given below:</para>
+
+    <programlisting>CALL new_customer('JOHN', 'SMITH');</programlisting>
+
+    <para>The routine body is often a compound statement. A compound statement
+    can contain one or more SQL statements, which can include control
+    statements, as well as nested compound statements.</para>
+
+    <section>
+      <title>Routine Statements</title>
+
+      <para>The following SQL Statements can be used only in routines.</para>
+
+      <simpara><literal>&lt;handler declaration&gt;</literal></simpara>
+
+      <simpara><literal>&lt;assignment statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;compound statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;case statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;if statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;while statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;repeat statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;for statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;loop statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;iterate statement</literal></simpara>
+
+      <simpara><literal>&lt;leave statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;signal statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;resignal statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;return statement&gt;</literal></simpara>
+
+      <simpara><literal>&lt;select statement: single
+      row&gt;</literal></simpara>
+
+      <para>The following SQL Statements can be used in procedures but not in
+      functions.</para>
+
+      <para><literal>&lt;call statement&gt;</literal></para>
+
+      <para><literal>&lt;delete statement&gt;</literal></para>
+
+      <para><literal>&lt;insert statement&gt;</literal></para>
+
+      <para><literal>&lt;update statement&gt;</literal></para>
+
+      <para><literal>&lt;merge statement&gt;</literal></para>
+
+      <para>As shown in the examples below, the formal parameters and the
+      variables of the routine can be used in statements, similar to the way a
+      column reference is used.</para>
+    </section>
+
+    <section>
+      <title>Compound Statement</title>
+
+      <para>A compound statement is enclosed in a BEGIN / END block with
+      optional labels. It can contain one or more <literal>&lt;SQL variable
+      declaration&gt;</literal> or <literal>&lt;handler
+      declaration&gt;</literal> before at least one SQL statement. The BNF is
+      given below:</para>
+
+      <simpara><literal>&lt;compound statement&gt; ::= [ &lt;beginning
+      label&gt; &lt;colon&gt; ] BEGIN [[NOT] ATOMIC] [{&lt;SQL variable
+      declaration&gt; &lt;semicolon&gt;} ...] [{&lt;handler declaration&gt;
+      &lt;semicolon&gt;}...] {&lt;SQL procedure statement&gt;
+      &lt;semicolon&gt;} ... END [ &lt;ending label&gt; ]</literal></simpara>
+
+      <para>An example of a simple compound statement body is given below. It
+      performs the common task of inserting related data into two table. The
+      IDENTITY value that is automatically inserted in the first table is
+      retrieved using the IDENTITY() function and inserted into the second
+      table.</para>
+
+      <programlisting>CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname  VARCHAR(50), address VARCHAR(100))
+  MODIFIES SQL DATA
+    BEGIN ATOMIC
+    INSERT INTO customers VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    INSERT INTO addresses VALUES (DEFAULT, IDENTITY(), address);
+  END
+
+</programlisting>
+    </section>
+
+    <section>
+      <title>Variables</title>
+
+      <para>A <literal>&lt;variable declaration&gt;</literal> defines the name
+      and data type of the variable and, optionally, its default value. In the
+      next example, a variable is used to hold the IDENTITY value. In
+      addition, the formal parameters of the procedure are identified as input
+      parameters with the use of the optional IN keyword. This procedure does
+      exactly the same job as the procedure in the previous example.</para>
+
+      <programlisting>CREATE PROCEDURE new_customer(IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+  MODIFIES SQL DATA
+  BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+  END
+
+</programlisting>
+
+      <para>The BNF for variable declaration is given below:</para>
+
+      <simpara><literal>&lt;SQL variable declaration&gt; ::= DECLARE
+      &lt;variable name list&gt; &lt;data type&gt; [DEFAULT &lt;default
+      value&gt;]</literal></simpara>
+
+      <simpara><literal>&lt;variable name list&gt; ::= &lt;variable name&gt; [
+      { &lt;comma&gt; &lt;variable name&gt; }... ]</literal></simpara>
+
+      <para>Examples of variable declaration are given below. Note that in a
+      DECLARE statement with multiple comma-separated variable names, the type
+      and the default value applies to all the variables in the list:</para>
+
+      <programlisting>  BEGIN ATOMIC
+    DECLARE temp_zero DATE;
+    DECLARE temp_one, temp_two INTEGER DEFAULT 2;
+    DECLARE temp_three VARCHAR(20) DEFAULT 'no name';
+    -- more statements ...
+    SET temp_zero = DATE '2010-03-18';
+    SET temp_two = 5;
+    -- more statements ...
+  END</programlisting>
+    </section>
+
+    <section>
+      <title>Handlers</title>
+
+      <para>A <literal>&lt;handler declaration&gt;</literal> defines the
+      course of action when an exception or warning is raised during the
+      execution of the compound statement. A compound statement may have one
+      or more handler declarations. These handlers become active when code
+      execution enters the compound statement block and remain active in any
+      sub-block and statement within the block. The handlers become inactive
+      when code execution leaves the block.</para>
+
+      <para>In the previous example, if an exception is thrown during the
+      execution of either SQL statement, the execution of the compound
+      statement is terminated and the exception is propagated and thrown by
+      the CALL statement for the procedure. A handler declaration can resolve
+      the thrown exception within the compound statement without propagating
+      it, and allow the execution of the &lt;compound statement&gt; to
+      continue.</para>
+
+      <para>In the example below, the UNDO handler declaration catches any
+      exception that is thrown during the execution of the compound statement
+      inside the BEGIN / END block. As it is an UNDO handler, all the changes
+      to data performed within the compound statement (BEGIN / END) block are
+      rolled back. The procedure then returns without throwing an
+      exception.</para>
+
+      <programlisting>CREATE PROCEDURE NEW_CUSTOMER(IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+    MODIFIES SQL DATA
+  label_one: BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    DECLARE UNDO HANDLER FOR SQLEXCEPTION LEAVE label_one;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+  END
+
+</programlisting>
+
+      <para>Other types of hander are CONTINUE and EXIT handlers. A CONTINUE
+      handler ignores any exception and proceeds to the next statement in the
+      block. An EXIT handler terminates execution without undoing the data
+      changes performed by the previous (successful) statements.</para>
+
+      <para>The conditions can be general conditions, or specific conditions.
+      Among general conditions that can be specified, SQLEXCEPTION covers all
+      exceptions, SQLWARNING covers all warnings, while NOT FOUND covers the
+      not-found condition, which is raised when a DELETE, UPDATE, INSERT or
+      MERGE statement completes without actually affecting any row.
+      Alternatively, one or more specific conditions can be specified
+      (separated with commas) which apply to specific exceptions or warnings
+      or classes or exceptions or warnings. A specific condition is specified
+      with <literal>SQLSTATE &lt;value&gt;</literal>, for example SQLSTATE
+      'W_01003' specifies the warning raised after a SQL statement is executed
+      which contains an aggregate function which encounters a null value
+      during execution. An example is given below which activates the handler
+      when either of the two warnings is raised:</para>
+
+      <programlisting>DECLARE UNDO HANDLER FOR SQLSTATE 'W_01003', 'W_01004' LEAVE label_one;</programlisting>
+
+      <para>The BNF for <literal>&lt;handler declaration&gt;</literal> is
+      given below:</para>
+
+      <simpara><literal>&lt;handler declaration&gt; ::= DECLARE {UNDO |
+      CONTINUE | EXIT} HANDLER FOR {SQLEXCEPTION | SQLWARNING | NOT FOUND} | {
+      SQL_STATE &lt;state value&gt; [, ...]} [&lt;SQL procedure
+      statement&gt;];</literal></simpara>
+
+      <para>A handler declaration may specify an SQL procedure statement to be
+      performed when the handler is activated. When an exception occurs, the
+      example below performs the UNDO as in the previous example, then inserts
+      the (invalid) data into a separate table.</para>
+
+      <programlisting>DECLARE UNDO HANDLER FOR SQLEXCEPTION
+    INSERT INTO invalid_customers VALUES(firstanme, lastname, address);</programlisting>
+
+      <para>The <literal>&lt;SQL procedure statement&gt;</literal> is required
+      by the SQL Standard but is optional in HyperSQL. If the execution of the
+      <literal>&lt;SQL procedure statement&gt;</literal> specified in the
+      handler declaration throws an exception itself, then it is handled by
+      the handlers that are currently active. The <literal>&lt;SQL procedure
+      statement&gt;</literal> can itself be a compound statement with its own
+      handlers.</para>
+    </section>
+
+    <section>
+      <title>Assignment Statement</title>
+
+      <para>The SET statement is used for assignment. It can be used flexibly
+      with rows or single values. The BNF is given below:</para>
+
+      <simpara><literal>&lt;assignment statement&gt; ::= &lt;singleton
+      variable assignment&gt; | &lt;multiple variable
+      assignment&gt;</literal></simpara>
+
+      <simpara><literal>&lt;singleton variable assignment&gt; ::= SET
+      &lt;assignment target&gt; &lt;equals operator&gt; &lt;assignment
+      source&gt;</literal></simpara>
+
+      <simpara><literal>&lt;multiple variable assignment&gt; ::= SET
+      (&lt;variable or parameter&gt;, ...) = &lt;row value
+      expression&gt;</literal></simpara>
+
+      <para>In the example below, the result of the SELECT is assigned to two
+      OUT or INOUT arguments. The SELECT must return one row. If it returns
+      more than one, an exception is raised. If it returns no row, no change
+      is made to ARG1 and ARG2.</para>
+
+      <programlisting>SET (arg1, arg2) = (SELECT col1, col2 FROM atable WHERE id = 10);</programlisting>
+
+      <para>In the example below, the result of a function call is assigned to
+      VAR1.</para>
+
+      <programlisting>SET var1 = SQRT(var2);</programlisting>
+    </section>
+
+    <section>
+      <title>Select Statement : Single Row</title>
+
+      <para>A special form of SELECT can also be used for assigning values
+      from a query to one or more arguments or variables. This works similar
+      to a SET statement that has a SELECT statement as the source.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SELECT : SINGLE ROW</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SELECT : SINGLE ROW</emphasis></simpara>
+
+      <simpara><emphasis>select statement: single row</emphasis></simpara>
+
+      <simpara><literal>&lt;select statement: single row&gt; ::= SELECT [
+      &lt;set quantifier&gt; ] &lt;select list&gt; INTO &lt;select target
+      list&gt; &lt;table expression&gt;</literal></simpara>
+
+      <simpara><literal>&lt;select target list&gt; ::= &lt;target
+      specification&gt; [ { &lt;comma&gt; &lt;target specification&gt; }...
+      ]</literal></simpara>
+
+      <simpara>Retrieve values from a specified row of a table and assign the
+      fields to the specified targets. The example below has an identical
+      effect to the example of SET statement given above.</simpara>
+
+      <programlisting>SELECT col1, col2 INTO arg1, arg2 FROM atable WHERE id = 10;</programlisting>
+    </section>
+
+    <section>
+      <title>Formal Parameters</title>
+
+      <para>Each parameter of a procedure can be defined as IN, OUT or INOUT.
+      An IN parameter is an input to the procedure and is passed by value. The
+      value cannot be modified inside the procedure body. An OUT parameter is
+      a reference for output. An INOUT parameter is a reference for both input
+      and output. An OUT or INOUT parameter argument is passed by reference,
+      therefore only a dynamic parameter argument or a variable within an
+      enclosing procedure can be passed for it. The assignment statement is
+      used to assign a value to an OUT or INOUT parameter.</para>
+
+      <para>In the example below, the procedure is declared with an OUT
+      parameter.</para>
+
+      <programlisting>CREATE PROCEDURE new_customer(OUT newid INT, IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+  MODIFIES SQL DATA
+  BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+    SET newid = temp_id;
+  END
+
+</programlisting>
+
+      <para>In the SQL session, or in the body of another stored procedure, a
+      variable must be assigned to the OUT parameter. After the procedure
+      call, this variable will hold the new identity value that was generated
+      inside the procedure.</para>
+
+      <para>In the example below, a session variable,
+      <literal>the_new_id</literal> is declared. After the call to
+      <literal>new_customer</literal>, the value for the identity is stored in
+      <literal>the_new_id</literal> variable. This is returned via the next
+      CALL statement. Alternatively, <literal>the_new_id</literal> can be used
+      as an argument to another CALL statement.</para>
+
+      <programlisting>DECLARE the_new_id INT DEFAULT NULL;
+CALL new_customer(the_new_id, 'John', 'Smith', '10 Parliament Square'); 
+CALL the_new_id;
+
+</programlisting>
+    </section>
+
+    <section>
+      <title>Iterated Statements</title>
+
+      <para>Various iterated statements can be used in routines. In these
+      statements, the <literal>&lt;SQL statement list&gt;</literal> consists
+      of one or more SQL statements. The <literal>&lt;search
+      condition&gt;</literal> can be any valid SQL expression of BOOLEAN
+      type.</para>
+
+      <simpara><literal>&lt;loop statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ] LOOP &lt;SQL statement list&gt; END LOOP [ &lt;ending
+      label&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;while statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ] WHILE &lt;search condition&gt; DO &lt;SQL statement
+      list&gt; END WHILE [ &lt;ending label&gt; ]</literal></simpara>
+
+      <simpara><literal>&lt;repeat statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ]</literal></simpara>
+
+      <simpara><literal>REPEAT &lt;SQL statement list&gt; UNTIL &lt;search
+      condition&gt; END REPEAT [ &lt;ending label&gt;</literal></simpara>
+
+      <para>In the example below, a multiple rows are inserted into a table in
+      a WHILE loop:</para>
+
+      <programlisting>loop_label: WHILE my_var &gt; 0 DO
+  INSERT INTO CUSTOMERS VALUES (DEFAULT, my_var);
+  SET my_var = my_var - 1;
+  IF my_var = 10 THEN SET my_var = 8; END IF;
+  IF my_var = 22 THEN LEAVE loop_label; END IF;
+END WHILE loop_label;
+
+</programlisting>
+    </section>
+
+    <section>
+      <title>Conditional Statements</title>
+
+      <para>There are two types of CASE ... WHEN statement and the IF ... THEN
+      statement.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CASE WHEN in routines</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CASE WHEN</emphasis></simpara>
+
+      <simpara><emphasis>case when statement</emphasis></simpara>
+
+      <para>The simple case statement uses a <literal>&lt;case
+      operand&gt;</literal> as the predicand of one or more predicates. For
+      the right part of each predicate, it specifies one or more SQL
+      statements to execute if the predicate evaluates TRUE. If the ELSE
+      clause is not specified, at least one of the search conditions must be
+      true, otherwise an exception is raised.</para>
+
+      <simpara><literal>&lt;simple case statement&gt; ::= CASE &lt;case
+      operand&gt; &lt;simple case statement when clause&gt;... [ &lt;case
+      statement else clause&gt; ] END CASE</literal></simpara>
+
+      <simpara><literal>&lt;simple case statement when clause&gt; ::= WHEN
+      &lt;when operand list&gt; THEN &lt;SQL statement
+      list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;case statement else clause&gt; ::= ELSE &lt;SQL
+      statement list&gt;</literal></simpara>
+
+      <para>A skeletal example is given below. The variable var_one is first
+      tested for equality with 22 or 23 and if the test evaluates to TRUE,
+      then the INSERT statement is performed and the statement ends. If the
+      test does not evaluate to TRUE, the next condition test, which is an IN
+      predicate, is performed with var_one and so on. The statement after the
+      ELSE clause is performed if none the previous tests returns TRUE.</para>
+
+      <programlisting>CASE var_one
+  WHEN 22, 23 THEN INSERT INTO t_one ...;
+  WHEN IN (2, 4, 5) THEN DELETE FROM t_one WHERE ...;
+  ELSE UPDATE t_one ...;
+  END CASE
+
+</programlisting>
+
+      <para>The searched case statement uses one or more search conditions,
+      and for each search condition, it specifies one or more SQL statements
+      to execute if the search condition evaluates TRUE. An exception is
+      raised if there is no ELSE clause and none of the search conditions
+      evaluates TRUE.</para>
+
+      <simpara><literal>&lt;searched case statement&gt; ::= CASE &lt;searched
+      case statement when clause&gt;... [ &lt;case statement else clause&gt; ]
+      END CASE</literal></simpara>
+
+      <simpara><literal>&lt;searched case statement when clause&gt; ::= WHEN
+      &lt;search condition&gt; THEN &lt;SQL statement
+      list&gt;</literal></simpara>
+
+      <para>The example below is partly a rewrite of the previous example, but
+      a new condition is added:</para>
+
+      <programlisting>CASE WHEN var_one = 22 OR var_one = 23 THEN INSERT INTO t_one ...;
+  WHEN var_one IN (2, 4, 5) THEN DELETE FROM t_one WHERE ...;
+  WHEN var_two IS NULL THEN UPDATE t_one ...;
+  ELSE UPDATE t_one ...;
+  END CASE
+
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>IF STATEMENT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">IF</emphasis></simpara>
+
+      <simpara><emphasis>if statement</emphasis></simpara>
+
+      <para>The if statement is very similar to the searched case statement.
+      The difference is that no exception is raised if there is no ELSE clause
+      and no search condition evaluates TRUE.</para>
+
+      <simpara><literal>&lt;if statement&gt; ::= IF &lt;search condition&gt;
+      &lt;if statement then clause&gt; [ &lt;if statement elseif clause&gt;...
+      ] [ &lt;if statement else clause&gt; ] END IF</literal></simpara>
+
+      <simpara><literal>&lt;if statement then clause&gt; ::= THEN &lt;SQL
+      statement list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;if statement elseif clause&gt; ::= ELSEIF
+      &lt;search condition&gt; THEN &lt;SQL statement
+      list&gt;</literal></simpara>
+
+      <simpara><literal>&lt;if statement else clause&gt; ::= ELSE &lt;SQL
+      statement list&gt;</literal></simpara>
+    </section>
+
+    <section>
+      <title>Return Statement</title>
+
+      <para>The RETURN statement is required and used only in functions. The
+      body of a function is either a RETURN statement, or a compound statement
+      that contains a RETURN statement.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>RETURN</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">RETURN</emphasis></simpara>
+
+      <simpara><emphasis>return statement</emphasis></simpara>
+
+      <simpara><literal>&lt;return statement&gt; ::= RETURN &lt;return
+      value&gt;</literal></simpara>
+
+      <simpara><literal>&lt;return value&gt; ::= &lt;value expression&gt; |
+      NULL</literal></simpara>
+
+      <simpara>Return a value from an SQL function. If the function is defined
+      as RETURNS TABLE, then the value is a TABLE expression such as RETURN
+      TABLE(SELECT ...) otherwise, the value expression can be any scalar
+      expression. In the examples below, the same function is written with or
+      without a BEGIN END block. In both versions, the RETURN value is a
+      scalar expression.</simpara>
+
+      <programlisting>CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP
+  RETURN (SELECT MAX(event_time) FROM atable WHERE event_type = e_type) - 1 HOUR
+
+CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP
+  BEGIN ATOMIC
+    DECLAR max_event TIMESTAMP;
+    SET max_event = SELECT MAX(event_time) FROM atable WHERE event_type = e_type;
+    RETURN max_event - 1 HOUR;
+  END
+
+</programlisting>
+    </section>
+
+    <section>
+      <title>Control Statements</title>
+
+      <para>In addition to the RETURN statement, the following statements can
+      be used in specific contexts.</para>
+
+      <para>ITERATE STATEMENT</para>
+
+      <para>The ITERATE statement can be used to cause the next iteration of a
+      labeled iterated statement (a WHILE, REPEAT or LOOP statement). It is
+      similar to the "continue" statement in C and Java.</para>
+
+      <simpara><literal>&lt;iterate statement&gt; ::= ITERATE &lt;statement
+      label&gt;</literal></simpara>
+
+      <para>LEAVE STATEMENT</para>
+
+      <para>The LEAVE statement can be used to leave a labeled block. When
+      used in an iterated statement, it is similar to the "break" statement is
+      C and Java. But it can be used in compound statements as well.</para>
+
+      <simpara><literal>&lt;leave statement&gt; ::= LEAVE &lt;statement
+      label&gt;</literal></simpara>
+
+      <simpara>Signal and Resignal Statements</simpara>
+
+      <para>The SIGNAL statement is used to throw an exception (or force an
+      exception). When invoked, any exception handler for the given exception
+      is in turn invoked. If there is no handler, the exception is propagated
+      to the enclosing context.</para>
+
+      <simpara><literal>&lt;signal statement&gt; ::= SIGNAL SQL_STATE
+      &lt;state value&gt;</literal></simpara>
+
+      <para>The RESIGNAL statement is used to throw an exception from an
+      exception handler’s <literal>&lt;SQL procedure statement&gt;</literal>,
+      in effect propagating the exception to the enclosing context without
+      further action by the currently active handlers.</para>
+
+      <simpara><literal>&lt;resignal statement&gt; ::= RESIGNAL SQL_STATE
+      &lt;state value&gt;</literal></simpara>
+    </section>
+
+    <section>
+      <title>Routine Polymorphism</title>
+
+      <para>More than one version of a routine can be created.</para>
+
+      <para>For procedures, the different versions must have different
+      parameter counts.  When the procedure is called, the parameter count
+      determines which version is called.</para>
+
+      <para>For functions, the different versions can have the same or
+      different parameter counts. When the parameter count of two versions of
+      a function is the same, the type of parameters must be different. The
+      best matching version of the function is called, according to both the
+      parameter count and parameter types.</para>
+
+      <para>Two versions of an overloaded function are given below. One
+      version accepts TIMESTAMP while the other accepts TIME arguments.</para>
+
+      <programlisting>CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  IF t &gt; CURRENT_TIMESTAMP THEN
+    RETURN CURRENT_TIMESTAMP;
+  ELSE
+    RETURN t - 1 HOUR;
+  END IF
+
+CREATE FUNCTION an_hour_before_or_now(t TIME)
+  RETURNS TIME
+  CASE t
+    WHEN &gt; CURRENT_TIME THEN
+      RETURN CURRENT_TIME;
+    WHEN &gt;= TIME'01:00:00' THEN
+      RETURN t - 1 HOUR;
+    ELSE
+      RETURN CURRENT_TIME;
+  END CASE
+
+</programlisting>
+
+      <para>more ..</para>
+    </section>
+
+    <section>
+      <title>Returning Data From Routines</title>
+
+      <para>The OUT or INOUT parameters of a procedure are used to assign
+      simple values to dynamic parameters or to variables in the calling
+      context. In addition, a SQL/PSM procedure may return result sets to the
+      calling context. These result sets are dynamic in the sense that a
+      procedure may return a different number of result sets or none at all in
+      different invocations.</para>
+
+      <para>The SQL Standard uses a mechanism called CURSORS for accessing and
+      modifying rows of a result set one by one. This mechanism is absolutely
+      necessary when the database is accessed from an external application
+      program. The JDBC ResultSet interface allows this method of access from
+      Java programs and is supported by HyperSQL.</para>
+
+      <para>The SQL Standard uses cursors within the body of a procedure to
+      return result sets. It specifies a somewhat complex mechanism to allow
+      access to these cursors from the calling contexts. HyperSQL does not
+      support access to such result sets within a calling SQL/PSM procedure.
+      This is considered redundant as all operations on data can be performed
+      with non-cursor SQL statements.</para>
+
+      <para>(feature to be implemented) HyperSQL will support returning single
+      or multiple result sets from SQL/PSM procedures only via the JDBC
+      CallableStatement interface. Cursors are declared and opened within the
+      body of the procedure. No further operation is performed on the cursors
+      within the procedure. When the execution of the procedure is complete,
+      the cursors become available as Java ResultSet objects via the
+      CallableStatement instance that called the SQL/PSM procedure.</para>
+
+      <para>Currently, a single result can be returned from FUNCTION routines,
+      when the function is defined as RETURNS TABLE ( .. )</para>
+
+      <para>To return a table from a SELECT statement, you should use a return
+      statement such as RETURN TABLE( SELECT ...); in a SQL/PSM function. A
+      Java function should return a JDBCResultSet instance. For an example of
+      how to construct a JDBCResultSet for this purpose, see the source code
+      for the org.hsqldb.jdbc.JDBCArray class.</para>
+
+      <para>The JDBC CallableStatement class is used with the SQL statement
+      <literal>CALL &lt;routine name&gt; ( &lt;argument 1&gt;, ... )</literal>
+      to call both functions and procedures. The <literal>getXXX()</literal>
+      methods can be used to retrieve INOUT or OUT arguments after the call.
+      The <literal>getResultSet()</literal> call can be used to access the
+      ResultSet returned from a function that returns a result set.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Java Language Routines (SQL/JRT)</title>
+
+    <para>The body of a Java language routine is a static method of a Java
+    class, specified with a fully qualified method name in the routine
+    definition.</para>
+
+    <para>In the example below, the static method named
+    <methodname>toZeroPaddedString</methodname> is specified to be called when
+    the function is invoked.</para>
+
+    <programlisting>CREATE FUNCTION zero_pad(x BIGINT, digits INT, maxsize INT)
+  RETURNS CHAR VARYING(100)
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME
+  'CLASSPATH:org.hsqldb.lib.StringUtil.toZeroPaddedString'
+
+</programlisting>
+
+    <para>The signature of the Java method (used in the Java code but not in
+    SQL code to create the function) is given below:</para>
+
+    <programlisting>public static String toZeroPaddedString(long value, int precision, int maxSize)</programlisting>
+
+    <para>The parameter and return types and of the SQL routine definition
+    must match those of the Java method according to the table below:</para>
+
+    <informaltable frame="all">
+      <tgroup cols="2">
+        <tbody>
+          <row>
+            <entry><para>SMALLINT   </para></entry>
+
+            <entry><para>Short or Short</para></entry>
+          </row>
+
+          <row>
+            <entry><para>INT</para></entry>
+
+            <entry><para>int or Integer</para></entry>
+          </row>
+
+          <row>
+            <entry><para>BIGINT</para></entry>
+
+            <entry><para>long or Long</para></entry>
+          </row>
+
+          <row>
+            <entry><para>NUMERIC  or DECIMAL</para></entry>
+
+            <entry><para>BigDecimal</para></entry>
+          </row>
+
+          <row>
+            <entry><para>FLOAT  or DOUBLE</para></entry>
+
+            <entry><para>Double or Double</para></entry>
+          </row>
+
+          <row>
+            <entry><para>CHAR or VARCHAR</para></entry>
+
+            <entry><para>String</para></entry>
+          </row>
+
+          <row>
+            <entry><para>DATE</para></entry>
+
+            <entry><para>java.sql.Date</para></entry>
+          </row>
+
+          <row>
+            <entry><para>TIME</para></entry>
+
+            <entry><para>java.sql.Time</para></entry>
+          </row>
+
+          <row>
+            <entry><para>TIMESTAMP</para></entry>
+
+            <entry><para>java.sql.Timestamp</para></entry>
+          </row>
+
+          <row>
+            <entry><para>BINARY</para></entry>
+
+            <entry><para>Byte[]</para></entry>
+          </row>
+
+          <row>
+            <entry><para>BOOLEAN</para></entry>
+
+            <entry><para>boolean or Boolean</para></entry>
+          </row>
+
+          <row>
+            <entry>ARRAY of any type</entry>
+
+            <entry>java.sql.Array</entry>
+          </row>
+
+          <row>
+            <entry><para>TABLE</para></entry>
+
+            <entry><para>java.sql.ResultSet</para></entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </informaltable>
+
+    <para>If the specified Java method is not found or its parameters and
+    return types do not match the definition, an exception is raised. If more
+    than one version of the Java method exist, then the one with matching
+    parameter and return types is found and registered. If two “equivalent”
+    methods exist, the first one is registered. (This situation arises only
+    when a parameter is a primitive in one version and an Object in another
+    version, e.g. <classname>long</classname> and
+    <classname>java.lang.Long</classname>.).</para>
+
+    <para>When the Java method of an SQL/JRT routine returns a value, it
+    should be within the size and precision limits defined in the return type
+    of the SQL-invoked routine, otherwise an exception is raised. The scale
+    difference are ignored and corrected. For example, in the above example,
+    the <literal>RETURNS CHAR VARYING(100)</literal> clause limits the length
+    of the strings returned from the Java method to 100. But if the number of
+    digits after the decimal point (scale) of a returned BigDecimal value is
+    larger than the scale specified in the RETURNS clause, the decimal
+    fraction is silently truncated and no exception of warning is
+    raised.</para>
+
+    <section>
+      <title>Polymorphism</title>
+
+      <para>If two versions of the same SQL invoked routine with different
+      parameter types are required, they can be defined to point to the same
+      method name or different method names, or even methods in different
+      classes. In the example below, the first two definitions refer to the
+      same method name in the same class. In the Java class, the two static
+      methods are defined with corresponding method signatures.</para>
+
+      <para>In the third example, the Java function returns a result set and
+      the SQL declaration includes RETURNS TABLE.</para>
+
+      <programlisting>CREATE FUNCTION an_hour_before_or_now(t TIME)
+  RETURNS TIME
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION testquery(INTEGER) 
+  RETURNS TABLE(n VARCHAR(20), i INT) 
+  READS SQL DATA
+  LANGUAGE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.TestJavaFunctions.getQueryResult'
+
+</programlisting>
+
+      <para>In the Java class:</para>
+
+      <programlisting>    public static java.sql.Time nowLessAnHour(java.sql.Time value) {
+        ...
+    }
+    public static java.sql.Timestamp nowLessAnHour(java.sql.Timestamp value)
+        ...
+    }
+
+    public static ResultSet getQueryResult(Connection connection, int i) throws SQLException {
+        Statement st = connection.createStatement();
+        return st.executeQuery("SELECT * FROM T WHERE I &lt; " + i);
+    }
+
+</programlisting>
+    </section>
+
+    <section>
+      <title>Java Language Procedures</title>
+
+      <para>Java procedures are defined similarly to functions. The
+      differences are:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>The return type of the Java static method must be void.</para>
+        </listitem>
+
+        <listitem>
+          <para>If a parameter is defined as OUT or INOUT, the corresponding
+          Java static method parameter must be defined as an array of the JDBC
+          non-primitive type.</para>
+        </listitem>
+
+        <listitem>
+          <para>When the Java static method is invoked, the OUT and INOUT
+          arguments are passed as a single-element array.</para>
+        </listitem>
+
+        <listitem>
+          <para>The static method can modify the OUT or INOUT param by
+          assigning a value to the sole element of the argument array.</para>
+        </listitem>
+
+        <listitem>
+          <para>If the procedure contains SQL statements, only statements for
+          data access and manipulation are allowed. The java method should not
+          perform commit or rollback. The SQL statements should not change the
+          session settings and should not include statements at create or
+          modify tables definitions or other database objects. These rules are
+          generally enforced by the engine, but additional enforcement may be
+          added in future versions</para>
+        </listitem>
+      </itemizedlist>
+
+      <para>An example of a procedure definition is given below:</para>
+
+      <programlisting>CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname  VARCHAR(50), address VARCHAR(100))
+  MODIFIES SQL DATA
+  LANGUAGE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.Test01.newCustomerProcedure'
+</programlisting>
+    </section>
+
+    <section>
+      <title>Legacy Support</title>
+
+      <para>The legacy HyperSQL statement, <literal>CREATE ALIAS &lt;name&gt;
+      FOR &lt;fully qualified Java method name&gt;</literal> is no longer
+      supported directly. It is supported when importing databases and
+      translates to a special <literal>CREATE FUNCTION &lt;name&gt;</literal>
+      statement that creates the function in the PUBLIC schema.</para>
+
+      <para>The direct use of a Java method as a function is still supported
+      but deprecated. It is internally translated to a special <literal>CREATE
+      FUNCTION</literal> statement where the name of the function is the
+      double quoted, fully qualified name of the Java method used.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>SQL Language Aggregate Functions</title>
+
+    <para>HyperSQL adds an extension to the SQL Standard to allow user defined
+    aggregate functions. A user defined aggregate function has a single
+    parameter when it is used in SQL statements. Unlike the predefined
+    aggregate functions, the keyword DISTINCT cannot be used when a user
+    defined aggregate function is invoked. Like all user defined functions, an
+    aggregate function belongs to a schema and can be polymorphic.</para>
+
+    <para>A user defined aggregate function can be used in SQL statements
+    where a predefined aggregate function is allowed.</para>
+
+    <section>
+      <title>Definition of Aggregate Functions</title>
+
+      <para>An aggregate function is always defined with 4 parameters. The
+      first parameter is the parameter that is used when the function is
+      invoked in SQL statements, the rest of the parameter are invisible to
+      the invoking statement. The type of the first parameter is user defined.
+      The type of the second parameter must be BOOLEAN. The third and fourth
+      parameters have user defined types and must be defined as INOUT
+      parameters. The defined return type of the function determines the type
+      of the value returned when the function is invoked.</para>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>CREATE AGGREGATE FUNCTION</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">CREATE AGGREGATE
+      FUNCTION</emphasis></simpara>
+
+      <simpara><emphasis>user defined aggregate function
+      definition</emphasis></simpara>
+
+      <para>Aggregate function definition is similar to normal function
+      definition and has the mandatory <literal>&lt;returns
+      clause&gt;</literal>. The BNF is given below.</para>
+
+      <simpara><literal>&lt;user defined aggregate function&gt; ::= CREATE
+      AGGREGATE FUNCTION &lt;schema qualified routine name&gt; &lt;SQL
+      aggregate parameter declaration list&gt; &lt;returns clause&gt;
+      &lt;routine characteristics&gt; &lt;routine body&gt;</literal></simpara>
+
+      <para>The parameter declaration list BNF is given below. The type of the
+      first parameter is used when the function is invoked as part of an SQL
+      statement. When multiple versions of a function are required, each
+      version will have the first parameter of a different type.</para>
+
+      <simpara><literal>&lt;SQL aggregate declaration list&gt; ::= &lt;left
+      paren&gt; [IN] [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt;
+      &lt;comma&gt; [IN] [ &lt;SQL parameter name&gt; ] BOOLEAN &lt;comma&gt;
+      INOUT [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt;
+      &lt;comma&gt; INOUT [ &lt;SQL parameter name&gt; ] &lt;parameter
+      type&gt; &lt;right paren&gt;</literal></simpara>
+
+      <para>The return type is user defined. This is the type of the resulting
+      value when the function is called. Usually an aggregate function is
+      defined with CONTAINS SQL, as it normally does not read the data in
+      database tables, but it is possible to define the function with READS
+      SQL DATA and access the database tables.</para>
+
+      <para>HyperSQL invokes the aggregate function, with all the arguments
+      set, once per each row in order to compute the values. Finally, it
+      invokes the function once more to return the final result.</para>
+
+      <para>In the computation phase, the first argument is the value of the
+      user argument as specified in the SQL statement, computed for the
+      current row. The second argument is the boolean FALSE. The third and
+      fourth argument values are initially null, but they can be updated in
+      the body of the function during each invocation. The third and fourth
+      arguments act as registers and hold their values between invocations.
+      The return value of the function is ignored during the computation phase
+      (when the second parameter is FALSE).</para>
+
+      <para>After the computation phase, the function is invoked once more to
+      get the final result. In this invocation, the first argument is NULL and
+      the second argument is boolean TRUE. The third and fourth arguments hold
+      the values they held at the end of the last invocation. The value
+      returned by the function in this invocation is used as the result of the
+      aggregate function computation in the invoking SQL statement. In SQL
+      queries with GROUP BY, the call sequence is repeated for each separate
+      group.</para>
+    </section>
+
+    <section>
+      <title>SQL PSM Aggregate Functions</title>
+
+      <para>The example below features a user defined version of the Standard
+      <literal>AVG(&lt;value expression&gt;)</literal> aggregate function for
+      INTEGER input and output types. This function behaves differently from
+      the Standard AVG function as it returns 0 when all the input values are
+      null.</para>
+
+      <programlisting>CREATE AGGREGATE FUNCTION udavg(IN x INTEGER, IN flag BOOLEAN, INOUT addup BIGINT, INOUT counter INT)
+  RETURNS INTEGER
+  CONTAINS SQL
+  BEGIN ATOMIC
+    IF flag THEN
+      RETURN addup / counter;
+    ELSE
+      SET counter = COALESCE(counter, 0) + 1;
+      SET addup = COALESCE(addup, 0) || COALESCE(x, 0);
+      RETURN NULL;
+    END IF;
+  END
+
+</programlisting>
+
+      <para>The user defined aggregate function is used in a select statement
+      in the example below. Only the first parameter is visible and utilised
+      in the select statement.</para>
+
+      <programlisting>SELECT udavg(id) FROM customers GROUP BY lastname;</programlisting>
+
+      <para>In the example below, the function returns an array that contains
+      all the values passed for the aggregated column. For use with longer
+      arrays, you can optimise the function by defining a larger array in the
+      first iteration, and using the TRIM_ARRAY function on the RETURN to cut
+      the array to size :</para>
+
+      <programlisting>CREATE AGGREGATE FUNCTION array_aggregate(IN val VARCHAR(100), IN flag boolean, INOUT buffer VARCHAR(100) ARRAY, INOUT counter INT)
+  RETURNS VARCHAR(100) ARRAY
+  CONTAINS SQL
+  BEGIN ATOMIC
+    IF flag THEN
+      RETURN buffer;
+    ELSE
+      IF val IS NULL THEN RETURN NULL; END IF;
+      IF counter IS NULL THEN SET counter = 0; END IF;
+      SET counter = counter + 1;
+      IF counter = 1 THEN SET buffer = ARRAY[val];
+      ELSE SET buffer[counter] = val; END IF;
+      RETURN NULL;
+    END IF;
+  END
+</programlisting>
+
+      <para>The tables and data for the select statement below are created
+      with the DatabaseManager or DatabaseManagerSwing GUI apps. Part of the
+      output is shown. Each row of the output includes an array containing the
+      values for the invoices for each customer.</para>
+
+      <programlisting>SELECT ID, FIRSTNAME, LASTNAME, ARRAY_AGGREGATE(CAST(INVOICE.TOTAL AS VARCHAR(100))) 
+  FROM customer JOIN INVOICE ON ID =CUSTOMERID
+  GROUP BY ID, FIRSTNAME, LASTNAME
+
+11 Susanne   Karsen    ARRAY['3988.20']                               
+12 John      Peterson  ARRAY['2903.10','4382.10','4139.70','3316.50'] 
+13 Michael   Clancy    ARRAY['6525.30']                               
+14 James     King      ARRAY['3665.40','905.10','498.00']             
+18 Sylvia    Clancy    ARRAY['634.20','4883.10']                      
+20 Bob       Clancy    ARRAY['3414.60','744.60']
+</programlisting>
+    </section>
+
+    <section>
+      <title>Java Aggregate Functions</title>
+
+      <para>A Java aggregate function is defined similarly to PSM functions,
+      apart from the routine body, which is defined as <literal>EXTERNAL NAME
+      ...</literal> The Java function signature must follow the rules for both
+      nullable and INOUT parameters, therefore:</para>
+
+      <para>No agrument is defined as a primitive or primitive array type.
+      This allows nulls to be passed to the function. The second and third
+      arguments must be defined as arrays of the JDBC non-primitive types
+      listed in the table in the previous section.</para>
+
+      <para>In the example below, a user-defined aggregate function for
+      geometric mean is defined.</para>
+
+      <programlisting>CREATE AGGREGATE FUNCTION geometric_mean(IN val DOUBLE, IN flag BOOLEAN, INOUT register DOUBLE, INOUT counter INT)
+ RETURNS DOUBLE
+ NO SQL
+ LANGUAGE JAVA
+ EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.Test01.geometricMean'
+</programlisting>
+
+      <para>The Java function definition is given below:</para>
+
+      <programlisting>public static Double geometricMean(Double in, Boolean flag,
+        Double[] register, Integer[] counter) {
+
+    if (flag) {
+        if (register[0] == null) { return null; }
+        double a = register[0].doubleValue();
+        double b = 1 / (double) counter[0];
+        return Double.valueOf(java.lang.Math.pow(a, b));
+    }
+    if (in == null) { return null; }
+    if (in.doubleValue() == 0) { return null; }
+    if (register[0] == null) {
+        register[0] = in;
+        counter[0]  = Integer.valueOf(1);
+    } else {
+        register[0] = Double.valueOf(register[0].doubleValue() * in.doubleValue());
+        counter[0] = Integer.valueOf(counter[0].intValue() + 1);
+    }
+    return null;
+}
+</programlisting>
+
+      <para>In a select statement, the function is used like built in
+      aggregate functions:</para>
+
+      <programlisting>SELECT geometric_mean(age) FROM  FROM customer
+</programlisting>
+    </section>
+  </section>
+
+  <section>
+    <title>Routine Definition</title>
+
+    <para>As discussed in the previous pages, routine definition has several
+    mandatory or optional clauses. The complete BNF supported by HyperSQL and
+    the remaining clauses are documented in this section.</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CREATE FUNCTION</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CREATE FUNCTION</emphasis></simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CREATE PROCEDURE</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CREATE PROCEDURE</emphasis></simpara>
+
+    <simpara><emphasis>routine definition</emphasis></simpara>
+
+    <para>Routine definition is similar for procedures and functions. A
+    function definition has the mandatory <literal>&lt;returns
+    clause&gt;</literal> which is discussed later. The description given so
+    far covers the essential elements of the specification with the BNF given
+    below.</para>
+
+    <simpara><literal>&lt;schema procedure&gt; ::= CREATE PROCEDURE &lt;schema
+    qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+    &lt;routine characteristics&gt; &lt;routine body&gt;</literal></simpara>
+
+    <simpara><literal>&lt;schema function&gt; ::= CREATE FUNCTION &lt;schema
+    qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+    &lt;returns clause&gt; &lt;routine characteristics&gt; &lt;routine
+    body&gt;</literal></simpara>
+
+    <para>Parameter declaration list has been described above. For SQL/JRT
+    routines, the <literal>&lt;SQL parameter name&gt;</literal> is optional
+    while for SQL/PSM routines, it is required. If the <literal>&lt;parameter
+    mode&gt;</literal> of a parameter is OUT or INOUT, it must be specified.
+    The BNF is given below:</para>
+
+    <simpara><literal>&lt;SQL parameter declaration list&gt; ::= &lt;left
+    paren&gt; [ &lt;SQL parameter declaration&gt; [ { &lt;comma&gt; &lt;SQL
+    parameter declaration&gt; }... ] ] &lt;right paren&gt;</literal></simpara>
+
+    <simpara><literal>&lt;SQL parameter declaration&gt; ::= [ &lt;parameter
+    mode&gt; ] [ &lt;SQL parameter name&gt; ] &lt;parameter
+    type&gt;</literal></simpara>
+
+    <simpara><literal>&lt;parameter mode&gt; ::= IN | OUT |
+    INOUT</literal></simpara>
+
+    <simpara><literal>&lt;parameter type&gt; ::= &lt;data
+    type&gt;</literal></simpara>
+
+    <para>Return Value and Table Functions</para>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>RETURNS</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">RETURNS</emphasis></simpara>
+
+    <simpara><emphasis>returns clause</emphasis></simpara>
+
+    <para>The <literal>&lt;returns clause&gt;</literal> specifies the type of
+    the return value of a function. For all SQL/PSM functions and ordinary
+    SQL/JRT functions, this is simply a type definition which can be a
+    built-in type, a DOMAIN type or a DISTINCT type, or alternatively, a TABLE
+    definition. For example, RETURNS INTEGER.</para>
+
+    <para>For a SQL/JRT function, it is possible to define a
+    <literal>&lt;returns table type&gt;</literal> for a Java method that
+    returns a <classname>java.sql.ResultSet</classname> object. Such SQL/JRT
+    functions are called <glossterm>table functions</glossterm>. Table
+    functions are used differently from normal functions. A table function can
+    be used in an SQL query expression exactly where a normal table or view is
+    allowed. At the time of invocation, the Java method is called and the
+    returned ResultSet is transformed into an SQL table. The column types of
+    the declared TABLE must match those of the ResultSet, otherwise an
+    exception is raised at the time of invocation.</para>
+
+    <para>If a <literal>&lt;returns table type&gt;</literal> is defined for an
+    SQL/PSM function, the following expression is used inside the function to
+    return a table: <literal>RETURN TABLE ( &lt;query expression&gt;
+    );</literal> In the example blow, a table with two columns is
+    returned.</para>
+
+    <programlisting>RETURN TABLE ( SELECT a, b FROM atable WHERE e = 10 );</programlisting>
+
+    <para>If a JDBC <literal>CallableStatement</literal> is used to CALL the
+    function, the table returned from the function call is returned and can be
+    accessed with the <literal>getResultSet()</literal> method of the
+    <literal>CallableStatement</literal>.</para>
+
+    <simpara><literal>&lt;returns clause&gt; ::= RETURNS &lt;returns
+    type&gt;</literal></simpara>
+
+    <simpara><literal>&lt;returns type&gt; ::= &lt;returns data type&gt; |
+    &lt;returns table type&gt;</literal></simpara>
+
+    <simpara><literal>&lt;returns table type&gt; ::= TABLE &lt;table function
+    column list&gt;</literal></simpara>
+
+    <simpara><literal>&lt;table function column list&gt; ::= &lt;left
+    paren&gt; &lt;table function column list element&gt; [ { &lt;comma&gt;
+    &lt;table function column list element&gt; } ... ] &lt;right
+    paren&gt;</literal></simpara>
+
+    <simpara><literal>&lt;table function column list element&gt; ::=
+    &lt;column name&gt; &lt;data type&gt;</literal></simpara>
+
+    <simpara><literal>&lt;returns data type&gt; ::= &lt;data
+    type&gt;</literal></simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>routine body</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">routine body</emphasis></simpara>
+
+    <simpara><emphasis>routine body</emphasis></simpara>
+
+    <para>Routine body is either one or more SQL statements or a Java
+    reference, as described. The user that defines the routine by issuing the
+    CREATE FUNCTION or CREATE SCHEMA command must have the relevant access
+    rights to all tables, sequences, routines, etc. that are accessed by the
+    routine. If another user is given EXECUTE privilege on the routine, then
+    there are two possibilities, depending on the <literal>&lt;rights
+    clause&gt;</literal>. This clause refers to the access rights that are
+    checked when a routine is invoked. The default is <literal>SQL SECURITY
+    DEFINER</literal>, which means access rights of the definer are used;
+    therefore no extra checks are performed when the other user invokes the
+    routine. The alternative <literal>SQL SECURITY INVOKER</literal> means
+    access rights on all the database objects referenced by the routine are
+    checked for the invoker. This alternative is not supported by
+    HyperSQL.</para>
+
+    <simpara><literal>&lt;routine body&gt; ::= &lt;SQL routine spec&gt; |
+    &lt;external body reference&gt;</literal></simpara>
+
+    <simpara><literal>&lt;SQL routine spec&gt; ::= [ &lt;rights clause&gt; ]
+    &lt;SQL routine body&gt;</literal></simpara>
+
+    <simpara><literal>&lt;rights clause&gt; ::= SQL SECURITY INVOKER | SQL
+    SECURITY DEFINER</literal></simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>SQL routine body</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">SQL routine body</emphasis></simpara>
+
+    <simpara><emphasis>SQL routine body</emphasis></simpara>
+
+    <para>The routine body of a an SQL routine consists of an
+    statement.</para>
+
+    <simpara><literal>&lt;SQL routine body&gt; ::= &lt;SQL procedure
+    statement&gt;</literal></simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>EXTERNAL NAME</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">EXTERNAL NAME</emphasis></simpara>
+
+    <simpara><emphasis>external body reference</emphasis></simpara>
+
+    <para>External name specifies the qualified name of the Java method
+    associated with this routine. Early releases of HyperSQL 2.0 only supports
+    Java methods within the classpath. The <literal>&lt;external Java
+    reference string&gt;</literal> is a quoted string which starts with
+    CLASSPATH: and is followed by the Java package, class and method names
+    separated with dots. HyperSQL does not currently support the optional
+    <literal>&lt;Java parameter declaration list&gt;</literal>.</para>
+
+    <simpara><literal>&lt;external body reference&gt; ::= EXTERNAL NAME
+    &lt;external Java reference string&gt;</literal></simpara>
+
+    <simpara><literal>&lt;external Java reference string&gt; ::= &lt;jar and
+    class name&gt; &lt;period&gt; &lt;Java method name&gt; [ &lt;Java
+    parameter declaration list&gt; ]</literal></simpara>
+
+    <section>
+      <title>Routine Characteristics</title>
+
+      <para>The <literal>&lt;routine characteristics&gt;</literal> clause
+      covers several sub-clauses</para>
+
+      <simpara><literal>&lt;routine characteristics&gt; ::= [ &lt;routine
+      characteristic&gt;... ]</literal></simpara>
+
+      <simpara><literal>&lt;routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | SPECIFIC &lt;specific
+      name&gt; | &lt;deterministic characteristic&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | &lt;savepoint level
+      indication&gt;</literal></simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>LANGUAGE</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">LANGUAGE</emphasis></simpara>
+
+      <simpara><emphasis>language clause</emphasis></simpara>
+
+      <para>The <literal>&lt;language clause&gt;</literal> refers to the
+      language in which the routine body is written. It is either SQL or Java.
+      The default is SQL, so JAVA must be specified for SQL/JRT
+      routines.</para>
+
+      <simpara><literal>&lt;language clause&gt; ::= LANGUAGE &lt;language
+      name&gt;</literal></simpara>
+
+      <simpara><literal>&lt;language name&gt; ::= SQL |
+      JAVA</literal></simpara>
+
+      <para>The parameter style is not allowed for SQL routines. It is
+      optional for Java routines and, in HyperSQL, the only value allowed is
+      JAVA.</para>
+
+      <simpara><literal>&lt;parameter style&gt; ::= JAVA</literal></simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SPECIFIC NAME</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SPECIFIC NAME</emphasis></simpara>
+
+      <simpara><emphasis>specific name</emphasis></simpara>
+
+      <para>The <literal>SPECIFIC &lt;specific name&gt;</literal> clause is
+      optional but the engine will creates an automatic name if it is not
+      present. When there are several versions of the same routine, the
+      <literal>&lt;specific name&gt;</literal> is used in schema manipulation
+      statements to drop or alter a specific version. The
+      <literal>&lt;specific name&gt;</literal> is a user-defined name. It
+      applies to both functions and procedures. In the examples below, a
+      specific name is specified for each function.</para>
+
+      <programlisting>CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  SPECIFIC an_hour_before_or_now_with_timestamp
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP SPECIFIC an_hour_before_max_with_int
+  RETURN (SELECT MAX(event_time) FROM atable WHERE event_type = e_type) - 1 HOUR
+
+</programlisting>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DETERMINISTIC characteristic</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DETERMINISTIC</emphasis></simpara>
+
+      <simpara><emphasis>deterministic characteristic</emphasis></simpara>
+
+      <para>The <literal>&lt;deterministic characteristic&gt;</literal> clause
+      indicates that a routine is deterministic or not. Deterministic means
+      the routine does not reference random values, external variables, or
+      time of invocation. The default is <literal>NOT DETERMINISTIC</literal>.
+      It is essential to declare this characteristics correctly for an SQL/JRT
+      routine, as the engine does not know the contents of the Java code,
+      which could include calls to methods returning random or time sensitive
+      values.</para>
+
+      <simpara><literal>&lt;deterministic characteristic&gt; ::= DETERMINISTIC
+      | NOT DETERMINISTIC</literal></simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SQL DATA access characteristic</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SQL DATA access</emphasis></simpara>
+
+      <simpara><emphasis>SQL DATA access characteristic</emphasis></simpara>
+
+      <para>The <literal>&lt;SQL-data access indication&gt;</literal>  clause
+      indicates the extent to which a routine interacts with the database or
+      the data stored in the database tables (SQL data).  NO SQL means no SQL
+      command is issued in the routine body and can be used only for SQL/JRT
+      functions. <literal>CONTAINS SQL</literal> means some SQL commands are
+      used, but they do not read or modify the SQL data. <literal>READS SQL
+      DATA</literal> and <literal>MODIFIES SQL DATA</literal> are self
+      explanatory.</para>
+
+      <simpara><literal>&lt;SQL-data access indication&gt; ::= NO SQL |
+      CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA</literal></simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>NULL INPUT</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">NULL INPUT</emphasis></simpara>
+
+      <simpara><emphasis>null call clause</emphasis></simpara>
+
+      <para>Null Arguments</para>
+
+      <para>The <literal>&lt;null-call clause&gt;</literal> is used only for
+      functions. If a function returns NULL when any of the calling arguments
+      is null, then by specifying <literal>RETURNS NULL ON NULL
+      INPUT</literal>, calls to the function are known to be redundant and do
+      not take place when an argument is null. This simplifies the coding of
+      the SQL/JRT Java methods and improves performance at the same
+      time.</para>
+
+      <simpara><literal>&lt;null-call clause&gt; ::= RETURNS NULL ON NULL
+      INPUT | CALLED ON NULL INPUT</literal></simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>SAVEPOINT LEVEL</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">SAVEPOINT LEVEL</emphasis></simpara>
+
+      <simpara><emphasis>transaction impact</emphasis></simpara>
+
+      <para>The <literal>&lt;savepoint level indication&gt;</literal> is used
+      only for procedures and refers to the visibility of existing savepoints
+      within the body of the procedure. If <literal>NEW SAVEPOINT
+      LEVEL</literal> is specified, savepoints that have been declared prior
+      to calling the procedure become invisible within the body of the
+      procedure. HyperSQL’s implementation accepts only <literal>NEW SAVEPOINT
+      LEVEL</literal>, which must be specified.</para>
+
+      <simpara><literal>&lt;savepoint level indication&gt; ::= NEW SAVEPOINT
+      LEVEL | OLD SAVEPOINT LEVEL</literal></simpara>
+
+      <indexterm significance="preferred" type="sql">
+        <primary>DYNAMIC RESULT SETS</primary>
+      </indexterm>
+
+      <simpara><emphasis role="bold">DYNAMIC RESULT SETS</emphasis></simpara>
+
+      <simpara><emphasis>returned result sets
+      characteristic</emphasis></simpara>
+
+      <para>The <literal>&lt;returned result sets characteristic&gt;</literal>
+      is used only for SQL/PSM procedures. The maximum number of result sets
+      that a procedure may return can be specified with the clause below. The
+      default is zero. Details are discussed in the previous sections.</para>
+
+      <simpara><literal>&lt;returned result sets characteristic&gt; ::=
+      DYNAMIC RESULT SETS &lt;maximum returned result
+      sets&gt;</literal></simpara>
+    </section>
+  </section>
+</chapter>
diff --git a/doc-src/guide/texttables.xml b/doc-src/guide/texttables.xml
new file mode 100644
index 0000000..69d0419
--- /dev/null
+++ b/doc-src/guide/texttables.xml
@@ -0,0 +1,474 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="texttables-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/1999/xhtml"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns2="http://www.w3.org/1999/xlink"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="texttables-title">Text Tables</title>
+
+  <subtitle>Text Tables as a Standard Feature of Hsqldb</subtitle>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Bob</firstname>
+        <surname>Preston</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+
+      <author>
+        <personname><firstname>Fred</firstname>
+        <surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3601 $</releaseinfo>
+
+    <pubdate>$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>HyperSQL</keyword>
+
+      <keyword>HSQLDB</keyword>
+
+      <keyword>SQL</keyword>
+
+      <keyword>Text</keyword>
+
+      <keyword>Tables</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2002-2010 Bob Preston and Fred Toussi. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license. Additional permission is granted to the
+      HSQL Development Group to distribute this document with or without
+      alterations under the terms of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section xml:id="texttables_overview-sect">
+    <title>Overview</title>
+
+    <para>Text Table support for HSQLDB was originally developed by Bob
+    Preston independently from the Project. Subsequently Bob joined the
+    Project and incorporated this feature into version 1.7.0, with a number of
+    enhancements, especially the use of conventional SQL commands for
+    specifying the files used for Text Tables.</para>
+
+    <para>In a nutshell, Text Tables are CSV or other delimited files treated
+    as SQL tables. Any ordinary CSV or other delimited file can be used. The
+    full range of SQL queries can be performed on these files, including
+    SELECT, INSERT, UPDATE and DELETE. Indexes and unique constraints can be
+    set up, and foreign key constraints can be used to enforce referential
+    integrity between Text Tables themselves or with conventional
+    tables.</para>
+
+    <para>The delimited file can be created by the engine, or an existing file
+    can be used.</para>
+
+    <para>HyperSQL with Text Table support is the only comprehensive solution
+    that employs the power of SQL and the universal reach of JDBC to handle
+    data stored in text files.</para>
+  </section>
+
+  <section xml:id="texttables_impl-sect">
+    <title>The Implementation</title>
+
+    <section>
+      <title>Definition of Tables</title>
+
+      <para>Text Tables are defined similarly to conventional tables with the
+      added TEXT keyword:</para>
+
+      <programlisting>    CREATE TEXT TABLE &lt;tablename&gt; (&lt;column definition&gt; [&lt;constraint definition&gt;])</programlisting>
+
+      <para>The table is at first empty and cannot be written to. An
+      additional SET command specifies the file and the separator character
+      that the Text table uses:</para>
+
+      <programlisting>   SET TABLE &lt;tablename&gt; SOURCE &lt;quoted_filename_and_options&gt; [DESC]</programlisting>
+
+      <para>Text Tables cannot be created in <glossterm>mem:</glossterm>
+      (all-in-memory) databases (databases that have no script file).</para>
+    </section>
+
+    <section>
+      <title>Scope and Reassignment</title>
+
+      <itemizedlist>
+        <listitem>
+          <para>A Text table without a file assigned to it is READ ONLY and
+          EMPTY.</para>
+        </listitem>
+
+        <listitem>
+          <para>Reassigning a Text Table definition to a new file has
+          implications in the following areas:</para>
+
+          <orderedlist>
+            <listitem>
+              <para>The user is required to be an administrator.</para>
+            </listitem>
+
+            <listitem>
+              <para>Existing transactions are committed at this point.</para>
+            </listitem>
+
+            <listitem>
+              <para>Constraints, including foreign keys referencing this
+              table, are kept intact. It is the responsibility of the
+              administrator to ensure their integrity.</para>
+            </listitem>
+          </orderedlist>
+
+          <para>The new source file is scanned and indexes are built when it
+          is assigned to the table. At this point any violation of NOT NULL,
+          UNIQUE or PRIMARY KEY constraints are caught and the assignment is
+          aborted. However, foreign key constraints are not checked at the
+          time of assignment or reassignment of the source file.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section>
+      <title>Null Values in Columns of Text Tables</title>
+
+      <itemizedlist>
+        <listitem>
+          <para>Empty fields are treated as NULL. These are fields where there
+          is nothing or just spaces between the separators.</para>
+        </listitem>
+
+        <listitem>
+          <para>Quoted empty strings are treated as empty strings.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section>
+      <title>Configuration</title>
+
+      <para>The default field separator is a comma (,). A different field
+      separator can be specified within the SET TABLE SOURCE statement. For
+      example, to change the field separator for the table mytable to a
+      vertical bar, place the following in the SET TABLE SOURCE statement, for
+      example:</para>
+
+      <informalexample>
+        <programlisting>    SET TABLE mytable SOURCE "myfile;fs=|"</programlisting>
+      </informalexample>
+
+      <para>Since HSQLDB treats CHAR and VARCHAR strings the same, the ability
+      to assign a different separator to the latter is provided. When a
+      different separator is assigned to a VARCHAR, it will terminate any CSV
+      field of that type. For example, if the first field is CHAR, and the
+      second field VARCHAR, and the separator fs has been defined as the pipe
+      (|) and vs as the period (.) then the data in the CSV file for a row
+      will look like:</para>
+
+      <screen>    First field data|Second field data.Third field data</screen>
+
+      <para>This facility in effect offers an extra, special separator which
+      can be used in addition to the global separator. The following example
+      shows how to change the default separator to the pipe (|), VARCHAR
+      separator to the period (.) within a SET TABLE SOURCE statement:</para>
+
+      <informalexample>
+        <programlisting>    SET TABLE mytable SOURCE "myfile;fs=|;vs=."</programlisting>
+      </informalexample>
+
+      <para>HSQLDB also recognises the following special indicators for
+      separators:</para>
+
+      <variablelist>
+        <title>special indicators for separators</title>
+
+        <varlistentry>
+          <term>\semi</term>
+
+          <listitem>
+            <para>semicolon</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\quote</term>
+
+          <listitem>
+            <para>single-quote</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\space</term>
+
+          <listitem>
+            <para>space character</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\apos</term>
+
+          <listitem>
+            <para>apostrophe</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\n</term>
+
+          <listitem>
+            <para>newline - Used as an end anchor (like $ in regular
+            expressions)</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\r</term>
+
+          <listitem>
+            <para>carriage return</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\t</term>
+
+          <listitem>
+            <para>tab</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\\</term>
+
+          <listitem>
+            <para>backslash</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>\u####</term>
+
+          <listitem>
+            <para>a Unicode character specified in hexadecimal</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <para>Furthermore, HSQLDB provides csv file support with three
+      additional boolean options: <varname>ignore_first</varname>,
+      <varname>quoted</varname> and <varname>all_quoted</varname>. The
+      <varname>ignore_first</varname> option (default false) tells HSQLDB to
+      ignore the first line in a file. This option is used when the first line
+      of the file contains column headings. The <varname>all_quoted</varname>
+      option (default false) tells the program that it should use quotes
+      around all character fields when writing to the source file. The
+      <varname>quoted</varname> option (default true) uses quotes only when
+      necessary to distinguish a field that contains the separator character.
+      It can be set to false to prevent the use of quoting altogether and
+      treat quote characters as normal characters. These options may be
+      specified within the <literal>SET TABLE SOURCE</literal>
+      statement:</para>
+
+      <programlisting>    SET TABLE mytable SOURCE "myfile;ignore_first=true;all_quoted=true"</programlisting>
+
+      <para>When the default options <literal>all_quoted=</literal>
+      <literal>false</literal> and <literal>quoted=true</literal> are in
+      force, fields that are written to a line of the csv file will be quoted
+      only if they contain the separator or the quote character. The quote
+      character is doubled when used inside a string. When
+      <literal>all_quoted=false</literal> and <literal>quoted=false</literal>
+      the quote character is not doubled. With this option, it is not possible
+      to insert any string containing the separator into the table, as it
+      would become impossible to distinguish from a separator. While reading
+      an existing data source file, the program treats each individual field
+      separately. It determines that a field is quoted only if the first
+      character is the quote character. It interprets the rest of the field on
+      this basis.</para>
+
+      <para>The character encoding for the source file is<literal> ASCII
+      </literal>by default. To support UNICODE or source files prepared with
+      different encodings this can be changed to <literal>UTF-8</literal> or
+      any other encoding. The default is <literal>encoding=ASCII </literal>and
+      the option <literal>encoding=UTF-8</literal> or other supported
+      encodings can be used.</para>
+
+      <para>Finally, HSQLDB provides the ability to read a text file as READ
+      ONLY, by placing the keyword "DESC" at the end of the SET TABLE SOURCE
+      statement:</para>
+
+      <programlisting>    SET TABLE mytable SOURCE "myfile" DESC</programlisting>
+
+      <para>Text table source files are cached in memory. The maximum number
+      of rows of data that are in memory at any time is controlled by the
+      <varname>textdb.cache_scale</varname> property. The default value for
+      <varname>textdb.cache_scale</varname> is 10 and can be changed by
+      setting the property in the .properties file for the database. The
+      number of rows in memory is calculated as 3*(2**scale), which translates
+      to 3072 rows for the default textdb.cache_scale setting (10). The
+      property can also be set for individual text tables:</para>
+
+      <programlisting>    SET TABLE mytable SOURCE "myfile;ignore_first=true;all_quoted=true;cache_scale=12"</programlisting>
+    </section>
+
+    <section xml:id="disconnecting_text_tables">
+      <title>Disconnecting Text Tables</title>
+
+      <para>Text tables may be <glossterm>disconnected</glossterm> from their
+      underlying data source, i.e. the text file.</para>
+
+      <para>You can explicitly disconnect a text table from its file by
+      issuing the following statement: <programlisting>    SET TABLE mytable SOURCE OFF</programlisting></para>
+
+      <para>Subsequently, <literal>mytable</literal> will be empty and
+      read-only. However, the data source description will be preserved, and
+      the table can be re-connected to it with <programlisting>    SET TABLE mytable SOURCE ON</programlisting></para>
+
+      <para>When a database is opened, if the source file for an existing text
+      table is missing the table remains disconnected from its data source,
+      but the source description is preserved. This allows the missing source
+      file to be added to the directory and the table re-connected to it with
+      the above command.</para>
+
+      <para>Disconnecting text tables from their source has several uses.
+      While disconnected, the text source can be edited outside HSQLDB
+      provided data integrity is respected. When large text sources are used,
+      and several constraints or indexes need to be created on the table, it
+      is possible to disconnect the source during the creation of constraints
+      and indexes and reduce the time it takes to perform the
+      operation.</para>
+    </section>
+  </section>
+
+  <section xml:id="texttables_issues-sect">
+    <title>Text File Usage</title>
+
+    <para>The following information applies to the usage of text
+    tables.</para>
+
+    <itemizedlist>
+      <title>Text File Issues</title>
+
+      <listitem>
+        <para>File locations are restricted to below the directory that
+        contains the database, unless the
+        <varname>textdb.allow_full_path</varname> property is set true as a
+        Java system property. This feature is for security, otherwise an admin
+        database user may be able to open random files.</para>
+      </listitem>
+
+      <listitem>
+        <para>Blank lines are allowed anywhere in the text file, and are
+        ignored.</para>
+      </listitem>
+
+      <listitem>
+        <para>It is possible to define a primary key, identity column, unique,
+        foreign key and check constraints for text tables.</para>
+      </listitem>
+
+      <listitem>
+        <para>When a table source file is used with the<literal>
+        ignore_first=true </literal>option, the first, ignored line is
+        replaced with a blank line after a SHUTDOWN COMPACT, unless the SOURCE
+        HEADER statement has been used.</para>
+      </listitem>
+
+      <listitem>
+        <para>An existing table source file may include CHARACTER fields that
+        do not begin with the quote character but contain instances of the
+        quote character. These fields are read as literal strings.
+        Alternatively, if any field begins with the quote character, then it
+        is interpreted as a quoted string that should end with the quote
+        character and any instances of the quote character within the string
+        is doubled. When any field containing the quote character or the
+        separator is written out to the source file by the program, the field
+        is enclosed in quote character and any instance of the quote character
+        inside the field is doubled.</para>
+      </listitem>
+
+      <listitem>
+        <para>Inserts or updates of CHARACTER type field values are allowed
+        with strings that contains the linefeed or the carriage return
+        character. This feature is disabled when both quoted and all_quoted
+        properties are false.</para>
+      </listitem>
+
+      <listitem>
+        <para>ALTER TABLE commands that add or drop columns or constraints
+        (apart from check constraints) are not supported with text tables that
+        are connected to a source. First use the SET TABLE &lt;name&gt; SOURCE
+        OFF, make the changes, then turn the source ON.</para>
+      </listitem>
+    </itemizedlist>
+  </section>
+
+  <section xml:id="texttables_globalprops-sect">
+    <title>Text File Global Properties</title>
+
+    <itemizedlist>
+      <title>Complete list of supported global properties in *.properties
+      files</title>
+
+      <listitem>
+        <para><varname>textdb.fs</varname></para>
+      </listitem>
+
+      <listitem>
+        <para><varname>textdb.vs</varname></para>
+      </listitem>
+
+      <listitem>
+        <para><varname>textdb.quoted</varname></para>
+      </listitem>
+
+      <listitem>
+        <para><varname>textdb.all_quoted</varname></para>
+      </listitem>
+
+      <listitem>
+        <para><varname>textdb.ignore_first</varname></para>
+      </listitem>
+
+      <listitem>
+        <para><varname>textdb.encoding</varname></para>
+      </listitem>
+
+      <listitem>
+        <para><varname>textdb.cache_scale</varname></para>
+      </listitem>
+
+      <listitem>
+        <para><varname>textdb.allow_full_path</varname></para>
+      </listitem>
+    </itemizedlist>
+  </section>
+
+  <section>
+    <title>Transactions</title>
+
+    <para>Text tables fully support transactions. New or changed rows that
+    have not been committed are not updated in the source file. Therefore the
+    source file always contains committed rows.</para>
+
+    <para>However, text tables are not as resilient to machine crashes as
+    other types of tables. If the crash happens while the text source is being
+    written to, the text source may contain only some of the changes made
+    during a committed transaction. With other types of tables, additional
+    mechanisms ensure the integrity of the data and this situation will not
+    arise.</para>
+  </section>
+</chapter>
diff --git a/doc-src/guide/triggers.xml b/doc-src/guide/triggers.xml
new file mode 100644
index 0000000..000505a
--- /dev/null
+++ b/doc-src/guide/triggers.xml
@@ -0,0 +1,507 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="triggers-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/1999/xhtml"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns2="http://www.w3.org/1999/xlink"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <title xml:id="triggers-title">Triggers</title>
+
+  <info>
+    <authorgroup>
+      <author>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3042 $</releaseinfo>
+
+    <pubdate>$Date: 2009-07-14 17:55:19 +0100 (Tue, 14 Jul 2009) $</pubdate>
+
+    <keywordset>
+      <keyword>Hsqldb</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>SQL</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <section>
+    <title>Overview</title>
+
+    <simpara>Trigger functionality first appeared in SQL:1999. Triggers embody
+    the <emphasis>live database</emphasis> concept, where changes in SQL data
+    can be monitored and acted upon. This means each time a DELETE, UPDATE or
+    INSERT is performed, additional actions are taken by the declared
+    triggers. SQL Standard triggers are <glossterm>imperative</glossterm>
+    while the <glossterm>relational</glossterm> aspects of SQL are
+    <glossterm>declarative</glossterm>. Triggers allow performing an arbitrary
+    transformation of data that is being updated or inserted, or to prevent
+    insert, updated or deletes, or to perform additional operations.</simpara>
+
+    <simpara>Some bad examples of SQL triggers in effect enforce an “integrity
+    constraint” which would better be expressed as a CHECK constraint. A
+    trigger that causes an exception if the value inserted in a column is
+    negative is such an example. A check constraint that declares
+    <literal>CHECK VALUE &gt;= 0</literal> (declarative) is a better way of
+    expressing an integrity constraint than a trigger that throws an exception
+    if the same condition is false.</simpara>
+
+    <simpara>Usage constraints cannot always be expressed by SQL’s integrity
+    constraint statements. Triggers can enforce these constraints. For
+    example, it is may be possible to write a check constraint that prevents
+    data from being added, or modified on weekends. But it is not possible to
+    use a check constraint to prevent deletes. A trigger can be used to
+    enforce the time when each operation is allowed.</simpara>
+
+    <simpara>A trigger can modify the values that are inserted into the
+    database, instead of rejecting them. For example, a badly formatted string
+    can be cleaned up by a trigger before INSERT.</simpara>
+
+    <simpara>Triggers can also perform additional data changes, for example
+    inserting an additional row into a different table for data
+    audits.</simpara>
+
+    <simpara>A trigger is declared to activate when an UPDATE, INSERT or
+    DELETE action is performed on a table. These actions may be direct or
+    indirect. Indirect actions may arise from CASCADE actions of FOREIGN KEY
+    constraints, or from data change statements performed on a VIEW that is
+    based on the table that in.</simpara>
+
+    <simpara>It is possible to declare multiple triggers on a single table.
+    The triggers activate one by one according to the order in which they were
+    defined.</simpara>
+
+    <simpara>A row level trigger allows access to the deleted or inserted
+    rows. For UPDATE actions there is both an old and new version of each row.
+    A trigger can be specified to activate before or after the action has been
+    performed. Triggers that are performed after the action cannot modify the
+    rows that have been modified. These triggers can perform other actions,
+    such as inserting rows into other tables. Triggers that are performed
+    before the action can modify the inserted or updated rows but not the
+    deleted rows.</simpara>
+
+    <simpara>A TRIGGER that is declared on a VIEW, is an INSTEAD OF trigger.
+    This term means when an INSERT, UPDATE or DELETE statement is executed,
+    the trigger action is all that is performed, and no further data change
+    takes place on the VIEW. The trigger action can include all the statements
+    that are necessary to change the data in the tables that underlie the
+    VIEW. With the use of INSTEAD OF triggers a read-only view can effectively
+    become updatable or insertable-into.</simpara>
+  </section>
+
+  <section>
+    <title>Trigger Properties</title>
+
+    <para>A trigger is declared on a specific table or view. Various trigger
+    properties determine when the trigger is executed and how.</para>
+
+    <section>
+      <title>Trigger Event</title>
+
+      <para>The trigger event specifies the type of SQL statement that causes
+      the trigger to execute. Each trigger is specified to execute when an
+      INSERT, DELETE or UPDATE takes place.</para>
+
+      <para>The event can be filtered by two separate means. For all triggers,
+      the WHEN clause can specify a condition against the rows that are the
+      subject of the trigger, together with the data in the database. For
+      example, a trigger can activate when the size of a table becomes larger
+      than a certain amount. Or it can activate when the values in the rows
+      being modified satisfy certain conditions.</para>
+
+      <para>An UPDATE trigger can be declared to execute only when certain
+      columns are the subject of an update statement. For example, a trigger
+      declared as AFTER UPDATE OF (datecolumn) will activate only when the
+      UPDATE statement that is executed includes the column, datecolumn, as
+      one of the columns specified in its SET statements.</para>
+    </section>
+
+    <section>
+      <title>Granularity</title>
+
+      <para>A statement level trigger is performed once for the executed SQL
+      statement and is declared as FOR EACH STATEMENT.</para>
+
+      <para>A row level trigger is performed once for each row that is
+      modified during the execution of an SQL statement and is declared as FOR
+      EACH ROW. Note that an SQL statement can INSERT, UPDATE or DELETE zero
+      or more rows.</para>
+
+      <para>If a statement does not apply to any row, then the trigger is not
+      executed.</para>
+
+      <para>If FOR EACH ROW or FOR EACH STATEMENT is not specified, then the
+      default is FOR EACH STATEMENT.</para>
+
+      <para>The granularity dictates whether the REFERENCING clause can
+      specify OLD ROW, NEW ROW, or OLD TABLE, NEW TABLE.</para>
+
+      <para>A trigger declared as FOR EACH STATEMENT can only be an AFTER
+      trigger.</para>
+    </section>
+
+    <section>
+      <title>Trigger Action Time</title>
+
+      <para>A trigger is executed BEFORE, AFTER or INSTEAD OF the trigger
+      event.</para>
+
+      <para>INSTEAD OF triggers are allowed only when the trigger is declared
+      on a VIEW. With this type of trigger, the event (SQL statement) itself
+      is not executed, only the trigger.</para>
+
+      <para>BEFORE or AFTER triggers are executed just before or just after
+      the execution of the event. For example, just before a row is inserted
+      into a table, the BEFORE trigger is activated, and just after the row is
+      inserted, the AFTER trigger is executed.</para>
+
+      <para>BEFORE triggers can modify the row that is being inserted or
+      updated. AFTER triggers cannot modify rows. They are usually used to
+      perform additional operations, such as inserting rows into other
+      tables.</para>
+
+      <para>A trigger declared as FOR EACH STATEMENT can only be an AFTER
+      trigger.</para>
+    </section>
+
+    <section>
+      <title>References to Rows</title>
+
+      <para>If the old rows or new rows are referenced in the SQL statements
+      in the trigger action, they must have names. The REFERENCING clause is
+      used to give names to the old and new rows. The clause, REFERENCING OLD
+      | NEW TABLE is used for statement level triggers. The clause,
+      REFERENCING OLD | NEW ROW is used for row level triggers. If the old
+      rows or new rows are referenced in the SQL statements in the trigger
+      action, they must have names. In the SQL statements, the columns of the
+      old or new rows are qualified with the specified names.</para>
+    </section>
+
+    <section>
+      <title>Trigger Condition</title>
+
+      <para>The WHEN clause can specify a condition for the columns of the row
+      that is being changed. Using this clause you can simply avoid
+      unnecessary trigger activation for rows that do not need it.</para>
+
+      <para>For UPDATE trigger, you can specify a list of columns of the
+      table. If a list of columns is specified, then if the UPDATE statement
+      does not change the columns with SET clauses, then the trigger is not
+      activated at all.</para>
+    </section>
+
+    <section>
+      <title>Trigger Action in SQL</title>
+
+      <para>The trigger action specifies what the trigger does when it is
+      activated. This is usually written as one or more SQL statements.</para>
+
+      <para>When a row level trigger is activated, there is an OLD ROW, or a
+      NEW ROW, or both. An INSERT statement supplies a NEW ROW row to be
+      inserted into a table. A DELETE statement supplied an OLD ROW be
+      deleted. An UPDATE statement supplies both OLD ROW and NEW ROW that
+      represent the updated rows before and after the update. The REFERENCING
+      clause gives names to these rows, so that the rows can be referenced in
+      the trigger action.</para>
+
+      <para>In the example below, a name is given to the NEW ROW and it is
+      used both in the WHEN clause and in the trigger action SQL to insert a
+      row into a triglog table after each row insert into the testtrig
+      table.</para>
+
+      <programlisting>create trigger trig after insert on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.id &gt; 1)
+   insert into triglog values (newrow.id, newrow.data, 'inserted')
+</programlisting>
+
+      <para>In the example blow, the trigger code modifies the updated data if
+      a condition is true. This type of trigger is useful when the application
+      does not perform the necessary checks and modifications to data.</para>
+
+      <programlisting>create trigger t before update on customer
+   referencing new as newrow for each row
+   begin atomic
+   if length(newrow.firstname ) &gt; 10 then
+   set newrow.firstname = lower(newrow.firstname);
+   end if;
+   end
+</programlisting>
+    </section>
+
+    <section>
+      <title>Trigger Action in Java</title>
+
+      <para>A trigger action can be written as a Java class that implements
+      the org.hsqldb.Trigger interface. This interface has a single method
+      which is called when the trigger is activated, either before or after
+      the event. When the method is called by the engine, it supplies the name
+      of the trigger (as name argument), the name of the table (as table
+      argument), the OLD ROW (as row1 argument) and the NEW ROW (as row2
+      argument). The row1 argument is null for row level INSERT triggers. The
+      row2 argument is null for row level DELETE triggers. For table level
+      triggers, both arguments are null (that is, there is no access to the
+      data). The triggerType argument is one of the constants in the
+      org.hsqldb.Trigger interface which indicate the type of trigger, for
+      example, INSERT_BEFORE_ROW or UPDATE_AFTER_ROW.</para>
+
+      <para>The Java class for the trigger can be reused for several triggers
+      on different tables. The method code can distinguish between the
+      different tables and triggers using the supplied arguments and take
+      appropriate action.</para>
+
+      <programlisting>    fire (int triggerType, String name, String table, Object row1[], Object row2[])
+</programlisting>
+
+      <para>The Java method for a synchronous trigger (see below) can modify
+      the values in row2 in a BEFORE trigger. Such modifications are reflected
+      in the row that is being inserted or updated. Any other modifications
+      are ignored by the engine.</para>
+
+      <para>A Java trigger that uses an instance of
+      <classname>org.hsqldb.Trigger</classname> has two forms, synchronous, or
+      asynchronous (immediate or queued). By default, or when QUEUE 0 is
+      specified, the action is performed immediately by calling the Java
+      method. This is similar to SQL trigger actions. When QUEUE n is
+      specified with n larger than 0, the engine uses a separate thread to
+      execute the Java method, using a queue with the size n. For certain
+      applications, such as real-time systems this allows asynchronous
+      notifications to be sent by the trigger event, without introducing
+      delays in the engine. With asynchronous triggers, an extra parameter,
+      NOWAIT can be used in trigger definition. This overcomes the queue full
+      condition. In this mode, old calls that are still in the queue are
+      discarded one by one and replaced with new calls.</para>
+
+      <para>Java triggers can modify the row data. They should not be used to
+      modify the database, e.g. insert new rows, etc.</para>
+
+      <para>For sample trigger classes and test code see,
+      org.hsqldb.sample.TriggerSample, org.hsqldb.test.TestTriggers,
+      org.hsqldb.test.TriggerClass and the associated text script
+      TestTriggers.txt in /testrun/hsqldb/ directory. In the example below,
+      the trigger is activated only if the update statement includes SET
+      clauses that modify any of the specified columns (c1, c2, c3).
+      Furthermore, the trigger is not activated if the c2 column in the
+      updated row is null.</para>
+
+      <programlisting>create trigger trigbur before update of c1, c2, c3 on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.c2 is not null)
+   call "org.hsqldb.test.TriggerClass"
+</programlisting>
+
+      <para>Java functions can be called from an SQL trigger. So it is
+      possible to define the Java function to perform any external
+      communication that are necessary for the trigger, and use SQL code for
+      checks and alterations to data.</para>
+
+      <programlisting>create trigger t before update on customer
+   referencing new as newrow for each row
+   begin atomic
+   if length(newrow.firstname ) &gt; 10 then
+   call my_java_function(newrow.firstname, newrow.lastname);
+   end if;
+   end
+</programlisting>
+    </section>
+  </section>
+
+  <section>
+    <title>Trigger Creation</title>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>CREATE TRIGGER</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">CREATE TRIGGER</emphasis></simpara>
+
+    <simpara><emphasis>trigger definition</emphasis></simpara>
+
+    <simpara><literal>&lt;trigger definition&gt; ::= CREATE TRIGGER
+    &lt;trigger name&gt; &lt;trigger action time&gt; &lt;trigger event&gt; ON
+    &lt;table name&gt; [BEFORE &lt;other trigger name&gt;] [ REFERENCING
+    &lt;transition table or variable list&gt; ] &lt;triggered
+    action&gt;</literal></simpara>
+
+    <simpara><literal>&lt;trigger action time&gt; ::= BEFORE | AFTER | INSTEAD
+    OF</literal></simpara>
+
+    <simpara><literal>&lt;trigger event&gt; ::= INSERT | DELETE | UPDATE [ OF
+    &lt;trigger column list&gt; ]</literal></simpara>
+
+    <simpara><literal>&lt;trigger column list&gt; ::= &lt;column name
+    list&gt;</literal></simpara>
+
+    <simpara><literal>&lt;triggered action&gt; ::= [ FOR EACH { ROW |
+    STATEMENT } ] [ &lt;triggered when clause&gt; ] &lt;triggered SQL
+    statement&gt;</literal></simpara>
+
+    <simpara><literal>&lt;triggered when clause&gt; ::= WHEN &lt;left
+    paren&gt; &lt;search condition&gt; &lt;right paren&gt;</literal></simpara>
+
+    <simpara><literal>&lt;triggered SQL statement&gt; ::= &lt;SQL procedure
+    statement&gt; | BEGIN ATOMIC { &lt;SQL procedure statement&gt;
+    &lt;semicolon&gt; }... END | [QUEUE &lt;integer literal&gt;] [NOWAIT] CALL
+    &lt;HSQLDB trigger class FQN&gt;</literal></simpara>
+
+    <simpara><literal>&lt;transition table or variable list&gt; ::=
+    &lt;transition table or variable&gt;...</literal></simpara>
+
+    <simpara><literal>&lt;transition table or variable&gt; ::= OLD [ ROW ] [
+    AS ] &lt;old transition variable name&gt; | NEW [ ROW ] [ AS ] &lt;new
+    transition variable name&gt; | OLD TABLE [ AS ] &lt;old transition table
+    name&gt; | NEW TABLE [ AS ] &lt;new transition table
+    name&gt;</literal></simpara>
+
+    <simpara><literal>&lt;old transition table name&gt; ::= &lt;transition
+    table name&gt;</literal></simpara>
+
+    <simpara><literal>&lt;new transition table name&gt; ::= &lt;transition
+    table name&gt;</literal></simpara>
+
+    <simpara><literal>&lt;transition table name&gt; ::=
+    &lt;identifier&gt;</literal></simpara>
+
+    <simpara><literal>&lt;old transition variable name&gt; ::= &lt;correlation
+    name&gt;</literal></simpara>
+
+    <simpara><literal>&lt;new transition variable name&gt; ::= &lt;correlation
+    name&gt;</literal></simpara>
+
+    <simpara>Trigger definition is a relatively complex statement. The
+    combination of <literal>&lt;trigger action time&gt;</literal> and
+    <literal>&lt;trigger event&gt;</literal> determines the type of the
+    trigger. Examples include BEFORE DELETE, AFTER UPDATE, INSTEAD OF INSERT.
+    If the optional <literal>[ OF &lt;trigger column list&gt; ]</literal> is
+    specified for an UPDATE trigger, then the trigger is activated only if one
+    of the columns that is in the <literal>&lt;trigger column
+    list&gt;</literal> is specified in the UPDATE statement that activates the
+    trigger.</simpara>
+
+    <simpara>If a trigger is <literal>FOR EACH ROW</literal>, which is the
+    default option, then the trigger is activated for each row of the table
+    that is affected by the execution of an SQL statement. Otherwise, it is
+    activated once only per statement execution. In the first case, there is a
+    before and after state for each row. For UPDATE triggers, both before and
+    after states exist, representing the row before the update, and after the
+    update. For DELETE, triggers, there is only a before state. For INSERT
+    triggers, there is only an after state. If a trigger is <literal>FOR EACH
+    STATEMENT</literal>, then a transient table is created containing all the
+    rows for the before state and another transient table is created for the
+    after state.</simpara>
+
+    <simpara>The <literal>[ REFERENCING &lt;transition table or variable&gt;
+    ]</literal> is used to give a name to the before and after data row or
+    table. This name can be referenced in the <literal>&lt;SQL procedure
+    statement&gt;</literal> to access the data.</simpara>
+
+    <simpara>The optional <literal>&lt;triggered when clause&gt;</literal> is
+    a search condition, similar to the search condition of a DELETE or UPDATE
+    statement. If the search condition is not TRUE for a row, then the trigger
+    is not activated for that row.</simpara>
+
+    <simpara>The <literal>&lt;SQL procedure statement&gt;</literal> is limited
+    to INSERT, DELETE, UPDATE and MERGE statements.</simpara>
+
+    <simpara>The <literal>&lt;HSQLDB trigger class FQN&gt;</literal> is a
+    delimited identifer that contains the fully qualified name of a Java class
+    that implements the <classname>org.hsqldb.Trigger</classname>
+    interface.</simpara>
+
+    <simpara>Early releases of HyperSQL version 2.0 do not allow the use of
+    OLD TABLE or NEW TABLE in statement level triggers.</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TRIGGERED SQL STATEMENT</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TRIGGERED SQL
+    STATEMENT</emphasis></simpara>
+
+    <simpara><emphasis>triggered SQL statement</emphasis></simpara>
+
+    <simpara><literal>The &lt;triggered SQL statement&gt;</literal> has three
+    forms.</simpara>
+
+    <simpara>The first form is a single SQL procedure statement. This
+    statement can reference the OLD ROW and NEW ROW variables. For example, it
+    can reference these variables and insert a row into a separate
+    table.</simpara>
+
+    <simpara>The second form is enclosed in a BEGIN ... END block and can
+    include one or more SQL procedure statements. In BEFORE triggers, you can
+    include SET statements to modify the inserted or updated rows. In AFTER
+    triggers, you can include INSERT, DELETE and UPDATE statements to change
+    the data in other database tables. SELECT and CALL statements are allowed
+    in BEFORE and AFTER triggers. CALL statements in BEFORE triggers should
+    not modify data.</simpara>
+
+    <simpara>The third form specifies a call to a Java method.</simpara>
+
+    <simpara>An example of a trigger with a block is given below. The block
+    can include elements discussed the <link endterm="sqlroutines-title"
+    ns2:href="#sqlroutines-chapt" ns2:title=""></link> chapter, including
+    local variables, loops and conditionals. You can also raise an exception
+    in such blocks in order to terminate the execution of the SQL statement
+    that caused the trigger to execute.</simpara>
+
+    <programlisting>create trigger trig after insert on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.id &gt; 1)
+   begin atomic
+   insert into triglog values (newrow.id, newrow.data, 'inserted');
+   /* more statements can be included */
+   end
+</programlisting>
+
+    <simpara></simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>TRIGGER EXECUTION ORDER</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">TRIGGER EXECUTION
+    ORDER</emphasis></simpara>
+
+    <simpara><emphasis>trigger execution order</emphasis></simpara>
+
+    <simpara><literal>&lt;trigger execution order&gt; ::= BEFORE &lt;other
+    trigger name&gt;</literal></simpara>
+
+    <simpara>HyperSQL extends the SQL Standard to allow the order of execution
+    of a trigger to be specified by using [BEFORE &lt;other trigger name&gt;]
+    in the definition. The newly defined trigger will be executed before the
+    specified other trigger. If this clause is not used, the new trigger is
+    executed after all the previously defined triggers of the same scope
+    (BEFORE, AFTER, EACH ROW, EACH STATEMENT).</simpara>
+
+    <indexterm significance="preferred" type="sql">
+      <primary>DROP TRIGGER</primary>
+    </indexterm>
+
+    <simpara><emphasis role="bold">DROP TRIGGER</emphasis></simpara>
+
+    <simpara><emphasis>drop trigger statement</emphasis></simpara>
+
+    <simpara><literal>&lt;drop trigger statement&gt; ::= DROP TRIGGER
+    &lt;trigger name&gt;</literal></simpara>
+
+    <simpara>Destroy a trigger.</simpara>
+  </section>
+</chapter>
diff --git a/doc-src/guide/unix.xml b/doc-src/guide/unix.xml
new file mode 100644
index 0000000..2f61401
--- /dev/null
+++ b/doc-src/guide/unix.xml
@@ -0,0 +1,768 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: unix.xml 3360 2009-12-16 15:03:31Z unsaved $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+]>
+<chapter version="5.0" xml:id="unix-chapt"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/2000/svg"
+         xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns3="http://www.w3.org/1999/xhtml"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <info>
+    <title xml:id="unix-title">HyperSQL on UNIX</title>
+
+    <subtitle>How to quickly get a HyperSQL (aka HSQLDB) Listener up and
+    running on UNIX, including Mac OS X</subtitle>
+
+    <author>
+      <personname><firstname>Blaine</firstname>
+      <surname>Simpson</surname></personname>
+
+      <affiliation>
+        <orgname>The HSQL Development Group</orgname>
+      </affiliation>
+    </author>
+
+    <releaseinfo>$Revision: 3360 $</releaseinfo>
+
+    <pubdate>$Date: 2009-12-16 10:03:31 -0500 (Wed, 16 Dec 2009) $</pubdate>
+
+    <keywordset>
+      <keyword>HSQLDB</keyword>
+
+      <keyword>HyperSQL</keyword>
+
+      <keyword>UNIX</keyword>
+
+      <keyword>Linux</keyword>
+
+      <keyword>HOWTO</keyword>
+    </keywordset>
+  </info>
+
+  <section xml:id="unix_purpose-sect">
+    <title>Purpose</title>
+
+    <simpara>This chapter explains how to quickly install, run, and use a
+    HyperSQL Listener (aka Server) on UNIX.</simpara>
+
+    <simpara>Note that, unlike a traditional database server, there are many
+    use cases
+    where it makes sense to run HyperSQL without any listener. This type of
+    setup is called <glossterm>in-process</glossterm>, and is not covered
+    here, since there is no UNIX-specific setup in that case.</simpara>
+
+    <simpara>I intend to cover what I think is the most common
+    UNIX setup: To run a multi-user, externally-accessible catalog with
+    permanent data persistence. (By the latter I mean that data is stored to
+    disk so that the catalog data will persist across process shutdowns and
+    startups). I also cover how to run the Listener as a system
+    daemon.</simpara>
+
+    <simpara>When I give sample shell commands below, I use commands which
+    will work in Bourne-compatible shells, including Bash and Korn. Users who
+    insist on using the inferior C-shells will need to convert.</simpara>
+  </section>
+
+  <section xml:id="unix_install-sect">
+    <title>Installation</title>
+
+    <simpara>Go to <link
+    xlink:href="http://sourceforge.net/projects/hsqldb"></link> and click on
+    the "files" link. You want the current version. I can't be more specific
+    because SourceForge/Geeknet are likely to continue changing their
+    interface. See if there's a distribution for the current HSQLDB version in
+    the format that you want.</simpara>
+
+    <simpara>If you want a binary package and we either don't provide it, or
+    you prefer somebody else's build, you should still find out the current
+    version of HyperSQL available at SourceForge. It's very
+    likely that you can find a binary package for your UNIX variant with your
+    OS distributor, <link xlink:href="http://www.jpackage.org/"></link>, <link
+    xlink:href="http://sunfreeware.com/"></link>, etc. Nowadays, most UNIXes
+    have software package management systems which check Internet
+    repositories. Just search the repositories for "hsqldb" and "hypersql".
+    The challenge is to find an <emphasis>up-to-date</emphasis> package. You
+    will get better features and support if you work with the current stable
+    release of HyperSQL. (In particular, HyperSQL version 2.0.0 added tons of
+    new features). Pay attention to what JVM versions your binary package
+    supports. Our builds (version 2.0 and later) document the Java version it
+    was built with in the file <filename>doc/index.html</filename>, but you
+    can't depend on this if somebody else assembled your distribution. Java
+    jar files are generally compatible with the same or greater major
+    versions. For example,if your <filename>hsqldb.jar</filename> was built
+    with Java 1.3.6-11, then it is compatible with Java versions 1.3.* and
+    greater.</simpara>
+
+    <note>
+      <simpara>It could very well happen that some of the file formats which I
+      discuss below are not in fact offered. If so, then we have not gotten
+      around to building them.</simpara>
+    </note>
+
+    <simpara>Binary installation depends on the package format that you
+    downloaded.</simpara>
+
+    <variablelist>
+      <varlistentry>
+        <term>Installing from a .pkg.Z file</term>
+
+        <listitem>
+          <para>This package is only for use by a Solaris super-user. It's a
+          System V package. Download then uncompress the package with
+          uncompress or gunzip <informalexample>
+              <screen>    uncompress filename.pkg.Z</screen>
+            </informalexample> You can read about the package by running
+          <informalexample>
+              <screen>    pkginfo -l -d filename.pkg</screen>
+            </informalexample> Run pkgadd as root to install.</para>
+
+          <informalexample>
+            <screen>
+    pkgadd -d filename.pkg</screen>
+          </informalexample>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>Installing from a BSD Port or Package</term>
+
+        <listitem>
+          <simpara>You're on your own. I find everything much easier when I
+          install software to BSD without their package management
+          systems.</simpara>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>Installing from a .rpm file</term>
+
+        <listitem>
+          <para>Just skip this section if you know how to install an RPM. If
+          you found the RPM using a software management system, then just have
+          it install it. The remainder of item explains a generic command-line
+          method which should work with any Linux variant. After you download
+          the rpm, you can read about it by running <informalexample>
+              <screen>    rpm -qip /path/to/file.rpm</screen>
+            </informalexample></para>
+
+          <para>Rpms can be installed or upgraded by running <informalexample>
+              <screen>    rpm -Uvh /path/to/file.rpm</screen>
+            </informalexample> as root. Suse users may want to keep Yast aware
+          of installed packages by running rpm through Yast: <literal>yast2 -i
+          /path/to/file.rpm</literal>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>Installing from a .zip file</term>
+
+        <listitem>
+          <simpara>Extract the zip file in an ancestor directory of the new
+          HSQLDB home. You don't need to create the
+          <varname>HSQLDB_HOME</varname> directory because the extraction will
+          create a version-labelled directory, and the subdirectory "hsqldb".
+          This "hsqldb" directory is your <varname>HSQLDB_HOME</varname>, and
+          you can move it to wherever you wish. If you will be upgrading or
+          maintaining multiple versions of HyperSQL, you will want to retain
+          the version number in the directory tree somehow.</simpara>
+
+          <informalexample>
+            <screen>    cd ancestor/of/new/hsqldb/home
+    unzip /path/to/file.zip</screen>
+          </informalexample>
+
+          <simpara>All the files in the zip archive will be extracted to
+          underneath a new subdirectory named like
+          <filename>hsqldb-2.0.2a/hsqldb</filename>.</simpara>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <simpara>Take a look at the files you installed. (Under
+    <filename>hsqldb</filename> for zip file installations. Otherwise, use the
+    utilities for your packaging system). The most important file of the
+    HyperSQL system is <filename>hsqldb.jar</filename>, which resides in the
+    subdirectory <filename>lib</filename>.
+    Depending on who built your distribution, your file name may have a
+    version label in it, like <filename>hsqldb-1.2.3.4.jar</filename>.
+    </simpara>
+
+    <important>
+      <simpara>For the purposes of this chapter, I define
+      <varname>HSQLDB_HOME</varname> to be the parent directory of the lib
+      directory that contains <filename>hsqldb.jar</filename>. E.g., if your
+      path to <filename>hsqldb.jar</filename> is
+      <filename>/a/b/hsqldb/lib/hsqldb.jar</filename>, then your
+      <varname>HSQLDB_HOME</varname> is
+      <filename>/a/b/hsqldb</filename>.</simpara>
+
+      <simpara>Furthermore, unless I state otherwise, all local file paths
+      that I give are relative to the
+      <varname>HSQLDB_HOME</varname>.</simpara>
+    </important>
+
+    <simpara>If the description of your distribution says that the
+    <filename>hsqldb.jar</filename> file will work for your Java version, then
+    you are finished with installation. Otherwise you need to build a new
+    <filename>hsqldb.jar</filename> file.</simpara>
+
+    <simpara>If you followed the instructions above and you still don't know
+    what Java version your <filename>hsqldb.jar</filename> supports, then try
+    reading documentation files like <filename>readme.txt</filename>,
+    <filename>README.TXT</filename>, <filename>INSTALL.txt</filename> etc. (As
+    I said above, our newer distributions always document the Java version for
+    the build, in the file <filename>doc/index.html</filename>). If that still
+    doesn't help, then you can just try your <filename>hsqldb.jar</filename>
+    and see if it works, or build your own.</simpara>
+
+    <simpara>To use the supplied <filename>hsqldb.jar</filename>, just skip to
+    the <link xlink:href="#unix_cat_setup-sect"> next section of this
+    document</link>. Otherwise build a new
+    <filename>hsqldb.jar</filename>.</simpara>
+
+    <procedure>
+      <title>Building hsqldb.jar</title>
+
+      <step>
+        <para>If you don't already have Ant, download the latest stable binary
+        version from <link xlink:href="http://ant.apache.org"></link>. cd to
+        where you want Ant to live, and extract from the archive with
+        <informalexample>
+            <screen>    unzip /path/to/file.zip</screen>
+          </informalexample>or<informalexample>
+            <screen>    tar -xzf /path/to/file.tar.gz</screen>
+          </informalexample>or<informalexample>
+            <screen>    bunzip2 -c /path/to/file.tar.bz2 | tar -xzf -</screen>
+          </informalexample> Everything will be installed into a new
+        subdirectory named <filename>apache-ant- + version</filename>. You can
+        rename the directory after the extraction if you wish.</para>
+      </step>
+
+      <step>
+        <para>Set the environmental variable <varname>JAVA_HOME</varname> to
+        the base directory of your Java JRE or SDK, like <informalexample>
+            <screen>    export JAVA_HOME; JAVA_HOME=/usr/java/j2sdk1.4.0</screen>
+          </informalexample> The location is entirely dependent upon your
+        variety of UNIX. Sun's rpm distributions of Java normally install to
+        <filename>/usr/java/something</filename>. Sun's System V package
+        distributions of Java (including those that come with Solaris)
+        normally install to <filename>/usr/something</filename>, with a
+        sym-link from <filename>/usr/java</filename> to the default version
+        (so for Solaris you will usually set JAVA_HOME to
+        <filename>/usr/java</filename>).</para>
+      </step>
+
+      <step>
+        <simpara>Remove the existing file <varname>HSQLDB_HOME</varname>
+        <filename>/lib/hsqldb.jar</filename>.</simpara>
+      </step>
+
+      <step>
+        <para>cd to <varname>HSQLDB_HOME</varname><filename>/build</filename>.
+        Make sure that the bin directory under your Ant home is in your search
+        path. Run the following command. <informalexample>
+            <screen>    ant hsqldb</screen>
+          </informalexample> This will build a new
+        <varname>HSQLDB_HOME</varname><filename>/lib/hsqldb.jar</filename>.</para>
+      </step>
+    </procedure>
+
+    <simpara>See the <link endterm="building-title"
+    xlink:href="#building-app"></link> appendix if you want to build anything
+    other than <filename>hsqldb.jar</filename> with all default
+    settings.</simpara>
+  </section>
+
+  <section xml:id="unix_cat_setup-sect">
+    <title>Setting up a HyperSQL Persistent Database Catalog and a HyperSQL
+    Network Listener</title>
+
+    <titleabbrev>Setting up Database Catalog and Listener</titleabbrev>
+
+    <simpara>If you installed from an OS-specific package, you may already
+    have a catalog and listener pre-configured. See if your package includes a
+    file named <filename>server.properties</filename> (make use of your
+    packaging utilities). If you do, then I suggest that you still read this
+    section while you poke around, in order to understand your
+    setup.</simpara>
+
+    <procedure>
+      <step>
+        <simpara>Select a UNIX user to run the database process (JVM) as. If
+        this database is for the use of multiple users, or is a production
+        system (or to emulate a production system), you should dedicate a UNIX
+        user for this purpose. In my examples, I use the user name
+        <literal>hsqldb</literal>. In this chapter, I refer to this user as
+        the <varname>HSQLDB_OWNER</varname>, since that user will own the
+        database catalog files and the JVM processes.</simpara>
+
+        <para>If the account doesn't exist, then create it. On all system-5
+        UNIXes and most hybrids (including Linux), you can run (as root)
+        something like <informalexample>
+            <screen>    useradd -c 'HSQLDB Database Owner' -s /bin/bash -m hsqldb</screen>
+          </informalexample> (BSD-variant users can use a similar <literal>pw
+        useradd hsqldb...</literal> command).</para>
+      </step>
+
+      <step>
+        <simpara>Become the <varname>HSQLDB_OWNER</varname>. Copy the sample
+        file <filename xlink:href="#server.properties-link">
+        sample/server.properties</filename> to the
+        <varname>HSQLDB_OWNER</varname>'s home directory and rename it to
+        <filename>server.properties</filename>. (As a final reminder,
+        "sampleserver.properties" is a relative path, so it is understood to
+        be relative to your <varname>HSQLDB_HOME</varname>).</simpara>
+
+        <programlisting><xi:include encoding="ISO-8859-1"
+            href="../verbatim/sample/server.properties" parse="text" /></programlisting>
+
+        <simpara>Since the value of the first database
+        (<property>server.database.0</property>) begins with
+        <glossterm>file:</glossterm>, the catalog will be persisted to a set
+        of files in the specified directory with names beginning with the
+        specified name. Set the path to whatever you want (relative paths will
+        be relative to the directory containing the properties file). You can
+        read about how to specify other catalogs of various types, and how to
+        make settings for the listen port and many other things in other
+        chapters of this guide.</simpara>
+      </step>
+
+      <step>
+        <para>Set and export the environmental variable
+        <varname>CLASSPATH</varname> to the value of
+        <varname>HSQLDB_HOME</varname> (as described above) plus
+        "/lib/hsqldb.jar", like <informalexample>
+            <screen>    export CLASSPATH; CLASSPATH=/path/to/hsqldb/lib/hsqldb.jar</screen>
+          </informalexample> In <varname>HSQLDB_OWNER</varname>'s home
+        directory, run</para>
+
+        <informalexample>
+          <screen>    nohup java org.hsqldb.server.Server &amp;</screen>
+        </informalexample>
+
+        <simpara>This will start the Listener process in the background, and
+        will create your new database catalog "db0". Continue on when you see
+        the message containing <literal>HSQLDB server... is online</literal>.
+        <literal>nohup</literal> just makes sure that the command will not
+        quit when you exit the current shell (omit it if that's what you want
+        to do).</simpara>
+      </step>
+    </procedure>
+  </section>
+
+  <section xml:id="unix_access-sect">
+    <title>Accessing your Database</title>
+    <simpara>
+      We're going to use SqlTool to access the database, so you will need the
+      file <filename>sqltool.jar</filename> in addition to
+      <filename>hsqldb.jar</filename>.
+      If <filename>sqltool.jar</filename> isn't already sitting there beside
+      <filename>hsqldb.jar</filename> (they both come pre-built), build it
+      exactly as you would build <filename>hsqldb.jar</filename>, except use
+      ant target <literal>sqltool</literal>.
+      If your distribution came with a sqltool jar file with a version label,
+      like <filename>sqltool-1.2.3.4.jar</filename>, that's fine-- use that
+      file whenever I say <filename>sqltool.jar</filename> below.
+    </simpara>
+
+    <simpara>Copy the file <filename
+    xlink:href="#sqltool.rc-link">sample/sqltool.rc</filename> to the
+    <varname>HSQLDB_OWNER</varname>'s home directory. Use
+    <literal>chmod</literal> to make the file readable and writable only to
+    <varname>HSQLDB_OWNER</varname>.</simpara>
+
+    <programlisting><xi:include href="../verbatim/sample/sqltool.rc"
+        parse="text" /></programlisting>
+
+    <simpara>We will be using the "localhost-sa" sample urlid definition from
+    the config file. The JDBC URL for this urlid is
+    <literal>jdbc:hsqldb:hsql://localhost</literal>. That is the URL for the
+    default catalog of a HyperSQL Listener running on the default port of the
+    local host. You can read about URLs to connect to other catalogs with and
+    without listeners in other chapters of this guide.</simpara>
+
+    <para>Run <classname>SqlTool</classname>. <informalexample>
+        <screen>    java -jar path/to/sqltool.jar localhost-sa</screen>
+      </informalexample> If you get a prompt, then all is well. If security is
+    of any concern to you at all, then you should change the privileged
+    password in the database. Use the command <literal
+    xlink:href="#set_password-sql">SET PASSWORD</literal> command to change
+    SA's password. <informalexample>
+        <programlisting>    SET PASSWORD 'newpassword';</programlisting>
+      </informalexample>
+    Set a <emphasis>strong</emphasis> password!
+    </para>
+    <note><simpara>
+        If, like most UNIX System Administrators, you often need to make up
+        strong passwords, I highly suggest the great little program
+        <filename xlink:href="https://sourceforge.net/projects/pwgen/">pwgen</filename>.
+        You can probably get it where you get your other OS packages.
+        The command <literal>pwgen -1</literal> is usually all you need.
+    </simpara></note>
+
+    <simpara>Note that with SQL-conformant databases like HyperSQL 2.0, user
+    names and passwords are case sensitive. If you don't quote the name, it
+    will be interpreted as upper-case, like any named SQL object. (Only for
+    backwards compatibility, we do make an exception for the special user name
+    SA, but you should always use upper-case "SA" nevertheless).</simpara>
+
+    <simpara>When you're finished playing, exit with the command
+    <literal>\q</literal>.</simpara>
+
+    <simpara>If you changed the SA password, then you need to update the
+    password in the <filename>sqltool.rc</filename> file accordingly.</simpara>
+
+    <simpara>You can, of course, also access the database with any JDBC client
+    program.
+    You will need to modify your classpath to include
+    <filename>hsqldb.jar</filename> as well as your client class(es). You can
+    also use the other HSQLDB client programs, such as
+    <classname>org.hsqldb.util.DatabasManagerSwing</classname>, a graphical
+    client with a similar purpose to <classname>SqlTool</classname>.</simpara>
+
+    <simpara>You can use any normal UNIX account to run the JDBC clients,
+    including <classname>SqlTool</classname>, as long as the account has read
+    access to the <filename>sqltool.jar</filename> file and to an
+    <filename>sqltool.rc</filename> file. See the Utilities Guide about where
+    to put <filename>sqltool.rc</filename>, how to execute sql files, and
+    other <classname>SqlTool</classname> features.</simpara>
+  </section>
+
+  <section xml:id="unix_addl_accts-sect">
+    <title>Create additional Accounts</title>
+
+    <simpara>Connect to the database as SA (or any other Administrative user)
+    and run <literal xlink:href="#create_user-sql">CREATE USER</literal> to
+    create new accounts for your catalog. HSQLDB accounts are
+    database-catalog-specific, not
+    <classname>Listener</classname>-specific.</simpara>
+
+    <simpara>In SQL-compliant databases, all database objects are created in a
+    <emphasis>schema</emphasis>. If you don't specify a schema, then the new
+    object will be created in the default schema. To create a database object,
+    your account (the account that you connected with) must have the role
+    <literal>DBA</literal>, or your account must have authorization for the
+    target schema (see the CREATE SCHEMA command about this last). When you
+    first create a HyperSQL catalog, it has only one database user-- SA, a DBA
+    account, with an empty string password. You should set a password (as
+    described above). You can create as many additional users as you wish. To
+    make a user a DBA, you can use the "ADMIN" option to the <literal
+    xlink:href="#create_user-sql">CREATE USER</literal> command, command, or
+    GRANT the DBA Role to the account after creating it.</simpara>
+
+    <simpara>Once an object is created, the object creator and users with the
+    DBA role will have all privileges to work with that object. Other users
+    will have only the rights which the pseudo-user PUBLIC has. To give
+    specific users more permissions, even rights to read objects, you can
+    GRANT permissions for specific objects, grant Roles (which encompass a set
+    of permissions), or grant the DBA Role itself.</simpara>
+
+    <simpara>Since only people with a database account may do anything at all
+    with the database, it is often useful to permit other database users to
+    view the data in your tables. To optimize performance, reduce contention,
+    and minimize administration, it is often best to grant SELECT to PUBLIC on
+    table-like objects that need to be accessed by multiple database users,
+    with the significant exception of any data which you want to keep secret.
+    (Similary with EXECUTE priv for routines and USAGE priv for other object
+    types).
+    Note that this is not at all equivalent to giving the world or the Internet
+    read access to your tables-- you are giving read access to people that have
+    been given accounts for the target database catalog.
+    </simpara>
+  </section>
+
+  <section xml:id="unix_shutdown-sect">
+    <title>Shutdown</title>
+
+    <para>Do a clean database shutdown when you are finished with the database
+    catalog. You need to connect up as SA or some other Admin user, of course.
+    With SqlTool, you can run <informalexample>
+        <screen>    java -jar path/to/sqltool.jar --sql 'shutdown;' localhost-sa</screen>
+      </informalexample> You don't have to worry about stopping the
+    <classname>Listener</classname> because it shuts down automatically when
+    all served database catalogs are shut down.</para>
+  </section>
+
+  <section xml:id="unix_daemon-sect">
+    <title>Running Hsqldb as a System Daemon</title>
+
+    <indexterm significance="preferred">
+      <primary>init script</primary>
+    </indexterm>
+
+    <simpara>You can, of course, run HSQLDB through inittab on System V
+    UNIXes, but usually an init script is more convenient and manageable. This
+    section explains how to set up and use our UNIX init script. Our init
+    script is only for use by root. (That is not to say that the
+    <emphasis>Listener</emphasis> will run as root-- it usually should
+    not).</simpara>
+
+    <simpara>The main purpose of the init script is to start up a Listener for
+    the database catalogs specified in your
+    <filename>server.properties</filename> file; and to gracefully shut down
+    these same catalogs. For each catalog defined by a
+    <varname>server.database.X</varname> setting in your .properties file, you
+    must define an administrative "urlid" in your
+    <filename>sqltool.rc</filename> (these are used to access the catalogs for
+    validation and shutdown purposes). Finally, you list the urlid names in
+    your init script config file. If, due to firewall issues, you want to run
+    a WebServer instead of a Server, then make sure you have a healthy
+    WebServer with a webserver.properties set up, adjust your URLs in
+    <filename>sqltool.rc</filename>, and set TARGET_CLASS in the config
+    file.</simpara>
+
+    <simpara>By following the commented examples in the config file, you can
+    start up any number of Server and/or WebServer listener instances with or
+    without TLS encryption, and each listener instance can serve any number of
+    HyperSQL catalogs (independent data sets), all with optimal efficiency
+    from a single JVM process. There are instructions in the init script
+    itself about how to run multiple, independently-configured JVM processes.
+    Most UNIX installations, however, will run a single JVM with a single
+    Listener instance which serves multiple catalogs, for easier management
+    and more efficient resource usage.</simpara>
+
+    <simpara>After you have the init script set up, root can use it anytime to
+    start or stop HSQLDB. (I.e., not just at system bootup or
+    shutdown).</simpara>
+
+    <section>
+      <title>Portability of <filename>hsqldb</filename> init script</title>
+
+      <simpara>The primary design criterion of the init script is portability.
+      It does not print pretty color startup/shutdown messages as is common in
+      late-model Linuxes and HPUX; and it does not keep subsystem state files
+      or use the startup/shutdown functions supplied by many UNIXes, because
+      these features are all non-portable.</simpara>
+
+      <simpara>Offsetting these limitations, this one script does it's
+      intended job great on the UNIX varieties I have tested, and can easily
+      be modified to accommodate other UNIXes. While you don't have tight
+      integration with OS-specific daemon administration guis, etc., you do
+      have a well tested and well behaved script that gives good, utilitarian
+      feedback.</simpara>
+    </section>
+
+    <section>
+      <title>Init script Setup Procedure</title>
+
+      <simpara>The strategy taken here is to get the init script to run your
+      single Server or WebServer first (as specified by TARGET_CLASS). After
+      that's working, you can customize the JVM that is run by running
+      additional Listener instances in it, running your own application in it
+      (embedding), or even overriding HSQLDB behavior with your own overriding
+      classes.</simpara>
+
+      <procedure>
+        <step>
+          <simpara>Copy the init script <filename
+          xlink:href="#hsqldb.init-link"> sample/hsqldb.init</filename> to
+          <filename>hsqldb</filename> in the directory where init scripts live
+          on your variety of UNIX. The most common locations are
+          <filename>/etc/init.d</filename> or
+          <filename>/etc/rc.d/init.d</filename> on System V style UNIXes,
+          <filename>/usr/local/etc/rc.d</filename> on BSD style UNIXes, and
+          <filename>/Library/StartupItems/hsqldb</filename> on OS X (you'll
+          need to create the directory for the last).</simpara>
+        </step>
+
+        <step>
+          <para>View your <filename>server.properties</filename> file. Make a
+          note of every catalog define by a
+          <varname>server.database.X</varname> setting. A couple steps down,
+          you will need to set up administrative access for each of these
+          catalogs. If you are using our sample <filename
+          xlink:href="#server.properties-link"> server.properties</filename>
+          file, you will just need to set up access for the
+          catalog specified with <literal>file:db0/dbo</literal>.</para>
+
+          <note>
+            <simpara>Pre-2.0 versions of the hsqldb init script required use
+            of .properties settings of the
+            form<varname>server.urlid.X</varname>. These settings are obsolete
+            and should be removed.</simpara>
+          </note>
+        </step>
+
+        <step>
+          <simpara>Either copy <varname>HSQLDB_OWNER</varname>'s
+          <filename>sqltool.rc</filename> file into root's home directory, or
+          set the value of <varname>AUTH_FILE</varname> to the absolute path
+          of <varname>HSQLDB_OWNER</varname>'s <filename>sqltool.rc</filename>
+          file. This file is read directly by root, even if you run hsqldb as
+          non-root (by setting <varname>HSQLDB_OWNER</varname> in the config
+          file). If you copy the file, make sure to use
+          <literal>chmod</literal> to restrict permissions on the new copy.
+          The init script will abort with an appropriate exhortation if you
+          have the permissions set incorrectly.</simpara>
+
+          <simpara>You need to set up a urlid stanza in your
+          <filename>sqltool.rc</filename> file for network access (i.e. JDBC
+          URL with hsql:, hsqls:, http:, or https:) for each catalog in your
+          <filename>server.properties</filename> file. For our example, you
+          need to define a stanza for the <literal>file:db0/db0</literal>
+          catalog. You must supply for this catalog, a hsql: JDBC URL, an
+          administrative user name, and the password.</simpara>
+
+          <example>
+            <title>example sqltool.rc stanza</title>
+
+            <programlisting>    urlid localhostdb1
+    url jdbc:hsqldb:hsql://localhost
+    username SA
+    password secret</programlisting>
+          </example>
+        </step>
+
+        <step>
+          <simpara>Look at the comment towards the top of the init script
+          which lists recommended locations for the configuration file for
+          various UNIX platforms. Copy the sample config file <filename
+          xlink:href="#hsqldb.cfg-link">sample/hsqldb.cfg</filename> to one of
+          the listed locations (your choice). Edit the config file according
+          to the instructions in it. For our example, you will set the value
+          of <varname>URLIDS</varname> to <literal>localhostdb1</literal>,
+          since that is the urlid name that we used in the
+          <filename>sqltool.rc</filename> file.</simpara>
+
+          <programlisting><xi:include href="../verbatim/sample/hsqldb.cfg"
+              parse="text" /></programlisting>
+
+          <simpara><emphasis role="bold">Verify that the init script
+          works.</emphasis></simpara>
+
+          <para>Just run <informalexample>
+              <screen>    /path/to/hsqldb</screen>
+            </informalexample> as root to see the arguments you may use.
+          Notice that you can run</para>
+
+          <para><screen>    /path/to/hsqldb status</screen>at any time to see
+          whether your HSQLDB <classname>Listener</classname> is
+          running.</para>
+
+          <simpara>Re-run the script with each of the possible arguments to
+          really test it good. If anything doesn't work right, then see the
+          <link endterm="unix_inittrouble-title"
+          xlink:href="#unix_inittrouble-sect"></link> section.</simpara>
+        </step>
+
+        <step>
+          <simpara>Tell your OS to run the init script upon system startup and
+          shutdown. If you are using a UNIX variant that has
+          <filename>/etc/rc.conf</filename> or
+          <filename>/etc/rc.conf.local</filename> (like BSD variants and
+          Gentoo), you must set "hsqldb_enable" to "YES" in either of those
+          files. (Just run <literal>cd /etc; ls rc.conf
+          rc.conf.local</literal> to see if you have one of these files). For
+          good UNIXes that use System V style init, you must set up hard links
+          or soft links either manually or with management tools (such as
+          <literal>chkconfig</literal> or <literal>insserv</literal>) or Gui's
+          (like run level editors).</simpara>
+
+          <para>This paragraph is for Mac OS X users only. If you followed the
+          instructions above, your init script should reside at
+          <filename>/Library/StartupItems/hsqldb/hsqldb</filename>. Now copy
+          the file <filename>StartupParameters.plist</filename> from the
+          directory <filename>src/org.hsqldb/sample</filename> of your HSQLDB
+          distribution to the same directory as the init script. As long as
+          these two files reside in
+          <filename>/Library/StartupItems/hsqldb</filename>, your init script
+          is active (for portability reasons, it doesn't check for a setting
+          in <filename>/etc/hostconfig</filename>). You can run it as a
+          <emphasis>Startup Item</emphasis> by running <screen>    SystemStarter {start|stop|restart} Hsqldb</screen>
+          Hsqldb is the service name. See the man page for
+          <classname>SystemStarter</classname>. To disable the init script,
+          wipe out the <filename>/Library/StartupItems/hsqldb</filename>
+          directory. Hard to believe, but the Mac people tell me that during
+          system shutdown the Startup Items don't run at all. Therefore, if
+          you don't want your data corrupted, make sure to run "SystemStarter
+          stop Hsqldb" before shutting down your Mac.</para>
+        </step>
+      </procedure>
+
+      <simpara>Follow the examples in the config file to add additional
+      classes to the server JVM's classpath and to execute additional classes
+      in your JVM. (See the <varname>SERVER_ADDL_CLASSPATH</varname> and
+      <varname>INVOC_ADDL_ARGS</varname> items).</simpara>
+    </section>
+
+    <section xml:id="unix_inittrouble-sect">
+      <title xml:id="unix_inittrouble-title">Troubleshooting the Init
+      Script</title>
+
+      <simpara>Definitely look at the init script log file, which is at an
+      OS-sependent location, but is usually at
+      <filename>/var/log/hsqldb.log</filename>.</simpara>
+
+      <simpara>Do a <literal>ps</literal> to look for processes containing the
+      string <literal>hsqldb</literal>, and try to connect to the database
+      from any client. If the init script starts up your database
+      successfully, but incorrectly reports that it has not, then your problem
+      is with specification of urlid(s) or SqlTool setup. If your database
+      really did not start, then skip to the next paragraph. Verify that your
+      config file assigns a urlid for each catalog defined in
+      <filename>server.properties</filename> or
+      <filename>webserver.properties</filename>, then verify that you can run
+      <classname>SqlTool</classname> as root to connect to the catalogs with
+      these urlids. (For the latter test, use the <literal>--rcfile</literal>
+      switch if you are setting <varname>AUTH_FILE</varname> in the init
+      script config file).</simpara>
+
+      <simpara>If your database really is not starting, then verify that you
+      can <literal>su</literal> to the database owner account and start the
+      database. The command
+      <literal>su USERNAME -c ...</literal> won't work on most UNIXes unless
+      the target user has a real login shell. Therefore, if you try to tighten
+      up security by disabling this user's login shell, you will break the
+      init script. If these possibilities don't pan out, then debug the init
+      script or seek help, as described below.</simpara>
+
+      <para>To debug the init script, run it in verbose mode to see exactly
+      what is happening (and perhaps manually run the steps that are suspect).
+      To run an init script (in fact, any sh shell script) in verbose mode,
+      use <literal>sh</literal> with the <literal>-x</literal> or
+      <literal>-v</literal> switch, like <screen>    sh -x path/to/hsqldb start</screen>
+      See the man page for <literal>sh</literal> if you don't know the
+      difference between <literal>-v</literal> and
+      <literal>-x</literal>.</para>
+
+      <para>If you want troubleshooting help, use the HSQLDB lists/forums.
+      Make sure to include the revision number from your
+      <filename>hsqldb</filename> init script (it's towards the top in the
+      line that starts like "# $Id:"), and the output of a run of <screen>    sh -x path/to/hsqldb start &gt; /tmp/hstart.log 2&gt;&amp;1</screen></para>
+    </section>
+  </section>
+
+  <section xml:id="unix_upgrade-sect">
+    <title>Upgrading</title>
+
+    <simpara>This section is for users who are using our UNIX init script, and
+    who are upgrading their HyperSQL installation.</simpara>
+
+    <simpara>Most users will not have customized the init script itself, and
+    your customizations will all be encapsulated in the init script
+    configuration file. These users should just overwrite their init script
+    with a new one from the HyperSQL installation, and manually merge config
+    file settings. First, just copy the file
+    <filename>/sample/hsqldb.init</filename> over top of of your init script
+    (wherever it runs from). Then update your old config file according to the
+    instructions in the new config file template at
+    <filename>sample/hsqldb.cfg</filename>. You will have to change very few
+    settings. If you are upgrading from a pre-2.0 installation to a post-2.0
+    installation, you will need to (1) add the setting
+    <varname>URLIDS</varname>, as described above and in the inline comments,
+    and (2) replace variable <varname>HSQLDB_JAR_PATH</varname> with
+    <varname>SQLTOOL_JAR_PATH</varname> which (if you haven't guessed) should
+    be set to the path to your <filename>sqltool.jar</filename> file.</simpara>
+
+    <simpara>Users who customized their init script will need to merge their
+    customizations into the new init script.</simpara>
+  </section>
+</chapter>
diff --git a/doc-src/hsqldb_lic.txt b/doc-src/hsqldb_lic.txt
new file mode 100644
index 0000000..ca4b07a
--- /dev/null
+++ b/doc-src/hsqldb_lic.txt
@@ -0,0 +1,31 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * Redistributions of source code must retain the above copyright notice, this

+ * list of conditions and the following disclaimer.

+ *

+ * Redistributions in binary form must reproduce the above copyright notice,

+ * this list of conditions and the following disclaimer in the documentation

+ * and/or other materials provided with the distribution.

+ *

+ * Neither the name of the HSQL Development Group nor the names of its

+ * contributors may be used to endorse or promote products derived from this

+ * software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,

+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+

diff --git a/doc-src/hypersonic_lic.txt b/doc-src/hypersonic_lic.txt
new file mode 100644
index 0000000..1e674ea
--- /dev/null
+++ b/doc-src/hypersonic_lic.txt
@@ -0,0 +1,70 @@
+/*

+ * For work developed by the HSQL Development Group:

+ *

+ * Copyright (c) 2001-2010, The HSQL Development Group

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * Redistributions of source code must retain the above copyright notice, this

+ * list of conditions and the following disclaimer.

+ *

+ * Redistributions in binary form must reproduce the above copyright notice,

+ * this list of conditions and the following disclaimer in the documentation

+ * and/or other materials provided with the distribution.

+ *

+ * Neither the name of the HSQL Development Group nor the names of its

+ * contributors may be used to endorse or promote products derived from this

+ * software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,

+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ *

+ *

+ * For work originally developed by the Hypersonic SQL Group:

+ *

+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * Redistributions of source code must retain the above copyright notice, this

+ * list of conditions and the following disclaimer.

+ *

+ * Redistributions in binary form must reproduce the above copyright notice,

+ * this list of conditions and the following disclaimer in the documentation

+ * and/or other materials provided with the distribution.

+ *

+ * Neither the name of the Hypersonic SQL Group nor the names of its

+ * contributors may be used to endorse or promote products derived from this

+ * software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,

+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This software consists of voluntary contributions made by many individuals

+ * on behalf of the Hypersonic SQL Group.

+ */

+

+

diff --git a/doc-src/images/hypersql_logo.png b/doc-src/images/hypersql_logo.png
new file mode 100644
index 0000000..84c7a3e
--- /dev/null
+++ b/doc-src/images/hypersql_logo.png
Binary files differ
diff --git a/doc-src/images/hypersql_logo2.png b/doc-src/images/hypersql_logo2.png
new file mode 100644
index 0000000..7652d49
--- /dev/null
+++ b/doc-src/images/hypersql_logo2.png
Binary files differ
diff --git a/doc-src/index.html b/doc-src/index.html
new file mode 100644
index 0000000..140066f
--- /dev/null
+++ b/doc-src/index.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>HSQLDB</title>
+
+</head>
+
+<body>
+<h3>HyperSQL version ${hsqldb.version} Documentation</h3>
+<p>HSQLDB (HyperSQL Database) is a relational database engine
+written in Java. Version 2.0 is the result of over 4 years development
+since the last major version. It offers many features and adheres
+closely to the latest SQL and JDBC 4 standards.</p>
+<div class="section_title"> </div>
+<p>A set of HTML, PDF and text documents covering different
+aspects of HSQLDB and some of its utilities.</p>
+<p><a href="guide/index.html">HyperSQL User Guide</a>
+in HTML format. <br>
+<a href="guide/guide.pdf">HyperSQL User Guide</a> in
+PDF format. </p>
+<p><a href="util-guide/index.html">HyperSQL
+Utilities Guide</a> in HTML format.<br>
+<a href="util-guide/util-guide.pdf">HyperSQL Utilities
+Guide</a> in PDF format.
+</p>
+<p>The <a href="apidocs/index.html">JavaDoc</a>
+for public classes, including the JDBC documentation.
+</p>
+<p>Chronological list of minor changes and bug fixes since the
+release of version 2.0 <a href="changelist_2_0.txt">changelist_2_0.txt</a>
+</p>
+<p>The license texts for the source and binaries, based on the
+BSD license. <a href="hsqldb_lic.txt">hsqldb_lic.txt</a>
+is for sources developed entirely by the HSQL Development Group. <a href="hypersonic_lic.txt">hypersonic_lic.txt</a> is
+for sources that contain code from the closed HypersonicSQL project.</p>
+<h4>Additional Resources</h4>
+<p>Support for HyperSQL is available from <a target="_top" href="http://hsqldb.org/support">http://hsqldb.org/support</a>
+in various forms, including a mailing list and user forums. The web
+site features the latest bugfix versions of the software, FAQ and other
+useful resources.</p>
+<p>$Date: 2010-03-22 19:56:59 -0400 (Mon, 22 Mar 2010) $</p>
+</body></html>
diff --git a/doc-src/odbc.txt b/doc-src/odbc.txt
new file mode 100644
index 0000000..175e20b
--- /dev/null
+++ b/doc-src/odbc.txt
@@ -0,0 +1,211 @@
+$Id: odbc.txt 2850 2009-02-23 22:27:10Z unsaved $

+

+This file documents various aspects of HyerSQL's ODBC support.

+It does not document driver-side issues (at least once we can discriminate),

+since those issues will be documented with the dedicated ODBC driver product.

+

+Critical server-side todo items.

+

+    + Support passing of size/precision/scale values for columns to the ODBC

+      client.  I guess the client uses this for display formatting purposes (I

+      don't know any other reason why the client would want the value, since

+      the database, not the client, enforces conformance).

+      It's quite possible that no real purpose is served.  In that case we can

+      greatly improve efficiency of the PgType class by sharing a static list

+      of elements instead of making tons of PgType instances.

+

+    + Support binary database data types (BINARY, OBJECT, etc.)

+

+    + Support TIME and DATETIME database data types (DATEs already supported)

+      (May want to postpone *INTERVAL* types for another iteration).

+

+    + Verify tactic used to generate numeric "object identifiers" for tables

+      is adequate: Java hash of String "schema.tablename".

+

+    + Fix column oid (numeric object identifier) generation tactic.  I am

+      just returning the sequence in the generated result set.  The problem

+      with this tactic is that the number for a column is dependent upon

+      the query instead of on the table definition.

+

+KNOWN LIMITATIONS

+

+    Limitations corresponding to the TODO items above.

+

+    Can't fetch the same column (or virtual column) twice from JDBC, even with

+    different getters like rs.getInt() and rs.getObject().  I don't know what

+    product is responsible for this limitation.

+

+    No metadata querying ability, other than the ones implicit with setting

+    up prepared statements (including the 'D').

+

+    Don't know if it is a bug with Sun's jdbc:odbc or with psqlodbc, but

+    all fetchsize settings are rejected with a message saying that the

+    value is unacceptable.

+

+    psqlodbc can handle compound commands (*;*) only in SIMPLE (Q) mode; and

+    even that needs to be tested to see if server will generate the expected

+    number of reply packets.

+

+

+POSTGRESQL DEPENDENCIES TO BE ELIMINATED (uncertain whether will handle these

+ on client or server side).

+Search ServerConnection.java (from odbcproto1 branch) for comments about

+ "stub" and "swallow", ignoring stuff about client side swallowing.

+Over-the-wire Postgresql-specific SQL commands that must be handled.

+    SELECT

+    PREPARE/EXECUTE/DEALLOCATE

+    SET/SHOW

+    DECLARE/FETCH/MOVE/CLOSE

+psqlodbc source code locations

+    The info30.c file seems to be good (ODBC v.3 metadata)

+    connect.c

+        select oid,... upon startup.

+        current_schema()

+    convert.c

+        Uses ctid pseudo-column

+        convert_escape() generates queries.  Func. should probably be

+         eliminated.

+        copy_statement_with_parameters looks dependent upon PostgresQL

+         PREPARE SQL statements.

+         (this calls Prepare_and_convert(), which also depends on them).

+    multibyte.c

+        CC_lookup_cs_new()  Not run from Linux driver.  Test whether

+         called from CC_lookup_characterset() from Windows ANSI client.

+    parse.c

+        CheckHasOids()

+        getCOLIfromTable()

+    results.c

+        tupleExists()  uses ctid pseudo-column

+Literal commands known to be sent over the wire:

+

+    select n.nspname, c.relname, a.attname, a.atttypid,t.typname, a.attnum, a.attlen, a.atttypmod, a.attnotnull, c.relhasrules, c.relkind, c.oid, d.adsrc from (((pg_catalog.pg_class c inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace and c.oid = 3411470544) inner join pg_catalog.pg_attribute a on (not a.attisdropped) and a.attnum > 0 and a.attrelid = c.oid) inner join pg_catalog.pg_type t on t.oid = a.atttypid) left outer join pg_attrdef d on a.atthasdef and d.adrelid = a.attrelid and d.adnum = a.attnum order by n.nspname, c.relname, attnum

+

+    select current_schema()

+

+    select oid, typbasetype from pg_type where typname = 'lo'

+

+    deallocate <cursorname> (all cases I've encountered so far seem to be

+     an over-zealous attempt by the driver to free cursors managed completely

+     EXTENDED protocol, and therefore my server code can handle these).

+

+    set client_encoding to...

+

+Literal commands I see in code, but have not yet taken the time to confirm or

+reject as will ever be sent to our server.  Repeat:  THESE STATEMENTS MAY

+NEVER BE SENT.  I will have a definitive answer about several of these shortly.:

+

+    "select oid, 0 from pg_type where typname='" PG_TYPE_LO_NAME "'"

+

+    Dynamic queries with: " where ctid = '(0,0)';select \"ctid"... from...

+

+    All sorts of metadata/data-dictionary stuff in "info.c" file.

+

+    select relhasoids, c.oid from pg_class c, pg_namespace n where relname = '%s' and nspname = '%s' and c.relnamespace = n.oid"

+

+    "select a.attname, a.atttypid from pg_index i, pg_attribute a where indrelid=%u and indnatts=1 and indisunique

+ and indexprs is null and indpred is null and i.indrelid = a.attrelid and a.attnum=i.indkey[0] and attnotnull and atttypid in (%d, %d)"

+

+    "select nspname from pg_namespace n, pg_class c"

+

+    "select 1 from \"%s\" where ctid = '(%d,%d)'"

+

+    Complex dynamic parsing or genereration code in convert.c:convert_escape().

+

+    SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL *

+

+    show max_identifier_length

+

+    Show Client_Encoding

+

+

+DATA TYPE SUPPORT MATRIX   (type synonyms not listed) @=Yet-to-be-Implemented

+

+    HyperSQL type               wid prec scale |  Driver type oid adtsz atttypm

+    --------------------------- --- ---- ----- -  ----------- --- ---   ---

+    TINYINT                       8    3    0  |  HSQL_TINYINT 9999 1    -1

+    SMALLINT                     16    5    0  |  int2         21   2    -1

+    INTEGER                      32   10    0  |  int4         23   4    -1

+    BIGINT                       64   19    0  |  int8         20   8    -1

+    NUMERIC(p?,s?)                  [100]  [0] |  numeric    1700  -1   [-1]**

+    FLOAT(p?)                   128   [0]   0  |  float8      701   8    -1**

+    DOUBLE                      128    0    0  |  float8      701   8    -1

+    BOOLEAN                            0    0  |  bool         16   1    -1

+    CHAR(1l)* =                       [1]++ 0  |  bpchar     1042  -1    [1]

+    VARCHAR(1l)                       [0]   0  |  varchar    1043  -1   [-1]

+                  If precision unlimited/0:    |  text         25  -1    -1

+LITERAL, simple atomic str+:CHARACTER len   0  |  unknown     705  -2    -1

+DERIVED, compound str+:   VARCHAR  prtlen   0  |  text         25  -1    -1

+    CLOB(1l)                          [0]   0  |  @

+    BINARY(1l)*                       [0]   0  |  bytea        17  -1    -1

+    VARBINARY(1l)                     [0]   0  |  bytea        17  -1    -1

+    BLOB(1l)                          [0]   0  |  @

+    BIT(1l)*                          [1]   0  |  bit       1560   -1    -1

+    BIT VARYING(1l)                   [0]   0  |  varbit    1562   -1    -1

+    OTHER                              0    0  |  @

+    DATE                               0    0  |  date       1082   4    -1

+    TIME(p0)                           0   [0] |  time       1083   8   [-1]

+    TIME(p0) WITH TIME ZONE            0   [0] |  time_with_tmzone 1266 12 [-1]

+    TIMESTAMP(p0)                      0   [6] |  timestamp_no_tmzone 1114 8[-1]

+    TIMESTAMP (p0) WITH TIME ZONE      0   [6] |  datetime  ?1184   8 [-1]*****

+    INTERVAL...(p2,p0)                [2]  [6] |  tinterval  1186  16  [-1]****

+* these types present at least a facade of data values always padded to the

+  specified length.

+** atttypmod for numerics determines column size and scale.

+     atttypmod = (precision << 16) + scale + 4

+     (but there seems to be a bug in psqlodbc where this still does not work).

+*** Postgresql seems to use the FLOAT(x) precisions specifier just to decide

+ whether to create a float4 or float8 column.

+**** I get atttypmod value of 2147418111 for INTERVAL(3)

+    = short of 32767 + short of -1 and 217418110 for INTERVAL(2)

+    So far unsuccessful to reverse engineer atttypmods for INTERVALs.

+    As of today, support for following HyperSQL INTERVAL variants:

+      DAY TO SECOND, HOUR TO SECOND, MINUTE TO SECOND, SECOND.

+***** Seems to be a driver bug here.  Should return 1296 for TIMESTAMP, not

+      1184 for DATETIME.

++:  If HyperSQL determines the output is a known constant size, it sets the

+    precision to that.  That seems to be the intention of Postgresql, but PG is

+    not as smart about figuring out when expressions will resolve to a constant.

+    When combining a constant and a col., HyperSQL confusingly some really

+    crazy lengths.  I haven't figured out the method or intention.

+++: This defaults to 1 instead of 0 if sql.enforce_strict_size is set.

+

+Interval types seem to be wildly different between PG and HyperSQL.

+I believe that for all interval literals, precisions will automatically be set

+ to preserve the specified value (unless you specify the precisions).

+ Therefore, in practice, precision specs are usually only useful in col. defs.

+PG:  INTERVAL(p);  Where [0] <= p <= 6 (sub-sec. resolution, trunk/round vary!)

+     Resolution years to microsecond.  Literals:

+     '1 12:59:10 ago'  ==  '1 day 12 hours 59 min 10 sec ago'

+     '1.234' = '1.234 sec'

+     '-8 days - 12:59:10.472'

+HS:  Resolution is either in months or (sub)seconds.  Can't mix.

+   p1 [2], p2[0].

+     INTERVAL NON_SECOND(p1) TO NON_SECOND

+   Or

+     INTERVAL NON_SECOND(p1) TO SECOND(p2)

+   Or

+     INTERVAL NON_SECOND(p1)

+   Or

+     INTERVAL SECOND(p1,p2)

+   Literals

+       INTERVAL '145 23:12:19.345' DAY(3) TO SECOND(3)

+         = INTERVAL '3503:12:19.345' HOUR TO SECOND(3)

+       INTERVAL '19.345' SECOND(4,3)

+

+

+REFERENCES

+

+    JDBC type mapping tables.  Section "Tables for Type Mapping" of Sun's

+    "Getting Started with the JDBC API", which is section 9.9 of the current

+    version, but this section number changes with document revisions.

+    http://java.sun.com/javase/6/docs/technotes/guides/jdbc/getstart/mapping.html#1038075

+

+    psqlodbc code repository.  Module "psqlodbc" at

+      :pserver:anonymous@cvs.pgfoundry.org:/cvsroot/psqlodbc

+    This is the code base that our odbc driver forked from.

+

+    Protocol specification:

+    http://www.postgresql.org/docs/8.3/interactive/protocol.html

+

+    Article on ODBC escape sequences.  May support these some day.

+    http://www.ibprovider.com/eng/documentation/odbc_escape_sequences_eng.html

diff --git a/doc-src/readme-docauthors.txt b/doc-src/readme-docauthors.txt
new file mode 100644
index 0000000..a138372
--- /dev/null
+++ b/doc-src/readme-docauthors.txt
@@ -0,0 +1,43 @@
+$Id: readme-docauthors.txt 844 2009-01-19 15:02:56Z unsaved $

+

+BUILDING

+

+You need JDK 1.5 or later and Ant 1.7 or later.

+

+Run "ant gen-docs" from the build subdirectory.

+Error messages should be self-explanatory.

+

+

+SYSTEM

+

+See http://pub.admc.com/howtos/ant-docbook-howto/system-chapt.html#system-features-sect and

+http://pub.admc.com/howtos/ant-docbook-howto/tips-app.html for

+important tips.  This HOWTO document explains the build system used here.

+

+

+EDITING

+

+Use DocBook v. 5 syntax in your DocBook source XML files.

+

+Because of the amount of extra infrastructure needed for DocBook olinking,

+we are not supporting direct inter-document linking.  If you want to refer

+from one DocBook document to content in another one, then add a link to

+the canonical document (like using a &distro_bseurl;/guide/index.html link)

+and just describe the location referred to.

+

+Top-level DocBook source files for individual DocBook documents reside at

+doc-src/X/X.xml.  Other files may be xincluded into these files, and lots of

+other resources are referenced or pulled in from under doc-src.

+

+Please use the product name HyperSQL in major titles.  Where introducing

+HyperSQL, use a subtitle like "aka HSQLDB".

+In the text, use "HyperSQL" as the product name.

+In filepaths and package names you code as required for the filepath or package

+name, of course.

+

+Don't capitalize words or phrases to emphasize them (including in

+section titles or headings).

+If you want to emphasize something a certain way, then use a DocBook emphasis

+role, and leave the presentation decisions to the style sheets.

+It is very easy to set a CSS style to capitalize headings if you want them to

+appear that way.

diff --git a/doc-src/readme-template.txt b/doc-src/readme-template.txt
new file mode 100644
index 0000000..da921d9
--- /dev/null
+++ b/doc-src/readme-template.txt
@@ -0,0 +1,9 @@
+Readme File

+$Date: 2009-03-16 13:05:36 -0400 (Mon, 16 Mar 2009) $

+This package contains HyperSQL v. ${hsqldb.version}

+

+HyperSQL is a relational database engine and a set of tools written in Java.

+HyperSQL is also known as HSQLDB.

+

+The file "index.html" explains the contents of this distribution and has

+links to documentation and support resources.

diff --git a/doc-src/util-guide/entities/versions.ent b/doc-src/util-guide/entities/versions.ent
new file mode 100644
index 0000000..d46b4ce
--- /dev/null
+++ b/doc-src/util-guide/entities/versions.ent
@@ -0,0 +1,4 @@
+<!-- $Id: versions.ent 3640 2010-06-07 01:21:01Z unsaved $ -->
+
+<!ENTITY SqlTool_rev "3406">
+<!ENTITY SqlFile_rev "3604">
diff --git a/doc-src/util-guide/filelinks-app.xml b/doc-src/util-guide/filelinks-app.xml
new file mode 100644
index 0000000..f37eda8
--- /dev/null
+++ b/doc-src/util-guide/filelinks-app.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: filelinks-app.xml 807 2009-01-15 21:10:31Z unsaved $ -->
+
+<!DOCTYPE book [
+  <!ENTITY % dummy22 SYSTEM "../entities/global.ent"> %dummy22;
+]>
+
+<appendix version="5.0" xmlns="http://docbook.org/ns/docbook"
+          xmlns:xlink="http://www.w3.org/1999/xlink">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <info xml:id="filelinks-app">
+    <title>HyperSQL File Links</title>
+    <subtitle>HyperSQL Files referred to in this Guide</subtitle>
+  </info>
+  <simpara>
+    HyperSQL files referred to in the text may be retrieved from the
+    canonical HyperSQL documentation site, &distro_baseurl;, or from the
+    same location you are reading this page from.
+  </simpara>
+  <note><simpara>
+    If you are reading this document with a standalone PDF reader,
+    only the &distro_baseurl;/... links will function.
+  </simpara></note>
+
+  <itemizedlist>
+    <title>
+      Pairs of local + &distro_baseurl; links for referenced files.
+    </title>
+    <listitem xml:id="sqltool.rc-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/sqltool.rc"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/sqltool.rc"/>
+      </simpara>
+    </listitem> <listitem xml:id="sampledata.sql-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/sampledata.sql"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/sampledata.sql"/>
+      </simpara>
+    </listitem> <listitem xml:id="sample.sql-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/sample.sql"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/sample.sql"/>
+      </simpara>
+    </listitem> <listitem xml:id="pl.sql-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/pl.sql"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/pl.sql"/>
+      </simpara>
+    </listitem> <listitem xml:id="plsql.sql-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/plsql.sql"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/plsql.sql"/>
+      </simpara>
+    </listitem> <listitem xml:id="dsv-sample.sql-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/sample/dsv-sample.sql"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/sample/dsv-sample.sql"/>
+      </simpara>
+    </listitem> <listitem xml:id="sqljrt.sql-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/testrun/sqltool/sqljrt.sql"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/testrun/sqltool/sqljrt.sql"/>
+      </simpara>
+    </listitem> <listitem xml:id="sqlpsm.sql-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/testrun/sqltool/sqlpsm.sql"/>
+      </simpara> <simpara>
+        <link xlink:href="&distro_baseurl;/verbatim/testrun/sqltool/sqlpsm.sql"/>
+      </simpara>
+    </listitem> <listitem xml:id="SqlFileEmbedder.java-link">
+      <simpara>
+        Local:
+        <link xlink:href="../verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java"/>
+      </simpara> <simpara>
+      <link xlink:href="&distro_baseurl;/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java"/>
+      </simpara>
+    </listitem> <listitem xml:id="SqlTool.html-link">
+      <simpara>
+        Local:
+        <link xlink:href="../apidocs/org/hsqldb/cmdline/SqlFile.html"/>
+      </simpara> <simpara>
+      <link xlink:href="&distro_baseurl;/apidocs/org/hsqldb/jcmdline/SqlFile.html"/>
+      </simpara>
+    </listitem>
+  </itemizedlist>
+</appendix>
diff --git a/doc-src/util-guide/rejreport-sample.png b/doc-src/util-guide/rejreport-sample.png
new file mode 100644
index 0000000..d8c8631
--- /dev/null
+++ b/doc-src/util-guide/rejreport-sample.png
Binary files differ
diff --git a/doc-src/util-guide/sqltool-chapt.xml b/doc-src/util-guide/sqltool-chapt.xml
new file mode 100644
index 0000000..523ddd2
--- /dev/null
+++ b/doc-src/util-guide/sqltool-chapt.xml
@@ -0,0 +1,3429 @@
+<?xml version="1.0"?>
+<!-- $Id: sqltool-chapt.xml 3607 2010-06-01 11:18:26Z unsaved $ -->
+
+<!DOCTYPE book [
+    <!ENTITY % dummy22 SYSTEM "../entities/global.ent"> %dummy22;
+    <!ENTITY % dummy25 SYSTEM "entities/versions.ent"> %dummy25;
+]>
+
+<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
+      xmlns:xlink="http://www.w3.org/1999/xlink"
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      xml:id='sqltool-chapt'>
+    <title xml:id='sqltool-title'>SqlTool</title>
+    <subtitle>SqlTool Manual</subtitle>
+    <info>
+        <authorgroup>
+            <author>
+              <personname>
+                <firstname>Blaine</firstname>
+                <surname>Simpson</surname>
+              </personname>
+              <affiliation>
+                <orgname>HSQL Development Group</orgname>
+              </affiliation>
+            </author>
+        </authorgroup>
+        <releaseinfo>$Revision: 3607 $</releaseinfo>
+        <pubdate>$Date: 2010-06-01 07:18:26 -0400 (Tue, 01 Jun 2010) $</pubdate>
+        <keywordset>
+            <keyword>SqlTool</keyword>
+            <keyword>HSQLDB</keyword>
+            <keyword>HyperSQL</keyword>
+            <keyword>SQL</keyword>
+            <keyword>JDBC</keyword>
+        </keywordset>
+    </info>
+
+    <section xml:id="sqltool_book_purpose-sect">
+        <title>Purpose, Coverage, Changes in Behavior</title>
+      <note> <simpara>
+        Due to many important improvements to SqlTool, both in terms of
+        stability and features, all users of SqlTool are advised to use the
+        latest version of SqlTool, even if your database instances run with an
+        older HSQLDB version.
+        How to do this is documented in the
+      <link xlink:href='#sqltool_olderaccess-sect' endterm='olderaccess-title'/>
+        section below.
+      </simpara> </note>
+        <simpara>
+            This document explains how to use SqlTool, the main purpose of
+            which is to read your SQL text file or stdin, and execute the SQL
+            commands therein against a JDBC database.
+            There are also a great number of features to facilitate both
+            interactive use and automation.
+            The following paragraphs explain in a general way why SqlTool is
+            better than any existing tool for text-mode interactive SQL work,
+            and for automated SQL tasks.
+            Two important benefits which SqlTool shares with other pure Java
+            JDBC tools is that users can use a consistent interface and
+            syntax to interact with a huge variety of databases-- any
+            database which supports JDBC; plus the tool itself runs on any
+            Java platform.
+            Instead of using <filename>isql</filename> for Sybase,
+            <filename>psql</filename> for Postgresql,
+            <filename>Sql*plus</filename> for Oracle, etc., you can
+            use SqlTool for all of them.
+            As far as I know, SqlTool is the only production-ready, pure
+            Java, command-line, generic JDBC client.
+            Several databases come with a command-line client with limited
+            JDBC abilities (usually designed for use with just their specific
+            database).
+      </simpara> <important> <simpara>
+          The SqlTool commands and settings are intuitive once you are
+          famililar with the usage idioms.
+          This Guide does not attempt to list every SqlTool command and
+          option available.
+          When you want to know what SqlTool commands or options are available
+          for a specific purpose, you need to list the commands of the
+          appropriate type with the relevant "?" command.
+          For example, as explained below, to see all Special commands, you
+          would run <literal>\?</literal>; and to see all DSV export options,
+          you run \x?.
+      </simpara> </important> <simpara>
+          SqlTool is purposefully not a Gui tool like Toad or DatabaseManager.
+          There are many use cases where a Gui SQL tool would be better.
+          Where automation is involved in any way, you really need a text
+          client to at least test things properly and usually to prototype
+          and try things out.
+          A command-line tool is really better for executing SQL scripts,
+          any form of automation, direct-to-file fetching, and remote client
+          usage.
+          To clarify this last, if you have to do your SQL client work on a
+          work server on the other side of a VPN connection, you will quickly
+          appreciate the speed difference between text data transmission
+          and graphical data transmission, even if using VNC or Remote Console.
+          Another case would be where you are doing some repetitive or
+          very structured work where variables or language features would
+          be useful.
+          Gui proponents may disagree with me, but scripting (of any sort)
+          is more efficient than repetitive copy &amp; pasting with a Gui
+          editor.
+          SqlTool starts up very quickly, and it takes up a tiny fraction of
+          the RAM required to run a comparably complex Gui like Toad.
+        </simpara> <simpara>
+          SqlTool is superior for interactive use because over many years it
+          has evolved lots of features proven to be efficient for day-to-day
+          use.
+          Four concise help commands (\?, :?, *?, and /?) list all available
+          commands of the corresponding type.
+          SqlTool doesn't support up-arrow or other OOB escapes (due to basic
+          Java I/O limitations), but it more than makes up for this limitation
+          with macros, user variables, command-line history and recall, and
+          command-line editing with extended Perl/Java regular expressions.
+          The \d commands deliver JDBC metadata information as consistently as
+          possible (in several cases, database-specific work-arounds are used
+          to obtain the underlying data even though the database doesn't
+          provide metadata according to the JDBC specs).
+          Unlike server-side language features, the same feature set works
+          for any database server.
+          Database access details may be supplied on the command line, but
+          day-to-day users will want to centralize JDBC connection details
+          into a single, protected RC file.
+          You can put connection details (username, password, URL, and other
+          optional settings) for scores of target databases into your RC file,
+          then connect to any of them whenever you want by just giving
+          SqlTool the ID ("urlid") for that database.
+          When you Execute SqlTool interactively, it behaves by default
+          exactly as you would want it to.
+          If errors occur, you are given specific error messages and you
+          can decide whether to roll back your session.
+          You can easily change this behavior to auto-commit,
+          exit-upon-error, etc., for the current session or for all
+          interactive invocations.
+          You can import or export delimiter-separated-value files.
+          If you need to run a specific statement repeatedly, perhaps changing
+          the WHERE clause each time, it is very simple to define a macro.
+        </simpara> <simpara>
+          When you Execute SqlTool with a SQL script, it also behaves by
+          default exactly as you would want it to.
+          If any error is encountered, the connection will be rolled back,
+          then SqlTool will exit with an error exit value.
+          If you wish, you can detect and handle error (or other) conditions
+          yourself.
+          For scripts expected to produce errors (like many scripts provided
+          by database vendors), you can have SqlTool continue-upon-error.
+          For SQL script-writers, you will have access to portable scripting
+          features which you've had to live without until now.
+          You can use variables set on the command line or in your script.
+          You can handle specific errors based on the output of SQL commands
+          or of your variables.
+          You can chain SQL scripts, invoke external programs, dump data
+          to files, use prepared statements,
+          Finally, you have a procedural language with <literal>if</literal>,
+          <literal>foreach</literal>, <literal>while</literal>,
+          <literal>continue</literal>, and <literal>break</literal> statements.
+        </simpara>
+        <section>
+        <title>Platforms and SqlTool versions covered</title>
+          <simpara>
+            SqlTool runs on any Java 1.5 or later platform.
+            I know that SqlTool works well with Sun and OpenJDK JVMs.
+            I haven't run other vendors' JVMs in years (IBM, JRockit, etc.).
+            As my use with OpenJDK proves that I don't depend on Sun-specific
+            classes, I expect it to work well with other (1.5-compatible) Java
+            implementations.
+        </simpara> <simpara>
+            SqlTool no longer writes any files without being explicitly
+            instructed to.
+            Therefore, it should work fine on read-only systems, and you'll
+            never have orphaned temp files left around.
+        </simpara> <simpara>
+            The command-line examples in this chapter work as given on all
+            platforms (if you substitute in a normalized path in place of
+            <literal>$HSQLDB_HOME</literal>), except where noted otherwise.
+            When doing any significant command-line work on Windows
+            (especially shell scripting), you're better off to completely
+            avoid paths with spaces or funny characters.
+            If you can't avoid it, use double-quotes and expect problems.
+            As with any Java program, file or directory paths on the command
+            line after "java" can use forward slashes instead of back slashes
+            (this goes for System properties and the
+            <varname>CLASSPATH</varname> variable too).
+            I use forward slashes because they can be used consistently, and
+            I don't have to contort my fingers to type them :).
+        </simpara> <simpara>
+            If you are using SqlTool from a HyperSQL distribution of version
+            1.8.x or earlier, you should use the documentation with that
+            distribution, because this manual documents many new features,
+            several significant changes to interactive-only commands, and
+            a few changes effecting backwards-compatibility (see next
+            section about that).
+            This document is now updated for the current versions of SqlTool
+            and SqlFile at the time I am writing this (versions
+            &SqlTool_rev; and &SqlFile_rev; correspondingly-- SqlFile is the
+            class which actually processes the SQL content for SqlTool).
+            Therefore, if you are using a version of SqlTool or SqlFile that
+            is more than a couple revisions greater, you should find a newer
+            version of this document.
+            (The imprecision is due to content-independent revision increments
+            at build time, and the likelihood of one or two
+            behavior-independent bug fixes after public releases).
+            The startup banner will report both versions when you run SqlTool
+            interactively.
+            (Dotted version numbers of SqlTool and SqlFile definitely indicate
+            ancient versions).
+        </simpara> <simpara>
+            This guide covers SqlTool as bundled with HSQLDB after 1.8.x.
+            <footnote label='1' xml:id='samplelocFn'><simpara>
+            To reduce the time I will need to spend maintaining this document,
+            in this chapter I am giving the path to the
+            <filename>sample</filename> directory as it is in HyperSQL 2.0.x
+            distributions, namely, <filename>HSQLDB_HOME/sample</filename>.
+            Users of HSQLDB before 2.0.x should translate these sample
+            directory paths
+            to use <filename>HSQLDB_HOME/src/org/hsqldb/sample/...</filename>.
+            </simpara></footnote>
+        </simpara>
+        </section>
+        <section><title>Recent Functional Changes</title>
+            <simpara>This section lists changes to SqlTool since the last
+              major release of HSQLDB which may effect the portability
+              of SQL scripts.
+              For this revision of this document, this list consists of
+              script-impacting changes made to SqlTool
+              <emphasis>after</emphasis> the final 1.8.0.0 HSQLDB release.
+              I'm specifically not listing changes to interactive(:)-only
+              commands ( with one legacy exception which is listed below),i
+              since these commands can't be used in SQL scripts;
+              and I'm specifically not listing backwards-compatible feature
+              additions and enhancements.
+              The reason for limiting the change list to only portability-
+              impacting changes is that a list of all enhancements since
+              just 1.8.1.1 would be pages long.
+            </simpara>
+            <itemizedlist>
+                <listitem><simpara>
+                 SqlTool is now bundled in the supplied file
+                 <literal>sqltool.jar</literal> instead of
+                 <filename>hsqldb.jar</filename>.
+                 Therefore, the usage idiom
+                 <literal>java -jar .../hsqldb.jar</literal> has changed to
+                 <literal>java -jar .../sqltool.jar</literal>.
+                 (depending on where you get your HyperSQL resources from,
+                 these files may be named with a version label, like
+                 <filename>sqltool-1.2.3.4.jar</filename>).
+                </simpara></listitem><listitem><simpara>
+                 The package of SqlTool and support classes has been changed
+                 from <classname>org.hsqldb.util</classname> to
+                 <classname>org.hsqldb.cmdline</classname>.
+                 There is no change to <literal>java -jar...</literal> command-lines,
+                 but you will need to change the package name in SqlTool
+                 command lines of the form <literal>java... org.hsqldb...</literal>.
+                 This later usage is necessary if you need to modify the
+                 classpath for any reason, such as for embedding, to use a
+                 logging config file, or to use a non-HSQLDB JDBC driver.
+                </simpara></listitem><listitem><simpara>
+                  SqlTool now consistently outputs \r\n line breaks when
+                  on \r\n-linebreak platforms, like Windows.
+                  This includes output written to stdout, \w files,
+                  and \o files.
+                </simpara></listitem><listitem><simpara>
+                  Time type values are always output with the date as
+                  well as the time.
+                  This was required in order to produce consistent output
+                  for the wildly varying formats provided by different
+                  database vendors.
+                </simpara></listitem><listitem><simpara>
+                  DSV input now takes JDBC Timestamp format with date and
+                  optionally time of day.
+                </simpara></listitem><listitem><simpara>
+                  The command ":;" is now strictly an interactive command.
+                  If you want to repeat a command in an SQL scripts, just
+                  repeat the exact text of the command.
+                  Non-interactive use now has no dependency on command history.
+                </simpara></listitem><listitem><simpara>
+                  The command ":w" has replace the command \w.
+                  Unlike writing "output" to a file with \w, :w is used to
+                  write SQL "commands", and this is an interactive feature.
+                </simpara></listitem><listitem><simpara>
+                  Shell scripts using raw mode (e.g. PL/SQL scripts) must
+                  terminate the raw code with a line containing ".;", which
+                  will also send the code to the database for execution.
+                  (The old "." command has been changed to ":." to make it
+                  very clear that that command is now an interactive command).
+                </simpara></listitem><listitem><simpara>
+                  You must use raw mode to <emphasis>chunk</emphasis> SQL
+                  statements to your DB server.
+                  I.e., with previous versions of SqlTool, SQL statements
+                  were only sent to the DB server when a semi-colon is read
+                  at the end of a line.
+                  SqlTool now has a much more powerful parser, and individual
+                  SQL statements are sent to the DB server as soon as they
+                  are terminated with a semi-colon, regardless of line
+                  delimiters.
+                  Therefore, to send multiple SQL statements to the DB server
+                  in one transmittal, you must use raw mode.
+                </simpara></listitem><listitem><simpara>
+                  The --sql argument will never automatically append a
+                  semicolon to the text you provide.
+                  If you want to execute a command ending with a semi--
+                  then type a semi.
+                </simpara></listitem><listitem><simpara>
+                  Default encoding used is now the platform's default encoding
+                  instead of <literal>US-ASCII</literal>.
+                </simpara></listitem><listitem><simpara>
+                  To minimize side-effects (especialy for instance-based
+                  programmatic usage), the only System properties used are
+                  those predefined by the JVM (incl.
+                  <literal>javax.net.ssl.*</literal>.
+                  Properties of the form <literal>sqlfile.*</literal> and
+                  <literal>sqltool.*</literal> are specifically no longer
+                  supported.
+                  (Less invasive configuration systems are provided to serve
+                  the same purposes).
+                </simpara></listitem><listitem><simpara>
+                  SqlTool no longer displays the usage banner if none of
+                  inline-RC, urlid, SQL files are supplied, because that now
+                  starts up SqlTool with no JDBC Connection.
+                  To see the usage banner, use the <literal>--help</literal>
+                  command-line switch.
+                </simpara></listitem><listitem><simpara>
+                  Requires Java 1.5 in order to build or run.
+                </simpara></listitem><listitem><simpara>
+                  Update and row counts are not displayed in non-interactive
+                  mode.
+                  The count values are readily available in a format more
+                  suitable for scripting uses through PL variables (like with
+                  <literal>*{?}</literal> or <literal>* VARNAME _</literal>).
+                </simpara></listitem>
+            </itemizedlist>
+            <simpara>
+                Although it doesn't effect scripts, I will mention a
+                significant recent change to interactive commands which could
+                confuse existing power users.
+                Special and PL commands are now stored to the edit buffer
+                and to command history, so they can be recalled and edited
+                just like SQL commands.  Now, all commands other than
+                edit/history : commands are stored to the buffer and history.
+            </simpara>
+        </section>
+        <section><title>New Features</title>
+            <itemizedlist>
+                <listitem><simpara>
+                    DSV column and row delimiters are now specified
+                    separately for input and output.
+                    This allows the input delimiters to be regular expressions.
+                    (Which in turn, allows for the next item).
+                </simpara></listitem><listitem><simpara>
+                    The new default DSM import row delimiter works for
+                    standard UNIX, Windows, Mac lines.
+                    This makes DSV files portable across these platforms.
+                    (If using a change control system like Subversion, CVS,
+                    or whatever, you can now change control your .dsv files
+                    as native ASCII files).
+                </simpara></listitem><listitem><simpara>
+                    Both <literal>/* This kind */</literal> and
+                    <literal>-- This kind</literal> of comments are now
+                    handled generally and intuitively, in SQL statements
+                    and in SqlTool-specific commands.
+                    (There were previously several limitations to where they
+                    could be used).
+                </simpara></listitem><listitem><simpara>
+                    At the cost of adding another
+                    <emphasis>command type</emphasis>, command aliases were
+                    replaced by / <emphasis>macros</emphasis>.
+                    Usage (i.e., execution) is basically the same, but the new
+                    macros are much easier to define and list; and macros can
+                    be used for both PL and Special commands now (not just
+                    for SQL statements).
+                </simpara></listitem><listitem><simpara>
+                    Reports Transaction Isolation level and JDBC Connection
+                    Read/Write or Read-Only state connection or request
+                    (with \j).
+                </simpara></listitem><listitem><simpara>
+                    New \t command to report database exection duration times.
+                </simpara></listitem><listitem><simpara>
+                    New \v command to set or report the Connection's
+                    Transaction Isolation LeVel.
+                </simpara></listitem><listitem><simpara>
+                    <literal>\d object filter</literal> commands now use the
+                    filter as a regular expression, where possible, and
+                    filter may have optional prefix / to mean to match the
+                    filter against all output (not just the object name).
+                </simpara></listitem><listitem><simpara>
+                    <literal>\dX filter</literal> commands now use the
+                    filter as a regular expression, where possible.
+                </simpara></listitem><listitem><simpara>
+                    New <varname>*DSV_TRIM_ALL</varname> to automatically
+                    handle import of
+                    data which is both positional and character-delimited.
+                </simpara></listitem><listitem><simpara>
+                    New \l command to log user-specified messages with
+                    <classname>java.util.logging</classname> or Log4j
+                    logging facility.
+                    Nothing at all is written directly to stderr.
+                </simpara></listitem><listitem><simpara>
+                    All warnings and messages now use logging facility.
+                    This allows for declarative fine control of what gets
+                    logged and where the messages go to, as well as allowing
+                    for embedded apps to manage SqlTool apps in an integrated
+                    fashion with other app log entries.
+                </simpara></listitem><listitem><simpara>
+                    New *DSV_RECORDS_PER_COMMIT setting to support
+                    user-specified tuning of large DSV imports.
+                </simpara></listitem><listitem><simpara>
+                    (Optional) DSV log report can be customized with style
+                    sheets.
+                </simpara></listitem><listitem><simpara>
+                    You can interactively (or in SQL scripts) switch JDBC data
+                    sources (with \j).
+                    SqlTool can be started and used without any data source,
+                    though you'll obviously need to connect to a data source
+                    before issuing SQL commands.
+                </simpara></listitem><listitem><simpara>
+                  Array types are now supported, including in DSV imports and
+                  exports, with the exception that DSV imports do not support
+                  element values containing commas.
+                </simpara></listitem>
+            </itemizedlist>
+        </section>
+    </section>
+
+    <section xml:id='sqltool_baremin-sect'>
+        <title xml:id='baremin-title'>The Bare Minimum</title>
+        <subtitle>The Bare Minimum You Need to Know to Run SqlTool</subtitle>
+        <warning><simpara>
+            If you are using an Oracle database server, it will commit your
+            current transaction if you cleanly disconnect, regardless of
+            whether you have set auto-commit or not.
+            This will occur if you exit SqlTool (or any other client) in
+            the normal way (as opposed to killing the process or using
+            Ctrl-C, etc.).
+            This is mentioned in this section only for brevity, so I don't
+            need to mention it in the main text in the many places where
+            auto-commit is discussed.
+            This behavior has nothing to do with SqlTool.
+            It is a quirk of Oracle.
+        </simpara></warning>
+        <simpara>
+            If you want to use SqlTool, then you either have an SQL text file,
+            or you want to interactively type in SQL commands.
+            If neither case applies to you, then you are probably
+            looking at the wrong program.
+        </simpara>
+            <procedure>
+                <title>To run SqlTool...</title>
+                <step><simpara>
+                    Copy the file
+                    <filename xlink:href="#sqltool.rc-link">
+                    sample/sqltool.rc</filename>
+                    <footnoteref linkend='samplelocFn'/>
+                    of your HyperSQL distribution to your home directory and
+                    secure access to it if your computer is accessible
+                    to anybody else (most likely from the network).
+                    This file will work as-is for a Memory Only database
+                    instance; or if your target is a HyperSQL Server
+                    running on your local computer with default settings
+                    and the password for the "SA" account is blank
+                    (the SA password is blank when new HyperSQL database
+                    instances are created).
+                    Edit the file if you need to change the target Server URL,
+                    username, password, character set, JDBC driver, or TLS
+                    trust store as documented in the
+                    <link xlink:href="#sqltool_auth-sect" endterm="auth-title"/>
+                    section.
+                    You could, alternatively, use the
+                    <literal>--inlineRc</literal> command-line switch or the
+                    \j special command to connect up to a data source, as
+                    documented below.
+                </simpara></step><step><simpara>
+                    Find out where your <filename>sqltool.jar</filename> file
+                    resides.
+                    It typically resides at
+            <varname>HSQLDB_HOME</varname><filename>/lib/sqltool.jar</filename>
+                    where <varname>HSQLDB_HOME</varname> is the
+                    "hsqldb" directory inside the root level of your HyperSQL
+                    software installation.
+                    (For example, if you extract
+                    <filename>hsqldb-9.1.0.zip</filename> into
+                    <filename>c:\temp</filename>,
+                    your <varname>HSQLDB_HOME</varname> would be
+                    <filename>c:/temp/hsqldb-9.1.0/hsqldb</filename>.
+                    Your file may also have a version label in the file name,
+                    like <filename>sqltool-1.2.3.4.jar</filename>.
+                    The forward slashes work just fine on Windows).
+                    For this reason, I'm going to use
+                    "$HSQLDB_HOME/lib/sqltool.jar" as the path to
+                    <filename>sqltool.jar</filename> for my examples, but
+                    understand that you need to use the actual path to your
+                    own <filename>sqltool.jar</filename> file.
+                    (Unix users may set a real env. variable if they wish,
+                    in which case the examples may be used verbatim;
+                    Window users may do the same, but will need to dereference
+                    the variables like <literal>%THIS%</literal> instead of
+                    like <literal>$THIS</literal>).
+                </simpara><warning><simpara>
+                    My examples assume there are no spaces or funky characters
+                    in your file paths.
+                    This avoids bugs with the Windows cmd shell and makes for
+                    simpler syntax all-around.
+                    If you insist on using directories with spaces or shell
+                    metacharacters (including standard Windows home directories
+                    like <filename>C:\Documents and Settings\blaine</filename>),
+                    you will need to double-quote arguments containing these
+                    paths.
+                    (On UNIX you can alternatively use single-quotes to avoid
+                    variable dereferencing at the same time).
+                </simpara></warning></step><step><para>
+                    If you are just starting with SqlTool, you are best off
+                    running your SqlTool command from a shell
+                    <emphasis>command-line</emphasis> (as opposed to by
+                    using icons or the Windows'
+                    <guimenuitem>Start/Run...</guimenuitem> or
+                    <guimenuitem>Start/Start Search</guimenuitem>).
+                    This way, you will be sure to see error messages if you
+                    type the command wrong or if SqlTool can't start up for
+                    some reason.
+                    On recent versions of Windows, you can get a shell by
+                    running <literal>cmd</literal> from
+                    <guimenuitem>Start/Run...</guimenuitem> or
+                    <guimenuitem>Start/Start Search</guimenuitem>).
+                    On UNIX or Linux, any real or virtual terminal will work.
+                    </para><para>
+                    On your shell command line, run
+                    <informalexample>
+              <screen>    java -jar $HSQLDB_HOME/lib/sqltool.jar --help</screen>
+                </informalexample>
+                    to see what command-line arguments are available.
+                    Note that you don't need to worry about setting the
+                    <varname>CLASSPATH</varname>
+                    when you use the <literal>-jar</literal> switch
+                    to <filename>java</filename>.
+              </para><para>
+                To run SqlTool without a JDBC connection, run
+                    <informalexample>
+              <screen>    java -jar $HSQLDB_HOME/lib/sqltool.jar</screen>
+                </informalexample>
+                You won't be able to execute any SQL, but you can play with
+                the SqlTool interface (including using PL features).
+              </para>
+              <para>
+                To execute SQL, you'll need the classes for the target
+                database's JDBC driver (and database engine classes for
+                <glossterm>in-process</glossterm> databases).
+                As this section is titled <emphasis>The Bare Minimum</emphasis>,
+                I'll just say that if you are running SqlTool from a HyperSQL
+                product installation, you are all set to connect to any kind of
+                HyperSQL database.
+                This is because SqlTool will look for the file
+                <filename>hsqldb.jar</filename> in the same directory as
+                <filename>sqltool.jar</filename>, and that file contains all of
+                the needed classes.
+                (SqlTool supports all JDBC databases and does not require a
+                HyperSQL installation, but these cases would take us beyond
+                <emphasis>the bare minimum</emphasis>).
+                So, with <filename>hsqldb.jar</filename> in place, you can run
+                commands like
+                    <informalexample>
+                  <screen>    java -jar $HSQLDB_HOME/lib/sqltool.jar mem</screen>
+                </informalexample>
+                    for interactive use, or
+                    <informalexample>
+                    <screen>    java -jar $HSQLDB_HOME/lib/sqltool.jar --sql="SQL statement;" mem</screen>
+                    </informalexample>
+                    or
+                    <informalexample>
+                    <screen>     java -jar $HSQLDB_HOME/lib/sqltool.jar mem filepath1.sql...</screen>
+                    </informalexample>
+                    where <literal>mem</literal> is an
+                    <emphasis>urlid</emphasis>,
+                    and the following arguments are paths to text SQL files.
+                    For the filepaths, you can use whatever wildcards your
+                    operating system shell supports.
+                    </para><simpara>
+                    The <emphasis>urlid</emphasis> <literal>mem
+                    </literal>in these commands is a key
+                    into your RC file, as explained in the
+                    <link xlink:href='#sqltool_auth-sect' endterm='auth-title'/> section.
+                    Since this is a <glossterm>mem:</glossterm> type catalog,
+                    you can use SqlTool
+                    with this urlid immediately with no database setup
+                    whatsoever (however, you can't persist any changes that
+                    you make to this database).
+                    The sample sqltool.rc file also defines the urlid
+                    "localhost-sa" for a local HyperSQL Listener.
+                    At the end of this section, I explain how you can load
+                    some sample data to play with, if you want to.
+                </simpara></step>
+            </procedure>
+        <tip><simpara>
+            If SqlTool fails to connect to the specified urlid and you don't
+            know why, add the invocation parameter <literal>--debug</literal>.
+            This will cause SqlTool to display a stack trace from where the
+            connection attempt fails.
+            (If a connection attempt fails with the interactive \j command,
+            details will always be displayed).
+        </simpara></tip>
+        <important><simpara>
+            SqlTool does not <emphasis>commit</emphasis> SQL changes by default.
+            (You can use the <literal>--autoCommit</literal> command-line
+            switch to have it auto-commit).
+            This leaves it to the user's disgression whether to commit or
+            rollback their modifications.
+            If you do want your changes committed, remember to run \= before
+            quitting SqlTool.
+            (Most databases also support the SQL command
+            <literal>commit;</literal>),
+        </simpara></important>
+        <simpara>
+            If you put a file named <filename>auto.sql</filename> into your
+            home directory, this file will be executed automatically every
+            time that you run SqlTool interactively (unless you invoke with
+            the <literal>--noAutoFile</literal> switch).
+        </simpara> <para>
+            To use a JDBC Driver other than the HyperSQL driver, you can't use
+            the <literal>-jar</literal> switch because you need to modify the
+            classpath.
+            You must add the <filename>sqltool.jar</filename> file and your JDBC
+            driver classes to your classpath,
+            and you must tell SqlTool what the JDBC driver class name is.
+            The latter can be accomplished by either using the "--driver"
+            switch, or setting "driver" in your config file.
+            The <link xlink:href='#sqltool_auth-sect' endterm='auth-title'/> section.
+            explains the second method.  Here's an example of the first method
+            (after you have set the classpath appropriately).
+            <informalexample>
+              <screen>java org.hsqldb.cmdline.SqlTool --driver=oracle.jdbc.OracleDriver urlid</screen>
+        </informalexample></para>
+        <tip><simpara>
+            If the tables of query output on your screen are all messy
+            because of lines wrapping, the best and easiest solution
+            is usually to resize your terminal emulator window to make it
+            wider.
+            (With some terms you click &amp; drag the frame edges to resize,
+            with others you use a menu system where you can enter the number
+            of columns).
+        </simpara></tip>
+        <section><title>Embedding</title>
+          <subtitle>Using SqlTool to execute SQL files from your own Java
+            code</subtitle>
+          <simpara>
+            To repeat what is stated in the JavaDoc for the
+            <classname xlink:href="#SqlTool.html-link">SqlTool</classname>
+            class itself:
+            <emphasis>
+              Programmatic users will usually want to use the
+              objectMain(String[]) method if they want arguments and behavior
+              exactly like command-line SqlTool. If you don't need invocation
+              parameter parsing, <filename>auto.sql</filename> exection, etc.,
+              you will have more control and efficiency by using the SqlFile
+              class directly. The file
+              <filename xlink:href="#SqlFileEmbedder.java-link">
+                src/org/hsqldb/sample/SqlFileEmbedder.java</filename>
+              in the HyperSQL distribution provides an example for this latter
+              strategy. 
+            </emphasis>
+          </simpara>
+        </section>
+        <section><title>Non-displayable Types</title>
+            <simpara>
+            There are some SQL types which SqlTool (being a text-based
+            program) can't display properly.
+            This includes the SQL types <literal>BLOB</literal>,
+            <literal>JAVA_OBJECT</literal>, <literal>STRUCT</literal>,
+            and <literal>OTHER</literal>.
+            When you run a query that returns any of these, SqlTool will
+            save the very first such value obtained to the binary buffer
+            and will not display any output from this query.
+            You can then save the binary value to a file, as explained in the
+          <link xlink:href='#sqltool_binary_files-sect' endterm='binary_files-title'/>
+            section.
+            </simpara> <simpara>
+            There are other types, such as <literal>BINARY</literal>, which
+            JDBC can make displayable (by using ResultSet.getString()), but
+            which you may very well want to retrieve in raw binary format.
+            You can use the \b command to retrieve any-column-type-at-all
+            in raw binary format (so you can later store the value to a
+            binary file).
+            </simpara> <simpara>
+            Another restriction which all text-based database clients have
+            is the practical inability for the user to type in binary data
+            such as photos, audio streams, and serialized Java objects.
+            You can use SqlTool to load any binary object into a database
+            by telling SqlTool to get the insert/update datum from a file.
+            This is also explained in the
+          <link xlink:href='#sqltool_binary_files-sect' endterm='binary_files-title'/>
+            section.
+            </simpara>
+        </section>
+        <section><title>Desktop shortcuts</title>
+            <simpara>
+                Desktop shortcuts and quick launch icons are useful, especially
+                if you often run SqlTool with the same set of arguments.
+                It's really easy to set up several of them-- one for each
+                way that you invoke SqlTool (i.e., each one would start
+                SqlTool with all the arguments for one of your typical startup
+                needs).
+                One typical setup is to have one shortcut for each database
+                account which you normally use (use a different
+                <literal>urlid</literal> argument in each shortcut's
+                <guilabel>Target</guilabel> specification.
+            </simpara><simpara>
+                Desktop icon setup varies depending on your Desktop manager,
+                of course.
+                I'll explain how to set up a SqlTool startup icon in Windows
+                XP.
+                Linux and Mac users should be able to take it from there, since
+                it's easier with the common Linux and Mac desktops.
+            </simpara>
+            <procedure>
+                <title>Creating a Desktop Shortcut for SqlTool</title>
+                <step><simpara>
+                    Right click in the main Windows background.
+                </simpara></step> <step><simpara>
+                    <guimenuitem>New</guimenuitem>
+                </simpara></step> <step><simpara>
+                    <guimenuitem>Shortcut</guimenuitem>
+                </simpara></step> <step><simpara>
+                    <guibutton>Browse</guibutton>
+                </simpara></step> <step><simpara>
+                    Navigate to where your good JRE lives.  For recent Sun
+                    JRE's, it installs to
+                    <filename>C:\Program Files\Java\*\bin</filename>
+                    by default (the * will be a JDK or JRE identifier and
+                    version number).
+                </simpara></step> <step><simpara>
+                    Select <filename>java.exe</filename>.
+                </simpara></step> <step><simpara>
+                    <guibutton>OK</guibutton>
+                </simpara></step> <step><simpara>
+                    <guimenuitem>Next</guimenuitem>
+                </simpara></step> <step><simpara>
+                    Enter any name
+                </simpara></step> <step><simpara>
+                    <guimenuitem>Finish</guimenuitem>
+                </simpara></step> <step><simpara>
+                    Right click the new icon.
+                </simpara></step> <step><simpara>
+                    <guimenuitem>Properties</guimenuitem>
+                </simpara></step> <step><simpara>
+                    Edit the <guilabel>Target</guilabel> field.
+                </simpara></step> <step><simpara>
+                    Leave the path to java.exe exactly as it is, including the
+                    quotes, but append to what is there.
+                    Beginning with a space, enter the command-line that you
+                    want run.
+                </simpara></step> <step><simpara>
+                    <guibutton>Change Icon...</guibutton> to a pretty icon.
+                </simpara></step> <step><simpara>
+                    If you want a quick-launch icon instead of (or in addition
+                    to) a desktop shortcut icon, click and drag it to your
+                    quick launch bar.  (You may or may not need to edit the
+                    Windows Toolbar properties to let you add new items).
+                </simpara></step>
+            </procedure>
+        </section>
+        <section><title>Loading sample data</title>
+            <para>
+                If you want some sample database objects and data to play
+                with, execute the
+                <filename xlink:href="#sampledata.sql-link">
+                  sample/sampledata.sql</filename> SQL file
+                <footnoteref linkend='samplelocFn'/>.
+                To separate the sample data from your regular data, you can
+                put it into its own schema by running this before you import:
+                <informalexample>
+                <programlisting>    CREATE SCHEMA sampledata AUTHORIZATION dba;
+    SET SCHEMA sampledata;</programlisting>
+            </informalexample>
+                Run it like this from an SqlTool session
+      <programlisting>    \i HSQLDB_HOME/sample/sampledata.sql</programlisting>
+                where <emphasis role='bold'>HSQLDB_HOME</emphasis> is the
+                base directory of your HSQLDB software installation
+                <footnoteref linkend='samplelocFn'/>.
+            </para>
+            <simpara>
+                For memory-only databases, you'll need to run this every
+                time that you run SqlTool.
+                For other (persistent) databases, the data will reside in
+                your database until you drop the tables.
+            </simpara>
+        </section>
+    </section>
+
+    <section>
+      <title>Satisfying SqlTool's CLASSPATH Requirements</title>
+      <simpara>
+        As discussed earlier, only the single file
+        <filename>sqltool.jar</filename> is required to run SqlTool (the file
+        name may contain a version label like
+        <filename>sqltool-1.2.3.4.jar</filename>).
+        But it's useless as an SQL <emphasis>Tool</emphasis> unless you can
+        connect to a JDBC data source, and for that you need the target
+        database's JDBC driver in the classpath.
+        For <glossterm>in-process</glossterm> catalogs, you'll also need the
+        database engine classes in the CLASSPATH.
+        The <link xlink:href='#sqltool_baremin-sect' endterm='baremin-title'/>
+        section explains that the easiest way to use SqlTool with any HyperSQL
+        database is to just use <filename>sqltool.jar</filename> in-place where
+        it resides in a HyperSQL installation.
+        This section explains how to satisfy the CLASSPATH requirements for
+        other setups and use cases.
+      </simpara>
+      <section xml:id='sqltool_olderaccess-sect'>
+        <title xml:id='olderaccess-title'>
+          Accessing older HSQLDB Databases with SqlTool</title>
+        <simpara>
+          If you are using SqlTool to access non-HSQLDB database(s), then you
+          should use the latest and greatest-- just
+          grab the newest public release of SqlTool (like from the latest
+          public HyperSQL release) and skip this subsection.
+        </simpara> <para>
+          You are strongly encouraged to use the latest SqlTool release to
+          access older HSQLDB databases, to enjoy greatly improved SqlTool
+          robustness and features.
+          It is very easy to do this.
+          <procedure>
+            <step><simpara>
+            Obtain the latest <filename>sqltool.jar</filename> file.
+            One way to obtain the latest <filename>sqltool.jar</filename> file
+            is to download the latest HyperSQL distribution and extract that
+            single file
+            </simpara></step>
+            <step><simpara>
+                Place (or copy) your new <filename>sqltool.jar</filename> file
+                right alongside the <filename>hsqldb.jar</filename> file for
+                your target database version.
+                If you don't have a local copy of the
+                <filename>hsqldb.jar</filename> file for your target database,
+                just copy it from your database server, or download the full
+                distribution for that server version and extract it.
+            </simpara></step>
+            <step><para>
+                <emphasis>
+                  (If you have used older versions of SqlTool before, notice
+                  that you now invoke SqlTool by specifying the
+                  <filename>sqltool.jar</filename> file instead of the
+                  <filename>hsqldb.jar</filename>).
+                </emphasis>
+                If your target database is a previous 2.x version of HyperSQL,
+                then you are finished and can use the new SqlTool for your older
+                database.  Users upgrading from a pre-2.x version please
+                continue...
+              </para><para>
+                Run SqlTool like this.
+                <informalexample>
+                  <screen>    java -jar path/to/sqltool.jar --driver=org.hsqldb.jdbcDriver...</screen>
+                </informalexample>
+                where you specify the pre-2.x JDBC driver name
+                <classname>org.hsqldb.jdbcDriver</classname>.
+                Give any other SqlTool parameters as you usually would.
+              </para><para>
+                Once you have verified that you can access your database using
+                the <literal>--driver</literal> paramater as explained above,
+                edit your <filename>sqltool.rc</filename> file, and add a
+                new line
+                <informalexample>
+                  <programlisting>    driver org.hsqldb.jdbcDriver</programlisting>
+                </informalexample>
+                after each urlid that is for a pre-2.x database.
+                Once you do this, you can invoke SqlTool as usual (i.e. you
+                no longer need the <literal>--driver</literal>
+                argument for your invocations).
+            </para></step>
+          </procedure>
+        </para>
+      </section>
+      <section>
+        <title>App-specific Classes, Embedding, and non-HyperSQL Databases</title>
+        <simpara>
+          For these situations, you need to add your custom, third-party, or
+          SQL driver classes to your Java CLASSPATH.
+          Java doesn't support adding arbitrary elements to the classpath when
+          you use the <literal>-jar</literal>, so you must set a classpath
+          containing <filename>sqltool.jar</filename> plus whatever else you
+          need, then invoke SqlTool without the <literal>-jar</literal> switch,
+          as briefly described at the end of the
+          <link xlink:href='#sqltool_baremin-sect' endterm='baremin-title'/>
+          section.
+          For embedded apps, invoke your own main class instead of SqlTool, and
+          you can invoke <classname>SqlTool</classname> or
+          <classname>SqlFile</classname> from your code base.
+        </simpara> <para>
+          To customize the classpath,
+          you need to set up your classpath by using your
+          operating system or shell variable <varname>CLASSPATH</varname> or
+          by using the <filename>java</filename> switch <literal>-cp</literal>
+          (or the equivalent <literal>-classpath</literal>).
+          I'm not going to take up space here to explain how to set up a
+          Java CLASSPATH.  That is a platform-dependent task that is
+          documented well in tons of Java introductions and tutorials.
+          What I'm responsible for telling you is <emphasis>what</emphasis>
+          you need to add to your classpath.
+          For the non-embedded case where you have set up your CLASSPATH
+          environmental varialbe, you would invoke SqlTool like this.
+          <informalexample>
+            <screen>    java org.hsqldb.cmdline.SqlTool ...</screen>
+          </informalexample>
+            If you are using the <literal>-cp</literal> switch instead of a
+            <varname>CLASSPATH</varname> variable, stick it after
+            <literal>java</literal>.
+            After "<literal>SqlTool</literal>", give any SqlTool parameters
+            exactly as you would put after
+            <literal>java -jar .../sqltool.jar</literal> if you didn't need to
+            customize the CLASSPATH.
+            You can specify a JDBC driver class to use either with the
+            <literal>--driver</literal> switch to SqlTool, or in your
+            RC file stanza (the last method is usually more convenient).
+        </para><simpara>
+          Note that without the <literal>-jar</literal> switch, SqlTool will
+          still automatically pull in HyperSQL JDBC driver or engine classes
+          from HyperSQL jar files in the same directory.
+          It's often a good practice to minimize your runtime classpath.
+          To prevent the possibility of pulling in classes from other HyperSQL
+          jar files, just copy <filename>sqltool.jar</filename> to some other
+          directory (which does not contain other HyperSQL jar files) and put
+          the path to that one in your classpath.
+        </simpara>
+      </section>
+      <section>
+        <title>Distributing SqlTool with your Apps</title>
+        <simpara>
+          You can distribute SqlTool along with your application, for
+          standalone or embedded invocation.
+          For embedded use, you will need to customize the classpath as
+          discussed in the previous item.
+          Either way, you should minimize your application footprint by
+          distributing only those HyperSQL jar files needed by your app.
+          You will obviously need <filename>sqltool.jar</filename> if you will
+          use the <classname>SqlTool</classname> or
+          <classname>SqlFile</classname> class in any way.
+          If your app will only connect to external HyperSQL listeners, then
+          build and include <filename>hsqljdbc.jar</filename>.
+          If your app will also <emphasis>run</emphasis> a HyperSQL Listener,
+          you'll need to include <filename>hsqldb.jar</filename>.
+          If your app will connect directly to a
+          <glossterm>in-process</glossterm> catalog, then include
+          <filename>hsqldbmain.jar</filename>.
+          Note that you never need to include more than one of
+          <filename>hsqldb.jar</filename>, <filename>hsqldbmain.jar</filename>,
+          <filename>hsqljdbc.jar</filename>, since the former jars include
+          everything in the following jars.
+        </simpara>
+      </section>
+      <section>
+        <title>SqlTool Client PCs</title>
+        <simpara>
+          If you just want to be able to run SqlTool (interactively or
+          non-interactively) on a PC, and have no need for documentation, then
+          it's usually easiest to just copy 
+          <filename>sqltool.jar</filename> and <filename>hsqldb.jar</filename>
+          to the PCs (plus JDBC driver jars for any other target databases).
+          If you want to minize what you distribute, then build and
+          distribute <filename>hsqljdbc.jar</filename> or
+          <filename>hsqldbmain.jar</filename> instead of
+          <filename>hsqldb.jar</filename>, according to the criteria listed in
+          the previous sub-section.
+        </simpara>
+      </section>
+    </section>
+
+    <section xml:id='sqltool_auth-sect'>
+        <title xml:id='auth-title'>RC File Authentication Setup</title>
+        <simpara>
+            RC file authentication setup is accomplished by creating a text
+            RC configuration file.
+            In this section, when I say <emphasis>configuration</emphasis>
+            or <emphasis>config</emphasis> file, I mean an RC configuration
+            file.
+            RC files can be used by any JDBC client program that uses the
+            org.hsqldb.util.RCData class-- this includes
+            SqlTool, DatabaseManager, DatabaseManagerSwing.
+        </simpara><simpara>
+            You can use it for your own JDBC client programs too.
+            There is example code showing how to do this at
+            <filename xlink:href="#SqlFileEmbedder.java-link">
+              src/org/hsqldb/sample/SqlFileEmbedder.java</filename>.
+        </simpara><simpara>
+            The sample RC file shown here resides at
+            <filename xlink:href="#sqltool.rc-link">sample/sqltool.rc</filename>
+            in your HSQLDB distribution
+            <footnoteref linkend='samplelocFn'/>.
+        </simpara>
+        <example>
+            <title>Sample RC File</title>
+            <programlisting><xi:include href="../verbatim/sample/sqltool.rc"
+                                        parse="text"/></programlisting>
+        </example>
+        <simpara>
+            As noted in the comment (and as used in a couple examples), you
+            can use Java system properties like this: <code>${user.home}</code>.
+            Windows users, please read the suggestion directed to you in the
+            file.
+        </simpara> <para>
+            You can put this file anywhere you want to, and specify the
+            location to SqlTool/DatabaseManager/DatabaseManagerSwing by
+            using the <literal>--rcfile</literal> argument.
+            If there is no reason to not use the default location (and there
+            are situations where you would not want to), then use the default
+            location and you won't have to give <literal>--rcfile</literal>
+            arguments to SqlTool/DatabaseManager/DatabaseManagerSwing.
+            The default location is <filename>sqltool.rc</filename> or
+            <filename>dbmanager.rc</filename> in your home directory
+            (corresponding to the program using it).
+            If you have any doubt about where your home directory is, just
+            run SqlTool with a phony urlid and it will tell you where it
+            expects the configuration file to be.
+            <informalexample>
+              <screen>    java -jar $HSQLDB_HOME/lib/sqltool.jar x</screen>
+            </informalexample></para><para>
+            The config file consists of stanza(s) like this:
+        <informalexample><screen>    urlid web
+    url jdbc:hsqldb:hsql://localhost
+    username web
+    password webspassword</screen>
+        </informalexample></para><para>
+            These four settings are required for every urlid.
+            (There are optional settings also, which are described a couple
+            paragraphs down).
+            The URL may contain JDBC connection properties.
+            You can have as many blank lines and comments like
+        <informalexample><screen>    # This comment</screen>
+        </informalexample>
+        </para><simpara>
+            in the file as you like.
+            The whole point is that the <emphasis>urlid</emphasis> that you
+            give in your SqlTool/DatabaseManager command must match a
+            <emphasis>urlid </emphasis> in your configuration file.
+        </simpara><important><simpara>
+            Use whatever facilities are at  your disposal to protect your
+            configuration file.
+        </simpara></important><simpara>
+            It should be readable, both locally and remotely, only to users
+            who run programs that need it.
+            On UNIX, this is easily accomplished by using <literal>chmod/chown
+            </literal> commands and making sure that it is protected from
+            anonymous remote access (like via NFS, FTP or Samba).
+        </simpara><simpara>
+            You can also put the following optional settings into a urlid
+            stanza.  The setting will, of course, only apply to that urlid.
+        </simpara>
+        <variablelist>
+            <varlistentry><term>charset</term><listitem><simpara>
+                This is used by the SqlTool program, but not by the
+                DatabaseManager programs.
+                See the <link xlink:href='#sqltool_charencoding-sect'
+                    endterm='charencoding-title'/> section of the
+                <link xlink:href='#sqltool_nonint-sect' endterm='nonint-title'/>
+                section.
+                This is used for input and output files, not for stdin or
+                stdout, which are controlled by environmental variables and
+                Java system properties.
+                If you set no encoding for an urlid, input and outfiles will
+                use the same encoding as for stdin/stdout.
+                (As of right now, the charset setting here is not honored by
+                the \j command, but only when SqlTool loads an urlid specified
+                on the command-line).
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>driver</term><listitem><simpara>
+                Sets the JDBC driver class name.
+                You can, alternatively, set this for one
+                SqlTool/DatabaseManager invocation by using the command
+                line switch <emphasis>--driver</emphasis>.
+                Defaults to <emphasis>org.hsqldb.jdbc.JDBCDriver</emphasis>.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>truststore</term><listitem><simpara>
+                TLS trust keystore store file path as documented in the
+                TLS section of the Listeners chapter of the
+                <link xlink:href="&distro_baseurl;/guide/index.html">
+                  HyperSQL User Guide</link>
+                You usually only need to set this if the server is using a
+                non-publicly-certified certificate (like a self-signed
+                self-ca'd cert).
+                Relative paths will be resolved relative to the
+                <varname>${user.dir}</varname>
+                system property at JRE invocation time.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>transiso</term><listitem><simpara>
+                Specify the Transaction Isolation Level with an all-caps
+                string, exactly as listed in he Field Summary of the Java
+                API Spec for the class
+                <classname>java.sql.Connection</classname>.
+            </simpara></listitem></varlistentry>
+        </variablelist>
+        <simpara>
+            Property and SqlTool command-line switches override settings made
+            in the configuration file.
+        </simpara>
+    </section>
+
+    <section xml:id='sqltool_dsswitch-sect'>
+        <title xml:id='dsswitch-title'>Switching Data Sources</title>
+        <simpara>
+          The \j command lets you switch JDBC Data Sources in your SQL files
+          (or interactively).
+          "\?" shows the syntax to make a connection by either RCData urlid
+          or by name + password + JDBC Url.
+          The urlid variant uses RC file of
+          <filename>$HOME/sqltool.rc</filename>.
+          We will add a way to specify an RC file if there is any demand for
+          that.
+        </simpara> <para>
+          You can start SqlTool without any JDBC Connection by specifying no
+          Inline RC and urlid of "-" (just a hyphen).
+          If you don't need to specify any SQL file paths, you can skip the
+          hypen, as in this example.
+            <informalexample>
+              <screen>java -jar $HSQLDB_HOME/lib/sqltool.jar --setVar=v1=one</screen>
+            </informalexample>
+          (The "-" is required when specifying one or more SQL files, in order
+          to distinguish urlid-spec from file-spec).
+          Consequently, if you invoke SqlTool with no parameters at all, you
+          will get a SqlTool session with no JDBC Connection.
+          You will obviously need to use \j before doing any database work.
+        </para>
+    </section>
+
+    <section xml:id='sqltool_ilauth-sect'>
+        <title xml:id='ilauth-title'>Using Inline RC Authentication</title>
+        <simpara>
+            Inline RC authentication setup is accomplished by using the
+            <literal>--inlineRc</literal> command-line switch on SqlTool.
+            The <literal>--inlineRc</literal> command-line switch takes
+            a comma-separated list of key/value elements.
+            The <literal>url</literal> and <literal>user</literal> elements
+            are required.  The rest are optional.
+            The <literal>--inlineRc</literal> switch is the only case where
+            you can give SQL file paths without a preceding urlid indicator
+            (an urlid or -).
+            The program knows not to look for an urlid if you give an inline.
+        </simpara>
+        <variablelist>
+            <varlistentry><term><varname>url</varname></term><listitem><simpara>
+                The JDBC URL of the database you wish to connect to.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term><varname>user</varname></term><listitem><simpara>
+                The username to connect to the database as.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term><varname>charset</varname></term><listitem><simpara>
+              Sets the character encoding. Overrides the platform default, or
+              what you have set by env variables or Java system properties.
+              (Does not effect stdin or stdout).
+            </simpara></listitem></varlistentry>
+            <varlistentry><term><varname>truststore</varname></term><listitem><simpara>
+                The TLS trust keystore file path as documented in the TLS chapter.
+                Relative paths will be resolved relative to the current directory.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term><varname>transiso</varname></term><listitem><simpara>
+                <classname>java.sql.Connection</classname> transaction
+                isolation level to connect with, as specified in the Java
+                API spec.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term><varname>password</varname></term><listitem><para>
+                You may only use this element to set empty password, like
+                <informalexample>
+                  <screen>    password=</screen>
+                </informalexample>For any other password value, omit the
+                <literal>password</literal> element and you will be prompted
+                for the value.
+            </para></listitem></varlistentry>
+        </variablelist>
+        <para>
+            (Use the <literal>--driver</literal> switch instead of
+            <literal>--inlineRc</literal> to specify a JDBC driver class).
+            Here is an example of invoking SqlTool to connect to a standalone database.
+            <informalexample>
+              <screen>java -jar $HSQLDB_HOME/lib/sqltool.jar --inlineRc=url=jdbc:hsqldb:file:/home/dan/dandb,user=dan</screen>
+            </informalexample>
+        </para>
+        <simpara>
+            For security reasons, you cannot specify a non-empty password as
+            an argument. You
+            will be prompted for a password as part of the login process.
+        </simpara>
+    </section>
+
+    <section xml:id="sqltool_logging-sect">
+        <title>Logging</title>
+        <simpara>
+            Both the \l command and all warnings and error messages now use
+            a logging facility.
+            The logging facility hands off to Log4j if Log4j is found in the
+            classpath, and otherwise will hand off to
+            <classname>java.util.logging</classname>.
+            The default behavior of <classname>java.util.logging</classname>
+            should work fine for most users.
+            If you are using log4j and are redirecting with pipes, you may
+            want to configure a Console Appender with target of
+            <literal>"System.err"</literal> so that error output will go to
+            the error stream (all console output for
+            <classname>java.util.logging</classname> goes to stderr by default).
+            See the API specs for Log4j and for J2SE for how to configure
+            either product.
+            If you are embedding SqlTool in a product to process SQL files,
+            I suggest that you use log4j.
+            <classname>java.util.logging</classname> is neither scalable nor
+            well-designed.
+        </simpara> <simpara>
+            Run the command <literal>\l?</literal> to see how to use the
+            logging command <literal>\l</literal> in your SQL files (or
+            interactively), including what logging levels you may specify.
+        </simpara>
+    </section>
+
+    <section xml:id='sqltool_int-sect'>
+        <title xml:id='int-title'>Interactive Usage</title>
+        <para>
+            Do read the
+            <link xlink:href='#sqltool_baremin-sect' endterm='baremin-title'/>
+            section before you read this section.
+        </para>
+        <para>
+            You run SqlTool interactively by specifying no SQL filepaths on
+            the SqlTool command line.  Like this.
+            <informalexample>
+              <screen>    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid</screen>
+        </informalexample></para><procedure>
+            <title>What happens when SqlTool is run interactively
+                (using all default settings)
+            </title>
+            <step><simpara>
+                SqlTool starts up and connects to the specified database,
+                using your SqlTool configuration file
+                (as explained in the
+                <link xlink:href='#sqltool_auth-sect' endterm='auth-title'/> section).
+            </simpara></step><step><simpara>
+                SQL file <filename>auto.sql</filename> in your home directory
+                is executed (if there is one),
+            </simpara></step><step><simpara>
+                SqlTool displays a
+                banner showing the SqlTool and SqlFile version numbers and
+                describes the different command types that you can give, as
+                well as commands to list all of the specific commands available
+                to you.
+            </simpara></step>
+        </procedure><simpara>
+            You exit your session by using the "\q" special command or ending
+            input (like with Ctrl-D or Ctrl-Z).
+        </simpara>
+        <important><simpara>
+          Any command may be preceded by space characters.
+          Special Commands, Edit Buffer Commands, PL Commands, Macros always
+          consist of just one line.
+        </simpara><simpara>
+            These rules do not apply at all to
+            <link xlink:href='#sqltool_raw-sect' endterm='raw-title'/>.
+            Raw mode is for use by advanced users when they want to completely
+            bypass SqlTool processing in order to enter a chunk of text for
+            direct transmission to the database engine.
+        </simpara></important>
+        <section><title>SqlTool Command-Line Editing</title>
+        <para>
+            If you are really comfortable with grep, perl, or vim, you will
+            instantly be an expert with SqlTool command-line editing.
+            Due to limitations of Java I/O, we can't use up-arrow recall,
+            which many people are used to from DosKey and Bash shell.
+            If you don't know how to use regular expressions, and don't want
+            to learn how to use them, then just forget command-recall.
+            <itemizedlist>
+                <title>Basic command entry (i.e., without regexps)</title>
+                <listitem><simpara>
+                    Just type in your command, and use the backspace-key to
+                    fix mistakes on the same line.
+                </simpara></listitem> <listitem><simpara>
+                    If you goof up a multi-line command, just hit the ENTER
+                    key twice to start over.  (The command will be moved to
+                    the buffer where it will do no harm).
+                </simpara></listitem> <listitem><simpara>
+                    Use the ":h" command to view your command history.
+                    You can use your terminal emulator scroll bar and copy
+                    and paste facility to repeat commands.
+                </simpara></listitem> <listitem><simpara>
+                    As long as you don't need to change text that is already
+                    in a command, you can easily repeat commands from the
+                    history like ":14;" to re-run command number 14 from
+                    history.
+                </simpara></listitem> <listitem><simpara>
+                    Expanding just a bit from the previous item, you can
+                    add on to a previous command by running a command like
+                    ":14a" (where the "a" means <emphasis>append</emphasis>).
+                </simpara></listitem> <listitem><simpara>
+                   See the <link xlink:href='#sqltool_macro-sect' endterm='macro-title'/>
+                    section about how to set and use macros.
+                </simpara></listitem>
+            </itemizedlist>
+        </para>
+        <simpara>
+            If you use regular expressions to search through your command
+            history, or to modify commands, be aware that the command type
+            of commands in history are fixed.
+            You can search and modify the text after a \ or * prefix (if any),
+            but you can't search on or change a prefix (or add or remove one).
+        </simpara>
+        </section>
+        <section><title>Command Types</title>
+        <simpara>
+            When you are typing into SqlTool, you are always typing part of
+            the <emphasis>immediate command</emphasis>.
+            If the immediate command is an SQL statement, it is executed as
+            soon as SqlTool reads in the trailing (unquoted) semi-colon.
+            Commands of the other command types are executed as soon as you
+            hit ENTER.
+            The interactive : commands can perform actions with or on the
+            edit buffer.
+            The <emphasis>edit buffer</emphasis> usually contains a copy of
+            the last command executed, and you can always view it with the :b
+            command.
+            If you never use any : commands, you can entirely ignore the
+            edit buffer.
+            If you want to repeat commands or edit previous commands, you
+            will need to work with the edit buffer.
+            The immediate command contains whatever (and exactly what)
+            you type.
+            The command history and edit buffer may contain any type of
+            command other than comments and : commands
+            (i.e., : commands and comments are just not copied to the history
+            or to the edit buffer).
+          </simpara><simpara>
+            Hopefully an example will clarify the difference between the
+            immediate command and the edit buffer.
+            If you type in the edit buffer Substitution command
+            "<literal>:s/tbl/table/</literal>", the :s command that you typed
+            is the immediate command (and it will never be stored to the
+            edit buffer or history, since it is a : command), but the purpose
+            of the substitution command is to modify the contents of the
+            edit buffer (perform a substitution on it)-- the goal being that
+            after your substitutions you would execute the buffer with the
+            "<literal>:;</literal>" command.
+            The ":a" command is special in that when you hit ENTER to execute
+            it, it copies the contents of the edit buffer to a new immediate
+            command and leaves you in a state where you are
+            <emphasis>appending</emphasis> to that
+            <emphasis>immediate</emphasis> command (nearly) exactly as if
+            you had just typed it in.
+        </simpara>
+        </section>
+        </section>
+        <section><title>Command Types</title>
+        <variablelist><title>Command types</title>
+            <varlistentry><term>SQL Statement</term><listitem><simpara>
+                Any command that you enter which does not begin with "\", ":",
+                "* " or "/" is an SQL Statement.
+                The command is not terminated when you hit ENTER, like most
+                OS shells.
+                You terminate SQL Statements with either ";" or with a blank
+                line.
+                In the former case, the SQL Statement will be executed against
+                the SQL database and the command will go into the edit
+                buffer and SQL command history for editing or viewing later on.
+                In the former case,
+                <emphasis>execute against the SQL database</emphasis> means
+                to transmit the SQL text to the database engine for execution.
+                In the latter case (you end an SQL Statement with a blank
+                line), the command will go to the edit buffer and SQL history,
+                but will not be executed (but you can execute it later from the
+                edit buffer).
+            </simpara><simpara>
+                (Blank lines are only interpreted this way when SqlTool is
+                run interactively.
+                In SQL files, blank lines inside of SQL statements remain
+                part of the SQL statement).
+            </simpara><simpara>
+                As a result of these termination rules, whenever you are
+                entering text that is not a Special Command, Edit Buffer /
+                History Command, or PL Command, you are always
+                <emphasis>appending</emphasis> lines to an SQL Statement
+                or comment.
+                (In the case of the first line, you will be appending to an
+                empty SQL statement.  I.e. you will be starting a new SQL
+                Statement or comment).
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>Special Command</term><listitem><simpara>
+                Run the command "\?" to list the Special Commands.
+                All of the Special Commands begin with "\".
+                I'll describe some of the most
+                useful Special Commands below.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>Edit Buffer / History Command</term><listitem><simpara>
+                Run the command ":?" to list the Edit-Buffer/History Commands.
+                All of these commands begin with ":".
+                These commands use commands from the command history, or
+                operate upon the edit "buffer", so that
+                you can edit and/or (re-)execute previously entered commands.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>PL Command</term><listitem><para>
+                Procedural Langage commands.
+                Run the command "*?" to list the PL Commands.
+                All of the PL Commands begin with "*".
+                PL commands are for setting and using scripting variables
+                and conditional and flow control statements like
+                <literal>* if</literal> and <literal>* while</literal>.
+                A few PL features (such as macros and updating and
+                selecing data directly from/to files) can be a real
+                convenience for nearly all users, so these features will be
+                discussed briefly in this section.
+                More detailed explanation of PL variables and the other
+                PL features, with examples, are covered in the
+                <link xlink:href='#sqltool_pl-sect' endterm='pl-title'/> section.
+            </para></listitem></varlistentry>
+            <varlistentry><term>Macro Command</term><listitem><simpara>
+                Macro definition and usage commands.
+                Run the command "/?" to show the define, list, or use macros.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>Raw Mode</term><listitem><simpara>
+                The descriptions of command-types above do not apply to
+                <link xlink:href='#sqltool_raw-sect' endterm='raw-title'/>.
+                In raw mode, SqlTool
+                doesn't interpret what you type at all.  It all just
+                goes into the edit buffer which you can send to the database
+                engine.
+                Beginners can safely ignore raw mode.
+                You will never encounter it unless you run the "\."
+                special command, or define a stored procedure or function.
+                See the
+                <link xlink:href='#sqltool_raw-sect' endterm='raw-title'/> section
+                for the details.
+            </simpara></listitem></varlistentry>
+        </variablelist>
+        </section>
+        <section><title>Special Commands</title>
+        <variablelist><title>Essential Special Commands</title>
+            <varlistentry><term>\?</term><listitem><simpara>
+                help
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>\q</term><listitem><simpara>
+                quit
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>\j...</term><listitem><simpara>
+                View JDBC Data Source details or connect up to a JDBC Data
+                Source (replacing the current connection, if any).
+                Run \? to see the syntax for the different usages.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>\i path/to/script.sql</term><listitem><simpara>
+                execute the specified SQL script, then continue again
+                interactively.
+                Since SqlTool is a Java program, you can safely use forward
+                slashes in your file paths, regardless of your operating
+                system.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>\=</term><listitem><simpara>
+                commit the current SQL transaction.
+                Most users are used to typing the SQL statement
+                <literal>commit;</literal>, but this command is crucial for
+                those databases which don't support the statement.
+                It's obviously unnecessary if you have auto-commit mode on.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>\x?</term><listitem><simpara>
+                List a summary of DSV eXporting, and all available DSV options.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>\m?</term><listitem><simpara>
+                List a summary of DSV iMporting, and all available DSV options.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>\d?</term><listitem><simpara>
+                List a summary of the \d commands below.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>\dt [filter_substring]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\dv [filter_substring]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\ds [filter_substring]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\di [table_name]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\dS [filter_substring]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\da [filter_substring]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\dn [filter_substring]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\du [filter_substring]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\dr [filter_substring]</term><listitem><simpara/></listitem></varlistentry>
+            <varlistentry><term>\d* [filter_substring]</term><listitem><para>
+                Lists available objects of the given type.
+                <itemizedlist>
+                    <listitem><simpara>t: non-system Tables</simpara></listitem>
+                    <listitem><simpara>v: Views</simpara></listitem>
+                    <listitem><simpara>s: Sequences</simpara></listitem>
+                    <listitem><simpara>i: Indexes</simpara></listitem>
+                    <listitem><simpara>S: System tables</simpara></listitem>
+                    <listitem><simpara>a: Aliases</simpara></listitem>
+                    <listitem><simpara>n: schema Names</simpara></listitem>
+                    <listitem><simpara>u: database Users</simpara></listitem>
+                    <listitem><simpara>r: Roles</simpara></listitem>
+                    <listitem><simpara>*: all table-like objects</simpara></listitem>
+                </itemizedlist>
+                If your database supports schemas, then the schema name will
+                also be listed.
+                </para><simpara>
+                If you supply an optional <emphasis>filter substring</emphasis>,
+                then only items which match the specified substring.
+                will be listed.
+                In most cases, the specified filter will be treated as a
+                regular expression matched against the candidate object names.
+                In order to take advantage of extreme server-side performance
+                benefits, however, in some cases the substring is passed to
+                the database server and the filter will processed by the server.
+                </simpara> <important><simpara>
+                    The regexp test is case-sensitive!
+                    Even though in SQL queries and for the "\d objectname"
+                    command object names are usually case-insensitive, for
+                    the \dX commands, you must capitalize the filter
+                    substring exactly as it will appear in the special
+                    command output.
+                    This is an inconvenience, since the database engine
+                    will change names in SQL to default case unless you
+                    double-quote the name, but that is server-side
+                    functionality which cannot (portably) be reproduced by
+                    SqlTool.
+                    You can use spaces and other special characters in
+                    the string.
+                </simpara></important>
+                <tip><simpara>
+                    Filter substrings ending with "." are special.
+                    If a substring ends with ".", then this means to narrow
+                    the search by the exact, case-sensitive schema name
+                    given.
+                    For example, if I run "\d* BLAINE.", this will list all
+                    table-like database objects in the "BLAINE" schema.
+                    The capitalization of the schema must be exactly the same
+                    as how the schema name is listed by the "\dn" command.
+                    You can use spaces and other special characters in
+                    the string.
+                    (I.e., enter the name exactly how you would enter it
+                    inside of double-quotes in an SQL command).
+                    This is an inconvenience, since the database engine
+                    will change names in SQL to default case unless you
+                    double-quote the name, but that is server-side
+                    functionality which cannot (portably) be reproduced by
+                    SqlTool.
+                </simpara></tip>
+                <tip><simpara>
+                    The filter string "." (just a plain dot) means the current
+                    session schema, for databases which support the concept
+                    according to the SQL standard (HyperSQL database does).
+                </simpara></tip>
+                <important><simpara>
+                    Indexes may not be searched for by
+                    <emphasis>substring</emphasis>, only by
+                    exact target table name.
+                    So if <literal>I1</literal> is an index on table
+                    <literal>T1</literal>, then you list this index by running
+                    "\di T1".
+                    In addition, many database vendors will report on indexes
+                    only if a target table is identified.
+                    Therefore, "\di" with no argument will fail if your database
+                    vendor does not support it.
+                </simpara></important>
+            </listitem></varlistentry>
+            <varlistentry><term>\d objectname [[/]regexp]</term><listitem><simpara>
+                Lists names of columns in the specified table or view.
+                <literal>objectname</literal> may be a base table name or
+                a schema.object name.
+                </simpara><simpara>
+                If you supply a filter string, then only columns with a name
+                matching the given regular expression will be listd.
+                (If no special characters are used, this just means that
+                names containing the specified substring will match).
+                You'll find this filter is a great convenience compared to
+                other database utilities, where you have to list all columns
+                of large tables when you are only interested in one of them.
+                </simpara><simpara>
+                To narrow the displayed information based on all column
+                outputs, instead of just the column names, just prefix the
+                expression with /.
+                For example, to list all INTERGER columns, you could run
+                <literal>\d mytable /INTEGER</literal>.
+                </simpara><tip><simpara>
+                When working with real data (as opposed to learning or playing),
+                I often find it useful to run two SqlTool sessions in two
+                side-by-side terminal emulator windows.
+                I do all of my real work in one window, and use the other
+                mostly for \d commands.
+                This way I can refer to the data dictionary while writing SQL
+                commands, without having to scroll.
+            </simpara></tip></listitem></varlistentry>
+        </variablelist>
+        <simpara>
+            This list here includes only the <emphasis>essential</emphasis>
+            Special Commands, but n.b. that there are other useful Special
+            Commands which you can list by running <literal>\?</literal>.
+            (You can, for example, execute SQL from external SQL files, and
+            save your interactive SQL commands to files).
+            Some specifics of these other commands are specified immediately
+            below, and the
+            <link xlink:href='#sqltool_report-sect' endterm='report-title'/>
+            section explains how to use the "\o" and "\H" special commands to
+            generate reports.
+        </simpara> <simpara>
+            Be aware that the <literal>\!</literal> Special Command does
+            not work for external programs that read from standard input.
+            You can invoke non-interactive and graphical interactive programs,
+            but not command-line interactive programs.
+        </simpara> <simpara>
+            SqlTool executes <literal>\!</literal> programs directly, it does
+            not run an operating system shell (this is to avoid OS-specific
+            code in SqlTool).
+            Because of this, you can give as many command-line arguments
+            as you wish, but you can't use shell wildcards or redirection.
+        </simpara> <simpara>
+            The \w command can be used to store any command in your SQL
+            history to a file.
+            Just restore the command to the edit buffer
+            with a command like "\-4" before you give the \w command.
+        </simpara>
+        </section>
+        <section><title>Edit Buffer / History Commands</title>
+        <variablelist><title>Edit Buffer / History Commands</title>
+            <varlistentry><term>:?</term><listitem><simpara>
+                help
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>:b</term><listitem><simpara>
+                List the current contents of the edit buffer.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>:h</term><listitem><simpara>
+                Shows the Command History.
+                For each command which has been executed (up to the max
+                history length), the SQL command history will show the
+                command; its command number (#); and also how many commands
+                <emphasis>back</emphasis> it is (as a negative number).
+                : commands are never added to the history list.
+                You can then use either form of the command identifier to
+                recall a command to the edit buffer (the command described
+                next) or as the target of any of the following : commands.
+                This last is accomplished in a manner very similar to the
+                vi editor.
+                You specify the target command number between the colon
+                and the command.
+                As an example, if you gave the command
+                <literal>:s/X/Y/</literal>, that would perform the
+                substitution on the contents of the edit buffer; but if you
+                gave the command <literal>:-3 s/X/Y/</literal>, that would
+                perform the substitution on the command 3 back in the
+                command history (and copy the output to the edit buffer).
+                Also, just like vi, you can identify the command to recall
+                by using a regular expression inside of slashes, like
+                <literal>:/blue/ s/X/Y/</literal> to operate on the last
+                command you ran which contains "blue".
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>:13  OR  :-2  OR   :/blue/</term><listitem><simpara>
+                Recalls a command from Command history to the edit buffer.
+                Enter ":" followed by the positive command number from
+                Command history, like ":13"...  or ":" followed by a negative
+                number like ":-2" for two commands back in the Command
+                history... or ":" followed by a regular expression inside
+                slashes, like ":/blue/" to recall the last command which
+                contains "blue".
+                The specified command  will be written to the edit buffer
+                so that you can execute it or edit it using the commands below.
+                </simpara><simpara>
+                As described under the :h command immediately above,
+                you can follow the command number here with
+                any of the commands below to perform the given operation
+                on the specified command from history instead of on the
+                edit buffer contents.
+                So, for example, ":4;" would load command 4 from history
+                then execute it (see the ":;" command below).
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>:;</term><listitem><simpara>
+                Executes the SQL, Special or PL statement in the edit buffer
+                (by default).
+                This is an extremely useful command.
+                It's easy to remember because it consists of ":", meaning
+                <emphasis>Edit Buffer Command</emphasis>, plus a
+                line-terminating ";", (which generally means to execute an
+                SQL statement, though in this case it will also execute a
+                special or PL command).
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>:a</term><listitem><simpara>
+                Enter append mode with the contents of the edit buffer (by
+                default) as the current command.
+                When you hit ENTER, things will be nearly exactly the same
+                as if you
+                physically re-typed the command that is in the edit buffer.
+                Whatever lines you type next will be appended to the immediate
+                command.
+                As always, you then have the choice of hitting ENTER to
+                execute a Special or PL command, entering a blank line to
+                store back to the edit buffer, or end a SQL statement with
+                semi-colon and ENTER to execute it.
+                </simpara><simpara>
+                You can, optionally, put a string after the :a, in which
+                case things will be exactly as just described except the
+                additional text will also be appended to the new immediate
+                command.
+                If you put a string after the :a which ends with ;, then
+                the resultant new immediate command will just be executed
+                right away, as if you typed in and entered the entire thing.
+                </simpara><simpara>
+                If your edit buffer contains
+                <literal>SELECT x FROM mytab</literal> and you run
+                <literal>a:le</literal>, the resultant command will be
+                <literal>SELECT x FROM mytable</literal>.
+                If your edit buffer contains
+                <literal>SELECT x FROM mytab</literal> and you run
+                <literal>a: ORDER BY y</literal>, the resultant command will be
+                <literal>SELECT x FROM mytab ORDER BY y</literal>.
+                Notice that in the latter case the append text begins with a
+                space character.
+            </simpara><simpara>
+                You may notice that you can't use the left-arrow or backspace
+                key to back up over the original text.
+                This is due to Java and portability constraints.
+                If you want to edit existing text, then you shouldn't use the
+                Append command.
+            </simpara></listitem></varlistentry>
+            <varlistentry>
+                <term>:s/from regex/to string/switches</term>
+                <listitem>
+                <simpara>
+                The Substitution Command is the primary method for SqlTool
+                command editing-- it operates upon the current edit buffer
+                by default.
+                The "to string" and the "switches" are both optional (though
+                the final "/" is not).
+                To start with, I'll discuss the use and behavior if you don't
+                supply any substitution mode switches.
+                </simpara>
+                <para>
+                Don't use "/" if it occurs in either "from string" or "to
+                string".
+                You can use any character that you want in place of "/", but
+                it must not occur in the <emphasis>from</emphasis> or
+                <emphasis>to</emphasis> strings.
+                Example
+                <informalexample>
+                  <screen>    :s@from string@to string@</screen>
+                </informalexample></para>
+                <simpara>
+                The <emphasis>to string </emphasis> is substituted for the first
+                occurrence of the (case-specific)
+                <emphasis>from string</emphasis>.
+                The replacement will consider the entire SQL statement, even
+                if it is a multi-line statement.
+                </simpara><simpara>
+                In the example above, the from regex was a plain string, but
+                it is interpreted as a regular expression so you can do
+                all kinds of powerful substitutions.
+                See the <literal>perlre</literal> man page, or the
+                <link xlink:href='http://http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html'>java.util.regex.Pattern</link>
+                API Spec for everything you need to know about extended
+                regular expressions.
+                </simpara>
+                <simpara>
+                Don't end a <emphasis>to</emphasis> string with ";" in attempt
+                to make a command execute.
+                There is a substitution mode switch to use for that purpose.
+                </simpara><para>
+                You can use any combination of the substitution mode switches.
+                <itemizedlist>
+                    <listitem><para>
+                        Use "i" to make the searches for
+                        <emphasis>from regex</emphasis> case insensitive.
+                    </para></listitem> <listitem><para>
+                        Use "g" to substitute Globally, i.e., to subsitute
+                        <emphasis>all</emphasis> occurrences of the
+                        <emphasis>from regex</emphasis> instead of only the
+                        first occurrence found.
+                    </para></listitem> <listitem><para>
+                        Use ";" to execute the command immediately after the
+                        substitution is performed.
+                    </para></listitem> <listitem><para>
+                        Use "m" for ^ and $ to match each line-break in a
+                        multi-line edit buffer, instead of just at the very
+                        beginning and every end of the entire buffer.
+                    </para></listitem>
+                </itemizedlist>
+            </para>
+            <para>
+                If you specify a command number (from the command history),
+                you end up with a feature very reminiscent of vi, but even
+                more powerful, since the Perl/Java regular expression are
+                a superset of the vi regular expressions.
+                As an example,
+                <informalexample>
+                  <screen>    :24 s/pin/needle/g;</screen>
+                </informalexample> would start with command number 24 from
+                command history, substitute "needle" for all occurrences of
+                "pin", then execute the result of that substitution
+                (and this final statement will of course be copied to the
+                edit buffer and to command history).
+            </para>
+            </listitem></varlistentry>
+            <varlistentry><term>:w /path/to/file.sql</term><listitem><simpara>
+                This appends the contents of the current buffer (by default)
+                to the specified file.
+                Since what is being written are Special, PL, or SQL commands,
+                you are effectively creating an SQL script.
+            </simpara></listitem></varlistentry>
+        </variablelist>
+        <para>
+            I find the ":/regex/"  and ":/regex/;" constructs particularly
+            handy for every-day usage.
+            <informalexample>
+              <screen>    :/\\d/;</screen>
+            </informalexample>re-executes the last \d command that you gave
+            (The extra "\" is needed to escape the special meaning of "\"
+            in regular expressions).
+            It's great to be able to recall and execute the last "insert"
+            command, for example, without needing to check the history or
+            keep track of how many commands back it was.  To re-execute
+            the last insert command, just run ":/insert/;".
+            If you want to be safe about it, do it in two steps to verify
+            that you didn't accidentally recall some other command which
+            happened to contain the string "insert", like
+            <informalexample>
+                 <screen>    :/insert/
+    :;</screen>
+               </informalexample>(Executing the last only if you are
+            satisfied when SqlTool reports what command it restored).
+            Often, of course, you will want to change the command before
+            re-executing, and that's when you combine the :s and :a commands.
+        </para> <simpara>
+            We'll finish up with a couple fine points about Edit/Buffer
+            commands.
+            You generally can't use PL variables in Edit/Buffer commands, to
+            eliminate possible ambiguities and complexities when modifying
+            commands.
+            The :w command is an exception to this rule, since it can be
+            useful to use variables to determine the output file, and this
+            command does not do any "editing".
+        </simpara> <simpara>
+            The :? help explains how you can change the default regular
+            expression matching behavior (case sensitivity, etc.), but
+            you can always use syntax like "(?i)" inside of your regular
+            expression, as described in the Java API spec for class
+            <classname
+            xlink:href='http://http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html'>
+              java.util.regex.Pattern</classname>.
+            History-command-matching with the /regex/ construct is
+            purposefully liberal, matching any portion of the command,
+            case sensitive, etc., but you can still use the method just
+            described to modify this behavior.  In this case, you could
+            use "(?-i)" at the beginning of your regular expression to
+            be case-sensitive.
+        </simpara>
+        </section>
+
+        <section xml:id='sqltool_interactive_pl_commands-sect'>
+        <title>PL Commands</title>
+        <variablelist><title xml:id='interactive_pl_commands-title'>Essential PL Command</title>
+            <varlistentry><term>* VARNAME = value</term><listitem><simpara>
+                Set the value of a variable.
+                If the variable doesn't exist yet, it will be created.
+                The most common use for this is so that you can later use
+                it in SQL statements, print statements, and PL conditionals,
+                by using the <literal>*{VARNAME}</literal> or
+                <literal>*{:VARNAME}</literal> construct.
+                The only difference between <literal>*{literal}</literal> and
+                <literal>*{:VARNAME}</literal> is that the former produces an
+                error if VARNAME is not set, whereas the latter will expand
+                to a zero-length string if VARNAME is not set.
+            </simpara><simpara>
+                If you put variable definitions into the SQL file
+                <filename>auto.sql</filename> in your home directory, those
+                variables will always be available for interactive use.
+            </simpara> <simpara>
+                PL variables can be expanded within all commands other than
+                : edit/history commands.
+            </simpara>
+            </listitem></varlistentry>
+            <varlistentry><term>* load VARNAME /file/path.txt</term><listitem><simpara>
+                Sets VARNAME to the content of the specified ASCII file.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>* prepare VARNAME</term><listitem><simpara>
+                Indicate that next command should be a SQL INSERT or UPDATE
+                command containing one question mark.
+                The value of VARNAME will be substuted for the ? variable.
+                This does work for CLOB columns.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>* VARNAME _</term><listitem><simpara>
+                When next SQL command is run, instead of displaying the rows,
+                just store the very first column value to variable VARNAME.
+                This works for CLOB columns too.
+                It also works with Oracle XML type columns if you use
+                column labels and the <literal>getclobval</literal> function.
+            </simpara></listitem></varlistentry>
+            <varlistentry><term>* VARNAME ~</term><listitem><para>
+                Exactly the same as
+                <programlisting>    * VARNAME ~</programlisting>
+                except that the fetched results will be displayed in addition
+                to setting the variable.
+            </para></listitem></varlistentry>
+            <varlistentry><term>* dump VARNAME /file/path.txt</term><listitem><simpara>
+                Store the value of VARNAME to the specified ASCII file.
+            </simpara></listitem></varlistentry>
+        </variablelist>
+        <section>
+          <title>? Variable</title>
+          <para>
+            You don't set the ? variable.
+            It is just like the Bourne shell variable $? in that it is always
+            automatically set to the first value of a result set (or the
+            return value of other SQL commands).
+            It works just like the <literal>* VARNAME ~</literal>
+            command described above, but it all happens automatically.
+            You can, of course, dereference ? like any PL variable, but it
+            does not list with the <literal>list</literal> and
+            <literal>listvalues</literal> commands.
+            You can see the value whenever you want by running
+            <informalexample><programlisting>    \p *{?}</programlisting></informalexample>
+          </para>
+        <simpara>
+            Note that PL commands are used to upload and download column
+            values to/from local ASCII files, but the corresponding actions
+            for binary files use the special \b commands.
+            This is because PL variables are used for ASCII values and
+            you can store any number of column values in PL variables.
+            This is not true for binary column values.
+            The \b commands work with a single binary byte buffer.
+        </simpara> <simpara>
+            See the <link xlink:href='#sqltool_pl-sect' endterm='pl-title'/> section
+            below for information on using variables in other ways, and
+            information on the other PL commands and features.
+        </simpara>
+        </section>
+        <section xml:id='sqltool_binary_files-sect'>
+            <title xml:id='binary_files-title'>
+                Storing and retrieving binary files</title>
+        <simpara>
+            You can upload binary files such as photographs, audio files,
+            or serialized Java objects into database columns.
+            SqlTool keeps one binary buffer which you can load from files
+            with the \bl command, or from a database query by doing a
+            one-row query for any non-displayable type (including
+            <literal>BLOB</literal>, <literal>OBJECT</literal>, and
+            <literal>OTHER</literal>).
+            In the latter case, the data returned for the first
+            non-displayable column of the first result row will be stored
+            into the binary buffer.
+        </simpara><simpara>
+            Once you have data in the binary buffer, you can upload it
+            to a database column (including <literal>BLOB</literal>,
+            <literal>OBJECT</literal>, and <literal>OTHER</literal> type
+            columns), or save it to a file.
+            The former is accomplished by the special command \bp followed
+            by a <emphasis>prepared</emphasis> SQL query containing one
+            question mark place-holder to indicate where the data gets
+            inserted.
+            The latter is accomplished with the \bd command.
+        </simpara><simpara>
+            You can also store the output from normal, displayable column
+            into the binary buffer by using the special command \b.
+            The very first column value from the first result row of the
+            next SQL command will be stored to the binary byte buffer.
+        </simpara>
+        <example><title>Inserting binary data into database from a file</title>
+          <screen>    \bl /tmp/favoritesong.mp3
+    \bp
+    INSERT INTO musictbl (id, stream) VALUES(3112, ?);</screen>
+        </example>
+        <example><title>Downloading binary data from database to a file</title>
+            <screen>    SELECT stream FROM musictbl WHERE id = 3112;
+    \bd /tmp/favoritesong.mp3</screen>
+        </example>
+        <simpara>
+            You can also store and retrieve text column values to/from
+            ASCII files, as documented in the
+            <link xlink:href='#sqltool_interactive_pl_commands-sect' endterm='interactive_pl_commands-title'/>
+            section.
+        </simpara>
+        </section>
+        <section><title>Command History</title>
+        <para>
+            The SQL history shown by the \h command, and used by other commands,
+            is truncated to 100 entries, since its utility comes from being
+            able to quickly view the history list.
+            You can change the history length by setting the system property
+            <literal>sqltool.historyLength</literal> to the desire integer
+            value (using any of the System Property mechanisms provided by
+            Java).
+            If there is any demand, I'll make the setting of this value more
+            convenient.
+        </para> <simpara>
+            The SQL history list contains all executed commands other than
+            Edit Buffer commands and comments, even if the command has a
+            syntax error or fails upon execution.
+            The reason for including bad commands is so that you can
+            recall and fix them if you wish to.
+            The same applies to the edit buffer.
+            If you copy a command to the edit buffer by entering blank
+            line, or if you edit the edit buffer, that edit buffer value
+            will never make it into the command history until and if
+            you execute it.
+        </simpara>
+        </section>
+        <section><title>Shell scripting and command-line piping</title>
+            <simpara>
+            You normally use non-interactive mode for input piping.
+            You specify "-" as the SQL file name.
+            See the <link xlink:href='#sqltool_scripting-sect' endterm='scripting-title'/>
+            subsection of the Non-Interactive chapter.
+            </simpara>
+        </section>
+        <section><title>Emulating Non-Interactive mode</title>
+            <simpara>
+            You can run SqlTool <emphasis>interactively</emphasis>, but
+            have SqlTool behave exactly as if it were processing an SQL
+            file (i.e., no command-line prompts, error-handling
+            that defaults to fail-upon-error, etc.).
+            Just specify "-" as the SQL file name in the command line.
+            This is a good way to test what SqlTool will do when it
+            encounters any specific command in an SQL file.
+            See the <link xlink:href='#sqltool_scripting-sect' endterm='scripting-title'/>
+            subsection of the Non-Interactive chapter for an example.
+            </simpara>
+        </section>
+    </section>
+
+    <section xml:id='sqltool_nonint-sect'>
+        <title xml:id='nonint-title'>Non-Interactive</title>
+        <simpara>
+            Read the <link xlink:href='#sqltool_int-sect' endterm='int-title'/>
+            section if you have not already,
+            because much of what is in this section builds upon that.
+            You can skip all discussion about Command History and the
+            edit buffer if you will not use those interactive features.
+        </simpara>
+        <important><simpara>
+            If you're doing data updates, remember to issue a commit command
+            or use the <literal>--autoCommit</literal> switch.
+        </simpara></important>
+        <simpara>
+            As you'll see, SqlTool has many features that are very
+            convenient for scripting.  But what really makes it superior for
+            automation tasks (as compared to SQL tools from other vendors)
+            is the ability to reliably detect errors and to control JDBC
+            transactions.
+            SqlTool is designed so that you can reliably determine if errors
+            occurred within SQL scripts themselves, and from the invoking
+            environment (for example, from a perl, Bash, or Python script,
+            or a simple cron tab invocation).
+        </simpara>
+        <section xml:id='sqltool_sqlswitch-sect'>
+            <title xml:id='sqlswitch-title'>Giving SQL on the Command Line</title>
+            <para>
+                If you just have a couple Commands to run, you can run them
+                directly from the comand-line or from a shell script without an
+                SQL file, like this.
+              <informalexample>
+                  <screen>java -jar $HSQLDB_HOME/lib/sqltool.jar --sql="SQL statement;" urlid</screen>
+            </informalexample>
+            <note>
+              <simpara>The <literal>--sql</literal> switch automatically implies
+                <literal>--noinput</literal>, so if you want to execute the
+                specified SQL before <emphasis>and in addition to</emphasis> an
+                interactive session (or stdin piping), then you must also give
+                the <emphasis>--stdinput</emphasis> switch.
+              </simpara>
+            </note>
+            </para><para>
+                Since SqlTool transmits SQL statements to the database engine
+                only when a line is terminated with ";", if you want feedback
+                from multiple SQL statements in an --sql expression, you will
+                need to use functionality of your OS shell to include
+                linebreaks after the semicolons in the expression.
+                With any Bourne-compatible shell, you can include linebreaks in
+                the SQL statements like this.
+                <informalexample>
+                  <screen>    java -jar $HSQLDB_HOME/lib/sqltool.jar --sql='
+        SQL statement number one;
+        SQL statement
+            number two;
+        SQL statement three;
+    ' urlid</screen>
+              </informalexample>
+            </para><note><simpara>
+                The multi-line examples in this section will only work as-is
+                with a Bourne-compatible shell.
+                With some ugliness they can be converted to C shell.
+                For Windows, you are better off to stick with SQL files for
+                multi-line input.
+            </simpara></note><para>
+                If you don't need feedback, just separate the SQL commands
+                with semicolons and the entire expression will be
+                <link xlink:href='#sqltool_chunk-sect'>chunked</link>.
+            </para><para>
+                The <emphasis>--sql</emphasis> switch is very useful for
+                setting shell variables to the output of SQL Statements, like
+                this.
+                <informalexample>
+                  <programlisting><![CDATA[    # A shell script
+    USERCOUNT=`java -jar $HSQLDB_HOME/lib/sqltool.jar --sql='
+        select count(*) from usertbl;
+    ' urlid` || {
+        # Handle the SqlTool error
+    }
+    echo "There are $USERCOUNT users registered in the database."
+    [ "$USECOUNT" -gt 3 ] && {   # If there are more than 3 users registered
+        # Some conditional shell scripting]]></programlisting>
+              </informalexample>
+            </para>
+        </section>
+        <section><title>SQL Files</title>
+            <simpara>
+                Just give paths to sql text file(s) on the command line after
+                the <emphasis>urlid</emphasis>.
+            </simpara><para>
+                Often, you will want to redirect output to a file, like
+                <informalexample>
+                  <screen><![CDATA[ java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql... > /tmp/file.log 2>&1]]></screen>
+            </informalexample></para><simpara>
+                You can also execute SQL files from an interactive session with
+                the "\i"' Special Command,
+                but be aware that the default behavior in an interactive
+                session is to continue upon errors.
+                If the SQL file was written without any concern for error
+                handling, then the file will continue to execute after errors
+                occur.
+                You could run <literal>\c false</literal> before
+                <literal>\i filename</literal>, but then your SqlTool session
+                will exit if an error is encountered in the SQL file.
+                If you have an SQL file without error handling, and you want
+                to abort that file when an error occurs, but not exit
+                SqlTool, the easiest way to accomplish this is usually to add
+                <literal>\c false</literal> to the top of the script.
+            </simpara><simpara>
+                If you specify multiple SQL files on the command-line, the
+                default behavior is to exit SqlTool immediately if any of
+                the SQL files encounters an error.
+            </simpara><simpara>
+                <emphasis role='bold'>
+                SQL files themselves have ultimate control over error handling.
+                </emphasis>
+                Regardless of what command-line options are set, or what
+                commands you give interactively, if a SQL file gives error
+                handling statements, they will take precedence.
+            </simpara><simpara>
+                You can also use \i in SQL files.
+                This results in nested SQL files.
+            </simpara><simpara>
+                You can use the following SQL file,
+                <filename xlink:href="#sample.sql-link">
+                  sample/sample.sql</filename>,
+                from your HyperSQL distribution
+                <footnoteref linkend='samplelocFn'/>.
+                It contains SQL as well as Special Commands making good
+                use of most of the Special Commands documented below.
+            </simpara>
+            <programlisting><xi:include href="../verbatim/sample/sample.sql"
+                                        parse="text"/></programlisting>
+            <para>
+                You can execute this SQL file with a Memory Only database with
+                a command like
+              <informalexample>
+              <programlisting>    java -jar $HSQLDB_HOME/lib/sqltool.jar  --sql='
+        create user tomcat password "x";
+    ' mem path/to/hsqldb/sample/sample.sql</programlisting>
+            </informalexample>
+            This shows how you can mix SQL on the command line, and SQL inside
+            an SQL file.
+            </para><note><simpara>
+                The example above uses Bourne shell syntax.
+                C shell syntax would be similar.
+                You would need to use an SQL file to accomplish this on Windows.
+            </simpara></note> <simpara>
+                (The <literal>--sql="create...;"</literal> arguments create an
+                account which the script uses).
+                You should see error messages between the
+                <literal>Continue-on-error...true</literal> and
+                <literal>Continue-on-error...false</literal>.  The script
+                purposefully runs commands that might fail there.
+                The reason the script does this is to perform
+                database-independent conditional table removals.
+                (The SQL clause <literal>IF EXISTS</literal> is more graceful
+                and succinct, so you may want to use that if you don't need to
+                support databases which don't support
+                <literal>IF EXISTS</literal>).
+                If an error occurs when continue-on-error is false, the
+                script would abort immedately.
+            </simpara>
+        </section>
+        <section xml:id='sqltool_scripting-sect'>
+            <title xml:id='scripting-title'>Piping and shell scripting</title>
+            <para>
+                You can of course, redirect output
+                <emphasis>from</emphasis> SqlTool to a file
+                or another program.
+                <informalexample>
+                  <screen><![CDATA[java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql > file.txt 2>&1
+
+java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql 2>&1 | someprogram...]]></screen>
+            </informalexample></para><para>
+                You can type commands in to SqlTool while being in
+                non-interactive mode by supplying "-" as the file name.
+                This is a good way to test how SqlTool will behave when
+                processing your SQL files.
+                <informalexample>
+                  <screen>    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid -</screen>
+                </informalexample></para>
+                <para>
+                This is how you have SqlTool read its input from another
+                program:
+                <example><title>Piping input into SqlTool</title>
+                  <screen>    echo "Some SQL commands with '$VARIABLES';" |
+    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid -</screen>
+            </example>
+            For a shell not as graceful as the Bourne-compatible shells, you
+            would need to type this all on the same line (or use a
+            line-continuation trick).
+            </para>
+            <warning><simpara>
+              Beware of null stdin to SqlTool (or SqlFile).
+              At least with Java 6 on UNIX, <classname>System.in</classname>
+              returns megabytes of garbage for reads if stdin is closed.
+              I consider this an obvious bug.
+              Therefore, unlike any other program you would invoke from scripts,
+              check stdin before running any Java program that will read from
+              it.
+              I consider this a big ugly bug in Java.
+              This is not just theoretical, because many remote execution
+              environments will have stdin closed off.
+            </simpara></warning>
+            <simpara>
+                Make sure that you also read the
+                <link xlink:href='#sqltool_sqlswitch-sect' endterm='sqlswitch-title'/>
+                section.
+                The <literal>--sql</literal> switch is a great facility to use
+                with shell scripts.
+            </simpara>
+        </section>
+        <section>
+            <title>Optimally Compatible SQL Files</title>
+            <simpara>
+                If you want your SQL scripts optimally compatible among other
+                SQL tools, then don't use any Special or PL Commands.
+                SqlTool has default behavior which I think is far superior to
+                the other SQL tools, but you will have to disable these
+                defaults in order to have optimally compatible behavior.
+            </simpara><para>
+                These switches provide compatibilty at the cost of poor
+                control and error detection.
+                <itemizedlist>
+                    <listitem>
+                        <simpara>
+                            --continueOnErr=true
+                        </simpara> <simpara>
+                            The output will still contain error messages about
+                            everything that SqlTool doesn't like
+                            (malformatted commands, SQL command failures,
+                            empty SQL commands), but SqlTool will continue to
+                            run.
+                            Errors will not cause rollbacks (but that won't
+                            matter because of the following setting).
+                        </simpara>
+                    </listitem>
+                    <listitem><simpara>--autoCommit</simpara></listitem>
+                </itemizedlist>
+            </para><simpara>
+                You don't have to worry about accidental expansion of
+                PL variables, since SqlTool will never expand PL variables
+                if you don't set any variables on the command line, or give
+                any "* " PL commands.
+                (And you could not have "* " commands in a compatible SQL
+                file).
+            </simpara>
+        </section>
+        <section><title>Comments</title>
+            <simpara>
+                Comments of the form <literal>/*...*/</literal> or
+                <literal>--</literal> behave as a SQL programmer would
+                expect, in all contexts other than in interactive
+                edit/history commands.
+            </simpara>
+            <simpara>
+                If a comment occurs outside of an SQL statement, SqlTool
+                will not send the comment to the database (to improve
+                performance).
+                Raw mode can be used to send just comments to the database.
+                In order to proactively catch accidents, SqlTool will complain
+                if you attempt to send an empty SQL statement (i.e., just
+                whitespace) to the database, even in raw mode.
+            </simpara>
+        </section>
+        <section>
+            <title>Special Commands and Edit Buffer Commands in SQL Files</title>
+            <simpara>
+                Don't use Edit Buffer / History Commands in your sql files,
+                because they won't work.
+                Edit Buffer / History Commands are for interactive use only.
+                (But, see the
+                <link xlink:href='#sqltool_raw-sect' endterm='raw-title'/> section
+                for an exception).
+                You can, of course, use any SqlTool command at all
+                interactively.
+                I just wanted to group together the commands most useful to
+                script-writers.
+            </simpara>
+            <variablelist>
+                <varlistentry><term>\q [abort message]</term><listitem><para>
+                    Be aware that the \q command will cause SqlTool to
+                    completely exit.
+                    If a script <filename>x.sql</filename> has a \q command in
+                    it, then it doesn't matter if the script is executed like
+          <screen>    java -jar .../sqltool.jar urlid a.sql x.sql z.sql</screen>
+                    or if you use
+                    \i to read it in interactively, or if another SQL file
+                    uses \i to nest it.
+                    If \q is encountered, SqlTool will quit.
+                    See the <link xlink:href='#sqltool_pl-sect' endterm='pl-title'/>
+                    section for commands to abort an SQL file (or even parts
+                    of an SQL file) without causing SqlTool to exit.
+                </para><para>
+                    \q takes an optional argument, which is an abort message.
+                    If you give an abort message, the message is displayed to
+                    the user and SqlTool will exit with a failure status.
+                    If you give no abort message, then SqlTool will exit
+                    quietly with successful status.
+                    As a result, <programlisting>    \q</programlisting>
+                    means to make an immediate but graceful exit, whereas
+                    <programlisting>    \q Message</programlisting>
+                    means to abort immediately.
+                </para></listitem></varlistentry>
+                <varlistentry><term>\p [text to print]</term><listitem><simpara>
+                    Print the given string to stdout.
+                    Just give "\p" alone to print a blank line.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>\i /path/to/file.sql</term><listitem><simpara>
+                    Include another SQL file at this location.
+                    You can use this to nest SQL files.
+                    For database installation scripts I often have a master
+                    SQL file which includes all of the other SQL files in the
+                    correct sequence.
+                    Be aware that the current continue-upon-error behavior
+                    will apply to included files until such point as the SQL
+                    file runs its own error handling commands.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>\o [file/path.txt]</term><listitem><para>
+                    Tee output to the specified file (or stop doing so).
+                    See the
+                    <link xlink:href='#sqltool_report-sect' endterm='report-title'/>
+                    section.
+                </para></listitem></varlistentry>
+                <varlistentry><term>\=</term><listitem><simpara>
+                    A database-independent way to commit your SQL session.
+                    Useful for database which have no <literal>COMMIT</literal>
+                    SQL statement.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>\a [true|false]</term><listitem><simpara>
+                    This turns on and off SQL transaction autocommits.
+                    Auto-commit defaults to false, but you can change that
+                    behavior by using the <literal>--autoCommit</literal>
+                    command-line switch.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>\c [true|false]</term><listitem><simpara>
+                    A "true" setting tells SqlTool to Continue when errors are
+                    encountered.
+                    The current transaction will not be rolled back upon SQL
+                    errors, so if \c is true, then run the
+                    <literal>ROLLCACK;</literal> command yourself if that's
+                    what you want to happen.
+                    The default for interactive use is to continue upon error,
+                    but the default for non-interactive use is to abort upon
+                    error.
+                    You can override this behavior by using the
+                    <literal>--continueOnErr</literal> command-line switch.
+                    </simpara><simpara>
+                    With database setup scripts, I usually find it convenient
+                    to set "true" before dropping tables (so that things will
+                    continue if the tables aren't there), then set it back to
+                    false so that real errors are caught.
+                    <literal>DROP TABLE tablename IF EXISTS;</literal>
+                    is a more elegant, but less portable, way to accomplish
+                    the same thing.
+                    </simpara>
+                    <tip><simpara>
+                        It depends on what you want your SQL files to do, of
+                        course, but I usually want my SQL files to abort when
+                        an error is encountered, without necessarily killing
+                        the SqlTool session.
+                        If this is the behavior that you want, then
+                        put an explicit <literal>\c false</literal>
+                        at the top of your SQL file and turn on
+                        continue-upon-error only for sections where you really
+                        want to permit errors, or where you are using PL
+                        commands to handle errors manually.
+                        This will give the desired behavior whether your
+                        script is called by
+                        somebody interactively, from the SqlTool command-line,
+                        or included in another SQL file (i.e. nested).
+                    </simpara></tip><important><simpara>
+                        The default settings are usually best for people who
+                        don't want to put in any explicit \c or error handling
+                        code at all.
+                        If you run SQL files from the SqlTool command line,
+                        then any errors will cause SqlTool to roll back and
+                        abort immediately.
+                        If you run SqlTool interactively and invoke SQL files
+                        with \i commands, the scripts will continue to run
+                        upon errors (and will not roll back).
+                        This behavior was chosen because there are lots of
+                        SQL files out there that produce errors which can be
+                        ignored; but we don't want to ignore errors that a
+                        user won't see.
+                        I reiterate that any and all of this behavior can (and
+                        often should) be changed by Special Commands run in
+                        your interactive shell or in the SQL files.
+                        Only you know whether errors in your SQL files can
+                        safely be ignored.
+                    </simpara></important>
+                </listitem></varlistentry>
+            </variablelist>
+        </section>
+        <section><title>Automation</title>
+            <simpara>
+                SqlTool is ideal for mission-critical automation because,
+                unlike other SQL tools, SqlTool returns a dependable exit
+                status and gives you control over error handling and SQL
+                transactions.
+                Autocommit is off by default, so you can build a completely
+                dependable solution by intelligently using \c commands
+                (Continue upon Errors) and commit statements, and by
+                verifying exit statuses.
+            </simpara> <simpara>
+                Using the SqlTool Procedural Language, you have ultimate
+                control over program flow, and you can use variables for
+                database input and output as well as for many other purposes.
+                See the <link xlink:href='#sqltool_pl-sect' endterm='pl-title'/>
+                section.
+            </simpara>
+        </section>
+        <section><title>Getting Interactive Functionality with SQL Files</title>
+            <para>
+                Some script developers may run into cases where they want to
+                run with sql files but they alwo want SqlTool's interactive
+                behavior.
+                For example, they may want to do command recall in the sql file,
+                or they may want to log SqlTool's command-line prompts (which
+                are not printed in non-interactive mode).
+                In this case, do not give the sql file(s) as an argument to
+                SqlTool, but pipe them in instead, like
+                <informalexample>
+                  <screen><![CDATA[java -jar $HSQLDB_HOME/lib/sqltool.jar urlid < filepath1.sql > /tmp/log.html 2]]></screen>
+              </informalexample>
+                or
+              <informalexample>
+                <screen><![CDATA[cat filepath1.sql... |
+java -jar $HSQLDB_HOME/lib/sqltool.jar urlid > /tmp/log.html 2>&1]]></screen>
+            </informalexample>
+            For a shell not as graceful as the Bourne-compatible shells, you
+            would need to type this all on the same line (or use a
+            line-continuation trick).
+            </para>
+        </section>
+        <section xml:id='sqltool_charencoding-sect'><title xml:id='charencoding-title'>
+                Character Encoding</title>
+            <simpara>
+              There are several levels of encoding settings.
+              First there are your platform defaults.
+              These can be changed, temporarily or permanently, with system
+              settings or environmental variables.
+              Java system properties may be used to change the encodings for
+              the JVM run.
+              Finally, can specify a different encoding in your RC file, as
+              documented in the
+              <link xlink:href='#sqltool_auth-sect' endterm='auth-title'/>
+              section, though these will not effect stdin or stdout (as
+              explained there).
+              Programmatic users of <classname>SqlFile</classname> have
+              complete control over encoding by setting up
+              <classname>Reader</classname>s and
+              <classname>PrintWriter</classname>s,
+              or by using constructors with an <literal>encoding</literal>
+              parameter.
+              Developers should understand that where a
+              <filename>SqlFile</filename> constructor takes a
+              <classname>Reader</classname> or a
+              <classname>PrintWriter</classname> parameter, we will not apply
+              encoding settings to them, leaving that up to you.
+            </simpara>
+        </section>
+    </section>
+
+    <section xml:id='sqltool_report-sect'>
+        <title xml:id='report-title'>Generating Text or HTML Reports</title>
+        <simpara>
+            This section is about making a file containing the output of
+            database queries.
+            You can generate reports by using operating system facilities
+            such as redirection, tee, and cutting and pasting.
+            But it is much easier to use the "\o" and "\H" special commands.
+        </simpara>
+        <note><simpara>
+            I've neglected the \H feature, because I don't know of anybody
+            using it.
+            Be aware that it writes very old-fashioned HTML, with no attention
+            to encoding, metadata, style sheets, etc.
+        </simpara></note>
+        <procedure>
+            <title>Writing query output to an external file</title>
+            <step><simpara>
+                By default, everthing will be done in plain text.
+                If you want your report to be in HTML format, then give the
+                special command <literal>\H</literal>.
+                If you do so, you will probably want to use filenames with an
+                suffix of ".html" or ".htm" instead of ".txt" in the next step.
+            </simpara></step> <step><simpara>
+                Run the command <literal>\o path/to/reportfile.txt</literal>.
+                From this point on, output from your queries will be appended
+                to the specified file.
+                (I.e. another <emphasis>copy</emphasis> of the output is
+                generated.)
+                This way you can continue to monitor or use output as usual as
+                the report is generated.
+            </simpara></step> <step><simpara>
+                When you want SqlTool to stop writing to the file, run
+                <literal>\o</literal> (or just quit SqlTool if you have no
+                other work to do).
+            </simpara></step> <step><simpara>
+                If you turned on HTML mode with <literal>\H</literal> before,
+                you can run <literal>\H</literal> again to turn it back off,
+                if you wish.
+            </simpara></step>
+        </procedure>
+        <para>
+            It is not just the output of "SELECT" statements that will make
+            it into the report file, but
+            <itemizedlist>
+                <title>Kinds of output that get teed to \o files</title>
+                <listitem><simpara>
+                    Output of SELECT statements.
+                </simpara></listitem> <listitem><simpara>
+                    Output of all "\d" Special Commands.
+                    (I.e., "\dt", "\dv", etc., and "\d OBJECTNAME").
+                </simpara></listitem> <listitem><simpara>
+                    Output of "\p" Special Commands.
+                    You will want to use this to add titles, and perhaps
+                    spacing, for the output of individual queries.
+                </simpara></listitem>
+            </itemizedlist>
+            Other output will go to your screen or stdout, but will not make
+            it into the report file.
+            Be aware that no error messages will go into the report file.
+            If SqlTool is run non-interactively (including if you give any
+            SQL file(s) on the command line), SqlTool will abort with an error
+            status if errors are encountered.
+            The right way to handle errors is to check the SqlTool exit status.
+            (The described error-handling behavior can be modified with
+            SqlTool command-line switches and Special Commands).
+        </para> <warning><simpara>
+            Remember that \o <emphasis>appends</emphasis> to the named file.
+            If you want a new file, then use a new file name or remove the
+            pre-existing target file ahead of time.
+        </simpara></warning><tip><simpara>
+            So that I don't end up with a bunch of junk in my report file, I
+            usually leave \o off while I perfect my SQL.  With \o off,
+            I perfect the SQL query until it produces on my screen exactly
+            what I want saved to file.
+            At this point I turn on \o and run ":/select/;" to repeat the
+            last SQL command containing the given string ("select" in this
+            example).
+            If I have several complex queries to run, I turn \o off and
+            repeat until I'm finished.
+            (Every time you turn \o on, it will append to the file, just
+            like we need).
+            </simpara><simpara>
+            Usually it doesn't come to mind that I need a wider screen until
+            a query produces lines that are too long.
+            In this case, stretch your window and repeat the last command with
+            the ":;" Edit Buffer Command.
+        </simpara></tip>
+    </section>
+
+    <section xml:id='sqltool_pl-sect'>
+        <title xml:id='pl-title'>SqlTool Procedural Language</title>
+        <subtitle>Aka PL</subtitle>
+        <simpara>
+            Most importantly, run <filename>SqlTool</filename> interactively
+            and give the "*?" command to see what PL commands are available to
+            you.
+            I've tried to design the language features to be intuitive.
+            Readers experience with significant shell scripting in any
+            language can probably learn everything they need to know by
+            looking at (and running!) the sample script
+            <filename xlink:href="#pl.sql-link">
+              sample/pl.sql</filename> in your HyperSQL distribution
+            <footnoteref linkend='samplelocFn'/> and
+            using the <varname>*?</varname> command from within an interactive
+            SqlTool session as a reference.  (By
+            <emphasis>significant</emphasis> shell scripting, I mean to the
+            extent of using variables, for loops, etc.).
+        </simpara> <simpara>
+            PL variables will only be expanded after you run a PL command (or
+            set variable(s) from the command-line).
+            We only want to turn on variable expansion if the user wants
+            variable expansion.
+            People who don't use PL don't have to worry about strings getting
+            accidentally expanded.
+        </simpara> <simpara>
+            All other PL commands imply the "*" command, so you only need to
+            use the "*" statement if your script uses PL variables
+            and it is possible that no variables may be set before-hand (and
+            no PL commands have been run previously).
+            In this case, without "*", your script would silently use a
+            literal value like "*{x}" instead of trying to expand it.
+            With a preceding "*" command, PL will notice that the variable
+            <literal>x</literal> has not been set and will generate an error.
+            (If x had been set here will be no issue because setting a
+            variable automatically turns on PL variable expansion).
+        </simpara>
+        <simpara>
+            PL is also used to upload and download column values to/from
+            local ASCII files, analogously to the special \b commands
+            for binary files.
+            This is explained above in the Interactive
+            <link xlink:href='#sqltool_interactive_pl_commands-sect' endterm='interactive_pl_commands-title'/>
+            section above.
+        </simpara>
+        <section>
+            <title>Variables</title>
+            <itemizedlist>
+                <listitem><simpara>
+                    Use the <literal>* list</literal> command to list some or
+                    all variables; or <literal>* listvalues</literal> to also
+                    see the values.
+                </simpara></listitem> <listitem><simpara>
+                    You can set variables using the
+                    <literal>* VARNAME = value</literal> command.
+                    This document explains elsewhere how you can set a values
+                    to the contents of files, and to the return value of SQL
+                    statements and fetches.
+                </simpara></listitem> <listitem><simpara>
+                    You can also set variables using the
+                    <literal>--setvar</literal> command-line switch.
+                    I give a very brief but useful example of this below.
+                </simpara></listitem> <listitem><simpara>
+                    SqlTool does not allow for setting system variables.
+                    As explained below, they are expanded in the same way as
+                    PL variables.
+                </simpara></listitem> <listitem><simpara>
+                    Variables are always expanded in SQL, Special, and PL
+                    commands if they are written like
+                    <literal>*{VARNAME}</literal>
+                    (assuming that a PL command has been run previously).
+                    Your SQL scripts can give good feedback by echoing the
+                    value of variables with the "\p" special command.
+                    Use the construct <literal>*{:VARNAME}</literal> to
+                    expand the variable, but to expand to a zero-length
+                    string instead of fail if VARNAME is not set.
+                </simpara></listitem> <listitem><simpara>
+                    Java system variables work the same exact way, except you
+                    use <literal>$</literal> instead of <varname>*</varname>
+                    to dereference, like so:  <literal>${user.name}</literal>.
+                </simpara></listitem> <listitem><simpara>
+                    Variables are normally written like
+                    <varname>*VARNAME</varname> in logical expressions to
+                    prevent them from being evaluated too early.
+                    See below about logical expressions.
+                </simpara></listitem> <listitem><para>
+                    You can't do math with expression variables, but you
+                    can get functionality like the traditional
+                    <literal>for (i = 0; i &lt; x; i++)</literal> by appending
+                    to a variable and testing the string length, like
+                    <programlisting>    * while (*i &lt; ${x})
+        * i = *{i}.</programlisting>
+                    <literal>i</literal> will be a growing line of dots.
+                </para></listitem> <listitem><para>
+                Variable names must not contain white space, or
+                the characters "}" or "=".
+                </para></listitem>
+            </itemizedlist>
+        </section>
+        <section xml:id='sqltool_macro-sect'>
+            <title xml:id='macro-title'>Macros</title>
+            <simpara>
+                Macros are just shortcut commands that you can run in place of
+                the full commands which they stand for.
+                Macros stand for SQL, Special or PL commands, whereas PL
+                variables can only be used for elements within a command.
+                It is very easy to define, list, and use macros.
+                Run the command "/?" to see how.
+                If you often run a particular query, then for the effort of
+                about 5 extra keystrokes, you can define a macro for it so
+                that you can enter just "/q;" to run it, whether the original
+                query is 1 line or 40 lines.  (You can use any name in place
+                of "q", and the target command can be any kind of SQL,
+                special, or PL command).
+            </simpara> <para>
+                When you run/use a macro, you can append to the macro value.
+                <emphasis>appendage</emphasis> in the "/?" listing shows
+                where you can append additional text to the original command.
+                So, if you define
+                <programlisting>    sql> /= myworkers  SELECT name FROM employees</programlisting>
+                , you could narrow the query variously during different macro
+                invocations, like
+                <programlisting>    sql> /myworkers WHERE dept = 20;
+    sql> /myworkers WHERE name like 'Karen%';</programlisting>
+                </para><para>
+                Just like when recalling a command from history, you use ";"
+                to execute even Special and PL macro commands.
+                <programlisting>    sql> /= notate  Work completed by
+    sql> /notate Blaine;</programlisting>
+                If you don't type the ;, you will just recall the command
+                to the buffer (from which you can execute or edit it, if
+                you wish to).
+            </para> <simpara>
+                To make a macro for a mult-line SQL statement, you use the
+                "/= name :" construct.
+                First, get the target command into the command buffer.
+                If you have already run the command, then run ":h" to see the
+                command number and load it to the buffer like ":13".
+                If you haven't run the command yet, then just enter the
+                command, but end it with a blank line (and no semi-colon).
+                You can check the buffer with ":b" to make sure it is what
+                you want.
+                Then just run "/= name :" to define a macro with name "name".
+            </simpara>
+        </section>
+        <section><title>PL Sample</title>
+            <simpara>
+                Here is a short SQL file that gives the specified user write
+                permissions on some application tables.
+            </simpara>
+            <example><title>Simple SQL file using PL</title>
+                <programlisting>    /*
+       grantwrite.sql
+
+       Run SqlTool like this:
+           java -jar path/to/sqltool.jar -setvar=USER=debbie grantwrite.sql
+     */
+
+    /* Explicitly turn on PL variable expansion, in case no variables have
+       been set yet.  (Only the case if user did not set USER).
+    */
+    *
+
+    GRANT all ON book TO *{USER};
+    GRANT all ON category TO *{USER};</programlisting>
+            </example>
+            <simpara>
+                Note that this script will work for any (existing) user just
+                by supplying a different user name on the command-line.
+                I.e., no need to modify the tested and proven script.
+                There is no need for a <literal>commit</literal> statement
+                in this SQL file since no DML is done.
+                If the script is accidentally run without setting the
+                USER variable, SqlTool will give a very clear notificaton of
+                that.
+            </simpara> <simpara>
+                The purpose of the plain "*" command is just
+                so that the *{USER} variables will be expanded.
+                (This would not be necessary if the USER variable, or any
+                other variable, were set, but we don't want to depend upon
+                that).
+            </simpara>
+        </section>
+        <section>
+            <title>Logical Expressions</title>
+            <simpara>
+                Logical expressions occur only inside of logical expression
+                parentheses in PL statements.
+                For example, <literal>if (*var1 > astring)</literal> and
+                <literal>while (*checkvar)</literal>.
+                (The parentheses after "foreach" do not enclose a logical
+                expression, they just enclose a list).
+            </simpara> <simpara>
+                There is a critical difference between
+                <literal>*{VARNAME}</literal> and <varname>*VARNAME</varname>
+                inside logical expressions.
+                <literal>*{VARNAME}</literal> is expanded one time when the
+                parser first encounters the logical expression.
+                <varname>*VARNAME</varname> is re-expanded every time that the
+                expression is evaluated.
+                So, you would never want to code
+                <literal>* while (*{X} &lt; 5)</literal> because the statement
+                will always be true or always be false.
+                (I.e. the following block will loop infinitely or will never
+                run).
+            </simpara> <simpara>
+                Don't use quotes or whitespace of any kind in
+                <literal>*{VARNAME}</literal> variables in expressions.
+                (They would expand and then the expression would most likely
+                no longer be a valid expression as listed in the table below).
+                Quotes and whitespace are fine in <varname>*VARNAME</varname>
+                variables, but it is the entire value that will be used in
+                evaluations, regardless of whether quotes match up, etc.
+                I.e. quotes and whitespace are not <emphasis>special</emphasis>
+                to the token evaluator.
+            </simpara>
+            <variablelist>
+                <title>Logical Operators</title>
+                <varlistentry><term>TOKEN</term><listitem><simpara>
+                    The token may be a literal, a <literal>*{VARNAME}</literal>
+                    which is expanded early, or a <varname>*VARNAME</varname>
+                    which is expanded late.
+                    (You usually do not want to use
+                    <literal>*{VARNAME}</literal> in logical expressions).
+                    False if the token is not set, empty, or "0".
+                    True otherwise.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>TOKEN1 == TOKEN2</term><listitem><simpara>
+                    True if the two tokens are equivalent "strings".
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>TOKEN1 &lt;&gt; TOKEN2</term><listitem><simpara>
+                    Ditto.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>TOKEN1 &gt;&lt; TOKEN2</term><listitem><simpara>
+                    Ditto.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>TOKEN1 &gt; TOKEN2</term><listitem><simpara>
+                    True if the TOKEN1 string is longer than TOKEN2 or is
+                    the same length but is greater according to a string sort.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>TOKEN1 &lt; TOKEN2</term><listitem><simpara>
+                    Similarly to TOKEN1 &gt; TOKEN2.
+                </simpara></listitem></varlistentry>
+                <varlistentry><term>! LOGICAL_EXPRESSION</term><listitem><simpara>
+                    Logical negation of any of the expressions listed above.
+                </simpara></listitem></varlistentry>
+            </variablelist>
+            <simpara>
+                <varname>*VARNAME</varname>s in logical expressions, where the
+                VARNAME variable is not set, evaluate to an empty string.
+                Therefore <literal>(*UNSETVAR = 0)</literal> would be false,
+                even though <literal>(*UNSETVAR)</literal> by itself is false
+                and <literal>(0)</literal> by itself is false.
+                Another way of saying this is that <varname>*VARNAME</varname>
+                in a logical
+                expression is equivalent to *{:VARNAME} out of a logical
+                expression.
+            </simpara> <simpara>
+                When developing scripts, you definitely use SqlTool
+                interactively to verify that SqlTool evaluates logical
+                expressions as you expect.
+                Just run <literal>* if</literal> commands that print something
+                (i.e. \p) if the test expression is true.
+            </simpara>
+        </section>
+        <section>
+            <title>Flow Control</title>
+            <simpara>
+                Flow control works by conditionally executing blocks of
+                Commands according to conditions specified by logical
+                expressions.
+            </simpara> <simpara>
+                The conditionally executed blocks are called
+                <emphasis>PL Blocks</emphasis>.
+                These PL Blocks always occur between a PL flow control
+                statement (like <literal>* foreach, *while, * if</literal>)
+                and a corresponding <literal>* end</literal> PL Command
+                (like <literal>* end foreach</literal>).
+            </simpara> <simpara>
+                The values of control variables for foreach and while PL
+                blocks will change as expected.
+            </simpara> <simpara>
+                There are <literal>* break</literal> and
+                <literal>* continue</literal>, which work as any shell
+                scripter would expect them to.
+                The <literal>* break</literal> command can also be used to
+                quit the current SQL file without triggering any error
+                processing.
+                (I.e. processing will continue with the next line in the
+                <emphasis>including</emphasis> SQL file or interactive
+                session, or with the next SQL file if you supplied multiple on
+                the command-line).
+            </simpara>
+        </section>
+        <section> <title>Example</title>
+            <para>
+                Below is the example SQL file
+                <filename xlink:href="#pl.sql-link">sample/pl.sql</filename>,
+                which shows how to use most PL
+                features <footnoteref linkend='samplelocFn'/>.
+                If you have a question about how to use a particular
+                PL feature, check this file in your distrubition before asking
+                for help.
+                Definitely give it a run, like
+                <screen>java -jar $HSQLDB_HOME/lib/sqltool.jar mem $HSQLDB_HOME/pl.jar</screen>
+            </para>
+            <example><title>SQL File showing use of most PL features</title>
+                <programlisting><xi:include href="../verbatim/sample/pl.sql"
+                                            parse="text"/></programlisting>
+            </example>
+        </section>
+    </section>
+
+    <section xml:id='sqltool_chunk-sect'>
+        <title xml:id='chunk-title'>Chunking</title>
+        <para>
+            We hereby call the ability to transmit multiple SQL commands to
+            the database in one transmission <emphasis>chunking</emphasis>.
+            Normally it's best to send SQL statements to the database
+            one-at-a-time.
+            That way, the database can give you or your program feedback about
+            each statement.
+            But there are situations where it is more important to transmit
+            multiple-statements-at-a-time than to get feedback for each
+            statement individually.
+        </para>
+        <section>
+            <title>Why?</title>
+            <simpara>
+                The first general reason to chunk SQL commands is performance.
+                For standalone databases, the most common performance
+                bottleneck is network latency.
+                Chunking SQL commands can dramatically reduce network traffic.
+            </simpara> <simpara>
+              The second reason is that there are a couple SQL commands which
+              require the terminating ";" to be sent to the database engine.
+              For simplicity and efficiency, it's usually better for general
+              JDBC clients like SqlTool to strip off the final delimiter.
+              Raw commands retains everything that the user types.
+            </simpara> <para>
+                The third general reason to chunk SQL commands is if your
+                database requires you to send multiple commands in one
+                transmission.
+                This is usually the case with the following types of commands:
+                <itemizedlist>
+                    <listitem><simpara>
+                        Nested SQL commands, like the nested CREATE SCHEMA
+                        variant, and most stored procedure, function, and
+                        trigger definitions.
+                    </simpara></listitem><listitem><simpara>
+                        Commands containing non-quoted programming language to
+                        be interpreted by the database engine.
+                        Definitions of stored procedures, function, and triggers
+                        often contain code like this.
+                    </simpara></listitem>
+                </itemizedlist>
+            </para>
+        </section>
+        <section>
+            <title>How?</title>
+            <simpara>
+                Use raw mode.
+                Go to the
+                <link xlink:href='#sqltool_raw-sect' endterm='raw-title'/> section
+                to see how.
+                You can enter any text at all, exactly how you want it to
+                be sent to the database engine.
+                Therefore, in addition to chunking SQL commands, you can
+                give commands for non-SQL extensions to the database.
+                For example, you could enter JavaScript code to be used
+                in a stored procedure.
+            </simpara>
+        </section>
+    </section>
+
+    <section xml:id='sqltool_raw-sect'>
+        <title xml:id='raw-title'>Raw Mode</title>
+        <simpara>
+            You begin raw mode by issuing the Special Command "\.".
+            You can then enter as much text in any format you want.
+            When you are finished, enter a line consisting of only ".;"
+            to store the input to the edit buffer and send it to the
+            database server for execution.
+        </simpara> <simpara>
+            This paragraph applies only to interactive usage.
+            Interactive users may may end the raw input with ":."
+            instead of ".;".
+            This will just save the input to the edit buffer so that you can
+            edit it and send it to the database manually.
+            You can look at the edit buffer with the ":b" Buffer Command.
+            You would normally use the command ":;" to
+            send the buffer to the database after you are satisfied with it.
+            You'll notice that your prompt will be the "raw" prompt
+            between entering "\." and terminating the raw input with ".;"
+            or ":.".
+        </simpara> <simpara>
+            Just by running commands beginning with
+            <literal>BEGIN</literal>, <literal>DECLARE</literal>,
+            <literal>CREATE function</literal>,
+            or <literal>CREATE procedure</literal>, your SqlTool session will
+            automatically be changed to Raw mode, exactly as if you had entered
+            "\.".
+            That's because these commands are universally used to define
+            stored procedures or functions, and these commands require raw mode
+            (as explained in the previous section).
+        </simpara>
+        <para>
+          <example><title>Interactive Raw Mode example</title>
+            <screen>    sql> \.
+    Enter RAW SQL.  No \, :, * commands.
+    End with a line containing only ".;" to send to database,
+    or ":." to store to edit buffer for editing or saving.
+    -----------------------------------------------------------
+    raw> line one;
+    raw> line two;
+    raw> line three;
+    raw> :.
+    Raw SQL chunk moved into buffer.  Run ":;" to execute the chunk.
+    sql> :;
+    Executing command from buffer:
+    line one;
+    line two;
+    line three;
+
+    SQL Error at 'stdin' line 13:
+    "line one;
+    line two;
+    line three;"
+    Unexpected token: LINE in statement [line]
+    sql></screen>
+            </example>
+            The error message "Unexpected token: LINE in statement [line]"
+            comes from the database engine, not SqlTool.
+            All three lines were transmitted to the database engine.
+        </para>
+        <simpara>
+            Edit Buffer Commands are not available when running SqlTool
+            non-interactively.
+        </simpara>
+    </section>
+
+    <section xml:id="sqltool_embedded-langs-sect">
+      <title>SQL/PSM, SQL/JRT, and PL/SQL</title>
+        <simpara>
+          This section covers database-engine-embedded languages, which are
+          often used in the definition of stored procedures, stored functions,
+          and triggers.
+          <literal>SQL/PSM</literal>, <literal>SQL/JRT</literal>,
+          and <literal>PL/SQ:</literal> are well known examples.
+          We prefer <literal>SQL/PSM</literal> and <literal>SQL/JRT</literal>
+          because unlike the alternatives, they are based on open SQL
+          specifications.
+        </simpara>
+        <note><simpara>
+            PL/SQL is <emphasis role='bold'>not</emphasis> the same as
+            PL.  PL is the procedural language of SqlFile and is
+            independent of your back-end database.
+            PL commands always begin with *.
+            PL/SQL is an Oracle-specific extension processed on the server side.
+            You can not intermix PL and any server-embedded language
+            (except for setting a PL variable to the output of execution),
+            because when you enter server language to SqlTool, that input is
+            not processed by SqlFile.
+        </simpara></note>
+        <simpara>
+            Use <link xlink:href='#sqltool_raw-sect' endterm='raw-title'/> to send
+            server-language code blocks to the database engine.
+            You do not need to enter the "\." command to enter raw mode.
+            Just begin a new SqlTool command line with "DECLARE",
+            "BEGIN", "CREATE FUNCTION", or "CREATE PROCEDURE",
+            and SqlTool will automatically put you into raw mode.
+            See the <link xlink:href='#sqltool_raw-sect' endterm='raw-title'/>
+            section for details.
+        </simpara>
+        <para>
+            The following sample SQL file resides at
+            <filename xlink:href="#plsql.sql-link">sample/plsql.sql</filename>
+            in your HyperSQL distribution
+            <footnoteref linkend='samplelocFn'/>.
+            This script will only work with Oracle, only if you have
+            permission to create the table
+            "T1" in the default schema, and if that object does not
+            already exist.
+            <example><title>PL/SQL Example</title>
+                <programlisting><xi:include href="../verbatim/sample/plsql.sql"
+                                            parse="text"/></programlisting>
+            </example>
+            Note that, inside of raw mode, you can use any kind of formatting
+            that your database engine needs or permits:  Whatever you enter--
+            blank lines, comments,
+            everything-- will be transmitted to the database engine.
+        </para>
+        <para>
+          This file resides at
+          <filename xlink:href="#sqljrt.sql-link">
+            testrun/sqltool/sqljrt.sql</filename>
+          <example><title>SQL/JRT Example</title>
+      <programlisting><xi:include href="../verbatim/testrun/sqltool/sqljrt.sql"
+                            parse="text"/></programlisting>
+          </example>
+          This file resides at
+          <filename xlink:href="#sqlpsm.sql-link">
+            testrun/sqltool/sqlpsm.sql</filename>
+          <example><title>SQL/PSM Example</title>
+      <programlisting><xi:include href="../verbatim/testrun/sqltool/sqlpsm.sql"
+                            parse="text"/></programlisting>
+          </example>
+        </para>
+    </section>
+
+    <section xml:id="sqltool_dsv-sect">
+        <title>Delimiter-Separated-Value Imports and Exports</title>
+        <para>
+          SqlTool's DSV functionality encompasses what many users will
+          recognize as CSV export, as well as portable backup or transfer of
+          data.
+          Those familiar with Oracle's SQL*Loader will recognize the extreme
+          usefulness of the feature set.
+          Besides database- and platform-independent data backups, exports can
+          be used to deploy data sets with applications, to transfer data
+          among multiple database instances (even drastically different
+          database instances such as SQL Server and HyperSQL), and to properly
+          change control data sets with a content management system such as a
+          collaboration server or Subversion.
+          To jump way ahead for a moment to whet your appetite, here is a
+          sample <emphasis>import reject report</emphasis> which will can be
+          generated automatically for you upon import just by setting the PL
+          variable <varname>*DSV_REJECT_REPORT</varname> (to the desired
+          destination HTML file name).
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="rejreport-sample.png"
+                       align="center" format="PNG"/>
+             <!-- Instead of specifying width="6.5in" here, I've scaled the
+                  image file itself.  This causes HTML representation to
+                  display the image without distortion and reduction with its
+                  native size, and is manually sized correctly for PDF/PS. -->
+            </imageobject>
+            <caption>
+              <simpara>A DSV Import reject report</simpara>
+            </caption>
+          </mediaobject>
+          If you wish to, you can review the reject report before deciding
+          whether to commit or roll back the inserts.
+        </para>
+        <note><simpara>
+            This feature is independent of HyperSQL Text Tables.
+            (See the Text Tables chapter of the
+              <link xlink:href="&distro_baseurl;/guide/index.html">
+                HyperSQL User Guide</link> for details about them).
+            a server-side feature of HyperSQL.
+            It makes no difference to SqlTool whether the source or target
+            table of your export/import is a memory, cache, or text table.
+            Indeed, like all features of SqlTool, it works fine with other
+            JDBC databases.
+            It works great, for example to migrate data from a table
+            of one type to a table of another type, or to another schema,
+            or to another database instance, or to another database system.
+        </simpara></note>
+        <simpara>
+            This feature is what most business people call "CSV", but
+            these files are more accurately called <emphasis>Delimiter
+            Separated Value files</emphasis> because the delimiter is
+            usually not a comma, and, more importantly, we purposefully
+            choose an effective delimiter instead of the CSV method of
+            using a delimiter which works in some cases and then use
+            quotes and back-slashes to escape occurrence of the delimiter
+            in the actual data.
+            Just by choosing a delimiter which never needs escaping, we
+            eliminate the whole mess, and the data in our files always
+            looks just like the corresponding data in the database.
+            To make this CSV / Delimiter-separated-value dintinction clear,
+            I use the suffix ".dsv" for my data files.
+            This leads me to stipulate the abbreviation DSV for the
+            <emphasis>Delimiter Separated Value</emphasis> feature of HyperSQL.
+        </simpara><simpara>
+            Use the <literal>\x</literal> command to eXport a table to a
+            DSV file, and the <literal>\m</literal> command to iMport a
+            DSV file into a pre-existing table.
+        </simpara><simpara>
+            The row and column delimiters may be any String (or even a
+            regular expression for import), not just a single character.
+            And just as the delimiter capability is more general than
+            traditional CSV delimiters, the export function is also more
+            general than just a table data exporter.
+            Besides the trivial generalization that you may specify a
+            view or other virtual table name in place of a table name,
+            you can alternatively export the output of any query which
+            produces normal text output.
+            A benefit to this approach is that it allows you to export only
+            some columns of a table, and to specify a WHERE clause to narrow
+            down the rows to be exported (or perform any other SQL
+            transformation, mapping, join, etc.).
+            One specific use for this would be to exclude columns of
+            binary data (which can be exported by other means, such as
+            a PL loop to store binary values to files with the \bd command).
+        </simpara><simpara>
+            Note that the import command will not create a new table.
+            This is because of the impossibility of guessing appropriate
+            types and constraints based only on column names and a data
+            sampling (which is all that a DSV-importer has access to).
+            Therefore, if you wish to populate a new table, create the
+            table before running the import.
+            The import file does not need to have data for all columns of a
+            table.
+            The only required columns are those required by database
+            constraints (non-null, indexes, keys, etc.)
+            One specific reason to omit columns is if you want values of
+            some columns to be created automatically by column DEFAULT
+            settings, triggers, HyperSQL identity sequences, etc.
+            Another reason would be to skip binary columns.
+        </simpara>
+        <section>
+            <title>Simple DSV exports and imports using default settings</title>
+            <simpara>
+                Even if you need to change delimiters, table names, or file
+                names from the defaults, I suggest that you run one export
+                and import with default settings as a practice run.
+                A memory-only HyperSQL instance is ideal for test runs like this.
+            </simpara> <para>
+                This command exports the table <literal>icf.projects</literal>
+                to the file <filename>projects.dsv</filename> in the current
+                directory (where you invoked SqlTool from).
+                By default, the output file name will be the specified source
+                table name plus the extension <literal>.dsv</literal>.
+                <example><title>DSV Export Example</title>
+                    <screen>    SET SCHEMA icf;
+    \x projects</screen>
+                </example>
+                We could also have run <literal>\x icf.projects</literal>
+                (which would have created a file named
+                <filename>icf.projects.dsv</filename>)
+                instead of changing the session schema.
+                In this example we have chosen to make the export file name
+                independent of the schema to facilitate importing it into
+                a different schema.
+            </para> <simpara>
+                Take a look at the output file.
+                Notice that the first line consists of column names, not
+                data.
+                This line is present because it will be needed if the file is
+                to used for a DSV import.
+                Notice the following characterstics about the export data.
+                The column delimiter is the pipe character "|".
+                The record delimiter is the default line delimiter character(s)
+                for your operating system.
+                The string used to represent database <literal>NULL</literal>s
+                is <literal>[null]</literal>.
+                See the next section for how to change these from their default
+                values.
+            </simpara>
+            <warning><simpara>
+                You can not DSV import Array values where any Array elements
+                contain commas, for example an Array of VARCHARs which contain
+                one or more commas.
+                There is no such limitation on DSV exports, which you can use
+                for purposes other than SqlTool importing, or you could use
+                a script to change the commas to some other character.
+            </simpara></warning>
+            <para>
+                This command imports the data from the file
+                <filename>projects.dsv</filename> in the current
+                directory (where you invoked SqlTool from) into the table
+                <literal>newschema.projects</literal>.
+                By default, the output table name will be the input filename
+                after removing optional leading directory and trailing final
+                extension.
+                <example><title>DSV Import Example</title>
+                    <screen>    SET SCHEMA newschema;
+    \m projects.dsv</screen>
+                </example>
+                If the DSV file was named with the target schema, you would
+                have skipped the <literal>SET SCHEMA</literal> command, like
+                <literal>\m newschema.projects.dsv</literal>.
+                In order to allow for more flexibility, the default input
+                input delimiters are not exactly the same as the output
+                delimiters.
+                The input delimiters are regular expressions.
+                The input column delimiter happens to be the regular expression
+                corresponding exatly to "|"; but the input record delimiter
+                matches UNIX, Windows, Mac, and HTTP line breaks.
+            </para>
+        </section>
+        <section>
+            <title>Specifying queries and options</title>
+            <para>
+                For a hands on example of a DSM import which generates
+                an import report and uses some other options, change to
+                directory <filename>HSQLDB/sample</filename> and play
+                with the working script
+                <filename xlink:href="#dsv-sample.sql-link">
+                  dsv-sample.sql</filename>
+                <footnoteref linkend='samplelocFn'/>.
+                You can execute it like
+                <informalexample>
+            <screen>    java -jar ../lib/sqltool.jar mem dsv-sample.sql</screen>
+                </informalexample>
+                (assuming that you are using the supplied
+                <filename>sqltool.rc</filename> file or have have urlid
+                <literal>mem</literal> set up).
+            </para><simpara>
+                The header line in the DSV file is required at this time.
+                (If there is user demand, it can be made optional for
+                exporting, but it will remain required for importing).
+            </simpara><para>
+                Your export will fail if the output column or record delimiter,
+                or the null representation value occurs in the data being
+                exported.
+                You change these values by setting the PL variables
+                <varname>*DSV_COL_DELIM</varname>,
+                <varname>*DSV_ROW_DELIM</varname>,
+                <varname>*DSV_NULL_REP</varname>.
+                Notice that the asterisk is part of the variable names, to
+                indicate that these variables are used by SqlTool internally.
+                When specifying delimiters, you can use the escape seqpences
+                \n, \r, \f, \t, \\, and decimal, octal or hex specifications
+                like \20, \020, \0x20.
+                For example, to change the column delimiter to the tab character,
+                you would give the command
+                <informalexample>
+                  <screen>    * *DSV_COL_DELIM = \t</screen>
+                </informalexample>
+            </para><simpara>
+                The input (\m) delimiter values,
+                <varname>*DSV_COL_SPLITTER</varname> and
+                <varname>*DSV_ROW_SPLITTER</varname>, are set using normal
+                Perl/Java regexp syntax.
+                There are escapes for specifying special characters, and
+                anything else you would need.
+                Input vs. output row and column delimiters are easily
+                distinguished by containing "SPLITTER" for splitting input
+                (\m) files; or "DELIM" for the delimiters that we will write
+                (\x) among the data.
+            </simpara><para>
+                For imports, you must always specify the source DSV file path.
+                If you want to <emphasis>export</emphasis> to a different file
+                than one in the current directory named according to the source
+                table, set the PL variable <varname>*DSV_TARGET_FILE</varname>,
+                like
+                <informalexample>
+                  <screen>    * *DSV_TARGET_FILE = /tmp/dtbl.dsv</screen>
+                </informalexample>
+            </para><simpara>
+                For exports, you must always specify the source table name
+                or query.
+                If you want to <emphasis>import</emphasis> to a table other
+                than that derived from
+                the input DSV file name, set the PL variable
+                <varname>*DSV_TARGET_TABLE</varname>.
+                The table name may contain a schema name prefix.
+            </simpara><simpara>
+                You don't need to import all of the columns in a data file.
+                To designate the fields to be skipped, iether set the PL
+                PL variable <varname>*DSV_SKIP_COLUMNS</varname>, or replace
+                the column names in the header line to "-" (hyphen).
+                The value of <varname>*DSV_SKIP_COLUMNS</varname> is
+                case-insensitive, and multiple column names are separated with
+                white space and/or commas.
+            </simpara><para>
+                You can specify a query instead of a tablename with the
+                \x command in order to filter or transform data from a table
+                or view, or to export the output of a join, etc.
+                You must set the PL variable <varname>*DSV_TARGET_FILE</varname>,
+                as explained above (since there is no table name from which to
+                automatically map a file name).
+                <example>
+                    <title>DSV Export of an Arbitrary SELECT Statement</title>
+                    <screen>    * *DSV_TARGET_FILE = outfile.txt
+    \x SELECT entrydate, 2 * aval "Double aval", modtime FROM bs.dtbl</screen>
+                </example>
+                Note that I specified the column label alias "Double aval"
+                so that the label for that column in the DSV file header will
+                not be blank.
+            </para>
+            <simpara>
+                By default, imports will abort as soon as a error is
+                encountered during parsing the file or inserting data.
+                If you invoke SqlTool with a SQL script on the command line,
+                the failure will cause SqlTool to roll back and exit.
+                If run interactively, you can decide whether to commit or
+                roll back the rows that inserted before the failure.
+                You can modify this behavior with the \a and \c settings.
+            </simpara> <simpara>
+                If you set either a reject dsv file or a reject report file,
+                then failures during imports will be reported but will not
+                cause the import to abort.
+                When run in this way, SqlTool will give you a report at
+                the end about how many records were skipped, rejected, and
+                successfully inserted.
+                The reject dsv file is just a dsv file with exact copies of
+                the dsv records that failed to insert.
+                The reject report file is a HTML report which lists, for
+                every rejected record, why that record was rejected.
+                <literal>\m?</literal> will show you that the required PL
+                variables for this functionality are
+                <varname>*DSV_REJECT_FILE</varname>
+                and <varname>*DSV_REJECT_REPORT</varname>.
+                In both cases, you set the variable value to the path of the
+                file which SqlTool will create.
+            </simpara> <simpara>
+                To allow for user-friendly entry of headers, we require
+                that tables for DSV import/exports use standard column names.
+                I.e., no column names that require quoting.
+                The DSV import and export parsers are very smart and
+                user-friendly.
+                The data types of columns are checked so that the parser can
+                make safe assumptions about white space and blank entries in
+                the data.
+                If a column is a JDBC Boolean type, for example, then we
+                know that a field value of "  True " obviously means "True",
+                and that a field value of "" obviously means null.
+                Since we require vanilla style column names, we allow
+                white space anywhere in the header column.
+                We allow blank lines anywhere (where "lines" are delimited
+                by *DSV_ROW_DELIM).
+                By default, commented lines are ignored, and the comment
+                character can be changed from its default value.
+            </simpara> <simpara>
+                Run the command "\x?" or "\m?" to see the several system PL
+                variables which you can set to adjust reject file behavior,
+                commenting behavior, and other DSV features.
+            </simpara> <para>
+                You can also define some settings right in the DSV file,
+                and you can even specify multiple header lines in a single
+                DSV file.
+                I use this last feature to import data from one data set
+                into multple tables that are joined.
+                Since I don't have any more time to dedicate to explaining
+                all of these features, I'll give you some examples from
+                working DSV files and let you take it from there.
+        <example>
+            <title>Sample DSV headerswitch settings</title>
+            <programlisting>    # RCS keyword was here.
+
+    headerswitch{
+    itemdef:name|-|-|hardness|breakdc|-
+    simpleitemdef:itemdef_name|maxvalue|weight|-|-|maxhp
+    }</programlisting>
+        </example>
+            I'll just note that the prefixes for the header rows must be of
+            format target-table-name + :.
+            You can use * for target-table-name here, for the obvious purpose.
+        <example>
+            <title>DSV targettable setting</title>
+            <programlisting>    targettable=t</programlisting>
+        </example>
+                This last example is from the SqlTool unit test file
+                <filename>dsv-trimming.dsv</filename>.
+                These special commands must be at the top of the file
+                (before any normal data or header lines).
+            </para>
+            <simpara>
+                There is also the <varname>*DSV_CONST_COLS</varname> setting,
+                which you can use to automatically write static, constant
+                values to the specified columns of all inserted rows.
+            </simpara>
+        </section>
+    </section>
+
+    <section xml:id="sqltool_unittest-sect">
+        <title>Unit Testing SqlTool</title>
+        <simpara>
+          The SqlTool unit tests reside at testrun/sqltool in the
+          HyperSQL source code repository.
+          Just run the <filename>runtests.bash</filename> script from
+          that directory to execute all of the tests.
+          As you can see, the test runner, unfortunately, requires a Bash
+          shell at this time.
+          Read the file <filename>README.txt</filename> to find out all
+          about it, including everything you'd need to know to test your
+          own scripts or to add more unit test scripts for SqlTool.
+        </simpara>
+    </section>
+</chapter>
diff --git a/doc-src/util-guide/util-guide.xml b/doc-src/util-guide/util-guide.xml
new file mode 100644
index 0000000..d93da7d
--- /dev/null
+++ b/doc-src/util-guide/util-guide.xml
@@ -0,0 +1,729 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Id: util-guide.xml 3539 2010-03-17 15:47:21Z fredt $ -->
+<!DOCTYPE book [
+<!ENTITY % dummy22 SYSTEM "../entities/global.ent">
+%dummy22;
+<!ENTITY % dummy25 SYSTEM "entities/versions.ent">
+%dummy25;
+]>
+<book version="5.0" xmlns="http://docbook.org/ns/docbook"
+      xmlns:xlink="http://www.w3.org/1999/xlink"
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      xmlns:ns5="http://www.w3.org/2000/svg"
+      xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+      xmlns:ns3="http://www.w3.org/1999/xhtml"
+      xmlns:ns="http://docbook.org/ns/docbook">
+  <!-- We declare the default namespace + those for prefixes xlink: and xi: in
+       the root element, so we can use them anywhere in this file. -->
+
+  <info>
+    <title>HyperSQL Utilities Guide</title>
+
+    <authorgroup>
+      <editor>
+        <orgname>The HSQLB Development Group</orgname>
+      </editor>
+
+      <editor>
+        <personname><firstname>Blaine</firstname><surname>Simpson</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </editor>
+
+      <editor>
+        <personname><firstname>Fred</firstname><surname>Toussi</surname></personname>
+
+        <affiliation>
+          <orgname>The HSQL Development Group</orgname>
+        </affiliation>
+      </editor>
+    </authorgroup>
+
+    <releaseinfo>$Revision: 3539 $</releaseinfo>
+
+    <pubdate>$Date: 2010-03-17 11:47:21 -0400 (Wed, 17 Mar 2010) $</pubdate>
+
+    <keywordset>
+      <keyword>HyperSQL</keyword>
+
+      <keyword>Hsqldb</keyword>
+
+      <keyword>Hypersonic</keyword>
+
+      <keyword>Database</keyword>
+
+      <keyword>JDBC</keyword>
+
+      <keyword>Java</keyword>
+    </keywordset>
+
+    <legalnotice>
+      <para>Copyright 2002-2009 The HSQL Development Group. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license.</para>
+    </legalnotice>
+  </info>
+
+  <preface xml:id="book-pref">
+    <title>Preface</title>
+
+    <para>If you notice any mistakes in this document, please email the author
+    listed at the beginning of the chapter. If you have problems with the
+    procedures themselves, please use the HSQLDB support facilities which are
+    listed at <link
+    xlink:href="http://hsqldb.org/web/hsqlSupport.html"></link>.</para>
+
+    <xi:include href="../altformats-sect.xml" />
+  </preface>
+
+  <xi:include href="sqltool-chapt.xml" />
+
+  <chapter xml:id="test-utility-chapt">
+    <title>Hsqldb Test Utility</title>
+
+    <info>
+      <keywordset>
+        <keyword>Hsqldb</keyword>
+
+        <keyword>Test</keyword>
+
+        <keyword>Utility</keyword>
+      </keywordset>
+    </info>
+
+    <para>The <classname>org.hsqldb.test</classname> package contains a number
+    of tests for various functions of the database engine. Among these, the
+    <classname>TestUtil</classname> class performs the tests that are based on
+    scripts. To run the tests, you should compile the
+    <filename>hsqldbtest.jar</filename> target with Ant and JUnit.</para>
+
+    <para>The <classname>TestUtil</classname> class should be run in the
+    /testrun/hsqldb directory of the distributed files. It then runs the set
+    of TestSelf*.txt files in the directory. To start the application in
+    Windows, change to the directory and type:</para>
+
+    <screen> java org.hsqldb.test.TestUtil</screen>
+
+    <para>All files in the working directory with names matching TestSelf*.txt
+    are processed in alphabetical order.</para>
+
+    <para>You can add your own scripts to test different series of SQL
+    queries. The format of the TestSelf*.txt file is simple text, with some
+    indentation and prefixes in the form of Java-style comments. The prefixes
+    indicate what the expected result should be.</para>
+
+    <para>The class <classname>org.hsqldb.test.TestScriptRunner</classname> is
+    a more general program which you can use to test any script files which
+    you specify (with scripts of the same exact format as described below).
+    For example, <screen>java org.hsqldb.test.TestScriptRunner --urlid=mem script1.tsql script2.sql</screen>
+    You must have the HSQLDB classes, including the util and test classes, in
+    your <varname>CLASSPATH</varname>. The urlid must be set up in an RC file
+    as explained in the <link endterm="auth-title"
+    xlink:href="#sqltool_auth-sect"></link> section. Use the
+    <literal>rcfile=</literal> argument to specify an RC file other than the
+    default of <filename>testscriptrunner.rc</filename> in the current
+    directory. To see all invocation possibilities, just run TestScriptRunner
+    with no arguments at all. TestScriptRunner can run tests sequentially (the
+    default) or in simultaneous asynchronous threads.</para>
+
+    <itemizedlist>
+      <listitem>
+        <para>Comment lines must start with -- and are ignored</para>
+      </listitem>
+
+      <listitem>
+        <para>Lines starting with spaces are the continuation of the previous
+        line (for long SQL statements)</para>
+      </listitem>
+
+      <listitem>
+        <para>SQL statements with no prefix are simply executed.</para>
+      </listitem>
+
+      <listitem>
+        <para><emphasis>The remaining items in this list exemplify use of the
+        available command line-prefixes.</emphasis></para>
+      </listitem>
+
+      <listitem>
+        <informalexample>
+          <simpara>The /*s*/ option stands for silent. It is used for
+          executing quries regardless of results. Used for preparation of
+          tests, not for actual tests.</simpara>
+
+          <programlisting>/*s*/ Any SQL statement - errors are ignored</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <informalexample>
+          <simpara>The /*c&lt;rows&gt;*/ option is for SELECT queries and
+          asserts the number of rows in the result matches the given
+          count.</simpara>
+
+          <programlisting>/*c&lt;rows&gt;*/ SQL statement returning count of &lt;rows&gt;</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <informalexample>
+          <simpara>The /*u*/ option is for queries that return an update
+          count, such as DELETE and UPDATE. It asserts the update count
+          matches.</simpara>
+
+          <programlisting>/*u&lt;count&gt;*/ SQL statement returning an update count equal to &lt;count&gt;</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <informalexample>
+          <simpara>The /*e*/ option asserts that the given query results in an
+          erros. It is mainly used for testing the error detection
+          capabilities of the engine. The SQL State of the expected error can
+          be defined, for example /*e42578*/, to verify the returned error.
+          This option can be used with syntactically valid queries to assert a
+          certain state in the database. For example a CREATE TABLE can be
+          used to assert the table of the same name already exists.</simpara>
+
+          <programlisting>/*e*/ SQL statement that should produce an error when executing</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <informalexample>
+          <simpara>The /*r....*/ option asserts the SELECT query returns a
+          single row containing the given set of field values.</simpara>
+
+          <programlisting>/*r&lt;string1&gt;,&lt;string2&gt;*/ SQL statement returning a single row ResultSet equal to the specified value</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <informalexample>
+          <simpara>The extended /*r...*/ option asserts the SELECT query
+          returns the given rows containing the given set of field
+          values.</simpara>
+
+          <programlisting>/*r
+    &lt;string1&gt;,&lt;string2&gt;
+    &lt;string1&gt;,&lt;string2&gt;
+    &lt;string1&gt;,&lt;string2&gt;
+*/ SQL statement returning a multiple row ResultSet equal to the specified values</programlisting>
+        </informalexample>
+
+        <simpara>(note that the result set lines are indented).</simpara>
+      </listitem>
+
+      <listitem>
+        <simpara>The /*d*/ directive just displays the supplied
+        text.</simpara>
+
+        <informalexample>
+          <programlisting>/*d*/ Some message</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <simpara>The /*w MILLIS*/ directive causes the test to Wait for a
+        specified number of millisedonds.</simpara>
+
+        <informalexample>
+          <programlisting>/*w 1000*/ Optional message</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <simpara>The /*w ENFORCE_SEQUENCE WAITER_NAME*/ directive causes the
+        test to Wait for the specified <emphasis>Waiter</emphasis>. A waiter
+        is just name that is used to associate a /*w*/ directive to its
+        corresponding /*p*/ directive. The ENFORCE_SEQUENCE argument must be
+        set to <literal>true</literal> or <literal>false</literal> to specify
+        whether to fail unless the /*p*/ command runs after the /*w*/ command
+        is waiting.</simpara>
+
+        <informalexample>
+          <programlisting>/*w true script4*/ Optional message</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <simpara>The /*p ENFORCE_SEQUENC WAITER_NAME*/ directive is the peer
+        directive to /*w*/, which causes a waiting thread to
+        Proceed.</simpara>
+
+        <informalexample>
+          <programlisting>/*p true script4*/ Optional message</programlisting>
+        </informalexample>
+      </listitem>
+
+      <listitem>
+        <para>All the options are lowercase letters. During development, an
+        uppercase can be used for a given test to exclude a test from the test
+        run. The utility will just report the test blocks that have been
+        excluded without running them. Once the code has been developed, the
+        option can be turned into lowercase to perform the actual test.</para>
+      </listitem>
+    </itemizedlist>
+
+    <simpara>See the TestSelf*.txt files in the /testrun/hsqldb/ directory for
+    actual examples.</simpara>
+
+    <para>The String <literal>${timestamp}</literal> may be used in script
+    messages (like in /*d*/, /*w*/, /*p*/). It expands to the current time,
+    down to the second. For example, <informalexample>
+        <programlisting>/*d*/ It is now ${timestamp}</programlisting>
+      </informalexample></para>
+  </chapter>
+
+  <chapter xml:id="dbm-chapt">
+    <title>Database Manager</title>
+
+    <info>
+      <authorgroup>
+        <author>
+          <personname><firstname>Fred</firstname>
+          <surname>Toussi</surname></personname>
+
+          <affiliation>
+            <orgname>The HSQL Development Group</orgname>
+          </affiliation>
+        </author>
+
+        <author>
+          <personname><firstname>Blaine</firstname>
+          <surname>Simpson</surname></personname>
+
+          <affiliation>
+            <orgname>The HSQL Development Group</orgname>
+          </affiliation>
+        </author>
+      </authorgroup>
+
+      <!-- No sense for separate stamps while this is in a shared file.
+    <releaseinfo>$Revision: 3539 $</releaseinfo>
+
+    <pubdate>$Date: 2010-03-17 11:47:21 -0400 (Wed, 17 Mar 2010) $</pubdate>
+    -->
+
+      <keywordset>
+        <keyword>Hsqldb</keyword>
+
+        <keyword>Database</keyword>
+
+        <keyword>Manager</keyword>
+      </keywordset>
+    </info>
+
+    <section xml:id="dbm_intro-sect">
+      <title>Brief Introduction</title>
+
+      <para>The Database Manager tool is a simple GUI database query tool with
+      a tree display of the tables. Both AWT and SWING versions of the tool
+      are available and work almost identically. The AWT version class name is
+      org.hsqldb.util.DatabaseManager; the SWING version,
+      org.hsqldb.util.DatabaseManagerSwing. The SWING version has more
+      refinements than the AWT version.</para>
+
+      <para>The AWT version of the database manager can be deployed as an
+      applet in a browser. A demo HTML file with an embedded Database Manager
+      is included in the /demo directory.</para>
+
+      <para>When the Database Manager is started, a dialogue allows you to
+      enter the JDBC driver, URL, user and password for the new connection. A
+      drop-down box, Type, offers preset values for JDBC driver and URL for
+      most popular database engines, including HSQLDB. Once you have selected
+      an item from this drop-down box, you should edit the URL to specify the
+      details of the database or any additional properties to pass. You should
+      also enter the username and password before clicking on the OK
+      button.</para>
+
+      <para>The connection dialogue allows you to save the settings for the
+      connection you are about to make. You can then access the connection in
+      future sessions. To save a connection setting, enter a name in the
+      Setting Name box before clicking on the OK button. Next time the
+      connection dialogue is displayed, the drop-down box labeled Recent will
+      include the name for all the saved connection settings. When you select
+      a name, the individual settings are displayed in the appropriate
+      boxes.</para>
+
+      <para>The small Clr button next to the drop-down box allows you to clear
+      all the saved settings. If you want to modify an existing setting, first
+      select it from the drop-down box then modify any of the text boxes
+      before making the connection. The modified values will be saved.</para>
+
+      <simpara>Most SWING menu items have context-sensitive tool tip help text
+      which will appear if you hold the mouse cursor still over the desired
+      menu item. (Assuming that you don't turn Tooltips off under the
+      <guimenu>Help</guimenu> menu.</simpara>
+
+      <simpara>The database object tree in the SWING version allows you to
+      right click on the name of a table or column and choose from common SQL
+      statements for the object, for example SELECT * FROM thistable ... If
+      you click on one of the given choices, the sample statement is copied to
+      the command window, where you can modify and complete it.</simpara>
+
+      <simpara>The DatabaseManagers do work with HSQLDB servers serving
+      TLS-encrypted JDBC data. See the TLS section of the Listeners chapter of
+      the <link xlink:href="distro_baseurl_DEFAULTVAL/guide/index.html">
+      HyperSQL User Guide</link></simpara>
+
+      <tip>
+        <simpara>If you are using DatabaseManagerSwing with Oracle, you will
+        want to make sure that <guimenuitem>Show row counts</guimenuitem> and
+        <guimenuitem>Show row counts</guimenuitem> are both off
+        <emphasis>before connecting to the database</emphasis>. You may also
+        want to turn off Auto tree-update, as described in the next
+        section.</simpara>
+      </tip>
+    </section>
+
+    <section xml:id="dbm_tree-sect">
+      <title>Auto tree-update</title>
+
+      <simpara>By default, the object tree in the left panel is refreshed when
+      you execute DDL which may update those objects. If you are on a slow
+      network or performance-challenged PC, use the <guimenu>view</guimenu> /
+      <guimenuitem>Auto-refresh tree</guimenuitem> menu item to turn it off.
+      You will then need to use the
+      <guimenu>view</guimenu><guimenuitem>Refresh tree</guimenuitem> menu item
+      every time that you want to refresh the tree.</simpara>
+
+      <note>
+        <simpara>Auto-refresh tree does not automatically show all updates to
+        database objects, it only refreshes when you submit DDL which may
+        update database objects. (This behavior is a compromise between
+        utility and performance).</simpara>
+      </note>
+    </section>
+
+    <section xml:id="dbm-autoconn-sect">
+      <title>Automatic Connection</title>
+
+      <para>You can use command-line switches to supply connection
+      information. If you use these switch(es), then the connection dialog
+      window will be skipped and a JDBC connection will be established
+      immediately. Assuming that the <filename>hsqldb.jar</filename> (or an
+      alternative jar) are in your <varname>CLASSPATH</varname>, this command
+      will list the available command-line options. <informalexample>
+          <screen>    java org.hsqldb.util.DatabaseManagerSwing --help</screen>
+        </informalexample></para>
+
+      <simpara>It's convenient to skip the connection dialog window if you
+      always work with the same database account.</simpara>
+
+      <warning>
+        <simpara>Use of the --password switch is not secure. Everything typed
+        on command-lines is generally available to other users on the
+        computer. The problem is compounded if you use a network connection to
+        obtain your command line. The RC File section explains how you can set
+        up automatic connections without supplying a password on the command
+        line.</simpara>
+      </warning>
+    </section>
+
+    <section xml:id="dbm_rcfile-sect">
+      <title>RC File</title>
+
+      <simpara>You can skip the connection dialog window securely by putting
+      the connection information into an RC file and then using the
+      <literal>--urlid</literal> switch to DatabaseManager or
+      DatabaseManagerSwing. This strategy is great for adding launch menu
+      items and/or launch icons to your desktop. You can set up one icon for
+      each of the database accounts which you regularly use.</simpara>
+
+      <simpara>The default location for the RC file is
+      <filename>dbmanager.rc</filename> in your home directory. The <link
+      endterm="auth-title" xlink:href="#sqltool_auth-sect"></link> section
+      explains how to put the connection information into this text file. If
+      you also run <link endterm="sqltool-title"
+      xlink:href="#sqltool-chapt"></link>, then you can share the RC file with
+      SqlTool by using a sym-link (if your operating system supports sym
+      links), or by using the <literal>--rcfile</literal> switch for either
+      SqlTool or DatabaseManagerSwing.</simpara>
+
+      <warning>
+        <simpara>Use your operating system facilities to prevent others from
+        reading your RC file, since it contains passwords.</simpara>
+      </warning>
+
+      <para>To set up launch items/icons, first experiment on your command
+      line to find exactly what command works. For example, <informalexample>
+          <screen>java -cp /path/to/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing --urlid mem</screen>
+        </informalexample> Then, use your window manager to add an item that
+      runs this command.</para>
+    </section>
+
+    <section xml:id="dbm_wold-sect">
+      <title>Using the current DatabaseManagers with an older HSQLDB
+      distribution.</title>
+
+      <simpara>This procedure will allow users of a legacy version of HSQLDB
+      to use all of the new features of the DatabaseManagers. You will also
+      get the new version of the SqlTool! This procedure works for distros
+      going back to 1.7.3.3 at least, probably much farther.</simpara>
+
+      <simpara>These instructions assume that you are capable of running an
+      Ant build. See the Building Appendix of the <link
+      xlink:href="distro_baseurl_DEFAULTVAL/guide/index.html"> HyperSQL User
+      Guide</link>.</simpara>
+
+      <procedure>
+        <step>
+          <simpara>Download and extract a current HSQLDB distribution. If you
+          don't want to use the source code, documentation, etc., you can use
+          a temporary directory and remove it afterwards.</simpara>
+        </step>
+
+        <step>
+          <simpara>Cd to the build directory under the root directory where
+          you extracted the distribution to.</simpara>
+        </step>
+
+        <step>
+          <simpara>Run <literal>ant hsqldbutil</literal>.</simpara>
+        </step>
+
+        <step>
+          <simpara>If you're going to wipe out the build directory, copy
+          <filename>hsqldbutil.jar</filename> to a safe location
+          first.</simpara>
+        </step>
+
+        <step>
+          <simpara>For now on, whenver you are going to run DatabaseManager*,
+          make sure that you have this <filename>hsqldbutil.jar</filename> as
+          the first item in your <varname>CLASSPATH</varname>.</simpara>
+        </step>
+      </procedure>
+
+      <para>Here's a UNIX example where somebody wants to use the new
+      DatabaseManagerSwing with their older HSQLDB database, as well as with
+      Postgresql and a local application. <informalexample>
+          <screen>CLASSPATH=/path/to/hsqldbutil.jar:/home/bob/myapp/classes:/usr/local/lib/pg.jdbc3.jar
+export CLASSPATH
+java org.hsqldb.util.DatabaseManagerSwing --urlid urlid</screen>
+        </informalexample></para>
+    </section>
+
+    <section xml:id="dbm_applet-sect">
+      <title>DatabaseManagerSwing as an Applet</title>
+
+      <simpara>DatabaseManagerSwing is also an applet. You can use it in HTML,
+      JSPs, etc. Be aware that in Applet mode, actions to load or save local
+      files will be disabled, and attempts to access any server other than the
+      HTML-serving-host will fail.</simpara>
+
+      <para>Since the Applet can not store or load locally saved preferences,
+      the only way to have persistent preference settings is by using Applet
+      parameters. <variablelist>
+          <title>DatabaseManagerSwing Applet Parameters</title>
+
+          <varlistentry>
+            <term>jdbcUrl</term>
+
+            <listitem>
+              <simpara>URL of a data source to auto-connect to. String
+              value.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>jdbcDriver</term>
+
+            <listitem>
+              <simpara>URL of a data source to auto-connect to. String value.
+              Defaults to
+              <classname>org.hsqldb.driver.JDBCDriver</classname>.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>jdbcUser</term>
+
+            <listitem>
+              <simpara>User name for data source to auto-connect to. String
+              value.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>jdbcPassword</term>
+
+            <listitem>
+              <simpara>Password for data source to auto-connect to. String
+              value. Defaults to zero-length string.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>schemaFilter</term>
+
+            <listitem>
+              <simpara>Display only object from this schema in the object
+              navigator. String value.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>laf</term>
+
+            <listitem>
+              <simpara>Look-and-feel. String value.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>loadSampleData</term>
+
+            <listitem>
+              <simpara>Auto-load sample data. Boolean value. Defaults to
+              false.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>autoRefresh</term>
+
+            <listitem>
+              <simpara>Auto-refresh the object navigator when DDL
+              modifications detected in user SQL commands. Boolean value.
+              Defaults to true.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>showRowCounts</term>
+
+            <listitem>
+              <simpara>Show number of rows in each table in the object
+              navigator. Boolean value. Defaults to false.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>showSysTables</term>
+
+            <listitem>
+              <simpara>Show system tables in the object navigator. Boolean
+              value. Defaults to false.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>showSchemas</term>
+
+            <listitem>
+              <simpara>Show object names like schema.name in object navigator.
+              Boolean value. Defaults to true.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>resultGrid</term>
+
+            <listitem>
+              <simpara>Show query results in Gui grid (as opposed to in plain
+              text). Boolean value. Defaults to true.</simpara>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>showToolTips</term>
+
+            <listitem>
+              <simpara>Show help hover-text. Boolean value. Defaults to
+              true.</simpara>
+            </listitem>
+          </varlistentry>
+        </variablelist></para>
+    </section>
+  </chapter>
+
+  <chapter xml:id="transfer-tool-chapt">
+    <title>Transfer Tool</title>
+
+    <info>
+      <authorgroup>
+        <author>
+          <personname><firstname>Fred</firstname>
+          <surname>Toussi</surname></personname>
+
+          <affiliation>
+            <orgname>The HSQL Development Group</orgname>
+          </affiliation>
+        </author>
+      </authorgroup>
+
+      <!-- No sense for separate stamps while this is in a shared file.
+    <releaseinfo>$Revision: 3539 $</releaseinfo>
+
+    <pubdate>$Date: 2010-03-17 11:47:21 -0400 (Wed, 17 Mar 2010) $</pubdate>
+    -->
+
+      <keywordset>
+        <keyword>Hsqldb</keyword>
+
+        <keyword>Transfer</keyword>
+      </keywordset>
+    </info>
+
+    <section xml:id="trantool_intro-sect">
+      <title>Brief Introduction</title>
+
+      <para>Transfer Tool is a GUI program for transferring SQL schema and
+      data from one JDBC source to another. Source and destination can be
+      different database engines or different databases on the same
+      server.</para>
+
+      <para>Transfer Tool works in two different modes. Direct transfer
+      maintains a connection to both source and destination and performs the
+      transfer. Dump and Restore mode is invoked once to transfer the data
+      from the source to a text file (Dump), then again to transfer the data
+      from the text file to the destination (Restore). With Dump and Restore,
+      it is possible to make any changes to database object definitions and
+      data prior to restoring it to the target.</para>
+
+      <para>Dump and Restore modes can be set via the command line with -d
+      (--dump) or -r (--restore) options. Alternatively the Transfer Tool can
+      be started with any of the three modes from the Database Manager's Tools
+      menu.</para>
+
+      <para>The connection dialogue allows you to save the settings for the
+      connection you are about to make. You can then access the connection in
+      future sessions. These settings are shared with those from the Database
+      Manager tool. See the appendix on Database Manager for details of the
+      connection dialogue box.</para>
+
+      <para>From version 1.8.0 Transfer Tool is no longer part of the
+      <filename>hsqldb.jar</filename>. You can build the
+      <filename>hsqldbutil.jar</filename> using the Ant command of the same
+      name, to build a jar that includes Transfer Tool and the Database
+      Manager.</para>
+
+      <para>When collecting meta-data, Transfer Tool performs SELECT * FROM
+      &lt;table&gt; queries on all the tables in the source database. This may
+      take a long time with some database engines. When the source database is
+      HSQLDB, this means memory should be available for the result sets
+      returned from the queries. Therefore, the memory allocation of the java
+      process in which Transfer Tool is executed may have to be high.</para>
+
+      <para>The current version of Transfer is far from ideal, as it has not
+      been actively developed for several years. The program also lacks the
+      ability to create UNIQUE constraints and creates UNIQUE indexes instead.
+      However, some bugs have been fixed in the latest version and the program
+      can be used with most of the supported databases. The best way to use
+      the program is the DUMP and RESTORE modes, which allow you to manually
+      change the SQL statements in the dump file before restoring to a
+      database. A useful idea is to dump and restore the database definition
+      separately from the database data.</para>
+    </section>
+  </chapter>
+
+  <xi:include href="filelinks-app.xml" />
+
+  <!--  Enable the index as soon as mark some index terms.
+  <index xml:id="book-ind"/>
+  -->
+</book>
diff --git a/doc-src/verbatim/sample/acl.txt b/doc-src/verbatim/sample/acl.txt
new file mode 100644
index 0000000..d3d57f9
--- /dev/null
+++ b/doc-src/verbatim/sample/acl.txt
@@ -0,0 +1,31 @@
+# $Id: acl.txt 826 2009-01-17 05:04:52Z unsaved $

+

+# Sample HyperSQL Network Listener ACL file.

+# Specify "allow" and "deny" rules

+# For address specifications, individual addresses, host names, and

+# network addresses with /bit suffix are allowed, but read the caveat about

+# host names below, under the sample "localhost" rule.

+

+# Blank lines ignored.

+   # Lines with # as the first non-whitespace character are ignored.

+

+

+allow 2001:db8::/32

+# Allow this 32-bit ipv4 subnet

+

+allow localhost

+# You should use numerical addresses in ACL files, unless you are certain that

+# the name will always be known to your network address resolution system

+# (assume that you will lose Internet connectivity at some time).

+# With a default name resolution setup on UNIX, you are safe to use names

+# defined in your /etc/hosts file.

+

+deny 192.168.101.253

+# Deny a single IP address.

+# In our example, 192.168.101.0/24 is our local, organizational network.

+# 192.168.101.253 is the IP address of our Intern's PC.

+# The Intern does not have permission to access our databases directly.

+

+allow 192.168.101.0/24

+

+# Any ipv4 or ipv6 candidate address not matched above will be denied

diff --git a/doc-src/verbatim/sample/dsv-sample.sql b/doc-src/verbatim/sample/dsv-sample.sql
new file mode 100644
index 0000000..5a040ea
--- /dev/null
+++ b/doc-src/verbatim/sample/dsv-sample.sql
@@ -0,0 +1,37 @@
+/*
+ * $Id: dsv-sample.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * Imports delimiter-separated-values, and generates an output 
+ * reject .dsv file, and a reject report.
+ *
+ * To execute, set up a SqlTool database urlid (see User Guide if you don't
+ * know how to do that); then (from this directory) execute this script like
+ *
+ *    java ../lib/hsqldb.jar mem dsv-sample.sql
+ *
+ * (replace "mem" with your urlid).
+ */
+
+CREATE TABLE sampletable(i INT, d DATE NOT NULL, b BOOLEAN);
+
+/* If you dont' set *DSV_TARGET_TABLE, it defaults to the base name of the
+   .dsv file. */
+* *DSV_TARGET_TABLE = sampletable
+
+\p WARNING:  Some records will be skipped, and some others will be rejected.
+\p This is on purpose, so you can work with a reject report.
+\p
+
+/* By default, no reject files are written, and the import will abort upon
+ * the first error encountered.  If you set either of these settings, the
+ * import will continue to completion if at all possible. */
+* *DSV_REJECT_FILE = ${java.io.tmpdir}/sample-reject.dsv
+* *DSV_REJECT_REPORT = ${java.io.tmpdir}/sample-reject.html
+\m sample.dsv
+
+/* Enable this line if you want to display all successfully imported data:
+SELECT * FROM sampletable;
+*/
+
+\p
+\p See import reject report at '*{*DSV_REJECT_REPORT}'.
diff --git a/doc-src/verbatim/sample/hsqldb.cfg b/doc-src/verbatim/sample/hsqldb.cfg
new file mode 100644
index 0000000..37889e8
--- /dev/null
+++ b/doc-src/verbatim/sample/hsqldb.cfg
@@ -0,0 +1,173 @@
+# $Id: hsqldb.cfg 3583 2010-05-16 01:49:52Z unsaved $
+
+# Sample configuration file for HyperSQL Server Listener.
+# See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide.
+
+# N.b.!!!!  You must place this in the right location for your type of UNIX.
+# See the init script "hsqldb" to see where this must be placed and
+# what it should be renamed to.
+
+# This file is "sourced" by a Bourne shell, so use Bourne shell syntax.
+
+# This file WILL NOT WORK until you set (at least) the non-commented
+# variables to the appropriate values for your system.
+# Life will be easier if you avoid all filepaths with spaces or any other
+# funny characters.  Don't ask for support if you ignore this advice.
+
+# The URLIDS setting below is new and REQUIRED.  This setting replaces the
+# server.urlid.X settings which used to be needed in your Server's
+# properties file.
+
+# -- Blaine (blaine dot simpson at admc dot com)
+
+JAVA_EXECUTABLE=/usr/bin/java
+
+# Unless you copied the jar files from another system, this typically
+# resides at $HSQLDB_HOME/lib/sqltool.jar, where $HSQLDB_HOME is your HSQLDB
+# software base directory.
+# The file name may actually have a version label in it, like
+# sqltool-1.2.3.jar (in which case, you must specify the full name here).
+# A 'hsqldb.jar' file (with or without version label) must reside in the same
+# directory as the specified sqltool.jar file.
+SQLTOOL_JAR_PATH=/opt/hsqldb-2.0.0/hsqldb/lib/sqltool.jar
+# For the sample value above, there must also exist a file
+# /opt/hsqldb-2.0.0/hsqldb/lib/hsqldb*.jar.
+
+# Where the file "server.properties" or "webserver.properties" resides.
+SERVER_HOME=/opt/hsqldb-2.0.0/hsqldb/data
+
+# What UNIX user the server will run as.
+# (The shutdown client is always run as root or the invoker of the init script).
+# Runs as root by default, but you should take the time to set database file
+# ownerships to another user and set that user name here.
+HSQLDB_OWNER=hsqldb
+
+# The HSQLDB jar file specified in HSQLDB_JAR_PATH above will automatically
+# be in the class path.  This arg specifies additional classpath elements.
+# To embed your own application, add your jar file(s) or class base
+# directories here, and add your main class to the INVOC_ADDL_ARGS setting
+# below.  Another common use-case for adding to your class path is to make
+# classes available to the DB engines for SQL/JRT functions and procedures.
+#SERVER_ADDL_CLASSPATH=/usr/local/dist/currencybank.jar
+
+# For startup or shutdown failures, you can save a lot of debugging time by
+# temporarily adjusting down MAX_START_SECS and MAX_TERMINATE_SECS to a
+# little over what it should take for successful startup and shutdown on
+# your system.
+
+# We require all Server/WebServer instances to be accessible within 
+# $MAX_START_SECS from when the Server/WebServer is started.
+# Defaults to 60.
+# Raise this is you are running lots of DB instances or have a slow server.
+#MAX_START_SECS=200
+
+# Max time to allow for JVM to die after all HSQLDB instances stopped.
+# Defaults to 60.  Set high because the script will always continue as soon as
+# the process has stopped.  The importance of this setting is, how long until
+# a non-stopping-JVM-problem will be detected.
+#MAX_TERMINATE_SECS=0
+
+# NEW AND IMPORTANT!!!
+# As noted at the top of this file, this setting replaces the old property
+# settings server.urlid.X.
+# Simply list the URLIDs for all DB instances which your *Server starts.
+# Usually, these will exactly mirror the server.database.X settings in your
+# server.properties or webserver.properties file.
+# Each urlid listed here must be defined to a NETWORK url with Admin privileges
+# in the AUTH_FILE specified below.  (Network type because we use this for
+# inter-process communication)
+# Separate multiple values with white space.  NO OTHER SPECIAL CHARACTERS!
+# Make sure to quote the entire value if it contains white space separator(s).
+URLIDS='localhostdb1'
+
+# These are urlids # ** IN ADDITION TO URLIDS **, for instances which the init
+# script should stop but not start.
+# Most users will not need this setting.  If you need it, you'll know it.
+# Defaults to none (i.e., only URLIDS will be stopped).
+#SHUTDOWN_URLIDS='ondemand'
+
+# SqlTool authentication file used only for shutdown.
+# The default value will be sqltool.rc in root's home directory, since it is 
+# root who runs the init script.
+# (See the SqlTool chapter of the HyperSQL Utilities Guide if you don't
+# understand this).
+#AUTH_FILE=/home/blaine/sqltool.rc
+
+# Typical users will leave this unset and it will default to
+# org.hsqldb.server.Server.  If you need to run the HSQLDB WebServer class
+# instead, due to a firewall or routing impediment, set this to
+# org.hsqldb.server.WebServer, see the docs about running WebServr, and
+# set up a "webserver.properties" file instead of a "server.properties".
+# The JVM that is started can invoke many classes (see the following item
+# about that), but this is the server that is used (1) to check status,
+# (2) to shut down the JVM.
+#TARGET_CLASS=org.hsqldb.server.WebServer
+
+# This is where you may specify both command-line parameters to TARGET_CLASS,
+# plus any number of additional progams to run (along with their command-line
+# parameters).  The MainInvoker program is used to embed these multiple
+# static main invocations into a single JVM, so see the API spec for
+# org.hsqldb.util.MainInvoker if you want to learn more.
+# N.b. You should only use this setting to set HSQLDB Server or WebServer
+# parameters if you run multiple instances of this class, since you can use the
+# server/webserver.properties file for a single instance.
+# Every additional class (in addition to the TARGET_CLASS)
+# must be preceded with an empty string, so that MainInvoker will know
+# you are giving a class name.  MainInvoker will invoke the normal 
+# static main(String[]) method of each such class.  
+# By default, MainInvoker will just run TARGET_CLASS with no args.
+# Example that runs just the TARGET_CLASS with the specified arguments:
+#INVOC_ADDL_ARGS='-silent false'   #but use server.properties property instead!
+# Example that runs the TARGET_CLASS plus a WebServer:
+#INVOC_ADDL_ARGS='"" org.hsqldb.server.WebServer'
+# Note the empty string preceding the class name.
+# Example that starts TARGET_CLASS with an argument + a WebServer +
+# your own application with its args (i.e., the HSQLDB Servers are
+# "embedded" in your application).  (Set SERVER_ADDL_CLASSPATH too).:
+#INVOC_ADDL_ARGS='-silent false "" org.hsqldb.server.WebServer "" com.acme.Stone --env prod localhost'
+#   but use server.properties for -silent option instead!
+# Example to run a non-TLS server in same JVM with a TLS server.  In this
+# case, TARGET_CLASS is Server which will run both in TLS mode by virtue of 
+# setting the tls, keyStore, and keyStorePassword settings in
+# server*.properties, as described below; plus an "additional" Server with
+# overridden 'tls' and 'port' settings:
+#INVOC_ADDL_ARGS="'' org.hsqldb.server.Server --port 9002 --tls false"
+# This is an important use case.  If you run more than one Server instance,
+# you can specify different parameters for each here, even though only one
+# server.properties file is supported.
+# Note that you use nested quotes to group arguments and to specify the
+# empty-string delimiter.
+
+# The TLS_* settings have been obsoleted.
+# To get your server running with TLS, set
+# system.javax.net.ssl.keyStore=/path/to/your/private.keystore
+# system.javax.net.ssl.keyStorePassword=secretPassword
+# server.ssl=true
+# IN server.properties or webserver.properties, and
+# MAKE THE FILE OWNER-READ-ONLY!
+# See the TLS Encryption section of the HyperSQL User Guide, paying attention
+# to the security warning(s).
+# If you are running with a private server cert, then you will also need to 
+# set "truststore" in the your SqlTool config file (location is set by the
+# AUTH_FILE variable in this file, or it must be at the default location for 
+# HSQLDB_OWNER).
+
+# Any JVM args for the invocation of the JDBC client used to verify DB
+# instances and to shut them down (SqlToolSprayer).
+# Server-side System Properties should normally be set with system.*
+# settings in the server/webserver.properties file.
+# This example specifies the location of a private trust store for TLS 
+# encryption.
+# For multiple args, put quotes around entire value.
+# If you are starting just a TLS_encrypted Listener, you need to uncomment
+# this so the init scripts uses TLS to connect.
+# If using a private keystore, you also need to set "truststore" settings in
+# the sqltool.rc file.
+#CLIENT_JVMARGS=-Djavax.net.debug=ssl
+# This sample value displays useful debugging information about TLS/SSL.
+
+# Any JVM args for the server.
+# For multiple args, put quotes around entire value.
+#SERVER_JVMARGS=-Xmx512m
+# You can set the "javax.net.debug" property on the server side here, in the
+# same exact way as shown for the client side above.
diff --git a/doc-src/verbatim/sample/pl.sql b/doc-src/verbatim/sample/pl.sql
new file mode 100644
index 0000000..e616108
--- /dev/null
+++ b/doc-src/verbatim/sample/pl.sql
@@ -0,0 +1,87 @@
+/*
+    $Id: pl.sql 3353 2009-12-15 19:52:13Z unsaved $
+    SQL File to illustrate the use of SqlTool PL features.
+    Invoke like
+        java -jar .../hsqldb.jar .../pl.sql mem
+                                                         -- blaine
+*/
+
+* if (! *MYTABLE)
+    \p MYTABLE variable not set!
+    /* You could use \q to Quit SqlTool, but it's often better to just
+       break out of the current SQL file.
+       If people invoke your script from SqlTool interactively (with
+       \i yourscriptname.sql) any \q will kill their SqlTool session. */
+    \p Use arguments "--setvar=MYTABLE=mytablename" for SqlTool
+    * break
+* end if
+
+/* Turning on Continue-upon-errors so that we can check for errors ourselves.*/
+\c true
+
+\p
+\p Loading up a table named '*{MYTABLE}'...
+
+/* This sets the PL variable 'retval' to the return status of the following
+   SQL command */
+* retval ~
+CREATE TABLE *{MYTABLE} (
+    i int,
+    s varchar(20);
+);
+\p CREATE status is *{retval}
+\p
+
+/* Validate our return status.  In logical expressions, unset variables like
+   *unsetvar are equivalent to empty string, which is not equal to 0
+   (though both do evaluate to false on their own, i.e. (*retval) is false
+   and (0) is false */
+* if (*retval != 0)
+    \p Our CREATE TABLE command failed.
+    * break
+* end if
+
+/* Default Continue-on-error behavior is what you usually want */
+\c false
+\p
+
+/* Insert data with a foreach loop.
+   These values could be from a read of another table or from variables
+   set on the command line like
+*/
+\p Inserting some data int our new table (you should see 3 row update messages)
+* foreach VALUE (12 22 24 15)
+    * if (*VALUE > 23)
+        \p Skipping *{VALUE} because it is greater than 23
+        * continue
+        \p YOU WILL NEVER SEE THIS LINE, because we just 'continued'.
+    * end if
+    INSERT INTO *{MYTABLE} VALUES (*{VALUE}, 'String of *{VALUE}');
+* end foreach
+\p
+
+* themax ~
+/* Can put Special Commands and comments between "* VARNAME ~" and the target 
+   SQL statement. */
+\p We're saving the max value for later.  You'll still see query output here:
+SELECT MAX(i) FROM *{MYTABLE};
+
+/* This is usually unnecessary because if the SELECT failed, retval would
+   be undefined and the following print statement would make SqlTool exit with
+   a failure status */
+* if (! *themax)
+    \p Failed to get the max value.
+    /* It's possible that the query succeeded but themax is "0".
+       You can check for that if you need to. */
+    * break
+    \p YOU WILL NEVER SEE THIS LINE, because we just 'broke'.
+* end if
+
+\p
+\p ##############################################################
+\p The results of our work:
+SELECT * FROM *{MYTABLE};
+\p MAX value is *{themax}
+
+\p
+\p Everything worked.
diff --git a/doc-src/verbatim/sample/plsql.sql b/doc-src/verbatim/sample/plsql.sql
new file mode 100644
index 0000000..af08686
--- /dev/null
+++ b/doc-src/verbatim/sample/plsql.sql
@@ -0,0 +1,51 @@
+/*
+ * $Id: plsql.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * This example is copied from the "Simple Programs in PL/SQL"
+ * example by Yu-May Chang, Jeff Ullman, Prof. Jennifer Widom at
+ * the Standord University Database Group's page
+ * http://www-db.stanford.edu/~ullman/fcdb/oracle/or-plsql.html .
+ * I have only removed some blank lines (in case somebody wants to
+ * copy this code interactively-- because you can't use blank
+ * lines inside of SQL commands in non-raw mode SqlTool when running
+ * it interactively); and, at the bottom I have  replaced the
+ * client-specific, non-standard command "run;" with SqlTool's
+ * corresponding command ".;" and added a plain SQL SELECT command
+ * to show whether the PL/SQL code worked.  - Blaine
+ */
+
+CREATE TABLE T1(
+    e INTEGER,
+    f INTEGER
+);
+
+DELETE FROM T1;
+
+INSERT INTO T1 VALUES(1, 3);
+
+INSERT INTO T1 VALUES(2, 4);
+
+/* Above is plain SQL; below is the PL/SQL program. */
+DECLARE
+
+    a NUMBER;
+
+    b NUMBER;
+
+BEGIN
+
+    SELECT e,f INTO a,b FROM T1 WHERE e>1;
+
+    INSERT INTO T1 VALUES(b,a);
+
+END;
+
+.;
+/** The statement on the previous line, ".;" is SqlTool specific.
+ *  This command says to save the input up to this point to the
+ *  edit buffer and send it to the database server for execution.
+ *  I added the SELECT statement below to give imm
+ */
+
+/* This should show 3 rows, one containing values 4 and 2 (in this order)...*/
+SELECT * FROM t1;
diff --git a/doc-src/verbatim/sample/sample.sql b/doc-src/verbatim/sample/sample.sql
new file mode 100644
index 0000000..a6de8a5
--- /dev/null
+++ b/doc-src/verbatim/sample/sample.sql
@@ -0,0 +1,47 @@
+/*
+    $Id: sample.sql 3637 2010-06-07 00:59:13Z unsaved $
+    Exemplifies use of SqlTool.
+    PCTASK Table creation
+*/
+
+/* Ignore error for these two statements */
+\c true
+DROP TABLE pctasklist;
+DROP TABLE pctask;
+\c false
+
+\p Creating table pctask
+CREATE TABLE pctask (
+    id integer identity,
+    name varchar(40),
+    description varchar(256),
+    url varchar(80),
+    UNIQUE (name)
+);
+
+\p Creating table pctasklist
+CREATE TABLE pctasklist (
+    id integer identity,
+    host varchar(20) not null,
+    tasksequence int not null,
+    pctask integer,
+    assigndate timestamp default current_timestamp,
+    completedate timestamp,
+    show boolean default true,
+    FOREIGN KEY (pctask) REFERENCES pctask,
+    UNIQUE (host, tasksequence)
+);
+
+\p Granting privileges
+GRANT select ON pctask TO public;
+GRANT all ON pctask TO tomcat;
+GRANT select ON pctasklist TO public;
+GRANT all ON pctasklist TO tomcat;
+
+\p Inserting test records
+INSERT INTO pctask (name, description, url) VALUES (
+    'task one', 'Description for task 1', 'http://cnn.com');
+INSERT INTO pctasklist (host, tasksequence, pctask) VALUES (
+    'admc-masq', 101, (SELECT id FROM pctask WHERE name = 'task one'));
+
+commit;
diff --git a/doc-src/verbatim/sample/sampledata.sql b/doc-src/verbatim/sample/sampledata.sql
new file mode 100644
index 0000000..1c59ea8
--- /dev/null
+++ b/doc-src/verbatim/sample/sampledata.sql
@@ -0,0 +1,822 @@
+/*
+ *  $Id: sampledata.sql 3353 2009-12-15 19:52:13Z unsaved $
+ *
+ *  Creates and populates database objects with sample data.
+ *  This file was created by grabbing the commands made by creating
+ *  sample data with the DatabaseManager utility.
+ */
+
+
+DROP TABLE Item IF EXISTS;
+DROP TABLE Invoice IF EXISTS;
+DROP TABLE Product IF EXISTS;
+DROP TABLE Customer IF EXISTS;
+CREATE TABLE Customer(ID INTEGER PRIMARY KEY,FirstName VARCHAR(20),LastName VARCHAR(30),Street VARCHAR(50),City VARCHAR(25));
+CREATE TABLE Product(ID INTEGER PRIMARY KEY,Name VARCHAR(30),Price DECIMAL);
+CREATE TABLE Invoice(ID INTEGER PRIMARY KEY,CustomerID INTEGER,Total DECIMAL, FOREIGN KEY (CustomerId) REFERENCES Customer(ID) ON DELETE CASCADE);
+CREATE TABLE Item(InvoiceID INTEGER,Item INTEGER,ProductID INTEGER,Quantity INTEGER,Cost DECIMAL,PRIMARY KEY(InvoiceID,Item), FOREIGN KEY (InvoiceId) REFERENCES Invoice (ID) ON DELETE CASCADE, FOREIGN KEY (ProductId) REFERENCES Product(ID) ON DELETE CASCADE);
+INSERT INTO Customer VALUES(0,'Laura','Steel','429 Seventh Av.','Dallas');
+INSERT INTO Product VALUES(0,'Iron Iron',54);
+INSERT INTO Customer VALUES(1,'Susanne','King','366 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(1,'Chair Shoe',248);
+INSERT INTO Customer VALUES(2,'Anne','Miller','20 Upland Pl.','Lyon');
+INSERT INTO Product VALUES(2,'Telephone Clock',248);
+INSERT INTO Customer VALUES(3,'Michael','Clancy','542 Upland Pl.','San Francisco');
+INSERT INTO Product VALUES(3,'Chair Chair',254);
+INSERT INTO Customer VALUES(4,'Sylvia','Ringer','365 College Av.','Dallas');
+INSERT INTO Product VALUES(4,'Ice Tea Shoe',128);
+INSERT INTO Customer VALUES(5,'Laura','Miller','294 Seventh Av.','Paris');
+INSERT INTO Product VALUES(5,'Clock Clock',236);
+INSERT INTO Customer VALUES(6,'Laura','White','506 Upland Pl.','Palo Alto');
+INSERT INTO Product VALUES(6,'Ice Tea Chair',98);
+INSERT INTO Customer VALUES(7,'James','Peterson','231 Upland Pl.','San Francisco');
+INSERT INTO Product VALUES(7,'Telephone Shoe',84);
+INSERT INTO Customer VALUES(8,'Andrew','Miller','288 - 20th Ave.','Seattle');
+INSERT INTO Product VALUES(8,'Ice Tea Clock',226);
+INSERT INTO Customer VALUES(9,'James','Schneider','277 Seventh Av.','Berne');
+INSERT INTO Product VALUES(9,'Clock Telephone',172);
+INSERT INTO Customer VALUES(10,'Anne','Fuller','135 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(10,'Telephone Ice Tea',204);
+INSERT INTO Customer VALUES(11,'Julia','White','412 Upland Pl.','Chicago');
+INSERT INTO Product VALUES(11,'Telephone Iron',88);
+INSERT INTO Customer VALUES(12,'George','Ott','381 Upland Pl.','Palo Alto');
+INSERT INTO Product VALUES(12,'Clock Ice Tea',168);
+INSERT INTO Customer VALUES(13,'Laura','Ringer','38 College Av.','New York');
+INSERT INTO Product VALUES(13,'Telephone Clock',180);
+INSERT INTO Customer VALUES(14,'Bill','Karsen','53 College Av.','Oslo');
+INSERT INTO Product VALUES(14,'Telephone Iron',124);
+INSERT INTO Customer VALUES(15,'Bill','Clancy','319 Upland Pl.','Seattle');
+INSERT INTO Product VALUES(15,'Ice Tea Chair',94);
+INSERT INTO Customer VALUES(16,'John','Fuller','195 Seventh Av.','New York');
+INSERT INTO Product VALUES(16,'Ice Tea Shoe',194);
+INSERT INTO Customer VALUES(17,'Laura','Ott','443 Seventh Av.','Lyon');
+INSERT INTO Product VALUES(17,'Clock Ice Tea',220);
+INSERT INTO Customer VALUES(18,'Sylvia','Fuller','158 - 20th Ave.','Paris');
+INSERT INTO Product VALUES(18,'Chair Clock',172);
+INSERT INTO Customer VALUES(19,'Susanne','Heiniger','86 - 20th Ave.','Dallas');
+INSERT INTO Product VALUES(19,'Ice Tea Ice Tea',110);
+INSERT INTO Customer VALUES(20,'Janet','Schneider','309 - 20th Ave.','Oslo');
+INSERT INTO Product VALUES(20,'Ice Tea Telephone',200);
+INSERT INTO Customer VALUES(21,'Julia','Clancy','18 Seventh Av.','Seattle');
+INSERT INTO Product VALUES(21,'Chair Chair',114);
+INSERT INTO Customer VALUES(22,'Bill','Ott','250 - 20th Ave.','Berne');
+INSERT INTO Product VALUES(22,'Iron Iron',66);
+INSERT INTO Customer VALUES(23,'Julia','Heiniger','358 College Av.','Boston');
+INSERT INTO Product VALUES(23,'Shoe Chair',76);
+INSERT INTO Customer VALUES(24,'James','Sommer','333 Upland Pl.','Olten');
+INSERT INTO Product VALUES(24,'Chair Shoe',72);
+INSERT INTO Customer VALUES(25,'Sylvia','Steel','269 College Av.','Paris');
+INSERT INTO Product VALUES(25,'Shoe Shoe',162);
+INSERT INTO Customer VALUES(26,'James','Clancy','195 Upland Pl.','Oslo');
+INSERT INTO Product VALUES(26,'Shoe Shoe',252);
+INSERT INTO Customer VALUES(27,'Bob','Sommer','509 College Av.','Seattle');
+INSERT INTO Product VALUES(27,'Telephone Iron',230);
+INSERT INTO Customer VALUES(28,'Susanne','White','74 - 20th Ave.','Lyon');
+INSERT INTO Product VALUES(28,'Clock Iron',30);
+INSERT INTO Customer VALUES(29,'Andrew','Smith','254 College Av.','New York');
+INSERT INTO Product VALUES(29,'Chair Telephone',112);
+INSERT INTO Customer VALUES(30,'Bill','Sommer','362 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(30,'Shoe Iron',232);
+INSERT INTO Customer VALUES(31,'Bob','Ringer','371 College Av.','Olten');
+INSERT INTO Product VALUES(31,'Ice Tea Telephone',48);
+INSERT INTO Customer VALUES(32,'Michael','Ott','339 College Av.','Boston');
+INSERT INTO Product VALUES(32,'Clock Iron',190);
+INSERT INTO Customer VALUES(33,'Mary','King','491 College Av.','Oslo');
+INSERT INTO Product VALUES(33,'Iron Chair',182);
+INSERT INTO Customer VALUES(34,'Julia','May','33 Upland Pl.','Seattle');
+INSERT INTO Product VALUES(34,'Chair Iron',256);
+INSERT INTO Customer VALUES(35,'George','Karsen','412 College Av.','Chicago');
+INSERT INTO Product VALUES(35,'Telephone Shoe',76);
+INSERT INTO Customer VALUES(36,'John','Steel','276 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(36,'Ice Tea Iron',32);
+INSERT INTO Customer VALUES(37,'Michael','Clancy','19 Seventh Av.','Dallas');
+INSERT INTO Product VALUES(37,'Clock Shoe',94);
+INSERT INTO Customer VALUES(38,'Andrew','Heiniger','347 College Av.','Lyon');
+INSERT INTO Product VALUES(38,'Clock Ice Tea',216);
+INSERT INTO Customer VALUES(39,'Mary','Karsen','202 College Av.','Chicago');
+INSERT INTO Product VALUES(39,'Ice Tea Shoe',154);
+INSERT INTO Customer VALUES(40,'Susanne','Miller','440 - 20th Ave.','Dallas');
+INSERT INTO Product VALUES(40,'Shoe Clock',28);
+INSERT INTO Customer VALUES(41,'Bill','King','546 College Av.','New York');
+INSERT INTO Product VALUES(41,'Clock Ice Tea',206);
+INSERT INTO Customer VALUES(42,'Robert','Ott','503 Seventh Av.','Oslo');
+INSERT INTO Product VALUES(42,'Iron Chair',198);
+INSERT INTO Customer VALUES(43,'Susanne','Smith','2 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(43,'Telephone Clock',94);
+INSERT INTO Customer VALUES(44,'Sylvia','Ott','361 College Av.','New York');
+INSERT INTO Product VALUES(44,'Ice Tea Ice Tea',96);
+INSERT INTO Customer VALUES(45,'Janet','May','396 Seventh Av.','Oslo');
+INSERT INTO Product VALUES(45,'Iron Ice Tea',180);
+INSERT INTO Customer VALUES(46,'Andrew','May','172 Seventh Av.','New York');
+INSERT INTO Product VALUES(46,'Ice Tea Clock',62);
+INSERT INTO Customer VALUES(47,'Janet','Fuller','445 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(47,'Ice Tea Iron',178);
+INSERT INTO Customer VALUES(48,'Robert','White','549 Seventh Av.','San Francisco');
+INSERT INTO Product VALUES(48,'Clock Clock',210);
+INSERT INTO Customer VALUES(49,'George','Fuller','534 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(49,'Iron Iron',22);
+INSERT INTO Invoice VALUES(0,0,0.0);
+INSERT INTO Invoice VALUES(1,33,0.0);
+INSERT INTO Invoice VALUES(2,23,0.0);
+INSERT INTO Invoice VALUES(3,21,0.0);
+INSERT INTO Invoice VALUES(4,30,0.0);
+INSERT INTO Invoice VALUES(5,34,0.0);
+INSERT INTO Invoice VALUES(6,19,0.0);
+INSERT INTO Invoice VALUES(7,26,0.0);
+INSERT INTO Invoice VALUES(8,29,0.0);
+INSERT INTO Invoice VALUES(9,38,0.0);
+INSERT INTO Invoice VALUES(10,24,0.0);
+INSERT INTO Invoice VALUES(11,24,0.0);
+INSERT INTO Invoice VALUES(12,23,0.0);
+INSERT INTO Invoice VALUES(13,39,0.0);
+INSERT INTO Invoice VALUES(14,35,0.0);
+INSERT INTO Invoice VALUES(15,39,0.0);
+INSERT INTO Invoice VALUES(16,45,0.0);
+INSERT INTO Invoice VALUES(17,46,0.0);
+INSERT INTO Invoice VALUES(18,4,0.0);
+INSERT INTO Invoice VALUES(19,9,0.0);
+INSERT INTO Invoice VALUES(20,19,0.0);
+INSERT INTO Invoice VALUES(21,8,0.0);
+INSERT INTO Invoice VALUES(22,40,0.0);
+INSERT INTO Invoice VALUES(23,36,0.0);
+INSERT INTO Invoice VALUES(24,15,0.0);
+INSERT INTO Invoice VALUES(25,31,0.0);
+INSERT INTO Invoice VALUES(26,27,0.0);
+INSERT INTO Invoice VALUES(27,24,0.0);
+INSERT INTO Invoice VALUES(28,35,0.0);
+INSERT INTO Invoice VALUES(29,46,0.0);
+INSERT INTO Invoice VALUES(30,13,0.0);
+INSERT INTO Invoice VALUES(31,22,0.0);
+INSERT INTO Invoice VALUES(32,20,0.0);
+INSERT INTO Invoice VALUES(33,40,0.0);
+INSERT INTO Invoice VALUES(34,33,0.0);
+INSERT INTO Invoice VALUES(35,4,0.0);
+INSERT INTO Invoice VALUES(36,42,0.0);
+INSERT INTO Invoice VALUES(37,39,0.0);
+INSERT INTO Invoice VALUES(38,46,0.0);
+INSERT INTO Invoice VALUES(39,5,0.0);
+INSERT INTO Invoice VALUES(40,4,0.0);
+INSERT INTO Invoice VALUES(41,19,0.0);
+INSERT INTO Invoice VALUES(42,38,0.0);
+INSERT INTO Invoice VALUES(43,13,0.0);
+INSERT INTO Invoice VALUES(44,32,0.0);
+INSERT INTO Invoice VALUES(45,42,0.0);
+INSERT INTO Invoice VALUES(46,24,0.0);
+INSERT INTO Invoice VALUES(47,45,0.0);
+INSERT INTO Invoice VALUES(48,22,0.0);
+INSERT INTO Invoice VALUES(49,32,0.0);
+INSERT INTO Item VALUES(0,12,1,11,1.5);
+INSERT INTO Item VALUES(0,11,12,4,1.5);
+INSERT INTO Item VALUES(0,10,4,8,1.5);
+INSERT INTO Item VALUES(0,9,35,4,1.5);
+INSERT INTO Item VALUES(0,8,0,23,1.5);
+INSERT INTO Item VALUES(0,7,7,10,1.5);
+INSERT INTO Item VALUES(0,6,16,9,1.5);
+INSERT INTO Item VALUES(0,5,12,15,1.5);
+INSERT INTO Item VALUES(0,4,47,1,1.5);
+INSERT INTO Item VALUES(0,3,1,9,1.5);
+INSERT INTO Item VALUES(0,2,47,3,1.5);
+INSERT INTO Item VALUES(0,1,14,19,1.5);
+INSERT INTO Item VALUES(0,0,7,12,1.5);
+INSERT INTO Item VALUES(1,6,25,19,1.5);
+INSERT INTO Item VALUES(1,5,25,9,1.5);
+INSERT INTO Item VALUES(1,4,16,16,1.5);
+INSERT INTO Item VALUES(1,3,38,8,1.5);
+INSERT INTO Item VALUES(1,2,19,6,1.5);
+INSERT INTO Item VALUES(1,1,0,9,1.5);
+INSERT INTO Item VALUES(1,0,40,8,1.5);
+INSERT INTO Item VALUES(2,16,36,24,1.5);
+INSERT INTO Item VALUES(2,15,0,18,1.5);
+INSERT INTO Item VALUES(2,14,48,19,1.5);
+INSERT INTO Item VALUES(2,13,12,1,1.5);
+INSERT INTO Item VALUES(2,12,21,15,1.5);
+INSERT INTO Item VALUES(2,11,42,21,1.5);
+INSERT INTO Item VALUES(2,10,49,11,1.5);
+INSERT INTO Item VALUES(2,9,18,7,1.5);
+INSERT INTO Item VALUES(2,8,39,2,1.5);
+INSERT INTO Item VALUES(2,7,30,5,1.5);
+INSERT INTO Item VALUES(2,6,43,8,1.5);
+INSERT INTO Item VALUES(2,5,30,4,1.5);
+INSERT INTO Item VALUES(2,4,38,18,1.5);
+INSERT INTO Item VALUES(2,3,19,13,1.5);
+INSERT INTO Item VALUES(2,2,11,9,1.5);
+INSERT INTO Item VALUES(2,1,25,3,1.5);
+INSERT INTO Item VALUES(2,0,4,18,1.5);
+INSERT INTO Item VALUES(3,17,30,17,1.5);
+INSERT INTO Item VALUES(3,16,19,11,1.5);
+INSERT INTO Item VALUES(3,15,23,18,1.5);
+INSERT INTO Item VALUES(3,14,17,22,1.5);
+INSERT INTO Item VALUES(3,13,41,2,1.5);
+INSERT INTO Item VALUES(3,12,41,22,1.5);
+INSERT INTO Item VALUES(3,11,7,11,1.5);
+INSERT INTO Item VALUES(3,10,10,17,1.5);
+INSERT INTO Item VALUES(3,9,29,17,1.5);
+INSERT INTO Item VALUES(3,8,49,9,1.5);
+INSERT INTO Item VALUES(3,7,26,4,1.5);
+INSERT INTO Item VALUES(3,6,13,18,1.5);
+INSERT INTO Item VALUES(3,5,30,10,1.5);
+INSERT INTO Item VALUES(3,4,20,12,1.5);
+INSERT INTO Item VALUES(3,3,0,22,1.5);
+INSERT INTO Item VALUES(3,2,49,3,1.5);
+INSERT INTO Item VALUES(3,1,1,20,1.5);
+INSERT INTO Item VALUES(3,0,11,21,1.5);
+INSERT INTO Item VALUES(4,5,37,24,1.5);
+INSERT INTO Item VALUES(4,4,9,18,1.5);
+INSERT INTO Item VALUES(4,3,23,20,1.5);
+INSERT INTO Item VALUES(4,2,41,23,1.5);
+INSERT INTO Item VALUES(4,1,35,15,1.5);
+INSERT INTO Item VALUES(4,0,28,9,1.5);
+INSERT INTO Item VALUES(5,13,18,17,1.5);
+INSERT INTO Item VALUES(5,12,8,15,1.5);
+INSERT INTO Item VALUES(5,11,38,23,1.5);
+INSERT INTO Item VALUES(5,10,28,18,1.5);
+INSERT INTO Item VALUES(5,9,37,9,1.5);
+INSERT INTO Item VALUES(5,8,20,3,1.5);
+INSERT INTO Item VALUES(5,7,2,4,1.5);
+INSERT INTO Item VALUES(5,6,7,9,1.5);
+INSERT INTO Item VALUES(5,5,46,15,1.5);
+INSERT INTO Item VALUES(5,4,32,14,1.5);
+INSERT INTO Item VALUES(5,3,24,12,1.5);
+INSERT INTO Item VALUES(5,2,20,18,1.5);
+INSERT INTO Item VALUES(5,1,9,23,1.5);
+INSERT INTO Item VALUES(5,0,9,5,1.5);
+INSERT INTO Item VALUES(6,11,44,1,1.5);
+INSERT INTO Item VALUES(6,10,16,13,1.5);
+INSERT INTO Item VALUES(6,9,19,2,1.5);
+INSERT INTO Item VALUES(6,8,41,19,1.5);
+INSERT INTO Item VALUES(6,7,26,10,1.5);
+INSERT INTO Item VALUES(6,6,37,22,1.5);
+INSERT INTO Item VALUES(6,5,14,20,1.5);
+INSERT INTO Item VALUES(6,4,31,20,1.5);
+INSERT INTO Item VALUES(6,3,30,2,1.5);
+INSERT INTO Item VALUES(6,2,23,8,1.5);
+INSERT INTO Item VALUES(6,1,38,21,1.5);
+INSERT INTO Item VALUES(6,0,15,20,1.5);
+INSERT INTO Item VALUES(7,18,23,5,1.5);
+INSERT INTO Item VALUES(7,17,40,1,1.5);
+INSERT INTO Item VALUES(7,16,7,12,1.5);
+INSERT INTO Item VALUES(7,15,24,17,1.5);
+INSERT INTO Item VALUES(7,14,47,14,1.5);
+INSERT INTO Item VALUES(7,13,32,23,1.5);
+INSERT INTO Item VALUES(7,12,40,16,1.5);
+INSERT INTO Item VALUES(7,11,19,13,1.5);
+INSERT INTO Item VALUES(7,10,7,1,1.5);
+INSERT INTO Item VALUES(7,9,9,21,1.5);
+INSERT INTO Item VALUES(7,8,42,19,1.5);
+INSERT INTO Item VALUES(7,7,2,22,1.5);
+INSERT INTO Item VALUES(7,6,14,4,1.5);
+INSERT INTO Item VALUES(7,5,24,10,1.5);
+INSERT INTO Item VALUES(7,4,2,13,1.5);
+INSERT INTO Item VALUES(7,3,30,2,1.5);
+INSERT INTO Item VALUES(7,2,27,17,1.5);
+INSERT INTO Item VALUES(7,1,23,12,1.5);
+INSERT INTO Item VALUES(7,0,43,16,1.5);
+INSERT INTO Item VALUES(8,9,21,23,1.5);
+INSERT INTO Item VALUES(8,8,38,7,1.5);
+INSERT INTO Item VALUES(8,7,6,5,1.5);
+INSERT INTO Item VALUES(8,6,15,19,1.5);
+INSERT INTO Item VALUES(8,5,24,18,1.5);
+INSERT INTO Item VALUES(8,4,15,8,1.5);
+INSERT INTO Item VALUES(8,3,41,16,1.5);
+INSERT INTO Item VALUES(8,2,11,8,1.5);
+INSERT INTO Item VALUES(8,1,44,16,1.5);
+INSERT INTO Item VALUES(8,0,34,15,1.5);
+INSERT INTO Item VALUES(9,19,48,23,1.5);
+INSERT INTO Item VALUES(9,18,3,12,1.5);
+INSERT INTO Item VALUES(9,17,13,17,1.5);
+INSERT INTO Item VALUES(9,16,24,10,1.5);
+INSERT INTO Item VALUES(9,15,48,23,1.5);
+INSERT INTO Item VALUES(9,14,15,8,1.5);
+INSERT INTO Item VALUES(9,13,42,13,1.5);
+INSERT INTO Item VALUES(9,12,25,23,1.5);
+INSERT INTO Item VALUES(9,11,12,16,1.5);
+INSERT INTO Item VALUES(9,10,38,11,1.5);
+INSERT INTO Item VALUES(9,9,13,6,1.5);
+INSERT INTO Item VALUES(9,8,24,11,1.5);
+INSERT INTO Item VALUES(9,7,2,22,1.5);
+INSERT INTO Item VALUES(9,6,18,10,1.5);
+INSERT INTO Item VALUES(9,5,6,2,1.5);
+INSERT INTO Item VALUES(9,4,36,16,1.5);
+INSERT INTO Item VALUES(9,3,4,14,1.5);
+INSERT INTO Item VALUES(9,2,29,12,1.5);
+INSERT INTO Item VALUES(9,1,18,21,1.5);
+INSERT INTO Item VALUES(9,0,45,8,1.5);
+INSERT INTO Item VALUES(10,9,5,10,1.5);
+INSERT INTO Item VALUES(10,8,22,11,1.5);
+INSERT INTO Item VALUES(10,7,4,13,1.5);
+INSERT INTO Item VALUES(10,6,18,14,1.5);
+INSERT INTO Item VALUES(10,5,5,24,1.5);
+INSERT INTO Item VALUES(10,4,10,24,1.5);
+INSERT INTO Item VALUES(10,3,46,1,1.5);
+INSERT INTO Item VALUES(10,2,7,9,1.5);
+INSERT INTO Item VALUES(10,1,33,17,1.5);
+INSERT INTO Item VALUES(10,0,20,1,1.5);
+INSERT INTO Item VALUES(11,8,20,1,1.5);
+INSERT INTO Item VALUES(11,7,48,22,1.5);
+INSERT INTO Item VALUES(11,6,0,12,1.5);
+INSERT INTO Item VALUES(11,5,19,2,1.5);
+INSERT INTO Item VALUES(11,4,47,16,1.5);
+INSERT INTO Item VALUES(11,3,32,21,1.5);
+INSERT INTO Item VALUES(11,2,0,3,1.5);
+INSERT INTO Item VALUES(11,1,21,21,1.5);
+INSERT INTO Item VALUES(11,0,45,10,1.5);
+INSERT INTO Item VALUES(12,18,9,4,1.5);
+INSERT INTO Item VALUES(12,17,31,15,1.5);
+INSERT INTO Item VALUES(12,16,0,9,1.5);
+INSERT INTO Item VALUES(12,15,22,16,1.5);
+INSERT INTO Item VALUES(12,14,25,11,1.5);
+INSERT INTO Item VALUES(12,13,36,21,1.5);
+INSERT INTO Item VALUES(12,12,13,12,1.5);
+INSERT INTO Item VALUES(12,11,28,16,1.5);
+INSERT INTO Item VALUES(12,10,46,19,1.5);
+INSERT INTO Item VALUES(12,9,25,22,1.5);
+INSERT INTO Item VALUES(12,8,48,2,1.5);
+INSERT INTO Item VALUES(12,7,48,7,1.5);
+INSERT INTO Item VALUES(12,6,31,15,1.5);
+INSERT INTO Item VALUES(12,5,37,17,1.5);
+INSERT INTO Item VALUES(12,4,20,11,1.5);
+INSERT INTO Item VALUES(12,3,0,18,1.5);
+INSERT INTO Item VALUES(12,2,6,5,1.5);
+INSERT INTO Item VALUES(12,1,41,19,1.5);
+INSERT INTO Item VALUES(12,0,1,24,1.5);
+INSERT INTO Item VALUES(13,21,40,1,1.5);
+INSERT INTO Item VALUES(13,20,5,19,1.5);
+INSERT INTO Item VALUES(13,19,42,18,1.5);
+INSERT INTO Item VALUES(13,18,0,16,1.5);
+INSERT INTO Item VALUES(13,17,32,18,1.5);
+INSERT INTO Item VALUES(13,16,22,23,1.5);
+INSERT INTO Item VALUES(13,15,0,20,1.5);
+INSERT INTO Item VALUES(13,14,1,12,1.5);
+INSERT INTO Item VALUES(13,13,10,20,1.5);
+INSERT INTO Item VALUES(13,12,17,3,1.5);
+INSERT INTO Item VALUES(13,11,14,3,1.5);
+INSERT INTO Item VALUES(13,10,45,24,1.5);
+INSERT INTO Item VALUES(13,9,24,10,1.5);
+INSERT INTO Item VALUES(13,8,48,11,1.5);
+INSERT INTO Item VALUES(13,7,29,24,1.5);
+INSERT INTO Item VALUES(13,6,19,8,1.5);
+INSERT INTO Item VALUES(13,5,22,19,1.5);
+INSERT INTO Item VALUES(13,4,26,21,1.5);
+INSERT INTO Item VALUES(13,3,32,2,1.5);
+INSERT INTO Item VALUES(13,2,13,20,1.5);
+INSERT INTO Item VALUES(13,1,1,1,1.5);
+INSERT INTO Item VALUES(13,0,16,10,1.5);
+INSERT INTO Item VALUES(14,13,11,23,1.5);
+INSERT INTO Item VALUES(14,12,4,20,1.5);
+INSERT INTO Item VALUES(14,11,25,15,1.5);
+INSERT INTO Item VALUES(14,10,44,16,1.5);
+INSERT INTO Item VALUES(14,9,13,16,1.5);
+INSERT INTO Item VALUES(14,8,23,7,1.5);
+INSERT INTO Item VALUES(14,7,43,4,1.5);
+INSERT INTO Item VALUES(14,6,26,18,1.5);
+INSERT INTO Item VALUES(14,5,11,8,1.5);
+INSERT INTO Item VALUES(14,4,41,17,1.5);
+INSERT INTO Item VALUES(14,3,34,11,1.5);
+INSERT INTO Item VALUES(14,2,15,18,1.5);
+INSERT INTO Item VALUES(14,1,9,22,1.5);
+INSERT INTO Item VALUES(14,0,42,18,1.5);
+INSERT INTO Item VALUES(15,2,24,6,1.5);
+INSERT INTO Item VALUES(15,1,13,21,1.5);
+INSERT INTO Item VALUES(15,0,17,12,1.5);
+INSERT INTO Item VALUES(16,15,12,3,1.5);
+INSERT INTO Item VALUES(16,14,0,19,1.5);
+INSERT INTO Item VALUES(16,13,20,1,1.5);
+INSERT INTO Item VALUES(16,12,18,2,1.5);
+INSERT INTO Item VALUES(16,11,24,7,1.5);
+INSERT INTO Item VALUES(16,10,43,8,1.5);
+INSERT INTO Item VALUES(16,9,11,10,1.5);
+INSERT INTO Item VALUES(16,8,13,17,1.5);
+INSERT INTO Item VALUES(16,7,8,17,1.5);
+INSERT INTO Item VALUES(16,6,44,7,1.5);
+INSERT INTO Item VALUES(16,5,11,15,1.5);
+INSERT INTO Item VALUES(16,4,10,24,1.5);
+INSERT INTO Item VALUES(16,3,0,3,1.5);
+INSERT INTO Item VALUES(16,2,20,15,1.5);
+INSERT INTO Item VALUES(16,1,36,20,1.5);
+INSERT INTO Item VALUES(16,0,18,15,1.5);
+INSERT INTO Item VALUES(17,19,46,12,1.5);
+INSERT INTO Item VALUES(17,18,5,9,1.5);
+INSERT INTO Item VALUES(17,17,7,5,1.5);
+INSERT INTO Item VALUES(17,16,8,16,1.5);
+INSERT INTO Item VALUES(17,15,35,10,1.5);
+INSERT INTO Item VALUES(17,14,18,2,1.5);
+INSERT INTO Item VALUES(17,13,41,5,1.5);
+INSERT INTO Item VALUES(17,12,22,16,1.5);
+INSERT INTO Item VALUES(17,11,45,10,1.5);
+INSERT INTO Item VALUES(17,10,10,12,1.5);
+INSERT INTO Item VALUES(17,9,8,15,1.5);
+INSERT INTO Item VALUES(17,8,49,8,1.5);
+INSERT INTO Item VALUES(17,7,6,15,1.5);
+INSERT INTO Item VALUES(17,6,43,6,1.5);
+INSERT INTO Item VALUES(17,5,44,1,1.5);
+INSERT INTO Item VALUES(17,4,23,2,1.5);
+INSERT INTO Item VALUES(17,3,24,4,1.5);
+INSERT INTO Item VALUES(17,2,44,11,1.5);
+INSERT INTO Item VALUES(17,1,19,19,1.5);
+INSERT INTO Item VALUES(17,0,16,8,1.5);
+INSERT INTO Item VALUES(18,18,10,1,1.5);
+INSERT INTO Item VALUES(18,17,8,1,1.5);
+INSERT INTO Item VALUES(18,16,31,12,1.5);
+INSERT INTO Item VALUES(18,15,44,20,1.5);
+INSERT INTO Item VALUES(18,14,28,20,1.5);
+INSERT INTO Item VALUES(18,13,14,12,1.5);
+INSERT INTO Item VALUES(18,12,37,12,1.5);
+INSERT INTO Item VALUES(18,11,30,8,1.5);
+INSERT INTO Item VALUES(18,10,34,18,1.5);
+INSERT INTO Item VALUES(18,9,2,2,1.5);
+INSERT INTO Item VALUES(18,8,1,24,1.5);
+INSERT INTO Item VALUES(18,7,15,14,1.5);
+INSERT INTO Item VALUES(18,6,29,4,1.5);
+INSERT INTO Item VALUES(18,5,15,6,1.5);
+INSERT INTO Item VALUES(18,4,28,6,1.5);
+INSERT INTO Item VALUES(18,3,19,8,1.5);
+INSERT INTO Item VALUES(18,2,40,12,1.5);
+INSERT INTO Item VALUES(18,1,33,12,1.5);
+INSERT INTO Item VALUES(18,0,32,1,1.5);
+INSERT INTO Item VALUES(19,4,36,24,1.5);
+INSERT INTO Item VALUES(19,3,49,23,1.5);
+INSERT INTO Item VALUES(19,2,4,22,1.5);
+INSERT INTO Item VALUES(19,1,31,2,1.5);
+INSERT INTO Item VALUES(19,0,12,7,1.5);
+INSERT INTO Item VALUES(20,11,15,8,1.5);
+INSERT INTO Item VALUES(20,10,25,11,1.5);
+INSERT INTO Item VALUES(20,9,12,8,1.5);
+INSERT INTO Item VALUES(20,8,44,18,1.5);
+INSERT INTO Item VALUES(20,7,9,9,1.5);
+INSERT INTO Item VALUES(20,6,20,2,1.5);
+INSERT INTO Item VALUES(20,5,8,14,1.5);
+INSERT INTO Item VALUES(20,4,30,13,1.5);
+INSERT INTO Item VALUES(20,3,25,14,1.5);
+INSERT INTO Item VALUES(20,2,24,22,1.5);
+INSERT INTO Item VALUES(20,1,29,6,1.5);
+INSERT INTO Item VALUES(20,0,47,15,1.5);
+INSERT INTO Item VALUES(21,11,20,11,1.5);
+INSERT INTO Item VALUES(21,10,19,14,1.5);
+INSERT INTO Item VALUES(21,9,35,17,1.5);
+INSERT INTO Item VALUES(21,8,44,19,1.5);
+INSERT INTO Item VALUES(21,7,8,9,1.5);
+INSERT INTO Item VALUES(21,6,26,7,1.5);
+INSERT INTO Item VALUES(21,5,27,18,1.5);
+INSERT INTO Item VALUES(21,4,49,22,1.5);
+INSERT INTO Item VALUES(21,3,30,13,1.5);
+INSERT INTO Item VALUES(21,2,31,17,1.5);
+INSERT INTO Item VALUES(21,1,38,19,1.5);
+INSERT INTO Item VALUES(21,0,9,10,1.5);
+INSERT INTO Item VALUES(22,9,23,1,1.5);
+INSERT INTO Item VALUES(22,8,3,2,1.5);
+INSERT INTO Item VALUES(22,7,21,6,1.5);
+INSERT INTO Item VALUES(22,6,4,11,1.5);
+INSERT INTO Item VALUES(22,5,24,5,1.5);
+INSERT INTO Item VALUES(22,4,5,21,1.5);
+INSERT INTO Item VALUES(22,3,22,5,1.5);
+INSERT INTO Item VALUES(22,2,12,20,1.5);
+INSERT INTO Item VALUES(22,1,30,11,1.5);
+INSERT INTO Item VALUES(22,0,9,6,1.5);
+INSERT INTO Item VALUES(23,16,8,11,1.5);
+INSERT INTO Item VALUES(23,15,13,17,1.5);
+INSERT INTO Item VALUES(23,14,44,2,1.5);
+INSERT INTO Item VALUES(23,13,14,17,1.5);
+INSERT INTO Item VALUES(23,12,4,17,1.5);
+INSERT INTO Item VALUES(23,11,41,8,1.5);
+INSERT INTO Item VALUES(23,10,4,18,1.5);
+INSERT INTO Item VALUES(23,9,20,18,1.5);
+INSERT INTO Item VALUES(23,8,6,17,1.5);
+INSERT INTO Item VALUES(23,7,39,3,1.5);
+INSERT INTO Item VALUES(23,6,16,1,1.5);
+INSERT INTO Item VALUES(23,5,32,14,1.5);
+INSERT INTO Item VALUES(23,4,23,19,1.5);
+INSERT INTO Item VALUES(23,3,40,19,1.5);
+INSERT INTO Item VALUES(23,2,33,18,1.5);
+INSERT INTO Item VALUES(23,1,26,8,1.5);
+INSERT INTO Item VALUES(23,0,48,22,1.5);
+INSERT INTO Item VALUES(24,15,39,17,1.5);
+INSERT INTO Item VALUES(24,14,1,13,1.5);
+INSERT INTO Item VALUES(24,13,15,21,1.5);
+INSERT INTO Item VALUES(24,12,0,8,1.5);
+INSERT INTO Item VALUES(24,11,1,4,1.5);
+INSERT INTO Item VALUES(24,10,27,4,1.5);
+INSERT INTO Item VALUES(24,9,21,8,1.5);
+INSERT INTO Item VALUES(24,8,5,18,1.5);
+INSERT INTO Item VALUES(24,7,7,13,1.5);
+INSERT INTO Item VALUES(24,6,40,3,1.5);
+INSERT INTO Item VALUES(24,5,35,16,1.5);
+INSERT INTO Item VALUES(24,4,15,17,1.5);
+INSERT INTO Item VALUES(24,3,17,23,1.5);
+INSERT INTO Item VALUES(24,2,38,10,1.5);
+INSERT INTO Item VALUES(24,1,46,18,1.5);
+INSERT INTO Item VALUES(24,0,43,14,1.5);
+INSERT INTO Item VALUES(25,8,38,3,1.5);
+INSERT INTO Item VALUES(25,7,16,8,1.5);
+INSERT INTO Item VALUES(25,6,21,18,1.5);
+INSERT INTO Item VALUES(25,5,10,5,1.5);
+INSERT INTO Item VALUES(25,4,47,10,1.5);
+INSERT INTO Item VALUES(25,3,19,4,1.5);
+INSERT INTO Item VALUES(25,2,13,8,1.5);
+INSERT INTO Item VALUES(25,1,43,13,1.5);
+INSERT INTO Item VALUES(25,0,5,15,1.5);
+INSERT INTO Item VALUES(26,16,30,4,1.5);
+INSERT INTO Item VALUES(26,15,8,6,1.5);
+INSERT INTO Item VALUES(26,14,26,6,1.5);
+INSERT INTO Item VALUES(26,13,13,10,1.5);
+INSERT INTO Item VALUES(26,12,27,20,1.5);
+INSERT INTO Item VALUES(26,11,18,3,1.5);
+INSERT INTO Item VALUES(26,10,34,16,1.5);
+INSERT INTO Item VALUES(26,9,1,23,1.5);
+INSERT INTO Item VALUES(26,8,40,13,1.5);
+INSERT INTO Item VALUES(26,7,4,16,1.5);
+INSERT INTO Item VALUES(26,6,7,23,1.5);
+INSERT INTO Item VALUES(26,5,38,4,1.5);
+INSERT INTO Item VALUES(26,4,46,7,1.5);
+INSERT INTO Item VALUES(26,3,16,3,1.5);
+INSERT INTO Item VALUES(26,2,33,7,1.5);
+INSERT INTO Item VALUES(26,1,43,21,1.5);
+INSERT INTO Item VALUES(26,0,42,16,1.5);
+INSERT INTO Item VALUES(27,2,19,1,1.5);
+INSERT INTO Item VALUES(27,1,45,15,1.5);
+INSERT INTO Item VALUES(27,0,24,15,1.5);
+INSERT INTO Item VALUES(28,8,28,6,1.5);
+INSERT INTO Item VALUES(28,7,28,8,1.5);
+INSERT INTO Item VALUES(28,6,33,16,1.5);
+INSERT INTO Item VALUES(28,5,49,4,1.5);
+INSERT INTO Item VALUES(28,4,45,17,1.5);
+INSERT INTO Item VALUES(28,3,6,3,1.5);
+INSERT INTO Item VALUES(28,2,44,22,1.5);
+INSERT INTO Item VALUES(28,1,15,13,1.5);
+INSERT INTO Item VALUES(28,0,35,13,1.5);
+INSERT INTO Item VALUES(29,8,35,6,1.5);
+INSERT INTO Item VALUES(29,7,5,1,1.5);
+INSERT INTO Item VALUES(29,6,4,16,1.5);
+INSERT INTO Item VALUES(29,5,31,13,1.5);
+INSERT INTO Item VALUES(29,4,4,7,1.5);
+INSERT INTO Item VALUES(29,3,7,21,1.5);
+INSERT INTO Item VALUES(29,2,17,23,1.5);
+INSERT INTO Item VALUES(29,1,38,12,1.5);
+INSERT INTO Item VALUES(29,0,33,17,1.5);
+INSERT INTO Item VALUES(30,6,14,23,1.5);
+INSERT INTO Item VALUES(30,5,43,23,1.5);
+INSERT INTO Item VALUES(30,4,34,2,1.5);
+INSERT INTO Item VALUES(30,3,33,2,1.5);
+INSERT INTO Item VALUES(30,2,10,18,1.5);
+INSERT INTO Item VALUES(30,1,16,19,1.5);
+INSERT INTO Item VALUES(30,0,14,7,1.5);
+INSERT INTO Item VALUES(31,10,0,3,1.5);
+INSERT INTO Item VALUES(31,9,14,15,1.5);
+INSERT INTO Item VALUES(31,8,7,5,1.5);
+INSERT INTO Item VALUES(31,7,38,3,1.5);
+INSERT INTO Item VALUES(31,6,26,16,1.5);
+INSERT INTO Item VALUES(31,5,1,4,1.5);
+INSERT INTO Item VALUES(31,4,8,14,1.5);
+INSERT INTO Item VALUES(31,3,12,10,1.5);
+INSERT INTO Item VALUES(31,2,4,3,1.5);
+INSERT INTO Item VALUES(31,1,4,23,1.5);
+INSERT INTO Item VALUES(31,0,33,10,1.5);
+INSERT INTO Item VALUES(32,2,1,14,1.5);
+INSERT INTO Item VALUES(32,1,30,13,1.5);
+INSERT INTO Item VALUES(32,0,35,11,1.5);
+INSERT INTO Item VALUES(33,15,38,7,1.5);
+INSERT INTO Item VALUES(33,14,44,13,1.5);
+INSERT INTO Item VALUES(33,13,25,16,1.5);
+INSERT INTO Item VALUES(33,12,16,23,1.5);
+INSERT INTO Item VALUES(33,11,5,7,1.5);
+INSERT INTO Item VALUES(33,10,24,9,1.5);
+INSERT INTO Item VALUES(33,9,29,5,1.5);
+INSERT INTO Item VALUES(33,8,3,15,1.5);
+INSERT INTO Item VALUES(33,7,43,10,1.5);
+INSERT INTO Item VALUES(33,6,17,16,1.5);
+INSERT INTO Item VALUES(33,5,8,11,1.5);
+INSERT INTO Item VALUES(33,4,24,1,1.5);
+INSERT INTO Item VALUES(33,3,48,1,1.5);
+INSERT INTO Item VALUES(33,2,36,16,1.5);
+INSERT INTO Item VALUES(33,1,10,21,1.5);
+INSERT INTO Item VALUES(33,0,36,5,1.5);
+INSERT INTO Item VALUES(34,14,46,7,1.5);
+INSERT INTO Item VALUES(34,13,30,14,1.5);
+INSERT INTO Item VALUES(34,12,43,21,1.5);
+INSERT INTO Item VALUES(34,11,4,17,1.5);
+INSERT INTO Item VALUES(34,10,41,16,1.5);
+INSERT INTO Item VALUES(34,9,8,17,1.5);
+INSERT INTO Item VALUES(34,8,3,1,1.5);
+INSERT INTO Item VALUES(34,7,21,22,1.5);
+INSERT INTO Item VALUES(34,6,32,7,1.5);
+INSERT INTO Item VALUES(34,5,45,13,1.5);
+INSERT INTO Item VALUES(34,4,27,1,1.5);
+INSERT INTO Item VALUES(34,3,44,15,1.5);
+INSERT INTO Item VALUES(34,2,28,22,1.5);
+INSERT INTO Item VALUES(34,1,4,3,1.5);
+INSERT INTO Item VALUES(34,0,10,22,1.5);
+INSERT INTO Item VALUES(35,13,19,17,1.5);
+INSERT INTO Item VALUES(35,12,7,23,1.5);
+INSERT INTO Item VALUES(35,11,44,9,1.5);
+INSERT INTO Item VALUES(35,10,17,11,1.5);
+INSERT INTO Item VALUES(35,9,19,1,1.5);
+INSERT INTO Item VALUES(35,8,0,1,1.5);
+INSERT INTO Item VALUES(35,7,22,15,1.5);
+INSERT INTO Item VALUES(35,6,5,4,1.5);
+INSERT INTO Item VALUES(35,5,33,5,1.5);
+INSERT INTO Item VALUES(35,4,14,17,1.5);
+INSERT INTO Item VALUES(35,3,27,10,1.5);
+INSERT INTO Item VALUES(35,2,14,4,1.5);
+INSERT INTO Item VALUES(35,1,3,9,1.5);
+INSERT INTO Item VALUES(35,0,20,17,1.5);
+INSERT INTO Item VALUES(36,11,44,9,1.5);
+INSERT INTO Item VALUES(36,10,47,11,1.5);
+INSERT INTO Item VALUES(36,9,31,18,1.5);
+INSERT INTO Item VALUES(36,8,4,21,1.5);
+INSERT INTO Item VALUES(36,7,39,19,1.5);
+INSERT INTO Item VALUES(36,6,39,20,1.5);
+INSERT INTO Item VALUES(36,5,25,8,1.5);
+INSERT INTO Item VALUES(36,4,40,5,1.5);
+INSERT INTO Item VALUES(36,3,10,8,1.5);
+INSERT INTO Item VALUES(36,2,1,6,1.5);
+INSERT INTO Item VALUES(36,1,15,23,1.5);
+INSERT INTO Item VALUES(36,0,18,13,1.5);
+INSERT INTO Item VALUES(37,21,6,9,1.5);
+INSERT INTO Item VALUES(37,20,14,1,1.5);
+INSERT INTO Item VALUES(37,19,19,20,1.5);
+INSERT INTO Item VALUES(37,18,26,22,1.5);
+INSERT INTO Item VALUES(37,17,38,18,1.5);
+INSERT INTO Item VALUES(37,16,27,8,1.5);
+INSERT INTO Item VALUES(37,15,32,12,1.5);
+INSERT INTO Item VALUES(37,14,12,3,1.5);
+INSERT INTO Item VALUES(37,13,32,3,1.5);
+INSERT INTO Item VALUES(37,12,24,23,1.5);
+INSERT INTO Item VALUES(37,11,30,5,1.5);
+INSERT INTO Item VALUES(37,10,1,18,1.5);
+INSERT INTO Item VALUES(37,9,47,16,1.5);
+INSERT INTO Item VALUES(37,8,46,9,1.5);
+INSERT INTO Item VALUES(37,7,24,19,1.5);
+INSERT INTO Item VALUES(37,6,34,12,1.5);
+INSERT INTO Item VALUES(37,5,1,14,1.5);
+INSERT INTO Item VALUES(37,4,13,20,1.5);
+INSERT INTO Item VALUES(37,3,26,7,1.5);
+INSERT INTO Item VALUES(37,2,36,8,1.5);
+INSERT INTO Item VALUES(37,1,15,20,1.5);
+INSERT INTO Item VALUES(37,0,41,24,1.5);
+INSERT INTO Item VALUES(38,19,4,7,1.5);
+INSERT INTO Item VALUES(38,18,28,20,1.5);
+INSERT INTO Item VALUES(38,17,32,4,1.5);
+INSERT INTO Item VALUES(38,16,40,18,1.5);
+INSERT INTO Item VALUES(38,15,47,10,1.5);
+INSERT INTO Item VALUES(38,14,20,7,1.5);
+INSERT INTO Item VALUES(38,13,8,7,1.5);
+INSERT INTO Item VALUES(38,12,1,18,1.5);
+INSERT INTO Item VALUES(38,11,19,18,1.5);
+INSERT INTO Item VALUES(38,10,4,18,1.5);
+INSERT INTO Item VALUES(38,9,27,20,1.5);
+INSERT INTO Item VALUES(38,8,40,10,1.5);
+INSERT INTO Item VALUES(38,7,15,1,1.5);
+INSERT INTO Item VALUES(38,6,5,19,1.5);
+INSERT INTO Item VALUES(38,5,48,17,1.5);
+INSERT INTO Item VALUES(38,4,45,14,1.5);
+INSERT INTO Item VALUES(38,3,27,19,1.5);
+INSERT INTO Item VALUES(38,2,4,8,1.5);
+INSERT INTO Item VALUES(38,1,45,13,1.5);
+INSERT INTO Item VALUES(38,0,48,14,1.5);
+INSERT INTO Item VALUES(39,3,20,17,1.5);
+INSERT INTO Item VALUES(39,2,39,16,1.5);
+INSERT INTO Item VALUES(39,1,24,6,1.5);
+INSERT INTO Item VALUES(39,0,10,12,1.5);
+INSERT INTO Item VALUES(40,20,4,16,1.5);
+INSERT INTO Item VALUES(40,19,7,23,1.5);
+INSERT INTO Item VALUES(40,18,33,11,1.5);
+INSERT INTO Item VALUES(40,17,4,20,1.5);
+INSERT INTO Item VALUES(40,16,27,16,1.5);
+INSERT INTO Item VALUES(40,15,22,12,1.5);
+INSERT INTO Item VALUES(40,14,4,24,1.5);
+INSERT INTO Item VALUES(40,13,6,8,1.5);
+INSERT INTO Item VALUES(40,12,35,13,1.5);
+INSERT INTO Item VALUES(40,11,27,2,1.5);
+INSERT INTO Item VALUES(40,10,6,11,1.5);
+INSERT INTO Item VALUES(40,9,40,17,1.5);
+INSERT INTO Item VALUES(40,8,11,4,1.5);
+INSERT INTO Item VALUES(40,7,31,1,1.5);
+INSERT INTO Item VALUES(40,6,28,12,1.5);
+INSERT INTO Item VALUES(40,5,32,18,1.5);
+INSERT INTO Item VALUES(40,4,18,13,1.5);
+INSERT INTO Item VALUES(40,3,26,10,1.5);
+INSERT INTO Item VALUES(40,2,4,5,1.5);
+INSERT INTO Item VALUES(40,1,45,24,1.5);
+INSERT INTO Item VALUES(40,0,46,24,1.5);
+INSERT INTO Item VALUES(41,11,48,15,1.5);
+INSERT INTO Item VALUES(41,10,24,20,1.5);
+INSERT INTO Item VALUES(41,9,26,21,1.5);
+INSERT INTO Item VALUES(41,8,9,22,1.5);
+INSERT INTO Item VALUES(41,7,22,18,1.5);
+INSERT INTO Item VALUES(41,6,17,11,1.5);
+INSERT INTO Item VALUES(41,5,9,21,1.5);
+INSERT INTO Item VALUES(41,4,16,22,1.5);
+INSERT INTO Item VALUES(41,3,29,20,1.5);
+INSERT INTO Item VALUES(41,2,36,2,1.5);
+INSERT INTO Item VALUES(41,1,47,19,1.5);
+INSERT INTO Item VALUES(41,0,5,24,1.5);
+INSERT INTO Item VALUES(42,4,48,15,1.5);
+INSERT INTO Item VALUES(42,3,40,14,1.5);
+INSERT INTO Item VALUES(42,2,40,19,1.5);
+INSERT INTO Item VALUES(42,1,18,21,1.5);
+INSERT INTO Item VALUES(42,0,48,9,1.5);
+INSERT INTO Item VALUES(43,16,38,12,1.5);
+INSERT INTO Item VALUES(43,15,48,7,1.5);
+INSERT INTO Item VALUES(43,14,3,18,1.5);
+INSERT INTO Item VALUES(43,13,44,22,1.5);
+INSERT INTO Item VALUES(43,12,40,24,1.5);
+INSERT INTO Item VALUES(43,11,49,23,1.5);
+INSERT INTO Item VALUES(43,10,35,1,1.5);
+INSERT INTO Item VALUES(43,9,7,23,1.5);
+INSERT INTO Item VALUES(43,8,44,8,1.5);
+INSERT INTO Item VALUES(43,7,11,15,1.5);
+INSERT INTO Item VALUES(43,6,24,1,1.5);
+INSERT INTO Item VALUES(43,5,33,6,1.5);
+INSERT INTO Item VALUES(43,4,32,22,1.5);
+INSERT INTO Item VALUES(43,3,6,18,1.5);
+INSERT INTO Item VALUES(43,2,2,15,1.5);
+INSERT INTO Item VALUES(43,1,18,19,1.5);
+INSERT INTO Item VALUES(43,0,15,22,1.5);
+INSERT INTO Item VALUES(44,8,28,23,1.5);
+INSERT INTO Item VALUES(44,7,49,17,1.5);
+INSERT INTO Item VALUES(44,6,14,15,1.5);
+INSERT INTO Item VALUES(44,5,41,22,1.5);
+INSERT INTO Item VALUES(44,4,12,3,1.5);
+INSERT INTO Item VALUES(44,3,3,14,1.5);
+INSERT INTO Item VALUES(44,2,17,14,1.5);
+INSERT INTO Item VALUES(44,1,34,17,1.5);
+INSERT INTO Item VALUES(44,0,33,20,1.5);
+INSERT INTO Item VALUES(45,14,3,16,1.5);
+INSERT INTO Item VALUES(45,13,47,8,1.5);
+INSERT INTO Item VALUES(45,12,32,13,1.5);
+INSERT INTO Item VALUES(45,11,31,22,1.5);
+INSERT INTO Item VALUES(45,10,41,24,1.5);
+INSERT INTO Item VALUES(45,9,26,18,1.5);
+INSERT INTO Item VALUES(45,8,9,2,1.5);
+INSERT INTO Item VALUES(45,7,6,24,1.5);
+INSERT INTO Item VALUES(45,6,39,5,1.5);
+INSERT INTO Item VALUES(45,5,45,17,1.5);
+INSERT INTO Item VALUES(45,4,3,14,1.5);
+INSERT INTO Item VALUES(45,3,14,11,1.5);
+INSERT INTO Item VALUES(45,2,46,8,1.5);
+INSERT INTO Item VALUES(45,1,11,6,1.5);
+INSERT INTO Item VALUES(45,0,44,6,1.5);
+INSERT INTO Item VALUES(46,17,12,23,1.5);
+INSERT INTO Item VALUES(46,16,46,21,1.5);
+INSERT INTO Item VALUES(46,15,40,11,1.5);
+INSERT INTO Item VALUES(46,14,24,10,1.5);
+INSERT INTO Item VALUES(46,13,36,20,1.5);
+INSERT INTO Item VALUES(46,12,21,24,1.5);
+INSERT INTO Item VALUES(46,11,1,4,1.5);
+INSERT INTO Item VALUES(46,10,11,24,1.5);
+INSERT INTO Item VALUES(46,9,7,4,1.5);
+INSERT INTO Item VALUES(46,8,8,22,1.5);
+INSERT INTO Item VALUES(46,7,49,9,1.5);
+INSERT INTO Item VALUES(46,6,41,18,1.5);
+INSERT INTO Item VALUES(46,5,25,9,1.5);
+INSERT INTO Item VALUES(46,4,17,5,1.5);
+INSERT INTO Item VALUES(46,3,21,19,1.5);
+INSERT INTO Item VALUES(46,2,30,14,1.5);
+INSERT INTO Item VALUES(46,1,12,24,1.5);
+INSERT INTO Item VALUES(46,0,5,21,1.5);
+INSERT INTO Item VALUES(47,13,33,8,1.5);
+INSERT INTO Item VALUES(47,12,12,20,1.5);
+INSERT INTO Item VALUES(47,11,35,10,1.5);
+INSERT INTO Item VALUES(47,10,45,2,1.5);
+INSERT INTO Item VALUES(47,9,32,9,1.5);
+INSERT INTO Item VALUES(47,8,16,2,1.5);
+INSERT INTO Item VALUES(47,7,28,14,1.5);
+INSERT INTO Item VALUES(47,6,8,10,1.5);
+INSERT INTO Item VALUES(47,5,40,8,1.5);
+INSERT INTO Item VALUES(47,4,15,1,1.5);
+INSERT INTO Item VALUES(47,3,1,4,1.5);
+INSERT INTO Item VALUES(47,2,17,6,1.5);
+INSERT INTO Item VALUES(47,1,23,13,1.5);
+INSERT INTO Item VALUES(47,0,23,15,1.5);
+INSERT INTO Item VALUES(48,10,41,10,1.5);
+INSERT INTO Item VALUES(48,9,35,17,1.5);
+INSERT INTO Item VALUES(48,8,5,12,1.5);
+INSERT INTO Item VALUES(48,7,30,19,1.5);
+INSERT INTO Item VALUES(48,6,11,17,1.5);
+INSERT INTO Item VALUES(48,5,24,16,1.5);
+INSERT INTO Item VALUES(48,4,48,4,1.5);
+INSERT INTO Item VALUES(48,3,10,2,1.5);
+INSERT INTO Item VALUES(48,2,23,10,1.5);
+INSERT INTO Item VALUES(48,1,26,23,1.5);
+INSERT INTO Item VALUES(48,0,6,23,1.5);
+INSERT INTO Item VALUES(49,16,24,18,1.5);
+INSERT INTO Item VALUES(49,15,19,24,1.5);
+INSERT INTO Item VALUES(49,14,23,5,1.5);
+INSERT INTO Item VALUES(49,13,6,22,1.5);
+INSERT INTO Item VALUES(49,12,21,17,1.5);
+INSERT INTO Item VALUES(49,11,40,15,1.5);
+INSERT INTO Item VALUES(49,10,30,16,1.5);
+INSERT INTO Item VALUES(49,9,7,24,1.5);
+INSERT INTO Item VALUES(49,8,48,24,1.5);
+INSERT INTO Item VALUES(49,7,6,21,1.5);
+INSERT INTO Item VALUES(49,6,29,15,1.5);
+INSERT INTO Item VALUES(49,5,16,1,1.5);
+INSERT INTO Item VALUES(49,4,47,14,1.5);
+INSERT INTO Item VALUES(49,3,17,19,1.5);
+INSERT INTO Item VALUES(49,2,29,6,1.5);
+INSERT INTO Item VALUES(49,1,22,16,1.5);
+INSERT INTO Item VALUES(49,0,18,6,1.5);
+UPDATE Product SET Price=ROUND(Price*.1,2);
+UPDATE Item SET Cost=Cost*(SELECT Price FROM Product prod WHERE ProductID=prod.ID);
+UPDATE Invoice SET Total=SELECT SUM(Cost*Quantity) FROM Item WHERE InvoiceID=Invoice.ID;
+
+COMMIT;
diff --git a/doc-src/verbatim/sample/server.properties b/doc-src/verbatim/sample/server.properties
new file mode 100644
index 0000000..8726b34
--- /dev/null
+++ b/doc-src/verbatim/sample/server.properties
@@ -0,0 +1,20 @@
+# Hsqldb Server cfg file.
+# See the HyperSQL Network Listeners chapter of the HyperSQL User Guide.
+
+# Each server.database.X setting defines a database "catalog".
+# I.e., an independent set of data.
+# Each server.database.X setting corresponds exactly to the jdbc:hsqldb:*
+# JDBC URL you would use if you wanted to get a direct (In-Process)
+# Connection to the catalog instead of "serving" it.
+
+server.database.0=file:db0/db0
+# I suggest that, for every file: catalog you define, you add the
+# connection property "ifexists=true" after the database instance
+# is created (which happens simply by starting the Server one time).
+# Just append ";ifexists=true" to the file: URL, like so:
+# server.database.0=file:db0/db0;ifexists=true
+
+# server.dbname.0 defaults to "" (i.e. server.dbname.n for n==0), but
+# the catalog definition n will be entirely ignored for n > 0 if you do not
+# set server.dbname.n.  I.e. dbname setting is required for n > 0, though it
+# may be set to blank (e.g. "server.dbname.3=")
diff --git a/doc-src/verbatim/sample/sqltool.rc b/doc-src/verbatim/sample/sqltool.rc
new file mode 100644
index 0000000..0a772a7
--- /dev/null
+++ b/doc-src/verbatim/sample/sqltool.rc
@@ -0,0 +1,141 @@
+# $Id: sqltool.rc 3353 2009-12-15 19:52:13Z unsaved $
+
+# This is a sample RC configuration file used by SqlTool, DatabaseManager,
+# and any other program that uses the org.hsqldb.lib.RCData class.
+# See the documentation for SqlTool for various ways to use this file.
+
+# If you have the least concerns about security, then secure access to
+# your RC file.
+
+# You can run SqlTool right now by copying this file to your home directory
+# and running
+#    java -jar /path/to/sqltool.jar mem
+# This will access the first urlid definition below in order to use a 
+# personal Memory-Only database.
+# "url" values may, of course, contain JDBC connection properties, delimited
+# with semicolons.
+# As of revision 3347 of SqlFile, you can also connect to datasources defined
+# here from within an SqlTool session/file with the command "\j urlid".
+
+# You can use Java system property values in this file like this:  ${user.home}
+
+# The only feature added recently is the optional "transiso" setting,
+# which may be set to an all-caps transaction isolation level as listed
+# in the Java API Spec for java.sql.Connection.
+# Windows users are advised to use forward slashes instead of reverse slashes,
+# and to avoid paths containing spaces or other funny characters.  (This
+# recommendation applies to any Java app, not just SqlTool).
+
+# A personal Memory-Only (non-persistent) database.
+urlid mem
+url jdbc:hsqldb:mem:memdbid
+username SA
+password
+
+# A personal, local, persistent database.
+urlid personal
+url jdbc:hsqldb:file:${user.home}/db/personal;shutdown=true
+username SA
+password
+transiso TRANSACTION_READ_COMMITTED
+# When connecting directly to a file database like this, you should 
+# use the shutdown connection property like this to shut down the DB
+# properly when you exit the JVM.
+
+# This is for a hsqldb Server running with default settings on your local
+# computer (and for which you have not changed the password for "SA").
+urlid localhost-sa
+url jdbc:hsqldb:hsql://localhost
+username SA
+password
+
+
+
+# Template for a urlid for an Oracle database.
+# You will need to put the oracle.jdbc.OracleDriver class into your 
+# classpath.
+# In the great majority of cases, you want to use the file classes12.zip
+# (which you can get from the directory $ORACLE_HOME/jdbc/lib of any
+# Oracle installation compatible with your server).
+# Since you need to add to the classpath, you can't invoke SqlTool with
+# the jar switch, like "java -jar .../hsqldb.jar..." or 
+# "java -jar .../hsqlsqltool.jar...".
+# Put both the HSQLDB jar and classes12.zip in your classpath (and export!)
+# and run something like "java org.hsqldb.util.SqlTool...".
+
+#urlid cardiff2
+#url jdbc:oracle:thin:@aegir.admc.com:1522:TRAFFIC_SID
+#username blaine
+#password secretpassword
+#driver oracle.jdbc.OracleDriver
+
+
+
+# Template for a TLS-encrypted HSQLDB Server.
+# Remember that the hostname in hsqls (and https) JDBC URLs must match the
+# CN of the server certificate (the port and instance alias that follows 
+# are not part of the certificate at all).
+# You only need to set "truststore" if the server cert is not approved by
+# your system default truststore (which a commercial certificate probably
+# would be).
+
+#urlid tls
+#url jdbc:hsqldb:hsqls://db.admc.com:9001/lm2
+#username BLAINE
+#password asecret
+#truststore ${user.home}/ca/db/db-trust.store
+
+
+# Template for a Postgresql database
+#urlid blainedb
+#url jdbc:postgresql://idun.africawork.org/blainedb
+#username blaine
+#password losung1
+#driver org.postgresql.Driver
+
+# Template for a MySQL database.  MySQL has poor JDBC support.
+#urlid mysql-testdb
+#url jdbc:mysql://hostname:3306/dbname
+#username root
+#password hiddenpwd
+#driver com.mysql.jdbc.Driver
+
+# Note that "databases" in SQL Server and Sybase are traditionally used for
+# the same purpose as "schemas" with more SQL-compliant databases.
+
+# Template for a Microsoft SQL Server database
+#urlid msprojsvr
+#url jdbc:microsoft:sqlserver://hostname;DatabaseName=DbName;SelectMethod=Cursor
+# The SelectMethod setting is required to do more than one thing on a JDBC
+# session (I guess Microsoft thought nobody would really use Java for 
+# anything other than a "hello world" program).
+# This is for Microsoft's SQL Server 2000 driver (requires mssqlserver.jar
+# and msutil.jar).
+#driver com.microsoft.jdbc.sqlserver.SQLServerDriver
+#username myuser
+#password hiddenpwd
+
+# Template for a Sybase database
+#urlid sybase
+#url jdbc:sybase:Tds:hostname:4100/dbname
+#username blaine
+#password hiddenpwd
+# This is for the jConnect driver (requires jconn3.jar).
+#driver com.sybase.jdbc3.jdbc.SybDriver
+
+# Template for Embedded Derby / Java DB.
+#urlid derby1
+#url jdbc:derby:path/to/derby/directory;create=true
+#username ${user.name}
+#password any_noauthbydefault
+#driver org.apache.derby.jdbc.EmbeddedDriver
+# The embedded Derby driver requires derby.jar.
+# There'a also the org.apache.derby.jdbc.ClientDriver driver with URL
+# like jdbc:derby://<server>[:<port>]/databaseName, which requires
+# derbyclient.jar.
+# You can use \= to commit, since the Derby team decided (why???)
+# not to implement the SQL standard statement "commit"!!
+# Note that SqlTool can not shut down an embedded Derby database properly,
+# since that requires an additional SQL connection just for that purpose.
+# However, I've never lost data by not shutting it down properly.
+# Other than not supporting this quirk of Derby, SqlTool is miles ahead of ij.
diff --git a/doc-src/verbatim/src/org/hsqldb/Tokens.java b/doc-src/verbatim/src/org/hsqldb/Tokens.java
new file mode 100644
index 0000000..3c0365e
--- /dev/null
+++ b/doc-src/verbatim/src/org/hsqldb/Tokens.java
@@ -0,0 +1,2302 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.OrderedIntHashSet;
+
+/**
+ * Defines and enumerates reserved and non-reserved SQL keywords.<p>
+ *
+ * @author  Nitin Chauhan (initial work)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class Tokens {
+
+    //
+    // SQL 200n reserved words full set
+    static final String        T_ABS              = "ABS";
+    public static final String T_ALL              = "ALL";
+    static final String        T_ALLOCATE         = "ALLOCATE";
+    public static final String T_ALTER            = "ALTER";
+    static final String        T_AND              = "AND";
+    static final String        T_ANY              = "ANY";
+    static final String        T_ARE              = "ARE";
+    public static final String T_ARRAY            = "ARRAY";
+    public static final String T_AS               = "AS";
+    static final String        T_ASENSITIVE       = "ASENSITIVE";
+    static final String        T_ASYMMETRIC       = "ASYMMETRIC";
+    static final String        T_AT               = "AT";
+    static final String        T_ATOMIC           = "ATOMIC";
+    public static final String T_AUTHORIZATION    = "AUTHORIZATION";
+    static final String        T_AVG              = "AVG";
+    static final String        T_BEGIN            = "BEGIN";
+    static final String        T_BETWEEN          = "BETWEEN";
+    public static final String T_BIGINT           = "BIGINT";
+    public static final String T_BINARY           = "BINARY";
+    static final String        T_BIT_LENGTH       = "BIT_LENGTH";
+    public static final String T_BLOB             = "BLOB";
+    public static final String T_BOOLEAN          = "BOOLEAN";
+    static final String        T_BOTH             = "BOTH";
+    static final String        T_BY               = "BY";
+    public static final String T_CALL             = "CALL";
+    static final String        T_CALLED           = "CALLED";
+    static final String        T_CARDINALITY      = "CARDINALITY";
+    public static final String T_CASCADED         = "CASCADED";
+    static final String        T_CASE             = "CASE";
+    static final String        T_CAST             = "CAST";
+    static final String        T_CEIL             = "CEIL";
+    static final String        T_CEILING          = "CEILING";
+    static final String        T_CHAR             = "CHAR";
+    static final String        T_CHAR_LENGTH      = "CHAR_LENGTH";
+    public static final String T_CHARACTER        = "CHARACTER";
+    static final String        T_CHARACTER_LENGTH = "CHARACTER_LENGTH";
+    public static final String T_CHECK            = "CHECK";
+    public static final String T_CLOB             = "CLOB";
+    static final String        T_CLOSE            = "CLOSE";
+    static final String        T_COALESCE         = "COALESCE";
+    static final String        T_COLLATE          = "COLLATE";
+    static final String        T_COLLECT          = "COLLECT";
+    static final String        T_COLUMN           = "COLUMN";
+    public static final String T_COMMIT           = "COMMIT";
+    static final String        T_CONDITION        = "CONDIITON";
+    public static final String T_CONNECT          = "CONNECT";
+    public static final String T_CONSTRAINT       = "CONSTRAINT";
+    static final String        T_CONVERT          = "CONVERT";
+    static final String        T_CORR             = "CORR";
+    static final String        T_CORRESPONDING    = "CORRESPONDING";
+    static final String        T_COUNT            = "COUNT";
+    static final String        T_COVAR_POP        = "COVAR_POP";
+    static final String        T_COVAR_SAMP       = "COVAR_SAMP";
+    public static final String T_CREATE           = "CREATE";
+    static final String        T_CROSS            = "CROSS";
+    static final String        T_CUBE             = "CUBE";
+    static final String        T_CUME_DIST        = "CUME_DIST";
+    static final String        T_CURRENT          = "CURRENT";
+    static final String        T_CURRENT_CATALOG  = "CURRENT_CATALOG";
+    static final String        T_CURRENT_DATE     = "CURRENT_DATE";
+    static final String T_CURRENT_DEFAULT_TRANSFORM_GROUP =
+        "CURRENT_DEFAULT_TRANSFORM_GROUP";
+    static final String T_CURRENT_PATH      = "CURRENT_PATH";
+    static final String T_CURRENT_ROLE      = "CURRENT_ROLE";
+    static final String T_CURRENT_SCHEMA    = "CURRENT_SCHEMA";
+    static final String T_CURRENT_TIME      = "CURRENT_TIME";
+    static final String T_CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP";
+    static final String T_CURRENT_TRANSFORM_GROUP_FOR_TYPE =
+        "CURRENT_TRANSFORM_GROUP_FOR_TYPE";
+    static final String        T_CURRENT_USER      = "CURRENT_USER";
+    static final String        T_CURSOR            = "CURSOR";
+    static final String        T_CYCLE             = "CYCLE";
+    public static final String T_DATE              = "DATE";
+    public static final String T_DAY               = "DAY";
+    static final String        T_DEALLOCATE        = "DEALLOCATE";
+    static final String        T_DEC               = "DEC";
+    public static final String T_DECIMAL           = "DECIMAL";
+    static final String        T_DECLARE           = "DECLARE";
+    public static final String T_DEFAULT           = "DEFAULT";
+    public static final String T_DELETE            = "DELETE";
+    static final String        T_DENSE_RANK        = "DENSE_RANK";
+    static final String        T_DEREF             = "DEREF";
+    static final String        T_DESCRIBE          = "DESCRIBE";
+    static final String        T_DETERMINISTIC     = "DETERMINISTIC";
+    static final String        T_DISCONNECT        = "DISCONNECT";
+    static final String        T_DISTINCT          = "DISTINCT";
+    public static final String T_DO                = "DO";
+    public static final String T_DOUBLE            = "DOUBLE";
+    static final String        T_DROP              = "DROP";
+    static final String        T_DYNAMIC           = "DYNAMIC";
+    static final String        T_EACH              = "EACH";
+    static final String        T_ELEMENT           = "ELEMENT";
+    static final String        T_ELSE              = "ELSE";
+    static final String        T_ELSEIF            = "ELSEIF";
+    static final String        T_END               = "END";
+    static final String        T_END_EXEC          = "END_EXEC";
+    static final String        T_ESCAPE            = "ESCAPE";
+    static final String        T_EVERY             = "EVERY";
+    static final String        T_EXCEPT            = "EXCEPT";
+    static final String        T_EXEC              = "EXEC";
+    public static final String T_EXECUTE           = "EXECUTE";
+    static final String        T_EXISTS            = "EXISTS";
+    static final String        T_EXP               = "EXP";
+    static final String        T_EXTERNAL          = "EXTERNAL";
+    static final String        T_EXTRACT           = "EXTRACT";
+    public static final String T_FALSE             = "FALSE";
+    static final String        T_FETCH             = "FETCH";
+    static final String        T_FILTER            = "FILTER";
+    static final String        T_FIRST_VALUE       = "FIRST_VALUE";
+    public static final String T_FLOAT             = "FLOAT";
+    static final String        T_FLOOR             = "FLOOR";
+    static final String        T_FOR               = "FOR";
+    public static final String T_FOREIGN           = "FOREIGN";
+    static final String        T_FREE              = "FREE";
+    static final String        T_FROM              = "FROM";
+    static final String        T_FULL              = "FULL";
+    public static final String T_FUNCTION          = "FUNCTION";
+    static final String        T_FUSION            = "FUSION";
+    public static final String T_GET               = "GET";
+    static final String        T_GLOBAL            = "GLOBAL";
+    public static final String T_GRANT             = "GRANT";
+    static final String        T_GROUP             = "GROUP";
+    static final String        T_GROUPING          = "GROUPING";
+    static final String        T_HANDLER           = "HANDLER";
+    static final String        T_HAVING            = "HAVING";
+    static final String        T_HOLD              = "HOLD";
+    public static final String T_HOUR              = "HOUR";
+    static final String        T_IDENTITY          = "IDENTITY";
+    static final String        T_IF                = "IF";
+    static final String        T_IMPORT            = "IMPORT";
+    static final String        T_IN                = "IN";
+    static final String        T_INDICATOR         = "INDICATOR";
+    static final String        T_INNER             = "INNER";
+    static final String        T_INOUT             = "INOUT";
+    static final String        T_INSENSITIVE       = "INSENSITIVE";
+    public static final String T_INSERT            = "INSERT";
+    static final String        T_INT               = "INT";
+    public static final String T_INTEGER           = "INTEGER";
+    static final String        T_INTERSECT         = "INTERSECT";
+    static final String        T_INTERSECTION      = "INTERSECTION";
+    public static final String T_INTERVAL          = "INTERVAL";
+    static final String        T_INTO              = "INTO";
+    static final String        T_ITERATE           = "ITERATE";
+    static final String        T_IS                = "IS";
+    static final String        T_JAR               = "JAR";              // SQL/JRT
+    static final String        T_JOIN              = "JOIN";
+    static final String        T_LAG               = "LAG";
+    public static final String T_LANGUAGE          = "LANGUAGE";
+    static final String        T_LARGE             = "LARGE";
+    static final String        T_LAST_VALUE        = "LAST_VALUE";
+    static final String        T_LATERAL           = "LATERAL";
+    static final String        T_LEAD              = "LEAD";
+    static final String        T_LEADING           = "LEADING";
+    static final String        T_LEAVE             = "LEAVE";
+    static final String        T_LEFT              = "LEFT";
+    static final String        T_LIKE              = "LIKE";
+    static final String        T_LIKE_REGX         = "LIKE_REGX";
+    static final String        T_LN                = "LN";
+    public static final String T_LOCAL             = "LOCAL";
+    static final String        T_LOCALTIME         = "LOCALTIME";
+    static final String        T_LOCALTIMESTAMP    = "LOCALTIMESTAMP";
+    public static final String T_LOOP              = "LOOP";
+    static final String        T_LOWER             = "LOWER";
+    static final String        T_MATCH             = "MATCH";
+    static final String        T_MAX               = "MAX";
+    static final String        T_MAX_CARDINALITY   = "MAX_CARDINALITY";
+    static final String        T_MEMBER            = "MEMBER";
+    static final String        T_MERGE             = "MERGE";
+    static final String        T_METHOD            = "METHOD";
+    static final String        T_MIN               = "MIN";
+    public static final String T_MINUTE            = "MINUTE";
+    static final String        T_MOD               = "MOD";
+    static final String        T_MODIFIES          = "MODIFIES";
+    static final String        T_MODULE            = "MODULE";
+    public static final String T_MONTH             = "MONTH";
+    public static final String T_MULTISET          = "MULTISET";
+    static final String        T_NATIONAL          = "NATIONAL";
+    static final String        T_NATURAL           = "NATURAL";
+    static final String        T_NCHAR             = "NCHAR";
+    static final String        T_NCLOB             = "NCLOB";
+    static final String        T_NEW               = "NEW";
+    public static final String T_NO                = "NO";
+    public static final String T_NONE              = "NONE";
+    static final String        T_NORMALIZE         = "NORMALIZE";
+    static final String        T_NOT               = "NOT";
+    static final String        T_NTH_VALUE         = "NTH_VALUE";
+    static final String        T_NTILE             = "NTILE";
+    public static final String T_NULL              = "NULL";
+    public static final String T_NULLIF            = "NULLIF";
+    public static final String T_NUMERIC           = "NUMERIC";
+    static final String        T_OCCURRENCES_REGEX = "OCCURRENCES_REGEX";
+    static final String        T_OCTET_LENGTH      = "OCTET_LENGTH";
+    static final String        T_OF                = "OF";
+    static final String        T_OFFSET            = "OFFSET";
+    static final String        T_OLD               = "OLD";
+    public static final String T_ON                = "ON";
+    public static final String T_ONLY              = "ONLY";
+    static final String        T_OPEN              = "OPEN";
+    static final String        T_OR                = "OR";
+    static final String        T_ORDER             = "ORDER";
+    static final String        T_OUT               = "OUT";
+    static final String        T_OUTER             = "OUTER";
+    static final String        T_OVER              = "OVER";
+    static final String        T_OVERLAPS          = "OVERLAPS";
+    static final String        T_OVERLAY           = "OVERLAY";
+    static final String        T_PARAMETER         = "PARAMETER";
+    static final String        T_PARTITION         = "PARTITION";
+    static final String        T_PERCENT_RANK      = "PERCENT_RANK";
+    static final String        T_PERCENTILE_CONT   = "PERCENTILE_CONT";
+    static final String        T_PERCENTILE_DISC   = "PERCENTILE_DISC";
+    static final String        T_POSITION          = "POSITION";
+    static final String        T_POSITION_REGEX    = "POSITION_REGEX";
+    static final String        T_POWER             = "POWER";
+    static final String        T_PRECISION         = "PRECISION";
+    static final String        T_PREPARE           = "PREPARE";
+    static final String        T_PRIMARY           = "PRIMARY";
+    public static final String T_PROCEDURE         = "PROCEDURE";
+    static final String        T_RANGE             = "RANGE";
+    static final String        T_RANK              = "RANK";
+    static final String        T_READS             = "READS";
+    public static final String T_REAL              = "REAL";
+    static final String        T_RECURSIVE         = "RECURSIVE";
+    static final String        T_REF               = "REF";
+    public static final String T_REFERENCES        = "REFERENCES";
+    static final String        T_REFERENCING       = "REFERENCING";
+    static final String        T_REGR_AVGX         = "REGR_AVGX";
+    static final String        T_REGR_AVGY         = "REGR_AVGY";
+    static final String        T_REGR_COUNT        = "REGR_COUNT";
+    static final String        T_REGR_INTERCEPT    = "REGR_INTERCEPT";
+    static final String        T_REGR_R2           = "REGR_R2";
+    static final String        T_REGR_SLOPE        = "REGR_SLOPE";
+    static final String        T_REGR_SXX          = "REGR_SXX";
+    static final String        T_REGR_SXY          = "REGR_SXY";
+    static final String        T_REGR_SYY          = "REGR_SYY";
+    static final String        T_RELEASE           = "RELEASE";
+    static final String        T_REPEAT            = "REPEAT";
+    static final String        T_RESIGNAL          = "RESIGNAL";
+    public static final String T_RESULT            = "RESULT";
+    static final String        T_RETURN            = "RETURN";
+    static final String        T_RETURNS           = "RETURNS";
+    static final String        T_REVOKE            = "REVOKE";
+    static final String        T_RIGHT             = "RIGHT";
+    static final String        T_ROLLBACK          = "ROLLBACK";
+    static final String        T_ROLLUP            = "ROLLUP";
+    public static final String T_ROW               = "ROW";
+    static final String        T_ROW_NUMBER        = "ROW_NUMBER";
+    public static final String T_ROWS              = "ROWS";
+    static final String        T_SAVEPOINT         = "SAVEPOINT";
+    static final String        T_SCOPE             = "SCOPE";
+    static final String        T_SCROLL            = "SCROLL";
+    static final String        T_SEARCH            = "SEARCH";
+    public static final String T_SECOND            = "SECOND";
+    public static final String T_SELECT            = "SELECT";
+    static final String        T_SENSITIVE         = "SENSITIVE";
+    static final String        T_SESSION_USER      = "SESSION_USER";
+    public static final String T_SET               = "SET";
+    static final String        T_SIGNAL            = "SIGNAL";
+    static final String        T_SIMILAR           = "SIMILAR";
+    public static final String T_SMALLINT          = "SMALLINT";
+    static final String        T_SOME              = "SOME";
+    public static final String T_SPECIFIC          = "SPECIFIC";
+    static final String        T_SPECIFICTYPE      = "SPECIFICTYPE";
+    public static final String T_SQL               = "SQL";
+    static final String        T_SQLEXCEPTION      = "SQLEXCEPTION";
+    static final String        T_SQLSTATE          = "SQLSTATE";
+    static final String        T_SQLWARNING        = "SQLWARNING";
+    static final String        T_SQRT              = "SQRT";
+    static final String        T_START             = "START";
+    static final String        T_STATIC            = "STATIC";
+    static final String        T_STDDEV_POP        = "STDDEV_POP";
+    static final String        T_STDDEV_SAMP       = "STDDEV_SAMP";
+    static final String        T_SUBMULTISET       = "SUBMULTISET";
+    static final String        T_SUBSTRING         = "SUBSTRING";
+    static final String        T_SUBSTRING_REGEX   = "SUBSTRING_REGEX";
+    static final String        T_SUM               = "SUM";
+    static final String        T_SYMMETRIC         = "SYMMETRIC";
+    static final String        T_SYSTEM            = "SYSTEM";
+    static final String        T_SYSTEM_USER       = "SYSTEM_USER";
+    public static final String T_TABLE             = "TABLE";
+    static final String        T_TABLESAMPLE       = "TABLESAMPLE";
+    static final String        T_THEN              = "THEN";
+    public static final String T_TIME              = "TIME";
+    public static final String T_TIMESTAMP         = "TIMESTAMP";
+    public static final String T_TIMEZONE_HOUR     = "TIMEZONE_HOUR";
+    public static final String T_TIMEZONE_MINUTE   = "TIMEZONE_MINUTE";
+    public static final String T_TO                = "TO";
+    static final String        T_TRAILING          = "TRAILING";
+    static final String        T_TRANSLATE         = "TRANSLATE";
+    static final String        T_TRANSLATE_REGEX   = "TRANSLATE_REGEX";
+    static final String        T_TRANSLATION       = "TRANSLATION";
+    static final String        T_TREAT             = "TREAT";
+    public static final String T_TRIGGER           = "TRIGGER";
+    static final String        T_TRIM              = "TRIM";
+    static final String        T_TRIM_ARRAY        = "TRIM_ARRAY";
+    public static final String T_TRUE              = "TRUE";
+    static final String        T_TRUNCATE          = "TRUNCATE";
+    static final String        T_UESCAPE           = "UESCAPE";
+    static final String        T_UNION             = "UNION";
+    public static final String T_UNIQUE            = "UNIQUE";
+    public static final String T_UNKNOWN           = "UNKNOWN";
+    static final String        T_UNNEST            = "UNNEST";
+    static final String        T_UNTIL             = "UNTIL";
+    public static final String T_UPDATE            = "UPDATE";
+    static final String        T_UPPER             = "UPPER";
+    public static final String T_USER              = "USER";
+    static final String        T_USING             = "USING";
+    static final String        T_VALUE             = "VALUE";
+    static final String        T_VALUES            = "VALUES";
+    static final String        T_VAR_POP           = "VAR_POP";
+    static final String        T_VAR_SAMP          = "VAR_SAMP";
+    public static final String T_VARBINARY         = "VARBINARY";
+    public static final String T_VARCHAR           = "VARCHAR";
+    static final String        T_VARYING           = "VARYING";
+    static final String        T_WHEN              = "WHEN";
+    static final String        T_WHENEVER          = "WHENEVER";
+    static final String        T_WHERE             = "WHERE";
+    public static final String T_WHILE             = "WHILE";
+    static final String        T_WIDTH_BUCKET      = "WIDTH_BUCKET";
+    static final String        T_WINDOW            = "WINDOW";
+    public static final String T_WITH              = "WITH";
+    static final String        T_WITHIN            = "WITHIN";
+    static final String        T_WITHOUT           = "WITHOUT";
+    public static final String T_YEAR              = "YEAR";
+
+    // ops
+    static final String        T_ASTERISK       = "*";
+    public static final String T_COMMA          = ",";
+    static final String        T_CIRCUMFLEX     = "^";
+    static final String        T_CLOSEBRACKET   = ")";
+    static final String        T_COLON          = ":";
+    static final String        T_CONCAT         = "||";
+    public static final String T_DIVIDE         = "/";
+    static final String        T_EQUALS         = "=";
+    static final String        T_GREATER        = ">";
+    static final String        T_GREATER_EQUALS = ">=";
+    public static final String T_LEFTBRACKET    = "[";
+    static final String        T_LESS           = "<";
+    static final String        T_LESS_EQUALS    = "<=";
+    static final String        T_PERCENT        = "%";
+    static final String        T_PLUS           = "+";
+    static final String        T_MINUS          = "-";
+    static final String        T_NOT_EQUALS     = "<>";
+    static final String        T_NOT_EQUALS_ALT = "!=";
+    static final String        T_OPENBRACKET    = "(";
+    static final String        T_QUESTION       = "?";
+    public static final String T_RIGHTBRACKET   = "]";
+    static final String        T_SEMICOLON      = ";";
+    static final String        T_DOUBLE_COLON   = "::";
+
+    // SQL:200n non-reserved word list
+    static final String        T_A                    = "A";
+    static final String        T_ABSOLUTE             = "ABSOLUTE";
+    static final String        T_ACTION               = "ACTION";
+    static final String        T_ADA                  = "ADA";
+    static final String        T_ADMIN                = "ADMIN";
+    static final String        T_AFTER                = "AFTER";
+    static final String        T_ALWAYS               = "ALWAYS";
+    static final String        T_ASC                  = "ASC";
+    static final String        T_ASSERTION            = "ASSERTION";
+    static final String        T_ASSIGNMENT           = "ASSIGNMENT";
+    static final String        T_ATTRIBUTE            = "ATTRIBUTE";
+    static final String        T_ATTRIBUTES           = "ATTRIBUTES";
+    static final String        T_BEFORE               = "BEFORE";
+    static final String        T_BERNOULLI            = "BERNOULLI";
+    static final String        T_BREADTH              = "BREADTH";
+    static final String        T_C                    = "C";
+    static final String        T_CASCADE              = "CASCADE";
+    public static final String T_CATALOG              = "CATALOG";
+    public static final String T_CATALOG_NAME         = "CATALOG_NAME";
+    static final String        T_CHAIN                = "CHAIN";
+    static final String T_CHARACTER_SET_CATALOG = "CHARACTER_SET_CATALOG";
+    static final String        T_CHARACTER_SET_NAME   = "CHARACTER_SET_NAME";
+    static final String        T_CHARACTER_SET_SCHEMA = "CHARACTER_SET_SCHEMA";
+    static final String        T_CHARACTERISTICS      = "CHARACTERISTICS";
+    static final String        T_CHARACTERS           = "CHARACTERS";
+    static final String        T_CLASS_ORIGIN         = "CLASS_ORIGIN";
+    static final String        T_COBOL                = "COBOL";
+    static final String        T_COLLATION            = "COLLATION";
+    static final String        T_COLLATION_CATALOG    = "COLLATION_CATALOG";
+    static final String        T_COLLATION_NAME       = "COLLATION_NAME";
+    static final String        T_COLLATION_SCHEMA     = "COLLATION_SCHEMA";
+    static final String        T_COLUMN_NAME          = "COLUMN_NAME";
+    static final String        T_COMMAND_FUNCTION     = "COMMAND_FUNCTION";
+    static final String T_COMMAND_FUNCTION_CODE = "COMMAND_FUNCTION_CODE";
+    public static final String T_COMMITTED            = "COMMITTED";
+    static final String        T_COMPARABLE           = "COMPARABLE";    // SQL/JRT
+    static final String        T_CONDITION_IDENTIFIER = "CONDIITON_IDENTIFIER";
+    static final String        T_CONDITION_NUMBER     = "CONDITION_NUMBER";
+    static final String        T_CONNECTION_NAME      = "CONNECTION_NAME";
+    static final String        T_CONSTRAINT_CATALOG   = "CONSTRAINT_CATALOG";
+    static final String        T_CONSTRAINT_NAME      = "CONSTRAINT_NAME";
+    static final String        T_CONSTRAINT_SCHEMA    = "CONSTRAINT_SCHEMA";
+    static final String        T_CONSTRAINTS          = "CONSTRAINTS";
+    static final String        T_CONSTRUCTOR          = "CONSTRUCTOR";
+    static final String        T_CONTAINS             = "CONTAINS";
+    static final String        T_CONTINUE             = "CONTINUE";
+    static final String        T_CURRENT_COLLATION    = "CURRENT_COLLATION";
+    static final String        T_CURSOR_NAME          = "CURSOR_NAME";
+    public static final String T_DATA                 = "DATA";
+    static final String T_DATETIME_INTERVAL_CODE = "DATETIME_INTERVAL_CODE";
+    static final String T_DATETIME_INTERVAL_PRECISION =
+        "DATETIME_INTERVAL_PRECISION";
+    public static final String T_DEFAULTS             = "DEFAULTS";
+    static final String        T_DEFERRABLE           = "DEFERRABLE";
+    static final String        T_DEFERRED             = "DEFERRED";
+    static final String        T_DEFINED              = "DEFINED";
+    static final String        T_DEFINER              = "DEFINER";
+    static final String        T_DEGREE               = "DEGREE";
+    static final String        T_DEPTH                = "DEPTH";
+    static final String        T_DERIVED              = "DERIVED";
+    static final String        T_DESC                 = "DESC";
+    static final String        T_DESCRIPTOR           = "DESCRIPTOR";
+    static final String        T_DIAGNOSTICS          = "DIAGNOSTICS";
+    static final String        T_DISPATCH             = "DISPATCH";
+    public static final String T_DOMAIN               = "DOMAIN";
+    static final String        T_DYNAMIC_FUNCTION     = "DYNAMIC_FUNCTION";
+    static final String T_DYNAMIC_FUNCTION_CODE = "DYNAMIC_FUNCTION_CODE";
+    static final String        T_EXCEPTION            = "EXCEPTION";
+    static final String        T_EXCLUDE              = "EXCLUDE";
+    static final String        T_EXCLUDING            = "EXCLUDING";
+    static final String        T_EXIT                 = "EXIT";
+    static final String        T_FINAL                = "FINAL";
+    static final String        T_FIRST                = "FIRST";
+    static final String        T_FOLLOWING            = "FOLLOWING";
+    static final String        T_FORTRAN              = "FORTRAN";
+    static final String        T_FOUND                = "FOUND";
+    public static final String T_G_FACTOR             = "G";
+    static final String        T_GENERAL              = "GENERAL";
+    static final String        T_GO                   = "GO";
+    static final String        T_GOTO                 = "GOTO";
+    static final String        T_GRANTED              = "GRANTED";
+    static final String        T_HIERARCHY            = "HIERARCHY";
+    static final String        T_IMPLEMENTATION       = "IMPLEMENTATION";
+    static final String        T_INCLUDING            = "INCLUDING";
+    public static final String T_INCREMENT            = "INCREMENT";
+    static final String        T_INITIALLY            = "INITIALLY";
+    static final String        T_INPUT                = "INPUT";
+    static final String        T_INSTANCE             = "INSTANCE";
+    static final String        T_INSTANTIABLE         = "INSTANTIABLE";
+    static final String        T_INSTEAD              = "INSTEAD";
+    static final String        T_INTERFACE            = "INTERFACE";     // SQL/JRT
+    static final String        T_INVOKER              = "INVOKER";
+    public static final String T_ISOLATION            = "ISOLATION";
+    public static final String T_JAVA                 = "JAVA";          // SQL/JRT
+    public static final String T_K_FACTOR             = "K";
+    static final String        T_KEY                  = "KEY";
+    static final String        T_KEY_MEMBER           = "KEY_MEMBER";
+    static final String        T_KEY_TYPE             = "KEY_TYPE";
+    static final String        T_LAST                 = "LAST";
+    static final String        T_LENGTH               = "LENGTH";
+    public static final String T_LEVEL                = "LEVEL";
+    public static final String T_LIBRARY              = "LIBRARY";
+    static final String        T_LOCATOR              = "LOCATOR";
+    public static final String T_M_FACTOR             = "M";
+    static final String        T_MAP                  = "MAP";
+    static final String        T_MATCHED              = "MATCHED";
+    static final String        T_MAXVALUE             = "MAXVALUE";
+    static final String        T_MESSAGE_LENGTH       = "MESSAGE_LENGTH";
+    static final String        T_MESSAGE_OCTET_LENGTH = "MESSAGE_OCTET_LENGTH";
+    static final String        T_MESSAGE_TEXT         = "MESSAGE_TEXT";
+    static final String        T_MINVALUE             = "MINVALUE";
+    static final String        T_MORE                 = "MORE";
+    static final String        T_MUMPS                = "MUMPS";
+    public static final String T_NAME                 = "NAME";
+    public static final String T_NAMES                = "NAMES";
+    static final String        T_NESTING              = "NESTING";
+    static final String        T_NEXT                 = "NEXT";
+    static final String        T_NORMALIZED           = "NORMALIZED";
+    static final String        T_NULLABLE             = "NULLABLE";
+    public static final String T_NULLS                = "NULLS";
+    static final String        T_NUMBER               = "NUMBER";
+    public static final String T_OBJECT               = "OBJECT";
+    static final String        T_OCTETS               = "OCTETS";
+    static final String        T_OPTION               = "OPTION";
+    static final String        T_OPTIONS              = "OPTIONS";
+    static final String        T_ORDERING             = "ORDERING";
+    static final String        T_ORDINALITY           = "ORDINALITY";
+    static final String        T_OTHERS               = "OTHERS";
+    public static final String T_OVERRIDING           = "OVERRIDING";
+    public static final String T_P_FACTOR             = "P";
+    static final String        T_PAD                  = "PAD";
+    static final String        T_PARAMETER_MODE       = "PARAMETER_MODE";
+    static final String        T_PARAMETER_NAME       = "PARAMETER_NAME";
+    static final String T_PARAMETER_ORDINAL_POSITION =
+        "PARAMETER_ORDINAL_POSITION";
+    static final String T_PARAMETER_SPECIFIC_CATALOG =
+        "PARAMETER_SPECIFIC_CATALOG";
+    static final String T_PARAMETER_SPEC_NAME = "PARAMETER_SPECIFIC_NAME";
+    static final String T_PARAMETER_SPEC_SCHEMA = "PARAMETER_SPECIFIC_SCHEMA";
+    static final String        T_PARTIAL              = "PARTIAL";
+    static final String        T_PASCAL               = "PASCAL";
+    public static final String T_PATH                 = "PATH";
+    static final String        T_PLACING              = "PLACING";
+    static final String        T_PLI                  = "PLI";
+    static final String        T_PRECEDING            = "PRECEDING";
+    static final String        T_PRESERVE             = "PRESERVE";
+    static final String        T_PRIOR                = "PRIOR";
+    static final String        T_PRIVILEGES           = "PRIVILEGES";
+    public static final String T_PUBLIC               = "PUBLIC";
+    public static final String T_READ                 = "READ";
+    static final String        T_RELATIVE             = "RELATIVE";
+    static final String        T_REPEATABLE           = "REPEATABLE";
+    static final String        T_RESTART              = "RESTART";
+    static final String        T_RETURNED_CARDINALITY = "RETURNED_CARDINALITY";
+    static final String        T_RETURNED_LENGTH      = "RETURNED_LENGTH";
+    static final String T_RETURNED_OCTET_LENGTH = "RETURNED_OCTET_LENGTH";
+    static final String        T_RETURNED_SQLSTATE    = "RETURNED_SQLSTATE";
+    public static final String T_ROLE                 = "ROLE";
+    public static final String T_ROUTINE              = "ROUTINE";
+    static final String        T_ROUTINE_CATALOG      = "ROUTINE_CATALOG";
+    static final String        T_ROUTINE_NAME         = "ROUTINE_NAME";
+    static final String        T_ROUTINE_SCHEMA       = "ROUTINE_SCHEMA";
+    static final String        T_ROW_COUNT            = "ROW_COUNT";
+    public static final String T_SCALE                = "SCALE";
+    public static final String T_SCHEMA               = "SCHEMA";
+    static final String        T_SCHEMA_NAME          = "SCHEMA_NAME";
+    static final String        T_SCOPE_CATALOG        = "SCOPE_CATALOG";
+    static final String        T_SCOPE_NAME           = "SCOPE_NAME";
+    static final String        T_SCOPE_SCHEMA         = "SCOPE_SCHEMA";
+    static final String        T_SECTION              = "SECTION";
+    static final String        T_SECURITY             = "SECURITY";
+    static final String        T_SELF                 = "SELF";
+    public static final String T_SEQUENCE             = "SEQUENCE";
+    public static final String T_SERIALIZABLE         = "SERIALIZABLE";
+    public static final String T_SERVER               = "SERVER";
+    static final String        T_SERVER_NAME          = "SERVER_NAME";
+    public static final String T_SESSION              = "SESSION";
+    static final String        T_SETS                 = "SETS";
+    static final String        T_SIMPLE               = "SIMPLE";
+    public static final String T_SIZE                 = "SIZE";
+    static final String        T_SOURCE               = "SOURCE";
+    static final String        T_SPACE                = "SPACE";
+    static final String        T_SPECIFIC_NAME        = "SPECIFIC_NAME";
+    static final String        T_SQLDATA              = "SQLDATA";       // SQL/JRT
+    static final String        T_STACKED              = "STACKED";
+    static final String        T_STATE                = "STATE";
+    static final String        T_STATEMENT            = "STATEMENT";
+    static final String        T_STRUCTURE            = "STRUCTURE";
+    static final String        T_STYLE                = "STYLE";
+    static final String        T_SUBCLASS_ORIGIN      = "SUBCLASS_ORIGIN";
+    public static final String T_T_FACTOR             = "T";
+    static final String        T_TABLE_NAME           = "TABLE_NAME";
+    static final String        T_TEMPORARY            = "TEMPORARY";
+    static final String        T_TIES                 = "TIES";
+    static final String        T_TOP_LEVEL_COUNT      = "TOP_LEVEL_COUNT";
+    public static final String T_TRANSACTION          = "TRANSACTION";
+    static final String        T_TRANSACT_COMMITTED = "TRANSACTIONS_COMMITTED";
+    static final String T_TRANSACTION_ROLLED_BACK = "TRANSACTIONS_ROLLED_BACK";
+    static final String        T_TRANSACT_ACTIVE      = "TRANSACTION_ACTIVE";
+    static final String        T_TRANSFORM            = "TRANSFORM";
+    static final String        T_TRANSFORMS           = "TRANSFORMS";
+    static final String        T_TRIGGER_CATALOG      = "TRIGGER_CATALOG";
+    static final String        T_TRIGGER_NAME         = "TRIGGER_NAME";
+    static final String        T_TRIGGER_SCHEMA       = "TRIGGER_SCHEMA";
+    public static final String T_TYPE                 = "TYPE";
+    static final String        T_UNBOUNDED            = "UNBOUNDED";
+    static final String        T_UNCOMMITTED          = "UNCOMMITTED";
+    static final String        T_UNDER                = "UNDER";
+    static final String        T_UNDO                 = "UNDO";
+    static final String        T_UNNAMED              = "UNNAMED";
+    public static final String T_USAGE                = "USAGE";
+    static final String T_USER_DEFINED_TYPE_CATALOG =
+        "USER_DEFINED_TYPE_CATALOG";
+    static final String T_USER_DEFINED_TYPE_CODE = "USER_DEFINED_TYPE_CODE";
+    static final String T_USER_DEFINED_TYPE_NAME = "USER_DEFINED_TYPE_NAME";
+    static final String T_USER_DEFINED_TYPE_SCHEMA =
+        "USER_DEFINED_TYPE_SCHEMA";
+    static final String        T_VIEW    = "VIEW";
+    static final String        T_WORK    = "WORK";
+    public static final String T_WRAPPER = "WRAPPER";
+    public static final String T_WRITE   = "WRITE";
+    public static final String T_ZONE    = "ZONE";
+
+    // other tokens
+    static final String        T_ADD                 = "ADD";
+    static final String        T_ALIAS               = "ALIAS";
+    static final String        T_AGGREGATE           = "AGGREGATE";
+    static final String        T_AUTOCOMMIT          = "AUTOCOMMIT";
+    public static final String T_BACKUP              = "BACKUP";
+    public static final String T_BIT                 = "BIT";
+    static final String        T_BITLENGTH           = "BITLENGTH";
+    public static final String T_CACHE               = "CACHE";
+    static final String        T_CACHED              = "CACHED";
+    static final String        T_CASEWHEN            = "CASEWHEN";
+    static final String        T_CHECKPOINT          = "CHECKPOINT";
+    static final String        T_CLASS               = "CLASS";
+    static final String        T_COMMENT             = "COMMENT";
+    static final String        T_COMPACT             = "COMPACT";
+    public static final String T_COMPRESSED          = "COMPRESSED";
+    public static final String T_CONTROL             = "CONTROL";
+    static final String        T_CURDATE             = "CURDATE";
+    static final String        T_CURTIME             = "CURTIME";
+    public static final String T_DATABASE            = "DATABASE";
+    public static final String T_DEFRAG              = "DEFRAG";
+    public static final String T_DELAY               = "DELAY";
+    static final String        T_EXPLAIN             = "EXPLAIN";
+    public static final String T_EVENT               = "EVENT";
+    static final String        T_FILE                = "FILE";
+    public static final String T_FILES               = "FILES";
+    static final String        T_FOLD                = "FOLD";
+    static final String        T_GENERATED           = "GENERATED";
+    static final String        T_HEADER              = "HEADER";
+    static final String        T_IFNULL              = "IFNULL";
+    static final String        T_IGNORECASE          = "IGNORECASE";
+    static final String        T_IMMEDIATELY         = "IMMEDIATELY";
+    public static final String T_INDEX               = "INDEX";
+    public static final String T_INITIAL             = "INITIAL";
+    public static final String T_INTEGRITY           = "INTEGRITY";
+    static final String        T_ISAUTOCOMMIT        = "ISAUTOCOMMIT";
+    static final String        T_ISREADONLYDATABASE  = "ISREADONLYDATABASE";
+    static final String T_ISREADONLYDATABASEFILES = "ISREADONLYDATABASEFILES";
+    static final String        T_ISREADONLYSESSION   = "ISREADONLYSESSION";
+    static final String        T_LIMIT               = "LIMIT";
+    public static final String T_LOB                 = "LOB";
+    public static final String T_LOCK                = "LOCK";
+    public static final String T_LOCKS               = "LOCKS";
+    static final String        T_MAXROWS             = "MAXROWS";
+    public static final String T_MEMORY              = "MEMORY";
+    public static final String T_MILLIS              = "MILLIS";
+    static final String        T_MINUS_EXCEPT        = "MINUS";
+    public static final String T_MVCC                = "MVCC";
+    public static final String T_MVLOCKS             = "MVLOCKS";
+    public static final String T_NIO                 = "NIO";
+    static final String        T_NOWAIT              = "NOWAIT";
+    static final String        T_NVL                 = "NVL";
+    static final String        T_OCTETLENGTH         = "OCTETLENGTH";
+    static final String        T_OFF                 = "OFF";
+    public static final String T_OTHER               = "OTHER";
+    public static final String T_PASSWORD            = "PASSWORD";
+    static final String        T_PLAN                = "PLAN";
+    static final String        T_PROPERTY            = "PROPERTY";
+    static final String        T_QUEUE               = "QUEUE";
+    static final String        T_READONLY            = "READONLY";
+    static final String        T_REFERENTIAL         = "REFERENTIAL";
+    static final String        T_RENAME              = "RENAME";
+    static final String        T_RESTRICT            = "RESTRICT";
+    static final String        T_SCRIPT              = "SCRIPT";
+    static final String        T_SCRIPTFORMAT        = "SCRIPTFORMAT";
+    static final String        T_BLOCKING            = "BLOCKING";
+    static final String        T_SHUTDOWN            = "SHUTDOWN";
+    static final String        T_SQL_TSI_DAY         = "SQL_TSI_DAY";
+    static final String        T_SQL_TSI_FRAC_SECOND = "SQL_TSI_FRAC_SECOND";
+    static final String        T_SQL_TSI_HOUR        = "SQL_TSI_HOUR";
+    static final String        T_SQL_TSI_MINUTE      = "SQL_TSI_MINUTE";
+    static final String        T_SQL_TSI_MONTH       = "SQL_TSI_MONTH";
+    static final String        T_SQL_TSI_QUARTER     = "SQL_TSI_QUARTER";
+    static final String        T_SQL_TSI_SECOND      = "SQL_TSI_SECOND";
+    static final String        T_SQL_TSI_WEEK        = "SQL_TSI_WEEK";
+    static final String        T_SQL_TSI_YEAR        = "SQL_TSI_YEAR";
+    static final String        T_SQL_BIGINT          = "SQL_BIGINT";
+    static final String        T_SQL_BINARY          = "SQL_BINARY";
+    static final String        T_SQL_BIT             = "SQL_BIT";
+    static final String        T_SQL_BLOB            = "SQL_BLOB";
+    static final String        T_SQL_BOOLEAN         = "SQL_BOOLEAN";
+    static final String        T_SQL_CHAR            = "SQL_CHAR";
+    static final String        T_SQL_CLOB            = "SQL_CLOB";
+    static final String        T_SQL_DATE            = "SQL_DATE";
+    static final String        T_SQL_DECIMAL         = "SQL_DECIMAL";
+    static final String        T_SQL_DATALINK        = "SQL_DATALINK";
+    static final String        T_SQL_DOUBLE          = "SQL_DOUBLE";
+    static final String        T_SQL_FLOAT           = "SQL_FLOAT";
+    static final String        T_SQL_INTEGER         = "SQL_INTEGER";
+    static final String        T_SQL_LONGVARBINARY   = "SQL_LONGVARBINARY";
+    static final String        T_SQL_LONGNVARCHAR    = "SQL_LONGNVARCHAR";
+    static final String        T_SQL_LONGVARCHAR     = "SQL_LONGVARCHAR";
+    static final String        T_SQL_NCHAR           = "SQL_NCHAR";
+    static final String        T_SQL_NCLOB           = "SQL_NCLOB";
+    static final String        T_SQL_NUMERIC         = "SQL_NUMERIC";
+    static final String        T_SQL_NVARCHAR        = "SQL_NVARCHAR";
+    static final String        T_SQL_REAL            = "SQL_REAL";
+    static final String        T_SQL_ROWID           = "SQL_ROWID";
+    static final String        T_SQL_SQLXML          = "SQL_SQLXML";
+    static final String        T_SQL_SMALLINT        = "SQL_SMALLINT";
+    static final String        T_SQL_TIME            = "SQL_TIME";
+    static final String        T_SQL_TIMESTAMP       = "SQL_TIMESTAMP";
+    static final String        T_SQL_TINYINT         = "SQL_TINYINT";
+    static final String        T_SQL_VARBINARY       = "SQL_VARBINARY";
+    static final String        T_SQL_VARCHAR         = "SQL_VARCHAR";
+    public static final String T_TEMP                = "TEMP";
+    public static final String T_TEXT                = "TEXT";
+    static final String        T_TIMESTAMPADD        = "TIMESTAMPADD";
+    static final String        T_TIMESTAMPDIFF       = "TIMESTAMPDIFF";
+    public static final String T_TINYINT             = "TINYINT";
+    static final String        T_TO_CHAR             = "TO_CHAR";
+    static final String        T_TODAY               = "TODAY";
+    static final String        T_TOP                 = "TOP";
+    public static final String T_VARCHAR_IGNORECASE  = "VARCHAR_IGNORECASE";
+    static final String        T_WRITE_DELAY         = "WRITE_DELAY";
+    public static final String T_YES                 = "YES";
+
+    //
+    public static final String T_DAY_NAME     = "DAY_NAME";
+    public static final String T_MONTH_NAME   = "MONTH_NAME";
+    public static final String T_QUARTER      = "QUARTER";
+    public static final String T_DAY_OF_WEEK  = "DAY_OF_WEEK";
+    public static final String T_DAY_OF_MONTH = "DAY_OF_MONTH";
+    public static final String T_DAY_OF_YEAR  = "DAY_OF_YEAR";
+    public static final String T_WEEK_OF_YEAR = "WEEK_OF_YEAR";
+    static final String        T_DAYNAME      = "DAYNAME";
+    static final String        T_MONTHNAME    = "MONTHNAME";
+    static final String        T_DAYOFMONTH   = "DAYOFMONTH";
+    static final String        T_DAYOFWEEK    = "DAYOFWEEK";
+    static final String        T_DAYOFYEAR    = "DAYOFYEAR";
+    static final String        T_WEEK         = "WEEK";
+
+    //
+    static final String        T_ACOS             = "ACOS";
+    static final String        T_ASCII            = "ASCII";
+    static final String        T_ASIN             = "ASIN";
+    static final String        T_ATAN             = "ATAN";
+    static final String        T_ATAN2            = "ATAN2";
+    static final String        T_BITAND           = "BITAND";
+    static final String        T_BITOR            = "BITOR";
+    static final String        T_BITXOR           = "BITXOR";
+    static final String        T_CONCAT_WORD      = "CONCAT";
+    static final String        T_COS              = "COS";
+    static final String        T_COT              = "COT";
+    static final String        T_CRYPT_KEY        = "CRYPT_KEY";
+    static final String        T_DATEADD          = "DATEADD";
+    static final String        T_DATEDIFF         = "DATEDIFF";
+    static final String        T_DECODE           = "DECODE";
+    static final String        T_DEGREES          = "DEGREES";
+    static final String        T_DIFFERENCE       = "DIFFERENCE";
+    static final String        T_DMOD             = "DMOD";
+    public static final String T_GC               = "GC";
+    static final String        T_GREATEST         = "GREATEST";
+    static final String        T_HEXTORAW         = "HEXTORAW";
+    static final String        T_LCASE            = "LCASE";
+    static final String        T_LEAST            = "LEAST";
+    static final String        T_LOCATE           = "LOCATE";
+    public static final String T_LOG              = "LOG";
+    static final String        T_LOG10            = "LOG10";
+    static final String        T_LTRIM            = "LTRIM";
+    static final String        T_NOW              = "NOW";
+    static final String        T_PI               = "PI";
+    static final String        T_RADIANS          = "RADIANS";
+    static final String        T_RAND             = "RAND";
+    static final String        T_RAWTOHEX         = "RAWTOHEX";
+    public static final String T_REGEXP_MATCHES   = "REGEXP_MATCHES";
+    static final String        T_REPLACE          = "REPLACE";
+    static final String        T_REVERSE          = "REVERSE";
+    static final String        T_ROUND            = "ROUND";
+    static final String        T_ROUNDMAGIC       = "ROUNDMAGIC";
+    static final String        T_RTRIM            = "RTRIM";
+    public static final String T_SECONDS_MIDNIGHT = "SECONDS_SINCE_MIDNIGHT";
+    static final String        T_SIGN             = "SIGN";
+    static final String        T_SIN              = "SIN";
+    static final String        T_SOUNDEX          = "SOUNDEX";
+    static final String        T_SUBSTR           = "SUBSTR";
+    static final String        T_SYSDATE          = "SYSDATE";
+    static final String        T_TAN              = "TAN";
+    static final String        T_UCASE            = "UCASE";
+
+    //
+    static final String T_ISOLATION_LEVEL         = "ISOLATION_LEVEL";
+    static final String T_SESSION_ISOLATION_LEVEL = "SESSION_ISOLATION_LEVEL";
+    static final String T_DATABASE_ISOLATION_LEVEL =
+        "DATABASE_ISOLATION_LEVEL";
+    static final String T_TRANSACTION_CONTROL = "TRANSACTION_CONTROL";
+    static final String T_TIMEZONE            = "TIMEZONE";
+    static final String T_SESSION_TIMEZONE    = "SESSION_TIMEZONE";
+    static final String T_DATABASE_TIMEZONE   = "DATABASE_TIMEZONE";
+    static final String T_DATABASE_VERSION    = "DATABASE_VERSION";
+
+    //
+    //SQL 200n Standard reserved keywords - full set
+    public static final int ABS                              = 1;
+    public static final int ALL                              = 2;
+    public static final int ALLOCATE                         = 3;
+    public static final int ALTER                            = 4;
+    public static final int AND                              = 5;
+    public static final int ANY                              = 6;
+    public static final int ARE                              = 7;
+    public static final int ARRAY                            = 8;
+    public static final int AS                               = 9;
+    public static final int ASENSITIVE                       = 10;
+    public static final int ASYMMETRIC                       = 11;
+    public static final int AT                               = 12;
+    public static final int ATOMIC                           = 13;
+    public static final int AUTHORIZATION                    = 14;
+    public static final int AVG                              = 15;
+    public static final int BEGIN                            = 16;
+    public static final int BETWEEN                          = 17;
+    public static final int BIGINT                           = 18;
+    public static final int BINARY                           = 19;
+    public static final int BLOB                             = 20;
+    public static final int BOOLEAN                          = 21;
+    public static final int BOTH                             = 22;
+    public static final int BY                               = 23;
+    public static final int CALL                             = 24;
+    public static final int CALLED                           = 25;
+    public static final int CARDINALITY                      = 26;
+    public static final int CASCADED                         = 27;
+    public static final int CASE                             = 28;
+    public static final int CAST                             = 29;
+    public static final int CEIL                             = 30;
+    public static final int CEILING                          = 31;
+    public static final int CHAR                             = 32;
+    public static final int CHAR_LENGTH                      = 33;
+    public static final int CHARACTER                        = 34;
+    public static final int CHARACTER_LENGTH                 = 35;
+    public static final int CHECK                            = 36;
+    public static final int CLOB                             = 37;
+    public static final int CLOSE                            = 38;
+    public static final int COALESCE                         = 39;
+    public static final int COLLATE                          = 40;
+    public static final int COLLECT                          = 41;
+    public static final int COLUMN                           = 42;
+    public static final int COMMIT                           = 43;
+    public static final int COMPARABLE                       = 44;
+    public static final int CONDITION                        = 45;
+    public static final int CONNECT                          = 46;
+    public static final int CONSTRAINT                       = 47;
+    public static final int CONVERT                          = 48;
+    public static final int CORR                             = 49;
+    public static final int CORRESPONDING                    = 50;
+    public static final int COUNT                            = 51;
+    public static final int COVAR_POP                        = 52;
+    public static final int COVAR_SAMP                       = 53;
+    public static final int CREATE                           = 54;
+    public static final int CROSS                            = 55;
+    public static final int CUBE                             = 56;
+    public static final int CUME_DIST                        = 57;
+    public static final int CURRENT                          = 58;
+    public static final int CURRENT_CATALOG                  = 59;
+    public static final int CURRENT_DATE                     = 60;
+    public static final int CURRENT_DEFAULT_TRANSFORM_GROUP  = 61;
+    public static final int CURRENT_PATH                     = 62;
+    public static final int CURRENT_ROLE                     = 63;
+    public static final int CURRENT_SCHEMA                   = 64;
+    public static final int CURRENT_TIME                     = 65;
+    public static final int CURRENT_TIMESTAMP                = 66;
+    public static final int CURRENT_TRANSFORM_GROUP_FOR_TYPE = 67;
+    public static final int CURRENT_USER                     = 68;
+    public static final int CURSOR                           = 69;
+    public static final int CYCLE                            = 70;
+    public static final int DATE                             = 71;
+    public static final int DAY                              = 72;
+    public static final int DEALLOCATE                       = 73;
+    public static final int DEC                              = 74;
+    public static final int DECIMAL                          = 75;
+    public static final int DECLARE                          = 76;
+    public static final int DEFAULT                          = 77;
+    public static final int DELETE                           = 78;
+    public static final int DENSE_RANK                       = 79;
+    public static final int DEREF                            = 80;
+    public static final int DESCRIBE                         = 81;
+    public static final int DETERMINISTIC                    = 82;
+    public static final int DISCONNECT                       = 83;
+    public static final int DISTINCT                         = 84;
+    public static final int DO                               = 85;
+    public static final int DOUBLE                           = 86;
+    public static final int DROP                             = 87;
+    public static final int DYNAMIC                          = 88;
+    public static final int EACH                             = 89;
+    public static final int ELEMENT                          = 90;
+    public static final int ELSE                             = 91;
+    public static final int ELSEIF                           = 92;
+    public static final int END                              = 93;
+    public static final int END_EXEC                         = 94;
+    public static final int ESCAPE                           = 95;
+    public static final int EVERY                            = 96;
+    public static final int EXCEPT                           = 97;
+    public static final int EXEC                             = 98;
+    public static final int EXECUTE                          = 99;
+    public static final int EXISTS                           = 100;
+    public static final int EXIT                             = 101;
+    public static final int EXP                              = 102;
+    public static final int EXTERNAL                         = 103;
+    public static final int EXTRACT                          = 104;
+    public static final int FALSE                            = 105;
+    public static final int FETCH                            = 106;
+    public static final int FILTER                           = 107;
+    public static final int FIRST_VALUE                      = 108;
+    public static final int FLOAT                            = 109;
+    public static final int FLOOR                            = 110;
+    public static final int FOR                              = 111;
+    public static final int FOREIGN                          = 112;
+    public static final int FREE                             = 113;
+    public static final int FROM                             = 114;
+    public static final int FULL                             = 115;
+    public static final int FUNCTION                         = 116;
+    public static final int FUSION                           = 117;
+    public static final int GET                              = 118;
+    public static final int GLOBAL                           = 119;
+    public static final int GRANT                            = 120;
+    public static final int GROUP                            = 121;
+    public static final int GROUPING                         = 122;
+    public static final int HANDLER                          = 123;
+    public static final int HAVING                           = 124;
+    public static final int HOLD                             = 125;
+    public static final int HOUR                             = 126;
+    public static final int IDENTITY                         = 127;
+    public static final int IMPORT                           = 128;
+    public static final int IN                               = 129;
+    public static final int INDICATOR                        = 130;
+    public static final int INNER                            = 131;
+    public static final int INOUT                            = 132;
+    public static final int INSENSITIVE                      = 133;
+    public static final int INSERT                           = 134;
+    public static final int INT                              = 135;
+    public static final int INTEGER                          = 136;
+    public static final int INTERSECT                        = 137;
+    public static final int INTERSECTION                     = 138;
+    public static final int INTERVAL                         = 139;
+    public static final int INTO                             = 140;
+    public static final int IS                               = 141;
+    public static final int ITERATE                          = 142;
+    public static final int JOIN                             = 143;
+    public static final int LAG                              = 144;
+    public static final int LANGUAGE                         = 145;
+    public static final int LARGE                            = 146;
+    public static final int LAST_VALUE                       = 147;
+    public static final int LATERAL                          = 148;
+    public static final int LEAD                             = 149;
+    public static final int LEADING                          = 150;
+    public static final int LEAVE                            = 151;
+    public static final int LEFT                             = 152;
+    public static final int LIKE                             = 153;
+    public static final int LIKE_REGEX                       = 154;
+    public static final int LN                               = 155;
+    public static final int LOCAL                            = 156;
+    public static final int LOCALTIME                        = 157;
+    public static final int LOCALTIMESTAMP                   = 158;
+    public static final int LOOP                             = 159;
+    public static final int LOWER                            = 160;
+    public static final int MATCH                            = 161;
+    public static final int MAX                              = 162;
+    public static final int MAX_CARDINALITY                  = 163;
+    public static final int MEMBER                           = 164;
+    public static final int MERGE                            = 165;
+    public static final int METHOD                           = 166;
+    public static final int MIN                              = 167;
+    public static final int MINUTE                           = 168;
+    public static final int MOD                              = 169;
+    public static final int MODIFIES                         = 170;
+    public static final int MODULE                           = 171;
+    public static final int MONTH                            = 172;
+    public static final int MULTISET                         = 173;
+    public static final int NATIONAL                         = 174;
+    public static final int NATURAL                          = 175;
+    public static final int NCHAR                            = 176;
+    public static final int NCLOB                            = 177;
+    public static final int NEW                              = 178;
+    public static final int NO                               = 179;
+    public static final int NONE                             = 180;
+    public static final int NORMALIZE                        = 181;
+    public static final int NOT                              = 182;
+    public static final int NTH_VALUE                        = 183;
+    public static final int NTILE                            = 184;
+    public static final int NULL                             = 185;
+    public static final int NULLIF                           = 186;
+    public static final int NUMERIC                          = 187;
+    public static final int OCCURRENCES_REGEX                = 188;
+    public static final int OCTET_LENGTH                     = 189;
+    public static final int OF                               = 190;
+    public static final int OFFSET                           = 191;
+    public static final int OLD                              = 192;
+    public static final int ON                               = 193;
+    public static final int ONLY                             = 194;
+    public static final int OPEN                             = 195;
+    public static final int OR                               = 196;
+    public static final int ORDER                            = 197;
+    public static final int OUT                              = 198;
+    public static final int OUTER                            = 199;
+    public static final int OVER                             = 200;
+    public static final int OVERLAPS                         = 201;
+    public static final int OVERLAY                          = 202;
+    public static final int PARAMETER                        = 203;
+    public static final int PARTITION                        = 204;
+    public static final int PERCENT_RANK                     = 205;
+    public static final int PERCENTILE_CONT                  = 206;
+    public static final int PERCENTILE_DISC                  = 207;
+    public static final int POSITION                         = 208;
+    public static final int POSITION_REGEX                   = 209;
+    public static final int POWER                            = 210;
+    public static final int PRECISION                        = 211;
+    public static final int PREPARE                          = 212;
+    public static final int PRIMARY                          = 213;
+    public static final int PROCEDURE                        = 214;
+    public static final int RANGE                            = 215;
+    public static final int RANK                             = 216;
+    public static final int READS                            = 217;
+    public static final int REAL                             = 218;
+    public static final int RECURSIVE                        = 219;
+    public static final int REF                              = 220;
+    public static final int REFERENCES                       = 221;
+    public static final int REFERENCING                      = 222;
+    public static final int REGR_AVGX                        = 223;
+    public static final int REGR_AVGY                        = 224;
+    public static final int REGR_COUNT                       = 225;
+    public static final int REGR_INTERCEPT                   = 226;
+    public static final int REGR_R2                          = 227;
+    public static final int REGR_SLOPE                       = 228;
+    public static final int REGR_SXX                         = 229;
+    public static final int REGR_SXY                         = 230;
+    public static final int REGR_SYY                         = 231;
+    public static final int RELEASE                          = 232;
+    public static final int REPEAT                           = 233;
+    public static final int RESIGNAL                         = 234;
+    public static final int RESULT                           = 235;
+    public static final int RETURN                           = 236;
+    public static final int RETURNS                          = 237;
+    public static final int REVOKE                           = 238;
+    public static final int RIGHT                            = 239;
+    public static final int ROLLBACK                         = 240;
+    public static final int ROLLUP                           = 241;
+    public static final int ROW                              = 242;
+    public static final int ROW_NUMBER                       = 243;
+    public static final int ROWS                             = 244;
+    public static final int SAVEPOINT                        = 245;
+    public static final int SCOPE                            = 246;
+    public static final int SCROLL                           = 247;
+    public static final int SEARCH                           = 248;
+    public static final int SECOND                           = 249;
+    public static final int SELECT                           = 250;
+    public static final int SENSITIVE                        = 251;
+    public static final int SESSION_USER                     = 252;
+    public static final int SET                              = 253;
+    public static final int SIGNAL                           = 254;
+    public static final int SIMILAR                          = 255;
+    public static final int SMALLINT                         = 256;
+    public static final int SOME                             = 257;
+    public static final int SPECIFIC                         = 258;
+    public static final int SPECIFICTYPE                     = 259;
+    public static final int SQL                              = 260;
+    public static final int SQLEXCEPTION                     = 261;
+    public static final int SQLSTATE                         = 262;
+    public static final int SQLWARNING                       = 263;
+    public static final int SQRT                             = 264;
+    public static final int STACKED                          = 265;
+    public static final int START                            = 266;
+    public static final int STATIC                           = 267;
+    public static final int STDDEV_POP                       = 268;
+    public static final int STDDEV_SAMP                      = 269;
+    public static final int SUBMULTISET                      = 270;
+    public static final int SUBSTRING                        = 271;
+    public static final int SUBSTRING_REGEX                  = 272;
+    public static final int SUM                              = 273;
+    public static final int SYMMETRIC                        = 274;
+    public static final int SYSTEM                           = 275;
+    public static final int SYSTEM_USER                      = 276;
+    public static final int TABLE                            = 277;
+    public static final int TABLESAMPLE                      = 278;
+    public static final int THEN                             = 279;
+    public static final int TIME                             = 280;
+    public static final int TIMESTAMP                        = 281;
+    public static final int TIMEZONE_HOUR                    = 282;
+    public static final int TIMEZONE_MINUTE                  = 283;
+    public static final int TO                               = 284;
+    public static final int TRAILING                         = 285;
+    public static final int TRANSLATE                        = 286;
+    public static final int TRANSLATE_REGEX                  = 287;
+    public static final int TRANSLATION                      = 288;
+    public static final int TREAT                            = 289;
+    public static final int TRIGGER                          = 290;
+    public static final int TRIM                             = 291;
+    public static final int TRIM_ARRAY                       = 292;
+    public static final int TRUE                             = 293;
+    public static final int TRUNCATE                         = 294;
+    public static final int UESCAPE                          = 295;
+    public static final int UNDO                             = 296;
+    public static final int UNION                            = 297;
+    public static final int UNIQUE                           = 298;
+    public static final int UNKNOWN                          = 299;
+    public static final int UNNEST                           = 300;
+    public static final int UNTIL                            = 301;
+    public static final int UPDATE                           = 302;
+    public static final int UPPER                            = 303;
+    public static final int USER                             = 304;
+    public static final int USING                            = 305;
+    public static final int VALUE                            = 306;
+    public static final int VALUES                           = 307;
+    public static final int VAR_POP                          = 308;
+    public static final int VAR_SAMP                         = 309;
+    public static final int VARBINARY                        = 310;
+    public static final int VARCHAR                          = 311;
+    public static final int VARYING                          = 312;
+    public static final int WHEN                             = 313;
+    public static final int WHENEVER                         = 314;
+    public static final int WHERE                            = 315;
+    public static final int WIDTH_BUCKET                     = 316;
+    public static final int WINDOW                           = 317;
+    public static final int WITH                             = 318;
+    public static final int WITHIN                           = 319;
+    public static final int WITHOUT                          = 320;
+    public static final int WHILE                            = 321;
+    public static final int YEAR                             = 322;
+
+    //
+    //SQL 200n Standard non-reserved keywords - full set
+    public static final int A                           = 330;
+    public static final int ABSOLUTE                    = 331;
+    public static final int ACTION                      = 332;
+    public static final int ADA                         = 333;
+    public static final int ADD                         = 334;
+    public static final int ADMIN                       = 335;
+    public static final int AFTER                       = 336;
+    public static final int ALWAYS                      = 337;
+    public static final int ASC                         = 338;
+    public static final int ASSERTION                   = 339;
+    public static final int ASSIGNMENT                  = 340;
+    public static final int ATTRIBUTE                   = 341;
+    public static final int ATTRIBUTES                  = 342;
+    public static final int BEFORE                      = 343;
+    public static final int BERNOULLI                   = 344;
+    public static final int BREADTH                     = 345;
+    public static final int C                           = 346;
+    public static final int CASCADE                     = 347;
+    public static final int CATALOG                     = 348;
+    public static final int CATALOG_NAME                = 349;
+    public static final int CHAIN                       = 350;
+    public static final int CHARACTER_SET_CATALOG       = 351;
+    public static final int CHARACTER_SET_NAME          = 352;
+    public static final int CHARACTER_SET_SCHEMA        = 353;
+    public static final int CHARACTERISTICS             = 354;
+    public static final int CHARACTERS                  = 355;
+    public static final int CLASS_ORIGIN                = 356;
+    public static final int COBOL                       = 357;
+    public static final int COLLATION                   = 358;
+    public static final int COLLATION_CATALOG           = 359;
+    public static final int COLLATION_NAME              = 360;
+    public static final int COLLATION_SCHEMA            = 361;
+    public static final int COLUMN_NAME                 = 362;
+    public static final int COMMAND_FUNCTION            = 363;
+    public static final int COMMAND_FUNCTION_CODE       = 364;
+    public static final int COMMITTED                   = 365;
+    public static final int CONDITION_IDENTIFIER        = 366;
+    public static final int CONDITION_NUMBER            = 367;
+    public static final int CONNECTION                  = 368;
+    public static final int CONNECTION_NAME             = 369;
+    public static final int CONSTRAINT_CATALOG          = 370;
+    public static final int CONSTRAINT_NAME             = 371;
+    public static final int CONSTRAINT_SCHEMA           = 372;
+    public static final int CONSTRAINTS                 = 373;
+    public static final int CONSTRUCTOR                 = 374;
+    public static final int CONTAINS                    = 375;
+    public static final int CONTINUE                    = 376;
+    public static final int CURSOR_NAME                 = 377;
+    public static final int DATA                        = 378;
+    public static final int DATETIME_INTERVAL_CODE      = 379;
+    public static final int DATETIME_INTERVAL_PRECISION = 380;
+    public static final int DEFAULTS                    = 381;
+    public static final int DEFERRABLE                  = 382;
+    public static final int DEFERRED                    = 383;
+    public static final int DEFINED                     = 384;
+    public static final int DEFINER                     = 385;
+    public static final int DEGREE                      = 386;
+    public static final int DEPTH                       = 387;
+    public static final int DERIVED                     = 388;
+    public static final int DESC                        = 389;
+    public static final int DESCRIPTOR                  = 390;
+    public static final int DIAGNOSTICS                 = 391;
+    public static final int DISPATCH                    = 392;
+    public static final int DOMAIN                      = 393;
+    public static final int DYNAMIC_FUNCTION            = 394;
+    public static final int DYNAMIC_FUNCTION_CODE       = 395;
+    public static final int EQUALS                      = 396;
+    public static final int EXCEPTION                   = 397;
+    public static final int EXCLUDE                     = 398;
+    public static final int EXCLUDING                   = 399;
+    public static final int FINAL                       = 400;
+    public static final int FIRST                       = 401;
+    public static final int FOLLOWING                   = 402;
+    public static final int FORTRAN                     = 403;
+    public static final int FOUND                       = 404;
+    public static final int G                           = 405;
+    public static final int GENERAL                     = 406;
+    public static final int GENERATED                   = 407;
+    public static final int GO                          = 408;
+    public static final int GOTO                        = 409;
+    public static final int GRANTED                     = 410;
+    public static final int HIERARCHY                   = 411;
+    public static final int IF                          = 412;
+    public static final int IGNORE                      = 413;
+    public static final int IMMEDIATE                   = 414;
+    public static final int IMPLEMENTATION              = 415;
+    public static final int INCLUDING                   = 416;
+    public static final int INCREMENT                   = 417;
+    public static final int INITIALLY                   = 418;
+    public static final int INPUT                       = 419;
+    public static final int INSTANCE                    = 420;
+    public static final int INSTANTIABLE                = 421;
+    public static final int INSTEAD                     = 422;
+    public static final int INVOKER                     = 423;
+    public static final int ISOLATION                   = 424;
+    public static final int JAVA                        = 425;
+    public static final int K                           = 426;
+    public static final int KEY                         = 427;
+    public static final int KEY_MEMBER                  = 428;
+    public static final int KEY_TYPE                    = 429;
+    public static final int LAST                        = 430;
+    public static final int LENGTH                      = 431;
+    public static final int LEVEL                       = 432;
+    public static final int LIBRARY                     = 433;
+    public static final int LOCATOR                     = 434;
+    public static final int M                           = 435;
+    public static final int MAP                         = 436;
+    public static final int MATCHED                     = 437;
+    public static final int MAXVALUE                    = 438;
+    public static final int MESSAGE_LENGTH              = 439;
+    public static final int MESSAGE_OCTET_LENGTH        = 440;
+    public static final int MESSAGE_TEXT                = 441;
+    public static final int MINVALUE                    = 442;
+    public static final int MORE                        = 443;
+    public static final int MUMPS                       = 444;
+    public static final int NAME                        = 445;
+    public static final int NAMES                       = 446;
+    public static final int NESTING                     = 447;
+    public static final int NEXT                        = 448;
+    public static final int NORMALIZED                  = 449;
+    public static final int NULLABLE                    = 450;
+    public static final int NULLS                       = 451;
+    public static final int NUMBER                      = 452;
+    public static final int OBJECT                      = 453;
+    public static final int OCTETS                      = 454;
+    public static final int OPTION                      = 455;
+    public static final int OPTIONS                     = 456;
+    public static final int ORDERING                    = 457;
+    public static final int ORDINALITY                  = 458;
+    public static final int OTHERS                      = 459;
+    public static final int OUTPUT                      = 460;
+    public static final int OVERRIDING                  = 461;
+    public static final int P                           = 462;
+    public static final int PAD                         = 463;
+    public static final int PARAMETER_MODE              = 464;
+    public static final int PARAMETER_NAME              = 465;
+    public static final int PARAMETER_ORDINAL_POSITION  = 466;
+    public static final int PARAMETER_SPECIFIC_CATALOG  = 467;
+    public static final int PARAMETER_SPECIFIC_NAME     = 468;
+    public static final int PARAMETER_SPECIFIC_SCHEMA   = 469;
+    public static final int PARTIAL                     = 470;
+    public static final int PASCAL                      = 471;
+    public static final int PATH                        = 472;
+    public static final int PLACING                     = 473;
+    public static final int PLI                         = 474;
+    public static final int PRECEDING                   = 475;
+    public static final int PRESERVE                    = 476;
+    public static final int PRIOR                       = 477;
+    public static final int PRIVILEGES                  = 478;
+    public static final int PUBLIC                      = 479;
+    public static final int READ                        = 480;
+    public static final int RELATIVE                    = 481;
+    public static final int REPEATABLE                  = 482;
+    public static final int RESPECT                     = 483;
+    public static final int RESTART                     = 484;
+    public static final int RESTRICT                    = 485;
+    public static final int RETURNED_CARDINALITY        = 486;
+    public static final int RETURNED_LENGTH             = 487;
+    public static final int RETURNED_OCTET_LENGTH       = 488;
+    public static final int RETURNED_SQLSTATE           = 489;
+    public static final int ROLE                        = 490;
+    public static final int ROUTINE                     = 491;
+    public static final int ROUTINE_CATALOG             = 492;
+    public static final int ROUTINE_NAME                = 493;
+    public static final int ROUTINE_SCHEMA              = 494;
+    public static final int ROW_COUNT                   = 495;
+    public static final int SCALE                       = 496;
+    public static final int SCHEMA                      = 497;
+    public static final int SCHEMA_NAME                 = 498;
+    public static final int SCOPE_CATALOG               = 499;
+    public static final int SCOPE_NAME                  = 500;
+    public static final int SCOPE_SCHEMA                = 501;
+    public static final int SECTION                     = 502;
+    public static final int SECURITY                    = 503;
+    public static final int SELF                        = 504;
+    public static final int SEQUENCE                    = 505;
+    public static final int SERIALIZABLE                = 506;
+    public static final int SERVER_NAME                 = 507;
+    public static final int SESSION                     = 508;
+    public static final int SERVER                      = 509;
+    public static final int SETS                        = 510;
+    public static final int SIMPLE                      = 511;
+    public static final int SIZE                        = 512;
+    public static final int SOURCE                      = 513;
+    public static final int SPACE                       = 514;
+    public static final int SPECIFIC_NAME               = 515;
+    public static final int STATE                       = 516;
+    public static final int STATEMENT                   = 517;
+    public static final int STRUCTURE                   = 518;
+    public static final int STYLE                       = 519;
+    public static final int SUBCLASS_ORIGIN             = 520;
+    public static final int T                           = 521;
+    public static final int TABLE_NAME                  = 522;
+    public static final int TEMPORARY                   = 523;
+    public static final int TIES                        = 524;
+    public static final int TOP_LEVEL_COUNT             = 525;
+    public static final int TRANSACTION                 = 526;
+    public static final int TRANSACTION_ACTIVE          = 527;
+    public static final int TRANSACTIONS_COMMITTED      = 528;
+    public static final int TRANSACTIONS_ROLLED_BACK    = 529;
+    public static final int TRANSFORM                   = 530;
+    public static final int TRANSFORMS                  = 531;
+    public static final int TRIGGER_CATALOG             = 532;
+    public static final int TRIGGER_NAME                = 533;
+    public static final int TRIGGER_SCHEMA              = 534;
+    public static final int TYPE                        = 535;
+    public static final int UNBOUNDED                   = 536;
+    public static final int UNCOMMITTED                 = 537;
+    public static final int UNDER                       = 538;
+    public static final int UNNAMED                     = 539;
+    public static final int USAGE                       = 540;
+    public static final int USER_DEFINED_TYPE_CATALOG   = 541;
+    public static final int USER_DEFINED_TYPE_CODE      = 542;
+    public static final int USER_DEFINED_TYPE_NAME      = 543;
+    public static final int USER_DEFINED_TYPE_SCHEMA    = 544;
+    public static final int VIEW                        = 545;
+    public static final int WORK                        = 546;
+    public static final int WRITE                       = 547;
+    public static final int WRAPPER                     = 548;
+    public static final int ZONE                        = 549;
+
+    // other token values used as switch cases
+    static final int ALIAS        = 551;
+    static final int AGGREGATE    = 552;
+    static final int AUTOCOMMIT   = 553;
+    static final int BACKUP       = 554;
+    static final int BIT          = 555;
+    static final int BLOCKING     = 556;
+    static final int CACHE        = 557;
+    static final int CACHED       = 558;
+    static final int CASEWHEN     = 559;
+    static final int CHECKPOINT   = 560;
+    static final int CLASS        = 561;
+    static final int COMMENT      = 562;
+    static final int COMPACT      = 563;
+    static final int COMPRESSED   = 564;
+    static final int CONTROL      = 565;
+    static final int DATABASE     = 566;
+    static final int DEFRAG       = 567;
+    static final int DELAY        = 568;
+    static final int EVENT        = 569;
+    static final int EXPLAIN      = 570;
+    static final int FILE         = 571;
+    static final int FILES        = 572;
+    static final int GC           = 573;
+    static final int HEADER       = 574;
+    static final int IGNORECASE   = 575;
+    static final int IMMEDIATELY  = 576;
+    static final int INTEGRITY    = 577;
+    static final int INDEX        = 578;
+    static final int INITIAL      = 579;
+    static final int LIMIT        = 580;
+    static final int LOCK         = 581;
+    static final int LOCKS        = 582;
+    static final int MAXROWS      = 583;
+    static final int MEMORY       = 584;
+    static final int MILLIS       = 585;
+    static final int MINUS_EXCEPT = 586;
+    static final int OFF          = 587;
+    static final int PASSWORD     = 588;
+    static final int PLAN         = 589;
+    static final int PROPERTY     = 590;
+    static final int READONLY     = 591;
+    static final int REFERENTIAL  = 592;
+    static final int RENAME       = 593;
+    static final int SCRIPT       = 594;
+    static final int SCRIPTFORMAT = 595;
+    static final int SHUTDOWN     = 596;
+    static final int TEMP         = 597;
+    static final int TEXT         = 598;
+    static final int WRITE_DELAY  = 599;
+
+    //
+    static final int        ACOS                    = 601;
+    static final int        ASCII                   = 602;
+    static final int        ASIN                    = 603;
+    static final int        ATAN                    = 604;
+    static final int        ATAN2                   = 605;
+    static final int        BIT_LENGTH              = 606;
+    static final int        BITAND                  = 607;
+    static final int        BITLENGTH               = 608;
+    static final int        BITOR                   = 609;
+    static final int        BITXOR                  = 610;
+    static final int        CONCAT_WORD             = 611;
+    static final int        COS                     = 612;
+    static final int        COT                     = 613;
+    static final int        CRYPT_KEY               = 614;
+    static final int        CURDATE                 = 615;
+    static final int        CURTIME                 = 616;
+    static final int        DATEADD                 = 617;
+    static final int        DATEDIFF                = 618;
+    public static final int DAY_NAME                = 619;
+    public static final int DAY_OF_MONTH            = 620;
+    public static final int DAY_OF_WEEK             = 621;
+    public static final int DAY_OF_YEAR             = 622;
+    static final int        DAYNAME                 = 623;
+    static final int        DAYOFMONTH              = 624;
+    static final int        DAYOFWEEK               = 625;
+    static final int        DAYOFYEAR               = 626;
+    static final int        DECODE                  = 627;
+    static final int        DEGREES                 = 628;
+    static final int        DIFFERENCE              = 629;
+    static final int        DMOD                    = 630;
+    static final int        HEXTORAW                = 631;
+    static final int        IFNULL                  = 632;
+    static final int        ISAUTOCOMMIT            = 633;
+    static final int        ISREADONLYDATABASE      = 634;
+    static final int        ISREADONLYDATABASEFILES = 635;
+    static final int        ISREADONLYSESSION       = 636;
+    static final int        LCASE                   = 637;
+    static final int        LEAST                   = 638;
+    static final int        LOCATE                  = 639;
+    static final int        LOB                     = 640;
+    static final int        LOG                     = 641;
+    static final int        LOG10                   = 642;
+    static final int        LTRIM                   = 643;
+    static final int        GREATEST                = 644;
+    public static final int MONTH_NAME              = 645;
+    static final int        MONTHNAME               = 646;
+    static final int        MVCC                    = 647;
+    static final int        MVLOCKS                 = 648;
+    static final int        NIO                     = 649;
+    static final int        NOW                     = 650;
+    static final int        OCTETLENGTH             = 651;
+    static final int        PI                      = 652;
+    public static final int QUARTER                 = 653;
+    static final int        RADIANS                 = 654;
+    static final int        RAND                    = 655;
+    static final int        RAWTOHEX                = 656;
+    static final int        REGEXP_MATCHES          = 657;
+    static final int        REPLACE                 = 658;
+    static final int        REVERSE                 = 659;
+    static final int        ROUND                   = 660;
+    static final int        ROUNDMAGIC              = 661;
+    static final int        RTRIM                   = 662;
+    public static final int SECONDS_MIDNIGHT        = 663;
+    static final int        SIGN                    = 664;
+    static final int        SIN                     = 665;
+    static final int        SOUNDEX                 = 666;
+    static final int        SPACE_WORD              = 667;
+    static final int        SUBSTR                  = 668;
+    static final int        SYSDATE                 = 669;
+    static final int        TAN                     = 670;
+    static final int        TIMESTAMPADD            = 671;
+    static final int        TIMESTAMPDIFF           = 672;
+    static final int        TO_CHAR                 = 673;
+    static final int        TODAY                   = 674;
+    static final int        TOP                     = 675;
+    static final int        UCASE                   = 676;
+    static final int        WEEK                    = 677;
+    public static final int WEEK_OF_YEAR            = 678;
+
+    //
+    static final int ISOLATION_LEVEL          = 681;
+    static final int SESSION_ISOLATION_LEVEL  = 682;
+    static final int DATABASE_ISOLATION_LEVEL = 683;
+    static final int TRANSACTION_CONTROL      = 684;
+    static final int TIMEZONE                 = 685;
+    static final int SESSION_TIMEZONE         = 686;
+    static final int DATABASE_TIMEZONE        = 687;
+    static final int DATABASE_VERSION         = 688;
+
+    //
+    static final int        ASTERISK         = 771;
+    static final int        CLOSEBRACKET     = 772;
+    static final int        COLON            = 773;
+    static final int        COMMA            = 774;
+    static final int        CONCAT           = 775;
+    static final int        DIVIDE           = 776;
+    static final int        DOUBLE_COLON_OP  = 777;
+    static final int        DOUBLE_PERIOD_OP = 778;
+    static final int        GREATER          = 779;
+    static final int        GREATER_EQUALS   = 780;
+    static final int        LEFTBRACKET      = 781;
+    static final int        LESS             = 782;
+    static final int        LESS_EQUALS      = 783;
+    public static final int MINUS            = 784;
+    static final int        NOT_EQUALS       = 785;
+    static final int        OPENBRACKET      = 786;
+    static final int        PLUS             = 787;
+    static final int        QUESTION         = 788;
+    static final int        RIGHT_ARROW_OP   = 789;
+    static final int        RIGHTBRACKET     = 790;
+    static final int        SEMICOLON        = 791;
+
+    //
+    static final int SQL_BIGINT        = 801;
+    static final int SQL_BINARY        = 802;
+    static final int SQL_BIT           = 803;
+    static final int SQL_BLOB          = 804;
+    static final int SQL_BOOLEAN       = 805;
+    static final int SQL_CHAR          = 806;
+    static final int SQL_CLOB          = 807;
+    static final int SQL_DATE          = 808;
+    static final int SQL_DECIMAL       = 809;
+    static final int SQL_DATALINK      = 810;
+    static final int SQL_DOUBLE        = 811;
+    static final int SQL_FLOAT         = 812;
+    static final int SQL_INTEGER       = 813;
+    static final int SQL_LONGVARBINARY = 814;
+    static final int SQL_LONGNVARCHAR  = 815;
+    static final int SQL_LONGVARCHAR   = 816;
+    static final int SQL_NCHAR         = 817;
+    static final int SQL_NCLOB         = 818;
+    static final int SQL_NUMERIC       = 819;
+    static final int SQL_NVARCHAR      = 820;
+    static final int SQL_REAL          = 821;
+    static final int SQL_ROWID         = 822;
+    static final int SQL_SQLXML        = 823;
+    static final int SQL_SMALLINT      = 824;
+    static final int SQL_TIME          = 825;
+    static final int SQL_TIMESTAMP     = 826;
+    static final int SQL_TINYINT       = 827;
+    static final int SQL_VARBINARY     = 828;
+    static final int SQL_VARCHAR       = 829;
+
+    //
+    static final int SQL_TSI_FRAC_SECOND = 831;
+    static final int SQL_TSI_SECOND      = 832;
+    static final int SQL_TSI_MINUTE      = 833;
+    static final int SQL_TSI_HOUR        = 834;
+    static final int SQL_TSI_DAY         = 835;
+    static final int SQL_TSI_WEEK        = 836;
+    static final int SQL_TSI_MONTH       = 837;
+    static final int SQL_TSI_QUARTER     = 838;
+    static final int SQL_TSI_YEAR        = 839;
+
+    //
+    static final int X_KEYSET      = 841;
+    static final int X_OPTION      = 842;
+    static final int X_REPEAT      = 843;
+    static final int X_POS_INTEGER = 844;
+
+    //
+    public static final int X_VALUE                    = 845;
+    public static final int X_IDENTIFIER               = 846;
+    public static final int X_DELIMITED_IDENTIFIER     = 847;
+    public static final int X_ENDPARSE                 = 848;
+    public static final int X_STARTPARSE               = 849;
+    public static final int X_REMARK                   = 850;
+    public static final int X_NULL                     = 851;
+    public static final int X_LOB_SIZE                 = 852;
+    public static final int X_MALFORMED_STRING         = 853;
+    public static final int X_MALFORMED_NUMERIC        = 854;
+    public static final int X_MALFORMED_BIT_STRING     = 855;
+    public static final int X_MALFORMED_BINARY_STRING  = 856;
+    public static final int X_MALFORMED_UNICODE_STRING = 857;
+    public static final int X_MALFORMED_COMMENT        = 858;
+    public static final int X_MALFORMED_IDENTIFIER     = 859;
+    public static final int X_MALFORMED_UNICODE_ESCAPE = 860;
+
+    //
+    public static final int X_UNKNOWN_TOKEN = -1;
+    private static final IntValueHashMap reservedKeys =
+        new IntValueHashMap(351);
+
+    static {
+        reservedKeys.put(Tokens.T_ABS, ABS);
+        reservedKeys.put(Tokens.T_AGGREGATE, AGGREGATE);
+        reservedKeys.put(Tokens.T_ALL, ALL);
+        reservedKeys.put(Tokens.T_ALLOCATE, ALLOCATE);
+        reservedKeys.put(Tokens.T_ALTER, ALTER);
+        reservedKeys.put(Tokens.T_AND, AND);
+        reservedKeys.put(Tokens.T_ANY, ANY);
+        reservedKeys.put(Tokens.T_ARE, ARE);
+        reservedKeys.put(Tokens.T_ARRAY, ARRAY);
+        reservedKeys.put(Tokens.T_AS, AS);
+        reservedKeys.put(Tokens.T_ASENSITIVE, ASENSITIVE);
+        reservedKeys.put(Tokens.T_ASYMMETRIC, ASYMMETRIC);
+        reservedKeys.put(Tokens.T_AT, AT);
+        reservedKeys.put(Tokens.T_ATOMIC, ATOMIC);
+        reservedKeys.put(Tokens.T_AUTHORIZATION, AUTHORIZATION);
+        reservedKeys.put(Tokens.T_AVG, AVG);
+        reservedKeys.put(Tokens.T_BEGIN, BEGIN);
+        reservedKeys.put(Tokens.T_BETWEEN, BETWEEN);
+        reservedKeys.put(Tokens.T_BIGINT, BIGINT);
+        reservedKeys.put(Tokens.T_BINARY, BINARY);
+        reservedKeys.put(Tokens.T_BIT_LENGTH, BIT_LENGTH);
+        reservedKeys.put(Tokens.T_BLOB, BLOB);
+        reservedKeys.put(Tokens.T_BOOLEAN, BOOLEAN);
+        reservedKeys.put(Tokens.T_BOTH, BOTH);
+        reservedKeys.put(Tokens.T_BY, BY);
+        reservedKeys.put(Tokens.T_CALL, CALL);
+        reservedKeys.put(Tokens.T_CALLED, CALLED);
+        reservedKeys.put(Tokens.T_CARDINALITY, CARDINALITY);
+        reservedKeys.put(Tokens.T_CASCADED, CASCADED);
+        reservedKeys.put(Tokens.T_CASE, CASE);
+        reservedKeys.put(Tokens.T_CAST, CAST);
+        reservedKeys.put(Tokens.T_CEIL, CEIL);
+        reservedKeys.put(Tokens.T_CEILING, CEILING);
+        reservedKeys.put(Tokens.T_CHAR, CHAR);
+        reservedKeys.put(Tokens.T_CHAR_LENGTH, CHAR_LENGTH);
+        reservedKeys.put(Tokens.T_CHARACTER, CHARACTER);
+        reservedKeys.put(Tokens.T_CHARACTER_LENGTH, CHARACTER_LENGTH);
+        reservedKeys.put(Tokens.T_CHECK, CHECK);
+        reservedKeys.put(Tokens.T_CLOB, CLOB);
+        reservedKeys.put(Tokens.T_CLOSE, CLOSE);
+        reservedKeys.put(Tokens.T_COALESCE, COALESCE);
+        reservedKeys.put(Tokens.T_COLLATE, COLLATE);
+        reservedKeys.put(Tokens.T_COLLECT, COLLECT);
+        reservedKeys.put(Tokens.T_COLUMN, COLUMN);
+        reservedKeys.put(Tokens.T_COMMIT, COMMIT);
+        reservedKeys.put(Tokens.T_COMPARABLE, COMPARABLE);
+        reservedKeys.put(Tokens.T_CONDITION, CONDITION);
+        reservedKeys.put(Tokens.T_CONNECT, CONNECT);
+        reservedKeys.put(Tokens.T_CONSTRAINT, CONSTRAINT);
+        reservedKeys.put(Tokens.T_CONVERT, CONVERT);
+        reservedKeys.put(Tokens.T_CORR, CORR);
+        reservedKeys.put(Tokens.T_CORRESPONDING, CORRESPONDING);
+        reservedKeys.put(Tokens.T_COUNT, COUNT);
+        reservedKeys.put(Tokens.T_COVAR_POP, COVAR_POP);
+        reservedKeys.put(Tokens.T_COVAR_SAMP, COVAR_SAMP);
+        reservedKeys.put(Tokens.T_CREATE, CREATE);
+        reservedKeys.put(Tokens.T_CROSS, CROSS);
+        reservedKeys.put(Tokens.T_CUBE, CUBE);
+        reservedKeys.put(Tokens.T_CUME_DIST, CUME_DIST);
+        reservedKeys.put(Tokens.T_CURRENT, CURRENT);
+        reservedKeys.put(Tokens.T_CURRENT_CATALOG, CURRENT_CATALOG);
+        reservedKeys.put(Tokens.T_CURRENT_DATE, CURRENT_DATE);
+        reservedKeys.put(Tokens.T_CURRENT_DEFAULT_TRANSFORM_GROUP,
+                         CURRENT_DEFAULT_TRANSFORM_GROUP);
+        reservedKeys.put(Tokens.T_CURRENT_PATH, CURRENT_PATH);
+        reservedKeys.put(Tokens.T_CURRENT_ROLE, CURRENT_ROLE);
+        reservedKeys.put(Tokens.T_CURRENT_SCHEMA, CURRENT_SCHEMA);
+        reservedKeys.put(Tokens.T_CURRENT_TIME, CURRENT_TIME);
+        reservedKeys.put(Tokens.T_CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
+        reservedKeys.put(Tokens.T_DO, DO);
+        reservedKeys.put(Tokens.T_CURRENT_TRANSFORM_GROUP_FOR_TYPE,
+                         CURRENT_TRANSFORM_GROUP_FOR_TYPE);
+        reservedKeys.put(Tokens.T_CURRENT_USER, CURRENT_USER);
+        reservedKeys.put(Tokens.T_CURSOR, CURSOR);
+        reservedKeys.put(Tokens.T_CYCLE, CYCLE);
+        reservedKeys.put(Tokens.T_DATE, DATE);
+        reservedKeys.put(Tokens.T_DAY, DAY);
+        reservedKeys.put(Tokens.T_DEALLOCATE, DEALLOCATE);
+        reservedKeys.put(Tokens.T_DEC, DEC);
+        reservedKeys.put(Tokens.T_DECIMAL, DECIMAL);
+        reservedKeys.put(Tokens.T_DECLARE, DECLARE);
+        reservedKeys.put(Tokens.T_DEFAULT, DEFAULT);
+        reservedKeys.put(Tokens.T_DELETE, DELETE);
+        reservedKeys.put(Tokens.T_DENSE_RANK, DENSE_RANK);
+        reservedKeys.put(Tokens.T_DEREF, DEREF);
+        reservedKeys.put(Tokens.T_DESCRIBE, DESCRIBE);
+        reservedKeys.put(Tokens.T_DETERMINISTIC, DETERMINISTIC);
+        reservedKeys.put(Tokens.T_DISCONNECT, DISCONNECT);
+        reservedKeys.put(Tokens.T_DISTINCT, DISTINCT);
+        reservedKeys.put(Tokens.T_DOUBLE, DOUBLE);
+        reservedKeys.put(Tokens.T_DROP, DROP);
+        reservedKeys.put(Tokens.T_DYNAMIC, DYNAMIC);
+        reservedKeys.put(Tokens.T_EACH, EACH);
+        reservedKeys.put(Tokens.T_ELEMENT, ELEMENT);
+        reservedKeys.put(Tokens.T_ELSE, ELSE);
+        reservedKeys.put(Tokens.T_ELSEIF, ELSEIF);
+        reservedKeys.put(Tokens.T_END, END);
+        reservedKeys.put(Tokens.T_END_EXEC, END_EXEC);
+        reservedKeys.put(Tokens.T_ESCAPE, ESCAPE);
+        reservedKeys.put(Tokens.T_EVERY, EVERY);
+        reservedKeys.put(Tokens.T_EXCEPT, EXCEPT);
+        reservedKeys.put(Tokens.T_EXEC, EXEC);
+        reservedKeys.put(Tokens.T_EXECUTE, EXECUTE);
+        reservedKeys.put(Tokens.T_EXISTS, EXISTS);
+        reservedKeys.put(Tokens.T_EXIT, EXIT);
+        reservedKeys.put(Tokens.T_EXP, EXP);
+        reservedKeys.put(Tokens.T_EXTERNAL, EXTERNAL);
+        reservedKeys.put(Tokens.T_EXTRACT, EXTRACT);
+        reservedKeys.put(Tokens.T_FALSE, FALSE);
+        reservedKeys.put(Tokens.T_FETCH, FETCH);
+        reservedKeys.put(Tokens.T_FILTER, FILTER);
+        reservedKeys.put(Tokens.T_FIRST_VALUE, FIRST_VALUE);
+        reservedKeys.put(Tokens.T_FLOAT, FLOAT);
+        reservedKeys.put(Tokens.T_FLOOR, FLOOR);
+        reservedKeys.put(Tokens.T_FOR, FOR);
+        reservedKeys.put(Tokens.T_FOREIGN, FOREIGN);
+        reservedKeys.put(Tokens.T_FREE, FREE);
+        reservedKeys.put(Tokens.T_FROM, FROM);
+        reservedKeys.put(Tokens.T_FULL, FULL);
+        reservedKeys.put(Tokens.T_FUNCTION, FUNCTION);
+        reservedKeys.put(Tokens.T_FUSION, FUSION);
+        reservedKeys.put(Tokens.T_GET, GET);
+        reservedKeys.put(Tokens.T_GLOBAL, GLOBAL);
+        reservedKeys.put(Tokens.T_GRANT, GRANT);
+        reservedKeys.put(Tokens.T_GROUP, GROUP);
+        reservedKeys.put(Tokens.T_GROUPING, GROUPING);
+        reservedKeys.put(Tokens.T_HANDLER, HANDLER);
+        reservedKeys.put(Tokens.T_HAVING, HAVING);
+        reservedKeys.put(Tokens.T_HOLD, HOLD);
+        reservedKeys.put(Tokens.T_HOUR, HOUR);
+        reservedKeys.put(Tokens.T_IDENTITY, IDENTITY);
+        reservedKeys.put(Tokens.T_IF, IF);
+        reservedKeys.put(Tokens.T_IMPORT, IMPORT);
+        reservedKeys.put(Tokens.T_IN, IN);
+        reservedKeys.put(Tokens.T_INDICATOR, INDICATOR);
+        reservedKeys.put(Tokens.T_INNER, INNER);
+        reservedKeys.put(Tokens.T_INOUT, INOUT);
+        reservedKeys.put(Tokens.T_INSENSITIVE, INSENSITIVE);
+        reservedKeys.put(Tokens.T_INSERT, INSERT);
+        reservedKeys.put(Tokens.T_INT, INT);
+        reservedKeys.put(Tokens.T_INTEGER, INTEGER);
+        reservedKeys.put(Tokens.T_INTERSECT, INTERSECT);
+        reservedKeys.put(Tokens.T_INTERSECTION, INTERSECTION);
+        reservedKeys.put(Tokens.T_INTERVAL, INTERVAL);
+        reservedKeys.put(Tokens.T_INTO, INTO);
+        reservedKeys.put(Tokens.T_IS, IS);
+        reservedKeys.put(Tokens.T_ITERATE, ITERATE);
+        reservedKeys.put(Tokens.T_JOIN, JOIN);
+        reservedKeys.put(Tokens.T_LAG, LAG);
+        reservedKeys.put(Tokens.T_LANGUAGE, LANGUAGE);
+        reservedKeys.put(Tokens.T_LARGE, LARGE);
+        reservedKeys.put(Tokens.T_LAST_VALUE, LAST_VALUE);
+        reservedKeys.put(Tokens.T_LATERAL, LATERAL);
+        reservedKeys.put(Tokens.T_LEAD, LEAD);
+        reservedKeys.put(Tokens.T_LEADING, LEADING);
+        reservedKeys.put(Tokens.T_LEAVE, LEAVE);
+        reservedKeys.put(Tokens.T_LEFT, LEFT);
+        reservedKeys.put(Tokens.T_LIKE, LIKE);
+        reservedKeys.put(Tokens.T_LIKE_REGX, LIKE_REGEX);
+        reservedKeys.put(Tokens.T_LN, LN);
+        reservedKeys.put(Tokens.T_LOCAL, LOCAL);
+        reservedKeys.put(Tokens.T_LOCALTIME, LOCALTIME);
+        reservedKeys.put(Tokens.T_LOCALTIMESTAMP, LOCALTIMESTAMP);
+        reservedKeys.put(Tokens.T_LOOP, LOOP);
+        reservedKeys.put(Tokens.T_LOWER, LOWER);
+        reservedKeys.put(Tokens.T_MATCH, MATCH);
+        reservedKeys.put(Tokens.T_MAX, MAX);
+        reservedKeys.put(Tokens.T_MAX_CARDINALITY, MAX_CARDINALITY);
+        reservedKeys.put(Tokens.T_MEMBER, MEMBER);
+        reservedKeys.put(Tokens.T_MERGE, MERGE);
+        reservedKeys.put(Tokens.T_METHOD, METHOD);
+        reservedKeys.put(Tokens.T_MIN, MIN);
+        reservedKeys.put(Tokens.T_MINUTE, MINUTE);
+        reservedKeys.put(Tokens.T_MOD, MOD);
+        reservedKeys.put(Tokens.T_MODIFIES, MODIFIES);
+        reservedKeys.put(Tokens.T_MODULE, MODULE);
+        reservedKeys.put(Tokens.T_MONTH, MONTH);
+        reservedKeys.put(Tokens.T_MULTISET, MULTISET);
+        reservedKeys.put(Tokens.T_NATIONAL, NATIONAL);
+        reservedKeys.put(Tokens.T_NATURAL, NATURAL);
+        reservedKeys.put(Tokens.T_NCHAR, NCHAR);
+        reservedKeys.put(Tokens.T_NCLOB, NCLOB);
+        reservedKeys.put(Tokens.T_NEW, NEW);
+        reservedKeys.put(Tokens.T_NO, NO);
+        reservedKeys.put(Tokens.T_NONE, NONE);
+        reservedKeys.put(Tokens.T_NORMALIZE, NORMALIZE);
+        reservedKeys.put(Tokens.T_NOT, NOT);
+        reservedKeys.put(Tokens.T_NTH_VALUE, NTH_VALUE);
+        reservedKeys.put(Tokens.T_NTILE, NTILE);
+        reservedKeys.put(Tokens.T_NULL, NULL);
+        reservedKeys.put(Tokens.T_NULLIF, NULLIF);
+        reservedKeys.put(Tokens.T_NUMERIC, NUMERIC);
+        reservedKeys.put(Tokens.T_OCCURRENCES_REGEX, OCCURRENCES_REGEX);
+        reservedKeys.put(Tokens.T_OCTET_LENGTH, OCTET_LENGTH);
+        reservedKeys.put(Tokens.T_OF, OF);
+        reservedKeys.put(Tokens.T_OFFSET, OFFSET);
+        reservedKeys.put(Tokens.T_OLD, OLD);
+        reservedKeys.put(Tokens.T_ON, ON);
+        reservedKeys.put(Tokens.T_ONLY, ONLY);
+        reservedKeys.put(Tokens.T_OPEN, OPEN);
+        reservedKeys.put(Tokens.T_OR, OR);
+        reservedKeys.put(Tokens.T_ORDER, ORDER);
+        reservedKeys.put(Tokens.T_OUT, OUT);
+        reservedKeys.put(Tokens.T_OUTER, OUTER);
+        reservedKeys.put(Tokens.T_OVER, OVER);
+        reservedKeys.put(Tokens.T_OVERLAPS, OVERLAPS);
+        reservedKeys.put(Tokens.T_OVERLAY, OVERLAY);
+        reservedKeys.put(Tokens.T_PARAMETER, PARAMETER);
+        reservedKeys.put(Tokens.T_PARTITION, PARTITION);
+        reservedKeys.put(Tokens.T_PERCENT_RANK, PERCENT_RANK);
+        reservedKeys.put(Tokens.T_PERCENTILE_CONT, PERCENTILE_CONT);
+        reservedKeys.put(Tokens.T_PERCENTILE_DISC, PERCENTILE_DISC);
+        reservedKeys.put(Tokens.T_POSITION, POSITION);
+        reservedKeys.put(Tokens.T_POSITION_REGEX, POSITION_REGEX);
+        reservedKeys.put(Tokens.T_POWER, POWER);
+        reservedKeys.put(Tokens.T_PRECISION, PRECISION);
+        reservedKeys.put(Tokens.T_PREPARE, PREPARE);
+        reservedKeys.put(Tokens.T_PRIMARY, PRIMARY);
+        reservedKeys.put(Tokens.T_PROCEDURE, PROCEDURE);
+        reservedKeys.put(Tokens.T_RANGE, RANGE);
+        reservedKeys.put(Tokens.T_RANK, RANK);
+        reservedKeys.put(Tokens.T_READS, READS);
+        reservedKeys.put(Tokens.T_REAL, REAL);
+        reservedKeys.put(Tokens.T_RECURSIVE, RECURSIVE);
+        reservedKeys.put(Tokens.T_REF, REF);
+        reservedKeys.put(Tokens.T_REFERENCES, REFERENCES);
+        reservedKeys.put(Tokens.T_REFERENCING, REFERENCING);
+        reservedKeys.put(Tokens.T_REGR_AVGX, REGR_AVGX);
+        reservedKeys.put(Tokens.T_REGR_AVGY, REGR_AVGY);
+        reservedKeys.put(Tokens.T_REGR_COUNT, REGR_COUNT);
+        reservedKeys.put(Tokens.T_REGR_INTERCEPT, REGR_INTERCEPT);
+        reservedKeys.put(Tokens.T_REGR_R2, REGR_R2);
+        reservedKeys.put(Tokens.T_REGR_SLOPE, REGR_SLOPE);
+        reservedKeys.put(Tokens.T_REGR_SXX, REGR_SXX);
+        reservedKeys.put(Tokens.T_REGR_SXY, REGR_SXY);
+        reservedKeys.put(Tokens.T_REGR_SYY, REGR_SYY);
+        reservedKeys.put(Tokens.T_RELEASE, RELEASE);
+        reservedKeys.put(Tokens.T_REPEAT, REPEAT);
+        reservedKeys.put(Tokens.T_RESIGNAL, RESIGNAL);
+        reservedKeys.put(Tokens.T_RETURN, RETURN);
+        reservedKeys.put(Tokens.T_RETURNS, RETURNS);
+        reservedKeys.put(Tokens.T_REVOKE, REVOKE);
+        reservedKeys.put(Tokens.T_RIGHT, RIGHT);
+        reservedKeys.put(Tokens.T_ROLLBACK, ROLLBACK);
+        reservedKeys.put(Tokens.T_ROLLUP, ROLLUP);
+        reservedKeys.put(Tokens.T_ROW, ROW);
+        reservedKeys.put(Tokens.T_ROW_NUMBER, ROW_NUMBER);
+        reservedKeys.put(Tokens.T_ROWS, ROWS);
+        reservedKeys.put(Tokens.T_SAVEPOINT, SAVEPOINT);
+        reservedKeys.put(Tokens.T_SCOPE, SCOPE);
+        reservedKeys.put(Tokens.T_SCROLL, SCROLL);
+        reservedKeys.put(Tokens.T_SEARCH, SEARCH);
+        reservedKeys.put(Tokens.T_SECOND, SECOND);
+        reservedKeys.put(Tokens.T_SELECT, SELECT);
+        reservedKeys.put(Tokens.T_SENSITIVE, SENSITIVE);
+        reservedKeys.put(Tokens.T_SESSION_USER, SESSION_USER);
+        reservedKeys.put(Tokens.T_SET, SET);
+        reservedKeys.put(Tokens.T_SIGNAL, SIGNAL);
+        reservedKeys.put(Tokens.T_SIMILAR, SIMILAR);
+        reservedKeys.put(Tokens.T_SMALLINT, SMALLINT);
+        reservedKeys.put(Tokens.T_SOME, SOME);
+        reservedKeys.put(Tokens.T_SPECIFIC, SPECIFIC);
+        reservedKeys.put(Tokens.T_SPECIFICTYPE, SPECIFICTYPE);
+        reservedKeys.put(Tokens.T_SQL, SQL);
+        reservedKeys.put(Tokens.T_SQLEXCEPTION, SQLEXCEPTION);
+        reservedKeys.put(Tokens.T_SQLSTATE, SQLSTATE);
+        reservedKeys.put(Tokens.T_SQLWARNING, SQLWARNING);
+        reservedKeys.put(Tokens.T_SQRT, SQRT);
+        reservedKeys.put(Tokens.T_STACKED, STACKED);
+        reservedKeys.put(Tokens.T_START, START);
+        reservedKeys.put(Tokens.T_STATIC, STATIC);
+        reservedKeys.put(Tokens.T_STDDEV_POP, STDDEV_POP);
+        reservedKeys.put(Tokens.T_STDDEV_SAMP, STDDEV_SAMP);
+        reservedKeys.put(Tokens.T_SUBMULTISET, SUBMULTISET);
+        reservedKeys.put(Tokens.T_SUBSTRING, SUBSTRING);
+        reservedKeys.put(Tokens.T_SUBSTRING_REGEX, SUBSTRING_REGEX);
+        reservedKeys.put(Tokens.T_SUM, SUM);
+        reservedKeys.put(Tokens.T_SYMMETRIC, SYMMETRIC);
+        reservedKeys.put(Tokens.T_SYSTEM, SYSTEM);
+        reservedKeys.put(Tokens.T_SYSTEM_USER, SYSTEM_USER);
+        reservedKeys.put(Tokens.T_TABLE, TABLE);
+        reservedKeys.put(Tokens.T_TABLESAMPLE, TABLESAMPLE);
+        reservedKeys.put(Tokens.T_THEN, THEN);
+        reservedKeys.put(Tokens.T_TIME, TIME);
+        reservedKeys.put(Tokens.T_TIMESTAMP, TIMESTAMP);
+        reservedKeys.put(Tokens.T_TIMEZONE_HOUR, TIMEZONE_HOUR);
+        reservedKeys.put(Tokens.T_TIMEZONE_MINUTE, TIMEZONE_MINUTE);
+        reservedKeys.put(Tokens.T_TO, TO);
+        reservedKeys.put(Tokens.T_TRAILING, TRAILING);
+        reservedKeys.put(Tokens.T_TRANSLATE, TRANSLATE);
+        reservedKeys.put(Tokens.T_TRANSLATE_REGEX, TRANSLATE_REGEX);
+        reservedKeys.put(Tokens.T_TRANSLATION, TRANSLATION);
+        reservedKeys.put(Tokens.T_TREAT, TREAT);
+        reservedKeys.put(Tokens.T_TRIGGER, TRIGGER);
+        reservedKeys.put(Tokens.T_TRIM, TRIM);
+        reservedKeys.put(Tokens.T_TRIM_ARRAY, TRIM_ARRAY);
+        reservedKeys.put(Tokens.T_TRUE, TRUE);
+        reservedKeys.put(Tokens.T_TRUNCATE, TRUNCATE);
+        reservedKeys.put(Tokens.T_UESCAPE, UESCAPE);
+        reservedKeys.put(Tokens.T_UNDO, UNDO);
+        reservedKeys.put(Tokens.T_UNION, UNION);
+        reservedKeys.put(Tokens.T_UNIQUE, UNIQUE);
+        reservedKeys.put(Tokens.T_UNKNOWN, UNKNOWN);
+        reservedKeys.put(Tokens.T_UNNEST, UNNEST);
+        reservedKeys.put(Tokens.T_UNTIL, UNTIL);
+        reservedKeys.put(Tokens.T_UPDATE, UPDATE);
+        reservedKeys.put(Tokens.T_UPPER, UPPER);
+        reservedKeys.put(Tokens.T_USER, USER);
+        reservedKeys.put(Tokens.T_USING, USING);
+        reservedKeys.put(Tokens.T_VALUE, VALUE);
+        reservedKeys.put(Tokens.T_VALUES, VALUES);
+        reservedKeys.put(Tokens.T_VAR_POP, VAR_POP);
+        reservedKeys.put(Tokens.T_VAR_SAMP, VAR_SAMP);
+        reservedKeys.put(Tokens.T_VARBINARY, VARBINARY);
+        reservedKeys.put(Tokens.T_VARCHAR, VARCHAR);
+        reservedKeys.put(Tokens.T_VARYING, VARYING);
+        reservedKeys.put(Tokens.T_WHEN, WHEN);
+        reservedKeys.put(Tokens.T_WHENEVER, WHENEVER);
+        reservedKeys.put(Tokens.T_WHERE, WHERE);
+        reservedKeys.put(Tokens.T_WIDTH_BUCKET, WIDTH_BUCKET);
+        reservedKeys.put(Tokens.T_WINDOW, WINDOW);
+        reservedKeys.put(Tokens.T_WITH, WITH);
+        reservedKeys.put(Tokens.T_WITHIN, WITHIN);
+        reservedKeys.put(Tokens.T_WITHOUT, WITHOUT);
+        reservedKeys.put(Tokens.T_WHILE, WHILE);
+        reservedKeys.put(Tokens.T_YEAR, YEAR);
+    }
+
+    private static final IntValueHashMap commandSet = new IntValueHashMap(251);
+
+    static {
+        commandSet.put(T_ACTION, ACTION);
+        commandSet.put(T_ADD, ADD);
+        commandSet.put(T_ADMIN, ADMIN);
+        commandSet.put(T_AFTER, AFTER);
+        commandSet.put(T_ALIAS, ALIAS);
+        commandSet.put(T_ALWAYS, ALWAYS);
+        commandSet.put(T_ASC, ASC);
+        commandSet.put(T_AUTOCOMMIT, AUTOCOMMIT);
+        commandSet.put(T_BACKUP, BACKUP);
+        commandSet.put(T_BEFORE, BEFORE);
+        commandSet.put(T_BIT, BIT);
+        commandSet.put(T_BLOCKING, BLOCKING);
+        commandSet.put(T_CACHE, CACHE);
+        commandSet.put(T_CACHED, CACHED);
+        commandSet.put(T_CASCADE, CASCADE);
+        commandSet.put(T_CATALOG, CATALOG);
+        commandSet.put(T_CHARACTERISTICS, CHARACTERISTICS);
+        commandSet.put(T_CHECKPOINT, CHECKPOINT);
+        commandSet.put(T_CRYPT_KEY, CRYPT_KEY);
+        commandSet.put(T_CLASS, CLASS);
+        commandSet.put(T_COLLATE, COLLATE);
+        commandSet.put(T_COLLATION, COLLATION);
+        commandSet.put(T_COMMENT, COMMENT);
+        commandSet.put(T_COMMITTED, COMMITTED);
+        commandSet.put(T_COMPACT, COMPACT);
+        commandSet.put(T_COMPRESSED, COMPRESSED);
+        commandSet.put(T_CONDITION_IDENTIFIER, Tokens.CONDITION_IDENTIFIER);
+        commandSet.put(T_CONTAINS, CONTAINS);
+        commandSet.put(T_CONTINUE, CONTINUE);
+        commandSet.put(T_CONTROL, CONTROL);
+        commandSet.put(T_CURDATE, CURDATE);
+        commandSet.put(T_CURTIME, CURTIME);
+        commandSet.put(T_DATA, DATA);
+        commandSet.put(T_DATABASE, DATABASE);
+        commandSet.put(T_DEFAULTS, DEFAULTS);
+        commandSet.put(T_DEFRAG, DEFRAG);
+        commandSet.put(T_DELAY, DELAY);
+        commandSet.put(T_DESC, DESC);
+        commandSet.put(T_DOMAIN, DOMAIN);
+        commandSet.put(T_EVENT, EVENT);
+        commandSet.put(T_EXCLUDING, EXCLUDING);
+        commandSet.put(T_EXPLAIN, EXPLAIN);
+        commandSet.put(T_FILE, FILE);
+        commandSet.put(T_FILES, FILES);
+        commandSet.put(T_FINAL, FINAL);
+        commandSet.put(T_FIRST, FIRST);
+        commandSet.put(T_G_FACTOR, G);
+        commandSet.put(T_GC, GC);
+        commandSet.put(T_GENERATED, GENERATED);
+        commandSet.put(T_GRANTED, GRANTED);
+        commandSet.put(T_HEADER, HEADER);
+        commandSet.put(T_IF, Tokens.IF);
+        commandSet.put(T_IGNORECASE, IGNORECASE);
+        commandSet.put(T_IMMEDIATELY, IMMEDIATELY);
+        commandSet.put(T_INCLUDING, INCLUDING);
+        commandSet.put(T_INCREMENT, INCREMENT);
+        commandSet.put(T_INDEX, INDEX);
+        commandSet.put(T_INITIAL, INITIAL);
+        commandSet.put(T_INPUT, INPUT);
+        commandSet.put(T_INSTEAD, INSTEAD);
+        commandSet.put(T_INTEGRITY, INTEGRITY);
+        commandSet.put(T_ISAUTOCOMMIT, ISAUTOCOMMIT);
+        commandSet.put(T_ISOLATION, ISOLATION);
+        commandSet.put(T_ISREADONLYDATABASE, ISREADONLYDATABASE);
+        commandSet.put(T_ISREADONLYDATABASEFILES, ISREADONLYDATABASEFILES);
+        commandSet.put(T_ISREADONLYSESSION, ISREADONLYSESSION);
+        commandSet.put(T_JAVA, JAVA);
+        commandSet.put(T_K_FACTOR, K);
+        commandSet.put(T_KEY, KEY);
+        commandSet.put(T_LAST, LAST);
+        commandSet.put(T_LENGTH, LENGTH);
+        commandSet.put(T_LEVEL, LEVEL);
+        commandSet.put(T_LIBRARY, LIBRARY);
+        commandSet.put(T_LIMIT, LIMIT);
+        commandSet.put(T_LOB, LOB);
+        commandSet.put(T_LOCK, LOCK);
+        commandSet.put(T_LOCKS, LOCKS);
+        commandSet.put(T_M_FACTOR, M);
+        commandSet.put(T_MATCHED, MATCHED);
+        commandSet.put(T_MAXROWS, MAXROWS);
+        commandSet.put(T_MAXVALUE, MAXVALUE);
+        commandSet.put(T_MEMORY, MEMORY);
+        commandSet.put(T_MILLIS, MILLIS);
+        commandSet.put(T_MINUS_EXCEPT, MINUS_EXCEPT);
+        commandSet.put(T_MINVALUE, MINVALUE);
+        commandSet.put(T_MVCC, MVCC);
+        commandSet.put(T_MVLOCKS, MVLOCKS);
+        commandSet.put(T_NAME, NAME);
+        commandSet.put(T_NEXT, NEXT);
+        commandSet.put(T_NIO, NIO);
+        commandSet.put(T_NOW, NOW);
+        commandSet.put(T_NULLS, NULLS);
+        commandSet.put(T_OFF, OFF);
+        commandSet.put(T_OPTION, OPTION);
+        commandSet.put(T_ORDINALITY, ORDINALITY);
+        commandSet.put(T_OVERRIDING, OVERRIDING);
+        commandSet.put(T_P_FACTOR, P);
+        commandSet.put(T_PARTIAL, PARTIAL);
+        commandSet.put(T_PASSWORD, PASSWORD);
+        commandSet.put(T_PLACING, PLACING);
+        commandSet.put(T_PLAN, PLAN);
+        commandSet.put(T_PRESERVE, PRESERVE);
+        commandSet.put(T_PRIVILEGES, PRIVILEGES);
+        commandSet.put(T_PROPERTY, PROPERTY);
+        commandSet.put(T_READ, READ);
+        commandSet.put(T_READONLY, READONLY);
+        commandSet.put(T_REFERENTIAL, REFERENTIAL);
+        commandSet.put(T_RENAME, RENAME);
+        commandSet.put(T_REPEATABLE, REPEATABLE);
+        commandSet.put(T_RESTART, RESTART);
+        commandSet.put(T_RESTRICT, RESTRICT);
+        commandSet.put(T_RESULT, RESULT);
+        commandSet.put(T_ROLE, ROLE);
+        commandSet.put(T_ROUTINE, ROUTINE);
+        commandSet.put(T_SCALE, SCALE);
+        commandSet.put(T_SCHEMA, SCHEMA);
+        commandSet.put(T_SCRIPT, SCRIPT);
+        commandSet.put(T_SCRIPTFORMAT, SCRIPTFORMAT);
+        commandSet.put(T_SEQUENCE, SEQUENCE);
+        commandSet.put(T_SERIALIZABLE, SERIALIZABLE);
+        commandSet.put(T_SERVER, SERVER);
+        commandSet.put(T_SESSION, SESSION);
+        commandSet.put(T_SHUTDOWN, SHUTDOWN);
+        commandSet.put(T_SIMPLE, SIMPLE);
+        commandSet.put(T_SIZE, SIZE);
+        commandSet.put(T_SOURCE, SOURCE);
+        commandSet.put(T_SQL_BIGINT, SQL_BIGINT);
+        commandSet.put(T_SQL_BINARY, SQL_BINARY);
+        commandSet.put(T_SQL_BIT, SQL_BIT);
+        commandSet.put(T_SQL_BLOB, SQL_BLOB);
+        commandSet.put(T_SQL_BOOLEAN, SQL_BOOLEAN);
+        commandSet.put(T_SQL_CHAR, SQL_CHAR);
+        commandSet.put(T_SQL_CLOB, SQL_CLOB);
+        commandSet.put(T_SQL_DATALINK, SQL_DATALINK);
+        commandSet.put(T_SQL_DATE, SQL_DATE);
+        commandSet.put(T_SQL_DECIMAL, SQL_DECIMAL);
+        commandSet.put(T_SQL_DOUBLE, SQL_DOUBLE);
+        commandSet.put(T_SQL_FLOAT, SQL_FLOAT);
+        commandSet.put(T_SQL_INTEGER, SQL_INTEGER);
+        commandSet.put(T_SQL_LONGNVARCHAR, SQL_LONGNVARCHAR);
+        commandSet.put(T_SQL_LONGVARBINARY, SQL_LONGVARBINARY);
+        commandSet.put(T_SQL_LONGVARCHAR, SQL_LONGVARCHAR);
+        commandSet.put(T_SQL_NCHAR, SQL_NCHAR);
+        commandSet.put(T_SQL_NCLOB, SQL_NCLOB);
+        commandSet.put(T_SQL_NUMERIC, SQL_NUMERIC);
+        commandSet.put(T_SQL_NVARCHAR, SQL_NVARCHAR);
+        commandSet.put(T_SQL_REAL, SQL_REAL);
+        commandSet.put(T_SQL_ROWID, SQL_ROWID);
+        commandSet.put(T_SQL_SMALLINT, SQL_SMALLINT);
+        commandSet.put(T_SQL_SQLXML, SQL_SQLXML);
+        commandSet.put(T_SQL_TIME, SQL_TIME);
+        commandSet.put(T_SQL_TIMESTAMP, SQL_TIMESTAMP);
+        commandSet.put(T_SQL_TINYINT, SQL_TINYINT);
+        commandSet.put(T_SQL_VARBINARY, SQL_VARBINARY);
+        commandSet.put(T_SQL_VARCHAR, SQL_VARCHAR);
+        commandSet.put(T_SQL_TSI_DAY, SQL_TSI_DAY);
+        commandSet.put(T_SQL_TSI_FRAC_SECOND, SQL_TSI_FRAC_SECOND);
+        commandSet.put(T_SQL_TSI_HOUR, SQL_TSI_HOUR);
+        commandSet.put(T_SQL_TSI_MINUTE, SQL_TSI_MINUTE);
+        commandSet.put(T_SQL_TSI_MONTH, SQL_TSI_MONTH);
+        commandSet.put(T_SQL_TSI_QUARTER, SQL_TSI_QUARTER);
+        commandSet.put(T_SQL_TSI_SECOND, SQL_TSI_SECOND);
+        commandSet.put(T_SQL_TSI_WEEK, SQL_TSI_WEEK);
+        commandSet.put(T_SQL_TSI_YEAR, SQL_TSI_YEAR);
+        commandSet.put(T_STATEMENT, STATEMENT);
+        commandSet.put(T_STYLE, STYLE);
+        commandSet.put(T_T_FACTOR, T);
+        commandSet.put(T_TEMP, TEMP);
+        commandSet.put(T_TEMPORARY, TEMPORARY);
+        commandSet.put(T_TEXT, TEXT);
+        commandSet.put(T_TIMESTAMPADD, TIMESTAMPADD);
+        commandSet.put(T_TIMESTAMPDIFF, TIMESTAMPDIFF);
+        commandSet.put(T_TO_CHAR, TO_CHAR);
+        commandSet.put(T_TODAY, TODAY);
+        commandSet.put(T_TOP, TOP);
+        commandSet.put(T_TRANSACTION, TRANSACTION);
+        commandSet.put(T_TYPE, TYPE);
+        commandSet.put(T_UNCOMMITTED, UNCOMMITTED);
+        commandSet.put(T_USAGE, USAGE);
+        commandSet.put(T_VIEW, VIEW);
+        commandSet.put(T_WORK, WORK);
+        commandSet.put(T_WRAPPER, WRAPPER);
+        commandSet.put(T_WRITE, WRITE);
+        commandSet.put(T_WRITE_DELAY, WRITE_DELAY);
+        commandSet.put(T_ZONE, ZONE);
+
+        //
+        commandSet.put(T_ACOS, ACOS);
+        commandSet.put(T_ASCII, ASCII);
+        commandSet.put(T_ASIN, ASIN);
+        commandSet.put(T_ATAN, ATAN);
+        commandSet.put(T_ATAN2, ATAN2);
+        commandSet.put(T_BITAND, BITAND);
+        commandSet.put(T_BITLENGTH, BITLENGTH);
+        commandSet.put(T_BITOR, BITOR);
+        commandSet.put(T_BITXOR, BITXOR);
+        commandSet.put(T_CASEWHEN, Tokens.CASEWHEN);
+        commandSet.put(T_CONCAT_WORD, CONCAT_WORD);
+        commandSet.put(T_COS, COS);
+        commandSet.put(T_COT, COT);
+        commandSet.put(T_DATEADD, DATEADD);
+        commandSet.put(T_DATEDIFF, DATEDIFF);
+        commandSet.put(T_DAY_NAME, DAY_NAME);
+        commandSet.put(T_DAY_OF_MONTH, DAY_OF_MONTH);
+        commandSet.put(T_DAY_OF_WEEK, DAY_OF_WEEK);
+        commandSet.put(T_DAY_OF_YEAR, DAY_OF_YEAR);
+        commandSet.put(T_DAYNAME, DAYNAME);
+        commandSet.put(T_DAYOFMONTH, DAYOFMONTH);
+        commandSet.put(T_DAYOFWEEK, DAYOFWEEK);
+        commandSet.put(T_DAYOFYEAR, DAYOFYEAR);
+        commandSet.put(T_DECODE, DECODE);
+        commandSet.put(T_DEGREES, DEGREES);
+        commandSet.put(T_DIFFERENCE, DIFFERENCE);
+        commandSet.put(T_DMOD, DMOD);
+        commandSet.put(T_GREATEST, GREATEST);
+        commandSet.put(T_HEXTORAW, HEXTORAW);
+        commandSet.put(T_IFNULL, Tokens.IFNULL);
+        commandSet.put(T_LCASE, LCASE);
+        commandSet.put(T_LEAST, LEAST);
+        commandSet.put(T_LOCATE, LOCATE);
+        commandSet.put(T_LOG, LOG);
+        commandSet.put(T_LOG10, LOG10);
+        commandSet.put(T_LTRIM, LTRIM);
+        commandSet.put(T_MONTH_NAME, MONTH_NAME);
+        commandSet.put(T_MONTHNAME, MONTHNAME);
+        commandSet.put(T_NAMES, Tokens.NAMES);
+        commandSet.put(T_NVL, Tokens.IFNULL);
+        commandSet.put(T_OCTETLENGTH, OCTETLENGTH);
+        commandSet.put(T_PI, PI);
+        commandSet.put(T_QUARTER, QUARTER);
+        commandSet.put(T_RADIANS, RADIANS);
+        commandSet.put(T_RAND, RAND);
+        commandSet.put(T_RAWTOHEX, RAWTOHEX);
+        commandSet.put(T_REGEXP_MATCHES, REGEXP_MATCHES);
+        commandSet.put(T_REPLACE, REPLACE);
+        commandSet.put(T_REVERSE, REVERSE);
+        commandSet.put(T_ROUND, ROUND);
+        commandSet.put(T_ROUNDMAGIC, ROUNDMAGIC);
+        commandSet.put(T_RTRIM, RTRIM);
+        commandSet.put(T_SECONDS_MIDNIGHT, SECONDS_MIDNIGHT);
+        commandSet.put(T_SIGN, SIGN);
+        commandSet.put(T_SIN, SIN);
+        commandSet.put(T_SOUNDEX, SOUNDEX);
+        commandSet.put(T_SPACE, SPACE);
+        commandSet.put(T_SUBSTR, SUBSTR);
+        commandSet.put(T_SYSDATE, SYSDATE);
+        commandSet.put(T_TAN, TAN);
+        commandSet.put(T_UCASE, UCASE);
+        commandSet.put(T_WEEK, WEEK);
+        commandSet.put(T_WEEK_OF_YEAR, WEEK_OF_YEAR);
+
+        //
+        commandSet.put(T_ISOLATION_LEVEL, ISOLATION_LEVEL);
+        commandSet.put(T_SESSION_ISOLATION_LEVEL, SESSION_ISOLATION_LEVEL);
+        commandSet.put(T_DATABASE_ISOLATION_LEVEL, DATABASE_ISOLATION_LEVEL);
+        commandSet.put(T_TRANSACTION_CONTROL, TRANSACTION_CONTROL);
+        commandSet.put(T_TIMEZONE, TIMEZONE);
+        commandSet.put(T_SESSION_TIMEZONE, SESSION_TIMEZONE);
+        commandSet.put(T_DATABASE_TIMEZONE, DATABASE_TIMEZONE);
+        commandSet.put(T_DATABASE_VERSION, DATABASE_VERSION);
+
+        //
+        commandSet.put(T_ASTERISK, Tokens.ASTERISK);
+        commandSet.put(T_CLOSEBRACKET, CLOSEBRACKET);
+        commandSet.put(T_COLON, Tokens.COLON);
+        commandSet.put(T_COMMA, Tokens.COMMA);
+        commandSet.put(T_CONCAT, Tokens.CONCAT);
+        commandSet.put(T_DIVIDE, Tokens.DIVIDE);
+        commandSet.put(T_EQUALS, Tokens.EQUALS);
+        commandSet.put(T_GREATER, Tokens.GREATER);
+        commandSet.put(T_GREATER_EQUALS, Tokens.GREATER_EQUALS);
+        commandSet.put(T_LEFTBRACKET, LEFTBRACKET);
+        commandSet.put(T_LESS, Tokens.LESS);
+        commandSet.put(T_LESS_EQUALS, Tokens.LESS_EQUALS);
+        commandSet.put(T_MINUS, Tokens.MINUS);
+        commandSet.put(T_NOT_EQUALS, Tokens.NOT_EQUALS);
+        commandSet.put(T_NOT_EQUALS_ALT, Tokens.NOT_EQUALS);
+        commandSet.put(T_OPENBRACKET, OPENBRACKET);
+        commandSet.put(T_PLUS, Tokens.PLUS);
+        commandSet.put(T_QUESTION, Tokens.QUESTION);
+        commandSet.put(T_RIGHTBRACKET, RIGHTBRACKET);
+        commandSet.put(T_SEMICOLON, SEMICOLON);
+    }
+
+    static int get(String token) {
+
+        int type = reservedKeys.get(token, -1);
+
+        if (type == -1) {
+            return commandSet.get(token, -1);
+        }
+
+        return type;
+    }
+
+    public static boolean isCoreKeyword(int token) {
+        return coreReservedWords.contains(token);
+    }
+
+    public static boolean isKeyword(String token) {
+        return reservedKeys.containsKey(token);
+    }
+
+    public static int getKeywordID(String token, int defaultValue) {
+        return reservedKeys.get(token, defaultValue);
+    }
+
+    public static int getNonKeywordID(String token, int defaultValue) {
+        return commandSet.get(token, defaultValue);
+    }
+
+    public static String getKeyword(int token) {
+
+        String key = (String) reservedKeys.getKey(token);
+
+        if (key != null) {
+            return key;
+        }
+
+        key = (String) commandSet.getKey(token);
+
+        return key;
+    }
+
+    private static final OrderedIntHashSet coreReservedWords;
+
+    static {
+
+        // minimal set of identifier not allowed as table / column / alias names
+        // these are in effect interpreted as reserved words used by HSQLDB
+        coreReservedWords = new OrderedIntHashSet(128);
+
+        short[] keyword = {
+            ADMIN, AS, AND, ALL, ANY, AT, AVG, BY, BETWEEN, BOTH, CALL, CASE,
+            CAST, CORRESPONDING, CONVERT, COUNT, COALESCE, CREATE, CROSS,
+            DISTINCT, DROP, ELSE, END, EVERY, EXISTS, EXCEPT, FOR, FROM, FULL,
+            GRANT, GROUP, HAVING, INTO, IS, IN, INTERSECT, JOIN, INNER, LEFT,
+            LEADING, LIKE, MAX, MIN, NATURAL, NULLIF, NOT, ON, ORDER, OR,
+            OUTER, PRIMARY, REFERENCES, RIGHT, SELECT, SET, SOME, STDDEV_POP,
+            STDDEV_SAMP, SUM, TABLE, THEN, TO, TRAILING, TRIGGER, UNION,
+            UNIQUE, USING, VALUES, VAR_POP, VAR_SAMP, WHEN, WHERE, WITH,
+        };
+
+        for (int i = 0; i < keyword.length; i++) {
+            coreReservedWords.add(keyword[i]);
+        }
+    }
+
+    public static final short[] SQL_INTERVAL_FIELD_CODES = new short[] {
+        Tokens.YEAR, Tokens.MONTH, Tokens.DAY, Tokens.HOUR, Tokens.MINUTE,
+        Tokens.SECOND
+    };
+    public static final String[] SQL_INTERVAL_FIELD_NAMES = new String[] {
+        Tokens.T_YEAR, Tokens.T_MONTH, Tokens.T_DAY, Tokens.T_HOUR,
+        Tokens.T_MINUTE, Tokens.T_SECOND
+    };
+    private static final IntKeyHashMap sqlTSILookup = new IntKeyHashMap(10);
+
+    static {
+        sqlTSILookup.put(SQL_TSI_DAY, T_SQL_TSI_DAY);
+        sqlTSILookup.put(SQL_TSI_FRAC_SECOND, T_SQL_TSI_FRAC_SECOND);
+        sqlTSILookup.put(SQL_TSI_HOUR, T_SQL_TSI_HOUR);
+        sqlTSILookup.put(SQL_TSI_MINUTE, T_SQL_TSI_MINUTE);
+        sqlTSILookup.put(SQL_TSI_MONTH, T_SQL_TSI_MONTH);
+        sqlTSILookup.put(SQL_TSI_QUARTER, T_SQL_TSI_QUARTER);
+        sqlTSILookup.put(SQL_TSI_SECOND, T_SQL_TSI_SECOND);
+        sqlTSILookup.put(SQL_TSI_WEEK, T_SQL_TSI_WEEK);
+        sqlTSILookup.put(SQL_TSI_YEAR, T_SQL_TSI_YEAR);
+    }
+
+    public static String getSQLTSIString(int token) {
+        return (String) sqlTSILookup.get(token);
+    }
+}
diff --git a/doc-src/verbatim/src/org/hsqldb/Trigger.java b/doc-src/verbatim/src/org/hsqldb/Trigger.java
new file mode 100644
index 0000000..a3979be
--- /dev/null
+++ b/doc-src/verbatim/src/org/hsqldb/Trigger.java
@@ -0,0 +1,128 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+// fredt@users 20030727 - signature altered to support update triggers
+/*
+
+Contents of row1[] and row2[] in each type of trigger.
+
+AFTER INSERT
+ - row1[] contains single String object = "Statement-level".
+
+AFTER UPDATE
+ - row1[] contains single String object = "Statement-level".
+
+AFTER DELETE
+ - row1[] contains single String object = "Statement-level".
+
+BEFORE INSERT FOR EACH ROW
+ - row2[] contains data about to be inserted and this can
+be modified within the trigger such that modified data gets written to the
+database.
+
+AFTER INSERT FOR EACH ROW
+ - row2[] contains data just inserted into the table.
+
+BEFORE UPDATE FOR EACH ROW
+ - row1[] contains currently stored data and not the data that is about to be
+updated.
+
+ - row2[] contains the data that is about to be updated.
+
+AFTER UPDATE FOR EACH ROW
+ - row1[] contains old stored data.
+ - row2[] contains the new data.
+
+BEFORE DELETE FOR EACH ROW
+ - row1[] contains row data about to be deleted.
+
+AFTER DELETE FOR EACH ROW
+ - row1[] contains row data that has been deleted.
+
+List compiled by Andrew Knight (quozzbat@users)
+*/
+
+/**
+ * The interface an HSQLDB TRIGGER must implement. The user-supplied class that
+ * implements this must have a default constructor.
+ *
+ * @author Peter Hudson
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public interface Trigger {
+
+    // type of trigger
+    int INSERT_AFTER      = 0;
+    int DELETE_AFTER      = 1;
+    int UPDATE_AFTER      = 2;
+    int INSERT_AFTER_ROW  = 3;
+    int DELETE_AFTER_ROW  = 4;
+    int UPDATE_AFTER_ROW  = 5;
+    int INSERT_BEFORE_ROW = 6;
+    int DELETE_BEFORE_ROW = 7;
+    int UPDATE_BEFORE_ROW = 8;
+
+    /**
+     * The method invoked upon each triggered action.
+     *
+     * <p> type contains the integer index id for trigger type, e.g.
+     * TriggerDef.INSERT_AFTER
+     *
+     * <p> For all triggers defined as default FOR EACH STATEMENT both
+     *  oldRow and newRow are null.
+     *
+     * <p> For triggers defined as FOR EACH ROW, the following will apply:
+     *
+     * <p> When UPDATE triggers are fired, oldRow contains the existing values
+     * of the table row and newRow contains the new values.
+     *
+     * <p> For INSERT triggers, oldRow is null and newRow contains the table row
+     * to be inserted. For DELETE triggers, newRow is null and oldRow contains
+     * the table row to be deleted.
+     *
+     * <p> For error conditions, users can construct an HsqlException using one
+     * of the static methods of org.hsqldb.error.Error with a predefined
+     * SQL State from org.hsqldb.error.ErrorCode.
+     *
+     * @param type int
+     * @param trigName the name of the trigger
+     * @param tabName the name of the table upon which the triggered action is
+     *   occuring
+     * @param oldRow the old row
+     * @param newRow the new row
+     * @throws HsqlException
+     */
+    void fire(int type, String trigName, String tabName, Object[] oldRow,
+              Object[] newRow) throws HsqlException;
+}
diff --git a/doc-src/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java b/doc-src/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java
new file mode 100644
index 0000000..1fefc45
--- /dev/null
+++ b/doc-src/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java
@@ -0,0 +1,150 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import org.hsqldb.lib.RCData;
+import org.hsqldb.cmdline.SqlFile;
+import org.hsqldb.cmdline.SqlToolError;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Sample class which executes SQL files, by embedding SqlFile.
+ * <P/>
+ * Suitable for using as a template.
+ * <P/>
+ * This class also serves as an example of using RCData to allow your
+ * application users to store JDBC access information in a convenient
+ * text file.
+ *
+ * @see #main(String[])
+ * @see SqlFile
+ * @see RCData
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class SqlFileEmbedder {
+    private Connection conn;
+
+    /**
+     * For applications that use a persistent JDBC connection, this class can
+     * be used to encapsulate that connection.  (Just strip out the SqlFile
+     * stuff if you don't need that).
+     *
+     * @return The encapsulated JDBC Connection.
+     */
+    public Connection getConn() {
+        return conn;
+    }
+
+    /**
+     * Run<PRE>
+     *     java SqlFileEmbedder</PRE>
+     * to see Syntax message.
+     */
+    public static void main(String[] sa) throws Exception {
+        if (sa.length < 3) {
+            System.err.println("SYNTAX:  " + SqlFileEmbedder.class.getName()
+                    + " path/ro/file.rc URLID file1.sql...");
+            System.exit(2);
+        }
+        SqlFileEmbedder embedder =
+                new SqlFileEmbedder(new File(sa[0]), sa[1]);
+        String[] files = new String[sa.length - 2];
+        for (int i = 0; i < sa.length - 2; i++) {
+            files[i] = sa[i + 2];
+        }
+        try {
+            embedder.executeFiles(files);
+        } finally {
+            try {
+                embedder.getConn().close();
+            } catch (SQLException se) {
+                // Purposefully ignoring.
+                // We have done what we want and are now going to exit, so
+                // who cares.
+            }
+        }
+    }
+
+    /**
+     * Instantiates SqlFileEmbedder object and connects to specified database.
+     * <P/>
+     * N.b., you do not need to use RCData to use SqlFile.
+     * All SqlFile needs is a live Connection.
+     * I'm using RCData because it is a convenient way for a non-contained
+     * app (i.e. one that doesn't run in a 3rd party container) to get a
+     * Connection.
+     */
+    public SqlFileEmbedder(File rcFile, String urlid) throws Exception {
+        conn = (new RCData(rcFile, urlid)).getConnection();
+        conn.setAutoCommit(false);
+    }
+
+    /**
+     * Your own classes can use this method to execute SQL files.
+     * <P/>
+     * See source code for the main(String[]) method for an example of calling
+     * this method.
+     *
+     * @see #main(String[])
+     */
+    public void executeFiles(String[] fileStrings)
+            throws IOException, SqlToolError, SQLException {
+        Map<String, String> sqlVarMap = new HashMap<String, String>();
+        sqlVarMap.put("invoker", getClass().getName());
+        // This variable is pretty useless, but this should show you how to
+        // set variables which you can access inside of scripts like *{this}.
+
+        File file;
+        SqlFile sqlFile;
+        for (String fileString : fileStrings) {
+            file = new File(fileString);
+            if (!file.isFile())
+                throw new IOException("SQL file not present: "
+                        + file.getAbsolutePath());
+            sqlFile = new SqlFile(file);
+            sqlFile.setConnection(conn);
+            sqlFile.addUserVars(sqlVarMap);
+            sqlFile.execute();
+
+            // The only reason for the following two statements is so that
+            // changes made by one .sql file will effect the future SQL files.
+            // Has no effect if you only execute one SQL file.
+            conn = sqlFile.getConnection();
+            sqlVarMap = sqlFile.getUserVars();
+        }
+    }
+}
diff --git a/doc-src/verbatim/src/org/hsqldb/sample/Testdb.java b/doc-src/verbatim/src/org/hsqldb/sample/Testdb.java
new file mode 100644
index 0000000..f211469
--- /dev/null
+++ b/doc-src/verbatim/src/org/hsqldb/sample/Testdb.java
@@ -0,0 +1,203 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * Title:        Testdb
+ * Description:  simple hello world db example of a
+ *               standalone persistent db application
+ *
+ *               every time it runs it adds four more rows to sample_table
+ *               it does a query and prints the results to standard out
+ *
+ * Author: Karl Meissner karl@meissnersd.com
+ */
+public class Testdb {
+
+    Connection conn;                                                //our connnection to the db - presist for life of program
+
+    // we dont want this garbage collected until we are done
+    public Testdb(String db_file_name_prefix) throws Exception {    // note more general exception
+
+        // Load the HSQL Database Engine JDBC driver
+        // hsqldb.jar should be in the class path or made part of the current jar
+        Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+        // connect to the database.   This will load the db files and start the
+        // database if it is not alread running.
+        // db_file_name_prefix is used to open or create files that hold the state
+        // of the db.
+        // It can contain directory names relative to the
+        // current working directory
+        conn = DriverManager.getConnection("jdbc:hsqldb:"
+                                           + db_file_name_prefix,    // filenames
+                                           "SA",                     // username
+                                           "");                      // password
+    }
+
+    public void shutdown() throws SQLException {
+
+        Statement st = conn.createStatement();
+
+        // db writes out to files and performs clean shuts down
+        // otherwise there will be an unclean shutdown
+        // when program ends
+        st.execute("SHUTDOWN");
+        conn.close();    // if there are no other open connection
+    }
+
+//use for SQL command SELECT
+    public synchronized void query(String expression) throws SQLException {
+
+        Statement st = null;
+        ResultSet rs = null;
+
+        st = conn.createStatement();         // statement objects can be reused with
+
+        // repeated calls to execute but we
+        // choose to make a new one each time
+        rs = st.executeQuery(expression);    // run the query
+
+        // do something with the result set.
+        dump(rs);
+        st.close();    // NOTE!! if you close a statement the associated ResultSet is
+
+        // closed too
+        // so you should copy the contents to some other object.
+        // the result set is invalidated also  if you recycle an Statement
+        // and try to execute some other query before the result set has been
+        // completely examined.
+    }
+
+//use for SQL commands CREATE, DROP, INSERT and UPDATE
+    public synchronized void update(String expression) throws SQLException {
+
+        Statement st = null;
+
+        st = conn.createStatement();    // statements
+
+        int i = st.executeUpdate(expression);    // run the query
+
+        if (i == -1) {
+            System.out.println("db error : " + expression);
+        }
+
+        st.close();
+    }    // void update()
+
+    public static void dump(ResultSet rs) throws SQLException {
+
+        // the order of the rows in a cursor
+        // are implementation dependent unless you use the SQL ORDER statement
+        ResultSetMetaData meta   = rs.getMetaData();
+        int               colmax = meta.getColumnCount();
+        int               i;
+        Object            o = null;
+
+        // the result set is a cursor into the data.  You can only
+        // point to one row at a time
+        // assume we are pointing to BEFORE the first row
+        // rs.next() points to next row and returns true
+        // or false if there is no next row, which breaks the loop
+        for (; rs.next(); ) {
+            for (i = 0; i < colmax; ++i) {
+                o = rs.getObject(i + 1);    // Is SQL the first column is indexed
+
+                // with 1 not 0
+                System.out.print(o.toString() + " ");
+            }
+
+            System.out.println(" ");
+        }
+    }                                       //void dump( ResultSet rs )
+
+    public static void main(String[] args) {
+
+        Testdb db = null;
+
+        try {
+            db = new Testdb("db_file");
+        } catch (Exception ex1) {
+            ex1.printStackTrace();    // could not start db
+
+            return;                   // bye bye
+        }
+
+        try {
+
+            //make an empty table
+            //
+            // by declaring the id column IDENTITY, the db will automatically
+            // generate unique values for new rows- useful for row keys
+            db.update(
+                "CREATE TABLE sample_table ( id INTEGER IDENTITY, str_col VARCHAR(256), num_col INTEGER)");
+        } catch (SQLException ex2) {
+
+            //ignore
+            //ex2.printStackTrace();  // second time we run program
+            //  should throw execption since table
+            // already there
+            //
+            // this will have no effect on the db
+        }
+
+        try {
+
+            // add some rows - will create duplicates if run more then once
+            // the id column is automatically generated
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Ford', 100)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Toyota', 200)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Honda', 300)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('GM', 400)");
+
+            // do a query
+            db.query("SELECT * FROM sample_table WHERE num_col < 250");
+
+            // at end of program
+            db.shutdown();
+        } catch (SQLException ex3) {
+            ex3.printStackTrace();
+        }
+    }    // main()
+}    // class Testdb
+
diff --git a/doc-src/verbatim/src/org/hsqldb/sample/TriggerSample.java b/doc-src/verbatim/src/org/hsqldb/sample/TriggerSample.java
new file mode 100644
index 0000000..42831c6
--- /dev/null
+++ b/doc-src/verbatim/src/org/hsqldb/sample/TriggerSample.java
@@ -0,0 +1,506 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.Trigger;
+import org.hsqldb.lib.StringUtil;
+
+// peterhudson@users 20020130 - patch 478657 by peterhudson - new class
+// fredt@users 20030727 - signature altered
+// boucherb@users 20040315 - sample updated
+
+/**
+ * <P>Sample code for use of triggers in hsqldb.
+ *
+ * This class org.hsqldb.sample package, but a typical implementation is in
+ * users's class hierarchy.
+ *
+ * SQL to invoke is:<p>
+ * CREATE TRIGGER triggerSample BEFORE|AFTER INSERT|UPDATE|DELETE
+ * ON myTable [FOR EACH ROW] [QUEUE n] [NOWAIT] CALL "myPackage.trigClass"<br>
+ *
+ * This will create a thread that will wait for its firing event to occur;
+ * when this happens, the trigger's thread runs the 'trigClass.fire'
+ * Note that this is still in the same Java Virtual Machine as the
+ * database, so make sure the fired method does not hang.<p>
+ *
+ * There is a queue of events waiting to be run by each trigger thread.
+ * This is particularly useful for 'FOR EACH ROW' triggers, when a large
+ * number of trigger events occur in rapid succession, without the trigger
+ * thread getting a chance to run. If the queue becomes full, subsequent
+ * additions to it cause the database engine to suspend awaiting space
+ * in the queue. Take great care to avoid this situation if the trigger
+ * action involves accessing the database, as deadlock will occur.
+ * This can be avoided either by ensuring the QUEUE parameter makes a large
+ * enough queue, or by using the NOWAIT parameter, which causes a new
+ * trigger event to overwrite the most recent event in the queue.
+ * The default queue size is 1024.<p>
+ *
+ * Ensure that "myPackage.trigClass" is present in the classpath which
+ * you use to start hsql.<p>
+ *
+ * If the method wants to access the database, it must establish
+ * a JDBC connection.<p>
+ *
+ * When the 'fire' method is called, it is passed the following arguments: <p>
+ *
+ * fire (int type, String trigName, String tabName, Object oldRow[],
+ *       Object[] newRow) <p>
+ *
+ * where 'type' is one of the values enumerated in the Trigger interface and
+ * the 'oldRow'/'newRow' pair represents the rows acted on. The first
+ * length - 1 array slots contain column values and the final slot contains
+ * either null or the value of the internally assigned row identity, if
+ * the concerned table has no primary key. The final slot must _never_ be
+ * modified. <p>
+ *
+ * The mapping of row classes to database types is specified in
+ * /doc/hsqlSyntax.html#Datatypes. <p>
+ *
+ * To be done:<p>
+ *
+ * <ol>
+ * <li> Implement the "jdbc:default:connection: URL to provide transparent
+ *      and portable access to internal connections for use in triggers and
+ *      stored procedures. <p>
+ *
+ * <li> Implement declaritive column to trigger method argument
+ *      mapping, conditional execution (WHEN clause), etc. <p>
+ *
+ * <li> Investigate and refine synchronous and asynchronous trigger models. <p>
+ *
+ *      Because certain combinations of trigger create parameters cause the
+ *      individual triggered actions of a multirow update to run in different
+ *      threads, it is possible for an 'after' trigger to run before its
+ *      corresponding 'before' trigger; the acceptability and implications
+ *      of this needs to be investigated, documented and the behaviour of
+ *      the engine fully specified.
+ *
+ * <li> Investigate and implement the SQL 200n specified execution stack under
+ *      arbitrary triggered action and SQL-invoked routine call graphs.
+ * </ol>
+ *
+ * @author Peter Hudson
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+public class TriggerSample implements Trigger {
+
+    static final PrintWriter out  = new PrintWriter(System.out);
+    static final String      drv  = "org.hsqldb.jdbc.JDBCDriver";
+    static final String      url  = "jdbc:hsqldb:mem:trigger-sample";
+    static final String      usr  = "SA";
+    static final String      pwd  = "";
+    static final String      impl = TriggerSample.class.getName();
+    static final String      tn   = "trig_test";
+    static final String drop_test_table_stmt = "DROP TABLE " + tn
+        + " IF EXISTS";
+    static final String create_test_table_stmt = "CREATE TABLE " + tn
+        + "(id INTEGER PRIMARY KEY, value VARCHAR(20))";
+    static final String drop_audit_table_stmt = "DROP TABLE audit IF EXISTS";
+    static final String create_audit_table_stmt = "CREATE TABLE audit("
+        + "id  INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1), "
+        + "op  VARCHAR(6), " + "tn  VARCHAR(20), " + "ors LONGVARCHAR, "
+        + "nrs LONGVARCHAR, " + "ts  TIMESTAMP DEFAULT CURRENT_TIMESTAMP)";
+    static final String audit_insert_stmt =
+        "INSERT INTO audit(op, tn, ors, nrs) VALUES(?, ?, ?, ?)";
+
+    /**
+     * A sample HSQLDB Trigger interface implementation. <p>
+     *
+     * This sample prints information about the firing trigger and records
+     * actions in an audit table. <p>
+     *
+     * The techniques used here are simplified dramatically for demonstration
+     * purposes and are in no way recommended as a model upon which to build
+     * actual installations involving triggered actions.
+     *
+     * @param typ trigger type
+     * @param trn trigger name
+     * @param tn  table name
+     * @param or  old row
+     * @param nr  new row
+     */
+    public void fire(int typ, String trn, String tn, Object[] or,
+                     Object[] nr) {
+
+        synchronized (TriggerSample.class) {
+            String ors = or == null ? "null"
+                                    : StringUtil.arrayToString(or);
+            String nrs = nr == null ? "null"
+                                    : StringUtil.arrayToString(nr);
+
+            out.println("----------------------------------------");
+            out.println(getTriggerDescriptor(trn, typ, tn));
+            out.println("old row : " + ors);
+            out.println("new row : " + nrs);
+            out.flush();
+
+            if ("TRIG_TEST".equals(tn)) {
+                switch (typ) {
+
+                    case INSERT_BEFORE_ROW : {
+
+                        // Business rule: ID shall be less than 11.
+                        // (Marti DiBergi, we love you ;-)
+                        // You can cast row[i] given your knowledge of what
+                        // the table format is:
+                        final int ID = ((Number) nr[0]).intValue();
+
+                        doAssert(ID < 11, "ID < 11");
+
+                        break;
+                    }
+                    case UPDATE_BEFORE_ROW : {
+
+                        // Business rule:  ignore update of VALUE 'unchangable'.
+                        if ("unchangable".equals(or[1])) {
+                            nr[1] = or[1];    // short-circuit the update
+                        }
+
+                        // !!!Warning!!!
+                        // The engine does not check the class of substituted
+                        // values; it's up to you to use the correct class.
+                        // For example, this will cause database curruption:
+                        //  nr[1] = new Integer(5);
+                        break;
+                    }
+                }
+            }
+
+            doAuditStep(typ, tn, ors, nrs);
+        }
+    }
+
+    private static void doAssert(boolean b, String msg) {
+
+        if (b) {
+
+            // do nothing
+        } else {
+            throw org.hsqldb.error.Error.error(ErrorCode.GENERAL_ERROR,
+                                               msg);
+        }
+    }
+
+    private static void doAuditStep(int typ, String tn, String ors,
+                                    String nrs) {
+
+        Connection        conn;
+        PreparedStatement stmt;
+
+        switch (typ) {
+
+            case INSERT_AFTER_ROW :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER_ROW : {
+                try {
+                    conn = getConnection();
+                    stmt = conn.prepareStatement(audit_insert_stmt);
+
+                    stmt.setString(1, getOperationSpec(typ));
+                    stmt.setString(2, tn);
+                    stmt.setString(3, ors);
+                    stmt.setString(4, nrs);
+                    stmt.executeUpdate();
+                    conn.close();
+                } catch (SQLException se) {
+                    se.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public static String getWhenSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_BEFORE_ROW :
+            case UPDATE_BEFORE_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "BEFORE";
+            }
+            case INSERT_AFTER :
+            case INSERT_AFTER_ROW :
+            case UPDATE_AFTER :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER :
+            case DELETE_AFTER_ROW : {
+                return "AFTER";
+            }
+            default : {
+                return "";
+            }
+        }
+    }
+
+    public static String getOperationSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_AFTER :
+            case INSERT_AFTER_ROW :
+            case INSERT_BEFORE_ROW : {
+                return "INSERT";
+            }
+            case UPDATE_AFTER :
+            case UPDATE_AFTER_ROW :
+            case UPDATE_BEFORE_ROW : {
+                return "UPDATE";
+            }
+            case DELETE_AFTER :
+            case DELETE_AFTER_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "DELETE";
+            }
+            default : {
+                return "";
+            }
+        }
+    }
+
+    public static String getQueueSpec(int qs) {
+        return (qs < 0) ? ""
+                        : ("QUEUE " + qs);
+    }
+
+    public static String getForEachSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_BEFORE_ROW :
+            case INSERT_AFTER_ROW :
+            case UPDATE_BEFORE_ROW :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "FOR EACH ROW";
+            }
+            default : {
+                return "FOR EACH STATEMENT";
+            }
+        }
+    }
+
+    public static String getTriggerDDL(String trn, int typ, String tab,
+                                       int qs,
+                                       String impl) throws SQLException {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("CREATE TRIGGER ");
+        sb.append(trn);
+        sb.append(' ');
+        sb.append(getWhenSpec(typ));
+        sb.append(' ');
+        sb.append(getOperationSpec(typ));
+        sb.append(" ON ");
+        sb.append(tab);
+        sb.append(' ');
+        sb.append(getForEachSpec(typ));
+        sb.append(' ');
+        sb.append(getQueueSpec(qs));
+        sb.append(" CALL \"");
+        sb.append(impl);
+        sb.append("\"");
+
+        return sb.toString();
+    }
+
+    public static String getTriggerDescriptor(String trn, int typ,
+            String tab) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("TRIGGER : ");
+        sb.append(trn);
+        sb.append(' ');
+        sb.append(getWhenSpec(typ));
+        sb.append(' ');
+        sb.append(getOperationSpec(typ));
+        sb.append(" ON ");
+        sb.append(tab);
+        sb.append(' ');
+        sb.append(getForEachSpec(typ));
+
+        return sb.toString();
+    }
+
+    private static Connection getConnection() throws SQLException {
+
+        try {
+            Class.forName(drv).newInstance();
+
+            return DriverManager.getConnection(url, usr, pwd);
+        } catch (SQLException se) {
+            throw se;
+        } catch (Exception e) {
+            throw new SQLException(e.toString());
+        }
+    }
+
+    private static void createTrigger(Statement stmt, String trn,
+                                      int typ) throws SQLException {
+        stmt.execute(getTriggerDDL(trn, typ, tn, 0, impl));
+    }
+
+    private static void setup() throws SQLException {
+
+        Connection conn = getConnection();
+        Statement  stmt = conn.createStatement();
+
+        stmt.execute(drop_test_table_stmt);
+        stmt.execute(create_test_table_stmt);
+        stmt.execute(drop_audit_table_stmt);
+        stmt.execute(create_audit_table_stmt);
+        createTrigger(stmt, "tibr_" + tn, INSERT_BEFORE_ROW);
+        createTrigger(stmt, "tia_" + tn, INSERT_AFTER);
+        createTrigger(stmt, "tiar_" + tn, INSERT_AFTER_ROW);
+        createTrigger(stmt, "tubr_" + tn, UPDATE_BEFORE_ROW);
+        createTrigger(stmt, "tua_" + tn, UPDATE_AFTER);
+        createTrigger(stmt, "tuar_" + tn, UPDATE_AFTER_ROW);
+        createTrigger(stmt, "tdbr_" + tn, DELETE_BEFORE_ROW);
+        createTrigger(stmt, "tda_" + tn, DELETE_AFTER);
+        createTrigger(stmt, "tdar_" + tn, DELETE_AFTER_ROW);
+        stmt.close();
+        conn.close();
+    }
+
+    private static void doSomeWork() throws SQLException {
+
+        Connection conn = getConnection();
+        Statement  stmt = conn.createStatement();
+
+        conn.setAutoCommit(false);
+        stmt.execute("INSERT INTO trig_test VALUES (1, 'hello')");
+        stmt.execute("INSERT INTO trig_test VALUES (2, 'now what?')");
+        stmt.execute("INSERT INTO trig_test VALUES (3, 'unchangable')");
+        stmt.execute("INSERT INTO trig_test VALUES (4, 'goodbye')");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.execute("UPDATE trig_test SET value = 'all done'");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.execute("DELETE FROM trig_test");
+        conn.rollback();
+        dumpTable("trig_test");
+
+        try {
+            stmt.execute("INSERT INTO trig_test VALUES(11, 'whatever')");
+        } catch (SQLException se) {
+            se.printStackTrace();
+        }
+
+        stmt.execute("INSERT INTO trig_test VALUES(10, 'whatever')");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.close();
+        conn.close();
+    }
+
+    private static void dumpTable(String tn) throws SQLException {
+
+        Connection        conn  = getConnection();
+        Statement         stmt  = conn.createStatement();
+        ResultSet         rs    = stmt.executeQuery("select * from " + tn);
+        ResultSetMetaData rsmd  = rs.getMetaData();
+        int               count = rsmd.getColumnCount();
+
+        out.println();
+        out.println("****************************************");
+        out.println("DUMP FOR TABLE: " + tn);
+        out.println("****************************************");
+        out.flush();
+
+        while (rs.next()) {
+            out.print("[");
+
+            for (int i = 1; i <= count; i++) {
+                out.print(rs.getString(i));
+
+                if (i < count) {
+                    out.print(" : ");
+                }
+            }
+
+            out.println("]");
+        }
+
+        out.println();
+        out.flush();
+        rs.close();
+        stmt.close();
+        conn.close();
+    }
+
+    private static void runSample() throws SQLException {
+
+        setup();
+        doSomeWork();
+        dumpTable("audit");
+    }
+
+    public static void main(String[] args) throws SQLException {
+        runSample();
+    }
+}
+/*
+    test SQL
+    CREATE CACHED TABLE trig_test (int_field     integer)
+    CREATE TRIGGER ins_before BEFORE INSERT ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER ins_after  AFTER  INSERT ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_before BEFORE UPDATE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_after  AFTER  UPDATE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_before_row BEFORE UPDATE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_after_row  AFTER  UPDATE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_before BEFORE DELETE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_after  AFTER  DELETE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_before_row BEFORE DELETE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_after_row  AFTER  DELETE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    INSERT INTO trig_test VALUES (1)
+    INSERT INTO trig_test VALUES (2)
+    INSERT INTO trig_test VALUES (3)
+    UPDATE trig_test SET int_field = int_field + 3
+    DELETE FROM trig_test
+ */
diff --git a/doc-src/verbatim/src/org/hsqldb/server/Servlet.java b/doc-src/verbatim/src/org/hsqldb/server/Servlet.java
new file mode 100644
index 0000000..e26635a
--- /dev/null
+++ b/doc-src/verbatim/src/org/hsqldb/server/Servlet.java
@@ -0,0 +1,320 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Session;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.rowio.RowInputBinary;
+import org.hsqldb.rowio.RowOutputBinary;
+
+// fredt@users 20020130 - patch 475586 by wreissen@users
+// fredt@users 20020328 - patch 1.7.0 by fredt - error trapping
+// fredt@users 20030630 - patch 1.7.2 - new protocol, persistent sessions
+// fredt@users 20041112 - patch by Willian Crick - use web_inf directory
+
+/**
+ * Servlet can act as an interface between the client and the database for the
+ * the client / server mode of HSQL Database Engine. It uses the HTTP protocol
+ * for communication. This class is not required if the included HSQLDB
+ * Weberver is used on the server host. But if the host is running a J2EE
+ * application server or a servlet container such as Tomcat, the Servlet class
+ * can be hosted on this server / container to serve external requests from
+ * external hosts.<p>
+ * The remote applet / application should
+ * use the normal JDBC interfaces to connect to the URL of this servlet. An
+ * example URL is:
+ * <pre>
+ * jdbc:hsqldb:http://myhost.com:8080/servlet/org.hsqldb.server.Servlet
+ * </pre>
+ * The database path/name is taken from the servlet engine property:
+ * <pre>
+ * hsqldb.server.database
+ * </pre>
+ * <p>
+ * If the database is deployed in the WEB-INF directory of the servlet container,
+ * the property:
+ * <pre>
+ *  hsqldb.server.use_web-inf_path
+ * </pre>
+ * should be set "true" in the web.xml file of the servlet container.
+ * In this case, the database path should begin with a "/".
+ *
+ * JDBC connections via the HTTP protocol are persistent
+ * in the JDBC sense. The JDBC Connection that is established can support
+ * transactions spanning several Statement calls and real PreparedStatement
+ * calls are supported. This class has been rewritten to support the new
+ * features.<p>
+ * (fredt@users)<p>
+ *
+ * Extensively rewritten for HSQLDB.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class Servlet extends javax.servlet.http.HttpServlet {
+
+    private static final int BUFFER_SIZE = 256;
+    private String           dbType;
+    private String           dbPath;
+    private String           errorStr;
+    private RowOutputBinary  rowOut;
+    private RowInputBinary   rowIn;
+    private int              iQueries;
+
+    public void init(ServletConfig config) {
+
+        try {
+            super.init(config);
+
+            rowOut = new RowOutputBinary(BUFFER_SIZE, 1);
+            rowIn  = new RowInputBinary(rowOut);
+        } catch (ServletException e) {
+            log(e.toString());
+        }
+
+        String dbStr = getInitParameter("hsqldb.server.database");
+
+        if (dbStr == null) {
+            dbStr = ".";
+        }
+
+// begin WEB-INF patch */
+        String useWebInfStr =
+            getInitParameter("hsqldb.server.use_web-inf_path");
+
+        if (!dbStr.equals(".") && "true".equalsIgnoreCase(useWebInfStr)) {
+            dbStr = getServletContext().getRealPath("/") + "WEB-INF/" + dbStr;
+        }
+
+// end WEB-INF patch
+        HsqlProperties dbURL = DatabaseURL.parseURL(dbStr, false, false);
+
+        log("Database filename = " + dbStr);
+
+        if (dbURL == null) {
+            errorStr = "Bad Database name";
+        } else {
+            dbPath = dbURL.getProperty("database");
+            dbType = dbURL.getProperty("connection_type");
+
+            try {
+
+// loosecannon1@users 1.7.2 patch properties on the JDBC URL
+                DatabaseManager.getDatabase(dbType, dbPath, dbURL);
+            } catch (HsqlException e) {
+                errorStr = e.getMessage();
+            }
+        }
+
+        log(errorStr);
+        log("Initialization completed.");
+    }
+
+    private static long lModified = 0;
+
+    protected long getLastModified(HttpServletRequest req) {
+
+        // this is made so that the cache of the http server is not used
+        // maybe there is some other way
+        return lModified++;
+    }
+
+    public void doGet(HttpServletRequest request,
+                      HttpServletResponse response)
+                      throws IOException, ServletException {
+
+        String query = request.getQueryString();
+
+        if ((query == null) || (query.length() == 0)) {
+            response.setContentType("text/html");
+
+// fredt@users 20020130 - patch 1.7.0 by fredt
+// to avoid caching on the browser
+            response.setHeader("Pragma", "no-cache");
+
+            PrintWriter out = response.getWriter();
+
+            out.println(
+                "<html><head><title>HSQL Database Engine Servlet</title>");
+            out.println("</head><body><h1>HSQL Database Engine Servlet</h1>");
+            out.println("The servlet is running.<p>");
+
+            if (errorStr == null) {
+                out.println("The database is also running.<p>");
+                out.println("Database name: " + dbType + dbPath + "<p>");
+                out.println("Queries processed: " + iQueries + "<p>");
+            } else {
+                out.println("<h2>The database is not running!</h2>");
+                out.println("The error message is:<p>");
+                out.println(errorStr);
+            }
+
+            out.println("</body></html>");
+        }
+    }
+
+    public void doPost(HttpServletRequest request,
+                       HttpServletResponse response)
+                       throws IOException, ServletException {
+
+        synchronized (this) {
+            DataInputStream  inStream = null;
+            DataOutputStream dataOut  = null;
+
+            try {
+
+                // fredt@users - the servlet container, Resin does not return all
+                // the bytes with one call to input.read(b,0,len) when len > 8192
+                // bytes, the loop in the Result.read() method handles this
+                inStream = new DataInputStream(request.getInputStream());
+
+                int  databaseID = inStream.readInt();
+                long sessionID  = inStream.readLong();
+                int  mode       = inStream.readByte();
+                Session session = DatabaseManager.getSession(databaseID,
+                    sessionID);
+                Result resultIn = Result.newResult(session, mode, inStream,
+                                                   rowIn);
+
+                resultIn.setDatabaseId(databaseID);
+                resultIn.setSessionId(sessionID);
+
+                Result resultOut;
+
+                if (resultIn.getType() == ResultConstants.CONNECT) {
+                    try {
+                        session = DatabaseManager.newSession(
+                            dbType, dbPath, resultIn.getMainString(),
+                            resultIn.getSubString(), new HsqlProperties(),
+                            resultIn.getZoneString(),
+                            resultIn.getUpdateCount());
+
+                        resultIn.readAdditionalResults(null, inStream, rowIn);
+
+                        resultOut = Result.newConnectionAcknowledgeResponse(
+                            session.getDatabase(), session.getId(),
+                            session.getDatabase().getDatabaseID());
+                    } catch (HsqlException e) {
+                        resultOut = Result.newErrorResult(e);
+                    }
+                } else {
+                    int  dbId      = resultIn.getDatabaseId();
+                    long sessionId = resultIn.getSessionId();
+
+                    session = DatabaseManager.getSession(dbId, sessionId);
+
+                    resultIn.readAdditionalResults(session, inStream, rowIn);
+
+                    resultOut = session.execute(resultIn);
+                }
+
+                //
+                response.setContentType("application/octet-stream");
+                response.setContentLength(rowOut.size());
+
+                //
+                dataOut = new DataOutputStream(response.getOutputStream());
+
+                resultOut.write(dataOut, rowOut);
+
+                iQueries++;
+            } catch (HsqlException e) {}
+            finally {
+                if (dataOut != null) {
+                    dataOut.close();
+                }
+
+                if (inStream != null) {
+                    inStream.close();
+                }
+            }
+        }
+
+        // Trace.printSystemOut("Queries processed: "+iQueries+"  \n");
+    }
+}
diff --git a/doc-src/verbatim/src/org/hsqldb/server/WebServer.java b/doc-src/verbatim/src/org/hsqldb/server/WebServer.java
new file mode 100644
index 0000000..b3ce0d7
--- /dev/null
+++ b/doc-src/verbatim/src/org/hsqldb/server/WebServer.java
@@ -0,0 +1,270 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.resources.BundleHandler;
+
+// fredt@users 20020215 - patch 1.7.0 by fredt
+// method rorganised to use new HsqlServerProperties class
+// unsaved@users 20021113 - patch 1.7.2 - SSL support
+// boucherb@users 20030510 - patch 1.7.2 - SSL support moved to factory interface
+// boucherb@users 20030510 - patch 1.7.2 - moved all common code to Server
+// boucherb@users 20030510 - patch 1.7.2 - general lint removal
+
+/**
+ *  The HSQLDB HTTP protocol network database server. <p>
+ *
+ *  WebServer has two distinct functions:<p>
+ *
+ *  The primary function is to allow client/server access to HSQLDB databases
+ *  via the HTTP protocol. This protocol is less efficient than the HSQL
+ *  protocol used by the Server class and should be used only in situations
+ *  where sandboxes or firewalls between the client and the server do not
+ *  allow the use of the HSQL protocol. One example is client/server access by
+ *  an applet running in browsers on remote hosts and accessing the database
+ *  engine on the HTTP server from which the applet originated. From version
+ *  1.7.2, HTTP database connections are persistent and support transactions.
+ *  Similar to HSQL connections, they should be explicitly closed to free the
+ *  server resources. <p>
+ *
+ *  The secondary function of WebServer is to act as a simple general purpose
+ *  HTTP server. It is aimed to support the minimum requirements set out by
+ *  the HTTP/1.0 standard. The HEAD and GET methods can be used to query and
+ *  retreive static files from the HTTP server.<p>
+ *
+ *  Both the database server and HTTP server functions of WebServer can be
+ *  configured with the webserver.properties file. It contains entries for the
+ *  database server similar to those for the HSQL protocol Server class. In
+ *  addition, a list mapping different file endings to their mime types may be
+ *  included in this file. (fredt@users) <p>
+ *
+ * From the command line, the options are as follows: <p>
+ * <pre>
+ * +-----------------+-------------+----------+------------------------------+
+ * |    OPTION       |    TYPE     | DEFAULT  |         DESCRIPTION          |
+ * +-----------------+-------------+----------+------------------------------|
+ * | --help          |             |          | prints this message          |
+ * | --address       | name|number | any      | server inet address          |
+ * | --port          | number      | 80       | port at which server listens |
+ * | --database.i    | [type]spec  | 0=test   | path of database i           |
+ * | --dbname.i      | alias       |          | url alias for database i     |
+ * | --silent        | true|false  | true     | false => display all queries |
+ * | --trace         | true|false  | false    | display JDBC trace messages  |
+ * | --no_system_exit| true|false  | false    | do not issue System.exit()   |
+ * +-----------------+-------------+----------+------------------------------+
+ * </pre>
+ *
+ *  Example of the webserver.properties file:
+ *
+ * <pre>
+ * server.port=80
+ * server.database.0=test
+ * server.dbname.0=...
+ * ...
+ * server.database.n=...
+ * server.dbname.n=...
+ * server.silent=true
+ *
+ * .htm=text/html
+ * .html=text/html
+ * .txt=text/plain
+ * .gif=image/gif
+ * .class=application/octet-stream
+ * .jpg=image/jpeg
+ * .jgep=image/jpeg
+ * .zip=application/x-zip-compressed
+ * </pre>
+ *
+ * <ul>
+ *   <li>For server.root, use '/'  as the separator, even for DOS/Windows.
+ *   <li>File extensions for mime types must be lowercase and start with '.'
+ * </ul>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class WebServer extends Server {
+
+    /**
+     * Handle to resource bundle providing i18n for things like
+     * HTTP error pages.
+     */
+    static int webBundleHandle = BundleHandler.getBundleHandle("webserver",
+        null);
+
+    public WebServer() {
+        super(ServerConstants.SC_PROTOCOL_HTTP);
+    }
+
+    /**
+     *  Starts a new WebServer.
+     *
+     * @param  args the "command line" parameters with which to start
+     *      the WebServer.  "-?" will cause the command line arguments
+     *      help to be printed to the standard output
+     */
+    public static void main(String[] args) {
+
+        String propsPath =
+            FileUtil.getFileUtil().canonicalOrAbsolutePath("webserver");
+        ServerProperties fileProps = ServerConfiguration.getPropertiesFromFile(
+            ServerConstants.SC_PROTOCOL_HTTP, propsPath);
+        ServerProperties props =
+            fileProps == null
+            ? new ServerProperties(ServerConstants.SC_PROTOCOL_HTTP)
+            : fileProps;
+        HsqlProperties stringProps = null;
+
+        stringProps = HsqlProperties.argArrayToProps(args,
+                ServerConstants.SC_KEY_PREFIX);
+
+        if (stringProps.getErrorKeys().length != 0) {
+            printHelp("webserver.help");
+
+            return;
+        }
+
+        props.addProperties(stringProps);
+        ServerConfiguration.translateDefaultDatabaseProperty(props);
+
+        // Standard behaviour when started from the command line
+        // is to halt the VM when the server shuts down.  This may, of
+        // course, be overridden by whatever, if any, security policy
+        // is in place.
+        ServerConfiguration.translateDefaultNoSystemExitProperty(props);
+
+        // finished setting up properties;
+        Server server = new WebServer();
+
+        try {
+            server.setProperties(props);
+            props.validate();
+
+            // This must be called after setProperties, because stringProps
+            // isn't populated until then.
+        } catch (Exception e) {
+            server.printError("Failed to set properties");
+            server.printStackTrace(e);
+
+            return;
+        }
+
+        // now messages go to the channel specified in properties
+        server.print("Startup sequence initiated from main() method");
+
+        if (fileProps != null) {
+            server.print("Loaded properties from [" + propsPath
+                         + ".properties]");
+        } else {
+            server.print("Could not load properties from file");
+            server.print("Using cli/default properties only");
+        }
+
+        server.start();
+    }
+
+    /**
+     * Retrieves the name of the web page served when no page is specified.
+     * This attribute is relevant only when server protocol is HTTP(S).
+     *
+     * @return the name of the web page served when no page is specified
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Used when server protocol is HTTP(S)"
+     */
+    public String getDefaultWebPage() {
+        return serverProperties.getProperty(
+            ServerConstants.SC_KEY_WEB_DEFAULT_PAGE);
+    }
+
+    /**
+     * Retrieves a String object describing the command line and
+     * properties options for this Server.
+     *
+     * @return the command line and properties options help for this Server
+     */
+    public String getHelpString() {
+        return BundleHandler.getString(serverBundleHandle, "webserver.help");
+    }
+
+    /**
+     * Retrieves this server's product name.  <p>
+     *
+     * Typically, this will be something like: "HSQLDB xxx server".
+     *
+     * @return the product name of this server
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Of Server"
+     */
+    public String getProductName() {
+        return "HSQLDB web server";
+    }
+
+    /**
+     * Retrieves a string respresentaion of the network protocol
+     * this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.
+     *
+     * @return string respresentation of this server's protocol
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Used to handle connections"
+     */
+    public String getProtocol() {
+        return isTls() ? "HTTPS"
+                       : "HTTP";
+    }
+
+    /**
+     * Retrieves the root context (directory) from which web content
+     * is served.  This property is relevant only when the server
+     * protocol is HTTP(S).  Although unlikely, it may be that in the future
+     * other contexts, such as jar urls may be supported, so that pages can
+     * be served from the contents of a jar or from the JVM class path.
+     *
+     * @return the root context (directory) from which web content is served
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Context (directory)"
+     */
+    public String getWebRoot() {
+        return serverProperties.getProperty(ServerConstants.SC_KEY_WEB_ROOT);
+    }
+}
diff --git a/doc-src/verbatim/src/org/hsqldb/test/TestBase.java b/doc-src/verbatim/src/org/hsqldb/test/TestBase.java
new file mode 100644
index 0000000..1ecb4c9
--- /dev/null
+++ b/doc-src/verbatim/src/org/hsqldb/test/TestBase.java
@@ -0,0 +1,155 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.lang.reflect.Constructor;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import org.hsqldb.server.Server;
+import org.hsqldb.server.WebServer;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * HSQLDB TestBugBase Junit test case. <p>
+ *
+ * @author  boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public abstract class TestBase extends TestCase {
+
+    //  change the url to reflect your preferred db location and name
+    String  serverProps;
+    String  url;
+    String  user     = "sa";
+    String  password = "";
+    Server  server;
+    boolean isNetwork = true;
+    boolean isHTTP    = false;
+
+    public TestBase(String name) {
+        super(name);
+    }
+
+    public TestBase(String name, String url, boolean isNetwork,
+                    boolean isHTTP) {
+
+        super(name);
+
+        this.isNetwork = isNetwork;
+        this.url       = url;
+        this.isHTTP    = isHTTP;
+    }
+
+    protected void setUp() {
+
+        if (isNetwork) {
+            if (url == null) {
+                url = isHTTP ? "jdbc:hsqldb:http://localhost/test"
+                             : "jdbc:hsqldb:hsql://localhost/test";
+            }
+
+            server = isHTTP ? new WebServer()
+                            : new Server();
+
+            server.setDatabaseName(0, "test");
+            server.setDatabasePath(0, "mem:test;sql.enforce_strict_size=true");
+            server.setLogWriter(null);
+            server.setErrWriter(null);
+            server.start();
+        } else {
+            if (url == null) {
+                url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
+            }
+        }
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println(this + ".setUp() error: " + e.getMessage());
+        }
+    }
+
+    protected void tearDown() {
+
+        if (isNetwork) {
+            server.stop();
+
+            server = null;
+        }
+    }
+
+    Connection newConnection() throws SQLException {
+        return DriverManager.getConnection(url, user, password);
+    }
+
+    public static void runWithResult(Class testCaseClass, String testName) {
+
+        try {
+            Constructor ctor = testCaseClass.getConstructor(new Class[]{
+                String.class });
+            TestBase theTest = (TestBase) ctor.newInstance(new Object[]{
+                testName });
+
+            theTest.runWithResult();
+        } catch (Exception ex) {
+            System.err.println("couldn't execute test:");
+            ex.printStackTrace(System.err);
+        }
+    }
+
+    public void runWithResult() {
+
+        TestResult result   = run();
+        String     testName = this.getClass().getName();
+
+        if (testName.startsWith("org.hsqldb.test.")) {
+            testName = testName.substring(16);
+        }
+
+        testName += "." + getName();
+
+        int failureCount = result.failureCount();
+
+        System.out.println(testName + " failure count: " + failureCount);
+
+        java.util.Enumeration failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.err.println(failures.nextElement());
+        }
+    }
+}
diff --git a/doc-src/verbatim/testrun/sqltool/sqljrt.sql b/doc-src/verbatim/testrun/sqltool/sqljrt.sql
new file mode 100644
index 0000000..2068480
--- /dev/null
+++ b/doc-src/verbatim/testrun/sqltool/sqljrt.sql
@@ -0,0 +1,17 @@
+/*
+ * $Id: sqljrt.sql 3353 2009-12-15 19:52:13Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create function dehex(VARCHAR(80), INTEGER)
+    returns INTEGER
+    no sql
+    language java
+    external name 'CLASSPATH:java.lang.Integer.valueOf'
+.;
+
+CALL dehex('12', 16);
+*if (*? != 18)
+    \q SQL/JRT function failed
+*end if
diff --git a/doc-src/verbatim/testrun/sqltool/sqlpsm.sql b/doc-src/verbatim/testrun/sqltool/sqlpsm.sql
new file mode 100644
index 0000000..7462e4d
--- /dev/null
+++ b/doc-src/verbatim/testrun/sqltool/sqlpsm.sql
@@ -0,0 +1,27 @@
+/*
+ * $Id: sqlpsm.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create table customers(
+    id INTEGER default 0, firstname VARCHAR(50), lastname VARCHAR(50),
+    entrytime TIMESTAMP);
+
+create procedure new_customer(firstname varchar(50), lastname varchar(50))
+    modifies sql data
+    insert into customers values (
+        default, firstname, lastname, current_timestamp)
+.;
+
+SELECT count(*) FROM customers;
+*if (*? != 0)
+    \q SQL/PSM preparation failed
+*end if
+
+CALL new_customer('blaine', 'simpson');
+
+SELECT count(*) FROM customers;
+*if (*? != 1)
+    \q SQL/PSM procedure failed
+*end if
diff --git a/doc/apidocs/allclasses-frame.html b/doc/apidocs/allclasses-frame.html
new file mode 100644
index 0000000..4d904b8
--- /dev/null
+++ b/doc/apidocs/allclasses-frame.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+All Classes (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameHeadingFont">
+<B>All Classes</B></FONT>
+<BR>
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc" target="classFrame">BlobInputStream</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc" target="classFrame">ClobInputStream</A>
+<BR>
+<A HREF="org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar" target="classFrame">DbBackup</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCArray</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCBlob</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCBlobClient</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCCallableStatement</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCClob</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCClobClient</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCColumnMetaData</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCConnection</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDatabaseMetaData</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDataSource</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDataSourceFactory</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDriver</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDriver</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCNClob</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCParameterMetaData</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCPreparedStatement</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCResultSet</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCResultSetMetaData</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCRowId</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCSavepoint</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCSQLXML</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCStatement</A>
+<BR>
+<A HREF="org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util" target="classFrame">MainInvoker</A>
+<BR>
+<A HREF="org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib" target="classFrame">RCData</A>
+<BR>
+<A HREF="org/hsqldb/server/Server.html" title="class in org.hsqldb.server" target="classFrame">Server</A>
+<BR>
+<A HREF="org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server" target="classFrame">ServerAcl</A>
+<BR>
+<A HREF="org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server" target="classFrame">ServerAcl.AclFormatException</A>
+<BR>
+<A HREF="org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline" target="classFrame">SqlFile</A>
+<BR>
+<A HREF="org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample" target="classFrame">SqlFileEmbedder</A>
+<BR>
+<A HREF="org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline" target="classFrame">SqlTool</A>
+<BR>
+<A HREF="org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline" target="classFrame">SqlTool.SqlToolException</A>
+<BR>
+<A HREF="org/hsqldb/Trigger.html" title="interface in org.hsqldb" target="classFrame"><I>Trigger</I></A>
+<BR>
+<A HREF="org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample" target="classFrame">TriggerSample</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc" target="classFrame">Util</A>
+<BR>
+<A HREF="org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server" target="classFrame">WebServer</A>
+<BR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/allclasses-noframe.html b/doc/apidocs/allclasses-noframe.html
new file mode 100644
index 0000000..c3d159e
--- /dev/null
+++ b/doc/apidocs/allclasses-noframe.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+All Classes (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameHeadingFont">
+<B>All Classes</B></FONT>
+<BR>
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc">BlobInputStream</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc">ClobInputStream</A>
+<BR>
+<A HREF="org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc">JDBCDataSourceFactory</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc">JDBCNClob</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc">JDBCSavepoint</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<BR>
+<A HREF="org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util">MainInvoker</A>
+<BR>
+<A HREF="org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<BR>
+<A HREF="org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<BR>
+<A HREF="org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<BR>
+<A HREF="org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A>
+<BR>
+<A HREF="org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<BR>
+<A HREF="org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample">SqlFileEmbedder</A>
+<BR>
+<A HREF="org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<BR>
+<A HREF="org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">SqlTool.SqlToolException</A>
+<BR>
+<A HREF="org/hsqldb/Trigger.html" title="interface in org.hsqldb"><I>Trigger</I></A>
+<BR>
+<A HREF="org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<BR>
+<A HREF="org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<BR>
+<A HREF="org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A>
+<BR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/constant-values.html b/doc/apidocs/constant-values.html
new file mode 100644
index 0000000..e39b23c
--- /dev/null
+++ b/doc/apidocs/constant-values.html
@@ -0,0 +1,415 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Constant Field Values (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Constant Field Values (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?constant-values.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="constant-values.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H1>
+Constant Field Values</H1>
+</CENTER>
+<HR SIZE="4" NOSHADE>
+<B>Contents</B><UL>
+<LI><A HREF="#org.hsqldb">org.hsqldb.*</A>
+</UL>
+
+<A NAME="org.hsqldb"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left"><FONT SIZE="+2">
+org.hsqldb.*</FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.hsqldb.<A HREF="org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.DELETE_AFTER"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#DELETE_AFTER">DELETE_AFTER</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.DELETE_AFTER_ROW"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#DELETE_AFTER_ROW">DELETE_AFTER_ROW</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.DELETE_BEFORE_ROW"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#DELETE_BEFORE_ROW">DELETE_BEFORE_ROW</A></CODE></TD>
+<TD ALIGN="right"><CODE>7</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.INSERT_AFTER"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#INSERT_AFTER">INSERT_AFTER</A></CODE></TD>
+<TD ALIGN="right"><CODE>0</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.INSERT_AFTER_ROW"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#INSERT_AFTER_ROW">INSERT_AFTER_ROW</A></CODE></TD>
+<TD ALIGN="right"><CODE>3</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.INSERT_BEFORE_ROW"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#INSERT_BEFORE_ROW">INSERT_BEFORE_ROW</A></CODE></TD>
+<TD ALIGN="right"><CODE>6</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.UPDATE_AFTER"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#UPDATE_AFTER">UPDATE_AFTER</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.UPDATE_AFTER_ROW"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#UPDATE_AFTER_ROW">UPDATE_AFTER_ROW</A></CODE></TD>
+<TD ALIGN="right"><CODE>5</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.Trigger.UPDATE_BEFORE_ROW"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/Trigger.html#UPDATE_BEFORE_ROW">UPDATE_BEFORE_ROW</A></CODE></TD>
+<TD ALIGN="right"><CODE>8</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.hsqldb.cmdline.<A HREF="org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.cmdline.SqlTool.CONNECTERR_EXITVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/cmdline/SqlTool.html#CONNECTERR_EXITVAL">CONNECTERR_EXITVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>7</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.cmdline.SqlTool.FILEERR_EXITVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/cmdline/SqlTool.html#FILEERR_EXITVAL">FILEERR_EXITVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>5</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.cmdline.SqlTool.INPUTERR_EXITVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/cmdline/SqlTool.html#INPUTERR_EXITVAL">INPUTERR_EXITVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>6</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.cmdline.SqlTool.IOERR_EXITVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/cmdline/SqlTool.html#IOERR_EXITVAL">IOERR_EXITVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.cmdline.SqlTool.RCERR_EXITVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/cmdline/SqlTool.html#RCERR_EXITVAL">RCERR_EXITVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.cmdline.SqlTool.SQLERR_EXITVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/cmdline/SqlTool.html#SQLERR_EXITVAL">SQLERR_EXITVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>3</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.cmdline.SqlTool.SQLTOOLERR_EXITVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/cmdline/SqlTool.html#SQLTOOLERR_EXITVAL">SQLTOOLERR_EXITVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.cmdline.SqlTool.SYNTAXERR_EXITVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/cmdline/SqlTool.html#SYNTAXERR_EXITVAL">SYNTAXERR_EXITVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>11</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCBlob.MAX_POS"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;long</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCBlob.html#MAX_POS">MAX_POS</A></CODE></TD>
+<TD ALIGN="right"><CODE>2147483648L</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCBlob.MIN_POS"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;long</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCBlob.html#MIN_POS">MIN_POS</A></CODE></TD>
+<TD ALIGN="right"><CODE>1L</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCDatabaseMetaData.JDBC_MAJOR"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCDatabaseMetaData.html#JDBC_MAJOR">JDBC_MAJOR</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.CLOSE_CURSORS_AT_COMMIT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#CLOSE_CURSORS_AT_COMMIT">CLOSE_CURSORS_AT_COMMIT</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.CONCUR_READ_ONLY"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#CONCUR_READ_ONLY">CONCUR_READ_ONLY</A></CODE></TD>
+<TD ALIGN="right"><CODE>1007</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.CONCUR_UPDATABLE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#CONCUR_UPDATABLE">CONCUR_UPDATABLE</A></CODE></TD>
+<TD ALIGN="right"><CODE>1008</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.FETCH_FORWARD"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#FETCH_FORWARD">FETCH_FORWARD</A></CODE></TD>
+<TD ALIGN="right"><CODE>1000</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.FETCH_REVERSE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#FETCH_REVERSE">FETCH_REVERSE</A></CODE></TD>
+<TD ALIGN="right"><CODE>1001</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.FETCH_UNKNOWN"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#FETCH_UNKNOWN">FETCH_UNKNOWN</A></CODE></TD>
+<TD ALIGN="right"><CODE>1002</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.HOLD_CURSORS_OVER_COMMIT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#HOLD_CURSORS_OVER_COMMIT">HOLD_CURSORS_OVER_COMMIT</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.TYPE_FORWARD_ONLY"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#TYPE_FORWARD_ONLY">TYPE_FORWARD_ONLY</A></CODE></TD>
+<TD ALIGN="right"><CODE>1003</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.TYPE_SCROLL_INSENSITIVE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#TYPE_SCROLL_INSENSITIVE">TYPE_SCROLL_INSENSITIVE</A></CODE></TD>
+<TD ALIGN="right"><CODE>1004</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.jdbc.JDBCResultSet.TYPE_SCROLL_SENSITIVE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#TYPE_SCROLL_SENSITIVE">TYPE_SCROLL_SENSITIVE</A></CODE></TD>
+<TD ALIGN="right"><CODE>1005</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.hsqldb.lib.<A HREF="org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.hsqldb.lib.RCData.DEFAULT_JDBC_DRIVER"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/hsqldb/lib/RCData.html#DEFAULT_JDBC_DRIVER">DEFAULT_JDBC_DRIVER</A></CODE></TD>
+<TD ALIGN="right"><CODE>"org.hsqldb.jdbc.JDBCDriver"</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?constant-values.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="constant-values.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/deprecated-list.html b/doc/apidocs/deprecated-list.html
new file mode 100644
index 0000000..af856d6
--- /dev/null
+++ b/doc/apidocs/deprecated-list.html
@@ -0,0 +1,190 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Deprecated List (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Deprecated List (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?deprecated-list.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="deprecated-list.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Deprecated API</B></H2>
+</CENTER>
+<HR SIZE="4" NOSHADE>
+<B>Contents</B><UL>
+<LI><A HREF="#method">Deprecated Methods</A>
+</UL>
+
+<A NAME="method"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Deprecated Methods</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(int, int)">org.hsqldb.jdbc.JDBCResultSet.getBigDecimal(int, int)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>by java.sun.com as of JDK 1.2</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/hsqldb/jdbc/JDBCCallableStatement.html#getBigDecimal(int, int)">org.hsqldb.jdbc.JDBCCallableStatement.getBigDecimal(int, int)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>use <code>getBigDecimal(int parameterIndex)</code>
+             or <code>getBigDecimal(String parameterName)</code></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(java.lang.String, int)">org.hsqldb.jdbc.JDBCResultSet.getBigDecimal(String, int)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>by java.sun.com as of JDK 1.2</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#getUnicodeStream(int)">org.hsqldb.jdbc.JDBCResultSet.getUnicodeStream(int)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>use <code>getCharacterStream</code> in place of
+              <code>getUnicodeStream</code></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/hsqldb/jdbc/JDBCResultSet.html#getUnicodeStream(java.lang.String)">org.hsqldb.jdbc.JDBCResultSet.getUnicodeStream(String)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>use <code>getCharacterStream</code> instead</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/hsqldb/jdbc/JDBCPreparedStatement.html#setUnicodeStream(int, java.io.InputStream, int)">org.hsqldb.jdbc.JDBCPreparedStatement.setUnicodeStream(int, InputStream, int)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Sun does not include a reason, but presumably
+      this is because setCharacterStream is now prefered</I>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?deprecated-list.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="deprecated-list.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/help-doc.html b/doc/apidocs/help-doc.html
new file mode 100644
index 0000000..3b784c3
--- /dev/null
+++ b/doc/apidocs/help-doc.html
@@ -0,0 +1,224 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+API Help (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="API Help (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?help-doc.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="help-doc.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H1>
+How This API Document Is Organized</H1>
+</CENTER>
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.<H3>
+Overview</H3>
+<BLOCKQUOTE>
+
+<P>
+The <A HREF="overview-summary.html">Overview</A> page is the front page of this API document and provides a list of all packages with a summary for each.  This page can also contain an overall description of the set of packages.</BLOCKQUOTE>
+<H3>
+Package</H3>
+<BLOCKQUOTE>
+
+<P>
+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:<UL>
+<LI>Interfaces (italic)<LI>Classes<LI>Enums<LI>Exceptions<LI>Errors<LI>Annotation Types</UL>
+</BLOCKQUOTE>
+<H3>
+Class/Interface</H3>
+<BLOCKQUOTE>
+
+<P>
+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:<UL>
+<LI>Class inheritance diagram<LI>Direct Subclasses<LI>All Known Subinterfaces<LI>All Known Implementing Classes<LI>Class/interface declaration<LI>Class/interface description
+<P>
+<LI>Nested Class Summary<LI>Field Summary<LI>Constructor Summary<LI>Method Summary
+<P>
+<LI>Field Detail<LI>Constructor Detail<LI>Method Detail</UL>
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</BLOCKQUOTE>
+</BLOCKQUOTE>
+<H3>
+Annotation Type</H3>
+<BLOCKQUOTE>
+
+<P>
+Each annotation type has its own separate page with the following sections:<UL>
+<LI>Annotation Type declaration<LI>Annotation Type description<LI>Required Element Summary<LI>Optional Element Summary<LI>Element Detail</UL>
+</BLOCKQUOTE>
+</BLOCKQUOTE>
+<H3>
+Enum</H3>
+<BLOCKQUOTE>
+
+<P>
+Each enum has its own separate page with the following sections:<UL>
+<LI>Enum declaration<LI>Enum description<LI>Enum Constant Summary<LI>Enum Constant Detail</UL>
+</BLOCKQUOTE>
+<H3>
+Use</H3>
+<BLOCKQUOTE>
+Each documented package, class and interface has its own Use page.  This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A.  You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.</BLOCKQUOTE>
+<H3>
+Tree (Class Hierarchy)</H3>
+<BLOCKQUOTE>
+There is a <A HREF="overview-tree.html">Class Hierarchy</A> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.<UL>
+<LI>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.<LI>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</UL>
+</BLOCKQUOTE>
+<H3>
+Deprecated API</H3>
+<BLOCKQUOTE>
+The <A HREF="deprecated-list.html">Deprecated API</A> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</BLOCKQUOTE>
+<H3>
+Index</H3>
+<BLOCKQUOTE>
+The <A HREF="index-all.html">Index</A> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</BLOCKQUOTE>
+<H3>
+Prev/Next</H3>
+These links take you to the next or previous class, interface, package, or related page.<H3>
+Frames/No Frames</H3>
+These links show and hide the HTML frames.  All pages are available with or without frames.
+<P>
+<H3>
+Serialized Form</H3>
+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+<P>
+<H3>
+Constant Field Values</H3>
+The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.
+<P>
+<FONT SIZE="-1">
+<EM>
+This help file applies to API documentation generated using the standard doclet.</EM>
+</FONT>
+<BR>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?help-doc.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="help-doc.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/hsqldb.gif b/doc/apidocs/hsqldb.gif
new file mode 100644
index 0000000..3585222
--- /dev/null
+++ b/doc/apidocs/hsqldb.gif
Binary files differ
diff --git a/doc/apidocs/index-all.html b/doc/apidocs/index-all.html
new file mode 100644
index 0000000..826abd1
--- /dev/null
+++ b/doc/apidocs/index-all.html
@@ -0,0 +1,4250 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Index (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="./javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Index (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="./overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="./overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="./deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="./help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="./index.html?index-all.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="index-all.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="./allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="./allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<A HREF="#_A_">A</A> <A HREF="#_B_">B</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_F_">F</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_J_">J</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_P_">P</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_W_">W</A> <HR>
+<A NAME="_A_"><!-- --></A><H2>
+<B>A</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#absolute(int)"><B>absolute(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor to the given row number in
+ this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#acceptsURL(java.lang.String)"><B>acceptsURL(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Returns true if the driver thinks that it can open a connection to
+  the given URL.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#acceptsURL(java.lang.String)"><B>acceptsURL(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Returns true if the driver thinks that it can open a connection to
+  the given URL.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#addBatch()"><B>addBatch()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Adds a set of parameters to this <code>PreparedStatement</code>
+ object's batch of commands.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#addBatch(java.lang.String)"><B>addBatch(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>This method should always throw if called for a PreparedStatement or
+ CallableStatment.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#addBatch(java.lang.String)"><B>addBatch(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Adds the given SQL command to the current list of commmands for this
+ <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#addMacros(java.util.Map)"><B>addMacros(Map&lt;String, Token&gt;)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#addUserVars(java.util.Map)"><B>addUserVars(Map&lt;String, String&gt;)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#afterLast()"><B>afterLast()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor to the end of
+ this <code>ResultSet</code> object, just after the
+ last row.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#allProceduresAreCallable()"><B>allProceduresAreCallable()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether the current user can call all the procedures
+ returned by the method <code>getProcedures</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#allTablesAreSelectable()"><B>allTablesAreSelectable()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether the current user can use all the tables returned
+ by the method <code>getTables</code> in a <code>SELECT</code>
+ statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#autoCommitFailureClosesAllResultSets()"><B>autoCommitFailureClosesAllResultSets()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a <code>SQLException</code> while autoCommit is <code>true</code> inidcates
+ that all open ResultSets are closed, even ones that are holdable.
+<DT><A HREF="./org/hsqldb/jdbc/BlobInputStream.html#available()"><B>available()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc">BlobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/ClobInputStream.html#available()"><B>available()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc">ClobInputStream</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_B_"><!-- --></A><H2>
+<B>B</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#beforeFirst()"><B>beforeFirst()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor to the front of
+ this <code>ResultSet</code> object, just before the
+ first row.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#bitCharsToBytes(java.lang.String)"><B>bitCharsToBytes(String)</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Just a stub for now.
+<DT><A HREF="./org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc"><B>BlobInputStream</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>This class is used as an InputStream to retrieve data from a Blob.<DT><A HREF="./org/hsqldb/jdbc/BlobInputStream.html#BlobInputStream(org.hsqldb.jdbc.JDBCBlobClient, long, long, int)"><B>BlobInputStream(JDBCBlobClient, long, long, int)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc">BlobInputStream</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_C_"><!-- --></A><H2>
+<B>C</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#cancel()"><B>cancel()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Cancels this <code>Statement</code> object if both the DBMS and
+ driver support aborting an SQL statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#cancel()"><B>cancel()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Cancels this <code>Statement</code> object if both the DBMS and
+ driver support aborting an SQL statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#cancelRowUpdates()"><B>cancelRowUpdates()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Cancels the updates made to the current row in this
+ <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#canDisplayType(int)"><B>canDisplayType(int)</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>This method is used to tell SqlFile whether this Sql Type must
+ ALWAYS be loaded to the binary buffer without displaying.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#catalogName"><B>catalogName</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The column's table's catalog name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#characters(char[], int, int)"><B>characters(char[], int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive notification of character data.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#charset"><B>charset</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/Server.html#checkRunning(boolean)"><B>checkRunning(boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Checks if this Server object is or is not running and throws if the
+ current state does not match the specified value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#clearBatch()"><B>clearBatch()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Empties this <code>Statement</code> object's current list of
+ SQL commands.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#clearBatch()"><B>clearBatch()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Empties this <code>Statement</code> object's current list of
+ SQL commands.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#clearParameters()"><B>clearParameters()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Clears the current parameter values immediately.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#clearWarnings()"><B>clearWarnings()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Clears all warnings reported for this <code>Connection</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#clearWarnings()"><B>clearWarnings()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Clears all the warnings reported on this <code>Statement</code>
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#clearWarnings()"><B>clearWarnings()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Clears all warnings reported on this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#clearWarnings()"><B>clearWarnings()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Clears all the warnings reported on this <code>Statement</code>
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><B>ClobInputStream</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>This class is used as an InputStream to retrieve data from a Blob.<DT><A HREF="./org/hsqldb/jdbc/ClobInputStream.html#ClobInputStream(org.hsqldb.jdbc.JDBCClobClient, long, long, int)"><B>ClobInputStream(JDBCClobClient, long, long, int)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc">ClobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/BlobInputStream.html#close()"><B>close()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc">BlobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/ClobInputStream.html#close()"><B>close()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc">ClobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#close()"><B>close()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Does the specialized work required to free this object's resources and
+ that of it's parent classes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#close()"><B>close()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Releases this <code>Connection</code> object's database and JDBC resources
+ immediately instead of waiting for them to be automatically released.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#close()"><B>close()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Does the specialized work required to free this object's resources and
+ that of it's parent class.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#close()"><B>close()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Releases this <code>ResultSet</code> object's database and
+ JDBC resources immediately instead of waiting for
+ this to happen when it is automatically closed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#close()"><B>close()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Closes this object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#close()"><B>close()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Releases this <code>Statement</code> object's database
+ and JDBC resources immediately instead of waiting for
+ this to happen when it is automatically closed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#CLOSE_CURSORS_AT_COMMIT"><B>CLOSE_CURSORS_AT_COMMIT</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#closeReader()"><B>closeReader()</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Close the reader.
+<DT><A HREF="./org/hsqldb/server/ServerAcl.html#colonNotation(byte[])"><B>colonNotation(byte[])</B></A> - 
+Static method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#columnClassName"><B>columnClassName</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The fully-qualified name of the Java class whose instances are
+ manufactured if the method ResultSet.getObject is called to retrieve
+ a value from the column.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#columnDisplaySize"><B>columnDisplaySize</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The column's normal max width in chars.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#columnLabel"><B>columnLabel</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The suggested column title for use in printouts and displays.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#columnName"><B>columnName</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The column's name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#columnType"><B>columnType</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The column's SQL type.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#comment(char[], int, int)"><B>comment(char[], int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#commit()"><B>commit()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Makes all changes made since the previous
+ commit/rollback permanent and releases any database locks
+ currently held by this <code>Connection</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#CONCUR_READ_ONLY"><B>CONCUR_READ_ONLY</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#CONCUR_UPDATABLE"><B>CONCUR_UPDATABLE</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#connect(java.lang.String, java.util.Properties)"><B>connect(String, Properties)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Attempts to make a database connection to the given URL.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#connect(java.lang.String, java.util.Properties)"><B>connect(String, Properties)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Attempts to make a database connection to the given URL.
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#CONNECTERR_EXITVAL"><B>CONNECTERR_EXITVAL</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#connectionClosedException()"><B>connectionClosedException()</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#convertEscapes(java.lang.String)"><B>convertEscapes(String)</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Translates user-supplied escapes into the traditionaly corresponding
+ corresponding binary characters.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createArrayOf(java.lang.String, java.lang.Object[])"><B>createArrayOf(String, Object[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Factory method for creating Array objects.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createBlob()"><B>createBlob()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Constructs an object that implements the <code>Blob</code> interface.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createClob()"><B>createClob()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Constructs an object that implements the <code>Clob</code> interface.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createNClob()"><B>createNClob()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Constructs an object that implements the <code>NClob</code> interface.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createSQLXML()"><B>createSQLXML()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Constructs an object that implements the <code>SQLXML</code> interface.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createStatement()"><B>createStatement()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>Statement</code> object for sending
+ SQL statements to the database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createStatement(int, int)"><B>createStatement(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>Statement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createStatement(int, int, int)"><B>createStatement(int, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>Statement</code> object that will generate
+ <code>ResultSet</code> objects with the given type, concurrency,
+ and holdability.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#createStruct(java.lang.String, java.lang.Object[])"><B>createStruct(String, Object[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Factory method for creating Struct objects.
+</DL>
+<HR>
+<A NAME="_D_"><!-- --></A><H2>
+<B>D</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#dataDefinitionCausesTransactionCommit()"><B>dataDefinitionCausesTransactionCommit()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a data definition statement within a transaction forces
+ the transaction to commit.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#dataDefinitionIgnoredInTransactions()"><B>dataDefinitionIgnoredInTransactions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database ignores a data definition statement
+ within a transaction.
+<DT><A HREF="./org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar"><B>DbBackup</B></A> - Class in <A HREF="./org/hsqldb/lib/tar/package-summary.html">org.hsqldb.lib.tar</A><DD>Works with tar archives containing HSQLDB database instance backups.<DT><A HREF="./org/hsqldb/lib/tar/DbBackup.html#DbBackup(java.io.File, java.lang.String)"><B>DbBackup(File, String)</B></A> - 
+Constructor for class org.hsqldb.lib.tar.<A HREF="./org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A>
+<DD>Instantiate a DbBackup instance for creating a Database Instance backup.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#DEFAULT_JDBC_DRIVER"><B>DEFAULT_JDBC_DRIVER</B></A> - 
+Static variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#DEFAULT_RCFILE"><B>DEFAULT_RCFILE</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html#DELETE_AFTER"><B>DELETE_AFTER</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html#DELETE_AFTER_ROW"><B>DELETE_AFTER_ROW</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html#DELETE_BEFORE_ROW"><B>DELETE_BEFORE_ROW</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#deleteRow()"><B>deleteRow()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Deletes the current row from this <code>ResultSet</code> object
+ and from the underlying database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#deletesAreDetected(int)"><B>deletesAreDetected(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether or not a visible row delete can be detected by
+ calling the method <code>ResultSet.rowDeleted</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#doesMaxRowSizeIncludeBlobs()"><B>doesMaxRowSizeIncludeBlobs()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether the return value for the method
+ <code>getMaxRowSize</code> includes the SQL data types
+ <code>LONGVARCHAR</code> and <code>LONGVARBINARY</code>.
+<DT><A HREF="./org/hsqldb/server/ServerAcl.html#dottedNotation(byte[])"><B>dottedNotation(byte[])</B></A> - 
+Static method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/lib/RCData.html#driver"><B>driver</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#dsvSafe(java.lang.String)"><B>dsvSafe(String)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Validate that String is safe to write TO DSV file.
+</DL>
+<HR>
+<A NAME="_E_"><!-- --></A><H2>
+<B>E</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endDocument()"><B>endDocument()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive notification of the end of a document.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endElement(java.lang.String, java.lang.String, java.lang.String)"><B>endElement(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive notification of the end of an element.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endPrefixMapping(java.lang.String)"><B>endPrefixMapping(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>End the scope of a prefix-URI mapping.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCRowId.html#equals(java.lang.Object)"><B>equals(Object)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A>
+<DD>Compares this <code>RowId</code> to the specified object.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#execute()"><B>execute()</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Process all the commands from the file or Reader associated with
+ "this" object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#execute()"><B>execute()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Executes the SQL statement in this <code>PreparedStatement</code> object,
+ which may be any kind of SQL statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String)"><B>execute(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>This method should always throw if called for a PreparedStatement or
+ CallableStatment.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, int)"><B>execute(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, int[])"><B>execute(String, int[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, java.lang.String[])"><B>execute(String, String[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String)"><B>execute(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement, which may return multiple results.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String, int)"><B>execute(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement, which may return multiple results,
+ and signals the driver that any
+ auto-generated keys should be made available
+ for retrieval.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String, int[])"><B>execute(String, int[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement, which may return multiple results,
+ and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String, java.lang.String[])"><B>execute(String, String[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement, which may return multiple results,
+ and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#executeBatch()"><B>executeBatch()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Submits a batch of commands to the database for execution and
+ if all commands execute successfully, returns an array of update counts.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#executeBatch()"><B>executeBatch()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Submits a batch of commands to the database for execution and
+ if all commands execute successfully, returns an array of update counts.
+<DT><A HREF="./org/hsqldb/sample/SqlFileEmbedder.html#executeFiles(java.lang.String[])"><B>executeFiles(String[])</B></A> - 
+Method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample">SqlFileEmbedder</A>
+<DD>Your own classes can use this method to execute SQL files.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#executeQuery()"><B>executeQuery()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Executes the SQL query in this <code>PreparedStatement</code> object
+ and returns the <code>ResultSet</code> object generated by the query.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#executeQuery(java.lang.String)"><B>executeQuery(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>This method should always throw if called for a PreparedStatement or
+ CallableStatment.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#executeQuery(java.lang.String)"><B>executeQuery(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement, which returns a single
+ <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate()"><B>executeUpdate()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Executes the SQL statement in this <code>PreparedStatement</code> object,
+ (JDBC4 clarification:)
+ which must be an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+ <code>DELETE</code>; or an SQL statement that returns nothing,
+ such as a DDL statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String)"><B>executeUpdate(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>This method should always throw if called for a PreparedStatement or
+ CallableStatment.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, int)"><B>executeUpdate(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Statement methods that must be overridden in this class and throw
+ an exception.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, int[])"><B>executeUpdate(String, int[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, java.lang.String[])"><B>executeUpdate(String, String[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#executeUpdate(java.lang.String)"><B>executeUpdate(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement, which may be an <code>INSERT</code>,
+ <code>UPDATE</code>, or <code>DELETE</code> statement or an
+ SQL statement that returns nothing, such as an SQL DDL statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#executeUpdate(java.lang.String, int)"><B>executeUpdate(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement and signals the driver with the
+ given flag about whether the
+ auto-generated keys produced by this <code>Statement</code> object
+ should be made available for retrieval.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#executeUpdate(java.lang.String, int[])"><B>executeUpdate(String, int[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#executeUpdate(java.lang.String, java.lang.String[])"><B>executeUpdate(String, String[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Executes the given SQL statement and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#expandSysPropVars(java.lang.String)"><B>expandSysPropVars(String)</B></A> - 
+Static method in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Returns a copy of the given String with System property names in the
+ format <code>${system.property}</code> replaced by the corresponding Java
+ System Properties.
+</DL>
+<HR>
+<A NAME="_F_"><!-- --></A><H2>
+<B>F</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#FETCH_FORWARD"><B>FETCH_FORWARD</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#FETCH_REVERSE"><B>FETCH_REVERSE</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#FETCH_UNKNOWN"><B>FETCH_UNKNOWN</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#FILEERR_EXITVAL"><B>FILEERR_EXITVAL</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#findColumn(java.lang.String)"><B>findColumn(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Maps the given <code>ResultSet</code> column label to its
+ <code>ResultSet</code> column index.
+<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#fire(int, java.lang.String, java.lang.String, java.lang.Object[], java.lang.Object[])"><B>fire(int, String, String, Object[], Object[])</B></A> - 
+Method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>A sample HSQLDB Trigger interface implementation.
+<DT><A HREF="./org/hsqldb/Trigger.html#fire(int, java.lang.String, java.lang.String, java.lang.Object[], java.lang.Object[])"><B>fire(int, String, String, Object[], Object[])</B></A> - 
+Method in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>The method invoked upon each triggered action.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#first()"><B>first()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor to the first row in
+ this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#free()"><B>free()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>This method frees the <code>Array</code> object and releases the resources that
+ it holds.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#free()"><B>free()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>This method frees the <code>Blob</code> object and releases the resources that
+ it holds.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#free()"><B>free()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>This method frees the <code>Blob</code> object and releases the resources that
+ it holds.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#free()"><B>free()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>This method frees the <code>Clob</code> object and releases the resources the resources
+ that it holds.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#free()"><B>free()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>This method frees the <code>Clob</code> object and releases the resources the resources
+ that it holds.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#free()"><B>free()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>This method closes this object and releases the resources that it held.
+</DL>
+<HR>
+<A NAME="_G_"><!-- --></A><H2>
+<B>G</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/lib/tar/DbBackup.html#getAbortUponModify()"><B>getAbortUponModify()</B></A> - 
+Method in class org.hsqldb.lib.tar.<A HREF="./org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/Server.html#getAddress()"><B>getAddress()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves, in string form, this server's host address.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getArray()"><B>getArray()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves the contents of the SQL <code>ARRAY</code> value designated
+ by this
+ <code>Array</code> object in the form of an array in the Java
+ programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getArray(java.util.Map)"><B>getArray(Map&lt;String, Class&lt;?&gt;&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves the contents of the SQL <code>ARRAY</code> value designated by this
+ <code>Array</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getArray(long, int)"><B>getArray(long, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves a slice of the SQL <code>ARRAY</code>
+ value designated by this <code>Array</code> object, beginning with the
+ specified <code>index</code> and containing up to <code>count</code>
+ successive elements of the SQL array.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getArray(long, int, java.util.Map)"><B>getArray(long, int, Map&lt;String, Class&lt;?&gt;&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retreives a slice of the SQL <code>ARRAY</code> value
+ designated by this <code>Array</code> object, beginning with the specified
+ <code>index</code> and containing up to <code>count</code>
+ successive elements of the SQL array.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getArray(int)"><B>getArray(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>ARRAY</code> parameter as an
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql"><CODE>Array</CODE></A> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getArray(java.lang.String)"><B>getArray(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>ARRAY</code> parameter as an
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql"><CODE>Array</CODE></A> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getArray(int)"><B>getArray(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Array</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getArray(java.lang.String)"><B>getArray(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Array</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#getAsciiStream()"><B>getAsciiStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
+ object as an ascii stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#getAsciiStream()"><B>getAsciiStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Retrieves the <code>CLOB</code> value designated by this
+ <code>Clob</code> object as an ascii stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getAsciiStream(int)"><B>getAsciiStream(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a stream of ASCII characters.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getAsciiStream(java.lang.String)"><B>getAsciiStream(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a stream of
+ ASCII characters.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getAttributes(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>getAttributes(String, String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the given attribute of the given type
+ for a user-defined type (UDT) that is available in the given schema
+ and catalog.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getAutoCommit()"><B>getAutoCommit()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves the current auto-commit mode for this <code>Connection</code>
+ object.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#getBanner(java.sql.Connection)"><B>getBanner(Connection)</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Returns a String report for the specified JDBC Connection.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getBaseType()"><B>getBaseType()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves the JDBC type of the elements in the array designated
+ by this <code>Array</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getBaseTypeName()"><B>getBaseTypeName()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves the SQL type name of the elements in
+ the array designated by this <code>Array</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getBestRowIdentifier(java.lang.String, java.lang.String, java.lang.String, int, boolean)"><B>getBestRowIdentifier(String, String, String, int, boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of a table's optimal set of columns that
+ uniquely identifies a row.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBigDecimal(int, int)"><B>getBigDecimal(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD><B>Deprecated.</B>&nbsp;<I>use <code>getBigDecimal(int parameterIndex)</code>
+             or <code>getBigDecimal(String parameterName)</code></I>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBigDecimal(int)"><B>getBigDecimal(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a
+ <code>java.math.BigDecimal</code> object with as many digits to the
+ right of the decimal point as the value contains.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBigDecimal(java.lang.String)"><B>getBigDecimal(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>NUMERIC</code> parameter as a
+ <code>java.math.BigDecimal</code> object with as many digits to the
+ right of the decimal point as the value contains.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(int, int)"><B>getBigDecimal(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD><B>Deprecated.</B>&nbsp;<I>by java.sun.com as of JDK 1.2</I>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(java.lang.String, int)"><B>getBigDecimal(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD><B>Deprecated.</B>&nbsp;<I>by java.sun.com as of JDK 1.2</I>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(int)"><B>getBigDecimal(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.math.BigDecimal</code> with full precision.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(java.lang.String)"><B>getBigDecimal(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.math.BigDecimal</code> with full precision.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#getBinaryStream()"><B>getBinaryStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Retrieves the <code>BLOB</code> value designated by this
+ <code>Blob</code> instance as a stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#getBinaryStream(long, long)"><B>getBinaryStream(long, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+ starting  with the byte specified by pos, which is length bytes in length.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#getBinaryStream()"><B>getBinaryStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Retrieves the <code>BLOB</code> value designated by this
+ <code>Blob</code> instance as a stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#getBinaryStream(long, long)"><B>getBinaryStream(long, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+ starting  with the byte specified by pos, which is length bytes in length.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBinaryStream(int)"><B>getBinaryStream(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a  stream of
+ uninterpreted bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBinaryStream(java.lang.String)"><B>getBinaryStream(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a stream of uninterpreted
+ <code>byte</code>s.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#getBinaryStream()"><B>getBinaryStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Retrieves the XML value designated by this SQLXML instance as a stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBlob(int)"><B>getBlob(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>BLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql"><CODE>Blob</CODE></A> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBlob(java.lang.String)"><B>getBlob(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>BLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql"><CODE>Blob</CODE></A> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBlob(int)"><B>getBlob(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Blob</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBlob(java.lang.String)"><B>getBlob(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Blob</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBoolean(int)"><B>getBoolean(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>(JDBC4 modified:)
+ Retrieves the value of the designated JDBC <code>BIT</code>
+ or <code>BOOLEAN</code> parameter as a
+ <code>boolean</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBoolean(java.lang.String)"><B>getBoolean(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>(JDBC4 modified:)
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBoolean(int)"><B>getBoolean(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>boolean</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBoolean(java.lang.String)"><B>getBoolean(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>boolean</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getByte(int)"><B>getByte(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>TINYINT</code> parameter
+ as a <code>byte</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getByte(java.lang.String)"><B>getByte(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getByte(int)"><B>getByte(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getByte(java.lang.String)"><B>getByte(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#getBytes(long, int)"><B>getBytes(long, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Retrieves all or part of the <code>BLOB</code>
+ value that this <code>Blob</code> object represents, as an array of
+ bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#getBytes(long, int)"><B>getBytes(long, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Retrieves all or part of the <code>BLOB</code> value that this
+ <code>Blob</code> object represents, as an array of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBytes(int)"><B>getBytes(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>BINARY</code> or
+ <code>VARBINARY</code> parameter as an array of <code>byte</code>
+ values in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getBytes(java.lang.String)"><B>getBytes(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code>
+ parameter as an array of <code>byte</code> values in the Java
+ programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBytes(int)"><B>getBytes(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> array in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getBytes(java.lang.String)"><B>getBytes(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> array in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCRowId.html#getBytes()"><B>getBytes()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A>
+<DD>Returns an array of bytes representing the value of the SQL <code>ROWID</code>
+ designated by this <code>java.sql.RowId</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getCatalog()"><B>getCatalog()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves this <code>Connection</code> object's current catalog name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getCatalogName(int)"><B>getCatalogName(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Gets the designated column's table's catalog name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getCatalogs()"><B>getCatalogs()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the catalog names available in this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getCatalogSeparator()"><B>getCatalogSeparator()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the <code>String</code> that this database uses as the
+ separator between a catalog and table name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getCatalogTerm()"><B>getCatalogTerm()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the database vendor's preferred term for "catalog".
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getCharacterStream(int)"><B>getCharacterStream(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getCharacterStream(java.lang.String)"><B>getCharacterStream(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#getCharacterStream()"><B>getCharacterStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
+ object as a <code>java.io.Reader</code> object (or as a stream of
+ characters).
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#getCharacterStream(long, long)"><B>getCharacterStream(long, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
+ with the character specified by pos, which is length characters in length.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#getCharacterStream()"><B>getCharacterStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Retrieves the <code>CLOB</code> value designated by this
+ <code>Clob</code> object as a <code>java.io.Reader</code> object (or
+ as a stream of characters).
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#getCharacterStream(long, long)"><B>getCharacterStream(long, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
+ with the character specified by pos, which is length characters in length.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getCharacterStream(int)"><B>getCharacterStream(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getCharacterStream(java.lang.String)"><B>getCharacterStream(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#getCharacterStream()"><B>getCharacterStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Retrieves the XML value designated by this SQLXML instance as a java.io.Reader object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getClientInfo(java.lang.String)"><B>getClientInfo(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Returns the value of the client info property specified by name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getClientInfo()"><B>getClientInfo()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Returns a list containing the name and current value of each client info
+ property supported by the driver.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getClientInfoProperties()"><B>getClientInfoProperties()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a list of the client info properties
+ that the driver supports.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getClob(int)"><B>getClob(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>CLOB</code> parameter as a
+ <code>java.sql.Clob</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getClob(java.lang.String)"><B>getClob(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>CLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql"><CODE>Clob</CODE></A> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getClob(int)"><B>getClob(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Clob</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getClob(java.lang.String)"><B>getClob(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Clob</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnClassName(int)"><B>getColumnClassName(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnCount()"><B>getColumnCount()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Returns the number of columns in this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnDisplaySize(int)"><B>getColumnDisplaySize(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates the designated column's normal maximum width in characters.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnLabel(int)"><B>getColumnLabel(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Gets the designated column's suggested title for use in printouts and
+ displays.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnName(int)"><B>getColumnName(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Get the designated column's name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getColumnPrivileges(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>getColumnPrivileges(String, String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the access rights for a table's columns.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>getColumns(String, String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of table columns available in
+ the specified catalog.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnType(int)"><B>getColumnType(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Retrieves the designated column's SQL type.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnTypeName(int)"><B>getColumnTypeName(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Retrieves the designated column's database-specific type name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getConcurrency()"><B>getConcurrency()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the concurrency mode of this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/sample/SqlFileEmbedder.html#getConn()"><B>getConn()</B></A> - 
+Method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample">SqlFileEmbedder</A>
+<DD>For applications that use a persistent JDBC connection, this class can
+ be used to encapsulate that connection.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#getConnection()"><B>getConnection()</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getConnection()"><B>getConnection()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the connection that produced this metadata object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#getConnection()"><B>getConnection()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Attempts to establish a connection with the data source that
+ this <code>DataSource</code> object represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#getConnection(java.lang.String, java.lang.String)"><B>getConnection(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Attempts to establish a connection with the data source that
+ this <code>DataSource</code> object represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#getConnection(java.lang.String, java.util.Properties)"><B>getConnection(String, Properties)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>The static equivalent of the <code>connect(String,Properties)</code>
+ method.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#getConnection(java.lang.String, java.util.Properties)"><B>getConnection(String, Properties)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>The static equivalent of the <code>connect(String,Properties)</code>
+ method.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getConnection()"><B>getConnection()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the <code>Connection</code> object
+ that produced this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getConnection()"><B>getConnection()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the <code>Connection</code> object
+ that produced this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#getConnection()"><B>getConnection()</B></A> - 
+Method in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Gets a JDBC Connection using the data of this RCData object.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#getConnection(java.lang.String, java.lang.String)"><B>getConnection(String, String)</B></A> - 
+Method in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Gets a JDBC Connection using the data of this RCData object with
+ specified override elements
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getCrossReference(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>getCrossReference(String, String, String, String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>(JDBC4 clarification:)
+ Retrieves a description of the foreign key columns in the given foreign key
+ table that reference the primary key or the columns representing a unique constraint of the  parent table (could be the same or a different table).
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#getCurrentSchema()"><B>getCurrentSchema()</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getCursorName()"><B>getCursorName()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the name of the SQL cursor used by this <code>ResultSet</code>
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#getDatabase()"><B>getDatabase()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Retrieves the jdbc database connection url attribute.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDatabaseMajorVersion()"><B>getDatabaseMajorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the major version number of the underlying database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDatabaseMinorVersion()"><B>getDatabaseMinorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the minor version number of the underlying database.
+<DT><A HREF="./org/hsqldb/server/Server.html#getDatabaseName(int, boolean)"><B>getDatabaseName(int, boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves the url alias (network name) of the i'th database
+ that this Server hosts.
+<DT><A HREF="./org/hsqldb/server/Server.html#getDatabasePath(int, boolean)"><B>getDatabasePath(int, boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves the HSQLDB path descriptor (uri) of the i'th
+ Database that this Server hosts.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDatabaseProductName()"><B>getDatabaseProductName()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the name of this database product.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDatabaseProductVersion()"><B>getDatabaseProductVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the version number of this database product.
+<DT><A HREF="./org/hsqldb/server/Server.html#getDatabaseType(int)"><B>getDatabaseType(int)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(int)"><B>getDate(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(int, java.util.Calendar)"><B>getDate(int, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object, using
+ the given <code>Calendar</code> object
+ to construct the date.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(java.lang.String)"><B>getDate(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(java.lang.String, java.util.Calendar)"><B>getDate(String, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object, using
+ the given <code>Calendar</code> object
+ to construct the date.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getDate(int)"><B>getDate(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Date</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getDate(java.lang.String)"><B>getDate(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Date</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getDate(int, java.util.Calendar)"><B>getDate(int, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getDate(java.lang.String, java.util.Calendar)"><B>getDate(String, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#getDefaultJdbcDriverName()"><B>getDefaultJdbcDriverName()</B></A> - 
+Method in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDefaultTransactionIsolation()"><B>getDefaultTransactionIsolation()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves this database's default transaction isolation level.
+<DT><A HREF="./org/hsqldb/server/Server.html#getDefaultWebPage()"><B>getDefaultWebPage()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves the name of the web page served when no page is specified.
+<DT><A HREF="./org/hsqldb/server/WebServer.html#getDefaultWebPage()"><B>getDefaultWebPage()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A>
+<DD>Retrieves the name of the web page served when no page is specified.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#getDocumentLocator()"><B>getDocumentLocator()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Retrieves the Locator.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getDouble(int)"><B>getDouble(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>DOUBLE</code> parameter as a <code>double</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getDouble(java.lang.String)"><B>getDouble(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getDouble(int)"><B>getDouble(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>double</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getDouble(java.lang.String)"><B>getDouble(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>double</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDriverMajorVersion()"><B>getDriverMajorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves this JDBC driver's major version number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDriverMinorVersion()"><B>getDriverMinorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves this JDBC driver's minor version number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDriverName()"><B>getDriverName()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the name of this JDBC driver.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDriverVersion()"><B>getDriverVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the version number of this JDBC driver as a <code>String</code>.
+<DT><A HREF="./org/hsqldb/server/Server.html#getErrWriter()"><B>getErrWriter()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves the PrintWriter to which server errors are printed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getExportedKeys(java.lang.String, java.lang.String, java.lang.String)"><B>getExportedKeys(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the foreign key columns that reference the
+ given table's primary key columns (the foreign keys exported by a
+ table).
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getExtraNameCharacters()"><B>getExtraNameCharacters()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves all the "extra" characters that can be used in unquoted
+ identifier names (those beyond a-z, A-Z, 0-9 and _).
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getFetchDirection()"><B>getFetchDirection()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the direction for fetching rows from
+ database tables that is the default for result sets
+ generated from this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getFetchDirection()"><B>getFetchDirection()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the fetch direction for this
+ <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getFetchDirection()"><B>getFetchDirection()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the direction for fetching rows from
+ database tables that is the default for result sets
+ generated from this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getFetchSize()"><B>getFetchSize()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the number of result set rows that is the default
+ fetch size for <code>ResultSet</code> objects
+ generated from this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getFetchSize()"><B>getFetchSize()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the fetch size for this
+ <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getFetchSize()"><B>getFetchSize()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the number of result set rows that is the default
+ fetch size for <code>ResultSet</code> objects
+ generated from this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getFloat(int)"><B>getFloat(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>FLOAT</code> parameter
+ as a <code>float</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getFloat(java.lang.String)"><B>getFloat(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getFloat(int)"><B>getFloat(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>float</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getFloat(java.lang.String)"><B>getFloat(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>float</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#getForEachSpec(int)"><B>getForEachSpec(int)</B></A> - 
+Static method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getFunctionColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>getFunctionColumns(String, String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the given catalog's system or user
+ function parameters and return type.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getFunctions(java.lang.String, java.lang.String, java.lang.String)"><B>getFunctions(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the user functions available in the given
+ catalog.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getGeneratedKeys()"><B>getGeneratedKeys()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves any auto-generated keys created as a result of executing this
+ <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getGeneratedKeys()"><B>getGeneratedKeys()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves any auto-generated keys created as a result of executing this
+ <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/server/Server.html#getHelpString()"><B>getHelpString()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves a String object describing the command line and
+ properties options for this Server.
+<DT><A HREF="./org/hsqldb/server/WebServer.html#getHelpString()"><B>getHelpString()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A>
+<DD>Retrieves a String object describing the command line and
+ properties options for this Server.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><B>getHoldability()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves the current holdability of <code>ResultSet</code> objects
+ created using this <code>Connection</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getHoldability()"><B>getHoldability()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the holdability of this <code>ResultSet</code> object
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getIdentifierQuoteString()"><B>getIdentifierQuoteString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the string used to quote SQL identifiers.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getImportedKeys(java.lang.String, java.lang.String, java.lang.String)"><B>getImportedKeys(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the primary key columns that are
+ referenced by the given table's foreign key columns (the primary keys
+ imported by a table).
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getIndexInfo(java.lang.String, java.lang.String, java.lang.String, boolean, boolean)"><B>getIndexInfo(String, String, String, boolean, boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the given table's indices and statistics.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getInt(int)"><B>getInt(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>INTEGER</code> parameter
+ as an <code>int</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getInt(java.lang.String)"><B>getInt(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getInt(int)"><B>getInt(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ an <code>int</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getInt(java.lang.String)"><B>getInt(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ an <code>int</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getJDBCMajorVersion()"><B>getJDBCMajorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the major JDBC version number for this
+ driver.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getJDBCMinorVersion()"><B>getJDBCMinorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the minor JDBC version number for this
+ driver.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#getLoginTimeout()"><B>getLoginTimeout()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Gets the maximum time in seconds that this data source can wait
+ while attempting to connect to a database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#getLogWriter()"><B>getLogWriter()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Retrieves the log writer for this <code>DataSource</code>
+ object.
+<DT><A HREF="./org/hsqldb/server/Server.html#getLogWriter()"><B>getLogWriter()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves the PrintWriter to which server messages are printed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getLong(int)"><B>getLong(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>BIGINT</code> parameter
+ as a <code>long</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getLong(java.lang.String)"><B>getLong(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getLong(int)"><B>getLong(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>long</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getLong(java.lang.String)"><B>getLong(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>long</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#getMacros()"><B>getMacros()</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#getMajorVersion()"><B>getMajorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Gets the driver's major version number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#getMajorVersion()"><B>getMajorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Gets the driver's major version number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxBinaryLiteralLength()"><B>getMaxBinaryLiteralLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of hex characters this database allows in an
+ inline binary literal.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxCatalogNameLength()"><B>getMaxCatalogNameLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters that this database allows in a
+ catalog name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxCharLiteralLength()"><B>getMaxCharLiteralLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters this database allows
+ for a character literal.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnNameLength()"><B>getMaxColumnNameLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters this database allows
+ for a column name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInGroupBy()"><B>getMaxColumnsInGroupBy()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of columns this database allows in a
+ <code>GROUP BY</code> clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInIndex()"><B>getMaxColumnsInIndex()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of columns this database allows in an index.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInOrderBy()"><B>getMaxColumnsInOrderBy()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of columns this database allows in an
+ <code>ORDER BY</code> clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInSelect()"><B>getMaxColumnsInSelect()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of columns this database allows in a
+ <code>SELECT</code> list.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInTable()"><B>getMaxColumnsInTable()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of columns this database allows in a table.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxConnections()"><B>getMaxConnections()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of concurrent connections to this
+ database that are possible.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxCursorNameLength()"><B>getMaxCursorNameLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters that this database allows in a
+ cursor name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getMaxFieldSize()"><B>getMaxFieldSize()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the maximum number of bytes that can be
+ returned for character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getMaxFieldSize()"><B>getMaxFieldSize()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the maximum number of bytes that can be
+ returned for character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxIndexLength()"><B>getMaxIndexLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of bytes this database allows for an
+ index, including all of the parts of the index.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxProcedureNameLength()"><B>getMaxProcedureNameLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters that this database allows in a
+ procedure name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getMaxRows()"><B>getMaxRows()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the maximum number of rows that a
+ <code>ResultSet</code> object produced by this
+ <code>Statement</code> object can contain.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getMaxRows()"><B>getMaxRows()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the maximum number of rows that a
+ <code>ResultSet</code> object produced by this
+ <code>Statement</code> object can contain.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxRowSize()"><B>getMaxRowSize()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of bytes this database allows in
+ a single row.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxSchemaNameLength()"><B>getMaxSchemaNameLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters that this database allows in a
+ schema name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxStatementLength()"><B>getMaxStatementLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters this database allows in
+ an SQL statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxStatements()"><B>getMaxStatements()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of active statements to this database
+ that can be open at the same time.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxTableNameLength()"><B>getMaxTableNameLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters this database allows in
+ a table name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxTablesInSelect()"><B>getMaxTablesInSelect()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of tables this database allows in a
+ <code>SELECT</code> statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxUserNameLength()"><B>getMaxUserNameLength()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the maximum number of characters this database allows in
+ a user name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getMetaData()"><B>getMetaData()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves a <code>DatabaseMetaData</code> object that contains
+ metadata about the database to which this
+ <code>Connection</code> object represents a connection.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getMetaData()"><B>getMetaData()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves a <code>ResultSetMetaData</code> object that contains
+ information about the columns of the <code>ResultSet</code> object
+ that will be returned when this <code>PreparedStatement</code> object
+ is executed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getMetaData()"><B>getMetaData()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the  number, types and properties of
+ this <code>ResultSet</code> object's columns.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#getMinorVersion()"><B>getMinorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Gets the driver's minor version number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#getMinorVersion()"><B>getMinorVersion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Gets the driver's minor version number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getMoreResults(int)"><B>getMoreResults(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Moves to this <code>Statement</code> object's next result, deals with
+ any current <code>ResultSet</code> object(s) according  to the instructions
+ specified by the given flag, and returns
+ <code>true</code> if the next result is a <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getMoreResults()"><B>getMoreResults()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Moves to this <code>Statement</code> object's next result, returns
+ <code>true</code> if it is a <code>ResultSet</code> object, and
+ implicitly closes any current <code>ResultSet</code>
+ object(s) obtained with the method <code>getResultSet</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getMoreResults()"><B>getMoreResults()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Moves to this <code>Statement</code> object's next result, returns
+ <code>true</code> if it is a <code>ResultSet</code> object, and
+ implicitly closes any current <code>ResultSet</code>
+ object(s) obtained with the method <code>getResultSet</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getMoreResults(int)"><B>getMoreResults(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Moves to this <code>Statement</code> object's next result, deals with
+ any current <code>ResultSet</code> object(s) according  to the instructions
+ specified by the given flag, and returns
+ <code>true</code> if the next result is a <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getNCharacterStream(int)"><B>getNCharacterStream(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getNCharacterStream(java.lang.String)"><B>getNCharacterStream(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getNCharacterStream(int)"><B>getNCharacterStream(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getNCharacterStream(java.lang.String)"><B>getNCharacterStream(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getNClob(int)"><B>getNClob(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>NCLOB</code> parameter as a
+ <code>java.sql.NClob</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getNClob(java.lang.String)"><B>getNClob(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>NCLOB</code> parameter as a
+ <code>java.sql.NClob</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getNClob(int)"><B>getNClob(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>NClob</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getNClob(java.lang.String)"><B>getNClob(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>NClob</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getNString(int)"><B>getNString(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated <code>NCHAR</code>,
+ <code>NVARCHAR</code>
+ or <code>LONGNVARCHAR</code> parameter as
+ a <code>String</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getNString(java.lang.String)"><B>getNString(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated <code>NCHAR</code>,
+ <code>NVARCHAR</code>
+ or <code>LONGNVARCHAR</code> parameter as
+ a <code>String</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getNString(int)"><B>getNString(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getNString(java.lang.String)"><B>getNString(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getNumericFunctions()"><B>getNumericFunctions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a comma-separated list of math functions available with
+ this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int)"><B>getObject(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated parameter as an <code>Object</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int, java.util.Map)"><B>getObject(int, Map&lt;String, Class&lt;?&gt;&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Returns an object representing the value of OUT parameter
+ <code>parameterIndex</code> and uses <code>map</code> for the custom
+ mapping of the parameter value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(java.lang.String)"><B>getObject(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a parameter as an <code>Object</code> in the Java
+ programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(java.lang.String, java.util.Map)"><B>getObject(String, Map)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getObject(int)"><B>getObject(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getObject(java.lang.String)"><B>getObject(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getObject(int, java.util.Map)"><B>getObject(int, Map)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Object</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getObject(java.lang.String, java.util.Map)"><B>getObject(String, Map)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Object</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSourceFactory.html#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)"><B>getObjectInstance(Object, Name, Context, Hashtable)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc">JDBCDataSourceFactory</A>
+<DD>Creates a JDBCDataSource object using the location or reference
+ information specified.
+<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#getOperationSpec(int)"><B>getOperationSpec(int)</B></A> - 
+Static method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/lib/tar/DbBackup.html#getOverWrite()"><B>getOverWrite()</B></A> - 
+Method in class org.hsqldb.lib.tar.<A HREF="./org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterClassName(int)"><B>getParameterClassName(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves the fully-qualified name of the Java class whose instances
+ should be passed to the method <code>PreparedStatement.setObject</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterCount()"><B>getParameterCount()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves the number of parameters in the <code>PreparedStatement</code>
+ object for which this <code>ParameterMetaData</code> object contains
+ information.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getParameterMetaData()"><B>getParameterMetaData()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the number, types and properties of this
+ <code>PreparedStatement</code> object's parameters.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterMode(int)"><B>getParameterMode(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves the designated parameter's mode.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterType(int)"><B>getParameterType(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves the designated parameter's SQL type.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterTypeName(int)"><B>getParameterTypeName(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves the designated parameter's database-specific type name.
+<DT><A HREF="./org/hsqldb/server/Server.html#getPort()"><B>getPort()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves this server's host port.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#getPrecision(int)"><B>getPrecision(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves the designated parameter's specified column size.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getPrecision(int)"><B>getPrecision(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>(JDBC4 clarification:)
+ Get the designated column's specified column size.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String)"><B>getPrimaryKeys(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the given table's primary key columns.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getProcedureColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>getProcedureColumns(String, String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the given catalog's stored procedure parameter
+ and result columns.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getProcedures(java.lang.String, java.lang.String, java.lang.String)"><B>getProcedures(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the stored procedures available in the given
+ catalog.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getProcedureTerm()"><B>getProcedureTerm()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the database vendor's preferred term for "procedure".
+<DT><A HREF="./org/hsqldb/server/Server.html#getProductName()"><B>getProductName()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves this server's product name.
+<DT><A HREF="./org/hsqldb/server/WebServer.html#getProductName()"><B>getProductName()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A>
+<DD>Retrieves this server's product name.
+<DT><A HREF="./org/hsqldb/server/Server.html#getProductVersion()"><B>getProductVersion()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves the server's product version, as a String.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#getPropertyInfo(java.lang.String, java.util.Properties)"><B>getPropertyInfo(String, Properties)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Gets information about the possible properties for this driver.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#getPropertyInfo(java.lang.String, java.util.Properties)"><B>getPropertyInfo(String, Properties)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Gets information about the possible properties for this driver.
+<DT><A HREF="./org/hsqldb/server/Server.html#getProtocol()"><B>getProtocol()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves a string respresentaion of the network protocol
+ this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.
+<DT><A HREF="./org/hsqldb/server/WebServer.html#getProtocol()"><B>getProtocol()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A>
+<DD>Retrieves a string respresentaion of the network protocol
+ this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getQueryTimeout()"><B>getQueryTimeout()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the number of seconds the driver will
+ wait for a <code>Statement</code> object to execute.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getQueryTimeout()"><B>getQueryTimeout()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the number of seconds the driver will
+ wait for a <code>Statement</code> object to execute.
+<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#getQueueSpec(int)"><B>getQueueSpec(int)</B></A> - 
+Static method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getRef(int)"><B>getRef(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>REF(&lt;structured-type&gt;)</code>
+ parameter as a <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql"><CODE>Ref</CODE></A> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getRef(java.lang.String)"><B>getRef(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>REF(&lt;structured-type&gt;)</code>
+ parameter as a <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql"><CODE>Ref</CODE></A> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getRef(int)"><B>getRef(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Ref</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getRef(java.lang.String)"><B>getRef(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Ref</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#getReference()"><B>getReference()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getResultSet()"><B>getResultSet()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves a result set that contains the elements of the SQL
+ <code>ARRAY</code> value
+ designated by this <code>Array</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getResultSet(java.util.Map)"><B>getResultSet(Map&lt;String, Class&lt;?&gt;&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves a result set that contains the elements of the SQL
+ <code>ARRAY</code> value designated by this <code>Array</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getResultSet(long, int)"><B>getResultSet(long, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves a result set holding the elements of the subarray that
+ starts at index <code>index</code> and contains up to
+ <code>count</code> successive elements.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#getResultSet(long, int, java.util.Map)"><B>getResultSet(long, int, Map&lt;String, Class&lt;?&gt;&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Retrieves a result set holding the elements of the subarray that
+ starts at index <code>index</code> and contains up to
+ <code>count</code> successive elements.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSet()"><B>getResultSet()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the current result as a <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getResultSet()"><B>getResultSet()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the current result as a <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetConcurrency()"><B>getResultSetConcurrency()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the result set concurrency for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getResultSetConcurrency()"><B>getResultSetConcurrency()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the result set concurrency for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getResultSetHoldability()"><B>getResultSetHoldability()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>(JDBC4 clarification:)
+ Retrieves this database's default holdability for <code>ResultSet</code>
+ objects.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetHoldability()"><B>getResultSetHoldability()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the result set holdability for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getResultSetHoldability()"><B>getResultSetHoldability()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the result set holdability for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetType()"><B>getResultSetType()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the result set type for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getResultSetType()"><B>getResultSetType()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the result set type for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getRow()"><B>getRow()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the current row number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getRowId(int)"><B>getRowId(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a
+ <code>java.sql.RowId</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getRowId(java.lang.String)"><B>getRowId(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a
+ <code>java.sql.RowId</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getRowId(int)"><B>getRowId(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row of this
+ <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
+ programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getRowId(java.lang.String)"><B>getRowId(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row of this
+ <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
+ programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getRowIdLifetime()"><B>getRowIdLifetime()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Indicates whether or not this data source supports the SQL <code>ROWID</code> type,
+ and if so  the lifetime for which a <code>RowId</code> object remains valid.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSavepoint.html#getSavepointId()"><B>getSavepointId()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc">JDBCSavepoint</A>
+<DD>Retrieves the generated ID for the savepoint that this
+ <code>Savepoint</code> object represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSavepoint.html#getSavepointName()"><B>getSavepointName()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc">JDBCSavepoint</A>
+<DD>Retrieves the name of the savepoint that this <code>Savepoint</code>
+ object represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#getScale(int)"><B>getScale(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves the designated parameter's number of digits to right of the decimal point.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getScale(int)"><B>getScale(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Gets the designated column's number of digits to right of the decimal point.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getSchemaName(int)"><B>getSchemaName(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Get the designated column's table's schema.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSchemas()"><B>getSchemas()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the schema names available in this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSchemas(java.lang.String, java.lang.String)"><B>getSchemas(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the schema names available in this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSchemaTerm()"><B>getSchemaTerm()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the database vendor's preferred term for "schema".
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><B>getSearchStringEscape()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the string that can be used to escape wildcard characters.
+<DT><A HREF="./org/hsqldb/server/Server.html#getServerError()"><B>getServerError()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves a Throwable indicating the last server error, if any.
+<DT><A HREF="./org/hsqldb/server/Server.html#getServerId()"><B>getServerId()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves a String identifying this Server object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getShort(int)"><B>getShort(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>SMALLINT</code> parameter
+ as a <code>short</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getShort(java.lang.String)"><B>getShort(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code>
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getShort(int)"><B>getShort(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>short</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getShort(java.lang.String)"><B>getShort(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>short</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#getSource(java.lang.Class)"><B>getSource(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Returns a Source for reading the XML value designated by this SQLXML instance.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSQLKeywords()"><B>getSQLKeywords()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a comma-separated list of all of this database's SQL keywords
+ that are NOT also SQL:2003 keywords.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSQLStateType()"><B>getSQLStateType()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>(JDBC4 modified:)
+ Indicates whether the SQLSTATE returned by <code>SQLException.getSQLState</code>
+ is X/Open (now known as Open Group) SQL CLI or SQL:2003.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getSQLXML(int)"><B>getSQLXML(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated <code>SQL XML</code> parameter as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getSQLXML(java.lang.String)"><B>getSQLXML(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated <code>SQL XML</code> parameter as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getSQLXML(int)"><B>getSQLXML(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in  the current row of
+  this <code>ResultSet</code> as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getSQLXML(java.lang.String)"><B>getSQLXML(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in  the current row of
+  this <code>ResultSet</code> as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/server/Server.html#getState()"><B>getState()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves current state of this server in numerically coded form.
+<DT><A HREF="./org/hsqldb/server/Server.html#getStateDescriptor()"><B>getStateDescriptor()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves a character sequence describing this server's current state,
+ including the message of the last exception, if there is one and it
+ is still in context.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getStatement()"><B>getStatement()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the <code>Statement</code> object that produced this
+ <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getString(int)"><B>getString(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>CHAR</code>,
+ <code>VARCHAR</code>, or <code>LONGVARCHAR</code> parameter as a
+ <code>String</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getString(java.lang.String)"><B>getString(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
+ or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
+ the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getString(int)"><B>getString(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getString(java.lang.String)"><B>getString(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#getString()"><B>getString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Returns a string representation of the XML value designated by this SQLXML instance.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getStringFunctions()"><B>getStringFunctions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a comma-separated list of string functions available with
+ this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#getSubString(long, int)"><B>getSubString(long, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Retrieves a copy of the specified substring
+ in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#getSubString(long, int)"><B>getSubString(long, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Retrieves a copy of the specified substring in the <code>CLOB</code>
+ value designated by this <code>Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSuperTables(java.lang.String, java.lang.String, java.lang.String)"><B>getSuperTables(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the table hierarchies defined in a particular
+ schema in this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSuperTypes(java.lang.String, java.lang.String, java.lang.String)"><B>getSuperTypes(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the user-defined type (UDT) hierarchies defined in a
+ particular schema in this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSystemFunctions()"><B>getSystemFunctions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a comma-separated list of system functions available with
+ this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#getTableName(int)"><B>getTableName(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Gets the designated column's table name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTablePrivileges(java.lang.String, java.lang.String, java.lang.String)"><B>getTablePrivileges(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the access rights for each table available
+ in a catalog.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])"><B>getTables(String, String, String, String[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the tables available in the given catalog.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTableTypes()"><B>getTableTypes()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the table types available in this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(int)"><B>getTime(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(int, java.util.Calendar)"><B>getTime(int, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object, using
+ the given <code>Calendar</code> object
+ to construct the time.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(java.lang.String)"><B>getTime(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(java.lang.String, java.util.Calendar)"><B>getTime(String, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object, using
+ the given <code>Calendar</code> object
+ to construct the time.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getTime(int)"><B>getTime(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Time</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getTime(java.lang.String)"><B>getTime(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Time</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getTime(int, java.util.Calendar)"><B>getTime(int, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Time</code>
+ object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getTime(java.lang.String, java.util.Calendar)"><B>getTime(String, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Time</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTimeDateFunctions()"><B>getTimeDateFunctions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a comma-separated list of the time and date functions available
+ with this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(int)"><B>getTimestamp(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>TIMESTAMP</code>
+ parameter as a <code>java.sql.Timestamp</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(int, java.util.Calendar)"><B>getTimestamp(int, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object, using
+ the given <code>Calendar</code> object to construct
+ the <code>Timestamp</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(java.lang.String)"><B>getTimestamp(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(java.lang.String, java.util.Calendar)"><B>getTimestamp(String, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object, using
+ the given <code>Calendar</code> object to construct
+ the <code>Timestamp</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getTimestamp(int)"><B>getTimestamp(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Timestamp</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getTimestamp(java.lang.String)"><B>getTimestamp(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Timestamp</code> object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getTimestamp(int, java.util.Calendar)"><B>getTimestamp(int, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getTimestamp(java.lang.String, java.util.Calendar)"><B>getTimestamp(String, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
+ in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getTransactionIsolation()"><B>getTransactionIsolation()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves this <code>Connection</code> object's current
+ transaction isolation level.
+<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#getTriggerDDL(java.lang.String, int, java.lang.String, int, java.lang.String)"><B>getTriggerDDL(String, int, String, int, String)</B></A> - 
+Static method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#getTriggerDescriptor(java.lang.String, int, java.lang.String)"><B>getTriggerDescriptor(String, int, String)</B></A> - 
+Static method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getType()"><B>getType()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the type of this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTypeInfo()"><B>getTypeInfo()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of all the (JDBC4 clarification:) data types supported by
+ this database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getTypeMap()"><B>getTypeMap()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves the <code>Map</code> object associated with this
+ <code>Connection</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getUDTs(java.lang.String, java.lang.String, java.lang.String, int[])"><B>getUDTs(String, String, String, int[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of the user-defined types (UDTs) defined
+ in a particular schema.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getUnicodeStream(int)"><B>getUnicodeStream(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD><B>Deprecated.</B>&nbsp;<I>use <code>getCharacterStream</code> in place of
+              <code>getUnicodeStream</code></I>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getUnicodeStream(java.lang.String)"><B>getUnicodeStream(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD><B>Deprecated.</B>&nbsp;<I>use <code>getCharacterStream</code> instead</I>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getUpdateCount()"><B>getUpdateCount()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the current result as an update count;
+  if the result is a <code>ResultSet</code> object or there are no more results, -1
+  is returned.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getUpdateCount()"><B>getUpdateCount()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the current result as an update count;
+  if the result is a <code>ResultSet</code> object or there are no more results, -1
+  is returned.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getURL(int)"><B>getURL(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of the designated JDBC <code>DATALINK</code> parameter as a
+ <code>java.net.URL</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#getURL(java.lang.String)"><B>getURL(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves the value of a JDBC <code>DATALINK</code> parameter as a
+ <code>java.net.URL</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getURL()"><B>getURL()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the URL for this DBMS.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getURL(int)"><B>getURL(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.net.URL</code>
+ object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getURL(java.lang.String)"><B>getURL(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.net.URL</code>
+ object in the Java programming language.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#getUser()"><B>getUser()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Retrieves the user ID for the connection.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getUserName()"><B>getUserName()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves the user name as known to this database.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#getUserVars()"><B>getUserVars()</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getVersionColumns(java.lang.String, java.lang.String, java.lang.String)"><B>getVersionColumns(String, String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves a description of a table's columns that are automatically
+ updated when any value in a row is updated.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#getWarnings()"><B>getWarnings()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves the first warning reported by calls on this
+ <code>Connection</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#getWarnings()"><B>getWarnings()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves the first warning reported by calls on this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#getWarnings()"><B>getWarnings()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves the first warning reported by calls on this
+ <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#getWarnings()"><B>getWarnings()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves the first warning reported by calls on this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/server/Server.html#getWebRoot()"><B>getWebRoot()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves the root context (directory) from which web content
+ is served.
+<DT><A HREF="./org/hsqldb/server/WebServer.html#getWebRoot()"><B>getWebRoot()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A>
+<DD>Retrieves the root context (directory) from which web content
+ is served.
+<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#getWhenSpec(int)"><B>getWhenSpec(int)</B></A> - 
+Static method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#getWriter()"><B>getWriter()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_H_"><!-- --></A><H2>
+<B>H</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/server/Server.html#handleConnection(java.net.Socket)"><B>handleConnection(Socket)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Assigns the specified socket to a new conection handler and
+ starts the handler in a new Thread.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCRowId.html#hashCode()"><B>hashCode()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A>
+<DD>Returns a hash code value of this <code>RowId</code> object.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#hexCharOctetsToBytes(java.lang.String)"><B>hexCharOctetsToBytes(String)</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Convert a String to a byte array by interpreting every 2 characters as
+ an octal byte value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#HOLD_CURSORS_OVER_COMMIT"><B>HOLD_CURSORS_OVER_COMMIT</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+</DL>
+<HR>
+<A NAME="_I_"><!-- --></A><H2>
+<B>I</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/lib/RCData.html#id"><B>id</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#ignorableWhitespace(char[], int, int)"><B>ignorableWhitespace(char[], int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive notification of ignorable whitespace in element content.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#importDsv(java.lang.String, java.lang.String)"><B>importDsv(String, String)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Name is self-explanatory.
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#INPUTERR_EXITVAL"><B>INPUTERR_EXITVAL</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html#INSERT_AFTER"><B>INSERT_AFTER</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html#INSERT_AFTER_ROW"><B>INSERT_AFTER_ROW</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html#INSERT_BEFORE_ROW"><B>INSERT_BEFORE_ROW</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#insertRow()"><B>insertRow()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Inserts the contents of the insert row into this
+ <code>ResultSet</code> object and into the database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#insertsAreDetected(int)"><B>insertsAreDetected(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether or not a visible row insert can be detected
+ by calling the method <code>ResultSet.rowInserted</code>.
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#invalidArgument()"><B>invalidArgument()</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#invalidArgument(java.lang.String)"><B>invalidArgument(String)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/util/MainInvoker.html#invoke(java.lang.String, java.lang.String[])"><B>invoke(String, String[])</B></A> - 
+Static method in class org.hsqldb.util.<A HREF="./org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util">MainInvoker</A>
+<DD>Invokes the static main(String[]) method from each specified class.
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#IOERR_EXITVAL"><B>IOERR_EXITVAL</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#isAfterLast()"><B>isAfterLast()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves whether the cursor is after the last row in
+ this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isAutoIncrement"><B>isAutoIncrement</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Whether the value of the column are automatically numbered.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isAutoIncrement(int)"><B>isAutoIncrement(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates whether the designated column is automatically numbered.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#isBeforeFirst()"><B>isBeforeFirst()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves whether the cursor is before the first row in
+ this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isCaseSensitive"><B>isCaseSensitive</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Whether the column's value's case matters.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isCaseSensitive(int)"><B>isCaseSensitive(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates whether a column's case matters.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#isCatalogAtStart()"><B>isCatalogAtStart()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a catalog appears at the start of a fully qualified
+ table name.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#isClosed()"><B>isClosed()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#isClosed()"><B>isClosed()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#isClosed()"><B>isClosed()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves whether this <code>Connection</code> object has been
+ closed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#isClosed()"><B>isClosed()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves whether this <code>Statement</code> object has been closed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#isClosed()"><B>isClosed()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves whether this <code>ResultSet</code> object has been closed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#isClosed()"><B>isClosed()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Retrieves whether this object is closed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#isClosed()"><B>isClosed()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Retrieves whether this <code>Statement</code> object has been closed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isCurrency"><B>isCurrency</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Whether the values in the column are cash values.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isCurrency(int)"><B>isCurrency(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates whether the designated column is a cash value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isDefinitelyWritable"><B>isDefinitelyWritable</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Whether a write on the column will definitely succeed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isDefinitelyWritable(int)"><B>isDefinitelyWritable(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates whether a write on the designated column will definitely succeed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#isFirst()"><B>isFirst()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves whether the cursor is on the first row of
+ this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#isGetBinaryStreamUsesCopy()"><B>isGetBinaryStreamUsesCopy()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Retrieves whether getBinaryStream() uses a copy of
+ the underlying buffer.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#isLast()"><B>isLast()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves whether the cursor is on the last row of
+ this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/server/Server.html#isNoSystemExit()"><B>isNoSystemExit()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves whether this server calls System.exit() when shutdown.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isNullable"><B>isNullable</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The nullability of values in the column.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#isNullable(int)"><B>isNullable(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves whether null values are allowed in the designated parameter.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isNullable(int)"><B>isNullable(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates the nullability of values in the designated column.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#isPoolable()"><B>isPoolable()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Returns a  value indicating whether the <code>Statement</code>
+ is poolable or not.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#isPoolable()"><B>isPoolable()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Returns a  value indicating whether the <code>Statement</code>
+ is poolable or not.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#isReadable()"><B>isReadable()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Retrieves the object's readability status.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isReadOnly"><B>isReadOnly</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Whether the column's values are definitely not writable.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#isReadOnly()"><B>isReadOnly()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Retrieves whether this <code>Connection</code>
+ object is in read-only mode.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#isReadOnly()"><B>isReadOnly()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database is in read-only mode.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isReadOnly(int)"><B>isReadOnly(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates whether the designated column is definitely not writable.
+<DT><A HREF="./org/hsqldb/server/Server.html#isRestartOnShutdown()"><B>isRestartOnShutdown()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves whether this server restarts on shutdown.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isSearchable"><B>isSearchable</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Whether the column's values can be used in a where clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isSearchable(int)"><B>isSearchable(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates whether the designated column can be used in a where clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isSigned"><B>isSigned</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Whether values in the column are signed numbers.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#isSigned(int)"><B>isSigned(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves whether values for the designated parameter can be signed numbers.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isSigned(int)"><B>isSigned(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates whether values in the designated column are signed numbers.
+<DT><A HREF="./org/hsqldb/server/Server.html#isSilent()"><B>isSilent()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves whether silent mode operation was requested in
+ the server properties.
+<DT><A HREF="./org/hsqldb/server/Server.html#isTls()"><B>isTls()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves whether the use of secure sockets was requested in the
+ server properties.
+<DT><A HREF="./org/hsqldb/server/Server.html#isTrace()"><B>isTrace()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Retrieves whether JDBC trace messages are to go to System.out or the
+ DriverManger PrintStream/PrintWriter, if any.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#isValid(int)"><B>isValid(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Returns true if the connection has not been closed and is still valid.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#isWrapperFor(java.lang.Class)"><B>isWrapperFor(Class&lt;?&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#isWrapperFor(java.lang.Class)"><B>isWrapperFor(Class&lt;?&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#isWrapperFor(java.lang.Class)"><B>isWrapperFor(Class&lt;?&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#isWrapperFor(java.lang.Class)"><B>isWrapperFor(Class&lt;?&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#isWrapperFor(java.lang.Class)"><B>isWrapperFor(Class&lt;?&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#isWrapperFor(java.lang.Class)"><B>isWrapperFor(Class&lt;?&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isWrapperFor(java.lang.Class)"><B>isWrapperFor(Class&lt;?&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#isWrapperFor(java.lang.Class)"><B>isWrapperFor(Class&lt;?&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#isWritable"><B>isWritable</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Whether it is possible for a write on the column to succeed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#isWritable(int)"><B>isWritable(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Indicates whether it is possible for a write on the designated column to
+ succeed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#isWritable()"><B>isWritable()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Retrieves the object's readability status.
+</DL>
+<HR>
+<A NAME="_J_"><!-- --></A><H2>
+<B>J</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#JDBC_MAJOR"><B>JDBC_MAJOR</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><B>JDBCArray</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>The mapping in the Java programming language for the SQL type
+ <code>ARRAY</code>.<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><B>JDBCBlob</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>The representation (mapping) in
+ the Java<sup><font size=-2>TM</font></sup> programming
+ language of an SQL
+ <code>BLOB</code> value.<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#JDBCBlob(byte[])"><B>JDBCBlob(byte[])</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Constructs a new JDBCBlob instance wrapping the given octet sequence.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><B>JDBCBlobClient</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>A wrapper for HSQLDB BlobData objects.<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCCallableStatement</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>The interface used to execute SQL stored procedures.<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#JDBCCallableStatement(org.hsqldb.jdbc.JDBCConnection, java.lang.String, int, int, int)"><B>JDBCCallableStatement(JDBCConnection, String, int, int, int)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Constructs a new JDBCCallableStatement with the specified connection and
+ result type.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><B>JDBCClob</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ for the SQL <code>CLOB</code> type.<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#JDBCClob(java.lang.String)"><B>JDBCClob(String)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Constructs a new JDBCClob object wrapping the given character
+ sequence.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><B>JDBCClobClient</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>A wrapper for HSQLDB ClobData objects.<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCColumnMetaData</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>Provides a site for holding the ResultSetMetaData for individual ResultSet
+ columns.<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#JDBCColumnMetaData()"><B>JDBCColumnMetaData()</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#jdbcCompliant()"><B>jdbcCompliant()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Reports whether this driver is a genuine JDBC Compliant<sup><font
+ size=-2>TM</font></sup> driver.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#jdbcCompliant()"><B>jdbcCompliant()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Reports whether this driver is a genuine JDBC Compliant<sup><font
+ size=-2>TM</font></sup> driver.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><B>JDBCConnection</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>&nbsp;<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#JDBCConnection(org.hsqldb.persist.HsqlProperties)"><B>JDBCConnection(HsqlProperties)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Constructs a new external <code>Connection</code> to an HSQLDB
+ <code>Database</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#JDBCConnection(org.hsqldb.SessionInterface)"><B>JDBCConnection(SessionInterface)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Constructs an <code>INTERNAL</code> <code>Connection</code>,
+ using the specified <CODE>SessionInterface</CODE>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCDatabaseMetaData</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>Comprehensive information about the database as a whole.<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><B>JDBCDataSource</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>A factory for connections to the physical data source that this
+ <code>DataSource</code> object represents.<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#JDBCDataSource()"><B>JDBCDataSource()</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Constructor
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><B>JDBCDataSourceFactory</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>A JNDI ObjectFactory for creating <A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><CODE>JDBCDataSource</CODE></A>
+ object instances.<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSourceFactory.html#JDBCDataSourceFactory()"><B>JDBCDataSourceFactory()</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc">JDBCDataSourceFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><B>JDBCDriver</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>Provides the java.sql.Driver interface implementation required by
+ the JDBC specification.<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><B>JDBCDriver</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>Provides the java.sql.Driver interface implementation required by
+ the JDBC specification.<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#JDBCDriver()"><B>JDBCDriver()</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Default constructor
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDriver.html#JDBCDriver()"><B>JDBCDriver()</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A>
+<DD>Default constructor
+<DT><A HREF="./org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><B>JDBCNClob</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ for the SQL <code>NCLOB</code> type.<DT><A HREF="./org/hsqldb/jdbc/JDBCNClob.html#JDBCNClob(java.lang.String)"><B>JDBCNClob(String)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc">JDBCNClob</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCParameterMetaData</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>An object that can be used to get information about the types
+ and properties for each parameter marker in a
+ <code>PreparedStatement</code> object.<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCPreparedStatement</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>An object that represents a precompiled SQL statement.<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><B>JDBCResultSet</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>A table of data representing a database result set, which
+ is usually generated by executing a statement that queries the database.<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#JDBCResultSet(org.hsqldb.jdbc.JDBCConnection, org.hsqldb.jdbc.JDBCStatementBase, org.hsqldb.result.Result, org.hsqldb.result.ResultMetaData)"><B>JDBCResultSet(JDBCConnection, JDBCStatementBase, Result, ResultMetaData)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Constructs a new <code>JDBCResultSet</code> object using the specified
+ navigator and <code>org.hsqldb.result.ResultMetaData</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#JDBCResultSet(org.hsqldb.jdbc.JDBCConnection, org.hsqldb.result.Result, org.hsqldb.result.ResultMetaData)"><B>JDBCResultSet(JDBCConnection, Result, ResultMetaData)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCResultSetMetaData</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>An object that can be used to get information about the types
+ and properties of the columns in a <code>ResultSet</code> object.<DT><A HREF="./org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><B>JDBCRowId</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>The representation (mapping) in the Java programming language of an SQL ROWID
+ value.<DT><A HREF="./org/hsqldb/jdbc/JDBCRowId.html#JDBCRowId(byte[])"><B>JDBCRowId(byte[])</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A>
+<DD>Constructs a new JDBCRowId instance wrapping the given octet sequence.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCRowId.html#JDBCRowId(java.sql.RowId)"><B>JDBCRowId(RowId)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A>
+<DD>Constructs a new JDBCRowId instance whose internal octet sequence is
+ is a copy of the octet sequence of the given RowId object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCRowId.html#JDBCRowId(java.lang.String)"><B>JDBCRowId(String)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A>
+<DD>Constructs a new JDBCRowId instance whose internal octet sequence is
+ is that represented by the given hexidecimal character sequence.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><B>JDBCSavepoint</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>The representation of a savepoint, which is a point within
+ the current transaction that can be referenced from the
+ <code>Connection.rollback</code> method.<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><B>JDBCSQLXML</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>The mapping in the JavaTM programming language for the SQL XML type.<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#JDBCSQLXML(javax.xml.transform.Source)"><B>JDBCSQLXML(Source)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Constructs a new read-only JDBCSQLXML object from the given Source
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><B>JDBCSQLXML.SAX2XMLStreamWriter</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>Writes to a <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamWriter.html?is-external=true" title="class or interface in javax.xml.stream"><CODE>XMLStreamWriter</CODE></A>
+ from SAX events.<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#JDBCSQLXML.SAX2XMLStreamWriter(javax.xml.stream.XMLStreamWriter)"><B>JDBCSQLXML.SAX2XMLStreamWriter(XMLStreamWriter)</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Constructs a new SAX2XMLStreamWriter that writes SAX events to the
+ designated XMLStreamWriter.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCStatement</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>&nbsp;</DL>
+<HR>
+<A NAME="_L_"><!-- --></A><H2>
+<B>L</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#last()"><B>last()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor to the last row in
+ this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#length()"><B>length()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Returns the number of bytes in the <code>BLOB</code> value
+ designated by this <code>Blob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#length()"><B>length()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Returns the number of bytes in the <code>BLOB</code> value designated
+ by this <code>Blob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#length()"><B>length()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Retrieves the number of characters
+ in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#length()"><B>length()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Retrieves the number of characters in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#libpath"><B>libpath</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#loadBinary(java.io.File)"><B>loadBinary(File)</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Binary file load
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#locatorsUpdateCopy()"><B>locatorsUpdateCopy()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Indicates whether updates made to a LOB are made on a copy or directly
+ to the LOB.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#LS"><B>LS</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Platform-specific line separator
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#LS"><B>LS</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>Platform-specific line separator
+<DT><A HREF="./org/hsqldb/util/MainInvoker.html#LS"><B>LS</B></A> - 
+Static variable in class org.hsqldb.util.<A HREF="./org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util">MainInvoker</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_M_"><!-- --></A><H2>
+<B>M</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>A static wrapper for objectMain, so that that method may be executed
+ as a Java "program".
+<DT><A HREF="./org/hsqldb/lib/tar/DbBackup.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class org.hsqldb.lib.tar.<A HREF="./org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A>
+<DD>Command line invocation to create, examine, or extract HSQLDB database
+ backup tar archives.
+<DT><A HREF="./org/hsqldb/sample/SqlFileEmbedder.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample">SqlFileEmbedder</A>
+<DD>Run
+<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/Server.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Creates and starts a new Server.
+<DT><A HREF="./org/hsqldb/server/ServerAcl.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<DD>Utility method that allows interactive testing of individal
+ ACL records, as well as the net effect of the ACL record list.
+<DT><A HREF="./org/hsqldb/server/WebServer.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A>
+<DD>Starts a new WebServer.
+<DT><A HREF="./org/hsqldb/util/MainInvoker.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class org.hsqldb.util.<A HREF="./org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util">MainInvoker</A>
+<DD>Invokes the static main(String[]) method from each specified class.
+<DT><A HREF="./org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util"><B>MainInvoker</B></A> - Class in <A HREF="./org/hsqldb/util/package-summary.html">org.hsqldb.util</A><DD>Invokes the static main(String[]) method from each class specified.<DT><A HREF="./org/hsqldb/util/MainInvoker.html#MainInvoker()"><B>MainInvoker()</B></A> - 
+Constructor for class org.hsqldb.util.<A HREF="./org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util">MainInvoker</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#MAX_POS"><B>MAX_POS</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#MIN_POS"><B>MIN_POS</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#moveToCurrentRow()"><B>moveToCurrentRow()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor to the remembered cursor position, usually the
+ current row.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#moveToInsertRow()"><B>moveToInsertRow()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor to the insert row.
+</DL>
+<HR>
+<A NAME="_N_"><!-- --></A><H2>
+<B>N</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#nativeSQL(java.lang.String)"><B>nativeSQL(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Converts the given SQL statement into the system's native SQL grammar.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#next()"><B>next()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor froward one row from its current position.
+<DT><A HREF="./org/hsqldb/server/Server.html#notify(int, int)"><B>notify(int, int)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>This is called from org.hsqldb.DatabaseManager when a database is
+ shutdown.
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#nullArgument()"><B>nullArgument()</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullPlusNonNullIsNull()"><B>nullPlusNonNullIsNull()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports concatenations between
+ <code>NULL</code> and non-<code>NULL</code> values being
+ <code>NULL</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullsAreSortedAtEnd()"><B>nullsAreSortedAtEnd()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether <code>NULL</code> values are sorted at the end regardless of
+ sort order.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullsAreSortedAtStart()"><B>nullsAreSortedAtStart()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether <code>NULL</code> values are sorted at the start regardless
+ of sort order.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullsAreSortedHigh()"><B>nullsAreSortedHigh()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether <code>NULL</code> values are sorted high.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullsAreSortedLow()"><B>nullsAreSortedLow()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether <code>NULL</code> values are sorted low.
+</DL>
+<HR>
+<A NAME="_O_"><!-- --></A><H2>
+<B>O</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#objectMain(java.lang.String[])"><B>objectMain(String[])</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>Connect to a JDBC Database and execute the commands given on
+ stdin or in SQL file(s).
+<DT><A HREF="./org/hsqldb/jdbc/package-summary.html"><B>org.hsqldb.jdbc</B></A> - package org.hsqldb.jdbc<DD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#othersDeletesAreVisible(int)"><B>othersDeletesAreVisible(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether deletes made by others are visible.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#othersInsertsAreVisible(int)"><B>othersInsertsAreVisible(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether inserts made by others are visible.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#othersUpdatesAreVisible(int)"><B>othersUpdatesAreVisible(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether updates made by others are visible.
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#outOfRangeArgument()"><B>outOfRangeArgument()</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#outOfRangeArgument(java.lang.String)"><B>outOfRangeArgument(String)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#ownDeletesAreVisible(int)"><B>ownDeletesAreVisible(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a result set's own deletes are visible.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#ownInsertsAreVisible(int)"><B>ownInsertsAreVisible(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a result set's own inserts are visible.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#ownUpdatesAreVisible(int)"><B>ownUpdatesAreVisible(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether for the given type of <code>ResultSet</code> object,
+ the result set's own updates are visible.
+</DL>
+<HR>
+<A NAME="_P_"><!-- --></A><H2>
+<B>P</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/lib/RCData.html#password"><B>password</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/ServerAcl.html#permitAccess(java.lang.String)"><B>permitAccess(String)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<DD>Uses system network libraries to resolve the given String to an IP addr,
+ then determine whether this address is permitted or denied.
+<DT><A HREF="./org/hsqldb/server/ServerAcl.html#permitAccess(byte[])"><B>permitAccess(byte[])</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#position(byte[], long)"><B>position(byte[], long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Retrieves the byte position at which the specified byte array
+ <code>pattern</code> begins within the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#position(java.sql.Blob, long)"><B>position(Blob, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Retrieves the byte position in the <code>BLOB</code> value
+ designated by this <code>Blob</code> object at which
+ <code>pattern</code> begins.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#position(byte[], long)"><B>position(byte[], long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Retrieves the byte position at which the specified byte array
+ <code>pattern</code> begins within the <code>BLOB</code> value that
+ this <code>Blob</code> object represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#position(java.sql.Blob, long)"><B>position(Blob, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Retrieves the byte position in the <code>BLOB</code> value designated
+ by this <code>Blob</code> object at which <code>pattern</code> begins.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#position(java.lang.String, long)"><B>position(String, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Retrieves the character position at which the specified substring
+ <code>searchstr</code> appears in the SQL <code>CLOB</code> value
+ represented by this <code>Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#position(java.sql.Clob, long)"><B>position(Clob, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Retrieves the character position at which the specified
+ <code>Clob</code> object <code>searchstr</code> appears in this
+ <code>Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#position(java.lang.String, long)"><B>position(String, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Retrieves the character position at which the specified substring
+ <code>searchstr</code> appears in the SQL <code>CLOB</code> value
+ represented by this <code>Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#position(java.sql.Clob, long)"><B>position(Clob, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Retrieves the character position at which the specified
+ <code>Clob</code> object <code>searchstr</code> appears in this
+ <code>Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#precision"><B>precision</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The column's value's number of decimal digits.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String)"><B>prepareCall(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>CallableStatement</code> object for calling
+ database stored procedures.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String, int, int)"><B>prepareCall(String, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>CallableStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String, int, int, int)"><B>prepareCall(String, int, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>CallableStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String)"><B>prepareStatement(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>PreparedStatement</code> object for sending
+ parameterized SQL statements to the database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int, int)"><B>prepareStatement(String, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>PreparedStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int, int, int)"><B>prepareStatement(String, int, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a <code>PreparedStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type, concurrency,
+ and holdability.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int)"><B>prepareStatement(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a default <code>PreparedStatement</code> object that has
+ the capability to retrieve auto-generated keys.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int[])"><B>prepareStatement(String, int[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a default <code>PreparedStatement</code> object capable
+ of returning the auto-generated keys designated by the given array.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, java.lang.String[])"><B>prepareStatement(String, String[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a default <code>PreparedStatement</code> object capable
+ of returning the auto-generated keys designated by the given array.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#previous()"><B>previous()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor to the previous row in this
+ <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#processingInstruction(java.lang.String, java.lang.String)"><B>processingInstruction(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive notification of a processing instruction.
+<DT><A HREF="./org/hsqldb/server/Server.html#putPropertiesFromFile(java.lang.String)"><B>putPropertiesFromFile(String)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Attempts to put properties from the file
+ with the specified path.
+<DT><A HREF="./org/hsqldb/server/Server.html#putPropertiesFromString(java.lang.String)"><B>putPropertiesFromString(String)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Puts properties from the supplied string argument.
+</DL>
+<HR>
+<A NAME="_R_"><!-- --></A><H2>
+<B>R</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib"><B>RCData</B></A> - Class in <A HREF="./org/hsqldb/lib/package-summary.html">org.hsqldb.lib</A><DD>Manages all the details we need to connect up to JDBC database(s),
+ in a declarative way.<DT><A HREF="./org/hsqldb/lib/RCData.html#RCData(java.io.File, java.lang.String)"><B>RCData(File, String)</B></A> - 
+Constructor for class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Creates a RCDataObject by looking up the given key in the
+ given authentication file.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>RCData(String, String, String, String, String, String, String)</B></A> - 
+Constructor for class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Convenience constructor for backward compatibility.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>RCData(String, String, String, String, String, String, String, String)</B></A> - 
+Constructor for class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Wrapper for unset Transaction Isolation.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><B>RCData(String, String, String, String, String, String, String, String, String)</B></A> - 
+Constructor for class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Creates a new <code>RCData</code> object.
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#RCERR_EXITVAL"><B>RCERR_EXITVAL</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/BlobInputStream.html#read()"><B>read()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc">BlobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/ClobInputStream.html#read()"><B>read()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc">ClobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/ClobInputStream.html#read(char[], int, int)"><B>read(char[], int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc">ClobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#refreshRow()"><B>refreshRow()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Refreshes the current row with its most recent value in
+ the database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(int, int)"><B>registerOutParameter(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Registers the OUT parameter in ordinal position
+ <code>parameterIndex</code> to the JDBC type
+ <code>sqlType</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(int, int, int)"><B>registerOutParameter(int, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Registers the parameter in ordinal position
+ <code>parameterIndex</code> to be of JDBC type
+ <code>sqlType</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(int, int, java.lang.String)"><B>registerOutParameter(int, int, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Registers the designated output parameter.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(java.lang.String, int)"><B>registerOutParameter(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Registers the OUT parameter named
+ <code>parameterName</code> to the JDBC type
+ <code>sqlType</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(java.lang.String, int, int)"><B>registerOutParameter(String, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Registers the parameter named
+ <code>parameterName</code> to be of JDBC type
+ <code>sqlType</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(java.lang.String, int, java.lang.String)"><B>registerOutParameter(String, int, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Registers the designated output parameter.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#relative(int)"><B>relative(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Moves the cursor a relative number of rows, either positive or negative.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#releaseSavepoint(java.sql.Savepoint)"><B>releaseSavepoint(Savepoint)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Removes the specified <code>Savepoint</code> (JDBC4 Clarification:) and subsequent <code>Savepoint</code> objects from the current
+ transaction.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#reset()"><B>reset()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Resets this connection so it can be used again.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#result"><B>result</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>The underlying result.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#rollback()"><B>rollback()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Undoes all changes made in the current transaction
+ and releases any database locks currently held
+ by this <code>Connection</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#rollback(java.sql.Savepoint)"><B>rollback(Savepoint)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Undoes all changes made after the given <code>Savepoint</code> object
+ was set.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#rowDeleted()"><B>rowDeleted()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves whether a row has been deleted.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#rowInserted()"><B>rowInserted()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves whether the current row has had an insertion.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#rowUpdated()"><B>rowUpdated()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Retrieves whether the current row has been updated.
+</DL>
+<HR>
+<A NAME="_S_"><!-- --></A><H2>
+<B>S</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#scale"><B>scale</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The column's value's number of digits to right of the decimal point.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#schemaName"><B>schemaName</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The column's table's schema.
+<DT><A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><B>Server</B></A> - Class in <A HREF="./org/hsqldb/server/package-summary.html">org.hsqldb.server</A><DD>The HSQLDB HSQL protocol network database server.<DT><A HREF="./org/hsqldb/server/Server.html#Server()"><B>Server()</B></A> - 
+Constructor for class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Creates a new Server instance handling HSQL protocol connections.
+<DT><A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><B>ServerAcl</B></A> - Class in <A HREF="./org/hsqldb/server/package-summary.html">org.hsqldb.server</A><DD>A list of ACL permit and deny entries with a permitAccess method
+ which tells whether candidate addresses are permitted or denied
+ by this ACL list.<DT><A HREF="./org/hsqldb/server/ServerAcl.html#ServerAcl(java.io.File)"><B>ServerAcl(File)</B></A> - 
+Constructor for class org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><B>ServerAcl.AclFormatException</B></A> - Exception in <A HREF="./org/hsqldb/server/package-summary.html">org.hsqldb.server</A><DD>&nbsp;<DT><A HREF="./org/hsqldb/server/ServerAcl.AclFormatException.html#ServerAcl.AclFormatException(java.lang.String)"><B>ServerAcl.AclFormatException(String)</B></A> - 
+Constructor for exception org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/lib/tar/DbBackup.html#setAbortUponModify(boolean)"><B>setAbortUponModify(boolean)</B></A> - 
+Method in class org.hsqldb.lib.tar.<A HREF="./org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A>
+<DD>Defaults to true.
+<DT><A HREF="./org/hsqldb/server/Server.html#setAddress(java.lang.String)"><B>setAddress(String)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets the InetAddress with which this server's ServerSocket will be
+ constructed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setArray(int, java.sql.Array)"><B>setArray(int, Array)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Array</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setAsciiStream(java.lang.String, java.io.InputStream, int)"><B>setAsciiStream(String, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setAsciiStream(java.lang.String, java.io.InputStream, long)"><B>setAsciiStream(String, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setAsciiStream(java.lang.String, java.io.InputStream)"><B>setAsciiStream(String, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given input stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#setAsciiStream(long)"><B>setAsciiStream(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Retrieves a stream to be used to write Ascii characters to the
+ <code>CLOB</code> value that this <code>Clob</code> object represents,
+ starting at position <code>pos</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#setAsciiStream(long)"><B>setAsciiStream(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Retrieves a stream to be used to write Ascii characters to the
+ <code>CLOB</code> value that this <code>Clob</code> object represents,
+ starting at position <code>pos</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream, int)"><B>setAsciiStream(int, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream, long)"><B>setAsciiStream(int, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream)"><B>setAsciiStream(int, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given input stream.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#setAutoClose(boolean)"><B>setAutoClose(boolean)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Specify whether the supplied or generated input Reader should
+ automatically be closed by the execute() method.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setAutoCommit(boolean)"><B>setAutoCommit(boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Sets this connection's auto-commit mode to the given state.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBigDecimal(java.lang.String, java.math.BigDecimal)"><B>setBigDecimal(String, BigDecimal)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given
+ <code>java.math.BigDecimal</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBigDecimal(int, java.math.BigDecimal)"><B>setBigDecimal(int, BigDecimal)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.math.BigDecimal</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#setBinaryStream(long)"><B>setBinaryStream(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Retrieves a stream that can be used to write to the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#setBinaryStream(long)"><B>setBinaryStream(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Retrieves a stream that can be used to write to the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBinaryStream(java.lang.String, java.io.InputStream, int)"><B>setBinaryStream(String, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBinaryStream(java.lang.String, java.io.InputStream, long)"><B>setBinaryStream(String, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBinaryStream(java.lang.String, java.io.InputStream)"><B>setBinaryStream(String, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given input stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream, int)"><B>setBinaryStream(int, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream, long)"><B>setBinaryStream(int, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream)"><B>setBinaryStream(int, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given input stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#setBinaryStream()"><B>setBinaryStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Retrieves a stream that can be used to write the XML value that this SQLXML instance represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBlob(java.lang.String, java.io.InputStream, long)"><B>setBlob(String, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>InputStream</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBlob(java.lang.String, java.sql.Blob)"><B>setBlob(String, Blob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Blob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBlob(java.lang.String, java.io.InputStream)"><B>setBlob(String, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>InputStream</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.sql.Blob)"><B>setBlob(int, Blob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Blob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.io.InputStream, long)"><B>setBlob(int, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>InputStream</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.io.InputStream)"><B>setBlob(int, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>InputStream</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBoolean(java.lang.String, boolean)"><B>setBoolean(String, boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java <code>boolean</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBoolean(int, boolean)"><B>setBoolean(int, boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java <code>boolean</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setByte(java.lang.String, byte)"><B>setByte(String, byte)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java <code>byte</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setByte(int, byte)"><B>setByte(int, byte)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java <code>byte</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#setBytes(long, byte[])"><B>setBytes(long, byte[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Writes the given array of bytes to the <code>BLOB</code> value that
+ this <code>Blob</code> object represents, starting at position
+ <code>pos</code>, and returns the number of bytes written.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#setBytes(long, byte[], int, int)"><B>setBytes(long, byte[], int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Writes all or part of the given <code>byte</code> array to the
+ <code>BLOB</code> value that this <code>Blob</code> object represents
+ and returns the number of bytes written.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#setBytes(long, byte[])"><B>setBytes(long, byte[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Writes the given array of bytes to the <code>BLOB</code> value that
+ this <code>Blob</code> object represents, starting at position
+ <code>pos</code>, and returns the number of bytes written.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#setBytes(long, byte[], int, int)"><B>setBytes(long, byte[], int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Writes all or part of the given <code>byte</code> array to the
+ <code>BLOB</code> value that this <code>Blob</code> object represents
+ and returns the number of bytes written.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setBytes(java.lang.String, byte[])"><B>setBytes(String, byte[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java array of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setBytes(int, byte[])"><B>setBytes(int, byte[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java array of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setCatalog(java.lang.String)"><B>setCatalog(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Sets the given catalog name in order to select
+ a subspace of this <code>Connection</code> object's database
+ in which to work.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setCharacterStream(java.lang.String, java.io.Reader, int)"><B>setCharacterStream(String, Reader, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setCharacterStream(java.lang.String, java.io.Reader, long)"><B>setCharacterStream(String, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setCharacterStream(java.lang.String, java.io.Reader)"><B>setCharacterStream(String, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#setCharacterStream(long)"><B>setCharacterStream(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Retrieves a stream to be used to write a stream of Unicode characters
+ to the <code>CLOB</code> value that this <code>Clob</code> object
+ represents, at position <code>pos</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#setCharacterStream(long)"><B>setCharacterStream(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Retrieves a stream to be used to write a stream of Unicode characters
+ to the <code>CLOB</code> value that this <code>Clob</code> object
+ represents, at position <code>pos</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader, int)"><B>setCharacterStream(int, Reader, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader, long)"><B>setCharacterStream(int, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader)"><B>setCharacterStream(int, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#setCharacterStream()"><B>setCharacterStream()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Retrieves a stream to be used to write the XML value that this SQLXML instance represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setClientInfo(java.lang.String, java.lang.String)"><B>setClientInfo(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Sets the value of the client info property specified by name to the
+ value specified by value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setClientInfo(java.util.Properties)"><B>setClientInfo(Properties)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Sets the value of the connection's client info properties.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setClob(java.lang.String, java.io.Reader, long)"><B>setClob(String, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setClob(java.lang.String, java.sql.Clob)"><B>setClob(String, Clob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setClob(java.lang.String, java.io.Reader)"><B>setClob(String, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.sql.Clob)"><B>setClob(int, Clob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Clob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.io.Reader, long)"><B>setClob(int, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.io.Reader)"><B>setClob(int, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#setConnection(java.sql.Connection)"><B>setConnection(Connection)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#setContinueOnError(boolean)"><B>setContinueOnError(boolean)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setCursorName(java.lang.String)"><B>setCursorName(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the SQL cursor name to the given <code>String</code>, which
+ will be used by subsequent <code>Statement</code> object
+ <code>execute</code> methods.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#setCursorName(java.lang.String)"><B>setCursorName(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Sets the SQL cursor name to the given <code>String</code>, which
+ will be used by subsequent <code>Statement</code> object
+ <code>execute</code> methods.
+<DT><A HREF="./org/hsqldb/server/Server.html#setDaemon(boolean)"><B>setDaemon(boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets whether server thread is a daemon.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#setDatabase(java.lang.String)"><B>setDatabase(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Assigns the value of this object's jdbc database connection
+ url attribute.
+<DT><A HREF="./org/hsqldb/server/Server.html#setDatabaseName(int, java.lang.String)"><B>setDatabaseName(int, String)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets the external name (url alias) of the i'th hosted database.
+<DT><A HREF="./org/hsqldb/server/Server.html#setDatabasePath(int, java.lang.String)"><B>setDatabasePath(int, String)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets the path of the hosted database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setDate(java.lang.String, java.sql.Date)"><B>setDate(String, Date)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Date</code> value
+ (JDBC4 clarification:)
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setDate(java.lang.String, java.sql.Date, java.util.Calendar)"><B>setDate(String, Date, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Date</code> value,
+ using the given <code>Calendar</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setDate(int, java.sql.Date)"><B>setDate(int, Date)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>(JDBC4 clarification:)
+ Sets the designated parameter to the given <code>java.sql.Date</code> value
+ using the default time zone of the virtual machine that is running
+ the application.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setDate(int, java.sql.Date, java.util.Calendar)"><B>setDate(int, Date, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Date</code> value,
+ using the given <code>Calendar</code> object.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#setDefaultJdbcDriver(java.lang.String)"><B>setDefaultJdbcDriver(String)</B></A> - 
+Method in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/Server.html#setDefaultWebPage(java.lang.String)"><B>setDefaultWebPage(String)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets the name of the web page served when no page is specified.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#setDocumentLocator(org.xml.sax.Locator)"><B>setDocumentLocator(Locator)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive an object for locating the origin of SAX document events.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setDouble(java.lang.String, double)"><B>setDouble(String, double)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java <code>double</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setDouble(int, double)"><B>setDouble(int, double)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java <code>double</code> value.
+<DT><A HREF="./org/hsqldb/server/Server.html#setErrWriter(java.io.PrintWriter)"><B>setErrWriter(PrintWriter)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets the PrintWriter to which server errors are logged.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setEscapeProcessing(boolean)"><B>setEscapeProcessing(boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets escape processing on or off.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#setEscapeProcessing(boolean)"><B>setEscapeProcessing(boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Sets escape processing on or off.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setFetchDirection(int)"><B>setFetchDirection(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Gives the driver a hint as to the direction in which
+ rows will be processed in <code>ResultSet</code>
+ objects created using this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#setFetchDirection(int)"><B>setFetchDirection(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Gives a hint as to the direction in which the rows in this
+ <code>ResultSet</code> object will be processed.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#setFetchDirection(int)"><B>setFetchDirection(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Gives the driver a hint as to the direction in which
+ rows will be processed in <code>ResultSet</code>
+ objects created using this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setFetchSize(int)"><B>setFetchSize(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>(JDBC4 clarification:)
+ Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for
+ <code>ResultSet</code> objects genrated by this <code>Statement</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#setFetchSize(int)"><B>setFetchSize(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for this
+ <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#setFetchSize(int)"><B>setFetchSize(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>(JDBC4 clarification:)
+ Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for
+ <code>ResultSet</code> objects genrated by this <code>Statement</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setFloat(java.lang.String, float)"><B>setFloat(String, float)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java <code>float</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setFloat(int, float)"><B>setFloat(int, float)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java <code>float</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#setGetBinaryStreamUsesCopy(boolean)"><B>setGetBinaryStreamUsesCopy(boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Assigns whether getBinaryStream() uses a copy of
+ the underlying byte[].
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setHoldability(int)"><B>setHoldability(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>(JDBC4 Clarification:)
+ Changes the default holdability of <code>ResultSet</code> objects
+ created using this <code>Connection</code> object to the given
+ holdability.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setInt(java.lang.String, int)"><B>setInt(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java <code>int</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setInt(int, int)"><B>setInt(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java <code>int</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#setLoginTimeout(int)"><B>setLoginTimeout(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Sets the maximum time in seconds that this data source will wait
+ while attempting to connect to a database.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#setLogWriter(java.io.PrintWriter)"><B>setLogWriter(PrintWriter)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Sets the log writer for this <code>DataSource</code>
+ object to the given <code>java.io.PrintWriter</code> object.
+<DT><A HREF="./org/hsqldb/server/Server.html#setLogWriter(java.io.PrintWriter)"><B>setLogWriter(PrintWriter)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets the PrintWriter to which server messages are logged.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setLong(java.lang.String, long)"><B>setLong(String, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java <code>long</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setLong(int, long)"><B>setLong(int, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java <code>long</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setMaxFieldSize(int)"><B>setMaxFieldSize(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>(JDBC4 clarification:) Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
+ Sets the limit for the maximum number of bytes that can be returned for
+ character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#setMaxFieldSize(int)"><B>setMaxFieldSize(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>(JDBC4 clarification:) Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
+ Sets the limit for the maximum number of bytes that can be returned for
+ character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#setMaxHistoryLength(int)"><B>setMaxHistoryLength(int)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setMaxRows(int)"><B>setMaxRows(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>(JDBC4 clarification:)
+ Sets the limit for the maximum number of rows that any
+ <code>ResultSet</code> object  generated by this <code>Statement</code>
+ object can contain to the given number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#setMaxRows(int)"><B>setMaxRows(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>(JDBC4 clarification:)
+ Sets the limit for the maximum number of rows that any
+ <code>ResultSet</code> object  generated by this <code>Statement</code>
+ object can contain to the given number.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setNCharacterStream(java.lang.String, java.io.Reader, long)"><B>setNCharacterStream(String, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setNCharacterStream(java.lang.String, java.io.Reader)"><B>setNCharacterStream(String, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setNCharacterStream(int, java.io.Reader, long)"><B>setNCharacterStream(int, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setNCharacterStream(int, java.io.Reader)"><B>setNCharacterStream(int, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setNClob(java.lang.String, java.sql.NClob)"><B>setNClob(String, NClob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>java.sql.NClob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setNClob(java.lang.String, java.io.Reader, long)"><B>setNClob(String, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setNClob(java.lang.String, java.io.Reader)"><B>setNClob(String, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.sql.NClob)"><B>setNClob(int, NClob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>java.sql.NClob</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.io.Reader, long)"><B>setNClob(int, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.io.Reader)"><B>setNClob(int, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+<DT><A HREF="./org/hsqldb/server/Server.html#setNoSystemExit(boolean)"><B>setNoSystemExit(boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets whether this server calls System.exit() when shutdown.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setNString(java.lang.String, java.lang.String)"><B>setNString(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>String</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setNString(int, java.lang.String)"><B>setNString(int, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated paramter to the given <code>String</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setNull(java.lang.String, int)"><B>setNull(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to SQL <code>NULL</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setNull(java.lang.String, int, java.lang.String)"><B>setNull(String, int, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to SQL <code>NULL</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setNull(int, int)"><B>setNull(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to SQL <code>NULL</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setNull(int, int, java.lang.String)"><B>setNull(int, int, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to SQL <code>NULL</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object, int, int)"><B>setObject(String, Object, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the value of the designated parameter with the given object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object, int)"><B>setObject(String, Object, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the value of the designated parameter with the given object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object)"><B>setObject(String, Object)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the value of the designated parameter with the given object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object, int, int)"><B>setObject(int, Object, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the value of the designated parameter with the given object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object, int)"><B>setObject(int, Object, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the value of the designated parameter with the given object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object)"><B>setObject(int, Object)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/lib/tar/DbBackup.html#setOverWrite(boolean)"><B>setOverWrite(boolean)</B></A> - 
+Method in class org.hsqldb.lib.tar.<A HREF="./org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A>
+<DD>Defaults to false.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#setPassword(java.lang.String)"><B>setPassword(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Sets the password to use for connecting to the database
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setPoolable(boolean)"><B>setPoolable(boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Requests that a <code>Statement</code> be pooled or not pooled.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#setPoolable(boolean)"><B>setPoolable(boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Requests that a <code>Statement</code> be pooled or not pooled.
+<DT><A HREF="./org/hsqldb/server/Server.html#setPort(int)"><B>setPort(int)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets the server listen port.
+<DT><A HREF="./org/hsqldb/server/ServerAcl.html#setPrintWriter(java.io.PrintWriter)"><B>setPrintWriter(PrintWriter)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/Server.html#setProperties(org.hsqldb.persist.HsqlProperties)"><B>setProperties(HsqlProperties)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets server properties using the specified properties object
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setQueryTimeout(int)"><B>setQueryTimeout(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the number of seconds the driver will wait for a
+ <code>Statement</code> object to execute to the given number of seconds.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#setQueryTimeout(int)"><B>setQueryTimeout(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Sets the number of seconds the driver will wait for a
+ <code>Statement</code> object to execute to the given number of seconds.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setReadOnly(boolean)"><B>setReadOnly(boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Puts this connection in read-only mode as a hint to the driver to enable
+ database optimizations.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setRef(int, java.sql.Ref)"><B>setRef(int, Ref)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given
+  <code>REF(&lt;structured-type&gt;)</code> value.
+<DT><A HREF="./org/hsqldb/server/Server.html#setRestartOnShutdown(boolean)"><B>setRestartOnShutdown(boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets whether this server restarts on shutdown.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#setResult(java.lang.Class)"><B>setResult(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Returns a Result for setting the XML value designated by this SQLXML instance.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setRowId(java.lang.String, java.sql.RowId)"><B>setRowId(String, RowId)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.RowId</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setRowId(int, java.sql.RowId)"><B>setRowId(int, RowId)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.RowId</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setSavepoint()"><B>setSavepoint()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates an unnamed savepoint in the current transaction and
+ returns the new <code>Savepoint</code> object that represents it.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setSavepoint(java.lang.String)"><B>setSavepoint(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Creates a savepoint with the given name in the current transaction
+ and returns the new <code>Savepoint</code> object that represents it.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setShort(java.lang.String, short)"><B>setShort(String, short)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java <code>short</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setShort(int, short)"><B>setShort(int, short)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java <code>short</code> value.
+<DT><A HREF="./org/hsqldb/server/Server.html#setSilent(boolean)"><B>setSilent(boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets silent mode operation
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setSQLXML(java.lang.String, java.sql.SQLXML)"><B>setSQLXML(String, SQLXML)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.SQLXML</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setSQLXML(int, java.sql.SQLXML)"><B>setSQLXML(int, SQLXML)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.SQLXML</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setString(java.lang.String, java.lang.String)"><B>setString(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given Java <code>String</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#setString(long, java.lang.String)"><B>setString(long, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Writes the given Java <code>String</code> to the <code>CLOB</code>
+ value that this <code>Clob</code> object designates at the position
+ <code>pos</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#setString(long, java.lang.String, int, int)"><B>setString(long, String, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Writes <code>len</code> characters of <code>str</code>, starting
+ at character <code>offset</code>, to the <code>CLOB</code> value
+ that this <code>Clob</code> represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#setString(long, java.lang.String)"><B>setString(long, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Writes the given Java <code>String</code> to the <code>CLOB</code>
+ value that this <code>Clob</code> object designates at the position
+ <code>pos</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#setString(long, java.lang.String, int, int)"><B>setString(long, String, int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Writes <code>len</code> characters of <code>str</code>, starting at
+ character <code>offset</code>, to the <code>CLOB</code> value that
+ this <code>Clob</code> represents.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setString(int, java.lang.String)"><B>setString(int, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given Java <code>String</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html#setString(java.lang.String)"><B>setString(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A>
+<DD>Sets the XML value designated by this SQLXML instance to the given String representation.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#setTI(java.sql.Connection, java.lang.String)"><B>setTI(Connection, String)</B></A> - 
+Static method in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Set Transaction Isolation level on the specified JDBC Connection
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setTime(java.lang.String, java.sql.Time)"><B>setTime(String, Time)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Time</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setTime(java.lang.String, java.sql.Time, java.util.Calendar)"><B>setTime(String, Time, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Time</code> value,
+ using the given <code>Calendar</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setTime(int, java.sql.Time)"><B>setTime(int, Time)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Time</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setTime(int, java.sql.Time, java.util.Calendar)"><B>setTime(int, Time, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Time</code> value,
+ using the given <code>Calendar</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setTimestamp(java.lang.String, java.sql.Timestamp)"><B>setTimestamp(String, Timestamp)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setTimestamp(java.lang.String, java.sql.Timestamp, java.util.Calendar)"><B>setTimestamp(String, Timestamp, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
+ using the given <code>Calendar</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setTimestamp(int, java.sql.Timestamp)"><B>setTimestamp(int, Timestamp)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setTimestamp(int, java.sql.Timestamp, java.util.Calendar)"><B>setTimestamp(int, Timestamp, Calendar)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
+ using the given <code>Calendar</code> object.
+<DT><A HREF="./org/hsqldb/server/Server.html#setTls(boolean)"><B>setTls(boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets whether to use secure sockets
+<DT><A HREF="./org/hsqldb/server/Server.html#setTrace(boolean)"><B>setTrace(boolean)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets whether trace messages go to System.out or the
+ DriverManger PrintStream/PrintWriter, if any.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setTransactionIsolation(int)"><B>setTransactionIsolation(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD><code>Connection</code> object to the one given.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#setTypeMap(java.util.Map)"><B>setTypeMap(Map&lt;String, Class&lt;?&gt;&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Installs the given <code>TypeMap</code> object as the type map for
+ this <code>Connection</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setUnicodeStream(int, java.io.InputStream, int)"><B>setUnicodeStream(int, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Sun does not include a reason, but presumably
+      this is because setCharacterStream is now prefered</I>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#setURL(java.lang.String, java.net.URL)"><B>setURL(String, URL)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Sets the designated parameter to the given <code>java.net.URL</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#setURL(int, java.net.URL)"><B>setURL(int, URL)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Sets the designated parameter to the given <code>java.net.URL</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#setUser(java.lang.String)"><B>setUser(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Sets the userid
+<DT><A HREF="./org/hsqldb/server/Server.html#setWebRoot(java.lang.String)"><B>setWebRoot(String)</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Sets the path of the root directory from which web content is served.
+<DT><A HREF="./org/hsqldb/server/Server.html#shutdown()"><B>shutdown()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>External method to shut down this server.
+<DT><A HREF="./org/hsqldb/server/Server.html#signalCloseAllServerConnections()"><B>signalCloseAllServerConnections()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Closes all connections to this Server.
+<DT><A HREF="./org/hsqldb/jdbc/BlobInputStream.html#skip(long)"><B>skip(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc">BlobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/ClobInputStream.html#skip(long)"><B>skip(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc">ClobInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#skippedEntity(java.lang.String)"><B>skippedEntity(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive notification of a skipped entity.
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#SQLERR_EXITVAL"><B>SQLERR_EXITVAL</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlException(org.hsqldb.HsqlException)"><B>sqlException(HsqlException)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlException(org.hsqldb.HsqlException, java.lang.Throwable)"><B>sqlException(HsqlException, Throwable)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlException(int)"><B>sqlException(int)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlException(int, java.lang.String)"><B>sqlException(int, String)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlException(int, java.lang.String, java.lang.Exception)"><B>sqlException(int, String, Exception)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlException(int, int)"><B>sqlException(int, int)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlException(org.hsqldb.result.Result)"><B>sqlException(Result)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlException(java.lang.String, java.lang.String, int, java.lang.Throwable)"><B>sqlException(String, String, int, Throwable)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlExceptionSQL(int)"><B>sqlExceptionSQL(int)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><B>SqlFile</B></A> - Class in <A HREF="./org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A><DD>Encapsulation of SQL text and the environment under which it will executed
+ with a JDBC Connection.<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.File)"><B>SqlFile(File)</B></A> - 
+Constructor for class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Convenience wrapper for the SqlFile(File, String) constructor
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.File, java.lang.String)"><B>SqlFile(File, String)</B></A> - 
+Constructor for class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Convenience wrapper for the SqlFile(File, String, boolean) constructor
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.File, java.lang.String, boolean)"><B>SqlFile(File, String, boolean)</B></A> - 
+Constructor for class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Constructor for non-interactive usage with a SQL file, using the
+ specified encoding and sending normal output to stdout.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#SqlFile(java.lang.String, boolean)"><B>SqlFile(String, boolean)</B></A> - 
+Constructor for class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Constructor for interactive usage with stdin/stdout
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.Reader, java.lang.String, java.io.PrintStream, java.lang.String, boolean)"><B>SqlFile(Reader, String, PrintStream, String, boolean)</B></A> - 
+Constructor for class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Instantiate a SqlFile instance for SQL input from 'reader'.
+<DT><A HREF="./org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><B>SqlFileEmbedder</B></A> - Class in <A HREF="./org/hsqldb/sample/package-summary.html">org.hsqldb.sample</A><DD>Sample class which executes SQL files, by embedding SqlFile.<DT><A HREF="./org/hsqldb/sample/SqlFileEmbedder.html#SqlFileEmbedder(java.io.File, java.lang.String)"><B>SqlFileEmbedder(File, String)</B></A> - 
+Constructor for class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample">SqlFileEmbedder</A>
+<DD>Instantiates SqlFileEmbedder object and connects to specified database.
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><B>SqlTool</B></A> - Class in <A HREF="./org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A><DD>A command-line JDBC SQL tool supporting both interactive and
+ non-interactive usage.<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#SqlTool()"><B>SqlTool()</B></A> - 
+Constructor for class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline"><B>SqlTool.SqlToolException</B></A> - Exception in <A HREF="./org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A><DD>&nbsp;<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#SQLTOOLERR_EXITVAL"><B>SQLTOOLERR_EXITVAL</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#sqlTypeToString(int)"><B>sqlTypeToString(int)</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>Return a String representation of the specified java.sql.Types type.
+<DT><A HREF="./org/hsqldb/jdbc/Util.html#sqlWarning(org.hsqldb.result.Result)"><B>sqlWarning(Result)</B></A> - 
+Static method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/Server.html#start()"><B>start()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Starts this server synchronously.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startDocument()"><B>startDocument()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive notification of the beginning of a document.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)"><B>startElement(String, String, String, Attributes)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Receive notification of the beginning of an element.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startPrefixMapping(java.lang.String, java.lang.String)"><B>startPrefixMapping(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<DD>Begin the scope of a prefix-URI Namespace mapping.
+<DT><A HREF="./org/hsqldb/server/Server.html#stop()"><B>stop()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A>
+<DD>Stops this server asynchronously.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesLowerCaseIdentifiers()"><B>storesLowerCaseIdentifiers()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in lower case.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesLowerCaseQuotedIdentifiers()"><B>storesLowerCaseQuotedIdentifiers()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in lower case.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesMixedCaseIdentifiers()"><B>storesMixedCaseIdentifiers()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in mixed case.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesMixedCaseQuotedIdentifiers()"><B>storesMixedCaseQuotedIdentifiers()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in mixed case.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseIdentifiers()"><B>storesUpperCaseIdentifiers()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in upper case.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseQuotedIdentifiers()"><B>storesUpperCaseQuotedIdentifiers()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in upper case.
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#streamToBytes(java.io.InputStream)"><B>streamToBytes(InputStream)</B></A> - 
+Static method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>As the name says...
+<DT><A HREF="./org/hsqldb/cmdline/SqlFile.html#streamToString(java.io.InputStream, java.lang.String)"><B>streamToString(InputStream, String)</B></A> - 
+Method in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A>
+<DD>As the name says...
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsAlterTableWithAddColumn()"><B>supportsAlterTableWithAddColumn()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports <code>ALTER TABLE</code>
+ with add column.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsAlterTableWithDropColumn()"><B>supportsAlterTableWithDropColumn()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports <code>ALTER TABLE</code>
+ with drop column.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsANSI92EntryLevelSQL()"><B>supportsANSI92EntryLevelSQL()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the ANSI92 entry level SQL
+ grammar.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsANSI92FullSQL()"><B>supportsANSI92FullSQL()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the ANSI92 full SQL grammar supported.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsANSI92IntermediateSQL()"><B>supportsANSI92IntermediateSQL()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the ANSI92 intermediate SQL grammar supported.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsBatchUpdates()"><B>supportsBatchUpdates()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports batch updates.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInDataManipulation()"><B>supportsCatalogsInDataManipulation()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a catalog name can be used in a data manipulation statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInIndexDefinitions()"><B>supportsCatalogsInIndexDefinitions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a catalog name can be used in an index definition statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInPrivilegeDefinitions()"><B>supportsCatalogsInPrivilegeDefinitions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a catalog name can be used in a privilege definition statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInProcedureCalls()"><B>supportsCatalogsInProcedureCalls()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a catalog name can be used in a procedure call statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInTableDefinitions()"><B>supportsCatalogsInTableDefinitions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a catalog name can be used in a table definition statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsColumnAliasing()"><B>supportsColumnAliasing()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports column aliasing.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsConvert()"><B>supportsConvert()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>(JDBC4 clarification:)
+ Retrieves whether this database supports the JDBC scalar function
+ <code>CONVERT</code> for the conversion of one JDBC type to another.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsConvert(int, int)"><B>supportsConvert(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>(JDBC4 clarification:)
+ Retrieves whether this database supports the JDBC scalar function
+ <code>CONVERT</code> for conversions between the JDBC types <i>fromType</i>
+ and <i>toType</i>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCoreSQLGrammar()"><B>supportsCoreSQLGrammar()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the ODBC Core SQL grammar.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCorrelatedSubqueries()"><B>supportsCorrelatedSubqueries()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports correlated subqueries.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsDataDefinitionAndDataManipulationTransactions()"><B>supportsDataDefinitionAndDataManipulationTransactions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports both data definition and
+ data manipulation statements within a transaction.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsDataManipulationTransactionsOnly()"><B>supportsDataManipulationTransactionsOnly()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports only data manipulation
+ statements within a transaction.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsDifferentTableCorrelationNames()"><B>supportsDifferentTableCorrelationNames()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether, when table correlation names are supported, they
+ are restricted to being different from the names of the tables.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsExpressionsInOrderBy()"><B>supportsExpressionsInOrderBy()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports expressions in
+ <code>ORDER BY</code> lists.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsExtendedSQLGrammar()"><B>supportsExtendedSQLGrammar()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the ODBC Extended SQL grammar.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsFullOuterJoins()"><B>supportsFullOuterJoins()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports full nested outer joins.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsGetGeneratedKeys()"><B>supportsGetGeneratedKeys()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether auto-generated keys can be retrieved after
+ a statement has been executed
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsGroupBy()"><B>supportsGroupBy()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports some form of
+ <code>GROUP BY</code> clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsGroupByBeyondSelect()"><B>supportsGroupByBeyondSelect()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports using columns not included in
+ the <code>SELECT</code> statement in a <code>GROUP BY</code> clause
+ provided that all of the columns in the <code>SELECT</code> statement
+ are included in the <code>GROUP BY</code> clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsGroupByUnrelated()"><B>supportsGroupByUnrelated()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports using a column that is
+ not in the <code>SELECT</code> statement in a
+ <code>GROUP BY</code> clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsIntegrityEnhancementFacility()"><B>supportsIntegrityEnhancementFacility()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the SQL Integrity
+ Enhancement Facility.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsLikeEscapeClause()"><B>supportsLikeEscapeClause()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports specifying a
+ <code>LIKE</code> escape clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsLimitedOuterJoins()"><B>supportsLimitedOuterJoins()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database provides limited support for outer
+ joins.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMinimumSQLGrammar()"><B>supportsMinimumSQLGrammar()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the ODBC Minimum SQL grammar.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseIdentifiers()"><B>supportsMixedCaseIdentifiers()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case sensitive and as a result stores them in mixed case.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseQuotedIdentifiers()"><B>supportsMixedCaseQuotedIdentifiers()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case sensitive and as a result stores them in mixed case.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMultipleOpenResults()"><B>supportsMultipleOpenResults()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether it is possible to have multiple <code>ResultSet</code> objects
+ returned from a <code>CallableStatement</code> object
+ simultaneously.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMultipleResultSets()"><B>supportsMultipleResultSets()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports getting multiple
+ <code>ResultSet</code> objects from a single call to the
+ method <code>execute</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMultipleTransactions()"><B>supportsMultipleTransactions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database allows having multiple
+ transactions open at once (on different connections).
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsNamedParameters()"><B>supportsNamedParameters()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports named parameters to callable
+ statements.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsNonNullableColumns()"><B>supportsNonNullableColumns()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether columns in this database may be defined as non-nullable.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOpenCursorsAcrossCommit()"><B>supportsOpenCursorsAcrossCommit()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports keeping cursors open
+ across commits.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOpenCursorsAcrossRollback()"><B>supportsOpenCursorsAcrossRollback()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports keeping cursors open
+ across rollbacks.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOpenStatementsAcrossCommit()"><B>supportsOpenStatementsAcrossCommit()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports keeping statements open
+ across commits.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOpenStatementsAcrossRollback()"><B>supportsOpenStatementsAcrossRollback()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports keeping statements open
+ across rollbacks.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOrderByUnrelated()"><B>supportsOrderByUnrelated()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports using a column that is
+ not in the <code>SELECT</code> statement in an
+ <code>ORDER BY</code> clause.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOuterJoins()"><B>supportsOuterJoins()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports some form of outer join.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsPositionedDelete()"><B>supportsPositionedDelete()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports positioned <code>DELETE</code>
+ statements.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsPositionedUpdate()"><B>supportsPositionedUpdate()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports positioned <code>UPDATE</code>
+ statements.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsResultSetConcurrency(int, int)"><B>supportsResultSetConcurrency(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the given concurrency type
+ in combination with the given result set type.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsResultSetHoldability(int)"><B>supportsResultSetHoldability(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the given result set holdability.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsResultSetType(int)"><B>supportsResultSetType(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the given result set type.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSavepoints()"><B>supportsSavepoints()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports savepoints.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInDataManipulation()"><B>supportsSchemasInDataManipulation()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a schema name can be used in a data manipulation statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInIndexDefinitions()"><B>supportsSchemasInIndexDefinitions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a schema name can be used in an index definition statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInPrivilegeDefinitions()"><B>supportsSchemasInPrivilegeDefinitions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a schema name can be used in a privilege definition statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInProcedureCalls()"><B>supportsSchemasInProcedureCalls()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a schema name can be used in a procedure call statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInTableDefinitions()"><B>supportsSchemasInTableDefinitions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether a schema name can be used in a table definition statement.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSelectForUpdate()"><B>supportsSelectForUpdate()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports <code>SELECT FOR UPDATE</code>
+ statements.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsStatementPooling()"><B>supportsStatementPooling()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports statement pooling.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsStoredFunctionsUsingCallSyntax()"><B>supportsStoredFunctionsUsingCallSyntax()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports invoking user-defined or vendor functions
+ using the stored procedure escape syntax.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsStoredProcedures()"><B>supportsStoredProcedures()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports stored procedure calls
+ that use the stored procedure escape syntax.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSubqueriesInComparisons()"><B>supportsSubqueriesInComparisons()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports subqueries in comparison
+ expressions.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSubqueriesInExists()"><B>supportsSubqueriesInExists()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports subqueries in
+ <code>EXISTS</code> expressions.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSubqueriesInIns()"><B>supportsSubqueriesInIns()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>(JDBC4 correction:)
+ Retrieves whether this database supports subqueries in
+ <code>IN</code> expressions.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSubqueriesInQuantifieds()"><B>supportsSubqueriesInQuantifieds()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports subqueries in quantified
+ expressions.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsTableCorrelationNames()"><B>supportsTableCorrelationNames()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports table correlation names.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsTransactionIsolationLevel(int)"><B>supportsTransactionIsolationLevel(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports the given transaction isolation level.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsTransactions()"><B>supportsTransactions()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports transactions.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsUnion()"><B>supportsUnion()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports SQL <code>UNION</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsUnionAll()"><B>supportsUnionAll()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database supports SQL <code>UNION ALL</code>.
+<DT><A HREF="./org/hsqldb/cmdline/SqlTool.html#SYNTAXERR_EXITVAL"><B>SYNTAXERR_EXITVAL</B></A> - 
+Static variable in class org.hsqldb.cmdline.<A HREF="./org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_T_"><!-- --></A><H2>
+<B>T</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#tableName"><B>tableName</B></A> - 
+Variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>The column's table's name.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#ti"><B>ti</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/lib/RCData.html#tiToString(int)"><B>tiToString(int)</B></A> - 
+Static method in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>Return a String representation for the given numerical
+ java.sql.Connection Transaction level.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCArray.html#toString()"><B>toString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A>
+<DD>Returns a string representation in the form <code>ARRAY[..., ...]</code>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html#toString()"><B>toString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A>
+<DD>Retrieves a String representation of this object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#toString()"><B>toString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Retrieves a String repsentation of this object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#toString()"><B>toString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Retrieves a String representation of this object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#toString()"><B>toString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Returns a string representation of the object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCRowId.html#toString()"><B>toString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A>
+<DD>Returns a String representing the value of the SQL ROWID designated by this
+ <code>java.sql.RowId</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCSavepoint.html#toString()"><B>toString()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc">JDBCSavepoint</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/server/ServerAcl.html#toString()"><B>toString()</B></A> - 
+Method in class org.hsqldb.server.<A HREF="./org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb"><B>Trigger</B></A> - Interface in <A HREF="./org/hsqldb/package-summary.html">org.hsqldb</A><DD>The interface an HSQLDB TRIGGER must implement.<DT><A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample"><B>TriggerSample</B></A> - Class in <A HREF="./org/hsqldb/sample/package-summary.html">org.hsqldb.sample</A><DD>Sample code for use of triggers in hsqldb.<DT><A HREF="./org/hsqldb/sample/TriggerSample.html#TriggerSample()"><B>TriggerSample()</B></A> - 
+Constructor for class org.hsqldb.sample.<A HREF="./org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlob.html#truncate(long)"><B>truncate(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A>
+<DD>Truncates the <code>BLOB</code> value that this <code>Blob</code>
+ object represents to be <code>len</code> bytes in length.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html#truncate(long)"><B>truncate(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>
+<DD>Truncates the <code>BLOB</code> value that this <code>Blob</code>
+ object represents to be <code>len</code> bytes in length.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClob.html#truncate(long)"><B>truncate(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A>
+<DD>Truncates the <code>CLOB</code> value that this <code>Clob</code>
+ designates to have a length of <code>len</code>
+ characters.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCClobClient.html#truncate(long)"><B>truncate(long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>
+<DD>Truncates the <code>CLOB</code> value that this <code>Clob</code>
+ designates to have a length of <code>len</code> characters.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#truststore"><B>truststore</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#TYPE_FORWARD_ONLY"><B>TYPE_FORWARD_ONLY</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#TYPE_SCROLL_INSENSITIVE"><B>TYPE_SCROLL_INSENSITIVE</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#TYPE_SCROLL_SENSITIVE"><B>TYPE_SCROLL_SENSITIVE</B></A> - 
+Static variable in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+</DL>
+<HR>
+<A NAME="_U_"><!-- --></A><H2>
+<B>U</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCConnection.html#unwrap(java.lang.Class)"><B>unwrap(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#unwrap(java.lang.Class)"><B>unwrap(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Returns an object that implements the given interface to allow access to non-standard methods,
+ or standard methods not exposed by the proxy.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDataSource.html#unwrap(java.lang.Class)"><B>unwrap(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html#unwrap(java.lang.Class)"><B>unwrap(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html#unwrap(java.lang.Class)"><B>unwrap(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#unwrap(java.lang.Class)"><B>unwrap(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html#unwrap(java.lang.Class)"><B>unwrap(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCStatement.html#unwrap(java.lang.Class)"><B>unwrap(Class&lt;T&gt;)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+<DT><A HREF="./org/hsqldb/Trigger.html#UPDATE_AFTER"><B>UPDATE_AFTER</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html#UPDATE_AFTER_ROW"><B>UPDATE_AFTER_ROW</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/Trigger.html#UPDATE_BEFORE_ROW"><B>UPDATE_BEFORE_ROW</B></A> - 
+Static variable in interface org.hsqldb.<A HREF="./org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateArray(int, java.sql.Array)"><B>updateArray(int, Array)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Array</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateArray(java.lang.String, java.sql.Array)"><B>updateArray(String, Array)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Array</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(int, java.io.InputStream, int)"><B>updateAsciiStream(int, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>(JDBC4 clarification:)
+ Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(java.lang.String, java.io.InputStream, int)"><B>updateAsciiStream(String, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>(JDBC4 clarification:)
+ Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(int, java.io.InputStream, long)"><B>updateAsciiStream(int, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(java.lang.String, java.io.InputStream, long)"><B>updateAsciiStream(String, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes..
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(int, java.io.InputStream)"><B>updateAsciiStream(int, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an ascii stream value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(java.lang.String, java.io.InputStream)"><B>updateAsciiStream(String, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an ascii stream value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBigDecimal(int, java.math.BigDecimal)"><B>updateBigDecimal(int, BigDecimal)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.math.BigDecimal</code>
+ value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBigDecimal(java.lang.String, java.math.BigDecimal)"><B>updateBigDecimal(String, BigDecimal)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.BigDecimal</code>
+ value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(int, java.io.InputStream, int)"><B>updateBinaryStream(int, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>(JDBC4 clarification:)
+ Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(java.lang.String, java.io.InputStream, int)"><B>updateBinaryStream(String, InputStream, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>(JDBC4 clarification:)
+ Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(int, java.io.InputStream, long)"><B>updateBinaryStream(int, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(java.lang.String, java.io.InputStream, long)"><B>updateBinaryStream(String, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(int, java.io.InputStream)"><B>updateBinaryStream(int, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a binary stream value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(java.lang.String, java.io.InputStream)"><B>updateBinaryStream(String, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a binary stream value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(int, java.sql.Blob)"><B>updateBlob(int, Blob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Blob</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(java.lang.String, java.sql.Blob)"><B>updateBlob(String, Blob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Blob</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(int, java.io.InputStream, long)"><B>updateBlob(int, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given input stream, which
+ will have the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(java.lang.String, java.io.InputStream, long)"><B>updateBlob(String, InputStream, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given input stream, which
+ will have the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(int, java.io.InputStream)"><B>updateBlob(int, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given input stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(java.lang.String, java.io.InputStream)"><B>updateBlob(String, InputStream)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given input stream.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBoolean(int, boolean)"><B>updateBoolean(int, boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>boolean</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBoolean(java.lang.String, boolean)"><B>updateBoolean(String, boolean)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>boolean</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateByte(int, byte)"><B>updateByte(int, byte)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>byte</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateByte(java.lang.String, byte)"><B>updateByte(String, byte)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>byte</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBytes(int, byte[])"><B>updateBytes(int, byte[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>byte</code> array value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateBytes(java.lang.String, byte[])"><B>updateBytes(String, byte[])</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a byte array value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(int, java.io.Reader, int)"><B>updateCharacterStream(int, Reader, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>(JDBC4 clarification:)
+ Updates the designated column with a character stream value, which will have
+ the specified number of (CHECKME: characters?) bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(java.lang.String, java.io.Reader, int)"><B>updateCharacterStream(String, Reader, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>(JDBC4 clarification)
+ Updates the designated column with a character stream value, which will have
+ the specified number of (CHECKME: characters?) bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(int, java.io.Reader, long)"><B>updateCharacterStream(int, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a character stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(java.lang.String, java.io.Reader, long)"><B>updateCharacterStream(String, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a character stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(int, java.io.Reader)"><B>updateCharacterStream(int, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a character stream value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(java.lang.String, java.io.Reader)"><B>updateCharacterStream(String, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a character stream value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateClob(int, java.sql.Clob)"><B>updateClob(int, Clob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Clob</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateClob(java.lang.String, java.sql.Clob)"><B>updateClob(String, Clob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Clob</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateClob(int, java.io.Reader, long)"><B>updateClob(int, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateClob(java.lang.String, java.io.Reader, long)"><B>updateClob(String, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateClob(int, java.io.Reader)"><B>updateClob(int, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateClob(java.lang.String, java.io.Reader)"><B>updateClob(String, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateDate(int, java.sql.Date)"><B>updateDate(int, Date)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Date</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateDate(java.lang.String, java.sql.Date)"><B>updateDate(String, Date)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Date</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateDouble(int, double)"><B>updateDouble(int, double)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>double</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateDouble(java.lang.String, double)"><B>updateDouble(String, double)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>double</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateFloat(int, float)"><B>updateFloat(int, float)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>float</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateFloat(java.lang.String, float)"><B>updateFloat(String, float)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>float </code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateInt(int, int)"><B>updateInt(int, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an <code>int</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateInt(java.lang.String, int)"><B>updateInt(String, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an <code>int</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateLong(int, long)"><B>updateLong(int, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>long</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateLong(java.lang.String, long)"><B>updateLong(String, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>long</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNCharacterStream(int, java.io.Reader, long)"><B>updateNCharacterStream(int, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a character stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNCharacterStream(java.lang.String, java.io.Reader, long)"><B>updateNCharacterStream(String, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a character stream value, which will have
+ the specified number of bytes.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNCharacterStream(int, java.io.Reader)"><B>updateNCharacterStream(int, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a character stream value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNCharacterStream(java.lang.String, java.io.Reader)"><B>updateNCharacterStream(String, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a character stream value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(int, java.sql.NClob)"><B>updateNClob(int, NClob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.NClob</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(java.lang.String, java.sql.NClob)"><B>updateNClob(String, NClob)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.NClob</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(int, java.io.Reader, long)"><B>updateNClob(int, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given <code>Reader</code>
+  object, which is the given number of characters long.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(java.lang.String, java.io.Reader, long)"><B>updateNClob(String, Reader, long)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(int, java.io.Reader)"><B>updateNClob(int, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given <code>Reader</code>
+
+  The data will be read from the stream
+  as needed until end-of-stream is reached.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(java.lang.String, java.io.Reader)"><B>updateNClob(String, Reader)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNString(int, java.lang.String)"><B>updateNString(int, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>String</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNString(java.lang.String, java.lang.String)"><B>updateNString(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>String</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNull(int)"><B>updateNull(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>(JDBC4 clarification:)
+ Updates the designated column with a <code>null</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateNull(java.lang.String)"><B>updateNull(String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>null</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateObject(int, java.lang.Object, int)"><B>updateObject(int, Object, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an <code>Object</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateObject(int, java.lang.Object)"><B>updateObject(int, Object)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an <code>Object</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateObject(java.lang.String, java.lang.Object, int)"><B>updateObject(String, Object, int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an <code>Object</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateObject(java.lang.String, java.lang.Object)"><B>updateObject(String, Object)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with an <code>Object</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateRef(int, java.sql.Ref)"><B>updateRef(int, Ref)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Ref</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateRef(java.lang.String, java.sql.Ref)"><B>updateRef(String, Ref)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Ref</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateRow()"><B>updateRow()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the underlying database with the new contents of the
+ current row of this <code>ResultSet</code> object.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateRowId(int, java.sql.RowId)"><B>updateRowId(int, RowId)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>RowId</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateRowId(java.lang.String, java.sql.RowId)"><B>updateRowId(String, RowId)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>RowId</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#updatesAreDetected(int)"><B>updatesAreDetected(int)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether or not a visible row update can be detected by
+ calling the method <code>ResultSet.rowUpdated</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateShort(int, short)"><B>updateShort(int, short)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>short</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateShort(java.lang.String, short)"><B>updateShort(String, short)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>short</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateSQLXML(int, java.sql.SQLXML)"><B>updateSQLXML(int, SQLXML)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.SQLXML</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateSQLXML(java.lang.String, java.sql.SQLXML)"><B>updateSQLXML(String, SQLXML)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.SQLXML</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateString(int, java.lang.String)"><B>updateString(int, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>String</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateString(java.lang.String, java.lang.String)"><B>updateString(String, String)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>String</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateTime(int, java.sql.Time)"><B>updateTime(int, Time)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Time</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateTime(java.lang.String, java.sql.Time)"><B>updateTime(String, Time)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Time</code> value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateTimestamp(int, java.sql.Timestamp)"><B>updateTimestamp(int, Timestamp)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Timestamp</code>
+ value.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#updateTimestamp(java.lang.String, java.sql.Timestamp)"><B>updateTimestamp(String, Timestamp)</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Updates the designated column with a <code>java.sql.Timestamp</code>
+ value.
+<DT><A HREF="./org/hsqldb/lib/RCData.html#url"><B>url</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/lib/RCData.html#username"><B>username</B></A> - 
+Variable in class org.hsqldb.lib.<A HREF="./org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#usesLocalFilePerTable()"><B>usesLocalFilePerTable()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database uses a file for each table.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html#usesLocalFiles()"><B>usesLocalFiles()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A>
+<DD>Retrieves whether this database stores tables in a local file.
+<DT><A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc"><B>Util</B></A> - Class in <A HREF="./org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A><DD>Provides driver constants and a gateway from internal HsqlExceptions to
+ external SQLExceptions.<DT><A HREF="./org/hsqldb/jdbc/Util.html#Util()"><B>Util()</B></A> - 
+Constructor for class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_W_"><!-- --></A><H2>
+<B>W</B></H2>
+<DL>
+<DT><A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html#wasNull()"><B>wasNull()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A>
+<DD>Retrieves whether the last OUT parameter read had the value of
+ SQL <code>NULL</code>.
+<DT><A HREF="./org/hsqldb/jdbc/JDBCResultSet.html#wasNull()"><B>wasNull()</B></A> - 
+Method in class org.hsqldb.jdbc.<A HREF="./org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A>
+<DD>Reports whether
+ the last column read had a value of SQL <code>NULL</code>.
+<DT><A HREF="./org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server"><B>WebServer</B></A> - Class in <A HREF="./org/hsqldb/server/package-summary.html">org.hsqldb.server</A><DD>The HSQLDB HTTP protocol network database server.<DT><A HREF="./org/hsqldb/server/WebServer.html#WebServer()"><B>WebServer()</B></A> - 
+Constructor for class org.hsqldb.server.<A HREF="./org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A>
+<DD>&nbsp;
+<DT><A HREF="./org/hsqldb/lib/tar/DbBackup.html#write()"><B>write()</B></A> - 
+Method in class org.hsqldb.lib.tar.<A HREF="./org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A>
+<DD>This method always backs up the .properties and .script files.
+</DL>
+<HR>
+<A HREF="#_A_">A</A> <A HREF="#_B_">B</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_F_">F</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_J_">J</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_P_">P</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_W_">W</A> 
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="./overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="./overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="./deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="./help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="./index.html?index-all.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="index-all.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="./allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="./allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/index.html b/doc/apidocs/index.html
new file mode 100644
index 0000000..f11da55
--- /dev/null
+++ b/doc/apidocs/index.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Jun 06 23:05:47 EDT 2010-->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+HSQLDB 2.0.0 API
+</TITLE>
+<SCRIPT type="text/javascript">
+    targetPage = "" + window.location.search;
+    if (targetPage != "" && targetPage != "undefined")
+        targetPage = targetPage.substring(1);
+    if (targetPage.indexOf(":") != -1)
+        targetPage = "undefined";
+    function loadFrames() {
+        if (targetPage != "" && targetPage != "undefined")
+             top.classFrame.location = top.targetPage;
+    }
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+</HEAD>
+<FRAMESET cols="20%,80%" title="" onLoad="top.loadFrames()">
+<FRAMESET rows="30%,70%" title="" onLoad="top.loadFrames()">
+<FRAME src="overview-frame.html" name="packageListFrame" title="All Packages">
+<FRAME src="allclasses-frame.html" name="packageFrame" title="All classes and interfaces (except non-static nested types)">
+</FRAMESET>
+<FRAME src="overview-summary.html" name="classFrame" title="Package, class and interface descriptions" scrolling="yes">
+<NOFRAMES>
+<H2>
+Frame Alert</H2>
+
+<P>
+This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+<BR>
+Link to<A HREF="overview-summary.html">Non-frame version.</A>
+</NOFRAMES>
+</FRAMESET>
+</HTML>
diff --git a/doc/apidocs/javadoc.css b/doc/apidocs/javadoc.css
new file mode 100644
index 0000000..5b3fb93
--- /dev/null
+++ b/doc/apidocs/javadoc.css
@@ -0,0 +1,91 @@
+/* Javadoc style sheet */
+
+/* Define colors, fonts and other style attributes here to override the defaults */
+
+/* Page background color, width % */
+body { background-color: #FFFFFF; padding-right: 1em; }
+
+/* Table colors */
+.TableHeadingColor     { background: #CCCCFF } /* Dark mauve */
+.TableSubHeadingColor  { background: #EEEEFF } /* Light mauve */
+.TableRowColor         { background: #FFFFFF } /* White */
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont   { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+.FrameHeadingFont { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+.FrameItemFont    { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+
+/* Example of smaller, sans-serif font in frames */
+/* .FrameItemFont  { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */
+
+/* Navigation bar fonts and colors */
+.NavBarCell1    { background-color: #EEEEFF;}/* Light mauve */
+.NavBarCell1Rev { background-color: #00008B;}/* Dark Blue */
+.NavBarFont1    { font-family: Arial, Helvetica, sans-serif; color: #000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color: #FFFFFF;}
+
+.NavBarCell2    { font-family: Arial, Helvetica, sans-serif; background-color: #FFFFFF;}
+.NavBarCell3    { font-family: Arial, Helvetica, sans-serif; background-color: #FFFFFF;}
+
+.GenericDocumentation { color: #000000; }
+
+DIV.ReleaseSpecificDocumentation { 
+        color:              #006A00;
+        background-color:   #EEEEFF;
+        border:             2px ridge white;
+        padding-top:        5px;
+        padding-right:      10px;
+        padding-bottom:     5px;
+        padding-left:       10px;
+        text-align:         justify;
+}
+
+DIV.ReleaseSpecificDocumentation h3 {
+	margin-top:         0px;
+	margin-left:        0px;
+	margin-right:       0px;
+        padding-top:        14px;
+        padding-right:      0px;
+        padding-bottom:     15px;
+        padding-left:       50px;
+        border-top:         1px dashed rgb(120,172,255);
+	border-bottom:      1px dashed rgb(120,172,255);
+        background:         url(hsqldb.gif) #E6E6FF no-repeat left center;
+}
+
+PRE.JavaCodeExample   { 
+        color:              #000000; 
+        background-color:   #EEEEEE;
+        border:             1px ridge white;
+        padding-top:        1em;
+        padding-right:      1em;
+        padding-bottom:     0em;
+        padding-left:       1em;
+}
+
+.JavaStringLiteral { color: #99006B; }
+.JavaNumericLiteral { color: #780000; }
+.JavaKeyWord       { color: #000099; font-weight: bold; }
+
+PRE.SqlCodeExample   {
+        /*color:              #550022;*/
+        color:              #601030; 
+        background-color:   #EEEEEE; 
+        border:             1px ridge white;
+        font-weight:        bold;
+        padding-top:        1em;
+        padding-right:      1em;
+        padding-bottom:     0em;
+        padding-left:       1em;
+        line-height:        150%;
+}
+
+PRE.GeneralExample   {
+        color:              #000000; 
+        background-color:   #EEEEEE; 
+        border:             1px ridge white;
+        padding-top:        1em;
+        padding-right:      1em;
+        padding-bottom:     0em;
+        padding-left:       1em;
+}
diff --git a/doc/apidocs/org/hsqldb/Trigger.html b/doc/apidocs/org/hsqldb/Trigger.html
new file mode 100644
index 0000000..40cb0f4
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/Trigger.html
@@ -0,0 +1,434 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Trigger (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Trigger (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/Trigger.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../index.html?org/hsqldb/Trigger.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Trigger.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb</FONT>
+<BR>
+Interface Trigger</H2>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD><A HREF="../../org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public interface <B>Trigger</B></DL>
+</PRE>
+
+<P>
+The interface an HSQLDB TRIGGER must implement. The user-supplied class that
+ implements this must have a default constructor.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.7.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>Peter Hudson</DD>
+</DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#DELETE_AFTER">DELETE_AFTER</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#DELETE_AFTER_ROW">DELETE_AFTER_ROW</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#DELETE_BEFORE_ROW">DELETE_BEFORE_ROW</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#INSERT_AFTER">INSERT_AFTER</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#INSERT_AFTER_ROW">INSERT_AFTER_ROW</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#INSERT_BEFORE_ROW">INSERT_BEFORE_ROW</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#UPDATE_AFTER">UPDATE_AFTER</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#UPDATE_AFTER_ROW">UPDATE_AFTER_ROW</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#UPDATE_BEFORE_ROW">UPDATE_BEFORE_ROW</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../org/hsqldb/Trigger.html#fire(int, java.lang.String, java.lang.String, java.lang.Object[], java.lang.Object[])">fire</A></B>(int&nbsp;type,
+     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;trigName,
+     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tabName,
+     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;oldRow,
+     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;newRow)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The method invoked upon each triggered action.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="INSERT_AFTER"><!-- --></A><H3>
+INSERT_AFTER</H3>
+<PRE>
+static final int <B>INSERT_AFTER</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.INSERT_AFTER">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="DELETE_AFTER"><!-- --></A><H3>
+DELETE_AFTER</H3>
+<PRE>
+static final int <B>DELETE_AFTER</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.DELETE_AFTER">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="UPDATE_AFTER"><!-- --></A><H3>
+UPDATE_AFTER</H3>
+<PRE>
+static final int <B>UPDATE_AFTER</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.UPDATE_AFTER">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="INSERT_AFTER_ROW"><!-- --></A><H3>
+INSERT_AFTER_ROW</H3>
+<PRE>
+static final int <B>INSERT_AFTER_ROW</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.INSERT_AFTER_ROW">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="DELETE_AFTER_ROW"><!-- --></A><H3>
+DELETE_AFTER_ROW</H3>
+<PRE>
+static final int <B>DELETE_AFTER_ROW</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.DELETE_AFTER_ROW">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="UPDATE_AFTER_ROW"><!-- --></A><H3>
+UPDATE_AFTER_ROW</H3>
+<PRE>
+static final int <B>UPDATE_AFTER_ROW</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.UPDATE_AFTER_ROW">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="INSERT_BEFORE_ROW"><!-- --></A><H3>
+INSERT_BEFORE_ROW</H3>
+<PRE>
+static final int <B>INSERT_BEFORE_ROW</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.INSERT_BEFORE_ROW">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="DELETE_BEFORE_ROW"><!-- --></A><H3>
+DELETE_BEFORE_ROW</H3>
+<PRE>
+static final int <B>DELETE_BEFORE_ROW</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.DELETE_BEFORE_ROW">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="UPDATE_BEFORE_ROW"><!-- --></A><H3>
+UPDATE_BEFORE_ROW</H3>
+<PRE>
+static final int <B>UPDATE_BEFORE_ROW</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#org.hsqldb.Trigger.UPDATE_BEFORE_ROW">Constant Field Values</A></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="fire(int, java.lang.String, java.lang.String, java.lang.Object[], java.lang.Object[])"><!-- --></A><H3>
+fire</H3>
+<PRE>
+void <B>fire</B>(int&nbsp;type,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;trigName,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tabName,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;oldRow,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;newRow)
+          throws org.hsqldb.HsqlException</PRE>
+<DL>
+<DD>The method invoked upon each triggered action.
+
+ <p> type contains the integer index id for trigger type, e.g.
+ TriggerDef.INSERT_AFTER
+
+ <p> For all triggers defined as default FOR EACH STATEMENT both
+  oldRow and newRow are null.
+
+ <p> For triggers defined as FOR EACH ROW, the following will apply:
+
+ <p> When UPDATE triggers are fired, oldRow contains the existing values
+ of the table row and newRow contains the new values.
+
+ <p> For INSERT triggers, oldRow is null and newRow contains the table row
+ to be inserted. For DELETE triggers, newRow is null and oldRow contains
+ the table row to be deleted.
+
+ <p> For error conditions, users can construct an HsqlException using one
+ of the static methods of org.hsqldb.error.Error with a predefined
+ SQL State from org.hsqldb.error.ErrorCode.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - int<DD><CODE>trigName</CODE> - the name of the trigger<DD><CODE>tabName</CODE> - the name of the table upon which the triggered action is
+   occuring<DD><CODE>oldRow</CODE> - the old row<DD><CODE>newRow</CODE> - the new row
+<DT><B>Throws:</B>
+<DD><CODE>org.hsqldb.HsqlException</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/Trigger.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../index.html?org/hsqldb/Trigger.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Trigger.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/class-use/Trigger.html b/doc/apidocs/org/hsqldb/class-use/Trigger.html
new file mode 100644
index 0000000..621f753
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/class-use/Trigger.html
@@ -0,0 +1,181 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Interface org.hsqldb.Trigger (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Interface org.hsqldb.Trigger (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb//class-useTrigger.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Trigger.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Interface<br>org.hsqldb.Trigger</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.sample"><B>org.hsqldb.sample</B></A></TD>
+<TD>Contains examples for hooking into HyperSQL from your own Java code.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.sample"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A> in <A HREF="../../../org/hsqldb/sample/package-summary.html">org.hsqldb.sample</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Classes in <A HREF="../../../org/hsqldb/sample/package-summary.html">org.hsqldb.sample</A> that implement <A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sample code for use of triggers in hsqldb.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb//class-useTrigger.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Trigger.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/SqlFile.html b/doc/apidocs/org/hsqldb/cmdline/SqlFile.html
new file mode 100644
index 0000000..ea91b0c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/SqlFile.html
@@ -0,0 +1,1034 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+SqlFile (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="SqlFile (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/SqlFile.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/SqlFile.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlFile.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.cmdline</FONT>
+<BR>
+Class SqlFile</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.cmdline.SqlFile</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>SqlFile</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+Encapsulation of SQL text and the environment under which it will executed
+ with a JDBC Connection.
+ 'SqlInputStream' would be a more precise name, but the content we are
+ talking about here is what is colloqially known as the contents of
+ "SQL file"s.
+ <P>
+ The file <CODE>src/org/hsqldb/sample/SqlFileEmbedder.java</CODE>
+ in the HSQLDB distribution provides an example for using SqlFile to
+ execute SQL files directly from your own Java classes.
+ <P/><P>
+ The complexities of passing userVars and macros maps are to facilitate
+ strong scoping (among blocks and nested scripts).
+ <P/><P>
+ Some implementation comments and variable names use keywords based
+ on the following definitions.  <UL>
+ <LI> COMMAND = Statement || SpecialCommand || BufferCommand
+ <LI>Statement = SQL statement like "SQL Statement;"
+ <LI>SpecialCommand =  Special Command like "\x arg..."
+ <LI>BufferCommand =  Editing/buffer command like ":s/this/that/"
+ </UL>
+ <P/><P>
+ When entering SQL statements, you are always "appending" to the
+ "immediate" command (not the "buffer", which is a different thing).
+ All you can do to the immediate command is append new lines to it,
+ execute it, or save it to buffer.
+ When you are entering a buffer edit command like ":s/this/that/",
+ your immediate command is the buffer-edit-command.  The buffer
+ is the command string that you are editing.
+ The buffer usually contains either an exact copy of the last command
+ executed or sent to buffer by entering a blank line,
+ but BUFFER commands can change the contents of the buffer.
+ <P/><P>
+ In general, the special commands mirror those of Postgresql's psql,
+ but SqlFile handles command editing very differently than Postgresql
+ does, in part because of Java's lack of support for raw tty I/O.
+ The \p special command, in particular, is very different from psql's.
+ <P/><P>
+ Buffer commands are unique to SQLFile.  The ":" commands allow
+ you to edit the buffer and to execute the buffer.
+ <P/><P>
+ \d commands are very poorly supported for Mysql because
+ (a) Mysql lacks most of the most basic JDBC support elements, and
+ the most basic role and schema features, and
+ (b) to access the Mysql data dictionary, one must change the database
+ instance (to do that would require work to restore the original state
+ and could have disastrous effects upon transactions).
+ <P/><P>
+ The process*() methods, other than processBuffHist() ALWAYS execute
+ on "buffer", and expect it to contain the method specific prefix
+ (if any).
+ <P/><P>
+ The input/output Reader/Stream are generally managed by the caller.
+ An exception is that the input reader may be closed automatically or on
+ demand by the user, since in some cases this class builds the Reader.
+ There is no corresponding functionality for output since the user always
+ has control over that object (which may be null or System.out).
+ <P/>
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Blaine Simpson (blaine dot simpson at admc dot com)</DD>
+<DT><B>See Also:</B><DD><a href="../../../../util-guide/sqltool-chapt.html" target="guide">
+     The SqlTool chapter of the
+     HyperSQL Utilities Guide</a>, 
+<A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><CODE>SqlFileEmbedder</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#LS">LS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Platform-specific line separator</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.File)">SqlFile</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;inputFile)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convenience wrapper for the SqlFile(File, String) constructor</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.File, java.lang.String)">SqlFile</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;inputFile,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;encoding)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convenience wrapper for the SqlFile(File, String, boolean) constructor</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.File, java.lang.String, boolean)">SqlFile</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;inputFile,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;encoding,
+        boolean&nbsp;interactive)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructor for non-interactive usage with a SQL file, using the
+ specified encoding and sending normal output to stdout.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.Reader, java.lang.String, java.io.PrintStream, java.lang.String, boolean)">SqlFile</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;inputStreamLabel,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintStream.html?is-external=true" title="class or interface in java.io">PrintStream</A>&nbsp;psStd,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;encoding,
+        boolean&nbsp;interactive)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Instantiate a SqlFile instance for SQL input from 'reader'.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.lang.String, boolean)">SqlFile</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;encoding,
+        boolean&nbsp;interactive)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructor for interactive usage with stdin/stdout</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#addMacros(java.util.Map)">addMacros</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,org.hsqldb.cmdline.sqltool.Token&gt;&nbsp;newMacros)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#addUserVars(java.util.Map)">addUserVars</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&gt;&nbsp;newUserVars)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#bitCharsToBytes(java.lang.String)">bitCharsToBytes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;hexChars)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Just a stub for now.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#canDisplayType(int)">canDisplayType</A></B>(int&nbsp;i)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method is used to tell SqlFile whether this Sql Type must
+ ALWAYS be loaded to the binary buffer without displaying.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#closeReader()">closeReader</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Close the reader.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#convertEscapes(java.lang.String)">convertEscapes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;inString)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Translates user-supplied escapes into the traditionaly corresponding
+ corresponding binary characters.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#dsvSafe(java.lang.String)">dsvSafe</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;s)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Validate that String is safe to write TO DSV file.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#execute()">execute</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Process all the commands from the file or Reader associated with
+ "this" object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#getBanner(java.sql.Connection)">getBanner</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>&nbsp;c)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a String report for the specified JDBC Connection.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#getConnection()">getConnection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#getCurrentSchema()">getCurrentSchema</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,org.hsqldb.cmdline.sqltool.Token&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#getMacros()">getMacros</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#getUserVars()">getUserVars</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#hexCharOctetsToBytes(java.lang.String)">hexCharOctetsToBytes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;hexChars)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert a String to a byte array by interpreting every 2 characters as
+ an octal byte value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#importDsv(java.lang.String, java.lang.String)">importDsv</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;filePath,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;skipPrefix)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name is self-explanatory.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#loadBinary(java.io.File)">loadBinary</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;binFile)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Binary file load</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#setAutoClose(boolean)">setAutoClose</A></B>(boolean&nbsp;autoClose)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Specify whether the supplied or generated input Reader should
+ automatically be closed by the execute() method.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#setConnection(java.sql.Connection)">setConnection</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>&nbsp;jdbcConn)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#setContinueOnError(boolean)">setContinueOnError</A></B>(boolean&nbsp;continueOnError)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#setMaxHistoryLength(int)">setMaxHistoryLength</A></B>(int&nbsp;maxHistoryLength)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#sqlTypeToString(int)">sqlTypeToString</A></B>(int&nbsp;i)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return a String representation of the specified java.sql.Types type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#streamToBytes(java.io.InputStream)">streamToBytes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;is)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As the name says...</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#streamToString(java.io.InputStream, java.lang.String)">streamToString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;isIn,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;cs)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As the name says...</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="LS"><!-- --></A><H3>
+LS</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>LS</B></PRE>
+<DL>
+<DD>Platform-specific line separator
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="SqlFile(java.io.File)"><!-- --></A><H3>
+SqlFile</H3>
+<PRE>
+public <B>SqlFile</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;inputFile)
+        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>Convenience wrapper for the SqlFile(File, String) constructor
+<P>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.File, java.lang.String)"><CODE>SqlFile(File, String)</CODE></A></DL>
+</DL>
+<HR>
+
+<A NAME="SqlFile(java.io.File, java.lang.String)"><!-- --></A><H3>
+SqlFile</H3>
+<PRE>
+public <B>SqlFile</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;inputFile,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;encoding)
+        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>Convenience wrapper for the SqlFile(File, String, boolean) constructor
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>encoding</CODE> - is applied to both the given File and other files
+        read in or written out. Null will use your env+JVM settings.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.File, java.lang.String, boolean)"><CODE>SqlFile(File, String, boolean)</CODE></A></DL>
+</DL>
+<HR>
+
+<A NAME="SqlFile(java.io.File, java.lang.String, boolean)"><!-- --></A><H3>
+SqlFile</H3>
+<PRE>
+public <B>SqlFile</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;inputFile,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;encoding,
+               boolean&nbsp;interactive)
+        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>Constructor for non-interactive usage with a SQL file, using the
+ specified encoding and sending normal output to stdout.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>encoding</CODE> - is applied to the given File and other files
+        read in or written out. Null will use your env+JVM settings.<DD><CODE>interactive</CODE> - If true, prompts are printed, the interactive
+                     Special commands are enabled, and
+                     continueOnError defaults to true.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.Reader, java.lang.String, java.io.PrintStream, java.lang.String, boolean)"><CODE>SqlFile(Reader, String, PrintStream, String, boolean)</CODE></A></DL>
+</DL>
+<HR>
+
+<A NAME="SqlFile(java.lang.String, boolean)"><!-- --></A><H3>
+SqlFile</H3>
+<PRE>
+public <B>SqlFile</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;encoding,
+               boolean&nbsp;interactive)
+        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>Constructor for interactive usage with stdin/stdout
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>encoding</CODE> - is applied to other files read in or written out (but
+                     not to stdin or stdout).
+                     Null will use your env+JVM settings.<DD><CODE>interactive</CODE> - If true, prompts are printed, the interactive
+                     Special commands are enabled, and
+                     continueOnError defaults to true.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#SqlFile(java.io.Reader, java.lang.String, java.io.PrintStream, java.lang.String, boolean)"><CODE>SqlFile(Reader, String, PrintStream, String, boolean)</CODE></A></DL>
+</DL>
+<HR>
+
+<A NAME="SqlFile(java.io.Reader, java.lang.String, java.io.PrintStream, java.lang.String, boolean)"><!-- --></A><H3>
+SqlFile</H3>
+<PRE>
+public <B>SqlFile</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;inputStreamLabel,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintStream.html?is-external=true" title="class or interface in java.io">PrintStream</A>&nbsp;psStd,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;encoding,
+               boolean&nbsp;interactive)
+        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>Instantiate a SqlFile instance for SQL input from 'reader'.
+
+ After any needed customization, the SQL can be executed by the
+ execute method.
+ <P>
+ Most Special Commands and many Buffer commands are only for
+ interactive use.
+ </P> <P>
+ This program never writes to an error stream (stderr or alternative).
+ All meta messages and error messages are written using the logging
+ facility.
+ </P>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>reader</CODE> - Source for the SQL to be executed.
+                     Caller is responsible for setting up encoding.
+                     (the 'encoding' parameter will NOT be applied
+                     to this reader).<DD><CODE>psStd</CODE> - PrintStream for normal output.
+                     If null, normal output will be discarded.
+                     Caller is responsible for settingup encoding
+                     (the 'encoding' parameter will NOT be applied
+                     to this stream).<DD><CODE>interactive</CODE> - If true, prompts are printed, the interactive
+                     Special commands are enabled, and
+                     continueOnError defaults to true.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/cmdline/SqlFile.html#execute()"><CODE>execute()</CODE></A></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="setConnection(java.sql.Connection)"><!-- --></A><H3>
+setConnection</H3>
+<PRE>
+public void <B>setConnection</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>&nbsp;jdbcConn)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConnection()"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setContinueOnError(boolean)"><!-- --></A><H3>
+setContinueOnError</H3>
+<PRE>
+public void <B>setContinueOnError</B>(boolean&nbsp;continueOnError)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMaxHistoryLength(int)"><!-- --></A><H3>
+setMaxHistoryLength</H3>
+<PRE>
+public void <B>setMaxHistoryLength</B>(int&nbsp;maxHistoryLength)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addMacros(java.util.Map)"><!-- --></A><H3>
+addMacros</H3>
+<PRE>
+public void <B>addMacros</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,org.hsqldb.cmdline.sqltool.Token&gt;&nbsp;newMacros)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addUserVars(java.util.Map)"><!-- --></A><H3>
+addUserVars</H3>
+<PRE>
+public void <B>addUserVars</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&gt;&nbsp;newUserVars)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUserVars()"><!-- --></A><H3>
+getUserVars</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&gt; <B>getUserVars</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMacros()"><!-- --></A><H3>
+getMacros</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,org.hsqldb.cmdline.sqltool.Token&gt; <B>getMacros</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAutoClose(boolean)"><!-- --></A><H3>
+setAutoClose</H3>
+<PRE>
+public void <B>setAutoClose</B>(boolean&nbsp;autoClose)</PRE>
+<DL>
+<DD>Specify whether the supplied or generated input Reader should
+ automatically be closed by the execute() method.
+ <P>
+ execute() will close the Reader by default (i.e. 'autoClose' defaults
+ to true).
+ You may want to set this to false if you want to stop execution with
+ \q or similar, then continue using the Reader or underlying Stream.
+ </P> <P>
+ The caller is always responsible for closing the output object (if any)
+ used by SqlFile.
+ </P>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute()"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public void <B>execute</B>()
+             throws org.hsqldb.cmdline.SqlToolError,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Process all the commands from the file or Reader associated with
+ "this" object.
+ SQL commands in the content get executed against the current JDBC
+ data source connection.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>SQLExceptions</CODE> - thrown by JDBC driver.
+                       Only possible if in "\c false" mode.
+<DD><CODE>org.hsqldb.cmdline.SqlToolError</CODE> - all other errors.
+               This includes including QuitNow, BreakException,
+               ContinueException for recursive calls only.
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="closeReader()"><!-- --></A><H3>
+closeReader</H3>
+<PRE>
+public void <B>closeReader</B>()</PRE>
+<DL>
+<DD>Close the reader.
+
+ The execute method will run this automatically, by default.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCurrentSchema()"><!-- --></A><H3>
+getCurrentSchema</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getCurrentSchema</B>()
+                        throws org.hsqldb.cmdline.SqlFile.BadSpecial,
+                               org.hsqldb.cmdline.SqlToolError</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>org.hsqldb.cmdline.SqlFile.BadSpecial</CODE>
+<DD><CODE>org.hsqldb.cmdline.SqlToolError</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="streamToString(java.io.InputStream, java.lang.String)"><!-- --></A><H3>
+streamToString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>streamToString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;isIn,
+                             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;cs)
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>As the name says...
+ This method always closes the input stream.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="streamToBytes(java.io.InputStream)"><!-- --></A><H3>
+streamToBytes</H3>
+<PRE>
+public static byte[] <B>streamToBytes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;is)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>As the name says...
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="loadBinary(java.io.File)"><!-- --></A><H3>
+loadBinary</H3>
+<PRE>
+public static byte[] <B>loadBinary</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;binFile)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>Binary file load
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>The bytes which are the content of the fil
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="canDisplayType(int)"><!-- --></A><H3>
+canDisplayType</H3>
+<PRE>
+public static boolean <B>canDisplayType</B>(int&nbsp;i)</PRE>
+<DL>
+<DD>This method is used to tell SqlFile whether this Sql Type must
+ ALWAYS be loaded to the binary buffer without displaying.
+ <P>
+ N.b.:  If this returns "true" for a type, then the user can never
+ "see" values for these columns.
+ Therefore, if a type may-or-may-not-be displayable, better to return
+ false here and let the user choose.
+ In general, if there is a toString() operator for this Sql Type
+ then return false, since the JDBC driver should know how to make the
+ value displayable.
+ </P>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A href="http://java.sun.com/docs/books/tutorial/jdbc/basics/retrieving.html">http://java.sun.com/docs/books/tutorial/jdbc/basics/retrieving.html</A>
+      The table on this page lists the most common SqlTypes, all of which
+      must implement toString(), 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlTypeToString(int)"><!-- --></A><H3>
+sqlTypeToString</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>sqlTypeToString</B>(int&nbsp;i)</PRE>
+<DL>
+<DD>Return a String representation of the specified java.sql.Types type.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="dsvSafe(java.lang.String)"><!-- --></A><H3>
+dsvSafe</H3>
+<PRE>
+public void <B>dsvSafe</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;s)
+             throws org.hsqldb.cmdline.SqlToolError</PRE>
+<DL>
+<DD>Validate that String is safe to write TO DSV file.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>org.hsqldb.cmdline.SqlToolError</CODE> - if validation fails.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="convertEscapes(java.lang.String)"><!-- --></A><H3>
+convertEscapes</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>convertEscapes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;inString)</PRE>
+<DL>
+<DD>Translates user-supplied escapes into the traditionaly corresponding
+ corresponding binary characters.
+
+ Allowed sequences:
+ <UL>
+  <LI>\0\d+   (an octal digit)
+  <LI>\[0-9]\d*  (a decimal digit)
+  <LI>\[Xx][0-9]{2}  (a hex digit)
+  <LI>\n  Newline  (Ctrl-J)
+  <LI>\r  Carriage return  (Ctrl-M)
+  <LI>\t  Horizontal tab  (Ctrl-I)
+  <LI>\f  Form feed  (Ctrl-L)
+ </UL>
+
+ Java 1.4 String methods will make this into a 1 or 2 line task.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="importDsv(java.lang.String, java.lang.String)"><!-- --></A><H3>
+importDsv</H3>
+<PRE>
+public void <B>importDsv</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;filePath,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;skipPrefix)
+               throws org.hsqldb.cmdline.SqlToolError</PRE>
+<DL>
+<DD>Name is self-explanatory.
+
+ If there is user demand, open file in random access mode so don't
+ need to load 2 copies of the entire file into memory.
+ This will be difficult because can't use standard Java language
+ features to search through a character array for multi-character
+ substrings.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>org.hsqldb.cmdline.SqlToolError</CODE> - Would prefer to throw an internal exception,
+                       but we want this method to have external
+                       visibility.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hexCharOctetsToBytes(java.lang.String)"><!-- --></A><H3>
+hexCharOctetsToBytes</H3>
+<PRE>
+public static byte[] <B>hexCharOctetsToBytes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;hexChars)</PRE>
+<DL>
+<DD>Convert a String to a byte array by interpreting every 2 characters as
+ an octal byte value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="bitCharsToBytes(java.lang.String)"><!-- --></A><H3>
+bitCharsToBytes</H3>
+<PRE>
+public static byte[] <B>bitCharsToBytes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;hexChars)</PRE>
+<DL>
+<DD>Just a stub for now.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBanner(java.sql.Connection)"><!-- --></A><H3>
+getBanner</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getBanner</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>&nbsp;c)</PRE>
+<DL>
+<DD>Returns a String report for the specified JDBC Connection.
+
+ For databases with poor JDBC support, you won't get much detail.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/SqlFile.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/SqlFile.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlFile.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/SqlTool.SqlToolException.html b/doc/apidocs/org/hsqldb/cmdline/SqlTool.SqlToolException.html
new file mode 100644
index 0000000..29cc1df
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/SqlTool.SqlToolException.html
@@ -0,0 +1,211 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+SqlTool.SqlToolException (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="SqlTool.SqlToolException (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/SqlTool.SqlToolException.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/SqlTool.SqlToolException.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlTool.SqlToolException.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Throwable">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.cmdline</FONT>
+<BR>
+Class SqlTool.SqlToolException</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">java.lang.Throwable</A>
+      <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">java.lang.Exception</A>
+          <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.cmdline.SqlTool.SqlToolException</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A></DD>
+</DL>
+<DL>
+<DT><B>Enclosing class:</B><DD><A HREF="../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public static class <B>SqlTool.SqlToolException</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></DL>
+</PRE>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.hsqldb.cmdline.SqlTool.SqlToolException">Serialized Form</A></DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Throwable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#fillInStackTrace()" title="class or interface in java.lang">fillInStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#getCause()" title="class or interface in java.lang">getCause</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#getLocalizedMessage()" title="class or interface in java.lang">getLocalizedMessage</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#getMessage()" title="class or interface in java.lang">getMessage</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#getStackTrace()" title="class or interface in java.lang">getStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#initCause(java.lang.Throwable)" title="class or interface in java.lang">initCause</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#printStackTrace()" title="class or interface in java.lang">printStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#printStackTrace(java.io.PrintStream)" title="class or interface in java.lang">printStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#printStackTrace(java.io.PrintWriter)" title="class or interface in java.lang">printStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#setStackTrace(java.lang.StackTraceElement[])" title="class or interface in java.lang">setStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/SqlTool.SqlToolException.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/SqlTool.SqlToolException.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlTool.SqlToolException.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Throwable">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/SqlTool.html b/doc/apidocs/org/hsqldb/cmdline/SqlTool.html
new file mode 100644
index 0000000..1908b75
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/SqlTool.html
@@ -0,0 +1,540 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+SqlTool (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="SqlTool (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/SqlTool.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/SqlTool.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlTool.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.cmdline</FONT>
+<BR>
+Class SqlTool</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.cmdline.SqlTool</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>SqlTool</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+A command-line JDBC SQL tool supporting both interactive and
+ non-interactive usage.
+ <P>
+ See JavaDocs for the main method for syntax of how to run from the
+ command-line.
+ <P/> <P>
+ Programmatic users will usually want to use the objectMain(String[]) method
+ if they want arguments and behavior exactly like command-line SqlTool.
+ But in many cases, you will have better control and efficiency by using
+ the SqlFile class directly.  The file
+ <CODE>src/org/hsqldb/sample/SqlFileEmbedder.java</CODE>
+ in the HSQLDB distribution provides an example for this latter strategy.
+ <P/>
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Blaine Simpson (blaine dot simpson at admc dot com)</DD>
+<DT><B>See Also:</B><DD><a href="../../../../util-guide/sqltool-chapt.html" target="guide">
+     The SqlTool chapter of the
+     HyperSQL Utilities Guide</a>, 
+<A HREF="../../../org/hsqldb/cmdline/SqlTool.html#main(java.lang.String[])"><CODE>main(String[])</CODE></A>, 
+<A HREF="../../../org/hsqldb/cmdline/SqlTool.html#objectMain(java.lang.String[])"><CODE>objectMain(String[])</CODE></A>, 
+<A HREF="../../../org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><CODE>SqlFile</CODE></A>, 
+<A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><CODE>SqlFileEmbedder</CODE></A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">SqlTool.SqlToolException</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#CONNECTERR_EXITVAL">CONNECTERR_EXITVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#DEFAULT_RCFILE">DEFAULT_RCFILE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#FILEERR_EXITVAL">FILEERR_EXITVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#INPUTERR_EXITVAL">INPUTERR_EXITVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#IOERR_EXITVAL">IOERR_EXITVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#LS">LS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Platform-specific line separator</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#RCERR_EXITVAL">RCERR_EXITVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#SQLERR_EXITVAL">SQLERR_EXITVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#SQLTOOLERR_EXITVAL">SQLTOOLERR_EXITVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#SYNTAXERR_EXITVAL">SYNTAXERR_EXITVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#SqlTool()">SqlTool</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A static wrapper for objectMain, so that that method may be executed
+ as a Java "program".</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#objectMain(java.lang.String[])">objectMain</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;arg)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connect to a JDBC Database and execute the commands given on
+ stdin or in SQL file(s).</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="DEFAULT_RCFILE"><!-- --></A><H3>
+DEFAULT_RCFILE</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>DEFAULT_RCFILE</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="SQLTOOLERR_EXITVAL"><!-- --></A><H3>
+SQLTOOLERR_EXITVAL</H3>
+<PRE>
+public static final int <B>SQLTOOLERR_EXITVAL</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.cmdline.SqlTool.SQLTOOLERR_EXITVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="SYNTAXERR_EXITVAL"><!-- --></A><H3>
+SYNTAXERR_EXITVAL</H3>
+<PRE>
+public static final int <B>SYNTAXERR_EXITVAL</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.cmdline.SqlTool.SYNTAXERR_EXITVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="RCERR_EXITVAL"><!-- --></A><H3>
+RCERR_EXITVAL</H3>
+<PRE>
+public static final int <B>RCERR_EXITVAL</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.cmdline.SqlTool.RCERR_EXITVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="SQLERR_EXITVAL"><!-- --></A><H3>
+SQLERR_EXITVAL</H3>
+<PRE>
+public static final int <B>SQLERR_EXITVAL</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.cmdline.SqlTool.SQLERR_EXITVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="IOERR_EXITVAL"><!-- --></A><H3>
+IOERR_EXITVAL</H3>
+<PRE>
+public static final int <B>IOERR_EXITVAL</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.cmdline.SqlTool.IOERR_EXITVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FILEERR_EXITVAL"><!-- --></A><H3>
+FILEERR_EXITVAL</H3>
+<PRE>
+public static final int <B>FILEERR_EXITVAL</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.cmdline.SqlTool.FILEERR_EXITVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="INPUTERR_EXITVAL"><!-- --></A><H3>
+INPUTERR_EXITVAL</H3>
+<PRE>
+public static final int <B>INPUTERR_EXITVAL</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.cmdline.SqlTool.INPUTERR_EXITVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="CONNECTERR_EXITVAL"><!-- --></A><H3>
+CONNECTERR_EXITVAL</H3>
+<PRE>
+public static final int <B>CONNECTERR_EXITVAL</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.cmdline.SqlTool.CONNECTERR_EXITVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="LS"><!-- --></A><H3>
+LS</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>LS</B></PRE>
+<DL>
+<DD>Platform-specific line separator
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="SqlTool()"><!-- --></A><H3>
+SqlTool</H3>
+<PRE>
+public <B>SqlTool</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)</PRE>
+<DL>
+<DD>A static wrapper for objectMain, so that that method may be executed
+ as a Java "program".
+ <P>
+ Throws only RuntimeExceptions or Errors, because this method is intended
+ to System.exit() for all but disastrous system problems, for which
+ the inconvenience of a stack trace would be the least of your worries.
+ <P/> <P>
+ If you don't want SqlTool to System.exit(), then use the method
+ objectMain() instead of this method.
+ <P/>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/cmdline/SqlTool.html#objectMain(java.lang.String[])"><CODE>objectMain(String[])</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="objectMain(java.lang.String[])"><!-- --></A><H3>
+objectMain</H3>
+<PRE>
+public static void <B>objectMain</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;arg)
+                       throws <A HREF="../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">SqlTool.SqlToolException</A></PRE>
+<DL>
+<DD>Connect to a JDBC Database and execute the commands given on
+ stdin or in SQL file(s).
+ <P>
+ This method is changed for HSQLDB 1.8.0.8 and later to never
+ System.exit().
+ Developers may catch Throwables to handle all fatal situations.
+ </P>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>arg</CODE> - Run "java... org.hsqldb.cmdline.SqlTool --help" for syntax.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">SqlTool.SqlToolException</A></CODE> - Upon any fatal error, with useful
+                          reason as the exception's message.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/SqlTool.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/SqlTool.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlTool.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/class-use/SqlFile.html b/doc/apidocs/org/hsqldb/cmdline/class-use/SqlFile.html
new file mode 100644
index 0000000..39074b4
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/class-use/SqlFile.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.cmdline.SqlFile (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.cmdline.SqlFile (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/cmdline//class-useSqlFile.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlFile.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.cmdline.SqlFile</B></H2>
+</CENTER>
+No usage of org.hsqldb.cmdline.SqlFile
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/cmdline//class-useSqlFile.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlFile.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/class-use/SqlTool.SqlToolException.html b/doc/apidocs/org/hsqldb/cmdline/class-use/SqlTool.SqlToolException.html
new file mode 100644
index 0000000..4741e01
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/class-use/SqlTool.SqlToolException.html
@@ -0,0 +1,182 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.cmdline.SqlTool.SqlToolException (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.cmdline.SqlTool.SqlToolException (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/cmdline//class-useSqlTool.SqlToolException.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlTool.SqlToolException.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.cmdline.SqlTool.SqlToolException</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">SqlTool.SqlToolException</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.cmdline"><B>org.hsqldb.cmdline</B></A></TD>
+<TD>Contains command-line utilities.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.cmdline"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">SqlTool.SqlToolException</A> in <A HREF="../../../../org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Methods in <A HREF="../../../../org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A> that throw <A HREF="../../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">SqlTool.SqlToolException</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B>SqlTool.</B><B><A HREF="../../../../org/hsqldb/cmdline/SqlTool.html#objectMain(java.lang.String[])">objectMain</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;arg)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connect to a JDBC Database and execute the commands given on
+ stdin or in SQL file(s).</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/cmdline//class-useSqlTool.SqlToolException.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlTool.SqlToolException.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/class-use/SqlTool.html b/doc/apidocs/org/hsqldb/cmdline/class-use/SqlTool.html
new file mode 100644
index 0000000..7b434a1
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/class-use/SqlTool.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.cmdline.SqlTool (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.cmdline.SqlTool (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/cmdline//class-useSqlTool.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlTool.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.cmdline.SqlTool</B></H2>
+</CENTER>
+No usage of org.hsqldb.cmdline.SqlTool
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/cmdline//class-useSqlTool.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlTool.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/package-frame.html b/doc/apidocs/org/hsqldb/cmdline/package-frame.html
new file mode 100644
index 0000000..3be02df
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/package-frame.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.cmdline (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../org/hsqldb/cmdline/package-summary.html" target="classFrame">org.hsqldb.cmdline</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="SqlFile.html" title="class in org.hsqldb.cmdline" target="classFrame">SqlFile</A>
+<BR>
+<A HREF="SqlTool.html" title="class in org.hsqldb.cmdline" target="classFrame">SqlTool</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Exceptions</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline" target="classFrame">SqlTool.SqlToolException</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/package-summary.html b/doc/apidocs/org/hsqldb/cmdline/package-summary.html
new file mode 100644
index 0000000..7da621b
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/package-summary.html
@@ -0,0 +1,196 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.cmdline (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.cmdline (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.hsqldb.cmdline
+</H2>
+Contains command-line utilities.
+<P>
+<B>See:</B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline">SqlFile</A></B></TD>
+<TD>Encapsulation of SQL text and the environment under which it will executed
+ with a JDBC Connection.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline">SqlTool</A></B></TD>
+<TD>A command-line JDBC SQL tool supporting both interactive and
+ non-interactive usage.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Exception Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">SqlTool.SqlToolException</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package org.hsqldb.cmdline Description
+</H2>
+
+<P>
+Contains command-line utilities.
+See <a href="../../../../util-guide/sqltool-chapt.html" target="guide">
+  the SqlTool chapter of the
+  HyperSQL Utilities Guide</a>
+<P>
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/package-tree.html b/doc/apidocs/org/hsqldb/cmdline/package-tree.html
new file mode 100644
index 0000000..58fb2c7
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/package-tree.html
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.cmdline Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.cmdline Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.hsqldb.cmdline
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><B>Object</B></A><UL>
+<LI TYPE="circle">org.hsqldb.cmdline.<A HREF="../../../org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><B>SqlFile</B></A><LI TYPE="circle">org.hsqldb.cmdline.<A HREF="../../../org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><B>SqlTool</B></A><LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang"><B>Throwable</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A>)
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang"><B>Exception</B></A><UL>
+<LI TYPE="circle">org.hsqldb.cmdline.<A HREF="../../../org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline"><B>SqlTool.SqlToolException</B></A></UL>
+</UL>
+</UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/cmdline/package-use.html b/doc/apidocs/org/hsqldb/cmdline/package-use.html
new file mode 100644
index 0000000..33fd0ae
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/cmdline/package-use.html
@@ -0,0 +1,196 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Package org.hsqldb.cmdline (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Package org.hsqldb.cmdline (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>org.hsqldb.cmdline</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.cmdline"><B>org.hsqldb.cmdline</B></A></TD>
+<TD>Contains command-line utilities.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.sample"><B>org.hsqldb.sample</B></A></TD>
+<TD>Contains examples for hooking into HyperSQL from your own Java code.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.cmdline"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Classes in <A HREF="../../../org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A> used by <A HREF="../../../org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/cmdline/class-use/SqlTool.SqlToolException.html#org.hsqldb.cmdline"><B>SqlTool.SqlToolException</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/cmdline/class-use/SqlToolError.html#org.hsqldb.cmdline"><B>SqlToolError</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exceptions thrown by the SqlTool system externally to SqlFile.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.sample"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Classes in <A HREF="../../../org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A> used by <A HREF="../../../org/hsqldb/sample/package-summary.html">org.hsqldb.sample</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/cmdline/class-use/SqlToolError.html#org.hsqldb.sample"><B>SqlToolError</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exceptions thrown by the SqlTool system externally to SqlFile.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/cmdline/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/BlobInputStream.html b/doc/apidocs/org/hsqldb/jdbc/BlobInputStream.html
new file mode 100644
index 0000000..34f5d80
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/BlobInputStream.html
@@ -0,0 +1,369 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+BlobInputStream (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="BlobInputStream (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/BlobInputStream.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/BlobInputStream.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="BlobInputStream.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class BlobInputStream</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">java.io.InputStream</A>
+      <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.BlobInputStream</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>BlobInputStream</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></DL>
+</PRE>
+
+<P>
+This class is used as an InputStream to retrieve data from a Blob.
+ mark() and reset() are not supported.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.9.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>Fred Toussi (fredt@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html#BlobInputStream(org.hsqldb.jdbc.JDBCBlobClient, long, long, int)">BlobInputStream</A></B>(<A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>&nbsp;blob,
+                long&nbsp;offset,
+                long&nbsp;length,
+                int&nbsp;blockSize)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html#available()">available</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html#close()">close</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html#read()">read</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html#skip(long)">skip</A></B>(long&nbsp;n)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.io.InputStream"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#mark(int)" title="class or interface in java.io">mark</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#markSupported()" title="class or interface in java.io">markSupported</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#read(byte[])" title="class or interface in java.io">read</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#read(byte[], int, int)" title="class or interface in java.io">read</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#reset()" title="class or interface in java.io">reset</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="BlobInputStream(org.hsqldb.jdbc.JDBCBlobClient, long, long, int)"><!-- --></A><H3>
+BlobInputStream</H3>
+<PRE>
+public <B>BlobInputStream</B>(<A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>&nbsp;blob,
+                       long&nbsp;offset,
+                       long&nbsp;length,
+                       int&nbsp;blockSize)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="read()"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>()
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#read()" title="class or interface in java.io">read</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="skip(long)"><!-- --></A><H3>
+skip</H3>
+<PRE>
+public long <B>skip</B>(long&nbsp;n)
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#skip(long)" title="class or interface in java.io">skip</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="available()"><!-- --></A><H3>
+available</H3>
+<PRE>
+public int <B>available</B>()
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#available()" title="class or interface in java.io">available</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="close()"><!-- --></A><H3>
+close</H3>
+<PRE>
+public void <B>close</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true#close()" title="class or interface in java.io">close</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A></CODE><DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true#close()" title="class or interface in java.io">close</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/BlobInputStream.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/BlobInputStream.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="BlobInputStream.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/ClobInputStream.html b/doc/apidocs/org/hsqldb/jdbc/ClobInputStream.html
new file mode 100644
index 0000000..a601277
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/ClobInputStream.html
@@ -0,0 +1,395 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+ClobInputStream (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="ClobInputStream (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/ClobInputStream.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/ClobInputStream.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ClobInputStream.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class ClobInputStream</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">java.io.Reader</A>
+      <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.ClobInputStream</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Readable.html?is-external=true" title="class or interface in java.lang">Readable</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public final class <B>ClobInputStream</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></DL>
+</PRE>
+
+<P>
+This class is used as an InputStream to retrieve data from a Blob.
+ mark() and reset() are not supported.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.9.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>Fred Toussi (fredt@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html#ClobInputStream(org.hsqldb.jdbc.JDBCClobClient, long, long, int)">ClobInputStream</A></B>(<A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>&nbsp;clob,
+                long&nbsp;offset,
+                long&nbsp;length,
+                int&nbsp;blockSize)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html#available()">available</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html#close()">close</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html#read()">read</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html#read(char[], int, int)">read</A></B>(char[]&nbsp;cbuf,
+     int&nbsp;off,
+     int&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html#skip(long)">skip</A></B>(long&nbsp;n)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.io.Reader"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#mark(int)" title="class or interface in java.io">mark</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#markSupported()" title="class or interface in java.io">markSupported</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#read(char[])" title="class or interface in java.io">read</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#read(java.nio.CharBuffer)" title="class or interface in java.io">read</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#ready()" title="class or interface in java.io">ready</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#reset()" title="class or interface in java.io">reset</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ClobInputStream(org.hsqldb.jdbc.JDBCClobClient, long, long, int)"><!-- --></A><H3>
+ClobInputStream</H3>
+<PRE>
+public <B>ClobInputStream</B>(<A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>&nbsp;clob,
+                       long&nbsp;offset,
+                       long&nbsp;length,
+                       int&nbsp;blockSize)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="read()"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>()
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#read()" title="class or interface in java.io">read</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="read(char[], int, int)"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>(char[]&nbsp;cbuf,
+                int&nbsp;off,
+                int&nbsp;len)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#read(char[], int, int)" title="class or interface in java.io">read</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="skip(long)"><!-- --></A><H3>
+skip</H3>
+<PRE>
+public long <B>skip</B>(long&nbsp;n)
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#skip(long)" title="class or interface in java.io">skip</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="available()"><!-- --></A><H3>
+available</H3>
+<PRE>
+public int <B>available</B>()
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="close()"><!-- --></A><H3>
+close</H3>
+<PRE>
+public void <B>close</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true#close()" title="class or interface in java.io">close</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A></CODE><DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true#close()" title="class or interface in java.io">close</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/ClobInputStream.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/ClobInputStream.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ClobInputStream.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCArray.html b/doc/apidocs/org/hsqldb/jdbc/JDBCArray.html
new file mode 100644
index 0000000..a6934c7
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCArray.html
@@ -0,0 +1,859 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCArray (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCArray (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCArray.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCArray.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCArray.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCArray</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCArray</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCArray</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></DL>
+</PRE>
+
+<P>
+The mapping in the Java programming language for the SQL type
+ <code>ARRAY</code>.
+ By default, an <code>Array</code> value is a transaction-duration
+ reference to an SQL <code>ARRAY</code> value.  By default, an <code>Array</code>
+ object is implemented using an SQL LOCATOR(array) internally, which
+ means that an <code>Array</code> object contains a logical pointer
+ to the data in the SQL <code>ARRAY</code> value rather
+ than containing the <code>ARRAY</code> value's data.
+ <p>
+ The <code>Array</code> interface provides methods for bringing an SQL
+ <code>ARRAY</code> value's data to the client as either an array or a
+ <code>ResultSet</code> object.
+ If the elements of the SQL <code>ARRAY</code>
+ are a UDT, they may be custom mapped.  To create a custom mapping,
+ a programmer must do two things:
+ <ul>
+ <li>create a class that implements the <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLData.html?is-external=true" title="class or interface in java.sql"><CODE>SQLData</CODE></A>
+ interface for the UDT to be custom mapped.
+ <li>make an entry in a type map that contains
+   <ul>
+   <li>the fully-qualified SQL type name of the UDT
+   <li>the <code>Class</code> object for the class implementing
+       <code>SQLData</code>
+   </ul>
+ </ul>
+ <p>
+ When a type map with an entry for
+ the base type is supplied to the methods <code>getArray</code>
+ and <code>getResultSet</code>, the mapping
+ it contains will be used to map the elements of the <code>ARRAY</code> value.
+ If no type map is supplied, which would typically be the case,
+ the connection's type map is used by default.
+ If the connection's type map or a type map supplied to a method has no entry
+ for the base type, the elements are mapped according to the standard mapping.
+ <p>
+ All methods on the <code>Array</code> interface must be fully implemented if the
+ JDBC driver supports the data type.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#free()">free</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method frees the <code>Array</code> object and releases the resources that
+ it holds.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getArray()">getArray</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the contents of the SQL <code>ARRAY</code> value designated
+ by this
+ <code>Array</code> object in the form of an array in the Java
+ programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getArray(long, int)">getArray</A></B>(long&nbsp;index,
+         int&nbsp;count)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a slice of the SQL <code>ARRAY</code>
+ value designated by this <code>Array</code> object, beginning with the
+ specified <code>index</code> and containing up to <code>count</code>
+ successive elements of the SQL array.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getArray(long, int, java.util.Map)">getArray</A></B>(long&nbsp;index,
+         int&nbsp;count,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retreives a slice of the SQL <code>ARRAY</code> value
+ designated by this <code>Array</code> object, beginning with the specified
+ <code>index</code> and containing up to <code>count</code>
+ successive elements of the SQL array.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getArray(java.util.Map)">getArray</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the contents of the SQL <code>ARRAY</code> value designated by this
+ <code>Array</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getBaseType()">getBaseType</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the JDBC type of the elements in the array designated
+ by this <code>Array</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getBaseTypeName()">getBaseTypeName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the SQL type name of the elements in
+ the array designated by this <code>Array</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getResultSet()">getResultSet</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a result set that contains the elements of the SQL
+ <code>ARRAY</code> value
+ designated by this <code>Array</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getResultSet(long, int)">getResultSet</A></B>(long&nbsp;index,
+             int&nbsp;count)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a result set holding the elements of the subarray that
+ starts at index <code>index</code> and contains up to
+ <code>count</code> successive elements.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getResultSet(long, int, java.util.Map)">getResultSet</A></B>(long&nbsp;index,
+             int&nbsp;count,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a result set holding the elements of the subarray that
+ starts at index <code>index</code> and contains up to
+ <code>count</code> successive elements.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#getResultSet(java.util.Map)">getResultSet</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a result set that contains the elements of the SQL
+ <code>ARRAY</code> value designated by this <code>Array</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a string representation in the form <code>ARRAY[..., ...]</code></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getBaseTypeName()"><!-- --></A><H3>
+getBaseTypeName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getBaseTypeName</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the SQL type name of the elements in
+ the array designated by this <code>Array</code> object.
+ If the elements are a built-in type, it returns
+ the database-specific type name of the elements.
+ If the elements are a user-defined type (UDT),
+ this method returns the fully-qualified SQL type name.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getBaseTypeName()" title="class or interface in java.sql">getBaseTypeName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>String</code> that is the database-specific
+ name for a built-in base type; or the fully-qualified SQL type
+ name for a base type that is a UDT
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting
+ to access the type name
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBaseType()"><!-- --></A><H3>
+getBaseType</H3>
+<PRE>
+public int <B>getBaseType</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the JDBC type of the elements in the array designated
+ by this <code>Array</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getBaseType()" title="class or interface in java.sql">getBaseType</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a constant from the class <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A> that is
+ the type code for the elements in the array designated by this
+ <code>Array</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting
+ to access the base type
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArray()"><!-- --></A><H3>
+getArray</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getArray</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the contents of the SQL <code>ARRAY</code> value designated
+ by this
+ <code>Array</code> object in the form of an array in the Java
+ programming language. This version of the method <code>getArray</code>
+ uses the type map associated with the connection for customizations of
+ the type mappings.
+ <p>
+ <strong>Note:</strong> When <code>getArray</code> is used to materialize
+ a base type that maps to a primitive data type, then it is
+ implementation-defined whether the array returned is an array of
+ that primitive data type or an array of <code>Object</code>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB always returns an array of <code>Object</code>.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getArray()" title="class or interface in java.sql">getArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array in the Java programming language that contains
+ the ordered elements of the SQL <code>ARRAY</code> value
+ designated by this <code>Array</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting to
+ access the array
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArray(java.util.Map)"><!-- --></A><H3>
+getArray</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getArray</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the contents of the SQL <code>ARRAY</code> value designated by this
+ <code>Array</code> object.
+ This method uses
+ the specified <code>map</code> for type map customizations
+ unless the base type of the array does not match a user-defined
+ type in <code>map</code>, in which case it
+ uses the standard mapping. This version of the method
+ <code>getArray</code> uses either the given type map or the standard mapping;
+ it never uses the type map associated with the connection.
+ <p>
+ <strong>Note:</strong> When <code>getArray</code> is used to materialize
+ a base type that maps to a primitive data type, then it is
+ implementation-defined whether the array returned is an array of
+ that primitive data type or an array of <code>Object</code>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB always returns an array of <code>Object</code>.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getArray(java.util.Map)" title="class or interface in java.sql">getArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>map</CODE> - a <code>java.util.Map</code> object that contains mappings
+            of SQL type names to classes in the Java programming language
+<DT><B>Returns:</B><DD>an array in the Java programming language that contains the ordered
+         elements of the SQL array designated by this object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting to
+                         access the array
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArray(long, int)"><!-- --></A><H3>
+getArray</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getArray</B>(long&nbsp;index,
+                       int&nbsp;count)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves a slice of the SQL <code>ARRAY</code>
+ value designated by this <code>Array</code> object, beginning with the
+ specified <code>index</code> and containing up to <code>count</code>
+ successive elements of the SQL array.  This method uses the type map
+ associated with the connection for customizations of the type mappings.
+ <p>
+ <strong>Note:</strong> When <code>getArray</code> is used to materialize
+ a base type that maps to a primitive data type, then it is
+ implementation-defined whether the array returned is an array of
+ that primitive data type or an array of <code>Object</code>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB always returns an array of <code>Object</code>.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getArray(long, int)" title="class or interface in java.sql">getArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the array index of the first element to retrieve;
+              the first element is at index 1<DD><CODE>count</CODE> - the number of successive SQL array elements to retrieve
+<DT><B>Returns:</B><DD>an array containing up to <code>count</code> consecutive elements
+ of the SQL array, beginning with element <code>index</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting to
+ access the array
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArray(long, int, java.util.Map)"><!-- --></A><H3>
+getArray</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getArray</B>(long&nbsp;index,
+                       int&nbsp;count,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retreives a slice of the SQL <code>ARRAY</code> value
+ designated by this <code>Array</code> object, beginning with the specified
+ <code>index</code> and containing up to <code>count</code>
+ successive elements of the SQL array.
+ <P>
+ This method uses
+ the specified <code>map</code> for type map customizations
+ unless the base type of the array does not match a user-defined
+ type in <code>map</code>, in which case it
+ uses the standard mapping. This version of the method
+ <code>getArray</code> uses either the given type map or the standard mapping;
+ it never uses the type map associated with the connection.
+ <p>
+ <strong>Note:</strong> When <code>getArray</code> is used to materialize
+ a base type that maps to a primitive data type, then it is
+ implementation-defined whether the array returned is an array of
+ that primitive data type or an array of <code>Object</code>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB always returns an array of <code>Object</code>.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getArray(long, int, java.util.Map)" title="class or interface in java.sql">getArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the array index of the first element to retrieve;
+              the first element is at index 1<DD><CODE>count</CODE> - the number of successive SQL array elements to
+ retrieve<DD><CODE>map</CODE> - a <code>java.util.Map</code> object
+ that contains SQL type names and the classes in
+ the Java programming language to which they are mapped
+<DT><B>Returns:</B><DD>an array containing up to <code>count</code>
+ consecutive elements of the SQL <code>ARRAY</code> value designated by this
+ <code>Array</code> object, beginning with element
+ <code>index</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting to
+ access the array
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSet()"><!-- --></A><H3>
+getResultSet</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getResultSet</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a result set that contains the elements of the SQL
+ <code>ARRAY</code> value
+ designated by this <code>Array</code> object.  If appropriate,
+ the elements of the array are mapped using the connection's type
+ map; otherwise, the standard mapping is used.
+ <p>
+ The result set contains one row for each array element, with
+ two columns in each row.  The second column stores the element
+ value; the first column stores the index into the array for
+ that element (with the first array element being at index 1).
+ The rows are in ascending order corresponding to
+ the order of the indices.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getResultSet()" title="class or interface in java.sql">getResultSet</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A> object containing one row for each
+ of the elements in the array designated by this <code>Array</code>
+ object, with the rows in ascending order based on the indices.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting to
+ access the array
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSet(java.util.Map)"><!-- --></A><H3>
+getResultSet</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getResultSet</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a result set that contains the elements of the SQL
+ <code>ARRAY</code> value designated by this <code>Array</code> object.
+ This method uses
+ the specified <code>map</code> for type map customizations
+ unless the base type of the array does not match a user-defined
+ type in <code>map</code>, in which case it
+ uses the standard mapping. This version of the method
+ <code>getResultSet</code> uses either the given type map or the standard mapping;
+ it never uses the type map associated with the connection.
+ <p>
+ The result set contains one row for each array element, with
+ two columns in each row.  The second column stores the element
+ value; the first column stores the index into the array for
+ that element (with the first array element being at index 1).
+ The rows are in ascending order corresponding to
+ the order of the indices.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getResultSet(java.util.Map)" title="class or interface in java.sql">getResultSet</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>map</CODE> - contains the mapping of SQL user-defined types to
+ classes in the Java programming language
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object containing one row for each
+ of the elements in the array designated by this <code>Array</code>
+ object, with the rows in ascending order based on the indices.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting to
+ access the array
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSet(long, int)"><!-- --></A><H3>
+getResultSet</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getResultSet</B>(long&nbsp;index,
+                              int&nbsp;count)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a result set holding the elements of the subarray that
+ starts at index <code>index</code> and contains up to
+ <code>count</code> successive elements.  This method uses
+ the connection's type map to map the elements of the array if
+ the map contains an entry for the base type. Otherwise, the
+ standard mapping is used.
+ <P>
+ The result set has one row for each element of the SQL array
+ designated by this object, with the first row containing the
+ element at index <code>index</code>.  The result set has
+ up to <code>count</code> rows in ascending order based on the
+ indices.  Each row has two columns:  The second column stores
+ the element value; the first column stores the index into the
+ array for that element.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getResultSet(long, int)" title="class or interface in java.sql">getResultSet</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the array index of the first element to retrieve;
+              the first element is at index 1<DD><CODE>count</CODE> - the number of successive SQL array elements to retrieve
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object containing up to
+ <code>count</code> consecutive elements of the SQL array
+ designated by this <code>Array</code> object, starting at
+ index <code>index</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting to
+ access the array
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSet(long, int, java.util.Map)"><!-- --></A><H3>
+getResultSet</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getResultSet</B>(long&nbsp;index,
+                              int&nbsp;count,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a result set holding the elements of the subarray that
+ starts at index <code>index</code> and contains up to
+ <code>count</code> successive elements.
+ This method uses
+ the specified <code>map</code> for type map customizations
+ unless the base type of the array does not match a user-defined
+ type in <code>map</code>, in which case it
+ uses the standard mapping. This version of the method
+ <code>getResultSet</code> uses either the given type map or the standard mapping;
+ it never uses the type map associated with the connection.
+ <P>
+ The result set has one row for each element of the SQL array
+ designated by this object, with the first row containing the
+ element at index <code>index</code>.  The result set has
+ up to <code>count</code> rows in ascending order based on the
+ indices.  Each row has two columns:  The second column stores
+ the element value; the first column stroes the index into the
+ array for that element.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#getResultSet(long, int, java.util.Map)" title="class or interface in java.sql">getResultSet</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the array index of the first element to retrieve;
+              the first element is at index 1<DD><CODE>count</CODE> - the number of successive SQL array elements to retrieve<DD><CODE>map</CODE> - the <code>Map</code> object that contains the mapping
+ of SQL type names to classes in the Java(tm) programming language
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object containing up to
+ <code>count</code> consecutive elements of the SQL array
+ designated by this <code>Array</code> object, starting at
+ index <code>index</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while attempting to
+ access the array
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>toString</B>()</PRE>
+<DL>
+<DD>Returns a string representation in the form <code>ARRAY[..., ...]</code>
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="free()"><!-- --></A><H3>
+free</H3>
+<PRE>
+public void <B>free</B>()
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method frees the <code>Array</code> object and releases the resources that
+ it holds. The object is invalid once the <code>free</code>
+ method is called.
+ <p>
+ After <code>free</code> has been called, any attempt to invoke a
+ method other than <code>free</code> will result in a <code>SQLException</code>
+ being thrown.  If <code>free</code> is called multiple times, the subsequent
+ calls to <code>free</code> are treated as a no-op.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true#free()" title="class or interface in java.sql">free</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs releasing
+ the Array's resources
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCArray.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCArray.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCArray.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCBlob.html b/doc/apidocs/org/hsqldb/jdbc/JDBCBlob.html
new file mode 100644
index 0000000..105b644
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCBlob.html
@@ -0,0 +1,1049 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCBlob (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCBlob (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCBlob.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCBlob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCBlob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCBlob</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCBlob</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCBlob</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></DL>
+</PRE>
+
+<P>
+The representation (mapping) in
+ the Java<sup><font size=-2>TM</font></sup> programming
+ language of an SQL
+ <code>BLOB</code> value.  An SQL <code>BLOB</code> is a built-in type
+ that stores a Binary Large Object as a column value in a row of
+ a database table. By default drivers implement <code>Blob</code> using
+ an SQL <code>locator(BLOB)</code>, which means that a
+ <code>Blob</code> object contains a logical pointer to the
+ SQL <code>BLOB</code> data rather than the data itself.
+ A <code>Blob</code> object is valid for the duration of the
+ transaction in which is was created.
+
+ <P>Methods in the interfaces <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A>,
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql"><CODE>CallableStatement</CODE></A>, and <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql"><CODE>PreparedStatement</CODE></A>, such as
+ <code>getBlob</code> and <code>setBlob</code> allow a programmer to
+ access an SQL <code>BLOB</code> value.
+ The <code>Blob</code> interface provides methods for getting the
+ length of an SQL <code>BLOB</code> (Binary Large Object) value,
+ for materializing a <code>BLOB</code> value on the client, and for
+ determining the position of a pattern of bytes within a
+ <code>BLOB</code> value. In addition, this interface has methods for updating
+ a <code>BLOB</code> value.
+ <p>
+ All methods on the <code>Blob</code> interface must be fully implemented if the
+ JDBC driver supports the data type.
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Previous to 2.0, the HSQLDB driver did not implement Blob using an SQL
+ locator(BLOB).  That is, an HSQLDB Blob object did not contain a logical
+ pointer to SQL BLOB data; rather it directly contained a representation of
+ the data (a byte array). As a result, an HSQLDB Blob object was itself
+ valid beyond the duration of the transaction in which is was created,
+ although it did not necessarily represent a corresponding value
+ on the database. Also, the interface methods for updating a BLOB value
+ were unsupported, with the exception of the truncate method,
+ in that it could be used to truncate the local value. <p>
+
+ Starting with 2.0, the HSQLDB driver fully supports both local and remote
+ SQL BLOB data implementations, meaning that an HSQLDB Blob object <em>may</em>
+ contain a logical pointer to remote SQL BLOB data (see <A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><CODE>JDBCBlobClient</CODE></A>) or it may directly contain a local representation of the
+ data (as implemented in this class).  In particular, when the product is built
+ under JDK 1.6+ and the Blob instance is constructed as a result of calling
+ JDBCConnection.createBlob(), then the resulting Blob instance is initially
+ disconnected (is not bound to the tranaction scope of the vending Connection
+ object), the data is contained directly and all interface methods for
+ updating the BLOB value are supported for local use until the first
+ invocation of free(); otherwise, an HSQLDB Blob's implementation is
+ determined at runtime by the driver, it is typically not valid beyond the
+ duration of the transaction in which is was created, and there no
+ standard way to query whether it represents a local or remote
+ value.<p>
+
+ </div>
+ <!-- end Release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>james house jhouse@part.net, boucherb@users</DD>
+</DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#MAX_POS">MAX_POS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#MIN_POS">MIN_POS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#JDBCBlob(byte[])">JDBCBlob</A></B>(byte[]&nbsp;data)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new JDBCBlob instance wrapping the given octet sequence.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#free()">free</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method frees the <code>Blob</code> object and releases the resources that
+ it holds.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#getBinaryStream()">getBinaryStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>BLOB</code> value designated by this
+ <code>Blob</code> instance as a stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#getBinaryStream(long, long)">getBinaryStream</A></B>(long&nbsp;pos,
+                long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+ starting  with the byte specified by pos, which is length bytes in length.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#getBytes(long, int)">getBytes</A></B>(long&nbsp;pos,
+         int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves all or part of the <code>BLOB</code>
+ value that this <code>Blob</code> object represents, as an array of
+ bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#isGetBinaryStreamUsesCopy()">isGetBinaryStreamUsesCopy</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether getBinaryStream() uses a copy of
+ the underlying buffer.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#length()">length</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the number of bytes in the <code>BLOB</code> value
+ designated by this <code>Blob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#position(java.sql.Blob, long)">position</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;pattern,
+         long&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the byte position in the <code>BLOB</code> value
+ designated by this <code>Blob</code> object at which
+ <code>pattern</code> begins.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#position(byte[], long)">position</A></B>(byte[]&nbsp;pattern,
+         long&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the byte position at which the specified byte array
+ <code>pattern</code> begins within the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#setBinaryStream(long)">setBinaryStream</A></B>(long&nbsp;pos)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a stream that can be used to write to the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#setBytes(long, byte[])">setBytes</A></B>(long&nbsp;pos,
+         byte[]&nbsp;bytes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes the given array of bytes to the <code>BLOB</code> value that
+ this <code>Blob</code> object represents, starting at position
+ <code>pos</code>, and returns the number of bytes written.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#setBytes(long, byte[], int, int)">setBytes</A></B>(long&nbsp;pos,
+         byte[]&nbsp;bytes,
+         int&nbsp;offset,
+         int&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes all or part of the given <code>byte</code> array to the
+ <code>BLOB</code> value that this <code>Blob</code> object represents
+ and returns the number of bytes written.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#setGetBinaryStreamUsesCopy(boolean)">setGetBinaryStreamUsesCopy</A></B>(boolean&nbsp;b)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assigns whether getBinaryStream() uses a copy of
+ the underlying byte[].</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#truncate(long)">truncate</A></B>(long&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Truncates the <code>BLOB</code> value that this <code>Blob</code>
+ object represents to be <code>len</code> bytes in length.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="MIN_POS"><!-- --></A><H3>
+MIN_POS</H3>
+<PRE>
+public static final long <B>MIN_POS</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCBlob.MIN_POS">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="MAX_POS"><!-- --></A><H3>
+MAX_POS</H3>
+<PRE>
+public static final long <B>MAX_POS</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCBlob.MAX_POS">Constant Field Values</A></DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCBlob(byte[])"><!-- --></A><H3>
+JDBCBlob</H3>
+<PRE>
+public <B>JDBCBlob</B>(byte[]&nbsp;data)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new JDBCBlob instance wrapping the given octet sequence. <p>
+
+ This constructor is used internally to retrieve result set values as
+ Blob objects, yet it must be public to allow access from other packages.
+ As such (in the interest of efficiency) this object maintains a reference
+ to the given octet sequence rather than making a copy; special care
+ should be taken by extenal clients never to use this constructor with a
+ byte array object that may later be modified extenally.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>data</CODE> - the octet sequence representing the Blob value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the argument is null</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="length()"><!-- --></A><H3>
+length</H3>
+<PRE>
+public long <B>length</B>()
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns the number of bytes in the <code>BLOB</code> value
+ designated by this <code>Blob</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#length()" title="class or interface in java.sql">length</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>length of the <code>BLOB</code> in bytes
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+ length of the <code>BLOB</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBytes(long, int)"><!-- --></A><H3>
+getBytes</H3>
+<PRE>
+public byte[] <B>getBytes</B>(long&nbsp;pos,
+                       int&nbsp;length)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves all or part of the <code>BLOB</code>
+ value that this <code>Blob</code> object represents, as an array of
+ bytes.  This <code>byte</code> array contains up to <code>length</code>
+ consecutive bytes starting at position <code>pos</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The official specification above is ambiguous in that it does not
+ precisely indicate the policy to be observed when
+ pos > this.length() - length.  One policy would be to retrieve the
+ octets from pos to this.length().  Another would be to throw an
+ exception.  HSQLDB observes the second policy.
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#getBytes(long, int)" title="class or interface in java.sql">getBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the ordinal position of the first byte in the
+        <code>BLOB</code> value to be extracted; the first byte is at
+        position 1<DD><CODE>length</CODE> - the number of consecutive bytes to be copied
+<DT><B>Returns:</B><DD>a byte array containing up to <code>length</code>
+         consecutive bytes from the <code>BLOB</code> value designated
+         by this <code>Blob</code> object, starting with the
+         byte at position <code>pos</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the BLOB value;
+            if <code>pos</code> is less than 1 or <code>length</code> is
+            less than 0.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#setBytes(long, byte[])"><CODE>setBytes(long, byte[])</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBinaryStream()"><!-- --></A><H3>
+getBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getBinaryStream</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the <code>BLOB</code> value designated by this
+ <code>Blob</code> instance as a stream.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#getBinaryStream()" title="class or interface in java.sql">getBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a stream containing the <code>BLOB</code> data
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>BLOB</code> value
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#setBinaryStream(long)"><CODE>setBinaryStream(long)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="position(byte[], long)"><!-- --></A><H3>
+position</H3>
+<PRE>
+public long <B>position</B>(byte[]&nbsp;pattern,
+                     long&nbsp;start)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the byte position at which the specified byte array
+ <code>pattern</code> begins within the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.  The
+ search for <code>pattern</code> begins at position
+ <code>start</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#position(byte[], long)" title="class or interface in java.sql">position</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - the byte array for which to search<DD><CODE>start</CODE> - the position at which to begin searching; the
+        first position is 1
+<DT><B>Returns:</B><DD>the position at which the pattern appears, else -1
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+ <code>BLOB</code> or if start is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="position(java.sql.Blob, long)"><!-- --></A><H3>
+position</H3>
+<PRE>
+public long <B>position</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;pattern,
+                     long&nbsp;start)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the byte position in the <code>BLOB</code> value
+ designated by this <code>Blob</code> object at which
+ <code>pattern</code> begins.  The search begins at position
+ <code>start</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#position(java.sql.Blob, long)" title="class or interface in java.sql">position</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - the <code>Blob</code> object designating
+ the <code>BLOB</code> value for which to search<DD><CODE>start</CODE> - the position in the <code>BLOB</code> value
+        at which to begin searching; the first position is 1
+<DT><B>Returns:</B><DD>the position at which the pattern begins, else -1
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>BLOB</code> value or if start is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBytes(long, byte[])"><!-- --></A><H3>
+setBytes</H3>
+<PRE>
+public int <B>setBytes</B>(long&nbsp;pos,
+                    byte[]&nbsp;bytes)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Writes the given array of bytes to the <code>BLOB</code> value that
+ this <code>Blob</code> object represents, starting at position
+ <code>pos</code>, and returns the number of bytes written.
+ The array of bytes will overwrite the existing bytes
+ in the <code>Blob</code> object starting at the position
+ <code>pos</code>.  If the end of the <code>Blob</code> value is reached
+ while writing the array of bytes, then the length of the <code>Blob</code>
+ value will be increased to accomodate the extra bytes.
+ <p>
+ <b>Note:</b> If the value specified for <code>pos</code>
+ is greater then the length+1 of the <code>BLOB</code> value then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is supported. <p>
+
+ When built under JDK 1.6+ and the Blob instance is constructed as a
+ result of calling JDBCConnection.createBlob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in a
+ database because JDBCConnection.createBlob() constructs disconnected,
+ initially empty Blob instances. To propogate the Blob value to a database
+ in this case, it is required to supply the Blob instance to an updating
+ or inserting setXXX method of a Prepared or Callable Statement, or to
+ supply the Blob instance to an updateXXX method of an updateable
+ ResultSet. <p>
+
+ <b>Implementation Notes:</b><p>
+
+ No attempt is made to ensure precise thread safety. Instead, volatile
+ member field and local variable snapshot isolation semantics are
+ implemented.  This is expected to eliminate most issues related
+ to race conditions, with the possible exception of concurrent
+ invocation of free(). <p>
+
+ In general, however, if an application may perform concurrent
+ JDBCBlob modifications and the integrity of the application depends on
+ total order Blob modification semantics, then such operations
+ should be synchronized on an appropriate monitor.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#setBytes(long, byte[])" title="class or interface in java.sql">setBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position in the <code>BLOB</code> object at which
+        to start writing; the first position is 1<DD><CODE>bytes</CODE> - the array of bytes to be written to the <code>BLOB</code>
+        value that this <code>Blob</code> object represents
+<DT><B>Returns:</B><DD>the number of bytes written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>BLOB</code> value or if pos is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#getBytes(long, int)"><CODE>getBytes(long, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBytes(long, byte[], int, int)"><!-- --></A><H3>
+setBytes</H3>
+<PRE>
+public int <B>setBytes</B>(long&nbsp;pos,
+                    byte[]&nbsp;bytes,
+                    int&nbsp;offset,
+                    int&nbsp;len)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Writes all or part of the given <code>byte</code> array to the
+ <code>BLOB</code> value that this <code>Blob</code> object represents
+ and returns the number of bytes written.
+ Writing starts at position <code>pos</code> in the <code>BLOB</code>
+ value; <code>len</code> bytes from the given byte array are written.
+ The array of bytes will overwrite the existing bytes
+ in the <code>Blob</code> object starting at the position
+ <code>pos</code>.  If the end of the <code>Blob</code> value is reached
+ while writing the array of bytes, then the length of the <code>Blob</code>
+ value will be increased to accomodate the extra bytes.
+ <p>
+ <b>Note:</b> If the value specified for <code>pos</code>
+ is greater then the length+1 of the <code>BLOB</code> value then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is supported. <p>
+
+ When built under JDK 1.6+ and the Blob instance is constructed as a
+ result of calling JDBCConnection.createBlob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in a
+ database because JDBCConnection.createBlob() constructs disconnected,
+ initially empty Blob instances. To propogate the Blob value to a database
+ in this case, it is required to supply the Blob instance to an updating
+ or inserting setXXX method of a Prepared or Callable Statement, or to
+ supply the Blob instance to an updateXXX method of an updateable
+ ResultSet. <p>
+
+ <b>Implementation Notes:</b><p>
+
+ If the value specified for <code>pos</code>
+ is greater than the length of the <code>BLOB</code> value, then
+ the <code>BLOB</code> value is extended in length to accept the
+ written octets and the undefined region up to <code>pos</code> is
+ filled with (byte)0. <p>
+
+ No attempt is made to ensure precise thread safety. Instead, volatile
+ member field and local variable snapshot isolation semantics are
+ implemented.  This is expected to eliminate most issues related
+ to race conditions, with the possible exception of concurrent
+ invocation of free(). <p>
+
+ In general, however, if an application may perform concurrent
+ JDBCBlob modifications and the integrity of the application depends on
+ total order Blob modification semantics, then such operations
+ should be synchronized on an appropriate monitor.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#setBytes(long, byte[], int, int)" title="class or interface in java.sql">setBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position in the <code>BLOB</code> object at which
+        to start writing; the first position is 1<DD><CODE>bytes</CODE> - the array of bytes to be written to this <code>BLOB</code>
+        object<DD><CODE>offset</CODE> - the offset into the array <code>bytes</code> at which
+        to start reading the bytes to be set<DD><CODE>len</CODE> - the number of bytes to be written to the <code>BLOB</code>
+        value from the array of bytes <code>bytes</code>
+<DT><B>Returns:</B><DD>the number of bytes written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>BLOB</code> value or if pos is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#getBytes(long, int)"><CODE>getBytes(long, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream(long)"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A> <B>setBinaryStream</B>(long&nbsp;pos)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a stream that can be used to write to the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.  The stream begins
+ at position <code>pos</code>.
+ The  bytes written to the stream will overwrite the existing bytes
+ in the <code>Blob</code> object starting at the position
+ <code>pos</code>.  If the end of the <code>Blob</code> value is reached
+ while writing to the stream, then the length of the <code>Blob</code>
+ value will be increased to accomodate the extra bytes.
+ <p>
+ <b>Note:</b> If the value specified for <code>pos</code>
+ is greater then the length+1 of the <code>BLOB</code> value then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is supported. <p>
+
+ When built under JDK 1.6+ and the Blob instance is constructed as a
+ result of calling JDBCConnection.createBlob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in a
+ database because JDBCConnection.createBlob() constructs disconnected,
+ initially empty Blob instances. To propogate the Blob value to a database
+ in this case, it is required to supply the Blob instance to an updating
+ or inserting setXXX method of a Prepared or Callable Statement, or to
+ supply the Blob instance to an updateXXX method of an updateable
+ ResultSet. <p>
+
+ <b>Implementation Notes:</b><p>
+
+ The data written to the stream does not appear in this
+ Blob until the stream is closed <p>
+
+ When the stream is closed, if the value specified for <code>pos</code>
+ is greater than the length of the <code>BLOB</code> value, then
+ the <code>BLOB</code> value is extended in length to accept the
+ written octets and the undefined region up to <code>pos</code> is
+ filled with (byte)0. <p>
+
+ Also, no attempt is made to ensure precise thread safety. Instead,
+ volatile member field and local variable snapshot isolation semantics
+ are implemented.  This is expected to eliminate most issues related
+ to race conditions, with the possible exception of concurrent
+ invocation of free(). <p>
+
+ In general, however, if an application may perform concurrent
+ JDBCBlob modifications and the integrity of the application depends on
+ total order Blob modification semantics, then such operations
+ should be synchronized on an appropriate monitor.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#setBinaryStream(long)" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position in the <code>BLOB</code> value at which
+        to start writing; the first position is 1
+<DT><B>Returns:</B><DD>a <code>java.io.OutputStream</code> object to which data can
+         be written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>BLOB</code> value or if pos is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html#getBinaryStream()"><CODE>getBinaryStream()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="truncate(long)"><!-- --></A><H3>
+truncate</H3>
+<PRE>
+public void <B>truncate</B>(long&nbsp;len)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Truncates the <code>BLOB</code> value that this <code>Blob</code>
+ object represents to be <code>len</code> bytes in length.
+ <p>
+ <b>Note:</b> If the value specified for <code>pos</code>
+ is greater then the length+1 of the <code>BLOB</code> value then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is fully supported. <p>
+
+ When built under JDK 1.6+ and the Blob instance is constructed as a
+ result of calling JDBCConnection.createBlob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in a
+ database because JDBCConnection.createBlob() constructs disconnected,
+ initially empty Blob instances. To propogate the truncated Blob value to
+ a database in this case, it is required to supply the Blob instance to
+ an updating or inserting setXXX method of a Prepared or Callable
+ Statement, or to supply the Blob instance to an updateXXX method of an
+ updateable ResultSet. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#truncate(long)" title="class or interface in java.sql">truncate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>len</CODE> - the length, in bytes, to which the <code>BLOB</code> value
+        that this <code>Blob</code> object represents should be truncated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>BLOB</code> value or if len is less than 0
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="free()"><!-- --></A><H3>
+free</H3>
+<PRE>
+public void <B>free</B>()
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method frees the <code>Blob</code> object and releases the resources that
+ it holds. The object is invalid once the <code>free</code>
+ method is called.
+ <p>
+ After <code>free</code> has been called, any attempt to invoke a
+ method other than <code>free</code> will result in a <code>SQLException</code>
+ being thrown.  If <code>free</code> is called multiple times, the subsequent
+ calls to <code>free</code> are treated as a no-op.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#free()" title="class or interface in java.sql">free</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs releasing
+ the Blob's resources
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBinaryStream(long, long)"><!-- --></A><H3>
+getBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getBinaryStream</B>(long&nbsp;pos,
+                                   long&nbsp;length)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+ starting  with the byte specified by pos, which is length bytes in length.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#getBinaryStream(long, long)" title="class or interface in java.sql">getBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the offset to the first byte of the partial value to be retrieved.
+  The first byte in the <code>Blob</code> is at position 1<DD><CODE>length</CODE> - the length in bytes of the partial value to be retrieved
+<DT><B>Returns:</B><DD><code>InputStream</code> through which the partial <code>Blob</code> value can be read.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if pos is less than 1 or if pos is greater than the number of bytes
+ in the <code>Blob</code> or if pos + length is greater than the number of bytes
+ in the <code>Blob</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setGetBinaryStreamUsesCopy(boolean)"><!-- --></A><H3>
+setGetBinaryStreamUsesCopy</H3>
+<PRE>
+public void <B>setGetBinaryStreamUsesCopy</B>(boolean&nbsp;b)</PRE>
+<DL>
+<DD>Assigns whether getBinaryStream() uses a copy of
+ the underlying byte[].
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>b</CODE> - when true, then getBinaryStream() uses a copy of
+ the underlying byte[]</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGetBinaryStreamUsesCopy()"><!-- --></A><H3>
+isGetBinaryStreamUsesCopy</H3>
+<PRE>
+public boolean <B>isGetBinaryStreamUsesCopy</B>()</PRE>
+<DL>
+<DD>Retrieves whether getBinaryStream() uses a copy of
+ the underlying buffer.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if getBinaryStream() uses a copy of
+ the underlying buffer; else false</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCBlob.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCBlob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCBlob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCBlobClient.html b/doc/apidocs/org/hsqldb/jdbc/JDBCBlobClient.html
new file mode 100644
index 0000000..33d615f
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCBlobClient.html
@@ -0,0 +1,634 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCBlobClient (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCBlobClient (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCBlobClient.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCBlobClient.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCBlobClient.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCBlobClient</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCBlobClient</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCBlobClient</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></DL>
+</PRE>
+
+<P>
+A wrapper for HSQLDB BlobData objects.
+
+ Instances of this class are returnd by calls to ResultSet methods.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.9.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>Fred Toussi (fredt@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#free()">free</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method frees the <code>Blob</code> object and releases the resources that
+ it holds.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#getBinaryStream()">getBinaryStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>BLOB</code> value designated by this
+ <code>Blob</code> instance as a stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#getBinaryStream(long, long)">getBinaryStream</A></B>(long&nbsp;pos,
+                long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+ starting  with the byte specified by pos, which is length bytes in length.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#getBytes(long, int)">getBytes</A></B>(long&nbsp;pos,
+         int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves all or part of the <code>BLOB</code> value that this
+ <code>Blob</code> object represents, as an array of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#isClosed()">isClosed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#length()">length</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the number of bytes in the <code>BLOB</code> value designated
+ by this <code>Blob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#position(java.sql.Blob, long)">position</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;pattern,
+         long&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the byte position in the <code>BLOB</code> value designated
+ by this <code>Blob</code> object at which <code>pattern</code> begins.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#position(byte[], long)">position</A></B>(byte[]&nbsp;pattern,
+         long&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the byte position at which the specified byte array
+ <code>pattern</code> begins within the <code>BLOB</code> value that
+ this <code>Blob</code> object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#setBinaryStream(long)">setBinaryStream</A></B>(long&nbsp;pos)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a stream that can be used to write to the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#setBytes(long, byte[])">setBytes</A></B>(long&nbsp;pos,
+         byte[]&nbsp;bytes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes the given array of bytes to the <code>BLOB</code> value that
+ this <code>Blob</code> object represents, starting at position
+ <code>pos</code>, and returns the number of bytes written.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#setBytes(long, byte[], int, int)">setBytes</A></B>(long&nbsp;pos,
+         byte[]&nbsp;bytes,
+         int&nbsp;offset,
+         int&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes all or part of the given <code>byte</code> array to the
+ <code>BLOB</code> value that this <code>Blob</code> object represents
+ and returns the number of bytes written.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html#truncate(long)">truncate</A></B>(long&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Truncates the <code>BLOB</code> value that this <code>Blob</code>
+ object represents to be <code>len</code> bytes in length.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="length()"><!-- --></A><H3>
+length</H3>
+<PRE>
+public long <B>length</B>()
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns the number of bytes in the <code>BLOB</code> value designated
+ by this <code>Blob</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#length()" title="class or interface in java.sql">length</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>length of the <code>BLOB</code> in bytes
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the length of the
+   <code>BLOB</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBytes(long, int)"><!-- --></A><H3>
+getBytes</H3>
+<PRE>
+public byte[] <B>getBytes</B>(long&nbsp;pos,
+                       int&nbsp;length)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves all or part of the <code>BLOB</code> value that this
+ <code>Blob</code> object represents, as an array of bytes.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#getBytes(long, int)" title="class or interface in java.sql">getBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the ordinal position of the first byte in the
+   <code>BLOB</code> value to be extracted; the first byte is at
+   position 1<DD><CODE>length</CODE> - the number of consecutive bytes to be copied
+<DT><B>Returns:</B><DD>a byte array containing up to <code>length</code> consecutive
+   bytes from the <code>BLOB</code> value designated by this
+   <code>Blob</code> object, starting with the byte at position
+   <code>pos</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>BLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBinaryStream()"><!-- --></A><H3>
+getBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getBinaryStream</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the <code>BLOB</code> value designated by this
+ <code>Blob</code> instance as a stream.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#getBinaryStream()" title="class or interface in java.sql">getBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a stream containing the <code>BLOB</code> data
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>BLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="position(byte[], long)"><!-- --></A><H3>
+position</H3>
+<PRE>
+public long <B>position</B>(byte[]&nbsp;pattern,
+                     long&nbsp;start)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the byte position at which the specified byte array
+ <code>pattern</code> begins within the <code>BLOB</code> value that
+ this <code>Blob</code> object represents.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#position(byte[], long)" title="class or interface in java.sql">position</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - the byte array for which to search<DD><CODE>start</CODE> - the position at which to begin searching; the first
+   position is 1
+<DT><B>Returns:</B><DD>the position at which the pattern appears, else -1
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>BLOB</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="position(java.sql.Blob, long)"><!-- --></A><H3>
+position</H3>
+<PRE>
+public long <B>position</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;pattern,
+                     long&nbsp;start)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the byte position in the <code>BLOB</code> value designated
+ by this <code>Blob</code> object at which <code>pattern</code> begins.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#position(java.sql.Blob, long)" title="class or interface in java.sql">position</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - the <code>Blob</code> object designating the
+   <code>BLOB</code> value for which to search<DD><CODE>start</CODE> - the position in the <code>BLOB</code> value at which to
+   begin searching; the first position is 1
+<DT><B>Returns:</B><DD>the position at which the pattern begins, else -1
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>BLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBytes(long, byte[])"><!-- --></A><H3>
+setBytes</H3>
+<PRE>
+public int <B>setBytes</B>(long&nbsp;pos,
+                    byte[]&nbsp;bytes)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Writes the given array of bytes to the <code>BLOB</code> value that
+ this <code>Blob</code> object represents, starting at position
+ <code>pos</code>, and returns the number of bytes written.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#setBytes(long, byte[])" title="class or interface in java.sql">setBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position in the <code>BLOB</code> object at which to
+   start writing<DD><CODE>bytes</CODE> - the array of bytes to be written to the
+   <code>BLOB</code> value that this <code>Blob</code> object
+   represents
+<DT><B>Returns:</B><DD>the number of bytes written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>BLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBytes(long, byte[], int, int)"><!-- --></A><H3>
+setBytes</H3>
+<PRE>
+public int <B>setBytes</B>(long&nbsp;pos,
+                    byte[]&nbsp;bytes,
+                    int&nbsp;offset,
+                    int&nbsp;len)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Writes all or part of the given <code>byte</code> array to the
+ <code>BLOB</code> value that this <code>Blob</code> object represents
+ and returns the number of bytes written.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#setBytes(long, byte[], int, int)" title="class or interface in java.sql">setBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position in the <code>BLOB</code> object at which to
+   start writing<DD><CODE>bytes</CODE> - the array of bytes to be written to this
+   <code>BLOB</code> object<DD><CODE>offset</CODE> - the offset into the array <code>bytes</code> at which
+   to start reading the bytes to be set<DD><CODE>len</CODE> - the number of bytes to be written to the <code>BLOB</code>
+   value from the array of bytes <code>bytes</code>
+<DT><B>Returns:</B><DD>the number of bytes written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>BLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream(long)"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A> <B>setBinaryStream</B>(long&nbsp;pos)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a stream that can be used to write to the <code>BLOB</code>
+ value that this <code>Blob</code> object represents.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#setBinaryStream(long)" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position in the <code>BLOB</code> value at which to
+   start writing
+<DT><B>Returns:</B><DD>a <code>java.io.OutputStream</code> object to which data can
+   be written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>BLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="truncate(long)"><!-- --></A><H3>
+truncate</H3>
+<PRE>
+public void <B>truncate</B>(long&nbsp;len)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Truncates the <code>BLOB</code> value that this <code>Blob</code>
+ object represents to be <code>len</code> bytes in length.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#truncate(long)" title="class or interface in java.sql">truncate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>len</CODE> - the length, in bytes, to which the <code>BLOB</code> value
+   that this <code>Blob</code> object represents should be truncated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>BLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="free()"><!-- --></A><H3>
+free</H3>
+<PRE>
+public void <B>free</B>()
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method frees the <code>Blob</code> object and releases the resources that
+ it holds. The object is invalid once the <code>free</code>
+ method is called.
+ <p>
+ After <code>free</code> has been called, any attempt to invoke a
+ method other than <code>free</code> will result in a <code>SQLException</code>
+ being thrown.  If <code>free</code> is called multiple times, the subsequent
+ calls to <code>free</code> are treated as a no-op.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#free()" title="class or interface in java.sql">free</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs releasing
+ the Blob's resources
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBinaryStream(long, long)"><!-- --></A><H3>
+getBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getBinaryStream</B>(long&nbsp;pos,
+                                   long&nbsp;length)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+ starting  with the byte specified by pos, which is length bytes in length.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true#getBinaryStream(long, long)" title="class or interface in java.sql">getBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the offset to the first byte of the partial value to be retrieved.
+  The first byte in the <code>Blob</code> is at position 1<DD><CODE>length</CODE> - the length in bytes of the partial value to be retrieved
+<DT><B>Returns:</B><DD><code>InputStream</code> through which the partial <code>Blob</code> value can be read.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if pos is less than 1 or if pos is greater than the number of bytes
+ in the <code>Blob</code> or if pos + length is greater than the number of bytes
+ in the <code>Blob</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isClosed()"><!-- --></A><H3>
+isClosed</H3>
+<PRE>
+public boolean <B>isClosed</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCBlobClient.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCBlobClient.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCBlobClient.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCCallableStatement.html b/doc/apidocs/org/hsqldb/jdbc/JDBCCallableStatement.html
new file mode 100644
index 0000000..1c7a49c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCCallableStatement.html
@@ -0,0 +1,6269 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCCallableStatement (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCCallableStatement (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCCallableStatement.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCCallableStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCCallableStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCCallableStatement</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">org.hsqldb.jdbc.JDBCPreparedStatement</A>
+      <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCCallableStatement</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCCallableStatement</B><DT>extends <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></DL>
+</PRE>
+
+<P>
+<!-- start generic documentation -->
+
+ The interface used to execute SQL stored procedures.  The JDBC API
+ provides a stored procedure SQL escape syntax that allows stored procedures
+ to be called in a standard way for all RDBMSs. This escape syntax has one
+ form that includes a result parameter and one that does not. If used, the result
+ parameter must be registered as an OUT parameter. The other parameters
+ can be used for input, output or both. Parameters are referred to
+ sequentially, by number, with the first parameter being 1.
+ <p>(JDBC4 clarification:)
+ <PRE>
+   {?= call &lt;procedure-name&gt;[(&lt;arg1&gt;,&lt;arg2&gt;, ...)]}
+   {call &lt;procedure-name&gt;[(&lt;arg1&gt;,&lt;arg2&gt;, ...)]}
+ </PRE>
+ <P>
+ IN parameter values are set using the <code>set</code> methods inherited from
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql"><CODE>PreparedStatement</CODE></A>.  The type of all OUT parameters must be
+ registered prior to executing the stored procedure; their values
+ are retrieved after execution via the <code>get</code> methods provided here.
+ <P>
+ A <code>CallableStatement</code> can return one <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A> object or
+ multiple <code>ResultSet</code> objects.  Multiple
+ <code>ResultSet</code> objects are handled using operations
+ inherited from <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql"><CODE>Statement</CODE></A>.
+ <P>
+ For maximum portability, a call's <code>ResultSet</code> objects and
+ update counts should be processed prior to getting the values of output
+ parameters.
+ <P>
+
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Some of the previously unsupported features of this interface
+ are now supported, such as the parameterName-based setter methods. <p>
+
+ More importantly, JDBCCallableStatement objects are now backed by a true
+ compiled parameteric representation. Hence, there are now significant
+ performance gains to be had by using a CallableStatement object instead of
+ a Statement object, if a short-running CALL statement is to be executed more
+ than a small number of times.  Moreover, the recent work lays the foundation
+ for work in a subsequenct release to support CallableStatement OUT and
+ IN OUT style parameters, as well as the generation and retrieval of multiple
+ results in response to the execution of a CallableStatement object. <p>
+
+ For a more in-depth discussion of performance issues regarding HSQLDB
+ prepared and callable statement objects, please see overview section of
+ <A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><CODE>JDBCPreparedStatment</CODE></A>.
+
+ <hr>
+
+ As with many DBMS, HSQLDB support for stored procedures is not provided in
+ a completely standard fashion. <p>
+
+ Beyond the XOpen/ODBC extended scalar functions, stored procedures are
+ typically supported in ways that vary greatly from one DBMS implementation
+ to the next.  So, it is almost guaranteed that the code for a stored
+ procedure written under a specific DBMS product will not work without
+ at least some modification in the context of another vendor's product
+ or even across a single vendor's product lines.  Moving stored procedures
+ from one DBMS product line to another almost invariably involves complex
+ porting issues and often may not be possible at all. <em>Be warned</em>. <p>
+
+ One kind of HSQLDB stored procedures is Java routines that map directly onto
+ the static methods of compiled Java classes found on the classpath of the
+ engine at runtime. <p>
+
+ Overloaded methods are supported and resolved according to the type of
+ para;meters.
+
+ The other kind of HSQLDB stored procedures is SQL routines that are created
+ as part of schemas.
+
+ With SQL routines, <code>OUT</code> and <code>IN OUT</code> parameters
+ are also supported. <p>
+
+ In addition, HSQLDB stored procedure call mechanism allows the
+ more general HSQLDB SQL expression evaluation mechanism.  This
+ extension provides the ability to evaluate simple SQL expressions, possibly
+ containing Java method invocations. <p>
+
+ With HSQLDB, executing a <code>CALL</code> statement that produces an opaque
+ (OTHER) or known scalar object reference has virtually the same effect as:
+
+ <PRE class="SqlCodeExample">
+ CREATE TABLE DUAL (dummy VARCHAR);
+ INSERT INTO DUAL VALUES(NULL);
+ SELECT &lt;simple-expression&gt; FROM DUAL;
+ </PRE>
+
+ As a transitional measure, HSQLDB provides the ability to materialize a
+ general result set in response to stored procedure execution.  In this case,
+ the stored procedure's Java method descriptor must specify a return type of
+ java.lang.Object for external use (although at any point in the devlopment
+ cycle, other, proprietary return types may accepted internally for engine
+ development purposes).
+
+ When HSQLDB detects that the runtime class of the resulting Object is
+ elligible, an automatic internal unwrapping is performed to correctly
+ expose the underlying result set to the client, whether local or remote. <p>
+
+ Additionally, HSQLDB automatically detects if java.sql.Connection is
+ the class of the first argument of any underlying Java method(s).  If so,
+ then the engine transparently supplies the internal Connection object
+ corresponding to the Session executing the call, adjusting the positions
+ of other arguments to suite the SQL context. <p>
+
+ The features above are not intended to be permanent.  Rather, the intention
+ is to offer more general and powerful mechanisms in a future release;
+ it is recommend to use them only as a temporary convenience. <p>
+
+ For instance, one might be well advised to future-proof by writing
+ HSQLDB-specific adapter methods that in turn call the real logic of an
+ underlying generalized JDBC stored procedure library. <p>
+
+ Here is a very simple example of an HSQLDB stored procedure generating a
+ user-defined result set:
+
+ <pre class="JavaCodeExample">
+ <span class="JavaKeyWord">package</span> mypackage;
+
+ <span class="JavaKeyWord">class</span> MyClass {
+
+      <span class="JavaKeyWord">public static</span> Object <b>mySp</b>(Connection conn) <span class="JavaKeyWord">throws</span> SQLException {
+          <span class="JavaKeyWord">return</span> conn.<b>createStatement</b>().<b>executeQuery</b>(<span class="JavaStringLiteral">"select * from my_table"</span>);
+      }
+ }
+ </pre>
+
+ Here is a refinement demonstrating no more than the bare essence of the idea
+ behind a more portable style:
+
+ <pre class="JavaCodeExample">
+ <span class="JavaKeyWord">package</span> mypackage;
+
+ <span class="JavaKeyWord">import</span> java.sql.ResultSet;
+ <span class="JavaKeyWord">import</span> java.sql.SQLException;
+
+ <span class="JavaKeyWord">class</span> MyLibraryClass {
+
+      <span class="JavaKeyWord">public static</span> ResultSet <b>mySp()</b> <span class="JavaKeyWord">throws</span> SQLException {
+          <span class="JavaKeyWord">return</span> ctx.<b>getConnection</b>().<b>createStatement</b>().<b>executeQuery</b>(<span class="JavaStringLiteral">"select * from my_table"</span>);
+      }
+ }
+
+ //--
+
+ <span class="JavaKeyWord">package</span> myadaptorpackage;
+
+ <span class="JavaKeyWord">import</span> java.sql.Connection;
+ <span class="JavaKeyWord">import</span> java.sql.SQLException;
+
+ <span class="JavaKeyWord">class</span> MyAdaptorClass {
+
+      <span class="JavaKeyWord">public static</span> Object <b>mySp</b>(Connection conn) <span class="JavaKeyWord">throws</span> SQLException {
+          MyLibraryClass.<b>getCtx()</b>.<b>setConnection</b>(conn);
+          <span class="JavaKeyWord">return</span> MyLibraryClass.<b>mySp</b>();
+      }
+ }
+ </pre>
+
+ In a future release, it is intended to provided some new features
+ that will support writing fairly portable JDBC-based stored procedure
+ code: <P>
+
+ <ul>
+  <li> Support for the <span class="JavaStringLiteral">"jdbc:default:connection"</span>
+       standard database connection url. <p>
+
+  <li> A well-defined specification of the behaviour of the HSQLDB execution
+       stack under stored procedure calls. <p>
+
+  <li> A well-defined, pure JDBC specification for generating multiple
+       results from HSQLDB stored procedures for client retrieval.
+ </ul>
+
+ (boucherb@users)
+ </div>
+ <!-- end Release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String)"><CODE>JDBCConnection.prepareCall(java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.sql.Statement"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#CLOSE_ALL_RESULTS" title="class or interface in java.sql">CLOSE_ALL_RESULTS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#CLOSE_CURRENT_RESULT" title="class or interface in java.sql">CLOSE_CURRENT_RESULT</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#EXECUTE_FAILED" title="class or interface in java.sql">EXECUTE_FAILED</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#KEEP_CURRENT_RESULT" title="class or interface in java.sql">KEEP_CURRENT_RESULT</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#NO_GENERATED_KEYS" title="class or interface in java.sql">NO_GENERATED_KEYS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#RETURN_GENERATED_KEYS" title="class or interface in java.sql">RETURN_GENERATED_KEYS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#SUCCESS_NO_INFO" title="class or interface in java.sql">SUCCESS_NO_INFO</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#JDBCCallableStatement(org.hsqldb.jdbc.JDBCConnection, java.lang.String, int, int, int)">JDBCCallableStatement</A></B>(<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;c,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                      int&nbsp;resultSetType,
+                      int&nbsp;resultSetConcurrency,
+                      int&nbsp;resultSetHoldability)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new JDBCCallableStatement with the specified connection and
+ result type.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#close()">close</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Does the specialized work required to free this object's resources and
+ that of it's parent classes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getArray(int)">getArray</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>ARRAY</code> parameter as an
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql"><CODE>Array</CODE></A> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getArray(java.lang.String)">getArray</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>ARRAY</code> parameter as an
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql"><CODE>Array</CODE></A> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBigDecimal(int)">getBigDecimal</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a
+ <code>java.math.BigDecimal</code> object with as many digits to the
+ right of the decimal point as the value contains.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBigDecimal(int, int)">getBigDecimal</A></B>(int&nbsp;parameterIndex,
+              int&nbsp;scale)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>use <code>getBigDecimal(int parameterIndex)</code>
+             or <code>getBigDecimal(String parameterName)</code></I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBigDecimal(java.lang.String)">getBigDecimal</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>NUMERIC</code> parameter as a
+ <code>java.math.BigDecimal</code> object with as many digits to the
+ right of the decimal point as the value contains.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBlob(int)">getBlob</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>BLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql"><CODE>Blob</CODE></A> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBlob(java.lang.String)">getBlob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>BLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql"><CODE>Blob</CODE></A> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBoolean(int)">getBoolean</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 modified:)
+ Retrieves the value of the designated JDBC <code>BIT</code>
+ or <code>BOOLEAN</code> parameter as a
+ <code>boolean</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBoolean(java.lang.String)">getBoolean</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 modified:)</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getByte(int)">getByte</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>TINYINT</code> parameter
+ as a <code>byte</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getByte(java.lang.String)">getByte</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBytes(int)">getBytes</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>BINARY</code> or
+ <code>VARBINARY</code> parameter as an array of <code>byte</code>
+ values in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBytes(java.lang.String)">getBytes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code>
+ parameter as an array of <code>byte</code> values in the Java
+ programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getCharacterStream(int)">getCharacterStream</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getCharacterStream(java.lang.String)">getCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getClob(int)">getClob</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>CLOB</code> parameter as a
+ <code>java.sql.Clob</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getClob(java.lang.String)">getClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>CLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql"><CODE>Clob</CODE></A> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(int)">getDate</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(int, java.util.Calendar)">getDate</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object, using
+ the given <code>Calendar</code> object
+ to construct the date.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(java.lang.String)">getDate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(java.lang.String, java.util.Calendar)">getDate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object, using
+ the given <code>Calendar</code> object
+ to construct the date.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;double</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDouble(int)">getDouble</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>DOUBLE</code> parameter as a <code>double</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;double</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDouble(java.lang.String)">getDouble</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;float</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getFloat(int)">getFloat</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>FLOAT</code> parameter
+ as a <code>float</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;float</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getFloat(java.lang.String)">getFloat</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getInt(int)">getInt</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>INTEGER</code> parameter
+ as an <code>int</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getInt(java.lang.String)">getInt</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getLong(int)">getLong</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>BIGINT</code> parameter
+ as a <code>long</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getLong(java.lang.String)">getLong</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getNCharacterStream(int)">getNCharacterStream</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getNCharacterStream(java.lang.String)">getNCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getNClob(int)">getNClob</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>NCLOB</code> parameter as a
+ <code>java.sql.NClob</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getNClob(java.lang.String)">getNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>NCLOB</code> parameter as a
+ <code>java.sql.NClob</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getNString(int)">getNString</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated <code>NCHAR</code>,
+ <code>NVARCHAR</code>
+ or <code>LONGNVARCHAR</code> parameter as
+ a <code>String</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getNString(java.lang.String)">getNString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated <code>NCHAR</code>,
+ <code>NVARCHAR</code>
+ or <code>LONGNVARCHAR</code> parameter as
+ a <code>String</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int)">getObject</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated parameter as an <code>Object</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int, java.util.Map)">getObject</A></B>(int&nbsp;parameterIndex,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object representing the value of OUT parameter
+ <code>parameterIndex</code> and uses <code>map</code> for the custom
+ mapping of the parameter value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(java.lang.String)">getObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a parameter as an <code>Object</code> in the Java
+ programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(java.lang.String, java.util.Map)">getObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getRef(int)">getRef</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>REF(&lt;structured-type&gt;)</code>
+ parameter as a <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql"><CODE>Ref</CODE></A> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getRef(java.lang.String)">getRef</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>REF(&lt;structured-type&gt;)</code>
+ parameter as a <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql"><CODE>Ref</CODE></A> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getRowId(int)">getRowId</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a
+ <code>java.sql.RowId</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getRowId(java.lang.String)">getRowId</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a
+ <code>java.sql.RowId</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;short</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getShort(int)">getShort</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>SMALLINT</code> parameter
+ as a <code>short</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;short</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getShort(java.lang.String)">getShort</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getSQLXML(int)">getSQLXML</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated <code>SQL XML</code> parameter as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getSQLXML(java.lang.String)">getSQLXML</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated <code>SQL XML</code> parameter as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getString(int)">getString</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>CHAR</code>,
+ <code>VARCHAR</code>, or <code>LONGVARCHAR</code> parameter as a
+ <code>String</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getString(java.lang.String)">getString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
+ or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
+ the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(int)">getTime</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(int, java.util.Calendar)">getTime</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object, using
+ the given <code>Calendar</code> object
+ to construct the time.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(java.lang.String)">getTime</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(java.lang.String, java.util.Calendar)">getTime</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object, using
+ the given <code>Calendar</code> object
+ to construct the time.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(int)">getTimestamp</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>TIMESTAMP</code>
+ parameter as a <code>java.sql.Timestamp</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(int, java.util.Calendar)">getTimestamp</A></B>(int&nbsp;parameterIndex,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object, using
+ the given <code>Calendar</code> object to construct
+ the <code>Timestamp</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(java.lang.String)">getTimestamp</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(java.lang.String, java.util.Calendar)">getTimestamp</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object, using
+ the given <code>Calendar</code> object to construct
+ the <code>Timestamp</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getURL(int)">getURL</A></B>(int&nbsp;parameterIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated JDBC <code>DATALINK</code> parameter as a
+ <code>java.net.URL</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getURL(java.lang.String)">getURL</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of a JDBC <code>DATALINK</code> parameter as a
+ <code>java.net.URL</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(int, int)">registerOutParameter</A></B>(int&nbsp;parameterIndex,
+                     int&nbsp;sqlType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Registers the OUT parameter in ordinal position
+ <code>parameterIndex</code> to the JDBC type
+ <code>sqlType</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(int, int, int)">registerOutParameter</A></B>(int&nbsp;parameterIndex,
+                     int&nbsp;sqlType,
+                     int&nbsp;scale)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Registers the parameter in ordinal position
+ <code>parameterIndex</code> to be of JDBC type
+ <code>sqlType</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(int, int, java.lang.String)">registerOutParameter</A></B>(int&nbsp;parameterIndex,
+                     int&nbsp;sqlType,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Registers the designated output parameter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(java.lang.String, int)">registerOutParameter</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     int&nbsp;sqlType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Registers the OUT parameter named
+ <code>parameterName</code> to the JDBC type
+ <code>sqlType</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(java.lang.String, int, int)">registerOutParameter</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     int&nbsp;sqlType,
+                     int&nbsp;scale)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Registers the parameter named
+ <code>parameterName</code> to be of JDBC type
+ <code>sqlType</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#registerOutParameter(java.lang.String, int, java.lang.String)">registerOutParameter</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     int&nbsp;sqlType,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Registers the designated output parameter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setAsciiStream(java.lang.String, java.io.InputStream)">setAsciiStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setAsciiStream(java.lang.String, java.io.InputStream, int)">setAsciiStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+               int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setAsciiStream(java.lang.String, java.io.InputStream, long)">setAsciiStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+               long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBigDecimal(java.lang.String, java.math.BigDecimal)">setBigDecimal</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given
+ <code>java.math.BigDecimal</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBinaryStream(java.lang.String, java.io.InputStream)">setBinaryStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBinaryStream(java.lang.String, java.io.InputStream, int)">setBinaryStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBinaryStream(java.lang.String, java.io.InputStream, long)">setBinaryStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBlob(java.lang.String, java.sql.Blob)">setBlob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Blob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBlob(java.lang.String, java.io.InputStream)">setBlob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>InputStream</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBlob(java.lang.String, java.io.InputStream, long)">setBlob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream,
+        long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>InputStream</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBoolean(java.lang.String, boolean)">setBoolean</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+           boolean&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>boolean</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setByte(java.lang.String, byte)">setByte</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        byte&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>byte</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBytes(java.lang.String, byte[])">setBytes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+         byte[]&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java array of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setCharacterStream(java.lang.String, java.io.Reader)">setCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>Reader</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setCharacterStream(java.lang.String, java.io.Reader, int)">setCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                   int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setCharacterStream(java.lang.String, java.io.Reader, long)">setCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                   long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setClob(java.lang.String, java.sql.Clob)">setClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setClob(java.lang.String, java.io.Reader)">setClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setClob(java.lang.String, java.io.Reader, long)">setClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+        long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDate(java.lang.String, java.sql.Date)">setDate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Date</code> value
+ (JDBC4 clarification:)</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDate(java.lang.String, java.sql.Date, java.util.Calendar)">setDate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Date</code> value,
+ using the given <code>Calendar</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDouble(java.lang.String, double)">setDouble</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+          double&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>double</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setFloat(java.lang.String, float)">setFloat</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+         float&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>float</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setInt(java.lang.String, int)">setInt</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+       int&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>int</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setLong(java.lang.String, long)">setLong</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        long&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>long</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNCharacterStream(java.lang.String, java.io.Reader)">setNCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNCharacterStream(java.lang.String, java.io.Reader, long)">setNCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;value,
+                    long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNClob(java.lang.String, java.sql.NClob)">setNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>java.sql.NClob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNClob(java.lang.String, java.io.Reader)">setNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNClob(java.lang.String, java.io.Reader, long)">setNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+         long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNString(java.lang.String, java.lang.String)">setNString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>String</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNull(java.lang.String, int)">setNull</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        int&nbsp;sqlType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to SQL <code>NULL</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNull(java.lang.String, int, java.lang.String)">setNull</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        int&nbsp;sqlType,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to SQL <code>NULL</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object)">setObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the designated parameter with the given object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object, int)">setObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+          int&nbsp;targetSqlType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the designated parameter with the given object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object, int, int)">setObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+          int&nbsp;targetSqlType,
+          int&nbsp;scale)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the designated parameter with the given object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setRowId(java.lang.String, java.sql.RowId)">setRowId</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.RowId</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setShort(java.lang.String, short)">setShort</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+         short&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>short</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setSQLXML(java.lang.String, java.sql.SQLXML)">setSQLXML</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>&nbsp;xmlObject)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.SQLXML</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setString(java.lang.String, java.lang.String)">setString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>String</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTime(java.lang.String, java.sql.Time)">setTime</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Time</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTime(java.lang.String, java.sql.Time, java.util.Calendar)">setTime</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Time</code> value,
+ using the given <code>Calendar</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTimestamp(java.lang.String, java.sql.Timestamp)">setTimestamp</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTimestamp(java.lang.String, java.sql.Timestamp, java.util.Calendar)">setTimestamp</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
+ using the given <code>Calendar</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setURL(java.lang.String, java.net.URL)">setURL</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A>&nbsp;val)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.net.URL</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#wasNull()">wasNull</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the last OUT parameter read had the value of
+ SQL <code>NULL</code>.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.hsqldb.jdbc.JDBCPreparedStatement"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#addBatch()">addBatch</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#addBatch(java.lang.String)">addBatch</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#cancel()">cancel</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#clearBatch()">clearBatch</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#clearParameters()">clearParameters</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#clearWarnings()">clearWarnings</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute()">execute</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String)">execute</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, int)">execute</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, int[])">execute</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, java.lang.String[])">execute</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeBatch()">executeBatch</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeQuery()">executeQuery</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeQuery(java.lang.String)">executeQuery</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate()">executeUpdate</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String)">executeUpdate</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, int)">executeUpdate</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, int[])">executeUpdate</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, java.lang.String[])">executeUpdate</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getConnection()">getConnection</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getFetchDirection()">getFetchDirection</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getFetchSize()">getFetchSize</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getGeneratedKeys()">getGeneratedKeys</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMaxFieldSize()">getMaxFieldSize</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMaxRows()">getMaxRows</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMetaData()">getMetaData</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMoreResults()">getMoreResults</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMoreResults(int)">getMoreResults</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getParameterMetaData()">getParameterMetaData</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getQueryTimeout()">getQueryTimeout</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSet()">getResultSet</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetConcurrency()">getResultSetConcurrency</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetHoldability()">getResultSetHoldability</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetType()">getResultSetType</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getUpdateCount()">getUpdateCount</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getWarnings()">getWarnings</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#isClosed()">isClosed</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#isPoolable()">isPoolable</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#isWrapperFor(java.lang.Class)">isWrapperFor</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setArray(int, java.sql.Array)">setArray</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream)">setAsciiStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream, int)">setAsciiStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream, long)">setAsciiStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBigDecimal(int, java.math.BigDecimal)">setBigDecimal</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream)">setBinaryStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream, int)">setBinaryStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream, long)">setBinaryStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.sql.Blob)">setBlob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.io.InputStream)">setBlob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.io.InputStream, long)">setBlob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBoolean(int, boolean)">setBoolean</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setByte(int, byte)">setByte</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBytes(int, byte[])">setBytes</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader)">setCharacterStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader, int)">setCharacterStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader, long)">setCharacterStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.sql.Clob)">setClob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.io.Reader)">setClob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.io.Reader, long)">setClob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setCursorName(java.lang.String)">setCursorName</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setDate(int, java.sql.Date)">setDate</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setDate(int, java.sql.Date, java.util.Calendar)">setDate</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setDouble(int, double)">setDouble</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setEscapeProcessing(boolean)">setEscapeProcessing</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setFetchDirection(int)">setFetchDirection</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setFetchSize(int)">setFetchSize</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setFloat(int, float)">setFloat</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setInt(int, int)">setInt</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setLong(int, long)">setLong</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setMaxFieldSize(int)">setMaxFieldSize</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setMaxRows(int)">setMaxRows</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNCharacterStream(int, java.io.Reader)">setNCharacterStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNCharacterStream(int, java.io.Reader, long)">setNCharacterStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.sql.NClob)">setNClob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.io.Reader)">setNClob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.io.Reader, long)">setNClob</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNString(int, java.lang.String)">setNString</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNull(int, int)">setNull</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNull(int, int, java.lang.String)">setNull</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object)">setObject</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object, int)">setObject</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object, int, int)">setObject</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setPoolable(boolean)">setPoolable</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setQueryTimeout(int)">setQueryTimeout</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setRef(int, java.sql.Ref)">setRef</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setRowId(int, java.sql.RowId)">setRowId</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setShort(int, short)">setShort</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setSQLXML(int, java.sql.SQLXML)">setSQLXML</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setString(int, java.lang.String)">setString</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setTime(int, java.sql.Time)">setTime</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setTime(int, java.sql.Time, java.util.Calendar)">setTime</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setTimestamp(int, java.sql.Timestamp)">setTimestamp</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setTimestamp(int, java.sql.Timestamp, java.util.Calendar)">setTimestamp</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setUnicodeStream(int, java.io.InputStream, int)">setUnicodeStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setURL(int, java.net.URL)">setURL</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#toString()">toString</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#unwrap(java.lang.Class)">unwrap</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.sql.PreparedStatement"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#addBatch()" title="class or interface in java.sql">addBatch</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#clearParameters()" title="class or interface in java.sql">clearParameters</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#execute()" title="class or interface in java.sql">execute</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#executeQuery()" title="class or interface in java.sql">executeQuery</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#executeUpdate()" title="class or interface in java.sql">executeUpdate</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#getMetaData()" title="class or interface in java.sql">getMetaData</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#getParameterMetaData()" title="class or interface in java.sql">getParameterMetaData</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setArray(int, java.sql.Array)" title="class or interface in java.sql">setArray</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setAsciiStream(int, java.io.InputStream)" title="class or interface in java.sql">setAsciiStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setAsciiStream(int, java.io.InputStream, int)" title="class or interface in java.sql">setAsciiStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setAsciiStream(int, java.io.InputStream, long)" title="class or interface in java.sql">setAsciiStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBigDecimal(int, java.math.BigDecimal)" title="class or interface in java.sql">setBigDecimal</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBinaryStream(int, java.io.InputStream)" title="class or interface in java.sql">setBinaryStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBinaryStream(int, java.io.InputStream, int)" title="class or interface in java.sql">setBinaryStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBinaryStream(int, java.io.InputStream, long)" title="class or interface in java.sql">setBinaryStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBlob(int, java.sql.Blob)" title="class or interface in java.sql">setBlob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBlob(int, java.io.InputStream)" title="class or interface in java.sql">setBlob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBlob(int, java.io.InputStream, long)" title="class or interface in java.sql">setBlob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBoolean(int, boolean)" title="class or interface in java.sql">setBoolean</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setByte(int, byte)" title="class or interface in java.sql">setByte</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBytes(int, byte[])" title="class or interface in java.sql">setBytes</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setCharacterStream(int, java.io.Reader)" title="class or interface in java.sql">setCharacterStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setCharacterStream(int, java.io.Reader, int)" title="class or interface in java.sql">setCharacterStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setCharacterStream(int, java.io.Reader, long)" title="class or interface in java.sql">setCharacterStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setClob(int, java.sql.Clob)" title="class or interface in java.sql">setClob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setClob(int, java.io.Reader)" title="class or interface in java.sql">setClob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setClob(int, java.io.Reader, long)" title="class or interface in java.sql">setClob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setDate(int, java.sql.Date)" title="class or interface in java.sql">setDate</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setDate(int, java.sql.Date, java.util.Calendar)" title="class or interface in java.sql">setDate</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setDouble(int, double)" title="class or interface in java.sql">setDouble</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setFloat(int, float)" title="class or interface in java.sql">setFloat</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setInt(int, int)" title="class or interface in java.sql">setInt</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setLong(int, long)" title="class or interface in java.sql">setLong</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNCharacterStream(int, java.io.Reader)" title="class or interface in java.sql">setNCharacterStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNCharacterStream(int, java.io.Reader, long)" title="class or interface in java.sql">setNCharacterStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNClob(int, java.sql.NClob)" title="class or interface in java.sql">setNClob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNClob(int, java.io.Reader)" title="class or interface in java.sql">setNClob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNClob(int, java.io.Reader, long)" title="class or interface in java.sql">setNClob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNString(int, java.lang.String)" title="class or interface in java.sql">setNString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNull(int, int)" title="class or interface in java.sql">setNull</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNull(int, int, java.lang.String)" title="class or interface in java.sql">setNull</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setObject(int, java.lang.Object)" title="class or interface in java.sql">setObject</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setObject(int, java.lang.Object, int)" title="class or interface in java.sql">setObject</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setObject(int, java.lang.Object, int, int)" title="class or interface in java.sql">setObject</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setRef(int, java.sql.Ref)" title="class or interface in java.sql">setRef</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setRowId(int, java.sql.RowId)" title="class or interface in java.sql">setRowId</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setShort(int, short)" title="class or interface in java.sql">setShort</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setSQLXML(int, java.sql.SQLXML)" title="class or interface in java.sql">setSQLXML</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setString(int, java.lang.String)" title="class or interface in java.sql">setString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setTime(int, java.sql.Time)" title="class or interface in java.sql">setTime</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setTime(int, java.sql.Time, java.util.Calendar)" title="class or interface in java.sql">setTime</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setTimestamp(int, java.sql.Timestamp)" title="class or interface in java.sql">setTimestamp</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setTimestamp(int, java.sql.Timestamp, java.util.Calendar)" title="class or interface in java.sql">setTimestamp</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setUnicodeStream(int, java.io.InputStream, int)" title="class or interface in java.sql">setUnicodeStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setURL(int, java.net.URL)" title="class or interface in java.sql">setURL</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.sql.Statement"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#addBatch(java.lang.String)" title="class or interface in java.sql">addBatch</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#cancel()" title="class or interface in java.sql">cancel</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#clearBatch()" title="class or interface in java.sql">clearBatch</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#clearWarnings()" title="class or interface in java.sql">clearWarnings</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String)" title="class or interface in java.sql">execute</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, int)" title="class or interface in java.sql">execute</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, int[])" title="class or interface in java.sql">execute</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, java.lang.String[])" title="class or interface in java.sql">execute</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeBatch()" title="class or interface in java.sql">executeBatch</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeQuery(java.lang.String)" title="class or interface in java.sql">executeQuery</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String)" title="class or interface in java.sql">executeUpdate</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, int)" title="class or interface in java.sql">executeUpdate</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, int[])" title="class or interface in java.sql">executeUpdate</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, java.lang.String[])" title="class or interface in java.sql">executeUpdate</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getConnection()" title="class or interface in java.sql">getConnection</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getFetchDirection()" title="class or interface in java.sql">getFetchDirection</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getFetchSize()" title="class or interface in java.sql">getFetchSize</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getGeneratedKeys()" title="class or interface in java.sql">getGeneratedKeys</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMaxFieldSize()" title="class or interface in java.sql">getMaxFieldSize</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMaxRows()" title="class or interface in java.sql">getMaxRows</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMoreResults()" title="class or interface in java.sql">getMoreResults</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMoreResults(int)" title="class or interface in java.sql">getMoreResults</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getQueryTimeout()" title="class or interface in java.sql">getQueryTimeout</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSet()" title="class or interface in java.sql">getResultSet</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetConcurrency()" title="class or interface in java.sql">getResultSetConcurrency</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetHoldability()" title="class or interface in java.sql">getResultSetHoldability</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetType()" title="class or interface in java.sql">getResultSetType</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getUpdateCount()" title="class or interface in java.sql">getUpdateCount</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getWarnings()" title="class or interface in java.sql">getWarnings</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#isClosed()" title="class or interface in java.sql">isClosed</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#isPoolable()" title="class or interface in java.sql">isPoolable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setCursorName(java.lang.String)" title="class or interface in java.sql">setCursorName</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setEscapeProcessing(boolean)" title="class or interface in java.sql">setEscapeProcessing</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setFetchDirection(int)" title="class or interface in java.sql">setFetchDirection</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setFetchSize(int)" title="class or interface in java.sql">setFetchSize</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setMaxFieldSize(int)" title="class or interface in java.sql">setMaxFieldSize</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setMaxRows(int)" title="class or interface in java.sql">setMaxRows</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setPoolable(boolean)" title="class or interface in java.sql">setPoolable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setQueryTimeout(int)" title="class or interface in java.sql">setQueryTimeout</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.sql.Wrapper"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCCallableStatement(org.hsqldb.jdbc.JDBCConnection, java.lang.String, int, int, int)"><!-- --></A><H3>
+JDBCCallableStatement</H3>
+<PRE>
+public <B>JDBCCallableStatement</B>(<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;c,
+                             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                             int&nbsp;resultSetType,
+                             int&nbsp;resultSetConcurrency,
+                             int&nbsp;resultSetHoldability)
+                      throws org.hsqldb.HsqlException,
+                             <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new JDBCCallableStatement with the specified connection and
+ result type.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>c</CODE> - the connection on which this statement will execute<DD><CODE>sql</CODE> - the SQL statement this object represents<DD><CODE>resultSetType</CODE> - the type of result this statement will produce
+<DT><B>Throws:</B>
+<DD><CODE>org.hsqldb.HsqlException</CODE> - if the statement is not accepted by the database
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if preprocessing by driver fails</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="registerOutParameter(int, int)"><!-- --></A><H3>
+registerOutParameter</H3>
+<PRE>
+public void <B>registerOutParameter</B>(int&nbsp;parameterIndex,
+                                 int&nbsp;sqlType)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Registers the OUT parameter in ordinal position
+ <code>parameterIndex</code> to the JDBC type
+ <code>sqlType</code>.  All OUT parameters must be registered
+ before a stored procedure is executed.
+ <p>
+ The JDBC type specified by <code>sqlType</code> for an OUT
+ parameter determines the Java type that must be used
+ in the <code>get</code> method to read the value of that parameter.
+ <p>
+ If the JDBC type expected to be returned to this output parameter
+ is specific to this particular database, <code>sqlType</code>
+ should be <code>java.sql.Types.OTHER</code>.  The method
+ <A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int)"><CODE>getObject(int)</CODE></A> retrieves the value.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#registerOutParameter(int, int)" title="class or interface in java.sql">registerOutParameter</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on<DD><CODE>sqlType</CODE> - the JDBC type code defined by <code>java.sql.Types</code>.
+        If the parameter is of JDBC type <code>NUMERIC</code>
+        or <code>DECIMAL</code>, the version of
+        <code>registerOutParameter</code> that accepts a scale value
+        should be used.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>sqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="registerOutParameter(int, int, int)"><!-- --></A><H3>
+registerOutParameter</H3>
+<PRE>
+public void <B>registerOutParameter</B>(int&nbsp;parameterIndex,
+                                 int&nbsp;sqlType,
+                                 int&nbsp;scale)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Registers the parameter in ordinal position
+ <code>parameterIndex</code> to be of JDBC type
+ <code>sqlType</code>.  (JDBC4 clarification:) All OUT parameters must be registered
+ before a stored procedure is executed.
+ <p>
+ The JDBC type specified by <code>sqlType</code> for an OUT
+ parameter determines the Java type that must be used
+ in the <code>get</code> method to read the value of that parameter.
+ <p>
+ This version of <code>registerOutParameter</code> should be
+ used when the parameter is of JDBC type <code>NUMERIC</code>
+ or <code>DECIMAL</code>.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#registerOutParameter(int, int, int)" title="class or interface in java.sql">registerOutParameter</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on<DD><CODE>sqlType</CODE> - the SQL type code defined by <code>java.sql.Types</code>.<DD><CODE>scale</CODE> - the desired number of digits to the right of the
+ decimal point.  It must be greater than or equal to zero.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>sqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="wasNull()"><!-- --></A><H3>
+wasNull</H3>
+<PRE>
+public boolean <B>wasNull</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves whether the last OUT parameter read had the value of
+ SQL <code>NULL</code>.  Note that this method should be called only after
+ calling a getter method; otherwise, there is no value to use in
+ determining whether it is <code>null</code> or not.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#wasNull()" title="class or interface in java.sql">wasNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the last parameter read was SQL
+ <code>NULL</code>; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getString(int)"><!-- --></A><H3>
+getString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getString</B>(int&nbsp;parameterIndex)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>CHAR</code>,
+ <code>VARCHAR</code>, or <code>LONGVARCHAR</code> parameter as a
+ <code>String</code> in the Java programming language.
+ <p>
+ For the fixed-length type JDBC <code>CHAR</code>,
+ the <code>String</code> object
+ returned has exactly the same value the (JDBC4 clarification:) SQL
+ <code>CHAR</code> value had in the
+ database, including any padding added by the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getString(int)" title="class or interface in java.sql">getString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on
+<DT><B>Returns:</B><DD>the parameter value. If the value is SQL <code>NULL</code>,
+         the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setString(java.lang.String, java.lang.String)"><CODE>setString(java.lang.String, java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBoolean(int)"><!-- --></A><H3>
+getBoolean</H3>
+<PRE>
+public boolean <B>getBoolean</B>(int&nbsp;parameterIndex)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ (JDBC4 modified:)
+ Retrieves the value of the designated JDBC <code>BIT</code>
+ or <code>BOOLEAN</code> parameter as a
+ <code>boolean</code> in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBoolean(int)" title="class or interface in java.sql">getBoolean</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>,
+         the result is <code>false</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBoolean(java.lang.String, boolean)"><CODE>setBoolean(java.lang.String, boolean)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getByte(int)"><!-- --></A><H3>
+getByte</H3>
+<PRE>
+public byte <B>getByte</B>(int&nbsp;parameterIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>TINYINT</code> parameter
+ as a <code>byte</code> in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getByte(int)" title="class or interface in java.sql">getByte</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setByte(java.lang.String, byte)"><CODE>setByte(java.lang.String, byte)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getShort(int)"><!-- --></A><H3>
+getShort</H3>
+<PRE>
+public short <B>getShort</B>(int&nbsp;parameterIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>SMALLINT</code> parameter
+ as a <code>short</code> in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getShort(int)" title="class or interface in java.sql">getShort</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setShort(java.lang.String, short)"><CODE>setShort(java.lang.String, short)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getInt(int)"><!-- --></A><H3>
+getInt</H3>
+<PRE>
+public int <B>getInt</B>(int&nbsp;parameterIndex)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>INTEGER</code> parameter
+ as an <code>int</code> in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getInt(int)" title="class or interface in java.sql">getInt</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setInt(java.lang.String, int)"><CODE>setInt(java.lang.String, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLong(int)"><!-- --></A><H3>
+getLong</H3>
+<PRE>
+public long <B>getLong</B>(int&nbsp;parameterIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>BIGINT</code> parameter
+ as a <code>long</code> in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getLong(int)" title="class or interface in java.sql">getLong</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setLong(java.lang.String, long)"><CODE>setLong(java.lang.String, long)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFloat(int)"><!-- --></A><H3>
+getFloat</H3>
+<PRE>
+public float <B>getFloat</B>(int&nbsp;parameterIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>FLOAT</code> parameter
+ as a <code>float</code> in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getFloat(int)" title="class or interface in java.sql">getFloat</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setFloat(java.lang.String, float)"><CODE>setFloat(java.lang.String, float)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDouble(int)"><!-- --></A><H3>
+getDouble</H3>
+<PRE>
+public double <B>getDouble</B>(int&nbsp;parameterIndex)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>DOUBLE</code> parameter as a <code>double</code>
+ in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getDouble(int)" title="class or interface in java.sql">getDouble</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDouble(java.lang.String, double)"><CODE>setDouble(java.lang.String, double)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBigDecimal(int, int)"><!-- --></A><H3>
+getBigDecimal</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A> <B>getBigDecimal</B>(int&nbsp;parameterIndex,
+                                int&nbsp;scale)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>use <code>getBigDecimal(int parameterIndex)</code>
+             or <code>getBigDecimal(String parameterName)</code></I>
+<P>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a
+ <code>java.math.BigDecimal</code> object with <i>scale</i> digits to
+ the right of the decimal point.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBigDecimal(int, int)" title="class or interface in java.sql">getBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on<DD><CODE>scale</CODE> - the number of digits to the right of the decimal point
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBigDecimal(java.lang.String, java.math.BigDecimal)"><CODE>setBigDecimal(java.lang.String, java.math.BigDecimal)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBytes(int)"><!-- --></A><H3>
+getBytes</H3>
+<PRE>
+public byte[] <B>getBytes</B>(int&nbsp;parameterIndex)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>BINARY</code> or
+ <code>VARBINARY</code> parameter as an array of <code>byte</code>
+ values in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBytes(int)" title="class or interface in java.sql">getBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBytes(java.lang.String, byte[])"><CODE>setBytes(java.lang.String, byte[])</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDate(int)"><!-- --></A><H3>
+getDate</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A> <B>getDate</B>(int&nbsp;parameterIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getDate(int)" title="class or interface in java.sql">getDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDate(java.lang.String, java.sql.Date)"><CODE>setDate(java.lang.String, java.sql.Date)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTime(int)"><!-- --></A><H3>
+getTime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A> <B>getTime</B>(int&nbsp;parameterIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getTime(int)" title="class or interface in java.sql">getTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTime(java.lang.String, java.sql.Time)"><CODE>setTime(java.lang.String, java.sql.Time)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimestamp(int)"><!-- --></A><H3>
+getTimestamp</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A> <B>getTimestamp</B>(int&nbsp;parameterIndex)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>TIMESTAMP</code>
+ parameter as a <code>java.sql.Timestamp</code> object. <p>
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getTimestamp(int)" title="class or interface in java.sql">getTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTimestamp(java.lang.String, java.sql.Timestamp)"><CODE>setTimestamp(java.lang.String, java.sql.Timestamp)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObject(int)"><!-- --></A><H3>
+getObject</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObject</B>(int&nbsp;parameterIndex)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated parameter as an <code>Object</code>
+ in the Java programming language. If the value is an SQL <code>NULL</code>,
+ the driver returns a Java <code>null</code>.
+ <p>
+ This method returns a Java object whose type corresponds to the JDBC
+ type that was registered for this parameter using the method
+ <code>registerOutParameter</code>.  By registering the target JDBC
+ type as <code>java.sql.Types.OTHER</code>, this method can be used
+ to read database-specific abstract data types.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getObject(int)" title="class or interface in java.sql">getObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+        and so on
+<DT><B>Returns:</B><DD>A <code>java.lang.Object</code> holding the OUT parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object, int, int)"><CODE>setObject(java.lang.String, java.lang.Object, int, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBigDecimal(int)"><!-- --></A><H3>
+getBigDecimal</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A> <B>getBigDecimal</B>(int&nbsp;parameterIndex)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a
+ <code>java.math.BigDecimal</code> object with as many digits to the
+ right of the decimal point as the value contains.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBigDecimal(int)" title="class or interface in java.sql">getBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on
+<DT><B>Returns:</B><DD>the parameter value in full precision.  If the value is
+ SQL <code>NULL</code>, the result is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCParameterMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBigDecimal(java.lang.String, java.math.BigDecimal)"><CODE>setBigDecimal(java.lang.String, java.math.BigDecimal)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObject(int, java.util.Map)"><!-- --></A><H3>
+getObject</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObject</B>(int&nbsp;parameterIndex,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Returns an object representing the value of OUT parameter
+ <code>parameterIndex</code> and uses <code>map</code> for the custom
+ mapping of the parameter value.
+ <p>
+ This method returns a Java object whose type corresponds to the
+ JDBC type that was registered for this parameter using the method
+ <code>registerOutParameter</code>.  By registering the target
+ JDBC type as <code>java.sql.Types.OTHER</code>, this method can
+ be used to read database-specific abstract data types.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getObject(int, java.util.Map)" title="class or interface in java.sql">getObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, and so on<DD><CODE>map</CODE> - the mapping from SQL type names to Java classes
+<DT><B>Returns:</B><DD>a <code>java.lang.Object</code> holding the OUT parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCParameterMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object, int, int)"><CODE>setObject(java.lang.String, java.lang.Object, int, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRef(int)"><!-- --></A><H3>
+getRef</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A> <B>getRef</B>(int&nbsp;parameterIndex)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>REF(&lt;structured-type&gt;)</code>
+ parameter as a <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql"><CODE>Ref</CODE></A> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getRef(int)" title="class or interface in java.sql">getRef</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on
+<DT><B>Returns:</B><DD>the parameter value as a <code>Ref</code> object in the
+ Java programming language.  If the value was SQL <code>NULL</code>, the value
+ <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBlob(int)"><!-- --></A><H3>
+getBlob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A> <B>getBlob</B>(int&nbsp;parameterIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>BLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql"><CODE>Blob</CODE></A> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBlob(int)" title="class or interface in java.sql">getBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on
+<DT><B>Returns:</B><DD>the parameter value as a <code>Blob</code> object in the
+ Java programming language.  If the value was SQL <code>NULL</code>, the value
+ <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getClob(int)"><!-- --></A><H3>
+getClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A> <B>getClob</B>(int&nbsp;parameterIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>CLOB</code> parameter as a
+ <code>java.sql.Clob</code> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getClob(int)" title="class or interface in java.sql">getClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, and
+ so on
+<DT><B>Returns:</B><DD>the parameter value as a <code>Clob</code> object in the
+ Java programming language.  If the value was SQL <code>NULL</code>, the
+ value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArray(int)"><!-- --></A><H3>
+getArray</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A> <B>getArray</B>(int&nbsp;parameterIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>ARRAY</code> parameter as an
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql"><CODE>Array</CODE></A> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getArray(int)" title="class or interface in java.sql">getArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, and
+ so on
+<DT><B>Returns:</B><DD>the parameter value as an <code>Array</code> object in
+ the Java programming language.  If the value was SQL <code>NULL</code>, the
+ value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDate(int, java.util.Calendar)"><!-- --></A><H3>
+getDate</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A> <B>getDate</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object, using
+ the given <code>Calendar</code> object
+ to construct the date.
+ With a <code>Calendar</code> object, the driver
+ can calculate the date taking into account a custom timezone and locale.
+ If no <code>Calendar</code> object is specified, the driver uses the
+ default timezone and locale.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getDate(int, java.util.Calendar)" title="class or interface in java.sql">getDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the date
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+      JDBCParameterMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDate(java.lang.String, java.sql.Date)"><CODE>setDate(java.lang.String, java.sql.Date)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTime(int, java.util.Calendar)"><!-- --></A><H3>
+getTime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A> <B>getTime</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object, using
+ the given <code>Calendar</code> object
+ to construct the time.
+ With a <code>Calendar</code> object, the driver
+ can calculate the time taking into account a custom timezone and locale.
+ If no <code>Calendar</code> object is specified, the driver uses the
+ default timezone and locale.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getTime(int, java.util.Calendar)" title="class or interface in java.sql">getTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the time
+<DT><B>Returns:</B><DD>the parameter value; if the value is SQL <code>NULL</code>, the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCParameterMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTime(java.lang.String, java.sql.Time)"><CODE>setTime(java.lang.String, java.sql.Time)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimestamp(int, java.util.Calendar)"><!-- --></A><H3>
+getTimestamp</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A> <B>getTimestamp</B>(int&nbsp;parameterIndex,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object, using
+ the given <code>Calendar</code> object to construct
+ the <code>Timestamp</code> object.
+ With a <code>Calendar</code> object, the driver
+ can calculate the timestamp taking into account a custom timezone and locale.
+ If no <code>Calendar</code> object is specified, the driver uses the
+ default timezone and locale.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getTimestamp(int, java.util.Calendar)" title="class or interface in java.sql">getTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,
+ and so on<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the timestamp
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCParameterMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTimestamp(java.lang.String, java.sql.Timestamp)"><CODE>setTimestamp(java.lang.String, java.sql.Timestamp)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="registerOutParameter(int, int, java.lang.String)"><!-- --></A><H3>
+registerOutParameter</H3>
+<PRE>
+public void <B>registerOutParameter</B>(int&nbsp;parameterIndex,
+                                 int&nbsp;sqlType,
+                                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Registers the designated output parameter.
+ This version of
+ the method <code>registerOutParameter</code>
+ should be used for a user-defined or <code>REF</code> output parameter.  Examples
+ of user-defined types include: <code>STRUCT</code>, <code>DISTINCT</code>,
+ <code>JAVA_OBJECT</code>, and named array types.
+ <p>
+ All OUT parameters must be registered
+ before a stored procedure is executed.
+ <p>  For a user-defined parameter, the fully-qualified SQL
+ type name of the parameter should also be given, while a <code>REF</code>
+ parameter requires that the fully-qualified type name of the
+ referenced type be given.  A JDBC driver that does not need the
+ type code and type name information may ignore it.   To be portable,
+ however, applications should always provide these values for
+ user-defined and <code>REF</code> parameters.
+
+ Although it is intended for user-defined and <code>REF</code> parameters,
+ this method may be used to register a parameter of any JDBC type.
+ If the parameter does not have a user-defined or <code>REF</code> type, the
+ <i>typeName</i> parameter is ignored.
+
+ <P><B>Note:</B> When reading the value of an out parameter, you
+ must use the getter method whose Java type corresponds to the
+ parameter's registered SQL type.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#registerOutParameter(int, int, java.lang.String)" title="class or interface in java.sql">registerOutParameter</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,...<DD><CODE>sqlType</CODE> - a value from <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A><DD><CODE>typeName</CODE> - the fully-qualified name of an SQL structured type
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>sqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCParameterMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="registerOutParameter(java.lang.String, int)"><!-- --></A><H3>
+registerOutParameter</H3>
+<PRE>
+public void <B>registerOutParameter</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                                 int&nbsp;sqlType)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Registers the OUT parameter named
+ <code>parameterName</code> to the JDBC type
+ <code>sqlType</code>.  All OUT parameters must be registered
+ before a stored procedure is executed.
+ <p>
+ The JDBC type specified by <code>sqlType</code> for an OUT
+ parameter determines the Java type that must be used
+ in the <code>get</code> method to read the value of that parameter.
+ <p>
+ If the JDBC type expected to be returned to this output parameter
+ is specific to this particular database, <code>sqlType</code>
+ should be <code>java.sql.Types.OTHER</code>.  The method
+ <A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int)"><CODE>getObject(int)</CODE></A> retrieves the value.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#registerOutParameter(java.lang.String, int)" title="class or interface in java.sql">registerOutParameter</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>sqlType</CODE> - the JDBC type code defined by <code>java.sql.Types</code>.
+ If the parameter is of JDBC type <code>NUMERIC</code>
+ or <code>DECIMAL</code>, the version of
+ <code>registerOutParameter</code> that accepts a scale value
+ should be used.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>sqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type or if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQL 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="registerOutParameter(java.lang.String, int, int)"><!-- --></A><H3>
+registerOutParameter</H3>
+<PRE>
+public void <B>registerOutParameter</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                                 int&nbsp;sqlType,
+                                 int&nbsp;scale)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Registers the parameter named
+ <code>parameterName</code> to be of JDBC type
+ <code>sqlType</code>.  (JDBC4 clarification:) All OUT parameters must be registered
+ before a stored procedure is executed.
+ <p>
+ The JDBC type specified by <code>sqlType</code> for an OUT
+ parameter determines the Java type that must be used
+ in the <code>get</code> method to read the value of that parameter.
+ <p>
+ This version of <code>registerOutParameter</code> should be
+ used when the parameter is of JDBC type <code>NUMERIC</code>
+ or <code>DECIMAL</code>.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#registerOutParameter(java.lang.String, int, int)" title="class or interface in java.sql">registerOutParameter</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>sqlType</CODE> - SQL type code defined by <code>java.sql.Types</code>.<DD><CODE>scale</CODE> - the desired number of digits to the right of the
+ decimal point.  It must be greater than or equal to zero.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>sqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type or if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="registerOutParameter(java.lang.String, int, java.lang.String)"><!-- --></A><H3>
+registerOutParameter</H3>
+<PRE>
+public void <B>registerOutParameter</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                                 int&nbsp;sqlType,
+                                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Registers the designated output parameter.  This version of
+ the method <code>registerOutParameter</code>
+ should be used for a user-named or REF output parameter.  Examples
+ of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and
+ named array types.
+ <p>
+ (JDBC4 clarification:)<p>
+ All OUT parameters must be registered
+ before a stored procedure is executed.
+ <p>
+ For a user-named parameter the fully-qualified SQL
+ type name of the parameter should also be given, while a REF
+ parameter requires that the fully-qualified type name of the
+ referenced type be given.  A JDBC driver that does not need the
+ type code and type name information may ignore it.   To be portable,
+ however, applications should always provide these values for
+ user-named and REF parameters.
+
+ Although it is intended for user-named and REF parameters,
+ this method may be used to register a parameter of any JDBC type.
+ If the parameter does not have a user-named or REF type, the
+ typeName parameter is ignored.
+
+ <P><B>Note:</B> When reading the value of an out parameter, you
+ must use the <code>getXXX</code> method whose Java type XXX corresponds to the
+ parameter's registered SQL type.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#registerOutParameter(java.lang.String, int, java.lang.String)" title="class or interface in java.sql">registerOutParameter</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>sqlType</CODE> - a value from <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A><DD><CODE>typeName</CODE> - the fully-qualified name of an SQL structured type
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>sqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type or if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQL 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getURL(int)"><!-- --></A><H3>
+getURL</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A> <B>getURL</B>(int&nbsp;parameterIndex)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>DATALINK</code> parameter as a
+ <code>java.net.URL</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getURL(int)" title="class or interface in java.sql">getURL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,...
+<DT><B>Returns:</B><DD>a <code>java.net.URL</code> object that represents the
+         JDBC <code>DATALINK</code> value used as the designated
+         parameter
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>CallableStatement</code>,
+            or if the URL being returned is
+            not a valid URL on the Java platform
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setURL(java.lang.String, java.net.URL)"><CODE>setURL(java.lang.String, java.net.URL)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setURL(java.lang.String, java.net.URL)"><!-- --></A><H3>
+setURL</H3>
+<PRE>
+public void <B>setURL</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A>&nbsp;val)
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>java.net.URL</code> object.
+ The driver converts this to an SQL <code>DATALINK</code> value when
+ it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setURL(java.lang.String, java.net.URL)" title="class or interface in java.sql">setURL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>val</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>CallableStatement</code>,
+            or if a URL is malformed
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getURL(int)"><CODE>getURL(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNull(java.lang.String, int)"><!-- --></A><H3>
+setNull</H3>
+<PRE>
+public void <B>setNull</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    int&nbsp;sqlType)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to SQL <code>NULL</code>.
+
+ <P><B>Note:</B> You must specify the parameter's SQL type.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setNull(java.lang.String, int)" title="class or interface in java.sql">setNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>sqlType</CODE> - the SQL type code defined in <code>java.sql.Types</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBoolean(java.lang.String, boolean)"><!-- --></A><H3>
+setBoolean</H3>
+<PRE>
+public void <B>setBoolean</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                       boolean&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java <code>boolean</code> value.
+
+ <p>(JDBC4 clarification:)<p>
+
+ The driver converts this
+ to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBoolean(java.lang.String, boolean)" title="class or interface in java.sql">setBoolean</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBoolean(int)"><CODE>getBoolean(int)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBoolean(int)"><CODE>getBoolean(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setByte(java.lang.String, byte)"><!-- --></A><H3>
+setByte</H3>
+<PRE>
+public void <B>setByte</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    byte&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java <code>byte</code> value.
+ The driver converts this
+ to an SQL <code>TINYINT</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setByte(java.lang.String, byte)" title="class or interface in java.sql">setByte</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getByte(int)"><CODE>getByte(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setShort(java.lang.String, short)"><!-- --></A><H3>
+setShort</H3>
+<PRE>
+public void <B>setShort</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     short&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java <code>short</code> value.
+ The driver converts this
+ to an SQL <code>SMALLINT</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setShort(java.lang.String, short)" title="class or interface in java.sql">setShort</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getShort(int)"><CODE>getShort(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInt(java.lang.String, int)"><!-- --></A><H3>
+setInt</H3>
+<PRE>
+public void <B>setInt</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                   int&nbsp;x)
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java <code>int</code> value.
+ The driver converts this
+ to an SQL <code>INTEGER</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setInt(java.lang.String, int)" title="class or interface in java.sql">setInt</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getInt(int)"><CODE>getInt(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLong(java.lang.String, long)"><!-- --></A><H3>
+setLong</H3>
+<PRE>
+public void <B>setLong</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    long&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java <code>long</code> value.
+ The driver converts this
+ to an SQL <code>BIGINT</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setLong(java.lang.String, long)" title="class or interface in java.sql">setLong</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getLong(int)"><CODE>getLong(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFloat(java.lang.String, float)"><!-- --></A><H3>
+setFloat</H3>
+<PRE>
+public void <B>setFloat</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     float&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java <code>float</code> value.
+ The driver converts this
+ to an SQL <code>FLOAT</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setFloat(java.lang.String, float)" title="class or interface in java.sql">setFloat</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getFloat(int)"><CODE>getFloat(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDouble(java.lang.String, double)"><!-- --></A><H3>
+setDouble</H3>
+<PRE>
+public void <B>setDouble</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                      double&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java <code>double</code> value.
+ The driver converts this
+ to an SQL <code>DOUBLE</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setDouble(java.lang.String, double)" title="class or interface in java.sql">setDouble</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDouble(int)"><CODE>getDouble(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBigDecimal(java.lang.String, java.math.BigDecimal)"><!-- --></A><H3>
+setBigDecimal</H3>
+<PRE>
+public void <B>setBigDecimal</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A>&nbsp;x)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given
+ <code>java.math.BigDecimal</code> value.
+ The driver converts this to an SQL <code>NUMERIC</code> value when
+ it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBigDecimal(java.lang.String, java.math.BigDecimal)" title="class or interface in java.sql">setBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBigDecimal(int, int)"><CODE>getBigDecimal(int, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setString(java.lang.String, java.lang.String)"><!-- --></A><H3>
+setString</H3>
+<PRE>
+public void <B>setString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java <code>String</code> value.
+ The driver converts this
+ to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
+ (depending on the argument's
+ size relative to the driver's limits on <code>VARCHAR</code> values)
+ when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setString(java.lang.String, java.lang.String)" title="class or interface in java.sql">setString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getString(int)"><CODE>getString(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBytes(java.lang.String, byte[])"><!-- --></A><H3>
+setBytes</H3>
+<PRE>
+public void <B>setBytes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     byte[]&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given Java array of bytes.
+ The driver converts this to an SQL <code>VARBINARY</code> or
+ <code>LONGVARBINARY</code> (depending on the argument's size relative
+ to the driver's limits on <code>VARBINARY</code> values) when it sends
+ it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBytes(java.lang.String, byte[])" title="class or interface in java.sql">setBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getBytes(int)"><CODE>getBytes(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDate(java.lang.String, java.sql.Date)"><!-- --></A><H3>
+setDate</H3>
+<PRE>
+public void <B>setDate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>java.sql.Date</code> value
+ (JDBC4 clarification:)<p>
+ using the default time zone of the virtual machine that is running
+ the application.
+ The driver converts this
+ to an SQL <code>DATE</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setDate(java.lang.String, java.sql.Date)" title="class or interface in java.sql">setDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(int)"><CODE>getDate(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTime(java.lang.String, java.sql.Time)"><!-- --></A><H3>
+setTime</H3>
+<PRE>
+public void <B>setTime</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>java.sql.Time</code> value.
+ The driver converts this
+ to an SQL <code>TIME</code> value when it sends it to the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setTime(java.lang.String, java.sql.Time)" title="class or interface in java.sql">setTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(int)"><CODE>getTime(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTimestamp(java.lang.String, java.sql.Timestamp)"><!-- --></A><H3>
+setTimestamp</H3>
+<PRE>
+public void <B>setTimestamp</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
+ The driver
+ converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the
+ database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setTimestamp(java.lang.String, java.sql.Timestamp)" title="class or interface in java.sql">setTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(int)"><CODE>getTimestamp(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAsciiStream(java.lang.String, java.io.InputStream, int)"><!-- --></A><H3>
+setAsciiStream</H3>
+<PRE>
+public void <B>setAsciiStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                           int&nbsp;length)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+ When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code>. Data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from ASCII to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setAsciiStream(java.lang.String, java.io.InputStream, int)" title="class or interface in java.sql">setAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the Java input stream that contains the ASCII parameter value<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream(java.lang.String, java.io.InputStream, int)"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public void <B>setBinaryStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                            int&nbsp;length)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+ When a very large binary value is input to a <code>LONGVARBINARY</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBinaryStream(java.lang.String, java.io.InputStream, int)" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the java input stream which contains the binary parameter value<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setObject(java.lang.String, java.lang.Object, int, int)"><!-- --></A><H3>
+setObject</H3>
+<PRE>
+public void <B>setObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+                      int&nbsp;targetSqlType,
+                      int&nbsp;scale)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the value of the designated parameter with the given object. The second
+ argument must be an object type; for integral values, the
+ <code>java.lang</code> equivalent objects should be used.
+
+ <p>The given Java object will be converted to the given targetSqlType
+ before being sent to the database.
+
+ If the object has a custom mapping (is of a class implementing the
+ interface <code>SQLData</code>),
+ the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it
+ to the SQL data stream.
+ If, on the other hand, the object is of a class implementing
+ <code>Ref</code>, <code>Blob</code>, <code>Clob</code>,  <code>NClob</code>,
+  <code>Struct</code>, <code>java.net.URL</code>,
+ or <code>Array</code>, the driver should pass it to the database as a
+ value of the corresponding SQL type.
+ <P>
+ Note that this method may be used to pass datatabase-
+ specific abstract data types.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setObject(java.lang.String, java.lang.Object, int, int)" title="class or interface in java.sql">setObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the object containing the input parameter value<DD><CODE>targetSqlType</CODE> - the SQL type (as defined in java.sql.Types) to be
+ sent to the database. The scale argument may further qualify this type.<DD><CODE>scale</CODE> - for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,
+          this is the number of digits after the decimal point.  For all other
+          types, this value will be ignored.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>targetSqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int)"><CODE>getObject(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setObject(java.lang.String, java.lang.Object, int)"><!-- --></A><H3>
+setObject</H3>
+<PRE>
+public void <B>setObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+                      int&nbsp;targetSqlType)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the value of the designated parameter with the given object.
+ This method is like the method <code>setObject</code>
+ above, except that it assumes a scale of zero.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setObject(java.lang.String, java.lang.Object, int)" title="class or interface in java.sql">setObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the object containing the input parameter value<DD><CODE>targetSqlType</CODE> - the SQL type (as defined in java.sql.Types) to be
+                      sent to the database
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>targetSqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int)"><CODE>getObject(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setObject(java.lang.String, java.lang.Object)"><!-- --></A><H3>
+setObject</H3>
+<PRE>
+public void <B>setObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the value of the designated parameter with the given object.
+ The second parameter must be of type <code>Object</code>; therefore, the
+ <code>java.lang</code> equivalent objects should be used for built-in types.
+
+ <p>The JDBC specification specifies a standard mapping from
+ Java <code>Object</code> types to SQL types.  The given argument
+ will be converted to the corresponding SQL type before being
+ sent to the database.
+
+ <p>Note that this method may be used to pass datatabase-
+ specific abstract data types, by using a driver-specific Java
+ type.
+
+ If the object is of a class implementing the interface <code>SQLData</code>,
+ the JDBC driver should call the method <code>SQLData.writeSQL</code>
+ to write it to the SQL data stream.
+ If, on the other hand, the object is of a class implementing
+ <code>Ref</code>, <code>Blob</code>, <code>Clob</code>,  <code>NClob</code>,
+  <code>Struct</code>, <code>java.net.URL</code>,
+ or <code>Array</code>, the driver should pass it to the database as a
+ value of the corresponding SQL type.
+ <P>
+ This method throws an exception if there is an ambiguity, for example, if the
+ object is of a class implementing more than one of the interfaces named above.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setObject(java.lang.String, java.lang.Object)" title="class or interface in java.sql">setObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the object containing the input parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>CallableStatement</code> or if the given
+            <code>Object</code> parameter is ambiguous
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getObject(int)"><CODE>getObject(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream(java.lang.String, java.io.Reader, int)"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public void <B>setCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                               int&nbsp;length)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setCharacterStream(java.lang.String, java.io.Reader, int)" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object that
+        contains the UNICODE data used as the designated parameter<DD><CODE>length</CODE> - the number of characters in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDate(java.lang.String, java.sql.Date, java.util.Calendar)"><!-- --></A><H3>
+setDate</H3>
+<PRE>
+public void <B>setDate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>java.sql.Date</code> value,
+ using the given <code>Calendar</code> object.  The driver uses
+ the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
+ which the driver then sends to the database.  With a
+ a <code>Calendar</code> object, the driver can calculate the date
+ taking into account a custom timezone.  If no
+ <code>Calendar</code> object is specified, the driver uses the default
+ timezone, which is that of the virtual machine running the application.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setDate(java.lang.String, java.sql.Date, java.util.Calendar)" title="class or interface in java.sql">setDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the date
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getDate(int)"><CODE>getDate(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTime(java.lang.String, java.sql.Time, java.util.Calendar)"><!-- --></A><H3>
+setTime</H3>
+<PRE>
+public void <B>setTime</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>java.sql.Time</code> value,
+ using the given <code>Calendar</code> object.  The driver uses
+ the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
+ which the driver then sends to the database.  With a
+ a <code>Calendar</code> object, the driver can calculate the time
+ taking into account a custom timezone.  If no
+ <code>Calendar</code> object is specified, the driver uses the default
+ timezone, which is that of the virtual machine running the application.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setTime(java.lang.String, java.sql.Time, java.util.Calendar)" title="class or interface in java.sql">setTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the time
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTime(int)"><CODE>getTime(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTimestamp(java.lang.String, java.sql.Timestamp, java.util.Calendar)"><!-- --></A><H3>
+setTimestamp</H3>
+<PRE>
+public void <B>setTimestamp</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
+ using the given <code>Calendar</code> object.  The driver uses
+ the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,
+ which the driver then sends to the database.  With a
+ a <code>Calendar</code> object, the driver can calculate the timestamp
+ taking into account a custom timezone.  If no
+ <code>Calendar</code> object is specified, the driver uses the default
+ timezone, which is that of the virtual machine running the application.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setTimestamp(java.lang.String, java.sql.Timestamp, java.util.Calendar)" title="class or interface in java.sql">setTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the timestamp
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#getTimestamp(int)"><CODE>getTimestamp(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNull(java.lang.String, int, java.lang.String)"><!-- --></A><H3>
+setNull</H3>
+<PRE>
+public void <B>setNull</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    int&nbsp;sqlType,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to SQL <code>NULL</code>.
+ This version of the method <code>setNull</code> should
+ be used for user-defined types and REF type parameters.  Examples
+ of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and
+ named array types.
+
+ <P><B>Note:</B> To be portable, applications must give the
+ SQL type code and the fully-qualified SQL type name when specifying
+ a NULL user-defined or REF parameter.  In the case of a user-defined type
+ the name is the type name of the parameter itself.  For a REF
+ parameter, the name is the type name of the referenced type.  If
+ a JDBC driver does not need the type code or type name information,
+ it may ignore it.
+
+ Although it is intended for user-defined and Ref parameters,
+ this method may be used to set a null parameter of any JDBC type.
+ If the parameter does not have a user-defined or REF type, the given
+ typeName is ignored.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setNull(java.lang.String, int, java.lang.String)" title="class or interface in java.sql">setNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>sqlType</CODE> - a value from <code>java.sql.Types</code><DD><CODE>typeName</CODE> - the fully-qualified name of an SQL user-defined type;
+        ignored if the parameter is not a user-defined type or
+        SQL <code>REF</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getString(java.lang.String)"><!-- --></A><H3>
+getString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
+ or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
+ the Java programming language.
+ <p>
+ For the fixed-length type JDBC <code>CHAR</code>,
+ the <code>String</code> object
+ returned has exactly the same value the (JDBC4 clarification:) SQL
+ <code>CHAR</code> value had in the
+ database, including any padding added by the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getString(java.lang.String)" title="class or interface in java.sql">getString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value. If the value is SQL <code>NULL</code>, the result
+ is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setString(java.lang.String, java.lang.String)"><CODE>setString(java.lang.String, java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBoolean(java.lang.String)"><!-- --></A><H3>
+getBoolean</H3>
+<PRE>
+public boolean <B>getBoolean</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ (JDBC4 modified:)<p>
+ Retrieves the value of a JDBC <code>BIT</code> or <code>BOOLEAN</code>
+ parameter as a
+ <code>boolean</code> in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBoolean(java.lang.String)" title="class or interface in java.sql">getBoolean</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>false</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBoolean(java.lang.String, boolean)"><CODE>setBoolean(java.lang.String, boolean)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getByte(java.lang.String)"><!-- --></A><H3>
+getByte</H3>
+<PRE>
+public byte <B>getByte</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code>
+ in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getByte(java.lang.String)" title="class or interface in java.sql">getByte</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setByte(java.lang.String, byte)"><CODE>setByte(java.lang.String, byte)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getShort(java.lang.String)"><!-- --></A><H3>
+getShort</H3>
+<PRE>
+public short <B>getShort</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code>
+ in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getShort(java.lang.String)" title="class or interface in java.sql">getShort</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setShort(java.lang.String, short)"><CODE>setShort(java.lang.String, short)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getInt(java.lang.String)"><!-- --></A><H3>
+getInt</H3>
+<PRE>
+public int <B>getInt</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code>
+ in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getInt(java.lang.String)" title="class or interface in java.sql">getInt</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>,
+         the result is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setInt(java.lang.String, int)"><CODE>setInt(java.lang.String, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLong(java.lang.String)"><!-- --></A><H3>
+getLong</H3>
+<PRE>
+public long <B>getLong</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code>
+ in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getLong(java.lang.String)" title="class or interface in java.sql">getLong</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>,
+         the result is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setLong(java.lang.String, long)"><CODE>setLong(java.lang.String, long)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFloat(java.lang.String)"><!-- --></A><H3>
+getFloat</H3>
+<PRE>
+public float <B>getFloat</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code>
+ in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getFloat(java.lang.String)" title="class or interface in java.sql">getFloat</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>,
+         the result is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setFloat(java.lang.String, float)"><CODE>setFloat(java.lang.String, float)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDouble(java.lang.String)"><!-- --></A><H3>
+getDouble</H3>
+<PRE>
+public double <B>getDouble</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code>
+ in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getDouble(java.lang.String)" title="class or interface in java.sql">getDouble</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>,
+         the result is <code>0</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDouble(java.lang.String, double)"><CODE>setDouble(java.lang.String, double)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBytes(java.lang.String)"><!-- --></A><H3>
+getBytes</H3>
+<PRE>
+public byte[] <B>getBytes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code>
+ parameter as an array of <code>byte</code> values in the Java
+ programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBytes(java.lang.String)" title="class or interface in java.sql">getBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result is
+  <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBytes(java.lang.String, byte[])"><CODE>setBytes(java.lang.String, byte[])</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDate(java.lang.String)"><!-- --></A><H3>
+getDate</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A> <B>getDate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getDate(java.lang.String)" title="class or interface in java.sql">getDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDate(java.lang.String, java.sql.Date)"><CODE>setDate(java.lang.String, java.sql.Date)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTime(java.lang.String)"><!-- --></A><H3>
+getTime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A> <B>getTime</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getTime(java.lang.String)" title="class or interface in java.sql">getTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTime(java.lang.String, java.sql.Time)"><CODE>setTime(java.lang.String, java.sql.Time)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimestamp(java.lang.String)"><!-- --></A><H3>
+getTimestamp</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A> <B>getTimestamp</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getTimestamp(java.lang.String)" title="class or interface in java.sql">getTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result
+ is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTimestamp(java.lang.String, java.sql.Timestamp)"><CODE>setTimestamp(java.lang.String, java.sql.Timestamp)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObject(java.lang.String)"><!-- --></A><H3>
+getObject</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a parameter as an <code>Object</code> in the Java
+ programming language. If the value is an SQL <code>NULL</code>, the
+ driver returns a Java <code>null</code>.
+ <p>
+ This method returns a Java object whose type corresponds to the JDBC
+ type that was registered for this parameter using the method
+ <code>registerOutParameter</code>.  By registering the target JDBC
+ type as <code>java.sql.Types.OTHER</code>, this method can be used
+ to read database-specific abstract data types.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getObject(java.lang.String)" title="class or interface in java.sql">getObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>A <code>java.lang.Object</code> holding the OUT parameter value.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setObject(java.lang.String, java.lang.Object, int, int)"><CODE>setObject(java.lang.String, java.lang.Object, int, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBigDecimal(java.lang.String)"><!-- --></A><H3>
+getBigDecimal</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A> <B>getBigDecimal</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>NUMERIC</code> parameter as a
+ <code>java.math.BigDecimal</code> object with as many digits to the
+ right of the decimal point as the value contains.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBigDecimal(java.lang.String)" title="class or interface in java.sql">getBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value in full precision.  If the value is
+ SQL <code>NULL</code>, the result is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setBigDecimal(java.lang.String, java.math.BigDecimal)"><CODE>setBigDecimal(java.lang.String, java.math.BigDecimal)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObject(java.lang.String, java.util.Map)"><!-- --></A><H3>
+getObject</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&nbsp;map)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getObject(java.lang.String, java.util.Map)" title="class or interface in java.sql">getObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRef(java.lang.String)"><!-- --></A><H3>
+getRef</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A> <B>getRef</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>REF(&lt;structured-type&gt;)</code>
+ parameter as a <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql"><CODE>Ref</CODE></A> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getRef(java.lang.String)" title="class or interface in java.sql">getRef</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value as a <code>Ref</code> object in the
+         Java programming language.  If the value was SQL <code>NULL</code>,
+         the value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBlob(java.lang.String)"><!-- --></A><H3>
+getBlob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A> <B>getBlob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>BLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql"><CODE>Blob</CODE></A> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getBlob(java.lang.String)" title="class or interface in java.sql">getBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value as a <code>Blob</code> object in the
+         Java programming language.  If the value was SQL <code>NULL</code>,
+         the value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getClob(java.lang.String)"><!-- --></A><H3>
+getClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A> <B>getClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>CLOB</code> parameter as a
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql"><CODE>Clob</CODE></A> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getClob(java.lang.String)" title="class or interface in java.sql">getClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value as a <code>Clob</code> object in the
+         Java programming language.  If the value was SQL <code>NULL</code>,
+         the value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArray(java.lang.String)"><!-- --></A><H3>
+getArray</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A> <B>getArray</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>ARRAY</code> parameter as an
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql"><CODE>Array</CODE></A> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getArray(java.lang.String)" title="class or interface in java.sql">getArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value as an <code>Array</code> object in
+         Java programming language.  If the value was SQL <code>NULL</code>,
+         the value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDate(java.lang.String, java.util.Calendar)"><!-- --></A><H3>
+getDate</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A> <B>getDate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>DATE</code> parameter as a
+ <code>java.sql.Date</code> object, using
+ the given <code>Calendar</code> object
+ to construct the date.
+ With a <code>Calendar</code> object, the driver
+ can calculate the date taking into account a custom timezone and locale.
+ If no <code>Calendar</code> object is specified, the driver uses the
+ default timezone and locale.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getDate(java.lang.String, java.util.Calendar)" title="class or interface in java.sql">getDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the date
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>,
+ the result is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setDate(java.lang.String, java.sql.Date)"><CODE>setDate(java.lang.String, java.sql.Date)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTime(java.lang.String, java.util.Calendar)"><!-- --></A><H3>
+getTime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A> <B>getTime</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>TIME</code> parameter as a
+ <code>java.sql.Time</code> object, using
+ the given <code>Calendar</code> object
+ to construct the time.
+ With a <code>Calendar</code> object, the driver
+ can calculate the time taking into account a custom timezone and locale.
+ If no <code>Calendar</code> object is specified, the driver uses the
+ default timezone and locale.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getTime(java.lang.String, java.util.Calendar)" title="class or interface in java.sql">getTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the time
+<DT><B>Returns:</B><DD>the parameter value; if the value is SQL <code>NULL</code>, the result is
+ <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTime(java.lang.String, java.sql.Time)"><CODE>setTime(java.lang.String, java.sql.Time)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimestamp(java.lang.String, java.util.Calendar)"><!-- --></A><H3>
+getTimestamp</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A> <B>getTimestamp</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
+ <code>java.sql.Timestamp</code> object, using
+ the given <code>Calendar</code> object to construct
+ the <code>Timestamp</code> object.
+ With a <code>Calendar</code> object, the driver
+ can calculate the timestamp taking into account a custom timezone and locale.
+ If no <code>Calendar</code> object is specified, the driver uses the
+ default timezone and locale.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getTimestamp(java.lang.String, java.util.Calendar)" title="class or interface in java.sql">getTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the timestamp
+<DT><B>Returns:</B><DD>the parameter value.  If the value is SQL <code>NULL</code>, the result is
+ <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setTimestamp(java.lang.String, java.sql.Timestamp)"><CODE>setTimestamp(java.lang.String, java.sql.Timestamp)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getURL(java.lang.String)"><!-- --></A><H3>
+getURL</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A> <B>getURL</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>DATALINK</code> parameter as a
+ <code>java.net.URL</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getURL(java.lang.String)" title="class or interface in java.sql">getURL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value as a <code>java.net.URL</code> object in the
+ Java programming language.  If the value was SQL <code>NULL</code>, the
+ value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>CallableStatement</code>,
+            or if there is a problem with the URL
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setURL(java.lang.String, java.net.URL)"><CODE>setURL(java.lang.String, java.net.URL)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRowId(int)"><!-- --></A><H3>
+getRowId</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A> <B>getRowId</B>(int&nbsp;parameterIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a
+ <code>java.sql.RowId</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getRowId(int)" title="class or interface in java.sql">getRowId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2,...
+<DT><B>Returns:</B><DD>a <code>RowId</code> object that represents the JDBC <code>ROWID</code>
+     value is used as the designated parameter. If the parameter contains
+ a SQL <code>NULL</code>, then a <code>null</code> value is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRowId(java.lang.String)"><!-- --></A><H3>
+getRowId</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A> <B>getRowId</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a
+ <code>java.sql.RowId</code> object.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getRowId(java.lang.String)" title="class or interface in java.sql">getRowId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>a <code>RowId</code> object that represents the JDBC <code>ROWID</code>
+     value is used as the designated parameter. If the parameter contains
+ a SQL <code>NULL</code>, then a <code>null</code> value is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setRowId(java.lang.String, java.sql.RowId)"><!-- --></A><H3>
+setRowId</H3>
+<PRE>
+public void <B>setRowId</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the designated parameter to the given <code>java.sql.RowId</code> object. The
+ driver converts this to a SQL <code>ROWID</code> when it sends it to the
+ database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setRowId(java.lang.String, java.sql.RowId)" title="class or interface in java.sql">setRowId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNString(java.lang.String, java.lang.String)"><!-- --></A><H3>
+setNString</H3>
+<PRE>
+public void <B>setNString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;value)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>String</code> object.
+ The driver converts this to a SQL <code>NCHAR</code> or
+ <code>NVARCHAR</code> or <code>LONGNVARCHAR</code>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setNString(java.lang.String, java.lang.String)" title="class or interface in java.sql">setNString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter to be set<DD><CODE>value</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNCharacterStream(java.lang.String, java.io.Reader, long)"><!-- --></A><H3>
+setNCharacterStream</H3>
+<PRE>
+public void <B>setNCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;value,
+                                long&nbsp;length)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object. The
+ <code>Reader</code> reads the data till end-of-file is reached. The
+ driver does the necessary conversion from Java character format to
+ the national character set in the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setNCharacterStream(java.lang.String, java.io.Reader, long)" title="class or interface in java.sql">setNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter to be set<DD><CODE>value</CODE> - the parameter value<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNClob(java.lang.String, java.sql.NClob)"><!-- --></A><H3>
+setNClob</H3>
+<PRE>
+public void <B>setNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>&nbsp;value)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>java.sql.NClob</code> object. The object
+ implements the <code>java.sql.NClob</code> interface. This <code>NClob</code>
+ object maps to a SQL <code>NCLOB</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setNClob(java.lang.String, java.sql.NClob)" title="class or interface in java.sql">setNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter to be set<DD><CODE>value</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClob(java.lang.String, java.io.Reader, long)"><!-- --></A><H3>
+setClob</H3>
+<PRE>
+public void <B>setClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                    long&nbsp;length)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object.  The <code>reader</code> must contain  the number
+ of characters specified by length otherwise a <code>SQLException</code> will be
+ generated when the <code>CallableStatement</code> is executed.
+ This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
+ because it informs the driver that the parameter value should be sent to
+ the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+ driver may have to do extra work to determine whether the parameter
+ data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setClob(java.lang.String, java.io.Reader, long)" title="class or interface in java.sql">setClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter to be set<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement; if the length specified is less than zero;
+ a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBlob(java.lang.String, java.io.InputStream, long)"><!-- --></A><H3>
+setBlob</H3>
+<PRE>
+public void <B>setBlob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream,
+                    long&nbsp;length)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>InputStream</code> object.  The <code>inputstream</code> must contain  the number
+ of characters specified by length, otherwise a <code>SQLException</code> will be
+ generated when the <code>CallableStatement</code> is executed.
+ This method differs from the <code>setBinaryStream (int, InputStream, int)</code>
+ method because it informs the driver that the parameter value should be
+ sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
+ the driver may have to do extra work to determine whether the parameter
+ data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBlob(java.lang.String, java.io.InputStream, long)" title="class or interface in java.sql">setBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter to be set
+ the second is 2, ...<DD><CODE>inputStream</CODE> - An object that contains the data to set the parameter
+ value to.<DD><CODE>length</CODE> - the number of bytes in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond
+ to a parameter marker in the SQL statement,  or if the length specified
+ is less than zero; if the number of bytes in the inputstream does not match
+ the specfied length; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNClob(java.lang.String, java.io.Reader, long)"><!-- --></A><H3>
+setNClob</H3>
+<PRE>
+public void <B>setNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                     long&nbsp;length)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object.  The <code>reader</code> must contain  the number
+ of characters specified by length otherwise a <code>SQLException</code> will be
+ generated when the <code>CallableStatement</code> is executed.
+ This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
+ because it informs the driver that the parameter value should be sent to
+ the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+ driver may have to do extra work to determine whether the parameter
+ data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setNClob(java.lang.String, java.io.Reader, long)" title="class or interface in java.sql">setNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter to be set<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement; if the length specified is less than zero;
+ if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNClob(int)"><!-- --></A><H3>
+getNClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A> <B>getNClob</B>(int&nbsp;parameterIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated JDBC <code>NCLOB</code> parameter as a
+ <code>java.sql.NClob</code> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getNClob(int)" title="class or interface in java.sql">getNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, and
+ so on
+<DT><B>Returns:</B><DD>the parameter value as a <code>NClob</code> object in the
+ Java programming language.  If the value was SQL <code>NULL</code>, the
+ value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNClob(java.lang.String)"><!-- --></A><H3>
+getNClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A> <B>getNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of a JDBC <code>NCLOB</code> parameter as a
+ <code>java.sql.NClob</code> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getNClob(java.lang.String)" title="class or interface in java.sql">getNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>the parameter value as a <code>NClob</code> object in the
+         Java programming language.  If the value was SQL <code>NULL</code>,
+         the value <code>null</code> is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setSQLXML(java.lang.String, java.sql.SQLXML)"><!-- --></A><H3>
+setSQLXML</H3>
+<PRE>
+public void <B>setSQLXML</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>&nbsp;xmlObject)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an
+ <code>SQL XML</code> value when it sends it to the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setSQLXML(java.lang.String, java.sql.SQLXML)" title="class or interface in java.sql">setSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>xmlObject</CODE> - a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>CallableStatement</code> or
+ the <code>java.xml.transform.Result</code>,
+  <code>Writer</code> or <code>OutputStream</code> has not been closed for the <code>SQLXML</code> object
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSQLXML(int)"><!-- --></A><H3>
+getSQLXML</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A> <B>getSQLXML</B>(int&nbsp;parameterIndex)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated <code>SQL XML</code> parameter as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getSQLXML(int)" title="class or interface in java.sql">getSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSQLXML(java.lang.String)"><!-- --></A><H3>
+getSQLXML</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A> <B>getSQLXML</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated <code>SQL XML</code> parameter as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getSQLXML(java.lang.String)" title="class or interface in java.sql">getSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNString(int)"><!-- --></A><H3>
+getNString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getNString</B>(int&nbsp;parameterIndex)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated <code>NCHAR</code>,
+ <code>NVARCHAR</code>
+ or <code>LONGNVARCHAR</code> parameter as
+ a <code>String</code> in the Java programming language.
+  <p>
+ For the fixed-length type JDBC <code>NCHAR</code>,
+ the <code>String</code> object
+ returned has exactly the same value the SQL
+ <code>NCHAR</code> value had in the
+ database, including any padding added by the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getNString(int)" title="class or interface in java.sql">getNString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>String</code> object that maps an
+ <code>NCHAR</code>, <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNString(java.lang.String, java.lang.String)"><CODE>setNString(java.lang.String, java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNString(java.lang.String)"><!-- --></A><H3>
+getNString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getNString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+  Retrieves the value of the designated <code>NCHAR</code>,
+ <code>NVARCHAR</code>
+ or <code>LONGNVARCHAR</code> parameter as
+ a <code>String</code> in the Java programming language.
+ <p>
+ For the fixed-length type JDBC <code>NCHAR</code>,
+ the <code>String</code> object
+ returned has exactly the same value the SQL
+ <code>NCHAR</code> value had in the
+ database, including any padding added by the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getNString(java.lang.String)" title="class or interface in java.sql">getNString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>a <code>String</code> object that maps an
+ <code>NCHAR</code>, <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html#setNString(java.lang.String, java.lang.String)"><CODE>setNString(java.lang.String, java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNCharacterStream(int)"><!-- --></A><H3>
+getNCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getNCharacterStream</B>(int&nbsp;parameterIndex)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.
+ It is intended for use when
+ accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> parameters.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getNCharacterStream(int)" title="class or interface in java.sql">getNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object that contains the parameter
+ value; if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNCharacterStream(java.lang.String)"><!-- --></A><H3>
+getNCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getNCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.
+ It is intended for use when
+ accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> parameters.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getNCharacterStream(java.lang.String)" title="class or interface in java.sql">getNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object that contains the parameter
+ value; if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream(int)"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>(int&nbsp;parameterIndex)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.
+
+ <!-- end generic documentstion -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. <p>
+
+ Calling this method always throws an <code>SQLException</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getCharacterStream(int)" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object that contains the parameter
+ value; if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream(java.lang.String)"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the value of the designated parameter as a
+ <code>java.io.Reader</code> object in the Java programming language.
+
+ <!-- end generic documentstion -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#getCharacterStream(java.lang.String)" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object that contains the parameter
+ value; if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBlob(java.lang.String, java.sql.Blob)"><!-- --></A><H3>
+setBlob</H3>
+<PRE>
+public void <B>setBlob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>java.sql.Blob</code> object.
+ The driver converts this to an SQL <code>BLOB</code> value when it
+ sends it to the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBlob(java.lang.String, java.sql.Blob)" title="class or interface in java.sql">setBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClob(java.lang.String, java.sql.Clob)"><!-- --></A><H3>
+setClob</H3>
+<PRE>
+public void <B>setClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>java.sql.Clob</code> object.
+ The driver converts this to an SQL <code>CLOB</code> value when it
+ sends it to the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setClob(java.lang.String, java.sql.Clob)" title="class or interface in java.sql">setClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAsciiStream(java.lang.String, java.io.InputStream, long)"><!-- --></A><H3>
+setAsciiStream</H3>
+<PRE>
+public void <B>setAsciiStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                           long&nbsp;length)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+ When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code>. Data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from ASCII to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setAsciiStream(java.lang.String, java.io.InputStream, long)" title="class or interface in java.sql">setAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the Java input stream that contains the ASCII parameter value<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterName does not correspond to a named
+ parameter; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream(java.lang.String, java.io.InputStream, long)"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public void <B>setBinaryStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                            long&nbsp;length)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+ When a very large binary value is input to a <code>LONGVARBINARY</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBinaryStream(java.lang.String, java.io.InputStream, long)" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the java input stream which contains the binary parameter value<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream(java.lang.String, java.io.Reader, long)"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public void <B>setCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                               long&nbsp;length)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setCharacterStream(java.lang.String, java.io.Reader, long)" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object that
+        contains the UNICODE data used as the designated parameter<DD><CODE>length</CODE> - the number of characters in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAsciiStream(java.lang.String, java.io.InputStream)"><!-- --></A><H3>
+setAsciiStream</H3>
+<PRE>
+public void <B>setAsciiStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given input stream.
+ When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code>. Data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from ASCII to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setAsciiStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setAsciiStream(java.lang.String, java.io.InputStream)" title="class or interface in java.sql">setAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the Java input stream that contains the ASCII parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterName does not correspond to a named
+ parameter; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream(java.lang.String, java.io.InputStream)"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public void <B>setBinaryStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given input stream.
+ When a very large binary value is input to a <code>LONGVARBINARY</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code> object. The data will be read from the
+ stream as needed until end-of-file is reached.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setBinaryStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBinaryStream(java.lang.String, java.io.InputStream)" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>x</CODE> - the java input stream which contains the binary parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterName does not correspond to a named
+ parameter; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream(java.lang.String, java.io.Reader)"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public void <B>setCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setCharacterStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setCharacterStream(java.lang.String, java.io.Reader)" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object that contains the
+        Unicode data
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterName does not correspond to a named
+ parameter; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNCharacterStream(java.lang.String, java.io.Reader)"><!-- --></A><H3>
+setNCharacterStream</H3>
+<PRE>
+public void <B>setNCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;value)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object. The
+   <code>Reader</code> reads the data till end-of-file is reached. The
+   driver does the necessary conversion from Java character format to
+   the national character set in the database.
+
+   <P><B>Note:</B> This stream object can either be a standard
+   Java stream object or your own subclass that implements the
+   standard interface.
+   <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+   it might be more efficient to use a version of
+   <code>setNCharacterStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setNCharacterStream(java.lang.String, java.io.Reader)" title="class or interface in java.sql">setNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>value</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterName does not correspond to a named
+   parameter; if the driver does not support national
+           character sets;  if the driver can detect that a data conversion
+    error could occur; if a database access error occurs; or
+   this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClob(java.lang.String, java.io.Reader)"><!-- --></A><H3>
+setClob</H3>
+<PRE>
+public void <B>setClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+ This method differs from the <code>setCharacterStream (int, Reader)</code> method
+ because it informs the driver that the parameter value should be sent to
+ the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+ driver may have to do extra work to determine whether the parameter
+ data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setClob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setClob(java.lang.String, java.io.Reader)" title="class or interface in java.sql">setClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterName does not correspond to a named
+ parameter; if a database access error occurs or this method is called on
+ a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBlob(java.lang.String, java.io.InputStream)"><!-- --></A><H3>
+setBlob</H3>
+<PRE>
+public void <B>setBlob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>InputStream</code> object.
+ This method differs from the <code>setBinaryStream (int, InputStream)</code>
+ method because it informs the driver that the parameter value should be
+ sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
+ the driver may have to do extra work to determine whether the parameter
+ data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setBlob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setBlob(java.lang.String, java.io.InputStream)" title="class or interface in java.sql">setBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>inputStream</CODE> - An object that contains the data to set the parameter
+ value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterName does not correspond to a named
+ parameter; if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNClob(java.lang.String, java.io.Reader)"><!-- --></A><H3>
+setNClob</H3>
+<PRE>
+public void <B>setNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parameterName,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+ This method differs from the <code>setCharacterStream (int, Reader)</code> method
+ because it informs the driver that the parameter value should be sent to
+ the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+ driver may have to do extra work to determine whether the parameter
+ data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setNClob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true#setNClob(java.lang.String, java.io.Reader)" title="class or interface in java.sql">setNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterName</CODE> - the name of the parameter<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterName does not correspond to a named
+ parameter; if the driver does not support national character sets;
+ if the driver can detect that a data conversion
+  error could occur;  if a database access error occurs or
+ this method is called on a closed <code>CallableStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="close()"><!-- --></A><H3>
+close</H3>
+<PRE>
+public void <B>close</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Does the specialized work required to free this object's resources and
+ that of it's parent classes. <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#close()" title="class or interface in java.sql">close</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE><DT><B>Overrides:</B><DD><CODE><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#close()">close</A></CODE> in class <CODE><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCCallableStatement.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCCallableStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCCallableStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCClob.html b/doc/apidocs/org/hsqldb/jdbc/JDBCClob.html
new file mode 100644
index 0000000..f1e9f55
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCClob.html
@@ -0,0 +1,1090 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:45 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCClob (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCClob (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCClob.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCClob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCClob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCClob</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCClob</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc">JDBCNClob</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCClob</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></DL>
+</PRE>
+
+<P>
+The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ for the SQL <code>CLOB</code> type.
+ An SQL <code>CLOB</code> is a built-in type
+ that stores a Character Large Object as a column value in a row of
+ a database table.
+ By default drivers implement a <code>Clob</code> object using an SQL
+ <code>locator(CLOB)</code>, which means that a <code>Clob</code> object
+ contains a logical pointer to the SQL <code>CLOB</code> data rather than
+ the data itself. A <code>Clob</code> object is valid for the duration
+ of the transaction in which it was created.
+ <P>The <code>Clob</code> interface provides methods for getting the
+ length of an SQL <code>CLOB</code> (Character Large Object) value,
+ for materializing a <code>CLOB</code> value on the client, and for
+ searching for a substring or <code>CLOB</code> object within a
+ <code>CLOB</code> value.
+ Methods in the interfaces <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A>,
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql"><CODE>CallableStatement</CODE></A>, and <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql"><CODE>PreparedStatement</CODE></A>, such as
+ <code>getClob</code> and <code>setClob</code> allow a programmer to
+ access an SQL <code>CLOB</code> value.  In addition, this interface
+ has methods for updating a <code>CLOB</code> value.
+ <p>
+ All methods on the <code>Clob</code> interface must be fully implemented if the
+ JDBC driver supports the data type.
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Previous to 2.0, the HSQLDB driver did not implement Clob using an SQL
+ locator(CLOB).  That is, an HSQLDB Clob object did not contain a logical
+ pointer to SQL CLOB data; rather it directly contained a representation of
+ the data (a String). As a result, an HSQLDB Clob object was itself
+ valid beyond the duration of the transaction in which is was created,
+ although it did not necessarily represent a corresponding value
+ on the database. Also, the interface methods for updating a CLOB value
+ were unsupported, with the exception of the truncate method,
+ in that it could be used to truncate the local value. <p>
+
+ Starting with 2.0, the HSQLDB driver fully supports both local and remote
+ SQL CLOB data implementations, meaning that an HSQLDB Clob object <em>may</em>
+ contain a logical pointer to remote SQL CLOB data (see <A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><CODE>JDBCClobClient</CODE></A>) or it may directly contain a local representation of the
+ data (as implemented in this class).  In particular, when the product is built
+ under JDK 1.6+ and the Clob instance is constructed as a result of calling
+ JDBCConnection.createClob(), then the resulting Clob instance is initially
+ disconnected (is not bound to the tranaction scope of the vending Connection
+ object), the data is contained directly and all interface methods for
+ updating the CLOB value are supported for local use until the first
+ invocation of free(); otherwise, an HSQLDB Clob's implementation is
+ determined at runtime by the driver, it is typically not valid beyond
+ the duration of the transaction in which is was created, and there no
+ standard way to query whether it represents a local or remote value.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>boucherb@users</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#JDBCClob(java.lang.String)">JDBCClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;data)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new JDBCClob object wrapping the given character
+ sequence.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#free()">free</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method frees the <code>Clob</code> object and releases the resources the resources
+ that it holds.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getAsciiStream()">getAsciiStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
+ object as an ascii stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getCharacterStream()">getCharacterStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
+ object as a <code>java.io.Reader</code> object (or as a stream of
+ characters).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getCharacterStream(long, long)">getCharacterStream</A></B>(long&nbsp;pos,
+                   long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
+ with the character specified by pos, which is length characters in length.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getSubString(long, int)">getSubString</A></B>(long&nbsp;pos,
+             int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a copy of the specified substring
+ in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#length()">length</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the number of characters
+ in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#position(java.sql.Clob, long)">position</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;searchstr,
+         long&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the character position at which the specified
+ <code>Clob</code> object <code>searchstr</code> appears in this
+ <code>Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#position(java.lang.String, long)">position</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;searchstr,
+         long&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the character position at which the specified substring
+ <code>searchstr</code> appears in the SQL <code>CLOB</code> value
+ represented by this <code>Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setAsciiStream(long)">setAsciiStream</A></B>(long&nbsp;pos)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a stream to be used to write Ascii characters to the
+ <code>CLOB</code> value that this <code>Clob</code> object represents,
+ starting at position <code>pos</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Writer.html?is-external=true" title="class or interface in java.io">Writer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setCharacterStream(long)">setCharacterStream</A></B>(long&nbsp;pos)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a stream to be used to write a stream of Unicode characters
+ to the <code>CLOB</code> value that this <code>Clob</code> object
+ represents, at position <code>pos</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setString(long, java.lang.String)">setString</A></B>(long&nbsp;pos,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;str)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes the given Java <code>String</code> to the <code>CLOB</code>
+ value that this <code>Clob</code> object designates at the position
+ <code>pos</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setString(long, java.lang.String, int, int)">setString</A></B>(long&nbsp;pos,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;str,
+          int&nbsp;offset,
+          int&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes <code>len</code> characters of <code>str</code>, starting
+ at character <code>offset</code>, to the <code>CLOB</code> value
+ that this <code>Clob</code> represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#truncate(long)">truncate</A></B>(long&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Truncates the <code>CLOB</code> value that this <code>Clob</code>
+ designates to have a length of <code>len</code>
+ characters.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCClob(java.lang.String)"><!-- --></A><H3>
+JDBCClob</H3>
+<PRE>
+public <B>JDBCClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;data)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new JDBCClob object wrapping the given character
+ sequence. <p>
+
+ This constructor is used internally to retrieve result set values as
+ Clob objects, yet it must be public to allow access from other packages.
+ As such (in the interest of efficiency) this object maintains a reference
+ to the given String object rather than making a copy and so it is
+ gently suggested (in the interest of effective memory management) that
+ extenal clients using this constructor either take pause to consider
+ the implications or at least take care to provide a String object whose
+ internal character buffer is not much larger than required to represent
+ the value.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>data</CODE> - the character sequence representing the Clob value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the argument is null</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="length()"><!-- --></A><H3>
+length</H3>
+<PRE>
+public long <B>length</B>()
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the number of characters
+ in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#length()" title="class or interface in java.sql">length</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>length of the <code>CLOB</code> in characters
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            length of the <code>CLOB</code> value
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSubString(long, int)"><!-- --></A><H3>
+getSubString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getSubString</B>(long&nbsp;pos,
+                           int&nbsp;length)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a copy of the specified substring
+ in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.
+ The substring begins at position
+ <code>pos</code> and has up to <code>length</code> consecutive
+ characters.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The official specification above is ambiguous in that it does not
+ precisely indicate the policy to be observed when
+ pos > this.length() - length.  One policy would be to retrieve the
+ characters from pos to this.length().  Another would be to throw
+ an exception.  HSQLDB observes the second policy. <p>
+
+ <b>Note</b><p>
+
+ Depending java.lang.String implementation, the returned value
+ may be sharing the underlying (and possibly much larger) character
+ buffer.  This facilitates much faster operation and will save memory
+ if many transient substrings are to be retrieved during processing, but
+ it has memory management implications should retrieved substrings be
+ required to survive for any non-trivial duration.  It is left up to the
+ client to decide how to handle the trade-off (whether to make an isolated
+ copy of the returned substring or risk that more memory remains allocated
+ than is absolutely reuired).
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getSubString(long, int)" title="class or interface in java.sql">getSubString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the first character of the substring to be extracted.
+            The first character is at position 1.<DD><CODE>length</CODE> - the number of consecutive characters to be copied
+<DT><B>Returns:</B><DD>a <code>String</code> that is the specified substring in
+         the <code>CLOB</code> value designated by this <code>Clob</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value or if pos is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream()"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
+ object as a <code>java.io.Reader</code> object (or as a stream of
+ characters).
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getCharacterStream()" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object containing the
+         <code>CLOB</code> data
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setCharacterStream(long)"><CODE>setCharacterStream(long)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAsciiStream()"><!-- --></A><H3>
+getAsciiStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getAsciiStream</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
+ object as an ascii stream.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getAsciiStream()" title="class or interface in java.sql">getAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>java.io.InputStream</code> object containing the
+         <code>CLOB</code> data
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setAsciiStream(long)"><CODE>setAsciiStream(long)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="position(java.lang.String, long)"><!-- --></A><H3>
+position</H3>
+<PRE>
+public long <B>position</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;searchstr,
+                     long&nbsp;start)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the character position at which the specified substring
+ <code>searchstr</code> appears in the SQL <code>CLOB</code> value
+ represented by this <code>Clob</code> object.  The search
+ begins at position <code>start</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#position(java.lang.String, long)" title="class or interface in java.sql">position</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>searchstr</CODE> - the substring for which to search<DD><CODE>start</CODE> - the position at which to begin searching; the first position
+              is 1
+<DT><B>Returns:</B><DD>the position at which the substring appears or -1 if it is not
+         present; the first position is 1
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value or if start is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="position(java.sql.Clob, long)"><!-- --></A><H3>
+position</H3>
+<PRE>
+public long <B>position</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;searchstr,
+                     long&nbsp;start)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the character position at which the specified
+ <code>Clob</code> object <code>searchstr</code> appears in this
+ <code>Clob</code> object.  The search begins at position
+ <code>start</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#position(java.sql.Clob, long)" title="class or interface in java.sql">position</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>searchstr</CODE> - the <code>Clob</code> object for which to search<DD><CODE>start</CODE> - the position at which to begin searching; the first
+              position is 1
+<DT><B>Returns:</B><DD>the position at which the <code>Clob</code> object appears
+              or -1 if it is not present; the first position is 1
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value or if start is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setString(long, java.lang.String)"><!-- --></A><H3>
+setString</H3>
+<PRE>
+public int <B>setString</B>(long&nbsp;pos,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;str)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Writes the given Java <code>String</code> to the <code>CLOB</code>
+ value that this <code>Clob</code> object designates at the position
+ <code>pos</code>. The string will overwrite the existing characters
+ in the <code>Clob</code> object starting at the position
+ <code>pos</code>.  If the end of the <code>Clob</code> value is reached
+ while writing the given string, then the length of the <code>Clob</code>
+ value will be increased to accomodate the extra characters.
+ <p>
+ <b>Note:</b> If the value specified for <code>pos</code>
+ is greater then the length+1 of the <code>CLOB</code> value then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is supported. <p>
+
+ When built under JDK 1.6+ and the Clob instance is constructed as a
+ result of calling JDBCConnection.createClob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in the
+ database because JDBCConnection.createClob() constructs disconnected,
+ initially empty Clob instances. To propogate the Clob value to a database
+ in this case, it is required to supply the Clob instance to an updating
+ or inserting setXXX method of a Prepared or Callable Statement, or to
+ supply the Clob instance to an updateXXX method of an updateable
+ ResultSet. <p>
+
+ <b>Implementation Notes:</b><p>
+
+ No attempt is made to ensure precise thread safety. Instead, volatile
+ member field and local variable snapshot isolation semantics are
+ implemented.  This is expected to eliminate most issues related
+ to race conditions, with the possible exception of concurrent
+ invocation of free(). <p>
+
+ In general, however, if an application may perform concurrent
+ JDBCClob modifications and the integrity of the application depends on
+ total order Clob modification semantics, then such operations
+ should be synchronized on an appropriate monitor.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setString(long, java.lang.String)" title="class or interface in java.sql">setString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position at which to start writing to the <code>CLOB</code>
+         value that this <code>Clob</code> object represents;
+ The first position is 1<DD><CODE>str</CODE> - the string to be written to the <code>CLOB</code>
+        value that this <code>Clob</code> designates
+<DT><B>Returns:</B><DD>the number of characters written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value or if pos is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setString(long, java.lang.String, int, int)"><!-- --></A><H3>
+setString</H3>
+<PRE>
+public int <B>setString</B>(long&nbsp;pos,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;str,
+                     int&nbsp;offset,
+                     int&nbsp;len)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Writes <code>len</code> characters of <code>str</code>, starting
+ at character <code>offset</code>, to the <code>CLOB</code> value
+ that this <code>Clob</code> represents.  The string will overwrite the existing characters
+ in the <code>Clob</code> object starting at the position
+ <code>pos</code>.  If the end of the <code>Clob</code> value is reached
+ while writing the given string, then the length of the <code>Clob</code>
+ value will be increased to accomodate the extra characters.
+ <p>
+ <b>Note:</b> If the value specified for <code>pos</code>
+ is greater then the length+1 of the <code>CLOB</code> value then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is supported. <p>
+
+ When built under JDK 1.6+ and the Clob instance is constructed as a
+ result of calling JDBCConnection.createClob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in a
+ database because JDBCConnection.createClob() constructs disconnected,
+ initially empty Clob instances. To propogate the Clob value to a database
+ in this case, it is required to supply the Clob instance to an updating
+ or inserting setXXX method of a Prepared or Callable Statement, or to
+ supply the Clob instance to an updateXXX method of an updateable
+ ResultSet. <p>
+
+ <b>Implementation Notes:</b><p>
+
+ If the value specified for <code>pos</code>
+ is greater than the length of the <code>CLOB</code> value, then
+ the <code>CLOB</code> value is extended in length to accept the
+ written characters and the undefined region up to <code>pos</code> is
+ filled with (char)0. <p>
+
+ No attempt is made to ensure precise thread safety. Instead, volatile
+ member field and local variable snapshot isolation semantics are
+ implemented.  This is expected to eliminate most issues related
+ to race conditions, with the possible exception of concurrent
+ invocation of free(). <p>
+
+ In general, however, if an application may perform concurrent
+ JDBCClob modifications and the integrity of the application depends on
+ total order Clob modification semantics, then such operations
+ should be synchronized on an appropriate monitor.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setString(long, java.lang.String, int, int)" title="class or interface in java.sql">setString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position at which to start writing to this
+        <code>CLOB</code> object; The first position  is 1<DD><CODE>str</CODE> - the string to be written to the <code>CLOB</code>
+        value that this <code>Clob</code> object represents<DD><CODE>offset</CODE> - the offset into <code>str</code> to start reading
+        the characters to be written<DD><CODE>len</CODE> - the number of characters to be written
+<DT><B>Returns:</B><DD>the number of characters written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value or if pos is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAsciiStream(long)"><!-- --></A><H3>
+setAsciiStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A> <B>setAsciiStream</B>(long&nbsp;pos)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a stream to be used to write Ascii characters to the
+ <code>CLOB</code> value that this <code>Clob</code> object represents,
+ starting at position <code>pos</code>.  Characters written to the stream
+ will overwrite the existing characters
+ in the <code>Clob</code> object starting at the position
+ <code>pos</code>.  If the end of the <code>Clob</code> value is reached
+ while writing characters to the stream, then the length of the <code>Clob</code>
+ value will be increased to accomodate the extra characters.
+ <p>
+ <b>Note:</b> If the value specified for <code>pos</code>
+ is greater than the length of the <code>CLOB</code> value, then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is supported. <p>
+
+ When built under JDK 1.6+ and the Clob instance is constructed as a
+ result of calling JDBCConnection.createClob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in a
+ database because JDBCConnection.createClob() constructs disconnected,
+ initially empty Clob instances. To propogate the Clob value to a database
+ in this case, it is required to supply the Clob instance to an updating
+ or inserting setXXX method of a Prepared or Callable Statement, or to
+ supply the Clob instance to an updateXXX method of an updateable
+ ResultSet. <p>
+
+ <b>Implementation Notes:</b><p>
+
+ The data written to the stream does not appear in this
+ Clob until the stream is closed. <p>
+
+ When the stream is closed, if the value specified for <code>pos</code>
+ is greater than the length of the <code>CLOB</code> value, then
+ the <code>CLOB</code> value is extended in length to accept the
+ written characters and the undefined region up to <code>pos</code> is
+ filled with (char)0. <p>
+
+ Also, no attempt is made to ensure precise thread safety. Instead,
+ volatile member field and local variable snapshot isolation semantics
+ are implemented.  This is expected to eliminate most issues related
+ to race conditions, with the possible exception of concurrent
+ invocation of free(). <p>
+
+ In general, however, if an application may perform concurrent
+ JDBCClob modifications and the integrity of the application depends on
+ total order Clob modification semantics, then such operations
+ should be synchronized on an appropriate monitor.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setAsciiStream(long)" title="class or interface in java.sql">setAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position at which to start writing to this
+        <code>CLOB</code> object; The first position is 1
+<DT><B>Returns:</B><DD>the stream to which ASCII encoded characters can be written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value or if pos is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getAsciiStream()"><CODE>getAsciiStream()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream(long)"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Writer.html?is-external=true" title="class or interface in java.io">Writer</A> <B>setCharacterStream</B>(long&nbsp;pos)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a stream to be used to write a stream of Unicode characters
+ to the <code>CLOB</code> value that this <code>Clob</code> object
+ represents, at position <code>pos</code>. Characters written to the stream
+ will overwrite the existing characters
+ in the <code>Clob</code> object starting at the position
+ <code>pos</code>.  If the end of the <code>Clob</code> value is reached
+ while writing characters to the stream, then the length of the <code>Clob</code>
+ value will be increased to accomodate the extra characters.
+ <p>
+ <b>Note:</b> If the value specified for <code>pos</code>
+ is greater then the length+1 of the <code>CLOB</code> value then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is supported. <p>
+
+ When built under JDK 1.6+ and the Clob instance is constructed as a
+ result of calling JDBCConnection.createClob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in a
+ database because JDBCConnection.createClob() constructs disconnected,
+ initially empty Clob instances. To propogate the Clob value to a database
+ in this case, it is required to supply the Clob instance to an updating
+ or inserting setXXX method of a Prepared or Callable Statement, or to
+ supply the Clob instance to an updateXXX method of an updateable
+ ResultSet. <p>
+
+ <b>Implementation Notes:</b><p>
+
+ The data written to the stream does not appear in this
+ Clob until the stream is closed. <p>
+
+ When the stream is closed, if the value specified for <code>pos</code>
+ is greater than the length of the <code>CLOB</code> value, then
+ the <code>CLOB</code> value is extended in length to accept the
+ written characters and the undefined region up to <code>pos</code> is
+ filled with (char)0. <p>
+
+ Also, no attempt is made to ensure precise thread safety. Instead,
+ volatile member field and local variable snapshot isolation semantics
+ are implemented.  This is expected to eliminate most issues related
+ to race conditions, with the possible exception of concurrent
+ invocation of free(). <p>
+
+ In general, however, if an application may perform concurrent
+ JDBCClob modifications and the integrity of the application depends on
+ total order Clob modification semantics, then such operations
+ should be synchronized on an appropriate monitor.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setCharacterStream(long)" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position at which to start writing to the
+        <code>CLOB</code> value; The first position is 1
+<DT><B>Returns:</B><DD>a stream to which Unicode encoded characters can be written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value or if pos is less than 1
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getCharacterStream()"><CODE>getCharacterStream()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="truncate(long)"><!-- --></A><H3>
+truncate</H3>
+<PRE>
+public void <B>truncate</B>(long&nbsp;len)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Truncates the <code>CLOB</code> value that this <code>Clob</code>
+ designates to have a length of <code>len</code>
+ characters.
+ <p>
+ <b>Note:</b> If the value specified for <code>len</code>
+ is greater than the length of the <code>CLOB</code> value, then the
+ behavior is undefined. Some JDBC drivers may throw a
+ <code>SQLException</code> while other drivers may support this
+ operation.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0 this feature is fully supported. <p>
+
+ When built under JDK 1.6+ and the Clob instance is constructed as a
+ result of calling JDBCConnection.createClob(), this operation affects
+ only the client-side value; it has no effect upon a value stored in a
+ database because JDBCConnection.createClob() constructs disconnected,
+ initially empty Blob instances. To propogate the truncated clob value to
+ a database in this case, it is required to supply the Clob instance to
+ an updating or inserting setXXX method of a Prepared or Callable
+ Statement, or to supply the Blob instance to an updateXXX method of an
+ updateable ResultSet. <p>
+
+ <b>Implementation Notes:</b> <p>
+
+ HSQLDB throws an SQLException if the specified <tt>len</tt> is greater
+ than the value returned by <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#length()"><CODE>length</CODE></A>. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#truncate(long)" title="class or interface in java.sql">truncate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>len</CODE> - the length, in characters, to which the <code>CLOB</code> value
+        should be truncated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+            <code>CLOB</code> value or if len is less than 0
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="free()"><!-- --></A><H3>
+free</H3>
+<PRE>
+public void <B>free</B>()
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method frees the <code>Clob</code> object and releases the resources the resources
+ that it holds.  The object is invalid once the <code>free</code> method
+ is called.
+ <p>
+ After <code>free</code> has been called, any attempt to invoke a
+ method other than <code>free</code> will result in a <code>SQLException</code>
+ being thrown.  If <code>free</code> is called multiple times, the subsequent
+ calls to <code>free</code> are treated as a no-op.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#free()" title="class or interface in java.sql">free</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs releasing
+ the Clob's resources
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream(long, long)"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>(long&nbsp;pos,
+                                 long&nbsp;length)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
+ with the character specified by pos, which is length characters in length.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getCharacterStream(long, long)" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the offset to the first character of the partial value to
+ be retrieved.  The first character in the Clob is at position 1.<DD><CODE>length</CODE> - the length in characters of the partial value to be retrieved.
+<DT><B>Returns:</B><DD><code>Reader</code> through which the partial <code>Clob</code> value can be read.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if pos is less than 1 or if pos is greater than the number of
+ characters in the <code>Clob</code> or if pos + length is greater than the number of
+ characters in the <code>Clob</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCClob.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCClob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCClob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCClobClient.html b/doc/apidocs/org/hsqldb/jdbc/JDBCClobClient.html
new file mode 100644
index 0000000..cee2d11
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCClobClient.html
@@ -0,0 +1,703 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:45 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCClobClient (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCClobClient (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCClobClient.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCClobClient.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCClobClient.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCClobClient</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCClobClient</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCClobClient</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></DL>
+</PRE>
+
+<P>
+A wrapper for HSQLDB ClobData objects.
+
+ Instances of this class are returnd by calls to ResultSet methods.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.9.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>Fred Toussi (fredt@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#free()">free</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method frees the <code>Clob</code> object and releases the resources the resources
+ that it holds.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#getAsciiStream()">getAsciiStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>CLOB</code> value designated by this
+ <code>Clob</code> object as an ascii stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#getCharacterStream()">getCharacterStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>CLOB</code> value designated by this
+ <code>Clob</code> object as a <code>java.io.Reader</code> object (or
+ as a stream of characters).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#getCharacterStream(long, long)">getCharacterStream</A></B>(long&nbsp;pos,
+                   long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
+ with the character specified by pos, which is length characters in length.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#getSubString(long, int)">getSubString</A></B>(long&nbsp;pos,
+             int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a copy of the specified substring in the <code>CLOB</code>
+ value designated by this <code>Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#isClosed()">isClosed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#length()">length</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the number of characters in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#position(java.sql.Clob, long)">position</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;searchstr,
+         long&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the character position at which the specified
+ <code>Clob</code> object <code>searchstr</code> appears in this
+ <code>Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#position(java.lang.String, long)">position</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;searchstr,
+         long&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the character position at which the specified substring
+ <code>searchstr</code> appears in the SQL <code>CLOB</code> value
+ represented by this <code>Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#setAsciiStream(long)">setAsciiStream</A></B>(long&nbsp;pos)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a stream to be used to write Ascii characters to the
+ <code>CLOB</code> value that this <code>Clob</code> object represents,
+ starting at position <code>pos</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Writer.html?is-external=true" title="class or interface in java.io">Writer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#setCharacterStream(long)">setCharacterStream</A></B>(long&nbsp;pos)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a stream to be used to write a stream of Unicode characters
+ to the <code>CLOB</code> value that this <code>Clob</code> object
+ represents, at position <code>pos</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#setString(long, java.lang.String)">setString</A></B>(long&nbsp;pos,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;str)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes the given Java <code>String</code> to the <code>CLOB</code>
+ value that this <code>Clob</code> object designates at the position
+ <code>pos</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#setString(long, java.lang.String, int, int)">setString</A></B>(long&nbsp;pos,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;str,
+          int&nbsp;offset,
+          int&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes <code>len</code> characters of <code>str</code>, starting at
+ character <code>offset</code>, to the <code>CLOB</code> value that
+ this <code>Clob</code> represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html#truncate(long)">truncate</A></B>(long&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Truncates the <code>CLOB</code> value that this <code>Clob</code>
+ designates to have a length of <code>len</code> characters.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getAsciiStream()"><!-- --></A><H3>
+getAsciiStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getAsciiStream</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the <code>CLOB</code> value designated by this
+ <code>Clob</code> object as an ascii stream.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getAsciiStream()" title="class or interface in java.sql">getAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>java.io.InputStream</code> object containing the
+   <code>CLOB</code> data
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream()"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the <code>CLOB</code> value designated by this
+ <code>Clob</code> object as a <code>java.io.Reader</code> object (or
+ as a stream of characters).
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getCharacterStream()" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object containing the
+   <code>CLOB</code> data
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSubString(long, int)"><!-- --></A><H3>
+getSubString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getSubString</B>(long&nbsp;pos,
+                           int&nbsp;length)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a copy of the specified substring in the <code>CLOB</code>
+ value designated by this <code>Clob</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getSubString(long, int)" title="class or interface in java.sql">getSubString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the first character of the substring to be extracted. The
+   first character is at position 1.<DD><CODE>length</CODE> - the number of consecutive characters to be copied
+<DT><B>Returns:</B><DD>a <code>String</code> that is the specified substring in the
+   <code>CLOB</code> value designated by this <code>Clob</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="length()"><!-- --></A><H3>
+length</H3>
+<PRE>
+public long <B>length</B>()
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the number of characters in the <code>CLOB</code> value
+ designated by this <code>Clob</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#length()" title="class or interface in java.sql">length</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>length of the <code>CLOB</code> in characters
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the length of the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="position(java.lang.String, long)"><!-- --></A><H3>
+position</H3>
+<PRE>
+public long <B>position</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;searchstr,
+                     long&nbsp;start)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the character position at which the specified substring
+ <code>searchstr</code> appears in the SQL <code>CLOB</code> value
+ represented by this <code>Clob</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#position(java.lang.String, long)" title="class or interface in java.sql">position</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>searchstr</CODE> - the substring for which to search<DD><CODE>start</CODE> - the position at which to begin searching; the first
+   position is 1
+<DT><B>Returns:</B><DD>the position at which the substring appears or -1 if it is
+   not present; the first position is 1
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="position(java.sql.Clob, long)"><!-- --></A><H3>
+position</H3>
+<PRE>
+public long <B>position</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;searchstr,
+                     long&nbsp;start)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the character position at which the specified
+ <code>Clob</code> object <code>searchstr</code> appears in this
+ <code>Clob</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#position(java.sql.Clob, long)" title="class or interface in java.sql">position</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>searchstr</CODE> - the <code>Clob</code> object for which to search<DD><CODE>start</CODE> - the position at which to begin searching; the first
+   position is 1
+<DT><B>Returns:</B><DD>the position at which the <code>Clob</code> object appears or
+   -1 if it is not present; the first position is 1
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAsciiStream(long)"><!-- --></A><H3>
+setAsciiStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A> <B>setAsciiStream</B>(long&nbsp;pos)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a stream to be used to write Ascii characters to the
+ <code>CLOB</code> value that this <code>Clob</code> object represents,
+ starting at position <code>pos</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setAsciiStream(long)" title="class or interface in java.sql">setAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position at which to start writing to this
+   <code>CLOB</code> object
+<DT><B>Returns:</B><DD>the stream to which ASCII encoded characters can be written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream(long)"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Writer.html?is-external=true" title="class or interface in java.io">Writer</A> <B>setCharacterStream</B>(long&nbsp;pos)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a stream to be used to write a stream of Unicode characters
+ to the <code>CLOB</code> value that this <code>Clob</code> object
+ represents, at position <code>pos</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setCharacterStream(long)" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position at which to start writing to the
+   <code>CLOB</code> value
+<DT><B>Returns:</B><DD>a stream to which Unicode encoded characters can be written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setString(long, java.lang.String)"><!-- --></A><H3>
+setString</H3>
+<PRE>
+public int <B>setString</B>(long&nbsp;pos,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;str)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Writes the given Java <code>String</code> to the <code>CLOB</code>
+ value that this <code>Clob</code> object designates at the position
+ <code>pos</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setString(long, java.lang.String)" title="class or interface in java.sql">setString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position at which to start writing to the
+   <code>CLOB</code> value that this <code>Clob</code> object
+   represents<DD><CODE>str</CODE> - the string to be written to the <code>CLOB</code> value
+   that this <code>Clob</code> designates
+<DT><B>Returns:</B><DD>the number of characters written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setString(long, java.lang.String, int, int)"><!-- --></A><H3>
+setString</H3>
+<PRE>
+public int <B>setString</B>(long&nbsp;pos,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;str,
+                     int&nbsp;offset,
+                     int&nbsp;len)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Writes <code>len</code> characters of <code>str</code>, starting at
+ character <code>offset</code>, to the <code>CLOB</code> value that
+ this <code>Clob</code> represents.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setString(long, java.lang.String, int, int)" title="class or interface in java.sql">setString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the position at which to start writing to this
+   <code>CLOB</code> object<DD><CODE>str</CODE> - the string to be written to the <code>CLOB</code> value
+   that this <code>Clob</code> object represents<DD><CODE>offset</CODE> - the offset into <code>str</code> to start reading the
+   characters to be written<DD><CODE>len</CODE> - the number of characters to be written
+<DT><B>Returns:</B><DD>the number of characters written
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="truncate(long)"><!-- --></A><H3>
+truncate</H3>
+<PRE>
+public void <B>truncate</B>(long&nbsp;len)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Truncates the <code>CLOB</code> value that this <code>Clob</code>
+ designates to have a length of <code>len</code> characters.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#truncate(long)" title="class or interface in java.sql">truncate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>len</CODE> - the length, in bytes, to which the <code>CLOB</code> value
+   should be truncated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error accessing the
+   <code>CLOB</code> value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="free()"><!-- --></A><H3>
+free</H3>
+<PRE>
+public void <B>free</B>()
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method frees the <code>Clob</code> object and releases the resources the resources
+ that it holds.  The object is invalid once the <code>free</code> method
+ is called.
+ <p>
+ After <code>free</code> has been called, any attempt to invoke a
+ method other than <code>free</code> will result in a <code>SQLException</code>
+ being thrown.  If <code>free</code> is called multiple times, the subsequent
+ calls to <code>free</code> are treated as a no-op.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#free()" title="class or interface in java.sql">free</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs releasing
+ the Clob's resources
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream(long, long)"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>(long&nbsp;pos,
+                                 long&nbsp;length)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
+ with the character specified by pos, which is length characters in length.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getCharacterStream(long, long)" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pos</CODE> - the offset to the first character of the partial value to
+ be retrieved.  The first character in the Clob is at position 1.<DD><CODE>length</CODE> - the length in characters of the partial value to be retrieved.
+<DT><B>Returns:</B><DD><code>Reader</code> through which the partial <code>Clob</code> value can be read.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if pos is less than 1 or if pos is greater than the number of
+ characters in the <code>Clob</code> or if pos + length is greater than the number of
+ characters in the <code>Clob</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isClosed()"><!-- --></A><H3>
+isClosed</H3>
+<PRE>
+public boolean <B>isClosed</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCClobClient.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCClobClient.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCClobClient.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCColumnMetaData.html b/doc/apidocs/org/hsqldb/jdbc/JDBCColumnMetaData.html
new file mode 100644
index 0000000..c351ee2
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCColumnMetaData.html
@@ -0,0 +1,674 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:45 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCColumnMetaData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCColumnMetaData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCColumnMetaData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCColumnMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCColumnMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCColumnMetaData</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCColumnMetaData</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>JDBCColumnMetaData</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+Provides a site for holding the ResultSetMetaData for individual ResultSet
+ columns. In 2.0 it is implemented as a simple data structure derived
+ from calls to JDBCResultSetMetaData methods.
+ purposes.<p>
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>HSQLDB 1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#catalogName">catalogName</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column's table's catalog name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#columnClassName">columnClassName</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The fully-qualified name of the Java class whose instances are
+ manufactured if the method ResultSet.getObject is called to retrieve
+ a value from the column.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#columnDisplaySize">columnDisplaySize</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column's normal max width in chars.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#columnLabel">columnLabel</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The suggested column title for use in printouts and displays.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#columnName">columnName</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column's name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#columnType">columnType</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column's SQL type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isAutoIncrement">isAutoIncrement</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Whether the value of the column are automatically numbered.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isCaseSensitive">isCaseSensitive</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Whether the column's value's case matters.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isCurrency">isCurrency</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Whether the values in the column are cash values.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isDefinitelyWritable">isDefinitelyWritable</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Whether a write on the column will definitely succeed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isNullable">isNullable</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The nullability of values in the column.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isReadOnly">isReadOnly</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Whether the column's values are definitely not writable.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isSearchable">isSearchable</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Whether the column's values can be used in a where clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isSigned">isSigned</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Whether values in the column are signed numbers.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#isWritable">isWritable</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Whether it is possible for a write on the column to succeed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#precision">precision</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column's value's number of decimal digits.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#scale">scale</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column's value's number of digits to right of the decimal point.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#schemaName">schemaName</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column's table's schema.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#tableName">tableName</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column's table's name.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#JDBCColumnMetaData()">JDBCColumnMetaData</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a String representation of this object.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="catalogName"><!-- --></A><H3>
+catalogName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>catalogName</B></PRE>
+<DL>
+<DD>The column's table's catalog name.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="columnClassName"><!-- --></A><H3>
+columnClassName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>columnClassName</B></PRE>
+<DL>
+<DD>The fully-qualified name of the Java class whose instances are
+ manufactured if the method ResultSet.getObject is called to retrieve
+ a value from the column.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="columnDisplaySize"><!-- --></A><H3>
+columnDisplaySize</H3>
+<PRE>
+public int <B>columnDisplaySize</B></PRE>
+<DL>
+<DD>The column's normal max width in chars.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="columnLabel"><!-- --></A><H3>
+columnLabel</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>columnLabel</B></PRE>
+<DL>
+<DD>The suggested column title for use in printouts and displays.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="columnName"><!-- --></A><H3>
+columnName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>columnName</B></PRE>
+<DL>
+<DD>The column's name.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="columnType"><!-- --></A><H3>
+columnType</H3>
+<PRE>
+public int <B>columnType</B></PRE>
+<DL>
+<DD>The column's SQL type.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="precision"><!-- --></A><H3>
+precision</H3>
+<PRE>
+public int <B>precision</B></PRE>
+<DL>
+<DD>The column's value's number of decimal digits.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="scale"><!-- --></A><H3>
+scale</H3>
+<PRE>
+public int <B>scale</B></PRE>
+<DL>
+<DD>The column's value's number of digits to right of the decimal point.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="schemaName"><!-- --></A><H3>
+schemaName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>schemaName</B></PRE>
+<DL>
+<DD>The column's table's schema.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="tableName"><!-- --></A><H3>
+tableName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>tableName</B></PRE>
+<DL>
+<DD>The column's table's name.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isAutoIncrement"><!-- --></A><H3>
+isAutoIncrement</H3>
+<PRE>
+public boolean <B>isAutoIncrement</B></PRE>
+<DL>
+<DD>Whether the value of the column are automatically numbered.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isCaseSensitive"><!-- --></A><H3>
+isCaseSensitive</H3>
+<PRE>
+public boolean <B>isCaseSensitive</B></PRE>
+<DL>
+<DD>Whether the column's value's case matters.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isCurrency"><!-- --></A><H3>
+isCurrency</H3>
+<PRE>
+public boolean <B>isCurrency</B></PRE>
+<DL>
+<DD>Whether the values in the column are cash values.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isDefinitelyWritable"><!-- --></A><H3>
+isDefinitelyWritable</H3>
+<PRE>
+public boolean <B>isDefinitelyWritable</B></PRE>
+<DL>
+<DD>Whether a write on the column will definitely succeed.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isNullable"><!-- --></A><H3>
+isNullable</H3>
+<PRE>
+public int <B>isNullable</B></PRE>
+<DL>
+<DD>The nullability of values in the column.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isReadOnly"><!-- --></A><H3>
+isReadOnly</H3>
+<PRE>
+public boolean <B>isReadOnly</B></PRE>
+<DL>
+<DD>Whether the column's values are definitely not writable.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isSearchable"><!-- --></A><H3>
+isSearchable</H3>
+<PRE>
+public boolean <B>isSearchable</B></PRE>
+<DL>
+<DD>Whether the column's values can be used in a where clause.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isSigned"><!-- --></A><H3>
+isSigned</H3>
+<PRE>
+public boolean <B>isSigned</B></PRE>
+<DL>
+<DD>Whether values in the column are signed numbers.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="isWritable"><!-- --></A><H3>
+isWritable</H3>
+<PRE>
+public boolean <B>isWritable</B></PRE>
+<DL>
+<DD>Whether it is possible for a write on the column to succeed.
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCColumnMetaData()"><!-- --></A><H3>
+JDBCColumnMetaData</H3>
+<PRE>
+public <B>JDBCColumnMetaData</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>toString</B>()</PRE>
+<DL>
+<DD>Retrieves a String representation of this object.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a Sring representation of this object</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCColumnMetaData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCColumnMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCColumnMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCConnection.html b/doc/apidocs/org/hsqldb/jdbc/JDBCConnection.html
new file mode 100644
index 0000000..5610af8
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCConnection.html
@@ -0,0 +1,3601 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:45 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCConnection (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCConnection (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCConnection.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCConnection.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCConnection.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCConnection</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCConnection</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCConnection</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></DL>
+</PRE>
+
+<P>
+<!-- start generic documentation -->
+
+ <P>A connection (session) with a specific
+ database. SQL statements are executed and results are returned
+ within the context of a connection.
+ <P>
+ A <code>Connection</code> object's database is able to provide information
+ describing its tables, its supported SQL grammar, its stored
+ procedures, the capabilities of this connection, and so on. This
+ information is obtained with the <code>getMetaData</code> method.
+
+ <P>(JDBC4 clarification:)
+ <P><B>Note:</B> When configuring a <code>Connection</code>, JDBC applications
+  should use the appropritate <code>Connection</code> method such as
+  <code>setAutoCommit</code> or <code>setTransactionIsolation</code>.
+  Applications should not invoke SQL commands directly to change the connection's
+   configuration when there is a JDBC method available.  By default a <code>Connection</code> object is in
+ auto-commit mode, which means that it automatically commits changes
+ after executing each statement. If auto-commit mode has been
+ disabled, the method <code>commit</code> must be called explicitly in
+ order to commit changes; otherwise, database changes will not be saved.
+ <P>
+ A new <code>Connection</code> object created using the JDBC 2.1 core API
+ has an initially empty type map associated with it. A user may enter a
+ custom mapping for a UDT in this type map.
+ When a UDT is retrieved from a data source with the
+ method <code>ResultSet.getObject</code>, the <code>getObject</code> method
+ will check the connection's type map to see if there is an entry for that
+ UDT.  If so, the <code>getObject</code> method will map the UDT to the
+ class indicated.  If there is no entry, the UDT will be mapped using the
+ standard mapping.
+ <p>
+ A user may create a new type map, which is a <code>java.util.Map</code>
+ object, make an entry in it, and pass it to the <code>java.sql</code>
+ methods that can perform custom mapping.  In this case, the method
+ will use the given type map instead of the one associated with
+ the connection.
+ <p>
+ For example, the following code fragment specifies that the SQL
+ type <code>ATHLETES</code> will be mapped to the class
+ <code>Athletes</code> in the Java programming language.
+ The code fragment retrieves the type map for the <code>Connection
+ </code> object <code>con</code>, inserts the entry into it, and then sets
+ the type map with the new entry as the connection's type map.
+ <pre>
+      java.util.Map map = con.getTypeMap();
+      map.put("mySchemaName.ATHLETES", Class.forName("Athletes"));
+      con.setTypeMap(map);
+ </pre>
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ To get a <code>Connection</code> to an HSQLDB database, the
+ following code may be used (updated to reflect the most recent
+ recommendations): <p>
+
+ <hr>
+
+ When using HSQLDB, the database connection <b>&lt;url&gt;</b> must start with
+ <b>'jdbc:hsqldb:'</b><p>
+
+ Since 1.7.2, connection properties (&lt;key-value-pairs&gt;) may be appended
+ to the database connection <b>&lt;url&gt;</b>, using the form: <p>
+
+ <blockquote>
+      <b>'&lt;url&gt;[;key=value]*'</b>
+ </blockquote> <p>
+
+ Also since 1.7.2, the allowable forms of the HSQLDB database connection
+ <b>&lt;url&gt;</b> have been extended.  However, all legacy forms continue
+ to work, with unchanged semantics.  The extensions are as described in the
+ following material. <p>
+
+ <hr>
+
+ <b>Network Server Database Connections:</b> <p>
+
+ The <A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><CODE>Server</CODE></A> database connection <b>&lt;url&gt;</b>
+ takes one of the two following forms: <p>
+
+ <div class="GeneralExample">
+ <ol>
+ <li> <b>'jdbc:hsqldb:hsql://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
+
+ <li> <b>'jdbc:hsqldb:hsqls://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
+         (with TLS).
+ </ol>
+ </div> <p>
+
+ The <A HREF="../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server"><CODE>WebServer</CODE></A> database connection <b>&lt;url&gt;</b>
+ takes one of two following forms: <p>
+
+ <div class="GeneralExample">
+ <ol>
+ <li> <b>'jdbc:hsqldb:http://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
+
+ <li> <b>'jdbc:hsqldb:https://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
+      (with TLS).
+ </ol>
+ </div><p>
+
+ In both network server database connection <b>&lt;url&gt;</b> forms, the
+ optional <b>&lt;alias&gt;</b> component is used to identify one of possibly
+ several database instances available at the indicated host and port.  If the
+ <b>&lt;alias&gt;</b> component is omitted, then a connection is made to the
+ network server's default database instance, if such an instance is
+ available. <p>
+
+ For more information on server configuration regarding mounting multiple
+ databases and assigning them <b>&lt;alias&gt;</b> values, please read the
+ Java API documentation for <A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><CODE>Server</CODE></A> and related
+ chapters in the general documentation, especially the <em>Advanced Users
+ Guide</em>. <p>
+
+ <hr>
+
+ <b>Transient, In-Process Database Connections:</b> <p>
+
+ The 100% in-memory (transient, in-process) database connection
+ <b>&lt;url&gt;</b> takes one of the two following forms: <p>
+
+ <div class="GeneralExample">
+ <ol>
+ <li> <b>'jdbc:hsqldb:.[&lt;key-value-pairs&gt;]'</b>
+     (the legacy form, extended)
+
+ <li> <b>'jdbc:hsqldb:mem:&lt;alias&gt;[&lt;key-value-pairs&gt;]'</b>
+      (the new form)
+ </ol>
+ </div> <p>
+
+ The driver converts the supplied <b>&lt;alias&gt;</b> component to
+ Local.ENGLISH lower case and uses the resulting character sequence as the
+ key used to look up a <b>mem:</b> protocol database instance amongst the
+ collection of all such instances already in existence within the current
+ class loading context in the current JVM. If no such instance exists, one
+ <em>may</em> be automatically created and mapped to the <b>&lt;alias&gt;</b>,
+ as governed by the <b>'ifexists=true|false'</b> connection property. <p>
+
+ The rationale for converting the supplied <b>&lt;alias&gt;</b> component to
+ lower case is to provide consistency with the behavior of <b>res:</b>
+ protocol database connection <b>&lt;url&gt;</b>s, explained further on in
+ this overview.
+
+ <hr>
+
+ <b>Persistent, In-Process Database Connections:</b> <p>
+
+ The standalone (persistent, in-process) database connection
+ <b>&lt;url&gt;</b> takes one of the three following forms: <p>
+
+ <div class="GeneralExample">
+ <ol>
+ <li> <b>'jdbc:hsqldb:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
+      (the legacy form, extended)
+
+ <li> <b>'jdbc:hsqldb:file:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
+      (same semantics as the legacy form)
+
+ <li> <b>'jdbc:hsqldb:res:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
+      (new form with 'files_in_jar' semantics)
+ </ol>
+ </div> <p>
+
+ For the persistent, in-process database connection <b>&lt;url&gt;</b>,
+ the <b>&lt;path&gt;</b> component is the path prefix common to all of
+ the files that compose the database. <p>
+
+ From 1.7.2, although other files may be involved (such as transient working
+ files and/or TEXT table CSV data source files), the essential set that may,
+ at any particular point in time, compose an HSQLDB database is: <p>
+
+ <div class="GeneralExample">
+ <ul>
+ <li>&lt;path&gt;.properties
+ <li>&lt;path&gt;.script
+ <li>&lt;path&gt;.log
+ <li>&lt;path&gt;.data
+ <li>&lt;path&gt;.backup
+ <li>&lt;path&gt;.lck
+ </ul>
+ </div> <p>
+
+ For example: <b>'jdbc:hsqldb:file:test'</b> connects to a database
+ composed of some subset of the files listed above, where the expansion
+ of <b>&lt;path&gt;</b> is <b>'test'</b> prefixed with the canonical path of
+ the JVM's effective working directory at the time the designated database
+ is first opened in-process. <p>
+
+ Be careful to note that this canonical expansion of <b>&lt;path&gt;</b> is
+ cached by the driver until JVM exit. So, although legacy JVMs tend to fix
+ the reported effective working directory at the one noted upon JVM startup,
+ there is no guarantee that modern JVMs will continue to uphold this
+ behaviour.  What this means is there is effectively no guarantee into the
+ future that a relative <b>file:</b> protocol database connection
+ <b>&lt;url&gt;</b> will connect to the same database instance for the life
+ of the JVM.  To avoid any future ambigutity issues, it is probably a best
+ practice for clients to attempt to pre-canonicalize the <b>&lt;path&gt;</b>
+ component of <b>file:</b> protocol database connection* <b>&lt;url&gt;</b>s.
+ <p>
+
+ Under <em>Windows</em> <sup><font size="-2">TM</font> </sup>, <b>
+ 'jdbc:hsqldb:file:c:\databases\test'</b> connects to a database located
+ on drive <b>'C:'</b> in the directory <b>'databases'</b>, composed
+ of some subset of the files: <p>
+
+ <pre class="GeneralExample">
+ C:\
+ +--databases\
+    +--test.properties
+    +--test.script
+    +--test.log
+    +--test.data
+    +--test.backup
+    +--test.lck
+ </pre>
+
+ Under most variations of UNIX, <b>'jdbc:hsqldb:file:/databases/test'</b>
+ connects to a database located in the directory <b>'databases'</b> directly
+ under root, once again composed of some subset of the files: <p>
+
+ <pre class="GeneralExample">
+
+ +--databases
+    +--test.properties
+    +--test.script
+    +--test.log
+    +--test.data
+    +--test.backup
+    +--test.lck
+ </pre>
+
+ <b>Some Guidelines:</b> <p>
+
+ <ol>
+ <li> Both relative and absolute database file paths are supported. <p>
+
+ <li> Relative database file paths can be specified in a platform independent
+      manner as: <b>'[dir1/dir2/.../dirn/]&lt;file-name-prefix&gt;'</b>. <p>
+
+ <li> Specification of absolute file paths is operating-system specific.<br>
+      Please read your OS file system documentation. <p>
+
+ <li> Specification of network mounts may be operating-system specific.<br>
+      Please read your OS file system documentation. <p>
+
+ <li> Special care may be needed w.r.t. file path specifications
+      containing whitespace, mixed-case, special characters and/or
+      reserved file names.<br>
+      Please read your OS file system documentation. <p>
+ </ol> <p>
+
+ <b>Note:</b> Versions of HSQLDB previous to 1.7.0 did not support creating
+ directories along the file path specified in the persistent, in-process mode
+ database connection <b>&lt;url&gt;</b> form, in the case that they did
+ not already exist.  Starting with HSQLDB 1.7.0, directories <i>will</i>
+ be created if they do not already exist., but only if HSQLDB is built under
+ a version of the compiler greater than JDK 1.1.x. <p>
+
+ <hr>
+
+ <b>res: protocol Connections:</b><p>
+
+ The <b>'jdbc:hsqldb:res:&lt;path&gt;'</b> database connection
+ <b>&lt;url&gt;</b> has different semantics than the
+ <b>'jdbc:hsqldb:file:&lt;path&gt;'</b> form. The semantics are similar to
+ those of a <b>'files_readonly'</b> database, but with some additional
+ points to consider. <p>
+
+ Specifically, the <b>'&lt;path&gt;'</b> component of a <b>res:</b> protocol
+ database connection <b>&lt;url&gt;</b> is first converted to lower case
+ with <tt>Locale.ENGLISH</tt> and only then used to obtain resource URL
+ objects, which in turn are used to read the database files as resources on
+ the class path. <p>
+
+ Due to lower case conversion by the driver, <b>res:</b> <b>'&lt;path&gt;'</b>
+ components <em>never</em> find jar resources stored with
+ <tt>Locale.ENGLISH</tt> mixed case paths. The rationale for converting to
+ lower case is that not all pkzip implementations guarantee path case is
+ preserved when archiving resources, and conversion to lower case seems to
+ be the most common occurrence (although there is also no actual guarantee
+ that the conversion is <tt>Locale.ENGLISH</tt>).<p>
+
+ More importantly, <b>res:</b> <b>'&lt;path&gt;'</b> components <em>must</em>
+ point only to resources contained in one or more jars on the class
+ path. That is, only resources having the jar sub-protocol are considered
+ valid. <p>
+
+ This restriction is enforced to avoid the unfortunate situation in which,
+ because <b>res:</b> database instances do not create a <b>&lt;path&gt;</b>.lck
+ file (they are strictly files-read-only) and because the <b>&lt;path&gt;</b>
+ components of <b>res:</b> and <b>file:</b> database <tt>URI</tt>s are not
+ checked for file system equivalence, it is possible for the same database
+ files to be accessed concurrently by both <b>file:</b> and <b>res:</b>
+ database instances. That is, without this restriction, it is possible that
+ <b>&lt;path&gt;</b>.data and <b>&lt;path&gt;</b>.properties file content may
+ be written by a <b>file:</b> database instance without the knowlege or
+ cooperation of a <b>res:</b> database instance open on the same files,
+ potentially resulting in unexpected database errors, inconsistent operation
+ and/or data corruption. <p>
+
+ In short, a <b>res:</b> type database connection <b>&lt;url&gt;</b> is
+ designed specifically to connect to a <b>'files_in_jar'</b> mode database
+ instance, which in turn is designed specifically to operate under
+ <em>Java WebStart</em><sup><font size="-2">TM</font></sup> and
+ <em>Java Applet</em><sup><font size="-2">TM</font></sup>configurations,
+ where co-locating the database files in the jars that make up the
+ <em>WebStart</em> application or Applet avoids the need for special security
+ configuration or code signing. <p>
+
+ <b>Note:</b> Since it is difficult and often nearly impossible to determine
+ or control at runtime from where all classes are being loaded or which class
+ loader is doing the loading (and hence how relative path specifications
+ are resolved) under <b>'files_in_jar'</b> semantics, the <b>&lt;path&gt;</b>
+ component of the <b>res:</b> database connection <b>&lt;url&gt;</b> is always
+ taken to be relative to the default package and resource URL resolution is
+ always performed using the ClassLoader that loads the
+ org.hsqldb.persist.Logger class. That is, if the <b>&lt;path&gt;</b>
+ component does not start with '/', then'/' is prepended when obtaining the
+ resource URLs used to read the database files, and only the effective class
+ path of org.hsqldb.persist.Logger's ClassLoader is searched. <p>
+
+ <hr>
+
+ For more information about HSQLDB file structure, various database modes
+ and other attributes such as those controlled through the HSQLDB properties
+ files, please read the general documentation, especially the Advanced Users
+ Guide. <p>
+
+ <hr>
+
+ <b>JRE 1.1.x Notes:</b> <p>
+
+ In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ versions of JDBC depends on the JDK version used for compiling and building
+ HSQLDB.<p>
+
+ Since 1.7.0, it is possible to build the product so that
+ all JDBC 2 methods can be called while executing under the version 1.1.x
+ <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ However, in addition to this technique requiring explicit casts to the
+ org.hsqldb.jdbc.* classes, some of the method calls also require
+ <code>int</code> values that are defined only in the JDBC 2 or greater
+ version of the <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A> interface.  For this
+ reason, when the product is compiled under JDK 1.1.x, these values are
+ defined in <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A>. <p>
+
+ In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ JDBC 2+ <code>ResultSet</code> values can be achieved by referring
+ to them in parameter specifications and return value comparisons,
+ respectively, as follows: <p>
+
+ <pre class="JavaCodeExample">
+ JDBCResultSet.FETCH_FORWARD
+ JDBCResultSet.TYPE_FORWARD_ONLY
+ JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ JDBCResultSet.CONCUR_READ_ONLY
+ // etc.
+ </pre>
+
+ However, please note that code written to use HSQLDB JDBC 2 features under
+ JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
+ also note that this feature is offered solely as a convenience to developers
+ who must work under JDK 1.1.x due to operating constraints, yet wish to
+ use some of the more advanced features available under the JDBC 2
+ specification. <p>
+
+ <hr>
+
+ <b>JDBC 4.0 Notes:</b><p>
+
+ Starting with JDBC 4.0 (JDK 1.6), the <code>DriverManager</code> methods
+ <code>getConnection</code> and <code>getDrivers</code> have been
+ enhanced to support the Java Standard Edition Service Provider mechanism.
+ When built under a Java runtime that supports JDBC 4.0, HSQLDB distribution
+ jars containing the Driver implementatiton also include the file
+ <code>META-INF/services/java.sql.Driver</code>. This file contains the fully
+ qualified class name ('org.hsqldb.jdbc.JDBCDriver') of the HSQLDB implementation
+ of <code>java.sql.Driver</code>. <p>
+
+ Hence, under JDBC 4.0 or greater, applications no longer need to explictly
+ load the HSQLDB JDBC driver using <code>Class.forName()</code>. Of course,
+ existing programs which do load JDBC drivers using
+ <code>Class.forName()</code> will continue to work without modification. <p>
+
+ <hr>
+
+ (fredt@users)<br>
+ (boucherb@users)<p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><CODE>JDBCDriver</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><CODE>JDBCStatement</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><CODE>JDBCParameterMetaData</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><CODE>JDBCCallableStatement</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><CODE>JDBCDatabaseMetaData</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DriverManager.html?is-external=true#getConnection(java.lang.String, java.util.Properties)" title="class or interface in java.sql"><CODE>DriverManager.getConnection(java.lang.String, java.util.Properties)</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql"><CODE>Statement</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql"><CODE>DatabaseMetaData</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.sql.Connection"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#TRANSACTION_NONE" title="class or interface in java.sql">TRANSACTION_NONE</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#TRANSACTION_READ_COMMITTED" title="class or interface in java.sql">TRANSACTION_READ_COMMITTED</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#TRANSACTION_READ_UNCOMMITTED" title="class or interface in java.sql">TRANSACTION_READ_UNCOMMITTED</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#TRANSACTION_REPEATABLE_READ" title="class or interface in java.sql">TRANSACTION_REPEATABLE_READ</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#TRANSACTION_SERIALIZABLE" title="class or interface in java.sql">TRANSACTION_SERIALIZABLE</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#JDBCConnection(org.hsqldb.persist.HsqlProperties)">JDBCConnection</A></B>(org.hsqldb.persist.HsqlProperties&nbsp;props)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new external <code>Connection</code> to an HSQLDB
+ <code>Database</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#JDBCConnection(org.hsqldb.SessionInterface)">JDBCConnection</A></B>(org.hsqldb.SessionInterface&nbsp;c)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs an <code>INTERNAL</code> <code>Connection</code>,
+ using the specified <CODE>SessionInterface</CODE>.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#clearWarnings()">clearWarnings</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clears all warnings reported for this <code>Connection</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#close()">close</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Releases this <code>Connection</code> object's database and JDBC resources
+ immediately instead of waiting for them to be automatically released.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#commit()">commit</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Makes all changes made since the previous
+ commit/rollback permanent and releases any database locks
+ currently held by this <code>Connection</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createArrayOf(java.lang.String, java.lang.Object[])">createArrayOf</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;elements)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Factory method for creating Array objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createBlob()">createBlob</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs an object that implements the <code>Blob</code> interface.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createClob()">createClob</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs an object that implements the <code>Clob</code> interface.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createNClob()">createNClob</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs an object that implements the <code>NClob</code> interface.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createSQLXML()">createSQLXML</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs an object that implements the <code>SQLXML</code> interface.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createStatement()">createStatement</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>Statement</code> object for sending
+ SQL statements to the database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createStatement(int, int)">createStatement</A></B>(int&nbsp;resultSetType,
+                int&nbsp;resultSetConcurrency)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>Statement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createStatement(int, int, int)">createStatement</A></B>(int&nbsp;resultSetType,
+                int&nbsp;resultSetConcurrency,
+                int&nbsp;resultSetHoldability)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>Statement</code> object that will generate
+ <code>ResultSet</code> objects with the given type, concurrency,
+ and holdability.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Struct.html?is-external=true" title="class or interface in java.sql">Struct</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createStruct(java.lang.String, java.lang.Object[])">createStruct</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Factory method for creating Struct objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getAutoCommit()">getAutoCommit</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the current auto-commit mode for this <code>Connection</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getCatalog()">getCatalog</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves this <code>Connection</code> object's current catalog name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getClientInfo()">getClientInfo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a list containing the name and current value of each client info
+ property supported by the driver.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getClientInfo(java.lang.String)">getClientInfo</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the value of the client info property specified by name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()">getHoldability</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the current holdability of <code>ResultSet</code> objects
+ created using this <code>Connection</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getMetaData()">getMetaData</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a <code>DatabaseMetaData</code> object that contains
+ metadata about the database to which this
+ <code>Connection</code> object represents a connection.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getTransactionIsolation()">getTransactionIsolation</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves this <code>Connection</code> object's current
+ transaction isolation level.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getTypeMap()">getTypeMap</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>Map</code> object associated with this
+ <code>Connection</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getWarnings()">getWarnings</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the first warning reported by calls on this
+ <code>Connection</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#isClosed()">isClosed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this <code>Connection</code> object has been
+ closed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#isReadOnly()">isReadOnly</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this <code>Connection</code>
+ object is in read-only mode.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#isValid(int)">isValid</A></B>(int&nbsp;timeout)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the connection has not been closed and is still valid.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#isWrapperFor(java.lang.Class)">isWrapperFor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#nativeSQL(java.lang.String)">nativeSQL</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Converts the given SQL statement into the system's native SQL grammar.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String)">prepareCall</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>CallableStatement</code> object for calling
+ database stored procedures.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String, int, int)">prepareCall</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+            int&nbsp;resultSetType,
+            int&nbsp;resultSetConcurrency)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>CallableStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String, int, int, int)">prepareCall</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+            int&nbsp;resultSetType,
+            int&nbsp;resultSetConcurrency,
+            int&nbsp;resultSetHoldability)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>CallableStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String)">prepareStatement</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>PreparedStatement</code> object for sending
+ parameterized SQL statements to the database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int)">prepareStatement</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                 int&nbsp;autoGeneratedKeys)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a default <code>PreparedStatement</code> object that has
+ the capability to retrieve auto-generated keys.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int[])">prepareStatement</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                 int[]&nbsp;columnIndexes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a default <code>PreparedStatement</code> object capable
+ of returning the auto-generated keys designated by the given array.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int, int)">prepareStatement</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                 int&nbsp;resultSetType,
+                 int&nbsp;resultSetConcurrency)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>PreparedStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int, int, int)">prepareStatement</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                 int&nbsp;resultSetType,
+                 int&nbsp;resultSetConcurrency,
+                 int&nbsp;resultSetHoldability)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a <code>PreparedStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type, concurrency,
+ and holdability.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, java.lang.String[])">prepareStatement</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a default <code>PreparedStatement</code> object capable
+ of returning the auto-generated keys designated by the given array.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#releaseSavepoint(java.sql.Savepoint)">releaseSavepoint</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A>&nbsp;savepoint)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes the specified <code>Savepoint</code> (JDBC4 Clarification:) and subsequent <code>Savepoint</code> objects from the current
+ transaction.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#reset()">reset</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Resets this connection so it can be used again.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#rollback()">rollback</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Undoes all changes made in the current transaction
+ and releases any database locks currently held
+ by this <code>Connection</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#rollback(java.sql.Savepoint)">rollback</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A>&nbsp;savepoint)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Undoes all changes made after the given <code>Savepoint</code> object
+ was set.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setAutoCommit(boolean)">setAutoCommit</A></B>(boolean&nbsp;autoCommit)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets this connection's auto-commit mode to the given state.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setCatalog(java.lang.String)">setCatalog</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the given catalog name in order to select
+ a subspace of this <code>Connection</code> object's database
+ in which to work.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setClientInfo(java.util.Properties)">setClientInfo</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A>&nbsp;properties)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the connection's client info properties.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setClientInfo(java.lang.String, java.lang.String)">setClientInfo</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the client info property specified by name to the
+ value specified by value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setHoldability(int)">setHoldability</A></B>(int&nbsp;holdability)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 Clarification:)
+ Changes the default holdability of <code>ResultSet</code> objects
+ created using this <code>Connection</code> object to the given
+ holdability.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setReadOnly(boolean)">setReadOnly</A></B>(boolean&nbsp;readOnly)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Puts this connection in read-only mode as a hint to the driver to enable
+ database optimizations.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setSavepoint()">setSavepoint</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates an unnamed savepoint in the current transaction and
+ returns the new <code>Savepoint</code> object that represents it.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setSavepoint(java.lang.String)">setSavepoint</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a savepoint with the given name in the current transaction
+ and returns the new <code>Savepoint</code> object that represents it.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setTransactionIsolation(int)">setTransactionIsolation</A></B>(int&nbsp;level)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>Connection</code> object to the one given.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setTypeMap(java.util.Map)">setTypeMap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Installs the given <code>TypeMap</code> object as the type map for
+ this <code>Connection</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T&gt; T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#unwrap(java.lang.Class)">unwrap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCConnection(org.hsqldb.persist.HsqlProperties)"><!-- --></A><H3>
+JDBCConnection</H3>
+<PRE>
+public <B>JDBCConnection</B>(org.hsqldb.persist.HsqlProperties&nbsp;props)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new external <code>Connection</code> to an HSQLDB
+ <code>Database</code>. <p>
+
+ This constructor is called on behalf of the
+ <code>java.sql.DriverManager</code> when getting a
+ <code>Connection</code> for use in normal (external)
+ client code. <p>
+
+ Internal client code, that being code located in HSQLDB SQL
+ functions and stored procedures, receives an INTERNAL
+ connection constructed by the <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#JDBCConnection(org.hsqldb.SessionInterface)"><CODE>JDBCConnection(SessionInterface)</CODE></A> constructor. <p>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>props</CODE> - A <code>Properties</code> object containing the connection
+      properties
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - when the user/password combination is
+     invalid, the connection url is invalid, or the
+     <code>Database</code> is unavailable. <p>
+
+     The <code>Database</code> may be unavailable for a number
+     of reasons, including network problems or the fact that it
+     may already be in use by another process.</DL>
+</DL>
+<HR>
+
+<A NAME="JDBCConnection(org.hsqldb.SessionInterface)"><!-- --></A><H3>
+JDBCConnection</H3>
+<PRE>
+public <B>JDBCConnection</B>(org.hsqldb.SessionInterface&nbsp;c)</PRE>
+<DL>
+<DD>Constructs an <code>INTERNAL</code> <code>Connection</code>,
+ using the specified <CODE>SessionInterface</CODE>. <p>
+
+ This constructor is called only on behalf of an existing
+ <code>Session</code> (the internal parallel of a
+ <code>Connection</code>), to be used as a parameter to a SQL
+ function or stored procedure that needs to execute in the context
+ of that <code>Session</code>. <p>
+
+ When a Java SQL function or stored procedure is called and its
+ first parameter is of type <code>Connection</code>, HSQLDB
+ automatically notices this and constructs an <code>INTERNAL</code>
+ <code>Connection</code> using the current <code>Session</code>.
+ HSQLDB then passes this <code>Connection</code> in the first
+ parameter position, moving any other parameter values
+ specified in the SQL statement to the right by one position.
+ <p>
+
+ To read more about this, see
+ <CODE>Routine</CODE>. <p>
+
+ <B>Notes:</B> <p>
+
+ Starting with HSQLDB 1.7.2, <code>INTERNAL</code> connections are not
+ closed by a call to close() or by a SQL DISCONNECT.
+
+ For HSQLDB developers not involved with writing database
+ internals, this change only applies to connections obtained
+ automatically from the database as the first parameter to
+ stored procedures and SQL functions. This is mainly an issue
+ to developers writing custom SQL function and stored procedure
+ libraries for HSQLDB. Presently, it is recommended that SQL function and
+ stored procedure code avoid depending on closing or issuing a
+ DISCONNECT on a connection obtained in this manner. <p>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>c</CODE> - the Session requesting the construction of this
+     Connection
+<DT><B>Throws:</B>
+<DD><CODE>org.hsqldb.HsqlException</CODE> - never (reserved for future use);<DT><B>See Also:</B><DD><CODE>Routine</CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="createStatement()"><!-- --></A><H3>
+createStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A> <B>createStatement</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>Statement</code> object for sending
+ SQL statements to the database.
+ SQL statements without parameters are normally
+ executed using <code>Statement</code> objects. If the same SQL statement
+ is executed many times, it may be more efficient to use a
+ <code>PreparedStatement</code> object.
+ <P>
+ Result sets created using the returned <code>Statement</code>
+ object will by default be type <code>TYPE_FORWARD_ONLY</code>
+ and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 1.7.2, support for precompilation at the engine level
+ has been implemented, so it is now much more efficient and performant
+ to use a <code>PreparedStatement</code> object if the same short-running
+ SQL statement is to be executed many times. <p>
+
+ HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+ <code>TYPE_SCROLL_INSENSITIVE</code> and <code>CONCUR_READ_ONLY</code>
+ results. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createStatement()" title="class or interface in java.sql">createStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a new default <code>Statement</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 clarification:)
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createStatement(int, int)"><CODE>createStatement(int,int)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createStatement(int, int, int)"><CODE>createStatement(int,int,int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareStatement(java.lang.String)"><!-- --></A><H3>
+prepareStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A> <B>prepareStatement</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>PreparedStatement</code> object for sending
+ parameterized SQL statements to the database.
+ <P>
+ A SQL statement with or without IN parameters can be
+ pre-compiled and stored in a <code>PreparedStatement</code> object. This
+ object can then be used to efficiently execute this statement
+ multiple times.
+
+ <P><B>Note:</B> This method is optimized for handling
+ parametric SQL statements that benefit from precompilation. If
+ the driver supports precompilation,
+ the method <code>prepareStatement</code> will send
+ the statement to the database for precompilation. Some drivers
+ may not support precompilation. In this case, the statement may
+ not be sent to the database until the <code>PreparedStatement</code>
+ object is executed.  This has no direct effect on users; however, it does
+ affect which methods throw certain <code>SQLException</code> objects.
+ <P>
+ Result sets created using the returned <code>PreparedStatement</code>
+ object will by default be type <code>TYPE_FORWARD_ONLY</code>
+ and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 1.7.2, support for precompilation at the engine level
+ has been implemented, so it is now much more efficient and performant
+ to use a <code>PreparedStatement</code> object if the same short-running
+ SQL statement is to be executed many times. <p>
+
+ The support for and behaviour of PreparedStatment complies with SQL and
+ JDBC standards.  Please read the introductory section
+ of the documentation for ${link JDBCParameterMetaData}. <P>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareStatement(java.lang.String)" title="class or interface in java.sql">prepareStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL statement that may contain one or more '?' IN
+ parameter placeholders
+<DT><B>Returns:</B><DD>a new default <code>PreparedStatement</code> object containing the
+ pre-compiled SQL statement
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 clarification:)
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String, int, int)"><CODE>prepareStatement(String,int,int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareCall(java.lang.String)"><!-- --></A><H3>
+prepareCall</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A> <B>prepareCall</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>CallableStatement</code> object for calling
+ database stored procedures.
+ The <code>CallableStatement</code> object provides
+ methods for setting up its IN and OUT parameters, and
+ methods for executing the call to a stored procedure.
+
+ <P><B>Note:</B> This method is optimized for handling stored
+ procedure call statements. Some drivers may send the call
+ statement to the database when the method <code>prepareCall</code>
+ is done; others
+ may wait until the <code>CallableStatement</code> object
+ is executed. This has no
+ direct effect on users; however, it does affect which method
+ throws certain SQLExceptions.
+ <P>
+ Result sets created using the returned <code>CallableStatement</code>
+ object will by default be type <code>TYPE_FORWARD_ONLY</code>
+ and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.7.2, the support for and behaviour of
+ CallableStatement has changed.  Please read the introductory section
+ of the documentation for org.hsqldb.jdbc.JDBCCallableStatement.
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareCall(java.lang.String)" title="class or interface in java.sql">prepareCall</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL statement that may contain one or more '?'
+ parameter placeholders. (JDBC4 clarification:) Typically this statement is specified using JDBC
+ call escape syntax.
+<DT><B>Returns:</B><DD>a new default <code>CallableStatement</code> object containing the
+ pre-compiled SQL statement
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 clarification:)
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String, int, int)"><CODE>prepareCall(String,int,int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nativeSQL(java.lang.String)"><!-- --></A><H3>
+nativeSQL</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>nativeSQL</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Converts the given SQL statement into the system's native SQL grammar.
+ A driver may convert the JDBC SQL grammar into its system's
+ native SQL grammar prior to sending it. This method returns the
+ native form of the statement that the driver would have sent.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the JDBC SQL
+ grammar into the system's native SQL grammar prior to sending
+ it, if escape processing is set true; this method returns the
+ native form of the statement that the driver would send in place
+ of client-specified JDBC SQL grammar. <p>
+
+ Before 1.7.2, escape processing was incomplete and
+ also broken in terms of support for nested escapes. <p>
+
+ Starting with 1.7.2, escape processing is complete and handles nesting
+ to arbitrary depth, but enforces a very strict interpretation of the
+ syntax and does not detect or process SQL comments. <p>
+
+ In essence, the HSQLDB engine directly handles the prescribed syntax
+ and date / time formats specified internal to the JDBC escapes.
+ It also directly offers the XOpen / ODBC extended scalar
+ functions specified available internal to the {fn ...} JDBC escape.
+ As such, the driver simply removes the curly braces and JDBC escape
+ codes in the simplest and fastest fashion possible, by replacing them
+ with whitespace.
+
+ But to avoid a great deal of complexity, certain forms of input
+ whitespace are currently not recognised.  For instance,
+ the driver handles "{?= call ...}" but not "{ ?= call ...} or
+ "{? = call ...}" <p>
+
+ Also, comments embedded in SQL are currently not detected or
+ processed and thus may have unexpected effects on the output
+ of this method, for instance causing otherwise valid SQL to become
+ invalid. It is especially important to be aware of this because escape
+ processing is set true by default for Statement objects and is always
+ set true when producing a PreparedStatement from prepareStatement()
+ or CallableStatement from prepareCall().  Currently, it is simply
+ recommended to avoid submitting SQL having comments containing JDBC
+ escape sequence patterns and/or single or double quotation marks,
+ as this will avoid any potential problems.
+
+ It is intended to implement a less strict handling of whitespace and
+ proper processing of SQL comments at some point in the near future.
+
+ In any event, 1.7.2 now correctly processes the following JDBC escape
+ forms to arbitrary nesting depth, but only if the exact whitespace
+ layout described below is used: <p>
+
+ <ol>
+ <li>{call ...}
+ <li>{?= call ...}
+ <li>{fn ...}
+ <li>{oj ...}
+ <li>{d ...}
+ <li>{t ...}
+ <li>{ts ...}
+ </ol> <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#nativeSQL(java.lang.String)" title="class or interface in java.sql">nativeSQL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL statement that may contain one or more '?'
+ parameter placeholders
+<DT><B>Returns:</B><DD>the native form of this statement
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 clarification:)
+ or this method is called on a closed connection</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAutoCommit(boolean)"><!-- --></A><H3>
+setAutoCommit</H3>
+<PRE>
+public void <B>setAutoCommit</B>(boolean&nbsp;autoCommit)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets this connection's auto-commit mode to the given state.
+ If a connection is in auto-commit mode, then all its SQL
+ statements will be executed and committed as individual
+ transactions.  Otherwise, its SQL statements are grouped into
+ transactions that are terminated by a call to either
+ the method <code>commit</code> or the method <code>rollback</code>.
+ By default, new connections are in auto-commit
+ mode.
+ <P>
+ The commit occurs when the statement completes. The time when the statement
+ completes depends on the type of SQL Statement:
+ <ul>
+ <li>For DML statements, such as Insert, Update or Delete, and DDL statements,
+ the statement is complete as soon as it has finished executing.
+ <li>For Select statements, the statement is complete when the associated result
+ set is closed.
+ <li>For <code>CallableStatement</code> objects or for statements that return
+ multiple results, the statement is complete
+ when all of the associated result sets have been closed, and all update
+ counts and output parameters have been retrieved.
+ </ul>
+ <P>
+ <B>NOTE:</B>  If this method is called during a transaction and the
+ auto-commit mode is changed, the transaction is committed.  If
+ <code>setAutoCommit</code> is called and the auto-commit mode is
+ not changed, the call is a no-op.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Up to and including HSQLDB 2.0, <p>
+
+ <ol>
+   <li> All rows of a result set are retrieved internally <em>
+   before</em> the first row can actually be fetched.<br>
+   Therefore, a statement can be considered complete as soon as
+   any XXXStatement.executeXXX method returns. </li>
+
+   <li> Multiple result sets and output parameters are not yet
+   supported. </li>
+ </ol>
+ <p>
+
+ Starting with 2.0, HSQLDB may not return a result set to the network
+ client as a whole; the generic documentation will apply. The fetch
+ size is taken into account
+
+ (boucherb@users) </div> <!-- end release-specific
+ documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setAutoCommit(boolean)" title="class or interface in java.sql">setAutoCommit</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>autoCommit</CODE> - <code>true</code> to enable auto-commit mode;
+         <code>false</code> to disable it
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+  (JDBC4 Clarification:)
+  setAutoCommit(true) is called while participating in a distributed transaction,
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getAutoCommit()"><CODE>getAutoCommit()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAutoCommit()"><!-- --></A><H3>
+getAutoCommit</H3>
+<PRE>
+public boolean <B>getAutoCommit</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the current auto-commit mode for this <code>Connection</code>
+ object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getAutoCommit()" title="class or interface in java.sql">getAutoCommit</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current state of this <code>Connection</code> object's
+         auto-commit mode
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setAutoCommit(boolean)"><CODE>setAutoCommit(boolean)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="commit()"><!-- --></A><H3>
+commit</H3>
+<PRE>
+public void <B>commit</B>()
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Makes all changes made since the previous
+ commit/rollback permanent and releases any database locks
+ currently held by this <code>Connection</code> object.
+ This method should be
+ used only when auto-commit mode has been disabled.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+ </div><!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#commit()" title="class or interface in java.sql">commit</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ (JDBC4 Clarification:)
+ this method is called while participating in a distributed transaction,
+ if this method is called on a closed conection or this
+            <code>Connection</code> object is in auto-commit mode<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setAutoCommit(boolean)"><CODE>setAutoCommit(boolean)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="rollback()"><!-- --></A><H3>
+rollback</H3>
+<PRE>
+public void <B>rollback</B>()
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Undoes all changes made in the current transaction
+ and releases any database locks currently held
+ by this <code>Connection</code> object. This method should be
+ used only when auto-commit mode has been disabled.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 1.7.2, savepoints are fully supported both
+ in SQL and via the JDBC interface. <p>
+
+ Using SQL, savepoints may be set, released and used in rollback
+ as follows:
+
+ <pre>
+ SAVEPOINT &lt;savepoint-name&gt;
+ RELEASE SAVEPOINT &lt;savepoint-name&gt;
+ ROLLBACK TO SAVEPOINT &lt;savepoint-name&gt;
+ </pre>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#rollback()" title="class or interface in java.sql">rollback</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ (JDBC4 Clarification:)
+ this method is called while participating in a distributed transaction,
+ this method is called on a closed connection or this
+            <code>Connection</code> object is in auto-commit mode<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setAutoCommit(boolean)"><CODE>setAutoCommit(boolean)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="close()"><!-- --></A><H3>
+close</H3>
+<PRE>
+public void <B>close</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Releases this <code>Connection</code> object's database and JDBC resources
+ immediately instead of waiting for them to be automatically released.
+ <P>
+ Calling the method <code>close</code> on a <code>Connection</code>
+ object that is already closed is a no-op.
+ <P>
+ It is <b>strongly recommended</b> that an application explicitly
+ commits or rolls back an active transaction prior to calling the
+ <code>close</code> method.  If the <code>close</code> method is called
+ and there is an active transaction, the results are implementation-defined.
+ <P>
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 1.7.2, HSQLDB <code>INTERNAL</code> <code>Connection</code>
+ objects are not closable from JDBC client code. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#close()" title="class or interface in java.sql">close</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - SQLException if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isClosed()"><!-- --></A><H3>
+isClosed</H3>
+<PRE>
+public boolean <B>isClosed</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this <code>Connection</code> object has been
+ closed.  A connection is closed if the method <code>close</code>
+ has been called on it or if certain fatal errors have occurred.
+ This method is guaranteed to return <code>true</code> only when
+ it is called after the method <code>Connection.close</code> has
+ been called.
+ <P>
+ This method generally cannot be called to determine whether a
+ connection to a database is valid or invalid.  A typical client
+ can determine that a connection is invalid by catching any
+ exceptions that might be thrown when an operation is attempted.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#isClosed()" title="class or interface in java.sql">isClosed</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if this <code>Connection</code> object
+         is closed; <code>false</code> if it is still open
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMetaData()"><!-- --></A><H3>
+getMetaData</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A> <B>getMetaData</B>()
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves a <code>DatabaseMetaData</code> object that contains
+ metadata about the database to which this
+ <code>Connection</code> object represents a connection.
+ The metadata includes information about the database's
+ tables, its supported SQL grammar, its stored
+ procedures, the capabilities of this connection, and so on.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 essentially supports full database metadata. <p>
+
+ For discussion in greater detail, please follow the link to the
+ overview for JDBCDatabaseMetaData, below.
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getMetaData()" title="class or interface in java.sql">getMetaData</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>DatabaseMetaData</code> object for this
+         <code>Connection</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification)
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><CODE>JDBCDatabaseMetaData</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setReadOnly(boolean)"><!-- --></A><H3>
+setReadOnly</H3>
+<PRE>
+public void <B>setReadOnly</B>(boolean&nbsp;readOnly)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Puts this connection in read-only mode as a hint to the driver to enable
+ database optimizations.
+
+ <P><B>Note:</B> This method cannot be called during a transaction.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports the SQL standard, which will not allow calls to
+ this method to succeed during a transaction.<p>
+
+ Additionally, HSQLDB provides a way to put a whole database in
+ read-only mode. This is done by manually adding the line
+ 'readonly=true' to the database's .properties file while the
+ database is offline. Upon restart, all connections will be
+ readonly, since the entire database will be readonly. To take
+ a database out of readonly mode, simply take the database
+ offline and remove the line 'readonly=true' from the
+ database's .properties file. Upon restart, the database will
+ be in regular (read-write) mode. <p>
+
+ When a database is put in readonly mode, its files are opened
+ in readonly mode, making it possible to create CD-based
+ readonly databases. To create a CD-based readonly database
+ that has CACHED tables and whose .data file is suspected of
+ being highly fragmented, it is recommended that the database
+ first be SHUTDOWN COMPACTed before copying the database
+ files to CD. This will reduce the space required and may
+ improve access times against the .data file which holds the
+ CACHED table data. <p>
+
+ Starting with 1.7.2, an alternate approach to opimizing the
+ .data file before creating a CD-based readonly database is to issue
+ the CHECKPOINT DEFRAG command followed by SHUTDOWN to take the
+ database offline in preparation to burn the database files to CD. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setReadOnly(boolean)" title="class or interface in java.sql">setReadOnly</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>readOnly</CODE> - <code>true</code> enables read-only mode;
+        <code>false</code> disables it
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+  method is called on a closed connection or this
+            method is called during a transaction</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isReadOnly()"><!-- --></A><H3>
+isReadOnly</H3>
+<PRE>
+public boolean <B>isReadOnly</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this <code>Connection</code>
+ object is in read-only mode.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#isReadOnly()" title="class or interface in java.sql">isReadOnly</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if this <code>Connection</code> object
+         is read-only; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - SQLException if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCatalog(java.lang.String)"><!-- --></A><H3>
+setCatalog</H3>
+<PRE>
+public void <B>setCatalog</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Sets the given catalog name in order to select
+ a subspace of this <code>Connection</code> object's database
+ in which to work.
+ <P>
+
+ (JDBC4 Clarification:)<p>
+ If the driver does not support catalogs, it will
+ silently ignore this request.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports a single catalog per database. If the given catalog name
+ is not the same as the database catalog name, this method throws an
+ error. <p>
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setCatalog(java.lang.String)" title="class or interface in java.sql">setCatalog</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - the name of a catalog (subspace in this
+        <code>Connection</code> object's database) in which to work
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification)
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getCatalog()"><CODE>getCatalog()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCatalog()"><!-- --></A><H3>
+getCatalog</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getCatalog</B>()
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves this <code>Connection</code> object's current catalog name.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports a single catalog per database. This method
+ returns the catalog name for the current database
+ error. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getCatalog()" title="class or interface in java.sql">getCatalog</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current catalog name or <code>null</code> if there is none
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setCatalog(java.lang.String)"><CODE>setCatalog(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTransactionIsolation(int)"><!-- --></A><H3>
+setTransactionIsolation</H3>
+<PRE>
+public void <B>setTransactionIsolation</B>(int&nbsp;level)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ <code>Connection</code> object to the one given.
+ The constants defined in the interface <code>Connection</code>
+ are the possible transaction isolation levels.
+ <P>
+ <B>Note:</B> If this method is called during a transaction, the result
+ is implementation-defined.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports all isolation levels. <code>Connection.TRANSACTION_READ_UNCOMMITED</code>
+ is promoted to <code>Connection.TRANSACTION_READ_COMMITED</code>.
+ Calling this method during a transaction always fails.<p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setTransactionIsolation(int)" title="class or interface in java.sql">setTransactionIsolation</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>level</CODE> - one of the following <code>Connection</code> constants:
+        <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>,
+        <code>Connection.TRANSACTION_READ_COMMITTED</code>,
+        <code>Connection.TRANSACTION_REPEATABLE_READ</code>, or
+        <code>Connection.TRANSACTION_SERIALIZABLE</code>.
+        (Note that <code>Connection.TRANSACTION_NONE</code> cannot be used
+        because it specifies that transactions are not supported.)
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+ method is called on a closed connection
+ (:JDBC4 End Clarification)
+            or the given parameter is not one of the <code>Connection</code>
+            constants<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsTransactionIsolationLevel(int)"><CODE>JDBCDatabaseMetaData.supportsTransactionIsolationLevel(int)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getTransactionIsolation()"><CODE>getTransactionIsolation()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTransactionIsolation()"><!-- --></A><H3>
+getTransactionIsolation</H3>
+<PRE>
+public int <B>getTransactionIsolation</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves this <code>Connection</code> object's current
+ transaction isolation level.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports all isolation levels. <code>Connection.TRANSACTION_READ_UNCOMMITED</code>
+ is promoted to <code>Connection.TRANSACTION_READ_COMMITED</code>.
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getTransactionIsolation()" title="class or interface in java.sql">getTransactionIsolation</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current transaction isolation level, which will be one
+         of the following constants:
+        <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>,
+        <code>Connection.TRANSACTION_READ_COMMITTED</code>,
+        <code>Connection.TRANSACTION_REPEATABLE_READ</code>,
+        <code>Connection.TRANSACTION_SERIALIZABLE</code>, or
+        <code>Connection.TRANSACTION_NONE</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsTransactionIsolationLevel(int)"><CODE>JDBCDatabaseMetaData.supportsTransactionIsolationLevel(int)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setTransactionIsolation(int)"><CODE>setTransactionIsolation(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWarnings()"><!-- --></A><H3>
+getWarnings</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A> <B>getWarnings</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the first warning reported by calls on this
+ <code>Connection</code> object.  If there is more than one
+ warning, subsequent warnings will be chained to the first one
+ and can be retrieved by calling the method
+ <code>SQLWarning.getNextWarning</code> on the warning
+ that was retrieved previously.
+ <P>
+ This method may not be
+ called on a closed connection; doing so will cause an
+ <code>SQLException</code> to be thrown.
+
+ <P><B>Note:</B> Subsequent warnings will be chained to this
+ SQLWarning.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB produces warnings whenever a createStatement(),
+ prepareStatement() or prepareCall() invocation requests an unsupported
+ but defined combination of result set type, concurrency and holdability,
+ such that another set is substituted.<p>
+ Other warnings are typically raised during the execution of data change
+ and query statements.<p>
+
+ Only the warnings caused by the last operation on this connection are
+ returned by this method. A single operation may return up to 10 chained
+ warnings.
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getWarnings()" title="class or interface in java.sql">getWarnings</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the first <code>SQLWarning</code> object or <code>null</code>
+         if there are none
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+            this method is called on a closed connection<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql"><CODE>SQLWarning</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clearWarnings()"><!-- --></A><H3>
+clearWarnings</H3>
+<PRE>
+public void <B>clearWarnings</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Clears all warnings reported for this <code>Connection</code> object.
+ After a call to this method, the method <code>getWarnings</code>
+ returns <code>null</code> until a new warning is
+ reported for this <code>Connection</code> object.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The standard behaviour is implemented. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#clearWarnings()" title="class or interface in java.sql">clearWarnings</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - SQLException if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createStatement(int, int)"><!-- --></A><H3>
+createStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A> <B>createStatement</B>(int&nbsp;resultSetType,
+                                 int&nbsp;resultSetConcurrency)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>Statement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.
+ This method is the same as the <code>createStatement</code> method
+ above, but it allows the default result set
+ type and concurrency to be overridden.
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+ interpretation of of resultSetType and resultSetConcurrency has
+ changed in this version.<p>
+
+ HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+ <code>TYPE_SCROLL_INSENSITIVE</code>,
+ <code>CONCUR_READ_ONLY</code>,
+ <code>CONCUR_UPDATABLE</code>
+ results. <p>
+
+ If an unsupported combination is requested, a SQLWarning is issued on
+ this Connection and the closest supported combination is used instead. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createStatement(int, int)" title="class or interface in java.sql">createStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>resultSetType</CODE> - a result set type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code><DD><CODE>resultSetConcurrency</CODE> - a concurrency type; one of
+        <code>ResultSet.CONCUR_READ_ONLY</code> or
+        <code>ResultSet.CONCUR_UPDATABLE</code>
+<DT><B>Returns:</B><DD>a new <code>Statement</code> object that will generate
+         <code>ResultSet</code> objects with the given type and
+         concurrency
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+ method is called on a closed connection
+ (:JDBC4 Clarification)
+         or the given parameters are not <code>ResultSet</code>
+         constants indicating type and concurrency
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method or this method is not supported for the specified result
+ set type and result set concurrency.<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+  for JDBCConnection)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareStatement(java.lang.String, int, int)"><!-- --></A><H3>
+prepareStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A> <B>prepareStatement</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                                          int&nbsp;resultSetType,
+                                          int&nbsp;resultSetConcurrency)
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>PreparedStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.
+ This method is the same as the <code>prepareStatement</code> method
+ above, but it allows the default result set
+ type and concurrency to be overridden.
+ (JDBC4 Clarification:)
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+ interpretation of of resultSetType and resultSetConcurrency has
+ changed in this version.<p>
+
+ HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+ <code>TYPE_SCROLL_INSENSITIVE</code>,
+ <code>CONCUR_READ_ONLY</code>,
+ <code>CONCUR_UPDATABLE</code>
+ results. <p>
+
+ If an unsupported combination is requested, a SQLWarning is issued on
+ this Connection and the closest supported combination is used instead. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareStatement(java.lang.String, int, int)" title="class or interface in java.sql">prepareStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - a <code>String</code> object that is the SQL statement to
+            be sent to the database; may contain one or more '?' IN
+            parameters<DD><CODE>resultSetType</CODE> - a result set type; one of
+         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code><DD><CODE>resultSetConcurrency</CODE> - a concurrency type; one of
+         <code>ResultSet.CONCUR_READ_ONLY</code> or
+         <code>ResultSet.CONCUR_UPDATABLE</code>
+<DT><B>Returns:</B><DD>a new PreparedStatement object containing the
+ pre-compiled SQL statement that will produce <code>ResultSet</code>
+ objects with the given type and concurrency
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+ method is called on a closed connection
+ (:JDBC4 Clarification)
+         or the given parameters are not <code>ResultSet</code>
+         constants indicating type and concurrency
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method or this method is not supported for the specified result
+ set type and result set concurrency.<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+  for JDBCConnection)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareCall(java.lang.String, int, int)"><!-- --></A><H3>
+prepareCall</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A> <B>prepareCall</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                                     int&nbsp;resultSetType,
+                                     int&nbsp;resultSetConcurrency)
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>CallableStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.
+ This method is the same as the <code>prepareCall</code> method
+ above, but it allows the default result set
+ type and concurrency to be overridden.
+ (JDBC4 Clarification:)
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+ interpretation of of resultSetType and resultSetConcurrency has
+ changed in this version.<p>
+
+ HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+ <code>TYPE_SCROLL_INSENSITIVE</code>,
+ <code>CONCUR_READ_ONLY</code>,
+ <code>CONCUR_UPDATABLE</code>
+ results. <p>
+
+ If an unsupported combination is requested, a SQLWarning is issued on
+ this Connection and the closest supported combination is used instead. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareCall(java.lang.String, int, int)" title="class or interface in java.sql">prepareCall</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - a <code>String</code> object that is the SQL statement to
+            be sent to the database; may contain on or more '?' parameters<DD><CODE>resultSetType</CODE> - a result set type; one of
+         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code><DD><CODE>resultSetConcurrency</CODE> - a concurrency type; one of
+         <code>ResultSet.CONCUR_READ_ONLY</code> or
+         <code>ResultSet.CONCUR_UPDATABLE</code>
+<DT><B>Returns:</B><DD>a new <code>CallableStatement</code> object containing the
+ pre-compiled SQL statement that will produce <code>ResultSet</code>
+ objects with the given type and concurrency
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this method
+ (JDBC4 Clarification:)
+ is called on a closed connection
+ (:JDBC4 Clarification)
+         or the given parameters are not <code>ResultSet</code>
+         constants indicating type and concurrency
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method or this method is not supported for the specified result
+ set type and result set concurrency.<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+ for JDBCConnection)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTypeMap()"><!-- --></A><H3>
+getTypeMap</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt; <B>getTypeMap</B>()
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the <code>Map</code> object associated with this
+ <code>Connection</code> object.
+ Unless the application has added an entry, the type map returned
+ will be empty.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ For compatibility, HSQLDB returns an empty map. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getTypeMap()" title="class or interface in java.sql">getTypeMap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the <code>java.util.Map</code> object associated
+         with this <code>Connection</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCConnection)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTypeMap(java.util.Map)"><!-- --></A><H3>
+setTypeMap</H3>
+<PRE>
+public void <B>setTypeMap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&gt;&nbsp;map)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Installs the given <code>TypeMap</code> object as the type map for
+ this <code>Connection</code> object.  The type map will be used for the
+ custom mapping of SQL structured types and distinct types.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not yet support this feature. Calling this
+ method always throws a <code>SQLException</code>, stating that
+ the function is not supported. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setTypeMap(java.util.Map)" title="class or interface in java.sql">setTypeMap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>map</CODE> - the <code>java.util.Map</code> object to install
+        as the replacement for this <code>Connection</code>
+        object's default type map
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+ method is called on a closed connection or
+ (:JDBC4 Clarification)
+        the given parameter is not a <code>java.util.Map</code>
+        object
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCConnection)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getTypeMap()"><CODE>getTypeMap()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setHoldability(int)"><!-- --></A><H3>
+setHoldability</H3>
+<PRE>
+public void <B>setHoldability</B>(int&nbsp;holdability)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ (JDBC4 Clarification:)
+ Changes the default holdability of <code>ResultSet</code> objects
+ created using this <code>Connection</code> object to the given
+ holdability.  The default holdability of <code>ResultSet</code> objects
+ can be be determined by invoking
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getResultSetHoldability()" title="class or interface in java.sql"><CODE>DatabaseMetaData.getResultSetHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setHoldability(int)" title="class or interface in java.sql">setHoldability</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>holdability</CODE> - a <code>ResultSet</code> holdability constant; one of
+        <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+        <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access occurs, this method is called
+ (JDBC4 Clarification:)
+ on a closed connection, or the given parameter
+ (:JDBC4 Clkarification)
+         is not a <code>ResultSet</code> constant indicating holdability
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the given holdability is not supported<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getResultSetHoldability()" title="class or interface in java.sql"><CODE>DatabaseMetaData.getResultSetHoldability()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getHoldability()"><!-- --></A><H3>
+getHoldability</H3>
+<PRE>
+public int <B>getHoldability</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Retrieves the current holdability of <code>ResultSet</code> objects
+ created using this <code>Connection</code> object.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB returns the current holdability.<p>
+
+ The default is HOLD_CURSORS_OVER_COMMIT. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getHoldability()" title="class or interface in java.sql">getHoldability</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the holdability, one of
+        <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+        <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#setHoldability(int)"><CODE>setHoldability(int)</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getResultSetHoldability()" title="class or interface in java.sql"><CODE>DatabaseMetaData.getResultSetHoldability()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setSavepoint()"><!-- --></A><H3>
+setSavepoint</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A> <B>setSavepoint</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates an unnamed savepoint in the current transaction and
+ returns the new <code>Savepoint</code> object that represents it.
+
+ <p>(JDBC4 clarification:)
+ <p> if setSavepoint is invoked outside of an active transaction, a transaction will be started at this newly created
+ savepoint.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports this feature. <p>
+
+ Note: Unnamed savepoints are not part of the SQL:2003 standard.
+ Use setSavepoint(String name) instead. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setSavepoint()" title="class or interface in java.sql">setSavepoint</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the new <code>Savepoint</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ (JDBC4 Clarification:)
+ this method is called while participating in a distributed transaction,
+ this method is called on a closed connection
+            or this <code>Connection</code> object is currently in
+            auto-commit mode
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><CODE>JDBCSavepoint</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql"><CODE>Savepoint</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setSavepoint(java.lang.String)"><!-- --></A><H3>
+setSavepoint</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A> <B>setSavepoint</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a savepoint with the given name in the current transaction
+ and returns the new <code>Savepoint</code> object that represents it.
+
+ <p> if setSavepoint is invoked outside of an active transaction, a
+ transaction will be started at this newly created savepoint.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Previous to JDBC 4, if the connection is autoCommit,
+ setting a savepoint has no effect, as it is cleared upon the execution
+ of the next transactional statement. When built for JDBC 4, this method
+ throws an SQLException when this <tt>Connection</tt> object is currently
+ in auto-commit mode, as per the JDBC 4 standard.
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setSavepoint(java.lang.String)" title="class or interface in java.sql">setSavepoint</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - a <code>String</code> containing the name of the savepoint
+<DT><B>Returns:</B><DD>the new <code>Savepoint</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ (JDBC4 Clarification:)
+      this method is called while participating in a distributed transaction,
+ this method is called on a closed connection
+            or this <code>Connection</code> object is currently in
+            auto-commit mode
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><CODE>JDBCSavepoint</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql"><CODE>Savepoint</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="rollback(java.sql.Savepoint)"><!-- --></A><H3>
+rollback</H3>
+<PRE>
+public void <B>rollback</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A>&nbsp;savepoint)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Undoes all changes made after the given <code>Savepoint</code> object
+ was set.
+ <P>
+ This method should be used only when auto-commit has been disabled.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Previous to JDBC 4, <tt>JDBCSavepoint</tt> objects are valid for the life of
+ the originating <tt>Connection</tt> object and hence can be used
+ interchangably, as long as they have equal savepoint names. <p>
+
+ When built for JDBC 4, <tt>JDBCConnection</tt> objects invalidate
+ <tt>JDBCSavepoint</tt> objects when auto-commit mode is entered as well
+ as when they are used to successfully release or roll back to a named SQL
+ savepoint.  As per the JDBC 4 standard, when built for JDBC 4, this
+ method throws an <tt>SQLException</tt> when this <tt>Connection</tt>
+ object is currently in auto-commit mode and an invalidated
+ <tt>JDBCSavepoint</tt> is specified.
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#rollback(java.sql.Savepoint)" title="class or interface in java.sql">rollback</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>savepoint</CODE> - the <code>Savepoint</code> object to roll back to
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called while participating in a distributed transaction,
+ this method is called on a closed connection,
+            the <code>Savepoint</code> object is no longer valid,
+            or this <code>Connection</code> object is currently in
+            auto-commit mode
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><CODE>JDBCSavepoint</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql"><CODE>Savepoint</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#rollback()"><CODE>rollback()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="releaseSavepoint(java.sql.Savepoint)"><!-- --></A><H3>
+releaseSavepoint</H3>
+<PRE>
+public void <B>releaseSavepoint</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A>&nbsp;savepoint)
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Removes the specified <code>Savepoint</code> (JDBC4 Clarification:) and subsequent <code>Savepoint</code> objects from the current
+ transaction. Any reference to the savepoint after it have been removed
+ will cause an <code>SQLException</code> to be thrown.
+
+ <!-- end generic documentation -->
+
+
+ <b>HSLQDB Note:</b><p>
+
+ Previous to JDBC 4, <tt>JDBCSavepoint</tt> objects are valid for the life of
+ the originating <tt>Connection</tt> object and hence can be used
+ interchangably, as long as they have equal savepoint names. <p>
+
+ When built for JDBC 4, <tt>JDBCConnection</tt> objects invalidate
+ <tt>JDBCSavepoint</tt> objects when auto-commit mode is entered as well
+ as when they are used to successfully release or roll back to a named SQL
+ savepoint.  As per the JDBC 4 standard, when built for JDBC 4, this
+ method throws an <tt>SQLException</tt> when this <tt>Connection</tt>
+ object is currently in auto-commit mode and when an invalidated
+ <tt>JDBCSavepoint</tt> is specified. <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#releaseSavepoint(java.sql.Savepoint)" title="class or interface in java.sql">releaseSavepoint</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>savepoint</CODE> - the <code>Savepoint</code> object to be removed
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+  (JDBC4 Clarification:)
+  method is called on a closed connection or
+            the given <code>Savepoint</code> object is not a valid
+            savepoint in the current transaction
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><CODE>JDBCSavepoint</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql"><CODE>Savepoint</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createStatement(int, int, int)"><!-- --></A><H3>
+createStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A> <B>createStatement</B>(int&nbsp;resultSetType,
+                                 int&nbsp;resultSetConcurrency,
+                                 int&nbsp;resultSetHoldability)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>Statement</code> object that will generate
+ <code>ResultSet</code> objects with the given type, concurrency,
+ and holdability.
+ This method is the same as the <code>createStatement</code> method
+ above, but it allows the default result set
+ type, concurrency, and holdability to be overridden.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+ interpretation of of resultSetType and resultSetConcurrency has
+ changed in this version.<p>
+
+ HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+ <code>TYPE_SCROLL_INSENSITIVE</code>,
+ <code>CONCUR_READ_ONLY</code>,
+ <code>CONCUR_UPDATABLE</code>
+ results. <p>
+
+ If an unsupported combination is requested, a SQLWarning is issued on
+ this Connection and the closest supported combination is used instead. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createStatement(int, int, int)" title="class or interface in java.sql">createStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>resultSetType</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code><DD><CODE>resultSetConcurrency</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.CONCUR_READ_ONLY</code> or
+         <code>ResultSet.CONCUR_UPDATABLE</code><DD><CODE>resultSetHoldability</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Returns:</B><DD>a new <code>Statement</code> object that will generate
+         <code>ResultSet</code> objects with the given type,
+         concurrency, and holdability
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+ method is called on a closed connection
+ (:JDBC4 Clarification)
+            or the given parameters are not <code>ResultSet</code>
+            constants indicating type, concurrency, and holdability
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method or this method is not supported for the specified result
+ set type, result set holdability and result set concurrency.<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareStatement(java.lang.String, int, int, int)"><!-- --></A><H3>
+prepareStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A> <B>prepareStatement</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                                          int&nbsp;resultSetType,
+                                          int&nbsp;resultSetConcurrency,
+                                          int&nbsp;resultSetHoldability)
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>PreparedStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type, concurrency,
+ and holdability.
+ <P>
+ This method is the same as the <code>prepareStatement</code> method
+ above, but it allows the default result set
+ type, concurrency, and holdability to be overridden.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+ interpretation of of resultSetType and resultSetConcurrency has
+ changed in this version.<p>
+
+ HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+ <code>TYPE_SCROLL_INSENSITIVE</code>,
+ <code>CONCUR_READ_ONLY</code>,
+ <code>CONCUR_UPDATABLE</code>
+ results. <p>
+
+ If an unsupported combination is requested, a SQLWarning is issued on
+ this Connection and the closest supported combination is used instead. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareStatement(java.lang.String, int, int, int)" title="class or interface in java.sql">prepareStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - a <code>String</code> object that is the SQL statement to
+            be sent to the database; may contain one or more '?' IN
+            parameters<DD><CODE>resultSetType</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code><DD><CODE>resultSetConcurrency</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.CONCUR_READ_ONLY</code> or
+         <code>ResultSet.CONCUR_UPDATABLE</code><DD><CODE>resultSetHoldability</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Returns:</B><DD>a new <code>PreparedStatement</code> object, containing the
+         pre-compiled SQL statement, that will generate
+         <code>ResultSet</code> objects with the given type,
+         concurrency, and holdability
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+ method is called on a closed connection
+ (:JDBC4 Clarification)
+            or the given parameters are not <code>ResultSet</code>
+            constants indicating type, concurrency, and holdability
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method or this method is not supported for the specified result
+ set type, result set holdability and result set concurrency.<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareCall(java.lang.String, int, int, int)"><!-- --></A><H3>
+prepareCall</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A> <B>prepareCall</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                                     int&nbsp;resultSetType,
+                                     int&nbsp;resultSetConcurrency,
+                                     int&nbsp;resultSetHoldability)
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a <code>CallableStatement</code> object that will generate
+ <code>ResultSet</code> objects with the given type and concurrency.
+ This method is the same as the <code>prepareCall</code> method
+ above, but it allows the default result set
+ type, result set concurrency type and holdability to be overridden.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+ interpretation of of resultSetType and resultSetConcurrency has
+ changed in this version.<p>
+
+ HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+ <code>TYPE_SCROLL_INSENSITIVE</code>,
+ <code>CONCUR_READ_ONLY</code>,
+ <code>CONCUR_UPDATABLE</code>
+ results. <p>
+
+ If an unsupported combination is requested, a SQLWarning is issued on
+ this Connection and the closest supported combination is used instead. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareCall(java.lang.String, int, int, int)" title="class or interface in java.sql">prepareCall</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - a <code>String</code> object that is the SQL statement to
+            be sent to the database; may contain on or more '?' parameters<DD><CODE>resultSetType</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code><DD><CODE>resultSetConcurrency</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.CONCUR_READ_ONLY</code> or
+         <code>ResultSet.CONCUR_UPDATABLE</code><DD><CODE>resultSetHoldability</CODE> - one of the following <code>ResultSet</code>
+        constants:
+         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Returns:</B><DD>a new <code>CallableStatement</code> object, containing the
+         pre-compiled SQL statement, that will generate
+         <code>ResultSet</code> objects with the given type,
+         concurrency, and holdability
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+ method is called on a closed connection
+ (:JDBC4 Clarification)
+            or the given parameters are not <code>ResultSet</code>
+            constants indicating type, concurrency, and holdability
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method or this method is not supported for the specified result
+ set type, result set holdability and result set concurrency.<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareStatement(java.lang.String, int)"><!-- --></A><H3>
+prepareStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A> <B>prepareStatement</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                                          int&nbsp;autoGeneratedKeys)
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a default <code>PreparedStatement</code> object that has
+ the capability to retrieve auto-generated keys. The given constant
+ tells the driver whether it should make auto-generated keys
+ available for retrieval.  This parameter is ignored if the SQL statement
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ auto-generated keys (the list of such statements is vendor-specific).
+ <P>
+ <B>Note:</B> This method is optimized for handling
+ parametric SQL statements that benefit from precompilation. If
+ the driver supports precompilation,
+ the method <code>prepareStatement</code> will send
+ the statement to the database for precompilation. Some drivers
+ may not support precompilation. In this case, the statement may
+ not be sent to the database until the <code>PreparedStatement</code>
+ object is executed.  This has no direct effect on users; however, it does
+ affect which methods throw certain SQLExceptions.
+ <P>
+ Result sets created using the returned <code>PreparedStatement</code>
+ object will by default be type <code>TYPE_FORWARD_ONLY</code>
+ and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+ (JDBC4 Clarification:)
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Supported in 2.0
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareStatement(java.lang.String, int)" title="class or interface in java.sql">prepareStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL statement that may contain one or more '?' IN
+        parameter placeholders<DD><CODE>autoGeneratedKeys</CODE> - a flag indicating whether auto-generated keys
+        should be returned; one of
+        <code>Statement.RETURN_GENERATED_KEYS</code> or
+        <code>Statement.NO_GENERATED_KEYS</code>
+<DT><B>Returns:</B><DD>a new <code>PreparedStatement</code> object, containing the
+         pre-compiled SQL statement, that will have the capability of
+         returning auto-generated keys
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ (JDBC4 Clarification:)
+  method is called on a closed connection
+ (:JDBC4 Clarification)
+         or the given parameter is not a <code>Statement</code>
+         constant indicating whether auto-generated keys should be
+         returned
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method with a constant of Statement.RETURN_GENERATED_KEYS<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareStatement(java.lang.String, int[])"><!-- --></A><H3>
+prepareStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A> <B>prepareStatement</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                                          int[]&nbsp;columnIndexes)
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Creates a default <code>PreparedStatement</code> object capable
+ of returning the auto-generated keys designated by the given array.
+ This array contains the indexes of the columns in the target
+ table that contain the auto-generated keys that should be made
+ available.  The driver will ignore the array if the SQL statement
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ auto-generated keys (the list of such statements is vendor-specific).
+ <p>
+ An SQL statement with or without IN parameters can be
+ pre-compiled and stored in a <code>PreparedStatement</code> object. This
+ object can then be used to efficiently execute this statement
+ multiple times.
+ <P>
+ <B>Note:</B> This method is optimized for handling
+ parametric SQL statements that benefit from precompilation. If
+ the driver supports precompilation,
+ the method <code>prepareStatement</code> will send
+ the statement to the database for precompilation. Some drivers
+ may not support precompilation. In this case, the statement may
+ not be sent to the database until the <code>PreparedStatement</code>
+ object is executed.  This has no direct effect on users; however, it does
+ affect which methods throw certain SQLExceptions.
+ <P>
+ Result sets created using the returned <code>PreparedStatement</code>
+ object will by default be type <code>TYPE_FORWARD_ONLY</code>
+ and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+ (JDBC4 Clarification:)
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Supported in 2.0
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareStatement(java.lang.String, int[])" title="class or interface in java.sql">prepareStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL statement that may contain one or more '?' IN
+        parameter placeholders<DD><CODE>columnIndexes</CODE> - an array of column indexes indicating the columns
+        that should be returned from the inserted row or rows
+<DT><B>Returns:</B><DD>a new <code>PreparedStatement</code> object, containing the
+         pre-compiled statement, that is capable of returning the
+         auto-generated keys designated by the given array of column
+         indexes
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prepareStatement(java.lang.String, java.lang.String[])"><!-- --></A><H3>
+prepareStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A> <B>prepareStatement</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+
+ Creates a default <code>PreparedStatement</code> object capable
+ of returning the auto-generated keys designated by the given array.
+ This array contains the names of the columns in the target
+ table that contain the auto-generated keys that should be returned.
+ The driver will ignore the array if the SQL statement
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ auto-generated keys (the list of such statements is vendor-specific).
+ <P>
+ An SQL statement with or without IN parameters can be
+ pre-compiled and stored in a <code>PreparedStatement</code> object. This
+ object can then be used to efficiently execute this statement
+ multiple times.
+ <P>
+ <B>Note:</B> This method is optimized for handling
+ parametric SQL statements that benefit from precompilation. If
+ the driver supports precompilation,
+ the method <code>prepareStatement</code> will send
+ the statement to the database for precompilation. Some drivers
+ may not support precompilation. In this case, the statement may
+ not be sent to the database until the <code>PreparedStatement</code>
+ object is executed.  This has no direct effect on users; however, it does
+ affect which methods throw certain SQLExceptions.
+ <P>
+ Result sets created using the returned <code>PreparedStatement</code>
+ object will by default be type <code>TYPE_FORWARD_ONLY</code>
+ and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+ (JDBC4 Clarification:)
+ The holdability of the created result sets can be determined by
+ calling <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#getHoldability()"><CODE>getHoldability()</CODE></A>.
+
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Supported in 2.0
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#prepareStatement(java.lang.String, java.lang.String[])" title="class or interface in java.sql">prepareStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL statement that may contain one or more '?' IN
+        parameter placeholders<DD><CODE>columnNames</CODE> - an array of column names indicating the columns
+        that should be returned from the inserted row or rows
+<DT><B>Returns:</B><DD>a new <code>PreparedStatement</code> object, containing the
+         pre-compiled statement, that is capable of returning the
+         auto-generated keys designated by the given array of column
+         names
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ (JDBC4 Clarification:)
+ or this method is called on a closed connection
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createClob()"><!-- --></A><H3>
+createClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A> <B>createClob</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs an object that implements the <code>Clob</code> interface. The object
+ returned initially contains no data.  The <code>setAsciiStream</code>,
+ <code>setCharacterStream</code> and <code>setString</code> methods of
+ the <code>Clob</code> interface may be used to add data to the <code>Clob</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createClob()" title="class or interface in java.sql">createClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>An object that implements the <code>Clob</code> interface
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an object that implements the
+ <code>Clob</code> interface can not be constructed, this method is
+ called on a closed connection or a database access error occurs.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createBlob()"><!-- --></A><H3>
+createBlob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A> <B>createBlob</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs an object that implements the <code>Blob</code> interface. The object
+ returned initially contains no data.  The <code>setBinaryStream</code> and
+ <code>setBytes</code> methods of the <code>Blob</code> interface may be used to add data to
+ the <code>Blob</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createBlob()" title="class or interface in java.sql">createBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>An object that implements the <code>Blob</code> interface
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an object that implements the
+ <code>Blob</code> interface can not be constructed, this method is
+ called on a closed connection or a database access error occurs.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createNClob()"><!-- --></A><H3>
+createNClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A> <B>createNClob</B>()
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs an object that implements the <code>NClob</code> interface. The object
+ returned initially contains no data.  The <code>setAsciiStream</code>,
+ <code>setCharacterStream</code> and <code>setString</code> methods of the <code>NClob</code> interface may
+ be used to add data to the <code>NClob</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createNClob()" title="class or interface in java.sql">createNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>An object that implements the <code>NClob</code> interface
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an object that implements the
+ <code>NClob</code> interface can not be constructed, this method is
+ called on a closed connection or a database access error occurs.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createSQLXML()"><!-- --></A><H3>
+createSQLXML</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A> <B>createSQLXML</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs an object that implements the <code>SQLXML</code> interface. The object
+ returned initially contains no data. The <code>createXmlStreamWriter</code> object and
+ <code>setString</code> method of the <code>SQLXML</code> interface may be used to add data to the <code>SQLXML</code>
+ object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createSQLXML()" title="class or interface in java.sql">createSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>An object that implements the <code>SQLXML</code> interface
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an object that implements the <code>SQLXML</code> interface can not
+ be constructed, this method is
+ called on a closed connection or a database access error occurs.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isValid(int)"><!-- --></A><H3>
+isValid</H3>
+<PRE>
+public boolean <B>isValid</B>(int&nbsp;timeout)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if the connection has not been closed and is still valid.
+ The driver shall submit a query on the connection or use some other
+ mechanism that positively verifies the connection is still valid when
+ this method is called.
+ <p>
+ The query submitted by the driver to validate the connection shall be
+ executed in the context of the current transaction.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#isValid(int)" title="class or interface in java.sql">isValid</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>timeout</CODE> - -         The time in seconds to wait for the database operation
+                                          used to validate the connection to complete.  If
+                                          the timeout period expires before the operation
+                                          completes, this method returns false.  A value of
+                                          0 indicates a timeout is not applied to the
+                                          database operation.
+ <p>
+<DT><B>Returns:</B><DD>true if the connection is valid, false otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the value supplied for <code>timeout</code>
+ is less then 0<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0
+ <p></DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getClientInfoProperties()"><CODE>JDBCDatabaseMetaData.getClientInfoProperties()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClientInfo(java.lang.String, java.lang.String)"><!-- --></A><H3>
+setClientInfo</H3>
+<PRE>
+public void <B>setClientInfo</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;value)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLClientInfoException.html?is-external=true" title="class or interface in java.sql">SQLClientInfoException</A></PRE>
+<DL>
+<DD>Sets the value of the client info property specified by name to the
+ value specified by value.
+ <p>
+ Applications may use the <code>DatabaseMetaData.getClientInfoProperties</code>
+ method to determine the client info properties supported by the driver
+ and the maximum length that may be specified for each property.
+ <p>
+ The driver stores the value specified in a suitable location in the
+ database.  For example in a special register, session parameter, or
+ system table column.  For efficiency the driver may defer setting the
+ value in the database until the next time a statement is executed or
+ prepared.  Other than storing the client information in the appropriate
+ place in the database, these methods shall not alter the behavior of
+ the connection in anyway.  The values supplied to these methods are
+ used for accounting, diagnostics and debugging purposes only.
+ <p>
+ The driver shall generate a warning if the client info name specified
+ is not recognized by the driver.
+ <p>
+ If the value specified to this method is greater than the maximum
+ length for the property the driver may either truncate the value and
+ generate a warning or generate a <code>SQLClientInfoException</code>.  If the driver
+ generates a <code>SQLClientInfoException</code>, the value specified was not set on the
+ connection.
+ <p>
+ The following are standard client info properties.  Drivers are not
+ required to support these properties however if the driver supports a
+ client info property that can be described by one of the standard
+ properties, the standard property name should be used.
+ <p>
+ <ul>
+ <li>ApplicationName      -       The name of the application currently utilizing
+                                                  the connection</li>
+ <li>ClientUser           -       The name of the user that the application using
+                                                  the connection is performing work for.  This may
+                                                  not be the same as the user name that was used
+                                                  in establishing the connection.</li>
+ <li>ClientHostname       -       The hostname of the computer the application
+                                                  using the connection is running on.</li>
+ </ul>
+ <p>
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0, throws an SQLClientInfoException when this method is
+ called.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setClientInfo(java.lang.String, java.lang.String)" title="class or interface in java.sql">setClientInfo</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - The name of the client info property to set<DD><CODE>value</CODE> - The value to set the client info property to.  If the
+                                  value is null, the current value of the specified
+                                  property is cleared.
+ <p>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLClientInfoException.html?is-external=true" title="class or interface in java.sql">SQLClientInfoException</A></CODE> - if the database server returns an error while
+                  setting the client info value on the database server or this method
+ is called on a closed connection
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClientInfo(java.util.Properties)"><!-- --></A><H3>
+setClientInfo</H3>
+<PRE>
+public void <B>setClientInfo</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A>&nbsp;properties)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLClientInfoException.html?is-external=true" title="class or interface in java.sql">SQLClientInfoException</A></PRE>
+<DL>
+<DD>Sets the value of the connection's client info properties.  The
+ <code>Properties</code> object contains the names and values of the client info
+ properties to be set.  The set of client info properties contained in
+ the properties list replaces the current set of client info properties
+ on the connection.  If a property that is currently set on the
+ connection is not present in the properties list, that property is
+ cleared.  Specifying an empty properties list will clear all of the
+ properties on the connection.  See <code>setClientInfo (String, String)</code> for
+ more information.
+ <p>
+ If an error occurs in setting any of the client info properties, a
+ <code>SQLClientInfoException</code> is thrown. The <code>SQLClientInfoException</code>
+ contains information indicating which client info properties were not set.
+ The state of the client information is unknown because
+ some databases do not allow multiple client info properties to be set
+ atomically.  For those databases, one or more properties may have been
+ set before the error occurred.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setClientInfo(java.util.Properties)" title="class or interface in java.sql">setClientInfo</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>properties</CODE> - the list of client info properties to set
+ <p>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLClientInfoException.html?is-external=true" title="class or interface in java.sql">SQLClientInfoException</A></CODE> - if the database server returns an error while
+                  setting the clientInfo values on the database server or this method
+ is called on a closed connection
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0
+ <p></DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#setClientInfo(java.lang.String, java.lang.String)" title="class or interface in java.sql"><CODE>setClientInfo(String, String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getClientInfo(java.lang.String)"><!-- --></A><H3>
+getClientInfo</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getClientInfo</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns the value of the client info property specified by name.  This
+ method may return null if the specified client info property has not
+ been set and does not have a default value.  This method will also
+ return null if the specified client info property name is not supported
+ by the driver.
+ <p>
+ Applications may use the <code>DatabaseMetaData.getClientInfoProperties</code>
+ method to determine the client info properties supported by the driver.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getClientInfo(java.lang.String)" title="class or interface in java.sql">getClientInfo</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - The name of the client info property to retrieve
+ <p>
+<DT><B>Returns:</B><DD>The value of the client info property specified
+ <p>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the database server returns an error when
+                                                  fetching the client info value from the database
+ or this method is called on a closed connection
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0
+ <p></DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getClientInfoProperties()" title="class or interface in java.sql"><CODE>DatabaseMetaData.getClientInfoProperties()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getClientInfo()"><!-- --></A><H3>
+getClientInfo</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A> <B>getClientInfo</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns a list containing the name and current value of each client info
+ property supported by the driver.  The value of a client info property
+ may be null if the property has not been set and does not have a
+ default value.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#getClientInfo()" title="class or interface in java.sql">getClientInfo</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>A <code>Properties</code> object that contains the name and current value of
+                  each of the client info properties supported by the driver.
+ <p>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the database server returns an error when
+                  fetching the client info values from the database
+ or this method is called on a closed connection
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createArrayOf(java.lang.String, java.lang.Object[])"><!-- --></A><H3>
+createArrayOf</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A> <B>createArrayOf</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;elements)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Factory method for creating Array objects.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createArrayOf(java.lang.String, java.lang.Object[])" title="class or interface in java.sql">createArrayOf</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>typeName</CODE> - the SQL name of the type the elements of the array map to. The typeName is a
+ database-specific name which may be the name of a built-in type, a user-defined type or a standard  SQL type supported by this database. This
+  is the value returned by <code>Array.getBaseTypeName</code><DD><CODE>elements</CODE> - the elements that populate the returned object
+<DT><B>Returns:</B><DD>an Array object whose elements map to the specified SQL type
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database error occurs, the typeName is null or this method is called on a closed connection
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.6_b80, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createStruct(java.lang.String, java.lang.Object[])"><!-- --></A><H3>
+createStruct</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Struct.html?is-external=true" title="class or interface in java.sql">Struct</A> <B>createStruct</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;attributes)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Factory method for creating Struct objects.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true#createStruct(java.lang.String, java.lang.Object[])" title="class or interface in java.sql">createStruct</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>typeName</CODE> - the SQL type name of the SQL structured type that this <code>Struct</code>
+ object maps to. The typeName is the name of  a user-defined type that
+ has been defined for this database. It is the value returned by
+ <code>Struct.getSQLTypeName</code>.<DD><CODE>attributes</CODE> - the attributes that populate the returned object
+<DT><B>Returns:</B><DD>a Struct object that maps to the given SQL type and is populated with the given attributes
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database error occurs, the typeName is null or this method is called on a closed connection
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this data type<DT><B>Since:</B></DT>
+  <DD>JDK 1.6_b80, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap(java.lang.Class)"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public &lt;T&gt; T <B>unwrap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+
+ If the receiver implements the interface then the result is the receiver
+ or a proxy for the receiver. If the receiver is a wrapper
+ and the wrapped object implements the interface then the result is the
+ wrapped object or a proxy for the wrapped object. Otherwise return the
+ the result of calling <code>unwrap</code> recursively on the wrapped object
+ or a proxy for that result. If the receiver is not a
+ wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - A Class defining an interface that the result must implement.
+<DT><B>Returns:</B><DD>an object that implements the interface. May be a proxy for the actual implementing object.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - If no object found that implements the interface<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWrapperFor(java.lang.Class)"><!-- --></A><H3>
+isWrapperFor</H3>
+<PRE>
+public boolean <B>isWrapperFor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does. Returns false otherwise. If this implements the interface then return true,
+ else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+ object. If this does not implement the interface and is not a wrapper, return false.
+ This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+ callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+ returns true then calling <code>unwrap</code> with the same argument should succeed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - a Class defining an interface.
+<DT><B>Returns:</B><DD>true if this implements the interface or directly or indirectly wraps an object that does.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while determining whether this is a wrapper
+ for an object with the given interface.<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reset()"><!-- --></A><H3>
+reset</H3>
+<PRE>
+public void <B>reset</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Resets this connection so it can be used again. Used when connections are
+ returned to a connection pool.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCConnection.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCConnection.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCConnection.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCDataSource.html b/doc/apidocs/org/hsqldb/jdbc/JDBCDataSource.html
new file mode 100644
index 0000000..2b53ac4
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCDataSource.html
@@ -0,0 +1,733 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCDataSource (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCDataSource (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCDataSource.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCDataSource.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDataSource.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCDataSource</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCDataSource</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>, <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Referenceable.html?is-external=true" title="class or interface in javax.naming">Referenceable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true" title="class or interface in javax.sql">CommonDataSource</A>, <A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html?is-external=true" title="class or interface in javax.sql">DataSource</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCDataSource</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Referenceable.html?is-external=true" title="class or interface in javax.naming">Referenceable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html?is-external=true" title="class or interface in javax.sql">DataSource</A>, <A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true" title="class or interface in javax.sql">CommonDataSource</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DL>
+</PRE>
+
+<P>
+<p>A factory for connections to the physical data source that this
+ <code>DataSource</code> object represents.  An alternative to the
+ <code>DriverManager</code> facility, a <code>DataSource</code> object
+ is the preferred means of getting a connection. An object that implements
+ the <code>DataSource</code> interface will typically be
+ registered with a naming service based on the
+ Java<sup><font size=-2>TM</font></sup> Naming and Directory (JNDI) API.
+ <P>
+ The <code>DataSource</code> interface is implemented by a driver vendor.
+ There are three types of implementations:
+ <OL>
+   <LI>Basic implementation -- produces a standard <code>Connection</code>
+       object
+   <LI>Connection pooling implementation -- produces a <code>Connection</code>
+       object that will automatically participate in connection pooling.  This
+       implementation works with a middle-tier connection pooling manager.
+   <LI>Distributed transaction implementation -- produces a
+       <code>Connection</code> object that may be used for distributed
+       transactions and almost always participates in connection pooling.
+       This implementation works with a middle-tier
+       transaction manager and almost always with a connection
+       pooling manager.
+ </OL>
+ <P>
+ A <code>DataSource</code> object has properties that can be modified
+ when necessary.  For example, if the data source is moved to a different
+ server, the property for the server can be changed.  The benefit is that
+ because the data source's properties can be changed, any code accessing
+ that data source does not need to be changed.
+ <P>
+ A driver that is accessed via a <code>DataSource</code> object does not
+ register itself with the <code>DriverManager</code>.  Rather, a
+ <code>DataSource</code> object is retrieved though a lookup operation
+ and then used to create a <code>Connection</code> object.  With a basic
+ implementation, the connection obtained through a <code>DataSource</code>
+ object is identical to a connection obtained through the
+ <code>DriverManager</code> facility.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>JDK 1.4</DD>
+<DT><B>Author:</B></DT>
+  <DD>deforest@users, boucherb@users</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.hsqldb.jdbc.JDBCDataSource">Serialized Form</A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#JDBCDataSource()">JDBCDataSource</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructor</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getConnection()">getConnection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Attempts to establish a connection with the data source that
+ this <code>DataSource</code> object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getConnection(java.lang.String, java.lang.String)">getConnection</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;username,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Attempts to establish a connection with the data source that
+ this <code>DataSource</code> object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getDatabase()">getDatabase</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the jdbc database connection url attribute.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getLoginTimeout()">getLoginTimeout</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the maximum time in seconds that this data source can wait
+ while attempting to connect to a database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getLogWriter()">getLogWriter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the log writer for this <code>DataSource</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Reference.html?is-external=true" title="class or interface in javax.naming">Reference</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getReference()">getReference</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getUser()">getUser</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the user ID for the connection.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#isWrapperFor(java.lang.Class)">isWrapperFor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#setDatabase(java.lang.String)">setDatabase</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;database)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assigns the value of this object's jdbc database connection
+ url attribute.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#setLoginTimeout(int)">setLoginTimeout</A></B>(int&nbsp;seconds)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the maximum time in seconds that this data source will wait
+ while attempting to connect to a database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#setLogWriter(java.io.PrintWriter)">setLogWriter</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A>&nbsp;logWriter)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the log writer for this <code>DataSource</code>
+ object to the given <code>java.io.PrintWriter</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#setPassword(java.lang.String)">setPassword</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the password to use for connecting to the database</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#setUser(java.lang.String)">setUser</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;user)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the userid</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T&gt; T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#unwrap(java.lang.Class)">unwrap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCDataSource()"><!-- --></A><H3>
+JDBCDataSource</H3>
+<PRE>
+public <B>JDBCDataSource</B>()</PRE>
+<DL>
+<DD>Constructor
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getConnection()"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><p>Attempts to establish a connection with the data source that
+ this <code>DataSource</code> object represents.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html?is-external=true#getConnection()" title="class or interface in javax.sql">getConnection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html?is-external=true" title="class or interface in javax.sql">DataSource</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a connection to the data source
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConnection(java.lang.String, java.lang.String)"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;username,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><p>Attempts to establish a connection with the data source that
+ this <code>DataSource</code> object represents.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html?is-external=true#getConnection(java.lang.String, java.lang.String)" title="class or interface in javax.sql">getConnection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html?is-external=true" title="class or interface in javax.sql">DataSource</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>username</CODE> - the database user on whose behalf the connection is
+  being made<DD><CODE>password</CODE> - the user's password
+<DT><B>Returns:</B><DD>a connection to the data source
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap(java.lang.Class)"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public &lt;T&gt; T <B>unwrap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+
+ If the receiver implements the interface then the result is the receiver
+ or a proxy for the receiver. If the receiver is a wrapper
+ and the wrapped object implements the interface then the result is the
+ wrapped object or a proxy for the wrapped object. Otherwise return the
+ the result of calling <code>unwrap</code> recursively on the wrapped object
+ or a proxy for that result. If the receiver is not a
+ wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - A Class defining an interface that the result must implement.
+<DT><B>Returns:</B><DD>an object that implements the interface. May be a proxy for the actual implementing object.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - If no object found that implements the interface<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWrapperFor(java.lang.Class)"><!-- --></A><H3>
+isWrapperFor</H3>
+<PRE>
+public boolean <B>isWrapperFor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does. Returns false otherwise. If this implements the interface then return true,
+ else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+ object. If this does not implement the interface and is not a wrapper, return false.
+ This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+ callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+ returns true then calling <code>unwrap</code> with the same argument should succeed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - a Class defining an interface.
+<DT><B>Returns:</B><DD>true if this implements the interface or directly or indirectly wraps an object that does.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while determining whether this is a wrapper
+ for an object with the given interface.<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDatabase()"><!-- --></A><H3>
+getDatabase</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDatabase</B>()</PRE>
+<DL>
+<DD>Retrieves the jdbc database connection url attribute. <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the jdbc database connection url attribute</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLoginTimeout()"><!-- --></A><H3>
+getLoginTimeout</H3>
+<PRE>
+public int <B>getLoginTimeout</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Gets the maximum time in seconds that this data source can wait
+ while attempting to connect to a database.  A value of zero
+ means that the timeout is the default system timeout
+ if there is one; otherwise, it means that there is no timeout.
+ When a <code>DataSource</code> object is created, the login timeout is
+ initially zero.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true#getLoginTimeout()" title="class or interface in javax.sql">getLoginTimeout</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true" title="class or interface in javax.sql">CommonDataSource</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the data source login time limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs.<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#setLoginTimeout(int)"><CODE>setLoginTimeout(int)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#setLoginTimeout(int)"><CODE>setLoginTimeout(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLogWriter()"><!-- --></A><H3>
+getLogWriter</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A> <B>getLogWriter</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><p>Retrieves the log writer for this <code>DataSource</code>
+ object.
+
+ <p>The log writer is a character output stream to which all logging
+ and tracing messages for this data source will be
+ printed.  This includes messages printed by the methods of this
+ object, messages printed by methods of other objects manufactured
+ by this object, and so on.  Messages printed to a data source
+ specific log writer are not printed to the log writer associated
+ with the <code>java.sql.Drivermanager</code> class.  When a
+ <code>DataSource</code> object is
+ created, the log writer is initially null; in other words, the
+ default is for logging to be disabled.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true#getLogWriter()" title="class or interface in javax.sql">getLogWriter</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true" title="class or interface in javax.sql">CommonDataSource</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the log writer for this data source or null if
+        logging is disabled
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#setLogWriter(java.io.PrintWriter)"><CODE>setLogWriter(java.io.PrintWriter)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getReference()"><!-- --></A><H3>
+getReference</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Reference.html?is-external=true" title="class or interface in javax.naming">Reference</A> <B>getReference</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/NamingException.html?is-external=true" title="class or interface in javax.naming">NamingException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Referenceable.html?is-external=true#getReference()" title="class or interface in javax.naming">getReference</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Referenceable.html?is-external=true" title="class or interface in javax.naming">Referenceable</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/NamingException.html?is-external=true" title="class or interface in javax.naming">NamingException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUser()"><!-- --></A><H3>
+getUser</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getUser</B>()</PRE>
+<DL>
+<DD>Retrieves the user ID for the connection. <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the user ID for the connection</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDatabase(java.lang.String)"><!-- --></A><H3>
+setDatabase</H3>
+<PRE>
+public void <B>setDatabase</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;database)</PRE>
+<DL>
+<DD>Assigns the value of this object's jdbc database connection
+ url attribute. <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>database</CODE> - the new value of this object's jdbc database connection
+      url attribute</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLoginTimeout(int)"><!-- --></A><H3>
+setLoginTimeout</H3>
+<PRE>
+public void <B>setLoginTimeout</B>(int&nbsp;seconds)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><p>Sets the maximum time in seconds that this data source will wait
+ while attempting to connect to a database.  A value of zero
+ specifies that the timeout is the default system timeout
+ if there is one; otherwise, it specifies that there is no timeout.
+ When a <code>DataSource</code> object is created, the login timeout is
+ initially zero.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true#setLoginTimeout(int)" title="class or interface in javax.sql">setLoginTimeout</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true" title="class or interface in javax.sql">CommonDataSource</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>seconds</CODE> - the data source login time limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs.<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getLoginTimeout()"><CODE>getLoginTimeout()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLogWriter(java.io.PrintWriter)"><!-- --></A><H3>
+setLogWriter</H3>
+<PRE>
+public void <B>setLogWriter</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A>&nbsp;logWriter)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><p>Sets the log writer for this <code>DataSource</code>
+ object to the given <code>java.io.PrintWriter</code> object.
+
+ <p>The log writer is a character output stream to which all logging
+ and tracing messages for this data source will be
+ printed.  This includes messages printed by the methods of this
+ object, messages printed by methods of other objects manufactured
+ by this object, and so on.  Messages printed to a data source-
+ specific log writer are not printed to the log writer associated
+ with the <code>java.sql.DriverManager</code> class. When a
+ <code>DataSource</code> object is created the log writer is
+ initially null; in other words, the default is for logging to be
+ disabled.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true#setLogWriter(java.io.PrintWriter)" title="class or interface in javax.sql">setLogWriter</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true" title="class or interface in javax.sql">CommonDataSource</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>logWriter</CODE> - the new log writer; to disable logging, set to null
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html#getLogWriter()"><CODE>getLogWriter()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setPassword(java.lang.String)"><!-- --></A><H3>
+setPassword</H3>
+<PRE>
+public void <B>setPassword</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password)</PRE>
+<DL>
+<DD>Sets the password to use for connecting to the database
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>password</CODE> - the password</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setUser(java.lang.String)"><!-- --></A><H3>
+setUser</H3>
+<PRE>
+public void <B>setUser</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;user)</PRE>
+<DL>
+<DD>Sets the userid
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>user</CODE> - the user id</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCDataSource.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCDataSource.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDataSource.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCDataSourceFactory.html b/doc/apidocs/org/hsqldb/jdbc/JDBCDataSourceFactory.html
new file mode 100644
index 0000000..5b1f6a6
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCDataSourceFactory.html
@@ -0,0 +1,287 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCDataSourceFactory (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCDataSourceFactory (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCDataSourceFactory.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCDataSourceFactory.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDataSourceFactory.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCDataSourceFactory</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCDataSourceFactory</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/spi/ObjectFactory.html?is-external=true" title="class or interface in javax.naming.spi">ObjectFactory</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCDataSourceFactory</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/spi/ObjectFactory.html?is-external=true" title="class or interface in javax.naming.spi">ObjectFactory</A></DL>
+</PRE>
+
+<P>
+A JNDI ObjectFactory for creating <A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><CODE>JDBCDataSource</CODE></A>
+ object instances.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>deforest@users</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html#JDBCDataSourceFactory()">JDBCDataSourceFactory</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)">getObjectInstance</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;obj,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Name.html?is-external=true" title="class or interface in javax.naming">Name</A>&nbsp;name,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Context.html?is-external=true" title="class or interface in javax.naming">Context</A>&nbsp;nameCtx,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Hashtable.html?is-external=true" title="class or interface in java.util">Hashtable</A>&nbsp;environment)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a JDBCDataSource object using the location or reference
+ information specified.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCDataSourceFactory()"><!-- --></A><H3>
+JDBCDataSourceFactory</H3>
+<PRE>
+public <B>JDBCDataSourceFactory</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)"><!-- --></A><H3>
+getObjectInstance</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObjectInstance</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;obj,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Name.html?is-external=true" title="class or interface in javax.naming">Name</A>&nbsp;name,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Context.html?is-external=true" title="class or interface in javax.naming">Context</A>&nbsp;nameCtx,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Hashtable.html?is-external=true" title="class or interface in java.util">Hashtable</A>&nbsp;environment)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></PRE>
+<DL>
+<DD>Creates a JDBCDataSource object using the location or reference
+ information specified.<p>
+
+ The Reference object should support the properties, database, user,
+ password.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/spi/ObjectFactory.html?is-external=true#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)" title="class or interface in javax.naming.spi">getObjectInstance</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/spi/ObjectFactory.html?is-external=true" title="class or interface in javax.naming.spi">ObjectFactory</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - The reference information used in creating a
+      JDBCDatasource object.<DD><CODE>name</CODE> - ignored<DD><CODE>nameCtx</CODE> - ignored<DD><CODE>environment</CODE> - ignored
+<DT><B>Returns:</B><DD>A newly created JDBCDataSource object; null if an object
+      cannot be created.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></CODE> - never</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCDataSourceFactory.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCDataSourceFactory.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDataSourceFactory.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html b/doc/apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html
new file mode 100644
index 0000000..88c4cbb
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html
@@ -0,0 +1,8576 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:45 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCDatabaseMetaData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCDatabaseMetaData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCDatabaseMetaData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCDatabaseMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDatabaseMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCDatabaseMetaData</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCDatabaseMetaData</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCDatabaseMetaData</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DL>
+</PRE>
+
+<P>
+Comprehensive information about the database as a whole.
+ <P>
+ This interface is implemented by driver vendors to let users know the capabilities
+ of a Database Management System (DBMS) in combination with
+ the driver based on JDBC<sup><font size=-2>TM</font></sup> technology
+ ("JDBC driver") that is used with it.  Different relational DBMSs often support
+ different features, implement features in different ways, and use different
+ data types.  In addition, a driver may implement a feature on top of what the
+ DBMS offers.  Information returned by methods in this interface applies
+ to the capabilities of a particular driver and a particular DBMS working
+ together. Note that as used in this documentation, the term "database" is
+ used generically to refer to both the driver and DBMS.
+ <P>
+ A user for this interface is commonly a tool that needs to discover how to
+ deal with the underlying DBMS.  This is especially true for applications
+ that are intended to be used with more than one DBMS. For example, a tool might use the method
+ <code>getTypeInfo</code> to find out what data types can be used in a
+ <code>CREATE TABLE</code> statement.  Or a user might call the method
+ <code>supportsCorrelatedSubqueries</code> to see if it is possible to use
+ a correlated subquery or <code>supportsBatchUpdates</code> to see if it is
+ possible to use batch updates.
+ <P>
+ Some <code>DatabaseMetaData</code> methods return lists of information
+ in the form of <code>ResultSet</code> objects.
+ Regular <code>ResultSet</code> methods, such as
+ <code>getString</code> and <code>getInt</code>, can be used
+ to retrieve the data from these <code>ResultSet</code> objects.  If
+ a given form of metadata is not available, an empty <code>ResultSet</code>
+ will be returned. Additional columns beyond the columns defined to be
+ returned by the <code>ResultSet</code> object for a given method
+ can be defined by the JDBC driver vendor and must be accessed
+ by their <B>column label</B>.
+ <P>
+ Some <code>DatabaseMetaData</code> methods take arguments that are
+ String patterns.  These arguments all have names such as fooPattern.
+ Within a pattern String, "%" means match any substring of 0 or more
+ characters, and "_" means match any one character. Only metadata
+ entries matching the search pattern are returned. If a search pattern
+ argument is set to <code>null</code>, that argument's criterion will
+ be dropped from the search.
+ <P>
+ A method that gets information about a feature that the driver does not
+ support will throw an <code>SQLException</code>.
+ In the case of methods that return a <code>ResultSet</code>
+ object, either a <code>ResultSet</code> object (which may be empty) is
+ returned or an <code>SQLException</code> is thrown.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 1.7.2, an option is provided to allow alternate
+ system table production implementations.  In this distribution, there are
+ three implementations whose behaviour ranges from producing no system
+ tables at all to producing a richer and more complete body of information
+ about an HSQLDB database than was previously available. The information
+ provided through the default implementation is, unlike previous
+ versions, accessible to all database users, regardless of admin status.
+ This is now possible because the table content it produces for each
+ user is pre-filtered, based on the user's access rights. That is, each
+ system table now acts like a security-aware View.<p>
+
+ The process of installing a system table production class is transparent and
+ occurs dynamically at runtime during the opening sequence of a
+ <code>Database</code> instance, in the newDatabaseInformation() factory
+ method of the revised DatabaseInformation class, using the following
+ steps: <p>
+
+ <div class="GeneralExample">
+ <ol>
+ <li>If a class whose fully qualified name is org.hsqldb.dbinfo.DatabaseInformationFull
+     can be found and it has an accesible constructor that takes an
+     org.hsqldb.Database object as its single parameter, then an instance of
+     that class is reflectively instantiated and is used by the database
+     instance to produce its system tables. <p>
+
+ <li>If 1.) fails, then the process is repeated, attempting to create an
+     instance of org.hsqldb.dbinfo.DatabaseInformationMain (which provides just the
+     core set of system tables required to service this class, but now does
+     so in a more security aware and comprehensive fashion). <p>
+
+ <li>If 2.) fails, then an instance of org.hsqldb.dbinfo.DatabaseInformation is
+     installed (that, by default, produces no system tables, meaning that
+     calls to all related methods in this class will fail, throwing an
+     SQLException stating that a required system table is not found). <p>
+
+ </ol>
+ </div> <p>
+
+ The process of searching for alternate implementations of database
+ support classes, ending with the installation of a minimal but functional
+ default will be refered to henceforth as <i>graceful degradation</i>.
+ This process is advantageous in that it allows developers and administrators
+ to easily choose packaging options, simply by adding to or deleting concerned
+ classes from an  HSQLDB installation, without worry over providing complex
+ initialization properties or disrupting the core operation of the engine.
+ In this particular context, <i>graceful degradation</i> allows easy choices
+ regarding database metadata, spanning the range of full (design-time),
+ custom-written, minimal (production-time) or <CODE>null</CODE>
+ (space-constrained) system table production implementations. <p>
+
+ In the default full implementation, a number of new system tables are
+ provided that, although not used directly by this class, present previously
+ unavailable information about the database, such as about its triggers and
+ aliases. <p>
+
+ In order to better support graphical database exploration tools and as an
+ experimental intermediate step toward more fully supporting SQL9n and
+ SQL200n, the default installed DatabaseInformation implementation
+ is also capable of reporting pseudo name space information, such as
+ the catalog (database URI) of database objects. <p>
+
+ The catalog reporting feature is turned off by default but
+ can be turned on by providing the appropriate entries in the database
+ properties file (see the advanced topics section of the product
+ documentation). <p>
+
+ When the feature is turned on, catalog is reported using
+ the following conventions: <p>
+
+ <ol>
+ <li>All objects are reported as having a catalog equal to the URI of the
+     database, which is equivalent to the catenation of the
+     <b>&lt;type&gt;</b> and <b>&lt;path&gt;</b> portions of the HSQLDB
+     internal JDBC connection URL.<p>
+
+     Examples: <p>
+
+     <pre class="JavaCodeExample">
+     <span class="JavaStringLiteral">&quot;jdbc:hsqldb:file:test&quot;</span>      => <span class="JavaStringLiteral">&quot;file:test&quot;</span>
+     <span class="JavaStringLiteral">&quot;jdbc:hsqldb:mem:.&quot;</span>          => <span class="JavaStringLiteral">&quot;mem:.&quot;</span>
+     <span class="JavaStringLiteral">&quot;jdbc:hsqldb:hsql:/host/<alias>...&quot;</span> => URI of aliased database
+     <span class="JavaStringLiteral">&quot;jdbc:hsqldb:http:/host/<alias>...&quot;</span> => URI of aliased database
+     </pre>
+
+     <b>Note:</b> No provision is made for qualifying database objects
+     by catalog in DML or DDL SQL.  This feature is functional only with
+     respect to browsing the database through the DatabaseMetaData and system
+     table interfaces. <p>
+
+ </ol>
+
+ Again, it should be well understood that this feature provide an
+ <i>emulation</i> of catalog support and is intended only
+ as an experimental implementation to enhance the browsing experience
+ when using graphical database explorers and to make a first foray
+ into tackling the issue of implementing true catalog support
+ in the future. <p>
+
+ Due the nature of the new database system table production process, fewer
+ assumptions can be made by this class about what information is made
+ available in the system tables supporting <code>DatabaseMetaData</code>
+ methods. Because of this, the SQL queries behind the <code>ResultSet</code>
+ producing methods have been cleaned up and made to adhere more strictly to
+ the JDBC contracts specified in relation to the method parameters. <p>
+
+ One of the remaining assumptions concerns the <code>approximate</code>
+ argument of <A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getIndexInfo(java.lang.String, java.lang.String, java.lang.String, boolean, boolean)"><CODE>getIndexInfo()</CODE></A>. This parameter is still
+ ignored since there is not yet any process in place to internally gather
+ and persist table and index statistics.  A primitive version of a statistics
+ gathering and reporting subsystem <em>may</em> be introduced at some time in
+ the future. <p>
+
+ Another assumption is that simple select queries against certain system
+ tables will return rows in JDBC contract order in the absence of an
+ &quot;ORDER BY&quot; clause.  The reason for this is that results
+ come back much faster when no &quot;ORDER BY&quot; clause is used.
+ Developers wishing to extend or replace an existing system table production
+ class should be aware of this, either adding the contract
+ &quot;ORDER BY&quot; clause to the SQL in corresponding methods in this class,
+ or, better, by maintaing rows in the correct order in the underlying
+ system tables, prefereably by creating appropriate primary indices. <p>
+
+ <hr>
+
+ <b>JRE 1.1.x Notes:</b> <p>
+
+ In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ versions of JDBC depends on the JDK version used for compiling and building
+ HSQLDB.<p>
+
+ Since 1.7.0, it is possible to build the product so that
+ all JDBC 2 methods can be called while executing under the version 1.1.x
+ <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ However, some of these method calls require <code>int</code> values that
+ are defined only in the JDBC 2 or greater version of the
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A> interface.  For this reason, when the
+ product is compiled under JDK 1.1.x, these values are defined in
+ <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A>.<p>
+
+ In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ to them in parameter specifications and return value comparisons,
+ respectively, as follows: <p>
+
+ <pre class="JavaCodeExample">
+ JDBCResultSet.FETCH_FORWARD
+ JDBCResultSet.TYPE_FORWARD_ONLY
+ JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ JDBCResultSet.CONCUR_READ_ONLY
+ // etc
+ </pre>
+
+ However, please note that code written in such a manner will not be
+ compatible for use with other JDBC 2 drivers, since they expect and use
+ <code>ResultSet</code>, rather than <code>JDBCResultSet</code>.  Also
+ note, this feature is offered solely as a convenience to developers
+ who must work under JDK 1.1.x due to operating constraints, yet wish to
+ use some of the more advanced features available under the JDBC 2
+ specification.<p>
+
+ (fredt@users)<br>
+ (boucherb@users)
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+<DT><B>See Also:</B><DD><CODE>DatabaseInformation</CODE>, 
+<CODE>DatabaseInformationMain</CODE>, 
+<CODE>DatabaseInformationFull</CODE></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#JDBC_MAJOR">JDBC_MAJOR</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.sql.DatabaseMetaData"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#attributeNoNulls" title="class or interface in java.sql">attributeNoNulls</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#attributeNullable" title="class or interface in java.sql">attributeNullable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#attributeNullableUnknown" title="class or interface in java.sql">attributeNullableUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#bestRowNotPseudo" title="class or interface in java.sql">bestRowNotPseudo</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#bestRowPseudo" title="class or interface in java.sql">bestRowPseudo</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#bestRowSession" title="class or interface in java.sql">bestRowSession</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#bestRowTemporary" title="class or interface in java.sql">bestRowTemporary</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#bestRowTransaction" title="class or interface in java.sql">bestRowTransaction</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#bestRowUnknown" title="class or interface in java.sql">bestRowUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#columnNoNulls" title="class or interface in java.sql">columnNoNulls</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#columnNullable" title="class or interface in java.sql">columnNullable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#columnNullableUnknown" title="class or interface in java.sql">columnNullableUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionColumnIn" title="class or interface in java.sql">functionColumnIn</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionColumnInOut" title="class or interface in java.sql">functionColumnInOut</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionColumnOut" title="class or interface in java.sql">functionColumnOut</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionColumnResult" title="class or interface in java.sql">functionColumnResult</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionColumnUnknown" title="class or interface in java.sql">functionColumnUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionNoNulls" title="class or interface in java.sql">functionNoNulls</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionNoTable" title="class or interface in java.sql">functionNoTable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionNullable" title="class or interface in java.sql">functionNullable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionNullableUnknown" title="class or interface in java.sql">functionNullableUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionResultUnknown" title="class or interface in java.sql">functionResultUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionReturn" title="class or interface in java.sql">functionReturn</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#functionReturnsTable" title="class or interface in java.sql">functionReturnsTable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#importedKeyCascade" title="class or interface in java.sql">importedKeyCascade</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#importedKeyInitiallyDeferred" title="class or interface in java.sql">importedKeyInitiallyDeferred</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#importedKeyInitiallyImmediate" title="class or interface in java.sql">importedKeyInitiallyImmediate</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#importedKeyNoAction" title="class or interface in java.sql">importedKeyNoAction</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#importedKeyNotDeferrable" title="class or interface in java.sql">importedKeyNotDeferrable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#importedKeyRestrict" title="class or interface in java.sql">importedKeyRestrict</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#importedKeySetDefault" title="class or interface in java.sql">importedKeySetDefault</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#importedKeySetNull" title="class or interface in java.sql">importedKeySetNull</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureColumnIn" title="class or interface in java.sql">procedureColumnIn</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureColumnInOut" title="class or interface in java.sql">procedureColumnInOut</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureColumnOut" title="class or interface in java.sql">procedureColumnOut</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureColumnResult" title="class or interface in java.sql">procedureColumnResult</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureColumnReturn" title="class or interface in java.sql">procedureColumnReturn</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureColumnUnknown" title="class or interface in java.sql">procedureColumnUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureNoNulls" title="class or interface in java.sql">procedureNoNulls</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureNoResult" title="class or interface in java.sql">procedureNoResult</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureNullable" title="class or interface in java.sql">procedureNullable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureNullableUnknown" title="class or interface in java.sql">procedureNullableUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureResultUnknown" title="class or interface in java.sql">procedureResultUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#procedureReturnsResult" title="class or interface in java.sql">procedureReturnsResult</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#sqlStateSQL" title="class or interface in java.sql">sqlStateSQL</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#sqlStateSQL99" title="class or interface in java.sql">sqlStateSQL99</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#sqlStateXOpen" title="class or interface in java.sql">sqlStateXOpen</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#tableIndexClustered" title="class or interface in java.sql">tableIndexClustered</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#tableIndexHashed" title="class or interface in java.sql">tableIndexHashed</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#tableIndexOther" title="class or interface in java.sql">tableIndexOther</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#tableIndexStatistic" title="class or interface in java.sql">tableIndexStatistic</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#typeNoNulls" title="class or interface in java.sql">typeNoNulls</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#typeNullable" title="class or interface in java.sql">typeNullable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#typeNullableUnknown" title="class or interface in java.sql">typeNullableUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#typePredBasic" title="class or interface in java.sql">typePredBasic</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#typePredChar" title="class or interface in java.sql">typePredChar</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#typePredNone" title="class or interface in java.sql">typePredNone</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#typeSearchable" title="class or interface in java.sql">typeSearchable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#versionColumnNotPseudo" title="class or interface in java.sql">versionColumnNotPseudo</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#versionColumnPseudo" title="class or interface in java.sql">versionColumnPseudo</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#versionColumnUnknown" title="class or interface in java.sql">versionColumnUnknown</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#allProceduresAreCallable()">allProceduresAreCallable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the current user can call all the procedures
+ returned by the method <code>getProcedures</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#allTablesAreSelectable()">allTablesAreSelectable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the current user can use all the tables returned
+ by the method <code>getTables</code> in a <code>SELECT</code>
+ statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#autoCommitFailureClosesAllResultSets()">autoCommitFailureClosesAllResultSets</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a <code>SQLException</code> while autoCommit is <code>true</code> inidcates
+ that all open ResultSets are closed, even ones that are holdable.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#dataDefinitionCausesTransactionCommit()">dataDefinitionCausesTransactionCommit</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a data definition statement within a transaction forces
+ the transaction to commit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#dataDefinitionIgnoredInTransactions()">dataDefinitionIgnoredInTransactions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database ignores a data definition statement
+ within a transaction.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#deletesAreDetected(int)">deletesAreDetected</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether or not a visible row delete can be detected by
+ calling the method <code>ResultSet.rowDeleted</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#doesMaxRowSizeIncludeBlobs()">doesMaxRowSizeIncludeBlobs</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the return value for the method
+ <code>getMaxRowSize</code> includes the SQL data types
+ <code>LONGVARCHAR</code> and <code>LONGVARBINARY</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getAttributes(java.lang.String, java.lang.String, java.lang.String, java.lang.String)">getAttributes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeNamePattern,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;attributeNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the given attribute of the given type
+ for a user-defined type (UDT) that is available in the given schema
+ and catalog.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getBestRowIdentifier(java.lang.String, java.lang.String, java.lang.String, int, boolean)">getBestRowIdentifier</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table,
+                     int&nbsp;scope,
+                     boolean&nbsp;nullable)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of a table's optimal set of columns that
+ uniquely identifies a row.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getCatalogs()">getCatalogs</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the catalog names available in this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getCatalogSeparator()">getCatalogSeparator</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>String</code> that this database uses as the
+ separator between a catalog and table name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getCatalogTerm()">getCatalogTerm</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the database vendor's preferred term for "catalog".</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getClientInfoProperties()">getClientInfoProperties</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a list of the client info properties
+ that the driver supports.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getColumnPrivileges(java.lang.String, java.lang.String, java.lang.String, java.lang.String)">getColumnPrivileges</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the access rights for a table's columns.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)">getColumns</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tableNamePattern,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of table columns available in
+ the specified catalog.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getConnection()">getConnection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the connection that produced this metadata object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getCrossReference(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)">getCrossReference</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parentCatalog,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parentSchema,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parentTable,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;foreignCatalog,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;foreignSchema,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;foreignTable)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Retrieves a description of the foreign key columns in the given foreign key
+ table that reference the primary key or the columns representing a unique constraint of the  parent table (could be the same or a different table).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDatabaseMajorVersion()">getDatabaseMajorVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the major version number of the underlying database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDatabaseMinorVersion()">getDatabaseMinorVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the minor version number of the underlying database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDatabaseProductName()">getDatabaseProductName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the name of this database product.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDatabaseProductVersion()">getDatabaseProductVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the version number of this database product.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDefaultTransactionIsolation()">getDefaultTransactionIsolation</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves this database's default transaction isolation level.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDriverMajorVersion()">getDriverMajorVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves this JDBC driver's major version number.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDriverMinorVersion()">getDriverMinorVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves this JDBC driver's minor version number.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDriverName()">getDriverName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the name of this JDBC driver.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getDriverVersion()">getDriverVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the version number of this JDBC driver as a <code>String</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getExportedKeys(java.lang.String, java.lang.String, java.lang.String)">getExportedKeys</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the foreign key columns that reference the
+ given table's primary key columns (the foreign keys exported by a
+ table).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getExtraNameCharacters()">getExtraNameCharacters</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves all the "extra" characters that can be used in unquoted
+ identifier names (those beyond a-z, A-Z, 0-9 and _).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getFunctionColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)">getFunctionColumns</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;functionNamePattern,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the given catalog's system or user
+ function parameters and return type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getFunctions(java.lang.String, java.lang.String, java.lang.String)">getFunctions</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;functionNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the user functions available in the given
+ catalog.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getIdentifierQuoteString()">getIdentifierQuoteString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the string used to quote SQL identifiers.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getImportedKeys(java.lang.String, java.lang.String, java.lang.String)">getImportedKeys</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the primary key columns that are
+ referenced by the given table's foreign key columns (the primary keys
+ imported by a table).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getIndexInfo(java.lang.String, java.lang.String, java.lang.String, boolean, boolean)">getIndexInfo</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table,
+             boolean&nbsp;unique,
+             boolean&nbsp;approximate)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the given table's indices and statistics.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getJDBCMajorVersion()">getJDBCMajorVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the major JDBC version number for this
+ driver.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getJDBCMinorVersion()">getJDBCMinorVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the minor JDBC version number for this
+ driver.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxBinaryLiteralLength()">getMaxBinaryLiteralLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of hex characters this database allows in an
+ inline binary literal.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxCatalogNameLength()">getMaxCatalogNameLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters that this database allows in a
+ catalog name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxCharLiteralLength()">getMaxCharLiteralLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters this database allows
+ for a character literal.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnNameLength()">getMaxColumnNameLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters this database allows
+ for a column name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInGroupBy()">getMaxColumnsInGroupBy</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of columns this database allows in a
+ <code>GROUP BY</code> clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInIndex()">getMaxColumnsInIndex</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of columns this database allows in an index.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInOrderBy()">getMaxColumnsInOrderBy</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of columns this database allows in an
+ <code>ORDER BY</code> clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInSelect()">getMaxColumnsInSelect</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of columns this database allows in a
+ <code>SELECT</code> list.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxColumnsInTable()">getMaxColumnsInTable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of columns this database allows in a table.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxConnections()">getMaxConnections</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of concurrent connections to this
+ database that are possible.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxCursorNameLength()">getMaxCursorNameLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters that this database allows in a
+ cursor name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxIndexLength()">getMaxIndexLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of bytes this database allows for an
+ index, including all of the parts of the index.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxProcedureNameLength()">getMaxProcedureNameLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters that this database allows in a
+ procedure name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxRowSize()">getMaxRowSize</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of bytes this database allows in
+ a single row.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxSchemaNameLength()">getMaxSchemaNameLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters that this database allows in a
+ schema name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxStatementLength()">getMaxStatementLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters this database allows in
+ an SQL statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxStatements()">getMaxStatements</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of active statements to this database
+ that can be open at the same time.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxTableNameLength()">getMaxTableNameLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters this database allows in
+ a table name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxTablesInSelect()">getMaxTablesInSelect</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of tables this database allows in a
+ <code>SELECT</code> statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxUserNameLength()">getMaxUserNameLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of characters this database allows in
+ a user name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getNumericFunctions()">getNumericFunctions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a comma-separated list of math functions available with
+ this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String)">getPrimaryKeys</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the given table's primary key columns.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getProcedureColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)">getProcedureColumns</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;procedureNamePattern,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the given catalog's stored procedure parameter
+ and result columns.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getProcedures(java.lang.String, java.lang.String, java.lang.String)">getProcedures</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;procedureNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the stored procedures available in the given
+ catalog.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getProcedureTerm()">getProcedureTerm</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the database vendor's preferred term for "procedure".</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getResultSetHoldability()">getResultSetHoldability</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Retrieves this database's default holdability for <code>ResultSet</code>
+ objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowIdLifetime.html?is-external=true" title="class or interface in java.sql">RowIdLifetime</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getRowIdLifetime()">getRowIdLifetime</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether or not this data source supports the SQL <code>ROWID</code> type,
+ and if so  the lifetime for which a <code>RowId</code> object remains valid.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSchemas()">getSchemas</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the schema names available in this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSchemas(java.lang.String, java.lang.String)">getSchemas</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the schema names available in this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSchemaTerm()">getSchemaTerm</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the database vendor's preferred term for "schema".</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()">getSearchStringEscape</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the string that can be used to escape wildcard characters.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSQLKeywords()">getSQLKeywords</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a comma-separated list of all of this database's SQL keywords
+ that are NOT also SQL:2003 keywords.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSQLStateType()">getSQLStateType</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 modified:)
+ Indicates whether the SQLSTATE returned by <code>SQLException.getSQLState</code>
+ is X/Open (now known as Open Group) SQL CLI or SQL:2003.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getStringFunctions()">getStringFunctions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a comma-separated list of string functions available with
+ this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSuperTables(java.lang.String, java.lang.String, java.lang.String)">getSuperTables</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tableNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the table hierarchies defined in a particular
+ schema in this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSuperTypes(java.lang.String, java.lang.String, java.lang.String)">getSuperTypes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the user-defined type (UDT) hierarchies defined in a
+ particular schema in this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSystemFunctions()">getSystemFunctions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a comma-separated list of system functions available with
+ this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTablePrivileges(java.lang.String, java.lang.String, java.lang.String)">getTablePrivileges</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tableNamePattern)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the access rights for each table available
+ in a catalog.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])">getTables</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tableNamePattern,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;types)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the tables available in the given catalog.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTableTypes()">getTableTypes</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the table types available in this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTimeDateFunctions()">getTimeDateFunctions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a comma-separated list of the time and date functions available
+ with this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTypeInfo()">getTypeInfo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of all the (JDBC4 clarification:) data types supported by
+ this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getUDTs(java.lang.String, java.lang.String, java.lang.String, int[])">getUDTs</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeNamePattern,
+        int[]&nbsp;types)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of the user-defined types (UDTs) defined
+ in a particular schema.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getURL()">getURL</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the URL for this DBMS.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getUserName()">getUserName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the user name as known to this database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getVersionColumns(java.lang.String, java.lang.String, java.lang.String)">getVersionColumns</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a description of a table's columns that are automatically
+ updated when any value in a row is updated.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#insertsAreDetected(int)">insertsAreDetected</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether or not a visible row insert can be detected
+ by calling the method <code>ResultSet.rowInserted</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#isCatalogAtStart()">isCatalogAtStart</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a catalog appears at the start of a fully qualified
+ table name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#isReadOnly()">isReadOnly</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database is in read-only mode.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#isWrapperFor(java.lang.Class)">isWrapperFor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#locatorsUpdateCopy()">locatorsUpdateCopy</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether updates made to a LOB are made on a copy or directly
+ to the LOB.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullPlusNonNullIsNull()">nullPlusNonNullIsNull</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports concatenations between
+ <code>NULL</code> and non-<code>NULL</code> values being
+ <code>NULL</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullsAreSortedAtEnd()">nullsAreSortedAtEnd</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether <code>NULL</code> values are sorted at the end regardless of
+ sort order.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullsAreSortedAtStart()">nullsAreSortedAtStart</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether <code>NULL</code> values are sorted at the start regardless
+ of sort order.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullsAreSortedHigh()">nullsAreSortedHigh</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether <code>NULL</code> values are sorted high.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#nullsAreSortedLow()">nullsAreSortedLow</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether <code>NULL</code> values are sorted low.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#othersDeletesAreVisible(int)">othersDeletesAreVisible</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether deletes made by others are visible.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#othersInsertsAreVisible(int)">othersInsertsAreVisible</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether inserts made by others are visible.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#othersUpdatesAreVisible(int)">othersUpdatesAreVisible</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether updates made by others are visible.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#ownDeletesAreVisible(int)">ownDeletesAreVisible</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a result set's own deletes are visible.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#ownInsertsAreVisible(int)">ownInsertsAreVisible</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a result set's own inserts are visible.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#ownUpdatesAreVisible(int)">ownUpdatesAreVisible</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether for the given type of <code>ResultSet</code> object,
+ the result set's own updates are visible.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesLowerCaseIdentifiers()">storesLowerCaseIdentifiers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in lower case.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesLowerCaseQuotedIdentifiers()">storesLowerCaseQuotedIdentifiers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in lower case.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesMixedCaseIdentifiers()">storesMixedCaseIdentifiers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in mixed case.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesMixedCaseQuotedIdentifiers()">storesMixedCaseQuotedIdentifiers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in mixed case.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseIdentifiers()">storesUpperCaseIdentifiers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in upper case.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseQuotedIdentifiers()">storesUpperCaseQuotedIdentifiers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in upper case.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsAlterTableWithAddColumn()">supportsAlterTableWithAddColumn</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports <code>ALTER TABLE</code>
+ with add column.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsAlterTableWithDropColumn()">supportsAlterTableWithDropColumn</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports <code>ALTER TABLE</code>
+ with drop column.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsANSI92EntryLevelSQL()">supportsANSI92EntryLevelSQL</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the ANSI92 entry level SQL
+ grammar.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsANSI92FullSQL()">supportsANSI92FullSQL</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the ANSI92 full SQL grammar supported.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsANSI92IntermediateSQL()">supportsANSI92IntermediateSQL</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the ANSI92 intermediate SQL grammar supported.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsBatchUpdates()">supportsBatchUpdates</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports batch updates.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInDataManipulation()">supportsCatalogsInDataManipulation</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a catalog name can be used in a data manipulation statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInIndexDefinitions()">supportsCatalogsInIndexDefinitions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a catalog name can be used in an index definition statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInPrivilegeDefinitions()">supportsCatalogsInPrivilegeDefinitions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a catalog name can be used in a privilege definition statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInProcedureCalls()">supportsCatalogsInProcedureCalls</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a catalog name can be used in a procedure call statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCatalogsInTableDefinitions()">supportsCatalogsInTableDefinitions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a catalog name can be used in a table definition statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsColumnAliasing()">supportsColumnAliasing</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports column aliasing.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsConvert()">supportsConvert</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Retrieves whether this database supports the JDBC scalar function
+ <code>CONVERT</code> for the conversion of one JDBC type to another.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsConvert(int, int)">supportsConvert</A></B>(int&nbsp;fromType,
+                int&nbsp;toType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Retrieves whether this database supports the JDBC scalar function
+ <code>CONVERT</code> for conversions between the JDBC types <i>fromType</i>
+ and <i>toType</i>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCoreSQLGrammar()">supportsCoreSQLGrammar</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the ODBC Core SQL grammar.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsCorrelatedSubqueries()">supportsCorrelatedSubqueries</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports correlated subqueries.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsDataDefinitionAndDataManipulationTransactions()">supportsDataDefinitionAndDataManipulationTransactions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports both data definition and
+ data manipulation statements within a transaction.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsDataManipulationTransactionsOnly()">supportsDataManipulationTransactionsOnly</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports only data manipulation
+ statements within a transaction.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsDifferentTableCorrelationNames()">supportsDifferentTableCorrelationNames</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether, when table correlation names are supported, they
+ are restricted to being different from the names of the tables.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsExpressionsInOrderBy()">supportsExpressionsInOrderBy</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports expressions in
+ <code>ORDER BY</code> lists.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsExtendedSQLGrammar()">supportsExtendedSQLGrammar</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the ODBC Extended SQL grammar.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsFullOuterJoins()">supportsFullOuterJoins</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports full nested outer joins.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsGetGeneratedKeys()">supportsGetGeneratedKeys</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether auto-generated keys can be retrieved after
+ a statement has been executed
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation"></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsGroupBy()">supportsGroupBy</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports some form of
+ <code>GROUP BY</code> clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsGroupByBeyondSelect()">supportsGroupByBeyondSelect</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports using columns not included in
+ the <code>SELECT</code> statement in a <code>GROUP BY</code> clause
+ provided that all of the columns in the <code>SELECT</code> statement
+ are included in the <code>GROUP BY</code> clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsGroupByUnrelated()">supportsGroupByUnrelated</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports using a column that is
+ not in the <code>SELECT</code> statement in a
+ <code>GROUP BY</code> clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsIntegrityEnhancementFacility()">supportsIntegrityEnhancementFacility</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the SQL Integrity
+ Enhancement Facility.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsLikeEscapeClause()">supportsLikeEscapeClause</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports specifying a
+ <code>LIKE</code> escape clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsLimitedOuterJoins()">supportsLimitedOuterJoins</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database provides limited support for outer
+ joins.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMinimumSQLGrammar()">supportsMinimumSQLGrammar</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the ODBC Minimum SQL grammar.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseIdentifiers()">supportsMixedCaseIdentifiers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case sensitive and as a result stores them in mixed case.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseQuotedIdentifiers()">supportsMixedCaseQuotedIdentifiers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case sensitive and as a result stores them in mixed case.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMultipleOpenResults()">supportsMultipleOpenResults</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether it is possible to have multiple <code>ResultSet</code> objects
+ returned from a <code>CallableStatement</code> object
+ simultaneously.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMultipleResultSets()">supportsMultipleResultSets</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports getting multiple
+ <code>ResultSet</code> objects from a single call to the
+ method <code>execute</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMultipleTransactions()">supportsMultipleTransactions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database allows having multiple
+ transactions open at once (on different connections).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsNamedParameters()">supportsNamedParameters</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports named parameters to callable
+ statements.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsNonNullableColumns()">supportsNonNullableColumns</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether columns in this database may be defined as non-nullable.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOpenCursorsAcrossCommit()">supportsOpenCursorsAcrossCommit</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports keeping cursors open
+ across commits.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOpenCursorsAcrossRollback()">supportsOpenCursorsAcrossRollback</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports keeping cursors open
+ across rollbacks.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOpenStatementsAcrossCommit()">supportsOpenStatementsAcrossCommit</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports keeping statements open
+ across commits.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOpenStatementsAcrossRollback()">supportsOpenStatementsAcrossRollback</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports keeping statements open
+ across rollbacks.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOrderByUnrelated()">supportsOrderByUnrelated</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports using a column that is
+ not in the <code>SELECT</code> statement in an
+ <code>ORDER BY</code> clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsOuterJoins()">supportsOuterJoins</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports some form of outer join.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsPositionedDelete()">supportsPositionedDelete</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports positioned <code>DELETE</code>
+ statements.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsPositionedUpdate()">supportsPositionedUpdate</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports positioned <code>UPDATE</code>
+ statements.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsResultSetConcurrency(int, int)">supportsResultSetConcurrency</A></B>(int&nbsp;type,
+                             int&nbsp;concurrency)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the given concurrency type
+ in combination with the given result set type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsResultSetHoldability(int)">supportsResultSetHoldability</A></B>(int&nbsp;holdability)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the given result set holdability.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsResultSetType(int)">supportsResultSetType</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the given result set type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSavepoints()">supportsSavepoints</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports savepoints.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInDataManipulation()">supportsSchemasInDataManipulation</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a schema name can be used in a data manipulation statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInIndexDefinitions()">supportsSchemasInIndexDefinitions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a schema name can be used in an index definition statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInPrivilegeDefinitions()">supportsSchemasInPrivilegeDefinitions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a schema name can be used in a privilege definition statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInProcedureCalls()">supportsSchemasInProcedureCalls</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a schema name can be used in a procedure call statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSchemasInTableDefinitions()">supportsSchemasInTableDefinitions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a schema name can be used in a table definition statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSelectForUpdate()">supportsSelectForUpdate</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports <code>SELECT FOR UPDATE</code>
+ statements.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsStatementPooling()">supportsStatementPooling</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports statement pooling.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsStoredFunctionsUsingCallSyntax()">supportsStoredFunctionsUsingCallSyntax</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports invoking user-defined or vendor functions
+ using the stored procedure escape syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsStoredProcedures()">supportsStoredProcedures</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports stored procedure calls
+ that use the stored procedure escape syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSubqueriesInComparisons()">supportsSubqueriesInComparisons</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports subqueries in comparison
+ expressions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSubqueriesInExists()">supportsSubqueriesInExists</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports subqueries in
+ <code>EXISTS</code> expressions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSubqueriesInIns()">supportsSubqueriesInIns</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 correction:)
+ Retrieves whether this database supports subqueries in
+ <code>IN</code> expressions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsSubqueriesInQuantifieds()">supportsSubqueriesInQuantifieds</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports subqueries in quantified
+ expressions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsTableCorrelationNames()">supportsTableCorrelationNames</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports table correlation names.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsTransactionIsolationLevel(int)">supportsTransactionIsolationLevel</A></B>(int&nbsp;level)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports the given transaction isolation level.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsTransactions()">supportsTransactions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports transactions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsUnion()">supportsUnion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports SQL <code>UNION</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsUnionAll()">supportsUnionAll</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database supports SQL <code>UNION ALL</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T&gt; T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#unwrap(java.lang.Class)">unwrap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object that implements the given interface to allow access to non-standard methods,
+ or standard methods not exposed by the proxy.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#updatesAreDetected(int)">updatesAreDetected</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether or not a visible row update can be detected by
+ calling the method <code>ResultSet.rowUpdated</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#usesLocalFilePerTable()">usesLocalFilePerTable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database uses a file for each table.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#usesLocalFiles()">usesLocalFiles</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this database stores tables in a local file.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBC_MAJOR"><!-- --></A><H3>
+JDBC_MAJOR</H3>
+<PRE>
+public static final int <B>JDBC_MAJOR</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCDatabaseMetaData.JDBC_MAJOR">Constant Field Values</A></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="allProceduresAreCallable()"><!-- --></A><H3>
+allProceduresAreCallable</H3>
+<PRE>
+public boolean <B>allProceduresAreCallable</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether the current user can call all the procedures
+ returned by the method <code>getProcedures</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ This method still <em>always</em> returns
+ <code>true</code>. <p>
+
+ In a future release, the plugin interface may be modified to allow
+ implementors to report different values here, based on their
+ implementations.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#allProceduresAreCallable()" title="class or interface in java.sql">allProceduresAreCallable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="allTablesAreSelectable()"><!-- --></A><H3>
+allTablesAreSelectable</H3>
+<PRE>
+public boolean <B>allTablesAreSelectable</B>()
+                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether the current user can use all the tables returned
+ by the method <code>getTables</code> in a <code>SELECT</code>
+ statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB always reports <code>true</code>.<p>
+
+ Please note that the default HSQLDB <code>getTables</code> behaviour is
+ omit from the list of <em>requested</em> tables only those to which the
+ invoking user has <em>no</em> access of any kind. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#allTablesAreSelectable()" title="class or interface in java.sql">allTablesAreSelectable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getURL()"><!-- --></A><H3>
+getURL</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getURL</B>()
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the URL for this DBMS.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getURL()" title="class or interface in java.sql">getURL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the URL for this DBMS or <code>null</code> if it cannot be
+          generated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUserName()"><!-- --></A><H3>
+getUserName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getUserName</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the user name as known to this database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getUserName()" title="class or interface in java.sql">getUserName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the database user name
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isReadOnly()"><!-- --></A><H3>
+isReadOnly</H3>
+<PRE>
+public boolean <B>isReadOnly</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database is in read-only mode.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.7.2, this makes
+ an SQL call to the new isReadOnlyDatabase function
+ which provides correct determination of the read-only status for
+ both local and remote database instances.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#isReadOnly()" title="class or interface in java.sql">isReadOnly</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nullsAreSortedHigh()"><!-- --></A><H3>
+nullsAreSortedHigh</H3>
+<PRE>
+public boolean <B>nullsAreSortedHigh</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether <code>NULL</code> values are sorted high.
+ Sorted high means that <code>NULL</code> values
+ sort higher than any other value in a domain.  In an ascending order,
+ if this method returns <code>true</code>,  <code>NULL</code> values
+ will appear at the end. By contrast, the method
+ <code>nullsAreSortedAtEnd</code> indicates whether <code>NULL</code> values
+ are sorted at the end regardless of sort order.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ By default HSQLDB sorts null at start; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#nullsAreSortedHigh()" title="class or interface in java.sql">nullsAreSortedHigh</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nullsAreSortedLow()"><!-- --></A><H3>
+nullsAreSortedLow</H3>
+<PRE>
+public boolean <B>nullsAreSortedLow</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether <code>NULL</code> values are sorted low.
+ Sorted low means that <code>NULL</code> values
+ sort lower than any other value in a domain.  In an ascending order,
+ if this method returns <code>true</code>,  <code>NULL</code> values
+ will appear at the beginning. By contrast, the method
+ <code>nullsAreSortedAtStart</code> indicates whether <code>NULL</code> values
+ are sorted at the beginning regardless of sort order.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ By default HSQLDB sorts null at the start; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#nullsAreSortedLow()" title="class or interface in java.sql">nullsAreSortedLow</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nullsAreSortedAtStart()"><!-- --></A><H3>
+nullsAreSortedAtStart</H3>
+<PRE>
+public boolean <B>nullsAreSortedAtStart</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether <code>NULL</code> values are sorted at the start regardless
+ of sort order.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ By default HSQLDB sorts null at the start; this method always returns <code>true</code>.
+ Use NULLS LAST in the ORDER BY clause to sort null at the end.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#nullsAreSortedAtStart()" title="class or interface in java.sql">nullsAreSortedAtStart</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nullsAreSortedAtEnd()"><!-- --></A><H3>
+nullsAreSortedAtEnd</H3>
+<PRE>
+public boolean <B>nullsAreSortedAtEnd</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether <code>NULL</code> values are sorted at the end regardless of
+ sort order.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ By default HSQLDB sorts null at the start; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#nullsAreSortedAtEnd()" title="class or interface in java.sql">nullsAreSortedAtEnd</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDatabaseProductName()"><!-- --></A><H3>
+getDatabaseProductName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDatabaseProductName</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the name of this database product.
+
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Returns the name of the HSQLDB engine.
+ </div> <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDatabaseProductName()" title="class or interface in java.sql">getDatabaseProductName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>database product name
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDatabaseProductVersion()"><!-- --></A><H3>
+getDatabaseProductVersion</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDatabaseProductVersion</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the version number of this database product.
+
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Returns the full version string.
+ </div> <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDatabaseProductVersion()" title="class or interface in java.sql">getDatabaseProductVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>database version number
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDriverName()"><!-- --></A><H3>
+getDriverName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDriverName</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the name of this JDBC driver.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDriverName()" title="class or interface in java.sql">getDriverName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>JDBC driver name
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDriverVersion()"><!-- --></A><H3>
+getDriverVersion</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDriverVersion</B>()
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the version number of this JDBC driver as a <code>String</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDriverVersion()" title="class or interface in java.sql">getDriverVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>JDBC driver version
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDriverMajorVersion()"><!-- --></A><H3>
+getDriverMajorVersion</H3>
+<PRE>
+public int <B>getDriverMajorVersion</B>()</PRE>
+<DL>
+<DD>Retrieves this JDBC driver's major version number.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDriverMajorVersion()" title="class or interface in java.sql">getDriverMajorVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>JDBC driver major version</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDriverMinorVersion()"><!-- --></A><H3>
+getDriverMinorVersion</H3>
+<PRE>
+public int <B>getDriverMinorVersion</B>()</PRE>
+<DL>
+<DD>Retrieves this JDBC driver's minor version number.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDriverMinorVersion()" title="class or interface in java.sql">getDriverMinorVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>JDBC driver minor version number</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="usesLocalFiles()"><!-- --></A><H3>
+usesLocalFiles</H3>
+<PRE>
+public boolean <B>usesLocalFiles</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database stores tables in a local file.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From HSQLDB 1.7.2 it is assumed that this refers to data being stored
+ by the JDBC client. This method always returns false.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#usesLocalFiles()" title="class or interface in java.sql">usesLocalFiles</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="usesLocalFilePerTable()"><!-- --></A><H3>
+usesLocalFilePerTable</H3>
+<PRE>
+public boolean <B>usesLocalFilePerTable</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database uses a file for each table.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not use a file for each table.
+ This method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#usesLocalFilePerTable()" title="class or interface in java.sql">usesLocalFilePerTable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if this database uses a local file for each table;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsMixedCaseIdentifiers()"><!-- --></A><H3>
+supportsMixedCaseIdentifiers</H3>
+<PRE>
+public boolean <B>supportsMixedCaseIdentifiers</B>()
+                                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case sensitive and as a result stores them in mixed case.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB treats unquoted identifiers as case insensitive and stores
+ them in upper case. It treats quoted identifiers as case sensitive and
+ stores them verbatim; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsMixedCaseIdentifiers()" title="class or interface in java.sql">supportsMixedCaseIdentifiers</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="storesUpperCaseIdentifiers()"><!-- --></A><H3>
+storesUpperCaseIdentifiers</H3>
+<PRE>
+public boolean <B>storesUpperCaseIdentifiers</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in upper case.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB treats unquoted identifiers as case insensitive and stores
+ them in upper case. It treats quoted identifiers as case sensitive and
+ stores them verbatim; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#storesUpperCaseIdentifiers()" title="class or interface in java.sql">storesUpperCaseIdentifiers</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="storesLowerCaseIdentifiers()"><!-- --></A><H3>
+storesLowerCaseIdentifiers</H3>
+<PRE>
+public boolean <B>storesLowerCaseIdentifiers</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in lower case.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB treats unquoted identifiers as case insensitive and stores
+ them in upper case. It treats quoted identifiers as case sensitive and
+ stores them verbatim; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#storesLowerCaseIdentifiers()" title="class or interface in java.sql">storesLowerCaseIdentifiers</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="storesMixedCaseIdentifiers()"><!-- --></A><H3>
+storesMixedCaseIdentifiers</H3>
+<PRE>
+public boolean <B>storesMixedCaseIdentifiers</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database treats mixed case unquoted SQL identifiers as
+ case insensitive and stores them in mixed case.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB treats unquoted identifiers as case insensitive and stores
+ them in upper case. It treats quoted identifiers as case sensitive and
+ stores them verbatim; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#storesMixedCaseIdentifiers()" title="class or interface in java.sql">storesMixedCaseIdentifiers</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsMixedCaseQuotedIdentifiers()"><!-- --></A><H3>
+supportsMixedCaseQuotedIdentifiers</H3>
+<PRE>
+public boolean <B>supportsMixedCaseQuotedIdentifiers</B>()
+                                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case sensitive and as a result stores them in mixed case.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB treats unquoted identifiers as case insensitive and stores
+ them in upper case. It treats quoted identifiers as case sensitive and
+ stores them verbatim; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsMixedCaseQuotedIdentifiers()" title="class or interface in java.sql">supportsMixedCaseQuotedIdentifiers</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="storesUpperCaseQuotedIdentifiers()"><!-- --></A><H3>
+storesUpperCaseQuotedIdentifiers</H3>
+<PRE>
+public boolean <B>storesUpperCaseQuotedIdentifiers</B>()
+                                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in upper case.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB treats unquoted identifiers as case insensitive and stores
+ them in upper case. It treats quoted identifiers as case sensitive and
+ stores them verbatim; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#storesUpperCaseQuotedIdentifiers()" title="class or interface in java.sql">storesUpperCaseQuotedIdentifiers</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="storesLowerCaseQuotedIdentifiers()"><!-- --></A><H3>
+storesLowerCaseQuotedIdentifiers</H3>
+<PRE>
+public boolean <B>storesLowerCaseQuotedIdentifiers</B>()
+                                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in lower case.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB treats unquoted identifiers as case insensitive and stores
+ them in upper case. It treats quoted identifiers as case sensitive and
+ stores them verbatim; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#storesLowerCaseQuotedIdentifiers()" title="class or interface in java.sql">storesLowerCaseQuotedIdentifiers</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="storesMixedCaseQuotedIdentifiers()"><!-- --></A><H3>
+storesMixedCaseQuotedIdentifiers</H3>
+<PRE>
+public boolean <B>storesMixedCaseQuotedIdentifiers</B>()
+                                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database treats mixed case quoted SQL identifiers as
+ case insensitive and stores them in mixed case.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB treats unquoted identifiers as case insensitive and stores
+ them in upper case. It treats quoted identifiers as case sensitive and
+ stores them verbatim; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#storesMixedCaseQuotedIdentifiers()" title="class or interface in java.sql">storesMixedCaseQuotedIdentifiers</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getIdentifierQuoteString()"><!-- --></A><H3>
+getIdentifierQuoteString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getIdentifierQuoteString</B>()
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the string used to quote SQL identifiers.
+ This method returns a space " " if identifier quoting is not supported.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB uses the standard SQL identifier quote character
+ (the double quote character); this method always returns <b>"</b>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getIdentifierQuoteString()" title="class or interface in java.sql">getIdentifierQuoteString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the quoting string or a space if quoting is not supported
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSQLKeywords()"><!-- --></A><H3>
+getSQLKeywords</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getSQLKeywords</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a comma-separated list of all of this database's SQL keywords
+ that are NOT also SQL:2003 keywords.
+ (JDBC4 modified => SQL:2003)
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The list is empty. However, HSQLDB also supports SQL:2008 keywords
+ and disallows them for database object names without double quoting.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSQLKeywords()" title="class or interface in java.sql">getSQLKeywords</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the list of this database's keywords that are not also
+         SQL:2003 keywords
+         (JDBC4 modified => SQL:2003)
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNumericFunctions()"><!-- --></A><H3>
+getNumericFunctions</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getNumericFunctions</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a comma-separated list of math functions available with
+ this database.  These are the Open /Open CLI math function names used in
+ the JDBC function escape clause.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getNumericFunctions()" title="class or interface in java.sql">getNumericFunctions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the list of math functions supported by this database
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStringFunctions()"><!-- --></A><H3>
+getStringFunctions</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getStringFunctions</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a comma-separated list of string functions available with
+ this database.  These are the  Open Group CLI string function names used
+ in the JDBC function escape clause.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getStringFunctions()" title="class or interface in java.sql">getStringFunctions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the list of string functions supported by this database
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSystemFunctions()"><!-- --></A><H3>
+getSystemFunctions</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getSystemFunctions</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a comma-separated list of system functions available with
+ this database.  These are the  Open Group CLI system function names used
+ in the JDBC function escape clause.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSystemFunctions()" title="class or interface in java.sql">getSystemFunctions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a list of system functions supported by this database
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimeDateFunctions()"><!-- --></A><H3>
+getTimeDateFunctions</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getTimeDateFunctions</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a comma-separated list of the time and date functions available
+ with this database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getTimeDateFunctions()" title="class or interface in java.sql">getTimeDateFunctions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the list of time and date functions supported by this database
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSearchStringEscape()"><!-- --></A><H3>
+getSearchStringEscape</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getSearchStringEscape</B>()
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the string that can be used to escape wildcard characters.
+ This is the string that can be used to escape '_' or '%' in
+ the catalog search parameters that are a pattern (and therefore use one
+ of the wildcard characters).
+
+ <P>The '_' character represents any single character;
+ the '%' character represents any sequence of zero or
+ more characters.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB uses the "\" character to escape wildcard characters.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSearchStringEscape()" title="class or interface in java.sql">getSearchStringEscape</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the string used to escape wildcard characters
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getExtraNameCharacters()"><!-- --></A><H3>
+getExtraNameCharacters</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getExtraNameCharacters</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves all the "extra" characters that can be used in unquoted
+ identifier names (those beyond a-z, A-Z, 0-9 and _).
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support using any "extra" characters in unquoted
+ identifier names; this method always returns the empty String.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getExtraNameCharacters()" title="class or interface in java.sql">getExtraNameCharacters</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the string containing the extra characters
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsAlterTableWithAddColumn()"><!-- --></A><H3>
+supportsAlterTableWithAddColumn</H3>
+<PRE>
+public boolean <B>supportsAlterTableWithAddColumn</B>()
+                                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports <code>ALTER TABLE</code>
+ with add column.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 1.7.0, HSQLDB supports this type of
+ <code>ALTER TABLE</code> statement; this method always
+ returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsAlterTableWithAddColumn()" title="class or interface in java.sql">supportsAlterTableWithAddColumn</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsAlterTableWithDropColumn()"><!-- --></A><H3>
+supportsAlterTableWithDropColumn</H3>
+<PRE>
+public boolean <B>supportsAlterTableWithDropColumn</B>()
+                                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports <code>ALTER TABLE</code>
+ with drop column.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 1.7.0, HSQLDB supports this type of
+ <code>ALTER TABLE</code> statement; this method always
+ returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsAlterTableWithDropColumn()" title="class or interface in java.sql">supportsAlterTableWithDropColumn</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsColumnAliasing()"><!-- --></A><H3>
+supportsColumnAliasing</H3>
+<PRE>
+public boolean <B>supportsColumnAliasing</B>()
+                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports column aliasing.
+
+ <P>If so, the SQL AS clause can be used to provide names for
+ computed columns or to provide alias names for columns as
+ required.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports column aliasing; this method always
+ returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsColumnAliasing()" title="class or interface in java.sql">supportsColumnAliasing</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nullPlusNonNullIsNull()"><!-- --></A><H3>
+nullPlusNonNullIsNull</H3>
+<PRE>
+public boolean <B>nullPlusNonNullIsNull</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports concatenations between
+ <code>NULL</code> and non-<code>NULL</code> values being
+ <code>NULL</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this; this method always
+ returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#nullPlusNonNullIsNull()" title="class or interface in java.sql">nullPlusNonNullIsNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsConvert()"><!-- --></A><H3>
+supportsConvert</H3>
+<PRE>
+public boolean <B>supportsConvert</B>()
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>(JDBC4 clarification:)
+ Retrieves whether this database supports the JDBC scalar function
+ <code>CONVERT</code> for the conversion of one JDBC type to another.
+ The JDBC types are the generic SQL data types defined
+ in <code>java.sql.Types</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports conversions; this method always
+ returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsConvert()" title="class or interface in java.sql">supportsConvert</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsConvert(int, int)"><!-- --></A><H3>
+supportsConvert</H3>
+<PRE>
+public boolean <B>supportsConvert</B>(int&nbsp;fromType,
+                               int&nbsp;toType)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>(JDBC4 clarification:)
+ Retrieves whether this database supports the JDBC scalar function
+ <code>CONVERT</code> for conversions between the JDBC types <i>fromType</i>
+ and <i>toType</i>.  The JDBC types are the generic SQL data types defined
+ in <code>java.sql.Types</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports conversion according to SQL standards. In addition,
+ it supports conversion between values of BOOLEAN and BIT types.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsConvert(int, int)" title="class or interface in java.sql">supportsConvert</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>fromType</CODE> - the type to convert from; one of the type codes from
+        the class <code>java.sql.Types</code><DD><CODE>toType</CODE> - the type to convert to; one of the type codes from
+        the class <code>java.sql.Types</code>
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsTableCorrelationNames()"><!-- --></A><H3>
+supportsTableCorrelationNames</H3>
+<PRE>
+public boolean <B>supportsTableCorrelationNames</B>()
+                                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports table correlation names.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports table correlation names; this method always
+ returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsTableCorrelationNames()" title="class or interface in java.sql">supportsTableCorrelationNames</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsDifferentTableCorrelationNames()"><!-- --></A><H3>
+supportsDifferentTableCorrelationNames</H3>
+<PRE>
+public boolean <B>supportsDifferentTableCorrelationNames</B>()
+                                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether, when table correlation names are supported, they
+ are restricted to being different from the names of the tables.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB requires that table correlation names are different from the
+ names of the tables; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsDifferentTableCorrelationNames()" title="class or interface in java.sql">supportsDifferentTableCorrelationNames</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsExpressionsInOrderBy()"><!-- --></A><H3>
+supportsExpressionsInOrderBy</H3>
+<PRE>
+public boolean <B>supportsExpressionsInOrderBy</B>()
+                                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports expressions in
+ <code>ORDER BY</code> lists.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports expressions in <code>ORDER BY</code> lists; this
+ method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsExpressionsInOrderBy()" title="class or interface in java.sql">supportsExpressionsInOrderBy</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsOrderByUnrelated()"><!-- --></A><H3>
+supportsOrderByUnrelated</H3>
+<PRE>
+public boolean <B>supportsOrderByUnrelated</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports using a column that is
+ not in the <code>SELECT</code> statement in an
+ <code>ORDER BY</code> clause.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports using a column that is not in the <code>SELECT</code>
+ statement in an <code>ORDER BY</code> clause; this method always
+ returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsOrderByUnrelated()" title="class or interface in java.sql">supportsOrderByUnrelated</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsGroupBy()"><!-- --></A><H3>
+supportsGroupBy</H3>
+<PRE>
+public boolean <B>supportsGroupBy</B>()
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports some form of
+ <code>GROUP BY</code> clause.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports using the <code>GROUP BY</code> clause; this method
+ always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsGroupBy()" title="class or interface in java.sql">supportsGroupBy</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsGroupByUnrelated()"><!-- --></A><H3>
+supportsGroupByUnrelated</H3>
+<PRE>
+public boolean <B>supportsGroupByUnrelated</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports using a column that is
+ not in the <code>SELECT</code> statement in a
+ <code>GROUP BY</code> clause.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports using a column that is
+ not in the <code>SELECT</code> statement in a
+ <code>GROUP BY</code> clause; this method
+ always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsGroupByUnrelated()" title="class or interface in java.sql">supportsGroupByUnrelated</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsGroupByBeyondSelect()"><!-- --></A><H3>
+supportsGroupByBeyondSelect</H3>
+<PRE>
+public boolean <B>supportsGroupByBeyondSelect</B>()
+                                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports using columns not included in
+ the <code>SELECT</code> statement in a <code>GROUP BY</code> clause
+ provided that all of the columns in the <code>SELECT</code> statement
+ are included in the <code>GROUP BY</code> clause.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports using columns not included in
+ the <code>SELECT</code> statement in a <code>GROUP BY</code> clause
+ provided that all of the columns in the <code>SELECT</code> statement
+ are included in the <code>GROUP BY</code> clause; this method
+ always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsGroupByBeyondSelect()" title="class or interface in java.sql">supportsGroupByBeyondSelect</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsLikeEscapeClause()"><!-- --></A><H3>
+supportsLikeEscapeClause</H3>
+<PRE>
+public boolean <B>supportsLikeEscapeClause</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports specifying a
+ <code>LIKE</code> escape clause.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports specifying a
+ <code>LIKE</code> escape clause; this method
+ always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsLikeEscapeClause()" title="class or interface in java.sql">supportsLikeEscapeClause</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsMultipleResultSets()"><!-- --></A><H3>
+supportsMultipleResultSets</H3>
+<PRE>
+public boolean <B>supportsMultipleResultSets</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports getting multiple
+ <code>ResultSet</code> objects from a single call to the
+ method <code>execute</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Up to and including 2.0, HSQLDB does not support getting multiple
+ <code>ResultSet</code> objects from a single call to the method
+ <code>execute</code>; this method always returns <code>false</code>. <p>
+
+ This behaviour <i>may</i> change in a future release.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsMultipleResultSets()" title="class or interface in java.sql">supportsMultipleResultSets</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsMultipleTransactions()"><!-- --></A><H3>
+supportsMultipleTransactions</H3>
+<PRE>
+public boolean <B>supportsMultipleTransactions</B>()
+                                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database allows having multiple
+ transactions open at once (on different connections).
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB allows having multiple
+ transactions open at once (on different connections); this method
+ always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsMultipleTransactions()" title="class or interface in java.sql">supportsMultipleTransactions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsNonNullableColumns()"><!-- --></A><H3>
+supportsNonNullableColumns</H3>
+<PRE>
+public boolean <B>supportsNonNullableColumns</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether columns in this database may be defined as non-nullable.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the specification of non-nullable columns; this method
+ always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsNonNullableColumns()" title="class or interface in java.sql">supportsNonNullableColumns</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsMinimumSQLGrammar()"><!-- --></A><H3>
+supportsMinimumSQLGrammar</H3>
+<PRE>
+public boolean <B>supportsMinimumSQLGrammar</B>()
+                                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the ODBC Minimum SQL grammar.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports the ODBC Minimum SQL grammar;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsMinimumSQLGrammar()" title="class or interface in java.sql">supportsMinimumSQLGrammar</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsCoreSQLGrammar()"><!-- --></A><H3>
+supportsCoreSQLGrammar</H3>
+<PRE>
+public boolean <B>supportsCoreSQLGrammar</B>()
+                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the ODBC Core SQL grammar.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports the ODBC Core SQL grammar;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsCoreSQLGrammar()" title="class or interface in java.sql">supportsCoreSQLGrammar</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsExtendedSQLGrammar()"><!-- --></A><H3>
+supportsExtendedSQLGrammar</H3>
+<PRE>
+public boolean <B>supportsExtendedSQLGrammar</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the ODBC Extended SQL grammar.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports the ODBC Extended SQL grammar;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsExtendedSQLGrammar()" title="class or interface in java.sql">supportsExtendedSQLGrammar</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsANSI92EntryLevelSQL()"><!-- --></A><H3>
+supportsANSI92EntryLevelSQL</H3>
+<PRE>
+public boolean <B>supportsANSI92EntryLevelSQL</B>()
+                                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the ANSI92 entry level SQL
+ grammar.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports the ANSI92 entry level SQL grammar;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsANSI92EntryLevelSQL()" title="class or interface in java.sql">supportsANSI92EntryLevelSQL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsANSI92IntermediateSQL()"><!-- --></A><H3>
+supportsANSI92IntermediateSQL</H3>
+<PRE>
+public boolean <B>supportsANSI92IntermediateSQL</B>()
+                                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the ANSI92 intermediate SQL grammar supported.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports the ANSI92 intermediate SQL grammar;
+ this method always returns <code>true</code>.
+ <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsANSI92IntermediateSQL()" title="class or interface in java.sql">supportsANSI92IntermediateSQL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsANSI92FullSQL()"><!-- --></A><H3>
+supportsANSI92FullSQL</H3>
+<PRE>
+public boolean <B>supportsANSI92FullSQL</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the ANSI92 full SQL grammar supported.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports the ANSI92 full SQL grammar. The exceptions,
+ such as support for ASSERTION, are not considered grammer issues.
+ This method always returns <code>true</code>. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsANSI92FullSQL()" title="class or interface in java.sql">supportsANSI92FullSQL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsIntegrityEnhancementFacility()"><!-- --></A><H3>
+supportsIntegrityEnhancementFacility</H3>
+<PRE>
+public boolean <B>supportsIntegrityEnhancementFacility</B>()
+                                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the SQL Integrity
+ Enhancement Facility.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ This method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsIntegrityEnhancementFacility()" title="class or interface in java.sql">supportsIntegrityEnhancementFacility</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsOuterJoins()"><!-- --></A><H3>
+supportsOuterJoins</H3>
+<PRE>
+public boolean <B>supportsOuterJoins</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports some form of outer join.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports outer joins; this method always returns
+ <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsOuterJoins()" title="class or interface in java.sql">supportsOuterJoins</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsFullOuterJoins()"><!-- --></A><H3>
+supportsFullOuterJoins</H3>
+<PRE>
+public boolean <B>supportsFullOuterJoins</B>()
+                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports full nested outer joins.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports full nested outer
+ joins; this method always returns <code>true</code>. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsFullOuterJoins()" title="class or interface in java.sql">supportsFullOuterJoins</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsLimitedOuterJoins()"><!-- --></A><H3>
+supportsLimitedOuterJoins</H3>
+<PRE>
+public boolean <B>supportsLimitedOuterJoins</B>()
+                                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database provides limited support for outer
+ joins.  (This will be <code>true</code> if the method
+ <code>supportsFullOuterJoins</code> returns <code>true</code>).
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the LEFT OUTER join syntax;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsLimitedOuterJoins()" title="class or interface in java.sql">supportsLimitedOuterJoins</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSchemaTerm()"><!-- --></A><H3>
+getSchemaTerm</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getSchemaTerm</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the database vendor's preferred term for "schema".
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.8.0, HSQLDB supports schemas.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSchemaTerm()" title="class or interface in java.sql">getSchemaTerm</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the vendor term for "schema"
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProcedureTerm()"><!-- --></A><H3>
+getProcedureTerm</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getProcedureTerm</B>()
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the database vendor's preferred term for "procedure".
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports declaration of
+ functions or procedures directly in SQL.<p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getProcedureTerm()" title="class or interface in java.sql">getProcedureTerm</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the vendor term for "procedure"
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCatalogTerm()"><!-- --></A><H3>
+getCatalogTerm</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getCatalogTerm</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the database vendor's preferred term for "catalog".
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB uses the standard name CATALOG.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getCatalogTerm()" title="class or interface in java.sql">getCatalogTerm</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the vendor term for "catalog"
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isCatalogAtStart()"><!-- --></A><H3>
+isCatalogAtStart</H3>
+<PRE>
+public boolean <B>isCatalogAtStart</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a catalog appears at the start of a fully qualified
+ table name.  If not, the catalog appears at the end.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ When allowed, a catalog appears at the start of a fully qualified
+ table name; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#isCatalogAtStart()" title="class or interface in java.sql">isCatalogAtStart</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the catalog name appears at the beginning
+         of a fully qualified table name; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCatalogSeparator()"><!-- --></A><H3>
+getCatalogSeparator</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getCatalogSeparator</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the <code>String</code> that this database uses as the
+ separator between a catalog and table name.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ When used, a catalog name is separated with period;
+ this method <em>always</em> returns a period
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getCatalogSeparator()" title="class or interface in java.sql">getCatalogSeparator</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the separator string
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSchemasInDataManipulation()"><!-- --></A><H3>
+supportsSchemasInDataManipulation</H3>
+<PRE>
+public boolean <B>supportsSchemasInDataManipulation</B>()
+                                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a schema name can be used in a data manipulation statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports schemas where allowed by the standard;
+ this method always returns <code>true</code>.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSchemasInDataManipulation()" title="class or interface in java.sql">supportsSchemasInDataManipulation</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSchemasInProcedureCalls()"><!-- --></A><H3>
+supportsSchemasInProcedureCalls</H3>
+<PRE>
+public boolean <B>supportsSchemasInProcedureCalls</B>()
+                                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a schema name can be used in a procedure call statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports schemas where allowed by the standard;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSchemasInProcedureCalls()" title="class or interface in java.sql">supportsSchemasInProcedureCalls</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSchemasInTableDefinitions()"><!-- --></A><H3>
+supportsSchemasInTableDefinitions</H3>
+<PRE>
+public boolean <B>supportsSchemasInTableDefinitions</B>()
+                                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a schema name can be used in a table definition statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports schemas where allowed by the standard;
+ this method always returns <code>true</code>.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSchemasInTableDefinitions()" title="class or interface in java.sql">supportsSchemasInTableDefinitions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSchemasInIndexDefinitions()"><!-- --></A><H3>
+supportsSchemasInIndexDefinitions</H3>
+<PRE>
+public boolean <B>supportsSchemasInIndexDefinitions</B>()
+                                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a schema name can be used in an index definition statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports schemas where allowed by the standard;
+ this method always returns <code>true</code>.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSchemasInIndexDefinitions()" title="class or interface in java.sql">supportsSchemasInIndexDefinitions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSchemasInPrivilegeDefinitions()"><!-- --></A><H3>
+supportsSchemasInPrivilegeDefinitions</H3>
+<PRE>
+public boolean <B>supportsSchemasInPrivilegeDefinitions</B>()
+                                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a schema name can be used in a privilege definition statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports schemas where allowed by the standard;
+ this method always returns <code>true</code>.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSchemasInPrivilegeDefinitions()" title="class or interface in java.sql">supportsSchemasInPrivilegeDefinitions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsCatalogsInDataManipulation()"><!-- --></A><H3>
+supportsCatalogsInDataManipulation</H3>
+<PRE>
+public boolean <B>supportsCatalogsInDataManipulation</B>()
+                                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a catalog name can be used in a data manipulation statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports catalog names where allowed by the standard;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsCatalogsInDataManipulation()" title="class or interface in java.sql">supportsCatalogsInDataManipulation</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsCatalogsInProcedureCalls()"><!-- --></A><H3>
+supportsCatalogsInProcedureCalls</H3>
+<PRE>
+public boolean <B>supportsCatalogsInProcedureCalls</B>()
+                                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a catalog name can be used in a procedure call statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports catalog names where allowed by the standard;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsCatalogsInProcedureCalls()" title="class or interface in java.sql">supportsCatalogsInProcedureCalls</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsCatalogsInTableDefinitions()"><!-- --></A><H3>
+supportsCatalogsInTableDefinitions</H3>
+<PRE>
+public boolean <B>supportsCatalogsInTableDefinitions</B>()
+                                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a catalog name can be used in a table definition statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports catalog names where allowed by the standard;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsCatalogsInTableDefinitions()" title="class or interface in java.sql">supportsCatalogsInTableDefinitions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsCatalogsInIndexDefinitions()"><!-- --></A><H3>
+supportsCatalogsInIndexDefinitions</H3>
+<PRE>
+public boolean <B>supportsCatalogsInIndexDefinitions</B>()
+                                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a catalog name can be used in an index definition statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports catalog names where allowed by the standard;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsCatalogsInIndexDefinitions()" title="class or interface in java.sql">supportsCatalogsInIndexDefinitions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsCatalogsInPrivilegeDefinitions()"><!-- --></A><H3>
+supportsCatalogsInPrivilegeDefinitions</H3>
+<PRE>
+public boolean <B>supportsCatalogsInPrivilegeDefinitions</B>()
+                                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a catalog name can be used in a privilege definition statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB supports catalog names where allowed by the standard;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsCatalogsInPrivilegeDefinitions()" title="class or interface in java.sql">supportsCatalogsInPrivilegeDefinitions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsPositionedDelete()"><!-- --></A><H3>
+supportsPositionedDelete</H3>
+<PRE>
+public boolean <B>supportsPositionedDelete</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports positioned <code>DELETE</code>
+ statements.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports updateable result sets;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsPositionedDelete()" title="class or interface in java.sql">supportsPositionedDelete</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsPositionedUpdate()"><!-- --></A><H3>
+supportsPositionedUpdate</H3>
+<PRE>
+public boolean <B>supportsPositionedUpdate</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports positioned <code>UPDATE</code>
+ statements.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports updateable result sets;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsPositionedUpdate()" title="class or interface in java.sql">supportsPositionedUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSelectForUpdate()"><!-- --></A><H3>
+supportsSelectForUpdate</H3>
+<PRE>
+public boolean <B>supportsSelectForUpdate</B>()
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports <code>SELECT FOR UPDATE</code>
+ statements.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports updateable result sets;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSelectForUpdate()" title="class or interface in java.sql">supportsSelectForUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsStoredProcedures()"><!-- --></A><H3>
+supportsStoredProcedures</H3>
+<PRE>
+public boolean <B>supportsStoredProcedures</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports stored procedure calls
+ that use the stored procedure escape syntax.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports calling public static Java methods in the context of SQL
+ Stored Procedures; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsStoredProcedures()" title="class or interface in java.sql">supportsStoredProcedures</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><CODE>JDBCParameterMetaData</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareCall(java.lang.String)"><CODE>JDBCConnection.prepareCall(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSubqueriesInComparisons()"><!-- --></A><H3>
+supportsSubqueriesInComparisons</H3>
+<PRE>
+public boolean <B>supportsSubqueriesInComparisons</B>()
+                                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports subqueries in comparison
+ expressions.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB has always supported subqueries in comparison expressions;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSubqueriesInComparisons()" title="class or interface in java.sql">supportsSubqueriesInComparisons</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSubqueriesInExists()"><!-- --></A><H3>
+supportsSubqueriesInExists</H3>
+<PRE>
+public boolean <B>supportsSubqueriesInExists</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports subqueries in
+ <code>EXISTS</code> expressions.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB has always supported subqueries in <code>EXISTS</code>
+ expressions; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSubqueriesInExists()" title="class or interface in java.sql">supportsSubqueriesInExists</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSubqueriesInIns()"><!-- --></A><H3>
+supportsSubqueriesInIns</H3>
+<PRE>
+public boolean <B>supportsSubqueriesInIns</B>()
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>(JDBC4 correction:)
+ Retrieves whether this database supports subqueries in
+ <code>IN</code> expressions.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB has always supported subqueries in <code>IN</code>
+ statements; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSubqueriesInIns()" title="class or interface in java.sql">supportsSubqueriesInIns</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSubqueriesInQuantifieds()"><!-- --></A><H3>
+supportsSubqueriesInQuantifieds</H3>
+<PRE>
+public boolean <B>supportsSubqueriesInQuantifieds</B>()
+                                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports subqueries in quantified
+ expressions.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB has always supported subqueries in quantified
+ expressions; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSubqueriesInQuantifieds()" title="class or interface in java.sql">supportsSubqueriesInQuantifieds</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsCorrelatedSubqueries()"><!-- --></A><H3>
+supportsCorrelatedSubqueries</H3>
+<PRE>
+public boolean <B>supportsCorrelatedSubqueries</B>()
+                                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports correlated subqueries.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB has always supported correlated subqueries;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsCorrelatedSubqueries()" title="class or interface in java.sql">supportsCorrelatedSubqueries</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsUnion()"><!-- --></A><H3>
+supportsUnion</H3>
+<PRE>
+public boolean <B>supportsUnion</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports SQL <code>UNION</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports SQL <code>UNION</code>;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsUnion()" title="class or interface in java.sql">supportsUnion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsUnionAll()"><!-- --></A><H3>
+supportsUnionAll</H3>
+<PRE>
+public boolean <B>supportsUnionAll</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports SQL <code>UNION ALL</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports SQL <code>UNION ALL</code>;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsUnionAll()" title="class or interface in java.sql">supportsUnionAll</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsOpenCursorsAcrossCommit()"><!-- --></A><H3>
+supportsOpenCursorsAcrossCommit</H3>
+<PRE>
+public boolean <B>supportsOpenCursorsAcrossCommit</B>()
+                                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports keeping cursors open
+ across commits.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports keeping cursors open across commits.
+ This method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsOpenCursorsAcrossCommit()" title="class or interface in java.sql">supportsOpenCursorsAcrossCommit</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if cursors always remain open;
+       <code>false</code> if they might not remain open
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsOpenCursorsAcrossRollback()"><!-- --></A><H3>
+supportsOpenCursorsAcrossRollback</H3>
+<PRE>
+public boolean <B>supportsOpenCursorsAcrossRollback</B>()
+                                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports keeping cursors open
+ across rollbacks.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 closes open cursors at rollback.
+ This method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsOpenCursorsAcrossRollback()" title="class or interface in java.sql">supportsOpenCursorsAcrossRollback</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if cursors always remain open;
+       <code>false</code> if they might not remain open
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsOpenStatementsAcrossCommit()"><!-- --></A><H3>
+supportsOpenStatementsAcrossCommit</H3>
+<PRE>
+public boolean <B>supportsOpenStatementsAcrossCommit</B>()
+                                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports keeping statements open
+ across commits.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports keeping statements open across commits;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsOpenStatementsAcrossCommit()" title="class or interface in java.sql">supportsOpenStatementsAcrossCommit</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if statements always remain open;
+       <code>false</code> if they might not remain open
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsOpenStatementsAcrossRollback()"><!-- --></A><H3>
+supportsOpenStatementsAcrossRollback</H3>
+<PRE>
+public boolean <B>supportsOpenStatementsAcrossRollback</B>()
+                                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports keeping statements open
+ across rollbacks.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports keeping statements open  across rollbacks;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsOpenStatementsAcrossRollback()" title="class or interface in java.sql">supportsOpenStatementsAcrossRollback</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if statements always remain open;
+       <code>false</code> if they might not remain open
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxBinaryLiteralLength()"><!-- --></A><H3>
+getMaxBinaryLiteralLength</H3>
+<PRE>
+public int <B>getMaxBinaryLiteralLength</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of hex characters this database allows in an
+ inline binary literal.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxBinaryLiteralLength()" title="class or interface in java.sql">getMaxBinaryLiteralLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>max the maximum length (in hex characters) for a binary literal;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxCharLiteralLength()"><!-- --></A><H3>
+getMaxCharLiteralLength</H3>
+<PRE>
+public int <B>getMaxCharLiteralLength</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters this database allows
+ for a character literal.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxCharLiteralLength()" title="class or interface in java.sql">getMaxCharLiteralLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed for a character literal;
+      a result of zero means that there is no limit or the limit is
+      not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxColumnNameLength()"><!-- --></A><H3>
+getMaxColumnNameLength</H3>
+<PRE>
+public int <B>getMaxColumnNameLength</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters this database allows
+ for a column name.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+ all names.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxColumnNameLength()" title="class or interface in java.sql">getMaxColumnNameLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed for a column name;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxColumnsInGroupBy()"><!-- --></A><H3>
+getMaxColumnsInGroupBy</H3>
+<PRE>
+public int <B>getMaxColumnsInGroupBy</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of columns this database allows in a
+ <code>GROUP BY</code> clause.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxColumnsInGroupBy()" title="class or interface in java.sql">getMaxColumnsInGroupBy</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of columns allowed;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxColumnsInIndex()"><!-- --></A><H3>
+getMaxColumnsInIndex</H3>
+<PRE>
+public int <B>getMaxColumnsInIndex</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of columns this database allows in an index.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxColumnsInIndex()" title="class or interface in java.sql">getMaxColumnsInIndex</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of columns allowed;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxColumnsInOrderBy()"><!-- --></A><H3>
+getMaxColumnsInOrderBy</H3>
+<PRE>
+public int <B>getMaxColumnsInOrderBy</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of columns this database allows in an
+ <code>ORDER BY</code> clause.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxColumnsInOrderBy()" title="class or interface in java.sql">getMaxColumnsInOrderBy</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of columns allowed;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxColumnsInSelect()"><!-- --></A><H3>
+getMaxColumnsInSelect</H3>
+<PRE>
+public int <B>getMaxColumnsInSelect</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of columns this database allows in a
+ <code>SELECT</code> list.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxColumnsInSelect()" title="class or interface in java.sql">getMaxColumnsInSelect</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of columns allowed;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxColumnsInTable()"><!-- --></A><H3>
+getMaxColumnsInTable</H3>
+<PRE>
+public int <B>getMaxColumnsInTable</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of columns this database allows in a table.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxColumnsInTable()" title="class or interface in java.sql">getMaxColumnsInTable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of columns allowed;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxConnections()"><!-- --></A><H3>
+getMaxConnections</H3>
+<PRE>
+public int <B>getMaxConnections</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of concurrent connections to this
+ database that are possible.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxConnections()" title="class or interface in java.sql">getMaxConnections</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of active connections possible at one time;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxCursorNameLength()"><!-- --></A><H3>
+getMaxCursorNameLength</H3>
+<PRE>
+public int <B>getMaxCursorNameLength</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters that this database allows in a
+ cursor name.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+ all names.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxCursorNameLength()" title="class or interface in java.sql">getMaxCursorNameLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed in a cursor name;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxIndexLength()"><!-- --></A><H3>
+getMaxIndexLength</H3>
+<PRE>
+public int <B>getMaxIndexLength</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of bytes this database allows for an
+ index, including all of the parts of the index.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory and disk availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxIndexLength()" title="class or interface in java.sql">getMaxIndexLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of bytes allowed; this limit includes the
+      composite of all the constituent parts of the index;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxSchemaNameLength()"><!-- --></A><H3>
+getMaxSchemaNameLength</H3>
+<PRE>
+public int <B>getMaxSchemaNameLength</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters that this database allows in a
+ schema name.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+ all names.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxSchemaNameLength()" title="class or interface in java.sql">getMaxSchemaNameLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed in a schema name;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxProcedureNameLength()"><!-- --></A><H3>
+getMaxProcedureNameLength</H3>
+<PRE>
+public int <B>getMaxProcedureNameLength</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters that this database allows in a
+ procedure name.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+ all names.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxProcedureNameLength()" title="class or interface in java.sql">getMaxProcedureNameLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed in a procedure name;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxCatalogNameLength()"><!-- --></A><H3>
+getMaxCatalogNameLength</H3>
+<PRE>
+public int <B>getMaxCatalogNameLength</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters that this database allows in a
+ catalog name.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+ all names.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxCatalogNameLength()" title="class or interface in java.sql">getMaxCatalogNameLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed in a catalog name;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxRowSize()"><!-- --></A><H3>
+getMaxRowSize</H3>
+<PRE>
+public int <B>getMaxRowSize</B>()
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of bytes this database allows in
+ a single row.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory and disk availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxRowSize()" title="class or interface in java.sql">getMaxRowSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of bytes allowed for a row; a result of
+         zero means that there is no limit or the limit is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="doesMaxRowSizeIncludeBlobs()"><!-- --></A><H3>
+doesMaxRowSizeIncludeBlobs</H3>
+<PRE>
+public boolean <B>doesMaxRowSizeIncludeBlobs</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether the return value for the method
+ <code>getMaxRowSize</code> includes the SQL data types
+ <code>LONGVARCHAR</code> and <code>LONGVARBINARY</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Indormation:</h3><p>
+
+ Including 2.0, <A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getMaxRowSize()"><CODE>getMaxRowSize()</CODE></A> <em>always</em> returns
+ 0, indicating that the maximum row size is unknown or has no limit.
+ This applies to the above types as well; this method <em>always</em>
+ returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#doesMaxRowSizeIncludeBlobs()" title="class or interface in java.sql">doesMaxRowSizeIncludeBlobs</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxStatementLength()"><!-- --></A><H3>
+getMaxStatementLength</H3>
+<PRE>
+public int <B>getMaxStatementLength</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters this database allows in
+ an SQL statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxStatementLength()" title="class or interface in java.sql">getMaxStatementLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed for an SQL statement;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxStatements()"><!-- --></A><H3>
+getMaxStatements</H3>
+<PRE>
+public int <B>getMaxStatements</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of active statements to this database
+ that can be open at the same time.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxStatements()" title="class or interface in java.sql">getMaxStatements</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of statements that can be open at one time;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxTableNameLength()"><!-- --></A><H3>
+getMaxTableNameLength</H3>
+<PRE>
+public int <B>getMaxTableNameLength</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters this database allows in
+ a table name.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Up to and including 1.8.0.x, HSQLDB did not impose a "known" limit.  Th
+ hard limit was the maximum length of a java.lang.String
+ (java.lang.Integer.MAX_VALUE); this method always returned
+ <code>0</code>.
+
+ Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+ all names.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxTableNameLength()" title="class or interface in java.sql">getMaxTableNameLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed for a table name;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxTablesInSelect()"><!-- --></A><H3>
+getMaxTablesInSelect</H3>
+<PRE>
+public int <B>getMaxTablesInSelect</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of tables this database allows in a
+ <code>SELECT</code> statement.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not impose a "known" limit.  The limit is subject to
+ memory availabily; this method always returns <code>0</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxTablesInSelect()" title="class or interface in java.sql">getMaxTablesInSelect</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of tables allowed in a <code>SELECT</code>
+         statement; a result of zero means that there is no limit or
+         the limit is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxUserNameLength()"><!-- --></A><H3>
+getMaxUserNameLength</H3>
+<PRE>
+public int <B>getMaxUserNameLength</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the maximum number of characters this database allows in
+ a user name.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+ all names.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getMaxUserNameLength()" title="class or interface in java.sql">getMaxUserNameLength</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the maximum number of characters allowed for a user name;
+      a result of zero means that there is no limit or the limit
+      is not known
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDefaultTransactionIsolation()"><!-- --></A><H3>
+getDefaultTransactionIsolation</H3>
+<PRE>
+public int <B>getDefaultTransactionIsolation</B>()
+                                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves this database's default transaction isolation level.  The
+ possible values are defined in <code>java.sql.Connection</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information</h3>
+
+ Default isolation mode in version 2.0 is TRANSACTION_READ_COMMITED.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDefaultTransactionIsolation()" title="class or interface in java.sql">getDefaultTransactionIsolation</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the default isolation level
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><CODE>JDBCConnection</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsTransactions()"><!-- --></A><H3>
+supportsTransactions</H3>
+<PRE>
+public boolean <B>supportsTransactions</B>()
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports transactions. If not, invoking the
+ method <code>commit</code> is a noop, and the isolation level is
+ <code>TRANSACTION_NONE</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports transactions;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsTransactions()" title="class or interface in java.sql">supportsTransactions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if transactions are supported;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsTransactionIsolationLevel(int)"><!-- --></A><H3>
+supportsTransactionIsolationLevel</H3>
+<PRE>
+public boolean <B>supportsTransactionIsolationLevel</B>(int&nbsp;level)
+                                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the given transaction isolation level.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information</h3>
+ HSQLDB supports all levels.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsTransactionIsolationLevel(int)" title="class or interface in java.sql">supportsTransactionIsolationLevel</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>level</CODE> - one of the transaction isolation levels defined in
+         <code>java.sql.Connection</code>
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><CODE>JDBCConnection</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsDataDefinitionAndDataManipulationTransactions()"><!-- --></A><H3>
+supportsDataDefinitionAndDataManipulationTransactions</H3>
+<PRE>
+public boolean <B>supportsDataDefinitionAndDataManipulationTransactions</B>()
+                                                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports both data definition and
+ data manipulation statements within a transaction.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support a mix of both data definition and
+ data manipulation statements within a transaction.  DDL commits the
+ current transaction before proceding;
+ this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsDataDefinitionAndDataManipulationTransactions()" title="class or interface in java.sql">supportsDataDefinitionAndDataManipulationTransactions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsDataManipulationTransactionsOnly()"><!-- --></A><H3>
+supportsDataManipulationTransactionsOnly</H3>
+<PRE>
+public boolean <B>supportsDataManipulationTransactionsOnly</B>()
+                                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports only data manipulation
+ statements within a transaction.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports only data manipulation
+ statements within a transaction.  DDL commits the
+ current transaction before proceeding, while DML does not;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsDataManipulationTransactionsOnly()" title="class or interface in java.sql">supportsDataManipulationTransactionsOnly</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="dataDefinitionCausesTransactionCommit()"><!-- --></A><H3>
+dataDefinitionCausesTransactionCommit</H3>
+<PRE>
+public boolean <B>dataDefinitionCausesTransactionCommit</B>()
+                                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a data definition statement within a transaction forces
+ the transaction to commit.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, a data definition statement within a transaction forces
+ the transaction to commit; this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#dataDefinitionCausesTransactionCommit()" title="class or interface in java.sql">dataDefinitionCausesTransactionCommit</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="dataDefinitionIgnoredInTransactions()"><!-- --></A><H3>
+dataDefinitionIgnoredInTransactions</H3>
+<PRE>
+public boolean <B>dataDefinitionIgnoredInTransactions</B>()
+                                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database ignores a data definition statement
+ within a transaction.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, a data definition statement is not ignored within a
+ transaction.  Rather, a data definition statement within a
+ transaction forces the transaction to commit; this method
+ <em>always</em> returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#dataDefinitionIgnoredInTransactions()" title="class or interface in java.sql">dataDefinitionIgnoredInTransactions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProcedures(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getProcedures</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getProcedures</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;procedureNamePattern)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the stored procedures available in the given
+ catalog.
+ <P>
+ Only procedure descriptions matching the schema and
+ procedure name criteria are returned.  They are ordered by
+ <code>PROCEDURE_SCHEM</code>, <code>PROCEDURE_NAME</code> and (new to JDBC4) <code>SPECIFIC_ NAME</code>.
+
+ <P>Each procedure description has the the following columns:
+  <OL>
+  <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be <code>null</code>)
+  <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be <code>null</code>)
+  <LI><B>PROCEDURE_NAME</B> String => procedure name
+  <LI> reserved for future use
+       (HSQLDB-specific: NUM_INPUT_PARAMS)
+  <LI> reserved for future use
+       (HSQLDB-specific: NUM_OUTPUT_PARAMS)
+  <LI> reserved for future use
+       (HSQLDB-specific: NUM_RESULT_SETS)
+  <LI><B>REMARKS</B> String => explanatory comment on the procedure
+  <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
+      <UL>
+      <LI> procedureResultUnknown - (JDBC4 clarification:) Cannot determine if  a return value
+       will be returned
+      <LI> procedureNoResult - (JDBC4 clarification:) Does not return a return value
+      <LI> procedureReturnsResult - (JDBC4 clarification:) Returns a return value
+      </UL>
+  <LI><B>SPECIFIC_NAME</B> String  => (JDBC4 new:) The name which uniquely identifies this procedure within its schema
+  </OL>
+ <p>
+ A user may not have permissions to execute any of the procedures that are
+ returned by <code>getProcedures</code>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ In version 1.9, the rows returned by this method are based on rows in
+ the INFORMATION_SCHEMA.ROUTINES table.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getProcedures(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getProcedures</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema name pattern; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>procedureNamePattern</CODE> - a procedure name pattern; must match the
+        procedure name as it is stored in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a procedure description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProcedureColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getProcedureColumns</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getProcedureColumns</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;procedureNamePattern,
+                                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnNamePattern)
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the given catalog's stored procedure parameter
+ and result columns.
+
+ <P>Only descriptions matching the schema, procedure and
+ parameter name criteria are returned.  They are ordered by
+ PROCEDURE_SCHEM, PROCEDURE_NAME and SPECIFIC_NAME. Within this, the return value,
+ if any, is first. Next are the parameter descriptions in call
+ order. The column descriptions follow in column number order.
+
+ <P>Each row in the <code>ResultSet</code> is a parameter description or
+ column description with the following fields:
+  <OL>
+  <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be <code>null</code>)
+  <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be <code>null</code>)
+  <LI><B>PROCEDURE_NAME</B> String => procedure name
+  <LI><B>COLUMN_NAME</B> String => column/parameter name
+  <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
+      <UL>
+      <LI> procedureColumnUnknown - nobody knows
+      <LI> procedureColumnIn - IN parameter
+      <LI> procedureColumnInOut - INOUT parameter
+      <LI> procedureColumnOut - OUT parameter
+      <LI> procedureColumnReturn - procedure return value
+      <LI> procedureColumnResult - result column in <code>ResultSet</code>
+      </UL>
+  <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
+  <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
+  type name is fully qualified
+  <LI><B>PRECISION</B> int => precision
+  <LI><B>LENGTH</B> int => length in bytes of data
+  <LI><B>SCALE</B> short => scale -  null is returned for data types where
+ SCALE is not applicable.
+  <LI><B>RADIX</B> short => radix
+  <LI><B>NULLABLE</B> short => can it contain NULL.
+      <UL>
+      <LI> procedureNoNulls - does not allow NULL values
+      <LI> procedureNullable - allows NULL values
+      <LI> procedureNullableUnknown - nullability unknown
+      </UL>
+  <LI><B>REMARKS</B> String => comment describing parameter/column
+  <LI><B>COLUMN_DEF</B> String => default value for the column, which should be interpreted as a string when the value is enclosed in single quotes (may be <code>null</code>)
+      <UL>
+      <LI> The string NULL (not enclosed in quotes) - if NULL was specified as the default value
+      <LI> TRUNCATE (not enclosed in quotes)        - if the specified default value cannot be represented without truncation
+      <LI> NULL                                     - if a default value was not specified
+      </UL>
+  <LI><B>SQL_DATA_TYPE</B> int  => (JDBC4 new:) Reserved for future use
+
+        <p>HSQLDB-specific: CLI type from SQL 2003 Table 37,
+        tables 6-9 Annex A1, and/or addendums in other
+        documents, such as:<br>
+        SQL 2003 Part 9: Management of External Data (SQL/MED) : DATALINK<br>
+        SQL 2003 Part 14: XML-Related Specifications (SQL/XML) : XML<p>
+
+  <LI><B>SQL_DATETIME_SUB</B> int  => (JDBC4 new:) reserved for future use
+
+        <p>HSQLDB-specific: CLI SQL_DATETIME_SUB from SQL 2003 Table 37
+
+  <LI><B>CHAR_OCTET_LENGTH</B> int  => (JDBC4 new:) the maximum length of binary and character based columns.  For any other datatype the returned value is a
+ NULL
+  <LI><B>ORDINAL_POSITION</B> int  => (JDBC4 new:) the ordinal position, starting from 1, for the input and output parameters for a procedure. A value of 0
+ is returned if this row describes the procedure's return value.
+  <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine the nullability for a column.
+       <UL>
+       <LI> YES           --- if the parameter can include NULLs
+       <LI> NO            --- if the parameter cannot include NULLs
+       <LI> empty string  --- if the nullability for the
+ parameter is unknown
+       </UL>
+  <LI><B>SPECIFIC_NAME</B> String  => (JDBC4 new:) the name which uniquely identifies this procedure within its schema.
+ </OL>
+
+ <P><B>Note:</B> Some databases may not return the column
+ descriptions for a procedure. Additional columns beyond (JDBC4 modified:)
+ SPECIFIC_NAME can be defined by the database and must be accessed by their <B>column name</B>.
+
+ <p>(JDBC4 clarification:)
+ <p>The PRECISION column represents the specified column size for the given column.
+ For numeric data, this is the maximum precision.  For character data, this is the [declared or implicit maximum] length in characters.
+ For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+ maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+ this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+ column size is not applicable.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationFull</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getProcedureColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getProcedureColumns</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema name pattern; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>procedureNamePattern</CODE> - a procedure name pattern; must match the
+        procedure name as it is stored in the database<DD><CODE>columnNamePattern</CODE> - a column name pattern; must match the column name
+        as it is stored in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row describes a stored procedure parameter or
+      column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])"><!-- --></A><H3>
+getTables</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getTables</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tableNamePattern,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;types)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the tables available in the given catalog.
+ Only table descriptions matching the catalog, schema, table
+ name and type criteria are returned.  They are ordered by
+ TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
+ <P>
+ Each table description has the following columns:
+  <OL>
+  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+  <LI><B>TABLE_NAME</B> String => table name
+  <LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
+                  "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
+                  "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
+  <LI><B>REMARKS</B> String => explanatory comment on the table
+  <LI><B>TYPE_CAT</B> String => the types catalog (may be <code>null</code>)
+  <LI><B>TYPE_SCHEM</B> String => the types schema (may be <code>null</code>)
+  <LI><B>TYPE_NAME</B> String => type name (may be <code>null</code>)
+  <LI><B>SELF_REFERENCING_COL_NAME</B> String => name of the designated
+                  "identifier" column of a typed table (may be <code>null</code>)
+  <LI><B>REF_GENERATION</B> String => specifies how values in
+                  SELF_REFERENCING_COL_NAME are created. Values are
+                  "SYSTEM", "USER", "DERIVED". (may be <code>null</code>)
+  </OL>
+
+ <P><B>Note:</B> Some databases may not return information for
+ all tables.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ HSQLDB returns extra information on TEXT tables in the REMARKS column. <p>
+
+ HSQLDB includes the JDBC3 columns TYPE_CAT, TYPE_SCHEM, TYPE_NAME and
+ SELF_REFERENCING_COL_NAME in anticipation of JDBC3 compliant tools. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])" title="class or interface in java.sql">getTables</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema name pattern; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>tableNamePattern</CODE> - a table name pattern; must match the
+        table name as it is stored in the database<DD><CODE>types</CODE> - a list of table types, which must be from the list of table types
+         returned from <A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getTableTypes()"><CODE>getTableTypes()</CODE></A>,to include; <code>null</code> returns
+ all types
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a table description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSchemas()"><!-- --></A><H3>
+getSchemas</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getSchemas</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the schema names available in this database.  The results
+ are ordered by schema name.
+
+ <P>The schema columns are:
+  <OL>
+  <LI><B>TABLE_SCHEM</B> String => schema name
+  <LI><B>TABLE_CATALOG</B> String => catalog name (may be <code>null</code>)
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.8.0, the list of schemas is returned.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSchemas()" title="class or interface in java.sql">getSchemas</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row is a
+         schema description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCatalogs()"><!-- --></A><H3>
+getCatalogs</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getCatalogs</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the catalog names available in this database.  The results
+ are ordered by catalog name.
+
+ <P>The catalog column is:
+  <OL>
+  <LI><B>TABLE_CAT</B> String => catalog name
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getCatalogs()" title="class or interface in java.sql">getCatalogs</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row has a
+         single <code>String</code> column that is a catalog name
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTableTypes()"><!-- --></A><H3>
+getTableTypes</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getTableTypes</B>()
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the table types available in this database.  The results
+ are ordered by table type.
+
+ <P>The table type is:
+  <OL>
+  <LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
+                  "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
+                  "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.1, HSQLDB reports: "TABLE", "VIEW" and "GLOBAL TEMPORARY"
+ types.
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getTableTypes()" title="class or interface in java.sql">getTableTypes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row has a
+         single <code>String</code> column that is a table type
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getColumns</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getColumns</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tableNamePattern,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnNamePattern)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of table columns available in
+ the specified catalog.
+
+ <P>Only column descriptions matching the catalog, schema, table
+ and column name criteria are returned.  They are ordered by
+ <code>TABLE_SCHEM</code>, <code>TABLE_NAME</code>, and
+ <code>ORDINAL_POSITION</code>.
+
+ <P>Each column description has the following columns:
+  <OL>
+  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+  <LI><B>TABLE_NAME</B> String => table name
+  <LI><B>COLUMN_NAME</B> String => column name
+  <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
+  <LI><B>TYPE_NAME</B> String => Data source dependent type name,
+  for a UDT the type name is fully qualified
+  <LI><B>COLUMN_SIZE</B> int => column size.
+  <LI><B>BUFFER_LENGTH</B> is not used.
+  <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits. Null is returned for data types where
+ DECIMAL_DIGITS is not applicable.
+  <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
+  <LI><B>NULLABLE</B> int => is NULL allowed.
+      <UL>
+      <LI> columnNoNulls - might not allow <code>NULL</code> values
+      <LI> columnNullable - definitely allows <code>NULL</code> values
+      <LI> columnNullableUnknown - nullability unknown
+      </UL>
+  <LI><B>REMARKS</B> String => comment describing column (may be <code>null</code>)
+  <LI><B>COLUMN_DEF</B> String => (JDBC4 clarification:) default value for the column, which should be interpreted as a string when the value is enclosed in quotes (may be <code>null</code>)
+  <LI><B>SQL_DATA_TYPE</B> int => unused
+
+        <p>HSQLDB-specific: CLI type from SQL 2003 Table 37,
+        tables 6-9 Annex A1, and/or addendums in other
+        documents, such as:<br>
+        SQL 2003 Part 9: Management of External Data (SQL/MED) : DATALINK<br>
+        SQL 2003 Part 14: XML-Related Specifications (SQL/XML) : XML<p>
+
+  <LI><B>SQL_DATETIME_SUB</B> int => unused (HSQLDB-specific: SQL 2003 CLI datetime/interval subcode)
+  <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
+       maximum number of bytes in the column
+  <LI><B>ORDINAL_POSITION</B> int => index of column in table
+      (starting at 1)
+  <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine the nullability for a column.
+       <UL>
+       <LI> YES           --- if the parameter can include NULLs
+       <LI> NO            --- if the parameter cannot include NULLs
+       <LI> empty string  --- if the nullability for the
+ parameter is unknown
+       </UL>
+  <LI><B>SCOPE_CATLOG</B> String => catalog of table that is the scope
+      of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+  <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the scope
+      of a reference attribute (<code>null</code> if the DATA_TYPE isn't REF)
+  <LI><B>SCOPE_TABLE</B> String => table name that this the scope
+      of a reference attribure (<code>null</code> if the DATA_TYPE isn't REF)
+  <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct type or user-generated
+      Ref type, SQL type from java.sql.Types (<code>null</code> if DATA_TYPE
+      isn't DISTINCT or user-generated REF)
+   <LI><B>IS_AUTOINCREMENT</B> String  => Indicates whether this column is auto incremented
+       <UL>
+       <LI> YES           --- if the column is auto incremented
+       <LI> NO            --- if the column is not auto incremented
+       <LI> empty string  --- if it cannot be determined whether the column is auto incremented
+ parameter is unknown
+       </UL>
+  </OL>
+
+ <p>(JDBC4 clarification:) The COLUMN_SIZE column represents the specified column size for the given column.
+ For numeric data, this is the maximum precision.  For character data, this is the [declared or implicit maximum] length in characters.
+ For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+ maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+ this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+ column size is not applicable. <p>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ This feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformation</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getColumns</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema name pattern; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>tableNamePattern</CODE> - a table name pattern; must match the
+        table name as it is stored in the database<DD><CODE>columnNamePattern</CODE> - a column name pattern; must match the column
+        name as it is stored in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a column description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnPrivileges(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getColumnPrivileges</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getColumnPrivileges</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table,
+                                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnNamePattern)
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the access rights for a table's columns.
+
+ <P>Only privileges matching the column name criteria are
+ returned.  They are ordered by COLUMN_NAME and PRIVILEGE.
+
+ <P>Each privilige description has the following columns:
+  <OL>
+  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+  <LI><B>TABLE_NAME</B> String => table name
+  <LI><B>COLUMN_NAME</B> String => column name
+  <LI><B>GRANTOR</B> => grantor of access (may be <code>null</code>)
+  <LI><B>GRANTEE</B> String => grantee of access
+  <LI><B>PRIVILEGE</B> String => name of access (SELECT,
+      INSERT, UPDATE, REFRENCES, ...)
+  <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
+      to grant to others; "NO" if not; <code>null</code> if unknown
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getColumnPrivileges(java.lang.String, java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getColumnPrivileges</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schema</CODE> - a schema name; must match the schema name as it is
+        stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>table</CODE> - a table name; must match the table name as it is
+        stored in the database<DD><CODE>columnNamePattern</CODE> - a column name pattern; must match the column
+        name as it is stored in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a column privilege description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTablePrivileges(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getTablePrivileges</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getTablePrivileges</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tableNamePattern)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the access rights for each table available
+ in a catalog. Note that a table privilege applies to one or
+ more columns in the table. It would be wrong to assume that
+ this privilege applies to all columns (this may be true for
+ some systems but is not true for all.)
+
+ <P>Only privileges matching the schema and table name
+ criteria are returned.  They are ordered by TABLE_SCHEM,
+ TABLE_NAME, and PRIVILEGE.
+
+ <P>Each privilige description has the following columns:
+  <OL>
+  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+  <LI><B>TABLE_NAME</B> String => table name
+  <LI><B>GRANTOR</B> => grantor of access (may be <code>null</code>)
+  <LI><B>GRANTEE</B> String => grantee of access
+  <LI><B>PRIVILEGE</B> String => name of access (SELECT,
+      INSERT, UPDATE, REFRENCES, ...)
+  <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
+      to grant to others; "NO" if not; <code>null</code> if unknown
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getTablePrivileges(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getTablePrivileges</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema name pattern; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>tableNamePattern</CODE> - a table name pattern; must match the
+        table name as it is stored in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a table privilege description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBestRowIdentifier(java.lang.String, java.lang.String, java.lang.String, int, boolean)"><!-- --></A><H3>
+getBestRowIdentifier</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getBestRowIdentifier</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table,
+                                      int&nbsp;scope,
+                                      boolean&nbsp;nullable)
+                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of a table's optimal set of columns that
+ uniquely identifies a row. They are ordered by SCOPE.
+
+ <P>Each column description has the following columns:
+  <OL>
+  <LI><B>SCOPE</B> short => actual scope of result
+      <UL>
+      <LI> bestRowTemporary - very temporary, while using row
+      <LI> bestRowTransaction - valid for remainder of current transaction
+      <LI> bestRowSession - valid for remainder of current session
+      </UL>
+  <LI><B>COLUMN_NAME</B> String => column name
+  <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
+  <LI><B>TYPE_NAME</B> String => Data source dependent type name,
+  for a UDT the type name is fully qualified
+  <LI><B>COLUMN_SIZE</B> int => precision
+  <LI><B>BUFFER_LENGTH</B> int => not used
+  <LI><B>DECIMAL_DIGITS</B> short  => scale - Null is returned for data types where
+ DECIMAL_DIGITS is not applicable.
+  <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
+      like an Oracle ROWID
+      <UL>
+      <LI> bestRowUnknown - may or may not be pseudo column
+      <LI> bestRowNotPseudo - is NOT a pseudo column
+      <LI> bestRowPseudo - is a pseudo column
+      </UL>
+  </OL>
+
+ <p>(JDBC4 clarification:)<p>
+ The COLUMN_SIZE column represents the specified column size for the given column.
+ For numeric data, this is the maximum precision.  For character data, this is the [declared or implicit maximum] length in characters.
+ For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+ maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+ this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+ column size is not applicable. <p>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ If the name of a column is defined in the database without double
+ quotes, an all-uppercase name must be specified when calling this
+ method. Otherwise, the name must be specified in the exact case of
+ the column definition in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getBestRowIdentifier(java.lang.String, java.lang.String, java.lang.String, int, boolean)" title="class or interface in java.sql">getBestRowIdentifier</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schema</CODE> - a schema name; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>table</CODE> - a table name; must match the table name as it is stored
+        in the database<DD><CODE>scope</CODE> - the scope of interest; use same values as SCOPE<DD><CODE>nullable</CODE> - include columns that are nullable.
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a column description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getVersionColumns(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getVersionColumns</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getVersionColumns</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of a table's columns that are automatically
+ updated when any value in a row is updated.  They are
+ unordered.
+
+ <P>Each column description has the following columns:
+  <OL>
+  <LI><B>SCOPE</B> short => is not used
+  <LI><B>COLUMN_NAME</B> String => column name
+  <LI><B>DATA_TYPE</B> int => SQL data type from <code>java.sql.Types</code>
+  <LI><B>TYPE_NAME</B> String => Data source-dependent type name
+  <LI><B>COLUMN_SIZE</B> int => precision
+  <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
+  <LI><B>DECIMAL_DIGITS</B> short  => scale - Null is returned for data types where
+ DECIMAL_DIGITS is not applicable.
+  <LI><B>PSEUDO_COLUMN</B> short => whether this is pseudo column
+      like an Oracle ROWID
+      <UL>
+      <LI> versionColumnUnknown - may or may not be pseudo column
+      <LI> versionColumnNotPseudo - is NOT a pseudo column
+      <LI> versionColumnPseudo - is a pseudo column
+      </UL>
+  </OL>
+
+ <p>(JDBC4 clarification:)
+
+ <p>The COLUMN_SIZE column represents the specified column size for the given column.
+ For numeric data, this is the maximum precision.  For character data, this is the [declared or implicit maximum] length in characters.
+ For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+ maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+ this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+ column size is not applicable.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getVersionColumns(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getVersionColumns</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schema</CODE> - a schema name; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>table</CODE> - a table name; must match the table name as it is stored
+        in the database
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row is a
+         column description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getPrimaryKeys</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getPrimaryKeys</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the given table's primary key columns.  They
+ are ordered by COLUMN_NAME.
+
+ <P>Each primary key column description has the following columns:
+  <OL>
+  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+  <LI><B>TABLE_NAME</B> String => table name
+  <LI><B>COLUMN_NAME</B> String => column name
+  <LI><B>KEY_SEQ</B> short => (JDBC4 Clarification:) sequence number within primary key( a value
+  of 1 represents the first column of the primary key, a value of 2 would
+  represent the second column within the primary key).
+  <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getPrimaryKeys</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schema</CODE> - a schema name; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>table</CODE> - a table name; must match the table name as it is stored
+        in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a primary key column description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseQuotedIdentifiers()"><CODE>supportsMixedCaseQuotedIdentifiers()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseIdentifiers()"><CODE>storesUpperCaseIdentifiers()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getImportedKeys(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getImportedKeys</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getImportedKeys</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the primary key columns that are
+ referenced by the given table's foreign key columns (the primary keys
+ imported by a table).  They are ordered by PKTABLE_CAT,
+ PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
+
+ <P>Each primary key column description has the following columns:
+  <OL>
+  <LI><B>PKTABLE_CAT</B> String => primary key table catalog
+      being imported (may be <code>null</code>)
+  <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
+      being imported (may be <code>null</code>)
+  <LI><B>PKTABLE_NAME</B> String => primary key table name
+      being imported
+  <LI><B>PKCOLUMN_NAME</B> String => primary key column name
+      being imported
+  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
+  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
+  <LI><B>FKTABLE_NAME</B> String => foreign key table name
+  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
+  <LI><B>KEY_SEQ</B> short => (JDBC4 clarification) sequence number within a foreign key (a value
+  of 1 represents the first column of the foreign key, a value of 2 would
+  represent the second column within the foreign key).
+  <LI><B>UPDATE_RULE</B> short => What happens to a
+       foreign key when the primary key is updated:
+      <UL>
+      <LI> importedNoAction - do not allow update of primary
+               key if it has been imported
+      <LI> importedKeyCascade - change imported key to agree
+               with primary key update
+      <LI> importedKeySetNull - change imported key to <code>NULL</code>
+               if its primary key has been updated
+      <LI> importedKeySetDefault - change imported key to default values
+               if its primary key has been updated
+      <LI> importedKeyRestrict - same as importedKeyNoAction
+                                 (for ODBC 2.x compatibility)
+      </UL>
+  <LI><B>DELETE_RULE</B> short => What happens to
+      the foreign key when primary is deleted.
+      <UL>
+      <LI> importedKeyNoAction - do not allow delete of primary
+               key if it has been imported
+      <LI> importedKeyCascade - delete rows that import a deleted key
+      <LI> importedKeySetNull - change imported key to NULL if
+               its primary key has been deleted
+      <LI> importedKeyRestrict - same as importedKeyNoAction
+                                 (for ODBC 2.x compatibility)
+      <LI> importedKeySetDefault - change imported key to default if
+               its primary key has been deleted
+      </UL>
+  <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
+  <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
+  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
+      constraints be deferred until commit
+      <UL>
+      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
+      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
+      <LI> importedKeyNotDeferrable - see SQL92 for definition
+      </UL>
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getImportedKeys(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getImportedKeys</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schema</CODE> - a schema name; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>table</CODE> - a table name; must match the table name as it is stored
+        in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a primary key column description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getExportedKeys(java.lang.String, java.lang.String, java.lang.String)"><CODE>getExportedKeys(java.lang.String, java.lang.String, java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseQuotedIdentifiers()"><CODE>supportsMixedCaseQuotedIdentifiers()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseIdentifiers()"><CODE>storesUpperCaseIdentifiers()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getExportedKeys(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getExportedKeys</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getExportedKeys</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the foreign key columns that reference the
+ given table's primary key columns (the foreign keys exported by a
+ table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
+ FKTABLE_NAME, and KEY_SEQ.
+
+ <P>Each foreign key column description has the following columns:
+  <OL>
+  <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be <code>null</code>)
+  <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be <code>null</code>)
+  <LI><B>PKTABLE_NAME</B> String => primary key table name
+  <LI><B>PKCOLUMN_NAME</B> String => primary key column name
+  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
+      being exported (may be <code>null</code>)
+  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
+      being exported (may be <code>null</code>)
+  <LI><B>FKTABLE_NAME</B> String => foreign key table name
+      being exported
+  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
+      being exported
+  <LI><B>KEY_SEQ</B> short => (JDBC4 clarification:) sequence number within foreign key( a value
+  of 1 represents the first column of the foreign key, a value of 2 would
+  represent the second column within the foreign key).
+  <LI><B>UPDATE_RULE</B> short => What happens to
+       foreign key when primary is updated:
+      <UL>
+      <LI> importedNoAction - do not allow update of primary
+               key if it has been imported
+      <LI> importedKeyCascade - change imported key to agree
+               with primary key update
+      <LI> importedKeySetNull - change imported key to <code>NULL</code> if
+               its primary key has been updated
+      <LI> importedKeySetDefault - change imported key to default values
+               if its primary key has been updated
+      <LI> importedKeyRestrict - same as importedKeyNoAction
+                                 (for ODBC 2.x compatibility)
+      </UL>
+  <LI><B>DELETE_RULE</B> short => What happens to
+      the foreign key when primary is deleted.
+      <UL>
+      <LI> importedKeyNoAction - do not allow delete of primary
+               key if it has been imported
+      <LI> importedKeyCascade - delete rows that import a deleted key
+      <LI> importedKeySetNull - change imported key to <code>NULL</code> if
+               its primary key has been deleted
+      <LI> importedKeyRestrict - same as importedKeyNoAction
+                                 (for ODBC 2.x compatibility)
+      <LI> importedKeySetDefault - change imported key to default if
+               its primary key has been deleted
+      </UL>
+  <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
+  <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
+  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
+      constraints be deferred until commit
+      <UL>
+      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
+      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
+      <LI> importedKeyNotDeferrable - see SQL92 for definition
+      </UL>
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getExportedKeys(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getExportedKeys</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in this database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schema</CODE> - a schema name; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>table</CODE> - a table name; must match the table name as it is stored
+        in this database
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row is a
+         foreign key column description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getImportedKeys(java.lang.String, java.lang.String, java.lang.String)"><CODE>getImportedKeys(java.lang.String, java.lang.String, java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseQuotedIdentifiers()"><CODE>supportsMixedCaseQuotedIdentifiers()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseIdentifiers()"><CODE>storesUpperCaseIdentifiers()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCrossReference(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getCrossReference</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getCrossReference</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parentCatalog,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parentSchema,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;parentTable,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;foreignCatalog,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;foreignSchema,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;foreignTable)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>(JDBC4 clarification:)
+ Retrieves a description of the foreign key columns in the given foreign key
+ table that reference the primary key or the columns representing a unique constraint of the  parent table (could be the same or a different table).
+ The number of columns returned from the parent table must match the number of
+ columns that make up the foreign key.  They
+ are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
+ KEY_SEQ.
+
+ <P>Each foreign key column description has the following columns:
+  <OL>
+  <LI><B>PKTABLE_CAT</B> String => parent key table catalog (may be <code>null</code>)
+  <LI><B>PKTABLE_SCHEM</B> String => parent key table schema (may be <code>null</code>)
+  <LI><B>PKTABLE_NAME</B> String => parent key table name
+  <LI><B>PKCOLUMN_NAME</B> String => parent key column name
+  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
+      being exported (may be <code>null</code>)
+  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
+      being exported (may be <code>null</code>)
+  <LI><B>FKTABLE_NAME</B> String => foreign key table name
+      being exported
+  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
+      being exported
+  <LI><B>KEY_SEQ</B> short => sequence number within foreign key( a value
+  of 1 represents the first column of the foreign key, a value of 2 would
+  represent the second column within the foreign key).
+  <LI><B>UPDATE_RULE</B> short => What happens to
+       foreign key when parent key is updated:
+      <UL>
+      <LI> importedNoAction - do not allow update of parent
+               key if it has been imported
+      <LI> importedKeyCascade - change imported key to agree
+               with parent key update
+      <LI> importedKeySetNull - change imported key to <code>NULL</code> if
+               its parent key has been updated
+      <LI> importedKeySetDefault - change imported key to default values
+               if its parent key has been updated
+      <LI> importedKeyRestrict - same as importedKeyNoAction
+                                 (for ODBC 2.x compatibility)
+      </UL>
+  <LI><B>DELETE_RULE</B> short => What happens to
+      the foreign key when parent key is deleted.
+      <UL>
+      <LI> importedKeyNoAction - do not allow delete of parent
+               key if it has been imported
+      <LI> importedKeyCascade - delete rows that import a deleted key
+      <LI> importedKeySetNull - change imported key to <code>NULL</code> if
+               its primary key has been deleted
+      <LI> importedKeyRestrict - same as importedKeyNoAction
+                                 (for ODBC 2.x compatibility)
+      <LI> importedKeySetDefault - change imported key to default if
+               its parent key has been deleted
+      </UL>
+  <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
+  <LI><B>PK_NAME</B> String => parent key name (may be <code>null</code>)
+  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
+      constraints be deferred until commit
+      <UL>
+      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
+      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
+      <LI> importedKeyNotDeferrable - see SQL92 for definition
+      </UL>
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getCrossReference(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getCrossReference</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parentCatalog</CODE> - a catalog name; must match the catalog name
+ as it is stored in the database; "" retrieves those without a
+ catalog; <code>null</code> means drop catalog name from the selection criteria<DD><CODE>parentSchema</CODE> - a schema name; must match the schema name as
+ it is stored in the database; "" retrieves those without a schema;
+ <code>null</code> means drop schema name from the selection criteria<DD><CODE>parentTable</CODE> - the name of the table that exports the key; must match
+ the table name as it is stored in the database<DD><CODE>foreignCatalog</CODE> - a catalog name; must match the catalog name as
+ it is stored in the database; "" retrieves those without a
+ catalog; <code>null</code> means drop catalog name from the selection criteria<DD><CODE>foreignSchema</CODE> - a schema name; must match the schema name as it
+ is stored in the database; "" retrieves those without a schema;
+ <code>null</code> means drop schema name from the selection criteria<DD><CODE>foreignTable</CODE> - the name of the table that imports the key; must match
+ the table name as it is stored in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a foreign key column description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getImportedKeys(java.lang.String, java.lang.String, java.lang.String)"><CODE>getImportedKeys(java.lang.String, java.lang.String, java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseQuotedIdentifiers()"><CODE>supportsMixedCaseQuotedIdentifiers()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseIdentifiers()"><CODE>storesUpperCaseIdentifiers()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTypeInfo()"><!-- --></A><H3>
+getTypeInfo</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getTypeInfo</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of all the (JDBC4 clarification:) data types supported by
+ this database. They are ordered by DATA_TYPE and then by how
+ closely the data type maps to the corresponding JDBC SQL type.
+
+ <P>(JDBC4 clarification:) If the database supports SQL distinct types, then getTypeInfo() will return
+ a single row with a TYPE_NAME of DISTINCT and a DATA_TYPE of Types.DISTINCT.
+ If the database supports SQL structured types, then getTypeInfo() will return
+ a single row with a TYPE_NAME of STRUCT and a DATA_TYPE of Types.STRUCT.
+
+ <P>(JDBC4 clarification:)
+ <P>If SQL distinct or structured types are supported, then information on the
+ individual types may be obtained from the getUDTs() method.
+
+
+ <P>Each type description has the following columns:
+  <OL>
+  <LI><B>TYPE_NAME</B> String => Type name
+  <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
+  <LI><B>PRECISION</B> int => maximum precision
+  <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
+      (may be <code>null</code>)
+  <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
+ (may be <code>null</code>)
+  <LI><B>CREATE_PARAMS</B> String => parameters used in creating
+      the type (may be <code>null</code>)
+  <LI><B>NULLABLE</B> short => can you use NULL for this type.
+      <UL>
+      <LI> typeNoNulls - does not allow NULL values
+      <LI> typeNullable - allows NULL values
+      <LI> typeNullableUnknown - nullability unknown
+      </UL>
+  <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive.
+  <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
+      <UL>
+      <LI> typePredNone - No support
+      <LI> typePredChar - Only supported with WHERE .. LIKE
+      <LI> typePredBasic - Supported except for WHERE .. LIKE
+      <LI> typeSearchable - Supported for all WHERE ..
+      </UL>
+  <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned.
+  <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value.
+  <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
+      auto-increment value.
+  <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
+      (may be <code>null</code>)
+  <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
+  <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
+  <LI><B>SQL_DATA_TYPE</B> int => unused
+  <LI><B>SQL_DATETIME_SUB</B> int => unused
+  <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
+  </OL>
+
+ <p>(JDBC4 clarification:) The PRECISION column represents the maximum column size that the server supports for the given datatype.
+ For numeric data, this is the maximum precision.  For character data, this is the [maximum] length in characters.
+ For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+ maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+ this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+ column size is not applicable.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getTypeInfo()" title="class or interface in java.sql">getTypeInfo</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row is an SQL
+         type description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getIndexInfo(java.lang.String, java.lang.String, java.lang.String, boolean, boolean)"><!-- --></A><H3>
+getIndexInfo</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getIndexInfo</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schema,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;table,
+                              boolean&nbsp;unique,
+                              boolean&nbsp;approximate)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the given table's indices and statistics. They are
+ ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
+
+ <P>Each index column description has the following columns:
+  <OL>
+  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+  <LI><B>TABLE_NAME</B> String => table name
+  <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique.
+      false when TYPE is tableIndexStatistic
+  <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be <code>null</code>);
+      <code>null</code> when TYPE is tableIndexStatistic
+  <LI><B>INDEX_NAME</B> String => index name; <code>null</code> when TYPE is
+      tableIndexStatistic
+  <LI><B>TYPE</B> short => index type:
+      <UL>
+      <LI> tableIndexStatistic - this identifies table statistics that are
+           returned in conjuction with a table's index descriptions
+      <LI> tableIndexClustered - this is a clustered index
+      <LI> tableIndexHashed - this is a hashed index
+      <LI> tableIndexOther - this is some other style of index
+      </UL>
+  <LI><B>ORDINAL_POSITION</B> short => column sequence number
+      within index; zero when TYPE is tableIndexStatistic
+  <LI><B>COLUMN_NAME</B> String => column name; <code>null</code> when TYPE is
+      tableIndexStatistic
+  <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
+      "D" => descending, may be <code>null</code> if sort sequence is not supported;
+      <code>null</code> when TYPE is tableIndexStatistic
+  <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
+      this is the number of rows in the table; otherwise, it is the
+      number of unique values in the index.
+  <LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then
+      this is the number of pages used for the table, otherwise it
+      is the number of pages used for the current index.
+  <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
+      (may be <code>null</code>)
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Since 1.7.2, this feature is supported by default. If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getIndexInfo(java.lang.String, java.lang.String, java.lang.String, boolean, boolean)" title="class or interface in java.sql">getIndexInfo</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in this database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schema</CODE> - a schema name; must match the schema name
+        as it is stored in this database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>table</CODE> - a table name; must match the table name as it is stored
+        in this database<DD><CODE>unique</CODE> - when true, return only indices for unique values;
+     when false, return indices regardless of whether unique or not<DD><CODE>approximate</CODE> - when true, result is allowed to reflect approximate
+     or out of data values; when false, results are requested to be
+     accurate
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is an index column description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#supportsMixedCaseQuotedIdentifiers()"><CODE>supportsMixedCaseQuotedIdentifiers()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#storesUpperCaseIdentifiers()"><CODE>storesUpperCaseIdentifiers()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsResultSetType(int)"><!-- --></A><H3>
+supportsResultSetType</H3>
+<PRE>
+public boolean <B>supportsResultSetType</B>(int&nbsp;type)
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the given result set type.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsResultSetType(int)" title="class or interface in java.sql">supportsResultSetType</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - defined in <code>java.sql.ResultSet</code>
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+      for JDBCDatabaseMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><CODE>JDBCConnection</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsResultSetConcurrency(int, int)"><!-- --></A><H3>
+supportsResultSetConcurrency</H3>
+<PRE>
+public boolean <B>supportsResultSetConcurrency</B>(int&nbsp;type,
+                                            int&nbsp;concurrency)
+                                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the given concurrency type
+ in combination with the given result set type.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsResultSetConcurrency(int, int)" title="class or interface in java.sql">supportsResultSetConcurrency</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - defined in <code>java.sql.ResultSet</code><DD><CODE>concurrency</CODE> - type defined in <code>java.sql.ResultSet</code>
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+      for JDBCDatabaseMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><CODE>JDBCConnection</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="ownUpdatesAreVisible(int)"><!-- --></A><H3>
+ownUpdatesAreVisible</H3>
+<PRE>
+public boolean <B>ownUpdatesAreVisible</B>(int&nbsp;type)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether for the given type of <code>ResultSet</code> object,
+ the result set's own updates are visible.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+ Updates to ResultSet rows are not visible after moving from the updated
+ row.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#ownUpdatesAreVisible(int)" title="class or interface in java.sql">ownUpdatesAreVisible</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if updates are visible for the given result set type;
+        <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="ownDeletesAreVisible(int)"><!-- --></A><H3>
+ownDeletesAreVisible</H3>
+<PRE>
+public boolean <B>ownDeletesAreVisible</B>(int&nbsp;type)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a result set's own deletes are visible.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Rows deleted from the ResultSet are still visible after moving from the
+ deleted row.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#ownDeletesAreVisible(int)" title="class or interface in java.sql">ownDeletesAreVisible</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if deletes are visible for the given result set type;
+        <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="ownInsertsAreVisible(int)"><!-- --></A><H3>
+ownInsertsAreVisible</H3>
+<PRE>
+public boolean <B>ownInsertsAreVisible</B>(int&nbsp;type)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a result set's own inserts are visible.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Rows added to a ResultSet are not visible after moving from the
+ insert row; this method always returns <code>false</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#ownInsertsAreVisible(int)" title="class or interface in java.sql">ownInsertsAreVisible</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if inserts are visible for the given result set type;
+        <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="othersUpdatesAreVisible(int)"><!-- --></A><H3>
+othersUpdatesAreVisible</H3>
+<PRE>
+public boolean <B>othersUpdatesAreVisible</B>(int&nbsp;type)
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether updates made by others are visible.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Updates made by other connections or the same connection while the
+ ResultSet is open are not visible in the ResultSet.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#othersUpdatesAreVisible(int)" title="class or interface in java.sql">othersUpdatesAreVisible</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if updates made by others
+        are visible for the given result set type;
+        <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="othersDeletesAreVisible(int)"><!-- --></A><H3>
+othersDeletesAreVisible</H3>
+<PRE>
+public boolean <B>othersDeletesAreVisible</B>(int&nbsp;type)
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether deletes made by others are visible.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Deletes made by other connections or the same connection while the
+ ResultSet is open are not visible in the ResultSet.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#othersDeletesAreVisible(int)" title="class or interface in java.sql">othersDeletesAreVisible</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if deletes made by others
+        are visible for the given result set type;
+        <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="othersInsertsAreVisible(int)"><!-- --></A><H3>
+othersInsertsAreVisible</H3>
+<PRE>
+public boolean <B>othersInsertsAreVisible</B>(int&nbsp;type)
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether inserts made by others are visible.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Inserts made by other connections or the same connection while the
+ ResultSet is open are not visible in the ResultSet.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#othersInsertsAreVisible(int)" title="class or interface in java.sql">othersInsertsAreVisible</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if inserts made by others
+         are visible for the given result set type;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updatesAreDetected(int)"><!-- --></A><H3>
+updatesAreDetected</H3>
+<PRE>
+public boolean <B>updatesAreDetected</B>(int&nbsp;type)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether or not a visible row update can be detected by
+ calling the method <code>ResultSet.rowUpdated</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Updates made to the rows of the ResultSet are not detected by
+ calling the <code>ResultSet.rowUpdated</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#updatesAreDetected(int)" title="class or interface in java.sql">updatesAreDetected</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if changes are detected by the result set type;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="deletesAreDetected(int)"><!-- --></A><H3>
+deletesAreDetected</H3>
+<PRE>
+public boolean <B>deletesAreDetected</B>(int&nbsp;type)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether or not a visible row delete can be detected by
+ calling the method <code>ResultSet.rowDeleted</code>.  If the method
+ <code>deletesAreDetected</code> returns <code>false</code>, it means that
+ deleted rows are removed from the result set.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Deletes made to the rows of the ResultSet are not detected by
+ calling the <code>ResultSet.rowDeleted/code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#deletesAreDetected(int)" title="class or interface in java.sql">deletesAreDetected</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if deletes are detected by the given result set type;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="insertsAreDetected(int)"><!-- --></A><H3>
+insertsAreDetected</H3>
+<PRE>
+public boolean <B>insertsAreDetected</B>(int&nbsp;type)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether or not a visible row insert can be detected
+ by calling the method <code>ResultSet.rowInserted</code>.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Inserts made into the ResultSet are not visible and thus not detected by
+ calling the <code>ResultSet.rowInserted</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#insertsAreDetected(int)" title="class or interface in java.sql">insertsAreDetected</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>type</CODE> - the <code>ResultSet</code> type; one of
+        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Returns:</B><DD><code>true</code> if changes are detected by the specified result
+         set type; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsBatchUpdates()"><!-- --></A><H3>
+supportsBatchUpdates</H3>
+<PRE>
+public boolean <B>supportsBatchUpdates</B>()
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports batch updates.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports batch updates;
+ this method always returns <code>true</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsBatchUpdates()" title="class or interface in java.sql">supportsBatchUpdates</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if this database supports batch upcates;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUDTs(java.lang.String, java.lang.String, java.lang.String, int[])"><!-- --></A><H3>
+getUDTs</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getUDTs</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeNamePattern,
+                         int[]&nbsp;types)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the user-defined types (UDTs) defined
+ in a particular schema.  Schema-specific UDTs may have type
+ <code>JAVA_OBJECT</code>, <code>STRUCT</code>,
+ or <code>DISTINCT</code>.
+
+ <P>Only types matching the catalog, schema, type name and type
+ criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM
+ and TYPE_NAME.  The type name parameter may be a fully-qualified
+ name.  In this case, the catalog and schemaPattern parameters are
+ ignored.
+
+ <P>Each type description has the following columns:
+  <OL>
+  <LI><B>TYPE_CAT</B> String => the type's catalog (may be <code>null</code>)
+  <LI><B>TYPE_SCHEM</B> String => type's schema (may be <code>null</code>)
+  <LI><B>TYPE_NAME</B> String => type name
+  <LI><B>CLASS_NAME</B> String => Java class name
+  <LI><B>DATA_TYPE</B> int => type value defined in java.sql.Types.
+     One of JAVA_OBJECT, STRUCT, or DISTINCT
+  <LI><B>REMARKS</B> String => explanatory comment on the type
+  <LI><B>BASE_TYPE</B> short => type code of the source type of a
+     DISTINCT type or the type that implements the user-generated
+     reference type of the SELF_REFERENCING_COLUMN of a structured
+     type as defined in java.sql.Types (<code>null</code> if DATA_TYPE is not
+     DISTINCT or not STRUCT with REFERENCE_GENERATION = USER_DEFINED)
+  </OL>
+
+ <P><B>Note:</B> If the driver does not support UDTs, an empty
+ result set is returned.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ Starting with 2.0, DISTICT types are supported and are reported by this
+ method.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getUDTs(java.lang.String, java.lang.String, java.lang.String, int[])" title="class or interface in java.sql">getUDTs</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema pattern name; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>typeNamePattern</CODE> - a type name pattern; must match the type name
+        as it is stored in the database; may be a fully qualified name<DD><CODE>types</CODE> - a list of user-defined types (JAVA_OBJECT,
+        STRUCT, or DISTINCT) to include; <code>null</code> returns all types
+<DT><B>Returns:</B><DD><code>ResultSet</code> object in which each row describes a UDT
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+     for JDBCDatabaseMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>(JDBC4 clarification)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConnection()"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the connection that produced this metadata object.
+ <P>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getConnection()" title="class or interface in java.sql">getConnection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the connection that produced this metadata object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+      for JDBCDatabaseMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsSavepoints()"><!-- --></A><H3>
+supportsSavepoints</H3>
+<PRE>
+public boolean <B>supportsSavepoints</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports savepoints.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Beginning with 1.7.2, this SQL feature is supported
+ through JDBC as well as SQL. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsSavepoints()" title="class or interface in java.sql">supportsSavepoints</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if savepoints are supported;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsNamedParameters()"><!-- --></A><H3>
+supportsNamedParameters</H3>
+<PRE>
+public boolean <B>supportsNamedParameters</B>()
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports named parameters to callable
+ statements.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.7.2, HSQLDB supports JDBC named parameters to
+ callable statements; this method returns true. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsNamedParameters()" title="class or interface in java.sql">supportsNamedParameters</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if named parameters are supported;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsMultipleOpenResults()"><!-- --></A><H3>
+supportsMultipleOpenResults</H3>
+<PRE>
+public boolean <B>supportsMultipleOpenResults</B>()
+                                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether it is possible to have multiple <code>ResultSet</code> objects
+ returned from a <code>CallableStatement</code> object
+ simultaneously.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports multiple ResultSet
+ objects returned from a <code>CallableStatement</code>;
+ this method always returns <code>true</code>. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsMultipleOpenResults()" title="class or interface in java.sql">supportsMultipleOpenResults</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if a <code>CallableStatement</code> object
+         can return multiple <code>ResultSet</code> objects
+         simultaneously; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a datanase access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsGetGeneratedKeys()"><!-- --></A><H3>
+supportsGetGeneratedKeys</H3>
+<PRE>
+public boolean <B>supportsGetGeneratedKeys</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether auto-generated keys can be retrieved after
+ a statement has been executed
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports retrieval of
+ autogenerated keys through the JDBC interface;
+ this method always returns <code>true</code>. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsGetGeneratedKeys()" title="class or interface in java.sql">supportsGetGeneratedKeys</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if auto-generated keys can be retrieved
+         after a statement has executed; <code>false</code> otherwise
+ <p>(JDBC4 Clarification:)
+ <p>If <code>true</code> is returned, the JDBC driver must support the
+ returning of auto-generated keys for at least SQL INSERT statements
+ <p>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSuperTypes(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getSuperTypes</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getSuperTypes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeNamePattern)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the user-defined type (UDT) hierarchies defined in a
+ particular schema in this database. Only the immediate super type
+ sub type relationship is modeled.
+ <P>
+ Only supertype information for UDTs matching the catalog,
+ schema, and type name is returned. The type name parameter
+ may be a fully-qualified name. When the UDT name supplied is a
+ fully-qualified name, the catalog and schemaPattern parameters are
+ ignored.
+ <P>
+ If a UDT does not have a direct super type, it is not listed here.
+ A row of the <code>ResultSet</code> object returned by this method
+ describes the designated UDT and a direct supertype. A row has the following
+ columns:
+  <OL>
+  <LI><B>TYPE_CAT</B> String => the UDT's catalog (may be <code>null</code>)
+  <LI><B>TYPE_SCHEM</B> String => UDT's schema (may be <code>null</code>)
+  <LI><B>TYPE_NAME</B> String => type name of the UDT
+  <LI><B>SUPERTYPE_CAT</B> String => the direct super type's catalog
+                           (may be <code>null</code>)
+  <LI><B>SUPERTYPE_SCHEM</B> String => the direct super type's schema
+                             (may be <code>null</code>)
+  <LI><B>SUPERTYPE_NAME</B> String => the direct super type's name
+  </OL>
+
+ <P><B>Note:</B> If the driver does not support type hierarchies, an
+ empty result set is returned.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+ case insensitive in SQL and stores
+ them in upper case; it treats quoted identifiers as case sensitive and
+ stores them verbatim. All JDBCDatabaseMetaData methods perform
+ case-sensitive comparison between name (pattern) arguments and the
+ corresponding identifier values as they are stored in the database.
+ Therefore, care must be taken to specify name arguments precisely
+ (including case) as they are stored in the database. <p>
+
+ From 2.0, this feature is supported by default and return supertypes
+ for DOMAIN and DISTINCT types.<p>
+
+ If the jar is
+ compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+ not supported. The default implementation is
+ <CODE>DatabaseInformationMain</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSuperTypes(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getSuperTypes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; "" retrieves those without a catalog;
+        <code>null</code> means drop catalog name from the selection criteria<DD><CODE>schemaPattern</CODE> - a schema name pattern; "" retrieves those
+        without a schema<DD><CODE>typeNamePattern</CODE> - a UDT name pattern; may be a fully-qualified
+        name
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which a row gives information
+         about the designated UDT
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>(JDBC4 clarification)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSuperTables(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getSuperTables</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getSuperTables</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tableNamePattern)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the table hierarchies defined in a particular
+ schema in this database.
+
+ <P>Only supertable information for tables matching the catalog, schema
+ and table name are returned. The table name parameter may be a fully-
+ qualified name, in which case, the catalog and schemaPattern parameters
+ are ignored. If a table does not have a super table, it is not listed here.
+ Supertables have to be defined in the same catalog and schema as the
+ sub tables. Therefore, the type description does not need to include
+ this information for the supertable.
+
+ <P>Each type description has the following columns:
+  <OL>
+  <LI><B>TABLE_CAT</B> String => the type's catalog (may be <code>null</code>)
+  <LI><B>TABLE_SCHEM</B> String => type's schema (may be <code>null</code>)
+  <LI><B>TABLE_NAME</B> String => type name
+  <LI><B>SUPERTABLE_NAME</B> String => the direct super type's name
+  </OL>
+
+ <P><B>Note:</B> If the driver does not support type hierarchies, an
+ empty result set is returned.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ This method is intended for tables of structured types.
+ From 2.0 this method returns an empty ResultSet.
+ <CODE>DatabaseInformationFull</CODE>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSuperTables(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getSuperTables</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; "" retrieves those without a catalog;
+        <code>null</code> means drop catalog name from the selection criteria<DD><CODE>schemaPattern</CODE> - a schema name pattern; "" retrieves those
+        without a schema<DD><CODE>tableNamePattern</CODE> - a table name pattern; may be a fully-qualified
+        name
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row is a type description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>(JDBC4 clarification)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAttributes(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getAttributes</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getAttributes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeNamePattern,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;attributeNamePattern)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the given attribute of the given type
+ for a user-defined type (UDT) that is available in the given schema
+ and catalog.
+ <P>
+ Descriptions are returned only for attributes of UDTs matching the
+ catalog, schema, type, and attribute name criteria. They are ordered by
+ TYPE_SCHEM, TYPE_NAME and ORDINAL_POSITION. This description
+ does not contain inherited attributes.
+ <P>
+ The <code>ResultSet</code> object that is returned has the following
+ columns:
+ <OL>
+  <LI><B>TYPE_CAT</B> String => type catalog (may be <code>null</code>)
+  <LI><B>TYPE_SCHEM</B> String => type schema (may be <code>null</code>)
+  <LI><B>TYPE_NAME</B> String => type name
+  <LI><B>ATTR_NAME</B> String => attribute name
+  <LI><B>DATA_TYPE</B> int => attribute type SQL type from java.sql.Types
+  <LI><B>ATTR_TYPE_NAME</B> String => Data source dependent type name.
+  For a UDT, the type name is fully qualified. For a REF, the type name is
+  fully qualified and represents the target type of the reference type.
+  <LI><B>ATTR_SIZE</B> int => column size.  For char or date
+      types this is the maximum number of characters; for numeric or
+      decimal types this is precision.
+  <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits. Null is returned for data types where
+ DECIMAL_DIGITS is not applicable.
+  <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
+  <LI><B>NULLABLE</B> int => whether NULL is allowed
+      <UL>
+      <LI> attributeNoNulls - might not allow NULL values
+      <LI> attributeNullable - definitely allows NULL values
+      <LI> attributeNullableUnknown - nullability unknown
+      </UL>
+  <LI><B>REMARKS</B> String => comment describing column (may be <code>null</code>)
+  <LI><B>ATTR_DEF</B> String => default value (may be <code>null</code>)
+  <LI><B>SQL_DATA_TYPE</B> int => unused
+  <LI><B>SQL_DATETIME_SUB</B> int => unused
+  <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
+       maximum number of bytes in the column
+  <LI><B>ORDINAL_POSITION</B> int => index of column in table
+      (starting at 1)
+  <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine the nullability for a column.
+       <UL>
+       <LI> YES           --- if the parameter can include NULLs
+       <LI> NO            --- if the parameter cannot include NULLs
+       <LI> empty string  --- if the nullability for the
+ parameter is unknown
+       </UL>
+  <LI><B>SCOPE_CATALOG</B> String => catalog of table that is the
+      scope of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+  <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the
+      scope of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+  <LI><B>SCOPE_TABLE</B> String => table name that is the scope of a
+      reference attribute (<code>null</code> if the DATA_TYPE isn't REF)
+ <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct type or user-generated
+      Ref type,SQL type from java.sql.Types (<code>null</code> if DATA_TYPE
+      isn't DISTINCT or user-generated REF)
+  </OL>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ This method is intended for attributes of structured types.
+ From 2.0 this method returns an empty ResultSet.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getAttributes(java.lang.String, java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getAttributes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema name pattern; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>typeNamePattern</CODE> - a type name pattern; must match the
+        type name as it is stored in the database<DD><CODE>attributeNamePattern</CODE> - an attribute name pattern; must match the attribute
+        name as it is declared in the database
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row is an
+         attribute description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsResultSetHoldability(int)"><!-- --></A><H3>
+supportsResultSetHoldability</H3>
+<PRE>
+public boolean <B>supportsResultSetHoldability</B>(int&nbsp;holdability)
+                                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports the given result set holdability.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB returns true for both alternatives. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsResultSetHoldability(int)" title="class or interface in java.sql">supportsResultSetHoldability</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>holdability</CODE> - one of the following constants:
+          <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+          <code>ResultSet.CLOSE_CURSORS_AT_COMMIT<code>
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><CODE>JDBCConnection</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSetHoldability()"><!-- --></A><H3>
+getResultSetHoldability</H3>
+<PRE>
+public int <B>getResultSetHoldability</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>(JDBC4 clarification:)
+ Retrieves this database's default holdability for <code>ResultSet</code>
+ objects.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB defaults to HOLD_CURSORS_OVER_COMMIT for CONSUR_READ_ONLY
+ ResultSet objects.
+ If the ResultSet concurrency is CONCUR_UPDATABLE, then holdability is
+ is enforced as CLOSE_CURSORS_AT_COMMIT. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getResultSetHoldability()" title="class or interface in java.sql">getResultSetHoldability</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the default holdability; either
+         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDatabaseMajorVersion()"><!-- --></A><H3>
+getDatabaseMajorVersion</H3>
+<PRE>
+public int <B>getDatabaseMajorVersion</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the major version number of the underlying database.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+ Returns the major version
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDatabaseMajorVersion()" title="class or interface in java.sql">getDatabaseMajorVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the underlying database's major version
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDatabaseMinorVersion()"><!-- --></A><H3>
+getDatabaseMinorVersion</H3>
+<PRE>
+public int <B>getDatabaseMinorVersion</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the minor version number of the underlying database.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ This returns the digit after the first point in version.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getDatabaseMinorVersion()" title="class or interface in java.sql">getDatabaseMinorVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>underlying database's minor version
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getJDBCMajorVersion()"><!-- --></A><H3>
+getJDBCMajorVersion</H3>
+<PRE>
+public int <B>getJDBCMajorVersion</B>()
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the major JDBC version number for this
+ driver.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getJDBCMajorVersion()" title="class or interface in java.sql">getJDBCMajorVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>JDBC version major number
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getJDBCMinorVersion()"><!-- --></A><H3>
+getJDBCMinorVersion</H3>
+<PRE>
+public int <B>getJDBCMinorVersion</B>()
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the minor JDBC version number for this
+ driver.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getJDBCMinorVersion()" title="class or interface in java.sql">getJDBCMinorVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>JDBC version minor number
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSQLStateType()"><!-- --></A><H3>
+getSQLStateType</H3>
+<PRE>
+public int <B>getSQLStateType</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>(JDBC4 modified:)
+ Indicates whether the SQLSTATE returned by <code>SQLException.getSQLState</code>
+ is X/Open (now known as Open Group) SQL CLI or SQL:2003.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB returns  <code>sqlStateSQL</code> under JDBC4 which is equivalent
+ to JDBC3 value of sqlStateSQL99. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSQLStateType()" title="class or interface in java.sql">getSQLStateType</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the type of SQLSTATE; one of:
+        sqlStateXOpen or
+        sqlStateSQL
+
+ <p>sqlStateSQL is new in JDBC4 and its value is the same as JDBC3 sqlStateSQL99
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="locatorsUpdateCopy()"><!-- --></A><H3>
+locatorsUpdateCopy</H3>
+<PRE>
+public boolean <B>locatorsUpdateCopy</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Indicates whether updates made to a LOB are made on a copy or directly
+ to the LOB.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Updates to a LOB are made directly.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#locatorsUpdateCopy()" title="class or interface in java.sql">locatorsUpdateCopy</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if updates are made to a copy of the LOB;
+         <code>false</code> if updates are made directly to the LOB
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsStatementPooling()"><!-- --></A><H3>
+supportsStatementPooling</H3>
+<PRE>
+public boolean <B>supportsStatementPooling</B>()
+                                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports statement pooling.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB supports statement pooling when built under
+ JDK 1.6+. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsStatementPooling()" title="class or interface in java.sql">supportsStatementPooling</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRowIdLifetime()"><!-- --></A><H3>
+getRowIdLifetime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowIdLifetime.html?is-external=true" title="class or interface in java.sql">RowIdLifetime</A> <B>getRowIdLifetime</B>()
+                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Indicates whether or not this data source supports the SQL <code>ROWID</code> type,
+ and if so  the lifetime for which a <code>RowId</code> object remains valid.
+ <p>
+ The returned int values have the following relationship:
+ <pre>
+     ROWID_UNSUPPORTED < ROWID_VALID_OTHER < ROWID_VALID_TRANSACTION
+         < ROWID_VALID_SESSION < ROWID_VALID_FOREVER
+ </pre>
+ so conditional logic such as
+ <pre>
+     if (metadata.getRowIdLifetime() > DatabaseMetaData.ROWID_VALID_TRANSACTION)
+ </pre>
+ can be used. Valid Forever means valid across all Sessions, and valid for
+ a Session means valid across all its contained Transactions.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getRowIdLifetime()" title="class or interface in java.sql">getRowIdLifetime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the status indicating the lifetime of a <code>RowId</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSchemas(java.lang.String, java.lang.String)"><!-- --></A><H3>
+getSchemas</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getSchemas</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the schema names available in this database.  The results
+ are ordered by schema name.
+
+ <P>The schema columns are:
+  <OL>
+  <LI><B>TABLE_SCHEM</B> String => schema name
+  <LI><B>TABLE_CATALOG</B> String => catalog name (may be <code>null</code>)
+  </OL>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getSchemas(java.lang.String, java.lang.String)" title="class or interface in java.sql">getSchemas</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it is stored
+ in the database;"" retrieves those without a catalog; null means catalog
+ name should not be used to narrow down the search.<DD><CODE>schemaPattern</CODE> - a schema name; must match the schema name as it is
+ stored in the database; null means
+ schema name should not be used to narrow down the search.
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object in which each row is a
+         schema description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="supportsStoredFunctionsUsingCallSyntax()"><!-- --></A><H3>
+supportsStoredFunctionsUsingCallSyntax</H3>
+<PRE>
+public boolean <B>supportsStoredFunctionsUsingCallSyntax</B>()
+                                               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this database supports invoking user-defined or vendor functions
+ using the stored procedure escape syntax.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsStoredFunctionsUsingCallSyntax()" title="class or interface in java.sql">supportsStoredFunctionsUsingCallSyntax</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="autoCommitFailureClosesAllResultSets()"><!-- --></A><H3>
+autoCommitFailureClosesAllResultSets</H3>
+<PRE>
+public boolean <B>autoCommitFailureClosesAllResultSets</B>()
+                                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether a <code>SQLException</code> while autoCommit is <code>true</code> inidcates
+ that all open ResultSets are closed, even ones that are holdable.  When a <code>SQLException</code> occurs while
+ autocommit is <code>true</code>, it is vendor specific whether the JDBC driver responds with a commit operation, a
+ rollback operation, or by doing neither a commit nor a rollback.  A potential result of this difference
+ is in whether or not holdable ResultSets are closed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#autoCommitFailureClosesAllResultSets()" title="class or interface in java.sql">autoCommitFailureClosesAllResultSets</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getClientInfoProperties()"><!-- --></A><H3>
+getClientInfoProperties</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getClientInfoProperties</B>()
+                                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a list of the client info properties
+ that the driver supports.  The result set contains the following columns
+ <p>
+ <ol>
+ <li><b>NAME</b> String=> The name of the client info property<br>
+ <li><b>MAX_LEN</b> int=> The maximum length of the value for the property<br>
+ <li><b>DEFAULT_VALUE</b> String=> The default value of the property<br>
+ <li><b>DESCRIPTION</b> String=> A description of the property.  This will typically
+                                                  contain information as to where this property is
+                                                  stored in the database.
+ </ol>
+ <p>
+ The <code>ResultSet</code> is sorted by the NAME column
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getClientInfoProperties()" title="class or interface in java.sql">getClientInfoProperties</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>A <code>ResultSet</code> object; each row is a supported client info
+ property
+ <p>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFunctions(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getFunctions</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getFunctions</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;functionNamePattern)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the user functions available in the given
+ catalog.
+ <P>
+ Only system and user function descriptions matching the schema and
+ function name criteria are returned.  They are ordered by
+ <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>,
+ <code>FUNCTION_NAME</code> and
+ <code>SPECIFIC_ NAME</code>.
+
+ <P>Each function description has the the following columns:
+  <OL>
+  <LI><B>FUNCTION_CAT</B> String => function catalog (may be <code>null</code>)
+  <LI><B>FUNCTION_SCHEM</B> String => function schema (may be <code>null</code>)
+  <LI><B>FUNCTION_NAME</B> String => function name.  This is the name
+ used to invoke the function
+  <LI><B>REMARKS</B> String => explanatory comment on the function
+ <LI><B>FUNCTION_TYPE</B> short => kind of function:
+      <UL>
+      <LI>functionResultUnknown - Cannot determine if a return value
+       or table will be returned
+      <LI> functionNoTable- Does not return a table
+      <LI> functionReturnsTable - Returns a table
+      </UL>
+  <LI><B>SPECIFIC_NAME</B> String  => the name which uniquely identifies
+  this function within its schema.  This is a user specified, or DBMS
+ generated, name that may be different then the <code>FUNCTION_NAME</code>
+ for example with overload functions
+  </OL>
+ <p>
+ A user may not have permission to execute any of the functions that are
+ returned by <code>getFunctions</code>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getFunctions(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getFunctions</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema name pattern; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>functionNamePattern</CODE> - a function name pattern; must match the
+        function name as it is stored in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row is a function description
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFunctionColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+getFunctionColumns</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getFunctionColumns</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;catalog,
+                                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;schemaPattern,
+                                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;functionNamePattern,
+                                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnNamePattern)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a description of the given catalog's system or user
+ function parameters and return type.
+
+ <P>Only descriptions matching the schema,  function and
+ parameter name criteria are returned. They are ordered by
+ <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>,
+ <code>FUNCTION_NAME</code> and
+ <code>SPECIFIC_ NAME</code>. Within this, the return value,
+ if any, is first. Next are the parameter descriptions in call
+ order. The column descriptions follow in column number order.
+
+ <P>Each row in the <code>ResultSet</code>
+ is a parameter description, column description or
+ return type description with the following fields:
+  <OL>
+  <LI><B>FUNCTION_CAT</B> String => function catalog (may be <code>null</code>)
+  <LI><B>FUNCTION_SCHEM</B> String => function schema (may be <code>null</code>)
+  <LI><B>FUNCTION_NAME</B> String => function name.  This is the name
+ used to invoke the function
+  <LI><B>COLUMN_NAME</B> String => column/parameter name
+  <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
+      <UL>
+      <LI> functionColumnUnknown - nobody knows
+      <LI> functionColumnIn - IN parameter
+      <LI> functionColumnInOut - INOUT parameter
+      <LI> functionColumnOut - OUT parameter
+      <LI> functionColumnReturn - function return value
+      <LI> functionColumnResult - Indicates that the parameter or column
+  is a column in the <code>ResultSet</code>
+      </UL>
+  <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
+  <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
+  type name is fully qualified
+  <LI><B>PRECISION</B> int => precision
+  <LI><B>LENGTH</B> int => length in bytes of data
+  <LI><B>SCALE</B> short => scale -  null is returned for data types where
+ SCALE is not applicable.
+  <LI><B>RADIX</B> short => radix
+  <LI><B>NULLABLE</B> short => can it contain NULL.
+      <UL>
+      <LI> functionNoNulls - does not allow NULL values
+      <LI> functionNullable - allows NULL values
+      <LI> functionNullableUnknown - nullability unknown
+      </UL>
+  <LI><B>REMARKS</B> String => comment describing column/parameter
+  <LI><B>CHAR_OCTET_LENGTH</B> int  => the maximum length of binary
+ and character based parameters or columns.  For any other datatype the returned value
+ is a NULL
+  <LI><B>ORDINAL_POSITION</B> int  => the ordinal position, starting
+ from 1, for the input and output parameters. A value of 0
+ is returned if this row describes the function's return value.
+ For result set columns, it is the
+ ordinal position of the column in the result set starting from 1.
+  <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine
+ the nullability for a parameter or column.
+       <UL>
+       <LI> YES           --- if the parameter or column can include NULLs
+       <LI> NO            --- if the parameter or column  cannot include NULLs
+       <LI> empty string  --- if the nullability for the
+ parameter  or column is unknown
+       </UL>
+  <LI><B>SPECIFIC_NAME</B> String  => the name which uniquely identifies
+ this function within its schema.  This is a user specified, or DBMS
+ generated, name that may be different then the <code>FUNCTION_NAME</code>
+ for example with overload functions
+  </OL>
+
+ <p>The PRECISION column represents the specified column size for the given
+ parameter or column.
+ For numeric data, this is the maximum precision.  For character data, this is the length in characters.
+ For datetime datatypes, this is the length in characters of the String representation (assuming the
+ maximum allowed precision of the fractional seconds component). For binary data, this is the length in bytes.  For the ROWID datatype,
+ this is the length in bytes. Null is returned for data types where the
+ column size is not applicable.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#getFunctionColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)" title="class or interface in java.sql">getFunctionColumns</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>catalog</CODE> - a catalog name; must match the catalog name as it
+        is stored in the database; "" retrieves those without a catalog;
+        <code>null</code> means that the catalog name should not be used to narrow
+        the search<DD><CODE>schemaPattern</CODE> - a schema name pattern; must match the schema name
+        as it is stored in the database; "" retrieves those without a schema;
+        <code>null</code> means that the schema name should not be used to narrow
+        the search<DD><CODE>functionNamePattern</CODE> - a procedure name pattern; must match the
+        function name as it is stored in the database<DD><CODE>columnNamePattern</CODE> - a parameter name pattern; must match the
+ parameter or column name as it is stored in the database
+<DT><B>Returns:</B><DD><code>ResultSet</code> - each row describes a
+ user function parameter, column  or return type
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#getSearchStringEscape()"><CODE>getSearchStringEscape()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap(java.lang.Class)"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public &lt;T&gt; T <B>unwrap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an object that implements the given interface to allow access to non-standard methods,
+ or standard methods not exposed by the proxy.
+ The result may be either the object found to implement the interface or a proxy for that object.
+ If the receiver implements the interface then that is the object. If the receiver is a wrapper
+ and the wrapped object implements the interface then that is the object. Otherwise the object is
+  the result of calling <code>unwrap</code> recursively on the wrapped object. If the receiver is not a
+ wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - A Class defining an interface that the result must implement.
+<DT><B>Returns:</B><DD>an object that implements the interface. May be a proxy for the actual implementing object.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - If no object found that implements the interface<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWrapperFor(java.lang.Class)"><!-- --></A><H3>
+isWrapperFor</H3>
+<PRE>
+public boolean <B>isWrapperFor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does. Returns false otherwise. If this implements the interface then return true,
+ else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+ object. If this does not implement the interface and is not a wrapper, return false.
+ This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+ callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+ returns true then calling <code>unwrap</code> with the same argument should succeed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - a Class defining an interface.
+<DT><B>Returns:</B><DD>true if this implements the interface or directly or indirectly wraps an object that does.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while determining whether this is a wrapper
+ for an object with the given interface.<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.9</DD>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCDatabaseMetaData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCDatabaseMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDatabaseMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCDriver.html b/doc/apidocs/org/hsqldb/jdbc/JDBCDriver.html
new file mode 100644
index 0000000..0ad284e
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCDriver.html
@@ -0,0 +1,650 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCDriver (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCDriver (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCDriver.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCDriver.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDriver.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCDriver</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCDriver</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCDriver</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A></DL>
+</PRE>
+
+<P>
+Provides the java.sql.Driver interface implementation required by
+ the JDBC specification. <p>
+
+  The Java SQL framework allows for multiple database drivers. <p>
+
+  The DriverManager will try to load as many drivers as it can find and
+  then for any given connection request, it will ask each driver in turn
+  to try to connect to the target URL. <p>
+
+  The application developer will normally not need to call any function of
+  the Driver directly. All required calls are made by the DriverManager. <p>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+  When the HSQL Database Engine Driver class is loaded, it creates an
+  instance of itself and register it with the DriverManager. This means
+  that a user can load and register the HSQL Database Engine driver by
+  calling:
+  <pre>
+  <code>Class.forName("org.hsqldb.jdbc.JDBCDriver")</code>
+  </pre>
+
+  For detailed information about how to obtain HSQLDB JDBC Connections,
+  please see <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><CODE>JDBCConnection</CODE></A>.<p>
+
+ <hr>
+
+ <b>JRE 1.1.x Notes:</b> <p>
+
+ In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ versions of JDBC depends on the JDK version used for compiling and building
+ HSQLDB.<p>
+
+ Since 1.7.0, it is possible to build the product so that
+ all JDBC 2 methods can be called while executing under the version 1.1.x
+ <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ However, in addition to this technique requiring explicit casts to the
+ org.hsqldb.jdbc.* classes, some of the method calls also require
+ <code>int</code> values that are defined only in the JDBC 2 or greater
+ version of the <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A> interface.  For this
+ reason, when the product is compiled under JDK 1.1.x, these values are
+ defined in <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A>. <p>
+
+ In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ to them in parameter specifications and return value comparisons,
+ respectively, as follows: <p>
+
+ <pre class="JavaCodeExample">
+ JDBCResultSet.FETCH_FORWARD
+ JDBCResultSet.TYPE_FORWARD_ONLY
+ JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ JDBCResultSet.CONCUR_READ_ONLY
+ // etc.
+ </pre>
+
+ However, please note that code written to use HSQLDB JDBC 2 features under
+ JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
+ also note that this feature is offered solely as a convenience to developers
+ who must work under JDK 1.1.x due to operating constraints, yet wish to
+ use some of the more advanced features available under the JDBC 2
+ specification. <p>
+
+ <hr>
+
+ <b>JDBC 4.0 notes:</b><p>
+
+ Starting with JDBC 4.0 (JDK 1.6), the <code>DriverManager</code> methods
+ <code>getConnection</code> and <code>getDrivers</code> have been
+ enhanced to support the Java Standard Edition Service Provider mechanism.
+ When built under a Java runtime that supports JDBC 4.0, HSQLDB distribution
+ jars containing the Driver implementation also include the file
+ <code>META-INF/services/java.sql.Driver</code>. This file contains the fully
+ qualified class name ('org.hsqldb.jdbc.JDBCDriver') of the HSQLDB implementation
+ of <code>java.sql.Driver</code>. <p>
+
+ Hence, under JDBC 4.0 or greater, applications no longer need to explictly
+ load the HSQLDB JDBC driver using <code>Class.forName()</code>. Of course,
+ existing programs which do load JDBC drivers using
+ <code>Class.forName()</code> will continue to work without modification. <p>
+
+ <hr>
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><CODE>JDBCConnection</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html#JDBCDriver()">JDBCDriver</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Default constructor</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html#acceptsURL(java.lang.String)">acceptsURL</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the driver thinks that it can open a connection to
+  the given URL.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html#connect(java.lang.String, java.util.Properties)">connect</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A>&nbsp;info)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Attempts to make a database connection to the given URL.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html#getConnection(java.lang.String, java.util.Properties)">getConnection</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A>&nbsp;info)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The static equivalent of the <code>connect(String,Properties)</code>
+ method.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html#getMajorVersion()">getMajorVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the driver's major version number.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html#getMinorVersion()">getMinorVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the driver's minor version number.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DriverPropertyInfo.html?is-external=true" title="class or interface in java.sql">DriverPropertyInfo</A>[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html#getPropertyInfo(java.lang.String, java.util.Properties)">getPropertyInfo</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A>&nbsp;info)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets information about the possible properties for this driver.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html#jdbcCompliant()">jdbcCompliant</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reports whether this driver is a genuine JDBC Compliant<sup><font
+ size=-2>TM</font></sup> driver.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCDriver()"><!-- --></A><H3>
+JDBCDriver</H3>
+<PRE>
+public <B>JDBCDriver</B>()</PRE>
+<DL>
+<DD>Default constructor
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="connect(java.lang.String, java.util.Properties)"><!-- --></A><H3>
+connect</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>connect</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A>&nbsp;info)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Attempts to make a database connection to the given URL.<p>
+
+ Returns "null" if this is the wrong kind of driver to connect to the
+ given URL.  This will be common, as when the JDBC driver manager is asked
+ to connect to a given URL it passes the URL to each loaded driver in
+ turn. <p>
+
+ <P>The driver throws an <code>SQLException</code> if it is the right
+ driver to connect to the given URL but has trouble connecting to
+ the database. <p>
+
+ <P>The <code>java.util.Properties</code> argument can be used to pass
+ arbitrary string tag/value pairs as connection arguments.
+ Normally at least "user" and "password" properties should be
+ included in the <code>Properties</code> object. <p>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+  For the HSQL Database Engine, at least "user" and
+  "password" properties should be included in the Properties.<p>
+
+  From version 1.7.1, two optional properties are supported:<p>
+
+  <ul>
+      <li><code>get_column_name</code> (default true) -  if set to false,
+          a ResultSetMetaData.getColumnName() call will return the user
+          defined label (getColumnLabel()) instead of the column
+          name.<br/>
+
+          This property is available in order to achieve
+          compatibility with certain non-HSQLDB JDBC driver
+          implementations.</li>
+
+      <li><code>strict_md</code> if set to true, some ResultSetMetaData
+          methods return more strict values for compatibility
+          reasons.</li>
+  </ul> <p>
+
+  From version 1.8.0.x, <code>strict_md</code> is deprecated (ignored)
+  because metadata reporting is always strict (JDBC-compliant), and
+  three new optional properties are supported: <p>
+
+  <ul>
+      <li><code>ifexits</code> (default false) - when true, an exception
+          is raised when attempting to connect to an in-process
+          file: or mem: scheme database instance if it has not yet been
+          created.  When false, an in-process file: or mem: scheme
+          database instance is created automatically if it has not yet
+          been created. This property does not apply to requests for
+          network or res: (i.e. files_in_jar) scheme connections. <li>
+
+      <li><code>shutdown</code> (default false) - when true, the
+          the target database mimics the behaviour of 1.7.1 and older
+          versions. When the last connection to a database is closed,
+          the database is automatically shut down. The property takes
+          effect only when the first connection is made to the database.
+          This means the connection that opens the database. It has no
+          effect if used with subsequent, simultaneous connections. <br/>
+
+          This command has two uses. One is for test suites, where
+          connections to the database are made from one JVM context,
+          immediately followed by another context. The other use is for
+          applications where it is not easy to configure the environment
+          to shutdown the database. Examples reported by users include
+          web application servers, where the closing of the last
+          connection conicides with the web app being shut down.</li>
+
+      <li><code>default_schema</code> - backwards compatibility feature.
+          To be used for clients written before HSQLDB schema support.
+          Denotes whether to use the default schema when a schema
+          qualifier is not included in a database object's SQL identifier
+          character sequence. Also affects the semantics of
+          DatabaseMetaData calls that supply null-valued schemaNamePattern
+          parameter values.</li>
+  </ul>
+
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true#connect(java.lang.String, java.util.Properties)" title="class or interface in java.sql">connect</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>url</CODE> - the URL of the database to which to connect<DD><CODE>info</CODE> - a list of arbitrary string tag/value pairs as connection
+      arguments. Normally at least a "user" and "password" property
+      should be included.
+<DT><B>Returns:</B><DD>a <code>Connection</code> object that represents a
+      connection to the URL
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConnection(java.lang.String, java.util.Properties)"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+                                       <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A>&nbsp;info)
+                                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>The static equivalent of the <code>connect(String,Properties)</code>
+ method. <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>url</CODE> - the URL of the database to which to connect<DD><CODE>info</CODE> - a list of arbitrary string tag/value pairs as connection
+      arguments including at least at a "user" and a "password" property
+<DT><B>Returns:</B><DD>a <code>Connection</code> object that represents a
+      connection to the URL
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="acceptsURL(java.lang.String)"><!-- --></A><H3>
+acceptsURL</H3>
+<PRE>
+public boolean <B>acceptsURL</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url)</PRE>
+<DL>
+<DD>Returns true if the driver thinks that it can open a connection to
+  the given URL. Typically drivers will return true if they understand
+  the subprotocol specified in the URL and false if they don't.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true#acceptsURL(java.lang.String)" title="class or interface in java.sql">acceptsURL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>url</CODE> - the URL of the database
+<DT><B>Returns:</B><DD>true if this driver can connect to the given URL</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getPropertyInfo(java.lang.String, java.util.Properties)"><!-- --></A><H3>
+getPropertyInfo</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DriverPropertyInfo.html?is-external=true" title="class or interface in java.sql">DriverPropertyInfo</A>[] <B>getPropertyInfo</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+                                            <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Properties.html?is-external=true" title="class or interface in java.util">Properties</A>&nbsp;info)</PRE>
+<DL>
+<DD>Gets information about the possible properties for this driver. <p>
+
+  The getPropertyInfo method is intended to allow a generic GUI tool
+  to discover what properties it should prompt a human for in order to
+  get enough information to connect to a database. Note that depending
+  on the values the human has supplied so far, additional values may
+  become necessary, so it may be necessary to iterate though several
+  calls to getPropertyInfo.<p>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB uses the values submitted in info to set the value for
+ each DriverPropertyInfo object returned. It does not use the default
+ value that it would use for the property if the value is null. <p>
+
+ </div> <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true#getPropertyInfo(java.lang.String, java.util.Properties)" title="class or interface in java.sql">getPropertyInfo</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>url</CODE> - the URL of the database to which to connect<DD><CODE>info</CODE> - a proposed list of tag/value pairs that will be sent on
+      connect open
+<DT><B>Returns:</B><DD>an array of DriverPropertyInfo objects describing possible
+      properties. This array may be an empty array if no properties
+      are required.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMajorVersion()"><!-- --></A><H3>
+getMajorVersion</H3>
+<PRE>
+public int <B>getMajorVersion</B>()</PRE>
+<DL>
+<DD>Gets the driver's major version number.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true#getMajorVersion()" title="class or interface in java.sql">getMajorVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>this driver's major version number</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMinorVersion()"><!-- --></A><H3>
+getMinorVersion</H3>
+<PRE>
+public int <B>getMinorVersion</B>()</PRE>
+<DL>
+<DD>Gets the driver's minor version number.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true#getMinorVersion()" title="class or interface in java.sql">getMinorVersion</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>this driver's minor version number</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="jdbcCompliant()"><!-- --></A><H3>
+jdbcCompliant</H3>
+<PRE>
+public boolean <B>jdbcCompliant</B>()</PRE>
+<DL>
+<DD>Reports whether this driver is a genuine JDBC Compliant<sup><font
+ size=-2>TM</font></sup> driver. A driver may only report
+ <code>true</code> here if it passes the JDBC compliance tests; otherwise
+ it is required to return <code>false</code>. <p>
+
+ JDBC compliance requires full support for the JDBC API and full support
+ for SQL 92 Entry Level. <p>
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+  HSQLDB 2.0 is aimed to be compliant with JDBC 4.0 specification.
+  It supports SQL 92 Entry Level and beyond.
+ </div> <!-- end release-specific documentation -->
+
+ This method is not intended to encourage the development of non-JDBC
+ compliant drivers, but is a recognition of the fact that some vendors
+ are interested in using the JDBC API and framework for lightweight
+ databases that do not support full database functionality, or for
+ special databases such as document information retrieval where a SQL
+ implementation may not be feasible.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true#jdbcCompliant()" title="class or interface in java.sql">jdbcCompliant</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if this driver is JDBC Compliant;
+         <code>false</code> otherwise</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCDriver.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCDriver.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDriver.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCNClob.html b/doc/apidocs/org/hsqldb/jdbc/JDBCNClob.html
new file mode 100644
index 0000000..4551ba5
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCNClob.html
@@ -0,0 +1,293 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCNClob (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCNClob (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCNClob.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCNClob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCNClob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_org.hsqldb.jdbc.JDBCClob">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCNClob</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">org.hsqldb.jdbc.JDBCClob</A>
+      <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCNClob</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCNClob</B><DT>extends <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A></DL>
+</PRE>
+
+<P>
+The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ for the SQL <code>NCLOB</code> type.
+ An SQL <code>NCLOB</code> is a built-in type
+ that stores a Character Large Object using the National Character Set
+  as a column value in a row of  a database table.
+ <P>The <code>NClob</code> interface extends the <code>Clob</code> interface
+ which provides provides methods for getting the
+ length of an SQL <code>NCLOB</code> value,
+ for materializing a <code>NCLOB</code> value on the client, and for
+ searching for a substring or <code>NCLOB</code> object within a
+ <code>NCLOB</code> value. A <code>NClob</code> object, just like a <code>Clob</code> object, is valid for the duration
+ of the transaction in which it was created.
+ Methods in the interfaces <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A>,
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql"><CODE>CallableStatement</CODE></A>, and <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql"><CODE>PreparedStatement</CODE></A>, such as
+ <code>getNClob</code> and <code>setNClob</code> allow a programmer to
+ access an SQL <code>NCLOB</code> value.  In addition, this interface
+ has methods for updating a <code>NCLOB</code> value.
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ First, it should be noted that since HSQLDB represents all character data
+ internally as Java UNICODE (UTF16) String objects, there is not currently any
+ appreciable difference between the HSQLDB XXXCHAR types and the SQL 2003
+ NXXXCHAR and NCLOB types. <p>
+
+ See <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><CODE>JDBCClob</CODE></A> for further information.
+
+ </div>
+ <!-- end Release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>boucherb@users</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><CODE>JDBCClob</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><CODE>JDBCClobClient</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCNClob.html#JDBCNClob(java.lang.String)">JDBCNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;data)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.hsqldb.jdbc.JDBCClob"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#free()">free</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getAsciiStream()">getAsciiStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getCharacterStream()">getCharacterStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getCharacterStream(long, long)">getCharacterStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#getSubString(long, int)">getSubString</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#length()">length</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#position(java.sql.Clob, long)">position</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#position(java.lang.String, long)">position</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setAsciiStream(long)">setAsciiStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setCharacterStream(long)">setCharacterStream</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setString(long, java.lang.String)">setString</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#setString(long, java.lang.String, int, int)">setString</A>, <A HREF="../../../org/hsqldb/jdbc/JDBCClob.html#truncate(long)">truncate</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.sql.Clob"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#free()" title="class or interface in java.sql">free</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getAsciiStream()" title="class or interface in java.sql">getAsciiStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getCharacterStream()" title="class or interface in java.sql">getCharacterStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getCharacterStream(long, long)" title="class or interface in java.sql">getCharacterStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#getSubString(long, int)" title="class or interface in java.sql">getSubString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#length()" title="class or interface in java.sql">length</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#position(java.sql.Clob, long)" title="class or interface in java.sql">position</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#position(java.lang.String, long)" title="class or interface in java.sql">position</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setAsciiStream(long)" title="class or interface in java.sql">setAsciiStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setCharacterStream(long)" title="class or interface in java.sql">setCharacterStream</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setString(long, java.lang.String)" title="class or interface in java.sql">setString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#setString(long, java.lang.String, int, int)" title="class or interface in java.sql">setString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true#truncate(long)" title="class or interface in java.sql">truncate</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCNClob(java.lang.String)"><!-- --></A><H3>
+JDBCNClob</H3>
+<PRE>
+public <B>JDBCNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;data)
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCNClob.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCNClob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCNClob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_org.hsqldb.jdbc.JDBCClob">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCParameterMetaData.html b/doc/apidocs/org/hsqldb/jdbc/JDBCParameterMetaData.html
new file mode 100644
index 0000000..0a9e0de
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCParameterMetaData.html
@@ -0,0 +1,647 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCParameterMetaData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCParameterMetaData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCParameterMetaData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCParameterMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCParameterMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCParameterMetaData</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCParameterMetaData</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCParameterMetaData</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DL>
+</PRE>
+
+<P>
+An object that can be used to get information about the types
+ and properties for each parameter marker in a
+ <code>PreparedStatement</code> object. (JDBC4 Clarification:) For some queries and driver
+ implementations, the data that would be returned by a <code>ParameterMetaData</code>
+ object may not be available until the <code>PreparedStatement</code> has
+ been executed.
+ <p>
+ Some driver implementations may not be able to provide information about the
+ types and properties for each parameter marker in a <code>CallableStatement</code>
+ object.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.sql.ParameterMetaData"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#parameterModeIn" title="class or interface in java.sql">parameterModeIn</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#parameterModeInOut" title="class or interface in java.sql">parameterModeInOut</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#parameterModeOut" title="class or interface in java.sql">parameterModeOut</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#parameterModeUnknown" title="class or interface in java.sql">parameterModeUnknown</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#parameterNoNulls" title="class or interface in java.sql">parameterNoNulls</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#parameterNullable" title="class or interface in java.sql">parameterNullable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#parameterNullableUnknown" title="class or interface in java.sql">parameterNullableUnknown</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterClassName(int)">getParameterClassName</A></B>(int&nbsp;param)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the fully-qualified name of the Java class whose instances
+ should be passed to the method <code>PreparedStatement.setObject</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterCount()">getParameterCount</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the number of parameters in the <code>PreparedStatement</code>
+ object for which this <code>ParameterMetaData</code> object contains
+ information.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterMode(int)">getParameterMode</A></B>(int&nbsp;param)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the designated parameter's mode.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterType(int)">getParameterType</A></B>(int&nbsp;param)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the designated parameter's SQL type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#getParameterTypeName(int)">getParameterTypeName</A></B>(int&nbsp;param)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the designated parameter's database-specific type name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#getPrecision(int)">getPrecision</A></B>(int&nbsp;param)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the designated parameter's specified column size.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#getScale(int)">getScale</A></B>(int&nbsp;param)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the designated parameter's number of digits to right of the decimal point.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#isNullable(int)">isNullable</A></B>(int&nbsp;param)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether null values are allowed in the designated parameter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#isSigned(int)">isSigned</A></B>(int&nbsp;param)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether values for the designated parameter can be signed numbers.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#isWrapperFor(java.lang.Class)">isWrapperFor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a String repsentation of this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T&gt; T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html#unwrap(java.lang.Class)">unwrap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getParameterCount()"><!-- --></A><H3>
+getParameterCount</H3>
+<PRE>
+public int <B>getParameterCount</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the number of parameters in the <code>PreparedStatement</code>
+ object for which this <code>ParameterMetaData</code> object contains
+ information.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#getParameterCount()" title="class or interface in java.sql">getParameterCount</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the number of parameters
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isNullable(int)"><!-- --></A><H3>
+isNullable</H3>
+<PRE>
+public int <B>isNullable</B>(int&nbsp;param)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether null values are allowed in the designated parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#isNullable(int)" title="class or interface in java.sql">isNullable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>param</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the nullability status of the given parameter; one of
+        <code>ParameterMetaData.parameterNoNulls</code>,
+        <code>ParameterMetaData.parameterNullable</code>, or
+        <code>ParameterMetaData.parameterNullableUnknown</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isSigned(int)"><!-- --></A><H3>
+isSigned</H3>
+<PRE>
+public boolean <B>isSigned</B>(int&nbsp;param)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether values for the designated parameter can be signed numbers.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#isSigned(int)" title="class or interface in java.sql">isSigned</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>param</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getPrecision(int)"><!-- --></A><H3>
+getPrecision</H3>
+<PRE>
+public int <B>getPrecision</B>(int&nbsp;param)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the designated parameter's specified column size.
+
+ <P>The returned value represents the maximum column size for the given parameter.
+ For numeric data, this is the maximum precision.  For character data, this is the length in characters.
+ For datetime datatypes, this is the length in characters of the String representation (assuming the
+ maximum allowed precision of the fractional seconds component). For binary data, this is the length in bytes.  For the ROWID datatype,
+ this is the length in bytes. 0 is returned for data types where the
+ column size is not applicable.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#getPrecision(int)" title="class or interface in java.sql">getPrecision</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>param</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>precision
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getScale(int)"><!-- --></A><H3>
+getScale</H3>
+<PRE>
+public int <B>getScale</B>(int&nbsp;param)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the designated parameter's number of digits to right of the decimal point.
+ 0 is returned for data types where the scale is not applicable.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#getScale(int)" title="class or interface in java.sql">getScale</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>param</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>scale
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParameterType(int)"><!-- --></A><H3>
+getParameterType</H3>
+<PRE>
+public int <B>getParameterType</B>(int&nbsp;param)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the designated parameter's SQL type.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#getParameterType(int)" title="class or interface in java.sql">getParameterType</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>param</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>SQL type from <code>java.sql.Types</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParameterTypeName(int)"><!-- --></A><H3>
+getParameterTypeName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getParameterTypeName</B>(int&nbsp;param)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the designated parameter's database-specific type name.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#getParameterTypeName(int)" title="class or interface in java.sql">getParameterTypeName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>param</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>type the name used by the database. If the parameter type is
+ a user-defined type, then a fully-qualified type name is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParameterClassName(int)"><!-- --></A><H3>
+getParameterClassName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getParameterClassName</B>(int&nbsp;param)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the fully-qualified name of the Java class whose instances
+ should be passed to the method <code>PreparedStatement.setObject</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#getParameterClassName(int)" title="class or interface in java.sql">getParameterClassName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>param</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the fully-qualified name of the class in the Java programming
+         language that would be used by the method
+         <code>PreparedStatement.setObject</code> to set the value
+         in the specified parameter. This is the class name used
+         for custom mapping.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParameterMode(int)"><!-- --></A><H3>
+getParameterMode</H3>
+<PRE>
+public int <B>getParameterMode</B>(int&nbsp;param)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the designated parameter's mode.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true#getParameterMode(int)" title="class or interface in java.sql">getParameterMode</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>param</CODE> - the first parameter is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>mode of the parameter; one of
+        <code>ParameterMetaData.parameterModeIn</code>,
+        <code>ParameterMetaData.parameterModeOut</code>, or
+        <code>ParameterMetaData.parameterModeInOut</code>
+        <code>ParameterMetaData.parameterModeUnknown</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap(java.lang.Class)"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public &lt;T&gt; T <B>unwrap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+
+ If the receiver implements the interface then the result is the receiver
+ or a proxy for the receiver. If the receiver is a wrapper
+ and the wrapped object implements the interface then the result is the
+ wrapped object or a proxy for the wrapped object. Otherwise return the
+ the result of calling <code>unwrap</code> recursively on the wrapped object
+ or a proxy for that result. If the receiver is not a
+ wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - A Class defining an interface that the result must implement.
+<DT><B>Returns:</B><DD>an object that implements the interface. May be a proxy for the actual implementing object.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - If no object found that implements the interface<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWrapperFor(java.lang.Class)"><!-- --></A><H3>
+isWrapperFor</H3>
+<PRE>
+public boolean <B>isWrapperFor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does. Returns false otherwise. If this implements the interface then return true,
+ else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+ object. If this does not implement the interface and is not a wrapper, return false.
+ This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+ callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+ returns true then calling <code>unwrap</code> with the same argument should succeed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - a Class defining an interface.
+<DT><B>Returns:</B><DD>true if this implements the interface or directly or indirectly wraps an object that does.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while determining whether this is a wrapper
+ for an object with the given interface.<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>toString</B>()</PRE>
+<DL>
+<DD>Retrieves a String repsentation of this object. <p>
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a String repsentation of this object</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCParameterMetaData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCParameterMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCParameterMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html b/doc/apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html
new file mode 100644
index 0000000..6922a59
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html
@@ -0,0 +1,4909 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCPreparedStatement (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCPreparedStatement (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCPreparedStatement.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCPreparedStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCPreparedStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCPreparedStatement</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCPreparedStatement</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCPreparedStatement</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></DL>
+</PRE>
+
+<P>
+<!-- start generic documentation -->
+
+ An object that represents a precompiled SQL statement.
+ <P>A SQL statement is precompiled and stored in a
+ <code>PreparedStatement</code> object. This object can then be used to
+ efficiently execute this statement multiple times.
+
+ <P><B>Note:</B> The setter methods (<code>setShort</code>, <code>setString</code>,
+ and so on) for setting IN parameter values
+ must specify types that are compatible with the defined SQL type of
+ the input parameter. For instance, if the IN parameter has SQL type
+ <code>INTEGER</code>, then the method <code>setInt</code> should be used.
+
+ <p>If arbitrary parameter type conversions are required, the method
+ <code>setObject</code> should be used with a target SQL type.
+ <P>
+ In the following example of setting a parameter, <code>con</code> represents
+ an active connection:
+ <PRE>
+   PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
+                                     SET SALARY = ? WHERE ID = ?");
+   pstmt.setBigDecimal(1, 153833.00)
+   pstmt.setInt(2, 110592)
+ </PRE>
+
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From version 2.0, the implementation meets the JDBC specification
+ requirment that any existing ResultSet is closed when execute() or
+ executeQuery() methods are called.
+ <p>
+ JDBCPreparedStatement objects are backed by
+ a true compiled parameteric representation. Hence, there are now significant
+ performance gains to be had by using a JDBCPreparedStatement object in
+ preference to a JDBCStatement object when a short-running SQL statement is
+ to be executed more than once. <p>
+
+ When it can be otherwise avoided, it should be considered poor practice to
+ fully prepare (construct), parameterize, execute, fetch and close a
+ JDBCParameterMetaData object for each execution cycle. Indeed,
+ because the prepare and execute phases
+ both represent a round-trip to the engine, this practice is likely to be
+ noticably <em>less</em> performant for short-running statements (and
+ possibly even orders of magnitude less performant over network connections
+ for short-running statements) than the equivalent process using JDBCStatement
+ objects, albeit far more convenient, less error prone and certainly much
+ less resource-intensive, especially when large binary and character values
+ are involved, due to the optimized parameterization facility. <p>
+
+ Instead, when developing an application that is not totally oriented toward
+ the execution of ad hoc SQL, it is recommended to expend some effort toward
+ identifing the SQL statements that are good candidates for regular reuse and
+ adapting the structure of the application accordingly. Often, this is done
+ by recording the text of candidate SQL statements in an application resource
+ object (which has the nice side-benefit of isolating and hiding differences
+ in SQL dialects across different drivers) and caching for possible reuse the
+ PreparedStatement objects derived from the recorded text. <p>
+
+ Starting with 2.0, when built under a JDBC 4 environment, statement caching
+ can be transparently enabled or disabled on a statement-by-statement basis by
+ invoking setPoolable(true | false), respectively, upon Statement objects of
+ interest. <p>
+
+ <b>Multi thread use:</b> <p>
+
+ A PreparedStatement object is stateful and should not normally be shared
+ by multiple threads. If it has to be shared, the calls to set the
+ parameters, calls to add batch statements, the execute call and any
+ post-execute calls should be made within a block synchronized on the
+ PreparedStatement Object.<p>
+
+ <b>JRE 1.1.x Notes:</b> <p>
+
+ In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ versions of JDBC depends on the JDK version used for compiling and building
+ HSQLDB.<p>
+
+ Since 1.7.0, all JDBC 2 methods can be called while executing under the
+ version 1.1.x
+ <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ However, in addition to this technique requiring explicit casts to the
+ org.hsqldb.jdbc.* classes, some of these method calls require
+ <code>int</code> values that are defined only in the JDBC 2 or greater
+ version of the <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A> interface.  For this
+ reason these values are defined in <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A>.<p>
+
+ In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ to them in parameter specifications and return value comparisons,
+ respectively, as follows: <p>
+
+ <pre class="JavaCodeExample">
+ JDBCResultSet.FETCH_FORWARD
+ JDBCResultSet.TYPE_FORWARD_ONLY
+ JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ JDBCResultSet.CONCUR_READ_ONLY
+ //etc.
+ </pre> <p>
+
+ However, please note that code written to use HSQLDB JDBC 2 features under
+ JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
+ also note that this feature is offered solely as a convenience to developers
+ who must work under JDK 1.1.x due to operating constraints, yet wish to
+ use some of the more advanced features available under the JDBC 2
+ specification. <p>
+
+ (fredt@users)<br>
+ (boucherb@users)<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#prepareStatement(java.lang.String)"><CODE>JDBCConnection.prepareStatement(java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.sql.Statement"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#CLOSE_ALL_RESULTS" title="class or interface in java.sql">CLOSE_ALL_RESULTS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#CLOSE_CURRENT_RESULT" title="class or interface in java.sql">CLOSE_CURRENT_RESULT</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#EXECUTE_FAILED" title="class or interface in java.sql">EXECUTE_FAILED</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#KEEP_CURRENT_RESULT" title="class or interface in java.sql">KEEP_CURRENT_RESULT</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#NO_GENERATED_KEYS" title="class or interface in java.sql">NO_GENERATED_KEYS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#RETURN_GENERATED_KEYS" title="class or interface in java.sql">RETURN_GENERATED_KEYS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#SUCCESS_NO_INFO" title="class or interface in java.sql">SUCCESS_NO_INFO</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#addBatch()">addBatch</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Adds a set of parameters to this <code>PreparedStatement</code>
+ object's batch of commands.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#addBatch(java.lang.String)">addBatch</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method should always throw if called for a PreparedStatement or
+ CallableStatment.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#cancel()">cancel</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cancels this <code>Statement</code> object if both the DBMS and
+ driver support aborting an SQL statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#clearBatch()">clearBatch</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Empties this <code>Statement</code> object's current list of
+ SQL commands.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#clearParameters()">clearParameters</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clears the current parameter values immediately.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#clearWarnings()">clearWarnings</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clears all the warnings reported on this <code>Statement</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#close()">close</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Does the specialized work required to free this object's resources and
+ that of it's parent class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute()">execute</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the SQL statement in this <code>PreparedStatement</code> object,
+ which may be any kind of SQL statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String)">execute</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method should always throw if called for a PreparedStatement or
+ CallableStatment.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, int)">execute</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+        int&nbsp;autoGeneratedKeys)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, int[])">execute</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+        int[]&nbsp;columnIndexes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute(java.lang.String, java.lang.String[])">execute</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeBatch()">executeBatch</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Submits a batch of commands to the database for execution and
+ if all commands execute successfully, returns an array of update counts.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeQuery()">executeQuery</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the SQL query in this <code>PreparedStatement</code> object
+ and returns the <code>ResultSet</code> object generated by the query.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeQuery(java.lang.String)">executeQuery</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method should always throw if called for a PreparedStatement or
+ CallableStatment.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate()">executeUpdate</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the SQL statement in this <code>PreparedStatement</code> object,
+ (JDBC4 clarification:)
+ which must be an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+ <code>DELETE</code>; or an SQL statement that returns nothing,
+ such as a DDL statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String)">executeUpdate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method should always throw if called for a PreparedStatement or
+ CallableStatment.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, int)">executeUpdate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+              int&nbsp;autoGeneratedKeys)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Statement methods that must be overridden in this class and throw
+ an exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, int[])">executeUpdate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+              int[]&nbsp;columnIndexes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#executeUpdate(java.lang.String, java.lang.String[])">executeUpdate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getConnection()">getConnection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>Connection</code> object
+ that produced this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getFetchDirection()">getFetchDirection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the direction for fetching rows from
+ database tables that is the default for result sets
+ generated from this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getFetchSize()">getFetchSize</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the number of result set rows that is the default
+ fetch size for <code>ResultSet</code> objects
+ generated from this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getGeneratedKeys()">getGeneratedKeys</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves any auto-generated keys created as a result of executing this
+ <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMaxFieldSize()">getMaxFieldSize</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of bytes that can be
+ returned for character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMaxRows()">getMaxRows</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of rows that a
+ <code>ResultSet</code> object produced by this
+ <code>Statement</code> object can contain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMetaData()">getMetaData</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a <code>ResultSetMetaData</code> object that contains
+ information about the columns of the <code>ResultSet</code> object
+ that will be returned when this <code>PreparedStatement</code> object
+ is executed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMoreResults()">getMoreResults</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves to this <code>Statement</code> object's next result, returns
+ <code>true</code> if it is a <code>ResultSet</code> object, and
+ implicitly closes any current <code>ResultSet</code>
+ object(s) obtained with the method <code>getResultSet</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMoreResults(int)">getMoreResults</A></B>(int&nbsp;current)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves to this <code>Statement</code> object's next result, deals with
+ any current <code>ResultSet</code> object(s) according  to the instructions
+ specified by the given flag, and returns
+ <code>true</code> if the next result is a <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getParameterMetaData()">getParameterMetaData</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the number, types and properties of this
+ <code>PreparedStatement</code> object's parameters.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getQueryTimeout()">getQueryTimeout</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the number of seconds the driver will
+ wait for a <code>Statement</code> object to execute.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSet()">getResultSet</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the current result as a <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetConcurrency()">getResultSetConcurrency</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the result set concurrency for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetHoldability()">getResultSetHoldability</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the result set holdability for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getResultSetType()">getResultSetType</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the result set type for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getUpdateCount()">getUpdateCount</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the current result as an update count;
+  if the result is a <code>ResultSet</code> object or there are no more results, -1
+  is returned.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getWarnings()">getWarnings</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the first warning reported by calls on this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#isClosed()">isClosed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this <code>Statement</code> object has been closed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#isPoolable()">isPoolable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a  value indicating whether the <code>Statement</code>
+ is poolable or not.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#isWrapperFor(java.lang.Class)">isWrapperFor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setArray(int, java.sql.Array)">setArray</A></B>(int&nbsp;parameterIndex,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Array</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream)">setAsciiStream</A></B>(int&nbsp;parameterIndex,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream, int)">setAsciiStream</A></B>(int&nbsp;parameterIndex,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+               int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setAsciiStream(int, java.io.InputStream, long)">setAsciiStream</A></B>(int&nbsp;parameterIndex,
+               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+               long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBigDecimal(int, java.math.BigDecimal)">setBigDecimal</A></B>(int&nbsp;parameterIndex,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.math.BigDecimal</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream)">setBinaryStream</A></B>(int&nbsp;parameterIndex,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream, int)">setBinaryStream</A></B>(int&nbsp;parameterIndex,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBinaryStream(int, java.io.InputStream, long)">setBinaryStream</A></B>(int&nbsp;parameterIndex,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.sql.Blob)">setBlob</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Blob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.io.InputStream)">setBlob</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>InputStream</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBlob(int, java.io.InputStream, long)">setBlob</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream,
+        long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>InputStream</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBoolean(int, boolean)">setBoolean</A></B>(int&nbsp;parameterIndex,
+           boolean&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>boolean</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setByte(int, byte)">setByte</A></B>(int&nbsp;parameterIndex,
+        byte&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>byte</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setBytes(int, byte[])">setBytes</A></B>(int&nbsp;parameterIndex,
+         byte[]&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java array of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader)">setCharacterStream</A></B>(int&nbsp;parameterIndex,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>Reader</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader, int)">setCharacterStream</A></B>(int&nbsp;parameterIndex,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                   int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setCharacterStream(int, java.io.Reader, long)">setCharacterStream</A></B>(int&nbsp;parameterIndex,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                   long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.sql.Clob)">setClob</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Clob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.io.Reader)">setClob</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setClob(int, java.io.Reader, long)">setClob</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+        long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setCursorName(java.lang.String)">setCursorName</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the SQL cursor name to the given <code>String</code>, which
+ will be used by subsequent <code>Statement</code> object
+ <code>execute</code> methods.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setDate(int, java.sql.Date)">setDate</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Sets the designated parameter to the given <code>java.sql.Date</code> value
+ using the default time zone of the virtual machine that is running
+ the application.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setDate(int, java.sql.Date, java.util.Calendar)">setDate</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Date</code> value,
+ using the given <code>Calendar</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setDouble(int, double)">setDouble</A></B>(int&nbsp;parameterIndex,
+          double&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>double</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setEscapeProcessing(boolean)">setEscapeProcessing</A></B>(boolean&nbsp;enable)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets escape processing on or off.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setFetchDirection(int)">setFetchDirection</A></B>(int&nbsp;direction)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gives the driver a hint as to the direction in which
+ rows will be processed in <code>ResultSet</code>
+ objects created using this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setFetchSize(int)">setFetchSize</A></B>(int&nbsp;rows)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for
+ <code>ResultSet</code> objects genrated by this <code>Statement</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setFloat(int, float)">setFloat</A></B>(int&nbsp;parameterIndex,
+         float&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>float</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setInt(int, int)">setInt</A></B>(int&nbsp;parameterIndex,
+       int&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>int</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setLong(int, long)">setLong</A></B>(int&nbsp;parameterIndex,
+        long&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>long</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setMaxFieldSize(int)">setMaxFieldSize</A></B>(int&nbsp;max)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:) Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
+ Sets the limit for the maximum number of bytes that can be returned for
+ character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setMaxRows(int)">setMaxRows</A></B>(int&nbsp;max)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Sets the limit for the maximum number of rows that any
+ <code>ResultSet</code> object  generated by this <code>Statement</code>
+ object can contain to the given number.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNCharacterStream(int, java.io.Reader)">setNCharacterStream</A></B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNCharacterStream(int, java.io.Reader, long)">setNCharacterStream</A></B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;value,
+                    long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.sql.NClob)">setNClob</A></B>(int&nbsp;parameterIndex,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>java.sql.NClob</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.io.Reader)">setNClob</A></B>(int&nbsp;parameterIndex,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNClob(int, java.io.Reader, long)">setNClob</A></B>(int&nbsp;parameterIndex,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+         long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to a <code>Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNString(int, java.lang.String)">setNString</A></B>(int&nbsp;parameterIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated paramter to the given <code>String</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNull(int, int)">setNull</A></B>(int&nbsp;parameterIndex,
+        int&nbsp;sqlType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to SQL <code>NULL</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setNull(int, int, java.lang.String)">setNull</A></B>(int&nbsp;parameterIndex,
+        int&nbsp;sqlType,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to SQL <code>NULL</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object)">setObject</A></B>(int&nbsp;parameterIndex,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object, int)">setObject</A></B>(int&nbsp;parameterIndex,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+          int&nbsp;targetSqlType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the designated parameter with the given object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object, int, int)">setObject</A></B>(int&nbsp;parameterIndex,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+          int&nbsp;targetSqlType,
+          int&nbsp;scaleOrLength)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the designated parameter with the given object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setPoolable(boolean)">setPoolable</A></B>(boolean&nbsp;poolable)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Requests that a <code>Statement</code> be pooled or not pooled.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setQueryTimeout(int)">setQueryTimeout</A></B>(int&nbsp;seconds)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the number of seconds the driver will wait for a
+ <code>Statement</code> object to execute to the given number of seconds.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setRef(int, java.sql.Ref)">setRef</A></B>(int&nbsp;parameterIndex,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given
+  <code>REF(&lt;structured-type&gt;)</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setRowId(int, java.sql.RowId)">setRowId</A></B>(int&nbsp;parameterIndex,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.RowId</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setShort(int, short)">setShort</A></B>(int&nbsp;parameterIndex,
+         short&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>short</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setSQLXML(int, java.sql.SQLXML)">setSQLXML</A></B>(int&nbsp;parameterIndex,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>&nbsp;xmlObject)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.SQLXML</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setString(int, java.lang.String)">setString</A></B>(int&nbsp;parameterIndex,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given Java <code>String</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setTime(int, java.sql.Time)">setTime</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Time</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setTime(int, java.sql.Time, java.util.Calendar)">setTime</A></B>(int&nbsp;parameterIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Time</code> value,
+ using the given <code>Calendar</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setTimestamp(int, java.sql.Timestamp)">setTimestamp</A></B>(int&nbsp;parameterIndex,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setTimestamp(int, java.sql.Timestamp, java.util.Calendar)">setTimestamp</A></B>(int&nbsp;parameterIndex,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
+ using the given <code>Calendar</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setUnicodeStream(int, java.io.InputStream, int)">setUnicodeStream</A></B>(int&nbsp;parameterIndex,
+                 <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                 int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Sun does not include a reason, but presumably
+      this is because setCharacterStream is now prefered</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setURL(int, java.net.URL)">setURL</A></B>(int&nbsp;parameterIndex,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the designated parameter to the given <code>java.net.URL</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a String representation of this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T&gt; T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#unwrap(java.lang.Class)">unwrap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="executeQuery()"><!-- --></A><H3>
+executeQuery</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>executeQuery</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the SQL query in this <code>PreparedStatement</code> object
+ and returns the <code>ResultSet</code> object generated by the query.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#executeQuery()" title="class or interface in java.sql">executeQuery</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object that contains the data produced by the
+         query; never <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed  <code>PreparedStatement</code> or the SQL
+            statement does not return a <code>ResultSet</code> object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate()"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>()
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the SQL statement in this <code>PreparedStatement</code> object,
+ (JDBC4 clarification:)
+ which must be an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+ <code>DELETE</code>; or an SQL statement that returns nothing,
+ such as a DDL statement.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#executeUpdate()" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>(JDBC4 clarification:) either (1) the row count for SQL Data Manipulation Language (DML) statements
+         or (2) 0 for SQL statements that return nothing
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed  <code>PreparedStatement</code>
+ or the SQL
+            statement returns a <code>ResultSet</code> object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNull(int, int)"><!-- --></A><H3>
+setNull</H3>
+<PRE>
+public void <B>setNull</B>(int&nbsp;parameterIndex,
+                    int&nbsp;sqlType)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to SQL <code>NULL</code>.
+
+ <P><B>Note:</B> You must specify the parameter's SQL type.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB currently ignores the sqlType argument.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNull(int, int)" title="class or interface in java.sql">setNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>sqlType</CODE> - the SQL type code defined in <code>java.sql.Types</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>sqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBoolean(int, boolean)"><!-- --></A><H3>
+setBoolean</H3>
+<PRE>
+public void <B>setBoolean</B>(int&nbsp;parameterIndex,
+                       boolean&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java <code>boolean</code> value.
+ The driver converts this
+ (JDBC4 Modified:)
+ to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports BOOLEAN type for boolean values. This method can also
+ be used to set the value of a parameter of the SQL type BIT(1), which is
+ a bit string consisting of a 0 or 1.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBoolean(int, boolean)" title="class or interface in java.sql">setBoolean</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setByte(int, byte)"><!-- --></A><H3>
+setByte</H3>
+<PRE>
+public void <B>setByte</B>(int&nbsp;parameterIndex,
+                    byte&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java <code>byte</code> value.
+ The driver converts this
+ to an SQL <code>TINYINT</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setByte(int, byte)" title="class or interface in java.sql">setByte</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setShort(int, short)"><!-- --></A><H3>
+setShort</H3>
+<PRE>
+public void <B>setShort</B>(int&nbsp;parameterIndex,
+                     short&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java <code>short</code> value.
+ The driver converts this
+ to an SQL <code>SMALLINT</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setShort(int, short)" title="class or interface in java.sql">setShort</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInt(int, int)"><!-- --></A><H3>
+setInt</H3>
+<PRE>
+public void <B>setInt</B>(int&nbsp;parameterIndex,
+                   int&nbsp;x)
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java <code>int</code> value.
+ The driver converts this
+ to an SQL <code>INTEGER</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setInt(int, int)" title="class or interface in java.sql">setInt</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLong(int, long)"><!-- --></A><H3>
+setLong</H3>
+<PRE>
+public void <B>setLong</B>(int&nbsp;parameterIndex,
+                    long&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java <code>long</code> value.
+ The driver converts this
+ to an SQL <code>BIGINT</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setLong(int, long)" title="class or interface in java.sql">setLong</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFloat(int, float)"><!-- --></A><H3>
+setFloat</H3>
+<PRE>
+public void <B>setFloat</B>(int&nbsp;parameterIndex,
+                     float&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java <code>float</code> value.
+ The driver converts this
+ (JDBC4 correction:)
+ to an SQL <code>REAL</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.1, HSQLDB handles Java positive/negative Infinity
+ and NaN <code>float</code> values consistent with the Java Language
+ Specification; these <em>special</em> values are now correctly stored
+ to and retrieved from the database.
+ </div>
+ <!-- start release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setFloat(int, float)" title="class or interface in java.sql">setFloat</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDouble(int, double)"><!-- --></A><H3>
+setDouble</H3>
+<PRE>
+public void <B>setDouble</B>(int&nbsp;parameterIndex,
+                      double&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java <code>double</code> value.
+ The driver converts this
+ to an SQL <code>DOUBLE</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.1, HSQLDB handles Java positive/negative Infinity
+ and NaN <code>double</code> values consistent with the Java Language
+ Specification; these <em>special</em> values are now correctly stored
+ to and retrieved from the database.
+ </div>
+ <!-- start release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setDouble(int, double)" title="class or interface in java.sql">setDouble</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBigDecimal(int, java.math.BigDecimal)"><!-- --></A><H3>
+setBigDecimal</H3>
+<PRE>
+public void <B>setBigDecimal</B>(int&nbsp;parameterIndex,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A>&nbsp;x)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.math.BigDecimal</code> value.
+ The driver converts this to an SQL <code>NUMERIC</code> value when
+ it sends it to the database.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBigDecimal(int, java.math.BigDecimal)" title="class or interface in java.sql">setBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setString(int, java.lang.String)"><!-- --></A><H3>
+setString</H3>
+<PRE>
+public void <B>setString</B>(int&nbsp;parameterIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java <code>String</code> value.
+ The driver converts this
+ to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
+ (depending on the argument's
+ size relative to the driver's limits on <code>VARCHAR</code> values)
+ when it sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, HSQLDB represents all XXXCHAR values internally as
+ java.lang.String objects; there is no appreciable difference between
+ CHAR, VARCHAR and LONGVARCHAR.
+ </div>
+ <!-- start release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setString(int, java.lang.String)" title="class or interface in java.sql">setString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBytes(int, byte[])"><!-- --></A><H3>
+setBytes</H3>
+<PRE>
+public void <B>setBytes</B>(int&nbsp;parameterIndex,
+                     byte[]&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given Java array of bytes.  The driver converts
+ this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
+ (depending on the argument's size relative to the driver's limits on
+ <code>VARBINARY</code> values) when it sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, HSQLDB represents all XXXBINARY values the same way
+ internally; there is no appreciable difference between BINARY,
+ VARBINARY and LONGVARBINARY as far as JDBC is concerned.
+ </div>
+ <!-- start release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBytes(int, byte[])" title="class or interface in java.sql">setBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDate(int, java.sql.Date)"><!-- --></A><H3>
+setDate</H3>
+<PRE>
+public void <B>setDate</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Sets the designated parameter to the given <code>java.sql.Date</code> value
+ using the default time zone of the virtual machine that is running
+ the application.
+ The driver converts this
+ to an SQL <code>DATE</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ When a setXXX method is used to set a parameter of type
+ TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone of the
+ client application is used as time zone
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setDate(int, java.sql.Date)" title="class or interface in java.sql">setDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTime(int, java.sql.Time)"><!-- --></A><H3>
+setTime</H3>
+<PRE>
+public void <B>setTime</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.sql.Time</code> value.
+ The driver converts this
+ to an SQL <code>TIME</code> value when it sends it to the database.
+ <!-- end generic documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ When a setXXX method is used to set a parameter of type
+ TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone of the
+ client application is used as time zone
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setTime(int, java.sql.Time)" title="class or interface in java.sql">setTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTimestamp(int, java.sql.Timestamp)"><!-- --></A><H3>
+setTimestamp</H3>
+<PRE>
+public void <B>setTimestamp</B>(int&nbsp;parameterIndex,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
+ The driver
+ converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the
+ database.
+ <!-- end generic documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ When a setXXX method is used to set a parameter of type
+ TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone of the
+ client application is used as time zone.<p>
+
+ When this method is used to set a parameter of type TIME or
+ TIME WITH TIME ZONE, then the nanosecond value of the Timestamp object
+ will be used if the TIME parameter accpets fractional seconds.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setTimestamp(int, java.sql.Timestamp)" title="class or interface in java.sql">setTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAsciiStream(int, java.io.InputStream, int)"><!-- --></A><H3>
+setAsciiStream</H3>
+<PRE>
+public void <B>setAsciiStream</B>(int&nbsp;parameterIndex,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                           int&nbsp;length)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+ When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code>. Data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from ASCII to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From HSQLDB 2.0 this method uses the US-ASCII character encoding to convert bytes
+ from the stream into the characters of a String.<p>
+ This method does not use streaming to send the data,
+ whether the target is a CLOB or other binary object.<p>
+
+ For long streams (larger than a few megabytes) with CLOB targets,
+ it is more efficient to use a version of setCharacterStream which takes
+ the a length parameter.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setAsciiStream(int, java.io.InputStream, int)" title="class or interface in java.sql">setAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the Java input stream that contains the ASCII parameter value<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setUnicodeStream(int, java.io.InputStream, int)"><!-- --></A><H3>
+setUnicodeStream</H3>
+<PRE>
+public void <B>setUnicodeStream</B>(int&nbsp;parameterIndex,
+                             <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                             int&nbsp;length)
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Sun does not include a reason, but presumably
+      this is because setCharacterStream is now prefered</I>
+<P>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given input stream, which
+ will have the specified number of bytes.
+ (JDBC4 deleted:)
+ [A Unicode character has two bytes, with the first byte being the high
+ byte, and the second being the low byte.] <p>
+
+ When a very large Unicode value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code> object. The data will be read from the
+ stream as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from Unicode to the database char format.
+
+ (JDBC4 added:)
+ The byte format of the Unicode stream must be a Java UTF-8, as defined in the
+ Java Virtual Machine Specification.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 1.7.0 to 1.8.0.x, this method complies with behavior as defined by
+ the JDBC3 specification (the stream is treated as though it has UTF16
+ encoding). <p>
+
+ Starting with 2.0, this method behaves according to the JDBC4
+ specification (the stream is treated as though it has UTF-8
+ encoding, as defined in the Java Virtual Machine Specification) when
+ built under JDK 1.6+; otherwise, it behaves as defined by the JDBC3
+ specification.  Regardless, this method is deprecated: please use
+ setCharacterStream(...) instead.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setUnicodeStream(int, java.io.InputStream, int)" title="class or interface in java.sql">setUnicodeStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - a <code>java.io.InputStream</code> object that contains the
+        Unicode parameter value
+ (JDBC4 deleted:)
+       [as two-byte Unicode characters]<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream(int, java.io.InputStream, int)"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public void <B>setBinaryStream</B>(int&nbsp;parameterIndex,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                            int&nbsp;length)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+ When a very large binary value is input to a <code>LONGVARBINARY</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code> object. The data will be read from the
+ stream as needed until end-of-file is reached.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.2, this method works according to the standard.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBinaryStream(int, java.io.InputStream, int)" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the java input stream which contains the binary parameter value<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clearParameters()"><!-- --></A><H3>
+clearParameters</H3>
+<PRE>
+public void <B>clearParameters</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Clears the current parameter values immediately.
+ <P>In general, parameter values remain in force for repeated use of a
+ statement. Setting a parameter value automatically clears its
+ previous value.  However, in some cases it is useful to immediately
+ release the resources used by the current parameter values; this can
+ be done by calling the method <code>clearParameters</code>.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#clearParameters()" title="class or interface in java.sql">clearParameters</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setObject(int, java.lang.Object, int, int)"><!-- --></A><H3>
+setObject</H3>
+<PRE>
+public void <B>setObject</B>(int&nbsp;parameterIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+                      int&nbsp;targetSqlType,
+                      int&nbsp;scaleOrLength)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><p>Sets the value of the designated parameter with the given object. The second
+ argument must be an object type; for integral values, the
+ <code>java.lang</code> equivalent objects should be used.
+
+ If the second argument is an <code>InputStream</code> then the stream must contain
+ the number of bytes specified by scaleOrLength.  If the second argument is a
+ <code>Reader</code> then the reader must contain the number of characters specified
+ by scaleOrLength. If these conditions are not true the driver will generate a
+ <code>SQLException</code> when the prepared statement is executed.
+
+ <p>The given Java object will be converted to the given targetSqlType
+ before being sent to the database.
+
+ If the object has a custom mapping (is of a class implementing the
+ interface <code>SQLData</code>),
+ the JDBC driver should call the method <code>SQLData.writeSQL</code> to
+ write it to the SQL data stream.
+ If, on the other hand, the object is of a class implementing
+ <code>Ref</code>, <code>Blob</code>, <code>Clob</code>,  <code>NClob</code>,
+  <code>Struct</code>, <code>java.net.URL</code>,
+ or <code>Array</code>, the driver should pass it to the database as a
+ value of the corresponding SQL type.
+
+ <p>Note that this method may be used to pass database-specific
+ abstract data types.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setObject(int, java.lang.Object, int, int)" title="class or interface in java.sql">setObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the object containing the input parameter value<DD><CODE>targetSqlType</CODE> - the SQL type (as defined in java.sql.Types) to be
+ sent to the database. The scale argument may further qualify this type.<DD><CODE>scaleOrLength</CODE> - for <code>java.sql.Types.DECIMAL</code>
+          or <code>java.sql.Types.NUMERIC types</code>,
+          this is the number of digits after the decimal point. For
+          Java Object types <code>InputStream</code> and <code>Reader</code>,
+          this is the length
+          of the data in the stream or reader.  For all other types,
+          this value will be ignored.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>PreparedStatement</code> or
+            if the Java Object specified by x is an InputStream
+            or Reader object and the value of the scale parameter is less
+            than zero
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>targetSqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setObject(int, java.lang.Object, int)"><!-- --></A><H3>
+setObject</H3>
+<PRE>
+public void <B>setObject</B>(int&nbsp;parameterIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+                      int&nbsp;targetSqlType)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the value of the designated parameter with the given object.
+ This method is like the method <code>setObject</code>
+ above, except that it assumes a scale of zero.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.2, this method supports conversions listed in the
+ conversion table B-5 of the JDBC 3 specification.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setObject(int, java.lang.Object, int)" title="class or interface in java.sql">setObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the object containing the input parameter value<DD><CODE>targetSqlType</CODE> - the SQL type (as defined in java.sql.Types) to be
+                      sent to the database
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>targetSqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setObject(int, java.lang.Object)"><CODE>setObject(int,Object)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setObject(int, java.lang.Object)"><!-- --></A><H3>
+setObject</H3>
+<PRE>
+public void <B>setObject</B>(int&nbsp;parameterIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ <p>Sets the value of the designated parameter using the given object.
+ The second parameter must be of type <code>Object</code>; therefore, the
+ <code>java.lang</code> equivalent objects should be used for built-in types.
+
+ <p>The JDBC specification specifies a standard mapping from
+ Java <code>Object</code> types to SQL types.  The given argument
+ will be converted to the corresponding SQL type before being
+ sent to the database.
+
+ <p>Note that this method may be used to pass datatabase-
+ specific abstract data types, by using a driver-specific Java
+ type.
+
+ If the object is of a class implementing the interface <code>SQLData</code>,
+ the JDBC driver should call the method <code>SQLData.writeSQL</code>
+ to write it to the SQL data stream.
+ If, on the other hand, the object is of a class implementing
+ <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, (JDBC4 new:) [ <code>NClob</code> ],
+  <code>Struct</code>, <code>java.net.URL</code>, (JDBC4 new:) [ <code>RowId</code>, <code>SQLXML</code> ]
+ or <code>Array</code>, the driver should pass it to the database as a
+ value of the corresponding SQL type.
+ <P>
+ <b>Note:</b> Not all databases allow for a non-typed Null to be sent to
+ the backend. For maximum portability, the <code>setNull</code> or the
+ <code>setObject(int parameterIndex, Object x, int sqlType)</code>
+ method should be used
+ instead of <code>setObject(int parameterIndex, Object x)</code>.
+ <p>
+ <b>Note:</b> This method throws an exception if there is an ambiguity, for example, if the
+ object is of a class implementing more than one of the interfaces named above.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3><p>
+
+ Since 1.7.2, this method supports conversions listed in the conversion
+ table B-5 of the JDBC 3 specification.
+ </div>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setObject(int, java.lang.Object)" title="class or interface in java.sql">setObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the object containing the input parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+  this method is called on a closed <code>PreparedStatement</code>
+ or the type of the given object is ambiguous</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute()"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the SQL statement in this <code>PreparedStatement</code> object,
+ which may be any kind of SQL statement.
+ Some prepared statements return multiple results; the <code>execute</code>
+ method handles these complex statements as well as the simpler
+ form of statements handled by the methods <code>executeQuery</code>
+ and <code>executeUpdate</code>.
+ <P>
+ The <code>execute</code> method returns a <code>boolean</code> to
+ indicate the form of the first result.  You must call either the method
+ <code>getResultSet</code> or <code>getUpdateCount</code>
+ to retrieve the result; you must call <code>getMoreResults</code> to
+ move to any subsequent result(s).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Up to 1.8.0.x, prepared statements do not generate
+ multiple fetchable results. <p>
+
+ In future versions, it will be possible that statements
+ generate multiple fetchable results under certain conditions.
+
+ </div>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#execute()" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the first result is a <code>ResultSet</code>
+         object; <code>false</code> if the first result is an update
+         count or there is no result
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>PreparedStatement</code>
+ or an argument is supplied to this method<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String)"><CODE>JDBCStatement.execute(java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSet()"><CODE>JDBCStatement.getResultSet()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getUpdateCount()"><CODE>JDBCStatement.getUpdateCount()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMoreResults()"><CODE>JDBCStatement.getMoreResults()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addBatch()"><!-- --></A><H3>
+addBatch</H3>
+<PRE>
+public void <B>addBatch</B>()
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Adds a set of parameters to this <code>PreparedStatement</code>
+ object's batch of commands.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.2, this feature is supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#addBatch()" title="class or interface in java.sql">addBatch</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCParameterMetaData)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#addBatch(java.lang.String)"><CODE>JDBCStatement.addBatch(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream(int, java.io.Reader, int)"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public void <B>setCharacterStream</B>(int&nbsp;parameterIndex,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                               int&nbsp;length)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From HSQLDB 2.0 this method uses streaming to send data
+ when the target is a CLOB.<p>
+ HSQLDB represents CHARACTER and related SQL types as UTF16 Unicode
+ internally, so this method does not perform any conversion.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setCharacterStream(int, java.io.Reader, int)" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object that contains the
+        Unicode data<DD><CODE>length</CODE> - the number of characters in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setRef(int, java.sql.Ref)"><!-- --></A><H3>
+setRef</H3>
+<PRE>
+public void <B>setRef</B>(int&nbsp;parameterIndex,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A>&nbsp;x)
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given
+  <code>REF(&lt;structured-type&gt;)</code> value.
+ The driver converts this to an SQL <code>REF</code> value when it
+ sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0 HSQLDB does not support the SQL REF type. Calling this method
+ throws an exception.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setRef(int, java.sql.Ref)" title="class or interface in java.sql">setRef</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - an SQL <code>REF</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBlob(int, java.sql.Blob)"><!-- --></A><H3>
+setBlob</H3>
+<PRE>
+public void <B>setBlob</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.sql.Blob</code> object.
+ The driver converts this to an SQL <code>BLOB</code> value when it
+ sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ For parameters of type Blob, setBlob works normally.<p>
+
+ In addition since 1.7.2, setBlob is supported for BINARY and VARBINARY
+ parameters. In this context, the Blob object is
+ hard-limited to those of length less than or equal to Integer.MAX_VALUE.
+ In practice, soft limits such as available heap and maximum disk usage
+ per file (such as the transaction log) dictate a much smaller maximum
+ length. <p>
+
+ For BINARY and VARBINARY parameter types setBlob(i,x) is roughly
+ equivalent (null and length handling not shown) to:<p>
+
+ <pre class="JavaCodeExample">
+ <b>setBinaryStream</b>(i, x.<b>getBinaryStream</b>(), (<span class="JavaKeyWord">int</span>) x.<b>length</b>());
+ </pre></div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBlob(int, java.sql.Blob)" title="class or interface in java.sql">setBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClob(int, java.sql.Clob)"><!-- --></A><H3>
+setClob</H3>
+<PRE>
+public void <B>setClob</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;x)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.sql.Clob</code> object.
+ The driver converts this to an SQL <code>CLOB</code> value when it
+ sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ For parameters of type Clob, setClob works normally.<p>
+
+ In addition since 1.7.2, setClob is supported for CHARACTER and VARCHAR
+ parameters. In this context, the Clob object is
+ hard-limited to those of length less than or equal to Integer.MAX_VALUE.
+ In practice, soft limits such as available heap and maximum disk usage
+ per file (such as the transaction log) dictate a much smaller maximum
+ length. <p>
+
+ For CHARACTER and VARCHAR parameter types setClob(i,x) is roughly
+ equivalent (null and length handling not shown) to:<p>
+
+ <pre class="JavaCodeExample">
+ <b>setCharacterStream</b>(i, x.<b>getCharacterStream</b>(), (<span class="JavaKeyWord">int</span>) x.<b>length</b>());
+ </pre></div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setClob(int, java.sql.Clob)" title="class or interface in java.sql">setClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setArray(int, java.sql.Array)"><!-- --></A><H3>
+setArray</H3>
+<PRE>
+public void <B>setArray</B>(int&nbsp;parameterIndex,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A>&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.sql.Array</code> object.
+ The driver converts this to an SQL <code>ARRAY</code> value when it
+ sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From version 2.0, HSQLDB supports the SQL ARRAY type.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setArray(int, java.sql.Array)" title="class or interface in java.sql">setArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - an <code>Array</code> object that maps an SQL <code>ARRAY</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMetaData()"><!-- --></A><H3>
+getMetaData</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A> <B>getMetaData</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves a <code>ResultSetMetaData</code> object that contains
+ information about the columns of the <code>ResultSet</code> object
+ that will be returned when this <code>PreparedStatement</code> object
+ is executed.
+ <P>
+ Because a <code>PreparedStatement</code> object is precompiled, it is
+ possible to know about the <code>ResultSet</code> object that it will
+ return without having to execute it.  Consequently, it is possible
+ to invoke the method <code>getMetaData</code> on a
+ <code>PreparedStatement</code> object rather than waiting to execute
+ it and then invoking the <code>ResultSet.getMetaData</code> method
+ on the <code>ResultSet</code> object that is returned.
+ <P>
+ <B>NOTE:</B> Using this method may be expensive for some drivers due
+ to the lack of underlying DBMS support.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.2, this feature is supported and is <em>inexpensive</em> as
+ it is backed by underlying DBMS support.  If the statement
+ generates an update count, then null is returned.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#getMetaData()" title="class or interface in java.sql">getMetaData</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the description of a <code>ResultSet</code> object's columns or
+         <code>null</code> if the driver cannot return a
+         <code>ResultSetMetaData</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDate(int, java.sql.Date, java.util.Calendar)"><!-- --></A><H3>
+setDate</H3>
+<PRE>
+public void <B>setDate</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.sql.Date</code> value,
+ using the given <code>Calendar</code> object.  The driver uses
+ the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
+ which the driver then sends to the database.  With
+ a <code>Calendar</code> object, the driver can calculate the date
+ taking into account a custom timezone.  If no
+ <code>Calendar</code> object is specified, the driver uses the default
+ timezone, which is that of the virtual machine running the application.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setDate(int, java.sql.Date, java.util.Calendar)" title="class or interface in java.sql">setDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the date
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTime(int, java.sql.Time, java.util.Calendar)"><!-- --></A><H3>
+setTime</H3>
+<PRE>
+public void <B>setTime</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.sql.Time</code> value,
+ using the given <code>Calendar</code> object.  The driver uses
+ the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
+ which the driver then sends to the database.  With
+ a <code>Calendar</code> object, the driver can calculate the time
+ taking into account a custom timezone.  If no
+ <code>Calendar</code> object is specified, the driver uses the default
+ timezone, which is that of the virtual machine running the application.
+ <!-- end generic documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ When a setXXX method is used to set a parameter of type
+ TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone (including
+ Daylight Saving Time) of the Calendar is used as time zone for the
+ value.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setTime(int, java.sql.Time, java.util.Calendar)" title="class or interface in java.sql">setTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the time
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTimestamp(int, java.sql.Timestamp, java.util.Calendar)"><!-- --></A><H3>
+setTimestamp</H3>
+<PRE>
+public void <B>setTimestamp</B>(int&nbsp;parameterIndex,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
+ using the given <code>Calendar</code> object.  The driver uses
+ the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,
+ which the driver then sends to the database.  With a
+  <code>Calendar</code> object, the driver can calculate the timestamp
+ taking into account a custom timezone.  If no
+ <code>Calendar</code> object is specified, the driver uses the default
+ timezone, which is that of the virtual machine running the application.
+ <!-- end generic documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ When a setXXX method is used to set a parameter of type
+ TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone (including
+ Daylight Saving Time) of the Calendar is used as time zone.<p>
+ In this case, if the Calendar argument is null, then the default Calendar
+ for the clients JVM is used as the Calendar<p>
+
+ When this method is used to set a parameter of type TIME or
+ TIME WITH TIME ZONE, then the nanosecond value of the Timestamp object
+ is used if the TIME parameter accepts fractional seconds.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setTimestamp(int, java.sql.Timestamp, java.util.Calendar)" title="class or interface in java.sql">setTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value<DD><CODE>cal</CODE> - the <code>Calendar</code> object the driver will use
+            to construct the timestamp
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNull(int, int, java.lang.String)"><!-- --></A><H3>
+setNull</H3>
+<PRE>
+public void <B>setNull</B>(int&nbsp;parameterIndex,
+                    int&nbsp;sqlType,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;typeName)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to SQL <code>NULL</code>.
+ This version of the method <code>setNull</code> should
+ be used for user-defined types and REF type parameters.  Examples
+ of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and
+ named array types.
+
+ <P><B>Note:</B> To be portable, applications must give the
+ SQL type code and the fully-qualified SQL type name when specifying
+ a NULL user-defined or REF parameter.  In the case of a user-defined type
+ the name is the type name of the parameter itself.  For a REF
+ parameter, the name is the type name of the referenced type.  If
+ a JDBC driver does not need the type code or type name information,
+ it may ignore it.
+
+ Although it is intended for user-defined and Ref parameters,
+ this method may be used to set a null parameter of any JDBC type.
+ If the parameter does not have a user-defined or REF type, the given
+ typeName is ignored.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB simply ignores the sqlType and typeName arguments.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNull(int, int, java.lang.String)" title="class or interface in java.sql">setNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>sqlType</CODE> - a value from <code>java.sql.Types</code><DD><CODE>typeName</CODE> - the fully-qualified name of an SQL user-defined type;
+  ignored if the parameter is not a user-defined type or REF
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if <code>sqlType</code> is
+ a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+ <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+ <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+ or  <code>STRUCT</code> data type and the JDBC driver does not support
+ this data type or if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCParameterMetaData)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeBatch()"><!-- --></A><H3>
+executeBatch</H3>
+<PRE>
+public int[] <B>executeBatch</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Submits a batch of commands to the database for execution and
+ if all commands execute successfully, returns an array of update counts.
+ The <code>int</code> elements of the array that is returned are ordered
+ to correspond to the commands in the batch, which are ordered
+ according to the order in which they were added to the batch.
+ The elements in the array returned by the method <code>executeBatch</code>
+ may be one of the following:
+ <OL>
+ <LI>A number greater than or equal to zero -- indicates that the
+ command was processed successfully and is an update count giving the
+ number of rows in the database that were affected by the command's
+ execution
+ <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was
+ processed successfully but that the number of rows affected is
+ unknown
+ <P>
+ If one of the commands in a batch update fails to execute properly,
+ this method throws a <code>BatchUpdateException</code>, and a JDBC
+ driver may or may not continue to process the remaining commands in
+ the batch.  However, the driver's behavior must be consistent with a
+ particular DBMS, either always continuing to process commands or never
+ continuing to process commands.  If the driver continues processing
+ after a failure, the array returned by the method
+ <code>BatchUpdateException.getUpdateCounts</code>
+ will contain as many elements as there are commands in the batch, and
+ at least one of the elements will be the following:
+ <P>
+ <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command failed
+ to execute successfully and occurs only if a driver continues to
+ process commands after a command fails
+ </OL>
+ <P>
+ A driver is not required to implement this method.
+ The possible implementations and return values have been modified in
+ the Java 2 SDK, Standard Edition, version 1.3 to
+ accommodate the option of continuing to proccess commands in a batch
+ update after a <code>BatchUpdateException</code> obejct has been thrown. <p>
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 1.7.2, this feature is supported. <p>
+
+ HSQLDB stops execution of commands in a batch when one of the commands
+ results in an exception. The size of the returned array equals the
+ number of commands that were executed successfully.<p>
+
+ When the product is built under the JAVA1 target, an exception
+ is never thrown and it is the responsibility of the client software to
+ check the size of the  returned update count array to determine if any
+ batch items failed.  To build and run under the JAVA2 target, JDK/JRE
+ 1.3 or higher must be used.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeBatch()" title="class or interface in java.sql">executeBatch</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of update counts containing one element for each
+ command in the batch.  The elements of the array are ordered according
+ to the order in which commands were added to the batch.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the
+ driver does not support batch statements. Throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/BatchUpdateException.html?is-external=true" title="class or interface in java.sql"><CODE>BatchUpdateException</CODE></A>
+ (a subclass of <code>SQLException</code>) if one of the commands sent to the
+ database fails to execute properly or attempts to return a result set.<DT><B>Since:</B></DT>
+  <DD>JDK 1.3 (JDK 1.1.x developers: read the overview for
+ JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#addBatch()"><CODE>addBatch()</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsBatchUpdates()" title="class or interface in java.sql"><CODE>DatabaseMetaData.supportsBatchUpdates()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setEscapeProcessing(boolean)"><!-- --></A><H3>
+setEscapeProcessing</H3>
+<PRE>
+public void <B>setEscapeProcessing</B>(boolean&nbsp;enable)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets escape processing on or off. <p>
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ As per JDBC spec, calling this method has no effect.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setEscapeProcessing(boolean)" title="class or interface in java.sql">setEscapeProcessing</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>enable</CODE> - <code>true</code> to enable escape processing;
+     <code>false</code> to disable it
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addBatch(java.lang.String)"><!-- --></A><H3>
+addBatch</H3>
+<PRE>
+public void <B>addBatch</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method should always throw if called for a PreparedStatement or
+ CallableStatment.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#addBatch(java.lang.String)" title="class or interface in java.sql">addBatch</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - ignored
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - always</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeQuery(java.lang.String)"><!-- --></A><H3>
+executeQuery</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>executeQuery</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method should always throw if called for a PreparedStatement or
+ CallableStatment.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeQuery(java.lang.String)" title="class or interface in java.sql">executeQuery</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - ignored
+<DT><B>Returns:</B><DD>nothing
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - always</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute(java.lang.String)"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method should always throw if called for a PreparedStatement or
+ CallableStatment.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String)" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - ignored
+<DT><B>Returns:</B><DD>nothing
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - always</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate(java.lang.String)"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method should always throw if called for a PreparedStatement or
+ CallableStatment.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String)" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - ignored
+<DT><B>Returns:</B><DD>nothing
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - always</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="close()"><!-- --></A><H3>
+close</H3>
+<PRE>
+public void <B>close</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Does the specialized work required to free this object's resources and
+ that of it's parent class. <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#close()" title="class or interface in java.sql">close</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>toString</B>()</PRE>
+<DL>
+<DD>Retrieves a String representation of this object.  <p>
+
+ The representation is of the form: <p>
+
+ class-name@hash[sql=[char-sequence], parameters=[p1, ...pi, ...pn]] <p>
+
+ p1, ...pi, ...pn are the String representations of the currently set
+ parameter values that will be used with the non-batch execution
+ methods. <p>
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a String representation of this object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setURL(int, java.net.URL)"><!-- --></A><H3>
+setURL</H3>
+<PRE>
+public void <B>setURL</B>(int&nbsp;parameterIndex,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A>&nbsp;x)
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the designated parameter to the given <code>java.net.URL</code> value.
+ The driver converts this to an SQL <code>DATALINK</code> value
+ when it sends it to the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, HSQLDB does not support the DATALINK SQL type for which this
+ method is intended. Calling this method throws an exception.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setURL(int, java.net.URL)" title="class or interface in java.sql">setURL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the <code>java.net.URL</code> object to be set
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQL 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParameterMetaData()"><!-- --></A><H3>
+getParameterMetaData</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A> <B>getParameterMetaData</B>()
+                                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the number, types and properties of this
+ <code>PreparedStatement</code> object's parameters.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.7.2, this feature is supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#getParameterMetaData()" title="class or interface in java.sql">getParameterMetaData</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>ParameterMetaData</code> object that contains information
+         about the number, types and properties for each
+  parameter marker of this <code>PreparedStatement</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQL 1.7.0</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql"><CODE>ParameterMetaData</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate(java.lang.String, int)"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                         int&nbsp;autoGeneratedKeys)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Statement methods that must be overridden in this class and throw
+ an exception.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, int)" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute(java.lang.String, int)"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                       int&nbsp;autoGeneratedKeys)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, int)" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate(java.lang.String, int[])"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                         int[]&nbsp;columnIndexes)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, int[])" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute(java.lang.String, int[])"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                       int[]&nbsp;columnIndexes)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, int[])" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate(java.lang.String, java.lang.String[])"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, java.lang.String[])" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute(java.lang.String, java.lang.String[])"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, java.lang.String[])" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMoreResults(int)"><!-- --></A><H3>
+getMoreResults</H3>
+<PRE>
+public boolean <B>getMoreResults</B>(int&nbsp;current)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves to this <code>Statement</code> object's next result, deals with
+ any current <code>ResultSet</code> object(s) according  to the instructions
+ specified by the given flag, and returns
+ <code>true</code> if the next result is a <code>ResultSet</code> object.
+
+ <P>There are no more results when the following is true:
+ <PRE>
+     // stmt is a Statement object
+     ((stmt.getMoreResults(current) == false) && (stmt.getUpdateCount() == -1))
+ </PRE>
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMoreResults(int)" title="class or interface in java.sql">getMoreResults</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>current</CODE> - one of the following <code>Statement</code>
+        constants indicating what should happen to current
+        <code>ResultSet</code> objects obtained using the method
+        <code>getResultSet</code>:
+        <code>Statement.CLOSE_CURRENT_RESULT</code>,
+        <code>Statement.KEEP_CURRENT_RESULT</code>, or
+        <code>Statement.CLOSE_ALL_RESULTS</code>
+<DT><B>Returns:</B><DD><code>true</code> if the next result is a <code>ResultSet</code>
+         object; <code>false</code> if it is an update count or there are no
+         more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the argument
+             supplied is not one of the following:
+        <code>Statement.CLOSE_CURRENT_RESULT</code>,
+        <code>Statement.KEEP_CURRENT_RESULT</code>, or
+        <code>Statement.CLOSE_ALL_RESULTS</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute()"><CODE>execute()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getGeneratedKeys()"><!-- --></A><H3>
+getGeneratedKeys</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getGeneratedKeys</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves any auto-generated keys created as a result of executing this
+ <code>Statement</code> object. If this <code>Statement</code> object did
+ not generate any keys, an empty <code>ResultSet</code>
+ object is returned.
+ <p>(JDBC4 clarification:)
+ <p><B>Note:</B>If the columns which represent the auto-generated keys were not specified,
+ the JDBC driver implementation will determine the columns which best represent the auto-generated keys.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Supported in version 2.0.<p>
+
+ If column names or indexes provided by the user in the executeUpdate()
+ method calls are not correct, an empty result is returned.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getGeneratedKeys()" title="class or interface in java.sql">getGeneratedKeys</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object containing the auto-generated key(s)
+         generated by the execution of this <code>Statement</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSetHoldability()"><!-- --></A><H3>
+getResultSetHoldability</H3>
+<PRE>
+public int <B>getResultSetHoldability</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the result set holdability for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.7.2, this method returns HOLD_CURSORS_OVER_COMMIT
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetHoldability()" title="class or interface in java.sql">getResultSetHoldability</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isClosed()"><!-- --></A><H3>
+isClosed</H3>
+<PRE>
+public boolean <B>isClosed</B>()</PRE>
+<DL>
+<DD>Retrieves whether this <code>Statement</code> object has been closed. A <code>Statement</code> is closed if the
+ method close has been called on it, or if it is automatically closed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#isClosed()" title="class or interface in java.sql">isClosed</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if this <code>Statement</code> object is closed; false if it is still open
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setRowId(int, java.sql.RowId)"><!-- --></A><H3>
+setRowId</H3>
+<PRE>
+public void <B>setRowId</B>(int&nbsp;parameterIndex,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;x)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>java.sql.RowId</code> object. The
+ driver converts this to a SQL <code>ROWID</code> value when it sends it
+ to the database
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setRowId(int, java.sql.RowId)" title="class or interface in java.sql">setRowId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNString(int, java.lang.String)"><!-- --></A><H3>
+setNString</H3>
+<PRE>
+public void <B>setNString</B>(int&nbsp;parameterIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;value)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated paramter to the given <code>String</code> object.
+ The driver converts this to a SQL <code>NCHAR</code> or
+ <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+ (depending on the argument's
+ size relative to the driver's limits on <code>NVARCHAR</code> values)
+ when it sends it to the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNString(int, java.lang.String)" title="class or interface in java.sql">setNString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - of the first parameter is 1, the second is 2, ...<DD><CODE>value</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur ; if a database access error occurs; or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNCharacterStream(int, java.io.Reader, long)"><!-- --></A><H3>
+setNCharacterStream</H3>
+<PRE>
+public void <B>setNCharacterStream</B>(int&nbsp;parameterIndex,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;value,
+                                long&nbsp;length)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object. The
+ <code>Reader</code> reads the data till end-of-file is reached. The
+ driver does the necessary conversion from Java character format to
+ the national character set in the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNCharacterStream(int, java.io.Reader, long)" title="class or interface in java.sql">setNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - of the first parameter is 1, the second is 2, ...<DD><CODE>value</CODE> - the parameter value<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur ; if a database access error occurs; or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNClob(int, java.sql.NClob)"><!-- --></A><H3>
+setNClob</H3>
+<PRE>
+public void <B>setNClob</B>(int&nbsp;parameterIndex,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>&nbsp;value)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to a
+ SQL <code>NCLOB</code> value when it sends it to the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNClob(int, java.sql.NClob)" title="class or interface in java.sql">setNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - of the first parameter is 1, the second is 2, ...<DD><CODE>value</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur ; if a database access error occurs; or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClob(int, java.io.Reader, long)"><!-- --></A><H3>
+setClob</H3>
+<PRE>
+public void <B>setClob</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                    long&nbsp;length)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object.  The reader must contain  the number
+ of characters specified by length otherwise a <code>SQLException</code> will be
+ generated when the <code>PreparedStatement</code> is executed.
+ This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
+ because it informs the driver that the parameter value should be sent to
+ the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+ driver may have to do extra work to determine whether the parameter
+ data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setClob(int, java.io.Reader, long)" title="class or interface in java.sql">setClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1, the second is 2, ...<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this method is called on
+ a closed <code>PreparedStatement</code>, if parameterIndex does not correspond to a parameter
+ marker in the SQL statement, or if the length specified is less than zero.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBlob(int, java.io.InputStream, long)"><!-- --></A><H3>
+setBlob</H3>
+<PRE>
+public void <B>setBlob</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream,
+                    long&nbsp;length)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>InputStream</code> object.  The inputstream must contain  the number
+ of characters specified by length otherwise a <code>SQLException</code> will be
+ generated when the <code>PreparedStatement</code> is executed.
+ This method differs from the <code>setBinaryStream (int, InputStream, int)</code>
+ method because it informs the driver that the parameter value should be
+ sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
+ the driver may have to do extra work to determine whether the parameter
+ data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ In HSQLDB 2.0, this method uses streaming to send the data when the
+ stream is assigned to a BLOB target. For other binary targets the
+ stream is read on the client side and a byte array is sent.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBlob(int, java.io.InputStream, long)" title="class or interface in java.sql">setBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1,
+ the second is 2, ...<DD><CODE>inputStream</CODE> - An object that contains the data to set the parameter
+ value to.<DD><CODE>length</CODE> - the number of bytes in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>PreparedStatement</code>,
+ if parameterIndex does not correspond
+ to a parameter marker in the SQL statement,  if the length specified
+ is less than zero or if the number of bytes in the inputstream does not match
+ the specfied length.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNClob(int, java.io.Reader, long)"><!-- --></A><H3>
+setNClob</H3>
+<PRE>
+public void <B>setNClob</B>(int&nbsp;parameterIndex,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                     long&nbsp;length)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object.  The reader must contain  the number
+ of characters specified by length otherwise a <code>SQLException</code> will be
+ generated when the <code>PreparedStatement</code> is executed.
+ This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
+ because it informs the driver that the parameter value should be sent to
+ the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+ driver may have to do extra work to determine whether the parameter
+ data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNClob(int, java.io.Reader, long)" title="class or interface in java.sql">setNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1, the second is 2, ...<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement; if the length specified is less than zero;
+ if the driver does not support national character sets;
+ if the driver can detect that a data conversion
+  error could occur;  if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setSQLXML(int, java.sql.SQLXML)"><!-- --></A><H3>
+setSQLXML</H3>
+<PRE>
+public void <B>setSQLXML</B>(int&nbsp;parameterIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>&nbsp;xmlObject)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>java.sql.SQLXML</code> object.
+ The driver converts this to an
+ SQL <code>XML</code> value when it sends it to the database.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setSQLXML(int, java.sql.SQLXML)" title="class or interface in java.sql">setSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1, the second is 2, ...<DD><CODE>xmlObject</CODE> - a <code>SQLXML</code> object that maps an SQL <code>XML</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+  this method is called on a closed <code>PreparedStatement</code>
+ or the <code>java.xml.transform.Result</code>,
+  <code>Writer</code> or <code>OutputStream</code> has not been closed for
+ the <code>SQLXML</code> object
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAsciiStream(int, java.io.InputStream, long)"><!-- --></A><H3>
+setAsciiStream</H3>
+<PRE>
+public void <B>setAsciiStream</B>(int&nbsp;parameterIndex,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                           long&nbsp;length)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+ When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code>. Data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from ASCII to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From HSQLDB 2.0 this method uses the US-ASCII character encoding to convert bytes
+ from the stream into the characters of a String.<p>
+ This method does not use streaming to send the data,
+ whether the target is a CLOB or other binary object.<p>
+
+ For long streams (larger than a few megabytes) with CLOB targets,
+ it is more efficient to use a version of setCharacterStream which takes
+ the a length parameter.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setAsciiStream(int, java.io.InputStream, long)" title="class or interface in java.sql">setAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the Java input stream that contains the ASCII parameter value<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.6 b86, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream(int, java.io.InputStream, long)"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public void <B>setBinaryStream</B>(int&nbsp;parameterIndex,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                            long&nbsp;length)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given input stream, which will have
+ the specified number of bytes.
+ When a very large binary value is input to a <code>LONGVARBINARY</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code> object. The data will be read from the
+ stream as needed until end-of-file is reached.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ In HSQLDB 2.0, this method uses streaming to send the data when the
+ stream is assigned to a BLOB target. For other binary targets the
+ stream is read on the client side and a byte array is sent.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBinaryStream(int, java.io.InputStream, long)" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the java input stream which contains the binary parameter value<DD><CODE>length</CODE> - the number of bytes in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.6 b86, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream(int, java.io.Reader, long)"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public void <B>setCharacterStream</B>(int&nbsp;parameterIndex,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                               long&nbsp;length)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object, which is the given number of characters long.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From HSQLDB 2.0 this method uses streaming to send data
+ when the target is a CLOB.<p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setCharacterStream(int, java.io.Reader, long)" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object that contains the
+        Unicode data<DD><CODE>length</CODE> - the number of characters in the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.6 b86, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAsciiStream(int, java.io.InputStream)"><!-- --></A><H3>
+setAsciiStream</H3>
+<PRE>
+public void <B>setAsciiStream</B>(int&nbsp;parameterIndex,
+                           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given input stream.
+ When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code>. Data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from ASCII to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setAsciiStream</code> which takes a length parameter.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ In HSQLDB 2.0, this method does not use streaming to send the data,
+ whether the target is a CLOB or other binary object.
+
+ For long streams (larger than a few megabytes), it is more efficient to
+ use a version of setCharacterStream which takes the a length parameter.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setAsciiStream(int, java.io.InputStream)" title="class or interface in java.sql">setAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the Java input stream that contains the ASCII parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement; if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream(int, java.io.InputStream)"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public void <B>setBinaryStream</B>(int&nbsp;parameterIndex,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given input stream.
+ When a very large binary value is input to a <code>LONGVARBINARY</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code> object. The data will be read from the
+ stream as needed until end-of-file is reached.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setBinaryStream</code> which takes a length parameter.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From HSQLDB 2.0 this method uses the US-ASCII character encoding to convert bytes
+ from the stream into the characters of a String.<p>
+ This method does not use streaming to send the data,
+ whether the target is a CLOB or other binary object.<p>
+
+ For long streams (larger than a few megabytes) with CLOB targets,
+ it is more efficient to use a version of setCharacterStream which takes
+ the a length parameter.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBinaryStream(int, java.io.InputStream)" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>x</CODE> - the java input stream which contains the binary parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement; if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream(int, java.io.Reader)"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public void <B>setCharacterStream</B>(int&nbsp;parameterIndex,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to the given <code>Reader</code>
+ object.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setCharacterStream</code> which takes a length parameter.
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ In HSQLDB 2.0, this method does not use streaming to send the data,
+ whether the target is a CLOB or other binary object.
+
+ For long streams (larger than a few megabytes), it is more efficient to
+ use a version of setCharacterStream which takes the a length parameter.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setCharacterStream(int, java.io.Reader)" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - the first parameter is 1, the second is 2, ...<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object that contains the
+        Unicode data
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement; if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNCharacterStream(int, java.io.Reader)"><!-- --></A><H3>
+setNCharacterStream</H3>
+<PRE>
+public void <B>setNCharacterStream</B>(int&nbsp;parameterIndex,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;value)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object. The
+   <code>Reader</code> reads the data till end-of-file is reached. The
+   driver does the necessary conversion from Java character format to
+   the national character set in the database.
+
+   <P><B>Note:</B> This stream object can either be a standard
+   Java stream object or your own subclass that implements the
+   standard interface.
+   <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+   it might be more efficient to use a version of
+   <code>setNCharacterStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNCharacterStream(int, java.io.Reader)" title="class or interface in java.sql">setNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - of the first parameter is 1, the second is 2, ...<DD><CODE>value</CODE> - the parameter value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+   marker in the SQL statement; if the driver does not support national
+           character sets;  if the driver can detect that a data conversion
+    error could occur; if a database access error occurs; or
+   this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClob(int, java.io.Reader)"><!-- --></A><H3>
+setClob</H3>
+<PRE>
+public void <B>setClob</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+ This method differs from the <code>setCharacterStream (int, Reader)</code> method
+ because it informs the driver that the parameter value should be sent to
+ the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+ driver may have to do extra work to determine whether the parameter
+ data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setClob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setClob(int, java.io.Reader)" title="class or interface in java.sql">setClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1, the second is 2, ...<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement; if a database access error occurs; this method is called on
+ a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter
+ marker in the SQL statement
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBlob(int, java.io.InputStream)"><!-- --></A><H3>
+setBlob</H3>
+<PRE>
+public void <B>setBlob</B>(int&nbsp;parameterIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>InputStream</code> object.
+ This method differs from the <code>setBinaryStream (int, InputStream)</code>
+ method because it informs the driver that the parameter value should be
+ sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
+ the driver may have to do extra work to determine whether the parameter
+ data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setBlob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setBlob(int, java.io.InputStream)" title="class or interface in java.sql">setBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1,
+ the second is 2, ...<DD><CODE>inputStream</CODE> - An object that contains the data to set the parameter
+ value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement; if a database access error occurs;
+ this method is called on a closed <code>PreparedStatement</code> or
+ if parameterIndex does not correspond
+ to a parameter marker in the SQL statement,
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNClob(int, java.io.Reader)"><!-- --></A><H3>
+setNClob</H3>
+<PRE>
+public void <B>setNClob</B>(int&nbsp;parameterIndex,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the designated parameter to a <code>Reader</code> object.
+ This method differs from the <code>setCharacterStream (int, Reader)</code> method
+ because it informs the driver that the parameter value should be sent to
+ the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+ driver may have to do extra work to determine whether the parameter
+ data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>setNClob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true#setNClob(int, java.io.Reader)" title="class or interface in java.sql">setNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parameterIndex</CODE> - index of the first parameter is 1, the second is 2, ...<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if parameterIndex does not correspond to a parameter
+ marker in the SQL statement;
+ if the driver does not support national character sets;
+ if the driver can detect that a data conversion
+  error could occur;  if a database access error occurs or
+ this method is called on a closed <code>PreparedStatement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxFieldSize()"><!-- --></A><H3>
+getMaxFieldSize</H3>
+<PRE>
+public int <B>getMaxFieldSize</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the maximum number of bytes that can be
+ returned for character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.
+ This limit applies only to  <code>BINARY</code>, <code>VARBINARY</code>,
+ <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
+ (JDBC4 new:) <code>NCHAR</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>
+ and <code>LONGVARCHAR</code> columns.  If the limit is exceeded, the
+ excess data is silently discarded.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB always returns zero, meaning there is no limit.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMaxFieldSize()" title="class or interface in java.sql">getMaxFieldSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current column size limit for columns storing character and
+         binary values; zero means there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setMaxFieldSize(int)"><CODE>setMaxFieldSize(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMaxFieldSize(int)"><!-- --></A><H3>
+setMaxFieldSize</H3>
+<PRE>
+public void <B>setMaxFieldSize</B>(int&nbsp;max)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:) Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
+ Sets the limit for the maximum number of bytes that can be returned for
+ character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.
+
+ This limit applies
+ only to <code>BINARY</code>, <code>VARBINARY</code>,
+ <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
+ (JDBC4 new:) <code>NCHAR</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code> and
+ <code>LONGVARCHAR</code> fields.  If the limit is exceeded, the excess data
+ is silently discarded. For maximum portability, use values
+ greater than 256.
+ <!-- emd generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ To present, calls to this method are simply ignored; HSQLDB always
+ stores the full number of bytes when dealing with any of the field types
+ mentioned above. These types all have an absolute maximum element upper
+ bound determined by the Java array index limit
+ java.lang.Integer.MAX_VALUE.  For XXXBINARY types, this translates to
+ Integer.MAX_VALUE bytes.  For XXXCHAR types, this translates to
+ 2 * Integer.MAX_VALUE bytes (2 bytes / character). <p>
+
+ In practice, field sizes are limited to values much smaller than the
+ absolute maximum element upper bound, in particular due to limits imposed
+ on the maximum available Java heap memory.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setMaxFieldSize(int)" title="class or interface in java.sql">setMaxFieldSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>max</CODE> - the new column size limit in bytes; zero means there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>
+            or the condition max >= 0 is not satisfied<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMaxFieldSize()"><CODE>getMaxFieldSize()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxRows()"><!-- --></A><H3>
+getMaxRows</H3>
+<PRE>
+public int <B>getMaxRows</B>()
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the maximum number of rows that a
+ <code>ResultSet</code> object produced by this
+ <code>Statement</code> object can contain.  If this limit is exceeded,
+ the excess rows are silently dropped.
+ <!-- start generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMaxRows()" title="class or interface in java.sql">getMaxRows</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current maximum number of rows for a <code>ResultSet</code>
+         object produced by this <code>Statement</code> object;
+         zero means there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setMaxRows(int)"><CODE>setMaxRows(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMaxRows(int)"><!-- --></A><H3>
+setMaxRows</H3>
+<PRE>
+public void <B>setMaxRows</B>(int&nbsp;max)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Sets the limit for the maximum number of rows that any
+ <code>ResultSet</code> object  generated by this <code>Statement</code>
+ object can contain to the given number.
+ If the limit is exceeded, the excess
+ rows are silently dropped.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setMaxRows(int)" title="class or interface in java.sql">setMaxRows</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>max</CODE> - the new max rows limit; zero means there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>
+            or the condition max >= 0 is not satisfied<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getMaxRows()"><CODE>getMaxRows()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getQueryTimeout()"><!-- --></A><H3>
+getQueryTimeout</H3>
+<PRE>
+public int <B>getQueryTimeout</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the number of seconds the driver will
+ wait for a <code>Statement</code> object to execute.
+ If the limit is exceeded, a
+ <code>SQLException</code> is thrown.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ To present, HSQLDB always returns zero, meaning there
+ is no limit.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getQueryTimeout()" title="class or interface in java.sql">getQueryTimeout</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current query timeout limit in seconds; zero means there is
+         no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setQueryTimeout(int)"><CODE>setQueryTimeout(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setQueryTimeout(int)"><!-- --></A><H3>
+setQueryTimeout</H3>
+<PRE>
+public void <B>setQueryTimeout</B>(int&nbsp;seconds)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the number of seconds the driver will wait for a
+ <code>Statement</code> object to execute to the given number of seconds.
+ If the limit is exceeded, an <code>SQLException</code> is thrown. A JDBC
+ (JDBC4 clarification:)
+ driver must apply this limit to the <code>execute</code>,
+ <code>executeQuery</code> and <code>executeUpdate</code> methods. JDBC driver
+ implementations may also apply this limit to <code>ResultSet</code> methods
+ (consult your driver vendor documentation for details).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The maximum value is Short.MAX_VALUE. The minimum is 0, indicating no limit.
+ In 2.0, calls to this method are ignored; HSQLDB waits an
+ unlimited amount of time for statement execution
+ requests to return.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setQueryTimeout(int)" title="class or interface in java.sql">setQueryTimeout</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>seconds</CODE> - the new query timeout limit in seconds; zero means
+        there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>
+            or the condition seconds >= 0 is not satisfied<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getQueryTimeout()"><CODE>getQueryTimeout()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="cancel()"><!-- --></A><H3>
+cancel</H3>
+<PRE>
+public void <B>cancel</B>()
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Cancels this <code>Statement</code> object if both the DBMS and
+ driver support aborting an SQL statement.
+ This method can be used by one thread to cancel a statement that
+ is being executed by another thread.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, HSQLDB does <i>not</i> support aborting an SQL
+ statement; calls to this method are ignored.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#cancel()" title="class or interface in java.sql">cancel</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWarnings()"><!-- --></A><H3>
+getWarnings</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A> <B>getWarnings</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the first warning reported by calls on this <code>Statement</code> object.
+ Subsequent <code>Statement</code> object warnings will be chained to this
+ <code>SQLWarning</code> object.
+
+ <p>The warning chain is automatically cleared each time
+ a statement is (re)executed. This method may not be called on a closed
+ <code>Statement</code> object; doing so will cause an <code>SQLException</code>
+ to be thrown.
+
+ <P><B>Note:</B> If you are processing a <code>ResultSet</code> object, any
+ warnings associated with reads on that <code>ResultSet</code> object
+ will be chained on it rather than on the <code>Statement</code>
+ object that produced it.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 1.9 HSQLDB, produces Statement warnings.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getWarnings()" title="class or interface in java.sql">getWarnings</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the first <code>SQLWarning</code> object or <code>null</code>
+         if there are no warnings
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clearWarnings()"><!-- --></A><H3>
+clearWarnings</H3>
+<PRE>
+public void <B>clearWarnings</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Clears all the warnings reported on this <code>Statement</code>
+ object. After a call to this method,
+ the method <code>getWarnings</code> will return
+ <code>null</code> until a new warning is reported for this
+ <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Supported in HSQLDB 1.9.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#clearWarnings()" title="class or interface in java.sql">clearWarnings</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCursorName(java.lang.String)"><!-- --></A><H3>
+setCursorName</H3>
+<PRE>
+public void <B>setCursorName</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the SQL cursor name to the given <code>String</code>, which
+ will be used by subsequent <code>Statement</code> object
+ <code>execute</code> methods. This name can then be
+ used in SQL positioned update or delete statements to identify the
+ current row in the <code>ResultSet</code> object generated by this
+ statement.  If the database does not support positioned update/delete,
+ this method is a noop.  To insure that a cursor has the proper isolation
+ level to support updates, the cursor's <code>SELECT</code> statement
+ should have the form <code>SELECT FOR UPDATE</code>.  If
+ <code>FOR UPDATE</code> is not present, positioned updates may fail.
+
+ <P><B>Note:</B> By definition, the execution of positioned updates and
+ deletes must be done by a different <code>Statement</code> object than
+ the one that generated the <code>ResultSet</code> object being used for
+ positioning. Also, cursor names must be unique within a connection.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, HSQLDB does not support named cursors;
+ calls to this method are ignored.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setCursorName(java.lang.String)" title="class or interface in java.sql">setCursorName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the new cursor name, which must be unique within
+             a connection
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSet()"><!-- --></A><H3>
+getResultSet</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getResultSet</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+  Retrieves the current result as a <code>ResultSet</code> object.
+  This method should be called only once per result.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Without an interceding call to executeXXX, each invocation of this
+ method will produce a new, initialized ResultSet instance referring to
+ the current result, if any.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSet()" title="class or interface in java.sql">getResultSet</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current result as a <code>ResultSet</code> object or
+ <code>null</code> if the result is an update count or there are no more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute()"><CODE>execute()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUpdateCount()"><!-- --></A><H3>
+getUpdateCount</H3>
+<PRE>
+public int <B>getUpdateCount</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+  Retrieves the current result as an update count;
+  if the result is a <code>ResultSet</code> object or there are no more results, -1
+  is returned. This method should be called only once per result.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getUpdateCount()" title="class or interface in java.sql">getUpdateCount</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current result as an update count; -1 if the current result is a
+ <code>ResultSet</code> object or there are no more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute()"><CODE>execute()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMoreResults()"><!-- --></A><H3>
+getMoreResults</H3>
+<PRE>
+public boolean <B>getMoreResults</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves to this <code>Statement</code> object's next result, returns
+ <code>true</code> if it is a <code>ResultSet</code> object, and
+ implicitly closes any current <code>ResultSet</code>
+ object(s) obtained with the method <code>getResultSet</code>.
+
+ <P>There are no more results when the following is true:
+ <PRE>
+     // stmt is a Statement object
+     ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
+ </PRE>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMoreResults()" title="class or interface in java.sql">getMoreResults</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the next result is a <code>ResultSet</code>
+         object; <code>false</code> if it is an update count or there are
+         no more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#execute()"><CODE>execute()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFetchDirection(int)"><!-- --></A><H3>
+setFetchDirection</H3>
+<PRE>
+public void <B>setFetchDirection</B>(int&nbsp;direction)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Gives the driver a hint as to the direction in which
+ rows will be processed in <code>ResultSet</code>
+ objects created using this <code>Statement</code> object.  The
+ default value is <code>ResultSet.FETCH_FORWARD</code>.
+ <P>
+ Note that this method sets the default fetch direction for
+ result sets generated by this <code>Statement</code> object.
+ Each result set has its own methods for getting and setting
+ its own fetch direction.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Up to 1.8.0.x, HSQLDB supports only <code>FETCH_FORWARD</code>;
+ Setting any other value would throw an <code>SQLException</code>
+ stating that the operation is not supported. <p>
+
+ Starting with 2.0, HSQLDB accepts any valid value.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setFetchDirection(int)" title="class or interface in java.sql">setFetchDirection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>direction</CODE> - the initial direction for processing rows
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>
+ or the given direction
+ is not one of <code>ResultSet.FETCH_FORWARD</code>,
+ <code>ResultSet.FETCH_REVERSE</code>, or <code>ResultSet.FETCH_UNKNOWN</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+    for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getFetchDirection()"><CODE>getFetchDirection()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFetchDirection()"><!-- --></A><H3>
+getFetchDirection</H3>
+<PRE>
+public int <B>getFetchDirection</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the direction for fetching rows from
+ database tables that is the default for result sets
+ generated from this <code>Statement</code> object.
+ If this <code>Statement</code> object has not set
+ a fetch direction by calling the method <code>setFetchDirection</code>,
+ the return value is implementation-specific.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Up to 1.8.0.x, HSQLDB always returned FETCH_FORWARD.
+
+ Starting with 2.0, HSQLDB returns FETCH_FORWARD by default, or
+ whatever value has been explicitly assigned by invoking
+ <code>setFetchDirection</code>.
+ .
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getFetchDirection()" title="class or interface in java.sql">getFetchDirection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the default fetch direction for result sets generated
+          from this <code>Statement</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+    for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setFetchDirection(int)"><CODE>setFetchDirection(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFetchSize(int)"><!-- --></A><H3>
+setFetchSize</H3>
+<PRE>
+public void <B>setFetchSize</B>(int&nbsp;rows)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for
+ <code>ResultSet</code> objects genrated by this <code>Statement</code>.
+ If the value specified is zero, then the hint is ignored.
+ The default value is zero.
+ <!-- start generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB uses the specified value as a hint, but may process more or fewer
+ rows than specified.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setFetchSize(int)" title="class or interface in java.sql">setFetchSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>rows</CODE> - the number of rows to fetch
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the
+        (JDBC4 modified:)
+        condition  <code>rows >= 0</code> is not satisfied.<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+   for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#getFetchSize()"><CODE>getFetchSize()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFetchSize()"><!-- --></A><H3>
+getFetchSize</H3>
+<PRE>
+public int <B>getFetchSize</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the number of result set rows that is the default
+ fetch size for <code>ResultSet</code> objects
+ generated from this <code>Statement</code> object.
+ If this <code>Statement</code> object has not set
+ a fetch size by calling the method <code>setFetchSize</code>,
+ the return value is implementation-specific.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <b>HSQLDB-Specific Information</b> <p>
+
+ HSQLDB returns 0 by default, or the fetch size specified by setFetchSize
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getFetchSize()" title="class or interface in java.sql">getFetchSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the default fetch size for result sets generated
+          from this <code>Statement</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+  for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setFetchSize(int)"><CODE>setFetchSize(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSetConcurrency()"><!-- --></A><H3>
+getResultSetConcurrency</H3>
+<PRE>
+public int <B>getResultSetConcurrency</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the result set concurrency for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports <code>CONCUR_READ_ONLY</code> and
+ <code>CONCUR_READ_UPDATEBLE</code> concurrency.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetConcurrency()" title="class or interface in java.sql">getResultSetConcurrency</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>either <code>ResultSet.CONCUR_READ_ONLY</code> or
+ <code>ResultSet.CONCUR_UPDATABLE</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+  for JDBCStatement)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSetType()"><!-- --></A><H3>
+getResultSetType</H3>
+<PRE>
+public int <B>getResultSetType</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the result set type for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 1.7.0 and later versions support <code>TYPE_FORWARD_ONLY</code>
+ and <code>TYPE_SCROLL_INSENSITIVE</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetType()" title="class or interface in java.sql">getResultSetType</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+ <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+ <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+   for JDBCStatement)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clearBatch()"><!-- --></A><H3>
+clearBatch</H3>
+<PRE>
+public void <B>clearBatch</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Empties this <code>Statement</code> object's current list of
+ SQL commands.
+ <P>
+ (JDBC4 clarification:) <p>
+ <B>NOTE:</B>  Support of an ability to batch updates is optional.
+ <!-- start generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 1.7.2, this feature is supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#clearBatch()" title="class or interface in java.sql">clearBatch</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+  this method is called on a closed <code>Statement</code> or the
+ driver does not support batch updates<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+   for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#addBatch()"><CODE>addBatch()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConnection()"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the <code>Connection</code> object
+ that produced this <code>Statement</code> object.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getConnection()" title="class or interface in java.sql">getConnection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the connection that produced this statement
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+    for JDBCStatement)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setPoolable(boolean)"><!-- --></A><H3>
+setPoolable</H3>
+<PRE>
+public void <B>setPoolable</B>(boolean&nbsp;poolable)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Requests that a <code>Statement</code> be pooled or not pooled.  The value
+ specified is a hint to the statement pool implementation indicating
+ whether the application wants the statement to be pooled.  It is up to
+ the statement pool manager as to whether the hint is used.
+ <p>
+ The poolable value of a statement is applicable to both internal
+ statement caches implemented by the driver and external statement caches
+ implemented by application servers and other applications.
+ <p>
+ By default, a <code>Statement</code> is not poolable when created, and
+ a <code>PreparedStatement</code> and <code>CallableStatement</code>
+ are poolable when created.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setPoolable(boolean)" title="class or interface in java.sql">setPoolable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>poolable</CODE> - requests that the statement be pooled if true and
+                                          that the statement not be pooled if false
+ <p>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if this method is called on a closed
+ <code>Statement</code>
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6 Build 81, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isPoolable()"><!-- --></A><H3>
+isPoolable</H3>
+<PRE>
+public boolean <B>isPoolable</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns a  value indicating whether the <code>Statement</code>
+ is poolable or not.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#isPoolable()" title="class or interface in java.sql">isPoolable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the <code>Statement</code>
+ is poolable; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if this method is called on a closed
+ <code>Statement</code>
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6 Build 81, HSQLDB 2.0
+ <p></DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html#setPoolable(boolean)"><CODE>setPoolable(boolean)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap(java.lang.Class)"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public &lt;T&gt; T <B>unwrap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+
+ If the receiver implements the interface then the result is the receiver
+ or a proxy for the receiver. If the receiver is a wrapper
+ and the wrapped object implements the interface then the result is the
+ wrapped object or a proxy for the wrapped object. Otherwise return the
+ the result of calling <code>unwrap</code> recursively on the wrapped object
+ or a proxy for that result. If the receiver is not a
+ wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - A Class defining an interface that the result must implement.
+<DT><B>Returns:</B><DD>an object that implements the interface. May be a proxy for the actual implementing object.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - If no object found that implements the interface<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWrapperFor(java.lang.Class)"><!-- --></A><H3>
+isWrapperFor</H3>
+<PRE>
+public boolean <B>isWrapperFor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does. Returns false otherwise. If this implements the interface then return true,
+ else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+ object. If this does not implement the interface and is not a wrapper, return false.
+ This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+ callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+ returns true then calling <code>unwrap</code> with the same argument should succeed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - a Class defining an interface.
+<DT><B>Returns:</B><DD>true if this implements the interface or directly or indirectly wraps an object that does.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while determining whether this is a wrapper
+ for an object with the given interface.<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCPreparedStatement.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCPreparedStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCPreparedStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCResultSet.html b/doc/apidocs/org/hsqldb/jdbc/JDBCResultSet.html
new file mode 100644
index 0000000..2330776
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCResultSet.html
@@ -0,0 +1,9984 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCResultSet (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCResultSet (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCResultSet.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCResultSet.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCResultSet.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCResultSet</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCResultSet</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCResultSet</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></DL>
+</PRE>
+
+<P>
+<!-- start generic documentation -->
+ A table of data representing a database result set, which
+ is usually generated by executing a statement that queries the database.
+
+ <P>A <code>ResultSet</code> object  maintains a cursor pointing
+ to its current row of data.  Initially the cursor is positioned
+ before the first row. The <code>next</code> method moves the
+ cursor to the next row, and because it returns <code>false</code>
+ when there are no more rows in the <code>ResultSet</code> object,
+ it can be used in a <code>while</code> loop to iterate through
+ the result set.
+ <P>
+ A default <code>ResultSet</code> object is not updatable and
+ has a cursor that moves forward only.  Thus, you can
+ iterate through it only once and only from the first row to the
+ last row. It is possible to
+ produce <code>ResultSet</code> objects that are scrollable and/or
+ updatable.  The following code fragment, in which <code>con</code>
+ is a valid <code>Connection</code> object, illustrates how to make
+ a result set that is scrollable and insensitive to updates by others, and
+ that is updatable. See <code>ResultSet</code> fields for other
+ options.
+ <PRE>
+
+       Statement stmt = con.createStatement(
+                                      ResultSet.TYPE_SCROLL_INSENSITIVE,
+                                      ResultSet.CONCUR_UPDATABLE);
+       ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
+       // rs will be scrollable, will not show changes made by others,
+       // and will be updatable
+
+ </PRE>
+ The <code>ResultSet</code> interface provides
+ <i>getter</i> methods (<code>getBoolean</code>, <code>getLong</code>, and so on)
+ for retrieving column values from the current row.
+ Values can be retrieved using either the index number of the
+ column or the name of the column.  In general, using the
+ column index will be more efficient.  Columns are numbered from 1.
+ For maximum portability, result set columns within each row should be
+ read in left-to-right order, and each column should be read only once.
+
+ <P>For the getter methods, a JDBC driver attempts
+ to convert the underlying data to the Java type specified in the
+ getter method and returns a suitable Java value.  The JDBC specification
+ has a table showing the allowable mappings from SQL types to Java types
+ that can be used by the <code>ResultSet</code> getter methods.
+ <P>
+ <P>Column names used as input to getter methods are case
+ insensitive.  When a getter method is called  with
+ a column name and several columns have the same name,
+ the value of the first matching column will be returned.
+ The column name option is
+ designed to be used when column names are used in the SQL
+ query that generated the result set.
+ For columns that are NOT explicitly named in the query, it
+ is best to use column numbers. (JDBC4 clarification:) If column names are used, the
+ programmer should take care to guarantee that they uniquely refer to
+ the intended columns, which can be assured with the SQL <i>AS</i> clause.
+ <P>
+ A set of updater methods were added to this interface
+ in the JDBC 2.0 API (Java<sup><font size=-2>TM</font></sup> 2 SDK,
+ Standard Edition, version 1.2). The comments regarding parameters
+ to the getter methods also apply to parameters to the
+ updater methods.
+ <P>
+ The updater methods may be used in two ways:
+ <ol>
+ <li>to update a column value in the current row.  In a scrollable
+     <code>ResultSet</code> object, the cursor can be moved backwards
+     and forwards, to an absolute position, or to a position
+     relative to the current row.
+     The following code fragment updates the <code>NAME</code> column
+     in the fifth row of the <code>ResultSet</code> object
+     <code>rs</code> and then uses the method <code>updateRow</code>
+     to update the data source table from which <code>rs</code> was derived.
+ <PRE>
+
+       rs.absolute(5); // moves the cursor to the fifth row of rs
+       rs.updateString("NAME", "AINSWORTH"); // updates the
+          // <code>NAME</code> column of row 5 to be <code>AINSWORTH</code>
+       rs.updateRow(); // updates the row in the data source
+
+ </PRE>
+ </li>
+ <li>to insert column values into the insert row.  An updatable
+     <code>ResultSet</code> object has a special row associated with
+     it that serves as a staging area for building a row to be inserted.
+     The following code fragment moves the cursor to the insert row, builds
+     a three-column row, and inserts it into <code>rs</code> and into
+     the data source table using the method <code>insertRow</code>.
+ <PRE>
+
+       rs.moveToInsertRow(); // moves cursor to the insert row
+       rs.updateString(1, "AINSWORTH"); // updates the
+          // first column of the insert row to be <code>AINSWORTH</code>
+       rs.updateInt(2,35); // updates the second column to be <code>35</code>
+       rs.updateBoolean(3, true); // updates the third column to <code>true</code>
+       rs.insertRow();
+       rs.moveToCurrentRow();
+
+ </PRE>
+ </li>
+ </ol>
+ <P>A <code>ResultSet</code> object is automatically closed when the
+ <code>Statement</code> object that
+ generated it is closed, re-executed, or used
+ to retrieve the next result from a sequence of multiple results.
+
+ <P>The number, types and properties of a <code>ResultSet</code>
+ object's columns are provided by the <code>ResulSetMetaData</code>
+ object returned by the <code>ResultSet.getMetaData</code> method.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ A <code>ResultSet</code> object generated by HSQLDB is by default of
+ <code>ResultSet.TYPE_FORWARD_ONLY</code> (as is standard JDBC behavior)
+ and does not allow the use of absolute and relative positioning
+ methods.  If a statement is created with:<p>
+
+ <pre class="JavaCodeExample">
+ Statement stmt = conn.<b>createStatement</b>(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+ </pre>
+
+ then the <code>ResultSet</code> objects it produces support
+ using all of  the absolute and relative positioning methods of JDBC2
+ to set the position of the current row, for example:<p>
+
+ <pre class="JavaCodeExample">
+ rs.<b>absolute</b>(<span class="JavaNumericLiteral">5</span>);
+ String fifthRowValue = rs.<b>getString</b>(<span class="JavaNumericLiteral">1</span>);
+ rs.<b>relative</b>(<span class="JavaNumericLiteral">4</span>);
+ String ninthRowValue = rs.<b>getString</b>(<span class="JavaNumericLiteral">1</span>);
+ </pre>
+
+ Note: An HSQLDB <code>ResultSet</code> object persists, even after its
+ connection is closed.  This is regardless of the operational mode of
+ the <CODE>Database</CODE> from which it came.  That is, they
+ persist whether originating from a <code>Server</code>,
+ <code>WebServer</code> or in-process mode <code>Database.</code>
+ <p>
+
+ From HSQLDB 2.0, there is full support for updatable result sets.
+ Supported methods
+ include all updateXXX methods for the supported types, as well as the
+ <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#insertRow()"><CODE>insertRow()</CODE></A>,
+ <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateRow()"><CODE>updateRow()</CODE></A>, <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#deleteRow()"><CODE>deleteRow()</CODE></A>, <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#moveToInsertRow()"><CODE>moveToInsertRow()</CODE></A>
+ methods.<p>
+
+ The Statement must be created with ResultSet.CONCUR_UPDATABLE instead of
+ CONCUR_READ_ONLY.<p>
+
+ Updatability of a result set follows the SQL standards. Some or all columns
+ of an updatable result set can be updated. The current row in such result sets
+ can be deleted using the <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#deleteRow()"><CODE>deleteRow()</CODE></A> method. Some updatable result set
+ can also be inserted into and support <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#moveToInsertRow()"><CODE>moveToInsertRow()</CODE></A>.<p>
+
+ A result set is updatable if the SELECT statement
+ is updatable. This includes SELECT from TABLE and updatable VIEW objects.
+ An updatable SELECT statement has a single uderlying table or view.
+ HSQLDB supports both scrollable and forward-only result sets for updatability.
+
+ <pre class="JavaCodeExample">
+ -- In the SELECT below, columns A and B are updatable, any row can be
+ -- deleted, but it is not insertable-into as column C is not directly from
+ -- the table.
+ SELECT A, B, A + B AS C FROM T WHERE ...
+
+ -- The SELECT below can be insertable-into so long as other columns of the
+ -- table that do not appear in the SELECT list have a default value.
+ SELECT A, B FROM T WHERE ...
+ </pre>
+
+ <b>JRE 1.1.x Notes:</b> <p>
+
+ In general, JDBC 2 support requires Java 1.2 and above, and JDBC 3 requires
+ Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ versions of JDBC depends on the JDK version used for compiling and building
+ HSQLDB.<p>
+
+ Since 1.7.0, it is possible to build the product so that
+ all JDBC 2 methods can be called while executing under the version 1.1.x
+ <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ However, some of these method calls require <code>int</code> values that
+ are defined only in the JDBC 2 or greater version of the
+ <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A> interface.  For this reason, when the
+ product is compiled under JDK 1.1.x, these values are defined here, in this
+ class. <p>
+
+ In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ to them in parameter specifications and return value comparisons,
+ respectively, as follows: <p>
+
+ <pre class="JavaCodeExample">
+ JDBCResultSet.FETCH_FORWARD
+ JDBCResultSet.TYPE_FORWARD_ONLY
+ JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ JDBCResultSet.CONCUR_READ_ONLY
+ // etc.
+ </pre>
+
+ However, please note that code written in such a manner will not be
+ compatible for use with other JDBC 2 drivers, since they expect and use
+ <code>ResultSet</code>, rather than <code>JDBCResultSet</code>.  Also
+ note, this feature is offered solely as a convenience to developers
+ who must work under JDK 1.1.x due to operating constraints, yet wish to
+ use some of the more advanced features available under the JDBC 2
+ specification.<p>
+
+ (fredt@users) <br>
+ (boucherb@users)<p>
+
+ </div>
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.9.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeQuery(java.lang.String)"><CODE>JDBCStatement.executeQuery(java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSet()"><CODE>JDBCStatement.getResultSet()</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSetMetaData</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#CLOSE_CURSORS_AT_COMMIT">CLOSE_CURSORS_AT_COMMIT</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#CONCUR_READ_ONLY">CONCUR_READ_ONLY</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#CONCUR_UPDATABLE">CONCUR_UPDATABLE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#FETCH_FORWARD">FETCH_FORWARD</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#FETCH_REVERSE">FETCH_REVERSE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#FETCH_UNKNOWN">FETCH_UNKNOWN</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#HOLD_CURSORS_OVER_COMMIT">HOLD_CURSORS_OVER_COMMIT</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;org.hsqldb.result.Result</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#result">result</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The underlying result.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#TYPE_FORWARD_ONLY">TYPE_FORWARD_ONLY</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#TYPE_SCROLL_INSENSITIVE">TYPE_SCROLL_INSENSITIVE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#TYPE_SCROLL_SENSITIVE">TYPE_SCROLL_SENSITIVE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copy of java.sql.ResultSet constant, for JDK 1.1 clients.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#JDBCResultSet(org.hsqldb.jdbc.JDBCConnection, org.hsqldb.jdbc.JDBCStatementBase, org.hsqldb.result.Result, org.hsqldb.result.ResultMetaData)">JDBCResultSet</A></B>(<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;conn,
+              org.hsqldb.jdbc.JDBCStatementBase&nbsp;s,
+              org.hsqldb.result.Result&nbsp;r,
+              org.hsqldb.result.ResultMetaData&nbsp;metaData)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new <code>JDBCResultSet</code> object using the specified
+ navigator and <code>org.hsqldb.result.ResultMetaData</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#JDBCResultSet(org.hsqldb.jdbc.JDBCConnection, org.hsqldb.result.Result, org.hsqldb.result.ResultMetaData)">JDBCResultSet</A></B>(<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;conn,
+              org.hsqldb.result.Result&nbsp;r,
+              org.hsqldb.result.ResultMetaData&nbsp;metaData)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#absolute(int)">absolute</A></B>(int&nbsp;row)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor to the given row number in
+ this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#afterLast()">afterLast</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor to the end of
+ this <code>ResultSet</code> object, just after the
+ last row.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#beforeFirst()">beforeFirst</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor to the front of
+ this <code>ResultSet</code> object, just before the
+ first row.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#cancelRowUpdates()">cancelRowUpdates</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cancels the updates made to the current row in this
+ <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#clearWarnings()">clearWarnings</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clears all warnings reported on this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#close()">close</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Releases this <code>ResultSet</code> object's database and
+ JDBC resources immediately instead of waiting for
+ this to happen when it is automatically closed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#deleteRow()">deleteRow</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Deletes the current row from this <code>ResultSet</code> object
+ and from the underlying database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#findColumn(java.lang.String)">findColumn</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Maps the given <code>ResultSet</code> column label to its
+ <code>ResultSet</code> column index.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#first()">first</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor to the first row in
+ this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getArray(int)">getArray</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Array</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getArray(java.lang.String)">getArray</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Array</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getAsciiStream(int)">getAsciiStream</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a stream of ASCII characters.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getAsciiStream(java.lang.String)">getAsciiStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a stream of
+ ASCII characters.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(int)">getBigDecimal</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.math.BigDecimal</code> with full precision.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(int, int)">getBigDecimal</A></B>(int&nbsp;columnIndex,
+              int&nbsp;scale)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>by java.sun.com as of JDK 1.2</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(java.lang.String)">getBigDecimal</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.math.BigDecimal</code> with full precision.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBigDecimal(java.lang.String, int)">getBigDecimal</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+              int&nbsp;scale)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>by java.sun.com as of JDK 1.2</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBinaryStream(int)">getBinaryStream</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a  stream of
+ uninterpreted bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBinaryStream(java.lang.String)">getBinaryStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a stream of uninterpreted
+ <code>byte</code>s.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBlob(int)">getBlob</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Blob</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBlob(java.lang.String)">getBlob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Blob</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBoolean(int)">getBoolean</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>boolean</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBoolean(java.lang.String)">getBoolean</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>boolean</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getByte(int)">getByte</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getByte(java.lang.String)">getByte</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBytes(int)">getBytes</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> array in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getBytes(java.lang.String)">getBytes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> array in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getCharacterStream(int)">getCharacterStream</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getCharacterStream(java.lang.String)">getCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getClob(int)">getClob</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Clob</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getClob(java.lang.String)">getClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Clob</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getConcurrency()">getConcurrency</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the concurrency mode of this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getCursorName()">getCursorName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the name of the SQL cursor used by this <code>ResultSet</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getDate(int)">getDate</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Date</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getDate(int, java.util.Calendar)">getDate</A></B>(int&nbsp;columnIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getDate(java.lang.String)">getDate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Date</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getDate(java.lang.String, java.util.Calendar)">getDate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;double</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getDouble(int)">getDouble</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>double</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;double</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getDouble(java.lang.String)">getDouble</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>double</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getFetchDirection()">getFetchDirection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the fetch direction for this
+ <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getFetchSize()">getFetchSize</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the fetch size for this
+ <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;float</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getFloat(int)">getFloat</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>float</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;float</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getFloat(java.lang.String)">getFloat</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>float</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getHoldability()">getHoldability</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the holdability of this <code>ResultSet</code> object</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getInt(int)">getInt</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ an <code>int</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getInt(java.lang.String)">getInt</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ an <code>int</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getLong(int)">getLong</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>long</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getLong(java.lang.String)">getLong</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>long</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getMetaData()">getMetaData</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the  number, types and properties of
+ this <code>ResultSet</code> object's columns.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getNCharacterStream(int)">getNCharacterStream</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getNCharacterStream(java.lang.String)">getNCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getNClob(int)">getNClob</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>NClob</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getNClob(java.lang.String)">getNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>NClob</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getNString(int)">getNString</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getNString(java.lang.String)">getNString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getObject(int)">getObject</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getObject(int, java.util.Map)">getObject</A></B>(int&nbsp;columnIndex,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Object</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getObject(java.lang.String)">getObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getObject(java.lang.String, java.util.Map)">getObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&nbsp;map)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Object</code>
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getRef(int)">getRef</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Ref</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getRef(java.lang.String)">getRef</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Ref</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getRow()">getRow</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the current row number.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getRowId(int)">getRowId</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row of this
+ <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
+ programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getRowId(java.lang.String)">getRowId</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row of this
+ <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
+ programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;short</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getShort(int)">getShort</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>short</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;short</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getShort(java.lang.String)">getShort</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>short</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getSQLXML(int)">getSQLXML</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in  the current row of
+  this <code>ResultSet</code> as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getSQLXML(java.lang.String)">getSQLXML</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in  the current row of
+  this <code>ResultSet</code> as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getStatement()">getStatement</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>Statement</code> object that produced this
+ <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getString(int)">getString</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getString(java.lang.String)">getString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getTime(int)">getTime</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Time</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getTime(int, java.util.Calendar)">getTime</A></B>(int&nbsp;columnIndex,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Time</code>
+ object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getTime(java.lang.String)">getTime</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Time</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getTime(java.lang.String, java.util.Calendar)">getTime</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Time</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getTimestamp(int)">getTimestamp</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Timestamp</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getTimestamp(int, java.util.Calendar)">getTimestamp</A></B>(int&nbsp;columnIndex,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getTimestamp(java.lang.String)">getTimestamp</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Timestamp</code> object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getTimestamp(java.lang.String, java.util.Calendar)">getTimestamp</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
+ in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getType()">getType</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the type of this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getUnicodeStream(int)">getUnicodeStream</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>use <code>getCharacterStream</code> in place of
+              <code>getUnicodeStream</code></I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getUnicodeStream(java.lang.String)">getUnicodeStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>use <code>getCharacterStream</code> instead</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getURL(int)">getURL</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.net.URL</code>
+ object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getURL(java.lang.String)">getURL</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.net.URL</code>
+ object in the Java programming language.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getWarnings()">getWarnings</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the first warning reported by calls on this
+ <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#insertRow()">insertRow</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Inserts the contents of the insert row into this
+ <code>ResultSet</code> object and into the database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#isAfterLast()">isAfterLast</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the cursor is after the last row in
+ this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#isBeforeFirst()">isBeforeFirst</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the cursor is before the first row in
+ this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#isClosed()">isClosed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this <code>ResultSet</code> object has been closed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#isFirst()">isFirst</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the cursor is on the first row of
+ this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#isLast()">isLast</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the cursor is on the last row of
+ this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#isWrapperFor(java.lang.Class)">isWrapperFor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#last()">last</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor to the last row in
+ this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#moveToCurrentRow()">moveToCurrentRow</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor to the remembered cursor position, usually the
+ current row.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#moveToInsertRow()">moveToInsertRow</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor to the insert row.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#next()">next</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor froward one row from its current position.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#previous()">previous</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor to the previous row in this
+ <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#refreshRow()">refreshRow</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Refreshes the current row with its most recent value in
+ the database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#relative(int)">relative</A></B>(int&nbsp;rows)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves the cursor a relative number of rows, either positive or negative.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#rowDeleted()">rowDeleted</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether a row has been deleted.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#rowInserted()">rowInserted</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the current row has had an insertion.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#rowUpdated()">rowUpdated</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the current row has been updated.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#setFetchDirection(int)">setFetchDirection</A></B>(int&nbsp;direction)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gives a hint as to the direction in which the rows in this
+ <code>ResultSet</code> object will be processed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#setFetchSize(int)">setFetchSize</A></B>(int&nbsp;rows)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for this
+ <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T&gt; T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#unwrap(java.lang.Class)">unwrap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateArray(int, java.sql.Array)">updateArray</A></B>(int&nbsp;columnIndex,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Array</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateArray(java.lang.String, java.sql.Array)">updateArray</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Array</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(int, java.io.InputStream)">updateAsciiStream</A></B>(int&nbsp;columnIndex,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an ascii stream value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(int, java.io.InputStream, int)">updateAsciiStream</A></B>(int&nbsp;columnIndex,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                  int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(int, java.io.InputStream, long)">updateAsciiStream</A></B>(int&nbsp;columnIndex,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                  long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(java.lang.String, java.io.InputStream)">updateAsciiStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an ascii stream value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(java.lang.String, java.io.InputStream, int)">updateAsciiStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                  int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateAsciiStream(java.lang.String, java.io.InputStream, long)">updateAsciiStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                  long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes..</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBigDecimal(int, java.math.BigDecimal)">updateBigDecimal</A></B>(int&nbsp;columnIndex,
+                 <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.math.BigDecimal</code>
+ value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBigDecimal(java.lang.String, java.math.BigDecimal)">updateBigDecimal</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                 <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.BigDecimal</code>
+ value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(int, java.io.InputStream)">updateBinaryStream</A></B>(int&nbsp;columnIndex,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a binary stream value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(int, java.io.InputStream, int)">updateBinaryStream</A></B>(int&nbsp;columnIndex,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                   int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(int, java.io.InputStream, long)">updateBinaryStream</A></B>(int&nbsp;columnIndex,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                   long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(java.lang.String, java.io.InputStream)">updateBinaryStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a binary stream value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(java.lang.String, java.io.InputStream, int)">updateBinaryStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                   int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBinaryStream(java.lang.String, java.io.InputStream, long)">updateBinaryStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                   long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(int, java.sql.Blob)">updateBlob</A></B>(int&nbsp;columnIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Blob</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(int, java.io.InputStream)">updateBlob</A></B>(int&nbsp;columnIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(int, java.io.InputStream, long)">updateBlob</A></B>(int&nbsp;columnIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream,
+           long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given input stream, which
+ will have the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(java.lang.String, java.sql.Blob)">updateBlob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Blob</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(java.lang.String, java.io.InputStream)">updateBlob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBlob(java.lang.String, java.io.InputStream, long)">updateBlob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream,
+           long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given input stream, which
+ will have the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBoolean(int, boolean)">updateBoolean</A></B>(int&nbsp;columnIndex,
+              boolean&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>boolean</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBoolean(java.lang.String, boolean)">updateBoolean</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+              boolean&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>boolean</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateByte(int, byte)">updateByte</A></B>(int&nbsp;columnIndex,
+           byte&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>byte</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateByte(java.lang.String, byte)">updateByte</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           byte&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>byte</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBytes(int, byte[])">updateBytes</A></B>(int&nbsp;columnIndex,
+            byte[]&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>byte</code> array value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateBytes(java.lang.String, byte[])">updateBytes</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+            byte[]&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a byte array value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(int, java.io.Reader)">updateCharacterStream</A></B>(int&nbsp;columnIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a character stream value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(int, java.io.Reader, int)">updateCharacterStream</A></B>(int&nbsp;columnIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;x,
+                      int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Updates the designated column with a character stream value, which will have
+ the specified number of (CHECKME: characters?) bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(int, java.io.Reader, long)">updateCharacterStream</A></B>(int&nbsp;columnIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;x,
+                      long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a character stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(java.lang.String, java.io.Reader)">updateCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a character stream value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(java.lang.String, java.io.Reader, int)">updateCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                      int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification)
+ Updates the designated column with a character stream value, which will have
+ the specified number of (CHECKME: characters?) bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateCharacterStream(java.lang.String, java.io.Reader, long)">updateCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                      long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a character stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateClob(int, java.sql.Clob)">updateClob</A></B>(int&nbsp;columnIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Clob</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateClob(int, java.io.Reader)">updateClob</A></B>(int&nbsp;columnIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given <code>Reader</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateClob(int, java.io.Reader, long)">updateClob</A></B>(int&nbsp;columnIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+           long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateClob(java.lang.String, java.sql.Clob)">updateClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Clob</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateClob(java.lang.String, java.io.Reader)">updateClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given <code>Reader</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateClob(java.lang.String, java.io.Reader, long)">updateClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+           long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateDate(int, java.sql.Date)">updateDate</A></B>(int&nbsp;columnIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Date</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateDate(java.lang.String, java.sql.Date)">updateDate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Date</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateDouble(int, double)">updateDouble</A></B>(int&nbsp;columnIndex,
+             double&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>double</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateDouble(java.lang.String, double)">updateDouble</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+             double&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>double</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateFloat(int, float)">updateFloat</A></B>(int&nbsp;columnIndex,
+            float&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>float</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateFloat(java.lang.String, float)">updateFloat</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+            float&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>float </code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateInt(int, int)">updateInt</A></B>(int&nbsp;columnIndex,
+          int&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an <code>int</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateInt(java.lang.String, int)">updateInt</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+          int&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an <code>int</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateLong(int, long)">updateLong</A></B>(int&nbsp;columnIndex,
+           long&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>long</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateLong(java.lang.String, long)">updateLong</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           long&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>long</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNCharacterStream(int, java.io.Reader)">updateNCharacterStream</A></B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a character stream value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNCharacterStream(int, java.io.Reader, long)">updateNCharacterStream</A></B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;x,
+                       long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a character stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNCharacterStream(java.lang.String, java.io.Reader)">updateNCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a character stream value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNCharacterStream(java.lang.String, java.io.Reader, long)">updateNCharacterStream</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                       long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a character stream value, which will have
+ the specified number of bytes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(int, java.sql.NClob)">updateNClob</A></B>(int&nbsp;columnIndex,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>&nbsp;nClob)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.NClob</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(int, java.io.Reader)">updateNClob</A></B>(int&nbsp;columnIndex,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given <code>Reader</code>
+
+  The data will be read from the stream
+  as needed until end-of-stream is reached.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(int, java.io.Reader, long)">updateNClob</A></B>(int&nbsp;columnIndex,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+            long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given <code>Reader</code>
+  object, which is the given number of characters long.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(java.lang.String, java.sql.NClob)">updateNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>&nbsp;nClob)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.NClob</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(java.lang.String, java.io.Reader)">updateNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given <code>Reader</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNClob(java.lang.String, java.io.Reader, long)">updateNClob</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+            long&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNString(int, java.lang.String)">updateNString</A></B>(int&nbsp;columnIndex,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;nString)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>String</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNString(java.lang.String, java.lang.String)">updateNString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;nString)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>String</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNull(int)">updateNull</A></B>(int&nbsp;columnIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Updates the designated column with a <code>null</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateNull(java.lang.String)">updateNull</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>null</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateObject(int, java.lang.Object)">updateObject</A></B>(int&nbsp;columnIndex,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an <code>Object</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateObject(int, java.lang.Object, int)">updateObject</A></B>(int&nbsp;columnIndex,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+             int&nbsp;scaleOrLength)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an <code>Object</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateObject(java.lang.String, java.lang.Object)">updateObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an <code>Object</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateObject(java.lang.String, java.lang.Object, int)">updateObject</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+             int&nbsp;scaleOrLength)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with an <code>Object</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateRef(int, java.sql.Ref)">updateRef</A></B>(int&nbsp;columnIndex,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Ref</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateRef(java.lang.String, java.sql.Ref)">updateRef</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+          <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Ref</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateRow()">updateRow</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the underlying database with the new contents of the
+ current row of this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateRowId(int, java.sql.RowId)">updateRowId</A></B>(int&nbsp;columnIndex,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>RowId</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateRowId(java.lang.String, java.sql.RowId)">updateRowId</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+            <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>RowId</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateShort(int, short)">updateShort</A></B>(int&nbsp;columnIndex,
+            short&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>short</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateShort(java.lang.String, short)">updateShort</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+            short&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>short</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateSQLXML(int, java.sql.SQLXML)">updateSQLXML</A></B>(int&nbsp;columnIndex,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>&nbsp;xmlObject)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.SQLXML</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateSQLXML(java.lang.String, java.sql.SQLXML)">updateSQLXML</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>&nbsp;xmlObject)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.SQLXML</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateString(int, java.lang.String)">updateString</A></B>(int&nbsp;columnIndex,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>String</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateString(java.lang.String, java.lang.String)">updateString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>String</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateTime(int, java.sql.Time)">updateTime</A></B>(int&nbsp;columnIndex,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Time</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateTime(java.lang.String, java.sql.Time)">updateTime</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Time</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateTimestamp(int, java.sql.Timestamp)">updateTimestamp</A></B>(int&nbsp;columnIndex,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Timestamp</code>
+ value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#updateTimestamp(java.lang.String, java.sql.Timestamp)">updateTimestamp</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Updates the designated column with a <code>java.sql.Timestamp</code>
+ value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#wasNull()">wasNull</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reports whether
+ the last column read had a value of SQL <code>NULL</code>.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="result"><!-- --></A><H3>
+result</H3>
+<PRE>
+public org.hsqldb.result.Result <B>result</B></PRE>
+<DL>
+<DD>The underlying result.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="FETCH_FORWARD"><!-- --></A><H3>
+FETCH_FORWARD</H3>
+<PRE>
+public static final int <B>FETCH_FORWARD</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.FETCH_FORWARD">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FETCH_REVERSE"><!-- --></A><H3>
+FETCH_REVERSE</H3>
+<PRE>
+public static final int <B>FETCH_REVERSE</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.FETCH_REVERSE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FETCH_UNKNOWN"><!-- --></A><H3>
+FETCH_UNKNOWN</H3>
+<PRE>
+public static final int <B>FETCH_UNKNOWN</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.FETCH_UNKNOWN">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="TYPE_FORWARD_ONLY"><!-- --></A><H3>
+TYPE_FORWARD_ONLY</H3>
+<PRE>
+public static final int <B>TYPE_FORWARD_ONLY</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.TYPE_FORWARD_ONLY">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="TYPE_SCROLL_INSENSITIVE"><!-- --></A><H3>
+TYPE_SCROLL_INSENSITIVE</H3>
+<PRE>
+public static final int <B>TYPE_SCROLL_INSENSITIVE</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients. <p>
+
+  (JDBC4 clarification:) scrollable but generally not sensitive
+  to changes to the data that underlies the <code>ResultSet</code>.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.TYPE_SCROLL_INSENSITIVE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="TYPE_SCROLL_SENSITIVE"><!-- --></A><H3>
+TYPE_SCROLL_SENSITIVE</H3>
+<PRE>
+public static final int <B>TYPE_SCROLL_SENSITIVE</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients. <p>
+
+  (JDBC4 clarification:) scrollable and generally sensitive
+  to changes to the data that underlies the <code>ResultSet</code>.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.TYPE_SCROLL_SENSITIVE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="CONCUR_READ_ONLY"><!-- --></A><H3>
+CONCUR_READ_ONLY</H3>
+<PRE>
+public static final int <B>CONCUR_READ_ONLY</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.CONCUR_READ_ONLY">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="CONCUR_UPDATABLE"><!-- --></A><H3>
+CONCUR_UPDATABLE</H3>
+<PRE>
+public static final int <B>CONCUR_UPDATABLE</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.CONCUR_UPDATABLE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="HOLD_CURSORS_OVER_COMMIT"><!-- --></A><H3>
+HOLD_CURSORS_OVER_COMMIT</H3>
+<PRE>
+public static final int <B>HOLD_CURSORS_OVER_COMMIT</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.HOLD_CURSORS_OVER_COMMIT">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="CLOSE_CURSORS_AT_COMMIT"><!-- --></A><H3>
+CLOSE_CURSORS_AT_COMMIT</H3>
+<PRE>
+public static final int <B>CLOSE_CURSORS_AT_COMMIT</B></PRE>
+<DL>
+<DD>Copy of java.sql.ResultSet constant, for JDK 1.1 clients.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.jdbc.JDBCResultSet.CLOSE_CURSORS_AT_COMMIT">Constant Field Values</A></DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCResultSet(org.hsqldb.jdbc.JDBCConnection, org.hsqldb.jdbc.JDBCStatementBase, org.hsqldb.result.Result, org.hsqldb.result.ResultMetaData)"><!-- --></A><H3>
+JDBCResultSet</H3>
+<PRE>
+public <B>JDBCResultSet</B>(<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;conn,
+                     org.hsqldb.jdbc.JDBCStatementBase&nbsp;s,
+                     org.hsqldb.result.Result&nbsp;r,
+                     org.hsqldb.result.ResultMetaData&nbsp;metaData)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new <code>JDBCResultSet</code> object using the specified
+ navigator and <code>org.hsqldb.result.ResultMetaData</code>.
+ <p>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>conn</CODE> - JDBCConnection<DD><CODE>s</CODE> - the statement<DD><CODE>r</CODE> - the internal result form that the new
+   <code>JDBCResultSet</code> represents<DD><CODE>metaData</CODE> - the connection properties
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - when the supplied Result is of type
+   org.hsqldb.Result.ERROR</DL>
+</DL>
+<HR>
+
+<A NAME="JDBCResultSet(org.hsqldb.jdbc.JDBCConnection, org.hsqldb.result.Result, org.hsqldb.result.ResultMetaData)"><!-- --></A><H3>
+JDBCResultSet</H3>
+<PRE>
+public <B>JDBCResultSet</B>(<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;conn,
+                     org.hsqldb.result.Result&nbsp;r,
+                     org.hsqldb.result.ResultMetaData&nbsp;metaData)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="next()"><!-- --></A><H3>
+next</H3>
+<PRE>
+public boolean <B>next</B>()
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor froward one row from its current position.
+ A <code>ResultSet</code> cursor is initially positioned
+ before the first row; the first call to the method
+ <code>next</code> makes the first row the current row; the
+ second call makes the second row the current row, and so on.
+ <p>(JDBC4 clarification:)
+ When a call to the <code>next</code> method returns <code>false</code>,
+ the cursor is positioned after the last row. Any
+ invocation of a <code>ResultSet</code> method which requires a
+ current row will result in a <code>SQLException</code> being thrown.
+  If the result set type is <code>TYPE_FORWARD_ONLY</code>, it is vendor specified
+ whether their JDBC driver implementation will return <code>false</code> or
+  throw an <code>SQLException</code> on a
+ subsequent call to <code>next</code>.
+
+ <P>If an input stream is open for the current row, a call
+ to the method <code>next</code> will
+ implicitly close it. A <code>ResultSet</code> object's
+ warning chain is cleared when a new row is read.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#next()" title="class or interface in java.sql">next</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the new current row is valid;
+ <code>false</code> if there are no more rows
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="close()"><!-- --></A><H3>
+close</H3>
+<PRE>
+public void <B>close</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Releases this <code>ResultSet</code> object's database and
+ JDBC resources immediately instead of waiting for
+ this to happen when it is automatically closed.
+
+ <P>(JDBC4 clarification:)
+ The closing of a <code>ResultSet</code> object does <strong>not</strong> close the <code>Blob</code>,
+ <code>Clob</code> or <code>NClob</code> objects created by the <code>ResultSet</code>. <code>Blob</code>,
+ <code>Clob</code> or <code>NClob</code> objects remain valid for at least the duration of the
+ transaction in which they are created, unless their <code>free</code> method is invoked.
+ <p>
+ (JDBC4 clarification:)
+ When a <code>ResultSet</code> is closed, any <code>ResultSetMetaData</code>
+ instances that were created by calling the  <code>getMetaData</code>
+ method remain accessible.
+
+ <P><B>Note:</B> A <code>ResultSet</code> object
+ is automatically closed by the
+ <code>Statement</code> object that generated it when
+ that <code>Statement</code> object is closed,
+ re-executed, or is used to retrieve the next result from a
+ sequence of multiple results.
+ (JDBC4 deleted:) [A <code>ResultSet</code> object is also automatically
+ closed when it is garbage collected.]
+ <p>
+ Calling the method <code>close</code> on a <code>ResultSet</code>
+ object that is already closed is a no-op.
+ <P>
+ <p>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#close()" title="class or interface in java.sql">close</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="wasNull()"><!-- --></A><H3>
+wasNull</H3>
+<PRE>
+public boolean <B>wasNull</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Reports whether
+ the last column read had a value of SQL <code>NULL</code>.
+ Note that you must first call one of the getter methods
+ on a column to try to read its value and then call
+ the method <code>wasNull</code> to see if the value read was
+ SQL <code>NULL</code>.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#wasNull()" title="class or interface in java.sql">wasNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the last column value read was SQL
+         <code>NULL</code> and <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getString(int)"><!-- --></A><H3>
+getString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getString</B>(int&nbsp;columnIndex)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getString(int)" title="class or interface in java.sql">getString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBoolean(int)"><!-- --></A><H3>
+getBoolean</H3>
+<PRE>
+public boolean <B>getBoolean</B>(int&nbsp;columnIndex)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>boolean</code> in the Java programming language.
+
+
+ <P>(JDBC4 clarification:)
+ <P>If the designated column has a datatype of CHAR or VARCHAR
+ and contains a "0" or has a datatype of BIT, TINYINT, SMALLINT, INTEGER or BIGINT
+ and contains  a 0, a value of <code>false</code> is returned.  If the designated column has a datatype
+ of CHAR or VARCHAR
+ and contains a "1" or has a datatype of BIT, TINYINT, SMALLINT, INTEGER or BIGINT
+ and contains  a 1, a value of <code>true</code> is returned.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBoolean(int)" title="class or interface in java.sql">getBoolean</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>false</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getByte(int)"><!-- --></A><H3>
+getByte</H3>
+<PRE>
+public byte <B>getByte</B>(int&nbsp;columnIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the numeric value to the return type. If the value is
+ out of the range for the return type, an error is returned. For example,
+ this can happen if getByte() or getShort() is used to retrieve a value
+ of type INTEGER or BIGINT and the value is beyond the range covered by
+ the return type.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getByte(int)" title="class or interface in java.sql">getByte</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getShort(int)"><!-- --></A><H3>
+getShort</H3>
+<PRE>
+public short <B>getShort</B>(int&nbsp;columnIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>short</code> in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the numeric value to the return type. If the value is
+ out of the range for the return type, an error is returned. For example,
+ this can happen if getByte() or getShort() is used to retrieve a value
+ of type INTEGER or BIGINT and the value is beyond the range covered by
+ the return type.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getShort(int)" title="class or interface in java.sql">getShort</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getInt(int)"><!-- --></A><H3>
+getInt</H3>
+<PRE>
+public int <B>getInt</B>(int&nbsp;columnIndex)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ an <code>int</code> in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the numeric value to the return type. If the value is
+ out of the range for the return type, an error is returned. For example,
+ this can happen if getInt() or getLong() is used to retrieve a value
+ of type DECIMAL or NUMERIC with a large precision and the value is beyond
+ the range covered by the return type.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getInt(int)" title="class or interface in java.sql">getInt</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLong(int)"><!-- --></A><H3>
+getLong</H3>
+<PRE>
+public long <B>getLong</B>(int&nbsp;columnIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>long</code> in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the numeric value to the return type. If the value is
+ out of the range for the return type, an error is returned. For example,
+ this can happen if getInt() or getLong() is used to retrieve a value
+ of type DECIMAL or NUMERIC with a large precision and the value is beyond
+ the range covered by the return type.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getLong(int)" title="class or interface in java.sql">getLong</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFloat(int)"><!-- --></A><H3>
+getFloat</H3>
+<PRE>
+public float <B>getFloat</B>(int&nbsp;columnIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>float</code> in the Java programming language.
+ <!-- end generic documentation -->
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the numeric value to the return type. If the value is
+ out of the range for the return type, an error is returned. For example,
+ this can happen if getFloat() or getDouble() is used to retrieve a value
+ of type DECIMAL or NUMERIC with a large precision and the value is beyond
+ the range covered by the return type.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getFloat(int)" title="class or interface in java.sql">getFloat</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDouble(int)"><!-- --></A><H3>
+getDouble</H3>
+<PRE>
+public double <B>getDouble</B>(int&nbsp;columnIndex)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>double</code> in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the numeric value to the return type. If the value is
+ out of the range for the return type, an error is returned. For example,
+ this can happen if getFloat() or getDouble() is used to retrieve a value
+ of type DECIMAL or NUMERIC with a large precision and the value is beyond
+ the range covered by the return type.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getDouble(int)" title="class or interface in java.sql">getDouble</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBigDecimal(int, int)"><!-- --></A><H3>
+getBigDecimal</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A> <B>getBigDecimal</B>(int&nbsp;columnIndex,
+                                int&nbsp;scale)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>by java.sun.com as of JDK 1.2</I>
+<P>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.BigDecimal</code> in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the result and sets the scale
+ with BigDecimal.ROUND_HALF_DOWN.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBigDecimal(int, int)" title="class or interface in java.sql">getBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>scale</CODE> - the number of digits to the right of the decimal point
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBytes(int)"><!-- --></A><H3>
+getBytes</H3>
+<PRE>
+public byte[] <B>getBytes</B>(int&nbsp;columnIndex)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> array in the Java programming language.
+ The bytes represent the raw values returned by the driver.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB returns correct values for columns of binary types
+ <code>BINARY</code>, <code>BIT</code>,  <code>BLOB</code>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBytes(int)" title="class or interface in java.sql">getBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDate(int)"><!-- --></A><H3>
+getDate</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A> <B>getDate</B>(int&nbsp;columnIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Date</code> object in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getDate(int)" title="class or interface in java.sql">getDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTime(int)"><!-- --></A><H3>
+getTime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A> <B>getTime</B>(int&nbsp;columnIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Time</code> object in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getTime(int)" title="class or interface in java.sql">getTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimestamp(int)"><!-- --></A><H3>
+getTimestamp</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A> <B>getTimestamp</B>(int&nbsp;columnIndex)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Timestamp</code> object in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getTimestamp(int)" title="class or interface in java.sql">getTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAsciiStream(int)"><!-- --></A><H3>
+getAsciiStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getAsciiStream</B>(int&nbsp;columnIndex)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a stream of ASCII characters. The value can then be read in chunks from the
+ stream. This method is particularly
+ suitable for retrieving large <char>LONGVARCHAR</char> values.
+ The JDBC driver will
+ do any necessary conversion from the database format into ASCII.
+
+ <P><B>Note:</B> All the data in the returned stream must be
+ read prior to getting the value of any other column. The next
+ call to a getter method implicitly closes the stream.  Also, a
+ stream may return <code>0</code> when the method
+ <code>InputStream.available</code>
+ is called whether there is data available or not.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The limitation noted above does not apply to HSQLDB.<p>
+
+ When the column is of type CHAR and its variations, it requires no
+ conversion since it is represented internally already as a
+ Java String object. When the column is not of type CHAR and its
+ variations, the returned stream is based on a conversion to the
+ Java <code>String</code> representation of the value. In either case,
+ the obtained stream is always equivalent to a stream of the low order
+ bytes from the value's String representation. <p>
+
+ HSQLDB SQL <code>CHAR</code> and its variations are all Unicode strings
+ internally, so the recommended alternatives to this method are
+ <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getString(int)"><CODE>getString</CODE></A>,
+ <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getUnicodeStream(int)"><CODE>getUnicodeStream</CODE></A> (<b>deprecated</b>)
+ and new to 1.7.0: <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getCharacterStream(int)"><CODE>getCharacterStream</CODE></A>
+ (now prefered over the deprecated getUnicodeStream alternative).
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getAsciiStream(int)" title="class or interface in java.sql">getAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a Java input stream that delivers the database column value
+ as a stream of one-byte ASCII characters;
+ if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUnicodeStream(int)"><!-- --></A><H3>
+getUnicodeStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getUnicodeStream</B>(int&nbsp;columnIndex)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>use <code>getCharacterStream</code> in place of
+              <code>getUnicodeStream</code></I>
+<P>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ as a stream of two-byte Unicode characters. The first byte is
+ the high byte; the second byte is the low byte.
+
+ The value can then be read in chunks from the
+ stream. This method is particularly
+ suitable for retrieving large <code>LONGVARCHAR</code>values.  The
+ JDBC driver will do any necessary conversion from the database
+ format into Unicode.
+
+ <P><B>Note:</B> All the data in the returned stream must be
+ read prior to getting the value of any other column. The next
+ call to a getter method implicitly closes the stream.
+ Also, a stream may return <code>0</code> when the method
+ <code>InputStream.available</code>
+ is called, whether there is data available or not.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The limitation noted above does not apply to HSQLDB.<p>
+
+ When the column is of type CHAR and its variations, it requires no
+ conversion since it is represented internally already as
+ Java Strings. When the column is not of type CHAR and its variations,
+ the returned stream is based on a conversion to the
+ Java <code>String</code> representation of the value. In either case,
+ the obtained stream is always equivalent to a stream of
+ bytes from the value's String representation, with high-byte first.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getUnicodeStream(int)" title="class or interface in java.sql">getUnicodeStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a Java input stream that delivers the database column value
+         as a stream of two-byte Unicode characters;
+         if the value is SQL <code>NULL</code>, the value returned is
+         <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBinaryStream(int)"><!-- --></A><H3>
+getBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getBinaryStream</B>(int&nbsp;columnIndex)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a  stream of
+ uninterpreted bytes. The value can then be read in chunks from the
+ stream. This method is particularly
+ suitable for retrieving large <code>LONGVARBINARY</code> values.
+
+ <P><B>Note:</B> All the data in the returned stream must be
+ read prior to getting the value of any other column. The next
+ call to a getter method implicitly closes the stream.  Also, a
+ stream may return <code>0</code> when the method
+ <code>InputStream.available</code>
+ is called whether there is data available or not.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBinaryStream(int)" title="class or interface in java.sql">getBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a Java input stream that delivers the database column value
+         as a stream of uninterpreted bytes;
+         if the value is SQL <code>NULL</code>, the value returned is
+         <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getString(java.lang.String)"><!-- --></A><H3>
+getString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getString(java.lang.String)" title="class or interface in java.sql">getString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBoolean(java.lang.String)"><!-- --></A><H3>
+getBoolean</H3>
+<PRE>
+public boolean <B>getBoolean</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>boolean</code> in the Java programming language.
+
+ <P>(JDBC4 clarification:) If the designated column has a datatype of CHAR or VARCHAR
+ and contains a "0" or has a datatype of BIT, TINYINT, SMALLINT, INTEGER or BIGINT
+ and contains  a 0, a value of <code>false</code> is returned.  If the designated column has a datatype
+ of CHAR or VARCHAR
+ and contains a "1" or has a datatype of BIT, TINYINT, SMALLINT, INTEGER or BIGINT
+ and contains  a 1, a value of <code>true</code> is returned.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBoolean(java.lang.String)" title="class or interface in java.sql">getBoolean</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>false</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getByte(java.lang.String)"><!-- --></A><H3>
+getByte</H3>
+<PRE>
+public byte <B>getByte</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getByte(java.lang.String)" title="class or interface in java.sql">getByte</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getShort(java.lang.String)"><!-- --></A><H3>
+getShort</H3>
+<PRE>
+public short <B>getShort</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>short</code> in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getShort(java.lang.String)" title="class or interface in java.sql">getShort</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getInt(java.lang.String)"><!-- --></A><H3>
+getInt</H3>
+<PRE>
+public int <B>getInt</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ an <code>int</code> in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getInt(java.lang.String)" title="class or interface in java.sql">getInt</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLong(java.lang.String)"><!-- --></A><H3>
+getLong</H3>
+<PRE>
+public long <B>getLong</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>long</code> in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getLong(java.lang.String)" title="class or interface in java.sql">getLong</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFloat(java.lang.String)"><!-- --></A><H3>
+getFloat</H3>
+<PRE>
+public float <B>getFloat</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>float</code> in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getFloat(java.lang.String)" title="class or interface in java.sql">getFloat</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDouble(java.lang.String)"><!-- --></A><H3>
+getDouble</H3>
+<PRE>
+public double <B>getDouble</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>double</code> in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getDouble(java.lang.String)" title="class or interface in java.sql">getDouble</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>0</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBigDecimal(java.lang.String, int)"><!-- --></A><H3>
+getBigDecimal</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A> <B>getBigDecimal</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                                int&nbsp;scale)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>by java.sun.com as of JDK 1.2</I>
+<P>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.math.BigDecimal</code> in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB converts the result and sets the scale
+ with BigDecimal.ROUND_HALF_DOWN.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBigDecimal(java.lang.String, int)" title="class or interface in java.sql">getBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>scale</CODE> - the number of digits to the right of the decimal point
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBytes(java.lang.String)"><!-- --></A><H3>
+getBytes</H3>
+<PRE>
+public byte[] <B>getBytes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>byte</code> array in the Java programming language.
+ The bytes represent the raw values returned by the driver.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBytes(java.lang.String)" title="class or interface in java.sql">getBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDate(java.lang.String)"><!-- --></A><H3>
+getDate</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A> <B>getDate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Date</code> object in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getDate(java.lang.String)" title="class or interface in java.sql">getDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTime(java.lang.String)"><!-- --></A><H3>
+getTime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A> <B>getTime</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Time</code> object in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getTime(java.lang.String)" title="class or interface in java.sql">getTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimestamp(java.lang.String)"><!-- --></A><H3>
+getTimestamp</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A> <B>getTimestamp</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>java.sql.Timestamp</code> object in the Java programming language.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getTimestamp(java.lang.String)" title="class or interface in java.sql">getTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAsciiStream(java.lang.String)"><!-- --></A><H3>
+getAsciiStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getAsciiStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a stream of
+ ASCII characters. The value can then be read in chunks from the
+ stream. This method is particularly
+ suitable for retrieving large <code>LONGVARCHAR</code> values.
+ The JDBC driver will
+ do any necessary conversion from the database format into ASCII.
+
+ <P><B>Note:</B> All the data in the returned stream must be
+ read prior to getting the value of any other column. The next
+ call to a getter method implicitly closes the stream. Also, a
+ stream may return <code>0</code> when the method <code>available</code>
+ is called whether there is data available or not.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getAsciiStream(java.lang.String)" title="class or interface in java.sql">getAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>a Java input stream that delivers the database column value
+ as a stream of one-byte ASCII characters.
+ If the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getAsciiStream(int)"><CODE>getAsciiStream(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUnicodeStream(java.lang.String)"><!-- --></A><H3>
+getUnicodeStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getUnicodeStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>use <code>getCharacterStream</code> instead</I>
+<P>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a stream of two-byte
+ Unicode characters. The first byte is the high byte; the second
+ byte is the low byte.
+
+ The value can then be read in chunks from the
+ stream. This method is particularly
+ suitable for retrieving large <code>LONGVARCHAR</code> values.
+ The JDBC technology-enabled driver will
+ do any necessary conversion from the database format into Unicode.
+
+ <P><B>Note:</B> All the data in the returned stream must be
+ read prior to getting the value of any other column. The next
+ call to a getter method implicitly closes the stream.
+ Also, a stream may return <code>0</code> when the method
+ <code>InputStream.available</code> is called, whether there
+ is data available or not.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getUnicodeStream(java.lang.String)" title="class or interface in java.sql">getUnicodeStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>a Java input stream that delivers the database column value
+         as a stream of two-byte Unicode characters.
+         If the value is SQL <code>NULL</code>, the value returned
+         is <code>null</code>.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getUnicodeStream(int)"><CODE>getUnicodeStream(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBinaryStream(java.lang.String)"><!-- --></A><H3>
+getBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getBinaryStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a stream of uninterpreted
+ <code>byte</code>s.
+ The value can then be read in chunks from the
+ stream. This method is particularly
+ suitable for retrieving large <code>LONGVARBINARY</code>
+ values.
+
+ <P><B>Note:</B> All the data in the returned stream must be
+ read prior to getting the value of any other column. The next
+ call to a getter method implicitly closes the stream. Also, a
+ stream may return <code>0</code> when the method <code>available</code>
+ is called whether there is data available or not.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBinaryStream(java.lang.String)" title="class or interface in java.sql">getBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>a Java input stream that delivers the database column value
+ as a stream of uninterpreted bytes;
+ if the value is SQL <code>NULL</code>, the result is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWarnings()"><!-- --></A><H3>
+getWarnings</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A> <B>getWarnings</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the first warning reported by calls on this
+ <code>ResultSet</code> object.
+ Subsequent warnings on this <code>ResultSet</code> object
+ will be chained to the <code>SQLWarning</code> object that
+ this method returns.
+
+ <P>The warning chain is automatically cleared each time a new
+ row is read.  This method may not be called on a <code>ResultSet</code>
+ object that has been closed; doing so will cause an
+ <code>SQLException</code> to be thrown.
+ <P>
+ <B>Note:</B> This warning chain only covers warnings caused
+ by <code>ResultSet</code> methods.  Any warning caused by
+ <code>Statement</code> methods
+ (such as reading OUT parameters) will be chained on the
+ <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not produce <code>SQLWarning</code>
+ objects on any ResultSet object warning chain; this
+ method always returns <code>null</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getWarnings()" title="class or interface in java.sql">getWarnings</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the first <code>SQLWarning</code> object reported or
+         <code>null</code> if there are none
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clearWarnings()"><!-- --></A><H3>
+clearWarnings</H3>
+<PRE>
+public void <B>clearWarnings</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Clears all warnings reported on this <code>ResultSet</code> object.
+ After this method is called, the method <code>getWarnings</code>
+ returns <code>null</code> until a new warning is
+ reported for this <code>ResultSet</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not produce <code>SQLWarning</code>
+ objects on any ResultSet object warning chain; calls to this method
+ are ignored.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#clearWarnings()" title="class or interface in java.sql">clearWarnings</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCursorName()"><!-- --></A><H3>
+getCursorName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getCursorName</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the name of the SQL cursor used by this <code>ResultSet</code>
+ object.
+
+ <P>In SQL, a result table is retrieved through a cursor that is
+ named. The current row of a result set can be updated or deleted
+ using a positioned update/delete statement that references the
+ cursor name. To insure that the cursor has the proper isolation
+ level to support update, the cursor's <code>SELECT</code> statement
+ should be of the form <code>SELECT FOR UPDATE</code>. If
+ <code>FOR UPDATE</code> is omitted, the positioned updates may fail.
+
+ <P>The JDBC API supports this SQL feature by providing the name of the
+ SQL cursor used by a <code>ResultSet</code> object.
+ The current row of a <code>ResultSet</code> object
+ is also the current row of this SQL cursor.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature when the cursor has a name.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getCursorName()" title="class or interface in java.sql">getCursorName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the SQL name for this <code>ResultSet</code> object's cursor
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMetaData()"><!-- --></A><H3>
+getMetaData</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A> <B>getMetaData</B>()
+                              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the  number, types and properties of
+ this <code>ResultSet</code> object's columns.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ <B>Example:</B> <p>
+
+ The following code fragment creates a <code>ResultSet</code> object rs,
+ creates a <code>ResultSetMetaData</code> object rsmd, and uses rsmd
+ to find out how many columns rs has and whether the first column
+ in rs can be used in a <code>WHERE</code> clause. <p>
+
+ <pre class="JavaCodeExample">
+ ResultSet rs   = stmt.<b>executeQuery</b>(<span class="JavaStringLiteral">"SELECT a, b, c FROM TABLE2"</span>);
+ ResultSetMetaData rsmd = rs.<b>getMetaData</b>();<br>
+ int numberOfColumns = rsmd.<b>getColumnCount</b>();<br>
+ boolean b = rsmd.<b>isSearchable</b>(1);<br>
+ </pre>
+
+ <hr>
+
+ <B>Changes:</B> <p>
+
+ With version 2.0, the engine's SQL implementation has been
+ completely rewritten. Changes to this class and the implementation of
+ ResultSetMetaData reflect the engine's new capabilities and provide
+ more accurate information. <p>
+
+ changes to consider: <p>
+
+ <ol>
+ <li>isAutoIncrement(int) <i>always</i> returned <code>false</code></li>
+ <li>isNullable(int) returns the nullability of a real table or view
+     column in the ResultSet and returns
+     <code>columnNoNulls</code> for non-base-column ResultSet columns
+     (columns of the ResultSet that are based on expressions or
+     aggregates).</li>
+ <li>getColumnDisplaySize(int) returns correct results even for expression
+     columns.</li>
+ <li>getPrecision(int) returns the correct precision even for expression
+     columns.</li>
+ <li>getScale(int) returns the correct precision even for expression
+     columns.</li>
+ <li>getCatalogName(int) returns the catalog name of the database.</li>
+ </ol> <p>
+
+ <hr>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getMetaData()" title="class or interface in java.sql">getMetaData</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the description of this <code>ResultSet</code> object's columns
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSetMetaData</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObject(int)"><!-- --></A><H3>
+getObject</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObject</B>(int&nbsp;columnIndex)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ <p>Gets the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ an <code>Object</code> in the Java programming language.
+
+ <p>This method will return the value of the given column as a
+ Java object.  The type of the Java object will be the default
+ Java object type corresponding to the column's SQL type,
+ following the mapping for built-in types specified in the JDBC
+ specification. If the value is an SQL <code>NULL</code>,
+ the driver returns a Java <code>null</code>.
+
+ <p>This method may also be used to read database-specific
+ abstract data types.
+
+ In the JDBC 2.0 API, the behavior of method
+ <code>getObject</code> is extended to materialize
+ data of SQL user-defined types.
+ <p>
+ If <code>Connection.getTypeMap</code> does not throw a
+ <code>SQLFeatureNotSupportedException</code>,
+ then when a column contains a structured or distinct value,
+ the behavior of this method is as
+ if it were a call to: <code>getObject(columnIndex,
+ this.getStatement().getConnection().getTypeMap())</code>.
+
+ If <code>Connection.getTypeMap</code> does throw a
+ <code>SQLFeatureNotSupportedException</code>,
+ then structured values are not supported, and distinct values
+ are mapped to the default Java class as determined by the
+ underlying SQL type of the DISTINCT type.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getObject(int)" title="class or interface in java.sql">getObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>java.lang.Object</code> holding the column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObject(java.lang.String)"><!-- --></A><H3>
+getObject</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ <p>Gets the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ an <code>Object</code> in the Java programming language.
+
+ <p>This method will return the value of the given column as a
+ Java object.  The type of the Java object will be the default
+ Java object type corresponding to the column's SQL type,
+ following the mapping for built-in types specified in the JDBC
+ specification. If the value is an SQL <code>NULL</code>,
+ the driver returns a Java <code>null</code>.
+ <P>
+ This method may also be used to read database-specific
+ abstract data types.
+ <P>
+ In the JDBC 2.0 API, the behavior of the method
+ <code>getObject</code> is extended to materialize
+ data of SQL user-defined types.  When a column contains
+ a structured or distinct value, the behavior of this method is as
+ if it were a call to: <code>getObject(columnIndex,
+ this.getStatement().getConnection().getTypeMap())</code>.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getObject(java.lang.String)" title="class or interface in java.sql">getObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>a <code>java.lang.Object</code> holding the column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="findColumn(java.lang.String)"><!-- --></A><H3>
+findColumn</H3>
+<PRE>
+public int <B>findColumn</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Maps the given <code>ResultSet</code> column label to its
+ <code>ResultSet</code> column index.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.9.x, HSQLDB does an exhaustive search, backed by
+ a cache lookup (to improve performance for subsequent invocations with
+ a given input). <p>
+
+ This is in response to an observation posted here: <p>
+
+ http://sourceforge.net/forum/forum.php?thread_id=1388727&forum_id=73674<p>
+
+ Upon careful investigation of the JDBC specification and the behaviour
+ of existing JDBC drivers, there is actually nothing preventing the
+ findColumn method from doing an exhaustive search, as long as it conforms
+ to the following rules (which describe the new implementation): <p>
+
+ <ol>
+ <li> the entire search is case insensitive
+ <li> each search iteration occurs from leftmost to rightmost column,
+      returning the first match encountered
+ <li> the first pass matches only bare column labels
+ <li> the second pass matches only simple column names
+ <li> further passes conform to the identifier qualification
+      and identifier quoting rules of the engine
+ </ol>
+
+ In this implementation, the SQL tokenizer is not employed, both because
+ it does not yet correctly handle greater than two part qualification
+ and also because is is not immediately considered important to do a
+ truly exhaustive search, handling the full range of possibly mixed quoted
+ and unquoted identifier components. <p>
+
+ Instead: <p>
+ <ul>
+ <li> a third pass matches simple table-dot-column qualified names
+ <li> a fourth pass matches simple schema-dot-table-dot-column qualified column names
+ </ul>
+ </div>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#findColumn(java.lang.String)" title="class or interface in java.sql">findColumn</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column index of the given column name
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the <code>ResultSet</code> object
+ does not contain a column labeled <code>columnLabel</code>, a database access error occurs
+  or this method is called on a closed result set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream(int)"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>(int&nbsp;columnIndex)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getCharacterStream(int)" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object that contains the column
+ value; if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream(java.lang.String)"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getCharacterStream(java.lang.String)" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object that contains the column
+ value; if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBigDecimal(int)"><!-- --></A><H3>
+getBigDecimal</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A> <B>getBigDecimal</B>(int&nbsp;columnIndex)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.math.BigDecimal</code> with full precision.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBigDecimal(int)" title="class or interface in java.sql">getBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value (full precision);
+ if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBigDecimal(java.lang.String)"><!-- --></A><H3>
+getBigDecimal</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A> <B>getBigDecimal</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.math.BigDecimal</code> with full precision.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBigDecimal(java.lang.String)" title="class or interface in java.sql">getBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>the column value (full precision);
+ if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isBeforeFirst()"><!-- --></A><H3>
+isBeforeFirst</H3>
+<PRE>
+public boolean <B>isBeforeFirst</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves whether the cursor is before the first row in
+ this <code>ResultSet</code> object.
+ <p>
+ (JDBC4 Clarification:) <p>
+ <strong>Note:</strong>Support for the <code>isBeforeFirst</code> method
+ is optional for <code>ResultSet</code>s with a result
+ set type of <code>TYPE_FORWARD_ONLY</code>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#isBeforeFirst()" title="class or interface in java.sql">isBeforeFirst</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the cursor is before the first row;
+ <code>false</code> if the cursor is at any other position or the
+ result set contains no rows
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isAfterLast()"><!-- --></A><H3>
+isAfterLast</H3>
+<PRE>
+public boolean <B>isAfterLast</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves whether the cursor is after the last row in
+ this <code>ResultSet</code> object.
+ <p>
+ (JDBC4 Clarification:)<p>
+ <strong>Note:</strong>Support for the <code>isAfterLast</code> method
+ is optional for <code>ResultSet</code>s with a result
+ set type of <code>TYPE_FORWARD_ONLY</code>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#isAfterLast()" title="class or interface in java.sql">isAfterLast</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the cursor is after the last row;
+ <code>false</code> if the cursor is at any other position or the
+ result set contains no rows
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isFirst()"><!-- --></A><H3>
+isFirst</H3>
+<PRE>
+public boolean <B>isFirst</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves whether the cursor is on the first row of
+ this <code>ResultSet</code> object.
+ <p>
+ (JDBC4 Clarification:) <p>
+ <strong>Note:</strong>Support for the <code>isFirst</code> method
+ is optional for <code>ResultSet</code>s with a result
+ set type of <code>TYPE_FORWARD_ONLY</code>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#isFirst()" title="class or interface in java.sql">isFirst</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the cursor is on the first row;
+ <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isLast()"><!-- --></A><H3>
+isLast</H3>
+<PRE>
+public boolean <B>isLast</B>()
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves whether the cursor is on the last row of
+ this <code>ResultSet</code> object.
+  <strong>Note:</strong> Calling the method <code>isLast</code> may be expensive
+ because the JDBC driver
+ might need to fetch ahead one row in order to determine
+ whether the current row is the last row in the result set.
+ <p>
+ (JDBC4 Clarification:) <p>
+ <strong>Note:</strong> Support for the <code>isLast</code> method
+ is optional for <code>ResultSet</code>s with a result
+ set type of <code>TYPE_FORWARD_ONLY</code>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#isLast()" title="class or interface in java.sql">isLast</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the cursor is on the last row;
+ <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or this method is
+            called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="beforeFirst()"><!-- --></A><H3>
+beforeFirst</H3>
+<PRE>
+public void <B>beforeFirst</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor to the front of
+ this <code>ResultSet</code> object, just before the
+ first row. This method has no effect if the result set contains no rows.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#beforeFirst()" title="class or interface in java.sql">beforeFirst</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error
+ occurs, this method is called on a closed result set or the
+ result set type is <code>TYPE_FORWARD_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="afterLast()"><!-- --></A><H3>
+afterLast</H3>
+<PRE>
+public void <B>afterLast</B>()
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor to the end of
+ this <code>ResultSet</code> object, just after the
+ last row. This method has no effect if the result set contains no rows.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#afterLast()" title="class or interface in java.sql">afterLast</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error
+ occurs, this method is called on a closed result set
+ or the result set type is <code>TYPE_FORWARD_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="first()"><!-- --></A><H3>
+first</H3>
+<PRE>
+public boolean <B>first</B>()
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor to the first row in
+ this <code>ResultSet</code> object.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#first()" title="class or interface in java.sql">first</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the cursor is on a valid row;
+ <code>false</code> if there are no rows in the result set
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error
+ occurs, this method is called on a closed result set
+ or the result set type is <code>TYPE_FORWARD_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="last()"><!-- --></A><H3>
+last</H3>
+<PRE>
+public boolean <B>last</B>()
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor to the last row in
+ this <code>ResultSet</code> object.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#last()" title="class or interface in java.sql">last</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the cursor is on a valid row;
+ <code>false</code> if there are no rows in the result set
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error
+ occurs, this method is called on a closed result set
+ or the result set type is <code>TYPE_FORWARD_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRow()"><!-- --></A><H3>
+getRow</H3>
+<PRE>
+public int <B>getRow</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the current row number.  The first row is number 1, the
+ second number 2, and so on.
+ <p>
+ (JDBC4 Clarification:) <p>
+ <strong>Note:</strong>Support for the <code>getRow</code> method
+ is optional for <code>ResultSet</code>s with a result
+ set type of <code>TYPE_FORWARD_ONLY</code>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getRow()" title="class or interface in java.sql">getRow</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current row number; <code>0</code> if there is no current row
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="absolute(int)"><!-- --></A><H3>
+absolute</H3>
+<PRE>
+public boolean <B>absolute</B>(int&nbsp;row)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor to the given row number in
+ this <code>ResultSet</code> object.
+
+ <p>If the row number is positive, the cursor moves to
+ the given row number with respect to the
+ beginning of the result set.  The first row is row 1, the second
+ is row 2, and so on.
+
+ <p>If the given row number is negative, the cursor moves to
+ an absolute row position with respect to
+ the end of the result set.  For example, calling the method
+ <code>absolute(-1)</code> positions the
+ cursor on the last row; calling the method <code>absolute(-2)</code>
+ moves the cursor to the next-to-last row, and so on.
+
+ <p>An attempt to position the cursor beyond the first/last row in
+ the result set leaves the cursor before the first row or after
+ the last row.
+
+ <p><B>Note:</B> Calling <code>absolute(1)</code> is the same
+ as calling <code>first()</code>. Calling <code>absolute(-1)</code>
+ is the same as calling <code>last()</code>.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#absolute(int)" title="class or interface in java.sql">absolute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>row</CODE> - the number of the row to which the cursor should move.
+        A positive number indicates the row number counting from the
+        beginning of the result set; a negative number indicates the
+        row number counting from the end of the result set
+<DT><B>Returns:</B><DD><code>true</code> if the cursor is moved to a position in this
+ <code>ResultSet</code> object;
+ <code>false</code> if the cursor is before the first row or after the
+ last row
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error
+ occurs, this method is called on a closed result set
+ or the result set type is <code>TYPE_FORWARD_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="relative(int)"><!-- --></A><H3>
+relative</H3>
+<PRE>
+public boolean <B>relative</B>(int&nbsp;rows)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor a relative number of rows, either positive or negative.
+ Attempting to move beyond the first/last row in the
+ result set positions the cursor before/after the
+ the first/last row. Calling <code>relative(0)</code> is valid, but does
+ not change the cursor position.
+
+ <p>Note: Calling the method <code>relative(1)</code>
+ is identical to calling the method <code>next()</code> and
+ calling the method <code>relative(-1)</code> is identical
+ to calling the method <code>previous()</code>.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#relative(int)" title="class or interface in java.sql">relative</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>rows</CODE> - an <code>int</code> specifying the number of rows to
+        move from the current row; a positive number moves the cursor
+        forward; a negative number moves the cursor backward
+<DT><B>Returns:</B><DD><code>true</code> if the cursor is on a row;
+         <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,  this method
+ is called on a closed result set,
+            there is no current row, or the result set type is
+            <code>TYPE_FORWARD_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="previous()"><!-- --></A><H3>
+previous</H3>
+<PRE>
+public boolean <B>previous</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor to the previous row in this
+ <code>ResultSet</code> object.
+ <p>
+ (JDBC4 clarification:)
+ When a call to the <code>previous</code> method returns <code>false</code>,
+ the cursor is positioned before the first row.  Any invocation of a
+ <code>ResultSet</code> method which requires a current row will result in a
+ <code>SQLException</code> being thrown.
+ <p>
+ (JDBC4 clarification:)
+ If an input stream is open for the current row, a call to the method
+ <code>previous</code> will implicitly close it.  A <code>ResultSet</code>
+  object's warning change is cleared when a new row is read.
+ <p>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#previous()" title="class or interface in java.sql">previous</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>(JDBC4 clarification:) <code>true</code> if the cursor is now positioned on a valid row;
+ <code>false</code> if the cursor is positioned before the first row
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error
+ occurs; this method is called on a closed result set
+ or the result set type is <code>TYPE_FORWARD_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFetchDirection(int)"><!-- --></A><H3>
+setFetchDirection</H3>
+<PRE>
+public void <B>setFetchDirection</B>(int&nbsp;direction)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Gives a hint as to the direction in which the rows in this
+ <code>ResultSet</code> object will be processed.
+ The initial value is determined by the
+ <code>Statement</code> object
+ that produced this <code>ResultSet</code> object.
+ The fetch direction may be changed at any time.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not need this hint. However, as mandated by the JDBC standard,
+ an SQLException is thrown if the result set type is TYPE_FORWARD_ONLY
+ and a fetch direction other than FETCH_FORWARD is requested. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#setFetchDirection(int)" title="class or interface in java.sql">setFetchDirection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>direction</CODE> - an <code>int</code> specifying the suggested
+        fetch direction; one of <code>ResultSet.FETCH_FORWARD</code>,
+        <code>ResultSet.FETCH_REVERSE</code>, or
+        <code>ResultSet.FETCH_UNKNOWN</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs; this
+ method is called on a closed result set or
+ the result set type is <code>TYPE_FORWARD_ONLY</code> and the fetch
+ direction is not <code>FETCH_FORWARD</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setFetchDirection(int)"><CODE>JDBCStatement.setFetchDirection(int)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getFetchDirection()"><CODE>getFetchDirection()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFetchDirection()"><!-- --></A><H3>
+getFetchDirection</H3>
+<PRE>
+public int <B>getFetchDirection</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the fetch direction for this
+ <code>ResultSet</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not depend on fetch direction and always returns
+ <code>FETCH_FORWARD</code>, but the value has no real meaning. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getFetchDirection()" title="class or interface in java.sql">getFetchDirection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current fetch direction for this <code>ResultSet</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#setFetchDirection(int)"><CODE>setFetchDirection(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFetchSize(int)"><!-- --></A><H3>
+setFetchSize</H3>
+<PRE>
+public void <B>setFetchSize</B>(int&nbsp;rows)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for this
+ <code>ResultSet</code> object.
+ If the fetch size specified is zero, the JDBC driver
+ ignores the value and is free to make its own best guess as to what
+ the fetch size should be.  The default value is set by the
+ <code>Statement</code> object
+ that created the result set.  The fetch size may be changed at any time.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB may not build and return a result set as a
+ whole. Therefore the supplied, non-zero, fetch size value is used for
+ some ResultSet objects.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#setFetchSize(int)" title="class or interface in java.sql">setFetchSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>rows</CODE> - the number of rows to fetch
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs; this method
+ (JDBC4 Clarification:)
+ is called on a closed result set or the
+ (JDBC4 clarification:)
+ condition <code>rows >= 0 </code> is not satisfied<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#getFetchSize()"><CODE>getFetchSize()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setFetchSize(int)"><CODE>JDBCStatement.setFetchSize(int)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getFetchSize()"><CODE>JDBCStatement.getFetchSize()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFetchSize()"><!-- --></A><H3>
+getFetchSize</H3>
+<PRE>
+public int <B>getFetchSize</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the fetch size for this
+ <code>ResultSet</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB may not build and return a result set as a
+ whole. The acutal fetch size for this result set is returned.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getFetchSize()" title="class or interface in java.sql">getFetchSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current fetch size for this <code>ResultSet</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html#setFetchSize(int)"><CODE>setFetchSize(int)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getFetchSize()"><CODE>JDBCStatement.getFetchSize()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setFetchSize(int)"><CODE>JDBCStatement.setFetchSize(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getType()"><!-- --></A><H3>
+getType</H3>
+<PRE>
+public int <B>getType</B>()
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the type of this <code>ResultSet</code> object.
+ The type is determined by the <code>Statement</code> object
+ that created the result set.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB accurately
+ reports the actual runtime scrollability of this result set instance.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getType()" title="class or interface in java.sql">getType</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>ResultSet.TYPE_FORWARD_ONLY</code>,
+         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>,
+         or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConcurrency()"><!-- --></A><H3>
+getConcurrency</H3>
+<PRE>
+public int <B>getConcurrency</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the concurrency mode of this <code>ResultSet</code> object.
+ The concurrency used is determined by the
+ <code>Statement</code> object that created the result set.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports updatable result sets and accurately reports the actual
+ runtime concurrency of this result set instance.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getConcurrency()" title="class or interface in java.sql">getConcurrency</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the concurrency type, either
+         <code>ResultSet.CONCUR_READ_ONLY</code>
+         or <code>ResultSet.CONCUR_UPDATABLE</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="rowUpdated()"><!-- --></A><H3>
+rowUpdated</H3>
+<PRE>
+public boolean <B>rowUpdated</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves whether the current row has been updated.  The value returned
+ depends on whether or not the result set can detect updates.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports updatable result sets and accurately reports the actual
+ value.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#rowUpdated()" title="class or interface in java.sql">rowUpdated</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the current row is detected to
+ have been visibly updated by the owner or another; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#updatesAreDetected(int)"><CODE>JDBCDatabaseMetaData.updatesAreDetected(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="rowInserted()"><!-- --></A><H3>
+rowInserted</H3>
+<PRE>
+public boolean <B>rowInserted</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves whether the current row has had an insertion.
+ The value returned depends on whether or not this
+ <code>ResultSet</code> object can detect visible inserts.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports updatable result sets and accurately reports the actual
+ value.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#rowInserted()" title="class or interface in java.sql">rowInserted</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the current row is detected to
+ have been inserted; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#insertsAreDetected(int)"><CODE>JDBCDatabaseMetaData.insertsAreDetected(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="rowDeleted()"><!-- --></A><H3>
+rowDeleted</H3>
+<PRE>
+public boolean <B>rowDeleted</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves whether a row has been deleted.  A deleted row may leave
+ a visible "hole" in a result set.  This method can be used to
+ detect holes in a result set.  The value returned depends on whether
+ or not this <code>ResultSet</code> object can detect deletions.
+ <p>
+ (JDBC4 Clarification:) <p>
+ <strong>Note:</strong> Support for the <code>rowDeleted</code> method is optional with a result set
+ concurrency of <code>CONCUR_READ_ONLY</code>
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports updatable result sets and accurately reports the actual
+ value.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#rowDeleted()" title="class or interface in java.sql">rowDeleted</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the current row is detected to
+ have been deleted by the owner or another; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html#deletesAreDetected(int)"><CODE>JDBCDatabaseMetaData.deletesAreDetected(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNull(int)"><!-- --></A><H3>
+updateNull</H3>
+<PRE>
+public void <B>updateNull</B>(int&nbsp;columnIndex)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Updates the designated column with a <code>null</code> value.
+
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code>
+ or <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNull(int)" title="class or interface in java.sql">updateNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBoolean(int, boolean)"><!-- --></A><H3>
+updateBoolean</H3>
+<PRE>
+public void <B>updateBoolean</B>(int&nbsp;columnIndex,
+                          boolean&nbsp;x)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>boolean</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBoolean(int, boolean)" title="class or interface in java.sql">updateBoolean</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateByte(int, byte)"><!-- --></A><H3>
+updateByte</H3>
+<PRE>
+public void <B>updateByte</B>(int&nbsp;columnIndex,
+                       byte&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>byte</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateByte(int, byte)" title="class or interface in java.sql">updateByte</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateShort(int, short)"><!-- --></A><H3>
+updateShort</H3>
+<PRE>
+public void <B>updateShort</B>(int&nbsp;columnIndex,
+                        short&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>short</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateShort(int, short)" title="class or interface in java.sql">updateShort</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateInt(int, int)"><!-- --></A><H3>
+updateInt</H3>
+<PRE>
+public void <B>updateInt</B>(int&nbsp;columnIndex,
+                      int&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with an <code>int</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateInt(int, int)" title="class or interface in java.sql">updateInt</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateLong(int, long)"><!-- --></A><H3>
+updateLong</H3>
+<PRE>
+public void <B>updateLong</B>(int&nbsp;columnIndex,
+                       long&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>long</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateLong(int, long)" title="class or interface in java.sql">updateLong</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateFloat(int, float)"><!-- --></A><H3>
+updateFloat</H3>
+<PRE>
+public void <B>updateFloat</B>(int&nbsp;columnIndex,
+                        float&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>float</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateFloat(int, float)" title="class or interface in java.sql">updateFloat</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateDouble(int, double)"><!-- --></A><H3>
+updateDouble</H3>
+<PRE>
+public void <B>updateDouble</B>(int&nbsp;columnIndex,
+                         double&nbsp;x)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>double</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateDouble(int, double)" title="class or interface in java.sql">updateDouble</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBigDecimal(int, java.math.BigDecimal)"><!-- --></A><H3>
+updateBigDecimal</H3>
+<PRE>
+public void <B>updateBigDecimal</B>(int&nbsp;columnIndex,
+                             <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A>&nbsp;x)
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.math.BigDecimal</code>
+ value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBigDecimal(int, java.math.BigDecimal)" title="class or interface in java.sql">updateBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateString(int, java.lang.String)"><!-- --></A><H3>
+updateString</H3>
+<PRE>
+public void <B>updateString</B>(int&nbsp;columnIndex,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;x)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>String</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateString(int, java.lang.String)" title="class or interface in java.sql">updateString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBytes(int, byte[])"><!-- --></A><H3>
+updateBytes</H3>
+<PRE>
+public void <B>updateBytes</B>(int&nbsp;columnIndex,
+                        byte[]&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>byte</code> array value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBytes(int, byte[])" title="class or interface in java.sql">updateBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateDate(int, java.sql.Date)"><!-- --></A><H3>
+updateDate</H3>
+<PRE>
+public void <B>updateDate</B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Date</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateDate(int, java.sql.Date)" title="class or interface in java.sql">updateDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateTime(int, java.sql.Time)"><!-- --></A><H3>
+updateTime</H3>
+<PRE>
+public void <B>updateTime</B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Time</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateTime(int, java.sql.Time)" title="class or interface in java.sql">updateTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateTimestamp(int, java.sql.Timestamp)"><!-- --></A><H3>
+updateTimestamp</H3>
+<PRE>
+public void <B>updateTimestamp</B>(int&nbsp;columnIndex,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Timestamp</code>
+ value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateTimestamp(int, java.sql.Timestamp)" title="class or interface in java.sql">updateTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateAsciiStream(int, java.io.InputStream, int)"><!-- --></A><H3>
+updateAsciiStream</H3>
+<PRE>
+public void <B>updateAsciiStream</B>(int&nbsp;columnIndex,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                              int&nbsp;length)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateAsciiStream(int, java.io.InputStream, int)" title="class or interface in java.sql">updateAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBinaryStream(int, java.io.InputStream, int)"><!-- --></A><H3>
+updateBinaryStream</H3>
+<PRE>
+public void <B>updateBinaryStream</B>(int&nbsp;columnIndex,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                               int&nbsp;length)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBinaryStream(int, java.io.InputStream, int)" title="class or interface in java.sql">updateBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateCharacterStream(int, java.io.Reader, int)"><!-- --></A><H3>
+updateCharacterStream</H3>
+<PRE>
+public void <B>updateCharacterStream</B>(int&nbsp;columnIndex,
+                                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;x,
+                                  int&nbsp;length)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Updates the designated column with a character stream value, which will have
+ the specified number of (CHECKME: characters?) bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateCharacterStream(int, java.io.Reader, int)" title="class or interface in java.sql">updateCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateObject(int, java.lang.Object, int)"><!-- --></A><H3>
+updateObject</H3>
+<PRE>
+public void <B>updateObject</B>(int&nbsp;columnIndex,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+                         int&nbsp;scaleOrLength)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with an <code>Object</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <p>
+ (JDBC clarification:)
+ If the second argument is an <code>InputStream</code> then the stream must contain
+ the number of bytes specified by scaleOrLength.  If the second argument is a
+ <code>Reader</code> then the reader must contain the number of characters specified
+ by scaleOrLength. If these conditions are not true the driver will generate a
+ <code>SQLException</code> when the statement is executed.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateObject(int, java.lang.Object, int)" title="class or interface in java.sql">updateObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value<DD><CODE>scaleOrLength</CODE> - for an object of <code>java.math.BigDecimal</code> ,
+          this is the number of digits after the decimal point. For
+          Java Object types <code>InputStream</code> and <code>Reader</code>,
+          this is the length
+          of the data in the stream or reader.  For all other types,
+          this value will be ignored.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateObject(int, java.lang.Object)"><!-- --></A><H3>
+updateObject</H3>
+<PRE>
+public void <B>updateObject</B>(int&nbsp;columnIndex,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with an <code>Object</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateObject(int, java.lang.Object)" title="class or interface in java.sql">updateObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNull(java.lang.String)"><!-- --></A><H3>
+updateNull</H3>
+<PRE>
+public void <B>updateNull</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>null</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNull(java.lang.String)" title="class or interface in java.sql">updateNull</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBoolean(java.lang.String, boolean)"><!-- --></A><H3>
+updateBoolean</H3>
+<PRE>
+public void <B>updateBoolean</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                          boolean&nbsp;x)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>boolean</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBoolean(java.lang.String, boolean)" title="class or interface in java.sql">updateBoolean</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateByte(java.lang.String, byte)"><!-- --></A><H3>
+updateByte</H3>
+<PRE>
+public void <B>updateByte</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       byte&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>byte</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateByte(java.lang.String, byte)" title="class or interface in java.sql">updateByte</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateShort(java.lang.String, short)"><!-- --></A><H3>
+updateShort</H3>
+<PRE>
+public void <B>updateShort</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        short&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>short</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateShort(java.lang.String, short)" title="class or interface in java.sql">updateShort</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateInt(java.lang.String, int)"><!-- --></A><H3>
+updateInt</H3>
+<PRE>
+public void <B>updateInt</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                      int&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with an <code>int</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateInt(java.lang.String, int)" title="class or interface in java.sql">updateInt</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateLong(java.lang.String, long)"><!-- --></A><H3>
+updateLong</H3>
+<PRE>
+public void <B>updateLong</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       long&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>long</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateLong(java.lang.String, long)" title="class or interface in java.sql">updateLong</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateFloat(java.lang.String, float)"><!-- --></A><H3>
+updateFloat</H3>
+<PRE>
+public void <B>updateFloat</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        float&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>float </code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateFloat(java.lang.String, float)" title="class or interface in java.sql">updateFloat</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateDouble(java.lang.String, double)"><!-- --></A><H3>
+updateDouble</H3>
+<PRE>
+public void <B>updateDouble</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                         double&nbsp;x)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>double</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateDouble(java.lang.String, double)" title="class or interface in java.sql">updateDouble</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBigDecimal(java.lang.String, java.math.BigDecimal)"><!-- --></A><H3>
+updateBigDecimal</H3>
+<PRE>
+public void <B>updateBigDecimal</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                             <A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A>&nbsp;x)
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.BigDecimal</code>
+ value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBigDecimal(java.lang.String, java.math.BigDecimal)" title="class or interface in java.sql">updateBigDecimal</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateString(java.lang.String, java.lang.String)"><!-- --></A><H3>
+updateString</H3>
+<PRE>
+public void <B>updateString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;x)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>String</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateString(java.lang.String, java.lang.String)" title="class or interface in java.sql">updateString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBytes(java.lang.String, byte[])"><!-- --></A><H3>
+updateBytes</H3>
+<PRE>
+public void <B>updateBytes</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        byte[]&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a byte array value.
+
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code>
+ or <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBytes(java.lang.String, byte[])" title="class or interface in java.sql">updateBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateDate(java.lang.String, java.sql.Date)"><!-- --></A><H3>
+updateDate</H3>
+<PRE>
+public void <B>updateDate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A>&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Date</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateDate(java.lang.String, java.sql.Date)" title="class or interface in java.sql">updateDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateTime(java.lang.String, java.sql.Time)"><!-- --></A><H3>
+updateTime</H3>
+<PRE>
+public void <B>updateTime</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A>&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Time</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateTime(java.lang.String, java.sql.Time)" title="class or interface in java.sql">updateTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateTimestamp(java.lang.String, java.sql.Timestamp)"><!-- --></A><H3>
+updateTimestamp</H3>
+<PRE>
+public void <B>updateTimestamp</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A>&nbsp;x)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Timestamp</code>
+ value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateTimestamp(java.lang.String, java.sql.Timestamp)" title="class or interface in java.sql">updateTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateAsciiStream(java.lang.String, java.io.InputStream, int)"><!-- --></A><H3>
+updateAsciiStream</H3>
+<PRE>
+public void <B>updateAsciiStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                              int&nbsp;length)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateAsciiStream(java.lang.String, java.io.InputStream, int)" title="class or interface in java.sql">updateAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBinaryStream(java.lang.String, java.io.InputStream, int)"><!-- --></A><H3>
+updateBinaryStream</H3>
+<PRE>
+public void <B>updateBinaryStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                               int&nbsp;length)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBinaryStream(java.lang.String, java.io.InputStream, int)" title="class or interface in java.sql">updateBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateCharacterStream(java.lang.String, java.io.Reader, int)"><!-- --></A><H3>
+updateCharacterStream</H3>
+<PRE>
+public void <B>updateCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                                  int&nbsp;length)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification)
+ Updates the designated column with a character stream value, which will have
+ the specified number of (CHECKME: characters?) bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateCharacterStream(java.lang.String, java.io.Reader, int)" title="class or interface in java.sql">updateCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object containing
+        the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateObject(java.lang.String, java.lang.Object, int)"><!-- --></A><H3>
+updateObject</H3>
+<PRE>
+public void <B>updateObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x,
+                         int&nbsp;scaleOrLength)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with an <code>Object</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <p>
+ (JDBC4 Clarification:)
+ If the second argument is an <code>InputStream</code> then the stream must contain
+ the number of bytes specified by scaleOrLength.  If the second argument is a
+ <code>Reader</code> then the reader must contain the number of characters specified
+ by scaleOrLength. If these conditions are not true the driver will generate a
+ <code>SQLException</code> when the statement is executed.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateObject(java.lang.String, java.lang.Object, int)" title="class or interface in java.sql">updateObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value<DD><CODE>scaleOrLength</CODE> - for an object of <code>java.math.BigDecimal</code> ,
+          this is the number of digits after the decimal point. For
+          Java Object types <code>InputStream</code> and <code>Reader</code>,
+          this is the length
+          of the data in the stream or reader.  For all other types,
+          this value will be ignored.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateObject(java.lang.String, java.lang.Object)"><!-- --></A><H3>
+updateObject</H3>
+<PRE>
+public void <B>updateObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;x)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with an <code>Object</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateObject(java.lang.String, java.lang.Object)" title="class or interface in java.sql">updateObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="insertRow()"><!-- --></A><H3>
+insertRow</H3>
+<PRE>
+public void <B>insertRow</B>()
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Inserts the contents of the insert row into this
+ <code>ResultSet</code> object and into the database.
+ The cursor must be on the insert row when this method is called.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#insertRow()" title="class or interface in java.sql">insertRow</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>,
+ this method is called on a closed result set,
+ if this method is called when the cursor is not on the insert row,
+ or if not all of non-nullable columns in
+ the insert row have been given a non-null value
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateRow()"><!-- --></A><H3>
+updateRow</H3>
+<PRE>
+public void <B>updateRow</B>()
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the underlying database with the new contents of the
+ current row of this <code>ResultSet</code> object.
+ This method cannot be called when the cursor is on the insert row.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ After updating any values in the current row, it is not possible to
+ move the cursor position without calling this method, or alternatively
+ calling cancelRowUpdates() to abandon the row update.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateRow()" title="class or interface in java.sql">updateRow</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>;
+  this method is called on a closed result set or
+ if this method is called when the cursor is on the insert row
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="deleteRow()"><!-- --></A><H3>
+deleteRow</H3>
+<PRE>
+public void <B>deleteRow</B>()
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Deletes the current row from this <code>ResultSet</code> object
+ and from the underlying database.  This method cannot be called when
+ the cursor is on the insert row.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+
+ After a successful call to this method, the row is deleted.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#deleteRow()" title="class or interface in java.sql">deleteRow</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>;
+ this method is called on a closed result set
+ or if this method is called when the cursor is on the insert row
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="refreshRow()"><!-- --></A><H3>
+refreshRow</H3>
+<PRE>
+public void <B>refreshRow</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Refreshes the current row with its most recent value in
+ the database.  This method cannot be called when
+ the cursor is on the insert row.
+
+ <P>The <code>refreshRow</code> method provides a way for an
+ application to
+ explicitly tell the JDBC driver to refetch a row(s) from the
+ database.  An application may want to call <code>refreshRow</code> when
+ caching or prefetching is being done by the JDBC driver to
+ fetch the latest value of a row from the database.  The JDBC driver
+ may actually refresh multiple rows at once if the fetch size is
+ greater than one.
+
+ <P> All values are refetched subject to the transaction isolation
+ level and cursor sensitivity.  If <code>refreshRow</code> is called after
+ calling an updater method, but before calling
+ the method <code>updateRow</code>, then the
+ updates made to the row are lost.  Calling the method
+ <code>refreshRow</code> frequently will likely slow performance.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#refreshRow()" title="class or interface in java.sql">refreshRow</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error
+ occurs; this method is called on a closed result set;
+ the result set type is <code>TYPE_FORWARD_ONLY</code> or if this
+ method is called when the cursor is on the insert row
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method or this method is not supported for the specified result
+ set type and result set concurrency.<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="cancelRowUpdates()"><!-- --></A><H3>
+cancelRowUpdates</H3>
+<PRE>
+public void <B>cancelRowUpdates</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Cancels the updates made to the current row in this
+ <code>ResultSet</code> object.
+ This method may be called after calling an
+ updater method(s) and before calling
+ the method <code>updateRow</code> to roll back
+ the updates made to a row.  If no updates have been made or
+ <code>updateRow</code> has already been called, this method has no
+ effect.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#cancelRowUpdates()" title="class or interface in java.sql">cancelRowUpdates</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error
+            occurs; this method is called on a closed result set;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or if this method is called when the cursor is
+            on the insert row
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="moveToInsertRow()"><!-- --></A><H3>
+moveToInsertRow</H3>
+<PRE>
+public void <B>moveToInsertRow</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor to the insert row.  The current cursor position is
+ remembered while the cursor is positioned on the insert row.
+
+ The insert row is a special row associated with an updatable
+ result set.  It is essentially a buffer where a new row may
+ be constructed by calling the updater methods prior to
+ inserting the row into the result set.
+
+ Only the updater, getter,
+ and <code>insertRow</code> methods may be
+ called when the cursor is on the insert row.  All of the columns in
+ a result set must be given a value each time this method is
+ called before calling <code>insertRow</code>.
+ An updater method must be called before a
+ getter method can be called on a column value.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#moveToInsertRow()" title="class or interface in java.sql">moveToInsertRow</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs; this
+ method is called on a closed result set
+ or the result set concurrency is <code>CONCUR_READ_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="moveToCurrentRow()"><!-- --></A><H3>
+moveToCurrentRow</H3>
+<PRE>
+public void <B>moveToCurrentRow</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves the cursor to the remembered cursor position, usually the
+ current row.  This method has no effect if the cursor is not on
+ the insert row.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#moveToCurrentRow()" title="class or interface in java.sql">moveToCurrentRow</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this
+ method is called on a closed result set
+  or the result set concurrency is <code>CONCUR_READ_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStatement()"><!-- --></A><H3>
+getStatement</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A> <B>getStatement</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the <code>Statement</code> object that produced this
+ <code>ResultSet</code> object.
+ If the result set was generated some other way, such as by a
+ <code>DatabaseMetaData</code> method, this method  may return
+ <code>null</code>.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getStatement()" title="class or interface in java.sql">getStatement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the <code>Statment</code> object that produced
+ this <code>ResultSet</code> object or <code>null</code>
+ if the result set was produced some other way
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+    JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObject(int, java.util.Map)"><!-- --></A><H3>
+getObject</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObject</B>(int&nbsp;columnIndex,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&nbsp;map)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Object</code>
+ in the Java programming language.
+ If the value is an SQL <code>NULL</code>,
+ the driver returns a Java <code>null</code>.
+ This method uses the given <code>Map</code> object
+ for the custom mapping of the
+ SQL structured or distinct type that is being retrieved.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature, but ignores the map.  <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getObject(int, java.util.Map)" title="class or interface in java.sql">getObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>map</CODE> - a <code>java.util.Map</code> object that contains the mapping
+ from SQL type names to classes in the Java programming language
+<DT><B>Returns:</B><DD>an <code>Object</code> in the Java programming language
+ representing the SQL value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRef(int)"><!-- --></A><H3>
+getRef</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A> <B>getRef</B>(int&nbsp;columnIndex)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Ref</code> object
+ in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support this feature; this method always
+ throws an <code>SQLException</code> stating that the operation is not
+ supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getRef(int)" title="class or interface in java.sql">getRef</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>Ref</code> object representing an SQL <code>REF</code>
+         value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+ JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBlob(int)"><!-- --></A><H3>
+getBlob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A> <B>getBlob</B>(int&nbsp;columnIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Blob</code> object
+ in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports this feature for objects of type BLOB and BINARY.
+ The Blob returned for BINARY objects is a memory object. The Blob
+ return for BLOB objects is not held entirely in memory. Its contents are
+ fetched from the database when its getXXX() methods are called. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBlob(int)" title="class or interface in java.sql">getBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>Blob</code> object representing the SQL
+         <code>BLOB</code> value in the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getClob(int)"><!-- --></A><H3>
+getClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A> <B>getClob</B>(int&nbsp;columnIndex)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Clob</code> object
+ in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports this feature for objects of type CLOB and
+ the variations of CHAR.
+ The Clob returned for CHAR objects is a memory object. The Clob
+ return for CLOB objects is not held entirely in memory. Its contents are
+ fetched from the database when its getXXX() methods are called. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getClob(int)" title="class or interface in java.sql">getClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>Clob</code> object representing the SQL
+         <code>CLOB</code> value in the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArray(int)"><!-- --></A><H3>
+getArray</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A> <B>getArray</B>(int&nbsp;columnIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Array</code> object
+ in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From version 2.0, HSQLDB supports array types.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getArray(int)" title="class or interface in java.sql">getArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>an <code>Array</code> object representing the SQL
+         <code>ARRAY</code> value in the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObject(java.lang.String, java.util.Map)"><!-- --></A><H3>
+getObject</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>getObject</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&nbsp;map)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Object</code>
+ in the Java programming language.
+ If the value is an SQL <code>NULL</code>,
+ the driver returns a Java <code>null</code>.
+ This method uses the specified <code>Map</code> object for
+ custom mapping if appropriate.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports this feature. But the Map parameter is ignored.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getObject(java.lang.String, java.util.Map)" title="class or interface in java.sql">getObject</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>map</CODE> - a <code>java.util.Map</code> object that contains the mapping
+ from SQL type names to classes in the Java programming language
+<DT><B>Returns:</B><DD>an <code>Object</code> representing the SQL value in the
+         specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRef(java.lang.String)"><!-- --></A><H3>
+getRef</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A> <B>getRef</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Ref</code> object
+ in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, HSQLDB does not support reference types; this method
+ always throws an <code>SQLException</code> stating that the operation
+ is not supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getRef(java.lang.String)" title="class or interface in java.sql">getRef</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>a <code>Ref</code> object representing the SQL <code>REF</code>
+         value in the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBlob(java.lang.String)"><!-- --></A><H3>
+getBlob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A> <B>getBlob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Blob</code> object
+ in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports this feature for objects of type BLOB and BINARY.
+ The Blob returned for BINARY objects is a memory object. The Blob
+ return for BLOB objects is not held entirely in memory. Its contents are
+ fetched from the database when its getXXX() methods are called. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getBlob(java.lang.String)" title="class or interface in java.sql">getBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>a <code>Blob</code> object representing the SQL <code>BLOB</code>
+         value in the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getClob(java.lang.String)"><!-- --></A><H3>
+getClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A> <B>getClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>Clob</code> object
+ in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports this feature for objects of type CLOB and
+ the variations of CHAR.
+ The Clob returned for CHAR objects is a memory object. The Clob
+ return for CLOB objects is not held entirely in memory. Its contents are
+ fetched from the database when its getXXX() methods are called. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getClob(java.lang.String)" title="class or interface in java.sql">getClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>a <code>Clob</code> object representing the SQL <code>CLOB</code>
+ value in the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArray(java.lang.String)"><!-- --></A><H3>
+getArray</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A> <B>getArray</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as an <code>Array</code> object
+ in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From version 2.0, HSQLDB supports array types.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getArray(java.lang.String)" title="class or interface in java.sql">getArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+<DT><B>Returns:</B><DD>an <code>Array</code> object representing the SQL <code>ARRAY</code> value in
+         the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDate(int, java.util.Calendar)"><!-- --></A><H3>
+getDate</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A> <B>getDate</B>(int&nbsp;columnIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
+ in the Java programming language.
+ This method uses the given calendar to construct an appropriate millisecond
+ value for the date if the underlying database does not store
+ timezone information.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getDate(int, java.util.Calendar)" title="class or interface in java.sql">getDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>cal</CODE> - the <code>java.util.Calendar</code> object
+ to use in constructing the date
+<DT><B>Returns:</B><DD>the column value as a <code>java.sql.Date</code> object;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDate(java.lang.String, java.util.Calendar)"><!-- --></A><H3>
+getDate</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Date.html?is-external=true" title="class or interface in java.sql">Date</A> <B>getDate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
+ in the Java programming language.
+ This method uses the given calendar to construct an appropriate millisecond
+ value for the date if the underlying database does not store
+ timezone information.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getDate(java.lang.String, java.util.Calendar)" title="class or interface in java.sql">getDate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>cal</CODE> - the <code>java.util.Calendar</code> object
+ to use in constructing the date
+<DT><B>Returns:</B><DD>the column value as a <code>java.sql.Date</code> object;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTime(int, java.util.Calendar)"><!-- --></A><H3>
+getTime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A> <B>getTime</B>(int&nbsp;columnIndex,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Time</code>
+ object in the Java programming language.
+ This method uses the given calendar to construct an appropriate millisecond
+ value for the time if the underlying database does not store
+ timezone information.
+ <!-- end generic documentation -->
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The JDBC specification for this method is vague. HSQLDB interprets the
+ specification as follows:
+
+ <ol>
+ <li>If the SQL type of the column is WITH TIME ZONE, then the UTC value
+ of the returned java.sql.Time object is the UTC of the SQL value without
+ modification. In other words, the Calendar object is not used.</li>
+ <li>If the SQL type of the column is WITHOUT TIME ZONE, then the UTC
+ value of the returned java.sql.Time is correct for the given Calendar
+ object.</li>
+ <li>If the cal argument is null, it it ignored and the method returns
+ the same Object as the method without the Calendar parameter.</li>
+ </ol>
+ </div>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getTime(int, java.util.Calendar)" title="class or interface in java.sql">getTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>cal</CODE> - the <code>java.util.Calendar</code> object
+ to use in constructing the time
+<DT><B>Returns:</B><DD>the column value as a <code>java.sql.Time</code> object;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+   JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTime(java.lang.String, java.util.Calendar)"><!-- --></A><H3>
+getTime</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Time.html?is-external=true" title="class or interface in java.sql">Time</A> <B>getTime</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                    <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Time</code> object
+ in the Java programming language.
+ This method uses the given calendar to construct an appropriate millisecond
+ value for the time if the underlying database does not store
+ timezone information.
+ <!-- end generic documentation -->
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The JDBC specification for this method is vague. HSQLDB interprets the
+ specification as follows:
+
+ <ol>
+ <li>If the SQL type of the column is WITH TIME ZONE, then the UTC value
+ of the returned java.sql.Time object is the UTC of the SQL value without
+ modification. In other words, the Calendar object is not used.</li>
+ <li>If the SQL type of the column is WITHOUT TIME ZONE, then the UTC
+ value of the returned java.sql.Time is correct for the given Calendar
+ object.</li>
+ <li>If the cal argument is null, it it ignored and the method returns
+ the same Object as the method without the Calendar parameter.</li>
+ </ol>
+ </div>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getTime(java.lang.String, java.util.Calendar)" title="class or interface in java.sql">getTime</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>cal</CODE> - the <code>java.util.Calendar</code> object
+ to use in constructing the time
+<DT><B>Returns:</B><DD>the column value as a <code>java.sql.Time</code> object;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimestamp(int, java.util.Calendar)"><!-- --></A><H3>
+getTimestamp</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A> <B>getTimestamp</B>(int&nbsp;columnIndex,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
+ in the Java programming language.
+ This method uses the given calendar to construct an appropriate millisecond
+ value for the timestamp if the underlying database does not store
+ timezone information.
+ <!-- end generic documentation -->
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The JDBC specification for this method is vague. HSQLDB interprets the
+ specification as follows:
+
+ <ol>
+ <li>If the SQL type of the column is WITH TIME ZONE, then the UTC value
+ of the returned java.sql.Timestamp object is the UTC of the SQL value
+ without modification. In other words, the Calendar object is not used.
+ </li>
+ <li>If the SQL type of the column is WITHOUT TIME ZONE, then the
+ UTC value of the returned java.sql.Timestamp will represent the correct
+ timestamp for the time zone (including daylight saving time) of the given
+ Calendar object. </li>
+ <li>In this case, if the cal argument is null, then the default Calendar
+ of the JVM is used, which results in the same Object as one returned by the
+ getTimestamp() methods without the Calendar parameter.</li>
+ </ol>
+ </div>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getTimestamp(int, java.util.Calendar)" title="class or interface in java.sql">getTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>cal</CODE> - the <code>java.util.Calendar</code> object
+ to use in constructing the timestamp
+<DT><B>Returns:</B><DD>the column value as a <code>java.sql.Timestamp</code> object;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTimestamp(java.lang.String, java.util.Calendar)"><!-- --></A><H3>
+getTimestamp</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Timestamp.html?is-external=true" title="class or interface in java.sql">Timestamp</A> <B>getTimestamp</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html?is-external=true" title="class or interface in java.util">Calendar</A>&nbsp;cal)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
+ in the Java programming language.
+ This method uses the given calendar to construct an appropriate millisecond
+ value for the timestamp if the underlying database does not store
+ timezone information.
+ <!-- end generic documentation -->
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The JDBC specification for this method is vague. HSQLDB interprets the
+ specification as follows:
+
+ <ol>
+ <li>If the SQL type of the column is WITH TIME ZONE, then the UTC value
+ of the returned java.sql.Timestamp object is the UTC of the SQL value
+ without modification. In other words, the Calendar object is not used.
+ </li>
+ <li>If the SQL type of the column is WITHOUT TIME ZONE, then the UTC
+ value of the returned java.sql.Timestamp is correct for the given
+ Calendar object.</li>
+ <li>If the cal argument is null, it it ignored and the method returns
+ the same Object as the method without the Calendar parameter.</li>
+ </ol>
+ </div>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getTimestamp(java.lang.String, java.util.Calendar)" title="class or interface in java.sql">getTimestamp</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>cal</CODE> - the <code>java.util.Calendar</code> object
+ to use in constructing the date
+<DT><B>Returns:</B><DD>the column value as a <code>java.sql.Timestamp</code> object;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+  JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getURL(int)"><!-- --></A><H3>
+getURL</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A> <B>getURL</B>(int&nbsp;columnIndex)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.net.URL</code>
+ object in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support the datalink type; this method
+ always throws an <code>SQLException</code> stating that the operation is
+ not supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getURL(int)" title="class or interface in java.sql">getURL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the index of the column 1 is the first, 2 is the second,...
+<DT><B>Returns:</B><DD>the column value as a <code>java.net.URL</code> object;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs; this method
+ is called on a closed result set or if a URL is malformed
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getURL(java.lang.String)"><!-- --></A><H3>
+getURL</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</A> <B>getURL</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>java.net.URL</code>
+ object in the Java programming language.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support the datalink type; this method
+ always throws an <code>SQLException</code> stating that the operation is
+ not supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getURL(java.lang.String)" title="class or interface in java.sql">getURL</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column
+<DT><B>Returns:</B><DD>the column value as a <code>java.net.URL</code> object;
+ if the value is SQL <code>NULL</code>,
+ the value returned is <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occur; this method
+ is called on a closed result set or if a URL is malformed
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateRef(int, java.sql.Ref)"><!-- --></A><H3>
+updateRef</H3>
+<PRE>
+public void <B>updateRef</B>(int&nbsp;columnIndex,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A>&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Ref</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support reference types; this method
+ always throws an <code>SQLException</code> stating that the operation is
+ not supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateRef(int, java.sql.Ref)" title="class or interface in java.sql">updateRef</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateRef(java.lang.String, java.sql.Ref)"><!-- --></A><H3>
+updateRef</H3>
+<PRE>
+public void <B>updateRef</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Ref.html?is-external=true" title="class or interface in java.sql">Ref</A>&nbsp;x)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Ref</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support reference types; this method
+ always throws an <code>SQLException</code> stating that the operation is
+ not supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateRef(java.lang.String, java.sql.Ref)" title="class or interface in java.sql">updateRef</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBlob(int, java.sql.Blob)"><!-- --></A><H3>
+updateBlob</H3>
+<PRE>
+public void <B>updateBlob</B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Blob</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports this feature for columns of type BLOB.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBlob(int, java.sql.Blob)" title="class or interface in java.sql">updateBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBlob(java.lang.String, java.sql.Blob)"><!-- --></A><H3>
+updateBlob</H3>
+<PRE>
+public void <B>updateBlob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Blob</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports this feature for columns of type BLOB.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBlob(java.lang.String, java.sql.Blob)" title="class or interface in java.sql">updateBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateClob(int, java.sql.Clob)"><!-- --></A><H3>
+updateClob</H3>
+<PRE>
+public void <B>updateClob</B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Clob</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports this feature for columns of type CLOB.<p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateClob(int, java.sql.Clob)" title="class or interface in java.sql">updateClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateClob(java.lang.String, java.sql.Clob)"><!-- --></A><H3>
+updateClob</H3>
+<PRE>
+public void <B>updateClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>&nbsp;x)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Clob</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 supports this feature for columns of type CLOB.<p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateClob(java.lang.String, java.sql.Clob)" title="class or interface in java.sql">updateClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateArray(int, java.sql.Array)"><!-- --></A><H3>
+updateArray</H3>
+<PRE>
+public void <B>updateArray</B>(int&nbsp;columnIndex,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A>&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Array</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support array types; this method always
+ throws an <code>SQLException</code> stating that the operation is not
+ supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateArray(int, java.sql.Array)" title="class or interface in java.sql">updateArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateArray(java.lang.String, java.sql.Array)"><!-- --></A><H3>
+updateArray</H3>
+<PRE>
+public void <B>updateArray</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A>&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Updates the designated column with a <code>java.sql.Array</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support array types; this method always
+ throws an <code>SQLException</code> stating that the operation is not
+ supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateArray(java.lang.String, java.sql.Array)" title="class or interface in java.sql">updateArray</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRowId(int)"><!-- --></A><H3>
+getRowId</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A> <B>getRowId</B>(int&nbsp;columnIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in the current row of this
+ <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
+ programming language.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getRowId(int)" title="class or interface in java.sql">getRowId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is a SQL <code>NULL</code> the
+     value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRowId(java.lang.String)"><!-- --></A><H3>
+getRowId</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A> <B>getRowId</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in the current row of this
+ <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
+ programming language.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support the RowId type; this method always
+ throws an <code>SQLException</code> stating that the operation is not
+ supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getRowId(java.lang.String)" title="class or interface in java.sql">getRowId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column
+<DT><B>Returns:</B><DD>the column value ; if the value is a SQL <code>NULL</code> the
+     value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateRowId(int, java.sql.RowId)"><!-- --></A><H3>
+updateRowId</H3>
+<PRE>
+public void <B>updateRowId</B>(int&nbsp;columnIndex,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a <code>RowId</code> value. The updater
+ methods are used to update column values in the current row or the insert
+ row. The updater methods do not update the underlying database; instead
+ the <code>updateRow</code> or <code>insertRow</code> methods are called
+ to update the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support the RowId type; this method always
+ throws an <code>SQLException</code> stating that the operation is not
+ supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateRowId(int, java.sql.RowId)" title="class or interface in java.sql">updateRowId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second 2, ...<DD><CODE>x</CODE> - the column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateRowId(java.lang.String, java.sql.RowId)"><!-- --></A><H3>
+updateRowId</H3>
+<PRE>
+public void <B>updateRowId</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;x)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a <code>RowId</code> value. The updater
+ methods are used to update column values in the current row or the insert
+ row. The updater methods do not update the underlying database; instead
+ the <code>updateRow</code> or <code>insertRow</code> methods are called
+ to update the database.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB does not support the RowId type; this method always
+ throws an <code>SQLException</code> stating that the operation is not
+ supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateRowId(java.lang.String, java.sql.RowId)" title="class or interface in java.sql">updateRowId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>x</CODE> - the column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getHoldability()"><!-- --></A><H3>
+getHoldability</H3>
+<PRE>
+public int <B>getHoldability</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the holdability of this <code>ResultSet</code> object
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getHoldability()" title="class or interface in java.sql">getHoldability</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isClosed()"><!-- --></A><H3>
+isClosed</H3>
+<PRE>
+public boolean <B>isClosed</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this <code>ResultSet</code> object has been closed.
+ A <code>ResultSet</code> is closed if the
+ method close has been called on it, or if it is automatically closed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#isClosed()" title="class or interface in java.sql">isClosed</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if this <code>ResultSet</code> object is closed; false if it is still open
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNString(int, java.lang.String)"><!-- --></A><H3>
+updateNString</H3>
+<PRE>
+public void <B>updateNString</B>(int&nbsp;columnIndex,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;nString)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a <code>String</code> value.
+ It is intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNString(int, java.lang.String)" title="class or interface in java.sql">updateNString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second 2, ...<DD><CODE>nString</CODE> - the value for the column to be updated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; this method is called on a closed result set,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or if a database access error occurs
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNString(java.lang.String, java.lang.String)"><!-- --></A><H3>
+updateNString</H3>
+<PRE>
+public void <B>updateNString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;nString)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a <code>String</code> value.
+ It is intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNString(java.lang.String, java.lang.String)" title="class or interface in java.sql">updateNString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>nString</CODE> - the value for the column to be updated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; this method is called on a closed result set;
+ the result set concurrency is <CODE>CONCUR_READ_ONLY</code>
+  or if a database access error occurs
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNClob(int, java.sql.NClob)"><!-- --></A><H3>
+updateNClob</H3>
+<PRE>
+public void <B>updateNClob</B>(int&nbsp;columnIndex,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>&nbsp;nClob)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a <code>java.sql.NClob</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNClob(int, java.sql.NClob)" title="class or interface in java.sql">updateNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second 2, ...<DD><CODE>nClob</CODE> - the value for the column to be updated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; this method is called on a closed result set,
+ if a database access error occurs or
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNClob(java.lang.String, java.sql.NClob)"><!-- --></A><H3>
+updateNClob</H3>
+<PRE>
+public void <B>updateNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>&nbsp;nClob)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a <code>java.sql.NClob</code> value.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNClob(java.lang.String, java.sql.NClob)" title="class or interface in java.sql">updateNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>nClob</CODE> - the value for the column to be updated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; this method is called on a closed result set;
+  if a database access error occurs or
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNClob(int)"><!-- --></A><H3>
+getNClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A> <B>getNClob</B>(int&nbsp;columnIndex)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>NClob</code> object
+ in the Java programming language.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getNClob(int)" title="class or interface in java.sql">getNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>NClob</code> object representing the SQL
+         <code>NCLOB</code> value in the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; this method is called on a closed result set
+ or if a database access error occurs
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNClob(java.lang.String)"><!-- --></A><H3>
+getNClob</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A> <B>getNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a <code>NClob</code> object
+ in the Java programming language.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getNClob(java.lang.String)" title="class or interface in java.sql">getNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column
+<DT><B>Returns:</B><DD>a <code>NClob</code> object representing the SQL <code>NCLOB</code>
+ value in the specified column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; this method is called on a closed result set
+ or if a database access error occurs
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSQLXML(int)"><!-- --></A><H3>
+getSQLXML</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A> <B>getSQLXML</B>(int&nbsp;columnIndex)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in  the current row of
+  this <code>ResultSet</code> as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getSQLXML(int)" title="class or interface in java.sql">getSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSQLXML(java.lang.String)"><!-- --></A><H3>
+getSQLXML</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A> <B>getSQLXML</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in  the current row of
+  this <code>ResultSet</code> as a
+ <code>java.sql.SQLXML</code> object in the Java programming language.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getSQLXML(java.lang.String)" title="class or interface in java.sql">getSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column
+<DT><B>Returns:</B><DD>a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateSQLXML(int, java.sql.SQLXML)"><!-- --></A><H3>
+updateSQLXML</H3>
+<PRE>
+public void <B>updateSQLXML</B>(int&nbsp;columnIndex,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>&nbsp;xmlObject)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a <code>java.sql.SQLXML</code> value.
+ The updater
+ methods are used to update column values in the current row or the insert
+ row. The updater methods do not update the underlying database; instead
+ the <code>updateRow</code> or <code>insertRow</code> methods are called
+ to update the database.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateSQLXML(int, java.sql.SQLXML)" title="class or interface in java.sql">updateSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second 2, ...<DD><CODE>xmlObject</CODE> - the value for the column to be updated
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this method
+  is called on a closed result set,
+ the <code>java.xml.transform.Result</code>,
+  <code>Writer</code> or <code>OutputStream</code> has not been closed
+ for the <code>SQLXML</code> object,
+  if there is an error processing the XML value or
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>.  The <code>getCause</code> method
+  of the exception may provide a more detailed exception, for example, if the
+  stream does not contain valid XML.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateSQLXML(java.lang.String, java.sql.SQLXML)"><!-- --></A><H3>
+updateSQLXML</H3>
+<PRE>
+public void <B>updateSQLXML</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>&nbsp;xmlObject)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a <code>java.sql.SQLXML</code> value.
+ The updater
+ methods are used to update column values in the current row or the insert
+ row. The updater methods do not update the underlying database; instead
+ the <code>updateRow</code> or <code>insertRow</code> methods are called
+ to update the database.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateSQLXML(java.lang.String, java.sql.SQLXML)" title="class or interface in java.sql">updateSQLXML</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>xmlObject</CODE> - the column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs, this method
+  is called on a closed result set,
+ the <code>java.xml.transform.Result</code>,
+  <code>Writer</code> or <code>OutputStream</code> has not been closed
+ for the <code>SQLXML</code> object,
+  if there is an error processing the XML value or
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>.  The <code>getCause</code> method
+  of the exception may provide a more detailed exception, for example, if the
+  stream does not contain valid XML.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNString(int)"><!-- --></A><H3>
+getNString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getNString</B>(int&nbsp;columnIndex)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.
+ It is intended for use when
+ accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getNString(int)" title="class or interface in java.sql">getNString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNString(java.lang.String)"><!-- --></A><H3>
+getNString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getNString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as
+ a <code>String</code> in the Java programming language.
+ It is intended for use when
+ accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getNString(java.lang.String)" title="class or interface in java.sql">getNString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column
+<DT><B>Returns:</B><DD>the column value; if the value is SQL <code>NULL</code>, the
+ value returned is <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNCharacterStream(int)"><!-- --></A><H3>
+getNCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getNCharacterStream</B>(int&nbsp;columnIndex)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.
+ It is intended for use when
+ accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getNCharacterStream(int)" title="class or interface in java.sql">getNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object that contains the column
+ value; if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNCharacterStream(java.lang.String)"><!-- --></A><H3>
+getNCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getNCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the value of the designated column in the current row
+ of this <code>ResultSet</code> object as a
+ <code>java.io.Reader</code> object.
+ It is intended for use when
+ accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#getNCharacterStream(java.lang.String)" title="class or interface in java.sql">getNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column
+<DT><B>Returns:</B><DD>a <code>java.io.Reader</code> object that contains the column
+ value; if the value is SQL <code>NULL</code>, the value returned is
+ <code>null</code> in the Java programming language
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNCharacterStream(int, java.io.Reader, long)"><!-- --></A><H3>
+updateNCharacterStream</H3>
+<PRE>
+public void <B>updateNCharacterStream</B>(int&nbsp;columnIndex,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;x,
+                                   long&nbsp;length)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a character stream value, which will have
+ the specified number of bytes.   The
+ driver does the necessary conversion from Java character format to
+ the national character set in the database.
+ It is intended for use when
+ updating  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNCharacterStream(int, java.io.Reader, long)" title="class or interface in java.sql">updateNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNCharacterStream(java.lang.String, java.io.Reader, long)"><!-- --></A><H3>
+updateNCharacterStream</H3>
+<PRE>
+public void <B>updateNCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                                   long&nbsp;length)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a character stream value, which will have
+ the specified number of bytes.  The
+ driver does the necessary conversion from Java character format to
+ the national character set in the database.
+ It is intended for use when
+ updating  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNCharacterStream(java.lang.String, java.io.Reader, long)" title="class or interface in java.sql">updateNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object containing
+        the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateAsciiStream(int, java.io.InputStream, long)"><!-- --></A><H3>
+updateAsciiStream</H3>
+<PRE>
+public void <B>updateAsciiStream</B>(int&nbsp;columnIndex,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                              long&nbsp;length)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateAsciiStream(int, java.io.InputStream, long)" title="class or interface in java.sql">updateAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBinaryStream(int, java.io.InputStream, long)"><!-- --></A><H3>
+updateBinaryStream</H3>
+<PRE>
+public void <B>updateBinaryStream</B>(int&nbsp;columnIndex,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                               long&nbsp;length)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBinaryStream(int, java.io.InputStream, long)" title="class or interface in java.sql">updateBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateCharacterStream(int, java.io.Reader, long)"><!-- --></A><H3>
+updateCharacterStream</H3>
+<PRE>
+public void <B>updateCharacterStream</B>(int&nbsp;columnIndex,
+                                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;x,
+                                  long&nbsp;length)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a character stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateCharacterStream(int, java.io.Reader, long)" title="class or interface in java.sql">updateCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateAsciiStream(java.lang.String, java.io.InputStream, long)"><!-- --></A><H3>
+updateAsciiStream</H3>
+<PRE>
+public void <B>updateAsciiStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                              long&nbsp;length)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with an ascii stream value, which will have
+ the specified number of bytes..
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateAsciiStream(java.lang.String, java.io.InputStream, long)" title="class or interface in java.sql">updateAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBinaryStream(java.lang.String, java.io.InputStream, long)"><!-- --></A><H3>
+updateBinaryStream</H3>
+<PRE>
+public void <B>updateBinaryStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x,
+                               long&nbsp;length)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a binary stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBinaryStream(java.lang.String, java.io.InputStream, long)" title="class or interface in java.sql">updateBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>x</CODE> - the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateCharacterStream(java.lang.String, java.io.Reader, long)"><!-- --></A><H3>
+updateCharacterStream</H3>
+<PRE>
+public void <B>updateCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                                  long&nbsp;length)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a character stream value, which will have
+ the specified number of bytes.
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateCharacterStream(java.lang.String, java.io.Reader, long)" title="class or interface in java.sql">updateCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object containing
+        the new column value<DD><CODE>length</CODE> - the length of the stream
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBlob(int, java.io.InputStream, long)"><!-- --></A><H3>
+updateBlob</H3>
+<PRE>
+public void <B>updateBlob</B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream,
+                       long&nbsp;length)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given input stream, which
+ will have the specified number of bytes.
+ When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code>. Data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from ASCII to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBlob(int, java.io.InputStream, long)" title="class or interface in java.sql">updateBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>inputStream</CODE> - An object that contains the data to set the parameter
+ value to.<DD><CODE>length</CODE> - the number of bytes in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBlob(java.lang.String, java.io.InputStream, long)"><!-- --></A><H3>
+updateBlob</H3>
+<PRE>
+public void <B>updateBlob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream,
+                       long&nbsp;length)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given input stream, which
+ will have the specified number of bytes.
+ When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.InputStream</code>. Data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from ASCII to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBlob(java.lang.String, java.io.InputStream, long)" title="class or interface in java.sql">updateBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>inputStream</CODE> - An object that contains the data to set the parameter
+ value to.<DD><CODE>length</CODE> - the number of bytes in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateClob(int, java.io.Reader, long)"><!-- --></A><H3>
+updateClob</H3>
+<PRE>
+public void <B>updateClob</B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                       long&nbsp;length)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateClob(int, java.io.Reader, long)" title="class or interface in java.sql">updateClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateClob(java.lang.String, java.io.Reader, long)"><!-- --></A><H3>
+updateClob</H3>
+<PRE>
+public void <B>updateClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                       long&nbsp;length)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateClob(java.lang.String, java.io.Reader, long)" title="class or interface in java.sql">updateClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNClob(int, java.io.Reader, long)"><!-- --></A><H3>
+updateNClob</H3>
+<PRE>
+public void <B>updateNClob</B>(int&nbsp;columnIndex,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                        long&nbsp;length)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given <code>Reader</code>
+  object, which is the given number of characters long.
+  When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+  parameter, it may be more practical to send it via a
+  <code>java.io.Reader</code> object. The data will be read from the stream
+  as needed until end-of-file is reached.  The JDBC driver will
+  do any necessary conversion from UNICODE to the database char format.
+
+  <P><B>Note:</B> This stream object can either be a standard
+  Java stream object or your own subclass that implements the
+  standard interface.
+  <p>
+  The updater methods are used to update column values in the
+  current row or the insert row.  The updater methods do not
+  update the underlying database; instead the <code>updateRow</code> or
+  <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNClob(int, java.io.Reader, long)" title="class or interface in java.sql">updateNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second 2, ...<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+          character sets;  if the driver can detect that a data conversion
+   error could occur; this method is called on a closed result set,
+  if a database access error occurs or
+  the result set concurrency is <code>CONCUR_READ_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+  this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNClob(java.lang.String, java.io.Reader, long)"><!-- --></A><H3>
+updateNClob</H3>
+<PRE>
+public void <B>updateNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader,
+                        long&nbsp;length)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object, which is the given number of characters long.
+ When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+ parameter, it may be more practical to send it via a
+ <code>java.io.Reader</code> object. The data will be read from the stream
+ as needed until end-of-file is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <P><B>Note:</B> This stream object can either be a standard
+ Java stream object or your own subclass that implements the
+ standard interface.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNClob(java.lang.String, java.io.Reader, long)" title="class or interface in java.sql">updateNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS
+ clause.  If the SQL AS clause was not specified, then the label is the
+ name of the column<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.<DD><CODE>length</CODE> - the number of characters in the parameter data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; this method is called on a closed result set;
+  if a database access error occurs or
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNCharacterStream(int, java.io.Reader)"><!-- --></A><H3>
+updateNCharacterStream</H3>
+<PRE>
+public void <B>updateNCharacterStream</B>(int&nbsp;columnIndex,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a character stream value.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.  The
+ driver does the necessary conversion from Java character format to
+ the national character set in the database.
+ It is intended for use when
+ updating  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateNCharacterStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNCharacterStream(int, java.io.Reader)" title="class or interface in java.sql">updateNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>reader</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnIndex is not valid;
+ if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNCharacterStream(java.lang.String, java.io.Reader)"><!-- --></A><H3>
+updateNCharacterStream</H3>
+<PRE>
+public void <B>updateNCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a character stream value.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.  The
+ driver does the necessary conversion from Java character format to
+ the national character set in the database.
+ It is intended for use when
+ updating  <code>NCHAR</code>,<code>NVARCHAR</code>
+ and <code>LONGNVARCHAR</code> columns.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateNCharacterStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNCharacterStream(java.lang.String, java.io.Reader)" title="class or interface in java.sql">updateNCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object containing
+        the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnLabel is not valid;
+ if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateAsciiStream(int, java.io.InputStream)"><!-- --></A><H3>
+updateAsciiStream</H3>
+<PRE>
+public void <B>updateAsciiStream</B>(int&nbsp;columnIndex,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with an ascii stream value.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateAsciiStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateAsciiStream(int, java.io.InputStream)" title="class or interface in java.sql">updateAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnIndex is not valid;
+ if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBinaryStream(int, java.io.InputStream)"><!-- --></A><H3>
+updateBinaryStream</H3>
+<PRE>
+public void <B>updateBinaryStream</B>(int&nbsp;columnIndex,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a binary stream value.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateBinaryStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBinaryStream(int, java.io.InputStream)" title="class or interface in java.sql">updateBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnIndex is not valid;
+ if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateCharacterStream(int, java.io.Reader)"><!-- --></A><H3>
+updateCharacterStream</H3>
+<PRE>
+public void <B>updateCharacterStream</B>(int&nbsp;columnIndex,
+                                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;x)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a character stream value.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateCharacterStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateCharacterStream(int, java.io.Reader)" title="class or interface in java.sql">updateCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnIndex is not valid;
+ if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateAsciiStream(java.lang.String, java.io.InputStream)"><!-- --></A><H3>
+updateAsciiStream</H3>
+<PRE>
+public void <B>updateAsciiStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                              <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with an ascii stream value.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateAsciiStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateAsciiStream(java.lang.String, java.io.InputStream)" title="class or interface in java.sql">updateAsciiStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnLabel is not valid;
+ if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBinaryStream(java.lang.String, java.io.InputStream)"><!-- --></A><H3>
+updateBinaryStream</H3>
+<PRE>
+public void <B>updateBinaryStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;x)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a binary stream value.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateBinaryStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBinaryStream(java.lang.String, java.io.InputStream)" title="class or interface in java.sql">updateBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>x</CODE> - the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnLabel is not valid;
+ if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateCharacterStream(java.lang.String, java.io.Reader)"><!-- --></A><H3>
+updateCharacterStream</H3>
+<PRE>
+public void <B>updateCharacterStream</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                                  <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column with a character stream value.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateCharacterStream</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateCharacterStream(java.lang.String, java.io.Reader)" title="class or interface in java.sql">updateCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>reader</CODE> - the <code>java.io.Reader</code> object containing
+        the new column value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnLabel is not valid; if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBlob(int, java.io.InputStream)"><!-- --></A><H3>
+updateBlob</H3>
+<PRE>
+public void <B>updateBlob</B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given input stream. The data will be read from the stream
+ as needed until end-of-stream is reached.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateBlob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBlob(int, java.io.InputStream)" title="class or interface in java.sql">updateBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>inputStream</CODE> - An object that contains the data to set the parameter
+ value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnIndex is not valid; if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateBlob(java.lang.String, java.io.InputStream)"><!-- --></A><H3>
+updateBlob</H3>
+<PRE>
+public void <B>updateBlob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A>&nbsp;inputStream)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given input stream. The data will be read from the stream
+ as needed until end-of-stream is reached.
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+   <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateBlob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateBlob(java.lang.String, java.io.InputStream)" title="class or interface in java.sql">updateBlob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>inputStream</CODE> - An object that contains the data to set the parameter
+ value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnLabel is not valid; if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateClob(int, java.io.Reader)"><!-- --></A><H3>
+updateClob</H3>
+<PRE>
+public void <B>updateClob</B>(int&nbsp;columnIndex,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object.
+  The data will be read from the stream
+ as needed until end-of-stream is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+   <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateClob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateClob(int, java.io.Reader)" title="class or interface in java.sql">updateClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second is 2, ...<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnIndex is not valid;
+ if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateClob(java.lang.String, java.io.Reader)"><!-- --></A><H3>
+updateClob</H3>
+<PRE>
+public void <B>updateClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object.
+  The data will be read from the stream
+ as needed until end-of-stream is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateClob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateClob(java.lang.String, java.io.Reader)" title="class or interface in java.sql">updateClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnLabel is not valid; if a database access error occurs;
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+ or this method is called on a closed result set
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNClob(int, java.io.Reader)"><!-- --></A><H3>
+updateNClob</H3>
+<PRE>
+public void <B>updateNClob</B>(int&nbsp;columnIndex,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given <code>Reader</code>
+
+  The data will be read from the stream
+  as needed until end-of-stream is reached.  The JDBC driver will
+  do any necessary conversion from UNICODE to the database char format.
+
+  <p>
+  The updater methods are used to update column values in the
+  current row or the insert row.  The updater methods do not
+  update the underlying database; instead the <code>updateRow</code> or
+  <code>insertRow</code> methods are called to update the database.
+
+  <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+  it might be more efficient to use a version of
+  <code>updateNClob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNClob(int, java.io.Reader)" title="class or interface in java.sql">updateNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnIndex</CODE> - the first column is 1, the second 2, ...<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnIndex is not valid;
+ if the driver does not support national
+          character sets;  if the driver can detect that a data conversion
+   error could occur; this method is called on a closed result set,
+  if a database access error occurs or
+  the result set concurrency is <code>CONCUR_READ_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+  this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="updateNClob(java.lang.String, java.io.Reader)"><!-- --></A><H3>
+updateNClob</H3>
+<PRE>
+public void <B>updateNClob</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;columnLabel,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A>&nbsp;reader)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Updates the designated column using the given <code>Reader</code>
+ object.
+ The data will be read from the stream
+ as needed until end-of-stream is reached.  The JDBC driver will
+ do any necessary conversion from UNICODE to the database char format.
+
+ <p>
+ The updater methods are used to update column values in the
+ current row or the insert row.  The updater methods do not
+ update the underlying database; instead the <code>updateRow</code> or
+ <code>insertRow</code> methods are called to update the database.
+
+ <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+ it might be more efficient to use a version of
+ <code>updateNClob</code> which takes a length parameter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true#updateNClob(java.lang.String, java.io.Reader)" title="class or interface in java.sql">updateNClob</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnLabel</CODE> - the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column<DD><CODE>reader</CODE> - An object that contains the data to set the parameter value to.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the columnLabel is not valid; if the driver does not support national
+         character sets;  if the driver can detect that a data conversion
+  error could occur; this method is called on a closed result set;
+  if a database access error occurs or
+ the result set concurrency is <code>CONCUR_READ_ONLY</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap(java.lang.Class)"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public &lt;T&gt; T <B>unwrap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+
+ If the receiver implements the interface then the result is the receiver
+ or a proxy for the receiver. If the receiver is a wrapper
+ and the wrapped object implements the interface then the result is the
+ wrapped object or a proxy for the wrapped object. Otherwise return the
+ the result of calling <code>unwrap</code> recursively on the wrapped object
+ or a proxy for that result. If the receiver is not a
+ wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - A Class defining an interface that the result must implement.
+<DT><B>Returns:</B><DD>an object that implements the interface. May be a proxy for the actual implementing object.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - If no object found that implements the interface<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWrapperFor(java.lang.Class)"><!-- --></A><H3>
+isWrapperFor</H3>
+<PRE>
+public boolean <B>isWrapperFor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does. Returns false otherwise. If this implements the interface then return true,
+ else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+ object. If this does not implement the interface and is not a wrapper, return false.
+ This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+ callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+ returns true then calling <code>unwrap</code> with the same argument should succeed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - a Class defining an interface.
+<DT><B>Returns:</B><DD>true if this implements the interface or directly or indirectly wraps an object that does.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while determining whether this is a wrapper
+ for an object with the given interface.<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCResultSet.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCResultSet.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCResultSet.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCResultSetMetaData.html b/doc/apidocs/org/hsqldb/jdbc/JDBCResultSetMetaData.html
new file mode 100644
index 0000000..2b74d06
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCResultSetMetaData.html
@@ -0,0 +1,1351 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCResultSetMetaData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCResultSetMetaData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCResultSetMetaData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCResultSetMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCResultSetMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCResultSetMetaData</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCResultSetMetaData</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCResultSetMetaData</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></DL>
+</PRE>
+
+<P>
+<!-- start generic documentation -->
+ An object that can be used to get information about the types
+ and properties of the columns in a <code>ResultSet</code> object.
+ The following code fragment creates the <code>ResultSet</code> object rs,
+ creates the <code>ResultSetMetaData</code> object rsmd, and uses rsmd
+ to find out how many columns rs has and whether the first column in rs
+ can be used in a <code>WHERE</code> clause.
+ <PRE>
+
+     ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
+     ResultSetMetaData rsmd = rs.getMetaData();
+     int numberOfColumns = rsmd.getColumnCount();
+     boolean b = rsmd.isSearchable(1);
+
+ </PRE>
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports a subset of the <code>ResultSetMetaData</code> interface.<p>
+
+ The JDBC specification for <code>ResultSetMetaData</code> is in part very
+ vague. This causes potential incompatibility between interpretations of the
+ specification as realized in different JDBC driver implementations. As such,
+ deciding to what degree reporting ResultSetMetaData is accurate has been
+ considered very carefully. Hopefully, the design decisions made in light of
+ these considerations have yeilded precisely the subset of full
+ ResultSetMetaData support that is most commonly needed and that is most
+ important, while also providing, under the most common use-cases, the
+ fastest access with the least overhead and the best comprimise between
+ speed, accuracy, jar-footprint and retention of JDBC resources. <p>
+
+ (fredt@users) <br>
+ (boucherb@users)<p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeQuery(java.lang.String)"><CODE>JDBCStatement.executeQuery(java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSet()"><CODE>JDBCStatement.getResultSet()</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSetMetaData</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.sql.ResultSetMetaData"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#columnNoNulls" title="class or interface in java.sql">columnNoNulls</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#columnNullable" title="class or interface in java.sql">columnNullable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#columnNullableUnknown" title="class or interface in java.sql">columnNullableUnknown</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getCatalogName(int)">getCatalogName</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the designated column's table's catalog name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnClassName(int)">getColumnClassName</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnCount()">getColumnCount</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the number of columns in this <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnDisplaySize(int)">getColumnDisplaySize</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates the designated column's normal maximum width in characters.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnLabel(int)">getColumnLabel</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the designated column's suggested title for use in printouts and
+ displays.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnName(int)">getColumnName</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the designated column's name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnType(int)">getColumnType</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the designated column's SQL type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnTypeName(int)">getColumnTypeName</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the designated column's database-specific type name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getPrecision(int)">getPrecision</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Get the designated column's specified column size.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getScale(int)">getScale</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the designated column's number of digits to right of the decimal point.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getSchemaName(int)">getSchemaName</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the designated column's table's schema.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getTableName(int)">getTableName</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the designated column's table name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isAutoIncrement(int)">isAutoIncrement</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether the designated column is automatically numbered.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isCaseSensitive(int)">isCaseSensitive</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether a column's case matters.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isCurrency(int)">isCurrency</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether the designated column is a cash value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isDefinitelyWritable(int)">isDefinitelyWritable</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether a write on the designated column will definitely succeed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isNullable(int)">isNullable</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates the nullability of values in the designated column.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isReadOnly(int)">isReadOnly</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether the designated column is definitely not writable.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isSearchable(int)">isSearchable</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether the designated column can be used in a where clause.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isSigned(int)">isSigned</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether values in the designated column are signed numbers.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isWrapperFor(java.lang.Class)">isWrapperFor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#isWritable(int)">isWritable</A></B>(int&nbsp;column)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether it is possible for a write on the designated column to
+ succeed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a string representation of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T&gt; T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#unwrap(java.lang.Class)">unwrap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getColumnCount()"><!-- --></A><H3>
+getColumnCount</H3>
+<PRE>
+public int <B>getColumnCount</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Returns the number of columns in this <code>ResultSet</code> object.
+
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getColumnCount()" title="class or interface in java.sql">getColumnCount</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the number of columns
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isAutoIncrement(int)"><!-- --></A><H3>
+isAutoIncrement</H3>
+<PRE>
+public boolean <B>isAutoIncrement</B>(int&nbsp;column)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates whether the designated column is automatically numbered.
+ <p>(JDBC4 deleted:)[, thus read-only.]
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 fully supports SQL Satandard features T174 and T176 that
+ define identity column support.
+
+ <hr>
+
+ However, it must be stated here that contrary to the generic
+ documentation previous to the JDBC4 specification, HSQLDB automatically
+ numbered columns (IDENTITY columns, in HSQLDB parlance) are not
+ read-only. <p>
+
+ In fact, the generic documentation previous to the JDBC4 specification
+ seems to contradict the general definition of what, at minimum,
+ an auto-increment column is: <p>
+
+ Simply, an auto-increment column is one that guarantees it has a
+ autogenerated value after a successful insert or update operation,
+ even if no value is supplied, or DEFAULT is specified.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isAutoIncrement(int)" title="class or interface in java.sql">isAutoIncrement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isCaseSensitive(int)"><!-- --></A><H3>
+isCaseSensitive</H3>
+<PRE>
+public boolean <B>isCaseSensitive</B>(int&nbsp;column)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates whether a column's case matters.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 1.7.1 did not report this value accurately.  <p>
+
+ Starting with 1.7.2, this feature is better supported.  <p>
+
+ This method returns true for any column whose data type is a character
+ type, with the exception of VARCHAR_IGNORECASE for which it returns
+ false. It also returns false for any column whose data type is a
+ not a character data type. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isCaseSensitive(int)" title="class or interface in java.sql">isCaseSensitive</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isSearchable(int)"><!-- --></A><H3>
+isSearchable</H3>
+<PRE>
+public boolean <B>isSearchable</B>(int&nbsp;column)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates whether the designated column can be used in a where clause.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 handles this differently from previous versions. <p>
+
+ If the column in question is a database table or view column, and the
+ type of the column allows searching, then returns true, otherwise false.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isSearchable(int)" title="class or interface in java.sql">isSearchable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isCurrency(int)"><!-- --></A><H3>
+isCurrency</H3>
+<PRE>
+public boolean <B>isCurrency</B>(int&nbsp;column)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates whether the designated column is a cash value.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 fully supports this feature and returns true for
+ NUMERIC and DECIMAL columns. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isCurrency(int)" title="class or interface in java.sql">isCurrency</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isNullable(int)"><!-- --></A><H3>
+isNullable</H3>
+<PRE>
+public int <B>isNullable</B>(int&nbsp;column)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates the nullability of values in the designated column.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 fully supports this feature.  <p>
+
+ <tt>columnNoNulls</tt> is always returned for result set columns
+ that do not directly represent table column values (i.e. are calculated),
+ while the corresponding value in [INFORMATION_SCHEMA.]SYSTEM_COLUMNS.NULLABLE
+ is returned for result set columns that do directly represent table
+ column values. <p>
+
+ To determine the nullable status of a table column in isolation from
+ ResultSetMetaData and in a DBMS-independent fashion, the
+ DatabaseMetaData.getColumns() method can be invoked with the
+ appropriate filter values and the result should be inspected at the
+ position described in the DatabaseMetaData.getColumns() API
+ documentation.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isNullable(int)" title="class or interface in java.sql">isNullable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the nullability status of the given column; one of <code>columnNoNulls</code>,
+          <code>columnNullable</code> or <code>columnNullableUnknown</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isSigned(int)"><!-- --></A><H3>
+isSigned</H3>
+<PRE>
+public boolean <B>isSigned</B>(int&nbsp;column)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates whether values in the designated column are signed numbers.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 fully supports this feature.  <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isSigned(int)" title="class or interface in java.sql">isSigned</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnDisplaySize(int)"><!-- --></A><H3>
+getColumnDisplaySize</H3>
+<PRE>
+public int <B>getColumnDisplaySize</B>(int&nbsp;column)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates the designated column's normal maximum width in characters.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 fully supports this feature.  <p>
+
+ The current calculation follows these rules: <p>
+
+ <ol>
+ <li>Long character types and datetime types:<p>
+
+     The maximum length/precision, repectively.<p>
+
+ <li>CHAR and VARCHAR types: <p>
+
+      <ul>
+      <li> If the result set column is a direct pass through of a table
+           column value and column size was declared, then the declared
+           value is returned. <p>
+
+      <li> Otherwise, the computed length according to SQL Standard is
+           returned. For very large values, the value of the system property
+           hsqldb.max_xxxchar_display_size or the magic value
+           32766 (0x7FFE) (tested usable/accepted by most tools and
+           compatible with assumptions made by java.io read/write
+           UTF) when the system property is not defined or is not
+           accessible, due to security constraints. <p>
+
+      </ul>
+
+      It must be noted that the latter value in no way affects the
+      ability of the HSQLDB JDBC driver to retrieve longer values
+      and serves only as the current best effort at providing a
+      value that maximizes usability across a wide range of tools,
+      given that the HSQLDB database engine allows very large
+      lengths to be declared. <p>
+
+ <li>Number types: <p>
+
+     The max precision, plus the length of the negation character (1),
+     plus (if applicable) the maximum number of characters that may
+     occupy the exponent character sequence.  Note that some legacy tools
+     do not correctly handle BIGINT values of greater than 18 digits. <p>
+
+ <li>BOOLEAN type: <p>
+
+     The length of the character sequence "false" (5), the longer of the
+     two boolean value String representations. <p>
+
+ <li>Remaining types: <p>
+
+     The maximum length/precision, respectively, as reported by
+     DatabaseMetaData.getTypeInfo(), when applicable.  If the maximum
+     display size is unknown, unknowable or inapplicable, then zero is
+     returned. <p>
+
+ </ol>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getColumnDisplaySize(int)" title="class or interface in java.sql">getColumnDisplaySize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the normal maximum number of characters allowed as the width
+          of the designated column
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnLabel(int)"><!-- --></A><H3>
+getColumnLabel</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getColumnLabel</B>(int&nbsp;column)
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Gets the designated column's suggested title for use in printouts and
+ displays. (JDBC4 clarification:) The suggested title is usually specified by the SQL <code>AS</code>
+ clause.  If a SQL <code>AS</code> is not specified, the value returned from
+ <code>getColumnLabel</code> will be the same as the value returned by the
+ <code>getColumnName</code> method.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ In HSQLDB, a <code>ResultSet</code> column label is determined using the
+ following order of precedence:<p>
+
+ <OL>
+ <LI>The label (alias) specified in the generating query.</LI>
+ <LI>The name of the underlying column, if no label is specified.<br>
+ <L1>C1, C2, etc. for computed columns that have no label.</LI>
+ </OL> <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getColumnLabel(int)" title="class or interface in java.sql">getColumnLabel</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the suggested column title
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnName(int)"><!-- --></A><H3>
+getColumnName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getColumnName</B>(int&nbsp;column)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Get the designated column's name.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ In HSQLDB, a ResultSet column name is determined using the following
+ order of prcedence:<p>
+
+ <OL>
+ <LI>The name of the underlying columnm, if the ResultSet column
+   represents a column in a table.</LI>
+ <LI>The label or alias specified in the generating query.</LI>
+ <L1>C1, C2, etc. for computed columns that have no label.</LI>
+ </OL> <p>
+
+ If the <code>jdbc.get_column_name</code> property of the JDBC Connection
+ has been set to false, this method returns the same value as
+ <A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html#getColumnLabel(int)"><CODE>getColumnLabel(int)</CODE></A>.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getColumnName(int)" title="class or interface in java.sql">getColumnName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>column name
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSchemaName(int)"><!-- --></A><H3>
+getSchemaName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getSchemaName</B>(int&nbsp;column)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Get the designated column's table's schema.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Since 1.8.0.x, HSQLDB implements standard SQL SCHEMA support;
+ this method returns the actual schema of the column's table.
+ Columns generated in queries have no schema name.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getSchemaName(int)" title="class or interface in java.sql">getSchemaName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>schema name or "" if not applicable
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getPrecision(int)"><!-- --></A><H3>
+getPrecision</H3>
+<PRE>
+public int <B>getPrecision</B>(int&nbsp;column)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Get the designated column's specified column size.
+ For numeric data, this is the maximum precision.  For character data, this is the [maximum] length in characters.
+ For datetime datatypes, this is the [maximim] length in characters of the String representation (assuming the
+ maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+ this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+ column size is not applicable.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.8.0, HSQLDB reports the declared length or precision
+ specifiers for table columns, if they are defined.<p>
+
+ From 2.0, HSQLDB, reports the correct length or precision for
+ computed columns according to the SQL Standard.<p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getPrecision(int)" title="class or interface in java.sql">getPrecision</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>precision
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getScale(int)"><!-- --></A><H3>
+getScale</H3>
+<PRE>
+public int <B>getScale</B>(int&nbsp;column)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Gets the designated column's number of digits to right of the decimal point.
+ 0 is returned for data types where the scale is not applicable.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.8.0, HSQLDB reports the declared
+ scale for table columns.<p>
+
+ From 2.0, HSQLDB, reports the correct scale for
+ computed columns according to the SQL Standard.<p>
+
+ <pre>
+ sql.enforce_strict_size
+ </pre>
+ For datetime and interval types such as Timestamp or Time, the
+ fractional second precision is reported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getScale(int)" title="class or interface in java.sql">getScale</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>scale
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTableName(int)"><!-- --></A><H3>
+getTableName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getTableName</B>(int&nbsp;column)
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Gets the designated column's table name.
+
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getTableName(int)" title="class or interface in java.sql">getTableName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>table name or "" if not applicable
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCatalogName(int)"><!-- --></A><H3>
+getCatalogName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getCatalogName</B>(int&nbsp;column)
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Gets the designated column's table's catalog name.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0, HSQLDB returns the name of the catalog. The default name is
+ PUBLIC.
+ This value can be changed for the database using an SQL command.<p>
+
+ HSQLDB supports use of catalog qualification in DLL or DML when it is
+ allowed by the Standard. <p>
+
+ However, not all clients respect the SQL Standard and may use a
+ catalog qualifier in a context where it is not suppoted by the Standard.
+ <p>
+
+ For greater detail, see discussion at:
+ <A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><CODE>JDBCDatabaseMetaData</CODE></A>. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getCatalogName(int)" title="class or interface in java.sql">getCatalogName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the name of the catalog for the table in which the given column
+          appears or "" if not applicable
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnType(int)"><!-- --></A><H3>
+getColumnType</H3>
+<PRE>
+public int <B>getColumnType</B>(int&nbsp;column)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the designated column's SQL type.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ This reports the SQL type code of the column. For time and timestamp
+ types that are WITH TIME ZONE, the values as the SQL Standarc CLI
+ codes.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getColumnType(int)" title="class or interface in java.sql">getColumnType</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>SQL type from java.sql.Types
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Types.html?is-external=true" title="class or interface in java.sql"><CODE>Types</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnTypeName(int)"><!-- --></A><H3>
+getColumnTypeName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getColumnTypeName</B>(int&nbsp;column)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the designated column's database-specific type name.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getColumnTypeName(int)" title="class or interface in java.sql">getColumnTypeName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>type name used by the database. If the column type is
+ a user-defined type, then a fully-qualified type name is returned.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isReadOnly(int)"><!-- --></A><H3>
+isReadOnly</H3>
+<PRE>
+public boolean <B>isReadOnly</B>(int&nbsp;column)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates whether the designated column is definitely not writable.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0 this method returns true if the ResuleSet is not updatable
+ or the column in question is not updatable.<p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isReadOnly(int)" title="class or interface in java.sql">isReadOnly</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWritable(int)"><!-- --></A><H3>
+isWritable</H3>
+<PRE>
+public boolean <B>isWritable</B>(int&nbsp;column)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates whether it is possible for a write on the designated column to
+ succeed.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0 this method returns false if the ResuleSet is not updatable
+ or the column in question is not updatable.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isWritable(int)" title="class or interface in java.sql">isWritable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isDefinitelyWritable(int)"><!-- --></A><H3>
+isDefinitelyWritable</H3>
+<PRE>
+public boolean <B>isDefinitelyWritable</B>(int&nbsp;column)
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Indicates whether a write on the designated column will definitely succeed.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ From 2.0 this method returns false if the ResuleSet is not updatable
+ or the column in question is not updatable.<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#isDefinitelyWritable(int)" title="class or interface in java.sql">isDefinitelyWritable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD><code>true</code> if so; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnClassName(int)"><!-- --></A><H3>
+getColumnClassName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getColumnClassName</B>(int&nbsp;column)
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ <p>Returns the fully-qualified name of the Java class whose instances
+ are manufactured if the method <code>ResultSet.getObject</code>
+ is called to retrieve a value
+ from the column.  <code>ResultSet.getObject</code> may return a subclass of the
+ class returned by this method.
+ <!-- end generic documentation -->
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 2.0 fully supports this feature.<p>
+
+ For columns of type OTHER, there is no specific class name and
+ java.lang.Object is returned.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true#getColumnClassName(int)" title="class or interface in java.sql">getColumnClassName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>column</CODE> - the first column is 1, the second is 2, ...
+<DT><B>Returns:</B><DD>the fully-qualified name of the class in the Java programming
+         language that would be used by the method
+ <code>ResultSet.getObject</code> to retrieve the value in the specified
+ column. This is the class name used for custom mapping.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview for
+      JDBCResultSet)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap(java.lang.Class)"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public &lt;T&gt; T <B>unwrap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+
+ If the receiver implements the interface then the result is the receiver
+ or a proxy for the receiver. If the receiver is a wrapper
+ and the wrapped object implements the interface then the result is the
+ wrapped object or a proxy for the wrapped object. Otherwise return the
+ the result of calling <code>unwrap</code> recursively on the wrapped object
+ or a proxy for that result. If the receiver is not a
+ wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - A Class defining an interface that the result must implement.
+<DT><B>Returns:</B><DD>an object that implements the interface. May be a proxy for the actual implementing object.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - If no object found that implements the interface<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.8.x</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWrapperFor(java.lang.Class)"><!-- --></A><H3>
+isWrapperFor</H3>
+<PRE>
+public boolean <B>isWrapperFor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does. Returns false otherwise. If this implements the interface then return true,
+ else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+ object. If this does not implement the interface and is not a wrapper, return false.
+ This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+ callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+ returns true then calling <code>unwrap</code> with the same argument should succeed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - a Class defining an interface.
+<DT><B>Returns:</B><DD>true if this implements the interface or directly or indirectly wraps an object that does.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while determining whether this is a wrapper
+ for an object with the given interface.<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 1.8.x</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>toString</B>()</PRE>
+<DL>
+<DD>Returns a string representation of the object. <p>
+
+ The string consists of the name of the class of which the
+ object is an instance, the at-sign character `<code>@</code>',
+ the unsigned hexadecimal representation of the hash code of the
+ object and a comma-delimited list of this object's indexed attributes,
+ enclosed in square brakets.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a string representation of the object.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCResultSetMetaData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCResultSetMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCResultSetMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCRowId.html b/doc/apidocs/org/hsqldb/jdbc/JDBCRowId.html
new file mode 100644
index 0000000..b2ae585
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCRowId.html
@@ -0,0 +1,467 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCRowId (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCRowId (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCRowId.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCRowId.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCRowId.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCRowId</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCRowId</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public final class <B>JDBCRowId</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></DL>
+</PRE>
+
+<P>
+The representation (mapping) in the Java programming language of an SQL ROWID
+ value. An SQL ROWID is a built-in type, a value of which can be thought of as
+ an address  for its identified row in a database table. Whether that address
+ is logical or, in any  respects, physical is determined by its originating data
+ source.
+ <p>
+ Methods in the interfaces <code>ResultSet</code>, <code>CallableStatement</code>,
+ and <code>PreparedStatement</code>, such as <code>getRowId</code> and <code>setRowId</code>
+ allow a programmer to access a SQL <code>ROWID</code>  value. The <code>RowId</code>
+ interface provides a method
+ for representing the value of the <code>ROWID</code> as a byte array or as a
+ <code>String</code>.
+ <p>
+ The method <code>getRowIdLifetime</code> in the interface <code>DatabaseMetaData</code>,
+ can be used
+ to determine if a <code>RowId</code> object remains valid for the duration of the transaction in
+ which  the <code>RowId</code> was created, the duration of the session in which
+ the <code>RowId</code> was created,
+ or, effectively, for as long as its identified row is not deleted. In addition
+ to specifying the duration of its valid lifetime outside its originating data
+ source, <code>getRowIdLifetime</code> specifies the duration of a <code>ROWID</code>
+ value's valid lifetime
+ within its originating data source. In this, it differs from a large object,
+ because there is no limit on the valid lifetime of a large  object within its
+ originating data source.
+ <p>
+ All methods on the <code>RowId</code> interface must be fully implemented if the
+ JDBC driver supports the data type.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>boucherb@users</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql"><CODE>DatabaseMetaData</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html#JDBCRowId(byte[])">JDBCRowId</A></B>(byte[]&nbsp;id)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new JDBCRowId instance wrapping the given octet sequence.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html#JDBCRowId(java.sql.RowId)">JDBCRowId</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;id)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new JDBCRowId instance whose internal octet sequence is
+ is a copy of the octet sequence of the given RowId object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html#JDBCRowId(java.lang.String)">JDBCRowId</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;hex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new JDBCRowId instance whose internal octet sequence is
+ is that represented by the given hexidecimal character sequence.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html#equals(java.lang.Object)">equals</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;obj)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compares this <code>RowId</code> to the specified object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html#getBytes()">getBytes</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an array of bytes representing the value of the SQL <code>ROWID</code>
+ designated by this <code>java.sql.RowId</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html#hashCode()">hashCode</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a hash code value of this <code>RowId</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a String representing the value of the SQL ROWID designated by this
+ <code>java.sql.RowId</code> object.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCRowId(byte[])"><!-- --></A><H3>
+JDBCRowId</H3>
+<PRE>
+public <B>JDBCRowId</B>(byte[]&nbsp;id)
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new JDBCRowId instance wrapping the given octet sequence. <p>
+
+ This constructor may be used internally to retrieve result set values as
+ RowId objects, yet it also may need to be public to allow access from
+ other packages. As such (in the interest of efficiency) this object
+ maintains a reference to the given octet sequence rather than making a
+ copy; special care should be taken by extenal clients never to use this
+ constructor with a byte array object that may later be modified
+ extenally.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>id</CODE> - the octet sequence representing the Rowid value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the argument is null</DL>
+</DL>
+<HR>
+
+<A NAME="JDBCRowId(java.sql.RowId)"><!-- --></A><H3>
+JDBCRowId</H3>
+<PRE>
+public <B>JDBCRowId</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>&nbsp;id)
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new JDBCRowId instance whose internal octet sequence is
+ is a copy of the octet sequence of the given RowId object. <p>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>id</CODE> - the octet sequence representing the Rowid value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the argument is null</DL>
+</DL>
+<HR>
+
+<A NAME="JDBCRowId(java.lang.String)"><!-- --></A><H3>
+JDBCRowId</H3>
+<PRE>
+public <B>JDBCRowId</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;hex)
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new JDBCRowId instance whose internal octet sequence is
+ is that represented by the given hexidecimal character sequence. <p>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>hex</CODE> - the hexadecimal character sequence from which to derive
+        the internal octet sequence
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the argument is null or is not a valid
+         hexadecimal character sequence</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="equals(java.lang.Object)"><!-- --></A><H3>
+equals</H3>
+<PRE>
+public boolean <B>equals</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>&nbsp;obj)</PRE>
+<DL>
+<DD>Compares this <code>RowId</code> to the specified object. The result is
+ <code>true</code> if and only if the argument is not null and is a RowId
+ object that represents the same ROWID as  this object.
+ <p>
+ It is important
+ to consider both the origin and the valid lifetime of a <code>RowId</code>
+ when comparing it to another <code>RowId</code>. If both are valid, and
+ both are from the same table on the same data source, then if they are equal
+ they identify
+ the same row; if one or more is no longer guaranteed to be valid, or if
+ they originate from different data sources, or different tables on the
+ same data source, they  may be equal but still
+ not identify the same row.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.sql">equals</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></CODE><DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - the <code>Object</code> to compare this <code>RowId</code> object
+     against.
+<DT><B>Returns:</B><DD>true if the <code>RowId</code>s are equal; false otherwise<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBytes()"><!-- --></A><H3>
+getBytes</H3>
+<PRE>
+public byte[] <B>getBytes</B>()</PRE>
+<DL>
+<DD>Returns an array of bytes representing the value of the SQL <code>ROWID</code>
+ designated by this <code>java.sql.RowId</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true#getBytes()" title="class or interface in java.sql">getBytes</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of bytes, whose length is determined by the driver supplying
+     the connection, representing the value of the ROWID designated by this
+     java.sql.RowId object.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>toString</B>()</PRE>
+<DL>
+<DD>Returns a String representing the value of the SQL ROWID designated by this
+ <code>java.sql.RowId</code> object.
+ <p>
+ Like <code>java.sql.Date.toString()</code>
+ returns the contents of its DATE as the <code>String</code> "2004-03-17"
+ rather than as  DATE literal in SQL (which would have been the <code>String</code>
+ DATE "2004-03-17"), toString()
+ returns the contents of its ROWID in a form specific to the driver supplying
+ the connection, and possibly not as a <code>ROWID</code> literal.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true#toString()" title="class or interface in java.sql">toString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></CODE><DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a String whose format is determined by the driver supplying the
+     connection, representing the value of the <code>ROWID</code> designated
+     by this <code>java.sql.RowId</code>  object.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hashCode()"><!-- --></A><H3>
+hashCode</H3>
+<PRE>
+public int <B>hashCode</B>()</PRE>
+<DL>
+<DD>Returns a hash code value of this <code>RowId</code> object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true#hashCode()" title="class or interface in java.sql">hashCode</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A></CODE><DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a hash code for the <code>RowId</code></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCRowId.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCRowId.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCRowId.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html b/doc/apidocs/org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html
new file mode 100644
index 0000000..c49bb4d
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html
@@ -0,0 +1,923 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCSQLXML.SAX2XMLStreamWriter (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCSQLXML.SAX2XMLStreamWriter (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCSQLXML.SAX2XMLStreamWriter.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSQLXML.SAX2XMLStreamWriter.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCSQLXML.SAX2XMLStreamWriter</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCSQLXML.SAX2XMLStreamWriter</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A>, <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></DD>
+</DL>
+<DL>
+<DT><B>Enclosing class:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public static class <B>JDBCSQLXML.SAX2XMLStreamWriter</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A></DL>
+</PRE>
+
+<P>
+Writes to a <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamWriter.html?is-external=true" title="class or interface in javax.xml.stream"><CODE>XMLStreamWriter</CODE></A>
+ from SAX events.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#JDBCSQLXML.SAX2XMLStreamWriter(javax.xml.stream.XMLStreamWriter)">JDBCSQLXML.SAX2XMLStreamWriter</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamWriter.html?is-external=true" title="class or interface in javax.xml.stream">XMLStreamWriter</A>&nbsp;writer)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new SAX2XMLStreamWriter that writes SAX events to the
+ designated XMLStreamWriter.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#characters(char[], int, int)">characters</A></B>(char[]&nbsp;ch,
+           int&nbsp;start,
+           int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive notification of character data.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#close()">close</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Closes this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#comment(char[], int, int)">comment</A></B>(char[]&nbsp;ch,
+        int&nbsp;start,
+        int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endDocument()">endDocument</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive notification of the end of a document.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endElement(java.lang.String, java.lang.String, java.lang.String)">endElement</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;namespaceURI,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;localName,
+           <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;qName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive notification of the end of an element.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endPrefixMapping(java.lang.String)">endPrefixMapping</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;prefix)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End the scope of a prefix-URI mapping.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Locator.html?is-external=true" title="class or interface in org.xml.sax">Locator</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#getDocumentLocator()">getDocumentLocator</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the Locator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamWriter.html?is-external=true" title="class or interface in javax.xml.stream">XMLStreamWriter</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#getWriter()">getWriter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#ignorableWhitespace(char[], int, int)">ignorableWhitespace</A></B>(char[]&nbsp;ch,
+                    int&nbsp;start,
+                    int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive notification of ignorable whitespace in element content.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#isClosed()">isClosed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this object is closed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#processingInstruction(java.lang.String, java.lang.String)">processingInstruction</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;target,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;data)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive notification of a processing instruction.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#setDocumentLocator(org.xml.sax.Locator)">setDocumentLocator</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Locator.html?is-external=true" title="class or interface in org.xml.sax">Locator</A>&nbsp;locator)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive an object for locating the origin of SAX document events.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#skippedEntity(java.lang.String)">skippedEntity</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive notification of a skipped entity.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startDocument()">startDocument</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive notification of the beginning of a document.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)">startElement</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;namespaceURI,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;localName,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;qName,
+             <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Attributes.html?is-external=true" title="class or interface in org.xml.sax">Attributes</A>&nbsp;atts)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Receive notification of the beginning of an element.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startPrefixMapping(java.lang.String, java.lang.String)">startPrefixMapping</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;prefix,
+                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;uri)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Begin the scope of a prefix-URI Namespace mapping.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCSQLXML.SAX2XMLStreamWriter(javax.xml.stream.XMLStreamWriter)"><!-- --></A><H3>
+JDBCSQLXML.SAX2XMLStreamWriter</H3>
+<PRE>
+public <B>JDBCSQLXML.SAX2XMLStreamWriter</B>(<A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamWriter.html?is-external=true" title="class or interface in javax.xml.stream">XMLStreamWriter</A>&nbsp;writer)</PRE>
+<DL>
+<DD>Constructs a new SAX2XMLStreamWriter that writes SAX events to the
+ designated XMLStreamWriter.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>writer</CODE> - the writer to which to write SAX events</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="startDocument()"><!-- --></A><H3>
+startDocument</H3>
+<PRE>
+public void <B>startDocument</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Receive notification of the beginning of a document.
+
+ <p>The SAX parser will invoke this method only once, before any
+ other event callbacks (except for <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#setDocumentLocator(org.xml.sax.Locator)"><CODE>setDocumentLocator</CODE></A>).</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#startDocument()" title="class or interface in org.xml.sax">startDocument</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - any SAX exception, possibly
+            wrapping another exception<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endDocument()"><CODE>endDocument()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="endDocument()"><!-- --></A><H3>
+endDocument</H3>
+<PRE>
+public void <B>endDocument</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Receive notification of the end of a document.
+
+ <p><strong>There is an apparent contradiction between the
+ documentation for this method and the documentation for <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ErrorHandler.html?is-external=true#fatalError(org.xml.sax.SAXParseException)" title="class or interface in org.xml.sax"><CODE>ErrorHandler.fatalError(org.xml.sax.SAXParseException)</CODE></A>.  Until this ambiguity is
+ resolved in a future major release, clients should make no
+ assumptions about whether endDocument() will or will not be
+ invoked when the parser has reported a fatalError() or thrown
+ an exception.</strong></p>
+
+ <p>The SAX parser will invoke this method only once, and it will
+ be the last method invoked during the parse.  The parser shall
+ not invoke this method until it has either abandoned parsing
+ (because of an unrecoverable error) or reached the end of
+ input.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#endDocument()" title="class or interface in org.xml.sax">endDocument</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - any SAX exception, possibly
+            wrapping another exception<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startDocument()"><CODE>startDocument()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="characters(char[], int, int)"><!-- --></A><H3>
+characters</H3>
+<PRE>
+public void <B>characters</B>(char[]&nbsp;ch,
+                       int&nbsp;start,
+                       int&nbsp;length)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Receive notification of character data.
+
+ <p>The Parser will call this method to report each chunk of
+ character data.  SAX parsers may return all contiguous character
+ data in a single chunk, or they may split it into several
+ chunks; however, all of the characters in any single event
+ must come from the same external entity so that the Locator
+ provides useful information.</p>
+
+ <p>The application must not attempt to read from the array
+ outside of the specified range.</p>
+
+ <p>Individual characters may consist of more than one Java
+ <code>char</code> value.  There are two important cases where this
+ happens, because characters can't be represented in just sixteen bits.
+ In one case, characters are represented in a <em>Surrogate Pair</em>,
+ using two special Unicode values. Such characters are in the so-called
+ "Astral Planes", with a code point above U+FFFF.  A second case involves
+ composite characters, such as a base character combining with one or
+ more accent characters. </p>
+
+ <p> Your code should not assume that algorithms using
+ <code>char</code>-at-a-time idioms will be working in character
+ units; in some cases they will split characters.  This is relevant
+ wherever XML permits arbitrary characters, such as attribute values,
+ processing instruction data, and comments as well as in data reported
+ from this method.  It's also generally relevant whenever Java code
+ manipulates internationalized text; the issue isn't unique to XML.</p>
+
+ <p>Note that some parsers will report whitespace in element
+ content using the <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#ignorableWhitespace(char[], int, int)"><CODE>ignorableWhitespace</CODE></A>
+ method rather than this one (validating parsers <em>must</em>
+ do so).</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#characters(char[], int, int)" title="class or interface in org.xml.sax">characters</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>ch</CODE> - the characters from the XML document<DD><CODE>start</CODE> - the start position in the array<DD><CODE>length</CODE> - the number of characters to read from the array
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - any SAX exception, possibly
+            wrapping another exception<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#ignorableWhitespace(char[], int, int)"><CODE>ignorableWhitespace(char[], int, int)</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Locator.html?is-external=true" title="class or interface in org.xml.sax"><CODE>Locator</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)"><!-- --></A><H3>
+startElement</H3>
+<PRE>
+public void <B>startElement</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;namespaceURI,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;localName,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;qName,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Attributes.html?is-external=true" title="class or interface in org.xml.sax">Attributes</A>&nbsp;atts)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Receive notification of the beginning of an element.
+
+ <p>The Parser will invoke this method at the beginning of every
+ element in the XML document; there will be a corresponding
+ <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endElement(java.lang.String, java.lang.String, java.lang.String)"><CODE>endElement</CODE></A> event for every startElement event
+ (even when the element is empty). All of the element's content will be
+ reported, in order, before the corresponding endElement
+ event.</p>
+
+ <p>This event allows up to three name components for each
+ element:</p>
+
+ <ol>
+ <li>the Namespace URI;</li>
+ <li>the local name; and</li>
+ <li>the qualified (prefixed) name.</li>
+ </ol>
+
+ <p>Any or all of these may be provided, depending on the
+ values of the <var>http://xml.org/sax/features/namespaces</var>
+ and the <var>http://xml.org/sax/features/namespace-prefixes</var>
+ properties:</p>
+
+ <ul>
+ <li>the Namespace URI and local name are required when
+ the namespaces property is <var>true</var> (the default), and are
+ optional when the namespaces property is <var>false</var> (if one is
+ specified, both must be);</li>
+ <li>the qualified name is required when the namespace-prefixes property
+ is <var>true</var>, and is optional when the namespace-prefixes property
+ is <var>false</var> (the default).</li>
+ </ul>
+
+ <p>Note that the attribute list provided will contain only
+ attributes with explicit values (specified or defaulted):
+ #IMPLIED attributes will be omitted.  The attribute list
+ will contain attributes used for Namespace declarations
+ (xmlns* attributes) only if the
+ <code>http://xml.org/sax/features/namespace-prefixes</code>
+ property is true (it is false by default, and support for a
+ true value is optional).</p>
+
+ <p>Like <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#characters(char[], int, int)"><CODE>characters()</CODE></A>, attribute values may have
+ characters that need more than one <code>char</code> value.  </p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)" title="class or interface in org.xml.sax">startElement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>namespaceURI</CODE> - the Namespace URI, or the empty string if the
+        element has no Namespace URI or if Namespace
+        processing is not being performed<DD><CODE>localName</CODE> - the local name (without prefix), or the
+        empty string if Namespace processing is not being
+        performed<DD><CODE>qName</CODE> - the qualified name (with prefix), or the
+        empty string if qualified names are not available<DD><CODE>atts</CODE> - the attributes attached to the element.  If
+        there are no attributes, it shall be an empty
+        Attributes object.  The value of this object after
+        startElement returns is undefined
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - any SAX exception, possibly
+            wrapping another exception<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endElement(java.lang.String, java.lang.String, java.lang.String)"><CODE>endElement(java.lang.String, java.lang.String, java.lang.String)</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Attributes.html?is-external=true" title="class or interface in org.xml.sax"><CODE>Attributes</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/helpers/AttributesImpl.html?is-external=true" title="class or interface in org.xml.sax.helpers"><CODE>AttributesImpl</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="endElement(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+endElement</H3>
+<PRE>
+public void <B>endElement</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;namespaceURI,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;localName,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;qName)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Receive notification of the end of an element.
+
+ <p>The SAX parser will invoke this method at the end of every
+ element in the XML document; there will be a corresponding
+ <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)"><CODE>startElement</CODE></A> event for every endElement
+ event (even when the element is empty).</p>
+
+ <p>For information on the names, see startElement.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#endElement(java.lang.String, java.lang.String, java.lang.String)" title="class or interface in org.xml.sax">endElement</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>namespaceURI</CODE> - the Namespace URI, or the empty string if the
+        element has no Namespace URI or if Namespace
+        processing is not being performed<DD><CODE>localName</CODE> - the local name (without prefix), or the
+        empty string if Namespace processing is not being
+        performed<DD><CODE>qName</CODE> - the qualified XML name (with prefix), or the
+        empty string if qualified names are not available
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - any SAX exception, possibly
+            wrapping another exception</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="startPrefixMapping(java.lang.String, java.lang.String)"><!-- --></A><H3>
+startPrefixMapping</H3>
+<PRE>
+public void <B>startPrefixMapping</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;prefix,
+                               <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;uri)
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Begin the scope of a prefix-URI Namespace mapping.
+
+ <p>The information from this event is not necessary for
+ normal Namespace processing: the SAX XML reader will
+ automatically replace prefixes for element and attribute
+ names when the <code>http://xml.org/sax/features/namespaces</code>
+ feature is <var>true</var> (the default).</p>
+
+ <p>There are cases, however, when applications need to
+ use prefixes in character data or in attribute values,
+ where they cannot safely be expanded automatically; the
+ start/endPrefixMapping event supplies the information
+ to the application to expand prefixes in those contexts
+ itself, if necessary.</p>
+
+ <p>Note that start/endPrefixMapping events are not
+ guaranteed to be properly nested relative to each other:
+ all startPrefixMapping events will occur immediately before the
+ corresponding <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)"><CODE>startElement</CODE></A> event,
+ and all <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endPrefixMapping(java.lang.String)"><CODE>endPrefixMapping</CODE></A>
+ events will occur immediately after the corresponding
+ <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endElement(java.lang.String, java.lang.String, java.lang.String)"><CODE>endElement</CODE></A> event,
+ but their order is not otherwise
+ guaranteed.</p>
+
+ <p>There should never be start/endPrefixMapping events for the
+ "xml" prefix, since it is predeclared and immutable.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#startPrefixMapping(java.lang.String, java.lang.String)" title="class or interface in org.xml.sax">startPrefixMapping</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>prefix</CODE> - the Namespace prefix being declared.
+      An empty string is used for the default element namespace,
+      which has no prefix.<DD><CODE>uri</CODE> - the Namespace URI the prefix is mapped to
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - the client may throw
+            an exception during processing<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endPrefixMapping(java.lang.String)"><CODE>endPrefixMapping(java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)"><CODE>startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="endPrefixMapping(java.lang.String)"><!-- --></A><H3>
+endPrefixMapping</H3>
+<PRE>
+public void <B>endPrefixMapping</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;prefix)
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>End the scope of a prefix-URI mapping.
+
+ <p>See <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startPrefixMapping(java.lang.String, java.lang.String)"><CODE>startPrefixMapping</CODE></A> for
+ details.  These events will always occur immediately after the
+ corresponding <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endElement(java.lang.String, java.lang.String, java.lang.String)"><CODE>endElement</CODE></A> event, but the order of
+ <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endPrefixMapping(java.lang.String)"><CODE>endPrefixMapping</CODE></A> events is not otherwise
+ guaranteed.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#endPrefixMapping(java.lang.String)" title="class or interface in org.xml.sax">endPrefixMapping</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>prefix</CODE> - the prefix that was being mapped.
+      This is the empty string when a default mapping scope ends.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - the client may throw
+            an exception during processing<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startPrefixMapping(java.lang.String, java.lang.String)"><CODE>startPrefixMapping(java.lang.String, java.lang.String)</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endElement(java.lang.String, java.lang.String, java.lang.String)"><CODE>endElement(java.lang.String, java.lang.String, java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="ignorableWhitespace(char[], int, int)"><!-- --></A><H3>
+ignorableWhitespace</H3>
+<PRE>
+public void <B>ignorableWhitespace</B>(char[]&nbsp;ch,
+                                int&nbsp;start,
+                                int&nbsp;length)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Receive notification of ignorable whitespace in element content.
+
+ <p>Validating Parsers must use this method to report each chunk
+ of whitespace in element content (see the W3C XML 1.0
+ recommendation, section 2.10): non-validating parsers may also
+ use this method if they are capable of parsing and using
+ content models.</p>
+
+ <p>SAX parsers may return all contiguous whitespace in a single
+ chunk, or they may split it into several chunks; however, all of
+ the characters in any single event must come from the same
+ external entity, so that the Locator provides useful
+ information.</p>
+
+ <p>The application must not attempt to read from the array
+ outside of the specified range.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#ignorableWhitespace(char[], int, int)" title="class or interface in org.xml.sax">ignorableWhitespace</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>ch</CODE> - the characters from the XML document<DD><CODE>start</CODE> - the start position in the array<DD><CODE>length</CODE> - the number of characters to read from the array
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - any SAX exception, possibly
+            wrapping another exception<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#characters(char[], int, int)"><CODE>characters(char[], int, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="processingInstruction(java.lang.String, java.lang.String)"><!-- --></A><H3>
+processingInstruction</H3>
+<PRE>
+public void <B>processingInstruction</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;target,
+                                  <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;data)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Receive notification of a processing instruction.
+
+ <p>The Parser will invoke this method once for each processing
+ instruction found: note that processing instructions may occur
+ before or after the main document element.</p>
+
+ <p>A SAX parser must never report an XML declaration (XML 1.0,
+ section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+ using this method.</p>
+
+ <p>Like <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#characters(char[], int, int)"><CODE>characters()</CODE></A>, processing instruction
+ data may have characters that need more than one <code>char</code>
+ value. </p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#processingInstruction(java.lang.String, java.lang.String)" title="class or interface in org.xml.sax">processingInstruction</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>target</CODE> - the processing instruction target<DD><CODE>data</CODE> - the processing instruction data, or null if
+        none was supplied.  The data does not include any
+        whitespace separating it from the target
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - any SAX exception, possibly
+            wrapping another exception</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDocumentLocator(org.xml.sax.Locator)"><!-- --></A><H3>
+setDocumentLocator</H3>
+<PRE>
+public void <B>setDocumentLocator</B>(<A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Locator.html?is-external=true" title="class or interface in org.xml.sax">Locator</A>&nbsp;locator)</PRE>
+<DL>
+<DD>Receive an object for locating the origin of SAX document events.
+
+ <p>SAX parsers are strongly encouraged (though not absolutely
+ required) to supply a locator: if it does so, it must supply
+ the locator to the application by invoking this method before
+ invoking any of the other methods in the ContentHandler
+ interface.</p>
+
+ <p>The locator allows the application to determine the end
+ position of any document-related event, even if the parser is
+ not reporting an error.  Typically, the application will
+ use this information for reporting its own errors (such as
+ character content that does not match an application's
+ business rules).  The information returned by the locator
+ is probably not sufficient for use with a search engine.</p>
+
+ <p>Note that the locator will return correct information only
+ during the invocation SAX event callbacks after
+ <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#startDocument()"><CODE>startDocument</CODE></A> returns and before
+ <A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html#endDocument()"><CODE>endDocument</CODE></A> is called.  The
+ application should not attempt to use it at any other time.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#setDocumentLocator(org.xml.sax.Locator)" title="class or interface in org.xml.sax">setDocumentLocator</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>locator</CODE> - an object that can return the location of
+                any SAX document event<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Locator.html?is-external=true" title="class or interface in org.xml.sax"><CODE>Locator</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDocumentLocator()"><!-- --></A><H3>
+getDocumentLocator</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/Locator.html?is-external=true" title="class or interface in org.xml.sax">Locator</A> <B>getDocumentLocator</B>()</PRE>
+<DL>
+<DD>Retrieves the Locator. <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the Locator</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="skippedEntity(java.lang.String)"><!-- --></A><H3>
+skippedEntity</H3>
+<PRE>
+public void <B>skippedEntity</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD>Receive notification of a skipped entity.
+ This is not called for entity references within markup constructs
+ such as element start tags or markup declarations.  (The XML
+ recommendation requires reporting skipped external entities.
+ SAX also reports internal entity expansion/non-expansion, except
+ within markup constructs.)
+
+ <p>The Parser will invoke this method each time the entity is
+ skipped.  Non-validating processors may skip entities if they
+ have not seen the declarations (because, for example, the
+ entity was declared in an external DTD subset).  All processors
+ may skip external entities, depending on the values of the
+ <code>http://xml.org/sax/features/external-general-entities</code>
+ and the
+ <code>http://xml.org/sax/features/external-parameter-entities</code>
+ properties.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true#skippedEntity(java.lang.String)" title="class or interface in org.xml.sax">skippedEntity</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the skipped entity.  If it is a
+        parameter entity, the name will begin with '%', and if
+        it is the external DTD subset, it will be the string
+        "[dtd]"
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE> - any SAX exception, possibly
+            wrapping another exception</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="comment(char[], int, int)"><!-- --></A><H3>
+comment</H3>
+<PRE>
+public void <B>comment</B>(char[]&nbsp;ch,
+                    int&nbsp;start,
+                    int&nbsp;length)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/SAXException.html?is-external=true" title="class or interface in org.xml.sax">SAXException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWriter()"><!-- --></A><H3>
+getWriter</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamWriter.html?is-external=true" title="class or interface in javax.xml.stream">XMLStreamWriter</A> <B>getWriter</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="close()"><!-- --></A><H3>
+close</H3>
+<PRE>
+public void <B>close</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>Closes this object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true#close()" title="class or interface in java.io">close</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isClosed()"><!-- --></A><H3>
+isClosed</H3>
+<PRE>
+public boolean <B>isClosed</B>()</PRE>
+<DL>
+<DD>Retrieves whether this object is closed.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCSQLXML.SAX2XMLStreamWriter.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSQLXML.SAX2XMLStreamWriter.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCSQLXML.html b/doc/apidocs/org/hsqldb/jdbc/JDBCSQLXML.html
new file mode 100644
index 0000000..e09d926
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCSQLXML.html
@@ -0,0 +1,998 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCSQLXML (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCSQLXML (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCSQLXML.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCSQLXML.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSQLXML.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCSQLXML</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCSQLXML</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCSQLXML</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></DL>
+</PRE>
+
+<P>
+<!-- start generic documentation -->
+ The mapping in the JavaTM programming language for the SQL XML type.
+ XML is a built-in type that stores an XML value
+ as a column value in a row of a database table.
+ By default drivers implement an SQLXML object as
+ a logical pointer to the XML data
+ rather than the data itself.
+ An SQLXML object is valid for the duration of the transaction in which it was created.
+ <p>
+ The SQLXML interface provides methods for accessing the XML value
+ as a String, a Reader or Writer, or as a Stream.  The XML value
+ may also be accessed through a Source or set as a Result, which
+ are used with XML Parser APIs such as DOM, SAX, and StAX, as
+ well as with XSLT transforms and XPath evaluations.
+ <p>
+ Methods in the interfaces ResultSet, CallableStatement, and PreparedStatement,
+ such as getSQLXML allow a programmer to access an XML value.
+ In addition, this interface has methods for updating an XML value.
+ <p>
+ The XML value of the SQLXML instance may be obtained as a BinaryStream using
+ <pre>
+   SQLXML sqlxml = resultSet.getSQLXML(column);
+   InputStream binaryStream = sqlxml.getBinaryStream();
+ </pre>
+ For example, to parse an XML value with a DOM parser:
+ <pre>
+   DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+   Document result = parser.parse(binaryStream);
+ </pre>
+ or to parse an XML value with a SAX parser to your handler:
+ <pre>
+   SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+   parser.parse(binaryStream, myHandler);
+ </pre>
+ or to parse an XML value with a StAX parser:
+ <pre>
+   XMLInputFactory factory = XMLInputFactory.newInstance();
+   XMLStreamReader streamReader = factory.createXMLStreamReader(binaryStream);
+ </pre>
+ <p>
+ Because databases may use an optimized representation for the XML,
+ accessing the value through getSource() and
+ setResult() can lead to improved processing performance
+ without serializing to a stream representation and parsing the XML.
+ <p>
+ For example, to obtain a DOM Document Node:
+ <pre>
+   DOMSource domSource = sqlxml.getSource(DOMSource.class);
+   Document document = (Document) domSource.getNode();
+ </pre>
+ or to set the value to a DOM Document Node to myNode:
+ <pre>
+   DOMResult domResult = sqlxml.setResult(DOMResult.class);
+   domResult.setNode(myNode);
+ </pre>
+ or, to send SAX events to your handler:
+ <pre>
+   SAXSource saxSource = sqlxml.getSource(SAXSource.class);
+   XMLReader xmlReader = saxSource.getXMLReader();
+   xmlReader.setContentHandler(myHandler);
+   xmlReader.parse(saxSource.getInputSource());
+ </pre>
+ or, to set the result value from SAX events:
+ <pre>
+   SAXResult saxResult = sqlxml.setResult(SAXResult.class);
+   ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
+   contentHandler.startDocument();
+   // set the XML elements and attributes into the result
+   contentHandler.endDocument();
+ </pre>
+ or, to obtain StAX events:
+ <pre>
+   StAXSource staxSource = sqlxml.getSource(StAXSource.class);
+   XMLStreamReader streamReader = staxSource.getXMLStreamReader();
+ </pre>
+ or, to set the result value from StAX events:
+ <pre>
+   StAXResult staxResult = sqlxml.getResult(StAXResult.class);
+   XMLStreamWriter streamWriter = staxResult.getXMLStreamWriter();
+ </pre>
+ or, to perform XSLT transformations on the XML value using the XSLT in xsltFile
+ output to file resultFile:
+ <pre>
+   File xsltFile = new File("a.xslt");
+   File myFile = new File("result.xml");
+   Transformer xslt = TransformerFactory.newInstance().newTransformer(new StreamSource(xsltFile));
+   Source source = sqlxml.getSource(null);
+   Result result = new StreamResult(myFile);
+   xslt.transform(source, result);
+ </pre>
+ or, to evaluate an XPath expression on the XML value:
+ <pre>
+   XPath xpath = XPathFactory.newInstance().newXPath();
+   DOMSource domSource = sqlxml.getSource(DOMSource.class);
+   Document document = (Document) domSource.getNode();
+   String expression = "/foo/@bar";
+   String barValue = xpath.evaluate(expression, document);
+ </pre>
+ To set the XML value to be the result of an XSLT transform:
+ <pre>
+   File sourceFile = new File("source.xml");
+   Transformer xslt = TransformerFactory.newInstance().newTransformer(new StreamSource(xsltFile));
+   Source streamSource = new StreamSource(sourceFile);
+   Result result = sqlxml.setResult(null);
+   xslt.transform(streamSource, result);
+ </pre>
+ Any Source can be transformed to a Result using the identity transform
+ specified by calling newTransformer():
+ <pre>
+   Transformer identity = TransformerFactory.newInstance().newTransformer();
+   Source source = sqlxml.getSource(null);
+   File myFile = new File("result.xml");
+   Result result = new StreamResult(myFile);
+   identity.transform(source, result);
+ </pre>
+ To write the contents of a Source to standard output:
+ <pre>
+   Transformer identity = TransformerFactory.newInstance().newTransformer();
+   Source source = sqlxml.getSource(null);
+   Result result = new StreamResult(System.out);
+   identity.transform(source, result);
+ </pre>
+ To create a DOMSource from a DOMResult:
+ <pre>
+    DOMSource domSource = new DOMSource(domResult.getNode());
+ </pre>
+ <p>
+ Incomplete or invalid XML values may cause an SQLException when
+ set or the exception may occur when execute() occurs.  All streams
+ must be closed before execute() occurs or an SQLException will be thrown.
+ <p>
+ Reading and writing XML values to or from an SQLXML object can happen at most once.
+ The conceptual states of readable and not readable determine if one
+ of the reading APIs will return a value or throw an exception.
+ The conceptual states of writable and not writable determine if one
+ of the writing APIs will set a value or throw an exception.
+ <p>
+ The state moves from readable to not readable once free() or any of the
+ reading APIs are called: getBinaryStream(), getCharacterStream(), getSource(), and getString().
+ Implementations may also change the state to not writable when this occurs.
+ <p>
+ The state moves from writable to not writeable once free() or any of the
+ writing APIs are called: setBinaryStream(), setCharacterStream(), setResult(), and setString().
+ Implementations may also change the state to not readable when this occurs.
+ <p>
+ All methods on the <code>SQLXML</code> interface must be fully implemented if the
+ JDBC driver supports the data type.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 2.0, a rudimentary client-side SQLXML interface
+ implementation (this class) is supported for local use when the product is
+ built and run under JDK 1.6+ and the SQLXML instance is constructed as the
+ result of calling JDBCConnection.createSQLXML(). <p>
+
+ SQLXML instances retrieved in such a fashion are initially write-only, with
+ the lifecycle of read and write availability constrained in accordance with
+ the documentation of the interface methods. <p>
+
+ When build and run under JDK 1.6+, it is also possible to retrieve read-only
+ SQLXML instances from JDBCResultSet.getSQLXML(...), given that the underlying
+ data can be converted to an XML Document Object Model (DOM). <p>
+
+ However, at the time of this writing (2007-06-12) it is not yet possible to
+ store SQLXML objects directly into an HSQLDB database or to use them directly
+ for HSQLDB statement parameterization purposes.  This is because the SQLXML
+ data type is not yet natively supported by the HSQLDB engine. Instead, a
+ JDBCSQLXML instance must first be read as a string, binary input stream,
+ character input stream and so on, which can then be used for such purposes. <p>
+
+ Here is the current read/write availability lifecycle for JDBCSQLXML:
+
+ <TABLE border="1" cellspacing=1" cellpadding="3">
+     <THEAD valign="bottom">
+         <TR align="center">
+             <TH>
+                 Origin
+             </TH>
+             <TH>
+                 Initially
+             </TH>
+             <TH>
+                 After 1<SUP>st</SUP> Write
+             </TH>
+             <TH>
+                 After 1<SUP>st</SUP> Read
+             </TH>
+             <TH>
+                 After 1<SUP>st</SUP> Free
+             </TH>
+         </TR>
+     </THEAD>
+     <TBODY>
+         <TR >
+             <TH>
+                 <tt>org.hsqldb.jdbc.JDBCConnection.createSQLXML()</tt>
+             </TH>
+             <TD >
+                 Write-only
+             </TD>
+             <TD>
+                 Read-only
+             </TD>
+             <TD>
+                 Not readable or writable
+             </TD>
+             <TD>
+                 Not readable or writable
+             </TD>
+         </TR>
+         <TR>
+             <TH>
+                 <tt>org.hsqldb.jdbc.JDBCResultSet.getSQLXML(...)</tt>
+             </TH>
+             <TD >
+                 Read-only
+             </TD>
+             <TD>
+                 N/A
+             </TD>
+             <TD>
+                 Not readable or writable
+             </TD>
+             <TD>
+                 Not readable or writable
+             </TD>
+         </TR>
+     </TBODY>
+ </TABLE>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>boucherb@users</DD>
+<DT><B>See Also:</B><DD><A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/parsers/package-summary.html?is-external=true"><CODE>javax.xml.parsers</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/package-summary.html?is-external=true"><CODE>javax.xml.stream</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/transform/package-summary.html?is-external=true"><CODE>javax.xml.transform</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/xpath/package-summary.html?is-external=true"><CODE>javax.xml.xpath</CODE></A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Writes to a <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamWriter.html?is-external=true" title="class or interface in javax.xml.stream"><CODE>XMLStreamWriter</CODE></A>
+ from SAX events.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#JDBCSQLXML(javax.xml.transform.Source)">JDBCSQLXML</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/transform/Source.html?is-external=true" title="class or interface in javax.xml.transform">Source</A>&nbsp;source)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new read-only JDBCSQLXML object from the given Source
+ object.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#free()">free</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method closes this object and releases the resources that it held.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#getBinaryStream()">getBinaryStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the XML value designated by this SQLXML instance as a stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#getCharacterStream()">getCharacterStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the XML value designated by this SQLXML instance as a java.io.Reader object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/transform/Source.html?is-external=true" title="class or interface in javax.xml.transform">Source</A>&gt; 
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#getSource(java.lang.Class)">getSource</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;sourceClass)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a Source for reading the XML value designated by this SQLXML instance.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#getString()">getString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a string representation of the XML value designated by this SQLXML instance.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#isReadable()">isReadable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the object's readability status.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#isWritable()">isWritable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the object's readability status.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#setBinaryStream()">setBinaryStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a stream that can be used to write the XML value that this SQLXML instance represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Writer.html?is-external=true" title="class or interface in java.io">Writer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#setCharacterStream()">setCharacterStream</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a stream to be used to write the XML value that this SQLXML instance represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/transform/Result.html?is-external=true" title="class or interface in javax.xml.transform">Result</A>&gt; 
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#setResult(java.lang.Class)">setResult</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;resultClass)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a Result for setting the XML value designated by this SQLXML instance.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html#setString(java.lang.String)">setString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the XML value designated by this SQLXML instance to the given String representation.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JDBCSQLXML(javax.xml.transform.Source)"><!-- --></A><H3>
+JDBCSQLXML</H3>
+<PRE>
+public <B>JDBCSQLXML</B>(<A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/transform/Source.html?is-external=true" title="class or interface in javax.xml.transform">Source</A>&nbsp;source)
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Constructs a new read-only JDBCSQLXML object from the given Source
+ object. <p>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>source</CODE> - a Source representing an SQLXML value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if the argument does not represent a
+      valid SQLXML value</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="free()"><!-- --></A><H3>
+free</H3>
+<PRE>
+public void <B>free</B>()
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>This method closes this object and releases the resources that it held.
+ The SQL XML object becomes invalid and neither readable or writeable
+ when this method is called.
+
+ After <code>free</code> has been called, any attempt to invoke a
+ method other than <code>free</code> will result in a <code>SQLException</code>
+ being thrown.  If <code>free</code> is called multiple times, the subsequent
+ calls to <code>free</code> are treated as a no-op.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#free()" title="class or interface in java.sql">free</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error freeing the XML value.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getBinaryStream()"><!-- --></A><H3>
+getBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io">InputStream</A> <B>getBinaryStream</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the XML value designated by this SQLXML instance as a stream.
+ The bytes of the input stream are interpreted according to appendix F of the XML 1.0 specification.
+ The behavior of this method is the same as ResultSet.getBinaryStream()
+ when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+ <p>
+ The SQL XML object becomes not readable when this method is called and
+ may also become not writable depending on implementation.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#getBinaryStream()" title="class or interface in java.sql">getBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a stream containing the XML data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error processing the XML value.
+   An exception is thrown if the state is not readable.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setBinaryStream()"><!-- --></A><H3>
+setBinaryStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html?is-external=true" title="class or interface in java.io">OutputStream</A> <B>setBinaryStream</B>()
+                             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a stream that can be used to write the XML value that this SQLXML instance represents.
+ The stream begins at position 0.
+ The bytes of the stream are interpreted according to appendix F of the XML 1.0 specification
+ The behavior of this method is the same as ResultSet.updateBinaryStream()
+ when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+ <p>
+ The SQL XML object becomes not writeable when this method is called and
+ may also become not readable depending on implementation.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#setBinaryStream()" title="class or interface in java.sql">setBinaryStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a stream to which data can be written.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error processing the XML value.
+   An exception is thrown if the state is not writable.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCharacterStream()"><!-- --></A><H3>
+getCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io">Reader</A> <B>getCharacterStream</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the XML value designated by this SQLXML instance as a java.io.Reader object.
+ The format of this stream is defined by org.xml.sax.InputSource,
+ where the characters in the stream represent the unicode code points for
+ XML according to section 2 and appendix B of the XML 1.0 specification.
+ Although an encoding declaration other than unicode may be present,
+ the encoding of the stream is unicode.
+ The behavior of this method is the same as ResultSet.getCharacterStream()
+ when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+ <p>
+ The SQL XML object becomes not readable when this method is called and
+ may also become not writable depending on implementation.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#getCharacterStream()" title="class or interface in java.sql">getCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a stream containing the XML data.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error processing the XML value.
+   The getCause() method of the exception may provide a more detailed exception, for example,
+   if the stream does not contain valid characters.
+   An exception is thrown if the state is not readable.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCharacterStream()"><!-- --></A><H3>
+setCharacterStream</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/Writer.html?is-external=true" title="class or interface in java.io">Writer</A> <B>setCharacterStream</B>()
+                          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves a stream to be used to write the XML value that this SQLXML instance represents.
+ The format of this stream is defined by org.xml.sax.InputSource,
+ where the characters in the stream represent the unicode code points for
+ XML according to section 2 and appendix B of the XML 1.0 specification.
+ Although an encoding declaration other than unicode may be present,
+ the encoding of the stream is unicode.
+ The behavior of this method is the same as ResultSet.updateCharacterStream()
+ when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+ <p>
+ The SQL XML object becomes not writeable when this method is called and
+ may also become not readable depending on implementation.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#setCharacterStream()" title="class or interface in java.sql">setCharacterStream</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a stream to which data can be written.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error processing the XML value.
+   The getCause() method of the exception may provide a more detailed exception, for example,
+   if the stream does not contain valid characters.
+   An exception is thrown if the state is not writable.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6 Build 79</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getString()"><!-- --></A><H3>
+getString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getString</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns a string representation of the XML value designated by this SQLXML instance.
+ The format of this String is defined by org.xml.sax.InputSource,
+ where the characters in the stream represent the unicode code points for
+ XML according to section 2 and appendix B of the XML 1.0 specification.
+ Although an encoding declaration other than unicode may be present,
+ the encoding of the String is unicode.
+ The behavior of this method is the same as ResultSet.getString()
+ when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+ <p>
+ The SQL XML object becomes not readable when this method is called and
+ may also become not writable depending on implementation.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#getString()" title="class or interface in java.sql">getString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a string representation of the XML value designated by this SQLXML instance.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error processing the XML value.
+   The getCause() method of the exception may provide a more detailed exception, for example,
+   if the stream does not contain valid characters.
+   An exception is thrown if the state is not readable.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setString(java.lang.String)"><!-- --></A><H3>
+setString</H3>
+<PRE>
+public void <B>setString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;value)
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Sets the XML value designated by this SQLXML instance to the given String representation.
+ The format of this String is defined by org.xml.sax.InputSource,
+ where the characters in the stream represent the unicode code points for
+ XML according to section 2 and appendix B of the XML 1.0 specification.
+ Although an encoding declaration other than unicode may be present,
+ the encoding of the String is unicode.
+ The behavior of this method is the same as ResultSet.updateString()
+ when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+ <p>
+ The SQL XML object becomes not writeable when this method is called and
+ may also become not readable depending on implementation.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#setString(java.lang.String)" title="class or interface in java.sql">setString</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>value</CODE> - the XML value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error processing the XML value.
+   The getCause() method of the exception may provide a more detailed exception, for example,
+   if the stream does not contain valid characters.
+   An exception is thrown if the state is not writable.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSource(java.lang.Class)"><!-- --></A><H3>
+getSource</H3>
+<PRE>
+public &lt;T extends <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/transform/Source.html?is-external=true" title="class or interface in javax.xml.transform">Source</A>&gt; T <B>getSource</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;sourceClass)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns a Source for reading the XML value designated by this SQLXML instance.
+ Sources are used as inputs to XML parsers and XSLT transformers.
+ <p>
+ Sources for XML parsers will have namespace processing on by default.
+ The systemID of the Source is implementation dependent.
+ <p>
+ The SQL XML object becomes not readable when this method is called and
+ may also become not writable depending on implementation.
+ <p>
+ Note that SAX is a callback architecture, so a returned
+ SAXSource should then be set with a content handler that will
+ receive the SAX events from parsing.  The content handler
+ will receive callbacks based on the contents of the XML.
+ <pre>
+   SAXSource saxSource = sqlxml.getSource(SAXSource.class);
+   XMLReader xmlReader = saxSource.getXMLReader();
+   xmlReader.setContentHandler(myHandler);
+   xmlReader.parse(saxSource.getInputSource());
+ </pre>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#getSource(java.lang.Class)" title="class or interface in java.sql">getSource</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sourceClass</CODE> - The class of the source, or null.
+ If the class is null, a vendor specifc Source implementation will be returned.
+ The following classes are supported at a minimum:
+ <pre>
+   javax.xml.transform.dom.DOMSource - returns a DOMSource
+   javax.xml.transform.sax.SAXSource - returns a SAXSource
+   javax.xml.transform.stax.StAXSource - returns a StAXSource
+   javax.xml.transform.stream.StreamSource - returns a StreamSource
+ </pre>
+<DT><B>Returns:</B><DD>a Source for reading the XML value.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error processing the XML value
+   or if this feature is not supported.
+   The getCause() method of the exception may provide a more detailed exception, for example,
+   if an XML parser exception occurs.
+   An exception is thrown if the state is not readable.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6 Build 79</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setResult(java.lang.Class)"><!-- --></A><H3>
+setResult</H3>
+<PRE>
+public &lt;T extends <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/transform/Result.html?is-external=true" title="class or interface in javax.xml.transform">Result</A>&gt; T <B>setResult</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;resultClass)
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns a Result for setting the XML value designated by this SQLXML instance.
+ <p>
+ The systemID of the Result is implementation dependent.
+ <p>
+ The SQL XML object becomes not writeable when this method is called and
+ may also become not readable depending on implementation.
+ <p>
+ Note that SAX is a callback architecture and the returned
+ SAXResult has a content handler assigned that will receive the
+ SAX events based on the contents of the XML.  Call the content
+ handler with the contents of the XML document to assign the values.
+ <pre>
+   SAXResult saxResult = sqlxml.getResult(SAXResult.class);
+   ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
+   contentHandler.startDocument();
+   // set the XML elements and attributes into the result
+   contentHandler.endDocument();
+ </pre>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true#setResult(java.lang.Class)" title="class or interface in java.sql">setResult</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>resultClass</CODE> - The class of the result, or null.
+ If resultClass is null, a vendor specific Result implementation will be returned.
+ The following classes are supported at a minimum:
+ <pre>
+   javax.xml.transform.dom.DOMResult - returns a DOMResult
+   javax.xml.transform.sax.SAXResult - returns a SAXResult
+   javax.xml.transform.stax.StAXResult - returns a StAXResult
+   javax.xml.transform.stream.StreamResult - returns a StreamResult
+ </pre>
+<DT><B>Returns:</B><DD>Returns a Result for setting the XML value.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if there is an error processing the XML value
+   or if this feature is not supported.
+   The getCause() method of the exception may provide a more detailed exception, for example,
+   if an XML parser exception occurs.
+   An exception is thrown if the state is not writable.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.6 Build 79</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isReadable()"><!-- --></A><H3>
+isReadable</H3>
+<PRE>
+public boolean <B>isReadable</B>()</PRE>
+<DL>
+<DD>Retrieves the object's readability status.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>if <tt>true</tt>, then readable; else not readable</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWritable()"><!-- --></A><H3>
+isWritable</H3>
+<PRE>
+public boolean <B>isWritable</B>()</PRE>
+<DL>
+<DD>Retrieves the object's readability status.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>if <tt>true</tt>, then writable; else not writable</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCSQLXML.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCSQLXML.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSQLXML.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCSavepoint.html b/doc/apidocs/org/hsqldb/jdbc/JDBCSavepoint.html
new file mode 100644
index 0000000..508e69b
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCSavepoint.html
@@ -0,0 +1,321 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCSavepoint (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCSavepoint (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCSavepoint.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCSavepoint.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSavepoint.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCSavepoint</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCSavepoint</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCSavepoint</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A></DL>
+</PRE>
+
+<P>
+The representation of a savepoint, which is a point within
+ the current transaction that can be referenced from the
+ <code>Connection.rollback</code> method. When a transaction
+ is rolled back to a savepoint all changes made after that
+ savepoint are undone.
+ <p>
+ Savepoints can be either named or unnamed. Unnamed savepoints
+ are identified by an ID generated by the underlying data source.
+
+ <!-- start Release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ SQL 2003 standard does not support unnamed savepoints. However, this
+ feature is supported from version 2.0.<p>
+
+ If the connection is autoCommit, setting savepoints has no effect as any
+ such savepoint is cleared upon the execution of the first transactional
+ statement. <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>boucherb@users</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html#getSavepointId()">getSavepointId</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the generated ID for the savepoint that this
+ <code>Savepoint</code> object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html#getSavepointName()">getSavepointName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the name of the savepoint that this <code>Savepoint</code>
+ object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getSavepointId()"><!-- --></A><H3>
+getSavepointId</H3>
+<PRE>
+public int <B>getSavepointId</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the generated ID for the savepoint that this
+ <code>Savepoint</code> object represents.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true#getSavepointId()" title="class or interface in java.sql">getSavepointId</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the numeric ID of this savepoint
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if this is a named savepoint<DT><B>Since:</B></DT>
+  <DD>1.4</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSavepointName()"><!-- --></A><H3>
+getSavepointName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getSavepointName</B>()
+                        throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves the name of the savepoint that this <code>Savepoint</code>
+ object represents.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true#getSavepointName()" title="class or interface in java.sql">getSavepointName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the name of this savepoint
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if this is an un-named savepoint<DT><B>Since:</B></DT>
+  <DD>1.4</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>toString</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCSavepoint.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCSavepoint.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSavepoint.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/JDBCStatement.html b/doc/apidocs/org/hsqldb/jdbc/JDBCStatement.html
new file mode 100644
index 0000000..3205b5c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/JDBCStatement.html
@@ -0,0 +1,2424 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+JDBCStatement (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="JDBCStatement (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCStatement.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class JDBCStatement</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.JDBCStatement</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JDBCStatement</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></DL>
+</PRE>
+
+<P>
+<!-- start generic documentation -->
+ <P>The object used for executing a static SQL statement
+ and returning the results it produces.
+ <P>
+ By default, only one <code>ResultSet</code> object per <code>Statement</code>
+ object can be open at the same time. Therefore, if the reading of one
+ <code>ResultSet</code> object is interleaved
+ with the reading of another, each must have been generated by
+ different <code>Statement</code> objects. All execution methods in the
+ <code>Statement</code> interface implicitly close a statment's current
+ <code>ResultSet</code> object if an open one exists.
+ <!-- end generic documentation-->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3><p>
+ From version 2.0, the implementation meets the JDBC specification
+ requirment that any existing ResultSet is closed when execute() or
+ executeQuery() methods are called.
+ <p>
+
+ <b>JRE 1.1.x Notes:</b> <p>
+
+ In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ versions of JDBC depends on the JDK version used for compiling and building
+ HSQLDB.<p>
+
+ Since 1.7.0, all JDBC 2 methods can be called while executing under the
+ version 1.1.x
+ <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ However, in addition to this technique requiring explicit casts to the
+ org.hsqldb.jdbc.* classes, some of these method calls require
+ <code>int</code> values that are defined only in the JDBC 2 or greater
+ version of the <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql"><CODE>ResultSet</CODE></A> interface.  For this
+ reason these values are defined in <A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A>.<p>
+
+ In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ to them in parameter specifications and return value comparisons,
+ respectively, as follows: <p>
+
+ <pre class="JavaCodeExample">
+ JDBCResultSet.FETCH_FORWARD
+ JDBCResultSet.TYPE_FORWARD_ONLY
+ JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ JDBCResultSet.CONCUR_READ_ONLY
+ //etc.
+ </pre> <p>
+
+ However, please note that code written to use HSQLDB JDBC 2 features under
+ JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
+ also note that this feature is offered solely as a convenience to developers
+ who must work under JDK 1.1.x due to operating constraints, yet wish to
+ use some of the more advanced features available under the JDBC 2
+ specification. <p>
+
+ (fredt@users)<br>
+ (boucherb@users)<p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html#createStatement()"><CODE>JDBCConnection.createStatement()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><CODE>JDBCResultSet</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.sql.Statement"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#CLOSE_ALL_RESULTS" title="class or interface in java.sql">CLOSE_ALL_RESULTS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#CLOSE_CURRENT_RESULT" title="class or interface in java.sql">CLOSE_CURRENT_RESULT</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#EXECUTE_FAILED" title="class or interface in java.sql">EXECUTE_FAILED</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#KEEP_CURRENT_RESULT" title="class or interface in java.sql">KEEP_CURRENT_RESULT</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#NO_GENERATED_KEYS" title="class or interface in java.sql">NO_GENERATED_KEYS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#RETURN_GENERATED_KEYS" title="class or interface in java.sql">RETURN_GENERATED_KEYS</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#SUCCESS_NO_INFO" title="class or interface in java.sql">SUCCESS_NO_INFO</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#addBatch(java.lang.String)">addBatch</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Adds the given SQL command to the current list of commmands for this
+ <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#cancel()">cancel</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cancels this <code>Statement</code> object if both the DBMS and
+ driver support aborting an SQL statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#clearBatch()">clearBatch</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Empties this <code>Statement</code> object's current list of
+ SQL commands.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#clearWarnings()">clearWarnings</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clears all the warnings reported on this <code>Statement</code>
+ object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#close()">close</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Releases this <code>Statement</code> object's database
+ and JDBC resources immediately instead of waiting for
+ this to happen when it is automatically closed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String)">execute</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement, which may return multiple results.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String, int)">execute</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+        int&nbsp;autoGeneratedKeys)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement, which may return multiple results,
+ and signals the driver that any
+ auto-generated keys should be made available
+ for retrieval.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String, int[])">execute</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+        int[]&nbsp;columnIndexes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement, which may return multiple results,
+ and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String, java.lang.String[])">execute</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+        <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement, which may return multiple results,
+ and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeBatch()">executeBatch</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Submits a batch of commands to the database for execution and
+ if all commands execute successfully, returns an array of update counts.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeQuery(java.lang.String)">executeQuery</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement, which returns a single
+ <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeUpdate(java.lang.String)">executeUpdate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement, which may be an <code>INSERT</code>,
+ <code>UPDATE</code>, or <code>DELETE</code> statement or an
+ SQL statement that returns nothing, such as an SQL DDL statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeUpdate(java.lang.String, int)">executeUpdate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+              int&nbsp;autoGeneratedKeys)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement and signals the driver with the
+ given flag about whether the
+ auto-generated keys produced by this <code>Statement</code> object
+ should be made available for retrieval.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeUpdate(java.lang.String, int[])">executeUpdate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+              int[]&nbsp;columnIndexes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeUpdate(java.lang.String, java.lang.String[])">executeUpdate</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the given SQL statement and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getConnection()">getConnection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the <code>Connection</code> object
+ that produced this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getFetchDirection()">getFetchDirection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the direction for fetching rows from
+ database tables that is the default for result sets
+ generated from this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getFetchSize()">getFetchSize</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the number of result set rows that is the default
+ fetch size for <code>ResultSet</code> objects
+ generated from this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getGeneratedKeys()">getGeneratedKeys</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves any auto-generated keys created as a result of executing this
+ <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMaxFieldSize()">getMaxFieldSize</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of bytes that can be
+ returned for character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMaxRows()">getMaxRows</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the maximum number of rows that a
+ <code>ResultSet</code> object produced by this
+ <code>Statement</code> object can contain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMoreResults()">getMoreResults</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves to this <code>Statement</code> object's next result, returns
+ <code>true</code> if it is a <code>ResultSet</code> object, and
+ implicitly closes any current <code>ResultSet</code>
+ object(s) obtained with the method <code>getResultSet</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMoreResults(int)">getMoreResults</A></B>(int&nbsp;current)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moves to this <code>Statement</code> object's next result, deals with
+ any current <code>ResultSet</code> object(s) according  to the instructions
+ specified by the given flag, and returns
+ <code>true</code> if the next result is a <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getQueryTimeout()">getQueryTimeout</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the number of seconds the driver will
+ wait for a <code>Statement</code> object to execute.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSet()">getResultSet</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the current result as a <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSetConcurrency()">getResultSetConcurrency</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the result set concurrency for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSetHoldability()">getResultSetHoldability</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the result set holdability for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSetType()">getResultSetType</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the result set type for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getUpdateCount()">getUpdateCount</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the current result as an update count;
+  if the result is a <code>ResultSet</code> object or there are no more results, -1
+  is returned.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getWarnings()">getWarnings</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the first warning reported by calls on this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#isClosed()">isClosed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this <code>Statement</code> object has been closed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#isPoolable()">isPoolable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a  value indicating whether the <code>Statement</code>
+ is poolable or not.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#isWrapperFor(java.lang.Class)">isWrapperFor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setCursorName(java.lang.String)">setCursorName</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the SQL cursor name to the given <code>String</code>, which
+ will be used by subsequent <code>Statement</code> object
+ <code>execute</code> methods.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setEscapeProcessing(boolean)">setEscapeProcessing</A></B>(boolean&nbsp;enable)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets escape processing on or off.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setFetchDirection(int)">setFetchDirection</A></B>(int&nbsp;direction)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gives the driver a hint as to the direction in which
+ rows will be processed in <code>ResultSet</code>
+ objects created using this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setFetchSize(int)">setFetchSize</A></B>(int&nbsp;rows)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for
+ <code>ResultSet</code> objects genrated by this <code>Statement</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setMaxFieldSize(int)">setMaxFieldSize</A></B>(int&nbsp;max)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:) Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
+ Sets the limit for the maximum number of bytes that can be returned for
+ character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setMaxRows(int)">setMaxRows</A></B>(int&nbsp;max)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(JDBC4 clarification:)
+ Sets the limit for the maximum number of rows that any
+ <code>ResultSet</code> object  generated by this <code>Statement</code>
+ object can contain to the given number.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setPoolable(boolean)">setPoolable</A></B>(boolean&nbsp;poolable)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Requests that a <code>Statement</code> be pooled or not pooled.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setQueryTimeout(int)">setQueryTimeout</A></B>(int&nbsp;seconds)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the number of seconds the driver will wait for a
+ <code>Statement</code> object to execute to the given number of seconds.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T&gt; T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#unwrap(java.lang.Class)">unwrap</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="executeQuery(java.lang.String)"><!-- --></A><H3>
+executeQuery</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>executeQuery</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement, which returns a single
+ <code>ResultSet</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ This method should not be used for statements other than SELECT queries.<p>
+
+ From 2.0, HSQLDB throws an exception when the statement
+ is a DDL statement or an UPDATE or DELETE statement.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeQuery(java.lang.String)" title="class or interface in java.sql">executeQuery</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL statement to be sent to the database, typically a
+        static SQL <code>SELECT</code> statement
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object that contains the data produced
+         by the given query; never <code>null</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the given
+            SQL statement produces anything other than a single
+            <code>ResultSet</code> object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate(java.lang.String)"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement, which may be an <code>INSERT</code>,
+ <code>UPDATE</code>, or <code>DELETE</code> statement or an
+ SQL statement that returns nothing, such as an SQL DDL statement.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String)" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - (JDBC4 clarification:) an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+ <code>DELETE</code>; or an SQL statement that returns nothing,
+ such as a DDL statement.
+<DT><B>Returns:</B><DD>(JDBC4 clarification:) either (1) the row count for SQL Data Manipulation Language (DML) statements
+         or (2) 0 for SQL statements that return nothing
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the given
+            SQL statement produces a <code>ResultSet</code> object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="close()"><!-- --></A><H3>
+close</H3>
+<PRE>
+public void <B>close</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Releases this <code>Statement</code> object's database
+ and JDBC resources immediately instead of waiting for
+ this to happen when it is automatically closed.
+ It is generally good practice to release resources as soon as
+ you are finished with them to avoid tying up database
+ resources.
+ <P>
+ Calling the method <code>close</code> on a <code>Statement</code>
+ object that is already closed has no effect.
+ <P>
+ <B>Note:</B>When a <code>Statement</code> object is
+ closed, its current <code>ResultSet</code> object, if one exists, is
+ also closed.
+ (JDBC4 deleted:) [A <code>Statement</code> object is
+ automatically closed when it is garbage collected.]
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#close()" title="class or interface in java.sql">close</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxFieldSize()"><!-- --></A><H3>
+getMaxFieldSize</H3>
+<PRE>
+public int <B>getMaxFieldSize</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the maximum number of bytes that can be
+ returned for character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.
+ This limit applies only to  <code>BINARY</code>, <code>VARBINARY</code>,
+ <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
+ (JDBC4 new:) <code>NCHAR</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>
+ and <code>LONGVARCHAR</code> columns.  If the limit is exceeded, the
+ excess data is silently discarded.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 1.7.2, HSQLDB always returns zero, meaning there
+ is no limit.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMaxFieldSize()" title="class or interface in java.sql">getMaxFieldSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current column size limit for columns storing character and
+         binary values; zero means there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setMaxFieldSize(int)"><CODE>setMaxFieldSize(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMaxFieldSize(int)"><!-- --></A><H3>
+setMaxFieldSize</H3>
+<PRE>
+public void <B>setMaxFieldSize</B>(int&nbsp;max)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:) Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
+ Sets the limit for the maximum number of bytes that can be returned for
+ character and binary column values in a <code>ResultSet</code>
+ object produced by this <code>Statement</code> object.
+
+ This limit applies
+ only to <code>BINARY</code>, <code>VARBINARY</code>,
+ <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
+ (JDBC4 new:) <code>NCHAR</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code> and
+ <code>LONGVARCHAR</code> fields.  If the limit is exceeded, the excess data
+ is silently discarded. For maximum portability, use values
+ greater than 256.
+ <!-- emd generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ To present, calls to this method are simply ignored; HSQLDB always
+ stores the full number of bytes when dealing with any of the field types
+ mentioned above. These types all have an absolute maximum element upper
+ bound determined by the Java array index limit
+ java.lang.Integer.MAX_VALUE.  For XXXBINARY types, this translates to
+ Integer.MAX_VALUE bytes.  For XXXCHAR types, this translates to
+ 2 * Integer.MAX_VALUE bytes (2 bytes / character). <p>
+
+ In practice, field sizes are limited to values much smaller than the
+ absolute maximum element upper bound, in particular due to limits imposed
+ on the maximum available Java heap memory.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setMaxFieldSize(int)" title="class or interface in java.sql">setMaxFieldSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>max</CODE> - the new column size limit in bytes; zero means there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>
+            or the condition max >= 0 is not satisfied<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMaxFieldSize()"><CODE>getMaxFieldSize()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxRows()"><!-- --></A><H3>
+getMaxRows</H3>
+<PRE>
+public int <B>getMaxRows</B>()
+               throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the maximum number of rows that a
+ <code>ResultSet</code> object produced by this
+ <code>Statement</code> object can contain.  If this limit is exceeded,
+ the excess rows are silently dropped.
+ <!-- start generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMaxRows()" title="class or interface in java.sql">getMaxRows</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current maximum number of rows for a <code>ResultSet</code>
+         object produced by this <code>Statement</code> object;
+         zero means there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setMaxRows(int)"><CODE>setMaxRows(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMaxRows(int)"><!-- --></A><H3>
+setMaxRows</H3>
+<PRE>
+public void <B>setMaxRows</B>(int&nbsp;max)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Sets the limit for the maximum number of rows that any
+ <code>ResultSet</code> object  generated by this <code>Statement</code>
+ object can contain to the given number.
+ If the limit is exceeded, the excess
+ rows are silently dropped.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setMaxRows(int)" title="class or interface in java.sql">setMaxRows</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>max</CODE> - the new max rows limit; zero means there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>
+            or the condition max >= 0 is not satisfied<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMaxRows()"><CODE>getMaxRows()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setEscapeProcessing(boolean)"><!-- --></A><H3>
+setEscapeProcessing</H3>
+<PRE>
+public void <B>setEscapeProcessing</B>(boolean&nbsp;enable)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets escape processing on or off.
+ If escape scanning is on (the default), the driver will do
+ escape substitution before sending the SQL statement to the database.
+
+ Note: Since prepared statements have usually been parsed prior
+ to making this call, disabling escape processing for
+ <code>PreparedStatements</code> objects will have no effect.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setEscapeProcessing(boolean)" title="class or interface in java.sql">setEscapeProcessing</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>enable</CODE> - <code>true</code> to enable escape processing;
+       <code>false</code> to disable it
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getQueryTimeout()"><!-- --></A><H3>
+getQueryTimeout</H3>
+<PRE>
+public int <B>getQueryTimeout</B>()
+                    throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the number of seconds the driver will
+ wait for a <code>Statement</code> object to execute.
+ If the limit is exceeded, a
+ <code>SQLException</code> is thrown.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ To present, HSQLDB always returns zero, meaning there
+ is no limit.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getQueryTimeout()" title="class or interface in java.sql">getQueryTimeout</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current query timeout limit in seconds; zero means there is
+         no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setQueryTimeout(int)"><CODE>setQueryTimeout(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setQueryTimeout(int)"><!-- --></A><H3>
+setQueryTimeout</H3>
+<PRE>
+public void <B>setQueryTimeout</B>(int&nbsp;seconds)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the number of seconds the driver will wait for a
+ <code>Statement</code> object to execute to the given number of seconds.
+ If the limit is exceeded, an <code>SQLException</code> is thrown. A JDBC
+ (JDBC4 clarification:)
+ driver must apply this limit to the <code>execute</code>,
+ <code>executeQuery</code> and <code>executeUpdate</code> methods. JDBC driver
+ implementations may also apply this limit to <code>ResultSet</code> methods
+ (consult your driver vendor documentation for details).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ The maximum value is Short.MAX_VALUE. The minimum is 0, indicating no limit.
+ In version 2.0, calls to this method are ignored; HSQLDB waits an
+ unlimited amount of time for statement execution
+ requests to return.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setQueryTimeout(int)" title="class or interface in java.sql">setQueryTimeout</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>seconds</CODE> - the new query timeout limit in seconds; zero means
+        there is no limit
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>
+            or the condition seconds >= 0 is not satisfied<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getQueryTimeout()"><CODE>getQueryTimeout()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="cancel()"><!-- --></A><H3>
+cancel</H3>
+<PRE>
+public void <B>cancel</B>()
+            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Cancels this <code>Statement</code> object if both the DBMS and
+ driver support aborting an SQL statement.
+ This method can be used by one thread to cancel a statement that
+ is being executed by another thread.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, HSQLDB does <i>not</i> support aborting an SQL
+ statement; calls to this method are ignored.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#cancel()" title="class or interface in java.sql">cancel</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWarnings()"><!-- --></A><H3>
+getWarnings</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A> <B>getWarnings</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the first warning reported by calls on this <code>Statement</code> object.
+ Subsequent <code>Statement</code> object warnings will be chained to this
+ <code>SQLWarning</code> object.
+
+ <p>The warning chain is automatically cleared each time
+ a statement is (re)executed. This method may not be called on a closed
+ <code>Statement</code> object; doing so will cause an <code>SQLException</code>
+ to be thrown.
+
+ <P><B>Note:</B> If you are processing a <code>ResultSet</code> object, any
+ warnings associated with reads on that <code>ResultSet</code> object
+ will be chained on it rather than on the <code>Statement</code>
+ object that produced it.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ In 2.0, HSQLDB may produces Statement warnings;
+ this method always returns null.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getWarnings()" title="class or interface in java.sql">getWarnings</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the first <code>SQLWarning</code> object or <code>null</code>
+         if there are no warnings
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clearWarnings()"><!-- --></A><H3>
+clearWarnings</H3>
+<PRE>
+public void <B>clearWarnings</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Clears all the warnings reported on this <code>Statement</code>
+ object. After a call to this method,
+ the method <code>getWarnings</code> will return
+ <code>null</code> until a new warning is reported for this
+ <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ In HSQLDB 2.0, <code>SQLWarning</code> objects may
+ be produced for Statement Objects; calls to this method clear the warnings.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#clearWarnings()" title="class or interface in java.sql">clearWarnings</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCursorName(java.lang.String)"><!-- --></A><H3>
+setCursorName</H3>
+<PRE>
+public void <B>setCursorName</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Sets the SQL cursor name to the given <code>String</code>, which
+ will be used by subsequent <code>Statement</code> object
+ <code>execute</code> methods. This name can then be
+ used in SQL positioned update or delete statements to identify the
+ current row in the <code>ResultSet</code> object generated by this
+ statement.  If the database does not support positioned update/delete,
+ this method is a noop.  To insure that a cursor has the proper isolation
+ level to support updates, the cursor's <code>SELECT</code> statement
+ should have the form <code>SELECT FOR UPDATE</code>.  If
+ <code>FOR UPDATE</code> is not present, positioned updates may fail.
+
+ <P><B>Note:</B> By definition, the execution of positioned updates and
+ deletes must be done by a different <code>Statement</code> object than
+ the one that generated the <code>ResultSet</code> object being used for
+ positioning. Also, cursor names must be unique within a connection.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Including 2.0, HSQLDB does not support named cursors;
+ calls to this method are ignored.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setCursorName(java.lang.String)" title="class or interface in java.sql">setCursorName</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the new cursor name, which must be unique within
+             a connection
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute(java.lang.String)"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement, which may return multiple results.
+ In some (uncommon) situations, a single SQL statement may return
+ multiple result sets and/or update counts.  Normally you can ignore
+ this unless you are (1) executing a stored procedure that you know may
+ return multiple results or (2) you are dynamically executing an
+ unknown SQL string.
+ <P>
+ The <code>execute</code> method executes an SQL statement and indicates the
+ form of the first result.  You must then use the methods
+ <code>getResultSet</code> or <code>getUpdateCount</code>
+ to retrieve the result, and <code>getMoreResults</code> to
+ move to any subsequent result(s).
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String)" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - any SQL statement
+<DT><B>Returns:</B><DD><code>true</code> if the first result is a <code>ResultSet</code>
+         object; <code>false</code> if it is an update count or there are
+         no results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSet()"><CODE>getResultSet()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getUpdateCount()"><CODE>getUpdateCount()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMoreResults()"><CODE>getMoreResults()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSet()"><!-- --></A><H3>
+getResultSet</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getResultSet</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+  Retrieves the current result as a <code>ResultSet</code> object.
+  This method should be called only once per result.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSet()" title="class or interface in java.sql">getResultSet</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current result as a <code>ResultSet</code> object or
+ <code>null</code> if the result is an update count or there are no more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String)"><CODE>execute(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUpdateCount()"><!-- --></A><H3>
+getUpdateCount</H3>
+<PRE>
+public int <B>getUpdateCount</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+  Retrieves the current result as an update count;
+  if the result is a <code>ResultSet</code> object or there are no more results, -1
+  is returned. This method should be called only once per result.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getUpdateCount()" title="class or interface in java.sql">getUpdateCount</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the current result as an update count; -1 if the current result is a
+ <code>ResultSet</code> object or there are no more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String)"><CODE>execute(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMoreResults()"><!-- --></A><H3>
+getMoreResults</H3>
+<PRE>
+public boolean <B>getMoreResults</B>()
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves to this <code>Statement</code> object's next result, returns
+ <code>true</code> if it is a <code>ResultSet</code> object, and
+ implicitly closes any current <code>ResultSet</code>
+ object(s) obtained with the method <code>getResultSet</code>.
+
+ <P>There are no more results when the following is true:
+ <PRE>
+     // stmt is a Statement object
+     ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
+ </PRE>
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMoreResults()" title="class or interface in java.sql">getMoreResults</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the next result is a <code>ResultSet</code>
+         object; <code>false</code> if it is an update count or there are
+         no more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String)"><CODE>execute(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFetchDirection(int)"><!-- --></A><H3>
+setFetchDirection</H3>
+<PRE>
+public void <B>setFetchDirection</B>(int&nbsp;direction)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Gives the driver a hint as to the direction in which
+ rows will be processed in <code>ResultSet</code>
+ objects created using this <code>Statement</code> object.  The
+ default value is <code>ResultSet.FETCH_FORWARD</code>.
+ <P>
+ Note that this method sets the default fetch direction for
+ result sets generated by this <code>Statement</code> object.
+ Each result set has its own methods for getting and setting
+ its own fetch direction.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB accepts all valid parameters. <p>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setFetchDirection(int)" title="class or interface in java.sql">setFetchDirection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>direction</CODE> - the initial direction for processing rows
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>
+ or the given direction
+ is not one of <code>ResultSet.FETCH_FORWARD</code>,
+ <code>ResultSet.FETCH_REVERSE</code>, or <code>ResultSet.FETCH_UNKNOWN</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+    for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getFetchDirection()"><CODE>getFetchDirection()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFetchDirection()"><!-- --></A><H3>
+getFetchDirection</H3>
+<PRE>
+public int <B>getFetchDirection</B>()
+                      throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the direction for fetching rows from
+ database tables that is the default for result sets
+ generated from this <code>Statement</code> object.
+ If this <code>Statement</code> object has not set
+ a fetch direction by calling the method <code>setFetchDirection</code>,
+ the return value is implementation-specific.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB returns the fetch direction. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getFetchDirection()" title="class or interface in java.sql">getFetchDirection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the default fetch direction for result sets generated
+          from this <code>Statement</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+    for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setFetchDirection(int)"><CODE>setFetchDirection(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setFetchSize(int)"><!-- --></A><H3>
+setFetchSize</H3>
+<PRE>
+public void <B>setFetchSize</B>(int&nbsp;rows)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ (JDBC4 clarification:)
+ Gives the JDBC driver a hint as to the number of rows that should
+ be fetched from the database when more rows are needed for
+ <code>ResultSet</code> objects genrated by this <code>Statement</code>.
+ If the value specified is zero, then the hint is ignored.
+ The default value is zero.
+ <!-- start generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB uses the specified value as a hint, but may process more or fewer
+ rows than specified.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setFetchSize(int)" title="class or interface in java.sql">setFetchSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>rows</CODE> - the number of rows to fetch
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the
+        (JDBC4 modified:)
+        condition  <code>rows >= 0</code> is not satisfied.<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+   for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getFetchSize()"><CODE>getFetchSize()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFetchSize()"><!-- --></A><H3>
+getFetchSize</H3>
+<PRE>
+public int <B>getFetchSize</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the number of result set rows that is the default
+ fetch size for <code>ResultSet</code> objects
+ generated from this <code>Statement</code> object.
+ If this <code>Statement</code> object has not set
+ a fetch size by calling the method <code>setFetchSize</code>,
+ the return value is implementation-specific.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <b>HSQLDB-Specific Information</b> <p>
+
+ HSQLDB returns 0 by default, or the fetch size specified by setFetchSize
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getFetchSize()" title="class or interface in java.sql">getFetchSize</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the default fetch size for result sets generated
+          from this <code>Statement</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+  for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setFetchSize(int)"><CODE>setFetchSize(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSetConcurrency()"><!-- --></A><H3>
+getResultSetConcurrency</H3>
+<PRE>
+public int <B>getResultSetConcurrency</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the result set concurrency for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB supports <code>CONCUR_READ_ONLY</code> and
+ <code>CONCUR_UPDATABLE</code> concurrency.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetConcurrency()" title="class or interface in java.sql">getResultSetConcurrency</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>either <code>ResultSet.CONCUR_READ_ONLY</code> or
+ <code>ResultSet.CONCUR_UPDATABLE</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+  for JDBCStatement)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSetType()"><!-- --></A><H3>
+getResultSetType</H3>
+<PRE>
+public int <B>getResultSetType</B>()
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the result set type for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB 1.7.0 and later versions support <code>TYPE_FORWARD_ONLY</code>
+ and <code>TYPE_SCROLL_INSENSITIVE</code>.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetType()" title="class or interface in java.sql">getResultSetType</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+ <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+ <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+   for JDBCStatement)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addBatch(java.lang.String)"><!-- --></A><H3>
+addBatch</H3>
+<PRE>
+public void <B>addBatch</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql)
+              throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Adds the given SQL command to the current list of commmands for this
+ <code>Statement</code> object. The commands in this list can be
+ executed as a batch by calling the method <code>executeBatch</code>.
+ <P>
+ (JDBC4 clarification:)<p>
+ <B>NOTE:</B>  Support of an ability to batch updates is optional.
+
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.7.2, this feature is supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#addBatch(java.lang.String)" title="class or interface in java.sql">addBatch</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - typically this is a SQL <code>INSERT</code> or
+ <code>UPDATE</code> statement
+ (:JDBC4 modified)
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the
+ driver does not support batch updates<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+   for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#executeBatch()"><CODE>executeBatch()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clearBatch()"><!-- --></A><H3>
+clearBatch</H3>
+<PRE>
+public void <B>clearBatch</B>()
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Empties this <code>Statement</code> object's current list of
+ SQL commands.
+ <P>
+ (JDBC4 clarification:) <p>
+ <B>NOTE:</B>  Support of an ability to batch updates is optional.
+ <!-- start generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 1.7.2, this feature is supported.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#clearBatch()" title="class or interface in java.sql">clearBatch</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+  this method is called on a closed <code>Statement</code> or the
+ driver does not support batch updates<DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+   for JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#addBatch(java.lang.String)"><CODE>addBatch(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeBatch()"><!-- --></A><H3>
+executeBatch</H3>
+<PRE>
+public int[] <B>executeBatch</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Submits a batch of commands to the database for execution and
+ if all commands execute successfully, returns an array of update counts.
+ The <code>int</code> elements of the array that is returned are ordered
+ to correspond to the commands in the batch, which are ordered
+ according to the order in which they were added to the batch.
+ The elements in the array returned by the method <code>executeBatch</code>
+ may be one of the following:
+ <OL>
+ <LI>A number greater than or equal to zero -- indicates that the
+ command was processed successfully and is an update count giving the
+ number of rows in the database that were affected by the command's
+ execution
+ <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was
+ processed successfully but that the number of rows affected is
+ unknown
+ <P>
+ If one of the commands in a batch update fails to execute properly,
+ this method throws a <code>BatchUpdateException</code>, and a JDBC
+ driver may or may not continue to process the remaining commands in
+ the batch.  However, the driver's behavior must be consistent with a
+ particular DBMS, either always continuing to process commands or never
+ continuing to process commands.  If the driver continues processing
+ after a failure, the array returned by the method
+ <code>BatchUpdateException.getUpdateCounts</code>
+ will contain as many elements as there are commands in the batch, and
+ at least one of the elements will be the following:
+ <P>
+ <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command failed
+ to execute successfully and occurs only if a driver continues to
+ process commands after a command fails
+ </OL>
+ <P>
+ (JDBC4 clarification:) <p>
+ <B>NOTE:</B>  Support of an ability to batch updates is optional.
+ <p>
+ The possible implementations and return values have been modified in
+ the Java 2 SDK, Standard Edition, version 1.3 to
+ accommodate the option of continuing to proccess commands in a batch
+ update after a <code>BatchUpdateException</code> obejct has been thrown.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with HSQLDB 1.7.2, this feature is supported. <p>
+
+ HSQLDB stops execution of commands in a batch when one of the commands
+ results in an exception. The size of the returned array equals the
+ number of commands that were executed successfully.<p>
+
+ When the product is built under the JAVA1 target, an exception
+ is never thrown and it is the responsibility of the client software to
+ check the size of the  returned update count array to determine if any
+ batch items failed.  To build and run under the JAVA2 target, JDK/JRE
+ 1.3 or higher must be used.
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeBatch()" title="class or interface in java.sql">executeBatch</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of update counts containing one element for each
+ command in the batch.  The elements of the array are ordered according
+ to the order in which commands were added to the batch.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the
+ driver does not support batch statements. Throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/BatchUpdateException.html?is-external=true" title="class or interface in java.sql"><CODE>BatchUpdateException</CODE></A>
+ (a subclass of <code>SQLException</code>) if one of the commands sent to the
+ database fails to execute properly or attempts to return a result set.<DT><B>Since:</B></DT>
+  <DD>JDK 1.3 (JDK 1.1.x developers: read the overview for
+ JDBCStatement)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#addBatch(java.lang.String)"><CODE>addBatch(java.lang.String)</CODE></A>, 
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true#supportsBatchUpdates()" title="class or interface in java.sql"><CODE>DatabaseMetaData.supportsBatchUpdates()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConnection()"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the <code>Connection</code> object
+ that produced this <code>Statement</code> object.
+ <!-- end generic documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getConnection()" title="class or interface in java.sql">getConnection</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the connection that produced this statement
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.2 (JDK 1.1.x developers: read the overview
+    for JDBCStatement)</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMoreResults(int)"><!-- --></A><H3>
+getMoreResults</H3>
+<PRE>
+public boolean <B>getMoreResults</B>(int&nbsp;current)
+                       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Moves to this <code>Statement</code> object's next result, deals with
+ any current <code>ResultSet</code> object(s) according  to the instructions
+ specified by the given flag, and returns
+ <code>true</code> if the next result is a <code>ResultSet</code> object.
+
+ <P>There are no more results when the following is true:
+ <PRE>
+     // stmt is a Statement object
+     ((stmt.getMoreResults(current) == false) && (stmt.getUpdateCount() == -1))
+ </PRE>
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ HSQLDB moves to the next ResultSet and returns the correct result. <p>
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getMoreResults(int)" title="class or interface in java.sql">getMoreResults</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>current</CODE> - one of the following <code>Statement</code>
+        constants indicating what should happen to current
+        <code>ResultSet</code> objects obtained using the method
+        <code>getResultSet</code>:
+        <code>Statement.CLOSE_CURRENT_RESULT</code>,
+        <code>Statement.KEEP_CURRENT_RESULT</code>, or
+        <code>Statement.CLOSE_ALL_RESULTS</code>
+<DT><B>Returns:</B><DD><code>true</code> if the next result is a <code>ResultSet</code>
+         object; <code>false</code> if it is an update count or there are no
+         more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the argument
+             supplied is not one of the following:
+        <code>Statement.CLOSE_CURRENT_RESULT</code>,
+        <code>Statement.KEEP_CURRENT_RESULT</code>, or
+        <code>Statement.CLOSE_ALL_RESULTS</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#execute(java.lang.String)"><CODE>execute(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getGeneratedKeys()"><!-- --></A><H3>
+getGeneratedKeys</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A> <B>getGeneratedKeys</B>()
+                           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves any auto-generated keys created as a result of executing this
+ <code>Statement</code> object. If this <code>Statement</code> object did
+ not generate any keys, an empty <code>ResultSet</code>
+ object is returned.
+ <p>(JDBC4 clarification:)
+ <p><B>Note:</B>If the columns which represent the auto-generated keys were not specified,
+ the JDBC driver implementation will determine the columns which best represent the auto-generated keys.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Supported in version 2.0 <p>
+
+ If column names or indexes provided by the user in the executeUpdate()
+ method calls are not correct, an empty result is returned.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getGeneratedKeys()" title="class or interface in java.sql">getGeneratedKeys</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a <code>ResultSet</code> object containing the auto-generated key(s)
+         generated by the execution of this <code>Statement</code> object
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code>
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate(java.lang.String, int)"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                         int&nbsp;autoGeneratedKeys)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement and signals the driver with the
+ given flag about whether the
+ auto-generated keys produced by this <code>Statement</code> object
+ should be made available for retrieval.  The driver will ignore the
+ flag if the SQL statement
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ auto-generated keys (the list of such statements is vendor-specific).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with version 2.0, HSQLDB supports this feature.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, int)" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+ <code>DELETE</code>; or an SQL statement that returns nothing,
+ such as a DDL statement.
+ (:JDBC4 clarification)<DD><CODE>autoGeneratedKeys</CODE> - a flag indicating whether auto-generated keys
+        should be made available for retrieval;
+         one of the following constants:
+         <code>Statement.RETURN_GENERATED_KEYS</code>
+         <code>Statement.NO_GENERATED_KEYS</code>
+<DT><B>Returns:</B><DD>either (1) the row count for SQL Data Manipulation Language (DML) statements
+         or (2) 0 for SQL statements that return nothing
+         (:JDBC4 clarification)
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+  this method is called on a closed <code>Statement</code>, the given
+            SQL statement returns a <code>ResultSet</code> object, or
+            the given constant is not one of those allowed
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method with a constant of Statement.RETURN_GENERATED_KEYS<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate(java.lang.String, int[])"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                         int[]&nbsp;columnIndexes)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.  The driver will ignore the array if the SQL statement
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ (JDBC 4 clarification)
+ auto-generated keys (the list of such statements is vendor-specific).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with version 2.0, HSQLDB supports this feature with single-row and
+ multi-row inserts. <p>
+ CHECKME: possibly change method depending to final GENERATED column support.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, int[])" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+ <code>DELETE</code>; or an SQL statement that returns nothing,
+ such as a DDL statement.
+ (:JDBC4 clarification)<DD><CODE>columnIndexes</CODE> - an array of column indexes indicating the columns
+        that should be returned from the inserted row
+<DT><B>Returns:</B><DD>either (1) the row count for SQL Data Manipulation Language (DML) statements
+         or (2) 0 for SQL statements that return nothing
+         (:JDBC 4 clarification)
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code>, the SQL
+            statement returns a <code>ResultSet</code> object, or the
+            second argument supplied to this method is not an <code>int</code> array
+            whose elements are valid column indexes
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeUpdate(java.lang.String, java.lang.String[])"><!-- --></A><H3>
+executeUpdate</H3>
+<PRE>
+public int <B>executeUpdate</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.   The driver will ignore the array if the SQL statement
+ (JDBC4 clarification:)
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ auto-generated keys (the list of such statements is vendor-specific).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB supports this feature.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#executeUpdate(java.lang.String, java.lang.String[])" title="class or interface in java.sql">executeUpdate</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+ <code>DELETE</code>; or an SQL statement that returns nothing,
+ such as a DDL statement.
+ (:JDBC4 clarification)<DD><CODE>columnNames</CODE> - an array of the names of the columns that should be
+        returned from the inserted row
+<DT><B>Returns:</B><DD>either the row count for <code>INSERT</code>, <code>UPDATE</code>,
+         or <code>DELETE</code> statements, or 0 for SQL statements
+         that return nothing
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+  this method is called on a closed <code>Statement</code>, the SQL
+            statement returns a <code>ResultSet</code> object, or the
+            second argument supplied to this method is not a <code>String</code> array
+            whose elements are valid column names
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute(java.lang.String, int)"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                       int&nbsp;autoGeneratedKeys)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement, which may return multiple results,
+ and signals the driver that any
+ auto-generated keys should be made available
+ for retrieval.  The driver will ignore this signal if the SQL statement
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ (JDBC4 clarification)
+ auto-generated keys (the list of such statements is vendor-specific).
+ <P>
+ In some (uncommon) situations, a single SQL statement may return
+ multiple result sets and/or update counts.  Normally you can ignore
+ this unless you are (1) executing a stored procedure that you know may
+ return multiple results or (2) you are dynamically executing an
+ unknown SQL string.
+ <P>
+ The <code>execute</code> method executes an SQL statement and indicates the
+ form of the first result.  You must then use the methods
+ <code>getResultSet</code> or <code>getUpdateCount</code>
+ to retrieve the result, and <code>getMoreResults</code> to
+ move to any subsequent result(s).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB supports this feature.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, int)" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - any SQL statement<DD><CODE>autoGeneratedKeys</CODE> - a constant indicating whether auto-generated
+        keys should be made available for retrieval using the method
+        <code>getGeneratedKeys</code>; one of the following constants:
+        <code>Statement.RETURN_GENERATED_KEYS</code> or
+        <code>Statement.NO_GENERATED_KEYS</code>
+<DT><B>Returns:</B><DD><code>true</code> if the first result is a <code>ResultSet</code>
+         object; <code>false</code> if it is an update count or there are
+         no results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the second
+         parameter supplied to this method is not
+         <code>Statement.RETURN_GENERATED_KEYS</code> or
+         <code>Statement.NO_GENERATED_KEYS</code>.
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support
+ this method with a constant of Statement.RETURN_GENERATED_KEYS<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSet()"><CODE>getResultSet()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getUpdateCount()"><CODE>getUpdateCount()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMoreResults()"><CODE>getMoreResults()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getGeneratedKeys()"><CODE>getGeneratedKeys()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute(java.lang.String, int[])"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                       int[]&nbsp;columnIndexes)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement, which may return multiple results,
+ and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval.  This array contains the indexes of the columns in the
+ target table that contain the auto-generated keys that should be made
+ available.  The driver will ignore the array if the SQL statement
+ (JDBC4 clarification)
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ auto-generated keys (the list of such statements is vendor-specific).
+ <P>
+ Under some (uncommon) situations, a single SQL statement may return
+ multiple result sets and/or update counts.  Normally you can ignore
+ this unless you are (1) executing a stored procedure that you know may
+ return multiple results or (2) you are dynamically executing an
+ unknown SQL string.
+ <P>
+ The <code>execute</code> method executes an SQL statement and indicates the
+ form of the first result.  You must then use the methods
+ <code>getResultSet</code> or <code>getUpdateCount</code>
+ to retrieve the result, and <code>getMoreResults</code> to
+ move to any subsequent result(s).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB supports this feature.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, int[])" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - any SQL statement<DD><CODE>columnIndexes</CODE> - an array of the indexes of the columns in the
+        inserted row that should be  made available for retrieval by a
+        call to the method <code>getGeneratedKeys</code>
+<DT><B>Returns:</B><DD><code>true</code> if the first result is a <code>ResultSet</code>
+         object; <code>false</code> if it is an update count or there
+         are no results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the
+            elements in the <code>int</code> array passed to this method
+            are not valid column indexes
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSet()"><CODE>getResultSet()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getUpdateCount()"><CODE>getUpdateCount()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMoreResults()"><CODE>getMoreResults()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execute(java.lang.String, java.lang.String[])"><!-- --></A><H3>
+execute</H3>
+<PRE>
+public boolean <B>execute</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;columnNames)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Executes the given SQL statement, which may return multiple results,
+ and signals the driver that the
+ auto-generated keys indicated in the given array should be made available
+ for retrieval. This array contains the names of the columns in the
+ target table that contain the auto-generated keys that should be made
+ available.  The driver will ignore the array if the SQL statement
+ is not an <code>INSERT</code> statement, or an SQL statement able to return
+ auto-generated keys (the list of such statements is vendor-specific).
+ <P>
+ In some (uncommon) situations, a single SQL statement may return
+ multiple result sets and/or update counts.  Normally you can ignore
+ this unless you are (1) executing a stored procedure that you know may
+ return multiple results or (2) you are dynamically executing an
+ unknown SQL string.
+ <P>
+ The <code>execute</code> method executes an SQL statement and indicates the
+ form of the first result.  You must then use the methods
+ <code>getResultSet</code> or <code>getUpdateCount</code>
+ to retrieve the result, and <code>getMoreResults</code> to
+ move to any subsequent result(s).
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 2.0, HSQLDB supports this feature.
+
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#execute(java.lang.String, java.lang.String[])" title="class or interface in java.sql">execute</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sql</CODE> - any SQL statement<DD><CODE>columnNames</CODE> - an array of the names of the columns in the inserted
+        row that should be made available for retrieval by a call to the
+        method <code>getGeneratedKeys</code>
+<DT><B>Returns:</B><DD><code>true</code> if the next result is a <code>ResultSet</code>
+         object; <code>false</code> if it is an update count or there
+         are no more results
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs,
+ this method is called on a closed <code>Statement</code> or the
+          elements of the <code>String</code> array passed to this
+          method are not valid column names
+<DD><CODE>SQLFeatureNotSupportedException</CODE> - if the JDBC driver does not support this method<DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getResultSet()"><CODE>getResultSet()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getUpdateCount()"><CODE>getUpdateCount()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getMoreResults()"><CODE>getMoreResults()</CODE></A>, 
+<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#getGeneratedKeys()"><CODE>getGeneratedKeys()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getResultSetHoldability()"><!-- --></A><H3>
+getResultSetHoldability</H3>
+<PRE>
+public int <B>getResultSetHoldability</B>()
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><!-- start generic documentation -->
+ Retrieves the result set holdability for <code>ResultSet</code> objects
+ generated by this <code>Statement</code> object.
+ <!-- end generic documentation -->
+
+ <!-- start release-specific documentation -->
+ <div class="ReleaseSpecificDocumentation">
+ <h3>HSQLDB-Specific Information:</h3> <p>
+
+ Starting with 1.7.2, this method returns HOLD_CURSORS_OVER_COMMIT
+ </div>
+ <!-- end release-specific documentation -->
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#getResultSetHoldability()" title="class or interface in java.sql">getResultSetHoldability</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs or
+ this method is called on a closed <code>Statement</code><DT><B>Since:</B></DT>
+  <DD>JDK 1.4, HSQLDB 1.7</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isClosed()"><!-- --></A><H3>
+isClosed</H3>
+<PRE>
+public boolean <B>isClosed</B>()
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Retrieves whether this <code>Statement</code> object has been closed. A <code>Statement</code> is closed if the
+ method close has been called on it, or if it is automatically closed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#isClosed()" title="class or interface in java.sql">isClosed</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if this <code>Statement</code> object is closed; false if it is still open
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if a database access error occurs<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setPoolable(boolean)"><!-- --></A><H3>
+setPoolable</H3>
+<PRE>
+public void <B>setPoolable</B>(boolean&nbsp;poolable)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Requests that a <code>Statement</code> be pooled or not pooled.  The value
+ specified is a hint to the statement pool implementation indicating
+ whether the applicaiton wants the statement to be pooled.  It is up to
+ the statement pool manager as to whether the hint is used.
+ <p>
+ The poolable value of a statement is applicable to both internal
+ statement caches implemented by the driver and external statement caches
+ implemented by application servers and other applications.
+ <p>
+ By default, a <code>Statement</code> is not poolable when created, and
+ a <code>PreparedStatement</code> and <code>CallableStatement</code>
+ are poolable when created.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#setPoolable(boolean)" title="class or interface in java.sql">setPoolable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>poolable</CODE> - requests that the statement be pooled if true and
+                                          that the statement not be pooled if false
+ <p>
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if this method is called on a closed
+ <code>Statement</code>
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6 Build 81, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isPoolable()"><!-- --></A><H3>
+isPoolable</H3>
+<PRE>
+public boolean <B>isPoolable</B>()
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns a  value indicating whether the <code>Statement</code>
+ is poolable or not.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true#isPoolable()" title="class or interface in java.sql">isPoolable</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD><code>true</code> if the <code>Statement</code>
+ is poolable; <code>false</code> otherwise
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if this method is called on a closed
+ <code>Statement</code>
+ <p><DT><B>Since:</B></DT>
+  <DD>JDK 1.6 Build 81, HSQLDB 2.0
+ <p></DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html#setPoolable(boolean)"><CODE>setPoolable(boolean)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap(java.lang.Class)"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public &lt;T&gt; T <B>unwrap</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;T&gt;&nbsp;iface)
+         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns an object that implements the given interface to allow access to
+ non-standard methods, or standard methods not exposed by the proxy.
+
+ If the receiver implements the interface then the result is the receiver
+ or a proxy for the receiver. If the receiver is a wrapper
+ and the wrapped object implements the interface then the result is the
+ wrapped object or a proxy for the wrapped object. Otherwise return the
+ the result of calling <code>unwrap</code> recursively on the wrapped object
+ or a proxy for that result. If the receiver is not a
+ wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#unwrap(java.lang.Class)" title="class or interface in java.sql">unwrap</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - A Class defining an interface that the result must implement.
+<DT><B>Returns:</B><DD>an object that implements the interface. May be a proxy for the actual implementing object.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - If no object found that implements the interface<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isWrapperFor(java.lang.Class)"><!-- --></A><H3>
+isWrapperFor</H3>
+<PRE>
+public boolean <B>isWrapperFor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</A>&lt;?&gt;&nbsp;iface)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+ for an object that does. Returns false otherwise. If this implements the interface then return true,
+ else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+ object. If this does not implement the interface and is not a wrapper, return false.
+ This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+ callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+ returns true then calling <code>unwrap</code> with the same argument should succeed.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true#isWrapperFor(java.lang.Class)" title="class or interface in java.sql">isWrapperFor</A></CODE> in interface <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>iface</CODE> - a Class defining an interface.
+<DT><B>Returns:</B><DD>true if this implements the interface or directly or indirectly wraps an object that does.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE> - if an error occurs while determining whether this is a wrapper
+ for an object with the given interface.<DT><B>Since:</B></DT>
+  <DD>JDK 1.6, HSQLDB 2.0</DD>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/JDBCStatement.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/JDBCStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/Util.html b/doc/apidocs/org/hsqldb/jdbc/Util.html
new file mode 100644
index 0000000..f3b0707
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/Util.html
@@ -0,0 +1,565 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Util (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Util (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/Util.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/Util.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Util.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.jdbc</FONT>
+<BR>
+Class Util</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.jdbc.Util</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>Util</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+Provides driver constants and a gateway from internal HsqlExceptions to
+ external SQLExceptions.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#Util()">Util</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#connectionClosedException()">connectionClosedException</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#invalidArgument()">invalidArgument</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#invalidArgument(java.lang.String)">invalidArgument</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#nullArgument()">nullArgument</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#outOfRangeArgument()">outOfRangeArgument</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#outOfRangeArgument(java.lang.String)">outOfRangeArgument</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlException(org.hsqldb.HsqlException)">sqlException</A></B>(org.hsqldb.HsqlException&nbsp;e)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlException(org.hsqldb.HsqlException, java.lang.Throwable)">sqlException</A></B>(org.hsqldb.HsqlException&nbsp;e,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</A>&nbsp;cause)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlException(int)">sqlException</A></B>(int&nbsp;id)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlException(int, int)">sqlException</A></B>(int&nbsp;id,
+             int&nbsp;add)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlException(int, java.lang.String)">sqlException</A></B>(int&nbsp;id,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;message)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlException(int, java.lang.String, java.lang.Exception)">sqlException</A></B>(int&nbsp;id,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;message,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A>&nbsp;cause)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlException(org.hsqldb.result.Result)">sqlException</A></B>(org.hsqldb.result.Result&nbsp;r)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlException(java.lang.String, java.lang.String, int, java.lang.Throwable)">sqlException</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;msg,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sqlstate,
+             int&nbsp;code,
+             <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</A>&nbsp;cause)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlExceptionSQL(int)">sqlExceptionSQL</A></B>(int&nbsp;id)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/jdbc/Util.html#sqlWarning(org.hsqldb.result.Result)">sqlWarning</A></B>(org.hsqldb.result.Result&nbsp;r)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="Util()"><!-- --></A><H3>
+Util</H3>
+<PRE>
+public <B>Util</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="sqlException(org.hsqldb.HsqlException)"><!-- --></A><H3>
+sqlException</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlException</B>(org.hsqldb.HsqlException&nbsp;e)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlException(org.hsqldb.HsqlException, java.lang.Throwable)"><!-- --></A><H3>
+sqlException</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlException</B>(org.hsqldb.HsqlException&nbsp;e,
+                                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</A>&nbsp;cause)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlException(int)"><!-- --></A><H3>
+sqlException</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlException</B>(int&nbsp;id)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlExceptionSQL(int)"><!-- --></A><H3>
+sqlExceptionSQL</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlExceptionSQL</B>(int&nbsp;id)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlException(int, java.lang.String)"><!-- --></A><H3>
+sqlException</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlException</B>(int&nbsp;id,
+                                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;message)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlException(int, java.lang.String, java.lang.Exception)"><!-- --></A><H3>
+sqlException</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlException</B>(int&nbsp;id,
+                                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;message,
+                                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A>&nbsp;cause)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlException(int, int)"><!-- --></A><H3>
+sqlException</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlException</B>(int&nbsp;id,
+                                              int&nbsp;add)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nullArgument()"><!-- --></A><H3>
+nullArgument</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>nullArgument</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="invalidArgument()"><!-- --></A><H3>
+invalidArgument</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>invalidArgument</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="invalidArgument(java.lang.String)"><!-- --></A><H3>
+invalidArgument</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>invalidArgument</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="outOfRangeArgument()"><!-- --></A><H3>
+outOfRangeArgument</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>outOfRangeArgument</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="outOfRangeArgument(java.lang.String)"><!-- --></A><H3>
+outOfRangeArgument</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>outOfRangeArgument</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="connectionClosedException()"><!-- --></A><H3>
+connectionClosedException</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>connectionClosedException</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlWarning(org.hsqldb.result.Result)"><!-- --></A><H3>
+sqlWarning</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLWarning.html?is-external=true" title="class or interface in java.sql">SQLWarning</A> <B>sqlWarning</B>(org.hsqldb.result.Result&nbsp;r)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlException(org.hsqldb.result.Result)"><!-- --></A><H3>
+sqlException</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlException</B>(org.hsqldb.result.Result&nbsp;r)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sqlException(java.lang.String, java.lang.String, int, java.lang.Throwable)"><!-- --></A><H3>
+sqlException</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A> <B>sqlException</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;msg,
+                                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sqlstate,
+                                              int&nbsp;code,
+                                              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</A>&nbsp;cause)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/Util.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/Util.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Util.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/BlobInputStream.html b/doc/apidocs/org/hsqldb/jdbc/class-use/BlobInputStream.html
new file mode 100644
index 0000000..5f129d9
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/BlobInputStream.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.BlobInputStream (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.BlobInputStream (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useBlobInputStream.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="BlobInputStream.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.BlobInputStream</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.BlobInputStream
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useBlobInputStream.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="BlobInputStream.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/ClobInputStream.html b/doc/apidocs/org/hsqldb/jdbc/class-use/ClobInputStream.html
new file mode 100644
index 0000000..531074a
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/ClobInputStream.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.ClobInputStream (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.ClobInputStream (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useClobInputStream.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ClobInputStream.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.ClobInputStream</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.ClobInputStream
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useClobInputStream.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ClobInputStream.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCArray.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCArray.html
new file mode 100644
index 0000000..a150b22
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCArray.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCArray (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCArray (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCArray.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCArray.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCArray</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCArray
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCArray.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCArray.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCBlob.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCBlob.html
new file mode 100644
index 0000000..47b01ec
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCBlob.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCBlob (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCBlob (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCBlob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCBlob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCBlob</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCBlob
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCBlob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCBlob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCBlobClient.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCBlobClient.html
new file mode 100644
index 0000000..0258832
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCBlobClient.html
@@ -0,0 +1,183 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCBlobClient (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCBlobClient (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCBlobClient.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCBlobClient.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCBlobClient</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.jdbc"><B>org.hsqldb.jdbc</B></A></TD>
+<TD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.jdbc"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A> in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Constructors in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A> with parameters of type <A HREF="../../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/hsqldb/jdbc/BlobInputStream.html#BlobInputStream(org.hsqldb.jdbc.JDBCBlobClient, long, long, int)">BlobInputStream</A></B>(<A HREF="../../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A>&nbsp;blob,
+                long&nbsp;offset,
+                long&nbsp;length,
+                int&nbsp;blockSize)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCBlobClient.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCBlobClient.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCCallableStatement.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCCallableStatement.html
new file mode 100644
index 0000000..f3e9be5
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCCallableStatement.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCCallableStatement (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCCallableStatement (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCCallableStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCCallableStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCCallableStatement</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCCallableStatement
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCCallableStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCCallableStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCClob.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCClob.html
new file mode 100644
index 0000000..deda649
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCClob.html
@@ -0,0 +1,183 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCClob (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCClob (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCClob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCClob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCClob</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.jdbc"><B>org.hsqldb.jdbc</B></A></TD>
+<TD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.jdbc"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A> in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Subclasses of <A HREF="../../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A> in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc">JDBCNClob</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ for the SQL <code>NCLOB</code> type.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCClob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCClob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCClobClient.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCClobClient.html
new file mode 100644
index 0000000..da19976
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCClobClient.html
@@ -0,0 +1,183 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCClobClient (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCClobClient (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCClobClient.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCClobClient.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCClobClient</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.jdbc"><B>org.hsqldb.jdbc</B></A></TD>
+<TD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.jdbc"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A> in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Constructors in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A> with parameters of type <A HREF="../../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/hsqldb/jdbc/ClobInputStream.html#ClobInputStream(org.hsqldb.jdbc.JDBCClobClient, long, long, int)">ClobInputStream</A></B>(<A HREF="../../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A>&nbsp;clob,
+                long&nbsp;offset,
+                long&nbsp;length,
+                int&nbsp;blockSize)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCClobClient.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCClobClient.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCColumnMetaData.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCColumnMetaData.html
new file mode 100644
index 0000000..0af6951
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCColumnMetaData.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCColumnMetaData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCColumnMetaData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCColumnMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCColumnMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCColumnMetaData</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCColumnMetaData
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCColumnMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCColumnMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCConnection.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCConnection.html
new file mode 100644
index 0000000..20ed811
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCConnection.html
@@ -0,0 +1,203 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCConnection (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCConnection (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCConnection.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCConnection.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCConnection</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.jdbc"><B>org.hsqldb.jdbc</B></A></TD>
+<TD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.jdbc"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A> in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Constructors in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A> with parameters of type <A HREF="../../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/hsqldb/jdbc/JDBCCallableStatement.html#JDBCCallableStatement(org.hsqldb.jdbc.JDBCConnection, java.lang.String, int, int, int)">JDBCCallableStatement</A></B>(<A HREF="../../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;c,
+                      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;sql,
+                      int&nbsp;resultSetType,
+                      int&nbsp;resultSetConcurrency,
+                      int&nbsp;resultSetHoldability)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new JDBCCallableStatement with the specified connection and
+ result type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/hsqldb/jdbc/JDBCResultSet.html#JDBCResultSet(org.hsqldb.jdbc.JDBCConnection, org.hsqldb.jdbc.JDBCStatementBase, org.hsqldb.result.Result, org.hsqldb.result.ResultMetaData)">JDBCResultSet</A></B>(<A HREF="../../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;conn,
+              org.hsqldb.jdbc.JDBCStatementBase&nbsp;s,
+              org.hsqldb.result.Result&nbsp;r,
+              org.hsqldb.result.ResultMetaData&nbsp;metaData)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructs a new <code>JDBCResultSet</code> object using the specified
+ navigator and <code>org.hsqldb.result.ResultMetaData</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/hsqldb/jdbc/JDBCResultSet.html#JDBCResultSet(org.hsqldb.jdbc.JDBCConnection, org.hsqldb.result.Result, org.hsqldb.result.ResultMetaData)">JDBCResultSet</A></B>(<A HREF="../../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A>&nbsp;conn,
+              org.hsqldb.result.Result&nbsp;r,
+              org.hsqldb.result.ResultMetaData&nbsp;metaData)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCConnection.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCConnection.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDataSource.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDataSource.html
new file mode 100644
index 0000000..418596a
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDataSource.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCDataSource (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCDataSource (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCDataSource.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDataSource.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCDataSource</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCDataSource
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCDataSource.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDataSource.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDataSourceFactory.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDataSourceFactory.html
new file mode 100644
index 0000000..0c7c6c4
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDataSourceFactory.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCDataSourceFactory (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCDataSourceFactory (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCDataSourceFactory.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDataSourceFactory.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCDataSourceFactory</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCDataSourceFactory
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCDataSourceFactory.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDataSourceFactory.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDatabaseMetaData.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDatabaseMetaData.html
new file mode 100644
index 0000000..052b399
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDatabaseMetaData.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCDatabaseMetaData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCDatabaseMetaData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCDatabaseMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDatabaseMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCDatabaseMetaData</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCDatabaseMetaData
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCDatabaseMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDatabaseMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDriver.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDriver.html
new file mode 100644
index 0000000..be21b91
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCDriver.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCDriver (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCDriver (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCDriver.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDriver.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCDriver</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCDriver
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCDriver.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCDriver.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCNClob.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCNClob.html
new file mode 100644
index 0000000..3528854
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCNClob.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCNClob (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCNClob (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCNClob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCNClob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCNClob</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCNClob
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCNClob.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCNClob.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCParameterMetaData.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCParameterMetaData.html
new file mode 100644
index 0000000..2988f8b
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCParameterMetaData.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCParameterMetaData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCParameterMetaData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCParameterMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCParameterMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCParameterMetaData</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCParameterMetaData
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCParameterMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCParameterMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCPreparedStatement.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCPreparedStatement.html
new file mode 100644
index 0000000..19a12b0
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCPreparedStatement.html
@@ -0,0 +1,182 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCPreparedStatement (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCPreparedStatement (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCPreparedStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCPreparedStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCPreparedStatement</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.jdbc"><B>org.hsqldb.jdbc</B></A></TD>
+<TD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.jdbc"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A> in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Subclasses of <A HREF="../../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A> in <A HREF="../../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The interface used to execute SQL stored procedures.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCPreparedStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCPreparedStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCResultSet.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCResultSet.html
new file mode 100644
index 0000000..6d5e1ae
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCResultSet.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCResultSet (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCResultSet (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCResultSet.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCResultSet.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCResultSet</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCResultSet
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCResultSet.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCResultSet.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCResultSetMetaData.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCResultSetMetaData.html
new file mode 100644
index 0000000..d92de63
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCResultSetMetaData.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCResultSetMetaData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCResultSetMetaData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCResultSetMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCResultSetMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCResultSetMetaData</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCResultSetMetaData
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCResultSetMetaData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCResultSetMetaData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCRowId.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCRowId.html
new file mode 100644
index 0000000..26be454
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCRowId.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCRowId (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCRowId (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCRowId.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCRowId.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCRowId</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCRowId
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCRowId.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCRowId.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSQLXML.SAX2XMLStreamWriter.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSQLXML.SAX2XMLStreamWriter.html
new file mode 100644
index 0000000..4aa8de3
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSQLXML.SAX2XMLStreamWriter.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCSQLXML.SAX2XMLStreamWriter (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCSQLXML.SAX2XMLStreamWriter (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCSQLXML.SAX2XMLStreamWriter.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSQLXML.SAX2XMLStreamWriter.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCSQLXML.SAX2XMLStreamWriter</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCSQLXML.SAX2XMLStreamWriter
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCSQLXML.SAX2XMLStreamWriter.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSQLXML.SAX2XMLStreamWriter.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSQLXML.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSQLXML.html
new file mode 100644
index 0000000..c0d7aaa
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSQLXML.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCSQLXML (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCSQLXML (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCSQLXML.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSQLXML.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCSQLXML</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCSQLXML
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCSQLXML.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSQLXML.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSavepoint.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSavepoint.html
new file mode 100644
index 0000000..06d9260
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCSavepoint.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCSavepoint (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCSavepoint (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCSavepoint.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSavepoint.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCSavepoint</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCSavepoint
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCSavepoint.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCSavepoint.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCStatement.html b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCStatement.html
new file mode 100644
index 0000000..6a3aeb6
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/JDBCStatement.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.JDBCStatement (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.JDBCStatement (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.JDBCStatement</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.JDBCStatement
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useJDBCStatement.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="JDBCStatement.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/class-use/Util.html b/doc/apidocs/org/hsqldb/jdbc/class-use/Util.html
new file mode 100644
index 0000000..d34eb33
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/class-use/Util.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.jdbc.Util (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.jdbc.Util (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useUtil.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Util.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.jdbc.Util</B></H2>
+</CENTER>
+No usage of org.hsqldb.jdbc.Util
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/jdbc//class-useUtil.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Util.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/package-frame.html b/doc/apidocs/org/hsqldb/jdbc/package-frame.html
new file mode 100644
index 0000000..80bb7b6
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/package-frame.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.jdbc (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../org/hsqldb/jdbc/package-summary.html" target="classFrame">org.hsqldb.jdbc</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="BlobInputStream.html" title="class in org.hsqldb.jdbc" target="classFrame">BlobInputStream</A>
+<BR>
+<A HREF="ClobInputStream.html" title="class in org.hsqldb.jdbc" target="classFrame">ClobInputStream</A>
+<BR>
+<A HREF="JDBCArray.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCArray</A>
+<BR>
+<A HREF="JDBCBlob.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCBlob</A>
+<BR>
+<A HREF="JDBCBlobClient.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCBlobClient</A>
+<BR>
+<A HREF="JDBCCallableStatement.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCCallableStatement</A>
+<BR>
+<A HREF="JDBCClob.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCClob</A>
+<BR>
+<A HREF="JDBCClobClient.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCClobClient</A>
+<BR>
+<A HREF="JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCColumnMetaData</A>
+<BR>
+<A HREF="JDBCConnection.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCConnection</A>
+<BR>
+<A HREF="JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDatabaseMetaData</A>
+<BR>
+<A HREF="JDBCDataSource.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDataSource</A>
+<BR>
+<A HREF="JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDataSourceFactory</A>
+<BR>
+<A HREF="JDBCDriver.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCDriver</A>
+<BR>
+<A HREF="JDBCNClob.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCNClob</A>
+<BR>
+<A HREF="JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCParameterMetaData</A>
+<BR>
+<A HREF="JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCPreparedStatement</A>
+<BR>
+<A HREF="JDBCResultSet.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCResultSet</A>
+<BR>
+<A HREF="JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCResultSetMetaData</A>
+<BR>
+<A HREF="JDBCRowId.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCRowId</A>
+<BR>
+<A HREF="JDBCSavepoint.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCSavepoint</A>
+<BR>
+<A HREF="JDBCSQLXML.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCSQLXML</A>
+<BR>
+<A HREF="JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCSQLXML.SAX2XMLStreamWriter</A>
+<BR>
+<A HREF="JDBCStatement.html" title="class in org.hsqldb.jdbc" target="classFrame">JDBCStatement</A>
+<BR>
+<A HREF="Util.html" title="class in org.hsqldb.jdbc" target="classFrame">Util</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/package-summary.html b/doc/apidocs/org/hsqldb/jdbc/package-summary.html
new file mode 100644
index 0000000..19ee250
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/package-summary.html
@@ -0,0 +1,290 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.jdbc (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.jdbc (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/lib/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.hsqldb.jdbc
+</H2>
+Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.
+<P>
+<B>See:</B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc">BlobInputStream</A></B></TD>
+<TD>This class is used as an InputStream to retrieve data from a Blob.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc">ClobInputStream</A></B></TD>
+<TD>This class is used as an InputStream to retrieve data from a Blob.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc">JDBCArray</A></B></TD>
+<TD>The mapping in the Java programming language for the SQL type
+ <code>ARRAY</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc">JDBCBlob</A></B></TD>
+<TD>The representation (mapping) in
+ the Java<sup><font size=-2>TM</font></sup> programming
+ language of an SQL
+ <code>BLOB</code> value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc">JDBCBlobClient</A></B></TD>
+<TD>A wrapper for HSQLDB BlobData objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc">JDBCCallableStatement</A></B></TD>
+<TD>The interface used to execute SQL stored procedures.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc">JDBCClob</A></B></TD>
+<TD>The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ for the SQL <code>CLOB</code> type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc">JDBCClobClient</A></B></TD>
+<TD>A wrapper for HSQLDB ClobData objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc">JDBCColumnMetaData</A></B></TD>
+<TD>Provides a site for holding the ResultSetMetaData for individual ResultSet
+ columns.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc">JDBCConnection</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc">JDBCDatabaseMetaData</A></B></TD>
+<TD>Comprehensive information about the database as a whole.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">JDBCDataSource</A></B></TD>
+<TD>A factory for connections to the physical data source that this
+ <code>DataSource</code> object represents.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc">JDBCDataSourceFactory</A></B></TD>
+<TD>A JNDI ObjectFactory for creating <A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><CODE>JDBCDataSource</CODE></A>
+ object instances.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc">JDBCDriver</A></B></TD>
+<TD>Provides the java.sql.Driver interface implementation required by
+ the JDBC specification.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc">JDBCNClob</A></B></TD>
+<TD>The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ for the SQL <code>NCLOB</code> type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc">JDBCParameterMetaData</A></B></TD>
+<TD>An object that can be used to get information about the types
+ and properties for each parameter marker in a
+ <code>PreparedStatement</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc">JDBCPreparedStatement</A></B></TD>
+<TD>An object that represents a precompiled SQL statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc">JDBCResultSet</A></B></TD>
+<TD>A table of data representing a database result set, which
+ is usually generated by executing a statement that queries the database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc">JDBCResultSetMetaData</A></B></TD>
+<TD>An object that can be used to get information about the types
+ and properties of the columns in a <code>ResultSet</code> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc">JDBCRowId</A></B></TD>
+<TD>The representation (mapping) in the Java programming language of an SQL ROWID
+ value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc">JDBCSavepoint</A></B></TD>
+<TD>The representation of a savepoint, which is a point within
+ the current transaction that can be referenced from the
+ <code>Connection.rollback</code> method.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc">JDBCSQLXML</A></B></TD>
+<TD>The mapping in the JavaTM programming language for the SQL XML type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc">JDBCSQLXML.SAX2XMLStreamWriter</A></B></TD>
+<TD>Writes to a <A HREF="http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamWriter.html?is-external=true" title="class or interface in javax.xml.stream"><CODE>XMLStreamWriter</CODE></A>
+ from SAX events.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc">JDBCStatement</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc">Util</A></B></TD>
+<TD>Provides driver constants and a gateway from internal HsqlExceptions to
+ external SQLExceptions.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package org.hsqldb.jdbc Description
+</H2>
+
+<P>
+Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.
+<P>
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/lib/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/package-tree.html b/doc/apidocs/org/hsqldb/jdbc/package-tree.html
new file mode 100644
index 0000000..abacc6c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/package-tree.html
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.jdbc Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.jdbc Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/lib/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.hsqldb.jdbc
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><B>Object</B></A><UL>
+<LI TYPE="circle">java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io"><B>InputStream</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A>)
+<UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc"><B>BlobInputStream</B></A></UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><B>JDBCArray</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><B>JDBCBlob</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><B>JDBCBlobClient</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><B>JDBCClob</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>)
+<UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><B>JDBCNClob</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>)
+</UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><B>JDBCClobClient</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCColumnMetaData</B></A><LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><B>JDBCConnection</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCDatabaseMetaData</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A>, java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><B>JDBCDataSource</B></A> (implements javax.sql.<A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true" title="class or interface in javax.sql">CommonDataSource</A>, javax.sql.<A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html?is-external=true" title="class or interface in javax.sql">DataSource</A>, javax.naming.<A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Referenceable.html?is-external=true" title="class or interface in javax.naming">Referenceable</A>, java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A>, java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><B>JDBCDataSourceFactory</B></A> (implements javax.naming.spi.<A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/spi/ObjectFactory.html?is-external=true" title="class or interface in javax.naming.spi">ObjectFactory</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><B>JDBCDriver</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCParameterMetaData</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A>, java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCPreparedStatement</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A>)
+<UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCCallableStatement</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A>)
+</UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><B>JDBCResultSet</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCResultSetMetaData</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><B>JDBCRowId</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><B>JDBCSavepoint</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><B>JDBCSQLXML</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><B>JDBCSQLXML.SAX2XMLStreamWriter</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A>, org.xml.sax.<A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCStatement</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A>, java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>)
+<LI TYPE="circle">java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io"><B>Reader</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A>, java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Readable.html?is-external=true" title="class or interface in java.lang">Readable</A>)
+<UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><B>ClobInputStream</B></A></UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="../../../org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc"><B>Util</B></A></UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/cmdline/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/lib/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/jdbc/package-use.html b/doc/apidocs/org/hsqldb/jdbc/package-use.html
new file mode 100644
index 0000000..a59ea09
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/jdbc/package-use.html
@@ -0,0 +1,197 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Package org.hsqldb.jdbc (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Package org.hsqldb.jdbc (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>org.hsqldb.jdbc</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.jdbc"><B>org.hsqldb.jdbc</B></A></TD>
+<TD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.jdbc"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Classes in <A HREF="../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A> used by <A HREF="../../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/jdbc/class-use/JDBCBlobClient.html#org.hsqldb.jdbc"><B>JDBCBlobClient</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A wrapper for HSQLDB BlobData objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/jdbc/class-use/JDBCClob.html#org.hsqldb.jdbc"><B>JDBCClob</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ for the SQL <code>CLOB</code> type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/jdbc/class-use/JDBCClobClient.html#org.hsqldb.jdbc"><B>JDBCClobClient</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A wrapper for HSQLDB ClobData objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/jdbc/class-use/JDBCConnection.html#org.hsqldb.jdbc"><B>JDBCConnection</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/jdbc/class-use/JDBCPreparedStatement.html#org.hsqldb.jdbc"><B>JDBCPreparedStatement</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An object that represents a precompiled SQL statement.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/jdbc/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/RCData.html b/doc/apidocs/org/hsqldb/lib/RCData.html
new file mode 100644
index 0000000..9a6ce3b
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/RCData.html
@@ -0,0 +1,752 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+RCData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="RCData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/RCData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/lib/RCData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="RCData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.lib</FONT>
+<BR>
+Class RCData</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.lib.RCData</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>RCData</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+Manages all the details we need to connect up to JDBC database(s),
+ in a declarative way.
+ <P>
+ The file <CODE>src/org/hsqldb/sample/SqlFileEmbedder.java</CODE>
+ in the HSQLDB distribution provides an example of how to use RCData for your
+ own programs.
+ <P/>
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Blaine Simpson (blaine dot simpson at admc dot com)</DD>
+<DT><B>See Also:</B><DD><A href="../../../../util-guide/sqltool-chapt.html#sqltool_auth-sect"
+      target="guide">
+     The RC File section of the HyperSQL Utilities Guide</A>, 
+<A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><CODE>SqlFileEmbedder</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#charset">charset</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#DEFAULT_JDBC_DRIVER">DEFAULT_JDBC_DRIVER</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#driver">driver</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#id">id</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#libpath">libpath</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#password">password</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#ti">ti</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#truststore">truststore</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#url">url</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#username">username</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#RCData(java.io.File, java.lang.String)">RCData</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;file,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;dbKey)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a RCDataObject by looking up the given key in the
+ given authentication file.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)">RCData</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;id,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;username,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;driver,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;charset,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;truststore)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convenience constructor for backward compatibility.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)">RCData</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;id,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;username,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;driver,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;charset,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;truststore,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;libpath)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wrapper for unset Transaction Isolation.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)">RCData</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;id,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;username,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;driver,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;charset,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;truststore,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;libpath,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;ti)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a new <code>RCData</code> object.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#expandSysPropVars(java.lang.String)">expandSysPropVars</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;inString)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a copy of the given String with System property names in the
+ format <code>${system.property}</code> replaced by the corresponding Java
+ System Properties.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#getConnection()">getConnection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets a JDBC Connection using the data of this RCData object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#getConnection(java.lang.String, java.lang.String)">getConnection</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;curDriverIn,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;curTrustStoreIn)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets a JDBC Connection using the data of this RCData object with
+ specified override elements</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#getDefaultJdbcDriverName()">getDefaultJdbcDriverName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#setDefaultJdbcDriver(java.lang.String)">setDefaultJdbcDriver</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;defaultJdbcDriverName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#setTI(java.sql.Connection, java.lang.String)">setTI</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>&nbsp;c,
+      <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tiString)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set Transaction Isolation level on the specified JDBC Connection</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/lib/RCData.html#tiToString(int)">tiToString</A></B>(int&nbsp;ti)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return a String representation for the given numerical
+ java.sql.Connection Transaction level.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="DEFAULT_JDBC_DRIVER"><!-- --></A><H3>
+DEFAULT_JDBC_DRIVER</H3>
+<PRE>
+public static final <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>DEFAULT_JDBC_DRIVER</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.hsqldb.lib.RCData.DEFAULT_JDBC_DRIVER">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="id"><!-- --></A><H3>
+id</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>id</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="url"><!-- --></A><H3>
+url</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>url</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="username"><!-- --></A><H3>
+username</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>username</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="password"><!-- --></A><H3>
+password</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>password</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="ti"><!-- --></A><H3>
+ti</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>ti</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="driver"><!-- --></A><H3>
+driver</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>driver</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="charset"><!-- --></A><H3>
+charset</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>charset</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="truststore"><!-- --></A><H3>
+truststore</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>truststore</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="libpath"><!-- --></A><H3>
+libpath</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>libpath</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="RCData(java.io.File, java.lang.String)"><!-- --></A><H3>
+RCData</H3>
+<PRE>
+public <B>RCData</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;file,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;dbKey)
+       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></PRE>
+<DL>
+<DD>Creates a RCDataObject by looking up the given key in the
+ given authentication file.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>dbKey</CODE> - Key to look up in the file.
+              If null, then will echo all urlids in the file to stdout.
+              (A rather ill-conceived design).<DD><CODE>file</CODE> - File containing the authentication information.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></CODE></DL>
+</DL>
+<HR>
+
+<A NAME="RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+RCData</H3>
+<PRE>
+public <B>RCData</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;id,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;username,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;driver,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;charset,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;truststore)
+       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></PRE>
+<DL>
+<DD>Convenience constructor for backward compatibility.
+<P>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></CODE><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/lib/RCData.html#RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><CODE>RCData(String,String,String,String,String,String,String,String)</CODE></A></DL>
+</DL>
+<HR>
+
+<A NAME="RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+RCData</H3>
+<PRE>
+public <B>RCData</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;id,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;username,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;driver,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;charset,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;truststore,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;libpath)
+       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></PRE>
+<DL>
+<DD>Wrapper for unset Transaction Isolation.
+<P>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></CODE></DL>
+</DL>
+<HR>
+
+<A NAME="RCData(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+RCData</H3>
+<PRE>
+public <B>RCData</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;id,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;url,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;username,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;password,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;driver,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;charset,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;truststore,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;libpath,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;ti)
+       throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></PRE>
+<DL>
+<DD>Creates a new <code>RCData</code> object.
+
+ <P>
+ The parameters driver, charset, truststore, and libpath are optional.
+ Setting these parameters to <code>NULL</code> will set them to their
+ default values.
+ <P/>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>id</CODE> - The identifier for these connection settings<DD><CODE>url</CODE> - The URL of the database to connect to<DD><CODE>username</CODE> - The username to log in as<DD><CODE>password</CODE> - The password of the username<DD><CODE>driver</CODE> - The JDBC driver to use<DD><CODE>charset</CODE> - The character set to use<DD><CODE>truststore</CODE> - The trust store to use<DD><CODE>libpath</CODE> - The JDBC library to add to CLASSPATH
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></CODE> - if the a non-optional parameter is set to <code>NULL</code></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="setDefaultJdbcDriver(java.lang.String)"><!-- --></A><H3>
+setDefaultJdbcDriver</H3>
+<PRE>
+public void <B>setDefaultJdbcDriver</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;defaultJdbcDriverName)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDefaultJdbcDriverName()"><!-- --></A><H3>
+getDefaultJdbcDriverName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDefaultJdbcDriverName</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConnection()"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>()
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/ClassNotFoundException.html?is-external=true" title="class or interface in java.lang">ClassNotFoundException</A>,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A>,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/net/MalformedURLException.html?is-external=true" title="class or interface in java.net">MalformedURLException</A></PRE>
+<DL>
+<DD>Gets a JDBC Connection using the data of this RCData object.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>New JDBC Connection
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/ClassNotFoundException.html?is-external=true" title="class or interface in java.lang">ClassNotFoundException</A></CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/net/MalformedURLException.html?is-external=true" title="class or interface in java.net">MalformedURLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getConnection(java.lang.String, java.lang.String)"><!-- --></A><H3>
+getConnection</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConnection</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;curDriverIn,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;curTrustStoreIn)
+                         throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/ClassNotFoundException.html?is-external=true" title="class or interface in java.lang">ClassNotFoundException</A>,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/net/MalformedURLException.html?is-external=true" title="class or interface in java.net">MalformedURLException</A>,
+                                <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Gets a JDBC Connection using the data of this RCData object with
+ specified override elements
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>New JDBC Connection
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/ClassNotFoundException.html?is-external=true" title="class or interface in java.lang">ClassNotFoundException</A></CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/net/MalformedURLException.html?is-external=true" title="class or interface in java.net">MalformedURLException</A></CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="expandSysPropVars(java.lang.String)"><!-- --></A><H3>
+expandSysPropVars</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>expandSysPropVars</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;inString)</PRE>
+<DL>
+<DD>Returns a copy of the given String with System property names in the
+ format <code>${system.property}</code> replaced by the corresponding Java
+ System Properties.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTI(java.sql.Connection, java.lang.String)"><!-- --></A><H3>
+setTI</H3>
+<PRE>
+public static void <B>setTI</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>&nbsp;c,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tiString)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Set Transaction Isolation level on the specified JDBC Connection
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="tiToString(int)"><!-- --></A><H3>
+tiToString</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>tiToString</B>(int&nbsp;ti)</PRE>
+<DL>
+<DD>Return a String representation for the given numerical
+ java.sql.Connection Transaction level.
+ <P>
+ Database implementations are free to provide their own transaction
+ isolation levels, so you can't depend upon this method to much.
+ </P>
+ Returns null, since DB implementations are free to provide
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/RCData.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/lib/RCData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="RCData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/class-use/RCData.html b/doc/apidocs/org/hsqldb/lib/class-use/RCData.html
new file mode 100644
index 0000000..7628a5c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/class-use/RCData.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.lib.RCData (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.lib.RCData (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib//class-useRCData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="RCData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.lib.RCData</B></H2>
+</CENTER>
+No usage of org.hsqldb.lib.RCData
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib//class-useRCData.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="RCData.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/package-frame.html b/doc/apidocs/org/hsqldb/lib/package-frame.html
new file mode 100644
index 0000000..1e03b83
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/package-frame.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.lib (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../org/hsqldb/lib/package-summary.html" target="classFrame">org.hsqldb.lib</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="RCData.html" title="class in org.hsqldb.lib" target="classFrame">RCData</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/package-summary.html b/doc/apidocs/org/hsqldb/lib/package-summary.html
new file mode 100644
index 0000000..41d6960
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/package-summary.html
@@ -0,0 +1,174 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.lib (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.lib (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/lib/tar/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/lib/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.hsqldb.lib
+</H2>
+Shared classes used by other HyperSQL classes.
+<P>
+<B>See:</B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib">RCData</A></B></TD>
+<TD>Manages all the details we need to connect up to JDBC database(s),
+ in a declarative way.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package org.hsqldb.lib Description
+</H2>
+
+<P>
+Shared classes used by other HyperSQL classes.
+<P>
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/lib/tar/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/lib/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/package-tree.html b/doc/apidocs/org/hsqldb/lib/package-tree.html
new file mode 100644
index 0000000..a72199c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/package-tree.html
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.lib Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.lib Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/lib/tar/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/lib/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.hsqldb.lib
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><B>Object</B></A><UL>
+<LI TYPE="circle">org.hsqldb.lib.<A HREF="../../../org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib"><B>RCData</B></A></UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/jdbc/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/lib/tar/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/lib/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/package-use.html b/doc/apidocs/org/hsqldb/lib/package-use.html
new file mode 100644
index 0000000..bad17bd
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/package-use.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Package org.hsqldb.lib (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Package org.hsqldb.lib (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/lib/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>org.hsqldb.lib</B></H2>
+</CENTER>
+No usage of org.hsqldb.lib
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/lib/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/tar/DbBackup.html b/doc/apidocs/org/hsqldb/lib/tar/DbBackup.html
new file mode 100644
index 0000000..08f3268
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/tar/DbBackup.html
@@ -0,0 +1,429 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+DbBackup (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="DbBackup (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/DbBackup.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib/tar/DbBackup.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="DbBackup.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.lib.tar</FONT>
+<BR>
+Class DbBackup</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.lib.tar.DbBackup</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>DbBackup</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+Works with tar archives containing HSQLDB database instance backups.
+ Viz, creating, examining, or extracting these archives.
+ <P>
+ This class provides OO Tar backup-creation control.
+ The extraction and listing features are implemented only in static fashion
+ in the Main method, which provides a consistent interface for all three
+ features from the command-line.
+ </P> <P>
+ For tar creation, the default behavior is to fail if the target archive
+ exists, and to abort if any database change is detected.
+ Use the JavaBean setters to changes this behavior.
+ See the main(String[]) method for details about command-line usage.
+ </P>
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Blaine Simpson (blaine dot simpson at admc dot com)</DD>
+<DT><B>See Also:</B><DD><a href="../../../../../guide/deployment-chapt.html#deployment_backup-sect"
+      target="guide">
+     The database backup section of the HyperSQL User Guide</a>, 
+<A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#main(java.lang.String[])"><CODE>main(String[])</CODE></A>, 
+<A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#setOverWrite(boolean)"><CODE>setOverWrite(boolean)</CODE></A>, 
+<A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#setAbortUponModify(boolean)"><CODE>setAbortUponModify(boolean)</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#DbBackup(java.io.File, java.lang.String)">DbBackup</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;archiveFile,
+         <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;dbPath)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Instantiate a DbBackup instance for creating a Database Instance backup.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#getAbortUponModify()">getAbortUponModify</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#getOverWrite()">getOverWrite</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Command line invocation to create, examine, or extract HSQLDB database
+ backup tar archives.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#setAbortUponModify(boolean)">setAbortUponModify</A></B>(boolean&nbsp;abortUponModify)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Defaults to true.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#setOverWrite(boolean)">setOverWrite</A></B>(boolean&nbsp;overWrite)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Defaults to false.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html#write()">write</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method always backs up the .properties and .script files.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="DbBackup(java.io.File, java.lang.String)"><!-- --></A><H3>
+DbBackup</H3>
+<PRE>
+public <B>DbBackup</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;archiveFile,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;dbPath)</PRE>
+<DL>
+<DD>Instantiate a DbBackup instance for creating a Database Instance backup.
+
+ Much validation is deferred until the write() method, to prevent
+ problems with files changing between the constructor and the write call.
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A>,
+                        org.hsqldb.lib.tar.TarMalformatException</PRE>
+<DL>
+<DD>Command line invocation to create, examine, or extract HSQLDB database
+ backup tar archives.
+ <P>
+ This class stores tar entries as relative files without specifying
+ parent directories, in what is commonly referred to as <I>tar bomb</I>
+ format.
+ The set of files is small, with known extensions, and the potential
+ inconvenience of messing up the user's current directory is more than
+ compensated by making it easier for the user to restore to a new
+ database URL location at a peer level to the original.
+ </P> <P>
+ Automatically calculates buffer sizes based on the largest component
+ file (for "save" mode) or tar file size (for other modes).
+ </P> <P>
+ Run<CODE><PRE>
+     java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup
+ </PRE></CODE> for syntax help.
+ </P>
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE>
+<DD><CODE>org.hsqldb.lib.tar.TarMalformatException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setOverWrite(boolean)"><!-- --></A><H3>
+setOverWrite</H3>
+<PRE>
+public void <B>setOverWrite</B>(boolean&nbsp;overWrite)</PRE>
+<DL>
+<DD>Defaults to false.
+
+ If false, then attempts to write a tar file that already exist will
+ abort.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAbortUponModify(boolean)"><!-- --></A><H3>
+setAbortUponModify</H3>
+<PRE>
+public void <B>setAbortUponModify</B>(boolean&nbsp;abortUponModify)</PRE>
+<DL>
+<DD>Defaults to true.
+
+ If true, then the write() method will validate that the database is
+ closed, and it will verify that no DB file changes between when we
+ start writing the tar, and when we finish.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getOverWrite()"><!-- --></A><H3>
+getOverWrite</H3>
+<PRE>
+public boolean <B>getOverWrite</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAbortUponModify()"><!-- --></A><H3>
+getAbortUponModify</H3>
+<PRE>
+public boolean <B>getAbortUponModify</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="write()"><!-- --></A><H3>
+write</H3>
+<PRE>
+public void <B>write</B>()
+           throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A>,
+                  org.hsqldb.lib.tar.TarMalformatException</PRE>
+<DL>
+<DD>This method always backs up the .properties and .script files.
+ It will back up all of .backup, .data, and .log which exist.
+
+ If abortUponModify is set, no tar file will be created, and this
+ method will throw.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE> - for any of many possible I/O problems
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/IllegalStateException.html?is-external=true" title="class or interface in java.lang">IllegalStateException</A></CODE> - only if abortUponModify is set, and
+                               database is open or is modified.
+<DD><CODE>org.hsqldb.lib.tar.TarMalformatException</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/DbBackup.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib/tar/DbBackup.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="DbBackup.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/tar/class-use/DbBackup.html b/doc/apidocs/org/hsqldb/lib/tar/class-use/DbBackup.html
new file mode 100644
index 0000000..d3dd70e
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/tar/class-use/DbBackup.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.lib.tar.DbBackup (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.lib.tar.DbBackup (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../../index.html?org/hsqldb/lib/tar//class-useDbBackup.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="DbBackup.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.lib.tar.DbBackup</B></H2>
+</CENTER>
+No usage of org.hsqldb.lib.tar.DbBackup
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../../index.html?org/hsqldb/lib/tar//class-useDbBackup.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="DbBackup.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/tar/package-frame.html b/doc/apidocs/org/hsqldb/lib/tar/package-frame.html
new file mode 100644
index 0000000..817a785
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/tar/package-frame.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.lib.tar (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../org/hsqldb/lib/tar/package-summary.html" target="classFrame">org.hsqldb.lib.tar</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="DbBackup.html" title="class in org.hsqldb.lib.tar" target="classFrame">DbBackup</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/tar/package-summary.html b/doc/apidocs/org/hsqldb/lib/tar/package-summary.html
new file mode 100644
index 0000000..5b21034
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/tar/package-summary.html
@@ -0,0 +1,177 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.lib.tar (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.lib.tar (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/hsqldb/lib/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/hsqldb/sample/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib/tar/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.hsqldb.lib.tar
+</H2>
+Contains the DbBackup class, for backing up HyperSQL databases, and support
+  classes for handling files in tar and pax format.
+<P>
+<B>See:</B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar">DbBackup</A></B></TD>
+<TD>Works with tar archives containing HSQLDB database instance backups.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package org.hsqldb.lib.tar Description
+</H2>
+
+<P>
+Contains the DbBackup class, for backing up HyperSQL databases, and support
+  classes for handling files in tar and pax format.
+  See <a href="../../../../../guide/deployment-chapt.html#deployment_backup-sect" target="guide">
+  the database backup section of the HyperSQL User Guide</a>
+<P>
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/hsqldb/lib/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/hsqldb/sample/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib/tar/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/tar/package-tree.html b/doc/apidocs/org/hsqldb/lib/tar/package-tree.html
new file mode 100644
index 0000000..030b09c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/tar/package-tree.html
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.lib.tar Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.lib.tar Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/hsqldb/lib/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/hsqldb/sample/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib/tar/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.hsqldb.lib.tar
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><B>Object</B></A><UL>
+<LI TYPE="circle">org.hsqldb.lib.tar.<A HREF="../../../../org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar"><B>DbBackup</B></A></UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/hsqldb/lib/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/hsqldb/sample/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib/tar/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/lib/tar/package-use.html b/doc/apidocs/org/hsqldb/lib/tar/package-use.html
new file mode 100644
index 0000000..f4a41e0
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/lib/tar/package-use.html
@@ -0,0 +1,172 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Package org.hsqldb.lib.tar (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Package org.hsqldb.lib.tar (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib/tar/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>org.hsqldb.lib.tar</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/lib/tar/package-summary.html">org.hsqldb.lib.tar</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.lib.tar"><B>org.hsqldb.lib.tar</B></A></TD>
+<TD>Contains the DbBackup class, for backing up HyperSQL databases, and support
+  classes for handling files in tar and pax format.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.lib.tar"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Classes in <A HREF="../../../../org/hsqldb/lib/tar/package-summary.html">org.hsqldb.lib.tar</A> used by <A HREF="../../../../org/hsqldb/lib/tar/package-summary.html">org.hsqldb.lib.tar</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../../org/hsqldb/lib/tar/class-use/TarMalformatException.html#org.hsqldb.lib.tar"><B>TarMalformatException</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/lib/tar/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/package-frame.html b/doc/apidocs/org/hsqldb/package-frame.html
new file mode 100644
index 0000000..58b84a5
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/package-frame.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../org/hsqldb/package-summary.html" target="classFrame">org.hsqldb</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Trigger.html" title="interface in org.hsqldb" target="classFrame"><I>Trigger</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/package-summary.html b/doc/apidocs/org/hsqldb/package-summary.html
new file mode 100644
index 0000000..c5ef36c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/package-summary.html
@@ -0,0 +1,175 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV PACKAGE&nbsp;
+&nbsp;<A HREF="../../org/hsqldb/cmdline/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../index.html?org/hsqldb/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.hsqldb
+</H2>
+Contains basic HyperSQL engine classes.
+<P>
+<B>See:</B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A></B></TD>
+<TD>The interface an HSQLDB TRIGGER must implement.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package org.hsqldb Description
+</H2>
+
+<P>
+Contains basic HyperSQL engine classes.
+  See <a href="../../../guide/index.html" target="guide">
+  the HyperSQL User Guide for details about HyperSQL database </a>
+<P>
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV PACKAGE&nbsp;
+&nbsp;<A HREF="../../org/hsqldb/cmdline/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../index.html?org/hsqldb/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/package-tree.html b/doc/apidocs/org/hsqldb/package-tree.html
new file mode 100644
index 0000000..0eb8f81
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/package-tree.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;<A HREF="../../org/hsqldb/cmdline/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../index.html?org/hsqldb/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.hsqldb
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">org.hsqldb.<A HREF="../../org/hsqldb/Trigger.html" title="interface in org.hsqldb"><B>Trigger</B></A></UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;<A HREF="../../org/hsqldb/cmdline/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../index.html?org/hsqldb/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/package-use.html b/doc/apidocs/org/hsqldb/package-use.html
new file mode 100644
index 0000000..e32f2fe
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/package-use.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Package org.hsqldb (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Package org.hsqldb (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../index.html?org/hsqldb/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>org.hsqldb</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../org/hsqldb/package-summary.html">org.hsqldb</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb"><B>org.hsqldb</B></A></TD>
+<TD>Contains basic HyperSQL engine classes.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.jdbc"><B>org.hsqldb.jdbc</B></A></TD>
+<TD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.sample"><B>org.hsqldb.sample</B></A></TD>
+<TD>Contains examples for hooking into HyperSQL from your own Java code.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Classes in <A HREF="../../org/hsqldb/package-summary.html">org.hsqldb</A> used by <A HREF="../../org/hsqldb/package-summary.html">org.hsqldb</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../org/hsqldb/class-use/HsqlException.html#org.hsqldb"><B>HsqlException</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class encapsulating all exceptions that can be thrown within the engine.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.jdbc"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Classes in <A HREF="../../org/hsqldb/package-summary.html">org.hsqldb</A> used by <A HREF="../../org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../org/hsqldb/class-use/HsqlException.html#org.hsqldb.jdbc"><B>HsqlException</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class encapsulating all exceptions that can be thrown within the engine.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../org/hsqldb/class-use/SessionInterface.html#org.hsqldb.jdbc"><B>SessionInterface</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Interface to Session and its remote proxy objects.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.sample"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Classes in <A HREF="../../org/hsqldb/package-summary.html">org.hsqldb</A> used by <A HREF="../../org/hsqldb/sample/package-summary.html">org.hsqldb.sample</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../org/hsqldb/class-use/Trigger.html#org.hsqldb.sample"><B>Trigger</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The interface an HSQLDB TRIGGER must implement.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../index.html?org/hsqldb/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/sample/SqlFileEmbedder.html b/doc/apidocs/org/hsqldb/sample/SqlFileEmbedder.html
new file mode 100644
index 0000000..d9fe47b
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/sample/SqlFileEmbedder.html
@@ -0,0 +1,347 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+SqlFileEmbedder (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="SqlFileEmbedder (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/SqlFileEmbedder.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/SqlFileEmbedder.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlFileEmbedder.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.sample</FONT>
+<BR>
+Class SqlFileEmbedder</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.sample.SqlFileEmbedder</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>SqlFileEmbedder</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+Sample class which executes SQL files, by embedding SqlFile.
+ <P/>
+ Suitable for using as a template.
+ <P/>
+ This class also serves as an example of using RCData to allow your
+ application users to store JDBC access information in a convenient
+ text file.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+  <DD>Blaine Simpson (blaine dot simpson at admc dot com)</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html#main(java.lang.String[])"><CODE>main(String[])</CODE></A>, 
+<A HREF="../../../org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><CODE>SqlFile</CODE></A>, 
+<A HREF="../../../org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib"><CODE>RCData</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html#SqlFileEmbedder(java.io.File, java.lang.String)">SqlFileEmbedder</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;rcFile,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;urlid)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Instantiates SqlFileEmbedder object and connects to specified database.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html#executeFiles(java.lang.String[])">executeFiles</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;fileStrings)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Your own classes can use this method to execute SQL files.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html#getConn()">getConn</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;For applications that use a persistent JDBC connection, this class can
+ be used to encapsulate that connection.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Run</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="SqlFileEmbedder(java.io.File, java.lang.String)"><!-- --></A><H3>
+SqlFileEmbedder</H3>
+<PRE>
+public <B>SqlFileEmbedder</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;rcFile,
+                       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;urlid)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></PRE>
+<DL>
+<DD>Instantiates SqlFileEmbedder object and connects to specified database.
+ <P/>
+ N.b., you do not need to use RCData to use SqlFile.
+ All SqlFile needs is a live Connection.
+ I'm using RCData because it is a convenient way for a non-contained
+ app (i.e. one that doesn't run in a 3rd party container) to get a
+ Connection.
+<P>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getConn()"><!-- --></A><H3>
+getConn</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>getConn</B>()</PRE>
+<DL>
+<DD>For applications that use a persistent JDBC connection, this class can
+ be used to encapsulate that connection.  (Just strip out the SqlFile
+ stuff if you don't need that).
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>The encapsulated JDBC Connection.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></PRE>
+<DL>
+<DD>Run<PRE>
+     java SqlFileEmbedder</PRE>
+ to see Syntax message.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="executeFiles(java.lang.String[])"><!-- --></A><H3>
+executeFiles</H3>
+<PRE>
+public void <B>executeFiles</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;fileStrings)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A>,
+                         org.hsqldb.cmdline.SqlToolError,
+                         <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD>Your own classes can use this method to execute SQL files.
+ <P/>
+ See source code for the main(String[]) method for an example of calling
+ this method.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE>
+<DD><CODE>org.hsqldb.cmdline.SqlToolError</CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE><DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html#main(java.lang.String[])"><CODE>main(String[])</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/SqlFileEmbedder.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/SqlFileEmbedder.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlFileEmbedder.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/sample/TriggerSample.html b/doc/apidocs/org/hsqldb/sample/TriggerSample.html
new file mode 100644
index 0000000..f10e09c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/sample/TriggerSample.html
@@ -0,0 +1,544 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+TriggerSample (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="TriggerSample (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/TriggerSample.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/TriggerSample.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="TriggerSample.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.sample</FONT>
+<BR>
+Class TriggerSample</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.sample.TriggerSample</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>TriggerSample</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements <A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A></DL>
+</PRE>
+
+<P>
+<P>Sample code for use of triggers in hsqldb.
+
+ This class org.hsqldb.sample package, but a typical implementation is in
+ users's class hierarchy.
+
+ SQL to invoke is:<p>
+ CREATE TRIGGER triggerSample BEFORE|AFTER INSERT|UPDATE|DELETE
+ ON myTable [FOR EACH ROW] [QUEUE n] [NOWAIT] CALL "myPackage.trigClass"<br>
+
+ This will create a thread that will wait for its firing event to occur;
+ when this happens, the trigger's thread runs the 'trigClass.fire'
+ Note that this is still in the same Java Virtual Machine as the
+ database, so make sure the fired method does not hang.<p>
+
+ There is a queue of events waiting to be run by each trigger thread.
+ This is particularly useful for 'FOR EACH ROW' triggers, when a large
+ number of trigger events occur in rapid succession, without the trigger
+ thread getting a chance to run. If the queue becomes full, subsequent
+ additions to it cause the database engine to suspend awaiting space
+ in the queue. Take great care to avoid this situation if the trigger
+ action involves accessing the database, as deadlock will occur.
+ This can be avoided either by ensuring the QUEUE parameter makes a large
+ enough queue, or by using the NOWAIT parameter, which causes a new
+ trigger event to overwrite the most recent event in the queue.
+ The default queue size is 1024.<p>
+
+ Ensure that "myPackage.trigClass" is present in the classpath which
+ you use to start hsql.<p>
+
+ If the method wants to access the database, it must establish
+ a JDBC connection.<p>
+
+ When the 'fire' method is called, it is passed the following arguments: <p>
+
+ fire (int type, String trigName, String tabName, Object oldRow[],
+       Object[] newRow) <p>
+
+ where 'type' is one of the values enumerated in the Trigger interface and
+ the 'oldRow'/'newRow' pair represents the rows acted on. The first
+ length - 1 array slots contain column values and the final slot contains
+ either null or the value of the internally assigned row identity, if
+ the concerned table has no primary key. The final slot must _never_ be
+ modified. <p>
+
+ The mapping of row classes to database types is specified in
+ /doc/hsqlSyntax.html#Datatypes. <p>
+
+ To be done:<p>
+
+ <ol>
+ <li> Implement the "jdbc:default:connection: URL to provide transparent
+      and portable access to internal connections for use in triggers and
+      stored procedures. <p>
+
+ <li> Implement declaritive column to trigger method argument
+      mapping, conditional execution (WHEN clause), etc. <p>
+
+ <li> Investigate and refine synchronous and asynchronous trigger models. <p>
+
+      Because certain combinations of trigger create parameters cause the
+      individual triggered actions of a multirow update to run in different
+      threads, it is possible for an 'after' trigger to run before its
+      corresponding 'before' trigger; the acceptability and implications
+      of this needs to be investigated, documented and the behaviour of
+      the engine fully specified.
+
+ <li> Investigate and implement the SQL 200n specified execution stack under
+      arbitrary triggered action and SQL-invoked routine call graphs.
+ </ol>
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.7.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>Peter Hudson, boucherb@users</DD>
+</DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.hsqldb.Trigger"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface org.hsqldb.<A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/hsqldb/Trigger.html#DELETE_AFTER">DELETE_AFTER</A>, <A HREF="../../../org/hsqldb/Trigger.html#DELETE_AFTER_ROW">DELETE_AFTER_ROW</A>, <A HREF="../../../org/hsqldb/Trigger.html#DELETE_BEFORE_ROW">DELETE_BEFORE_ROW</A>, <A HREF="../../../org/hsqldb/Trigger.html#INSERT_AFTER">INSERT_AFTER</A>, <A HREF="../../../org/hsqldb/Trigger.html#INSERT_AFTER_ROW">INSERT_AFTER_ROW</A>, <A HREF="../../../org/hsqldb/Trigger.html#INSERT_BEFORE_ROW">INSERT_BEFORE_ROW</A>, <A HREF="../../../org/hsqldb/Trigger.html#UPDATE_AFTER">UPDATE_AFTER</A>, <A HREF="../../../org/hsqldb/Trigger.html#UPDATE_AFTER_ROW">UPDATE_AFTER_ROW</A>, <A HREF="../../../org/hsqldb/Trigger.html#UPDATE_BEFORE_ROW">UPDATE_BEFORE_ROW</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#TriggerSample()">TriggerSample</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#fire(int, java.lang.String, java.lang.String, java.lang.Object[], java.lang.Object[])">fire</A></B>(int&nbsp;typ,
+     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;trn,
+     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tn,
+     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;or,
+     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;nr)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A sample HSQLDB Trigger interface implementation.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#getForEachSpec(int)">getForEachSpec</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#getOperationSpec(int)">getOperationSpec</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#getQueueSpec(int)">getQueueSpec</A></B>(int&nbsp;qs)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#getTriggerDDL(java.lang.String, int, java.lang.String, int, java.lang.String)">getTriggerDDL</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;trn,
+              int&nbsp;typ,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tab,
+              int&nbsp;qs,
+              <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;impl)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#getTriggerDescriptor(java.lang.String, int, java.lang.String)">getTriggerDescriptor</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;trn,
+                     int&nbsp;typ,
+                     <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tab)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#getWhenSpec(int)">getWhenSpec</A></B>(int&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="TriggerSample()"><!-- --></A><H3>
+TriggerSample</H3>
+<PRE>
+public <B>TriggerSample</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="fire(int, java.lang.String, java.lang.String, java.lang.Object[], java.lang.Object[])"><!-- --></A><H3>
+fire</H3>
+<PRE>
+public void <B>fire</B>(int&nbsp;typ,
+                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;trn,
+                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tn,
+                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;or,
+                 <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A>[]&nbsp;nr)</PRE>
+<DL>
+<DD>A sample HSQLDB Trigger interface implementation. <p>
+
+ This sample prints information about the firing trigger and records
+ actions in an audit table. <p>
+
+ The techniques used here are simplified dramatically for demonstration
+ purposes and are in no way recommended as a model upon which to build
+ actual installations involving triggered actions.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/hsqldb/Trigger.html#fire(int, java.lang.String, java.lang.String, java.lang.Object[], java.lang.Object[])">fire</A></CODE> in interface <CODE><A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>typ</CODE> - trigger type<DD><CODE>trn</CODE> - trigger name<DD><CODE>tn</CODE> - table name<DD><CODE>or</CODE> - old row<DD><CODE>nr</CODE> - new row</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWhenSpec(int)"><!-- --></A><H3>
+getWhenSpec</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getWhenSpec</B>(int&nbsp;type)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getOperationSpec(int)"><!-- --></A><H3>
+getOperationSpec</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getOperationSpec</B>(int&nbsp;type)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getQueueSpec(int)"><!-- --></A><H3>
+getQueueSpec</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getQueueSpec</B>(int&nbsp;qs)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getForEachSpec(int)"><!-- --></A><H3>
+getForEachSpec</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getForEachSpec</B>(int&nbsp;type)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTriggerDDL(java.lang.String, int, java.lang.String, int, java.lang.String)"><!-- --></A><H3>
+getTriggerDDL</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getTriggerDDL</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;trn,
+                                   int&nbsp;typ,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tab,
+                                   int&nbsp;qs,
+                                   <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;impl)
+                            throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTriggerDescriptor(java.lang.String, int, java.lang.String)"><!-- --></A><H3>
+getTriggerDescriptor</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getTriggerDescriptor</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;trn,
+                                          int&nbsp;typ,
+                                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;tab)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)
+                 throws <A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true" title="class or interface in java.sql">SQLException</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/TriggerSample.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/TriggerSample.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="TriggerSample.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/sample/class-use/SqlFileEmbedder.html b/doc/apidocs/org/hsqldb/sample/class-use/SqlFileEmbedder.html
new file mode 100644
index 0000000..08d1eba
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/sample/class-use/SqlFileEmbedder.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.sample.SqlFileEmbedder (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.sample.SqlFileEmbedder (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/sample//class-useSqlFileEmbedder.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlFileEmbedder.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.sample.SqlFileEmbedder</B></H2>
+</CENTER>
+No usage of org.hsqldb.sample.SqlFileEmbedder
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/sample//class-useSqlFileEmbedder.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="SqlFileEmbedder.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/sample/class-use/TriggerSample.html b/doc/apidocs/org/hsqldb/sample/class-use/TriggerSample.html
new file mode 100644
index 0000000..7bc34a8
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/sample/class-use/TriggerSample.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.sample.TriggerSample (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.sample.TriggerSample (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/sample//class-useTriggerSample.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="TriggerSample.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.sample.TriggerSample</B></H2>
+</CENTER>
+No usage of org.hsqldb.sample.TriggerSample
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/sample//class-useTriggerSample.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="TriggerSample.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/sample/package-frame.html b/doc/apidocs/org/hsqldb/sample/package-frame.html
new file mode 100644
index 0000000..72e9f89
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/sample/package-frame.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.sample (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../org/hsqldb/sample/package-summary.html" target="classFrame">org.hsqldb.sample</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="SqlFileEmbedder.html" title="class in org.hsqldb.sample" target="classFrame">SqlFileEmbedder</A>
+<BR>
+<A HREF="TriggerSample.html" title="class in org.hsqldb.sample" target="classFrame">TriggerSample</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/sample/package-summary.html b/doc/apidocs/org/hsqldb/sample/package-summary.html
new file mode 100644
index 0000000..09efa55
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/sample/package-summary.html
@@ -0,0 +1,180 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.sample (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.sample (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/lib/tar/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.hsqldb.sample
+</H2>
+Contains examples for hooking into HyperSQL from your own Java code.
+<P>
+<B>See:</B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample">SqlFileEmbedder</A></B></TD>
+<TD>Sample class which executes SQL files, by embedding SqlFile.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample">TriggerSample</A></B></TD>
+<TD>Sample code for use of triggers in hsqldb.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package org.hsqldb.sample Description
+</H2>
+
+<P>
+Contains examples for hooking into HyperSQL from your own Java code.
+  <P/>
+  Other examples may be found in the <CODE>sample/</CODE> subdirectory of
+  your HyperSQL distribution
+<P>
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/lib/tar/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/sample/package-tree.html b/doc/apidocs/org/hsqldb/sample/package-tree.html
new file mode 100644
index 0000000..b25db5c
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/sample/package-tree.html
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.sample Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.sample Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/lib/tar/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.hsqldb.sample
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><B>Object</B></A><UL>
+<LI TYPE="circle">org.hsqldb.sample.<A HREF="../../../org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><B>SqlFileEmbedder</B></A><LI TYPE="circle">org.hsqldb.sample.<A HREF="../../../org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample"><B>TriggerSample</B></A> (implements org.hsqldb.<A HREF="../../../org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>)
+</UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/lib/tar/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/sample/package-use.html b/doc/apidocs/org/hsqldb/sample/package-use.html
new file mode 100644
index 0000000..1e2392e
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/sample/package-use.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Package org.hsqldb.sample (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Package org.hsqldb.sample (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>org.hsqldb.sample</B></H2>
+</CENTER>
+No usage of org.hsqldb.sample
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/sample/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/Server.html b/doc/apidocs/org/hsqldb/server/Server.html
new file mode 100644
index 0000000..97d29e6
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/Server.html
@@ -0,0 +1,1681 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Server (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Server (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/Server.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/Server.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Server.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.server</FONT>
+<BR>
+Class Server</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.server.Server</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>org.hsqldb.server.HsqlSocketRequestHandler</DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>Server</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A><DT>implements org.hsqldb.server.HsqlSocketRequestHandler</DL>
+</PRE>
+
+<P>
+The HSQLDB HSQL protocol network database server. <p>
+
+ A Server object acts as a network database server and is one way of using
+ the client-server mode of HSQLDB Database Engine. Instances of this
+ class handle native HSQL protocol connections exclusively, allowing database
+ queries to be performed efficienly across the network.  Server's direct
+ descendent, WebServer, handles HTTP protocol connections exclusively,
+ allowing HSQL protocol to be tunneled over HTTP to avoid sandbox and
+ firewall issues, albeit less efficiently. <p>
+
+ There are a number of ways to configure and start a Server instance. <p>
+
+ When started from the command line or programatically via the main(String[])
+ method, configuration occurs in three phases, with later phases overriding
+ properties set by previous phases:
+
+ <ol>
+   <li>Upon construction, a Server object is assigned a set of default
+       properties. <p>
+
+   <li>If it exists, properties are loaded from a file named
+       'server.properties' in the present working directory. <p>
+
+   <li>The command line arguments (alternatively, the String[] passed to
+       main()) are parsed and used to further configure the Server's
+       properties. <p>
+
+ </ol> <p>
+
+ From the command line, the options are as follows: <p>
+ <pre>
+ +-----------------+-------------+----------+------------------------------+
+ |    OPTION       |    TYPE     | DEFAULT  |         DESCRIPTION          |
+ +-----------------+-------------+----------+------------------------------|
+ | --help          |             |          | prints this message          |
+ | --address       | name|number | any      | server inet address          |
+ | --port          | number      | 9001/544 | port at which server listens |
+ | --database.i    | [type]spec  | 0=test   | path of database i           |
+ | --dbname.i      | alias       |          | url alias for database i     |
+ | --silent        | true|false  | true     | false => display all queries |
+ | --trace         | true|false  | false    | display JDBC trace messages  |
+ | --tls           | true|false  | false    | TLS/SSL (secure) sockets     |
+ | --no_system_exit| true|false  | false    | do not issue System.exit()  |
+ | --remote_open   | true|false  | false    | can open databases remotely  |
+ +-----------------+-------------+----------+------------------------------+
+ </pre>
+
+ The <em>database.i</em> and <em>dbname.i</em> options need further
+ explanation:
+
+ <ul>
+   <li>Multiple databases can be served by each instance of the Server.
+       The value of <em>i</em> is currently limited to the range 0..9,
+       allowing up to 10 different databases. Any number is this range
+       can be used.<p>
+
+   <li>The value assigned to <em>database.i</em> is interpreted using the
+       format <b>'[type]spec'</b>, where the optional <em>type</em> component
+       is one of <b>'file:'</b>, <b>'res:'</b> or <b>'mem:'</b> and the
+       <em>spec</em> component is interpreted in the context of the
+       <em>type</em> component.  <p>
+
+       If omitted, the <em>type</em> component is taken to be
+       <b>'file:'</b>.  <p>
+
+        A full description of how
+       <b>'[type]spec'</b> values are interpreted appears in the overview for
+       <A HREF="../../../org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><CODE>JDBCConnection</CODE></A>. <p>
+
+   <li>The value assigned to <em>dbname.i</em> is taken to be the key used to
+       look up the desired database instance and thus corresponds to the
+       <b>&lt;alias&gt;</b> component of the HSQLDB HSQL protocol database
+       connection url:
+       'jdbc:hsqldb:hsql[s]://host[port][/<b>&lt;alias&gt;</b>]'. <p>
+
+   <li>The value of <em>database.0</em> is special. If  <em>dbname.0</em>
+       is not specified, then this defaults to an empty string and
+       a connection is made to <em>database.0</em> path when
+       the <b>&lt;alias&gt;</b> component of an HSQLDB HSQL protocol database
+       connection url is omitted. If a <em>database</em> key/value pair is
+       found in the properties when the main method is called, this
+       pair is supersedes the <em>database.0</em> setting<p>
+
+       This behaviour allows the previous
+       database connection url format to work with essentially unchanged
+       semantics.<p>
+
+   <li>When the  <em>remote_open</em> property is true, a connection attempt
+       to an unopened database results in the database being opened. The URL
+       for connection should include the property filepath to specify the path.
+       'jdbc:hsqldb:hsql[s]://host[port]/<b>&lt;alias&gt;;filepath=hsqldb:file:&lt;database path&gt;</b>'.
+       the given alias and filepath value will be associated together. The
+       database user and password to start this connection must be valid.
+       If this form of connection is used again, after the database has been
+       opened, the filepath property is ignored.<p>
+
+   <li>Once an alias such as "mydb" has been associated with a path, it cannot
+       be  reassigned to a different path.<p>
+
+   <li>If a database is closed with the SHUTDOWN command, its
+       alias is removed. It is then possible to connect to this database again
+       with a different (or the same) alias.<p>
+
+   <li>If the same database is connected to via two different
+       aliases, and then one of the is closed with the SHUTDOWN command, the
+       other is also closed.<p>
+ </ul>
+
+ From the 'server.properties' file, options can be set similarly, using a
+ slightly different format. <p>
+
+ Here is an example 'server.properties' file:
+
+ <pre>
+ server.port=9001
+ server.database.0=test
+ server.dbname.0=...
+ ...
+ server.database.n=...
+ server.dbname.n=...
+ server.silent=true
+ </pre>
+
+ Starting with 1.7.2, Server has been refactored to become a simple JavaBean
+ with non-blocking start() and stop() service methods.  It is possible to
+ configure a Server instance through the JavaBean API as well, but this
+ part of the public interface is still under review and will not be finalized
+ or documented fully until the final 1.7.2 release. <p>
+
+ <b>Note:</b> <p>
+
+ The 'no_system_exit' property is of particular interest. <p>
+
+ If a Server instance is to run embedded in, say, an application server,
+ such as when the JDBCDataSource or HsqlServerFactory classes are used, it
+ is typically necessary to avoid calling System.exit() when the Server
+ instance shuts down. <p>
+
+ By default, 'no_system_exit' is set: <p>
+
+ <ol>
+    <li><b>true</b> when a Server is started directly from the start()
+        method. <p>
+
+    <li><b>false</b> when a Server is started from the main(String[])
+         method.
+ </ol> <p>
+
+ These values are natural to their context because the first case allows
+ the JVM to exit by default on Server shutdown when a Server instance is
+ started from a command line environment, whereas the second case prevents
+ a typically unwanted JVM exit on Server shutdown when a Server intance
+ is started as part of a larger framework. <p>
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>Fred Toussi (fredt@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#Server()">Server</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a new Server instance handling HSQL protocol connections.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#checkRunning(boolean)">checkRunning</A></B>(boolean&nbsp;running)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Checks if this Server object is or is not running and throws if the
+ current state does not match the specified value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getAddress()">getAddress</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves, in string form, this server's host address.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getDatabaseName(int, boolean)">getDatabaseName</A></B>(int&nbsp;index,
+                boolean&nbsp;asconfigured)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the url alias (network name) of the i'th database
+ that this Server hosts.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getDatabasePath(int, boolean)">getDatabasePath</A></B>(int&nbsp;index,
+                boolean&nbsp;asconfigured)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the HSQLDB path descriptor (uri) of the i'th
+ Database that this Server hosts.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getDatabaseType(int)">getDatabaseType</A></B>(int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getDefaultWebPage()">getDefaultWebPage</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the name of the web page served when no page is specified.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getErrWriter()">getErrWriter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the PrintWriter to which server errors are printed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getHelpString()">getHelpString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a String object describing the command line and
+ properties options for this Server.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getLogWriter()">getLogWriter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the PrintWriter to which server messages are printed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getPort()">getPort</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves this server's host port.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getProductName()">getProductName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves this server's product name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getProductVersion()">getProductVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the server's product version, as a String.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getProtocol()">getProtocol</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a string respresentaion of the network protocol
+ this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getServerError()">getServerError</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a Throwable indicating the last server error, if any.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getServerId()">getServerId</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a String identifying this Server object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getState()">getState</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves current state of this server in numerically coded form.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getStateDescriptor()">getStateDescriptor</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a character sequence describing this server's current state,
+ including the message of the last exception, if there is one and it
+ is still in context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#getWebRoot()">getWebRoot</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the root context (directory) from which web content
+ is served.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#handleConnection(java.net.Socket)">handleConnection</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/net/Socket.html?is-external=true" title="class or interface in java.net">Socket</A>&nbsp;s)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assigns the specified socket to a new conection handler and
+ starts the handler in a new Thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#isNoSystemExit()">isNoSystemExit</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this server calls System.exit() when shutdown.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#isRestartOnShutdown()">isRestartOnShutdown</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether this server restarts on shutdown.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#isSilent()">isSilent</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether silent mode operation was requested in
+ the server properties.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#isTls()">isTls</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether the use of secure sockets was requested in the
+ server properties.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#isTrace()">isTrace</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves whether JDBC trace messages are to go to System.out or the
+ DriverManger PrintStream/PrintWriter, if any.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates and starts a new Server.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#notify(int, int)">notify</A></B>(int&nbsp;action,
+       int&nbsp;id)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This is called from org.hsqldb.DatabaseManager when a database is
+ shutdown.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#putPropertiesFromFile(java.lang.String)">putPropertiesFromFile</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;path)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Attempts to put properties from the file
+ with the specified path.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#putPropertiesFromString(java.lang.String)">putPropertiesFromString</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;s)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Puts properties from the supplied string argument.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setAddress(java.lang.String)">setAddress</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;address)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the InetAddress with which this server's ServerSocket will be
+ constructed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setDaemon(boolean)">setDaemon</A></B>(boolean&nbsp;daemon)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets whether server thread is a daemon.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setDatabaseName(int, java.lang.String)">setDatabaseName</A></B>(int&nbsp;index,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the external name (url alias) of the i'th hosted database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setDatabasePath(int, java.lang.String)">setDatabasePath</A></B>(int&nbsp;index,
+                <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;path)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the path of the hosted database.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setDefaultWebPage(java.lang.String)">setDefaultWebPage</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;file)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the name of the web page served when no page is specified.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setErrWriter(java.io.PrintWriter)">setErrWriter</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A>&nbsp;pw)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the PrintWriter to which server errors are logged.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setLogWriter(java.io.PrintWriter)">setLogWriter</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A>&nbsp;pw)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the PrintWriter to which server messages are logged.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setNoSystemExit(boolean)">setNoSystemExit</A></B>(boolean&nbsp;noExit)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets whether this server calls System.exit() when shutdown.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setPort(int)">setPort</A></B>(int&nbsp;port)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the server listen port.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setProperties(org.hsqldb.persist.HsqlProperties)">setProperties</A></B>(org.hsqldb.persist.HsqlProperties&nbsp;p)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets server properties using the specified properties object</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setRestartOnShutdown(boolean)">setRestartOnShutdown</A></B>(boolean&nbsp;restart)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets whether this server restarts on shutdown.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setSilent(boolean)">setSilent</A></B>(boolean&nbsp;silent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets silent mode operation</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setTls(boolean)">setTls</A></B>(boolean&nbsp;tls)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets whether to use secure sockets</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setTrace(boolean)">setTrace</A></B>(boolean&nbsp;trace)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets whether trace messages go to System.out or the
+ DriverManger PrintStream/PrintWriter, if any.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#setWebRoot(java.lang.String)">setWebRoot</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;root)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the path of the root directory from which web content is served.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#shutdown()">shutdown</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;External method to shut down this server.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#signalCloseAllServerConnections()">signalCloseAllServerConnections</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Closes all connections to this Server.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#start()">start</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Starts this server synchronously.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/Server.html#stop()">stop</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stops this server asynchronously.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="Server()"><!-- --></A><H3>
+Server</H3>
+<PRE>
+public <B>Server</B>()</PRE>
+<DL>
+<DD>Creates a new Server instance handling HSQL protocol connections.
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="checkRunning(boolean)"><!-- --></A><H3>
+checkRunning</H3>
+<PRE>
+public void <B>checkRunning</B>(boolean&nbsp;running)
+                  throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></PRE>
+<DL>
+<DD>Checks if this Server object is or is not running and throws if the
+ current state does not match the specified value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>running</CODE> - if true, ensure the server is running, else ensure the
+      server is not running
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE> - if the supplied value does not match the
+      current running status</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="signalCloseAllServerConnections()"><!-- --></A><H3>
+signalCloseAllServerConnections</H3>
+<PRE>
+public void <B>signalCloseAllServerConnections</B>()</PRE>
+<DL>
+<DD>Closes all connections to this Server.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>signalCloseAllServerConnections</CODE> in interface <CODE>org.hsqldb.server.HsqlSocketRequestHandler</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAddress()"><!-- --></A><H3>
+getAddress</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getAddress</B>()</PRE>
+<DL>
+<DD>Retrieves, in string form, this server's host address.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>this server's host address</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDatabaseName(int, boolean)"><!-- --></A><H3>
+getDatabaseName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDatabaseName</B>(int&nbsp;index,
+                              boolean&nbsp;asconfigured)</PRE>
+<DL>
+<DD>Retrieves the url alias (network name) of the i'th database
+ that this Server hosts.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the index of the url alias upon which to report<DD><CODE>asconfigured</CODE> - if true, report the configured value, else
+      the live value
+<DT><B>Returns:</B><DD>the url alias component of the i'th database
+      that this Server hosts, or null if no such name exists.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDatabasePath(int, boolean)"><!-- --></A><H3>
+getDatabasePath</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDatabasePath</B>(int&nbsp;index,
+                              boolean&nbsp;asconfigured)</PRE>
+<DL>
+<DD>Retrieves the HSQLDB path descriptor (uri) of the i'th
+ Database that this Server hosts.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the index of the uri upon which to report<DD><CODE>asconfigured</CODE> - if true, report the configured value, else
+      the live value
+<DT><B>Returns:</B><DD>the HSQLDB database path descriptor of the i'th database
+      that this Server hosts, or null if no such path descriptor
+      exists</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDatabaseType(int)"><!-- --></A><H3>
+getDatabaseType</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDatabaseType</B>(int&nbsp;index)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDefaultWebPage()"><!-- --></A><H3>
+getDefaultWebPage</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDefaultWebPage</B>()</PRE>
+<DL>
+<DD>Retrieves the name of the web page served when no page is specified.
+ This attribute is relevant only when server protocol is HTTP(S).
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the name of the web page served when no page is specified</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getHelpString()"><!-- --></A><H3>
+getHelpString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getHelpString</B>()</PRE>
+<DL>
+<DD>Retrieves a String object describing the command line and
+ properties options for this Server.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the command line and properties options help for this Server</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getErrWriter()"><!-- --></A><H3>
+getErrWriter</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A> <B>getErrWriter</B>()</PRE>
+<DL>
+<DD>Retrieves the PrintWriter to which server errors are printed.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the PrintWriter to which server errors are printed.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLogWriter()"><!-- --></A><H3>
+getLogWriter</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A> <B>getLogWriter</B>()</PRE>
+<DL>
+<DD>Retrieves the PrintWriter to which server messages are printed.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the PrintWriter to which server messages are printed.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getPort()"><!-- --></A><H3>
+getPort</H3>
+<PRE>
+public int <B>getPort</B>()</PRE>
+<DL>
+<DD>Retrieves this server's host port.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>this server's host port</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProductName()"><!-- --></A><H3>
+getProductName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getProductName</B>()</PRE>
+<DL>
+<DD>Retrieves this server's product name.  <p>
+
+ Typically, this will be something like: "HSQLDB xxx server".
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the product name of this server</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProductVersion()"><!-- --></A><H3>
+getProductVersion</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getProductVersion</B>()</PRE>
+<DL>
+<DD>Retrieves the server's product version, as a String.  <p>
+
+ Typically, this will be something like: "1.x.x" or "2.x.x" and so on.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the product version of the server</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProtocol()"><!-- --></A><H3>
+getProtocol</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getProtocol</B>()</PRE>
+<DL>
+<DD>Retrieves a string respresentaion of the network protocol
+ this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>string respresentation of this server's protocol</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getServerError()"><!-- --></A><H3>
+getServerError</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</A> <B>getServerError</B>()</PRE>
+<DL>
+<DD>Retrieves a Throwable indicating the last server error, if any. <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a Throwable indicating the last server error</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getServerId()"><!-- --></A><H3>
+getServerId</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getServerId</B>()</PRE>
+<DL>
+<DD>Retrieves a String identifying this Server object.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a String identifying this Server object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getState()"><!-- --></A><H3>
+getState</H3>
+<PRE>
+public int <B>getState</B>()</PRE>
+<DL>
+<DD>Retrieves current state of this server in numerically coded form. <p>
+
+ Typically, this will be one of: <p>
+
+ <ol>
+ <li>ServerProperties.SERVER_STATE_ONLINE (1)
+ <li>ServerProperties.SERVER_STATE_OPENING (4)
+ <li>ServerProperties.SERVER_STATE_CLOSING (8)
+ <li>ServerProperties.SERVER_STATE_SHUTDOWN (16)
+ </ol>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>this server's state code.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStateDescriptor()"><!-- --></A><H3>
+getStateDescriptor</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getStateDescriptor</B>()</PRE>
+<DL>
+<DD>Retrieves a character sequence describing this server's current state,
+ including the message of the last exception, if there is one and it
+ is still in context.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>this server's state represented as a character sequence.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWebRoot()"><!-- --></A><H3>
+getWebRoot</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getWebRoot</B>()</PRE>
+<DL>
+<DD>Retrieves the root context (directory) from which web content
+ is served.  This property is relevant only when the server
+ protocol is HTTP(S).  Although unlikely, it may be that in the future
+ other contexts, such as jar urls may be supported, so that pages can
+ be served from the contents of a jar or from the JVM class path.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the root context (directory) from which web content is served</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="handleConnection(java.net.Socket)"><!-- --></A><H3>
+handleConnection</H3>
+<PRE>
+public void <B>handleConnection</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/net/Socket.html?is-external=true" title="class or interface in java.net">Socket</A>&nbsp;s)</PRE>
+<DL>
+<DD>Assigns the specified socket to a new conection handler and
+ starts the handler in a new Thread.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>handleConnection</CODE> in interface <CODE>org.hsqldb.server.HsqlSocketRequestHandler</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>s</CODE> - the socket to connect</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isNoSystemExit()"><!-- --></A><H3>
+isNoSystemExit</H3>
+<PRE>
+public boolean <B>isNoSystemExit</B>()</PRE>
+<DL>
+<DD>Retrieves whether this server calls System.exit() when shutdown.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if this server does not call System.exit()</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isRestartOnShutdown()"><!-- --></A><H3>
+isRestartOnShutdown</H3>
+<PRE>
+public boolean <B>isRestartOnShutdown</B>()</PRE>
+<DL>
+<DD>Retrieves whether this server restarts on shutdown.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true this server restarts on shutdown</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isSilent()"><!-- --></A><H3>
+isSilent</H3>
+<PRE>
+public boolean <B>isSilent</B>()</PRE>
+<DL>
+<DD>Retrieves whether silent mode operation was requested in
+ the server properties.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>if true, silent mode was requested, else trace messages
+      are to be printed</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isTls()"><!-- --></A><H3>
+isTls</H3>
+<PRE>
+public boolean <B>isTls</B>()</PRE>
+<DL>
+<DD>Retrieves whether the use of secure sockets was requested in the
+ server properties.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>if true, secure sockets are requested, else not</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isTrace()"><!-- --></A><H3>
+isTrace</H3>
+<PRE>
+public boolean <B>isTrace</B>()</PRE>
+<DL>
+<DD>Retrieves whether JDBC trace messages are to go to System.out or the
+ DriverManger PrintStream/PrintWriter, if any.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if tracing is on (JDBC trace messages to system out)</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="putPropertiesFromFile(java.lang.String)"><!-- --></A><H3>
+putPropertiesFromFile</H3>
+<PRE>
+public boolean <B>putPropertiesFromFile</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;path)</PRE>
+<DL>
+<DD>Attempts to put properties from the file
+ with the specified path. The file
+ extension '.properties' is implicit and should not
+ be included in the path specification.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>path</CODE> - the path of the desired properties file, without the
+      '.properties' file extension
+<DT><B>Returns:</B><DD>true if the indicated file was read sucessfully, else false
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE> - if this server is running</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="putPropertiesFromString(java.lang.String)"><!-- --></A><H3>
+putPropertiesFromString</H3>
+<PRE>
+public void <B>putPropertiesFromString</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;s)</PRE>
+<DL>
+<DD>Puts properties from the supplied string argument.  The relevant
+ key value pairs are the same as those for the (web)server.properties
+ file format, except that the 'server.' prefix should not be specified.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>s</CODE> - semicolon-delimited key=value pair string,
+      e.g. silent=false;port=8080;...
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE> - if this server is running</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAddress(java.lang.String)"><!-- --></A><H3>
+setAddress</H3>
+<PRE>
+public void <B>setAddress</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;address)
+                throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></PRE>
+<DL>
+<DD>Sets the InetAddress with which this server's ServerSocket will be
+ constructed.  A null or empty string or the special value "0.0.0.0"
+ can be used to bypass explicit selection, causing the ServerSocket
+ to be constructed without specifying an InetAddress.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>address</CODE> - A string representing the desired InetAddress as would
+    be retrieved by InetAddres.getByName(), or a null or empty string
+    or "0.0.0.0" to signify that the server socket should be constructed
+    using the signature that does not specify the InetAddress.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE> - if this server is running</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDatabaseName(int, java.lang.String)"><!-- --></A><H3>
+setDatabaseName</H3>
+<PRE>
+public void <B>setDatabaseName</B>(int&nbsp;index,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;name)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></PRE>
+<DL>
+<DD>Sets the external name (url alias) of the i'th hosted database.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - external name (url alias) of the i'th HSQLDB database
+      instance this server is to host.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE> - if this server is running</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDatabasePath(int, java.lang.String)"><!-- --></A><H3>
+setDatabasePath</H3>
+<PRE>
+public void <B>setDatabasePath</B>(int&nbsp;index,
+                            <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;path)
+                     throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></PRE>
+<DL>
+<DD>Sets the path of the hosted database. The path always starts with the
+ catalog type. Examples of the path include: "file:mydir/mydb",
+ "mem:mymemdb", "res:org/mydomain/mydbs/settingsdb".
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>path</CODE> - The path of the i'th HSQLDB database instance this server
+      is to host.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDefaultWebPage(java.lang.String)"><!-- --></A><H3>
+setDefaultWebPage</H3>
+<PRE>
+public void <B>setDefaultWebPage</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;file)</PRE>
+<DL>
+<DD>Sets the name of the web page served when no page is specified.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>file</CODE> - the name of the web page served when no page is specified</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setPort(int)"><!-- --></A><H3>
+setPort</H3>
+<PRE>
+public void <B>setPort</B>(int&nbsp;port)
+             throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></PRE>
+<DL>
+<DD>Sets the server listen port.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>port</CODE> - the port at which this server listens
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setErrWriter(java.io.PrintWriter)"><!-- --></A><H3>
+setErrWriter</H3>
+<PRE>
+public void <B>setErrWriter</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A>&nbsp;pw)</PRE>
+<DL>
+<DD>Sets the PrintWriter to which server errors are logged. <p>
+
+ Setting this attribute to null disables server error logging
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pw</CODE> - the PrintWriter to which server messages are logged</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLogWriter(java.io.PrintWriter)"><!-- --></A><H3>
+setLogWriter</H3>
+<PRE>
+public void <B>setLogWriter</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A>&nbsp;pw)</PRE>
+<DL>
+<DD>Sets the PrintWriter to which server messages are logged. <p>
+
+ Setting this attribute to null disables server message logging
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pw</CODE> - the PrintWriter to which server messages are logged</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNoSystemExit(boolean)"><!-- --></A><H3>
+setNoSystemExit</H3>
+<PRE>
+public void <B>setNoSystemExit</B>(boolean&nbsp;noExit)</PRE>
+<DL>
+<DD>Sets whether this server calls System.exit() when shutdown.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>noExit</CODE> - if true, System.exit() will not be called.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setRestartOnShutdown(boolean)"><!-- --></A><H3>
+setRestartOnShutdown</H3>
+<PRE>
+public void <B>setRestartOnShutdown</B>(boolean&nbsp;restart)</PRE>
+<DL>
+<DD>Sets whether this server restarts on shutdown.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>restart</CODE> - if true, this server restarts on shutdown</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setSilent(boolean)"><!-- --></A><H3>
+setSilent</H3>
+<PRE>
+public void <B>setSilent</B>(boolean&nbsp;silent)</PRE>
+<DL>
+<DD>Sets silent mode operation
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>silent</CODE> - if true, then silent mode, else trace messages
+  are to be printed</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTls(boolean)"><!-- --></A><H3>
+setTls</H3>
+<PRE>
+public void <B>setTls</B>(boolean&nbsp;tls)</PRE>
+<DL>
+<DD>Sets whether to use secure sockets
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>tls</CODE> - true for secure sockets, else false
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE> - if this server is running</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTrace(boolean)"><!-- --></A><H3>
+setTrace</H3>
+<PRE>
+public void <B>setTrace</B>(boolean&nbsp;trace)</PRE>
+<DL>
+<DD>Sets whether trace messages go to System.out or the
+ DriverManger PrintStream/PrintWriter, if any.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>trace</CODE> - if true, route JDBC trace messages to System.out</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDaemon(boolean)"><!-- --></A><H3>
+setDaemon</H3>
+<PRE>
+public void <B>setDaemon</B>(boolean&nbsp;daemon)</PRE>
+<DL>
+<DD>Sets whether server thread is a daemon. Used before starting
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setWebRoot(java.lang.String)"><!-- --></A><H3>
+setWebRoot</H3>
+<PRE>
+public void <B>setWebRoot</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;root)</PRE>
+<DL>
+<DD>Sets the path of the root directory from which web content is served.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>root</CODE> - the root (context) directory from which web content
+      is served</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setProperties(org.hsqldb.persist.HsqlProperties)"><!-- --></A><H3>
+setProperties</H3>
+<PRE>
+public void <B>setProperties</B>(org.hsqldb.persist.HsqlProperties&nbsp;p)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A>,
+                          <A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></PRE>
+<DL>
+<DD>Sets server properties using the specified properties object
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>p</CODE> - The object containing properties to set
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></CODE> - ACL list was requested but problem loading ACL.
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE> - ACL list was requested but I/O problem loading ACL.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="start()"><!-- --></A><H3>
+start</H3>
+<PRE>
+public int <B>start</B>()</PRE>
+<DL>
+<DD>Starts this server synchronously. <p>
+
+ This method waits for current state to change from
+ SERVER_STATE_OPENNING. In order to discover the success or failure
+ of this operation, server state must be polled or a subclass of Server
+ must be used that overrides the setState method to provide state
+ change notification.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the server state noted at entry to this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="stop()"><!-- --></A><H3>
+stop</H3>
+<PRE>
+public int <B>stop</B>()</PRE>
+<DL>
+<DD>Stops this server asynchronously. <p>
+
+ This method returns immediately, regardless of current state.  In order
+ to discover the success or failure of this operation, server state must
+ be polled or a subclass of Server must be used that overrides the
+ setState method to provide state change notification.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the server state noted at entry to this method</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="notify(int, int)"><!-- --></A><H3>
+notify</H3>
+<PRE>
+public final void <B>notify</B>(int&nbsp;action,
+                         int&nbsp;id)</PRE>
+<DL>
+<DD>This is called from org.hsqldb.DatabaseManager when a database is
+ shutdown. This shuts the server down if it is the last database
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>action</CODE> - a code indicating what has happend</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="shutdown()"><!-- --></A><H3>
+shutdown</H3>
+<PRE>
+public void <B>shutdown</B>()</PRE>
+<DL>
+<DD>External method to shut down this server.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)</PRE>
+<DL>
+<DD>Creates and starts a new Server.  <p>
+
+ Allows starting a Server via the command line interface. <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>args</CODE> - the command line arguments for the Server instance</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/Server.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/Server.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Server.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/ServerAcl.AclFormatException.html b/doc/apidocs/org/hsqldb/server/ServerAcl.AclFormatException.html
new file mode 100644
index 0000000..5aca4bf
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/ServerAcl.AclFormatException.html
@@ -0,0 +1,244 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+ServerAcl.AclFormatException (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="ServerAcl.AclFormatException (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/ServerAcl.AclFormatException.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/ServerAcl.AclFormatException.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ServerAcl.AclFormatException.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Throwable">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.server</FONT>
+<BR>
+Class ServerAcl.AclFormatException</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">java.lang.Throwable</A>
+      <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">java.lang.Exception</A>
+          <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.server.ServerAcl.AclFormatException</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A></DD>
+</DL>
+<DL>
+<DT><B>Enclosing class:</B><DD><A HREF="../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public static final class <B>ServerAcl.AclFormatException</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A></DL>
+</PRE>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.hsqldb.server.ServerAcl.AclFormatException">Serialized Form</A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html#ServerAcl.AclFormatException(java.lang.String)">ServerAcl.AclFormatException</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;s)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Throwable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#fillInStackTrace()" title="class or interface in java.lang">fillInStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#getCause()" title="class or interface in java.lang">getCause</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#getLocalizedMessage()" title="class or interface in java.lang">getLocalizedMessage</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#getMessage()" title="class or interface in java.lang">getMessage</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#getStackTrace()" title="class or interface in java.lang">getStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#initCause(java.lang.Throwable)" title="class or interface in java.lang">initCause</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#printStackTrace()" title="class or interface in java.lang">printStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#printStackTrace(java.io.PrintStream)" title="class or interface in java.lang">printStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#printStackTrace(java.io.PrintWriter)" title="class or interface in java.lang">printStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#setStackTrace(java.lang.StackTraceElement[])" title="class or interface in java.lang">setStackTrace</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ServerAcl.AclFormatException(java.lang.String)"><!-- --></A><H3>
+ServerAcl.AclFormatException</H3>
+<PRE>
+public <B>ServerAcl.AclFormatException</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;s)</PRE>
+<DL>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/ServerAcl.AclFormatException.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/ServerAcl.AclFormatException.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ServerAcl.AclFormatException.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Throwable">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/ServerAcl.html b/doc/apidocs/org/hsqldb/server/ServerAcl.html
new file mode 100644
index 0000000..8bb4610
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/ServerAcl.html
@@ -0,0 +1,461 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+ServerAcl (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="ServerAcl (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/ServerAcl.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/ServerAcl.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ServerAcl.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.server</FONT>
+<BR>
+Class ServerAcl</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.server.ServerAcl</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>ServerAcl</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+A list of ACL permit and deny entries with a permitAccess method
+ which tells whether candidate addresses are permitted or denied
+ by this ACL list.
+ <P>
+ The ACL file is reloaded whenever a modification to it is detected.
+ If you copy in a file with an older file date, you will need to touch it.
+ </P>
+
+ <P>
+ The public runtime method is permitAccess().
+ The public setup method is the constructor.
+ </P> <P>
+ Each non-comment line in the ACL file must be a rule of the format:
+ <PRE><CODE>
+     {allow|deny} <ip_address>[/significant-bits]
+ </CODE></PRE>
+ For example
+ <PRE><CODE>
+     allow ahostname
+     deny ahost.domain.com
+     allow 127.0.0.1
+     allow 2001:db8::/32
+ </CODE></PRE>
+ </P> <P>
+ In order to detect bit specification mistakes, we require that
+ non-significant bits be zero in the values.
+ An undesirable consequence of this is, you can't use a specification like
+ the following to mean "all of the hosts on the same network as x.admc.com":
+ <PRE><CODE>
+     allow x.admc.com/24
+ </CODE></PRE>
+ </P>
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/server/ServerAcl.html#ServerAcl(java.io.File)"><CODE>ServerAcl(File)</CODE></A>, 
+<A HREF="../../../org/hsqldb/server/ServerAcl.html#permitAccess(java.lang.String)"><CODE>permitAccess(java.lang.String)</CODE></A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.html#ServerAcl(java.io.File)">ServerAcl</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;aclFile)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.html#colonNotation(byte[])">colonNotation</A></B>(byte[]&nbsp;uba)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.html#dottedNotation(byte[])">dottedNotation</A></B>(byte[]&nbsp;uba)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Utility method that allows interactive testing of individal
+ ACL records, as well as the net effect of the ACL record list.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.html#permitAccess(byte[])">permitAccess</A></B>(byte[]&nbsp;addr)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.html#permitAccess(java.lang.String)">permitAccess</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;s)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Uses system network libraries to resolve the given String to an IP addr,
+ then determine whether this address is permitted or denied.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.html#setPrintWriter(java.io.PrintWriter)">setPrintWriter</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A>&nbsp;pw)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/ServerAcl.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ServerAcl(java.io.File)"><!-- --></A><H3>
+ServerAcl</H3>
+<PRE>
+public <B>ServerAcl</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;aclFile)
+          throws <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A>,
+                 <A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></PRE>
+<DL>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE>
+<DD><CODE><A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="dottedNotation(byte[])"><!-- --></A><H3>
+dottedNotation</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>dottedNotation</B>(byte[]&nbsp;uba)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>uba</CODE> - Unsigned byte array</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="colonNotation(byte[])"><!-- --></A><H3>
+colonNotation</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>colonNotation</B>(byte[]&nbsp;uba)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>uba</CODE> - Unsigned byte array</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setPrintWriter(java.io.PrintWriter)"><!-- --></A><H3>
+setPrintWriter</H3>
+<PRE>
+public void <B>setPrintWriter</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html?is-external=true" title="class or interface in java.io">PrintWriter</A>&nbsp;pw)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>toString</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A></CODE> in class <CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="permitAccess(java.lang.String)"><!-- --></A><H3>
+permitAccess</H3>
+<PRE>
+public boolean <B>permitAccess</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;s)</PRE>
+<DL>
+<DD>Uses system network libraries to resolve the given String to an IP addr,
+ then determine whether this address is permitted or denied.
+
+ Specified name may be a numerical-based String like "1.2.3.4", a
+ constant known to the networking libraries, or a host name to be
+ resolved by the systems name resolution system.
+
+ If the given String can't be resolved to an IP addr, false is returned.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/hsqldb/server/ServerAcl.html#permitAccess(byte[])"><CODE>permitAccess(byte[])</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="permitAccess(byte[])"><!-- --></A><H3>
+permitAccess</H3>
+<PRE>
+public boolean <B>permitAccess</B>(byte[]&nbsp;addr)</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if access for the candidate address should be permitted,
+          false if access should be denied.
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A></CODE> - if no rule covers the candidate address.
+          This would be the case if this class is applied to some
+          network protocol other than ipv4 or ipv6, without adding a
+          default rule for it.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)
+                 throws <A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A>,
+                        <A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></PRE>
+<DL>
+<DD>Utility method that allows interactive testing of individal
+ ACL records, as well as the net effect of the ACL record list.
+
+ Run  "java -cp path/to/hsqldb.jar org.hsqldb.server.ServerAcl --help"
+ for Syntax help.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/ServerAcl.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/ServerAcl.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ServerAcl.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/WebServer.html b/doc/apidocs/org/hsqldb/server/WebServer.html
new file mode 100644
index 0000000..af9aaa5
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/WebServer.html
@@ -0,0 +1,483 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:42 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+WebServer (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="WebServer (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/WebServer.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/WebServer.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="WebServer.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.server</FONT>
+<BR>
+Class WebServer</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">org.hsqldb.server.Server</A>
+      <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.server.WebServer</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>org.hsqldb.server.HsqlSocketRequestHandler</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>WebServer</B><DT>extends <A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></DL>
+</PRE>
+
+<P>
+The HSQLDB HTTP protocol network database server. <p>
+
+  WebServer has two distinct functions:<p>
+
+  The primary function is to allow client/server access to HSQLDB databases
+  via the HTTP protocol. This protocol is less efficient than the HSQL
+  protocol used by the Server class and should be used only in situations
+  where sandboxes or firewalls between the client and the server do not
+  allow the use of the HSQL protocol. One example is client/server access by
+  an applet running in browsers on remote hosts and accessing the database
+  engine on the HTTP server from which the applet originated. From version
+  1.7.2, HTTP database connections are persistent and support transactions.
+  Similar to HSQL connections, they should be explicitly closed to free the
+  server resources. <p>
+
+  The secondary function of WebServer is to act as a simple general purpose
+  HTTP server. It is aimed to support the minimum requirements set out by
+  the HTTP/1.0 standard. The HEAD and GET methods can be used to query and
+  retreive static files from the HTTP server.<p>
+
+  Both the database server and HTTP server functions of WebServer can be
+  configured with the webserver.properties file. It contains entries for the
+  database server similar to those for the HSQL protocol Server class. In
+  addition, a list mapping different file endings to their mime types may be
+  included in this file. (fredt@users) <p>
+
+ From the command line, the options are as follows: <p>
+ <pre>
+ +-----------------+-------------+----------+------------------------------+
+ |    OPTION       |    TYPE     | DEFAULT  |         DESCRIPTION          |
+ +-----------------+-------------+----------+------------------------------|
+ | --help          |             |          | prints this message          |
+ | --address       | name|number | any      | server inet address          |
+ | --port          | number      | 80       | port at which server listens |
+ | --database.i    | [type]spec  | 0=test   | path of database i           |
+ | --dbname.i      | alias       |          | url alias for database i     |
+ | --silent        | true|false  | true     | false => display all queries |
+ | --trace         | true|false  | false    | display JDBC trace messages  |
+ | --no_system_exit| true|false  | false    | do not issue System.exit()   |
+ +-----------------+-------------+----------+------------------------------+
+ </pre>
+
+  Example of the webserver.properties file:
+
+ <pre>
+ server.port=80
+ server.database.0=test
+ server.dbname.0=...
+ ...
+ server.database.n=...
+ server.dbname.n=...
+ server.silent=true
+
+ .htm=text/html
+ .html=text/html
+ .txt=text/plain
+ .gif=image/gif
+ .class=application/octet-stream
+ .jpg=image/jpeg
+ .jgep=image/jpeg
+ .zip=application/x-zip-compressed
+ </pre>
+
+ <ul>
+   <li>For server.root, use '/'  as the separator, even for DOS/Windows.
+   <li>File extensions for mime types must be lowercase and start with '.'
+ </ul>
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>1.7.2</DD>
+<DT><B>Author:</B></DT>
+  <DD>Campbell Boucher-Burnett (boucherb@users dot sourceforge.net), Fred Toussi (fredt@users dot sourceforge.net)</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/WebServer.html#WebServer()">WebServer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/WebServer.html#getDefaultWebPage()">getDefaultWebPage</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the name of the web page served when no page is specified.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/WebServer.html#getHelpString()">getHelpString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a String object describing the command line and
+ properties options for this Server.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/WebServer.html#getProductName()">getProductName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves this server's product name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/WebServer.html#getProtocol()">getProtocol</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves a string respresentaion of the network protocol
+ this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/WebServer.html#getWebRoot()">getWebRoot</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the root context (directory) from which web content
+ is served.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/server/WebServer.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Starts a new WebServer.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.hsqldb.server.Server"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.hsqldb.server.<A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/hsqldb/server/Server.html#checkRunning(boolean)">checkRunning</A>, <A HREF="../../../org/hsqldb/server/Server.html#getAddress()">getAddress</A>, <A HREF="../../../org/hsqldb/server/Server.html#getDatabaseName(int, boolean)">getDatabaseName</A>, <A HREF="../../../org/hsqldb/server/Server.html#getDatabasePath(int, boolean)">getDatabasePath</A>, <A HREF="../../../org/hsqldb/server/Server.html#getDatabaseType(int)">getDatabaseType</A>, <A HREF="../../../org/hsqldb/server/Server.html#getErrWriter()">getErrWriter</A>, <A HREF="../../../org/hsqldb/server/Server.html#getLogWriter()">getLogWriter</A>, <A HREF="../../../org/hsqldb/server/Server.html#getPort()">getPort</A>, <A HREF="../../../org/hsqldb/server/Server.html#getProductVersion()">getProductVersion</A>, <A HREF="../../../org/hsqldb/server/Server.html#getServerError()">getServerError</A>, <A HREF="../../../org/hsqldb/server/Server.html#getServerId()">getServerId</A>, <A HREF="../../../org/hsqldb/server/Server.html#getState()">getState</A>, <A HREF="../../../org/hsqldb/server/Server.html#getStateDescriptor()">getStateDescriptor</A>, <A HREF="../../../org/hsqldb/server/Server.html#handleConnection(java.net.Socket)">handleConnection</A>, <A HREF="../../../org/hsqldb/server/Server.html#isNoSystemExit()">isNoSystemExit</A>, <A HREF="../../../org/hsqldb/server/Server.html#isRestartOnShutdown()">isRestartOnShutdown</A>, <A HREF="../../../org/hsqldb/server/Server.html#isSilent()">isSilent</A>, <A HREF="../../../org/hsqldb/server/Server.html#isTls()">isTls</A>, <A HREF="../../../org/hsqldb/server/Server.html#isTrace()">isTrace</A>, <A HREF="../../../org/hsqldb/server/Server.html#notify(int, int)">notify</A>, <A HREF="../../../org/hsqldb/server/Server.html#putPropertiesFromFile(java.lang.String)">putPropertiesFromFile</A>, <A HREF="../../../org/hsqldb/server/Server.html#putPropertiesFromString(java.lang.String)">putPropertiesFromString</A>, <A HREF="../../../org/hsqldb/server/Server.html#setAddress(java.lang.String)">setAddress</A>, <A HREF="../../../org/hsqldb/server/Server.html#setDaemon(boolean)">setDaemon</A>, <A HREF="../../../org/hsqldb/server/Server.html#setDatabaseName(int, java.lang.String)">setDatabaseName</A>, <A HREF="../../../org/hsqldb/server/Server.html#setDatabasePath(int, java.lang.String)">setDatabasePath</A>, <A HREF="../../../org/hsqldb/server/Server.html#setDefaultWebPage(java.lang.String)">setDefaultWebPage</A>, <A HREF="../../../org/hsqldb/server/Server.html#setErrWriter(java.io.PrintWriter)">setErrWriter</A>, <A HREF="../../../org/hsqldb/server/Server.html#setLogWriter(java.io.PrintWriter)">setLogWriter</A>, <A HREF="../../../org/hsqldb/server/Server.html#setNoSystemExit(boolean)">setNoSystemExit</A>, <A HREF="../../../org/hsqldb/server/Server.html#setPort(int)">setPort</A>, <A HREF="../../../org/hsqldb/server/Server.html#setProperties(org.hsqldb.persist.HsqlProperties)">setProperties</A>, <A HREF="../../../org/hsqldb/server/Server.html#setRestartOnShutdown(boolean)">setRestartOnShutdown</A>, <A HREF="../../../org/hsqldb/server/Server.html#setSilent(boolean)">setSilent</A>, <A HREF="../../../org/hsqldb/server/Server.html#setTls(boolean)">setTls</A>, <A HREF="../../../org/hsqldb/server/Server.html#setTrace(boolean)">setTrace</A>, <A HREF="../../../org/hsqldb/server/Server.html#setWebRoot(java.lang.String)">setWebRoot</A>, <A HREF="../../../org/hsqldb/server/Server.html#shutdown()">shutdown</A>, <A HREF="../../../org/hsqldb/server/Server.html#signalCloseAllServerConnections()">signalCloseAllServerConnections</A>, <A HREF="../../../org/hsqldb/server/Server.html#start()">start</A>, <A HREF="../../../org/hsqldb/server/Server.html#stop()">stop</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="WebServer()"><!-- --></A><H3>
+WebServer</H3>
+<PRE>
+public <B>WebServer</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)</PRE>
+<DL>
+<DD>Starts a new WebServer.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>args</CODE> - the "command line" parameters with which to start
+      the WebServer.  "-?" will cause the command line arguments
+      help to be printed to the standard output</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDefaultWebPage()"><!-- --></A><H3>
+getDefaultWebPage</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getDefaultWebPage</B>()</PRE>
+<DL>
+<DD>Retrieves the name of the web page served when no page is specified.
+ This attribute is relevant only when server protocol is HTTP(S).
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../../org/hsqldb/server/Server.html#getDefaultWebPage()">getDefaultWebPage</A></CODE> in class <CODE><A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the name of the web page served when no page is specified</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getHelpString()"><!-- --></A><H3>
+getHelpString</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getHelpString</B>()</PRE>
+<DL>
+<DD>Retrieves a String object describing the command line and
+ properties options for this Server.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../../org/hsqldb/server/Server.html#getHelpString()">getHelpString</A></CODE> in class <CODE><A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the command line and properties options help for this Server</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProductName()"><!-- --></A><H3>
+getProductName</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getProductName</B>()</PRE>
+<DL>
+<DD>Retrieves this server's product name.  <p>
+
+ Typically, this will be something like: "HSQLDB xxx server".
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../../org/hsqldb/server/Server.html#getProductName()">getProductName</A></CODE> in class <CODE><A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the product name of this server</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProtocol()"><!-- --></A><H3>
+getProtocol</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getProtocol</B>()</PRE>
+<DL>
+<DD>Retrieves a string respresentaion of the network protocol
+ this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../../org/hsqldb/server/Server.html#getProtocol()">getProtocol</A></CODE> in class <CODE><A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>string respresentation of this server's protocol</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWebRoot()"><!-- --></A><H3>
+getWebRoot</H3>
+<PRE>
+public <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>getWebRoot</B>()</PRE>
+<DL>
+<DD>Retrieves the root context (directory) from which web content
+ is served.  This property is relevant only when the server
+ protocol is HTTP(S).  Although unlikely, it may be that in the future
+ other contexts, such as jar urls may be supported, so that pages can
+ be served from the contents of a jar or from the JVM class path.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../../org/hsqldb/server/Server.html#getWebRoot()">getWebRoot</A></CODE> in class <CODE><A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the root context (directory) from which web content is served</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/WebServer.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/WebServer.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="WebServer.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/class-use/Server.html b/doc/apidocs/org/hsqldb/server/class-use/Server.html
new file mode 100644
index 0000000..bf0f85e
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/class-use/Server.html
@@ -0,0 +1,181 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.server.Server (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.server.Server (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/server//class-useServer.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Server.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.server.Server</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.server"><B>org.hsqldb.server</B></A></TD>
+<TD>The HyperSQL network listener classes.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.server"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A> in <A HREF="../../../../org/hsqldb/server/package-summary.html">org.hsqldb.server</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Subclasses of <A HREF="../../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A> in <A HREF="../../../../org/hsqldb/server/package-summary.html">org.hsqldb.server</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The HSQLDB HTTP protocol network database server.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/server//class-useServer.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Server.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/class-use/ServerAcl.AclFormatException.html b/doc/apidocs/org/hsqldb/server/class-use/ServerAcl.AclFormatException.html
new file mode 100644
index 0000000..471f7e7
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/class-use/ServerAcl.AclFormatException.html
@@ -0,0 +1,204 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.server.ServerAcl.AclFormatException (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.server.ServerAcl.AclFormatException (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/server//class-useServerAcl.AclFormatException.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ServerAcl.AclFormatException.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.server.ServerAcl.AclFormatException</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.server"><B>org.hsqldb.server</B></A></TD>
+<TD>The HyperSQL network listener classes.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.server"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Uses of <A HREF="../../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A> in <A HREF="../../../../org/hsqldb/server/package-summary.html">org.hsqldb.server</A></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Methods in <A HREF="../../../../org/hsqldb/server/package-summary.html">org.hsqldb.server</A> that throw <A HREF="../../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B>ServerAcl.</B><B><A HREF="../../../../org/hsqldb/server/ServerAcl.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Utility method that allows interactive testing of individal
+ ACL records, as well as the net effect of the ACL record list.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B>Server.</B><B><A HREF="../../../../org/hsqldb/server/Server.html#setProperties(org.hsqldb.persist.HsqlProperties)">setProperties</A></B>(org.hsqldb.persist.HsqlProperties&nbsp;p)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets server properties using the specified properties object</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2">Constructors in <A HREF="../../../../org/hsqldb/server/package-summary.html">org.hsqldb.server</A> that throw <A HREF="../../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/hsqldb/server/ServerAcl.html#ServerAcl(java.io.File)">ServerAcl</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/io/File.html?is-external=true" title="class or interface in java.io">File</A>&nbsp;aclFile)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/server//class-useServerAcl.AclFormatException.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ServerAcl.AclFormatException.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/class-use/ServerAcl.html b/doc/apidocs/org/hsqldb/server/class-use/ServerAcl.html
new file mode 100644
index 0000000..9e1b1f8
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/class-use/ServerAcl.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.server.ServerAcl (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.server.ServerAcl (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/server//class-useServerAcl.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ServerAcl.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.server.ServerAcl</B></H2>
+</CENTER>
+No usage of org.hsqldb.server.ServerAcl
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/server//class-useServerAcl.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="ServerAcl.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/class-use/WebServer.html b/doc/apidocs/org/hsqldb/server/class-use/WebServer.html
new file mode 100644
index 0000000..3e6591d
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/class-use/WebServer.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.server.WebServer (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.server.WebServer (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/server//class-useWebServer.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="WebServer.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.server.WebServer</B></H2>
+</CENTER>
+No usage of org.hsqldb.server.WebServer
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/server//class-useWebServer.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="WebServer.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/package-frame.html b/doc/apidocs/org/hsqldb/server/package-frame.html
new file mode 100644
index 0000000..d38e8fe
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/package-frame.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.server (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../org/hsqldb/server/package-summary.html" target="classFrame">org.hsqldb.server</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Server.html" title="class in org.hsqldb.server" target="classFrame">Server</A>
+<BR>
+<A HREF="ServerAcl.html" title="class in org.hsqldb.server" target="classFrame">ServerAcl</A>
+<BR>
+<A HREF="WebServer.html" title="class in org.hsqldb.server" target="classFrame">WebServer</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Exceptions</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="ServerAcl.AclFormatException.html" title="class in org.hsqldb.server" target="classFrame">ServerAcl.AclFormatException</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/package-summary.html b/doc/apidocs/org/hsqldb/server/package-summary.html
new file mode 100644
index 0000000..7116ae0
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/package-summary.html
@@ -0,0 +1,197 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.server (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.server (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/sample/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/util/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.hsqldb.server
+</H2>
+The HyperSQL network listener classes.
+<P>
+<B>See:</B>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="#package_description"><B>Description</B></A>
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server">Server</A></B></TD>
+<TD>The HSQLDB HSQL protocol network database server.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server">ServerAcl</A></B></TD>
+<TD>A list of ACL permit and deny entries with a permitAccess method
+ which tells whether candidate addresses are permitted or denied
+ by this ACL list.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server">WebServer</A></B></TD>
+<TD>The HSQLDB HTTP protocol network database server.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Exception Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">ServerAcl.AclFormatException</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<A NAME="package_description"><!-- --></A><H2>
+Package org.hsqldb.server Description
+</H2>
+
+<P>
+The HyperSQL network listener classes.
+<P>
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/sample/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/util/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/package-tree.html b/doc/apidocs/org/hsqldb/server/package-tree.html
new file mode 100644
index 0000000..a88714a
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/package-tree.html
@@ -0,0 +1,162 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.server Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.server Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/sample/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/util/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.hsqldb.server
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><B>Object</B></A><UL>
+<LI TYPE="circle">org.hsqldb.server.<A HREF="../../../org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><B>Server</B></A> (implements org.hsqldb.server.HsqlSocketRequestHandler)
+<UL>
+<LI TYPE="circle">org.hsqldb.server.<A HREF="../../../org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server"><B>WebServer</B></A></UL>
+<LI TYPE="circle">org.hsqldb.server.<A HREF="../../../org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><B>ServerAcl</B></A><LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang"><B>Throwable</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A>)
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang"><B>Exception</B></A><UL>
+<LI TYPE="circle">org.hsqldb.server.<A HREF="../../../org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><B>ServerAcl.AclFormatException</B></A></UL>
+</UL>
+</UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/sample/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/hsqldb/util/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/server/package-use.html b/doc/apidocs/org/hsqldb/server/package-use.html
new file mode 100644
index 0000000..67c8be0
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/server/package-use.html
@@ -0,0 +1,177 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Package org.hsqldb.server (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Package org.hsqldb.server (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>org.hsqldb.server</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Packages that use <A HREF="../../../org/hsqldb/server/package-summary.html">org.hsqldb.server</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="#org.hsqldb.server"><B>org.hsqldb.server</B></A></TD>
+<TD>The HyperSQL network listener classes.&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="org.hsqldb.server"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+Classes in <A HREF="../../../org/hsqldb/server/package-summary.html">org.hsqldb.server</A> used by <A HREF="../../../org/hsqldb/server/package-summary.html">org.hsqldb.server</A></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/server/class-use/Server.html#org.hsqldb.server"><B>Server</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The HSQLDB HSQL protocol network database server.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><B><A HREF="../../../org/hsqldb/server/class-use/ServerAcl.AclFormatException.html#org.hsqldb.server"><B>ServerAcl.AclFormatException</B></A></B>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/server/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/util/MainInvoker.html b/doc/apidocs/org/hsqldb/util/MainInvoker.html
new file mode 100644
index 0000000..7f6db60
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/util/MainInvoker.html
@@ -0,0 +1,343 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:43 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+MainInvoker (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="MainInvoker (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/MainInvoker.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/util/MainInvoker.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="MainInvoker.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.hsqldb.util</FONT>
+<BR>
+Class MainInvoker</H2>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</A>
+  <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.hsqldb.util.MainInvoker</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>MainInvoker</B><DT>extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></DL>
+</PRE>
+
+<P>
+Invokes the static main(String[]) method from each class specified.
+
+ This class <b>will System.exit()</b> if any invocation fails.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+  <DD>HSQLDB 1.8.0</DD>
+<DT><B>Author:</B></DT>
+  <DD>Blaine Simpson (blaine dot simpson at admc dot com)</DD>
+</DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/util/MainInvoker.html#LS">LS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/hsqldb/util/MainInvoker.html#MainInvoker()">MainInvoker</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/util/MainInvoker.html#invoke(java.lang.String, java.lang.String[])">invoke</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;className,
+       <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Invokes the static main(String[]) method from each specified class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/hsqldb/util/MainInvoker.html#main(java.lang.String[])">main</A></B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Invokes the static main(String[]) method from each specified class.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</A>, <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true#wait(long, int)" title="class or interface in java.lang">wait</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="LS"><!-- --></A><H3>
+LS</H3>
+<PRE>
+public static <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>LS</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="MainInvoker()"><!-- --></A><H3>
+MainInvoker</H3>
+<PRE>
+public <B>MainInvoker</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;sa)</PRE>
+<DL>
+<DD>Invokes the static main(String[]) method from each specified class.
+ This method <b>will System.exit()</b> if any invocation fails.
+
+ Note that multiple class invocations are delimited by empty-string
+ parameters.  How the user supplies these empty strings is determined
+ entirely by the caller's environment.  From Windows this can
+ generally be accomplished with double-quotes like "".  From all
+ popular UNIX shells, this can be accomplished with single or
+ double-quotes:  '' or "".
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sa</CODE> - Run java org.hsqldb.util.MainInvoker --help for syntax help</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="invoke(java.lang.String, java.lang.String[])"><!-- --></A><H3>
+invoke</H3>
+<PRE>
+public static void <B>invoke</B>(<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&nbsp;className,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[]&nbsp;args)
+                   throws <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/ClassNotFoundException.html?is-external=true" title="class or interface in java.lang">ClassNotFoundException</A>,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/NoSuchMethodException.html?is-external=true" title="class or interface in java.lang">NoSuchMethodException</A>,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/IllegalAccessException.html?is-external=true" title="class or interface in java.lang">IllegalAccessException</A>,
+                          <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/reflect/InvocationTargetException.html?is-external=true" title="class or interface in java.lang.reflect">InvocationTargetException</A></PRE>
+<DL>
+<DD>Invokes the static main(String[]) method from each specified class.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/ClassNotFoundException.html?is-external=true" title="class or interface in java.lang">ClassNotFoundException</A></CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/NoSuchMethodException.html?is-external=true" title="class or interface in java.lang">NoSuchMethodException</A></CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/IllegalAccessException.html?is-external=true" title="class or interface in java.lang">IllegalAccessException</A></CODE>
+<DD><CODE><A HREF="http://java.sun.com/javase/6/docs/api/java/lang/reflect/InvocationTargetException.html?is-external=true" title="class or interface in java.lang.reflect">InvocationTargetException</A></CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="class-use/MainInvoker.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/util/MainInvoker.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="MainInvoker.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/util/class-use/MainInvoker.html b/doc/apidocs/org/hsqldb/util/class-use/MainInvoker.html
new file mode 100644
index 0000000..29e2931
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/util/class-use/MainInvoker.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Class org.hsqldb.util.MainInvoker (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Class org.hsqldb.util.MainInvoker (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/util//class-useMainInvoker.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="MainInvoker.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Class<br>org.hsqldb.util.MainInvoker</B></H2>
+</CENTER>
+No usage of org.hsqldb.util.MainInvoker
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util"><FONT CLASS="NavBarFont1"><B>Class</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../../index.html?org/hsqldb/util//class-useMainInvoker.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="MainInvoker.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/util/package-frame.html b/doc/apidocs/org/hsqldb/util/package-frame.html
new file mode 100644
index 0000000..4e94317
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/util/package-frame.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.util (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../org/hsqldb/util/package-summary.html" target="classFrame">org.hsqldb.util</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="MainInvoker.html" title="class in org.hsqldb.util" target="classFrame">MainInvoker</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/util/package-summary.html b/doc/apidocs/org/hsqldb/util/package-summary.html
new file mode 100644
index 0000000..6550224
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/util/package-summary.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.util (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.util (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;NEXT PACKAGE</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/util/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.hsqldb.util
+</H2>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util">MainInvoker</A></B></TD>
+<TD>Invokes the static main(String[]) method from each class specified.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-use.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;NEXT PACKAGE</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/util/package-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/util/package-tree.html b/doc/apidocs/org/hsqldb/util/package-tree.html
new file mode 100644
index 0000000..0ccecca
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/util/package-tree.html
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+org.hsqldb.util Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="org.hsqldb.util Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/util/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.hsqldb.util
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><B>Object</B></A><UL>
+<LI TYPE="circle">org.hsqldb.util.<A HREF="../../../org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util"><B>MainInvoker</B></A></UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/hsqldb/server/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/util/package-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/org/hsqldb/util/package-use.html b/doc/apidocs/org/hsqldb/util/package-use.html
new file mode 100644
index 0000000..91d6530
--- /dev/null
+++ b/doc/apidocs/org/hsqldb/util/package-use.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Uses of Package org.hsqldb.util (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Uses of Package org.hsqldb.util (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/util/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Uses of Package<br>org.hsqldb.util</B></H2>
+</CENTER>
+No usage of org.hsqldb.util
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Use</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/hsqldb/util/package-use.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="package-use.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/overview-frame.html b/doc/apidocs/overview-frame.html
new file mode 100644
index 0000000..ec3923f
--- /dev/null
+++ b/doc/apidocs/overview-frame.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Overview List (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TH ALIGN="left" NOWRAP><FONT size="+1" CLASS="FrameTitleFont">
+<B></B></FONT></TH>
+</TR>
+</TABLE>
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="allclasses-frame.html" target="packageFrame">All Classes</A></FONT>
+<P>
+<FONT size="+1" CLASS="FrameHeadingFont">
+Packages</FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/package-frame.html" target="packageFrame">org.hsqldb</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/cmdline/package-frame.html" target="packageFrame">org.hsqldb.cmdline</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/jdbc/package-frame.html" target="packageFrame">org.hsqldb.jdbc</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/lib/package-frame.html" target="packageFrame">org.hsqldb.lib</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/lib/tar/package-frame.html" target="packageFrame">org.hsqldb.lib.tar</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/sample/package-frame.html" target="packageFrame">org.hsqldb.sample</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/server/package-frame.html" target="packageFrame">org.hsqldb.server</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/hsqldb/util/package-frame.html" target="packageFrame">org.hsqldb.util</A></FONT>
+<BR>
+</TD>
+</TR>
+</TABLE>
+
+<P>
+&nbsp;
+</BODY>
+</HTML>
diff --git a/doc/apidocs/overview-summary.html b/doc/apidocs/overview-summary.html
new file mode 100644
index 0000000..86d005f
--- /dev/null
+++ b/doc/apidocs/overview-summary.html
@@ -0,0 +1,187 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Overview (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Overview (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?overview-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="overview-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H1>
+HSQLDB 2.0.0
+</H1>
+</CENTER>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Packages</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/hsqldb/package-summary.html">org.hsqldb</A></B></TD>
+<TD>Contains basic HyperSQL engine classes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/hsqldb/cmdline/package-summary.html">org.hsqldb.cmdline</A></B></TD>
+<TD>Contains command-line utilities.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/hsqldb/jdbc/package-summary.html">org.hsqldb.jdbc</A></B></TD>
+<TD>Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/hsqldb/lib/package-summary.html">org.hsqldb.lib</A></B></TD>
+<TD>Shared classes used by other HyperSQL classes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/hsqldb/lib/tar/package-summary.html">org.hsqldb.lib.tar</A></B></TD>
+<TD>Contains the DbBackup class, for backing up HyperSQL databases, and support
+  classes for handling files in tar and pax format.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/hsqldb/sample/package-summary.html">org.hsqldb.sample</A></B></TD>
+<TD>Contains examples for hooking into HyperSQL from your own Java code.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/hsqldb/server/package-summary.html">org.hsqldb.server</A></B></TD>
+<TD>The HyperSQL network listener classes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/hsqldb/util/package-summary.html">org.hsqldb.util</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+</TABLE>
+
+<P>
+&nbsp;<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?overview-summary.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="overview-summary.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/overview-tree.html b/doc/apidocs/overview-tree.html
new file mode 100644
index 0000000..f764daf
--- /dev/null
+++ b/doc/apidocs/overview-tree.html
@@ -0,0 +1,198 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:47 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Class Hierarchy (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Class Hierarchy (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?overview-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="overview-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For All Packages</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="org/hsqldb/package-tree.html">org.hsqldb</A>, <A HREF="org/hsqldb/cmdline/package-tree.html">org.hsqldb.cmdline</A>, <A HREF="org/hsqldb/jdbc/package-tree.html">org.hsqldb.jdbc</A>, <A HREF="org/hsqldb/lib/package-tree.html">org.hsqldb.lib</A>, <A HREF="org/hsqldb/lib/tar/package-tree.html">org.hsqldb.lib.tar</A>, <A HREF="org/hsqldb/sample/package-tree.html">org.hsqldb.sample</A>, <A HREF="org/hsqldb/server/package-tree.html">org.hsqldb.server</A>, <A HREF="org/hsqldb/util/package-tree.html">org.hsqldb.util</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><B>Object</B></A><UL>
+<LI TYPE="circle">org.hsqldb.lib.tar.<A HREF="org/hsqldb/lib/tar/DbBackup.html" title="class in org.hsqldb.lib.tar"><B>DbBackup</B></A><LI TYPE="circle">java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html?is-external=true" title="class or interface in java.io"><B>InputStream</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A>)
+<UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/BlobInputStream.html" title="class in org.hsqldb.jdbc"><B>BlobInputStream</B></A></UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCArray.html" title="class in org.hsqldb.jdbc"><B>JDBCArray</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Array.html?is-external=true" title="class or interface in java.sql">Array</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCBlob.html" title="class in org.hsqldb.jdbc"><B>JDBCBlob</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCBlobClient.html" title="class in org.hsqldb.jdbc"><B>JDBCBlobClient</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Blob.html?is-external=true" title="class or interface in java.sql">Blob</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCClob.html" title="class in org.hsqldb.jdbc"><B>JDBCClob</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>)
+<UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCNClob.html" title="class in org.hsqldb.jdbc"><B>JDBCNClob</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/NClob.html?is-external=true" title="class or interface in java.sql">NClob</A>)
+</UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCClobClient.html" title="class in org.hsqldb.jdbc"><B>JDBCClobClient</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Clob.html?is-external=true" title="class or interface in java.sql">Clob</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCColumnMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCColumnMetaData</B></A><LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCConnection.html" title="class in org.hsqldb.jdbc"><B>JDBCConnection</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCDatabaseMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCDatabaseMetaData</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A>, java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc"><B>JDBCDataSource</B></A> (implements javax.sql.<A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/CommonDataSource.html?is-external=true" title="class or interface in javax.sql">CommonDataSource</A>, javax.sql.<A HREF="http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html?is-external=true" title="class or interface in javax.sql">DataSource</A>, javax.naming.<A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/Referenceable.html?is-external=true" title="class or interface in javax.naming">Referenceable</A>, java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A>, java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCDataSourceFactory.html" title="class in org.hsqldb.jdbc"><B>JDBCDataSourceFactory</B></A> (implements javax.naming.spi.<A HREF="http://java.sun.com/javase/6/docs/api/javax/naming/spi/ObjectFactory.html?is-external=true" title="class or interface in javax.naming.spi">ObjectFactory</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCDriver.html" title="class in org.hsqldb.jdbc"><B>JDBCDriver</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Driver.html?is-external=true" title="class or interface in java.sql">Driver</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCParameterMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCParameterMetaData</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ParameterMetaData.html?is-external=true" title="class or interface in java.sql">ParameterMetaData</A>, java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCPreparedStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCPreparedStatement</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html?is-external=true" title="class or interface in java.sql">PreparedStatement</A>)
+<UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCCallableStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCCallableStatement</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/CallableStatement.html?is-external=true" title="class or interface in java.sql">CallableStatement</A>)
+</UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCResultSet.html" title="class in org.hsqldb.jdbc"><B>JDBCResultSet</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html?is-external=true" title="class or interface in java.sql">ResultSet</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCResultSetMetaData.html" title="class in org.hsqldb.jdbc"><B>JDBCResultSetMetaData</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/ResultSetMetaData.html?is-external=true" title="class or interface in java.sql">ResultSetMetaData</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCRowId.html" title="class in org.hsqldb.jdbc"><B>JDBCRowId</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/RowId.html?is-external=true" title="class or interface in java.sql">RowId</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCSavepoint.html" title="class in org.hsqldb.jdbc"><B>JDBCSavepoint</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Savepoint.html?is-external=true" title="class or interface in java.sql">Savepoint</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCSQLXML.html" title="class in org.hsqldb.jdbc"><B>JDBCSQLXML</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/SQLXML.html?is-external=true" title="class or interface in java.sql">SQLXML</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCSQLXML.SAX2XMLStreamWriter.html" title="class in org.hsqldb.jdbc"><B>JDBCSQLXML.SAX2XMLStreamWriter</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A>, org.xml.sax.<A HREF="http://java.sun.com/javase/6/docs/api/org/xml/sax/ContentHandler.html?is-external=true" title="class or interface in org.xml.sax">ContentHandler</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/JDBCStatement.html" title="class in org.hsqldb.jdbc"><B>JDBCStatement</B></A> (implements java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A>, java.sql.<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Wrapper.html?is-external=true" title="class or interface in java.sql">Wrapper</A>)
+<LI TYPE="circle">org.hsqldb.util.<A HREF="org/hsqldb/util/MainInvoker.html" title="class in org.hsqldb.util"><B>MainInvoker</B></A><LI TYPE="circle">org.hsqldb.lib.<A HREF="org/hsqldb/lib/RCData.html" title="class in org.hsqldb.lib"><B>RCData</B></A><LI TYPE="circle">java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Reader.html?is-external=true" title="class or interface in java.io"><B>Reader</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</A>, java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Readable.html?is-external=true" title="class or interface in java.lang">Readable</A>)
+<UL>
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/ClobInputStream.html" title="class in org.hsqldb.jdbc"><B>ClobInputStream</B></A></UL>
+<LI TYPE="circle">org.hsqldb.server.<A HREF="org/hsqldb/server/Server.html" title="class in org.hsqldb.server"><B>Server</B></A> (implements org.hsqldb.server.HsqlSocketRequestHandler)
+<UL>
+<LI TYPE="circle">org.hsqldb.server.<A HREF="org/hsqldb/server/WebServer.html" title="class in org.hsqldb.server"><B>WebServer</B></A></UL>
+<LI TYPE="circle">org.hsqldb.server.<A HREF="org/hsqldb/server/ServerAcl.html" title="class in org.hsqldb.server"><B>ServerAcl</B></A><LI TYPE="circle">org.hsqldb.cmdline.<A HREF="org/hsqldb/cmdline/SqlFile.html" title="class in org.hsqldb.cmdline"><B>SqlFile</B></A><LI TYPE="circle">org.hsqldb.sample.<A HREF="org/hsqldb/sample/SqlFileEmbedder.html" title="class in org.hsqldb.sample"><B>SqlFileEmbedder</B></A><LI TYPE="circle">org.hsqldb.cmdline.<A HREF="org/hsqldb/cmdline/SqlTool.html" title="class in org.hsqldb.cmdline"><B>SqlTool</B></A><LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang"><B>Throwable</B></A> (implements java.io.<A HREF="http://java.sun.com/javase/6/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</A>)
+<UL>
+<LI TYPE="circle">java.lang.<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang"><B>Exception</B></A><UL>
+<LI TYPE="circle">org.hsqldb.server.<A HREF="org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server"><B>ServerAcl.AclFormatException</B></A><LI TYPE="circle">org.hsqldb.cmdline.<A HREF="org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline"><B>SqlTool.SqlToolException</B></A></UL>
+</UL>
+<LI TYPE="circle">org.hsqldb.sample.<A HREF="org/hsqldb/sample/TriggerSample.html" title="class in org.hsqldb.sample"><B>TriggerSample</B></A> (implements org.hsqldb.<A HREF="org/hsqldb/Trigger.html" title="interface in org.hsqldb">Trigger</A>)
+<LI TYPE="circle">org.hsqldb.jdbc.<A HREF="org/hsqldb/jdbc/Util.html" title="class in org.hsqldb.jdbc"><B>Util</B></A></UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">org.hsqldb.<A HREF="org/hsqldb/Trigger.html" title="interface in org.hsqldb"><B>Trigger</B></A></UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?overview-tree.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="overview-tree.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/apidocs/package-list b/doc/apidocs/package-list
new file mode 100644
index 0000000..0788ae0
--- /dev/null
+++ b/doc/apidocs/package-list
@@ -0,0 +1,8 @@
+org.hsqldb
+org.hsqldb.cmdline
+org.hsqldb.jdbc
+org.hsqldb.lib
+org.hsqldb.lib.tar
+org.hsqldb.sample
+org.hsqldb.server
+org.hsqldb.util
diff --git a/doc/apidocs/resources/inherit.gif b/doc/apidocs/resources/inherit.gif
new file mode 100644
index 0000000..c814867
--- /dev/null
+++ b/doc/apidocs/resources/inherit.gif
Binary files differ
diff --git a/doc/apidocs/serialized-form.html b/doc/apidocs/serialized-form.html
new file mode 100644
index 0000000..07ff62d
--- /dev/null
+++ b/doc/apidocs/serialized-form.html
@@ -0,0 +1,2225 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_20) on Sun Jun 06 23:05:46 EDT 2010 -->
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<TITLE>
+Serialized Form (HSQLDB 2.0.0 API)
+</TITLE>
+
+<META NAME="date" CONTENT="2010-06-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="javadoc.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="Serialized Form (HSQLDB 2.0.0 API)";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?serialized-form.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="serialized-form.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H1>
+Serialized Form</H1>
+</CENTER>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.hsqldb</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.hsqldb.HsqlException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.HsqlException extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/RuntimeException.html?is-external=true" title="class or interface in java.lang">RuntimeException</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+message</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>message</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+state</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>state</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+code</H3>
+<PRE>
+int <B>code</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+level</H3>
+<PRE>
+int <B>level</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+statementGroup</H3>
+<PRE>
+int <B>statementGroup</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+statementCode</H3>
+<PRE>
+int <B>statementCode</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.hsqldb.HsqlException.HsqlRuntimeMemoryError"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.HsqlException.HsqlRuntimeMemoryError extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/OutOfMemoryError.html?is-external=true" title="class or interface in java.lang">OutOfMemoryError</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<A NAME="org.hsqldb.SetFunction"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.SetFunction extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+distinctValues</H3>
+<PRE>
+org.hsqldb.lib.HashSet <B>distinctValues</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+isDistinct</H3>
+<PRE>
+boolean <B>isDistinct</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+setType</H3>
+<PRE>
+int <B>setType</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+dataType</H3>
+<PRE>
+int <B>dataType</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+type</H3>
+<PRE>
+org.hsqldb.types.Type <B>type</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+count</H3>
+<PRE>
+int <B>count</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+hasNull</H3>
+<PRE>
+boolean <B>hasNull</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+every</H3>
+<PRE>
+boolean <B>every</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+some</H3>
+<PRE>
+boolean <B>some</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+currentLong</H3>
+<PRE>
+long <B>currentLong</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+currentDouble</H3>
+<PRE>
+double <B>currentDouble</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+currentBigDecimal</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html?is-external=true" title="class or interface in java.math">BigDecimal</A> <B>currentBigDecimal</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+currentValue</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> <B>currentValue</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+hi</H3>
+<PRE>
+long <B>hi</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+lo</H3>
+<PRE>
+long <B>lo</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sk</H3>
+<PRE>
+double <B>sk</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+vk</H3>
+<PRE>
+double <B>vk</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+n</H3>
+<PRE>
+long <B>n</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+initialized</H3>
+<PRE>
+boolean <B>initialized</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sample</H3>
+<PRE>
+boolean <B>sample</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.hsqldb.cmdline</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.hsqldb.cmdline.SqlTool.SqlToolException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/hsqldb/cmdline/SqlTool.SqlToolException.html" title="class in org.hsqldb.cmdline">org.hsqldb.cmdline.SqlTool.SqlToolException</A> extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>1424909871915188519L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+exitValue</H3>
+<PRE>
+int <B>exitValue</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.hsqldb.cmdline.SqlToolError"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.cmdline.SqlToolError extends org.hsqldb.lib.AppendableException implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>1792522673702223649L
+
+<P>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.hsqldb.jdbc</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.hsqldb.jdbc.JDBCDataSource"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/hsqldb/jdbc/JDBCDataSource.html" title="class in org.hsqldb.jdbc">org.hsqldb.jdbc.JDBCDataSource</A> extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+loginTimeout</H3>
+<PRE>
+int <B>loginTimeout</B></PRE>
+<DL>
+<DD>Login timeout
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+password</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>password</B></PRE>
+<DL>
+<DD>Default password to use for connections
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+user</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>user</B></PRE>
+<DL>
+<DD>Default user to use for connections
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+database</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>database</B></PRE>
+<DL>
+<DD>Database location
+<P>
+<DL>
+</DL>
+</DL>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.hsqldb.lib</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.hsqldb.lib.AppendableException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.lib.AppendableException extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-1002629580611098803L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+appendages</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">E</A>&gt; <B>appendages</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.hsqldb.lib.tar</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.hsqldb.lib.tar.PIFData"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.lib.tar.PIFData extends <A HREF="http://java.sun.com/javase/6/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>&gt; implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>3086795680582315773L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+sizeObject</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</A> <B>sizeObject</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.hsqldb.lib.tar.TarMalformatException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.lib.tar.TarMalformatException extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<A NAME="org.hsqldb.lib.tar.TarReader.TarEntryHeader.MissingField"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.lib.tar.TarReader.TarEntryHeader.MissingField extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+field</H3>
+<PRE>
+org.hsqldb.lib.tar.TarHeaderField <B>field</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.hsqldb.sample</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.hsqldb.sample.ConnectionTypesSample"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.sample.ConnectionTypesSample extends <A HREF="http://java.sun.com/javase/6/docs/api/java/util/Vector.html?is-external=true" title="class or interface in java.util">Vector</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<A NAME="org.hsqldb.sample.DatabaseManagerSample"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.sample.DatabaseManagerSample extends org.hsqldb.util.DatabaseManager implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.hsqldb.server</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.hsqldb.server.ServerAcl.AclFormatException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/hsqldb/server/ServerAcl.AclFormatException.html" title="class in org.hsqldb.server">org.hsqldb.server.ServerAcl.AclFormatException</A> extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<A NAME="org.hsqldb.server.Servlet"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.server.Servlet extends <A HREF="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/http/HttpServlet.html?is-external=true" title="class or interface in javax.servlet.http">HttpServlet</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+dbType</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>dbType</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+dbPath</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>dbPath</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+errorStr</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>errorStr</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+rowOut</H3>
+<PRE>
+org.hsqldb.rowio.RowOutputBinary <B>rowOut</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+rowIn</H3>
+<PRE>
+org.hsqldb.rowio.RowInputBinary <B>rowIn</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+iQueries</H3>
+<PRE>
+int <B>iQueries</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.hsqldb.util</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.hsqldb.util.ConnectionSetting"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.util.ConnectionSetting extends <A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+name</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>name</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+driver</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>driver</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+url</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>url</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+user</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>user</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+pw</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>pw</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.hsqldb.util.DatabaseManager"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.util.DatabaseManager extends <A HREF="http://java.sun.com/javase/6/docs/api/java/applet/Applet.html?is-external=true" title="class or interface in java.applet">Applet</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+cConn</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>cConn</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+dMeta</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A> <B>dMeta</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sStatement</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A> <B>sStatement</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+mRecent</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Menu.html?is-external=true" title="class or interface in java.awt">Menu</A> <B>mRecent</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sRecent</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[] <B>sRecent</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+iRecent</H3>
+<PRE>
+int <B>iRecent</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+txtCommand</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextArea.html?is-external=true" title="class or interface in java.awt">TextArea</A> <B>txtCommand</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+butExecute</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Button.html?is-external=true" title="class or interface in java.awt">Button</A> <B>butExecute</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+butClear</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Button.html?is-external=true" title="class or interface in java.awt">Button</A> <B>butClear</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tTree</H3>
+<PRE>
+org.hsqldb.util.Tree <B>tTree</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+pResult</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Panel.html?is-external=true" title="class or interface in java.awt">Panel</A> <B>pResult</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+lTime</H3>
+<PRE>
+long <B>lTime</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+iResult</H3>
+<PRE>
+int <B>iResult</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+gResult</H3>
+<PRE>
+org.hsqldb.util.Grid <B>gResult</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+txtResult</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextArea.html?is-external=true" title="class or interface in java.awt">TextArea</A> <B>txtResult</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+bHelp</H3>
+<PRE>
+boolean <B>bHelp</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+fMain</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Frame.html?is-external=true" title="class or interface in java.awt">Frame</A> <B>fMain</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+imgEmpty</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Image.html?is-external=true" title="class or interface in java.awt">Image</A> <B>imgEmpty</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+ifHuge</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>ifHuge</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.hsqldb.util.DatabaseManagerSwing"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.util.DatabaseManagerSwing extends <A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JApplet.html?is-external=true" title="class or interface in javax.swing">JApplet</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+isOracle</H3>
+<PRE>
+boolean <B>isOracle</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+localActionList</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/util/ArrayList.html?is-external=true" title="class or interface in java.util">ArrayList</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/ArrayList.html?is-external=true" title="class or interface in java.util">E</A>&gt; <B>localActionList</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+jframe</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JFrame.html?is-external=true" title="class or interface in javax.swing">JFrame</A> <B>jframe</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cConn</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>cConn</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+rowConn</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Connection.html?is-external=true" title="class or interface in java.sql">Connection</A> <B>rowConn</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+dMeta</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/DatabaseMetaData.html?is-external=true" title="class or interface in java.sql">DatabaseMetaData</A> <B>dMeta</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sStatement</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/sql/Statement.html?is-external=true" title="class or interface in java.sql">Statement</A> <B>sStatement</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+mRecent</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JMenu.html?is-external=true" title="class or interface in javax.swing">JMenu</A> <B>mRecent</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sRecent</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[] <B>sRecent</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+iRecent</H3>
+<PRE>
+int <B>iRecent</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+txtCommand</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JTextArea.html?is-external=true" title="class or interface in javax.swing">JTextArea</A> <B>txtCommand</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+txtCommandScroll</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JScrollPane.html?is-external=true" title="class or interface in javax.swing">JScrollPane</A> <B>txtCommandScroll</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+butExecute</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JButton.html?is-external=true" title="class or interface in javax.swing">JButton</A> <B>butExecute</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tTree</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JTree.html?is-external=true" title="class or interface in javax.swing">JTree</A> <B>tTree</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tScrollPane</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JScrollPane.html?is-external=true" title="class or interface in javax.swing">JScrollPane</A> <B>tScrollPane</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+treeModel</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/tree/DefaultTreeModel.html?is-external=true" title="class or interface in javax.swing.tree">DefaultTreeModel</A> <B>treeModel</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tableModel</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/table/TableModel.html?is-external=true" title="class or interface in javax.swing.table">TableModel</A> <B>tableModel</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+rootNode</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/tree/DefaultMutableTreeNode.html?is-external=true" title="class or interface in javax.swing.tree">DefaultMutableTreeNode</A> <B>rootNode</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+pResult</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JPanel.html?is-external=true" title="class or interface in javax.swing">JPanel</A> <B>pResult</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+lTime</H3>
+<PRE>
+long <B>lTime</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+gResult</H3>
+<PRE>
+org.hsqldb.util.GridSwing <B>gResult</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+gResultTable</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JTable.html?is-external=true" title="class or interface in javax.swing">JTable</A> <B>gResultTable</B></PRE>
+<DL>
+<DD>I think this is used to store model info whether we're using Grid
+  output or not (this object is queried for data to display for
+  text output mode).
+  If so, the presentation-independent model part should be moved
+  to an appropriately-named class instead of storing pure data in
+  a Swing-specific class.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+gScrollPane</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JScrollPane.html?is-external=true" title="class or interface in javax.swing">JScrollPane</A> <B>gScrollPane</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+txtResult</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JTextArea.html?is-external=true" title="class or interface in javax.swing">JTextArea</A> <B>txtResult</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+txtResultScroll</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JScrollPane.html?is-external=true" title="class or interface in javax.swing">JScrollPane</A> <B>txtResultScroll</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+nsSplitPane</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JSplitPane.html?is-external=true" title="class or interface in javax.swing">JSplitPane</A> <B>nsSplitPane</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+ewSplitPane</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JSplitPane.html?is-external=true" title="class or interface in javax.swing">JSplitPane</A> <B>ewSplitPane</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+bHelp</H3>
+<PRE>
+boolean <B>bHelp</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+fMain</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/RootPaneContainer.html?is-external=true" title="class or interface in javax.swing">RootPaneContainer</A> <B>fMain</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sqlScriptBuffer</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>sqlScriptBuffer</B></PRE>
+<DL>
+<DD>Value of this variable only retained if huge input script read in.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+jtoolbar</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JToolBar.html?is-external=true" title="class or interface in javax.swing">JToolBar</A> <B>jtoolbar</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+showSchemas</H3>
+<PRE>
+boolean <B>showSchemas</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+showTooltips</H3>
+<PRE>
+boolean <B>showTooltips</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+autoRefresh</H3>
+<PRE>
+boolean <B>autoRefresh</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+gridFormat</H3>
+<PRE>
+boolean <B>gridFormat</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+displayRowCounts</H3>
+<PRE>
+boolean <B>displayRowCounts</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+showSys</H3>
+<PRE>
+boolean <B>showSys</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+showIndexDetails</H3>
+<PRE>
+boolean <B>showIndexDetails</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+currentLAF</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>currentLAF</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+pStatus</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JPanel.html?is-external=true" title="class or interface in javax.swing">JPanel</A> <B>pStatus</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+rbAllSchemas</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JRadioButtonMenuItem.html?is-external=true" title="class or interface in javax.swing">JRadioButtonMenuItem</A> <B>rbAllSchemas</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+mitemAbout</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JMenuItem.html?is-external=true" title="class or interface in javax.swing">JMenuItem</A> <B>mitemAbout</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+mitemHelp</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JMenuItem.html?is-external=true" title="class or interface in javax.swing">JMenuItem</A> <B>mitemHelp</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+mitemUpdateSchemas</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JMenuItem.html?is-external=true" title="class or interface in javax.swing">JMenuItem</A> <B>mitemUpdateSchemas</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+boxAutoCommit</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JCheckBoxMenuItem.html?is-external=true" title="class or interface in javax.swing">JCheckBoxMenuItem</A> <B>boxAutoCommit</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+boxLogging</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JCheckBoxMenuItem.html?is-external=true" title="class or interface in javax.swing">JCheckBoxMenuItem</A> <B>boxLogging</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+boxShowSchemas</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JCheckBoxMenuItem.html?is-external=true" title="class or interface in javax.swing">JCheckBoxMenuItem</A> <B>boxShowSchemas</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+boxAutoRefresh</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JCheckBoxMenuItem.html?is-external=true" title="class or interface in javax.swing">JCheckBoxMenuItem</A> <B>boxAutoRefresh</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+boxTooltips</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JCheckBoxMenuItem.html?is-external=true" title="class or interface in javax.swing">JCheckBoxMenuItem</A> <B>boxTooltips</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+boxRowCounts</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JCheckBoxMenuItem.html?is-external=true" title="class or interface in javax.swing">JCheckBoxMenuItem</A> <B>boxRowCounts</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+boxShowGrid</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JCheckBoxMenuItem.html?is-external=true" title="class or interface in javax.swing">JCheckBoxMenuItem</A> <B>boxShowGrid</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+boxShowSys</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JCheckBoxMenuItem.html?is-external=true" title="class or interface in javax.swing">JCheckBoxMenuItem</A> <B>boxShowSys</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+rbNativeLF</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JRadioButtonMenuItem.html?is-external=true" title="class or interface in javax.swing">JRadioButtonMenuItem</A> <B>rbNativeLF</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+rbJavaLF</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JRadioButtonMenuItem.html?is-external=true" title="class or interface in javax.swing">JRadioButtonMenuItem</A> <B>rbJavaLF</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+rbMotifLF</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JRadioButtonMenuItem.html?is-external=true" title="class or interface in javax.swing">JRadioButtonMenuItem</A> <B>rbMotifLF</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+jStatusLine</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JLabel.html?is-external=true" title="class or interface in javax.swing">JLabel</A> <B>jStatusLine</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+fMainCursor</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Cursor.html?is-external=true" title="class or interface in java.awt">Cursor</A> <B>fMainCursor</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+txtCommandCursor</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Cursor.html?is-external=true" title="class or interface in java.awt">Cursor</A> <B>txtCommandCursor</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+txtResultCursor</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Cursor.html?is-external=true" title="class or interface in java.awt">Cursor</A> <B>txtResultCursor</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tipMap</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">K</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">V</A>&gt; <B>tipMap</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+mnuSchemas</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JMenu.html?is-external=true" title="class or interface in javax.swing">JMenu</A> <B>mnuSchemas</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+waitCursor</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Cursor.html?is-external=true" title="class or interface in java.awt">Cursor</A> <B>waitCursor</B></PRE>
+<DL>
+<DD>Wait Cursor
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+schemaFilter</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>schemaFilter</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+prefs</H3>
+<PRE>
+org.hsqldb.util.DatabaseManagerSwing.DBMPrefs <B>prefs</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+dummyThread</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Thread.html?is-external=true" title="class or interface in java.lang">Thread</A> <B>dummyThread</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+busyText</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>busyText</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+enableButtonRunnable</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Runnable.html?is-external=true" title="class or interface in java.lang">Runnable</A> <B>enableButtonRunnable</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+disableButtonRunnable</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Runnable.html?is-external=true" title="class or interface in java.lang">Runnable</A> <B>disableButtonRunnable</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+buttonUpdaterThread</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Thread.html?is-external=true" title="class or interface in java.lang">Thread</A> <B>buttonUpdaterThread</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+buttonUpdater</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Runnable.html?is-external=true" title="class or interface in java.lang">Runnable</A> <B>buttonUpdater</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+jbuttonClear</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JButton.html?is-external=true" title="class or interface in javax.swing">JButton</A> <B>jbuttonClear</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+jbuttonExecute</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JButton.html?is-external=true" title="class or interface in javax.swing">JButton</A> <B>jbuttonExecute</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+treeRefreshRunnable</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/Runnable.html?is-external=true" title="class or interface in java.lang">Runnable</A> <B>treeRefreshRunnable</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+alreadyHandled</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/event/MouseEvent.html?is-external=true" title="class or interface in java.awt.event">MouseEvent</A> <B>alreadyHandled</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+schemaListListener</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/event/ActionListener.html?is-external=true" title="class or interface in java.awt.event">ActionListener</A> <B>schemaListListener</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.hsqldb.util.FontDialogSwing"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.util.FontDialogSwing extends <A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/JDialog.html?is-external=true" title="class or interface in javax.swing">JDialog</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<A NAME="org.hsqldb.util.TableSorter"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.util.TableSorter extends <A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/table/AbstractTableModel.html?is-external=true" title="class or interface in javax.swing.table">AbstractTableModel</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+tableModel</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/table/TableModel.html?is-external=true" title="class or interface in javax.swing.table">TableModel</A> <B>tableModel</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+viewToModel</H3>
+<PRE>
+org.hsqldb.util.TableSorter.Row[] <B>viewToModel</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+modelToView</H3>
+<PRE>
+int[] <B>modelToView</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tableHeader</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/table/JTableHeader.html?is-external=true" title="class or interface in javax.swing.table">JTableHeader</A> <B>tableHeader</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+mouseListener</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/event/MouseListener.html?is-external=true" title="class or interface in java.awt.event">MouseListener</A> <B>mouseListener</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tableModelListener</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/javax/swing/event/TableModelListener.html?is-external=true" title="class or interface in javax.swing.event">TableModelListener</A> <B>tableModelListener</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+columnComparators</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">K</A>,<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">V</A>&gt; <B>columnComparators</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sortingColumns</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">E</A>&gt; <B>sortingColumns</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.hsqldb.util.Transfer"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.hsqldb.util.Transfer extends <A HREF="http://java.sun.com/javase/6/docs/api/java/applet/Applet.html?is-external=true" title="class or interface in java.applet">Applet</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+fMain</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Frame.html?is-external=true" title="class or interface in java.awt">Frame</A> <B>fMain</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+imgEmpty</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Image.html?is-external=true" title="class or interface in java.awt">Image</A> <B>imgEmpty</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sourceDb</H3>
+<PRE>
+org.hsqldb.util.DataAccessPoint <B>sourceDb</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+targetDb</H3>
+<PRE>
+org.hsqldb.util.DataAccessPoint <B>targetDb</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tCurrent</H3>
+<PRE>
+org.hsqldb.util.TransferTable <B>tCurrent</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+iMaxRows</H3>
+<PRE>
+int <B>iMaxRows</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+iSelectionStep</H3>
+<PRE>
+int <B>iSelectionStep</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tTable</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Vector.html?is-external=true" title="class or interface in java.util">Vector</A>&lt;<A HREF="http://java.sun.com/javase/6/docs/api/java/util/Vector.html?is-external=true" title="class or interface in java.util">E</A>&gt; <B>tTable</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+lTable</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/List.html?is-external=true" title="class or interface in java.awt">List</A> <B>lTable</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sSourceSchemas</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A>[] <B>sSourceSchemas</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sSourceCatalog</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>sSourceCatalog</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sDestSchema</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>sDestSchema</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sDestCatalog</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</A> <B>sDestCatalog</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tSourceTable</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tSourceTable</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tDestTable</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tDestTable</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tDestDropIndex</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tDestDropIndex</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tDestCreateIndex</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tDestCreateIndex</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tDestDrop</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tDestDrop</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tDestCreate</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tDestCreate</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tDestDelete</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tDestDelete</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tDestAlter</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tDestAlter</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tSourceSelect</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tSourceSelect</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tDestInsert</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tDestInsert</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cTransfer</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cTransfer</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cDrop</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cDrop</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cCreate</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cCreate</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cDelete</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cDelete</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cInsert</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cInsert</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cAlter</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cAlter</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cCreateIndex</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cCreateIndex</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cDropIndex</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cDropIndex</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cFKForced</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cFKForced</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cIdxForced</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Checkbox.html?is-external=true" title="class or interface in java.awt">Checkbox</A> <B>cIdxForced</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+bStart</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Button.html?is-external=true" title="class or interface in java.awt">Button</A> <B>bStart</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+bContinue</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/Button.html?is-external=true" title="class or interface in java.awt">Button</A> <B>bContinue</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tMessage</H3>
+<PRE>
+<A HREF="http://java.sun.com/javase/6/docs/api/java/awt/TextField.html?is-external=true" title="class or interface in java.awt">TextField</A> <B>tMessage</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+iTransferMode</H3>
+<PRE>
+int <B>iTransferMode</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+CurrentTransfer</H3>
+<PRE>
+int <B>CurrentTransfer</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+CurrentAlter</H3>
+<PRE>
+int <B>CurrentAlter</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Use</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html?serialized-form.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="serialized-form.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+<i>Copyright © 2001 - 2009 HSQL Development Group.</i>
+</BODY>
+</HTML>
diff --git a/doc/branding-frag.xhtml b/doc/branding-frag.xhtml
new file mode 100644
index 0000000..5f30c34
--- /dev/null
+++ b/doc/branding-frag.xhtml
@@ -0,0 +1,5 @@
+<!-- $Id: branding-frag.xhtml 3510 2010-03-08 17:38:55Z unsaved $ -->
+
+<div class="branding">
+  <img src="../images/hypersql_logo.png"/>
+</div>
diff --git a/doc/docbook.css b/doc/docbook.css
new file mode 100644
index 0000000..0890083
--- /dev/null
+++ b/doc/docbook.css
@@ -0,0 +1,106 @@
+/* COMMENT:  The shared.css stylesheet for the hsqldb/docs directory and elsewhere *?
+/* This material is published under the Copyrights and Licenses listed at */
+/* and in the directory /hsqldb/docs/hsqldb_lic.txt */
+
+a:visited { color: #000080; }
+a:link { color: #0000BB; }
+a:active { color: #0000FF; }
+
+span.guibutton, span.guilabel, span.guimenu, span.guimenuitem, span.guisubmenu {
+    color: #000080;
+    font-family:sans-serif;
+}
+span.guibutton, span.guilabel {
+    font-weight:bold;
+}
+span.guimenu, span.guimenuitem, span.guisubmenu {
+    font-style:italic;
+}
+
+div.caption      { font-size: 80%; }
+
+/********** Admonitions *****************/
+div.tip, div.note {
+    background-color:#FFE4E1;
+    border:2px solid gray;
+}
+div.warning, div.caution, div.important {
+    background-color:#FFE4E1;
+    border:2px solid black;
+}
+/****************************************/
+
+pre.screen         {
+    background-color:#F5F5F5;
+    border:1px solid gray;
+    padding:5px;
+    font-family:monospace;
+}
+
+pre.programlisting {
+    background-color:#F0F8FF;
+    border:1px solid gray;
+    padding:5px;
+    font-family:monospace;
+}
+
+div.variablelist {
+    border:1px solid gray;
+    padding:2px;
+}
+
+span.term {  /* in a variablelist, also in dl dt */
+    font-weight:bold;
+    padding-left:3px; padding-right:3px;
+    color:#000080;
+}
+
+div.itemizedlist ul.disc li {
+    margin-bottom:3px;
+}
+
+h1.title {
+    font-size: 200%; /* Book title */
+    color:#000080;
+}
+h2.subtitle { font-size: 140%; } /* Book subtitle */
+div.chapter h2.title, div.preface h2.title, div.appendix h2.title, div.index h2.title {
+    /* All components */
+    font-size: 170%;
+    font-weight: bold;
+    color: #000080;
+}
+div.chapter h2.subtitle, div.preface h2.subtitle, div.appendix h2.subtitle, div.index h2.subtitle {
+    font-size: 130%;
+}
+div.section h2.title {
+    /* level1 sections */
+    font-size: 150%;
+    font-weight: bold;
+    color: #000080;
+}
+div.section h3.title {
+    /* level2 sections */
+    font-size: 130%;
+    font-weight: bold;
+}
+div.section h4.title {
+    /* level3 sections */
+    font-size: 123%;
+    font-weight: bold;
+}
+div.section h5.title {
+    /* level4 sections */
+    font-size: 116%;
+    font-weight: bold;
+}
+
+span.remark        {
+    background-color:#32cd32;
+    font:normal bold 12px sans-serif;
+    border:2px solid green; padding-left:2px; padding-right:2px;
+}
+
+img { border:0; padding:0; margin:0; }
+
+p.copyright { font-family:sans-serif; }
diff --git a/doc/guide/accesscontrol-chapt.html b/doc/guide/accesscontrol-chapt.html
new file mode 100644
index 0000000..2ad6bb7
--- /dev/null
+++ b/doc/guide/accesscontrol-chapt.html
@@ -0,0 +1,712 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;6.&nbsp;Access Control</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="texttables-chapt.html" title="Chapter&nbsp;5.&nbsp;Text Tables">
+<link rel="next" href="dataaccess-chapt.html" title="Chapter&nbsp;7.&nbsp;Data Access and Change">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="texttables-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;6.&nbsp;Access Control</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="dataaccess-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;5.&nbsp;Text Tables&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;7.&nbsp;Data Access and Change</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="accesscontrol-chapt"></a>Chapter&nbsp;6.&nbsp;Access Control</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3096 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N1170F"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2009-08-09 17:50:39 +0100 (Sun, 09 Aug 2009) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N11712">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N11752">Authorizations and Access Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a></span>
+</dt>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N117CE">Access Rights</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N11712"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>Apart from schemas and their object, each HyperSQL catalog has USER
+    and ROLE objects. These objects are collectively called
+    <span class="emphasis"><em>authorizations</em></span>. Each AUTHORIZATION has some access
+    rights on some of the schemas or the objects they contain. The persistent
+    elements of an SQL environment are database objects</p>
+<p>Each database object has a name. A name is an identifier and is
+    unique within its name-space. Authorizations names follow the rules
+    described below and the case-normal form is stored in the database. When
+    connecting to a database, the user name and password must match the case
+    of the case-normal form.</p>
+<a name="N1171C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>identifier</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>definition of identifier</em></span>
+</p>
+<p>
+<code class="literal">&lt;identifier&gt; ::= &lt;regular identifier&gt; |
+    &lt;delimited identifier&gt; | &lt;SQL language identifier&gt;
+    </code>
+</p>
+<p>
+<code class="literal">&lt;delimited identifier&gt; ::= &lt;double quote&gt;
+    &lt;character sequence&gt; &lt;double quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;regular identifier&gt; ::= &lt;special character
+    sequence&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL language identifier&gt; ::= &lt;special
+    character sequence&gt;</code>
+</p>
+<p>A <code class="literal">&lt;delimited identifier&gt;</code> is a sequence
+    of characters enclosed with double-quote symbols. All characters are
+    allowed in the character sequence.</p>
+<p>A <code class="literal">&lt;regular identifier&gt;</code> is a special
+    sequence of characters. It consists of letters, digits and the underscore
+    characters. It must begin with a letter.</p>
+<p>A <code class="literal">&lt;SQL language identifier&gt;</code> is similar
+    to <code class="literal">&lt;regular identifier&gt;</code> but the letters can range
+    only from A-Z in the ASCII character set. This type of identifier is used
+    for names of CHARACTER SET objects.</p>
+<p>If the character sequence of a delimited identifier is the same
+    as an undelimited identifier, it represents the same identifier. For
+    example "JOHN" is the same identifier as JOHN. In a <code class="literal">&lt;regular
+    identifier&gt;</code> the case-normal form is considered for
+    comparison. This form consists of the upper-case of equivalent of all the
+    letters.</p>
+<p>The character sequence length of all identifiers must be between
+    1 and 128 characters.</p>
+<p>A reserved word is one that is used by the SQL Standard for
+    special purposes. It is similar to a <code class="literal">&lt;regular
+    identifier&gt;</code> but it cannot be used as an identifier for user
+    objects. If a reserved word is enclosed in double quote characters, it
+    becomes a quoted identifier and can be used for database
+    objects.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N11752"></a>Authorizations and Access Control</h2>
+</div>
+</div>
+</div>
+<p>In general, ROLE and USER objects simply control access to schema
+    objects. This is the scope of the SQL Standard. However, there are special
+    roles that allow the creation of USER and ROLE objects and also allow some
+    special operations on the database as a whole. These roles are not defined
+    by the Standard, which has left it to implementors to define such roles as
+    they are needed for the particular SQL implementation.</p>
+<p>A ROLE has a name a collection of zero or more other roles, plus
+    some privileges (access rights). A USER has a name and a password. It
+    similarly has a collection of zero or more roles plus some
+    privileges.</p>
+<p>USER objects existed in the SQL-92, but ROLE objects were introduced
+    in SQL:1999. Originally it was intended that USER objects would normally
+    be the same as the operating system USER objects and their authentication
+    would be handled outside the SQL environment. The co-existence of ROLE and
+    USER objects results in complexity. With the addition of ROLE objects,
+    there is no rationale, other than legacy support, for granting privileges
+    to USER objects directly. It is better to create roles and grant
+    privileges to them, then grant the roles to USER objects.</p>
+<p>The Standard effectively defines a special ROLE, named PUBLIC. All
+    authorization have the PUBLIC role, which cannot be removed from them.
+    Therefore any access right assigned to the PUBLIC role applies to all
+    authorizations in the database. For many simple databases, it is adequate
+    to create a single, non-admin user, then assign access rights to the
+    pre-existing PUBLIC role. Access to INFORMATION_SCHEMA views is granted to
+    PUBLIC, therefore these views are accessible to all. However, the contents
+    of each view depends on the ROLE or USER (AUTHORIZATION) that is in force
+    while accessing the view.</p>
+<p>Each schema has a single AUTHORIZATION. This is commonly known as
+    the <span class="emphasis"><em>owner</em></span> of the schema. All the objects in the
+    schema inherit the schema owner. The schema owner can add objects to the
+    schema, drop them or alter them.</p>
+<p>By default, the objects in a schema can only be accessed by the
+    schema owner. The schema owner can grant access rights on the objects to
+    other users or roles.</p>
+<a name="N11764" class="indexterm"></a>
+<p>
+<span class="bold"><strong>authorization
+    identifier</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>authorization identifier</em></span>
+</p>
+<p>
+<code class="literal">&lt;authorization identifier&gt; ::= &lt;role name&gt; |
+    &lt;user name&gt;</code>
+</p>
+<p>Authorization identifiers share the same name-space within the
+    database. The same name cannot be used for a USER and a ROLE.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11775"></a>Built-In Roles and Users</h3>
+</div>
+</div>
+</div>
+<p>There are some pre-defined roles in each database; some defined by
+      the SQL Standard, some by HyperSQL. These roles can be assigned to users
+      (directly or via other, user-defined roles). In addition, there is the
+      default initial user, SA, created with each new database.</p>
+<a name="N1177A" class="indexterm"></a>
+<p>
+<span class="bold"><strong>PUBLIC</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the PUBLIC role</em></span>
+</p>
+<p>The role that is assigned to all authorizations (roles and
+      users) in the database. This role has access rights to all objects in
+      the INFORMATION_SCHEMA. Any roles or rights granted to this role, are in
+      effect granted to all users of the database.</p>
+<a name="N11788" class="indexterm"></a>
+<p>
+<span class="bold"><strong>_SYSTEM</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the _SYSTEM role</em></span>
+</p>
+<p>This role is the authorization for the pre-defined (system)
+      objects in the database, including the INFORMATION_SCHEMA. This role
+      cannot be assigned to any authorization.</p>
+<a name="N11796" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DBA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the DBA role (HyperSQL-specific)</em></span>
+</p>
+<p>This is a special role in HyperSQL. A user that has this role
+      can perform all possible administrative tasks on the database. The DBA
+      role can also act as a proxy for all the roles and users in the
+      database. This means it can do everything the authorization for a schema
+      can do, including dropping the schema or its objects, or granting rights
+      on the schema objects to a grantee.</p>
+<a name="N117A4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE_SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the CREATE_SCHEMA role
+      (HyperSQL-specific)</em></span>
+</p>
+<p>An authorization that has this role, can create schemas. The
+      DBA authorization has this role and can grant it to other
+      authorizations.</p>
+<a name="N117B2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CHANGE_AUTHORIZATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the CHANGE_AUTHORIZATION role
+      (HyperSQL-specific)</em></span>
+</p>
+<p>A user that has this role, can change the authorization for the
+      current session to another user. The DBA authorization has this role and
+      can grant it to other authorizations.</p>
+<a name="N117C0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the SA user (HyperSQL-specific)</em></span>
+</p>
+<p>This user is automatically created with a new database and has
+      the DBA role. Initially, the password for this user is an empty string.
+      After connecting to the new database as this user, it is possible to
+      change the password, create other users and created new schema objects.
+      The SA user can be dropped by another user that has the DBA
+      role.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N117CE"></a>Access Rights</h3>
+</div>
+</div>
+</div>
+<p>By default, the objects in a schema can only be accessed by the
+      schema owner. But the schema owner can grant privileges (access rights)
+      on the objects to other users or roles.</p>
+<p>Things can get far more complex, because the grant of privileges
+      can be made WITH GRANT OPTION. In this case, the role or user that has
+      been granted the privilege can grant the privilege to other roles and
+      users.</p>
+<p>Privileges can also be revoked from users or roles.</p>
+<p>The statements for granting and revoking privileges normally
+      specify which privileges are granted or revoked. However, there is a
+      shortcut, ALL PRIVILEGES, which means all the privileges that the
+      <code class="literal">&lt;grantor&gt;</code> has on the schema object. The
+      <code class="literal">&lt;grantor&gt;</code> is normally the CURRENT_USER of the
+      session that issues the statement.</p>
+<p>The user or role that is granted privileges is referred to as
+      <code class="literal">&lt;grantee&gt;</code> for the granted privileges.</p>
+<p>
+<span class="bold"><strong>Table</strong></span>
+</p>
+<p>For tables, including views, privileges can be granted with
+      different degrees of granularity. It is possible to grant a privilege on
+      all columns of a table, or on specific columns of the table.</p>
+<p>The DELETE privilege applies to the table, rather than its
+      columns. It applies to all DELETE statements.</p>
+<p>The SELECT, INSERT and UPDATE privileges may apply to all
+      columns or to individual columns. These privileges determine whether the
+      <code class="literal">&lt;grantee&gt;</code> can execute SQL data statements on
+      the table.</p>
+<p>The SELECT privilege designates the columns that can be
+      referenced in SELECT statements, as well as the columns that are read in
+      a DELETE or UPDATE statement, including the search condition.</p>
+<p>The INSERT privilege designates the columns into which explicit
+      values can be inserted. To be able to insert a row into the table, the
+      user must therefore have the INSERT privilege on the table, or at least
+      all the columns that do not have a default value.</p>
+<p>The UPDATE privilege simply designates the table or the
+      specific columns that can be updated.</p>
+<p>The REFERENCES privilege allows the
+      <code class="literal">&lt;grantee&gt;</code> to define a FOREIGN KEY constraint on
+      a different table, which references the table or the specific columns
+      designated for the REFERENCES privilege.</p>
+<p>The TRIGGER privilege allows adding a trigger to the
+      table.</p>
+<p>
+<span class="bold"><strong>Sequence, Type, Domain, Character Set,
+      Collation, Transliteration,</strong></span>
+</p>
+<p>For these objects, only USAGE can be granted. The USAGE
+      privilege is needed when object is referenced directly in an SQL
+      statement.</p>
+<p>
+<span class="bold"><strong>Routine</strong></span>
+</p>
+<p>For routines, including procedures or functions, only EXECUTE
+      privilege can be granted. This privilege is needed when the routine is
+      used directly in an SQL statement.</p>
+<p>
+<span class="bold"><strong>Other Objects</strong></span>
+</p>
+<p>Other objects such as constraints and assertions are not used
+      directly and there is no grantable privilege that refers to
+      them.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N11810"></a>Statements for
+    Authorization and Access Control</h2>
+</div>
+</div>
+</div>
+<p>The statements listed below allow creation and destruction of USER
+    and ROLE objects. The GRANT and REVOKE statements allow roles to be
+    assigned to other roles or to users. The same statements are also used in
+    a different form to assign privileges on schema objects to users and
+    roles.</p>
+<a name="N11816" class="indexterm"></a>
+<p>
+<a name="create_user-sql"></a><span class="bold"><strong>CREATE
+    USER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>user definition (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;user definition&gt; ::= CREATE USER &lt;user
+    name&gt; PASSWORD &lt;password&gt; [ ADMIN ]</code>
+</p>
+<p>Define a new user and its password. <code class="literal">&lt;user
+    name&gt;</code> is an SQL identifier. If it is double-quoted it is
+    case-sensitive, otherwise it is turned to uppercase.
+    <code class="literal">&lt;password&gt;</code> is a string enclosed with single quote
+    characters and is case-sensitive. If <code class="literal">ADMIN</code> is
+    specified, the DBA role is granted to the new user. Only a user with the
+    DBA role can execute this statement.</p>
+<a name="N11831" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP USER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop user statement (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop user statement&gt; ::= DROP USER &lt;user
+    name&gt;</code>
+</p>
+<p>Drop (destroy) an existing user. If the specified user is the
+    authorization for a schema, the schema is destroyed. Only a user with the
+    DBA role can execute this statement.</p>
+<a name="N11842" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER USER ... SET
+    PASSWORD</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set the password for a user
+    (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter user set password statement&gt; ::= ALTER USER
+    &lt;user name&gt; SET PASSWORD &lt;password&gt;</code>
+</p>
+<p>Change the password of an existing user. <code class="literal">&lt;user
+    name&gt;</code> is an SQL identifier. If it is double-quoted it is
+    case-sensitive, otherwise it is turned to uppercase.
+    <code class="literal">&lt;password&gt;</code> is a string enclosed with single quote
+    characters and is case-sensitive. Only a user with the DBA role can
+    execute this command.</p>
+<a name="N11859" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER USER ... SET INITIAL
+    SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set the initial schema for a user
+    (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter user set initial schema statement&gt; ::=
+    ALTER USER &lt;user name&gt; SET INITIAL SCHEMA &lt;schema name&gt; |
+    DEFAULT</code>
+</p>
+<p>Change the initial schema for a user. The initial schema is the
+    schema used by default for SQL statements issued during a session. If
+    <code class="literal">DEFAULT</code> is used, the default initial schema for all
+    users is used as the initial schema for the user. The SET SCHEMA command
+    allows the user to change the schema for the duration of the session. Only
+    a user with the DBA role can execute this statement.</p>
+<a name="N1186D" class="indexterm"></a>
+<p>
+<a name="set_password-sql"></a><span class="bold"><strong>SET
+    PASSWORD</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set password statement (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;set password statement&gt; ::= SET PASSWORD
+    &lt;password&gt;</code>
+</p>
+<p>Set the password for the current user.
+    <code class="literal">&lt;password&gt;</code> is a string enclosed with single quote
+    characters and is case-sensitive.</p>
+<a name="N11882" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET INITIAL SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set the initial schema for the current user
+    (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;set initial schema statement&gt; ::= SET INITIAL
+    SCHEMA &lt;schema name&gt; | DEFAULT</code>
+</p>
+<p>Change the initial schema for the current user. The initial
+    schema is the schema used by default for SQL statements issued during a
+    session. If <code class="literal">DEFAULT</code> is used, the default initial schema
+    for all users is used as the initial schema for the current user. The
+    separate SET SCHEMA command allows the user to change the schema for the
+    duration of the session. See also the <a class="link" href="sessions-chapt.html" title="Chapter&nbsp;3.&nbsp;Sessions and Transactions">Sessions and Transactions</a> chapter.</p>
+<a name="N1189B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE DEFAULT INITIAL
+    SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set the default initial schema for all users
+    (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database default initial schema statement&gt;
+    ::= SET DATABASE DEFAULT INITIAL SCHEMA &lt;schema
+    name&gt;</code>
+</p>
+<p>Sets the initial schema for new users. This schema can later be
+    changed with the <code class="literal">&lt;set initial schema statement&gt;</code>
+    command.</p>
+<a name="N118AF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE ROLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>role definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;role definition&gt; ::= CREATE ROLE &lt;role
+    name&gt; [ WITH ADMIN &lt;grantor&gt; ]</code>
+</p>
+<p>Defines a new role. Initially the role has no rights, except
+    those of the PUBLIC role. Only a user with the DBA role can execute this
+    command.</p>
+<a name="N118C0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP ROLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop role statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop role statement&gt; ::= DROP ROLE &lt;role
+    name&gt;</code>
+</p>
+<p>Drop (destroy) a role. If the specified role is the authorization
+    for a schema, the schema is destroyed. Only a user with the DBA role can
+    execute this statement.</p>
+<a name="N118D1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>GRANTED BY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>grantor determination</em></span>
+</p>
+<p>
+<code class="literal">GRANTED BY &lt;grantor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;grantor&gt; ::= CURRENT_USER |
+    CURRENT_ROLE</code>
+</p>
+<p>The authorization that is granting or revoking a role or
+    privileges. The optional <code class="literal">GRANTED BY &lt;grantor&gt;</code>
+    clause can be used in various statements that perform GRANT or REVOKE
+    actions. If the clause is not used, the authorization is CURRENT_USER.
+    Otherwise, it is the specified authorization.</p>
+<a name="N118E8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>GRANT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>grant privilege statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;grant privilege statement&gt; ::= GRANT
+    &lt;privileges&gt; TO &lt;grantee&gt; [ { &lt;comma&gt; &lt;grantee&gt;
+    }... ] [ WITH GRANT OPTION ] [ GRANTED BY &lt;grantor&gt;
+    ]</code>
+</p>
+<p>Assign privileges on schema objects to roles or users. Each
+    <code class="literal">&lt;grantee&gt;</code> is a role or a user. If <code class="literal">[ WITH
+    GRANT OPTION ]</code> is specified, then the
+    <code class="literal">&lt;grantee&gt;</code> can assign the privileges to other
+    <code class="literal">&lt;grantee&gt;</code> objects.</p>
+<p>
+<code class="literal">&lt;privileges&gt; ::= &lt;object privileges&gt; ON
+    &lt;object name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;object name&gt; ::= [ TABLE ] &lt;table name&gt; |
+    DOMAIN &lt;domain name&gt; | COLLATION &lt;collation name&gt; | CHARACTER
+    SET &lt;character set name&gt; | TRANSLATION &lt;transliteration name&gt;
+    | TYPE &lt;user-defined type name&gt; | SEQUENCE &lt;sequence generator
+    name&gt; | &lt;specific routine designator&gt; | ROUTINE &lt;routine
+    name&gt; | FUNCTION &lt;function name&gt; | PROCEDURE &lt;procedure
+    name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;object privileges&gt; ::= ALL PRIVILEGES |
+    &lt;action&gt; [ { &lt;comma&gt; &lt;action&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;action&gt; ::= SELECT | SELECT &lt;left paren&gt;
+    &lt;privilege column list&gt; &lt;right paren&gt; | DELETE | INSERT [
+    &lt;left paren&gt; &lt;privilege column list&gt; &lt;right paren&gt; ] |
+    UPDATE [ &lt;left paren&gt; &lt;privilege column list&gt; &lt;right
+    paren&gt; ] | REFERENCES [ &lt;left paren&gt; &lt;privilege column
+    list&gt; &lt;right paren&gt; ] | USAGE | TRIGGER |
+    EXECUTE</code>
+</p>
+<p>
+<code class="literal">&lt;privilege column list&gt; ::= &lt;column name
+    list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;grantee&gt; ::= PUBLIC | &lt;authorization
+    identifier&gt;</code>
+</p>
+<p>The <code class="literal">&lt;object privileges&gt;</code> that can be used
+    depend on the type of the <code class="literal">&lt;object name&gt;</code>. These
+    are discussed in the previous section. For a table, if
+    <code class="literal">&lt;privilege column list&gt;</code> is not specified, then
+    the privilege is granted on the table, which includes all of its columns
+    and any column that may be added to it in the future. For routines, the
+    name of the routine can be specified in two ways, either as the generic
+    name as the specific name. HyperSQL allows referencing all overloaded
+    versions of a routine at the same time, using its name. This differs from
+    the SQL Standard which requires the use of <code class="literal">&lt;specific routine
+    designator&gt;</code> to grant privileges separately on each different
+    signature of the routine.</p>
+<p>Each <code class="literal">&lt;grantee&gt;</code> is the name of a role or
+    a user. Examples of GRANT statement are given below:</p>
+<div class="informalexample">
+<pre class="programlisting">GRANT ALL ON SEQUENCE aSequence TO roleOrUser 
+GRANT SELELCT ON aTable TO roleOrUser  
+GRANT SELECT, UPDATE ON aTABLE TO roleOrUser1, roleOrUser2
+GRANT SELECT(columnA, columnB), UPDATE(columnA, columnB) ON TABLE aTable TO roleOrUser
+GRANT EXECUTE ON SPECIFIC ROUTINE aroutine_1234 TO rolOrUser
+</pre>
+</div>
+<p>As mentioned in the general discussion, it is better to define a
+    role for the collection of all the privileges required by an application.
+    This role is then granted to any user. If further changes are made to the
+    privileges of this role, they are automatically reflected in all the users
+    that have the role.</p>
+<a name="N1192F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>GRANT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>grant role statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;grant role statement&gt; ::= GRANT &lt;role name&gt;
+    [ { &lt;comma&gt; &lt;role name&gt; }... ] TO &lt;grantee&gt; [ {
+    &lt;comma&gt; &lt;grantee&gt; }... ] [ WITH ADMIN OPTION ] [ GRANTED BY
+    &lt;grantor&gt; ]</code>
+</p>
+<p>Assign roles to roles or users. One or more roles can be assigned
+    to one or more <code class="literal">&lt;grantee&gt;</code> objects. A
+    <code class="literal">&lt;grantee&gt;</code> is a user or a role. If the <code class="literal">[
+    WITH ADMIN OPTION ]</code> is specified, then each
+    <code class="literal">&lt;grantee&gt;</code> can grant the newly assigned roles to
+    other grantees. An example of user and role creation with grants is given
+    below:</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE USER appuser
+CREATE ROLE approle
+GRANT approle TO appuser
+GRANT SELECT, UPDATE ON TABLE atable TO approle
+GRANT USAGE ON SEQUENCE asequence to approle
+GRANT EXECUTE ON ROUTINE aroutine TO approle
+</pre>
+</div>
+<a name="N1194F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REVOKE privilege</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>revoke statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;revoke privilege statement&gt; ::= REVOKE [ GRANT
+    OPTION FOR ] &lt;privileges&gt; FROM &lt;grantee&gt; [ { &lt;comma&gt;
+    &lt;grantee&gt; }... ] [ GRANTED BY &lt;grantor&gt; ] RESTRICT |
+    CASCADE</code>
+</p>
+<p>Revoke privileges from a user or role.</p>
+<a name="N11960" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REVOKE role</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>revoke role statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;revoke role statement&gt; ::= REVOKE [ ADMIN OPTION
+    FOR ] &lt;role revoked&gt; [ { &lt;comma&gt; &lt;role revoked&gt; }... ]
+    FROM &lt;grantee&gt; [ { &lt;comma&gt; &lt;grantee&gt; }... ] [ GRANTED BY
+    &lt;grantor&gt; ] RESTRICT | CASCADE</code>
+</p>
+<p>
+<code class="literal">&lt;role revoked&gt; ::= &lt;role
+    name&gt;</code>
+</p>
+<p>Revoke a role from users or roles.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="texttables-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="dataaccess-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;5.&nbsp;Text Tables&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;7.&nbsp;Data Access and Change</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/apd.html b/doc/guide/apd.html
new file mode 100644
index 0000000..251d610
--- /dev/null
+++ b/doc/guide/apd.html
@@ -0,0 +1,343 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Appendix&nbsp;D.&nbsp;HyperSQL File Links</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="openoffice-app.html" title="Appendix&nbsp;C.&nbsp;HyperSQL with OpenOffice.org">
+<link rel="next" href="sql-ind.html" title="SQL Index">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="openoffice-app.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Appendix&nbsp;D.&nbsp;HyperSQL File Links</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="sql-ind.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Appendix&nbsp;C.&nbsp;HyperSQL with OpenOffice.org&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;SQL Index</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="N147E4"></a>HyperSQL File Links</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>HyperSQL Files referred to in this Guide</i>
+</h3>
+</div>
+</div>
+</div>
+<p>
+    HyperSQL files referred to in the text may be retrieved from the
+    canonical HyperSQL documentation site, http://hsqldb.org/doc/2.0, or from the
+    same location you are reading this page from.
+  </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+    If you are reading this document with a standalone PDF reader,
+    only the http://hsqldb.org/doc/2.0/... links will function.
+  </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="itemizedlist">
+<p class="title">
+<b>
+      Pairs of local + http://hsqldb.org/doc/2.0 links for referenced files.
+    </b>
+</p>
+<ul type="disc">
+<li>
+<a name="JDBCConnection.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCConnection.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCConnection.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCConnection.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCConnection.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCDriver.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCDriver.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCDriver.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCDriver.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCDriver.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCDatabaseMetaData.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCResultSet.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCResultSet.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCResultSet.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCResultSet.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCResultSet.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCStatement.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCStatement.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCStatement.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCStatement.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCStatement.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCPreparedStatement.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html</a>
+      
+</p>
+</li>
+<li>
+<a name="MainInvoker.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/util/MainInvoker.html" target="_top">../apidocs/org/hsqldb/util/MainInvoker.html</a>
+      
+</p>
+<p>
+      
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/util/MainInvoker.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/util/MainInvoker.html</a>
+      
+</p>
+</li>
+<li>
+<a name="javadoc-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/index.html" target="_top">../apidocs/index.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/" target="_top">http://hsqldb.org/doc/2.0/apidocs/</a>
+      
+</p>
+</li>
+<li>
+<a name="Servlet.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/server/Servlet.java" target="_top">../verbatim/src/org/hsqldb/server/Servlet.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/server/Servlet.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/server/Servlet.java</a>
+      
+</p>
+</li>
+<li>
+<a name="Tokens.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/Tokens.java" target="_top">../verbatim/src/org/hsqldb/Tokens.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/Tokens.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/Tokens.java</a>
+      
+</p>
+</li>
+<li>
+<a name="WebServer.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/server/WebServer.java" target="_top">../verbatim/src/org/hsqldb/server/WebServer.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/server/WebServer.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/server/WebServer.java</a>
+      
+</p>
+</li>
+<li>
+<a name="TestBase.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/test/TestBase.java" target="_top">../verbatim/src/org/hsqldb/test/TestBase.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/test/TestBase.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/test/TestBase.java</a>
+      
+</p>
+</li>
+<li>
+<a name="Trigger.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/Trigger.java" target="_top">../verbatim/src/org/hsqldb/Trigger.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/Trigger.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/Trigger.java</a>
+      
+</p>
+</li>
+<li>
+<a name="TriggerSample.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/sample/TriggerSample.java" target="_top">../verbatim/src/org/hsqldb/sample/TriggerSample.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/test/sample/TriggerSample.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/test/sample/TriggerSample.java</a>
+      
+</p>
+</li>
+<li>
+<a name="MainInvoker.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/util/MainInvoker.java" target="_top">../verbatim/src/org/hsqldb/util/MainInvoker.java</a>
+      
+</p>
+<p>
+      
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/util/MainInvoker.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/util/MainInvoker.java</a>
+      
+</p>
+</li>
+<li>
+<a name="hsqldb.cfg-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/hsqldb.cfg" target="_top">../verbatim/sample/hsqldb.cfg</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/hsqldb.cfg" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/hsqldb.cfg</a>
+      
+</p>
+</li>
+<li>
+<a name="acl.txt-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/acl.txt" target="_top">../verbatim/sample/acl.txt</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/acl.txt" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/acl.txt</a>
+      
+</p>
+</li>
+<li>
+<a name="server.properties-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/server.properties" target="_top">../verbatim/sample/server.properties</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/server.properties" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/server.properties</a>
+      
+</p>
+</li>
+<li>
+<a name="sqltool.rc-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/sqltool.rc" target="_top">../verbatim/sample/sqltool.rc</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/sqltool.rc" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/sqltool.rc</a>
+      
+</p>
+</li>
+<li>
+<a name="hsqldb.init-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/hsqldb.init" target="_top">../verbatim/sample/hsqldb.init</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/hsqldb.init" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/hsqldb.init</a>
+      
+</p>
+</li>
+</ul>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="openoffice-app.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="sql-ind.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Appendix&nbsp;C.&nbsp;HyperSQL with OpenOffice.org&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;SQL Index</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/book-ind.html b/doc/guide/book-ind.html
new file mode 100644
index 0000000..e333759
--- /dev/null
+++ b/doc/guide/book-ind.html
@@ -0,0 +1,888 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>General Index</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="sql-ind.html" title="SQL Index">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="sql-ind.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">General Index</td><td align="right" width="30%">&nbsp;</td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">SQL Index&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="index">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="book-ind"></a>General Index</h2>
+</div>
+</div>
+</div>
+<div class="index">
+<div class="indexdiv">
+<h3>Symbols</h3>
+<dl>
+<dt>_SYSTEM ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>A</h3>
+<dl>
+<dt>ABS function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ACL, <a class="indexterm" href="listeners-chapt.html#listeners_acl-sect">Network Access Control</a>
+</dt>
+<dt>ACOS function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ADD COLUMN, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ADD CONSTRAINT, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ADD DOMAIN CONSTRAINT, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>aggregate function, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>ALL and ANY predicates, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>ALTER COLUMN, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>alter column nullability, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER DOMAIN, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>alter identity column, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER routine, <a class="indexterm" href="databaseobjects-chapt.html#N1124D">Routine Creation</a>
+</dt>
+<dt>ALTER SEQUENCE, <a class="indexterm" href="databaseobjects-chapt.html#N112F5">Sequence Creation</a>
+</dt>
+<dt>ALTER TABLE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER USER ... SET INITIAL SCHEMA, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>ALTER USER ... SET PASSWORD, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>ALTER view, <a class="indexterm" href="databaseobjects-chapt.html#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>Ant, <a class="indexterm" href="building-app.html#building-ant-sect">Building with Apache Ant</a>
+</dt>
+<dt>ASCII function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>ASIN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ATAN2 function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ATAN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>AUTHORIZATION IDENTIFIER, <a class="indexterm" href="accesscontrol-chapt.html#N11752">Authorizations and Access Control</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>B</h3>
+<dl>
+<dt>backup, <a class="indexterm" href="deployment-chapt.html#deployment_backup-sect">Backing Up Database Catalogs</a>
+</dt>
+<dt>BACKUP DATABASE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>BETWEEN predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>binary literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>BINARY types, <a class="indexterm" href="sqlgeneral-chapt.html#N104D7">Binary String Types</a>
+</dt>
+<dt>BIT_LENGTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>BITAND function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>bit literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>BITOR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>BIT types, <a class="indexterm" href="sqlgeneral-chapt.html#N104F5">Bit String Types</a>
+</dt>
+<dt>BITXOR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>boolean literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>BOOLEAN types, <a class="indexterm" href="sqlgeneral-chapt.html#N10482">Boolean Type</a>
+</dt>
+<dt>boolean value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>C</h3>
+<dl>
+<dt>CARDINALITY function, <a class="indexterm" href="builtinfunctions-chapt.html#N132C8">Array Functions</a>
+</dt>
+<dt>CASCADE or RESTRICT, <a class="indexterm" href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>case expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>CASE WHEN in routines, <a class="indexterm" href="sqlroutines-chapt.html#N12699">Conditional Statements</a>
+</dt>
+<dt>CAST, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>CEIL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>CHANGE_AUTHORIZATION, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>CHARACTER_LENGTH, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>character literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>CHARACTER types, <a class="indexterm" href="sqlgeneral-chapt.html#N104A8">Character String Types</a>
+</dt>
+<dt>character value function, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>CHECK constraint, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CHECKPOINT, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>COALESCE expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>COALESCE function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>COLLATE, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>column definition, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>column reference, <a class="indexterm" href="dataaccess-chapt.html#N11B9C">References, etc.</a>
+</dt>
+<dt>COMMENT, <a class="indexterm" href="databaseobjects-chapt.html#N10D01">Commenting Objects</a>
+</dt>
+<dt>COMMIT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>comparison predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>CONCAT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>CONSTRAINT, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>CONSTRAINT (table constraint), <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CONSTRAINT name and characteristics, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>contextually typed value specification, <a class="indexterm" href="dataaccess-chapt.html#N11B9C">References, etc.</a>
+</dt>
+<dt>CONVERT function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>COS function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>COT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>CREATE_SCHEMA ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>CREATE AGGREGATE FUNCTION, <a class="indexterm" href="sqlroutines-chapt.html#N12802">Definition of Aggregate Functions</a>
+</dt>
+<dt>CREATE ASSERTION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE CAST, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE CHARACTER SET, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE COLLATION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE DOMAIN, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>CREATE FUNCTION, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>CREATE INDEX, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE PROCEDURE, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>CREATE ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>CREATE SCHEMA, <a class="indexterm" href="databaseobjects-chapt.html#N10D1D">Schema Creation</a>
+</dt>
+<dt>CREATE SEQUENCE, <a class="indexterm" href="databaseobjects-chapt.html#N112F5">Sequence Creation</a>
+</dt>
+<dt>CREATE TABLE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CREATE TRANSLATION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE TRIGGER, <a class="indexterm" href="databaseobjects-chapt.html#N111D1">Trigger Creation</a>, <a class="indexterm" href="triggers-chapt.html#N12A85">Trigger Creation</a>
+</dt>
+<dt>CREATE TYPE, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE USER, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>CREATE VIEW, <a class="indexterm" href="databaseobjects-chapt.html#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>CROSS JOIN, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>CRYPT_KEY, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>CRYPT_KEY function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURDATE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_CATALOG function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_DATE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_ROLE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_SCHEMA function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_TIME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_TIMESTAMP function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_USER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURTIME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>D</h3>
+<dl>
+<dt>DATABASE_ISOLATION_LEVEL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATABASE_TIMEZONE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DATABASE_VERSION function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATABASE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATEADD function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DATEDIFF function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>datetime and interval literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>Datetime Operations, <a class="indexterm" href="sqlgeneral-chapt.html#N10544">Datetime types</a>
+</dt>
+<dt>DATETIME types, <a class="indexterm" href="sqlgeneral-chapt.html#N10544">Datetime types</a>
+</dt>
+<dt>datetime value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>datetime value function, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>DAYNAME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFMONTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFWEEK function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFYEAR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DBA ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>DECODE function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>DEFAULT clause, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DEGREES function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>DELETE FROM, <a class="indexterm" href="dataaccess-chapt.html#N123DD">Delete Statement</a>
+</dt>
+<dt>DETERMINISTIC characteristic, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>DIFFERENCE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>DISCONNECT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>DROP ASSERTION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP CAST, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP CHARACTER SET, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP COLLATION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP COLUMN, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP CONSTRAINT, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP DEFAULT (table), <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN CONSTRAINT, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN DEFAULT, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP INDEX, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>DROP routine, <a class="indexterm" href="databaseobjects-chapt.html#N1124D">Routine Creation</a>
+</dt>
+<dt>DROP SCHEMA, <a class="indexterm" href="databaseobjects-chapt.html#N10D1D">Schema Creation</a>
+</dt>
+<dt>DROP SEQUENCE, <a class="indexterm" href="databaseobjects-chapt.html#N112F5">Sequence Creation</a>
+</dt>
+<dt>DROP TABLE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP TRANSLATION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP TRIGGER, <a class="indexterm" href="databaseobjects-chapt.html#N111D1">Trigger Creation</a>, <a class="indexterm" href="triggers-chapt.html#N12A85">Trigger Creation</a>
+</dt>
+<dt>DROP USER, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>DROP VIEW, <a class="indexterm" href="databaseobjects-chapt.html#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>DYNAMIC RESULT SETS, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>E</h3>
+<dl>
+<dt>EXISTS predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>EXP function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>EXTERNAL NAME, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>EXTRACT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>F</h3>
+<dl>
+<dt>FLOOR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>FOREIGN KEY constraint, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>G</h3>
+<dl>
+<dt>GRANTED BY, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GRANT privilege, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GRANT role, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GREATEST function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>GROUPING OPERATIONS, <a class="indexterm" href="dataaccess-chapt.html#N12338">Grouping Operations</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>H</h3>
+<dl>
+<dt>HEXTORAW function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>HOUR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>I</h3>
+<dl>
+<dt>identifier chain, <a class="indexterm" href="dataaccess-chapt.html#N11B9C">References, etc.</a>
+</dt>
+<dt>identifier definition, <a class="indexterm" href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a>, <a class="indexterm" href="accesscontrol-chapt.html#N11712">Overview</a>
+</dt>
+<dt>IDENTITY function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>IF EXISTS, <a class="indexterm" href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>IFNULL function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>IF STATEMENT, <a class="indexterm" href="sqlroutines-chapt.html#N12699">Conditional Statements</a>
+</dt>
+<dt>init script, <a class="indexterm" href="unix-chapt.html#unix_daemon-sect">Running Hsqldb as a System Daemon</a>
+</dt>
+<dt>IN predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>INSERT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>INSERT INTO, <a class="indexterm" href="dataaccess-chapt.html#N1241F">Insert Statement</a>
+</dt>
+<dt>interval absolute value function, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>interval term, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>INTERVAL types, <a class="indexterm" href="sqlgeneral-chapt.html#N1063D">Interval Types</a>
+</dt>
+<dt>ISAUTOCOMMIT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>IS DISTINCT predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>IS NULL predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>ISOLATION_LEVEL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYDATABASEFILES function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYDATABASE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYSESSION function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>J</h3>
+<dl>
+<dt>JOIN USING, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>JOIN with condition, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>L</h3>
+<dl>
+<dt>LANGUAGE, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>LCASE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LEAST function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>LEFT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LENGTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LIKE predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>LN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LOCALTIME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>LOCALTIMESTAMP function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>LOCATE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LOCK TABLE, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>LOG10 function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LOG function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LTRIM function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>M</h3>
+<dl>
+<dt>MATCH predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>MAX_CARDINALITY function, <a class="indexterm" href="builtinfunctions-chapt.html#N132C8">Array Functions</a>
+</dt>
+<dt>memory use, <a class="indexterm" href="deployment-chapt.html#deployment_mem_disk-sect">Memory and Disk Use</a>
+</dt>
+<dt>MERGE INTO, <a class="indexterm" href="dataaccess-chapt.html#N124B8">Merge Statement</a>
+</dt>
+<dt>MINUTE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>MOD function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>MONTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>MONTHNAME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>N</h3>
+<dl>
+<dt>name resolution, <a class="indexterm" href="dataaccess-chapt.html#N122F6">Naming</a>
+</dt>
+<dt>naming in joined table, <a class="indexterm" href="dataaccess-chapt.html#N122F6">Naming</a>
+</dt>
+<dt>naming in select list, <a class="indexterm" href="dataaccess-chapt.html#N122F6">Naming</a>
+</dt>
+<dt>NATURAL JOIN, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>NEXT VALUE FOR, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>NOW function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>NULLIF expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>NULLIF function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>NULL INPUT, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>numeric literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>NUMERIC types, <a class="indexterm" href="sqlgeneral-chapt.html#N103BA">Numeric Types</a>
+</dt>
+<dt>numeric value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>numeric value function, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>NVL function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>O</h3>
+<dl>
+<dt>OCTET_LENGTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>OTHER type, <a class="indexterm" href="sqlgeneral-chapt.html#N1050A">Storage and Handling of Java Objects</a>
+</dt>
+<dt>OUTER JOIN, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>OVERLAPS predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>OVERLAY function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>P</h3>
+<dl>
+<dt>PATH, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>PI function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>POSITION function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>POWER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>PRIMARY KEY constraint, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>PUBLIC ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>Q</h3>
+<dl>
+<dt>QUARTER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>R</h3>
+<dl>
+<dt>RADIANS function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>RAND function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>RAWTOHEX function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REGEXP_MATCHES function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>RELEASE SAVEPOINT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>RENAME, <a class="indexterm" href="databaseobjects-chapt.html#N10CE1">Renaming Objects</a>
+</dt>
+<dt>REPEAT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REPLACE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>RETURN, <a class="indexterm" href="sqlroutines-chapt.html#N126E2">Return Statement</a>
+</dt>
+<dt>RETURNS, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>REVERSE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REVOKE, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>REVOKE ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>RIGHT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>ROLLBACK, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>ROLLBACK TO SAVEPOINT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>ROUND function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>routine body, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>routine invocation, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>row value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>RTRIM function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>S</h3>
+<dl>
+<dt>SA USER, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>SAVEPOINT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SAVEPOINT LEVEL, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>schema routine, <a class="indexterm" href="databaseobjects-chapt.html#N1124D">Routine Creation</a>
+</dt>
+<dt>SCRIPT, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>search condition, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>SECOND function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SECONDS_SINCE_MIDNIGHT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>security, <a class="indexterm" href="running-chapt.html#running_security-sect">Security Considerations</a>, <a class="indexterm" href="listeners-chapt.html#listeners_tls-sect">TLS Encryption</a>, <a class="indexterm" href="listeners-chapt.html#listeners_acl-sect">Network Access Control</a>
+</dt>
+<dt>SELECT : SINGLE ROW, <a class="indexterm" href="sqlroutines-chapt.html#N12648">Select Statement : Single Row</a>
+</dt>
+<dt>SESSION_ISOLATION_LEVEL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>SESSION_TIMEZONE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SESSION_USER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>SET AUTOCOMMIT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET CATALOG, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>set clause in UPDATE and MERGE statements, <a class="indexterm" href="dataaccess-chapt.html#N1246A">Update Statement</a>
+</dt>
+<dt>SET CONSTRAINTS, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET DATABASE COLLATION, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE DEFAULT INITIAL SCHEMA, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET DATABASE DEFAULT RESULT MEMORY ROWS, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE DEFAULT TABLE TYPE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE EVENT LOG LEVEL, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE GC, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL NAMES, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL REFERENCES, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL SIZE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE TRANSACTION CONTROL, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE UNIQUE NAME*, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATA TYPE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET DEFAULT, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET DOMAIN DEFAULT, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>SET FILES BACKUP INCREMENT, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES CACHE ROWS, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES CACHE SIZE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES DEFRAG, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOB SCALE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOG, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOG SIZE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES NIO, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES SCALE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES WRITE DELAY, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>set function specification, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>SET IGNORECASE, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET INITIAL SCHEMA*, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET MAXROWS, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET OPERATIONS, <a class="indexterm" href="dataaccess-chapt.html#N1234D">Set Operations</a>
+</dt>
+<dt>SET PASSWORD, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET PATH, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET REFERENTIAL INTEGRITY, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET ROLE, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SCHEMA, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION AUTHORIZATION, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION CHARACTERISTICS, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION RESULT MEMORY ROWS, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET TABLE read-write property, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE HEADER, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE on-off, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TIME ZONE, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET TRANSACTION, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SHUTDOWN, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SIGN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>SIN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>sort specification list, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>SOUNDEX function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SPACE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SPECIFIC, <a class="indexterm" href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>SPECIFIC NAME, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>SQL DATA access characteristic, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>SQL parameter reference, <a class="indexterm" href="dataaccess-chapt.html#N11B9C">References, etc.</a>
+</dt>
+<dt>SQL procedure statement, <a class="indexterm" href="databaseobjects-chapt.html#N1137F">SQL Procedure Statement</a>
+</dt>
+<dt>SQL routine body, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>SQRT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>START TRANSACTION, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>string value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>SUBSTR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SUBSTRING function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SYSTEM_USER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>T</h3>
+<dl>
+<dt>TAN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>TIMESTAMPADD function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TIMESTAMPDIFF function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>Time Zone, <a class="indexterm" href="sqlgeneral-chapt.html#N10544">Datetime types</a>
+</dt>
+<dt>TIMEZONE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TO_CHAR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TRANSACTION_CONTROL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>transaction characteristics, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>TRIGGERED SQL STATEMENT, <a class="indexterm" href="triggers-chapt.html#N12A85">Trigger Creation</a>
+</dt>
+<dt>TRIGGER EXECUTION ORDER, <a class="indexterm" href="triggers-chapt.html#N12A85">Trigger Creation</a>
+</dt>
+<dt>TRIM_ARRAY function, <a class="indexterm" href="builtinfunctions-chapt.html#N132C8">Array Functions</a>
+</dt>
+<dt>TRIM function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>TRUNCATE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>TRUNCATE TABLE, <a class="indexterm" href="dataaccess-chapt.html#N123FD">Truncate Statement</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>U</h3>
+<dl>
+<dt>UCASE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>unicode escape elements, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>UNION JOIN, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>UNIQUE constraint, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>UNIQUE predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>UPDATE, <a class="indexterm" href="dataaccess-chapt.html#N1246A">Update Statement</a>
+</dt>
+<dt>upgrading, <a class="indexterm" href="deployment-chapt.html#deployment_upgrade-sect">Upgrading Databases</a>
+</dt>
+<dt>USER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>V</h3>
+<dl>
+<dt>value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>value expression primary, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>value specification, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>W</h3>
+<dl>
+<dt>WEEK function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>Y</h3>
+<dl>
+<dt>YEAR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="sql-ind.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;</td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">SQL Index&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/book-pref.html b/doc/guide/book-pref.html
new file mode 100644
index 0000000..26dcc67
--- /dev/null
+++ b/doc/guide/book-pref.html
@@ -0,0 +1,158 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Preface</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="index.html" title="HyperSQL User Guide">
+<link rel="next" href="running-chapt.html" title="Chapter&nbsp;1.&nbsp;Running and Using HyperSQL">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="index.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Preface</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="running-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">HyperSQL User Guide&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;1.&nbsp;Running and Using HyperSQL</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="preface" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="book-pref"></a>Preface</h2>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="book-pref.html#altformats-sect">Available formats for this document</a></span>
+</dt>
+</dl>
+</div>
+<p>HSQLDB (HyperSQL DataBase) is a modern relational database manager
+    that conforms closely to the SQL:2008 Standard and JDBC 4 specifications.
+    It supports all core features and many of the optional features of
+    SQL:2008.</p>
+<p>The first versions of HSQLDB were released in 2001. Version 2.0,
+    first released in 2010, includes a complete rewrite of most parts of the
+    database engine.</p>
+<p>This documentation covers HyperSQL version 2.0. This documentation
+    is regularly improved and undated. The latest, updated version can be
+    found at http://hsqldb.org/doc/2.0/</p>
+<p>If you notice any mistakes in this document, or if you have problems
+    with the procedures themselves, please use the HSQLDB support facilities
+    which are listed at http://hsqldb.org/support</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="altformats-sect"></a>Available formats for this document</h2>
+</div>
+</div>
+</div>
+<p>This document is available in several formats.</p>
+<p>
+      You may be reading this document right now at http://hsqldb.org/doc/2.0, or in
+      a distribution somewhere else.
+      I hereby call the document distribution from which you are reading 
+      this, your <span class="emphasis"><em>current distro</em></span>.
+  </p>
+<p>
+      http://hsqldb.org/doc/2.0 hosts the latest production versions of all available formats.
+      If you want a different format of the same <span class="emphasis"><em>version</em></span>
+      of the document you are reading now, then you should try your
+      current distro.
+      If you want the latest production version, you should try http://hsqldb.org/doc/2.0.
+  </p>
+<p>
+      Sometimes, distributions other than http://hsqldb.org/doc/2.0 do not host all
+      available formats.
+      So, if you can't access the format that you want in your current
+      distro, you have no choice but to use the newest production version at 
+      http://hsqldb.org/doc/2.0.
+  </p>
+<p>
+    
+<div class="table">
+<a name="altformats-tbl"></a>
+<p class="title">
+<b>Table&nbsp;1.&nbsp;Available formats of this document</b>
+</p>
+<div class="table-contents">
+<table summary="Available formats of this document" cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">format</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">your distro</th><th style="border-bottom: 0.5pt solid ; " align="left">at http://hsqldb.org/doc/2.0</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              Chunked HTML
+          </td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              <a class="link" href="index.html" target="_top">index.html</a>
+          </td><td style="border-bottom: 0.5pt solid ; " align="left">
+          <a class="link" href="http://hsqldb.org/doc/2.0/guide/" target="_top">http://hsqldb.org/doc/2.0/guide/</a>
+          </td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              All-in-one HTML
+          </td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              <a class="link" href="guide.html" target="_top">guide.html</a>
+          </td><td style="border-bottom: 0.5pt solid ; " align="left">
+        <a class="link" href="http://hsqldb.org/doc/2.0/guide/guide.html" target="_top">http://hsqldb.org/doc/2.0/guide/guide.html</a>
+          </td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left">
+              PDF
+          </td><td style="border-right: 0.5pt solid ; " align="left">
+              <a class="link" href="guide.pdf" target="_top">guide.pdf</a>
+          </td><td style="" align="left">
+          <a class="link" href="http://hsqldb.org/doc/2.0/guide/guide.pdf" target="_top">http://hsqldb.org/doc/2.0/guide/guide.pdf</a>
+          </td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+    If you are reading this document now with a standalone PDF reader, the
+    <span class="guilabel">your distro</span> links may not work.
+  </p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="index.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="running-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">HyperSQL User Guide&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;1.&nbsp;Running and Using HyperSQL</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/building-app.html b/doc/guide/building-app.html
new file mode 100644
index 0000000..8cdd929
--- /dev/null
+++ b/doc/guide/building-app.html
@@ -0,0 +1,458 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Appendix&nbsp;B.&nbsp;Building HyperSQL Jars</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HSQLDB, HyperSQL, Building, Ant">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="lists-app.html" title="Appendix&nbsp;A.&nbsp;Lists of Keywords">
+<link rel="next" href="openoffice-app.html" title="Appendix&nbsp;C.&nbsp;HyperSQL with OpenOffice.org">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="lists-app.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Appendix&nbsp;B.&nbsp;Building HyperSQL Jars</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="openoffice-app.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Appendix&nbsp;A.&nbsp;Lists of Keywords&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Appendix&nbsp;C.&nbsp;HyperSQL with OpenOffice.org</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="building-app"></a>Building HyperSQL Jars</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>How to build customized or specialized jar files</i>
+</h3>
+</div>
+<div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3556 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-03-26 19:09:40 -0400 (Fri, 26 Mar 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="building-app.html#N14693">Purpose</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#building-ant-sect">Building with Ant</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="building-app.html#N146AA">Obtaining Ant</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#N146C0">Building Hsqldb with Ant</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#N1475D">Building for Older JDKs</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="building-app.html#N14765">Building with IDE's</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#N1476A">Hsqldb CodeSwitcher</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#N14791">Building documentation</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14693"></a>Purpose</h2>
+</div>
+</div>
+</div>
+<p>From 2.0, the supplied <code class="filename">hsqldb.jar</code> file is
+    built with Java 1.6. If you want to run with a 1.5 or older JVM, or if you
+    want to use an alternative jar (<code class="filename">hsqldb-min.jar</code>, etc.)
+    you must build the desired jar with a Java JDK and Ant version
+    1.7.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="building-ant-sect"></a>Building with Apache Ant</h2>
+</div>
+</div>
+</div>
+<a name="N146A4" class="indexterm"></a>
+<p>You should use version 1.7.x of Ant (Another Neat Tool) to do
+    builds with HyperSQL.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N146AA"></a>Obtaining Ant</h3>
+</div>
+</div>
+</div>
+<p>Ant is a part of the Jakarta/Apache Project.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<a class="link" href="http://ant.apache.org" target="_top">Home of the Apache
+          Ant project</a>
+</li>
+<li>The <a class="link" href="http://ant.apache.org/manual/install.html#installing" target="_top">
+          Installing Ant</a> page of the <a class="link" href="http://ant.apache.org/manual" target="_top">Ant Manual</a>. Follow
+          the directions for your platform.</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N146C0"></a>Building Hsqldb with Ant</h3>
+</div>
+</div>
+</div>
+<p>Once you have unpacked the zip package for hsqldb, under the
+      <code class="filename">/hsqldb</code> folder, in <code class="filename">/build</code>
+      there is a <code class="filename">build.xml</code> file that builds the
+      <code class="filename">hsqldb.jar</code> with Ant (Ant must be already
+      installed). To use it, change to <code class="filename">/build</code> then
+      type:</p>
+<div class="informalexample">
+<pre class="screen"> ant -projecthelp</pre>
+</div>
+<p>This displays the available ant targets, which you can supply
+      as command line arguments to ant. These include</p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">hsqldb</span>
+</p>
+</td><td>to build the <code class="filename">hsqldb.jar</code>
+            file</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">explainjars</span>
+</p>
+</td><td>Lists all targets which build jar files, with an
+            explanation of the purposes of the different jars.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">clean</span>
+</p>
+</td><td>to clean up the /classes directory that is
+            created</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">clean-all</span>
+</p>
+</td><td>to remove the old jar and doc files as well</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">javadoc</span>
+</p>
+</td><td>to build javadoc</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">hsqldbmain</span>
+</p>
+</td><td>to build a smaller jar for HSQLDB that does not contain
+            utilities</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">hsqljdbc</span>
+</p>
+</td><td>to build an extremely small jar containing only the
+            client-side JDBC driver (can connect only to a HyperSQL
+            Server).</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">hsqldbmin</span>
+</p>
+</td><td>to build a small jar that supports
+            <span class="emphasis"><em>in-process</em></span> catalogs, but neither running nor
+            connecting to HyperSQL Servers.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">sqltool</span>
+</p>
+</td><td>to build sqltool.jar, which contains only the SqlTool
+            classes.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">...</span>
+</p>
+</td><td>Many more targets are available. Run <code class="literal">ant
+            -p</code> and <code class="literal">ant explainjars</code>.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>HSQLDB can be built in any combination of two JRE (Java Runtime
+      Environment) versions and many jar file sizes.</p>
+<p>A jar built with an older JRE is compatible for use with a
+      newer JRE (you can compile with Java 1.5 and run with 1.6). But the
+      newer JDBC capabilities of the JRE will be not be available.</p>
+<p>The client jar (<code class="filename">hsqljdbc.jar</code>) contains
+      only the HSQLDB JDBC Driver client. The smallest engine jar
+      (<code class="filename">hsqldbmin.jar</code>) contains the engine and the HSQLDB
+      JDBC Driver client. The default size (<code class="filename">hsqldb.jar</code>)
+      also contains server mode support and the utilities. The largest size
+      (<code class="filename">hsqldbtest.jar</code>)includes some test classes as well.
+      Before building the <code class="filename">hsqldbtest.jar</code> package, you
+      should download the junit jar from <a class="link" href="http://www.junit.org" target="_top">http://www.junit.org</a> and put it in the
+      <code class="filename">/lib</code> directory, alongside
+      <code class="filename">servlet.jar</code>, which is included in the .zip
+      package.</p>
+<p>If you want your code built for high performance, as opposed to
+      debugging (in the same way that we make our production distributions),
+      make a file named <code class="filename">build.properties</code> in your build
+      directory with the contents <div class="informalexample">
+<pre class="screen">build.debug: false</pre>
+</div>The resulting Java binaries will be faster and
+      smaller, at the cost of exception stack traces not identifying source
+      code locations (which can be extremely useful for debugging).</p>
+<p>After installing Ant on your system use the following command
+      from the <code class="filename">/build</code> directory. Just run <code class="literal">ant
+      explainjars</code> for a concise list of all available jar
+      files.</p>
+<div class="informalexample">
+<pre class="screen">ant explainjars</pre>
+</div>
+<p>The command displays a list of different options for building
+      different sizes of the HSQLDB Jar. The default is built using:</p>
+<div class="example">
+<a name="N14756"></a>
+<p class="title">
+<b>Example&nbsp;B.1.&nbsp;Buiding the standard Hsqldb jar file with Ant</b>
+</p>
+<div class="example-contents">
+<pre class="screen">ant hsqldb</pre>
+</div>
+</div>
+<br class="example-break">
+<p>The Ant method always builds a jar with the JDK that is used by
+      Ant and specified in its JAVA_HOME environment variable.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1475D"></a>Building for Older JDKs</h3>
+</div>
+</div>
+</div>
+<p>HyperSQL version 2.0 cannot be directly compiled or used with JDK
+      1.4. It may be possible to use the RetroTranslator tool to achieve this.
+      The suggested procedure is as follows: First use Ant with JDK 1.5 and
+      build the jar. Then translate the jar using RetroTranslator with
+      backport (which bundles replacement classes for concurrency control).
+      This translation should cover the concurrency features that are specific
+      to version 1.5 and later.<div class="informalexample">
+<pre class="screen">ant switchtojdk14
+ant hsqldb
+-- translate the jar
+</pre>
+</div>
+</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14765"></a>Building with IDE's</h2>
+</div>
+</div>
+</div>
+<p>All HyperSQL source files are supplied ready to compile. There is
+    no complex pre-compile stage. It is therefore possible to compile the
+    sources with an IDE, without using ant. Only if compilation with Java 1.5
+    is required, you should first run the Ant code switcher task before
+    compiling and remove from the source directories a few source files that
+    are specific to Java 6 (these are listed in the build.xml file).</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1476A"></a>Hsqldb CodeSwitcher</h2>
+</div>
+</div>
+</div>
+<p>CodeSwitcher is a tool to manage different version of Java source
+    code. It allows to compile HyperSQL for different JDKs. It is something
+    like a precompiler in C but it works directly on the source code and does
+    not create intermediate output or extra files.</p>
+<p>CodeSwitcher is used internally in the Ant build. You do not have
+    to use it separately to compile HyperSQL.</p>
+<p>CodeSwitcher reads the source code of a file, removes comments
+    where appropriate and comments out the blocks that are not used for a
+    particular version of the file. This operation is done for all files of a
+    defined directory, and all subdirectories.</p>
+<div class="example">
+<a name="N14773"></a>
+<p class="title">
+<b>Example&nbsp;B.2.&nbsp;Example source code before CodeSwitcher is run</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">
+        ...
+
+    //#ifdef JAVA2
+
+        properties.store(out,"hsqldb database");
+
+    //#else
+
+    /*
+
+        properties.save(out,"hsqldb database");
+
+    */
+
+    //#endif
+
+        ...</pre>
+</div>
+</div>
+<br class="example-break">
+<p>The next step is to run CodeSwitcher.</p>
+<div class="example">
+<a name="N1477A"></a>
+<p class="title">
+<b>Example&nbsp;B.3.&nbsp;CodeSwitcher command line invocation</b>
+</p>
+<div class="example-contents">
+<pre class="screen">
+    java org.hsqldb.util.CodeSwitcher . -JAVA2</pre>
+</div>
+</div>
+<br class="example-break">
+<p>The '.' means the program works on the current directory (all
+    subdirectories are processed recursively). <code class="literal">-JAVA2</code> means
+    the code labelled with JAVA2 must be switched off.</p>
+<div class="example">
+<a name="N14784"></a>
+<p class="title">
+<b>Example&nbsp;B.4.&nbsp;Source code after CodeSwitcher processing</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">
+        ...
+
+    //#ifdef JAVA2
+
+    /*
+
+        pProperties.store(out,"hsqldb database");
+
+    */
+
+    //#else
+
+        pProperties.save(out,"hsqldb database");
+
+    //#endif
+
+        ...</pre>
+</div>
+</div>
+<br class="example-break">
+<p>For detailed information on the command line options run
+    <code class="classname">java org.hsqldb.util.CodeSwitcher</code>. Usage examples
+    can be found in the build.xml file in the <code class="filename">/build</code>
+    directory.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14791"></a>Building documentation</h2>
+</div>
+</div>
+</div>
+<p>The JavaDoc can be built simply by invoking the javadoc
+    target.</p>
+<p>The two Guides are in DocBook XML source format. To rebuild, run
+    the Ant target <code class="literal">gen-docs</code>. Instructions will be
+    displayed. See the file <code class="filename">doc-src/readme-docauthors.txt</code>
+    for tips.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="lists-app.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="openoffice-app.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Appendix&nbsp;A.&nbsp;Lists of Keywords&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Appendix&nbsp;C.&nbsp;HyperSQL with OpenOffice.org</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/builtinfunctions-chapt.html b/doc/guide/builtinfunctions-chapt.html
new file mode 100644
index 0000000..5a7a179
--- /dev/null
+++ b/doc/guide/builtinfunctions-chapt.html
@@ -0,0 +1,1780 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;10.&nbsp;Built In Functions</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="triggers-chapt.html" title="Chapter&nbsp;9.&nbsp;Triggers">
+<link rel="next" href="deployment-chapt.html" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="triggers-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;10.&nbsp;Built In Functions</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="deployment-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;9.&nbsp;Triggers&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;11.&nbsp;System Management and Deployment
+  Issues</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="builtinfunctions-chapt"></a>Chapter&nbsp;10.&nbsp;Built In Functions</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N12B56"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_intro-sect">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#N132C8">Array Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#N132FD">General Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_intro-sect"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL supports a wide range of built-in functions and allows
+    user-defined functions written in SQL and Java languages. User defined
+    functions are covered in a separate chapter. If a built-in function is not
+    available, you can write your own using SQL. Aggregate functions are
+    discussed in chapters that cover SQL in general.</p>
+<p>The built-in functions fall into three groups:</p>
+<p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>SQL Standard Functions</p>
+<p>A wide rang of functions defined by SQL/Foundation are
+          supported. SQL/Foundation functions that have no parameter are
+          called without empty parentheses. Functions with multiple parameters
+          often use keywords instead of commas to separate the parameters.
+          Many functions are overloaded. Among these, some have one or more
+          optional parameters that can be omitted, while the return type of
+          some functions is dependent upon the type of one of the parameters.
+          The usage of SQL Standard Functions (where they can be used) is
+          covered more extensively in the <a class="link" href="dataaccess-chapt.html" title="Chapter&nbsp;7.&nbsp;Data Access and Change">Data Access and Change</a> chapter</p>
+</li>
+<li>
+<p>JDBC Open Group CLI Functions</p>
+<p>These functions were defined as an extension to the CLI
+          standard, which is the basis for ODBC and JDBC and supported by many
+          database products. JDBC supports an escape mechanism to specify
+          function calls in SQL statements in a manner that is independent of
+          the function names supported by the target database engine. For
+          example <code class="literal">SELECT {fn DAYOFMONTH (dateColumn)} FROM
+          myTable</code> can be used in JDBC and is translated to Standard
+          SQL as <code class="literal">SELECT EXTRACT (DAY_OF_MONTH FROM dateColumn) FROM
+          myTable</code> if a database engine supports the Standard syntax.
+          If a database engine does not support Standard SQL, then the
+          translation will be different. HyperSQL supports all the function
+          names specified in the JDBC specifications as native functions.
+          Therefore, there is no need to use the <code class="literal">{fn FUNC_NAME ( ...
+          ) }</code> escape with HyperSQL. If a JDBC function is supported
+          by the SQL Standard in a different form, the SQL Standard form is
+          the preferred form to use.</p>
+</li>
+<li>
+<p>HyperSQL Built-In Functions</p>
+<p>Several additional built-in functions are available for some
+          useful operations. Some of these functions return the current
+          setting for the session and the database. The General Functions
+          accept arguments of different types and return values based on
+          comparison between the arguments.</p>
+</li>
+</ul>
+</div>
+</p>
+<p>In the BNF specification used here, words in capital letters are
+    actual tokens. Syntactic elements such as expressions are enclosed in
+    angle brackets. The <code class="literal">&lt;left paren&gt;</code> and
+    <code class="literal">&lt;right paren&gt;</code> tokens are represented with the
+    actual symbol. Optional elements are enclosed with square brackets (
+    <code class="literal">&lt;left bracket&gt;</code> and <code class="literal">&lt;right
+    bracket&gt;</code> ). Multiple options for a required element are
+    enclosed with braces (<code class="literal"> &lt;left brace&gt;</code> and
+    <code class="literal">&lt;right brace&gt;</code> )<code class="literal">.</code> Alternative
+    tokens are separated with the vertical bar ( <code class="literal">&lt;vertical
+    bar&gt;</code> ). At the end of each function definition, the standard
+    which specifies the function is noted in parentheses as JDBC or HyperSQL,
+    unless the function is in the SQL/Foundation part of the SQL
+    Standard.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_string-sect"></a>String and Binary String Functions</h2>
+</div>
+</div>
+</div>
+<p>In SQL, there are three kinds of string: character, binary and bit.
+    The units are respectively characters, octets, and bits. Each kind of
+    string can be in different data types. CHAR, VARCHAR and CLOB are the
+    character data types. BINARY, VARBINARY and BLOB are the binary data
+    types. BIT and BIT VARYING are the bit string types. In all string
+    functions, the position of a unit of the string within the whole string is
+    specified from 1 to the length of the whole string. In the BNF,
+    <code class="literal">&lt;char value expr&gt; </code>indicates any valid SQL
+    expression that evaluates to a character type. Likewise,
+    <code class="literal">&lt;binary value expr&gt; </code>indicates a binary type
+    and<code class="literal"> &lt;num value expr&gt; </code>indicates a numeric
+    type.</p>
+<a name="N12BA8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ASCII</strong></span>
+</p>
+<p>
+<code class="literal">ASCII ( &lt;char value expr&gt; )</code>
+</p>
+<p>Returns an INTEGER equal to the ASCII code value of the first
+    character of <code class="literal">&lt;char value expr&gt;</code>. (JDBC)</p>
+<p>
+<code class="literal">CHAR ( &lt;UNICODE code&gt; ) </code>
+</p>
+<p>The argument is an INTEGER. Returns a character string containing a
+    single character that has the specified<code class="literal"> &lt;UNICODE
+    code&gt;</code>, which is an integer. ASCII codes are a subset of the
+    allowed values for <code class="literal">&lt;UNICODE code&gt;</code>. (JDBC)</p>
+<a name="N12BC4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONCAT</strong></span>
+</p>
+<p>
+<code class="literal">CONCAT ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; )</code>
+</p>
+<p>
+<code class="literal">CONCAT ( &lt;binary value expr 1&gt;, &lt;binary value expr
+    2&gt; )</code>
+</p>
+<p>The arguments are character strings or binary strings. Returns a
+    string formed by concatenation of the arguments. Equivalent to the SQL
+    concatenation expression <code class="literal">&lt;value expr 1&gt; || &lt;value expr
+    2&gt;</code>. (JDBC)</p>
+<a name="N12BD8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DIFFERENCE</strong></span>
+</p>
+<p>
+<code class="literal">DIFFERENCE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; )</code>
+</p>
+<p>The arguments are character strings. Converts the arguments into
+    SOUNDEX codes, and returns an INTEGER between 0-4 which indicates how
+    similar the two SOUNDEX value are. If the values are the same, it returns
+    4, if the values have no similarity, it returns 0. In-between values are
+    returned for partial similarity. (JDBC)</p>
+<a name="N12BE6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>INSERT</strong></span>
+</p>
+<p>
+<code class="literal">INSERT ( &lt;char value expr 1&gt;, &lt;offset&gt;,
+    &lt;length&gt;, &lt;char value expr 2&gt; )</code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value expr
+    1&gt;</code> in which <code class="literal">&lt;length&gt;</code> characters have
+    been removed from the <code class="literal">&lt;offset&gt;</code> position and in
+    their place, the whole <code class="literal">&lt;char value expr 2&gt;</code> is
+    copied. Equivalent to SQL/Foundation <code class="literal">OVERLAY( &lt;char value
+    expr1&gt; PLACING &lt; char value expr2&gt; FROM &lt;offset&gt; FOR
+    &lt;length&gt; )</code> . (JDBC)</p>
+<a name="N12C03" class="indexterm"></a>
+<p>
+<span class="bold"><strong>HEXTORAW</strong></span>
+</p>
+<p>
+<code class="literal">HEXTORAW( &lt;char value expr&gt; )</code>
+</p>
+<p>Returns a BINARY string formed by translation of hexadecimal digits
+    and letters in the &lt;<code class="literal">char value expr&gt;</code>. Each
+    character of the <code class="literal">&lt;char value expr&gt;</code> must be a
+    digit or a letter in the A | B | C | D | E | F set. Each byte of the
+    retired binary string is formed by translating two hex digits into one
+    byte. (HyperSQL)</p>
+<a name="N12C17" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LCASE</strong></span>
+</p>
+<p>
+<code class="literal">LCASE ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a character string that is the lower case version of the
+    <code class="literal">&lt;char value expr&gt;</code>. Equivalent to SQL/Foundation
+    <code class="literal">LOWER (&lt;char value expr&gt;)</code>. (JDBC)</p>
+<a name="N12C2B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LEFT</strong></span>
+</p>
+<p>
+<code class="literal">LEFT ( &lt;char value expr&gt;, &lt;length&gt; )
+    </code>
+</p>
+<p>Returns a character string consisting of the first
+    <code class="literal">&lt;length&gt;</code> characters of <code class="literal">&lt;char value
+    expr&gt;</code>. Equivalent to SQL/Foundation<code class="literal">
+    SUBSTRING(&lt;char value expr&gt; FROM 0 FOR &lt;length&gt;)</code>.
+    (JDBC)</p>
+<a name="N12C42" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LENGTH</strong></span>
+</p>
+<p>
+<code class="literal">LENGTH ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns as a BIGINT value the number of characters in
+    <code class="literal">&lt;char value expr&gt;</code>. Equivalent to SQL/Foundation
+    <code class="literal">CHAR_LENGTH(&lt;char value expr&gt;)</code>. (JDBC)</p>
+<a name="N12C56" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOCATE</strong></span>
+</p>
+<p>
+<code class="literal">LOCATE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; [ , &lt;offset&gt; ] ) </code>
+</p>
+<p>Returns as a BIGINT value the starting position of the first
+    occurrence of <code class="literal">&lt;char value expr 1&gt;</code> within
+    <code class="literal">&lt;char value expr 2&gt;</code>. If
+    <code class="literal">&lt;offset</code>&gt; is specified, the search begins with the
+    position indicated by <code class="literal">&lt;offset&gt;</code>. If the search is
+    not successful, 0 is returned. Equivalent to SQL/Foundation
+    <code class="literal">POSITION(&lt;char value expr 1&gt; IN &lt;char value expr
+    2&gt;)</code>. (JDBC)</p>
+<a name="N12C73" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LTRIM</strong></span>
+</p>
+<p>
+<code class="literal">LTRIM ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value
+    expr&gt;</code> with the leading space characters removed. Equivalent
+    to SQL/Foundation <code class="literal">TRIM( LEADING ' ' FROM &lt;char value expr&gt;
+    )</code>. (JDBC)</p>
+<a name="N12C87" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RAWTOHEX</strong></span>
+</p>
+<p>
+<code class="literal">RAWTOHEX( &lt;binary value expr&gt; )</code>
+</p>
+<p>Returns a character string composed of hexadecimal digits
+    representing the bytes in the <code class="literal">&lt;binary value
+    expr&gt;</code>. Each byte of the <code class="literal">&lt;binary value
+    expr&gt;</code> is translated into two hex digits. (HyperSQL)</p>
+<a name="N12C9B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REGEXP_MATCHES</strong></span>
+</p>
+<p>
+<code class="literal">REGEXP_MATCHES ( &lt;char value expr&gt;, &lt;regular
+    expression&gt; ) </code>
+</p>
+<p>Returns true if the &lt;char value expr&gt; matches the &lt;regular
+    expression&gt;. The &lt;regular expression&gt; is defined according to
+    Java language rules. (HyperSQL)</p>
+<a name="N12CA9" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REPEAT</strong></span>
+</p>
+<p>
+<code class="literal">REPEAT ( &lt;char value expr&gt;, &lt;count&gt; )
+    </code>
+</p>
+<p>Returns a character string based on<code class="literal"> &lt;char value
+    expr&gt;</code>, repeated <code class="literal">&lt;count&gt;</code> times.
+    (JDBC)</p>
+<a name="N12CBD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REPLACE</strong></span>
+</p>
+<p>
+<code class="literal">REPLACE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt;, &lt;char value expr 3&gt; )</code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value expr
+    1&gt;</code> where each occurrence of <code class="literal">&lt;char value expr
+    2&gt;</code> has been replaced with a copy of <code class="literal">&lt;char value
+    expr 3&gt;</code>. (JDBC)</p>
+<a name="N12CD4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REVERSE</strong></span>
+</p>
+<p>
+<code class="literal">REVERSE ( &lt;char value expr&gt; )</code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value
+    expr&gt;</code> with characters in the reverse order. (HyperSQL)</p>
+<a name="N12CE5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RIGHT</strong></span>
+</p>
+<p>
+<code class="literal">RIGHT ( &lt;char value expr&gt;, &lt;count&gt; )
+    </code>
+</p>
+<p>Returns a character string consisting of the last
+    <code class="literal">&lt;count&gt;</code> characters of <code class="literal">&lt;char value
+    expr&gt;</code>. (JDBC)</p>
+<a name="N12CF9" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RTRIM</strong></span>
+</p>
+<p>
+<code class="literal">RTRIM ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value
+    expr&gt;</code> with the trailing space characters removed. Equivalent
+    to SQL/Foundation <code class="literal">TRIM(TRAILING ' ' FROM &lt;character
+    string&gt;)</code>. (JDBC)</p>
+<a name="N12D0D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SOUNDEX</strong></span>
+</p>
+<p>
+<code class="literal">SOUNDEX ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a four character code representing the sound of
+    <code class="literal">&lt;char value expr&gt;</code>. The US census algorithm is
+    used. For example the soundex value for Washington is W252. (JDBC)</p>
+<a name="N12D1E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SPACE</strong></span>
+</p>
+<p>
+<code class="literal">SPACE ( &lt;count&gt; ) </code>
+</p>
+<p>Returns a character string consisting of <code class="literal">&lt;count&gt;
+    </code>spaces. (JDBC)</p>
+<a name="N12D2F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SUBSTR</strong></span>
+</p>
+<p>
+<code class="literal">{ SUBSTR | SUBSTRING } ( &lt;char value expr&gt;,
+    &lt;offset&gt;, &lt;length&gt; )</code>
+</p>
+<p>The JDBC version of SQL/Foundation <code class="literal">SUBSTRING</code>
+    returns a character string that consists of
+    <code class="literal">&lt;length&gt;</code> characters from <code class="literal">&lt;char value
+    expr&gt; </code>starting at the <code class="literal">&lt;offset&gt;</code>
+    position. (JDBC)</p>
+<a name="N12D49" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UCASE</strong></span>
+</p>
+<p>
+<code class="literal">UCASE ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a character string that is the lower case version of the
+    <code class="literal">&lt;char value expr&gt;</code>. Equivalent to SQL/Foundation
+    <code class="literal">UPPER( &lt;char value expr&gt; )</code> . (JDBC)</p>
+<a name="N12D5D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CHARACTER_LENGTH</strong></span>
+</p>
+<p>
+<code class="literal">{ CHAR_LENGTH | CHARACTER_LENGTH } ( &lt;char value
+    expression&gt; [ USING { CHARACTERS | OCTETS } ] )</code>
+</p>
+<a name="N12D69" class="indexterm"></a>
+<p>
+<span class="bold"><strong>OCTET_LENGTH</strong></span>
+</p>
+<p>
+<code class="literal">OCTET_LENGTH ( &lt;string value expression&gt;
+    )</code>
+</p>
+<a name="N12D75" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BIT_LENGTH</strong></span>
+</p>
+<p>
+<code class="literal">BIT_LENGTH ( &lt;string value expression&gt;
+    )</code>
+</p>
+<p>The CHAR_LENGTH or CHARACTER_LENGTH function can be used with
+    character strings, while OCTET_LENGTH can be used with character or binary
+    strings and BIT_LENGTH can be used with character, binary and bit
+    strings.</p>
+<p>All functions return a BIGINT value that measures the length of the
+    string in the given unit. CHAR_LENGTH counts characters, OCTET_LENGTH
+    counts octets and BIT_LENGTH counts bits in the string. For CHAR_LENGTH,
+    if <code class="literal">[ USING OCTETS ] </code>is specified, the octet count is
+    returned. (Foundation)</p>
+<a name="N12D88" class="indexterm"></a>
+<p>
+<span class="bold"><strong>OVERLAY</strong></span>
+</p>
+<p>
+<code class="literal">OVERLAY ( &lt;char value expr 1&gt; PLACING &lt;char value
+    expr 2&gt;</code>
+</p>
+<p>
+<code class="literal">FROM &lt;start position&gt; [ FOR &lt;string length&gt; ] [
+    USING CHARACTERS ] )</code>
+</p>
+<p>
+<code class="literal">OVERLAY ( &lt;binary value expr 1&gt; PLACING &lt;binary
+    value expr 2&gt;</code>
+</p>
+<p>
+<code class="literal">FROM &lt;start position&gt; [ FOR &lt;string length&gt; ]
+    )</code>
+</p>
+<p>The character version of OVERLAY returns a character string based on
+    <code class="literal">&lt;char value expr 1&gt;</code> in which <code class="literal">&lt;string
+    length&gt;</code> characters have been removed from the
+    <code class="literal">&lt;start position&gt;</code> and in their place, the whole
+    <code class="literal">&lt;char value expr 2&gt;</code> is copied.</p>
+<p>The binary version of OVERLAY returns a binary string formed in the
+    same manner as the character version. (Foundation)</p>
+<a name="N12DAD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>POSITION</strong></span>
+</p>
+<p>
+<code class="literal">POSITION ( &lt;char value expr 1&gt; IN &lt;char value expr
+    2&gt; [ USING CHARACTERS ] )</code>
+</p>
+<p>
+<code class="literal">POSITION ( &lt;binary value expr 1&gt; IN &lt;binary value
+    expr 2&gt; )</code>
+</p>
+<p>The character and binary versions of POSITION search the string
+    value of the second argument for the first occurrence of the first
+    argument string. If the search is successful, the position in the string
+    is returned as a BIGINT. Otherwise zero is returned.</p>
+<a name="N12DBE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SUBSTRING</strong></span>
+</p>
+<p>
+<code class="literal">SUBSTRING ( &lt;char value expr&gt; FROM &lt;start
+    position&gt; [ FOR &lt;string length&gt; ] [ USING CHARACTERS ]
+    )</code>
+</p>
+<p>
+<code class="literal">SUBSTRING ( &lt;binary value expr&gt; FROM &lt;start
+    position&gt; [ FOR &lt;string length&gt; ] )</code>
+</p>
+<p>The character version of SUBSTRING returns a character string that
+    consists of the characters of the <code class="literal">&lt;char value expr&gt;
+    </code>from <code class="literal">&lt;start position&gt;</code>. If the
+    optional<code class="literal"> &lt;string length&gt;</code> is specified, only
+    <code class="literal">&lt;string length&gt; </code>characters are returned.</p>
+<p>The binary version of SUBSTRING returns a binary string in the same
+    manner. (Foundation)</p>
+<a name="N12DDD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRIM</strong></span>
+</p>
+<p>
+<code class="literal">TRIM ([ [ LEADING | TRAILING | BOTH ] [ &lt;trim
+    character&gt; ] FROM ] &lt;char value expr&gt; )</code>
+</p>
+<p>
+<code class="literal">TRIM ([ [ LEADING | TRAILING | BOTH ] [ &lt;trim octet&gt;
+    ] FROM ] &lt;binary value expr&gt; )</code>
+</p>
+<p>The character version of TRIM returns a character string based on
+    <code class="literal">&lt;char value expr&gt;</code>. Consecutive instances of
+    <code class="literal">&lt;trim character&gt; </code>are removed from the beginning,
+    the end or both ends of the<code class="literal">&lt;char value expr&gt;
+    </code>depending on the value of the optional first qualifier
+    <code class="literal">[ LEADING | TRAILING | BOTH ]</code>. If no qualifier is
+    specified, <code class="literal">BOTH </code>is used as default. If <code class="literal">[
+    &lt;trim character&gt; ]</code> is not specified, the space character
+    is used as default.</p>
+<p>The binary version of TRIM returns a binary string based on
+    <code class="literal">&lt;binary value expr&gt;</code>. Consecutive instances of
+    <code class="literal">&lt;trim octet&gt; </code>are removed in the same manner as in
+    the character version. If<code class="literal"> [ &lt;trim octet&gt; ]</code> is not
+    specified, the 0 octet is used as default. (Foundation)</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_numeric-sect"></a>Numeric Functions</h2>
+</div>
+</div>
+</div>
+<a name="N12E0F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ABS</strong></span>
+</p>
+<p>
+<code class="literal">ABS ( &lt;num value expr&gt; | &lt;interval value expr&gt;
+    ) </code>
+</p>
+<p>Returns the absolute value of the argument as a value of the same
+    type. (JDBC and Foundation)</p>
+<a name="N12E1D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ACOS</strong></span>
+</p>
+<p>
+<code class="literal">ACOS ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the arc-cosine of the argument in radians as a value of
+    DOUBLE type. (JDBC)</p>
+<a name="N12E2B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ASIN</strong></span>
+</p>
+<p>
+<code class="literal">ASIN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the arc-sine of the argument in radians as a value of DOUBLE
+    type. (JDBC)</p>
+<a name="N12E39" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ATAN</strong></span>
+</p>
+<p>
+<code class="literal">ATAN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the arc-tangent of the argument in radians as a value of
+    DOUBLE type. (JDBC)</p>
+<a name="N12E47" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ATAN2</strong></span>
+</p>
+<p>
+<code class="literal">ATAN2 ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    ) </code>
+</p>
+<p>The <code class="literal">&lt;num value expr 1&gt;</code> and <code class="literal">&lt;num
+    value expr 2&gt;</code> express the <code class="varname">x</code> and
+    <code class="varname">y</code> coordinates of a point. Returns the angle, in
+    radians, representing the angle coordinate of the point in polar
+    coordinates, as a value of DOUBLE type. (JDBC)</p>
+<a name="N12E61" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CEILING</strong></span>
+</p>
+<p>
+<code class="literal">{ CEIL | CEILING } ( &lt;num value expr&gt; )
+    </code>
+</p>
+<p>Returns the smallest integer greater than or equal to the argument.
+    If the argument is exact numeric then the result is exact numeric with a
+    scale of 0. If the argument is approximate numeric, then the result is of
+    DOUBLE type. (JDBC and Foundation)</p>
+<a name="N12E6F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BITAND</strong></span>
+</p>
+<p>
+<code class="literal">BITAND ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">BITAND ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</code>
+</p>
+<a name="N12E7E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BITOR</strong></span>
+</p>
+<p>
+<code class="literal">BITOR ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">BITOR ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</code>
+</p>
+<a name="N12E8D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BITXOR</strong></span>
+</p>
+<p>
+<code class="literal">BITXOR ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">BITXOR ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</code>
+</p>
+<p>These three functions perform the bit operations: OR, AND, XOR, on
+    two values. The values are either integer values, or bit strings. The
+    result is an integer value of the same type as the arguments, or a bit
+    string of the same length as the argument. Each bit of the result is
+    formed by performing the operation on corresponding bits of the arguments.
+    (HyperSQL)</p>
+<a name="N12E9E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COS</strong></span>
+</p>
+<p>
+<code class="literal">COS ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the cosine of the argument (an angle expressed in radians)
+    as a value of DOUBLE type. (JDBC)</p>
+<a name="N12EAC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COT</strong></span>
+</p>
+<p>
+<code class="literal">COT ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the cotangent of the argument as a value of DOUBLE type. The
+    <code class="literal">&lt;num value expr&gt;</code> represents an angle expressed in
+    radians. (JDBC)</p>
+<a name="N12EBD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DEGREES</strong></span>
+</p>
+<p>
+<code class="literal">DEGREES ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Converts the argument (an angle expressed in<code class="literal">
+    radians</code>) into degrees and returns the value in the DOUBLE type.
+    (JDBC)</p>
+<a name="N12ECE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>EXP</strong></span>
+</p>
+<p>
+<code class="literal">EXP ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the exponential value of the argument as a value of DOUBLE
+    type. (JDBC and Foundation)</p>
+<a name="N12EDC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>FLOOR</strong></span>
+</p>
+<p>
+<code class="literal">FLOOR ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the largest integer that is less than or equal to the
+    argument. If the argument is exact numeric then the result is exact
+    numeric with a scale of 0. If the argument is approximate numeric, then
+    the result is of DOUBLE type. (JDBC and Foundation)</p>
+<a name="N12EEA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LN</strong></span>
+</p>
+<p>
+<code class="literal">LN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the natural logarithm of the argument, as a value of DOUBLE
+    type. (Foundation)</p>
+<a name="N12EF8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOG</strong></span>
+</p>
+<p>
+<code class="literal">LOG ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the natural logarithm of the argument, as a value of DOUBLE
+    type. (JDBC)</p>
+<a name="N12F06" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOG10</strong></span>
+</p>
+<p>
+<code class="literal">LOG10 ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the base 10 logarithm of the argument as a value of DOUBLE
+    type. (JDBC)</p>
+<p>
+<code class="literal">MOD ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt; )
+    </code>
+</p>
+<a name="N12F17" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MOD</strong></span>
+</p>
+<p>Returns the remainder (modulus) of <code class="literal">&lt;num value expr
+    1&gt;</code> divided by <code class="literal">&lt;num value expr 2&gt;.</code>
+    The data type of the returned value is the same as the second argument.
+    (JDBC and Foundation)</p>
+<a name="N12F28" class="indexterm"></a>
+<p>
+<span class="bold"><strong>PI</strong></span>
+</p>
+<p>
+<code class="literal">PI () </code>
+</p>
+<p>Returns the constant pi as a value of DOUBLE type. (JDBC)</p>
+<a name="N12F36" class="indexterm"></a>
+<p>
+<span class="bold"><strong>POWER</strong></span>
+</p>
+<p>
+<code class="literal">POWER ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    ) </code>
+</p>
+<p>Returns the value of <code class="literal">&lt;num value expr 1&gt;</code>
+    raised to the power of <code class="literal">&lt;int value expr 2&gt;</code> as a
+    value of DOUBLE type. (JDBC and Foundation)</p>
+<a name="N12F4A" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RADIANS</strong></span>
+</p>
+<p>
+<code class="literal">RADIANS ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Converts the argument (an angle expressed in<code class="literal">
+    degrees</code>) into radians and returns the value in the DOUBLE type.
+    (JDBC)</p>
+<a name="N12F5B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RAND</strong></span>
+</p>
+<p>
+<code class="literal">RAND ( [ &lt;int value expr&gt; ] ) </code>
+</p>
+<p>Returns a random value in the DOUBLE type. The optional <code class="literal">[
+    &lt;int value expr&gt; ]</code> is used as seed value. In HyperSQL each
+    session has a separate random number generator. The first call that uses a
+    seed parameter sets the seed for subsequent calls that do not include a
+    parameter. (JDBC)</p>
+<a name="N12F6C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ROUND</strong></span>
+</p>
+<p>
+<code class="literal">ROUND ( &lt;num value expr&gt;, &lt;int value expr&gt; )
+    </code>
+</p>
+<p>The <code class="literal">&lt;num value expr&gt; </code>is of the DOUBLE type.
+    The function returns a DOUBLE value which is the value of the argument
+    rounded to <code class="literal">&lt;int value expr&gt;</code> places right of the
+    decimal point. If <code class="literal">&lt;int value expr&gt;</code> is negative,
+    the first argument is rounded to <code class="literal">&lt;int value expr&gt;</code>
+    places to the left of the decimal point. (JDBC)</p>
+<a name="N12F86" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SIGN</strong></span>
+</p>
+<p>
+<code class="literal">SIGN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns an INTEGER, indicating the sign of the argument. If the
+    argument is negative then -1 is returned. If it is equal to zero then 0 is
+    returned. If the argument is positive then 1 is returned. (JDBC)</p>
+<a name="N12F94" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SIN</strong></span>
+</p>
+<p>
+<code class="literal">SIN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the sine of the argument (an angle expressed in radians) as
+    a value of DOUBLE type. (JDBC)</p>
+<a name="N12FA2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQRT</strong></span>
+</p>
+<p>
+<code class="literal">SQRT ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the square root of the argument as a value of DOUBLE type.
+    (JDBC and Foundation)</p>
+<a name="N12FB0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TAN</strong></span>
+</p>
+<p>
+<code class="literal">TAN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the tangent of the argument (an angle expressed in radians)
+    as a value of DOUBLE type. (JDBC)</p>
+<a name="N12FBE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRUNCATE</strong></span>
+</p>
+<p>
+<code class="literal">TRUNCATE ( &lt;num value expr&gt;, &lt;int value expr&gt; )
+    </code>
+</p>
+<p>Returns a value in the same type as <code class="literal">&lt;num value
+    expr&gt;</code>. The value is rounded by replacing digits with zeros
+    from <code class="literal">&lt;int value expr&gt;</code> places right of the decimal
+    point to the end. If <code class="literal">&lt;int value expr&gt;</code> is
+    negative, <code class="literal">ABS( &lt;int value expr&gt; )</code> digits to left
+    of the decimal point and all digits to the right of the decimal points are
+    replaced with zeros. Results of calling TRUNCATE with 12345.6789 with (-2,
+    0, 2, 4) are (12300.0000, 12345.0000, 12345.6700, 12345.6789).
+    (JDBC)</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_datetime-sect"></a>Date Time and Interval Functions</h2>
+</div>
+</div>
+</div>
+<a name="N12FDC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TIMEZONE</strong></span>
+</p>
+<p>
+<code class="literal">TIMEZONE()</code>
+</p>
+<p>Returns the current time zone for the session. Returns an INTERVAL
+    HOUR TO MINUTE value. (HyperSQL)</p>
+<a name="N12FEA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SESSION_TIMEZONE</strong></span>
+</p>
+<p>
+<code class="literal">SESSION_TIMEZONE()</code>
+</p>
+<p>Returns the default time zone for the current session. Returns an
+    INTERVAL HOUR TO MINUTE value. (HyperSQL)</p>
+<a name="N12FF8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATABASE_TIMEZONE</strong></span>
+</p>
+<p>
+<code class="literal">DATABASE_TIMEZONE()</code>
+</p>
+<p>Returns the time zone for the database engine. This is based on
+    where the database server process is located. Returns an INTERVAL HOUR TO
+    MINUTE value. (HyperSQL)</p>
+<a name="N13006" class="indexterm"></a>
+<p>
+<span class="bold"><strong>EXTRACT</strong></span>
+</p>
+<p>
+<code class="literal">EXTRACT ( &lt;extract field&gt; FROM &lt;extract source&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">&lt;extract field&gt; ::= YEAR | MONTH | DAY | HOUR |
+    MINUTE | DAY_OF_WEEK | WEEK_OF_YEAR | QUARTER | DAY_OF_YEAR | DAY_OF_MONTH
+    |</code>
+</p>
+<p>
+<code class="literal">TIMEZONE_HOUR | TIMEZONE_MINUTE | SECOND |
+    SECONDS_SINCE_MIDNIGHT |</code>
+</p>
+<p>
+<code class="literal">DAY_NAME | MONTH_NAME</code>
+</p>
+<p>
+<code class="literal">&lt;extract source&gt; ::= &lt;datatime value expr&gt; |
+    &lt;interval value expr&gt;</code>
+</p>
+<p>The EXTRACT function returns a field or element of the
+    <code class="literal">&lt;extract source&gt;</code>. The <code class="literal">&lt;extract
+    source&gt;</code> is a datetime or interval expression. The type of the
+    return value is BIGINT for most of the<code class="literal"> &lt;extract
+    field&gt;</code> options. The exceptions is <code class="literal">SECOND
+    </code>where a DECIMAL value is returned which has the same precision
+    as the datetime or interval expression. The field values <code class="literal">DAY_NAME
+    </code>or<code class="literal"> MONTH_NAME </code>result in a character string.
+    When <code class="literal">MONTH_NAME</code> is specified, a string in the range
+    January - December is returned. When <code class="literal">DAY_NAME </code>is
+    specified, a string in the range Sunday -Saturday is returned.</p>
+<p>If the <code class="literal">&lt;extract source&gt;</code> is <code class="literal">FROM
+    &lt;datatime value expr&gt;</code>, different groups of
+    <code class="literal">&lt;extract source&gt;</code> can be used depending on the
+    data type of the expression. The <code class="literal">TIMEZONE_HOUR |
+    TIMEZONE_MINUTE</code> options are valid only for TIME WITH TIMEZONE
+    and TIMESTAMP WITH TIMEZONE data types. The <code class="literal">HOUR | MINUTE |
+    SECOND | SECONDS_MIDNIGHT</code> options, are valid for TIME and
+    TIMESTAMP types. The rest of the fields are valid for DATE and TIMESTAMP
+    types.</p>
+<p>If the <code class="literal">&lt;extract source&gt;</code> is <code class="literal">FROM
+    &lt;interval value expr&gt;</code>, the <code class="literal">&lt;extract
+    field&gt;</code> must be one of the fields of the INTERVAL type of the
+    expressions. The <code class="literal">YEAR | MONTH</code> options may be valid for
+    INTERVAL types based on months. The <code class="literal">DAY | HOUR | MINUTE | SECOND
+    | SECONDS_MIDNIGHT</code> options may be valid for INTERVAL types based
+    on seconds. For example,<code class="literal"> DAY | HOUR | MINUTE</code> are the
+    only valid fields for the INTERVAL DAY TO MINUTE data type. (Foundation
+    with HyperSQL extensions)</p>
+<a name="N1305D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_DATE</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_DATE</code>
+</p>
+<a name="N13069" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_TIME</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_TIME [ ( &lt;time precision&gt; )
+    ]</code>
+</p>
+<a name="N13075" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOCALTIME</strong></span>
+</p>
+<p>
+<code class="literal">LOCALTIME [ ( &lt;time precision&gt; ) ]</code>
+</p>
+<a name="N13081" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_TIMESTAMP</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_TIMESTAMP [ ( &lt;timestamp precision&gt; )
+    ]</code>
+</p>
+<a name="N1308D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOCALTIMESTAMP</strong></span>
+</p>
+<p>
+<code class="literal">LOCALTIMESTAMP [ ( &lt;timestamp precision&gt; )
+    ]</code>
+</p>
+<p>These datetime functions return the datetime value representing the
+    moment the function is called. CURRENT_DATE returns a value of DATE type.
+    CURRENT_TIME returns a value of TIME WITH TIME ZONE type. LOCALTIME
+    returns a value of TIME type. CURRENT_TIMESTAMP returns a value of
+    TIMESTAMP WITH TIME ZONE type. LOCALTIMESTAMP returns a value of TIMESTAMP
+    type. If the optional <code class="literal">[ ( &lt;time precision&gt; ) ]</code>
+    or<code class="literal"> [ ( &lt;timestamp precision&gt; ) ]</code> is used, then
+    the returned value has the specified fraction of the second precision.
+    (Foundation)</p>
+<a name="N130A1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURDATE</strong></span>
+</p>
+<p>
+<code class="literal">CURDATE ()</code>
+</p>
+<p>This function is equivalent to<code class="literal"> CURRENT_DATE.
+    </code>(JDBC)</p>
+<a name="N130B2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURTIME</strong></span>
+</p>
+<p>
+<code class="literal">CURTIME ()</code>
+</p>
+<p>This function is equivalent to<code class="literal"> LOCALTIME</code>.
+    (JDBC)</p>
+<a name="N130C3" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DAYNAME</strong></span>
+</p>
+<p>
+<code class="literal">DAYNAME ( &lt;datatime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( DAY_NAME FROM ...
+    ) </code>Returns a string in the range of Sunday - Saturday.
+    (JDBC)</p>
+<a name="N130D4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DAYOFMONTH</strong></span>
+</p>
+<p>
+<code class="literal">DAYOFMONTH ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( DAY_OF_MONTH FROM
+    ... ) </code>Returns an integer value in the range of 1-31.
+    (JDBC)</p>
+<a name="N130E5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DAYOFWEEK</strong></span>
+</p>
+<p>
+<code class="literal">DAYOFWEEK ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( DAY_OF_WEEK FROM
+    ... ) </code>Returns an integer value in the range of 1-7. The first
+    day of the week is Sunday. (JDBC)</p>
+<a name="N130F6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DAYOFYEAR</strong></span>
+</p>
+<p>
+<code class="literal">DAYOFYEAR ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( DAY_OF_YEAR FROM
+    ... ) </code>Returns an integer value in the range of 1-366.
+    (JDBC)</p>
+<a name="N13107" class="indexterm"></a>
+<p>
+<span class="bold"><strong>HOUR</strong></span>
+</p>
+<p>
+<code class="literal">HOUR ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( HOUR FROM ... )
+    </code>Returns an integer value in the range of 0-23. (JDBC)</p>
+<a name="N13118" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MINUTE</strong></span>
+</p>
+<p>
+<code class="literal">MINUTE ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( MINUTE FROM ... )
+    </code>Returns an integer value in the range of 0 - 59. (JDBC)</p>
+<a name="N13129" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MONTH</strong></span>
+</p>
+<p>
+<code class="literal">MONTH ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( MONTH FROM ... )
+    </code>Returns an integer value in the range of 1-12. (JDBC)</p>
+<a name="N1313A" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MONTHNAME</strong></span>
+</p>
+<p>
+<code class="literal">MONTHNAME ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( NAME_OF_MONTH FROM
+    ... ) </code>Returns a string in the range of January - December.
+    (JDBC)</p>
+<a name="N1314B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NOW</strong></span>
+</p>
+<p>
+<code class="literal">NOW ()</code>
+</p>
+<p>This function is equivalent to
+    <code class="literal">LOCAL_TIMESTAMP.</code>
+</p>
+<a name="N1315B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>QUARTER</strong></span>
+</p>
+<p>
+<code class="literal">QUARTER ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( QUARTER FROM ... )
+    </code>Returns an integer in the range of 1 - 4. (JDBC)</p>
+<a name="N1316C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SECOND</strong></span>
+</p>
+<p>
+<code class="literal">SECOND ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( SECOND FROM ... )
+    </code>Returns an integer or decimal in the range of 0 - 59, with the
+    same precision as the &lt;datetime value expr&gt;. (JDBC)</p>
+<a name="N1317D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SECONDS_SINCE_MIDNIGHT</strong></span>
+</p>
+<p>
+<code class="literal">SECONDS_SINCE_MIDNIGHT ( &lt;datetime value expr&gt;
+    )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT (
+    SECONDS_SINCE_MIDNIGHT FROM ... ) </code>Returns an integer in the
+    range of 0 - 86399. (HyperSQL)</p>
+<a name="N1318E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>WEEK</strong></span>
+</p>
+<p>
+<code class="literal">WEEK ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( WEEK_OF_YEAR FROM
+    ... ) </code>Returns an integer in the range of 1 - 54. (JDBC)</p>
+<a name="N1319F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>YEAR</strong></span>
+</p>
+<p>
+<code class="literal">YEAR ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( YEAR FROM ... )
+    </code>Returns an integer in the range of 1 - 9999. (JDBC)</p>
+<a name="N131B0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TIMESTAMPADD</strong></span>
+</p>
+<p>
+<code class="literal">TIMESTAMPADD ( &lt;tsi datetime field&gt;, &lt;numeric
+    value expression&gt;, &lt;datetime value expr&gt;)</code>
+</p>
+<a name="N131BC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TIMESTAMPDIFF</strong></span>
+</p>
+<p>
+<code class="literal">TIMESTAMPDIFF ( &lt;tsi datetime field&gt;, &lt;datetime
+    value expr 1&gt;, &lt;datetime value expr 2&gt;)</code>
+</p>
+<p>
+<code class="literal">&lt;tsi datetime field&gt; ::= SQL_TSI_FRAC_SECOND |
+    SQL_TSI_SECOND | SQL_TSI_MINUTE | SQL_TSI_HOUR | SQL_TSI_DAY |
+    SQL_TSI_WEEK | SQL_TSI_MONTH | SQL_TSI_QUARTER |
+    SQL_TSI_YEAR</code>
+</p>
+<p>HyperSQL supports full SQL Standard datetime features. It supports
+    adding integers representing units of time directly to datetime values
+    using the arithmetic plus operator. It also supports subtracting one
+    <code class="literal">&lt;datetime value expr&gt;</code> from another in the given
+    units of days using the minus operator. An example of
+    <code class="literal">&lt;datetime value expr&gt; + &lt;numeric value expression&gt;
+    &lt;datetime field&gt; </code>is <code class="literal">LOCAL_TIMESTAMP + 5
+    DAY</code>. An example of <code class="literal">( &lt;datetime value expr&gt; -
+    &lt;numeric value expression&gt; ) &lt;datetime field&gt; </code>is
+    <code class="literal">(CURRENT_DATE - DATE '2008-08-8') MONTH </code>which returns
+    the number of calendar months between the two dates.</p>
+<p>The two JDBC functions, <code class="literal">TIMESTAMPADD </code>and
+    <code class="literal">TIMESTAMPDIFF</code> perform the same function as above SQL
+    expressions. The field names are keywords and are different from those
+    used in the EXTRACT functions. These names are valid for use only when
+    calling these two functions. The return value for TIMESTAMPADD is of the
+    same type as the datetime argument used. The return type for TIMESTAMPDIFF
+    is always BIGINT, regardless of the type of arguments. The two datetime
+    arguments of TIMESTAMPDIFF should be of the same type. (JDBC)</p>
+<a name="N131E4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATEADD</strong></span>
+</p>
+<p>
+<code class="literal">DATEADD ( &lt;field&gt;, &lt;numeric value expr&gt;,
+    &lt;datetime value expr&gt; )</code>
+</p>
+<a name="N131F0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATEDIFF</strong></span>
+</p>
+<p>
+<code class="literal">DATEDIFF ( &lt;field&gt;, &lt;datetime value expr 1&gt;,
+    datetime value expr 2&gt; )</code>
+</p>
+<p>
+<code class="literal">&lt;field&gt; ::= 'yy' | 'mm' | 'dd' | 'hh' | 'mi' | 'ss' |
+    'ms'</code>
+</p>
+<p>The DATEADD and DATEDIFF functions are alternatives to TIMESTAMPADD
+    and TIMESTAMPDIFF, with fewer available field options. The field names are
+    specified as strings, rather than keywords. The fields translate to YEAR,
+    MONTH, DAY, HOUR, MINUTE, SECOND and MILLISECOND. (HyperSQL}</p>
+<a name="N13201" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TO_CHAR</strong></span>
+</p>
+<p>
+<code class="literal">TO_CHAR( &lt;datetime value expr&gt;, &lt;char value
+    expr&gt; )</code>
+</p>
+<p>This function formats a datetime or numeric value to the format
+    specified by the pattern given in the second argument. The pattern can
+    contain pattern elements from the list given below, plus punctuation and
+    space characters. An example, including the result, is given below:</p>
+<pre class="programlisting">TO_CHAR ( TIMESTAMP'2008-02-01 20:30:40', 'YYYY BC MONTH, DAY HH')
+
+2008 AD February, Friday 8
+</pre>
+<p>The format is internally translated to a
+    <code class="classname">java.text.SimpleDateFormat</code> format string. Any
+    character sequences not listed below are included in the Java format
+    string and may cause unexpected results or errors. Therefore unsupported
+    format strings should not be used. The supported format components are as
+    follows:</p>
+<div class="table">
+<a name="N13216"></a>
+<p class="title">
+<b>Table&nbsp;10.1.&nbsp;TO CHAR Values</b>
+</p>
+<div class="table-contents">
+<table summary="TO CHAR Values" cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">BC | B.C. | AD | A.D.</code></td><td style="border-bottom: 0.5pt solid ; ">Returns <code class="literal">AD</code> for common era and
+            <code class="literal">BC</code> for before common era</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">RRRR</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>4-digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">YYYY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>4-digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">IYYY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>4-digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">YY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>2 digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">IY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>2 digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">IYYY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>4-digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">MM</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Month (01-12)</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">MON</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Short three-letter name of month</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">MONTH</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Name of month</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">WW</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Week of year (1-53) where week 1 starts on the first
+            day of the year and continues to the seventh day of the
+            year.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">W</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Week of month (1-5) where week 1 starts on the first
+            day of the month and ends on the seventh.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">IW</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Week of year (1-52 or 1-53) based on the ISO
+            standard.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">DAY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Name of day.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">DD</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Day of month (1-31).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">DDD</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Day of year (1-366).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">DY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Short three-letter name of day.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">HH</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Hour of day (0-11).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">HH12</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Hour of day (0-11).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">HH24</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Hour of day (0-23).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">MI</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Minute (0-59).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">SS</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Second (0-59).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; "><code class="literal">FF</code></td><td style="">
+<p>Fractional seconds.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N132C8"></a>Array Functions</h2>
+</div>
+</div>
+</div>
+<p>Array functions are specialised functions with ARRAY
+    parameters.</p>
+<a name="N132CD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CARDINALITY</strong></span>
+</p>
+<p>
+<code class="literal">CARDINALITY( &lt;array value expr&gt; )</code>
+</p>
+<p>Returns the element count for the given array argument.
+    (Foundation)</p>
+<a name="N132DB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MAX_CARDINALITY</strong></span>
+</p>
+<p>
+<code class="literal">MAX_CARDINALITY( &lt;array value expr&gt;
+    )</code>
+</p>
+<p>Returns the maximum allowed element count for the given array
+    argument. (Foundation)</p>
+<a name="N132E9" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRIM_ARRAY</strong></span>
+</p>
+<p>
+<code class="literal">TRIM_ARRAY( &lt;array value expr&gt;, &lt;num value
+    expr&gt; )</code>
+</p>
+<p>Returns a new array that contains the elements of the
+    <code class="literal">&lt;array value expr&gt;</code> minus the number of elements
+    specified by the <code class="literal">&lt;num value expr&gt;. </code>Elements are
+    discarded from the end of the array. (Foundation)</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N132FD"></a>General Functions</h2>
+</div>
+</div>
+</div>
+<p>General functions can take different types of arguments. Some
+    General Functions accept a variable number of arguments.</p>
+<a name="N13302" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COALESCE</strong></span>
+</p>
+<p>
+<code class="literal">COALESCE( &lt;value expr 1&gt;, &lt;value expr 2&gt; [,
+    ...] )</code>
+</p>
+<p>Returns <code class="literal">&lt;value expr 1&gt;</code> if it is not null,
+    otherwise returns <code class="literal">&lt;value expr 2&gt;</code> if not null and
+    so on. The type of both arguments must be comparable. (Foundation)</p>
+<a name="N13316" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONVERT</strong></span>
+</p>
+<p>
+<code class="literal">CONVERT ( &lt;value expr&gt; , &lt;data type&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">&lt;data type&gt; ::= { SQL_BIGINT | SQL_BINARY | SQL_BIT
+    |SQL_BLOB | SQL_BOOLEAN | SQL_CHAR | SQL_CLOB | SQL_DATE | SQL_DECIMAL |
+    SQL_DATALINK |SQL_DOUBLE | SQL_FLOAT | SQL_INTEGER | SQL_LONGVARBINARY |
+    SQL_LONGNVARCHAR | SQL_LONGVARCHAR | SQL_NCHAR | SQL_NCLOB | SQL_NUMERIC |
+    SQL_NVARCHAR | SQL_REAL | SQL_ROWID | SQL_SQLXML | SQL_SMALLINT | SQL_TIME
+    | SQL_TIMESTAMP | SQL_TINYINT | SQL_VARBINARY | SQL_VARCHAR} [ (
+    &lt;precision, length or scale parameters&gt; ) ]</code>
+</p>
+<p>The CONVERT function is a JDBC escape function, equivalent to the
+    SQL standard CAST expression. It converts the <code class="literal">&lt;value
+    expr&gt;</code> into the given <code class="literal">&lt;data type&gt;</code> and
+    returns the value. The <code class="literal">&lt;data type&gt;</code> options are
+    synthetic names made by prefixing type names with <code class="literal">SQL_</code>.
+    Some of the <code class="literal">&lt;data type&gt;</code> options represent valid
+    SQL types, but some are based on non-standard type names, namely
+    <code class="literal">{ SQL_LONGNVARCHAR | SQL_LONGVARBINARY |SQL_LONGVARCHAR |
+    SQL_TINYINT }</code>. None of the synthetic names can be used in any
+    other context than the CONVERT function.</p>
+<p>The definition of CONVERT in the JDBC Standard does not allow the
+    precision, scale or length to be specified. This is required by the SQL
+    standard for BINARY, BIT, BLOB, CHAR, CLOB, VARBINARY and VARCHAR types
+    and is often needed for DECIMAL and NUMERIC. Therefore, HyperSQL allows
+    the use of precision, scale or length for the type definition when they
+    are valid for the type definition. HyperSQL also allows the use of real
+    type names (without the <code class="literal">SQL_</code> prefix). (JDBC)</p>
+<a name="N1333E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DECODE</strong></span>
+</p>
+<p>
+<code class="literal">DECODE( &lt;value expr main&gt;, &lt;value expr match
+    1&gt;, &lt;value expr result 1&gt; [...,] [, &lt;value expr default&gt;]
+    )</code>
+</p>
+<p>DECODE takes at least 3 arguments. The <code class="literal">&lt;value expr
+    main&gt;</code> is compared with <code class="literal">&lt;value expr match
+    1&gt;</code> and if it matches, <code class="literal">&lt;value expr result
+    1&gt;</code> is returned. If there are additional pairs of
+    <code class="literal">&lt;value expr match n&gt;</code> and <code class="literal">&lt;value expr
+    result n&gt;</code>, comparison is repeated until a match is found the
+    result is returned. If no match is found, the <code class="literal">&lt;value expr
+    default&gt;</code> is returned if it is specified, otherwise NULL is
+    returned. The type of the return value is a combination of the types of
+    the <code class="literal">&lt;value expr result ... &gt;</code> arguments.
+    (HyperSQL)</p>
+<a name="N13361" class="indexterm"></a>
+<p>
+<span class="bold"><strong>GREATEST</strong></span>
+</p>
+<p>
+<code class="literal">GREATEST( &lt;value expr 1&gt;, [&lt;value expr ...&gt;,
+    ...] )</code>
+</p>
+<p>The GREATEST function takes one or more arguments. It compares the
+    arguments with each other and returns the greatest argument. The return
+    type is the combined type of the arguments. Arguments can be of any type,
+    so long as they are comparable. (HyperSQL)</p>
+<a name="N1336F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IFNULL</strong></span>
+</p>
+<p>
+<code class="literal">IFNULL( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</code>
+</p>
+<p>Returns <code class="literal">&lt;value expr 1&gt;</code> if it is not null,
+    otherwise returns <code class="literal">&lt;value expr 2&gt;</code>. The type of
+    both arguments must be the same. Equivalent to SQL Standard
+    <code class="literal">COALESCE(&lt;value expr 1&gt;, &lt;value expr 2&gt;)</code>
+    function. (JDBC)</p>
+<a name="N13386" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LEAST</strong></span>
+</p>
+<p>
+<code class="literal">LEAST( &lt;value expr 1&gt;, [&lt;value expr ...&gt;, ...]
+    )</code>
+</p>
+<p>The LEAST function takes one or more arguments. It compares the
+    arguments with each other and returns the smallest argument. The return
+    type is the combined type of the arguments. Arguments can be of any type,
+    so long as they are comparable. (HyperSQL)</p>
+<a name="N13394" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NULLIF</strong></span>
+</p>
+<p>
+<code class="literal">NULLIF( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</code>
+</p>
+<p>Returns <code class="literal">&lt;value expr 1&gt;</code> if it is not equal
+    to <code class="literal">&lt;value expr 2&gt;</code>, otherwise returns null. The
+    type of both arguments must be the same. This function is a shorthand for
+    a specific CASE expression. (Foundation)</p>
+<a name="N133A8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NVL</strong></span>
+</p>
+<p>
+<code class="literal">NVL( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</code>
+</p>
+<p>Returns <code class="literal">&lt;value expr 1&gt;</code> if it is not null,
+    otherwise returns <code class="literal">&lt;value expr 2&gt;</code>. The type of the
+    return value is the combined type of the two value expressions. For
+    example, if &lt;value expr 1&gt; is an INTEGER column and
+    <code class="literal">&lt;value expr 2&gt;</code> is a DOUBLE constant, the return
+    type is DOUBLE. This function is the same as IFNULL and COALESCE
+    (HyperSQL)</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_sysfunc-sect"></a>System Functions</h2>
+</div>
+</div>
+</div>
+<a name="N133C3" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CRYPT_KEY</strong></span>
+</p>
+<p>
+<code class="literal">CRYPT_KEY( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</code>
+</p>
+<p>Returns a binary string representation of a cryptography key for the
+    given cipher and cyptography provider. The cipher specification is
+    specified by <code class="literal">&lt;value expr 1&gt;</code> and the provider by
+    <code class="literal">&lt;value expr 2&gt;</code>. To use the default provider,
+    specify null for <code class="literal">&lt;value expr 2&gt;</code>.
+    (HyperSQL)</p>
+<a name="N133DA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IDENTITY</strong></span>
+</p>
+<p>
+<code class="literal">IDENTITY ()</code>
+</p>
+<p>Returns the last IDENTITY value inserted into a row by the current
+    session. The statement, CALL IDENTITY() can be made after an INSERT
+    statement that inserts a row into a table with an IDENTITY column. The
+    CALL IDENTITY() statement returns the last IDENTITY value that was
+    inserted into a table by the current session. Each session manages this
+    function call separately and is not affected by inserts in other sessions.
+    The statement can be executed as a direct statement or a prepared
+    statement. (HyperSQL)</p>
+<a name="N133E8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATABASE</strong></span>
+</p>
+<p>
+<code class="literal">DATABASE ()</code>
+</p>
+<p>Returns the file name (without directory information) of the
+    database. (JDBC)</p>
+<a name="N133F6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATABASE_VERSION</strong></span>
+</p>
+<p>
+<code class="literal">DATABASE_VERSION ()</code>
+</p>
+<p>Returns the full version string for the database engine. For
+    example, 2.0.1. (JDBC)</p>
+<a name="N13404" class="indexterm"></a>
+<p>
+<span class="bold"><strong>USER</strong></span>
+</p>
+<p>
+<code class="literal">USER ()</code>
+</p>
+<p>Equivalent to the SQL function <code class="literal">CURRENT_USER</code>.
+    (JDBC)</p>
+<a name="N13415" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_USER</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_USER</code>
+</p>
+<a name="N13421" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_ROLE</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_ROLE</code>
+</p>
+<a name="N1342D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SESSION_USER</strong></span>
+</p>
+<p>
+<code class="literal">SESSION_USER</code>
+</p>
+<a name="N13439" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SYSTEM_USER</strong></span>
+</p>
+<p>
+<code class="literal">SYSTEM_USER</code>
+</p>
+<a name="N13445" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_SCHEMA</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_SCHEMA</code>
+</p>
+<a name="N13451" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_CATALOG</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_CATALOG</code>
+</p>
+<p>These functions return the named current session attribute. They are
+    all SQL Standard functions.</p>
+<p>The CURRENT_USER is the user that connected to the database, or a
+    user subsequently set by the SET AUTHORIZATION statement.</p>
+<p>SESSION_USER is the same as CURRENT_USER</p>
+<p>SYSTEM_USER is the user that connected to the database. It is not
+    changed with any command until the session is closed.</p>
+<p>CURRENT_SCHEMA is default schema of the user, or a schema
+    subsequently set by the SET SCHEMA command.</p>
+<p>CURRENT_CATALOG is always the same within a given HyperSQL database
+    and indicates the name of the catalog.</p>
+<a name="N13469" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISAUTOCOMMIT</strong></span>
+</p>
+<p>
+<code class="literal">ISAUTOCOMMIT()</code>
+</p>
+<p>Returns TRUE if the session is in autocommit mode. (HyperSQL)</p>
+<a name="N13477" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISREADONLYSESSION</strong></span>
+</p>
+<p>
+<code class="literal">ISREADONLYSESSION()</code>
+</p>
+<p>Returns TRUE if the session is in read only mode. (HyperSQL)</p>
+<a name="N13485" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISREADONLYDATABASE</strong></span>
+</p>
+<p>
+<code class="literal">ISREADONLYDATABASE()</code>
+</p>
+<p>Returns TRUE if the database is a read only database.
+    (HyperSQL)</p>
+<a name="N13493" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISREADONLYDATABASEFILES</strong></span>
+</p>
+<p>
+<code class="literal">ISREADONLYDATABASEFILES()</code>
+</p>
+<p>Returns TRUE if the database is a read-only files database. In this
+    kind of database, it is possible to modify the data, but the changes are
+    not persisted to the database files. (HyperSQL)</p>
+<a name="N134A1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISOLATION_LEVEL</strong></span>
+</p>
+<p>
+<code class="literal">ISOLATION_LEVEL()</code>
+</p>
+<p>Returns the current transaction isolation level for the session.
+    Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</p>
+<a name="N134AF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SESSION_ISOLATION_LEVEL</strong></span>
+</p>
+<p>
+<code class="literal">SESSION_ISOLATION_LEVEL()</code>
+</p>
+<p>Returns the default transaction isolation level for the current
+    session. Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</p>
+<a name="N134BD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATABASE_ISOLATION_LEVEL</strong></span>
+</p>
+<p>
+<code class="literal">DATABASE_ISOLATION_LEVEL()</code>
+</p>
+<p>Returns the default transaction isolation level for the database.
+    Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</p>
+<a name="N134CB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRANSACTION_CONTROL</strong></span>
+</p>
+<p>
+<code class="literal">TRANSACTION_CONTROL()</code>
+</p>
+<p>Returns the current transaction model for the database. Returns
+    LOCKS, MVLOCKS or MVCC as a string. (HyperSQL)</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="triggers-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="deployment-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;9.&nbsp;Triggers&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;11.&nbsp;System Management and Deployment
+  Issues</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/dataaccess-chapt.html b/doc/guide/dataaccess-chapt.html
new file mode 100644
index 0000000..0961cac
--- /dev/null
+++ b/doc/guide/dataaccess-chapt.html
@@ -0,0 +1,3455 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;7.&nbsp;Data Access and Change</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="accesscontrol-chapt.html" title="Chapter&nbsp;6.&nbsp;Access Control">
+<link rel="next" href="sqlroutines-chapt.html" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="accesscontrol-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;7.&nbsp;Data Access and Change</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="sqlroutines-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;6.&nbsp;Access Control&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;8.&nbsp;SQL-Invoked Routines</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="dataaccess-chapt"></a>Chapter&nbsp;7.&nbsp;Data Access and Change</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N11998"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1199B">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N119A0">Cursors And Result Sets</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N119BD">Columns and Rows</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N119D8">Navigation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N119EA">Updatability</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A28">Sensitivity</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A31">Holdability</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A44">Autocommit</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A4C">JDBC Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A59">JDBC Parameters</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A68">JDBC Returned Values</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A71">Syntax Elements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A76">Literals</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11B9C">References, etc.</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11BF8">Value Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11E1B">Predicates</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12147">Data Access Statements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1217F">Table</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12199">Query Specification</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N121DF">Table Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12246">Table Primary</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12278">Joined Table</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N122E5">Selection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N122EA">Projection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N122F1">Computed Columns</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N122F6">Naming</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12338">Grouping Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12346">Aggregation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1234D">Set Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12371">Query Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123B0">Ordering</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123C8">Slicing</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123DA">Data Change Statements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123DD">Delete Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123FD">Truncate Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1241F">Insert Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1246A">Update Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N124B8">Merge Statement</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1199B"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL data access and data change statements are fully compatible
+    with the latest SQL:2008 Standard. There are a few extensions and some
+    relaxation of rules, but these do not affect statements that are written
+    to the Standard syntax. There is full support for classic SQL, as
+    specified by SQL-92, and many enhancements added in later versions of the
+    standard.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N119A0"></a>Cursors And Result Sets</h2>
+</div>
+</div>
+</div>
+<p>An SQL statement can executed in two ways. One way is to use the
+    <code class="classname">java.sql.Statement</code> interface. The Statement object
+    can be reused to execute completely different SQL statements.
+    Alternatively a <code class="classname">PreparedStatment</code> can be used to
+    execute an SQL statement repeatedly, and the statements can be
+    parameterized. Using either form, if the SQL statement is a query
+    expression, a <code class="classname">ResultSet</code> is returned.</p>
+<p>In SQL, when a query expression (SELECT or similar SQL statement) is
+    executed, an ephemeral table is created. When this table is returned to
+    the application program, it is returned as a result set, which is accessed
+    row-by-row by a cursor. A JDBC <code class="classname">ResultSet</code> represents
+    an SQL result set and its cursor.</p>
+<p>The minimal definition of a cursor is a list of rows with a position
+    that can move forward. Some cursors also allow the position to move
+    backwards or jump to any position in the list.</p>
+<p>An SQL cursor has several attributes. These attributes depend on the
+    query expression. Some of these attributes can be overridden by specifying
+    qualifiers in the SQL statement or by specifying values for the parameters
+    of the JDBC <code class="classname">Statement</code> or
+    <code class="classname">PreparedStatement</code>.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N119BD"></a>Columns and Rows</h3>
+</div>
+</div>
+</div>
+<p>The columns of the rows of the result set are determined by the
+      query expression. The number of columns and the type and name
+      characteristics of each column are known when the query expression is
+      compiled and before its execution. This metadata information remains
+      constant regardless of changes to the contents of the tables used in the
+      query expression. The metadata for the JDBC
+      <code class="classname">ResultSet</code> is in the form of a
+      <code class="classname">ResultSetMetaData</code> object. Various methods of the
+      <code class="classname">ResultSetMetaData</code> interface return different
+      properties of each column of the
+      <code class="classname">ResultSet</code>.</p>
+<p>A result set may contain 0 or more rows. The rows are determined
+      by the execution of the query expression.</p>
+<p>The <code class="methodname">setMaxRows(int)</code> method of JDBC
+      <code class="classname">Statement</code> allows limiting the number of rows
+      returned by the statement. This limit is conceptually applied after the
+      result has been built, and the excess rows are discarded.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N119D8"></a>Navigation</h3>
+</div>
+</div>
+</div>
+<p>A cursor is either scrollable or not. Scrollable cursors allow
+      accessing rows by absolute or relative positioning. No-scroll cursors
+      only allow moving to the next row. The cursor can be optionally declared
+      with the SQL qualifiers SCROLL, or NO SCROLL. The JDBC statement
+      parameter can be specified as: TYPE_FORWARD_ONLY and
+      TYPE_SCROLL_INSENSITIVE. The JDBC type TYPE_SCROLL_SENSITIVE is not
+      supported by HSQLDB.</p>
+<p>The default is NO SCROLL or TYPE_FORWARD_ONLY.</p>
+<p>When a JDBC <code class="classname">ResultSet</code> is opened, it is
+      positioned before the first row. Using the
+      <code class="methodname">next()</code> method the position is moved to the
+      first row. While the <code class="classname">ResultSet</code> is positioned on a
+      row, various getter methods can be used to access the columns of the
+      row.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N119EA"></a>Updatability</h3>
+</div>
+</div>
+</div>
+<p>The result returned by some query expressions is updatable. HSQLDB
+      supports core SQL updatability features, plus some enhancements from the
+      SQL optional features.</p>
+<p>A query expression is updatable if it is a SELECT from a single
+      underlying base table (or updatable view) either directly or indirectly.
+      A SELECT statement featuring DISTINCT or GROUP BY or FETCH, LIMIT,
+      OFFSET is not updatable. In an updatable query expression, one or more
+      columns are updatable. An updatable column is a column that can be
+      traced directly to the underlying table. Therefore, columns that contain
+      expressions are not updatable. Examples of updatable query expressions
+      are given below. The view V is updatable when its query expression is
+      updatable. The SELECT statement from this view is also updatable:</p>
+<pre class="programlisting">SELECT A, B FROM T WHERE C &gt; 5
+SELECT A, B FROM (SELECT * FROM T WHERE C &gt; 10) AS TT WHERE TT.B &lt;10
+CREATE VIEW V(X,Y) AS SELECT A, B FROM T WHERE C &gt; 0 AND B &lt; 10
+SELECT X FROM V WHERE Y = 5
+</pre>
+<p>If a cursor is declared with the SQL qualifier, <code class="literal">FOR
+      UPDATE OF &lt;column name list&gt;</code>, then only the stated
+      columns in the result set become updatable. If any of the stated columns
+      is not actually updatable, then the cursor declaration will not
+      succeed.</p>
+<p>If the SQL qualifier, FOR UPDATE is used, then all the updatable
+      columns of the result set become updatable.</p>
+<p>If a cursor is declared with FOR READ ONLY, then it is not
+      updatable.</p>
+<p>In HSQLDB, if FOR READ ONLY or FOR UPDATE is not used then all the
+      updatable columns of the result set become updatable. This relaxes the
+      SQL standard rule that in this case limits updatability to only simply
+      updatable SELECT statements (where all columns are updatable).</p>
+<p>In JDBC, CONCUR_READ_ONLY or CONCUR_UPDATABLE can be specified for
+      the <code class="classname">Statement</code> parameter. CONCUR_UPDATABLE is
+      required if the returning ResultSet is to be updatable. If
+      CONCUR_READ_ONLY, which is the default, is used, then even an updatable
+      ResultSet becomes read-only.</p>
+<p>When a <code class="classname">ResultSet</code> is updatable, various
+      setter methods can be used to modify the column values. The names of the
+      setter methods begin with "update". After all the updates on a row are
+      done, the <code class="methodname">updateRow()</code> method must be called to
+      finalise the row update.</p>
+<p>An updatable <code class="classname">ResultSet</code> may or may not be
+      insertable-into. In an insertable <code class="classname">ResultSet</code>, all
+      columns of the result are updatable and any column of the base table
+      that is not in the result must be a generated column or have a default
+      value.</p>
+<p>In the <code class="classname">ResultSet</code> object, a special
+      pseudo-row, called the insert row, is used to populate values for
+      insertion into the <code class="classname">ResultSet</code> (and consequently,
+      into the base table). The setter methods must be used on all the
+      columns, followed by a call to
+      <code class="methodname">insertRow()</code>.</p>
+<p>Individual rows from all updatable result sets can be deleted one
+      at a time. The <code class="methodname">deleteRow()</code> is called when the
+      <code class="classname">ResultSet</code> is positioned on a row.</p>
+<p>While using an updatable ResultSet to modify data, it is
+      recommended not to change the same data using another ResultSet and not
+      to execute SQL data change statements that modify the same data.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A28"></a>Sensitivity</h3>
+</div>
+</div>
+</div>
+<p>The sensitivity of the cursor relates to visibility of changes
+      made to the data by the same transaction but without using the given
+      cursor. While the result set is open, the same transaction may use
+      statements such as INSERT or UPDATE, and change the data of the tables
+      from which the result set data is derived. A cursor is SENSITIVE if it
+      reflects those changes. It is INSENSITIVE if it ignores such changes. It
+      is ASENSITIVE if behaviour is implementation dependent.</p>
+<p>The SQL default is ASENSITIVE, i.e., implantation
+      dependent.</p>
+<p>In HSQLDB all cursors are INSENSITIVE. They do not reflect changes
+      to the data made by other statements.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A31"></a>Holdability</h3>
+</div>
+</div>
+</div>
+<p>A cursor is holdable if the result set is not automatically closed
+      when the current transaction is committed. Holdability can be specified
+      in the cursor declaration using the SQL qualifiers WITH HOLD or WITHOUT
+      HOLD.</p>
+<p>In JDBC, hodability is specified using either of the following
+      values for the Statement parameter: HOLD_CURSORS_OVER_COMMIT, or
+      CLOSE_CURSORS_AT_COMMIT.</p>
+<p>The SQL default is WITHOUT HOLD.</p>
+<p>The JDBC default for HSQLDB result sets is WITH HOLD for read-only
+      result sets and WITHOUT HOLD for updatable result sets.</p>
+<p>If the holdability of a <code class="classname">ResultSet</code> is
+      specified in a conflicting manner in the SQL statement and the JDBC
+      <code class="classname">Statement</code> object, the JDBC setting takes
+      precedence.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A44"></a>Autocommit</h3>
+</div>
+</div>
+</div>
+<p>The autocommit property of a connection is a feature of JDBC and
+      ODBC and is not part of the SQL Standard. In autocommit mode, all
+      transactional statements are followed by an implicit commit. In
+      autocommit mode, all <code class="classname">ResultSet</code> objects are
+      read-only and holdable.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A4C"></a>JDBC Overview</h3>
+</div>
+</div>
+</div>
+<p>The JDBC settings, ResultSet.CONCUR_READONLY and
+      ResultSet.CONCUR_UPDATABLE are the alternatives for read-only or
+      updatability. The default is ResultSet.CONCUR_READONLY.</p>
+<p>The JDBC settings, ResultSet.TYPE_FORWARD_ONLY,
+      ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE are
+      the alternatives for both scrollability (navigation) and sensitivity.
+      HyperSQL does not support ResultSet.TYPE_SCROLL_SENSITIVE. The two other
+      alternatives can be used for both updatable and read-only result
+      sets.</p>
+<p>The JDBC settings ResultSet.CLOSE_CURSORS_AT_COMMIT and
+      ResultSet.HOLD_CURSORS_OVER_COMMIT are the alternatives for the lifetime
+      of the result set. The default is ResultSet.CLOSE_CURSORS_AT_COMMIT. The
+      other setting can only be used for read-only result sets.</p>
+<p>Examples of creating statements for updatable result sets are
+      given below:</p>
+<pre class="programlisting">Connection c = newConnection();
+Statement st;
+c.setAutoCommit(false);
+st = c.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
+st = c.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A59"></a>JDBC Parameters</h3>
+</div>
+</div>
+</div>
+<p>When a JDBC PreparedStatement or CallableStatement is used with an
+      SQL statement that contains dynamic parameters, the data types of the
+      parameters are resolved and determined by the engine when the statement
+      is prepared. The SQL Standard has detailed rules to determine the data
+      types and imposes limits on the maximum length or precision of the
+      parameter. HyperSQL applies the standard rules with two exceptions for
+      parameters with String and BigDecimal Java types. HyperSQL ignores the
+      limits when the parameter value is set, and only enforces the necessary
+      limits when the PreparedStatement is executed. In all other cases,
+      parameter type limits are checked and enforce when the parameter is
+      set.</p>
+<p>In the example below the setString() calls do not raise an
+      exception, but one of the execute() statements does.</p>
+<pre class="programlisting">// table definition: CREATE TABLE T (NAME VARCHAR(12), ...)
+Connection c = newConnection();
+PreparedStatement st = c.prepareStatement("SELECT * FROM T WHERE NAME = ?");
+// type of the parameter is VARCHAR(12), which limits length to 12 characters
+st.setString(1, "Eyjafjallajokull"); // string is longer than type, but no exception is raised here
+set.execute(); // executes with no exception and does not find any rows
+// but if an UPDATE is attempted, an exception is raised
+st = c.prepareStatement("UPDATE T SET NAME = ? WHERE ID = 10");
+st.setString(1, "Eyjafjallajokull"); // string is longer than type, but no exception is raised here
+st.execute(); // exception is thrown when HyperSQL checks the value for update
+
+</pre>
+<p>All of the above also applies to setting the values in new and
+      updated rows in updatable ResultSet objects.</p>
+<p>JDBC parameters can be set with any compatible type, as supported
+      by the JDBC specification. For CLOB and BLOB types, you can use streams,
+      or create instances of BLOB or CLOB before assigning them to the
+      parameters. You can even use CLOB or BLOB objects returned from
+      connections to other RDBMS servers. The Connection.createBlob() and
+      createClob() methods can be used to create the new LOBs. For very large
+      LOB's the stream methods are preferable as they use less memory.</p>
+<p>For array parameters, you must use a java.sql.Array object that
+      contains the array elements before assigning to JDBC parameters. The
+      Connection.createArrayOf(...) method can be used to create a new object,
+      or you can use an Array returned from connections to other RDBMS
+      servers.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A68"></a>JDBC Returned Values</h3>
+</div>
+</div>
+</div>
+<p>The methods of the JDBC ResultSet interface can be used to return
+      values and to convert value to different types as supported by the JDBC
+      specification.</p>
+<p>When a CLOB and BLOB object is returned from a ResultSet, no data
+      is transferred until the data is read by various methods of
+      java.sql.CLOB and java.sql.BLOB. Data is streamed in large blocks to
+      avoid excessive memory use.</p>
+<p>Array objects are returned as instances of java.sql.Array.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N11A71"></a>Syntax Elements</h2>
+</div>
+</div>
+</div>
+<p>The syntax elements that can be used in data access and data change
+    statements are described in this section. The SQL Standard has a very
+    extensive set of definitions for these elements. The BNF definitions given
+    here are sometimes simplified.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A76"></a>Literals</h3>
+</div>
+</div>
+</div>
+<p>Literals are used to express constant values. The general type of
+      a literal is known by its format. The specific type is based on
+      conventions.</p>
+<a name="N11A7B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>unicode escape
+      elements</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>unicode escape elements</em></span>
+</p>
+<p>
+<code class="literal">&lt;Unicode escape specifier&gt; ::= [ UESCAPE
+      &lt;quote&gt;&lt;Unicode escape character&gt;&lt;quote&gt; ]
+      </code>
+</p>
+<p>
+<code class="literal">&lt;Unicode escape value&gt; ::= &lt;Unicode 4 digit
+      escape value&gt; | &lt;Unicode 6 digit escape value&gt; | &lt;Unicode
+      character escape value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode 4 digit escape value&gt; ::= &lt;Unicode
+      escape
+      character&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode 6 digit escape value&gt; ::= &lt;Unicode
+      escape character&gt;&lt;plus sign&gt;
+      &lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode character escape value&gt; ::= &lt;Unicode
+      escape character&gt;&lt;Unicode escape character&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode escape character&gt; ::= a single
+      character than a &lt;hexit&gt; (a-f, A-F, 0-9), &lt;plus sign&gt;,
+      &lt;quote&gt;, &lt;double quote&gt;, or &lt;white
+      space&gt;</code>
+</p>
+<a name="N11A99" class="indexterm"></a>
+<p>
+<span class="bold"><strong>character literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>character literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;character string literal&gt; ::= [
+      &lt;introducer&gt;&lt;character set specification&gt; ] &lt;quote&gt; [
+      &lt;character representation&gt;... ] &lt;quote&gt; [ {
+      &lt;separator&gt; &lt;quote&gt; [ &lt;character representation&gt;... ]
+      &lt;quote&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;introducer&gt; ::=
+      &lt;underscore&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;character representation&gt; ::= &lt;nonquote
+      character&gt; | &lt;quote symbol&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;nonquote character&gt; ::= any character apart
+      from the quote symbol.</code>
+</p>
+<p>
+<code class="literal">&lt;quote symbol&gt; ::=
+      &lt;quote&gt;&lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;national character string literal&gt; ::= N
+      &lt;quote&gt; [ &lt;character representation&gt;... ] &lt;quote&gt; [ {
+      &lt;separator&gt; &lt;quote&gt; [ &lt;character representation&gt;... ]
+      &lt;quote&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode character string literal&gt; ::= [
+      &lt;introducer&gt;&lt;character set specification&gt; ]
+      U&lt;ampersand&gt;&lt;quote&gt; [ &lt;Unicode representation&gt;... ]
+      &lt;quote&gt; [ { &lt;separator&gt; &lt;quote&gt; [ &lt;Unicode
+      representation&gt;... ] &lt;quote&gt; }... ] &lt;Unicode escape
+      specifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode representation&gt; ::= &lt;character
+      representation&gt; | &lt;Unicode escape value&gt;</code>
+</p>
+<p>The type of a character literal is CHARACTER. The length of the
+      string literal is the character length of the type. If the quote
+      character is used in a string, it is represented with two quote
+      characters. Long literals can be divided into multiple quoted strings,
+      separated with a space or end-of-line character.</p>
+<p>Unicode literals start with U&amp; and can contain ordinary
+      characters and unicode escapes. A unicode escape begins with the
+      backslash ( \ ) character and is followed by four hexadecimal characters
+      which specify the character code.</p>
+<p>Example of character literals are given below:</p>
+<pre class="programlisting">'a literal'  ' string seperated'  ' into parts'
+'a string''s literal form with quote character'
+U&amp;'Unicode string with Greek delta \0394 and phi \03a6 letters'
+</pre>
+<a name="N11AC5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>binary literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>binary literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;binary string literal&gt; ::= X &lt;quote&gt; [
+      &lt;space&gt;... ] [ { &lt;hexit&gt; [ &lt;space&gt;... ] &lt;hexit&gt;
+      [ &lt;space&gt;... ] }... ] &lt;quote&gt; [ { &lt;separator&gt;
+      &lt;quote&gt; [ &lt;space&gt;... ] [ { &lt;hexit&gt; [ &lt;space&gt;...
+      ] &lt;hexit&gt; [ &lt;space&gt;... ] }... ] &lt;quote&gt; }...
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;hexit&gt; ::= &lt;digit&gt; | A | B | C | D | E |
+      F | a | b | c | d | e | f</code>
+</p>
+<p>The type of a binary literal is BINARY. The octect length of
+      the binary literal is the length of the type. Case-insensitive
+      hexadecimal characters are used in the binary string. Each pair of
+      characters in the literal represents a byte in the binary string. Long
+      literals can be divided into multiple quoted strings, separated with a
+      space or end-of-line character.</p>
+<pre class="programlisting">X'1abACD34' 'Af'</pre>
+<a name="N11ADB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>bit literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>bit literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;bit string literal&gt; ::= B &lt;quote&gt; [
+      &lt;bit&gt; ... ] &lt;quote&gt; [ { &lt;separator&gt; &lt;quote&gt; [
+      &lt;bit&gt;... ] &lt;quote&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;bit&gt; ::= 0 | 1</code>
+</p>
+<p>The type of a binary literal is BIT. The bit length of the bit
+      literal is the length of the type. Digits 0 and 1 are used to represent
+      the bits. Long literals can be divided into multiple quoted strings,
+      separated with a space or end-of-line character.</p>
+<pre class="programlisting">B'10001001' '00010'</pre>
+<a name="N11AF1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>numeric literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>numeric literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;signed numeric literal&gt; ::= [ &lt;sign&gt; ]
+      &lt;unsigned numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unsigned numeric literal&gt; ::= &lt;exact numeric
+      literal&gt; | &lt;approximate numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;exact numeric literal&gt; ::= &lt;unsigned
+      integer&gt; [ &lt;period&gt; [ &lt;unsigned integer&gt; ] ] |
+      &lt;period&gt; &lt;unsigned integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sign&gt; ::= &lt;plus sign&gt; | &lt;minus
+      sign&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;approximate numeric literal&gt; ::=
+      &lt;mantissa&gt; E &lt;exponent&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;mantissa&gt; ::= &lt;exact numeric
+      literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;exponent&gt; ::= &lt;signed
+      integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;signed integer&gt; ::= [ &lt;sign&gt; ]
+      &lt;unsigned integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unsigned integer&gt; ::=
+      &lt;digit&gt;...</code>
+</p>
+<p>The type of an exact numeric literal without a decimal point is
+      INTEGER, BIGINT, or DECIMAL, depending on the value of the literal (the
+      smallest type that can represent the value is the type).</p>
+<p>The type of an exact numeric literal with a decimal point is
+      DECIMAL. The precision of a decimal literal is the total number of
+      digits of the literal. The scale of the literal is the total number of
+      digits to the right of the decimal point.</p>
+<p>The type of an approximate numeric literal is DOUBLE. An
+      approximate numeric literal always includes the mantissa and exponent,
+      separated by E.</p>
+<pre class="programlisting">12
+34.35
++12E-2
+</pre>
+<a name="N11B20" class="indexterm"></a>
+<p>
+<span class="bold"><strong>boolean literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>boolean literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;boolean literal&gt; ::= TRUE | FALSE |
+      UNKNOWN</code>
+</p>
+<p>The boolean literal is one of the specified keywords.</p>
+<a name="N11B31" class="indexterm"></a>
+<p>
+<span class="bold"><strong>datetime and interval
+      literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>datetime and interval literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;datetime literal&gt; ::= &lt;date literal&gt; |
+      &lt;time literal&gt; | &lt;timestamp literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;date literal&gt; ::= DATE &lt;date
+      string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time literal&gt; ::= TIME &lt;time
+      string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;timestamp literal&gt; ::= TIMESTAMP &lt;timestamp
+      string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;date string&gt; ::= &lt;quote&gt; &lt;unquoted
+      date string&gt; &lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time string&gt; ::= &lt;quote&gt; &lt;unquoted
+      time string&gt; &lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;timestamp string&gt; ::= &lt;quote&gt;
+      &lt;unquoted timestamp string&gt; &lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time zone interval&gt; ::= &lt;sign&gt; &lt;hours
+      value&gt; &lt;colon&gt; &lt;minutes value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;date value&gt; ::= &lt;years value&gt; &lt;minus
+      sign&gt; &lt;months value&gt; &lt;minus sign&gt; &lt;days
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time value&gt; ::= &lt;hours value&gt;
+      &lt;colon&gt; &lt;minutes value&gt; &lt;colon&gt; &lt;seconds
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval literal&gt; ::= INTERVAL [ &lt;sign&gt; ]
+      &lt;interval string&gt; &lt;interval qualifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval string&gt; ::= &lt;quote&gt; &lt;unquoted
+      interval string&gt; &lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unquoted date string&gt; ::= &lt;date
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unquoted time string&gt; ::= &lt;time value&gt; [
+      &lt;time zone interval&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;unquoted timestamp string&gt; ::= &lt;unquoted
+      date string&gt; &lt;space&gt; &lt;unquoted time
+      string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unquoted interval string&gt; ::= [ &lt;sign&gt; ]
+      { &lt;year-month literal&gt; | &lt;day-time literal&gt;
+      }</code>
+</p>
+<p>
+<code class="literal">&lt;year-month literal&gt; ::= &lt;years value&gt; [
+      &lt;minus sign&gt; &lt;months value&gt; ] | &lt;months
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;day-time literal&gt; ::= &lt;day-time interval&gt;
+      | &lt;time interval&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;day-time interval&gt; ::= &lt;days value&gt; [
+      &lt;space&gt; &lt;hours value&gt; [ &lt;colon&gt; &lt;minutes value&gt;
+      [ &lt;colon&gt; &lt;seconds value&gt; ] ] ]</code>
+</p>
+<p>
+<code class="literal">&lt;time interval&gt; ::= &lt;hours value&gt; [
+      &lt;colon&gt; &lt;minutes value&gt; [ &lt;colon&gt; &lt;seconds
+      value&gt; ] ] | &lt;minutes value&gt; [ &lt;colon&gt; &lt;seconds
+      value&gt; ] | &lt;seconds value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;years value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;months value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;days value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;hours value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;minutes value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;seconds value&gt; ::= &lt;seconds integer
+      value&gt; [ &lt;period&gt; [ &lt;seconds fraction&gt; ]
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;seconds integer value&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;seconds fraction&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;datetime value&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>The type of a datetime or interval type is specified in the
+      literal. The fractional second precision is the number of digits in the
+      fractional part of the literal. Details are described in the <a class="link" href="sqlgeneral-chapt.html" title="Chapter&nbsp;2.&nbsp;SQL Language">SQL Language</a>
+      chapter</p>
+<pre class="programlisting">DATE '2008-08-08'
+TIME '20:08:08'
+TIMESTAMP '2008-08-08 20:08:08.235'
+
+INTERVAL '10' DAY
+INTERVAL -'08:08' MINUTE TO SECOND
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11B9C"></a>References, etc.</h3>
+</div>
+</div>
+</div>
+<p>References are identifier chains, which can be a single
+      identifiers or identifiers chains composed of single identifiers chained
+      together with the period symbol.</p>
+<a name="N11BA1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>identifier chain</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>identifier chain</em></span>
+</p>
+<p>
+<code class="literal">&lt;identifier chain&gt; ::= &lt;identifier&gt; [ {
+      &lt;period&gt; &lt;identifier&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;basic identifier chain&gt; ::= &lt;identifier
+      chain&gt;</code>
+</p>
+<p>A period-separated chain of identifiers. The identifiers in an
+      identifier chain can refer to database objects in a hierarchy. The
+      possible hierarchies are as follows. In each hierarchy, elements from
+      the start or the end can be missing, but the order of elements cannot be
+      changed.</p>
+<p>catalog, schema, database object</p>
+<p>catalog, schema, table, column</p>
+<p>correlation name, column</p>
+<p>Examples of identifier chain are given below:</p>
+<pre class="programlisting">SELECT MYCAT.MYSCHEMA.MYTABLE.MYCOL FROM MYCAT.MYSCHEMA.MYTABLE
+DROP TABLE MYCAT.MYSCHEMA.MYTABLE CASCADE
+ALTER SEQUENCE MYCAT.MYSCHEMA.MYSEQUENCE RESTART WITH 100
+</pre>
+<a name="N11BBF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>column reference</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>column reference</em></span>
+</p>
+<p>
+<code class="literal">&lt;column reference&gt; ::= &lt;basic identifier
+      chain&gt; | MODULE &lt;period&gt; &lt;qualified identifier&gt;
+      &lt;period&gt; &lt;column name&gt;</code>
+</p>
+<p>Reference a column or a routine variable.</p>
+<a name="N11BD0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQL parameter
+      reference</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL parameter reference</em></span>
+</p>
+<p>
+<code class="literal">&lt;SQL parameter reference&gt; ::= &lt;basic
+      identifier chain&gt;</code>
+</p>
+<p>Reference an SQL routine parameter.</p>
+<a name="N11BE1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>contextually typed value
+      specification</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>contextually typed value
+      specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;contextually typed value specification&gt; ::=
+      &lt;null specification&gt; | &lt;default
+      specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;null specification&gt; ::=
+      NULL</code>
+</p>
+<p>
+<code class="literal">&lt;default specification&gt; ::=
+      DEFAULT</code>
+</p>
+<p>Specify a value whose data type or value is inferred from its
+      context. DEFAULT is used for assignments to table columns that have a
+      default value, or to table columns that are generated either as an
+      IDENTITY value or as an expression. NULL can be used only in a context
+      where the type of the value is known. For example, a NULL can be
+      assigned to a column of the table in an INSERT or UPDATE statement,
+      because the type of the column is known. But if NULL is used in a SELECT
+      list, it must be used in a CAST statement.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11BF8"></a>Value Expression</h3>
+</div>
+</div>
+</div>
+<p>Value expression is a general name for all expressions that return
+      a value. Different types of expressions are allowed in different
+      contexts.</p>
+<a name="N11BFD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>value expression
+      primary</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>value expression primary</em></span>
+</p>
+<p>
+<code class="literal">&lt;value expression primary&gt; ::= &lt;parenthesized
+      value expression&gt; | &lt;nonparenthesized value expression
+      primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;parenthesized value expression&gt; ::= &lt;left
+      paren&gt; &lt;value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;nonparenthesized value expression primary&gt; ::=
+      &lt;unsigned value specification&gt; | &lt;column reference&gt; |
+      &lt;set function specification&gt; | &lt;scalar subquery&gt; | &lt;case
+      expression&gt; | &lt;cast specification&gt; | &lt;next value
+      expression&gt; | &lt;routine invocation&gt;</code>
+</p>
+<p>Specify a value that is syntactically self-delimited.</p>
+<a name="N11C14" class="indexterm"></a>
+<p>
+<span class="bold"><strong>value specification</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>value specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;value specification&gt; ::= &lt;literal&gt; |
+      &lt;general value specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unsigned value specification&gt; ::= &lt;unsigned
+      literal&gt; | &lt;general value specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;target specification&gt; ::= &lt;host parameter
+      specification&gt; | &lt;SQL parameter reference&gt; | &lt;column
+      reference&gt; | &lt;dynamic parameter
+      specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;simple target specification&gt; ::= &lt;host
+      parameter specification&gt; | &lt;SQL parameter reference&gt; |
+      &lt;column reference&gt; | &lt;embedded variable
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;host parameter specification&gt; ::= &lt;host
+      parameter name&gt; [ &lt;indicator parameter&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;dynamic parameter specification&gt; ::=
+      &lt;question mark&gt;</code>
+</p>
+<p>Specify one or more values, host parameters, SQL parameters,
+      dynamic parameters, or host variables.</p>
+<a name="N11C34" class="indexterm"></a>
+<p>
+<span class="bold"><strong>row value expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>row value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;row value expression&gt; ::= &lt;row value special
+      case&gt; | &lt;explicit row value constructor&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;row value predicand&gt; ::= &lt;row value special
+      case&gt; | &lt;row value constructor predicand&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;row value special case&gt; ::=
+      &lt;nonparenthesized value expression primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;explicit row value constructor&gt; ::= &lt;left
+      paren&gt; &lt;row value constructor element&gt; &lt;comma&gt; &lt;row
+      value constructor element list&gt; &lt;right paren&gt;
+      |</code>
+</p>
+<p>
+<code class="literal"> ROW &lt;left paren&gt; &lt;row value constructor
+      element list&gt; &lt;right paren&gt; | &lt;row
+      subquery&gt;</code>
+</p>
+<p>Specify a row consisting of one or more elements. A comma
+      separated list of expressions, enclosed in brackets, with the optional
+      keyword ROW. In SQL, a row containing a single element can often be used
+      where a single value is expected.</p>
+<a name="N11C51" class="indexterm"></a>
+<p>
+<span class="bold"><strong>set function
+      specification</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set function specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;set function specification&gt; ::= &lt;aggregate
+      function&gt; | &lt;grouping operation&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;grouping operation&gt; ::= GROUPING &lt;left
+      paren&gt; &lt;column reference&gt; [ { &lt;comma&gt; &lt;column
+      reference&gt; }... ] &lt;right paren&gt;</code>
+</p>
+<p>Specify a value derived by the application of a function to an
+      argument. Early releases of HyperSQL 2.0 do not support
+      <code class="literal">&lt;grouping operation&gt;</code> .</p>
+<a name="N11C68" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COALESCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>coalesce expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;coalesce expression&gt; := COALESCE &lt;left
+      paren&gt; &lt;value expression&gt; { &lt;comma&gt; &lt;value
+      expression&gt; }... &lt;right paren&gt;</code>
+</p>
+<p>Replace null values with another value. The coalesce expression
+      has two or more instances of &lt;value expression&gt;. If the first
+      &lt;value expression&gt; evaluates to a non-null value, it is returned
+      as the result of the coalesce expression. If it is null, the next
+      <code class="literal">&lt;value expression&gt;</code> is evaluated and if it
+      evaluates to a non-non value, it is returned, and so on.</p>
+<p>The type of the return value of a COALESCE expression is the
+      aggregate type of the types of all the <code class="literal">&lt;value
+      expression&gt;</code> instances. Therefore, any value returned is
+      implicitly cast to this type. HyperSQL also features built-in functions
+      with similar functionality.</p>
+<a name="N11C81" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NULLIF</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>nullif expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;nullif expression&gt; := NULLIF &lt;left paren&gt;
+      &lt;value expression&gt; &lt;comma&gt; &lt;value expression&gt;
+      &lt;right paren&gt;</code>
+</p>
+<p>Return NULL if two values are equal. If the result of the first
+      <code class="literal">&lt;value expression&gt;</code> is not equal to the result
+      of the second, then it is returned, otherwise NULL is returned. The type
+      of the return value is the type of the first <code class="literal">&lt;value
+      expression&gt;</code>.</p>
+<pre class="programlisting">SELECT i, NULLIF(n, 'not defined') FROM t</pre>
+<a name="N11C9A" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CASE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>case specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;case specification&gt; ::= &lt;simple case&gt; |
+      &lt;searched case&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;simple case&gt; ::= CASE &lt;case operand&gt;
+      &lt;simple when clause&gt;... [ &lt;else clause&gt; ]
+      END</code>
+</p>
+<p>
+<code class="literal">&lt;searched case&gt; ::= CASE &lt;searched when
+      clause&gt;... [ &lt;else clause&gt; ] END</code>
+</p>
+<p>
+<code class="literal">&lt;simple when clause&gt; ::= WHEN &lt;when operand
+      list&gt; THEN &lt;result&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;searched when clause&gt; ::= WHEN &lt;search
+      condition&gt; THEN &lt;result&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;else clause&gt; ::= ELSE
+      &lt;result&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;case operand&gt; ::= &lt;row value predicand&gt; |
+      &lt;overlaps predicate part 1&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;when operand list&gt; ::= &lt;when operand&gt; [ {
+      &lt;comma&gt; &lt;when operand&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;when operand&gt; ::= &lt;row value predicand&gt; |
+      &lt;comparison predicate part 2&gt; | &lt;between predicate part 2&gt; |
+      &lt;in predicate part 2&gt; | &lt;character like predicate part 2&gt; |
+      &lt;octet like predicate part 2&gt; | &lt;similar predicate part 2&gt; |
+      &lt;regex like predicate part 2&gt; | &lt;null predicate part 2&gt; |
+      &lt;quantified comparison predicate part 2&gt; | &lt;match predicate
+      part 2&gt; | &lt;overlaps predicate part 2&gt; | &lt;distinct predicate
+      part 2&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;result&gt; ::= &lt;result expression&gt; |
+      NULL</code>
+</p>
+<p>
+<code class="literal">&lt;result expression&gt; ::= &lt;value
+      expression&gt;</code>
+</p>
+<p>Specify a conditional value. The result of a case expression is
+      always a value. All the values introduced with THEN must be of the same
+      type.</p>
+<p>An (simple) example of the CASE statement is given below. It
+      returns 'Britain', 'Germany', or 'Other country' depending on the value
+      of dialcode'</p>
+<pre class="programlisting">CASE dialcode WHEN 44 THEN 'Britain' WHEN 49 THEN 'Germany' ELSE 'Other country' END</pre>
+<p>The case statement can be far more complex and involve several
+      conditions.</p>
+<a name="N11CCF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CAST</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>cast specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;cast specification&gt; ::= CAST &lt;left paren&gt;
+      &lt;cast operand&gt; AS &lt;cast target&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;cast operand&gt; ::= &lt;value expression&gt; |
+      &lt;implicitly typed value specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;cast target&gt; ::= &lt;domain name&gt; | &lt;data
+      type&gt;</code>
+</p>
+<p>Specify a data conversion. Data conversion takes place
+      automatically among variants of a general type. For example numeric
+      values are freely converted from one type to another in
+      expressions.</p>
+<p>Explicit type conversion is necessary in two cases. One case is
+      to determine the type of a NULL value. The other case is to force
+      conversion for special purposes. Values of data types can be cast to a
+      character type. The exception is BINARY and OTHER types. The result of
+      the cast is the literal expression of the value. Conversely, a value of
+      a character type can be converted to another type if the character value
+      is a literal representation of the value in the target type. Special
+      conversions are possible between numeric and interval types, which are
+      described in the section covering interval types.</p>
+<p>The examples below show examples of cast with their
+      result:</p>
+<pre class="programlisting">CAST (NULL AS TIMESTAMP)
+CAST ('   199  ' AS INTEGER) = 199
+CAST ('tRue ' AS BOOLEAN) = TRUE
+CAST (INTERVAL '2' DAY AS INTEGER) = 2
+CAST ('1992-04-21' AS DATE) = DATE '1992-04-21'
+</pre>
+<a name="N11CEC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NEXT VALUE FOR</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>next value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;next value expression&gt; ::= NEXT VALUE FOR
+      &lt;sequence generator name&gt;</code>
+</p>
+<p>Return the next value of a sequence generator. This expression
+      can be used as a select list element in queries, or in assignments to
+      table columns in data change statements. If the expression is used more
+      than once in a single row that is being evaluated, the same value is
+      returned for each invocation. After evaluation of the particular row is
+      complete, the sequence generator will return a different value from the
+      old value. The new value is generated by the sequence generator by
+      adding the increment to the last value it generated. In the example
+      below:</p>
+<pre class="programlisting">INSERT INTO MYTABLE(COL1, COL2) VALUES 2, NEXT VALUE FOR MYSEQUENCE
+</pre>
+<a name="N11CFF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>value expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;value expression&gt; ::= &lt;numeric value
+      expression&gt; | &lt;string value expression&gt; | &lt;datetime value
+      expression&gt; | &lt;interval value expression&gt; | &lt;boolean value
+      expression&gt; | &lt;row value expression&gt;</code>
+</p>
+<p>An expression that returns a value. The value can be a single
+      value, or a row consisting more than one value.</p>
+<a name="N11D10" class="indexterm"></a>
+<p>
+<span class="bold"><strong>numeric value
+      expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>numeric value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;numeric value expression&gt; ::= &lt;term&gt; |
+      &lt;numeric value expression&gt; &lt;plus sign&gt; &lt;term&gt; |
+      &lt;numeric value expression&gt; &lt;minus sign&gt;
+      &lt;term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;term&gt; ::= &lt;factor&gt; | &lt;term&gt;
+      &lt;asterisk&gt; &lt;factor&gt; | &lt;term&gt; &lt;solidus&gt;
+      &lt;factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;factor&gt; ::= [ &lt;sign&gt; ] &lt;numeric
+      primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;numeric primary&gt; ::= &lt;value expression
+      primary&gt; | &lt;numeric value function&gt;</code>
+</p>
+<p>Specify a numeric value. The BNF indicates that
+      <code class="literal">&lt;asterisk&gt;</code> and
+      <code class="literal">&lt;solidus&gt;</code> (the operators for multiplication and
+      division) have precedence over <code class="literal">&lt;minus sign&gt;</code> and
+      <code class="literal">&lt;plus sign&gt;</code>.</p>
+<a name="N11D36" class="indexterm"></a>
+<p>
+<span class="bold"><strong>numeric value
+      function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>numeric value function</em></span>
+</p>
+<p>
+<code class="literal">&lt;numeric value function&gt; ::= &lt;position
+      expression&gt; | &lt;extract expression&gt; | &lt;length expression&gt;
+      ...</code>
+</p>
+<p>Specify a function yielding a value of type numeric. The
+      supported numeric value functions are listed and described in the <a class="link" href="builtinfunctions-chapt.html" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+<a name="N11D4B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>string value
+      expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>string value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;string value expression&gt; ::= &lt;string
+      concatenation&gt; | &lt;string factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;string factor&gt; ::= &lt;value expression
+      primary&gt; | &lt;string value function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;string concatenation&gt; ::= &lt;string value
+      expression&gt; &lt;concatenation operator&gt; &lt;string
+      factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;concatenation operator&gt; ::=
+      ||</code>
+</p>
+<p>Specify a character string value, a binary string value, or a
+      bit string value. The BNF indicates that a string value expression can
+      be formed by concatenation of two or more <code class="literal">&lt;value expression
+      primary&gt;</code>. The types of the <code class="literal">&lt;value expression
+      primary&gt;</code> elements must be compatible, that is, all must be
+      string, or binary or bit string values.</p>
+<a name="N11D6B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>character value
+      function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>string value function</em></span>
+</p>
+<p>
+<code class="literal">&lt;string value function&gt; ::=
+      ...</code>
+</p>
+<p>Specify a function that returns a character string or binary
+      string. The supported character value functions are listed and described
+      in the <a class="link" href="builtinfunctions-chapt.html" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+<a name="N11D80" class="indexterm"></a>
+<p>
+<span class="bold"><strong>datetime value
+      expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>datetime value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;datetime value expression&gt; ::= &lt;datetime
+      term&gt; | &lt;interval value expression&gt; &lt;plus sign&gt;
+      &lt;datetime term&gt; | &lt;datetime value expression&gt; &lt;plus
+      sign&gt; &lt;interval term&gt; | &lt;datetime value expression&gt;
+      &lt;minus sign&gt; &lt;interval term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;datetime term&gt; ::= &lt;datetime
+      factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;datetime factor&gt; ::= &lt;datetime primary&gt; [
+      &lt;time zone&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;datetime primary&gt; ::= &lt;value expression
+      primary&gt; | &lt;datetime value function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time zone&gt; ::= AT &lt;time zone
+      specifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time zone specifier&gt; ::= LOCAL | TIME ZONE
+      &lt;interval primary&gt;</code>
+</p>
+<p>Specify a datetime value. Details are described in the <a class="link" href="sqlgeneral-chapt.html" title="Chapter&nbsp;2.&nbsp;SQL Language">SQL Language</a>
+      chapter.</p>
+<a name="N11DA4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>datetime value
+      function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>datetime value function</em></span>
+</p>
+<p>
+<code class="literal">&lt;datetime value function&gt; ::=
+      ...</code>
+</p>
+<p>Specify a function that returns a datetime value. The supported
+      datetime value functions are listed and described in the <a class="link" href="builtinfunctions-chapt.html" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+<a name="N11DBA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>interval term</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>interval value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;interval value expression&gt; ::= &lt;interval
+      term&gt; | &lt;interval value expression 1&gt; &lt;plus sign&gt;
+      &lt;interval term 1&gt; | &lt;interval value expression 1&gt; &lt;minus
+      sign&gt; &lt;interval term 1&gt; | &lt;left paren&gt; &lt;datetime value
+      expression&gt; &lt;minus sign&gt; &lt;datetime term&gt; &lt;right
+      paren&gt; &lt;interval qualifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval term&gt; ::= &lt;interval factor&gt; |
+      &lt;interval term 2&gt; &lt;asterisk&gt; &lt;factor&gt; | &lt;interval
+      term 2&gt; &lt;solidus&gt; &lt;factor&gt; | &lt;term&gt;
+      &lt;asterisk&gt; &lt;interval factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval factor&gt; ::= [ &lt;sign&gt; ]
+      &lt;interval primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval primary&gt; ::= &lt;value expression
+      primary&gt; [ &lt;interval qualifier&gt; ] | &lt;interval value
+      function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval value expression 1&gt; ::= &lt;interval
+      value expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval term 1&gt; ::= &lt;interval
+      term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval term 2&gt; ::= &lt;interval
+      term&gt;</code>
+</p>
+<p>Specify an interval value. Details are described in the <a class="link" href="sqlgeneral-chapt.html" title="Chapter&nbsp;2.&nbsp;SQL Language">SQL Language</a>
+      chapter.</p>
+<a name="N11DE1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>interval absolute value
+      function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>interval value function</em></span>
+</p>
+<p>
+<code class="literal">&lt;interval value function&gt; ::= &lt;interval
+      absolute value function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval absolute value function&gt; ::= ABS
+      &lt;left paren&gt; &lt;interval value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>Specify a function that returns the absolute value of an
+      interval. If the interval is negative, it is negated, otherwise the
+      original value is returned.</p>
+<a name="N11DF5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>boolean value
+      expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>boolean value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;boolean value expression&gt; ::= &lt;boolean
+      term&gt; | &lt;boolean value expression&gt; OR &lt;boolean
+      term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;boolean term&gt; ::= &lt;boolean factor&gt; |
+      &lt;boolean term&gt; AND &lt;boolean factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;boolean factor&gt; ::= [ NOT ] &lt;boolean
+      test&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;boolean test&gt; ::= &lt;boolean primary&gt; [ IS
+      [ NOT ] &lt;truth value&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;truth value&gt; ::= TRUE | FALSE |
+      UNKNOWN</code>
+</p>
+<p>
+<code class="literal">&lt;boolean primary&gt; ::= &lt;predicate&gt; |
+      &lt;boolean predicand&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;boolean predicand&gt; ::= &lt;parenthesized
+      boolean value expression&gt; | &lt;nonparenthesized value expression
+      primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;parenthesized boolean value expression&gt; ::=
+      &lt;left paren&gt; &lt;boolean value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>Specify a boolean value.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11E1B"></a>Predicates</h3>
+</div>
+</div>
+</div>
+<p>Predicates are conditions with two sides and evaluate to a
+      boolean value. The left side of the predicate, the <code class="literal">&lt;row
+      value predicand&gt;</code>, is the common element of all predicates.
+      This element is a generalisation of both <code class="literal">&lt;value
+      expression&gt;</code>, which is a scalar, and of
+      <code class="literal">&lt;explicit row value constructor&gt;</code>, which is a
+      row. The two sides of a predicate can be split in CASE statements where
+      the <code class="literal">&lt;row value predicand&gt;</code> is part of multiple
+      predicates.</p>
+<p>The number of fields in all <code class="literal">&lt;row value
+      predicand&gt;</code> used in predicates must be the same and the
+      types of the fields in the same position must be compatible for
+      comparison. If either of these conditions does not hold, an exception is
+      raised. The number of fields in a row is called the
+      <em class="glossterm">degree</em>.</p>
+<p>In many types of predicates (but not all of them), if the
+      <code class="literal">&lt;row value predicand&gt;</code> evaluates to NULL, the
+      result of the predicate is UNKNOWN. If the <code class="literal">&lt;row value
+      predicand&gt;</code> has more than one element, and one or more of
+      the fields evaluate to NULL, the result depends on the particular
+      predicate.</p>
+<a name="N11E3C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>comparison predicand</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>comparison predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;comparison predicate&gt; ::= &lt;row value
+      predicand&gt; &lt;comp op&gt; &lt;row value
+      predicand&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;comp op&gt; ::= &lt;equals operator&gt; | &lt;not
+      equals operator&gt; | &lt;less than operator&gt; | &lt;greater than
+      operator&gt; | &lt;less than or equals operator&gt; | &lt;greater than
+      or equals operator&gt;</code>
+</p>
+<p>Specify a comparison of two row values. If either
+      <code class="literal">&lt;row value predicand&gt;</code> evaluates to NULL, the
+      result of <code class="literal">&lt;comparison predicate&gt;</code> is UNKNOWN.
+      Otherwise, the result is TRUE, FALSE or UNKNOWN.</p>
+<p>If the <em class="glossterm">degree</em> of <code class="literal">&lt;row value
+      predicand&gt;</code> is larger than one, comparison is performed
+      between each field and the corresponding field in the other
+      <code class="literal">&lt;row value predicand&gt;</code> from left to right, one
+      by one.</p>
+<p>When comparing two elements, if either field is NULL then the
+      result is UNKNOWN.</p>
+<p>For <code class="literal">&lt;equals operator&gt;</code>, if the result
+      of comparison is TRUE for all field, the result of the predicate is
+      TRUE. If the result of comparison is FALSE for one field, the result of
+      predicate is FALSE. Otherwise the result is UNKNOWN.</p>
+<p>The <code class="literal">&lt;not equals operator&gt;</code> is
+      translated to <code class="literal">NOT (&lt;row value predicand&gt; = &lt;row value
+      predicand&gt;)</code>.</p>
+<p>The <code class="literal">&lt;less than or equals operator&gt;</code> is
+      translated to <code class="literal">(&lt;row value predicand&gt; = &lt;row value
+      predicand&gt;) OR (&lt;row value predicand&gt; &lt; &lt;row value
+      predicand&gt;)</code>. The <code class="literal">&lt;greater than or equals
+      operator&gt;</code> is translated similarly.</p>
+<p>For the <code class="literal">&lt;less than operator&gt;</code> and
+      <code class="literal">&lt;greater than operator&gt;</code>, if two fields at a
+      given position are equal, then comparison continues to the next field.
+      Otherwise, the result of the last performed comparison is returned as
+      the result of the predicate. This means that if the first field is NULL,
+      the result is always UNKNOWN.</p>
+<p>The logic that governs NULL values and UNKNOWN result is as
+      follows: Suppose the NULL values were substituted by arbitrary real
+      values. If substitution cannot change the result of the predicate, then
+      the result is TRUE or FALSE, based on the existing non-NULL values,
+      otherwise the result of the predicate is UNKNOWN.</p>
+<p>The examples of comparison given below use literals, but the
+      literals actually represent the result of evaluation of some
+      expression.</p>
+<pre class="programlisting">((1, 2, 3, 4) = (1, 2, 3, 4)) IS TRUE
+((1, 2, 3, 4) = (1, 2, 3, 5)) IS FALSE
+((1, 2, 3, 4) &lt; (1, 2, 3, 4)) IS FALSE
+((1, 2, 3, 4) &lt; (1, 2, 3, 5)) IS TRUE
+((NULL, 1, NULL) = (NULL, 1, NULL)) IS UNKNOWN  
+((NULL, 1, NULL) = (NULL, 2, NULL)) IS FALSE  
+((NULL, 1, NULL) &lt;&gt; (NULL, 2, NULL)) IS TRUE  
+((NULL, 1, 2) &lt;all operators&gt; (NULL, 1, 2)) IS UNKNOWN
+((1, NULL, ...) &lt; (1, 2, ...)) IS UNKNOWN  
+((1, NULL, ...) &lt; (2, NULL, ...)) IS TRUE
+((2, NULL, ...) &lt; (1, NULL, ...)) IS FALSE
+</pre>
+<a name="N11E89" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BETWEEN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>between predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;between predicate&gt; ::= &lt;row value
+      predicand&gt; &lt;between predicate part 2&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;between predicate part 2&gt; ::= [ NOT ] BETWEEN [
+      ASYMMETRIC | SYMMETRIC ] &lt;row value predicand&gt; AND &lt;row value
+      predicand&gt;</code>
+</p>
+<p>Specify a range comparison. The default is ASYMMETRIC. The
+      expression <code class="literal">X BETWEEN Y AND Z</code> is equivalent to
+      <code class="literal">(X &gt;= Y AND X &lt;= Z)</code>. Therefore if Y &gt; Z, the
+      BETWEEN expression is never true. The expression <code class="literal">X BETWEEN
+      SYMMETRIC Y AND Z</code> is equivalent to <code class="literal">(X &gt;= Y AND X
+      &lt;= Z) OR (X &gt;= Z AND X &lt;= Y)</code>. The expression
+      <code class="literal">Z NOT BETWEEN ...</code> is equivalent to <code class="literal">NOT (Z
+      BETWEEN ...)</code>. If any of the three <code class="literal">&lt;row value
+      predicand&gt;</code> evaluates to NULL, the result is
+      UNKNOWN.</p>
+<a name="N11EB2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>in predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;in predicate&gt; ::= &lt;row value predicand&gt; [
+      NOT ] IN &lt;in predicate value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;in predicate value&gt; ::= &lt;table subquery&gt;
+      | &lt;left paren&gt; &lt;in value list&gt; &lt;right paren&gt;
+      </code>
+</p>
+<p>
+<code class="literal">| &lt;left paren&gt; UNNEST &lt;left paren&gt;
+      &lt;array value expression&gt; &lt;right paren&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;in value list&gt; ::= &lt;row value expression&gt;
+      [ { &lt;comma&gt; &lt;row value expression&gt; }...
+      ]</code>
+</p>
+<p>Specify a quantified comparison. The expression <code class="literal">X NOT
+      IN Y is</code> equivalent to <code class="literal">NOT (X IN Y)</code>. The
+      <code class="literal">( &lt;in value list&gt; )</code> is converted into a table
+      with one or more rows. The expression <code class="literal">X IN Y</code> is
+      equivalent to <code class="literal">X = ANY Y</code>, which is a
+      <code class="literal">&lt;quantified comparison predicate&gt;</code>.</p>
+<p>If the <code class="literal">&lt;table subquery&gt;</code> returns no
+      rows, the result is FALSE. Otherwise the <code class="literal">&lt;row value
+      predicand&gt;</code> is compared one by one with each row of the
+      <code class="literal">&lt;table subquery&gt;</code>.</p>
+<p>If the comparison is TRUE for at least one row, the result is
+      TRUE. If the comparison is FALSE for all rows, the result is FALSE.
+      Otherwise the result is UNKNOWN.</p>
+<p>HyperSQL supports an extension to the SQL Standard to allow an
+      array to be used in the &lt;in predicate value&gt;. This is intended to
+      be used with prepared statements where a variable length array of values
+      can be used as the parameter value for each call. The example below
+      shows how this is used.</p>
+<pre class="programlisting">SELECT * from customer where firstname in ( UNNEST(?) )
+</pre>
+<a name="N11EEF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LIKE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>like predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;like predicate&gt; ::= &lt;character like
+      predicate&gt; | &lt;octet like predicate&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;character like predicate&gt; ::= &lt;row value
+      predicand&gt; [ NOT ] LIKE &lt;character pattern&gt; [ ESCAPE &lt;escape
+      character&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;character pattern&gt; ::= &lt;character value
+      expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;escape character&gt; ::= &lt;character value
+      expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;octet like predicate&gt; ::= &lt;row value
+      predicand&gt; [ NOT ] LIKE &lt;octet pattern&gt; [ ESCAPE &lt;escape
+      octet&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;octet pattern&gt; ::= &lt;binary value
+      expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;escape octet&gt; ::= &lt;binary value
+      expression&gt;</code>
+</p>
+<p>Specify a pattern-match comparison for character or binary
+      strings. The <code class="literal">&lt;row value predicand&gt;</code> is always a
+      <code class="literal">&lt;string value expression&gt;</code> of character or
+      binary type. The <code class="literal">&lt;character pattern&gt;</code> or
+      <code class="literal">&lt;octet pattern&gt;</code> is a <code class="literal">&lt;string value
+      expression&gt;</code> in which the underscore and percent characters
+      have special meanings. The underscore means match any one character,
+      while the percent means match a sequence of zero or more characters. The
+      <code class="literal">&lt;escape character&gt;</code> or <code class="literal">&lt;escape
+      octet&gt;</code> is also a <code class="literal">&lt;string value
+      expression&gt;</code> that evaluates to a string of exactly one
+      character length. If the underscore or the percent is required as normal
+      characters in the pattern, the specified <code class="literal">&lt;escape
+      character&gt;</code> or <code class="literal">&lt;escape octet&gt;</code> can
+      be used in the pattern before the underscore or the percent. The
+      <code class="literal">&lt;row value predicand&gt;</code> is compared with the
+      <code class="literal">&lt;character pattern&gt;</code> and the result of
+      comparison is returned. If any of the expressions in the predicate
+      evaluates to NULL, the result of the predicate is UNKNOWN. The
+      expression <code class="literal">A NOT LIKE B</code> is equivalent to <code class="literal">NOT
+      (A LIKE B)</code>. If the length of the escape is not 1 or it is used
+      in the pattern not immediately before an underscore or a percent
+      character, an exception is raised.</p>
+<a name="N11F3C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IS NULL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>null predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;null predicate&gt; ::= &lt;row value predicand&gt;
+      IS [ NOT ] NULL</code>
+</p>
+<p>Specify a test for a null value. The expression <code class="literal">X IS
+      NOT NULL</code> is NOT equivalent to <code class="literal">NOT (X IS
+      NULL)</code>if the degree of the <code class="literal">&lt;row value
+      predicand&gt;</code> is larger than 1. The rules are: If all fields
+      are null, <code class="literal">X IS NULL</code> is TRUE and <code class="literal">X IS NOT
+      NULL</code> is FALSE. If only some fields are null, both <code class="literal">X
+      IS NULL</code> and <code class="literal">X IS NOT NULL</code> are FALSE. If all
+      fields are not null, <code class="literal">X IS NULL</code> is FALSE and
+      <code class="literal">X IS NOT NULL</code> is TRUE.</p>
+<a name="N11F68" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALL and ANY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>quantified comparison predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;quantified comparison predicate&gt; ::= &lt;row
+      value predicand&gt; &lt;comp op&gt; &lt;quantifier&gt; &lt;table
+      subquery&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;quantifier&gt; ::= &lt;all&gt; |
+      &lt;some&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;all&gt; ::= ALL</code>
+</p>
+<p>
+<code class="literal">&lt;some&gt; ::= SOME | ANY</code>
+</p>
+<p>Specify a quantified comparison. For a quantified comparison,
+      the <code class="literal">&lt;row value predicand&gt;</code> is compared one by
+      one with each row of the <code class="literal">&lt;table sub
+      query&gt;</code>.</p>
+<p>If the <code class="literal">&lt;table subquery&gt;</code> returns no
+      rows, then if <code class="literal">ALL</code> is specified the result is TRUE,
+      but if <code class="literal">SOME</code> or <code class="literal">ANY</code> is specified
+      the result is FALSE.</p>
+<p>If <code class="literal">ALL</code> is specified, if the comparison is
+      TRUE for all rows, the result of the predicate is TRUE. If the
+      comparison is FALSE for at least one row, the result is FALSE. Otherwise
+      the result is UNKNOWN.</p>
+<p>If <code class="literal">SOME</code> or <code class="literal">ANY</code> is
+      specified, if the comparison is TRUE for at least one row, the result is
+      TRUE. If the comparison is FALSE for all rows, the result is FALSE.
+      Otherwise the result is UNKNOWN. Note that the IN predicate is
+      equivalent to the SOME or ANY predicate using the <code class="literal">&lt;equals
+      operator&gt;</code>.</p>
+<p>In the examples below, the date of an invoice is compared to
+      holidays in a given year. In the first example the invoice date must
+      equal one of the holidays, in the second example it must be later than
+      all holidays (later than the last holiday), in the third example it must
+      be on or after some holiday (on or after the first holiday), and in the
+      fourth example, it must be before all holidays (before the first
+      holiday).</p>
+<pre class="programlisting">invoice_date = SOME (SELECT holiday_date FROM holidays)
+invoice_date &gt; ALL (SELECT holiday_date FROM holidays)
+invoice_date &gt;= ANY (SELECT holiday_date FROM holidays)
+invoice_date &lt; ALL (SELECT holiday_date FROM holidays)
+</pre>
+<a name="N11FAA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>EXISTS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>exists predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;exists predicate&gt; ::= EXISTS &lt;table
+      subquery&gt;</code>
+</p>
+<p>Specify a test for a non-empty set. If the evaluation of
+      <code class="literal">&lt;table subquery&gt;</code> results in one or more rows,
+      then the expression is TRUE, otherwise FALSE.</p>
+<a name="N11FBE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UNIQUE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>unique predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;unique predicate&gt; ::= UNIQUE &lt;table
+      subquery&gt;</code>
+</p>
+<p>Specify a test for the absence of duplicate rows. The result of
+      the test is either TRUE or FALSE (never UNKNOWN). The rows of the
+      <code class="literal">&lt;table subquery&gt;</code> that contain one or more NULL
+      values are not considered for this test. If the rest of the rows are
+      distinct from each other, the result of the test is TRUE, otherwise it
+      is FALSE. The distinctness of rows X and Y is tested with the predicate
+      <code class="literal">X IS DISTINCT FROM Y</code>.</p>
+<a name="N11FD5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MATCH</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>match predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;match predicate&gt; ::= &lt;row value
+      predicand&gt; MATCH [ UNIQUE ] [ SIMPLE | PARTIAL | FULL ] &lt;table
+      subquery&gt;</code>
+</p>
+<p>Specify a test for matching rows. The default is MATCH SIMPLE
+      without UNIQUE. The result of the test is either TRUE or FALSE (never
+      UNKNOWN).</p>
+<p>The interpretation of NULL values is different from other
+      predicates and quite counter-intuitive. If the <code class="literal">&lt;row value
+      predicand&gt;</code> is NULL, or all of its fields are NULL, the
+      result is TRUE.</p>
+<p>Otherwise, the <code class="literal">&lt;row value predicand&gt;</code>
+      is compared with each row of the <code class="literal">&lt;table
+      subquery&gt;</code>.</p>
+<p>If SIMPLE is specified, if some field of <code class="literal">&lt;row value
+      predicate&gt;</code> is NULL, the result is TRUE. Otherwise if
+      <code class="literal">&lt;row value predicate&gt; </code>is equal to one or more
+      rows of <code class="literal">&lt;table subquery&gt;</code> the result is TRUE if
+      UNIQUE is not specified, or if UNIQUE is specified and only one row
+      matches. Otherwise the result is FALSE.</p>
+<p>If PARTIAL is specified, if the non-null values
+      <code class="literal">&lt;row value predicate&gt; </code>are equal to those in one
+      or more rows of <code class="literal">&lt;table subquery&gt;</code> the result is
+      TRUE if UNIQUE is not specified, or if UNIQUE is specified and only one
+      row matches. Otherwise the result is FALSE.</p>
+<p>If FULL is specified, if some field of <code class="literal">&lt;row value
+      predicate&gt;</code> is NULL, the result is FALSE. Otherwise if
+      <code class="literal">&lt;row value predicate&gt;</code> is equal to one or more
+      rows of <code class="literal">&lt;table subquery&gt;</code> the result is TRUE if
+      UNIQUE is not specified, or if UNIQUE is specified and only one row
+      matches.</p>
+<p>Note that MATCH can also used be used in FOREIGN KEY constraint
+      definitions. The exact meaning is described in the <a class="link" href="databaseobjects-chapt.html" title="Chapter&nbsp;4.&nbsp;Schemas and Database Objects">Schemas and Database Objects</a> chapter.</p>
+<a name="N12017" class="indexterm"></a>
+<p>
+<span class="bold"><strong>OVERLAPS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>overlaps predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;overlaps predicate&gt; ::= &lt;row value
+      predicand&gt; OVERLAPS &lt;row value predicand&gt;</code>
+</p>
+<p>Specify a test for an overlap between two datetime periods.
+      Each <code class="literal">&lt;row value predicand&gt;</code> must have two fields
+      and the fields together represent a datetime period. So the predicates
+      is always in the form <code class="literal">(X1, X2) OVERLAPS (Y1, Y2)</code>. The
+      first field is always a datetime value, while the second field is either
+      a datetime value or an interval value.</p>
+<p>If the second value is an interval value, it is replaced with
+      the sum of the datetime value and itself, for example <code class="literal">(X1, X1 +
+      X2) OVERLAPS (Y1, Y1 + Y 2)</code>.</p>
+<p>If any of the values is NULL, the result is UNKNOWN.</p>
+<p>The expression is true if there is there is any overlap between
+      the two datetime periods. In the example below, the period is compared
+      with a week long period ending yesterday.</p>
+<pre class="programlisting">(startdate, enddate) OVERLAPS (CURRENT_DATE - 7 DAY, CURRENT_DATE - 1 DAY)</pre>
+<a name="N12039" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IS DISTINCT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>is distinct predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;distinct predicate&gt; ::= &lt;row value
+      predicand&gt; IS [ NOT ] DISTINCT FROM &lt;row value
+      predicand&gt;</code>
+</p>
+<p>Specify a test of whether two row values are distinct. The
+      result of the test is either TRUE or FALSE (never UNKNOWN). The
+      <em class="glossterm">degree</em> the two <code class="literal">&lt;row value
+      predicand&gt;</code> must be the same. Each field of the first
+      <code class="literal">&lt;row value predicand&gt;</code> is compared to the field
+      of the second <code class="literal">&lt;row value predicand&gt;</code> at the same
+      position. If one field is NULL and the other is not NULL, or if the
+      elements are NOT equal, then the result of the expression is TRUE. If no
+      comparison result is TRUE, then the result of the predicate is FALSE.
+      The expression <code class="literal">X IS NOT DISTINCT FROM Y</code> is equivalent
+      to <code class="literal">NOT (X IS DISTINCT FORM Y)</code>. The following check
+      returns true if startdate is not equal to enddate. It also returns true
+      if either startdate or enddate is NULL. It returns false in other
+      cases.</p>
+<pre class="programlisting">startdate IS DISTINCT FROM enddate</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1205E"></a>Other Syntax Elements</h3>
+</div>
+</div>
+</div>
+<a name="N12061" class="indexterm"></a>
+<p>
+<span class="bold"><strong>search condition</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>search condition</em></span>
+</p>
+<p>
+<code class="literal">&lt;search condition&gt; ::= &lt;boolean value
+      expression&gt;</code>
+</p>
+<p>Specify a condition that is TRUE, FALSE, or UNKNOWN. A search
+      condition is often a predicate.</p>
+<a name="N12072" class="indexterm"></a>
+<p>
+<span class="bold"><strong>PATH</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>path specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;path specification&gt; ::= PATH &lt;schema name
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema name list&gt; ::= &lt;schema name&gt; [ {
+      &lt;comma&gt; &lt;schema name&gt; }... ]</code>
+</p>
+<p>Specify an order for searching for a user-defined SQL-invoked
+      routine. This is not currently supported by HyperSQL.</p>
+<a name="N12086" class="indexterm"></a>
+<p>
+<span class="bold"><strong>routine invocation</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>routine invocation</em></span>
+</p>
+<p>
+<code class="literal">&lt;routine invocation&gt; ::= &lt;routine name&gt;
+      &lt;SQL argument list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;routine name&gt; ::= [ &lt;schema name&gt;
+      &lt;period&gt; ] &lt;qualified identifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL argument list&gt; ::= &lt;left paren&gt; [
+      &lt;SQL argument&gt; [ { &lt;comma&gt; &lt;SQL argument&gt; }... ] ]
+      &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL argument&gt; ::= &lt;value expression&gt; |
+      &lt;target specification&gt;</code>
+</p>
+<p>Invoke an SQL-invoked routine. Examples are given in the <a class="link" href="sqlroutines-chapt.html" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">SQL-Invoked Routines</a>
+      chapter.</p>
+<a name="N120A4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COLLATE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>collate clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;collate clause&gt; ::= COLLATE &lt;collation
+      name&gt;</code>
+</p>
+<p>Specify a default collation. This is not currently supported by
+      HyperSQL</p>
+<a name="N120B5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>constraint name definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;constraint name definition&gt; ::= CONSTRAINT
+      &lt;constraint name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;constraint characteristics&gt; ::= &lt;constraint
+      check time&gt; [ [ NOT ] DEFERRABLE ] | [ NOT ] DEFERRABLE [
+      &lt;constraint check time&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;constraint check time&gt; ::= INITIALLY DEFERRED |
+      INITIALLY IMMEDIATE</code>
+</p>
+<p>Specify the name of a constraint and its characteristics. This
+      is an optional element of CONSTRAINT definition, not yet supported by
+      HyperSQL.</p>
+<a name="N120CC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>aggregate function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>aggregate function</em></span>
+</p>
+<p>
+<code class="literal">&lt;aggregate function&gt; ::= COUNT &lt;left
+      paren&gt; &lt;asterisk&gt; &lt;right paren&gt; [ &lt;filter clause&gt; ]
+      | &lt;general set function&gt; [ &lt;filter clause&gt; ]
+      </code>
+</p>
+<p>
+<code class="literal">&lt;general set function&gt; ::= &lt;set function
+      type&gt; &lt;left paren&gt; [ &lt;set quantifier&gt; ] &lt;value
+      expression&gt; &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;set function type&gt; ::= &lt;computational
+      operation&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;computational operation&gt; ::= AVG | MAX | MIN |
+      SUM | EVERY | ANY | SOME | COUNT | STDDEV_POP | STDDEV_SAMP | VAR_SAMP |
+      VAR_POP</code>
+</p>
+<p>
+<code class="literal">&lt;set quantifier&gt; ::= DISTINCT |
+      ALL</code>
+</p>
+<p>
+<code class="literal">&lt;filter clause&gt; ::= FILTER &lt;left paren&gt;
+      WHERE &lt;search condition&gt; &lt;right paren&gt;</code>
+</p>
+<p>Specify a value computed from a collection of rows. An
+      aggregate function is used exclusively in a <code class="literal">&lt;query
+      specification&gt;</code> and its use transforms a normal query into
+      an aggregate query returning a single row instead of the group of
+      multiple rows that the original query returns. For example,
+      <code class="literal">SELECT acolumn &lt;table expression&gt;</code> is a query
+      that returns the value of acolumn for all the rows the satisfy the given
+      condition. But <code class="literal">SELECT MAX(acolumn) &lt;table
+      expression&gt;</code> returns only one row, containing the largest
+      value in that column. The query <code class="literal">SELECT COUNT(*) &lt;table
+      expression&gt;</code> returns the count of rows, while
+      <code class="literal">SELECT COUNT(acolumn) &lt;table expression&gt;</code>
+      returns the count of rows where <code class="literal">acolumn IS NOT
+      NULL</code>.</p>
+<p>If the <code class="literal">&lt;table expression&gt;</code> is a grouped
+      table, the aggregate function returns the result of the
+      <code class="literal">COUNT</code> or <code class="literal">&lt;computational
+      operation&gt;</code> for each group. In this case the result has the
+      same number of rows as the original query. For example <code class="literal">SELECT
+      SUM(acolumn) &lt;table expression&gt;</code> when <code class="literal">&lt;table
+      expression&gt;</code> has a <code class="literal">GROUP BY</code> clause,
+      returns the sum of values for <code class="literal">acolumn</code> in each
+      group.</p>
+<p>The AVG and SUM operations can be performed on numeric
+      expressions only. AVG returns the average value, while SUM returns the
+      sum of all non-null values. MAX and MIN return the minimum or the
+      maximum value. If all values are NULL, the operations return NULL. The
+      <code class="literal">COUNT(*)</code> operation returns the count of all values,
+      while <code class="literal">COUNT(&lt;value expression&gt;)</code> returns the
+      count of non-NULL values.</p>
+<p>The EVERY, ANY and SOME operations can be performed on boolean
+      expressions only. EVERY returns TRUE if all the values are TRUE,
+      otherwise FALSE. ANY and SOME are the same operation and return TRUE if
+      one of the values is TRUE, otherwise it returns FALSE.</p>
+<p>The other operations perform the statistical functions
+      STDDEV_POP, STDDEV_SAMP, VAR_SAMP, VAR_POP on numeric values. NULL
+      values are ignored in calculations.</p>
+<p>User defined aggregate functions can be defined and used
+      instead of the built-in aggregate functions. Syntax and examples are
+      given in the <a class="link" href="sqlroutines-chapt.html" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">SQL-Invoked Routines</a> chapter.</p>
+<a name="N12127" class="indexterm"></a>
+<p>
+<span class="bold"><strong>sort specification
+      list</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>sort specification list</em></span>
+</p>
+<p>
+<code class="literal">&lt;sort specification list&gt; ::= &lt;value
+      expression&gt; [ASC | DESC] [NULLS FIRST | NULLS
+      LAST]</code>
+</p>
+<p>Specify a sort order. A sort operation is performed on the
+      result of a <code class="literal">&lt;query expression&gt;</code> or
+      <code class="literal">&lt;query specification&gt;</code> and sorts the result
+      according to one or more <code class="literal">&lt;value expression&gt;</code>.
+      The <code class="literal">&lt;value expression&gt;</code> is usually a single
+      column of the result, but in some cases it can be a column of the
+      <code class="literal">&lt;table expression&gt;</code> that is not used in the
+      select list.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12147"></a>Data Access Statements</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL fully supports all of SQL-92 data access statements, plus
+    some additions from SQL:2008. Due to time constraints, the current version
+    of this Guide does not cover the subject fully. You are advised to consult
+    an SQL book such as the recent O'Reilly title "SQL and Relational Theory"
+    by C. J. Date.</p>
+<p>Database queries are data access statements. The most commonly used
+    data access statement is the SELECT statement, but there are other
+    statements that perform a similar role. Data access statements access
+    tables and return result tables. The returned result tables are falsely
+    called result sets, as they are not necessarily sets of rows, but
+    multisets of rows.</p>
+<p>Result tables are formed by performing the following operations on
+    base tables and views. These operations are loosely based on Relational
+    Algebra.</p>
+<p>
+<em class="glossterm">JOIN</em> operations</p>
+<p>
+<em class="glossterm">SET</em> and <em class="glossterm">MULTISET</em>
+    operations</p>
+<p>
+<em class="glossterm">SELECTION</em>
+</p>
+<p>
+<em class="glossterm">PROJECTION</em>
+</p>
+<p>
+<em class="glossterm">COMPUTING</em>
+</p>
+<p>
+<em class="glossterm">COLUMN NAMING</em>
+</p>
+<p>
+<em class="glossterm">GROUPING</em> and
+    <em class="glossterm">AGGREGATION</em>
+</p>
+<p>
+<em class="glossterm">SELECTION AFTER GROUPING OR
+    AGGREGATION</em>
+</p>
+<p>
+<em class="glossterm">SET and MULTISET (COLLECTION)
+    OPERATIONS</em>
+</p>
+<p>
+<em class="glossterm">ORDERING</em>
+</p>
+<p>
+<em class="glossterm">SLICING</em>
+</p>
+<p>Conceptually, the operations are performed one by one in the above
+    order if they apply to the given data access statement. In the example
+    below a simple select statement is made more complex by adding various
+    operations.</p>
+<p>
+<pre class="programlisting">CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+/* in the next SELECT, no join is performed and no further operation takes place */
+SELECT * FROM atable
+/* in the next SELECT, selection is performed by the WHERE clause, with no further action */
+SELECT * FROM atable WHERE a + b = c
+/* in the next SELECT, projection is performed after the other operations */
+SELECT d, e, f FROM atable WHERE a + b = c
+/* in the next SELECT, computation is performed after projection */
+SELECT (d + e) / f FROM atable WHERE a + b = c
+/* in the next two SELECT statements, column naming is performed in different ways*/
+SELECT (a + e) / f AS calc, f AS div FROM atable WHERE a + b = c
+SELECT dcol, ecol, fcol FROM atable(acol, bcol, ccol, dcol, ecol, fcol) WHERE acol + bcol = ccol
+/* in the next SELECT, both grouping and aggregation is performed */
+SELECT d, e, SUM(f) FROM atable GROUP BY d, e
+/* in the next SELECT, selection is performed after grouping and aggregation is performed */
+SELECT d, e, SUM(f) FROM atable GROUP BY d, e HAVING SUM(f) &gt; 10
+/* in the next SELECT, a UNION is performed on two selects from the same table */
+SELECT d, e, f FROM atable WHERE d = 3 UNION SELECT a, b, c FROM atable WHERE a = 30
+/* in the next SELECT, ordering is performed */
+SELECT (a + e) / f AS calc, f AS div FROM atable WHERE a + b = c ORDER BY calc DESC, div NULLS LAST
+/* in the next SELECT, slicing is performed after ordering */
+SELECT * FROM atable WHERE a + b = c ORDER BY a FETCH 5 ROWS ONLY
+
+</pre>The next sections discuss various types of tables and
+    operations involved in data access statements.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1217F"></a>Table</h3>
+</div>
+</div>
+</div>
+<p>In data access statements, a table can be a database table (or
+      view) or an ephemeral table formed for the duration of the query. Some
+      types of table are &lt;table primary&gt; and can participate in joins
+      without the use of extra parentheses. The BNF in the Table Primary
+      section below lists different types of &lt;table primary&gt;:</p>
+<p>Tables can also be formed by specifying the values that are
+      contained in them:</p>
+<p>
+<code class="literal">&lt;table value constructor&gt; ::= VALUES &lt;row
+      value expression list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;row value expression list&gt; ::= &lt;table row
+      value expression&gt; [ { &lt;comma&gt; &lt;table row value
+      expression&gt; }... ]</code>
+</p>
+<p>In the example below a table with two rows and 3 columns is
+      constructed out of some values:</p>
+<pre class="programlisting">VALUES (12, 14, null), (10, 11, CURRENT_DATE)</pre>
+<p>When a table is used directly in a UNION or similar operation,
+      the keyword TABLE is used with the name:</p>
+<p>
+<code class="literal">&lt;explicit table&gt; ::= TABLE &lt;table or query
+      name&gt;</code>
+</p>
+<p>In the examples below, all rows of the two tables are included
+      in the union. The keyword TABLE is used in the first example. The two
+      examples below are equivalent.</p>
+<pre class="programlisting">TABLE atable UNION TABLE anothertable
+SELECT * FROM atable UNION SELECT * FROM anothertable
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12199"></a>Query Specification</h3>
+</div>
+</div>
+</div>
+<p>A query specification is a SELECT statement. It is the most common
+      form of <code class="literal">&lt;derived table&gt;</code> . A <code class="literal">&lt;table
+      expression&gt;</code> is a base table, a view or any form of allowed
+      derived table. The SELECT statement performs projection, naming,
+      computing or aggregation on the rows of the <code class="literal">&lt;table
+      expression&gt;</code> .</p>
+<p>
+<code class="literal">&lt;query specification&gt; ::= SELECT [ DISTINCT |
+      ALL ] &lt;select list&gt; &lt;table expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;select list&gt; ::= &lt;asterisk&gt; | &lt;select
+      sublist&gt; [ { &lt;comma&gt; &lt;select sublist&gt; }... ]
+      </code>
+</p>
+<p>
+<code class="literal">&lt;select sublist&gt; ::= &lt;derived column&gt; |
+      &lt;qualified asterisk&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;qualified asterisk&gt; ::= &lt;asterisked
+      identifier chain&gt; &lt;period&gt; &lt;asterisk&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;asterisked identifier chain&gt; ::= &lt;asterisked
+      identifier&gt; [ { &lt;period&gt; &lt;asterisked identifier&gt; }... ]
+      </code>
+</p>
+<p>
+<code class="literal">&lt;asterisked identifier&gt; ::=
+      &lt;identifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;derived column&gt; ::= &lt;value expression&gt; [
+      &lt;as clause&gt; ] </code>
+</p>
+<p>
+<code class="literal">&lt;as clause&gt; ::= [ AS ] &lt;column name&gt;
+      </code>
+</p>
+<p>The qualifier DISTINCT or ALL apply to the results of the SELECT
+      statement after all other operations have been performed. ALL simply
+      returns the rows, while DISTINCT compares the rows and removes the
+      duplicate ones.</p>
+<p>Projection is performed by the <code class="literal">&lt;select
+      list&gt;</code>.</p>
+<p>A single <code class="literal">&lt;asterisk&gt;</code> means all columns of
+      the <code class="literal">&lt;table expression&gt;</code> are included, in the
+      same order as they appear in the <code class="literal">&lt;table
+      expression&gt;</code>. An asterisk qualified by a table name means
+      all the columns of the qualifier table name are included.</p>
+<p>A derived column is a <code class="literal">&lt;value expression&gt;</code>,
+      optionally named with the <code class="literal">&lt;as clause&gt;</code>. A
+      <code class="literal">&lt;value expression&gt;</code> can be many things. Common
+      types include: the name of a column in the <code class="literal">&lt;table
+      expression&gt;</code>; an expression based on different columns or
+      constant values; a function call; an aggregate function; a CASE WHEN
+      expression.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N121DF"></a>Table Expression</h3>
+</div>
+</div>
+</div>
+<p>A table expression is part of the SELECT statement and consists of
+      the FROM clause with optional other clauses that performs selection (of
+      rows) and grouping from the table(s) in the FROM clause.</p>
+<p>
+<code class="literal">&lt;table expression&gt; ::= &lt;from clause&gt; [
+      &lt;where clause&gt; ] [ &lt;group by clause&gt; ] [ &lt;having
+      clause&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;from clause&gt; ::= FROM &lt;table reference&gt; [ {
+      &lt;comma&gt; &lt;table reference&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;table reference&gt; ::= &lt;table primary&gt; |
+      &lt;joined table&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;table primary&gt; ::= &lt;table or query name&gt;
+      [ [ AS ] &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived
+      column list&gt; &lt;right paren&gt; ] ] </code>
+</p>
+<p>
+<code class="literal">| &lt;derived table&gt; [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] </code>
+</p>
+<p>
+<code class="literal">| &lt;lateral derived table&gt; [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] </code>
+</p>
+<p>
+<code class="literal">| &lt;collection derived table&gt; [ AS ]
+      &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived column
+      list&gt; &lt;right paren&gt; ] </code>
+</p>
+<p>
+<code class="literal">| &lt;table function derived table&gt; [ AS ]
+      &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived column
+      list&gt; &lt;right paren&gt; ] </code>
+</p>
+<p>
+<code class="literal">| &lt;parenthesized joined
+      table&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;where clause&gt; ::= WHERE &lt;boolean value
+      expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;group by clause&gt; ::= GROUP BY [ &lt;set
+      quantifier&gt; ] &lt;grouping element&gt; [ { &lt;comma&gt; &lt;grouping
+      element&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;having clause&gt; ::= HAVING &lt;boolean value
+      expression&gt;</code>
+</p>
+<p>The <code class="literal">&lt;from clause&gt;</code> contains one or more
+      <code class="literal">&lt;table reference&gt;</code> separated by commas. A table
+      reference is often a table or view name or a joined table.</p>
+<p>The <code class="literal">&lt;where clause&gt;</code> filters the rows of
+      the table in the &lt;from clause&gt; and removes the rows for which the
+      search condition is not TRUE.</p>
+<p>The <code class="literal">&lt;group by clause&gt;</code> is a comma
+      separated list of columns of the table in the <code class="literal">&lt;from
+      clause&gt;</code> or expressions based on the columns.</p>
+<p>When a <code class="literal">&lt;group by clause&gt;</code> is used, only
+      the columns used in the <code class="literal">&lt;group by clause&gt;</code> or
+      expressions used there, can be used in the <code class="literal">&lt;select
+      list&gt;</code>, together with any <code class="literal">&lt;aggregate
+      function&gt;</code> on other columns. A <code class="literal">&lt;group by
+      clause&gt;</code> compares the rows and groups together the rows that
+      have the same values in the columns of the <code class="literal">&lt;group by
+      clause&gt;</code>. Then any <code class="literal">&lt;aggregate
+      function&gt;</code> in the <code class="literal">&lt;select list&gt;</code> is
+      performed on each group, and for each group, a row is formed that
+      contains the values of the columns of the <code class="literal">&lt;group by
+      clause&gt;</code> and the values returned from each
+      <code class="literal">&lt;aggregate function&gt;. In the first example below, a
+      simple column reference is used in GROUP BY, while in the second
+      example, an expression is used.</code>
+<pre class="programlisting">CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+SELECT d, e, f FROM atable WHERE a + b = c GROUP BY d, e, f
+SELECT d + e, SUM(f) FROM atable WHERE a + b = c GROUP BY d + e HAVING SUM(f) &gt; 2 AND d + e &gt; 4
+</pre>
+</p>
+<p>A <code class="literal">&lt;having clause&gt;</code> filters the rows of the
+      table that is formed after applying the <code class="literal">&lt;group by
+      clause&gt;</code> using its search condition. The search condition
+      must be an expression based on the expressions in the GROUP BY list or
+      the aggregate functions used.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12246"></a>Table Primary</h3>
+</div>
+</div>
+</div>
+<p>Table primary refers to different forms of table reference in the
+      FROM clause.</p>
+<p>The simplest form of reference is simply a name. This is the name
+      of a table, a view, a transition table in a trigger definition, or a
+      query name specified in the WITH clause of a query expression.</p>
+<p>
+<code class="literal">&lt;table or query name&gt; ::= &lt;table name&gt; |
+      &lt;transition table name&gt; | &lt;query name&gt;</code>
+</p>
+<p>A query expression that is enclosed in parentheses and returns
+      from zero to many rows is a <code class="literal">&lt;table subquery&gt;</code>.
+      In a <code class="literal">&lt;derived table&gt;</code> the query expression is
+      self contained and cannot reference the columns of other table
+      references.</p>
+<p>
+<code class="literal">&lt;derived table&gt; ::= &lt;table
+      subquery&gt;</code>
+</p>
+<p>
+<code class="literal">When the word LITERAL is used before a &lt;table
+      subquery&gt;, it means the query expression can reference the columns of
+      other table references that precede it. </code>
+</p>
+<p>
+<code class="literal">&lt;lateral derived table&gt; ::= LATERAL &lt;table
+      subquery&gt;</code>
+</p>
+<p>UNNEST is similar to LATERAL, but instead of a query expression,
+      and expression that returns an array is used. This expression is
+      converted into a table which has one column that contains the elements
+      of the array, and, if WITH ORDINALITY is used, a second column that
+      contains the index of each element. The array expression usually
+      contains a reference to a column of the table reference preceding the
+      current table reference.</p>
+<p>
+<code class="literal">&lt;collection derived table&gt; ::= UNNEST &lt;left
+      paren&gt; &lt;array value expression&gt; &lt;right paren&gt; [ WITH
+      ORDINALITY ]</code>
+</p>
+<p>When TABLE is used in this context, it also converts an array
+      value expression to a table, but this array must be the result of a
+      function call. A function that returns a MULTISET can also be used in
+      this context and each row of the multiset is expanded into a row of the
+      table.</p>
+<p>
+<code class="literal">&lt;table function derived table&gt; ::= TABLE &lt;left
+      paren&gt; &lt;collection value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>The column list that is specified for the table reference must
+      contain names that are unique within the list</p>
+<p>
+<code class="literal">&lt;derived column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;column name list&gt; ::= &lt;column name&gt; [ {
+      &lt;comma&gt; &lt;column name&gt; }... ] </code>
+</p>
+<p>A parenthesized joined table is simply a joined table contained in
+      parentheses. Joined tables are discussed below.</p>
+<p>
+<code class="literal">&lt;parenthesized joined table&gt; ::= &lt;left paren&gt;
+      &lt;parenthesized joined table&gt; &lt;right paren&gt; | &lt;left
+      paren&gt; &lt;joined table&gt; &lt;right paren&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12278"></a>Joined Table</h3>
+</div>
+</div>
+</div>
+<p>Joins are operators with two table as the operands, resulting in a
+      third table, called joined table. All join operators are evaluated left
+      to right, therefore, with multiple joins, the table resulting from the
+      first join operator becomes an operand of the next join operator.
+      Parentheses can be used to group sequences of joined tables and change
+      the evaluation order. So if more than two tables are joined together
+      with join operators, the end result is also a joined table. There are
+      different types of join, each producing the result table in a different
+      way.</p>
+<a name="N1227D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CROSS JOIN</strong></span>
+</p>
+<p>The simplest form of join is CROSS JOIN. The CROSS JOIN of two
+      tables is a table that has all the columns of the first table, followed
+      by all the columns of the second table, in the original order. Each row
+      of the first table is combined with each row of the second table to fill
+      the rows of the new table. If the rows of each table form a set, then
+      the rows of the CROSS JOIN table form the Cartesian product of the rows
+      of the two table operands.</p>
+<p>The CROSS JOIN can be expressed in two forms. The first form is
+      <code class="literal">A CROSS JOIN B</code>. The second form is <code class="literal">A,
+      B</code>. This type of join is not generally very useful, as it
+      returns large result tables.</p>
+<a name="N12290" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UNION JOIN</strong></span>
+</p>
+<p>The UNION JOIN has limited use in queries. The result table has
+      the same columns as that of CROSS JOIN. Each row of the first table is
+      extended to the right with nulls and added to the new table. Each row of
+      the second table is extended to the left with nulls and added to the new
+      table. The UNION JOIN is expressed as <code class="literal">A UNION JOIN B</code>.
+      This should not be confused with <code class="literal">A UNION B</code>, which is
+      a set operation. Union join is for special applications and is not
+      commonly used.</p>
+<a name="N122A1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>JOIN ... ON</strong></span>
+</p>
+<p>The condition join is similar to CROSS JOIN, but a condition is
+      tested for each row of the new table and the row is created only if the
+      condition is true. This form of join is expressed as <code class="literal">A JOIN B
+      ON (&lt;search condition&gt;)</code>.</p>
+<p>Equijoin is a condition join in which the search condition is an
+      equality condition between on or more pairs of columns from the two
+      table. Equijoin is the most commonly used type of join.</p>
+<a name="N122B1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>JOIN ... USING</strong></span>
+</p>
+<a name="N122BA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NATURAL JOIN</strong></span>
+</p>
+<p>Joins with USING or NATURAL keywords joins are similar to an
+      equijoin but they cannot be replaced simply with an equijoin. The new
+      table is formed with the specified or implied shared columns of the two
+      tables, followed by the rest of the columns from each table. In NATURAL
+      JOIN, the shared columns are all the column pairs that have the same
+      name in the first and second table. In JOIN USING, only columns names
+      that are specified by the USING clause are shared. The joins are
+      expressed as <code class="literal">A NATURAL JOIN B</code>, and <code class="literal">A JOIN B
+      USING (&lt;comma separated column name list&gt;)</code>.</p>
+<p>The columns of the joined table are formed by the following
+      procedures: In JOIN ... USING the shared columns are added to the joined
+      table in the same order as they appear in the column name list. In
+      NATURAL JOIN the shared columns are added to the joined table in the
+      same order as they appear in the first table. In bother forms of join,
+      the non-shared columns of the first table are added in the order they
+      appear in the first table, finally the non-shared columns of the second
+      table are added in the order they appear in the second table.</p>
+<p>The type of each shared column of the joined table is based on the
+      type of the columns in the original tables. If the original types are
+      not exactly the same, the type of the shared column is formed by type
+      aggregation. Type aggregations selects a type that can represent values
+      of both aggregated types. Simple type aggregation picks one of the
+      types. For example SMALLINT and INTEGER, results in INTEGER, or
+      VARCHAR(10) and VARCHAR(20) results in VARCHAR(20). More complex type
+      aggregation inherits properties from both types. For example DECIMAL(8)
+      and DECIMAL (6,2) results in DECIMAL (8,2).</p>
+<a name="N122CF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>OUTER JOIN</strong></span>
+</p>
+<p>LEFT, RIGHT and FULL OUTER JOIN</p>
+<p>The three qualifiers can be added to all types of JOIN apart from
+      CROSS JOIN and UNION JOIN. First the new table is populated with the
+      rows from the original join. If LEFT is specified, all the rows from the
+      first table that did not make it into the new table are extended to the
+      right with nulls and added to the table. If RIGHT is specified, all the
+      rows from the second table that did not make it into the new table are
+      extended to the left with nulls and added to the table. If FULL is
+      specified, the addition of leftover rows is performed from both the
+      first and the second table. These forms are expressed by prefixing the
+      join specification with the given keyword. For example <code class="literal">A LEFT
+      OUTER JOIN B ON (&lt;search condition&gt;)</code> or <code class="literal">A
+      NATURAL FULL OUTER JOIN B</code> or <code class="literal">A FULL OUTER JOIN B
+      USING (&lt;comma separated column name list&gt;)</code>.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N122E5"></a>Selection</h3>
+</div>
+</div>
+</div>
+<p>Despite the name, selection has nothing to do with the list of
+      columns in a SELECT statement. In fact, it refers to the search
+      condition used to limit the rows that from a result table (selection of
+      rows, not columns). In SQL, simple selection is expressed with a WHERE
+      condition appended to a single table or a joined table. In some cases,
+      this method of selection is the only method available. But when it is
+      possible to perform the selection with join conditions, this is the
+      better method, as it results in a clearer expression of the
+      query.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N122EA"></a>Projection</h3>
+</div>
+</div>
+</div>
+<p>Projection is selection of the columns from a simple or joined
+      table to form a result table. Explicit projection is performed in the
+      SELECT statement by specifying the select column list. Some form of
+      projection is also performed in JOIN ... USING and NATURAL JOIN.</p>
+<p>The joined table has columns that are formed according to the
+      rules mentioned above. But in many cases, not all the columns are
+      necessary for the intended operation. If the statement is in the form,
+      SELECT * FROM &lt;joined table&gt;, then all the columns of &lt;joined
+      table&gt; are returned. But normally, the columns to be returned are
+      specified after the SELECT keyword, separated from each other with
+      commas.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N122F1"></a>Computed Columns</h3>
+</div>
+</div>
+</div>
+<p>In the select list, it is possible to use expressions that
+      reference any columns of &lt;joined table&gt;. Each of these expressions
+      forms a computed column. It is computed for each row of the result
+      table, using the values of the columns of the &lt;joined table&gt; for
+      that row.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N122F6"></a>Naming</h3>
+</div>
+</div>
+</div>
+<p>Naming is used to hide the original names of tables or table
+      columns and to replace them with new names in the scope of the query.
+      Naming is also used for defining names for computed columns.</p>
+<a name="N122FB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Naming in Joined
+      Table</strong></span>
+</p>
+<p>Naming is performed by adding a new name after a table's real name
+      and by adding a list of column names after the new table name. Both
+      table naming and column naming are optional, but table naming is
+      required for column naming. The expression <code class="literal">A [AS] X (&lt;comma
+      separated column name list&gt;)</code> means table A is used in the
+      query expression as table X and its columns are named as in the given
+      list. The original name A, or its original column names, are not visible
+      in the scope of the query. The BNF is given below. The
+      <code class="literal">&lt;correlation name&gt;</code> can be the same or different
+      from the name of the table. The <code class="literal">&lt;derived column
+      list&gt;</code> is a comma separated list of column names. The degree
+      of this list must be equal to the degree of the table. The column names
+      in the list must be distinct. They can be the same or different from the
+      names of the table's columns.</p>
+<p>
+<code class="literal">&lt;table or query name&gt; [ [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] ]</code>
+</p>
+<p>In the examples below, the columns of the original tables are
+      named (a, b, c, d, e, f). The two queries are equivalent. In the second
+      query, the table and its columns are renamed and the new names are used
+      in the WHERE clauses:</p>
+<pre class="programlisting">CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+SELECT d, e, f FROM atable WHERE a + b = c
+SELECT x, y, z FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w</pre>
+<a name="N12316" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Naming in Select
+      List</strong></span>
+</p>
+<p>Naming in the SELECT list logically takes place after naming in
+      the joined table. The new names for columns are not visible in the
+      immediate query expression or query expression. They become visible in
+      the ORDER BY clause and in the result table that is returned to the
+      user. Or if the query expression is used as a derived table in an
+      enclosing query expression.</p>
+<p>In the example below, the query is on the same table but with
+      column renaming in the Select list. The new names are used in the ORDER
+      BY clause:</p>
+<pre class="programlisting">SELECT x + y AS xysum, y + z AS yzsum FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w ORDER BY xysum, yzsum</pre>
+<p>If the names <code class="literal">xysum</code> or <code class="literal">yzsum</code>
+      are not used, the computed columns cannot be referenced in the ORDER BY
+      list.</p>
+<a name="N1232D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Name Resolution</strong></span>
+</p>
+<p>In a joined table, if a column name appears in tables on both
+      sides then any reference to the name must use the table name in order to
+      specify which table is being referred to.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12338"></a>Grouping Operations</h3>
+</div>
+</div>
+</div>
+<a name="N1233B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Grouping Operations</strong></span>
+</p>
+<p>Grouping results in the elimination of duplicate rows. A grouping
+      operation is performed after the operations discussed above. A simple
+      form of grouping is performed by the use of DISTINCT after SELECT. This
+      eliminates all the duplicate rows (rows that have the same value in each
+      of their columns when compared to another row). The other form of
+      grouping is performed with the GROUP BY clause. This form is usually
+      used together with aggregation.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12346"></a>Aggregation</h3>
+</div>
+</div>
+</div>
+<p>Aggregation is an operation that computes a single value from the
+      values of a column over several rows. The operation is performed with an
+      aggregate function. The simplest form of aggregation is counting,
+      performed by the COUNT function.</p>
+<p>Other common aggregate functions return the maximum, minimum and
+      average value among the values in different rows.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1234D"></a>Set Operations</h3>
+</div>
+</div>
+</div>
+<a name="N12350" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Set and Multiset
+      Operations</strong></span>
+</p>
+<p>While join operations generally result in laterally expanded
+      tables, SET and COLLECTION operations are performed on two tables that
+      have the same degree and result in a table of the same degree. The SET
+      operations are UNION, INTERSECT and EXCEPT (difference). When each of
+      these operations is performed on two tables, the collection of rows in
+      each table and in the result is reduced to a set of rows, by eliminating
+      duplicates. The set operations are then performed on the two tables,
+      resulting in the new table which itself is a set of rows. Collection
+      operations are similar but the tables are not reduced to sets before or
+      after the operation and the result is not necessarily a set, but a
+      collection of rows.</p>
+<p>The set operations on two tables A and B are: <code class="literal">A UNION
+      [DISTINCT] B</code>, <code class="literal">A INTERSECT [DISTINCT] B</code> and
+      <code class="literal">A EXCEPT [DISTINCT] B</code>. The result table is formed in
+      the following way: The UNION operation adds all the rows from A and B
+      into the new table, but avoids copying duplicate rows. The INTERSECT
+      operation copies only those rows from each table that also exist in the
+      other table, but avoids copying duplicate rows. The EXCEPT operation
+      copies those rows from the first table which do not exist in the second
+      table, but avoids copying duplicate rows.</p>
+<p>The collection operations are similar to the set operations, but
+      can return duplicate rows. They are <code class="literal">A UNION ALL B</code>,
+      <code class="literal">A INTERSECT ALL B</code> and <code class="literal">A EXCEPT ALL
+      B</code>. The UNION ALL operation adds all the rows from A and B into
+      the new table. The INTERSECT operation copies only those rows from each
+      table that also exist in the other table. If n copies of a rows exists
+      in one table, and m copies in the other table, the number of copies in
+      the result table is the smaller of n and m. The EXCEPT operation copies
+      those rows from the first table which do not exist in the second table.
+      If n copies of a row exist in the first table and m copies in the second
+      table the number of copies in the result table is n-m, or if n &lt; m,
+      then zero.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12371"></a>Query Expression</h3>
+</div>
+</div>
+</div>
+<p>A query expression consists of an optional WITH clause and a query
+      expression body. The WITH clause lists one or more named ephemeral
+      tables that can be referenced in the query expression body.</p>
+<p>
+<code class="literal">&lt;query expression&gt; ::= [ &lt;with clause&gt; ]
+      &lt;query expression body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;with clause&gt; ::= WITH &lt;with
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;with list&gt; ::= &lt;with list element&gt; [ {
+      &lt;comma&gt; &lt;with list element&gt; }... ] </code>
+</p>
+<p>
+<code class="literal">&lt;with list element&gt; ::= &lt;query name&gt; [
+      &lt;left paren&gt; &lt;with column list&gt; &lt;right paren&gt; ] AS
+      &lt;left paren&gt; &lt;query expression&gt; &lt;right paren&gt;
+      </code>
+</p>
+<p>
+<code class="literal">&lt;with column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>A query expression body refers to a table formed by using UNION
+      and other set operations. The query expression body is evaluated from
+      left to right and the INTERSECT operator has precedence over the UNION
+      and EXCEPT operators. A simplified BNF is given below:</p>
+<p>
+<code class="literal">&lt;query expression body&gt; ::= &lt;query term&gt; |
+      &lt;query expression body&gt; UNION | EXCEPT [ ALL | DISTINCT ] [
+      &lt;corresponding spec&gt; ] &lt;query term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;query term&gt; ::= &lt;query primary&gt; |
+      &lt;query term&gt; INTERSECT [ ALL | DISTINCT ] [ &lt;corresponding
+      spec&gt; ] &lt;query term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;query primary&gt; ::= &lt;simple table&gt; |
+      &lt;left paren&gt; &lt;query expression body&gt; [ &lt;order by
+      clause&gt; ] [ &lt;result offset clause&gt; ] [ &lt;fetch first
+      clause&gt; ] &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;simple table&gt; ::= &lt;query specification&gt; |
+      &lt;table value constructor&gt; | &lt;explicit table&gt; &lt;explicit
+      table&gt; ::= TABLE &lt;table or query name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;corresponding spec&gt; ::= CORRESPONDING [ BY
+      &lt;left paren&gt; &lt;column name list&gt; &lt;right paren&gt;
+      ]</code>
+</p>
+<p>A <code class="literal">&lt;query term&gt;</code> and a <code class="literal">&lt;query
+      primary&gt;</code> can be a SELECT statement, an
+      <code class="literal">&lt;explicit table&gt;</code>, or a <code class="literal">&lt;table value
+      constructor&gt;</code>.</p>
+<p>The CORRESPONDING clause is optional. If it is not specified, then
+      the <code class="literal">&lt;query term&gt;</code> and the <code class="literal">&lt;query
+      primary&gt;</code> must have the same number of columns. If
+      CORRESPONDING is specified, the two sides need not have the same number
+      of columns. If no column list is used with CORRESPONDING, then all the
+      column names that are common in the tables on two sides are used in the
+      order in which they appear in the first table. If a columns list is
+      used, it allows you to select only some columns of the tables on the
+      left and right side to create the new table. In the example below the
+      columns named u and v from the two SELECT statements are used to create
+      the UNION table.</p>
+<p>
+<pre class="programlisting">SELECT * FROM atable UNION CORRESPONDING BY (u, v) SELECT * FROM anothertable
+</pre>The type of each column of the query expression is determined
+      by combining the types of the corresponding columns from the two
+      participating tables.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N123B0"></a>Ordering</h3>
+</div>
+</div>
+</div>
+<p>When the rows of the result table have been formed, it is possible
+      to specify the order in which they are returned to the user. The ORDER
+      BY clause is used to specify the columns used for ordering, and whether
+      ascending or descending ordering is used. It can also specify whether
+      NULL values are returned first or last.</p>
+<pre class="programlisting">SELECT x + y AS xysum, y + z AS yzsum FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w ORDER BY xysum NULLS LAST, yzsum NULLS FIRST</pre>
+<p>The ORDER BY clause specifies one or more <code class="literal">&lt;value
+      expressions&gt;</code>. The list of rows is sorted according to the
+      first <code class="literal">&lt;value expression&gt;</code>. When some rows are
+      sorted equal then they are sorted according to the next
+      <code class="literal">&lt;value expression&gt;</code> and so on.</p>
+<p>
+<code class="literal">&lt;order by clause&gt; ::= ORDER BY &lt;sort
+      specification&gt; [ { &lt;comma&gt; &lt;sort specification&gt; }...
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;sort specification&gt; ::= &lt;value expression&gt; [
+      ASC | DESC ] [ NULLS FIRST | NULLS LAST ]</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N123C8"></a>Slicing</h3>
+</div>
+</div>
+</div>
+<p>A different form of limiting the rows can be performed on the
+      result table after it has been formed according to all the other
+      operations (selection, grouping, ordering etc.). This is specified by
+      the FETCH ... ROWS and OFFSET clauses of a SELECT statement. In this
+      form, the specified OFFSET rows are removed from start of the table,
+      then up to the specified FETCH rows are kept and the rest of the rows
+      are discarded.</p>
+<p>
+<code class="literal">&lt;result offset clause&gt; ::= OFFSET &lt;offset row
+      count&gt; { ROW | ROWS } </code>
+</p>
+<p>
+<code class="literal">&lt;fetch first clause&gt; ::= FETCH { FIRST | NEXT } [
+      &lt;fetch first row count&gt; ] { ROW | ROWS } ONLY</code>
+</p>
+<p>
+<code class="literal">&lt;limit clause&gt; ::= LIMIT [ &lt;fetch first row
+      count&gt; ]</code>
+</p>
+<p>A slicing operation takes the result set that has been already
+      processed and ordered. It then discards the specified number of rows
+      from the start of the result set and returns the specified number of
+      rows after the discarded rows.</p>
+<pre class="programlisting">SELECT a, b FROM atable WHERE d &lt; 5 ORDER BY absum OFFSET 3 FETCH 2 ROWS ONLY 
+SELECT a, b FROM atable WHERE d &lt; 5 ORDER BY absum OFFSET 3 LIMIT 2 /* alternative keyword */ </pre>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N123DA"></a>Data Change Statements</h2>
+</div>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N123DD"></a>Delete Statement</h3>
+</div>
+</div>
+</div>
+<a name="N123E0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DELETE FROM</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>delete statement: searched</em></span>
+</p>
+<p>
+<code class="literal">&lt;delete statement: searched&gt; ::= DELETE FROM
+      &lt;target table&gt; [ [ AS ] &lt;correlation name&gt; ] [ WHERE
+      &lt;search condition&gt; ]</code>
+</p>
+<p>Delete rows of a table. The search condition is a
+      <code class="literal">&lt;boolean value expression&gt;</code> that is evaluated
+      for each row of the table. If the condition is true, the row is deleted.
+      If the condition is not specified, all the rows of the table are
+      deleted. In fact, an implicit SELECT is performed in the form of
+      <code class="literal">SELECT * FROM &lt;target table&gt; [ WHERE &lt;search
+      condition&gt;]</code> and the selected rows are deleted. When used in
+      JDBC, the number of rows returned by the implicit SELECT is returned as
+      the update count.</p>
+<p>If there are FOREIGN KEY constraints on other tables that
+      reference the subject table, and the FOREIGN KEY constraints have
+      referential actions, then rows from those other tables that reference
+      the deleted rows are either deleted, or updated, according to the
+      specified referential actions.</p>
+<p>In the second example below the rows that have the maximum
+      value for column A are deleted;</p>
+<pre class="programlisting">DELETE FROM T WHERE C &gt; 5
+DELETE FROM T AS TT WHERE TT.A = (SELECT MAX(A) FROM T)
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N123FD"></a>Truncate Statement</h3>
+</div>
+</div>
+</div>
+<a name="N12400" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRUNCATE TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>truncate table statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;truncate table statement&gt; ::= TRUNCATE TABLE
+      &lt;target table&gt; [ &lt;identity column restart option&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;identity column restart option&gt; ::= CONTINUE
+      IDENTITY | RESTART IDENTITY</code>
+</p>
+<p>Delete all rows of a table without firing its triggers. This
+      statement can only be used on base tables (not views). If the table is
+      referenced in a FOREIGN KEY constraint, the statement causes an
+      exception. Triggers defined on the table are not executed with this
+      statement. The default for <code class="literal">&lt;identity column restart
+      option&gt;</code> is <code class="literal">CONTINUE IDENTITY</code>. This means
+      no change to the IDENTITY sequence of the table. If <code class="literal">RESTART
+      IDENTITY</code> is specified, then the sequence is reset to its start
+      value.</p>
+<p>TRUNCATE is faster than ordinary DELETE. The TRUNCATE statement
+      is an SQL Standard data change statement, therefore it is performed
+      under transaction control and can be rolled back if the connection is
+      not in the auto-commit mode.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1241F"></a>Insert Statement</h3>
+</div>
+</div>
+</div>
+<a name="N12422" class="indexterm"></a>
+<p>
+<span class="bold"><strong>INSERT INTO</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>insert statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;insert statement&gt; ::= INSERT INTO &lt;target
+      table&gt; &lt;insert columns and source&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;insert columns and source&gt; ::= &lt;from
+      subquery&gt; | &lt;from constructor&gt; | &lt;from
+      default&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;from subquery&gt; ::= [ &lt;left paren&gt;
+      &lt;insert column list&gt; &lt;right paren&gt; ] [ &lt;override
+      clause&gt; ] &lt;query expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;from constructor&gt; ::= [ &lt;left paren&gt;
+      &lt;insert column list&gt; &lt;right paren&gt; ] [ &lt;override
+      clause&gt; ] &lt;contextually typed table value
+      constructor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;override clause&gt; ::= OVERRIDING USER VALUE |
+      OVERRIDING SYSTEM VALUE</code>
+</p>
+<p>
+<code class="literal">&lt;from default&gt; ::= DEFAULT
+      VALUES</code>
+</p>
+<p>
+<code class="literal">&lt;insert column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>Insert new rows in a table. An INSERT statement inserts one or
+      more rows into the table.</p>
+<p>The special form, <code class="literal">INSERT INTO &lt;target table&gt;
+      DEFAULT VALUES</code> can be used with tables which have a default
+      value for each column.</p>
+<p>With the other forms of INSERT, the optional
+      <code class="literal">(&lt;insert column list&gt;)</code> specifies to which
+      columns of the table the new values are assigned.</p>
+<p>In one form, the inserted values are from a <code class="literal">&lt;query
+      expression&gt;</code> and all the rows that are returned by the
+      <code class="literal">&lt;query expression&gt;</code> are inserted into the table.
+      If the <code class="literal">&lt;query expression&gt;</code> returns no rows,
+      nothing is inserted.</p>
+<p>In the other form, a comma separated list of values called
+      <code class="literal">&lt;contextually typed table value constructor&gt;</code> is
+      used to insert one or more rows into the table. This list is
+      contextually typed, because the keywords NULL and DEFAULT can be used
+      for the values that are assigned to each column of the table. The
+      keyword DEFAULT means the default value of the column and can be used
+      only if the target column has a default value or is an IDENTITY or
+      GENERATED column of the table.</p>
+<p>The <code class="literal">&lt;override clause&gt;</code> must be used
+      when a value is explicitly assigned to a column that has been defined as
+      GENERATED ALWAYS AS IDENTITY. The clause, OVERRIDE SYSTEM VALUE means
+      the provided values are used for the insert, while OVERRIDING USER VALUE
+      means the provided values are simply ignored and the values generated by
+      the system are used instead.</p>
+<p>An array can be inserted into a column of the array type by
+      using literals, by specifying a parameter in a prepared statement or an
+      existing array returned by query expression. The last example below
+      inserts an array.</p>
+<p>The rows that are inserted into the table are checked against
+      all the constraints that have been declared on the table. The whole
+      INSERT operation fails if any row fails to inserted due to constraint
+      violation. Examples:</p>
+<pre class="programlisting">INSERT INTO T DEFAULT VALUES /* all columns of T have DEFAULT clauses */
+INSERT INTO T (SELECT * FROM Z) /* table Z has the same columns as table T */
+INSERT INTO T (A,B) VALUES ((1,2),(3,NULL), (DEFAULT,6)) /* three rows are inserted into table T */
+INSERT INTO T VALUES 3, ARRAY['hot','cold']
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1246A"></a>Update Statement</h3>
+</div>
+</div>
+</div>
+<a name="N1246D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UPDATE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>update statement: searched</em></span>
+</p>
+<p>
+<code class="literal">&lt;update statement: searched&gt; ::= UPDATE
+      &lt;target table&gt; [ [ AS ] &lt;correlation name&gt; ] SET &lt;set
+      clause list&gt; [ WHERE &lt;search condition&gt; ]</code>
+</p>
+<p>Update rows of a table. An UPDATE statement selects rows from
+      the <code class="literal">&lt;target table&gt;</code> using an implicit SELECT
+      statement formed in the following manner:</p>
+<p>
+<code class="literal">SELECT * FROM &lt;target table&gt; [ [ AS ]
+      &lt;correlation name&gt; ] [ WHERE &lt;search condition&gt;
+      ]</code>
+</p>
+<p>Then it applies the <code class="literal">SET &lt;set clause
+      list&gt;</code> expression to each selected row.</p>
+<p>If the implicit SELECT returns no rows, no update takes place.
+      When used in JDBC, the number of rows returned by the implicit SELECT is
+      returned as the update count.</p>
+<p>If there are FOREIGN KEY constraints on other tables that
+      reference the subject table, and the FOREIGN KEY constraints have
+      referential actions, then rows from those other tables that reference
+      the updated rows are updated, according to the specified referential
+      actions.</p>
+<p>The rows that are updated are checked against all the
+      constraints that have been declared on the table. The whole UPDATE
+      operation fails if any row violates any constraint.</p>
+<a name="N1248F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>set clause list</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set clause list</em></span>
+</p>
+<p>
+<code class="literal">&lt;set clause list&gt; ::= &lt;set clause&gt; [ {
+      &lt;comma&gt; &lt;set clause&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;set clause&gt; ::= &lt;multiple column
+      assignment&gt; | &lt;set target&gt; &lt;equals operator&gt; &lt;update
+      source&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;multiple column assignment&gt; ::= &lt;set target
+      list&gt; &lt;equals operator&gt; &lt;assigned
+      row&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;set target list&gt; ::= &lt;left paren&gt; &lt;set
+      target&gt; [ { &lt;comma&gt; &lt;set target&gt; }... ] &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;assigned row&gt; ::= &lt;contextually typed row
+      value expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;set target&gt; ::= &lt;column
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;update source&gt; ::= &lt;value expression&gt; |
+      &lt;contextually typed value specification&gt;</code>
+</p>
+<p>Specify a list of assignments. This is used in UPDATE, MERGE
+      and SET statements to assign values to a scalar or row target.</p>
+<p>Apart from setting a whole target to a value, a SET statement
+      can set individual elements of an array to new values. The last example
+      below shows this form of assignment to the array in the column named
+      B.</p>
+<p>In the examples given below, UPDATE statements with single and
+      multiple assignments are shown. Note in the third example, a SELECT
+      statement is used to provide the update values for columns A and C,
+      while the update value for column B is given separately. The SELECT
+      statement must return exactly one row . In this example the SELECT
+      statement refers to the existing value for column C in its search
+      condition.</p>
+<pre class="programlisting">UPDATE T SET A = 5 WHERE ...
+UPDATE T SET (A, B) = (1, NULL) WHERE ...
+UPDATE T SET (A, C) = (SELECT X, Y FROM U WHERE Z = C), B = 10 WHERE ...
+UPDATE T SET A = 3, B[3] = 'warm'
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N124B8"></a>Merge Statement</h3>
+</div>
+</div>
+</div>
+<a name="N124BB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MERGE INTO</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>merge statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;merge statement&gt; ::= MERGE INTO &lt;target
+      table&gt; [ [ AS ] &lt;merge correlation name&gt; ] USING &lt;table
+      reference&gt; ON &lt;search condition&gt; &lt;merge operation
+      specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge correlation name&gt; ::= &lt;correlation
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge operation specification&gt; ::= &lt;merge
+      when clause&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;merge when clause&gt; ::= &lt;merge when matched
+      clause&gt; | &lt;merge when not matched clause&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge when matched clause&gt; ::= WHEN MATCHED
+      THEN &lt;merge update specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge when not matched clause&gt; ::= WHEN NOT
+      MATCHED THEN &lt;merge insert specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge update specification&gt; ::= UPDATE SET
+      &lt;set clause list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge insert specification&gt; ::= INSERT [
+      &lt;left paren&gt; &lt;insert column list&gt; &lt;right paren&gt; ] [
+      &lt;override clause&gt; ] VALUES &lt;merge insert value
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge insert value list&gt; ::= &lt;left paren&gt;
+      &lt;merge insert value element&gt; [ { &lt;comma&gt; &lt;merge insert
+      value element&gt; }... ] &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge insert value element&gt; ::= &lt;value
+      expression&gt; | &lt;contextually typed value
+      specification&gt;</code>
+</p>
+<p>Update rows, or insert new rows into the <code class="literal">&lt;target
+      table&gt;</code>. The MERGE statement uses a second table, specified
+      by <code class="literal">&lt;table reference&gt;</code>, to determine the rows to
+      be updated or inserted. It is possible to use the statement only to
+      update rows or to insert rows, but usually both update and insert are
+      specified.</p>
+<p>The <code class="literal">&lt;search condition&gt;</code> matches each
+      row of the <code class="literal">&lt;table reference&gt;</code> with each row of
+      the <code class="literal">&lt;target table&gt;</code>. If the two rows match then
+      the UPDATE clause is used to update the matching row of the target
+      table. Those rows of <code class="literal">&lt;table reference&gt;</code> that
+      have no matching rows are then used to insert new rows into the
+      <code class="literal">&lt;target table&gt;</code>. Therefore, a MERGE statement
+      can update between 0 and all the rows of the <code class="literal">&lt;target
+      table&gt;</code> and can insert between 0 and the number of the rows
+      in <code class="literal">&lt;table reference&gt;</code> into the
+      <code class="literal">&lt;target table&gt;</code>. If any row in the
+      <code class="literal">&lt;target table&gt;</code> matches more than one row in
+      <code class="literal">&lt;table reference&gt;</code> a cardinality error is
+      raised. On the other hand, several rows in the <code class="literal">&lt;target
+      table&gt;</code> can matches a single row in <code class="literal">&lt;table
+      reference&gt;</code> without any error. The constraints and
+      referential actions specified on the database tables are enforced the
+      same way as for an update and an insert statement.</p>
+<p>The MERGE statement can be used with only the WHEN NOT MATCHED
+      clause as a conditional INSERT statement that inserts a row if no
+      existing rows match a condition.</p>
+<p>In the first example below, the table originally contains two
+      rows for different furniture. The <code class="literal">&lt;table
+      reference&gt;</code> is the <code class="literal">(VALUES(1, 'conference table'),
+      (14, 'sofa'), (5, 'coffee table'))</code> expression, which evaluates
+      to a table with 3 rows. When the x value for a row matches an existing
+      row, then the existing row is updated. When the x value does not match,
+      the row is inserted. Therefore one row of table t is updated from
+      'dining table' to 'conference table', and two rows are inserted into
+      table t. The second example uses a SELECT statement as the source of the
+      values for the MERGE.</p>
+<p>In the third example, a new row in inserted into the table only
+      when the primary key for the new row does not exist. This example uses
+      parameters and should be executed as a JDBC PreparedStatement.</p>
+<pre class="programlisting">CREATE TABLE t (id INT PRIMARY KEY, description VARCHAR(100))
+INSERT INTO t VALUES (1, 'dining table'), (2, 'deck chair')
+MERGE INTO t USING (VALUES(1, 'conference table'), (14, 'sofa'), (5, 'coffee table')) 
+   AS vals(x,y) ON t.id = vals.x
+   WHEN MATCHED THEN UPDATE SET t.description = vals.y
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, vals.y
+
+MERGE INTO t USING (SELECT * FROM tt WHERE acol = 2) AS vals(x,y) ON t.id = vals.x
+   WHEN MATCHED THEN UPDATE SET t.description = vals.y
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, vals.y
+
+MERGE INTO t USING (VALUES(CAST(? AS INT))) AS vals(x) ON t.id = vals.x
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, ?
+</pre>
+</div>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="accesscontrol-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="sqlroutines-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;6.&nbsp;Access Control&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;8.&nbsp;SQL-Invoked Routines</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/databaseobjects-chapt.html b/doc/guide/databaseobjects-chapt.html
new file mode 100644
index 0000000..f614f3b
--- /dev/null
+++ b/doc/guide/databaseobjects-chapt.html
@@ -0,0 +1,3129 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;4.&nbsp;Schemas and Database Objects</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="sessions-chapt.html" title="Chapter&nbsp;3.&nbsp;Sessions and Transactions">
+<link rel="next" href="texttables-chapt.html" title="Chapter&nbsp;5.&nbsp;Text Tables">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="sessions-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;4.&nbsp;Schemas and Database Objects</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="texttables-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;3.&nbsp;Sessions and Transactions&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;5.&nbsp;Text Tables</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="databaseobjects-chapt"></a>Chapter&nbsp;4.&nbsp;Schemas and Database Objects</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3622 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N10AC4"></a>
+<p>Copyright 2009 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-04 11:33:51 -0400 (Fri, 04 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10AC7">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10AD2">Schemas and Schema Objects</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10AF8">Names and References</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B18">Character Sets</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B32">Collations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B3F">Distinct Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B46">Domains</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B4D">Number Sequences</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10BA3">Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10BAF">Views</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10BCD">Constraints</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C26">Assertions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C30">Triggers</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C3E">Routines</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C57">Indexes</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C5C">Statements for Schema Definition and Manipulation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10CE1">Renaming Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10D01">Commenting Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10D1D">Schema Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N110DE">View Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N111D1">Trigger Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N1124D">Routine Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N112F5">Sequence Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N1137F">SQL Procedure Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N114B8">The Information Schema</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N114C3">Predefined Character Sets, Collations and Domains</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N114CE">Views in INFORMATION SCHEMA</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10AC7"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>The persistent elements of an SQL environment are database objects.
+    The database consists of catalogs plus authorizations.</p>
+<p>A catalog contains schemas, while schemas contain the objects that
+    contain data or govern the data.</p>
+<p>Each catalog contains a special schema called INFORMATION_SCHEMA.
+    This schema is read-only and contains some views and other schema objects.
+    The views contain lists of all the database objects that exist within the
+    catalog, plus all authorizations.</p>
+<p>Each database object has a name. A name is an identifier and is
+    unique within its name-space.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10AD2"></a>Schemas and Schema Objects</h2>
+</div>
+</div>
+</div>
+<p>In HyperSQL, there is only one catalog per database. The name of the
+    catalog is PUBLIC. You can rename the catalog with the <code class="literal">ALTER
+    CATALOG RENAME TO</code> statement. All schemas belong the this
+    catalog. The catalog name has no relation to the file name of the
+    database.</p>
+<p>Each database has also an internal "unique" name which is
+    automatically generated when the database is created. This name is used
+    for event logging. You can also change this unique name.</p>
+<p>Schema objects are database objects that contain data or govern or
+    perform operations on data. By definition, each schema object belongs to a
+    specific schema.</p>
+<p>Schema objects can be divided into groups according to their
+    characteristics.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Some kinds of schema objects can exist independently from other
+        schema object. Other kinds can exist only as an element of another
+        schema object. These dependent objects are automatically destroyed
+        when the parent object is dropped.</p>
+</li>
+<li>
+<p>Separate name-spaces exists for different kinds of schema
+        object. Some name-spaces are shared between two similar kinds of
+        schema objects.</p>
+</li>
+<li>
+<p>There can be dependencies between various schema objects, as a
+        schema object can include references to other schema objects. These
+        references can cross schema boundaries. Interdependence and cross
+        referencing between schema objects is allowed in some circumstances
+        and disallowed in some others.</p>
+</li>
+<li>
+<p>Schema objects can be destroyed with the DROP statement. If
+        dependent schema objects exist, a DROP statement will succeed only if
+        it has a CASCADE clause. In this case, dependent objects are also
+        destroyed in most cases. In some cases, such as dropping DOMAIN
+        objects, the dependent objects are not destroyed, but modified to
+        remove the dependency.</p>
+</li>
+</ul>
+</div>
+<p>A new HyperSQL catalog contains an empty schema called PUBLIC. By
+    default, this schema is the initial schema when a new session is started.
+    New schemas and schema objects can be defined and used in the PUBLIC
+    schema, as well as any new schema that is created by the user. You can
+    rename the PUBLIC schema.</p>
+<p>HyperSQL allows all schemas to be dropped, except the schema that is
+    the default initial schema for new sessions (by default, the PUBLIC
+    schema). For this schema, a DROP SCHEMA ... CASCADE statement will succeed
+    but will result in an empty schema, rather than no schema.</p>
+<p>The statements for setting the initial schema for users are
+    described in the <a class="link" href="accesscontrol-chapt.html" title="Chapter&nbsp;6.&nbsp;Access Control">Statements for
+    Authorization and Access Control</a> chapter.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10AF8"></a>Names and References</h3>
+</div>
+</div>
+</div>
+<p>The name of a schema object is an
+      <code class="literal">&lt;identifier&gt;</code>. The name belongs to the
+      name-space for the particular kind of schema object. The name is unique
+      within its name-space. For example, each schema has a separate
+      name-space for TRIGGER objects.</p>
+<p>In addition to the name-spaces in the schema. Each table has a
+      name-space for the names of its columns.</p>
+<p>Because a schema object is always in a schema and a schema always
+      in a catalog, it is possible, and sometimes necessary, to qualify the
+      name of the schema object that is being referenced in an SQL statement.
+      This is done by forming an &lt;<code class="literal">identifier chain&gt;</code>.
+      In some contexts, only a simple <code class="literal">&lt;identifier&gt;</code>
+      can be used and the <code class="literal">&lt;identifier chain&gt;</code> is
+      prohibited. While in some other contexts, the use of
+      <code class="literal">&lt;identifier chain&gt;</code> is optional. An identifier
+      chain is formed by qualifying each object with the name of the object
+      that owns its name-space. Therefore a column name is prefixed with a
+      table name, a table name is prefixed with a schema name, and a schema
+      name is prefixed with a catalog name. A fully qualified column name is
+      in the form <code class="literal">&lt;catalog name&gt;.&lt;schema name&gt;.&lt;table
+      name&gt;.&lt;column name&gt;</code>, likewise, a fully qualified
+      sequence name is in the form <code class="literal">&lt;catalog name&gt;.&lt;schema
+      name&gt;.&lt;sequence name&gt;</code>.</p>
+<p>HyperSQL extends the SQL standard to allow renaming all database
+      objects. The ALTER ... RENAME TO command has slightly different forms
+      depending on the type of object. If an object is referenced in a VIEW or
+      ROUTINE definition, it is not always possible to rename it.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B18"></a>Character Sets</h3>
+</div>
+</div>
+</div>
+<p>A CHARACTER SET is the whole or a subset of the UNICODE
+      character set.</p>
+<p>A character set name can only be a <code class="literal">&lt;regular
+      identifier&gt;</code>. There is a separate name-space for character
+      sets.</p>
+<p>There are several predefined character sets. These character
+      sets belong to INFORMATION_SCHEMA. However, when they are referenced in
+      a statement, no schema prefix can be used in the statement that
+      references them.</p>
+<p>The following character sets have been specified by the SQL
+      Standard:</p>
+<p>SQL_TEXT, SQL_IDENTIFIER, SQL_CHARACTER, ASCII_GRAPHIC,
+      GRAPHIC_IRV, ASCII_FULL, ISO8BIT, LATIN1, UTF32, UTF16, UTF8.</p>
+<p>The ASCII_GRAPHIC is the same as GRAPHIC_IRV and ASCII_FULL is
+      the same as ISO8BIT.</p>
+<p>Most of the character sets are defined by well-known standards
+      such as UNICODE.</p>
+<p>The SQL_CHARACTER consists of ASCII letters, digits and the
+      symbols used in the SQL language. The SQL_TEXT, SQL_IDENTIFIER are
+      implementation defined. HyperSQL defines SQL_TEXT as the UNICODE
+      character set and SQL_IDENTIFIER as the UNICODE character set minus the
+      SQL language special characters.</p>
+<p>The character repertoire of HyperSQL is the UTF16 character
+      set, which covers all possible character sets. If a predefined character
+      set is specified for a table column, then any string stored in the
+      column must contain only characters from the specified character
+      set.</p>
+<p>Early releases of HyperSQL version 2.0 may not enforce the
+      CHARACTER SET that is specified for a column and may accept any
+      character string.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B32"></a>Collations</h3>
+</div>
+</div>
+</div>
+<p>A COLLATION is the method used for ordering character strings
+      in ordered sets and to determine equivalence of two character
+      strings.</p>
+<p>There are several predefined collations. These collations
+      belong to INFORMATION_SCHEMA. However, when they are referenced in a
+      statement, no schema prefix can be used in the statement that references
+      them.</p>
+<p>There is a separate name-space for collations..</p>
+<p>Collations for a large number of languages are supported by
+      HyperSQL.</p>
+<p>Early releases of HyperSQL version 2.0 only support a single
+      collation for the whole database.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B3F"></a>Distinct Types</h3>
+</div>
+</div>
+</div>
+<p>A distinct, user-defined TYPE is simply based on a built-in
+      type. A distinct TYPE is used in table definitions and in CAST
+      statements.</p>
+<p>Distinct types share a name-space with domains.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B46"></a>Domains</h3>
+</div>
+</div>
+</div>
+<p>A DOMAIN is a user-defined type, simply based on a built-in
+      type. A DOMAIN can have constraints that limit the values that the
+      DOMAIN can represent. A DOMAIN can be used in table definitions and in
+      CAST statements.</p>
+<p>Distinct types share a name-space with domains.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B4D"></a>Number Sequences</h3>
+</div>
+</div>
+</div>
+<p>A SEQUENCE object produces INTEGER values in sequence. The
+      SEQUENCE can be referenced in special contexts only within certain SQL
+      statements. For each row where the object is referenced, its value is
+      incremented.</p>
+<p>There is a separate name-space for SEQUENCE objects.</p>
+<p>IDENTITY columns are columns of tables which have an internal,
+      unnamed SEQUENCE object.</p>
+<p>SEQUENCE objects and IDENTITY columns are supported fully
+      according to the latest SQL 2008 Standard syntax.</p>
+<p>
+<span class="bold"><strong>Sequences</strong></span>
+</p>
+<p>The SQL:2008 syntax and usage is different from what is supported
+      by many existing database engines. Sequences are created with the
+      <code class="literal">CREATE SEQUENCE</code> command and their current value can
+      be modified at any time with <code class="literal">ALTER SEQUENCE</code>. The next
+      value for a sequence is retrieved with the <code class="literal">NEXT VALUE FOR
+      &lt;name&gt;</code> expression. This expression can be used for
+      inserting and updating table rows.</p>
+<div class="example">
+<a name="N10B67"></a>
+<p class="title">
+<b>Example&nbsp;4.1.&nbsp;inserting the next sequence value into a table row</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">INSERT INTO mytable VALUES 2, 'John', NEXT VALUE FOR mysequence;</pre>
+</div>
+</div>
+<br class="example-break">
+<p>You can also use it in select statements. For example, if you want
+      to number the returned rows of a SELECT in sequential order, you can
+      use:</p>
+<div class="example">
+<a name="N10B6E"></a>
+<p class="title">
+<b>Example&nbsp;4.2.&nbsp;numbering returned rows of a SELECT in sequential order</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">SELECT NEXT VALUE FOR mysequence, col1, col2 FROM mytable WHERE ...</pre>
+</div>
+</div>
+<br class="example-break">
+<p>In version 2.0, the semantics of sequences is exactly as defined
+      by SQL:2008. If you use the same sequence twice in the same row in an
+      INSERT statement, you will get the same value as required by the
+      Standard.</p>
+<p>The correct way to use a sequence value is the NEXT VALUE FOR
+      expression. You can query the SEQUENCES table for the next value that
+      will be returned from any of the defined sequences. The SEQUENCE_NAME
+      column contains the name and the NEXT_VALUE column contains the next
+      value to be returned. Note that this is only for getting information and
+      you should not use the sequence value.</p>
+<p>
+<span class="bold"><strong>Identity Auto-Increment
+      Columns</strong></span>
+</p>
+<p>Each table can contain a single auto-increment column, known as
+      the IDENTITY column. An IDENTITY column is a SMALLINT, INTEGER, BIGINT,
+      DECIMAL or NUMERIC column with its value generated by a sequence
+      generator.</p>
+<p>In HyperSQL 2.0, an IDENTITY column is not by default treated as
+      the primary key for the table (as a result, multi-column primary keys
+      are possible with an IDENTITY column present).</p>
+<p>The SQL standard syntax is used, which allows the initial value
+      and other options to be specified.<pre class="programlisting">&lt;colname&gt; [ INTEGER | BIGINT | DECIMAL | NUMERIC ] GENERATED { BY DEFAULT | ALWAYS} AS IDENTITY [( &lt;options&gt; )] [PRIMARY KEY]</pre>
+</p>
+<p>When you add a new row to such a table using an <code class="literal">INSERT
+      INTO &lt;tablename&gt; ... </code>statement, you can use the DEFAULT
+      keyword for the IDENTITY column, which results in an auto-generated
+      value for the column. The <code class="literal">IDENTITY() </code>function returns
+      the last value inserted into any IDENTITY column by this session. Each
+      session manages this function call separately and is not affected by
+      inserts in other sessions. Use <code class="literal">CALL IDENTITY() </code>as an
+      SQL statement to retrieve this value. If you want to use the value for a
+      field in a child table, you can use <code class="literal">INSERT INTO
+      &lt;childtable&gt; VALUES (...,IDENTITY(),...);</code>. Both types of
+      call to<code class="literal"> IDENTITY()</code> must be made before any additional
+      update or insert statements are issued by the session.</p>
+<p>The last inserted IDENTITY value can also be retrieved via JDBC,
+      by specifying the Statement or PreparedStatement object to return the
+      generated value.</p>
+<p>The next IDENTITY value to be used can be changed with following
+      statement. Note that this statement is not used in normal operation and
+      is only for special purposes: <pre class="programlisting">ALTER TABLE ALTER COLUMN &lt;column name&gt; RESTART WITH &lt;new value&gt;;</pre>For
+      backward compatibility, support has been retained for <code class="literal">CREATE
+      TABLE &lt;tablename&gt;(&lt;colname&gt; IDENTITY, ...)</code> as a
+      shortcut which defines the column both as an IDENTITY column and a
+      PRIMARY KEY column. Also, for backward compatibility, it is possible to
+      use NULL as the value of an IDENTITY column in an INSERT statement and
+      the value will be generated automatically. You should avoid these
+      compatibility features as they may be removed from future versions of
+      HyperSQL.</p>
+<p>In the following example, the identity value for the first INSERT
+      statement is generated automatically using the DEFAULT keyword. The
+      second INSERT statement uses a call to the IDENTITY() function to
+      populate a row in the child table with the generated identity
+      value.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE star (id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 
+   firstname VARCHAR(20),
+   lastname VARCHAR(20))
+CREATE TABLE movies (starid INTEGER, movieid INTEGER PRIMARY KEY, title VARCHAR(40)) 
+INSERT INTO star (id, firstname, lastname) VALUES (DEFAULT, 'Felix', 'the Cat')
+INSERT INTO movies (starid, movieid, title) VALUES (IDENTITY(), 10, 'Felix in Hollywood')
+</pre>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10BA3"></a>Tables</h3>
+</div>
+</div>
+</div>
+<p>In the SQL environment, tables are the most essential
+      components, as they hold all persistent data.</p>
+<p>If TABLE is considered as metadata (i.e. without its actual
+      data) it is called a <span class="emphasis"><em>relation</em></span> in relational theory.
+      It has one or more columns, with each column having a distinct name and
+      a data type. A table usually has one or more constraints which limit the
+      values that can potentially be stored in the TABLE. These constraints
+      are discussed in the next section.</p>
+<p>A single column of the table can be defined as IDENTITY. The
+      values stored in this column are auto-generated and are based on an
+      (unnamed) identity sequence.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10BAF"></a>Views</h3>
+</div>
+</div>
+</div>
+<p>A VIEW is similar to a TABLE but it does not permanently
+      contain rows of data. A view is defined as a QUERY EXPRESSION, which is
+      often a SELECT statement that references views and tables, but it can
+      also consist of a TABLE CONSTRUCTOR that does not reference any tables
+      or views.</p>
+<p>A view has many uses:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Hide the structure and column names of tables. The view can
+          represent one or more tables or views as a separate table. This can
+          include aggregate data, such as sums and averages, from other
+          tables.</p>
+</li>
+<li>
+<p>Allow access to specific rows in a table. For example, allow
+          access to records that were added since a given date, while hiding
+          older records.</p>
+</li>
+<li>
+<p>Allow access to specific columns. For example allow access to
+          columns that contain non-confidential information. Note that this
+          can also be achieved with the GRANT SELECT statement, using
+          column-level privileges</p>
+</li>
+</ul>
+</div>
+<p>A VIEW that returns the columns of a single ordinary TABLE may
+      be <em class="glossterm">updatable</em>. Some
+      <em class="glossterm">updatable</em> views are
+      <em class="glossterm">insertable-into</em>. When rows of an updatable view
+      are updated, or new rows are inserted, these changes are reflected in
+      the base table. A VIEW definition may specify that the inserted or
+      updated rows conform to the search condition of the view. This is done
+      with the CHECK OPTION clause.</p>
+<p>Views share a name-space with tables.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10BCD"></a>Constraints</h3>
+</div>
+</div>
+</div>
+<p>A CONSTRAINT is a child schema object and can belong to a
+      DOMAIN or a TABLE. CONSTRAINT objects can be defined without specifying
+      a name. In this case the system generates a name for the new object
+      beginning with "SYS_".</p>
+<p>In a DOMAIN, CHECK constraints can be defined that limits the
+      value represented by the DOMAIN. These constraints work exactly like a
+      CHECK constraint on a single column of a table as described
+      below.</p>
+<p>In a TABLE, a constraint takes three basic forms.</p>
+<p>
+<span class="bold"><strong>CHECK</strong></span>
+</p>
+<p>A CHECK constraint consists of a <code class="literal">&lt;search
+      condition&gt;</code> that must not be false (can be unknown) for each
+      row of the table. The <code class="literal">&lt;search condition&gt;</code> can
+      reference all the columns of the current row, and if it contains a
+      <code class="literal">&lt;subquery&gt;</code>, other tables and views in the
+      database (excluding its own table).</p>
+<p>
+<span class="bold"><strong>NOT NULL</strong></span>
+</p>
+<p>A simple form of check constraint is the NOT NULL constraint,
+      which applies to a single column.</p>
+<p>
+<span class="bold"><strong>UNIQUE</strong></span>
+</p>
+<p>A UNIQUE constraint is based on an equality comparison of
+      values of specific columns (taken together) of one row with the same
+      values from each of the other rows. The result of the comparison must
+      never be true (can be false or unknown). If a row of the table has NULL
+      in any of the columns of the constraint, it conforms to the constraint.
+      A unique constraint on multiple columns (c1, c2, c3, ..) means that in
+      no two rows, the sets of values for the columns can be equal unless at
+      lease one of them is NULL. Each single column taken by itself can have
+      repeat values in different rows. The following example satisfies a
+      UNIQUE constraint on the two columns</p>
+<div class="example">
+<a name="N10BF2"></a>
+<p class="title">
+<b>Example&nbsp;4.3.&nbsp;Column values which satisfy a 2-column UNIQUE
+        constraint</b>
+</p>
+<div class="example-contents">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td>1,</td><td>2</td>
+</tr>
+<tr>
+<td>2,</td><td>1</td>
+</tr>
+<tr>
+<td>2,</td><td>2</td>
+</tr>
+<tr>
+<td>NULL,</td><td>1</td>
+</tr>
+<tr>
+<td>NULL,</td><td>1</td>
+</tr>
+<tr>
+<td>1,</td><td>NULL</td>
+</tr>
+<tr>
+<td>NULL,</td><td>NULL</td>
+</tr>
+<tr>
+<td>NULL,</td><td>NULL</td>
+</tr>
+</table>
+</div>
+</div>
+<br class="example-break">
+<p>
+<span class="bold"><strong>PRIMARY KEY</strong></span>
+</p>
+<p>A PRIMARY KEY constraint is equivalent to a UNIQUE constraint
+      on one or more NOT NULL columns. Only one PRIMARY KEY can be defined in
+      each table.</p>
+<p>
+<span class="bold"><strong>FOREIGN KEY</strong></span>
+</p>
+<p>A FOREIGN key constraint is based on an equality comparison
+      between values of specific columns (taken together) of each row with the
+      values of the columns of a UNIQUE constraint on another table or the
+      same table. The result of the comparison must never be false (can be
+      unknown). A special form of FOREIGN KEY constraint, based on its CHECK
+      clause, allows the result to be unknown only if the values for all
+      columns are NULL. A FOREIGN key can be declared only if a UNIQUE
+      constraint exists on the referenced columns.</p>
+<p>Constraints share a name space with assertions.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C26"></a>Assertions</h3>
+</div>
+</div>
+</div>
+<p>An ASSERTION is a top-level schema objects. It consists of a
+      <code class="literal">&lt;search condition&gt;</code> that must not be false (can
+      be unknown).</p>
+<p>Assertions share a name-space with constraints</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C30"></a>Triggers</h3>
+</div>
+</div>
+</div>
+<p>A TRIGGER is a child schema object that always belongs to a
+      TABLE or a VIEW.</p>
+<p>Each time a DELETE, UPDATE or INSERT is performed on the table
+      or view, additional actions are taken by the triggers that have been
+      declared on the table or view.</p>
+<p>Triggers are discussed in detail in chapter <a class="link" href="triggers-chapt.html" title="Chapter&nbsp;9.&nbsp;Triggers">Triggers</a>
+      .</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C3E"></a>Routines</h3>
+</div>
+</div>
+</div>
+<p>Routines are user-defined functions or procedures. The names
+      and usage of functions and procedures are different. FUNCTION is a
+      routine that can be referenced in many types of statements. PROCEDURE is
+      a routine that can be referenced only in a CALL statement.</p>
+<p>There is a separate name-space for routines.</p>
+<p>Because of the possibility of overloading, each routine can
+      have more than one name. The name of the routine is the same for all
+      overloaded variants, but each variant has a <em class="glossterm">specific
+      name</em>, different from all other routine names and specific
+      names in the schema. The <em class="glossterm">specific name</em> can be
+      specified in the routine definition statement. Otherwise it is assigned
+      by the engine. The specific name is used only for schema manipulation
+      statements, which need to reference a specific variant of the routine.
+      For example, if a routine has two signatures, each signature has its own
+      <em class="glossterm">specific name</em>. This allows the user to drop one
+      of the signatures while keeping the other.</p>
+<p>Routines are discussed in detail in chapter <a class="link" href="sqlroutines-chapt.html" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">SQL-Invoked Routines</a> .</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C57"></a>Indexes</h3>
+</div>
+</div>
+</div>
+<p>Indexes are an implementation-defined extension to the SQL
+      Standard. HyperSQL has a dedicated name-space for indexes in each
+      schema.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10C5C"></a>Statements for Schema Definition and Manipulation</h2>
+</div>
+</div>
+</div>
+<p>Schemas and schema objects can be created, modified and dropped.
+    The SQL Standard defines a range of statements for this purpose. HyperSQL
+    supports many additional statements, especially for changing the
+    properties of existing schema objects.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C61"></a>Common Elements and Statements</h3>
+</div>
+</div>
+</div>
+<p>These elements and statements are used for different types of
+      object. They are described here, before the statements that can use
+      them.</p>
+<a name="N10C66" class="indexterm"></a>
+<p>
+<span class="bold"><strong>identifier</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>definition of identifier</em></span>
+</p>
+<p>
+<code class="literal">&lt;identifier&gt; ::= &lt;regular identifier&gt; |
+      &lt;delimited identifier&gt; | &lt;SQL language identifier&gt;
+      </code>
+</p>
+<p>
+<code class="literal">&lt;delimited identifier&gt; ::= &lt;double quote&gt;
+      &lt;character sequence&gt; &lt;double quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;regular identifier&gt; ::= &lt;special character
+      sequence&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL language identifier&gt; ::= &lt;special
+      character sequence&gt;</code>
+</p>
+<p>A <code class="literal">&lt;delimited identifier&gt;</code> is a sequence
+      of characters enclosed with double-quote symbols. All characters are
+      allowed in the character sequence.</p>
+<p>A <code class="literal">&lt;regular identifier&gt;</code> is a special
+      sequence of characters. It consists of letters, digits and the
+      underscore characters. It must begin with a letter.</p>
+<p>A <code class="literal">&lt;SQL language identifier&gt;</code> is similar
+      to <code class="literal">&lt;regular identifier&gt;</code> but the letters can
+      range only from A-Z in the ASCII character set. This type of identifier
+      is used for names of CHARACTER SET objects.</p>
+<p>If the character sequence of a delimited identifier is the same
+      as an undelimited identifier, it represents the same identifier. For
+      example "JOHN" is the same identifier as JOHN. In a <code class="literal">&lt;regular
+      identifier&gt;</code> the case-normal form is considered for
+      comparison. This form consists of the upper-case of equivalent of all
+      the letters.</p>
+<p>The character sequence length of all identifiers must be
+      between 1 and 128 characters.</p>
+<p>A reserved word is one that is used by the SQL Standard for
+      special purposes. It is similar to a <code class="literal">&lt;regular
+      identifier&gt;</code> but it cannot be used as an identifier for user
+      objects. If a reserved word is enclosed in double quote characters, it
+      becomes a quoted identifier and can be used for database
+      objects.</p>
+<a name="N10C9C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CASCADE or RESTRICT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop behavior</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop behavior&gt; ::= CASCADE |
+      RESTRICT</code>
+</p>
+<p>The <code class="literal">&lt;drop behavior&gt;</code> is a required
+      element of statements that drop a SCHEMA or a schema object. If
+      <code class="literal">&lt;drop behavior&gt;</code> is not specified then
+      <code class="literal">RESTRICT</code> is implicit. It determines the effect of the
+      statement if there are other objects in the catalog that reference the
+      SCHEMA or the schema object. If RESTRICT is specified, the statement
+      fails if there are referencing objects. If CASCADE is specified, all the
+      referencing objects are modified or dropped with cascading effect.
+      Whether a referencing object is modified or dropped, depends on the kind
+      of schema object that is dropped.</p>
+<a name="N10CB6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IF EXISTS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop condition (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;if exists clause&gt; ::= IF
+      EXISTS</code>
+</p>
+<p>This clause is not part of the SQL standard and is a HyperSQL
+      extension to some commands that drop objects (schemas, tables, views,
+      sequences and indexes). If it is specified, then the statement does not
+      return an error if the drop statement is issued on a non-existent
+      object.</p>
+<a name="N10CC7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SPECIFIC</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>specific routine designator</em></span>
+</p>
+<p>
+<code class="literal">&lt;specific routine designator&gt; ::= SPECIFIC
+      &lt;routine type&gt; &lt;specific name&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;routine type&gt; ::= ROUTINE | FUNCTION |
+      PROCEDURE</code>
+</p>
+<p>This clause is used in statements that need to specify one of
+      the multiple versions of an overloaded routine. The
+      <code class="literal">&lt;specific name&gt;</code> is the one specified in the
+      <code class="literal">&lt;routine definition&gt;</code> statement.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10CE1"></a>Renaming Objects</h3>
+</div>
+</div>
+</div>
+<a name="N10CE4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RENAME</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>rename statement (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;rename statement&gt; ::= ALTER &lt;object type&gt;
+      &lt;name&gt; RENAME TO &lt;new name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;object type&gt; ::= CATALOG | SCHEMA | DOMAIN |
+      TYPE | TABLE | CONSTRAINT | INDEX | ROUTINE | SPECIFIC
+      ROUTINE</code>
+</p>
+<p>
+<code class="literal">&lt;column rename statement&gt; ::= ALTER TABLE
+      &lt;table name&gt; ALTER COLUMN &lt;name&gt; RENAME TO &lt;new
+      name&gt;</code>
+</p>
+<p>This statement is used to rename an existing object. It is not
+      part of the SQL Standard. The specified <code class="literal">&lt;name&gt;</code>
+      is the existing name, which can be qualified with a schema name, while
+      the <code class="literal">&lt;new name&gt;</code> is the new name for the
+      object.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10D01"></a>Commenting Objects</h3>
+</div>
+</div>
+</div>
+<a name="N10D04" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COMMENT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>comment statement (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;comment statement&gt; ::= COMMENT ON { TABLE |
+      COLUMN | ROUTINE } &lt;name&gt; IS &lt;character string
+      literal&gt;</code>
+</p>
+<p>Adds a comment to the object metadata, which can later be read
+      from an INFORMATION_SCHEMA view. This command is not part of the SQL
+      Standard. The strange syntax is due to compatibility with other database
+      engines that support the statement.<code class="literal"> The &lt;name&gt;</code>
+      is the name of a table, view, column or routine. The name of the column
+      consists of dot-separated<code class="literal"> &lt;table name&gt; . &lt;column
+      name&gt;</code>. The name of the table, view or routine can be a
+      simple name. All names can be qualified with a schema name. If there is
+      alread a comment on the object, the new comment will replace
+      it.</p>
+<p>The comments appear in the results returned by JDBC
+      DatabaseMetaData methods, getTables() and getColumns(). The
+      INFORMATION_SCHEMA.SYSTEM_COMMENTS view contains the comments. You can
+      query this view using the schema, table, and column names to retreive
+      the comments.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10D1D"></a>Schema Creation</h3>
+</div>
+</div>
+</div>
+<a name="N10D20" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>schema definition</em></span>
+</p>
+<p>The CREATE_SCHEMA or DBA role is required in order to create a
+      schema. A schema can be created with or without schema objects. Schema
+      objects can always be added after creating the schema, or existing ones
+      can be dropped. Within the <code class="literal">&lt;schema definition&gt;</code>
+      statement, all schema object creation takes place inside the newly
+      created schema. Therefore, if a schema name is specified for the schema
+      objects, the name must match that of the new schema. In addition to
+      statements for creating schema objects, the statement can include
+      instances of <code class="literal">&lt;grant statement&gt;</code> and
+      <code class="literal">&lt;role definition&gt;</code>. This is a curious aspect of
+      the SQL standard, as these elements do not really belong to schema
+      creation.</p>
+<p>
+<code class="literal">&lt;schema definition&gt; ::= CREATE SCHEMA &lt;schema
+      name clause&gt; [ &lt;schema character set specification&gt; ] [
+      &lt;schema element&gt;... ]</code>
+</p>
+<p>
+<code class="literal">&lt;schema name clause&gt; ::= &lt;schema name&gt; |
+      AUTHORIZATION &lt;authorization identifier&gt; | &lt;schema name&gt;
+      AUTHORIZATION &lt;authorization identifier&gt;</code>
+</p>
+<p>If the name of the schema is specified simply as
+      <code class="literal">&lt;schema name&gt;</code>, then the AUTHORIZATION is the
+      current user. Otherwise, the specified <code class="literal">&lt;authorization
+      identifier&gt;</code> is used as the AUTHORIZATION for the schema. If
+      <code class="literal">&lt;schema name&gt;</code> is omitted, then the name of the
+      schema is the same as the specified <code class="literal">&lt;authorization
+      identifier&gt;</code>.</p>
+<p>
+<code class="literal">&lt;schema element&gt; ::= &lt;table definition&gt; |
+      &lt;view definition&gt; | &lt;domain definition&gt; | &lt;character set
+      definition&gt; | &lt;collation definition&gt; | &lt;transliteration
+      definition&gt; | &lt;assertion definition&gt; | &lt;trigger
+      definition&gt; | &lt;user-defined type definition&gt; | &lt;user-defined
+      cast definition&gt; | &lt;user-defined ordering definition&gt; |
+      &lt;transform definition&gt; | &lt;schema routine&gt; | &lt;sequence
+      generator definition&gt; | &lt;grant statement&gt; | &lt;role
+      definition&gt;</code>
+</p>
+<p>An example of the command is given below. Note that a single
+      semicolon appears at the end, there should be no semicolon between the
+      statements:</p>
+<pre class="programlisting">    CREATE SCHEMA ACCOUNTS AUTHORIZATION DBA
+        CREATE TABLE AB(A INTEGER, ...)
+        CREATE TABLE CD(C CHAR(10), ...)
+        CREATE VIEW VI AS SELECT ...
+        GRANT SELECT ON AB TO PUBLIC
+        GRANT SELECT ON CD TO JOE;
+</pre>
+<p>It is not really necessary to create a schema and all its
+      objects as one command. The schema can be created first, and its objects
+      can be created one by one.</p>
+<a name="N10D54" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop schema statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop schema statement&gt; ::= DROP SCHEMA [ IF
+      EXISTS ] &lt;schema name&gt; [ IF EXISTS ] &lt;drop behavior&gt;
+      </code>
+</p>
+<p>This command destroys an existing schema. If <code class="literal">&lt;drop
+      behavior&gt;</code> is <code class="literal">RESTRICT</code>, the schema must
+      be empty, otherwise an error is raised. If <code class="literal">CASCADE</code> is
+      specified, then all the objects contained in the schema are destroyed
+      with a CASCADE option.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10D6E"></a>Table Creation and Manipulation</h3>
+</div>
+</div>
+</div>
+<a name="N10D71" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>table definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;table definition&gt; ::= CREATE [ { &lt;table
+      scope&gt; | &lt;table type&gt; } ] TABLE &lt;table name&gt; &lt;table
+      contents source&gt; [ ON COMMIT { PRESERVE | DELETE } ROWS
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;table scope&gt; ::= { GLOBAL | LOCAL }
+      TEMPORARY</code>
+</p>
+<p>
+<code class="literal">&lt;table type&gt; :: = MEMORY |
+      CACHED</code>
+</p>
+<p>
+<code class="literal">&lt;table contents source&gt; ::= &lt;table element
+      list&gt; | &lt;as subquery clause&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table element list&gt; ::= &lt;left paren&gt;
+      &lt;table element&gt; [ { &lt;comma&gt; &lt;table element&gt; }... ]
+      &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table element&gt; ::= &lt;column definition&gt; |
+      &lt;table constraint definition&gt; | &lt;like
+      clause&gt;</code>
+</p>
+<p>
+<span class="emphasis"><em>like clause</em></span>
+</p>
+<p>A <code class="literal">&lt;like clause&gt;</code> copies all column
+      definitions from another table into the newly created table. Its three
+      options indicate if the <code class="literal">&lt;default clause&gt;</code>,
+      <code class="literal">&lt;identity column specification&gt;</code> and
+      <code class="literal">&lt;generation clause&gt;</code> associated with the column
+      definitions are copied or not. If an option is not specified, it
+      defaults to <code class="literal">EXCLUDING</code>. The <code class="literal">&lt;generation
+      clause&gt;</code> refers to columns that are generated by an
+      expression but not to identity columns. All NOT NULL constraints are
+      copied with the original columns, other constraints are not. The
+      <code class="literal">&lt;like clause&gt;</code> can be used multiple times,
+      allowing the new table to have copies of the column definitions of one
+      or more other tables.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (id INTEGER PRIMARY KEY, LIKE atable INCLUDING DEFAULTS EXCLUDING IDENTITY)
+</pre>
+</div>
+<p>
+<code class="literal">&lt;like clause&gt; ::= LIKE &lt;table name&gt; [
+      &lt;like options&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;like options&gt; ::= &lt;like
+      option&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;like option&gt; ::= &lt;identity option&gt; |
+      &lt;column default option&gt; | &lt;generation
+      option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;identity option&gt; ::= INCLUDING IDENTITY |
+      EXCLUDING IDENTITY</code>
+</p>
+<p>
+<code class="literal">&lt;column default option&gt; ::= INCLUDING DEFAULTS |
+      EXCLUDING DEFAULTS</code>
+</p>
+<p>
+<code class="literal">&lt;generation option&gt; ::= INCLUDING GENERATED |
+      EXCLUDING GENERATED</code>
+</p>
+<p>
+<span class="emphasis"><em>as subquery clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;as subquery clause&gt; ::= [ &lt;left paren&gt;
+      &lt;column name list&gt; &lt;right paren&gt; ] AS &lt;table subquery&gt;
+      { WITH NO DATA | WITH DATA }</code>
+</p>
+<p>An <code class="literal">&lt;as subquery clause&gt;</code> used in table
+      definition creates a table based on a <code class="literal">&lt;table
+      subquery&gt;</code>. This kind of table definition is similar to a
+      view definition. If <code class="literal">WITH DATA</code> is specified, then the
+      new table will contain the rows of data returned by the
+      <code class="literal">&lt;table subquery&gt;</code>.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (a, b, c) AS (SELECT * FROM atable) WITH DATA
+</pre>
+</div>
+<a name="N10DD5" class="indexterm"></a>
+<p>
+<span class="emphasis"><em>column definition</em></span>
+</p>
+<p>A column definition consists of a <code class="literal">&lt;column
+      name&gt;</code> and in most cases a <code class="literal">&lt;data
+      type&gt;</code> or <code class="literal">&lt;domain name&gt;</code> as minimum.
+      The other elements of <code class="literal">&lt;column definition&gt;</code> are
+      optional. Each <code class="literal">&lt;column name&gt;</code> in a table is
+      unique.</p>
+<p>
+<code class="literal">&lt;column definition&gt; ::= &lt;column name&gt; [
+      &lt;data type or domain name&gt; ] [ &lt;default clause&gt; |
+      &lt;identity column specification&gt; | &lt;generation clause&gt; ] [
+      &lt;column constraint definition&gt;... ] [ &lt;collate clause&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;data type or domain name&gt; ::= &lt;data type&gt;
+      | &lt;domain name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;column constraint definition&gt; ::= [
+      &lt;constraint name definition&gt; ] &lt;column constraint&gt; [
+      &lt;constraint characteristics&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;column constraint&gt; ::= NOT NULL | &lt;unique
+      specification&gt; | &lt;references specification&gt; | &lt;check
+      constraint definition&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;identity column specification&gt; ::= GENERATED {
+      ALWAYS | BY DEFAULT } AS IDENTITY [ &lt;left paren&gt; &lt;common
+      sequence generator options&gt; &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;generation clause&gt; ::= GENERATED ALWAYS AS
+      &lt;generation expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;generation expression&gt; ::= &lt;left paren&gt;
+      &lt;value expression&gt; &lt;right paren&gt;</code>
+</p>
+<p>The <code class="literal">&lt;identity column specification&gt;</code>
+      can be specified for only a single column of the table.</p>
+<p>A <code class="literal">&lt;column constraint definition&gt;</code> is a
+      shortcut for a <code class="literal">&lt;table constraint definition&gt;</code>. A
+      constraint that is defined in this way is automatically turned into a
+      table constraint. A name is automatically generated for the constraint
+      and assigned to it.</p>
+<p>The <code class="literal">&lt;identity column specification&gt;</code> is
+      used for special columns which represent values based on unnamed
+      sequence generators. It is possible to insert a row into the able
+      without specifying a value for the column. The value is then generated
+      by the sequence generators according to its rules. An identity column
+      may or may not be the primary key. Example below:</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (id INTEGER GENERATED ALWAYS AS IDENTITY(START WITH 100), name VARCHAR(20) PRIMARY KEY, )
+</pre>
+</div>
+<p>The <code class="literal">&lt;generation clause&gt;</code> is used for
+      special columns which represent values based on the values held in other
+      columns in the same row. The <code class="literal">&lt;value expression&gt;</code>
+      must reference only other, non-generated, columns of the table in the
+      same row. Therefore, any function used in the expression may not access
+      SQL-data, and no <code class="literal">&lt;query expression&gt;</code> is allowed.
+      When <code class="literal">&lt;generation clause&gt;</code> is used,
+      <code class="literal">&lt;data type&gt;</code> or <code class="literal">&lt;domain
+      name&gt;</code> may be omitted.</p>
+<p>A generated column can be part of a foreign key or unique
+      constraints or a column of an index. This capability is the main reason
+      for using generated columns. A generated column may contain a formula
+      that computes a value based on the values of other columns. Fast
+      searches of the computed value can be performed when an index is
+      declared on the generated column. Or the computed values can be declared
+      to be unique, using a UNIQUE constraint on the table.</p>
+<p>When a row is inserted into a table, or an existing row is
+      updated, no value except DEFAULT can be specified for a generated
+      column. In the example below, data is inserted into the non-generated
+      columns and the generated column will contain 'Felix the Cat' or 'Pink
+      Panther'.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (id INTEGER PRIMARY KEY, 
+   firstname VARCHAR(20),
+   lastname VARCHAR(20), 
+   fullname VARCHAR(40) GENERATED ALWAYS AS (firstname || ' ' || lastname)) 
+INSERT INTO t (id, firstname, lastname) VALUES (1, 'Felix', 'the Cat')
+INSERT INTO t (id, firstname, lastname, fullname) VALUES (2, 'Pink', 'Panther', DEFAULT)
+</pre>
+</div>
+<a name="N10E33" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>default clause</em></span>
+</p>
+<p>A default clause can be used if GENERATED is not specified. If
+      a column has a <code class="literal">&lt;default clause&gt;</code> then it is
+      possible to insert a row into the table without specifying a value for
+      the column.</p>
+<p>
+<code class="literal">&lt;default clause&gt; ::= DEFAULT &lt;default
+      option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;default option&gt; ::= &lt;literal&gt; |
+      &lt;datetime value function&gt; | USER | CURRENT_USER | CURRENT_ROLE |
+      SESSION_USER | SYSTEM_USER | CURRENT_CATALOG | CURRENT_SCHEMA |
+      CURRENT_PATH | NULL</code>
+</p>
+<p>The type of the <code class="literal">&lt;default option&gt;</code> must
+      match the type of the column.</p>
+<a name="N10E4F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>constraint name and
+      characteristics</em></span>
+</p>
+<p>
+<code class="literal">&lt;constraint name definition&gt; ::= CONSTRAINT
+      &lt;constraint name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;constraint characteristics&gt; ::= &lt;constraint
+      check time&gt; [ [ NOT ] DEFERRABLE [ &lt;constraint check time&gt; ]
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;constraint check time&gt; ::= INITIALLY DEFERRED |
+      INITIALLY IMMEDIATE</code>
+</p>
+<p>Specify the name of a constraint and its characteristics. By
+      default the constraint is <code class="literal">NOT DEFERRABLE</code> and
+      <code class="literal">INITIALLY IMMEDIATE</code>. This means the constraint is
+      enforced as soon as a data change statement is executed. If
+      <code class="literal">INITIALLY DEFERRED</code> is specified, then the constraint
+      is enforced when the session commits. The characteristics must be
+      compatible. The constraint check time can be changed temporarily for an
+      SQL session. HyperSQL does not support deferring constraint enforcement.
+      This feature of the SQL Standard has been criticised because it allows a
+      session to read uncommitted data that violates database integrity
+      constraints but has not yet been checked.</p>
+<a name="N10E6F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>table constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;table constraint definition&gt; ::= [
+      &lt;constraint name definition&gt; ] &lt;table constraint&gt; [
+      &lt;constraint characteristics&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;table constraint&gt; ::= &lt;unique constraint
+      definition&gt; | &lt;referential constraint definition&gt; | &lt;check
+      constraint definition&gt;</code>
+</p>
+<p>Three kinds of constraint can be defined on a table: UNIQUE
+      (including PRIMARY KEY), FOREIGN KEY and CHECK. Each kind has its own
+      rules to limit the values that can be specified for different columns in
+      each row of the table.</p>
+<a name="N10E83" class="indexterm"></a><a name="N10E88" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UNIQUE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>unique constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;unique constraint definition&gt; ::= &lt;unique
+      specification&gt; &lt;left paren&gt; &lt;unique column list&gt;
+      &lt;right paren&gt; | UNIQUE ( VALUE )</code>
+</p>
+<p>
+<code class="literal">&lt;unique specification&gt; ::= UNIQUE | PRIMARY
+      KEY</code>
+</p>
+<p>
+<code class="literal">&lt;unique column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>A unique constraint is specified on a single column or on
+      multiple columns. On each set of columns taken together, only one UNIQUE
+      constraint can be specified. Each column of a PRIMARY KEY constraint has
+      an implicit NOT NULL constraint.</p>
+<p>If <code class="literal">UNIQUE( VALUE )</code> is specified, the
+      constraint created on all columns of the table.</p>
+<a name="N10EA4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>FOREIGN KEY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>referential constraint
+      definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;referential constraint definition&gt; ::= FOREIGN
+      KEY &lt;left paren&gt; &lt;referencing columns&gt; &lt;right paren&gt;
+      &lt;references specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;references specification&gt; ::= REFERENCES
+      &lt;referenced table and columns&gt; [ MATCH &lt;match type&gt; ] [
+      &lt;referential triggered action&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;match type&gt; ::= FULL | PARTIAL |
+      SIMPLE</code>
+</p>
+<p>
+<code class="literal">&lt;referencing columns&gt; ::= &lt;reference column
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;referenced table and columns&gt; ::= &lt;table
+      name&gt; [ &lt;left paren&gt; &lt;reference column list&gt; &lt;right
+      paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;reference column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;referential triggered action&gt; ::= &lt;update
+      rule&gt; [ &lt;delete rule&gt; ] | &lt;delete rule&gt; [ &lt;update
+      rule&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;update rule&gt; ::= ON UPDATE &lt;referential
+      action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;delete rule&gt; ::= ON DELETE &lt;referential
+      action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;referential action&gt; ::= CASCADE | SET NULL |
+      SET DEFAULT | RESTRICT | NO ACTION</code>
+</p>
+<p>A referential constraint allows links to be established between
+      the rows of two tables. The specified list of <code class="literal">&lt;referencing
+      columns&gt;</code> corresponds one by one to the columns of the
+      specified list of <code class="literal">&lt;referenced columns&gt;</code> in
+      another table (or sometimes in the same table). For each row in the
+      table, a row must exist in the referenced table with equivalent values
+      in the two column lists. There must exist a single unique constraint in
+      the referenced table on all the <code class="literal">&lt;referenced
+      columns&gt;</code>.</p>
+<p>The <code class="literal">[ MATCH match type ]</code> clause is optional
+      and has an effect only on multi-column foreign keys and only on rows
+      containing at least a NULL in one of the <code class="literal">&lt;referencing
+      columns&gt;</code>. If the clause is not specified, MATCH SIMPLE is
+      the default. If <code class="literal">MATCH SIMPLE</code> is specified, then any
+      NULL means the row can exist (without a corresponding row in the
+      referenced table). If <code class="literal">MATCH FULL</code> is specified then
+      either all the column values must be NULL or none of them.
+      <code class="literal">MATCH PARTIAL</code> allows any NULL but the non NULL values
+      must match those of a row in the referenced table. HyperSQL does not
+      support <code class="literal">MATCH PARTIAL</code>.</p>
+<p>Referential actions are specified with ON UPDATE and ON DELETE
+      clauses. These actions take place when a row in the referenced table
+      (the parent table) has referencing rows in the referencing table and it
+      is deleted or modified with any SQL statement. The default is NO ACTION.
+      This means the SQL statement that causes the DELETE or UPDATE is
+      terminated with an exception. The RESTRICT option is similar and works
+      exactly the same without deferrable constraints (which are not allowed
+      by HyperSQL). The other three options, CASCADE, SET NULL and SET DEFAULT
+      all allow the DELETE or UPDATE statement to complete. With DELETE
+      statements the CASCADE option results in the referencing rows to be
+      deleted. With UPDATE statements, the changes to the values of the
+      referenced columns are copied to the referencing rows. With both DELETE
+      or UPDATE statement, the SET NULL option results in the columns of the
+      referencing rows to be set to NULL. Similarly, the SET DEFAULT option
+      results in the columns of the referencing rows to be set to their
+      default values.</p>
+<a name="N10EEF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CHECK</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>check constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;check constraint definition&gt; ::= CHECK &lt;left
+      paren&gt; &lt;search condition&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>A CHECK constraint can exist for a TABLE or for a DOMAIN. The
+      <code class="literal">&lt;search condition&gt;</code> evaluates to an SQL BOOLEAN
+      value for each row of the table. Within the <code class="literal">&lt;search
+      condition&gt;</code> all columns of the table row can be referenced.
+      For all rows of the table, the <code class="literal">&lt;search
+      condition&gt;</code> evaluates to TRUE or UNKNOWN. When a new row is
+      inserted, or an existing row is updated, the <code class="literal">&lt;search
+      condition&gt;</code> is evaluated and if it is FALSE, the insert or
+      update fails.</p>
+<p>A CHECK constraint for a DOMAIN is similar. In its
+      <code class="literal">&lt;search condition&gt;</code>, the term VALUE is used to
+      represents the value to which the DOMAIN applies.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (a VARCHAR(20) CHECK (a IS NOT NULL AND CHARACTER_LENGTH(a) &gt; 2))
+</pre>
+</div>
+<p>The search condition of a CHECK constraint cannot contain any
+      function that is not deterministic. A check constraint is a data
+      integrity constraint, therefore it must hold with respect to the rest of
+      the data in the database. It cannot use values that are temporal or
+      ephemeral. For example CURRENT_USER is a function that returns different
+      values depending on who is using the database, or CURRENT_DATE changes
+      day-to-day. Some temporal expressions are retrospectively deterministic
+      and are allowed in check constraints. For example, (CHECK VALUE &lt;
+      CURRENT_DATE) is valid, because CURRENT_DATE will not move backwards in
+      time, but (CHECK VALUE &gt; CURRENT_DATE) is not acceptable.</p>
+<p>If you want to enforce the condition that a date value that is
+      inserted into the database belongs to the future (at the time of
+      insertion), or any similar constraint, then use a TRIGGER with the
+      desired condition.</p>
+<a name="N10F18" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TABLE
+      writeability</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set table write property
+      (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;set table read only statement&gt; ::= SET TABLE
+      &lt;table name&gt; { READ ONLY | READ WRITE }</code>
+</p>
+<p>Set the writeability property of a table. Tables are writable
+      by default. This statement can be used to change the property between
+      <code class="literal">READ ONLY</code> and <code class="literal">READ WRITE</code>. This is
+      a feature of HyperSQL.</p>
+<a name="N10F2F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TABLE SOURCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set table source statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set table source statement&gt; ::= SET TABLE
+      &lt;table name&gt; SOURCE &lt;file and options&gt;
+      [DESC]</code>
+</p>
+<p>
+<code class="literal">&lt;file and options&gt;::= &lt;doublequote&gt;
+      &lt;file path&gt; [&lt;semicolon&gt; &lt;property&gt;...]
+      &lt;doublequote&gt; </code>
+</p>
+<p>Set the text source for a text table. This statement cannot be
+      used for tables that are not defined as TEXT TABLE.</p>
+<div class="variablelist">
+<p class="title">
+<b>Supported Properties</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">quoted = { true | false }</span>
+</p>
+</td><td>
+<p>default is true. If false, treats double quotes as normal
+            characters</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">all_quoted = { true | false }</span>
+</p>
+</td><td>
+<p>default is false. If true, adds double quotes around all
+            fields.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">encoding = &lt;encoding name&gt;</span>
+</p>
+</td><td>
+<p>character encoding for text and character fields, for
+            example, encoding=UTF-8</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">ignore_first = { true | false }</span>
+</p>
+</td><td>
+<p>default is false. If true ignores the first line of the
+            file</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">cache_scale= &lt;numeric value&gt;</span>
+</p>
+</td><td>
+<p>exponent to calculate rows of the text file in cache.
+            Default is 8, equivalent to nearly 800 rows</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">cache_size_scale = &lt;numeric value&gt;r</span>
+</p>
+</td><td>
+<p>exponent to calculate average size of each row in cache.
+            Default is 8, equivalent to 256 bytes per row.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">fs = &lt;unquoted character&gt;</span>
+</p>
+</td><td>
+<p>field separator</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">vs = &lt;unquoted character&gt;</span>
+</p>
+</td><td>
+<p>varchar separator</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Special indicators for HyperSQL Text Table separators</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">\semi</span>
+</p>
+</td><td>
+<p>semicolon</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\quote</span>
+</p>
+</td><td>
+<p>quote</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\space</span>
+</p>
+</td><td>
+<p>space character</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\apos</span>
+</p>
+</td><td>
+<p>apostrophe</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\n</span>
+</p>
+</td><td>
+<p>newline - Used as an end anchor (like $ in regular
+            expressions)</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\r</span>
+</p>
+</td><td>
+<p>carriage return</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\t</span>
+</p>
+</td><td>
+<p>tab</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\\</span>
+</p>
+</td><td>
+<p>backslash</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\u####</span>
+</p>
+</td><td>
+<p>a Unicode character specified in hexadecimal</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>In the example below, the text source of the table is set to
+      "myfile", the field separator to the pipe symbol, and the long varchar
+      separator to the tilde symbol.</p>
+<pre class="programlisting">    SET TABLE mytable SOURCE 'myfile;fs=|;vs=.;lvs=~'</pre>
+<p>Only a user with the DBA role can execute this
+      statement.</p>
+<a name="N10FB5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TABLE SOURCE
+      HEADER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set table source header
+      statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set table source header statement&gt; ::= SET
+      TABLE &lt;table name&gt; SOURCE HEADER &lt;header
+      string&gt;</code>
+</p>
+<p>Set the header for the text source for a text table. If this
+      command is used, the <code class="literal">&lt;header string&gt;</code> is used as
+      the first line of the source file of the text table. This line is not
+      part of the table data. Only a user with the DBA role can execute this
+      statement.</p>
+<a name="N10FC9" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TABLE SOURCE
+      on-off</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set table source on-off
+      statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set table source on-off statement&gt; ::= SET
+      TABLE &lt;table name&gt; SOURCE { ON | OFF } </code>
+</p>
+<p>Attach or detach a text table from its text source. This
+      command does not change the properties or the name of the file that is
+      the source of a text table. When OFF is specified, the command detaches
+      the table from its source and closes the file for the source. In this
+      state, it is not possible to read or write to the table. This allows the
+      user to replace the file with a different file, or delete it. When ON is
+      specified, the source file is read. Only a user with the DBA role can
+      execute this statement</p>
+<a name="N10FDA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter table statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter table statement&gt; ::= ALTER TABLE
+      &lt;table name&gt; &lt;alter table action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter table action&gt; ::= &lt;add column
+      definition&gt; | &lt;alter column definition&gt; | &lt;drop column
+      definition&gt; | &lt;add table constraint definition&gt; | &lt;drop
+      table constraint definition&gt;</code>
+</p>
+<p>Change the definition of a table. Specific types of this
+      statement are covered below.</p>
+<a name="N10FEE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ADD COLUMN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>add column definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;add column definition&gt; ::= ADD [ COLUMN ]
+      &lt;column definition&gt; [ BEFORE &lt;other column name&gt;
+      ]</code>
+</p>
+<p>Add a column to an existing table. The <code class="literal">&lt;column
+      definition&gt;</code> is specified the same way as it is used in
+      <code class="literal">&lt;table definition&gt;</code>. HyperSQL allows the use of
+      <code class="literal">[ BEFORE &lt;other column name&gt; ]</code> to specify at
+      which position the new column is added to the table.</p>
+<p>If the table contains rows, the new column must have a
+      <code class="literal">&lt;default clause&gt;</code> or use one of the forms of
+      GENERATED. The column values for each row is then filled with the result
+      of the <code class="literal">&lt;default clause&gt;</code> or the generated
+      value.</p>
+<a name="N11010" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER COLUMN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter column definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter column definition&gt; ::= ALTER [ COLUMN ]
+      &lt;column name&gt; &lt;alter column action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter column action&gt; ::= &lt;set column default
+      clause&gt; | &lt;drop column default clause&gt; | &lt;alter column data
+      type clause&gt; | &lt;alter identity column specification&gt; |
+      &lt;alter column nullability&gt; | &lt;alter column
+      name&gt;</code>
+</p>
+<p>Change a column and its definition. Specific types of this
+      statement are covered below. See also the RENAME statement
+      above.</p>
+<a name="N11024" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set column default clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;set column default clause&gt; ::= SET &lt;default
+      clause&gt;</code>
+</p>
+<p>Set the default clause for a column. This can be used if the
+      column is not defined as GENERATED.</p>
+<a name="N11035" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop column default clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop column default clause&gt; ::= DROP
+      DEFAULT</code>
+</p>
+<p>Drop the default clause from a column.</p>
+<a name="N11046" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATA TYPE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter column data type clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter column data type clause&gt; ::= SET DATA
+      TYPE &lt;data type&gt;</code>
+</p>
+<p>Change the declared type of a column. The (proposed) SQL
+      Standard allows only changes to type properties such as maximum length,
+      precision, or scale, and only changes that cause the property to
+      enlarge. HyperSQL allows changing the type if all the existing values
+      can be cast into the new type without string truncation or loss of
+      significant digits.</p>
+<a name="N11057" class="indexterm"></a>
+<p>
+<span class="bold"><strong>alter identity
+      column</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter identity column
+      specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter identity column specification&gt; ::=
+      &lt;alter identity column option&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;alter identity column option&gt; ::= &lt;alter
+      sequence generator restart option&gt; | SET &lt;basic sequence generator
+      option&gt;</code>
+</p>
+<p>Change the properties of an identity column. This command is
+      similar to the commands used for changing the properties of named
+      SEQUENCE objects discussed in this section.</p>
+<a name="N1106B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET NULL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter column nullability</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter column nullability&gt; ::= SET
+      NULL</code>
+</p>
+<p>Removes a NOT NULL constraint from a column. This option is
+      specific to HyperSQL</p>
+<a name="N1107C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP COLUMN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop column definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop column definition&gt; ::= DROP [ COLUMN ]
+      &lt;column name&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy a column of a base table. The <code class="literal">&lt;drop
+      behavior&gt;</code> is either <code class="literal">RESTRICT</code> or
+      <code class="literal">CASCADE</code>. If the column is referenced in a table
+      constraint that references other columns as well as this column, or if
+      the column is referenced in a VIEW, or the column is referenced in a
+      TRIGGER, then the statement will fail if <code class="literal">RESTRICT</code> is
+      specified. If <code class="literal">CASCADE</code> is specified, then any
+      CONSTRAINT, VIEW or TRIGGER object that references the column is dropped
+      with a cascading effect.</p>
+<a name="N1109C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ADD CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>add table constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;add table constraint definition&gt; ::= ADD
+      &lt;table constraint definition&gt;</code>
+</p>
+<p>Add a constraint to a table. The existing rows of the table
+      must conform to the added constraint, otherwise the statement will not
+      succeed.</p>
+<a name="N110AD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop table constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop table constraint definition&gt; ::= DROP
+      CONSTRAINT &lt;constraint name&gt; &lt;drop
+      behavior&gt;</code>
+</p>
+<p>Destroy a constraint on a table. The <code class="literal">&lt;drop
+      behavior&gt;</code> has an effect only on UNIQUE and PRIMARY KEY
+      constraints. If such a constraint is referenced by a FOREIGN KEY
+      constraint, the FOREIGN KEY constraint will be dropped if
+      <code class="literal">CASCADE</code> is specified. If the columns of such a
+      constraint are used in a GROUP BY clause in the query expression of a
+      VIEW or another kind of schema object, and a functional dependency
+      relationship exists between these columns and the other columns in that
+      query expression, then the VIEW or other schema object will be dropped
+      when <code class="literal">CASCADE</code> is specified.</p>
+<a name="N110C7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop table statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop table statement&gt; ::= DROP TABLE [ IF
+      EXISTS ] &lt;table name&gt; [ IF EXISTS ] &lt;drop
+      behavior&gt;</code>
+</p>
+<p>Destroy a table. The default drop behaviour is RESTRICT and
+      will cause the statement to fail if there is any view or foreign key
+      constraint that references the table. If <code class="literal">&lt;drop
+      behavior&gt;</code> is <code class="literal">CASCADE</code>, it causes all
+      schema objects that reference the table to drop. Referencing views are
+      dropped. In the case of foreign key constraints that reference the
+      table, the constraint is dropped, rather than the TABLE or DOMAIN that
+      contains it.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N110DE"></a>View Creation and Manipulation</h3>
+</div>
+</div>
+</div>
+<a name="N110E1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE VIEW</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>view definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;view definition&gt; ::= CREATE [ RECURSIVE ] VIEW
+      &lt;table name&gt; &lt;view specification&gt; AS &lt;query
+      expression&gt; [ WITH [ CASCADED | LOCAL ] CHECK OPTION
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;view specification&gt; ::= [ &lt;left paren&gt;
+      &lt;view column list&gt; &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;view column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>Define a view. The <code class="literal">&lt;query expression&gt;</code>
+      is a SELECT or similar statement. The <code class="literal">&lt;view column
+      list&gt;</code> is the list of unique names for the columns of the
+      view. The number of columns in the <code class="literal">&lt;view column
+      list&gt;</code> must match the number of columns returned by the
+      <code class="literal">&lt;query expression&gt;</code>. If <code class="literal">&lt;view column
+      list&gt;</code> is not specified, then the columns of the
+      <code class="literal">&lt;query expression&gt;</code> should have unique names and
+      are used as the names of the view column.</p>
+<p>Some views are updatable. As covered elsewhere, an updatable
+      view is based on a single table or updatable view. For updatable views,
+      the optional <code class="literal">CHECK OPTION</code> clause can be specified. If
+      this option is specified, then if a row of the view is updated or a new
+      row is inserted into the view, then it should contain such values that
+      the row would be included in the view after the change. If <code class="literal">WITH
+      CASCADED CHECK OPTION</code> is specified, then if the
+      <code class="literal">&lt;query expression&gt;</code> of the view references
+      another view, then the search condition of the underlying view should
+      also be satisfied by the update or insert operation.</p>
+<p>More on recursive...</p>
+<a name="N11117" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP VIEW</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop view statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop view statement&gt; ::= DROP VIEW [ IF EXISTS
+      ] &lt;table name&gt; [ IF EXISTS ] &lt;drop
+      behavior&gt;</code>
+</p>
+<p>Destroy a view. The <code class="literal">&lt;drop behavior&gt;</code> is
+      similar to dropping a table.</p>
+<a name="N1112B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER VIEW</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter view statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter view statement&gt; ::= ALTER VIEW &lt;table
+      name&gt; &lt;view specification&gt; AS &lt;query expression&gt; [ WITH [
+      CASCADED | LOCAL ] CHECK OPTION ]</code>
+</p>
+<p>Alter a view. The statement is otherwise identical to CREATE
+      VIEW. The new definition replaces the old. If there are database objects
+      such as routines or views that reference the view, then these objects
+      are recompiled with the new view definition. If the new definition is
+      not compatible, the statement fails.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1113C"></a>Domain Creation and Manipulation</h3>
+</div>
+</div>
+</div>
+<a name="N1113F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE DOMAIN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>domain definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;domain definition&gt; ::= CREATE DOMAIN &lt;domain
+      name&gt; [ AS ] &lt;predefined type&gt; [ &lt;default clause&gt; ] [
+      &lt;domain constraint&gt;... ] [ &lt;collate clause&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;domain constraint&gt; ::= [ &lt;constraint name
+      definition&gt; ] &lt;check constraint definition&gt; [ &lt;constraint
+      characteristics&gt; ]</code>
+</p>
+<p>Define a domain. Although a DOMAIN is not strictly a type in
+      the SQL Standard, it can be informally considered as a type. A DOMAIN is
+      based on a <code class="literal">&lt;predefined type&gt;</code>, which is a base
+      type defined by the Standard. It can have a <code class="literal">&lt;default
+      clause&gt;</code>, similar to a column default clause. It can also
+      have one or more CHECK constraints which limit the values that can be
+      assigned to a column or variable that has the DOMAIN as its
+      type.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE DOMAIN valid_string AS VARCHAR(20) DEFAULT 'NO VALUE' CHECK (value IS NOT NULL AND CHARACTER_LENGTH(value) &gt; 2) 
+</pre>
+</div>
+<a name="N1115C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER DOMAIN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter domain statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter domain statement&gt; ::= ALTER DOMAIN
+      &lt;domain name&gt; &lt;alter domain action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter domain action&gt; ::= &lt;set domain default
+      clause&gt; | &lt;drop domain default clause&gt; | &lt;add domain
+      constraint definition&gt; | &lt;drop domain constraint
+      definition&gt;</code>
+</p>
+<p>Change a domain and its definition.</p>
+<a name="N11170" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set domain default clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;set domain default clause&gt; ::= SET &lt;default
+      clause&gt;</code>
+</p>
+<p>Set the default value in a domain.</p>
+<a name="N11181" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop domain default clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop domain default clause&gt; ::= DROP
+      DEFAULT</code>
+</p>
+<p>Remove the default clause of a domain.</p>
+<a name="N11192" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ADD CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>add domain constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;add domain constraint definition&gt; ::= ADD
+      &lt;domain constraint&gt;</code>
+</p>
+<p>Add a constraint to a domain.</p>
+<a name="N111A3" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop domain constraint
+      definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop domain constraint definition&gt; ::= DROP
+      CONSTRAINT &lt;constraint name&gt;</code>
+</p>
+<p>Destroy a constraint on a domain. If the <code class="literal">&lt;drop
+      behavior&gt;</code> is <code class="literal">CASCADE</code>, and the constraint
+      is a UNIQUE constraint which is referenced by a FOREIGN KEY constraint
+      on another table, then the FOREIGN KEY constraint is also
+      dropped.</p>
+<a name="N111BA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP DOMAIN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop domain statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop domain statement&gt; ::= DROP DOMAIN
+      &lt;domain name&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy a domain. If <code class="literal">&lt;drop behavior&gt;</code>
+      is <code class="literal">CASCADE</code>, it works differently from most other
+      objects. If a table features a column of the specified DOMAIN, the
+      column survives and inherits the DEFAULT CLAUSE, and the CHECK
+      CONSTRAINT of the DOMAIN.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N111D1"></a>Trigger Creation</h3>
+</div>
+</div>
+</div>
+<a name="N111D4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TRIGGER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>trigger definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;trigger definition&gt; ::= CREATE TRIGGER
+      &lt;trigger name&gt; &lt;trigger action time&gt; &lt;trigger event&gt;
+      ON &lt;table name&gt; [ REFERENCING &lt;transition table or variable
+      list&gt; ] &lt;triggered action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;trigger action time&gt; ::= BEFORE | AFTER |
+      INSTEAD OF</code>
+</p>
+<p>
+<code class="literal">&lt;trigger event&gt; ::= INSERT | DELETE | UPDATE [
+      OF &lt;trigger column list&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;trigger column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered action&gt; ::= [ FOR EACH { ROW |
+      STATEMENT } ] [ &lt;triggered when clause&gt; ] &lt;triggered SQL
+      statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered when clause&gt; ::= WHEN &lt;left
+      paren&gt; &lt;search condition&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered SQL statement&gt; ::= &lt;SQL procedure
+      statement&gt; | BEGIN ATOMIC { &lt;SQL procedure statement&gt;
+      &lt;semicolon&gt; }... END | [QUEUE &lt;integer literal&gt;] [NOWAIT]
+      CALL &lt;HSQLDB trigger class FQN&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transition table or variable list&gt; ::=
+      &lt;transition table or variable&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;transition table or variable&gt; ::= OLD [ ROW ] [
+      AS ] &lt;old transition variable name&gt; | NEW [ ROW ] [ AS ] &lt;new
+      transition variable name&gt; | OLD TABLE [ AS ] &lt;old transition table
+      name&gt; | NEW TABLE [ AS ] &lt;new transition table
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;old transition table name&gt; ::= &lt;transition
+      table name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;new transition table name&gt; ::= &lt;transition
+      table name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transition table name&gt; ::=
+      &lt;identifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;old transition variable name&gt; ::=
+      &lt;correlation name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;new transition variable name&gt; ::=
+      &lt;correlation name&gt;</code>
+</p>
+<p>Trigger definition is a relatively complex statement. The
+      combination of <code class="literal">&lt;trigger action time&gt;</code> and
+      <code class="literal">&lt;trigger event&gt;</code> determines the type of the
+      trigger. Examples include BEFORE DELETE, AFTER UPDATE, INSTEAD OF
+      INSERT. If the optional <code class="literal">[ OF &lt;trigger column list&gt;
+      ]</code> is specified for an UPDATE trigger, then the trigger is
+      activated only if one of the columns that is in the <code class="literal">&lt;trigger
+      column list&gt;</code> is specified in the UPDATE statement that
+      activates the trigger.</p>
+<p>If a trigger is <code class="literal">FOR EACH ROW</code>, which is the
+      default option, then the trigger is activated for each row of the table
+      that is affected by the execution of an SQL statement. Otherwise, it is
+      activated once only per statement execution. In the first case, there is
+      a before and after state for each row. For UPDATE triggers, both before
+      and after states exist, representing the row before the update, and
+      after the update. For DELETE, triggers, there is only a before state.
+      For INSERT triggers, there is only an after state. If a trigger is
+      <code class="literal">FOR EACH STATEMENT</code>, then a transient table is created
+      containing all the rows for the before state and another transient table
+      is created for the after state.</p>
+<p>The <code class="literal">[ REFERENCING &lt;transition table or variable&gt;
+      ]</code> is used to give a name to the before and after data row or
+      table. This name can be referenced in the <code class="literal">&lt;SQL procedure
+      statement&gt;</code> to access the data.</p>
+<p>The optional <code class="literal">&lt;triggered when clause&gt;</code>
+      is a search condition, similar to the search condition of a DELETE or
+      UPDATE statement. If the search condition is not TRUE for a row, then
+      the trigger is not activated for that row.</p>
+<p>The <code class="literal">&lt;SQL procedure statement&gt;</code> is
+      limited to INSERT, DELETE, UPDATE and MERGE statements.</p>
+<p>The <code class="literal">&lt;HSQLDB trigger class FQN&gt;</code> is a
+      delimited identifier that contains the fully qualified name of a Java
+      class that implements the <code class="classname">org.hsqldb.Trigger</code>
+      interface.</p>
+<p>Early releases of HyperSQL version 2.0 do not allow the use of
+      OLD TABLE or NEW TABLE in statement level trigger definitions.</p>
+<a name="N1123C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP TRIGGER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop trigger statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop trigger statement&gt; ::= DROP TRIGGER
+      &lt;trigger name&gt;</code>
+</p>
+<p>Destroy a trigger.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1124D"></a>Routine Creation</h3>
+</div>
+</div>
+</div>
+<a name="N11250" class="indexterm"></a>
+<p>
+<span class="bold"><strong>schema routine</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL-invoked routine</em></span>
+</p>
+<p>
+<code class="literal">&lt;SQL-invoked routine&gt; ::= &lt;schema
+      routine&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema routine&gt; ::= &lt;schema procedure&gt; |
+      &lt;schema function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema procedure&gt; ::= CREATE &lt;SQL-invoked
+      procedure&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema function&gt; ::= CREATE &lt;SQL-invoked
+      function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL-invoked procedure&gt; ::= PROCEDURE &lt;schema
+      qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+      &lt;routine characteristics&gt; &lt;routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL-invoked function&gt; ::= { &lt;function
+      specification&gt; | &lt;method specification designator&gt; }
+      &lt;routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL parameter declaration list&gt; ::= &lt;left
+      paren&gt; [ &lt;SQL parameter declaration&gt; [ { &lt;comma&gt; &lt;SQL
+      parameter declaration&gt; }... ] ] &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL parameter declaration&gt; ::= [ &lt;parameter
+      mode&gt; ] [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt; [
+      RESULT ]</code>
+</p>
+<p>
+<code class="literal">&lt;parameter mode&gt; ::= IN | OUT |
+      INOUT</code>
+</p>
+<p>
+<code class="literal">&lt;parameter type&gt; ::= &lt;data
+      type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;function specification&gt; ::= FUNCTION &lt;schema
+      qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+      &lt;returns clause&gt; &lt;routine characteristics&gt; [ &lt;dispatch
+      clause&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;method specification designator&gt; ::= SPECIFIC
+      METHOD &lt;specific method name&gt; | [ INSTANCE | STATIC | CONSTRUCTOR
+      ] METHOD &lt;method name&gt; &lt;SQL parameter declaration list&gt; [
+      &lt;returns clause&gt; ] FOR &lt;schema-resolved user-defined type
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;routine characteristics&gt; ::= [ &lt;routine
+      characteristic&gt;... ]</code>
+</p>
+<p>
+<code class="literal">&lt;routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | SPECIFIC &lt;specific
+      name&gt; | &lt;deterministic characteristic&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | &lt;savepoint level
+      indication&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;savepoint level indication&gt; ::= NEW SAVEPOINT
+      LEVEL | OLD SAVEPOINT LEVEL</code>
+</p>
+<p>
+<code class="literal">&lt;returned result sets characteristic&gt; ::=
+      DYNAMIC RESULT SETS &lt;maximum returned result
+      sets&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;parameter style clause&gt; ::= PARAMETER STYLE
+      &lt;parameter style&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;dispatch clause&gt; ::= STATIC
+      DISPATCH</code>
+</p>
+<p>
+<code class="literal">&lt;returns clause&gt; ::= RETURNS &lt;returns
+      type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns type&gt; ::= &lt;returns data type&gt; [
+      &lt;result cast&gt; ] | &lt;returns table type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns table type&gt; ::= TABLE &lt;table
+      function column list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table function column list&gt; ::= &lt;left
+      paren&gt; &lt;table function column list element&gt; [ { &lt;comma&gt;
+      &lt;table function column list element&gt; }... ] &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table function column list element&gt; ::=
+      &lt;column name&gt; &lt;data type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;result cast&gt; ::= CAST FROM &lt;result cast from
+      type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;result cast from type&gt; ::= &lt;data type&gt; [
+      &lt;locator indication&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;returns data type&gt; ::= &lt;data type&gt; [
+      &lt;locator indication&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;routine body&gt; ::= &lt;SQL routine spec&gt; |
+      &lt;external body reference&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL routine spec&gt; ::= [ &lt;rights clause&gt; ]
+      &lt;SQL routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;rights clause&gt; ::= SQL SECURITY INVOKER | SQL
+      SECURITY DEFINER</code>
+</p>
+<p>
+<code class="literal">&lt;SQL routine body&gt; ::= &lt;SQL procedure
+      statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;external body reference&gt; ::= EXTERNAL [ NAME
+      &lt;external routine name&gt; ] [ &lt;parameter style clause&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;parameter style&gt; ::= SQL |
+      GENERAL</code>
+</p>
+<p>
+<code class="literal">&lt;deterministic characteristic&gt; ::= DETERMINISTIC
+      | NOT DETERMINISTIC</code>
+</p>
+<p>
+<code class="literal">&lt;SQL-data access indication&gt; ::= NO SQL |
+      CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA</code>
+</p>
+<p>
+<code class="literal">&lt;null-call clause&gt; ::= RETURNS NULL ON NULL
+      INPUT | CALLED ON NULL INPUT</code>
+</p>
+<p>
+<code class="literal">&lt;maximum returned result sets&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>Define an SQL-invoked routine.</p>
+<a name="N112CA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER routine</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter routine statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter routine statement&gt; ::= ALTER &lt;specific
+      routine designator&gt; &lt;alter routine characteristics&gt; &lt;alter
+      routine behavior&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter routine characteristics&gt; ::= &lt;alter
+      routine characteristic&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;alter routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | NAME &lt;external routine
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter routine behavior&gt; ::=
+      RESTRICT</code>
+</p>
+<p>Alter a characteristic of an SQL-invoked routine. Early
+      releases of HyperSQL 2.0 may not support this statement.</p>
+<a name="N112E4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop routine statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop routine statement&gt; ::= DROP &lt;specific
+      routine designator&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy an SQL-invoked routine.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N112F5"></a>Sequence Creation</h3>
+</div>
+</div>
+</div>
+<a name="N112F8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE SEQUENCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>sequence generator definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;sequence generator definition&gt; ::= CREATE
+      SEQUENCE &lt;sequence generator name&gt; [ &lt;sequence generator
+      options&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator options&gt; ::= &lt;sequence
+      generator option&gt; ...</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator option&gt; ::= &lt;sequence
+      generator data type option&gt; | &lt;common sequence generator
+      options&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;common sequence generator options&gt; ::=
+      &lt;common sequence generator option&gt; ...</code>
+</p>
+<p>
+<code class="literal">&lt;common sequence generator option&gt; ::=
+      &lt;sequence generator start with option&gt; | &lt;basic sequence
+      generator option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;basic sequence generator option&gt; ::=
+      &lt;sequence generator increment by option&gt; | &lt;sequence generator
+      maxvalue option&gt; | &lt;sequence generator minvalue option&gt; |
+      &lt;sequence generator cycle option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator data type option&gt; ::= AS
+      &lt;data type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator start with option&gt; ::= START
+      WITH &lt;sequence generator start value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator start value&gt; ::= &lt;signed
+      numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator increment by option&gt; ::=
+      INCREMENT BY &lt;sequence generator increment&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator increment&gt; ::= &lt;signed
+      numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator maxvalue option&gt; ::=
+      MAXVALUE &lt;sequence generator max value&gt; | NO
+      MAXVALUE</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator max value&gt; ::= &lt;signed
+      numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator minvalue option&gt; ::=
+      MINVALUE &lt;sequence generator min value&gt; | NO
+      MINVALUE</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator min value&gt; ::= &lt;signed
+      numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator cycle option&gt; ::= CYCLE | NO
+      CYCLE</code>
+</p>
+<p>Define a named sequence generator. A SEQUENCE object generates
+      a sequence of integers according to the specified rules. The simple
+      definition without the options defines a sequence of numbers in INTEGER
+      type starting at 1 and incrementing by 1. By default the
+      <code class="literal">CYCLE</code> property is set and the minimum and maximum
+      limits are the minimum and maximum limits of the type of returned
+      values. There are self-explanatory options for changing various
+      properties of the sequence. The <code class="literal">MAXVALUE</code> and
+      <code class="literal">MINVALUE</code> specify the upper and lower limits. If
+      <code class="literal">CYCLE</code> is specified, after the sequence returns the
+      highest or lowest value in range, the next value will respectively be
+      the lowest or highest value in range. If <code class="literal">NO CYCLE</code> is
+      specified, the use of the sequence generator results in an error once
+      the limit has been reached.</p>
+<p>The integer types: SMALLINT, INTEGER, BIGINT, DECIMAL and
+      NUMERIC can be used as the type of the sequence. DECIMAL and NUMERIC
+      types must have a scale of 0 and a precision not exceeding 18.</p>
+<a name="N11347" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER SEQUENCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter sequence generator
+      statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter sequence generator statement&gt; ::= ALTER
+      SEQUENCE &lt;sequence generator name&gt; &lt;alter sequence generator
+      options&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter sequence generator options&gt; ::= &lt;alter
+      sequence generator option&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;alter sequence generator option&gt; ::= &lt;alter
+      sequence generator restart option&gt; | &lt;basic sequence generator
+      option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter sequence generator restart option&gt; ::=
+      RESTART [ WITH &lt;sequence generator restart value&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator restart value&gt; ::=
+      &lt;signed numeric literal&gt;</code>
+</p>
+<p>Change the definition of a named sequence generator. The same
+      options that are used in the definition of the SEQUENCE can be used to
+      alter it. The exception is the option for the start value which is
+      <code class="literal">RESTART WITH</code> for the ALTER SEQUENCE
+      statement..</p>
+<a name="N11367" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP SEQUENCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop sequence generator
+      statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop sequence generator statement&gt; ::= DROP
+      SEQUENCE [ IF EXISTS ] &lt;sequence generator name&gt; [ IF EXISTS ]
+      &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy an external sequence generator. If the
+      <code class="literal">&lt;drop behavior&gt;</code> is <code class="literal">CASCADE</code>,
+      then all objects that reference the sequence are dropped. These objects
+      can be VIEW, ROUTINE or TRIGGER objects.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1137F"></a>SQL Procedure Statement</h3>
+</div>
+</div>
+</div>
+<a name="N11382" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQL procedure
+      statement</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL procedure statement</em></span>
+</p>
+<p>The definition of CREATE TRIGGER and CREATE PROCEDURE
+      statements refers to &lt;SQL procedure statement&gt;. The definition of
+      this element is given below. However, only a subset of these statements
+      are allowed in trigger or routine definition.</p>
+<p>
+<code class="literal">&lt;SQL procedure statement&gt; ::= &lt;SQL executable
+      statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL executable statement&gt; ::= &lt;SQL schema
+      statement&gt; | &lt;SQL data statement&gt; | &lt;SQL control
+      statement&gt; | &lt;SQL transaction statement&gt; | &lt;SQL connection
+      statement&gt; | &lt;SQL session statement&gt; | &lt;SQL diagnostics
+      statement&gt; | &lt;SQL dynamic statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL schema statement&gt; ::= &lt;SQL schema
+      definition statement&gt; | &lt;SQL schema manipulation
+      statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL schema definition statement&gt; ::= &lt;schema
+      definition&gt; | &lt;table definition&gt; | &lt;view definition&gt; |
+      &lt;SQL-invoked routine&gt; | &lt;grant statement&gt; | &lt;role
+      definition&gt; | &lt;domain definition&gt; | &lt;character set
+      definition&gt; | &lt;collation definition&gt; | &lt;transliteration
+      definition&gt; | &lt;assertion definition&gt; | &lt;trigger
+      definition&gt; | &lt;user-defined type definition&gt; | &lt;user-defined
+      cast definition&gt; | &lt;user-defined ordering definition&gt; |
+      &lt;transform definition&gt; | &lt;sequence generator
+      definition&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL schema manipulation statement&gt; ::= &lt;drop
+      schema statement&gt; | &lt;alter table statement&gt; | &lt;drop table
+      statement&gt; | &lt;drop view statement&gt; | &lt;alter routine
+      statement&gt; | &lt;drop routine statement&gt; | &lt;drop user-defined
+      cast statement&gt; | &lt;revoke statement&gt; | &lt;drop role
+      statement&gt; | &lt;alter domain statement&gt; | &lt;drop domain
+      statement&gt; | &lt;drop character set statement&gt; | &lt;drop
+      collation statement&gt; | &lt;drop transliteration statement&gt; |
+      &lt;drop assertion statement&gt; | &lt;drop trigger statement&gt; |
+      &lt;alter type statement&gt; | &lt;drop data type statement&gt; |
+      &lt;alter sequence generator statement&gt; | &lt;drop sequence generator
+      statement&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1139F"></a>Other Schema Object Creation</h3>
+</div>
+</div>
+</div>
+<a name="N113A2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE INDEX</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>create index statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;create index statement&gt; ::= CREATE INDEX
+      &lt;index name&gt; ON &lt;table name&gt; &lt;left paren&gt; {&lt;column
+      name&gt; [ASC | DESC]}, ... &lt;left paren&gt;</code>
+</p>
+<p>Creates an index on a group of columns of a table. The optional
+      [ASC | DESC] specifies if the column is indexed in the ascending or
+      descending order, but has no effect on how the index is created (it is
+      allowed for compatibility with other database engines). HyperSQL can use
+      all indexes in ascending or descending order as needed.</p>
+<a name="N113B3" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP INDEX</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop index statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop index statement&gt; ::= DROP INDEX [ IF
+      EXISTS ] &lt;index name&gt; [ IF EXISTS ]</code>
+</p>
+<p>Destroy an index.</p>
+<a name="N113C4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TYPE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>user-defined type definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;user-defined type definition&gt; ::= CREATE TYPE
+      &lt;user-defined type body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;user-defined type body&gt; ::= &lt;schema-resolved
+      user-defined type name&gt; [ AS &lt;representation&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;representation&gt; ::= &lt;predefined
+      type&gt;</code>
+</p>
+<p>Define a user-defined type. Currently only simple distinct
+      types can be defined without further attributes.</p>
+<a name="N113DB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE CAST</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>user-defined cast definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;user-defined cast definition&gt; ::= CREATE CAST
+      &lt;left paren&gt; &lt;source data type&gt; AS &lt;target data type&gt;
+      &lt;right paren&gt; WITH &lt;cast function&gt; [ AS ASSIGNMENT
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;cast function&gt; ::= &lt;specific routine
+      designator&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;source data type&gt; ::= &lt;data
+      type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;target data type&gt; ::= &lt;data
+      type&gt;</code>
+</p>
+<p>Define a user-defined cast. This feature may be supported in a
+      future versions of HyperSQL.</p>
+<a name="N113F5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP CAST</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop user-defined cast statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop user-defined cast statement&gt; ::= DROP CAST
+      &lt;left paren&gt; &lt;source data type&gt; AS &lt;target data type&gt;
+      &lt;right paren&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy a user-defined cast. This feature may be supported in a
+      future versions of HyperSQL.</p>
+<a name="N11406" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE CHARACTER SET</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>character set definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;character set definition&gt; ::= CREATE CHARACTER
+      SET &lt;character set name&gt; [ AS ] &lt;character set source&gt; [
+      &lt;collate clause&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;character set source&gt; ::= GET &lt;character set
+      specification&gt;</code>
+</p>
+<p>Define a character set. A new CHARACTER SET is based on an
+      existing CHARACTER SET. The optional <code class="literal">&lt;collate
+      clause&gt;</code> specifies the collation to be used, otherwise the
+      collation is inherited from the default collation for the source
+      CHARACTER SET.</p>
+<a name="N1141D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP CHARACTER SET</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop character set statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop character set statement&gt; ::= DROP
+      CHARACTER SET &lt;character set name&gt;</code>
+</p>
+<p>Destroy a character set. If the character set name is
+      referenced in any database object, the command fails. Note that
+      <code class="literal">CASCADE</code> or <code class="literal">RESTRICT</code> cannot be
+      specified for this command.</p>
+<a name="N11434" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE COLLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>collation definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;collation definition&gt; ::= CREATE COLLATION
+      &lt;collation name&gt; FOR &lt;character set specification&gt; FROM
+      &lt;existing collation name&gt; [ &lt;pad characteristic&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;existing collation name&gt; ::= &lt;collation
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;pad characteristic&gt; ::= NO PAD | PAD
+      SPACE</code>
+</p>
+<p>Define a collation. A new collation is based on an existing
+      COLLATION and applies to an existing CHARACTER SET. The <code class="literal">&lt;pad
+      characteristic&gt;</code> specifies whether strings are padded with
+      spaces for comparison. This feature may be supported in a future
+      versions of HyperSQL.</p>
+<a name="N1144E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP COLLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop collation statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop collation statement&gt; ::= DROP COLLATION
+      &lt;collation name&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy a collation. If the <code class="literal">&lt;drop
+      behavior&gt;</code> is <code class="literal">CASCADE</code>, then all
+      references to the collation revert to the default collation that would
+      be in force if the dropped collation was not specified. This feature may
+      be supported in a future versions of HyperSQL.</p>
+<a name="N11465" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TRANSLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>transliteration definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;transliteration definition&gt; ::= CREATE
+      TRANSLATION &lt;transliteration name&gt; FOR &lt;source character set
+      specification&gt; TO &lt;target character set specification&gt; FROM
+      &lt;transliteration source&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;source character set specification&gt; ::=
+      &lt;character set specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;target character set specification&gt; ::=
+      &lt;character set specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transliteration source&gt; ::= &lt;existing
+      transliteration name&gt; | &lt;transliteration
+      routine&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;existing transliteration name&gt; ::=
+      &lt;transliteration name&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;transliteration routine&gt; ::= &lt;specific
+      routine designator&gt;</code>
+</p>
+<p>Define a character transliteration. This feature may be
+      supported in a future versions of HyperSQL.</p>
+<a name="N11485" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP TRANSLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop transliteration statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop transliteration statement&gt; ::= DROP
+      TRANSLATION &lt;transliteration name&gt;</code>
+</p>
+<p>Destroy a character transliteration. This feature may be
+      supported in a future versions of HyperSQL.</p>
+<a name="N11496" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE ASSERTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>assertion definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;assertion definition&gt; ::= CREATE ASSERTION
+      &lt;constraint name&gt; CHECK &lt;left paren&gt; &lt;search
+      condition&gt; &lt;right paren&gt; [ &lt;constraint characteristics&gt;
+      ]</code>
+</p>
+<p>Specify an integrity constraint. This feature may be supported
+      in a future versions of HyperSQL.</p>
+<a name="N114A7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP ASSERTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop assertion statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop assertion statement&gt; ::= DROP ASSERTION
+      &lt;constraint name&gt; [ &lt;drop behavior&gt; ]</code>
+</p>
+<p>Destroy an assertion. This feature may be supported in a future
+      versions of HyperSQL.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N114B8"></a>The Information Schema</h2>
+</div>
+</div>
+</div>
+<p>The Information Schema is a special schema in each catalog. The SQL
+    Standard defines a number of character sets and domains in this schema. In
+    addition, all the implementation-defined collations belong to the
+    Information Schema.</p>
+<p>The SQL Standard defines many views in the Information Schema. These
+    views show the properties of the database objects that currently exist in
+    the database. When a user accesses one these views, only the properties of
+    database objects that the user can access are included.</p>
+<p>HyperSQL supports all the views defined by the Standard, apart from
+    a few views that report on extended user-defined types and other optional
+    features of the Standard that are not supported by HyperSQL.</p>
+<p>HyperSQL also adds some views to the Information Schema. These views
+    are for features that are not reported in any of the views defined by the
+    Standard, or for use by JDBC DatabaseMetaData.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N114C3"></a>Predefined Character Sets, Collations and Domains</h3>
+</div>
+</div>
+</div>
+<p>The SQL Standard defines a number of character sets and domains in
+      the INFORMATION SCHEMA.</p>
+<p>These domains are used in the INFORMATION SCHEMA views:</p>
+<p>CARDINAL_NUMBER, YES_OR_NO, CHARACTER_DATA, SQL_IDENTIFIER,
+      TIME_STAMP</p>
+<p>All available collations are in the INFORMATION
+      SCHEMA.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N114CE"></a>Views in INFORMATION SCHEMA</h3>
+</div>
+</div>
+</div>
+<p>The following views are defined by the SQL Standard:</p>
+<p>ADMINISTRABLE_ROLE_AUTHORIZATIONS</p>
+<p>APPLICABLE_ROLES</p>
+<p>ASSERTIONS</p>
+<p>AUTHORIZATIONS</p>
+<p>CHARACTER_SETS</p>
+<p>CHECK_CONSTRAINTS</p>
+<p>CHECK_CONSTRAINT_ROUTINE_USAGE</p>
+<p>COLLATIONS</p>
+<p>COLUMNS</p>
+<p>COLUMN_COLUMN_USAGE</p>
+<p>COLUMN_DOMAIN_USAGE</p>
+<p>COLUMN_PRIVILEGES</p>
+<p>COLUMN_UDT_USAGE</p>
+<p>CONSTRAINT_COLUMN_USAGE</p>
+<p>CONSTRAINT_TABLE_USAGE</p>
+<p>DATA_TYPE_PRIVILEGES</p>
+<p>DOMAINS</p>
+<p>DOMAIN_CONSTRAINTS</p>
+<p>ENABLED_ROLES</p>
+<p>INFORMATION_SCHEMA_CATALOG_NAME</p>
+<p>KEY_COLUMN_USAGE</p>
+<p>PARAMETERS</p>
+<p>REFERENTIAL_CONSTRAINTS</p>
+<p>ROLE_AUTHORIZATION_DESCRIPTORS</p>
+<p>ROLE_COLUMN_GRANTS</p>
+<p>ROLE_ROUTINE_GRANTS</p>
+<p>ROLE_TABLE_GRANTS</p>
+<p>ROLE_UDT_GRANTS</p>
+<p>ROLE_USAGE_GRANTS</p>
+<p>ROUTINE_COLUMN_USAGE</p>
+<p>ROUTINE_JAR_USAGE</p>
+<p>ROUTINE_PRIVILEGES</p>
+<p>ROUTINE_ROUTINE_USAGE</p>
+<p>ROUTINE_SEQUENCE_USAGE</p>
+<p>ROUTINE_TABLE_USAGE</p>
+<p>ROUTINES</p>
+<p>SCHEMATA</p>
+<p>SEQUENCES</p>
+<p>SQL_FEATURES</p>
+<p>SQL_IMPLEMENTATION_INFO</p>
+<p>SQL_PACKAGES</p>
+<p>SQL_PARTS</p>
+<p>SQL_SIZING</p>
+<p>SQL_SIZING_PROFILES</p>
+<p>TABLES</p>
+<p>TABLE_CONSTRAINTS</p>
+<p>TABLE_PRIVILEGES</p>
+<p>TRANSLATIONS</p>
+<p>TRIGGERED_UPDATE_COLUMNS</p>
+<p>TRIGGERS</p>
+<p>TRIGGER_COLUMN_USAGE</p>
+<p>TRIGGER_ROUTINE_USAGE</p>
+<p>TRIGGER_SEQUENCE_USAGE</p>
+<p>TRIGGER_TABLE_USAGE</p>
+<p>USAGE_PRIVILEGES</p>
+<p>USER_DEFINED_TYPES</p>
+<p>VIEWS</p>
+<p>VIEW_COLUMN_USAGE</p>
+<p>VIEW_ROUTINE_USAGE</p>
+<p>VIEW_TABLE_USAGE</p>
+<p>The following views are specific to HyperSQL:</p>
+<p>SYSTEM_BESTROWIDENTIFIER</p>
+<p>SYSTEM_CACHEINFO</p>
+<p>SYSTEM_COLUMNS</p>
+<p>SYSTEM_COMMENTS</p>
+<p>SYSTEM_CROSSREFERENCE</p>
+<p>SYSTEM_INDEXINFO</p>
+<p>SYSTEM_PRIMARYKEYS</p>
+<p>SYSTEM_PROCEDURECOLUMNS</p>
+<p>SYSTEM_PROCEDURES</p>
+<p>SYSTEM_PROPERTIES</p>
+<p>SYSTEM_SCHEMAS</p>
+<p>SYSTEM_SEQUENCES</p>
+<p>SYSTEM_SESSIONINFO</p>
+<p>SYSTEM_SESSIONS</p>
+<p>SYSTEM_TABLES</p>
+<p>SYSTEM_TABLETYPES</p>
+<p>SYSTEM_TEXTTABLES</p>
+<p>SYSTEM_TYPEINFO</p>
+<p>SYSTEM_UDTS</p>
+<p>SYSTEM_USERS</p>
+<p>SYSTEM_VERSIONCOLUMNS</p>
+</div>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="sessions-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="texttables-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;3.&nbsp;Sessions and Transactions&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;5.&nbsp;Text Tables</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/dbproperties-chapt.html b/doc/guide/dbproperties-chapt.html
new file mode 100644
index 0000000..0fb3b44
--- /dev/null
+++ b/doc/guide/dbproperties-chapt.html
@@ -0,0 +1,976 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;12.&nbsp;Properties</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="deployment-chapt.html" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">
+<link rel="next" href="listeners-chapt.html" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="deployment-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;12.&nbsp;Properties</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="listeners-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;11.&nbsp;System Management and Deployment
+  Issues&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="dbproperties-chapt"></a>Chapter&nbsp;12.&nbsp;Properties</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3626 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N13AB9"></a>
+<p>Copyright 2002-2009 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-05 07:49:07 -0400 (Sat, 05 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="dbproperties-chapt.html#dbproperties_connections-sect">Connections</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dbproperties-chapt.html#conn_props-sect">Connection properties</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="dbproperties-chapt.html#N13C11">Database Properties in Connection URL and Properties</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbproperties_connections-sect"></a>Connections</h2>
+</div>
+</div>
+</div>
+<p>The normal method of accessing a HyperSQL catalog is via the JDBC
+    Connection interface. An introduction to different methods of providing
+    database services and accessing them can be found in the <a class="link" href="sqlgeneral-chapt.html" title="Chapter&nbsp;2.&nbsp;SQL Language">SQL Language</a> chapter.
+    Details and examples of how to connect via JDBC are provided in our
+    JavaDoc for <code class="classname"><a class="classname" href="apd.html#JDBCConnection.html-link">
+    JDBCConnection</a></code>.</p>
+<p>A uniform method is used to distinguish between different types of
+    connection. The common driver identifier is
+    <code class="literal">jdbc:hsqldb:</code> followed by a protocol identifier
+    (<code class="literal">mem: file: res: hsql: http: hsqls: https:</code>) then
+    followed by host and port identifiers in the case of servers, then
+    followed by database identifier. Additional property / value pairs can be
+    appended to the end of the URL, separated with semicolons.</p>
+<div class="table">
+<a name="N13AD2"></a>
+<p class="title">
+<b>Table&nbsp;12.1.&nbsp;HyperSQL URL Components</b>
+</p>
+<div class="table-contents">
+<table summary="HyperSQL URL Components" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Driver and Protocol</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Host and Port</th><th style="border-bottom: 0.5pt solid ; " align="left">Database</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">jdbc:hsqldb:mem:</code></td>
+</tr>
+</table>
+</td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">not available</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">accounts</code></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Lowercase, single-word
+            identifier creates the in-memory database when the first
+            connection is made. Subsequent use of the same Connection URL
+            connects to the existing DB.</p> 
+<p>The old form for the
+            URL, <code class="literal">jdbc:hsqldb:.</code> creates or connects to the
+            same database as the new form for the URL,
+            <code class="literal">jdbc:hsqldb:mem:.</code>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">jdbc:hsqldb:file:</code></td>
+</tr>
+</table>
+</td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">not available</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="filename">mydb</code></td>
+</tr>
+<tr>
+<td><code class="filename">/opt/db/accounts</code></td>
+</tr>
+<tr>
+<td><code class="filename">C:/data/mydb</code></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The file path specifies the
+            database file. In the above examples the first one refers to a set
+            of mydb.* files in the directory where the
+            <code class="literal">java</code>command for running the application was
+            issued. The second and third examples refer to absolute paths on
+            the host machine.</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">jdbc:hsqldb:res:</code></td>
+</tr>
+</table>
+</td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">not available</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="filename">/adirectory/dbname</code></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">Database files can be loaded from
+            one of the jars specified as part of the <code class="literal">Java</code>
+            command the same way as resource files are accessed in Java
+            programs. The <code class="literal">/adirectory</code> above stands for a
+            directory in one of the jars.</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">jdbc:hsqldb:hsql:</code></td>
+</tr>
+<tr>
+<td><code class="literal">jdbc:hsqldb:hsqls:</code></td>
+</tr>
+<tr>
+<td><code class="literal">jdbc:hsqldb:http:</code></td>
+</tr>
+<tr>
+<td><code class="literal">jdbc:hsqldb:https:</code></td>
+</tr>
+</table>
+</td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">//localhost</code></td>
+</tr>
+<tr>
+<td><code class="literal">//192.0.0.10:9500</code></td>
+</tr>
+<tr>
+<td><code class="literal">//dbserver.somedomain.com</code></td>
+</tr>
+</table>
+</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">/an_alias</code></td>
+</tr>
+<tr>
+<td><code class="literal">/enrollments</code></td>
+</tr>
+<tr>
+<td><code class="literal">/quickdb</code></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td style="" colspan="3" align="left" valign="top">
+<p>The host and port specify
+            the IP address or host name of the server and an optional port
+            number. The database to connect to is specified by an alias. This
+            alias is a lowercase string defined in the
+            <code class="filename">server.properties</code> file to refer to an actual
+            database on the file system of the server or a transient,
+            in-memory database on the server. The following example lines in
+            <code class="filename">server.properties</code> or
+            <code class="filename">webserver.properties</code> define the database
+            aliases listed above and accessible to clients to refer to
+            different file and in-memory databases.</p> 
+<p>The old form
+            for the server URL, e.g.,
+            <code class="literal">jdbc:hsqldb:hsql//localhost</code> connects to the
+            same database as the new form for the URL,
+            <code class="literal">jdbc:hsqldb:hsql//localhost/</code> where the alias is
+            a zero length string.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="conn_props-sect"></a>Connection properties</h3>
+</div>
+</div>
+</div>
+<p>Each JDBC Connection to a database can specify connection
+      properties. The properties <span class="property">user</span> and
+      <span class="property">password</span> are always required. In 2.0 the following
+      optional properties can also be used.</p>
+<p>Connection properties are specified either by establishing the
+      connection via the method call below, or the property can be appended to
+      the full Connection URL.</p>
+<pre class="programlisting">    DriverManager.getConnection (String url, Properties info);</pre>
+<div class="table">
+<a name="N13B9C"></a>
+<p class="title">
+<b>Table&nbsp;12.2.&nbsp;Connection Properties</b>
+</p>
+<div class="table-contents">
+<table summary="Connection Properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">get_column_name</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">column name in ResultSet</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property is used for
+              compatibility with other JDBC driver implementations. When true
+              (the default), <code class="methodname">ResultSet.getColumnName(int
+              c)</code> returns the underlying column name. This
+              property can be specified differently for different connections
+              to the same database.</p>
+<p>The default is true. When the
+              property is false, the above method returns the same value as
+              <code class="methodname">ResultSet.getColumnLabel(int column)</code>
+              Example below:</p>
+<pre class="programlisting">    jdbc:hsqldb:hsql://localhost/enrollments;get_column_name=false</pre>
+<p>When
+              a ResultSet is used inside a user-defined stored procedure, the
+              default, true, is always used for this property.</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">ifexists</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">connect only if database already exists</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Has an effect only with
+              <em class="glossterm">mem:</em> and <em class="glossterm">file:</em>
+              database. When true, will not create a new database if one does
+              not already exist for the URL.</p>
+<p>When the property is
+              false (the default), a new <em class="glossterm">mem:</em> or
+              <em class="glossterm">file:</em> database will be created if it does
+              not exist.</p> 
+<p>Setting the property to true is useful
+              when troubleshooting as no database is created if the URL is
+              malformed. Example below:</p> 
+<pre class="programlisting">    jdbc:hsqldb:file:enrollments;ifexists=true</pre>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">shutdown</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">shut down the database when the last connection is
+              closed</td>
+</tr>
+<tr>
+<td style="" colspan="3" align="left" valign="top">
+<p>If this property is
+              <code class="literal">true</code>, when the last connection to a database
+              is closed, the database is automatically shut down. The property
+              takes effect only when the first connection is made to the
+              database. This means the connection that opens the database. It
+              has no effect if used with subsequent connections.</p>
+              
+<p>This command has two uses. One is for test suites, where
+              connections to the database are made from one JVM context,
+              immediately followed by another context. The other use is for
+              applications where it is not easy to configure the environment
+              to shutdown the database. Examples reported by users include web
+              application servers, where the closing of the last connection
+              coincides with the web app being shut
+              down.</p>
+<pre class="programlisting">    jdbc:hsqldb:file:enrollments;shutdown=true</pre>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>In addition, when a connection to an
+      <em class="glossterm">in-process</em> database creates a new database, or
+      opens an existing database (i.e. it is the first connection made to the
+      database by the application), all the user-defined database properties
+      can be specified as URL properties. This can be used to specify
+      properties to enforce more strict SQL adherence, or to change
+      cache_scale or similar properties before the database files are created.
+      However, for new databases, it is recommended to use the SET PROPERTY
+      command for such settings.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N13C11"></a>Database Properties in Connection URL and Properties</h2>
+</div>
+</div>
+</div>
+<p>The database engine has several properties that are listed in the
+    <a class="link" href="deployment-chapt.html" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">System Management and Deployment
+  Issues</a>
+    chapter. These properties can be changed via SQL commands after a
+    connection is made to the database. It is possible to specify all of these
+    properties in the connection properties on as part of the URL string when
+    the first connection is made to a new file: or mem: database. This allows
+    the properties to be set without using any SQL commands. The corresponding
+    SQL command is given for each property.</p>
+<p>Management of properties has changed since version 1.8. The old SET
+    PROPERTY does not change a property and is retained to simplify
+    application upgrades.</p>
+<p>In the example URL below, two properties are set for the first
+    connection to a new database. If the properties are used for connection to
+    an existing database, they are ignored.</p>
+<pre class="programlisting">    jdbc:hsqldb:file:enrollments;hsqldb.cache_rows=10000;hsqldb.nio_data_file=false</pre>
+<p>In the table below, database properties that can be used as part of
+    the URL below are given. For each property that can also be set with an
+    SQL statement, the statement is also given. These statements are described
+    in the <a class="link" href="deployment-chapt.html" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">System Management and Deployment
+  Issues</a> chapter.</p>
+<div class="table">
+<a name="N13C26"></a>
+<p class="title">
+<b>Table&nbsp;12.3.&nbsp;Database-specific Property File Properties</b>
+</p>
+<div class="table-contents">
+<table summary="Database-specific Property File Properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Value</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Default</th><th style="border-bottom: 0.5pt solid ; " align="left">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">check_props</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">checks the validity of the connection properties</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is true,
+            every database property that is specified on the URL or in
+            connection properties is checked and if it is not used correctly,
+            an error is returned</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">crypt_lobs</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">encryption of lobs</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is true, the
+            contents of the .lobs file is encrypted as
+            well.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">crypt_key</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">none</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">encryption</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The cipher key for an
+            encrypted database</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">crypt_provider</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">none</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">encryption</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The fully-qualified class
+            name of the cryptography provider. This property is not used for
+            the default security provider.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">crypt_type</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">none</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">encryption</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The cipher
+            specification.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">read_only</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">readonly database</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property is a special
+            property that can be added manually to the .properties file, or
+            included in the URL or connection properties. When this property
+            is true, the database becomes
+            readonly.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">files_read_only</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">readonly files database</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property is used
+            similarly to the hsqldb.read_only property. When this property is
+            true, CACHED and TEXT tables are readonly but memory files are
+            not. Any change to the data is not persisted to database
+            files.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.log_data</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">recovery log</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property can be set to
+            false when database recovery in the event of an unexpected crash
+            is not necessary. A database that is used as a temporary cache is
+            an example. Regardless of the value of this property, if there is
+            a proper shutdown of the database, all the change data is
+            stored.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">sql.enforce_names</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">enforcing SQL keywords</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property, when set
+            true, prevents SQL keywords being used for database object names
+            such as columns and tables.</p>
+<p>
+<pre class="programlisting">SET DATABASE SQL NAMES { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">sql.enforce_size</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">trimming and padding string columns.</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property is the same as
+            sql.enforce_strict_size</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">sql.enforce_strict_size</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">size enforcement and padding string columns</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Conforms to SQL standards
+            for size and precision of data types. When true, all CHARACTER,
+            VARCHAR, NUMERIC and DECIMAL values that are in a row affected by
+            an INSERT INTO or UPDATE statement are checked against the size
+            specified in the SQL table definition. An exception is thrown if
+            the value is too long. Also all CHARACTER values that are shorter
+            than the specified size are padded with
+            spaces.</p>
+<p>
+<pre class="programlisting">SET DATABASE SQL SIZE { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">sql.enforce_refs</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">enforcing column reference disambiguation</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property, when set
+            true, causes an error when an SQL statements contains column
+            references that can be resovled by more than one table name or
+            alias. In effect forces such column references to have a table
+            name or table alias qualifier.</p>
+<p>
+<pre class="programlisting">SET DATABASE SQL REFERENCES { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">runtime.gc_interval</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">0</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">forced garbage collection</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This setting forces garbage
+            collection each time a set number of result set row or cache row
+            objects are created. The default, "0" means no garbage collection
+            is forced by the program.</p>
+<p>
+<pre class="programlisting">SET DATABASE GC &lt;numeric value&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.default_table_type</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">memory</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">type of table created with unqualified CREATE TABLE</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The CREATE TABLE command
+            results in a MEMORY table by default. Setting the value
+            <span class="emphasis"><em>cached</em></span> for this property will result in a
+            cached table by default. The qualified forms such as CREATE MEMORY
+            TABLE or CREATE CACHED TABLE are not affected at all by this
+            property.</p>
+<p>
+<pre class="programlisting">SET DATABASE DEFAULT TABLE TYPE { CACHED | MEMORY }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.applog</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">0</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">application logging level</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The default level 0
+            indicates no logging. Level 1 results in events related to
+            persistence to be logged, including any failures. Level 2
+            indicates all events, including ordinary events. The events are
+            logged in a file ending with
+            ".app.log".</p>
+<p>
+<pre class="programlisting">SET DATABASE EVENT LOG LEVEL { 0 | 1 | 2 }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.result_max_memory_rows</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">0</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">amount of result rows that are kept in memory</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Sets the maximum number of
+            rows of each result set and other internal temporary table that is
+            held in memory. </p>
+<p>
+<pre class="programlisting">SET DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned integer literal&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.tx</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">locks</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">database transaction control mode</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Indicates the transaction
+            control mode for the database. The values, locks, mvlocks and mvcc
+            are allowed.</p>
+<p>
+<pre class="programlisting">SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.cache_rows</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">50000</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">maximum number of rows in memory cache</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Indicates the maximum number
+            of rows of cached tables that are held in memory.</p>
+<p>The
+            value can range between 100-1,000,000. If the value is set via SET
+            FILES then it becomes effective after the next database SHUTDOWN
+            or CHECKPOINT.</p>
+<p>The property is changed via the
+            <code class="literal">SET FILES CACHE ROWS nnn</code> SQL
+            command.</p>
+<p>
+<pre class="programlisting">SET FILES CACHE ROWS &lt;numeric value&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.cache_size</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">10000</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">memory cache size</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Indicates the total size (in
+            kilobytes) of rows in the memory cache used with cached tables.
+            This size is calculated as the binary size of the rows, for
+            example an INTEGER is 4 bytes. The actual memory size used by the
+            objects is 2 to 4 times this value. This depends on the types of
+            objects in database rows, for example with binary objects the
+            factor is less than 2, with character strings, the factor is just
+            over 2 and with date and timestamp objects the factor is over
+            3.</p>
+<p>The value can range between 100-1,000,000. The
+            default is 10,000, representing 10,000 kilobytes. If the value is
+            set via SET FILES then it becomes effective after the next
+            database SHUTDOWN or CHECKPOINT.</p>
+<p>
+<pre class="programlisting">SET FILES CACHE SIZE &lt;numeric value&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.inc_backup</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">incremental backup of data file</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>During updates, the contents
+            of the .data file are modified. When this property is true, the
+            modified contents are backed up gradually. This causes a marginal
+            slowdown in operations, but allows fast checkpoint and
+            shutdown.</p>
+<p>When the property is false, the .data file
+            is backed up entirely at the time of checkpoint and shutdown. Up
+            to version 1.8, HSQLDB supported only full
+            backup.</p>
+<p>
+<pre class="programlisting">SET FILES INCREMENT BACKUP { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.lock_file</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">use of lock file</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>By default, a lock file is
+            created for each file database that is opened for read and write.
+            This property can be specified with the value false to prevent the
+            lock file from being created. This usage is not recommended but
+            may be desirable when flash type storage is
+            used.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.log_data</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">logging data change</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>When
+            <code class="literal">false</code> is specified, no data logging takes
+            place. A checkpoint or shutdown still rewrites the
+            <code class="literal">.script</code> file and saves the
+            <code class="literal">.backup</code> file according to the other
+            settings.</p>
+<p>
+<pre class="programlisting">SET FILES LOG  { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.log_size</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">50</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">size of log when checkpoint is performed</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The value is the size (in
+            megabytes) that the <code class="literal">.log</code> file can reach before
+            an automatic checkpoint occurs. A checkpoint rewrites the
+            <code class="literal">.script</code> file and clears the
+            <code class="literal">.log</code> file.</p>
+<p>
+<pre class="programlisting">SET FILES LOG SIZE &lt;numeric value&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.nio_data_file</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">use of nio access methods for the .data file</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>When HyperSQL is compiled
+            and run in Java 1.4 or higher, setting this property to
+            <code class="literal">false</code> will avoid the use of nio access methods,
+            resulting in somewhat reduced speed. If the data file is larger
+            than 256MB when it is first opened, nio access methods are not
+            used. Also, if the file gets larger than the amount of available
+            computer memory that needs to be allocated for nio access, non-nio
+            access methods are used.</p>
+<p>If used before defining any
+            CACHED table, it applies immediately, otherwise it comes into
+            effect after a SHUTDOWN and restart or
+            CHECKPOINT.</p>
+<p>
+<pre class="programlisting">SET FILES NIO { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.translate_dti_types</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">usage of type codes for advanced type datetime
+            types</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is true, the
+            datetime WITH TIME ZONE types and INTERVAL types are represented
+            as JDBC datetime types without time zone and the VARCHAR type
+            respectively.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.write_delay</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">write delay for writing log file entries</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is true, the
+            default WRITE DELAY property of the database is used, which is
+            1000 milliseconds. If the property is false, the WRITE DELAY is
+            set to 0 seconds. The SQL command for this property allows more
+            precise control over the property.</p>
+<p>
+<pre class="programlisting">SET FILES WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds value&gt; MILLIS</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.write_delay_millis</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">1000</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">write delay for writing log file entries</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is used, the
+            WRITE DELAY property of the database is set the given value. The
+            SQL command for this property allows the same level of control
+            over the property.</p>
+<p>
+<pre class="programlisting">SET FILES WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds value&gt; MILLIS</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">textdb.*</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">0</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">default properties for new text tables</td>
+</tr>
+<tr>
+<td style="" colspan="3" align="left" valign="top">
+<p>Properties that override the
+            database engine defaults for newly created text tables. Settings
+            in the text table <code class="literal">SET &lt;tablename&gt; SOURCE &lt;source
+            string&gt; </code>command override both the engine defaults and
+            the database properties defaults. Individual
+            <span class="property">textdb.*</span> properties are listed in the <a class="link" href="texttables-chapt.html" title="Chapter&nbsp;5.&nbsp;Text Tables">Text Tables</a>
+            chapter.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>When connecting to an <em class="glossterm">in-process</em> database
+    creates a new database, or opens an existing database (i.e. it is the
+    first connection made to the database by the application), all the
+    user-defined database properties listed in this section can be specified
+    as URL properties.</p>
+<p>When HSQLDB is used in OpenOffice.org, some property values will
+    have a different default. The properties and values are:</p>
+<p>hsqldb.default_table_type=cached hsqldb.cache_rows=25000;
+    hsqldb.cache_size=6000; hsqldb.log_size=10; hsqldb.nio_data_file=false;
+    sql.enforce_strict_size=true</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="deployment-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="listeners-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;11.&nbsp;System Management and Deployment
+  Issues&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/deployment-chapt.html b/doc/guide/deployment-chapt.html
new file mode 100644
index 0000000..2b6ea35
--- /dev/null
+++ b/doc/guide/deployment-chapt.html
@@ -0,0 +1,2081 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;11.&nbsp;System Management and Deployment Issues</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="builtinfunctions-chapt.html" title="Chapter&nbsp;10.&nbsp;Built In Functions">
+<link rel="next" href="dbproperties-chapt.html" title="Chapter&nbsp;12.&nbsp;Properties">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="builtinfunctions-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;11.&nbsp;System Management and Deployment
+  Issues</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="dbproperties-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;10.&nbsp;Built In Functions&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;12.&nbsp;Properties</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="deployment-chapt"></a>Chapter&nbsp;11.&nbsp;System Management and Deployment
+  Issues</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3630 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N134FD"></a>
+<p>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-06 10:44:27 -0400 (Sun, 06 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deploymen_modes-sect">Mode of Operation and Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13506">Mode of Operation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13525">Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1353A">Large Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1354D">Deployment context</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13559">Readonly Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deployment_mem_disk-sect">Memory and Disk Use</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13571">Table Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1357F">Result Set Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13594">Temporary Memory Use During Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135A0">Data Cache Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135BF">Object Pool Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135C7">Lob Memory Usage</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135CC">Disk Space</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deployment_conns-sect">Managing Database Connections</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135F4">Tweaking the Mode of Operation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135F9">Application Development and Testing</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1362A">Embedded Databases in Desktop Applications</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13632">Embedded Databases in Server Applications</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13639">Embedding a Database Listener</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1365D">Using HyperSQL Without Logging</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1366B">Server Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deployment_upgrade-sect">Upgrading Databases</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#upgrade_via_script-sect">Upgrading From Older
+      Versions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N136B7">Manual Changes to the *.script File</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N136FB">Backward Compatibility Issues</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deployment_backup-sect">Backing Up Database Catalogs</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13742">Making Online Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13751">Making Offline Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1376E">Examining Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13784">Restoring a Backup</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1379B">Encrypted Databases</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137A2">Creating and Accessing an Encrypted Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137B2">Speed Considerations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137B7">Security Considerations</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137C8">Monitoring Database Operations</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137CD">Statement Level Monitoring</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137D6">Internal Event Monitoring</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137E4">Server Operation Monitoring</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137E9">Statements</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deploymen_modes-sect"></a>Mode of Operation and Tables</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL has many modes of operation and features that allow it to
+    be used in very different scenarios. Levels of memory usage, speed and
+    accessibility by different applications are influenced by how HyperSQL is
+    deployed.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13506"></a>Mode of Operation</h3>
+</div>
+</div>
+</div>
+<p>The decision to run HyperSQL as a separate server process or as an
+      <em class="glossterm">in-process</em> database should be based on the
+      following:</p>
+<p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>When HyperSQL is run as a server on a separate machine, it
+            is isolated from hardware failures and crashes on the hosts
+            running the application.</p>
+</li>
+<li>
+<p>When HyperSQL is run as a server on the same machine, it is
+            isolated from application crashes and memory leaks.</p>
+</li>
+<li>
+<p>Server connections are slower than
+            <em class="glossterm">in-process</em> connections due to the overhead
+            of streaming the data for each JDBC call.</p>
+</li>
+<li>
+<p>You can reduce client/server traffic using SQL Stored
+            procedures to reduce the number of JDBC execute calls.</p>
+</li>
+<li>
+<p>During development, it is better to use a Server with
+            server.silent=false, which displays the statements sent to the
+            server on the console window.</p>
+</li>
+<li>
+<p>To improve speed of execution for statements that are
+            executed repeatedly, reuse a parameterized PreparedStatement for
+            the lifetime of the connections.</p>
+</li>
+</ul>
+</div>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13525"></a>Tables</h3>
+</div>
+</div>
+</div>
+<p>TEXT tables are designed for special applications where the data
+      has to be in an interchangeable format, such as CSV (comma separated
+      values). TEXT tables should not be used for routine storage of
+      data.</p>
+<p>MEMORY tables and CACHED tables are generally used for data
+      storage. The difference between the two is as follows:</p>
+<p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>The data for all MEMORY tables is read from the *.script
+            file when the database is started and stored in memory. In
+            contrast the data for cached tables is not read into memory until
+            the table is accessed. Furthermore, only part of the data for each
+            CACHED table is held in memory, allowing tables with more data
+            than can be held in memory.</p>
+</li>
+<li>
+<p>When the database is shutdown in the normal way, all the
+            data for MEMORY tables is written out to the disk. In comparison,
+            the data in CACHED tables that has changed is written out during
+            operation and at shutdown.</p>
+</li>
+<li>
+<p>The size and capacity of the data cache for all the CACHED
+            tables is configurable. This makes it possible to allow all the
+            data in CACHED tables to be cached in memory. In this case, speed
+            of access is good, but slightly slower than MEMORY tables.</p>
+</li>
+<li>
+<p>For normal applications it is recommended that MEMORY tables
+            are used for small amounts of data, leaving CACHED tables for
+            large data sets. For special applications in which speed is
+            paramount and a large amount of free memory is available, MEMORY
+            tables can be used for large tables as well.</p>
+</li>
+</ul>
+</div>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1353A"></a>Large Objects</h3>
+</div>
+</div>
+</div>
+<p>HyperSQL 2.0 supports dedicated storage and access to BLOB and
+      CLOB objects. These objects can have huge sizes. BLOB or CLOB is
+      specified as the type of a column of the table. Afterwards, rows can be
+      inserted into the table using a PreparedStatement for efficient transfer
+      of large LOB data to the database. In <em class="glossterm">mem:</em>
+      catalogs, CLOB and BLOB data is stored in memory. In
+      <em class="glossterm">file:</em> catalogs, this data is stored in a single
+      separate file which has the extension *.lobs. The size of this file can
+      grow to huge, terabyte figures.</p>
+<p>LOB data should be store in the database using a JDBC
+      PreparedStatement object. The streaming methods send the LOB to the
+      database in one operation as a binary or character stream. Inside the
+      database, the disk space is allocated as needed and the data is saved as
+      it is being received. LOB data should be retrieved from the database
+      using a JDBC ResultSet method. When a streaming method is used to
+      retrieve a LOB, it is retrieved in large chunks in a transparent manner.
+      LOB data can also be stored by calling a JDBC method with String or
+      byte[] argument, but these methods limit the size of the LOB that can be
+      stored or retrieved.</p>
+<p>LOB data is not duplicated in the database when a lob is copied
+      from one table to another. The disk space is reused when a LOB is
+      deleted and is not contained in any table.</p>
+<p>By using a dedicated LOB store, HyperSQL achieves consistently
+      high speeds (usually over 20MB / s) for both storage and retrieval of
+      LOBs.</p>
+<p>The LOB catalog is stored in the database as a memory table.
+      Therefore the amount of JVM memory should be increased when more than
+      tens of thousands of LOBs are stored in the database.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1354D"></a>Deployment context</h3>
+</div>
+</div>
+</div>
+<p>The files used for storing HyperSQL database data are all in the
+      same directory. New files are always created and deleted by the database
+      engine. Two simple principles must be observed:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>The Java process running HyperSQL must have full privileges on
+          the directory where the files are stored. This include create and
+          delete privileges.</p>
+</li>
+<li>
+<p>The file system must have enough spare room both for the
+          'permanent' and 'temporary' files. The default maximum size of the
+          *.log file is 50MB. The *.data file can grow to up to 16GB (more if
+          the default has been increased). The .backup file can be up to the
+          size of the *.data file. The *.lobs file can grow to several
+          terabytes. The temporary files created at the time of a SHUTDOWN can
+          be equal in size to the *.script file and the .data file.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13559"></a>Readonly Databases</h3>
+</div>
+</div>
+</div>
+<p>A <em class="glossterm">file:</em> catalog can be made readonly
+      permanently, or it can be opened as readonly. To make the database
+      readonly, the property, value pair, readonly=true can be added to the
+      .properties file of the database.</p>
+<p>It is also possible to open a normal database as readonly. For
+      this, the property can be included in the URL of the first connection to
+      the database.</p>
+<p>There is another option which allows MEMORY tables to be writable,
+      but without persisting the changes at SHUTDOWN. This option is activated
+      with the property, value pair, files_readonly= true, which can be added
+      to the .properties file of the database, or included in the URL of the
+      first connection to the database. This option is useful for running
+      application tests which operate on a predefined dataset.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deployment_mem_disk-sect"></a>Memory and Disk Use</h2>
+</div>
+</div>
+</div>
+<a name="N13569" class="indexterm"></a>
+<p>Memory used by the program can be thought of as two distinct pools:
+    memory used for table data which is not released unless the data is
+    deleted and memory that can be released or is released automatically,
+    including memory used for caching, building result sets and other internal
+    operations such as storing the information needed for a rollback a
+    transaction.</p>
+<p>Most JVM implementations allocate up to a maximum amount of memory
+    (usually 64 MB by default). This amount is generally not adequate when
+    large memory tables are used, or when the average size of rows in cached
+    tables is larger than a few hundred bytes. The maximum amount of allocated
+    memory can be set on the Java command line that is used for running
+    HyperSQL. For example, with Sun JVM, parameter -Xmx256m increases the
+    amount to 256 MB.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13571"></a>Table Memory Allocation</h3>
+</div>
+</div>
+</div>
+<p>The memory used for a MEMORY table is the sum of memory used by
+      each row. Each MEMORY table row is a Java object that has 2 int or
+      reference variables. It contains an array of objects for the fields in
+      the row. Each field is an object such as <code class="classname">Integer</code>,
+      <code class="classname">Long</code>, <code class="classname">String</code>, etc. In
+      addition each index on the table adds a node object to the row. Each
+      node object has 6 int or reference variables. As a result, a table with
+      just one column of type INTEGER will have four objects per row, with a
+      total of 10 variables of 4 bytes each - currently taking up 80 bytes per
+      row. Beyond this, each extra column in the table adds at least a few
+      bytes to the size of each row.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1357F"></a>Result Set Memory Allocation</h3>
+</div>
+</div>
+</div>
+<p>By default, all the rows in the result set are built in memory, so
+      very large result sets may not be possible to build. In server mode
+      databases, by default, the result set memory is released from the server
+      once the database server has returned the result set.
+      <em class="glossterm">in-process</em> databases release the memory when the
+      application program releases the
+      <code class="classname">java.sql.ResultSet</code> object. Server modes require
+      additional memory for returning result sets, as they convert the full
+      result set into an array of bytes which is then transmitted to the
+      client.</p>
+<p>HyperSQL 2.0 supports disk-based result sets. The commands,
+      <code class="literal">SET SESSION RESULT MEMORY ROWS &lt;integer&gt;</code> and
+      <code class="literal">SET DATABASE DEFAULT RESULT MEMORY ROWS
+      &lt;integer&gt;</code> specify a threshold for the number of rows.
+      Results with row counts above the threshold are stored on disk. These
+      settings also apply to temporary tables and subquery tables.</p>
+<p>When the setFetchSize() method of the Statement interface is used
+      to limit the number rows fetched, the whole result is held by the engine
+      and is returned to the JDBC ResultSet in blocks of rows of the specified
+      fetch size. Disk-based result sets slow down the database operations and
+      should be used only when absolutely necessary, perhaps with result sets
+      that are larger than tens of thousands of rows.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13594"></a>Temporary Memory Use During Operations</h3>
+</div>
+</div>
+</div>
+<p>When UPDATE and DELETE queries are performed on CACHED tables, the
+      full set of rows that are affected, including those affected due to ON
+      UPDATE actions, is held in memory for the duration of the operation.
+      This means it may not be possible to perform deletes or updates
+      involving very large numbers of rows of CACHED tables. Such operations
+      should be performed in smaller sets.</p>
+<p>When transactions support is enabled with SET AUTOCOMMIT FALSE,
+      lists of all insert, delete or update operations are stored in memory so
+      that they can be undone when ROLLBACK is issued. For CACHED tables, only
+      the transaction information is held in memory, not the actual rows that
+      have changed. Transactions that span thousands of modification to data
+      will take up a lot of memory until the next COMMIT or ROLLBACK clears
+      the list. Each row modification uses less than 100 bytes until
+      COMMIT.</p>
+<p>When subqueries or views are used in SELECT and other statements,
+      transient tables are created and populated by the engine. If the
+      <code class="literal">SET SESSION RESULT MEMORY ROWS &lt;integer&gt;</code>
+      statement has been used, these transient tables are stored on disk when
+      they are larger than the threshold.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135A0"></a>Data Cache Memory Allocation</h3>
+</div>
+</div>
+</div>
+<p>With CACHED tables, the data is stored on disk and only up to a
+      maximum number of rows are held in memory at any time. The default is up
+      to 50,000 rows. The SET FILES CACHE ROWS command or the
+      <span class="property">hsqldb.cache_rows</span> connection property can be set to
+      alter this amount. As any random subset of the rows in any of the CACHED
+      tables can be held in the cache, the amount of memory needed by cached
+      rows can reach the sum of the rows containing the largest field data.
+      For example if a table with 100,000 rows contains 40,000 rows with 1,000
+      bytes of data in each row and 60,000 rows with 100 bytes in each, the
+      cache can grow to contain 50,000 of the smaller rows, but as explained
+      further, only 10,000 or the large rows.</p>
+<p>An additional property, <span class="property">hsqldb.cache_size</span> is
+      used in conjunction with the <span class="property">hsqldb.cache_rows</span>
+      property. This puts a limit in bytes on the total size of rows that are
+      cached. The default values is 10,000KB. (This is the size of binary
+      images of the rows and indexes. It translates to more actual memory,
+      typically 2-4 times, used for the cache because the data is represented
+      by Java objects.)</p>
+<p>If memory is limited, the <span class="property">hsqldb.cache_rows</span>
+      or <span class="property">hsqldb.cache_size</span> database properties can be
+      reduced. In the example above, if the
+      <span class="property">hsqldb.cache_size</span> is reduced from 10,000 to 5,000,
+      it will allow the number of cached rows to reach 50,000 small rows, but
+      only 5,000 of the larger rows.</p>
+<p>Data for CLOB and BLOB columns is not cached and does not affect
+      the CACHED table memory cache.</p>
+<p>The use of Java nio file access method also increases memory
+      usage. Access with nio improves database update speed and is used by
+      default for data files up to 256 MB. For minimal memory use, nio access
+      should be disabled.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135BF"></a>Object Pool Memory Allocation</h3>
+</div>
+</div>
+</div>
+<p>HyperSQL uses a set of fast pools for immutable objects such as
+      Integer, Long and short String objects that are stored in the database.
+      In most circumstances, this reduces the memory footprint still further
+      as fewer copies of the most frequently-used objects are kept in memory.
+      The object pools are shared among all databases in the JVM. The size of
+      each pool can be modified only by altering and recompiling the
+      <code class="literal">org.hsqldb.store.ValuePool</code> class.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135C7"></a>Lob Memory Usage</h3>
+</div>
+</div>
+</div>
+<p>Access to lobs is always performed in chunks, so it is perfectly
+      possible to store and access a CLOB or BLOB that is larger than the JVM
+      memory allocation. Early versions of HyperSQL 2.0 use memory-based
+      tables for the lob catalog (not the data). Therefore it is practical to
+      store about 100,000 individual lobs in the database with the default JVM
+      memory allocation. More lobs can be stored with larger JVM memory
+      allocations. The realistic maximum number of lobs stored in the database
+      is probably about a million. The actual total size of lobs is almost
+      unlimited. We have tested with over 100 GB of lobs without any loss of
+      performance.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135CC"></a>Disk Space</h3>
+</div>
+</div>
+</div>
+<p>With file: database, the engine uses the disk for storage of data
+      and any change. For safely, the engine backs up the data internally
+      during operation. Spare space, at least equal to the size of the .data
+      and .script file is needed. The .lobs file is not backed up during
+      operation.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deployment_conns-sect"></a>Managing Database Connections</h2>
+</div>
+</div>
+</div>
+<p>In all running modes (server or <em class="glossterm">in-process</em>)
+    multiple connections to the database engine are supported.
+    <em class="glossterm">in-process</em> (standalone) mode supports connections
+    from the client in the same Java Virtual Machine, while server modes
+    support connections over the network from several different
+    clients.</p>
+<p>Connection pooling software can be used to connect to the database
+    but it is not generally necessary. Connection pools may be used for the
+    following reasons.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>To allow new queries to be performed while a time-consuming
+        query is being performed in the background. In HyperSQL, blocking
+        depends on the transaction control model, the isolation level, and the
+        current activity by other sessions.</p>
+</li>
+<li>
+<p>To limit the maximum number of simultaneous connections to the
+        database for performance reasons. With HSQLDB this can be useful if
+        your application is designed in a way that opens and closes
+        connections for each small task. Also, the overall performance may be
+        higher when fewer simultaneous connections are used. If you want to
+        reduce the number of simultaneous sessions, you can use a connection
+        pool with fewer pooled connections.</p>
+</li>
+</ul>
+</div>
+<p>An application that is not both multi-threaded and transactional,
+    such as an application for recording user login and logout actions, does
+    not need more than one connection. The connection can stay open
+    indefinitely and reopened only when it is dropped due to network
+    problems.</p>
+<p>When using an <em class="glossterm">in-process</em> database, when the
+    last connection to the database is closed, the database still remains
+    open. An explicit SHUTDOWN command, with or without an argument, is
+    required to close the database. A connection property on the connection
+    URL or in a properties object can be used to shutdown the database when
+    the last connection is closed.</p>
+<p>When using a server database (and to some extent, an
+    <em class="glossterm">in-process</em> database), care must be taken to avoid
+    creating and dropping JDBC Connections too frequently. Failure to observe
+    this will result in poor performance when the application is under heavy
+    load.</p>
+<p>A common error made by users in load-test simulations is to use a
+    single client machine to open and close thousands of connections to a
+    HyperSQL server instance. The connection attempts will fail after a few
+    thousand because of OS restrictions on opening sockets and the delay that
+    is built into the OS in closing them.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N135F4"></a>Tweaking the Mode of Operation</h2>
+</div>
+</div>
+</div>
+<p>Different modes of operation and settings are used for different
+    purposes. Some scenarios are discussed below:</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135F9"></a>Application Development and Testing</h3>
+</div>
+</div>
+</div>
+<p>For application unit testing you can use an all-in-memory,
+      in-process database.</p>
+<p>If the tests are all run in one process, then the contents of a
+      <em class="glossterm">mem:</em> database survives between tests. To release
+      the contents you can use the SHUTDOWN command (an SQL command). You can
+      even use multiple <em class="glossterm">mem:</em> databases in your tests
+      and SHUTDOWN each one separately.</p>
+<p>If the tests are in different processes and you want to keep the
+      data between the tests, the best solution is to use a Server instance
+      that has a <em class="glossterm">mem:</em> database. After the tests are
+      done, you can SHUTDOWN this database, which will shutdown the
+      server.</p>
+<p>The Server has an option that allows databases to be created as
+      needed by making a connection (see the Listeners Chapter). This option
+      is useful for testing, as your server is never shut down. Each time you
+      connect to the <em class="glossterm">mem:</em> database that is served by
+      the Server, the database is created if it does not exist (i.e. has been
+      previously shut down).</p>
+<p>If you do not want to run a Server instance, and you need
+      persistence between tests in different processes, then you should use a
+      <em class="glossterm">file:</em> database. You can use the
+      <code class="literal">shutdown=true</code> connection property to ensure the
+      database is persisted fully after the connections are closed. An
+      alternative option is to use <code class="literal">hsqldb.write_delay=false</code>
+      connection property, but this is slightly slower than the other
+      option.</p>
+<p>It has been reported that some data access frameworks do not close
+      all their connection to the database after the tests. In such
+      situations, you need to use zero WRITE DELAY if you want the data to
+      persist at the end of the tests</p>
+<p>You may actually want to use a <em class="glossterm">file:</em>
+      database, or a server instance that serves a
+      <em class="glossterm">file:</em> database in preference to a
+      <em class="glossterm">mem:</em> database. As HyperSQL logs the DDL and DML
+      statements in the .log file, this file can be used to check what is
+      being sent to the database. Note that UPDATE statements are represented
+      by a DELETE followed by an INSERT statement. Statements are written out
+      when the connection commits. The write delay also has an effect on how
+      soon the statements are written out.</p>
+<p>Some types of tests start with a database that already contains
+      the tables and data, and perform various operations on it during the
+      tests. You can create and populate the initial database then set the
+      property "files_read_only=true" in the .properties file of the database.
+      The tests can then modify the database, but these modifications are not
+      persisted after the tests have completed.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1362A"></a>Embedded Databases in Desktop Applications</h3>
+</div>
+</div>
+</div>
+<p>In this usage, the amount of data change is often limited and
+      there is often a requirement to persist the data immediately. You can
+      use the property <code class="literal">write_delay=false</code> to force a disk
+      sync after each commit. Before the application is closed, you should
+      perform the SHUTDOWN command to ensure the database is opened instantly
+      when it is next opened.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13632"></a>Embedded Databases in Server Applications</h3>
+</div>
+</div>
+</div>
+<p>This usage involves a server application, such as a web
+      application, connecting to an embedded HyperSQL instance. In this usage,
+      the database is often accessed heavily, therefore performance and
+      latency is a consideration. If the database is updated heavily, the
+      default value of the WRITE DELAY property (1 sec) is often enough, as it
+      is assumed the server or the application does not go down frequently. If
+      it is necessary, you can reduce the WRITE DELAY to a small value (20 ms)
+      without impacting the update speed. If you reduce WRITE DELAY to zero,
+      performance drops to the speed of disk file sync operation.</p>
+<p>Alternatively, a server application can use an all-in-mem database
+      instance for fast access, while sending the data changes to a
+      persistent, disk based instance either periodically or in real
+      time.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13639"></a>Embedding a Database Listener</h3>
+</div>
+</div>
+</div>
+<p>Since you won't be able to access
+      <em class="glossterm">in-process</em> database instances from other
+      processes, you will often want to run a Listener in your server
+      applications with embedded databases. You can do this by starting up a
+      Server or WebServer instance programmatically, but you could also use
+      the class <code class="classname">org.hsqldb.util.MainInvoker</code> to start up
+      your application and a Server or WebServer without any programming.
+      <div class="example">
+<a name="N13644"></a>
+<p class="title">
+<b>Example&nbsp;11.1.&nbsp;MainInvoker Example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  java -cp path/to/your/app.jar:path/to/hsqldb.jar your.App "" org.hsqldb.server.Server</pre>
+</div>
+</div>
+<br class="example-break"> (Use ; instead of : to delimit classpath elements on
+      Windows). Specify the same <em class="glossterm">in-process</em> JDBC URL to
+      your app and in the <code class="filename">server.properties</code> file. You can
+      then connect to the database from outside using a JDBC URL like
+      <code class="literal">jdbc:hsqldb:hsql://hostname</code>.</p>
+<p>This tactic can be used to run off-the-shelf server
+      applications with an embedded HyperSQL Server, without doing any
+      coding.</p>
+<p>
+<code class="classname">MainInvoker</code> can be used to run any
+      number of Java class main method invocations in a single JVM. See the
+      API spec for <code class="classname"><a class="classname" href="apd.html#MainInvoker.html-link">
+      MainInvoker</a></code> for details on its usage.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1365D"></a>Using HyperSQL Without Logging</h3>
+</div>
+</div>
+</div>
+<p>All file database that are not readonly, write changes to the .log
+      file. There are scenarios where writing to the .log file can be turned
+      off to improve performance, especially with larger databases. For these
+      applications you can set the property
+      <code class="literal">hsqldb.log_data=false</code> to disable the recovery log and
+      speed up data change performance. The equivalent SQL command is SET
+      FILES LOG FALSE.</p>
+<p>With this setting, no data is logged, but all the changes to
+      cached tables are written to the .data file. To persist all the data
+      changes up to date, you can use the CHECKPOINT command. If you perform
+      SHUTDOWN, the data is also persisted correctly. If you do not use
+      CHECKPOINT or SHUTDOWN. All the changes are lost and the database
+      reverts to its original state when it is opened.</p>
+<p>Your server applications can use a database as a temporary disk
+      data cache which is not persisted past the lifetime of the application.
+      For this usage, delete the database files when the application
+      ends.</p>
+<p>On some platforms, such as embedded devices which are reliable,
+      this is also a useful option. Your application issues CHECKPOINT to save
+      the changes made so far. This method of use reduces write operations on
+      SSD devices. For this usage, the lock file should also be disabled with
+      the connection property hsqldb.lock_file=false.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1366B"></a>Server Databases</h3>
+</div>
+</div>
+</div>
+<p>Running databases in a HyperSQL server is the best overall method
+      of access. As the JVM process is separate from the application, this
+      method is the most reliable as well as the most accessible method of
+      running databases.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deployment_upgrade-sect"></a>Upgrading Databases</h2>
+</div>
+</div>
+</div>
+<a name="N13674" class="indexterm"></a>
+<p>Any database that is not produced with the release version of
+    HyperSQL 2.0 must be upgraded to this version. Most catalogs created with
+    1.8.x can be upgraded simply by opening with HyperSQL 2. When this is not
+    possible due to errors, the rest of the procedures below should be
+    followed.</p>
+<p>Once a database is upgraded to 2.0, it can no longer be used with
+    previous versions of HyperSQL.</p>
+<p>If your database has been created with version 1.7.x, first upgrade
+    to version 1.8.1 and perform a SHUTDOWN COMPACT with this version. You can
+    then open and upgrade the database with version 2.0.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="upgrade_via_script-sect"></a>Upgrading From Older
+      Versions</h3>
+</div>
+</div>
+</div>
+<p>To upgrade from version 1.8.x with the default TEXT format script
+      files, simply open the database with 2.0. If the version 1.8.x files
+      have database script format set to BINARY or COMPRESSED (ZIPPED) you
+      must issue the SET SCRIPTFORMAT TEXT and SHUTDOWN SCRIPT commands with
+      the old version, then open with the new version of the engine. In most
+      cases the upgrade is successful and complete.</p>
+<p>It is strongly recommended to execute SHUTDOWN COMPACT after an
+      automatic upgrade from previous versions.</p>
+<p>If your database has been created with version 1.7.2 or 1.7.3,
+      first upgrade to version 1.8.1 and perform a SHUTDOWN COMPACT with this
+      version. You can then upgrade the database to version 2.0.</p>
+<p>To upgrade from older version database files (1.7.1 and older)
+      that contain CACHED tables, use the SCRIPT procedure below. In all
+      versions of HyperSQL, the <code class="literal">SCRIPT 'filename'</code> command
+      (used as an SQL statement) allows you to save a full record of your
+      database, including database object definitions and data, to a file of
+      your choice. You can export a script file using the old version of the
+      database engine and open the script as a database with 2.0.</p>
+<div class="procedure">
+<a name="N1368E"></a>
+<p class="title">
+<b>Procedure&nbsp;11.1.&nbsp;Upgrade Using the SCRIPT Procedure for Very Old
+        Versions</b>
+</p>
+<ol type="1">
+<li>
+<p>Open the original database in the old version of
+          DatabaseManager</p>
+</li>
+<li>
+<p>Issue the SCRIPT command, for example <code class="literal">SCRIPT
+          'newversion.script'</code> to create a script file containing a
+          copy of the database.</p>
+</li>
+<li>
+<p>SHUTDOWN this database.</p>
+</li>
+<li>
+<p>Copy the original <code class="literal">*.properties</code> file into
+          <code class="filename">newversion.properties</code> in the same directory as
+          <code class="filename">newversion.script</code>
+</p>
+</li>
+<li>
+<p>Try to open the new database <code class="filename">newversion</code>
+          using DatabaseManager of version 1.8.1.</p>
+</li>
+<li>
+<p>If there is any inconsistency in the data, the script line
+          number is reported on the console and the opening process is
+          aborted. Edit and correct any problems in the
+          <code class="filename">newversion.script</code> before attempting to open
+          again. Use the guidelines in the next section (Manual Changes to the
+          <code class="literal">.script</code> File). Use a programming editor that is
+          capable of handling very large files and does not wrap long lines of
+          text.</p>
+</li>
+</ol>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N136B7"></a>Manual Changes to the *.script File</h3>
+</div>
+</div>
+</div>
+<p>In HyperSQL 2.0 the full range of ALTER TABLE commands is
+      available to change the data structures and their names. However, if an
+      old database cannot be opened due to data inconsistencies, or it uses
+      index or column names that are not compatible with 2.0, manual editing
+      of the <code class="literal">*.script</code> file can be performed.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Version 2.0 does not accept duplicate names for indexes that
+          were allowed before 1.7.2.</p>
+</li>
+<li>
+<p>Version 2.0 does not accept some table or column names that
+          are SQL reserved keywords without double quoting.</p>
+</li>
+<li>
+<p>Version 2.0 is more strict with check conditions and default
+          values.</p>
+</li>
+</ul>
+</div>
+<p>Other manual changes are also possible. Note that the
+      <code class="literal">*.script</code> file must be the result of a SHUTDOWN SCRIPT
+      and must contain the full data for the database. The following changes
+      can be applied so long as they do not affect the integrity of existing
+      data.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Names of tables, columns and indexes can be changed. These
+          changes must be consistent regarding foreign key constraints.</p>
+</li>
+<li>
+<p>
+<code class="literal">CHECK</code>
+</p>
+<p>A check constraint can always be removed.</p>
+</li>
+<li>
+<p>
+<code class="literal">NOT NULL</code>
+</p>
+<p>A not-null constraint can always be removed.</p>
+</li>
+<li>
+<p>
+<code class="literal">PRIMARY KEY</code>
+</p>
+<p>A primary key constraint can be removed. It cannot be removed
+          if there is a foreign key referencing the column(s).</p>
+</li>
+<li>
+<p>
+<code class="literal">UNIQUE</code>
+</p>
+<p>A UNIQUE constraint can be removed if there is no foreign key
+          referencing the column(s).</p>
+</li>
+<li>
+<p>
+<code class="literal">FOREIGN KEY</code>
+</p>
+<p>A FOREIGN KEY constraint can always be removed.</p>
+</li>
+<li>
+<p>
+<code class="literal">COLUMN TYPES</code>
+</p>
+<p>Some changes to column types are possible. For example an
+          INTEGER column can be changed to BIGINT.</p>
+</li>
+</ul>
+</div>
+<p>After completing the changes and saving the modified
+      <code class="literal">.script</code> file, you can open the database as
+      normal.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N136FB"></a>Backward Compatibility Issues</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL 2.0 conforms to the SQL Standard better than previous
+    versions and supports more features. For these reasons, there may be some
+    compatibility issues when converting old database, or using applications
+    that were written for version 1.8.x or earlier. Some of the potential
+    issues are listed here.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>User names and passwords are case-sensitive. Check the .script
+        file of a database for the correct case of user name and password and
+        use this form in the connection properties or on connection
+        URL.</p>
+</li>
+<li>
+<p>Check constraints must conform to the SQL Standard. A check
+        constraint is rejected if it is not deterministic or retrospectively
+        deterministic. When opening an old database, HyperSQL silently drops
+        check constraints that no longer compile. See under check constraints
+        for more detail about what is not allowed.</p>
+</li>
+<li>
+<p>Type declarations in column definition and in cast expressions
+        must have the necessary size parameters.</p>
+</li>
+<li>
+<p>In connection with the above, an old database that did not have
+        the <code class="literal">enforce_strict_size</code> property, is now converted
+        to version 2.0 with the engine supplying the missing size parameters.
+        For example, a VARCHAR column declaration that has no size, is given a
+        32K size. Check these sizes are adequate for your use, and change the
+        column definition as necessary.</p>
+</li>
+<li>
+<p>Column names in a GROUP BY clause were previously resolved to
+        the column label. They are now resolved to column name first, and if
+        the name does not match, to the column label.</p>
+</li>
+<li>
+<p>If two or more tables in a join contain columns with the same
+        name, the columns cannot be referenced in join and where conditions.
+        Use table names before column names to qualify the references to such
+        columns.</p>
+</li>
+<li>
+<p>Table definitions containing GENERATED BY DEFAULT AS IDENTITY
+        but with no PRIMARY KEY do not automatically create a primary key.
+        Database .script files made with 1.8 are fine, as the PRIMARY KEY
+        clause is always included. But your application program may assume an
+        automatic primary key is created.</p>
+</li>
+<li>
+<p>CREATE ALIAS is now obsolete. Use the new function definition
+        syntax. The <code class="classname">org.hsqldb.Library </code>class no longer
+        exists. You should use the SQL form of the old library functions. For
+        example, use <code class="literal">LOG(x)</code> rather than the direct form,
+        <code class="literal">"org.hsqldb.Library.log"(x)</code>.</p>
+</li>
+<li>
+<p>The names of some commands for changing database and session
+        properties have changed. See the list of statements in this
+        chapter.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deployment_backup-sect"></a>Backing Up Database Catalogs</h2>
+</div>
+</div>
+</div>
+<a name="N1372C" class="indexterm"></a>
+<p>The database engine saves the files containing all the data in a
+    file catalog when a shutdown takes place. It automatically recovers from
+    an abnormal termination and preserves the data when the catalog is opened
+    next time. In an ideal operating environment, where there is no OS crash,
+    disk failure, bugs in code, etc. there would be no need regularly to
+    backup a database. This is meant to say, the engine performs the routine
+    shutdown procedure internally, therefore backing up catalogs is an
+    insurance policy against all sorts of misadventure that are not under the
+    control of the database engine.</p>
+<p>The data for each catalog consists of up to 5 files in the same
+    directory with the endings such as <code class="literal">*.properties</code>,
+    <code class="literal">*.script</code>, etc., as detailed in previous
+    chapters.</p>
+<p>HyperSQL 2.0 includes commands to backup the database files into
+    a single <code class="literal">.tar</code> or <code class="literal">.tar.gz</code> file
+    archive. The backup can be performed by a command given in a JDBC session
+    if the target database catalog is running, or on the command-line if the
+    target catalog has been shutdown.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13742"></a>Making Online Backups</h3>
+</div>
+</div>
+</div>
+<p>To back up a running catalog, obtain a JDBC connection and
+      issue a <code class="literal">BACKUP DATABASE</code> command in SQL. In its most
+      simple form, the command format below will backup the database as a
+      single <code class="literal">.tar.gz</code> file to the given directory.</p>
+<pre class="programlisting">  BACKUP DATABASE TO &lt;directory name&gt; BLOCKING</pre>
+<p>See the next section under Statements for details about the
+      command and its options. See the sections below about restoring a
+      backup.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13751"></a>Making Offline Backups</h3>
+</div>
+</div>
+</div>
+<p>To back up an offline catalog, the catalog must be in shut down
+      state. You will run a Java command like this <div class="example">
+<a name="N13756"></a>
+<p class="title">
+<b>Example&nbsp;11.2.&nbsp;Offline Backup Example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --save  \
+  tar/path.tar db/base/path</pre>
+</div>
+</div>
+<br class="example-break">where <code class="filename">tar/path.tar</code> is a file path to
+      the <code class="literal">*.tar</code> or <code class="literal">*.tar.gz</code> file to be
+      created, and <code class="filename">db/base/path</code> is the file path to the
+      catalog file base name (in same fashion as in
+      <code class="varname">server.database.*</code> settings and JDBC URLs with catalog
+      type <em class="glossterm">file:</em>.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1376E"></a>Examining Backups</h3>
+</div>
+</div>
+</div>
+<p>You can list the contents of backup tar files with
+      <code class="classname">DbBackup</code> on your operating system command line,
+      or with any Pax-compliant tar or pax client (this includes GNU tar),
+      <div class="example">
+<a name="N13776"></a>
+<p class="title">
+<b>Example&nbsp;11.3.&nbsp;Listing a Backup with DbBackup</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --list tar/path.tar</pre>
+</div>
+</div>
+<br class="example-break">You can also give regular expressions at the end of the
+      command line if you are only interested in some of the file entries in
+      the backup. Note that these are real regular expressions, not shell
+      globbing patterns, so you would use <code class="literal">.+script</code> to match
+      entries ending in "script", not <code class="literal">*script</code>.</p>
+<p>You can examine the contents of the backup in their entirety by
+      restoring the backup, as explained in the following section, to a
+      temporary directory.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13784"></a>Restoring a Backup</h3>
+</div>
+</div>
+</div>
+<p>You use <code class="classname">DbBackup</code> on your operating system
+      command line to restore a catalog from a backup. <div class="example">
+<a name="N1378C"></a>
+<p class="title">
+<b>Example&nbsp;11.4.&nbsp;Restoring a Backup with DbBackup</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --extract  \
+      tar/path.tar db/dir</pre>
+</div>
+</div>
+<br class="example-break">where <code class="filename">tar/path.tar</code> is a file path to
+      the *.tar or *.tar.gz file to be read, and <code class="filename">db/dir</code>
+      is the target directory to extract the catalog files into. Note that
+      <code class="filename">db/dir</code> specifies a directory path, without the
+      catalog file base name. The files will be created with the names stored
+      in the tar file (and which you can see as described in the preceding
+      section).</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1379B"></a>Encrypted Databases</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL supports encrypted databases. Encryption services use the
+    Java Cryptography Extensions (JCE) and uses the ciphers installed with the
+    JRE. HyperSQL itself does not contain any cryptography code.</p>
+<p>Three elements are involved in specifying the encryption method and
+    key. A cipher, together with its configuration is identified by a string
+    which includes the name of the cipher and optional parameters. A provider
+    is the fully qualified class name of the cipher provider. A key is
+    represented as a hexadecimal string.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137A2"></a>Creating and Accessing an Encrypted Database</h3>
+</div>
+</div>
+</div>
+<p>First, a key must be created for the desired cipher and
+      configuration. This is done by calling the function CRYPT_KEY(&lt;cipher
+      spec&gt;, &lt;provider&gt;). If the default provider (the built-in JVM
+      ciphers) is used, then NULL should be specified as the provider. The
+      CRYPT_KEY function returns a hexadecimal key. The function call can be
+      made in any HyperSQL database, so long as the provider class is on the
+      classpath. This key can be used to create a new encrypted database.
+      Calls to this function always return different keys, based on a
+      generated random values.</p>
+<p>As an example, a call to CRYPT_KEY('Blowfish', null) returned the
+      string, '604a6105889da65326bf35790a923932'. To create a new database,
+      the URL below is used:</p>
+<p>
+<code class="literal">jdbc:hsqldb:file:&lt;database
+      path&gt;;crypt_key=604a6105889da65326bf35790a923932;crypt_type=blowfish</code>
+</p>
+<p>The third property name is crypt_provider. This is specified only
+      when the provider is not the default provider.</p>
+<p>HyperSQL works with any symmetric cipher that may be available
+      from the JVM.</p>
+<p>The files that are encrypted include the .script, .data, .backup
+      and .log files. The .lobs file is not encrypted by default. The property
+      crypt_lobs=true must be specified to encrypt the .lobs file.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137B2"></a>Speed Considerations</h3>
+</div>
+</div>
+</div>
+<p>General operations on an encrypted database are performed the same
+      as with any database. However, some operations are significantly slower
+      than with the equivalent cleartext database. With MEMORY tables, there
+      is no difference to the speed of SELECT statements, but data change
+      statements are slower. With CACHED tables, the speed of all statements
+      is slower.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137B7"></a>Security Considerations</h3>
+</div>
+</div>
+</div>
+<p>Security considerations for encrypted databases have been
+      discussed at length in HSQLDB discussion groups. Development team
+      members have commented that encryption is not a panacea for all security
+      needs. The following issues should be taken into account:</p>
+<p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Encrypted files are relatively safe in transport, but
+            because databases contain many repeated values and words,
+            especially known tokens such as CREATE, INSERT, etc., breaking the
+            encryption of a database may be simpler than an unknown
+            file.</p>
+</li>
+<li>
+<p>Only the files are encrypted, not the memory image. Poking
+            into computer memory, while the database is open, will expose the
+            contents of the database.</p>
+</li>
+<li>
+<p>HyperSQL is open source. Someone who has the key, can
+            compile and use a modified version of the program that saves a
+            full cleartext dump of an encrypted database</p>
+</li>
+</ul>
+</div>Therefore encryption is generally effective only when
+      the users who have access to the crypt key are trusted.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N137C8"></a>Monitoring Database Operations</h2>
+</div>
+</div>
+</div>
+<p>Database operations can be monitored at different levels using
+    internal HyperSQL capabilities or add-ons.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137CD"></a>Statement Level Monitoring</h3>
+</div>
+</div>
+</div>
+<p>Statement level monitoring allows you to gather statistics about
+      executed statements. HyperSQL is supported by the monitoring tool JAMon
+      (Java Application Monitor). JAMon is currently developed as the
+      SourceForge project, jamonapi.</p>
+<p>JAMon works at the JDBC level. It can monitor and gather
+      statistics on different types of executed statements or other JDBC
+      calls.</p>
+<p>Early versions of JAMon were developed with HSQLDB and had to be
+      integrated into HSQLDB at code level. The latest versions can be added
+      on as a proxy in a much simpler fashion.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137D6"></a>Internal Event Monitoring</h3>
+</div>
+</div>
+</div>
+<p>HyperSQL can log important internal events of the engine. These
+      events occur during the operation of the engine, and are not always
+      coupled with the exact type of statement being executed. Normal events
+      such as opening and closing of files, or errors such as OutOfMemory
+      conditions are examples of logged events.</p>
+<p>HyperSQL supports two methods of logging. One method is specific
+      to the individual database and is managed internally by HyperSQL. The
+      other method is specific to JVM and is managed by a logging
+      framework.</p>
+<p>The internally-generated, individual log for the database can be
+      enabled with the <code class="literal">SET DATABASE EVENT LOG LEVEL</code>
+      statement, described in the next section. This method of logging is very
+      useful for desktop application deployment, as it provides an ongoing
+      record of database operations.</p>
+<p>HyperSQL also supports log4J and JDK logging. The same event
+      information that is passed to the internal log, is passed to external
+      logging frameworks. These frameworks are configured outside HyperSQL.
+      The log messages include the unique id of the database that generated
+      the message, so it can be identified in a multi-database server
+      context.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137E4"></a>Server Operation Monitoring</h3>
+</div>
+</div>
+</div>
+<p>A Server or WebServer instance can be started with the property
+      server.silent=false. This causes all the connections and their executed
+      statements to be printed to stdout as the statements are submitted to
+      the server.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N137E9"></a>Statements</h2>
+</div>
+</div>
+</div>
+<p>System level statements are listed in this section. Statements that
+    begin with SET DATABASE or SET FILES are for properties that have an
+    effect on the normal operation of HyperSQL. The effects of these
+    statements are also discussed in different chapters.</p>
+<a name="N137EE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SHUTDOWN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>shutdown statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;shutdown statement&gt; ::= SHUTDOWN [IMMEDIATELY |
+    COMPACT | SCRIPT]</code>
+</p>
+<p>Shutdown the database. If the optional qualifier is not used, a
+    normal SHUTDOWN is performed. A normal SHUTDOWN ensures all data is saved
+    correctly and the database opens without delay on next use.</p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">SHUTDOWN IMMEDIATELY</span>
+</p>
+</td><td>
+<p>Saves the *.log file and closes the database files. This is
+          the quickest form of shutdown. This command should not be used as
+          the routine method of closing the database, because when the
+          database is accessed next time, it may take a long time to
+          start.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">SHUTDOWN COMPACT</span>
+</p>
+</td><td>
+<p>This is similar to normal SHUTDOWN, but reduces the *.data
+          file to its minimum size. It takes longer than normal
+          SHUTDOWN.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">SHUTDOWN SCRIPT</span>
+</p>
+</td><td>
+<p>This is similar to SHUTDOWN COMPACT, but it does not rewrite
+          the <code class="literal">*.data</code> and text table files. After SHUTDOWN
+          SCRIPT, only the <code class="literal">*.script</code> and
+          <code class="literal">*.properties</code> files remain. At the next startup,
+          these files are processed and the <code class="literal">*.data</code> and
+          <code class="literal">*.backup</code> files are created. This command in
+          effect performs part of the job of SHUTDOWN COMPACT, leaving the
+          other part to be performed automatically at the next startup.</p>
+<p>This command produces a full script of the database which can
+          be edited for special purposes prior to the next startup.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13825" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BACKUP DATABASE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>backup database statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;backup database statement&gt; ::= BACKUP DATABASE TO
+    &lt;file path&gt; {SCRIPT | [NOT] COMPRESSED} BLOCKING</code>
+</p>
+<p>Backup the database to specified <code class="literal">&lt;file
+    path&gt;</code> for archiving purposes.</p>
+<p>The <code class="literal">&lt;file path&gt;</code> can be in two forms. If
+    the <code class="literal">&lt;file path&gt;</code> ends with a forward slash, it
+    specifies a directory. In this case, an automatic name for the archive is
+    generated that includes the date, time and the base name of the database.
+    The database is backed up to this archive file in the specified directory.
+    If the <code class="literal">&lt;file path&gt;</code> does not end with a forward
+    slash, it specifies a user-defined file name for the backup archive. The
+    archive is in tar, gzip format depending on whether it is compressed or
+    not.</p>
+<p>The SCRIPT option is not currently supported. If SCRIPT is
+    specified, the backup will consist of two files, a
+    <code class="literal">*.properties</code> file and a <code class="literal">*.script</code>
+    file, which contain all the data and settings of the database. These files
+    are not compressed.</p>
+<p>If COMPRESSED or NOT COMPRESSED is specified, the backup consists
+    of the current snapshot of database files. During backup, a CHECKPOINT
+    command is silently executed.</p>
+<p>The qualifier, BLOCKING, means all database operations are
+    suspended during backup.</p>
+<p>The HyperSQL jar also contains a program that creates an archive
+    of an offline database. It also contains a program to expand an archive
+    into database files. These programs are documented in this chapter under
+    Backing up Database Catalogs.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13854" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CHECKPOINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>checkpoint statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;checkpoint statement&gt; ::= CHECKPOINT
+    [DEFRAG]</code>
+</p>
+<p>Closes the database files, rewrites the script file, deletes the
+    log file and opens the database. If <code class="literal">DEFRAG</code> is
+    specified, also shrinks the <code class="literal">*.data</code> file to its minumum
+    size. Only a user with the DBA role can execute this statement.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N1386D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CRYPT_KEY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>crypt_key function</em></span>
+</p>
+<p>
+<code class="literal">&lt;crypt_key function&gt; ::= CRYPT_KEY ( &lt;cipher
+    spec&gt;, &lt;provider&gt; )</code>
+</p>
+<p>The statement, <code class="literal">CALL CRYPT_KEY( &lt;cipher spec&gt;,
+    &lt;provider&gt; )</code> returns a binary string representing a valid
+    key for the giver cipher and provider. The
+    <code class="literal">&lt;provider&gt;</code> argument is specified as NULL for the
+    default provider.</p>
+<a name="N13884" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SCRIPT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>script statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;script statement&gt; ::= SCRIPT [&lt;file
+    name&gt;]</code>
+</p>
+<p>Returns a script containing SQL statements that define the
+    database, its users, and its schema objects. If <code class="literal">&lt;file
+    name&gt;</code> is not specified, the statements are returned in a
+    ResultSet, with each row containing an SQL statement. No data statements
+    are included in this form. The optional file name is a single-quoted
+    string. If <code class="literal">&lt;file name&gt;</code> is specified, then the
+    script is written to the named file. In this case, all the data in all
+    tables of the database is included in the script as INSERT
+    statements.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N1389D" class="indexterm"></a><a name="N138A2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE COLLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database collation statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database collation statement&gt; ::= SET
+    DATABASE COLLATION &lt;collation name&gt;</code>
+</p>
+<p>Each database can have its own collation. Sets the collation from
+    the set of collations supported by HyperSQL. Once this command has been
+    issued, the database can be opened in any JVM and will retain its
+    collation. Only a user with the DBA role can execute this
+    statement.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N138B5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE DEFAULT TABLE
+    TYPE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database default table type
+    statement</em></span><code class="literal"> </code>
+</p>
+<p>
+<code class="literal">&lt;set database default table type&gt; ::= SET DATABASE
+    DEFAULT TABLE TYPE { CACHED | MEMORY }</code>
+</p>
+<p>Sets the type of table created when the next CREATE TABLE
+    statement is executed. The default is MEMORY.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N138CA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE DEFAULT RESULT MEMORY
+    ROWS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database default result memory rows
+    statement</em></span><code class="literal"> </code>
+</p>
+<p>
+<code class="literal">&lt;set database default result memory rows&gt; ::= SET
+    DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned integer
+    literal&gt;</code>
+</p>
+<p>Sets the maximum number of rows of each result set and other
+    internal temporary table that is held in memory. This setting applies to
+    all sessions. Individual sessions can change the value with the
+    <code class="literal">SET SESSION RESULT MEMORY ROWS</code> command. The default is
+    0, meaning all result sets are held in memory.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N138E2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE EVENT LOG
+    LEVEL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database event log level
+    statement*</em></span><code class="literal"> </code>
+</p>
+<p>
+<code class="literal">&lt;set database event log level&gt; ::= SET DATABASE
+    EVENT LOG LEVEL { 0 | 1 | 2 }</code>
+</p>
+<p>Sets the amount of information logged in the internal,
+    database-specific event log. Level 0 means no log. Level 1 means only
+    important (error) events. Level 2 means more events, including both
+    important and less important (normal) events. For readonly and
+    <em class="glossterm">mem:</em> databases, if the level is set above 0, the
+    log messages are directed to stderr.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N138FA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE GC</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database gc statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database gc statement&gt; ::= SET DATABASE GC
+    &lt;unsigned integer literal&gt;</code>
+</p>
+<p>An optional property which forces calls to <code class="literal">System.gc()
+    </code>after the specified number of row operations. The default value
+    for this property is 0, which means no System.gc() calls. Usual values for
+    this property range from 10000 depending on the system and the memory
+    allocation. This property may be useful in some in-process deployments,
+    especially with older JVM implementations.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13910" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE SQL SIZE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database sql size statement</em></span><code class="literal">
+    </code>
+</p>
+<p>
+<code class="literal">&lt;set database sql size statement&gt; ::= SET DATABASE
+    SQL SIZE { TRUE | FALSE }</code>
+</p>
+<p>Enable or disable enforcement of column sizes for CHAR and
+    VARCHAR columns. The default is TRUE, meaning table definition must
+    contain <code class="literal">VARCHAR(n)</code> instead of
+    <code class="literal">VARCHAR</code>.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N1392B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE SQL NAMES</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database sql names statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database sql names statement&gt; ::= SET
+    DATABASE SQL NAMES { TRUE | FALSE }</code>
+</p>
+<p>Enable or disable full enforcement of the rule that prevents SQL
+    keywords being used for database object names such as columns and tables.
+    The default is FALSE, meaning disable.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N1393E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE SQL
+    REFERENCES</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database sql references
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database sql references statement&gt; ::= SET
+    DATABASE SQL REFERENCES { TRUE | FALSE }</code>
+</p>
+<p>This command can enable or disable full enforcement of the rule
+    that prevents ambiguous column references in SQL statements (usually
+    SELECT statements). A column reference is ambiguous when it is not
+    qualified by a table name or table alias and can refer to more than one
+    column in a JOIN list.</p>
+<p>The property is FALSE by default. It is better to enable this
+    check while development, to improve the quality and correctness of SQL
+    statements.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13953" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE REFERENTIAL
+    INTEGRITY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database referential integrity
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database referential integrity statement&gt; ::=
+    SET DATABASE REFERENTIAL INTEGRITY { TRUE | FALSE }</code>
+</p>
+<p>This command enables or disables the enforcement of referential
+    integrity constraints (foreign key constraints), check constraints apart
+    from NOT NULL and triggers. By default, referential integrity constraints
+    are checked.</p>
+<p>The only legitimate use of this statement is before importing
+    large amounts of external data into tables that have existing FOREIGN KEY
+    constraints. After import, the statement must be used again to enable
+    constraint enforcement.</p>
+<p>If you are not sure the data conforms to the constraints, run
+    queries to verify all rows conform to the FOREIGN KEY constraints and take
+    appropriate actions for the rows that do not conform.</p>
+<p>A query example to return the rows in a foreign key table that
+    have no parent is given below:</p>
+<div class="example">
+<a name="N1396A"></a>
+<p class="title">
+<b>Example&nbsp;11.5.&nbsp;Finding foreign key rows with no parents after a bulk
+      import</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  SELECT * FROM foreign_key_table LEFT OUTER JOIN primary_key_table 
+    ON foreign_key_table.fk_col = primary_key_table.pk_col WHERE primary_key_table.pk_col IS NULL</pre>
+</div>
+</div>
+<br class="example-break">
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13971" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE UNIQUE
+    NAME</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database unique name</em></span><code class="literal">
+    </code>
+</p>
+<p>
+<code class="literal">&lt;set database unique name statement&gt; ::= SET
+    DATABASE UNIQUE NAME &lt;identifier&gt;</code>
+</p>
+<p>Each HyperSQL catalog (database) has an engine-generated internal
+    name. This name is based on the time of creation of the database and is
+    exactly 16 characters. The name is used for in log events sent to external
+    logging frameworks. This name can be changed by an administrator. The new
+    name must be exactly 16 characters long.</p>
+<a name="N13984" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE TRANSACTION
+    CONTROL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database transaction control
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database transaction control statement&gt; ::=
+    SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC
+    }</code>
+</p>
+<p>Set the concurrency control system for the database. It can be
+    issued only when all sessions have been committed or rolled back. This
+    command and its modes is discussed in the <a class="link" href="sqlroutines-chapt.html" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">Sessions and Transactions</a> chapter.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<p>
+<span class="bold"><strong>SET FILES BACKUP INCREMENT
+    </strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files backup increment
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database backup increment statement&gt; ::= SET
+    FILES BACKUP INCREMENT { TRUE | FALSE }</code>
+</p>
+<p>Older versions of HSQLDB perform a backup of the .data file
+    before its contents are modified and the whole .data file is saved in a
+    compressed form when a CHECKPOINT or SHUTDOWN is performed. This takes a
+    long time when the size of the database exceeds 100 MB or so (on an
+    average 2010 computer, you can expect a backup speed of 20MB / s or
+    more).</p>
+<p>The alternative is backup in increments, just before some part of
+    the .data file is modified. In this mode, no backup is performed at
+    CHECKPIONT or SHUTDOWN. This mode is preferred for large databases which
+    are opened and closed frequently.</p>
+<p>The default mode is TRUE. If the old method of backup is
+    preferred, the mode can be set FALSE.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N139AD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES CACHE ROWS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files cache rows statement</em></span><code class="literal">
+    </code>
+</p>
+<p>
+<code class="literal">&lt;set files cache rows statement&gt; ::= SET FILES
+    CACHE ROWS &lt;unsigned integer literal&gt;</code>
+</p>
+<p>Sets the maximum number of rows (of CACHED tables) held in the
+    memory cache.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N139C2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES CACHE SIZE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files cache size statement</em></span><code class="literal">
+    </code>
+</p>
+<p>
+<code class="literal">&lt;set files cache size statement&gt; ::= SET FILES
+    CACHE SIZE &lt;unsigned integer literal&gt;</code>
+</p>
+<p>Sets maximum amount of data (of CACHED tables) in kilobytes held
+    in the memory cache.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N139D7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES DEFRAG</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files defrag statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files defrag statement&gt; ::= SET FILES DEFRAG
+    &lt;unsigned integer literal&gt;</code>
+</p>
+<p>Sets the threshold for performing a DEFRAG during a checkpoint.
+    The <code class="literal">&lt;unsigned integer literal&gt;</code> is the percentage
+    of abandoned space in the <code class="literal">*.data</code> file. When a
+    CHECKPOINT is performed either as a result of the <code class="literal">.log</code>
+    file reaching the limit set by <code class="literal">SET FILES LOG SIZE m</code>, or
+    by the user issuing a CHECKPOINT command, the amount of space abandoned
+    since the database was opened is checked and if it is larger than
+    specified percentage, a CHECKPOINT DEFRAG is performed instead of a
+    CHECKPOINT.</p>
+<p>The default is 0, which indicates no DEFRAG. Useful values are
+    between 10 to 50</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N139F8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES LOG</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files log statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files log statement&gt; ::= SET FILES LOG { TRUE
+    | FALSE }</code>
+</p>
+<p>Sets logging of database operations on or off. Turning logging
+    off is for special usage, such as temporary cache usage.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A0B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES LOG SIZE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files log size statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files log size statement&gt; ::= SET FILES LOG
+    SIZE &lt;unsigned integer literal&gt;</code>
+</p>
+<p>Sets the maximum size in MB of the <code class="literal">*.log</code> file
+    to the specified value. The default maximum size is 50 MB. If the value is
+    zero, no limit is used for the size of the file. When the size of the file
+    reaches this value, a CHECKPOINT is performed and the the
+    <code class="literal">*.log</code> file is cleared to size 0.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A24" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES BACKUP
+    INCREMENT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files backup increment
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files increment backup statement&gt; ::= SET
+    FILES INCREMENT BACKUP { TRUE | FALSE }</code>
+</p>
+<p>This specifies the method for internal backup operation. The
+    default is true.</p>
+<p>During updates, the contents of the .data file is modified. When
+    this property is true, the modified contents are backed up gradually. This
+    causes a marginal slowdown in operations, but allows fast checkpoint and
+    shutdown with large .data files.</p>
+<p>When the property is false, the .data file is backed up entirely
+    at the time of checkpoint and shutdown. Up to version 1.8.0, HSQLDB
+    supported only full backup. Version 1.8.1 supports incremental
+    backup.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A3B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES NIO</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files nio</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files nio statement&gt; ::= SET FILES NIO { TRUE
+    | FALSE }</code>
+</p>
+<p>Changes the access method of the .data file. The default is TRUE
+    and uses the Java nio classes to access the file.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A4E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES WRITE DELAY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files write delay statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files write delay statement&gt; ::= SET FILES
+    WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds
+    value&gt; MILLIS}</code>
+</p>
+<p>Set the WRITE DELAY property of the database. The WRITE DELAY
+    controls the frequency of file sync for the log file. When WRITE_DELAY is
+    set to FALSE or 0, the sync takes place immediately at each COMMIT. WRITE
+    DELAY TRUE performs the sync once every 10 seconds (which is the default).
+    A numeric value can be specified instead.</p>
+<p>The purpose of this command is to control the amount of data loss in
+    case of a total system crash. A delay of 1 second means at most the data
+    written to disk during the last second before the crash is lost. All data
+    written prior to this has been synced and should be recoverable.</p>
+<p>A write delay of 0 impacts performance in high load situations, as
+    the engine has to wait for the file system to catch up.</p>
+<p>To avoid this, you can set write delay down to 10
+    milliseconds.</p>
+<p>Each time the SET FILES WRITE DELAY statement is executed with any
+    value, a sync is immediately performed. Only a user with the DBA role can
+    execute this statement.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A69" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES SCALE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files scale</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files scale statement&gt; ::= SET FILES SCALE
+    &lt;scale value&gt;</code>
+</p>
+<p>Changes the scale factor for the .data file. The default scale is
+    8 and allows 16GB of data storage capacity. The scale can be increased in
+    order to increase the maximum data storage capacity. The scale values 8,
+    16, 32, 64 and 128 are allowed. Scale value 128 allows a maximum capacity
+    of 256GB.</p>
+<p>This command can be used only when there is no data in CACHED
+    tables.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A7E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES LOB SCALE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files lob scale</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files lob scale statement&gt; ::= SET FILES LOB
+    SCALE &lt;scale value&gt;</code>
+</p>
+<p>Changes the scale factor for the .lobs file. The scale is
+    interpreted in kilobytes. The default scale is 32 and allows 64TB of lob
+    data storage capacity. The scale can be reduced in order to improve
+    storage efficiency. If the lobs are a lot smaller than 32 kilobytes,
+    reducing the scale will reduce wasted space. The scale values 1, 2, 4, 8,
+    16, 32 are allowed. For example if the average size of lobs is 4
+    kilobytes, the default scale of 32 will result in 28KB wasted space for
+    each lob. Reducing the lob scale to 2 will result in average 1KB wasted
+    space for each lob.</p>
+<p>This command can be used only when there is no lob in the
+    database.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="builtinfunctions-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="dbproperties-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;10.&nbsp;Built In Functions&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;12.&nbsp;Properties</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/dummy.html b/doc/guide/dummy.html
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/doc/guide/dummy.html
@@ -0,0 +1 @@
+
diff --git a/doc/guide/guide.html b/doc/guide/guide.html
new file mode 100644
index 0000000..f315669
--- /dev/null
+++ b/doc/guide/guide.html
@@ -0,0 +1,24394 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>HyperSQL User Guide</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="book" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="guide"></a>HyperSQL User Guide</h1>
+</div>
+<div>
+<h2 class="subtitle">HyperSQL Database Engine, aka HSQLDB</h2>
+</div>
+<table xmlns:xi="http://www.w3.org/2001/XInclude" class="titlead" cellspacing="0">
+<tr>
+<td>
+<div>
+<div class="authorgroup">
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="orgname">The HSQL Development Group</span>
+</h3>
+</div>
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N1003A"></a>
+<p>Copyright 2002-2010 The HSQL Development Group. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</td><td class="sponsorad">
+<div xml:base="../doc-src/branding-frag.xhtml" class="branding">
+<img src="../images/hypersql_logo.png"></div>
+</td>
+</tr>
+</table>
+</div>
+<hr>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="preface"><a href="#book-pref">Preface</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#altformats-sect">Available formats for this document</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#running-chapt">1. Running and Using HyperSQL</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#running_jar-sect">The HSQLDB Jar</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_tools-sect">Running Database Access Tools</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_db-sect">A HyperSQL Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_inprocess-sect">In-Process Access to Database Catalogs</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_modes-sect">Listener / Server Modes</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#running_hsqlserver-sect">HyperSQL HSQL Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_httpserver-sect">HyperSQL HTTP Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_servlet-sect">HyperSQL HTTP Servlet</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_connecting-sect">Connecting to a Database Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_security-sect">Security Considerations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_multiple_db-sect">Using Multiple Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#running-data-access-sect">Accessing the Data</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_closing-sect">Closing the Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_newdb-sect">Creating a New Database</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#sqlgeneral-chapt">2. SQL Language</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#sqlgeneral_standards-sect">Standards Support</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqlgeneral_tabletypes-sect">SQL Data and Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N1037B">Temporary Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10380">Persistent Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N103A7">Lob Data</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqlgeneral_types_ops-sect">Basic Types and Operations</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N103BA">Numeric Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10482">Boolean Type</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N104A8">Character String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N104D7">Binary String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N104F5">Bit String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1050A">Storage and Handling of Java Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10529">Type Length, Precision and Scale</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N10544">Datetime types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1063D">Interval Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N106BD">Arrays</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N106CA">Array Definition</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N106ED">Array Reference</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10706">Array Operations</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqlgeneral_constr_indexes-sect">Indexes and Query Speed</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1079B">Query Processing and Optimisation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#sessions-chapt">3. Sessions and Transactions</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N107E2">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10801">Session Attributes and Variables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10806">Session Attributes</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10814">Session Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10822">Session Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqlgeneral_trans_cc-sect">Transactions and Concurrency Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10846">Two Phase Locking</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10859">Two Phase Locking with Snapshot Isolation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10862">Lock Contention in 2PL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1086D">MVCC</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1087A">Choosing the Transaction Model</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10887">Schema and Database Change</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10892">Simultaneous Access to Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N10899">Session and Transaction Control Statements</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#databaseobjects-chapt">4. Schemas and Database Objects</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10AC7">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10AD2">Schemas and Schema Objects</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10AF8">Names and References</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B18">Character Sets</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B32">Collations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B3F">Distinct Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B46">Domains</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B4D">Number Sequences</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10BA3">Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10BAF">Views</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10BCD">Constraints</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C26">Assertions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C30">Triggers</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C3E">Routines</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C57">Indexes</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N10C5C">Statements for Schema Definition and Manipulation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10C61">Common Elements and Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10CE1">Renaming Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10D01">Commenting Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10D1D">Schema Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10D6E">Table Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N110DE">View Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1113C">Domain Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N111D1">Trigger Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1124D">Routine Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N112F5">Sequence Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1137F">SQL Procedure Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1139F">Other Schema Object Creation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N114B8">The Information Schema</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N114C3">Predefined Character Sets, Collations and Domains</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N114CE">Views in INFORMATION SCHEMA</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#texttables-chapt">5. Text Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#texttables_overview-sect">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#texttables_impl-sect">The Implementation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N115BF">Definition of Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N115CF">Scope and Reassignment</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N115E5">Null Values in Columns of Text Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N115EF">Configuration</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#disconnecting_text_tables">Disconnecting Text Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#texttables_issues-sect">Text File Usage</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#texttables_globalprops-sect">Text File Global Properties</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N116E4">Transactions</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#accesscontrol-chapt">6. Access Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N11712">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11752">Authorizations and Access Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N11775">Built-In Roles and Users</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N117CE">Access Rights</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N11810">Statements for
+    Authorization and Access Control</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#dataaccess-chapt">7. Data Access and Change</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N1199B">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N119A0">Cursors And Result Sets</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N119BD">Columns and Rows</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N119D8">Navigation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N119EA">Updatability</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A28">Sensitivity</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A31">Holdability</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A44">Autocommit</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A4C">JDBC Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A59">JDBC Parameters</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A68">JDBC Returned Values</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N11A71">Syntax Elements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N11A76">Literals</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11B9C">References, etc.</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11BF8">Value Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11E1B">Predicates</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1205E">Other Syntax Elements</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N12147">Data Access Statements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N1217F">Table</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12199">Query Specification</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N121DF">Table Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12246">Table Primary</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12278">Joined Table</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N122E5">Selection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N122EA">Projection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N122F1">Computed Columns</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N122F6">Naming</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12338">Grouping Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12346">Aggregation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1234D">Set Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12371">Query Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N123B0">Ordering</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N123C8">Slicing</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N123DA">Data Change Statements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N123DD">Delete Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N123FD">Truncate Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1241F">Insert Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1246A">Update Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N124B8">Merge Statement</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#sqlroutines-chapt">8. SQL-Invoked Routines</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N1257C">SQL Language Routines (PSM)</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N12597">Routine Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N125DC">Compound Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N125EE">Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12604">Handlers</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12632">Assignment Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12648">Select Statement : Single Row</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12663">Formal Parameters</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1267E">Iterated Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12699">Conditional Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N126E2">Return Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N126FD">Control Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1271F">Routine Polymorphism</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1272E">Returning Data From Routines</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N12748">Java Language Routines (SQL/JRT)</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N127C5">Polymorphism</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N127D2">Java Language Procedures</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N127EB">Legacy Support</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N127FB">SQL Language Aggregate Functions</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N12802">Definition of Aggregate Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12828">SQL PSM Aggregate Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1283E">Java Aggregate Functions</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N12854">Routine Definition</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N1291D">Routine Characteristics</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#triggers-chapt">9. Triggers</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N12A02">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A26">Trigger Properties</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N12A2B">Trigger Event</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A34">Granularity</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A43">Trigger Action Time</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A50">References to Rows</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A55">Trigger Condition</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A5C">Trigger Action in SQL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A6B">Trigger Action in Java</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N12A85">Trigger Creation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#builtinfunctions-chapt">10. Built In Functions</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#builtin_functions_intro-sect">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#builtin_functions_string-sect">String and Binary String Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#builtin_functions_numeric-sect">Numeric Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N132C8">Array Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N132FD">General Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#builtin_functions_sysfunc-sect">System Functions</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#deployment-chapt">11. System Management and Deployment
+  Issues</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#deploymen_modes-sect">Mode of Operation and Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N13506">Mode of Operation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13525">Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1353A">Large Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1354D">Deployment context</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13559">Readonly Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#deployment_mem_disk-sect">Memory and Disk Use</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N13571">Table Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1357F">Result Set Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13594">Temporary Memory Use During Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135A0">Data Cache Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135BF">Object Pool Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135C7">Lob Memory Usage</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135CC">Disk Space</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#deployment_conns-sect">Managing Database Connections</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135F4">Tweaking the Mode of Operation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N135F9">Application Development and Testing</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1362A">Embedded Databases in Desktop Applications</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13632">Embedded Databases in Server Applications</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13639">Embedding a Database Listener</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1365D">Using HyperSQL Without Logging</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1366B">Server Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#deployment_upgrade-sect">Upgrading Databases</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#upgrade_via_script-sect">Upgrading From Older
+      Versions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N136B7">Manual Changes to the *.script File</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N136FB">Backward Compatibility Issues</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#deployment_backup-sect">Backing Up Database Catalogs</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N13742">Making Online Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13751">Making Offline Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1376E">Examining Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13784">Restoring a Backup</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N1379B">Encrypted Databases</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N137A2">Creating and Accessing an Encrypted Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N137B2">Speed Considerations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N137B7">Security Considerations</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N137C8">Monitoring Database Operations</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N137CD">Statement Level Monitoring</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N137D6">Internal Event Monitoring</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N137E4">Server Operation Monitoring</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N137E9">Statements</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#dbproperties-chapt">12. Properties</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#dbproperties_connections-sect">Connections</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#conn_props-sect">Connection properties</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N13C11">Database Properties in Connection URL and Properties</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#listeners-chapt">13. HyperSQL Network Listeners</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#listeners-sect">Listeners</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#listeners_hsqlserver-sect">HyperSQL Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#listeners_httpserver-sect">HyperSQL HTTP Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#listeners_servlet-sect">HyperSQL HTTP Servlet</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#listeners_server_props-sect">Server and Web Server Properties</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#listeners_appstart-sect">Starting a Server from your application</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N14099">Allowing a Connection to Open a Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#listeners_tls-sect">TLS Encryption</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N140DB">Requirements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N140F8">Encrypting your JDBC connection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#jsse-sect">JSSE</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#privatekey-sect">Making a Private-key Keystore</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N141EB">Automatic Server or WebServer startup on UNIX</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#listeners_acl-sect">Network Access Control</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#unix-chapt">14. HyperSQL on UNIX</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#unix_purpose-sect">Purpose</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_install-sect">Installation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_cat_setup-sect">Setting up Database Catalog and Listener</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_access-sect">Accessing your Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_addl_accts-sect">Create additional Accounts</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_shutdown-sect">Shutdown</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_daemon-sect">Running Hsqldb as a System Daemon</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N144B8">Portability of hsqldb init script</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N144C2">Init script Setup Procedure</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_inittrouble-sect">Troubleshooting the Init
+      Script</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#unix_upgrade-sect">Upgrading</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="#lists-app">A. Lists of Keywords</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N14607">List of SQL Standard Keywords</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1463A">List of SQL Keywords Disallowed as HyperSQL Identifiers</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="#building-app">B. Building HyperSQL Jars</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N14693">Purpose</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#building-ant-sect">Building with Ant</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N146AA">Obtaining Ant</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N146C0">Building Hsqldb with Ant</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1475D">Building for Older JDKs</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N14765">Building with IDE's</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1476A">Hsqldb CodeSwitcher</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N14791">Building documentation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="#openoffice-app">C. HyperSQL with OpenOffice.org</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N147C8">HyperSQL with OpenOffice.org</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N147CF">Using OpenOffice.org as a Database Tool</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N147DE">Converting .odb files to use with HyperSQL Server</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="#N147E4">D. HyperSQL File Links</a></span>
+</dt>
+<dt>
+<span class="index"><a href="#sql-ind">SQL Index</a></span>
+</dt>
+<dt>
+<span class="index"><a href="#book-ind">General Index</a></span>
+</dt>
+</dl>
+</div>
+<div class="list-of-tables">
+<p>
+<b>List of Tables</b>
+</p>
+<dl>
+<dt>1. <a href="#altformats-tbl">Available formats of this document</a>
+</dt>
+<dt>10.1. <a href="#N13216">TO CHAR Values</a>
+</dt>
+<dt>12.1. <a href="#N13AD2">HyperSQL URL Components</a>
+</dt>
+<dt>12.2. <a href="#N13B9C">Connection Properties</a>
+</dt>
+<dt>12.3. <a href="#N13C26">Database-specific Property File Properties</a>
+</dt>
+<dt>13.1. <a href="#N13F59">common server and webserver properties</a>
+</dt>
+<dt>13.2. <a href="#N13FED">server properties</a>
+</dt>
+<dt>13.3. <a href="#N1401F">webserver properties</a>
+</dt>
+</dl>
+</div>
+<div class="list-of-examples">
+<p>
+<b>List of Examples</b>
+</p>
+<dl>
+<dt>1.1. <a href="#N1021A">Java code to connect to the local hsql Server</a>
+</dt>
+<dt>1.2. <a href="#N10224">Java code to connect to the local http Server</a>
+</dt>
+<dt>1.3. <a href="#N10248">Java code to connect to the local secure SSL hsql and http
+          Servers</a>
+</dt>
+<dt>1.4. <a href="#N102EF">specifying a connection property to shutdown the database when
+        the last connection is closed</a>
+</dt>
+<dt>1.5. <a href="#N1030C">specifying a connection property to disallow creating a new
+        database</a>
+</dt>
+<dt>3.1. <a href="#N1081D">User-defined Session Variables</a>
+</dt>
+<dt>3.2. <a href="#N10831">User-defined Temporary Session Tables</a>
+</dt>
+<dt>3.3. <a href="#N1090A">Setting Transaction Characteristics</a>
+</dt>
+<dt>3.4. <a href="#N10934">Locking Tables</a>
+</dt>
+<dt>3.5. <a href="#N10997">Rollback</a>
+</dt>
+<dt>3.6. <a href="#N109C9">Setting Session Characteristics</a>
+</dt>
+<dt>3.7. <a href="#N109DF">Setting Session Authorization</a>
+</dt>
+<dt>3.8. <a href="#N10A0C">Setting Session Time Zone</a>
+</dt>
+<dt>4.1. <a href="#N10B67">inserting the next sequence value into a table row</a>
+</dt>
+<dt>4.2. <a href="#N10B6E">numbering returned rows of a SELECT in sequential order</a>
+</dt>
+<dt>4.3. <a href="#N10BF2">Column values which satisfy a 2-column UNIQUE
+        constraint</a>
+</dt>
+<dt>11.1. <a href="#N13644">MainInvoker Example</a>
+</dt>
+<dt>11.2. <a href="#N13756">Offline Backup Example</a>
+</dt>
+<dt>11.3. <a href="#N13776">Listing a Backup with DbBackup</a>
+</dt>
+<dt>11.4. <a href="#N1378C">Restoring a Backup with DbBackup</a>
+</dt>
+<dt>11.5. <a href="#N1396A">Finding foreign key rows with no parents after a bulk
+      import</a>
+</dt>
+<dt>13.1. <a href="#N14118">Exporting certificate from the server's keystore</a>
+</dt>
+<dt>13.2. <a href="#N1412A">Adding a certificate to the client keystore</a>
+</dt>
+<dt>13.3. <a href="#N1413E">Specifying your own trust store to a JDBC client</a>
+</dt>
+<dt>13.4. <a href="#N141CA">Getting a pem-style private key into a JKS keystore</a>
+</dt>
+<dt>13.5. <a href="#N14251">Validating and Testing an ACL file</a>
+</dt>
+<dt>14.1. <a href="#N14517">example sqltool.rc stanza</a>
+</dt>
+<dt>B.1. <a href="#N14756">Buiding the standard Hsqldb jar file with Ant</a>
+</dt>
+<dt>B.2. <a href="#N14773">Example source code before CodeSwitcher is run</a>
+</dt>
+<dt>B.3. <a href="#N1477A">CodeSwitcher command line invocation</a>
+</dt>
+<dt>B.4. <a href="#N14784">Source code after CodeSwitcher processing</a>
+</dt>
+</dl>
+</div>
+<div class="preface" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="book-pref"></a>Preface</h2>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#altformats-sect">Available formats for this document</a></span>
+</dt>
+</dl>
+</div>
+<p>HSQLDB (HyperSQL DataBase) is a modern relational database manager
+    that conforms closely to the SQL:2008 Standard and JDBC 4 specifications.
+    It supports all core features and many of the optional features of
+    SQL:2008.</p>
+<p>The first versions of HSQLDB were released in 2001. Version 2.0,
+    first released in 2010, includes a complete rewrite of most parts of the
+    database engine.</p>
+<p>This documentation covers HyperSQL version 2.0. This documentation
+    is regularly improved and undated. The latest, updated version can be
+    found at http://hsqldb.org/doc/2.0/</p>
+<p>If you notice any mistakes in this document, or if you have problems
+    with the procedures themselves, please use the HSQLDB support facilities
+    which are listed at http://hsqldb.org/support</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="altformats-sect"></a>Available formats for this document</h2>
+</div>
+</div>
+</div>
+<p>This document is available in several formats.</p>
+<p>
+      You may be reading this document right now at http://hsqldb.org/doc/2.0, or in
+      a distribution somewhere else.
+      I hereby call the document distribution from which you are reading 
+      this, your <span class="emphasis"><em>current distro</em></span>.
+  </p>
+<p>
+      http://hsqldb.org/doc/2.0 hosts the latest production versions of all available formats.
+      If you want a different format of the same <span class="emphasis"><em>version</em></span>
+      of the document you are reading now, then you should try your
+      current distro.
+      If you want the latest production version, you should try http://hsqldb.org/doc/2.0.
+  </p>
+<p>
+      Sometimes, distributions other than http://hsqldb.org/doc/2.0 do not host all
+      available formats.
+      So, if you can't access the format that you want in your current
+      distro, you have no choice but to use the newest production version at 
+      http://hsqldb.org/doc/2.0.
+  </p>
+<p>
+    
+<div class="table">
+<a name="altformats-tbl"></a>
+<p class="title">
+<b>Table&nbsp;1.&nbsp;Available formats of this document</b>
+</p>
+<div class="table-contents">
+<table summary="Available formats of this document" cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">format</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">your distro</th><th style="border-bottom: 0.5pt solid ; " align="left">at http://hsqldb.org/doc/2.0</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              Chunked HTML
+          </td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              <a class="link" href="index.html" target="_top">index.html</a>
+          </td><td style="border-bottom: 0.5pt solid ; " align="left">
+          <a class="link" href="http://hsqldb.org/doc/2.0/guide/" target="_top">http://hsqldb.org/doc/2.0/guide/</a>
+          </td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              All-in-one HTML
+          </td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              <a class="link" href="guide.html" target="_top">guide.html</a>
+          </td><td style="border-bottom: 0.5pt solid ; " align="left">
+        <a class="link" href="http://hsqldb.org/doc/2.0/guide/guide.html" target="_top">http://hsqldb.org/doc/2.0/guide/guide.html</a>
+          </td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left">
+              PDF
+          </td><td style="border-right: 0.5pt solid ; " align="left">
+              <a class="link" href="guide.pdf" target="_top">guide.pdf</a>
+          </td><td style="" align="left">
+          <a class="link" href="http://hsqldb.org/doc/2.0/guide/guide.pdf" target="_top">http://hsqldb.org/doc/2.0/guide/guide.pdf</a>
+          </td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+    If you are reading this document now with a standalone PDF reader, the
+    <span class="guilabel">your distro</span> links may not work.
+  </p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="running-chapt"></a>Chapter&nbsp;1.&nbsp;Running and Using HyperSQL</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N100CC"></a>
+<p>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#running_jar-sect">The HSQLDB Jar</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_tools-sect">Running Database Access Tools</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_db-sect">A HyperSQL Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_inprocess-sect">In-Process Access to Database Catalogs</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_modes-sect">Listener / Server Modes</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#running_hsqlserver-sect">HyperSQL HSQL Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_httpserver-sect">HyperSQL HTTP Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_servlet-sect">HyperSQL HTTP Servlet</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_connecting-sect">Connecting to a Database Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_security-sect">Security Considerations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_multiple_db-sect">Using Multiple Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#running-data-access-sect">Accessing the Data</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_closing-sect">Closing the Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#running_newdb-sect">Creating a New Database</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_jar-sect"></a>The HSQLDB Jar</h2>
+</div>
+</div>
+</div>
+<p>The HSQLDB jar package is located in the /lib directory of the ZIP
+    package and contains several components and programs.</p>
+<div class="itemizedlist">
+<p class="title">
+<b>Components of the Hsqldb jar package</b>
+</p>
+<ul type="disc">
+<li>
+<p>HyperSQL RDBMS Engine (HSQLDB)</p>
+</li>
+<li>
+<p>HyperSQL JDBC Driver</p>
+</li>
+<li>
+<p>Database Manager (GUI database access tool, with Swing and AWT
+        versions)</p>
+</li>
+<li>
+<p>Sql Tool (command line database access tool)</p>
+</li>
+</ul>
+</div>
+<p>The HyperSQL RDBMS and JDBC Driver provide the core functionality.
+    An additional jar contains Sql Tool (command line database access tool).
+    SqlTool and the DatabaseManagers are general-purpose database tools that
+    can be used with any database engine that has a JDBC driver.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_tools-sect"></a>Running Database Access Tools</h2>
+</div>
+</div>
+</div>
+<p>The tools are used for interactive user access to databases,
+    including creation of a database, inserting or modifying data, or querying
+    the database. All tools are run in the normal way for Java programs. In
+    the following example the Swing version of the Database Manager is
+    executed. The <code class="filename">hsqldb.jar</code> is located in the directory
+    <code class="filename">../lib</code> relative to the current directory.</p>
+<pre class="screen">java -cp ../lib/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing</pre>
+<p>If <code class="filename">hsqldb.jar</code> is in the current directory, the
+    command would change to:</p>
+<pre class="screen">java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing</pre>
+<div class="itemizedlist">
+<p class="title">
+<b>Main classes for the Hsqldb tools</b>
+</p>
+<ul type="disc">
+<li>
+<p>
+<code class="classname">org.hsqldb.util.DatabaseManager</code>
+</p>
+</li>
+<li>
+<p>
+<code class="classname">org.hsqldb.util.DatabaseManagerSwing</code>
+</p>
+</li>
+</ul>
+</div>
+<p>When a tool is up and running, you can connect to a database (may be
+    a new database) and use SQL commands to access and modify the data.</p>
+<p>Tools can use command line arguments. You can add the command line
+    argument --help to get a list of available arguments for these
+    tools.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_db-sect"></a>A HyperSQL Database</h2>
+</div>
+</div>
+</div>
+<p>Each HyperSQL database is called a catalog. There are three types of
+    catalog depending on how the data is stored.</p>
+<div class="itemizedlist">
+<p class="title">
+<b>Types of catalog data</b>
+</p>
+<ul type="disc">
+<li>
+<p>
+<em class="glossterm">mem:</em> stored entirely in RAM - without any
+        persistence beyond the JVM process's life</p>
+</li>
+<li>
+<p>
+<em class="glossterm">file:</em> stored in filesystem files</p>
+</li>
+<li>
+<p>
+<em class="glossterm">res:</em> stored in a Java resource, such as a
+        Jar and always read-only</p>
+</li>
+</ul>
+</div>
+<p>All-in-memory, <em class="glossterm">mem:</em> catalogs can be used for
+    test data or as sophisticated caches for an application. These databases
+    do not have any files.</p>
+<p>A <em class="glossterm">file</em>: catalog consists of between 2 to 5
+    files, all named the same but with different extensions, located in the
+    same directory. For example, the database named "test" consists of the
+    following files:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>
+<code class="filename">test.properties</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.script</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.log</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.data</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.backup</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.lobs</code>
+</p>
+</li>
+</ul>
+</div>
+<p>The properties file contains a few settings about the database. The
+    script file contains the definition of tables and other database objects,
+    plus the data for non-cached tables. The log file contains recent changes
+    to the database. The data file contains the data for cached tables and the
+    backup file is a compressed backup of the last known consistent state of
+    the data file. All these files are essential and should never be deleted.
+    For some catalogs, the <code class="filename">test.data</code> and
+    <code class="filename">test.backup</code> files will not be present. In addition to
+    those files, a HyperSQL database may link to any formatted text files,
+    such as CSV lists, anywhere on the disk.</p>
+<p>While the "test" catalog is open, a <code class="filename">test.log</code>
+    file is used to write the changes made to data. This file is removed at a
+    normal SHUTDOWN. Otherwise (with abnormal shutdown) this file is used at
+    the next startup to redo the changes. A <code class="filename">test.lck </code>file
+    is also used to record the fact that the database is open. This is deleted
+    at a normal SHUTDOWN.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>When the engine closes the database at a shutdown, it creates
+      temporary files with the extension <code class="literal">.new</code> which it then
+      renames to those listed above. In some circumstances, a
+      <code class="filename">test.data.old</code> is created and deleted afterwards.
+      These files should not be deleted by the user. At the time of the next
+      startup, all such files will be deleted by the database engine.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>A <em class="glossterm">res:</em> catalog consists of the files for a
+    small, read-only database that can be stored inside a Java resource such
+    as a ZIP or JAR archive and distributed as part of a Java application
+    program.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_inprocess-sect"></a>In-Process Access to Database Catalogs</h2>
+</div>
+</div>
+</div>
+<p>In general, JDBC is used for all access to databases. This is done
+    by making a connection to the database, then using various methods of the
+    <code class="classname">java.sql.Connection</code> object that is returned to
+    access the data. Access to an <em class="glossterm">in-process</em> database
+    is started from JDBC, with the database path specified in the connection
+    URL. For example, if the <em class="glossterm">file: </em>database name is
+    "testdb" and its files are located in the same directory as where the
+    command to run your application was issued, the following code is used for
+    the connection:</p>
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:file:testdb", "SA", "");</pre>
+<p>The database file path format can be specified using forward slashes
+    in Windows hosts as well as Linux hosts. So relative paths or paths that
+    refer to the same directory on the same drive can be identical. For
+    example if your database path in Linux is
+    <code class="filename">/opt/db/testdb</code> and you create an identical directory
+    structure on the <code class="literal">C:</code> drive of a Windows host, you can
+    use the same URL in both Windows and Linux:</p>
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");</pre>
+<p>When using relative paths, these paths will be taken relative to the
+    directory in which the shell command to start the Java Virtual Machine was
+    executed. Refer to the Javadoc for <code class="classname"><a class="classname" href="#JDBCConnection.html-link">JDBCConnection</a></code> for more
+    details.</p>
+<p>Paths and database names for file databases are treated as
+    case-sensitive when the database is created or the first connection is
+    made to the database. But if a second connection is made to an open
+    database, using a path and name that differs only in case, then the
+    connection is made to the existing open database. This measure is
+    necessary because in Windows the two paths are equivalent.</p>
+<p>A <em class="glossterm">mem:</em> database is specified by the
+    <em class="glossterm">mem:</em> protocol. For <em class="glossterm">mem:</em>
+    databases, the path is simply a name. Several <em class="glossterm">mem:</em>
+    databases can exist at the same time and distinguished by their names. In
+    the example below, the database is called "mymemdb":</p>
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "SA", "");</pre>
+<p>A <em class="glossterm">res:</em> database, is specified by the
+    <em class="glossterm">res:</em> protocol. As it is a Java resource, the
+    database path is a Java URL (similar to the path to a class). In the
+    example below, "resdb" is the root name of the database files, which
+    exists in the directory "org/my/path" within the classpath (probably in a
+    Jar). A Java resource is stored in a compressed format and is decompressed
+    in memory when it is used. For this reason, a <em class="glossterm">res:</em>
+    database should not contain large amounts of data and is always
+    read-only.</p>
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:res:org.my.path.resdb", "SA", "");</pre>
+<p>The first time <em class="glossterm">in-process</em> connection is made
+    to a database, some general data structures are initialised and a few
+    helper threads are started. After this, creation of connections and calls
+    to JDBC methods of the connections execute as if they are part of the Java
+    application that is making the calls. When the SQL command "SHUTDOWN" is
+    executed, the global structures and helper threads for the database are
+    destroyed.</p>
+<p>Note that only one Java process at a time can make
+    <em class="glossterm">in-process</em> connections to a given
+    <em class="glossterm">file:</em> database. However, if the
+    <em class="glossterm">file:</em> database has been made read-only, or if
+    connections are made to a <em class="glossterm">res:</em> database, then it is
+    possible to make <em class="glossterm">in-process</em> connections from
+    multiple Java processes.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_modes-sect"></a>Listener / Server Modes</h2>
+</div>
+</div>
+</div>
+<p>For most applications, <em class="glossterm">in-process</em> access is
+    faster, as the data is not converted and sent over the network. The main
+    drawback is that it is not possible by default to connect to the database
+    from outside your application. As a result you cannot check the contents
+    of the database with external tools such as Database Manager while your
+    application is running.</p>
+<p>Server modes provide the maximum accessibility. The database engine
+    runs in a JVM and opens one or more <em class="glossterm">in-process</em>
+    catalogs. It listens for connections from programs on the same computer or
+    other computers on the network. It translates these connections into
+    <em class="glossterm">in-process</em> connections to the databases.</p>
+<p>Several different programs can connect to the server and retrieve or
+    update information. Applications programs (clients) connect to the server
+    using the HyperSQL JDBC driver. In most server modes, the server can serve
+    an unlimited number of databases that are specified at the time of running
+    the server, or optionally, as a connection request is received.</p>
+<p>A Sever mode is also the prefered mode of running the database
+    during development. It allows you to query the database from a separate
+    database access utility while your application is running.</p>
+<p>There are three server modes, based on the protocol used for
+    communications between the client and server. They are briefly discussed
+    below. More details on servers is provided in the <a class="link" href="#listeners-chapt" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">HyperSQL Network Listeners</a> chapter.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_hsqlserver-sect"></a>HyperSQL HSQL Server</h3>
+</div>
+</div>
+</div>
+<p>This is the preferred way of running a database server and the
+      fastest one. A proprietary communications protocol is used for this
+      mode. A command similar to those used for running tools and described
+      above is used for running the server. The following example of the
+      command for starting the server starts the server with one (default)
+      database with files named "mydb.*" and the public name of "xdb". The
+      public name hides the file names from users.</p>
+<div class="informalexample">
+<pre class="screen">  java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb</pre>
+</div>
+<p>The command line argument <code class="literal">--help</code> can be used to
+      get a list of available arguments.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_httpserver-sect"></a>HyperSQL HTTP Server</h3>
+</div>
+</div>
+</div>
+<p>This method of access is used when the computer hosting the
+      database server is restricted to the HTTP protocol. The only reason for
+      using this method of access is restrictions imposed by firewalls on the
+      client or server machines and it should not be used where there are no
+      such restrictions. The HyperSQL HTTP Server is a special web server that
+      allows JDBC clients to connect via HTTP. The server can also act as a
+      small general-purpose web server for static pages.</p>
+<p>To run an HTTP server, replace the main class for the server in
+      the example command line above with the following:</p>
+<div class="informalexample">
+<pre class="screen">  org.hsqldb.server.WebServer</pre>
+</div>
+<p>The command line argument <code class="literal">--help</code> can be used to
+      get a list of available arguments.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_servlet-sect"></a>HyperSQL HTTP Servlet</h3>
+</div>
+</div>
+</div>
+<p>This method of access also uses the HTTP protocol. It is used when
+      a separate servlet engine (or application server) such as Tomcat or
+      Resin provides access to the database. The Servlet Mode cannot be
+      started independently from the servlet engine. The
+      <code class="filename">Servlet</code> class, in the HSQLDB jar, should be
+      installed on the application server to provide the connection. The
+      database is specified using an application server property. Refer to the
+      source file <code class="filename"><a class="filename" href="#Servlet.java-link">
+      src/org/hsqldb/server/Servlet.java</a></code> to see the details.</p>
+<p>Both HTTP Server and Servlet modes can only be accessed using the
+      JDBC driver at the client end. They do not provide a web front end to
+      the database. The Servlet mode can serve only a single database.</p>
+<p>Please note that you do not normally use this mode if you are
+      using the database engine in an application server. In this situation,
+      connections to a catalog are usually made
+      <em class="glossterm">in-process</em>, or using a separate Server</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_connecting-sect"></a>Connecting to a Database Server</h3>
+</div>
+</div>
+</div>
+<p>When a HyperSQL server is running, client programs can connect to
+      it using the HSQLDB JDBC Driver contained in
+      <code class="filename">hsqldb.jar</code>. Full information on how to connect to a
+      server is provided in the Java Documentation for <code class="classname"><a class="classname" href="#JDBCConnection.html-link"> JDBCConnection</a></code>
+      (located in the <code class="filename">/doc/apidocs</code> directory of HSQLDB
+      distribution). A common example is connection to the default port (9001)
+      used for the <em class="glossterm">hsql:</em> protocol on the same
+      machine:</p>
+<div class="example">
+<a name="N1021A"></a>
+<p class="title">
+<b>Example&nbsp;1.1.&nbsp;Java code to connect to the local hsql Server</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  try {
+      Class.forName("org.hsqldb.jdbc.JDBCDriver" );
+  } catch (Exception e) {
+      System.err.println("ERROR: failed to load HSQLDB JDBC driver.");
+      e.printStackTrace();
+      return;
+  }
+
+  Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb", "SA", "");</pre>
+</div>
+</div>
+<br class="example-break">
+<p>If the HyperSQL HTTP server is used, the protocol is
+      <em class="glossterm">http:</em> and the URL will be different:</p>
+<div class="example">
+<a name="N10224"></a>
+<p class="title">
+<b>Example&nbsp;1.2.&nbsp;Java code to connect to the local http Server</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:http://localhost/xdb", "SA", "");</pre>
+</div>
+</div>
+<br class="example-break">
+<p>Note in the above connection URL, there is no mention of the
+      database file, as this was specified when running the server. Instead,
+      the public name defined for dbname.0 is used. Also, see the <a class="link" href="#listeners-chapt" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">HyperSQL Network Listeners</a> chapter
+      for the connection URL when there is more than one database per server
+      instance.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_security-sect"></a>Security Considerations</h3>
+</div>
+</div>
+</div>
+<a name="N10233" class="indexterm"></a>
+<p>When a HyperSQL server is run, network access should be adequately
+      protected. Source IP addresses may be restricted by use of our <a class="link" href="#listeners_acl-sect" title="Network Access Control">Access Control List feature</a>,
+      network filtering software, firewall software, or standalone firewalls.
+      Only secure passwords should be used-- most importantly, the password
+      for the default system user should be changed from the default empty
+      string. If you are purposefully providing data to the public, then the
+      wide-open public network connection should be used exclusively to access
+      the public data via read-only accounts. (i.e., neither secure data nor
+      privileged accounts should use this connection). These considerations
+      also apply to HyperSQL servers run with the HTTP protocol.</p>
+<p>HyperSQL provides two optional security mechanisms. The <a class="link" href="#listeners_tls-sect" title="TLS Encryption">encrypted SSL protocol</a>, and
+      <a class="link" href="#listeners_acl-sect" title="Network Access Control">Access Control Lists</a>. Both
+      mechanisms can be specified when running the Server or WebServer. From
+      the client, the URL's co connect to an SSL server is slightly
+      different:</p>
+<p>
+<div class="example">
+<a name="N10248"></a>
+<p class="title">
+<b>Example&nbsp;1.3.&nbsp;Java code to connect to the local secure SSL hsql and http
+          Servers</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:hsqls://localhost/xdb", "SA", "");
+  Connection c = DriverManager.getConnection("jdbc:hsqldb:https://localhost/xdb", "SA", "");
+</pre>
+</div>
+</div>
+<br class="example-break">The security features are discussed in detail in the <a class="link" href="#listeners-chapt" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">listeners</a>
+      chapter.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_multiple_db-sect"></a>Using Multiple Databases</h3>
+</div>
+</div>
+</div>
+<p>A server can provide connections to more than one database. In the
+      examples above, more than one set of database names can be specified on
+      the command line. It is also possible to specify all the databases in a
+      <code class="literal">.properties</code> file, instead of the command line. These
+      capabilities are covered in the <a class="link" href="#listeners-chapt" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">HyperSQL Network Listeners</a> chapter</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running-data-access-sect"></a>Accessing the Data</h2>
+</div>
+</div>
+</div>
+<p>As shown so far, a <code class="classname">java.sql.Connection</code> object
+    is always used to access the database. But the speed and performance
+    depends on the type of connection.</p>
+<p>Establishing a connection and closing it has some overheads,
+    therefore it is not good practice to create a new connection to perform a
+    small number of operations. A connection should be reused as much as
+    possible and closed only when it is not going to be used again for a long
+    while.</p>
+<p>Reuse is more important for server connections. A server connection
+    uses a TCP port for communications. Each time a connection is made, a port
+    is allocated by the operating system and deallocated after the connection
+    is closed. If many connections are made from a single client, the
+    operating system may not be able to keep up and may refuse the connection
+    attempt.</p>
+<p>A <code class="classname">java.sql.Connection</code> object has some methods
+    that return further <code class="classname">java.sql.*</code> objects. All these
+    objects belong to the connection that returned them and are closed when
+    the connection is closed. These objects can be reused, but if they are not
+    needed after performing the operations, they should be closed.</p>
+<p>A <code class="classname">java.sql.DatabaseMetaData</code> object is used to
+    get metadata for the database.</p>
+<p>A <code class="classname">java.sql.Statement</code> object is used to
+    execute queries and data change statements. A
+    <code class="classname">java.sql.Statement</code> can be reused to execute a
+    different statement each time.</p>
+<p>A <code class="classname">java.sql.PreparedStatement</code> object is used
+    to execute a single statement repeatedly. The SQL statement usually
+    contains parameters, which can be set to new values before each reuse.
+    When a <code class="classname">java.sql.PreparedStatement</code> object is
+    created, the engine keeps the compiled SQL statement for reuse, until the
+    <code class="classname">java.sql.PreparedStatement</code> object is closed. As a
+    result, repeated use of a
+    <code class="classname">java.sql.PreparedStatement</code> is much faster than
+    using a <code class="classname">java.sql.Statement</code> object.</p>
+<p>A <code class="classname">java.sql.CallableStatement</code> object is used
+    to execute an SQL CALL statement. The SQL CALL statement may contain
+    parameters, which should be set to new values before each reuse. Similar
+    to <code class="classname">java.sql.PreparedStatement</code>, the engine keeps the
+    compiled SQL statement for reuse, until the
+    <code class="classname">java.sql.CallableStatement</code> object is closed.</p>
+<p>A <code class="classname">java.sql.Connection</code> object also has some
+    methods for transaction control.</p>
+<p>The <code class="methodname">commit()</code> method performs a
+    <code class="literal">COMMIT</code> while the <code class="methodname">rollback()</code>
+    method performs a <code class="literal">ROLLBACK</code> SQL statement.</p>
+<p>The <code class="methodname">setSavepoint(String name)</code> method
+    performs a <code class="literal">SAVEPOINT &lt;name&gt;</code> SQL statement and
+    returns a <code class="classname">java.sql.Savepoint</code> object. The
+    <code class="methodname">rollback(Savepoint name)</code> method performs a
+    <code class="literal">ROLLBACK TO SAVEPOINT &lt;name&gt;</code> SQL
+    statement.</p>
+<p>The Javadoc for <code class="classname"><a class="classname" href="#JDBCConnection.html-link">
+    JDBCConnection</a></code>, <code class="classname"><a class="classname" href="#JDBCDriver.html-link">
+    JDBCDriver</a></code>, <code class="classname"><a class="classname" href="#JDBCDatabaseMetaData.html-link">
+    JDBCDatabaseMetadata</a></code> <code class="classname"><a class="classname" href="#JDBCResultSet.html-link"> JDBCResultSet</a></code>,
+    <code class="classname"><a class="classname" href="#JDBCStatement.html-link">
+    JDBCStatement</a></code>, <code class="classname"><a class="classname" href="#JDBCPreparedStatement.html-link">
+    JDBCPreparedStatement</a></code> list all the supported JDBC methods
+    together with information that is specific to HSQLDB.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_closing-sect"></a>Closing the Database</h2>
+</div>
+</div>
+</div>
+<p>All databases running in different modes can be closed with the
+    SHUTDOWN command, issued as an SQL statement.</p>
+<p>When SHUTDOWN is issued, all active transactions are rolled back.
+    The catalog files are then saved in a form that can be opened quickly the
+    next time the catalog is opened.</p>
+<p>A special form of closing the database is via the SHUTDOWN COMPACT
+    command. This command rewrites the <code class="literal">.data</code> file that
+    contains the information stored in CACHED tables and compacts it to its
+    minimum size. This command should be issued periodically, especially when
+    lots of inserts, updates or deletes have been performed on the cached
+    tables. Changes to the structure of the database, such as dropping or
+    modifying populated CACHED tables or indexes also create large amounts of
+    unused file space that can be reclaimed using this command.</p>
+<p>Databases are not closed when the last connection to the database is
+    explicitly closed via JDBC. A connection property,
+    <code class="literal">shutdown=true</code>, can be specified on the first connection
+    to the database (the connection that opens the database) to force a
+    shutdown when the last connection closes.</p>
+<p>
+<div class="example">
+<a name="N102EF"></a>
+<p class="title">
+<b>Example&nbsp;1.4.&nbsp;specifying a connection property to shutdown the database when
+        the last connection is closed</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  Connection c = DriverManager.getConnection(
+          "jdbc:hsqldb:file:/opt/db/testdb;shutdown=true", "SA", "");</pre>
+</div>
+</div>
+<br class="example-break">This feature is useful for running tests, where it may not be
+    practical to shutdown the database after each test. But it is not
+    recommended for application programs.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_newdb-sect"></a>Creating a New Database</h2>
+</div>
+</div>
+</div>
+<p>When a server instance is started, or when a connection is made to
+    an <em class="glossterm">in-process</em> database, a new, empty database is
+    created if no database exists at the given path.</p>
+<p>With HyperSQL 2.0 the username and password that are specified for
+    the connection are used for the new database. Both the username and
+    password are case-sensitive. (The exception is the default SA user, which
+    is not case-sensitive). If no username or password is specified, the
+    default SA user and an empty password are used.</p>
+<p>This feature has a side effect that can confuse new users. If a
+    mistake is made in specifying the path for connecting to an existing
+    database, a connection is nevertheless established to a new database. For
+    troubleshooting purposes, you can specify a connection property
+    <span class="property">ifexists</span>=<code class="literal">true</code> to allow connection
+    to an existing database only and avoid creating a new database. In this
+    case, if the database does not exist, the
+    <code class="methodname">getConnection()</code> method will throw an
+    exception.</p>
+<p>
+<div class="example">
+<a name="N1030C"></a>
+<p class="title">
+<b>Example&nbsp;1.5.&nbsp;specifying a connection property to disallow creating a new
+        database</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  Connection c = DriverManager.getConnection(
+          "jdbc:hsqldb:file:/opt/db/testdb;ifexists=true", "SA", "");</pre>
+</div>
+</div>
+<br class="example-break">
+</p>
+<p>A database has many optional properties, described in the <a class="link" href="#deployment-chapt" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">System Management and Deployment
+  Issues</a> chapter. You can specify most of
+    these properties on the URL or in the connection properties for the first
+    connection that creates the database. See the <a class="link" href="#deployment-chapt" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">Properties</a> chapter.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sqlgeneral-chapt"></a>Chapter&nbsp;2.&nbsp;SQL Language</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N10343"></a>
+<p>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#sqlgeneral_standards-sect">Standards Support</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqlgeneral_tabletypes-sect">SQL Data and Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N1037B">Temporary Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10380">Persistent Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N103A7">Lob Data</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqlgeneral_types_ops-sect">Basic Types and Operations</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N103BA">Numeric Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10482">Boolean Type</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N104A8">Character String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N104D7">Binary String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N104F5">Bit String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1050A">Storage and Handling of Java Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10529">Type Length, Precision and Scale</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N10544">Datetime types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1063D">Interval Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N106BD">Arrays</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N106CA">Array Definition</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N106ED">Array Reference</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10706">Array Operations</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqlgeneral_constr_indexes-sect">Indexes and Query Speed</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1079B">Query Processing and Optimisation</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_standards-sect"></a>Standards Support</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL 2.0 supports the dialect of SQL defined by SQL standards
+    92, 1999, 2003 and 2008. This means where a feature of the standard is
+    supported, e.g. left outer join, the syntax is that specified by the
+    standard text. Almost all syntactic features of SQL-92 up to Advanced
+    Level are supported, as well as SQL:2008 core and many optional features
+    of this standard. Work is in progress for a formal declaration of
+    conformance.</p>
+<p>At the time of this release, HyperSQL supports the widest range of
+    SQL standard features among all open source RDBMS.</p>
+<p>Various chapters of this guide list the supported syntax. When
+    writing or converting existing SQL DDL (Data Definition Language), DML
+    (Data Manipulation Language) or DQL (Data Query Language) statements for
+    HSQLDB, you should consult the supported syntax and modify the statements
+    accordingly. Some statements written for older versions may have to be
+    modified.</p>
+<p>Over 300 words are reserved by the standard and should not be used
+    as table or column names. For example, the word POSITION is reserved as it
+    is a function defined by the Standards with a similar role as
+    <code class="methodname">String.indexOf()</code> in Java. HyperSQL does not
+    currently prevent you from using a reserved word if it does not support
+    its use or can distinguish it. For example CUBE is a reserved words that
+    is not currently supported by HyperSQL and is allowed as a table or column
+    name. You should avoid using such names as future versions of HyperSQL are
+    likely to support the reserved words and may reject your table definitions
+    or queries. The full list of SQL reserved words is in the appendix <a class="link" href="#lists-app" title="Appendix&nbsp;A.&nbsp;Lists of Keywords">Lists of Keywords</a> .</p>
+<p>If you have to use a reserved keyword as the name of a database
+    object, you can enclose it in double quotes.</p>
+<p>HyperSQL also supports enhancements with keywords and expressions
+    that are not part of the SQL standard. Expressions such as <code class="literal">SELECT
+    TOP 5 FROM ..</code>, <code class="literal">SELECT LIMIT 0 10 FROM ...</code> or
+    <code class="literal">DROP TABLE mytable IF EXISTS</code> are among such
+    constructs.</p>
+<p>Many print books cover SQL Standard syntax and can be consulted. For
+    a well-written basic guide to SQL with examples, you can also consult
+    <a class="link" href="http://www.postgresql.org/files/documentation/books/aw_pgsql/index.html" target="_top">PostgreSQL:
+    Introduction and Concepts</a> by Bruce Momjian, which is available on
+    the web. Most of the core SQL coverage in the book applies also to
+    HyperSQL. There are some differences in keywords supported by one and not
+    the other engine (OUTER, OID's, etc.) or used differently
+    (IDENTITY/SERIAL, TRIGGER, SEQUENCE, etc.).</p>
+<p>In HyperSQL version 2.0, all features of JDBC4 that apply to the
+    capabilities of HSQLDB are fully supported. The relevant JDBC classes are
+    thoroughly documented with additional clarifications and HyperSQL specific
+    comments. See the <a class="link" href="#javadoc-link">JavaDoc</a> for the
+    <code class="classname">org.hsqldb.jdbc.*</code> classes.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_tabletypes-sect"></a>SQL Data and Tables</h2>
+</div>
+</div>
+</div>
+<p>In an SQL system, all significant data is stored in tables and
+    sequence generators. Therefore, the first step in creating a database is
+    defining the tables and their columns. The SQL standard supports temporary
+    tables, which are for temporary data, and permanent base tables, which are
+    for persistent data.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1037B"></a>Temporary Tables</h3>
+</div>
+</div>
+</div>
+<p>TEMPORARY tables are not saved and last only for the lifetime of
+      the Connection object. The contents of each TEMP table is visible only
+      from the Connection that was used to populate it. The definition of TEMP
+      tables conforms to the GLOBAL TEMPORARY type in the SQL standard. The
+      definition of the table persists but each new connections sees its own
+      copy of the table, which is empty at the beginning. When the connection
+      commits, the contents of the table are cleared by default. If the table
+      definition statements includes ON COMMIT PRESERVE ROWS, then the
+      contents are kept when a commit takes place.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10380"></a>Persistent Tables</h3>
+</div>
+</div>
+</div>
+<p>HSQLDB supports the Standard definition of persistent base table,
+      but defines three types according to the way the data is stored. These
+      are MEMORY tables, CACHED tables and TEXT tables.</p>
+<p>Memory tables are the default type when the CREATE TABLE command
+      is used. Their data is held entirely in memory but any change to their
+      structure or contents is written to the <code class="filename">*.log</code> and
+      <code class="filename">*.script</code> files. The <code class="filename">*.script</code>
+      file and the <code class="filename">*.log</code> file are read the next time the
+      database is opened, and the MEMORY tables are recreated with all their
+      contents. So unlike TEMPORARY tables, MEMORY tables are persistent. When
+      the database is opened, all the data for the memory tables is read and
+      inserted. This process may take a long time if the database is larger
+      than tens of megabytes. When the database is shutdown, all the data is
+      saved. This can also take a long time.</p>
+<p>CACHED tables are created with the CREATE CACHED TABLE command.
+      Only part of their data or indexes is held in memory, allowing large
+      tables that would otherwise take up to several hundred megabytes of
+      memory. Another advantage of cached tables is that the database engine
+      takes less time to start up when a cached table is used for large
+      amounts of data. The disadvantage of cached tables is a reduction in
+      speed. Do not use cached tables if your data set is relatively small. In
+      an application with some small tables and some large ones, it is better
+      to use the default, MEMORY mode for the small tables.</p>
+<p>TEXT tables use a CSV (Comma Separated Value) or other delimited
+      text file as the source of their data. You can specify an existing CSV
+      file, such as a dump from another database or program, as the source of
+      a TEXT table. Alternatively, you can specify an empty file to be filled
+      with data by the database engine. TEXT tables are efficient in memory
+      usage as they cache only part of the text data and all of the indexes.
+      The Text table data source can always be reassigned to a different file
+      if necessary. The commands are needed to set up a TEXT table as detailed
+      in the <a class="link" href="#texttables-chapt" title="Chapter&nbsp;5.&nbsp;Text Tables">Text Tables</a> chapter.</p>
+<p>With all-in-memory databases, both MEMORY table and CACHED table
+      declarations are treated as declarations for non-persistent memory
+      tables. TEXT table declarations are not allowed in these
+      databases.</p>
+<p>The default type of table resulting from future CREATE TABLE
+      statements can be specified with the SQL command:</p>
+<p>
+<pre class="programlisting">    SET DATABASE DEFAULT TABLE TYPE { CACHED | MEMORY };</pre>The
+      type of an existing table can be changed with the SQL command:</p>
+<p>
+<pre class="programlisting">    SET TABLE &lt;table name&gt; TYPE { CACHED | MEMORY };</pre>SQL
+      statements access different types of tables uniformly. No change to
+      statements is needed to access different types of table.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N103A7"></a>Lob Data</h3>
+</div>
+</div>
+</div>
+<p>Lobs are logically stored in columns of tables. Their physical
+      storage is a separate *.lobs file. In version 2.0 this file is created
+      as soon as a BLOB or CLOB is inserted into the database. The file will
+      grow as new lobs are inserted into the database. In version 2.0, the
+      *.lobs file is never deleted even if all lobs are deleted from the
+      database (In this case you can delete the .lobs file after a
+      SHTUDOWN).</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_types_ops-sect"></a>Basic Types and Operations</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL supports all the types defined by SQL-92, plus BOOLEAN,
+    BINARY and LOB types that were added later to the SQL Standard. It also
+    supports the non-standard OTHER type to store serializable Java
+    objects.</p>
+<p>SQL is a strongly typed language. All data stored in specific
+    columns of tables and other objects (such as sequence generators) have
+    specific types. Each data item conforms to the type limits such as
+    precision and scale for the column. It also conforms to any additional
+    integrity constraints that are defined as CHECK constraints in domains or
+    tables. Types can be explicitly converted using the CAST expression, but
+    in most expressions they are converted automatically.</p>
+<p>Data is returned to the user (or the application program) as a
+    result of executing SQL statements such as query expressions or function
+    calls. All statements are compiled prior to execution and the return type
+    of the data is known after compilation and before execution. Therefore,
+    once a statement is prepared, the data type of each column of the returned
+    result is known, including any precision or scale property. The type does
+    not change when the same query that returned one row, returns many rows as
+    a result of adding more data to the tables.</p>
+<p>Some SQL functions used within SQL statements are polymorphic, but
+    the exact type of the argument and the return value is determined at
+    compile time.</p>
+<p>When a statement is prepared, using a JDBC PreparedStatement object,
+    it is compiled by the engine and the type of the columns of its ResultSet
+    and / or its parameters are accessible through the methods of
+    PreparedStatement.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N103BA"></a>Numeric Types</h3>
+</div>
+</div>
+</div>
+<a name="N103BD" class="indexterm"></a>
+<p>TINYINT, SMALLINT, INTEGER, BIGINT, NUMERIC and DECIMAL (without a
+      decimal point) are the supported integral types. They correspond
+      respectively to <code class="classname">byte</code>,
+      <code class="classname">short</code>, <code class="classname">int</code>,
+      <code class="classname">long</code>, <code class="classname">BigDecimal</code> and
+      <code class="classname">BigDecimal</code> Java types in the range of values that
+      they can represent (NUMERIC and DECIMAL are equivalent). The type
+      TINYINT is an HSQLDB extension to the SQL Standard, while the others
+      conform to the Standard definition. The SQL type dictates the maximum
+      and minimum values that can be held in a field of each type. For example
+      the value range for TINYINT is -128 to +127. The bit precision of
+      TINYINT, SMALLINT, INTEGER and BIGINT is respectively 8, 16, 32 and 64.
+      For NUMERIC and DECIMAL, decimal precision is used.</p>
+<p>DECIMAL and NUMERIC with decimal fractions are mapped to
+      <code class="classname">java.math.BigDecimal</code> and can have very large
+      numbers of digits. In HyperSQL the two types are equivalent. These
+      types, together with integral types, are called exact numeric
+      types.</p>
+<p>In HyperSQL, REAL, FLOAT, DOUBLE are equivalent and all mapped to
+      <code class="classname">double</code> in Java. These types are defined by the
+      SQL Standard as approximate numeric types. The bit-precision of all
+      these types is 64 bits.</p>
+<p>The decimal precision and scale of NUMERIC and DECIMAL types can
+      be optionally defined. For example, DECIMAL(10,2) means maximum total
+      number of digits is 10 and there are always 2 digits after the decimal
+      point, while DECIMAL(10) means 10 digits without a decimal point. The
+      bit-precision of FLOAT can also be defined, but in this case, it is
+      ignored and the default bit-precision of 64 is used. The default
+      precision of NUMERIC and DECIMAL (when not defined) is 100.</p>
+<p>Note: If a database has been set to ignore type precision limits
+      with the SET DATABASE SQL SIZE FALSE command, then a type definition of
+      DECIMAL with no precision and scale is treated as DECIMAL(100,10). In
+      normal operation, it is treated as DECIMAL(100).</p>
+<p>
+<span class="bold"><strong>Integral Types</strong></span>
+</p>
+<p>In expressions, TINYINT, SMALLINT, INTEGER, BIGINT, NUMERIC and
+      DECIMAL (without a decimal point) are fully interchangeable, and no data
+      narrowing takes place.</p>
+<p>If the SELECT statement refers to a simple column or function,
+      then the return type is the type corresponding to the column or the
+      return type of the function. For example:</p>
+<div class="informalexample">
+<pre class="programlisting">    CREATE TABLE t(a INTEGER, b BIGINT);
+    SELECT MAX(a), MAX(b) FROM t;</pre>
+</div>
+<p>will return a <code class="classname">ResultSet</code> where the type of
+      the first column is <code class="classname">java.lang.Integer</code> and the
+      second column is <code class="classname">java.lang.Long</code>. However,</p>
+<div class="informalexample">
+<pre class="programlisting">    SELECT MAX(a) + 1, MAX(b) + 1 FROM t;</pre>
+</div>
+<p>will return <code class="classname">java.lang.Long</code> and
+      <code class="classname">BigDecimal</code> values, generated as a result of
+      uniform type promotion for all the return values. Note that type
+      promotion to <code class="classname">BigDecimal</code> ensures the correct value
+      is returned if <code class="literal">MAX(b)</code> evaluates to
+      <code class="literal">Long.MAX_VALUE</code>.</p>
+<p>There is no built-in limit on the size of intermediate integral
+      values in expressions. As a result, you should check for the type of the
+      <code class="classname">ResultSet</code> column and choose an appropriate
+      <code class="methodname">getXXXX()</code> method to retrieve it. Alternatively,
+      you can use the <code class="methodname">getObject()</code> method, then cast
+      the result to <code class="classname">java.lang.Number</code> and use the
+      <code class="methodname">intValue()</code> or
+      <code class="methodname">longValue()</code> methods on the result.</p>
+<p>When the result of an expression is stored in a column of a
+      database table, it has to fit in the target column, otherwise an error
+      is returned. For example when <code class="literal">1234567890123456789012 /
+      12345687901234567890</code> is evaluated, the result can be stored in
+      any integral type column, even a TINYINT column, as it is a small
+      value.</p>
+<p>In SQL Statements, an integer literal is treated as INTEGER,
+      unless its value does not fit. In this case it is treated as BIGINT or
+      DECIMAL, depending on the value.</p>
+<p>Depending on the types of the operands, the result of the
+      operations is returned in a JDBC <code class="classname">ResultSet</code> in any
+      of related Java types: <code class="classname">Integer</code>,
+      <code class="classname">Long</code> or <code class="classname">BigDecimal</code>. The
+      <code class="methodname">ResultSet.getXXXX()</code> methods can be used to
+      retrieve the values so long as the returned value can be represented by
+      the resulting type. This type is deterministically based on the query,
+      not on the actual rows returned.</p>
+<p>
+<span class="bold"><strong>Other Numeric Types</strong></span>
+</p>
+<p>In SQL statements, number literals with a decimal point are
+      treated as DECIMAL unless they are written with an exponent. Thus
+      <code class="literal">0.2</code> is considered a DECIMAL value but
+      <code class="literal">0.2E0</code> is considered a DOUBLE value.</p>
+<p>When an approximate numeric type, REAL, FLOAT or DOUBLE (all
+      synonymous) is part of an expression involving different numeric types,
+      the type of the result is DOUBLE. DECIMAL values can be converted to
+      DOUBLE unless they are beyond the <code class="literal">Double.MIN_VALUE -
+      Double.MAX_VALUE</code> range. For example, A * B, A / B, A + B, etc.
+      will return a DOUBLE value if either A or B is a DOUBLE.</p>
+<p>Otherwise, when no DOUBLE value exists, if a DECIMAL or NUMERIC
+      value is part an expression, the type of the result is DECIMAL or
+      NUMERIC. Similar to integral values, when the result of an expression is
+      assigned to a table column, the value has to fit in the target column,
+      otherwise an error is returned. This means a small, 4 digit value of
+      DECIMAL type can be assigned to a column of SMALLINT or INTEGER, but a
+      value with 15 digits cannot.</p>
+<p>When a DECIMAL values is multiplied by a DECIMAL or integral type,
+      the resulting scale is the sum of the scales of the two terms. When they
+      are divided, the result is a value with a scale (number of digits to the
+      right of the decimal point) equal to the larger of the scales of the two
+      terms. The precision for both operations is calculated (usually
+      increased) to allow all possible results.</p>
+<p>The distinction between DOUBLE and DECIMAL is important when a
+      division takes place. For example, <code class="literal">10.0/8.0</code> (DECIMAL)
+      equals <code class="literal">1.2</code> but <code class="literal">10.0E0/8.0E0</code>
+      (DOUBLE) equals <code class="literal">1.25</code>. Without division operations,
+      DECIMAL values represent exact arithmetic.</p>
+<p>REAL, FLOAT and DOUBLE values are all stored in the database as
+      <code class="classname">java.lang.Double</code> objects. Special values such as
+      NaN and +-Infinity are also stored and supported. These values can be
+      submitted to the database via JDBC
+      <code class="classname">PreparedStatement</code> methods and are returned in
+      <code class="classname">ResultSet</code> objects. The result can be retrieved
+      from a <code class="classname">ResultSet</code> in the required type so long as
+      it can be represented. When
+      <code class="methodname">PreparedStatement.setDouble()</code> or
+      <code class="methodname">setFloat()</code> is used, the value is treated as a
+      DOUBLE automatically.</p>
+<p>In short,</p>
+<p>
+<code class="literal">&lt;numeric type&gt; ::= &lt;exact numeric type&gt; |
+      &lt;approximate numeric type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;exact numeric type&gt; ::= NUMERIC [ &lt;left
+      paren&gt; &lt;precision&gt; [ &lt;comma&gt; &lt;scale&gt; ] &lt;right
+      paren&gt; ] | { DECIMAL | DEC } [ &lt;left paren&gt; &lt;precision&gt; [
+      &lt;comma&gt; &lt;scale&gt; ] &lt;right paren&gt; ] | SMALLINT | INTEGER
+      | INT | BIGINT</code>
+</p>
+<p>
+<code class="literal">&lt;approximate numeric type&gt; ::= FLOAT [ &lt;left
+      paren&gt; &lt;precision&gt; &lt;right paren&gt; ] | REAL | DOUBLE
+      PRECISION</code>
+</p>
+<p>
+<code class="literal">&lt;precision&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;scale&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10482"></a>Boolean Type</h3>
+</div>
+</div>
+</div>
+<a name="N10485" class="indexterm"></a>
+<p>The BOOLEAN type conforms to the SQL Standard and represents the
+      values <code class="literal">TRUE</code>, <code class="literal">FALSE</code> and
+      <code class="literal">UNKNOWN</code>. This type of column can be initialised with
+      Java boolean values, or with <code class="literal">NULL</code> for the
+      <code class="literal">UNKNOWN</code> value.</p>
+<p>The three-value logic is sometimes misunderstood. For example, x
+      IN (1, 2, NULL) does not return true if x is NULL.</p>
+<p>In previous versions of HyperSQL, BIT was simply an alias for
+      BOOLEAN. In version 2.0, BIT is a single-bit bit map.</p>
+<p>
+<code class="literal">&lt;boolean type&gt; ::= BOOLEAN</code>
+</p>
+<p>The SQL Standard does not support type conversion to BOOLEAN apart
+      from character strings that consists of boolean literals. Because the
+      BOOLEAN type is relatively new to the Standard, several database
+      products used other types to represent boolean values. For improved
+      compatibility, HyperSQL allows some type conversions to boolean.</p>
+<p>Values of BIT and BIT VARYING types with length 1 can be converted
+      to BOOLEAN. If the bit is set, the result of conversion is the TRUE
+      value, otherwise it is FALSE.</p>
+<p>Values of TINYINT, SMALLINT, INTEGER and BIGINT types can be
+      converted to BOOLEAN. If the value is zero, the result is the FALSE
+      value, otherwise it is TRUE.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N104A8"></a>Character String Types</h3>
+</div>
+</div>
+</div>
+<a name="N104AB" class="indexterm"></a>
+<p>The CHARACTER, CHARACTER VARYING and CLOB types are the SQL
+      Standard character string types. CHAR, VARCHAR and CHARACTER LARGE
+      OBJECT are synonyms for these types. HyperSQL also supports LONGVARCHAR
+      as a synonym for VARCHAR. If LONGVARCHAR is used without a length, then
+      a length of 1M is assigned.</p>
+<p>HyperSQL's default character set is Unicode, therefore all
+      possible character strings can be represented by these types.</p>
+<p>The SQL Standard behaviour of the CHARACTER type is a remnant of
+      legacy systems in which character strings are padded with spaces to fill
+      a fixed width. These spaces are sometimes significant while in other
+      cases they are silently discarded. It would be best to avoid the
+      CHARACTER type altogether. With the rest of the types, the strings are
+      not padded when assigned to columns or variables of the given type. The
+      trailing spaces are still considered discardable for all character
+      types. Therefore if a string with trailing spaces is too long to assign
+      to a column or variable of a given length, the spaces beyond the type
+      length are discarded and the assignment succeeds (provided all the
+      characters beyond the type length are spaces).</p>
+<p>The VARCHAR and CLOB types have length limits, but the strings are
+      not padded by the system. Note that if you use a large length for a
+      VARCHAR or CLOB type, no extra space is used in the database. The space
+      used for each stored item is proportional to its actual length.</p>
+<p>If CHARACTER is used without specifying the length, the length
+      defaults to 1. For the CLOB type, the length limit can be defined in
+      units of kilobyte (K, 1024), megabyte (M, 1024 * 1024) or gigabyte (G,
+      1024 * 1024 * 1024), using the <code class="literal">&lt;multiplier&gt;</code>. If
+      CLOB is used without specifying the length, the length defaults to
+      1M.</p>
+<p>
+<code class="literal">&lt;character string type&gt; ::= { CHARACTER | CHAR }
+      [ &lt;left paren&gt; &lt;character length&gt; &lt;right paren&gt; ] | {
+      CHARACTER VARYING | CHAR VARYING | VARCHAR } &lt;left paren&gt;
+      &lt;character length&gt; &lt;right paren&gt; | LONGVARCHAR [ &lt;left
+      paren&gt; &lt;character length&gt; &lt;right paren&gt; ] | &lt;character
+      large object type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;character large object type&gt; ::= { CHARACTER
+      LARGE OBJECT | CHAR LARGE OBJECT | CLOB } [ &lt;left paren&gt;
+      &lt;character large object length&gt; &lt;right paren&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;character length&gt; ::= &lt;unsigned integer&gt;
+      [ &lt;char length units&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;large object length&gt; ::= &lt;length&gt; [
+      &lt;multiplier&gt; ] | &lt;large object length
+      token&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;character large object length&gt; ::= &lt;large
+      object length&gt; [ &lt;char length units&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;large object length token&gt; ::= &lt;digit&gt;...
+      &lt;multiplier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;multiplier&gt; ::= K | M | G </code>
+</p>
+<p>
+<code class="literal">&lt;char length units&gt; ::= CHARACTERS |
+      OCTETS</code>
+</p>
+<pre class="programlisting">CHAR(10)
+CHARACTER(10)
+VARCHAR(2)
+CHAR VARYING(2)
+CLOB(1000)
+CLOB(30K)
+CHARACTER LARGE OBJECT(1M)
+LONGVARCHAR
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N104D7"></a>Binary String Types</h3>
+</div>
+</div>
+</div>
+<a name="N104DA" class="indexterm"></a>
+<p>The BINARY, BINARY VARYING and BLOB types are the SQL Standard
+      binary string types. VARBINARY and BINARY LARGE OBJECT are synonyms for
+      BINARY VARYING and BLOB types. HyperSQL also supports LONGVARBINARY as a
+      synonym for VARBINARY.</p>
+<p>Binary string types are used in a similar way to character string
+      types. There are several built-in functions that are overloaded to
+      support character, binary and bit strings.</p>
+<p>The BINARY type represents a fixed width-string. Each shorter
+      string is padded with zeros to fill the fixed width. Similar to the
+      CHARACTER type, the trailing zeros in the BINARY string are simply
+      discarded in some operations. For the same reason, it is best to avoid
+      this particular type.</p>
+<p>If BINARY is used without specifying the length, the length
+      defaults to 1. For the BLOB type, the length limit can be defined in
+      units of kilobyte (K, 1024), megabyte (M, 1024 * 1024) or gigabyte (G,
+      1024 * 1024 * 1024), using the <code class="literal">&lt;multiplier&gt;</code>. If
+      BLOB is used without specifying the length, the length defaults to
+      1M.</p>
+<p>
+<code class="literal">&lt;binary string type&gt; ::= BINARY [ &lt;left
+      paren&gt; &lt;length&gt; &lt;right paren&gt; ] | { BINARY VARYING |
+      VARBINARY } &lt;left paren&gt; &lt;length&gt; &lt;right paren&gt; |
+      LONGVARBINARY [ &lt;left paren&gt; &lt;length&gt; &lt;right paren&gt; ]
+      | &lt;binary large object string type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;binary large object string type&gt; ::= { BINARY
+      LARGE OBJECT | BLOB } [ &lt;left paren&gt; &lt;large object length&gt;
+      &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;length&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<pre class="programlisting">BINARY(10)
+VARBINARY(2)
+BINARY VARYING(2)
+BLOB(1000)
+BLOB(30K)
+BINARY LARGE OBJECT(1M)
+LONGVARBINARY
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N104F5"></a>Bit String Types</h3>
+</div>
+</div>
+</div>
+<a name="N104F8" class="indexterm"></a>
+<p>The BIT and BIT VARYING types are the supported bit string types.
+      These types were defined by SQL:1999 but were later removed from the
+      Standard. Bit types represent bit maps of given lengths. Each bit is 0
+      or 1. The BIT type represents a fixed width-string. Each shorter string
+      is padded with zeros to fill the fixed with. If BIT is used without
+      specifying the length, the length defaults to 1. The BIT VARYING type
+      has a maximum width and shorter strings are not padded.</p>
+<p>Before the introduction of the BOOLEAN type to the SQL Standard, a
+      sigle-bit string of the type BIT(1) was commonly used. For compatibility
+      with other products that do not conform to, or extend, the SQL Standard,
+      HyperSQL allows values of BIT and BIT VARYING types with length 1 to be
+      converted to and from the BOOLEAN type. BOOLEAN TRUE is considered equal
+      to B'1', BOOLEAN FALSE is considered equal to B'0'.</p>
+<p>For the same reason, numeric values can be assigned to columns and
+      variables of the type BIT(1). For assignment, the numeric value zero is
+      converted to B'0', while all other values are converted to B'1'. For
+      comparison, numeric values 1 is considered equal to B'1' and numeric
+      value zero is considered equal to B'0'.</p>
+<p>It is not allowed to perform other arithmetic or boolean
+      operations involving BIT(1) and BIT VARYING(1). The kid of operations
+      allowed on bit strings are analogous to those allowed on BINARY and
+      CHARACTER strings. Several built-in functions support all three types of
+      string.</p>
+<p>
+<code class="literal">&lt;bit string type&gt; ::= BIT [ &lt;left paren&gt;
+      &lt;length&gt; &lt;right paren&gt; ] | BIT VARYING &lt;left paren&gt;
+      &lt;length&gt; &lt;right paren&gt;</code>
+</p>
+<pre class="programlisting">BIT
+BIT(10)
+BIT VARYING(2)
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1050A"></a>Storage and Handling of Java Objects</h3>
+</div>
+</div>
+</div>
+<a name="N1050D" class="indexterm"></a>
+<p>Any serializable JAVA Object can be inserted directly into a
+      column of type OTHER using any variation of
+      <code class="methodname">PreparedStatement.setObject()</code> methods.</p>
+<p>For comparison purposes and in indexes, any two Java Objects are
+      considered equal unless one of them is NULL. You cannot search for a
+      specific object or perform a join on a column of type OTHER.</p>
+<p>Please note that HSQLDB is not an object-relational database. Java
+      Objects can simply be stored internally and no operations should be
+      performed on them other than assignment between columns of type OTHER or
+      tests for NULL. Tests such as <code class="literal">WHERE object1 = object2
+      </code>do not mean what you might expect, as any non-null object
+      would satisfy such a tests. But <code class="literal">WHERE object1 IS NOT
+      NULL</code> is perfectly acceptable.</p>
+<p>The engine does not allow normal column values to be assigned to
+      Java Object columns (for example, assigning an INTEGER or STRING to such
+      a column with an SQL statement such as <code class="literal">UPDATE mytable SET
+      objectcol = intcol WHERE ...</code>).</p>
+<p>
+<code class="literal">&lt;java object type&gt; ::= OTHER</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10529"></a>Type Length, Precision and Scale</h3>
+</div>
+</div>
+</div>
+<p>In older version of HyperSQL, all table column type definitions
+      with a column length, precision or scale qualifier were accepted and
+      ignored. HSQLDB 1.8 enforced correctness but included an option to
+      enforce the length, precision or scale.</p>
+<p>In HyperSQL 2.0, length, precision and scale qualifiers are always
+      enforced. For backward compatibility, when older databases which had the
+      property hsqldb.enforce_strict_size=false are converted to version 2.0,
+      this property is retained. However, this is a temporary measure. You
+      should test your application to ensure the length, precision and scale
+      that is used for column definitions is appropriate for the application
+      data. You can test with the default database setting, which enforces the
+      sizes.</p>
+<p>String types, including all BIT, BINARY and CHAR string types plus
+      CLOB and BLOB, are generally defined with a length. If no length is
+      specified for BIT, BINARY and CHAR, the default length is 1. For CLOB
+      and BLOB an implementation defined length of 1M is used.</p>
+<p>TIME and TIMESTAMP types can be defined with a fractional second
+      precision between 0 and 9. INTERVAL type definition may have precision
+      and, in some cases, fraction second precision. DECIMAL and NUMERIC types
+      may be defined with precision and scale. For all of these types a
+      default precision or scale value is used if one is not specified. The
+      default scale is 0. The default fractional precision for TIME is 0,
+      while it is 6 for TIMESTAMP.</p>
+<p>Values can be converted from one type to another in two different
+      ways: by using explicit CAST expression or by implicit conversion used
+      in assignment, comparison and aggregation.</p>
+<p>String values cannot be assigned to VARCHAR columns if they are
+      longer than the defined type length. For CHARACTER columns, a long
+      string can be assigned (with truncation) only if all the characters
+      after the length are spaces. Shorter strings are padded with the space
+      character when inserted into a CHARACTER column. Similar rules are
+      applied to VARBINARY and BINARY columns. For BINARY columns, the padding
+      and truncation rules are applied with zero bytes, instead of
+      spaces.</p>
+<p>Explicit CAST of a value to a CHARACTER or VARCHAR type will
+      result in forced truncation or padding. So a test such as <code class="literal">CAST
+      (mycol AS VARCHAR(2)) = 'xy'</code> will find the values beginning
+      with 'xy'. This is the equivalent of <code class="literal">SUBSTRING(mycol FROM 1 FOR
+      2)= 'xy'</code>.</p>
+<p>For all numeric types, the rules of explicit cast and implicit
+      conversion are the same. If cast or conversion causes any digits to be
+      lost from the fractional part, it can take place. If the non-fractional
+      part of the value cannot be represented in the new type, cast or
+      conversion cannot take place and will result in a data exception.</p>
+<p>There are special rules for DATE, TIME, TIMESTAMP and INTERVAL
+      casts and conversions.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10544"></a>Datetime types</h2>
+</div>
+</div>
+</div>
+<p>HSQLDB fully supports datetime and interval types and operations,
+    including all relevant optional features, as specified by the SQL Standard
+    since SQL-92. The two groups of types are complementary.</p>
+<a name="N10549" class="indexterm"></a>
+<p>The DATE type represents a calendar date with YEAR, MONTH and DAY
+    fields.</p>
+<p>The TIME type represents time of day with HOUR, MINUTE and SECOND
+    fields, plus an optional SECOND FRACTION field.</p>
+<p>The TIMESTAMP type represents the combination of DATE and TIME
+    types.</p>
+<p>TIME and TIMESTAMP types can include WITH TIME ZONE or WITHOUT TIME
+    ZONE (the default) qualifiers. They can have fractional second parts. For
+    example, TIME(6) has six fractional digits for the second field.</p>
+<p>If fractional second precision is not specified, it defaults to 0
+    for TIME and to 6 for TIMESTAMP.</p>
+<p>
+<code class="literal">&lt;datetime type&gt; ::= DATE | TIME [ &lt;left
+    paren&gt; &lt;time precision&gt; &lt;right paren&gt; ] [ &lt;with or
+    without time zone&gt; ] | TIMESTAMP [ &lt;left paren&gt; &lt;timestamp
+    precision&gt; &lt;right paren&gt; ] [ &lt;with or without time zone&gt;
+    ]</code>
+</p>
+<p>
+<code class="literal">&lt;with or without time zone&gt; ::= WITH TIME ZONE |
+    WITHOUT TIME ZONE</code>
+</p>
+<p>
+<code class="literal">&lt;time precision&gt; ::= &lt;time fractional seconds
+    precision&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;timestamp precision&gt; ::= &lt;time fractional
+    seconds precision&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time fractional seconds precision&gt; ::=
+    &lt;unsigned integer&gt;</code>
+</p>
+<pre class="programlisting">DATE
+TIME(6)
+TIMESTAMP(2) WITH TIME ZONE
+</pre>
+<p>Examples of the string literals used to represent date time values,
+    some with time zone, some without, are below:</p>
+<pre class="programlisting">DATE '2008-08-22'
+TIMESTAMP '2008-08-08 20:08:08'
+TIMESTAMP '2008-08-08 20:08:08+8:00' /* Beijing */
+TIME '20:08:08.034900'
+TIME '20:08:08.034900-8:00' /* US Pacific */</pre>
+<a name="N1056D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Time Zone</strong></span>
+</p>
+<p>DATE values do not take time zones. For example United Nations
+    designates 5 June as World Environment Day, which was observed on DATE
+    '2008-06-05' in different time zones.</p>
+<p>TIME and TIMESTAMP values without time zone, usually have a context
+    that indicates some local time zone. For example, a database for college
+    course timetables usually stores class dates and times without time zones.
+    This works because the location of the college is fixed and the time zone
+    displacement is the same for all the values. Even when the events take
+    place in different time zones, for example international flight times, it
+    is possible to store all the datetime information as references to a
+    single time zone, usually GMT. For some databases it may be useful to
+    store the time zone displacement together with each datetime value. SQL&rsquo;s
+    TIME WITH TIME ZONE and TIMESTAMP WITH TIME ZONE values include a time
+    zone displacement value.</p>
+<p>The time zone displacement is of the type INTERVAL HOUR TO MINUTE.
+    This data type is described in the next section. The legal values are
+    between '&ndash;14:00' and &nbsp; '+14:00'.</p>
+<a name="N1057C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Operations on Datetime
+    Types</strong></span>
+</p>
+<p>The expression <code class="literal">&lt;datetime expression&gt; AT TIME ZONE
+    &lt;time displacement&gt;</code> evaluates to a datetime value
+    representing exactly the same point of time in the specified
+    <code class="literal">&lt;time displacement&gt;</code>. The expression, <code class="literal">AT
+    LOCAL</code> is equivalent to <code class="literal">AT TIME ZONE &lt;local time
+    displacement&gt;</code>. If <code class="literal">AT TIME ZONE</code> is used
+    with a datetime operand of type WITHOUT TIME ZONE, the operand is first
+    converted to a value of type WITH TIME ZONE at the session&rsquo;s time
+    displacement, then the specified time zone displacement is set for the
+    value. Therefore, in these cases, the final value depends on the time zone
+    of the session in which the statement was used.</p>
+<p>AT TIME ZONE, modifies the field values of the datetime operand.
+    This is done by the following procedure:</p>
+<div class="orderedlist">
+<ol type="1">
+<li>
+<p>determine the corresponding datetime at UTC.</p>
+</li>
+<li>
+<p>find the datetime value at the given time zone that corresponds
+        with the UTC value from step 1.</p>
+</li>
+</ol>
+</div>
+<p>Example a:</p>
+<pre class="programlisting">TIME '12:00:00' AT TIME ZONE INTERVAL '1:00' HOUR TO MINUTE
+</pre>
+<p>If the session&rsquo;s time zone displacement is -'8:00', then in step 1,
+    TIME '12:00:00' is converted to UTC, which is TIME '20:00:00+0:00'. In
+    step 2, this value is expressed as TIME '21:00:00+1:00'.</p>
+<p>Example b:</p>
+<pre class="programlisting">TIME '12:00:00-5:00' AT TIME ZONE INTERVAL '1:00' HOUR TO MINUTE
+</pre>
+<p>Because the operand has a time zone, the result is independent of
+    the session &nbsp;time zone displacement. Step 1 results in TIME
+    '17:00:00+0:00', and step 2 results in TIME '18:00:00+1:00'</p>
+<p>Note that the operand is not limited to datetime literals used in
+    these examples. Any valid expression that evaluates to a datetime value
+    can be the operand.</p>
+<p>
+<span class="bold"><strong>Type Conversion</strong></span>
+</p>
+<p>CAST is used to for all other conversions. Examples:</p>
+<pre class="programlisting">CAST (&lt;value&gt; AS TIME WITHOUT TIME ZONE)
+CAST (&lt;value&gt; AS TIME WITH TIME ZONE)</pre>
+<p>In the first example, if <code class="literal">&lt;value&gt;</code> has a time
+    zone component, it is simply dropped. For example TIME '12:00:00-5:00' is
+    converted to TIME '12:00:00'</p>
+<p>In the second example, if <code class="literal">&lt;value&gt;</code> has no
+    time zone component, the current time zone displacement of the session is
+    added. For example TIME '12:00:00' is converted to TIME '12:00:00-8:00'
+    when the session time zone displacement is '-8:00'.</p>
+<p>Conversion between DATE and TIMESTAMP is performed by removing the
+    TIME component of a TIMESTAMP value or by setting the hour, minute and
+    second fields to zero. TIMESTAMP '2008-08-08 20:08:08+8:00' becomes DATE
+    '2008-08-08', while DATE '2008-08-22' becomes TIMESTAMP '2008-08-22
+    00:00:00'.</p>
+<p>Conversion between TIME and TIMESTAMP is performed by removing the
+    DATE field values of a TIMESTAMP value or by appending the fields of the
+    TIME value to the fields of the current session date value.</p>
+<p>
+<span class="bold"><strong>Assignment</strong></span>
+</p>
+<p>When a value is assigned to a datetime target, e.g., a value is used
+    to update a row of a table, the type of the value must be the same as the
+    target, but the WITH TIME ZONE or WITHOUT TIME ZONE characteristics can be
+    different. If the types are not the same, an explicit CAST must be used to
+    convert the value into the target type.</p>
+<p>
+<span class="bold"><strong>Comparison</strong></span>
+</p>
+<p>When values WITH TIME ZONE are compared, they are converted to UTC
+    values before comparison. If a value WITH TIME ZONE is compared to another
+    WITHOUT TIME ZONE, then the WITH TIME ZONE value is converted to AT LOCAL,
+    then converted to WITHOUT TIME ZONE before comparison.</p>
+<p>It is not recommended to design applications that rely on
+    comparisons and conversions between TIME values WITH TIME ZONE. The
+    conversions may involve normalisation of the time value, resulting in
+    unexpected results. For example, the expression: BETWEEN(TIME
+    '12:00:00-8:00', TIME '22:00:00-8:00') is converted to BETWEEN(TIME
+    '20:00:00+0:00', TIME '06:00:00+0:00') when it is evaluated in the UTC
+    zone, which is always FALSE.</p>
+<p>
+<span class="bold"><strong>Functions</strong></span>
+</p>
+<p>Several functions return the current session timestamp in different
+    datetime types:</p>
+<div class="informaltable">
+<table cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>CURRENT_DATE</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>DATE</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>CURRENT_TIME</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>TIME WITH TIME ZONE</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>CURRENT_TIMESTAMP</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>TIMESTAMP WITH TIME ZONE</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>LOCALTIME</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>TIMESTAMP WITHOUT TIME ZONE</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; ">
+<p>LOCALTIMESTAMP</p>
+</td><td style="">
+<p>TIMESTAMP WITHOUT TIME ZONE</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+<span class="bold"><strong>Session Time Zone
+    Displacement</strong></span>
+</p>
+<p>When an SQL session is started (with a JDBC connection) the local
+    time zone of the client JVM (including any seasonal time adjustments such
+    as daylight saving time) is used as the session time zone displacement.
+    Note that the SQL session time displacement is not changed when a seasonal
+    time adjustment takes place while the session is open. To change the SQL
+    session time zone displacement use the following commands:</p>
+<p>
+<code class="literal">SET TIME ZONE &lt;time
+    displacement&gt;</code>
+</p>
+<p>
+<code class="literal">SET TIME ZONE LOCAL</code>
+</p>
+<p>The first command sets the displacement to the given value. The
+    second command restores the original, real time zone displacement of the
+    session.</p>
+<p>
+<span class="bold"><strong>Datetime Values and
+    Java</strong></span>
+</p>
+<p>When datetime values are sent to the database using the
+    <code class="classname">PreparedStatement</code> or
+    <code class="classname">CallableStatement</code> interfaces, the Java object is
+    converted to the type of the prepared or callable statement parameter.
+    This type may be DATE, TIME, or TIMESTAMP (with or without time zone). The
+    time zone displacement is the time zone of the JDBC session.</p>
+<p>When datetime values are retrieved from the database using the
+    <code class="literal">ResultSet</code> interface, there are two representations. The
+    <code class="methodname">getString(&hellip;)</code> methods of the
+    <code class="classname">ResultSet</code> interface, return an exact representation
+    of the value in the SQL type as it is stored in the database. This
+    includes the correct number of digits for the fractional second field, and
+    for values with time zone displacement, the time zone displacement.
+    Therefore if TIME '12:00:00' is stored in the database, all users in
+    different time zones will get '12:00:00' when they retrieve the value as a
+    string. The <code class="methodname">getTime(&hellip;)</code> and
+    <code class="methodname">getTimestamp(&hellip;)</code> methods of the
+    <code class="classname">ResultSet</code> interface return Java objects that are
+    corrected for the session time zone. The UTC millisecond value contained
+    the <code class="classname">java.sql.Time</code> or
+    <code class="classname">java.sql.Timestamp</code> objects will be adjusted to the
+    time zone of the session, therefore the
+    <code class="methodname">toString()</code> method of these objects return the
+    same values in different time zones.</p>
+<p>If you want to store and retrieve UTC values that are independent of
+    any session's time zone, you can use a TIMESTAMP WITH TIME ZONE column.
+    The setTime(...) and setTimestamp(...) methods of the PreparedStatement
+    interface which have a Calendar parameter can be used to assign the
+    values. The time zone of the given Calendar argument is used as the time
+    zone. Conversely, the getTime(...) and getTimestamp(...) methods of the
+    ResultSet interface which have a Calendar parameter can be used with a
+    Calendar argument to retrieve the values.</p>
+<p>JDBC has an unfortunate limitation and does not include type codes
+    for SQL datetime types that have a TIME ZONE property. Therefore, for
+    compatibility with database tools that are limited to the JDBC type codes,
+    HyperSQL reports these types by default as datetime types without TIME
+    ZONE. You can use the URL property
+    <code class="literal">hsqldb.translate_dti_types=false</code> to override the
+    default behaviour.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1063D"></a>Interval Types</h2>
+</div>
+</div>
+</div>
+<a name="N10640" class="indexterm"></a>
+<p>Interval types are used to represent differences between date time
+    values. The difference between two date time values can be measured in
+    seconds or in months. For measurements in months, the units YEAR and MONTH
+    are available, while for measurements in seconds, the units DAY, HOUR,
+    MINUTE, SECOND are available. The units can be used individually, or as a
+    range. An interval type can specify the precision of the most significant
+    field and the second fraction digits of the SECOND field (if it has a
+    SECOND field). The default precision is 2. The default second precision is
+    0.</p>
+<p>
+<code class="literal">&lt;interval type&gt; ::= INTERVAL &lt;interval
+    qualifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval qualifier&gt; ::= &lt;start field&gt; TO
+    &lt;end field&gt; | &lt;single datetime field&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;start field&gt; ::= &lt;non-second primary datetime
+    field&gt; [ &lt;left paren&gt; &lt;interval leading field precision&gt;
+    &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;end field&gt; ::= &lt;non-second primary datetime
+    field&gt; | SECOND [ &lt;left paren&gt; &lt;interval fractional seconds
+    precision&gt; &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;single datetime field&gt; ::= &lt;non-second primary
+    datetime field&gt; [ &lt;left paren&gt; &lt;interval leading field
+    precision&gt; &lt;right paren&gt; ] | SECOND [ &lt;left paren&gt;
+    &lt;interval leading field precision&gt; [ &lt;comma&gt; &lt;interval
+    fractional seconds precision&gt; ] &lt;right paren&gt;
+    ]</code>
+</p>
+<p>
+<code class="literal">&lt;primary datetime field&gt; ::= &lt;non-second
+    primary datetime field&gt; | SECOND</code>
+</p>
+<p>
+<code class="literal">&lt;non-second primary datetime field&gt; ::= YEAR |
+    MONTH | DAY | HOUR | MINUTE</code>
+</p>
+<p>
+<code class="literal">&lt;interval fractional seconds precision&gt; ::=
+    &lt;unsigned integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval leading field precision&gt; ::=
+    &lt;unsigned integer&gt;</code>
+</p>
+<p>Examples of INTERVAL type definition:</p>
+<pre class="programlisting">INTERVAL YEAR TO MONTH
+INTERVAL YEAR(3)
+INTERVAL DAY(4) TO HOUR
+INTERVAL MINUTE(4) TO SECOND(6)
+INTERVAL SECOND(4,6)
+</pre>
+<p>The word INTERVAL indicates the general type name. The rest of the
+    definition is called an <code class="literal">&lt;interval qualifier&gt;</code>.
+    This designation is important, as in most expressions
+    <code class="literal">&lt;interval qualifier&gt;</code> is used without the word
+    INTERVAL.</p>
+<p>
+<span class="bold"><strong>Interval Values</strong></span>
+</p>
+<p>An interval value can be negative, positive or zero. An interval
+    type has all the datetime fields in the specified range. These fields are
+    similar to those in the TIMESTAMP type. The differences are as
+    follows:</p>
+<p>The first field of an interval value can hold any numeric value up
+    to the specified precision. For example, the hour field in HOUR(2) TO
+    SECOND can hold values above 23 (up to 99). The year and month fields can
+    hold zero (unlike a TIMESTAMP value) and the maximum value of a month
+    field that is not the most significant field, is 11.</p>
+<p>The standard function <code class="literal">ABS(&lt;interval value
+    expression&gt;)</code> can be used to convert a negative interval value
+    to a positive one.</p>
+<p>The literal representation of interval values consists of the type
+    definition, with a string representing the interval value inserted after
+    the word INTERVAL. Some examples of interval literal below:</p>
+<pre class="programlisting">INTERVAL '145 23:12:19.345' DAY(3) TO SECOND(3)
+INTERVAL '3503:12:19.345' HOUR TO SECOND(3) /* equal to the first value */
+INTERVAL '19.345' SECOND(4,3) /* maximum number of digits for the second value is 4, and each value is expressed with three fraction digits. */
+INTERVAL '-23-10' YEAR(2) TO MONTH
+</pre>
+<p>Interval values of the types that are based on seconds can be cast
+    into one another. Similarly those that are based on months can be cast
+    into one another. It is not possible to cast or convert a value based on
+    seconds to one based on months, or vice versa.</p>
+<p>When a cast is performed to a type with a smaller least-significant
+    field, nothing is lost from the interval value. Otherwise, the values for
+    the missing least-significant fields are discarded. Examples:</p>
+<pre class="programlisting">CAST ( INTERVAL '145 23:12:19' DAY TO SECOND AS INTERVAL DAY TO HOUR ) = INTERVAL '145 23' DAY TO HOUR
+CAST(INTERVAL '145 23' DAY TO HOUR AS INTERVAL DAY TO SECOND) = INTERVAL '145 23:00:00' DAY TO SECOND
+</pre>
+<p>A numeric value can be cast to an interval type. In this case the
+    numeric value is first converted to a single-field INTERVAL type with the
+    same field as the least significant field of the target interval type.
+    This value is then converted to the target interval type For example CAST(
+    22 AS INTERVAL YEAR TO MONTH) evaluates to INTERVAL '22' MONTH and then
+    INTERVAL '1 10' YEAR TO MONTH. Note that SQL Standard only supports casts
+    to single-field INTERVAL types, while HyperSQL allows casting to
+    multi-field types as well.</p>
+<p>An interval value can be cast to a numeric type. In this case the
+    interval value is first converted to a single-field INTERVAL type with the
+    same field as the least significant filed of the interval value. The value
+    is then converted to the target type. For example CAST (INTERVAL '1-11'
+    YEAR TO MONTH AS INT) evaluates to INTERVAL '23' MONTH, and then
+    23.</p>
+<p>An interval value can be cast into a character type, which results
+    in an INTERVAL literal. A character value can be cast into an INTERVAL
+    type so long as it is a string with a format compatible with an INTERVAL
+    literal.</p>
+<p>Two interval values can be added or subtracted so long as the types
+    of both are based on the same field, i.e., both are based on MONTH or
+    SECOND. The values are both converted to a single-field interval type with
+    same field as the least-significant field between the two types. After
+    addition or subtraction, the result is converted to an interval type that
+    contains all the fields of the two original types.</p>
+<p>An interval value can be multiplied or divided by a numeric value.
+    Again, the value is converted to a numeric, which is then multiplied or
+    divided, before converting back to the original interval type.</p>
+<p>An interval value is negated by simply prefixing with the minus
+    sign.</p>
+<p>Interval values used in expressions are either typed values,
+    including interval literals, or are interval casts. The expression:
+    <code class="literal">&lt;expression&gt; &lt;interval qualifier&gt;</code> is a cast
+    of the result of the <code class="literal">&lt;expression&gt;</code> into the
+    INTERVAL type specified by the <code class="literal">&lt;interval qualifier&gt;. The
+    cast can be formed by adding the keywords and parentheses as follows: CAST
+    ( &lt;expression&gt; AS INTERVAL &lt;interval qualifier&gt;
+    ).</code>
+</p>
+<p>
+<code class="literal">The examples below feature different forms of expression
+    that represent an interval value, which is then added to the given date
+    literal.</code>
+</p>
+<pre class="programlisting">DATE '2000-01-01' + INTERVAL '1-10' YEAR TO MONTH /* interval literal */
+DATE '2000-01-01' + '1-10' YEAR TO MONTH /* the string '1-10' is cast into INTERVAL YEAR TO MONTH */
+DATE '2000-01-01' + 22 MONTH /* the integer 22 is cast into INTERVAL MONTH, same value as above */
+DATE '2000-01-01' - 22 DAY /* the integer 22 is cast into INTERVAL DAY */
+DATE '2000-01-01' + COL2 /* the type of COL2 must be an INTERVAL type */
+DATE '2000-01-01' + COL2 MONTH /* COL2 may be a number, it is cast into a MONTH interval */
+</pre>
+<p>
+<span class="bold"><strong>Datetime and Interval
+    Operations</strong></span>
+</p>
+<p>An interval can be added to or subtracted from a datetime value so
+    long as they have some fields in common. For example, an INTERVAL MONTH
+    cannot be added to a TIME value, while an INTERVAL HOUR TO SECOND can. The
+    interval is first converted to a numeric value, then the value is added
+    to, or subtracted from, the corresponding field of the datetime
+    value.</p>
+<p>If the result of addition or subtraction is beyond the permissible
+    range for the field, the field value is normalised and carried over to the
+    next significant field until all the fields are normalised. For example,
+    adding 20 minutes to TIME '23:50:10' will result successively in
+    '23:70:10', '24:10:10' and finally TIME '00:10:10'. Subtracting 20 minutes
+    from the result is performed as follows: '00:-10:10', '-1:50:10', finally
+    TIME '23:50:10'. Note that if DATE or TIMESTAMP normalisation results in
+    the YEAR field value out of the range (1,1000), then an exception
+    condition is raised.</p>
+<p>If an interval value based on MONTH is added to, or subtracted from
+    a DATE or TIMESTAMP value, the result may have an invalid day (30 or 31)
+    for the given result month. In this case an exception condition is
+    raised.</p>
+<p>The result of subtraction of two datetime expressions is an interval
+    value. The two datetime expressions must be of the same type. The type of
+    the interval value must be specified in the expression, using only the
+    interval field names. The two datetime expressions are enclosed in
+    parentheses, followed by the <code class="literal">&lt;interval qualifier&gt;</code>
+    fields. In the first example below, COL1 and COL2 are of the same datetime
+    type, and the result is evaluated in INTERVAL YEAR TO MONTH type.</p>
+<pre class="programlisting">(COL1 &ndash; COL2) YEAR TO MONTH /* the difference between two DATE or two TIEMSTAMP values in years and months */
+(CURRENT_DATE &ndash; COL3) DAY /* the number of days between the value of COL3 and the current date */
+(CURRENT_DATE - DATE '2000-01-01') YEAR TO MONTH /* the number of years and months since the beginning of this century */
+CURRENT_DATE - 2 DAY /* the date of the day before yesterday */
+(CURRENT_TIMESTAMP - TIMESTAMP '2009-01-01 00:00:00') DAY(4) TO SECOND(2) /* days to seconds since the given date */
+</pre>
+<p>The individual fields of both datetime and interval values can be
+    extracted using the EXTRACT function. The same function can also be used
+    to extract the time zone displacement fields of a datetime value.</p>
+<p>
+<code class="literal">EXTRACT ({YEAR | MONTH | DAY | HOUR | MINUTE | SECOND |
+    TIMEZONE_HOUR | TIMEZONE_MINUTE | DAY_OF_WEEK | WEEK_OF_YEAR } FROM
+    {&lt;datetime value&gt; | &lt;interval value&gt;})</code>
+</p>
+<p>The dichotomy between interval types based on seconds, and those
+    based on months, stems from the fact that the different calendar months
+    have different numbers of days. For example, the expression, &ldquo;nine months
+    and nine days since an event&rdquo; is not exact when the date of the event is
+    unknown. It can represent a period of around 284 days give or take one.
+    SQL interval values are independent of any start or end dates or times.
+    However, when they are added to or subtracted from certain date or
+    timestamp values, the result may be invalid and cause an exception (e.g.
+    adding one month to January 30 results in February 30, which is
+    invalid).</p>
+<p>JDBC has an unfortunate limitation and does not include type codes
+    for SQL INTERVAL types. Therefore, for compatibility with database tools
+    that are limited to the JDBC type codes, HyperSQL reports these types by
+    default as VARCHAR. You can use the URL property
+    <code class="literal">hsqldb.translate_dti_types=false</code> to override the
+    default behaviour.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N106BD"></a>Arrays</h2>
+</div>
+</div>
+</div>
+<p>Array are a powerful feature of SQL:2008 and can help solve many
+    common problems. Arrays should not be used as a substitute for
+    tables.</p>
+<p>HyperSQL supports arrays of values according to the SQL:2008
+    Standard.</p>
+<p>Elements of the array are either NULL, or of the same data type. It
+    is possible to define arrays of all supported types, including the types
+    covered in this chapter and user defined types, except LOB types. An SQL
+    array is one dimensional and is addressed from position 1. An empty array
+    can also be used, which has no element.</p>
+<p>Arrays can be stored in the database, as well as being used as
+    temporary containers of values for simplifying SQL statements. They
+    facilitate data exchange between the SQL engine and the user's
+    application.</p>
+<p>The full range of supported syntax allows array to be created, used
+    in SELECT or other statements, combined with rows of tables and used in
+    routine calls.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N106CA"></a>Array Definition</h3>
+</div>
+</div>
+</div>
+<p>The type of a table column, a routine parameter, a variable, or
+      the return value of a function can be defined as an array.</p>
+<p>
+<code class="literal">&lt;array type&gt; ::= &lt;data type&gt; ARRAY [ &lt;left
+      bracket or trigraph&gt; &lt;maximum cardinality&gt; &lt;right bracket or
+      trigraph&gt; ]</code>
+</p>
+<p>The word ARRAY is added to any valid type definition except BLOB
+      and CLOB type definitions. If the optional <code class="literal">&lt;maximum
+      cardinality&gt;</code> is not used, the default value is 1024. The
+      size of the array cannot be extended beyond maximum cardinality.</p>
+<p>In the example below, the table contains a column of integer
+      arrays and a column of varchar arrays. The VARCHAR array has an explicit
+      maximum size of 10, which means each array can have between 0 and 10
+      elements. The INTEGER array has the default maximum size of 1024. The id
+      column has a default clause with an empty array. The default clause can
+      be defined only as DEFAULT NULL or DEFAULT ARRAY[] and does not allow
+      arrays containing elements.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (id INT PRIMARY KEY, scores INT ARRAY DEFAULT ARRAY[], names VARCHAR(20) ARRAY[10])</pre>
+</div>
+<p>An array can be constructed from value expressions or a query
+      expression.</p>
+<p>
+<code class="literal">&lt;array value constructor by enumeration&gt; ::= ARRAY
+      &lt;left bracket or trigraph&gt; &lt;array element list&gt; &lt;right
+      bracket or trigraph&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;array element list&gt; ::= &lt;value expression&gt; [
+      { &lt;comma&gt; &lt;value expression&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;array value constructor by query&gt; ::= ARRAY
+      &lt;left paren&gt; &lt;query expression&gt; [ &lt;order by clause&gt; ]
+      &lt;right paren&gt;</code>
+</p>
+<p>In the examples below, arrays are constructed from values, column
+      references or variables, function calls, or query expressions.</p>
+<div class="informalexample">
+<pre class="programlisting">ARRAY [ 1, 2, 3 ]
+ARRAY [ 'HOT', 'COLD' ]
+ARRAY [ var1, var2, CURRENT_DATE ]
+ARRAY (SELECT lastname FROM namestable ORDER BY id)
+</pre>
+</div>
+<p></p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N106ED"></a>Array Reference</h3>
+</div>
+</div>
+</div>
+<p>The most common operations on an array element reference and
+      assignment, which are used when reading or writing an element of the
+      array. Unlike Java and many other languages, arrays are extended if an
+      element is assigned to an index beyond the current length. This can
+      result in gaps containing NULL elements. Array length cannot exceed the
+      maximum cardinality.</p>
+<p>Elements of all arrays, including those that are the result of
+      function calls or other operations can be referenced for reading.</p>
+<p>
+<code class="literal">&lt;array element reference&gt; ::= &lt;array value
+      expression&gt; &lt;left bracket&gt; &lt;numeric value expression&gt;
+      &lt;right bracket&gt;</code>
+</p>
+<p>Elements of arrays that are table columns or routine variables can
+      be referenced for writing. This is done in a SET statement, either
+      inside an UPDATE statement, or as a separate statement in the case of
+      routine variables, OUT and INOUT parameters.</p>
+<p>
+<code class="literal">&lt;target array element specification&gt; ::= &lt;target
+      array reference&gt; &lt;left bracket or trigraph&gt; &lt;simple value
+      specification&gt; &lt;right bracket or trigraph&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;target array reference&gt; ::= &lt;SQL parameter
+      reference&gt; | &lt;column reference&gt;</code>
+</p>
+<p>Note that only simple values or variables are allowed for the
+      array index when an assignment is performed. The examples below
+      demonstrates how elements of the array are referenced in SELECT and an
+      UPDATE statement.</p>
+<p>
+<div class="informalexample">
+<pre class="programlisting">SELECT scores[ranking], names[ranking] FROM t JOIN t1 on (t.id = t1.tid)
+UPDATE t SET scores[2] = 123, names[2] = 'Reds' WHERE id = 10
+</pre>
+</div>
+</p>
+<p></p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10706"></a>Array Operations</h3>
+</div>
+</div>
+</div>
+<p>Several SQL operations and functions can be used with
+      arrays.</p>
+<p>
+<span class="emphasis"><em>CONCATENATION</em></span>
+</p>
+<p>Array concatenation is performed similar to string concatenation.
+      All elements of the array on the right are appended to the array on
+      left.</p>
+<p>
+<code class="literal">&lt;array concatenation&gt; ::= &lt;array value
+      expression 1&gt; &lt;concatenation operator&gt; &lt;array value
+      expression 2&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;concatenation operator&gt; ::= ||</code>
+</p>
+<p>
+<span class="emphasis"><em>FUNCTIONS</em></span>
+</p>
+<p>Three functions operate on arrays. Details are described in the
+      <a class="link" href="#builtinfunctions-chapt" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+<p>
+<code class="literal">CARDINALITY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">MAX_CARDINALITY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;right paren&gt;</code>
+</p>
+<p>Array cardinality and max cardinality are functions that return an
+      integer. CARDINALITY returns the element count, while MAX_CARDINALITY
+      returns the maximum declared cardinality of an array.</p>
+<p>
+<code class="literal">TRIM_ARRAY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;comma&gt; &lt;numeric value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>The TRIM_ARRAY function returns a copy of an array with the
+      specified number of elements removed from the end of the array. The
+      <code class="literal">&lt;array value expression&gt;</code> can be any expression
+      that evaluates to an array.</p>
+<p>
+<span class="emphasis"><em>CAST</em></span>
+</p>
+<p>An array can be cast into an array of a different type. Each
+      element of the array is cast into the element type of the target array
+      type.</p>
+<p>
+<span class="emphasis"><em>UNNEST</em></span>
+</p>
+<p>Arrays can be converted into table references with the UNNEST
+      keyword.</p>
+<p>
+<code class="literal">UNNEST(&lt;array value expression&gt;) [ WITH ORDINALITY
+      ]</code>
+</p>
+<p>The <code class="literal">&lt;array value expression&gt;</code> can be any
+      expression that evaluates to an array. A table is returned that contains
+      one column when WITH ORDINALITY is not used, or two columns when WITH
+      ORDINALITY is used. The first column contains the elements of the array
+      (including all the nulls). When the table has two columns, the second
+      column contains the ordinal position of the element in the array. When
+      UNNEST is used in the FROM clause of a query, it implies the LATERAL
+      keyword, which means the array that is converted to table can belong to
+      any table that precedes the UNNEST in the FROM clause. This is explained
+      in the <a class="link" href="#dataaccess-chapt" title="Chapter&nbsp;7.&nbsp;Data Access and Change">Data Access and Change</a> chapter.</p>
+<p>
+<span class="emphasis"><em>COMPARISON</em></span>
+</p>
+<p>Arrays can be compared for equality, but they cannot be compared
+      for ordering or ranges. Array expressions are therefore not allowed in
+      an ORDER BY clause, or in a comparison expression such as GREATER THAN.
+      Two arrays are equal if they have the same length and the values at each
+      index position are either equal or both NULL.</p>
+<p>
+<span class="emphasis"><em>USER DEFINED FUNCTIONS and PROCEDURES</em></span>
+</p>
+<p>Array parameters, variables and return values can be specified in
+      user defined functions and procedures, including aggregate functions. An
+      aggregate function can return an array that contains all the scalar
+      values that have been aggregated. These capabilities allow a wider range
+      of applications to be covered by user defined functions and easier data
+      exchange between the engine and the user's application.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_constr_indexes-sect"></a>Indexes and Query Speed</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL supports PRIMARY KEY, UNIQUE and FOREIGN KEY constraints,
+    which can span multiple columns.</p>
+<p>The engine creates indexes internally to support PRIMARY KEY, UNIQUE
+    and FOREIGN KEY constraints: a unique index is created for each PRIMARY
+    KEY or UNIQUE constraint; an ordinary index is created for each FOREIGN
+    KEY constraint.</p>
+<p>HyperSQL allows defining indexes on single or multiple columns. You
+    should not create duplicate user-defined indexes on the same column sets
+    covered by constraints. This would result in unnecessary memory and speed
+    overheads. See the discussion in the <a class="link" href="#deployment-chapt" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">System Management and Deployment
+  Issues</a> chapter for more
+    information.</p>
+<p>Indexes are crucial for adequate query speed. When range or equality
+    conditions are used e.g. <code class="literal">SELECT ... WHERE acol &gt; 10 AND bcol =
+    0</code>, an index should exist on one of the columns that has a
+    condition. In this example, the <code class="literal">bcol</code> column is the best
+    candidate. HyperSQL always uses the best condition and index. If there are
+    two indexes, one on acol, and another on bcol, it will choose the index on
+    bcol.</p>
+<p>Queries always return results whether indexes exist or not, but they
+    return much faster when an index exists. As a rule of thumb, HSQLDB is
+    capable of internal processing of queries at over 100,000 rows per second.
+    Any query that runs into several seconds is clearly accessing thousands of
+    rows. The query should be checked and indexes should be added to the
+    relevant columns of the tables if necessary. The EXPLAIN PLAN
+    &lt;query&gt; statement can be used to see which indexes are used to
+    process the query.</p>
+<p>When executing a DELETE or UPDATE statement, the engine needs to
+    find the rows that are to be deleted or updated. If there is an index on
+    one of the columns in the WHERE clause, it is often possible to start
+    directly from the first candidate row. Otherwise all the rows of the table
+    have to be examined.</p>
+<p>Indexes are even more important in joins between multiple tables.
+    <code class="literal">SELECT ... FROM t1 JOIN t2 ON t1.c1 = t2.c2 </code> is
+    performed by taking rows of t1 one by one and finding a matching row in
+    t2. If there is no index on t2.c2 then for each row of t1, all the rows of
+    t2 must be checked. Whereas with an index, a matching row can be found in
+    a fraction of the time. If the query also has a condition on t1, e.g.,
+    <code class="literal">SELECT ... FROM t1 JOIN t2 ON t1.c1 = t2.c2 WHERE t1.c3 =
+    4</code> then an index on t1.c3 would eliminate the need for checking
+    all the rows of t1 one by one, and will reduce query time to less than a
+    millisecond per returned row. So if t1 and t2 each contain 10,000 rows,
+    the query without indexes involves checking 100,000,000 row combinations.
+    With an index on t2.c2, this is reduced to 10,000 row checks and index
+    lookups. With the additional index on t2.c2, only about 4 rows are checked
+    to get the first result row.</p>
+<p>Note that in HSQLDB an index on multiple columns can be used
+    internally as a non-unique index on the first column in the list. For
+    example: <code class="literal">CONSTRAINT name1 UNIQUE (c1, c2, c3); </code> means
+    there is the equivalent of <code class="literal">CREATE INDEX name2 ON
+    atable(c1);</code>. So you do not need to specify an extra index if you
+    require one on the first column of the list.</p>
+<p>In HyperSQL 2.0, a multi-column index will speed up queries that
+    contain joins or values on the first n columns of the index. You need NOT
+    declare additional individual indexes on those columns unless you use
+    queries that search only on a subset of the columns. For example, rows of
+    a table that has a PRIMARY KEY or UNIQUE constraint on three columns or
+    simply an ordinary index on those columns can be found efficiently when
+    values for all three columns, or the first two columns, or the first
+    column, are specified in the WHERE clause. For example, <code class="literal">SELECT
+    ... FROM t1 WHERE t1.c1 = 4 AND t1.c2 = 6 AND t1.c3 = 8 </code>will use
+    an index on <code class="literal">t1(c1,c2,c3)</code> if it exists.</p>
+<p>A multi-column index will not speed up queries on the second or
+    third column only. The first column must be specified in the JOIN .. ON or
+    WHERE conditions.</p>
+<p>Sometimes query speed depends on the order of the tables in the JOIN
+    .. ON or FROM clauses. For example the second query below should be faster
+    with large tables (provided there is an index on
+    <code class="literal">TB.COL3</code>). The reason is that <code class="literal">TB.COL3</code>
+    can be evaluated very quickly if it applies to the first table (and there
+    is an index on <code class="literal">TB.COL3</code>):</p>
+<div class="informalexample">
+<pre class="programlisting">    (TB is a very large table with only a few rows where TB.COL3 = 4)
+
+    SELECT * FROM TA JOIN TB ON TA.COL1 = TB.COL2 AND TB.COL3 = 4;
+
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 AND TB.COL3 = 4;</pre>
+</div>
+<p>The general rule is to put first the table that has a narrowing
+    condition on one of its columns.</p>
+<p>HyperSQL features automatic, on-the-fly indexes for views and
+    subselects that are used in a query.</p>
+<p>Indexes have no effect on some LIKE conditions.</p>
+<p>Indexes are used for ORDER BY clauses if the same index is used for
+    selection and ordering of rows.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1079B"></a>Query Processing and Optimisation</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL does not change the order of tables in a query in order to
+    optimise processing. As mentioned in the previous section, the table that
+    has a narrowing condition should be the first table in the query.</p>
+<p>HyperSQL optimises queries to use indexes, for all types of range
+    and equality conditions, including IS NULL and NOT NULL conditions.
+    Conditions can be in join or WHERE clauses, including all types of
+    joins.</p>
+<p>In addition, HyperSQL will always use an index (if one exists) for
+    IN conditions, whether constants, variable, or subqueries are used on the
+    right hand side of the IN predicate.</p>
+<p>HyperSQL can always use indexes when several conditions are combined
+    with the AND operator, choosing a conditions which can use an index. This
+    now extended to all equality conditions on multiple columns that are part
+    of an index.</p>
+<p>HyperSQL will also use indexes when several conditions are combined
+    with the OR operator and each condition can use an index (each condition
+    may use a different index). For example, if a huge table has two separate
+    columns for first name and last name, and both columns are indexed, a
+    query such as the following example will use the indexes and complete in a
+    short time:</p>
+<div class="informalexample">
+<pre class="programlisting">    (TC is a very large table)
+
+    SELECT * FROM TC WHERE TC.FIRSTNAME = 'John' OR TC.LASTNAME = 'Smith' OR TC.LASTNAME = 'Williams'
+</pre>
+</div>
+<p>HyperSQL optimises simple row count queries in the form of SELECT
+    COUNT(*) FROM &lt;table&gt; and returns the result immediately (this
+    optimisation does not take place in MVCC mode).</p>
+<p>HyperSQL can use an index on a column for SELECT MAX(&lt;column&gt;)
+    FROM &lt;table&gt; and SELECT MIN(&lt;column&gt;) FROM &lt;table&gt;
+    queries. There should be an index on the &lt;column&gt; and the query can
+    have a WHERE condition on the same column. In the example below the
+    maximum value for the TB.COL3 below 1000000 is returned.</p>
+<div class="informalexample">
+<pre class="programlisting">    SELECT MAX(TB.COL3) FROM TB WHERE TB.COL &lt; 1000000
+</pre>
+</div>
+<p>HyperSQL can use an index on an ORDER BY clause if all the columns
+    in ORDER BY are in a single-column or multi-column index (in the exact
+    order). This is important if there is a LIMIT n (or FETCH n ROWS ONLY)
+    clause. In this situation, the use of index allows the query processor to
+    access only the number of rows specified in the LIMIT clause, instead of
+    building the whole result set, which can be huge. This also works for
+    joined tables when the ORDER BY clause is on the columns of the first
+    table in a join. Indexes are used in the same way when ORDER BY ... DESC
+    is specified in the query. Note that unlike other RDBMS, HyperSQL does not
+    create DESC indexes. It can use any index for ORDER BY ... DESC.</p>
+<p>If there is an equality or range condition (e.g. EQUALS, GREATER
+    THAN) condition on the columns specified in the ORDER BY clause, the index
+    is still used. But if the query contains an equality condition on another
+    indexed column in the table, this may take precedence and no index may be
+    used for ORDER BY.</p>
+<p>In the two examples below, the index on TB.COL3 is used and only up
+    to 1000 rows are processed and returned.</p>
+<div class="informalexample">
+<pre class="programlisting">    (TB is a very large table with an index on TB.COL3
+
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 WHERE TB.COL3 &gt; 40000 ORDER BY TB.COL3 LIMIT 1000;
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 WHERE TB.COL3 &gt; 40000 AND TB.COL3 &lt; 100000 ORDER BY TB.COL3 DESC LIMIT 1000;
+</pre>
+</div>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sessions-chapt"></a>Chapter&nbsp;3.&nbsp;Sessions and Transactions</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N107DF"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N107E2">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10801">Session Attributes and Variables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10806">Session Attributes</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10814">Session Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10822">Session Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqlgeneral_trans_cc-sect">Transactions and Concurrency Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10846">Two Phase Locking</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10859">Two Phase Locking with Snapshot Isolation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10862">Lock Contention in 2PL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1086D">MVCC</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1087A">Choosing the Transaction Model</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10887">Schema and Database Change</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10892">Simultaneous Access to Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N10899">Session and Transaction Control Statements</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N107E2"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>All SQL statements are executed in sessions. When a connection is
+    established to the database, a session is started. The authorization of
+    the session is the name of the user that started the session. A session
+    has several properties. These properties are set by default at the start
+    according to database settings.</p>
+<p>SQL Statements are generally transactional statements. When a
+    transactional statement is executed, it starts a transaction if no
+    transaction is in progress. If SQL Data is modified during a transaction,
+    the change can be undone with a ROLLBACK statement. When a COMMIT
+    statement is executed, the transaction is ended. If a single statement
+    fails, the transaction is not normally terminated. However, some failures
+    are caused by execution of statements that are in conflict with statements
+    executed in other concurrent sessions. Such failures result in an implicit
+    ROLLBACK, in addition to the exception that is raised.</p>
+<p>Schema definition and manipulation statements are also transactional
+    according to the SQL Standard. HyperSQL 2.0 performs automatic commits
+    before and after the execution of such transactions. Therefore,
+    schema-related statements cannot be rolled back. This is likely to change
+    in future versions.</p>
+<p>Some statements are not transactional. Most of these statements are
+    used to change the properties of the session. These statements begin with
+    the SET keyword.</p>
+<p>If the AUTOCOMMIT property of a session is TRUE, then each
+    transactional statement is followed by an implicit COMMIT.</p>
+<p>The default isolation level for a session is READ COMMITTED. This
+    can be changed using the JDBC <code class="classname">java.sql.Connection</code>
+    object and its <code class="methodname">setTransactionIsolation(int level)</code>
+    method. The session can be put in read-only mode using the
+    <code class="methodname">setReadOnly(boolean readOnly)</code> method. Both
+    methods can be invoked only after a commit or a rollback, but not during a
+    transaction.</p>
+<p>The isolation level and / or the readonly mode of a transaction
+    can also be modified using an SQL statement. You can use the statement to
+    change only the isolation mode, only the read-only mode, or both at the
+    same time. This command can be issued only after a commit or
+    rollback.</p>
+<p>
+<code class="literal">SET TRANSACTION &lt;transaction characteristic&gt; [
+    &lt;comma&gt; &lt;transaction characteristic&gt; ]</code>
+</p>
+<p>Details of the statement is described later in this chapter.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10801"></a>Session Attributes and Variables</h2>
+</div>
+</div>
+</div>
+<p>Each session has several system attributes. A session can also have
+    user-defined session variables.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10806"></a>Session Attributes</h3>
+</div>
+</div>
+</div>
+<p>The system attributes reflect the current mode of operation for
+      the session. These attributes can be accessed with function calls and
+      can be referenced in queries. For example, they can be returned using
+      the <code class="literal">VALUES &lt;attribute function&gt;, ...</code>
+      statement.</p>
+<p>The named attributes such as CURRENT_USER, CURRENT_SCHEMA, etc.
+      are SQL Standard functions. Other attributes of the session, such as
+      auto-commit or read-only modes can be read using other built-in
+      functions. All these functions are listed in the <a class="link" href="#builtinfunctions-chapt" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10814"></a>Session Variables</h3>
+</div>
+</div>
+</div>
+<p>Session variables are user-defined variables created the same way
+      as the variables for stored procedures and functions. Currently, these
+      variables cannot be used in general SQL statements. They can be assigned
+      to IN, INOUT and OUT parameters of stored procedures. This allows
+      calling stored procedures which have INOUT or OUT arguments and is
+      useful for development and debugging. See the example in the <a class="link" href="#sqlroutines-chapt" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">SQL-Invoked Routines</a>
+      chapter, under Formal Parameters.</p>
+<div class="example">
+<a name="N1081D"></a>
+<p class="title">
+<b>Example&nbsp;3.1.&nbsp;User-defined Session Variables</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  DECLARE counter INTEGER DEFAULT 3;
+  DECLARE result VARCHAR(20) DEFAULT NULL;
+  SET counter=15;
+  CALL myroutine(counter, result)
+</pre>
+</div>
+</div>
+<br class="example-break">
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10822"></a>Session Tables</h3>
+</div>
+</div>
+</div>
+<p>With necessary access privileges, sessions can access all table,
+      including GLOBAL TEMPORARY tables, that are defined in schemas. Although
+      GLOBAL TEMPORARY tables have a single name and definition which applies
+      to all sessions that use them, the contents of the tables are different
+      for each session. The contents are cleared either at the end of each
+      transaction or when the session is closed.</p>
+<p>Session tables are different because their definition is visible
+      only within the session that defines a table. The definition is dropped
+      when the session is closed. Session tables do not belong to
+      schemas.</p>
+<p>
+<code class="literal">&lt;temporary table declaration&gt; ::= DECLARE LOCAL
+      TEMPORARY TABLE &lt;table name&gt; &lt;table element list&gt; [ ON
+      COMMIT { PRESERVE | DELETE } ROWS ]</code>
+</p>
+<p>The syntax for declaration is based on the SQL Standard. A session
+      table cannot have FOREIGN KEY constraints, but it can have PRIMARY KEY,
+      UNIQUE or CHECK constraints. A session table definition cannot be
+      modified by adding or removing columns, indexes, etc.</p>
+<p>It is possible to refer to a session table using its name, which
+      takes precedence over a schema table of the same name. To distinguish a
+      session table from schema tables, the pseudo schema name, MODULE can be
+      used. An example is given below:</p>
+<p>
+<div class="example">
+<a name="N10831"></a>
+<p class="title">
+<b>Example&nbsp;3.2.&nbsp;User-defined Temporary Session Tables</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  DECLARE LOCAL TEMPORARY TABLE buffer (id INTEGER PRIMARY KEY, textdata VARCHAR(100)) ON COMMIT PRESERVE ROWS
+  INSERT INTO module.buffer SELECT id, firstname || ' ' || lastname FROM customers
+  -- do some more work
+  DROP TABLE module.buffer
+</pre>
+</div>
+</div>
+<br class="example-break">Session tables can be created inside a transaction.
+      Automatic indexes are created and used on session tables when necessary
+      for a query or other statement. By default, session table data is held
+      in memory. If the session property</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_trans_cc-sect"></a>Transactions and Concurrency Control</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL 2.0 has been fully redesigned to support different
+    transaction isolation models. It no longer supports the old 1.8.x model
+    with "dirty read". Although it is perfectly possible to add an
+    implementation of the transaction manager that supports the legacy model,
+    we thought this is no longer necessary. The new system allows you to
+    select the transaction isolation model even while the engine is running
+    and choose different isolation modes for different simultaneous
+    sessions.</p>
+<p>HyperSQL 2.0 supports three concurrency control models,
+    two-phase-locking (2PL), which is the default, multiversion concurrency
+    control (MVCC) and a hybrid model, which is 2PL plus multiversion rows.
+    Within each model, it supports some of 4 levels of transaction isolation:
+    READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ and SERIALIZABLE. The
+    isolation level is a property of each SQL session, so different sessions
+    can have different isolation levels. The concurrency control model is a
+    strategy that governs all the sessions and is set for the database, as
+    opposed for individual sessions. In the new implementation, all isolation
+    levels avoid the "dirty read" phenomenon and do not read uncommitted
+    changes made to rows by other transactions.</p>
+<p>HyperSQL is fully multi threaded in all transaction models. Sessions
+    continue to work simultaneously and can fully utilise multi-core
+    processors.</p>
+<p>To change the concurrency control model, the <code class="literal">SET DATABASE
+    TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC }</code> can be used by a
+    user with the DBA role.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10846"></a>Two Phase Locking</h3>
+</div>
+</div>
+</div>
+<p>The two-phase locking model is the default mode. It is referred to
+      by the keyword, LOCKS. In the 2PL model, each table that is read by a
+      transaction is locked with a shared lock, and each table that is written
+      to is locked with an exclusive lock. If two sessions read and modify
+      different tables then both go through simultaneously. If one session
+      tries to lock a table that has been locked by the other, if both locks
+      are shared locks, it will go ahead. If either of the locks is an
+      exclusive lock, the engine will put the session in wait until the other
+      session commits or rolls back its transaction. In some cases the engine
+      will invalidate the transaction of the current session, if the action
+      would result in deadlock.</p>
+<p>HyperSQL also supports explicit locking of a group of tables for
+      the duration of the current transaction. Use of this command blocks
+      access to the locked tables by other sessions and ensures the current
+      session can complete the intended reads and writes on the locked
+      tables.</p>
+<p>If a table is read-only, it will not be locked by any
+      transaction.</p>
+<p>The READ UNCOMMITTED isolation level can be used in 2PL modes for
+      read-only operations. It is the same as READ COMMITTED plus read
+      only.</p>
+<p>The READ COMMITTED isolation level is the default. It keeps write
+      locks on tables until commit, but releases the read locks after each
+      operation.</p>
+<p>The REPEATABLE READ level is upgraded to SERIALIZABLE. These
+      levels keep both read and write locks on tables until commit.</p>
+<p>It is possible to perform some critical operations at the
+      SERIALIZABLE level, while the rest of the operations are performed at
+      the READ COMMITTED level.</p>
+<p>Note: two phase locking refers to two periods in the life of a
+      transaction. In the first period, locks are acquired, in the second
+      period locks are released. No new lock is acquired after releasing a
+      lock.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10859"></a>Two Phase Locking with Snapshot Isolation</h3>
+</div>
+</div>
+</div>
+<p>This model is referred to as MVLOCKS. It works the same way as
+      normal 2PL as far as updates are concerned.</p>
+<p>SNAPSHOT ISOLATION is a multiversion concurrency strategy which
+      uses the snapshot of the whole database at the time of the start of the
+      transaction. In this model, read only transactions use SNAPSHOT
+      ISOLATION. While other sessions are busy changing the database, the read
+      only session sees a consistent view of the database and can access all
+      the tables even when they are locked by other sessions for
+      updates.</p>
+<p>There are many applications for this mode of operation. In heavily
+      updated data sets, this mode allows uninterrupted read access to the
+      data.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10862"></a>Lock Contention in 2PL</h3>
+</div>
+</div>
+</div>
+<p>When multiple connections are used to access the database, the
+      transaction manager controls their activities. When each transaction
+      performs only reads or writes on a single table, there is no contention.
+      Each transaction waits until it can obtain a lock then performs the
+      operation and commits. All contentions occur when transactions perform
+      reads and writes on more than one table, or perform a read, followed by
+      a write, on the same table.</p>
+<p>For example, when sessions are working at the SERIALIZABLE level,
+      when multiple sessions first read from a table in order to check if a
+      row exists, then insert a row into the same table when it doesn't exist,
+      there will be regular contention. Transaction A reads from the table,
+      then does Transaction B. Now if either Transaction A or B attempts to
+      insert a row, it will have to be terminated as the other transaction
+      holds a shared lock on the table. If instead of two operations, a single
+      MERGE statement is used to perform the read and write, no contention
+      occurs because both locks are obtained at the same time.</p>
+<p>Alternatively, there is the option of obtaining the necessary
+      locks with an explicit LOCK TABLE statement. This statement should be
+      executed before other statements and should include the names of all the
+      tables and the locks needed. After this statement, all the other
+      statements in the transaction can be executed and the transaction
+      committed. The commit will remove all the locks.</p>
+<p>HyperSQL is fully multi threaded. It therefore allows different
+      transactions to execute concurrently so long as they are not modifying
+      the same table.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1086D"></a>MVCC</h3>
+</div>
+</div>
+</div>
+<p>In the MVCC model, there are no shared, read locks. Exclusive
+      locks are used on individual rows, but their use is different.
+      Transactions can read and modify the same table simultaneously,
+      generally without waiting for other transactions.</p>
+<p>When transactions are running at READ COMMITTED level, no conflict
+      will normally occur. If a transaction that runs at this level wants to
+      modify a row that has been modified by another uncommitted transaction,
+      then the engine puts the transaction in wait, until the other
+      transaction has committed. The transaction then continues automatically.
+      (Conflict is possible if each transaction is waiting for a different row
+      modified by the other transaction, in which case, one of the
+      transactions is terminated). This isolation level is called READ
+      CONSISTENCY.</p>
+<p>When transactions are running in REPEATABLE READ or SERIALIZABLE
+      isolation levels, conflict is more likely to happen. There is no
+      difference in operation between these two isolation levels. If a
+      transaction that runs at these levels wants to modify a row that has
+      been modified by another uncommitted transaction, the engine will
+      invalidate the current transaction and roll back all its changes. This
+      isolation level is called SNAPSHOT ISOLATION.</p>
+<p>In the MVCC model, READ UNCOMMITTED is promoted to READ COMMITTED,
+      as the new architecture is based on multi-version rows for uncommitted
+      data and more than one version may exist for some rows.</p>
+<p>With MVCC, when a transaction only reads data, then it will go
+      ahead and complete regardless of what other transactions may do. This
+      does not depend on the transaction being read-only or the isolation
+      modes.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1087A"></a>Choosing the Transaction Model</h3>
+</div>
+</div>
+</div>
+<p>The SQL Standard defines the isolation levels as modes of
+      operation that avoid the three unwanted phenomena, "dirty read", "fuzzy
+      read" and "phantom row". The "dirty read" phenomenon occurs when a
+      session can read a row that has been changed by another session. The
+      "fuzzy read" phenomenon occurs when a row that was read by a session is
+      modified by another session, then the first session reads the row again.
+      The "phantom row" phenomenon occurs when a session performs an operation
+      that affects several rows, for example, counts the rows or modifies them
+      using a search condition, then another session adds one or more rows
+      that fulfil the same search condition, then the first session performs
+      an operation that relies on the results of its last operation. According
+      to the Standard, the SERIALIZABLE isolation level avoids all three
+      phenomena and also ensures that all the changes performed during a
+      transaction can be considered as a series of uninterrupted changes to
+      the database without any other transaction changing the database at all
+      for the duration of these actions. The changes made by other
+      transactions are considered to occur before the SERIALIZABLE transaction
+      starts, or after it ends. The READ COMMITTED level avoids "dirty read"
+      only, while the REPEATABLE READ level avoids "dirty read" and "fuzzy
+      read", but not "phantom row".</p>
+<p>The Standard allows the engine to return a higher isolation level
+      than requested by the application. HyperSQL promotes a READ UNCOMMITTED
+      request to READ COMMITTED and promotes a REPEATABLE READ request to
+      SERIALIZABLE.</p>
+<p>The MVCC model is not covered directly by the Standard. Research
+      has established that the READ CONSISTENCY level fulfills the
+      requirements of (and is stronger than) the READ COMMITTED level. The
+      SNAPSHOT ISOLATION level is stronger than the READ CONSISTENCY level. It
+      avoids the three anomalies defined by the Standard, and is therefore
+      stronger than the REPEATABLE READ level as defined by the Standard. When
+      operating with the MVCC model, HyperSQL treats a REPEATABLE READ or
+      SERIALIZABLE setting for a transaction as SNAPSHOT ISOLATION.</p>
+<p>All modes can be used with as many simultaneous connections as
+      required. The default 2PL model is fine for applications with a single
+      connection, or applications that do not access the same tables heavily
+      for writes. With multiple simultaneous connections, MVCC can be used for
+      most applications. Both READ CONSISTENCY and SNAPSHOT ISOLATION levels
+      are stronger than the corresponding READ COMMITTED level in the 2PL
+      mode. Some applications require SERIALIZABLE transactions for at least
+      some of their operations. For these applications, one of the 2PL modes
+      can be used. It is possible to switch the concurrency model while the
+      database is operational. Therefore, the model can be changed for the
+      duration of some special operations, such as synchronization with
+      another data source.</p>
+<p>All concurrency models are very fast in operation. When operating
+      mainly on the same tables, the MVCC model may be faster with multiple
+      processors.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10887"></a>Schema and Database Change</h3>
+</div>
+</div>
+</div>
+<p>There are a few SQL statements that must access a consistent state
+      of the database during their executions. These statements, which include
+      CHECKPOINT and BACKUP, put an exclusive lock on all the tables of the
+      database when they start.</p>
+<p>Some schema manipulation statements put an exclusive lock on one
+      or more tables. For example changing the columns of a table locks the
+      table exclusively.</p>
+<p>In the MVCC model, all statements that need an exclusive lock on
+      one or more tables, put an exclusive lock on the database catalog until
+      they complete.</p>
+<p>The effect of these exclusive locks is similar to the execution of
+      data manipulation statements with write locks. The session that is about
+      to execute the schema change statement waits until no other session is
+      holding a lock on any of the objects. At this point it starts its
+      operation and locks the objects to prevents any other session from
+      accessing the locked objects. As soon as the operation is complete, the
+      locks are all removed.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10892"></a>Simultaneous Access to Tables</h3>
+</div>
+</div>
+</div>
+<p>It was mentioned that there is no limit on the number of sessions
+      that can access the tables and all sessions work simultaneously in multi
+      threaded execution. However there are internal resources that are
+      shared. Simultaneous access to these resources reduces the overall
+      efficiency of the system. MEMORY and TEXT tables do not share resources
+      and do not block multi threaded access. With CACHED tables, each write
+      operation blocks the file and its cache until the operation is finished.
+      With CACHED tables, SELECT operations do not block each other, but
+      selecting from different tables and different parts of a large table
+      causes the row cache to be updated frequently and will reduce overall
+      performance.</p>
+<p>The new access pattern is the opposite of the access pattern of
+      version 1.8.x. In the old version, even when 20 sessions are actively
+      reading and writing, only a single session at a time performs an SQL
+      statement completely, before the next session is allowed access. In the
+      new version, while a session is performing a SELECT statement and
+      reading rows of a CACHED table to build a result set, another session
+      may perform an UPDATE statement that reads and writes rows of the same
+      table. The two operations are performed without any conflict, but the
+      row cache is updated more frequently than when one operation is
+      performed after the other operation has finished.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10899"></a>Session and Transaction Control Statements</h2>
+</div>
+</div>
+</div>
+<a name="N1089D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET AUTOCOMMIT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set autocommit command</em></span>
+</p>
+<p>
+<code class="literal">&lt;set autocommit statement&gt; ::= SET AUTOCOMMIT {
+    TRUE | FALSE }</code>
+</p>
+<p>When an SQL session is started by creating a JDBC connection, it
+    is in AUTOCOMMIT mode. In this mode, after each SQL statement a COMMIT is
+    performed automatically. This statement changes the mode. It is equivalent
+    to using the <code class="methodname">setAutoCommit( boolean autoCommit)</code>
+    method of the JDBC <code class="classname">Connection</code> object.</p>
+<a name="N108B4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>START TRANSACTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>start transaction statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;start transaction statement&gt; ::= START
+    TRANSACTION [ &lt;transaction characteristics&gt; ]</code>
+</p>
+<p>Start an SQL transaction and set its characteristics. All
+    transactional SQL statements start a transaction automatically, therefore
+    using this statement is not necessary. If the statement is called in the
+    middle of a transaction, an exception is thrown.</p>
+<a name="N108C5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE TRANSACTION
+    CONTROL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database transaction control</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database transaction control statement&gt; ::=
+    SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC
+    }</code>
+</p>
+<p>Set the concurrency control model for the whole database. It will
+    wait until all sessions have been committed or rolled back. The default is
+    LOCKS.</p>
+<a name="N108D6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TRANSACTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set next transaction
+    characteristics</em></span>
+</p>
+<p>
+<code class="literal">&lt;set transaction statement&gt; ::= SET [ LOCAL ]
+    TRANSACTION &lt;transaction characteristics&gt;</code>
+</p>
+<p>Set the characteristics of the next transaction in the current
+    session. This statement has an effect only on the next transactions and
+    has no effect on the future transactions after the next.</p>
+<a name="N108E7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>transaction
+    characteristics</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>transaction characteristics</em></span>
+</p>
+<p>
+<code class="literal">&lt;transaction characteristics&gt; ::= [
+    &lt;transaction mode&gt; [ { &lt;comma&gt; &lt;transaction mode&gt; }... ]
+    ]</code>
+</p>
+<p>
+<code class="literal">&lt;transaction mode&gt; ::= &lt;isolation level&gt; |
+    &lt;transaction access mode&gt; | &lt;diagnostics
+    size&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transaction access mode&gt; ::= READ ONLY | READ
+    WRITE</code>
+</p>
+<p>
+<code class="literal">&lt;isolation level&gt; ::= ISOLATION LEVEL &lt;level of
+    isolation&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;level of isolation&gt; ::= READ UNCOMMITTED | READ
+    COMMITTED | REPEATABLE READ | SERIALIZABLE</code>
+</p>
+<p>
+<code class="literal">&lt;diagnostics size&gt; ::= DIAGNOSTICS SIZE &lt;number
+    of conditions&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;number of conditions&gt; ::= &lt;simple value
+    specification&gt;</code>
+</p>
+<p>Specify transaction characteristics.</p>
+<div class="example">
+<a name="N1090A"></a>
+<p class="title">
+<b>Example&nbsp;3.3.&nbsp;Setting Transaction Characteristics</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  SET TRANSACTION READ ONLY
+  SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
+  SET TRANSACTION READ WRITE, ISOLATION LEVEL READ COMMITTED
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N1090F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET CONSTRAINTS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set constraints mode statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set constraints mode statement&gt; ::= SET
+    CONSTRAINTS &lt;constraint name list&gt; { DEFERRED | IMMEDIATE
+    }</code>
+</p>
+<p>
+<code class="literal">&lt;constraint name list&gt; ::= ALL | &lt;constraint
+    name&gt; [ { &lt;comma&gt; &lt;constraint name&gt; }...
+    ]</code>
+</p>
+<p>If the statement is issued during a transaction, it applies to
+    the rest of the current transaction. If the statement is issued when a
+    transaction is not active then it applies only to the next transaction in
+    the current session. HyperSQL does not yet support this feature.</p>
+<a name="N10923" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOCK TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>lock table statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;lock table statement&gt; ::= LOCK TABLE &lt;table
+    name&gt; { READ | WRITE} [, &lt;table name&gt; { READ | WRITE}
+    ...]}</code>
+</p>
+<p>In some circumstances, where multiple simultaneous transactions
+    are in progress, it may be necessary to ensure a transaction consisting of
+    several statements is completed, without being terminated due to possible
+    deadlock. When this statement is executed, it waits until it can obtain
+    all the listed locks, then returns. The SQL statements following this
+    statements use the locks already obtained (and obtain new locks if
+    necessary) and can proceed without waiting. All the locks are released
+    when a COMMIT or ROLLBACK statement is issued. Currently, this command
+    does not have any effect when the database transaction control model is
+    MVCC.</p>
+<div class="example">
+<a name="N10934"></a>
+<p class="title">
+<b>Example&nbsp;3.4.&nbsp;Locking Tables</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  LOCK TABLE table_a WRITE, table_b READ</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N10939" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SAVEPOINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>savepoint statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;savepoint statement&gt; ::= SAVEPOINT &lt;savepoint
+    specifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;savepoint specifier&gt; ::= &lt;savepoint
+    name&gt;</code>
+</p>
+<p>Establish a savepoint. This command is used during an SQL
+    transaction. It establishes a milestone for the current transaction. The
+    SAVEPOINT can be used at a later point in the transaction to rollback the
+    transaction to the milestone.</p>
+<a name="N1094D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RELEASE SAVEPOINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>release savepoint statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;release savepoint statement&gt; ::= RELEASE
+    SAVEPOINT &lt;savepoint specifier&gt;</code>
+</p>
+<p>Destroy a savepoint. This command is rarely used as it is not
+    very useful. It removes a SAVEPOINT that has already been
+    defined.</p>
+<a name="N1095E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COMMIT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>commit statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;commit statement&gt; ::= COMMIT [ WORK ] [ AND [ NO
+    ] CHAIN ]</code>
+</p>
+<p>Terminate the current SQL-transaction with commit. This make all
+    the changes to the database permanent.</p>
+<a name="N1096F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ROLLBACK</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>rollback statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;rollback statement&gt; ::= ROLLBACK [ WORK ] [ AND [
+    NO ] CHAIN ]</code>
+</p>
+<p>Rollback the current SQL transaction and terminate it. The
+    statement rolls back all the actions performed during the transaction. If
+    NO CHAIN is specified, a new SQL transaction is started just after the
+    rollback. The new transaction inherits the properties of the old
+    transaction.</p>
+<a name="N10980" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ROLLBACK TO SAVEPOINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>rollback statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;rollback statement&gt; ::= ROLLBACK [ WORK ] TO
+    SAVEPOINT &lt;savepoint specifier&gt;</code>
+</p>
+<p>Rollback part of the current SQL transaction and continue the
+    transaction. The statement rolls back all the actions performed after the
+    specified SAVEPOINT was created. The same effect can be achieved with the
+    <code class="literal">rollback( Savepoint savepoint)</code> method of the JDBC
+    <code class="classname">Connection</code> object.</p>
+<div class="example">
+<a name="N10997"></a>
+<p class="title">
+<b>Example&nbsp;3.5.&nbsp;Rollback</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  -- perform some inserts, deletes, etc.
+  SAVEPOINT A
+  -- perform some inserts, deletes, selects etc.
+  ROLLBACK WORK TO SAVEPOINT A
+  -- all the work after the declaration of SAVEPOINT A is rolled back
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N1099D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DISCONNECT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>disconnect statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;disconnect statement&gt; ::=
+    DISCONNECT</code>
+</p>
+<p>Terminate the current SQL session. Closing a JDBC connection has
+    the same effect as this command.</p>
+<a name="N109AF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET SESSION
+    CHARACTERISTICS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set session characteristics
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set session characteristics statement&gt; ::= SET
+    SESSION CHARACTERISTICS AS &lt;session characteristic
+    list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;session characteristic list&gt; ::= &lt;session
+    characteristic&gt; [ { &lt;comma&gt; &lt;session characteristic&gt; }...
+    ]</code>
+</p>
+<p>
+<code class="literal">&lt;session characteristic&gt; ::= &lt;session
+    transaction characteristics&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;session transaction characteristics&gt; ::=
+    TRANSACTION &lt;transaction mode&gt; [ { &lt;comma&gt; &lt;transaction
+    mode&gt; }... ]</code>
+</p>
+<p>Set one or more characteristics for the current SQL-session. This
+    command is used to set the transaction mode for the session. This endures
+    for all transactions until the session is closed or the next use of this
+    command. The current read-only mode can be accessed with the ISREADONLY()
+    function.</p>
+<div class="example">
+<a name="N109C9"></a>
+<p class="title">
+<b>Example&nbsp;3.6.&nbsp;Setting Session Characteristics</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY
+  SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE
+  SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE, ISOLATION LEVEL READ COMMITTED
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N109CE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET SESSION
+    AUTHORIZATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set session user identifier
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set session user identifier statement&gt; ::= SET
+    SESSION AUTHORIZATION &lt;value specification&gt;</code>
+</p>
+<p>Set the SQL-session user identifier. This statement changes the
+    current user. The user that executes this command must have the
+    CHANGE_AUTHORIZATION role, or the DBA role. After this statement is
+    executed, all SQL statements are executed with the privileges of the new
+    user. The current authorisation can be accessed with the CURRENT_USER and
+    SESSION_USER functions.</p>
+<div class="example">
+<a name="N109DF"></a>
+<p class="title">
+<b>Example&nbsp;3.7.&nbsp;Setting Session Authorization</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  SET SESSION AUTHORIZATION 'FELIX'
+  SET SESSION AUTHORIZATION SESSION_USER
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N109E4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET ROLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set role statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set role statement&gt; ::= SET ROLE &lt;role
+    specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;role specification&gt; ::= &lt;value
+    specification&gt; | NONE</code>
+</p>
+<p>Set the SQL-session role name and the current role name for the
+    current SQL-session context. The user that executes this command must have
+    the specified role. If NONE is specified, then the previous CURRENT_ROLE
+    is eliminated. The effect of this lasts for the lifetime of the session.
+    The current role can be accessed with the CURRENT_ROLE function.</p>
+<a name="N109F8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TIME ZONE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set local time zone statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set local time zone statement&gt; ::= SET TIME ZONE
+    &lt;set time zone value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;set time zone value&gt; ::= &lt;interval value
+    expression&gt; | LOCAL</code>
+</p>
+<p>Set the current default time zone displacement for the current
+    SQL-session. When the session starts, the time zone displacement is set to
+    the time zone of the client. This command changes the time zone
+    displacement. The effect of this lasts for the lifetime of the session. If
+    LOCAL is specified, the time zone displacement reverts to the local time
+    zone of the session.</p>
+<div class="example">
+<a name="N10A0C"></a>
+<p class="title">
+<b>Example&nbsp;3.8.&nbsp;Setting Session Time Zone</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    SET TIME ZONE LOCAL
+    SET TIME ZONE INTERVAL '+6:00' HOUR TO MINUTE
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N10A11" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET CATALOG</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set catalog statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set catalog statement&gt; ::= SET &lt;catalog name
+    characteristic&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;catalog name characteristic&gt; ::= CATALOG
+    &lt;value specification&gt;</code>
+</p>
+<p>Set the default schema name for unqualified names used in SQL
+    statements that are prepared or executed directly in the current sessions.
+    As there is only one catalog in the database, only the name of this
+    catalog can be used. The current catalog can be accessed with the
+    CURRENT_CATALOG function.</p>
+<a name="N10A25" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set schema statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set schema statement&gt; ::= SET &lt;schema name
+    characteristic&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema name characteristic&gt; ::= SCHEMA &lt;value
+    specification&gt; | &lt;schema name&gt;</code>
+</p>
+<p>Set the default schema name for unqualified names used in SQL
+    statements that are prepared or executed directly in the current sessions.
+    The effect of this lasts for the lifetime of the session. The SQL Standard
+    form requires the schema name as a single-quoted string. HyperSQL also
+    allows the use of the identifier for the schema. The current schema can be
+    accessed with the CURRENT_SCHEMA function.</p>
+<a name="N10A39" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET PATH</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set path statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set path statement&gt; ::= SET &lt;SQL-path
+    characteristic&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL-path characteristic&gt; ::= PATH &lt;value
+    specification&gt;</code>
+</p>
+<p>Set the SQL-path used to determine the subject routine of routine
+    invocations with unqualified routine names used in SQL statements that are
+    prepared or executed directly in the current sessions. The effect of this
+    lasts for the lifetime of the session.</p>
+<a name="N10A4D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET MAXROWS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set max rows statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set max rows statement&gt; ::= SET MAXROWS
+    &lt;unsigned integer literal&gt;</code>
+</p>
+<p>The normal operation of the session has no limit on the number of
+    rows returned from a SELECT statement. This command set the maximum number
+    of rows of the result returned by executing queries.</p>
+<p>This statement has a similar effect to the
+    <code class="methodname">setMaxRows(int max)</code> method of the JDBC
+    <code class="classname">Statement</code> interface, but it affects the results
+    returned from the next statement execution only. After the execution of
+    the next statement, the MAXROWS limit is removed.</p>
+<p>Only zero or positive values can be used with this command. The
+    value overrides any value specified with <code class="methodname">setMaxRows(int
+    max)</code> method of a JDBC statement. The statement <code class="literal">SET
+    MAXROWS 0</code> means no limit.</p>
+<p>It is possible to limit the number of rows returned from SELECT
+    statements with the FETCH &lt;n&gt; ROWS ONLY, or its alternative, LIMIT
+    &lt;n&gt;. Therefore this command is not recommended for general use. The
+    only legitimate use of this command is for checking and testing queries
+    that may return very large numbers of rows.</p>
+<a name="N10A70" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET SESSION RESULT MEMORY
+    ROWS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set session result memory rows
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set session result memory rows statement&gt; ::= SET
+    SESSION RESULT MEMORY ROWS &lt;unsigned integer
+    literal&gt;</code>
+</p>
+<p>By default the session uses memory to build result sets, subquery
+    results and temporary tables. This command sets the maximum number of rows
+    of the result (and temporary tables) that should be kept in memory. If the
+    row count of the result or temporary table exceeds the setting, the result
+    is stored on disk. The default is 0, meaning all result sets are held in
+    memory.</p>
+<p>This statement applies to the current session only. The general
+    database setting is:</p>
+<p>
+<code class="literal">SET DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned
+    integer literal&gt;</code>
+</p>
+<a name="N10A86" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET IGNORECASE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set ignore case statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set ignore case statement&gt; ::= SET IGNORECASE {
+    TRUE | FALSE }</code>
+</p>
+<p>Sets the type used for new VARCHAR table columns. By default,
+    character columns in new databases are case sensitive. If <code class="literal">SET
+    IGNORECASE TRUE</code> is used, all VARCHAR columns in new tables are
+    set to <code class="literal">VARCHAR_IGNORECASE</code>. It is possible to specify
+    the <code class="literal">VARCHAR_IGNORECASE</code> type for the definition of
+    individual columns. So it is possible to have some columns case sensitive
+    and some not, even in the same table. This statement must be switched
+    before creating tables. Existing tables and their data are not
+    affected.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="databaseobjects-chapt"></a>Chapter&nbsp;4.&nbsp;Schemas and Database Objects</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3622 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N10AC4"></a>
+<p>Copyright 2009 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-04 11:33:51 -0400 (Fri, 04 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N10AC7">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10AD2">Schemas and Schema Objects</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10AF8">Names and References</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B18">Character Sets</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B32">Collations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B3F">Distinct Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B46">Domains</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B4D">Number Sequences</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10BA3">Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10BAF">Views</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10BCD">Constraints</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C26">Assertions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C30">Triggers</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C3E">Routines</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C57">Indexes</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N10C5C">Statements for Schema Definition and Manipulation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10C61">Common Elements and Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10CE1">Renaming Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10D01">Commenting Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10D1D">Schema Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10D6E">Table Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N110DE">View Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1113C">Domain Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N111D1">Trigger Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1124D">Routine Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N112F5">Sequence Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1137F">SQL Procedure Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1139F">Other Schema Object Creation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N114B8">The Information Schema</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N114C3">Predefined Character Sets, Collations and Domains</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N114CE">Views in INFORMATION SCHEMA</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10AC7"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>The persistent elements of an SQL environment are database objects.
+    The database consists of catalogs plus authorizations.</p>
+<p>A catalog contains schemas, while schemas contain the objects that
+    contain data or govern the data.</p>
+<p>Each catalog contains a special schema called INFORMATION_SCHEMA.
+    This schema is read-only and contains some views and other schema objects.
+    The views contain lists of all the database objects that exist within the
+    catalog, plus all authorizations.</p>
+<p>Each database object has a name. A name is an identifier and is
+    unique within its name-space.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10AD2"></a>Schemas and Schema Objects</h2>
+</div>
+</div>
+</div>
+<p>In HyperSQL, there is only one catalog per database. The name of the
+    catalog is PUBLIC. You can rename the catalog with the <code class="literal">ALTER
+    CATALOG RENAME TO</code> statement. All schemas belong the this
+    catalog. The catalog name has no relation to the file name of the
+    database.</p>
+<p>Each database has also an internal "unique" name which is
+    automatically generated when the database is created. This name is used
+    for event logging. You can also change this unique name.</p>
+<p>Schema objects are database objects that contain data or govern or
+    perform operations on data. By definition, each schema object belongs to a
+    specific schema.</p>
+<p>Schema objects can be divided into groups according to their
+    characteristics.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Some kinds of schema objects can exist independently from other
+        schema object. Other kinds can exist only as an element of another
+        schema object. These dependent objects are automatically destroyed
+        when the parent object is dropped.</p>
+</li>
+<li>
+<p>Separate name-spaces exists for different kinds of schema
+        object. Some name-spaces are shared between two similar kinds of
+        schema objects.</p>
+</li>
+<li>
+<p>There can be dependencies between various schema objects, as a
+        schema object can include references to other schema objects. These
+        references can cross schema boundaries. Interdependence and cross
+        referencing between schema objects is allowed in some circumstances
+        and disallowed in some others.</p>
+</li>
+<li>
+<p>Schema objects can be destroyed with the DROP statement. If
+        dependent schema objects exist, a DROP statement will succeed only if
+        it has a CASCADE clause. In this case, dependent objects are also
+        destroyed in most cases. In some cases, such as dropping DOMAIN
+        objects, the dependent objects are not destroyed, but modified to
+        remove the dependency.</p>
+</li>
+</ul>
+</div>
+<p>A new HyperSQL catalog contains an empty schema called PUBLIC. By
+    default, this schema is the initial schema when a new session is started.
+    New schemas and schema objects can be defined and used in the PUBLIC
+    schema, as well as any new schema that is created by the user. You can
+    rename the PUBLIC schema.</p>
+<p>HyperSQL allows all schemas to be dropped, except the schema that is
+    the default initial schema for new sessions (by default, the PUBLIC
+    schema). For this schema, a DROP SCHEMA ... CASCADE statement will succeed
+    but will result in an empty schema, rather than no schema.</p>
+<p>The statements for setting the initial schema for users are
+    described in the <a class="link" href="#accesscontrol-chapt" title="Chapter&nbsp;6.&nbsp;Access Control">Statements for
+    Authorization and Access Control</a> chapter.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10AF8"></a>Names and References</h3>
+</div>
+</div>
+</div>
+<p>The name of a schema object is an
+      <code class="literal">&lt;identifier&gt;</code>. The name belongs to the
+      name-space for the particular kind of schema object. The name is unique
+      within its name-space. For example, each schema has a separate
+      name-space for TRIGGER objects.</p>
+<p>In addition to the name-spaces in the schema. Each table has a
+      name-space for the names of its columns.</p>
+<p>Because a schema object is always in a schema and a schema always
+      in a catalog, it is possible, and sometimes necessary, to qualify the
+      name of the schema object that is being referenced in an SQL statement.
+      This is done by forming an &lt;<code class="literal">identifier chain&gt;</code>.
+      In some contexts, only a simple <code class="literal">&lt;identifier&gt;</code>
+      can be used and the <code class="literal">&lt;identifier chain&gt;</code> is
+      prohibited. While in some other contexts, the use of
+      <code class="literal">&lt;identifier chain&gt;</code> is optional. An identifier
+      chain is formed by qualifying each object with the name of the object
+      that owns its name-space. Therefore a column name is prefixed with a
+      table name, a table name is prefixed with a schema name, and a schema
+      name is prefixed with a catalog name. A fully qualified column name is
+      in the form <code class="literal">&lt;catalog name&gt;.&lt;schema name&gt;.&lt;table
+      name&gt;.&lt;column name&gt;</code>, likewise, a fully qualified
+      sequence name is in the form <code class="literal">&lt;catalog name&gt;.&lt;schema
+      name&gt;.&lt;sequence name&gt;</code>.</p>
+<p>HyperSQL extends the SQL standard to allow renaming all database
+      objects. The ALTER ... RENAME TO command has slightly different forms
+      depending on the type of object. If an object is referenced in a VIEW or
+      ROUTINE definition, it is not always possible to rename it.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B18"></a>Character Sets</h3>
+</div>
+</div>
+</div>
+<p>A CHARACTER SET is the whole or a subset of the UNICODE
+      character set.</p>
+<p>A character set name can only be a <code class="literal">&lt;regular
+      identifier&gt;</code>. There is a separate name-space for character
+      sets.</p>
+<p>There are several predefined character sets. These character
+      sets belong to INFORMATION_SCHEMA. However, when they are referenced in
+      a statement, no schema prefix can be used in the statement that
+      references them.</p>
+<p>The following character sets have been specified by the SQL
+      Standard:</p>
+<p>SQL_TEXT, SQL_IDENTIFIER, SQL_CHARACTER, ASCII_GRAPHIC,
+      GRAPHIC_IRV, ASCII_FULL, ISO8BIT, LATIN1, UTF32, UTF16, UTF8.</p>
+<p>The ASCII_GRAPHIC is the same as GRAPHIC_IRV and ASCII_FULL is
+      the same as ISO8BIT.</p>
+<p>Most of the character sets are defined by well-known standards
+      such as UNICODE.</p>
+<p>The SQL_CHARACTER consists of ASCII letters, digits and the
+      symbols used in the SQL language. The SQL_TEXT, SQL_IDENTIFIER are
+      implementation defined. HyperSQL defines SQL_TEXT as the UNICODE
+      character set and SQL_IDENTIFIER as the UNICODE character set minus the
+      SQL language special characters.</p>
+<p>The character repertoire of HyperSQL is the UTF16 character
+      set, which covers all possible character sets. If a predefined character
+      set is specified for a table column, then any string stored in the
+      column must contain only characters from the specified character
+      set.</p>
+<p>Early releases of HyperSQL version 2.0 may not enforce the
+      CHARACTER SET that is specified for a column and may accept any
+      character string.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B32"></a>Collations</h3>
+</div>
+</div>
+</div>
+<p>A COLLATION is the method used for ordering character strings
+      in ordered sets and to determine equivalence of two character
+      strings.</p>
+<p>There are several predefined collations. These collations
+      belong to INFORMATION_SCHEMA. However, when they are referenced in a
+      statement, no schema prefix can be used in the statement that references
+      them.</p>
+<p>There is a separate name-space for collations..</p>
+<p>Collations for a large number of languages are supported by
+      HyperSQL.</p>
+<p>Early releases of HyperSQL version 2.0 only support a single
+      collation for the whole database.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B3F"></a>Distinct Types</h3>
+</div>
+</div>
+</div>
+<p>A distinct, user-defined TYPE is simply based on a built-in
+      type. A distinct TYPE is used in table definitions and in CAST
+      statements.</p>
+<p>Distinct types share a name-space with domains.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B46"></a>Domains</h3>
+</div>
+</div>
+</div>
+<p>A DOMAIN is a user-defined type, simply based on a built-in
+      type. A DOMAIN can have constraints that limit the values that the
+      DOMAIN can represent. A DOMAIN can be used in table definitions and in
+      CAST statements.</p>
+<p>Distinct types share a name-space with domains.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B4D"></a>Number Sequences</h3>
+</div>
+</div>
+</div>
+<p>A SEQUENCE object produces INTEGER values in sequence. The
+      SEQUENCE can be referenced in special contexts only within certain SQL
+      statements. For each row where the object is referenced, its value is
+      incremented.</p>
+<p>There is a separate name-space for SEQUENCE objects.</p>
+<p>IDENTITY columns are columns of tables which have an internal,
+      unnamed SEQUENCE object.</p>
+<p>SEQUENCE objects and IDENTITY columns are supported fully
+      according to the latest SQL 2008 Standard syntax.</p>
+<p>
+<span class="bold"><strong>Sequences</strong></span>
+</p>
+<p>The SQL:2008 syntax and usage is different from what is supported
+      by many existing database engines. Sequences are created with the
+      <code class="literal">CREATE SEQUENCE</code> command and their current value can
+      be modified at any time with <code class="literal">ALTER SEQUENCE</code>. The next
+      value for a sequence is retrieved with the <code class="literal">NEXT VALUE FOR
+      &lt;name&gt;</code> expression. This expression can be used for
+      inserting and updating table rows.</p>
+<div class="example">
+<a name="N10B67"></a>
+<p class="title">
+<b>Example&nbsp;4.1.&nbsp;inserting the next sequence value into a table row</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">INSERT INTO mytable VALUES 2, 'John', NEXT VALUE FOR mysequence;</pre>
+</div>
+</div>
+<br class="example-break">
+<p>You can also use it in select statements. For example, if you want
+      to number the returned rows of a SELECT in sequential order, you can
+      use:</p>
+<div class="example">
+<a name="N10B6E"></a>
+<p class="title">
+<b>Example&nbsp;4.2.&nbsp;numbering returned rows of a SELECT in sequential order</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">SELECT NEXT VALUE FOR mysequence, col1, col2 FROM mytable WHERE ...</pre>
+</div>
+</div>
+<br class="example-break">
+<p>In version 2.0, the semantics of sequences is exactly as defined
+      by SQL:2008. If you use the same sequence twice in the same row in an
+      INSERT statement, you will get the same value as required by the
+      Standard.</p>
+<p>The correct way to use a sequence value is the NEXT VALUE FOR
+      expression. You can query the SEQUENCES table for the next value that
+      will be returned from any of the defined sequences. The SEQUENCE_NAME
+      column contains the name and the NEXT_VALUE column contains the next
+      value to be returned. Note that this is only for getting information and
+      you should not use the sequence value.</p>
+<p>
+<span class="bold"><strong>Identity Auto-Increment
+      Columns</strong></span>
+</p>
+<p>Each table can contain a single auto-increment column, known as
+      the IDENTITY column. An IDENTITY column is a SMALLINT, INTEGER, BIGINT,
+      DECIMAL or NUMERIC column with its value generated by a sequence
+      generator.</p>
+<p>In HyperSQL 2.0, an IDENTITY column is not by default treated as
+      the primary key for the table (as a result, multi-column primary keys
+      are possible with an IDENTITY column present).</p>
+<p>The SQL standard syntax is used, which allows the initial value
+      and other options to be specified.<pre class="programlisting">&lt;colname&gt; [ INTEGER | BIGINT | DECIMAL | NUMERIC ] GENERATED { BY DEFAULT | ALWAYS} AS IDENTITY [( &lt;options&gt; )] [PRIMARY KEY]</pre>
+</p>
+<p>When you add a new row to such a table using an <code class="literal">INSERT
+      INTO &lt;tablename&gt; ... </code>statement, you can use the DEFAULT
+      keyword for the IDENTITY column, which results in an auto-generated
+      value for the column. The <code class="literal">IDENTITY() </code>function returns
+      the last value inserted into any IDENTITY column by this session. Each
+      session manages this function call separately and is not affected by
+      inserts in other sessions. Use <code class="literal">CALL IDENTITY() </code>as an
+      SQL statement to retrieve this value. If you want to use the value for a
+      field in a child table, you can use <code class="literal">INSERT INTO
+      &lt;childtable&gt; VALUES (...,IDENTITY(),...);</code>. Both types of
+      call to<code class="literal"> IDENTITY()</code> must be made before any additional
+      update or insert statements are issued by the session.</p>
+<p>The last inserted IDENTITY value can also be retrieved via JDBC,
+      by specifying the Statement or PreparedStatement object to return the
+      generated value.</p>
+<p>The next IDENTITY value to be used can be changed with following
+      statement. Note that this statement is not used in normal operation and
+      is only for special purposes: <pre class="programlisting">ALTER TABLE ALTER COLUMN &lt;column name&gt; RESTART WITH &lt;new value&gt;;</pre>For
+      backward compatibility, support has been retained for <code class="literal">CREATE
+      TABLE &lt;tablename&gt;(&lt;colname&gt; IDENTITY, ...)</code> as a
+      shortcut which defines the column both as an IDENTITY column and a
+      PRIMARY KEY column. Also, for backward compatibility, it is possible to
+      use NULL as the value of an IDENTITY column in an INSERT statement and
+      the value will be generated automatically. You should avoid these
+      compatibility features as they may be removed from future versions of
+      HyperSQL.</p>
+<p>In the following example, the identity value for the first INSERT
+      statement is generated automatically using the DEFAULT keyword. The
+      second INSERT statement uses a call to the IDENTITY() function to
+      populate a row in the child table with the generated identity
+      value.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE star (id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 
+   firstname VARCHAR(20),
+   lastname VARCHAR(20))
+CREATE TABLE movies (starid INTEGER, movieid INTEGER PRIMARY KEY, title VARCHAR(40)) 
+INSERT INTO star (id, firstname, lastname) VALUES (DEFAULT, 'Felix', 'the Cat')
+INSERT INTO movies (starid, movieid, title) VALUES (IDENTITY(), 10, 'Felix in Hollywood')
+</pre>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10BA3"></a>Tables</h3>
+</div>
+</div>
+</div>
+<p>In the SQL environment, tables are the most essential
+      components, as they hold all persistent data.</p>
+<p>If TABLE is considered as metadata (i.e. without its actual
+      data) it is called a <span class="emphasis"><em>relation</em></span> in relational theory.
+      It has one or more columns, with each column having a distinct name and
+      a data type. A table usually has one or more constraints which limit the
+      values that can potentially be stored in the TABLE. These constraints
+      are discussed in the next section.</p>
+<p>A single column of the table can be defined as IDENTITY. The
+      values stored in this column are auto-generated and are based on an
+      (unnamed) identity sequence.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10BAF"></a>Views</h3>
+</div>
+</div>
+</div>
+<p>A VIEW is similar to a TABLE but it does not permanently
+      contain rows of data. A view is defined as a QUERY EXPRESSION, which is
+      often a SELECT statement that references views and tables, but it can
+      also consist of a TABLE CONSTRUCTOR that does not reference any tables
+      or views.</p>
+<p>A view has many uses:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Hide the structure and column names of tables. The view can
+          represent one or more tables or views as a separate table. This can
+          include aggregate data, such as sums and averages, from other
+          tables.</p>
+</li>
+<li>
+<p>Allow access to specific rows in a table. For example, allow
+          access to records that were added since a given date, while hiding
+          older records.</p>
+</li>
+<li>
+<p>Allow access to specific columns. For example allow access to
+          columns that contain non-confidential information. Note that this
+          can also be achieved with the GRANT SELECT statement, using
+          column-level privileges</p>
+</li>
+</ul>
+</div>
+<p>A VIEW that returns the columns of a single ordinary TABLE may
+      be <em class="glossterm">updatable</em>. Some
+      <em class="glossterm">updatable</em> views are
+      <em class="glossterm">insertable-into</em>. When rows of an updatable view
+      are updated, or new rows are inserted, these changes are reflected in
+      the base table. A VIEW definition may specify that the inserted or
+      updated rows conform to the search condition of the view. This is done
+      with the CHECK OPTION clause.</p>
+<p>Views share a name-space with tables.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10BCD"></a>Constraints</h3>
+</div>
+</div>
+</div>
+<p>A CONSTRAINT is a child schema object and can belong to a
+      DOMAIN or a TABLE. CONSTRAINT objects can be defined without specifying
+      a name. In this case the system generates a name for the new object
+      beginning with "SYS_".</p>
+<p>In a DOMAIN, CHECK constraints can be defined that limits the
+      value represented by the DOMAIN. These constraints work exactly like a
+      CHECK constraint on a single column of a table as described
+      below.</p>
+<p>In a TABLE, a constraint takes three basic forms.</p>
+<p>
+<span class="bold"><strong>CHECK</strong></span>
+</p>
+<p>A CHECK constraint consists of a <code class="literal">&lt;search
+      condition&gt;</code> that must not be false (can be unknown) for each
+      row of the table. The <code class="literal">&lt;search condition&gt;</code> can
+      reference all the columns of the current row, and if it contains a
+      <code class="literal">&lt;subquery&gt;</code>, other tables and views in the
+      database (excluding its own table).</p>
+<p>
+<span class="bold"><strong>NOT NULL</strong></span>
+</p>
+<p>A simple form of check constraint is the NOT NULL constraint,
+      which applies to a single column.</p>
+<p>
+<span class="bold"><strong>UNIQUE</strong></span>
+</p>
+<p>A UNIQUE constraint is based on an equality comparison of
+      values of specific columns (taken together) of one row with the same
+      values from each of the other rows. The result of the comparison must
+      never be true (can be false or unknown). If a row of the table has NULL
+      in any of the columns of the constraint, it conforms to the constraint.
+      A unique constraint on multiple columns (c1, c2, c3, ..) means that in
+      no two rows, the sets of values for the columns can be equal unless at
+      lease one of them is NULL. Each single column taken by itself can have
+      repeat values in different rows. The following example satisfies a
+      UNIQUE constraint on the two columns</p>
+<div class="example">
+<a name="N10BF2"></a>
+<p class="title">
+<b>Example&nbsp;4.3.&nbsp;Column values which satisfy a 2-column UNIQUE
+        constraint</b>
+</p>
+<div class="example-contents">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td>1,</td><td>2</td>
+</tr>
+<tr>
+<td>2,</td><td>1</td>
+</tr>
+<tr>
+<td>2,</td><td>2</td>
+</tr>
+<tr>
+<td>NULL,</td><td>1</td>
+</tr>
+<tr>
+<td>NULL,</td><td>1</td>
+</tr>
+<tr>
+<td>1,</td><td>NULL</td>
+</tr>
+<tr>
+<td>NULL,</td><td>NULL</td>
+</tr>
+<tr>
+<td>NULL,</td><td>NULL</td>
+</tr>
+</table>
+</div>
+</div>
+<br class="example-break">
+<p>
+<span class="bold"><strong>PRIMARY KEY</strong></span>
+</p>
+<p>A PRIMARY KEY constraint is equivalent to a UNIQUE constraint
+      on one or more NOT NULL columns. Only one PRIMARY KEY can be defined in
+      each table.</p>
+<p>
+<span class="bold"><strong>FOREIGN KEY</strong></span>
+</p>
+<p>A FOREIGN key constraint is based on an equality comparison
+      between values of specific columns (taken together) of each row with the
+      values of the columns of a UNIQUE constraint on another table or the
+      same table. The result of the comparison must never be false (can be
+      unknown). A special form of FOREIGN KEY constraint, based on its CHECK
+      clause, allows the result to be unknown only if the values for all
+      columns are NULL. A FOREIGN key can be declared only if a UNIQUE
+      constraint exists on the referenced columns.</p>
+<p>Constraints share a name space with assertions.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C26"></a>Assertions</h3>
+</div>
+</div>
+</div>
+<p>An ASSERTION is a top-level schema objects. It consists of a
+      <code class="literal">&lt;search condition&gt;</code> that must not be false (can
+      be unknown).</p>
+<p>Assertions share a name-space with constraints</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C30"></a>Triggers</h3>
+</div>
+</div>
+</div>
+<p>A TRIGGER is a child schema object that always belongs to a
+      TABLE or a VIEW.</p>
+<p>Each time a DELETE, UPDATE or INSERT is performed on the table
+      or view, additional actions are taken by the triggers that have been
+      declared on the table or view.</p>
+<p>Triggers are discussed in detail in chapter <a class="link" href="#triggers-chapt" title="Chapter&nbsp;9.&nbsp;Triggers">Triggers</a>
+      .</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C3E"></a>Routines</h3>
+</div>
+</div>
+</div>
+<p>Routines are user-defined functions or procedures. The names
+      and usage of functions and procedures are different. FUNCTION is a
+      routine that can be referenced in many types of statements. PROCEDURE is
+      a routine that can be referenced only in a CALL statement.</p>
+<p>There is a separate name-space for routines.</p>
+<p>Because of the possibility of overloading, each routine can
+      have more than one name. The name of the routine is the same for all
+      overloaded variants, but each variant has a <em class="glossterm">specific
+      name</em>, different from all other routine names and specific
+      names in the schema. The <em class="glossterm">specific name</em> can be
+      specified in the routine definition statement. Otherwise it is assigned
+      by the engine. The specific name is used only for schema manipulation
+      statements, which need to reference a specific variant of the routine.
+      For example, if a routine has two signatures, each signature has its own
+      <em class="glossterm">specific name</em>. This allows the user to drop one
+      of the signatures while keeping the other.</p>
+<p>Routines are discussed in detail in chapter <a class="link" href="#sqlroutines-chapt" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">SQL-Invoked Routines</a> .</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C57"></a>Indexes</h3>
+</div>
+</div>
+</div>
+<p>Indexes are an implementation-defined extension to the SQL
+      Standard. HyperSQL has a dedicated name-space for indexes in each
+      schema.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10C5C"></a>Statements for Schema Definition and Manipulation</h2>
+</div>
+</div>
+</div>
+<p>Schemas and schema objects can be created, modified and dropped.
+    The SQL Standard defines a range of statements for this purpose. HyperSQL
+    supports many additional statements, especially for changing the
+    properties of existing schema objects.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C61"></a>Common Elements and Statements</h3>
+</div>
+</div>
+</div>
+<p>These elements and statements are used for different types of
+      object. They are described here, before the statements that can use
+      them.</p>
+<a name="N10C66" class="indexterm"></a>
+<p>
+<span class="bold"><strong>identifier</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>definition of identifier</em></span>
+</p>
+<p>
+<code class="literal">&lt;identifier&gt; ::= &lt;regular identifier&gt; |
+      &lt;delimited identifier&gt; | &lt;SQL language identifier&gt;
+      </code>
+</p>
+<p>
+<code class="literal">&lt;delimited identifier&gt; ::= &lt;double quote&gt;
+      &lt;character sequence&gt; &lt;double quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;regular identifier&gt; ::= &lt;special character
+      sequence&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL language identifier&gt; ::= &lt;special
+      character sequence&gt;</code>
+</p>
+<p>A <code class="literal">&lt;delimited identifier&gt;</code> is a sequence
+      of characters enclosed with double-quote symbols. All characters are
+      allowed in the character sequence.</p>
+<p>A <code class="literal">&lt;regular identifier&gt;</code> is a special
+      sequence of characters. It consists of letters, digits and the
+      underscore characters. It must begin with a letter.</p>
+<p>A <code class="literal">&lt;SQL language identifier&gt;</code> is similar
+      to <code class="literal">&lt;regular identifier&gt;</code> but the letters can
+      range only from A-Z in the ASCII character set. This type of identifier
+      is used for names of CHARACTER SET objects.</p>
+<p>If the character sequence of a delimited identifier is the same
+      as an undelimited identifier, it represents the same identifier. For
+      example "JOHN" is the same identifier as JOHN. In a <code class="literal">&lt;regular
+      identifier&gt;</code> the case-normal form is considered for
+      comparison. This form consists of the upper-case of equivalent of all
+      the letters.</p>
+<p>The character sequence length of all identifiers must be
+      between 1 and 128 characters.</p>
+<p>A reserved word is one that is used by the SQL Standard for
+      special purposes. It is similar to a <code class="literal">&lt;regular
+      identifier&gt;</code> but it cannot be used as an identifier for user
+      objects. If a reserved word is enclosed in double quote characters, it
+      becomes a quoted identifier and can be used for database
+      objects.</p>
+<a name="N10C9C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CASCADE or RESTRICT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop behavior</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop behavior&gt; ::= CASCADE |
+      RESTRICT</code>
+</p>
+<p>The <code class="literal">&lt;drop behavior&gt;</code> is a required
+      element of statements that drop a SCHEMA or a schema object. If
+      <code class="literal">&lt;drop behavior&gt;</code> is not specified then
+      <code class="literal">RESTRICT</code> is implicit. It determines the effect of the
+      statement if there are other objects in the catalog that reference the
+      SCHEMA or the schema object. If RESTRICT is specified, the statement
+      fails if there are referencing objects. If CASCADE is specified, all the
+      referencing objects are modified or dropped with cascading effect.
+      Whether a referencing object is modified or dropped, depends on the kind
+      of schema object that is dropped.</p>
+<a name="N10CB6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IF EXISTS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop condition (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;if exists clause&gt; ::= IF
+      EXISTS</code>
+</p>
+<p>This clause is not part of the SQL standard and is a HyperSQL
+      extension to some commands that drop objects (schemas, tables, views,
+      sequences and indexes). If it is specified, then the statement does not
+      return an error if the drop statement is issued on a non-existent
+      object.</p>
+<a name="N10CC7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SPECIFIC</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>specific routine designator</em></span>
+</p>
+<p>
+<code class="literal">&lt;specific routine designator&gt; ::= SPECIFIC
+      &lt;routine type&gt; &lt;specific name&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;routine type&gt; ::= ROUTINE | FUNCTION |
+      PROCEDURE</code>
+</p>
+<p>This clause is used in statements that need to specify one of
+      the multiple versions of an overloaded routine. The
+      <code class="literal">&lt;specific name&gt;</code> is the one specified in the
+      <code class="literal">&lt;routine definition&gt;</code> statement.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10CE1"></a>Renaming Objects</h3>
+</div>
+</div>
+</div>
+<a name="N10CE4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RENAME</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>rename statement (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;rename statement&gt; ::= ALTER &lt;object type&gt;
+      &lt;name&gt; RENAME TO &lt;new name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;object type&gt; ::= CATALOG | SCHEMA | DOMAIN |
+      TYPE | TABLE | CONSTRAINT | INDEX | ROUTINE | SPECIFIC
+      ROUTINE</code>
+</p>
+<p>
+<code class="literal">&lt;column rename statement&gt; ::= ALTER TABLE
+      &lt;table name&gt; ALTER COLUMN &lt;name&gt; RENAME TO &lt;new
+      name&gt;</code>
+</p>
+<p>This statement is used to rename an existing object. It is not
+      part of the SQL Standard. The specified <code class="literal">&lt;name&gt;</code>
+      is the existing name, which can be qualified with a schema name, while
+      the <code class="literal">&lt;new name&gt;</code> is the new name for the
+      object.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10D01"></a>Commenting Objects</h3>
+</div>
+</div>
+</div>
+<a name="N10D04" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COMMENT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>comment statement (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;comment statement&gt; ::= COMMENT ON { TABLE |
+      COLUMN | ROUTINE } &lt;name&gt; IS &lt;character string
+      literal&gt;</code>
+</p>
+<p>Adds a comment to the object metadata, which can later be read
+      from an INFORMATION_SCHEMA view. This command is not part of the SQL
+      Standard. The strange syntax is due to compatibility with other database
+      engines that support the statement.<code class="literal"> The &lt;name&gt;</code>
+      is the name of a table, view, column or routine. The name of the column
+      consists of dot-separated<code class="literal"> &lt;table name&gt; . &lt;column
+      name&gt;</code>. The name of the table, view or routine can be a
+      simple name. All names can be qualified with a schema name. If there is
+      alread a comment on the object, the new comment will replace
+      it.</p>
+<p>The comments appear in the results returned by JDBC
+      DatabaseMetaData methods, getTables() and getColumns(). The
+      INFORMATION_SCHEMA.SYSTEM_COMMENTS view contains the comments. You can
+      query this view using the schema, table, and column names to retreive
+      the comments.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10D1D"></a>Schema Creation</h3>
+</div>
+</div>
+</div>
+<a name="N10D20" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>schema definition</em></span>
+</p>
+<p>The CREATE_SCHEMA or DBA role is required in order to create a
+      schema. A schema can be created with or without schema objects. Schema
+      objects can always be added after creating the schema, or existing ones
+      can be dropped. Within the <code class="literal">&lt;schema definition&gt;</code>
+      statement, all schema object creation takes place inside the newly
+      created schema. Therefore, if a schema name is specified for the schema
+      objects, the name must match that of the new schema. In addition to
+      statements for creating schema objects, the statement can include
+      instances of <code class="literal">&lt;grant statement&gt;</code> and
+      <code class="literal">&lt;role definition&gt;</code>. This is a curious aspect of
+      the SQL standard, as these elements do not really belong to schema
+      creation.</p>
+<p>
+<code class="literal">&lt;schema definition&gt; ::= CREATE SCHEMA &lt;schema
+      name clause&gt; [ &lt;schema character set specification&gt; ] [
+      &lt;schema element&gt;... ]</code>
+</p>
+<p>
+<code class="literal">&lt;schema name clause&gt; ::= &lt;schema name&gt; |
+      AUTHORIZATION &lt;authorization identifier&gt; | &lt;schema name&gt;
+      AUTHORIZATION &lt;authorization identifier&gt;</code>
+</p>
+<p>If the name of the schema is specified simply as
+      <code class="literal">&lt;schema name&gt;</code>, then the AUTHORIZATION is the
+      current user. Otherwise, the specified <code class="literal">&lt;authorization
+      identifier&gt;</code> is used as the AUTHORIZATION for the schema. If
+      <code class="literal">&lt;schema name&gt;</code> is omitted, then the name of the
+      schema is the same as the specified <code class="literal">&lt;authorization
+      identifier&gt;</code>.</p>
+<p>
+<code class="literal">&lt;schema element&gt; ::= &lt;table definition&gt; |
+      &lt;view definition&gt; | &lt;domain definition&gt; | &lt;character set
+      definition&gt; | &lt;collation definition&gt; | &lt;transliteration
+      definition&gt; | &lt;assertion definition&gt; | &lt;trigger
+      definition&gt; | &lt;user-defined type definition&gt; | &lt;user-defined
+      cast definition&gt; | &lt;user-defined ordering definition&gt; |
+      &lt;transform definition&gt; | &lt;schema routine&gt; | &lt;sequence
+      generator definition&gt; | &lt;grant statement&gt; | &lt;role
+      definition&gt;</code>
+</p>
+<p>An example of the command is given below. Note that a single
+      semicolon appears at the end, there should be no semicolon between the
+      statements:</p>
+<pre class="programlisting">    CREATE SCHEMA ACCOUNTS AUTHORIZATION DBA
+        CREATE TABLE AB(A INTEGER, ...)
+        CREATE TABLE CD(C CHAR(10), ...)
+        CREATE VIEW VI AS SELECT ...
+        GRANT SELECT ON AB TO PUBLIC
+        GRANT SELECT ON CD TO JOE;
+</pre>
+<p>It is not really necessary to create a schema and all its
+      objects as one command. The schema can be created first, and its objects
+      can be created one by one.</p>
+<a name="N10D54" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop schema statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop schema statement&gt; ::= DROP SCHEMA [ IF
+      EXISTS ] &lt;schema name&gt; [ IF EXISTS ] &lt;drop behavior&gt;
+      </code>
+</p>
+<p>This command destroys an existing schema. If <code class="literal">&lt;drop
+      behavior&gt;</code> is <code class="literal">RESTRICT</code>, the schema must
+      be empty, otherwise an error is raised. If <code class="literal">CASCADE</code> is
+      specified, then all the objects contained in the schema are destroyed
+      with a CASCADE option.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10D6E"></a>Table Creation and Manipulation</h3>
+</div>
+</div>
+</div>
+<a name="N10D71" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>table definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;table definition&gt; ::= CREATE [ { &lt;table
+      scope&gt; | &lt;table type&gt; } ] TABLE &lt;table name&gt; &lt;table
+      contents source&gt; [ ON COMMIT { PRESERVE | DELETE } ROWS
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;table scope&gt; ::= { GLOBAL | LOCAL }
+      TEMPORARY</code>
+</p>
+<p>
+<code class="literal">&lt;table type&gt; :: = MEMORY |
+      CACHED</code>
+</p>
+<p>
+<code class="literal">&lt;table contents source&gt; ::= &lt;table element
+      list&gt; | &lt;as subquery clause&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table element list&gt; ::= &lt;left paren&gt;
+      &lt;table element&gt; [ { &lt;comma&gt; &lt;table element&gt; }... ]
+      &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table element&gt; ::= &lt;column definition&gt; |
+      &lt;table constraint definition&gt; | &lt;like
+      clause&gt;</code>
+</p>
+<p>
+<span class="emphasis"><em>like clause</em></span>
+</p>
+<p>A <code class="literal">&lt;like clause&gt;</code> copies all column
+      definitions from another table into the newly created table. Its three
+      options indicate if the <code class="literal">&lt;default clause&gt;</code>,
+      <code class="literal">&lt;identity column specification&gt;</code> and
+      <code class="literal">&lt;generation clause&gt;</code> associated with the column
+      definitions are copied or not. If an option is not specified, it
+      defaults to <code class="literal">EXCLUDING</code>. The <code class="literal">&lt;generation
+      clause&gt;</code> refers to columns that are generated by an
+      expression but not to identity columns. All NOT NULL constraints are
+      copied with the original columns, other constraints are not. The
+      <code class="literal">&lt;like clause&gt;</code> can be used multiple times,
+      allowing the new table to have copies of the column definitions of one
+      or more other tables.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (id INTEGER PRIMARY KEY, LIKE atable INCLUDING DEFAULTS EXCLUDING IDENTITY)
+</pre>
+</div>
+<p>
+<code class="literal">&lt;like clause&gt; ::= LIKE &lt;table name&gt; [
+      &lt;like options&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;like options&gt; ::= &lt;like
+      option&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;like option&gt; ::= &lt;identity option&gt; |
+      &lt;column default option&gt; | &lt;generation
+      option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;identity option&gt; ::= INCLUDING IDENTITY |
+      EXCLUDING IDENTITY</code>
+</p>
+<p>
+<code class="literal">&lt;column default option&gt; ::= INCLUDING DEFAULTS |
+      EXCLUDING DEFAULTS</code>
+</p>
+<p>
+<code class="literal">&lt;generation option&gt; ::= INCLUDING GENERATED |
+      EXCLUDING GENERATED</code>
+</p>
+<p>
+<span class="emphasis"><em>as subquery clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;as subquery clause&gt; ::= [ &lt;left paren&gt;
+      &lt;column name list&gt; &lt;right paren&gt; ] AS &lt;table subquery&gt;
+      { WITH NO DATA | WITH DATA }</code>
+</p>
+<p>An <code class="literal">&lt;as subquery clause&gt;</code> used in table
+      definition creates a table based on a <code class="literal">&lt;table
+      subquery&gt;</code>. This kind of table definition is similar to a
+      view definition. If <code class="literal">WITH DATA</code> is specified, then the
+      new table will contain the rows of data returned by the
+      <code class="literal">&lt;table subquery&gt;</code>.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (a, b, c) AS (SELECT * FROM atable) WITH DATA
+</pre>
+</div>
+<a name="N10DD5" class="indexterm"></a>
+<p>
+<span class="emphasis"><em>column definition</em></span>
+</p>
+<p>A column definition consists of a <code class="literal">&lt;column
+      name&gt;</code> and in most cases a <code class="literal">&lt;data
+      type&gt;</code> or <code class="literal">&lt;domain name&gt;</code> as minimum.
+      The other elements of <code class="literal">&lt;column definition&gt;</code> are
+      optional. Each <code class="literal">&lt;column name&gt;</code> in a table is
+      unique.</p>
+<p>
+<code class="literal">&lt;column definition&gt; ::= &lt;column name&gt; [
+      &lt;data type or domain name&gt; ] [ &lt;default clause&gt; |
+      &lt;identity column specification&gt; | &lt;generation clause&gt; ] [
+      &lt;column constraint definition&gt;... ] [ &lt;collate clause&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;data type or domain name&gt; ::= &lt;data type&gt;
+      | &lt;domain name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;column constraint definition&gt; ::= [
+      &lt;constraint name definition&gt; ] &lt;column constraint&gt; [
+      &lt;constraint characteristics&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;column constraint&gt; ::= NOT NULL | &lt;unique
+      specification&gt; | &lt;references specification&gt; | &lt;check
+      constraint definition&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;identity column specification&gt; ::= GENERATED {
+      ALWAYS | BY DEFAULT } AS IDENTITY [ &lt;left paren&gt; &lt;common
+      sequence generator options&gt; &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;generation clause&gt; ::= GENERATED ALWAYS AS
+      &lt;generation expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;generation expression&gt; ::= &lt;left paren&gt;
+      &lt;value expression&gt; &lt;right paren&gt;</code>
+</p>
+<p>The <code class="literal">&lt;identity column specification&gt;</code>
+      can be specified for only a single column of the table.</p>
+<p>A <code class="literal">&lt;column constraint definition&gt;</code> is a
+      shortcut for a <code class="literal">&lt;table constraint definition&gt;</code>. A
+      constraint that is defined in this way is automatically turned into a
+      table constraint. A name is automatically generated for the constraint
+      and assigned to it.</p>
+<p>The <code class="literal">&lt;identity column specification&gt;</code> is
+      used for special columns which represent values based on unnamed
+      sequence generators. It is possible to insert a row into the able
+      without specifying a value for the column. The value is then generated
+      by the sequence generators according to its rules. An identity column
+      may or may not be the primary key. Example below:</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (id INTEGER GENERATED ALWAYS AS IDENTITY(START WITH 100), name VARCHAR(20) PRIMARY KEY, )
+</pre>
+</div>
+<p>The <code class="literal">&lt;generation clause&gt;</code> is used for
+      special columns which represent values based on the values held in other
+      columns in the same row. The <code class="literal">&lt;value expression&gt;</code>
+      must reference only other, non-generated, columns of the table in the
+      same row. Therefore, any function used in the expression may not access
+      SQL-data, and no <code class="literal">&lt;query expression&gt;</code> is allowed.
+      When <code class="literal">&lt;generation clause&gt;</code> is used,
+      <code class="literal">&lt;data type&gt;</code> or <code class="literal">&lt;domain
+      name&gt;</code> may be omitted.</p>
+<p>A generated column can be part of a foreign key or unique
+      constraints or a column of an index. This capability is the main reason
+      for using generated columns. A generated column may contain a formula
+      that computes a value based on the values of other columns. Fast
+      searches of the computed value can be performed when an index is
+      declared on the generated column. Or the computed values can be declared
+      to be unique, using a UNIQUE constraint on the table.</p>
+<p>When a row is inserted into a table, or an existing row is
+      updated, no value except DEFAULT can be specified for a generated
+      column. In the example below, data is inserted into the non-generated
+      columns and the generated column will contain 'Felix the Cat' or 'Pink
+      Panther'.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (id INTEGER PRIMARY KEY, 
+   firstname VARCHAR(20),
+   lastname VARCHAR(20), 
+   fullname VARCHAR(40) GENERATED ALWAYS AS (firstname || ' ' || lastname)) 
+INSERT INTO t (id, firstname, lastname) VALUES (1, 'Felix', 'the Cat')
+INSERT INTO t (id, firstname, lastname, fullname) VALUES (2, 'Pink', 'Panther', DEFAULT)
+</pre>
+</div>
+<a name="N10E33" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>default clause</em></span>
+</p>
+<p>A default clause can be used if GENERATED is not specified. If
+      a column has a <code class="literal">&lt;default clause&gt;</code> then it is
+      possible to insert a row into the table without specifying a value for
+      the column.</p>
+<p>
+<code class="literal">&lt;default clause&gt; ::= DEFAULT &lt;default
+      option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;default option&gt; ::= &lt;literal&gt; |
+      &lt;datetime value function&gt; | USER | CURRENT_USER | CURRENT_ROLE |
+      SESSION_USER | SYSTEM_USER | CURRENT_CATALOG | CURRENT_SCHEMA |
+      CURRENT_PATH | NULL</code>
+</p>
+<p>The type of the <code class="literal">&lt;default option&gt;</code> must
+      match the type of the column.</p>
+<a name="N10E4F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>constraint name and
+      characteristics</em></span>
+</p>
+<p>
+<code class="literal">&lt;constraint name definition&gt; ::= CONSTRAINT
+      &lt;constraint name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;constraint characteristics&gt; ::= &lt;constraint
+      check time&gt; [ [ NOT ] DEFERRABLE [ &lt;constraint check time&gt; ]
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;constraint check time&gt; ::= INITIALLY DEFERRED |
+      INITIALLY IMMEDIATE</code>
+</p>
+<p>Specify the name of a constraint and its characteristics. By
+      default the constraint is <code class="literal">NOT DEFERRABLE</code> and
+      <code class="literal">INITIALLY IMMEDIATE</code>. This means the constraint is
+      enforced as soon as a data change statement is executed. If
+      <code class="literal">INITIALLY DEFERRED</code> is specified, then the constraint
+      is enforced when the session commits. The characteristics must be
+      compatible. The constraint check time can be changed temporarily for an
+      SQL session. HyperSQL does not support deferring constraint enforcement.
+      This feature of the SQL Standard has been criticised because it allows a
+      session to read uncommitted data that violates database integrity
+      constraints but has not yet been checked.</p>
+<a name="N10E6F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>table constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;table constraint definition&gt; ::= [
+      &lt;constraint name definition&gt; ] &lt;table constraint&gt; [
+      &lt;constraint characteristics&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;table constraint&gt; ::= &lt;unique constraint
+      definition&gt; | &lt;referential constraint definition&gt; | &lt;check
+      constraint definition&gt;</code>
+</p>
+<p>Three kinds of constraint can be defined on a table: UNIQUE
+      (including PRIMARY KEY), FOREIGN KEY and CHECK. Each kind has its own
+      rules to limit the values that can be specified for different columns in
+      each row of the table.</p>
+<a name="N10E83" class="indexterm"></a><a name="N10E88" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UNIQUE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>unique constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;unique constraint definition&gt; ::= &lt;unique
+      specification&gt; &lt;left paren&gt; &lt;unique column list&gt;
+      &lt;right paren&gt; | UNIQUE ( VALUE )</code>
+</p>
+<p>
+<code class="literal">&lt;unique specification&gt; ::= UNIQUE | PRIMARY
+      KEY</code>
+</p>
+<p>
+<code class="literal">&lt;unique column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>A unique constraint is specified on a single column or on
+      multiple columns. On each set of columns taken together, only one UNIQUE
+      constraint can be specified. Each column of a PRIMARY KEY constraint has
+      an implicit NOT NULL constraint.</p>
+<p>If <code class="literal">UNIQUE( VALUE )</code> is specified, the
+      constraint created on all columns of the table.</p>
+<a name="N10EA4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>FOREIGN KEY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>referential constraint
+      definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;referential constraint definition&gt; ::= FOREIGN
+      KEY &lt;left paren&gt; &lt;referencing columns&gt; &lt;right paren&gt;
+      &lt;references specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;references specification&gt; ::= REFERENCES
+      &lt;referenced table and columns&gt; [ MATCH &lt;match type&gt; ] [
+      &lt;referential triggered action&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;match type&gt; ::= FULL | PARTIAL |
+      SIMPLE</code>
+</p>
+<p>
+<code class="literal">&lt;referencing columns&gt; ::= &lt;reference column
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;referenced table and columns&gt; ::= &lt;table
+      name&gt; [ &lt;left paren&gt; &lt;reference column list&gt; &lt;right
+      paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;reference column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;referential triggered action&gt; ::= &lt;update
+      rule&gt; [ &lt;delete rule&gt; ] | &lt;delete rule&gt; [ &lt;update
+      rule&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;update rule&gt; ::= ON UPDATE &lt;referential
+      action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;delete rule&gt; ::= ON DELETE &lt;referential
+      action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;referential action&gt; ::= CASCADE | SET NULL |
+      SET DEFAULT | RESTRICT | NO ACTION</code>
+</p>
+<p>A referential constraint allows links to be established between
+      the rows of two tables. The specified list of <code class="literal">&lt;referencing
+      columns&gt;</code> corresponds one by one to the columns of the
+      specified list of <code class="literal">&lt;referenced columns&gt;</code> in
+      another table (or sometimes in the same table). For each row in the
+      table, a row must exist in the referenced table with equivalent values
+      in the two column lists. There must exist a single unique constraint in
+      the referenced table on all the <code class="literal">&lt;referenced
+      columns&gt;</code>.</p>
+<p>The <code class="literal">[ MATCH match type ]</code> clause is optional
+      and has an effect only on multi-column foreign keys and only on rows
+      containing at least a NULL in one of the <code class="literal">&lt;referencing
+      columns&gt;</code>. If the clause is not specified, MATCH SIMPLE is
+      the default. If <code class="literal">MATCH SIMPLE</code> is specified, then any
+      NULL means the row can exist (without a corresponding row in the
+      referenced table). If <code class="literal">MATCH FULL</code> is specified then
+      either all the column values must be NULL or none of them.
+      <code class="literal">MATCH PARTIAL</code> allows any NULL but the non NULL values
+      must match those of a row in the referenced table. HyperSQL does not
+      support <code class="literal">MATCH PARTIAL</code>.</p>
+<p>Referential actions are specified with ON UPDATE and ON DELETE
+      clauses. These actions take place when a row in the referenced table
+      (the parent table) has referencing rows in the referencing table and it
+      is deleted or modified with any SQL statement. The default is NO ACTION.
+      This means the SQL statement that causes the DELETE or UPDATE is
+      terminated with an exception. The RESTRICT option is similar and works
+      exactly the same without deferrable constraints (which are not allowed
+      by HyperSQL). The other three options, CASCADE, SET NULL and SET DEFAULT
+      all allow the DELETE or UPDATE statement to complete. With DELETE
+      statements the CASCADE option results in the referencing rows to be
+      deleted. With UPDATE statements, the changes to the values of the
+      referenced columns are copied to the referencing rows. With both DELETE
+      or UPDATE statement, the SET NULL option results in the columns of the
+      referencing rows to be set to NULL. Similarly, the SET DEFAULT option
+      results in the columns of the referencing rows to be set to their
+      default values.</p>
+<a name="N10EEF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CHECK</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>check constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;check constraint definition&gt; ::= CHECK &lt;left
+      paren&gt; &lt;search condition&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>A CHECK constraint can exist for a TABLE or for a DOMAIN. The
+      <code class="literal">&lt;search condition&gt;</code> evaluates to an SQL BOOLEAN
+      value for each row of the table. Within the <code class="literal">&lt;search
+      condition&gt;</code> all columns of the table row can be referenced.
+      For all rows of the table, the <code class="literal">&lt;search
+      condition&gt;</code> evaluates to TRUE or UNKNOWN. When a new row is
+      inserted, or an existing row is updated, the <code class="literal">&lt;search
+      condition&gt;</code> is evaluated and if it is FALSE, the insert or
+      update fails.</p>
+<p>A CHECK constraint for a DOMAIN is similar. In its
+      <code class="literal">&lt;search condition&gt;</code>, the term VALUE is used to
+      represents the value to which the DOMAIN applies.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (a VARCHAR(20) CHECK (a IS NOT NULL AND CHARACTER_LENGTH(a) &gt; 2))
+</pre>
+</div>
+<p>The search condition of a CHECK constraint cannot contain any
+      function that is not deterministic. A check constraint is a data
+      integrity constraint, therefore it must hold with respect to the rest of
+      the data in the database. It cannot use values that are temporal or
+      ephemeral. For example CURRENT_USER is a function that returns different
+      values depending on who is using the database, or CURRENT_DATE changes
+      day-to-day. Some temporal expressions are retrospectively deterministic
+      and are allowed in check constraints. For example, (CHECK VALUE &lt;
+      CURRENT_DATE) is valid, because CURRENT_DATE will not move backwards in
+      time, but (CHECK VALUE &gt; CURRENT_DATE) is not acceptable.</p>
+<p>If you want to enforce the condition that a date value that is
+      inserted into the database belongs to the future (at the time of
+      insertion), or any similar constraint, then use a TRIGGER with the
+      desired condition.</p>
+<a name="N10F18" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TABLE
+      writeability</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set table write property
+      (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;set table read only statement&gt; ::= SET TABLE
+      &lt;table name&gt; { READ ONLY | READ WRITE }</code>
+</p>
+<p>Set the writeability property of a table. Tables are writable
+      by default. This statement can be used to change the property between
+      <code class="literal">READ ONLY</code> and <code class="literal">READ WRITE</code>. This is
+      a feature of HyperSQL.</p>
+<a name="N10F2F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TABLE SOURCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set table source statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set table source statement&gt; ::= SET TABLE
+      &lt;table name&gt; SOURCE &lt;file and options&gt;
+      [DESC]</code>
+</p>
+<p>
+<code class="literal">&lt;file and options&gt;::= &lt;doublequote&gt;
+      &lt;file path&gt; [&lt;semicolon&gt; &lt;property&gt;...]
+      &lt;doublequote&gt; </code>
+</p>
+<p>Set the text source for a text table. This statement cannot be
+      used for tables that are not defined as TEXT TABLE.</p>
+<div class="variablelist">
+<p class="title">
+<b>Supported Properties</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">quoted = { true | false }</span>
+</p>
+</td><td>
+<p>default is true. If false, treats double quotes as normal
+            characters</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">all_quoted = { true | false }</span>
+</p>
+</td><td>
+<p>default is false. If true, adds double quotes around all
+            fields.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">encoding = &lt;encoding name&gt;</span>
+</p>
+</td><td>
+<p>character encoding for text and character fields, for
+            example, encoding=UTF-8</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">ignore_first = { true | false }</span>
+</p>
+</td><td>
+<p>default is false. If true ignores the first line of the
+            file</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">cache_scale= &lt;numeric value&gt;</span>
+</p>
+</td><td>
+<p>exponent to calculate rows of the text file in cache.
+            Default is 8, equivalent to nearly 800 rows</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">cache_size_scale = &lt;numeric value&gt;r</span>
+</p>
+</td><td>
+<p>exponent to calculate average size of each row in cache.
+            Default is 8, equivalent to 256 bytes per row.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">fs = &lt;unquoted character&gt;</span>
+</p>
+</td><td>
+<p>field separator</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">vs = &lt;unquoted character&gt;</span>
+</p>
+</td><td>
+<p>varchar separator</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Special indicators for HyperSQL Text Table separators</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">\semi</span>
+</p>
+</td><td>
+<p>semicolon</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\quote</span>
+</p>
+</td><td>
+<p>quote</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\space</span>
+</p>
+</td><td>
+<p>space character</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\apos</span>
+</p>
+</td><td>
+<p>apostrophe</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\n</span>
+</p>
+</td><td>
+<p>newline - Used as an end anchor (like $ in regular
+            expressions)</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\r</span>
+</p>
+</td><td>
+<p>carriage return</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\t</span>
+</p>
+</td><td>
+<p>tab</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\\</span>
+</p>
+</td><td>
+<p>backslash</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\u####</span>
+</p>
+</td><td>
+<p>a Unicode character specified in hexadecimal</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>In the example below, the text source of the table is set to
+      "myfile", the field separator to the pipe symbol, and the long varchar
+      separator to the tilde symbol.</p>
+<pre class="programlisting">    SET TABLE mytable SOURCE 'myfile;fs=|;vs=.;lvs=~'</pre>
+<p>Only a user with the DBA role can execute this
+      statement.</p>
+<a name="N10FB5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TABLE SOURCE
+      HEADER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set table source header
+      statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set table source header statement&gt; ::= SET
+      TABLE &lt;table name&gt; SOURCE HEADER &lt;header
+      string&gt;</code>
+</p>
+<p>Set the header for the text source for a text table. If this
+      command is used, the <code class="literal">&lt;header string&gt;</code> is used as
+      the first line of the source file of the text table. This line is not
+      part of the table data. Only a user with the DBA role can execute this
+      statement.</p>
+<a name="N10FC9" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TABLE SOURCE
+      on-off</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set table source on-off
+      statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set table source on-off statement&gt; ::= SET
+      TABLE &lt;table name&gt; SOURCE { ON | OFF } </code>
+</p>
+<p>Attach or detach a text table from its text source. This
+      command does not change the properties or the name of the file that is
+      the source of a text table. When OFF is specified, the command detaches
+      the table from its source and closes the file for the source. In this
+      state, it is not possible to read or write to the table. This allows the
+      user to replace the file with a different file, or delete it. When ON is
+      specified, the source file is read. Only a user with the DBA role can
+      execute this statement</p>
+<a name="N10FDA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter table statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter table statement&gt; ::= ALTER TABLE
+      &lt;table name&gt; &lt;alter table action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter table action&gt; ::= &lt;add column
+      definition&gt; | &lt;alter column definition&gt; | &lt;drop column
+      definition&gt; | &lt;add table constraint definition&gt; | &lt;drop
+      table constraint definition&gt;</code>
+</p>
+<p>Change the definition of a table. Specific types of this
+      statement are covered below.</p>
+<a name="N10FEE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ADD COLUMN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>add column definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;add column definition&gt; ::= ADD [ COLUMN ]
+      &lt;column definition&gt; [ BEFORE &lt;other column name&gt;
+      ]</code>
+</p>
+<p>Add a column to an existing table. The <code class="literal">&lt;column
+      definition&gt;</code> is specified the same way as it is used in
+      <code class="literal">&lt;table definition&gt;</code>. HyperSQL allows the use of
+      <code class="literal">[ BEFORE &lt;other column name&gt; ]</code> to specify at
+      which position the new column is added to the table.</p>
+<p>If the table contains rows, the new column must have a
+      <code class="literal">&lt;default clause&gt;</code> or use one of the forms of
+      GENERATED. The column values for each row is then filled with the result
+      of the <code class="literal">&lt;default clause&gt;</code> or the generated
+      value.</p>
+<a name="N11010" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER COLUMN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter column definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter column definition&gt; ::= ALTER [ COLUMN ]
+      &lt;column name&gt; &lt;alter column action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter column action&gt; ::= &lt;set column default
+      clause&gt; | &lt;drop column default clause&gt; | &lt;alter column data
+      type clause&gt; | &lt;alter identity column specification&gt; |
+      &lt;alter column nullability&gt; | &lt;alter column
+      name&gt;</code>
+</p>
+<p>Change a column and its definition. Specific types of this
+      statement are covered below. See also the RENAME statement
+      above.</p>
+<a name="N11024" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set column default clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;set column default clause&gt; ::= SET &lt;default
+      clause&gt;</code>
+</p>
+<p>Set the default clause for a column. This can be used if the
+      column is not defined as GENERATED.</p>
+<a name="N11035" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop column default clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop column default clause&gt; ::= DROP
+      DEFAULT</code>
+</p>
+<p>Drop the default clause from a column.</p>
+<a name="N11046" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATA TYPE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter column data type clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter column data type clause&gt; ::= SET DATA
+      TYPE &lt;data type&gt;</code>
+</p>
+<p>Change the declared type of a column. The (proposed) SQL
+      Standard allows only changes to type properties such as maximum length,
+      precision, or scale, and only changes that cause the property to
+      enlarge. HyperSQL allows changing the type if all the existing values
+      can be cast into the new type without string truncation or loss of
+      significant digits.</p>
+<a name="N11057" class="indexterm"></a>
+<p>
+<span class="bold"><strong>alter identity
+      column</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter identity column
+      specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter identity column specification&gt; ::=
+      &lt;alter identity column option&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;alter identity column option&gt; ::= &lt;alter
+      sequence generator restart option&gt; | SET &lt;basic sequence generator
+      option&gt;</code>
+</p>
+<p>Change the properties of an identity column. This command is
+      similar to the commands used for changing the properties of named
+      SEQUENCE objects discussed in this section.</p>
+<a name="N1106B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET NULL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter column nullability</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter column nullability&gt; ::= SET
+      NULL</code>
+</p>
+<p>Removes a NOT NULL constraint from a column. This option is
+      specific to HyperSQL</p>
+<a name="N1107C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP COLUMN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop column definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop column definition&gt; ::= DROP [ COLUMN ]
+      &lt;column name&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy a column of a base table. The <code class="literal">&lt;drop
+      behavior&gt;</code> is either <code class="literal">RESTRICT</code> or
+      <code class="literal">CASCADE</code>. If the column is referenced in a table
+      constraint that references other columns as well as this column, or if
+      the column is referenced in a VIEW, or the column is referenced in a
+      TRIGGER, then the statement will fail if <code class="literal">RESTRICT</code> is
+      specified. If <code class="literal">CASCADE</code> is specified, then any
+      CONSTRAINT, VIEW or TRIGGER object that references the column is dropped
+      with a cascading effect.</p>
+<a name="N1109C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ADD CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>add table constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;add table constraint definition&gt; ::= ADD
+      &lt;table constraint definition&gt;</code>
+</p>
+<p>Add a constraint to a table. The existing rows of the table
+      must conform to the added constraint, otherwise the statement will not
+      succeed.</p>
+<a name="N110AD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop table constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop table constraint definition&gt; ::= DROP
+      CONSTRAINT &lt;constraint name&gt; &lt;drop
+      behavior&gt;</code>
+</p>
+<p>Destroy a constraint on a table. The <code class="literal">&lt;drop
+      behavior&gt;</code> has an effect only on UNIQUE and PRIMARY KEY
+      constraints. If such a constraint is referenced by a FOREIGN KEY
+      constraint, the FOREIGN KEY constraint will be dropped if
+      <code class="literal">CASCADE</code> is specified. If the columns of such a
+      constraint are used in a GROUP BY clause in the query expression of a
+      VIEW or another kind of schema object, and a functional dependency
+      relationship exists between these columns and the other columns in that
+      query expression, then the VIEW or other schema object will be dropped
+      when <code class="literal">CASCADE</code> is specified.</p>
+<a name="N110C7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop table statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop table statement&gt; ::= DROP TABLE [ IF
+      EXISTS ] &lt;table name&gt; [ IF EXISTS ] &lt;drop
+      behavior&gt;</code>
+</p>
+<p>Destroy a table. The default drop behaviour is RESTRICT and
+      will cause the statement to fail if there is any view or foreign key
+      constraint that references the table. If <code class="literal">&lt;drop
+      behavior&gt;</code> is <code class="literal">CASCADE</code>, it causes all
+      schema objects that reference the table to drop. Referencing views are
+      dropped. In the case of foreign key constraints that reference the
+      table, the constraint is dropped, rather than the TABLE or DOMAIN that
+      contains it.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N110DE"></a>View Creation and Manipulation</h3>
+</div>
+</div>
+</div>
+<a name="N110E1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE VIEW</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>view definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;view definition&gt; ::= CREATE [ RECURSIVE ] VIEW
+      &lt;table name&gt; &lt;view specification&gt; AS &lt;query
+      expression&gt; [ WITH [ CASCADED | LOCAL ] CHECK OPTION
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;view specification&gt; ::= [ &lt;left paren&gt;
+      &lt;view column list&gt; &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;view column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>Define a view. The <code class="literal">&lt;query expression&gt;</code>
+      is a SELECT or similar statement. The <code class="literal">&lt;view column
+      list&gt;</code> is the list of unique names for the columns of the
+      view. The number of columns in the <code class="literal">&lt;view column
+      list&gt;</code> must match the number of columns returned by the
+      <code class="literal">&lt;query expression&gt;</code>. If <code class="literal">&lt;view column
+      list&gt;</code> is not specified, then the columns of the
+      <code class="literal">&lt;query expression&gt;</code> should have unique names and
+      are used as the names of the view column.</p>
+<p>Some views are updatable. As covered elsewhere, an updatable
+      view is based on a single table or updatable view. For updatable views,
+      the optional <code class="literal">CHECK OPTION</code> clause can be specified. If
+      this option is specified, then if a row of the view is updated or a new
+      row is inserted into the view, then it should contain such values that
+      the row would be included in the view after the change. If <code class="literal">WITH
+      CASCADED CHECK OPTION</code> is specified, then if the
+      <code class="literal">&lt;query expression&gt;</code> of the view references
+      another view, then the search condition of the underlying view should
+      also be satisfied by the update or insert operation.</p>
+<p>More on recursive...</p>
+<a name="N11117" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP VIEW</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop view statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop view statement&gt; ::= DROP VIEW [ IF EXISTS
+      ] &lt;table name&gt; [ IF EXISTS ] &lt;drop
+      behavior&gt;</code>
+</p>
+<p>Destroy a view. The <code class="literal">&lt;drop behavior&gt;</code> is
+      similar to dropping a table.</p>
+<a name="N1112B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER VIEW</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter view statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter view statement&gt; ::= ALTER VIEW &lt;table
+      name&gt; &lt;view specification&gt; AS &lt;query expression&gt; [ WITH [
+      CASCADED | LOCAL ] CHECK OPTION ]</code>
+</p>
+<p>Alter a view. The statement is otherwise identical to CREATE
+      VIEW. The new definition replaces the old. If there are database objects
+      such as routines or views that reference the view, then these objects
+      are recompiled with the new view definition. If the new definition is
+      not compatible, the statement fails.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1113C"></a>Domain Creation and Manipulation</h3>
+</div>
+</div>
+</div>
+<a name="N1113F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE DOMAIN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>domain definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;domain definition&gt; ::= CREATE DOMAIN &lt;domain
+      name&gt; [ AS ] &lt;predefined type&gt; [ &lt;default clause&gt; ] [
+      &lt;domain constraint&gt;... ] [ &lt;collate clause&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;domain constraint&gt; ::= [ &lt;constraint name
+      definition&gt; ] &lt;check constraint definition&gt; [ &lt;constraint
+      characteristics&gt; ]</code>
+</p>
+<p>Define a domain. Although a DOMAIN is not strictly a type in
+      the SQL Standard, it can be informally considered as a type. A DOMAIN is
+      based on a <code class="literal">&lt;predefined type&gt;</code>, which is a base
+      type defined by the Standard. It can have a <code class="literal">&lt;default
+      clause&gt;</code>, similar to a column default clause. It can also
+      have one or more CHECK constraints which limit the values that can be
+      assigned to a column or variable that has the DOMAIN as its
+      type.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE DOMAIN valid_string AS VARCHAR(20) DEFAULT 'NO VALUE' CHECK (value IS NOT NULL AND CHARACTER_LENGTH(value) &gt; 2) 
+</pre>
+</div>
+<a name="N1115C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER DOMAIN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter domain statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter domain statement&gt; ::= ALTER DOMAIN
+      &lt;domain name&gt; &lt;alter domain action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter domain action&gt; ::= &lt;set domain default
+      clause&gt; | &lt;drop domain default clause&gt; | &lt;add domain
+      constraint definition&gt; | &lt;drop domain constraint
+      definition&gt;</code>
+</p>
+<p>Change a domain and its definition.</p>
+<a name="N11170" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set domain default clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;set domain default clause&gt; ::= SET &lt;default
+      clause&gt;</code>
+</p>
+<p>Set the default value in a domain.</p>
+<a name="N11181" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP DEFAULT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop domain default clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop domain default clause&gt; ::= DROP
+      DEFAULT</code>
+</p>
+<p>Remove the default clause of a domain.</p>
+<a name="N11192" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ADD CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>add domain constraint definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;add domain constraint definition&gt; ::= ADD
+      &lt;domain constraint&gt;</code>
+</p>
+<p>Add a constraint to a domain.</p>
+<a name="N111A3" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop domain constraint
+      definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop domain constraint definition&gt; ::= DROP
+      CONSTRAINT &lt;constraint name&gt;</code>
+</p>
+<p>Destroy a constraint on a domain. If the <code class="literal">&lt;drop
+      behavior&gt;</code> is <code class="literal">CASCADE</code>, and the constraint
+      is a UNIQUE constraint which is referenced by a FOREIGN KEY constraint
+      on another table, then the FOREIGN KEY constraint is also
+      dropped.</p>
+<a name="N111BA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP DOMAIN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop domain statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop domain statement&gt; ::= DROP DOMAIN
+      &lt;domain name&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy a domain. If <code class="literal">&lt;drop behavior&gt;</code>
+      is <code class="literal">CASCADE</code>, it works differently from most other
+      objects. If a table features a column of the specified DOMAIN, the
+      column survives and inherits the DEFAULT CLAUSE, and the CHECK
+      CONSTRAINT of the DOMAIN.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N111D1"></a>Trigger Creation</h3>
+</div>
+</div>
+</div>
+<a name="N111D4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TRIGGER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>trigger definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;trigger definition&gt; ::= CREATE TRIGGER
+      &lt;trigger name&gt; &lt;trigger action time&gt; &lt;trigger event&gt;
+      ON &lt;table name&gt; [ REFERENCING &lt;transition table or variable
+      list&gt; ] &lt;triggered action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;trigger action time&gt; ::= BEFORE | AFTER |
+      INSTEAD OF</code>
+</p>
+<p>
+<code class="literal">&lt;trigger event&gt; ::= INSERT | DELETE | UPDATE [
+      OF &lt;trigger column list&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;trigger column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered action&gt; ::= [ FOR EACH { ROW |
+      STATEMENT } ] [ &lt;triggered when clause&gt; ] &lt;triggered SQL
+      statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered when clause&gt; ::= WHEN &lt;left
+      paren&gt; &lt;search condition&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered SQL statement&gt; ::= &lt;SQL procedure
+      statement&gt; | BEGIN ATOMIC { &lt;SQL procedure statement&gt;
+      &lt;semicolon&gt; }... END | [QUEUE &lt;integer literal&gt;] [NOWAIT]
+      CALL &lt;HSQLDB trigger class FQN&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transition table or variable list&gt; ::=
+      &lt;transition table or variable&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;transition table or variable&gt; ::= OLD [ ROW ] [
+      AS ] &lt;old transition variable name&gt; | NEW [ ROW ] [ AS ] &lt;new
+      transition variable name&gt; | OLD TABLE [ AS ] &lt;old transition table
+      name&gt; | NEW TABLE [ AS ] &lt;new transition table
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;old transition table name&gt; ::= &lt;transition
+      table name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;new transition table name&gt; ::= &lt;transition
+      table name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transition table name&gt; ::=
+      &lt;identifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;old transition variable name&gt; ::=
+      &lt;correlation name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;new transition variable name&gt; ::=
+      &lt;correlation name&gt;</code>
+</p>
+<p>Trigger definition is a relatively complex statement. The
+      combination of <code class="literal">&lt;trigger action time&gt;</code> and
+      <code class="literal">&lt;trigger event&gt;</code> determines the type of the
+      trigger. Examples include BEFORE DELETE, AFTER UPDATE, INSTEAD OF
+      INSERT. If the optional <code class="literal">[ OF &lt;trigger column list&gt;
+      ]</code> is specified for an UPDATE trigger, then the trigger is
+      activated only if one of the columns that is in the <code class="literal">&lt;trigger
+      column list&gt;</code> is specified in the UPDATE statement that
+      activates the trigger.</p>
+<p>If a trigger is <code class="literal">FOR EACH ROW</code>, which is the
+      default option, then the trigger is activated for each row of the table
+      that is affected by the execution of an SQL statement. Otherwise, it is
+      activated once only per statement execution. In the first case, there is
+      a before and after state for each row. For UPDATE triggers, both before
+      and after states exist, representing the row before the update, and
+      after the update. For DELETE, triggers, there is only a before state.
+      For INSERT triggers, there is only an after state. If a trigger is
+      <code class="literal">FOR EACH STATEMENT</code>, then a transient table is created
+      containing all the rows for the before state and another transient table
+      is created for the after state.</p>
+<p>The <code class="literal">[ REFERENCING &lt;transition table or variable&gt;
+      ]</code> is used to give a name to the before and after data row or
+      table. This name can be referenced in the <code class="literal">&lt;SQL procedure
+      statement&gt;</code> to access the data.</p>
+<p>The optional <code class="literal">&lt;triggered when clause&gt;</code>
+      is a search condition, similar to the search condition of a DELETE or
+      UPDATE statement. If the search condition is not TRUE for a row, then
+      the trigger is not activated for that row.</p>
+<p>The <code class="literal">&lt;SQL procedure statement&gt;</code> is
+      limited to INSERT, DELETE, UPDATE and MERGE statements.</p>
+<p>The <code class="literal">&lt;HSQLDB trigger class FQN&gt;</code> is a
+      delimited identifier that contains the fully qualified name of a Java
+      class that implements the <code class="classname">org.hsqldb.Trigger</code>
+      interface.</p>
+<p>Early releases of HyperSQL version 2.0 do not allow the use of
+      OLD TABLE or NEW TABLE in statement level trigger definitions.</p>
+<a name="N1123C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP TRIGGER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop trigger statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop trigger statement&gt; ::= DROP TRIGGER
+      &lt;trigger name&gt;</code>
+</p>
+<p>Destroy a trigger.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1124D"></a>Routine Creation</h3>
+</div>
+</div>
+</div>
+<a name="N11250" class="indexterm"></a>
+<p>
+<span class="bold"><strong>schema routine</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL-invoked routine</em></span>
+</p>
+<p>
+<code class="literal">&lt;SQL-invoked routine&gt; ::= &lt;schema
+      routine&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema routine&gt; ::= &lt;schema procedure&gt; |
+      &lt;schema function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema procedure&gt; ::= CREATE &lt;SQL-invoked
+      procedure&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema function&gt; ::= CREATE &lt;SQL-invoked
+      function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL-invoked procedure&gt; ::= PROCEDURE &lt;schema
+      qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+      &lt;routine characteristics&gt; &lt;routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL-invoked function&gt; ::= { &lt;function
+      specification&gt; | &lt;method specification designator&gt; }
+      &lt;routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL parameter declaration list&gt; ::= &lt;left
+      paren&gt; [ &lt;SQL parameter declaration&gt; [ { &lt;comma&gt; &lt;SQL
+      parameter declaration&gt; }... ] ] &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL parameter declaration&gt; ::= [ &lt;parameter
+      mode&gt; ] [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt; [
+      RESULT ]</code>
+</p>
+<p>
+<code class="literal">&lt;parameter mode&gt; ::= IN | OUT |
+      INOUT</code>
+</p>
+<p>
+<code class="literal">&lt;parameter type&gt; ::= &lt;data
+      type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;function specification&gt; ::= FUNCTION &lt;schema
+      qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+      &lt;returns clause&gt; &lt;routine characteristics&gt; [ &lt;dispatch
+      clause&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;method specification designator&gt; ::= SPECIFIC
+      METHOD &lt;specific method name&gt; | [ INSTANCE | STATIC | CONSTRUCTOR
+      ] METHOD &lt;method name&gt; &lt;SQL parameter declaration list&gt; [
+      &lt;returns clause&gt; ] FOR &lt;schema-resolved user-defined type
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;routine characteristics&gt; ::= [ &lt;routine
+      characteristic&gt;... ]</code>
+</p>
+<p>
+<code class="literal">&lt;routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | SPECIFIC &lt;specific
+      name&gt; | &lt;deterministic characteristic&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | &lt;savepoint level
+      indication&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;savepoint level indication&gt; ::= NEW SAVEPOINT
+      LEVEL | OLD SAVEPOINT LEVEL</code>
+</p>
+<p>
+<code class="literal">&lt;returned result sets characteristic&gt; ::=
+      DYNAMIC RESULT SETS &lt;maximum returned result
+      sets&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;parameter style clause&gt; ::= PARAMETER STYLE
+      &lt;parameter style&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;dispatch clause&gt; ::= STATIC
+      DISPATCH</code>
+</p>
+<p>
+<code class="literal">&lt;returns clause&gt; ::= RETURNS &lt;returns
+      type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns type&gt; ::= &lt;returns data type&gt; [
+      &lt;result cast&gt; ] | &lt;returns table type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns table type&gt; ::= TABLE &lt;table
+      function column list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table function column list&gt; ::= &lt;left
+      paren&gt; &lt;table function column list element&gt; [ { &lt;comma&gt;
+      &lt;table function column list element&gt; }... ] &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table function column list element&gt; ::=
+      &lt;column name&gt; &lt;data type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;result cast&gt; ::= CAST FROM &lt;result cast from
+      type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;result cast from type&gt; ::= &lt;data type&gt; [
+      &lt;locator indication&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;returns data type&gt; ::= &lt;data type&gt; [
+      &lt;locator indication&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;routine body&gt; ::= &lt;SQL routine spec&gt; |
+      &lt;external body reference&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL routine spec&gt; ::= [ &lt;rights clause&gt; ]
+      &lt;SQL routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;rights clause&gt; ::= SQL SECURITY INVOKER | SQL
+      SECURITY DEFINER</code>
+</p>
+<p>
+<code class="literal">&lt;SQL routine body&gt; ::= &lt;SQL procedure
+      statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;external body reference&gt; ::= EXTERNAL [ NAME
+      &lt;external routine name&gt; ] [ &lt;parameter style clause&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;parameter style&gt; ::= SQL |
+      GENERAL</code>
+</p>
+<p>
+<code class="literal">&lt;deterministic characteristic&gt; ::= DETERMINISTIC
+      | NOT DETERMINISTIC</code>
+</p>
+<p>
+<code class="literal">&lt;SQL-data access indication&gt; ::= NO SQL |
+      CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA</code>
+</p>
+<p>
+<code class="literal">&lt;null-call clause&gt; ::= RETURNS NULL ON NULL
+      INPUT | CALLED ON NULL INPUT</code>
+</p>
+<p>
+<code class="literal">&lt;maximum returned result sets&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>Define an SQL-invoked routine.</p>
+<a name="N112CA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER routine</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter routine statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter routine statement&gt; ::= ALTER &lt;specific
+      routine designator&gt; &lt;alter routine characteristics&gt; &lt;alter
+      routine behavior&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter routine characteristics&gt; ::= &lt;alter
+      routine characteristic&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;alter routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | NAME &lt;external routine
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter routine behavior&gt; ::=
+      RESTRICT</code>
+</p>
+<p>Alter a characteristic of an SQL-invoked routine. Early
+      releases of HyperSQL 2.0 may not support this statement.</p>
+<a name="N112E4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop routine statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop routine statement&gt; ::= DROP &lt;specific
+      routine designator&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy an SQL-invoked routine.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N112F5"></a>Sequence Creation</h3>
+</div>
+</div>
+</div>
+<a name="N112F8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE SEQUENCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>sequence generator definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;sequence generator definition&gt; ::= CREATE
+      SEQUENCE &lt;sequence generator name&gt; [ &lt;sequence generator
+      options&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator options&gt; ::= &lt;sequence
+      generator option&gt; ...</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator option&gt; ::= &lt;sequence
+      generator data type option&gt; | &lt;common sequence generator
+      options&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;common sequence generator options&gt; ::=
+      &lt;common sequence generator option&gt; ...</code>
+</p>
+<p>
+<code class="literal">&lt;common sequence generator option&gt; ::=
+      &lt;sequence generator start with option&gt; | &lt;basic sequence
+      generator option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;basic sequence generator option&gt; ::=
+      &lt;sequence generator increment by option&gt; | &lt;sequence generator
+      maxvalue option&gt; | &lt;sequence generator minvalue option&gt; |
+      &lt;sequence generator cycle option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator data type option&gt; ::= AS
+      &lt;data type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator start with option&gt; ::= START
+      WITH &lt;sequence generator start value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator start value&gt; ::= &lt;signed
+      numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator increment by option&gt; ::=
+      INCREMENT BY &lt;sequence generator increment&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator increment&gt; ::= &lt;signed
+      numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator maxvalue option&gt; ::=
+      MAXVALUE &lt;sequence generator max value&gt; | NO
+      MAXVALUE</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator max value&gt; ::= &lt;signed
+      numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator minvalue option&gt; ::=
+      MINVALUE &lt;sequence generator min value&gt; | NO
+      MINVALUE</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator min value&gt; ::= &lt;signed
+      numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator cycle option&gt; ::= CYCLE | NO
+      CYCLE</code>
+</p>
+<p>Define a named sequence generator. A SEQUENCE object generates
+      a sequence of integers according to the specified rules. The simple
+      definition without the options defines a sequence of numbers in INTEGER
+      type starting at 1 and incrementing by 1. By default the
+      <code class="literal">CYCLE</code> property is set and the minimum and maximum
+      limits are the minimum and maximum limits of the type of returned
+      values. There are self-explanatory options for changing various
+      properties of the sequence. The <code class="literal">MAXVALUE</code> and
+      <code class="literal">MINVALUE</code> specify the upper and lower limits. If
+      <code class="literal">CYCLE</code> is specified, after the sequence returns the
+      highest or lowest value in range, the next value will respectively be
+      the lowest or highest value in range. If <code class="literal">NO CYCLE</code> is
+      specified, the use of the sequence generator results in an error once
+      the limit has been reached.</p>
+<p>The integer types: SMALLINT, INTEGER, BIGINT, DECIMAL and
+      NUMERIC can be used as the type of the sequence. DECIMAL and NUMERIC
+      types must have a scale of 0 and a precision not exceeding 18.</p>
+<a name="N11347" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER SEQUENCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>alter sequence generator
+      statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter sequence generator statement&gt; ::= ALTER
+      SEQUENCE &lt;sequence generator name&gt; &lt;alter sequence generator
+      options&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter sequence generator options&gt; ::= &lt;alter
+      sequence generator option&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;alter sequence generator option&gt; ::= &lt;alter
+      sequence generator restart option&gt; | &lt;basic sequence generator
+      option&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;alter sequence generator restart option&gt; ::=
+      RESTART [ WITH &lt;sequence generator restart value&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;sequence generator restart value&gt; ::=
+      &lt;signed numeric literal&gt;</code>
+</p>
+<p>Change the definition of a named sequence generator. The same
+      options that are used in the definition of the SEQUENCE can be used to
+      alter it. The exception is the option for the start value which is
+      <code class="literal">RESTART WITH</code> for the ALTER SEQUENCE
+      statement..</p>
+<a name="N11367" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP SEQUENCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop sequence generator
+      statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop sequence generator statement&gt; ::= DROP
+      SEQUENCE [ IF EXISTS ] &lt;sequence generator name&gt; [ IF EXISTS ]
+      &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy an external sequence generator. If the
+      <code class="literal">&lt;drop behavior&gt;</code> is <code class="literal">CASCADE</code>,
+      then all objects that reference the sequence are dropped. These objects
+      can be VIEW, ROUTINE or TRIGGER objects.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1137F"></a>SQL Procedure Statement</h3>
+</div>
+</div>
+</div>
+<a name="N11382" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQL procedure
+      statement</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL procedure statement</em></span>
+</p>
+<p>The definition of CREATE TRIGGER and CREATE PROCEDURE
+      statements refers to &lt;SQL procedure statement&gt;. The definition of
+      this element is given below. However, only a subset of these statements
+      are allowed in trigger or routine definition.</p>
+<p>
+<code class="literal">&lt;SQL procedure statement&gt; ::= &lt;SQL executable
+      statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL executable statement&gt; ::= &lt;SQL schema
+      statement&gt; | &lt;SQL data statement&gt; | &lt;SQL control
+      statement&gt; | &lt;SQL transaction statement&gt; | &lt;SQL connection
+      statement&gt; | &lt;SQL session statement&gt; | &lt;SQL diagnostics
+      statement&gt; | &lt;SQL dynamic statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL schema statement&gt; ::= &lt;SQL schema
+      definition statement&gt; | &lt;SQL schema manipulation
+      statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL schema definition statement&gt; ::= &lt;schema
+      definition&gt; | &lt;table definition&gt; | &lt;view definition&gt; |
+      &lt;SQL-invoked routine&gt; | &lt;grant statement&gt; | &lt;role
+      definition&gt; | &lt;domain definition&gt; | &lt;character set
+      definition&gt; | &lt;collation definition&gt; | &lt;transliteration
+      definition&gt; | &lt;assertion definition&gt; | &lt;trigger
+      definition&gt; | &lt;user-defined type definition&gt; | &lt;user-defined
+      cast definition&gt; | &lt;user-defined ordering definition&gt; |
+      &lt;transform definition&gt; | &lt;sequence generator
+      definition&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL schema manipulation statement&gt; ::= &lt;drop
+      schema statement&gt; | &lt;alter table statement&gt; | &lt;drop table
+      statement&gt; | &lt;drop view statement&gt; | &lt;alter routine
+      statement&gt; | &lt;drop routine statement&gt; | &lt;drop user-defined
+      cast statement&gt; | &lt;revoke statement&gt; | &lt;drop role
+      statement&gt; | &lt;alter domain statement&gt; | &lt;drop domain
+      statement&gt; | &lt;drop character set statement&gt; | &lt;drop
+      collation statement&gt; | &lt;drop transliteration statement&gt; |
+      &lt;drop assertion statement&gt; | &lt;drop trigger statement&gt; |
+      &lt;alter type statement&gt; | &lt;drop data type statement&gt; |
+      &lt;alter sequence generator statement&gt; | &lt;drop sequence generator
+      statement&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1139F"></a>Other Schema Object Creation</h3>
+</div>
+</div>
+</div>
+<a name="N113A2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE INDEX</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>create index statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;create index statement&gt; ::= CREATE INDEX
+      &lt;index name&gt; ON &lt;table name&gt; &lt;left paren&gt; {&lt;column
+      name&gt; [ASC | DESC]}, ... &lt;left paren&gt;</code>
+</p>
+<p>Creates an index on a group of columns of a table. The optional
+      [ASC | DESC] specifies if the column is indexed in the ascending or
+      descending order, but has no effect on how the index is created (it is
+      allowed for compatibility with other database engines). HyperSQL can use
+      all indexes in ascending or descending order as needed.</p>
+<a name="N113B3" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP INDEX</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop index statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop index statement&gt; ::= DROP INDEX [ IF
+      EXISTS ] &lt;index name&gt; [ IF EXISTS ]</code>
+</p>
+<p>Destroy an index.</p>
+<a name="N113C4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TYPE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>user-defined type definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;user-defined type definition&gt; ::= CREATE TYPE
+      &lt;user-defined type body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;user-defined type body&gt; ::= &lt;schema-resolved
+      user-defined type name&gt; [ AS &lt;representation&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;representation&gt; ::= &lt;predefined
+      type&gt;</code>
+</p>
+<p>Define a user-defined type. Currently only simple distinct
+      types can be defined without further attributes.</p>
+<a name="N113DB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE CAST</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>user-defined cast definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;user-defined cast definition&gt; ::= CREATE CAST
+      &lt;left paren&gt; &lt;source data type&gt; AS &lt;target data type&gt;
+      &lt;right paren&gt; WITH &lt;cast function&gt; [ AS ASSIGNMENT
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;cast function&gt; ::= &lt;specific routine
+      designator&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;source data type&gt; ::= &lt;data
+      type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;target data type&gt; ::= &lt;data
+      type&gt;</code>
+</p>
+<p>Define a user-defined cast. This feature may be supported in a
+      future versions of HyperSQL.</p>
+<a name="N113F5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP CAST</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop user-defined cast statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop user-defined cast statement&gt; ::= DROP CAST
+      &lt;left paren&gt; &lt;source data type&gt; AS &lt;target data type&gt;
+      &lt;right paren&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy a user-defined cast. This feature may be supported in a
+      future versions of HyperSQL.</p>
+<a name="N11406" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE CHARACTER SET</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>character set definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;character set definition&gt; ::= CREATE CHARACTER
+      SET &lt;character set name&gt; [ AS ] &lt;character set source&gt; [
+      &lt;collate clause&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;character set source&gt; ::= GET &lt;character set
+      specification&gt;</code>
+</p>
+<p>Define a character set. A new CHARACTER SET is based on an
+      existing CHARACTER SET. The optional <code class="literal">&lt;collate
+      clause&gt;</code> specifies the collation to be used, otherwise the
+      collation is inherited from the default collation for the source
+      CHARACTER SET.</p>
+<a name="N1141D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP CHARACTER SET</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop character set statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop character set statement&gt; ::= DROP
+      CHARACTER SET &lt;character set name&gt;</code>
+</p>
+<p>Destroy a character set. If the character set name is
+      referenced in any database object, the command fails. Note that
+      <code class="literal">CASCADE</code> or <code class="literal">RESTRICT</code> cannot be
+      specified for this command.</p>
+<a name="N11434" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE COLLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>collation definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;collation definition&gt; ::= CREATE COLLATION
+      &lt;collation name&gt; FOR &lt;character set specification&gt; FROM
+      &lt;existing collation name&gt; [ &lt;pad characteristic&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;existing collation name&gt; ::= &lt;collation
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;pad characteristic&gt; ::= NO PAD | PAD
+      SPACE</code>
+</p>
+<p>Define a collation. A new collation is based on an existing
+      COLLATION and applies to an existing CHARACTER SET. The <code class="literal">&lt;pad
+      characteristic&gt;</code> specifies whether strings are padded with
+      spaces for comparison. This feature may be supported in a future
+      versions of HyperSQL.</p>
+<a name="N1144E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP COLLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop collation statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop collation statement&gt; ::= DROP COLLATION
+      &lt;collation name&gt; &lt;drop behavior&gt;</code>
+</p>
+<p>Destroy a collation. If the <code class="literal">&lt;drop
+      behavior&gt;</code> is <code class="literal">CASCADE</code>, then all
+      references to the collation revert to the default collation that would
+      be in force if the dropped collation was not specified. This feature may
+      be supported in a future versions of HyperSQL.</p>
+<a name="N11465" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TRANSLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>transliteration definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;transliteration definition&gt; ::= CREATE
+      TRANSLATION &lt;transliteration name&gt; FOR &lt;source character set
+      specification&gt; TO &lt;target character set specification&gt; FROM
+      &lt;transliteration source&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;source character set specification&gt; ::=
+      &lt;character set specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;target character set specification&gt; ::=
+      &lt;character set specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transliteration source&gt; ::= &lt;existing
+      transliteration name&gt; | &lt;transliteration
+      routine&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;existing transliteration name&gt; ::=
+      &lt;transliteration name&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;transliteration routine&gt; ::= &lt;specific
+      routine designator&gt;</code>
+</p>
+<p>Define a character transliteration. This feature may be
+      supported in a future versions of HyperSQL.</p>
+<a name="N11485" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP TRANSLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop transliteration statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop transliteration statement&gt; ::= DROP
+      TRANSLATION &lt;transliteration name&gt;</code>
+</p>
+<p>Destroy a character transliteration. This feature may be
+      supported in a future versions of HyperSQL.</p>
+<a name="N11496" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE ASSERTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>assertion definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;assertion definition&gt; ::= CREATE ASSERTION
+      &lt;constraint name&gt; CHECK &lt;left paren&gt; &lt;search
+      condition&gt; &lt;right paren&gt; [ &lt;constraint characteristics&gt;
+      ]</code>
+</p>
+<p>Specify an integrity constraint. This feature may be supported
+      in a future versions of HyperSQL.</p>
+<a name="N114A7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP ASSERTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop assertion statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop assertion statement&gt; ::= DROP ASSERTION
+      &lt;constraint name&gt; [ &lt;drop behavior&gt; ]</code>
+</p>
+<p>Destroy an assertion. This feature may be supported in a future
+      versions of HyperSQL.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N114B8"></a>The Information Schema</h2>
+</div>
+</div>
+</div>
+<p>The Information Schema is a special schema in each catalog. The SQL
+    Standard defines a number of character sets and domains in this schema. In
+    addition, all the implementation-defined collations belong to the
+    Information Schema.</p>
+<p>The SQL Standard defines many views in the Information Schema. These
+    views show the properties of the database objects that currently exist in
+    the database. When a user accesses one these views, only the properties of
+    database objects that the user can access are included.</p>
+<p>HyperSQL supports all the views defined by the Standard, apart from
+    a few views that report on extended user-defined types and other optional
+    features of the Standard that are not supported by HyperSQL.</p>
+<p>HyperSQL also adds some views to the Information Schema. These views
+    are for features that are not reported in any of the views defined by the
+    Standard, or for use by JDBC DatabaseMetaData.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N114C3"></a>Predefined Character Sets, Collations and Domains</h3>
+</div>
+</div>
+</div>
+<p>The SQL Standard defines a number of character sets and domains in
+      the INFORMATION SCHEMA.</p>
+<p>These domains are used in the INFORMATION SCHEMA views:</p>
+<p>CARDINAL_NUMBER, YES_OR_NO, CHARACTER_DATA, SQL_IDENTIFIER,
+      TIME_STAMP</p>
+<p>All available collations are in the INFORMATION
+      SCHEMA.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N114CE"></a>Views in INFORMATION SCHEMA</h3>
+</div>
+</div>
+</div>
+<p>The following views are defined by the SQL Standard:</p>
+<p>ADMINISTRABLE_ROLE_AUTHORIZATIONS</p>
+<p>APPLICABLE_ROLES</p>
+<p>ASSERTIONS</p>
+<p>AUTHORIZATIONS</p>
+<p>CHARACTER_SETS</p>
+<p>CHECK_CONSTRAINTS</p>
+<p>CHECK_CONSTRAINT_ROUTINE_USAGE</p>
+<p>COLLATIONS</p>
+<p>COLUMNS</p>
+<p>COLUMN_COLUMN_USAGE</p>
+<p>COLUMN_DOMAIN_USAGE</p>
+<p>COLUMN_PRIVILEGES</p>
+<p>COLUMN_UDT_USAGE</p>
+<p>CONSTRAINT_COLUMN_USAGE</p>
+<p>CONSTRAINT_TABLE_USAGE</p>
+<p>DATA_TYPE_PRIVILEGES</p>
+<p>DOMAINS</p>
+<p>DOMAIN_CONSTRAINTS</p>
+<p>ENABLED_ROLES</p>
+<p>INFORMATION_SCHEMA_CATALOG_NAME</p>
+<p>KEY_COLUMN_USAGE</p>
+<p>PARAMETERS</p>
+<p>REFERENTIAL_CONSTRAINTS</p>
+<p>ROLE_AUTHORIZATION_DESCRIPTORS</p>
+<p>ROLE_COLUMN_GRANTS</p>
+<p>ROLE_ROUTINE_GRANTS</p>
+<p>ROLE_TABLE_GRANTS</p>
+<p>ROLE_UDT_GRANTS</p>
+<p>ROLE_USAGE_GRANTS</p>
+<p>ROUTINE_COLUMN_USAGE</p>
+<p>ROUTINE_JAR_USAGE</p>
+<p>ROUTINE_PRIVILEGES</p>
+<p>ROUTINE_ROUTINE_USAGE</p>
+<p>ROUTINE_SEQUENCE_USAGE</p>
+<p>ROUTINE_TABLE_USAGE</p>
+<p>ROUTINES</p>
+<p>SCHEMATA</p>
+<p>SEQUENCES</p>
+<p>SQL_FEATURES</p>
+<p>SQL_IMPLEMENTATION_INFO</p>
+<p>SQL_PACKAGES</p>
+<p>SQL_PARTS</p>
+<p>SQL_SIZING</p>
+<p>SQL_SIZING_PROFILES</p>
+<p>TABLES</p>
+<p>TABLE_CONSTRAINTS</p>
+<p>TABLE_PRIVILEGES</p>
+<p>TRANSLATIONS</p>
+<p>TRIGGERED_UPDATE_COLUMNS</p>
+<p>TRIGGERS</p>
+<p>TRIGGER_COLUMN_USAGE</p>
+<p>TRIGGER_ROUTINE_USAGE</p>
+<p>TRIGGER_SEQUENCE_USAGE</p>
+<p>TRIGGER_TABLE_USAGE</p>
+<p>USAGE_PRIVILEGES</p>
+<p>USER_DEFINED_TYPES</p>
+<p>VIEWS</p>
+<p>VIEW_COLUMN_USAGE</p>
+<p>VIEW_ROUTINE_USAGE</p>
+<p>VIEW_TABLE_USAGE</p>
+<p>The following views are specific to HyperSQL:</p>
+<p>SYSTEM_BESTROWIDENTIFIER</p>
+<p>SYSTEM_CACHEINFO</p>
+<p>SYSTEM_COLUMNS</p>
+<p>SYSTEM_COMMENTS</p>
+<p>SYSTEM_CROSSREFERENCE</p>
+<p>SYSTEM_INDEXINFO</p>
+<p>SYSTEM_PRIMARYKEYS</p>
+<p>SYSTEM_PROCEDURECOLUMNS</p>
+<p>SYSTEM_PROCEDURES</p>
+<p>SYSTEM_PROPERTIES</p>
+<p>SYSTEM_SCHEMAS</p>
+<p>SYSTEM_SEQUENCES</p>
+<p>SYSTEM_SESSIONINFO</p>
+<p>SYSTEM_SESSIONS</p>
+<p>SYSTEM_TABLES</p>
+<p>SYSTEM_TABLETYPES</p>
+<p>SYSTEM_TEXTTABLES</p>
+<p>SYSTEM_TYPEINFO</p>
+<p>SYSTEM_UDTS</p>
+<p>SYSTEM_USERS</p>
+<p>SYSTEM_VERSIONCOLUMNS</p>
+</div>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="texttables-chapt"></a>Chapter&nbsp;5.&nbsp;Text Tables</h2>
+</div>
+<div>
+<h3 class="subtitle">
+<i>Text Tables as a Standard Feature of Hsqldb</i>
+</h3>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Bob</span> <span class="surname">Preston</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N115AC"></a>
+<p>Copyright 2002-2010 Bob Preston and Fred Toussi. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license. Additional permission is granted to the
+      HSQL Development Group to distribute this document with or without
+      alterations under the terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#texttables_overview-sect">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#texttables_impl-sect">The Implementation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N115BF">Definition of Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N115CF">Scope and Reassignment</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N115E5">Null Values in Columns of Text Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N115EF">Configuration</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#disconnecting_text_tables">Disconnecting Text Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#texttables_issues-sect">Text File Usage</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#texttables_globalprops-sect">Text File Global Properties</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N116E4">Transactions</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="texttables_overview-sect"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>Text Table support for HSQLDB was originally developed by Bob
+    Preston independently from the Project. Subsequently Bob joined the
+    Project and incorporated this feature into version 1.7.0, with a number of
+    enhancements, especially the use of conventional SQL commands for
+    specifying the files used for Text Tables.</p>
+<p>In a nutshell, Text Tables are CSV or other delimited files treated
+    as SQL tables. Any ordinary CSV or other delimited file can be used. The
+    full range of SQL queries can be performed on these files, including
+    SELECT, INSERT, UPDATE and DELETE. Indexes and unique constraints can be
+    set up, and foreign key constraints can be used to enforce referential
+    integrity between Text Tables themselves or with conventional
+    tables.</p>
+<p>The delimited file can be created by the engine, or an existing file
+    can be used.</p>
+<p>HyperSQL with Text Table support is the only comprehensive solution
+    that employs the power of SQL and the universal reach of JDBC to handle
+    data stored in text files.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="texttables_impl-sect"></a>The Implementation</h2>
+</div>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N115BF"></a>Definition of Tables</h3>
+</div>
+</div>
+</div>
+<p>Text Tables are defined similarly to conventional tables with the
+      added TEXT keyword:</p>
+<pre class="programlisting">    CREATE TEXT TABLE &lt;tablename&gt; (&lt;column definition&gt; [&lt;constraint definition&gt;])</pre>
+<p>The table is at first empty and cannot be written to. An
+      additional SET command specifies the file and the separator character
+      that the Text table uses:</p>
+<pre class="programlisting">   SET TABLE &lt;tablename&gt; SOURCE &lt;quoted_filename_and_options&gt; [DESC]</pre>
+<p>Text Tables cannot be created in <em class="glossterm">mem:</em>
+      (all-in-memory) databases (databases that have no script file).</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N115CF"></a>Scope and Reassignment</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>A Text table without a file assigned to it is READ ONLY and
+          EMPTY.</p>
+</li>
+<li>
+<p>Reassigning a Text Table definition to a new file has
+          implications in the following areas:</p>
+<div class="orderedlist">
+<ol type="1">
+<li>
+<p>The user is required to be an administrator.</p>
+</li>
+<li>
+<p>Existing transactions are committed at this point.</p>
+</li>
+<li>
+<p>Constraints, including foreign keys referencing this
+              table, are kept intact. It is the responsibility of the
+              administrator to ensure their integrity.</p>
+</li>
+</ol>
+</div>
+<p>The new source file is scanned and indexes are built when it
+          is assigned to the table. At this point any violation of NOT NULL,
+          UNIQUE or PRIMARY KEY constraints are caught and the assignment is
+          aborted. However, foreign key constraints are not checked at the
+          time of assignment or reassignment of the source file.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N115E5"></a>Null Values in Columns of Text Tables</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Empty fields are treated as NULL. These are fields where there
+          is nothing or just spaces between the separators.</p>
+</li>
+<li>
+<p>Quoted empty strings are treated as empty strings.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N115EF"></a>Configuration</h3>
+</div>
+</div>
+</div>
+<p>The default field separator is a comma (,). A different field
+      separator can be specified within the SET TABLE SOURCE statement. For
+      example, to change the field separator for the table mytable to a
+      vertical bar, place the following in the SET TABLE SOURCE statement, for
+      example:</p>
+<div class="informalexample">
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile;fs=|"</pre>
+</div>
+<p>Since HSQLDB treats CHAR and VARCHAR strings the same, the ability
+      to assign a different separator to the latter is provided. When a
+      different separator is assigned to a VARCHAR, it will terminate any CSV
+      field of that type. For example, if the first field is CHAR, and the
+      second field VARCHAR, and the separator fs has been defined as the pipe
+      (|) and vs as the period (.) then the data in the CSV file for a row
+      will look like:</p>
+<pre class="screen">    First field data|Second field data.Third field data</pre>
+<p>This facility in effect offers an extra, special separator which
+      can be used in addition to the global separator. The following example
+      shows how to change the default separator to the pipe (|), VARCHAR
+      separator to the period (.) within a SET TABLE SOURCE statement:</p>
+<div class="informalexample">
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile;fs=|;vs=."</pre>
+</div>
+<p>HSQLDB also recognises the following special indicators for
+      separators:</p>
+<div class="variablelist">
+<p class="title">
+<b>special indicators for separators</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">\semi</span>
+</p>
+</td><td>
+<p>semicolon</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\quote</span>
+</p>
+</td><td>
+<p>single-quote</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\space</span>
+</p>
+</td><td>
+<p>space character</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\apos</span>
+</p>
+</td><td>
+<p>apostrophe</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\n</span>
+</p>
+</td><td>
+<p>newline - Used as an end anchor (like $ in regular
+            expressions)</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\r</span>
+</p>
+</td><td>
+<p>carriage return</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\t</span>
+</p>
+</td><td>
+<p>tab</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\\</span>
+</p>
+</td><td>
+<p>backslash</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\u####</span>
+</p>
+</td><td>
+<p>a Unicode character specified in hexadecimal</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>Furthermore, HSQLDB provides csv file support with three
+      additional boolean options: <code class="varname">ignore_first</code>,
+      <code class="varname">quoted</code> and <code class="varname">all_quoted</code>. The
+      <code class="varname">ignore_first</code> option (default false) tells HSQLDB to
+      ignore the first line in a file. This option is used when the first line
+      of the file contains column headings. The <code class="varname">all_quoted</code>
+      option (default false) tells the program that it should use quotes
+      around all character fields when writing to the source file. The
+      <code class="varname">quoted</code> option (default true) uses quotes only when
+      necessary to distinguish a field that contains the separator character.
+      It can be set to false to prevent the use of quoting altogether and
+      treat quote characters as normal characters. These options may be
+      specified within the <code class="literal">SET TABLE SOURCE</code>
+      statement:</p>
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile;ignore_first=true;all_quoted=true"</pre>
+<p>When the default options <code class="literal">all_quoted=</code>
+      <code class="literal">false</code> and <code class="literal">quoted=true</code> are in
+      force, fields that are written to a line of the csv file will be quoted
+      only if they contain the separator or the quote character. The quote
+      character is doubled when used inside a string. When
+      <code class="literal">all_quoted=false</code> and <code class="literal">quoted=false</code>
+      the quote character is not doubled. With this option, it is not possible
+      to insert any string containing the separator into the table, as it
+      would become impossible to distinguish from a separator. While reading
+      an existing data source file, the program treats each individual field
+      separately. It determines that a field is quoted only if the first
+      character is the quote character. It interprets the rest of the field on
+      this basis.</p>
+<p>The character encoding for the source file is<code class="literal"> ASCII
+      </code>by default. To support UNICODE or source files prepared with
+      different encodings this can be changed to <code class="literal">UTF-8</code> or
+      any other encoding. The default is <code class="literal">encoding=ASCII </code>and
+      the option <code class="literal">encoding=UTF-8</code> or other supported
+      encodings can be used.</p>
+<p>Finally, HSQLDB provides the ability to read a text file as READ
+      ONLY, by placing the keyword "DESC" at the end of the SET TABLE SOURCE
+      statement:</p>
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile" DESC</pre>
+<p>Text table source files are cached in memory. The maximum number
+      of rows of data that are in memory at any time is controlled by the
+      <code class="varname">textdb.cache_scale</code> property. The default value for
+      <code class="varname">textdb.cache_scale</code> is 10 and can be changed by
+      setting the property in the .properties file for the database. The
+      number of rows in memory is calculated as 3*(2**scale), which translates
+      to 3072 rows for the default textdb.cache_scale setting (10). The
+      property can also be set for individual text tables:</p>
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile;ignore_first=true;all_quoted=true;cache_scale=12"</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="disconnecting_text_tables"></a>Disconnecting Text Tables</h3>
+</div>
+</div>
+</div>
+<p>Text tables may be <em class="glossterm">disconnected</em> from their
+      underlying data source, i.e. the text file.</p>
+<p>You can explicitly disconnect a text table from its file by
+      issuing the following statement: <pre class="programlisting">    SET TABLE mytable SOURCE OFF</pre>
+</p>
+<p>Subsequently, <code class="literal">mytable</code> will be empty and
+      read-only. However, the data source description will be preserved, and
+      the table can be re-connected to it with <pre class="programlisting">    SET TABLE mytable SOURCE ON</pre>
+</p>
+<p>When a database is opened, if the source file for an existing text
+      table is missing the table remains disconnected from its data source,
+      but the source description is preserved. This allows the missing source
+      file to be added to the directory and the table re-connected to it with
+      the above command.</p>
+<p>Disconnecting text tables from their source has several uses.
+      While disconnected, the text source can be edited outside HSQLDB
+      provided data integrity is respected. When large text sources are used,
+      and several constraints or indexes need to be created on the table, it
+      is possible to disconnect the source during the creation of constraints
+      and indexes and reduce the time it takes to perform the
+      operation.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="texttables_issues-sect"></a>Text File Usage</h2>
+</div>
+</div>
+</div>
+<p>The following information applies to the usage of text
+    tables.</p>
+<div class="itemizedlist">
+<p class="title">
+<b>Text File Issues</b>
+</p>
+<ul type="disc">
+<li>
+<p>File locations are restricted to below the directory that
+        contains the database, unless the
+        <code class="varname">textdb.allow_full_path</code> property is set true as a
+        Java system property. This feature is for security, otherwise an admin
+        database user may be able to open random files.</p>
+</li>
+<li>
+<p>Blank lines are allowed anywhere in the text file, and are
+        ignored.</p>
+</li>
+<li>
+<p>It is possible to define a primary key, identity column, unique,
+        foreign key and check constraints for text tables.</p>
+</li>
+<li>
+<p>When a table source file is used with the<code class="literal">
+        ignore_first=true </code>option, the first, ignored line is
+        replaced with a blank line after a SHUTDOWN COMPACT, unless the SOURCE
+        HEADER statement has been used.</p>
+</li>
+<li>
+<p>An existing table source file may include CHARACTER fields that
+        do not begin with the quote character but contain instances of the
+        quote character. These fields are read as literal strings.
+        Alternatively, if any field begins with the quote character, then it
+        is interpreted as a quoted string that should end with the quote
+        character and any instances of the quote character within the string
+        is doubled. When any field containing the quote character or the
+        separator is written out to the source file by the program, the field
+        is enclosed in quote character and any instance of the quote character
+        inside the field is doubled.</p>
+</li>
+<li>
+<p>Inserts or updates of CHARACTER type field values are allowed
+        with strings that contains the linefeed or the carriage return
+        character. This feature is disabled when both quoted and all_quoted
+        properties are false.</p>
+</li>
+<li>
+<p>ALTER TABLE commands that add or drop columns or constraints
+        (apart from check constraints) are not supported with text tables that
+        are connected to a source. First use the SET TABLE &lt;name&gt; SOURCE
+        OFF, make the changes, then turn the source ON.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="texttables_globalprops-sect"></a>Text File Global Properties</h2>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<p class="title">
+<b>Complete list of supported global properties in *.properties
+      files</b>
+</p>
+<ul type="disc">
+<li>
+<p>
+<code class="varname">textdb.fs</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.vs</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.quoted</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.all_quoted</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.ignore_first</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.encoding</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.cache_scale</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.allow_full_path</code>
+</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N116E4"></a>Transactions</h2>
+</div>
+</div>
+</div>
+<p>Text tables fully support transactions. New or changed rows that
+    have not been committed are not updated in the source file. Therefore the
+    source file always contains committed rows.</p>
+<p>However, text tables are not as resilient to machine crashes as
+    other types of tables. If the crash happens while the text source is being
+    written to, the text source may contain only some of the changes made
+    during a committed transaction. With other types of tables, additional
+    mechanisms ensure the integrity of the data and this situation will not
+    arise.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="accesscontrol-chapt"></a>Chapter&nbsp;6.&nbsp;Access Control</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3096 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N1170F"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2009-08-09 17:50:39 +0100 (Sun, 09 Aug 2009) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N11712">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11752">Authorizations and Access Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N11775">Built-In Roles and Users</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N117CE">Access Rights</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N11810">Statements for
+    Authorization and Access Control</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N11712"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>Apart from schemas and their object, each HyperSQL catalog has USER
+    and ROLE objects. These objects are collectively called
+    <span class="emphasis"><em>authorizations</em></span>. Each AUTHORIZATION has some access
+    rights on some of the schemas or the objects they contain. The persistent
+    elements of an SQL environment are database objects</p>
+<p>Each database object has a name. A name is an identifier and is
+    unique within its name-space. Authorizations names follow the rules
+    described below and the case-normal form is stored in the database. When
+    connecting to a database, the user name and password must match the case
+    of the case-normal form.</p>
+<a name="N1171C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>identifier</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>definition of identifier</em></span>
+</p>
+<p>
+<code class="literal">&lt;identifier&gt; ::= &lt;regular identifier&gt; |
+    &lt;delimited identifier&gt; | &lt;SQL language identifier&gt;
+    </code>
+</p>
+<p>
+<code class="literal">&lt;delimited identifier&gt; ::= &lt;double quote&gt;
+    &lt;character sequence&gt; &lt;double quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;regular identifier&gt; ::= &lt;special character
+    sequence&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL language identifier&gt; ::= &lt;special
+    character sequence&gt;</code>
+</p>
+<p>A <code class="literal">&lt;delimited identifier&gt;</code> is a sequence
+    of characters enclosed with double-quote symbols. All characters are
+    allowed in the character sequence.</p>
+<p>A <code class="literal">&lt;regular identifier&gt;</code> is a special
+    sequence of characters. It consists of letters, digits and the underscore
+    characters. It must begin with a letter.</p>
+<p>A <code class="literal">&lt;SQL language identifier&gt;</code> is similar
+    to <code class="literal">&lt;regular identifier&gt;</code> but the letters can range
+    only from A-Z in the ASCII character set. This type of identifier is used
+    for names of CHARACTER SET objects.</p>
+<p>If the character sequence of a delimited identifier is the same
+    as an undelimited identifier, it represents the same identifier. For
+    example "JOHN" is the same identifier as JOHN. In a <code class="literal">&lt;regular
+    identifier&gt;</code> the case-normal form is considered for
+    comparison. This form consists of the upper-case of equivalent of all the
+    letters.</p>
+<p>The character sequence length of all identifiers must be between
+    1 and 128 characters.</p>
+<p>A reserved word is one that is used by the SQL Standard for
+    special purposes. It is similar to a <code class="literal">&lt;regular
+    identifier&gt;</code> but it cannot be used as an identifier for user
+    objects. If a reserved word is enclosed in double quote characters, it
+    becomes a quoted identifier and can be used for database
+    objects.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N11752"></a>Authorizations and Access Control</h2>
+</div>
+</div>
+</div>
+<p>In general, ROLE and USER objects simply control access to schema
+    objects. This is the scope of the SQL Standard. However, there are special
+    roles that allow the creation of USER and ROLE objects and also allow some
+    special operations on the database as a whole. These roles are not defined
+    by the Standard, which has left it to implementors to define such roles as
+    they are needed for the particular SQL implementation.</p>
+<p>A ROLE has a name a collection of zero or more other roles, plus
+    some privileges (access rights). A USER has a name and a password. It
+    similarly has a collection of zero or more roles plus some
+    privileges.</p>
+<p>USER objects existed in the SQL-92, but ROLE objects were introduced
+    in SQL:1999. Originally it was intended that USER objects would normally
+    be the same as the operating system USER objects and their authentication
+    would be handled outside the SQL environment. The co-existence of ROLE and
+    USER objects results in complexity. With the addition of ROLE objects,
+    there is no rationale, other than legacy support, for granting privileges
+    to USER objects directly. It is better to create roles and grant
+    privileges to them, then grant the roles to USER objects.</p>
+<p>The Standard effectively defines a special ROLE, named PUBLIC. All
+    authorization have the PUBLIC role, which cannot be removed from them.
+    Therefore any access right assigned to the PUBLIC role applies to all
+    authorizations in the database. For many simple databases, it is adequate
+    to create a single, non-admin user, then assign access rights to the
+    pre-existing PUBLIC role. Access to INFORMATION_SCHEMA views is granted to
+    PUBLIC, therefore these views are accessible to all. However, the contents
+    of each view depends on the ROLE or USER (AUTHORIZATION) that is in force
+    while accessing the view.</p>
+<p>Each schema has a single AUTHORIZATION. This is commonly known as
+    the <span class="emphasis"><em>owner</em></span> of the schema. All the objects in the
+    schema inherit the schema owner. The schema owner can add objects to the
+    schema, drop them or alter them.</p>
+<p>By default, the objects in a schema can only be accessed by the
+    schema owner. The schema owner can grant access rights on the objects to
+    other users or roles.</p>
+<a name="N11764" class="indexterm"></a>
+<p>
+<span class="bold"><strong>authorization
+    identifier</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>authorization identifier</em></span>
+</p>
+<p>
+<code class="literal">&lt;authorization identifier&gt; ::= &lt;role name&gt; |
+    &lt;user name&gt;</code>
+</p>
+<p>Authorization identifiers share the same name-space within the
+    database. The same name cannot be used for a USER and a ROLE.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11775"></a>Built-In Roles and Users</h3>
+</div>
+</div>
+</div>
+<p>There are some pre-defined roles in each database; some defined by
+      the SQL Standard, some by HyperSQL. These roles can be assigned to users
+      (directly or via other, user-defined roles). In addition, there is the
+      default initial user, SA, created with each new database.</p>
+<a name="N1177A" class="indexterm"></a>
+<p>
+<span class="bold"><strong>PUBLIC</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the PUBLIC role</em></span>
+</p>
+<p>The role that is assigned to all authorizations (roles and
+      users) in the database. This role has access rights to all objects in
+      the INFORMATION_SCHEMA. Any roles or rights granted to this role, are in
+      effect granted to all users of the database.</p>
+<a name="N11788" class="indexterm"></a>
+<p>
+<span class="bold"><strong>_SYSTEM</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the _SYSTEM role</em></span>
+</p>
+<p>This role is the authorization for the pre-defined (system)
+      objects in the database, including the INFORMATION_SCHEMA. This role
+      cannot be assigned to any authorization.</p>
+<a name="N11796" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DBA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the DBA role (HyperSQL-specific)</em></span>
+</p>
+<p>This is a special role in HyperSQL. A user that has this role
+      can perform all possible administrative tasks on the database. The DBA
+      role can also act as a proxy for all the roles and users in the
+      database. This means it can do everything the authorization for a schema
+      can do, including dropping the schema or its objects, or granting rights
+      on the schema objects to a grantee.</p>
+<a name="N117A4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE_SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the CREATE_SCHEMA role
+      (HyperSQL-specific)</em></span>
+</p>
+<p>An authorization that has this role, can create schemas. The
+      DBA authorization has this role and can grant it to other
+      authorizations.</p>
+<a name="N117B2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CHANGE_AUTHORIZATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the CHANGE_AUTHORIZATION role
+      (HyperSQL-specific)</em></span>
+</p>
+<p>A user that has this role, can change the authorization for the
+      current session to another user. The DBA authorization has this role and
+      can grant it to other authorizations.</p>
+<a name="N117C0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>the SA user (HyperSQL-specific)</em></span>
+</p>
+<p>This user is automatically created with a new database and has
+      the DBA role. Initially, the password for this user is an empty string.
+      After connecting to the new database as this user, it is possible to
+      change the password, create other users and created new schema objects.
+      The SA user can be dropped by another user that has the DBA
+      role.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N117CE"></a>Access Rights</h3>
+</div>
+</div>
+</div>
+<p>By default, the objects in a schema can only be accessed by the
+      schema owner. But the schema owner can grant privileges (access rights)
+      on the objects to other users or roles.</p>
+<p>Things can get far more complex, because the grant of privileges
+      can be made WITH GRANT OPTION. In this case, the role or user that has
+      been granted the privilege can grant the privilege to other roles and
+      users.</p>
+<p>Privileges can also be revoked from users or roles.</p>
+<p>The statements for granting and revoking privileges normally
+      specify which privileges are granted or revoked. However, there is a
+      shortcut, ALL PRIVILEGES, which means all the privileges that the
+      <code class="literal">&lt;grantor&gt;</code> has on the schema object. The
+      <code class="literal">&lt;grantor&gt;</code> is normally the CURRENT_USER of the
+      session that issues the statement.</p>
+<p>The user or role that is granted privileges is referred to as
+      <code class="literal">&lt;grantee&gt;</code> for the granted privileges.</p>
+<p>
+<span class="bold"><strong>Table</strong></span>
+</p>
+<p>For tables, including views, privileges can be granted with
+      different degrees of granularity. It is possible to grant a privilege on
+      all columns of a table, or on specific columns of the table.</p>
+<p>The DELETE privilege applies to the table, rather than its
+      columns. It applies to all DELETE statements.</p>
+<p>The SELECT, INSERT and UPDATE privileges may apply to all
+      columns or to individual columns. These privileges determine whether the
+      <code class="literal">&lt;grantee&gt;</code> can execute SQL data statements on
+      the table.</p>
+<p>The SELECT privilege designates the columns that can be
+      referenced in SELECT statements, as well as the columns that are read in
+      a DELETE or UPDATE statement, including the search condition.</p>
+<p>The INSERT privilege designates the columns into which explicit
+      values can be inserted. To be able to insert a row into the table, the
+      user must therefore have the INSERT privilege on the table, or at least
+      all the columns that do not have a default value.</p>
+<p>The UPDATE privilege simply designates the table or the
+      specific columns that can be updated.</p>
+<p>The REFERENCES privilege allows the
+      <code class="literal">&lt;grantee&gt;</code> to define a FOREIGN KEY constraint on
+      a different table, which references the table or the specific columns
+      designated for the REFERENCES privilege.</p>
+<p>The TRIGGER privilege allows adding a trigger to the
+      table.</p>
+<p>
+<span class="bold"><strong>Sequence, Type, Domain, Character Set,
+      Collation, Transliteration,</strong></span>
+</p>
+<p>For these objects, only USAGE can be granted. The USAGE
+      privilege is needed when object is referenced directly in an SQL
+      statement.</p>
+<p>
+<span class="bold"><strong>Routine</strong></span>
+</p>
+<p>For routines, including procedures or functions, only EXECUTE
+      privilege can be granted. This privilege is needed when the routine is
+      used directly in an SQL statement.</p>
+<p>
+<span class="bold"><strong>Other Objects</strong></span>
+</p>
+<p>Other objects such as constraints and assertions are not used
+      directly and there is no grantable privilege that refers to
+      them.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N11810"></a>Statements for
+    Authorization and Access Control</h2>
+</div>
+</div>
+</div>
+<p>The statements listed below allow creation and destruction of USER
+    and ROLE objects. The GRANT and REVOKE statements allow roles to be
+    assigned to other roles or to users. The same statements are also used in
+    a different form to assign privileges on schema objects to users and
+    roles.</p>
+<a name="N11816" class="indexterm"></a>
+<p>
+<a name="create_user-sql"></a><span class="bold"><strong>CREATE
+    USER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>user definition (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;user definition&gt; ::= CREATE USER &lt;user
+    name&gt; PASSWORD &lt;password&gt; [ ADMIN ]</code>
+</p>
+<p>Define a new user and its password. <code class="literal">&lt;user
+    name&gt;</code> is an SQL identifier. If it is double-quoted it is
+    case-sensitive, otherwise it is turned to uppercase.
+    <code class="literal">&lt;password&gt;</code> is a string enclosed with single quote
+    characters and is case-sensitive. If <code class="literal">ADMIN</code> is
+    specified, the DBA role is granted to the new user. Only a user with the
+    DBA role can execute this statement.</p>
+<a name="N11831" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP USER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop user statement (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop user statement&gt; ::= DROP USER &lt;user
+    name&gt;</code>
+</p>
+<p>Drop (destroy) an existing user. If the specified user is the
+    authorization for a schema, the schema is destroyed. Only a user with the
+    DBA role can execute this statement.</p>
+<a name="N11842" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER USER ... SET
+    PASSWORD</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set the password for a user
+    (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter user set password statement&gt; ::= ALTER USER
+    &lt;user name&gt; SET PASSWORD &lt;password&gt;</code>
+</p>
+<p>Change the password of an existing user. <code class="literal">&lt;user
+    name&gt;</code> is an SQL identifier. If it is double-quoted it is
+    case-sensitive, otherwise it is turned to uppercase.
+    <code class="literal">&lt;password&gt;</code> is a string enclosed with single quote
+    characters and is case-sensitive. Only a user with the DBA role can
+    execute this command.</p>
+<a name="N11859" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALTER USER ... SET INITIAL
+    SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set the initial schema for a user
+    (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;alter user set initial schema statement&gt; ::=
+    ALTER USER &lt;user name&gt; SET INITIAL SCHEMA &lt;schema name&gt; |
+    DEFAULT</code>
+</p>
+<p>Change the initial schema for a user. The initial schema is the
+    schema used by default for SQL statements issued during a session. If
+    <code class="literal">DEFAULT</code> is used, the default initial schema for all
+    users is used as the initial schema for the user. The SET SCHEMA command
+    allows the user to change the schema for the duration of the session. Only
+    a user with the DBA role can execute this statement.</p>
+<a name="N1186D" class="indexterm"></a>
+<p>
+<a name="set_password-sql"></a><span class="bold"><strong>SET
+    PASSWORD</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set password statement (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;set password statement&gt; ::= SET PASSWORD
+    &lt;password&gt;</code>
+</p>
+<p>Set the password for the current user.
+    <code class="literal">&lt;password&gt;</code> is a string enclosed with single quote
+    characters and is case-sensitive.</p>
+<a name="N11882" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET INITIAL SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set the initial schema for the current user
+    (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;set initial schema statement&gt; ::= SET INITIAL
+    SCHEMA &lt;schema name&gt; | DEFAULT</code>
+</p>
+<p>Change the initial schema for the current user. The initial
+    schema is the schema used by default for SQL statements issued during a
+    session. If <code class="literal">DEFAULT</code> is used, the default initial schema
+    for all users is used as the initial schema for the current user. The
+    separate SET SCHEMA command allows the user to change the schema for the
+    duration of the session. See also the <a class="link" href="#sessions-chapt" title="Chapter&nbsp;3.&nbsp;Sessions and Transactions">Sessions and Transactions</a> chapter.</p>
+<a name="N1189B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE DEFAULT INITIAL
+    SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set the default initial schema for all users
+    (HyperSQL)</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database default initial schema statement&gt;
+    ::= SET DATABASE DEFAULT INITIAL SCHEMA &lt;schema
+    name&gt;</code>
+</p>
+<p>Sets the initial schema for new users. This schema can later be
+    changed with the <code class="literal">&lt;set initial schema statement&gt;</code>
+    command.</p>
+<a name="N118AF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE ROLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>role definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;role definition&gt; ::= CREATE ROLE &lt;role
+    name&gt; [ WITH ADMIN &lt;grantor&gt; ]</code>
+</p>
+<p>Defines a new role. Initially the role has no rights, except
+    those of the PUBLIC role. Only a user with the DBA role can execute this
+    command.</p>
+<a name="N118C0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP ROLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop role statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop role statement&gt; ::= DROP ROLE &lt;role
+    name&gt;</code>
+</p>
+<p>Drop (destroy) a role. If the specified role is the authorization
+    for a schema, the schema is destroyed. Only a user with the DBA role can
+    execute this statement.</p>
+<a name="N118D1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>GRANTED BY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>grantor determination</em></span>
+</p>
+<p>
+<code class="literal">GRANTED BY &lt;grantor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;grantor&gt; ::= CURRENT_USER |
+    CURRENT_ROLE</code>
+</p>
+<p>The authorization that is granting or revoking a role or
+    privileges. The optional <code class="literal">GRANTED BY &lt;grantor&gt;</code>
+    clause can be used in various statements that perform GRANT or REVOKE
+    actions. If the clause is not used, the authorization is CURRENT_USER.
+    Otherwise, it is the specified authorization.</p>
+<a name="N118E8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>GRANT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>grant privilege statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;grant privilege statement&gt; ::= GRANT
+    &lt;privileges&gt; TO &lt;grantee&gt; [ { &lt;comma&gt; &lt;grantee&gt;
+    }... ] [ WITH GRANT OPTION ] [ GRANTED BY &lt;grantor&gt;
+    ]</code>
+</p>
+<p>Assign privileges on schema objects to roles or users. Each
+    <code class="literal">&lt;grantee&gt;</code> is a role or a user. If <code class="literal">[ WITH
+    GRANT OPTION ]</code> is specified, then the
+    <code class="literal">&lt;grantee&gt;</code> can assign the privileges to other
+    <code class="literal">&lt;grantee&gt;</code> objects.</p>
+<p>
+<code class="literal">&lt;privileges&gt; ::= &lt;object privileges&gt; ON
+    &lt;object name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;object name&gt; ::= [ TABLE ] &lt;table name&gt; |
+    DOMAIN &lt;domain name&gt; | COLLATION &lt;collation name&gt; | CHARACTER
+    SET &lt;character set name&gt; | TRANSLATION &lt;transliteration name&gt;
+    | TYPE &lt;user-defined type name&gt; | SEQUENCE &lt;sequence generator
+    name&gt; | &lt;specific routine designator&gt; | ROUTINE &lt;routine
+    name&gt; | FUNCTION &lt;function name&gt; | PROCEDURE &lt;procedure
+    name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;object privileges&gt; ::= ALL PRIVILEGES |
+    &lt;action&gt; [ { &lt;comma&gt; &lt;action&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;action&gt; ::= SELECT | SELECT &lt;left paren&gt;
+    &lt;privilege column list&gt; &lt;right paren&gt; | DELETE | INSERT [
+    &lt;left paren&gt; &lt;privilege column list&gt; &lt;right paren&gt; ] |
+    UPDATE [ &lt;left paren&gt; &lt;privilege column list&gt; &lt;right
+    paren&gt; ] | REFERENCES [ &lt;left paren&gt; &lt;privilege column
+    list&gt; &lt;right paren&gt; ] | USAGE | TRIGGER |
+    EXECUTE</code>
+</p>
+<p>
+<code class="literal">&lt;privilege column list&gt; ::= &lt;column name
+    list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;grantee&gt; ::= PUBLIC | &lt;authorization
+    identifier&gt;</code>
+</p>
+<p>The <code class="literal">&lt;object privileges&gt;</code> that can be used
+    depend on the type of the <code class="literal">&lt;object name&gt;</code>. These
+    are discussed in the previous section. For a table, if
+    <code class="literal">&lt;privilege column list&gt;</code> is not specified, then
+    the privilege is granted on the table, which includes all of its columns
+    and any column that may be added to it in the future. For routines, the
+    name of the routine can be specified in two ways, either as the generic
+    name as the specific name. HyperSQL allows referencing all overloaded
+    versions of a routine at the same time, using its name. This differs from
+    the SQL Standard which requires the use of <code class="literal">&lt;specific routine
+    designator&gt;</code> to grant privileges separately on each different
+    signature of the routine.</p>
+<p>Each <code class="literal">&lt;grantee&gt;</code> is the name of a role or
+    a user. Examples of GRANT statement are given below:</p>
+<div class="informalexample">
+<pre class="programlisting">GRANT ALL ON SEQUENCE aSequence TO roleOrUser 
+GRANT SELELCT ON aTable TO roleOrUser  
+GRANT SELECT, UPDATE ON aTABLE TO roleOrUser1, roleOrUser2
+GRANT SELECT(columnA, columnB), UPDATE(columnA, columnB) ON TABLE aTable TO roleOrUser
+GRANT EXECUTE ON SPECIFIC ROUTINE aroutine_1234 TO rolOrUser
+</pre>
+</div>
+<p>As mentioned in the general discussion, it is better to define a
+    role for the collection of all the privileges required by an application.
+    This role is then granted to any user. If further changes are made to the
+    privileges of this role, they are automatically reflected in all the users
+    that have the role.</p>
+<a name="N1192F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>GRANT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>grant role statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;grant role statement&gt; ::= GRANT &lt;role name&gt;
+    [ { &lt;comma&gt; &lt;role name&gt; }... ] TO &lt;grantee&gt; [ {
+    &lt;comma&gt; &lt;grantee&gt; }... ] [ WITH ADMIN OPTION ] [ GRANTED BY
+    &lt;grantor&gt; ]</code>
+</p>
+<p>Assign roles to roles or users. One or more roles can be assigned
+    to one or more <code class="literal">&lt;grantee&gt;</code> objects. A
+    <code class="literal">&lt;grantee&gt;</code> is a user or a role. If the <code class="literal">[
+    WITH ADMIN OPTION ]</code> is specified, then each
+    <code class="literal">&lt;grantee&gt;</code> can grant the newly assigned roles to
+    other grantees. An example of user and role creation with grants is given
+    below:</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE USER appuser
+CREATE ROLE approle
+GRANT approle TO appuser
+GRANT SELECT, UPDATE ON TABLE atable TO approle
+GRANT USAGE ON SEQUENCE asequence to approle
+GRANT EXECUTE ON ROUTINE aroutine TO approle
+</pre>
+</div>
+<a name="N1194F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REVOKE privilege</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>revoke statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;revoke privilege statement&gt; ::= REVOKE [ GRANT
+    OPTION FOR ] &lt;privileges&gt; FROM &lt;grantee&gt; [ { &lt;comma&gt;
+    &lt;grantee&gt; }... ] [ GRANTED BY &lt;grantor&gt; ] RESTRICT |
+    CASCADE</code>
+</p>
+<p>Revoke privileges from a user or role.</p>
+<a name="N11960" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REVOKE role</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>revoke role statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;revoke role statement&gt; ::= REVOKE [ ADMIN OPTION
+    FOR ] &lt;role revoked&gt; [ { &lt;comma&gt; &lt;role revoked&gt; }... ]
+    FROM &lt;grantee&gt; [ { &lt;comma&gt; &lt;grantee&gt; }... ] [ GRANTED BY
+    &lt;grantor&gt; ] RESTRICT | CASCADE</code>
+</p>
+<p>
+<code class="literal">&lt;role revoked&gt; ::= &lt;role
+    name&gt;</code>
+</p>
+<p>Revoke a role from users or roles.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="dataaccess-chapt"></a>Chapter&nbsp;7.&nbsp;Data Access and Change</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N11998"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N1199B">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N119A0">Cursors And Result Sets</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N119BD">Columns and Rows</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N119D8">Navigation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N119EA">Updatability</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A28">Sensitivity</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A31">Holdability</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A44">Autocommit</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A4C">JDBC Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A59">JDBC Parameters</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11A68">JDBC Returned Values</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N11A71">Syntax Elements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N11A76">Literals</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11B9C">References, etc.</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11BF8">Value Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N11E1B">Predicates</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1205E">Other Syntax Elements</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N12147">Data Access Statements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N1217F">Table</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12199">Query Specification</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N121DF">Table Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12246">Table Primary</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12278">Joined Table</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N122E5">Selection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N122EA">Projection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N122F1">Computed Columns</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N122F6">Naming</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12338">Grouping Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12346">Aggregation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1234D">Set Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12371">Query Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N123B0">Ordering</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N123C8">Slicing</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N123DA">Data Change Statements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N123DD">Delete Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N123FD">Truncate Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1241F">Insert Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1246A">Update Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N124B8">Merge Statement</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1199B"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL data access and data change statements are fully compatible
+    with the latest SQL:2008 Standard. There are a few extensions and some
+    relaxation of rules, but these do not affect statements that are written
+    to the Standard syntax. There is full support for classic SQL, as
+    specified by SQL-92, and many enhancements added in later versions of the
+    standard.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N119A0"></a>Cursors And Result Sets</h2>
+</div>
+</div>
+</div>
+<p>An SQL statement can executed in two ways. One way is to use the
+    <code class="classname">java.sql.Statement</code> interface. The Statement object
+    can be reused to execute completely different SQL statements.
+    Alternatively a <code class="classname">PreparedStatment</code> can be used to
+    execute an SQL statement repeatedly, and the statements can be
+    parameterized. Using either form, if the SQL statement is a query
+    expression, a <code class="classname">ResultSet</code> is returned.</p>
+<p>In SQL, when a query expression (SELECT or similar SQL statement) is
+    executed, an ephemeral table is created. When this table is returned to
+    the application program, it is returned as a result set, which is accessed
+    row-by-row by a cursor. A JDBC <code class="classname">ResultSet</code> represents
+    an SQL result set and its cursor.</p>
+<p>The minimal definition of a cursor is a list of rows with a position
+    that can move forward. Some cursors also allow the position to move
+    backwards or jump to any position in the list.</p>
+<p>An SQL cursor has several attributes. These attributes depend on the
+    query expression. Some of these attributes can be overridden by specifying
+    qualifiers in the SQL statement or by specifying values for the parameters
+    of the JDBC <code class="classname">Statement</code> or
+    <code class="classname">PreparedStatement</code>.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N119BD"></a>Columns and Rows</h3>
+</div>
+</div>
+</div>
+<p>The columns of the rows of the result set are determined by the
+      query expression. The number of columns and the type and name
+      characteristics of each column are known when the query expression is
+      compiled and before its execution. This metadata information remains
+      constant regardless of changes to the contents of the tables used in the
+      query expression. The metadata for the JDBC
+      <code class="classname">ResultSet</code> is in the form of a
+      <code class="classname">ResultSetMetaData</code> object. Various methods of the
+      <code class="classname">ResultSetMetaData</code> interface return different
+      properties of each column of the
+      <code class="classname">ResultSet</code>.</p>
+<p>A result set may contain 0 or more rows. The rows are determined
+      by the execution of the query expression.</p>
+<p>The <code class="methodname">setMaxRows(int)</code> method of JDBC
+      <code class="classname">Statement</code> allows limiting the number of rows
+      returned by the statement. This limit is conceptually applied after the
+      result has been built, and the excess rows are discarded.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N119D8"></a>Navigation</h3>
+</div>
+</div>
+</div>
+<p>A cursor is either scrollable or not. Scrollable cursors allow
+      accessing rows by absolute or relative positioning. No-scroll cursors
+      only allow moving to the next row. The cursor can be optionally declared
+      with the SQL qualifiers SCROLL, or NO SCROLL. The JDBC statement
+      parameter can be specified as: TYPE_FORWARD_ONLY and
+      TYPE_SCROLL_INSENSITIVE. The JDBC type TYPE_SCROLL_SENSITIVE is not
+      supported by HSQLDB.</p>
+<p>The default is NO SCROLL or TYPE_FORWARD_ONLY.</p>
+<p>When a JDBC <code class="classname">ResultSet</code> is opened, it is
+      positioned before the first row. Using the
+      <code class="methodname">next()</code> method the position is moved to the
+      first row. While the <code class="classname">ResultSet</code> is positioned on a
+      row, various getter methods can be used to access the columns of the
+      row.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N119EA"></a>Updatability</h3>
+</div>
+</div>
+</div>
+<p>The result returned by some query expressions is updatable. HSQLDB
+      supports core SQL updatability features, plus some enhancements from the
+      SQL optional features.</p>
+<p>A query expression is updatable if it is a SELECT from a single
+      underlying base table (or updatable view) either directly or indirectly.
+      A SELECT statement featuring DISTINCT or GROUP BY or FETCH, LIMIT,
+      OFFSET is not updatable. In an updatable query expression, one or more
+      columns are updatable. An updatable column is a column that can be
+      traced directly to the underlying table. Therefore, columns that contain
+      expressions are not updatable. Examples of updatable query expressions
+      are given below. The view V is updatable when its query expression is
+      updatable. The SELECT statement from this view is also updatable:</p>
+<pre class="programlisting">SELECT A, B FROM T WHERE C &gt; 5
+SELECT A, B FROM (SELECT * FROM T WHERE C &gt; 10) AS TT WHERE TT.B &lt;10
+CREATE VIEW V(X,Y) AS SELECT A, B FROM T WHERE C &gt; 0 AND B &lt; 10
+SELECT X FROM V WHERE Y = 5
+</pre>
+<p>If a cursor is declared with the SQL qualifier, <code class="literal">FOR
+      UPDATE OF &lt;column name list&gt;</code>, then only the stated
+      columns in the result set become updatable. If any of the stated columns
+      is not actually updatable, then the cursor declaration will not
+      succeed.</p>
+<p>If the SQL qualifier, FOR UPDATE is used, then all the updatable
+      columns of the result set become updatable.</p>
+<p>If a cursor is declared with FOR READ ONLY, then it is not
+      updatable.</p>
+<p>In HSQLDB, if FOR READ ONLY or FOR UPDATE is not used then all the
+      updatable columns of the result set become updatable. This relaxes the
+      SQL standard rule that in this case limits updatability to only simply
+      updatable SELECT statements (where all columns are updatable).</p>
+<p>In JDBC, CONCUR_READ_ONLY or CONCUR_UPDATABLE can be specified for
+      the <code class="classname">Statement</code> parameter. CONCUR_UPDATABLE is
+      required if the returning ResultSet is to be updatable. If
+      CONCUR_READ_ONLY, which is the default, is used, then even an updatable
+      ResultSet becomes read-only.</p>
+<p>When a <code class="classname">ResultSet</code> is updatable, various
+      setter methods can be used to modify the column values. The names of the
+      setter methods begin with "update". After all the updates on a row are
+      done, the <code class="methodname">updateRow()</code> method must be called to
+      finalise the row update.</p>
+<p>An updatable <code class="classname">ResultSet</code> may or may not be
+      insertable-into. In an insertable <code class="classname">ResultSet</code>, all
+      columns of the result are updatable and any column of the base table
+      that is not in the result must be a generated column or have a default
+      value.</p>
+<p>In the <code class="classname">ResultSet</code> object, a special
+      pseudo-row, called the insert row, is used to populate values for
+      insertion into the <code class="classname">ResultSet</code> (and consequently,
+      into the base table). The setter methods must be used on all the
+      columns, followed by a call to
+      <code class="methodname">insertRow()</code>.</p>
+<p>Individual rows from all updatable result sets can be deleted one
+      at a time. The <code class="methodname">deleteRow()</code> is called when the
+      <code class="classname">ResultSet</code> is positioned on a row.</p>
+<p>While using an updatable ResultSet to modify data, it is
+      recommended not to change the same data using another ResultSet and not
+      to execute SQL data change statements that modify the same data.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A28"></a>Sensitivity</h3>
+</div>
+</div>
+</div>
+<p>The sensitivity of the cursor relates to visibility of changes
+      made to the data by the same transaction but without using the given
+      cursor. While the result set is open, the same transaction may use
+      statements such as INSERT or UPDATE, and change the data of the tables
+      from which the result set data is derived. A cursor is SENSITIVE if it
+      reflects those changes. It is INSENSITIVE if it ignores such changes. It
+      is ASENSITIVE if behaviour is implementation dependent.</p>
+<p>The SQL default is ASENSITIVE, i.e., implantation
+      dependent.</p>
+<p>In HSQLDB all cursors are INSENSITIVE. They do not reflect changes
+      to the data made by other statements.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A31"></a>Holdability</h3>
+</div>
+</div>
+</div>
+<p>A cursor is holdable if the result set is not automatically closed
+      when the current transaction is committed. Holdability can be specified
+      in the cursor declaration using the SQL qualifiers WITH HOLD or WITHOUT
+      HOLD.</p>
+<p>In JDBC, hodability is specified using either of the following
+      values for the Statement parameter: HOLD_CURSORS_OVER_COMMIT, or
+      CLOSE_CURSORS_AT_COMMIT.</p>
+<p>The SQL default is WITHOUT HOLD.</p>
+<p>The JDBC default for HSQLDB result sets is WITH HOLD for read-only
+      result sets and WITHOUT HOLD for updatable result sets.</p>
+<p>If the holdability of a <code class="classname">ResultSet</code> is
+      specified in a conflicting manner in the SQL statement and the JDBC
+      <code class="classname">Statement</code> object, the JDBC setting takes
+      precedence.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A44"></a>Autocommit</h3>
+</div>
+</div>
+</div>
+<p>The autocommit property of a connection is a feature of JDBC and
+      ODBC and is not part of the SQL Standard. In autocommit mode, all
+      transactional statements are followed by an implicit commit. In
+      autocommit mode, all <code class="classname">ResultSet</code> objects are
+      read-only and holdable.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A4C"></a>JDBC Overview</h3>
+</div>
+</div>
+</div>
+<p>The JDBC settings, ResultSet.CONCUR_READONLY and
+      ResultSet.CONCUR_UPDATABLE are the alternatives for read-only or
+      updatability. The default is ResultSet.CONCUR_READONLY.</p>
+<p>The JDBC settings, ResultSet.TYPE_FORWARD_ONLY,
+      ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE are
+      the alternatives for both scrollability (navigation) and sensitivity.
+      HyperSQL does not support ResultSet.TYPE_SCROLL_SENSITIVE. The two other
+      alternatives can be used for both updatable and read-only result
+      sets.</p>
+<p>The JDBC settings ResultSet.CLOSE_CURSORS_AT_COMMIT and
+      ResultSet.HOLD_CURSORS_OVER_COMMIT are the alternatives for the lifetime
+      of the result set. The default is ResultSet.CLOSE_CURSORS_AT_COMMIT. The
+      other setting can only be used for read-only result sets.</p>
+<p>Examples of creating statements for updatable result sets are
+      given below:</p>
+<pre class="programlisting">Connection c = newConnection();
+Statement st;
+c.setAutoCommit(false);
+st = c.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
+st = c.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A59"></a>JDBC Parameters</h3>
+</div>
+</div>
+</div>
+<p>When a JDBC PreparedStatement or CallableStatement is used with an
+      SQL statement that contains dynamic parameters, the data types of the
+      parameters are resolved and determined by the engine when the statement
+      is prepared. The SQL Standard has detailed rules to determine the data
+      types and imposes limits on the maximum length or precision of the
+      parameter. HyperSQL applies the standard rules with two exceptions for
+      parameters with String and BigDecimal Java types. HyperSQL ignores the
+      limits when the parameter value is set, and only enforces the necessary
+      limits when the PreparedStatement is executed. In all other cases,
+      parameter type limits are checked and enforce when the parameter is
+      set.</p>
+<p>In the example below the setString() calls do not raise an
+      exception, but one of the execute() statements does.</p>
+<pre class="programlisting">// table definition: CREATE TABLE T (NAME VARCHAR(12), ...)
+Connection c = newConnection();
+PreparedStatement st = c.prepareStatement("SELECT * FROM T WHERE NAME = ?");
+// type of the parameter is VARCHAR(12), which limits length to 12 characters
+st.setString(1, "Eyjafjallajokull"); // string is longer than type, but no exception is raised here
+set.execute(); // executes with no exception and does not find any rows
+// but if an UPDATE is attempted, an exception is raised
+st = c.prepareStatement("UPDATE T SET NAME = ? WHERE ID = 10");
+st.setString(1, "Eyjafjallajokull"); // string is longer than type, but no exception is raised here
+st.execute(); // exception is thrown when HyperSQL checks the value for update
+
+</pre>
+<p>All of the above also applies to setting the values in new and
+      updated rows in updatable ResultSet objects.</p>
+<p>JDBC parameters can be set with any compatible type, as supported
+      by the JDBC specification. For CLOB and BLOB types, you can use streams,
+      or create instances of BLOB or CLOB before assigning them to the
+      parameters. You can even use CLOB or BLOB objects returned from
+      connections to other RDBMS servers. The Connection.createBlob() and
+      createClob() methods can be used to create the new LOBs. For very large
+      LOB's the stream methods are preferable as they use less memory.</p>
+<p>For array parameters, you must use a java.sql.Array object that
+      contains the array elements before assigning to JDBC parameters. The
+      Connection.createArrayOf(...) method can be used to create a new object,
+      or you can use an Array returned from connections to other RDBMS
+      servers.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A68"></a>JDBC Returned Values</h3>
+</div>
+</div>
+</div>
+<p>The methods of the JDBC ResultSet interface can be used to return
+      values and to convert value to different types as supported by the JDBC
+      specification.</p>
+<p>When a CLOB and BLOB object is returned from a ResultSet, no data
+      is transferred until the data is read by various methods of
+      java.sql.CLOB and java.sql.BLOB. Data is streamed in large blocks to
+      avoid excessive memory use.</p>
+<p>Array objects are returned as instances of java.sql.Array.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N11A71"></a>Syntax Elements</h2>
+</div>
+</div>
+</div>
+<p>The syntax elements that can be used in data access and data change
+    statements are described in this section. The SQL Standard has a very
+    extensive set of definitions for these elements. The BNF definitions given
+    here are sometimes simplified.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11A76"></a>Literals</h3>
+</div>
+</div>
+</div>
+<p>Literals are used to express constant values. The general type of
+      a literal is known by its format. The specific type is based on
+      conventions.</p>
+<a name="N11A7B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>unicode escape
+      elements</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>unicode escape elements</em></span>
+</p>
+<p>
+<code class="literal">&lt;Unicode escape specifier&gt; ::= [ UESCAPE
+      &lt;quote&gt;&lt;Unicode escape character&gt;&lt;quote&gt; ]
+      </code>
+</p>
+<p>
+<code class="literal">&lt;Unicode escape value&gt; ::= &lt;Unicode 4 digit
+      escape value&gt; | &lt;Unicode 6 digit escape value&gt; | &lt;Unicode
+      character escape value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode 4 digit escape value&gt; ::= &lt;Unicode
+      escape
+      character&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode 6 digit escape value&gt; ::= &lt;Unicode
+      escape character&gt;&lt;plus sign&gt;
+      &lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;&lt;hexit&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode character escape value&gt; ::= &lt;Unicode
+      escape character&gt;&lt;Unicode escape character&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode escape character&gt; ::= a single
+      character than a &lt;hexit&gt; (a-f, A-F, 0-9), &lt;plus sign&gt;,
+      &lt;quote&gt;, &lt;double quote&gt;, or &lt;white
+      space&gt;</code>
+</p>
+<a name="N11A99" class="indexterm"></a>
+<p>
+<span class="bold"><strong>character literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>character literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;character string literal&gt; ::= [
+      &lt;introducer&gt;&lt;character set specification&gt; ] &lt;quote&gt; [
+      &lt;character representation&gt;... ] &lt;quote&gt; [ {
+      &lt;separator&gt; &lt;quote&gt; [ &lt;character representation&gt;... ]
+      &lt;quote&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;introducer&gt; ::=
+      &lt;underscore&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;character representation&gt; ::= &lt;nonquote
+      character&gt; | &lt;quote symbol&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;nonquote character&gt; ::= any character apart
+      from the quote symbol.</code>
+</p>
+<p>
+<code class="literal">&lt;quote symbol&gt; ::=
+      &lt;quote&gt;&lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;national character string literal&gt; ::= N
+      &lt;quote&gt; [ &lt;character representation&gt;... ] &lt;quote&gt; [ {
+      &lt;separator&gt; &lt;quote&gt; [ &lt;character representation&gt;... ]
+      &lt;quote&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode character string literal&gt; ::= [
+      &lt;introducer&gt;&lt;character set specification&gt; ]
+      U&lt;ampersand&gt;&lt;quote&gt; [ &lt;Unicode representation&gt;... ]
+      &lt;quote&gt; [ { &lt;separator&gt; &lt;quote&gt; [ &lt;Unicode
+      representation&gt;... ] &lt;quote&gt; }... ] &lt;Unicode escape
+      specifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;Unicode representation&gt; ::= &lt;character
+      representation&gt; | &lt;Unicode escape value&gt;</code>
+</p>
+<p>The type of a character literal is CHARACTER. The length of the
+      string literal is the character length of the type. If the quote
+      character is used in a string, it is represented with two quote
+      characters. Long literals can be divided into multiple quoted strings,
+      separated with a space or end-of-line character.</p>
+<p>Unicode literals start with U&amp; and can contain ordinary
+      characters and unicode escapes. A unicode escape begins with the
+      backslash ( \ ) character and is followed by four hexadecimal characters
+      which specify the character code.</p>
+<p>Example of character literals are given below:</p>
+<pre class="programlisting">'a literal'  ' string seperated'  ' into parts'
+'a string''s literal form with quote character'
+U&amp;'Unicode string with Greek delta \0394 and phi \03a6 letters'
+</pre>
+<a name="N11AC5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>binary literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>binary literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;binary string literal&gt; ::= X &lt;quote&gt; [
+      &lt;space&gt;... ] [ { &lt;hexit&gt; [ &lt;space&gt;... ] &lt;hexit&gt;
+      [ &lt;space&gt;... ] }... ] &lt;quote&gt; [ { &lt;separator&gt;
+      &lt;quote&gt; [ &lt;space&gt;... ] [ { &lt;hexit&gt; [ &lt;space&gt;...
+      ] &lt;hexit&gt; [ &lt;space&gt;... ] }... ] &lt;quote&gt; }...
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;hexit&gt; ::= &lt;digit&gt; | A | B | C | D | E |
+      F | a | b | c | d | e | f</code>
+</p>
+<p>The type of a binary literal is BINARY. The octect length of
+      the binary literal is the length of the type. Case-insensitive
+      hexadecimal characters are used in the binary string. Each pair of
+      characters in the literal represents a byte in the binary string. Long
+      literals can be divided into multiple quoted strings, separated with a
+      space or end-of-line character.</p>
+<pre class="programlisting">X'1abACD34' 'Af'</pre>
+<a name="N11ADB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>bit literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>bit literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;bit string literal&gt; ::= B &lt;quote&gt; [
+      &lt;bit&gt; ... ] &lt;quote&gt; [ { &lt;separator&gt; &lt;quote&gt; [
+      &lt;bit&gt;... ] &lt;quote&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;bit&gt; ::= 0 | 1</code>
+</p>
+<p>The type of a binary literal is BIT. The bit length of the bit
+      literal is the length of the type. Digits 0 and 1 are used to represent
+      the bits. Long literals can be divided into multiple quoted strings,
+      separated with a space or end-of-line character.</p>
+<pre class="programlisting">B'10001001' '00010'</pre>
+<a name="N11AF1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>numeric literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>numeric literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;signed numeric literal&gt; ::= [ &lt;sign&gt; ]
+      &lt;unsigned numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unsigned numeric literal&gt; ::= &lt;exact numeric
+      literal&gt; | &lt;approximate numeric literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;exact numeric literal&gt; ::= &lt;unsigned
+      integer&gt; [ &lt;period&gt; [ &lt;unsigned integer&gt; ] ] |
+      &lt;period&gt; &lt;unsigned integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;sign&gt; ::= &lt;plus sign&gt; | &lt;minus
+      sign&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;approximate numeric literal&gt; ::=
+      &lt;mantissa&gt; E &lt;exponent&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;mantissa&gt; ::= &lt;exact numeric
+      literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;exponent&gt; ::= &lt;signed
+      integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;signed integer&gt; ::= [ &lt;sign&gt; ]
+      &lt;unsigned integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unsigned integer&gt; ::=
+      &lt;digit&gt;...</code>
+</p>
+<p>The type of an exact numeric literal without a decimal point is
+      INTEGER, BIGINT, or DECIMAL, depending on the value of the literal (the
+      smallest type that can represent the value is the type).</p>
+<p>The type of an exact numeric literal with a decimal point is
+      DECIMAL. The precision of a decimal literal is the total number of
+      digits of the literal. The scale of the literal is the total number of
+      digits to the right of the decimal point.</p>
+<p>The type of an approximate numeric literal is DOUBLE. An
+      approximate numeric literal always includes the mantissa and exponent,
+      separated by E.</p>
+<pre class="programlisting">12
+34.35
++12E-2
+</pre>
+<a name="N11B20" class="indexterm"></a>
+<p>
+<span class="bold"><strong>boolean literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>boolean literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;boolean literal&gt; ::= TRUE | FALSE |
+      UNKNOWN</code>
+</p>
+<p>The boolean literal is one of the specified keywords.</p>
+<a name="N11B31" class="indexterm"></a>
+<p>
+<span class="bold"><strong>datetime and interval
+      literal</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>datetime and interval literal</em></span>
+</p>
+<p>
+<code class="literal">&lt;datetime literal&gt; ::= &lt;date literal&gt; |
+      &lt;time literal&gt; | &lt;timestamp literal&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;date literal&gt; ::= DATE &lt;date
+      string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time literal&gt; ::= TIME &lt;time
+      string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;timestamp literal&gt; ::= TIMESTAMP &lt;timestamp
+      string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;date string&gt; ::= &lt;quote&gt; &lt;unquoted
+      date string&gt; &lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time string&gt; ::= &lt;quote&gt; &lt;unquoted
+      time string&gt; &lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;timestamp string&gt; ::= &lt;quote&gt;
+      &lt;unquoted timestamp string&gt; &lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time zone interval&gt; ::= &lt;sign&gt; &lt;hours
+      value&gt; &lt;colon&gt; &lt;minutes value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;date value&gt; ::= &lt;years value&gt; &lt;minus
+      sign&gt; &lt;months value&gt; &lt;minus sign&gt; &lt;days
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time value&gt; ::= &lt;hours value&gt;
+      &lt;colon&gt; &lt;minutes value&gt; &lt;colon&gt; &lt;seconds
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval literal&gt; ::= INTERVAL [ &lt;sign&gt; ]
+      &lt;interval string&gt; &lt;interval qualifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval string&gt; ::= &lt;quote&gt; &lt;unquoted
+      interval string&gt; &lt;quote&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unquoted date string&gt; ::= &lt;date
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unquoted time string&gt; ::= &lt;time value&gt; [
+      &lt;time zone interval&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;unquoted timestamp string&gt; ::= &lt;unquoted
+      date string&gt; &lt;space&gt; &lt;unquoted time
+      string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unquoted interval string&gt; ::= [ &lt;sign&gt; ]
+      { &lt;year-month literal&gt; | &lt;day-time literal&gt;
+      }</code>
+</p>
+<p>
+<code class="literal">&lt;year-month literal&gt; ::= &lt;years value&gt; [
+      &lt;minus sign&gt; &lt;months value&gt; ] | &lt;months
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;day-time literal&gt; ::= &lt;day-time interval&gt;
+      | &lt;time interval&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;day-time interval&gt; ::= &lt;days value&gt; [
+      &lt;space&gt; &lt;hours value&gt; [ &lt;colon&gt; &lt;minutes value&gt;
+      [ &lt;colon&gt; &lt;seconds value&gt; ] ] ]</code>
+</p>
+<p>
+<code class="literal">&lt;time interval&gt; ::= &lt;hours value&gt; [
+      &lt;colon&gt; &lt;minutes value&gt; [ &lt;colon&gt; &lt;seconds
+      value&gt; ] ] | &lt;minutes value&gt; [ &lt;colon&gt; &lt;seconds
+      value&gt; ] | &lt;seconds value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;years value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;months value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;days value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;hours value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;minutes value&gt; ::= &lt;datetime
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;seconds value&gt; ::= &lt;seconds integer
+      value&gt; [ &lt;period&gt; [ &lt;seconds fraction&gt; ]
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;seconds integer value&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;seconds fraction&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;datetime value&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>The type of a datetime or interval type is specified in the
+      literal. The fractional second precision is the number of digits in the
+      fractional part of the literal. Details are described in the <a class="link" href="#sqlgeneral-chapt" title="Chapter&nbsp;2.&nbsp;SQL Language">SQL Language</a>
+      chapter</p>
+<pre class="programlisting">DATE '2008-08-08'
+TIME '20:08:08'
+TIMESTAMP '2008-08-08 20:08:08.235'
+
+INTERVAL '10' DAY
+INTERVAL -'08:08' MINUTE TO SECOND
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11B9C"></a>References, etc.</h3>
+</div>
+</div>
+</div>
+<p>References are identifier chains, which can be a single
+      identifiers or identifiers chains composed of single identifiers chained
+      together with the period symbol.</p>
+<a name="N11BA1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>identifier chain</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>identifier chain</em></span>
+</p>
+<p>
+<code class="literal">&lt;identifier chain&gt; ::= &lt;identifier&gt; [ {
+      &lt;period&gt; &lt;identifier&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;basic identifier chain&gt; ::= &lt;identifier
+      chain&gt;</code>
+</p>
+<p>A period-separated chain of identifiers. The identifiers in an
+      identifier chain can refer to database objects in a hierarchy. The
+      possible hierarchies are as follows. In each hierarchy, elements from
+      the start or the end can be missing, but the order of elements cannot be
+      changed.</p>
+<p>catalog, schema, database object</p>
+<p>catalog, schema, table, column</p>
+<p>correlation name, column</p>
+<p>Examples of identifier chain are given below:</p>
+<pre class="programlisting">SELECT MYCAT.MYSCHEMA.MYTABLE.MYCOL FROM MYCAT.MYSCHEMA.MYTABLE
+DROP TABLE MYCAT.MYSCHEMA.MYTABLE CASCADE
+ALTER SEQUENCE MYCAT.MYSCHEMA.MYSEQUENCE RESTART WITH 100
+</pre>
+<a name="N11BBF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>column reference</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>column reference</em></span>
+</p>
+<p>
+<code class="literal">&lt;column reference&gt; ::= &lt;basic identifier
+      chain&gt; | MODULE &lt;period&gt; &lt;qualified identifier&gt;
+      &lt;period&gt; &lt;column name&gt;</code>
+</p>
+<p>Reference a column or a routine variable.</p>
+<a name="N11BD0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQL parameter
+      reference</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL parameter reference</em></span>
+</p>
+<p>
+<code class="literal">&lt;SQL parameter reference&gt; ::= &lt;basic
+      identifier chain&gt;</code>
+</p>
+<p>Reference an SQL routine parameter.</p>
+<a name="N11BE1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>contextually typed value
+      specification</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>contextually typed value
+      specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;contextually typed value specification&gt; ::=
+      &lt;null specification&gt; | &lt;default
+      specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;null specification&gt; ::=
+      NULL</code>
+</p>
+<p>
+<code class="literal">&lt;default specification&gt; ::=
+      DEFAULT</code>
+</p>
+<p>Specify a value whose data type or value is inferred from its
+      context. DEFAULT is used for assignments to table columns that have a
+      default value, or to table columns that are generated either as an
+      IDENTITY value or as an expression. NULL can be used only in a context
+      where the type of the value is known. For example, a NULL can be
+      assigned to a column of the table in an INSERT or UPDATE statement,
+      because the type of the column is known. But if NULL is used in a SELECT
+      list, it must be used in a CAST statement.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11BF8"></a>Value Expression</h3>
+</div>
+</div>
+</div>
+<p>Value expression is a general name for all expressions that return
+      a value. Different types of expressions are allowed in different
+      contexts.</p>
+<a name="N11BFD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>value expression
+      primary</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>value expression primary</em></span>
+</p>
+<p>
+<code class="literal">&lt;value expression primary&gt; ::= &lt;parenthesized
+      value expression&gt; | &lt;nonparenthesized value expression
+      primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;parenthesized value expression&gt; ::= &lt;left
+      paren&gt; &lt;value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;nonparenthesized value expression primary&gt; ::=
+      &lt;unsigned value specification&gt; | &lt;column reference&gt; |
+      &lt;set function specification&gt; | &lt;scalar subquery&gt; | &lt;case
+      expression&gt; | &lt;cast specification&gt; | &lt;next value
+      expression&gt; | &lt;routine invocation&gt;</code>
+</p>
+<p>Specify a value that is syntactically self-delimited.</p>
+<a name="N11C14" class="indexterm"></a>
+<p>
+<span class="bold"><strong>value specification</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>value specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;value specification&gt; ::= &lt;literal&gt; |
+      &lt;general value specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;unsigned value specification&gt; ::= &lt;unsigned
+      literal&gt; | &lt;general value specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;target specification&gt; ::= &lt;host parameter
+      specification&gt; | &lt;SQL parameter reference&gt; | &lt;column
+      reference&gt; | &lt;dynamic parameter
+      specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;simple target specification&gt; ::= &lt;host
+      parameter specification&gt; | &lt;SQL parameter reference&gt; |
+      &lt;column reference&gt; | &lt;embedded variable
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;host parameter specification&gt; ::= &lt;host
+      parameter name&gt; [ &lt;indicator parameter&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;dynamic parameter specification&gt; ::=
+      &lt;question mark&gt;</code>
+</p>
+<p>Specify one or more values, host parameters, SQL parameters,
+      dynamic parameters, or host variables.</p>
+<a name="N11C34" class="indexterm"></a>
+<p>
+<span class="bold"><strong>row value expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>row value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;row value expression&gt; ::= &lt;row value special
+      case&gt; | &lt;explicit row value constructor&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;row value predicand&gt; ::= &lt;row value special
+      case&gt; | &lt;row value constructor predicand&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;row value special case&gt; ::=
+      &lt;nonparenthesized value expression primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;explicit row value constructor&gt; ::= &lt;left
+      paren&gt; &lt;row value constructor element&gt; &lt;comma&gt; &lt;row
+      value constructor element list&gt; &lt;right paren&gt;
+      |</code>
+</p>
+<p>
+<code class="literal"> ROW &lt;left paren&gt; &lt;row value constructor
+      element list&gt; &lt;right paren&gt; | &lt;row
+      subquery&gt;</code>
+</p>
+<p>Specify a row consisting of one or more elements. A comma
+      separated list of expressions, enclosed in brackets, with the optional
+      keyword ROW. In SQL, a row containing a single element can often be used
+      where a single value is expected.</p>
+<a name="N11C51" class="indexterm"></a>
+<p>
+<span class="bold"><strong>set function
+      specification</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set function specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;set function specification&gt; ::= &lt;aggregate
+      function&gt; | &lt;grouping operation&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;grouping operation&gt; ::= GROUPING &lt;left
+      paren&gt; &lt;column reference&gt; [ { &lt;comma&gt; &lt;column
+      reference&gt; }... ] &lt;right paren&gt;</code>
+</p>
+<p>Specify a value derived by the application of a function to an
+      argument. Early releases of HyperSQL 2.0 do not support
+      <code class="literal">&lt;grouping operation&gt;</code> .</p>
+<a name="N11C68" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COALESCE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>coalesce expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;coalesce expression&gt; := COALESCE &lt;left
+      paren&gt; &lt;value expression&gt; { &lt;comma&gt; &lt;value
+      expression&gt; }... &lt;right paren&gt;</code>
+</p>
+<p>Replace null values with another value. The coalesce expression
+      has two or more instances of &lt;value expression&gt;. If the first
+      &lt;value expression&gt; evaluates to a non-null value, it is returned
+      as the result of the coalesce expression. If it is null, the next
+      <code class="literal">&lt;value expression&gt;</code> is evaluated and if it
+      evaluates to a non-non value, it is returned, and so on.</p>
+<p>The type of the return value of a COALESCE expression is the
+      aggregate type of the types of all the <code class="literal">&lt;value
+      expression&gt;</code> instances. Therefore, any value returned is
+      implicitly cast to this type. HyperSQL also features built-in functions
+      with similar functionality.</p>
+<a name="N11C81" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NULLIF</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>nullif expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;nullif expression&gt; := NULLIF &lt;left paren&gt;
+      &lt;value expression&gt; &lt;comma&gt; &lt;value expression&gt;
+      &lt;right paren&gt;</code>
+</p>
+<p>Return NULL if two values are equal. If the result of the first
+      <code class="literal">&lt;value expression&gt;</code> is not equal to the result
+      of the second, then it is returned, otherwise NULL is returned. The type
+      of the return value is the type of the first <code class="literal">&lt;value
+      expression&gt;</code>.</p>
+<pre class="programlisting">SELECT i, NULLIF(n, 'not defined') FROM t</pre>
+<a name="N11C9A" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CASE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>case specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;case specification&gt; ::= &lt;simple case&gt; |
+      &lt;searched case&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;simple case&gt; ::= CASE &lt;case operand&gt;
+      &lt;simple when clause&gt;... [ &lt;else clause&gt; ]
+      END</code>
+</p>
+<p>
+<code class="literal">&lt;searched case&gt; ::= CASE &lt;searched when
+      clause&gt;... [ &lt;else clause&gt; ] END</code>
+</p>
+<p>
+<code class="literal">&lt;simple when clause&gt; ::= WHEN &lt;when operand
+      list&gt; THEN &lt;result&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;searched when clause&gt; ::= WHEN &lt;search
+      condition&gt; THEN &lt;result&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;else clause&gt; ::= ELSE
+      &lt;result&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;case operand&gt; ::= &lt;row value predicand&gt; |
+      &lt;overlaps predicate part 1&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;when operand list&gt; ::= &lt;when operand&gt; [ {
+      &lt;comma&gt; &lt;when operand&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;when operand&gt; ::= &lt;row value predicand&gt; |
+      &lt;comparison predicate part 2&gt; | &lt;between predicate part 2&gt; |
+      &lt;in predicate part 2&gt; | &lt;character like predicate part 2&gt; |
+      &lt;octet like predicate part 2&gt; | &lt;similar predicate part 2&gt; |
+      &lt;regex like predicate part 2&gt; | &lt;null predicate part 2&gt; |
+      &lt;quantified comparison predicate part 2&gt; | &lt;match predicate
+      part 2&gt; | &lt;overlaps predicate part 2&gt; | &lt;distinct predicate
+      part 2&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;result&gt; ::= &lt;result expression&gt; |
+      NULL</code>
+</p>
+<p>
+<code class="literal">&lt;result expression&gt; ::= &lt;value
+      expression&gt;</code>
+</p>
+<p>Specify a conditional value. The result of a case expression is
+      always a value. All the values introduced with THEN must be of the same
+      type.</p>
+<p>An (simple) example of the CASE statement is given below. It
+      returns 'Britain', 'Germany', or 'Other country' depending on the value
+      of dialcode'</p>
+<pre class="programlisting">CASE dialcode WHEN 44 THEN 'Britain' WHEN 49 THEN 'Germany' ELSE 'Other country' END</pre>
+<p>The case statement can be far more complex and involve several
+      conditions.</p>
+<a name="N11CCF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CAST</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>cast specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;cast specification&gt; ::= CAST &lt;left paren&gt;
+      &lt;cast operand&gt; AS &lt;cast target&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;cast operand&gt; ::= &lt;value expression&gt; |
+      &lt;implicitly typed value specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;cast target&gt; ::= &lt;domain name&gt; | &lt;data
+      type&gt;</code>
+</p>
+<p>Specify a data conversion. Data conversion takes place
+      automatically among variants of a general type. For example numeric
+      values are freely converted from one type to another in
+      expressions.</p>
+<p>Explicit type conversion is necessary in two cases. One case is
+      to determine the type of a NULL value. The other case is to force
+      conversion for special purposes. Values of data types can be cast to a
+      character type. The exception is BINARY and OTHER types. The result of
+      the cast is the literal expression of the value. Conversely, a value of
+      a character type can be converted to another type if the character value
+      is a literal representation of the value in the target type. Special
+      conversions are possible between numeric and interval types, which are
+      described in the section covering interval types.</p>
+<p>The examples below show examples of cast with their
+      result:</p>
+<pre class="programlisting">CAST (NULL AS TIMESTAMP)
+CAST ('   199  ' AS INTEGER) = 199
+CAST ('tRue ' AS BOOLEAN) = TRUE
+CAST (INTERVAL '2' DAY AS INTEGER) = 2
+CAST ('1992-04-21' AS DATE) = DATE '1992-04-21'
+</pre>
+<a name="N11CEC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NEXT VALUE FOR</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>next value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;next value expression&gt; ::= NEXT VALUE FOR
+      &lt;sequence generator name&gt;</code>
+</p>
+<p>Return the next value of a sequence generator. This expression
+      can be used as a select list element in queries, or in assignments to
+      table columns in data change statements. If the expression is used more
+      than once in a single row that is being evaluated, the same value is
+      returned for each invocation. After evaluation of the particular row is
+      complete, the sequence generator will return a different value from the
+      old value. The new value is generated by the sequence generator by
+      adding the increment to the last value it generated. In the example
+      below:</p>
+<pre class="programlisting">INSERT INTO MYTABLE(COL1, COL2) VALUES 2, NEXT VALUE FOR MYSEQUENCE
+</pre>
+<a name="N11CFF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>value expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;value expression&gt; ::= &lt;numeric value
+      expression&gt; | &lt;string value expression&gt; | &lt;datetime value
+      expression&gt; | &lt;interval value expression&gt; | &lt;boolean value
+      expression&gt; | &lt;row value expression&gt;</code>
+</p>
+<p>An expression that returns a value. The value can be a single
+      value, or a row consisting more than one value.</p>
+<a name="N11D10" class="indexterm"></a>
+<p>
+<span class="bold"><strong>numeric value
+      expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>numeric value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;numeric value expression&gt; ::= &lt;term&gt; |
+      &lt;numeric value expression&gt; &lt;plus sign&gt; &lt;term&gt; |
+      &lt;numeric value expression&gt; &lt;minus sign&gt;
+      &lt;term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;term&gt; ::= &lt;factor&gt; | &lt;term&gt;
+      &lt;asterisk&gt; &lt;factor&gt; | &lt;term&gt; &lt;solidus&gt;
+      &lt;factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;factor&gt; ::= [ &lt;sign&gt; ] &lt;numeric
+      primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;numeric primary&gt; ::= &lt;value expression
+      primary&gt; | &lt;numeric value function&gt;</code>
+</p>
+<p>Specify a numeric value. The BNF indicates that
+      <code class="literal">&lt;asterisk&gt;</code> and
+      <code class="literal">&lt;solidus&gt;</code> (the operators for multiplication and
+      division) have precedence over <code class="literal">&lt;minus sign&gt;</code> and
+      <code class="literal">&lt;plus sign&gt;</code>.</p>
+<a name="N11D36" class="indexterm"></a>
+<p>
+<span class="bold"><strong>numeric value
+      function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>numeric value function</em></span>
+</p>
+<p>
+<code class="literal">&lt;numeric value function&gt; ::= &lt;position
+      expression&gt; | &lt;extract expression&gt; | &lt;length expression&gt;
+      ...</code>
+</p>
+<p>Specify a function yielding a value of type numeric. The
+      supported numeric value functions are listed and described in the <a class="link" href="#builtinfunctions-chapt" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+<a name="N11D4B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>string value
+      expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>string value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;string value expression&gt; ::= &lt;string
+      concatenation&gt; | &lt;string factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;string factor&gt; ::= &lt;value expression
+      primary&gt; | &lt;string value function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;string concatenation&gt; ::= &lt;string value
+      expression&gt; &lt;concatenation operator&gt; &lt;string
+      factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;concatenation operator&gt; ::=
+      ||</code>
+</p>
+<p>Specify a character string value, a binary string value, or a
+      bit string value. The BNF indicates that a string value expression can
+      be formed by concatenation of two or more <code class="literal">&lt;value expression
+      primary&gt;</code>. The types of the <code class="literal">&lt;value expression
+      primary&gt;</code> elements must be compatible, that is, all must be
+      string, or binary or bit string values.</p>
+<a name="N11D6B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>character value
+      function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>string value function</em></span>
+</p>
+<p>
+<code class="literal">&lt;string value function&gt; ::=
+      ...</code>
+</p>
+<p>Specify a function that returns a character string or binary
+      string. The supported character value functions are listed and described
+      in the <a class="link" href="#builtinfunctions-chapt" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+<a name="N11D80" class="indexterm"></a>
+<p>
+<span class="bold"><strong>datetime value
+      expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>datetime value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;datetime value expression&gt; ::= &lt;datetime
+      term&gt; | &lt;interval value expression&gt; &lt;plus sign&gt;
+      &lt;datetime term&gt; | &lt;datetime value expression&gt; &lt;plus
+      sign&gt; &lt;interval term&gt; | &lt;datetime value expression&gt;
+      &lt;minus sign&gt; &lt;interval term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;datetime term&gt; ::= &lt;datetime
+      factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;datetime factor&gt; ::= &lt;datetime primary&gt; [
+      &lt;time zone&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;datetime primary&gt; ::= &lt;value expression
+      primary&gt; | &lt;datetime value function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time zone&gt; ::= AT &lt;time zone
+      specifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time zone specifier&gt; ::= LOCAL | TIME ZONE
+      &lt;interval primary&gt;</code>
+</p>
+<p>Specify a datetime value. Details are described in the <a class="link" href="#sqlgeneral-chapt" title="Chapter&nbsp;2.&nbsp;SQL Language">SQL Language</a>
+      chapter.</p>
+<a name="N11DA4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>datetime value
+      function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>datetime value function</em></span>
+</p>
+<p>
+<code class="literal">&lt;datetime value function&gt; ::=
+      ...</code>
+</p>
+<p>Specify a function that returns a datetime value. The supported
+      datetime value functions are listed and described in the <a class="link" href="#builtinfunctions-chapt" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+<a name="N11DBA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>interval term</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>interval value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;interval value expression&gt; ::= &lt;interval
+      term&gt; | &lt;interval value expression 1&gt; &lt;plus sign&gt;
+      &lt;interval term 1&gt; | &lt;interval value expression 1&gt; &lt;minus
+      sign&gt; &lt;interval term 1&gt; | &lt;left paren&gt; &lt;datetime value
+      expression&gt; &lt;minus sign&gt; &lt;datetime term&gt; &lt;right
+      paren&gt; &lt;interval qualifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval term&gt; ::= &lt;interval factor&gt; |
+      &lt;interval term 2&gt; &lt;asterisk&gt; &lt;factor&gt; | &lt;interval
+      term 2&gt; &lt;solidus&gt; &lt;factor&gt; | &lt;term&gt;
+      &lt;asterisk&gt; &lt;interval factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval factor&gt; ::= [ &lt;sign&gt; ]
+      &lt;interval primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval primary&gt; ::= &lt;value expression
+      primary&gt; [ &lt;interval qualifier&gt; ] | &lt;interval value
+      function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval value expression 1&gt; ::= &lt;interval
+      value expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval term 1&gt; ::= &lt;interval
+      term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval term 2&gt; ::= &lt;interval
+      term&gt;</code>
+</p>
+<p>Specify an interval value. Details are described in the <a class="link" href="#sqlgeneral-chapt" title="Chapter&nbsp;2.&nbsp;SQL Language">SQL Language</a>
+      chapter.</p>
+<a name="N11DE1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>interval absolute value
+      function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>interval value function</em></span>
+</p>
+<p>
+<code class="literal">&lt;interval value function&gt; ::= &lt;interval
+      absolute value function&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval absolute value function&gt; ::= ABS
+      &lt;left paren&gt; &lt;interval value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>Specify a function that returns the absolute value of an
+      interval. If the interval is negative, it is negated, otherwise the
+      original value is returned.</p>
+<a name="N11DF5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>boolean value
+      expression</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>boolean value expression</em></span>
+</p>
+<p>
+<code class="literal">&lt;boolean value expression&gt; ::= &lt;boolean
+      term&gt; | &lt;boolean value expression&gt; OR &lt;boolean
+      term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;boolean term&gt; ::= &lt;boolean factor&gt; |
+      &lt;boolean term&gt; AND &lt;boolean factor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;boolean factor&gt; ::= [ NOT ] &lt;boolean
+      test&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;boolean test&gt; ::= &lt;boolean primary&gt; [ IS
+      [ NOT ] &lt;truth value&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;truth value&gt; ::= TRUE | FALSE |
+      UNKNOWN</code>
+</p>
+<p>
+<code class="literal">&lt;boolean primary&gt; ::= &lt;predicate&gt; |
+      &lt;boolean predicand&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;boolean predicand&gt; ::= &lt;parenthesized
+      boolean value expression&gt; | &lt;nonparenthesized value expression
+      primary&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;parenthesized boolean value expression&gt; ::=
+      &lt;left paren&gt; &lt;boolean value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>Specify a boolean value.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N11E1B"></a>Predicates</h3>
+</div>
+</div>
+</div>
+<p>Predicates are conditions with two sides and evaluate to a
+      boolean value. The left side of the predicate, the <code class="literal">&lt;row
+      value predicand&gt;</code>, is the common element of all predicates.
+      This element is a generalisation of both <code class="literal">&lt;value
+      expression&gt;</code>, which is a scalar, and of
+      <code class="literal">&lt;explicit row value constructor&gt;</code>, which is a
+      row. The two sides of a predicate can be split in CASE statements where
+      the <code class="literal">&lt;row value predicand&gt;</code> is part of multiple
+      predicates.</p>
+<p>The number of fields in all <code class="literal">&lt;row value
+      predicand&gt;</code> used in predicates must be the same and the
+      types of the fields in the same position must be compatible for
+      comparison. If either of these conditions does not hold, an exception is
+      raised. The number of fields in a row is called the
+      <em class="glossterm">degree</em>.</p>
+<p>In many types of predicates (but not all of them), if the
+      <code class="literal">&lt;row value predicand&gt;</code> evaluates to NULL, the
+      result of the predicate is UNKNOWN. If the <code class="literal">&lt;row value
+      predicand&gt;</code> has more than one element, and one or more of
+      the fields evaluate to NULL, the result depends on the particular
+      predicate.</p>
+<a name="N11E3C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>comparison predicand</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>comparison predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;comparison predicate&gt; ::= &lt;row value
+      predicand&gt; &lt;comp op&gt; &lt;row value
+      predicand&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;comp op&gt; ::= &lt;equals operator&gt; | &lt;not
+      equals operator&gt; | &lt;less than operator&gt; | &lt;greater than
+      operator&gt; | &lt;less than or equals operator&gt; | &lt;greater than
+      or equals operator&gt;</code>
+</p>
+<p>Specify a comparison of two row values. If either
+      <code class="literal">&lt;row value predicand&gt;</code> evaluates to NULL, the
+      result of <code class="literal">&lt;comparison predicate&gt;</code> is UNKNOWN.
+      Otherwise, the result is TRUE, FALSE or UNKNOWN.</p>
+<p>If the <em class="glossterm">degree</em> of <code class="literal">&lt;row value
+      predicand&gt;</code> is larger than one, comparison is performed
+      between each field and the corresponding field in the other
+      <code class="literal">&lt;row value predicand&gt;</code> from left to right, one
+      by one.</p>
+<p>When comparing two elements, if either field is NULL then the
+      result is UNKNOWN.</p>
+<p>For <code class="literal">&lt;equals operator&gt;</code>, if the result
+      of comparison is TRUE for all field, the result of the predicate is
+      TRUE. If the result of comparison is FALSE for one field, the result of
+      predicate is FALSE. Otherwise the result is UNKNOWN.</p>
+<p>The <code class="literal">&lt;not equals operator&gt;</code> is
+      translated to <code class="literal">NOT (&lt;row value predicand&gt; = &lt;row value
+      predicand&gt;)</code>.</p>
+<p>The <code class="literal">&lt;less than or equals operator&gt;</code> is
+      translated to <code class="literal">(&lt;row value predicand&gt; = &lt;row value
+      predicand&gt;) OR (&lt;row value predicand&gt; &lt; &lt;row value
+      predicand&gt;)</code>. The <code class="literal">&lt;greater than or equals
+      operator&gt;</code> is translated similarly.</p>
+<p>For the <code class="literal">&lt;less than operator&gt;</code> and
+      <code class="literal">&lt;greater than operator&gt;</code>, if two fields at a
+      given position are equal, then comparison continues to the next field.
+      Otherwise, the result of the last performed comparison is returned as
+      the result of the predicate. This means that if the first field is NULL,
+      the result is always UNKNOWN.</p>
+<p>The logic that governs NULL values and UNKNOWN result is as
+      follows: Suppose the NULL values were substituted by arbitrary real
+      values. If substitution cannot change the result of the predicate, then
+      the result is TRUE or FALSE, based on the existing non-NULL values,
+      otherwise the result of the predicate is UNKNOWN.</p>
+<p>The examples of comparison given below use literals, but the
+      literals actually represent the result of evaluation of some
+      expression.</p>
+<pre class="programlisting">((1, 2, 3, 4) = (1, 2, 3, 4)) IS TRUE
+((1, 2, 3, 4) = (1, 2, 3, 5)) IS FALSE
+((1, 2, 3, 4) &lt; (1, 2, 3, 4)) IS FALSE
+((1, 2, 3, 4) &lt; (1, 2, 3, 5)) IS TRUE
+((NULL, 1, NULL) = (NULL, 1, NULL)) IS UNKNOWN  
+((NULL, 1, NULL) = (NULL, 2, NULL)) IS FALSE  
+((NULL, 1, NULL) &lt;&gt; (NULL, 2, NULL)) IS TRUE  
+((NULL, 1, 2) &lt;all operators&gt; (NULL, 1, 2)) IS UNKNOWN
+((1, NULL, ...) &lt; (1, 2, ...)) IS UNKNOWN  
+((1, NULL, ...) &lt; (2, NULL, ...)) IS TRUE
+((2, NULL, ...) &lt; (1, NULL, ...)) IS FALSE
+</pre>
+<a name="N11E89" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BETWEEN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>between predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;between predicate&gt; ::= &lt;row value
+      predicand&gt; &lt;between predicate part 2&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;between predicate part 2&gt; ::= [ NOT ] BETWEEN [
+      ASYMMETRIC | SYMMETRIC ] &lt;row value predicand&gt; AND &lt;row value
+      predicand&gt;</code>
+</p>
+<p>Specify a range comparison. The default is ASYMMETRIC. The
+      expression <code class="literal">X BETWEEN Y AND Z</code> is equivalent to
+      <code class="literal">(X &gt;= Y AND X &lt;= Z)</code>. Therefore if Y &gt; Z, the
+      BETWEEN expression is never true. The expression <code class="literal">X BETWEEN
+      SYMMETRIC Y AND Z</code> is equivalent to <code class="literal">(X &gt;= Y AND X
+      &lt;= Z) OR (X &gt;= Z AND X &lt;= Y)</code>. The expression
+      <code class="literal">Z NOT BETWEEN ...</code> is equivalent to <code class="literal">NOT (Z
+      BETWEEN ...)</code>. If any of the three <code class="literal">&lt;row value
+      predicand&gt;</code> evaluates to NULL, the result is
+      UNKNOWN.</p>
+<a name="N11EB2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>in predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;in predicate&gt; ::= &lt;row value predicand&gt; [
+      NOT ] IN &lt;in predicate value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;in predicate value&gt; ::= &lt;table subquery&gt;
+      | &lt;left paren&gt; &lt;in value list&gt; &lt;right paren&gt;
+      </code>
+</p>
+<p>
+<code class="literal">| &lt;left paren&gt; UNNEST &lt;left paren&gt;
+      &lt;array value expression&gt; &lt;right paren&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;in value list&gt; ::= &lt;row value expression&gt;
+      [ { &lt;comma&gt; &lt;row value expression&gt; }...
+      ]</code>
+</p>
+<p>Specify a quantified comparison. The expression <code class="literal">X NOT
+      IN Y is</code> equivalent to <code class="literal">NOT (X IN Y)</code>. The
+      <code class="literal">( &lt;in value list&gt; )</code> is converted into a table
+      with one or more rows. The expression <code class="literal">X IN Y</code> is
+      equivalent to <code class="literal">X = ANY Y</code>, which is a
+      <code class="literal">&lt;quantified comparison predicate&gt;</code>.</p>
+<p>If the <code class="literal">&lt;table subquery&gt;</code> returns no
+      rows, the result is FALSE. Otherwise the <code class="literal">&lt;row value
+      predicand&gt;</code> is compared one by one with each row of the
+      <code class="literal">&lt;table subquery&gt;</code>.</p>
+<p>If the comparison is TRUE for at least one row, the result is
+      TRUE. If the comparison is FALSE for all rows, the result is FALSE.
+      Otherwise the result is UNKNOWN.</p>
+<p>HyperSQL supports an extension to the SQL Standard to allow an
+      array to be used in the &lt;in predicate value&gt;. This is intended to
+      be used with prepared statements where a variable length array of values
+      can be used as the parameter value for each call. The example below
+      shows how this is used.</p>
+<pre class="programlisting">SELECT * from customer where firstname in ( UNNEST(?) )
+</pre>
+<a name="N11EEF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LIKE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>like predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;like predicate&gt; ::= &lt;character like
+      predicate&gt; | &lt;octet like predicate&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;character like predicate&gt; ::= &lt;row value
+      predicand&gt; [ NOT ] LIKE &lt;character pattern&gt; [ ESCAPE &lt;escape
+      character&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;character pattern&gt; ::= &lt;character value
+      expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;escape character&gt; ::= &lt;character value
+      expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;octet like predicate&gt; ::= &lt;row value
+      predicand&gt; [ NOT ] LIKE &lt;octet pattern&gt; [ ESCAPE &lt;escape
+      octet&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;octet pattern&gt; ::= &lt;binary value
+      expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;escape octet&gt; ::= &lt;binary value
+      expression&gt;</code>
+</p>
+<p>Specify a pattern-match comparison for character or binary
+      strings. The <code class="literal">&lt;row value predicand&gt;</code> is always a
+      <code class="literal">&lt;string value expression&gt;</code> of character or
+      binary type. The <code class="literal">&lt;character pattern&gt;</code> or
+      <code class="literal">&lt;octet pattern&gt;</code> is a <code class="literal">&lt;string value
+      expression&gt;</code> in which the underscore and percent characters
+      have special meanings. The underscore means match any one character,
+      while the percent means match a sequence of zero or more characters. The
+      <code class="literal">&lt;escape character&gt;</code> or <code class="literal">&lt;escape
+      octet&gt;</code> is also a <code class="literal">&lt;string value
+      expression&gt;</code> that evaluates to a string of exactly one
+      character length. If the underscore or the percent is required as normal
+      characters in the pattern, the specified <code class="literal">&lt;escape
+      character&gt;</code> or <code class="literal">&lt;escape octet&gt;</code> can
+      be used in the pattern before the underscore or the percent. The
+      <code class="literal">&lt;row value predicand&gt;</code> is compared with the
+      <code class="literal">&lt;character pattern&gt;</code> and the result of
+      comparison is returned. If any of the expressions in the predicate
+      evaluates to NULL, the result of the predicate is UNKNOWN. The
+      expression <code class="literal">A NOT LIKE B</code> is equivalent to <code class="literal">NOT
+      (A LIKE B)</code>. If the length of the escape is not 1 or it is used
+      in the pattern not immediately before an underscore or a percent
+      character, an exception is raised.</p>
+<a name="N11F3C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IS NULL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>null predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;null predicate&gt; ::= &lt;row value predicand&gt;
+      IS [ NOT ] NULL</code>
+</p>
+<p>Specify a test for a null value. The expression <code class="literal">X IS
+      NOT NULL</code> is NOT equivalent to <code class="literal">NOT (X IS
+      NULL)</code>if the degree of the <code class="literal">&lt;row value
+      predicand&gt;</code> is larger than 1. The rules are: If all fields
+      are null, <code class="literal">X IS NULL</code> is TRUE and <code class="literal">X IS NOT
+      NULL</code> is FALSE. If only some fields are null, both <code class="literal">X
+      IS NULL</code> and <code class="literal">X IS NOT NULL</code> are FALSE. If all
+      fields are not null, <code class="literal">X IS NULL</code> is FALSE and
+      <code class="literal">X IS NOT NULL</code> is TRUE.</p>
+<a name="N11F68" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ALL and ANY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>quantified comparison predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;quantified comparison predicate&gt; ::= &lt;row
+      value predicand&gt; &lt;comp op&gt; &lt;quantifier&gt; &lt;table
+      subquery&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;quantifier&gt; ::= &lt;all&gt; |
+      &lt;some&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;all&gt; ::= ALL</code>
+</p>
+<p>
+<code class="literal">&lt;some&gt; ::= SOME | ANY</code>
+</p>
+<p>Specify a quantified comparison. For a quantified comparison,
+      the <code class="literal">&lt;row value predicand&gt;</code> is compared one by
+      one with each row of the <code class="literal">&lt;table sub
+      query&gt;</code>.</p>
+<p>If the <code class="literal">&lt;table subquery&gt;</code> returns no
+      rows, then if <code class="literal">ALL</code> is specified the result is TRUE,
+      but if <code class="literal">SOME</code> or <code class="literal">ANY</code> is specified
+      the result is FALSE.</p>
+<p>If <code class="literal">ALL</code> is specified, if the comparison is
+      TRUE for all rows, the result of the predicate is TRUE. If the
+      comparison is FALSE for at least one row, the result is FALSE. Otherwise
+      the result is UNKNOWN.</p>
+<p>If <code class="literal">SOME</code> or <code class="literal">ANY</code> is
+      specified, if the comparison is TRUE for at least one row, the result is
+      TRUE. If the comparison is FALSE for all rows, the result is FALSE.
+      Otherwise the result is UNKNOWN. Note that the IN predicate is
+      equivalent to the SOME or ANY predicate using the <code class="literal">&lt;equals
+      operator&gt;</code>.</p>
+<p>In the examples below, the date of an invoice is compared to
+      holidays in a given year. In the first example the invoice date must
+      equal one of the holidays, in the second example it must be later than
+      all holidays (later than the last holiday), in the third example it must
+      be on or after some holiday (on or after the first holiday), and in the
+      fourth example, it must be before all holidays (before the first
+      holiday).</p>
+<pre class="programlisting">invoice_date = SOME (SELECT holiday_date FROM holidays)
+invoice_date &gt; ALL (SELECT holiday_date FROM holidays)
+invoice_date &gt;= ANY (SELECT holiday_date FROM holidays)
+invoice_date &lt; ALL (SELECT holiday_date FROM holidays)
+</pre>
+<a name="N11FAA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>EXISTS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>exists predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;exists predicate&gt; ::= EXISTS &lt;table
+      subquery&gt;</code>
+</p>
+<p>Specify a test for a non-empty set. If the evaluation of
+      <code class="literal">&lt;table subquery&gt;</code> results in one or more rows,
+      then the expression is TRUE, otherwise FALSE.</p>
+<a name="N11FBE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UNIQUE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>unique predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;unique predicate&gt; ::= UNIQUE &lt;table
+      subquery&gt;</code>
+</p>
+<p>Specify a test for the absence of duplicate rows. The result of
+      the test is either TRUE or FALSE (never UNKNOWN). The rows of the
+      <code class="literal">&lt;table subquery&gt;</code> that contain one or more NULL
+      values are not considered for this test. If the rest of the rows are
+      distinct from each other, the result of the test is TRUE, otherwise it
+      is FALSE. The distinctness of rows X and Y is tested with the predicate
+      <code class="literal">X IS DISTINCT FROM Y</code>.</p>
+<a name="N11FD5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MATCH</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>match predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;match predicate&gt; ::= &lt;row value
+      predicand&gt; MATCH [ UNIQUE ] [ SIMPLE | PARTIAL | FULL ] &lt;table
+      subquery&gt;</code>
+</p>
+<p>Specify a test for matching rows. The default is MATCH SIMPLE
+      without UNIQUE. The result of the test is either TRUE or FALSE (never
+      UNKNOWN).</p>
+<p>The interpretation of NULL values is different from other
+      predicates and quite counter-intuitive. If the <code class="literal">&lt;row value
+      predicand&gt;</code> is NULL, or all of its fields are NULL, the
+      result is TRUE.</p>
+<p>Otherwise, the <code class="literal">&lt;row value predicand&gt;</code>
+      is compared with each row of the <code class="literal">&lt;table
+      subquery&gt;</code>.</p>
+<p>If SIMPLE is specified, if some field of <code class="literal">&lt;row value
+      predicate&gt;</code> is NULL, the result is TRUE. Otherwise if
+      <code class="literal">&lt;row value predicate&gt; </code>is equal to one or more
+      rows of <code class="literal">&lt;table subquery&gt;</code> the result is TRUE if
+      UNIQUE is not specified, or if UNIQUE is specified and only one row
+      matches. Otherwise the result is FALSE.</p>
+<p>If PARTIAL is specified, if the non-null values
+      <code class="literal">&lt;row value predicate&gt; </code>are equal to those in one
+      or more rows of <code class="literal">&lt;table subquery&gt;</code> the result is
+      TRUE if UNIQUE is not specified, or if UNIQUE is specified and only one
+      row matches. Otherwise the result is FALSE.</p>
+<p>If FULL is specified, if some field of <code class="literal">&lt;row value
+      predicate&gt;</code> is NULL, the result is FALSE. Otherwise if
+      <code class="literal">&lt;row value predicate&gt;</code> is equal to one or more
+      rows of <code class="literal">&lt;table subquery&gt;</code> the result is TRUE if
+      UNIQUE is not specified, or if UNIQUE is specified and only one row
+      matches.</p>
+<p>Note that MATCH can also used be used in FOREIGN KEY constraint
+      definitions. The exact meaning is described in the <a class="link" href="#databaseobjects-chapt" title="Chapter&nbsp;4.&nbsp;Schemas and Database Objects">Schemas and Database Objects</a> chapter.</p>
+<a name="N12017" class="indexterm"></a>
+<p>
+<span class="bold"><strong>OVERLAPS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>overlaps predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;overlaps predicate&gt; ::= &lt;row value
+      predicand&gt; OVERLAPS &lt;row value predicand&gt;</code>
+</p>
+<p>Specify a test for an overlap between two datetime periods.
+      Each <code class="literal">&lt;row value predicand&gt;</code> must have two fields
+      and the fields together represent a datetime period. So the predicates
+      is always in the form <code class="literal">(X1, X2) OVERLAPS (Y1, Y2)</code>. The
+      first field is always a datetime value, while the second field is either
+      a datetime value or an interval value.</p>
+<p>If the second value is an interval value, it is replaced with
+      the sum of the datetime value and itself, for example <code class="literal">(X1, X1 +
+      X2) OVERLAPS (Y1, Y1 + Y 2)</code>.</p>
+<p>If any of the values is NULL, the result is UNKNOWN.</p>
+<p>The expression is true if there is there is any overlap between
+      the two datetime periods. In the example below, the period is compared
+      with a week long period ending yesterday.</p>
+<pre class="programlisting">(startdate, enddate) OVERLAPS (CURRENT_DATE - 7 DAY, CURRENT_DATE - 1 DAY)</pre>
+<a name="N12039" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IS DISTINCT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>is distinct predicate</em></span>
+</p>
+<p>
+<code class="literal">&lt;distinct predicate&gt; ::= &lt;row value
+      predicand&gt; IS [ NOT ] DISTINCT FROM &lt;row value
+      predicand&gt;</code>
+</p>
+<p>Specify a test of whether two row values are distinct. The
+      result of the test is either TRUE or FALSE (never UNKNOWN). The
+      <em class="glossterm">degree</em> the two <code class="literal">&lt;row value
+      predicand&gt;</code> must be the same. Each field of the first
+      <code class="literal">&lt;row value predicand&gt;</code> is compared to the field
+      of the second <code class="literal">&lt;row value predicand&gt;</code> at the same
+      position. If one field is NULL and the other is not NULL, or if the
+      elements are NOT equal, then the result of the expression is TRUE. If no
+      comparison result is TRUE, then the result of the predicate is FALSE.
+      The expression <code class="literal">X IS NOT DISTINCT FROM Y</code> is equivalent
+      to <code class="literal">NOT (X IS DISTINCT FORM Y)</code>. The following check
+      returns true if startdate is not equal to enddate. It also returns true
+      if either startdate or enddate is NULL. It returns false in other
+      cases.</p>
+<pre class="programlisting">startdate IS DISTINCT FROM enddate</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1205E"></a>Other Syntax Elements</h3>
+</div>
+</div>
+</div>
+<a name="N12061" class="indexterm"></a>
+<p>
+<span class="bold"><strong>search condition</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>search condition</em></span>
+</p>
+<p>
+<code class="literal">&lt;search condition&gt; ::= &lt;boolean value
+      expression&gt;</code>
+</p>
+<p>Specify a condition that is TRUE, FALSE, or UNKNOWN. A search
+      condition is often a predicate.</p>
+<a name="N12072" class="indexterm"></a>
+<p>
+<span class="bold"><strong>PATH</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>path specification</em></span>
+</p>
+<p>
+<code class="literal">&lt;path specification&gt; ::= PATH &lt;schema name
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema name list&gt; ::= &lt;schema name&gt; [ {
+      &lt;comma&gt; &lt;schema name&gt; }... ]</code>
+</p>
+<p>Specify an order for searching for a user-defined SQL-invoked
+      routine. This is not currently supported by HyperSQL.</p>
+<a name="N12086" class="indexterm"></a>
+<p>
+<span class="bold"><strong>routine invocation</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>routine invocation</em></span>
+</p>
+<p>
+<code class="literal">&lt;routine invocation&gt; ::= &lt;routine name&gt;
+      &lt;SQL argument list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;routine name&gt; ::= [ &lt;schema name&gt;
+      &lt;period&gt; ] &lt;qualified identifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL argument list&gt; ::= &lt;left paren&gt; [
+      &lt;SQL argument&gt; [ { &lt;comma&gt; &lt;SQL argument&gt; }... ] ]
+      &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL argument&gt; ::= &lt;value expression&gt; |
+      &lt;target specification&gt;</code>
+</p>
+<p>Invoke an SQL-invoked routine. Examples are given in the <a class="link" href="#sqlroutines-chapt" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">SQL-Invoked Routines</a>
+      chapter.</p>
+<a name="N120A4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COLLATE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>collate clause</em></span>
+</p>
+<p>
+<code class="literal">&lt;collate clause&gt; ::= COLLATE &lt;collation
+      name&gt;</code>
+</p>
+<p>Specify a default collation. This is not currently supported by
+      HyperSQL</p>
+<a name="N120B5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONSTRAINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>constraint name definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;constraint name definition&gt; ::= CONSTRAINT
+      &lt;constraint name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;constraint characteristics&gt; ::= &lt;constraint
+      check time&gt; [ [ NOT ] DEFERRABLE ] | [ NOT ] DEFERRABLE [
+      &lt;constraint check time&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;constraint check time&gt; ::= INITIALLY DEFERRED |
+      INITIALLY IMMEDIATE</code>
+</p>
+<p>Specify the name of a constraint and its characteristics. This
+      is an optional element of CONSTRAINT definition, not yet supported by
+      HyperSQL.</p>
+<a name="N120CC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>aggregate function</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>aggregate function</em></span>
+</p>
+<p>
+<code class="literal">&lt;aggregate function&gt; ::= COUNT &lt;left
+      paren&gt; &lt;asterisk&gt; &lt;right paren&gt; [ &lt;filter clause&gt; ]
+      | &lt;general set function&gt; [ &lt;filter clause&gt; ]
+      </code>
+</p>
+<p>
+<code class="literal">&lt;general set function&gt; ::= &lt;set function
+      type&gt; &lt;left paren&gt; [ &lt;set quantifier&gt; ] &lt;value
+      expression&gt; &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;set function type&gt; ::= &lt;computational
+      operation&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;computational operation&gt; ::= AVG | MAX | MIN |
+      SUM | EVERY | ANY | SOME | COUNT | STDDEV_POP | STDDEV_SAMP | VAR_SAMP |
+      VAR_POP</code>
+</p>
+<p>
+<code class="literal">&lt;set quantifier&gt; ::= DISTINCT |
+      ALL</code>
+</p>
+<p>
+<code class="literal">&lt;filter clause&gt; ::= FILTER &lt;left paren&gt;
+      WHERE &lt;search condition&gt; &lt;right paren&gt;</code>
+</p>
+<p>Specify a value computed from a collection of rows. An
+      aggregate function is used exclusively in a <code class="literal">&lt;query
+      specification&gt;</code> and its use transforms a normal query into
+      an aggregate query returning a single row instead of the group of
+      multiple rows that the original query returns. For example,
+      <code class="literal">SELECT acolumn &lt;table expression&gt;</code> is a query
+      that returns the value of acolumn for all the rows the satisfy the given
+      condition. But <code class="literal">SELECT MAX(acolumn) &lt;table
+      expression&gt;</code> returns only one row, containing the largest
+      value in that column. The query <code class="literal">SELECT COUNT(*) &lt;table
+      expression&gt;</code> returns the count of rows, while
+      <code class="literal">SELECT COUNT(acolumn) &lt;table expression&gt;</code>
+      returns the count of rows where <code class="literal">acolumn IS NOT
+      NULL</code>.</p>
+<p>If the <code class="literal">&lt;table expression&gt;</code> is a grouped
+      table, the aggregate function returns the result of the
+      <code class="literal">COUNT</code> or <code class="literal">&lt;computational
+      operation&gt;</code> for each group. In this case the result has the
+      same number of rows as the original query. For example <code class="literal">SELECT
+      SUM(acolumn) &lt;table expression&gt;</code> when <code class="literal">&lt;table
+      expression&gt;</code> has a <code class="literal">GROUP BY</code> clause,
+      returns the sum of values for <code class="literal">acolumn</code> in each
+      group.</p>
+<p>The AVG and SUM operations can be performed on numeric
+      expressions only. AVG returns the average value, while SUM returns the
+      sum of all non-null values. MAX and MIN return the minimum or the
+      maximum value. If all values are NULL, the operations return NULL. The
+      <code class="literal">COUNT(*)</code> operation returns the count of all values,
+      while <code class="literal">COUNT(&lt;value expression&gt;)</code> returns the
+      count of non-NULL values.</p>
+<p>The EVERY, ANY and SOME operations can be performed on boolean
+      expressions only. EVERY returns TRUE if all the values are TRUE,
+      otherwise FALSE. ANY and SOME are the same operation and return TRUE if
+      one of the values is TRUE, otherwise it returns FALSE.</p>
+<p>The other operations perform the statistical functions
+      STDDEV_POP, STDDEV_SAMP, VAR_SAMP, VAR_POP on numeric values. NULL
+      values are ignored in calculations.</p>
+<p>User defined aggregate functions can be defined and used
+      instead of the built-in aggregate functions. Syntax and examples are
+      given in the <a class="link" href="#sqlroutines-chapt" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">SQL-Invoked Routines</a> chapter.</p>
+<a name="N12127" class="indexterm"></a>
+<p>
+<span class="bold"><strong>sort specification
+      list</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>sort specification list</em></span>
+</p>
+<p>
+<code class="literal">&lt;sort specification list&gt; ::= &lt;value
+      expression&gt; [ASC | DESC] [NULLS FIRST | NULLS
+      LAST]</code>
+</p>
+<p>Specify a sort order. A sort operation is performed on the
+      result of a <code class="literal">&lt;query expression&gt;</code> or
+      <code class="literal">&lt;query specification&gt;</code> and sorts the result
+      according to one or more <code class="literal">&lt;value expression&gt;</code>.
+      The <code class="literal">&lt;value expression&gt;</code> is usually a single
+      column of the result, but in some cases it can be a column of the
+      <code class="literal">&lt;table expression&gt;</code> that is not used in the
+      select list.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12147"></a>Data Access Statements</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL fully supports all of SQL-92 data access statements, plus
+    some additions from SQL:2008. Due to time constraints, the current version
+    of this Guide does not cover the subject fully. You are advised to consult
+    an SQL book such as the recent O'Reilly title "SQL and Relational Theory"
+    by C. J. Date.</p>
+<p>Database queries are data access statements. The most commonly used
+    data access statement is the SELECT statement, but there are other
+    statements that perform a similar role. Data access statements access
+    tables and return result tables. The returned result tables are falsely
+    called result sets, as they are not necessarily sets of rows, but
+    multisets of rows.</p>
+<p>Result tables are formed by performing the following operations on
+    base tables and views. These operations are loosely based on Relational
+    Algebra.</p>
+<p>
+<em class="glossterm">JOIN</em> operations</p>
+<p>
+<em class="glossterm">SET</em> and <em class="glossterm">MULTISET</em>
+    operations</p>
+<p>
+<em class="glossterm">SELECTION</em>
+</p>
+<p>
+<em class="glossterm">PROJECTION</em>
+</p>
+<p>
+<em class="glossterm">COMPUTING</em>
+</p>
+<p>
+<em class="glossterm">COLUMN NAMING</em>
+</p>
+<p>
+<em class="glossterm">GROUPING</em> and
+    <em class="glossterm">AGGREGATION</em>
+</p>
+<p>
+<em class="glossterm">SELECTION AFTER GROUPING OR
+    AGGREGATION</em>
+</p>
+<p>
+<em class="glossterm">SET and MULTISET (COLLECTION)
+    OPERATIONS</em>
+</p>
+<p>
+<em class="glossterm">ORDERING</em>
+</p>
+<p>
+<em class="glossterm">SLICING</em>
+</p>
+<p>Conceptually, the operations are performed one by one in the above
+    order if they apply to the given data access statement. In the example
+    below a simple select statement is made more complex by adding various
+    operations.</p>
+<p>
+<pre class="programlisting">CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+/* in the next SELECT, no join is performed and no further operation takes place */
+SELECT * FROM atable
+/* in the next SELECT, selection is performed by the WHERE clause, with no further action */
+SELECT * FROM atable WHERE a + b = c
+/* in the next SELECT, projection is performed after the other operations */
+SELECT d, e, f FROM atable WHERE a + b = c
+/* in the next SELECT, computation is performed after projection */
+SELECT (d + e) / f FROM atable WHERE a + b = c
+/* in the next two SELECT statements, column naming is performed in different ways*/
+SELECT (a + e) / f AS calc, f AS div FROM atable WHERE a + b = c
+SELECT dcol, ecol, fcol FROM atable(acol, bcol, ccol, dcol, ecol, fcol) WHERE acol + bcol = ccol
+/* in the next SELECT, both grouping and aggregation is performed */
+SELECT d, e, SUM(f) FROM atable GROUP BY d, e
+/* in the next SELECT, selection is performed after grouping and aggregation is performed */
+SELECT d, e, SUM(f) FROM atable GROUP BY d, e HAVING SUM(f) &gt; 10
+/* in the next SELECT, a UNION is performed on two selects from the same table */
+SELECT d, e, f FROM atable WHERE d = 3 UNION SELECT a, b, c FROM atable WHERE a = 30
+/* in the next SELECT, ordering is performed */
+SELECT (a + e) / f AS calc, f AS div FROM atable WHERE a + b = c ORDER BY calc DESC, div NULLS LAST
+/* in the next SELECT, slicing is performed after ordering */
+SELECT * FROM atable WHERE a + b = c ORDER BY a FETCH 5 ROWS ONLY
+
+</pre>The next sections discuss various types of tables and
+    operations involved in data access statements.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1217F"></a>Table</h3>
+</div>
+</div>
+</div>
+<p>In data access statements, a table can be a database table (or
+      view) or an ephemeral table formed for the duration of the query. Some
+      types of table are &lt;table primary&gt; and can participate in joins
+      without the use of extra parentheses. The BNF in the Table Primary
+      section below lists different types of &lt;table primary&gt;:</p>
+<p>Tables can also be formed by specifying the values that are
+      contained in them:</p>
+<p>
+<code class="literal">&lt;table value constructor&gt; ::= VALUES &lt;row
+      value expression list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;row value expression list&gt; ::= &lt;table row
+      value expression&gt; [ { &lt;comma&gt; &lt;table row value
+      expression&gt; }... ]</code>
+</p>
+<p>In the example below a table with two rows and 3 columns is
+      constructed out of some values:</p>
+<pre class="programlisting">VALUES (12, 14, null), (10, 11, CURRENT_DATE)</pre>
+<p>When a table is used directly in a UNION or similar operation,
+      the keyword TABLE is used with the name:</p>
+<p>
+<code class="literal">&lt;explicit table&gt; ::= TABLE &lt;table or query
+      name&gt;</code>
+</p>
+<p>In the examples below, all rows of the two tables are included
+      in the union. The keyword TABLE is used in the first example. The two
+      examples below are equivalent.</p>
+<pre class="programlisting">TABLE atable UNION TABLE anothertable
+SELECT * FROM atable UNION SELECT * FROM anothertable
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12199"></a>Query Specification</h3>
+</div>
+</div>
+</div>
+<p>A query specification is a SELECT statement. It is the most common
+      form of <code class="literal">&lt;derived table&gt;</code> . A <code class="literal">&lt;table
+      expression&gt;</code> is a base table, a view or any form of allowed
+      derived table. The SELECT statement performs projection, naming,
+      computing or aggregation on the rows of the <code class="literal">&lt;table
+      expression&gt;</code> .</p>
+<p>
+<code class="literal">&lt;query specification&gt; ::= SELECT [ DISTINCT |
+      ALL ] &lt;select list&gt; &lt;table expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;select list&gt; ::= &lt;asterisk&gt; | &lt;select
+      sublist&gt; [ { &lt;comma&gt; &lt;select sublist&gt; }... ]
+      </code>
+</p>
+<p>
+<code class="literal">&lt;select sublist&gt; ::= &lt;derived column&gt; |
+      &lt;qualified asterisk&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;qualified asterisk&gt; ::= &lt;asterisked
+      identifier chain&gt; &lt;period&gt; &lt;asterisk&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;asterisked identifier chain&gt; ::= &lt;asterisked
+      identifier&gt; [ { &lt;period&gt; &lt;asterisked identifier&gt; }... ]
+      </code>
+</p>
+<p>
+<code class="literal">&lt;asterisked identifier&gt; ::=
+      &lt;identifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;derived column&gt; ::= &lt;value expression&gt; [
+      &lt;as clause&gt; ] </code>
+</p>
+<p>
+<code class="literal">&lt;as clause&gt; ::= [ AS ] &lt;column name&gt;
+      </code>
+</p>
+<p>The qualifier DISTINCT or ALL apply to the results of the SELECT
+      statement after all other operations have been performed. ALL simply
+      returns the rows, while DISTINCT compares the rows and removes the
+      duplicate ones.</p>
+<p>Projection is performed by the <code class="literal">&lt;select
+      list&gt;</code>.</p>
+<p>A single <code class="literal">&lt;asterisk&gt;</code> means all columns of
+      the <code class="literal">&lt;table expression&gt;</code> are included, in the
+      same order as they appear in the <code class="literal">&lt;table
+      expression&gt;</code>. An asterisk qualified by a table name means
+      all the columns of the qualifier table name are included.</p>
+<p>A derived column is a <code class="literal">&lt;value expression&gt;</code>,
+      optionally named with the <code class="literal">&lt;as clause&gt;</code>. A
+      <code class="literal">&lt;value expression&gt;</code> can be many things. Common
+      types include: the name of a column in the <code class="literal">&lt;table
+      expression&gt;</code>; an expression based on different columns or
+      constant values; a function call; an aggregate function; a CASE WHEN
+      expression.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N121DF"></a>Table Expression</h3>
+</div>
+</div>
+</div>
+<p>A table expression is part of the SELECT statement and consists of
+      the FROM clause with optional other clauses that performs selection (of
+      rows) and grouping from the table(s) in the FROM clause.</p>
+<p>
+<code class="literal">&lt;table expression&gt; ::= &lt;from clause&gt; [
+      &lt;where clause&gt; ] [ &lt;group by clause&gt; ] [ &lt;having
+      clause&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;from clause&gt; ::= FROM &lt;table reference&gt; [ {
+      &lt;comma&gt; &lt;table reference&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;table reference&gt; ::= &lt;table primary&gt; |
+      &lt;joined table&gt; </code>
+</p>
+<p>
+<code class="literal">&lt;table primary&gt; ::= &lt;table or query name&gt;
+      [ [ AS ] &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived
+      column list&gt; &lt;right paren&gt; ] ] </code>
+</p>
+<p>
+<code class="literal">| &lt;derived table&gt; [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] </code>
+</p>
+<p>
+<code class="literal">| &lt;lateral derived table&gt; [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] </code>
+</p>
+<p>
+<code class="literal">| &lt;collection derived table&gt; [ AS ]
+      &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived column
+      list&gt; &lt;right paren&gt; ] </code>
+</p>
+<p>
+<code class="literal">| &lt;table function derived table&gt; [ AS ]
+      &lt;correlation name&gt; [ &lt;left paren&gt; &lt;derived column
+      list&gt; &lt;right paren&gt; ] </code>
+</p>
+<p>
+<code class="literal">| &lt;parenthesized joined
+      table&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;where clause&gt; ::= WHERE &lt;boolean value
+      expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;group by clause&gt; ::= GROUP BY [ &lt;set
+      quantifier&gt; ] &lt;grouping element&gt; [ { &lt;comma&gt; &lt;grouping
+      element&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;having clause&gt; ::= HAVING &lt;boolean value
+      expression&gt;</code>
+</p>
+<p>The <code class="literal">&lt;from clause&gt;</code> contains one or more
+      <code class="literal">&lt;table reference&gt;</code> separated by commas. A table
+      reference is often a table or view name or a joined table.</p>
+<p>The <code class="literal">&lt;where clause&gt;</code> filters the rows of
+      the table in the &lt;from clause&gt; and removes the rows for which the
+      search condition is not TRUE.</p>
+<p>The <code class="literal">&lt;group by clause&gt;</code> is a comma
+      separated list of columns of the table in the <code class="literal">&lt;from
+      clause&gt;</code> or expressions based on the columns.</p>
+<p>When a <code class="literal">&lt;group by clause&gt;</code> is used, only
+      the columns used in the <code class="literal">&lt;group by clause&gt;</code> or
+      expressions used there, can be used in the <code class="literal">&lt;select
+      list&gt;</code>, together with any <code class="literal">&lt;aggregate
+      function&gt;</code> on other columns. A <code class="literal">&lt;group by
+      clause&gt;</code> compares the rows and groups together the rows that
+      have the same values in the columns of the <code class="literal">&lt;group by
+      clause&gt;</code>. Then any <code class="literal">&lt;aggregate
+      function&gt;</code> in the <code class="literal">&lt;select list&gt;</code> is
+      performed on each group, and for each group, a row is formed that
+      contains the values of the columns of the <code class="literal">&lt;group by
+      clause&gt;</code> and the values returned from each
+      <code class="literal">&lt;aggregate function&gt;. In the first example below, a
+      simple column reference is used in GROUP BY, while in the second
+      example, an expression is used.</code>
+<pre class="programlisting">CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+SELECT d, e, f FROM atable WHERE a + b = c GROUP BY d, e, f
+SELECT d + e, SUM(f) FROM atable WHERE a + b = c GROUP BY d + e HAVING SUM(f) &gt; 2 AND d + e &gt; 4
+</pre>
+</p>
+<p>A <code class="literal">&lt;having clause&gt;</code> filters the rows of the
+      table that is formed after applying the <code class="literal">&lt;group by
+      clause&gt;</code> using its search condition. The search condition
+      must be an expression based on the expressions in the GROUP BY list or
+      the aggregate functions used.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12246"></a>Table Primary</h3>
+</div>
+</div>
+</div>
+<p>Table primary refers to different forms of table reference in the
+      FROM clause.</p>
+<p>The simplest form of reference is simply a name. This is the name
+      of a table, a view, a transition table in a trigger definition, or a
+      query name specified in the WITH clause of a query expression.</p>
+<p>
+<code class="literal">&lt;table or query name&gt; ::= &lt;table name&gt; |
+      &lt;transition table name&gt; | &lt;query name&gt;</code>
+</p>
+<p>A query expression that is enclosed in parentheses and returns
+      from zero to many rows is a <code class="literal">&lt;table subquery&gt;</code>.
+      In a <code class="literal">&lt;derived table&gt;</code> the query expression is
+      self contained and cannot reference the columns of other table
+      references.</p>
+<p>
+<code class="literal">&lt;derived table&gt; ::= &lt;table
+      subquery&gt;</code>
+</p>
+<p>
+<code class="literal">When the word LITERAL is used before a &lt;table
+      subquery&gt;, it means the query expression can reference the columns of
+      other table references that precede it. </code>
+</p>
+<p>
+<code class="literal">&lt;lateral derived table&gt; ::= LATERAL &lt;table
+      subquery&gt;</code>
+</p>
+<p>UNNEST is similar to LATERAL, but instead of a query expression,
+      and expression that returns an array is used. This expression is
+      converted into a table which has one column that contains the elements
+      of the array, and, if WITH ORDINALITY is used, a second column that
+      contains the index of each element. The array expression usually
+      contains a reference to a column of the table reference preceding the
+      current table reference.</p>
+<p>
+<code class="literal">&lt;collection derived table&gt; ::= UNNEST &lt;left
+      paren&gt; &lt;array value expression&gt; &lt;right paren&gt; [ WITH
+      ORDINALITY ]</code>
+</p>
+<p>When TABLE is used in this context, it also converts an array
+      value expression to a table, but this array must be the result of a
+      function call. A function that returns a MULTISET can also be used in
+      this context and each row of the multiset is expanded into a row of the
+      table.</p>
+<p>
+<code class="literal">&lt;table function derived table&gt; ::= TABLE &lt;left
+      paren&gt; &lt;collection value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>The column list that is specified for the table reference must
+      contain names that are unique within the list</p>
+<p>
+<code class="literal">&lt;derived column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;column name list&gt; ::= &lt;column name&gt; [ {
+      &lt;comma&gt; &lt;column name&gt; }... ] </code>
+</p>
+<p>A parenthesized joined table is simply a joined table contained in
+      parentheses. Joined tables are discussed below.</p>
+<p>
+<code class="literal">&lt;parenthesized joined table&gt; ::= &lt;left paren&gt;
+      &lt;parenthesized joined table&gt; &lt;right paren&gt; | &lt;left
+      paren&gt; &lt;joined table&gt; &lt;right paren&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12278"></a>Joined Table</h3>
+</div>
+</div>
+</div>
+<p>Joins are operators with two table as the operands, resulting in a
+      third table, called joined table. All join operators are evaluated left
+      to right, therefore, with multiple joins, the table resulting from the
+      first join operator becomes an operand of the next join operator.
+      Parentheses can be used to group sequences of joined tables and change
+      the evaluation order. So if more than two tables are joined together
+      with join operators, the end result is also a joined table. There are
+      different types of join, each producing the result table in a different
+      way.</p>
+<a name="N1227D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CROSS JOIN</strong></span>
+</p>
+<p>The simplest form of join is CROSS JOIN. The CROSS JOIN of two
+      tables is a table that has all the columns of the first table, followed
+      by all the columns of the second table, in the original order. Each row
+      of the first table is combined with each row of the second table to fill
+      the rows of the new table. If the rows of each table form a set, then
+      the rows of the CROSS JOIN table form the Cartesian product of the rows
+      of the two table operands.</p>
+<p>The CROSS JOIN can be expressed in two forms. The first form is
+      <code class="literal">A CROSS JOIN B</code>. The second form is <code class="literal">A,
+      B</code>. This type of join is not generally very useful, as it
+      returns large result tables.</p>
+<a name="N12290" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UNION JOIN</strong></span>
+</p>
+<p>The UNION JOIN has limited use in queries. The result table has
+      the same columns as that of CROSS JOIN. Each row of the first table is
+      extended to the right with nulls and added to the new table. Each row of
+      the second table is extended to the left with nulls and added to the new
+      table. The UNION JOIN is expressed as <code class="literal">A UNION JOIN B</code>.
+      This should not be confused with <code class="literal">A UNION B</code>, which is
+      a set operation. Union join is for special applications and is not
+      commonly used.</p>
+<a name="N122A1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>JOIN ... ON</strong></span>
+</p>
+<p>The condition join is similar to CROSS JOIN, but a condition is
+      tested for each row of the new table and the row is created only if the
+      condition is true. This form of join is expressed as <code class="literal">A JOIN B
+      ON (&lt;search condition&gt;)</code>.</p>
+<p>Equijoin is a condition join in which the search condition is an
+      equality condition between on or more pairs of columns from the two
+      table. Equijoin is the most commonly used type of join.</p>
+<a name="N122B1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>JOIN ... USING</strong></span>
+</p>
+<a name="N122BA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NATURAL JOIN</strong></span>
+</p>
+<p>Joins with USING or NATURAL keywords joins are similar to an
+      equijoin but they cannot be replaced simply with an equijoin. The new
+      table is formed with the specified or implied shared columns of the two
+      tables, followed by the rest of the columns from each table. In NATURAL
+      JOIN, the shared columns are all the column pairs that have the same
+      name in the first and second table. In JOIN USING, only columns names
+      that are specified by the USING clause are shared. The joins are
+      expressed as <code class="literal">A NATURAL JOIN B</code>, and <code class="literal">A JOIN B
+      USING (&lt;comma separated column name list&gt;)</code>.</p>
+<p>The columns of the joined table are formed by the following
+      procedures: In JOIN ... USING the shared columns are added to the joined
+      table in the same order as they appear in the column name list. In
+      NATURAL JOIN the shared columns are added to the joined table in the
+      same order as they appear in the first table. In bother forms of join,
+      the non-shared columns of the first table are added in the order they
+      appear in the first table, finally the non-shared columns of the second
+      table are added in the order they appear in the second table.</p>
+<p>The type of each shared column of the joined table is based on the
+      type of the columns in the original tables. If the original types are
+      not exactly the same, the type of the shared column is formed by type
+      aggregation. Type aggregations selects a type that can represent values
+      of both aggregated types. Simple type aggregation picks one of the
+      types. For example SMALLINT and INTEGER, results in INTEGER, or
+      VARCHAR(10) and VARCHAR(20) results in VARCHAR(20). More complex type
+      aggregation inherits properties from both types. For example DECIMAL(8)
+      and DECIMAL (6,2) results in DECIMAL (8,2).</p>
+<a name="N122CF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>OUTER JOIN</strong></span>
+</p>
+<p>LEFT, RIGHT and FULL OUTER JOIN</p>
+<p>The three qualifiers can be added to all types of JOIN apart from
+      CROSS JOIN and UNION JOIN. First the new table is populated with the
+      rows from the original join. If LEFT is specified, all the rows from the
+      first table that did not make it into the new table are extended to the
+      right with nulls and added to the table. If RIGHT is specified, all the
+      rows from the second table that did not make it into the new table are
+      extended to the left with nulls and added to the table. If FULL is
+      specified, the addition of leftover rows is performed from both the
+      first and the second table. These forms are expressed by prefixing the
+      join specification with the given keyword. For example <code class="literal">A LEFT
+      OUTER JOIN B ON (&lt;search condition&gt;)</code> or <code class="literal">A
+      NATURAL FULL OUTER JOIN B</code> or <code class="literal">A FULL OUTER JOIN B
+      USING (&lt;comma separated column name list&gt;)</code>.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N122E5"></a>Selection</h3>
+</div>
+</div>
+</div>
+<p>Despite the name, selection has nothing to do with the list of
+      columns in a SELECT statement. In fact, it refers to the search
+      condition used to limit the rows that from a result table (selection of
+      rows, not columns). In SQL, simple selection is expressed with a WHERE
+      condition appended to a single table or a joined table. In some cases,
+      this method of selection is the only method available. But when it is
+      possible to perform the selection with join conditions, this is the
+      better method, as it results in a clearer expression of the
+      query.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N122EA"></a>Projection</h3>
+</div>
+</div>
+</div>
+<p>Projection is selection of the columns from a simple or joined
+      table to form a result table. Explicit projection is performed in the
+      SELECT statement by specifying the select column list. Some form of
+      projection is also performed in JOIN ... USING and NATURAL JOIN.</p>
+<p>The joined table has columns that are formed according to the
+      rules mentioned above. But in many cases, not all the columns are
+      necessary for the intended operation. If the statement is in the form,
+      SELECT * FROM &lt;joined table&gt;, then all the columns of &lt;joined
+      table&gt; are returned. But normally, the columns to be returned are
+      specified after the SELECT keyword, separated from each other with
+      commas.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N122F1"></a>Computed Columns</h3>
+</div>
+</div>
+</div>
+<p>In the select list, it is possible to use expressions that
+      reference any columns of &lt;joined table&gt;. Each of these expressions
+      forms a computed column. It is computed for each row of the result
+      table, using the values of the columns of the &lt;joined table&gt; for
+      that row.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N122F6"></a>Naming</h3>
+</div>
+</div>
+</div>
+<p>Naming is used to hide the original names of tables or table
+      columns and to replace them with new names in the scope of the query.
+      Naming is also used for defining names for computed columns.</p>
+<a name="N122FB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Naming in Joined
+      Table</strong></span>
+</p>
+<p>Naming is performed by adding a new name after a table's real name
+      and by adding a list of column names after the new table name. Both
+      table naming and column naming are optional, but table naming is
+      required for column naming. The expression <code class="literal">A [AS] X (&lt;comma
+      separated column name list&gt;)</code> means table A is used in the
+      query expression as table X and its columns are named as in the given
+      list. The original name A, or its original column names, are not visible
+      in the scope of the query. The BNF is given below. The
+      <code class="literal">&lt;correlation name&gt;</code> can be the same or different
+      from the name of the table. The <code class="literal">&lt;derived column
+      list&gt;</code> is a comma separated list of column names. The degree
+      of this list must be equal to the degree of the table. The column names
+      in the list must be distinct. They can be the same or different from the
+      names of the table's columns.</p>
+<p>
+<code class="literal">&lt;table or query name&gt; [ [ AS ] &lt;correlation
+      name&gt; [ &lt;left paren&gt; &lt;derived column list&gt; &lt;right
+      paren&gt; ] ]</code>
+</p>
+<p>In the examples below, the columns of the original tables are
+      named (a, b, c, d, e, f). The two queries are equivalent. In the second
+      query, the table and its columns are renamed and the new names are used
+      in the WHERE clauses:</p>
+<pre class="programlisting">CREATE TABLE atable (a INT, b INT, c INT, d INT, e INT, f INT);
+SELECT d, e, f FROM atable WHERE a + b = c
+SELECT x, y, z FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w</pre>
+<a name="N12316" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Naming in Select
+      List</strong></span>
+</p>
+<p>Naming in the SELECT list logically takes place after naming in
+      the joined table. The new names for columns are not visible in the
+      immediate query expression or query expression. They become visible in
+      the ORDER BY clause and in the result table that is returned to the
+      user. Or if the query expression is used as a derived table in an
+      enclosing query expression.</p>
+<p>In the example below, the query is on the same table but with
+      column renaming in the Select list. The new names are used in the ORDER
+      BY clause:</p>
+<pre class="programlisting">SELECT x + y AS xysum, y + z AS yzsum FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w ORDER BY xysum, yzsum</pre>
+<p>If the names <code class="literal">xysum</code> or <code class="literal">yzsum</code>
+      are not used, the computed columns cannot be referenced in the ORDER BY
+      list.</p>
+<a name="N1232D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Name Resolution</strong></span>
+</p>
+<p>In a joined table, if a column name appears in tables on both
+      sides then any reference to the name must use the table name in order to
+      specify which table is being referred to.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12338"></a>Grouping Operations</h3>
+</div>
+</div>
+</div>
+<a name="N1233B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Grouping Operations</strong></span>
+</p>
+<p>Grouping results in the elimination of duplicate rows. A grouping
+      operation is performed after the operations discussed above. A simple
+      form of grouping is performed by the use of DISTINCT after SELECT. This
+      eliminates all the duplicate rows (rows that have the same value in each
+      of their columns when compared to another row). The other form of
+      grouping is performed with the GROUP BY clause. This form is usually
+      used together with aggregation.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12346"></a>Aggregation</h3>
+</div>
+</div>
+</div>
+<p>Aggregation is an operation that computes a single value from the
+      values of a column over several rows. The operation is performed with an
+      aggregate function. The simplest form of aggregation is counting,
+      performed by the COUNT function.</p>
+<p>Other common aggregate functions return the maximum, minimum and
+      average value among the values in different rows.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1234D"></a>Set Operations</h3>
+</div>
+</div>
+</div>
+<a name="N12350" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Set and Multiset
+      Operations</strong></span>
+</p>
+<p>While join operations generally result in laterally expanded
+      tables, SET and COLLECTION operations are performed on two tables that
+      have the same degree and result in a table of the same degree. The SET
+      operations are UNION, INTERSECT and EXCEPT (difference). When each of
+      these operations is performed on two tables, the collection of rows in
+      each table and in the result is reduced to a set of rows, by eliminating
+      duplicates. The set operations are then performed on the two tables,
+      resulting in the new table which itself is a set of rows. Collection
+      operations are similar but the tables are not reduced to sets before or
+      after the operation and the result is not necessarily a set, but a
+      collection of rows.</p>
+<p>The set operations on two tables A and B are: <code class="literal">A UNION
+      [DISTINCT] B</code>, <code class="literal">A INTERSECT [DISTINCT] B</code> and
+      <code class="literal">A EXCEPT [DISTINCT] B</code>. The result table is formed in
+      the following way: The UNION operation adds all the rows from A and B
+      into the new table, but avoids copying duplicate rows. The INTERSECT
+      operation copies only those rows from each table that also exist in the
+      other table, but avoids copying duplicate rows. The EXCEPT operation
+      copies those rows from the first table which do not exist in the second
+      table, but avoids copying duplicate rows.</p>
+<p>The collection operations are similar to the set operations, but
+      can return duplicate rows. They are <code class="literal">A UNION ALL B</code>,
+      <code class="literal">A INTERSECT ALL B</code> and <code class="literal">A EXCEPT ALL
+      B</code>. The UNION ALL operation adds all the rows from A and B into
+      the new table. The INTERSECT operation copies only those rows from each
+      table that also exist in the other table. If n copies of a rows exists
+      in one table, and m copies in the other table, the number of copies in
+      the result table is the smaller of n and m. The EXCEPT operation copies
+      those rows from the first table which do not exist in the second table.
+      If n copies of a row exist in the first table and m copies in the second
+      table the number of copies in the result table is n-m, or if n &lt; m,
+      then zero.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12371"></a>Query Expression</h3>
+</div>
+</div>
+</div>
+<p>A query expression consists of an optional WITH clause and a query
+      expression body. The WITH clause lists one or more named ephemeral
+      tables that can be referenced in the query expression body.</p>
+<p>
+<code class="literal">&lt;query expression&gt; ::= [ &lt;with clause&gt; ]
+      &lt;query expression body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;with clause&gt; ::= WITH &lt;with
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;with list&gt; ::= &lt;with list element&gt; [ {
+      &lt;comma&gt; &lt;with list element&gt; }... ] </code>
+</p>
+<p>
+<code class="literal">&lt;with list element&gt; ::= &lt;query name&gt; [
+      &lt;left paren&gt; &lt;with column list&gt; &lt;right paren&gt; ] AS
+      &lt;left paren&gt; &lt;query expression&gt; &lt;right paren&gt;
+      </code>
+</p>
+<p>
+<code class="literal">&lt;with column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>A query expression body refers to a table formed by using UNION
+      and other set operations. The query expression body is evaluated from
+      left to right and the INTERSECT operator has precedence over the UNION
+      and EXCEPT operators. A simplified BNF is given below:</p>
+<p>
+<code class="literal">&lt;query expression body&gt; ::= &lt;query term&gt; |
+      &lt;query expression body&gt; UNION | EXCEPT [ ALL | DISTINCT ] [
+      &lt;corresponding spec&gt; ] &lt;query term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;query term&gt; ::= &lt;query primary&gt; |
+      &lt;query term&gt; INTERSECT [ ALL | DISTINCT ] [ &lt;corresponding
+      spec&gt; ] &lt;query term&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;query primary&gt; ::= &lt;simple table&gt; |
+      &lt;left paren&gt; &lt;query expression body&gt; [ &lt;order by
+      clause&gt; ] [ &lt;result offset clause&gt; ] [ &lt;fetch first
+      clause&gt; ] &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;simple table&gt; ::= &lt;query specification&gt; |
+      &lt;table value constructor&gt; | &lt;explicit table&gt; &lt;explicit
+      table&gt; ::= TABLE &lt;table or query name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;corresponding spec&gt; ::= CORRESPONDING [ BY
+      &lt;left paren&gt; &lt;column name list&gt; &lt;right paren&gt;
+      ]</code>
+</p>
+<p>A <code class="literal">&lt;query term&gt;</code> and a <code class="literal">&lt;query
+      primary&gt;</code> can be a SELECT statement, an
+      <code class="literal">&lt;explicit table&gt;</code>, or a <code class="literal">&lt;table value
+      constructor&gt;</code>.</p>
+<p>The CORRESPONDING clause is optional. If it is not specified, then
+      the <code class="literal">&lt;query term&gt;</code> and the <code class="literal">&lt;query
+      primary&gt;</code> must have the same number of columns. If
+      CORRESPONDING is specified, the two sides need not have the same number
+      of columns. If no column list is used with CORRESPONDING, then all the
+      column names that are common in the tables on two sides are used in the
+      order in which they appear in the first table. If a columns list is
+      used, it allows you to select only some columns of the tables on the
+      left and right side to create the new table. In the example below the
+      columns named u and v from the two SELECT statements are used to create
+      the UNION table.</p>
+<p>
+<pre class="programlisting">SELECT * FROM atable UNION CORRESPONDING BY (u, v) SELECT * FROM anothertable
+</pre>The type of each column of the query expression is determined
+      by combining the types of the corresponding columns from the two
+      participating tables.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N123B0"></a>Ordering</h3>
+</div>
+</div>
+</div>
+<p>When the rows of the result table have been formed, it is possible
+      to specify the order in which they are returned to the user. The ORDER
+      BY clause is used to specify the columns used for ordering, and whether
+      ascending or descending ordering is used. It can also specify whether
+      NULL values are returned first or last.</p>
+<pre class="programlisting">SELECT x + y AS xysum, y + z AS yzsum FROM atable AS t (u, v, w, x, y, z)  WHERE u + v = w ORDER BY xysum NULLS LAST, yzsum NULLS FIRST</pre>
+<p>The ORDER BY clause specifies one or more <code class="literal">&lt;value
+      expressions&gt;</code>. The list of rows is sorted according to the
+      first <code class="literal">&lt;value expression&gt;</code>. When some rows are
+      sorted equal then they are sorted according to the next
+      <code class="literal">&lt;value expression&gt;</code> and so on.</p>
+<p>
+<code class="literal">&lt;order by clause&gt; ::= ORDER BY &lt;sort
+      specification&gt; [ { &lt;comma&gt; &lt;sort specification&gt; }...
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;sort specification&gt; ::= &lt;value expression&gt; [
+      ASC | DESC ] [ NULLS FIRST | NULLS LAST ]</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N123C8"></a>Slicing</h3>
+</div>
+</div>
+</div>
+<p>A different form of limiting the rows can be performed on the
+      result table after it has been formed according to all the other
+      operations (selection, grouping, ordering etc.). This is specified by
+      the FETCH ... ROWS and OFFSET clauses of a SELECT statement. In this
+      form, the specified OFFSET rows are removed from start of the table,
+      then up to the specified FETCH rows are kept and the rest of the rows
+      are discarded.</p>
+<p>
+<code class="literal">&lt;result offset clause&gt; ::= OFFSET &lt;offset row
+      count&gt; { ROW | ROWS } </code>
+</p>
+<p>
+<code class="literal">&lt;fetch first clause&gt; ::= FETCH { FIRST | NEXT } [
+      &lt;fetch first row count&gt; ] { ROW | ROWS } ONLY</code>
+</p>
+<p>
+<code class="literal">&lt;limit clause&gt; ::= LIMIT [ &lt;fetch first row
+      count&gt; ]</code>
+</p>
+<p>A slicing operation takes the result set that has been already
+      processed and ordered. It then discards the specified number of rows
+      from the start of the result set and returns the specified number of
+      rows after the discarded rows.</p>
+<pre class="programlisting">SELECT a, b FROM atable WHERE d &lt; 5 ORDER BY absum OFFSET 3 FETCH 2 ROWS ONLY 
+SELECT a, b FROM atable WHERE d &lt; 5 ORDER BY absum OFFSET 3 LIMIT 2 /* alternative keyword */ </pre>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N123DA"></a>Data Change Statements</h2>
+</div>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N123DD"></a>Delete Statement</h3>
+</div>
+</div>
+</div>
+<a name="N123E0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DELETE FROM</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>delete statement: searched</em></span>
+</p>
+<p>
+<code class="literal">&lt;delete statement: searched&gt; ::= DELETE FROM
+      &lt;target table&gt; [ [ AS ] &lt;correlation name&gt; ] [ WHERE
+      &lt;search condition&gt; ]</code>
+</p>
+<p>Delete rows of a table. The search condition is a
+      <code class="literal">&lt;boolean value expression&gt;</code> that is evaluated
+      for each row of the table. If the condition is true, the row is deleted.
+      If the condition is not specified, all the rows of the table are
+      deleted. In fact, an implicit SELECT is performed in the form of
+      <code class="literal">SELECT * FROM &lt;target table&gt; [ WHERE &lt;search
+      condition&gt;]</code> and the selected rows are deleted. When used in
+      JDBC, the number of rows returned by the implicit SELECT is returned as
+      the update count.</p>
+<p>If there are FOREIGN KEY constraints on other tables that
+      reference the subject table, and the FOREIGN KEY constraints have
+      referential actions, then rows from those other tables that reference
+      the deleted rows are either deleted, or updated, according to the
+      specified referential actions.</p>
+<p>In the second example below the rows that have the maximum
+      value for column A are deleted;</p>
+<pre class="programlisting">DELETE FROM T WHERE C &gt; 5
+DELETE FROM T AS TT WHERE TT.A = (SELECT MAX(A) FROM T)
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N123FD"></a>Truncate Statement</h3>
+</div>
+</div>
+</div>
+<a name="N12400" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRUNCATE TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>truncate table statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;truncate table statement&gt; ::= TRUNCATE TABLE
+      &lt;target table&gt; [ &lt;identity column restart option&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;identity column restart option&gt; ::= CONTINUE
+      IDENTITY | RESTART IDENTITY</code>
+</p>
+<p>Delete all rows of a table without firing its triggers. This
+      statement can only be used on base tables (not views). If the table is
+      referenced in a FOREIGN KEY constraint, the statement causes an
+      exception. Triggers defined on the table are not executed with this
+      statement. The default for <code class="literal">&lt;identity column restart
+      option&gt;</code> is <code class="literal">CONTINUE IDENTITY</code>. This means
+      no change to the IDENTITY sequence of the table. If <code class="literal">RESTART
+      IDENTITY</code> is specified, then the sequence is reset to its start
+      value.</p>
+<p>TRUNCATE is faster than ordinary DELETE. The TRUNCATE statement
+      is an SQL Standard data change statement, therefore it is performed
+      under transaction control and can be rolled back if the connection is
+      not in the auto-commit mode.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1241F"></a>Insert Statement</h3>
+</div>
+</div>
+</div>
+<a name="N12422" class="indexterm"></a>
+<p>
+<span class="bold"><strong>INSERT INTO</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>insert statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;insert statement&gt; ::= INSERT INTO &lt;target
+      table&gt; &lt;insert columns and source&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;insert columns and source&gt; ::= &lt;from
+      subquery&gt; | &lt;from constructor&gt; | &lt;from
+      default&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;from subquery&gt; ::= [ &lt;left paren&gt;
+      &lt;insert column list&gt; &lt;right paren&gt; ] [ &lt;override
+      clause&gt; ] &lt;query expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;from constructor&gt; ::= [ &lt;left paren&gt;
+      &lt;insert column list&gt; &lt;right paren&gt; ] [ &lt;override
+      clause&gt; ] &lt;contextually typed table value
+      constructor&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;override clause&gt; ::= OVERRIDING USER VALUE |
+      OVERRIDING SYSTEM VALUE</code>
+</p>
+<p>
+<code class="literal">&lt;from default&gt; ::= DEFAULT
+      VALUES</code>
+</p>
+<p>
+<code class="literal">&lt;insert column list&gt; ::= &lt;column name
+      list&gt;</code>
+</p>
+<p>Insert new rows in a table. An INSERT statement inserts one or
+      more rows into the table.</p>
+<p>The special form, <code class="literal">INSERT INTO &lt;target table&gt;
+      DEFAULT VALUES</code> can be used with tables which have a default
+      value for each column.</p>
+<p>With the other forms of INSERT, the optional
+      <code class="literal">(&lt;insert column list&gt;)</code> specifies to which
+      columns of the table the new values are assigned.</p>
+<p>In one form, the inserted values are from a <code class="literal">&lt;query
+      expression&gt;</code> and all the rows that are returned by the
+      <code class="literal">&lt;query expression&gt;</code> are inserted into the table.
+      If the <code class="literal">&lt;query expression&gt;</code> returns no rows,
+      nothing is inserted.</p>
+<p>In the other form, a comma separated list of values called
+      <code class="literal">&lt;contextually typed table value constructor&gt;</code> is
+      used to insert one or more rows into the table. This list is
+      contextually typed, because the keywords NULL and DEFAULT can be used
+      for the values that are assigned to each column of the table. The
+      keyword DEFAULT means the default value of the column and can be used
+      only if the target column has a default value or is an IDENTITY or
+      GENERATED column of the table.</p>
+<p>The <code class="literal">&lt;override clause&gt;</code> must be used
+      when a value is explicitly assigned to a column that has been defined as
+      GENERATED ALWAYS AS IDENTITY. The clause, OVERRIDE SYSTEM VALUE means
+      the provided values are used for the insert, while OVERRIDING USER VALUE
+      means the provided values are simply ignored and the values generated by
+      the system are used instead.</p>
+<p>An array can be inserted into a column of the array type by
+      using literals, by specifying a parameter in a prepared statement or an
+      existing array returned by query expression. The last example below
+      inserts an array.</p>
+<p>The rows that are inserted into the table are checked against
+      all the constraints that have been declared on the table. The whole
+      INSERT operation fails if any row fails to inserted due to constraint
+      violation. Examples:</p>
+<pre class="programlisting">INSERT INTO T DEFAULT VALUES /* all columns of T have DEFAULT clauses */
+INSERT INTO T (SELECT * FROM Z) /* table Z has the same columns as table T */
+INSERT INTO T (A,B) VALUES ((1,2),(3,NULL), (DEFAULT,6)) /* three rows are inserted into table T */
+INSERT INTO T VALUES 3, ARRAY['hot','cold']
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1246A"></a>Update Statement</h3>
+</div>
+</div>
+</div>
+<a name="N1246D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UPDATE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>update statement: searched</em></span>
+</p>
+<p>
+<code class="literal">&lt;update statement: searched&gt; ::= UPDATE
+      &lt;target table&gt; [ [ AS ] &lt;correlation name&gt; ] SET &lt;set
+      clause list&gt; [ WHERE &lt;search condition&gt; ]</code>
+</p>
+<p>Update rows of a table. An UPDATE statement selects rows from
+      the <code class="literal">&lt;target table&gt;</code> using an implicit SELECT
+      statement formed in the following manner:</p>
+<p>
+<code class="literal">SELECT * FROM &lt;target table&gt; [ [ AS ]
+      &lt;correlation name&gt; ] [ WHERE &lt;search condition&gt;
+      ]</code>
+</p>
+<p>Then it applies the <code class="literal">SET &lt;set clause
+      list&gt;</code> expression to each selected row.</p>
+<p>If the implicit SELECT returns no rows, no update takes place.
+      When used in JDBC, the number of rows returned by the implicit SELECT is
+      returned as the update count.</p>
+<p>If there are FOREIGN KEY constraints on other tables that
+      reference the subject table, and the FOREIGN KEY constraints have
+      referential actions, then rows from those other tables that reference
+      the updated rows are updated, according to the specified referential
+      actions.</p>
+<p>The rows that are updated are checked against all the
+      constraints that have been declared on the table. The whole UPDATE
+      operation fails if any row violates any constraint.</p>
+<a name="N1248F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>set clause list</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set clause list</em></span>
+</p>
+<p>
+<code class="literal">&lt;set clause list&gt; ::= &lt;set clause&gt; [ {
+      &lt;comma&gt; &lt;set clause&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;set clause&gt; ::= &lt;multiple column
+      assignment&gt; | &lt;set target&gt; &lt;equals operator&gt; &lt;update
+      source&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;multiple column assignment&gt; ::= &lt;set target
+      list&gt; &lt;equals operator&gt; &lt;assigned
+      row&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;set target list&gt; ::= &lt;left paren&gt; &lt;set
+      target&gt; [ { &lt;comma&gt; &lt;set target&gt; }... ] &lt;right
+      paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;assigned row&gt; ::= &lt;contextually typed row
+      value expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;set target&gt; ::= &lt;column
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;update source&gt; ::= &lt;value expression&gt; |
+      &lt;contextually typed value specification&gt;</code>
+</p>
+<p>Specify a list of assignments. This is used in UPDATE, MERGE
+      and SET statements to assign values to a scalar or row target.</p>
+<p>Apart from setting a whole target to a value, a SET statement
+      can set individual elements of an array to new values. The last example
+      below shows this form of assignment to the array in the column named
+      B.</p>
+<p>In the examples given below, UPDATE statements with single and
+      multiple assignments are shown. Note in the third example, a SELECT
+      statement is used to provide the update values for columns A and C,
+      while the update value for column B is given separately. The SELECT
+      statement must return exactly one row . In this example the SELECT
+      statement refers to the existing value for column C in its search
+      condition.</p>
+<pre class="programlisting">UPDATE T SET A = 5 WHERE ...
+UPDATE T SET (A, B) = (1, NULL) WHERE ...
+UPDATE T SET (A, C) = (SELECT X, Y FROM U WHERE Z = C), B = 10 WHERE ...
+UPDATE T SET A = 3, B[3] = 'warm'
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N124B8"></a>Merge Statement</h3>
+</div>
+</div>
+</div>
+<a name="N124BB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MERGE INTO</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>merge statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;merge statement&gt; ::= MERGE INTO &lt;target
+      table&gt; [ [ AS ] &lt;merge correlation name&gt; ] USING &lt;table
+      reference&gt; ON &lt;search condition&gt; &lt;merge operation
+      specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge correlation name&gt; ::= &lt;correlation
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge operation specification&gt; ::= &lt;merge
+      when clause&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;merge when clause&gt; ::= &lt;merge when matched
+      clause&gt; | &lt;merge when not matched clause&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge when matched clause&gt; ::= WHEN MATCHED
+      THEN &lt;merge update specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge when not matched clause&gt; ::= WHEN NOT
+      MATCHED THEN &lt;merge insert specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge update specification&gt; ::= UPDATE SET
+      &lt;set clause list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge insert specification&gt; ::= INSERT [
+      &lt;left paren&gt; &lt;insert column list&gt; &lt;right paren&gt; ] [
+      &lt;override clause&gt; ] VALUES &lt;merge insert value
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge insert value list&gt; ::= &lt;left paren&gt;
+      &lt;merge insert value element&gt; [ { &lt;comma&gt; &lt;merge insert
+      value element&gt; }... ] &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge insert value element&gt; ::= &lt;value
+      expression&gt; | &lt;contextually typed value
+      specification&gt;</code>
+</p>
+<p>Update rows, or insert new rows into the <code class="literal">&lt;target
+      table&gt;</code>. The MERGE statement uses a second table, specified
+      by <code class="literal">&lt;table reference&gt;</code>, to determine the rows to
+      be updated or inserted. It is possible to use the statement only to
+      update rows or to insert rows, but usually both update and insert are
+      specified.</p>
+<p>The <code class="literal">&lt;search condition&gt;</code> matches each
+      row of the <code class="literal">&lt;table reference&gt;</code> with each row of
+      the <code class="literal">&lt;target table&gt;</code>. If the two rows match then
+      the UPDATE clause is used to update the matching row of the target
+      table. Those rows of <code class="literal">&lt;table reference&gt;</code> that
+      have no matching rows are then used to insert new rows into the
+      <code class="literal">&lt;target table&gt;</code>. Therefore, a MERGE statement
+      can update between 0 and all the rows of the <code class="literal">&lt;target
+      table&gt;</code> and can insert between 0 and the number of the rows
+      in <code class="literal">&lt;table reference&gt;</code> into the
+      <code class="literal">&lt;target table&gt;</code>. If any row in the
+      <code class="literal">&lt;target table&gt;</code> matches more than one row in
+      <code class="literal">&lt;table reference&gt;</code> a cardinality error is
+      raised. On the other hand, several rows in the <code class="literal">&lt;target
+      table&gt;</code> can matches a single row in <code class="literal">&lt;table
+      reference&gt;</code> without any error. The constraints and
+      referential actions specified on the database tables are enforced the
+      same way as for an update and an insert statement.</p>
+<p>The MERGE statement can be used with only the WHEN NOT MATCHED
+      clause as a conditional INSERT statement that inserts a row if no
+      existing rows match a condition.</p>
+<p>In the first example below, the table originally contains two
+      rows for different furniture. The <code class="literal">&lt;table
+      reference&gt;</code> is the <code class="literal">(VALUES(1, 'conference table'),
+      (14, 'sofa'), (5, 'coffee table'))</code> expression, which evaluates
+      to a table with 3 rows. When the x value for a row matches an existing
+      row, then the existing row is updated. When the x value does not match,
+      the row is inserted. Therefore one row of table t is updated from
+      'dining table' to 'conference table', and two rows are inserted into
+      table t. The second example uses a SELECT statement as the source of the
+      values for the MERGE.</p>
+<p>In the third example, a new row in inserted into the table only
+      when the primary key for the new row does not exist. This example uses
+      parameters and should be executed as a JDBC PreparedStatement.</p>
+<pre class="programlisting">CREATE TABLE t (id INT PRIMARY KEY, description VARCHAR(100))
+INSERT INTO t VALUES (1, 'dining table'), (2, 'deck chair')
+MERGE INTO t USING (VALUES(1, 'conference table'), (14, 'sofa'), (5, 'coffee table')) 
+   AS vals(x,y) ON t.id = vals.x
+   WHEN MATCHED THEN UPDATE SET t.description = vals.y
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, vals.y
+
+MERGE INTO t USING (SELECT * FROM tt WHERE acol = 2) AS vals(x,y) ON t.id = vals.x
+   WHEN MATCHED THEN UPDATE SET t.description = vals.y
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, vals.y
+
+MERGE INTO t USING (VALUES(CAST(? AS INT))) AS vals(x) ON t.id = vals.x
+   WHEN NOT MATCHED THEN INSERT VALUES vals.x, ?
+</pre>
+</div>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sqlroutines-chapt"></a>Chapter&nbsp;8.&nbsp;SQL-Invoked Routines</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3643 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N12545"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-06 23:04:17 -0400 (Sun, 06 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N1257C">SQL Language Routines (PSM)</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N12597">Routine Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N125DC">Compound Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N125EE">Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12604">Handlers</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12632">Assignment Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12648">Select Statement : Single Row</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12663">Formal Parameters</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1267E">Iterated Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12699">Conditional Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N126E2">Return Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N126FD">Control Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1271F">Routine Polymorphism</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1272E">Returning Data From Routines</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N12748">Java Language Routines (SQL/JRT)</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N127C5">Polymorphism</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N127D2">Java Language Procedures</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N127EB">Legacy Support</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N127FB">SQL Language Aggregate Functions</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N12802">Definition of Aggregate Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12828">SQL PSM Aggregate Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1283E">Java Aggregate Functions</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N12854">Routine Definition</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N1291D">Routine Characteristics</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</div>
+<p>SQL-invoked routines are functions and procedures called from SQL.
+  HyperSQL 2.0 supports routines conforming to two parts of the SQL Standard.
+  Routines written in the SQL language are supported in conformance to SQL/PSM
+  (Persistent Stored Modules) specification. Routines written in Java are
+  supported in (loose) conformance to SQL/JRT specification. In addition,
+  HyperSQL&rsquo;s previous non-standard support for calling Java routines without
+  prior method definition is retained and enhanced in the latest version by
+  extending the SQL/JRT specification.</p>
+<p>HyperSQL also supports user defined aggregate functions written in the
+  SQL language. This feature is an extension to the SQL Standard.</p>
+<p>SQL-invoked routines are schema objects. Naming and referencing
+  follows conventions common to all schema objects. The same routine name can
+  be defined in two different schemas and used with schema-qualified
+  references.</p>
+<p>A routine is either a procedure or a function.</p>
+<p>A function:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>is defined with CREATE FUNCTION</p>
+</li>
+<li>
+<p>always returns a value</p>
+</li>
+<li>
+<p>does not modify the data in the database</p>
+</li>
+<li>
+<p>is called as part of an SQL statement</p>
+</li>
+<li>
+<p>can have parameters</p>
+</li>
+<li>
+<p>can be polymorphic</p>
+</li>
+</ul>
+</div>
+<p>A procedure:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>is defined with CREATE PROCEDURE</p>
+</li>
+<li>
+<p>can return one or more values</p>
+</li>
+<li>
+<p>can modify the data in the database</p>
+</li>
+<li>
+<p>is called separately, using the CALL statement</p>
+</li>
+<li>
+<p>can have parameters</p>
+</li>
+<li>
+<p>can be polymorphic</p>
+</li>
+</ul>
+</div>
+<p>Definition of routine signature and characteristics, name resolution
+  and invocation are all implemented uniformly for routines written in SQL or
+  Java.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1257C"></a>SQL Language Routines (PSM)</h2>
+</div>
+</div>
+</div>
+<p>The PSM (Persistent Stored Module) specification extends the SQL
+    language to allow definition of both SQL Function and SQL procedure bodies
+    with the same structure and the same control statements (such as
+    conditional and loop statements) with minor exceptions.</p>
+<p>The routine body is a SQL statement. In its simplest form, the body
+    is a single SQL statement. A simple example of a function is given
+    below:</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before (t TIMESTAMP)
+  RETURNS TIMESTAMP
+  RETURN t - 1 HOUR
+
+</pre>
+<p>An example of the use of the function in an SQL statement is given
+    below:</p>
+<pre class="programlisting">SELECT an_hour_before(event_timestamp) AS notification_timestamp, event_name FROM events;</pre>
+<p>A simple example of a procedure is given below:</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname VARCHAR(50))
+  MODIFIES SQL DATA
+  INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP)
+
+</pre>
+<p>The procedure inserts a row into an existing table with the
+    definition given below:</p>
+<pre class="programlisting">CREATE TABLE customers(id INTEGER GENERATED BY DEFAULT AS IDENTITY, firstname VARCHAR(50), lastname VARCHAR(50), added TIMESTAMP);</pre>
+<p>An example of the use of the procedure is given below:</p>
+<pre class="programlisting">CALL new_customer('JOHN', 'SMITH');</pre>
+<p>The routine body is often a compound statement. A compound statement
+    can contain one or more SQL statements, which can include control
+    statements, as well as nested compound statements.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12597"></a>Routine Statements</h3>
+</div>
+</div>
+</div>
+<p>The following SQL Statements can be used only in routines.</p>
+<p>
+<code class="literal">&lt;handler declaration&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;assignment statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;compound statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;case statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;if statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;while statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;repeat statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;for statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;loop statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;iterate statement</code>
+</p>
+<p>
+<code class="literal">&lt;leave statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;signal statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;resignal statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;return statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;select statement: single
+      row&gt;</code>
+</p>
+<p>The following SQL Statements can be used in procedures but not in
+      functions.</p>
+<p>
+<code class="literal">&lt;call statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;delete statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;insert statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;update statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge statement&gt;</code>
+</p>
+<p>As shown in the examples below, the formal parameters and the
+      variables of the routine can be used in statements, similar to the way a
+      column reference is used.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N125DC"></a>Compound Statement</h3>
+</div>
+</div>
+</div>
+<p>A compound statement is enclosed in a BEGIN / END block with
+      optional labels. It can contain one or more <code class="literal">&lt;SQL variable
+      declaration&gt;</code> or <code class="literal">&lt;handler
+      declaration&gt;</code> before at least one SQL statement. The BNF is
+      given below:</p>
+<p>
+<code class="literal">&lt;compound statement&gt; ::= [ &lt;beginning
+      label&gt; &lt;colon&gt; ] BEGIN [[NOT] ATOMIC] [{&lt;SQL variable
+      declaration&gt; &lt;semicolon&gt;} ...] [{&lt;handler declaration&gt;
+      &lt;semicolon&gt;}...] {&lt;SQL procedure statement&gt;
+      &lt;semicolon&gt;} ... END [ &lt;ending label&gt; ]</code>
+</p>
+<p>An example of a simple compound statement body is given below. It
+      performs the common task of inserting related data into two table. The
+      IDENTITY value that is automatically inserted in the first table is
+      retrieved using the IDENTITY() function and inserted into the second
+      table.</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname  VARCHAR(50), address VARCHAR(100))
+  MODIFIES SQL DATA
+    BEGIN ATOMIC
+    INSERT INTO customers VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    INSERT INTO addresses VALUES (DEFAULT, IDENTITY(), address);
+  END
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N125EE"></a>Variables</h3>
+</div>
+</div>
+</div>
+<p>A <code class="literal">&lt;variable declaration&gt;</code> defines the name
+      and data type of the variable and, optionally, its default value. In the
+      next example, a variable is used to hold the IDENTITY value. In
+      addition, the formal parameters of the procedure are identified as input
+      parameters with the use of the optional IN keyword. This procedure does
+      exactly the same job as the procedure in the previous example.</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+  MODIFIES SQL DATA
+  BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+  END
+
+</pre>
+<p>The BNF for variable declaration is given below:</p>
+<p>
+<code class="literal">&lt;SQL variable declaration&gt; ::= DECLARE
+      &lt;variable name list&gt; &lt;data type&gt; [DEFAULT &lt;default
+      value&gt;]</code>
+</p>
+<p>
+<code class="literal">&lt;variable name list&gt; ::= &lt;variable name&gt; [
+      { &lt;comma&gt; &lt;variable name&gt; }... ]</code>
+</p>
+<p>Examples of variable declaration are given below. Note that in a
+      DECLARE statement with multiple comma-separated variable names, the type
+      and the default value applies to all the variables in the list:</p>
+<pre class="programlisting">  BEGIN ATOMIC
+    DECLARE temp_zero DATE;
+    DECLARE temp_one, temp_two INTEGER DEFAULT 2;
+    DECLARE temp_three VARCHAR(20) DEFAULT 'no name';
+    -- more statements ...
+    SET temp_zero = DATE '2010-03-18';
+    SET temp_two = 5;
+    -- more statements ...
+  END</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12604"></a>Handlers</h3>
+</div>
+</div>
+</div>
+<p>A <code class="literal">&lt;handler declaration&gt;</code> defines the
+      course of action when an exception or warning is raised during the
+      execution of the compound statement. A compound statement may have one
+      or more handler declarations. These handlers become active when code
+      execution enters the compound statement block and remain active in any
+      sub-block and statement within the block. The handlers become inactive
+      when code execution leaves the block.</p>
+<p>In the previous example, if an exception is thrown during the
+      execution of either SQL statement, the execution of the compound
+      statement is terminated and the exception is propagated and thrown by
+      the CALL statement for the procedure. A handler declaration can resolve
+      the thrown exception within the compound statement without propagating
+      it, and allow the execution of the &lt;compound statement&gt; to
+      continue.</p>
+<p>In the example below, the UNDO handler declaration catches any
+      exception that is thrown during the execution of the compound statement
+      inside the BEGIN / END block. As it is an UNDO handler, all the changes
+      to data performed within the compound statement (BEGIN / END) block are
+      rolled back. The procedure then returns without throwing an
+      exception.</p>
+<pre class="programlisting">CREATE PROCEDURE NEW_CUSTOMER(IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+    MODIFIES SQL DATA
+  label_one: BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    DECLARE UNDO HANDLER FOR SQLEXCEPTION LEAVE label_one;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+  END
+
+</pre>
+<p>Other types of hander are CONTINUE and EXIT handlers. A CONTINUE
+      handler ignores any exception and proceeds to the next statement in the
+      block. An EXIT handler terminates execution without undoing the data
+      changes performed by the previous (successful) statements.</p>
+<p>The conditions can be general conditions, or specific conditions.
+      Among general conditions that can be specified, SQLEXCEPTION covers all
+      exceptions, SQLWARNING covers all warnings, while NOT FOUND covers the
+      not-found condition, which is raised when a DELETE, UPDATE, INSERT or
+      MERGE statement completes without actually affecting any row.
+      Alternatively, one or more specific conditions can be specified
+      (separated with commas) which apply to specific exceptions or warnings
+      or classes or exceptions or warnings. A specific condition is specified
+      with <code class="literal">SQLSTATE &lt;value&gt;</code>, for example SQLSTATE
+      'W_01003' specifies the warning raised after a SQL statement is executed
+      which contains an aggregate function which encounters a null value
+      during execution. An example is given below which activates the handler
+      when either of the two warnings is raised:</p>
+<pre class="programlisting">DECLARE UNDO HANDLER FOR SQLSTATE 'W_01003', 'W_01004' LEAVE label_one;</pre>
+<p>The BNF for <code class="literal">&lt;handler declaration&gt;</code> is
+      given below:</p>
+<p>
+<code class="literal">&lt;handler declaration&gt; ::= DECLARE {UNDO |
+      CONTINUE | EXIT} HANDLER FOR {SQLEXCEPTION | SQLWARNING | NOT FOUND} | {
+      SQL_STATE &lt;state value&gt; [, ...]} [&lt;SQL procedure
+      statement&gt;];</code>
+</p>
+<p>A handler declaration may specify an SQL procedure statement to be
+      performed when the handler is activated. When an exception occurs, the
+      example below performs the UNDO as in the previous example, then inserts
+      the (invalid) data into a separate table.</p>
+<pre class="programlisting">DECLARE UNDO HANDLER FOR SQLEXCEPTION
+    INSERT INTO invalid_customers VALUES(firstanme, lastname, address);</pre>
+<p>The <code class="literal">&lt;SQL procedure statement&gt;</code> is required
+      by the SQL Standard but is optional in HyperSQL. If the execution of the
+      <code class="literal">&lt;SQL procedure statement&gt;</code> specified in the
+      handler declaration throws an exception itself, then it is handled by
+      the handlers that are currently active. The <code class="literal">&lt;SQL procedure
+      statement&gt;</code> can itself be a compound statement with its own
+      handlers.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12632"></a>Assignment Statement</h3>
+</div>
+</div>
+</div>
+<p>The SET statement is used for assignment. It can be used flexibly
+      with rows or single values. The BNF is given below:</p>
+<p>
+<code class="literal">&lt;assignment statement&gt; ::= &lt;singleton
+      variable assignment&gt; | &lt;multiple variable
+      assignment&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;singleton variable assignment&gt; ::= SET
+      &lt;assignment target&gt; &lt;equals operator&gt; &lt;assignment
+      source&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;multiple variable assignment&gt; ::= SET
+      (&lt;variable or parameter&gt;, ...) = &lt;row value
+      expression&gt;</code>
+</p>
+<p>In the example below, the result of the SELECT is assigned to two
+      OUT or INOUT arguments. The SELECT must return one row. If it returns
+      more than one, an exception is raised. If it returns no row, no change
+      is made to ARG1 and ARG2.</p>
+<pre class="programlisting">SET (arg1, arg2) = (SELECT col1, col2 FROM atable WHERE id = 10);</pre>
+<p>In the example below, the result of a function call is assigned to
+      VAR1.</p>
+<pre class="programlisting">SET var1 = SQRT(var2);</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12648"></a>Select Statement : Single Row</h3>
+</div>
+</div>
+</div>
+<p>A special form of SELECT can also be used for assigning values
+      from a query to one or more arguments or variables. This works similar
+      to a SET statement that has a SELECT statement as the source.</p>
+<a name="N1264D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SELECT : SINGLE ROW</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>select statement: single row</em></span>
+</p>
+<p>
+<code class="literal">&lt;select statement: single row&gt; ::= SELECT [
+      &lt;set quantifier&gt; ] &lt;select list&gt; INTO &lt;select target
+      list&gt; &lt;table expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;select target list&gt; ::= &lt;target
+      specification&gt; [ { &lt;comma&gt; &lt;target specification&gt; }...
+      ]</code>
+</p>
+<p>Retrieve values from a specified row of a table and assign the
+      fields to the specified targets. The example below has an identical
+      effect to the example of SET statement given above.</p>
+<pre class="programlisting">SELECT col1, col2 INTO arg1, arg2 FROM atable WHERE id = 10;</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12663"></a>Formal Parameters</h3>
+</div>
+</div>
+</div>
+<p>Each parameter of a procedure can be defined as IN, OUT or INOUT.
+      An IN parameter is an input to the procedure and is passed by value. The
+      value cannot be modified inside the procedure body. An OUT parameter is
+      a reference for output. An INOUT parameter is a reference for both input
+      and output. An OUT or INOUT parameter argument is passed by reference,
+      therefore only a dynamic parameter argument or a variable within an
+      enclosing procedure can be passed for it. The assignment statement is
+      used to assign a value to an OUT or INOUT parameter.</p>
+<p>In the example below, the procedure is declared with an OUT
+      parameter.</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(OUT newid INT, IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+  MODIFIES SQL DATA
+  BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+    SET newid = temp_id;
+  END
+
+</pre>
+<p>In the SQL session, or in the body of another stored procedure, a
+      variable must be assigned to the OUT parameter. After the procedure
+      call, this variable will hold the new identity value that was generated
+      inside the procedure.</p>
+<p>In the example below, a session variable,
+      <code class="literal">the_new_id</code> is declared. After the call to
+      <code class="literal">new_customer</code>, the value for the identity is stored in
+      <code class="literal">the_new_id</code> variable. This is returned via the next
+      CALL statement. Alternatively, <code class="literal">the_new_id</code> can be used
+      as an argument to another CALL statement.</p>
+<pre class="programlisting">DECLARE the_new_id INT DEFAULT NULL;
+CALL new_customer(the_new_id, 'John', 'Smith', '10 Parliament Square'); 
+CALL the_new_id;
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1267E"></a>Iterated Statements</h3>
+</div>
+</div>
+</div>
+<p>Various iterated statements can be used in routines. In these
+      statements, the <code class="literal">&lt;SQL statement list&gt;</code> consists
+      of one or more SQL statements. The <code class="literal">&lt;search
+      condition&gt;</code> can be any valid SQL expression of BOOLEAN
+      type.</p>
+<p>
+<code class="literal">&lt;loop statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ] LOOP &lt;SQL statement list&gt; END LOOP [ &lt;ending
+      label&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;while statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ] WHILE &lt;search condition&gt; DO &lt;SQL statement
+      list&gt; END WHILE [ &lt;ending label&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;repeat statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ]</code>
+</p>
+<p>
+<code class="literal">REPEAT &lt;SQL statement list&gt; UNTIL &lt;search
+      condition&gt; END REPEAT [ &lt;ending label&gt;</code>
+</p>
+<p>In the example below, a multiple rows are inserted into a table in
+      a WHILE loop:</p>
+<pre class="programlisting">loop_label: WHILE my_var &gt; 0 DO
+  INSERT INTO CUSTOMERS VALUES (DEFAULT, my_var);
+  SET my_var = my_var - 1;
+  IF my_var = 10 THEN SET my_var = 8; END IF;
+  IF my_var = 22 THEN LEAVE loop_label; END IF;
+END WHILE loop_label;
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12699"></a>Conditional Statements</h3>
+</div>
+</div>
+</div>
+<p>There are two types of CASE ... WHEN statement and the IF ... THEN
+      statement.</p>
+<a name="N1269E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CASE WHEN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>case when statement</em></span>
+</p>
+<p>The simple case statement uses a <code class="literal">&lt;case
+      operand&gt;</code> as the predicand of one or more predicates. For
+      the right part of each predicate, it specifies one or more SQL
+      statements to execute if the predicate evaluates TRUE. If the ELSE
+      clause is not specified, at least one of the search conditions must be
+      true, otherwise an exception is raised.</p>
+<p>
+<code class="literal">&lt;simple case statement&gt; ::= CASE &lt;case
+      operand&gt; &lt;simple case statement when clause&gt;... [ &lt;case
+      statement else clause&gt; ] END CASE</code>
+</p>
+<p>
+<code class="literal">&lt;simple case statement when clause&gt; ::= WHEN
+      &lt;when operand list&gt; THEN &lt;SQL statement
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;case statement else clause&gt; ::= ELSE &lt;SQL
+      statement list&gt;</code>
+</p>
+<p>A skeletal example is given below. The variable var_one is first
+      tested for equality with 22 or 23 and if the test evaluates to TRUE,
+      then the INSERT statement is performed and the statement ends. If the
+      test does not evaluate to TRUE, the next condition test, which is an IN
+      predicate, is performed with var_one and so on. The statement after the
+      ELSE clause is performed if none the previous tests returns TRUE.</p>
+<pre class="programlisting">CASE var_one
+  WHEN 22, 23 THEN INSERT INTO t_one ...;
+  WHEN IN (2, 4, 5) THEN DELETE FROM t_one WHERE ...;
+  ELSE UPDATE t_one ...;
+  END CASE
+
+</pre>
+<p>The searched case statement uses one or more search conditions,
+      and for each search condition, it specifies one or more SQL statements
+      to execute if the search condition evaluates TRUE. An exception is
+      raised if there is no ELSE clause and none of the search conditions
+      evaluates TRUE.</p>
+<p>
+<code class="literal">&lt;searched case statement&gt; ::= CASE &lt;searched
+      case statement when clause&gt;... [ &lt;case statement else clause&gt; ]
+      END CASE</code>
+</p>
+<p>
+<code class="literal">&lt;searched case statement when clause&gt; ::= WHEN
+      &lt;search condition&gt; THEN &lt;SQL statement
+      list&gt;</code>
+</p>
+<p>The example below is partly a rewrite of the previous example, but
+      a new condition is added:</p>
+<pre class="programlisting">CASE WHEN var_one = 22 OR var_one = 23 THEN INSERT INTO t_one ...;
+  WHEN var_one IN (2, 4, 5) THEN DELETE FROM t_one WHERE ...;
+  WHEN var_two IS NULL THEN UPDATE t_one ...;
+  ELSE UPDATE t_one ...;
+  END CASE
+
+</pre>
+<a name="N126C8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IF</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>if statement</em></span>
+</p>
+<p>The if statement is very similar to the searched case statement.
+      The difference is that no exception is raised if there is no ELSE clause
+      and no search condition evaluates TRUE.</p>
+<p>
+<code class="literal">&lt;if statement&gt; ::= IF &lt;search condition&gt;
+      &lt;if statement then clause&gt; [ &lt;if statement elseif clause&gt;...
+      ] [ &lt;if statement else clause&gt; ] END IF</code>
+</p>
+<p>
+<code class="literal">&lt;if statement then clause&gt; ::= THEN &lt;SQL
+      statement list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;if statement elseif clause&gt; ::= ELSEIF
+      &lt;search condition&gt; THEN &lt;SQL statement
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;if statement else clause&gt; ::= ELSE &lt;SQL
+      statement list&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N126E2"></a>Return Statement</h3>
+</div>
+</div>
+</div>
+<p>The RETURN statement is required and used only in functions. The
+      body of a function is either a RETURN statement, or a compound statement
+      that contains a RETURN statement.</p>
+<a name="N126E7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RETURN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>return statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;return statement&gt; ::= RETURN &lt;return
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;return value&gt; ::= &lt;value expression&gt; |
+      NULL</code>
+</p>
+<p>Return a value from an SQL function. If the function is defined
+      as RETURNS TABLE, then the value is a TABLE expression such as RETURN
+      TABLE(SELECT ...) otherwise, the value expression can be any scalar
+      expression. In the examples below, the same function is written with or
+      without a BEGIN END block. In both versions, the RETURN value is a
+      scalar expression.</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP
+  RETURN (SELECT MAX(event_time) FROM atable WHERE event_type = e_type) - 1 HOUR
+
+CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP
+  BEGIN ATOMIC
+    DECLAR max_event TIMESTAMP;
+    SET max_event = SELECT MAX(event_time) FROM atable WHERE event_type = e_type;
+    RETURN max_event - 1 HOUR;
+  END
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N126FD"></a>Control Statements</h3>
+</div>
+</div>
+</div>
+<p>In addition to the RETURN statement, the following statements can
+      be used in specific contexts.</p>
+<p>ITERATE STATEMENT</p>
+<p>The ITERATE statement can be used to cause the next iteration of a
+      labeled iterated statement (a WHILE, REPEAT or LOOP statement). It is
+      similar to the "continue" statement in C and Java.</p>
+<p>
+<code class="literal">&lt;iterate statement&gt; ::= ITERATE &lt;statement
+      label&gt;</code>
+</p>
+<p>LEAVE STATEMENT</p>
+<p>The LEAVE statement can be used to leave a labeled block. When
+      used in an iterated statement, it is similar to the "break" statement is
+      C and Java. But it can be used in compound statements as well.</p>
+<p>
+<code class="literal">&lt;leave statement&gt; ::= LEAVE &lt;statement
+      label&gt;</code>
+</p>
+<p>Signal and Resignal Statements</p>
+<p>The SIGNAL statement is used to throw an exception (or force an
+      exception). When invoked, any exception handler for the given exception
+      is in turn invoked. If there is no handler, the exception is propagated
+      to the enclosing context.</p>
+<p>
+<code class="literal">&lt;signal statement&gt; ::= SIGNAL SQL_STATE
+      &lt;state value&gt;</code>
+</p>
+<p>The RESIGNAL statement is used to throw an exception from an
+      exception handler&rsquo;s <code class="literal">&lt;SQL procedure statement&gt;</code>,
+      in effect propagating the exception to the enclosing context without
+      further action by the currently active handlers.</p>
+<p>
+<code class="literal">&lt;resignal statement&gt; ::= RESIGNAL SQL_STATE
+      &lt;state value&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1271F"></a>Routine Polymorphism</h3>
+</div>
+</div>
+</div>
+<p>More than one version of a routine can be created.</p>
+<p>For procedures, the different versions must have different
+      parameter counts. &nbsp;When the procedure is called, the parameter count
+      determines which version is called.</p>
+<p>For functions, the different versions can have the same or
+      different parameter counts. When the parameter count of two versions of
+      a function is the same, the type of parameters must be different. The
+      best matching version of the function is called, according to both the
+      parameter count and parameter types.</p>
+<p>Two versions of an overloaded function are given below. One
+      version accepts TIMESTAMP while the other accepts TIME arguments.</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  IF t &gt; CURRENT_TIMESTAMP THEN
+    RETURN CURRENT_TIMESTAMP;
+  ELSE
+    RETURN t - 1 HOUR;
+  END IF
+
+CREATE FUNCTION an_hour_before_or_now(t TIME)
+  RETURNS TIME
+  CASE t
+    WHEN &gt; CURRENT_TIME THEN
+      RETURN CURRENT_TIME;
+    WHEN &gt;= TIME'01:00:00' THEN
+      RETURN t - 1 HOUR;
+    ELSE
+      RETURN CURRENT_TIME;
+  END CASE
+
+</pre>
+<p>more ..</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1272E"></a>Returning Data From Routines</h3>
+</div>
+</div>
+</div>
+<p>The OUT or INOUT parameters of a procedure are used to assign
+      simple values to dynamic parameters or to variables in the calling
+      context. In addition, a SQL/PSM procedure may return result sets to the
+      calling context. These result sets are dynamic in the sense that a
+      procedure may return a different number of result sets or none at all in
+      different invocations.</p>
+<p>The SQL Standard uses a mechanism called CURSORS for accessing and
+      modifying rows of a result set one by one. This mechanism is absolutely
+      necessary when the database is accessed from an external application
+      program. The JDBC ResultSet interface allows this method of access from
+      Java programs and is supported by HyperSQL.</p>
+<p>The SQL Standard uses cursors within the body of a procedure to
+      return result sets. It specifies a somewhat complex mechanism to allow
+      access to these cursors from the calling contexts. HyperSQL does not
+      support access to such result sets within a calling SQL/PSM procedure.
+      This is considered redundant as all operations on data can be performed
+      with non-cursor SQL statements.</p>
+<p>(feature to be implemented) HyperSQL will support returning single
+      or multiple result sets from SQL/PSM procedures only via the JDBC
+      CallableStatement interface. Cursors are declared and opened within the
+      body of the procedure. No further operation is performed on the cursors
+      within the procedure. When the execution of the procedure is complete,
+      the cursors become available as Java ResultSet objects via the
+      CallableStatement instance that called the SQL/PSM procedure.</p>
+<p>Currently, a single result can be returned from FUNCTION routines,
+      when the function is defined as RETURNS TABLE ( .. )</p>
+<p>To return a table from a SELECT statement, you should use a return
+      statement such as RETURN TABLE( SELECT ...); in a SQL/PSM function. A
+      Java function should return a JDBCResultSet instance. For an example of
+      how to construct a JDBCResultSet for this purpose, see the source code
+      for the org.hsqldb.jdbc.JDBCArray class.</p>
+<p>The JDBC CallableStatement class is used with the SQL statement
+      <code class="literal">CALL &lt;routine name&gt; ( &lt;argument 1&gt;, ... )</code>
+      to call both functions and procedures. The <code class="literal">getXXX()</code>
+      methods can be used to retrieve INOUT or OUT arguments after the call.
+      The <code class="literal">getResultSet()</code> call can be used to access the
+      ResultSet returned from a function that returns a result set.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12748"></a>Java Language Routines (SQL/JRT)</h2>
+</div>
+</div>
+</div>
+<p>The body of a Java language routine is a static method of a Java
+    class, specified with a fully qualified method name in the routine
+    definition.</p>
+<p>In the example below, the static method named
+    <code class="methodname">toZeroPaddedString</code> is specified to be called when
+    the function is invoked.</p>
+<pre class="programlisting">CREATE FUNCTION zero_pad(x BIGINT, digits INT, maxsize INT)
+  RETURNS CHAR VARYING(100)
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME
+  'CLASSPATH:org.hsqldb.lib.StringUtil.toZeroPaddedString'
+
+</pre>
+<p>The signature of the Java method (used in the Java code but not in
+    SQL code to create the function) is given below:</p>
+<pre class="programlisting">public static String toZeroPaddedString(long value, int precision, int maxSize)</pre>
+<p>The parameter and return types and of the SQL routine definition
+    must match those of the Java method according to the table below:</p>
+<div class="informaltable">
+<table cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>SMALLINT &nbsp; </p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>Short or Short</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>INT</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>int or Integer</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>BIGINT</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>long or Long</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>NUMERIC &nbsp;or DECIMAL</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>BigDecimal</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>FLOAT &nbsp;or DOUBLE</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>Double or Double</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>CHAR or VARCHAR</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>String</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>DATE</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>java.sql.Date</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>TIME</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>java.sql.Time</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>TIMESTAMP</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>java.sql.Timestamp</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>BINARY</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>Byte[]</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>BOOLEAN</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>boolean or Boolean</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">ARRAY of any type</td><td style="border-bottom: 0.5pt solid ; ">java.sql.Array</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; ">
+<p>TABLE</p>
+</td><td style="">
+<p>java.sql.ResultSet</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>If the specified Java method is not found or its parameters and
+    return types do not match the definition, an exception is raised. If more
+    than one version of the Java method exist, then the one with matching
+    parameter and return types is found and registered. If two &ldquo;equivalent&rdquo;
+    methods exist, the first one is registered. (This situation arises only
+    when a parameter is a primitive in one version and an Object in another
+    version, e.g. <code class="classname">long</code> and
+    <code class="classname">java.lang.Long</code>.).</p>
+<p>When the Java method of an SQL/JRT routine returns a value, it
+    should be within the size and precision limits defined in the return type
+    of the SQL-invoked routine, otherwise an exception is raised. The scale
+    difference are ignored and corrected. For example, in the above example,
+    the <code class="literal">RETURNS CHAR VARYING(100)</code> clause limits the length
+    of the strings returned from the Java method to 100. But if the number of
+    digits after the decimal point (scale) of a returned BigDecimal value is
+    larger than the scale specified in the RETURNS clause, the decimal
+    fraction is silently truncated and no exception of warning is
+    raised.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N127C5"></a>Polymorphism</h3>
+</div>
+</div>
+</div>
+<p>If two versions of the same SQL invoked routine with different
+      parameter types are required, they can be defined to point to the same
+      method name or different method names, or even methods in different
+      classes. In the example below, the first two definitions refer to the
+      same method name in the same class. In the Java class, the two static
+      methods are defined with corresponding method signatures.</p>
+<p>In the third example, the Java function returns a result set and
+      the SQL declaration includes RETURNS TABLE.</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before_or_now(t TIME)
+  RETURNS TIME
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION testquery(INTEGER) 
+  RETURNS TABLE(n VARCHAR(20), i INT) 
+  READS SQL DATA
+  LANGUAGE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.TestJavaFunctions.getQueryResult'
+
+</pre>
+<p>In the Java class:</p>
+<pre class="programlisting">    public static java.sql.Time nowLessAnHour(java.sql.Time value) {
+        ...
+    }
+    public static java.sql.Timestamp nowLessAnHour(java.sql.Timestamp value)
+        ...
+    }
+
+    public static ResultSet getQueryResult(Connection connection, int i) throws SQLException {
+        Statement st = connection.createStatement();
+        return st.executeQuery("SELECT * FROM T WHERE I &lt; " + i);
+    }
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N127D2"></a>Java Language Procedures</h3>
+</div>
+</div>
+</div>
+<p>Java procedures are defined similarly to functions. The
+      differences are:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>The return type of the Java static method must be void.</p>
+</li>
+<li>
+<p>If a parameter is defined as OUT or INOUT, the corresponding
+          Java static method parameter must be defined as an array of the JDBC
+          non-primitive type.</p>
+</li>
+<li>
+<p>When the Java static method is invoked, the OUT and INOUT
+          arguments are passed as a single-element array.</p>
+</li>
+<li>
+<p>The static method can modify the OUT or INOUT param by
+          assigning a value to the sole element of the argument array.</p>
+</li>
+<li>
+<p>If the procedure contains SQL statements, only statements for
+          data access and manipulation are allowed. The java method should not
+          perform commit or rollback. The SQL statements should not change the
+          session settings and should not include statements at create or
+          modify tables definitions or other database objects. These rules are
+          generally enforced by the engine, but additional enforcement may be
+          added in future versions</p>
+</li>
+</ul>
+</div>
+<p>An example of a procedure definition is given below:</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname  VARCHAR(50), address VARCHAR(100))
+  MODIFIES SQL DATA
+  LANGUAGE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.Test01.newCustomerProcedure'
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N127EB"></a>Legacy Support</h3>
+</div>
+</div>
+</div>
+<p>The legacy HyperSQL statement, <code class="literal">CREATE ALIAS &lt;name&gt;
+      FOR &lt;fully qualified Java method name&gt;</code> is no longer
+      supported directly. It is supported when importing databases and
+      translates to a special <code class="literal">CREATE FUNCTION &lt;name&gt;</code>
+      statement that creates the function in the PUBLIC schema.</p>
+<p>The direct use of a Java method as a function is still supported
+      but deprecated. It is internally translated to a special <code class="literal">CREATE
+      FUNCTION</code> statement where the name of the function is the
+      double quoted, fully qualified name of the Java method used.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N127FB"></a>SQL Language Aggregate Functions</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL adds an extension to the SQL Standard to allow user defined
+    aggregate functions. A user defined aggregate function has a single
+    parameter when it is used in SQL statements. Unlike the predefined
+    aggregate functions, the keyword DISTINCT cannot be used when a user
+    defined aggregate function is invoked. Like all user defined functions, an
+    aggregate function belongs to a schema and can be polymorphic.</p>
+<p>A user defined aggregate function can be used in SQL statements
+    where a predefined aggregate function is allowed.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12802"></a>Definition of Aggregate Functions</h3>
+</div>
+</div>
+</div>
+<p>An aggregate function is always defined with 4 parameters. The
+      first parameter is the parameter that is used when the function is
+      invoked in SQL statements, the rest of the parameter are invisible to
+      the invoking statement. The type of the first parameter is user defined.
+      The type of the second parameter must be BOOLEAN. The third and fourth
+      parameters have user defined types and must be defined as INOUT
+      parameters. The defined return type of the function determines the type
+      of the value returned when the function is invoked.</p>
+<a name="N12807" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE AGGREGATE
+      FUNCTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>user defined aggregate function
+      definition</em></span>
+</p>
+<p>Aggregate function definition is similar to normal function
+      definition and has the mandatory <code class="literal">&lt;returns
+      clause&gt;</code>. The BNF is given below.</p>
+<p>
+<code class="literal">&lt;user defined aggregate function&gt; ::= CREATE
+      AGGREGATE FUNCTION &lt;schema qualified routine name&gt; &lt;SQL
+      aggregate parameter declaration list&gt; &lt;returns clause&gt;
+      &lt;routine characteristics&gt; &lt;routine body&gt;</code>
+</p>
+<p>The parameter declaration list BNF is given below. The type of the
+      first parameter is used when the function is invoked as part of an SQL
+      statement. When multiple versions of a function are required, each
+      version will have the first parameter of a different type.</p>
+<p>
+<code class="literal">&lt;SQL aggregate declaration list&gt; ::= &lt;left
+      paren&gt; [IN] [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt;
+      &lt;comma&gt; [IN] [ &lt;SQL parameter name&gt; ] BOOLEAN &lt;comma&gt;
+      INOUT [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt;
+      &lt;comma&gt; INOUT [ &lt;SQL parameter name&gt; ] &lt;parameter
+      type&gt; &lt;right paren&gt;</code>
+</p>
+<p>The return type is user defined. This is the type of the resulting
+      value when the function is called. Usually an aggregate function is
+      defined with CONTAINS SQL, as it normally does not read the data in
+      database tables, but it is possible to define the function with READS
+      SQL DATA and access the database tables.</p>
+<p>HyperSQL invokes the aggregate function, with all the arguments
+      set, once per each row in order to compute the values. Finally, it
+      invokes the function once more to return the final result.</p>
+<p>In the computation phase, the first argument is the value of the
+      user argument as specified in the SQL statement, computed for the
+      current row. The second argument is the boolean FALSE. The third and
+      fourth argument values are initially null, but they can be updated in
+      the body of the function during each invocation. The third and fourth
+      arguments act as registers and hold their values between invocations.
+      The return value of the function is ignored during the computation phase
+      (when the second parameter is FALSE).</p>
+<p>After the computation phase, the function is invoked once more to
+      get the final result. In this invocation, the first argument is NULL and
+      the second argument is boolean TRUE. The third and fourth arguments hold
+      the values they held at the end of the last invocation. The value
+      returned by the function in this invocation is used as the result of the
+      aggregate function computation in the invoking SQL statement. In SQL
+      queries with GROUP BY, the call sequence is repeated for each separate
+      group.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12828"></a>SQL PSM Aggregate Functions</h3>
+</div>
+</div>
+</div>
+<p>The example below features a user defined version of the Standard
+      <code class="literal">AVG(&lt;value expression&gt;)</code> aggregate function for
+      INTEGER input and output types. This function behaves differently from
+      the Standard AVG function as it returns 0 when all the input values are
+      null.</p>
+<pre class="programlisting">CREATE AGGREGATE FUNCTION udavg(IN x INTEGER, IN flag BOOLEAN, INOUT addup BIGINT, INOUT counter INT)
+  RETURNS INTEGER
+  CONTAINS SQL
+  BEGIN ATOMIC
+    IF flag THEN
+      RETURN addup / counter;
+    ELSE
+      SET counter = COALESCE(counter, 0) + 1;
+      SET addup = COALESCE(addup, 0) || COALESCE(x, 0);
+      RETURN NULL;
+    END IF;
+  END
+
+</pre>
+<p>The user defined aggregate function is used in a select statement
+      in the example below. Only the first parameter is visible and utilised
+      in the select statement.</p>
+<pre class="programlisting">SELECT udavg(id) FROM customers GROUP BY lastname;</pre>
+<p>In the example below, the function returns an array that contains
+      all the values passed for the aggregated column. For use with longer
+      arrays, you can optimise the function by defining a larger array in the
+      first iteration, and using the TRIM_ARRAY function on the RETURN to cut
+      the array to size :</p>
+<pre class="programlisting">CREATE AGGREGATE FUNCTION array_aggregate(IN val VARCHAR(100), IN flag boolean, INOUT buffer VARCHAR(100) ARRAY, INOUT counter INT)
+  RETURNS VARCHAR(100) ARRAY
+  CONTAINS SQL
+  BEGIN ATOMIC
+    IF flag THEN
+      RETURN buffer;
+    ELSE
+      IF val IS NULL THEN RETURN NULL; END IF;
+      IF counter IS NULL THEN SET counter = 0; END IF;
+      SET counter = counter + 1;
+      IF counter = 1 THEN SET buffer = ARRAY[val];
+      ELSE SET buffer[counter] = val; END IF;
+      RETURN NULL;
+    END IF;
+  END
+</pre>
+<p>The tables and data for the select statement below are created
+      with the DatabaseManager or DatabaseManagerSwing GUI apps. Part of the
+      output is shown. Each row of the output includes an array containing the
+      values for the invoices for each customer.</p>
+<pre class="programlisting">SELECT ID, FIRSTNAME, LASTNAME, ARRAY_AGGREGATE(CAST(INVOICE.TOTAL AS VARCHAR(100))) 
+  FROM customer JOIN INVOICE ON ID =CUSTOMERID
+  GROUP BY ID, FIRSTNAME, LASTNAME
+
+11 Susanne   Karsen    ARRAY['3988.20']                               
+12 John      Peterson  ARRAY['2903.10','4382.10','4139.70','3316.50'] 
+13 Michael   Clancy    ARRAY['6525.30']                               
+14 James     King      ARRAY['3665.40','905.10','498.00']             
+18 Sylvia    Clancy    ARRAY['634.20','4883.10']                      
+20 Bob       Clancy    ARRAY['3414.60','744.60']
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1283E"></a>Java Aggregate Functions</h3>
+</div>
+</div>
+</div>
+<p>A Java aggregate function is defined similarly to PSM functions,
+      apart from the routine body, which is defined as <code class="literal">EXTERNAL NAME
+      ...</code> The Java function signature must follow the rules for both
+      nullable and INOUT parameters, therefore:</p>
+<p>No agrument is defined as a primitive or primitive array type.
+      This allows nulls to be passed to the function. The second and third
+      arguments must be defined as arrays of the JDBC non-primitive types
+      listed in the table in the previous section.</p>
+<p>In the example below, a user-defined aggregate function for
+      geometric mean is defined.</p>
+<pre class="programlisting">CREATE AGGREGATE FUNCTION geometric_mean(IN val DOUBLE, IN flag BOOLEAN, INOUT register DOUBLE, INOUT counter INT)
+ RETURNS DOUBLE
+ NO SQL
+ LANGUAGE JAVA
+ EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.Test01.geometricMean'
+</pre>
+<p>The Java function definition is given below:</p>
+<pre class="programlisting">public static Double geometricMean(Double in, Boolean flag,
+        Double[] register, Integer[] counter) {
+
+    if (flag) {
+        if (register[0] == null) { return null; }
+        double a = register[0].doubleValue();
+        double b = 1 / (double) counter[0];
+        return Double.valueOf(java.lang.Math.pow(a, b));
+    }
+    if (in == null) { return null; }
+    if (in.doubleValue() == 0) { return null; }
+    if (register[0] == null) {
+        register[0] = in;
+        counter[0]  = Integer.valueOf(1);
+    } else {
+        register[0] = Double.valueOf(register[0].doubleValue() * in.doubleValue());
+        counter[0] = Integer.valueOf(counter[0].intValue() + 1);
+    }
+    return null;
+}
+</pre>
+<p>In a select statement, the function is used like built in
+      aggregate functions:</p>
+<pre class="programlisting">SELECT geometric_mean(age) FROM  FROM customer
+</pre>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12854"></a>Routine Definition</h2>
+</div>
+</div>
+</div>
+<p>As discussed in the previous pages, routine definition has several
+    mandatory or optional clauses. The complete BNF supported by HyperSQL and
+    the remaining clauses are documented in this section.</p>
+<a name="N12859" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE FUNCTION</strong></span>
+</p>
+<a name="N12862" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE PROCEDURE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>routine definition</em></span>
+</p>
+<p>Routine definition is similar for procedures and functions. A
+    function definition has the mandatory <code class="literal">&lt;returns
+    clause&gt;</code> which is discussed later. The description given so
+    far covers the essential elements of the specification with the BNF given
+    below.</p>
+<p>
+<code class="literal">&lt;schema procedure&gt; ::= CREATE PROCEDURE &lt;schema
+    qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+    &lt;routine characteristics&gt; &lt;routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema function&gt; ::= CREATE FUNCTION &lt;schema
+    qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+    &lt;returns clause&gt; &lt;routine characteristics&gt; &lt;routine
+    body&gt;</code>
+</p>
+<p>Parameter declaration list has been described above. For SQL/JRT
+    routines, the <code class="literal">&lt;SQL parameter name&gt;</code> is optional
+    while for SQL/PSM routines, it is required. If the <code class="literal">&lt;parameter
+    mode&gt;</code> of a parameter is OUT or INOUT, it must be specified.
+    The BNF is given below:</p>
+<p>
+<code class="literal">&lt;SQL parameter declaration list&gt; ::= &lt;left
+    paren&gt; [ &lt;SQL parameter declaration&gt; [ { &lt;comma&gt; &lt;SQL
+    parameter declaration&gt; }... ] ] &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL parameter declaration&gt; ::= [ &lt;parameter
+    mode&gt; ] [ &lt;SQL parameter name&gt; ] &lt;parameter
+    type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;parameter mode&gt; ::= IN | OUT |
+    INOUT</code>
+</p>
+<p>
+<code class="literal">&lt;parameter type&gt; ::= &lt;data
+    type&gt;</code>
+</p>
+<p>Return Value and Table Functions</p>
+<a name="N1288F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RETURNS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>returns clause</em></span>
+</p>
+<p>The <code class="literal">&lt;returns clause&gt;</code> specifies the type of
+    the return value of a function. For all SQL/PSM functions and ordinary
+    SQL/JRT functions, this is simply a type definition which can be a
+    built-in type, a DOMAIN type or a DISTINCT type, or alternatively, a TABLE
+    definition. For example, RETURNS INTEGER.</p>
+<p>For a SQL/JRT function, it is possible to define a
+    <code class="literal">&lt;returns table type&gt;</code> for a Java method that
+    returns a <code class="classname">java.sql.ResultSet</code> object. Such SQL/JRT
+    functions are called <em class="glossterm">table functions</em>. Table
+    functions are used differently from normal functions. A table function can
+    be used in an SQL query expression exactly where a normal table or view is
+    allowed. At the time of invocation, the Java method is called and the
+    returned ResultSet is transformed into an SQL table. The column types of
+    the declared TABLE must match those of the ResultSet, otherwise an
+    exception is raised at the time of invocation.</p>
+<p>If a <code class="literal">&lt;returns table type&gt;</code> is defined for an
+    SQL/PSM function, the following expression is used inside the function to
+    return a table: <code class="literal">RETURN TABLE ( &lt;query expression&gt;
+    );</code> In the example blow, a table with two columns is
+    returned.</p>
+<pre class="programlisting">RETURN TABLE ( SELECT a, b FROM atable WHERE e = 10 );</pre>
+<p>If a JDBC <code class="literal">CallableStatement</code> is used to CALL the
+    function, the table returned from the function call is returned and can be
+    accessed with the <code class="literal">getResultSet()</code> method of the
+    <code class="literal">CallableStatement</code>.</p>
+<p>
+<code class="literal">&lt;returns clause&gt; ::= RETURNS &lt;returns
+    type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns type&gt; ::= &lt;returns data type&gt; |
+    &lt;returns table type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns table type&gt; ::= TABLE &lt;table function
+    column list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table function column list&gt; ::= &lt;left
+    paren&gt; &lt;table function column list element&gt; [ { &lt;comma&gt;
+    &lt;table function column list element&gt; } ... ] &lt;right
+    paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table function column list element&gt; ::=
+    &lt;column name&gt; &lt;data type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns data type&gt; ::= &lt;data
+    type&gt;</code>
+</p>
+<a name="N128D2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>routine body</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>routine body</em></span>
+</p>
+<p>Routine body is either one or more SQL statements or a Java
+    reference, as described. The user that defines the routine by issuing the
+    CREATE FUNCTION or CREATE SCHEMA command must have the relevant access
+    rights to all tables, sequences, routines, etc. that are accessed by the
+    routine. If another user is given EXECUTE privilege on the routine, then
+    there are two possibilities, depending on the <code class="literal">&lt;rights
+    clause&gt;</code>. This clause refers to the access rights that are
+    checked when a routine is invoked. The default is <code class="literal">SQL SECURITY
+    DEFINER</code>, which means access rights of the definer are used;
+    therefore no extra checks are performed when the other user invokes the
+    routine. The alternative <code class="literal">SQL SECURITY INVOKER</code> means
+    access rights on all the database objects referenced by the routine are
+    checked for the invoker. This alternative is not supported by
+    HyperSQL.</p>
+<p>
+<code class="literal">&lt;routine body&gt; ::= &lt;SQL routine spec&gt; |
+    &lt;external body reference&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL routine spec&gt; ::= [ &lt;rights clause&gt; ]
+    &lt;SQL routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;rights clause&gt; ::= SQL SECURITY INVOKER | SQL
+    SECURITY DEFINER</code>
+</p>
+<a name="N128F2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQL routine body</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL routine body</em></span>
+</p>
+<p>The routine body of a an SQL routine consists of an
+    statement.</p>
+<p>
+<code class="literal">&lt;SQL routine body&gt; ::= &lt;SQL procedure
+    statement&gt;</code>
+</p>
+<a name="N12903" class="indexterm"></a>
+<p>
+<span class="bold"><strong>EXTERNAL NAME</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>external body reference</em></span>
+</p>
+<p>External name specifies the qualified name of the Java method
+    associated with this routine. Early releases of HyperSQL 2.0 only supports
+    Java methods within the classpath. The <code class="literal">&lt;external Java
+    reference string&gt;</code> is a quoted string which starts with
+    CLASSPATH: and is followed by the Java package, class and method names
+    separated with dots. HyperSQL does not currently support the optional
+    <code class="literal">&lt;Java parameter declaration list&gt;</code>.</p>
+<p>
+<code class="literal">&lt;external body reference&gt; ::= EXTERNAL NAME
+    &lt;external Java reference string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;external Java reference string&gt; ::= &lt;jar and
+    class name&gt; &lt;period&gt; &lt;Java method name&gt; [ &lt;Java
+    parameter declaration list&gt; ]</code>
+</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1291D"></a>Routine Characteristics</h3>
+</div>
+</div>
+</div>
+<p>The <code class="literal">&lt;routine characteristics&gt;</code> clause
+      covers several sub-clauses</p>
+<p>
+<code class="literal">&lt;routine characteristics&gt; ::= [ &lt;routine
+      characteristic&gt;... ]</code>
+</p>
+<p>
+<code class="literal">&lt;routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | SPECIFIC &lt;specific
+      name&gt; | &lt;deterministic characteristic&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | &lt;savepoint level
+      indication&gt;</code>
+</p>
+<a name="N1292B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LANGUAGE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>language clause</em></span>
+</p>
+<p>The <code class="literal">&lt;language clause&gt;</code> refers to the
+      language in which the routine body is written. It is either SQL or Java.
+      The default is SQL, so JAVA must be specified for SQL/JRT
+      routines.</p>
+<p>
+<code class="literal">&lt;language clause&gt; ::= LANGUAGE &lt;language
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;language name&gt; ::= SQL |
+      JAVA</code>
+</p>
+<p>The parameter style is not allowed for SQL routines. It is
+      optional for Java routines and, in HyperSQL, the only value allowed is
+      JAVA.</p>
+<p>
+<code class="literal">&lt;parameter style&gt; ::= JAVA</code>
+</p>
+<a name="N12947" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SPECIFIC NAME</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>specific name</em></span>
+</p>
+<p>The <code class="literal">SPECIFIC &lt;specific name&gt;</code> clause is
+      optional but the engine will creates an automatic name if it is not
+      present. When there are several versions of the same routine, the
+      <code class="literal">&lt;specific name&gt;</code> is used in schema manipulation
+      statements to drop or alter a specific version. The
+      <code class="literal">&lt;specific name&gt;</code> is a user-defined name. It
+      applies to both functions and procedures. In the examples below, a
+      specific name is specified for each function.</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  SPECIFIC an_hour_before_or_now_with_timestamp
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP SPECIFIC an_hour_before_max_with_int
+  RETURN (SELECT MAX(event_time) FROM atable WHERE event_type = e_type) - 1 HOUR
+
+</pre>
+<a name="N12960" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DETERMINISTIC</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>deterministic characteristic</em></span>
+</p>
+<p>The <code class="literal">&lt;deterministic characteristic&gt;</code> clause
+      indicates that a routine is deterministic or not. Deterministic means
+      the routine does not reference random values, external variables, or
+      time of invocation. The default is <code class="literal">NOT DETERMINISTIC</code>.
+      It is essential to declare this characteristics correctly for an SQL/JRT
+      routine, as the engine does not know the contents of the Java code,
+      which could include calls to methods returning random or time sensitive
+      values.</p>
+<p>
+<code class="literal">&lt;deterministic characteristic&gt; ::= DETERMINISTIC
+      | NOT DETERMINISTIC</code>
+</p>
+<a name="N12977" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQL DATA access</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL DATA access characteristic</em></span>
+</p>
+<p>The <code class="literal">&lt;SQL-data access indication&gt;</code> &nbsp;clause
+      indicates the extent to which a routine interacts with the database or
+      the data stored in the database tables (SQL data). &nbsp;NO SQL means no SQL
+      command is issued in the routine body and can be used only for SQL/JRT
+      functions. <code class="literal">CONTAINS SQL</code> means some SQL commands are
+      used, but they do not read or modify the SQL data. <code class="literal">READS SQL
+      DATA</code> and <code class="literal">MODIFIES SQL DATA</code> are self
+      explanatory.</p>
+<p>
+<code class="literal">&lt;SQL-data access indication&gt; ::= NO SQL |
+      CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA</code>
+</p>
+<a name="N12994" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NULL INPUT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>null call clause</em></span>
+</p>
+<p>Null Arguments</p>
+<p>The <code class="literal">&lt;null-call clause&gt;</code> is used only for
+      functions. If a function returns NULL when any of the calling arguments
+      is null, then by specifying <code class="literal">RETURNS NULL ON NULL
+      INPUT</code>, calls to the function are known to be redundant and do
+      not take place when an argument is null. This simplifies the coding of
+      the SQL/JRT Java methods and improves performance at the same
+      time.</p>
+<p>
+<code class="literal">&lt;null-call clause&gt; ::= RETURNS NULL ON NULL
+      INPUT | CALLED ON NULL INPUT</code>
+</p>
+<a name="N129AD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SAVEPOINT LEVEL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>transaction impact</em></span>
+</p>
+<p>The <code class="literal">&lt;savepoint level indication&gt;</code> is used
+      only for procedures and refers to the visibility of existing savepoints
+      within the body of the procedure. If <code class="literal">NEW SAVEPOINT
+      LEVEL</code> is specified, savepoints that have been declared prior
+      to calling the procedure become invisible within the body of the
+      procedure. HyperSQL&rsquo;s implementation accepts only <code class="literal">NEW SAVEPOINT
+      LEVEL</code>, which must be specified.</p>
+<p>
+<code class="literal">&lt;savepoint level indication&gt; ::= NEW SAVEPOINT
+      LEVEL | OLD SAVEPOINT LEVEL</code>
+</p>
+<a name="N129C7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DYNAMIC RESULT SETS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>returned result sets
+      characteristic</em></span>
+</p>
+<p>The <code class="literal">&lt;returned result sets characteristic&gt;</code>
+      is used only for SQL/PSM procedures. The maximum number of result sets
+      that a procedure may return can be specified with the clause below. The
+      default is zero. Details are discussed in the previous sections.</p>
+<p>
+<code class="literal">&lt;returned result sets characteristic&gt; ::=
+      DYNAMIC RESULT SETS &lt;maximum returned result
+      sets&gt;</code>
+</p>
+</div>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="triggers-chapt"></a>Chapter&nbsp;9.&nbsp;Triggers</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3042 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N129FF"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2009-07-14 17:55:19 +0100 (Tue, 14 Jul 2009) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N12A02">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A26">Trigger Properties</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N12A2B">Trigger Event</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A34">Granularity</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A43">Trigger Action Time</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A50">References to Rows</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A55">Trigger Condition</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A5C">Trigger Action in SQL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N12A6B">Trigger Action in Java</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N12A85">Trigger Creation</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12A02"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>Trigger functionality first appeared in SQL:1999. Triggers embody
+    the <span class="emphasis"><em>live database</em></span> concept, where changes in SQL data
+    can be monitored and acted upon. This means each time a DELETE, UPDATE or
+    INSERT is performed, additional actions are taken by the declared
+    triggers. SQL Standard triggers are <em class="glossterm">imperative</em>
+    while the <em class="glossterm">relational</em> aspects of SQL are
+    <em class="glossterm">declarative</em>. Triggers allow performing an arbitrary
+    transformation of data that is being updated or inserted, or to prevent
+    insert, updated or deletes, or to perform additional operations.</p>
+<p>Some bad examples of SQL triggers in effect enforce an &ldquo;integrity
+    constraint&rdquo; which would better be expressed as a CHECK constraint. A
+    trigger that causes an exception if the value inserted in a column is
+    negative is such an example. A check constraint that declares
+    <code class="literal">CHECK VALUE &gt;= 0</code> (declarative) is a better way of
+    expressing an integrity constraint than a trigger that throws an exception
+    if the same condition is false.</p>
+<p>Usage constraints cannot always be expressed by SQL&rsquo;s integrity
+    constraint statements. Triggers can enforce these constraints. For
+    example, it is may be possible to write a check constraint that prevents
+    data from being added, or modified on weekends. But it is not possible to
+    use a check constraint to prevent deletes. A trigger can be used to
+    enforce the time when each operation is allowed.</p>
+<p>A trigger can modify the values that are inserted into the
+    database, instead of rejecting them. For example, a badly formatted string
+    can be cleaned up by a trigger before INSERT.</p>
+<p>Triggers can also perform additional data changes, for example
+    inserting an additional row into a different table for data
+    audits.</p>
+<p>A trigger is declared to activate when an UPDATE, INSERT or
+    DELETE action is performed on a table. These actions may be direct or
+    indirect. Indirect actions may arise from CASCADE actions of FOREIGN KEY
+    constraints, or from data change statements performed on a VIEW that is
+    based on the table that in.</p>
+<p>It is possible to declare multiple triggers on a single table.
+    The triggers activate one by one according to the order in which they were
+    defined.</p>
+<p>A row level trigger allows access to the deleted or inserted
+    rows. For UPDATE actions there is both an old and new version of each row.
+    A trigger can be specified to activate before or after the action has been
+    performed. Triggers that are performed after the action cannot modify the
+    rows that have been modified. These triggers can perform other actions,
+    such as inserting rows into other tables. Triggers that are performed
+    before the action can modify the inserted or updated rows but not the
+    deleted rows.</p>
+<p>A TRIGGER that is declared on a VIEW, is an INSTEAD OF trigger.
+    This term means when an INSERT, UPDATE or DELETE statement is executed,
+    the trigger action is all that is performed, and no further data change
+    takes place on the VIEW. The trigger action can include all the statements
+    that are necessary to change the data in the tables that underlie the
+    VIEW. With the use of INSTEAD OF triggers a read-only view can effectively
+    become updatable or insertable-into.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12A26"></a>Trigger Properties</h2>
+</div>
+</div>
+</div>
+<p>A trigger is declared on a specific table or view. Various trigger
+    properties determine when the trigger is executed and how.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A2B"></a>Trigger Event</h3>
+</div>
+</div>
+</div>
+<p>The trigger event specifies the type of SQL statement that causes
+      the trigger to execute. Each trigger is specified to execute when an
+      INSERT, DELETE or UPDATE takes place.</p>
+<p>The event can be filtered by two separate means. For all triggers,
+      the WHEN clause can specify a condition against the rows that are the
+      subject of the trigger, together with the data in the database. For
+      example, a trigger can activate when the size of a table becomes larger
+      than a certain amount. Or it can activate when the values in the rows
+      being modified satisfy certain conditions.</p>
+<p>An UPDATE trigger can be declared to execute only when certain
+      columns are the subject of an update statement. For example, a trigger
+      declared as AFTER UPDATE OF (datecolumn) will activate only when the
+      UPDATE statement that is executed includes the column, datecolumn, as
+      one of the columns specified in its SET statements.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A34"></a>Granularity</h3>
+</div>
+</div>
+</div>
+<p>A statement level trigger is performed once for the executed SQL
+      statement and is declared as FOR EACH STATEMENT.</p>
+<p>A row level trigger is performed once for each row that is
+      modified during the execution of an SQL statement and is declared as FOR
+      EACH ROW. Note that an SQL statement can INSERT, UPDATE or DELETE zero
+      or more rows.</p>
+<p>If a statement does not apply to any row, then the trigger is not
+      executed.</p>
+<p>If FOR EACH ROW or FOR EACH STATEMENT is not specified, then the
+      default is FOR EACH STATEMENT.</p>
+<p>The granularity dictates whether the REFERENCING clause can
+      specify OLD ROW, NEW ROW, or OLD TABLE, NEW TABLE.</p>
+<p>A trigger declared as FOR EACH STATEMENT can only be an AFTER
+      trigger.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A43"></a>Trigger Action Time</h3>
+</div>
+</div>
+</div>
+<p>A trigger is executed BEFORE, AFTER or INSTEAD OF the trigger
+      event.</p>
+<p>INSTEAD OF triggers are allowed only when the trigger is declared
+      on a VIEW. With this type of trigger, the event (SQL statement) itself
+      is not executed, only the trigger.</p>
+<p>BEFORE or AFTER triggers are executed just before or just after
+      the execution of the event. For example, just before a row is inserted
+      into a table, the BEFORE trigger is activated, and just after the row is
+      inserted, the AFTER trigger is executed.</p>
+<p>BEFORE triggers can modify the row that is being inserted or
+      updated. AFTER triggers cannot modify rows. They are usually used to
+      perform additional operations, such as inserting rows into other
+      tables.</p>
+<p>A trigger declared as FOR EACH STATEMENT can only be an AFTER
+      trigger.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A50"></a>References to Rows</h3>
+</div>
+</div>
+</div>
+<p>If the old rows or new rows are referenced in the SQL statements
+      in the trigger action, they must have names. The REFERENCING clause is
+      used to give names to the old and new rows. The clause, REFERENCING OLD
+      | NEW TABLE is used for statement level triggers. The clause,
+      REFERENCING OLD | NEW ROW is used for row level triggers. If the old
+      rows or new rows are referenced in the SQL statements in the trigger
+      action, they must have names. In the SQL statements, the columns of the
+      old or new rows are qualified with the specified names.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A55"></a>Trigger Condition</h3>
+</div>
+</div>
+</div>
+<p>The WHEN clause can specify a condition for the columns of the row
+      that is being changed. Using this clause you can simply avoid
+      unnecessary trigger activation for rows that do not need it.</p>
+<p>For UPDATE trigger, you can specify a list of columns of the
+      table. If a list of columns is specified, then if the UPDATE statement
+      does not change the columns with SET clauses, then the trigger is not
+      activated at all.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A5C"></a>Trigger Action in SQL</h3>
+</div>
+</div>
+</div>
+<p>The trigger action specifies what the trigger does when it is
+      activated. This is usually written as one or more SQL statements.</p>
+<p>When a row level trigger is activated, there is an OLD ROW, or a
+      NEW ROW, or both. An INSERT statement supplies a NEW ROW row to be
+      inserted into a table. A DELETE statement supplied an OLD ROW be
+      deleted. An UPDATE statement supplies both OLD ROW and NEW ROW that
+      represent the updated rows before and after the update. The REFERENCING
+      clause gives names to these rows, so that the rows can be referenced in
+      the trigger action.</p>
+<p>In the example below, a name is given to the NEW ROW and it is
+      used both in the WHEN clause and in the trigger action SQL to insert a
+      row into a triglog table after each row insert into the testtrig
+      table.</p>
+<pre class="programlisting">create trigger trig after insert on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.id &gt; 1)
+   insert into triglog values (newrow.id, newrow.data, 'inserted')
+</pre>
+<p>In the example blow, the trigger code modifies the updated data if
+      a condition is true. This type of trigger is useful when the application
+      does not perform the necessary checks and modifications to data.</p>
+<pre class="programlisting">create trigger t before update on customer
+   referencing new as newrow for each row
+   begin atomic
+   if length(newrow.firstname ) &gt; 10 then
+   set newrow.firstname = lower(newrow.firstname);
+   end if;
+   end
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A6B"></a>Trigger Action in Java</h3>
+</div>
+</div>
+</div>
+<p>A trigger action can be written as a Java class that implements
+      the org.hsqldb.Trigger interface. This interface has a single method
+      which is called when the trigger is activated, either before or after
+      the event. When the method is called by the engine, it supplies the name
+      of the trigger (as name argument), the name of the table (as table
+      argument), the OLD ROW (as row1 argument) and the NEW ROW (as row2
+      argument). The row1 argument is null for row level INSERT triggers. The
+      row2 argument is null for row level DELETE triggers. For table level
+      triggers, both arguments are null (that is, there is no access to the
+      data). The triggerType argument is one of the constants in the
+      org.hsqldb.Trigger interface which indicate the type of trigger, for
+      example, INSERT_BEFORE_ROW or UPDATE_AFTER_ROW.</p>
+<p>The Java class for the trigger can be reused for several triggers
+      on different tables. The method code can distinguish between the
+      different tables and triggers using the supplied arguments and take
+      appropriate action.</p>
+<pre class="programlisting">    fire (int triggerType, String name, String table, Object row1[], Object row2[])
+</pre>
+<p>The Java method for a synchronous trigger (see below) can modify
+      the values in row2 in a BEFORE trigger. Such modifications are reflected
+      in the row that is being inserted or updated. Any other modifications
+      are ignored by the engine.</p>
+<p>A Java trigger that uses an instance of
+      <code class="classname">org.hsqldb.Trigger</code> has two forms, synchronous, or
+      asynchronous (immediate or queued). By default, or when QUEUE 0 is
+      specified, the action is performed immediately by calling the Java
+      method. This is similar to SQL trigger actions. When QUEUE n is
+      specified with n larger than 0, the engine uses a separate thread to
+      execute the Java method, using a queue with the size n. For certain
+      applications, such as real-time systems this allows asynchronous
+      notifications to be sent by the trigger event, without introducing
+      delays in the engine. With asynchronous triggers, an extra parameter,
+      NOWAIT can be used in trigger definition. This overcomes the queue full
+      condition. In this mode, old calls that are still in the queue are
+      discarded one by one and replaced with new calls.</p>
+<p>Java triggers can modify the row data. They should not be used to
+      modify the database, e.g. insert new rows, etc.</p>
+<p>For sample trigger classes and test code see,
+      org.hsqldb.sample.TriggerSample, org.hsqldb.test.TestTriggers,
+      org.hsqldb.test.TriggerClass and the associated text script
+      TestTriggers.txt in /testrun/hsqldb/ directory. In the example below,
+      the trigger is activated only if the update statement includes SET
+      clauses that modify any of the specified columns (c1, c2, c3).
+      Furthermore, the trigger is not activated if the c2 column in the
+      updated row is null.</p>
+<pre class="programlisting">create trigger trigbur before update of c1, c2, c3 on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.c2 is not null)
+   call "org.hsqldb.test.TriggerClass"
+</pre>
+<p>Java functions can be called from an SQL trigger. So it is
+      possible to define the Java function to perform any external
+      communication that are necessary for the trigger, and use SQL code for
+      checks and alterations to data.</p>
+<pre class="programlisting">create trigger t before update on customer
+   referencing new as newrow for each row
+   begin atomic
+   if length(newrow.firstname ) &gt; 10 then
+   call my_java_function(newrow.firstname, newrow.lastname);
+   end if;
+   end
+</pre>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12A85"></a>Trigger Creation</h2>
+</div>
+</div>
+</div>
+<a name="N12A88" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TRIGGER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>trigger definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;trigger definition&gt; ::= CREATE TRIGGER
+    &lt;trigger name&gt; &lt;trigger action time&gt; &lt;trigger event&gt; ON
+    &lt;table name&gt; [BEFORE &lt;other trigger name&gt;] [ REFERENCING
+    &lt;transition table or variable list&gt; ] &lt;triggered
+    action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;trigger action time&gt; ::= BEFORE | AFTER | INSTEAD
+    OF</code>
+</p>
+<p>
+<code class="literal">&lt;trigger event&gt; ::= INSERT | DELETE | UPDATE [ OF
+    &lt;trigger column list&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;trigger column list&gt; ::= &lt;column name
+    list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered action&gt; ::= [ FOR EACH { ROW |
+    STATEMENT } ] [ &lt;triggered when clause&gt; ] &lt;triggered SQL
+    statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered when clause&gt; ::= WHEN &lt;left
+    paren&gt; &lt;search condition&gt; &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered SQL statement&gt; ::= &lt;SQL procedure
+    statement&gt; | BEGIN ATOMIC { &lt;SQL procedure statement&gt;
+    &lt;semicolon&gt; }... END | [QUEUE &lt;integer literal&gt;] [NOWAIT] CALL
+    &lt;HSQLDB trigger class FQN&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transition table or variable list&gt; ::=
+    &lt;transition table or variable&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;transition table or variable&gt; ::= OLD [ ROW ] [
+    AS ] &lt;old transition variable name&gt; | NEW [ ROW ] [ AS ] &lt;new
+    transition variable name&gt; | OLD TABLE [ AS ] &lt;old transition table
+    name&gt; | NEW TABLE [ AS ] &lt;new transition table
+    name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;old transition table name&gt; ::= &lt;transition
+    table name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;new transition table name&gt; ::= &lt;transition
+    table name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transition table name&gt; ::=
+    &lt;identifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;old transition variable name&gt; ::= &lt;correlation
+    name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;new transition variable name&gt; ::= &lt;correlation
+    name&gt;</code>
+</p>
+<p>Trigger definition is a relatively complex statement. The
+    combination of <code class="literal">&lt;trigger action time&gt;</code> and
+    <code class="literal">&lt;trigger event&gt;</code> determines the type of the
+    trigger. Examples include BEFORE DELETE, AFTER UPDATE, INSTEAD OF INSERT.
+    If the optional <code class="literal">[ OF &lt;trigger column list&gt; ]</code> is
+    specified for an UPDATE trigger, then the trigger is activated only if one
+    of the columns that is in the <code class="literal">&lt;trigger column
+    list&gt;</code> is specified in the UPDATE statement that activates the
+    trigger.</p>
+<p>If a trigger is <code class="literal">FOR EACH ROW</code>, which is the
+    default option, then the trigger is activated for each row of the table
+    that is affected by the execution of an SQL statement. Otherwise, it is
+    activated once only per statement execution. In the first case, there is a
+    before and after state for each row. For UPDATE triggers, both before and
+    after states exist, representing the row before the update, and after the
+    update. For DELETE, triggers, there is only a before state. For INSERT
+    triggers, there is only an after state. If a trigger is <code class="literal">FOR EACH
+    STATEMENT</code>, then a transient table is created containing all the
+    rows for the before state and another transient table is created for the
+    after state.</p>
+<p>The <code class="literal">[ REFERENCING &lt;transition table or variable&gt;
+    ]</code> is used to give a name to the before and after data row or
+    table. This name can be referenced in the <code class="literal">&lt;SQL procedure
+    statement&gt;</code> to access the data.</p>
+<p>The optional <code class="literal">&lt;triggered when clause&gt;</code> is
+    a search condition, similar to the search condition of a DELETE or UPDATE
+    statement. If the search condition is not TRUE for a row, then the trigger
+    is not activated for that row.</p>
+<p>The <code class="literal">&lt;SQL procedure statement&gt;</code> is limited
+    to INSERT, DELETE, UPDATE and MERGE statements.</p>
+<p>The <code class="literal">&lt;HSQLDB trigger class FQN&gt;</code> is a
+    delimited identifer that contains the fully qualified name of a Java class
+    that implements the <code class="classname">org.hsqldb.Trigger</code>
+    interface.</p>
+<p>Early releases of HyperSQL version 2.0 do not allow the use of
+    OLD TABLE or NEW TABLE in statement level triggers.</p>
+<a name="N12AF0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRIGGERED SQL
+    STATEMENT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>triggered SQL statement</em></span>
+</p>
+<p>
+<code class="literal">The &lt;triggered SQL statement&gt;</code> has three
+    forms.</p>
+<p>The first form is a single SQL procedure statement. This
+    statement can reference the OLD ROW and NEW ROW variables. For example, it
+    can reference these variables and insert a row into a separate
+    table.</p>
+<p>The second form is enclosed in a BEGIN ... END block and can
+    include one or more SQL procedure statements. In BEFORE triggers, you can
+    include SET statements to modify the inserted or updated rows. In AFTER
+    triggers, you can include INSERT, DELETE and UPDATE statements to change
+    the data in other database tables. SELECT and CALL statements are allowed
+    in BEFORE and AFTER triggers. CALL statements in BEFORE triggers should
+    not modify data.</p>
+<p>The third form specifies a call to a Java method.</p>
+<p>An example of a trigger with a block is given below. The block
+    can include elements discussed the <a class="link" href="#sqlroutines-chapt" title="">SQL-Invoked Routines</a> chapter, including
+    local variables, loops and conditionals. You can also raise an exception
+    in such blocks in order to terminate the execution of the SQL statement
+    that caused the trigger to execute.</p>
+<pre class="programlisting">create trigger trig after insert on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.id &gt; 1)
+   begin atomic
+   insert into triglog values (newrow.id, newrow.data, 'inserted');
+   /* more statements can be included */
+   end
+</pre>
+<p></p>
+<a name="N12B10" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRIGGER EXECUTION
+    ORDER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>trigger execution order</em></span>
+</p>
+<p>
+<code class="literal">&lt;trigger execution order&gt; ::= BEFORE &lt;other
+    trigger name&gt;</code>
+</p>
+<p>HyperSQL extends the SQL Standard to allow the order of execution
+    of a trigger to be specified by using [BEFORE &lt;other trigger name&gt;]
+    in the definition. The newly defined trigger will be executed before the
+    specified other trigger. If this clause is not used, the new trigger is
+    executed after all the previously defined triggers of the same scope
+    (BEFORE, AFTER, EACH ROW, EACH STATEMENT).</p>
+<a name="N12B21" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP TRIGGER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop trigger statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop trigger statement&gt; ::= DROP TRIGGER
+    &lt;trigger name&gt;</code>
+</p>
+<p>Destroy a trigger.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="builtinfunctions-chapt"></a>Chapter&nbsp;10.&nbsp;Built In Functions</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N12B56"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#builtin_functions_intro-sect">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#builtin_functions_string-sect">String and Binary String Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#builtin_functions_numeric-sect">Numeric Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N132C8">Array Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N132FD">General Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#builtin_functions_sysfunc-sect">System Functions</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_intro-sect"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL supports a wide range of built-in functions and allows
+    user-defined functions written in SQL and Java languages. User defined
+    functions are covered in a separate chapter. If a built-in function is not
+    available, you can write your own using SQL. Aggregate functions are
+    discussed in chapters that cover SQL in general.</p>
+<p>The built-in functions fall into three groups:</p>
+<p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>SQL Standard Functions</p>
+<p>A wide rang of functions defined by SQL/Foundation are
+          supported. SQL/Foundation functions that have no parameter are
+          called without empty parentheses. Functions with multiple parameters
+          often use keywords instead of commas to separate the parameters.
+          Many functions are overloaded. Among these, some have one or more
+          optional parameters that can be omitted, while the return type of
+          some functions is dependent upon the type of one of the parameters.
+          The usage of SQL Standard Functions (where they can be used) is
+          covered more extensively in the <a class="link" href="#dataaccess-chapt" title="Chapter&nbsp;7.&nbsp;Data Access and Change">Data Access and Change</a> chapter</p>
+</li>
+<li>
+<p>JDBC Open Group CLI Functions</p>
+<p>These functions were defined as an extension to the CLI
+          standard, which is the basis for ODBC and JDBC and supported by many
+          database products. JDBC supports an escape mechanism to specify
+          function calls in SQL statements in a manner that is independent of
+          the function names supported by the target database engine. For
+          example <code class="literal">SELECT {fn DAYOFMONTH (dateColumn)} FROM
+          myTable</code> can be used in JDBC and is translated to Standard
+          SQL as <code class="literal">SELECT EXTRACT (DAY_OF_MONTH FROM dateColumn) FROM
+          myTable</code> if a database engine supports the Standard syntax.
+          If a database engine does not support Standard SQL, then the
+          translation will be different. HyperSQL supports all the function
+          names specified in the JDBC specifications as native functions.
+          Therefore, there is no need to use the <code class="literal">{fn FUNC_NAME ( ...
+          ) }</code> escape with HyperSQL. If a JDBC function is supported
+          by the SQL Standard in a different form, the SQL Standard form is
+          the preferred form to use.</p>
+</li>
+<li>
+<p>HyperSQL Built-In Functions</p>
+<p>Several additional built-in functions are available for some
+          useful operations. Some of these functions return the current
+          setting for the session and the database. The General Functions
+          accept arguments of different types and return values based on
+          comparison between the arguments.</p>
+</li>
+</ul>
+</div>
+</p>
+<p>In the BNF specification used here, words in capital letters are
+    actual tokens. Syntactic elements such as expressions are enclosed in
+    angle brackets. The <code class="literal">&lt;left paren&gt;</code> and
+    <code class="literal">&lt;right paren&gt;</code> tokens are represented with the
+    actual symbol. Optional elements are enclosed with square brackets (
+    <code class="literal">&lt;left bracket&gt;</code> and <code class="literal">&lt;right
+    bracket&gt;</code> ). Multiple options for a required element are
+    enclosed with braces (<code class="literal"> &lt;left brace&gt;</code> and
+    <code class="literal">&lt;right brace&gt;</code> )<code class="literal">.</code> Alternative
+    tokens are separated with the vertical bar ( <code class="literal">&lt;vertical
+    bar&gt;</code> ). At the end of each function definition, the standard
+    which specifies the function is noted in parentheses as JDBC or HyperSQL,
+    unless the function is in the SQL/Foundation part of the SQL
+    Standard.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_string-sect"></a>String and Binary String Functions</h2>
+</div>
+</div>
+</div>
+<p>In SQL, there are three kinds of string: character, binary and bit.
+    The units are respectively characters, octets, and bits. Each kind of
+    string can be in different data types. CHAR, VARCHAR and CLOB are the
+    character data types. BINARY, VARBINARY and BLOB are the binary data
+    types. BIT and BIT VARYING are the bit string types. In all string
+    functions, the position of a unit of the string within the whole string is
+    specified from 1 to the length of the whole string. In the BNF,
+    <code class="literal">&lt;char value expr&gt; </code>indicates any valid SQL
+    expression that evaluates to a character type. Likewise,
+    <code class="literal">&lt;binary value expr&gt; </code>indicates a binary type
+    and<code class="literal"> &lt;num value expr&gt; </code>indicates a numeric
+    type.</p>
+<a name="N12BA8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ASCII</strong></span>
+</p>
+<p>
+<code class="literal">ASCII ( &lt;char value expr&gt; )</code>
+</p>
+<p>Returns an INTEGER equal to the ASCII code value of the first
+    character of <code class="literal">&lt;char value expr&gt;</code>. (JDBC)</p>
+<p>
+<code class="literal">CHAR ( &lt;UNICODE code&gt; ) </code>
+</p>
+<p>The argument is an INTEGER. Returns a character string containing a
+    single character that has the specified<code class="literal"> &lt;UNICODE
+    code&gt;</code>, which is an integer. ASCII codes are a subset of the
+    allowed values for <code class="literal">&lt;UNICODE code&gt;</code>. (JDBC)</p>
+<a name="N12BC4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONCAT</strong></span>
+</p>
+<p>
+<code class="literal">CONCAT ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; )</code>
+</p>
+<p>
+<code class="literal">CONCAT ( &lt;binary value expr 1&gt;, &lt;binary value expr
+    2&gt; )</code>
+</p>
+<p>The arguments are character strings or binary strings. Returns a
+    string formed by concatenation of the arguments. Equivalent to the SQL
+    concatenation expression <code class="literal">&lt;value expr 1&gt; || &lt;value expr
+    2&gt;</code>. (JDBC)</p>
+<a name="N12BD8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DIFFERENCE</strong></span>
+</p>
+<p>
+<code class="literal">DIFFERENCE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; )</code>
+</p>
+<p>The arguments are character strings. Converts the arguments into
+    SOUNDEX codes, and returns an INTEGER between 0-4 which indicates how
+    similar the two SOUNDEX value are. If the values are the same, it returns
+    4, if the values have no similarity, it returns 0. In-between values are
+    returned for partial similarity. (JDBC)</p>
+<a name="N12BE6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>INSERT</strong></span>
+</p>
+<p>
+<code class="literal">INSERT ( &lt;char value expr 1&gt;, &lt;offset&gt;,
+    &lt;length&gt;, &lt;char value expr 2&gt; )</code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value expr
+    1&gt;</code> in which <code class="literal">&lt;length&gt;</code> characters have
+    been removed from the <code class="literal">&lt;offset&gt;</code> position and in
+    their place, the whole <code class="literal">&lt;char value expr 2&gt;</code> is
+    copied. Equivalent to SQL/Foundation <code class="literal">OVERLAY( &lt;char value
+    expr1&gt; PLACING &lt; char value expr2&gt; FROM &lt;offset&gt; FOR
+    &lt;length&gt; )</code> . (JDBC)</p>
+<a name="N12C03" class="indexterm"></a>
+<p>
+<span class="bold"><strong>HEXTORAW</strong></span>
+</p>
+<p>
+<code class="literal">HEXTORAW( &lt;char value expr&gt; )</code>
+</p>
+<p>Returns a BINARY string formed by translation of hexadecimal digits
+    and letters in the &lt;<code class="literal">char value expr&gt;</code>. Each
+    character of the <code class="literal">&lt;char value expr&gt;</code> must be a
+    digit or a letter in the A | B | C | D | E | F set. Each byte of the
+    retired binary string is formed by translating two hex digits into one
+    byte. (HyperSQL)</p>
+<a name="N12C17" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LCASE</strong></span>
+</p>
+<p>
+<code class="literal">LCASE ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a character string that is the lower case version of the
+    <code class="literal">&lt;char value expr&gt;</code>. Equivalent to SQL/Foundation
+    <code class="literal">LOWER (&lt;char value expr&gt;)</code>. (JDBC)</p>
+<a name="N12C2B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LEFT</strong></span>
+</p>
+<p>
+<code class="literal">LEFT ( &lt;char value expr&gt;, &lt;length&gt; )
+    </code>
+</p>
+<p>Returns a character string consisting of the first
+    <code class="literal">&lt;length&gt;</code> characters of <code class="literal">&lt;char value
+    expr&gt;</code>. Equivalent to SQL/Foundation<code class="literal">
+    SUBSTRING(&lt;char value expr&gt; FROM 0 FOR &lt;length&gt;)</code>.
+    (JDBC)</p>
+<a name="N12C42" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LENGTH</strong></span>
+</p>
+<p>
+<code class="literal">LENGTH ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns as a BIGINT value the number of characters in
+    <code class="literal">&lt;char value expr&gt;</code>. Equivalent to SQL/Foundation
+    <code class="literal">CHAR_LENGTH(&lt;char value expr&gt;)</code>. (JDBC)</p>
+<a name="N12C56" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOCATE</strong></span>
+</p>
+<p>
+<code class="literal">LOCATE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt; [ , &lt;offset&gt; ] ) </code>
+</p>
+<p>Returns as a BIGINT value the starting position of the first
+    occurrence of <code class="literal">&lt;char value expr 1&gt;</code> within
+    <code class="literal">&lt;char value expr 2&gt;</code>. If
+    <code class="literal">&lt;offset</code>&gt; is specified, the search begins with the
+    position indicated by <code class="literal">&lt;offset&gt;</code>. If the search is
+    not successful, 0 is returned. Equivalent to SQL/Foundation
+    <code class="literal">POSITION(&lt;char value expr 1&gt; IN &lt;char value expr
+    2&gt;)</code>. (JDBC)</p>
+<a name="N12C73" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LTRIM</strong></span>
+</p>
+<p>
+<code class="literal">LTRIM ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value
+    expr&gt;</code> with the leading space characters removed. Equivalent
+    to SQL/Foundation <code class="literal">TRIM( LEADING ' ' FROM &lt;char value expr&gt;
+    )</code>. (JDBC)</p>
+<a name="N12C87" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RAWTOHEX</strong></span>
+</p>
+<p>
+<code class="literal">RAWTOHEX( &lt;binary value expr&gt; )</code>
+</p>
+<p>Returns a character string composed of hexadecimal digits
+    representing the bytes in the <code class="literal">&lt;binary value
+    expr&gt;</code>. Each byte of the <code class="literal">&lt;binary value
+    expr&gt;</code> is translated into two hex digits. (HyperSQL)</p>
+<a name="N12C9B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REGEXP_MATCHES</strong></span>
+</p>
+<p>
+<code class="literal">REGEXP_MATCHES ( &lt;char value expr&gt;, &lt;regular
+    expression&gt; ) </code>
+</p>
+<p>Returns true if the &lt;char value expr&gt; matches the &lt;regular
+    expression&gt;. The &lt;regular expression&gt; is defined according to
+    Java language rules. (HyperSQL)</p>
+<a name="N12CA9" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REPEAT</strong></span>
+</p>
+<p>
+<code class="literal">REPEAT ( &lt;char value expr&gt;, &lt;count&gt; )
+    </code>
+</p>
+<p>Returns a character string based on<code class="literal"> &lt;char value
+    expr&gt;</code>, repeated <code class="literal">&lt;count&gt;</code> times.
+    (JDBC)</p>
+<a name="N12CBD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REPLACE</strong></span>
+</p>
+<p>
+<code class="literal">REPLACE ( &lt;char value expr 1&gt;, &lt;char value expr
+    2&gt;, &lt;char value expr 3&gt; )</code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value expr
+    1&gt;</code> where each occurrence of <code class="literal">&lt;char value expr
+    2&gt;</code> has been replaced with a copy of <code class="literal">&lt;char value
+    expr 3&gt;</code>. (JDBC)</p>
+<a name="N12CD4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>REVERSE</strong></span>
+</p>
+<p>
+<code class="literal">REVERSE ( &lt;char value expr&gt; )</code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value
+    expr&gt;</code> with characters in the reverse order. (HyperSQL)</p>
+<a name="N12CE5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RIGHT</strong></span>
+</p>
+<p>
+<code class="literal">RIGHT ( &lt;char value expr&gt;, &lt;count&gt; )
+    </code>
+</p>
+<p>Returns a character string consisting of the last
+    <code class="literal">&lt;count&gt;</code> characters of <code class="literal">&lt;char value
+    expr&gt;</code>. (JDBC)</p>
+<a name="N12CF9" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RTRIM</strong></span>
+</p>
+<p>
+<code class="literal">RTRIM ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a character string based on <code class="literal">&lt;char value
+    expr&gt;</code> with the trailing space characters removed. Equivalent
+    to SQL/Foundation <code class="literal">TRIM(TRAILING ' ' FROM &lt;character
+    string&gt;)</code>. (JDBC)</p>
+<a name="N12D0D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SOUNDEX</strong></span>
+</p>
+<p>
+<code class="literal">SOUNDEX ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a four character code representing the sound of
+    <code class="literal">&lt;char value expr&gt;</code>. The US census algorithm is
+    used. For example the soundex value for Washington is W252. (JDBC)</p>
+<a name="N12D1E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SPACE</strong></span>
+</p>
+<p>
+<code class="literal">SPACE ( &lt;count&gt; ) </code>
+</p>
+<p>Returns a character string consisting of <code class="literal">&lt;count&gt;
+    </code>spaces. (JDBC)</p>
+<a name="N12D2F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SUBSTR</strong></span>
+</p>
+<p>
+<code class="literal">{ SUBSTR | SUBSTRING } ( &lt;char value expr&gt;,
+    &lt;offset&gt;, &lt;length&gt; )</code>
+</p>
+<p>The JDBC version of SQL/Foundation <code class="literal">SUBSTRING</code>
+    returns a character string that consists of
+    <code class="literal">&lt;length&gt;</code> characters from <code class="literal">&lt;char value
+    expr&gt; </code>starting at the <code class="literal">&lt;offset&gt;</code>
+    position. (JDBC)</p>
+<a name="N12D49" class="indexterm"></a>
+<p>
+<span class="bold"><strong>UCASE</strong></span>
+</p>
+<p>
+<code class="literal">UCASE ( &lt;char value expr&gt; ) </code>
+</p>
+<p>Returns a character string that is the lower case version of the
+    <code class="literal">&lt;char value expr&gt;</code>. Equivalent to SQL/Foundation
+    <code class="literal">UPPER( &lt;char value expr&gt; )</code> . (JDBC)</p>
+<a name="N12D5D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CHARACTER_LENGTH</strong></span>
+</p>
+<p>
+<code class="literal">{ CHAR_LENGTH | CHARACTER_LENGTH } ( &lt;char value
+    expression&gt; [ USING { CHARACTERS | OCTETS } ] )</code>
+</p>
+<a name="N12D69" class="indexterm"></a>
+<p>
+<span class="bold"><strong>OCTET_LENGTH</strong></span>
+</p>
+<p>
+<code class="literal">OCTET_LENGTH ( &lt;string value expression&gt;
+    )</code>
+</p>
+<a name="N12D75" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BIT_LENGTH</strong></span>
+</p>
+<p>
+<code class="literal">BIT_LENGTH ( &lt;string value expression&gt;
+    )</code>
+</p>
+<p>The CHAR_LENGTH or CHARACTER_LENGTH function can be used with
+    character strings, while OCTET_LENGTH can be used with character or binary
+    strings and BIT_LENGTH can be used with character, binary and bit
+    strings.</p>
+<p>All functions return a BIGINT value that measures the length of the
+    string in the given unit. CHAR_LENGTH counts characters, OCTET_LENGTH
+    counts octets and BIT_LENGTH counts bits in the string. For CHAR_LENGTH,
+    if <code class="literal">[ USING OCTETS ] </code>is specified, the octet count is
+    returned. (Foundation)</p>
+<a name="N12D88" class="indexterm"></a>
+<p>
+<span class="bold"><strong>OVERLAY</strong></span>
+</p>
+<p>
+<code class="literal">OVERLAY ( &lt;char value expr 1&gt; PLACING &lt;char value
+    expr 2&gt;</code>
+</p>
+<p>
+<code class="literal">FROM &lt;start position&gt; [ FOR &lt;string length&gt; ] [
+    USING CHARACTERS ] )</code>
+</p>
+<p>
+<code class="literal">OVERLAY ( &lt;binary value expr 1&gt; PLACING &lt;binary
+    value expr 2&gt;</code>
+</p>
+<p>
+<code class="literal">FROM &lt;start position&gt; [ FOR &lt;string length&gt; ]
+    )</code>
+</p>
+<p>The character version of OVERLAY returns a character string based on
+    <code class="literal">&lt;char value expr 1&gt;</code> in which <code class="literal">&lt;string
+    length&gt;</code> characters have been removed from the
+    <code class="literal">&lt;start position&gt;</code> and in their place, the whole
+    <code class="literal">&lt;char value expr 2&gt;</code> is copied.</p>
+<p>The binary version of OVERLAY returns a binary string formed in the
+    same manner as the character version. (Foundation)</p>
+<a name="N12DAD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>POSITION</strong></span>
+</p>
+<p>
+<code class="literal">POSITION ( &lt;char value expr 1&gt; IN &lt;char value expr
+    2&gt; [ USING CHARACTERS ] )</code>
+</p>
+<p>
+<code class="literal">POSITION ( &lt;binary value expr 1&gt; IN &lt;binary value
+    expr 2&gt; )</code>
+</p>
+<p>The character and binary versions of POSITION search the string
+    value of the second argument for the first occurrence of the first
+    argument string. If the search is successful, the position in the string
+    is returned as a BIGINT. Otherwise zero is returned.</p>
+<a name="N12DBE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SUBSTRING</strong></span>
+</p>
+<p>
+<code class="literal">SUBSTRING ( &lt;char value expr&gt; FROM &lt;start
+    position&gt; [ FOR &lt;string length&gt; ] [ USING CHARACTERS ]
+    )</code>
+</p>
+<p>
+<code class="literal">SUBSTRING ( &lt;binary value expr&gt; FROM &lt;start
+    position&gt; [ FOR &lt;string length&gt; ] )</code>
+</p>
+<p>The character version of SUBSTRING returns a character string that
+    consists of the characters of the <code class="literal">&lt;char value expr&gt;
+    </code>from <code class="literal">&lt;start position&gt;</code>. If the
+    optional<code class="literal"> &lt;string length&gt;</code> is specified, only
+    <code class="literal">&lt;string length&gt; </code>characters are returned.</p>
+<p>The binary version of SUBSTRING returns a binary string in the same
+    manner. (Foundation)</p>
+<a name="N12DDD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRIM</strong></span>
+</p>
+<p>
+<code class="literal">TRIM ([ [ LEADING | TRAILING | BOTH ] [ &lt;trim
+    character&gt; ] FROM ] &lt;char value expr&gt; )</code>
+</p>
+<p>
+<code class="literal">TRIM ([ [ LEADING | TRAILING | BOTH ] [ &lt;trim octet&gt;
+    ] FROM ] &lt;binary value expr&gt; )</code>
+</p>
+<p>The character version of TRIM returns a character string based on
+    <code class="literal">&lt;char value expr&gt;</code>. Consecutive instances of
+    <code class="literal">&lt;trim character&gt; </code>are removed from the beginning,
+    the end or both ends of the<code class="literal">&lt;char value expr&gt;
+    </code>depending on the value of the optional first qualifier
+    <code class="literal">[ LEADING | TRAILING | BOTH ]</code>. If no qualifier is
+    specified, <code class="literal">BOTH </code>is used as default. If <code class="literal">[
+    &lt;trim character&gt; ]</code> is not specified, the space character
+    is used as default.</p>
+<p>The binary version of TRIM returns a binary string based on
+    <code class="literal">&lt;binary value expr&gt;</code>. Consecutive instances of
+    <code class="literal">&lt;trim octet&gt; </code>are removed in the same manner as in
+    the character version. If<code class="literal"> [ &lt;trim octet&gt; ]</code> is not
+    specified, the 0 octet is used as default. (Foundation)</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_numeric-sect"></a>Numeric Functions</h2>
+</div>
+</div>
+</div>
+<a name="N12E0F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ABS</strong></span>
+</p>
+<p>
+<code class="literal">ABS ( &lt;num value expr&gt; | &lt;interval value expr&gt;
+    ) </code>
+</p>
+<p>Returns the absolute value of the argument as a value of the same
+    type. (JDBC and Foundation)</p>
+<a name="N12E1D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ACOS</strong></span>
+</p>
+<p>
+<code class="literal">ACOS ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the arc-cosine of the argument in radians as a value of
+    DOUBLE type. (JDBC)</p>
+<a name="N12E2B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ASIN</strong></span>
+</p>
+<p>
+<code class="literal">ASIN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the arc-sine of the argument in radians as a value of DOUBLE
+    type. (JDBC)</p>
+<a name="N12E39" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ATAN</strong></span>
+</p>
+<p>
+<code class="literal">ATAN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the arc-tangent of the argument in radians as a value of
+    DOUBLE type. (JDBC)</p>
+<a name="N12E47" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ATAN2</strong></span>
+</p>
+<p>
+<code class="literal">ATAN2 ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    ) </code>
+</p>
+<p>The <code class="literal">&lt;num value expr 1&gt;</code> and <code class="literal">&lt;num
+    value expr 2&gt;</code> express the <code class="varname">x</code> and
+    <code class="varname">y</code> coordinates of a point. Returns the angle, in
+    radians, representing the angle coordinate of the point in polar
+    coordinates, as a value of DOUBLE type. (JDBC)</p>
+<a name="N12E61" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CEILING</strong></span>
+</p>
+<p>
+<code class="literal">{ CEIL | CEILING } ( &lt;num value expr&gt; )
+    </code>
+</p>
+<p>Returns the smallest integer greater than or equal to the argument.
+    If the argument is exact numeric then the result is exact numeric with a
+    scale of 0. If the argument is approximate numeric, then the result is of
+    DOUBLE type. (JDBC and Foundation)</p>
+<a name="N12E6F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BITAND</strong></span>
+</p>
+<p>
+<code class="literal">BITAND ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">BITAND ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</code>
+</p>
+<a name="N12E7E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BITOR</strong></span>
+</p>
+<p>
+<code class="literal">BITOR ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">BITOR ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</code>
+</p>
+<a name="N12E8D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BITXOR</strong></span>
+</p>
+<p>
+<code class="literal">BITXOR ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">BITXOR ( &lt;bit value expr 1&gt;, &lt;bit value expr 2&gt;
+    )</code>
+</p>
+<p>These three functions perform the bit operations: OR, AND, XOR, on
+    two values. The values are either integer values, or bit strings. The
+    result is an integer value of the same type as the arguments, or a bit
+    string of the same length as the argument. Each bit of the result is
+    formed by performing the operation on corresponding bits of the arguments.
+    (HyperSQL)</p>
+<a name="N12E9E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COS</strong></span>
+</p>
+<p>
+<code class="literal">COS ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the cosine of the argument (an angle expressed in radians)
+    as a value of DOUBLE type. (JDBC)</p>
+<a name="N12EAC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COT</strong></span>
+</p>
+<p>
+<code class="literal">COT ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the cotangent of the argument as a value of DOUBLE type. The
+    <code class="literal">&lt;num value expr&gt;</code> represents an angle expressed in
+    radians. (JDBC)</p>
+<a name="N12EBD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DEGREES</strong></span>
+</p>
+<p>
+<code class="literal">DEGREES ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Converts the argument (an angle expressed in<code class="literal">
+    radians</code>) into degrees and returns the value in the DOUBLE type.
+    (JDBC)</p>
+<a name="N12ECE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>EXP</strong></span>
+</p>
+<p>
+<code class="literal">EXP ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the exponential value of the argument as a value of DOUBLE
+    type. (JDBC and Foundation)</p>
+<a name="N12EDC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>FLOOR</strong></span>
+</p>
+<p>
+<code class="literal">FLOOR ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the largest integer that is less than or equal to the
+    argument. If the argument is exact numeric then the result is exact
+    numeric with a scale of 0. If the argument is approximate numeric, then
+    the result is of DOUBLE type. (JDBC and Foundation)</p>
+<a name="N12EEA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LN</strong></span>
+</p>
+<p>
+<code class="literal">LN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the natural logarithm of the argument, as a value of DOUBLE
+    type. (Foundation)</p>
+<a name="N12EF8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOG</strong></span>
+</p>
+<p>
+<code class="literal">LOG ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the natural logarithm of the argument, as a value of DOUBLE
+    type. (JDBC)</p>
+<a name="N12F06" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOG10</strong></span>
+</p>
+<p>
+<code class="literal">LOG10 ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the base 10 logarithm of the argument as a value of DOUBLE
+    type. (JDBC)</p>
+<p>
+<code class="literal">MOD ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt; )
+    </code>
+</p>
+<a name="N12F17" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MOD</strong></span>
+</p>
+<p>Returns the remainder (modulus) of <code class="literal">&lt;num value expr
+    1&gt;</code> divided by <code class="literal">&lt;num value expr 2&gt;.</code>
+    The data type of the returned value is the same as the second argument.
+    (JDBC and Foundation)</p>
+<a name="N12F28" class="indexterm"></a>
+<p>
+<span class="bold"><strong>PI</strong></span>
+</p>
+<p>
+<code class="literal">PI () </code>
+</p>
+<p>Returns the constant pi as a value of DOUBLE type. (JDBC)</p>
+<a name="N12F36" class="indexterm"></a>
+<p>
+<span class="bold"><strong>POWER</strong></span>
+</p>
+<p>
+<code class="literal">POWER ( &lt;num value expr 1&gt;, &lt;num value expr 2&gt;
+    ) </code>
+</p>
+<p>Returns the value of <code class="literal">&lt;num value expr 1&gt;</code>
+    raised to the power of <code class="literal">&lt;int value expr 2&gt;</code> as a
+    value of DOUBLE type. (JDBC and Foundation)</p>
+<a name="N12F4A" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RADIANS</strong></span>
+</p>
+<p>
+<code class="literal">RADIANS ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Converts the argument (an angle expressed in<code class="literal">
+    degrees</code>) into radians and returns the value in the DOUBLE type.
+    (JDBC)</p>
+<a name="N12F5B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RAND</strong></span>
+</p>
+<p>
+<code class="literal">RAND ( [ &lt;int value expr&gt; ] ) </code>
+</p>
+<p>Returns a random value in the DOUBLE type. The optional <code class="literal">[
+    &lt;int value expr&gt; ]</code> is used as seed value. In HyperSQL each
+    session has a separate random number generator. The first call that uses a
+    seed parameter sets the seed for subsequent calls that do not include a
+    parameter. (JDBC)</p>
+<a name="N12F6C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ROUND</strong></span>
+</p>
+<p>
+<code class="literal">ROUND ( &lt;num value expr&gt;, &lt;int value expr&gt; )
+    </code>
+</p>
+<p>The <code class="literal">&lt;num value expr&gt; </code>is of the DOUBLE type.
+    The function returns a DOUBLE value which is the value of the argument
+    rounded to <code class="literal">&lt;int value expr&gt;</code> places right of the
+    decimal point. If <code class="literal">&lt;int value expr&gt;</code> is negative,
+    the first argument is rounded to <code class="literal">&lt;int value expr&gt;</code>
+    places to the left of the decimal point. (JDBC)</p>
+<a name="N12F86" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SIGN</strong></span>
+</p>
+<p>
+<code class="literal">SIGN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns an INTEGER, indicating the sign of the argument. If the
+    argument is negative then -1 is returned. If it is equal to zero then 0 is
+    returned. If the argument is positive then 1 is returned. (JDBC)</p>
+<a name="N12F94" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SIN</strong></span>
+</p>
+<p>
+<code class="literal">SIN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the sine of the argument (an angle expressed in radians) as
+    a value of DOUBLE type. (JDBC)</p>
+<a name="N12FA2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQRT</strong></span>
+</p>
+<p>
+<code class="literal">SQRT ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the square root of the argument as a value of DOUBLE type.
+    (JDBC and Foundation)</p>
+<a name="N12FB0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TAN</strong></span>
+</p>
+<p>
+<code class="literal">TAN ( &lt;num value expr&gt; ) </code>
+</p>
+<p>Returns the tangent of the argument (an angle expressed in radians)
+    as a value of DOUBLE type. (JDBC)</p>
+<a name="N12FBE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRUNCATE</strong></span>
+</p>
+<p>
+<code class="literal">TRUNCATE ( &lt;num value expr&gt;, &lt;int value expr&gt; )
+    </code>
+</p>
+<p>Returns a value in the same type as <code class="literal">&lt;num value
+    expr&gt;</code>. The value is rounded by replacing digits with zeros
+    from <code class="literal">&lt;int value expr&gt;</code> places right of the decimal
+    point to the end. If <code class="literal">&lt;int value expr&gt;</code> is
+    negative, <code class="literal">ABS( &lt;int value expr&gt; )</code> digits to left
+    of the decimal point and all digits to the right of the decimal points are
+    replaced with zeros. Results of calling TRUNCATE with 12345.6789 with (-2,
+    0, 2, 4) are (12300.0000, 12345.0000, 12345.6700, 12345.6789).
+    (JDBC)</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_datetime-sect"></a>Date Time and Interval Functions</h2>
+</div>
+</div>
+</div>
+<a name="N12FDC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TIMEZONE</strong></span>
+</p>
+<p>
+<code class="literal">TIMEZONE()</code>
+</p>
+<p>Returns the current time zone for the session. Returns an INTERVAL
+    HOUR TO MINUTE value. (HyperSQL)</p>
+<a name="N12FEA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SESSION_TIMEZONE</strong></span>
+</p>
+<p>
+<code class="literal">SESSION_TIMEZONE()</code>
+</p>
+<p>Returns the default time zone for the current session. Returns an
+    INTERVAL HOUR TO MINUTE value. (HyperSQL)</p>
+<a name="N12FF8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATABASE_TIMEZONE</strong></span>
+</p>
+<p>
+<code class="literal">DATABASE_TIMEZONE()</code>
+</p>
+<p>Returns the time zone for the database engine. This is based on
+    where the database server process is located. Returns an INTERVAL HOUR TO
+    MINUTE value. (HyperSQL)</p>
+<a name="N13006" class="indexterm"></a>
+<p>
+<span class="bold"><strong>EXTRACT</strong></span>
+</p>
+<p>
+<code class="literal">EXTRACT ( &lt;extract field&gt; FROM &lt;extract source&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">&lt;extract field&gt; ::= YEAR | MONTH | DAY | HOUR |
+    MINUTE | DAY_OF_WEEK | WEEK_OF_YEAR | QUARTER | DAY_OF_YEAR | DAY_OF_MONTH
+    |</code>
+</p>
+<p>
+<code class="literal">TIMEZONE_HOUR | TIMEZONE_MINUTE | SECOND |
+    SECONDS_SINCE_MIDNIGHT |</code>
+</p>
+<p>
+<code class="literal">DAY_NAME | MONTH_NAME</code>
+</p>
+<p>
+<code class="literal">&lt;extract source&gt; ::= &lt;datatime value expr&gt; |
+    &lt;interval value expr&gt;</code>
+</p>
+<p>The EXTRACT function returns a field or element of the
+    <code class="literal">&lt;extract source&gt;</code>. The <code class="literal">&lt;extract
+    source&gt;</code> is a datetime or interval expression. The type of the
+    return value is BIGINT for most of the<code class="literal"> &lt;extract
+    field&gt;</code> options. The exceptions is <code class="literal">SECOND
+    </code>where a DECIMAL value is returned which has the same precision
+    as the datetime or interval expression. The field values <code class="literal">DAY_NAME
+    </code>or<code class="literal"> MONTH_NAME </code>result in a character string.
+    When <code class="literal">MONTH_NAME</code> is specified, a string in the range
+    January - December is returned. When <code class="literal">DAY_NAME </code>is
+    specified, a string in the range Sunday -Saturday is returned.</p>
+<p>If the <code class="literal">&lt;extract source&gt;</code> is <code class="literal">FROM
+    &lt;datatime value expr&gt;</code>, different groups of
+    <code class="literal">&lt;extract source&gt;</code> can be used depending on the
+    data type of the expression. The <code class="literal">TIMEZONE_HOUR |
+    TIMEZONE_MINUTE</code> options are valid only for TIME WITH TIMEZONE
+    and TIMESTAMP WITH TIMEZONE data types. The <code class="literal">HOUR | MINUTE |
+    SECOND | SECONDS_MIDNIGHT</code> options, are valid for TIME and
+    TIMESTAMP types. The rest of the fields are valid for DATE and TIMESTAMP
+    types.</p>
+<p>If the <code class="literal">&lt;extract source&gt;</code> is <code class="literal">FROM
+    &lt;interval value expr&gt;</code>, the <code class="literal">&lt;extract
+    field&gt;</code> must be one of the fields of the INTERVAL type of the
+    expressions. The <code class="literal">YEAR | MONTH</code> options may be valid for
+    INTERVAL types based on months. The <code class="literal">DAY | HOUR | MINUTE | SECOND
+    | SECONDS_MIDNIGHT</code> options may be valid for INTERVAL types based
+    on seconds. For example,<code class="literal"> DAY | HOUR | MINUTE</code> are the
+    only valid fields for the INTERVAL DAY TO MINUTE data type. (Foundation
+    with HyperSQL extensions)</p>
+<a name="N1305D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_DATE</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_DATE</code>
+</p>
+<a name="N13069" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_TIME</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_TIME [ ( &lt;time precision&gt; )
+    ]</code>
+</p>
+<a name="N13075" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOCALTIME</strong></span>
+</p>
+<p>
+<code class="literal">LOCALTIME [ ( &lt;time precision&gt; ) ]</code>
+</p>
+<a name="N13081" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_TIMESTAMP</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_TIMESTAMP [ ( &lt;timestamp precision&gt; )
+    ]</code>
+</p>
+<a name="N1308D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOCALTIMESTAMP</strong></span>
+</p>
+<p>
+<code class="literal">LOCALTIMESTAMP [ ( &lt;timestamp precision&gt; )
+    ]</code>
+</p>
+<p>These datetime functions return the datetime value representing the
+    moment the function is called. CURRENT_DATE returns a value of DATE type.
+    CURRENT_TIME returns a value of TIME WITH TIME ZONE type. LOCALTIME
+    returns a value of TIME type. CURRENT_TIMESTAMP returns a value of
+    TIMESTAMP WITH TIME ZONE type. LOCALTIMESTAMP returns a value of TIMESTAMP
+    type. If the optional <code class="literal">[ ( &lt;time precision&gt; ) ]</code>
+    or<code class="literal"> [ ( &lt;timestamp precision&gt; ) ]</code> is used, then
+    the returned value has the specified fraction of the second precision.
+    (Foundation)</p>
+<a name="N130A1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURDATE</strong></span>
+</p>
+<p>
+<code class="literal">CURDATE ()</code>
+</p>
+<p>This function is equivalent to<code class="literal"> CURRENT_DATE.
+    </code>(JDBC)</p>
+<a name="N130B2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURTIME</strong></span>
+</p>
+<p>
+<code class="literal">CURTIME ()</code>
+</p>
+<p>This function is equivalent to<code class="literal"> LOCALTIME</code>.
+    (JDBC)</p>
+<a name="N130C3" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DAYNAME</strong></span>
+</p>
+<p>
+<code class="literal">DAYNAME ( &lt;datatime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( DAY_NAME FROM ...
+    ) </code>Returns a string in the range of Sunday - Saturday.
+    (JDBC)</p>
+<a name="N130D4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DAYOFMONTH</strong></span>
+</p>
+<p>
+<code class="literal">DAYOFMONTH ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( DAY_OF_MONTH FROM
+    ... ) </code>Returns an integer value in the range of 1-31.
+    (JDBC)</p>
+<a name="N130E5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DAYOFWEEK</strong></span>
+</p>
+<p>
+<code class="literal">DAYOFWEEK ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( DAY_OF_WEEK FROM
+    ... ) </code>Returns an integer value in the range of 1-7. The first
+    day of the week is Sunday. (JDBC)</p>
+<a name="N130F6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DAYOFYEAR</strong></span>
+</p>
+<p>
+<code class="literal">DAYOFYEAR ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( DAY_OF_YEAR FROM
+    ... ) </code>Returns an integer value in the range of 1-366.
+    (JDBC)</p>
+<a name="N13107" class="indexterm"></a>
+<p>
+<span class="bold"><strong>HOUR</strong></span>
+</p>
+<p>
+<code class="literal">HOUR ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( HOUR FROM ... )
+    </code>Returns an integer value in the range of 0-23. (JDBC)</p>
+<a name="N13118" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MINUTE</strong></span>
+</p>
+<p>
+<code class="literal">MINUTE ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( MINUTE FROM ... )
+    </code>Returns an integer value in the range of 0 - 59. (JDBC)</p>
+<a name="N13129" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MONTH</strong></span>
+</p>
+<p>
+<code class="literal">MONTH ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( MONTH FROM ... )
+    </code>Returns an integer value in the range of 1-12. (JDBC)</p>
+<a name="N1313A" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MONTHNAME</strong></span>
+</p>
+<p>
+<code class="literal">MONTHNAME ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( NAME_OF_MONTH FROM
+    ... ) </code>Returns a string in the range of January - December.
+    (JDBC)</p>
+<a name="N1314B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NOW</strong></span>
+</p>
+<p>
+<code class="literal">NOW ()</code>
+</p>
+<p>This function is equivalent to
+    <code class="literal">LOCAL_TIMESTAMP.</code>
+</p>
+<a name="N1315B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>QUARTER</strong></span>
+</p>
+<p>
+<code class="literal">QUARTER ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( QUARTER FROM ... )
+    </code>Returns an integer in the range of 1 - 4. (JDBC)</p>
+<a name="N1316C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SECOND</strong></span>
+</p>
+<p>
+<code class="literal">SECOND ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to <code class="literal">EXTRACT ( SECOND FROM ... )
+    </code>Returns an integer or decimal in the range of 0 - 59, with the
+    same precision as the &lt;datetime value expr&gt;. (JDBC)</p>
+<a name="N1317D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SECONDS_SINCE_MIDNIGHT</strong></span>
+</p>
+<p>
+<code class="literal">SECONDS_SINCE_MIDNIGHT ( &lt;datetime value expr&gt;
+    )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT (
+    SECONDS_SINCE_MIDNIGHT FROM ... ) </code>Returns an integer in the
+    range of 0 - 86399. (HyperSQL)</p>
+<a name="N1318E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>WEEK</strong></span>
+</p>
+<p>
+<code class="literal">WEEK ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( WEEK_OF_YEAR FROM
+    ... ) </code>Returns an integer in the range of 1 - 54. (JDBC)</p>
+<a name="N1319F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>YEAR</strong></span>
+</p>
+<p>
+<code class="literal">YEAR ( &lt;datetime value expr&gt; )</code>
+</p>
+<p>This function is equivalent to<code class="literal"> EXTRACT ( YEAR FROM ... )
+    </code>Returns an integer in the range of 1 - 9999. (JDBC)</p>
+<a name="N131B0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TIMESTAMPADD</strong></span>
+</p>
+<p>
+<code class="literal">TIMESTAMPADD ( &lt;tsi datetime field&gt;, &lt;numeric
+    value expression&gt;, &lt;datetime value expr&gt;)</code>
+</p>
+<a name="N131BC" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TIMESTAMPDIFF</strong></span>
+</p>
+<p>
+<code class="literal">TIMESTAMPDIFF ( &lt;tsi datetime field&gt;, &lt;datetime
+    value expr 1&gt;, &lt;datetime value expr 2&gt;)</code>
+</p>
+<p>
+<code class="literal">&lt;tsi datetime field&gt; ::= SQL_TSI_FRAC_SECOND |
+    SQL_TSI_SECOND | SQL_TSI_MINUTE | SQL_TSI_HOUR | SQL_TSI_DAY |
+    SQL_TSI_WEEK | SQL_TSI_MONTH | SQL_TSI_QUARTER |
+    SQL_TSI_YEAR</code>
+</p>
+<p>HyperSQL supports full SQL Standard datetime features. It supports
+    adding integers representing units of time directly to datetime values
+    using the arithmetic plus operator. It also supports subtracting one
+    <code class="literal">&lt;datetime value expr&gt;</code> from another in the given
+    units of days using the minus operator. An example of
+    <code class="literal">&lt;datetime value expr&gt; + &lt;numeric value expression&gt;
+    &lt;datetime field&gt; </code>is <code class="literal">LOCAL_TIMESTAMP + 5
+    DAY</code>. An example of <code class="literal">( &lt;datetime value expr&gt; -
+    &lt;numeric value expression&gt; ) &lt;datetime field&gt; </code>is
+    <code class="literal">(CURRENT_DATE - DATE '2008-08-8') MONTH </code>which returns
+    the number of calendar months between the two dates.</p>
+<p>The two JDBC functions, <code class="literal">TIMESTAMPADD </code>and
+    <code class="literal">TIMESTAMPDIFF</code> perform the same function as above SQL
+    expressions. The field names are keywords and are different from those
+    used in the EXTRACT functions. These names are valid for use only when
+    calling these two functions. The return value for TIMESTAMPADD is of the
+    same type as the datetime argument used. The return type for TIMESTAMPDIFF
+    is always BIGINT, regardless of the type of arguments. The two datetime
+    arguments of TIMESTAMPDIFF should be of the same type. (JDBC)</p>
+<a name="N131E4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATEADD</strong></span>
+</p>
+<p>
+<code class="literal">DATEADD ( &lt;field&gt;, &lt;numeric value expr&gt;,
+    &lt;datetime value expr&gt; )</code>
+</p>
+<a name="N131F0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATEDIFF</strong></span>
+</p>
+<p>
+<code class="literal">DATEDIFF ( &lt;field&gt;, &lt;datetime value expr 1&gt;,
+    datetime value expr 2&gt; )</code>
+</p>
+<p>
+<code class="literal">&lt;field&gt; ::= 'yy' | 'mm' | 'dd' | 'hh' | 'mi' | 'ss' |
+    'ms'</code>
+</p>
+<p>The DATEADD and DATEDIFF functions are alternatives to TIMESTAMPADD
+    and TIMESTAMPDIFF, with fewer available field options. The field names are
+    specified as strings, rather than keywords. The fields translate to YEAR,
+    MONTH, DAY, HOUR, MINUTE, SECOND and MILLISECOND. (HyperSQL}</p>
+<a name="N13201" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TO_CHAR</strong></span>
+</p>
+<p>
+<code class="literal">TO_CHAR( &lt;datetime value expr&gt;, &lt;char value
+    expr&gt; )</code>
+</p>
+<p>This function formats a datetime or numeric value to the format
+    specified by the pattern given in the second argument. The pattern can
+    contain pattern elements from the list given below, plus punctuation and
+    space characters. An example, including the result, is given below:</p>
+<pre class="programlisting">TO_CHAR ( TIMESTAMP'2008-02-01 20:30:40', 'YYYY BC MONTH, DAY HH')
+
+2008 AD February, Friday 8
+</pre>
+<p>The format is internally translated to a
+    <code class="classname">java.text.SimpleDateFormat</code> format string. Any
+    character sequences not listed below are included in the Java format
+    string and may cause unexpected results or errors. Therefore unsupported
+    format strings should not be used. The supported format components are as
+    follows:</p>
+<div class="table">
+<a name="N13216"></a>
+<p class="title">
+<b>Table&nbsp;10.1.&nbsp;TO CHAR Values</b>
+</p>
+<div class="table-contents">
+<table summary="TO CHAR Values" cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">BC | B.C. | AD | A.D.</code></td><td style="border-bottom: 0.5pt solid ; ">Returns <code class="literal">AD</code> for common era and
+            <code class="literal">BC</code> for before common era</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">RRRR</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>4-digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">YYYY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>4-digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">IYYY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>4-digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">YY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>2 digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">IY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>2 digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">IYYY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>4-digit year</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">MM</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Month (01-12)</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">MON</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Short three-letter name of month</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">MONTH</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Name of month</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">WW</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Week of year (1-53) where week 1 starts on the first
+            day of the year and continues to the seventh day of the
+            year.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">W</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Week of month (1-5) where week 1 starts on the first
+            day of the month and ends on the seventh.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">IW</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Week of year (1-52 or 1-53) based on the ISO
+            standard.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">DAY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Name of day.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">DD</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Day of month (1-31).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">DDD</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Day of year (1-366).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">DY</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Short three-letter name of day.</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">HH</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Hour of day (0-11).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">HH12</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Hour of day (0-11).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">HH24</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Hour of day (0-23).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">MI</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Minute (0-59).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">SS</code></td><td style="border-bottom: 0.5pt solid ; ">
+<p>Second (0-59).</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; "><code class="literal">FF</code></td><td style="">
+<p>Fractional seconds.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N132C8"></a>Array Functions</h2>
+</div>
+</div>
+</div>
+<p>Array functions are specialised functions with ARRAY
+    parameters.</p>
+<a name="N132CD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CARDINALITY</strong></span>
+</p>
+<p>
+<code class="literal">CARDINALITY( &lt;array value expr&gt; )</code>
+</p>
+<p>Returns the element count for the given array argument.
+    (Foundation)</p>
+<a name="N132DB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>MAX_CARDINALITY</strong></span>
+</p>
+<p>
+<code class="literal">MAX_CARDINALITY( &lt;array value expr&gt;
+    )</code>
+</p>
+<p>Returns the maximum allowed element count for the given array
+    argument. (Foundation)</p>
+<a name="N132E9" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRIM_ARRAY</strong></span>
+</p>
+<p>
+<code class="literal">TRIM_ARRAY( &lt;array value expr&gt;, &lt;num value
+    expr&gt; )</code>
+</p>
+<p>Returns a new array that contains the elements of the
+    <code class="literal">&lt;array value expr&gt;</code> minus the number of elements
+    specified by the <code class="literal">&lt;num value expr&gt;. </code>Elements are
+    discarded from the end of the array. (Foundation)</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N132FD"></a>General Functions</h2>
+</div>
+</div>
+</div>
+<p>General functions can take different types of arguments. Some
+    General Functions accept a variable number of arguments.</p>
+<a name="N13302" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COALESCE</strong></span>
+</p>
+<p>
+<code class="literal">COALESCE( &lt;value expr 1&gt;, &lt;value expr 2&gt; [,
+    ...] )</code>
+</p>
+<p>Returns <code class="literal">&lt;value expr 1&gt;</code> if it is not null,
+    otherwise returns <code class="literal">&lt;value expr 2&gt;</code> if not null and
+    so on. The type of both arguments must be comparable. (Foundation)</p>
+<a name="N13316" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CONVERT</strong></span>
+</p>
+<p>
+<code class="literal">CONVERT ( &lt;value expr&gt; , &lt;data type&gt;
+    )</code>
+</p>
+<p>
+<code class="literal">&lt;data type&gt; ::= { SQL_BIGINT | SQL_BINARY | SQL_BIT
+    |SQL_BLOB | SQL_BOOLEAN | SQL_CHAR | SQL_CLOB | SQL_DATE | SQL_DECIMAL |
+    SQL_DATALINK |SQL_DOUBLE | SQL_FLOAT | SQL_INTEGER | SQL_LONGVARBINARY |
+    SQL_LONGNVARCHAR | SQL_LONGVARCHAR | SQL_NCHAR | SQL_NCLOB | SQL_NUMERIC |
+    SQL_NVARCHAR | SQL_REAL | SQL_ROWID | SQL_SQLXML | SQL_SMALLINT | SQL_TIME
+    | SQL_TIMESTAMP | SQL_TINYINT | SQL_VARBINARY | SQL_VARCHAR} [ (
+    &lt;precision, length or scale parameters&gt; ) ]</code>
+</p>
+<p>The CONVERT function is a JDBC escape function, equivalent to the
+    SQL standard CAST expression. It converts the <code class="literal">&lt;value
+    expr&gt;</code> into the given <code class="literal">&lt;data type&gt;</code> and
+    returns the value. The <code class="literal">&lt;data type&gt;</code> options are
+    synthetic names made by prefixing type names with <code class="literal">SQL_</code>.
+    Some of the <code class="literal">&lt;data type&gt;</code> options represent valid
+    SQL types, but some are based on non-standard type names, namely
+    <code class="literal">{ SQL_LONGNVARCHAR | SQL_LONGVARBINARY |SQL_LONGVARCHAR |
+    SQL_TINYINT }</code>. None of the synthetic names can be used in any
+    other context than the CONVERT function.</p>
+<p>The definition of CONVERT in the JDBC Standard does not allow the
+    precision, scale or length to be specified. This is required by the SQL
+    standard for BINARY, BIT, BLOB, CHAR, CLOB, VARBINARY and VARCHAR types
+    and is often needed for DECIMAL and NUMERIC. Therefore, HyperSQL allows
+    the use of precision, scale or length for the type definition when they
+    are valid for the type definition. HyperSQL also allows the use of real
+    type names (without the <code class="literal">SQL_</code> prefix). (JDBC)</p>
+<a name="N1333E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DECODE</strong></span>
+</p>
+<p>
+<code class="literal">DECODE( &lt;value expr main&gt;, &lt;value expr match
+    1&gt;, &lt;value expr result 1&gt; [...,] [, &lt;value expr default&gt;]
+    )</code>
+</p>
+<p>DECODE takes at least 3 arguments. The <code class="literal">&lt;value expr
+    main&gt;</code> is compared with <code class="literal">&lt;value expr match
+    1&gt;</code> and if it matches, <code class="literal">&lt;value expr result
+    1&gt;</code> is returned. If there are additional pairs of
+    <code class="literal">&lt;value expr match n&gt;</code> and <code class="literal">&lt;value expr
+    result n&gt;</code>, comparison is repeated until a match is found the
+    result is returned. If no match is found, the <code class="literal">&lt;value expr
+    default&gt;</code> is returned if it is specified, otherwise NULL is
+    returned. The type of the return value is a combination of the types of
+    the <code class="literal">&lt;value expr result ... &gt;</code> arguments.
+    (HyperSQL)</p>
+<a name="N13361" class="indexterm"></a>
+<p>
+<span class="bold"><strong>GREATEST</strong></span>
+</p>
+<p>
+<code class="literal">GREATEST( &lt;value expr 1&gt;, [&lt;value expr ...&gt;,
+    ...] )</code>
+</p>
+<p>The GREATEST function takes one or more arguments. It compares the
+    arguments with each other and returns the greatest argument. The return
+    type is the combined type of the arguments. Arguments can be of any type,
+    so long as they are comparable. (HyperSQL)</p>
+<a name="N1336F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IFNULL</strong></span>
+</p>
+<p>
+<code class="literal">IFNULL( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</code>
+</p>
+<p>Returns <code class="literal">&lt;value expr 1&gt;</code> if it is not null,
+    otherwise returns <code class="literal">&lt;value expr 2&gt;</code>. The type of
+    both arguments must be the same. Equivalent to SQL Standard
+    <code class="literal">COALESCE(&lt;value expr 1&gt;, &lt;value expr 2&gt;)</code>
+    function. (JDBC)</p>
+<a name="N13386" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LEAST</strong></span>
+</p>
+<p>
+<code class="literal">LEAST( &lt;value expr 1&gt;, [&lt;value expr ...&gt;, ...]
+    )</code>
+</p>
+<p>The LEAST function takes one or more arguments. It compares the
+    arguments with each other and returns the smallest argument. The return
+    type is the combined type of the arguments. Arguments can be of any type,
+    so long as they are comparable. (HyperSQL)</p>
+<a name="N13394" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NULLIF</strong></span>
+</p>
+<p>
+<code class="literal">NULLIF( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</code>
+</p>
+<p>Returns <code class="literal">&lt;value expr 1&gt;</code> if it is not equal
+    to <code class="literal">&lt;value expr 2&gt;</code>, otherwise returns null. The
+    type of both arguments must be the same. This function is a shorthand for
+    a specific CASE expression. (Foundation)</p>
+<a name="N133A8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NVL</strong></span>
+</p>
+<p>
+<code class="literal">NVL( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</code>
+</p>
+<p>Returns <code class="literal">&lt;value expr 1&gt;</code> if it is not null,
+    otherwise returns <code class="literal">&lt;value expr 2&gt;</code>. The type of the
+    return value is the combined type of the two value expressions. For
+    example, if &lt;value expr 1&gt; is an INTEGER column and
+    <code class="literal">&lt;value expr 2&gt;</code> is a DOUBLE constant, the return
+    type is DOUBLE. This function is the same as IFNULL and COALESCE
+    (HyperSQL)</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="builtin_functions_sysfunc-sect"></a>System Functions</h2>
+</div>
+</div>
+</div>
+<a name="N133C3" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CRYPT_KEY</strong></span>
+</p>
+<p>
+<code class="literal">CRYPT_KEY( &lt;value expr 1&gt;, &lt;value expr 2&gt;
+    )</code>
+</p>
+<p>Returns a binary string representation of a cryptography key for the
+    given cipher and cyptography provider. The cipher specification is
+    specified by <code class="literal">&lt;value expr 1&gt;</code> and the provider by
+    <code class="literal">&lt;value expr 2&gt;</code>. To use the default provider,
+    specify null for <code class="literal">&lt;value expr 2&gt;</code>.
+    (HyperSQL)</p>
+<a name="N133DA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IDENTITY</strong></span>
+</p>
+<p>
+<code class="literal">IDENTITY ()</code>
+</p>
+<p>Returns the last IDENTITY value inserted into a row by the current
+    session. The statement, CALL IDENTITY() can be made after an INSERT
+    statement that inserts a row into a table with an IDENTITY column. The
+    CALL IDENTITY() statement returns the last IDENTITY value that was
+    inserted into a table by the current session. Each session manages this
+    function call separately and is not affected by inserts in other sessions.
+    The statement can be executed as a direct statement or a prepared
+    statement. (HyperSQL)</p>
+<a name="N133E8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATABASE</strong></span>
+</p>
+<p>
+<code class="literal">DATABASE ()</code>
+</p>
+<p>Returns the file name (without directory information) of the
+    database. (JDBC)</p>
+<a name="N133F6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATABASE_VERSION</strong></span>
+</p>
+<p>
+<code class="literal">DATABASE_VERSION ()</code>
+</p>
+<p>Returns the full version string for the database engine. For
+    example, 2.0.1. (JDBC)</p>
+<a name="N13404" class="indexterm"></a>
+<p>
+<span class="bold"><strong>USER</strong></span>
+</p>
+<p>
+<code class="literal">USER ()</code>
+</p>
+<p>Equivalent to the SQL function <code class="literal">CURRENT_USER</code>.
+    (JDBC)</p>
+<a name="N13415" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_USER</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_USER</code>
+</p>
+<a name="N13421" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_ROLE</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_ROLE</code>
+</p>
+<a name="N1342D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SESSION_USER</strong></span>
+</p>
+<p>
+<code class="literal">SESSION_USER</code>
+</p>
+<a name="N13439" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SYSTEM_USER</strong></span>
+</p>
+<p>
+<code class="literal">SYSTEM_USER</code>
+</p>
+<a name="N13445" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_SCHEMA</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_SCHEMA</code>
+</p>
+<a name="N13451" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CURRENT_CATALOG</strong></span>
+</p>
+<p>
+<code class="literal">CURRENT_CATALOG</code>
+</p>
+<p>These functions return the named current session attribute. They are
+    all SQL Standard functions.</p>
+<p>The CURRENT_USER is the user that connected to the database, or a
+    user subsequently set by the SET AUTHORIZATION statement.</p>
+<p>SESSION_USER is the same as CURRENT_USER</p>
+<p>SYSTEM_USER is the user that connected to the database. It is not
+    changed with any command until the session is closed.</p>
+<p>CURRENT_SCHEMA is default schema of the user, or a schema
+    subsequently set by the SET SCHEMA command.</p>
+<p>CURRENT_CATALOG is always the same within a given HyperSQL database
+    and indicates the name of the catalog.</p>
+<a name="N13469" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISAUTOCOMMIT</strong></span>
+</p>
+<p>
+<code class="literal">ISAUTOCOMMIT()</code>
+</p>
+<p>Returns TRUE if the session is in autocommit mode. (HyperSQL)</p>
+<a name="N13477" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISREADONLYSESSION</strong></span>
+</p>
+<p>
+<code class="literal">ISREADONLYSESSION()</code>
+</p>
+<p>Returns TRUE if the session is in read only mode. (HyperSQL)</p>
+<a name="N13485" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISREADONLYDATABASE</strong></span>
+</p>
+<p>
+<code class="literal">ISREADONLYDATABASE()</code>
+</p>
+<p>Returns TRUE if the database is a read only database.
+    (HyperSQL)</p>
+<a name="N13493" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISREADONLYDATABASEFILES</strong></span>
+</p>
+<p>
+<code class="literal">ISREADONLYDATABASEFILES()</code>
+</p>
+<p>Returns TRUE if the database is a read-only files database. In this
+    kind of database, it is possible to modify the data, but the changes are
+    not persisted to the database files. (HyperSQL)</p>
+<a name="N134A1" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ISOLATION_LEVEL</strong></span>
+</p>
+<p>
+<code class="literal">ISOLATION_LEVEL()</code>
+</p>
+<p>Returns the current transaction isolation level for the session.
+    Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</p>
+<a name="N134AF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SESSION_ISOLATION_LEVEL</strong></span>
+</p>
+<p>
+<code class="literal">SESSION_ISOLATION_LEVEL()</code>
+</p>
+<p>Returns the default transaction isolation level for the current
+    session. Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</p>
+<a name="N134BD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DATABASE_ISOLATION_LEVEL</strong></span>
+</p>
+<p>
+<code class="literal">DATABASE_ISOLATION_LEVEL()</code>
+</p>
+<p>Returns the default transaction isolation level for the database.
+    Returns either READ COMMITTED or SERIALIZABLE as a string.
+    (HyperSQL)</p>
+<a name="N134CB" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRANSACTION_CONTROL</strong></span>
+</p>
+<p>
+<code class="literal">TRANSACTION_CONTROL()</code>
+</p>
+<p>Returns the current transaction model for the database. Returns
+    LOCKS, MVLOCKS or MVCC as a string. (HyperSQL)</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="deployment-chapt"></a>Chapter&nbsp;11.&nbsp;System Management and Deployment
+  Issues</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3630 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N134FD"></a>
+<p>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-06 10:44:27 -0400 (Sun, 06 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#deploymen_modes-sect">Mode of Operation and Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N13506">Mode of Operation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13525">Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1353A">Large Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1354D">Deployment context</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13559">Readonly Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#deployment_mem_disk-sect">Memory and Disk Use</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N13571">Table Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1357F">Result Set Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13594">Temporary Memory Use During Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135A0">Data Cache Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135BF">Object Pool Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135C7">Lob Memory Usage</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135CC">Disk Space</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#deployment_conns-sect">Managing Database Connections</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N135F4">Tweaking the Mode of Operation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N135F9">Application Development and Testing</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1362A">Embedded Databases in Desktop Applications</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13632">Embedded Databases in Server Applications</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13639">Embedding a Database Listener</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1365D">Using HyperSQL Without Logging</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1366B">Server Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#deployment_upgrade-sect">Upgrading Databases</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#upgrade_via_script-sect">Upgrading From Older
+      Versions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N136B7">Manual Changes to the *.script File</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N136FB">Backward Compatibility Issues</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#deployment_backup-sect">Backing Up Database Catalogs</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N13742">Making Online Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13751">Making Offline Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1376E">Examining Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N13784">Restoring a Backup</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N1379B">Encrypted Databases</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N137A2">Creating and Accessing an Encrypted Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N137B2">Speed Considerations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N137B7">Security Considerations</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N137C8">Monitoring Database Operations</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N137CD">Statement Level Monitoring</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N137D6">Internal Event Monitoring</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N137E4">Server Operation Monitoring</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N137E9">Statements</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deploymen_modes-sect"></a>Mode of Operation and Tables</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL has many modes of operation and features that allow it to
+    be used in very different scenarios. Levels of memory usage, speed and
+    accessibility by different applications are influenced by how HyperSQL is
+    deployed.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13506"></a>Mode of Operation</h3>
+</div>
+</div>
+</div>
+<p>The decision to run HyperSQL as a separate server process or as an
+      <em class="glossterm">in-process</em> database should be based on the
+      following:</p>
+<p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>When HyperSQL is run as a server on a separate machine, it
+            is isolated from hardware failures and crashes on the hosts
+            running the application.</p>
+</li>
+<li>
+<p>When HyperSQL is run as a server on the same machine, it is
+            isolated from application crashes and memory leaks.</p>
+</li>
+<li>
+<p>Server connections are slower than
+            <em class="glossterm">in-process</em> connections due to the overhead
+            of streaming the data for each JDBC call.</p>
+</li>
+<li>
+<p>You can reduce client/server traffic using SQL Stored
+            procedures to reduce the number of JDBC execute calls.</p>
+</li>
+<li>
+<p>During development, it is better to use a Server with
+            server.silent=false, which displays the statements sent to the
+            server on the console window.</p>
+</li>
+<li>
+<p>To improve speed of execution for statements that are
+            executed repeatedly, reuse a parameterized PreparedStatement for
+            the lifetime of the connections.</p>
+</li>
+</ul>
+</div>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13525"></a>Tables</h3>
+</div>
+</div>
+</div>
+<p>TEXT tables are designed for special applications where the data
+      has to be in an interchangeable format, such as CSV (comma separated
+      values). TEXT tables should not be used for routine storage of
+      data.</p>
+<p>MEMORY tables and CACHED tables are generally used for data
+      storage. The difference between the two is as follows:</p>
+<p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>The data for all MEMORY tables is read from the *.script
+            file when the database is started and stored in memory. In
+            contrast the data for cached tables is not read into memory until
+            the table is accessed. Furthermore, only part of the data for each
+            CACHED table is held in memory, allowing tables with more data
+            than can be held in memory.</p>
+</li>
+<li>
+<p>When the database is shutdown in the normal way, all the
+            data for MEMORY tables is written out to the disk. In comparison,
+            the data in CACHED tables that has changed is written out during
+            operation and at shutdown.</p>
+</li>
+<li>
+<p>The size and capacity of the data cache for all the CACHED
+            tables is configurable. This makes it possible to allow all the
+            data in CACHED tables to be cached in memory. In this case, speed
+            of access is good, but slightly slower than MEMORY tables.</p>
+</li>
+<li>
+<p>For normal applications it is recommended that MEMORY tables
+            are used for small amounts of data, leaving CACHED tables for
+            large data sets. For special applications in which speed is
+            paramount and a large amount of free memory is available, MEMORY
+            tables can be used for large tables as well.</p>
+</li>
+</ul>
+</div>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1353A"></a>Large Objects</h3>
+</div>
+</div>
+</div>
+<p>HyperSQL 2.0 supports dedicated storage and access to BLOB and
+      CLOB objects. These objects can have huge sizes. BLOB or CLOB is
+      specified as the type of a column of the table. Afterwards, rows can be
+      inserted into the table using a PreparedStatement for efficient transfer
+      of large LOB data to the database. In <em class="glossterm">mem:</em>
+      catalogs, CLOB and BLOB data is stored in memory. In
+      <em class="glossterm">file:</em> catalogs, this data is stored in a single
+      separate file which has the extension *.lobs. The size of this file can
+      grow to huge, terabyte figures.</p>
+<p>LOB data should be store in the database using a JDBC
+      PreparedStatement object. The streaming methods send the LOB to the
+      database in one operation as a binary or character stream. Inside the
+      database, the disk space is allocated as needed and the data is saved as
+      it is being received. LOB data should be retrieved from the database
+      using a JDBC ResultSet method. When a streaming method is used to
+      retrieve a LOB, it is retrieved in large chunks in a transparent manner.
+      LOB data can also be stored by calling a JDBC method with String or
+      byte[] argument, but these methods limit the size of the LOB that can be
+      stored or retrieved.</p>
+<p>LOB data is not duplicated in the database when a lob is copied
+      from one table to another. The disk space is reused when a LOB is
+      deleted and is not contained in any table.</p>
+<p>By using a dedicated LOB store, HyperSQL achieves consistently
+      high speeds (usually over 20MB / s) for both storage and retrieval of
+      LOBs.</p>
+<p>The LOB catalog is stored in the database as a memory table.
+      Therefore the amount of JVM memory should be increased when more than
+      tens of thousands of LOBs are stored in the database.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1354D"></a>Deployment context</h3>
+</div>
+</div>
+</div>
+<p>The files used for storing HyperSQL database data are all in the
+      same directory. New files are always created and deleted by the database
+      engine. Two simple principles must be observed:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>The Java process running HyperSQL must have full privileges on
+          the directory where the files are stored. This include create and
+          delete privileges.</p>
+</li>
+<li>
+<p>The file system must have enough spare room both for the
+          'permanent' and 'temporary' files. The default maximum size of the
+          *.log file is 50MB. The *.data file can grow to up to 16GB (more if
+          the default has been increased). The .backup file can be up to the
+          size of the *.data file. The *.lobs file can grow to several
+          terabytes. The temporary files created at the time of a SHUTDOWN can
+          be equal in size to the *.script file and the .data file.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13559"></a>Readonly Databases</h3>
+</div>
+</div>
+</div>
+<p>A <em class="glossterm">file:</em> catalog can be made readonly
+      permanently, or it can be opened as readonly. To make the database
+      readonly, the property, value pair, readonly=true can be added to the
+      .properties file of the database.</p>
+<p>It is also possible to open a normal database as readonly. For
+      this, the property can be included in the URL of the first connection to
+      the database.</p>
+<p>There is another option which allows MEMORY tables to be writable,
+      but without persisting the changes at SHUTDOWN. This option is activated
+      with the property, value pair, files_readonly= true, which can be added
+      to the .properties file of the database, or included in the URL of the
+      first connection to the database. This option is useful for running
+      application tests which operate on a predefined dataset.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deployment_mem_disk-sect"></a>Memory and Disk Use</h2>
+</div>
+</div>
+</div>
+<a name="N13569" class="indexterm"></a>
+<p>Memory used by the program can be thought of as two distinct pools:
+    memory used for table data which is not released unless the data is
+    deleted and memory that can be released or is released automatically,
+    including memory used for caching, building result sets and other internal
+    operations such as storing the information needed for a rollback a
+    transaction.</p>
+<p>Most JVM implementations allocate up to a maximum amount of memory
+    (usually 64 MB by default). This amount is generally not adequate when
+    large memory tables are used, or when the average size of rows in cached
+    tables is larger than a few hundred bytes. The maximum amount of allocated
+    memory can be set on the Java command line that is used for running
+    HyperSQL. For example, with Sun JVM, parameter -Xmx256m increases the
+    amount to 256 MB.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13571"></a>Table Memory Allocation</h3>
+</div>
+</div>
+</div>
+<p>The memory used for a MEMORY table is the sum of memory used by
+      each row. Each MEMORY table row is a Java object that has 2 int or
+      reference variables. It contains an array of objects for the fields in
+      the row. Each field is an object such as <code class="classname">Integer</code>,
+      <code class="classname">Long</code>, <code class="classname">String</code>, etc. In
+      addition each index on the table adds a node object to the row. Each
+      node object has 6 int or reference variables. As a result, a table with
+      just one column of type INTEGER will have four objects per row, with a
+      total of 10 variables of 4 bytes each - currently taking up 80 bytes per
+      row. Beyond this, each extra column in the table adds at least a few
+      bytes to the size of each row.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1357F"></a>Result Set Memory Allocation</h3>
+</div>
+</div>
+</div>
+<p>By default, all the rows in the result set are built in memory, so
+      very large result sets may not be possible to build. In server mode
+      databases, by default, the result set memory is released from the server
+      once the database server has returned the result set.
+      <em class="glossterm">in-process</em> databases release the memory when the
+      application program releases the
+      <code class="classname">java.sql.ResultSet</code> object. Server modes require
+      additional memory for returning result sets, as they convert the full
+      result set into an array of bytes which is then transmitted to the
+      client.</p>
+<p>HyperSQL 2.0 supports disk-based result sets. The commands,
+      <code class="literal">SET SESSION RESULT MEMORY ROWS &lt;integer&gt;</code> and
+      <code class="literal">SET DATABASE DEFAULT RESULT MEMORY ROWS
+      &lt;integer&gt;</code> specify a threshold for the number of rows.
+      Results with row counts above the threshold are stored on disk. These
+      settings also apply to temporary tables and subquery tables.</p>
+<p>When the setFetchSize() method of the Statement interface is used
+      to limit the number rows fetched, the whole result is held by the engine
+      and is returned to the JDBC ResultSet in blocks of rows of the specified
+      fetch size. Disk-based result sets slow down the database operations and
+      should be used only when absolutely necessary, perhaps with result sets
+      that are larger than tens of thousands of rows.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13594"></a>Temporary Memory Use During Operations</h3>
+</div>
+</div>
+</div>
+<p>When UPDATE and DELETE queries are performed on CACHED tables, the
+      full set of rows that are affected, including those affected due to ON
+      UPDATE actions, is held in memory for the duration of the operation.
+      This means it may not be possible to perform deletes or updates
+      involving very large numbers of rows of CACHED tables. Such operations
+      should be performed in smaller sets.</p>
+<p>When transactions support is enabled with SET AUTOCOMMIT FALSE,
+      lists of all insert, delete or update operations are stored in memory so
+      that they can be undone when ROLLBACK is issued. For CACHED tables, only
+      the transaction information is held in memory, not the actual rows that
+      have changed. Transactions that span thousands of modification to data
+      will take up a lot of memory until the next COMMIT or ROLLBACK clears
+      the list. Each row modification uses less than 100 bytes until
+      COMMIT.</p>
+<p>When subqueries or views are used in SELECT and other statements,
+      transient tables are created and populated by the engine. If the
+      <code class="literal">SET SESSION RESULT MEMORY ROWS &lt;integer&gt;</code>
+      statement has been used, these transient tables are stored on disk when
+      they are larger than the threshold.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135A0"></a>Data Cache Memory Allocation</h3>
+</div>
+</div>
+</div>
+<p>With CACHED tables, the data is stored on disk and only up to a
+      maximum number of rows are held in memory at any time. The default is up
+      to 50,000 rows. The SET FILES CACHE ROWS command or the
+      <span class="property">hsqldb.cache_rows</span> connection property can be set to
+      alter this amount. As any random subset of the rows in any of the CACHED
+      tables can be held in the cache, the amount of memory needed by cached
+      rows can reach the sum of the rows containing the largest field data.
+      For example if a table with 100,000 rows contains 40,000 rows with 1,000
+      bytes of data in each row and 60,000 rows with 100 bytes in each, the
+      cache can grow to contain 50,000 of the smaller rows, but as explained
+      further, only 10,000 or the large rows.</p>
+<p>An additional property, <span class="property">hsqldb.cache_size</span> is
+      used in conjunction with the <span class="property">hsqldb.cache_rows</span>
+      property. This puts a limit in bytes on the total size of rows that are
+      cached. The default values is 10,000KB. (This is the size of binary
+      images of the rows and indexes. It translates to more actual memory,
+      typically 2-4 times, used for the cache because the data is represented
+      by Java objects.)</p>
+<p>If memory is limited, the <span class="property">hsqldb.cache_rows</span>
+      or <span class="property">hsqldb.cache_size</span> database properties can be
+      reduced. In the example above, if the
+      <span class="property">hsqldb.cache_size</span> is reduced from 10,000 to 5,000,
+      it will allow the number of cached rows to reach 50,000 small rows, but
+      only 5,000 of the larger rows.</p>
+<p>Data for CLOB and BLOB columns is not cached and does not affect
+      the CACHED table memory cache.</p>
+<p>The use of Java nio file access method also increases memory
+      usage. Access with nio improves database update speed and is used by
+      default for data files up to 256 MB. For minimal memory use, nio access
+      should be disabled.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135BF"></a>Object Pool Memory Allocation</h3>
+</div>
+</div>
+</div>
+<p>HyperSQL uses a set of fast pools for immutable objects such as
+      Integer, Long and short String objects that are stored in the database.
+      In most circumstances, this reduces the memory footprint still further
+      as fewer copies of the most frequently-used objects are kept in memory.
+      The object pools are shared among all databases in the JVM. The size of
+      each pool can be modified only by altering and recompiling the
+      <code class="literal">org.hsqldb.store.ValuePool</code> class.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135C7"></a>Lob Memory Usage</h3>
+</div>
+</div>
+</div>
+<p>Access to lobs is always performed in chunks, so it is perfectly
+      possible to store and access a CLOB or BLOB that is larger than the JVM
+      memory allocation. Early versions of HyperSQL 2.0 use memory-based
+      tables for the lob catalog (not the data). Therefore it is practical to
+      store about 100,000 individual lobs in the database with the default JVM
+      memory allocation. More lobs can be stored with larger JVM memory
+      allocations. The realistic maximum number of lobs stored in the database
+      is probably about a million. The actual total size of lobs is almost
+      unlimited. We have tested with over 100 GB of lobs without any loss of
+      performance.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135CC"></a>Disk Space</h3>
+</div>
+</div>
+</div>
+<p>With file: database, the engine uses the disk for storage of data
+      and any change. For safely, the engine backs up the data internally
+      during operation. Spare space, at least equal to the size of the .data
+      and .script file is needed. The .lobs file is not backed up during
+      operation.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deployment_conns-sect"></a>Managing Database Connections</h2>
+</div>
+</div>
+</div>
+<p>In all running modes (server or <em class="glossterm">in-process</em>)
+    multiple connections to the database engine are supported.
+    <em class="glossterm">in-process</em> (standalone) mode supports connections
+    from the client in the same Java Virtual Machine, while server modes
+    support connections over the network from several different
+    clients.</p>
+<p>Connection pooling software can be used to connect to the database
+    but it is not generally necessary. Connection pools may be used for the
+    following reasons.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>To allow new queries to be performed while a time-consuming
+        query is being performed in the background. In HyperSQL, blocking
+        depends on the transaction control model, the isolation level, and the
+        current activity by other sessions.</p>
+</li>
+<li>
+<p>To limit the maximum number of simultaneous connections to the
+        database for performance reasons. With HSQLDB this can be useful if
+        your application is designed in a way that opens and closes
+        connections for each small task. Also, the overall performance may be
+        higher when fewer simultaneous connections are used. If you want to
+        reduce the number of simultaneous sessions, you can use a connection
+        pool with fewer pooled connections.</p>
+</li>
+</ul>
+</div>
+<p>An application that is not both multi-threaded and transactional,
+    such as an application for recording user login and logout actions, does
+    not need more than one connection. The connection can stay open
+    indefinitely and reopened only when it is dropped due to network
+    problems.</p>
+<p>When using an <em class="glossterm">in-process</em> database, when the
+    last connection to the database is closed, the database still remains
+    open. An explicit SHUTDOWN command, with or without an argument, is
+    required to close the database. A connection property on the connection
+    URL or in a properties object can be used to shutdown the database when
+    the last connection is closed.</p>
+<p>When using a server database (and to some extent, an
+    <em class="glossterm">in-process</em> database), care must be taken to avoid
+    creating and dropping JDBC Connections too frequently. Failure to observe
+    this will result in poor performance when the application is under heavy
+    load.</p>
+<p>A common error made by users in load-test simulations is to use a
+    single client machine to open and close thousands of connections to a
+    HyperSQL server instance. The connection attempts will fail after a few
+    thousand because of OS restrictions on opening sockets and the delay that
+    is built into the OS in closing them.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N135F4"></a>Tweaking the Mode of Operation</h2>
+</div>
+</div>
+</div>
+<p>Different modes of operation and settings are used for different
+    purposes. Some scenarios are discussed below:</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N135F9"></a>Application Development and Testing</h3>
+</div>
+</div>
+</div>
+<p>For application unit testing you can use an all-in-memory,
+      in-process database.</p>
+<p>If the tests are all run in one process, then the contents of a
+      <em class="glossterm">mem:</em> database survives between tests. To release
+      the contents you can use the SHUTDOWN command (an SQL command). You can
+      even use multiple <em class="glossterm">mem:</em> databases in your tests
+      and SHUTDOWN each one separately.</p>
+<p>If the tests are in different processes and you want to keep the
+      data between the tests, the best solution is to use a Server instance
+      that has a <em class="glossterm">mem:</em> database. After the tests are
+      done, you can SHUTDOWN this database, which will shutdown the
+      server.</p>
+<p>The Server has an option that allows databases to be created as
+      needed by making a connection (see the Listeners Chapter). This option
+      is useful for testing, as your server is never shut down. Each time you
+      connect to the <em class="glossterm">mem:</em> database that is served by
+      the Server, the database is created if it does not exist (i.e. has been
+      previously shut down).</p>
+<p>If you do not want to run a Server instance, and you need
+      persistence between tests in different processes, then you should use a
+      <em class="glossterm">file:</em> database. You can use the
+      <code class="literal">shutdown=true</code> connection property to ensure the
+      database is persisted fully after the connections are closed. An
+      alternative option is to use <code class="literal">hsqldb.write_delay=false</code>
+      connection property, but this is slightly slower than the other
+      option.</p>
+<p>It has been reported that some data access frameworks do not close
+      all their connection to the database after the tests. In such
+      situations, you need to use zero WRITE DELAY if you want the data to
+      persist at the end of the tests</p>
+<p>You may actually want to use a <em class="glossterm">file:</em>
+      database, or a server instance that serves a
+      <em class="glossterm">file:</em> database in preference to a
+      <em class="glossterm">mem:</em> database. As HyperSQL logs the DDL and DML
+      statements in the .log file, this file can be used to check what is
+      being sent to the database. Note that UPDATE statements are represented
+      by a DELETE followed by an INSERT statement. Statements are written out
+      when the connection commits. The write delay also has an effect on how
+      soon the statements are written out.</p>
+<p>Some types of tests start with a database that already contains
+      the tables and data, and perform various operations on it during the
+      tests. You can create and populate the initial database then set the
+      property "files_read_only=true" in the .properties file of the database.
+      The tests can then modify the database, but these modifications are not
+      persisted after the tests have completed.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1362A"></a>Embedded Databases in Desktop Applications</h3>
+</div>
+</div>
+</div>
+<p>In this usage, the amount of data change is often limited and
+      there is often a requirement to persist the data immediately. You can
+      use the property <code class="literal">write_delay=false</code> to force a disk
+      sync after each commit. Before the application is closed, you should
+      perform the SHUTDOWN command to ensure the database is opened instantly
+      when it is next opened.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13632"></a>Embedded Databases in Server Applications</h3>
+</div>
+</div>
+</div>
+<p>This usage involves a server application, such as a web
+      application, connecting to an embedded HyperSQL instance. In this usage,
+      the database is often accessed heavily, therefore performance and
+      latency is a consideration. If the database is updated heavily, the
+      default value of the WRITE DELAY property (1 sec) is often enough, as it
+      is assumed the server or the application does not go down frequently. If
+      it is necessary, you can reduce the WRITE DELAY to a small value (20 ms)
+      without impacting the update speed. If you reduce WRITE DELAY to zero,
+      performance drops to the speed of disk file sync operation.</p>
+<p>Alternatively, a server application can use an all-in-mem database
+      instance for fast access, while sending the data changes to a
+      persistent, disk based instance either periodically or in real
+      time.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13639"></a>Embedding a Database Listener</h3>
+</div>
+</div>
+</div>
+<p>Since you won't be able to access
+      <em class="glossterm">in-process</em> database instances from other
+      processes, you will often want to run a Listener in your server
+      applications with embedded databases. You can do this by starting up a
+      Server or WebServer instance programmatically, but you could also use
+      the class <code class="classname">org.hsqldb.util.MainInvoker</code> to start up
+      your application and a Server or WebServer without any programming.
+      <div class="example">
+<a name="N13644"></a>
+<p class="title">
+<b>Example&nbsp;11.1.&nbsp;MainInvoker Example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  java -cp path/to/your/app.jar:path/to/hsqldb.jar your.App "" org.hsqldb.server.Server</pre>
+</div>
+</div>
+<br class="example-break"> (Use ; instead of : to delimit classpath elements on
+      Windows). Specify the same <em class="glossterm">in-process</em> JDBC URL to
+      your app and in the <code class="filename">server.properties</code> file. You can
+      then connect to the database from outside using a JDBC URL like
+      <code class="literal">jdbc:hsqldb:hsql://hostname</code>.</p>
+<p>This tactic can be used to run off-the-shelf server
+      applications with an embedded HyperSQL Server, without doing any
+      coding.</p>
+<p>
+<code class="classname">MainInvoker</code> can be used to run any
+      number of Java class main method invocations in a single JVM. See the
+      API spec for <code class="classname"><a class="classname" href="#MainInvoker.html-link">
+      MainInvoker</a></code> for details on its usage.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1365D"></a>Using HyperSQL Without Logging</h3>
+</div>
+</div>
+</div>
+<p>All file database that are not readonly, write changes to the .log
+      file. There are scenarios where writing to the .log file can be turned
+      off to improve performance, especially with larger databases. For these
+      applications you can set the property
+      <code class="literal">hsqldb.log_data=false</code> to disable the recovery log and
+      speed up data change performance. The equivalent SQL command is SET
+      FILES LOG FALSE.</p>
+<p>With this setting, no data is logged, but all the changes to
+      cached tables are written to the .data file. To persist all the data
+      changes up to date, you can use the CHECKPOINT command. If you perform
+      SHUTDOWN, the data is also persisted correctly. If you do not use
+      CHECKPOINT or SHUTDOWN. All the changes are lost and the database
+      reverts to its original state when it is opened.</p>
+<p>Your server applications can use a database as a temporary disk
+      data cache which is not persisted past the lifetime of the application.
+      For this usage, delete the database files when the application
+      ends.</p>
+<p>On some platforms, such as embedded devices which are reliable,
+      this is also a useful option. Your application issues CHECKPOINT to save
+      the changes made so far. This method of use reduces write operations on
+      SSD devices. For this usage, the lock file should also be disabled with
+      the connection property hsqldb.lock_file=false.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1366B"></a>Server Databases</h3>
+</div>
+</div>
+</div>
+<p>Running databases in a HyperSQL server is the best overall method
+      of access. As the JVM process is separate from the application, this
+      method is the most reliable as well as the most accessible method of
+      running databases.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deployment_upgrade-sect"></a>Upgrading Databases</h2>
+</div>
+</div>
+</div>
+<a name="N13674" class="indexterm"></a>
+<p>Any database that is not produced with the release version of
+    HyperSQL 2.0 must be upgraded to this version. Most catalogs created with
+    1.8.x can be upgraded simply by opening with HyperSQL 2. When this is not
+    possible due to errors, the rest of the procedures below should be
+    followed.</p>
+<p>Once a database is upgraded to 2.0, it can no longer be used with
+    previous versions of HyperSQL.</p>
+<p>If your database has been created with version 1.7.x, first upgrade
+    to version 1.8.1 and perform a SHUTDOWN COMPACT with this version. You can
+    then open and upgrade the database with version 2.0.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="upgrade_via_script-sect"></a>Upgrading From Older
+      Versions</h3>
+</div>
+</div>
+</div>
+<p>To upgrade from version 1.8.x with the default TEXT format script
+      files, simply open the database with 2.0. If the version 1.8.x files
+      have database script format set to BINARY or COMPRESSED (ZIPPED) you
+      must issue the SET SCRIPTFORMAT TEXT and SHUTDOWN SCRIPT commands with
+      the old version, then open with the new version of the engine. In most
+      cases the upgrade is successful and complete.</p>
+<p>It is strongly recommended to execute SHUTDOWN COMPACT after an
+      automatic upgrade from previous versions.</p>
+<p>If your database has been created with version 1.7.2 or 1.7.3,
+      first upgrade to version 1.8.1 and perform a SHUTDOWN COMPACT with this
+      version. You can then upgrade the database to version 2.0.</p>
+<p>To upgrade from older version database files (1.7.1 and older)
+      that contain CACHED tables, use the SCRIPT procedure below. In all
+      versions of HyperSQL, the <code class="literal">SCRIPT 'filename'</code> command
+      (used as an SQL statement) allows you to save a full record of your
+      database, including database object definitions and data, to a file of
+      your choice. You can export a script file using the old version of the
+      database engine and open the script as a database with 2.0.</p>
+<div class="procedure">
+<a name="N1368E"></a>
+<p class="title">
+<b>Procedure&nbsp;11.1.&nbsp;Upgrade Using the SCRIPT Procedure for Very Old
+        Versions</b>
+</p>
+<ol type="1">
+<li>
+<p>Open the original database in the old version of
+          DatabaseManager</p>
+</li>
+<li>
+<p>Issue the SCRIPT command, for example <code class="literal">SCRIPT
+          'newversion.script'</code> to create a script file containing a
+          copy of the database.</p>
+</li>
+<li>
+<p>SHUTDOWN this database.</p>
+</li>
+<li>
+<p>Copy the original <code class="literal">*.properties</code> file into
+          <code class="filename">newversion.properties</code> in the same directory as
+          <code class="filename">newversion.script</code>
+</p>
+</li>
+<li>
+<p>Try to open the new database <code class="filename">newversion</code>
+          using DatabaseManager of version 1.8.1.</p>
+</li>
+<li>
+<p>If there is any inconsistency in the data, the script line
+          number is reported on the console and the opening process is
+          aborted. Edit and correct any problems in the
+          <code class="filename">newversion.script</code> before attempting to open
+          again. Use the guidelines in the next section (Manual Changes to the
+          <code class="literal">.script</code> File). Use a programming editor that is
+          capable of handling very large files and does not wrap long lines of
+          text.</p>
+</li>
+</ol>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N136B7"></a>Manual Changes to the *.script File</h3>
+</div>
+</div>
+</div>
+<p>In HyperSQL 2.0 the full range of ALTER TABLE commands is
+      available to change the data structures and their names. However, if an
+      old database cannot be opened due to data inconsistencies, or it uses
+      index or column names that are not compatible with 2.0, manual editing
+      of the <code class="literal">*.script</code> file can be performed.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Version 2.0 does not accept duplicate names for indexes that
+          were allowed before 1.7.2.</p>
+</li>
+<li>
+<p>Version 2.0 does not accept some table or column names that
+          are SQL reserved keywords without double quoting.</p>
+</li>
+<li>
+<p>Version 2.0 is more strict with check conditions and default
+          values.</p>
+</li>
+</ul>
+</div>
+<p>Other manual changes are also possible. Note that the
+      <code class="literal">*.script</code> file must be the result of a SHUTDOWN SCRIPT
+      and must contain the full data for the database. The following changes
+      can be applied so long as they do not affect the integrity of existing
+      data.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Names of tables, columns and indexes can be changed. These
+          changes must be consistent regarding foreign key constraints.</p>
+</li>
+<li>
+<p>
+<code class="literal">CHECK</code>
+</p>
+<p>A check constraint can always be removed.</p>
+</li>
+<li>
+<p>
+<code class="literal">NOT NULL</code>
+</p>
+<p>A not-null constraint can always be removed.</p>
+</li>
+<li>
+<p>
+<code class="literal">PRIMARY KEY</code>
+</p>
+<p>A primary key constraint can be removed. It cannot be removed
+          if there is a foreign key referencing the column(s).</p>
+</li>
+<li>
+<p>
+<code class="literal">UNIQUE</code>
+</p>
+<p>A UNIQUE constraint can be removed if there is no foreign key
+          referencing the column(s).</p>
+</li>
+<li>
+<p>
+<code class="literal">FOREIGN KEY</code>
+</p>
+<p>A FOREIGN KEY constraint can always be removed.</p>
+</li>
+<li>
+<p>
+<code class="literal">COLUMN TYPES</code>
+</p>
+<p>Some changes to column types are possible. For example an
+          INTEGER column can be changed to BIGINT.</p>
+</li>
+</ul>
+</div>
+<p>After completing the changes and saving the modified
+      <code class="literal">.script</code> file, you can open the database as
+      normal.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N136FB"></a>Backward Compatibility Issues</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL 2.0 conforms to the SQL Standard better than previous
+    versions and supports more features. For these reasons, there may be some
+    compatibility issues when converting old database, or using applications
+    that were written for version 1.8.x or earlier. Some of the potential
+    issues are listed here.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>User names and passwords are case-sensitive. Check the .script
+        file of a database for the correct case of user name and password and
+        use this form in the connection properties or on connection
+        URL.</p>
+</li>
+<li>
+<p>Check constraints must conform to the SQL Standard. A check
+        constraint is rejected if it is not deterministic or retrospectively
+        deterministic. When opening an old database, HyperSQL silently drops
+        check constraints that no longer compile. See under check constraints
+        for more detail about what is not allowed.</p>
+</li>
+<li>
+<p>Type declarations in column definition and in cast expressions
+        must have the necessary size parameters.</p>
+</li>
+<li>
+<p>In connection with the above, an old database that did not have
+        the <code class="literal">enforce_strict_size</code> property, is now converted
+        to version 2.0 with the engine supplying the missing size parameters.
+        For example, a VARCHAR column declaration that has no size, is given a
+        32K size. Check these sizes are adequate for your use, and change the
+        column definition as necessary.</p>
+</li>
+<li>
+<p>Column names in a GROUP BY clause were previously resolved to
+        the column label. They are now resolved to column name first, and if
+        the name does not match, to the column label.</p>
+</li>
+<li>
+<p>If two or more tables in a join contain columns with the same
+        name, the columns cannot be referenced in join and where conditions.
+        Use table names before column names to qualify the references to such
+        columns.</p>
+</li>
+<li>
+<p>Table definitions containing GENERATED BY DEFAULT AS IDENTITY
+        but with no PRIMARY KEY do not automatically create a primary key.
+        Database .script files made with 1.8 are fine, as the PRIMARY KEY
+        clause is always included. But your application program may assume an
+        automatic primary key is created.</p>
+</li>
+<li>
+<p>CREATE ALIAS is now obsolete. Use the new function definition
+        syntax. The <code class="classname">org.hsqldb.Library </code>class no longer
+        exists. You should use the SQL form of the old library functions. For
+        example, use <code class="literal">LOG(x)</code> rather than the direct form,
+        <code class="literal">"org.hsqldb.Library.log"(x)</code>.</p>
+</li>
+<li>
+<p>The names of some commands for changing database and session
+        properties have changed. See the list of statements in this
+        chapter.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="deployment_backup-sect"></a>Backing Up Database Catalogs</h2>
+</div>
+</div>
+</div>
+<a name="N1372C" class="indexterm"></a>
+<p>The database engine saves the files containing all the data in a
+    file catalog when a shutdown takes place. It automatically recovers from
+    an abnormal termination and preserves the data when the catalog is opened
+    next time. In an ideal operating environment, where there is no OS crash,
+    disk failure, bugs in code, etc. there would be no need regularly to
+    backup a database. This is meant to say, the engine performs the routine
+    shutdown procedure internally, therefore backing up catalogs is an
+    insurance policy against all sorts of misadventure that are not under the
+    control of the database engine.</p>
+<p>The data for each catalog consists of up to 5 files in the same
+    directory with the endings such as <code class="literal">*.properties</code>,
+    <code class="literal">*.script</code>, etc., as detailed in previous
+    chapters.</p>
+<p>HyperSQL 2.0 includes commands to backup the database files into
+    a single <code class="literal">.tar</code> or <code class="literal">.tar.gz</code> file
+    archive. The backup can be performed by a command given in a JDBC session
+    if the target database catalog is running, or on the command-line if the
+    target catalog has been shutdown.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13742"></a>Making Online Backups</h3>
+</div>
+</div>
+</div>
+<p>To back up a running catalog, obtain a JDBC connection and
+      issue a <code class="literal">BACKUP DATABASE</code> command in SQL. In its most
+      simple form, the command format below will backup the database as a
+      single <code class="literal">.tar.gz</code> file to the given directory.</p>
+<pre class="programlisting">  BACKUP DATABASE TO &lt;directory name&gt; BLOCKING</pre>
+<p>See the next section under Statements for details about the
+      command and its options. See the sections below about restoring a
+      backup.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13751"></a>Making Offline Backups</h3>
+</div>
+</div>
+</div>
+<p>To back up an offline catalog, the catalog must be in shut down
+      state. You will run a Java command like this <div class="example">
+<a name="N13756"></a>
+<p class="title">
+<b>Example&nbsp;11.2.&nbsp;Offline Backup Example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --save  \
+  tar/path.tar db/base/path</pre>
+</div>
+</div>
+<br class="example-break">where <code class="filename">tar/path.tar</code> is a file path to
+      the <code class="literal">*.tar</code> or <code class="literal">*.tar.gz</code> file to be
+      created, and <code class="filename">db/base/path</code> is the file path to the
+      catalog file base name (in same fashion as in
+      <code class="varname">server.database.*</code> settings and JDBC URLs with catalog
+      type <em class="glossterm">file:</em>.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1376E"></a>Examining Backups</h3>
+</div>
+</div>
+</div>
+<p>You can list the contents of backup tar files with
+      <code class="classname">DbBackup</code> on your operating system command line,
+      or with any Pax-compliant tar or pax client (this includes GNU tar),
+      <div class="example">
+<a name="N13776"></a>
+<p class="title">
+<b>Example&nbsp;11.3.&nbsp;Listing a Backup with DbBackup</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --list tar/path.tar</pre>
+</div>
+</div>
+<br class="example-break">You can also give regular expressions at the end of the
+      command line if you are only interested in some of the file entries in
+      the backup. Note that these are real regular expressions, not shell
+      globbing patterns, so you would use <code class="literal">.+script</code> to match
+      entries ending in "script", not <code class="literal">*script</code>.</p>
+<p>You can examine the contents of the backup in their entirety by
+      restoring the backup, as explained in the following section, to a
+      temporary directory.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N13784"></a>Restoring a Backup</h3>
+</div>
+</div>
+</div>
+<p>You use <code class="classname">DbBackup</code> on your operating system
+      command line to restore a catalog from a backup. <div class="example">
+<a name="N1378C"></a>
+<p class="title">
+<b>Example&nbsp;11.4.&nbsp;Restoring a Backup with DbBackup</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup --extract  \
+      tar/path.tar db/dir</pre>
+</div>
+</div>
+<br class="example-break">where <code class="filename">tar/path.tar</code> is a file path to
+      the *.tar or *.tar.gz file to be read, and <code class="filename">db/dir</code>
+      is the target directory to extract the catalog files into. Note that
+      <code class="filename">db/dir</code> specifies a directory path, without the
+      catalog file base name. The files will be created with the names stored
+      in the tar file (and which you can see as described in the preceding
+      section).</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1379B"></a>Encrypted Databases</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL supports encrypted databases. Encryption services use the
+    Java Cryptography Extensions (JCE) and uses the ciphers installed with the
+    JRE. HyperSQL itself does not contain any cryptography code.</p>
+<p>Three elements are involved in specifying the encryption method and
+    key. A cipher, together with its configuration is identified by a string
+    which includes the name of the cipher and optional parameters. A provider
+    is the fully qualified class name of the cipher provider. A key is
+    represented as a hexadecimal string.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137A2"></a>Creating and Accessing an Encrypted Database</h3>
+</div>
+</div>
+</div>
+<p>First, a key must be created for the desired cipher and
+      configuration. This is done by calling the function CRYPT_KEY(&lt;cipher
+      spec&gt;, &lt;provider&gt;). If the default provider (the built-in JVM
+      ciphers) is used, then NULL should be specified as the provider. The
+      CRYPT_KEY function returns a hexadecimal key. The function call can be
+      made in any HyperSQL database, so long as the provider class is on the
+      classpath. This key can be used to create a new encrypted database.
+      Calls to this function always return different keys, based on a
+      generated random values.</p>
+<p>As an example, a call to CRYPT_KEY('Blowfish', null) returned the
+      string, '604a6105889da65326bf35790a923932'. To create a new database,
+      the URL below is used:</p>
+<p>
+<code class="literal">jdbc:hsqldb:file:&lt;database
+      path&gt;;crypt_key=604a6105889da65326bf35790a923932;crypt_type=blowfish</code>
+</p>
+<p>The third property name is crypt_provider. This is specified only
+      when the provider is not the default provider.</p>
+<p>HyperSQL works with any symmetric cipher that may be available
+      from the JVM.</p>
+<p>The files that are encrypted include the .script, .data, .backup
+      and .log files. The .lobs file is not encrypted by default. The property
+      crypt_lobs=true must be specified to encrypt the .lobs file.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137B2"></a>Speed Considerations</h3>
+</div>
+</div>
+</div>
+<p>General operations on an encrypted database are performed the same
+      as with any database. However, some operations are significantly slower
+      than with the equivalent cleartext database. With MEMORY tables, there
+      is no difference to the speed of SELECT statements, but data change
+      statements are slower. With CACHED tables, the speed of all statements
+      is slower.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137B7"></a>Security Considerations</h3>
+</div>
+</div>
+</div>
+<p>Security considerations for encrypted databases have been
+      discussed at length in HSQLDB discussion groups. Development team
+      members have commented that encryption is not a panacea for all security
+      needs. The following issues should be taken into account:</p>
+<p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Encrypted files are relatively safe in transport, but
+            because databases contain many repeated values and words,
+            especially known tokens such as CREATE, INSERT, etc., breaking the
+            encryption of a database may be simpler than an unknown
+            file.</p>
+</li>
+<li>
+<p>Only the files are encrypted, not the memory image. Poking
+            into computer memory, while the database is open, will expose the
+            contents of the database.</p>
+</li>
+<li>
+<p>HyperSQL is open source. Someone who has the key, can
+            compile and use a modified version of the program that saves a
+            full cleartext dump of an encrypted database</p>
+</li>
+</ul>
+</div>Therefore encryption is generally effective only when
+      the users who have access to the crypt key are trusted.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N137C8"></a>Monitoring Database Operations</h2>
+</div>
+</div>
+</div>
+<p>Database operations can be monitored at different levels using
+    internal HyperSQL capabilities or add-ons.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137CD"></a>Statement Level Monitoring</h3>
+</div>
+</div>
+</div>
+<p>Statement level monitoring allows you to gather statistics about
+      executed statements. HyperSQL is supported by the monitoring tool JAMon
+      (Java Application Monitor). JAMon is currently developed as the
+      SourceForge project, jamonapi.</p>
+<p>JAMon works at the JDBC level. It can monitor and gather
+      statistics on different types of executed statements or other JDBC
+      calls.</p>
+<p>Early versions of JAMon were developed with HSQLDB and had to be
+      integrated into HSQLDB at code level. The latest versions can be added
+      on as a proxy in a much simpler fashion.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137D6"></a>Internal Event Monitoring</h3>
+</div>
+</div>
+</div>
+<p>HyperSQL can log important internal events of the engine. These
+      events occur during the operation of the engine, and are not always
+      coupled with the exact type of statement being executed. Normal events
+      such as opening and closing of files, or errors such as OutOfMemory
+      conditions are examples of logged events.</p>
+<p>HyperSQL supports two methods of logging. One method is specific
+      to the individual database and is managed internally by HyperSQL. The
+      other method is specific to JVM and is managed by a logging
+      framework.</p>
+<p>The internally-generated, individual log for the database can be
+      enabled with the <code class="literal">SET DATABASE EVENT LOG LEVEL</code>
+      statement, described in the next section. This method of logging is very
+      useful for desktop application deployment, as it provides an ongoing
+      record of database operations.</p>
+<p>HyperSQL also supports log4J and JDK logging. The same event
+      information that is passed to the internal log, is passed to external
+      logging frameworks. These frameworks are configured outside HyperSQL.
+      The log messages include the unique id of the database that generated
+      the message, so it can be identified in a multi-database server
+      context.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N137E4"></a>Server Operation Monitoring</h3>
+</div>
+</div>
+</div>
+<p>A Server or WebServer instance can be started with the property
+      server.silent=false. This causes all the connections and their executed
+      statements to be printed to stdout as the statements are submitted to
+      the server.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N137E9"></a>Statements</h2>
+</div>
+</div>
+</div>
+<p>System level statements are listed in this section. Statements that
+    begin with SET DATABASE or SET FILES are for properties that have an
+    effect on the normal operation of HyperSQL. The effects of these
+    statements are also discussed in different chapters.</p>
+<a name="N137EE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SHUTDOWN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>shutdown statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;shutdown statement&gt; ::= SHUTDOWN [IMMEDIATELY |
+    COMPACT | SCRIPT]</code>
+</p>
+<p>Shutdown the database. If the optional qualifier is not used, a
+    normal SHUTDOWN is performed. A normal SHUTDOWN ensures all data is saved
+    correctly and the database opens without delay on next use.</p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">SHUTDOWN IMMEDIATELY</span>
+</p>
+</td><td>
+<p>Saves the *.log file and closes the database files. This is
+          the quickest form of shutdown. This command should not be used as
+          the routine method of closing the database, because when the
+          database is accessed next time, it may take a long time to
+          start.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">SHUTDOWN COMPACT</span>
+</p>
+</td><td>
+<p>This is similar to normal SHUTDOWN, but reduces the *.data
+          file to its minimum size. It takes longer than normal
+          SHUTDOWN.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">SHUTDOWN SCRIPT</span>
+</p>
+</td><td>
+<p>This is similar to SHUTDOWN COMPACT, but it does not rewrite
+          the <code class="literal">*.data</code> and text table files. After SHUTDOWN
+          SCRIPT, only the <code class="literal">*.script</code> and
+          <code class="literal">*.properties</code> files remain. At the next startup,
+          these files are processed and the <code class="literal">*.data</code> and
+          <code class="literal">*.backup</code> files are created. This command in
+          effect performs part of the job of SHUTDOWN COMPACT, leaving the
+          other part to be performed automatically at the next startup.</p>
+<p>This command produces a full script of the database which can
+          be edited for special purposes prior to the next startup.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13825" class="indexterm"></a>
+<p>
+<span class="bold"><strong>BACKUP DATABASE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>backup database statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;backup database statement&gt; ::= BACKUP DATABASE TO
+    &lt;file path&gt; {SCRIPT | [NOT] COMPRESSED} BLOCKING</code>
+</p>
+<p>Backup the database to specified <code class="literal">&lt;file
+    path&gt;</code> for archiving purposes.</p>
+<p>The <code class="literal">&lt;file path&gt;</code> can be in two forms. If
+    the <code class="literal">&lt;file path&gt;</code> ends with a forward slash, it
+    specifies a directory. In this case, an automatic name for the archive is
+    generated that includes the date, time and the base name of the database.
+    The database is backed up to this archive file in the specified directory.
+    If the <code class="literal">&lt;file path&gt;</code> does not end with a forward
+    slash, it specifies a user-defined file name for the backup archive. The
+    archive is in tar, gzip format depending on whether it is compressed or
+    not.</p>
+<p>The SCRIPT option is not currently supported. If SCRIPT is
+    specified, the backup will consist of two files, a
+    <code class="literal">*.properties</code> file and a <code class="literal">*.script</code>
+    file, which contain all the data and settings of the database. These files
+    are not compressed.</p>
+<p>If COMPRESSED or NOT COMPRESSED is specified, the backup consists
+    of the current snapshot of database files. During backup, a CHECKPOINT
+    command is silently executed.</p>
+<p>The qualifier, BLOCKING, means all database operations are
+    suspended during backup.</p>
+<p>The HyperSQL jar also contains a program that creates an archive
+    of an offline database. It also contains a program to expand an archive
+    into database files. These programs are documented in this chapter under
+    Backing up Database Catalogs.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13854" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CHECKPOINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>checkpoint statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;checkpoint statement&gt; ::= CHECKPOINT
+    [DEFRAG]</code>
+</p>
+<p>Closes the database files, rewrites the script file, deletes the
+    log file and opens the database. If <code class="literal">DEFRAG</code> is
+    specified, also shrinks the <code class="literal">*.data</code> file to its minumum
+    size. Only a user with the DBA role can execute this statement.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N1386D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CRYPT_KEY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>crypt_key function</em></span>
+</p>
+<p>
+<code class="literal">&lt;crypt_key function&gt; ::= CRYPT_KEY ( &lt;cipher
+    spec&gt;, &lt;provider&gt; )</code>
+</p>
+<p>The statement, <code class="literal">CALL CRYPT_KEY( &lt;cipher spec&gt;,
+    &lt;provider&gt; )</code> returns a binary string representing a valid
+    key for the giver cipher and provider. The
+    <code class="literal">&lt;provider&gt;</code> argument is specified as NULL for the
+    default provider.</p>
+<a name="N13884" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SCRIPT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>script statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;script statement&gt; ::= SCRIPT [&lt;file
+    name&gt;]</code>
+</p>
+<p>Returns a script containing SQL statements that define the
+    database, its users, and its schema objects. If <code class="literal">&lt;file
+    name&gt;</code> is not specified, the statements are returned in a
+    ResultSet, with each row containing an SQL statement. No data statements
+    are included in this form. The optional file name is a single-quoted
+    string. If <code class="literal">&lt;file name&gt;</code> is specified, then the
+    script is written to the named file. In this case, all the data in all
+    tables of the database is included in the script as INSERT
+    statements.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N1389D" class="indexterm"></a><a name="N138A2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE COLLATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database collation statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database collation statement&gt; ::= SET
+    DATABASE COLLATION &lt;collation name&gt;</code>
+</p>
+<p>Each database can have its own collation. Sets the collation from
+    the set of collations supported by HyperSQL. Once this command has been
+    issued, the database can be opened in any JVM and will retain its
+    collation. Only a user with the DBA role can execute this
+    statement.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N138B5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE DEFAULT TABLE
+    TYPE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database default table type
+    statement</em></span><code class="literal"> </code>
+</p>
+<p>
+<code class="literal">&lt;set database default table type&gt; ::= SET DATABASE
+    DEFAULT TABLE TYPE { CACHED | MEMORY }</code>
+</p>
+<p>Sets the type of table created when the next CREATE TABLE
+    statement is executed. The default is MEMORY.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N138CA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE DEFAULT RESULT MEMORY
+    ROWS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database default result memory rows
+    statement</em></span><code class="literal"> </code>
+</p>
+<p>
+<code class="literal">&lt;set database default result memory rows&gt; ::= SET
+    DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned integer
+    literal&gt;</code>
+</p>
+<p>Sets the maximum number of rows of each result set and other
+    internal temporary table that is held in memory. This setting applies to
+    all sessions. Individual sessions can change the value with the
+    <code class="literal">SET SESSION RESULT MEMORY ROWS</code> command. The default is
+    0, meaning all result sets are held in memory.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N138E2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE EVENT LOG
+    LEVEL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database event log level
+    statement*</em></span><code class="literal"> </code>
+</p>
+<p>
+<code class="literal">&lt;set database event log level&gt; ::= SET DATABASE
+    EVENT LOG LEVEL { 0 | 1 | 2 }</code>
+</p>
+<p>Sets the amount of information logged in the internal,
+    database-specific event log. Level 0 means no log. Level 1 means only
+    important (error) events. Level 2 means more events, including both
+    important and less important (normal) events. For readonly and
+    <em class="glossterm">mem:</em> databases, if the level is set above 0, the
+    log messages are directed to stderr.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N138FA" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE GC</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database gc statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database gc statement&gt; ::= SET DATABASE GC
+    &lt;unsigned integer literal&gt;</code>
+</p>
+<p>An optional property which forces calls to <code class="literal">System.gc()
+    </code>after the specified number of row operations. The default value
+    for this property is 0, which means no System.gc() calls. Usual values for
+    this property range from 10000 depending on the system and the memory
+    allocation. This property may be useful in some in-process deployments,
+    especially with older JVM implementations.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13910" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE SQL SIZE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database sql size statement</em></span><code class="literal">
+    </code>
+</p>
+<p>
+<code class="literal">&lt;set database sql size statement&gt; ::= SET DATABASE
+    SQL SIZE { TRUE | FALSE }</code>
+</p>
+<p>Enable or disable enforcement of column sizes for CHAR and
+    VARCHAR columns. The default is TRUE, meaning table definition must
+    contain <code class="literal">VARCHAR(n)</code> instead of
+    <code class="literal">VARCHAR</code>.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N1392B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE SQL NAMES</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database sql names statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database sql names statement&gt; ::= SET
+    DATABASE SQL NAMES { TRUE | FALSE }</code>
+</p>
+<p>Enable or disable full enforcement of the rule that prevents SQL
+    keywords being used for database object names such as columns and tables.
+    The default is FALSE, meaning disable.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N1393E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE SQL
+    REFERENCES</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database sql references
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database sql references statement&gt; ::= SET
+    DATABASE SQL REFERENCES { TRUE | FALSE }</code>
+</p>
+<p>This command can enable or disable full enforcement of the rule
+    that prevents ambiguous column references in SQL statements (usually
+    SELECT statements). A column reference is ambiguous when it is not
+    qualified by a table name or table alias and can refer to more than one
+    column in a JOIN list.</p>
+<p>The property is FALSE by default. It is better to enable this
+    check while development, to improve the quality and correctness of SQL
+    statements.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13953" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE REFERENTIAL
+    INTEGRITY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database referential integrity
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database referential integrity statement&gt; ::=
+    SET DATABASE REFERENTIAL INTEGRITY { TRUE | FALSE }</code>
+</p>
+<p>This command enables or disables the enforcement of referential
+    integrity constraints (foreign key constraints), check constraints apart
+    from NOT NULL and triggers. By default, referential integrity constraints
+    are checked.</p>
+<p>The only legitimate use of this statement is before importing
+    large amounts of external data into tables that have existing FOREIGN KEY
+    constraints. After import, the statement must be used again to enable
+    constraint enforcement.</p>
+<p>If you are not sure the data conforms to the constraints, run
+    queries to verify all rows conform to the FOREIGN KEY constraints and take
+    appropriate actions for the rows that do not conform.</p>
+<p>A query example to return the rows in a foreign key table that
+    have no parent is given below:</p>
+<div class="example">
+<a name="N1396A"></a>
+<p class="title">
+<b>Example&nbsp;11.5.&nbsp;Finding foreign key rows with no parents after a bulk
+      import</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  SELECT * FROM foreign_key_table LEFT OUTER JOIN primary_key_table 
+    ON foreign_key_table.fk_col = primary_key_table.pk_col WHERE primary_key_table.pk_col IS NULL</pre>
+</div>
+</div>
+<br class="example-break">
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13971" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE UNIQUE
+    NAME</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database unique name</em></span><code class="literal">
+    </code>
+</p>
+<p>
+<code class="literal">&lt;set database unique name statement&gt; ::= SET
+    DATABASE UNIQUE NAME &lt;identifier&gt;</code>
+</p>
+<p>Each HyperSQL catalog (database) has an engine-generated internal
+    name. This name is based on the time of creation of the database and is
+    exactly 16 characters. The name is used for in log events sent to external
+    logging frameworks. This name can be changed by an administrator. The new
+    name must be exactly 16 characters long.</p>
+<a name="N13984" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE TRANSACTION
+    CONTROL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database transaction control
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database transaction control statement&gt; ::=
+    SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC
+    }</code>
+</p>
+<p>Set the concurrency control system for the database. It can be
+    issued only when all sessions have been committed or rolled back. This
+    command and its modes is discussed in the <a class="link" href="#sqlroutines-chapt" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">Sessions and Transactions</a> chapter.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<p>
+<span class="bold"><strong>SET FILES BACKUP INCREMENT
+    </strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files backup increment
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database backup increment statement&gt; ::= SET
+    FILES BACKUP INCREMENT { TRUE | FALSE }</code>
+</p>
+<p>Older versions of HSQLDB perform a backup of the .data file
+    before its contents are modified and the whole .data file is saved in a
+    compressed form when a CHECKPOINT or SHUTDOWN is performed. This takes a
+    long time when the size of the database exceeds 100 MB or so (on an
+    average 2010 computer, you can expect a backup speed of 20MB / s or
+    more).</p>
+<p>The alternative is backup in increments, just before some part of
+    the .data file is modified. In this mode, no backup is performed at
+    CHECKPIONT or SHUTDOWN. This mode is preferred for large databases which
+    are opened and closed frequently.</p>
+<p>The default mode is TRUE. If the old method of backup is
+    preferred, the mode can be set FALSE.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N139AD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES CACHE ROWS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files cache rows statement</em></span><code class="literal">
+    </code>
+</p>
+<p>
+<code class="literal">&lt;set files cache rows statement&gt; ::= SET FILES
+    CACHE ROWS &lt;unsigned integer literal&gt;</code>
+</p>
+<p>Sets the maximum number of rows (of CACHED tables) held in the
+    memory cache.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N139C2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES CACHE SIZE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files cache size statement</em></span><code class="literal">
+    </code>
+</p>
+<p>
+<code class="literal">&lt;set files cache size statement&gt; ::= SET FILES
+    CACHE SIZE &lt;unsigned integer literal&gt;</code>
+</p>
+<p>Sets maximum amount of data (of CACHED tables) in kilobytes held
+    in the memory cache.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N139D7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES DEFRAG</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files defrag statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files defrag statement&gt; ::= SET FILES DEFRAG
+    &lt;unsigned integer literal&gt;</code>
+</p>
+<p>Sets the threshold for performing a DEFRAG during a checkpoint.
+    The <code class="literal">&lt;unsigned integer literal&gt;</code> is the percentage
+    of abandoned space in the <code class="literal">*.data</code> file. When a
+    CHECKPOINT is performed either as a result of the <code class="literal">.log</code>
+    file reaching the limit set by <code class="literal">SET FILES LOG SIZE m</code>, or
+    by the user issuing a CHECKPOINT command, the amount of space abandoned
+    since the database was opened is checked and if it is larger than
+    specified percentage, a CHECKPOINT DEFRAG is performed instead of a
+    CHECKPOINT.</p>
+<p>The default is 0, which indicates no DEFRAG. Useful values are
+    between 10 to 50</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N139F8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES LOG</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files log statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files log statement&gt; ::= SET FILES LOG { TRUE
+    | FALSE }</code>
+</p>
+<p>Sets logging of database operations on or off. Turning logging
+    off is for special usage, such as temporary cache usage.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A0B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES LOG SIZE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files log size statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files log size statement&gt; ::= SET FILES LOG
+    SIZE &lt;unsigned integer literal&gt;</code>
+</p>
+<p>Sets the maximum size in MB of the <code class="literal">*.log</code> file
+    to the specified value. The default maximum size is 50 MB. If the value is
+    zero, no limit is used for the size of the file. When the size of the file
+    reaches this value, a CHECKPOINT is performed and the the
+    <code class="literal">*.log</code> file is cleared to size 0.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A24" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES BACKUP
+    INCREMENT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files backup increment
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files increment backup statement&gt; ::= SET
+    FILES INCREMENT BACKUP { TRUE | FALSE }</code>
+</p>
+<p>This specifies the method for internal backup operation. The
+    default is true.</p>
+<p>During updates, the contents of the .data file is modified. When
+    this property is true, the modified contents are backed up gradually. This
+    causes a marginal slowdown in operations, but allows fast checkpoint and
+    shutdown with large .data files.</p>
+<p>When the property is false, the .data file is backed up entirely
+    at the time of checkpoint and shutdown. Up to version 1.8.0, HSQLDB
+    supported only full backup. Version 1.8.1 supports incremental
+    backup.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A3B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES NIO</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files nio</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files nio statement&gt; ::= SET FILES NIO { TRUE
+    | FALSE }</code>
+</p>
+<p>Changes the access method of the .data file. The default is TRUE
+    and uses the Java nio classes to access the file.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A4E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES WRITE DELAY</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files write delay statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files write delay statement&gt; ::= SET FILES
+    WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds
+    value&gt; MILLIS}</code>
+</p>
+<p>Set the WRITE DELAY property of the database. The WRITE DELAY
+    controls the frequency of file sync for the log file. When WRITE_DELAY is
+    set to FALSE or 0, the sync takes place immediately at each COMMIT. WRITE
+    DELAY TRUE performs the sync once every 10 seconds (which is the default).
+    A numeric value can be specified instead.</p>
+<p>The purpose of this command is to control the amount of data loss in
+    case of a total system crash. A delay of 1 second means at most the data
+    written to disk during the last second before the crash is lost. All data
+    written prior to this has been synced and should be recoverable.</p>
+<p>A write delay of 0 impacts performance in high load situations, as
+    the engine has to wait for the file system to catch up.</p>
+<p>To avoid this, you can set write delay down to 10
+    milliseconds.</p>
+<p>Each time the SET FILES WRITE DELAY statement is executed with any
+    value, a sync is immediately performed. Only a user with the DBA role can
+    execute this statement.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A69" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES SCALE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files scale</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files scale statement&gt; ::= SET FILES SCALE
+    &lt;scale value&gt;</code>
+</p>
+<p>Changes the scale factor for the .data file. The default scale is
+    8 and allows 16GB of data storage capacity. The scale can be increased in
+    order to increase the maximum data storage capacity. The scale values 8,
+    16, 32, 64 and 128 are allowed. Scale value 128 allows a maximum capacity
+    of 256GB.</p>
+<p>This command can be used only when there is no data in CACHED
+    tables.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+<a name="N13A7E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET FILES LOB SCALE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set files lob scale</em></span>
+</p>
+<p>
+<code class="literal">&lt;set files lob scale statement&gt; ::= SET FILES LOB
+    SCALE &lt;scale value&gt;</code>
+</p>
+<p>Changes the scale factor for the .lobs file. The scale is
+    interpreted in kilobytes. The default scale is 32 and allows 64TB of lob
+    data storage capacity. The scale can be reduced in order to improve
+    storage efficiency. If the lobs are a lot smaller than 32 kilobytes,
+    reducing the scale will reduce wasted space. The scale values 1, 2, 4, 8,
+    16, 32 are allowed. For example if the average size of lobs is 4
+    kilobytes, the default scale of 32 will result in 28KB wasted space for
+    each lob. Reducing the lob scale to 2 will result in average 1KB wasted
+    space for each lob.</p>
+<p>This command can be used only when there is no lob in the
+    database.</p>
+<p>Only a user with the DBA role can execute this
+    statement.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="dbproperties-chapt"></a>Chapter&nbsp;12.&nbsp;Properties</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3626 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N13AB9"></a>
+<p>Copyright 2002-2009 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-05 07:49:07 -0400 (Sat, 05 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#dbproperties_connections-sect">Connections</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#conn_props-sect">Connection properties</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N13C11">Database Properties in Connection URL and Properties</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbproperties_connections-sect"></a>Connections</h2>
+</div>
+</div>
+</div>
+<p>The normal method of accessing a HyperSQL catalog is via the JDBC
+    Connection interface. An introduction to different methods of providing
+    database services and accessing them can be found in the <a class="link" href="#sqlgeneral-chapt" title="Chapter&nbsp;2.&nbsp;SQL Language">SQL Language</a> chapter.
+    Details and examples of how to connect via JDBC are provided in our
+    JavaDoc for <code class="classname"><a class="classname" href="#JDBCConnection.html-link">
+    JDBCConnection</a></code>.</p>
+<p>A uniform method is used to distinguish between different types of
+    connection. The common driver identifier is
+    <code class="literal">jdbc:hsqldb:</code> followed by a protocol identifier
+    (<code class="literal">mem: file: res: hsql: http: hsqls: https:</code>) then
+    followed by host and port identifiers in the case of servers, then
+    followed by database identifier. Additional property / value pairs can be
+    appended to the end of the URL, separated with semicolons.</p>
+<div class="table">
+<a name="N13AD2"></a>
+<p class="title">
+<b>Table&nbsp;12.1.&nbsp;HyperSQL URL Components</b>
+</p>
+<div class="table-contents">
+<table summary="HyperSQL URL Components" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Driver and Protocol</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Host and Port</th><th style="border-bottom: 0.5pt solid ; " align="left">Database</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">jdbc:hsqldb:mem:</code></td>
+</tr>
+</table>
+</td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">not available</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">accounts</code></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Lowercase, single-word
+            identifier creates the in-memory database when the first
+            connection is made. Subsequent use of the same Connection URL
+            connects to the existing DB.</p> 
+<p>The old form for the
+            URL, <code class="literal">jdbc:hsqldb:.</code> creates or connects to the
+            same database as the new form for the URL,
+            <code class="literal">jdbc:hsqldb:mem:.</code>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">jdbc:hsqldb:file:</code></td>
+</tr>
+</table>
+</td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">not available</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="filename">mydb</code></td>
+</tr>
+<tr>
+<td><code class="filename">/opt/db/accounts</code></td>
+</tr>
+<tr>
+<td><code class="filename">C:/data/mydb</code></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The file path specifies the
+            database file. In the above examples the first one refers to a set
+            of mydb.* files in the directory where the
+            <code class="literal">java</code>command for running the application was
+            issued. The second and third examples refer to absolute paths on
+            the host machine.</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">jdbc:hsqldb:res:</code></td>
+</tr>
+</table>
+</td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">not available</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="filename">/adirectory/dbname</code></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">Database files can be loaded from
+            one of the jars specified as part of the <code class="literal">Java</code>
+            command the same way as resource files are accessed in Java
+            programs. The <code class="literal">/adirectory</code> above stands for a
+            directory in one of the jars.</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">jdbc:hsqldb:hsql:</code></td>
+</tr>
+<tr>
+<td><code class="literal">jdbc:hsqldb:hsqls:</code></td>
+</tr>
+<tr>
+<td><code class="literal">jdbc:hsqldb:http:</code></td>
+</tr>
+<tr>
+<td><code class="literal">jdbc:hsqldb:https:</code></td>
+</tr>
+</table>
+</td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">//localhost</code></td>
+</tr>
+<tr>
+<td><code class="literal">//192.0.0.10:9500</code></td>
+</tr>
+<tr>
+<td><code class="literal">//dbserver.somedomain.com</code></td>
+</tr>
+</table>
+</td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">
+<table summary="Simple list" border="0" class="simplelist">
+<tr>
+<td><code class="literal">/an_alias</code></td>
+</tr>
+<tr>
+<td><code class="literal">/enrollments</code></td>
+</tr>
+<tr>
+<td><code class="literal">/quickdb</code></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td style="" colspan="3" align="left" valign="top">
+<p>The host and port specify
+            the IP address or host name of the server and an optional port
+            number. The database to connect to is specified by an alias. This
+            alias is a lowercase string defined in the
+            <code class="filename">server.properties</code> file to refer to an actual
+            database on the file system of the server or a transient,
+            in-memory database on the server. The following example lines in
+            <code class="filename">server.properties</code> or
+            <code class="filename">webserver.properties</code> define the database
+            aliases listed above and accessible to clients to refer to
+            different file and in-memory databases.</p> 
+<p>The old form
+            for the server URL, e.g.,
+            <code class="literal">jdbc:hsqldb:hsql//localhost</code> connects to the
+            same database as the new form for the URL,
+            <code class="literal">jdbc:hsqldb:hsql//localhost/</code> where the alias is
+            a zero length string.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="conn_props-sect"></a>Connection properties</h3>
+</div>
+</div>
+</div>
+<p>Each JDBC Connection to a database can specify connection
+      properties. The properties <span class="property">user</span> and
+      <span class="property">password</span> are always required. In 2.0 the following
+      optional properties can also be used.</p>
+<p>Connection properties are specified either by establishing the
+      connection via the method call below, or the property can be appended to
+      the full Connection URL.</p>
+<pre class="programlisting">    DriverManager.getConnection (String url, Properties info);</pre>
+<div class="table">
+<a name="N13B9C"></a>
+<p class="title">
+<b>Table&nbsp;12.2.&nbsp;Connection Properties</b>
+</p>
+<div class="table-contents">
+<table summary="Connection Properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">get_column_name</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">column name in ResultSet</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property is used for
+              compatibility with other JDBC driver implementations. When true
+              (the default), <code class="methodname">ResultSet.getColumnName(int
+              c)</code> returns the underlying column name. This
+              property can be specified differently for different connections
+              to the same database.</p>
+<p>The default is true. When the
+              property is false, the above method returns the same value as
+              <code class="methodname">ResultSet.getColumnLabel(int column)</code>
+              Example below:</p>
+<pre class="programlisting">    jdbc:hsqldb:hsql://localhost/enrollments;get_column_name=false</pre>
+<p>When
+              a ResultSet is used inside a user-defined stored procedure, the
+              default, true, is always used for this property.</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">ifexists</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">connect only if database already exists</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Has an effect only with
+              <em class="glossterm">mem:</em> and <em class="glossterm">file:</em>
+              database. When true, will not create a new database if one does
+              not already exist for the URL.</p>
+<p>When the property is
+              false (the default), a new <em class="glossterm">mem:</em> or
+              <em class="glossterm">file:</em> database will be created if it does
+              not exist.</p> 
+<p>Setting the property to true is useful
+              when troubleshooting as no database is created if the URL is
+              malformed. Example below:</p> 
+<pre class="programlisting">    jdbc:hsqldb:file:enrollments;ifexists=true</pre>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">shutdown</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">shut down the database when the last connection is
+              closed</td>
+</tr>
+<tr>
+<td style="" colspan="3" align="left" valign="top">
+<p>If this property is
+              <code class="literal">true</code>, when the last connection to a database
+              is closed, the database is automatically shut down. The property
+              takes effect only when the first connection is made to the
+              database. This means the connection that opens the database. It
+              has no effect if used with subsequent connections.</p>
+              
+<p>This command has two uses. One is for test suites, where
+              connections to the database are made from one JVM context,
+              immediately followed by another context. The other use is for
+              applications where it is not easy to configure the environment
+              to shutdown the database. Examples reported by users include web
+              application servers, where the closing of the last connection
+              coincides with the web app being shut
+              down.</p>
+<pre class="programlisting">    jdbc:hsqldb:file:enrollments;shutdown=true</pre>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>In addition, when a connection to an
+      <em class="glossterm">in-process</em> database creates a new database, or
+      opens an existing database (i.e. it is the first connection made to the
+      database by the application), all the user-defined database properties
+      can be specified as URL properties. This can be used to specify
+      properties to enforce more strict SQL adherence, or to change
+      cache_scale or similar properties before the database files are created.
+      However, for new databases, it is recommended to use the SET PROPERTY
+      command for such settings.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N13C11"></a>Database Properties in Connection URL and Properties</h2>
+</div>
+</div>
+</div>
+<p>The database engine has several properties that are listed in the
+    <a class="link" href="#deployment-chapt" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">System Management and Deployment
+  Issues</a>
+    chapter. These properties can be changed via SQL commands after a
+    connection is made to the database. It is possible to specify all of these
+    properties in the connection properties on as part of the URL string when
+    the first connection is made to a new file: or mem: database. This allows
+    the properties to be set without using any SQL commands. The corresponding
+    SQL command is given for each property.</p>
+<p>Management of properties has changed since version 1.8. The old SET
+    PROPERTY does not change a property and is retained to simplify
+    application upgrades.</p>
+<p>In the example URL below, two properties are set for the first
+    connection to a new database. If the properties are used for connection to
+    an existing database, they are ignored.</p>
+<pre class="programlisting">    jdbc:hsqldb:file:enrollments;hsqldb.cache_rows=10000;hsqldb.nio_data_file=false</pre>
+<p>In the table below, database properties that can be used as part of
+    the URL below are given. For each property that can also be set with an
+    SQL statement, the statement is also given. These statements are described
+    in the <a class="link" href="#deployment-chapt" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">System Management and Deployment
+  Issues</a> chapter.</p>
+<div class="table">
+<a name="N13C26"></a>
+<p class="title">
+<b>Table&nbsp;12.3.&nbsp;Database-specific Property File Properties</b>
+</p>
+<div class="table-contents">
+<table summary="Database-specific Property File Properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Value</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Default</th><th style="border-bottom: 0.5pt solid ; " align="left">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">check_props</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">checks the validity of the connection properties</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is true,
+            every database property that is specified on the URL or in
+            connection properties is checked and if it is not used correctly,
+            an error is returned</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">crypt_lobs</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">encryption of lobs</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is true, the
+            contents of the .lobs file is encrypted as
+            well.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">crypt_key</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">none</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">encryption</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The cipher key for an
+            encrypted database</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">crypt_provider</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">none</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">encryption</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The fully-qualified class
+            name of the cryptography provider. This property is not used for
+            the default security provider.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">crypt_type</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">none</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">encryption</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The cipher
+            specification.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">read_only</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">readonly database</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property is a special
+            property that can be added manually to the .properties file, or
+            included in the URL or connection properties. When this property
+            is true, the database becomes
+            readonly.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">files_read_only</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">readonly files database</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property is used
+            similarly to the hsqldb.read_only property. When this property is
+            true, CACHED and TEXT tables are readonly but memory files are
+            not. Any change to the data is not persisted to database
+            files.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.log_data</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">recovery log</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property can be set to
+            false when database recovery in the event of an unexpected crash
+            is not necessary. A database that is used as a temporary cache is
+            an example. Regardless of the value of this property, if there is
+            a proper shutdown of the database, all the change data is
+            stored.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">sql.enforce_names</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">enforcing SQL keywords</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property, when set
+            true, prevents SQL keywords being used for database object names
+            such as columns and tables.</p>
+<p>
+<pre class="programlisting">SET DATABASE SQL NAMES { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">sql.enforce_size</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">trimming and padding string columns.</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property is the same as
+            sql.enforce_strict_size</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">sql.enforce_strict_size</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">size enforcement and padding string columns</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Conforms to SQL standards
+            for size and precision of data types. When true, all CHARACTER,
+            VARCHAR, NUMERIC and DECIMAL values that are in a row affected by
+            an INSERT INTO or UPDATE statement are checked against the size
+            specified in the SQL table definition. An exception is thrown if
+            the value is too long. Also all CHARACTER values that are shorter
+            than the specified size are padded with
+            spaces.</p>
+<p>
+<pre class="programlisting">SET DATABASE SQL SIZE { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">sql.enforce_refs</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">enforcing column reference disambiguation</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This property, when set
+            true, causes an error when an SQL statements contains column
+            references that can be resovled by more than one table name or
+            alias. In effect forces such column references to have a table
+            name or table alias qualifier.</p>
+<p>
+<pre class="programlisting">SET DATABASE SQL REFERENCES { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">runtime.gc_interval</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">0</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">forced garbage collection</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>This setting forces garbage
+            collection each time a set number of result set row or cache row
+            objects are created. The default, "0" means no garbage collection
+            is forced by the program.</p>
+<p>
+<pre class="programlisting">SET DATABASE GC &lt;numeric value&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.default_table_type</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">memory</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">type of table created with unqualified CREATE TABLE</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The CREATE TABLE command
+            results in a MEMORY table by default. Setting the value
+            <span class="emphasis"><em>cached</em></span> for this property will result in a
+            cached table by default. The qualified forms such as CREATE MEMORY
+            TABLE or CREATE CACHED TABLE are not affected at all by this
+            property.</p>
+<p>
+<pre class="programlisting">SET DATABASE DEFAULT TABLE TYPE { CACHED | MEMORY }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.applog</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">0</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">application logging level</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The default level 0
+            indicates no logging. Level 1 results in events related to
+            persistence to be logged, including any failures. Level 2
+            indicates all events, including ordinary events. The events are
+            logged in a file ending with
+            ".app.log".</p>
+<p>
+<pre class="programlisting">SET DATABASE EVENT LOG LEVEL { 0 | 1 | 2 }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.result_max_memory_rows</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">0</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">amount of result rows that are kept in memory</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Sets the maximum number of
+            rows of each result set and other internal temporary table that is
+            held in memory. </p>
+<p>
+<pre class="programlisting">SET DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned integer literal&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.tx</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">locks</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">database transaction control mode</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Indicates the transaction
+            control mode for the database. The values, locks, mvlocks and mvcc
+            are allowed.</p>
+<p>
+<pre class="programlisting">SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.cache_rows</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">50000</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">maximum number of rows in memory cache</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Indicates the maximum number
+            of rows of cached tables that are held in memory.</p>
+<p>The
+            value can range between 100-1,000,000. If the value is set via SET
+            FILES then it becomes effective after the next database SHUTDOWN
+            or CHECKPOINT.</p>
+<p>The property is changed via the
+            <code class="literal">SET FILES CACHE ROWS nnn</code> SQL
+            command.</p>
+<p>
+<pre class="programlisting">SET FILES CACHE ROWS &lt;numeric value&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.cache_size</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">10000</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">memory cache size</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>Indicates the total size (in
+            kilobytes) of rows in the memory cache used with cached tables.
+            This size is calculated as the binary size of the rows, for
+            example an INTEGER is 4 bytes. The actual memory size used by the
+            objects is 2 to 4 times this value. This depends on the types of
+            objects in database rows, for example with binary objects the
+            factor is less than 2, with character strings, the factor is just
+            over 2 and with date and timestamp objects the factor is over
+            3.</p>
+<p>The value can range between 100-1,000,000. The
+            default is 10,000, representing 10,000 kilobytes. If the value is
+            set via SET FILES then it becomes effective after the next
+            database SHUTDOWN or CHECKPOINT.</p>
+<p>
+<pre class="programlisting">SET FILES CACHE SIZE &lt;numeric value&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.inc_backup</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">incremental backup of data file</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>During updates, the contents
+            of the .data file are modified. When this property is true, the
+            modified contents are backed up gradually. This causes a marginal
+            slowdown in operations, but allows fast checkpoint and
+            shutdown.</p>
+<p>When the property is false, the .data file
+            is backed up entirely at the time of checkpoint and shutdown. Up
+            to version 1.8, HSQLDB supported only full
+            backup.</p>
+<p>
+<pre class="programlisting">SET FILES INCREMENT BACKUP { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.lock_file</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">use of lock file</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>By default, a lock file is
+            created for each file database that is opened for read and write.
+            This property can be specified with the value false to prevent the
+            lock file from being created. This usage is not recommended but
+            may be desirable when flash type storage is
+            used.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.log_data</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">logging data change</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>When
+            <code class="literal">false</code> is specified, no data logging takes
+            place. A checkpoint or shutdown still rewrites the
+            <code class="literal">.script</code> file and saves the
+            <code class="literal">.backup</code> file according to the other
+            settings.</p>
+<p>
+<pre class="programlisting">SET FILES LOG  { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.log_size</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">50</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">size of log when checkpoint is performed</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>The value is the size (in
+            megabytes) that the <code class="literal">.log</code> file can reach before
+            an automatic checkpoint occurs. A checkpoint rewrites the
+            <code class="literal">.script</code> file and clears the
+            <code class="literal">.log</code> file.</p>
+<p>
+<pre class="programlisting">SET FILES LOG SIZE &lt;numeric value&gt;</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.nio_data_file</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">use of nio access methods for the .data file</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>When HyperSQL is compiled
+            and run in Java 1.4 or higher, setting this property to
+            <code class="literal">false</code> will avoid the use of nio access methods,
+            resulting in somewhat reduced speed. If the data file is larger
+            than 256MB when it is first opened, nio access methods are not
+            used. Also, if the file gets larger than the amount of available
+            computer memory that needs to be allocated for nio access, non-nio
+            access methods are used.</p>
+<p>If used before defining any
+            CACHED table, it applies immediately, otherwise it comes into
+            effect after a SHUTDOWN and restart or
+            CHECKPOINT.</p>
+<p>
+<pre class="programlisting">SET FILES NIO { TRUE | FALSE }</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.translate_dti_types</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">usage of type codes for advanced type datetime
+            types</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is true, the
+            datetime WITH TIME ZONE types and INTERVAL types are represented
+            as JDBC datetime types without time zone and the VARCHAR type
+            respectively.</p>
+<p>
+<pre class="programlisting">this property cannot be set with an SQL statement</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.write_delay</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">write delay for writing log file entries</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is true, the
+            default WRITE DELAY property of the database is used, which is
+            1000 milliseconds. If the property is false, the WRITE DELAY is
+            set to 0 seconds. The SQL command for this property allows more
+            precise control over the property.</p>
+<p>
+<pre class="programlisting">SET FILES WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds value&gt; MILLIS</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">hsqldb.write_delay_millis</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">1000</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">write delay for writing log file entries</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">
+<p>If the property is used, the
+            WRITE DELAY property of the database is set the given value. The
+            SQL command for this property allows the same level of control
+            over the property.</p>
+<p>
+<pre class="programlisting">SET FILES WRITE DELAY {{ TRUE | FALSE } | &lt;seconds value&gt; | &lt;milliseconds value&gt; MILLIS</pre>
+</p>
+</td>
+</tr>
+<tr>
+<td style="border-bottom: 0.5pt solid ; " colspan="3" align="left" valign="top">&nbsp;</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">textdb.*</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">0</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">default properties for new text tables</td>
+</tr>
+<tr>
+<td style="" colspan="3" align="left" valign="top">
+<p>Properties that override the
+            database engine defaults for newly created text tables. Settings
+            in the text table <code class="literal">SET &lt;tablename&gt; SOURCE &lt;source
+            string&gt; </code>command override both the engine defaults and
+            the database properties defaults. Individual
+            <span class="property">textdb.*</span> properties are listed in the <a class="link" href="#texttables-chapt" title="Chapter&nbsp;5.&nbsp;Text Tables">Text Tables</a>
+            chapter.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>When connecting to an <em class="glossterm">in-process</em> database
+    creates a new database, or opens an existing database (i.e. it is the
+    first connection made to the database by the application), all the
+    user-defined database properties listed in this section can be specified
+    as URL properties.</p>
+<p>When HSQLDB is used in OpenOffice.org, some property values will
+    have a different default. The properties and values are:</p>
+<p>hsqldb.default_table_type=cached hsqldb.cache_rows=25000;
+    hsqldb.cache_size=6000; hsqldb.log_size=10; hsqldb.nio_data_file=false;
+    sql.enforce_strict_size=true</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="listeners-chapt"></a>HyperSQL Network Listeners</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>Server, WebServer, and Servlet</i>
+</h3>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N13EF6"></a>
+<p>Copyright 2002-2009 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#listeners-sect">Listeners</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#listeners_hsqlserver-sect">HyperSQL Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#listeners_httpserver-sect">HyperSQL HTTP Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#listeners_servlet-sect">HyperSQL HTTP Servlet</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#listeners_server_props-sect">Server and Web Server Properties</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#listeners_appstart-sect">Starting a Server from your application</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N14099">Allowing a Connection to Open a Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#listeners_tls-sect">TLS Encryption</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N140DB">Requirements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N140F8">Encrypting your JDBC connection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#jsse-sect">JSSE</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#privatekey-sect">Making a Private-key Keystore</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N141EB">Automatic Server or WebServer startup on UNIX</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#listeners_acl-sect">Network Access Control</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners-sect"></a>Listeners</h2>
+</div>
+</div>
+</div>
+<p>As described in the <a class="link" href="#running-chapt" title="Chapter&nbsp;1.&nbsp;Running and Using HyperSQL">Running and Using HyperSQL</a> chapter, network listeners or servers
+    provide connectivity to catalogs from different JVM processes. The
+    HyperSQL listeners support both ipv4 and ipv6 network
+    addressing.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="listeners_hsqlserver-sect"></a>HyperSQL Server</h3>
+</div>
+</div>
+</div>
+<p>This is the preferred way of running a database server and the
+      fastest one. This mode uses the proprietary <em class="glossterm">hsql:</em>
+      communications protocol. The following example of the command for
+      starting the server starts the server with one (default) database with
+      files named "mydb.*" and the public name (alias) of "xdb".</p>
+<div class="informalexample">
+<pre class="screen">    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb</pre>
+</div>
+<p>Alternatively, a server.properties file can be used for passing
+      the arguments to the server. This file must be located in the directory
+      where the command is issued.</p>
+<pre class="screen">    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server</pre>
+<p>The contents of the server.properties file is described in the
+      next section.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="listeners_httpserver-sect"></a>HyperSQL HTTP Server</h3>
+</div>
+</div>
+</div>
+<p>This method of access is used when the computer hosting the
+      database server is restricted to the HTTP protocol. The only reason for
+      using this method of access is restrictions imposed by firewalls on the
+      client or server machines and it should not be used where there are no
+      such restrictions. The HyperSQL HTTP Server is a special web server that
+      allows JDBC clients to connect via HTTP. The server can also act as a
+      small general-purpose web server for static pages.</p>
+<p>To run an HTTP server, replace the main class for the server in
+      the example command line above with the following:</p>
+<div class="informalexample">
+<pre class="screen">    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server</pre>
+</div>
+<p>The contents of the server.properties file is described in the
+      next section.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="listeners_servlet-sect"></a>HyperSQL HTTP Servlet</h3>
+</div>
+</div>
+</div>
+<p>This method of access also uses the HTTP protocol. It is used when
+      a separate servlet engine (or application server) such as Tomcat or
+      Resin provides access to the database. The Servlet Mode cannot be
+      started independently from the servlet engine. The
+      <code class="filename">Servlet</code> class, in the HSQLDB jar, should be
+      installed on the application server to provide the connection. The
+      database is specified using an application server property. Refer to the
+      source file <code class="filename"><a class="filename" href="#Servlet.java-link">
+      src/org/hsqldb/server/Servlet.java</a></code> to see the details.</p>
+<p>Both HTTP Server and Servlet modes can only be accessed using the
+      JDBC driver at the client end. They do not provide a web front end to
+      the database. The Servlet mode can serve only a single database.</p>
+<p>Please note that you do not normally use this mode if you are
+      using the database engine in an application server. In this situation,
+      connections to a catalog are usually made
+      <em class="glossterm">in-process</em>, or using an external HSQL Server
+      instance.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners_server_props-sect"></a>Server and Web Server Properties</h2>
+</div>
+</div>
+</div>
+<p>Properties files for running the servers are not created
+    automatically. You should create your own files that contain
+    <span class="property">server.property</span>=<code class="literal">value</code> pairs for
+    each property. The <code class="filename">server.properties</code> or
+    <code class="filename">webserver.properties</code> files must be located in the
+    directory where the command to run the
+    <code class="classname">org.hsqldb.server.Server</code> class is issued.</p>
+<p>In all properties files, values are case-sensitive. All values apart
+    from names of files or pages are required in lowercase (e.g.
+    <span class="property">server.silent</span>=<code class="literal">FALSE</code> will have no
+    effect, but <span class="property">server.silent</span>=<code class="literal">false</code>
+    will work). Supported properties and their default values (if any) are as
+    follows:</p>
+<div class="table">
+<a name="N13F59"></a>
+<p class="title">
+<b>Table&nbsp;13.1.&nbsp;common server and webserver properties</b>
+</p>
+<div class="table-contents">
+<table summary="common server and webserver properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Value</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Default</th><th style="border-bottom: 0.5pt solid ; " align="left">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.database.0</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">file:test</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">the catalog type, path and file name of the first database
+            file to use</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.dbname.0</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">""</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">lowercase server alias for the first database file</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.database.n</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">NO DEFAULT</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">the catalog type, path and file name of the n'th database
+            file in use</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.dbname.n</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">NO DEFAULT</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">lowercase server alias for the n'th database file</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.silent</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">no extensive messages displayed on console</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.trace</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">JDBC trace messages displayed on console</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.address</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">NO DEFAULT</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">IP address of server</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.tls</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">Whether to encrypt network stream. If this is set to
+            <code class="literal">true</code>, then in normal situations you will also
+            need to set properties
+            <code class="varname">system.javax.net.ssl.keyStore</code> and
+            <code class="varname">system.javax.net.ssl.keyStorePassword</code>, as
+            documented elsewhere. The value of <code class="varname">server.tls</code>
+            impacts the default value of
+            <code class="varname">server.port</code>.</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left" valign="top"><span class="property">server.remote_open</span></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="" align="left" valign="top">Allows opening a database path remotely when the first
+            connection is made</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>In HyperSQL version 2.0, each server can serve an unlimited number
+    of databases simultaneously. The <span class="property">server.database.0</span>
+    property defines the filename / path whereas the
+    <span class="property">server.dbname.0</span> defines the lowercase alias used by
+    clients to connect to that database. The digit 0 is incremented for the
+    second database and so on. Values for the
+    <span class="property">server.database.n</span> property can use the
+    <em class="glossterm">mem:</em>, <em class="glossterm">file:</em> or
+    <em class="glossterm">res:</em> prefixes and connection properties as
+    discussed under CONNECTIONS. For example, <div class="informalexample">
+<pre class="programlisting">    database.0=mem:temp;sql.enforce_strict_size=true;</pre>
+</div>
+</p>
+<p>Properties or default values specific to
+    <code class="filename">server.properties</code> are:</p>
+<div class="table">
+<a name="N13FED"></a>
+<p class="title">
+<b>Table&nbsp;13.2.&nbsp;server properties</b>
+</p>
+<div class="table-contents">
+<table summary="server properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Value</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Default</th><th style="border-bottom: 0.5pt solid ; " align="left">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.port</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">9001 (normal) or 554 (if TLS
+            encrypted)</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">TCP/IP port used for talking to clients. All databases are
+            served on the same port.</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left" valign="top"><span class="property">server.no_system_exit</span></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="" align="left" valign="top">no <code class="literal">System.exit()</code> call when the database
+            is closed</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>Properties or default values specific to
+    <code class="filename">webserver.properties</code> are:</p>
+<div class="table">
+<a name="N1401F"></a>
+<p class="title">
+<b>Table&nbsp;13.3.&nbsp;webserver properties</b>
+</p>
+<div class="table-contents">
+<table summary="webserver properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Value</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Default</th><th style="border-bottom: 0.5pt solid ; " align="left">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.port</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">80 (normal) or 443 (if TLS
+            encrypted)</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">TCP/IP port used for talking to clients</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.default_page</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">index.html</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">the default web page for server</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.root</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">./</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">the location of served pages</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left" valign="top"><span class="property">.&lt;extension&gt;</span></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><code class="literal">NO DEFAULT</code></td><td style="" align="left" valign="top">multiple entries such as <code class="literal">.html=text/html</code>
+            define the mime types of the static files served by the web
+            server. See the source for <code class="filename"><a class="filename" href="#WebServer.java-link">
+            src/org/hsqldb/server/WebServer.java</a></code> for a
+            list.</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>An example of the contents of a
+    <code class="filename">server.properties</code> file is given below:</p>
+<pre class="programlisting">    server.database.0=file:/opt/db/accounts
+    server.dbname.0=accounts
+
+    server.database.1=file:/opt/db/mydb
+    server.dbname.1=enrollments
+
+    server.database.2=mem:adatabase
+    server.dbname.2=quickdb</pre>
+<p>In the above example, the <code class="filename">server.properties</code>
+    file indicates that the server provides access to 3 different databases.
+    Two of the databases are file-based, while the third is all-in-memory. The
+    aliases for the databases that the users connect to are
+    <code class="literal">accounts</code>, <code class="literal">enrollments</code> and
+    <code class="literal">quickdb</code>.</p>
+<p>All the above properties and their values can be specified on the
+    command line to start the server by omitting the
+    <code class="literal">server.</code> prefix. If a property/value pair is specified
+    on the command line, it overrides the property value specified in the
+    <code class="filename">server.properties</code> or
+    <code class="filename">webserver.properties</code> file.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Upgrading: If you have existing custom properties files, change
+      the values to the new naming convention. Note the use of digits at the
+      end of <span class="property">server.database.n</span> and
+      <span class="property">server.dbname.n</span> properties.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners_appstart-sect"></a>Starting a Server from your application</h2>
+</div>
+</div>
+</div>
+<p>If you want to start the server from within your application, as
+    opposed to the command line or batch files, you should create an instance
+    of Server or Web Server, then assign the properties and start the Server.
+    An working example of this can be found in the <code class="classname"><a class="classname" href="#TestBase.java-link"> org.hsqldb.test.TestBase</a></code>
+    source. The example below sets the same properties as in the
+    server.properties file example.</p>
+<pre class="programlisting">    HsqlProperties p = new HsqlProperties();
+    p.setProperty("server.database.0","file:/opt/db/accounts");
+    p.setProperty("server.dbname.0","an_alias");
+    // set up the rest of properties
+    Server server = new Server();
+    server.setProperties(p);
+    server.setLogWriter(null); // can use custom writer
+    server.setErrWriter(null); // can use custom writer
+    server.start();
+</pre>
+<p>The Server object has several alternative methods for setting
+    databases and their public names. The server should be shutdown using the
+    shutdown() method.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14099"></a>Allowing a Connection to Open a Database</h2>
+</div>
+</div>
+</div>
+<p>If the <code class="literal">server.remote_open</code> property is true, the
+    Server works differently from the normal mode. In this mode, it is not
+    necessary to have any databases listed as server.database.0 etc. in the
+    Server startup properties. If there are databases listed, they are opened
+    as normal. The server does not shutdown when the last database is
+    closed.</p>
+<p>In this mode, a connection can be established to a database that is
+    not open or does not exist. The server will open the database or create
+    it, then return a connection to the database.</p>
+<p>The connection URL must include the path to the database, separated
+    with a semicolon from the alias. In the example below, the database path
+    specified as <code class="literal">file:C:/files/mydatabase</code> is opened and the
+    database alias <code class="literal">xdb</code> is assigned to the database. After
+    this, the next connection to the specified alias will connect to the same
+    database.</p>
+<pre class="programlisting">Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb;file:C:/files/mydatabase", "SA", "");
+</pre>
+<p>The path can be a file: or mem: database.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners_tls-sect"></a>TLS Encryption</h2>
+</div>
+<div>
+<h2 class="subtitle">Listener TLS Support (a. k. a. SSL)</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<a name="N140D3" class="indexterm"></a>
+<p>This section explains how to encrypt the stream between JDBC network
+    clients and HyperSQL Listeners. If you are running an
+    <em class="glossterm">in-process</em> (non-Listener) setup, this chapter does
+    not apply to you.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N140DB"></a>Requirements</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<p class="title">
+<b>Hsqldb TLS Support Requirements</b>
+</p>
+<ul type="disc">
+<li>
+<p>Sun Java 2.x and up. (This is probably possible with IBM's
+          Java, but I don't think anybody has attempted to run HSQLDB with TLS
+          under IBM's Java, and I'm sure that nobody in the HSQLDB Development
+          Group has documented how to set up the environment).</p>
+</li>
+<li>
+<p>If Java 2.x or 3.x, then you will need to <a class="link" href="#jsse-sect" title="JSSE">install JSSE</a>. Your server and/or
+          client will start up much slower than that of Java 4.x users.
+          Client-side users will not be able to use the https: JDBC protocol
+          (because the https protocol handler is not implemented in 2.x/3.x
+          Java JSSE; if there is demand, we could work around this).</p>
+</li>
+<li>
+<p>A <a class="link" href="#privatekey-sect" title="Making a Private-key Keystore">JKS keystore containing
+          a private key</a>, in order to run a Listener.</p>
+</li>
+<li>
+<p>If you are running the listener side, then you'll need to run
+          a HSQLDB Server or WebServer Listener instance. It doesn't matter if
+          the underlying database catalogs are new, and it doesn't matter if
+          you are making a new Listener configuration or encrypting an
+          existing Listener configuration. (You can turn encryption on and off
+          at will).</p>
+</li>
+<li>
+<p>You need a HSQLDB jar file that was built with JSSE present.
+          If you obtained your HSQLDB 1.7.2-or-later distribution from us, you
+          are all set, because we build with Java 1.4 or later (which contains
+          JSSE). If you build your own jar file with Java 1.3, make sure to
+          install JSSE first.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N140F8"></a>Encrypting your JDBC connection</h3>
+</div>
+</div>
+</div>
+<p>At this time, only 1-way, server-cert encryption is tested.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h4 class="title">
+<a name="N140FD"></a>Client-Side</h4>
+</div>
+</div>
+</div>
+<p>Just use one of the following protocol prefixes.</p>
+<div class="itemizedlist">
+<p class="title">
+<b>Hsqldb TLS URL Prefixes</b>
+</p>
+<ul type="disc">
+<li>
+<p>
+<code class="literal">jdbc:hsqldb:hsqls://</code>
+</p>
+</li>
+<li>
+<p>
+<code class="literal">jdbc:hsqldb:https://</code>
+</p>
+</li>
+</ul>
+</div>
+<p>At this time, the latter will only work for clients running with
+        Java 1.4 or later.</p>
+<p>If the listener you wish to connect to is using a certificate
+        approved by your default trust keystore, then there is nothing else to
+        do. If not, then you need to tell Java to "trust" the server cert.
+        (It's a slight over-simplification to say that if the server
+        certificate was purchased, then you are all set; if somebody "signed
+        their own" certificate by self-signing or using a private ca
+        certificate, then you need to set up trust).</p>
+<p>First, you need to obtain the cert (only the "public" part of
+        it). Since this cert is passed to all clients, you could obtain it by
+        writing a Java client that dumps it to file, or perhaps by using
+        <span class="emphasis"><em>openssl s_client</em></span>. Since in most cases, if you
+        want to trust a non-commercial cert, you probably have access to the
+        server keystore, I'll show an example of how to get what you need from
+        the server-side JKS keystore.</p>
+<p>You may already have an X509 cert for your server. If you have a
+        server keystore, then you can generate a X509 cert like this. <div class="example">
+<a name="N14118"></a>
+<p class="title">
+<b>Example&nbsp;13.1.&nbsp;Exporting certificate from the server's keystore</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    keytool -export -keystore server.store -alias existing_alias -file server.cer</pre>
+</div>
+</div>
+<br class="example-break"> In this example, <code class="filename">server.cer</code> is the
+        X509 certificate that you need for the next step.</p>
+<p>Now, you need to add this cert to one of the system trust
+        keystores or to a keystore of your own. See <a class="link" href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores" target="_top">
+        the Customizing Stores section in JSSERefGuide.html</a> to see
+        where your system trust keystores are. You can put private keystores
+        anywhere you want to. The following command will add the cert to an
+        existing keystore, or create a new keystore if
+        <code class="filename">client.store</code> doesn't exist.</p>
+<div class="example">
+<a name="N1412A"></a>
+<p class="title">
+<b>Example&nbsp;13.2.&nbsp;Adding a certificate to the client keystore</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    keytool -import -trustcacerts -keystore trust.store -alias new_alias -file server.cer</pre>
+</div>
+</div>
+<br class="example-break">
+<p>If you are making a new keystore, you probably want to start
+        with a copy of your system default keystore which you can find
+        somewhere under your <code class="varname">JAVA_HOME</code> directory (typically
+        <code class="filename">jre/lib/security/cacerts</code> for a JDK, but I forget
+        exactly where it is for a JRE).</p>
+<p>Unless your OS can't stop other people from writing to your
+        files, you probably do not want to set a password on the trust
+        keystore.</p>
+<p>If you added the cert to a system trust store, then you are
+        finished. Otherwise you will need to specify your custom trust
+        keystore to your client program. The generic way to set the trust
+        keystore is to set the system property
+        <code class="classname">javax.net.ssl.trustStore</code> every time that you
+        run your client program. For example <div class="example">
+<a name="N1413E"></a>
+<p class="title">
+<b>Example&nbsp;13.3.&nbsp;Specifying your own trust store to a JDBC client</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    java -Djavax.net.ssl.trustStore=/home/blaine/trust.store -jar /path/to/hsqldb.jar dest-urlid</pre>
+</div>
+</div>
+<br class="example-break"> This example runs the program <a class="link" href="#unix-chapt" title="Chapter&nbsp;14.&nbsp;HyperSQL on UNIX">SqlTool</a>. SqlTool has built-in TLS
+        support however, so, for SqlTool you can set
+        <code class="varname">truststore</code> on a per-urlid basis in the SqlTool
+        configuration file.</p>
+<p>Note: The hostname in your database URL must match the
+        <span class="emphasis"><em>Common Name</em></span> of the server's certificate exactly.
+        That means that if a site certificate is <code class="literal">admc.com</code>,
+        you can not use <code class="literal">jdbc:hsqldb:hsqls://localhost</code> or
+        <code class="literal">jdbc:hsqldb:hsqls://www.admc.com:1100</code> to connect to
+        it.</p>
+<p>If you want more details on anything, see JSSERefGuide.html on
+        <a class="link" href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html" target="_top">
+        Sun's site</a>, or in the subdirectory
+        <code class="filename">docs/guide/security/jsse</code> of your Java SE
+        docs.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h4 class="title">
+<a name="N14162"></a>Server-Side, aka Listener-Side</h4>
+</div>
+</div>
+</div>
+<p>Get yourself a <a class="link" href="#privatekey-sect" title="Making a Private-key Keystore"> JKS
+        keystore containing a private key</a>. Then set properties
+        <code class="varname">server.tls</code>,
+        <code class="varname">system.javax.net.ssl.keyStore</code> and
+        <code class="varname">system.javax.net.ssl.keyStorePassword</code> in your
+        <code class="filename">server.properties</code> or
+        <code class="filename">webserver.properties</code> file. Set
+        <code class="varname">server.tls</code> to <code class="literal">true</code>,
+        <code class="varname">system.javax.net.ssl.keyStore</code> to the path of the
+        private key JKS keystore, and
+        <code class="varname">system.javax.net.ssl.keyStorePassword</code> to the
+        password (of both the keystore and the private key record-- they must
+        be the same). If you specify relative file path values, they will be
+        resolved relative to the <code class="varname">${user.dir}</code> when the JRE
+        is started.</p>
+<div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Caution">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Caution]" src="../images/db/caution.png"></td><th align="left"><a name="tlspassword-caution"></a>Caution</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>If you set any password in a .properties (or any other) file,
+          you need to restrict access to the file. On a good operating system,
+          you can do this like so: <div class="informalexample">
+<pre class="screen">    chmod 600 path/to/server.properties</pre>
+</div>
+</p>
+</td>
+</tr>
+</table>
+</div>
+<p>The values and behavior of the <code class="literal">system.*</code>
+        settings above match the usage documented for
+        <code class="varname">javax.net.ssl.keyStorePassword</code> and
+        <code class="varname">javax.net.ssl.keyStore</code> in the JSSE docs.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Before version 2.0, HyperSQL depended on directly setting
+          the corresponding JSSE properties. The new idiom is more secure and
+          easier to manage. If you have an old password in a UNIX init script
+          config file, you should remove it.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="jsse-sect"></a>JSSE</h3>
+</div>
+</div>
+</div>
+<p>If you are running Java 4.x or later, then you are all set. Java
+      1.x users, you are on your own (Sun does not provide a JSSE that will
+      work with 1.x). Java 2.x and 3.x users continue...</p>
+<p>Go to <a class="link" href="http://java.sun.com/products/jsse/index-103.html" target="_top">http://java.sun.com/products/jsse/index-103.html</a> If
+      you agree to the terms and meet the requirements, download the domestic
+      or global JSSE software. All you need from the software distro is the
+      three jar files. If you have a JDK installation, then move the 3 jar
+      files into the directory <code class="filename">$JAVA_HOME/jre/lib/ext</code>. If
+      you have a JRE installation, then move the 3 jar files into the
+      directory <code class="filename">$JAVA_HOME/lib/ext</code>.</p>
+<p>Pretty painless.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="privatekey-sect"></a>Making a Private-key Keystore</h3>
+</div>
+</div>
+</div>
+<p>There are two main ways to do this. Either you can use a
+      certificate signed by a certificate authority, or you can make your own.
+      One thing that you need to know in both cases is, the <span class="emphasis"><em>Common
+      Name</em></span> of the cert has to be the exact hostname that JDBC
+      clients will use in their database URL.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h4 class="title">
+<a name="N141BA"></a>CA-Signed Cert</h4>
+</div>
+</div>
+</div>
+<p>I'm not going to tell you how to get a CA-signed SSL
+        certificate. That is well documented at many other places.</p>
+<p>Assuming that you have a standard pem-style private key
+        certificate, here's how you can use <a class="link" href="http://www.openssl.org" target="_top">openssl</a> and the program
+        <code class="classname">DERImport</code> to get it into a JKS keystore.</p>
+<p>Because I have spent a lot of time on this document already, I
+        am just giving you an example.</p>
+<div class="example">
+<a name="N141CA"></a>
+<p class="title">
+<b>Example&nbsp;13.4.&nbsp;Getting a pem-style private key into a JKS keystore</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    openssl pkcs8 -topk8 -outform DER -in Xpvk.pem -inform PEM -out Xpvk.pk8 -nocrypt
+
+    openssl x509 -in Xcert.pem -out Xcert.der -outform DER
+
+    java DERImport new.keystore NEWALIAS Xpvk.pk8 Xcert.der</pre>
+</div>
+</div>
+<br class="example-break">
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Make sure to set the password of the key exactly the same as
+          the password for the keystore!</p>
+</td>
+</tr>
+</table>
+</div>
+<p>You need the program <code class="filename">DERImport.class</code> of
+        course. Do some internet searches to find
+        <code class="filename">DERImport.java</code> or
+        <code class="filename">DERImport.class</code> and download it.</p>
+<p>If DERImport has become difficult to obtain, I can write a
+        program to do the same thing-- just let me know.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h4 class="title">
+<a name="N141DF"></a>Non-CA-Signed Cert</h4>
+</div>
+</div>
+</div>
+<p>Run <code class="literal">man keytool</code> or see <a class="link" href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore" target="_top">
+        the Creating a Keystore section of JSSERefGuide.html</a>.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N141EB"></a>Automatic Server or WebServer startup on UNIX</h3>
+</div>
+</div>
+</div>
+<p>If you are on UNIX and want to automatically start and stop a
+      Server or WebServer running with encryption, set the
+      <code class="varname">system.javax.net.ssl.keyStore</code> and
+      <code class="varname">system.javax.net.ssl.keyStorePassword</code> properties as
+      instructed above, and follow the instructions in the <a class="link" href="#unix-chapt" title="Chapter&nbsp;14.&nbsp;HyperSQL on UNIX">HyperSQL on UNIX</a> chapter, paying
+      close attention to the TLS-related comments in the template config
+      file.</p>
+<p>If you are using a private server certificate, make sure to also
+      set the trust store filepath for relevant urlids in your RC file, as
+      explained in the sample <a class="link" href="#hsqldb.cfg-link">config
+      file</a>.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners_acl-sect"></a>Network Access Control</h2>
+</div>
+<div>
+<h2 class="subtitle">Aka Server ACLs</h2>
+</div>
+</div>
+</div>
+<a name="N14207" class="indexterm"></a><a name="N1420A" class="indexterm"></a>
+<p>JDBC connections will always be denied if the supplied user and
+    password are not found in the target catalog. But an HyperSQL listener can
+    also restrict access at the listener level, even protecting private
+    catalogs which have insecure (or default) passwords. If you have an
+    <em class="glossterm">in-process</em> setup, this section of the Guide doesn't
+    apply to you.</p>
+<p>Many (in fact, most) distributed database applications don't have
+    application clients connect directly to the database, but instead
+    encapsulate access in a controlling process. For example, a web app will
+    usually access the data source on behalf of users, with end-user web
+    browsers never accessing the database directly. In these cases and others,
+    the security benefits of restricting listener access to specific source
+    addresses is well worth the effort. ACLs work by restricting access
+    according to the source address of the incoming connection request. This
+    is efficient because the database engine never even gets the request until
+    it is approved by the ACL filter code.</p>
+<p>The sample file <code class="filename"><a class="filename" href="#acl.txt-link">sample/acl.txt</a></code> in your HyperSQL
+    distribution explains how to write an ACL file. <pre class="programlisting"># $Id: acl.txt 826 2009-01-17 05:04:52Z unsaved $
+
+# Sample HyperSQL Network Listener ACL file.
+# Specify "allow" and "deny" rules
+# For address specifications, individual addresses, host names, and
+# network addresses with /bit suffix are allowed, but read the caveat about
+# host names below, under the sample "localhost" rule.
+
+# Blank lines ignored.
+   # Lines with # as the first non-whitespace character are ignored.
+
+
+allow 2001:db8::/32
+# Allow this 32-bit ipv4 subnet
+
+allow localhost
+# You should use numerical addresses in ACL files, unless you are certain that
+# the name will always be known to your network address resolution system
+# (assume that you will lose Internet connectivity at some time).
+# With a default name resolution setup on UNIX, you are safe to use names
+# defined in your /etc/hosts file.
+
+deny 192.168.101.253
+# Deny a single IP address.
+# In our example, 192.168.101.0/24 is our local, organizational network.
+# 192.168.101.253 is the IP address of our Intern's PC.
+# The Intern does not have permission to access our databases directly.
+
+allow 192.168.101.0/24
+
+# Any ipv4 or ipv6 candidate address not matched above will be denied
+</pre>
+    You put your file wherever it is convenient for you, and specify that path
+    with the property <code class="varname">server.acl</code> or
+    <code class="varname">webserver.acl</code> in your
+    <code class="filename">server.properties</code> or
+    <code class="filename">webserver.properties</code> file (depending on whether your
+    listener instance is a <code class="classname">Server</code> or
+    <code class="classname">WebServer</code>). You can specify the ACL file path with
+    an absolute or relative path. If you use a relative path, it must be
+    relative to the <code class="filename">.properties</code> file. It's often
+    convenient to name the ACL file <code class="filename">acl.txt</code>, in the same
+    directory as your <code class="filename">.properties</code> file and specify the
+    property value as just <code class="filename">acl.txt</code>. This file name is
+    intuitive, and things will continue to work as expected if you move or
+    copy the entire directory.</p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>If your <code class="classname">Server</code> or
+      <code class="classname">WebServer</code> was started with a
+      <code class="varname">*.acl</code> property, changes afterwards to the ACL file
+      will be picked up immediately by your listener instance. You are advised
+      to use the procedure below to prevent partial edits or mistakes from
+      crippling your running server.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>When you edit your ACL file, it is both more convenient and more
+    secure to test it as explained here before activating it. You could, of
+    course, test an ACL file by editing it in-place, then trying to connect to
+    your listener with JDBC clients from various source addresses. Besides
+    being mightily laborious and boring, with this method it is very easy to
+    accidentally open access to all source addresses or to deny access to all
+    users until you fix incorrect ACL entries.</p>
+<p>The suggested method of creating or changing ACLs is to work with an
+    inactive file (for new ACL files, just don't enable the
+    <code class="varname">*.acl</code> property yet; for changing an existing file, just
+    copy it to a temporary file and edit the temporary file). Then use the
+    <code class="classname">ServerAcl</code> class to test it. <div class="example">
+<a name="N14251"></a>
+<p class="title">
+<b>Example&nbsp;13.5.&nbsp;Validating and Testing an ACL file</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    java -cp path/to/hsqldb.jar org.hsqldb.server.ServerAcl path/to/acl.txt</pre>
+</div>
+</div>
+<br class="example-break"> If the specified ACL file fails validation, you will be given
+    details about the problem. Otherwise, the validated rules will be
+    displayed (including the implicit, default deny rules). You then type in
+    host names and addresses, one-per-line. Each name or address is tested as
+    if it were a HyperSQL network client address, using the same exact method
+    that the HyperSQL listener will use. (HyperSQL listeners use this same
+    <code class="classname">ServerAcl</code> class to test incoming source addresses).
+    <code class="classname">ServerAcl</code> will report the rule which matches and
+    whether access is denied or allowed to that address.</p>
+<p>If you have edited a copy of an existing ACL file (as suggested
+    above), then overwrite your live ACL file with your new, validated ACL
+    file. I.e., copy your temp file over top of your live ACL file.</p>
+<p>
+<code class="classname">ServerAcl</code> can be run in the same exact way
+    described above, to troubleshoot runtime access issues. If you use an ACL
+    file and a user or application can't get a connection to the database, you
+    can run <code class="classname">ServerAcl</code> to quickly and definitively find
+    if the client is being prohibited by an ACL rule.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="unix-chapt"></a>HyperSQL on UNIX</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>How to quickly get a HyperSQL (aka HSQLDB) Listener up and
+    running on UNIX, including Mac OS X</i>
+</h3>
+</div>
+<div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3360 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2009-12-16 10:03:31 -0500 (Wed, 16 Dec 2009) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#unix_purpose-sect">Purpose</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_install-sect">Installation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_cat_setup-sect">Setting up Database Catalog and Listener</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_access-sect">Accessing your Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_addl_accts-sect">Create additional Accounts</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_shutdown-sect">Shutdown</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_daemon-sect">Running Hsqldb as a System Daemon</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N144B8">Portability of hsqldb init script</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N144C2">Init script Setup Procedure</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#unix_inittrouble-sect">Troubleshooting the Init
+      Script</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#unix_upgrade-sect">Upgrading</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_purpose-sect"></a>Purpose</h2>
+</div>
+</div>
+</div>
+<p>This chapter explains how to quickly install, run, and use a
+    HyperSQL Listener (aka Server) on UNIX.</p>
+<p>Note that, unlike a traditional database server, there are many
+    use cases
+    where it makes sense to run HyperSQL without any listener. This type of
+    setup is called <em class="glossterm">in-process</em>, and is not covered
+    here, since there is no UNIX-specific setup in that case.</p>
+<p>I intend to cover what I think is the most common
+    UNIX setup: To run a multi-user, externally-accessible catalog with
+    permanent data persistence. (By the latter I mean that data is stored to
+    disk so that the catalog data will persist across process shutdowns and
+    startups). I also cover how to run the Listener as a system
+    daemon.</p>
+<p>When I give sample shell commands below, I use commands which
+    will work in Bourne-compatible shells, including Bash and Korn. Users who
+    insist on using the inferior C-shells will need to convert.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_install-sect"></a>Installation</h2>
+</div>
+</div>
+</div>
+<p>Go to <a class="link" href="http://sourceforge.net/projects/hsqldb" target="_top">http://sourceforge.net/projects/hsqldb</a> and click on
+    the "files" link. You want the current version. I can't be more specific
+    because SourceForge/Geeknet are likely to continue changing their
+    interface. See if there's a distribution for the current HSQLDB version in
+    the format that you want.</p>
+<p>If you want a binary package and we either don't provide it, or
+    you prefer somebody else's build, you should still find out the current
+    version of HyperSQL available at SourceForge. It's very
+    likely that you can find a binary package for your UNIX variant with your
+    OS distributor, <a class="link" href="http://www.jpackage.org/" target="_top">http://www.jpackage.org/</a>, <a class="link" href="http://sunfreeware.com/" target="_top">http://sunfreeware.com/</a>, etc. Nowadays, most UNIXes
+    have software package management systems which check Internet
+    repositories. Just search the repositories for "hsqldb" and "hypersql".
+    The challenge is to find an <span class="emphasis"><em>up-to-date</em></span> package. You
+    will get better features and support if you work with the current stable
+    release of HyperSQL. (In particular, HyperSQL version 2.0.0 added tons of
+    new features). Pay attention to what JVM versions your binary package
+    supports. Our builds (version 2.0 and later) document the Java version it
+    was built with in the file <code class="filename">doc/index.html</code>, but you
+    can't depend on this if somebody else assembled your distribution. Java
+    jar files are generally compatible with the same or greater major
+    versions. For example,if your <code class="filename">hsqldb.jar</code> was built
+    with Java 1.3.6-11, then it is compatible with Java versions 1.3.* and
+    greater.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>It could very well happen that some of the file formats which I
+      discuss below are not in fact offered. If so, then we have not gotten
+      around to building them.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>Binary installation depends on the package format that you
+    downloaded.</p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">Installing from a .pkg.Z file</span>
+</p>
+</td><td>
+<p>This package is only for use by a Solaris super-user. It's a
+          System V package. Download then uncompress the package with
+          uncompress or gunzip <div class="informalexample">
+<pre class="screen">    uncompress filename.pkg.Z</pre>
+</div> You can read about the package by running
+          <div class="informalexample">
+<pre class="screen">    pkginfo -l -d filename.pkg</pre>
+</div> Run pkgadd as root to install.</p>
+<div class="informalexample">
+<pre class="screen">
+    pkgadd -d filename.pkg</pre>
+</div>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Installing from a BSD Port or Package</span>
+</p>
+</td><td>You're on your own. I find everything much easier when I
+          install software to BSD without their package management
+          systems.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Installing from a .rpm file</span>
+</p>
+</td><td>
+<p>Just skip this section if you know how to install an RPM. If
+          you found the RPM using a software management system, then just have
+          it install it. The remainder of item explains a generic command-line
+          method which should work with any Linux variant. After you download
+          the rpm, you can read about it by running <div class="informalexample">
+<pre class="screen">    rpm -qip /path/to/file.rpm</pre>
+</div>
+</p>
+<p>Rpms can be installed or upgraded by running <div class="informalexample">
+<pre class="screen">    rpm -Uvh /path/to/file.rpm</pre>
+</div> as root. Suse users may want to keep Yast aware
+          of installed packages by running rpm through Yast: <code class="literal">yast2 -i
+          /path/to/file.rpm</code>.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Installing from a .zip file</span>
+</p>
+</td><td>
+<p>Extract the zip file in an ancestor directory of the new
+          HSQLDB home. You don't need to create the
+          <code class="varname">HSQLDB_HOME</code> directory because the extraction will
+          create a version-labelled directory, and the subdirectory "hsqldb".
+          This "hsqldb" directory is your <code class="varname">HSQLDB_HOME</code>, and
+          you can move it to wherever you wish. If you will be upgrading or
+          maintaining multiple versions of HyperSQL, you will want to retain
+          the version number in the directory tree somehow.</p>
+<div class="informalexample">
+<pre class="screen">    cd ancestor/of/new/hsqldb/home
+    unzip /path/to/file.zip</pre>
+</div>
+<p>All the files in the zip archive will be extracted to
+          underneath a new subdirectory named like
+          <code class="filename">hsqldb-2.0.2a/hsqldb</code>.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>Take a look at the files you installed. (Under
+    <code class="filename">hsqldb</code> for zip file installations. Otherwise, use the
+    utilities for your packaging system). The most important file of the
+    HyperSQL system is <code class="filename">hsqldb.jar</code>, which resides in the
+    subdirectory <code class="filename">lib</code>.
+    Depending on who built your distribution, your file name may have a
+    version label in it, like <code class="filename">hsqldb-1.2.3.4.jar</code>.
+    </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>For the purposes of this chapter, I define
+      <code class="varname">HSQLDB_HOME</code> to be the parent directory of the lib
+      directory that contains <code class="filename">hsqldb.jar</code>. E.g., if your
+      path to <code class="filename">hsqldb.jar</code> is
+      <code class="filename">/a/b/hsqldb/lib/hsqldb.jar</code>, then your
+      <code class="varname">HSQLDB_HOME</code> is
+      <code class="filename">/a/b/hsqldb</code>.</p>
+<p>Furthermore, unless I state otherwise, all local file paths
+      that I give are relative to the
+      <code class="varname">HSQLDB_HOME</code>.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>If the description of your distribution says that the
+    <code class="filename">hsqldb.jar</code> file will work for your Java version, then
+    you are finished with installation. Otherwise you need to build a new
+    <code class="filename">hsqldb.jar</code> file.</p>
+<p>If you followed the instructions above and you still don't know
+    what Java version your <code class="filename">hsqldb.jar</code> supports, then try
+    reading documentation files like <code class="filename">readme.txt</code>,
+    <code class="filename">README.TXT</code>, <code class="filename">INSTALL.txt</code> etc. (As
+    I said above, our newer distributions always document the Java version for
+    the build, in the file <code class="filename">doc/index.html</code>). If that still
+    doesn't help, then you can just try your <code class="filename">hsqldb.jar</code>
+    and see if it works, or build your own.</p>
+<p>To use the supplied <code class="filename">hsqldb.jar</code>, just skip to
+    the <a class="link" href="#unix_cat_setup-sect" title="Setting up a HyperSQL Persistent Database Catalog and a HyperSQL Network Listener"> next section of this
+    document</a>. Otherwise build a new
+    <code class="filename">hsqldb.jar</code>.</p>
+<div class="procedure">
+<a name="N1434E"></a>
+<p class="title">
+<b>Procedure&nbsp;14.1.&nbsp;Building hsqldb.jar</b>
+</p>
+<ol type="1">
+<li>
+<p>If you don't already have Ant, download the latest stable binary
+        version from <a class="link" href="http://ant.apache.org" target="_top">http://ant.apache.org</a>. cd to
+        where you want Ant to live, and extract from the archive with
+        <div class="informalexample">
+<pre class="screen">    unzip /path/to/file.zip</pre>
+</div>or<div class="informalexample">
+<pre class="screen">    tar -xzf /path/to/file.tar.gz</pre>
+</div>or<div class="informalexample">
+<pre class="screen">    bunzip2 -c /path/to/file.tar.bz2 | tar -xzf -</pre>
+</div> Everything will be installed into a new
+        subdirectory named <code class="filename">apache-ant- + version</code>. You can
+        rename the directory after the extraction if you wish.</p>
+</li>
+<li>
+<p>Set the environmental variable <code class="varname">JAVA_HOME</code> to
+        the base directory of your Java JRE or SDK, like <div class="informalexample">
+<pre class="screen">    export JAVA_HOME; JAVA_HOME=/usr/java/j2sdk1.4.0</pre>
+</div> The location is entirely dependent upon your
+        variety of UNIX. Sun's rpm distributions of Java normally install to
+        <code class="filename">/usr/java/something</code>. Sun's System V package
+        distributions of Java (including those that come with Solaris)
+        normally install to <code class="filename">/usr/something</code>, with a
+        sym-link from <code class="filename">/usr/java</code> to the default version
+        (so for Solaris you will usually set JAVA_HOME to
+        <code class="filename">/usr/java</code>).</p>
+</li>
+<li>
+<p>Remove the existing file <code class="varname">HSQLDB_HOME</code>
+        <code class="filename">/lib/hsqldb.jar</code>.</p>
+</li>
+<li>
+<p>cd to <code class="varname">HSQLDB_HOME</code><code class="filename">/build</code>.
+        Make sure that the bin directory under your Ant home is in your search
+        path. Run the following command. <div class="informalexample">
+<pre class="screen">    ant hsqldb</pre>
+</div> This will build a new
+        <code class="varname">HSQLDB_HOME</code><code class="filename">/lib/hsqldb.jar</code>.</p>
+</li>
+</ol>
+</div>
+<p>See the <a class="link" href="#building-app" title="Appendix&nbsp;B.&nbsp;Building HyperSQL Jars">Building HyperSQL Jars</a> appendix if you want to build anything
+    other than <code class="filename">hsqldb.jar</code> with all default
+    settings.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_cat_setup-sect"></a>Setting up a HyperSQL Persistent Database Catalog and a HyperSQL
+    Network Listener</h2>
+</div>
+</div>
+</div>
+<p>If you installed from an OS-specific package, you may already
+    have a catalog and listener pre-configured. See if your package includes a
+    file named <code class="filename">server.properties</code> (make use of your
+    packaging utilities). If you do, then I suggest that you still read this
+    section while you poke around, in order to understand your
+    setup.</p>
+<div class="procedure">
+<ol type="1">
+<li>
+<p>Select a UNIX user to run the database process (JVM) as. If
+        this database is for the use of multiple users, or is a production
+        system (or to emulate a production system), you should dedicate a UNIX
+        user for this purpose. In my examples, I use the user name
+        <code class="literal">hsqldb</code>. In this chapter, I refer to this user as
+        the <code class="varname">HSQLDB_OWNER</code>, since that user will own the
+        database catalog files and the JVM processes.</p>
+<p>If the account doesn't exist, then create it. On all system-5
+        UNIXes and most hybrids (including Linux), you can run (as root)
+        something like <div class="informalexample">
+<pre class="screen">    useradd -c 'HSQLDB Database Owner' -s /bin/bash -m hsqldb</pre>
+</div> (BSD-variant users can use a similar <code class="literal">pw
+        useradd hsqldb...</code> command).</p>
+</li>
+<li>
+<p>Become the <code class="varname">HSQLDB_OWNER</code>. Copy the sample
+        file <code class="filename"><a class="filename" href="#server.properties-link">
+        sample/server.properties</a></code> to the
+        <code class="varname">HSQLDB_OWNER</code>'s home directory and rename it to
+        <code class="filename">server.properties</code>. (As a final reminder,
+        "sampleserver.properties" is a relative path, so it is understood to
+        be relative to your <code class="varname">HSQLDB_HOME</code>).</p>
+<pre class="programlisting"># Hsqldb Server cfg file.
+# See the HyperSQL Network Listeners chapter of the HyperSQL User Guide.
+
+# Each server.database.X setting defines a database "catalog".
+# I.e., an independent set of data.
+# Each server.database.X setting corresponds exactly to the jdbc:hsqldb:*
+# JDBC URL you would use if you wanted to get a direct (In-Process)
+# Connection to the catalog instead of "serving" it.
+
+server.database.0=file:db0/db0
+# I suggest that, for every file: catalog you define, you add the
+# connection property "ifexists=true" after the database instance
+# is created (which happens simply by starting the Server one time).
+# Just append ";ifexists=true" to the file: URL, like so:
+# server.database.0=file:db0/db0;ifexists=true
+
+# server.dbname.0 defaults to "" (i.e. server.dbname.n for n==0), but
+# the catalog definition n will be entirely ignored for n &gt; 0 if you do not
+# set server.dbname.n.  I.e. dbname setting is required for n &gt; 0, though it
+# may be set to blank (e.g. "server.dbname.3=")
+</pre>
+<p>Since the value of the first database
+        (<span class="property">server.database.0</span>) begins with
+        <em class="glossterm">file:</em>, the catalog will be persisted to a set
+        of files in the specified directory with names beginning with the
+        specified name. Set the path to whatever you want (relative paths will
+        be relative to the directory containing the properties file). You can
+        read about how to specify other catalogs of various types, and how to
+        make settings for the listen port and many other things in other
+        chapters of this guide.</p>
+</li>
+<li>
+<p>Set and export the environmental variable
+        <code class="varname">CLASSPATH</code> to the value of
+        <code class="varname">HSQLDB_HOME</code> (as described above) plus
+        "/lib/hsqldb.jar", like <div class="informalexample">
+<pre class="screen">    export CLASSPATH; CLASSPATH=/path/to/hsqldb/lib/hsqldb.jar</pre>
+</div> In <code class="varname">HSQLDB_OWNER</code>'s home
+        directory, run</p>
+<div class="informalexample">
+<pre class="screen">    nohup java org.hsqldb.server.Server &amp;</pre>
+</div>
+<p>This will start the Listener process in the background, and
+        will create your new database catalog "db0". Continue on when you see
+        the message containing <code class="literal">HSQLDB server... is online</code>.
+        <code class="literal">nohup</code> just makes sure that the command will not
+        quit when you exit the current shell (omit it if that's what you want
+        to do).</p>
+</li>
+</ol>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_access-sect"></a>Accessing your Database</h2>
+</div>
+</div>
+</div>
+<p>
+      We're going to use SqlTool to access the database, so you will need the
+      file <code class="filename">sqltool.jar</code> in addition to
+      <code class="filename">hsqldb.jar</code>.
+      If <code class="filename">sqltool.jar</code> isn't already sitting there beside
+      <code class="filename">hsqldb.jar</code> (they both come pre-built), build it
+      exactly as you would build <code class="filename">hsqldb.jar</code>, except use
+      ant target <code class="literal">sqltool</code>.
+      If your distribution came with a sqltool jar file with a version label,
+      like <code class="filename">sqltool-1.2.3.4.jar</code>, that's fine-- use that
+      file whenever I say <code class="filename">sqltool.jar</code> below.
+    </p>
+<p>Copy the file <code class="filename"><a class="filename" href="#sqltool.rc-link">sample/sqltool.rc</a></code> to the
+    <code class="varname">HSQLDB_OWNER</code>'s home directory. Use
+    <code class="literal">chmod</code> to make the file readable and writable only to
+    <code class="varname">HSQLDB_OWNER</code>.</p>
+<pre class="programlisting"># $Id: sqltool.rc 3353 2009-12-15 19:52:13Z unsaved $
+
+# This is a sample RC configuration file used by SqlTool, DatabaseManager,
+# and any other program that uses the org.hsqldb.lib.RCData class.
+# See the documentation for SqlTool for various ways to use this file.
+
+# If you have the least concerns about security, then secure access to
+# your RC file.
+
+# You can run SqlTool right now by copying this file to your home directory
+# and running
+#    java -jar /path/to/sqltool.jar mem
+# This will access the first urlid definition below in order to use a 
+# personal Memory-Only database.
+# "url" values may, of course, contain JDBC connection properties, delimited
+# with semicolons.
+# As of revision 3347 of SqlFile, you can also connect to datasources defined
+# here from within an SqlTool session/file with the command "\j urlid".
+
+# You can use Java system property values in this file like this:  ${user.home}
+
+# The only feature added recently is the optional "transiso" setting,
+# which may be set to an all-caps transaction isolation level as listed
+# in the Java API Spec for java.sql.Connection.
+# Windows users are advised to use forward slashes instead of reverse slashes,
+# and to avoid paths containing spaces or other funny characters.  (This
+# recommendation applies to any Java app, not just SqlTool).
+
+# A personal Memory-Only (non-persistent) database.
+urlid mem
+url jdbc:hsqldb:mem:memdbid
+username SA
+password
+
+# A personal, local, persistent database.
+urlid personal
+url jdbc:hsqldb:file:${user.home}/db/personal;shutdown=true
+username SA
+password
+transiso TRANSACTION_READ_COMMITTED
+# When connecting directly to a file database like this, you should 
+# use the shutdown connection property like this to shut down the DB
+# properly when you exit the JVM.
+
+# This is for a hsqldb Server running with default settings on your local
+# computer (and for which you have not changed the password for "SA").
+urlid localhost-sa
+url jdbc:hsqldb:hsql://localhost
+username SA
+password
+
+
+
+# Template for a urlid for an Oracle database.
+# You will need to put the oracle.jdbc.OracleDriver class into your 
+# classpath.
+# In the great majority of cases, you want to use the file classes12.zip
+# (which you can get from the directory $ORACLE_HOME/jdbc/lib of any
+# Oracle installation compatible with your server).
+# Since you need to add to the classpath, you can't invoke SqlTool with
+# the jar switch, like "java -jar .../hsqldb.jar..." or 
+# "java -jar .../hsqlsqltool.jar...".
+# Put both the HSQLDB jar and classes12.zip in your classpath (and export!)
+# and run something like "java org.hsqldb.util.SqlTool...".
+
+#urlid cardiff2
+#url jdbc:oracle:thin:@aegir.admc.com:1522:TRAFFIC_SID
+#username blaine
+#password secretpassword
+#driver oracle.jdbc.OracleDriver
+
+
+
+# Template for a TLS-encrypted HSQLDB Server.
+# Remember that the hostname in hsqls (and https) JDBC URLs must match the
+# CN of the server certificate (the port and instance alias that follows 
+# are not part of the certificate at all).
+# You only need to set "truststore" if the server cert is not approved by
+# your system default truststore (which a commercial certificate probably
+# would be).
+
+#urlid tls
+#url jdbc:hsqldb:hsqls://db.admc.com:9001/lm2
+#username BLAINE
+#password asecret
+#truststore ${user.home}/ca/db/db-trust.store
+
+
+# Template for a Postgresql database
+#urlid blainedb
+#url jdbc:postgresql://idun.africawork.org/blainedb
+#username blaine
+#password losung1
+#driver org.postgresql.Driver
+
+# Template for a MySQL database.  MySQL has poor JDBC support.
+#urlid mysql-testdb
+#url jdbc:mysql://hostname:3306/dbname
+#username root
+#password hiddenpwd
+#driver com.mysql.jdbc.Driver
+
+# Note that "databases" in SQL Server and Sybase are traditionally used for
+# the same purpose as "schemas" with more SQL-compliant databases.
+
+# Template for a Microsoft SQL Server database
+#urlid msprojsvr
+#url jdbc:microsoft:sqlserver://hostname;DatabaseName=DbName;SelectMethod=Cursor
+# The SelectMethod setting is required to do more than one thing on a JDBC
+# session (I guess Microsoft thought nobody would really use Java for 
+# anything other than a "hello world" program).
+# This is for Microsoft's SQL Server 2000 driver (requires mssqlserver.jar
+# and msutil.jar).
+#driver com.microsoft.jdbc.sqlserver.SQLServerDriver
+#username myuser
+#password hiddenpwd
+
+# Template for a Sybase database
+#urlid sybase
+#url jdbc:sybase:Tds:hostname:4100/dbname
+#username blaine
+#password hiddenpwd
+# This is for the jConnect driver (requires jconn3.jar).
+#driver com.sybase.jdbc3.jdbc.SybDriver
+
+# Template for Embedded Derby / Java DB.
+#urlid derby1
+#url jdbc:derby:path/to/derby/directory;create=true
+#username ${user.name}
+#password any_noauthbydefault
+#driver org.apache.derby.jdbc.EmbeddedDriver
+# The embedded Derby driver requires derby.jar.
+# There'a also the org.apache.derby.jdbc.ClientDriver driver with URL
+# like jdbc:derby://&lt;server&gt;[:&lt;port&gt;]/databaseName, which requires
+# derbyclient.jar.
+# You can use \= to commit, since the Derby team decided (why???)
+# not to implement the SQL standard statement "commit"!!
+# Note that SqlTool can not shut down an embedded Derby database properly,
+# since that requires an additional SQL connection just for that purpose.
+# However, I've never lost data by not shutting it down properly.
+# Other than not supporting this quirk of Derby, SqlTool is miles ahead of ij.
+</pre>
+<p>We will be using the "localhost-sa" sample urlid definition from
+    the config file. The JDBC URL for this urlid is
+    <code class="literal">jdbc:hsqldb:hsql://localhost</code>. That is the URL for the
+    default catalog of a HyperSQL Listener running on the default port of the
+    local host. You can read about URLs to connect to other catalogs with and
+    without listeners in other chapters of this guide.</p>
+<p>Run <code class="classname">SqlTool</code>. <div class="informalexample">
+<pre class="screen">    java -jar path/to/sqltool.jar localhost-sa</pre>
+</div> If you get a prompt, then all is well. If security is
+    of any concern to you at all, then you should change the privileged
+    password in the database. Use the command <code class="literal"><a class="literal" href="#set_password-sql">SET PASSWORD</a></code> command to change
+    SA's password. <div class="informalexample">
+<pre class="programlisting">    SET PASSWORD 'newpassword';</pre>
+</div>
+    Set a <span class="emphasis"><em>strong</em></span> password!
+    </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+        If, like most UNIX System Administrators, you often need to make up
+        strong passwords, I highly suggest the great little program
+        <code class="filename"><a class="filename" href="https://sourceforge.net/projects/pwgen/" target="_top">pwgen</a></code>.
+        You can probably get it where you get your other OS packages.
+        The command <code class="literal">pwgen -1</code> is usually all you need.
+    </p>
+</td>
+</tr>
+</table>
+</div>
+<p>Note that with SQL-conformant databases like HyperSQL 2.0, user
+    names and passwords are case sensitive. If you don't quote the name, it
+    will be interpreted as upper-case, like any named SQL object. (Only for
+    backwards compatibility, we do make an exception for the special user name
+    SA, but you should always use upper-case "SA" nevertheless).</p>
+<p>When you're finished playing, exit with the command
+    <code class="literal">\q</code>.</p>
+<p>If you changed the SA password, then you need to update the
+    password in the <code class="filename">sqltool.rc</code> file accordingly.</p>
+<p>You can, of course, also access the database with any JDBC client
+    program.
+    You will need to modify your classpath to include
+    <code class="filename">hsqldb.jar</code> as well as your client class(es). You can
+    also use the other HSQLDB client programs, such as
+    <code class="classname">org.hsqldb.util.DatabasManagerSwing</code>, a graphical
+    client with a similar purpose to <code class="classname">SqlTool</code>.</p>
+<p>You can use any normal UNIX account to run the JDBC clients,
+    including <code class="classname">SqlTool</code>, as long as the account has read
+    access to the <code class="filename">sqltool.jar</code> file and to an
+    <code class="filename">sqltool.rc</code> file. See the Utilities Guide about where
+    to put <code class="filename">sqltool.rc</code>, how to execute sql files, and
+    other <code class="classname">SqlTool</code> features.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_addl_accts-sect"></a>Create additional Accounts</h2>
+</div>
+</div>
+</div>
+<p>Connect to the database as SA (or any other Administrative user)
+    and run <code class="literal"><a class="literal" href="#create_user-sql">CREATE USER</a></code> to
+    create new accounts for your catalog. HSQLDB accounts are
+    database-catalog-specific, not
+    <code class="classname">Listener</code>-specific.</p>
+<p>In SQL-compliant databases, all database objects are created in a
+    <span class="emphasis"><em>schema</em></span>. If you don't specify a schema, then the new
+    object will be created in the default schema. To create a database object,
+    your account (the account that you connected with) must have the role
+    <code class="literal">DBA</code>, or your account must have authorization for the
+    target schema (see the CREATE SCHEMA command about this last). When you
+    first create a HyperSQL catalog, it has only one database user-- SA, a DBA
+    account, with an empty string password. You should set a password (as
+    described above). You can create as many additional users as you wish. To
+    make a user a DBA, you can use the "ADMIN" option to the <code class="literal"><a class="literal" href="#create_user-sql">CREATE USER</a></code> command, command, or
+    GRANT the DBA Role to the account after creating it.</p>
+<p>Once an object is created, the object creator and users with the
+    DBA role will have all privileges to work with that object. Other users
+    will have only the rights which the pseudo-user PUBLIC has. To give
+    specific users more permissions, even rights to read objects, you can
+    GRANT permissions for specific objects, grant Roles (which encompass a set
+    of permissions), or grant the DBA Role itself.</p>
+<p>Since only people with a database account may do anything at all
+    with the database, it is often useful to permit other database users to
+    view the data in your tables. To optimize performance, reduce contention,
+    and minimize administration, it is often best to grant SELECT to PUBLIC on
+    table-like objects that need to be accessed by multiple database users,
+    with the significant exception of any data which you want to keep secret.
+    (Similary with EXECUTE priv for routines and USAGE priv for other object
+    types).
+    Note that this is not at all equivalent to giving the world or the Internet
+    read access to your tables-- you are giving read access to people that have
+    been given accounts for the target database catalog.
+    </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_shutdown-sect"></a>Shutdown</h2>
+</div>
+</div>
+</div>
+<p>Do a clean database shutdown when you are finished with the database
+    catalog. You need to connect up as SA or some other Admin user, of course.
+    With SqlTool, you can run <div class="informalexample">
+<pre class="screen">    java -jar path/to/sqltool.jar --sql 'shutdown;' localhost-sa</pre>
+</div> You don't have to worry about stopping the
+    <code class="classname">Listener</code> because it shuts down automatically when
+    all served database catalogs are shut down.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_daemon-sect"></a>Running Hsqldb as a System Daemon</h2>
+</div>
+</div>
+</div>
+<a name="N1449D" class="indexterm"></a>
+<p>You can, of course, run HSQLDB through inittab on System V
+    UNIXes, but usually an init script is more convenient and manageable. This
+    section explains how to set up and use our UNIX init script. Our init
+    script is only for use by root. (That is not to say that the
+    <span class="emphasis"><em>Listener</em></span> will run as root-- it usually should
+    not).</p>
+<p>The main purpose of the init script is to start up a Listener for
+    the database catalogs specified in your
+    <code class="filename">server.properties</code> file; and to gracefully shut down
+    these same catalogs. For each catalog defined by a
+    <code class="varname">server.database.X</code> setting in your .properties file, you
+    must define an administrative "urlid" in your
+    <code class="filename">sqltool.rc</code> (these are used to access the catalogs for
+    validation and shutdown purposes). Finally, you list the urlid names in
+    your init script config file. If, due to firewall issues, you want to run
+    a WebServer instead of a Server, then make sure you have a healthy
+    WebServer with a webserver.properties set up, adjust your URLs in
+    <code class="filename">sqltool.rc</code>, and set TARGET_CLASS in the config
+    file.</p>
+<p>By following the commented examples in the config file, you can
+    start up any number of Server and/or WebServer listener instances with or
+    without TLS encryption, and each listener instance can serve any number of
+    HyperSQL catalogs (independent data sets), all with optimal efficiency
+    from a single JVM process. There are instructions in the init script
+    itself about how to run multiple, independently-configured JVM processes.
+    Most UNIX installations, however, will run a single JVM with a single
+    Listener instance which serves multiple catalogs, for easier management
+    and more efficient resource usage.</p>
+<p>After you have the init script set up, root can use it anytime to
+    start or stop HSQLDB. (I.e., not just at system bootup or
+    shutdown).</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N144B8"></a>Portability of <code class="filename">hsqldb</code> init script</h3>
+</div>
+</div>
+</div>
+<p>The primary design criterion of the init script is portability.
+      It does not print pretty color startup/shutdown messages as is common in
+      late-model Linuxes and HPUX; and it does not keep subsystem state files
+      or use the startup/shutdown functions supplied by many UNIXes, because
+      these features are all non-portable.</p>
+<p>Offsetting these limitations, this one script does it's
+      intended job great on the UNIX varieties I have tested, and can easily
+      be modified to accommodate other UNIXes. While you don't have tight
+      integration with OS-specific daemon administration guis, etc., you do
+      have a well tested and well behaved script that gives good, utilitarian
+      feedback.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N144C2"></a>Init script Setup Procedure</h3>
+</div>
+</div>
+</div>
+<p>The strategy taken here is to get the init script to run your
+      single Server or WebServer first (as specified by TARGET_CLASS). After
+      that's working, you can customize the JVM that is run by running
+      additional Listener instances in it, running your own application in it
+      (embedding), or even overriding HSQLDB behavior with your own overriding
+      classes.</p>
+<div class="procedure">
+<ol type="1">
+<li>
+<p>Copy the init script <code class="filename"><a class="filename" href="#hsqldb.init-link"> sample/hsqldb.init</a></code> to
+          <code class="filename">hsqldb</code> in the directory where init scripts live
+          on your variety of UNIX. The most common locations are
+          <code class="filename">/etc/init.d</code> or
+          <code class="filename">/etc/rc.d/init.d</code> on System V style UNIXes,
+          <code class="filename">/usr/local/etc/rc.d</code> on BSD style UNIXes, and
+          <code class="filename">/Library/StartupItems/hsqldb</code> on OS X (you'll
+          need to create the directory for the last).</p>
+</li>
+<li>
+<p>View your <code class="filename">server.properties</code> file. Make a
+          note of every catalog define by a
+          <code class="varname">server.database.X</code> setting. A couple steps down,
+          you will need to set up administrative access for each of these
+          catalogs. If you are using our sample <code class="filename"><a class="filename" href="#server.properties-link"> server.properties</a></code>
+          file, you will just need to set up access for the
+          catalog specified with <code class="literal">file:db0/dbo</code>.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Pre-2.0 versions of the hsqldb init script required use
+            of .properties settings of the
+            form<code class="varname">server.urlid.X</code>. These settings are obsolete
+            and should be removed.</p>
+</td>
+</tr>
+</table>
+</div>
+</li>
+<li>
+<p>Either copy <code class="varname">HSQLDB_OWNER</code>'s
+          <code class="filename">sqltool.rc</code> file into root's home directory, or
+          set the value of <code class="varname">AUTH_FILE</code> to the absolute path
+          of <code class="varname">HSQLDB_OWNER</code>'s <code class="filename">sqltool.rc</code>
+          file. This file is read directly by root, even if you run hsqldb as
+          non-root (by setting <code class="varname">HSQLDB_OWNER</code> in the config
+          file). If you copy the file, make sure to use
+          <code class="literal">chmod</code> to restrict permissions on the new copy.
+          The init script will abort with an appropriate exhortation if you
+          have the permissions set incorrectly.</p>
+<p>You need to set up a urlid stanza in your
+          <code class="filename">sqltool.rc</code> file for network access (i.e. JDBC
+          URL with hsql:, hsqls:, http:, or https:) for each catalog in your
+          <code class="filename">server.properties</code> file. For our example, you
+          need to define a stanza for the <code class="literal">file:db0/db0</code>
+          catalog. You must supply for this catalog, a hsql: JDBC URL, an
+          administrative user name, and the password.</p>
+<div class="example">
+<a name="N14517"></a>
+<p class="title">
+<b>Example&nbsp;14.1.&nbsp;example sqltool.rc stanza</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">    urlid localhostdb1
+    url jdbc:hsqldb:hsql://localhost
+    username SA
+    password secret</pre>
+</div>
+</div>
+<br class="example-break">
+</li>
+<li>
+<p>Look at the comment towards the top of the init script
+          which lists recommended locations for the configuration file for
+          various UNIX platforms. Copy the sample config file <code class="filename"><a class="filename" href="#hsqldb.cfg-link">sample/hsqldb.cfg</a></code> to one of
+          the listed locations (your choice). Edit the config file according
+          to the instructions in it. For our example, you will set the value
+          of <code class="varname">URLIDS</code> to <code class="literal">localhostdb1</code>,
+          since that is the urlid name that we used in the
+          <code class="filename">sqltool.rc</code> file.</p>
+<pre class="programlisting"># $Id: hsqldb.cfg 3583 2010-05-16 01:49:52Z unsaved $
+
+# Sample configuration file for HyperSQL Server Listener.
+# See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide.
+
+# N.b.!!!!  You must place this in the right location for your type of UNIX.
+# See the init script "hsqldb" to see where this must be placed and
+# what it should be renamed to.
+
+# This file is "sourced" by a Bourne shell, so use Bourne shell syntax.
+
+# This file WILL NOT WORK until you set (at least) the non-commented
+# variables to the appropriate values for your system.
+# Life will be easier if you avoid all filepaths with spaces or any other
+# funny characters.  Don't ask for support if you ignore this advice.
+
+# The URLIDS setting below is new and REQUIRED.  This setting replaces the
+# server.urlid.X settings which used to be needed in your Server's
+# properties file.
+
+# -- Blaine (blaine dot simpson at admc dot com)
+
+JAVA_EXECUTABLE=/usr/bin/java
+
+# Unless you copied the jar files from another system, this typically
+# resides at $HSQLDB_HOME/lib/sqltool.jar, where $HSQLDB_HOME is your HSQLDB
+# software base directory.
+# The file name may actually have a version label in it, like
+# sqltool-1.2.3.jar (in which case, you must specify the full name here).
+# A 'hsqldb.jar' file (with or without version label) must reside in the same
+# directory as the specified sqltool.jar file.
+SQLTOOL_JAR_PATH=/opt/hsqldb-2.0.0/hsqldb/lib/sqltool.jar
+# For the sample value above, there must also exist a file
+# /opt/hsqldb-2.0.0/hsqldb/lib/hsqldb*.jar.
+
+# Where the file "server.properties" or "webserver.properties" resides.
+SERVER_HOME=/opt/hsqldb-2.0.0/hsqldb/data
+
+# What UNIX user the server will run as.
+# (The shutdown client is always run as root or the invoker of the init script).
+# Runs as root by default, but you should take the time to set database file
+# ownerships to another user and set that user name here.
+HSQLDB_OWNER=hsqldb
+
+# The HSQLDB jar file specified in HSQLDB_JAR_PATH above will automatically
+# be in the class path.  This arg specifies additional classpath elements.
+# To embed your own application, add your jar file(s) or class base
+# directories here, and add your main class to the INVOC_ADDL_ARGS setting
+# below.  Another common use-case for adding to your class path is to make
+# classes available to the DB engines for SQL/JRT functions and procedures.
+#SERVER_ADDL_CLASSPATH=/usr/local/dist/currencybank.jar
+
+# For startup or shutdown failures, you can save a lot of debugging time by
+# temporarily adjusting down MAX_START_SECS and MAX_TERMINATE_SECS to a
+# little over what it should take for successful startup and shutdown on
+# your system.
+
+# We require all Server/WebServer instances to be accessible within 
+# $MAX_START_SECS from when the Server/WebServer is started.
+# Defaults to 60.
+# Raise this is you are running lots of DB instances or have a slow server.
+#MAX_START_SECS=200
+
+# Max time to allow for JVM to die after all HSQLDB instances stopped.
+# Defaults to 60.  Set high because the script will always continue as soon as
+# the process has stopped.  The importance of this setting is, how long until
+# a non-stopping-JVM-problem will be detected.
+#MAX_TERMINATE_SECS=0
+
+# NEW AND IMPORTANT!!!
+# As noted at the top of this file, this setting replaces the old property
+# settings server.urlid.X.
+# Simply list the URLIDs for all DB instances which your *Server starts.
+# Usually, these will exactly mirror the server.database.X settings in your
+# server.properties or webserver.properties file.
+# Each urlid listed here must be defined to a NETWORK url with Admin privileges
+# in the AUTH_FILE specified below.  (Network type because we use this for
+# inter-process communication)
+# Separate multiple values with white space.  NO OTHER SPECIAL CHARACTERS!
+# Make sure to quote the entire value if it contains white space separator(s).
+URLIDS='localhostdb1'
+
+# These are urlids # ** IN ADDITION TO URLIDS **, for instances which the init
+# script should stop but not start.
+# Most users will not need this setting.  If you need it, you'll know it.
+# Defaults to none (i.e., only URLIDS will be stopped).
+#SHUTDOWN_URLIDS='ondemand'
+
+# SqlTool authentication file used only for shutdown.
+# The default value will be sqltool.rc in root's home directory, since it is 
+# root who runs the init script.
+# (See the SqlTool chapter of the HyperSQL Utilities Guide if you don't
+# understand this).
+#AUTH_FILE=/home/blaine/sqltool.rc
+
+# Typical users will leave this unset and it will default to
+# org.hsqldb.server.Server.  If you need to run the HSQLDB WebServer class
+# instead, due to a firewall or routing impediment, set this to
+# org.hsqldb.server.WebServer, see the docs about running WebServr, and
+# set up a "webserver.properties" file instead of a "server.properties".
+# The JVM that is started can invoke many classes (see the following item
+# about that), but this is the server that is used (1) to check status,
+# (2) to shut down the JVM.
+#TARGET_CLASS=org.hsqldb.server.WebServer
+
+# This is where you may specify both command-line parameters to TARGET_CLASS,
+# plus any number of additional progams to run (along with their command-line
+# parameters).  The MainInvoker program is used to embed these multiple
+# static main invocations into a single JVM, so see the API spec for
+# org.hsqldb.util.MainInvoker if you want to learn more.
+# N.b. You should only use this setting to set HSQLDB Server or WebServer
+# parameters if you run multiple instances of this class, since you can use the
+# server/webserver.properties file for a single instance.
+# Every additional class (in addition to the TARGET_CLASS)
+# must be preceded with an empty string, so that MainInvoker will know
+# you are giving a class name.  MainInvoker will invoke the normal 
+# static main(String[]) method of each such class.  
+# By default, MainInvoker will just run TARGET_CLASS with no args.
+# Example that runs just the TARGET_CLASS with the specified arguments:
+#INVOC_ADDL_ARGS='-silent false'   #but use server.properties property instead!
+# Example that runs the TARGET_CLASS plus a WebServer:
+#INVOC_ADDL_ARGS='"" org.hsqldb.server.WebServer'
+# Note the empty string preceding the class name.
+# Example that starts TARGET_CLASS with an argument + a WebServer +
+# your own application with its args (i.e., the HSQLDB Servers are
+# "embedded" in your application).  (Set SERVER_ADDL_CLASSPATH too).:
+#INVOC_ADDL_ARGS='-silent false "" org.hsqldb.server.WebServer "" com.acme.Stone --env prod localhost'
+#   but use server.properties for -silent option instead!
+# Example to run a non-TLS server in same JVM with a TLS server.  In this
+# case, TARGET_CLASS is Server which will run both in TLS mode by virtue of 
+# setting the tls, keyStore, and keyStorePassword settings in
+# server*.properties, as described below; plus an "additional" Server with
+# overridden 'tls' and 'port' settings:
+#INVOC_ADDL_ARGS="'' org.hsqldb.server.Server --port 9002 --tls false"
+# This is an important use case.  If you run more than one Server instance,
+# you can specify different parameters for each here, even though only one
+# server.properties file is supported.
+# Note that you use nested quotes to group arguments and to specify the
+# empty-string delimiter.
+
+# The TLS_* settings have been obsoleted.
+# To get your server running with TLS, set
+# system.javax.net.ssl.keyStore=/path/to/your/private.keystore
+# system.javax.net.ssl.keyStorePassword=secretPassword
+# server.ssl=true
+# IN server.properties or webserver.properties, and
+# MAKE THE FILE OWNER-READ-ONLY!
+# See the TLS Encryption section of the HyperSQL User Guide, paying attention
+# to the security warning(s).
+# If you are running with a private server cert, then you will also need to 
+# set "truststore" in the your SqlTool config file (location is set by the
+# AUTH_FILE variable in this file, or it must be at the default location for 
+# HSQLDB_OWNER).
+
+# Any JVM args for the invocation of the JDBC client used to verify DB
+# instances and to shut them down (SqlToolSprayer).
+# Server-side System Properties should normally be set with system.*
+# settings in the server/webserver.properties file.
+# This example specifies the location of a private trust store for TLS 
+# encryption.
+# For multiple args, put quotes around entire value.
+# If you are starting just a TLS_encrypted Listener, you need to uncomment
+# this so the init scripts uses TLS to connect.
+# If using a private keystore, you also need to set "truststore" settings in
+# the sqltool.rc file.
+#CLIENT_JVMARGS=-Djavax.net.debug=ssl
+# This sample value displays useful debugging information about TLS/SSL.
+
+# Any JVM args for the server.
+# For multiple args, put quotes around entire value.
+#SERVER_JVMARGS=-Xmx512m
+# You can set the "javax.net.debug" property on the server side here, in the
+# same exact way as shown for the client side above.
+</pre>
+<p>
+<span class="bold"><strong>Verify that the init script
+          works.</strong></span>
+</p>
+<p>Just run <div class="informalexample">
+<pre class="screen">    /path/to/hsqldb</pre>
+</div> as root to see the arguments you may use.
+          Notice that you can run</p>
+<p>
+<pre class="screen">    /path/to/hsqldb status</pre>at any time to see
+          whether your HSQLDB <code class="classname">Listener</code> is
+          running.</p>
+<p>Re-run the script with each of the possible arguments to
+          really test it good. If anything doesn't work right, then see the
+          <a class="link" href="#unix_inittrouble-sect" title="Troubleshooting the Init Script">Troubleshooting the Init
+      Script</a> section.</p>
+</li>
+<li>
+<p>Tell your OS to run the init script upon system startup and
+          shutdown. If you are using a UNIX variant that has
+          <code class="filename">/etc/rc.conf</code> or
+          <code class="filename">/etc/rc.conf.local</code> (like BSD variants and
+          Gentoo), you must set "hsqldb_enable" to "YES" in either of those
+          files. (Just run <code class="literal">cd /etc; ls rc.conf
+          rc.conf.local</code> to see if you have one of these files). For
+          good UNIXes that use System V style init, you must set up hard links
+          or soft links either manually or with management tools (such as
+          <code class="literal">chkconfig</code> or <code class="literal">insserv</code>) or Gui's
+          (like run level editors).</p>
+<p>This paragraph is for Mac OS X users only. If you followed the
+          instructions above, your init script should reside at
+          <code class="filename">/Library/StartupItems/hsqldb/hsqldb</code>. Now copy
+          the file <code class="filename">StartupParameters.plist</code> from the
+          directory <code class="filename">src/org.hsqldb/sample</code> of your HSQLDB
+          distribution to the same directory as the init script. As long as
+          these two files reside in
+          <code class="filename">/Library/StartupItems/hsqldb</code>, your init script
+          is active (for portability reasons, it doesn't check for a setting
+          in <code class="filename">/etc/hostconfig</code>). You can run it as a
+          <span class="emphasis"><em>Startup Item</em></span> by running <pre class="screen">    SystemStarter {start|stop|restart} Hsqldb</pre>
+          Hsqldb is the service name. See the man page for
+          <code class="classname">SystemStarter</code>. To disable the init script,
+          wipe out the <code class="filename">/Library/StartupItems/hsqldb</code>
+          directory. Hard to believe, but the Mac people tell me that during
+          system shutdown the Startup Items don't run at all. Therefore, if
+          you don't want your data corrupted, make sure to run "SystemStarter
+          stop Hsqldb" before shutting down your Mac.</p>
+</li>
+</ol>
+</div>
+<p>Follow the examples in the config file to add additional
+      classes to the server JVM's classpath and to execute additional classes
+      in your JVM. (See the <code class="varname">SERVER_ADDL_CLASSPATH</code> and
+      <code class="varname">INVOC_ADDL_ARGS</code> items).</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="unix_inittrouble-sect"></a>Troubleshooting the Init
+      Script</h3>
+</div>
+</div>
+</div>
+<p>Definitely look at the init script log file, which is at an
+      OS-sependent location, but is usually at
+      <code class="filename">/var/log/hsqldb.log</code>.</p>
+<p>Do a <code class="literal">ps</code> to look for processes containing the
+      string <code class="literal">hsqldb</code>, and try to connect to the database
+      from any client. If the init script starts up your database
+      successfully, but incorrectly reports that it has not, then your problem
+      is with specification of urlid(s) or SqlTool setup. If your database
+      really did not start, then skip to the next paragraph. Verify that your
+      config file assigns a urlid for each catalog defined in
+      <code class="filename">server.properties</code> or
+      <code class="filename">webserver.properties</code>, then verify that you can run
+      <code class="classname">SqlTool</code> as root to connect to the catalogs with
+      these urlids. (For the latter test, use the <code class="literal">--rcfile</code>
+      switch if you are setting <code class="varname">AUTH_FILE</code> in the init
+      script config file).</p>
+<p>If your database really is not starting, then verify that you
+      can <code class="literal">su</code> to the database owner account and start the
+      database. The command
+      <code class="literal">su USERNAME -c ...</code> won't work on most UNIXes unless
+      the target user has a real login shell. Therefore, if you try to tighten
+      up security by disabling this user's login shell, you will break the
+      init script. If these possibilities don't pan out, then debug the init
+      script or seek help, as described below.</p>
+<p>To debug the init script, run it in verbose mode to see exactly
+      what is happening (and perhaps manually run the steps that are suspect).
+      To run an init script (in fact, any sh shell script) in verbose mode,
+      use <code class="literal">sh</code> with the <code class="literal">-x</code> or
+      <code class="literal">-v</code> switch, like <pre class="screen">    sh -x path/to/hsqldb start</pre>
+      See the man page for <code class="literal">sh</code> if you don't know the
+      difference between <code class="literal">-v</code> and
+      <code class="literal">-x</code>.</p>
+<p>If you want troubleshooting help, use the HSQLDB lists/forums.
+      Make sure to include the revision number from your
+      <code class="filename">hsqldb</code> init script (it's towards the top in the
+      line that starts like "# $Id:"), and the output of a run of <pre class="screen">    sh -x path/to/hsqldb start &gt; /tmp/hstart.log 2&gt;&amp;1</pre>
+</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_upgrade-sect"></a>Upgrading</h2>
+</div>
+</div>
+</div>
+<p>This section is for users who are using our UNIX init script, and
+    who are upgrading their HyperSQL installation.</p>
+<p>Most users will not have customized the init script itself, and
+    your customizations will all be encapsulated in the init script
+    configuration file. These users should just overwrite their init script
+    with a new one from the HyperSQL installation, and manually merge config
+    file settings. First, just copy the file
+    <code class="filename">/sample/hsqldb.init</code> over top of of your init script
+    (wherever it runs from). Then update your old config file according to the
+    instructions in the new config file template at
+    <code class="filename">sample/hsqldb.cfg</code>. You will have to change very few
+    settings. If you are upgrading from a pre-2.0 installation to a post-2.0
+    installation, you will need to (1) add the setting
+    <code class="varname">URLIDS</code>, as described above and in the inline comments,
+    and (2) replace variable <code class="varname">HSQLDB_JAR_PATH</code> with
+    <code class="varname">SQLTOOL_JAR_PATH</code> which (if you haven't guessed) should
+    be set to the path to your <code class="filename">sqltool.jar</code> file.</p>
+<p>Users who customized their init script will need to merge their
+    customizations into the new init script.</p>
+</div>
+</div>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="lists-app"></a>Lists of Keywords</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>List of SQL Keywords</i>
+</h3>
+</div>
+<div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 847 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2009-01-19 22:24:49 +0000 (Mon, 19 Jan 2009) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N14607">List of SQL Standard Keywords</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1463A">List of SQL Keywords Disallowed as HyperSQL Identifiers</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14607"></a>List of SQL Standard Keywords</h2>
+</div>
+</div>
+</div>
+<p>According to the SQL Standard, the SQL Language keywords cannot be
+    used as identifiers (names of database objects such as columns and
+    tables). HyperSQL has two modes of operation, which are selected with the
+    SET DATABASE SQL NAMES { TRUE | FALSE } to allow or disallow the keywords
+    as identifiers. The default mode is FALSE and allows the use of most
+    keywords as identifiers. Even in this mode, keywords cannot be used as
+    USER or ROLE identifiers.</p>
+<p>ABS ALL ALLOCATE ALTER AND ANY ARE ARRAY AS ASENSITIVE ASYMMETRIC
+    AT ATOMIC AUTHORIZATION AVG</p>
+<p>BEGIN BETWEEN BIGINT BINARY BLOB BOOLEAN BOTH BY</p>
+<p>CALL CALLED CARDINALITY CASCADED CASE CAST CEIL CEILING CHAR
+    CHAR_LENGTH CHARACTER CHARACTER_LENGTH CHECK CLOB CLOSE COALESCE COLLATE
+    COLLECT COLUMN COMMIT COMPARABLE CONDITION CONNECT CONSTRAINT CONVERT CORR
+    CORRESPONDING COUNT COVAR_POP COVAR_SAMP CREATE CROSS CUBE CUME_DIST
+    CURRENT CURRENT_CATALOG CURRENT_DATE CURRENT_DEFAULT_TRANSFORM_GROUP
+    CURRENT_PATH CURRENT_ROLE CURRENT_SCHEMA CURRENT_TIME CURRENT_TIMESTAMP
+    CURRENT_TRANSFORM_GROUP_FOR_TYPE CURRENT_USER CURSOR CYCLE</p>
+<p>DATE DAY DEALLOCATE DEC DECIMAL DECLARE DEFAULT DELETE DENSE_RANK
+    DEREF DESCRIBE DETERMINISTIC DISCONNECT DISTINCT DO DOUBLE DROP
+    DYNAMIC</p>
+<p>EACH ELEMENT ELSE ELSEIF END END_EXEC ESCAPE EVERY EXCEPT EXEC
+    EXECUTE EXISTS EXIT EXP EXTERNAL EXTRACT</p>
+<p>FALSE FETCH FILTER FIRST_VALUE FLOAT FLOOR FOR FOREIGN FREE FROM
+    FULL FUNCTION FUSION</p>
+<p>GET GLOBAL GRANT GROUP GROUPING</p>
+<p>HANDLER HAVING HOLD HOUR</p>
+<p>IDENTITY IN INDICATOR INNER INOUT INSENSITIVE INSERT INT INTEGER
+    INTERSECT INTERSECTION INTERVAL INTO IS ITERATE</p>
+<p>JOIN</p>
+<p>LAG</p>
+<p>LANGUAGE LARGE LAST_VALUE LATERAL LEAD LEADING LEAVE LEFT LIKE
+    LIKE_REGEX LN LOCAL LOCALTIME LOCALTIMESTAMP LOOP LOWER</p>
+<p>MATCH MAX MAX_CARDINALITY MEMBER MERGE METHOD MIN MINUTE MOD
+    MODIFIES MODULE MONTH MULTISET</p>
+<p>NATIONAL NATURAL NCHAR NCLOB NEW NO NONE NORMALIZE NOT NTH_VALUE
+    NTILE NULL NULLIF NUMERIC</p>
+<p>OCCURRENCES_REGEX OCTET_LENGTH OF OFFSET OLD ON ONLY OPEN OR
+    ORDER OUT OUTER OVER OVERLAPS OVERLAY</p>
+<p>PARAMETER PARTITION PERCENT_RANK PERCENTILE_CONT PERCENTILE_DISC
+    POSITION POSITION_REGEX POWER PRECISION PREPARE PRIMARY
+    PROCEDURE</p>
+<p>RANGE RANK READS REAL RECURSIVE REF REFERENCES REFERENCING
+    REGR_AVGX REGR_AVGY REGR_COUNT REGR_INTERCEPT REGR_R2 REGR_SLOPE REGR_SXX
+    REGR_SXY REGR_SYY RELEASE REPEAT RESIGNAL RESULT RETURN RETURNS REVOKE
+    RIGHT ROLLBACK ROLLUP ROW ROW_NUMBER ROWS</p>
+<p>SAVEPOINT SCOPE SCROLL SEARCH SECOND SELECT SENSITIVE
+    SESSION_USER SET SIGNAL SIMILAR SMALLINT SOME SPECIFIC SPECIFICTYPE SQL
+    SQLEXCEPTION SQLSTATE SQLWARNING SQRT STACKED START STATIC STDDEV_POP
+    STDDEV_SAMP SUBMULTISET SUBSTRING SUBSTRING_REGEX SUM SYMMETRIC SYSTEM
+    SYSTEM_USER</p>
+<p>TABLE TABLESAMPLE THEN TIME TIMESTAMP TIMEZONE_HOUR
+    TIMEZONE_MINUTE TO TRAILING TRANSLATE TRANSLATE_REGEX TRANSLATION TREAT
+    TRIGGER TRIM TRIM_ARRAY TRUE TRUNCATE</p>
+<p>UESCAPE UNDO UNION UNIQUE UNKNOWN UNNEST UNTIL UPDATE UPPER USER
+    USING</p>
+<p>VALUE VALUES VAR_POP VAR_SAMP VARBINARY VARCHAR VARYING</p>
+<p>WHEN WHENEVER WHERE WIDTH_BUCKET WINDOW WITH WITHIN WITHOUT
+    WHILE</p>
+<p>YEAR</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1463A"></a>List of SQL Keywords Disallowed as HyperSQL Identifiers</h2>
+</div>
+</div>
+</div>
+<p>A subset of SQL Standard keywords cannot be used at all as HyperSQL
+    identifiers. The keywords are as follows:</p>
+<p>ADMIN AND ALL ANY AS AT AVG</p>
+<p>BETWEEN BOTH BY</p>
+<p>CALL CASE CAST COALESCE CORRESPONDING CONVERT COUNT CREATE
+    CROSS</p>
+<p>DISTINCT DROP</p>
+<p>ELSE END EVERY EXISTS EXCEPT</p>
+<p>FOR FROM FULL</p>
+<p>GRANT GROUP</p>
+<p>HAVING</p>
+<p>IN INNER INTERSECT INTO IS</p>
+<p>JOIN</p>
+<p>LEFT LEADING LIKE</p>
+<p>MAX MIN</p>
+<p>NATURAL NOT NULLIF</p>
+<p>ON ORDER OR OUTER</p>
+<p>PRIMARY</p>
+<p>REFERENCES RIGHT</p>
+<p>SELECT SET SOME STDDEV_POP STDDEV_SAMP SUM</p>
+<p>TABLE THEN TO TRAILING TRIGGER</p>
+<p>UNION UNIQUE USING</p>
+<p>VALUES VAR_POP VAR_SAMP</p>
+<p>WHEN WHERE WITH</p>
+</div>
+</div>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="building-app"></a>Building HyperSQL Jars</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>How to build customized or specialized jar files</i>
+</h3>
+</div>
+<div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3556 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-03-26 19:09:40 -0400 (Fri, 26 Mar 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N14693">Purpose</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#building-ant-sect">Building with Ant</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N146AA">Obtaining Ant</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N146C0">Building Hsqldb with Ant</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1475D">Building for Older JDKs</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N14765">Building with IDE's</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1476A">Hsqldb CodeSwitcher</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N14791">Building documentation</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14693"></a>Purpose</h2>
+</div>
+</div>
+</div>
+<p>From 2.0, the supplied <code class="filename">hsqldb.jar</code> file is
+    built with Java 1.6. If you want to run with a 1.5 or older JVM, or if you
+    want to use an alternative jar (<code class="filename">hsqldb-min.jar</code>, etc.)
+    you must build the desired jar with a Java JDK and Ant version
+    1.7.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="building-ant-sect"></a>Building with Apache Ant</h2>
+</div>
+</div>
+</div>
+<a name="N146A4" class="indexterm"></a>
+<p>You should use version 1.7.x of Ant (Another Neat Tool) to do
+    builds with HyperSQL.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N146AA"></a>Obtaining Ant</h3>
+</div>
+</div>
+</div>
+<p>Ant is a part of the Jakarta/Apache Project.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<a class="link" href="http://ant.apache.org" target="_top">Home of the Apache
+          Ant project</a>
+</li>
+<li>The <a class="link" href="http://ant.apache.org/manual/install.html#installing" target="_top">
+          Installing Ant</a> page of the <a class="link" href="http://ant.apache.org/manual" target="_top">Ant Manual</a>. Follow
+          the directions for your platform.</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N146C0"></a>Building Hsqldb with Ant</h3>
+</div>
+</div>
+</div>
+<p>Once you have unpacked the zip package for hsqldb, under the
+      <code class="filename">/hsqldb</code> folder, in <code class="filename">/build</code>
+      there is a <code class="filename">build.xml</code> file that builds the
+      <code class="filename">hsqldb.jar</code> with Ant (Ant must be already
+      installed). To use it, change to <code class="filename">/build</code> then
+      type:</p>
+<div class="informalexample">
+<pre class="screen"> ant -projecthelp</pre>
+</div>
+<p>This displays the available ant targets, which you can supply
+      as command line arguments to ant. These include</p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">hsqldb</span>
+</p>
+</td><td>to build the <code class="filename">hsqldb.jar</code>
+            file</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">explainjars</span>
+</p>
+</td><td>Lists all targets which build jar files, with an
+            explanation of the purposes of the different jars.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">clean</span>
+</p>
+</td><td>to clean up the /classes directory that is
+            created</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">clean-all</span>
+</p>
+</td><td>to remove the old jar and doc files as well</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">javadoc</span>
+</p>
+</td><td>to build javadoc</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">hsqldbmain</span>
+</p>
+</td><td>to build a smaller jar for HSQLDB that does not contain
+            utilities</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">hsqljdbc</span>
+</p>
+</td><td>to build an extremely small jar containing only the
+            client-side JDBC driver (can connect only to a HyperSQL
+            Server).</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">hsqldbmin</span>
+</p>
+</td><td>to build a small jar that supports
+            <span class="emphasis"><em>in-process</em></span> catalogs, but neither running nor
+            connecting to HyperSQL Servers.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">sqltool</span>
+</p>
+</td><td>to build sqltool.jar, which contains only the SqlTool
+            classes.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">...</span>
+</p>
+</td><td>Many more targets are available. Run <code class="literal">ant
+            -p</code> and <code class="literal">ant explainjars</code>.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>HSQLDB can be built in any combination of two JRE (Java Runtime
+      Environment) versions and many jar file sizes.</p>
+<p>A jar built with an older JRE is compatible for use with a
+      newer JRE (you can compile with Java 1.5 and run with 1.6). But the
+      newer JDBC capabilities of the JRE will be not be available.</p>
+<p>The client jar (<code class="filename">hsqljdbc.jar</code>) contains
+      only the HSQLDB JDBC Driver client. The smallest engine jar
+      (<code class="filename">hsqldbmin.jar</code>) contains the engine and the HSQLDB
+      JDBC Driver client. The default size (<code class="filename">hsqldb.jar</code>)
+      also contains server mode support and the utilities. The largest size
+      (<code class="filename">hsqldbtest.jar</code>)includes some test classes as well.
+      Before building the <code class="filename">hsqldbtest.jar</code> package, you
+      should download the junit jar from <a class="link" href="http://www.junit.org" target="_top">http://www.junit.org</a> and put it in the
+      <code class="filename">/lib</code> directory, alongside
+      <code class="filename">servlet.jar</code>, which is included in the .zip
+      package.</p>
+<p>If you want your code built for high performance, as opposed to
+      debugging (in the same way that we make our production distributions),
+      make a file named <code class="filename">build.properties</code> in your build
+      directory with the contents <div class="informalexample">
+<pre class="screen">build.debug: false</pre>
+</div>The resulting Java binaries will be faster and
+      smaller, at the cost of exception stack traces not identifying source
+      code locations (which can be extremely useful for debugging).</p>
+<p>After installing Ant on your system use the following command
+      from the <code class="filename">/build</code> directory. Just run <code class="literal">ant
+      explainjars</code> for a concise list of all available jar
+      files.</p>
+<div class="informalexample">
+<pre class="screen">ant explainjars</pre>
+</div>
+<p>The command displays a list of different options for building
+      different sizes of the HSQLDB Jar. The default is built using:</p>
+<div class="example">
+<a name="N14756"></a>
+<p class="title">
+<b>Example&nbsp;B.1.&nbsp;Buiding the standard Hsqldb jar file with Ant</b>
+</p>
+<div class="example-contents">
+<pre class="screen">ant hsqldb</pre>
+</div>
+</div>
+<br class="example-break">
+<p>The Ant method always builds a jar with the JDK that is used by
+      Ant and specified in its JAVA_HOME environment variable.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1475D"></a>Building for Older JDKs</h3>
+</div>
+</div>
+</div>
+<p>HyperSQL version 2.0 cannot be directly compiled or used with JDK
+      1.4. It may be possible to use the RetroTranslator tool to achieve this.
+      The suggested procedure is as follows: First use Ant with JDK 1.5 and
+      build the jar. Then translate the jar using RetroTranslator with
+      backport (which bundles replacement classes for concurrency control).
+      This translation should cover the concurrency features that are specific
+      to version 1.5 and later.<div class="informalexample">
+<pre class="screen">ant switchtojdk14
+ant hsqldb
+-- translate the jar
+</pre>
+</div>
+</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14765"></a>Building with IDE's</h2>
+</div>
+</div>
+</div>
+<p>All HyperSQL source files are supplied ready to compile. There is
+    no complex pre-compile stage. It is therefore possible to compile the
+    sources with an IDE, without using ant. Only if compilation with Java 1.5
+    is required, you should first run the Ant code switcher task before
+    compiling and remove from the source directories a few source files that
+    are specific to Java 6 (these are listed in the build.xml file).</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1476A"></a>Hsqldb CodeSwitcher</h2>
+</div>
+</div>
+</div>
+<p>CodeSwitcher is a tool to manage different version of Java source
+    code. It allows to compile HyperSQL for different JDKs. It is something
+    like a precompiler in C but it works directly on the source code and does
+    not create intermediate output or extra files.</p>
+<p>CodeSwitcher is used internally in the Ant build. You do not have
+    to use it separately to compile HyperSQL.</p>
+<p>CodeSwitcher reads the source code of a file, removes comments
+    where appropriate and comments out the blocks that are not used for a
+    particular version of the file. This operation is done for all files of a
+    defined directory, and all subdirectories.</p>
+<div class="example">
+<a name="N14773"></a>
+<p class="title">
+<b>Example&nbsp;B.2.&nbsp;Example source code before CodeSwitcher is run</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">
+        ...
+
+    //#ifdef JAVA2
+
+        properties.store(out,"hsqldb database");
+
+    //#else
+
+    /*
+
+        properties.save(out,"hsqldb database");
+
+    */
+
+    //#endif
+
+        ...</pre>
+</div>
+</div>
+<br class="example-break">
+<p>The next step is to run CodeSwitcher.</p>
+<div class="example">
+<a name="N1477A"></a>
+<p class="title">
+<b>Example&nbsp;B.3.&nbsp;CodeSwitcher command line invocation</b>
+</p>
+<div class="example-contents">
+<pre class="screen">
+    java org.hsqldb.util.CodeSwitcher . -JAVA2</pre>
+</div>
+</div>
+<br class="example-break">
+<p>The '.' means the program works on the current directory (all
+    subdirectories are processed recursively). <code class="literal">-JAVA2</code> means
+    the code labelled with JAVA2 must be switched off.</p>
+<div class="example">
+<a name="N14784"></a>
+<p class="title">
+<b>Example&nbsp;B.4.&nbsp;Source code after CodeSwitcher processing</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">
+        ...
+
+    //#ifdef JAVA2
+
+    /*
+
+        pProperties.store(out,"hsqldb database");
+
+    */
+
+    //#else
+
+        pProperties.save(out,"hsqldb database");
+
+    //#endif
+
+        ...</pre>
+</div>
+</div>
+<br class="example-break">
+<p>For detailed information on the command line options run
+    <code class="classname">java org.hsqldb.util.CodeSwitcher</code>. Usage examples
+    can be found in the build.xml file in the <code class="filename">/build</code>
+    directory.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14791"></a>Building documentation</h2>
+</div>
+</div>
+</div>
+<p>The JavaDoc can be built simply by invoking the javadoc
+    target.</p>
+<p>The two Guides are in DocBook XML source format. To rebuild, run
+    the Ant target <code class="literal">gen-docs</code>. Instructions will be
+    displayed. See the file <code class="filename">doc-src/readme-docauthors.txt</code>
+    for tips.</p>
+</div>
+</div>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="openoffice-app"></a>HyperSQL with OpenOffice.org</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>How to use HyperSQL with OpenOffice.org</i>
+</h3>
+</div>
+<div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3498 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-03-06 12:42:28 -0500 (Sat, 06 Mar 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#N147C8">HyperSQL with OpenOffice.org</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N147CF">Using OpenOffice.org as a Database Tool</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N147DE">Converting .odb files to use with HyperSQL Server</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N147C8"></a>HyperSQL with OpenOffice.org</h2>
+</div>
+</div>
+</div>
+<p>OpenOffice.org includes HyperSQL and uses it for embedded
+    databases. Our collaboration with OpenOffice.org developers over the last
+    few years has benefited the development and maturity of HyperSQL. Before
+    integration into OOo, HSQLDB was intended solely for application-specific
+    database access. The application developer was expected to resolve any
+    integration issues. Because OpenOffice.org is used by a vast range of
+    users, from schoolchildren to corporate developers, a much higher level of
+    quality assurance has been required and we have achieved it with constant
+    help and feedback from OOo users and developers.</p>
+<p>Apart from embedded use, you may want to use OpenOffic.org with a
+    HyperSQL server instance. The typical use for this is to allow multiple
+    office users accessing the same database. There is, however, a strong case
+    for using OOo to develop your database schema and application, even if the
+    database is intended for your own application.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N147CF"></a>Using OpenOffice.org as a Database Tool</h2>
+</div>
+</div>
+</div>
+<p>OpenOffice.org is a very powerful database front end. If you want
+    to create schemas, edit tables, edit the database contents manually,
+    design and produce well-formatted reports, then OpenOffice.org is probably
+    the best open source tools currently available.</p>
+<p>To connect from OpenOffice.org to your database, first run a
+    local server instance for the database. This is describes in the Network
+    Listeners chapter of this guide.</p>
+<p>When you connect from OpenOffice.org, you must specify connection
+    to an external database and use the URL property "default_schema=true".
+    For example, the URL to connect the local database may be like</p>
+<pre class="programlisting"> jdbc;hsqldb:hsql://localhost/mydb;default_schema=true </pre>
+<p>The only current limitation is that OpenOffice.org only works
+    with the PUBLIC schema. This limitation will hopefully removed in the
+    future versions of OOo.</p>
+<p>When using of HyperSQL with OOo, you must use the HyperSQL jar
+    that is supplied with OOo. This wil hopefuly be a version 2.0 jar in the
+    future versions of OOo.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N147DE"></a>Converting .odb files to use with HyperSQL Server</h2>
+</div>
+</div>
+</div>
+<p>You may already have an OOo database file, which you want to use
+    outside OOo, or as a server database. The file is in fact in the standard
+    ZIP format and contains the normal HyperSQL database files. Just use a
+    utility such as 7Zip to expand the .odb file. In the /db directory, there
+    are files such as .script, .data, etc. Just rename these files into
+    mydb.script, mydb.data, etc. You can now open the mydb database directly
+    with HyperSQL as an embedded database or as a server instance.</p>
+</div>
+</div>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="N147E4"></a>HyperSQL File Links</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>HyperSQL Files referred to in this Guide</i>
+</h3>
+</div>
+</div>
+</div>
+<p>
+    HyperSQL files referred to in the text may be retrieved from the
+    canonical HyperSQL documentation site, http://hsqldb.org/doc/2.0, or from the
+    same location you are reading this page from.
+  </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+    If you are reading this document with a standalone PDF reader,
+    only the http://hsqldb.org/doc/2.0/... links will function.
+  </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="itemizedlist">
+<p class="title">
+<b>
+      Pairs of local + http://hsqldb.org/doc/2.0 links for referenced files.
+    </b>
+</p>
+<ul type="disc">
+<li>
+<a name="JDBCConnection.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCConnection.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCConnection.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCConnection.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCConnection.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCDriver.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCDriver.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCDriver.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCDriver.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCDriver.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCDatabaseMetaData.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCDatabaseMetaData.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCResultSet.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCResultSet.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCResultSet.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCResultSet.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCResultSet.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCStatement.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCStatement.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCStatement.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCStatement.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCStatement.html</a>
+      
+</p>
+</li>
+<li>
+<a name="JDBCPreparedStatement.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html" target="_top">../apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jdbc/JDBCPreparedStatement.html</a>
+      
+</p>
+</li>
+<li>
+<a name="MainInvoker.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/util/MainInvoker.html" target="_top">../apidocs/org/hsqldb/util/MainInvoker.html</a>
+      
+</p>
+<p>
+      
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/util/MainInvoker.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/util/MainInvoker.html</a>
+      
+</p>
+</li>
+<li>
+<a name="javadoc-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/index.html" target="_top">../apidocs/index.html</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/" target="_top">http://hsqldb.org/doc/2.0/apidocs/</a>
+      
+</p>
+</li>
+<li>
+<a name="Servlet.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/server/Servlet.java" target="_top">../verbatim/src/org/hsqldb/server/Servlet.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/server/Servlet.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/server/Servlet.java</a>
+      
+</p>
+</li>
+<li>
+<a name="Tokens.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/Tokens.java" target="_top">../verbatim/src/org/hsqldb/Tokens.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/Tokens.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/Tokens.java</a>
+      
+</p>
+</li>
+<li>
+<a name="WebServer.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/server/WebServer.java" target="_top">../verbatim/src/org/hsqldb/server/WebServer.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/server/WebServer.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/server/WebServer.java</a>
+      
+</p>
+</li>
+<li>
+<a name="TestBase.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/test/TestBase.java" target="_top">../verbatim/src/org/hsqldb/test/TestBase.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/test/TestBase.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/test/TestBase.java</a>
+      
+</p>
+</li>
+<li>
+<a name="Trigger.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/Trigger.java" target="_top">../verbatim/src/org/hsqldb/Trigger.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/Trigger.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/Trigger.java</a>
+      
+</p>
+</li>
+<li>
+<a name="TriggerSample.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/sample/TriggerSample.java" target="_top">../verbatim/src/org/hsqldb/sample/TriggerSample.java</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/test/sample/TriggerSample.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/test/sample/TriggerSample.java</a>
+      
+</p>
+</li>
+<li>
+<a name="MainInvoker.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/util/MainInvoker.java" target="_top">../verbatim/src/org/hsqldb/util/MainInvoker.java</a>
+      
+</p>
+<p>
+      
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/util/MainInvoker.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/util/MainInvoker.java</a>
+      
+</p>
+</li>
+<li>
+<a name="hsqldb.cfg-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/hsqldb.cfg" target="_top">../verbatim/sample/hsqldb.cfg</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/hsqldb.cfg" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/hsqldb.cfg</a>
+      
+</p>
+</li>
+<li>
+<a name="acl.txt-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/acl.txt" target="_top">../verbatim/sample/acl.txt</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/acl.txt" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/acl.txt</a>
+      
+</p>
+</li>
+<li>
+<a name="server.properties-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/server.properties" target="_top">../verbatim/sample/server.properties</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/server.properties" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/server.properties</a>
+      
+</p>
+</li>
+<li>
+<a name="sqltool.rc-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/sqltool.rc" target="_top">../verbatim/sample/sqltool.rc</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/sqltool.rc" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/sqltool.rc</a>
+      
+</p>
+</li>
+<li>
+<a name="hsqldb.init-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/hsqldb.init" target="_top">../verbatim/sample/hsqldb.init</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/hsqldb.init" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/hsqldb.init</a>
+      
+</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="index">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sql-ind"></a>SQL Index</h2>
+</div>
+</div>
+</div>
+<div class="index">
+<div class="indexdiv">
+<h3>Symbols</h3>
+<dl>
+<dt>_SYSTEM ROLE, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>A</h3>
+<dl>
+<dt>ABS function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ACOS function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ADD COLUMN, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ADD CONSTRAINT, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ADD DOMAIN CONSTRAINT, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>aggregate function, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>ALL and ANY predicates, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>ALTER COLUMN, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>alter column nullability, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER DOMAIN, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>alter identity column, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER routine, <a class="indexterm" href="#N1124D">Routine Creation</a>
+</dt>
+<dt>ALTER SEQUENCE, <a class="indexterm" href="#N112F5">Sequence Creation</a>
+</dt>
+<dt>ALTER TABLE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER USER ... SET INITIAL SCHEMA, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>ALTER USER ... SET PASSWORD, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>ALTER view, <a class="indexterm" href="#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>ASCII function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>ASIN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ATAN2 function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ATAN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>AUTHORIZATION IDENTIFIER, <a class="indexterm" href="#N11752">Authorizations and Access Control</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>B</h3>
+<dl>
+<dt>BACKUP DATABASE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>BETWEEN predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>binary literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>BINARY types, <a class="indexterm" href="#N104D7">Binary String Types</a>
+</dt>
+<dt>BIT_LENGTH function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>BITAND function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>bit literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>BITOR function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>BIT types, <a class="indexterm" href="#N104F5">Bit String Types</a>
+</dt>
+<dt>BITXOR function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>boolean literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>BOOLEAN types, <a class="indexterm" href="#N10482">Boolean Type</a>
+</dt>
+<dt>boolean value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>C</h3>
+<dl>
+<dt>CARDINALITY function, <a class="indexterm" href="#N132C8">Array Functions</a>
+</dt>
+<dt>CASCADE or RESTRICT, <a class="indexterm" href="#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>case expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>CASE WHEN in routines, <a class="indexterm" href="#N12699">Conditional Statements</a>
+</dt>
+<dt>CAST, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>CEIL function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>CHANGE_AUTHORIZATION, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>CHARACTER_LENGTH, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>character literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>CHARACTER types, <a class="indexterm" href="#N104A8">Character String Types</a>
+</dt>
+<dt>character value function, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>CHECK constraint, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CHECKPOINT, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>COALESCE expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>COALESCE function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>COLLATE, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>column definition, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>column reference, <a class="indexterm" href="#N11B9C">References, etc.</a>
+</dt>
+<dt>COMMENT, <a class="indexterm" href="#N10D01">Commenting Objects</a>
+</dt>
+<dt>COMMIT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>comparison predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>CONCAT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>CONSTRAINT, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>CONSTRAINT (table constraint), <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CONSTRAINT name and characteristics, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>contextually typed value specification, <a class="indexterm" href="#N11B9C">References, etc.</a>
+</dt>
+<dt>CONVERT function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>COS function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>COT function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>CREATE_SCHEMA ROLE, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>CREATE AGGREGATE FUNCTION, <a class="indexterm" href="#N12802">Definition of Aggregate Functions</a>
+</dt>
+<dt>CREATE ASSERTION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE CAST, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE CHARACTER SET, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE COLLATION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE DOMAIN, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>CREATE FUNCTION, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>CREATE INDEX, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE PROCEDURE, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>CREATE ROLE, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>CREATE SCHEMA, <a class="indexterm" href="#N10D1D">Schema Creation</a>
+</dt>
+<dt>CREATE SEQUENCE, <a class="indexterm" href="#N112F5">Sequence Creation</a>
+</dt>
+<dt>CREATE TABLE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CREATE TRANSLATION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE TRIGGER, <a class="indexterm" href="#N111D1">Trigger Creation</a>, <a class="indexterm" href="#N12A85">Trigger Creation</a>
+</dt>
+<dt>CREATE TYPE, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE USER, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>CREATE VIEW, <a class="indexterm" href="#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>CROSS JOIN, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>CRYPT_KEY, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>CRYPT_KEY function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURDATE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_CATALOG function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_DATE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_ROLE function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_SCHEMA function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_TIME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_TIMESTAMP function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_USER function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURTIME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>D</h3>
+<dl>
+<dt>DATABASE_ISOLATION_LEVEL function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATABASE_TIMEZONE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DATABASE_VERSION function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATABASE function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATEADD function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DATEDIFF function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>datetime and interval literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>Datetime Operations, <a class="indexterm" href="#N10544">Datetime types</a>
+</dt>
+<dt>DATETIME types, <a class="indexterm" href="#N10544">Datetime types</a>
+</dt>
+<dt>datetime value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>datetime value function, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>DAYNAME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFMONTH function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFWEEK function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFYEAR function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DBA ROLE, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>DECODE function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>DEFAULT clause, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DEGREES function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>DELETE FROM, <a class="indexterm" href="#N123DD">Delete Statement</a>
+</dt>
+<dt>DETERMINISTIC characteristic, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>DIFFERENCE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>DISCONNECT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>DROP ASSERTION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP CAST, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP CHARACTER SET, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP COLLATION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP COLUMN, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP CONSTRAINT, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP DEFAULT (table), <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN CONSTRAINT, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN DEFAULT, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP INDEX, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP ROLE, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>DROP routine, <a class="indexterm" href="#N1124D">Routine Creation</a>
+</dt>
+<dt>DROP SCHEMA, <a class="indexterm" href="#N10D1D">Schema Creation</a>
+</dt>
+<dt>DROP SEQUENCE, <a class="indexterm" href="#N112F5">Sequence Creation</a>
+</dt>
+<dt>DROP TABLE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP TRANSLATION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP TRIGGER, <a class="indexterm" href="#N111D1">Trigger Creation</a>, <a class="indexterm" href="#N12A85">Trigger Creation</a>
+</dt>
+<dt>DROP USER, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>DROP VIEW, <a class="indexterm" href="#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>DYNAMIC RESULT SETS, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>E</h3>
+<dl>
+<dt>EXISTS predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>EXP function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>EXTERNAL NAME, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>EXTRACT function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>F</h3>
+<dl>
+<dt>FLOOR function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>FOREIGN KEY constraint, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>G</h3>
+<dl>
+<dt>GRANTED BY, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GRANT privilege, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GRANT role, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GREATEST function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>GROUPING OPERATIONS, <a class="indexterm" href="#N12338">Grouping Operations</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>H</h3>
+<dl>
+<dt>HEXTORAW function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>HOUR function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>I</h3>
+<dl>
+<dt>identifier chain, <a class="indexterm" href="#N11B9C">References, etc.</a>
+</dt>
+<dt>identifier definition, <a class="indexterm" href="#N10C61">Common Elements and Statements</a>, <a class="indexterm" href="#N11712">Overview</a>
+</dt>
+<dt>IDENTITY function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>IF EXISTS, <a class="indexterm" href="#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>IFNULL function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>IF STATEMENT, <a class="indexterm" href="#N12699">Conditional Statements</a>
+</dt>
+<dt>IN predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>INSERT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>INSERT INTO, <a class="indexterm" href="#N1241F">Insert Statement</a>
+</dt>
+<dt>interval absolute value function, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>interval term, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>INTERVAL types, <a class="indexterm" href="#N1063D">Interval Types</a>
+</dt>
+<dt>ISAUTOCOMMIT function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>IS DISTINCT predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>IS NULL predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>ISOLATION_LEVEL function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYDATABASEFILES function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYDATABASE function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYSESSION function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>J</h3>
+<dl>
+<dt>JOIN USING, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>JOIN with condition, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>L</h3>
+<dl>
+<dt>LANGUAGE, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>LCASE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LEAST function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>LEFT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LENGTH function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LIKE predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>LN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LOCALTIME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>LOCALTIMESTAMP function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>LOCATE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LOCK TABLE, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>LOG10 function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LOG function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LTRIM function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>M</h3>
+<dl>
+<dt>MATCH predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>MAX_CARDINALITY function, <a class="indexterm" href="#N132C8">Array Functions</a>
+</dt>
+<dt>MERGE INTO, <a class="indexterm" href="#N124B8">Merge Statement</a>
+</dt>
+<dt>MINUTE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>MOD function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>MONTH function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>MONTHNAME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>N</h3>
+<dl>
+<dt>name resolution, <a class="indexterm" href="#N122F6">Naming</a>
+</dt>
+<dt>naming in joined table, <a class="indexterm" href="#N122F6">Naming</a>
+</dt>
+<dt>naming in select list, <a class="indexterm" href="#N122F6">Naming</a>
+</dt>
+<dt>NATURAL JOIN, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>NEXT VALUE FOR, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>NOW function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>NULLIF expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>NULLIF function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>NULL INPUT, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>numeric literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>NUMERIC types, <a class="indexterm" href="#N103BA">Numeric Types</a>
+</dt>
+<dt>numeric value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>numeric value function, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>NVL function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>O</h3>
+<dl>
+<dt>OCTET_LENGTH function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>OTHER type, <a class="indexterm" href="#N1050A">Storage and Handling of Java Objects</a>
+</dt>
+<dt>OUTER JOIN, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>OVERLAPS predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>OVERLAY function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>P</h3>
+<dl>
+<dt>PATH, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>PI function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>POSITION function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>POWER function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>PRIMARY KEY constraint, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>PUBLIC ROLE, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>Q</h3>
+<dl>
+<dt>QUARTER function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>R</h3>
+<dl>
+<dt>RADIANS function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>RAND function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>RAWTOHEX function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REGEXP_MATCHES function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>RELEASE SAVEPOINT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>RENAME, <a class="indexterm" href="#N10CE1">Renaming Objects</a>
+</dt>
+<dt>REPEAT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REPLACE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>RETURN, <a class="indexterm" href="#N126E2">Return Statement</a>
+</dt>
+<dt>RETURNS, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>REVERSE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REVOKE, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>REVOKE ROLE, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>RIGHT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>ROLLBACK, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>ROLLBACK TO SAVEPOINT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>ROUND function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>routine body, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>routine invocation, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>row value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>RTRIM function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>S</h3>
+<dl>
+<dt>SA USER, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>SAVEPOINT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SAVEPOINT LEVEL, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>schema routine, <a class="indexterm" href="#N1124D">Routine Creation</a>
+</dt>
+<dt>SCRIPT, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>search condition, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>SECOND function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SECONDS_SINCE_MIDNIGHT function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SELECT : SINGLE ROW, <a class="indexterm" href="#N12648">Select Statement : Single Row</a>
+</dt>
+<dt>SESSION_ISOLATION_LEVEL function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>SESSION_TIMEZONE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SESSION_USER function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>SET AUTOCOMMIT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET CATALOG, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>set clause in UPDATE and MERGE statements, <a class="indexterm" href="#N1246A">Update Statement</a>
+</dt>
+<dt>SET CONSTRAINTS, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET DATABASE COLLATION, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE DEFAULT INITIAL SCHEMA, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET DATABASE DEFAULT RESULT MEMORY ROWS, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE DEFAULT TABLE TYPE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE EVENT LOG LEVEL, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE GC, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL NAMES, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL REFERENCES, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL SIZE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE TRANSACTION CONTROL, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE UNIQUE NAME*, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATA TYPE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET DEFAULT, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET DOMAIN DEFAULT, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>SET FILES BACKUP INCREMENT, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES CACHE ROWS, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES CACHE SIZE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES DEFRAG, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOB SCALE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOG, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOG SIZE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES NIO, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES SCALE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES WRITE DELAY, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>set function specification, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>SET IGNORECASE, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET INITIAL SCHEMA*, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET MAXROWS, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET OPERATIONS, <a class="indexterm" href="#N1234D">Set Operations</a>
+</dt>
+<dt>SET PASSWORD, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET PATH, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET REFERENTIAL INTEGRITY, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET ROLE, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SCHEMA, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION AUTHORIZATION, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION CHARACTERISTICS, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION RESULT MEMORY ROWS, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET TABLE read-write property, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE HEADER, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE on-off, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TIME ZONE, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET TRANSACTION, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SHUTDOWN, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SIGN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>SIN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>sort specification list, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>SOUNDEX function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SPACE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SPECIFIC, <a class="indexterm" href="#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>SPECIFIC NAME, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>SQL DATA access characteristic, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>SQL parameter reference, <a class="indexterm" href="#N11B9C">References, etc.</a>
+</dt>
+<dt>SQL procedure statement, <a class="indexterm" href="#N1137F">SQL Procedure Statement</a>
+</dt>
+<dt>SQL routine body, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>SQRT function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>START TRANSACTION, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>string value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>SUBSTR function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SUBSTRING function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SYSTEM_USER function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>T</h3>
+<dl>
+<dt>TAN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>TIMESTAMPADD function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TIMESTAMPDIFF function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>Time Zone, <a class="indexterm" href="#N10544">Datetime types</a>
+</dt>
+<dt>TIMEZONE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TO_CHAR function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TRANSACTION_CONTROL function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>transaction characteristics, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>TRIGGERED SQL STATEMENT, <a class="indexterm" href="#N12A85">Trigger Creation</a>
+</dt>
+<dt>TRIGGER EXECUTION ORDER, <a class="indexterm" href="#N12A85">Trigger Creation</a>
+</dt>
+<dt>TRIM_ARRAY function, <a class="indexterm" href="#N132C8">Array Functions</a>
+</dt>
+<dt>TRIM function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>TRUNCATE function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>TRUNCATE TABLE, <a class="indexterm" href="#N123FD">Truncate Statement</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>U</h3>
+<dl>
+<dt>UCASE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>unicode escape elements, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>UNION JOIN, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>UNIQUE constraint, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>UNIQUE predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>UPDATE, <a class="indexterm" href="#N1246A">Update Statement</a>
+</dt>
+<dt>USER function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>V</h3>
+<dl>
+<dt>value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>value expression primary, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>value specification, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>W</h3>
+<dl>
+<dt>WEEK function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>Y</h3>
+<dl>
+<dt>YEAR function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+</div>
+</div>
+<div class="index">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="book-ind"></a>General Index</h2>
+</div>
+</div>
+</div>
+<div class="index">
+<div class="indexdiv">
+<h3>Symbols</h3>
+<dl>
+<dt>_SYSTEM ROLE, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>A</h3>
+<dl>
+<dt>ABS function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ACL, <a class="indexterm" href="#listeners_acl-sect">Network Access Control</a>
+</dt>
+<dt>ACOS function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ADD COLUMN, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ADD CONSTRAINT, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ADD DOMAIN CONSTRAINT, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>aggregate function, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>ALL and ANY predicates, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>ALTER COLUMN, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>alter column nullability, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER DOMAIN, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>alter identity column, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER routine, <a class="indexterm" href="#N1124D">Routine Creation</a>
+</dt>
+<dt>ALTER SEQUENCE, <a class="indexterm" href="#N112F5">Sequence Creation</a>
+</dt>
+<dt>ALTER TABLE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER USER ... SET INITIAL SCHEMA, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>ALTER USER ... SET PASSWORD, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>ALTER view, <a class="indexterm" href="#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>Ant, <a class="indexterm" href="#building-ant-sect">Building with Apache Ant</a>
+</dt>
+<dt>ASCII function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>ASIN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ATAN2 function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ATAN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>AUTHORIZATION IDENTIFIER, <a class="indexterm" href="#N11752">Authorizations and Access Control</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>B</h3>
+<dl>
+<dt>backup, <a class="indexterm" href="#deployment_backup-sect">Backing Up Database Catalogs</a>
+</dt>
+<dt>BACKUP DATABASE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>BETWEEN predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>binary literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>BINARY types, <a class="indexterm" href="#N104D7">Binary String Types</a>
+</dt>
+<dt>BIT_LENGTH function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>BITAND function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>bit literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>BITOR function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>BIT types, <a class="indexterm" href="#N104F5">Bit String Types</a>
+</dt>
+<dt>BITXOR function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>boolean literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>BOOLEAN types, <a class="indexterm" href="#N10482">Boolean Type</a>
+</dt>
+<dt>boolean value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>C</h3>
+<dl>
+<dt>CARDINALITY function, <a class="indexterm" href="#N132C8">Array Functions</a>
+</dt>
+<dt>CASCADE or RESTRICT, <a class="indexterm" href="#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>case expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>CASE WHEN in routines, <a class="indexterm" href="#N12699">Conditional Statements</a>
+</dt>
+<dt>CAST, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>CEIL function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>CHANGE_AUTHORIZATION, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>CHARACTER_LENGTH, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>character literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>CHARACTER types, <a class="indexterm" href="#N104A8">Character String Types</a>
+</dt>
+<dt>character value function, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>CHECK constraint, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CHECKPOINT, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>COALESCE expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>COALESCE function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>COLLATE, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>column definition, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>column reference, <a class="indexterm" href="#N11B9C">References, etc.</a>
+</dt>
+<dt>COMMENT, <a class="indexterm" href="#N10D01">Commenting Objects</a>
+</dt>
+<dt>COMMIT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>comparison predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>CONCAT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>CONSTRAINT, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>CONSTRAINT (table constraint), <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CONSTRAINT name and characteristics, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>contextually typed value specification, <a class="indexterm" href="#N11B9C">References, etc.</a>
+</dt>
+<dt>CONVERT function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>COS function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>COT function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>CREATE_SCHEMA ROLE, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>CREATE AGGREGATE FUNCTION, <a class="indexterm" href="#N12802">Definition of Aggregate Functions</a>
+</dt>
+<dt>CREATE ASSERTION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE CAST, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE CHARACTER SET, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE COLLATION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE DOMAIN, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>CREATE FUNCTION, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>CREATE INDEX, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE PROCEDURE, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>CREATE ROLE, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>CREATE SCHEMA, <a class="indexterm" href="#N10D1D">Schema Creation</a>
+</dt>
+<dt>CREATE SEQUENCE, <a class="indexterm" href="#N112F5">Sequence Creation</a>
+</dt>
+<dt>CREATE TABLE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CREATE TRANSLATION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE TRIGGER, <a class="indexterm" href="#N111D1">Trigger Creation</a>, <a class="indexterm" href="#N12A85">Trigger Creation</a>
+</dt>
+<dt>CREATE TYPE, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE USER, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>CREATE VIEW, <a class="indexterm" href="#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>CROSS JOIN, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>CRYPT_KEY, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>CRYPT_KEY function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURDATE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_CATALOG function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_DATE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_ROLE function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_SCHEMA function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_TIME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_TIMESTAMP function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_USER function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURTIME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>D</h3>
+<dl>
+<dt>DATABASE_ISOLATION_LEVEL function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATABASE_TIMEZONE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DATABASE_VERSION function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATABASE function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATEADD function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DATEDIFF function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>datetime and interval literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>Datetime Operations, <a class="indexterm" href="#N10544">Datetime types</a>
+</dt>
+<dt>DATETIME types, <a class="indexterm" href="#N10544">Datetime types</a>
+</dt>
+<dt>datetime value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>datetime value function, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>DAYNAME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFMONTH function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFWEEK function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFYEAR function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DBA ROLE, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>DECODE function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>DEFAULT clause, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DEGREES function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>DELETE FROM, <a class="indexterm" href="#N123DD">Delete Statement</a>
+</dt>
+<dt>DETERMINISTIC characteristic, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>DIFFERENCE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>DISCONNECT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>DROP ASSERTION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP CAST, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP CHARACTER SET, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP COLLATION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP COLUMN, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP CONSTRAINT, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP DEFAULT (table), <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN CONSTRAINT, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN DEFAULT, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP INDEX, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP ROLE, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>DROP routine, <a class="indexterm" href="#N1124D">Routine Creation</a>
+</dt>
+<dt>DROP SCHEMA, <a class="indexterm" href="#N10D1D">Schema Creation</a>
+</dt>
+<dt>DROP SEQUENCE, <a class="indexterm" href="#N112F5">Sequence Creation</a>
+</dt>
+<dt>DROP TABLE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP TRANSLATION, <a class="indexterm" href="#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP TRIGGER, <a class="indexterm" href="#N111D1">Trigger Creation</a>, <a class="indexterm" href="#N12A85">Trigger Creation</a>
+</dt>
+<dt>DROP USER, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>DROP VIEW, <a class="indexterm" href="#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>DYNAMIC RESULT SETS, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>E</h3>
+<dl>
+<dt>EXISTS predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>EXP function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>EXTERNAL NAME, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>EXTRACT function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>F</h3>
+<dl>
+<dt>FLOOR function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>FOREIGN KEY constraint, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>G</h3>
+<dl>
+<dt>GRANTED BY, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GRANT privilege, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GRANT role, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GREATEST function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>GROUPING OPERATIONS, <a class="indexterm" href="#N12338">Grouping Operations</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>H</h3>
+<dl>
+<dt>HEXTORAW function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>HOUR function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>I</h3>
+<dl>
+<dt>identifier chain, <a class="indexterm" href="#N11B9C">References, etc.</a>
+</dt>
+<dt>identifier definition, <a class="indexterm" href="#N10C61">Common Elements and Statements</a>, <a class="indexterm" href="#N11712">Overview</a>
+</dt>
+<dt>IDENTITY function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>IF EXISTS, <a class="indexterm" href="#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>IFNULL function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>IF STATEMENT, <a class="indexterm" href="#N12699">Conditional Statements</a>
+</dt>
+<dt>init script, <a class="indexterm" href="#unix_daemon-sect">Running Hsqldb as a System Daemon</a>
+</dt>
+<dt>IN predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>INSERT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>INSERT INTO, <a class="indexterm" href="#N1241F">Insert Statement</a>
+</dt>
+<dt>interval absolute value function, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>interval term, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>INTERVAL types, <a class="indexterm" href="#N1063D">Interval Types</a>
+</dt>
+<dt>ISAUTOCOMMIT function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>IS DISTINCT predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>IS NULL predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>ISOLATION_LEVEL function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYDATABASEFILES function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYDATABASE function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYSESSION function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>J</h3>
+<dl>
+<dt>JOIN USING, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>JOIN with condition, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>L</h3>
+<dl>
+<dt>LANGUAGE, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>LCASE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LEAST function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>LEFT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LENGTH function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LIKE predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>LN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LOCALTIME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>LOCALTIMESTAMP function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>LOCATE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LOCK TABLE, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>LOG10 function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LOG function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LTRIM function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>M</h3>
+<dl>
+<dt>MATCH predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>MAX_CARDINALITY function, <a class="indexterm" href="#N132C8">Array Functions</a>
+</dt>
+<dt>memory use, <a class="indexterm" href="#deployment_mem_disk-sect">Memory and Disk Use</a>
+</dt>
+<dt>MERGE INTO, <a class="indexterm" href="#N124B8">Merge Statement</a>
+</dt>
+<dt>MINUTE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>MOD function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>MONTH function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>MONTHNAME function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>N</h3>
+<dl>
+<dt>name resolution, <a class="indexterm" href="#N122F6">Naming</a>
+</dt>
+<dt>naming in joined table, <a class="indexterm" href="#N122F6">Naming</a>
+</dt>
+<dt>naming in select list, <a class="indexterm" href="#N122F6">Naming</a>
+</dt>
+<dt>NATURAL JOIN, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>NEXT VALUE FOR, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>NOW function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>NULLIF expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>NULLIF function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+<dt>NULL INPUT, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>numeric literal, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>NUMERIC types, <a class="indexterm" href="#N103BA">Numeric Types</a>
+</dt>
+<dt>numeric value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>numeric value function, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>NVL function, <a class="indexterm" href="#N132FD">General Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>O</h3>
+<dl>
+<dt>OCTET_LENGTH function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>OTHER type, <a class="indexterm" href="#N1050A">Storage and Handling of Java Objects</a>
+</dt>
+<dt>OUTER JOIN, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>OVERLAPS predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>OVERLAY function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>P</h3>
+<dl>
+<dt>PATH, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>PI function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>POSITION function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>POWER function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>PRIMARY KEY constraint, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>PUBLIC ROLE, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>Q</h3>
+<dl>
+<dt>QUARTER function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>R</h3>
+<dl>
+<dt>RADIANS function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>RAND function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>RAWTOHEX function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REGEXP_MATCHES function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>RELEASE SAVEPOINT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>RENAME, <a class="indexterm" href="#N10CE1">Renaming Objects</a>
+</dt>
+<dt>REPEAT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REPLACE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>RETURN, <a class="indexterm" href="#N126E2">Return Statement</a>
+</dt>
+<dt>RETURNS, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>REVERSE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REVOKE, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>REVOKE ROLE, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>RIGHT function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>ROLLBACK, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>ROLLBACK TO SAVEPOINT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>ROUND function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>routine body, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>routine invocation, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>row value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>RTRIM function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>S</h3>
+<dl>
+<dt>SA USER, <a class="indexterm" href="#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>SAVEPOINT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SAVEPOINT LEVEL, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>schema routine, <a class="indexterm" href="#N1124D">Routine Creation</a>
+</dt>
+<dt>SCRIPT, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>search condition, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>SECOND function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SECONDS_SINCE_MIDNIGHT function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>security, <a class="indexterm" href="#running_security-sect">Security Considerations</a>, <a class="indexterm" href="#listeners_tls-sect">TLS Encryption</a>, <a class="indexterm" href="#listeners_acl-sect">Network Access Control</a>
+</dt>
+<dt>SELECT : SINGLE ROW, <a class="indexterm" href="#N12648">Select Statement : Single Row</a>
+</dt>
+<dt>SESSION_ISOLATION_LEVEL function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>SESSION_TIMEZONE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SESSION_USER function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>SET AUTOCOMMIT, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET CATALOG, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>set clause in UPDATE and MERGE statements, <a class="indexterm" href="#N1246A">Update Statement</a>
+</dt>
+<dt>SET CONSTRAINTS, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET DATABASE COLLATION, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE DEFAULT INITIAL SCHEMA, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET DATABASE DEFAULT RESULT MEMORY ROWS, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE DEFAULT TABLE TYPE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE EVENT LOG LEVEL, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE GC, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL NAMES, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL REFERENCES, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL SIZE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE TRANSACTION CONTROL, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE UNIQUE NAME*, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET DATA TYPE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET DEFAULT, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET DOMAIN DEFAULT, <a class="indexterm" href="#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>SET FILES BACKUP INCREMENT, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES CACHE ROWS, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES CACHE SIZE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES DEFRAG, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOB SCALE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOG, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOG SIZE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES NIO, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES SCALE, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET FILES WRITE DELAY, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>set function specification, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>SET IGNORECASE, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET INITIAL SCHEMA*, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET MAXROWS, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET OPERATIONS, <a class="indexterm" href="#N1234D">Set Operations</a>
+</dt>
+<dt>SET PASSWORD, <a class="indexterm" href="#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET PATH, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET REFERENTIAL INTEGRITY, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SET ROLE, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SCHEMA, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION AUTHORIZATION, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION CHARACTERISTICS, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION RESULT MEMORY ROWS, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET TABLE read-write property, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE HEADER, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE on-off, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TIME ZONE, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET TRANSACTION, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SHUTDOWN, <a class="indexterm" href="#N137E9">Statements</a>
+</dt>
+<dt>SIGN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>SIN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>sort specification list, <a class="indexterm" href="#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>SOUNDEX function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SPACE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SPECIFIC, <a class="indexterm" href="#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>SPECIFIC NAME, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>SQL DATA access characteristic, <a class="indexterm" href="#N1291D">Routine Characteristics</a>
+</dt>
+<dt>SQL parameter reference, <a class="indexterm" href="#N11B9C">References, etc.</a>
+</dt>
+<dt>SQL procedure statement, <a class="indexterm" href="#N1137F">SQL Procedure Statement</a>
+</dt>
+<dt>SQL routine body, <a class="indexterm" href="#N12854">Routine Definition</a>
+</dt>
+<dt>SQRT function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>START TRANSACTION, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>string value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>SUBSTR function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SUBSTRING function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SYSTEM_USER function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>T</h3>
+<dl>
+<dt>TAN function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>TIMESTAMPADD function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TIMESTAMPDIFF function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>Time Zone, <a class="indexterm" href="#N10544">Datetime types</a>
+</dt>
+<dt>TIMEZONE function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TO_CHAR function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TRANSACTION_CONTROL function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>transaction characteristics, <a class="indexterm" href="#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>TRIGGERED SQL STATEMENT, <a class="indexterm" href="#N12A85">Trigger Creation</a>
+</dt>
+<dt>TRIGGER EXECUTION ORDER, <a class="indexterm" href="#N12A85">Trigger Creation</a>
+</dt>
+<dt>TRIM_ARRAY function, <a class="indexterm" href="#N132C8">Array Functions</a>
+</dt>
+<dt>TRIM function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>TRUNCATE function, <a class="indexterm" href="#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>TRUNCATE TABLE, <a class="indexterm" href="#N123FD">Truncate Statement</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>U</h3>
+<dl>
+<dt>UCASE function, <a class="indexterm" href="#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>unicode escape elements, <a class="indexterm" href="#N11A76">Literals</a>
+</dt>
+<dt>UNION JOIN, <a class="indexterm" href="#N12278">Joined Table</a>
+</dt>
+<dt>UNIQUE constraint, <a class="indexterm" href="#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>UNIQUE predicate, <a class="indexterm" href="#N11E1B">Predicates</a>
+</dt>
+<dt>UPDATE, <a class="indexterm" href="#N1246A">Update Statement</a>
+</dt>
+<dt>upgrading, <a class="indexterm" href="#deployment_upgrade-sect">Upgrading Databases</a>
+</dt>
+<dt>USER function, <a class="indexterm" href="#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>V</h3>
+<dl>
+<dt>value expression, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>value expression primary, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+<dt>value specification, <a class="indexterm" href="#N11BF8">Value Expression</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>W</h3>
+<dl>
+<dt>WEEK function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>Y</h3>
+<dl>
+<dt>YEAR function, <a class="indexterm" href="#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+</div>
+</div>
+</div>
+<HR>
+<P class="svnrev">$Revision: 3601 $</P>
+</body>
+</html>
diff --git a/doc/guide/guide.pdf b/doc/guide/guide.pdf
new file mode 100644
index 0000000..0ad3b42
--- /dev/null
+++ b/doc/guide/guide.pdf
Binary files differ
diff --git a/doc/guide/index.html b/doc/guide/index.html
new file mode 100644
index 0000000..31551a6
--- /dev/null
+++ b/doc/guide/index.html
@@ -0,0 +1,1246 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>HyperSQL User Guide</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="next" href="book-pref.html" title="Preface">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%">&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">HyperSQL User Guide</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="book-pref.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">&nbsp;</td><td align="center" width="40%">&nbsp;</td><td valign="top" align="right" width="30%">&nbsp;Preface</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="book" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="guide"></a>HyperSQL User Guide</h1>
+</div>
+<div>
+<h2 class="subtitle">HyperSQL Database Engine, aka HSQLDB</h2>
+</div>
+<table xmlns:xi="http://www.w3.org/2001/XInclude" class="titlead" cellspacing="0">
+<tr>
+<td>
+<div>
+<div class="authorgroup">
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="orgname">The HSQL Development Group</span>
+</h3>
+</div>
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N1003A"></a>
+<p>Copyright 2002-2010 The HSQL Development Group. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</td><td class="sponsorad">
+<div xml:base="../doc-src/branding-frag.xhtml" class="branding">
+<img src="../images/hypersql_logo.png"></div>
+</td>
+</tr>
+</table>
+</div>
+<hr>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="preface"><a href="book-pref.html">Preface</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="book-pref.html#altformats-sect">Available formats for this document</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="running-chapt.html">1. Running and Using HyperSQL</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="running-chapt.html#running_jar-sect">The HSQLDB Jar</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_tools-sect">Running Database Access Tools</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_db-sect">A HyperSQL Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_inprocess-sect">In-Process Access to Database Catalogs</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_modes-sect">Listener / Server Modes</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="running-chapt.html#running_hsqlserver-sect">HyperSQL HSQL Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_httpserver-sect">HyperSQL HTTP Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_servlet-sect">HyperSQL HTTP Servlet</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_connecting-sect">Connecting to a Database Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_security-sect">Security Considerations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_multiple_db-sect">Using Multiple Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="running-chapt.html#running-data-access-sect">Accessing the Data</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_closing-sect">Closing the Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_newdb-sect">Creating a New Database</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="sqlgeneral-chapt.html">2. SQL Language</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#sqlgeneral_standards-sect">Standards Support</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#sqlgeneral_tabletypes-sect">SQL Data and Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N1037B">Temporary Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10380">Persistent Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N103A7">Lob Data</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#sqlgeneral_types_ops-sect">Basic Types and Operations</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N103BA">Numeric Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10482">Boolean Type</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N104A8">Character String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N104D7">Binary String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N104F5">Bit String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N1050A">Storage and Handling of Java Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10529">Type Length, Precision and Scale</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10544">Datetime types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N1063D">Interval Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N106BD">Arrays</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N106CA">Array Definition</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N106ED">Array Reference</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10706">Array Operations</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#sqlgeneral_constr_indexes-sect">Indexes and Query Speed</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N1079B">Query Processing and Optimisation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="sessions-chapt.html">3. Sessions and Transactions</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N107E2">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10801">Session Attributes and Variables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10806">Session Attributes</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10814">Session Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10822">Session Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sessions-chapt.html#sqlgeneral_trans_cc-sect">Transactions and Concurrency Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10846">Two Phase Locking</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10859">Two Phase Locking with Snapshot Isolation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10862">Lock Contention in 2PL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N1086D">MVCC</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N1087A">Choosing the Transaction Model</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10887">Schema and Database Change</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10892">Simultaneous Access to Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="databaseobjects-chapt.html">4. Schemas and Database Objects</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10AC7">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10AD2">Schemas and Schema Objects</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10AF8">Names and References</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B18">Character Sets</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B32">Collations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B3F">Distinct Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B46">Domains</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10B4D">Number Sequences</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10BA3">Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10BAF">Views</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10BCD">Constraints</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C26">Assertions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C30">Triggers</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C3E">Routines</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C57">Indexes</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C5C">Statements for Schema Definition and Manipulation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10CE1">Renaming Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10D01">Commenting Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10D1D">Schema Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N110DE">View Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N111D1">Trigger Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N1124D">Routine Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N112F5">Sequence Creation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N1137F">SQL Procedure Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N114B8">The Information Schema</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N114C3">Predefined Character Sets, Collations and Domains</a></span>
+</dt>
+<dt>
+<span class="section"><a href="databaseobjects-chapt.html#N114CE">Views in INFORMATION SCHEMA</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="texttables-chapt.html">5. Text Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="texttables-chapt.html#texttables_overview-sect">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#texttables_impl-sect">The Implementation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N115BF">Definition of Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N115CF">Scope and Reassignment</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N115E5">Null Values in Columns of Text Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N115EF">Configuration</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#disconnecting_text_tables">Disconnecting Text Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="texttables-chapt.html#texttables_issues-sect">Text File Usage</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#texttables_globalprops-sect">Text File Global Properties</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N116E4">Transactions</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="accesscontrol-chapt.html">6. Access Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N11712">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N11752">Authorizations and Access Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a></span>
+</dt>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N117CE">Access Rights</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="dataaccess-chapt.html">7. Data Access and Change</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1199B">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N119A0">Cursors And Result Sets</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N119BD">Columns and Rows</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N119D8">Navigation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N119EA">Updatability</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A28">Sensitivity</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A31">Holdability</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A44">Autocommit</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A4C">JDBC Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A59">JDBC Parameters</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A68">JDBC Returned Values</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A71">Syntax Elements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11A76">Literals</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11B9C">References, etc.</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11BF8">Value Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N11E1B">Predicates</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12147">Data Access Statements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1217F">Table</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12199">Query Specification</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N121DF">Table Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12246">Table Primary</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12278">Joined Table</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N122E5">Selection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N122EA">Projection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N122F1">Computed Columns</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N122F6">Naming</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12338">Grouping Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12346">Aggregation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1234D">Set Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N12371">Query Expression</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123B0">Ordering</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123C8">Slicing</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123DA">Data Change Statements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123DD">Delete Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N123FD">Truncate Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1241F">Insert Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N1246A">Update Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dataaccess-chapt.html#N124B8">Merge Statement</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="sqlroutines-chapt.html">8. SQL-Invoked Routines</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1257C">SQL Language Routines (PSM)</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12597">Routine Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N125DC">Compound Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N125EE">Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12604">Handlers</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12632">Assignment Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12648">Select Statement : Single Row</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12663">Formal Parameters</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1267E">Iterated Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12699">Conditional Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N126E2">Return Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N126FD">Control Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1271F">Routine Polymorphism</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1272E">Returning Data From Routines</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12748">Java Language Routines (SQL/JRT)</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N127C5">Polymorphism</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N127D2">Java Language Procedures</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N127EB">Legacy Support</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N127FB">SQL Language Aggregate Functions</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12802">Definition of Aggregate Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12828">SQL PSM Aggregate Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1283E">Java Aggregate Functions</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12854">Routine Definition</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="triggers-chapt.html">9. Triggers</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A02">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A26">Trigger Properties</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A2B">Trigger Event</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A34">Granularity</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A43">Trigger Action Time</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A50">References to Rows</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A55">Trigger Condition</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A5C">Trigger Action in SQL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A6B">Trigger Action in Java</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A85">Trigger Creation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="builtinfunctions-chapt.html">10. Built In Functions</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_intro-sect">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#N132C8">Array Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#N132FD">General Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="deployment-chapt.html">11. System Management and Deployment
+  Issues</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deploymen_modes-sect">Mode of Operation and Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13506">Mode of Operation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13525">Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1353A">Large Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1354D">Deployment context</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13559">Readonly Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deployment_mem_disk-sect">Memory and Disk Use</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13571">Table Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1357F">Result Set Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13594">Temporary Memory Use During Operations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135A0">Data Cache Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135BF">Object Pool Memory Allocation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135C7">Lob Memory Usage</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135CC">Disk Space</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deployment_conns-sect">Managing Database Connections</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135F4">Tweaking the Mode of Operation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N135F9">Application Development and Testing</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1362A">Embedded Databases in Desktop Applications</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13632">Embedded Databases in Server Applications</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13639">Embedding a Database Listener</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1365D">Using HyperSQL Without Logging</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1366B">Server Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deployment_upgrade-sect">Upgrading Databases</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#upgrade_via_script-sect">Upgrading From Older
+      Versions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N136B7">Manual Changes to the *.script File</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N136FB">Backward Compatibility Issues</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#deployment_backup-sect">Backing Up Database Catalogs</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13742">Making Online Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13751">Making Offline Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1376E">Examining Backups</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N13784">Restoring a Backup</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N1379B">Encrypted Databases</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137A2">Creating and Accessing an Encrypted Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137B2">Speed Considerations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137B7">Security Considerations</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137C8">Monitoring Database Operations</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137CD">Statement Level Monitoring</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137D6">Internal Event Monitoring</a></span>
+</dt>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137E4">Server Operation Monitoring</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="deployment-chapt.html#N137E9">Statements</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="dbproperties-chapt.html">12. Properties</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dbproperties-chapt.html#dbproperties_connections-sect">Connections</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dbproperties-chapt.html#conn_props-sect">Connection properties</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="dbproperties-chapt.html#N13C11">Database Properties in Connection URL and Properties</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="listeners-chapt.html">13. HyperSQL Network Listeners</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners-sect">Listeners</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_hsqlserver-sect">HyperSQL Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_httpserver-sect">HyperSQL HTTP Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_servlet-sect">HyperSQL HTTP Servlet</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_server_props-sect">Server and Web Server Properties</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_appstart-sect">Starting a Server from your application</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#N14099">Allowing a Connection to Open a Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_tls-sect">TLS Encryption</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="listeners-chapt.html#N140DB">Requirements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#N140F8">Encrypting your JDBC connection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#jsse-sect">JSSE</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#privatekey-sect">Making a Private-key Keystore</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#N141EB">Automatic Server or WebServer startup on UNIX</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_acl-sect">Network Access Control</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="unix-chapt.html">14. HyperSQL on UNIX</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_purpose-sect">Purpose</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_install-sect">Installation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_cat_setup-sect">Setting up Database Catalog and Listener</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_access-sect">Accessing your Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_addl_accts-sect">Create additional Accounts</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_shutdown-sect">Shutdown</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_daemon-sect">Running Hsqldb as a System Daemon</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="unix-chapt.html#N144B8">Portability of hsqldb init script</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#N144C2">Init script Setup Procedure</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_inittrouble-sect">Troubleshooting the Init
+      Script</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_upgrade-sect">Upgrading</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="lists-app.html">A. Lists of Keywords</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="lists-app.html#N14607">List of SQL Standard Keywords</a></span>
+</dt>
+<dt>
+<span class="section"><a href="lists-app.html#N1463A">List of SQL Keywords Disallowed as HyperSQL Identifiers</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="building-app.html">B. Building HyperSQL Jars</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="building-app.html#N14693">Purpose</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#building-ant-sect">Building with Ant</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="building-app.html#N146AA">Obtaining Ant</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#N146C0">Building Hsqldb with Ant</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#N1475D">Building for Older JDKs</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="building-app.html#N14765">Building with IDE's</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#N1476A">Hsqldb CodeSwitcher</a></span>
+</dt>
+<dt>
+<span class="section"><a href="building-app.html#N14791">Building documentation</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="openoffice-app.html">C. HyperSQL with OpenOffice.org</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="openoffice-app.html#N147C8">HyperSQL with OpenOffice.org</a></span>
+</dt>
+<dt>
+<span class="section"><a href="openoffice-app.html#N147CF">Using OpenOffice.org as a Database Tool</a></span>
+</dt>
+<dt>
+<span class="section"><a href="openoffice-app.html#N147DE">Converting .odb files to use with HyperSQL Server</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="apd.html">D. HyperSQL File Links</a></span>
+</dt>
+<dt>
+<span class="index"><a href="sql-ind.html">SQL Index</a></span>
+</dt>
+<dt>
+<span class="index"><a href="book-ind.html">General Index</a></span>
+</dt>
+</dl>
+</div>
+<div class="list-of-tables">
+<p>
+<b>List of Tables</b>
+</p>
+<dl>
+<dt>1. <a href="book-pref.html#altformats-tbl">Available formats of this document</a>
+</dt>
+<dt>10.1. <a href="builtinfunctions-chapt.html#N13216">TO CHAR Values</a>
+</dt>
+<dt>12.1. <a href="dbproperties-chapt.html#N13AD2">HyperSQL URL Components</a>
+</dt>
+<dt>12.2. <a href="dbproperties-chapt.html#N13B9C">Connection Properties</a>
+</dt>
+<dt>12.3. <a href="dbproperties-chapt.html#N13C26">Database-specific Property File Properties</a>
+</dt>
+<dt>13.1. <a href="listeners-chapt.html#N13F59">common server and webserver properties</a>
+</dt>
+<dt>13.2. <a href="listeners-chapt.html#N13FED">server properties</a>
+</dt>
+<dt>13.3. <a href="listeners-chapt.html#N1401F">webserver properties</a>
+</dt>
+</dl>
+</div>
+<div class="list-of-examples">
+<p>
+<b>List of Examples</b>
+</p>
+<dl>
+<dt>1.1. <a href="running-chapt.html#N1021A">Java code to connect to the local hsql Server</a>
+</dt>
+<dt>1.2. <a href="running-chapt.html#N10224">Java code to connect to the local http Server</a>
+</dt>
+<dt>1.3. <a href="running-chapt.html#N10248">Java code to connect to the local secure SSL hsql and http
+          Servers</a>
+</dt>
+<dt>1.4. <a href="running-chapt.html#N102EF">specifying a connection property to shutdown the database when
+        the last connection is closed</a>
+</dt>
+<dt>1.5. <a href="running-chapt.html#N1030C">specifying a connection property to disallow creating a new
+        database</a>
+</dt>
+<dt>3.1. <a href="sessions-chapt.html#N1081D">User-defined Session Variables</a>
+</dt>
+<dt>3.2. <a href="sessions-chapt.html#N10831">User-defined Temporary Session Tables</a>
+</dt>
+<dt>3.3. <a href="sessions-chapt.html#N1090A">Setting Transaction Characteristics</a>
+</dt>
+<dt>3.4. <a href="sessions-chapt.html#N10934">Locking Tables</a>
+</dt>
+<dt>3.5. <a href="sessions-chapt.html#N10997">Rollback</a>
+</dt>
+<dt>3.6. <a href="sessions-chapt.html#N109C9">Setting Session Characteristics</a>
+</dt>
+<dt>3.7. <a href="sessions-chapt.html#N109DF">Setting Session Authorization</a>
+</dt>
+<dt>3.8. <a href="sessions-chapt.html#N10A0C">Setting Session Time Zone</a>
+</dt>
+<dt>4.1. <a href="databaseobjects-chapt.html#N10B67">inserting the next sequence value into a table row</a>
+</dt>
+<dt>4.2. <a href="databaseobjects-chapt.html#N10B6E">numbering returned rows of a SELECT in sequential order</a>
+</dt>
+<dt>4.3. <a href="databaseobjects-chapt.html#N10BF2">Column values which satisfy a 2-column UNIQUE
+        constraint</a>
+</dt>
+<dt>11.1. <a href="deployment-chapt.html#N13644">MainInvoker Example</a>
+</dt>
+<dt>11.2. <a href="deployment-chapt.html#N13756">Offline Backup Example</a>
+</dt>
+<dt>11.3. <a href="deployment-chapt.html#N13776">Listing a Backup with DbBackup</a>
+</dt>
+<dt>11.4. <a href="deployment-chapt.html#N1378C">Restoring a Backup with DbBackup</a>
+</dt>
+<dt>11.5. <a href="deployment-chapt.html#N1396A">Finding foreign key rows with no parents after a bulk
+      import</a>
+</dt>
+<dt>13.1. <a href="listeners-chapt.html#N14118">Exporting certificate from the server's keystore</a>
+</dt>
+<dt>13.2. <a href="listeners-chapt.html#N1412A">Adding a certificate to the client keystore</a>
+</dt>
+<dt>13.3. <a href="listeners-chapt.html#N1413E">Specifying your own trust store to a JDBC client</a>
+</dt>
+<dt>13.4. <a href="listeners-chapt.html#N141CA">Getting a pem-style private key into a JKS keystore</a>
+</dt>
+<dt>13.5. <a href="listeners-chapt.html#N14251">Validating and Testing an ACL file</a>
+</dt>
+<dt>14.1. <a href="unix-chapt.html#N14517">example sqltool.rc stanza</a>
+</dt>
+<dt>B.1. <a href="building-app.html#N14756">Buiding the standard Hsqldb jar file with Ant</a>
+</dt>
+<dt>B.2. <a href="building-app.html#N14773">Example source code before CodeSwitcher is run</a>
+</dt>
+<dt>B.3. <a href="building-app.html#N1477A">CodeSwitcher command line invocation</a>
+</dt>
+<dt>B.4. <a href="building-app.html#N14784">Source code after CodeSwitcher processing</a>
+</dt>
+</dl>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%">&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="book-pref.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%">&nbsp;</td><td valign="top" align="right" width="40%">&nbsp;Preface</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/listeners-chapt.html b/doc/guide/listeners-chapt.html
new file mode 100644
index 0000000..8d2fc4a
--- /dev/null
+++ b/doc/guide/listeners-chapt.html
@@ -0,0 +1,1015 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, Server, Listener">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="dbproperties-chapt.html" title="Chapter&nbsp;12.&nbsp;Properties">
+<link rel="next" href="unix-chapt.html" title="Chapter&nbsp;14.&nbsp;HyperSQL on UNIX">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="dbproperties-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="unix-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;12.&nbsp;Properties&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;14.&nbsp;HyperSQL on UNIX</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="listeners-chapt"></a>HyperSQL Network Listeners</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>Server, WebServer, and Servlet</i>
+</h3>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N13EF6"></a>
+<p>Copyright 2002-2009 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners-sect">Listeners</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_hsqlserver-sect">HyperSQL Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_httpserver-sect">HyperSQL HTTP Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_servlet-sect">HyperSQL HTTP Servlet</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_server_props-sect">Server and Web Server Properties</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_appstart-sect">Starting a Server from your application</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#N14099">Allowing a Connection to Open a Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_tls-sect">TLS Encryption</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="listeners-chapt.html#N140DB">Requirements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#N140F8">Encrypting your JDBC connection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#jsse-sect">JSSE</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#privatekey-sect">Making a Private-key Keystore</a></span>
+</dt>
+<dt>
+<span class="section"><a href="listeners-chapt.html#N141EB">Automatic Server or WebServer startup on UNIX</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="listeners-chapt.html#listeners_acl-sect">Network Access Control</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners-sect"></a>Listeners</h2>
+</div>
+</div>
+</div>
+<p>As described in the <a class="link" href="running-chapt.html" title="Chapter&nbsp;1.&nbsp;Running and Using HyperSQL">Running and Using HyperSQL</a> chapter, network listeners or servers
+    provide connectivity to catalogs from different JVM processes. The
+    HyperSQL listeners support both ipv4 and ipv6 network
+    addressing.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="listeners_hsqlserver-sect"></a>HyperSQL Server</h3>
+</div>
+</div>
+</div>
+<p>This is the preferred way of running a database server and the
+      fastest one. This mode uses the proprietary <em class="glossterm">hsql:</em>
+      communications protocol. The following example of the command for
+      starting the server starts the server with one (default) database with
+      files named "mydb.*" and the public name (alias) of "xdb".</p>
+<div class="informalexample">
+<pre class="screen">    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb</pre>
+</div>
+<p>Alternatively, a server.properties file can be used for passing
+      the arguments to the server. This file must be located in the directory
+      where the command is issued.</p>
+<pre class="screen">    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server</pre>
+<p>The contents of the server.properties file is described in the
+      next section.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="listeners_httpserver-sect"></a>HyperSQL HTTP Server</h3>
+</div>
+</div>
+</div>
+<p>This method of access is used when the computer hosting the
+      database server is restricted to the HTTP protocol. The only reason for
+      using this method of access is restrictions imposed by firewalls on the
+      client or server machines and it should not be used where there are no
+      such restrictions. The HyperSQL HTTP Server is a special web server that
+      allows JDBC clients to connect via HTTP. The server can also act as a
+      small general-purpose web server for static pages.</p>
+<p>To run an HTTP server, replace the main class for the server in
+      the example command line above with the following:</p>
+<div class="informalexample">
+<pre class="screen">    java -cp ../lib/hsqldb.jar org.hsqldb.server.Server</pre>
+</div>
+<p>The contents of the server.properties file is described in the
+      next section.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="listeners_servlet-sect"></a>HyperSQL HTTP Servlet</h3>
+</div>
+</div>
+</div>
+<p>This method of access also uses the HTTP protocol. It is used when
+      a separate servlet engine (or application server) such as Tomcat or
+      Resin provides access to the database. The Servlet Mode cannot be
+      started independently from the servlet engine. The
+      <code class="filename">Servlet</code> class, in the HSQLDB jar, should be
+      installed on the application server to provide the connection. The
+      database is specified using an application server property. Refer to the
+      source file <code class="filename"><a class="filename" href="apd.html#Servlet.java-link">
+      src/org/hsqldb/server/Servlet.java</a></code> to see the details.</p>
+<p>Both HTTP Server and Servlet modes can only be accessed using the
+      JDBC driver at the client end. They do not provide a web front end to
+      the database. The Servlet mode can serve only a single database.</p>
+<p>Please note that you do not normally use this mode if you are
+      using the database engine in an application server. In this situation,
+      connections to a catalog are usually made
+      <em class="glossterm">in-process</em>, or using an external HSQL Server
+      instance.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners_server_props-sect"></a>Server and Web Server Properties</h2>
+</div>
+</div>
+</div>
+<p>Properties files for running the servers are not created
+    automatically. You should create your own files that contain
+    <span class="property">server.property</span>=<code class="literal">value</code> pairs for
+    each property. The <code class="filename">server.properties</code> or
+    <code class="filename">webserver.properties</code> files must be located in the
+    directory where the command to run the
+    <code class="classname">org.hsqldb.server.Server</code> class is issued.</p>
+<p>In all properties files, values are case-sensitive. All values apart
+    from names of files or pages are required in lowercase (e.g.
+    <span class="property">server.silent</span>=<code class="literal">FALSE</code> will have no
+    effect, but <span class="property">server.silent</span>=<code class="literal">false</code>
+    will work). Supported properties and their default values (if any) are as
+    follows:</p>
+<div class="table">
+<a name="N13F59"></a>
+<p class="title">
+<b>Table&nbsp;13.1.&nbsp;common server and webserver properties</b>
+</p>
+<div class="table-contents">
+<table summary="common server and webserver properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Value</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Default</th><th style="border-bottom: 0.5pt solid ; " align="left">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.database.0</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">file:test</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">the catalog type, path and file name of the first database
+            file to use</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.dbname.0</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">""</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">lowercase server alias for the first database file</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.database.n</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">NO DEFAULT</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">the catalog type, path and file name of the n'th database
+            file in use</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.dbname.n</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">NO DEFAULT</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">lowercase server alias for the n'th database file</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.silent</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">no extensive messages displayed on console</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.trace</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">JDBC trace messages displayed on console</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.address</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">NO DEFAULT</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">IP address of server</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.tls</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">Whether to encrypt network stream. If this is set to
+            <code class="literal">true</code>, then in normal situations you will also
+            need to set properties
+            <code class="varname">system.javax.net.ssl.keyStore</code> and
+            <code class="varname">system.javax.net.ssl.keyStorePassword</code>, as
+            documented elsewhere. The value of <code class="varname">server.tls</code>
+            impacts the default value of
+            <code class="varname">server.port</code>.</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left" valign="top"><span class="property">server.remote_open</span></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><code class="literal">false</code></td><td style="" align="left" valign="top">Allows opening a database path remotely when the first
+            connection is made</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>In HyperSQL version 2.0, each server can serve an unlimited number
+    of databases simultaneously. The <span class="property">server.database.0</span>
+    property defines the filename / path whereas the
+    <span class="property">server.dbname.0</span> defines the lowercase alias used by
+    clients to connect to that database. The digit 0 is incremented for the
+    second database and so on. Values for the
+    <span class="property">server.database.n</span> property can use the
+    <em class="glossterm">mem:</em>, <em class="glossterm">file:</em> or
+    <em class="glossterm">res:</em> prefixes and connection properties as
+    discussed under CONNECTIONS. For example, <div class="informalexample">
+<pre class="programlisting">    database.0=mem:temp;sql.enforce_strict_size=true;</pre>
+</div>
+</p>
+<p>Properties or default values specific to
+    <code class="filename">server.properties</code> are:</p>
+<div class="table">
+<a name="N13FED"></a>
+<p class="title">
+<b>Table&nbsp;13.2.&nbsp;server properties</b>
+</p>
+<div class="table-contents">
+<table summary="server properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Value</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Default</th><th style="border-bottom: 0.5pt solid ; " align="left">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.port</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">9001 (normal) or 554 (if TLS
+            encrypted)</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">TCP/IP port used for talking to clients. All databases are
+            served on the same port.</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left" valign="top"><span class="property">server.no_system_exit</span></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><code class="literal">true</code></td><td style="" align="left" valign="top">no <code class="literal">System.exit()</code> call when the database
+            is closed</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>Properties or default values specific to
+    <code class="filename">webserver.properties</code> are:</p>
+<div class="table">
+<a name="N1401F"></a>
+<p class="title">
+<b>Table&nbsp;13.3.&nbsp;webserver properties</b>
+</p>
+<div class="table-contents">
+<table summary="webserver properties" cellspacing="0" width="100%" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Value</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">Default</th><th style="border-bottom: 0.5pt solid ; " align="left">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.port</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">80 (normal) or 443 (if TLS
+            encrypted)</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">TCP/IP port used for talking to clients</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.default_page</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">index.html</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">the default web page for server</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><span class="property">server.root</span></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><code class="literal">./</code></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top">the location of served pages</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left" valign="top"><span class="property">.&lt;extension&gt;</span></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><code class="literal">NO DEFAULT</code></td><td style="" align="left" valign="top">multiple entries such as <code class="literal">.html=text/html</code>
+            define the mime types of the static files served by the web
+            server. See the source for <code class="filename"><a class="filename" href="apd.html#WebServer.java-link">
+            src/org/hsqldb/server/WebServer.java</a></code> for a
+            list.</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+<p>An example of the contents of a
+    <code class="filename">server.properties</code> file is given below:</p>
+<pre class="programlisting">    server.database.0=file:/opt/db/accounts
+    server.dbname.0=accounts
+
+    server.database.1=file:/opt/db/mydb
+    server.dbname.1=enrollments
+
+    server.database.2=mem:adatabase
+    server.dbname.2=quickdb</pre>
+<p>In the above example, the <code class="filename">server.properties</code>
+    file indicates that the server provides access to 3 different databases.
+    Two of the databases are file-based, while the third is all-in-memory. The
+    aliases for the databases that the users connect to are
+    <code class="literal">accounts</code>, <code class="literal">enrollments</code> and
+    <code class="literal">quickdb</code>.</p>
+<p>All the above properties and their values can be specified on the
+    command line to start the server by omitting the
+    <code class="literal">server.</code> prefix. If a property/value pair is specified
+    on the command line, it overrides the property value specified in the
+    <code class="filename">server.properties</code> or
+    <code class="filename">webserver.properties</code> file.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Upgrading: If you have existing custom properties files, change
+      the values to the new naming convention. Note the use of digits at the
+      end of <span class="property">server.database.n</span> and
+      <span class="property">server.dbname.n</span> properties.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners_appstart-sect"></a>Starting a Server from your application</h2>
+</div>
+</div>
+</div>
+<p>If you want to start the server from within your application, as
+    opposed to the command line or batch files, you should create an instance
+    of Server or Web Server, then assign the properties and start the Server.
+    An working example of this can be found in the <code class="classname"><a class="classname" href="apd.html#TestBase.java-link"> org.hsqldb.test.TestBase</a></code>
+    source. The example below sets the same properties as in the
+    server.properties file example.</p>
+<pre class="programlisting">    HsqlProperties p = new HsqlProperties();
+    p.setProperty("server.database.0","file:/opt/db/accounts");
+    p.setProperty("server.dbname.0","an_alias");
+    // set up the rest of properties
+    Server server = new Server();
+    server.setProperties(p);
+    server.setLogWriter(null); // can use custom writer
+    server.setErrWriter(null); // can use custom writer
+    server.start();
+</pre>
+<p>The Server object has several alternative methods for setting
+    databases and their public names. The server should be shutdown using the
+    shutdown() method.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14099"></a>Allowing a Connection to Open a Database</h2>
+</div>
+</div>
+</div>
+<p>If the <code class="literal">server.remote_open</code> property is true, the
+    Server works differently from the normal mode. In this mode, it is not
+    necessary to have any databases listed as server.database.0 etc. in the
+    Server startup properties. If there are databases listed, they are opened
+    as normal. The server does not shutdown when the last database is
+    closed.</p>
+<p>In this mode, a connection can be established to a database that is
+    not open or does not exist. The server will open the database or create
+    it, then return a connection to the database.</p>
+<p>The connection URL must include the path to the database, separated
+    with a semicolon from the alias. In the example below, the database path
+    specified as <code class="literal">file:C:/files/mydatabase</code> is opened and the
+    database alias <code class="literal">xdb</code> is assigned to the database. After
+    this, the next connection to the specified alias will connect to the same
+    database.</p>
+<pre class="programlisting">Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb;file:C:/files/mydatabase", "SA", "");
+</pre>
+<p>The path can be a file: or mem: database.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners_tls-sect"></a>TLS Encryption</h2>
+</div>
+<div>
+<h2 class="subtitle">Listener TLS Support (a. k. a. SSL)</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<a name="N140D3" class="indexterm"></a>
+<p>This section explains how to encrypt the stream between JDBC network
+    clients and HyperSQL Listeners. If you are running an
+    <em class="glossterm">in-process</em> (non-Listener) setup, this chapter does
+    not apply to you.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N140DB"></a>Requirements</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<p class="title">
+<b>Hsqldb TLS Support Requirements</b>
+</p>
+<ul type="disc">
+<li>
+<p>Sun Java 2.x and up. (This is probably possible with IBM's
+          Java, but I don't think anybody has attempted to run HSQLDB with TLS
+          under IBM's Java, and I'm sure that nobody in the HSQLDB Development
+          Group has documented how to set up the environment).</p>
+</li>
+<li>
+<p>If Java 2.x or 3.x, then you will need to <a class="link" href="listeners-chapt.html#jsse-sect" title="JSSE">install JSSE</a>. Your server and/or
+          client will start up much slower than that of Java 4.x users.
+          Client-side users will not be able to use the https: JDBC protocol
+          (because the https protocol handler is not implemented in 2.x/3.x
+          Java JSSE; if there is demand, we could work around this).</p>
+</li>
+<li>
+<p>A <a class="link" href="listeners-chapt.html#privatekey-sect" title="Making a Private-key Keystore">JKS keystore containing
+          a private key</a>, in order to run a Listener.</p>
+</li>
+<li>
+<p>If you are running the listener side, then you'll need to run
+          a HSQLDB Server or WebServer Listener instance. It doesn't matter if
+          the underlying database catalogs are new, and it doesn't matter if
+          you are making a new Listener configuration or encrypting an
+          existing Listener configuration. (You can turn encryption on and off
+          at will).</p>
+</li>
+<li>
+<p>You need a HSQLDB jar file that was built with JSSE present.
+          If you obtained your HSQLDB 1.7.2-or-later distribution from us, you
+          are all set, because we build with Java 1.4 or later (which contains
+          JSSE). If you build your own jar file with Java 1.3, make sure to
+          install JSSE first.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N140F8"></a>Encrypting your JDBC connection</h3>
+</div>
+</div>
+</div>
+<p>At this time, only 1-way, server-cert encryption is tested.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h4 class="title">
+<a name="N140FD"></a>Client-Side</h4>
+</div>
+</div>
+</div>
+<p>Just use one of the following protocol prefixes.</p>
+<div class="itemizedlist">
+<p class="title">
+<b>Hsqldb TLS URL Prefixes</b>
+</p>
+<ul type="disc">
+<li>
+<p>
+<code class="literal">jdbc:hsqldb:hsqls://</code>
+</p>
+</li>
+<li>
+<p>
+<code class="literal">jdbc:hsqldb:https://</code>
+</p>
+</li>
+</ul>
+</div>
+<p>At this time, the latter will only work for clients running with
+        Java 1.4 or later.</p>
+<p>If the listener you wish to connect to is using a certificate
+        approved by your default trust keystore, then there is nothing else to
+        do. If not, then you need to tell Java to "trust" the server cert.
+        (It's a slight over-simplification to say that if the server
+        certificate was purchased, then you are all set; if somebody "signed
+        their own" certificate by self-signing or using a private ca
+        certificate, then you need to set up trust).</p>
+<p>First, you need to obtain the cert (only the "public" part of
+        it). Since this cert is passed to all clients, you could obtain it by
+        writing a Java client that dumps it to file, or perhaps by using
+        <span class="emphasis"><em>openssl s_client</em></span>. Since in most cases, if you
+        want to trust a non-commercial cert, you probably have access to the
+        server keystore, I'll show an example of how to get what you need from
+        the server-side JKS keystore.</p>
+<p>You may already have an X509 cert for your server. If you have a
+        server keystore, then you can generate a X509 cert like this. <div class="example">
+<a name="N14118"></a>
+<p class="title">
+<b>Example&nbsp;13.1.&nbsp;Exporting certificate from the server's keystore</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    keytool -export -keystore server.store -alias existing_alias -file server.cer</pre>
+</div>
+</div>
+<br class="example-break"> In this example, <code class="filename">server.cer</code> is the
+        X509 certificate that you need for the next step.</p>
+<p>Now, you need to add this cert to one of the system trust
+        keystores or to a keystore of your own. See <a class="link" href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores" target="_top">
+        the Customizing Stores section in JSSERefGuide.html</a> to see
+        where your system trust keystores are. You can put private keystores
+        anywhere you want to. The following command will add the cert to an
+        existing keystore, or create a new keystore if
+        <code class="filename">client.store</code> doesn't exist.</p>
+<div class="example">
+<a name="N1412A"></a>
+<p class="title">
+<b>Example&nbsp;13.2.&nbsp;Adding a certificate to the client keystore</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    keytool -import -trustcacerts -keystore trust.store -alias new_alias -file server.cer</pre>
+</div>
+</div>
+<br class="example-break">
+<p>If you are making a new keystore, you probably want to start
+        with a copy of your system default keystore which you can find
+        somewhere under your <code class="varname">JAVA_HOME</code> directory (typically
+        <code class="filename">jre/lib/security/cacerts</code> for a JDK, but I forget
+        exactly where it is for a JRE).</p>
+<p>Unless your OS can't stop other people from writing to your
+        files, you probably do not want to set a password on the trust
+        keystore.</p>
+<p>If you added the cert to a system trust store, then you are
+        finished. Otherwise you will need to specify your custom trust
+        keystore to your client program. The generic way to set the trust
+        keystore is to set the system property
+        <code class="classname">javax.net.ssl.trustStore</code> every time that you
+        run your client program. For example <div class="example">
+<a name="N1413E"></a>
+<p class="title">
+<b>Example&nbsp;13.3.&nbsp;Specifying your own trust store to a JDBC client</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    java -Djavax.net.ssl.trustStore=/home/blaine/trust.store -jar /path/to/hsqldb.jar dest-urlid</pre>
+</div>
+</div>
+<br class="example-break"> This example runs the program <a class="link" href="unix-chapt.html" title="Chapter&nbsp;14.&nbsp;HyperSQL on UNIX">SqlTool</a>. SqlTool has built-in TLS
+        support however, so, for SqlTool you can set
+        <code class="varname">truststore</code> on a per-urlid basis in the SqlTool
+        configuration file.</p>
+<p>Note: The hostname in your database URL must match the
+        <span class="emphasis"><em>Common Name</em></span> of the server's certificate exactly.
+        That means that if a site certificate is <code class="literal">admc.com</code>,
+        you can not use <code class="literal">jdbc:hsqldb:hsqls://localhost</code> or
+        <code class="literal">jdbc:hsqldb:hsqls://www.admc.com:1100</code> to connect to
+        it.</p>
+<p>If you want more details on anything, see JSSERefGuide.html on
+        <a class="link" href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html" target="_top">
+        Sun's site</a>, or in the subdirectory
+        <code class="filename">docs/guide/security/jsse</code> of your Java SE
+        docs.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h4 class="title">
+<a name="N14162"></a>Server-Side, aka Listener-Side</h4>
+</div>
+</div>
+</div>
+<p>Get yourself a <a class="link" href="listeners-chapt.html#privatekey-sect" title="Making a Private-key Keystore"> JKS
+        keystore containing a private key</a>. Then set properties
+        <code class="varname">server.tls</code>,
+        <code class="varname">system.javax.net.ssl.keyStore</code> and
+        <code class="varname">system.javax.net.ssl.keyStorePassword</code> in your
+        <code class="filename">server.properties</code> or
+        <code class="filename">webserver.properties</code> file. Set
+        <code class="varname">server.tls</code> to <code class="literal">true</code>,
+        <code class="varname">system.javax.net.ssl.keyStore</code> to the path of the
+        private key JKS keystore, and
+        <code class="varname">system.javax.net.ssl.keyStorePassword</code> to the
+        password (of both the keystore and the private key record-- they must
+        be the same). If you specify relative file path values, they will be
+        resolved relative to the <code class="varname">${user.dir}</code> when the JRE
+        is started.</p>
+<div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Caution">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Caution]" src="../images/db/caution.png"></td><th align="left"><a name="tlspassword-caution"></a>Caution</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>If you set any password in a .properties (or any other) file,
+          you need to restrict access to the file. On a good operating system,
+          you can do this like so: <div class="informalexample">
+<pre class="screen">    chmod 600 path/to/server.properties</pre>
+</div>
+</p>
+</td>
+</tr>
+</table>
+</div>
+<p>The values and behavior of the <code class="literal">system.*</code>
+        settings above match the usage documented for
+        <code class="varname">javax.net.ssl.keyStorePassword</code> and
+        <code class="varname">javax.net.ssl.keyStore</code> in the JSSE docs.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Before version 2.0, HyperSQL depended on directly setting
+          the corresponding JSSE properties. The new idiom is more secure and
+          easier to manage. If you have an old password in a UNIX init script
+          config file, you should remove it.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="jsse-sect"></a>JSSE</h3>
+</div>
+</div>
+</div>
+<p>If you are running Java 4.x or later, then you are all set. Java
+      1.x users, you are on your own (Sun does not provide a JSSE that will
+      work with 1.x). Java 2.x and 3.x users continue...</p>
+<p>Go to <a class="link" href="http://java.sun.com/products/jsse/index-103.html" target="_top">http://java.sun.com/products/jsse/index-103.html</a> If
+      you agree to the terms and meet the requirements, download the domestic
+      or global JSSE software. All you need from the software distro is the
+      three jar files. If you have a JDK installation, then move the 3 jar
+      files into the directory <code class="filename">$JAVA_HOME/jre/lib/ext</code>. If
+      you have a JRE installation, then move the 3 jar files into the
+      directory <code class="filename">$JAVA_HOME/lib/ext</code>.</p>
+<p>Pretty painless.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="privatekey-sect"></a>Making a Private-key Keystore</h3>
+</div>
+</div>
+</div>
+<p>There are two main ways to do this. Either you can use a
+      certificate signed by a certificate authority, or you can make your own.
+      One thing that you need to know in both cases is, the <span class="emphasis"><em>Common
+      Name</em></span> of the cert has to be the exact hostname that JDBC
+      clients will use in their database URL.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h4 class="title">
+<a name="N141BA"></a>CA-Signed Cert</h4>
+</div>
+</div>
+</div>
+<p>I'm not going to tell you how to get a CA-signed SSL
+        certificate. That is well documented at many other places.</p>
+<p>Assuming that you have a standard pem-style private key
+        certificate, here's how you can use <a class="link" href="http://www.openssl.org" target="_top">openssl</a> and the program
+        <code class="classname">DERImport</code> to get it into a JKS keystore.</p>
+<p>Because I have spent a lot of time on this document already, I
+        am just giving you an example.</p>
+<div class="example">
+<a name="N141CA"></a>
+<p class="title">
+<b>Example&nbsp;13.4.&nbsp;Getting a pem-style private key into a JKS keystore</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    openssl pkcs8 -topk8 -outform DER -in Xpvk.pem -inform PEM -out Xpvk.pk8 -nocrypt
+
+    openssl x509 -in Xcert.pem -out Xcert.der -outform DER
+
+    java DERImport new.keystore NEWALIAS Xpvk.pk8 Xcert.der</pre>
+</div>
+</div>
+<br class="example-break">
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Make sure to set the password of the key exactly the same as
+          the password for the keystore!</p>
+</td>
+</tr>
+</table>
+</div>
+<p>You need the program <code class="filename">DERImport.class</code> of
+        course. Do some internet searches to find
+        <code class="filename">DERImport.java</code> or
+        <code class="filename">DERImport.class</code> and download it.</p>
+<p>If DERImport has become difficult to obtain, I can write a
+        program to do the same thing-- just let me know.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h4 class="title">
+<a name="N141DF"></a>Non-CA-Signed Cert</h4>
+</div>
+</div>
+</div>
+<p>Run <code class="literal">man keytool</code> or see <a class="link" href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore" target="_top">
+        the Creating a Keystore section of JSSERefGuide.html</a>.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N141EB"></a>Automatic Server or WebServer startup on UNIX</h3>
+</div>
+</div>
+</div>
+<p>If you are on UNIX and want to automatically start and stop a
+      Server or WebServer running with encryption, set the
+      <code class="varname">system.javax.net.ssl.keyStore</code> and
+      <code class="varname">system.javax.net.ssl.keyStorePassword</code> properties as
+      instructed above, and follow the instructions in the <a class="link" href="unix-chapt.html" title="Chapter&nbsp;14.&nbsp;HyperSQL on UNIX">HyperSQL on UNIX</a> chapter, paying
+      close attention to the TLS-related comments in the template config
+      file.</p>
+<p>If you are using a private server certificate, make sure to also
+      set the trust store filepath for relevant urlids in your RC file, as
+      explained in the sample <a class="link" href="apd.html#hsqldb.cfg-link">config
+      file</a>.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="listeners_acl-sect"></a>Network Access Control</h2>
+</div>
+<div>
+<h2 class="subtitle">Aka Server ACLs</h2>
+</div>
+</div>
+</div>
+<a name="N14207" class="indexterm"></a><a name="N1420A" class="indexterm"></a>
+<p>JDBC connections will always be denied if the supplied user and
+    password are not found in the target catalog. But an HyperSQL listener can
+    also restrict access at the listener level, even protecting private
+    catalogs which have insecure (or default) passwords. If you have an
+    <em class="glossterm">in-process</em> setup, this section of the Guide doesn't
+    apply to you.</p>
+<p>Many (in fact, most) distributed database applications don't have
+    application clients connect directly to the database, but instead
+    encapsulate access in a controlling process. For example, a web app will
+    usually access the data source on behalf of users, with end-user web
+    browsers never accessing the database directly. In these cases and others,
+    the security benefits of restricting listener access to specific source
+    addresses is well worth the effort. ACLs work by restricting access
+    according to the source address of the incoming connection request. This
+    is efficient because the database engine never even gets the request until
+    it is approved by the ACL filter code.</p>
+<p>The sample file <code class="filename"><a class="filename" href="apd.html#acl.txt-link">sample/acl.txt</a></code> in your HyperSQL
+    distribution explains how to write an ACL file. <pre class="programlisting"># $Id: acl.txt 826 2009-01-17 05:04:52Z unsaved $
+
+# Sample HyperSQL Network Listener ACL file.
+# Specify "allow" and "deny" rules
+# For address specifications, individual addresses, host names, and
+# network addresses with /bit suffix are allowed, but read the caveat about
+# host names below, under the sample "localhost" rule.
+
+# Blank lines ignored.
+   # Lines with # as the first non-whitespace character are ignored.
+
+
+allow 2001:db8::/32
+# Allow this 32-bit ipv4 subnet
+
+allow localhost
+# You should use numerical addresses in ACL files, unless you are certain that
+# the name will always be known to your network address resolution system
+# (assume that you will lose Internet connectivity at some time).
+# With a default name resolution setup on UNIX, you are safe to use names
+# defined in your /etc/hosts file.
+
+deny 192.168.101.253
+# Deny a single IP address.
+# In our example, 192.168.101.0/24 is our local, organizational network.
+# 192.168.101.253 is the IP address of our Intern's PC.
+# The Intern does not have permission to access our databases directly.
+
+allow 192.168.101.0/24
+
+# Any ipv4 or ipv6 candidate address not matched above will be denied
+</pre>
+    You put your file wherever it is convenient for you, and specify that path
+    with the property <code class="varname">server.acl</code> or
+    <code class="varname">webserver.acl</code> in your
+    <code class="filename">server.properties</code> or
+    <code class="filename">webserver.properties</code> file (depending on whether your
+    listener instance is a <code class="classname">Server</code> or
+    <code class="classname">WebServer</code>). You can specify the ACL file path with
+    an absolute or relative path. If you use a relative path, it must be
+    relative to the <code class="filename">.properties</code> file. It's often
+    convenient to name the ACL file <code class="filename">acl.txt</code>, in the same
+    directory as your <code class="filename">.properties</code> file and specify the
+    property value as just <code class="filename">acl.txt</code>. This file name is
+    intuitive, and things will continue to work as expected if you move or
+    copy the entire directory.</p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>If your <code class="classname">Server</code> or
+      <code class="classname">WebServer</code> was started with a
+      <code class="varname">*.acl</code> property, changes afterwards to the ACL file
+      will be picked up immediately by your listener instance. You are advised
+      to use the procedure below to prevent partial edits or mistakes from
+      crippling your running server.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>When you edit your ACL file, it is both more convenient and more
+    secure to test it as explained here before activating it. You could, of
+    course, test an ACL file by editing it in-place, then trying to connect to
+    your listener with JDBC clients from various source addresses. Besides
+    being mightily laborious and boring, with this method it is very easy to
+    accidentally open access to all source addresses or to deny access to all
+    users until you fix incorrect ACL entries.</p>
+<p>The suggested method of creating or changing ACLs is to work with an
+    inactive file (for new ACL files, just don't enable the
+    <code class="varname">*.acl</code> property yet; for changing an existing file, just
+    copy it to a temporary file and edit the temporary file). Then use the
+    <code class="classname">ServerAcl</code> class to test it. <div class="example">
+<a name="N14251"></a>
+<p class="title">
+<b>Example&nbsp;13.5.&nbsp;Validating and Testing an ACL file</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    java -cp path/to/hsqldb.jar org.hsqldb.server.ServerAcl path/to/acl.txt</pre>
+</div>
+</div>
+<br class="example-break"> If the specified ACL file fails validation, you will be given
+    details about the problem. Otherwise, the validated rules will be
+    displayed (including the implicit, default deny rules). You then type in
+    host names and addresses, one-per-line. Each name or address is tested as
+    if it were a HyperSQL network client address, using the same exact method
+    that the HyperSQL listener will use. (HyperSQL listeners use this same
+    <code class="classname">ServerAcl</code> class to test incoming source addresses).
+    <code class="classname">ServerAcl</code> will report the rule which matches and
+    whether access is denied or allowed to that address.</p>
+<p>If you have edited a copy of an existing ACL file (as suggested
+    above), then overwrite your live ACL file with your new, validated ACL
+    file. I.e., copy your temp file over top of your live ACL file.</p>
+<p>
+<code class="classname">ServerAcl</code> can be run in the same exact way
+    described above, to troubleshoot runtime access issues. If you use an ACL
+    file and a user or application can't get a connection to the database, you
+    can run <code class="classname">ServerAcl</code> to quickly and definitively find
+    if the client is being prohibited by an ACL rule.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="dbproperties-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="unix-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;12.&nbsp;Properties&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;14.&nbsp;HyperSQL on UNIX</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/lists-app.html b/doc/guide/lists-app.html
new file mode 100644
index 0000000..be8ad3e
--- /dev/null
+++ b/doc/guide/lists-app.html
@@ -0,0 +1,188 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Appendix&nbsp;A.&nbsp;Lists of Keywords</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HSQLDB, HyperSQL, SQL Keywords SQL STAT">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="unix-chapt.html" title="Chapter&nbsp;14.&nbsp;HyperSQL on UNIX">
+<link rel="next" href="building-app.html" title="Appendix&nbsp;B.&nbsp;Building HyperSQL Jars">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="unix-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Appendix&nbsp;A.&nbsp;Lists of Keywords</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="building-app.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;14.&nbsp;HyperSQL on UNIX&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Appendix&nbsp;B.&nbsp;Building HyperSQL Jars</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="lists-app"></a>Lists of Keywords</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>List of SQL Keywords</i>
+</h3>
+</div>
+<div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 847 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2009-01-19 22:24:49 +0000 (Mon, 19 Jan 2009) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="lists-app.html#N14607">List of SQL Standard Keywords</a></span>
+</dt>
+<dt>
+<span class="section"><a href="lists-app.html#N1463A">List of SQL Keywords Disallowed as HyperSQL Identifiers</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N14607"></a>List of SQL Standard Keywords</h2>
+</div>
+</div>
+</div>
+<p>According to the SQL Standard, the SQL Language keywords cannot be
+    used as identifiers (names of database objects such as columns and
+    tables). HyperSQL has two modes of operation, which are selected with the
+    SET DATABASE SQL NAMES { TRUE | FALSE } to allow or disallow the keywords
+    as identifiers. The default mode is FALSE and allows the use of most
+    keywords as identifiers. Even in this mode, keywords cannot be used as
+    USER or ROLE identifiers.</p>
+<p>ABS ALL ALLOCATE ALTER AND ANY ARE ARRAY AS ASENSITIVE ASYMMETRIC
+    AT ATOMIC AUTHORIZATION AVG</p>
+<p>BEGIN BETWEEN BIGINT BINARY BLOB BOOLEAN BOTH BY</p>
+<p>CALL CALLED CARDINALITY CASCADED CASE CAST CEIL CEILING CHAR
+    CHAR_LENGTH CHARACTER CHARACTER_LENGTH CHECK CLOB CLOSE COALESCE COLLATE
+    COLLECT COLUMN COMMIT COMPARABLE CONDITION CONNECT CONSTRAINT CONVERT CORR
+    CORRESPONDING COUNT COVAR_POP COVAR_SAMP CREATE CROSS CUBE CUME_DIST
+    CURRENT CURRENT_CATALOG CURRENT_DATE CURRENT_DEFAULT_TRANSFORM_GROUP
+    CURRENT_PATH CURRENT_ROLE CURRENT_SCHEMA CURRENT_TIME CURRENT_TIMESTAMP
+    CURRENT_TRANSFORM_GROUP_FOR_TYPE CURRENT_USER CURSOR CYCLE</p>
+<p>DATE DAY DEALLOCATE DEC DECIMAL DECLARE DEFAULT DELETE DENSE_RANK
+    DEREF DESCRIBE DETERMINISTIC DISCONNECT DISTINCT DO DOUBLE DROP
+    DYNAMIC</p>
+<p>EACH ELEMENT ELSE ELSEIF END END_EXEC ESCAPE EVERY EXCEPT EXEC
+    EXECUTE EXISTS EXIT EXP EXTERNAL EXTRACT</p>
+<p>FALSE FETCH FILTER FIRST_VALUE FLOAT FLOOR FOR FOREIGN FREE FROM
+    FULL FUNCTION FUSION</p>
+<p>GET GLOBAL GRANT GROUP GROUPING</p>
+<p>HANDLER HAVING HOLD HOUR</p>
+<p>IDENTITY IN INDICATOR INNER INOUT INSENSITIVE INSERT INT INTEGER
+    INTERSECT INTERSECTION INTERVAL INTO IS ITERATE</p>
+<p>JOIN</p>
+<p>LAG</p>
+<p>LANGUAGE LARGE LAST_VALUE LATERAL LEAD LEADING LEAVE LEFT LIKE
+    LIKE_REGEX LN LOCAL LOCALTIME LOCALTIMESTAMP LOOP LOWER</p>
+<p>MATCH MAX MAX_CARDINALITY MEMBER MERGE METHOD MIN MINUTE MOD
+    MODIFIES MODULE MONTH MULTISET</p>
+<p>NATIONAL NATURAL NCHAR NCLOB NEW NO NONE NORMALIZE NOT NTH_VALUE
+    NTILE NULL NULLIF NUMERIC</p>
+<p>OCCURRENCES_REGEX OCTET_LENGTH OF OFFSET OLD ON ONLY OPEN OR
+    ORDER OUT OUTER OVER OVERLAPS OVERLAY</p>
+<p>PARAMETER PARTITION PERCENT_RANK PERCENTILE_CONT PERCENTILE_DISC
+    POSITION POSITION_REGEX POWER PRECISION PREPARE PRIMARY
+    PROCEDURE</p>
+<p>RANGE RANK READS REAL RECURSIVE REF REFERENCES REFERENCING
+    REGR_AVGX REGR_AVGY REGR_COUNT REGR_INTERCEPT REGR_R2 REGR_SLOPE REGR_SXX
+    REGR_SXY REGR_SYY RELEASE REPEAT RESIGNAL RESULT RETURN RETURNS REVOKE
+    RIGHT ROLLBACK ROLLUP ROW ROW_NUMBER ROWS</p>
+<p>SAVEPOINT SCOPE SCROLL SEARCH SECOND SELECT SENSITIVE
+    SESSION_USER SET SIGNAL SIMILAR SMALLINT SOME SPECIFIC SPECIFICTYPE SQL
+    SQLEXCEPTION SQLSTATE SQLWARNING SQRT STACKED START STATIC STDDEV_POP
+    STDDEV_SAMP SUBMULTISET SUBSTRING SUBSTRING_REGEX SUM SYMMETRIC SYSTEM
+    SYSTEM_USER</p>
+<p>TABLE TABLESAMPLE THEN TIME TIMESTAMP TIMEZONE_HOUR
+    TIMEZONE_MINUTE TO TRAILING TRANSLATE TRANSLATE_REGEX TRANSLATION TREAT
+    TRIGGER TRIM TRIM_ARRAY TRUE TRUNCATE</p>
+<p>UESCAPE UNDO UNION UNIQUE UNKNOWN UNNEST UNTIL UPDATE UPPER USER
+    USING</p>
+<p>VALUE VALUES VAR_POP VAR_SAMP VARBINARY VARCHAR VARYING</p>
+<p>WHEN WHENEVER WHERE WIDTH_BUCKET WINDOW WITH WITHIN WITHOUT
+    WHILE</p>
+<p>YEAR</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1463A"></a>List of SQL Keywords Disallowed as HyperSQL Identifiers</h2>
+</div>
+</div>
+</div>
+<p>A subset of SQL Standard keywords cannot be used at all as HyperSQL
+    identifiers. The keywords are as follows:</p>
+<p>ADMIN AND ALL ANY AS AT AVG</p>
+<p>BETWEEN BOTH BY</p>
+<p>CALL CASE CAST COALESCE CORRESPONDING CONVERT COUNT CREATE
+    CROSS</p>
+<p>DISTINCT DROP</p>
+<p>ELSE END EVERY EXISTS EXCEPT</p>
+<p>FOR FROM FULL</p>
+<p>GRANT GROUP</p>
+<p>HAVING</p>
+<p>IN INNER INTERSECT INTO IS</p>
+<p>JOIN</p>
+<p>LEFT LEADING LIKE</p>
+<p>MAX MIN</p>
+<p>NATURAL NOT NULLIF</p>
+<p>ON ORDER OR OUTER</p>
+<p>PRIMARY</p>
+<p>REFERENCES RIGHT</p>
+<p>SELECT SET SOME STDDEV_POP STDDEV_SAMP SUM</p>
+<p>TABLE THEN TO TRAILING TRIGGER</p>
+<p>UNION UNIQUE USING</p>
+<p>VALUES VAR_POP VAR_SAMP</p>
+<p>WHEN WHERE WITH</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="unix-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="building-app.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;14.&nbsp;HyperSQL on UNIX&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Appendix&nbsp;B.&nbsp;Building HyperSQL Jars</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/openoffice-app.html b/doc/guide/openoffice-app.html
new file mode 100644
index 0000000..32b83e7
--- /dev/null
+++ b/doc/guide/openoffice-app.html
@@ -0,0 +1,156 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Appendix&nbsp;C.&nbsp;HyperSQL with OpenOffice.org</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HSQLDB, HyperSQL, OpenOffice, OpenOfficeOrg">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="building-app.html" title="Appendix&nbsp;B.&nbsp;Building HyperSQL Jars">
+<link rel="next" href="apd.html" title="Appendix&nbsp;D.&nbsp;HyperSQL File Links">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="building-app.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Appendix&nbsp;C.&nbsp;HyperSQL with OpenOffice.org</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="apd.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Appendix&nbsp;B.&nbsp;Building HyperSQL Jars&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Appendix&nbsp;D.&nbsp;HyperSQL File Links</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="openoffice-app"></a>HyperSQL with OpenOffice.org</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>How to use HyperSQL with OpenOffice.org</i>
+</h3>
+</div>
+<div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3498 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-03-06 12:42:28 -0500 (Sat, 06 Mar 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="openoffice-app.html#N147C8">HyperSQL with OpenOffice.org</a></span>
+</dt>
+<dt>
+<span class="section"><a href="openoffice-app.html#N147CF">Using OpenOffice.org as a Database Tool</a></span>
+</dt>
+<dt>
+<span class="section"><a href="openoffice-app.html#N147DE">Converting .odb files to use with HyperSQL Server</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N147C8"></a>HyperSQL with OpenOffice.org</h2>
+</div>
+</div>
+</div>
+<p>OpenOffice.org includes HyperSQL and uses it for embedded
+    databases. Our collaboration with OpenOffice.org developers over the last
+    few years has benefited the development and maturity of HyperSQL. Before
+    integration into OOo, HSQLDB was intended solely for application-specific
+    database access. The application developer was expected to resolve any
+    integration issues. Because OpenOffice.org is used by a vast range of
+    users, from schoolchildren to corporate developers, a much higher level of
+    quality assurance has been required and we have achieved it with constant
+    help and feedback from OOo users and developers.</p>
+<p>Apart from embedded use, you may want to use OpenOffic.org with a
+    HyperSQL server instance. The typical use for this is to allow multiple
+    office users accessing the same database. There is, however, a strong case
+    for using OOo to develop your database schema and application, even if the
+    database is intended for your own application.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N147CF"></a>Using OpenOffice.org as a Database Tool</h2>
+</div>
+</div>
+</div>
+<p>OpenOffice.org is a very powerful database front end. If you want
+    to create schemas, edit tables, edit the database contents manually,
+    design and produce well-formatted reports, then OpenOffice.org is probably
+    the best open source tools currently available.</p>
+<p>To connect from OpenOffice.org to your database, first run a
+    local server instance for the database. This is describes in the Network
+    Listeners chapter of this guide.</p>
+<p>When you connect from OpenOffice.org, you must specify connection
+    to an external database and use the URL property "default_schema=true".
+    For example, the URL to connect the local database may be like</p>
+<pre class="programlisting"> jdbc;hsqldb:hsql://localhost/mydb;default_schema=true </pre>
+<p>The only current limitation is that OpenOffice.org only works
+    with the PUBLIC schema. This limitation will hopefully removed in the
+    future versions of OOo.</p>
+<p>When using of HyperSQL with OOo, you must use the HyperSQL jar
+    that is supplied with OOo. This wil hopefuly be a version 2.0 jar in the
+    future versions of OOo.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N147DE"></a>Converting .odb files to use with HyperSQL Server</h2>
+</div>
+</div>
+</div>
+<p>You may already have an OOo database file, which you want to use
+    outside OOo, or as a server database. The file is in fact in the standard
+    ZIP format and contains the normal HyperSQL database files. Just use a
+    utility such as 7Zip to expand the .odb file. In the /db directory, there
+    are files such as .script, .data, etc. Just rename these files into
+    mydb.script, mydb.data, etc. You can now open the mydb database directly
+    with HyperSQL as an embedded database or as a server instance.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="building-app.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="apd.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Appendix&nbsp;B.&nbsp;Building HyperSQL Jars&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Appendix&nbsp;D.&nbsp;HyperSQL File Links</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/running-chapt.html b/doc/guide/running-chapt.html
new file mode 100644
index 0000000..716f261
--- /dev/null
+++ b/doc/guide/running-chapt.html
@@ -0,0 +1,759 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;1.&nbsp;Running and Using HyperSQL</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="book-pref.html" title="Preface">
+<link rel="next" href="sqlgeneral-chapt.html" title="Chapter&nbsp;2.&nbsp;SQL Language">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="book-pref.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;1.&nbsp;Running and Using HyperSQL</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="sqlgeneral-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Preface&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;2.&nbsp;SQL Language</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="running-chapt"></a>Chapter&nbsp;1.&nbsp;Running and Using HyperSQL</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N100CC"></a>
+<p>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="running-chapt.html#running_jar-sect">The HSQLDB Jar</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_tools-sect">Running Database Access Tools</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_db-sect">A HyperSQL Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_inprocess-sect">In-Process Access to Database Catalogs</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_modes-sect">Listener / Server Modes</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="running-chapt.html#running_hsqlserver-sect">HyperSQL HSQL Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_httpserver-sect">HyperSQL HTTP Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_servlet-sect">HyperSQL HTTP Servlet</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_connecting-sect">Connecting to a Database Server</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_security-sect">Security Considerations</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_multiple_db-sect">Using Multiple Databases</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="running-chapt.html#running-data-access-sect">Accessing the Data</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_closing-sect">Closing the Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="running-chapt.html#running_newdb-sect">Creating a New Database</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_jar-sect"></a>The HSQLDB Jar</h2>
+</div>
+</div>
+</div>
+<p>The HSQLDB jar package is located in the /lib directory of the ZIP
+    package and contains several components and programs.</p>
+<div class="itemizedlist">
+<p class="title">
+<b>Components of the Hsqldb jar package</b>
+</p>
+<ul type="disc">
+<li>
+<p>HyperSQL RDBMS Engine (HSQLDB)</p>
+</li>
+<li>
+<p>HyperSQL JDBC Driver</p>
+</li>
+<li>
+<p>Database Manager (GUI database access tool, with Swing and AWT
+        versions)</p>
+</li>
+<li>
+<p>Sql Tool (command line database access tool)</p>
+</li>
+</ul>
+</div>
+<p>The HyperSQL RDBMS and JDBC Driver provide the core functionality.
+    An additional jar contains Sql Tool (command line database access tool).
+    SqlTool and the DatabaseManagers are general-purpose database tools that
+    can be used with any database engine that has a JDBC driver.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_tools-sect"></a>Running Database Access Tools</h2>
+</div>
+</div>
+</div>
+<p>The tools are used for interactive user access to databases,
+    including creation of a database, inserting or modifying data, or querying
+    the database. All tools are run in the normal way for Java programs. In
+    the following example the Swing version of the Database Manager is
+    executed. The <code class="filename">hsqldb.jar</code> is located in the directory
+    <code class="filename">../lib</code> relative to the current directory.</p>
+<pre class="screen">java -cp ../lib/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing</pre>
+<p>If <code class="filename">hsqldb.jar</code> is in the current directory, the
+    command would change to:</p>
+<pre class="screen">java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing</pre>
+<div class="itemizedlist">
+<p class="title">
+<b>Main classes for the Hsqldb tools</b>
+</p>
+<ul type="disc">
+<li>
+<p>
+<code class="classname">org.hsqldb.util.DatabaseManager</code>
+</p>
+</li>
+<li>
+<p>
+<code class="classname">org.hsqldb.util.DatabaseManagerSwing</code>
+</p>
+</li>
+</ul>
+</div>
+<p>When a tool is up and running, you can connect to a database (may be
+    a new database) and use SQL commands to access and modify the data.</p>
+<p>Tools can use command line arguments. You can add the command line
+    argument --help to get a list of available arguments for these
+    tools.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_db-sect"></a>A HyperSQL Database</h2>
+</div>
+</div>
+</div>
+<p>Each HyperSQL database is called a catalog. There are three types of
+    catalog depending on how the data is stored.</p>
+<div class="itemizedlist">
+<p class="title">
+<b>Types of catalog data</b>
+</p>
+<ul type="disc">
+<li>
+<p>
+<em class="glossterm">mem:</em> stored entirely in RAM - without any
+        persistence beyond the JVM process's life</p>
+</li>
+<li>
+<p>
+<em class="glossterm">file:</em> stored in filesystem files</p>
+</li>
+<li>
+<p>
+<em class="glossterm">res:</em> stored in a Java resource, such as a
+        Jar and always read-only</p>
+</li>
+</ul>
+</div>
+<p>All-in-memory, <em class="glossterm">mem:</em> catalogs can be used for
+    test data or as sophisticated caches for an application. These databases
+    do not have any files.</p>
+<p>A <em class="glossterm">file</em>: catalog consists of between 2 to 5
+    files, all named the same but with different extensions, located in the
+    same directory. For example, the database named "test" consists of the
+    following files:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>
+<code class="filename">test.properties</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.script</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.log</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.data</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.backup</code>
+</p>
+</li>
+<li>
+<p>
+<code class="filename">test.lobs</code>
+</p>
+</li>
+</ul>
+</div>
+<p>The properties file contains a few settings about the database. The
+    script file contains the definition of tables and other database objects,
+    plus the data for non-cached tables. The log file contains recent changes
+    to the database. The data file contains the data for cached tables and the
+    backup file is a compressed backup of the last known consistent state of
+    the data file. All these files are essential and should never be deleted.
+    For some catalogs, the <code class="filename">test.data</code> and
+    <code class="filename">test.backup</code> files will not be present. In addition to
+    those files, a HyperSQL database may link to any formatted text files,
+    such as CSV lists, anywhere on the disk.</p>
+<p>While the "test" catalog is open, a <code class="filename">test.log</code>
+    file is used to write the changes made to data. This file is removed at a
+    normal SHUTDOWN. Otherwise (with abnormal shutdown) this file is used at
+    the next startup to redo the changes. A <code class="filename">test.lck </code>file
+    is also used to record the fact that the database is open. This is deleted
+    at a normal SHUTDOWN.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>When the engine closes the database at a shutdown, it creates
+      temporary files with the extension <code class="literal">.new</code> which it then
+      renames to those listed above. In some circumstances, a
+      <code class="filename">test.data.old</code> is created and deleted afterwards.
+      These files should not be deleted by the user. At the time of the next
+      startup, all such files will be deleted by the database engine.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>A <em class="glossterm">res:</em> catalog consists of the files for a
+    small, read-only database that can be stored inside a Java resource such
+    as a ZIP or JAR archive and distributed as part of a Java application
+    program.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_inprocess-sect"></a>In-Process Access to Database Catalogs</h2>
+</div>
+</div>
+</div>
+<p>In general, JDBC is used for all access to databases. This is done
+    by making a connection to the database, then using various methods of the
+    <code class="classname">java.sql.Connection</code> object that is returned to
+    access the data. Access to an <em class="glossterm">in-process</em> database
+    is started from JDBC, with the database path specified in the connection
+    URL. For example, if the <em class="glossterm">file: </em>database name is
+    "testdb" and its files are located in the same directory as where the
+    command to run your application was issued, the following code is used for
+    the connection:</p>
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:file:testdb", "SA", "");</pre>
+<p>The database file path format can be specified using forward slashes
+    in Windows hosts as well as Linux hosts. So relative paths or paths that
+    refer to the same directory on the same drive can be identical. For
+    example if your database path in Linux is
+    <code class="filename">/opt/db/testdb</code> and you create an identical directory
+    structure on the <code class="literal">C:</code> drive of a Windows host, you can
+    use the same URL in both Windows and Linux:</p>
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");</pre>
+<p>When using relative paths, these paths will be taken relative to the
+    directory in which the shell command to start the Java Virtual Machine was
+    executed. Refer to the Javadoc for <code class="classname"><a class="classname" href="apd.html#JDBCConnection.html-link">JDBCConnection</a></code> for more
+    details.</p>
+<p>Paths and database names for file databases are treated as
+    case-sensitive when the database is created or the first connection is
+    made to the database. But if a second connection is made to an open
+    database, using a path and name that differs only in case, then the
+    connection is made to the existing open database. This measure is
+    necessary because in Windows the two paths are equivalent.</p>
+<p>A <em class="glossterm">mem:</em> database is specified by the
+    <em class="glossterm">mem:</em> protocol. For <em class="glossterm">mem:</em>
+    databases, the path is simply a name. Several <em class="glossterm">mem:</em>
+    databases can exist at the same time and distinguished by their names. In
+    the example below, the database is called "mymemdb":</p>
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "SA", "");</pre>
+<p>A <em class="glossterm">res:</em> database, is specified by the
+    <em class="glossterm">res:</em> protocol. As it is a Java resource, the
+    database path is a Java URL (similar to the path to a class). In the
+    example below, "resdb" is the root name of the database files, which
+    exists in the directory "org/my/path" within the classpath (probably in a
+    Jar). A Java resource is stored in a compressed format and is decompressed
+    in memory when it is used. For this reason, a <em class="glossterm">res:</em>
+    database should not contain large amounts of data and is always
+    read-only.</p>
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:res:org.my.path.resdb", "SA", "");</pre>
+<p>The first time <em class="glossterm">in-process</em> connection is made
+    to a database, some general data structures are initialised and a few
+    helper threads are started. After this, creation of connections and calls
+    to JDBC methods of the connections execute as if they are part of the Java
+    application that is making the calls. When the SQL command "SHUTDOWN" is
+    executed, the global structures and helper threads for the database are
+    destroyed.</p>
+<p>Note that only one Java process at a time can make
+    <em class="glossterm">in-process</em> connections to a given
+    <em class="glossterm">file:</em> database. However, if the
+    <em class="glossterm">file:</em> database has been made read-only, or if
+    connections are made to a <em class="glossterm">res:</em> database, then it is
+    possible to make <em class="glossterm">in-process</em> connections from
+    multiple Java processes.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_modes-sect"></a>Listener / Server Modes</h2>
+</div>
+</div>
+</div>
+<p>For most applications, <em class="glossterm">in-process</em> access is
+    faster, as the data is not converted and sent over the network. The main
+    drawback is that it is not possible by default to connect to the database
+    from outside your application. As a result you cannot check the contents
+    of the database with external tools such as Database Manager while your
+    application is running.</p>
+<p>Server modes provide the maximum accessibility. The database engine
+    runs in a JVM and opens one or more <em class="glossterm">in-process</em>
+    catalogs. It listens for connections from programs on the same computer or
+    other computers on the network. It translates these connections into
+    <em class="glossterm">in-process</em> connections to the databases.</p>
+<p>Several different programs can connect to the server and retrieve or
+    update information. Applications programs (clients) connect to the server
+    using the HyperSQL JDBC driver. In most server modes, the server can serve
+    an unlimited number of databases that are specified at the time of running
+    the server, or optionally, as a connection request is received.</p>
+<p>A Sever mode is also the prefered mode of running the database
+    during development. It allows you to query the database from a separate
+    database access utility while your application is running.</p>
+<p>There are three server modes, based on the protocol used for
+    communications between the client and server. They are briefly discussed
+    below. More details on servers is provided in the <a class="link" href="listeners-chapt.html" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">HyperSQL Network Listeners</a> chapter.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_hsqlserver-sect"></a>HyperSQL HSQL Server</h3>
+</div>
+</div>
+</div>
+<p>This is the preferred way of running a database server and the
+      fastest one. A proprietary communications protocol is used for this
+      mode. A command similar to those used for running tools and described
+      above is used for running the server. The following example of the
+      command for starting the server starts the server with one (default)
+      database with files named "mydb.*" and the public name of "xdb". The
+      public name hides the file names from users.</p>
+<div class="informalexample">
+<pre class="screen">  java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb</pre>
+</div>
+<p>The command line argument <code class="literal">--help</code> can be used to
+      get a list of available arguments.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_httpserver-sect"></a>HyperSQL HTTP Server</h3>
+</div>
+</div>
+</div>
+<p>This method of access is used when the computer hosting the
+      database server is restricted to the HTTP protocol. The only reason for
+      using this method of access is restrictions imposed by firewalls on the
+      client or server machines and it should not be used where there are no
+      such restrictions. The HyperSQL HTTP Server is a special web server that
+      allows JDBC clients to connect via HTTP. The server can also act as a
+      small general-purpose web server for static pages.</p>
+<p>To run an HTTP server, replace the main class for the server in
+      the example command line above with the following:</p>
+<div class="informalexample">
+<pre class="screen">  org.hsqldb.server.WebServer</pre>
+</div>
+<p>The command line argument <code class="literal">--help</code> can be used to
+      get a list of available arguments.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_servlet-sect"></a>HyperSQL HTTP Servlet</h3>
+</div>
+</div>
+</div>
+<p>This method of access also uses the HTTP protocol. It is used when
+      a separate servlet engine (or application server) such as Tomcat or
+      Resin provides access to the database. The Servlet Mode cannot be
+      started independently from the servlet engine. The
+      <code class="filename">Servlet</code> class, in the HSQLDB jar, should be
+      installed on the application server to provide the connection. The
+      database is specified using an application server property. Refer to the
+      source file <code class="filename"><a class="filename" href="apd.html#Servlet.java-link">
+      src/org/hsqldb/server/Servlet.java</a></code> to see the details.</p>
+<p>Both HTTP Server and Servlet modes can only be accessed using the
+      JDBC driver at the client end. They do not provide a web front end to
+      the database. The Servlet mode can serve only a single database.</p>
+<p>Please note that you do not normally use this mode if you are
+      using the database engine in an application server. In this situation,
+      connections to a catalog are usually made
+      <em class="glossterm">in-process</em>, or using a separate Server</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_connecting-sect"></a>Connecting to a Database Server</h3>
+</div>
+</div>
+</div>
+<p>When a HyperSQL server is running, client programs can connect to
+      it using the HSQLDB JDBC Driver contained in
+      <code class="filename">hsqldb.jar</code>. Full information on how to connect to a
+      server is provided in the Java Documentation for <code class="classname"><a class="classname" href="apd.html#JDBCConnection.html-link"> JDBCConnection</a></code>
+      (located in the <code class="filename">/doc/apidocs</code> directory of HSQLDB
+      distribution). A common example is connection to the default port (9001)
+      used for the <em class="glossterm">hsql:</em> protocol on the same
+      machine:</p>
+<div class="example">
+<a name="N1021A"></a>
+<p class="title">
+<b>Example&nbsp;1.1.&nbsp;Java code to connect to the local hsql Server</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  try {
+      Class.forName("org.hsqldb.jdbc.JDBCDriver" );
+  } catch (Exception e) {
+      System.err.println("ERROR: failed to load HSQLDB JDBC driver.");
+      e.printStackTrace();
+      return;
+  }
+
+  Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb", "SA", "");</pre>
+</div>
+</div>
+<br class="example-break">
+<p>If the HyperSQL HTTP server is used, the protocol is
+      <em class="glossterm">http:</em> and the URL will be different:</p>
+<div class="example">
+<a name="N10224"></a>
+<p class="title">
+<b>Example&nbsp;1.2.&nbsp;Java code to connect to the local http Server</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:http://localhost/xdb", "SA", "");</pre>
+</div>
+</div>
+<br class="example-break">
+<p>Note in the above connection URL, there is no mention of the
+      database file, as this was specified when running the server. Instead,
+      the public name defined for dbname.0 is used. Also, see the <a class="link" href="listeners-chapt.html" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">HyperSQL Network Listeners</a> chapter
+      for the connection URL when there is more than one database per server
+      instance.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_security-sect"></a>Security Considerations</h3>
+</div>
+</div>
+</div>
+<a name="N10233" class="indexterm"></a>
+<p>When a HyperSQL server is run, network access should be adequately
+      protected. Source IP addresses may be restricted by use of our <a class="link" href="listeners-chapt.html#listeners_acl-sect" title="Network Access Control">Access Control List feature</a>,
+      network filtering software, firewall software, or standalone firewalls.
+      Only secure passwords should be used-- most importantly, the password
+      for the default system user should be changed from the default empty
+      string. If you are purposefully providing data to the public, then the
+      wide-open public network connection should be used exclusively to access
+      the public data via read-only accounts. (i.e., neither secure data nor
+      privileged accounts should use this connection). These considerations
+      also apply to HyperSQL servers run with the HTTP protocol.</p>
+<p>HyperSQL provides two optional security mechanisms. The <a class="link" href="listeners-chapt.html#listeners_tls-sect" title="TLS Encryption">encrypted SSL protocol</a>, and
+      <a class="link" href="listeners-chapt.html#listeners_acl-sect" title="Network Access Control">Access Control Lists</a>. Both
+      mechanisms can be specified when running the Server or WebServer. From
+      the client, the URL's co connect to an SSL server is slightly
+      different:</p>
+<p>
+<div class="example">
+<a name="N10248"></a>
+<p class="title">
+<b>Example&nbsp;1.3.&nbsp;Java code to connect to the local secure SSL hsql and http
+          Servers</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  Connection c = DriverManager.getConnection("jdbc:hsqldb:hsqls://localhost/xdb", "SA", "");
+  Connection c = DriverManager.getConnection("jdbc:hsqldb:https://localhost/xdb", "SA", "");
+</pre>
+</div>
+</div>
+<br class="example-break">The security features are discussed in detail in the <a class="link" href="listeners-chapt.html" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">listeners</a>
+      chapter.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="running_multiple_db-sect"></a>Using Multiple Databases</h3>
+</div>
+</div>
+</div>
+<p>A server can provide connections to more than one database. In the
+      examples above, more than one set of database names can be specified on
+      the command line. It is also possible to specify all the databases in a
+      <code class="literal">.properties</code> file, instead of the command line. These
+      capabilities are covered in the <a class="link" href="listeners-chapt.html" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">HyperSQL Network Listeners</a> chapter</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running-data-access-sect"></a>Accessing the Data</h2>
+</div>
+</div>
+</div>
+<p>As shown so far, a <code class="classname">java.sql.Connection</code> object
+    is always used to access the database. But the speed and performance
+    depends on the type of connection.</p>
+<p>Establishing a connection and closing it has some overheads,
+    therefore it is not good practice to create a new connection to perform a
+    small number of operations. A connection should be reused as much as
+    possible and closed only when it is not going to be used again for a long
+    while.</p>
+<p>Reuse is more important for server connections. A server connection
+    uses a TCP port for communications. Each time a connection is made, a port
+    is allocated by the operating system and deallocated after the connection
+    is closed. If many connections are made from a single client, the
+    operating system may not be able to keep up and may refuse the connection
+    attempt.</p>
+<p>A <code class="classname">java.sql.Connection</code> object has some methods
+    that return further <code class="classname">java.sql.*</code> objects. All these
+    objects belong to the connection that returned them and are closed when
+    the connection is closed. These objects can be reused, but if they are not
+    needed after performing the operations, they should be closed.</p>
+<p>A <code class="classname">java.sql.DatabaseMetaData</code> object is used to
+    get metadata for the database.</p>
+<p>A <code class="classname">java.sql.Statement</code> object is used to
+    execute queries and data change statements. A
+    <code class="classname">java.sql.Statement</code> can be reused to execute a
+    different statement each time.</p>
+<p>A <code class="classname">java.sql.PreparedStatement</code> object is used
+    to execute a single statement repeatedly. The SQL statement usually
+    contains parameters, which can be set to new values before each reuse.
+    When a <code class="classname">java.sql.PreparedStatement</code> object is
+    created, the engine keeps the compiled SQL statement for reuse, until the
+    <code class="classname">java.sql.PreparedStatement</code> object is closed. As a
+    result, repeated use of a
+    <code class="classname">java.sql.PreparedStatement</code> is much faster than
+    using a <code class="classname">java.sql.Statement</code> object.</p>
+<p>A <code class="classname">java.sql.CallableStatement</code> object is used
+    to execute an SQL CALL statement. The SQL CALL statement may contain
+    parameters, which should be set to new values before each reuse. Similar
+    to <code class="classname">java.sql.PreparedStatement</code>, the engine keeps the
+    compiled SQL statement for reuse, until the
+    <code class="classname">java.sql.CallableStatement</code> object is closed.</p>
+<p>A <code class="classname">java.sql.Connection</code> object also has some
+    methods for transaction control.</p>
+<p>The <code class="methodname">commit()</code> method performs a
+    <code class="literal">COMMIT</code> while the <code class="methodname">rollback()</code>
+    method performs a <code class="literal">ROLLBACK</code> SQL statement.</p>
+<p>The <code class="methodname">setSavepoint(String name)</code> method
+    performs a <code class="literal">SAVEPOINT &lt;name&gt;</code> SQL statement and
+    returns a <code class="classname">java.sql.Savepoint</code> object. The
+    <code class="methodname">rollback(Savepoint name)</code> method performs a
+    <code class="literal">ROLLBACK TO SAVEPOINT &lt;name&gt;</code> SQL
+    statement.</p>
+<p>The Javadoc for <code class="classname"><a class="classname" href="apd.html#JDBCConnection.html-link">
+    JDBCConnection</a></code>, <code class="classname"><a class="classname" href="apd.html#JDBCDriver.html-link">
+    JDBCDriver</a></code>, <code class="classname"><a class="classname" href="apd.html#JDBCDatabaseMetaData.html-link">
+    JDBCDatabaseMetadata</a></code> <code class="classname"><a class="classname" href="apd.html#JDBCResultSet.html-link"> JDBCResultSet</a></code>,
+    <code class="classname"><a class="classname" href="apd.html#JDBCStatement.html-link">
+    JDBCStatement</a></code>, <code class="classname"><a class="classname" href="apd.html#JDBCPreparedStatement.html-link">
+    JDBCPreparedStatement</a></code> list all the supported JDBC methods
+    together with information that is specific to HSQLDB.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_closing-sect"></a>Closing the Database</h2>
+</div>
+</div>
+</div>
+<p>All databases running in different modes can be closed with the
+    SHUTDOWN command, issued as an SQL statement.</p>
+<p>When SHUTDOWN is issued, all active transactions are rolled back.
+    The catalog files are then saved in a form that can be opened quickly the
+    next time the catalog is opened.</p>
+<p>A special form of closing the database is via the SHUTDOWN COMPACT
+    command. This command rewrites the <code class="literal">.data</code> file that
+    contains the information stored in CACHED tables and compacts it to its
+    minimum size. This command should be issued periodically, especially when
+    lots of inserts, updates or deletes have been performed on the cached
+    tables. Changes to the structure of the database, such as dropping or
+    modifying populated CACHED tables or indexes also create large amounts of
+    unused file space that can be reclaimed using this command.</p>
+<p>Databases are not closed when the last connection to the database is
+    explicitly closed via JDBC. A connection property,
+    <code class="literal">shutdown=true</code>, can be specified on the first connection
+    to the database (the connection that opens the database) to force a
+    shutdown when the last connection closes.</p>
+<p>
+<div class="example">
+<a name="N102EF"></a>
+<p class="title">
+<b>Example&nbsp;1.4.&nbsp;specifying a connection property to shutdown the database when
+        the last connection is closed</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  Connection c = DriverManager.getConnection(
+          "jdbc:hsqldb:file:/opt/db/testdb;shutdown=true", "SA", "");</pre>
+</div>
+</div>
+<br class="example-break">This feature is useful for running tests, where it may not be
+    practical to shutdown the database after each test. But it is not
+    recommended for application programs.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="running_newdb-sect"></a>Creating a New Database</h2>
+</div>
+</div>
+</div>
+<p>When a server instance is started, or when a connection is made to
+    an <em class="glossterm">in-process</em> database, a new, empty database is
+    created if no database exists at the given path.</p>
+<p>With HyperSQL 2.0 the username and password that are specified for
+    the connection are used for the new database. Both the username and
+    password are case-sensitive. (The exception is the default SA user, which
+    is not case-sensitive). If no username or password is specified, the
+    default SA user and an empty password are used.</p>
+<p>This feature has a side effect that can confuse new users. If a
+    mistake is made in specifying the path for connecting to an existing
+    database, a connection is nevertheless established to a new database. For
+    troubleshooting purposes, you can specify a connection property
+    <span class="property">ifexists</span>=<code class="literal">true</code> to allow connection
+    to an existing database only and avoid creating a new database. In this
+    case, if the database does not exist, the
+    <code class="methodname">getConnection()</code> method will throw an
+    exception.</p>
+<p>
+<div class="example">
+<a name="N1030C"></a>
+<p class="title">
+<b>Example&nbsp;1.5.&nbsp;specifying a connection property to disallow creating a new
+        database</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">  Connection c = DriverManager.getConnection(
+          "jdbc:hsqldb:file:/opt/db/testdb;ifexists=true", "SA", "");</pre>
+</div>
+</div>
+<br class="example-break">
+</p>
+<p>A database has many optional properties, described in the <a class="link" href="deployment-chapt.html" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">System Management and Deployment
+  Issues</a> chapter. You can specify most of
+    these properties on the URL or in the connection properties for the first
+    connection that creates the database. See the <a class="link" href="deployment-chapt.html" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">Properties</a> chapter.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="book-pref.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="sqlgeneral-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Preface&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;2.&nbsp;SQL Language</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/sessions-chapt.html b/doc/guide/sessions-chapt.html
new file mode 100644
index 0000000..25801aa
--- /dev/null
+++ b/doc/guide/sessions-chapt.html
@@ -0,0 +1,1134 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;3.&nbsp;Sessions and Transactions</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="sqlgeneral-chapt.html" title="Chapter&nbsp;2.&nbsp;SQL Language">
+<link rel="next" href="databaseobjects-chapt.html" title="Chapter&nbsp;4.&nbsp;Schemas and Database Objects">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="sqlgeneral-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;3.&nbsp;Sessions and Transactions</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="databaseobjects-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;2.&nbsp;SQL Language&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;4.&nbsp;Schemas and Database Objects</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sessions-chapt"></a>Chapter&nbsp;3.&nbsp;Sessions and Transactions</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N107DF"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N107E2">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10801">Session Attributes and Variables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10806">Session Attributes</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10814">Session Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10822">Session Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sessions-chapt.html#sqlgeneral_trans_cc-sect">Transactions and Concurrency Control</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10846">Two Phase Locking</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10859">Two Phase Locking with Snapshot Isolation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10862">Lock Contention in 2PL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N1086D">MVCC</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N1087A">Choosing the Transaction Model</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10887">Schema and Database Change</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10892">Simultaneous Access to Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N107E2"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>All SQL statements are executed in sessions. When a connection is
+    established to the database, a session is started. The authorization of
+    the session is the name of the user that started the session. A session
+    has several properties. These properties are set by default at the start
+    according to database settings.</p>
+<p>SQL Statements are generally transactional statements. When a
+    transactional statement is executed, it starts a transaction if no
+    transaction is in progress. If SQL Data is modified during a transaction,
+    the change can be undone with a ROLLBACK statement. When a COMMIT
+    statement is executed, the transaction is ended. If a single statement
+    fails, the transaction is not normally terminated. However, some failures
+    are caused by execution of statements that are in conflict with statements
+    executed in other concurrent sessions. Such failures result in an implicit
+    ROLLBACK, in addition to the exception that is raised.</p>
+<p>Schema definition and manipulation statements are also transactional
+    according to the SQL Standard. HyperSQL 2.0 performs automatic commits
+    before and after the execution of such transactions. Therefore,
+    schema-related statements cannot be rolled back. This is likely to change
+    in future versions.</p>
+<p>Some statements are not transactional. Most of these statements are
+    used to change the properties of the session. These statements begin with
+    the SET keyword.</p>
+<p>If the AUTOCOMMIT property of a session is TRUE, then each
+    transactional statement is followed by an implicit COMMIT.</p>
+<p>The default isolation level for a session is READ COMMITTED. This
+    can be changed using the JDBC <code class="classname">java.sql.Connection</code>
+    object and its <code class="methodname">setTransactionIsolation(int level)</code>
+    method. The session can be put in read-only mode using the
+    <code class="methodname">setReadOnly(boolean readOnly)</code> method. Both
+    methods can be invoked only after a commit or a rollback, but not during a
+    transaction.</p>
+<p>The isolation level and / or the readonly mode of a transaction
+    can also be modified using an SQL statement. You can use the statement to
+    change only the isolation mode, only the read-only mode, or both at the
+    same time. This command can be issued only after a commit or
+    rollback.</p>
+<p>
+<code class="literal">SET TRANSACTION &lt;transaction characteristic&gt; [
+    &lt;comma&gt; &lt;transaction characteristic&gt; ]</code>
+</p>
+<p>Details of the statement is described later in this chapter.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10801"></a>Session Attributes and Variables</h2>
+</div>
+</div>
+</div>
+<p>Each session has several system attributes. A session can also have
+    user-defined session variables.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10806"></a>Session Attributes</h3>
+</div>
+</div>
+</div>
+<p>The system attributes reflect the current mode of operation for
+      the session. These attributes can be accessed with function calls and
+      can be referenced in queries. For example, they can be returned using
+      the <code class="literal">VALUES &lt;attribute function&gt;, ...</code>
+      statement.</p>
+<p>The named attributes such as CURRENT_USER, CURRENT_SCHEMA, etc.
+      are SQL Standard functions. Other attributes of the session, such as
+      auto-commit or read-only modes can be read using other built-in
+      functions. All these functions are listed in the <a class="link" href="builtinfunctions-chapt.html" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10814"></a>Session Variables</h3>
+</div>
+</div>
+</div>
+<p>Session variables are user-defined variables created the same way
+      as the variables for stored procedures and functions. Currently, these
+      variables cannot be used in general SQL statements. They can be assigned
+      to IN, INOUT and OUT parameters of stored procedures. This allows
+      calling stored procedures which have INOUT or OUT arguments and is
+      useful for development and debugging. See the example in the <a class="link" href="sqlroutines-chapt.html" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">SQL-Invoked Routines</a>
+      chapter, under Formal Parameters.</p>
+<div class="example">
+<a name="N1081D"></a>
+<p class="title">
+<b>Example&nbsp;3.1.&nbsp;User-defined Session Variables</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  DECLARE counter INTEGER DEFAULT 3;
+  DECLARE result VARCHAR(20) DEFAULT NULL;
+  SET counter=15;
+  CALL myroutine(counter, result)
+</pre>
+</div>
+</div>
+<br class="example-break">
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10822"></a>Session Tables</h3>
+</div>
+</div>
+</div>
+<p>With necessary access privileges, sessions can access all table,
+      including GLOBAL TEMPORARY tables, that are defined in schemas. Although
+      GLOBAL TEMPORARY tables have a single name and definition which applies
+      to all sessions that use them, the contents of the tables are different
+      for each session. The contents are cleared either at the end of each
+      transaction or when the session is closed.</p>
+<p>Session tables are different because their definition is visible
+      only within the session that defines a table. The definition is dropped
+      when the session is closed. Session tables do not belong to
+      schemas.</p>
+<p>
+<code class="literal">&lt;temporary table declaration&gt; ::= DECLARE LOCAL
+      TEMPORARY TABLE &lt;table name&gt; &lt;table element list&gt; [ ON
+      COMMIT { PRESERVE | DELETE } ROWS ]</code>
+</p>
+<p>The syntax for declaration is based on the SQL Standard. A session
+      table cannot have FOREIGN KEY constraints, but it can have PRIMARY KEY,
+      UNIQUE or CHECK constraints. A session table definition cannot be
+      modified by adding or removing columns, indexes, etc.</p>
+<p>It is possible to refer to a session table using its name, which
+      takes precedence over a schema table of the same name. To distinguish a
+      session table from schema tables, the pseudo schema name, MODULE can be
+      used. An example is given below:</p>
+<p>
+<div class="example">
+<a name="N10831"></a>
+<p class="title">
+<b>Example&nbsp;3.2.&nbsp;User-defined Temporary Session Tables</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  DECLARE LOCAL TEMPORARY TABLE buffer (id INTEGER PRIMARY KEY, textdata VARCHAR(100)) ON COMMIT PRESERVE ROWS
+  INSERT INTO module.buffer SELECT id, firstname || ' ' || lastname FROM customers
+  -- do some more work
+  DROP TABLE module.buffer
+</pre>
+</div>
+</div>
+<br class="example-break">Session tables can be created inside a transaction.
+      Automatic indexes are created and used on session tables when necessary
+      for a query or other statement. By default, session table data is held
+      in memory. If the session property</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_trans_cc-sect"></a>Transactions and Concurrency Control</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL 2.0 has been fully redesigned to support different
+    transaction isolation models. It no longer supports the old 1.8.x model
+    with "dirty read". Although it is perfectly possible to add an
+    implementation of the transaction manager that supports the legacy model,
+    we thought this is no longer necessary. The new system allows you to
+    select the transaction isolation model even while the engine is running
+    and choose different isolation modes for different simultaneous
+    sessions.</p>
+<p>HyperSQL 2.0 supports three concurrency control models,
+    two-phase-locking (2PL), which is the default, multiversion concurrency
+    control (MVCC) and a hybrid model, which is 2PL plus multiversion rows.
+    Within each model, it supports some of 4 levels of transaction isolation:
+    READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ and SERIALIZABLE. The
+    isolation level is a property of each SQL session, so different sessions
+    can have different isolation levels. The concurrency control model is a
+    strategy that governs all the sessions and is set for the database, as
+    opposed for individual sessions. In the new implementation, all isolation
+    levels avoid the "dirty read" phenomenon and do not read uncommitted
+    changes made to rows by other transactions.</p>
+<p>HyperSQL is fully multi threaded in all transaction models. Sessions
+    continue to work simultaneously and can fully utilise multi-core
+    processors.</p>
+<p>To change the concurrency control model, the <code class="literal">SET DATABASE
+    TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC }</code> can be used by a
+    user with the DBA role.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10846"></a>Two Phase Locking</h3>
+</div>
+</div>
+</div>
+<p>The two-phase locking model is the default mode. It is referred to
+      by the keyword, LOCKS. In the 2PL model, each table that is read by a
+      transaction is locked with a shared lock, and each table that is written
+      to is locked with an exclusive lock. If two sessions read and modify
+      different tables then both go through simultaneously. If one session
+      tries to lock a table that has been locked by the other, if both locks
+      are shared locks, it will go ahead. If either of the locks is an
+      exclusive lock, the engine will put the session in wait until the other
+      session commits or rolls back its transaction. In some cases the engine
+      will invalidate the transaction of the current session, if the action
+      would result in deadlock.</p>
+<p>HyperSQL also supports explicit locking of a group of tables for
+      the duration of the current transaction. Use of this command blocks
+      access to the locked tables by other sessions and ensures the current
+      session can complete the intended reads and writes on the locked
+      tables.</p>
+<p>If a table is read-only, it will not be locked by any
+      transaction.</p>
+<p>The READ UNCOMMITTED isolation level can be used in 2PL modes for
+      read-only operations. It is the same as READ COMMITTED plus read
+      only.</p>
+<p>The READ COMMITTED isolation level is the default. It keeps write
+      locks on tables until commit, but releases the read locks after each
+      operation.</p>
+<p>The REPEATABLE READ level is upgraded to SERIALIZABLE. These
+      levels keep both read and write locks on tables until commit.</p>
+<p>It is possible to perform some critical operations at the
+      SERIALIZABLE level, while the rest of the operations are performed at
+      the READ COMMITTED level.</p>
+<p>Note: two phase locking refers to two periods in the life of a
+      transaction. In the first period, locks are acquired, in the second
+      period locks are released. No new lock is acquired after releasing a
+      lock.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10859"></a>Two Phase Locking with Snapshot Isolation</h3>
+</div>
+</div>
+</div>
+<p>This model is referred to as MVLOCKS. It works the same way as
+      normal 2PL as far as updates are concerned.</p>
+<p>SNAPSHOT ISOLATION is a multiversion concurrency strategy which
+      uses the snapshot of the whole database at the time of the start of the
+      transaction. In this model, read only transactions use SNAPSHOT
+      ISOLATION. While other sessions are busy changing the database, the read
+      only session sees a consistent view of the database and can access all
+      the tables even when they are locked by other sessions for
+      updates.</p>
+<p>There are many applications for this mode of operation. In heavily
+      updated data sets, this mode allows uninterrupted read access to the
+      data.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10862"></a>Lock Contention in 2PL</h3>
+</div>
+</div>
+</div>
+<p>When multiple connections are used to access the database, the
+      transaction manager controls their activities. When each transaction
+      performs only reads or writes on a single table, there is no contention.
+      Each transaction waits until it can obtain a lock then performs the
+      operation and commits. All contentions occur when transactions perform
+      reads and writes on more than one table, or perform a read, followed by
+      a write, on the same table.</p>
+<p>For example, when sessions are working at the SERIALIZABLE level,
+      when multiple sessions first read from a table in order to check if a
+      row exists, then insert a row into the same table when it doesn't exist,
+      there will be regular contention. Transaction A reads from the table,
+      then does Transaction B. Now if either Transaction A or B attempts to
+      insert a row, it will have to be terminated as the other transaction
+      holds a shared lock on the table. If instead of two operations, a single
+      MERGE statement is used to perform the read and write, no contention
+      occurs because both locks are obtained at the same time.</p>
+<p>Alternatively, there is the option of obtaining the necessary
+      locks with an explicit LOCK TABLE statement. This statement should be
+      executed before other statements and should include the names of all the
+      tables and the locks needed. After this statement, all the other
+      statements in the transaction can be executed and the transaction
+      committed. The commit will remove all the locks.</p>
+<p>HyperSQL is fully multi threaded. It therefore allows different
+      transactions to execute concurrently so long as they are not modifying
+      the same table.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1086D"></a>MVCC</h3>
+</div>
+</div>
+</div>
+<p>In the MVCC model, there are no shared, read locks. Exclusive
+      locks are used on individual rows, but their use is different.
+      Transactions can read and modify the same table simultaneously,
+      generally without waiting for other transactions.</p>
+<p>When transactions are running at READ COMMITTED level, no conflict
+      will normally occur. If a transaction that runs at this level wants to
+      modify a row that has been modified by another uncommitted transaction,
+      then the engine puts the transaction in wait, until the other
+      transaction has committed. The transaction then continues automatically.
+      (Conflict is possible if each transaction is waiting for a different row
+      modified by the other transaction, in which case, one of the
+      transactions is terminated). This isolation level is called READ
+      CONSISTENCY.</p>
+<p>When transactions are running in REPEATABLE READ or SERIALIZABLE
+      isolation levels, conflict is more likely to happen. There is no
+      difference in operation between these two isolation levels. If a
+      transaction that runs at these levels wants to modify a row that has
+      been modified by another uncommitted transaction, the engine will
+      invalidate the current transaction and roll back all its changes. This
+      isolation level is called SNAPSHOT ISOLATION.</p>
+<p>In the MVCC model, READ UNCOMMITTED is promoted to READ COMMITTED,
+      as the new architecture is based on multi-version rows for uncommitted
+      data and more than one version may exist for some rows.</p>
+<p>With MVCC, when a transaction only reads data, then it will go
+      ahead and complete regardless of what other transactions may do. This
+      does not depend on the transaction being read-only or the isolation
+      modes.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1087A"></a>Choosing the Transaction Model</h3>
+</div>
+</div>
+</div>
+<p>The SQL Standard defines the isolation levels as modes of
+      operation that avoid the three unwanted phenomena, "dirty read", "fuzzy
+      read" and "phantom row". The "dirty read" phenomenon occurs when a
+      session can read a row that has been changed by another session. The
+      "fuzzy read" phenomenon occurs when a row that was read by a session is
+      modified by another session, then the first session reads the row again.
+      The "phantom row" phenomenon occurs when a session performs an operation
+      that affects several rows, for example, counts the rows or modifies them
+      using a search condition, then another session adds one or more rows
+      that fulfil the same search condition, then the first session performs
+      an operation that relies on the results of its last operation. According
+      to the Standard, the SERIALIZABLE isolation level avoids all three
+      phenomena and also ensures that all the changes performed during a
+      transaction can be considered as a series of uninterrupted changes to
+      the database without any other transaction changing the database at all
+      for the duration of these actions. The changes made by other
+      transactions are considered to occur before the SERIALIZABLE transaction
+      starts, or after it ends. The READ COMMITTED level avoids "dirty read"
+      only, while the REPEATABLE READ level avoids "dirty read" and "fuzzy
+      read", but not "phantom row".</p>
+<p>The Standard allows the engine to return a higher isolation level
+      than requested by the application. HyperSQL promotes a READ UNCOMMITTED
+      request to READ COMMITTED and promotes a REPEATABLE READ request to
+      SERIALIZABLE.</p>
+<p>The MVCC model is not covered directly by the Standard. Research
+      has established that the READ CONSISTENCY level fulfills the
+      requirements of (and is stronger than) the READ COMMITTED level. The
+      SNAPSHOT ISOLATION level is stronger than the READ CONSISTENCY level. It
+      avoids the three anomalies defined by the Standard, and is therefore
+      stronger than the REPEATABLE READ level as defined by the Standard. When
+      operating with the MVCC model, HyperSQL treats a REPEATABLE READ or
+      SERIALIZABLE setting for a transaction as SNAPSHOT ISOLATION.</p>
+<p>All modes can be used with as many simultaneous connections as
+      required. The default 2PL model is fine for applications with a single
+      connection, or applications that do not access the same tables heavily
+      for writes. With multiple simultaneous connections, MVCC can be used for
+      most applications. Both READ CONSISTENCY and SNAPSHOT ISOLATION levels
+      are stronger than the corresponding READ COMMITTED level in the 2PL
+      mode. Some applications require SERIALIZABLE transactions for at least
+      some of their operations. For these applications, one of the 2PL modes
+      can be used. It is possible to switch the concurrency model while the
+      database is operational. Therefore, the model can be changed for the
+      duration of some special operations, such as synchronization with
+      another data source.</p>
+<p>All concurrency models are very fast in operation. When operating
+      mainly on the same tables, the MVCC model may be faster with multiple
+      processors.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10887"></a>Schema and Database Change</h3>
+</div>
+</div>
+</div>
+<p>There are a few SQL statements that must access a consistent state
+      of the database during their executions. These statements, which include
+      CHECKPOINT and BACKUP, put an exclusive lock on all the tables of the
+      database when they start.</p>
+<p>Some schema manipulation statements put an exclusive lock on one
+      or more tables. For example changing the columns of a table locks the
+      table exclusively.</p>
+<p>In the MVCC model, all statements that need an exclusive lock on
+      one or more tables, put an exclusive lock on the database catalog until
+      they complete.</p>
+<p>The effect of these exclusive locks is similar to the execution of
+      data manipulation statements with write locks. The session that is about
+      to execute the schema change statement waits until no other session is
+      holding a lock on any of the objects. At this point it starts its
+      operation and locks the objects to prevents any other session from
+      accessing the locked objects. As soon as the operation is complete, the
+      locks are all removed.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10892"></a>Simultaneous Access to Tables</h3>
+</div>
+</div>
+</div>
+<p>It was mentioned that there is no limit on the number of sessions
+      that can access the tables and all sessions work simultaneously in multi
+      threaded execution. However there are internal resources that are
+      shared. Simultaneous access to these resources reduces the overall
+      efficiency of the system. MEMORY and TEXT tables do not share resources
+      and do not block multi threaded access. With CACHED tables, each write
+      operation blocks the file and its cache until the operation is finished.
+      With CACHED tables, SELECT operations do not block each other, but
+      selecting from different tables and different parts of a large table
+      causes the row cache to be updated frequently and will reduce overall
+      performance.</p>
+<p>The new access pattern is the opposite of the access pattern of
+      version 1.8.x. In the old version, even when 20 sessions are actively
+      reading and writing, only a single session at a time performs an SQL
+      statement completely, before the next session is allowed access. In the
+      new version, while a session is performing a SELECT statement and
+      reading rows of a CACHED table to build a result set, another session
+      may perform an UPDATE statement that reads and writes rows of the same
+      table. The two operations are performed without any conflict, but the
+      row cache is updated more frequently than when one operation is
+      performed after the other operation has finished.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10899"></a>Session and Transaction Control Statements</h2>
+</div>
+</div>
+</div>
+<a name="N1089D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET AUTOCOMMIT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set autocommit command</em></span>
+</p>
+<p>
+<code class="literal">&lt;set autocommit statement&gt; ::= SET AUTOCOMMIT {
+    TRUE | FALSE }</code>
+</p>
+<p>When an SQL session is started by creating a JDBC connection, it
+    is in AUTOCOMMIT mode. In this mode, after each SQL statement a COMMIT is
+    performed automatically. This statement changes the mode. It is equivalent
+    to using the <code class="methodname">setAutoCommit( boolean autoCommit)</code>
+    method of the JDBC <code class="classname">Connection</code> object.</p>
+<a name="N108B4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>START TRANSACTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>start transaction statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;start transaction statement&gt; ::= START
+    TRANSACTION [ &lt;transaction characteristics&gt; ]</code>
+</p>
+<p>Start an SQL transaction and set its characteristics. All
+    transactional SQL statements start a transaction automatically, therefore
+    using this statement is not necessary. If the statement is called in the
+    middle of a transaction, an exception is thrown.</p>
+<a name="N108C5" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET DATABASE TRANSACTION
+    CONTROL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set database transaction control</em></span>
+</p>
+<p>
+<code class="literal">&lt;set database transaction control statement&gt; ::=
+    SET DATABASE TRANSACTION CONTROL { LOCKS | MVLOCKS | MVCC
+    }</code>
+</p>
+<p>Set the concurrency control model for the whole database. It will
+    wait until all sessions have been committed or rolled back. The default is
+    LOCKS.</p>
+<a name="N108D6" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TRANSACTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set next transaction
+    characteristics</em></span>
+</p>
+<p>
+<code class="literal">&lt;set transaction statement&gt; ::= SET [ LOCAL ]
+    TRANSACTION &lt;transaction characteristics&gt;</code>
+</p>
+<p>Set the characteristics of the next transaction in the current
+    session. This statement has an effect only on the next transactions and
+    has no effect on the future transactions after the next.</p>
+<a name="N108E7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>transaction
+    characteristics</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>transaction characteristics</em></span>
+</p>
+<p>
+<code class="literal">&lt;transaction characteristics&gt; ::= [
+    &lt;transaction mode&gt; [ { &lt;comma&gt; &lt;transaction mode&gt; }... ]
+    ]</code>
+</p>
+<p>
+<code class="literal">&lt;transaction mode&gt; ::= &lt;isolation level&gt; |
+    &lt;transaction access mode&gt; | &lt;diagnostics
+    size&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transaction access mode&gt; ::= READ ONLY | READ
+    WRITE</code>
+</p>
+<p>
+<code class="literal">&lt;isolation level&gt; ::= ISOLATION LEVEL &lt;level of
+    isolation&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;level of isolation&gt; ::= READ UNCOMMITTED | READ
+    COMMITTED | REPEATABLE READ | SERIALIZABLE</code>
+</p>
+<p>
+<code class="literal">&lt;diagnostics size&gt; ::= DIAGNOSTICS SIZE &lt;number
+    of conditions&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;number of conditions&gt; ::= &lt;simple value
+    specification&gt;</code>
+</p>
+<p>Specify transaction characteristics.</p>
+<div class="example">
+<a name="N1090A"></a>
+<p class="title">
+<b>Example&nbsp;3.3.&nbsp;Setting Transaction Characteristics</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  SET TRANSACTION READ ONLY
+  SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
+  SET TRANSACTION READ WRITE, ISOLATION LEVEL READ COMMITTED
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N1090F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET CONSTRAINTS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set constraints mode statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set constraints mode statement&gt; ::= SET
+    CONSTRAINTS &lt;constraint name list&gt; { DEFERRED | IMMEDIATE
+    }</code>
+</p>
+<p>
+<code class="literal">&lt;constraint name list&gt; ::= ALL | &lt;constraint
+    name&gt; [ { &lt;comma&gt; &lt;constraint name&gt; }...
+    ]</code>
+</p>
+<p>If the statement is issued during a transaction, it applies to
+    the rest of the current transaction. If the statement is issued when a
+    transaction is not active then it applies only to the next transaction in
+    the current session. HyperSQL does not yet support this feature.</p>
+<a name="N10923" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LOCK TABLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>lock table statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;lock table statement&gt; ::= LOCK TABLE &lt;table
+    name&gt; { READ | WRITE} [, &lt;table name&gt; { READ | WRITE}
+    ...]}</code>
+</p>
+<p>In some circumstances, where multiple simultaneous transactions
+    are in progress, it may be necessary to ensure a transaction consisting of
+    several statements is completed, without being terminated due to possible
+    deadlock. When this statement is executed, it waits until it can obtain
+    all the listed locks, then returns. The SQL statements following this
+    statements use the locks already obtained (and obtain new locks if
+    necessary) and can proceed without waiting. All the locks are released
+    when a COMMIT or ROLLBACK statement is issued. Currently, this command
+    does not have any effect when the database transaction control model is
+    MVCC.</p>
+<div class="example">
+<a name="N10934"></a>
+<p class="title">
+<b>Example&nbsp;3.4.&nbsp;Locking Tables</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  LOCK TABLE table_a WRITE, table_b READ</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N10939" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SAVEPOINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>savepoint statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;savepoint statement&gt; ::= SAVEPOINT &lt;savepoint
+    specifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;savepoint specifier&gt; ::= &lt;savepoint
+    name&gt;</code>
+</p>
+<p>Establish a savepoint. This command is used during an SQL
+    transaction. It establishes a milestone for the current transaction. The
+    SAVEPOINT can be used at a later point in the transaction to rollback the
+    transaction to the milestone.</p>
+<a name="N1094D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RELEASE SAVEPOINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>release savepoint statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;release savepoint statement&gt; ::= RELEASE
+    SAVEPOINT &lt;savepoint specifier&gt;</code>
+</p>
+<p>Destroy a savepoint. This command is rarely used as it is not
+    very useful. It removes a SAVEPOINT that has already been
+    defined.</p>
+<a name="N1095E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>COMMIT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>commit statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;commit statement&gt; ::= COMMIT [ WORK ] [ AND [ NO
+    ] CHAIN ]</code>
+</p>
+<p>Terminate the current SQL-transaction with commit. This make all
+    the changes to the database permanent.</p>
+<a name="N1096F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ROLLBACK</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>rollback statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;rollback statement&gt; ::= ROLLBACK [ WORK ] [ AND [
+    NO ] CHAIN ]</code>
+</p>
+<p>Rollback the current SQL transaction and terminate it. The
+    statement rolls back all the actions performed during the transaction. If
+    NO CHAIN is specified, a new SQL transaction is started just after the
+    rollback. The new transaction inherits the properties of the old
+    transaction.</p>
+<a name="N10980" class="indexterm"></a>
+<p>
+<span class="bold"><strong>ROLLBACK TO SAVEPOINT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>rollback statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;rollback statement&gt; ::= ROLLBACK [ WORK ] TO
+    SAVEPOINT &lt;savepoint specifier&gt;</code>
+</p>
+<p>Rollback part of the current SQL transaction and continue the
+    transaction. The statement rolls back all the actions performed after the
+    specified SAVEPOINT was created. The same effect can be achieved with the
+    <code class="literal">rollback( Savepoint savepoint)</code> method of the JDBC
+    <code class="classname">Connection</code> object.</p>
+<div class="example">
+<a name="N10997"></a>
+<p class="title">
+<b>Example&nbsp;3.5.&nbsp;Rollback</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  -- perform some inserts, deletes, etc.
+  SAVEPOINT A
+  -- perform some inserts, deletes, selects etc.
+  ROLLBACK WORK TO SAVEPOINT A
+  -- all the work after the declaration of SAVEPOINT A is rolled back
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N1099D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DISCONNECT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>disconnect statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;disconnect statement&gt; ::=
+    DISCONNECT</code>
+</p>
+<p>Terminate the current SQL session. Closing a JDBC connection has
+    the same effect as this command.</p>
+<a name="N109AF" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET SESSION
+    CHARACTERISTICS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set session characteristics
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set session characteristics statement&gt; ::= SET
+    SESSION CHARACTERISTICS AS &lt;session characteristic
+    list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;session characteristic list&gt; ::= &lt;session
+    characteristic&gt; [ { &lt;comma&gt; &lt;session characteristic&gt; }...
+    ]</code>
+</p>
+<p>
+<code class="literal">&lt;session characteristic&gt; ::= &lt;session
+    transaction characteristics&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;session transaction characteristics&gt; ::=
+    TRANSACTION &lt;transaction mode&gt; [ { &lt;comma&gt; &lt;transaction
+    mode&gt; }... ]</code>
+</p>
+<p>Set one or more characteristics for the current SQL-session. This
+    command is used to set the transaction mode for the session. This endures
+    for all transactions until the session is closed or the next use of this
+    command. The current read-only mode can be accessed with the ISREADONLY()
+    function.</p>
+<div class="example">
+<a name="N109C9"></a>
+<p class="title">
+<b>Example&nbsp;3.6.&nbsp;Setting Session Characteristics</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY
+  SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE
+  SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE, ISOLATION LEVEL READ COMMITTED
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N109CE" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET SESSION
+    AUTHORIZATION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set session user identifier
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set session user identifier statement&gt; ::= SET
+    SESSION AUTHORIZATION &lt;value specification&gt;</code>
+</p>
+<p>Set the SQL-session user identifier. This statement changes the
+    current user. The user that executes this command must have the
+    CHANGE_AUTHORIZATION role, or the DBA role. After this statement is
+    executed, all SQL statements are executed with the privileges of the new
+    user. The current authorisation can be accessed with the CURRENT_USER and
+    SESSION_USER functions.</p>
+<div class="example">
+<a name="N109DF"></a>
+<p class="title">
+<b>Example&nbsp;3.7.&nbsp;Setting Session Authorization</b>
+</p>
+<div class="example-contents">
+<pre class="screen">  SET SESSION AUTHORIZATION 'FELIX'
+  SET SESSION AUTHORIZATION SESSION_USER
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N109E4" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET ROLE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set role statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set role statement&gt; ::= SET ROLE &lt;role
+    specification&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;role specification&gt; ::= &lt;value
+    specification&gt; | NONE</code>
+</p>
+<p>Set the SQL-session role name and the current role name for the
+    current SQL-session context. The user that executes this command must have
+    the specified role. If NONE is specified, then the previous CURRENT_ROLE
+    is eliminated. The effect of this lasts for the lifetime of the session.
+    The current role can be accessed with the CURRENT_ROLE function.</p>
+<a name="N109F8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET TIME ZONE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set local time zone statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set local time zone statement&gt; ::= SET TIME ZONE
+    &lt;set time zone value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;set time zone value&gt; ::= &lt;interval value
+    expression&gt; | LOCAL</code>
+</p>
+<p>Set the current default time zone displacement for the current
+    SQL-session. When the session starts, the time zone displacement is set to
+    the time zone of the client. This command changes the time zone
+    displacement. The effect of this lasts for the lifetime of the session. If
+    LOCAL is specified, the time zone displacement reverts to the local time
+    zone of the session.</p>
+<div class="example">
+<a name="N10A0C"></a>
+<p class="title">
+<b>Example&nbsp;3.8.&nbsp;Setting Session Time Zone</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    SET TIME ZONE LOCAL
+    SET TIME ZONE INTERVAL '+6:00' HOUR TO MINUTE
+</pre>
+</div>
+</div>
+<br class="example-break">
+<a name="N10A11" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET CATALOG</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set catalog statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set catalog statement&gt; ::= SET &lt;catalog name
+    characteristic&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;catalog name characteristic&gt; ::= CATALOG
+    &lt;value specification&gt;</code>
+</p>
+<p>Set the default schema name for unqualified names used in SQL
+    statements that are prepared or executed directly in the current sessions.
+    As there is only one catalog in the database, only the name of this
+    catalog can be used. The current catalog can be accessed with the
+    CURRENT_CATALOG function.</p>
+<a name="N10A25" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET SCHEMA</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set schema statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set schema statement&gt; ::= SET &lt;schema name
+    characteristic&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema name characteristic&gt; ::= SCHEMA &lt;value
+    specification&gt; | &lt;schema name&gt;</code>
+</p>
+<p>Set the default schema name for unqualified names used in SQL
+    statements that are prepared or executed directly in the current sessions.
+    The effect of this lasts for the lifetime of the session. The SQL Standard
+    form requires the schema name as a single-quoted string. HyperSQL also
+    allows the use of the identifier for the schema. The current schema can be
+    accessed with the CURRENT_SCHEMA function.</p>
+<a name="N10A39" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET PATH</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set path statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set path statement&gt; ::= SET &lt;SQL-path
+    characteristic&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL-path characteristic&gt; ::= PATH &lt;value
+    specification&gt;</code>
+</p>
+<p>Set the SQL-path used to determine the subject routine of routine
+    invocations with unqualified routine names used in SQL statements that are
+    prepared or executed directly in the current sessions. The effect of this
+    lasts for the lifetime of the session.</p>
+<a name="N10A4D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET MAXROWS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set max rows statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set max rows statement&gt; ::= SET MAXROWS
+    &lt;unsigned integer literal&gt;</code>
+</p>
+<p>The normal operation of the session has no limit on the number of
+    rows returned from a SELECT statement. This command set the maximum number
+    of rows of the result returned by executing queries.</p>
+<p>This statement has a similar effect to the
+    <code class="methodname">setMaxRows(int max)</code> method of the JDBC
+    <code class="classname">Statement</code> interface, but it affects the results
+    returned from the next statement execution only. After the execution of
+    the next statement, the MAXROWS limit is removed.</p>
+<p>Only zero or positive values can be used with this command. The
+    value overrides any value specified with <code class="methodname">setMaxRows(int
+    max)</code> method of a JDBC statement. The statement <code class="literal">SET
+    MAXROWS 0</code> means no limit.</p>
+<p>It is possible to limit the number of rows returned from SELECT
+    statements with the FETCH &lt;n&gt; ROWS ONLY, or its alternative, LIMIT
+    &lt;n&gt;. Therefore this command is not recommended for general use. The
+    only legitimate use of this command is for checking and testing queries
+    that may return very large numbers of rows.</p>
+<a name="N10A70" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET SESSION RESULT MEMORY
+    ROWS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set session result memory rows
+    statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set session result memory rows statement&gt; ::= SET
+    SESSION RESULT MEMORY ROWS &lt;unsigned integer
+    literal&gt;</code>
+</p>
+<p>By default the session uses memory to build result sets, subquery
+    results and temporary tables. This command sets the maximum number of rows
+    of the result (and temporary tables) that should be kept in memory. If the
+    row count of the result or temporary table exceeds the setting, the result
+    is stored on disk. The default is 0, meaning all result sets are held in
+    memory.</p>
+<p>This statement applies to the current session only. The general
+    database setting is:</p>
+<p>
+<code class="literal">SET DATABASE DEFAULT RESULT MEMORY ROWS &lt;unsigned
+    integer literal&gt;</code>
+</p>
+<a name="N10A86" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SET IGNORECASE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>set ignore case statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;set ignore case statement&gt; ::= SET IGNORECASE {
+    TRUE | FALSE }</code>
+</p>
+<p>Sets the type used for new VARCHAR table columns. By default,
+    character columns in new databases are case sensitive. If <code class="literal">SET
+    IGNORECASE TRUE</code> is used, all VARCHAR columns in new tables are
+    set to <code class="literal">VARCHAR_IGNORECASE</code>. It is possible to specify
+    the <code class="literal">VARCHAR_IGNORECASE</code> type for the definition of
+    individual columns. So it is possible to have some columns case sensitive
+    and some not, even in the same table. This statement must be switched
+    before creating tables. Existing tables and their data are not
+    affected.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="sqlgeneral-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="databaseobjects-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;2.&nbsp;SQL Language&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;4.&nbsp;Schemas and Database Objects</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/sql-ind.html b/doc/guide/sql-ind.html
new file mode 100644
index 0000000..bd001b1
--- /dev/null
+++ b/doc/guide/sql-ind.html
@@ -0,0 +1,875 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SQL Index</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="apd.html" title="Appendix&nbsp;D.&nbsp;HyperSQL File Links">
+<link rel="next" href="book-ind.html" title="General Index">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="apd.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">SQL Index</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="book-ind.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Appendix&nbsp;D.&nbsp;HyperSQL File Links&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;General Index</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="index">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sql-ind"></a>SQL Index</h2>
+</div>
+</div>
+</div>
+<div class="index">
+<div class="indexdiv">
+<h3>Symbols</h3>
+<dl>
+<dt>_SYSTEM ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>A</h3>
+<dl>
+<dt>ABS function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ACOS function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ADD COLUMN, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ADD CONSTRAINT, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ADD DOMAIN CONSTRAINT, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>aggregate function, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>ALL and ANY predicates, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>ALTER COLUMN, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>alter column nullability, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER DOMAIN, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>alter identity column, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER routine, <a class="indexterm" href="databaseobjects-chapt.html#N1124D">Routine Creation</a>
+</dt>
+<dt>ALTER SEQUENCE, <a class="indexterm" href="databaseobjects-chapt.html#N112F5">Sequence Creation</a>
+</dt>
+<dt>ALTER TABLE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>ALTER USER ... SET INITIAL SCHEMA, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>ALTER USER ... SET PASSWORD, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>ALTER view, <a class="indexterm" href="databaseobjects-chapt.html#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>ASCII function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>ASIN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ATAN2 function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>ATAN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>AUTHORIZATION IDENTIFIER, <a class="indexterm" href="accesscontrol-chapt.html#N11752">Authorizations and Access Control</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>B</h3>
+<dl>
+<dt>BACKUP DATABASE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>BETWEEN predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>binary literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>BINARY types, <a class="indexterm" href="sqlgeneral-chapt.html#N104D7">Binary String Types</a>
+</dt>
+<dt>BIT_LENGTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>BITAND function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>bit literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>BITOR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>BIT types, <a class="indexterm" href="sqlgeneral-chapt.html#N104F5">Bit String Types</a>
+</dt>
+<dt>BITXOR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>boolean literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>BOOLEAN types, <a class="indexterm" href="sqlgeneral-chapt.html#N10482">Boolean Type</a>
+</dt>
+<dt>boolean value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>C</h3>
+<dl>
+<dt>CARDINALITY function, <a class="indexterm" href="builtinfunctions-chapt.html#N132C8">Array Functions</a>
+</dt>
+<dt>CASCADE or RESTRICT, <a class="indexterm" href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>case expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>CASE WHEN in routines, <a class="indexterm" href="sqlroutines-chapt.html#N12699">Conditional Statements</a>
+</dt>
+<dt>CAST, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>CEIL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>CHANGE_AUTHORIZATION, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>CHARACTER_LENGTH, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>character literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>CHARACTER types, <a class="indexterm" href="sqlgeneral-chapt.html#N104A8">Character String Types</a>
+</dt>
+<dt>character value function, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>CHECK constraint, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CHECKPOINT, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>COALESCE expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>COALESCE function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>COLLATE, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>column definition, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>column reference, <a class="indexterm" href="dataaccess-chapt.html#N11B9C">References, etc.</a>
+</dt>
+<dt>COMMENT, <a class="indexterm" href="databaseobjects-chapt.html#N10D01">Commenting Objects</a>
+</dt>
+<dt>COMMIT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>comparison predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>CONCAT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>CONSTRAINT, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>CONSTRAINT (table constraint), <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CONSTRAINT name and characteristics, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>contextually typed value specification, <a class="indexterm" href="dataaccess-chapt.html#N11B9C">References, etc.</a>
+</dt>
+<dt>CONVERT function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>COS function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>COT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>CREATE_SCHEMA ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>CREATE AGGREGATE FUNCTION, <a class="indexterm" href="sqlroutines-chapt.html#N12802">Definition of Aggregate Functions</a>
+</dt>
+<dt>CREATE ASSERTION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE CAST, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE CHARACTER SET, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE COLLATION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE DOMAIN, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>CREATE FUNCTION, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>CREATE INDEX, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE PROCEDURE, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>CREATE ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>CREATE SCHEMA, <a class="indexterm" href="databaseobjects-chapt.html#N10D1D">Schema Creation</a>
+</dt>
+<dt>CREATE SEQUENCE, <a class="indexterm" href="databaseobjects-chapt.html#N112F5">Sequence Creation</a>
+</dt>
+<dt>CREATE TABLE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>CREATE TRANSLATION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE TRIGGER, <a class="indexterm" href="databaseobjects-chapt.html#N111D1">Trigger Creation</a>, <a class="indexterm" href="triggers-chapt.html#N12A85">Trigger Creation</a>
+</dt>
+<dt>CREATE TYPE, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>CREATE USER, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>CREATE VIEW, <a class="indexterm" href="databaseobjects-chapt.html#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>CROSS JOIN, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>CRYPT_KEY, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>CRYPT_KEY function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURDATE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_CATALOG function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_DATE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_ROLE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_SCHEMA function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURRENT_TIME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_TIMESTAMP function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>CURRENT_USER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>CURTIME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>D</h3>
+<dl>
+<dt>DATABASE_ISOLATION_LEVEL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATABASE_TIMEZONE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DATABASE_VERSION function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATABASE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>DATEADD function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DATEDIFF function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>datetime and interval literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>Datetime Operations, <a class="indexterm" href="sqlgeneral-chapt.html#N10544">Datetime types</a>
+</dt>
+<dt>DATETIME types, <a class="indexterm" href="sqlgeneral-chapt.html#N10544">Datetime types</a>
+</dt>
+<dt>datetime value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>datetime value function, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>DAYNAME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFMONTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFWEEK function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DAYOFYEAR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>DBA ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>DECODE function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>DEFAULT clause, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DEGREES function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>DELETE FROM, <a class="indexterm" href="dataaccess-chapt.html#N123DD">Delete Statement</a>
+</dt>
+<dt>DETERMINISTIC characteristic, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>DIFFERENCE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>DISCONNECT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>DROP ASSERTION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP CAST, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP CHARACTER SET, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP COLLATION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP COLUMN, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP CONSTRAINT, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP DEFAULT (table), <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN CONSTRAINT, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP DOMAIN DEFAULT, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>DROP INDEX, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>DROP routine, <a class="indexterm" href="databaseobjects-chapt.html#N1124D">Routine Creation</a>
+</dt>
+<dt>DROP SCHEMA, <a class="indexterm" href="databaseobjects-chapt.html#N10D1D">Schema Creation</a>
+</dt>
+<dt>DROP SEQUENCE, <a class="indexterm" href="databaseobjects-chapt.html#N112F5">Sequence Creation</a>
+</dt>
+<dt>DROP TABLE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>DROP TRANSLATION, <a class="indexterm" href="databaseobjects-chapt.html#N1139F">Other Schema Object Creation</a>
+</dt>
+<dt>DROP TRIGGER, <a class="indexterm" href="databaseobjects-chapt.html#N111D1">Trigger Creation</a>, <a class="indexterm" href="triggers-chapt.html#N12A85">Trigger Creation</a>
+</dt>
+<dt>DROP USER, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>DROP VIEW, <a class="indexterm" href="databaseobjects-chapt.html#N110DE">View Creation and Manipulation</a>
+</dt>
+<dt>DYNAMIC RESULT SETS, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>E</h3>
+<dl>
+<dt>EXISTS predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>EXP function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>EXTERNAL NAME, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>EXTRACT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>F</h3>
+<dl>
+<dt>FLOOR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>FOREIGN KEY constraint, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>G</h3>
+<dl>
+<dt>GRANTED BY, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GRANT privilege, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GRANT role, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>GREATEST function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>GROUPING OPERATIONS, <a class="indexterm" href="dataaccess-chapt.html#N12338">Grouping Operations</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>H</h3>
+<dl>
+<dt>HEXTORAW function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>HOUR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>I</h3>
+<dl>
+<dt>identifier chain, <a class="indexterm" href="dataaccess-chapt.html#N11B9C">References, etc.</a>
+</dt>
+<dt>identifier definition, <a class="indexterm" href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a>, <a class="indexterm" href="accesscontrol-chapt.html#N11712">Overview</a>
+</dt>
+<dt>IDENTITY function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>IF EXISTS, <a class="indexterm" href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>IFNULL function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>IF STATEMENT, <a class="indexterm" href="sqlroutines-chapt.html#N12699">Conditional Statements</a>
+</dt>
+<dt>IN predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>INSERT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>INSERT INTO, <a class="indexterm" href="dataaccess-chapt.html#N1241F">Insert Statement</a>
+</dt>
+<dt>interval absolute value function, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>interval term, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>INTERVAL types, <a class="indexterm" href="sqlgeneral-chapt.html#N1063D">Interval Types</a>
+</dt>
+<dt>ISAUTOCOMMIT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>IS DISTINCT predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>IS NULL predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>ISOLATION_LEVEL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYDATABASEFILES function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYDATABASE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>ISREADONLYSESSION function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>J</h3>
+<dl>
+<dt>JOIN USING, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>JOIN with condition, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>L</h3>
+<dl>
+<dt>LANGUAGE, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>LCASE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LEAST function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>LEFT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LENGTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LIKE predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>LN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LOCALTIME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>LOCALTIMESTAMP function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>LOCATE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>LOCK TABLE, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>LOG10 function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LOG function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>LTRIM function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>M</h3>
+<dl>
+<dt>MATCH predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>MAX_CARDINALITY function, <a class="indexterm" href="builtinfunctions-chapt.html#N132C8">Array Functions</a>
+</dt>
+<dt>MERGE INTO, <a class="indexterm" href="dataaccess-chapt.html#N124B8">Merge Statement</a>
+</dt>
+<dt>MINUTE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>MOD function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>MONTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>MONTHNAME function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>N</h3>
+<dl>
+<dt>name resolution, <a class="indexterm" href="dataaccess-chapt.html#N122F6">Naming</a>
+</dt>
+<dt>naming in joined table, <a class="indexterm" href="dataaccess-chapt.html#N122F6">Naming</a>
+</dt>
+<dt>naming in select list, <a class="indexterm" href="dataaccess-chapt.html#N122F6">Naming</a>
+</dt>
+<dt>NATURAL JOIN, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>NEXT VALUE FOR, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>NOW function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>NULLIF expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>NULLIF function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+<dt>NULL INPUT, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>numeric literal, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>NUMERIC types, <a class="indexterm" href="sqlgeneral-chapt.html#N103BA">Numeric Types</a>
+</dt>
+<dt>numeric value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>numeric value function, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>NVL function, <a class="indexterm" href="builtinfunctions-chapt.html#N132FD">General Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>O</h3>
+<dl>
+<dt>OCTET_LENGTH function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>OTHER type, <a class="indexterm" href="sqlgeneral-chapt.html#N1050A">Storage and Handling of Java Objects</a>
+</dt>
+<dt>OUTER JOIN, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>OVERLAPS predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>OVERLAY function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>P</h3>
+<dl>
+<dt>PATH, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>PI function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>POSITION function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>POWER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>PRIMARY KEY constraint, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>PUBLIC ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>Q</h3>
+<dl>
+<dt>QUARTER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>R</h3>
+<dl>
+<dt>RADIANS function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>RAND function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>RAWTOHEX function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REGEXP_MATCHES function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>RELEASE SAVEPOINT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>RENAME, <a class="indexterm" href="databaseobjects-chapt.html#N10CE1">Renaming Objects</a>
+</dt>
+<dt>REPEAT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REPLACE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>RETURN, <a class="indexterm" href="sqlroutines-chapt.html#N126E2">Return Statement</a>
+</dt>
+<dt>RETURNS, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>REVERSE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>REVOKE, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>REVOKE ROLE, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>RIGHT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>ROLLBACK, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>ROLLBACK TO SAVEPOINT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>ROUND function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>routine body, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>routine invocation, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>row value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>RTRIM function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>S</h3>
+<dl>
+<dt>SA USER, <a class="indexterm" href="accesscontrol-chapt.html#N11775">Built-In Roles and Users</a>
+</dt>
+<dt>SAVEPOINT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SAVEPOINT LEVEL, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>schema routine, <a class="indexterm" href="databaseobjects-chapt.html#N1124D">Routine Creation</a>
+</dt>
+<dt>SCRIPT, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>search condition, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>SECOND function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SECONDS_SINCE_MIDNIGHT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SELECT : SINGLE ROW, <a class="indexterm" href="sqlroutines-chapt.html#N12648">Select Statement : Single Row</a>
+</dt>
+<dt>SESSION_ISOLATION_LEVEL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>SESSION_TIMEZONE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>SESSION_USER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>SET AUTOCOMMIT, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET CATALOG, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>set clause in UPDATE and MERGE statements, <a class="indexterm" href="dataaccess-chapt.html#N1246A">Update Statement</a>
+</dt>
+<dt>SET CONSTRAINTS, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET DATABASE COLLATION, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE DEFAULT INITIAL SCHEMA, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET DATABASE DEFAULT RESULT MEMORY ROWS, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE DEFAULT TABLE TYPE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE EVENT LOG LEVEL, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE GC, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL NAMES, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL REFERENCES, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE SQL SIZE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE TRANSACTION CONTROL, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATABASE UNIQUE NAME*, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET DATA TYPE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET DEFAULT, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET DOMAIN DEFAULT, <a class="indexterm" href="databaseobjects-chapt.html#N1113C">Domain Creation and Manipulation</a>
+</dt>
+<dt>SET FILES BACKUP INCREMENT, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES CACHE ROWS, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES CACHE SIZE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES DEFRAG, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOB SCALE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOG, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES LOG SIZE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES NIO, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES SCALE, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET FILES WRITE DELAY, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>set function specification, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>SET IGNORECASE, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET INITIAL SCHEMA*, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET MAXROWS, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET OPERATIONS, <a class="indexterm" href="dataaccess-chapt.html#N1234D">Set Operations</a>
+</dt>
+<dt>SET PASSWORD, <a class="indexterm" href="accesscontrol-chapt.html#N11810">Statements for
+    Authorization and Access Control</a>
+</dt>
+<dt>SET PATH, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET REFERENTIAL INTEGRITY, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SET ROLE, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SCHEMA, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION AUTHORIZATION, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION CHARACTERISTICS, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET SESSION RESULT MEMORY ROWS, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET TABLE read-write property, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE HEADER, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TABLE SOURCE on-off, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>SET TIME ZONE, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SET TRANSACTION, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>SHUTDOWN, <a class="indexterm" href="deployment-chapt.html#N137E9">Statements</a>
+</dt>
+<dt>SIGN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>SIN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>sort specification list, <a class="indexterm" href="dataaccess-chapt.html#N1205E">Other Syntax Elements</a>
+</dt>
+<dt>SOUNDEX function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SPACE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SPECIFIC, <a class="indexterm" href="databaseobjects-chapt.html#N10C61">Common Elements and Statements</a>
+</dt>
+<dt>SPECIFIC NAME, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>SQL DATA access characteristic, <a class="indexterm" href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a>
+</dt>
+<dt>SQL parameter reference, <a class="indexterm" href="dataaccess-chapt.html#N11B9C">References, etc.</a>
+</dt>
+<dt>SQL procedure statement, <a class="indexterm" href="databaseobjects-chapt.html#N1137F">SQL Procedure Statement</a>
+</dt>
+<dt>SQL routine body, <a class="indexterm" href="sqlroutines-chapt.html#N12854">Routine Definition</a>
+</dt>
+<dt>SQRT function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>START TRANSACTION, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>string value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>SUBSTR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SUBSTRING function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>SYSTEM_USER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>T</h3>
+<dl>
+<dt>TAN function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>TIMESTAMPADD function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TIMESTAMPDIFF function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>Time Zone, <a class="indexterm" href="sqlgeneral-chapt.html#N10544">Datetime types</a>
+</dt>
+<dt>TIMEZONE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TO_CHAR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+<dt>TRANSACTION_CONTROL function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+<dt>transaction characteristics, <a class="indexterm" href="sessions-chapt.html#N10899">Session and Transaction Control Statements</a>
+</dt>
+<dt>TRIGGERED SQL STATEMENT, <a class="indexterm" href="triggers-chapt.html#N12A85">Trigger Creation</a>
+</dt>
+<dt>TRIGGER EXECUTION ORDER, <a class="indexterm" href="triggers-chapt.html#N12A85">Trigger Creation</a>
+</dt>
+<dt>TRIM_ARRAY function, <a class="indexterm" href="builtinfunctions-chapt.html#N132C8">Array Functions</a>
+</dt>
+<dt>TRIM function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>TRUNCATE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_numeric-sect">Numeric Functions</a>
+</dt>
+<dt>TRUNCATE TABLE, <a class="indexterm" href="dataaccess-chapt.html#N123FD">Truncate Statement</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>U</h3>
+<dl>
+<dt>UCASE function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_string-sect">String and Binary String Functions</a>
+</dt>
+<dt>unicode escape elements, <a class="indexterm" href="dataaccess-chapt.html#N11A76">Literals</a>
+</dt>
+<dt>UNION JOIN, <a class="indexterm" href="dataaccess-chapt.html#N12278">Joined Table</a>
+</dt>
+<dt>UNIQUE constraint, <a class="indexterm" href="databaseobjects-chapt.html#N10D6E">Table Creation and Manipulation</a>
+</dt>
+<dt>UNIQUE predicate, <a class="indexterm" href="dataaccess-chapt.html#N11E1B">Predicates</a>
+</dt>
+<dt>UPDATE, <a class="indexterm" href="dataaccess-chapt.html#N1246A">Update Statement</a>
+</dt>
+<dt>USER function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_sysfunc-sect">System Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>V</h3>
+<dl>
+<dt>value expression, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>value expression primary, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+<dt>value specification, <a class="indexterm" href="dataaccess-chapt.html#N11BF8">Value Expression</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>W</h3>
+<dl>
+<dt>WEEK function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+<div class="indexdiv">
+<h3>Y</h3>
+<dl>
+<dt>YEAR function, <a class="indexterm" href="builtinfunctions-chapt.html#builtin_functions_datetime-sect">Date Time and Interval Functions</a>
+</dt>
+</dl>
+</div>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="apd.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="book-ind.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Appendix&nbsp;D.&nbsp;HyperSQL File Links&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;General Index</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/sqlgeneral-chapt.html b/doc/guide/sqlgeneral-chapt.html
new file mode 100644
index 0000000..1cf1953
--- /dev/null
+++ b/doc/guide/sqlgeneral-chapt.html
@@ -0,0 +1,1711 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;2.&nbsp;SQL Language</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="running-chapt.html" title="Chapter&nbsp;1.&nbsp;Running and Using HyperSQL">
+<link rel="next" href="sessions-chapt.html" title="Chapter&nbsp;3.&nbsp;Sessions and Transactions">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="running-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;2.&nbsp;SQL Language</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="sessions-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;1.&nbsp;Running and Using HyperSQL&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;3.&nbsp;Sessions and Transactions</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sqlgeneral-chapt"></a>Chapter&nbsp;2.&nbsp;SQL Language</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N10343"></a>
+<p>Copyright 2002-2010 Fred Toussi. Permission is granted to
+      distribute this document without any alteration under the terms of the
+      HSQLDB license. Additional permission is granted to the HSQL Development
+      Group to distribute this document with or without alterations under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#sqlgeneral_standards-sect">Standards Support</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#sqlgeneral_tabletypes-sect">SQL Data and Tables</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N1037B">Temporary Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10380">Persistent Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N103A7">Lob Data</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#sqlgeneral_types_ops-sect">Basic Types and Operations</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N103BA">Numeric Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10482">Boolean Type</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N104A8">Character String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N104D7">Binary String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N104F5">Bit String Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N1050A">Storage and Handling of Java Objects</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10529">Type Length, Precision and Scale</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10544">Datetime types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N1063D">Interval Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N106BD">Arrays</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N106CA">Array Definition</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N106ED">Array Reference</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N10706">Array Operations</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#sqlgeneral_constr_indexes-sect">Indexes and Query Speed</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlgeneral-chapt.html#N1079B">Query Processing and Optimisation</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_standards-sect"></a>Standards Support</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL 2.0 supports the dialect of SQL defined by SQL standards
+    92, 1999, 2003 and 2008. This means where a feature of the standard is
+    supported, e.g. left outer join, the syntax is that specified by the
+    standard text. Almost all syntactic features of SQL-92 up to Advanced
+    Level are supported, as well as SQL:2008 core and many optional features
+    of this standard. Work is in progress for a formal declaration of
+    conformance.</p>
+<p>At the time of this release, HyperSQL supports the widest range of
+    SQL standard features among all open source RDBMS.</p>
+<p>Various chapters of this guide list the supported syntax. When
+    writing or converting existing SQL DDL (Data Definition Language), DML
+    (Data Manipulation Language) or DQL (Data Query Language) statements for
+    HSQLDB, you should consult the supported syntax and modify the statements
+    accordingly. Some statements written for older versions may have to be
+    modified.</p>
+<p>Over 300 words are reserved by the standard and should not be used
+    as table or column names. For example, the word POSITION is reserved as it
+    is a function defined by the Standards with a similar role as
+    <code class="methodname">String.indexOf()</code> in Java. HyperSQL does not
+    currently prevent you from using a reserved word if it does not support
+    its use or can distinguish it. For example CUBE is a reserved words that
+    is not currently supported by HyperSQL and is allowed as a table or column
+    name. You should avoid using such names as future versions of HyperSQL are
+    likely to support the reserved words and may reject your table definitions
+    or queries. The full list of SQL reserved words is in the appendix <a class="link" href="lists-app.html" title="Appendix&nbsp;A.&nbsp;Lists of Keywords">Lists of Keywords</a> .</p>
+<p>If you have to use a reserved keyword as the name of a database
+    object, you can enclose it in double quotes.</p>
+<p>HyperSQL also supports enhancements with keywords and expressions
+    that are not part of the SQL standard. Expressions such as <code class="literal">SELECT
+    TOP 5 FROM ..</code>, <code class="literal">SELECT LIMIT 0 10 FROM ...</code> or
+    <code class="literal">DROP TABLE mytable IF EXISTS</code> are among such
+    constructs.</p>
+<p>Many print books cover SQL Standard syntax and can be consulted. For
+    a well-written basic guide to SQL with examples, you can also consult
+    <a class="link" href="http://www.postgresql.org/files/documentation/books/aw_pgsql/index.html" target="_top">PostgreSQL:
+    Introduction and Concepts</a> by Bruce Momjian, which is available on
+    the web. Most of the core SQL coverage in the book applies also to
+    HyperSQL. There are some differences in keywords supported by one and not
+    the other engine (OUTER, OID's, etc.) or used differently
+    (IDENTITY/SERIAL, TRIGGER, SEQUENCE, etc.).</p>
+<p>In HyperSQL version 2.0, all features of JDBC4 that apply to the
+    capabilities of HSQLDB are fully supported. The relevant JDBC classes are
+    thoroughly documented with additional clarifications and HyperSQL specific
+    comments. See the <a class="link" href="apd.html#javadoc-link">JavaDoc</a> for the
+    <code class="classname">org.hsqldb.jdbc.*</code> classes.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_tabletypes-sect"></a>SQL Data and Tables</h2>
+</div>
+</div>
+</div>
+<p>In an SQL system, all significant data is stored in tables and
+    sequence generators. Therefore, the first step in creating a database is
+    defining the tables and their columns. The SQL standard supports temporary
+    tables, which are for temporary data, and permanent base tables, which are
+    for persistent data.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1037B"></a>Temporary Tables</h3>
+</div>
+</div>
+</div>
+<p>TEMPORARY tables are not saved and last only for the lifetime of
+      the Connection object. The contents of each TEMP table is visible only
+      from the Connection that was used to populate it. The definition of TEMP
+      tables conforms to the GLOBAL TEMPORARY type in the SQL standard. The
+      definition of the table persists but each new connections sees its own
+      copy of the table, which is empty at the beginning. When the connection
+      commits, the contents of the table are cleared by default. If the table
+      definition statements includes ON COMMIT PRESERVE ROWS, then the
+      contents are kept when a commit takes place.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10380"></a>Persistent Tables</h3>
+</div>
+</div>
+</div>
+<p>HSQLDB supports the Standard definition of persistent base table,
+      but defines three types according to the way the data is stored. These
+      are MEMORY tables, CACHED tables and TEXT tables.</p>
+<p>Memory tables are the default type when the CREATE TABLE command
+      is used. Their data is held entirely in memory but any change to their
+      structure or contents is written to the <code class="filename">*.log</code> and
+      <code class="filename">*.script</code> files. The <code class="filename">*.script</code>
+      file and the <code class="filename">*.log</code> file are read the next time the
+      database is opened, and the MEMORY tables are recreated with all their
+      contents. So unlike TEMPORARY tables, MEMORY tables are persistent. When
+      the database is opened, all the data for the memory tables is read and
+      inserted. This process may take a long time if the database is larger
+      than tens of megabytes. When the database is shutdown, all the data is
+      saved. This can also take a long time.</p>
+<p>CACHED tables are created with the CREATE CACHED TABLE command.
+      Only part of their data or indexes is held in memory, allowing large
+      tables that would otherwise take up to several hundred megabytes of
+      memory. Another advantage of cached tables is that the database engine
+      takes less time to start up when a cached table is used for large
+      amounts of data. The disadvantage of cached tables is a reduction in
+      speed. Do not use cached tables if your data set is relatively small. In
+      an application with some small tables and some large ones, it is better
+      to use the default, MEMORY mode for the small tables.</p>
+<p>TEXT tables use a CSV (Comma Separated Value) or other delimited
+      text file as the source of their data. You can specify an existing CSV
+      file, such as a dump from another database or program, as the source of
+      a TEXT table. Alternatively, you can specify an empty file to be filled
+      with data by the database engine. TEXT tables are efficient in memory
+      usage as they cache only part of the text data and all of the indexes.
+      The Text table data source can always be reassigned to a different file
+      if necessary. The commands are needed to set up a TEXT table as detailed
+      in the <a class="link" href="texttables-chapt.html" title="Chapter&nbsp;5.&nbsp;Text Tables">Text Tables</a> chapter.</p>
+<p>With all-in-memory databases, both MEMORY table and CACHED table
+      declarations are treated as declarations for non-persistent memory
+      tables. TEXT table declarations are not allowed in these
+      databases.</p>
+<p>The default type of table resulting from future CREATE TABLE
+      statements can be specified with the SQL command:</p>
+<p>
+<pre class="programlisting">    SET DATABASE DEFAULT TABLE TYPE { CACHED | MEMORY };</pre>The
+      type of an existing table can be changed with the SQL command:</p>
+<p>
+<pre class="programlisting">    SET TABLE &lt;table name&gt; TYPE { CACHED | MEMORY };</pre>SQL
+      statements access different types of tables uniformly. No change to
+      statements is needed to access different types of table.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N103A7"></a>Lob Data</h3>
+</div>
+</div>
+</div>
+<p>Lobs are logically stored in columns of tables. Their physical
+      storage is a separate *.lobs file. In version 2.0 this file is created
+      as soon as a BLOB or CLOB is inserted into the database. The file will
+      grow as new lobs are inserted into the database. In version 2.0, the
+      *.lobs file is never deleted even if all lobs are deleted from the
+      database (In this case you can delete the .lobs file after a
+      SHTUDOWN).</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_types_ops-sect"></a>Basic Types and Operations</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL supports all the types defined by SQL-92, plus BOOLEAN,
+    BINARY and LOB types that were added later to the SQL Standard. It also
+    supports the non-standard OTHER type to store serializable Java
+    objects.</p>
+<p>SQL is a strongly typed language. All data stored in specific
+    columns of tables and other objects (such as sequence generators) have
+    specific types. Each data item conforms to the type limits such as
+    precision and scale for the column. It also conforms to any additional
+    integrity constraints that are defined as CHECK constraints in domains or
+    tables. Types can be explicitly converted using the CAST expression, but
+    in most expressions they are converted automatically.</p>
+<p>Data is returned to the user (or the application program) as a
+    result of executing SQL statements such as query expressions or function
+    calls. All statements are compiled prior to execution and the return type
+    of the data is known after compilation and before execution. Therefore,
+    once a statement is prepared, the data type of each column of the returned
+    result is known, including any precision or scale property. The type does
+    not change when the same query that returned one row, returns many rows as
+    a result of adding more data to the tables.</p>
+<p>Some SQL functions used within SQL statements are polymorphic, but
+    the exact type of the argument and the return value is determined at
+    compile time.</p>
+<p>When a statement is prepared, using a JDBC PreparedStatement object,
+    it is compiled by the engine and the type of the columns of its ResultSet
+    and / or its parameters are accessible through the methods of
+    PreparedStatement.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N103BA"></a>Numeric Types</h3>
+</div>
+</div>
+</div>
+<a name="N103BD" class="indexterm"></a>
+<p>TINYINT, SMALLINT, INTEGER, BIGINT, NUMERIC and DECIMAL (without a
+      decimal point) are the supported integral types. They correspond
+      respectively to <code class="classname">byte</code>,
+      <code class="classname">short</code>, <code class="classname">int</code>,
+      <code class="classname">long</code>, <code class="classname">BigDecimal</code> and
+      <code class="classname">BigDecimal</code> Java types in the range of values that
+      they can represent (NUMERIC and DECIMAL are equivalent). The type
+      TINYINT is an HSQLDB extension to the SQL Standard, while the others
+      conform to the Standard definition. The SQL type dictates the maximum
+      and minimum values that can be held in a field of each type. For example
+      the value range for TINYINT is -128 to +127. The bit precision of
+      TINYINT, SMALLINT, INTEGER and BIGINT is respectively 8, 16, 32 and 64.
+      For NUMERIC and DECIMAL, decimal precision is used.</p>
+<p>DECIMAL and NUMERIC with decimal fractions are mapped to
+      <code class="classname">java.math.BigDecimal</code> and can have very large
+      numbers of digits. In HyperSQL the two types are equivalent. These
+      types, together with integral types, are called exact numeric
+      types.</p>
+<p>In HyperSQL, REAL, FLOAT, DOUBLE are equivalent and all mapped to
+      <code class="classname">double</code> in Java. These types are defined by the
+      SQL Standard as approximate numeric types. The bit-precision of all
+      these types is 64 bits.</p>
+<p>The decimal precision and scale of NUMERIC and DECIMAL types can
+      be optionally defined. For example, DECIMAL(10,2) means maximum total
+      number of digits is 10 and there are always 2 digits after the decimal
+      point, while DECIMAL(10) means 10 digits without a decimal point. The
+      bit-precision of FLOAT can also be defined, but in this case, it is
+      ignored and the default bit-precision of 64 is used. The default
+      precision of NUMERIC and DECIMAL (when not defined) is 100.</p>
+<p>Note: If a database has been set to ignore type precision limits
+      with the SET DATABASE SQL SIZE FALSE command, then a type definition of
+      DECIMAL with no precision and scale is treated as DECIMAL(100,10). In
+      normal operation, it is treated as DECIMAL(100).</p>
+<p>
+<span class="bold"><strong>Integral Types</strong></span>
+</p>
+<p>In expressions, TINYINT, SMALLINT, INTEGER, BIGINT, NUMERIC and
+      DECIMAL (without a decimal point) are fully interchangeable, and no data
+      narrowing takes place.</p>
+<p>If the SELECT statement refers to a simple column or function,
+      then the return type is the type corresponding to the column or the
+      return type of the function. For example:</p>
+<div class="informalexample">
+<pre class="programlisting">    CREATE TABLE t(a INTEGER, b BIGINT);
+    SELECT MAX(a), MAX(b) FROM t;</pre>
+</div>
+<p>will return a <code class="classname">ResultSet</code> where the type of
+      the first column is <code class="classname">java.lang.Integer</code> and the
+      second column is <code class="classname">java.lang.Long</code>. However,</p>
+<div class="informalexample">
+<pre class="programlisting">    SELECT MAX(a) + 1, MAX(b) + 1 FROM t;</pre>
+</div>
+<p>will return <code class="classname">java.lang.Long</code> and
+      <code class="classname">BigDecimal</code> values, generated as a result of
+      uniform type promotion for all the return values. Note that type
+      promotion to <code class="classname">BigDecimal</code> ensures the correct value
+      is returned if <code class="literal">MAX(b)</code> evaluates to
+      <code class="literal">Long.MAX_VALUE</code>.</p>
+<p>There is no built-in limit on the size of intermediate integral
+      values in expressions. As a result, you should check for the type of the
+      <code class="classname">ResultSet</code> column and choose an appropriate
+      <code class="methodname">getXXXX()</code> method to retrieve it. Alternatively,
+      you can use the <code class="methodname">getObject()</code> method, then cast
+      the result to <code class="classname">java.lang.Number</code> and use the
+      <code class="methodname">intValue()</code> or
+      <code class="methodname">longValue()</code> methods on the result.</p>
+<p>When the result of an expression is stored in a column of a
+      database table, it has to fit in the target column, otherwise an error
+      is returned. For example when <code class="literal">1234567890123456789012 /
+      12345687901234567890</code> is evaluated, the result can be stored in
+      any integral type column, even a TINYINT column, as it is a small
+      value.</p>
+<p>In SQL Statements, an integer literal is treated as INTEGER,
+      unless its value does not fit. In this case it is treated as BIGINT or
+      DECIMAL, depending on the value.</p>
+<p>Depending on the types of the operands, the result of the
+      operations is returned in a JDBC <code class="classname">ResultSet</code> in any
+      of related Java types: <code class="classname">Integer</code>,
+      <code class="classname">Long</code> or <code class="classname">BigDecimal</code>. The
+      <code class="methodname">ResultSet.getXXXX()</code> methods can be used to
+      retrieve the values so long as the returned value can be represented by
+      the resulting type. This type is deterministically based on the query,
+      not on the actual rows returned.</p>
+<p>
+<span class="bold"><strong>Other Numeric Types</strong></span>
+</p>
+<p>In SQL statements, number literals with a decimal point are
+      treated as DECIMAL unless they are written with an exponent. Thus
+      <code class="literal">0.2</code> is considered a DECIMAL value but
+      <code class="literal">0.2E0</code> is considered a DOUBLE value.</p>
+<p>When an approximate numeric type, REAL, FLOAT or DOUBLE (all
+      synonymous) is part of an expression involving different numeric types,
+      the type of the result is DOUBLE. DECIMAL values can be converted to
+      DOUBLE unless they are beyond the <code class="literal">Double.MIN_VALUE -
+      Double.MAX_VALUE</code> range. For example, A * B, A / B, A + B, etc.
+      will return a DOUBLE value if either A or B is a DOUBLE.</p>
+<p>Otherwise, when no DOUBLE value exists, if a DECIMAL or NUMERIC
+      value is part an expression, the type of the result is DECIMAL or
+      NUMERIC. Similar to integral values, when the result of an expression is
+      assigned to a table column, the value has to fit in the target column,
+      otherwise an error is returned. This means a small, 4 digit value of
+      DECIMAL type can be assigned to a column of SMALLINT or INTEGER, but a
+      value with 15 digits cannot.</p>
+<p>When a DECIMAL values is multiplied by a DECIMAL or integral type,
+      the resulting scale is the sum of the scales of the two terms. When they
+      are divided, the result is a value with a scale (number of digits to the
+      right of the decimal point) equal to the larger of the scales of the two
+      terms. The precision for both operations is calculated (usually
+      increased) to allow all possible results.</p>
+<p>The distinction between DOUBLE and DECIMAL is important when a
+      division takes place. For example, <code class="literal">10.0/8.0</code> (DECIMAL)
+      equals <code class="literal">1.2</code> but <code class="literal">10.0E0/8.0E0</code>
+      (DOUBLE) equals <code class="literal">1.25</code>. Without division operations,
+      DECIMAL values represent exact arithmetic.</p>
+<p>REAL, FLOAT and DOUBLE values are all stored in the database as
+      <code class="classname">java.lang.Double</code> objects. Special values such as
+      NaN and +-Infinity are also stored and supported. These values can be
+      submitted to the database via JDBC
+      <code class="classname">PreparedStatement</code> methods and are returned in
+      <code class="classname">ResultSet</code> objects. The result can be retrieved
+      from a <code class="classname">ResultSet</code> in the required type so long as
+      it can be represented. When
+      <code class="methodname">PreparedStatement.setDouble()</code> or
+      <code class="methodname">setFloat()</code> is used, the value is treated as a
+      DOUBLE automatically.</p>
+<p>In short,</p>
+<p>
+<code class="literal">&lt;numeric type&gt; ::= &lt;exact numeric type&gt; |
+      &lt;approximate numeric type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;exact numeric type&gt; ::= NUMERIC [ &lt;left
+      paren&gt; &lt;precision&gt; [ &lt;comma&gt; &lt;scale&gt; ] &lt;right
+      paren&gt; ] | { DECIMAL | DEC } [ &lt;left paren&gt; &lt;precision&gt; [
+      &lt;comma&gt; &lt;scale&gt; ] &lt;right paren&gt; ] | SMALLINT | INTEGER
+      | INT | BIGINT</code>
+</p>
+<p>
+<code class="literal">&lt;approximate numeric type&gt; ::= FLOAT [ &lt;left
+      paren&gt; &lt;precision&gt; &lt;right paren&gt; ] | REAL | DOUBLE
+      PRECISION</code>
+</p>
+<p>
+<code class="literal">&lt;precision&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;scale&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10482"></a>Boolean Type</h3>
+</div>
+</div>
+</div>
+<a name="N10485" class="indexterm"></a>
+<p>The BOOLEAN type conforms to the SQL Standard and represents the
+      values <code class="literal">TRUE</code>, <code class="literal">FALSE</code> and
+      <code class="literal">UNKNOWN</code>. This type of column can be initialised with
+      Java boolean values, or with <code class="literal">NULL</code> for the
+      <code class="literal">UNKNOWN</code> value.</p>
+<p>The three-value logic is sometimes misunderstood. For example, x
+      IN (1, 2, NULL) does not return true if x is NULL.</p>
+<p>In previous versions of HyperSQL, BIT was simply an alias for
+      BOOLEAN. In version 2.0, BIT is a single-bit bit map.</p>
+<p>
+<code class="literal">&lt;boolean type&gt; ::= BOOLEAN</code>
+</p>
+<p>The SQL Standard does not support type conversion to BOOLEAN apart
+      from character strings that consists of boolean literals. Because the
+      BOOLEAN type is relatively new to the Standard, several database
+      products used other types to represent boolean values. For improved
+      compatibility, HyperSQL allows some type conversions to boolean.</p>
+<p>Values of BIT and BIT VARYING types with length 1 can be converted
+      to BOOLEAN. If the bit is set, the result of conversion is the TRUE
+      value, otherwise it is FALSE.</p>
+<p>Values of TINYINT, SMALLINT, INTEGER and BIGINT types can be
+      converted to BOOLEAN. If the value is zero, the result is the FALSE
+      value, otherwise it is TRUE.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N104A8"></a>Character String Types</h3>
+</div>
+</div>
+</div>
+<a name="N104AB" class="indexterm"></a>
+<p>The CHARACTER, CHARACTER VARYING and CLOB types are the SQL
+      Standard character string types. CHAR, VARCHAR and CHARACTER LARGE
+      OBJECT are synonyms for these types. HyperSQL also supports LONGVARCHAR
+      as a synonym for VARCHAR. If LONGVARCHAR is used without a length, then
+      a length of 1M is assigned.</p>
+<p>HyperSQL's default character set is Unicode, therefore all
+      possible character strings can be represented by these types.</p>
+<p>The SQL Standard behaviour of the CHARACTER type is a remnant of
+      legacy systems in which character strings are padded with spaces to fill
+      a fixed width. These spaces are sometimes significant while in other
+      cases they are silently discarded. It would be best to avoid the
+      CHARACTER type altogether. With the rest of the types, the strings are
+      not padded when assigned to columns or variables of the given type. The
+      trailing spaces are still considered discardable for all character
+      types. Therefore if a string with trailing spaces is too long to assign
+      to a column or variable of a given length, the spaces beyond the type
+      length are discarded and the assignment succeeds (provided all the
+      characters beyond the type length are spaces).</p>
+<p>The VARCHAR and CLOB types have length limits, but the strings are
+      not padded by the system. Note that if you use a large length for a
+      VARCHAR or CLOB type, no extra space is used in the database. The space
+      used for each stored item is proportional to its actual length.</p>
+<p>If CHARACTER is used without specifying the length, the length
+      defaults to 1. For the CLOB type, the length limit can be defined in
+      units of kilobyte (K, 1024), megabyte (M, 1024 * 1024) or gigabyte (G,
+      1024 * 1024 * 1024), using the <code class="literal">&lt;multiplier&gt;</code>. If
+      CLOB is used without specifying the length, the length defaults to
+      1M.</p>
+<p>
+<code class="literal">&lt;character string type&gt; ::= { CHARACTER | CHAR }
+      [ &lt;left paren&gt; &lt;character length&gt; &lt;right paren&gt; ] | {
+      CHARACTER VARYING | CHAR VARYING | VARCHAR } &lt;left paren&gt;
+      &lt;character length&gt; &lt;right paren&gt; | LONGVARCHAR [ &lt;left
+      paren&gt; &lt;character length&gt; &lt;right paren&gt; ] | &lt;character
+      large object type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;character large object type&gt; ::= { CHARACTER
+      LARGE OBJECT | CHAR LARGE OBJECT | CLOB } [ &lt;left paren&gt;
+      &lt;character large object length&gt; &lt;right paren&gt;
+      ]</code>
+</p>
+<p>
+<code class="literal">&lt;character length&gt; ::= &lt;unsigned integer&gt;
+      [ &lt;char length units&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;large object length&gt; ::= &lt;length&gt; [
+      &lt;multiplier&gt; ] | &lt;large object length
+      token&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;character large object length&gt; ::= &lt;large
+      object length&gt; [ &lt;char length units&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;large object length token&gt; ::= &lt;digit&gt;...
+      &lt;multiplier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;multiplier&gt; ::= K | M | G </code>
+</p>
+<p>
+<code class="literal">&lt;char length units&gt; ::= CHARACTERS |
+      OCTETS</code>
+</p>
+<pre class="programlisting">CHAR(10)
+CHARACTER(10)
+VARCHAR(2)
+CHAR VARYING(2)
+CLOB(1000)
+CLOB(30K)
+CHARACTER LARGE OBJECT(1M)
+LONGVARCHAR
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N104D7"></a>Binary String Types</h3>
+</div>
+</div>
+</div>
+<a name="N104DA" class="indexterm"></a>
+<p>The BINARY, BINARY VARYING and BLOB types are the SQL Standard
+      binary string types. VARBINARY and BINARY LARGE OBJECT are synonyms for
+      BINARY VARYING and BLOB types. HyperSQL also supports LONGVARBINARY as a
+      synonym for VARBINARY.</p>
+<p>Binary string types are used in a similar way to character string
+      types. There are several built-in functions that are overloaded to
+      support character, binary and bit strings.</p>
+<p>The BINARY type represents a fixed width-string. Each shorter
+      string is padded with zeros to fill the fixed width. Similar to the
+      CHARACTER type, the trailing zeros in the BINARY string are simply
+      discarded in some operations. For the same reason, it is best to avoid
+      this particular type.</p>
+<p>If BINARY is used without specifying the length, the length
+      defaults to 1. For the BLOB type, the length limit can be defined in
+      units of kilobyte (K, 1024), megabyte (M, 1024 * 1024) or gigabyte (G,
+      1024 * 1024 * 1024), using the <code class="literal">&lt;multiplier&gt;</code>. If
+      BLOB is used without specifying the length, the length defaults to
+      1M.</p>
+<p>
+<code class="literal">&lt;binary string type&gt; ::= BINARY [ &lt;left
+      paren&gt; &lt;length&gt; &lt;right paren&gt; ] | { BINARY VARYING |
+      VARBINARY } &lt;left paren&gt; &lt;length&gt; &lt;right paren&gt; |
+      LONGVARBINARY [ &lt;left paren&gt; &lt;length&gt; &lt;right paren&gt; ]
+      | &lt;binary large object string type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;binary large object string type&gt; ::= { BINARY
+      LARGE OBJECT | BLOB } [ &lt;left paren&gt; &lt;large object length&gt;
+      &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;length&gt; ::= &lt;unsigned
+      integer&gt;</code>
+</p>
+<pre class="programlisting">BINARY(10)
+VARBINARY(2)
+BINARY VARYING(2)
+BLOB(1000)
+BLOB(30K)
+BINARY LARGE OBJECT(1M)
+LONGVARBINARY
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N104F5"></a>Bit String Types</h3>
+</div>
+</div>
+</div>
+<a name="N104F8" class="indexterm"></a>
+<p>The BIT and BIT VARYING types are the supported bit string types.
+      These types were defined by SQL:1999 but were later removed from the
+      Standard. Bit types represent bit maps of given lengths. Each bit is 0
+      or 1. The BIT type represents a fixed width-string. Each shorter string
+      is padded with zeros to fill the fixed with. If BIT is used without
+      specifying the length, the length defaults to 1. The BIT VARYING type
+      has a maximum width and shorter strings are not padded.</p>
+<p>Before the introduction of the BOOLEAN type to the SQL Standard, a
+      sigle-bit string of the type BIT(1) was commonly used. For compatibility
+      with other products that do not conform to, or extend, the SQL Standard,
+      HyperSQL allows values of BIT and BIT VARYING types with length 1 to be
+      converted to and from the BOOLEAN type. BOOLEAN TRUE is considered equal
+      to B'1', BOOLEAN FALSE is considered equal to B'0'.</p>
+<p>For the same reason, numeric values can be assigned to columns and
+      variables of the type BIT(1). For assignment, the numeric value zero is
+      converted to B'0', while all other values are converted to B'1'. For
+      comparison, numeric values 1 is considered equal to B'1' and numeric
+      value zero is considered equal to B'0'.</p>
+<p>It is not allowed to perform other arithmetic or boolean
+      operations involving BIT(1) and BIT VARYING(1). The kid of operations
+      allowed on bit strings are analogous to those allowed on BINARY and
+      CHARACTER strings. Several built-in functions support all three types of
+      string.</p>
+<p>
+<code class="literal">&lt;bit string type&gt; ::= BIT [ &lt;left paren&gt;
+      &lt;length&gt; &lt;right paren&gt; ] | BIT VARYING &lt;left paren&gt;
+      &lt;length&gt; &lt;right paren&gt;</code>
+</p>
+<pre class="programlisting">BIT
+BIT(10)
+BIT VARYING(2)
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1050A"></a>Storage and Handling of Java Objects</h3>
+</div>
+</div>
+</div>
+<a name="N1050D" class="indexterm"></a>
+<p>Any serializable JAVA Object can be inserted directly into a
+      column of type OTHER using any variation of
+      <code class="methodname">PreparedStatement.setObject()</code> methods.</p>
+<p>For comparison purposes and in indexes, any two Java Objects are
+      considered equal unless one of them is NULL. You cannot search for a
+      specific object or perform a join on a column of type OTHER.</p>
+<p>Please note that HSQLDB is not an object-relational database. Java
+      Objects can simply be stored internally and no operations should be
+      performed on them other than assignment between columns of type OTHER or
+      tests for NULL. Tests such as <code class="literal">WHERE object1 = object2
+      </code>do not mean what you might expect, as any non-null object
+      would satisfy such a tests. But <code class="literal">WHERE object1 IS NOT
+      NULL</code> is perfectly acceptable.</p>
+<p>The engine does not allow normal column values to be assigned to
+      Java Object columns (for example, assigning an INTEGER or STRING to such
+      a column with an SQL statement such as <code class="literal">UPDATE mytable SET
+      objectcol = intcol WHERE ...</code>).</p>
+<p>
+<code class="literal">&lt;java object type&gt; ::= OTHER</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10529"></a>Type Length, Precision and Scale</h3>
+</div>
+</div>
+</div>
+<p>In older version of HyperSQL, all table column type definitions
+      with a column length, precision or scale qualifier were accepted and
+      ignored. HSQLDB 1.8 enforced correctness but included an option to
+      enforce the length, precision or scale.</p>
+<p>In HyperSQL 2.0, length, precision and scale qualifiers are always
+      enforced. For backward compatibility, when older databases which had the
+      property hsqldb.enforce_strict_size=false are converted to version 2.0,
+      this property is retained. However, this is a temporary measure. You
+      should test your application to ensure the length, precision and scale
+      that is used for column definitions is appropriate for the application
+      data. You can test with the default database setting, which enforces the
+      sizes.</p>
+<p>String types, including all BIT, BINARY and CHAR string types plus
+      CLOB and BLOB, are generally defined with a length. If no length is
+      specified for BIT, BINARY and CHAR, the default length is 1. For CLOB
+      and BLOB an implementation defined length of 1M is used.</p>
+<p>TIME and TIMESTAMP types can be defined with a fractional second
+      precision between 0 and 9. INTERVAL type definition may have precision
+      and, in some cases, fraction second precision. DECIMAL and NUMERIC types
+      may be defined with precision and scale. For all of these types a
+      default precision or scale value is used if one is not specified. The
+      default scale is 0. The default fractional precision for TIME is 0,
+      while it is 6 for TIMESTAMP.</p>
+<p>Values can be converted from one type to another in two different
+      ways: by using explicit CAST expression or by implicit conversion used
+      in assignment, comparison and aggregation.</p>
+<p>String values cannot be assigned to VARCHAR columns if they are
+      longer than the defined type length. For CHARACTER columns, a long
+      string can be assigned (with truncation) only if all the characters
+      after the length are spaces. Shorter strings are padded with the space
+      character when inserted into a CHARACTER column. Similar rules are
+      applied to VARBINARY and BINARY columns. For BINARY columns, the padding
+      and truncation rules are applied with zero bytes, instead of
+      spaces.</p>
+<p>Explicit CAST of a value to a CHARACTER or VARCHAR type will
+      result in forced truncation or padding. So a test such as <code class="literal">CAST
+      (mycol AS VARCHAR(2)) = 'xy'</code> will find the values beginning
+      with 'xy'. This is the equivalent of <code class="literal">SUBSTRING(mycol FROM 1 FOR
+      2)= 'xy'</code>.</p>
+<p>For all numeric types, the rules of explicit cast and implicit
+      conversion are the same. If cast or conversion causes any digits to be
+      lost from the fractional part, it can take place. If the non-fractional
+      part of the value cannot be represented in the new type, cast or
+      conversion cannot take place and will result in a data exception.</p>
+<p>There are special rules for DATE, TIME, TIMESTAMP and INTERVAL
+      casts and conversions.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10544"></a>Datetime types</h2>
+</div>
+</div>
+</div>
+<p>HSQLDB fully supports datetime and interval types and operations,
+    including all relevant optional features, as specified by the SQL Standard
+    since SQL-92. The two groups of types are complementary.</p>
+<a name="N10549" class="indexterm"></a>
+<p>The DATE type represents a calendar date with YEAR, MONTH and DAY
+    fields.</p>
+<p>The TIME type represents time of day with HOUR, MINUTE and SECOND
+    fields, plus an optional SECOND FRACTION field.</p>
+<p>The TIMESTAMP type represents the combination of DATE and TIME
+    types.</p>
+<p>TIME and TIMESTAMP types can include WITH TIME ZONE or WITHOUT TIME
+    ZONE (the default) qualifiers. They can have fractional second parts. For
+    example, TIME(6) has six fractional digits for the second field.</p>
+<p>If fractional second precision is not specified, it defaults to 0
+    for TIME and to 6 for TIMESTAMP.</p>
+<p>
+<code class="literal">&lt;datetime type&gt; ::= DATE | TIME [ &lt;left
+    paren&gt; &lt;time precision&gt; &lt;right paren&gt; ] [ &lt;with or
+    without time zone&gt; ] | TIMESTAMP [ &lt;left paren&gt; &lt;timestamp
+    precision&gt; &lt;right paren&gt; ] [ &lt;with or without time zone&gt;
+    ]</code>
+</p>
+<p>
+<code class="literal">&lt;with or without time zone&gt; ::= WITH TIME ZONE |
+    WITHOUT TIME ZONE</code>
+</p>
+<p>
+<code class="literal">&lt;time precision&gt; ::= &lt;time fractional seconds
+    precision&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;timestamp precision&gt; ::= &lt;time fractional
+    seconds precision&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;time fractional seconds precision&gt; ::=
+    &lt;unsigned integer&gt;</code>
+</p>
+<pre class="programlisting">DATE
+TIME(6)
+TIMESTAMP(2) WITH TIME ZONE
+</pre>
+<p>Examples of the string literals used to represent date time values,
+    some with time zone, some without, are below:</p>
+<pre class="programlisting">DATE '2008-08-22'
+TIMESTAMP '2008-08-08 20:08:08'
+TIMESTAMP '2008-08-08 20:08:08+8:00' /* Beijing */
+TIME '20:08:08.034900'
+TIME '20:08:08.034900-8:00' /* US Pacific */</pre>
+<a name="N1056D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Time Zone</strong></span>
+</p>
+<p>DATE values do not take time zones. For example United Nations
+    designates 5 June as World Environment Day, which was observed on DATE
+    '2008-06-05' in different time zones.</p>
+<p>TIME and TIMESTAMP values without time zone, usually have a context
+    that indicates some local time zone. For example, a database for college
+    course timetables usually stores class dates and times without time zones.
+    This works because the location of the college is fixed and the time zone
+    displacement is the same for all the values. Even when the events take
+    place in different time zones, for example international flight times, it
+    is possible to store all the datetime information as references to a
+    single time zone, usually GMT. For some databases it may be useful to
+    store the time zone displacement together with each datetime value. SQL&rsquo;s
+    TIME WITH TIME ZONE and TIMESTAMP WITH TIME ZONE values include a time
+    zone displacement value.</p>
+<p>The time zone displacement is of the type INTERVAL HOUR TO MINUTE.
+    This data type is described in the next section. The legal values are
+    between '&ndash;14:00' and &nbsp; '+14:00'.</p>
+<a name="N1057C" class="indexterm"></a>
+<p>
+<span class="bold"><strong>Operations on Datetime
+    Types</strong></span>
+</p>
+<p>The expression <code class="literal">&lt;datetime expression&gt; AT TIME ZONE
+    &lt;time displacement&gt;</code> evaluates to a datetime value
+    representing exactly the same point of time in the specified
+    <code class="literal">&lt;time displacement&gt;</code>. The expression, <code class="literal">AT
+    LOCAL</code> is equivalent to <code class="literal">AT TIME ZONE &lt;local time
+    displacement&gt;</code>. If <code class="literal">AT TIME ZONE</code> is used
+    with a datetime operand of type WITHOUT TIME ZONE, the operand is first
+    converted to a value of type WITH TIME ZONE at the session&rsquo;s time
+    displacement, then the specified time zone displacement is set for the
+    value. Therefore, in these cases, the final value depends on the time zone
+    of the session in which the statement was used.</p>
+<p>AT TIME ZONE, modifies the field values of the datetime operand.
+    This is done by the following procedure:</p>
+<div class="orderedlist">
+<ol type="1">
+<li>
+<p>determine the corresponding datetime at UTC.</p>
+</li>
+<li>
+<p>find the datetime value at the given time zone that corresponds
+        with the UTC value from step 1.</p>
+</li>
+</ol>
+</div>
+<p>Example a:</p>
+<pre class="programlisting">TIME '12:00:00' AT TIME ZONE INTERVAL '1:00' HOUR TO MINUTE
+</pre>
+<p>If the session&rsquo;s time zone displacement is -'8:00', then in step 1,
+    TIME '12:00:00' is converted to UTC, which is TIME '20:00:00+0:00'. In
+    step 2, this value is expressed as TIME '21:00:00+1:00'.</p>
+<p>Example b:</p>
+<pre class="programlisting">TIME '12:00:00-5:00' AT TIME ZONE INTERVAL '1:00' HOUR TO MINUTE
+</pre>
+<p>Because the operand has a time zone, the result is independent of
+    the session &nbsp;time zone displacement. Step 1 results in TIME
+    '17:00:00+0:00', and step 2 results in TIME '18:00:00+1:00'</p>
+<p>Note that the operand is not limited to datetime literals used in
+    these examples. Any valid expression that evaluates to a datetime value
+    can be the operand.</p>
+<p>
+<span class="bold"><strong>Type Conversion</strong></span>
+</p>
+<p>CAST is used to for all other conversions. Examples:</p>
+<pre class="programlisting">CAST (&lt;value&gt; AS TIME WITHOUT TIME ZONE)
+CAST (&lt;value&gt; AS TIME WITH TIME ZONE)</pre>
+<p>In the first example, if <code class="literal">&lt;value&gt;</code> has a time
+    zone component, it is simply dropped. For example TIME '12:00:00-5:00' is
+    converted to TIME '12:00:00'</p>
+<p>In the second example, if <code class="literal">&lt;value&gt;</code> has no
+    time zone component, the current time zone displacement of the session is
+    added. For example TIME '12:00:00' is converted to TIME '12:00:00-8:00'
+    when the session time zone displacement is '-8:00'.</p>
+<p>Conversion between DATE and TIMESTAMP is performed by removing the
+    TIME component of a TIMESTAMP value or by setting the hour, minute and
+    second fields to zero. TIMESTAMP '2008-08-08 20:08:08+8:00' becomes DATE
+    '2008-08-08', while DATE '2008-08-22' becomes TIMESTAMP '2008-08-22
+    00:00:00'.</p>
+<p>Conversion between TIME and TIMESTAMP is performed by removing the
+    DATE field values of a TIMESTAMP value or by appending the fields of the
+    TIME value to the fields of the current session date value.</p>
+<p>
+<span class="bold"><strong>Assignment</strong></span>
+</p>
+<p>When a value is assigned to a datetime target, e.g., a value is used
+    to update a row of a table, the type of the value must be the same as the
+    target, but the WITH TIME ZONE or WITHOUT TIME ZONE characteristics can be
+    different. If the types are not the same, an explicit CAST must be used to
+    convert the value into the target type.</p>
+<p>
+<span class="bold"><strong>Comparison</strong></span>
+</p>
+<p>When values WITH TIME ZONE are compared, they are converted to UTC
+    values before comparison. If a value WITH TIME ZONE is compared to another
+    WITHOUT TIME ZONE, then the WITH TIME ZONE value is converted to AT LOCAL,
+    then converted to WITHOUT TIME ZONE before comparison.</p>
+<p>It is not recommended to design applications that rely on
+    comparisons and conversions between TIME values WITH TIME ZONE. The
+    conversions may involve normalisation of the time value, resulting in
+    unexpected results. For example, the expression: BETWEEN(TIME
+    '12:00:00-8:00', TIME '22:00:00-8:00') is converted to BETWEEN(TIME
+    '20:00:00+0:00', TIME '06:00:00+0:00') when it is evaluated in the UTC
+    zone, which is always FALSE.</p>
+<p>
+<span class="bold"><strong>Functions</strong></span>
+</p>
+<p>Several functions return the current session timestamp in different
+    datetime types:</p>
+<div class="informaltable">
+<table cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>CURRENT_DATE</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>DATE</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>CURRENT_TIME</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>TIME WITH TIME ZONE</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>CURRENT_TIMESTAMP</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>TIMESTAMP WITH TIME ZONE</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>LOCALTIME</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>TIMESTAMP WITHOUT TIME ZONE</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; ">
+<p>LOCALTIMESTAMP</p>
+</td><td style="">
+<p>TIMESTAMP WITHOUT TIME ZONE</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+<span class="bold"><strong>Session Time Zone
+    Displacement</strong></span>
+</p>
+<p>When an SQL session is started (with a JDBC connection) the local
+    time zone of the client JVM (including any seasonal time adjustments such
+    as daylight saving time) is used as the session time zone displacement.
+    Note that the SQL session time displacement is not changed when a seasonal
+    time adjustment takes place while the session is open. To change the SQL
+    session time zone displacement use the following commands:</p>
+<p>
+<code class="literal">SET TIME ZONE &lt;time
+    displacement&gt;</code>
+</p>
+<p>
+<code class="literal">SET TIME ZONE LOCAL</code>
+</p>
+<p>The first command sets the displacement to the given value. The
+    second command restores the original, real time zone displacement of the
+    session.</p>
+<p>
+<span class="bold"><strong>Datetime Values and
+    Java</strong></span>
+</p>
+<p>When datetime values are sent to the database using the
+    <code class="classname">PreparedStatement</code> or
+    <code class="classname">CallableStatement</code> interfaces, the Java object is
+    converted to the type of the prepared or callable statement parameter.
+    This type may be DATE, TIME, or TIMESTAMP (with or without time zone). The
+    time zone displacement is the time zone of the JDBC session.</p>
+<p>When datetime values are retrieved from the database using the
+    <code class="literal">ResultSet</code> interface, there are two representations. The
+    <code class="methodname">getString(&hellip;)</code> methods of the
+    <code class="classname">ResultSet</code> interface, return an exact representation
+    of the value in the SQL type as it is stored in the database. This
+    includes the correct number of digits for the fractional second field, and
+    for values with time zone displacement, the time zone displacement.
+    Therefore if TIME '12:00:00' is stored in the database, all users in
+    different time zones will get '12:00:00' when they retrieve the value as a
+    string. The <code class="methodname">getTime(&hellip;)</code> and
+    <code class="methodname">getTimestamp(&hellip;)</code> methods of the
+    <code class="classname">ResultSet</code> interface return Java objects that are
+    corrected for the session time zone. The UTC millisecond value contained
+    the <code class="classname">java.sql.Time</code> or
+    <code class="classname">java.sql.Timestamp</code> objects will be adjusted to the
+    time zone of the session, therefore the
+    <code class="methodname">toString()</code> method of these objects return the
+    same values in different time zones.</p>
+<p>If you want to store and retrieve UTC values that are independent of
+    any session's time zone, you can use a TIMESTAMP WITH TIME ZONE column.
+    The setTime(...) and setTimestamp(...) methods of the PreparedStatement
+    interface which have a Calendar parameter can be used to assign the
+    values. The time zone of the given Calendar argument is used as the time
+    zone. Conversely, the getTime(...) and getTimestamp(...) methods of the
+    ResultSet interface which have a Calendar parameter can be used with a
+    Calendar argument to retrieve the values.</p>
+<p>JDBC has an unfortunate limitation and does not include type codes
+    for SQL datetime types that have a TIME ZONE property. Therefore, for
+    compatibility with database tools that are limited to the JDBC type codes,
+    HyperSQL reports these types by default as datetime types without TIME
+    ZONE. You can use the URL property
+    <code class="literal">hsqldb.translate_dti_types=false</code> to override the
+    default behaviour.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1063D"></a>Interval Types</h2>
+</div>
+</div>
+</div>
+<a name="N10640" class="indexterm"></a>
+<p>Interval types are used to represent differences between date time
+    values. The difference between two date time values can be measured in
+    seconds or in months. For measurements in months, the units YEAR and MONTH
+    are available, while for measurements in seconds, the units DAY, HOUR,
+    MINUTE, SECOND are available. The units can be used individually, or as a
+    range. An interval type can specify the precision of the most significant
+    field and the second fraction digits of the SECOND field (if it has a
+    SECOND field). The default precision is 2. The default second precision is
+    0.</p>
+<p>
+<code class="literal">&lt;interval type&gt; ::= INTERVAL &lt;interval
+    qualifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval qualifier&gt; ::= &lt;start field&gt; TO
+    &lt;end field&gt; | &lt;single datetime field&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;start field&gt; ::= &lt;non-second primary datetime
+    field&gt; [ &lt;left paren&gt; &lt;interval leading field precision&gt;
+    &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;end field&gt; ::= &lt;non-second primary datetime
+    field&gt; | SECOND [ &lt;left paren&gt; &lt;interval fractional seconds
+    precision&gt; &lt;right paren&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;single datetime field&gt; ::= &lt;non-second primary
+    datetime field&gt; [ &lt;left paren&gt; &lt;interval leading field
+    precision&gt; &lt;right paren&gt; ] | SECOND [ &lt;left paren&gt;
+    &lt;interval leading field precision&gt; [ &lt;comma&gt; &lt;interval
+    fractional seconds precision&gt; ] &lt;right paren&gt;
+    ]</code>
+</p>
+<p>
+<code class="literal">&lt;primary datetime field&gt; ::= &lt;non-second
+    primary datetime field&gt; | SECOND</code>
+</p>
+<p>
+<code class="literal">&lt;non-second primary datetime field&gt; ::= YEAR |
+    MONTH | DAY | HOUR | MINUTE</code>
+</p>
+<p>
+<code class="literal">&lt;interval fractional seconds precision&gt; ::=
+    &lt;unsigned integer&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;interval leading field precision&gt; ::=
+    &lt;unsigned integer&gt;</code>
+</p>
+<p>Examples of INTERVAL type definition:</p>
+<pre class="programlisting">INTERVAL YEAR TO MONTH
+INTERVAL YEAR(3)
+INTERVAL DAY(4) TO HOUR
+INTERVAL MINUTE(4) TO SECOND(6)
+INTERVAL SECOND(4,6)
+</pre>
+<p>The word INTERVAL indicates the general type name. The rest of the
+    definition is called an <code class="literal">&lt;interval qualifier&gt;</code>.
+    This designation is important, as in most expressions
+    <code class="literal">&lt;interval qualifier&gt;</code> is used without the word
+    INTERVAL.</p>
+<p>
+<span class="bold"><strong>Interval Values</strong></span>
+</p>
+<p>An interval value can be negative, positive or zero. An interval
+    type has all the datetime fields in the specified range. These fields are
+    similar to those in the TIMESTAMP type. The differences are as
+    follows:</p>
+<p>The first field of an interval value can hold any numeric value up
+    to the specified precision. For example, the hour field in HOUR(2) TO
+    SECOND can hold values above 23 (up to 99). The year and month fields can
+    hold zero (unlike a TIMESTAMP value) and the maximum value of a month
+    field that is not the most significant field, is 11.</p>
+<p>The standard function <code class="literal">ABS(&lt;interval value
+    expression&gt;)</code> can be used to convert a negative interval value
+    to a positive one.</p>
+<p>The literal representation of interval values consists of the type
+    definition, with a string representing the interval value inserted after
+    the word INTERVAL. Some examples of interval literal below:</p>
+<pre class="programlisting">INTERVAL '145 23:12:19.345' DAY(3) TO SECOND(3)
+INTERVAL '3503:12:19.345' HOUR TO SECOND(3) /* equal to the first value */
+INTERVAL '19.345' SECOND(4,3) /* maximum number of digits for the second value is 4, and each value is expressed with three fraction digits. */
+INTERVAL '-23-10' YEAR(2) TO MONTH
+</pre>
+<p>Interval values of the types that are based on seconds can be cast
+    into one another. Similarly those that are based on months can be cast
+    into one another. It is not possible to cast or convert a value based on
+    seconds to one based on months, or vice versa.</p>
+<p>When a cast is performed to a type with a smaller least-significant
+    field, nothing is lost from the interval value. Otherwise, the values for
+    the missing least-significant fields are discarded. Examples:</p>
+<pre class="programlisting">CAST ( INTERVAL '145 23:12:19' DAY TO SECOND AS INTERVAL DAY TO HOUR ) = INTERVAL '145 23' DAY TO HOUR
+CAST(INTERVAL '145 23' DAY TO HOUR AS INTERVAL DAY TO SECOND) = INTERVAL '145 23:00:00' DAY TO SECOND
+</pre>
+<p>A numeric value can be cast to an interval type. In this case the
+    numeric value is first converted to a single-field INTERVAL type with the
+    same field as the least significant field of the target interval type.
+    This value is then converted to the target interval type For example CAST(
+    22 AS INTERVAL YEAR TO MONTH) evaluates to INTERVAL '22' MONTH and then
+    INTERVAL '1 10' YEAR TO MONTH. Note that SQL Standard only supports casts
+    to single-field INTERVAL types, while HyperSQL allows casting to
+    multi-field types as well.</p>
+<p>An interval value can be cast to a numeric type. In this case the
+    interval value is first converted to a single-field INTERVAL type with the
+    same field as the least significant filed of the interval value. The value
+    is then converted to the target type. For example CAST (INTERVAL '1-11'
+    YEAR TO MONTH AS INT) evaluates to INTERVAL '23' MONTH, and then
+    23.</p>
+<p>An interval value can be cast into a character type, which results
+    in an INTERVAL literal. A character value can be cast into an INTERVAL
+    type so long as it is a string with a format compatible with an INTERVAL
+    literal.</p>
+<p>Two interval values can be added or subtracted so long as the types
+    of both are based on the same field, i.e., both are based on MONTH or
+    SECOND. The values are both converted to a single-field interval type with
+    same field as the least-significant field between the two types. After
+    addition or subtraction, the result is converted to an interval type that
+    contains all the fields of the two original types.</p>
+<p>An interval value can be multiplied or divided by a numeric value.
+    Again, the value is converted to a numeric, which is then multiplied or
+    divided, before converting back to the original interval type.</p>
+<p>An interval value is negated by simply prefixing with the minus
+    sign.</p>
+<p>Interval values used in expressions are either typed values,
+    including interval literals, or are interval casts. The expression:
+    <code class="literal">&lt;expression&gt; &lt;interval qualifier&gt;</code> is a cast
+    of the result of the <code class="literal">&lt;expression&gt;</code> into the
+    INTERVAL type specified by the <code class="literal">&lt;interval qualifier&gt;. The
+    cast can be formed by adding the keywords and parentheses as follows: CAST
+    ( &lt;expression&gt; AS INTERVAL &lt;interval qualifier&gt;
+    ).</code>
+</p>
+<p>
+<code class="literal">The examples below feature different forms of expression
+    that represent an interval value, which is then added to the given date
+    literal.</code>
+</p>
+<pre class="programlisting">DATE '2000-01-01' + INTERVAL '1-10' YEAR TO MONTH /* interval literal */
+DATE '2000-01-01' + '1-10' YEAR TO MONTH /* the string '1-10' is cast into INTERVAL YEAR TO MONTH */
+DATE '2000-01-01' + 22 MONTH /* the integer 22 is cast into INTERVAL MONTH, same value as above */
+DATE '2000-01-01' - 22 DAY /* the integer 22 is cast into INTERVAL DAY */
+DATE '2000-01-01' + COL2 /* the type of COL2 must be an INTERVAL type */
+DATE '2000-01-01' + COL2 MONTH /* COL2 may be a number, it is cast into a MONTH interval */
+</pre>
+<p>
+<span class="bold"><strong>Datetime and Interval
+    Operations</strong></span>
+</p>
+<p>An interval can be added to or subtracted from a datetime value so
+    long as they have some fields in common. For example, an INTERVAL MONTH
+    cannot be added to a TIME value, while an INTERVAL HOUR TO SECOND can. The
+    interval is first converted to a numeric value, then the value is added
+    to, or subtracted from, the corresponding field of the datetime
+    value.</p>
+<p>If the result of addition or subtraction is beyond the permissible
+    range for the field, the field value is normalised and carried over to the
+    next significant field until all the fields are normalised. For example,
+    adding 20 minutes to TIME '23:50:10' will result successively in
+    '23:70:10', '24:10:10' and finally TIME '00:10:10'. Subtracting 20 minutes
+    from the result is performed as follows: '00:-10:10', '-1:50:10', finally
+    TIME '23:50:10'. Note that if DATE or TIMESTAMP normalisation results in
+    the YEAR field value out of the range (1,1000), then an exception
+    condition is raised.</p>
+<p>If an interval value based on MONTH is added to, or subtracted from
+    a DATE or TIMESTAMP value, the result may have an invalid day (30 or 31)
+    for the given result month. In this case an exception condition is
+    raised.</p>
+<p>The result of subtraction of two datetime expressions is an interval
+    value. The two datetime expressions must be of the same type. The type of
+    the interval value must be specified in the expression, using only the
+    interval field names. The two datetime expressions are enclosed in
+    parentheses, followed by the <code class="literal">&lt;interval qualifier&gt;</code>
+    fields. In the first example below, COL1 and COL2 are of the same datetime
+    type, and the result is evaluated in INTERVAL YEAR TO MONTH type.</p>
+<pre class="programlisting">(COL1 &ndash; COL2) YEAR TO MONTH /* the difference between two DATE or two TIEMSTAMP values in years and months */
+(CURRENT_DATE &ndash; COL3) DAY /* the number of days between the value of COL3 and the current date */
+(CURRENT_DATE - DATE '2000-01-01') YEAR TO MONTH /* the number of years and months since the beginning of this century */
+CURRENT_DATE - 2 DAY /* the date of the day before yesterday */
+(CURRENT_TIMESTAMP - TIMESTAMP '2009-01-01 00:00:00') DAY(4) TO SECOND(2) /* days to seconds since the given date */
+</pre>
+<p>The individual fields of both datetime and interval values can be
+    extracted using the EXTRACT function. The same function can also be used
+    to extract the time zone displacement fields of a datetime value.</p>
+<p>
+<code class="literal">EXTRACT ({YEAR | MONTH | DAY | HOUR | MINUTE | SECOND |
+    TIMEZONE_HOUR | TIMEZONE_MINUTE | DAY_OF_WEEK | WEEK_OF_YEAR } FROM
+    {&lt;datetime value&gt; | &lt;interval value&gt;})</code>
+</p>
+<p>The dichotomy between interval types based on seconds, and those
+    based on months, stems from the fact that the different calendar months
+    have different numbers of days. For example, the expression, &ldquo;nine months
+    and nine days since an event&rdquo; is not exact when the date of the event is
+    unknown. It can represent a period of around 284 days give or take one.
+    SQL interval values are independent of any start or end dates or times.
+    However, when they are added to or subtracted from certain date or
+    timestamp values, the result may be invalid and cause an exception (e.g.
+    adding one month to January 30 results in February 30, which is
+    invalid).</p>
+<p>JDBC has an unfortunate limitation and does not include type codes
+    for SQL INTERVAL types. Therefore, for compatibility with database tools
+    that are limited to the JDBC type codes, HyperSQL reports these types by
+    default as VARCHAR. You can use the URL property
+    <code class="literal">hsqldb.translate_dti_types=false</code> to override the
+    default behaviour.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N106BD"></a>Arrays</h2>
+</div>
+</div>
+</div>
+<p>Array are a powerful feature of SQL:2008 and can help solve many
+    common problems. Arrays should not be used as a substitute for
+    tables.</p>
+<p>HyperSQL supports arrays of values according to the SQL:2008
+    Standard.</p>
+<p>Elements of the array are either NULL, or of the same data type. It
+    is possible to define arrays of all supported types, including the types
+    covered in this chapter and user defined types, except LOB types. An SQL
+    array is one dimensional and is addressed from position 1. An empty array
+    can also be used, which has no element.</p>
+<p>Arrays can be stored in the database, as well as being used as
+    temporary containers of values for simplifying SQL statements. They
+    facilitate data exchange between the SQL engine and the user's
+    application.</p>
+<p>The full range of supported syntax allows array to be created, used
+    in SELECT or other statements, combined with rows of tables and used in
+    routine calls.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N106CA"></a>Array Definition</h3>
+</div>
+</div>
+</div>
+<p>The type of a table column, a routine parameter, a variable, or
+      the return value of a function can be defined as an array.</p>
+<p>
+<code class="literal">&lt;array type&gt; ::= &lt;data type&gt; ARRAY [ &lt;left
+      bracket or trigraph&gt; &lt;maximum cardinality&gt; &lt;right bracket or
+      trigraph&gt; ]</code>
+</p>
+<p>The word ARRAY is added to any valid type definition except BLOB
+      and CLOB type definitions. If the optional <code class="literal">&lt;maximum
+      cardinality&gt;</code> is not used, the default value is 1024. The
+      size of the array cannot be extended beyond maximum cardinality.</p>
+<p>In the example below, the table contains a column of integer
+      arrays and a column of varchar arrays. The VARCHAR array has an explicit
+      maximum size of 10, which means each array can have between 0 and 10
+      elements. The INTEGER array has the default maximum size of 1024. The id
+      column has a default clause with an empty array. The default clause can
+      be defined only as DEFAULT NULL or DEFAULT ARRAY[] and does not allow
+      arrays containing elements.</p>
+<div class="informalexample">
+<pre class="programlisting">CREATE TABLE t (id INT PRIMARY KEY, scores INT ARRAY DEFAULT ARRAY[], names VARCHAR(20) ARRAY[10])</pre>
+</div>
+<p>An array can be constructed from value expressions or a query
+      expression.</p>
+<p>
+<code class="literal">&lt;array value constructor by enumeration&gt; ::= ARRAY
+      &lt;left bracket or trigraph&gt; &lt;array element list&gt; &lt;right
+      bracket or trigraph&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;array element list&gt; ::= &lt;value expression&gt; [
+      { &lt;comma&gt; &lt;value expression&gt; }... ]</code>
+</p>
+<p>
+<code class="literal">&lt;array value constructor by query&gt; ::= ARRAY
+      &lt;left paren&gt; &lt;query expression&gt; [ &lt;order by clause&gt; ]
+      &lt;right paren&gt;</code>
+</p>
+<p>In the examples below, arrays are constructed from values, column
+      references or variables, function calls, or query expressions.</p>
+<div class="informalexample">
+<pre class="programlisting">ARRAY [ 1, 2, 3 ]
+ARRAY [ 'HOT', 'COLD' ]
+ARRAY [ var1, var2, CURRENT_DATE ]
+ARRAY (SELECT lastname FROM namestable ORDER BY id)
+</pre>
+</div>
+<p></p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N106ED"></a>Array Reference</h3>
+</div>
+</div>
+</div>
+<p>The most common operations on an array element reference and
+      assignment, which are used when reading or writing an element of the
+      array. Unlike Java and many other languages, arrays are extended if an
+      element is assigned to an index beyond the current length. This can
+      result in gaps containing NULL elements. Array length cannot exceed the
+      maximum cardinality.</p>
+<p>Elements of all arrays, including those that are the result of
+      function calls or other operations can be referenced for reading.</p>
+<p>
+<code class="literal">&lt;array element reference&gt; ::= &lt;array value
+      expression&gt; &lt;left bracket&gt; &lt;numeric value expression&gt;
+      &lt;right bracket&gt;</code>
+</p>
+<p>Elements of arrays that are table columns or routine variables can
+      be referenced for writing. This is done in a SET statement, either
+      inside an UPDATE statement, or as a separate statement in the case of
+      routine variables, OUT and INOUT parameters.</p>
+<p>
+<code class="literal">&lt;target array element specification&gt; ::= &lt;target
+      array reference&gt; &lt;left bracket or trigraph&gt; &lt;simple value
+      specification&gt; &lt;right bracket or trigraph&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;target array reference&gt; ::= &lt;SQL parameter
+      reference&gt; | &lt;column reference&gt;</code>
+</p>
+<p>Note that only simple values or variables are allowed for the
+      array index when an assignment is performed. The examples below
+      demonstrates how elements of the array are referenced in SELECT and an
+      UPDATE statement.</p>
+<p>
+<div class="informalexample">
+<pre class="programlisting">SELECT scores[ranking], names[ranking] FROM t JOIN t1 on (t.id = t1.tid)
+UPDATE t SET scores[2] = 123, names[2] = 'Reds' WHERE id = 10
+</pre>
+</div>
+</p>
+<p></p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10706"></a>Array Operations</h3>
+</div>
+</div>
+</div>
+<p>Several SQL operations and functions can be used with
+      arrays.</p>
+<p>
+<span class="emphasis"><em>CONCATENATION</em></span>
+</p>
+<p>Array concatenation is performed similar to string concatenation.
+      All elements of the array on the right are appended to the array on
+      left.</p>
+<p>
+<code class="literal">&lt;array concatenation&gt; ::= &lt;array value
+      expression 1&gt; &lt;concatenation operator&gt; &lt;array value
+      expression 2&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;concatenation operator&gt; ::= ||</code>
+</p>
+<p>
+<span class="emphasis"><em>FUNCTIONS</em></span>
+</p>
+<p>Three functions operate on arrays. Details are described in the
+      <a class="link" href="builtinfunctions-chapt.html" title="Chapter&nbsp;10.&nbsp;Built In Functions">Built In Functions</a> chapter.</p>
+<p>
+<code class="literal">CARDINALITY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">MAX_CARDINALITY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;right paren&gt;</code>
+</p>
+<p>Array cardinality and max cardinality are functions that return an
+      integer. CARDINALITY returns the element count, while MAX_CARDINALITY
+      returns the maximum declared cardinality of an array.</p>
+<p>
+<code class="literal">TRIM_ARRAY &lt;left paren&gt; &lt;array value
+      expression&gt; &lt;comma&gt; &lt;numeric value expression&gt; &lt;right
+      paren&gt;</code>
+</p>
+<p>The TRIM_ARRAY function returns a copy of an array with the
+      specified number of elements removed from the end of the array. The
+      <code class="literal">&lt;array value expression&gt;</code> can be any expression
+      that evaluates to an array.</p>
+<p>
+<span class="emphasis"><em>CAST</em></span>
+</p>
+<p>An array can be cast into an array of a different type. Each
+      element of the array is cast into the element type of the target array
+      type.</p>
+<p>
+<span class="emphasis"><em>UNNEST</em></span>
+</p>
+<p>Arrays can be converted into table references with the UNNEST
+      keyword.</p>
+<p>
+<code class="literal">UNNEST(&lt;array value expression&gt;) [ WITH ORDINALITY
+      ]</code>
+</p>
+<p>The <code class="literal">&lt;array value expression&gt;</code> can be any
+      expression that evaluates to an array. A table is returned that contains
+      one column when WITH ORDINALITY is not used, or two columns when WITH
+      ORDINALITY is used. The first column contains the elements of the array
+      (including all the nulls). When the table has two columns, the second
+      column contains the ordinal position of the element in the array. When
+      UNNEST is used in the FROM clause of a query, it implies the LATERAL
+      keyword, which means the array that is converted to table can belong to
+      any table that precedes the UNNEST in the FROM clause. This is explained
+      in the <a class="link" href="dataaccess-chapt.html" title="Chapter&nbsp;7.&nbsp;Data Access and Change">Data Access and Change</a> chapter.</p>
+<p>
+<span class="emphasis"><em>COMPARISON</em></span>
+</p>
+<p>Arrays can be compared for equality, but they cannot be compared
+      for ordering or ranges. Array expressions are therefore not allowed in
+      an ORDER BY clause, or in a comparison expression such as GREATER THAN.
+      Two arrays are equal if they have the same length and the values at each
+      index position are either equal or both NULL.</p>
+<p>
+<span class="emphasis"><em>USER DEFINED FUNCTIONS and PROCEDURES</em></span>
+</p>
+<p>Array parameters, variables and return values can be specified in
+      user defined functions and procedures, including aggregate functions. An
+      aggregate function can return an array that contains all the scalar
+      values that have been aggregated. These capabilities allow a wider range
+      of applications to be covered by user defined functions and easier data
+      exchange between the engine and the user's application.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqlgeneral_constr_indexes-sect"></a>Indexes and Query Speed</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL supports PRIMARY KEY, UNIQUE and FOREIGN KEY constraints,
+    which can span multiple columns.</p>
+<p>The engine creates indexes internally to support PRIMARY KEY, UNIQUE
+    and FOREIGN KEY constraints: a unique index is created for each PRIMARY
+    KEY or UNIQUE constraint; an ordinary index is created for each FOREIGN
+    KEY constraint.</p>
+<p>HyperSQL allows defining indexes on single or multiple columns. You
+    should not create duplicate user-defined indexes on the same column sets
+    covered by constraints. This would result in unnecessary memory and speed
+    overheads. See the discussion in the <a class="link" href="deployment-chapt.html" title="Chapter&nbsp;11.&nbsp;System Management and Deployment Issues">System Management and Deployment
+  Issues</a> chapter for more
+    information.</p>
+<p>Indexes are crucial for adequate query speed. When range or equality
+    conditions are used e.g. <code class="literal">SELECT ... WHERE acol &gt; 10 AND bcol =
+    0</code>, an index should exist on one of the columns that has a
+    condition. In this example, the <code class="literal">bcol</code> column is the best
+    candidate. HyperSQL always uses the best condition and index. If there are
+    two indexes, one on acol, and another on bcol, it will choose the index on
+    bcol.</p>
+<p>Queries always return results whether indexes exist or not, but they
+    return much faster when an index exists. As a rule of thumb, HSQLDB is
+    capable of internal processing of queries at over 100,000 rows per second.
+    Any query that runs into several seconds is clearly accessing thousands of
+    rows. The query should be checked and indexes should be added to the
+    relevant columns of the tables if necessary. The EXPLAIN PLAN
+    &lt;query&gt; statement can be used to see which indexes are used to
+    process the query.</p>
+<p>When executing a DELETE or UPDATE statement, the engine needs to
+    find the rows that are to be deleted or updated. If there is an index on
+    one of the columns in the WHERE clause, it is often possible to start
+    directly from the first candidate row. Otherwise all the rows of the table
+    have to be examined.</p>
+<p>Indexes are even more important in joins between multiple tables.
+    <code class="literal">SELECT ... FROM t1 JOIN t2 ON t1.c1 = t2.c2 </code> is
+    performed by taking rows of t1 one by one and finding a matching row in
+    t2. If there is no index on t2.c2 then for each row of t1, all the rows of
+    t2 must be checked. Whereas with an index, a matching row can be found in
+    a fraction of the time. If the query also has a condition on t1, e.g.,
+    <code class="literal">SELECT ... FROM t1 JOIN t2 ON t1.c1 = t2.c2 WHERE t1.c3 =
+    4</code> then an index on t1.c3 would eliminate the need for checking
+    all the rows of t1 one by one, and will reduce query time to less than a
+    millisecond per returned row. So if t1 and t2 each contain 10,000 rows,
+    the query without indexes involves checking 100,000,000 row combinations.
+    With an index on t2.c2, this is reduced to 10,000 row checks and index
+    lookups. With the additional index on t2.c2, only about 4 rows are checked
+    to get the first result row.</p>
+<p>Note that in HSQLDB an index on multiple columns can be used
+    internally as a non-unique index on the first column in the list. For
+    example: <code class="literal">CONSTRAINT name1 UNIQUE (c1, c2, c3); </code> means
+    there is the equivalent of <code class="literal">CREATE INDEX name2 ON
+    atable(c1);</code>. So you do not need to specify an extra index if you
+    require one on the first column of the list.</p>
+<p>In HyperSQL 2.0, a multi-column index will speed up queries that
+    contain joins or values on the first n columns of the index. You need NOT
+    declare additional individual indexes on those columns unless you use
+    queries that search only on a subset of the columns. For example, rows of
+    a table that has a PRIMARY KEY or UNIQUE constraint on three columns or
+    simply an ordinary index on those columns can be found efficiently when
+    values for all three columns, or the first two columns, or the first
+    column, are specified in the WHERE clause. For example, <code class="literal">SELECT
+    ... FROM t1 WHERE t1.c1 = 4 AND t1.c2 = 6 AND t1.c3 = 8 </code>will use
+    an index on <code class="literal">t1(c1,c2,c3)</code> if it exists.</p>
+<p>A multi-column index will not speed up queries on the second or
+    third column only. The first column must be specified in the JOIN .. ON or
+    WHERE conditions.</p>
+<p>Sometimes query speed depends on the order of the tables in the JOIN
+    .. ON or FROM clauses. For example the second query below should be faster
+    with large tables (provided there is an index on
+    <code class="literal">TB.COL3</code>). The reason is that <code class="literal">TB.COL3</code>
+    can be evaluated very quickly if it applies to the first table (and there
+    is an index on <code class="literal">TB.COL3</code>):</p>
+<div class="informalexample">
+<pre class="programlisting">    (TB is a very large table with only a few rows where TB.COL3 = 4)
+
+    SELECT * FROM TA JOIN TB ON TA.COL1 = TB.COL2 AND TB.COL3 = 4;
+
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 AND TB.COL3 = 4;</pre>
+</div>
+<p>The general rule is to put first the table that has a narrowing
+    condition on one of its columns.</p>
+<p>HyperSQL features automatic, on-the-fly indexes for views and
+    subselects that are used in a query.</p>
+<p>Indexes have no effect on some LIKE conditions.</p>
+<p>Indexes are used for ORDER BY clauses if the same index is used for
+    selection and ordering of rows.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1079B"></a>Query Processing and Optimisation</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL does not change the order of tables in a query in order to
+    optimise processing. As mentioned in the previous section, the table that
+    has a narrowing condition should be the first table in the query.</p>
+<p>HyperSQL optimises queries to use indexes, for all types of range
+    and equality conditions, including IS NULL and NOT NULL conditions.
+    Conditions can be in join or WHERE clauses, including all types of
+    joins.</p>
+<p>In addition, HyperSQL will always use an index (if one exists) for
+    IN conditions, whether constants, variable, or subqueries are used on the
+    right hand side of the IN predicate.</p>
+<p>HyperSQL can always use indexes when several conditions are combined
+    with the AND operator, choosing a conditions which can use an index. This
+    now extended to all equality conditions on multiple columns that are part
+    of an index.</p>
+<p>HyperSQL will also use indexes when several conditions are combined
+    with the OR operator and each condition can use an index (each condition
+    may use a different index). For example, if a huge table has two separate
+    columns for first name and last name, and both columns are indexed, a
+    query such as the following example will use the indexes and complete in a
+    short time:</p>
+<div class="informalexample">
+<pre class="programlisting">    (TC is a very large table)
+
+    SELECT * FROM TC WHERE TC.FIRSTNAME = 'John' OR TC.LASTNAME = 'Smith' OR TC.LASTNAME = 'Williams'
+</pre>
+</div>
+<p>HyperSQL optimises simple row count queries in the form of SELECT
+    COUNT(*) FROM &lt;table&gt; and returns the result immediately (this
+    optimisation does not take place in MVCC mode).</p>
+<p>HyperSQL can use an index on a column for SELECT MAX(&lt;column&gt;)
+    FROM &lt;table&gt; and SELECT MIN(&lt;column&gt;) FROM &lt;table&gt;
+    queries. There should be an index on the &lt;column&gt; and the query can
+    have a WHERE condition on the same column. In the example below the
+    maximum value for the TB.COL3 below 1000000 is returned.</p>
+<div class="informalexample">
+<pre class="programlisting">    SELECT MAX(TB.COL3) FROM TB WHERE TB.COL &lt; 1000000
+</pre>
+</div>
+<p>HyperSQL can use an index on an ORDER BY clause if all the columns
+    in ORDER BY are in a single-column or multi-column index (in the exact
+    order). This is important if there is a LIMIT n (or FETCH n ROWS ONLY)
+    clause. In this situation, the use of index allows the query processor to
+    access only the number of rows specified in the LIMIT clause, instead of
+    building the whole result set, which can be huge. This also works for
+    joined tables when the ORDER BY clause is on the columns of the first
+    table in a join. Indexes are used in the same way when ORDER BY ... DESC
+    is specified in the query. Note that unlike other RDBMS, HyperSQL does not
+    create DESC indexes. It can use any index for ORDER BY ... DESC.</p>
+<p>If there is an equality or range condition (e.g. EQUALS, GREATER
+    THAN) condition on the columns specified in the ORDER BY clause, the index
+    is still used. But if the query contains an equality condition on another
+    indexed column in the table, this may take precedence and no index may be
+    used for ORDER BY.</p>
+<p>In the two examples below, the index on TB.COL3 is used and only up
+    to 1000 rows are processed and returned.</p>
+<div class="informalexample">
+<pre class="programlisting">    (TB is a very large table with an index on TB.COL3
+
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 WHERE TB.COL3 &gt; 40000 ORDER BY TB.COL3 LIMIT 1000;
+    SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 WHERE TB.COL3 &gt; 40000 AND TB.COL3 &lt; 100000 ORDER BY TB.COL3 DESC LIMIT 1000;
+</pre>
+</div>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="running-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="sessions-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;1.&nbsp;Running and Using HyperSQL&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;3.&nbsp;Sessions and Transactions</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/sqlroutines-chapt.html b/doc/guide/sqlroutines-chapt.html
new file mode 100644
index 0000000..23deb11
--- /dev/null
+++ b/doc/guide/sqlroutines-chapt.html
@@ -0,0 +1,1791 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;8.&nbsp;SQL-Invoked Routines</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="dataaccess-chapt.html" title="Chapter&nbsp;7.&nbsp;Data Access and Change">
+<link rel="next" href="triggers-chapt.html" title="Chapter&nbsp;9.&nbsp;Triggers">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="dataaccess-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;8.&nbsp;SQL-Invoked Routines</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="triggers-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;7.&nbsp;Data Access and Change&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;9.&nbsp;Triggers</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sqlroutines-chapt"></a>Chapter&nbsp;8.&nbsp;SQL-Invoked Routines</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3643 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N12545"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-06 23:04:17 -0400 (Sun, 06 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1257C">SQL Language Routines (PSM)</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12597">Routine Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N125DC">Compound Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N125EE">Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12604">Handlers</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12632">Assignment Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12648">Select Statement : Single Row</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12663">Formal Parameters</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1267E">Iterated Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12699">Conditional Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N126E2">Return Statement</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N126FD">Control Statements</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1271F">Routine Polymorphism</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1272E">Returning Data From Routines</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12748">Java Language Routines (SQL/JRT)</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N127C5">Polymorphism</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N127D2">Java Language Procedures</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N127EB">Legacy Support</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N127FB">SQL Language Aggregate Functions</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12802">Definition of Aggregate Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12828">SQL PSM Aggregate Functions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1283E">Java Aggregate Functions</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N12854">Routine Definition</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqlroutines-chapt.html#N1291D">Routine Characteristics</a></span>
+</dt>
+</dl>
+</dd>
+</dl>
+</div>
+<p>SQL-invoked routines are functions and procedures called from SQL.
+  HyperSQL 2.0 supports routines conforming to two parts of the SQL Standard.
+  Routines written in the SQL language are supported in conformance to SQL/PSM
+  (Persistent Stored Modules) specification. Routines written in Java are
+  supported in (loose) conformance to SQL/JRT specification. In addition,
+  HyperSQL&rsquo;s previous non-standard support for calling Java routines without
+  prior method definition is retained and enhanced in the latest version by
+  extending the SQL/JRT specification.</p>
+<p>HyperSQL also supports user defined aggregate functions written in the
+  SQL language. This feature is an extension to the SQL Standard.</p>
+<p>SQL-invoked routines are schema objects. Naming and referencing
+  follows conventions common to all schema objects. The same routine name can
+  be defined in two different schemas and used with schema-qualified
+  references.</p>
+<p>A routine is either a procedure or a function.</p>
+<p>A function:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>is defined with CREATE FUNCTION</p>
+</li>
+<li>
+<p>always returns a value</p>
+</li>
+<li>
+<p>does not modify the data in the database</p>
+</li>
+<li>
+<p>is called as part of an SQL statement</p>
+</li>
+<li>
+<p>can have parameters</p>
+</li>
+<li>
+<p>can be polymorphic</p>
+</li>
+</ul>
+</div>
+<p>A procedure:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>is defined with CREATE PROCEDURE</p>
+</li>
+<li>
+<p>can return one or more values</p>
+</li>
+<li>
+<p>can modify the data in the database</p>
+</li>
+<li>
+<p>is called separately, using the CALL statement</p>
+</li>
+<li>
+<p>can have parameters</p>
+</li>
+<li>
+<p>can be polymorphic</p>
+</li>
+</ul>
+</div>
+<p>Definition of routine signature and characteristics, name resolution
+  and invocation are all implemented uniformly for routines written in SQL or
+  Java.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N1257C"></a>SQL Language Routines (PSM)</h2>
+</div>
+</div>
+</div>
+<p>The PSM (Persistent Stored Module) specification extends the SQL
+    language to allow definition of both SQL Function and SQL procedure bodies
+    with the same structure and the same control statements (such as
+    conditional and loop statements) with minor exceptions.</p>
+<p>The routine body is a SQL statement. In its simplest form, the body
+    is a single SQL statement. A simple example of a function is given
+    below:</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before (t TIMESTAMP)
+  RETURNS TIMESTAMP
+  RETURN t - 1 HOUR
+
+</pre>
+<p>An example of the use of the function in an SQL statement is given
+    below:</p>
+<pre class="programlisting">SELECT an_hour_before(event_timestamp) AS notification_timestamp, event_name FROM events;</pre>
+<p>A simple example of a procedure is given below:</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname VARCHAR(50))
+  MODIFIES SQL DATA
+  INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP)
+
+</pre>
+<p>The procedure inserts a row into an existing table with the
+    definition given below:</p>
+<pre class="programlisting">CREATE TABLE customers(id INTEGER GENERATED BY DEFAULT AS IDENTITY, firstname VARCHAR(50), lastname VARCHAR(50), added TIMESTAMP);</pre>
+<p>An example of the use of the procedure is given below:</p>
+<pre class="programlisting">CALL new_customer('JOHN', 'SMITH');</pre>
+<p>The routine body is often a compound statement. A compound statement
+    can contain one or more SQL statements, which can include control
+    statements, as well as nested compound statements.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12597"></a>Routine Statements</h3>
+</div>
+</div>
+</div>
+<p>The following SQL Statements can be used only in routines.</p>
+<p>
+<code class="literal">&lt;handler declaration&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;assignment statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;compound statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;case statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;if statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;while statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;repeat statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;for statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;loop statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;iterate statement</code>
+</p>
+<p>
+<code class="literal">&lt;leave statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;signal statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;resignal statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;return statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;select statement: single
+      row&gt;</code>
+</p>
+<p>The following SQL Statements can be used in procedures but not in
+      functions.</p>
+<p>
+<code class="literal">&lt;call statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;delete statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;insert statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;update statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;merge statement&gt;</code>
+</p>
+<p>As shown in the examples below, the formal parameters and the
+      variables of the routine can be used in statements, similar to the way a
+      column reference is used.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N125DC"></a>Compound Statement</h3>
+</div>
+</div>
+</div>
+<p>A compound statement is enclosed in a BEGIN / END block with
+      optional labels. It can contain one or more <code class="literal">&lt;SQL variable
+      declaration&gt;</code> or <code class="literal">&lt;handler
+      declaration&gt;</code> before at least one SQL statement. The BNF is
+      given below:</p>
+<p>
+<code class="literal">&lt;compound statement&gt; ::= [ &lt;beginning
+      label&gt; &lt;colon&gt; ] BEGIN [[NOT] ATOMIC] [{&lt;SQL variable
+      declaration&gt; &lt;semicolon&gt;} ...] [{&lt;handler declaration&gt;
+      &lt;semicolon&gt;}...] {&lt;SQL procedure statement&gt;
+      &lt;semicolon&gt;} ... END [ &lt;ending label&gt; ]</code>
+</p>
+<p>An example of a simple compound statement body is given below. It
+      performs the common task of inserting related data into two table. The
+      IDENTITY value that is automatically inserted in the first table is
+      retrieved using the IDENTITY() function and inserted into the second
+      table.</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname  VARCHAR(50), address VARCHAR(100))
+  MODIFIES SQL DATA
+    BEGIN ATOMIC
+    INSERT INTO customers VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    INSERT INTO addresses VALUES (DEFAULT, IDENTITY(), address);
+  END
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N125EE"></a>Variables</h3>
+</div>
+</div>
+</div>
+<p>A <code class="literal">&lt;variable declaration&gt;</code> defines the name
+      and data type of the variable and, optionally, its default value. In the
+      next example, a variable is used to hold the IDENTITY value. In
+      addition, the formal parameters of the procedure are identified as input
+      parameters with the use of the optional IN keyword. This procedure does
+      exactly the same job as the procedure in the previous example.</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+  MODIFIES SQL DATA
+  BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+  END
+
+</pre>
+<p>The BNF for variable declaration is given below:</p>
+<p>
+<code class="literal">&lt;SQL variable declaration&gt; ::= DECLARE
+      &lt;variable name list&gt; &lt;data type&gt; [DEFAULT &lt;default
+      value&gt;]</code>
+</p>
+<p>
+<code class="literal">&lt;variable name list&gt; ::= &lt;variable name&gt; [
+      { &lt;comma&gt; &lt;variable name&gt; }... ]</code>
+</p>
+<p>Examples of variable declaration are given below. Note that in a
+      DECLARE statement with multiple comma-separated variable names, the type
+      and the default value applies to all the variables in the list:</p>
+<pre class="programlisting">  BEGIN ATOMIC
+    DECLARE temp_zero DATE;
+    DECLARE temp_one, temp_two INTEGER DEFAULT 2;
+    DECLARE temp_three VARCHAR(20) DEFAULT 'no name';
+    -- more statements ...
+    SET temp_zero = DATE '2010-03-18';
+    SET temp_two = 5;
+    -- more statements ...
+  END</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12604"></a>Handlers</h3>
+</div>
+</div>
+</div>
+<p>A <code class="literal">&lt;handler declaration&gt;</code> defines the
+      course of action when an exception or warning is raised during the
+      execution of the compound statement. A compound statement may have one
+      or more handler declarations. These handlers become active when code
+      execution enters the compound statement block and remain active in any
+      sub-block and statement within the block. The handlers become inactive
+      when code execution leaves the block.</p>
+<p>In the previous example, if an exception is thrown during the
+      execution of either SQL statement, the execution of the compound
+      statement is terminated and the exception is propagated and thrown by
+      the CALL statement for the procedure. A handler declaration can resolve
+      the thrown exception within the compound statement without propagating
+      it, and allow the execution of the &lt;compound statement&gt; to
+      continue.</p>
+<p>In the example below, the UNDO handler declaration catches any
+      exception that is thrown during the execution of the compound statement
+      inside the BEGIN / END block. As it is an UNDO handler, all the changes
+      to data performed within the compound statement (BEGIN / END) block are
+      rolled back. The procedure then returns without throwing an
+      exception.</p>
+<pre class="programlisting">CREATE PROCEDURE NEW_CUSTOMER(IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+    MODIFIES SQL DATA
+  label_one: BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    DECLARE UNDO HANDLER FOR SQLEXCEPTION LEAVE label_one;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+  END
+
+</pre>
+<p>Other types of hander are CONTINUE and EXIT handlers. A CONTINUE
+      handler ignores any exception and proceeds to the next statement in the
+      block. An EXIT handler terminates execution without undoing the data
+      changes performed by the previous (successful) statements.</p>
+<p>The conditions can be general conditions, or specific conditions.
+      Among general conditions that can be specified, SQLEXCEPTION covers all
+      exceptions, SQLWARNING covers all warnings, while NOT FOUND covers the
+      not-found condition, which is raised when a DELETE, UPDATE, INSERT or
+      MERGE statement completes without actually affecting any row.
+      Alternatively, one or more specific conditions can be specified
+      (separated with commas) which apply to specific exceptions or warnings
+      or classes or exceptions or warnings. A specific condition is specified
+      with <code class="literal">SQLSTATE &lt;value&gt;</code>, for example SQLSTATE
+      'W_01003' specifies the warning raised after a SQL statement is executed
+      which contains an aggregate function which encounters a null value
+      during execution. An example is given below which activates the handler
+      when either of the two warnings is raised:</p>
+<pre class="programlisting">DECLARE UNDO HANDLER FOR SQLSTATE 'W_01003', 'W_01004' LEAVE label_one;</pre>
+<p>The BNF for <code class="literal">&lt;handler declaration&gt;</code> is
+      given below:</p>
+<p>
+<code class="literal">&lt;handler declaration&gt; ::= DECLARE {UNDO |
+      CONTINUE | EXIT} HANDLER FOR {SQLEXCEPTION | SQLWARNING | NOT FOUND} | {
+      SQL_STATE &lt;state value&gt; [, ...]} [&lt;SQL procedure
+      statement&gt;];</code>
+</p>
+<p>A handler declaration may specify an SQL procedure statement to be
+      performed when the handler is activated. When an exception occurs, the
+      example below performs the UNDO as in the previous example, then inserts
+      the (invalid) data into a separate table.</p>
+<pre class="programlisting">DECLARE UNDO HANDLER FOR SQLEXCEPTION
+    INSERT INTO invalid_customers VALUES(firstanme, lastname, address);</pre>
+<p>The <code class="literal">&lt;SQL procedure statement&gt;</code> is required
+      by the SQL Standard but is optional in HyperSQL. If the execution of the
+      <code class="literal">&lt;SQL procedure statement&gt;</code> specified in the
+      handler declaration throws an exception itself, then it is handled by
+      the handlers that are currently active. The <code class="literal">&lt;SQL procedure
+      statement&gt;</code> can itself be a compound statement with its own
+      handlers.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12632"></a>Assignment Statement</h3>
+</div>
+</div>
+</div>
+<p>The SET statement is used for assignment. It can be used flexibly
+      with rows or single values. The BNF is given below:</p>
+<p>
+<code class="literal">&lt;assignment statement&gt; ::= &lt;singleton
+      variable assignment&gt; | &lt;multiple variable
+      assignment&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;singleton variable assignment&gt; ::= SET
+      &lt;assignment target&gt; &lt;equals operator&gt; &lt;assignment
+      source&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;multiple variable assignment&gt; ::= SET
+      (&lt;variable or parameter&gt;, ...) = &lt;row value
+      expression&gt;</code>
+</p>
+<p>In the example below, the result of the SELECT is assigned to two
+      OUT or INOUT arguments. The SELECT must return one row. If it returns
+      more than one, an exception is raised. If it returns no row, no change
+      is made to ARG1 and ARG2.</p>
+<pre class="programlisting">SET (arg1, arg2) = (SELECT col1, col2 FROM atable WHERE id = 10);</pre>
+<p>In the example below, the result of a function call is assigned to
+      VAR1.</p>
+<pre class="programlisting">SET var1 = SQRT(var2);</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12648"></a>Select Statement : Single Row</h3>
+</div>
+</div>
+</div>
+<p>A special form of SELECT can also be used for assigning values
+      from a query to one or more arguments or variables. This works similar
+      to a SET statement that has a SELECT statement as the source.</p>
+<a name="N1264D" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SELECT : SINGLE ROW</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>select statement: single row</em></span>
+</p>
+<p>
+<code class="literal">&lt;select statement: single row&gt; ::= SELECT [
+      &lt;set quantifier&gt; ] &lt;select list&gt; INTO &lt;select target
+      list&gt; &lt;table expression&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;select target list&gt; ::= &lt;target
+      specification&gt; [ { &lt;comma&gt; &lt;target specification&gt; }...
+      ]</code>
+</p>
+<p>Retrieve values from a specified row of a table and assign the
+      fields to the specified targets. The example below has an identical
+      effect to the example of SET statement given above.</p>
+<pre class="programlisting">SELECT col1, col2 INTO arg1, arg2 FROM atable WHERE id = 10;</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12663"></a>Formal Parameters</h3>
+</div>
+</div>
+</div>
+<p>Each parameter of a procedure can be defined as IN, OUT or INOUT.
+      An IN parameter is an input to the procedure and is passed by value. The
+      value cannot be modified inside the procedure body. An OUT parameter is
+      a reference for output. An INOUT parameter is a reference for both input
+      and output. An OUT or INOUT parameter argument is passed by reference,
+      therefore only a dynamic parameter argument or a variable within an
+      enclosing procedure can be passed for it. The assignment statement is
+      used to assign a value to an OUT or INOUT parameter.</p>
+<p>In the example below, the procedure is declared with an OUT
+      parameter.</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(OUT newid INT, IN firstname VARCHAR(50), IN lastname VARCHAR(50), IN address VARCHAR(100))
+  MODIFIES SQL DATA
+  BEGIN ATOMIC
+    DECLARE temp_id INTEGER;
+    INSERT INTO CUSTOMERS VALUES (DEFAULT, firstname, lastname, CURRENT_TIMESTAMP);
+    SET temp_id = IDENTITY();
+    INSERT INTO ADDRESSES VALUES (DEFAULT, temp_id, address);
+    SET newid = temp_id;
+  END
+
+</pre>
+<p>In the SQL session, or in the body of another stored procedure, a
+      variable must be assigned to the OUT parameter. After the procedure
+      call, this variable will hold the new identity value that was generated
+      inside the procedure.</p>
+<p>In the example below, a session variable,
+      <code class="literal">the_new_id</code> is declared. After the call to
+      <code class="literal">new_customer</code>, the value for the identity is stored in
+      <code class="literal">the_new_id</code> variable. This is returned via the next
+      CALL statement. Alternatively, <code class="literal">the_new_id</code> can be used
+      as an argument to another CALL statement.</p>
+<pre class="programlisting">DECLARE the_new_id INT DEFAULT NULL;
+CALL new_customer(the_new_id, 'John', 'Smith', '10 Parliament Square'); 
+CALL the_new_id;
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1267E"></a>Iterated Statements</h3>
+</div>
+</div>
+</div>
+<p>Various iterated statements can be used in routines. In these
+      statements, the <code class="literal">&lt;SQL statement list&gt;</code> consists
+      of one or more SQL statements. The <code class="literal">&lt;search
+      condition&gt;</code> can be any valid SQL expression of BOOLEAN
+      type.</p>
+<p>
+<code class="literal">&lt;loop statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ] LOOP &lt;SQL statement list&gt; END LOOP [ &lt;ending
+      label&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;while statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ] WHILE &lt;search condition&gt; DO &lt;SQL statement
+      list&gt; END WHILE [ &lt;ending label&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;repeat statement&gt; ::= [ &lt;beginning label&gt;
+      &lt;colon&gt; ]</code>
+</p>
+<p>
+<code class="literal">REPEAT &lt;SQL statement list&gt; UNTIL &lt;search
+      condition&gt; END REPEAT [ &lt;ending label&gt;</code>
+</p>
+<p>In the example below, a multiple rows are inserted into a table in
+      a WHILE loop:</p>
+<pre class="programlisting">loop_label: WHILE my_var &gt; 0 DO
+  INSERT INTO CUSTOMERS VALUES (DEFAULT, my_var);
+  SET my_var = my_var - 1;
+  IF my_var = 10 THEN SET my_var = 8; END IF;
+  IF my_var = 22 THEN LEAVE loop_label; END IF;
+END WHILE loop_label;
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12699"></a>Conditional Statements</h3>
+</div>
+</div>
+</div>
+<p>There are two types of CASE ... WHEN statement and the IF ... THEN
+      statement.</p>
+<a name="N1269E" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CASE WHEN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>case when statement</em></span>
+</p>
+<p>The simple case statement uses a <code class="literal">&lt;case
+      operand&gt;</code> as the predicand of one or more predicates. For
+      the right part of each predicate, it specifies one or more SQL
+      statements to execute if the predicate evaluates TRUE. If the ELSE
+      clause is not specified, at least one of the search conditions must be
+      true, otherwise an exception is raised.</p>
+<p>
+<code class="literal">&lt;simple case statement&gt; ::= CASE &lt;case
+      operand&gt; &lt;simple case statement when clause&gt;... [ &lt;case
+      statement else clause&gt; ] END CASE</code>
+</p>
+<p>
+<code class="literal">&lt;simple case statement when clause&gt; ::= WHEN
+      &lt;when operand list&gt; THEN &lt;SQL statement
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;case statement else clause&gt; ::= ELSE &lt;SQL
+      statement list&gt;</code>
+</p>
+<p>A skeletal example is given below. The variable var_one is first
+      tested for equality with 22 or 23 and if the test evaluates to TRUE,
+      then the INSERT statement is performed and the statement ends. If the
+      test does not evaluate to TRUE, the next condition test, which is an IN
+      predicate, is performed with var_one and so on. The statement after the
+      ELSE clause is performed if none the previous tests returns TRUE.</p>
+<pre class="programlisting">CASE var_one
+  WHEN 22, 23 THEN INSERT INTO t_one ...;
+  WHEN IN (2, 4, 5) THEN DELETE FROM t_one WHERE ...;
+  ELSE UPDATE t_one ...;
+  END CASE
+
+</pre>
+<p>The searched case statement uses one or more search conditions,
+      and for each search condition, it specifies one or more SQL statements
+      to execute if the search condition evaluates TRUE. An exception is
+      raised if there is no ELSE clause and none of the search conditions
+      evaluates TRUE.</p>
+<p>
+<code class="literal">&lt;searched case statement&gt; ::= CASE &lt;searched
+      case statement when clause&gt;... [ &lt;case statement else clause&gt; ]
+      END CASE</code>
+</p>
+<p>
+<code class="literal">&lt;searched case statement when clause&gt; ::= WHEN
+      &lt;search condition&gt; THEN &lt;SQL statement
+      list&gt;</code>
+</p>
+<p>The example below is partly a rewrite of the previous example, but
+      a new condition is added:</p>
+<pre class="programlisting">CASE WHEN var_one = 22 OR var_one = 23 THEN INSERT INTO t_one ...;
+  WHEN var_one IN (2, 4, 5) THEN DELETE FROM t_one WHERE ...;
+  WHEN var_two IS NULL THEN UPDATE t_one ...;
+  ELSE UPDATE t_one ...;
+  END CASE
+
+</pre>
+<a name="N126C8" class="indexterm"></a>
+<p>
+<span class="bold"><strong>IF</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>if statement</em></span>
+</p>
+<p>The if statement is very similar to the searched case statement.
+      The difference is that no exception is raised if there is no ELSE clause
+      and no search condition evaluates TRUE.</p>
+<p>
+<code class="literal">&lt;if statement&gt; ::= IF &lt;search condition&gt;
+      &lt;if statement then clause&gt; [ &lt;if statement elseif clause&gt;...
+      ] [ &lt;if statement else clause&gt; ] END IF</code>
+</p>
+<p>
+<code class="literal">&lt;if statement then clause&gt; ::= THEN &lt;SQL
+      statement list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;if statement elseif clause&gt; ::= ELSEIF
+      &lt;search condition&gt; THEN &lt;SQL statement
+      list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;if statement else clause&gt; ::= ELSE &lt;SQL
+      statement list&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N126E2"></a>Return Statement</h3>
+</div>
+</div>
+</div>
+<p>The RETURN statement is required and used only in functions. The
+      body of a function is either a RETURN statement, or a compound statement
+      that contains a RETURN statement.</p>
+<a name="N126E7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RETURN</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>return statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;return statement&gt; ::= RETURN &lt;return
+      value&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;return value&gt; ::= &lt;value expression&gt; |
+      NULL</code>
+</p>
+<p>Return a value from an SQL function. If the function is defined
+      as RETURNS TABLE, then the value is a TABLE expression such as RETURN
+      TABLE(SELECT ...) otherwise, the value expression can be any scalar
+      expression. In the examples below, the same function is written with or
+      without a BEGIN END block. In both versions, the RETURN value is a
+      scalar expression.</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP
+  RETURN (SELECT MAX(event_time) FROM atable WHERE event_type = e_type) - 1 HOUR
+
+CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP
+  BEGIN ATOMIC
+    DECLAR max_event TIMESTAMP;
+    SET max_event = SELECT MAX(event_time) FROM atable WHERE event_type = e_type;
+    RETURN max_event - 1 HOUR;
+  END
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N126FD"></a>Control Statements</h3>
+</div>
+</div>
+</div>
+<p>In addition to the RETURN statement, the following statements can
+      be used in specific contexts.</p>
+<p>ITERATE STATEMENT</p>
+<p>The ITERATE statement can be used to cause the next iteration of a
+      labeled iterated statement (a WHILE, REPEAT or LOOP statement). It is
+      similar to the "continue" statement in C and Java.</p>
+<p>
+<code class="literal">&lt;iterate statement&gt; ::= ITERATE &lt;statement
+      label&gt;</code>
+</p>
+<p>LEAVE STATEMENT</p>
+<p>The LEAVE statement can be used to leave a labeled block. When
+      used in an iterated statement, it is similar to the "break" statement is
+      C and Java. But it can be used in compound statements as well.</p>
+<p>
+<code class="literal">&lt;leave statement&gt; ::= LEAVE &lt;statement
+      label&gt;</code>
+</p>
+<p>Signal and Resignal Statements</p>
+<p>The SIGNAL statement is used to throw an exception (or force an
+      exception). When invoked, any exception handler for the given exception
+      is in turn invoked. If there is no handler, the exception is propagated
+      to the enclosing context.</p>
+<p>
+<code class="literal">&lt;signal statement&gt; ::= SIGNAL SQL_STATE
+      &lt;state value&gt;</code>
+</p>
+<p>The RESIGNAL statement is used to throw an exception from an
+      exception handler&rsquo;s <code class="literal">&lt;SQL procedure statement&gt;</code>,
+      in effect propagating the exception to the enclosing context without
+      further action by the currently active handlers.</p>
+<p>
+<code class="literal">&lt;resignal statement&gt; ::= RESIGNAL SQL_STATE
+      &lt;state value&gt;</code>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1271F"></a>Routine Polymorphism</h3>
+</div>
+</div>
+</div>
+<p>More than one version of a routine can be created.</p>
+<p>For procedures, the different versions must have different
+      parameter counts. &nbsp;When the procedure is called, the parameter count
+      determines which version is called.</p>
+<p>For functions, the different versions can have the same or
+      different parameter counts. When the parameter count of two versions of
+      a function is the same, the type of parameters must be different. The
+      best matching version of the function is called, according to both the
+      parameter count and parameter types.</p>
+<p>Two versions of an overloaded function are given below. One
+      version accepts TIMESTAMP while the other accepts TIME arguments.</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  IF t &gt; CURRENT_TIMESTAMP THEN
+    RETURN CURRENT_TIMESTAMP;
+  ELSE
+    RETURN t - 1 HOUR;
+  END IF
+
+CREATE FUNCTION an_hour_before_or_now(t TIME)
+  RETURNS TIME
+  CASE t
+    WHEN &gt; CURRENT_TIME THEN
+      RETURN CURRENT_TIME;
+    WHEN &gt;= TIME'01:00:00' THEN
+      RETURN t - 1 HOUR;
+    ELSE
+      RETURN CURRENT_TIME;
+  END CASE
+
+</pre>
+<p>more ..</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1272E"></a>Returning Data From Routines</h3>
+</div>
+</div>
+</div>
+<p>The OUT or INOUT parameters of a procedure are used to assign
+      simple values to dynamic parameters or to variables in the calling
+      context. In addition, a SQL/PSM procedure may return result sets to the
+      calling context. These result sets are dynamic in the sense that a
+      procedure may return a different number of result sets or none at all in
+      different invocations.</p>
+<p>The SQL Standard uses a mechanism called CURSORS for accessing and
+      modifying rows of a result set one by one. This mechanism is absolutely
+      necessary when the database is accessed from an external application
+      program. The JDBC ResultSet interface allows this method of access from
+      Java programs and is supported by HyperSQL.</p>
+<p>The SQL Standard uses cursors within the body of a procedure to
+      return result sets. It specifies a somewhat complex mechanism to allow
+      access to these cursors from the calling contexts. HyperSQL does not
+      support access to such result sets within a calling SQL/PSM procedure.
+      This is considered redundant as all operations on data can be performed
+      with non-cursor SQL statements.</p>
+<p>(feature to be implemented) HyperSQL will support returning single
+      or multiple result sets from SQL/PSM procedures only via the JDBC
+      CallableStatement interface. Cursors are declared and opened within the
+      body of the procedure. No further operation is performed on the cursors
+      within the procedure. When the execution of the procedure is complete,
+      the cursors become available as Java ResultSet objects via the
+      CallableStatement instance that called the SQL/PSM procedure.</p>
+<p>Currently, a single result can be returned from FUNCTION routines,
+      when the function is defined as RETURNS TABLE ( .. )</p>
+<p>To return a table from a SELECT statement, you should use a return
+      statement such as RETURN TABLE( SELECT ...); in a SQL/PSM function. A
+      Java function should return a JDBCResultSet instance. For an example of
+      how to construct a JDBCResultSet for this purpose, see the source code
+      for the org.hsqldb.jdbc.JDBCArray class.</p>
+<p>The JDBC CallableStatement class is used with the SQL statement
+      <code class="literal">CALL &lt;routine name&gt; ( &lt;argument 1&gt;, ... )</code>
+      to call both functions and procedures. The <code class="literal">getXXX()</code>
+      methods can be used to retrieve INOUT or OUT arguments after the call.
+      The <code class="literal">getResultSet()</code> call can be used to access the
+      ResultSet returned from a function that returns a result set.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12748"></a>Java Language Routines (SQL/JRT)</h2>
+</div>
+</div>
+</div>
+<p>The body of a Java language routine is a static method of a Java
+    class, specified with a fully qualified method name in the routine
+    definition.</p>
+<p>In the example below, the static method named
+    <code class="methodname">toZeroPaddedString</code> is specified to be called when
+    the function is invoked.</p>
+<pre class="programlisting">CREATE FUNCTION zero_pad(x BIGINT, digits INT, maxsize INT)
+  RETURNS CHAR VARYING(100)
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME
+  'CLASSPATH:org.hsqldb.lib.StringUtil.toZeroPaddedString'
+
+</pre>
+<p>The signature of the Java method (used in the Java code but not in
+    SQL code to create the function) is given below:</p>
+<pre class="programlisting">public static String toZeroPaddedString(long value, int precision, int maxSize)</pre>
+<p>The parameter and return types and of the SQL routine definition
+    must match those of the Java method according to the table below:</p>
+<div class="informaltable">
+<table cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>SMALLINT &nbsp; </p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>Short or Short</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>INT</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>int or Integer</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>BIGINT</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>long or Long</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>NUMERIC &nbsp;or DECIMAL</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>BigDecimal</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>FLOAT &nbsp;or DOUBLE</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>Double or Double</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>CHAR or VARCHAR</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>String</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>DATE</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>java.sql.Date</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>TIME</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>java.sql.Time</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>TIMESTAMP</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>java.sql.Timestamp</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>BINARY</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>Byte[]</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">
+<p>BOOLEAN</p>
+</td><td style="border-bottom: 0.5pt solid ; ">
+<p>boolean or Boolean</p>
+</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">ARRAY of any type</td><td style="border-bottom: 0.5pt solid ; ">java.sql.Array</td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; ">
+<p>TABLE</p>
+</td><td style="">
+<p>java.sql.ResultSet</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>If the specified Java method is not found or its parameters and
+    return types do not match the definition, an exception is raised. If more
+    than one version of the Java method exist, then the one with matching
+    parameter and return types is found and registered. If two &ldquo;equivalent&rdquo;
+    methods exist, the first one is registered. (This situation arises only
+    when a parameter is a primitive in one version and an Object in another
+    version, e.g. <code class="classname">long</code> and
+    <code class="classname">java.lang.Long</code>.).</p>
+<p>When the Java method of an SQL/JRT routine returns a value, it
+    should be within the size and precision limits defined in the return type
+    of the SQL-invoked routine, otherwise an exception is raised. The scale
+    difference are ignored and corrected. For example, in the above example,
+    the <code class="literal">RETURNS CHAR VARYING(100)</code> clause limits the length
+    of the strings returned from the Java method to 100. But if the number of
+    digits after the decimal point (scale) of a returned BigDecimal value is
+    larger than the scale specified in the RETURNS clause, the decimal
+    fraction is silently truncated and no exception of warning is
+    raised.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N127C5"></a>Polymorphism</h3>
+</div>
+</div>
+</div>
+<p>If two versions of the same SQL invoked routine with different
+      parameter types are required, they can be defined to point to the same
+      method name or different method names, or even methods in different
+      classes. In the example below, the first two definitions refer to the
+      same method name in the same class. In the Java class, the two static
+      methods are defined with corresponding method signatures.</p>
+<p>In the third example, the Java function returns a result set and
+      the SQL declaration includes RETURNS TABLE.</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before_or_now(t TIME)
+  RETURNS TIME
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION testquery(INTEGER) 
+  RETURNS TABLE(n VARCHAR(20), i INT) 
+  READS SQL DATA
+  LANGUAGE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.TestJavaFunctions.getQueryResult'
+
+</pre>
+<p>In the Java class:</p>
+<pre class="programlisting">    public static java.sql.Time nowLessAnHour(java.sql.Time value) {
+        ...
+    }
+    public static java.sql.Timestamp nowLessAnHour(java.sql.Timestamp value)
+        ...
+    }
+
+    public static ResultSet getQueryResult(Connection connection, int i) throws SQLException {
+        Statement st = connection.createStatement();
+        return st.executeQuery("SELECT * FROM T WHERE I &lt; " + i);
+    }
+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N127D2"></a>Java Language Procedures</h3>
+</div>
+</div>
+</div>
+<p>Java procedures are defined similarly to functions. The
+      differences are:</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>The return type of the Java static method must be void.</p>
+</li>
+<li>
+<p>If a parameter is defined as OUT or INOUT, the corresponding
+          Java static method parameter must be defined as an array of the JDBC
+          non-primitive type.</p>
+</li>
+<li>
+<p>When the Java static method is invoked, the OUT and INOUT
+          arguments are passed as a single-element array.</p>
+</li>
+<li>
+<p>The static method can modify the OUT or INOUT param by
+          assigning a value to the sole element of the argument array.</p>
+</li>
+<li>
+<p>If the procedure contains SQL statements, only statements for
+          data access and manipulation are allowed. The java method should not
+          perform commit or rollback. The SQL statements should not change the
+          session settings and should not include statements at create or
+          modify tables definitions or other database objects. These rules are
+          generally enforced by the engine, but additional enforcement may be
+          added in future versions</p>
+</li>
+</ul>
+</div>
+<p>An example of a procedure definition is given below:</p>
+<pre class="programlisting">CREATE PROCEDURE new_customer(firstname VARCHAR(50), lastname  VARCHAR(50), address VARCHAR(100))
+  MODIFIES SQL DATA
+  LANGUAGE JAVA
+  EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.Test01.newCustomerProcedure'
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N127EB"></a>Legacy Support</h3>
+</div>
+</div>
+</div>
+<p>The legacy HyperSQL statement, <code class="literal">CREATE ALIAS &lt;name&gt;
+      FOR &lt;fully qualified Java method name&gt;</code> is no longer
+      supported directly. It is supported when importing databases and
+      translates to a special <code class="literal">CREATE FUNCTION &lt;name&gt;</code>
+      statement that creates the function in the PUBLIC schema.</p>
+<p>The direct use of a Java method as a function is still supported
+      but deprecated. It is internally translated to a special <code class="literal">CREATE
+      FUNCTION</code> statement where the name of the function is the
+      double quoted, fully qualified name of the Java method used.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N127FB"></a>SQL Language Aggregate Functions</h2>
+</div>
+</div>
+</div>
+<p>HyperSQL adds an extension to the SQL Standard to allow user defined
+    aggregate functions. A user defined aggregate function has a single
+    parameter when it is used in SQL statements. Unlike the predefined
+    aggregate functions, the keyword DISTINCT cannot be used when a user
+    defined aggregate function is invoked. Like all user defined functions, an
+    aggregate function belongs to a schema and can be polymorphic.</p>
+<p>A user defined aggregate function can be used in SQL statements
+    where a predefined aggregate function is allowed.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12802"></a>Definition of Aggregate Functions</h3>
+</div>
+</div>
+</div>
+<p>An aggregate function is always defined with 4 parameters. The
+      first parameter is the parameter that is used when the function is
+      invoked in SQL statements, the rest of the parameter are invisible to
+      the invoking statement. The type of the first parameter is user defined.
+      The type of the second parameter must be BOOLEAN. The third and fourth
+      parameters have user defined types and must be defined as INOUT
+      parameters. The defined return type of the function determines the type
+      of the value returned when the function is invoked.</p>
+<a name="N12807" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE AGGREGATE
+      FUNCTION</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>user defined aggregate function
+      definition</em></span>
+</p>
+<p>Aggregate function definition is similar to normal function
+      definition and has the mandatory <code class="literal">&lt;returns
+      clause&gt;</code>. The BNF is given below.</p>
+<p>
+<code class="literal">&lt;user defined aggregate function&gt; ::= CREATE
+      AGGREGATE FUNCTION &lt;schema qualified routine name&gt; &lt;SQL
+      aggregate parameter declaration list&gt; &lt;returns clause&gt;
+      &lt;routine characteristics&gt; &lt;routine body&gt;</code>
+</p>
+<p>The parameter declaration list BNF is given below. The type of the
+      first parameter is used when the function is invoked as part of an SQL
+      statement. When multiple versions of a function are required, each
+      version will have the first parameter of a different type.</p>
+<p>
+<code class="literal">&lt;SQL aggregate declaration list&gt; ::= &lt;left
+      paren&gt; [IN] [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt;
+      &lt;comma&gt; [IN] [ &lt;SQL parameter name&gt; ] BOOLEAN &lt;comma&gt;
+      INOUT [ &lt;SQL parameter name&gt; ] &lt;parameter type&gt;
+      &lt;comma&gt; INOUT [ &lt;SQL parameter name&gt; ] &lt;parameter
+      type&gt; &lt;right paren&gt;</code>
+</p>
+<p>The return type is user defined. This is the type of the resulting
+      value when the function is called. Usually an aggregate function is
+      defined with CONTAINS SQL, as it normally does not read the data in
+      database tables, but it is possible to define the function with READS
+      SQL DATA and access the database tables.</p>
+<p>HyperSQL invokes the aggregate function, with all the arguments
+      set, once per each row in order to compute the values. Finally, it
+      invokes the function once more to return the final result.</p>
+<p>In the computation phase, the first argument is the value of the
+      user argument as specified in the SQL statement, computed for the
+      current row. The second argument is the boolean FALSE. The third and
+      fourth argument values are initially null, but they can be updated in
+      the body of the function during each invocation. The third and fourth
+      arguments act as registers and hold their values between invocations.
+      The return value of the function is ignored during the computation phase
+      (when the second parameter is FALSE).</p>
+<p>After the computation phase, the function is invoked once more to
+      get the final result. In this invocation, the first argument is NULL and
+      the second argument is boolean TRUE. The third and fourth arguments hold
+      the values they held at the end of the last invocation. The value
+      returned by the function in this invocation is used as the result of the
+      aggregate function computation in the invoking SQL statement. In SQL
+      queries with GROUP BY, the call sequence is repeated for each separate
+      group.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12828"></a>SQL PSM Aggregate Functions</h3>
+</div>
+</div>
+</div>
+<p>The example below features a user defined version of the Standard
+      <code class="literal">AVG(&lt;value expression&gt;)</code> aggregate function for
+      INTEGER input and output types. This function behaves differently from
+      the Standard AVG function as it returns 0 when all the input values are
+      null.</p>
+<pre class="programlisting">CREATE AGGREGATE FUNCTION udavg(IN x INTEGER, IN flag BOOLEAN, INOUT addup BIGINT, INOUT counter INT)
+  RETURNS INTEGER
+  CONTAINS SQL
+  BEGIN ATOMIC
+    IF flag THEN
+      RETURN addup / counter;
+    ELSE
+      SET counter = COALESCE(counter, 0) + 1;
+      SET addup = COALESCE(addup, 0) || COALESCE(x, 0);
+      RETURN NULL;
+    END IF;
+  END
+
+</pre>
+<p>The user defined aggregate function is used in a select statement
+      in the example below. Only the first parameter is visible and utilised
+      in the select statement.</p>
+<pre class="programlisting">SELECT udavg(id) FROM customers GROUP BY lastname;</pre>
+<p>In the example below, the function returns an array that contains
+      all the values passed for the aggregated column. For use with longer
+      arrays, you can optimise the function by defining a larger array in the
+      first iteration, and using the TRIM_ARRAY function on the RETURN to cut
+      the array to size :</p>
+<pre class="programlisting">CREATE AGGREGATE FUNCTION array_aggregate(IN val VARCHAR(100), IN flag boolean, INOUT buffer VARCHAR(100) ARRAY, INOUT counter INT)
+  RETURNS VARCHAR(100) ARRAY
+  CONTAINS SQL
+  BEGIN ATOMIC
+    IF flag THEN
+      RETURN buffer;
+    ELSE
+      IF val IS NULL THEN RETURN NULL; END IF;
+      IF counter IS NULL THEN SET counter = 0; END IF;
+      SET counter = counter + 1;
+      IF counter = 1 THEN SET buffer = ARRAY[val];
+      ELSE SET buffer[counter] = val; END IF;
+      RETURN NULL;
+    END IF;
+  END
+</pre>
+<p>The tables and data for the select statement below are created
+      with the DatabaseManager or DatabaseManagerSwing GUI apps. Part of the
+      output is shown. Each row of the output includes an array containing the
+      values for the invoices for each customer.</p>
+<pre class="programlisting">SELECT ID, FIRSTNAME, LASTNAME, ARRAY_AGGREGATE(CAST(INVOICE.TOTAL AS VARCHAR(100))) 
+  FROM customer JOIN INVOICE ON ID =CUSTOMERID
+  GROUP BY ID, FIRSTNAME, LASTNAME
+
+11 Susanne   Karsen    ARRAY['3988.20']                               
+12 John      Peterson  ARRAY['2903.10','4382.10','4139.70','3316.50'] 
+13 Michael   Clancy    ARRAY['6525.30']                               
+14 James     King      ARRAY['3665.40','905.10','498.00']             
+18 Sylvia    Clancy    ARRAY['634.20','4883.10']                      
+20 Bob       Clancy    ARRAY['3414.60','744.60']
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1283E"></a>Java Aggregate Functions</h3>
+</div>
+</div>
+</div>
+<p>A Java aggregate function is defined similarly to PSM functions,
+      apart from the routine body, which is defined as <code class="literal">EXTERNAL NAME
+      ...</code> The Java function signature must follow the rules for both
+      nullable and INOUT parameters, therefore:</p>
+<p>No agrument is defined as a primitive or primitive array type.
+      This allows nulls to be passed to the function. The second and third
+      arguments must be defined as arrays of the JDBC non-primitive types
+      listed in the table in the previous section.</p>
+<p>In the example below, a user-defined aggregate function for
+      geometric mean is defined.</p>
+<pre class="programlisting">CREATE AGGREGATE FUNCTION geometric_mean(IN val DOUBLE, IN flag BOOLEAN, INOUT register DOUBLE, INOUT counter INT)
+ RETURNS DOUBLE
+ NO SQL
+ LANGUAGE JAVA
+ EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.Test01.geometricMean'
+</pre>
+<p>The Java function definition is given below:</p>
+<pre class="programlisting">public static Double geometricMean(Double in, Boolean flag,
+        Double[] register, Integer[] counter) {
+
+    if (flag) {
+        if (register[0] == null) { return null; }
+        double a = register[0].doubleValue();
+        double b = 1 / (double) counter[0];
+        return Double.valueOf(java.lang.Math.pow(a, b));
+    }
+    if (in == null) { return null; }
+    if (in.doubleValue() == 0) { return null; }
+    if (register[0] == null) {
+        register[0] = in;
+        counter[0]  = Integer.valueOf(1);
+    } else {
+        register[0] = Double.valueOf(register[0].doubleValue() * in.doubleValue());
+        counter[0] = Integer.valueOf(counter[0].intValue() + 1);
+    }
+    return null;
+}
+</pre>
+<p>In a select statement, the function is used like built in
+      aggregate functions:</p>
+<pre class="programlisting">SELECT geometric_mean(age) FROM  FROM customer
+</pre>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12854"></a>Routine Definition</h2>
+</div>
+</div>
+</div>
+<p>As discussed in the previous pages, routine definition has several
+    mandatory or optional clauses. The complete BNF supported by HyperSQL and
+    the remaining clauses are documented in this section.</p>
+<a name="N12859" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE FUNCTION</strong></span>
+</p>
+<a name="N12862" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE PROCEDURE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>routine definition</em></span>
+</p>
+<p>Routine definition is similar for procedures and functions. A
+    function definition has the mandatory <code class="literal">&lt;returns
+    clause&gt;</code> which is discussed later. The description given so
+    far covers the essential elements of the specification with the BNF given
+    below.</p>
+<p>
+<code class="literal">&lt;schema procedure&gt; ::= CREATE PROCEDURE &lt;schema
+    qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+    &lt;routine characteristics&gt; &lt;routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;schema function&gt; ::= CREATE FUNCTION &lt;schema
+    qualified routine name&gt; &lt;SQL parameter declaration list&gt;
+    &lt;returns clause&gt; &lt;routine characteristics&gt; &lt;routine
+    body&gt;</code>
+</p>
+<p>Parameter declaration list has been described above. For SQL/JRT
+    routines, the <code class="literal">&lt;SQL parameter name&gt;</code> is optional
+    while for SQL/PSM routines, it is required. If the <code class="literal">&lt;parameter
+    mode&gt;</code> of a parameter is OUT or INOUT, it must be specified.
+    The BNF is given below:</p>
+<p>
+<code class="literal">&lt;SQL parameter declaration list&gt; ::= &lt;left
+    paren&gt; [ &lt;SQL parameter declaration&gt; [ { &lt;comma&gt; &lt;SQL
+    parameter declaration&gt; }... ] ] &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL parameter declaration&gt; ::= [ &lt;parameter
+    mode&gt; ] [ &lt;SQL parameter name&gt; ] &lt;parameter
+    type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;parameter mode&gt; ::= IN | OUT |
+    INOUT</code>
+</p>
+<p>
+<code class="literal">&lt;parameter type&gt; ::= &lt;data
+    type&gt;</code>
+</p>
+<p>Return Value and Table Functions</p>
+<a name="N1288F" class="indexterm"></a>
+<p>
+<span class="bold"><strong>RETURNS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>returns clause</em></span>
+</p>
+<p>The <code class="literal">&lt;returns clause&gt;</code> specifies the type of
+    the return value of a function. For all SQL/PSM functions and ordinary
+    SQL/JRT functions, this is simply a type definition which can be a
+    built-in type, a DOMAIN type or a DISTINCT type, or alternatively, a TABLE
+    definition. For example, RETURNS INTEGER.</p>
+<p>For a SQL/JRT function, it is possible to define a
+    <code class="literal">&lt;returns table type&gt;</code> for a Java method that
+    returns a <code class="classname">java.sql.ResultSet</code> object. Such SQL/JRT
+    functions are called <em class="glossterm">table functions</em>. Table
+    functions are used differently from normal functions. A table function can
+    be used in an SQL query expression exactly where a normal table or view is
+    allowed. At the time of invocation, the Java method is called and the
+    returned ResultSet is transformed into an SQL table. The column types of
+    the declared TABLE must match those of the ResultSet, otherwise an
+    exception is raised at the time of invocation.</p>
+<p>If a <code class="literal">&lt;returns table type&gt;</code> is defined for an
+    SQL/PSM function, the following expression is used inside the function to
+    return a table: <code class="literal">RETURN TABLE ( &lt;query expression&gt;
+    );</code> In the example blow, a table with two columns is
+    returned.</p>
+<pre class="programlisting">RETURN TABLE ( SELECT a, b FROM atable WHERE e = 10 );</pre>
+<p>If a JDBC <code class="literal">CallableStatement</code> is used to CALL the
+    function, the table returned from the function call is returned and can be
+    accessed with the <code class="literal">getResultSet()</code> method of the
+    <code class="literal">CallableStatement</code>.</p>
+<p>
+<code class="literal">&lt;returns clause&gt; ::= RETURNS &lt;returns
+    type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns type&gt; ::= &lt;returns data type&gt; |
+    &lt;returns table type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns table type&gt; ::= TABLE &lt;table function
+    column list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table function column list&gt; ::= &lt;left
+    paren&gt; &lt;table function column list element&gt; [ { &lt;comma&gt;
+    &lt;table function column list element&gt; } ... ] &lt;right
+    paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;table function column list element&gt; ::=
+    &lt;column name&gt; &lt;data type&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;returns data type&gt; ::= &lt;data
+    type&gt;</code>
+</p>
+<a name="N128D2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>routine body</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>routine body</em></span>
+</p>
+<p>Routine body is either one or more SQL statements or a Java
+    reference, as described. The user that defines the routine by issuing the
+    CREATE FUNCTION or CREATE SCHEMA command must have the relevant access
+    rights to all tables, sequences, routines, etc. that are accessed by the
+    routine. If another user is given EXECUTE privilege on the routine, then
+    there are two possibilities, depending on the <code class="literal">&lt;rights
+    clause&gt;</code>. This clause refers to the access rights that are
+    checked when a routine is invoked. The default is <code class="literal">SQL SECURITY
+    DEFINER</code>, which means access rights of the definer are used;
+    therefore no extra checks are performed when the other user invokes the
+    routine. The alternative <code class="literal">SQL SECURITY INVOKER</code> means
+    access rights on all the database objects referenced by the routine are
+    checked for the invoker. This alternative is not supported by
+    HyperSQL.</p>
+<p>
+<code class="literal">&lt;routine body&gt; ::= &lt;SQL routine spec&gt; |
+    &lt;external body reference&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;SQL routine spec&gt; ::= [ &lt;rights clause&gt; ]
+    &lt;SQL routine body&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;rights clause&gt; ::= SQL SECURITY INVOKER | SQL
+    SECURITY DEFINER</code>
+</p>
+<a name="N128F2" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQL routine body</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL routine body</em></span>
+</p>
+<p>The routine body of a an SQL routine consists of an
+    statement.</p>
+<p>
+<code class="literal">&lt;SQL routine body&gt; ::= &lt;SQL procedure
+    statement&gt;</code>
+</p>
+<a name="N12903" class="indexterm"></a>
+<p>
+<span class="bold"><strong>EXTERNAL NAME</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>external body reference</em></span>
+</p>
+<p>External name specifies the qualified name of the Java method
+    associated with this routine. Early releases of HyperSQL 2.0 only supports
+    Java methods within the classpath. The <code class="literal">&lt;external Java
+    reference string&gt;</code> is a quoted string which starts with
+    CLASSPATH: and is followed by the Java package, class and method names
+    separated with dots. HyperSQL does not currently support the optional
+    <code class="literal">&lt;Java parameter declaration list&gt;</code>.</p>
+<p>
+<code class="literal">&lt;external body reference&gt; ::= EXTERNAL NAME
+    &lt;external Java reference string&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;external Java reference string&gt; ::= &lt;jar and
+    class name&gt; &lt;period&gt; &lt;Java method name&gt; [ &lt;Java
+    parameter declaration list&gt; ]</code>
+</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1291D"></a>Routine Characteristics</h3>
+</div>
+</div>
+</div>
+<p>The <code class="literal">&lt;routine characteristics&gt;</code> clause
+      covers several sub-clauses</p>
+<p>
+<code class="literal">&lt;routine characteristics&gt; ::= [ &lt;routine
+      characteristic&gt;... ]</code>
+</p>
+<p>
+<code class="literal">&lt;routine characteristic&gt; ::= &lt;language
+      clause&gt; | &lt;parameter style clause&gt; | SPECIFIC &lt;specific
+      name&gt; | &lt;deterministic characteristic&gt; | &lt;SQL-data access
+      indication&gt; | &lt;null-call clause&gt; | &lt;returned result sets
+      characteristic&gt; | &lt;savepoint level
+      indication&gt;</code>
+</p>
+<a name="N1292B" class="indexterm"></a>
+<p>
+<span class="bold"><strong>LANGUAGE</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>language clause</em></span>
+</p>
+<p>The <code class="literal">&lt;language clause&gt;</code> refers to the
+      language in which the routine body is written. It is either SQL or Java.
+      The default is SQL, so JAVA must be specified for SQL/JRT
+      routines.</p>
+<p>
+<code class="literal">&lt;language clause&gt; ::= LANGUAGE &lt;language
+      name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;language name&gt; ::= SQL |
+      JAVA</code>
+</p>
+<p>The parameter style is not allowed for SQL routines. It is
+      optional for Java routines and, in HyperSQL, the only value allowed is
+      JAVA.</p>
+<p>
+<code class="literal">&lt;parameter style&gt; ::= JAVA</code>
+</p>
+<a name="N12947" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SPECIFIC NAME</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>specific name</em></span>
+</p>
+<p>The <code class="literal">SPECIFIC &lt;specific name&gt;</code> clause is
+      optional but the engine will creates an automatic name if it is not
+      present. When there are several versions of the same routine, the
+      <code class="literal">&lt;specific name&gt;</code> is used in schema manipulation
+      statements to drop or alter a specific version. The
+      <code class="literal">&lt;specific name&gt;</code> is a user-defined name. It
+      applies to both functions and procedures. In the examples below, a
+      specific name is specified for each function.</p>
+<pre class="programlisting">CREATE FUNCTION an_hour_before_or_now(t TIMESTAMP)
+  RETURNS TIMESTAMP
+  NO SQL
+  LANGUAGE JAVA PARAMETER STYLE JAVA
+  SPECIFIC an_hour_before_or_now_with_timestamp
+  EXTERNAL NAME 'CLASSPATH:org.npo.lib.nowLessAnHour'
+
+CREATE FUNCTION an_hour_before_max (e_type INT)
+  RETURNS TIMESTAMP SPECIFIC an_hour_before_max_with_int
+  RETURN (SELECT MAX(event_time) FROM atable WHERE event_type = e_type) - 1 HOUR
+
+</pre>
+<a name="N12960" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DETERMINISTIC</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>deterministic characteristic</em></span>
+</p>
+<p>The <code class="literal">&lt;deterministic characteristic&gt;</code> clause
+      indicates that a routine is deterministic or not. Deterministic means
+      the routine does not reference random values, external variables, or
+      time of invocation. The default is <code class="literal">NOT DETERMINISTIC</code>.
+      It is essential to declare this characteristics correctly for an SQL/JRT
+      routine, as the engine does not know the contents of the Java code,
+      which could include calls to methods returning random or time sensitive
+      values.</p>
+<p>
+<code class="literal">&lt;deterministic characteristic&gt; ::= DETERMINISTIC
+      | NOT DETERMINISTIC</code>
+</p>
+<a name="N12977" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SQL DATA access</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>SQL DATA access characteristic</em></span>
+</p>
+<p>The <code class="literal">&lt;SQL-data access indication&gt;</code> &nbsp;clause
+      indicates the extent to which a routine interacts with the database or
+      the data stored in the database tables (SQL data). &nbsp;NO SQL means no SQL
+      command is issued in the routine body and can be used only for SQL/JRT
+      functions. <code class="literal">CONTAINS SQL</code> means some SQL commands are
+      used, but they do not read or modify the SQL data. <code class="literal">READS SQL
+      DATA</code> and <code class="literal">MODIFIES SQL DATA</code> are self
+      explanatory.</p>
+<p>
+<code class="literal">&lt;SQL-data access indication&gt; ::= NO SQL |
+      CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA</code>
+</p>
+<a name="N12994" class="indexterm"></a>
+<p>
+<span class="bold"><strong>NULL INPUT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>null call clause</em></span>
+</p>
+<p>Null Arguments</p>
+<p>The <code class="literal">&lt;null-call clause&gt;</code> is used only for
+      functions. If a function returns NULL when any of the calling arguments
+      is null, then by specifying <code class="literal">RETURNS NULL ON NULL
+      INPUT</code>, calls to the function are known to be redundant and do
+      not take place when an argument is null. This simplifies the coding of
+      the SQL/JRT Java methods and improves performance at the same
+      time.</p>
+<p>
+<code class="literal">&lt;null-call clause&gt; ::= RETURNS NULL ON NULL
+      INPUT | CALLED ON NULL INPUT</code>
+</p>
+<a name="N129AD" class="indexterm"></a>
+<p>
+<span class="bold"><strong>SAVEPOINT LEVEL</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>transaction impact</em></span>
+</p>
+<p>The <code class="literal">&lt;savepoint level indication&gt;</code> is used
+      only for procedures and refers to the visibility of existing savepoints
+      within the body of the procedure. If <code class="literal">NEW SAVEPOINT
+      LEVEL</code> is specified, savepoints that have been declared prior
+      to calling the procedure become invisible within the body of the
+      procedure. HyperSQL&rsquo;s implementation accepts only <code class="literal">NEW SAVEPOINT
+      LEVEL</code>, which must be specified.</p>
+<p>
+<code class="literal">&lt;savepoint level indication&gt; ::= NEW SAVEPOINT
+      LEVEL | OLD SAVEPOINT LEVEL</code>
+</p>
+<a name="N129C7" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DYNAMIC RESULT SETS</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>returned result sets
+      characteristic</em></span>
+</p>
+<p>The <code class="literal">&lt;returned result sets characteristic&gt;</code>
+      is used only for SQL/PSM procedures. The maximum number of result sets
+      that a procedure may return can be specified with the clause below. The
+      default is zero. Details are discussed in the previous sections.</p>
+<p>
+<code class="literal">&lt;returned result sets characteristic&gt; ::=
+      DYNAMIC RESULT SETS &lt;maximum returned result
+      sets&gt;</code>
+</p>
+</div>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="dataaccess-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="triggers-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;7.&nbsp;Data Access and Change&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;9.&nbsp;Triggers</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/texttables-chapt.html b/doc/guide/texttables-chapt.html
new file mode 100644
index 0000000..0ad3fcf
--- /dev/null
+++ b/doc/guide/texttables-chapt.html
@@ -0,0 +1,599 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;5.&nbsp;Text Tables</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HyperSQL, HSQLDB, SQL, Text, Tables">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="databaseobjects-chapt.html" title="Chapter&nbsp;4.&nbsp;Schemas and Database Objects">
+<link rel="next" href="accesscontrol-chapt.html" title="Chapter&nbsp;6.&nbsp;Access Control">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="databaseobjects-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;5.&nbsp;Text Tables</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="accesscontrol-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;4.&nbsp;Schemas and Database Objects&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;6.&nbsp;Access Control</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="texttables-chapt"></a>Chapter&nbsp;5.&nbsp;Text Tables</h2>
+</div>
+<div>
+<h3 class="subtitle">
+<i>Text Tables as a Standard Feature of Hsqldb</i>
+</h3>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Bob</span> <span class="surname">Preston</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3601 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N115AC"></a>
+<p>Copyright 2002-2010 Bob Preston and Fred Toussi. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license. Additional permission is granted to the
+      HSQL Development Group to distribute this document with or without
+      alterations under the terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-05-31 20:17:47 -0400 (Mon, 31 May 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="texttables-chapt.html#texttables_overview-sect">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#texttables_impl-sect">The Implementation</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N115BF">Definition of Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N115CF">Scope and Reassignment</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N115E5">Null Values in Columns of Text Tables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N115EF">Configuration</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#disconnecting_text_tables">Disconnecting Text Tables</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="texttables-chapt.html#texttables_issues-sect">Text File Usage</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#texttables_globalprops-sect">Text File Global Properties</a></span>
+</dt>
+<dt>
+<span class="section"><a href="texttables-chapt.html#N116E4">Transactions</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="texttables_overview-sect"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>Text Table support for HSQLDB was originally developed by Bob
+    Preston independently from the Project. Subsequently Bob joined the
+    Project and incorporated this feature into version 1.7.0, with a number of
+    enhancements, especially the use of conventional SQL commands for
+    specifying the files used for Text Tables.</p>
+<p>In a nutshell, Text Tables are CSV or other delimited files treated
+    as SQL tables. Any ordinary CSV or other delimited file can be used. The
+    full range of SQL queries can be performed on these files, including
+    SELECT, INSERT, UPDATE and DELETE. Indexes and unique constraints can be
+    set up, and foreign key constraints can be used to enforce referential
+    integrity between Text Tables themselves or with conventional
+    tables.</p>
+<p>The delimited file can be created by the engine, or an existing file
+    can be used.</p>
+<p>HyperSQL with Text Table support is the only comprehensive solution
+    that employs the power of SQL and the universal reach of JDBC to handle
+    data stored in text files.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="texttables_impl-sect"></a>The Implementation</h2>
+</div>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N115BF"></a>Definition of Tables</h3>
+</div>
+</div>
+</div>
+<p>Text Tables are defined similarly to conventional tables with the
+      added TEXT keyword:</p>
+<pre class="programlisting">    CREATE TEXT TABLE &lt;tablename&gt; (&lt;column definition&gt; [&lt;constraint definition&gt;])</pre>
+<p>The table is at first empty and cannot be written to. An
+      additional SET command specifies the file and the separator character
+      that the Text table uses:</p>
+<pre class="programlisting">   SET TABLE &lt;tablename&gt; SOURCE &lt;quoted_filename_and_options&gt; [DESC]</pre>
+<p>Text Tables cannot be created in <em class="glossterm">mem:</em>
+      (all-in-memory) databases (databases that have no script file).</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N115CF"></a>Scope and Reassignment</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>A Text table without a file assigned to it is READ ONLY and
+          EMPTY.</p>
+</li>
+<li>
+<p>Reassigning a Text Table definition to a new file has
+          implications in the following areas:</p>
+<div class="orderedlist">
+<ol type="1">
+<li>
+<p>The user is required to be an administrator.</p>
+</li>
+<li>
+<p>Existing transactions are committed at this point.</p>
+</li>
+<li>
+<p>Constraints, including foreign keys referencing this
+              table, are kept intact. It is the responsibility of the
+              administrator to ensure their integrity.</p>
+</li>
+</ol>
+</div>
+<p>The new source file is scanned and indexes are built when it
+          is assigned to the table. At this point any violation of NOT NULL,
+          UNIQUE or PRIMARY KEY constraints are caught and the assignment is
+          aborted. However, foreign key constraints are not checked at the
+          time of assignment or reassignment of the source file.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N115E5"></a>Null Values in Columns of Text Tables</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Empty fields are treated as NULL. These are fields where there
+          is nothing or just spaces between the separators.</p>
+</li>
+<li>
+<p>Quoted empty strings are treated as empty strings.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N115EF"></a>Configuration</h3>
+</div>
+</div>
+</div>
+<p>The default field separator is a comma (,). A different field
+      separator can be specified within the SET TABLE SOURCE statement. For
+      example, to change the field separator for the table mytable to a
+      vertical bar, place the following in the SET TABLE SOURCE statement, for
+      example:</p>
+<div class="informalexample">
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile;fs=|"</pre>
+</div>
+<p>Since HSQLDB treats CHAR and VARCHAR strings the same, the ability
+      to assign a different separator to the latter is provided. When a
+      different separator is assigned to a VARCHAR, it will terminate any CSV
+      field of that type. For example, if the first field is CHAR, and the
+      second field VARCHAR, and the separator fs has been defined as the pipe
+      (|) and vs as the period (.) then the data in the CSV file for a row
+      will look like:</p>
+<pre class="screen">    First field data|Second field data.Third field data</pre>
+<p>This facility in effect offers an extra, special separator which
+      can be used in addition to the global separator. The following example
+      shows how to change the default separator to the pipe (|), VARCHAR
+      separator to the period (.) within a SET TABLE SOURCE statement:</p>
+<div class="informalexample">
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile;fs=|;vs=."</pre>
+</div>
+<p>HSQLDB also recognises the following special indicators for
+      separators:</p>
+<div class="variablelist">
+<p class="title">
+<b>special indicators for separators</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">\semi</span>
+</p>
+</td><td>
+<p>semicolon</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\quote</span>
+</p>
+</td><td>
+<p>single-quote</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\space</span>
+</p>
+</td><td>
+<p>space character</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\apos</span>
+</p>
+</td><td>
+<p>apostrophe</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\n</span>
+</p>
+</td><td>
+<p>newline - Used as an end anchor (like $ in regular
+            expressions)</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\r</span>
+</p>
+</td><td>
+<p>carriage return</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\t</span>
+</p>
+</td><td>
+<p>tab</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\\</span>
+</p>
+</td><td>
+<p>backslash</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\u####</span>
+</p>
+</td><td>
+<p>a Unicode character specified in hexadecimal</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>Furthermore, HSQLDB provides csv file support with three
+      additional boolean options: <code class="varname">ignore_first</code>,
+      <code class="varname">quoted</code> and <code class="varname">all_quoted</code>. The
+      <code class="varname">ignore_first</code> option (default false) tells HSQLDB to
+      ignore the first line in a file. This option is used when the first line
+      of the file contains column headings. The <code class="varname">all_quoted</code>
+      option (default false) tells the program that it should use quotes
+      around all character fields when writing to the source file. The
+      <code class="varname">quoted</code> option (default true) uses quotes only when
+      necessary to distinguish a field that contains the separator character.
+      It can be set to false to prevent the use of quoting altogether and
+      treat quote characters as normal characters. These options may be
+      specified within the <code class="literal">SET TABLE SOURCE</code>
+      statement:</p>
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile;ignore_first=true;all_quoted=true"</pre>
+<p>When the default options <code class="literal">all_quoted=</code>
+      <code class="literal">false</code> and <code class="literal">quoted=true</code> are in
+      force, fields that are written to a line of the csv file will be quoted
+      only if they contain the separator or the quote character. The quote
+      character is doubled when used inside a string. When
+      <code class="literal">all_quoted=false</code> and <code class="literal">quoted=false</code>
+      the quote character is not doubled. With this option, it is not possible
+      to insert any string containing the separator into the table, as it
+      would become impossible to distinguish from a separator. While reading
+      an existing data source file, the program treats each individual field
+      separately. It determines that a field is quoted only if the first
+      character is the quote character. It interprets the rest of the field on
+      this basis.</p>
+<p>The character encoding for the source file is<code class="literal"> ASCII
+      </code>by default. To support UNICODE or source files prepared with
+      different encodings this can be changed to <code class="literal">UTF-8</code> or
+      any other encoding. The default is <code class="literal">encoding=ASCII </code>and
+      the option <code class="literal">encoding=UTF-8</code> or other supported
+      encodings can be used.</p>
+<p>Finally, HSQLDB provides the ability to read a text file as READ
+      ONLY, by placing the keyword "DESC" at the end of the SET TABLE SOURCE
+      statement:</p>
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile" DESC</pre>
+<p>Text table source files are cached in memory. The maximum number
+      of rows of data that are in memory at any time is controlled by the
+      <code class="varname">textdb.cache_scale</code> property. The default value for
+      <code class="varname">textdb.cache_scale</code> is 10 and can be changed by
+      setting the property in the .properties file for the database. The
+      number of rows in memory is calculated as 3*(2**scale), which translates
+      to 3072 rows for the default textdb.cache_scale setting (10). The
+      property can also be set for individual text tables:</p>
+<pre class="programlisting">    SET TABLE mytable SOURCE "myfile;ignore_first=true;all_quoted=true;cache_scale=12"</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="disconnecting_text_tables"></a>Disconnecting Text Tables</h3>
+</div>
+</div>
+</div>
+<p>Text tables may be <em class="glossterm">disconnected</em> from their
+      underlying data source, i.e. the text file.</p>
+<p>You can explicitly disconnect a text table from its file by
+      issuing the following statement: <pre class="programlisting">    SET TABLE mytable SOURCE OFF</pre>
+</p>
+<p>Subsequently, <code class="literal">mytable</code> will be empty and
+      read-only. However, the data source description will be preserved, and
+      the table can be re-connected to it with <pre class="programlisting">    SET TABLE mytable SOURCE ON</pre>
+</p>
+<p>When a database is opened, if the source file for an existing text
+      table is missing the table remains disconnected from its data source,
+      but the source description is preserved. This allows the missing source
+      file to be added to the directory and the table re-connected to it with
+      the above command.</p>
+<p>Disconnecting text tables from their source has several uses.
+      While disconnected, the text source can be edited outside HSQLDB
+      provided data integrity is respected. When large text sources are used,
+      and several constraints or indexes need to be created on the table, it
+      is possible to disconnect the source during the creation of constraints
+      and indexes and reduce the time it takes to perform the
+      operation.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="texttables_issues-sect"></a>Text File Usage</h2>
+</div>
+</div>
+</div>
+<p>The following information applies to the usage of text
+    tables.</p>
+<div class="itemizedlist">
+<p class="title">
+<b>Text File Issues</b>
+</p>
+<ul type="disc">
+<li>
+<p>File locations are restricted to below the directory that
+        contains the database, unless the
+        <code class="varname">textdb.allow_full_path</code> property is set true as a
+        Java system property. This feature is for security, otherwise an admin
+        database user may be able to open random files.</p>
+</li>
+<li>
+<p>Blank lines are allowed anywhere in the text file, and are
+        ignored.</p>
+</li>
+<li>
+<p>It is possible to define a primary key, identity column, unique,
+        foreign key and check constraints for text tables.</p>
+</li>
+<li>
+<p>When a table source file is used with the<code class="literal">
+        ignore_first=true </code>option, the first, ignored line is
+        replaced with a blank line after a SHUTDOWN COMPACT, unless the SOURCE
+        HEADER statement has been used.</p>
+</li>
+<li>
+<p>An existing table source file may include CHARACTER fields that
+        do not begin with the quote character but contain instances of the
+        quote character. These fields are read as literal strings.
+        Alternatively, if any field begins with the quote character, then it
+        is interpreted as a quoted string that should end with the quote
+        character and any instances of the quote character within the string
+        is doubled. When any field containing the quote character or the
+        separator is written out to the source file by the program, the field
+        is enclosed in quote character and any instance of the quote character
+        inside the field is doubled.</p>
+</li>
+<li>
+<p>Inserts or updates of CHARACTER type field values are allowed
+        with strings that contains the linefeed or the carriage return
+        character. This feature is disabled when both quoted and all_quoted
+        properties are false.</p>
+</li>
+<li>
+<p>ALTER TABLE commands that add or drop columns or constraints
+        (apart from check constraints) are not supported with text tables that
+        are connected to a source. First use the SET TABLE &lt;name&gt; SOURCE
+        OFF, make the changes, then turn the source ON.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="texttables_globalprops-sect"></a>Text File Global Properties</h2>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<p class="title">
+<b>Complete list of supported global properties in *.properties
+      files</b>
+</p>
+<ul type="disc">
+<li>
+<p>
+<code class="varname">textdb.fs</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.vs</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.quoted</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.all_quoted</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.ignore_first</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.encoding</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.cache_scale</code>
+</p>
+</li>
+<li>
+<p>
+<code class="varname">textdb.allow_full_path</code>
+</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N116E4"></a>Transactions</h2>
+</div>
+</div>
+</div>
+<p>Text tables fully support transactions. New or changed rows that
+    have not been committed are not updated in the source file. Therefore the
+    source file always contains committed rows.</p>
+<p>However, text tables are not as resilient to machine crashes as
+    other types of tables. If the crash happens while the text source is being
+    written to, the text source may contain only some of the changes made
+    during a committed transaction. With other types of tables, additional
+    mechanisms ensure the integrity of the data and this situation will not
+    arise.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="databaseobjects-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="accesscontrol-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;4.&nbsp;Schemas and Database Objects&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;6.&nbsp;Access Control</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/triggers-chapt.html b/doc/guide/triggers-chapt.html
new file mode 100644
index 0000000..750f419
--- /dev/null
+++ b/doc/guide/triggers-chapt.html
@@ -0,0 +1,597 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;9.&nbsp;Triggers</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, HyperSQL, SQL">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="sqlroutines-chapt.html" title="Chapter&nbsp;8.&nbsp;SQL-Invoked Routines">
+<link rel="next" href="builtinfunctions-chapt.html" title="Chapter&nbsp;10.&nbsp;Built In Functions">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="sqlroutines-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;9.&nbsp;Triggers</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="builtinfunctions-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;8.&nbsp;SQL-Invoked Routines&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;10.&nbsp;Built In Functions</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="triggers-chapt"></a>Chapter&nbsp;9.&nbsp;Triggers</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3042 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N129FF"></a>
+<p>Copyright 2010 Fred Toussi. Permission is granted to distribute
+      this document without any alteration under the terms of the HSQLDB
+      license. Additional permission is granted to the HSQL Development Group
+      to distribute this document with or without alterations under the terms
+      of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2009-07-14 17:55:19 +0100 (Tue, 14 Jul 2009) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A02">Overview</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A26">Trigger Properties</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A2B">Trigger Event</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A34">Granularity</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A43">Trigger Action Time</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A50">References to Rows</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A55">Trigger Condition</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A5C">Trigger Action in SQL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A6B">Trigger Action in Java</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="triggers-chapt.html#N12A85">Trigger Creation</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12A02"></a>Overview</h2>
+</div>
+</div>
+</div>
+<p>Trigger functionality first appeared in SQL:1999. Triggers embody
+    the <span class="emphasis"><em>live database</em></span> concept, where changes in SQL data
+    can be monitored and acted upon. This means each time a DELETE, UPDATE or
+    INSERT is performed, additional actions are taken by the declared
+    triggers. SQL Standard triggers are <em class="glossterm">imperative</em>
+    while the <em class="glossterm">relational</em> aspects of SQL are
+    <em class="glossterm">declarative</em>. Triggers allow performing an arbitrary
+    transformation of data that is being updated or inserted, or to prevent
+    insert, updated or deletes, or to perform additional operations.</p>
+<p>Some bad examples of SQL triggers in effect enforce an &ldquo;integrity
+    constraint&rdquo; which would better be expressed as a CHECK constraint. A
+    trigger that causes an exception if the value inserted in a column is
+    negative is such an example. A check constraint that declares
+    <code class="literal">CHECK VALUE &gt;= 0</code> (declarative) is a better way of
+    expressing an integrity constraint than a trigger that throws an exception
+    if the same condition is false.</p>
+<p>Usage constraints cannot always be expressed by SQL&rsquo;s integrity
+    constraint statements. Triggers can enforce these constraints. For
+    example, it is may be possible to write a check constraint that prevents
+    data from being added, or modified on weekends. But it is not possible to
+    use a check constraint to prevent deletes. A trigger can be used to
+    enforce the time when each operation is allowed.</p>
+<p>A trigger can modify the values that are inserted into the
+    database, instead of rejecting them. For example, a badly formatted string
+    can be cleaned up by a trigger before INSERT.</p>
+<p>Triggers can also perform additional data changes, for example
+    inserting an additional row into a different table for data
+    audits.</p>
+<p>A trigger is declared to activate when an UPDATE, INSERT or
+    DELETE action is performed on a table. These actions may be direct or
+    indirect. Indirect actions may arise from CASCADE actions of FOREIGN KEY
+    constraints, or from data change statements performed on a VIEW that is
+    based on the table that in.</p>
+<p>It is possible to declare multiple triggers on a single table.
+    The triggers activate one by one according to the order in which they were
+    defined.</p>
+<p>A row level trigger allows access to the deleted or inserted
+    rows. For UPDATE actions there is both an old and new version of each row.
+    A trigger can be specified to activate before or after the action has been
+    performed. Triggers that are performed after the action cannot modify the
+    rows that have been modified. These triggers can perform other actions,
+    such as inserting rows into other tables. Triggers that are performed
+    before the action can modify the inserted or updated rows but not the
+    deleted rows.</p>
+<p>A TRIGGER that is declared on a VIEW, is an INSTEAD OF trigger.
+    This term means when an INSERT, UPDATE or DELETE statement is executed,
+    the trigger action is all that is performed, and no further data change
+    takes place on the VIEW. The trigger action can include all the statements
+    that are necessary to change the data in the tables that underlie the
+    VIEW. With the use of INSTEAD OF triggers a read-only view can effectively
+    become updatable or insertable-into.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12A26"></a>Trigger Properties</h2>
+</div>
+</div>
+</div>
+<p>A trigger is declared on a specific table or view. Various trigger
+    properties determine when the trigger is executed and how.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A2B"></a>Trigger Event</h3>
+</div>
+</div>
+</div>
+<p>The trigger event specifies the type of SQL statement that causes
+      the trigger to execute. Each trigger is specified to execute when an
+      INSERT, DELETE or UPDATE takes place.</p>
+<p>The event can be filtered by two separate means. For all triggers,
+      the WHEN clause can specify a condition against the rows that are the
+      subject of the trigger, together with the data in the database. For
+      example, a trigger can activate when the size of a table becomes larger
+      than a certain amount. Or it can activate when the values in the rows
+      being modified satisfy certain conditions.</p>
+<p>An UPDATE trigger can be declared to execute only when certain
+      columns are the subject of an update statement. For example, a trigger
+      declared as AFTER UPDATE OF (datecolumn) will activate only when the
+      UPDATE statement that is executed includes the column, datecolumn, as
+      one of the columns specified in its SET statements.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A34"></a>Granularity</h3>
+</div>
+</div>
+</div>
+<p>A statement level trigger is performed once for the executed SQL
+      statement and is declared as FOR EACH STATEMENT.</p>
+<p>A row level trigger is performed once for each row that is
+      modified during the execution of an SQL statement and is declared as FOR
+      EACH ROW. Note that an SQL statement can INSERT, UPDATE or DELETE zero
+      or more rows.</p>
+<p>If a statement does not apply to any row, then the trigger is not
+      executed.</p>
+<p>If FOR EACH ROW or FOR EACH STATEMENT is not specified, then the
+      default is FOR EACH STATEMENT.</p>
+<p>The granularity dictates whether the REFERENCING clause can
+      specify OLD ROW, NEW ROW, or OLD TABLE, NEW TABLE.</p>
+<p>A trigger declared as FOR EACH STATEMENT can only be an AFTER
+      trigger.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A43"></a>Trigger Action Time</h3>
+</div>
+</div>
+</div>
+<p>A trigger is executed BEFORE, AFTER or INSTEAD OF the trigger
+      event.</p>
+<p>INSTEAD OF triggers are allowed only when the trigger is declared
+      on a VIEW. With this type of trigger, the event (SQL statement) itself
+      is not executed, only the trigger.</p>
+<p>BEFORE or AFTER triggers are executed just before or just after
+      the execution of the event. For example, just before a row is inserted
+      into a table, the BEFORE trigger is activated, and just after the row is
+      inserted, the AFTER trigger is executed.</p>
+<p>BEFORE triggers can modify the row that is being inserted or
+      updated. AFTER triggers cannot modify rows. They are usually used to
+      perform additional operations, such as inserting rows into other
+      tables.</p>
+<p>A trigger declared as FOR EACH STATEMENT can only be an AFTER
+      trigger.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A50"></a>References to Rows</h3>
+</div>
+</div>
+</div>
+<p>If the old rows or new rows are referenced in the SQL statements
+      in the trigger action, they must have names. The REFERENCING clause is
+      used to give names to the old and new rows. The clause, REFERENCING OLD
+      | NEW TABLE is used for statement level triggers. The clause,
+      REFERENCING OLD | NEW ROW is used for row level triggers. If the old
+      rows or new rows are referenced in the SQL statements in the trigger
+      action, they must have names. In the SQL statements, the columns of the
+      old or new rows are qualified with the specified names.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A55"></a>Trigger Condition</h3>
+</div>
+</div>
+</div>
+<p>The WHEN clause can specify a condition for the columns of the row
+      that is being changed. Using this clause you can simply avoid
+      unnecessary trigger activation for rows that do not need it.</p>
+<p>For UPDATE trigger, you can specify a list of columns of the
+      table. If a list of columns is specified, then if the UPDATE statement
+      does not change the columns with SET clauses, then the trigger is not
+      activated at all.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A5C"></a>Trigger Action in SQL</h3>
+</div>
+</div>
+</div>
+<p>The trigger action specifies what the trigger does when it is
+      activated. This is usually written as one or more SQL statements.</p>
+<p>When a row level trigger is activated, there is an OLD ROW, or a
+      NEW ROW, or both. An INSERT statement supplies a NEW ROW row to be
+      inserted into a table. A DELETE statement supplied an OLD ROW be
+      deleted. An UPDATE statement supplies both OLD ROW and NEW ROW that
+      represent the updated rows before and after the update. The REFERENCING
+      clause gives names to these rows, so that the rows can be referenced in
+      the trigger action.</p>
+<p>In the example below, a name is given to the NEW ROW and it is
+      used both in the WHEN clause and in the trigger action SQL to insert a
+      row into a triglog table after each row insert into the testtrig
+      table.</p>
+<pre class="programlisting">create trigger trig after insert on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.id &gt; 1)
+   insert into triglog values (newrow.id, newrow.data, 'inserted')
+</pre>
+<p>In the example blow, the trigger code modifies the updated data if
+      a condition is true. This type of trigger is useful when the application
+      does not perform the necessary checks and modifications to data.</p>
+<pre class="programlisting">create trigger t before update on customer
+   referencing new as newrow for each row
+   begin atomic
+   if length(newrow.firstname ) &gt; 10 then
+   set newrow.firstname = lower(newrow.firstname);
+   end if;
+   end
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N12A6B"></a>Trigger Action in Java</h3>
+</div>
+</div>
+</div>
+<p>A trigger action can be written as a Java class that implements
+      the org.hsqldb.Trigger interface. This interface has a single method
+      which is called when the trigger is activated, either before or after
+      the event. When the method is called by the engine, it supplies the name
+      of the trigger (as name argument), the name of the table (as table
+      argument), the OLD ROW (as row1 argument) and the NEW ROW (as row2
+      argument). The row1 argument is null for row level INSERT triggers. The
+      row2 argument is null for row level DELETE triggers. For table level
+      triggers, both arguments are null (that is, there is no access to the
+      data). The triggerType argument is one of the constants in the
+      org.hsqldb.Trigger interface which indicate the type of trigger, for
+      example, INSERT_BEFORE_ROW or UPDATE_AFTER_ROW.</p>
+<p>The Java class for the trigger can be reused for several triggers
+      on different tables. The method code can distinguish between the
+      different tables and triggers using the supplied arguments and take
+      appropriate action.</p>
+<pre class="programlisting">    fire (int triggerType, String name, String table, Object row1[], Object row2[])
+</pre>
+<p>The Java method for a synchronous trigger (see below) can modify
+      the values in row2 in a BEFORE trigger. Such modifications are reflected
+      in the row that is being inserted or updated. Any other modifications
+      are ignored by the engine.</p>
+<p>A Java trigger that uses an instance of
+      <code class="classname">org.hsqldb.Trigger</code> has two forms, synchronous, or
+      asynchronous (immediate or queued). By default, or when QUEUE 0 is
+      specified, the action is performed immediately by calling the Java
+      method. This is similar to SQL trigger actions. When QUEUE n is
+      specified with n larger than 0, the engine uses a separate thread to
+      execute the Java method, using a queue with the size n. For certain
+      applications, such as real-time systems this allows asynchronous
+      notifications to be sent by the trigger event, without introducing
+      delays in the engine. With asynchronous triggers, an extra parameter,
+      NOWAIT can be used in trigger definition. This overcomes the queue full
+      condition. In this mode, old calls that are still in the queue are
+      discarded one by one and replaced with new calls.</p>
+<p>Java triggers can modify the row data. They should not be used to
+      modify the database, e.g. insert new rows, etc.</p>
+<p>For sample trigger classes and test code see,
+      org.hsqldb.sample.TriggerSample, org.hsqldb.test.TestTriggers,
+      org.hsqldb.test.TriggerClass and the associated text script
+      TestTriggers.txt in /testrun/hsqldb/ directory. In the example below,
+      the trigger is activated only if the update statement includes SET
+      clauses that modify any of the specified columns (c1, c2, c3).
+      Furthermore, the trigger is not activated if the c2 column in the
+      updated row is null.</p>
+<pre class="programlisting">create trigger trigbur before update of c1, c2, c3 on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.c2 is not null)
+   call "org.hsqldb.test.TriggerClass"
+</pre>
+<p>Java functions can be called from an SQL trigger. So it is
+      possible to define the Java function to perform any external
+      communication that are necessary for the trigger, and use SQL code for
+      checks and alterations to data.</p>
+<pre class="programlisting">create trigger t before update on customer
+   referencing new as newrow for each row
+   begin atomic
+   if length(newrow.firstname ) &gt; 10 then
+   call my_java_function(newrow.firstname, newrow.lastname);
+   end if;
+   end
+</pre>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N12A85"></a>Trigger Creation</h2>
+</div>
+</div>
+</div>
+<a name="N12A88" class="indexterm"></a>
+<p>
+<span class="bold"><strong>CREATE TRIGGER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>trigger definition</em></span>
+</p>
+<p>
+<code class="literal">&lt;trigger definition&gt; ::= CREATE TRIGGER
+    &lt;trigger name&gt; &lt;trigger action time&gt; &lt;trigger event&gt; ON
+    &lt;table name&gt; [BEFORE &lt;other trigger name&gt;] [ REFERENCING
+    &lt;transition table or variable list&gt; ] &lt;triggered
+    action&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;trigger action time&gt; ::= BEFORE | AFTER | INSTEAD
+    OF</code>
+</p>
+<p>
+<code class="literal">&lt;trigger event&gt; ::= INSERT | DELETE | UPDATE [ OF
+    &lt;trigger column list&gt; ]</code>
+</p>
+<p>
+<code class="literal">&lt;trigger column list&gt; ::= &lt;column name
+    list&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered action&gt; ::= [ FOR EACH { ROW |
+    STATEMENT } ] [ &lt;triggered when clause&gt; ] &lt;triggered SQL
+    statement&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered when clause&gt; ::= WHEN &lt;left
+    paren&gt; &lt;search condition&gt; &lt;right paren&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;triggered SQL statement&gt; ::= &lt;SQL procedure
+    statement&gt; | BEGIN ATOMIC { &lt;SQL procedure statement&gt;
+    &lt;semicolon&gt; }... END | [QUEUE &lt;integer literal&gt;] [NOWAIT] CALL
+    &lt;HSQLDB trigger class FQN&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transition table or variable list&gt; ::=
+    &lt;transition table or variable&gt;...</code>
+</p>
+<p>
+<code class="literal">&lt;transition table or variable&gt; ::= OLD [ ROW ] [
+    AS ] &lt;old transition variable name&gt; | NEW [ ROW ] [ AS ] &lt;new
+    transition variable name&gt; | OLD TABLE [ AS ] &lt;old transition table
+    name&gt; | NEW TABLE [ AS ] &lt;new transition table
+    name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;old transition table name&gt; ::= &lt;transition
+    table name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;new transition table name&gt; ::= &lt;transition
+    table name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;transition table name&gt; ::=
+    &lt;identifier&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;old transition variable name&gt; ::= &lt;correlation
+    name&gt;</code>
+</p>
+<p>
+<code class="literal">&lt;new transition variable name&gt; ::= &lt;correlation
+    name&gt;</code>
+</p>
+<p>Trigger definition is a relatively complex statement. The
+    combination of <code class="literal">&lt;trigger action time&gt;</code> and
+    <code class="literal">&lt;trigger event&gt;</code> determines the type of the
+    trigger. Examples include BEFORE DELETE, AFTER UPDATE, INSTEAD OF INSERT.
+    If the optional <code class="literal">[ OF &lt;trigger column list&gt; ]</code> is
+    specified for an UPDATE trigger, then the trigger is activated only if one
+    of the columns that is in the <code class="literal">&lt;trigger column
+    list&gt;</code> is specified in the UPDATE statement that activates the
+    trigger.</p>
+<p>If a trigger is <code class="literal">FOR EACH ROW</code>, which is the
+    default option, then the trigger is activated for each row of the table
+    that is affected by the execution of an SQL statement. Otherwise, it is
+    activated once only per statement execution. In the first case, there is a
+    before and after state for each row. For UPDATE triggers, both before and
+    after states exist, representing the row before the update, and after the
+    update. For DELETE, triggers, there is only a before state. For INSERT
+    triggers, there is only an after state. If a trigger is <code class="literal">FOR EACH
+    STATEMENT</code>, then a transient table is created containing all the
+    rows for the before state and another transient table is created for the
+    after state.</p>
+<p>The <code class="literal">[ REFERENCING &lt;transition table or variable&gt;
+    ]</code> is used to give a name to the before and after data row or
+    table. This name can be referenced in the <code class="literal">&lt;SQL procedure
+    statement&gt;</code> to access the data.</p>
+<p>The optional <code class="literal">&lt;triggered when clause&gt;</code> is
+    a search condition, similar to the search condition of a DELETE or UPDATE
+    statement. If the search condition is not TRUE for a row, then the trigger
+    is not activated for that row.</p>
+<p>The <code class="literal">&lt;SQL procedure statement&gt;</code> is limited
+    to INSERT, DELETE, UPDATE and MERGE statements.</p>
+<p>The <code class="literal">&lt;HSQLDB trigger class FQN&gt;</code> is a
+    delimited identifer that contains the fully qualified name of a Java class
+    that implements the <code class="classname">org.hsqldb.Trigger</code>
+    interface.</p>
+<p>Early releases of HyperSQL version 2.0 do not allow the use of
+    OLD TABLE or NEW TABLE in statement level triggers.</p>
+<a name="N12AF0" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRIGGERED SQL
+    STATEMENT</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>triggered SQL statement</em></span>
+</p>
+<p>
+<code class="literal">The &lt;triggered SQL statement&gt;</code> has three
+    forms.</p>
+<p>The first form is a single SQL procedure statement. This
+    statement can reference the OLD ROW and NEW ROW variables. For example, it
+    can reference these variables and insert a row into a separate
+    table.</p>
+<p>The second form is enclosed in a BEGIN ... END block and can
+    include one or more SQL procedure statements. In BEFORE triggers, you can
+    include SET statements to modify the inserted or updated rows. In AFTER
+    triggers, you can include INSERT, DELETE and UPDATE statements to change
+    the data in other database tables. SELECT and CALL statements are allowed
+    in BEFORE and AFTER triggers. CALL statements in BEFORE triggers should
+    not modify data.</p>
+<p>The third form specifies a call to a Java method.</p>
+<p>An example of a trigger with a block is given below. The block
+    can include elements discussed the <a class="link" href="sqlroutines-chapt.html" title="">SQL-Invoked Routines</a> chapter, including
+    local variables, loops and conditionals. You can also raise an exception
+    in such blocks in order to terminate the execution of the SQL statement
+    that caused the trigger to execute.</p>
+<pre class="programlisting">create trigger trig after insert on testtrig 
+   referencing new row as newrow
+   for each row when (newrow.id &gt; 1)
+   begin atomic
+   insert into triglog values (newrow.id, newrow.data, 'inserted');
+   /* more statements can be included */
+   end
+</pre>
+<p></p>
+<a name="N12B10" class="indexterm"></a>
+<p>
+<span class="bold"><strong>TRIGGER EXECUTION
+    ORDER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>trigger execution order</em></span>
+</p>
+<p>
+<code class="literal">&lt;trigger execution order&gt; ::= BEFORE &lt;other
+    trigger name&gt;</code>
+</p>
+<p>HyperSQL extends the SQL Standard to allow the order of execution
+    of a trigger to be specified by using [BEFORE &lt;other trigger name&gt;]
+    in the definition. The newly defined trigger will be executed before the
+    specified other trigger. If this clause is not used, the new trigger is
+    executed after all the previously defined triggers of the same scope
+    (BEFORE, AFTER, EACH ROW, EACH STATEMENT).</p>
+<a name="N12B21" class="indexterm"></a>
+<p>
+<span class="bold"><strong>DROP TRIGGER</strong></span>
+</p>
+<p>
+<span class="emphasis"><em>drop trigger statement</em></span>
+</p>
+<p>
+<code class="literal">&lt;drop trigger statement&gt; ::= DROP TRIGGER
+    &lt;trigger name&gt;</code>
+</p>
+<p>Destroy a trigger.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="sqlroutines-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="builtinfunctions-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;8.&nbsp;SQL-Invoked Routines&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;10.&nbsp;Built In Functions</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/guide/unix-chapt.html b/doc/guide/unix-chapt.html
new file mode 100644
index 0000000..fd85405
--- /dev/null
+++ b/doc/guide/unix-chapt.html
@@ -0,0 +1,1207 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;14.&nbsp;HyperSQL on UNIX</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HSQLDB, HyperSQL, UNIX, Linux, HOWTO">
+<meta name="keywords" content="Hsqldb, HyperSQL, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL User Guide">
+<link rel="up" href="index.html" title="HyperSQL User Guide">
+<link rel="prev" href="listeners-chapt.html" title="Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners">
+<link rel="next" href="lists-app.html" title="Appendix&nbsp;A.&nbsp;Lists of Keywords">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="listeners-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;14.&nbsp;HyperSQL on UNIX</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="lists-app.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Appendix&nbsp;A.&nbsp;Lists of Keywords</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="unix-chapt"></a>HyperSQL on UNIX</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>How to quickly get a HyperSQL (aka HSQLDB) Listener up and
+    running on UNIX, including Mac OS X</i>
+</h3>
+</div>
+<div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3360 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2009-12-16 10:03:31 -0500 (Wed, 16 Dec 2009) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_purpose-sect">Purpose</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_install-sect">Installation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_cat_setup-sect">Setting up Database Catalog and Listener</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_access-sect">Accessing your Database</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_addl_accts-sect">Create additional Accounts</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_shutdown-sect">Shutdown</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_daemon-sect">Running Hsqldb as a System Daemon</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="unix-chapt.html#N144B8">Portability of hsqldb init script</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#N144C2">Init script Setup Procedure</a></span>
+</dt>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_inittrouble-sect">Troubleshooting the Init
+      Script</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="unix-chapt.html#unix_upgrade-sect">Upgrading</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_purpose-sect"></a>Purpose</h2>
+</div>
+</div>
+</div>
+<p>This chapter explains how to quickly install, run, and use a
+    HyperSQL Listener (aka Server) on UNIX.</p>
+<p>Note that, unlike a traditional database server, there are many
+    use cases
+    where it makes sense to run HyperSQL without any listener. This type of
+    setup is called <em class="glossterm">in-process</em>, and is not covered
+    here, since there is no UNIX-specific setup in that case.</p>
+<p>I intend to cover what I think is the most common
+    UNIX setup: To run a multi-user, externally-accessible catalog with
+    permanent data persistence. (By the latter I mean that data is stored to
+    disk so that the catalog data will persist across process shutdowns and
+    startups). I also cover how to run the Listener as a system
+    daemon.</p>
+<p>When I give sample shell commands below, I use commands which
+    will work in Bourne-compatible shells, including Bash and Korn. Users who
+    insist on using the inferior C-shells will need to convert.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_install-sect"></a>Installation</h2>
+</div>
+</div>
+</div>
+<p>Go to <a class="link" href="http://sourceforge.net/projects/hsqldb" target="_top">http://sourceforge.net/projects/hsqldb</a> and click on
+    the "files" link. You want the current version. I can't be more specific
+    because SourceForge/Geeknet are likely to continue changing their
+    interface. See if there's a distribution for the current HSQLDB version in
+    the format that you want.</p>
+<p>If you want a binary package and we either don't provide it, or
+    you prefer somebody else's build, you should still find out the current
+    version of HyperSQL available at SourceForge. It's very
+    likely that you can find a binary package for your UNIX variant with your
+    OS distributor, <a class="link" href="http://www.jpackage.org/" target="_top">http://www.jpackage.org/</a>, <a class="link" href="http://sunfreeware.com/" target="_top">http://sunfreeware.com/</a>, etc. Nowadays, most UNIXes
+    have software package management systems which check Internet
+    repositories. Just search the repositories for "hsqldb" and "hypersql".
+    The challenge is to find an <span class="emphasis"><em>up-to-date</em></span> package. You
+    will get better features and support if you work with the current stable
+    release of HyperSQL. (In particular, HyperSQL version 2.0.0 added tons of
+    new features). Pay attention to what JVM versions your binary package
+    supports. Our builds (version 2.0 and later) document the Java version it
+    was built with in the file <code class="filename">doc/index.html</code>, but you
+    can't depend on this if somebody else assembled your distribution. Java
+    jar files are generally compatible with the same or greater major
+    versions. For example,if your <code class="filename">hsqldb.jar</code> was built
+    with Java 1.3.6-11, then it is compatible with Java versions 1.3.* and
+    greater.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>It could very well happen that some of the file formats which I
+      discuss below are not in fact offered. If so, then we have not gotten
+      around to building them.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>Binary installation depends on the package format that you
+    downloaded.</p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">Installing from a .pkg.Z file</span>
+</p>
+</td><td>
+<p>This package is only for use by a Solaris super-user. It's a
+          System V package. Download then uncompress the package with
+          uncompress or gunzip <div class="informalexample">
+<pre class="screen">    uncompress filename.pkg.Z</pre>
+</div> You can read about the package by running
+          <div class="informalexample">
+<pre class="screen">    pkginfo -l -d filename.pkg</pre>
+</div> Run pkgadd as root to install.</p>
+<div class="informalexample">
+<pre class="screen">
+    pkgadd -d filename.pkg</pre>
+</div>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Installing from a BSD Port or Package</span>
+</p>
+</td><td>You're on your own. I find everything much easier when I
+          install software to BSD without their package management
+          systems.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Installing from a .rpm file</span>
+</p>
+</td><td>
+<p>Just skip this section if you know how to install an RPM. If
+          you found the RPM using a software management system, then just have
+          it install it. The remainder of item explains a generic command-line
+          method which should work with any Linux variant. After you download
+          the rpm, you can read about it by running <div class="informalexample">
+<pre class="screen">    rpm -qip /path/to/file.rpm</pre>
+</div>
+</p>
+<p>Rpms can be installed or upgraded by running <div class="informalexample">
+<pre class="screen">    rpm -Uvh /path/to/file.rpm</pre>
+</div> as root. Suse users may want to keep Yast aware
+          of installed packages by running rpm through Yast: <code class="literal">yast2 -i
+          /path/to/file.rpm</code>.</p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Installing from a .zip file</span>
+</p>
+</td><td>
+<p>Extract the zip file in an ancestor directory of the new
+          HSQLDB home. You don't need to create the
+          <code class="varname">HSQLDB_HOME</code> directory because the extraction will
+          create a version-labelled directory, and the subdirectory "hsqldb".
+          This "hsqldb" directory is your <code class="varname">HSQLDB_HOME</code>, and
+          you can move it to wherever you wish. If you will be upgrading or
+          maintaining multiple versions of HyperSQL, you will want to retain
+          the version number in the directory tree somehow.</p>
+<div class="informalexample">
+<pre class="screen">    cd ancestor/of/new/hsqldb/home
+    unzip /path/to/file.zip</pre>
+</div>
+<p>All the files in the zip archive will be extracted to
+          underneath a new subdirectory named like
+          <code class="filename">hsqldb-2.0.2a/hsqldb</code>.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>Take a look at the files you installed. (Under
+    <code class="filename">hsqldb</code> for zip file installations. Otherwise, use the
+    utilities for your packaging system). The most important file of the
+    HyperSQL system is <code class="filename">hsqldb.jar</code>, which resides in the
+    subdirectory <code class="filename">lib</code>.
+    Depending on who built your distribution, your file name may have a
+    version label in it, like <code class="filename">hsqldb-1.2.3.4.jar</code>.
+    </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>For the purposes of this chapter, I define
+      <code class="varname">HSQLDB_HOME</code> to be the parent directory of the lib
+      directory that contains <code class="filename">hsqldb.jar</code>. E.g., if your
+      path to <code class="filename">hsqldb.jar</code> is
+      <code class="filename">/a/b/hsqldb/lib/hsqldb.jar</code>, then your
+      <code class="varname">HSQLDB_HOME</code> is
+      <code class="filename">/a/b/hsqldb</code>.</p>
+<p>Furthermore, unless I state otherwise, all local file paths
+      that I give are relative to the
+      <code class="varname">HSQLDB_HOME</code>.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>If the description of your distribution says that the
+    <code class="filename">hsqldb.jar</code> file will work for your Java version, then
+    you are finished with installation. Otherwise you need to build a new
+    <code class="filename">hsqldb.jar</code> file.</p>
+<p>If you followed the instructions above and you still don't know
+    what Java version your <code class="filename">hsqldb.jar</code> supports, then try
+    reading documentation files like <code class="filename">readme.txt</code>,
+    <code class="filename">README.TXT</code>, <code class="filename">INSTALL.txt</code> etc. (As
+    I said above, our newer distributions always document the Java version for
+    the build, in the file <code class="filename">doc/index.html</code>). If that still
+    doesn't help, then you can just try your <code class="filename">hsqldb.jar</code>
+    and see if it works, or build your own.</p>
+<p>To use the supplied <code class="filename">hsqldb.jar</code>, just skip to
+    the <a class="link" href="unix-chapt.html#unix_cat_setup-sect" title="Setting up a HyperSQL Persistent Database Catalog and a HyperSQL Network Listener"> next section of this
+    document</a>. Otherwise build a new
+    <code class="filename">hsqldb.jar</code>.</p>
+<div class="procedure">
+<a name="N1434E"></a>
+<p class="title">
+<b>Procedure&nbsp;14.1.&nbsp;Building hsqldb.jar</b>
+</p>
+<ol type="1">
+<li>
+<p>If you don't already have Ant, download the latest stable binary
+        version from <a class="link" href="http://ant.apache.org" target="_top">http://ant.apache.org</a>. cd to
+        where you want Ant to live, and extract from the archive with
+        <div class="informalexample">
+<pre class="screen">    unzip /path/to/file.zip</pre>
+</div>or<div class="informalexample">
+<pre class="screen">    tar -xzf /path/to/file.tar.gz</pre>
+</div>or<div class="informalexample">
+<pre class="screen">    bunzip2 -c /path/to/file.tar.bz2 | tar -xzf -</pre>
+</div> Everything will be installed into a new
+        subdirectory named <code class="filename">apache-ant- + version</code>. You can
+        rename the directory after the extraction if you wish.</p>
+</li>
+<li>
+<p>Set the environmental variable <code class="varname">JAVA_HOME</code> to
+        the base directory of your Java JRE or SDK, like <div class="informalexample">
+<pre class="screen">    export JAVA_HOME; JAVA_HOME=/usr/java/j2sdk1.4.0</pre>
+</div> The location is entirely dependent upon your
+        variety of UNIX. Sun's rpm distributions of Java normally install to
+        <code class="filename">/usr/java/something</code>. Sun's System V package
+        distributions of Java (including those that come with Solaris)
+        normally install to <code class="filename">/usr/something</code>, with a
+        sym-link from <code class="filename">/usr/java</code> to the default version
+        (so for Solaris you will usually set JAVA_HOME to
+        <code class="filename">/usr/java</code>).</p>
+</li>
+<li>
+<p>Remove the existing file <code class="varname">HSQLDB_HOME</code>
+        <code class="filename">/lib/hsqldb.jar</code>.</p>
+</li>
+<li>
+<p>cd to <code class="varname">HSQLDB_HOME</code><code class="filename">/build</code>.
+        Make sure that the bin directory under your Ant home is in your search
+        path. Run the following command. <div class="informalexample">
+<pre class="screen">    ant hsqldb</pre>
+</div> This will build a new
+        <code class="varname">HSQLDB_HOME</code><code class="filename">/lib/hsqldb.jar</code>.</p>
+</li>
+</ol>
+</div>
+<p>See the <a class="link" href="building-app.html" title="Appendix&nbsp;B.&nbsp;Building HyperSQL Jars">Building HyperSQL Jars</a> appendix if you want to build anything
+    other than <code class="filename">hsqldb.jar</code> with all default
+    settings.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_cat_setup-sect"></a>Setting up a HyperSQL Persistent Database Catalog and a HyperSQL
+    Network Listener</h2>
+</div>
+</div>
+</div>
+<p>If you installed from an OS-specific package, you may already
+    have a catalog and listener pre-configured. See if your package includes a
+    file named <code class="filename">server.properties</code> (make use of your
+    packaging utilities). If you do, then I suggest that you still read this
+    section while you poke around, in order to understand your
+    setup.</p>
+<div class="procedure">
+<ol type="1">
+<li>
+<p>Select a UNIX user to run the database process (JVM) as. If
+        this database is for the use of multiple users, or is a production
+        system (or to emulate a production system), you should dedicate a UNIX
+        user for this purpose. In my examples, I use the user name
+        <code class="literal">hsqldb</code>. In this chapter, I refer to this user as
+        the <code class="varname">HSQLDB_OWNER</code>, since that user will own the
+        database catalog files and the JVM processes.</p>
+<p>If the account doesn't exist, then create it. On all system-5
+        UNIXes and most hybrids (including Linux), you can run (as root)
+        something like <div class="informalexample">
+<pre class="screen">    useradd -c 'HSQLDB Database Owner' -s /bin/bash -m hsqldb</pre>
+</div> (BSD-variant users can use a similar <code class="literal">pw
+        useradd hsqldb...</code> command).</p>
+</li>
+<li>
+<p>Become the <code class="varname">HSQLDB_OWNER</code>. Copy the sample
+        file <code class="filename"><a class="filename" href="apd.html#server.properties-link">
+        sample/server.properties</a></code> to the
+        <code class="varname">HSQLDB_OWNER</code>'s home directory and rename it to
+        <code class="filename">server.properties</code>. (As a final reminder,
+        "sampleserver.properties" is a relative path, so it is understood to
+        be relative to your <code class="varname">HSQLDB_HOME</code>).</p>
+<pre class="programlisting"># Hsqldb Server cfg file.
+# See the HyperSQL Network Listeners chapter of the HyperSQL User Guide.
+
+# Each server.database.X setting defines a database "catalog".
+# I.e., an independent set of data.
+# Each server.database.X setting corresponds exactly to the jdbc:hsqldb:*
+# JDBC URL you would use if you wanted to get a direct (In-Process)
+# Connection to the catalog instead of "serving" it.
+
+server.database.0=file:db0/db0
+# I suggest that, for every file: catalog you define, you add the
+# connection property "ifexists=true" after the database instance
+# is created (which happens simply by starting the Server one time).
+# Just append ";ifexists=true" to the file: URL, like so:
+# server.database.0=file:db0/db0;ifexists=true
+
+# server.dbname.0 defaults to "" (i.e. server.dbname.n for n==0), but
+# the catalog definition n will be entirely ignored for n &gt; 0 if you do not
+# set server.dbname.n.  I.e. dbname setting is required for n &gt; 0, though it
+# may be set to blank (e.g. "server.dbname.3=")
+</pre>
+<p>Since the value of the first database
+        (<span class="property">server.database.0</span>) begins with
+        <em class="glossterm">file:</em>, the catalog will be persisted to a set
+        of files in the specified directory with names beginning with the
+        specified name. Set the path to whatever you want (relative paths will
+        be relative to the directory containing the properties file). You can
+        read about how to specify other catalogs of various types, and how to
+        make settings for the listen port and many other things in other
+        chapters of this guide.</p>
+</li>
+<li>
+<p>Set and export the environmental variable
+        <code class="varname">CLASSPATH</code> to the value of
+        <code class="varname">HSQLDB_HOME</code> (as described above) plus
+        "/lib/hsqldb.jar", like <div class="informalexample">
+<pre class="screen">    export CLASSPATH; CLASSPATH=/path/to/hsqldb/lib/hsqldb.jar</pre>
+</div> In <code class="varname">HSQLDB_OWNER</code>'s home
+        directory, run</p>
+<div class="informalexample">
+<pre class="screen">    nohup java org.hsqldb.server.Server &amp;</pre>
+</div>
+<p>This will start the Listener process in the background, and
+        will create your new database catalog "db0". Continue on when you see
+        the message containing <code class="literal">HSQLDB server... is online</code>.
+        <code class="literal">nohup</code> just makes sure that the command will not
+        quit when you exit the current shell (omit it if that's what you want
+        to do).</p>
+</li>
+</ol>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_access-sect"></a>Accessing your Database</h2>
+</div>
+</div>
+</div>
+<p>
+      We're going to use SqlTool to access the database, so you will need the
+      file <code class="filename">sqltool.jar</code> in addition to
+      <code class="filename">hsqldb.jar</code>.
+      If <code class="filename">sqltool.jar</code> isn't already sitting there beside
+      <code class="filename">hsqldb.jar</code> (they both come pre-built), build it
+      exactly as you would build <code class="filename">hsqldb.jar</code>, except use
+      ant target <code class="literal">sqltool</code>.
+      If your distribution came with a sqltool jar file with a version label,
+      like <code class="filename">sqltool-1.2.3.4.jar</code>, that's fine-- use that
+      file whenever I say <code class="filename">sqltool.jar</code> below.
+    </p>
+<p>Copy the file <code class="filename"><a class="filename" href="apd.html#sqltool.rc-link">sample/sqltool.rc</a></code> to the
+    <code class="varname">HSQLDB_OWNER</code>'s home directory. Use
+    <code class="literal">chmod</code> to make the file readable and writable only to
+    <code class="varname">HSQLDB_OWNER</code>.</p>
+<pre class="programlisting"># $Id: sqltool.rc 3353 2009-12-15 19:52:13Z unsaved $
+
+# This is a sample RC configuration file used by SqlTool, DatabaseManager,
+# and any other program that uses the org.hsqldb.lib.RCData class.
+# See the documentation for SqlTool for various ways to use this file.
+
+# If you have the least concerns about security, then secure access to
+# your RC file.
+
+# You can run SqlTool right now by copying this file to your home directory
+# and running
+#    java -jar /path/to/sqltool.jar mem
+# This will access the first urlid definition below in order to use a 
+# personal Memory-Only database.
+# "url" values may, of course, contain JDBC connection properties, delimited
+# with semicolons.
+# As of revision 3347 of SqlFile, you can also connect to datasources defined
+# here from within an SqlTool session/file with the command "\j urlid".
+
+# You can use Java system property values in this file like this:  ${user.home}
+
+# The only feature added recently is the optional "transiso" setting,
+# which may be set to an all-caps transaction isolation level as listed
+# in the Java API Spec for java.sql.Connection.
+# Windows users are advised to use forward slashes instead of reverse slashes,
+# and to avoid paths containing spaces or other funny characters.  (This
+# recommendation applies to any Java app, not just SqlTool).
+
+# A personal Memory-Only (non-persistent) database.
+urlid mem
+url jdbc:hsqldb:mem:memdbid
+username SA
+password
+
+# A personal, local, persistent database.
+urlid personal
+url jdbc:hsqldb:file:${user.home}/db/personal;shutdown=true
+username SA
+password
+transiso TRANSACTION_READ_COMMITTED
+# When connecting directly to a file database like this, you should 
+# use the shutdown connection property like this to shut down the DB
+# properly when you exit the JVM.
+
+# This is for a hsqldb Server running with default settings on your local
+# computer (and for which you have not changed the password for "SA").
+urlid localhost-sa
+url jdbc:hsqldb:hsql://localhost
+username SA
+password
+
+
+
+# Template for a urlid for an Oracle database.
+# You will need to put the oracle.jdbc.OracleDriver class into your 
+# classpath.
+# In the great majority of cases, you want to use the file classes12.zip
+# (which you can get from the directory $ORACLE_HOME/jdbc/lib of any
+# Oracle installation compatible with your server).
+# Since you need to add to the classpath, you can't invoke SqlTool with
+# the jar switch, like "java -jar .../hsqldb.jar..." or 
+# "java -jar .../hsqlsqltool.jar...".
+# Put both the HSQLDB jar and classes12.zip in your classpath (and export!)
+# and run something like "java org.hsqldb.util.SqlTool...".
+
+#urlid cardiff2
+#url jdbc:oracle:thin:@aegir.admc.com:1522:TRAFFIC_SID
+#username blaine
+#password secretpassword
+#driver oracle.jdbc.OracleDriver
+
+
+
+# Template for a TLS-encrypted HSQLDB Server.
+# Remember that the hostname in hsqls (and https) JDBC URLs must match the
+# CN of the server certificate (the port and instance alias that follows 
+# are not part of the certificate at all).
+# You only need to set "truststore" if the server cert is not approved by
+# your system default truststore (which a commercial certificate probably
+# would be).
+
+#urlid tls
+#url jdbc:hsqldb:hsqls://db.admc.com:9001/lm2
+#username BLAINE
+#password asecret
+#truststore ${user.home}/ca/db/db-trust.store
+
+
+# Template for a Postgresql database
+#urlid blainedb
+#url jdbc:postgresql://idun.africawork.org/blainedb
+#username blaine
+#password losung1
+#driver org.postgresql.Driver
+
+# Template for a MySQL database.  MySQL has poor JDBC support.
+#urlid mysql-testdb
+#url jdbc:mysql://hostname:3306/dbname
+#username root
+#password hiddenpwd
+#driver com.mysql.jdbc.Driver
+
+# Note that "databases" in SQL Server and Sybase are traditionally used for
+# the same purpose as "schemas" with more SQL-compliant databases.
+
+# Template for a Microsoft SQL Server database
+#urlid msprojsvr
+#url jdbc:microsoft:sqlserver://hostname;DatabaseName=DbName;SelectMethod=Cursor
+# The SelectMethod setting is required to do more than one thing on a JDBC
+# session (I guess Microsoft thought nobody would really use Java for 
+# anything other than a "hello world" program).
+# This is for Microsoft's SQL Server 2000 driver (requires mssqlserver.jar
+# and msutil.jar).
+#driver com.microsoft.jdbc.sqlserver.SQLServerDriver
+#username myuser
+#password hiddenpwd
+
+# Template for a Sybase database
+#urlid sybase
+#url jdbc:sybase:Tds:hostname:4100/dbname
+#username blaine
+#password hiddenpwd
+# This is for the jConnect driver (requires jconn3.jar).
+#driver com.sybase.jdbc3.jdbc.SybDriver
+
+# Template for Embedded Derby / Java DB.
+#urlid derby1
+#url jdbc:derby:path/to/derby/directory;create=true
+#username ${user.name}
+#password any_noauthbydefault
+#driver org.apache.derby.jdbc.EmbeddedDriver
+# The embedded Derby driver requires derby.jar.
+# There'a also the org.apache.derby.jdbc.ClientDriver driver with URL
+# like jdbc:derby://&lt;server&gt;[:&lt;port&gt;]/databaseName, which requires
+# derbyclient.jar.
+# You can use \= to commit, since the Derby team decided (why???)
+# not to implement the SQL standard statement "commit"!!
+# Note that SqlTool can not shut down an embedded Derby database properly,
+# since that requires an additional SQL connection just for that purpose.
+# However, I've never lost data by not shutting it down properly.
+# Other than not supporting this quirk of Derby, SqlTool is miles ahead of ij.
+</pre>
+<p>We will be using the "localhost-sa" sample urlid definition from
+    the config file. The JDBC URL for this urlid is
+    <code class="literal">jdbc:hsqldb:hsql://localhost</code>. That is the URL for the
+    default catalog of a HyperSQL Listener running on the default port of the
+    local host. You can read about URLs to connect to other catalogs with and
+    without listeners in other chapters of this guide.</p>
+<p>Run <code class="classname">SqlTool</code>. <div class="informalexample">
+<pre class="screen">    java -jar path/to/sqltool.jar localhost-sa</pre>
+</div> If you get a prompt, then all is well. If security is
+    of any concern to you at all, then you should change the privileged
+    password in the database. Use the command <code class="literal"><a class="literal" href="accesscontrol-chapt.html#set_password-sql">SET PASSWORD</a></code> command to change
+    SA's password. <div class="informalexample">
+<pre class="programlisting">    SET PASSWORD 'newpassword';</pre>
+</div>
+    Set a <span class="emphasis"><em>strong</em></span> password!
+    </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+        If, like most UNIX System Administrators, you often need to make up
+        strong passwords, I highly suggest the great little program
+        <code class="filename"><a class="filename" href="https://sourceforge.net/projects/pwgen/" target="_top">pwgen</a></code>.
+        You can probably get it where you get your other OS packages.
+        The command <code class="literal">pwgen -1</code> is usually all you need.
+    </p>
+</td>
+</tr>
+</table>
+</div>
+<p>Note that with SQL-conformant databases like HyperSQL 2.0, user
+    names and passwords are case sensitive. If you don't quote the name, it
+    will be interpreted as upper-case, like any named SQL object. (Only for
+    backwards compatibility, we do make an exception for the special user name
+    SA, but you should always use upper-case "SA" nevertheless).</p>
+<p>When you're finished playing, exit with the command
+    <code class="literal">\q</code>.</p>
+<p>If you changed the SA password, then you need to update the
+    password in the <code class="filename">sqltool.rc</code> file accordingly.</p>
+<p>You can, of course, also access the database with any JDBC client
+    program.
+    You will need to modify your classpath to include
+    <code class="filename">hsqldb.jar</code> as well as your client class(es). You can
+    also use the other HSQLDB client programs, such as
+    <code class="classname">org.hsqldb.util.DatabasManagerSwing</code>, a graphical
+    client with a similar purpose to <code class="classname">SqlTool</code>.</p>
+<p>You can use any normal UNIX account to run the JDBC clients,
+    including <code class="classname">SqlTool</code>, as long as the account has read
+    access to the <code class="filename">sqltool.jar</code> file and to an
+    <code class="filename">sqltool.rc</code> file. See the Utilities Guide about where
+    to put <code class="filename">sqltool.rc</code>, how to execute sql files, and
+    other <code class="classname">SqlTool</code> features.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_addl_accts-sect"></a>Create additional Accounts</h2>
+</div>
+</div>
+</div>
+<p>Connect to the database as SA (or any other Administrative user)
+    and run <code class="literal"><a class="literal" href="accesscontrol-chapt.html#create_user-sql">CREATE USER</a></code> to
+    create new accounts for your catalog. HSQLDB accounts are
+    database-catalog-specific, not
+    <code class="classname">Listener</code>-specific.</p>
+<p>In SQL-compliant databases, all database objects are created in a
+    <span class="emphasis"><em>schema</em></span>. If you don't specify a schema, then the new
+    object will be created in the default schema. To create a database object,
+    your account (the account that you connected with) must have the role
+    <code class="literal">DBA</code>, or your account must have authorization for the
+    target schema (see the CREATE SCHEMA command about this last). When you
+    first create a HyperSQL catalog, it has only one database user-- SA, a DBA
+    account, with an empty string password. You should set a password (as
+    described above). You can create as many additional users as you wish. To
+    make a user a DBA, you can use the "ADMIN" option to the <code class="literal"><a class="literal" href="accesscontrol-chapt.html#create_user-sql">CREATE USER</a></code> command, command, or
+    GRANT the DBA Role to the account after creating it.</p>
+<p>Once an object is created, the object creator and users with the
+    DBA role will have all privileges to work with that object. Other users
+    will have only the rights which the pseudo-user PUBLIC has. To give
+    specific users more permissions, even rights to read objects, you can
+    GRANT permissions for specific objects, grant Roles (which encompass a set
+    of permissions), or grant the DBA Role itself.</p>
+<p>Since only people with a database account may do anything at all
+    with the database, it is often useful to permit other database users to
+    view the data in your tables. To optimize performance, reduce contention,
+    and minimize administration, it is often best to grant SELECT to PUBLIC on
+    table-like objects that need to be accessed by multiple database users,
+    with the significant exception of any data which you want to keep secret.
+    (Similary with EXECUTE priv for routines and USAGE priv for other object
+    types).
+    Note that this is not at all equivalent to giving the world or the Internet
+    read access to your tables-- you are giving read access to people that have
+    been given accounts for the target database catalog.
+    </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_shutdown-sect"></a>Shutdown</h2>
+</div>
+</div>
+</div>
+<p>Do a clean database shutdown when you are finished with the database
+    catalog. You need to connect up as SA or some other Admin user, of course.
+    With SqlTool, you can run <div class="informalexample">
+<pre class="screen">    java -jar path/to/sqltool.jar --sql 'shutdown;' localhost-sa</pre>
+</div> You don't have to worry about stopping the
+    <code class="classname">Listener</code> because it shuts down automatically when
+    all served database catalogs are shut down.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_daemon-sect"></a>Running Hsqldb as a System Daemon</h2>
+</div>
+</div>
+</div>
+<a name="N1449D" class="indexterm"></a>
+<p>You can, of course, run HSQLDB through inittab on System V
+    UNIXes, but usually an init script is more convenient and manageable. This
+    section explains how to set up and use our UNIX init script. Our init
+    script is only for use by root. (That is not to say that the
+    <span class="emphasis"><em>Listener</em></span> will run as root-- it usually should
+    not).</p>
+<p>The main purpose of the init script is to start up a Listener for
+    the database catalogs specified in your
+    <code class="filename">server.properties</code> file; and to gracefully shut down
+    these same catalogs. For each catalog defined by a
+    <code class="varname">server.database.X</code> setting in your .properties file, you
+    must define an administrative "urlid" in your
+    <code class="filename">sqltool.rc</code> (these are used to access the catalogs for
+    validation and shutdown purposes). Finally, you list the urlid names in
+    your init script config file. If, due to firewall issues, you want to run
+    a WebServer instead of a Server, then make sure you have a healthy
+    WebServer with a webserver.properties set up, adjust your URLs in
+    <code class="filename">sqltool.rc</code>, and set TARGET_CLASS in the config
+    file.</p>
+<p>By following the commented examples in the config file, you can
+    start up any number of Server and/or WebServer listener instances with or
+    without TLS encryption, and each listener instance can serve any number of
+    HyperSQL catalogs (independent data sets), all with optimal efficiency
+    from a single JVM process. There are instructions in the init script
+    itself about how to run multiple, independently-configured JVM processes.
+    Most UNIX installations, however, will run a single JVM with a single
+    Listener instance which serves multiple catalogs, for easier management
+    and more efficient resource usage.</p>
+<p>After you have the init script set up, root can use it anytime to
+    start or stop HSQLDB. (I.e., not just at system bootup or
+    shutdown).</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N144B8"></a>Portability of <code class="filename">hsqldb</code> init script</h3>
+</div>
+</div>
+</div>
+<p>The primary design criterion of the init script is portability.
+      It does not print pretty color startup/shutdown messages as is common in
+      late-model Linuxes and HPUX; and it does not keep subsystem state files
+      or use the startup/shutdown functions supplied by many UNIXes, because
+      these features are all non-portable.</p>
+<p>Offsetting these limitations, this one script does it's
+      intended job great on the UNIX varieties I have tested, and can easily
+      be modified to accommodate other UNIXes. While you don't have tight
+      integration with OS-specific daemon administration guis, etc., you do
+      have a well tested and well behaved script that gives good, utilitarian
+      feedback.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N144C2"></a>Init script Setup Procedure</h3>
+</div>
+</div>
+</div>
+<p>The strategy taken here is to get the init script to run your
+      single Server or WebServer first (as specified by TARGET_CLASS). After
+      that's working, you can customize the JVM that is run by running
+      additional Listener instances in it, running your own application in it
+      (embedding), or even overriding HSQLDB behavior with your own overriding
+      classes.</p>
+<div class="procedure">
+<ol type="1">
+<li>
+<p>Copy the init script <code class="filename"><a class="filename" href="apd.html#hsqldb.init-link"> sample/hsqldb.init</a></code> to
+          <code class="filename">hsqldb</code> in the directory where init scripts live
+          on your variety of UNIX. The most common locations are
+          <code class="filename">/etc/init.d</code> or
+          <code class="filename">/etc/rc.d/init.d</code> on System V style UNIXes,
+          <code class="filename">/usr/local/etc/rc.d</code> on BSD style UNIXes, and
+          <code class="filename">/Library/StartupItems/hsqldb</code> on OS X (you'll
+          need to create the directory for the last).</p>
+</li>
+<li>
+<p>View your <code class="filename">server.properties</code> file. Make a
+          note of every catalog define by a
+          <code class="varname">server.database.X</code> setting. A couple steps down,
+          you will need to set up administrative access for each of these
+          catalogs. If you are using our sample <code class="filename"><a class="filename" href="apd.html#server.properties-link"> server.properties</a></code>
+          file, you will just need to set up access for the
+          catalog specified with <code class="literal">file:db0/dbo</code>.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Pre-2.0 versions of the hsqldb init script required use
+            of .properties settings of the
+            form<code class="varname">server.urlid.X</code>. These settings are obsolete
+            and should be removed.</p>
+</td>
+</tr>
+</table>
+</div>
+</li>
+<li>
+<p>Either copy <code class="varname">HSQLDB_OWNER</code>'s
+          <code class="filename">sqltool.rc</code> file into root's home directory, or
+          set the value of <code class="varname">AUTH_FILE</code> to the absolute path
+          of <code class="varname">HSQLDB_OWNER</code>'s <code class="filename">sqltool.rc</code>
+          file. This file is read directly by root, even if you run hsqldb as
+          non-root (by setting <code class="varname">HSQLDB_OWNER</code> in the config
+          file). If you copy the file, make sure to use
+          <code class="literal">chmod</code> to restrict permissions on the new copy.
+          The init script will abort with an appropriate exhortation if you
+          have the permissions set incorrectly.</p>
+<p>You need to set up a urlid stanza in your
+          <code class="filename">sqltool.rc</code> file for network access (i.e. JDBC
+          URL with hsql:, hsqls:, http:, or https:) for each catalog in your
+          <code class="filename">server.properties</code> file. For our example, you
+          need to define a stanza for the <code class="literal">file:db0/db0</code>
+          catalog. You must supply for this catalog, a hsql: JDBC URL, an
+          administrative user name, and the password.</p>
+<div class="example">
+<a name="N14517"></a>
+<p class="title">
+<b>Example&nbsp;14.1.&nbsp;example sqltool.rc stanza</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">    urlid localhostdb1
+    url jdbc:hsqldb:hsql://localhost
+    username SA
+    password secret</pre>
+</div>
+</div>
+<br class="example-break">
+</li>
+<li>
+<p>Look at the comment towards the top of the init script
+          which lists recommended locations for the configuration file for
+          various UNIX platforms. Copy the sample config file <code class="filename"><a class="filename" href="apd.html#hsqldb.cfg-link">sample/hsqldb.cfg</a></code> to one of
+          the listed locations (your choice). Edit the config file according
+          to the instructions in it. For our example, you will set the value
+          of <code class="varname">URLIDS</code> to <code class="literal">localhostdb1</code>,
+          since that is the urlid name that we used in the
+          <code class="filename">sqltool.rc</code> file.</p>
+<pre class="programlisting"># $Id: hsqldb.cfg 3583 2010-05-16 01:49:52Z unsaved $
+
+# Sample configuration file for HyperSQL Server Listener.
+# See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide.
+
+# N.b.!!!!  You must place this in the right location for your type of UNIX.
+# See the init script "hsqldb" to see where this must be placed and
+# what it should be renamed to.
+
+# This file is "sourced" by a Bourne shell, so use Bourne shell syntax.
+
+# This file WILL NOT WORK until you set (at least) the non-commented
+# variables to the appropriate values for your system.
+# Life will be easier if you avoid all filepaths with spaces or any other
+# funny characters.  Don't ask for support if you ignore this advice.
+
+# The URLIDS setting below is new and REQUIRED.  This setting replaces the
+# server.urlid.X settings which used to be needed in your Server's
+# properties file.
+
+# -- Blaine (blaine dot simpson at admc dot com)
+
+JAVA_EXECUTABLE=/usr/bin/java
+
+# Unless you copied the jar files from another system, this typically
+# resides at $HSQLDB_HOME/lib/sqltool.jar, where $HSQLDB_HOME is your HSQLDB
+# software base directory.
+# The file name may actually have a version label in it, like
+# sqltool-1.2.3.jar (in which case, you must specify the full name here).
+# A 'hsqldb.jar' file (with or without version label) must reside in the same
+# directory as the specified sqltool.jar file.
+SQLTOOL_JAR_PATH=/opt/hsqldb-2.0.0/hsqldb/lib/sqltool.jar
+# For the sample value above, there must also exist a file
+# /opt/hsqldb-2.0.0/hsqldb/lib/hsqldb*.jar.
+
+# Where the file "server.properties" or "webserver.properties" resides.
+SERVER_HOME=/opt/hsqldb-2.0.0/hsqldb/data
+
+# What UNIX user the server will run as.
+# (The shutdown client is always run as root or the invoker of the init script).
+# Runs as root by default, but you should take the time to set database file
+# ownerships to another user and set that user name here.
+HSQLDB_OWNER=hsqldb
+
+# The HSQLDB jar file specified in HSQLDB_JAR_PATH above will automatically
+# be in the class path.  This arg specifies additional classpath elements.
+# To embed your own application, add your jar file(s) or class base
+# directories here, and add your main class to the INVOC_ADDL_ARGS setting
+# below.  Another common use-case for adding to your class path is to make
+# classes available to the DB engines for SQL/JRT functions and procedures.
+#SERVER_ADDL_CLASSPATH=/usr/local/dist/currencybank.jar
+
+# For startup or shutdown failures, you can save a lot of debugging time by
+# temporarily adjusting down MAX_START_SECS and MAX_TERMINATE_SECS to a
+# little over what it should take for successful startup and shutdown on
+# your system.
+
+# We require all Server/WebServer instances to be accessible within 
+# $MAX_START_SECS from when the Server/WebServer is started.
+# Defaults to 60.
+# Raise this is you are running lots of DB instances or have a slow server.
+#MAX_START_SECS=200
+
+# Max time to allow for JVM to die after all HSQLDB instances stopped.
+# Defaults to 60.  Set high because the script will always continue as soon as
+# the process has stopped.  The importance of this setting is, how long until
+# a non-stopping-JVM-problem will be detected.
+#MAX_TERMINATE_SECS=0
+
+# NEW AND IMPORTANT!!!
+# As noted at the top of this file, this setting replaces the old property
+# settings server.urlid.X.
+# Simply list the URLIDs for all DB instances which your *Server starts.
+# Usually, these will exactly mirror the server.database.X settings in your
+# server.properties or webserver.properties file.
+# Each urlid listed here must be defined to a NETWORK url with Admin privileges
+# in the AUTH_FILE specified below.  (Network type because we use this for
+# inter-process communication)
+# Separate multiple values with white space.  NO OTHER SPECIAL CHARACTERS!
+# Make sure to quote the entire value if it contains white space separator(s).
+URLIDS='localhostdb1'
+
+# These are urlids # ** IN ADDITION TO URLIDS **, for instances which the init
+# script should stop but not start.
+# Most users will not need this setting.  If you need it, you'll know it.
+# Defaults to none (i.e., only URLIDS will be stopped).
+#SHUTDOWN_URLIDS='ondemand'
+
+# SqlTool authentication file used only for shutdown.
+# The default value will be sqltool.rc in root's home directory, since it is 
+# root who runs the init script.
+# (See the SqlTool chapter of the HyperSQL Utilities Guide if you don't
+# understand this).
+#AUTH_FILE=/home/blaine/sqltool.rc
+
+# Typical users will leave this unset and it will default to
+# org.hsqldb.server.Server.  If you need to run the HSQLDB WebServer class
+# instead, due to a firewall or routing impediment, set this to
+# org.hsqldb.server.WebServer, see the docs about running WebServr, and
+# set up a "webserver.properties" file instead of a "server.properties".
+# The JVM that is started can invoke many classes (see the following item
+# about that), but this is the server that is used (1) to check status,
+# (2) to shut down the JVM.
+#TARGET_CLASS=org.hsqldb.server.WebServer
+
+# This is where you may specify both command-line parameters to TARGET_CLASS,
+# plus any number of additional progams to run (along with their command-line
+# parameters).  The MainInvoker program is used to embed these multiple
+# static main invocations into a single JVM, so see the API spec for
+# org.hsqldb.util.MainInvoker if you want to learn more.
+# N.b. You should only use this setting to set HSQLDB Server or WebServer
+# parameters if you run multiple instances of this class, since you can use the
+# server/webserver.properties file for a single instance.
+# Every additional class (in addition to the TARGET_CLASS)
+# must be preceded with an empty string, so that MainInvoker will know
+# you are giving a class name.  MainInvoker will invoke the normal 
+# static main(String[]) method of each such class.  
+# By default, MainInvoker will just run TARGET_CLASS with no args.
+# Example that runs just the TARGET_CLASS with the specified arguments:
+#INVOC_ADDL_ARGS='-silent false'   #but use server.properties property instead!
+# Example that runs the TARGET_CLASS plus a WebServer:
+#INVOC_ADDL_ARGS='"" org.hsqldb.server.WebServer'
+# Note the empty string preceding the class name.
+# Example that starts TARGET_CLASS with an argument + a WebServer +
+# your own application with its args (i.e., the HSQLDB Servers are
+# "embedded" in your application).  (Set SERVER_ADDL_CLASSPATH too).:
+#INVOC_ADDL_ARGS='-silent false "" org.hsqldb.server.WebServer "" com.acme.Stone --env prod localhost'
+#   but use server.properties for -silent option instead!
+# Example to run a non-TLS server in same JVM with a TLS server.  In this
+# case, TARGET_CLASS is Server which will run both in TLS mode by virtue of 
+# setting the tls, keyStore, and keyStorePassword settings in
+# server*.properties, as described below; plus an "additional" Server with
+# overridden 'tls' and 'port' settings:
+#INVOC_ADDL_ARGS="'' org.hsqldb.server.Server --port 9002 --tls false"
+# This is an important use case.  If you run more than one Server instance,
+# you can specify different parameters for each here, even though only one
+# server.properties file is supported.
+# Note that you use nested quotes to group arguments and to specify the
+# empty-string delimiter.
+
+# The TLS_* settings have been obsoleted.
+# To get your server running with TLS, set
+# system.javax.net.ssl.keyStore=/path/to/your/private.keystore
+# system.javax.net.ssl.keyStorePassword=secretPassword
+# server.ssl=true
+# IN server.properties or webserver.properties, and
+# MAKE THE FILE OWNER-READ-ONLY!
+# See the TLS Encryption section of the HyperSQL User Guide, paying attention
+# to the security warning(s).
+# If you are running with a private server cert, then you will also need to 
+# set "truststore" in the your SqlTool config file (location is set by the
+# AUTH_FILE variable in this file, or it must be at the default location for 
+# HSQLDB_OWNER).
+
+# Any JVM args for the invocation of the JDBC client used to verify DB
+# instances and to shut them down (SqlToolSprayer).
+# Server-side System Properties should normally be set with system.*
+# settings in the server/webserver.properties file.
+# This example specifies the location of a private trust store for TLS 
+# encryption.
+# For multiple args, put quotes around entire value.
+# If you are starting just a TLS_encrypted Listener, you need to uncomment
+# this so the init scripts uses TLS to connect.
+# If using a private keystore, you also need to set "truststore" settings in
+# the sqltool.rc file.
+#CLIENT_JVMARGS=-Djavax.net.debug=ssl
+# This sample value displays useful debugging information about TLS/SSL.
+
+# Any JVM args for the server.
+# For multiple args, put quotes around entire value.
+#SERVER_JVMARGS=-Xmx512m
+# You can set the "javax.net.debug" property on the server side here, in the
+# same exact way as shown for the client side above.
+</pre>
+<p>
+<span class="bold"><strong>Verify that the init script
+          works.</strong></span>
+</p>
+<p>Just run <div class="informalexample">
+<pre class="screen">    /path/to/hsqldb</pre>
+</div> as root to see the arguments you may use.
+          Notice that you can run</p>
+<p>
+<pre class="screen">    /path/to/hsqldb status</pre>at any time to see
+          whether your HSQLDB <code class="classname">Listener</code> is
+          running.</p>
+<p>Re-run the script with each of the possible arguments to
+          really test it good. If anything doesn't work right, then see the
+          <a class="link" href="unix-chapt.html#unix_inittrouble-sect" title="Troubleshooting the Init Script">Troubleshooting the Init
+      Script</a> section.</p>
+</li>
+<li>
+<p>Tell your OS to run the init script upon system startup and
+          shutdown. If you are using a UNIX variant that has
+          <code class="filename">/etc/rc.conf</code> or
+          <code class="filename">/etc/rc.conf.local</code> (like BSD variants and
+          Gentoo), you must set "hsqldb_enable" to "YES" in either of those
+          files. (Just run <code class="literal">cd /etc; ls rc.conf
+          rc.conf.local</code> to see if you have one of these files). For
+          good UNIXes that use System V style init, you must set up hard links
+          or soft links either manually or with management tools (such as
+          <code class="literal">chkconfig</code> or <code class="literal">insserv</code>) or Gui's
+          (like run level editors).</p>
+<p>This paragraph is for Mac OS X users only. If you followed the
+          instructions above, your init script should reside at
+          <code class="filename">/Library/StartupItems/hsqldb/hsqldb</code>. Now copy
+          the file <code class="filename">StartupParameters.plist</code> from the
+          directory <code class="filename">src/org.hsqldb/sample</code> of your HSQLDB
+          distribution to the same directory as the init script. As long as
+          these two files reside in
+          <code class="filename">/Library/StartupItems/hsqldb</code>, your init script
+          is active (for portability reasons, it doesn't check for a setting
+          in <code class="filename">/etc/hostconfig</code>). You can run it as a
+          <span class="emphasis"><em>Startup Item</em></span> by running <pre class="screen">    SystemStarter {start|stop|restart} Hsqldb</pre>
+          Hsqldb is the service name. See the man page for
+          <code class="classname">SystemStarter</code>. To disable the init script,
+          wipe out the <code class="filename">/Library/StartupItems/hsqldb</code>
+          directory. Hard to believe, but the Mac people tell me that during
+          system shutdown the Startup Items don't run at all. Therefore, if
+          you don't want your data corrupted, make sure to run "SystemStarter
+          stop Hsqldb" before shutting down your Mac.</p>
+</li>
+</ol>
+</div>
+<p>Follow the examples in the config file to add additional
+      classes to the server JVM's classpath and to execute additional classes
+      in your JVM. (See the <code class="varname">SERVER_ADDL_CLASSPATH</code> and
+      <code class="varname">INVOC_ADDL_ARGS</code> items).</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="unix_inittrouble-sect"></a>Troubleshooting the Init
+      Script</h3>
+</div>
+</div>
+</div>
+<p>Definitely look at the init script log file, which is at an
+      OS-sependent location, but is usually at
+      <code class="filename">/var/log/hsqldb.log</code>.</p>
+<p>Do a <code class="literal">ps</code> to look for processes containing the
+      string <code class="literal">hsqldb</code>, and try to connect to the database
+      from any client. If the init script starts up your database
+      successfully, but incorrectly reports that it has not, then your problem
+      is with specification of urlid(s) or SqlTool setup. If your database
+      really did not start, then skip to the next paragraph. Verify that your
+      config file assigns a urlid for each catalog defined in
+      <code class="filename">server.properties</code> or
+      <code class="filename">webserver.properties</code>, then verify that you can run
+      <code class="classname">SqlTool</code> as root to connect to the catalogs with
+      these urlids. (For the latter test, use the <code class="literal">--rcfile</code>
+      switch if you are setting <code class="varname">AUTH_FILE</code> in the init
+      script config file).</p>
+<p>If your database really is not starting, then verify that you
+      can <code class="literal">su</code> to the database owner account and start the
+      database. The command
+      <code class="literal">su USERNAME -c ...</code> won't work on most UNIXes unless
+      the target user has a real login shell. Therefore, if you try to tighten
+      up security by disabling this user's login shell, you will break the
+      init script. If these possibilities don't pan out, then debug the init
+      script or seek help, as described below.</p>
+<p>To debug the init script, run it in verbose mode to see exactly
+      what is happening (and perhaps manually run the steps that are suspect).
+      To run an init script (in fact, any sh shell script) in verbose mode,
+      use <code class="literal">sh</code> with the <code class="literal">-x</code> or
+      <code class="literal">-v</code> switch, like <pre class="screen">    sh -x path/to/hsqldb start</pre>
+      See the man page for <code class="literal">sh</code> if you don't know the
+      difference between <code class="literal">-v</code> and
+      <code class="literal">-x</code>.</p>
+<p>If you want troubleshooting help, use the HSQLDB lists/forums.
+      Make sure to include the revision number from your
+      <code class="filename">hsqldb</code> init script (it's towards the top in the
+      line that starts like "# $Id:"), and the output of a run of <pre class="screen">    sh -x path/to/hsqldb start &gt; /tmp/hstart.log 2&gt;&amp;1</pre>
+</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="unix_upgrade-sect"></a>Upgrading</h2>
+</div>
+</div>
+</div>
+<p>This section is for users who are using our UNIX init script, and
+    who are upgrading their HyperSQL installation.</p>
+<p>Most users will not have customized the init script itself, and
+    your customizations will all be encapsulated in the init script
+    configuration file. These users should just overwrite their init script
+    with a new one from the HyperSQL installation, and manually merge config
+    file settings. First, just copy the file
+    <code class="filename">/sample/hsqldb.init</code> over top of of your init script
+    (wherever it runs from). Then update your old config file according to the
+    instructions in the new config file template at
+    <code class="filename">sample/hsqldb.cfg</code>. You will have to change very few
+    settings. If you are upgrading from a pre-2.0 installation to a post-2.0
+    installation, you will need to (1) add the setting
+    <code class="varname">URLIDS</code>, as described above and in the inline comments,
+    and (2) replace variable <code class="varname">HSQLDB_JAR_PATH</code> with
+    <code class="varname">SQLTOOL_JAR_PATH</code> which (if you haven't guessed) should
+    be set to the path to your <code class="filename">sqltool.jar</code> file.</p>
+<p>Users who customized their init script will need to merge their
+    customizations into the new init script.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3601 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="listeners-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="lists-app.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;13.&nbsp;HyperSQL Network Listeners&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Appendix&nbsp;A.&nbsp;Lists of Keywords</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/hsqldb_lic.txt b/doc/hsqldb_lic.txt
new file mode 100644
index 0000000..ca4b07a
--- /dev/null
+++ b/doc/hsqldb_lic.txt
@@ -0,0 +1,31 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * Redistributions of source code must retain the above copyright notice, this

+ * list of conditions and the following disclaimer.

+ *

+ * Redistributions in binary form must reproduce the above copyright notice,

+ * this list of conditions and the following disclaimer in the documentation

+ * and/or other materials provided with the distribution.

+ *

+ * Neither the name of the HSQL Development Group nor the names of its

+ * contributors may be used to endorse or promote products derived from this

+ * software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,

+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+

diff --git a/doc/hypersonic_lic.txt b/doc/hypersonic_lic.txt
new file mode 100644
index 0000000..1e674ea
--- /dev/null
+++ b/doc/hypersonic_lic.txt
@@ -0,0 +1,70 @@
+/*

+ * For work developed by the HSQL Development Group:

+ *

+ * Copyright (c) 2001-2010, The HSQL Development Group

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * Redistributions of source code must retain the above copyright notice, this

+ * list of conditions and the following disclaimer.

+ *

+ * Redistributions in binary form must reproduce the above copyright notice,

+ * this list of conditions and the following disclaimer in the documentation

+ * and/or other materials provided with the distribution.

+ *

+ * Neither the name of the HSQL Development Group nor the names of its

+ * contributors may be used to endorse or promote products derived from this

+ * software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,

+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ *

+ *

+ * For work originally developed by the Hypersonic SQL Group:

+ *

+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * Redistributions of source code must retain the above copyright notice, this

+ * list of conditions and the following disclaimer.

+ *

+ * Redistributions in binary form must reproduce the above copyright notice,

+ * this list of conditions and the following disclaimer in the documentation

+ * and/or other materials provided with the distribution.

+ *

+ * Neither the name of the Hypersonic SQL Group nor the names of its

+ * contributors may be used to endorse or promote products derived from this

+ * software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,

+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ *

+ * This software consists of voluntary contributions made by many individuals

+ * on behalf of the Hypersonic SQL Group.

+ */

+

+

diff --git a/doc/images/db/annot-close.png b/doc/images/db/annot-close.png
new file mode 100644
index 0000000..b9e1a0d
--- /dev/null
+++ b/doc/images/db/annot-close.png
Binary files differ
diff --git a/doc/images/db/annot-open.png b/doc/images/db/annot-open.png
new file mode 100644
index 0000000..71040ec
--- /dev/null
+++ b/doc/images/db/annot-open.png
Binary files differ
diff --git a/doc/images/db/blank.png b/doc/images/db/blank.png
new file mode 100644
index 0000000..764bf4f
--- /dev/null
+++ b/doc/images/db/blank.png
Binary files differ
diff --git a/doc/images/db/callouts/1.gif b/doc/images/db/callouts/1.gif
new file mode 100644
index 0000000..9e7a87f
--- /dev/null
+++ b/doc/images/db/callouts/1.gif
Binary files differ
diff --git a/doc/images/db/callouts/1.png b/doc/images/db/callouts/1.png
new file mode 100644
index 0000000..7d47343
--- /dev/null
+++ b/doc/images/db/callouts/1.png
Binary files differ
diff --git a/doc/images/db/callouts/10.gif b/doc/images/db/callouts/10.gif
new file mode 100644
index 0000000..e80f7f8
--- /dev/null
+++ b/doc/images/db/callouts/10.gif
Binary files differ
diff --git a/doc/images/db/callouts/10.png b/doc/images/db/callouts/10.png
new file mode 100644
index 0000000..997bbc8
--- /dev/null
+++ b/doc/images/db/callouts/10.png
Binary files differ
diff --git a/doc/images/db/callouts/11.gif b/doc/images/db/callouts/11.gif
new file mode 100644
index 0000000..67f91a2
--- /dev/null
+++ b/doc/images/db/callouts/11.gif
Binary files differ
diff --git a/doc/images/db/callouts/11.png b/doc/images/db/callouts/11.png
new file mode 100644
index 0000000..ce47dac
--- /dev/null
+++ b/doc/images/db/callouts/11.png
Binary files differ
diff --git a/doc/images/db/callouts/12.gif b/doc/images/db/callouts/12.gif
new file mode 100644
index 0000000..54c4b42
--- /dev/null
+++ b/doc/images/db/callouts/12.gif
Binary files differ
diff --git a/doc/images/db/callouts/12.png b/doc/images/db/callouts/12.png
new file mode 100644
index 0000000..31daf4e
--- /dev/null
+++ b/doc/images/db/callouts/12.png
Binary files differ
diff --git a/doc/images/db/callouts/13.gif b/doc/images/db/callouts/13.gif
new file mode 100644
index 0000000..dd5d7d9
--- /dev/null
+++ b/doc/images/db/callouts/13.gif
Binary files differ
diff --git a/doc/images/db/callouts/13.png b/doc/images/db/callouts/13.png
new file mode 100644
index 0000000..14021a8
--- /dev/null
+++ b/doc/images/db/callouts/13.png
Binary files differ
diff --git a/doc/images/db/callouts/14.gif b/doc/images/db/callouts/14.gif
new file mode 100644
index 0000000..3d7a952
--- /dev/null
+++ b/doc/images/db/callouts/14.gif
Binary files differ
diff --git a/doc/images/db/callouts/14.png b/doc/images/db/callouts/14.png
new file mode 100644
index 0000000..64014b7
--- /dev/null
+++ b/doc/images/db/callouts/14.png
Binary files differ
diff --git a/doc/images/db/callouts/15.gif b/doc/images/db/callouts/15.gif
new file mode 100644
index 0000000..1c9183d
--- /dev/null
+++ b/doc/images/db/callouts/15.gif
Binary files differ
diff --git a/doc/images/db/callouts/15.png b/doc/images/db/callouts/15.png
new file mode 100644
index 0000000..0d65765
--- /dev/null
+++ b/doc/images/db/callouts/15.png
Binary files differ
diff --git a/doc/images/db/callouts/2.gif b/doc/images/db/callouts/2.gif
new file mode 100644
index 0000000..94d42a3
--- /dev/null
+++ b/doc/images/db/callouts/2.gif
Binary files differ
diff --git a/doc/images/db/callouts/2.png b/doc/images/db/callouts/2.png
new file mode 100644
index 0000000..5d09341
--- /dev/null
+++ b/doc/images/db/callouts/2.png
Binary files differ
diff --git a/doc/images/db/callouts/3.gif b/doc/images/db/callouts/3.gif
new file mode 100644
index 0000000..dd3541a
--- /dev/null
+++ b/doc/images/db/callouts/3.gif
Binary files differ
diff --git a/doc/images/db/callouts/3.png b/doc/images/db/callouts/3.png
new file mode 100644
index 0000000..ef7b700
--- /dev/null
+++ b/doc/images/db/callouts/3.png
Binary files differ
diff --git a/doc/images/db/callouts/4.gif b/doc/images/db/callouts/4.gif
new file mode 100644
index 0000000..4bcbf7e
--- /dev/null
+++ b/doc/images/db/callouts/4.gif
Binary files differ
diff --git a/doc/images/db/callouts/4.png b/doc/images/db/callouts/4.png
new file mode 100644
index 0000000..adb8364
--- /dev/null
+++ b/doc/images/db/callouts/4.png
Binary files differ
diff --git a/doc/images/db/callouts/5.gif b/doc/images/db/callouts/5.gif
new file mode 100644
index 0000000..1c62b4f
--- /dev/null
+++ b/doc/images/db/callouts/5.gif
Binary files differ
diff --git a/doc/images/db/callouts/5.png b/doc/images/db/callouts/5.png
new file mode 100644
index 0000000..4d7eb46
--- /dev/null
+++ b/doc/images/db/callouts/5.png
Binary files differ
diff --git a/doc/images/db/callouts/6.gif b/doc/images/db/callouts/6.gif
new file mode 100644
index 0000000..23bc555
--- /dev/null
+++ b/doc/images/db/callouts/6.gif
Binary files differ
diff --git a/doc/images/db/callouts/6.png b/doc/images/db/callouts/6.png
new file mode 100644
index 0000000..0ba694a
--- /dev/null
+++ b/doc/images/db/callouts/6.png
Binary files differ
diff --git a/doc/images/db/callouts/7.gif b/doc/images/db/callouts/7.gif
new file mode 100644
index 0000000..e55ce89
--- /dev/null
+++ b/doc/images/db/callouts/7.gif
Binary files differ
diff --git a/doc/images/db/callouts/7.png b/doc/images/db/callouts/7.png
new file mode 100644
index 0000000..472e96f
--- /dev/null
+++ b/doc/images/db/callouts/7.png
Binary files differ
diff --git a/doc/images/db/callouts/8.gif b/doc/images/db/callouts/8.gif
new file mode 100644
index 0000000..49375e0
--- /dev/null
+++ b/doc/images/db/callouts/8.gif
Binary files differ
diff --git a/doc/images/db/callouts/8.png b/doc/images/db/callouts/8.png
new file mode 100644
index 0000000..5e60973
--- /dev/null
+++ b/doc/images/db/callouts/8.png
Binary files differ
diff --git a/doc/images/db/callouts/9.gif b/doc/images/db/callouts/9.gif
new file mode 100644
index 0000000..da12a4f
--- /dev/null
+++ b/doc/images/db/callouts/9.gif
Binary files differ
diff --git a/doc/images/db/callouts/9.png b/doc/images/db/callouts/9.png
new file mode 100644
index 0000000..a0676d2
--- /dev/null
+++ b/doc/images/db/callouts/9.png
Binary files differ
diff --git a/doc/images/db/caution.gif b/doc/images/db/caution.gif
new file mode 100644
index 0000000..d9f5e5b
--- /dev/null
+++ b/doc/images/db/caution.gif
Binary files differ
diff --git a/doc/images/db/caution.png b/doc/images/db/caution.png
new file mode 100644
index 0000000..5b7809c
--- /dev/null
+++ b/doc/images/db/caution.png
Binary files differ
diff --git a/doc/images/db/draft.png b/doc/images/db/draft.png
new file mode 100644
index 0000000..59673fe
--- /dev/null
+++ b/doc/images/db/draft.png
Binary files differ
diff --git a/doc/images/db/home.gif b/doc/images/db/home.gif
new file mode 100644
index 0000000..6784f5b
--- /dev/null
+++ b/doc/images/db/home.gif
Binary files differ
diff --git a/doc/images/db/home.png b/doc/images/db/home.png
new file mode 100644
index 0000000..ef439f6
--- /dev/null
+++ b/doc/images/db/home.png
Binary files differ
diff --git a/doc/images/db/important.gif b/doc/images/db/important.gif
new file mode 100644
index 0000000..6795d9a
--- /dev/null
+++ b/doc/images/db/important.gif
Binary files differ
diff --git a/doc/images/db/important.png b/doc/images/db/important.png
new file mode 100644
index 0000000..12c90f6
--- /dev/null
+++ b/doc/images/db/important.png
Binary files differ
diff --git a/doc/images/db/next.gif b/doc/images/db/next.gif
new file mode 100644
index 0000000..aa1516e
--- /dev/null
+++ b/doc/images/db/next.gif
Binary files differ
diff --git a/doc/images/db/next.png b/doc/images/db/next.png
new file mode 100644
index 0000000..d74b96d
--- /dev/null
+++ b/doc/images/db/next.png
Binary files differ
diff --git a/doc/images/db/note.gif b/doc/images/db/note.gif
new file mode 100644
index 0000000..f329d35
--- /dev/null
+++ b/doc/images/db/note.gif
Binary files differ
diff --git a/doc/images/db/note.png b/doc/images/db/note.png
new file mode 100644
index 0000000..d0c3c64
--- /dev/null
+++ b/doc/images/db/note.png
Binary files differ
diff --git a/doc/images/db/prev.gif b/doc/images/db/prev.gif
new file mode 100644
index 0000000..64ca8f3
--- /dev/null
+++ b/doc/images/db/prev.gif
Binary files differ
diff --git a/doc/images/db/prev.png b/doc/images/db/prev.png
new file mode 100644
index 0000000..4ecb678
--- /dev/null
+++ b/doc/images/db/prev.png
Binary files differ
diff --git a/doc/images/db/tip.gif b/doc/images/db/tip.gif
new file mode 100644
index 0000000..823f2b4
--- /dev/null
+++ b/doc/images/db/tip.gif
Binary files differ
diff --git a/doc/images/db/tip.png b/doc/images/db/tip.png
new file mode 100644
index 0000000..5c4aab3
--- /dev/null
+++ b/doc/images/db/tip.png
Binary files differ
diff --git a/doc/images/db/toc-blank.png b/doc/images/db/toc-blank.png
new file mode 100644
index 0000000..6ffad17
--- /dev/null
+++ b/doc/images/db/toc-blank.png
Binary files differ
diff --git a/doc/images/db/toc-minus.png b/doc/images/db/toc-minus.png
new file mode 100644
index 0000000..abbb020
--- /dev/null
+++ b/doc/images/db/toc-minus.png
Binary files differ
diff --git a/doc/images/db/toc-plus.png b/doc/images/db/toc-plus.png
new file mode 100644
index 0000000..941312c
--- /dev/null
+++ b/doc/images/db/toc-plus.png
Binary files differ
diff --git a/doc/images/db/up.gif b/doc/images/db/up.gif
new file mode 100644
index 0000000..aabc2d0
--- /dev/null
+++ b/doc/images/db/up.gif
Binary files differ
diff --git a/doc/images/db/up.png b/doc/images/db/up.png
new file mode 100644
index 0000000..ef439f6
--- /dev/null
+++ b/doc/images/db/up.png
Binary files differ
diff --git a/doc/images/db/warning.gif b/doc/images/db/warning.gif
new file mode 100644
index 0000000..3adf191
--- /dev/null
+++ b/doc/images/db/warning.gif
Binary files differ
diff --git a/doc/images/db/warning.png b/doc/images/db/warning.png
new file mode 100644
index 0000000..1c33db8
--- /dev/null
+++ b/doc/images/db/warning.png
Binary files differ
diff --git a/doc/images/hypersql_logo.png b/doc/images/hypersql_logo.png
new file mode 100644
index 0000000..84c7a3e
--- /dev/null
+++ b/doc/images/hypersql_logo.png
Binary files differ
diff --git a/doc/images/hypersql_logo2.png b/doc/images/hypersql_logo2.png
new file mode 100644
index 0000000..7652d49
--- /dev/null
+++ b/doc/images/hypersql_logo2.png
Binary files differ
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 0000000..48e951e
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>HSQLDB</title>
+
+</head>
+
+<body>
+<h3>HyperSQL version 2.0.0 Documentation</h3>
+<p>HSQLDB (HyperSQL Database) is a relational database engine
+written in Java. Version 2.0 is the result of over 4 years development
+since the last major version. It offers many features and adheres
+closely to the latest SQL and JDBC 4 standards.</p>
+<div class="section_title"> </div>
+<p>A set of HTML, PDF and text documents covering different
+aspects of HSQLDB and some of its utilities.</p>
+<p><a href="guide/index.html">HyperSQL User Guide</a>
+in HTML format. <br>
+<a href="guide/guide.pdf">HyperSQL User Guide</a> in
+PDF format. </p>
+<p><a href="util-guide/index.html">HyperSQL
+Utilities Guide</a> in HTML format.<br>
+<a href="util-guide/util-guide.pdf">HyperSQL Utilities
+Guide</a> in PDF format.
+</p>
+<p>The <a href="apidocs/index.html">JavaDoc</a>
+for public classes, including the JDBC documentation.
+</p>
+<p>Chronological list of minor changes and bug fixes since the
+release of version 2.0 <a href="changelist_2_0.txt">changelist_2_0.txt</a>
+</p>
+<p>The license texts for the source and binaries, based on the
+BSD license. <a href="hsqldb_lic.txt">hsqldb_lic.txt</a>
+is for sources developed entirely by the HSQL Development Group. <a href="hypersonic_lic.txt">hypersonic_lic.txt</a> is
+for sources that contain code from the closed HypersonicSQL project.</p>
+<h4>Additional Resources</h4>
+<p>Support for HyperSQL is available from <a target="_top" href="http://hsqldb.org/support">http://hsqldb.org/support</a>
+in various forms, including a mailing list and user forums. The web
+site features the latest bugfix versions of the software, FAQ and other
+useful resources.</p>
+<p>$Date: 2010-03-22 19:56:59 -0400 (Mon, 22 Mar 2010) $</p>
+</body></html>
diff --git a/doc/odbc.txt b/doc/odbc.txt
new file mode 100644
index 0000000..175e20b
--- /dev/null
+++ b/doc/odbc.txt
@@ -0,0 +1,211 @@
+$Id: odbc.txt 2850 2009-02-23 22:27:10Z unsaved $

+

+This file documents various aspects of HyerSQL's ODBC support.

+It does not document driver-side issues (at least once we can discriminate),

+since those issues will be documented with the dedicated ODBC driver product.

+

+Critical server-side todo items.

+

+    + Support passing of size/precision/scale values for columns to the ODBC

+      client.  I guess the client uses this for display formatting purposes (I

+      don't know any other reason why the client would want the value, since

+      the database, not the client, enforces conformance).

+      It's quite possible that no real purpose is served.  In that case we can

+      greatly improve efficiency of the PgType class by sharing a static list

+      of elements instead of making tons of PgType instances.

+

+    + Support binary database data types (BINARY, OBJECT, etc.)

+

+    + Support TIME and DATETIME database data types (DATEs already supported)

+      (May want to postpone *INTERVAL* types for another iteration).

+

+    + Verify tactic used to generate numeric "object identifiers" for tables

+      is adequate: Java hash of String "schema.tablename".

+

+    + Fix column oid (numeric object identifier) generation tactic.  I am

+      just returning the sequence in the generated result set.  The problem

+      with this tactic is that the number for a column is dependent upon

+      the query instead of on the table definition.

+

+KNOWN LIMITATIONS

+

+    Limitations corresponding to the TODO items above.

+

+    Can't fetch the same column (or virtual column) twice from JDBC, even with

+    different getters like rs.getInt() and rs.getObject().  I don't know what

+    product is responsible for this limitation.

+

+    No metadata querying ability, other than the ones implicit with setting

+    up prepared statements (including the 'D').

+

+    Don't know if it is a bug with Sun's jdbc:odbc or with psqlodbc, but

+    all fetchsize settings are rejected with a message saying that the

+    value is unacceptable.

+

+    psqlodbc can handle compound commands (*;*) only in SIMPLE (Q) mode; and

+    even that needs to be tested to see if server will generate the expected

+    number of reply packets.

+

+

+POSTGRESQL DEPENDENCIES TO BE ELIMINATED (uncertain whether will handle these

+ on client or server side).

+Search ServerConnection.java (from odbcproto1 branch) for comments about

+ "stub" and "swallow", ignoring stuff about client side swallowing.

+Over-the-wire Postgresql-specific SQL commands that must be handled.

+    SELECT

+    PREPARE/EXECUTE/DEALLOCATE

+    SET/SHOW

+    DECLARE/FETCH/MOVE/CLOSE

+psqlodbc source code locations

+    The info30.c file seems to be good (ODBC v.3 metadata)

+    connect.c

+        select oid,... upon startup.

+        current_schema()

+    convert.c

+        Uses ctid pseudo-column

+        convert_escape() generates queries.  Func. should probably be

+         eliminated.

+        copy_statement_with_parameters looks dependent upon PostgresQL

+         PREPARE SQL statements.

+         (this calls Prepare_and_convert(), which also depends on them).

+    multibyte.c

+        CC_lookup_cs_new()  Not run from Linux driver.  Test whether

+         called from CC_lookup_characterset() from Windows ANSI client.

+    parse.c

+        CheckHasOids()

+        getCOLIfromTable()

+    results.c

+        tupleExists()  uses ctid pseudo-column

+Literal commands known to be sent over the wire:

+

+    select n.nspname, c.relname, a.attname, a.atttypid,t.typname, a.attnum, a.attlen, a.atttypmod, a.attnotnull, c.relhasrules, c.relkind, c.oid, d.adsrc from (((pg_catalog.pg_class c inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace and c.oid = 3411470544) inner join pg_catalog.pg_attribute a on (not a.attisdropped) and a.attnum > 0 and a.attrelid = c.oid) inner join pg_catalog.pg_type t on t.oid = a.atttypid) left outer join pg_attrdef d on a.atthasdef and d.adrelid = a.attrelid and d.adnum = a.attnum order by n.nspname, c.relname, attnum

+

+    select current_schema()

+

+    select oid, typbasetype from pg_type where typname = 'lo'

+

+    deallocate <cursorname> (all cases I've encountered so far seem to be

+     an over-zealous attempt by the driver to free cursors managed completely

+     EXTENDED protocol, and therefore my server code can handle these).

+

+    set client_encoding to...

+

+Literal commands I see in code, but have not yet taken the time to confirm or

+reject as will ever be sent to our server.  Repeat:  THESE STATEMENTS MAY

+NEVER BE SENT.  I will have a definitive answer about several of these shortly.:

+

+    "select oid, 0 from pg_type where typname='" PG_TYPE_LO_NAME "'"

+

+    Dynamic queries with: " where ctid = '(0,0)';select \"ctid"... from...

+

+    All sorts of metadata/data-dictionary stuff in "info.c" file.

+

+    select relhasoids, c.oid from pg_class c, pg_namespace n where relname = '%s' and nspname = '%s' and c.relnamespace = n.oid"

+

+    "select a.attname, a.atttypid from pg_index i, pg_attribute a where indrelid=%u and indnatts=1 and indisunique

+ and indexprs is null and indpred is null and i.indrelid = a.attrelid and a.attnum=i.indkey[0] and attnotnull and atttypid in (%d, %d)"

+

+    "select nspname from pg_namespace n, pg_class c"

+

+    "select 1 from \"%s\" where ctid = '(%d,%d)'"

+

+    Complex dynamic parsing or genereration code in convert.c:convert_escape().

+

+    SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL *

+

+    show max_identifier_length

+

+    Show Client_Encoding

+

+

+DATA TYPE SUPPORT MATRIX   (type synonyms not listed) @=Yet-to-be-Implemented

+

+    HyperSQL type               wid prec scale |  Driver type oid adtsz atttypm

+    --------------------------- --- ---- ----- -  ----------- --- ---   ---

+    TINYINT                       8    3    0  |  HSQL_TINYINT 9999 1    -1

+    SMALLINT                     16    5    0  |  int2         21   2    -1

+    INTEGER                      32   10    0  |  int4         23   4    -1

+    BIGINT                       64   19    0  |  int8         20   8    -1

+    NUMERIC(p?,s?)                  [100]  [0] |  numeric    1700  -1   [-1]**

+    FLOAT(p?)                   128   [0]   0  |  float8      701   8    -1**

+    DOUBLE                      128    0    0  |  float8      701   8    -1

+    BOOLEAN                            0    0  |  bool         16   1    -1

+    CHAR(1l)* =                       [1]++ 0  |  bpchar     1042  -1    [1]

+    VARCHAR(1l)                       [0]   0  |  varchar    1043  -1   [-1]

+                  If precision unlimited/0:    |  text         25  -1    -1

+LITERAL, simple atomic str+:CHARACTER len   0  |  unknown     705  -2    -1

+DERIVED, compound str+:   VARCHAR  prtlen   0  |  text         25  -1    -1

+    CLOB(1l)                          [0]   0  |  @

+    BINARY(1l)*                       [0]   0  |  bytea        17  -1    -1

+    VARBINARY(1l)                     [0]   0  |  bytea        17  -1    -1

+    BLOB(1l)                          [0]   0  |  @

+    BIT(1l)*                          [1]   0  |  bit       1560   -1    -1

+    BIT VARYING(1l)                   [0]   0  |  varbit    1562   -1    -1

+    OTHER                              0    0  |  @

+    DATE                               0    0  |  date       1082   4    -1

+    TIME(p0)                           0   [0] |  time       1083   8   [-1]

+    TIME(p0) WITH TIME ZONE            0   [0] |  time_with_tmzone 1266 12 [-1]

+    TIMESTAMP(p0)                      0   [6] |  timestamp_no_tmzone 1114 8[-1]

+    TIMESTAMP (p0) WITH TIME ZONE      0   [6] |  datetime  ?1184   8 [-1]*****

+    INTERVAL...(p2,p0)                [2]  [6] |  tinterval  1186  16  [-1]****

+* these types present at least a facade of data values always padded to the

+  specified length.

+** atttypmod for numerics determines column size and scale.

+     atttypmod = (precision << 16) + scale + 4

+     (but there seems to be a bug in psqlodbc where this still does not work).

+*** Postgresql seems to use the FLOAT(x) precisions specifier just to decide

+ whether to create a float4 or float8 column.

+**** I get atttypmod value of 2147418111 for INTERVAL(3)

+    = short of 32767 + short of -1 and 217418110 for INTERVAL(2)

+    So far unsuccessful to reverse engineer atttypmods for INTERVALs.

+    As of today, support for following HyperSQL INTERVAL variants:

+      DAY TO SECOND, HOUR TO SECOND, MINUTE TO SECOND, SECOND.

+***** Seems to be a driver bug here.  Should return 1296 for TIMESTAMP, not

+      1184 for DATETIME.

++:  If HyperSQL determines the output is a known constant size, it sets the

+    precision to that.  That seems to be the intention of Postgresql, but PG is

+    not as smart about figuring out when expressions will resolve to a constant.

+    When combining a constant and a col., HyperSQL confusingly some really

+    crazy lengths.  I haven't figured out the method or intention.

+++: This defaults to 1 instead of 0 if sql.enforce_strict_size is set.

+

+Interval types seem to be wildly different between PG and HyperSQL.

+I believe that for all interval literals, precisions will automatically be set

+ to preserve the specified value (unless you specify the precisions).

+ Therefore, in practice, precision specs are usually only useful in col. defs.

+PG:  INTERVAL(p);  Where [0] <= p <= 6 (sub-sec. resolution, trunk/round vary!)

+     Resolution years to microsecond.  Literals:

+     '1 12:59:10 ago'  ==  '1 day 12 hours 59 min 10 sec ago'

+     '1.234' = '1.234 sec'

+     '-8 days - 12:59:10.472'

+HS:  Resolution is either in months or (sub)seconds.  Can't mix.

+   p1 [2], p2[0].

+     INTERVAL NON_SECOND(p1) TO NON_SECOND

+   Or

+     INTERVAL NON_SECOND(p1) TO SECOND(p2)

+   Or

+     INTERVAL NON_SECOND(p1)

+   Or

+     INTERVAL SECOND(p1,p2)

+   Literals

+       INTERVAL '145 23:12:19.345' DAY(3) TO SECOND(3)

+         = INTERVAL '3503:12:19.345' HOUR TO SECOND(3)

+       INTERVAL '19.345' SECOND(4,3)

+

+

+REFERENCES

+

+    JDBC type mapping tables.  Section "Tables for Type Mapping" of Sun's

+    "Getting Started with the JDBC API", which is section 9.9 of the current

+    version, but this section number changes with document revisions.

+    http://java.sun.com/javase/6/docs/technotes/guides/jdbc/getstart/mapping.html#1038075

+

+    psqlodbc code repository.  Module "psqlodbc" at

+      :pserver:anonymous@cvs.pgfoundry.org:/cvsroot/psqlodbc

+    This is the code base that our odbc driver forked from.

+

+    Protocol specification:

+    http://www.postgresql.org/docs/8.3/interactive/protocol.html

+

+    Article on ODBC escape sequences.  May support these some day.

+    http://www.ibprovider.com/eng/documentation/odbc_escape_sequences_eng.html

diff --git a/doc/readme-docauthors.txt b/doc/readme-docauthors.txt
new file mode 100644
index 0000000..a138372
--- /dev/null
+++ b/doc/readme-docauthors.txt
@@ -0,0 +1,43 @@
+$Id: readme-docauthors.txt 844 2009-01-19 15:02:56Z unsaved $

+

+BUILDING

+

+You need JDK 1.5 or later and Ant 1.7 or later.

+

+Run "ant gen-docs" from the build subdirectory.

+Error messages should be self-explanatory.

+

+

+SYSTEM

+

+See http://pub.admc.com/howtos/ant-docbook-howto/system-chapt.html#system-features-sect and

+http://pub.admc.com/howtos/ant-docbook-howto/tips-app.html for

+important tips.  This HOWTO document explains the build system used here.

+

+

+EDITING

+

+Use DocBook v. 5 syntax in your DocBook source XML files.

+

+Because of the amount of extra infrastructure needed for DocBook olinking,

+we are not supporting direct inter-document linking.  If you want to refer

+from one DocBook document to content in another one, then add a link to

+the canonical document (like using a &distro_bseurl;/guide/index.html link)

+and just describe the location referred to.

+

+Top-level DocBook source files for individual DocBook documents reside at

+doc-src/X/X.xml.  Other files may be xincluded into these files, and lots of

+other resources are referenced or pulled in from under doc-src.

+

+Please use the product name HyperSQL in major titles.  Where introducing

+HyperSQL, use a subtitle like "aka HSQLDB".

+In the text, use "HyperSQL" as the product name.

+In filepaths and package names you code as required for the filepath or package

+name, of course.

+

+Don't capitalize words or phrases to emphasize them (including in

+section titles or headings).

+If you want to emphasize something a certain way, then use a DocBook emphasis

+role, and leave the presentation decisions to the style sheets.

+It is very easy to set a CSS style to capitalize headings if you want them to

+appear that way.

diff --git a/doc/util-guide/apa.html b/doc/util-guide/apa.html
new file mode 100644
index 0000000..e85ac40
--- /dev/null
+++ b/doc/util-guide/apa.html
@@ -0,0 +1,212 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Appendix&nbsp;A.&nbsp;HyperSQL File Links</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HyperSQL, Hsqldb, Hypersonic, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="up" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="prev" href="transfer-tool-chapt.html" title="Chapter&nbsp;4.&nbsp;Transfer Tool">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="transfer-tool-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Appendix&nbsp;A.&nbsp;HyperSQL File Links</td><td align="right" width="30%">&nbsp;</td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;4.&nbsp;Transfer Tool&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="N10E8E"></a>HyperSQL File Links</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>HyperSQL Files referred to in this Guide</i>
+</h3>
+</div>
+</div>
+</div>
+<p>
+    HyperSQL files referred to in the text may be retrieved from the
+    canonical HyperSQL documentation site, http://hsqldb.org/doc/2.0, or from the
+    same location you are reading this page from.
+  </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+    If you are reading this document with a standalone PDF reader,
+    only the http://hsqldb.org/doc/2.0/... links will function.
+  </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="itemizedlist">
+<p class="title">
+<b>
+      Pairs of local + http://hsqldb.org/doc/2.0 links for referenced files.
+    </b>
+</p>
+<ul type="disc">
+<li>
+<a name="sqltool.rc-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/sqltool.rc" target="_top">../verbatim/sample/sqltool.rc</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/sqltool.rc" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/sqltool.rc</a>
+      
+</p>
+</li>
+<li>
+<a name="sampledata.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/sampledata.sql" target="_top">../verbatim/sample/sampledata.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/sampledata.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/sampledata.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="sample.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/sample.sql" target="_top">../verbatim/sample/sample.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/sample.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/sample.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="pl.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/pl.sql" target="_top">../verbatim/sample/pl.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/pl.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/pl.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="plsql.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/plsql.sql" target="_top">../verbatim/sample/plsql.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/plsql.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/plsql.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="dsv-sample.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/dsv-sample.sql" target="_top">../verbatim/sample/dsv-sample.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/dsv-sample.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/dsv-sample.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="sqljrt.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/testrun/sqltool/sqljrt.sql" target="_top">../verbatim/testrun/sqltool/sqljrt.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/testrun/sqltool/sqljrt.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/testrun/sqltool/sqljrt.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="sqlpsm.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/testrun/sqltool/sqlpsm.sql" target="_top">../verbatim/testrun/sqltool/sqlpsm.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/testrun/sqltool/sqlpsm.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/testrun/sqltool/sqlpsm.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="SqlFileEmbedder.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java" target="_top">../verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java</a>
+      
+</p>
+<p>
+      
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java</a>
+      
+</p>
+</li>
+<li>
+<a name="SqlTool.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/cmdline/SqlFile.html" target="_top">../apidocs/org/hsqldb/cmdline/SqlFile.html</a>
+      
+</p>
+<p>
+      
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jcmdline/SqlFile.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jcmdline/SqlFile.html</a>
+      
+</p>
+</li>
+</ul>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3539 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="transfer-tool-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;</td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;4.&nbsp;Transfer Tool&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/util-guide/book-pref.html b/doc/util-guide/book-pref.html
new file mode 100644
index 0000000..557bb43
--- /dev/null
+++ b/doc/util-guide/book-pref.html
@@ -0,0 +1,149 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Preface</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HyperSQL, Hsqldb, Hypersonic, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="up" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="prev" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="next" href="sqltool-chapt.html" title="Chapter&nbsp;1.&nbsp;SqlTool">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="index.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Preface</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="sqltool-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">HyperSQL Utilities Guide&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;1.&nbsp;SqlTool</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="preface" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="book-pref"></a>Preface</h2>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="book-pref.html#altformats-sect">Available formats for this document</a></span>
+</dt>
+</dl>
+</div>
+<p>If you notice any mistakes in this document, please email the author
+    listed at the beginning of the chapter. If you have problems with the
+    procedures themselves, please use the HSQLDB support facilities which are
+    listed at <a class="link" href="http://hsqldb.org/web/hsqlSupport.html" target="_top">http://hsqldb.org/web/hsqlSupport.html</a>.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="altformats-sect"></a>Available formats for this document</h2>
+</div>
+</div>
+</div>
+<p>This document is available in several formats.</p>
+<p>
+      You may be reading this document right now at http://hsqldb.org/doc/2.0, or in
+      a distribution somewhere else.
+      I hereby call the document distribution from which you are reading 
+      this, your <span class="emphasis"><em>current distro</em></span>.
+  </p>
+<p>
+      http://hsqldb.org/doc/2.0 hosts the latest production versions of all available formats.
+      If you want a different format of the same <span class="emphasis"><em>version</em></span>
+      of the document you are reading now, then you should try your
+      current distro.
+      If you want the latest production version, you should try http://hsqldb.org/doc/2.0.
+  </p>
+<p>
+      Sometimes, distributions other than http://hsqldb.org/doc/2.0 do not host all
+      available formats.
+      So, if you can't access the format that you want in your current
+      distro, you have no choice but to use the newest production version at 
+      http://hsqldb.org/doc/2.0.
+  </p>
+<p>
+    
+<div class="table">
+<a name="altformats-tbl"></a>
+<p class="title">
+<b>Table&nbsp;1.&nbsp;Available formats of this document</b>
+</p>
+<div class="table-contents">
+<table summary="Available formats of this document" cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">format</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">your distro</th><th style="border-bottom: 0.5pt solid ; " align="left">at http://hsqldb.org/doc/2.0</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              Chunked HTML
+          </td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              <a class="link" href="index.html" target="_top">index.html</a>
+          </td><td style="border-bottom: 0.5pt solid ; " align="left">
+          <a class="link" href="http://hsqldb.org/doc/2.0/util-guide/" target="_top">http://hsqldb.org/doc/2.0/util-guide/</a>
+          </td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              All-in-one HTML
+          </td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              <a class="link" href="util-guide.html" target="_top">util-guide.html</a>
+          </td><td style="border-bottom: 0.5pt solid ; " align="left">
+        <a class="link" href="http://hsqldb.org/doc/2.0/util-guide/util-guide.html" target="_top">http://hsqldb.org/doc/2.0/util-guide/util-guide.html</a>
+          </td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left">
+              PDF
+          </td><td style="border-right: 0.5pt solid ; " align="left">
+              <a class="link" href="util-guide.pdf" target="_top">util-guide.pdf</a>
+          </td><td style="" align="left">
+          <a class="link" href="http://hsqldb.org/doc/2.0/util-guide/util-guide.pdf" target="_top">http://hsqldb.org/doc/2.0/util-guide/util-guide.pdf</a>
+          </td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+    If you are reading this document now with a standalone PDF reader, the
+    <span class="guilabel">your distro</span> links may not work.
+  </p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3539 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="index.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="sqltool-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">HyperSQL Utilities Guide&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;1.&nbsp;SqlTool</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/util-guide/dbm-chapt.html b/doc/util-guide/dbm-chapt.html
new file mode 100644
index 0000000..cb2d2c4
--- /dev/null
+++ b/doc/util-guide/dbm-chapt.html
@@ -0,0 +1,463 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;3.&nbsp;Database Manager</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, Database, Manager">
+<meta name="keywords" content="HyperSQL, Hsqldb, Hypersonic, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="up" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="prev" href="test-utility-chapt.html" title="Chapter&nbsp;2.&nbsp;Hsqldb Test Utility">
+<link rel="next" href="transfer-tool-chapt.html" title="Chapter&nbsp;4.&nbsp;Transfer Tool">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="test-utility-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;3.&nbsp;Database Manager</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="transfer-tool-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;2.&nbsp;Hsqldb Test Utility&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;4.&nbsp;Transfer Tool</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="dbm-chapt"></a>Chapter&nbsp;3.&nbsp;Database Manager</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_intro-sect">Brief Introduction</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_tree-sect">Auto tree-update</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm-autoconn-sect">Automatic Connection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_rcfile-sect">RC File</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_wold-sect">Using the current DatabaseManagers with an older HSQLDB
+      distribution.</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_applet-sect">DatabaseManagerSwing as an Applet</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_intro-sect"></a>Brief Introduction</h2>
+</div>
+</div>
+</div>
+<p>The Database Manager tool is a simple GUI database query tool with
+      a tree display of the tables. Both AWT and SWING versions of the tool
+      are available and work almost identically. The AWT version class name is
+      org.hsqldb.util.DatabaseManager; the SWING version,
+      org.hsqldb.util.DatabaseManagerSwing. The SWING version has more
+      refinements than the AWT version.</p>
+<p>The AWT version of the database manager can be deployed as an
+      applet in a browser. A demo HTML file with an embedded Database Manager
+      is included in the /demo directory.</p>
+<p>When the Database Manager is started, a dialogue allows you to
+      enter the JDBC driver, URL, user and password for the new connection. A
+      drop-down box, Type, offers preset values for JDBC driver and URL for
+      most popular database engines, including HSQLDB. Once you have selected
+      an item from this drop-down box, you should edit the URL to specify the
+      details of the database or any additional properties to pass. You should
+      also enter the username and password before clicking on the OK
+      button.</p>
+<p>The connection dialogue allows you to save the settings for the
+      connection you are about to make. You can then access the connection in
+      future sessions. To save a connection setting, enter a name in the
+      Setting Name box before clicking on the OK button. Next time the
+      connection dialogue is displayed, the drop-down box labeled Recent will
+      include the name for all the saved connection settings. When you select
+      a name, the individual settings are displayed in the appropriate
+      boxes.</p>
+<p>The small Clr button next to the drop-down box allows you to clear
+      all the saved settings. If you want to modify an existing setting, first
+      select it from the drop-down box then modify any of the text boxes
+      before making the connection. The modified values will be saved.</p>
+<p>Most SWING menu items have context-sensitive tool tip help text
+      which will appear if you hold the mouse cursor still over the desired
+      menu item. (Assuming that you don't turn Tooltips off under the
+      <span class="guimenu">Help</span> menu.</p>
+<p>The database object tree in the SWING version allows you to
+      right click on the name of a table or column and choose from common SQL
+      statements for the object, for example SELECT * FROM thistable ... If
+      you click on one of the given choices, the sample statement is copied to
+      the command window, where you can modify and complete it.</p>
+<p>The DatabaseManagers do work with HSQLDB servers serving
+      TLS-encrypted JDBC data. See the TLS section of the Listeners chapter of
+      the <a class="link" href="distro_baseurl_DEFAULTVAL/guide/index.html" target="_top">
+      HyperSQL User Guide</a>
+</p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>If you are using DatabaseManagerSwing with Oracle, you will
+        want to make sure that <span class="guimenuitem">Show row counts</span> and
+        <span class="guimenuitem">Show row counts</span> are both off
+        <span class="emphasis"><em>before connecting to the database</em></span>. You may also
+        want to turn off Auto tree-update, as described in the next
+        section.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_tree-sect"></a>Auto tree-update</h2>
+</div>
+</div>
+</div>
+<p>By default, the object tree in the left panel is refreshed when
+      you execute DDL which may update those objects. If you are on a slow
+      network or performance-challenged PC, use the <span class="guimenu">view</span> /
+      <span class="guimenuitem">Auto-refresh tree</span> menu item to turn it off.
+      You will then need to use the
+      <span class="guimenu">view</span><span class="guimenuitem">Refresh tree</span> menu item
+      every time that you want to refresh the tree.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Auto-refresh tree does not automatically show all updates to
+        database objects, it only refreshes when you submit DDL which may
+        update database objects. (This behavior is a compromise between
+        utility and performance).</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm-autoconn-sect"></a>Automatic Connection</h2>
+</div>
+</div>
+</div>
+<p>You can use command-line switches to supply connection
+      information. If you use these switch(es), then the connection dialog
+      window will be skipped and a JDBC connection will be established
+      immediately. Assuming that the <code class="filename">hsqldb.jar</code> (or an
+      alternative jar) are in your <code class="varname">CLASSPATH</code>, this command
+      will list the available command-line options. <div class="informalexample">
+<pre class="screen">    java org.hsqldb.util.DatabaseManagerSwing --help</pre>
+</div>
+</p>
+<p>It's convenient to skip the connection dialog window if you
+      always work with the same database account.</p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Use of the --password switch is not secure. Everything typed
+        on command-lines is generally available to other users on the
+        computer. The problem is compounded if you use a network connection to
+        obtain your command line. The RC File section explains how you can set
+        up automatic connections without supplying a password on the command
+        line.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_rcfile-sect"></a>RC File</h2>
+</div>
+</div>
+</div>
+<p>You can skip the connection dialog window securely by putting
+      the connection information into an RC file and then using the
+      <code class="literal">--urlid</code> switch to DatabaseManager or
+      DatabaseManagerSwing. This strategy is great for adding launch menu
+      items and/or launch icons to your desktop. You can set up one icon for
+      each of the database accounts which you regularly use.</p>
+<p>The default location for the RC file is
+      <code class="filename">dbmanager.rc</code> in your home directory. The <a class="link" href="sqltool-chapt.html#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section
+      explains how to put the connection information into this text file. If
+      you also run <a class="link" href="sqltool-chapt.html" title="Chapter&nbsp;1.&nbsp;SqlTool">SqlTool</a>, then you can share the RC file with
+      SqlTool by using a sym-link (if your operating system supports sym
+      links), or by using the <code class="literal">--rcfile</code> switch for either
+      SqlTool or DatabaseManagerSwing.</p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Use your operating system facilities to prevent others from
+        reading your RC file, since it contains passwords.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>To set up launch items/icons, first experiment on your command
+      line to find exactly what command works. For example, <div class="informalexample">
+<pre class="screen">java -cp /path/to/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing --urlid mem</pre>
+</div> Then, use your window manager to add an item that
+      runs this command.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_wold-sect"></a>Using the current DatabaseManagers with an older HSQLDB
+      distribution.</h2>
+</div>
+</div>
+</div>
+<p>This procedure will allow users of a legacy version of HSQLDB
+      to use all of the new features of the DatabaseManagers. You will also
+      get the new version of the SqlTool! This procedure works for distros
+      going back to 1.7.3.3 at least, probably much farther.</p>
+<p>These instructions assume that you are capable of running an
+      Ant build. See the Building Appendix of the <a class="link" href="distro_baseurl_DEFAULTVAL/guide/index.html" target="_top"> HyperSQL User
+      Guide</a>.</p>
+<div class="procedure">
+<ol type="1">
+<li>
+<p>Download and extract a current HSQLDB distribution. If you
+          don't want to use the source code, documentation, etc., you can use
+          a temporary directory and remove it afterwards.</p>
+</li>
+<li>
+<p>Cd to the build directory under the root directory where
+          you extracted the distribution to.</p>
+</li>
+<li>
+<p>Run <code class="literal">ant hsqldbutil</code>.</p>
+</li>
+<li>
+<p>If you're going to wipe out the build directory, copy
+          <code class="filename">hsqldbutil.jar</code> to a safe location
+          first.</p>
+</li>
+<li>
+<p>For now on, whenver you are going to run DatabaseManager*,
+          make sure that you have this <code class="filename">hsqldbutil.jar</code> as
+          the first item in your <code class="varname">CLASSPATH</code>.</p>
+</li>
+</ol>
+</div>
+<p>Here's a UNIX example where somebody wants to use the new
+      DatabaseManagerSwing with their older HSQLDB database, as well as with
+      Postgresql and a local application. <div class="informalexample">
+<pre class="screen">CLASSPATH=/path/to/hsqldbutil.jar:/home/bob/myapp/classes:/usr/local/lib/pg.jdbc3.jar
+export CLASSPATH
+java org.hsqldb.util.DatabaseManagerSwing --urlid urlid</pre>
+</div>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_applet-sect"></a>DatabaseManagerSwing as an Applet</h2>
+</div>
+</div>
+</div>
+<p>DatabaseManagerSwing is also an applet. You can use it in HTML,
+      JSPs, etc. Be aware that in Applet mode, actions to load or save local
+      files will be disabled, and attempts to access any server other than the
+      HTML-serving-host will fail.</p>
+<p>Since the Applet can not store or load locally saved preferences,
+      the only way to have persistent preference settings is by using Applet
+      parameters. <div class="variablelist">
+<p class="title">
+<b>DatabaseManagerSwing Applet Parameters</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">jdbcUrl</span>
+</p>
+</td><td>URL of a data source to auto-connect to. String
+              value.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">jdbcDriver</span>
+</p>
+</td><td>URL of a data source to auto-connect to. String value.
+              Defaults to
+              <code class="classname">org.hsqldb.driver.JDBCDriver</code>.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">jdbcUser</span>
+</p>
+</td><td>User name for data source to auto-connect to. String
+              value.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">jdbcPassword</span>
+</p>
+</td><td>Password for data source to auto-connect to. String
+              value. Defaults to zero-length string.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">schemaFilter</span>
+</p>
+</td><td>Display only object from this schema in the object
+              navigator. String value.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">laf</span>
+</p>
+</td><td>Look-and-feel. String value.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">loadSampleData</span>
+</p>
+</td><td>Auto-load sample data. Boolean value. Defaults to
+              false.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">autoRefresh</span>
+</p>
+</td><td>Auto-refresh the object navigator when DDL
+              modifications detected in user SQL commands. Boolean value.
+              Defaults to true.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">showRowCounts</span>
+</p>
+</td><td>Show number of rows in each table in the object
+              navigator. Boolean value. Defaults to false.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">showSysTables</span>
+</p>
+</td><td>Show system tables in the object navigator. Boolean
+              value. Defaults to false.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">showSchemas</span>
+</p>
+</td><td>Show object names like schema.name in object navigator.
+              Boolean value. Defaults to true.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">resultGrid</span>
+</p>
+</td><td>Show query results in Gui grid (as opposed to in plain
+              text). Boolean value. Defaults to true.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">showToolTips</span>
+</p>
+</td><td>Show help hover-text. Boolean value. Defaults to
+              true.</td>
+</tr>
+</tbody>
+</table>
+</div>
+</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3539 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="test-utility-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="transfer-tool-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;2.&nbsp;Hsqldb Test Utility&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;4.&nbsp;Transfer Tool</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/util-guide/dummy.html b/doc/util-guide/dummy.html
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/doc/util-guide/dummy.html
@@ -0,0 +1 @@
+
diff --git a/doc/util-guide/index.html b/doc/util-guide/index.html
new file mode 100644
index 0000000..1abbbf4
--- /dev/null
+++ b/doc/util-guide/index.html
@@ -0,0 +1,423 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>HyperSQL Utilities Guide</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HyperSQL, Hsqldb, Hypersonic, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="next" href="book-pref.html" title="Preface">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%">&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">HyperSQL Utilities Guide</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="book-pref.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">&nbsp;</td><td align="center" width="40%">&nbsp;</td><td valign="top" align="right" width="30%">&nbsp;Preface</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="book" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="N10002"></a>HyperSQL Utilities Guide</h1>
+</div>
+<table xmlns:xi="http://www.w3.org/2001/XInclude" class="titlead" cellspacing="0">
+<tr>
+<td>
+<div>
+<div class="authorgroup">
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="orgname">The HSQLB Development Group</span>
+</h3>
+</div>
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3539 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N10037"></a>
+<p>Copyright 2002-2009 The HSQL Development Group. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-03-17 11:47:21 -0400 (Wed, 17 Mar 2010) $</p>
+</div>
+</td><td class="sponsorad">
+<div xml:base="../doc-src/branding-frag.xhtml" class="branding">
+<img src="../images/hypersql_logo.png"></div>
+</td>
+</tr>
+</table>
+</div>
+<hr>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="preface"><a href="book-pref.html">Preface</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="book-pref.html#altformats-sect">Available formats for this document</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="sqltool-chapt.html">1. SqlTool</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_book_purpose-sect">Purpose, Coverage, Changes in Behavior</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N100FB">Platforms and SqlTool versions covered</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N1011D">Recent Functional Changes</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10188">New Features</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_baremin-sect">The Bare Minimum</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N102AE">Embedding</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N102C3">Non-displayable Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N102E3">Desktop shortcuts</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10344">Loading sample data</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10360">Satisfying SqlTool's CLASSPATH Requirements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_olderaccess-sect">
+          Accessing older HSQLDB Databases with SqlTool</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N103BC">App-specific Classes, Embedding, and non-HyperSQL Databases</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10403">Distributing SqlTool with your Apps</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10429">SqlTool Client PCs</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_auth-sect">RC File Authentication Setup</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_dsswitch-sect">Switching Data Sources</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_ilauth-sect">Using Inline RC Authentication</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_logging-sect">Logging</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_int-sect">Interactive Usage</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10578">SqlTool Command-Line Editing</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N1059C">Command Types</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N105B5">Command Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N105FB">Special Commands</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N106CC">Edit Buffer / History Commands</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_interactive_pl_commands-sect">PL Commands</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N107C2">? Variable</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_binary_files-sect">
+                Storing and retrieving binary files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N1080C">Command History</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10816">Shell scripting and command-line piping</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N1081F">Emulating Non-Interactive mode</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_nonint-sect">Non-Interactive</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_sqlswitch-sect">Giving SQL on the Command Line</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10871">SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_scripting-sect">Piping and shell scripting</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N108E1">Optimally Compatible SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N108F4">Comments</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10901">Special Commands and Edit Buffer Commands in SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10965">Automation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10970">Getting Interactive Functionality with SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_charencoding-sect">
+                Character Encoding</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_report-sect">Generating Text or HTML Reports</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_pl-sect">SqlTool Procedural Language</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10A08">Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_macro-sect">Macros</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10A67">PL Sample</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10A78">Logical Expressions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10AEB">Flow Control</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10B0E">Example</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_chunk-sect">Chunking</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10B2C">Why?</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10B3D">How?</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_raw-sect">Raw Mode</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_embedded-langs-sect">SQL/PSM, SQL/JRT, and PL/SQL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_dsv-sect">Delimiter-Separated-Value Imports and Exports</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10BE4">Simple DSV exports and imports using default settings</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10C1F">Specifying queries and options</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_unittest-sect">Unit Testing SqlTool</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="test-utility-chapt.html">2. Hsqldb Test Utility</a></span>
+</dt>
+<dt>
+<span class="chapter"><a href="dbm-chapt.html">3. Database Manager</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_intro-sect">Brief Introduction</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_tree-sect">Auto tree-update</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm-autoconn-sect">Automatic Connection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_rcfile-sect">RC File</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_wold-sect">Using the current DatabaseManagers with an older HSQLDB
+      distribution.</a></span>
+</dt>
+<dt>
+<span class="section"><a href="dbm-chapt.html#dbm_applet-sect">DatabaseManagerSwing as an Applet</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="transfer-tool-chapt.html">4. Transfer Tool</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="transfer-tool-chapt.html#trantool_intro-sect">Brief Introduction</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="apa.html">A. HyperSQL File Links</a></span>
+</dt>
+</dl>
+</div>
+<div class="list-of-tables">
+<p>
+<b>List of Tables</b>
+</p>
+<dl>
+<dt>1. <a href="book-pref.html#altformats-tbl">Available formats of this document</a>
+</dt>
+</dl>
+</div>
+<div class="list-of-examples">
+<p>
+<b>List of Examples</b>
+</p>
+<dl>
+<dt>1.1. <a href="sqltool-chapt.html#N10459">Sample RC File</a>
+</dt>
+<dt>1.2. <a href="sqltool-chapt.html#N107FC">Inserting binary data into database from a file</a>
+</dt>
+<dt>1.3. <a href="sqltool-chapt.html#N10801">Downloading binary data from database to a file</a>
+</dt>
+<dt>1.4. <a href="sqltool-chapt.html#N108CC">Piping input into SqlTool</a>
+</dt>
+<dt>1.5. <a href="sqltool-chapt.html#N10A6C">Simple SQL file using PL</a>
+</dt>
+<dt>1.6. <a href="sqltool-chapt.html#N10B1D">SQL File showing use of most PL features</a>
+</dt>
+<dt>1.7. <a href="sqltool-chapt.html#N10B5F">Interactive Raw Mode example</a>
+</dt>
+<dt>1.8. <a href="sqltool-chapt.html#N10B96">PL/SQL Example</a>
+</dt>
+<dt>1.9. <a href="sqltool-chapt.html#N10BA2">SQL/JRT Example</a>
+</dt>
+<dt>1.10. <a href="sqltool-chapt.html#N10BAC">SQL/PSM Example</a>
+</dt>
+<dt>1.11. <a href="sqltool-chapt.html#N10BF4">DSV Export Example</a>
+</dt>
+<dt>1.12. <a href="sqltool-chapt.html#N10C13">DSV Import Example</a>
+</dt>
+<dt>1.13. <a href="sqltool-chapt.html#N10C72">DSV Export of an Arbitrary SELECT Statement</a>
+</dt>
+<dt>1.14. <a href="sqltool-chapt.html#N10C8B">Sample DSV headerswitch settings</a>
+</dt>
+<dt>1.15. <a href="sqltool-chapt.html#N10C91">DSV targettable setting</a>
+</dt>
+</dl>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3539 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%">&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="book-pref.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%">&nbsp;</td><td valign="top" align="right" width="40%">&nbsp;Preface</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/util-guide/rejreport-sample.png b/doc/util-guide/rejreport-sample.png
new file mode 100644
index 0000000..d8c8631
--- /dev/null
+++ b/doc/util-guide/rejreport-sample.png
Binary files differ
diff --git a/doc/util-guide/sqltool-chapt.html b/doc/util-guide/sqltool-chapt.html
new file mode 100644
index 0000000..b4355ed
--- /dev/null
+++ b/doc/util-guide/sqltool-chapt.html
@@ -0,0 +1,5659 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;1.&nbsp;SqlTool</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="SqlTool, HSQLDB, HyperSQL, SQL, JDBC">
+<meta name="keywords" content="HyperSQL, Hsqldb, Hypersonic, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="up" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="prev" href="book-pref.html" title="Preface">
+<link rel="next" href="test-utility-chapt.html" title="Chapter&nbsp;2.&nbsp;Hsqldb Test Utility">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="book-pref.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;1.&nbsp;SqlTool</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="test-utility-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Preface&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;2.&nbsp;Hsqldb Test Utility</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sqltool-chapt"></a>Chapter&nbsp;1.&nbsp;SqlTool</h2>
+</div>
+<div>
+<h3 class="subtitle">
+<i>SqlTool Manual</i>
+</h3>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3607 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-01 07:18:26 -0400 (Tue, 01 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_book_purpose-sect">Purpose, Coverage, Changes in Behavior</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N100FB">Platforms and SqlTool versions covered</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N1011D">Recent Functional Changes</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10188">New Features</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_baremin-sect">The Bare Minimum</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N102AE">Embedding</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N102C3">Non-displayable Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N102E3">Desktop shortcuts</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10344">Loading sample data</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10360">Satisfying SqlTool's CLASSPATH Requirements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_olderaccess-sect">
+          Accessing older HSQLDB Databases with SqlTool</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N103BC">App-specific Classes, Embedding, and non-HyperSQL Databases</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10403">Distributing SqlTool with your Apps</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10429">SqlTool Client PCs</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_auth-sect">RC File Authentication Setup</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_dsswitch-sect">Switching Data Sources</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_ilauth-sect">Using Inline RC Authentication</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_logging-sect">Logging</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_int-sect">Interactive Usage</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10578">SqlTool Command-Line Editing</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N1059C">Command Types</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N105B5">Command Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N105FB">Special Commands</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N106CC">Edit Buffer / History Commands</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_interactive_pl_commands-sect">PL Commands</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N107C2">? Variable</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_binary_files-sect">
+                Storing and retrieving binary files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N1080C">Command History</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10816">Shell scripting and command-line piping</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N1081F">Emulating Non-Interactive mode</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_nonint-sect">Non-Interactive</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_sqlswitch-sect">Giving SQL on the Command Line</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10871">SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_scripting-sect">Piping and shell scripting</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N108E1">Optimally Compatible SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N108F4">Comments</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10901">Special Commands and Edit Buffer Commands in SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10965">Automation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10970">Getting Interactive Functionality with SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_charencoding-sect">
+                Character Encoding</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_report-sect">Generating Text or HTML Reports</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_pl-sect">SqlTool Procedural Language</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10A08">Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_macro-sect">Macros</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10A67">PL Sample</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10A78">Logical Expressions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10AEB">Flow Control</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10B0E">Example</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_chunk-sect">Chunking</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10B2C">Why?</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10B3D">How?</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_raw-sect">Raw Mode</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_embedded-langs-sect">SQL/PSM, SQL/JRT, and PL/SQL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_dsv-sect">Delimiter-Separated-Value Imports and Exports</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10BE4">Simple DSV exports and imports using default settings</a></span>
+</dt>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#N10C1F">Specifying queries and options</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="sqltool-chapt.html#sqltool_unittest-sect">Unit Testing SqlTool</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_book_purpose-sect"></a>Purpose, Coverage, Changes in Behavior</h2>
+</div>
+</div>
+</div>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+        Due to many important improvements to SqlTool, both in terms of
+        stability and features, all users of SqlTool are advised to use the
+        latest version of SqlTool, even if your database instances run with an
+        older HSQLDB version.
+        How to do this is documented in the
+      <a class="link" href="sqltool-chapt.html#sqltool_olderaccess-sect" title="Accessing older HSQLDB Databases with SqlTool">
+          Accessing older HSQLDB Databases with SqlTool</a>
+        section below.
+      </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            This document explains how to use SqlTool, the main purpose of
+            which is to read your SQL text file or stdin, and execute the SQL
+            commands therein against a JDBC database.
+            There are also a great number of features to facilitate both
+            interactive use and automation.
+            The following paragraphs explain in a general way why SqlTool is
+            better than any existing tool for text-mode interactive SQL work,
+            and for automated SQL tasks.
+            Two important benefits which SqlTool shares with other pure Java
+            JDBC tools is that users can use a consistent interface and
+            syntax to interact with a huge variety of databases-- any
+            database which supports JDBC; plus the tool itself runs on any
+            Java platform.
+            Instead of using <code class="filename">isql</code> for Sybase,
+            <code class="filename">psql</code> for Postgresql,
+            <code class="filename">Sql*plus</code> for Oracle, etc., you can
+            use SqlTool for all of them.
+            As far as I know, SqlTool is the only production-ready, pure
+            Java, command-line, generic JDBC client.
+            Several databases come with a command-line client with limited
+            JDBC abilities (usually designed for use with just their specific
+            database).
+      </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+          The SqlTool commands and settings are intuitive once you are
+          famililar with the usage idioms.
+          This Guide does not attempt to list every SqlTool command and
+          option available.
+          When you want to know what SqlTool commands or options are available
+          for a specific purpose, you need to list the commands of the
+          appropriate type with the relevant "?" command.
+          For example, as explained below, to see all Special commands, you
+          would run <code class="literal">\?</code>; and to see all DSV export options,
+          you run \x?.
+      </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+          SqlTool is purposefully not a Gui tool like Toad or DatabaseManager.
+          There are many use cases where a Gui SQL tool would be better.
+          Where automation is involved in any way, you really need a text
+          client to at least test things properly and usually to prototype
+          and try things out.
+          A command-line tool is really better for executing SQL scripts,
+          any form of automation, direct-to-file fetching, and remote client
+          usage.
+          To clarify this last, if you have to do your SQL client work on a
+          work server on the other side of a VPN connection, you will quickly
+          appreciate the speed difference between text data transmission
+          and graphical data transmission, even if using VNC or Remote Console.
+          Another case would be where you are doing some repetitive or
+          very structured work where variables or language features would
+          be useful.
+          Gui proponents may disagree with me, but scripting (of any sort)
+          is more efficient than repetitive copy &amp; pasting with a Gui
+          editor.
+          SqlTool starts up very quickly, and it takes up a tiny fraction of
+          the RAM required to run a comparably complex Gui like Toad.
+        </p>
+<p>
+          SqlTool is superior for interactive use because over many years it
+          has evolved lots of features proven to be efficient for day-to-day
+          use.
+          Four concise help commands (\?, :?, *?, and /?) list all available
+          commands of the corresponding type.
+          SqlTool doesn't support up-arrow or other OOB escapes (due to basic
+          Java I/O limitations), but it more than makes up for this limitation
+          with macros, user variables, command-line history and recall, and
+          command-line editing with extended Perl/Java regular expressions.
+          The \d commands deliver JDBC metadata information as consistently as
+          possible (in several cases, database-specific work-arounds are used
+          to obtain the underlying data even though the database doesn't
+          provide metadata according to the JDBC specs).
+          Unlike server-side language features, the same feature set works
+          for any database server.
+          Database access details may be supplied on the command line, but
+          day-to-day users will want to centralize JDBC connection details
+          into a single, protected RC file.
+          You can put connection details (username, password, URL, and other
+          optional settings) for scores of target databases into your RC file,
+          then connect to any of them whenever you want by just giving
+          SqlTool the ID ("urlid") for that database.
+          When you Execute SqlTool interactively, it behaves by default
+          exactly as you would want it to.
+          If errors occur, you are given specific error messages and you
+          can decide whether to roll back your session.
+          You can easily change this behavior to auto-commit,
+          exit-upon-error, etc., for the current session or for all
+          interactive invocations.
+          You can import or export delimiter-separated-value files.
+          If you need to run a specific statement repeatedly, perhaps changing
+          the WHERE clause each time, it is very simple to define a macro.
+        </p>
+<p>
+          When you Execute SqlTool with a SQL script, it also behaves by
+          default exactly as you would want it to.
+          If any error is encountered, the connection will be rolled back,
+          then SqlTool will exit with an error exit value.
+          If you wish, you can detect and handle error (or other) conditions
+          yourself.
+          For scripts expected to produce errors (like many scripts provided
+          by database vendors), you can have SqlTool continue-upon-error.
+          For SQL script-writers, you will have access to portable scripting
+          features which you've had to live without until now.
+          You can use variables set on the command line or in your script.
+          You can handle specific errors based on the output of SQL commands
+          or of your variables.
+          You can chain SQL scripts, invoke external programs, dump data
+          to files, use prepared statements,
+          Finally, you have a procedural language with <code class="literal">if</code>,
+          <code class="literal">foreach</code>, <code class="literal">while</code>,
+          <code class="literal">continue</code>, and <code class="literal">break</code> statements.
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N100FB"></a>Platforms and SqlTool versions covered</h3>
+</div>
+</div>
+</div>
+<p>
+            SqlTool runs on any Java 1.5 or later platform.
+            I know that SqlTool works well with Sun and OpenJDK JVMs.
+            I haven't run other vendors' JVMs in years (IBM, JRockit, etc.).
+            As my use with OpenJDK proves that I don't depend on Sun-specific
+            classes, I expect it to work well with other (1.5-compatible) Java
+            implementations.
+        </p>
+<p>
+            SqlTool no longer writes any files without being explicitly
+            instructed to.
+            Therefore, it should work fine on read-only systems, and you'll
+            never have orphaned temp files left around.
+        </p>
+<p>
+            The command-line examples in this chapter work as given on all
+            platforms (if you substitute in a normalized path in place of
+            <code class="literal">$HSQLDB_HOME</code>), except where noted otherwise.
+            When doing any significant command-line work on Windows
+            (especially shell scripting), you're better off to completely
+            avoid paths with spaces or funny characters.
+            If you can't avoid it, use double-quotes and expect problems.
+            As with any Java program, file or directory paths on the command
+            line after "java" can use forward slashes instead of back slashes
+            (this goes for System properties and the
+            <code class="varname">CLASSPATH</code> variable too).
+            I use forward slashes because they can be used consistently, and
+            I don't have to contort my fingers to type them :).
+        </p>
+<p>
+            If you are using SqlTool from a HyperSQL distribution of version
+            1.8.x or earlier, you should use the documentation with that
+            distribution, because this manual documents many new features,
+            several significant changes to interactive-only commands, and
+            a few changes effecting backwards-compatibility (see next
+            section about that).
+            This document is now updated for the current versions of SqlTool
+            and SqlFile at the time I am writing this (versions
+            3406 and 3604 correspondingly-- SqlFile is the
+            class which actually processes the SQL content for SqlTool).
+            Therefore, if you are using a version of SqlTool or SqlFile that
+            is more than a couple revisions greater, you should find a newer
+            version of this document.
+            (The imprecision is due to content-independent revision increments
+            at build time, and the likelihood of one or two
+            behavior-independent bug fixes after public releases).
+            The startup banner will report both versions when you run SqlTool
+            interactively.
+            (Dotted version numbers of SqlTool and SqlFile definitely indicate
+            ancient versions).
+        </p>
+<p>
+            This guide covers SqlTool as bundled with HSQLDB after 1.8.x.
+            <sup>[<a href="#ftn.samplelocFn" name="samplelocFn" class="footnote">1</a>]</sup>
+        
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1011D"></a>Recent Functional Changes</h3>
+</div>
+</div>
+</div>
+<p>This section lists changes to SqlTool since the last
+              major release of HSQLDB which may effect the portability
+              of SQL scripts.
+              For this revision of this document, this list consists of
+              script-impacting changes made to SqlTool
+              <span class="emphasis"><em>after</em></span> the final 1.8.0.0 HSQLDB release.
+              I'm specifically not listing changes to interactive(:)-only
+              commands ( with one legacy exception which is listed below),i
+              since these commands can't be used in SQL scripts;
+              and I'm specifically not listing backwards-compatible feature
+              additions and enhancements.
+              The reason for limiting the change list to only portability-
+              impacting changes is that a list of all enhancements since
+              just 1.8.1.1 would be pages long.
+            </p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+                 SqlTool is now bundled in the supplied file
+                 <code class="literal">sqltool.jar</code> instead of
+                 <code class="filename">hsqldb.jar</code>.
+                 Therefore, the usage idiom
+                 <code class="literal">java -jar .../hsqldb.jar</code> has changed to
+                 <code class="literal">java -jar .../sqltool.jar</code>.
+                 (depending on where you get your HyperSQL resources from,
+                 these files may be named with a version label, like
+                 <code class="filename">sqltool-1.2.3.4.jar</code>).
+                </li>
+<li>
+                 The package of SqlTool and support classes has been changed
+                 from <code class="classname">org.hsqldb.util</code> to
+                 <code class="classname">org.hsqldb.cmdline</code>.
+                 There is no change to <code class="literal">java -jar...</code> command-lines,
+                 but you will need to change the package name in SqlTool
+                 command lines of the form <code class="literal">java... org.hsqldb...</code>.
+                 This later usage is necessary if you need to modify the
+                 classpath for any reason, such as for embedding, to use a
+                 logging config file, or to use a non-HSQLDB JDBC driver.
+                </li>
+<li>
+                  SqlTool now consistently outputs \r\n line breaks when
+                  on \r\n-linebreak platforms, like Windows.
+                  This includes output written to stdout, \w files,
+                  and \o files.
+                </li>
+<li>
+                  Time type values are always output with the date as
+                  well as the time.
+                  This was required in order to produce consistent output
+                  for the wildly varying formats provided by different
+                  database vendors.
+                </li>
+<li>
+                  DSV input now takes JDBC Timestamp format with date and
+                  optionally time of day.
+                </li>
+<li>
+                  The command ":;" is now strictly an interactive command.
+                  If you want to repeat a command in an SQL scripts, just
+                  repeat the exact text of the command.
+                  Non-interactive use now has no dependency on command history.
+                </li>
+<li>
+                  The command ":w" has replace the command \w.
+                  Unlike writing "output" to a file with \w, :w is used to
+                  write SQL "commands", and this is an interactive feature.
+                </li>
+<li>
+                  Shell scripts using raw mode (e.g. PL/SQL scripts) must
+                  terminate the raw code with a line containing ".;", which
+                  will also send the code to the database for execution.
+                  (The old "." command has been changed to ":." to make it
+                  very clear that that command is now an interactive command).
+                </li>
+<li>
+                  You must use raw mode to <span class="emphasis"><em>chunk</em></span> SQL
+                  statements to your DB server.
+                  I.e., with previous versions of SqlTool, SQL statements
+                  were only sent to the DB server when a semi-colon is read
+                  at the end of a line.
+                  SqlTool now has a much more powerful parser, and individual
+                  SQL statements are sent to the DB server as soon as they
+                  are terminated with a semi-colon, regardless of line
+                  delimiters.
+                  Therefore, to send multiple SQL statements to the DB server
+                  in one transmittal, you must use raw mode.
+                </li>
+<li>
+                  The --sql argument will never automatically append a
+                  semicolon to the text you provide.
+                  If you want to execute a command ending with a semi--
+                  then type a semi.
+                </li>
+<li>
+                  Default encoding used is now the platform's default encoding
+                  instead of <code class="literal">US-ASCII</code>.
+                </li>
+<li>
+                  To minimize side-effects (especialy for instance-based
+                  programmatic usage), the only System properties used are
+                  those predefined by the JVM (incl.
+                  <code class="literal">javax.net.ssl.*</code>.
+                  Properties of the form <code class="literal">sqlfile.*</code> and
+                  <code class="literal">sqltool.*</code> are specifically no longer
+                  supported.
+                  (Less invasive configuration systems are provided to serve
+                  the same purposes).
+                </li>
+<li>
+                  SqlTool no longer displays the usage banner if none of
+                  inline-RC, urlid, SQL files are supplied, because that now
+                  starts up SqlTool with no JDBC Connection.
+                  To see the usage banner, use the <code class="literal">--help</code>
+                  command-line switch.
+                </li>
+<li>
+                  Requires Java 1.5 in order to build or run.
+                </li>
+<li>
+                  Update and row counts are not displayed in non-interactive
+                  mode.
+                  The count values are readily available in a format more
+                  suitable for scripting uses through PL variables (like with
+                  <code class="literal">*{?}</code> or <code class="literal">* VARNAME _</code>).
+                </li>
+</ul>
+</div>
+<p>
+                Although it doesn't effect scripts, I will mention a
+                significant recent change to interactive commands which could
+                confuse existing power users.
+                Special and PL commands are now stored to the edit buffer
+                and to command history, so they can be recalled and edited
+                just like SQL commands.  Now, all commands other than
+                edit/history : commands are stored to the buffer and history.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10188"></a>New Features</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+                    DSV column and row delimiters are now specified
+                    separately for input and output.
+                    This allows the input delimiters to be regular expressions.
+                    (Which in turn, allows for the next item).
+                </li>
+<li>
+                    The new default DSM import row delimiter works for
+                    standard UNIX, Windows, Mac lines.
+                    This makes DSV files portable across these platforms.
+                    (If using a change control system like Subversion, CVS,
+                    or whatever, you can now change control your .dsv files
+                    as native ASCII files).
+                </li>
+<li>
+                    Both <code class="literal">/* This kind */</code> and
+                    <code class="literal">-- This kind</code> of comments are now
+                    handled generally and intuitively, in SQL statements
+                    and in SqlTool-specific commands.
+                    (There were previously several limitations to where they
+                    could be used).
+                </li>
+<li>
+                    At the cost of adding another
+                    <span class="emphasis"><em>command type</em></span>, command aliases were
+                    replaced by / <span class="emphasis"><em>macros</em></span>.
+                    Usage (i.e., execution) is basically the same, but the new
+                    macros are much easier to define and list; and macros can
+                    be used for both PL and Special commands now (not just
+                    for SQL statements).
+                </li>
+<li>
+                    Reports Transaction Isolation level and JDBC Connection
+                    Read/Write or Read-Only state connection or request
+                    (with \j).
+                </li>
+<li>
+                    New \t command to report database exection duration times.
+                </li>
+<li>
+                    New \v command to set or report the Connection's
+                    Transaction Isolation LeVel.
+                </li>
+<li>
+                    
+<code class="literal">\d object filter</code> commands now use the
+                    filter as a regular expression, where possible, and
+                    filter may have optional prefix / to mean to match the
+                    filter against all output (not just the object name).
+                </li>
+<li>
+                    
+<code class="literal">\dX filter</code> commands now use the
+                    filter as a regular expression, where possible.
+                </li>
+<li>
+                    New <code class="varname">*DSV_TRIM_ALL</code> to automatically
+                    handle import of
+                    data which is both positional and character-delimited.
+                </li>
+<li>
+                    New \l command to log user-specified messages with
+                    <code class="classname">java.util.logging</code> or Log4j
+                    logging facility.
+                    Nothing at all is written directly to stderr.
+                </li>
+<li>
+                    All warnings and messages now use logging facility.
+                    This allows for declarative fine control of what gets
+                    logged and where the messages go to, as well as allowing
+                    for embedded apps to manage SqlTool apps in an integrated
+                    fashion with other app log entries.
+                </li>
+<li>
+                    New *DSV_RECORDS_PER_COMMIT setting to support
+                    user-specified tuning of large DSV imports.
+                </li>
+<li>
+                    (Optional) DSV log report can be customized with style
+                    sheets.
+                </li>
+<li>
+                    You can interactively (or in SQL scripts) switch JDBC data
+                    sources (with \j).
+                    SqlTool can be started and used without any data source,
+                    though you'll obviously need to connect to a data source
+                    before issuing SQL commands.
+                </li>
+<li>
+                  Array types are now supported, including in DSV imports and
+                  exports, with the exception that DSV imports do not support
+                  element values containing commas.
+                </li>
+</ul>
+</div>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_baremin-sect"></a>The Bare Minimum</h2>
+</div>
+<div>
+<h3 class="subtitle">The Bare Minimum You Need to Know to Run SqlTool</h3>
+</div>
+</div>
+</div>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            If you are using an Oracle database server, it will commit your
+            current transaction if you cleanly disconnect, regardless of
+            whether you have set auto-commit or not.
+            This will occur if you exit SqlTool (or any other client) in
+            the normal way (as opposed to killing the process or using
+            Ctrl-C, etc.).
+            This is mentioned in this section only for brevity, so I don't
+            need to mention it in the main text in the many places where
+            auto-commit is discussed.
+            This behavior has nothing to do with SqlTool.
+            It is a quirk of Oracle.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            If you want to use SqlTool, then you either have an SQL text file,
+            or you want to interactively type in SQL commands.
+            If neither case applies to you, then you are probably
+            looking at the wrong program.
+        </p>
+<div class="procedure">
+<a name="N101E0"></a>
+<p class="title">
+<b>Procedure&nbsp;1.1.&nbsp;To run SqlTool...</b>
+</p>
+<ol type="1">
+<li>
+<p>
+                    Copy the file
+                    <code class="filename"><a class="filename" href="apa.html#sqltool.rc-link">
+                    sample/sqltool.rc</a></code>
+                    <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup>
+                    of your HyperSQL distribution to your home directory and
+                    secure access to it if your computer is accessible
+                    to anybody else (most likely from the network).
+                    This file will work as-is for a Memory Only database
+                    instance; or if your target is a HyperSQL Server
+                    running on your local computer with default settings
+                    and the password for the "SA" account is blank
+                    (the SA password is blank when new HyperSQL database
+                    instances are created).
+                    Edit the file if you need to change the target Server URL,
+                    username, password, character set, JDBC driver, or TLS
+                    trust store as documented in the
+                    <a class="link" href="sqltool-chapt.html#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a>
+                    section.
+                    You could, alternatively, use the
+                    <code class="literal">--inlineRc</code> command-line switch or the
+                    \j special command to connect up to a data source, as
+                    documented below.
+                </p>
+</li>
+<li>
+<p>
+                    Find out where your <code class="filename">sqltool.jar</code> file
+                    resides.
+                    It typically resides at
+            <code class="varname">HSQLDB_HOME</code><code class="filename">/lib/sqltool.jar</code>
+                    where <code class="varname">HSQLDB_HOME</code> is the
+                    "hsqldb" directory inside the root level of your HyperSQL
+                    software installation.
+                    (For example, if you extract
+                    <code class="filename">hsqldb-9.1.0.zip</code> into
+                    <code class="filename">c:\temp</code>,
+                    your <code class="varname">HSQLDB_HOME</code> would be
+                    <code class="filename">c:/temp/hsqldb-9.1.0/hsqldb</code>.
+                    Your file may also have a version label in the file name,
+                    like <code class="filename">sqltool-1.2.3.4.jar</code>.
+                    The forward slashes work just fine on Windows).
+                    For this reason, I'm going to use
+                    "$HSQLDB_HOME/lib/sqltool.jar" as the path to
+                    <code class="filename">sqltool.jar</code> for my examples, but
+                    understand that you need to use the actual path to your
+                    own <code class="filename">sqltool.jar</code> file.
+                    (Unix users may set a real env. variable if they wish,
+                    in which case the examples may be used verbatim;
+                    Window users may do the same, but will need to dereference
+                    the variables like <code class="literal">%THIS%</code> instead of
+                    like <code class="literal">$THIS</code>).
+                </p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    My examples assume there are no spaces or funky characters
+                    in your file paths.
+                    This avoids bugs with the Windows cmd shell and makes for
+                    simpler syntax all-around.
+                    If you insist on using directories with spaces or shell
+                    metacharacters (including standard Windows home directories
+                    like <code class="filename">C:\Documents and Settings\blaine</code>),
+                    you will need to double-quote arguments containing these
+                    paths.
+                    (On UNIX you can alternatively use single-quotes to avoid
+                    variable dereferencing at the same time).
+                </p>
+</td>
+</tr>
+</table>
+</div>
+</li>
+<li>
+<p>
+                    If you are just starting with SqlTool, you are best off
+                    running your SqlTool command from a shell
+                    <span class="emphasis"><em>command-line</em></span> (as opposed to by
+                    using icons or the Windows'
+                    <span class="guimenuitem">Start/Run...</span> or
+                    <span class="guimenuitem">Start/Start Search</span>).
+                    This way, you will be sure to see error messages if you
+                    type the command wrong or if SqlTool can't start up for
+                    some reason.
+                    On recent versions of Windows, you can get a shell by
+                    running <code class="literal">cmd</code> from
+                    <span class="guimenuitem">Start/Run...</span> or
+                    <span class="guimenuitem">Start/Start Search</span>).
+                    On UNIX or Linux, any real or virtual terminal will work.
+                    </p>
+<p>
+                    On your shell command line, run
+                    <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar --help</pre>
+</div>
+                    to see what command-line arguments are available.
+                    Note that you don't need to worry about setting the
+                    <code class="varname">CLASSPATH</code>
+                    when you use the <code class="literal">-jar</code> switch
+                    to <code class="filename">java</code>.
+              </p>
+<p>
+                To run SqlTool without a JDBC connection, run
+                    <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar</pre>
+</div>
+                You won't be able to execute any SQL, but you can play with
+                the SqlTool interface (including using PL features).
+              </p>
+<p>
+                To execute SQL, you'll need the classes for the target
+                database's JDBC driver (and database engine classes for
+                <em class="glossterm">in-process</em> databases).
+                As this section is titled <span class="emphasis"><em>The Bare Minimum</em></span>,
+                I'll just say that if you are running SqlTool from a HyperSQL
+                product installation, you are all set to connect to any kind of
+                HyperSQL database.
+                This is because SqlTool will look for the file
+                <code class="filename">hsqldb.jar</code> in the same directory as
+                <code class="filename">sqltool.jar</code>, and that file contains all of
+                the needed classes.
+                (SqlTool supports all JDBC databases and does not require a
+                HyperSQL installation, but these cases would take us beyond
+                <span class="emphasis"><em>the bare minimum</em></span>).
+                So, with <code class="filename">hsqldb.jar</code> in place, you can run
+                commands like
+                    <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar mem</pre>
+</div>
+                    for interactive use, or
+                    <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar --sql="SQL statement;" mem</pre>
+</div>
+                    or
+                    <div class="informalexample">
+<pre class="screen">     java -jar $HSQLDB_HOME/lib/sqltool.jar mem filepath1.sql...</pre>
+</div>
+                    where <code class="literal">mem</code> is an
+                    <span class="emphasis"><em>urlid</em></span>,
+                    and the following arguments are paths to text SQL files.
+                    For the filepaths, you can use whatever wildcards your
+                    operating system shell supports.
+                    </p>
+<p>
+                    The <span class="emphasis"><em>urlid</em></span> <code class="literal">mem
+                    </code>in these commands is a key
+                    into your RC file, as explained in the
+                    <a class="link" href="sqltool-chapt.html#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section.
+                    Since this is a <em class="glossterm">mem:</em> type catalog,
+                    you can use SqlTool
+                    with this urlid immediately with no database setup
+                    whatsoever (however, you can't persist any changes that
+                    you make to this database).
+                    The sample sqltool.rc file also defines the urlid
+                    "localhost-sa" for a local HyperSQL Listener.
+                    At the end of this section, I explain how you can load
+                    some sample data to play with, if you want to.
+                </p>
+</li>
+</ol>
+</div>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            If SqlTool fails to connect to the specified urlid and you don't
+            know why, add the invocation parameter <code class="literal">--debug</code>.
+            This will cause SqlTool to display a stack trace from where the
+            connection attempt fails.
+            (If a connection attempt fails with the interactive \j command,
+            details will always be displayed).
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            SqlTool does not <span class="emphasis"><em>commit</em></span> SQL changes by default.
+            (You can use the <code class="literal">--autoCommit</code> command-line
+            switch to have it auto-commit).
+            This leaves it to the user's disgression whether to commit or
+            rollback their modifications.
+            If you do want your changes committed, remember to run \= before
+            quitting SqlTool.
+            (Most databases also support the SQL command
+            <code class="literal">commit;</code>),
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            If you put a file named <code class="filename">auto.sql</code> into your
+            home directory, this file will be executed automatically every
+            time that you run SqlTool interactively (unless you invoke with
+            the <code class="literal">--noAutoFile</code> switch).
+        </p>
+<p>
+            To use a JDBC Driver other than the HyperSQL driver, you can't use
+            the <code class="literal">-jar</code> switch because you need to modify the
+            classpath.
+            You must add the <code class="filename">sqltool.jar</code> file and your JDBC
+            driver classes to your classpath,
+            and you must tell SqlTool what the JDBC driver class name is.
+            The latter can be accomplished by either using the "--driver"
+            switch, or setting "driver" in your config file.
+            The <a class="link" href="sqltool-chapt.html#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section.
+            explains the second method.  Here's an example of the first method
+            (after you have set the classpath appropriately).
+            <div class="informalexample">
+<pre class="screen">java org.hsqldb.cmdline.SqlTool --driver=oracle.jdbc.OracleDriver urlid</pre>
+</div>
+</p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            If the tables of query output on your screen are all messy
+            because of lines wrapping, the best and easiest solution
+            is usually to resize your terminal emulator window to make it
+            wider.
+            (With some terms you click &amp; drag the frame edges to resize,
+            with others you use a menu system where you can enter the number
+            of columns).
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N102AE"></a>Embedding</h3>
+</div>
+<div>
+<h4 class="subtitle">Using SqlTool to execute SQL files from your own Java
+            code</h4>
+</div>
+</div>
+</div>
+<p>
+            To repeat what is stated in the JavaDoc for the
+            <code class="classname"><a class="classname" href="apa.html#SqlTool.html-link">SqlTool</a></code>
+            class itself:
+            <span class="emphasis"><em>
+              Programmatic users will usually want to use the
+              objectMain(String[]) method if they want arguments and behavior
+              exactly like command-line SqlTool. If you don't need invocation
+              parameter parsing, <code class="filename">auto.sql</code> exection, etc.,
+              you will have more control and efficiency by using the SqlFile
+              class directly. The file
+              <code class="filename"><a class="filename" href="apa.html#SqlFileEmbedder.java-link">
+                src/org/hsqldb/sample/SqlFileEmbedder.java</a></code>
+              in the HyperSQL distribution provides an example for this latter
+              strategy. 
+            </em></span>
+          
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N102C3"></a>Non-displayable Types</h3>
+</div>
+</div>
+</div>
+<p>
+            There are some SQL types which SqlTool (being a text-based
+            program) can't display properly.
+            This includes the SQL types <code class="literal">BLOB</code>,
+            <code class="literal">JAVA_OBJECT</code>, <code class="literal">STRUCT</code>,
+            and <code class="literal">OTHER</code>.
+            When you run a query that returns any of these, SqlTool will
+            save the very first such value obtained to the binary buffer
+            and will not display any output from this query.
+            You can then save the binary value to a file, as explained in the
+          <a class="link" href="sqltool-chapt.html#sqltool_binary_files-sect" title="Storing and retrieving binary files">
+                Storing and retrieving binary files</a>
+            section.
+            </p>
+<p>
+            There are other types, such as <code class="literal">BINARY</code>, which
+            JDBC can make displayable (by using ResultSet.getString()), but
+            which you may very well want to retrieve in raw binary format.
+            You can use the \b command to retrieve any-column-type-at-all
+            in raw binary format (so you can later store the value to a
+            binary file).
+            </p>
+<p>
+            Another restriction which all text-based database clients have
+            is the practical inability for the user to type in binary data
+            such as photos, audio streams, and serialized Java objects.
+            You can use SqlTool to load any binary object into a database
+            by telling SqlTool to get the insert/update datum from a file.
+            This is also explained in the
+          <a class="link" href="sqltool-chapt.html#sqltool_binary_files-sect" title="Storing and retrieving binary files">
+                Storing and retrieving binary files</a>
+            section.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N102E3"></a>Desktop shortcuts</h3>
+</div>
+</div>
+</div>
+<p>
+                Desktop shortcuts and quick launch icons are useful, especially
+                if you often run SqlTool with the same set of arguments.
+                It's really easy to set up several of them-- one for each
+                way that you invoke SqlTool (i.e., each one would start
+                SqlTool with all the arguments for one of your typical startup
+                needs).
+                One typical setup is to have one shortcut for each database
+                account which you normally use (use a different
+                <code class="literal">urlid</code> argument in each shortcut's
+                <span class="guilabel">Target</span> specification.
+            </p>
+<p>
+                Desktop icon setup varies depending on your Desktop manager,
+                of course.
+                I'll explain how to set up a SqlTool startup icon in Windows
+                XP.
+                Linux and Mac users should be able to take it from there, since
+                it's easier with the common Linux and Mac desktops.
+            </p>
+<div class="procedure">
+<a name="N102F0"></a>
+<p class="title">
+<b>Procedure&nbsp;1.2.&nbsp;Creating a Desktop Shortcut for SqlTool</b>
+</p>
+<ol type="1">
+<li>
+<p>
+                    Right click in the main Windows background.
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">New</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">Shortcut</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    
+<span class="guibutton">Browse</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    Navigate to where your good JRE lives.  For recent Sun
+                    JRE's, it installs to
+                    <code class="filename">C:\Program Files\Java\*\bin</code>
+                    by default (the * will be a JDK or JRE identifier and
+                    version number).
+                </p>
+</li>
+<li>
+<p>
+                    Select <code class="filename">java.exe</code>.
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guibutton">OK</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">Next</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    Enter any name
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">Finish</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    Right click the new icon.
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">Properties</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    Edit the <span class="guilabel">Target</span> field.
+                </p>
+</li>
+<li>
+<p>
+                    Leave the path to java.exe exactly as it is, including the
+                    quotes, but append to what is there.
+                    Beginning with a space, enter the command-line that you
+                    want run.
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guibutton">Change Icon...</span> to a pretty icon.
+                </p>
+</li>
+<li>
+<p>
+                    If you want a quick-launch icon instead of (or in addition
+                    to) a desktop shortcut icon, click and drag it to your
+                    quick launch bar.  (You may or may not need to edit the
+                    Windows Toolbar properties to let you add new items).
+                </p>
+</li>
+</ol>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10344"></a>Loading sample data</h3>
+</div>
+</div>
+</div>
+<p>
+                If you want some sample database objects and data to play
+                with, execute the
+                <code class="filename"><a class="filename" href="apa.html#sampledata.sql-link">
+                  sample/sampledata.sql</a></code> SQL file
+                <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+                To separate the sample data from your regular data, you can
+                put it into its own schema by running this before you import:
+                <div class="informalexample">
+<pre class="programlisting">    CREATE SCHEMA sampledata AUTHORIZATION dba;
+    SET SCHEMA sampledata;</pre>
+</div>
+                Run it like this from an SqlTool session
+      <pre class="programlisting">    \i HSQLDB_HOME/sample/sampledata.sql</pre>
+                where <span class="bold"><strong>HSQLDB_HOME</strong></span> is the
+                base directory of your HSQLDB software installation
+                <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+            </p>
+<p>
+                For memory-only databases, you'll need to run this every
+                time that you run SqlTool.
+                For other (persistent) databases, the data will reside in
+                your database until you drop the tables.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10360"></a>Satisfying SqlTool's CLASSPATH Requirements</h2>
+</div>
+</div>
+</div>
+<p>
+        As discussed earlier, only the single file
+        <code class="filename">sqltool.jar</code> is required to run SqlTool (the file
+        name may contain a version label like
+        <code class="filename">sqltool-1.2.3.4.jar</code>).
+        But it's useless as an SQL <span class="emphasis"><em>Tool</em></span> unless you can
+        connect to a JDBC data source, and for that you need the target
+        database's JDBC driver in the classpath.
+        For <em class="glossterm">in-process</em> catalogs, you'll also need the
+        database engine classes in the CLASSPATH.
+        The <a class="link" href="sqltool-chapt.html#sqltool_baremin-sect" title="The Bare Minimum">The Bare Minimum</a>
+        section explains that the easiest way to use SqlTool with any HyperSQL
+        database is to just use <code class="filename">sqltool.jar</code> in-place where
+        it resides in a HyperSQL installation.
+        This section explains how to satisfy the CLASSPATH requirements for
+        other setups and use cases.
+      </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_olderaccess-sect"></a>
+          Accessing older HSQLDB Databases with SqlTool</h3>
+</div>
+</div>
+</div>
+<p>
+          If you are using SqlTool to access non-HSQLDB database(s), then you
+          should use the latest and greatest-- just
+          grab the newest public release of SqlTool (like from the latest
+          public HyperSQL release) and skip this subsection.
+        </p>
+<p>
+          You are strongly encouraged to use the latest SqlTool release to
+          access older HSQLDB databases, to enjoy greatly improved SqlTool
+          robustness and features.
+          It is very easy to do this.
+          <div class="procedure">
+<ol type="1">
+<li>
+<p>
+            Obtain the latest <code class="filename">sqltool.jar</code> file.
+            One way to obtain the latest <code class="filename">sqltool.jar</code> file
+            is to download the latest HyperSQL distribution and extract that
+            single file
+            </p>
+</li>
+<li>
+<p>
+                Place (or copy) your new <code class="filename">sqltool.jar</code> file
+                right alongside the <code class="filename">hsqldb.jar</code> file for
+                your target database version.
+                If you don't have a local copy of the
+                <code class="filename">hsqldb.jar</code> file for your target database,
+                just copy it from your database server, or download the full
+                distribution for that server version and extract it.
+            </p>
+</li>
+<li>
+<p>
+                
+<span class="emphasis"><em>
+                  (If you have used older versions of SqlTool before, notice
+                  that you now invoke SqlTool by specifying the
+                  <code class="filename">sqltool.jar</code> file instead of the
+                  <code class="filename">hsqldb.jar</code>).
+                </em></span>
+                If your target database is a previous 2.x version of HyperSQL,
+                then you are finished and can use the new SqlTool for your older
+                database.  Users upgrading from a pre-2.x version please
+                continue...
+              </p>
+<p>
+                Run SqlTool like this.
+                <div class="informalexample">
+<pre class="screen">    java -jar path/to/sqltool.jar --driver=org.hsqldb.jdbcDriver...</pre>
+</div>
+                where you specify the pre-2.x JDBC driver name
+                <code class="classname">org.hsqldb.jdbcDriver</code>.
+                Give any other SqlTool parameters as you usually would.
+              </p>
+<p>
+                Once you have verified that you can access your database using
+                the <code class="literal">--driver</code> paramater as explained above,
+                edit your <code class="filename">sqltool.rc</code> file, and add a
+                new line
+                <div class="informalexample">
+<pre class="programlisting">    driver org.hsqldb.jdbcDriver</pre>
+</div>
+                after each urlid that is for a pre-2.x database.
+                Once you do this, you can invoke SqlTool as usual (i.e. you
+                no longer need the <code class="literal">--driver</code>
+                argument for your invocations).
+            </p>
+</li>
+</ol>
+</div>
+        
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N103BC"></a>App-specific Classes, Embedding, and non-HyperSQL Databases</h3>
+</div>
+</div>
+</div>
+<p>
+          For these situations, you need to add your custom, third-party, or
+          SQL driver classes to your Java CLASSPATH.
+          Java doesn't support adding arbitrary elements to the classpath when
+          you use the <code class="literal">-jar</code>, so you must set a classpath
+          containing <code class="filename">sqltool.jar</code> plus whatever else you
+          need, then invoke SqlTool without the <code class="literal">-jar</code> switch,
+          as briefly described at the end of the
+          <a class="link" href="sqltool-chapt.html#sqltool_baremin-sect" title="The Bare Minimum">The Bare Minimum</a>
+          section.
+          For embedded apps, invoke your own main class instead of SqlTool, and
+          you can invoke <code class="classname">SqlTool</code> or
+          <code class="classname">SqlFile</code> from your code base.
+        </p>
+<p>
+          To customize the classpath,
+          you need to set up your classpath by using your
+          operating system or shell variable <code class="varname">CLASSPATH</code> or
+          by using the <code class="filename">java</code> switch <code class="literal">-cp</code>
+          (or the equivalent <code class="literal">-classpath</code>).
+          I'm not going to take up space here to explain how to set up a
+          Java CLASSPATH.  That is a platform-dependent task that is
+          documented well in tons of Java introductions and tutorials.
+          What I'm responsible for telling you is <span class="emphasis"><em>what</em></span>
+          you need to add to your classpath.
+          For the non-embedded case where you have set up your CLASSPATH
+          environmental varialbe, you would invoke SqlTool like this.
+          <div class="informalexample">
+<pre class="screen">    java org.hsqldb.cmdline.SqlTool ...</pre>
+</div>
+            If you are using the <code class="literal">-cp</code> switch instead of a
+            <code class="varname">CLASSPATH</code> variable, stick it after
+            <code class="literal">java</code>.
+            After "<code class="literal">SqlTool</code>", give any SqlTool parameters
+            exactly as you would put after
+            <code class="literal">java -jar .../sqltool.jar</code> if you didn't need to
+            customize the CLASSPATH.
+            You can specify a JDBC driver class to use either with the
+            <code class="literal">--driver</code> switch to SqlTool, or in your
+            RC file stanza (the last method is usually more convenient).
+        </p>
+<p>
+          Note that without the <code class="literal">-jar</code> switch, SqlTool will
+          still automatically pull in HyperSQL JDBC driver or engine classes
+          from HyperSQL jar files in the same directory.
+          It's often a good practice to minimize your runtime classpath.
+          To prevent the possibility of pulling in classes from other HyperSQL
+          jar files, just copy <code class="filename">sqltool.jar</code> to some other
+          directory (which does not contain other HyperSQL jar files) and put
+          the path to that one in your classpath.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10403"></a>Distributing SqlTool with your Apps</h3>
+</div>
+</div>
+</div>
+<p>
+          You can distribute SqlTool along with your application, for
+          standalone or embedded invocation.
+          For embedded use, you will need to customize the classpath as
+          discussed in the previous item.
+          Either way, you should minimize your application footprint by
+          distributing only those HyperSQL jar files needed by your app.
+          You will obviously need <code class="filename">sqltool.jar</code> if you will
+          use the <code class="classname">SqlTool</code> or
+          <code class="classname">SqlFile</code> class in any way.
+          If your app will only connect to external HyperSQL listeners, then
+          build and include <code class="filename">hsqljdbc.jar</code>.
+          If your app will also <span class="emphasis"><em>run</em></span> a HyperSQL Listener,
+          you'll need to include <code class="filename">hsqldb.jar</code>.
+          If your app will connect directly to a
+          <em class="glossterm">in-process</em> catalog, then include
+          <code class="filename">hsqldbmain.jar</code>.
+          Note that you never need to include more than one of
+          <code class="filename">hsqldb.jar</code>, <code class="filename">hsqldbmain.jar</code>,
+          <code class="filename">hsqljdbc.jar</code>, since the former jars include
+          everything in the following jars.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10429"></a>SqlTool Client PCs</h3>
+</div>
+</div>
+</div>
+<p>
+          If you just want to be able to run SqlTool (interactively or
+          non-interactively) on a PC, and have no need for documentation, then
+          it's usually easiest to just copy 
+          <code class="filename">sqltool.jar</code> and <code class="filename">hsqldb.jar</code>
+          to the PCs (plus JDBC driver jars for any other target databases).
+          If you want to minize what you distribute, then build and
+          distribute <code class="filename">hsqljdbc.jar</code> or
+          <code class="filename">hsqldbmain.jar</code> instead of
+          <code class="filename">hsqldb.jar</code>, according to the criteria listed in
+          the previous sub-section.
+        </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_auth-sect"></a>RC File Authentication Setup</h2>
+</div>
+</div>
+</div>
+<p>
+            RC file authentication setup is accomplished by creating a text
+            RC configuration file.
+            In this section, when I say <span class="emphasis"><em>configuration</em></span>
+            or <span class="emphasis"><em>config</em></span> file, I mean an RC configuration
+            file.
+            RC files can be used by any JDBC client program that uses the
+            org.hsqldb.util.RCData class-- this includes
+            SqlTool, DatabaseManager, DatabaseManagerSwing.
+        </p>
+<p>
+            You can use it for your own JDBC client programs too.
+            There is example code showing how to do this at
+            <code class="filename"><a class="filename" href="apa.html#SqlFileEmbedder.java-link">
+              src/org/hsqldb/sample/SqlFileEmbedder.java</a></code>.
+        </p>
+<p>
+            The sample RC file shown here resides at
+            <code class="filename"><a class="filename" href="apa.html#sqltool.rc-link">sample/sqltool.rc</a></code>
+            in your HSQLDB distribution
+            <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+        </p>
+<div class="example">
+<a name="N10459"></a>
+<p class="title">
+<b>Example&nbsp;1.1.&nbsp;Sample RC File</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting"># $Id: sqltool.rc 3353 2009-12-15 19:52:13Z unsaved $
+
+# This is a sample RC configuration file used by SqlTool, DatabaseManager,
+# and any other program that uses the org.hsqldb.lib.RCData class.
+# See the documentation for SqlTool for various ways to use this file.
+
+# If you have the least concerns about security, then secure access to
+# your RC file.
+
+# You can run SqlTool right now by copying this file to your home directory
+# and running
+#    java -jar /path/to/sqltool.jar mem
+# This will access the first urlid definition below in order to use a 
+# personal Memory-Only database.
+# "url" values may, of course, contain JDBC connection properties, delimited
+# with semicolons.
+# As of revision 3347 of SqlFile, you can also connect to datasources defined
+# here from within an SqlTool session/file with the command "\j urlid".
+
+# You can use Java system property values in this file like this:  ${user.home}
+
+# The only feature added recently is the optional "transiso" setting,
+# which may be set to an all-caps transaction isolation level as listed
+# in the Java API Spec for java.sql.Connection.
+# Windows users are advised to use forward slashes instead of reverse slashes,
+# and to avoid paths containing spaces or other funny characters.  (This
+# recommendation applies to any Java app, not just SqlTool).
+
+# A personal Memory-Only (non-persistent) database.
+urlid mem
+url jdbc:hsqldb:mem:memdbid
+username SA
+password
+
+# A personal, local, persistent database.
+urlid personal
+url jdbc:hsqldb:file:${user.home}/db/personal;shutdown=true
+username SA
+password
+transiso TRANSACTION_READ_COMMITTED
+# When connecting directly to a file database like this, you should 
+# use the shutdown connection property like this to shut down the DB
+# properly when you exit the JVM.
+
+# This is for a hsqldb Server running with default settings on your local
+# computer (and for which you have not changed the password for "SA").
+urlid localhost-sa
+url jdbc:hsqldb:hsql://localhost
+username SA
+password
+
+
+
+# Template for a urlid for an Oracle database.
+# You will need to put the oracle.jdbc.OracleDriver class into your 
+# classpath.
+# In the great majority of cases, you want to use the file classes12.zip
+# (which you can get from the directory $ORACLE_HOME/jdbc/lib of any
+# Oracle installation compatible with your server).
+# Since you need to add to the classpath, you can't invoke SqlTool with
+# the jar switch, like "java -jar .../hsqldb.jar..." or 
+# "java -jar .../hsqlsqltool.jar...".
+# Put both the HSQLDB jar and classes12.zip in your classpath (and export!)
+# and run something like "java org.hsqldb.util.SqlTool...".
+
+#urlid cardiff2
+#url jdbc:oracle:thin:@aegir.admc.com:1522:TRAFFIC_SID
+#username blaine
+#password secretpassword
+#driver oracle.jdbc.OracleDriver
+
+
+
+# Template for a TLS-encrypted HSQLDB Server.
+# Remember that the hostname in hsqls (and https) JDBC URLs must match the
+# CN of the server certificate (the port and instance alias that follows 
+# are not part of the certificate at all).
+# You only need to set "truststore" if the server cert is not approved by
+# your system default truststore (which a commercial certificate probably
+# would be).
+
+#urlid tls
+#url jdbc:hsqldb:hsqls://db.admc.com:9001/lm2
+#username BLAINE
+#password asecret
+#truststore ${user.home}/ca/db/db-trust.store
+
+
+# Template for a Postgresql database
+#urlid blainedb
+#url jdbc:postgresql://idun.africawork.org/blainedb
+#username blaine
+#password losung1
+#driver org.postgresql.Driver
+
+# Template for a MySQL database.  MySQL has poor JDBC support.
+#urlid mysql-testdb
+#url jdbc:mysql://hostname:3306/dbname
+#username root
+#password hiddenpwd
+#driver com.mysql.jdbc.Driver
+
+# Note that "databases" in SQL Server and Sybase are traditionally used for
+# the same purpose as "schemas" with more SQL-compliant databases.
+
+# Template for a Microsoft SQL Server database
+#urlid msprojsvr
+#url jdbc:microsoft:sqlserver://hostname;DatabaseName=DbName;SelectMethod=Cursor
+# The SelectMethod setting is required to do more than one thing on a JDBC
+# session (I guess Microsoft thought nobody would really use Java for 
+# anything other than a "hello world" program).
+# This is for Microsoft's SQL Server 2000 driver (requires mssqlserver.jar
+# and msutil.jar).
+#driver com.microsoft.jdbc.sqlserver.SQLServerDriver
+#username myuser
+#password hiddenpwd
+
+# Template for a Sybase database
+#urlid sybase
+#url jdbc:sybase:Tds:hostname:4100/dbname
+#username blaine
+#password hiddenpwd
+# This is for the jConnect driver (requires jconn3.jar).
+#driver com.sybase.jdbc3.jdbc.SybDriver
+
+# Template for Embedded Derby / Java DB.
+#urlid derby1
+#url jdbc:derby:path/to/derby/directory;create=true
+#username ${user.name}
+#password any_noauthbydefault
+#driver org.apache.derby.jdbc.EmbeddedDriver
+# The embedded Derby driver requires derby.jar.
+# There'a also the org.apache.derby.jdbc.ClientDriver driver with URL
+# like jdbc:derby://&lt;server&gt;[:&lt;port&gt;]/databaseName, which requires
+# derbyclient.jar.
+# You can use \= to commit, since the Derby team decided (why???)
+# not to implement the SQL standard statement "commit"!!
+# Note that SqlTool can not shut down an embedded Derby database properly,
+# since that requires an additional SQL connection just for that purpose.
+# However, I've never lost data by not shutting it down properly.
+# Other than not supporting this quirk of Derby, SqlTool is miles ahead of ij.
+</pre>
+</div>
+</div>
+<br class="example-break">
+<p>
+            As noted in the comment (and as used in a couple examples), you
+            can use Java system properties like this: <code class="code">${user.home}</code>.
+            Windows users, please read the suggestion directed to you in the
+            file.
+        </p>
+<p>
+            You can put this file anywhere you want to, and specify the
+            location to SqlTool/DatabaseManager/DatabaseManagerSwing by
+            using the <code class="literal">--rcfile</code> argument.
+            If there is no reason to not use the default location (and there
+            are situations where you would not want to), then use the default
+            location and you won't have to give <code class="literal">--rcfile</code>
+            arguments to SqlTool/DatabaseManager/DatabaseManagerSwing.
+            The default location is <code class="filename">sqltool.rc</code> or
+            <code class="filename">dbmanager.rc</code> in your home directory
+            (corresponding to the program using it).
+            If you have any doubt about where your home directory is, just
+            run SqlTool with a phony urlid and it will tell you where it
+            expects the configuration file to be.
+            <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar x</pre>
+</div>
+</p>
+<p>
+            The config file consists of stanza(s) like this:
+        <div class="informalexample">
+<pre class="screen">    urlid web
+    url jdbc:hsqldb:hsql://localhost
+    username web
+    password webspassword</pre>
+</div>
+</p>
+<p>
+            These four settings are required for every urlid.
+            (There are optional settings also, which are described a couple
+            paragraphs down).
+            The URL may contain JDBC connection properties.
+            You can have as many blank lines and comments like
+        <div class="informalexample">
+<pre class="screen">    # This comment</pre>
+</div>
+        
+</p>
+<p>
+            in the file as you like.
+            The whole point is that the <span class="emphasis"><em>urlid</em></span> that you
+            give in your SqlTool/DatabaseManager command must match a
+            <span class="emphasis"><em>urlid </em></span> in your configuration file.
+        </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            Use whatever facilities are at  your disposal to protect your
+            configuration file.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            It should be readable, both locally and remotely, only to users
+            who run programs that need it.
+            On UNIX, this is easily accomplished by using <code class="literal">chmod/chown
+            </code> commands and making sure that it is protected from
+            anonymous remote access (like via NFS, FTP or Samba).
+        </p>
+<p>
+            You can also put the following optional settings into a urlid
+            stanza.  The setting will, of course, only apply to that urlid.
+        </p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">charset</span>
+</p>
+</td><td>
+                This is used by the SqlTool program, but not by the
+                DatabaseManager programs.
+                See the <a class="link" href="sqltool-chapt.html#sqltool_charencoding-sect" title="Character Encoding">
+                Character Encoding</a> section of the
+                <a class="link" href="sqltool-chapt.html#sqltool_nonint-sect" title="Non-Interactive">Non-Interactive</a>
+                section.
+                This is used for input and output files, not for stdin or
+                stdout, which are controlled by environmental variables and
+                Java system properties.
+                If you set no encoding for an urlid, input and outfiles will
+                use the same encoding as for stdin/stdout.
+                (As of right now, the charset setting here is not honored by
+                the \j command, but only when SqlTool loads an urlid specified
+                on the command-line).
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">driver</span>
+</p>
+</td><td>
+                Sets the JDBC driver class name.
+                You can, alternatively, set this for one
+                SqlTool/DatabaseManager invocation by using the command
+                line switch <span class="emphasis"><em>--driver</em></span>.
+                Defaults to <span class="emphasis"><em>org.hsqldb.jdbc.JDBCDriver</em></span>.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">truststore</span>
+</p>
+</td><td>
+                TLS trust keystore store file path as documented in the
+                TLS section of the Listeners chapter of the
+                <a class="link" href="http://hsqldb.org/doc/2.0/guide/index.html" target="_top">
+                  HyperSQL User Guide</a>
+                You usually only need to set this if the server is using a
+                non-publicly-certified certificate (like a self-signed
+                self-ca'd cert).
+                Relative paths will be resolved relative to the
+                <code class="varname">${user.dir}</code>
+                system property at JRE invocation time.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">transiso</span>
+</p>
+</td><td>
+                Specify the Transaction Isolation Level with an all-caps
+                string, exactly as listed in he Field Summary of the Java
+                API Spec for the class
+                <code class="classname">java.sql.Connection</code>.
+            </td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+            Property and SqlTool command-line switches override settings made
+            in the configuration file.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_dsswitch-sect"></a>Switching Data Sources</h2>
+</div>
+</div>
+</div>
+<p>
+          The \j command lets you switch JDBC Data Sources in your SQL files
+          (or interactively).
+          "\?" shows the syntax to make a connection by either RCData urlid
+          or by name + password + JDBC Url.
+          The urlid variant uses RC file of
+          <code class="filename">$HOME/sqltool.rc</code>.
+          We will add a way to specify an RC file if there is any demand for
+          that.
+        </p>
+<p>
+          You can start SqlTool without any JDBC Connection by specifying no
+          Inline RC and urlid of "-" (just a hyphen).
+          If you don't need to specify any SQL file paths, you can skip the
+          hypen, as in this example.
+            <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar --setVar=v1=one</pre>
+</div>
+          (The "-" is required when specifying one or more SQL files, in order
+          to distinguish urlid-spec from file-spec).
+          Consequently, if you invoke SqlTool with no parameters at all, you
+          will get a SqlTool session with no JDBC Connection.
+          You will obviously need to use \j before doing any database work.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_ilauth-sect"></a>Using Inline RC Authentication</h2>
+</div>
+</div>
+</div>
+<p>
+            Inline RC authentication setup is accomplished by using the
+            <code class="literal">--inlineRc</code> command-line switch on SqlTool.
+            The <code class="literal">--inlineRc</code> command-line switch takes
+            a comma-separated list of key/value elements.
+            The <code class="literal">url</code> and <code class="literal">user</code> elements
+            are required.  The rest are optional.
+            The <code class="literal">--inlineRc</code> switch is the only case where
+            you can give SQL file paths without a preceding urlid indicator
+            (an urlid or -).
+            The program knows not to look for an urlid if you give an inline.
+        </p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">url</code></span>
+</p>
+</td><td>
+                The JDBC URL of the database you wish to connect to.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">user</code></span>
+</p>
+</td><td>
+                The username to connect to the database as.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">charset</code></span>
+</p>
+</td><td>
+              Sets the character encoding. Overrides the platform default, or
+              what you have set by env variables or Java system properties.
+              (Does not effect stdin or stdout).
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">truststore</code></span>
+</p>
+</td><td>
+                The TLS trust keystore file path as documented in the TLS chapter.
+                Relative paths will be resolved relative to the current directory.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">transiso</code></span>
+</p>
+</td><td>
+                <code class="classname">java.sql.Connection</code> transaction
+                isolation level to connect with, as specified in the Java
+                API spec.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">password</code></span>
+</p>
+</td><td>
+<p>
+                You may only use this element to set empty password, like
+                <div class="informalexample">
+<pre class="screen">    password=</pre>
+</div>For any other password value, omit the
+                <code class="literal">password</code> element and you will be prompted
+                for the value.
+            </p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+            (Use the <code class="literal">--driver</code> switch instead of
+            <code class="literal">--inlineRc</code> to specify a JDBC driver class).
+            Here is an example of invoking SqlTool to connect to a standalone database.
+            <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar --inlineRc=url=jdbc:hsqldb:file:/home/dan/dandb,user=dan</pre>
+</div>
+        
+</p>
+<p>
+            For security reasons, you cannot specify a non-empty password as
+            an argument. You
+            will be prompted for a password as part of the login process.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_logging-sect"></a>Logging</h2>
+</div>
+</div>
+</div>
+<p>
+            Both the \l command and all warnings and error messages now use
+            a logging facility.
+            The logging facility hands off to Log4j if Log4j is found in the
+            classpath, and otherwise will hand off to
+            <code class="classname">java.util.logging</code>.
+            The default behavior of <code class="classname">java.util.logging</code>
+            should work fine for most users.
+            If you are using log4j and are redirecting with pipes, you may
+            want to configure a Console Appender with target of
+            <code class="literal">"System.err"</code> so that error output will go to
+            the error stream (all console output for
+            <code class="classname">java.util.logging</code> goes to stderr by default).
+            See the API specs for Log4j and for J2SE for how to configure
+            either product.
+            If you are embedding SqlTool in a product to process SQL files,
+            I suggest that you use log4j.
+            <code class="classname">java.util.logging</code> is neither scalable nor
+            well-designed.
+        </p>
+<p>
+            Run the command <code class="literal">\l?</code> to see how to use the
+            logging command <code class="literal">\l</code> in your SQL files (or
+            interactively), including what logging levels you may specify.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_int-sect"></a>Interactive Usage</h2>
+</div>
+</div>
+</div>
+<p>
+            Do read the
+            <a class="link" href="sqltool-chapt.html#sqltool_baremin-sect" title="The Bare Minimum">The Bare Minimum</a>
+            section before you read this section.
+        </p>
+<p>
+            You run SqlTool interactively by specifying no SQL filepaths on
+            the SqlTool command line.  Like this.
+            <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid</pre>
+</div>
+</p>
+<div class="procedure">
+<a name="N1055A"></a>
+<p class="title">
+<b>Procedure&nbsp;1.3.&nbsp;What happens when SqlTool is run interactively
+                (using all default settings)
+            </b>
+</p>
+<ol type="1">
+<li>
+<p>
+                SqlTool starts up and connects to the specified database,
+                using your SqlTool configuration file
+                (as explained in the
+                <a class="link" href="sqltool-chapt.html#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section).
+            </p>
+</li>
+<li>
+<p>
+                SQL file <code class="filename">auto.sql</code> in your home directory
+                is executed (if there is one),
+            </p>
+</li>
+<li>
+<p>
+                SqlTool displays a
+                banner showing the SqlTool and SqlFile version numbers and
+                describes the different command types that you can give, as
+                well as commands to list all of the specific commands available
+                to you.
+            </p>
+</li>
+</ol>
+</div>
+<p>
+            You exit your session by using the "\q" special command or ending
+            input (like with Ctrl-D or Ctrl-Z).
+        </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+          Any command may be preceded by space characters.
+          Special Commands, Edit Buffer Commands, PL Commands, Macros always
+          consist of just one line.
+        </p>
+<p>
+            These rules do not apply at all to
+            <a class="link" href="sqltool-chapt.html#sqltool_raw-sect" title="Raw Mode">Raw Mode</a>.
+            Raw mode is for use by advanced users when they want to completely
+            bypass SqlTool processing in order to enter a chunk of text for
+            direct transmission to the database engine.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10578"></a>SqlTool Command-Line Editing</h3>
+</div>
+</div>
+</div>
+<p>
+            If you are really comfortable with grep, perl, or vim, you will
+            instantly be an expert with SqlTool command-line editing.
+            Due to limitations of Java I/O, we can't use up-arrow recall,
+            which many people are used to from DosKey and Bash shell.
+            If you don't know how to use regular expressions, and don't want
+            to learn how to use them, then just forget command-recall.
+            <div class="itemizedlist">
+<p class="title">
+<b>Basic command entry (i.e., without regexps)</b>
+</p>
+<ul type="disc">
+<li>
+                    Just type in your command, and use the backspace-key to
+                    fix mistakes on the same line.
+                </li>
+<li>
+                    If you goof up a multi-line command, just hit the ENTER
+                    key twice to start over.  (The command will be moved to
+                    the buffer where it will do no harm).
+                </li>
+<li>
+                    Use the ":h" command to view your command history.
+                    You can use your terminal emulator scroll bar and copy
+                    and paste facility to repeat commands.
+                </li>
+<li>
+                    As long as you don't need to change text that is already
+                    in a command, you can easily repeat commands from the
+                    history like ":14;" to re-run command number 14 from
+                    history.
+                </li>
+<li>
+                    Expanding just a bit from the previous item, you can
+                    add on to a previous command by running a command like
+                    ":14a" (where the "a" means <span class="emphasis"><em>append</em></span>).
+                </li>
+<li>
+                   See the <a class="link" href="sqltool-chapt.html#sqltool_macro-sect" title="Macros">Macros</a>
+                    section about how to set and use macros.
+                </li>
+</ul>
+</div>
+        
+</p>
+<p>
+            If you use regular expressions to search through your command
+            history, or to modify commands, be aware that the command type
+            of commands in history are fixed.
+            You can search and modify the text after a \ or * prefix (if any),
+            but you can't search on or change a prefix (or add or remove one).
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1059C"></a>Command Types</h3>
+</div>
+</div>
+</div>
+<p>
+            When you are typing into SqlTool, you are always typing part of
+            the <span class="emphasis"><em>immediate command</em></span>.
+            If the immediate command is an SQL statement, it is executed as
+            soon as SqlTool reads in the trailing (unquoted) semi-colon.
+            Commands of the other command types are executed as soon as you
+            hit ENTER.
+            The interactive : commands can perform actions with or on the
+            edit buffer.
+            The <span class="emphasis"><em>edit buffer</em></span> usually contains a copy of
+            the last command executed, and you can always view it with the :b
+            command.
+            If you never use any : commands, you can entirely ignore the
+            edit buffer.
+            If you want to repeat commands or edit previous commands, you
+            will need to work with the edit buffer.
+            The immediate command contains whatever (and exactly what)
+            you type.
+            The command history and edit buffer may contain any type of
+            command other than comments and : commands
+            (i.e., : commands and comments are just not copied to the history
+            or to the edit buffer).
+          </p>
+<p>
+            Hopefully an example will clarify the difference between the
+            immediate command and the edit buffer.
+            If you type in the edit buffer Substitution command
+            "<code class="literal">:s/tbl/table/</code>", the :s command that you typed
+            is the immediate command (and it will never be stored to the
+            edit buffer or history, since it is a : command), but the purpose
+            of the substitution command is to modify the contents of the
+            edit buffer (perform a substitution on it)-- the goal being that
+            after your substitutions you would execute the buffer with the
+            "<code class="literal">:;</code>" command.
+            The ":a" command is special in that when you hit ENTER to execute
+            it, it copies the contents of the edit buffer to a new immediate
+            command and leaves you in a state where you are
+            <span class="emphasis"><em>appending</em></span> to that
+            <span class="emphasis"><em>immediate</em></span> command (nearly) exactly as if
+            you had just typed it in.
+        </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N105B5"></a>Command Types</h2>
+</div>
+</div>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Command types</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">SQL Statement</span>
+</p>
+</td><td>
+<p>
+                Any command that you enter which does not begin with "\", ":",
+                "* " or "/" is an SQL Statement.
+                The command is not terminated when you hit ENTER, like most
+                OS shells.
+                You terminate SQL Statements with either ";" or with a blank
+                line.
+                In the former case, the SQL Statement will be executed against
+                the SQL database and the command will go into the edit
+                buffer and SQL command history for editing or viewing later on.
+                In the former case,
+                <span class="emphasis"><em>execute against the SQL database</em></span> means
+                to transmit the SQL text to the database engine for execution.
+                In the latter case (you end an SQL Statement with a blank
+                line), the command will go to the edit buffer and SQL history,
+                but will not be executed (but you can execute it later from the
+                edit buffer).
+            </p>
+<p>
+                (Blank lines are only interpreted this way when SqlTool is
+                run interactively.
+                In SQL files, blank lines inside of SQL statements remain
+                part of the SQL statement).
+            </p>
+<p>
+                As a result of these termination rules, whenever you are
+                entering text that is not a Special Command, Edit Buffer /
+                History Command, or PL Command, you are always
+                <span class="emphasis"><em>appending</em></span> lines to an SQL Statement
+                or comment.
+                (In the case of the first line, you will be appending to an
+                empty SQL statement.  I.e. you will be starting a new SQL
+                Statement or comment).
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Special Command</span>
+</p>
+</td><td>
+                Run the command "\?" to list the Special Commands.
+                All of the Special Commands begin with "\".
+                I'll describe some of the most
+                useful Special Commands below.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Edit Buffer / History Command</span>
+</p>
+</td><td>
+                Run the command ":?" to list the Edit-Buffer/History Commands.
+                All of these commands begin with ":".
+                These commands use commands from the command history, or
+                operate upon the edit "buffer", so that
+                you can edit and/or (re-)execute previously entered commands.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">PL Command</span>
+</p>
+</td><td>
+<p>
+                Procedural Langage commands.
+                Run the command "*?" to list the PL Commands.
+                All of the PL Commands begin with "*".
+                PL commands are for setting and using scripting variables
+                and conditional and flow control statements like
+                <code class="literal">* if</code> and <code class="literal">* while</code>.
+                A few PL features (such as macros and updating and
+                selecing data directly from/to files) can be a real
+                convenience for nearly all users, so these features will be
+                discussed briefly in this section.
+                More detailed explanation of PL variables and the other
+                PL features, with examples, are covered in the
+                <a class="link" href="sqltool-chapt.html#sqltool_pl-sect" title="SqlTool Procedural Language">SqlTool Procedural Language</a> section.
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Macro Command</span>
+</p>
+</td><td>
+                Macro definition and usage commands.
+                Run the command "/?" to show the define, list, or use macros.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Raw Mode</span>
+</p>
+</td><td>
+                The descriptions of command-types above do not apply to
+                <a class="link" href="sqltool-chapt.html#sqltool_raw-sect" title="Raw Mode">Raw Mode</a>.
+                In raw mode, SqlTool
+                doesn't interpret what you type at all.  It all just
+                goes into the edit buffer which you can send to the database
+                engine.
+                Beginners can safely ignore raw mode.
+                You will never encounter it unless you run the "\."
+                special command, or define a stored procedure or function.
+                See the
+                <a class="link" href="sqltool-chapt.html#sqltool_raw-sect" title="Raw Mode">Raw Mode</a> section
+                for the details.
+            </td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N105FB"></a>Special Commands</h2>
+</div>
+</div>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Essential Special Commands</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">\?</span>
+</p>
+</td><td>
+                help
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\q</span>
+</p>
+</td><td>
+                quit
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\j...</span>
+</p>
+</td><td>
+                View JDBC Data Source details or connect up to a JDBC Data
+                Source (replacing the current connection, if any).
+                Run \? to see the syntax for the different usages.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\i path/to/script.sql</span>
+</p>
+</td><td>
+                execute the specified SQL script, then continue again
+                interactively.
+                Since SqlTool is a Java program, you can safely use forward
+                slashes in your file paths, regardless of your operating
+                system.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\=</span>
+</p>
+</td><td>
+                commit the current SQL transaction.
+                Most users are used to typing the SQL statement
+                <code class="literal">commit;</code>, but this command is crucial for
+                those databases which don't support the statement.
+                It's obviously unnecessary if you have auto-commit mode on.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\x?</span>
+</p>
+</td><td>
+                List a summary of DSV eXporting, and all available DSV options.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\m?</span>
+</p>
+</td><td>
+                List a summary of DSV iMporting, and all available DSV options.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\d?</span>
+</p>
+</td><td>
+                List a summary of the \d commands below.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dt [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dv [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\ds [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\di [table_name]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dS [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\da [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dn [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\du [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dr [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\d* [filter_substring]</span>
+</p>
+</td><td>
+<p>
+                Lists available objects of the given type.
+                <div class="itemizedlist">
+<ul type="disc">
+<li>t: non-system Tables</li>
+<li>v: Views</li>
+<li>s: Sequences</li>
+<li>i: Indexes</li>
+<li>S: System tables</li>
+<li>a: Aliases</li>
+<li>n: schema Names</li>
+<li>u: database Users</li>
+<li>r: Roles</li>
+<li>*: all table-like objects</li>
+</ul>
+</div>
+                If your database supports schemas, then the schema name will
+                also be listed.
+                </p>
+<p>
+                If you supply an optional <span class="emphasis"><em>filter substring</em></span>,
+                then only items which match the specified substring.
+                will be listed.
+                In most cases, the specified filter will be treated as a
+                regular expression matched against the candidate object names.
+                In order to take advantage of extreme server-side performance
+                benefits, however, in some cases the substring is passed to
+                the database server and the filter will processed by the server.
+                </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    The regexp test is case-sensitive!
+                    Even though in SQL queries and for the "\d objectname"
+                    command object names are usually case-insensitive, for
+                    the \dX commands, you must capitalize the filter
+                    substring exactly as it will appear in the special
+                    command output.
+                    This is an inconvenience, since the database engine
+                    will change names in SQL to default case unless you
+                    double-quote the name, but that is server-side
+                    functionality which cannot (portably) be reproduced by
+                    SqlTool.
+                    You can use spaces and other special characters in
+                    the string.
+                </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    Filter substrings ending with "." are special.
+                    If a substring ends with ".", then this means to narrow
+                    the search by the exact, case-sensitive schema name
+                    given.
+                    For example, if I run "\d* BLAINE.", this will list all
+                    table-like database objects in the "BLAINE" schema.
+                    The capitalization of the schema must be exactly the same
+                    as how the schema name is listed by the "\dn" command.
+                    You can use spaces and other special characters in
+                    the string.
+                    (I.e., enter the name exactly how you would enter it
+                    inside of double-quotes in an SQL command).
+                    This is an inconvenience, since the database engine
+                    will change names in SQL to default case unless you
+                    double-quote the name, but that is server-side
+                    functionality which cannot (portably) be reproduced by
+                    SqlTool.
+                </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    The filter string "." (just a plain dot) means the current
+                    session schema, for databases which support the concept
+                    according to the SQL standard (HyperSQL database does).
+                </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    Indexes may not be searched for by
+                    <span class="emphasis"><em>substring</em></span>, only by
+                    exact target table name.
+                    So if <code class="literal">I1</code> is an index on table
+                    <code class="literal">T1</code>, then you list this index by running
+                    "\di T1".
+                    In addition, many database vendors will report on indexes
+                    only if a target table is identified.
+                    Therefore, "\di" with no argument will fail if your database
+                    vendor does not support it.
+                </p>
+</td>
+</tr>
+</table>
+</div>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\d objectname [[/]regexp]</span>
+</p>
+</td><td>
+<p>
+                Lists names of columns in the specified table or view.
+                <code class="literal">objectname</code> may be a base table name or
+                a schema.object name.
+                </p>
+<p>
+                If you supply a filter string, then only columns with a name
+                matching the given regular expression will be listd.
+                (If no special characters are used, this just means that
+                names containing the specified substring will match).
+                You'll find this filter is a great convenience compared to
+                other database utilities, where you have to list all columns
+                of large tables when you are only interested in one of them.
+                </p>
+<p>
+                To narrow the displayed information based on all column
+                outputs, instead of just the column names, just prefix the
+                expression with /.
+                For example, to list all INTERGER columns, you could run
+                <code class="literal">\d mytable /INTEGER</code>.
+                </p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                When working with real data (as opposed to learning or playing),
+                I often find it useful to run two SqlTool sessions in two
+                side-by-side terminal emulator windows.
+                I do all of my real work in one window, and use the other
+                mostly for \d commands.
+                This way I can refer to the data dictionary while writing SQL
+                commands, without having to scroll.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+            This list here includes only the <span class="emphasis"><em>essential</em></span>
+            Special Commands, but n.b. that there are other useful Special
+            Commands which you can list by running <code class="literal">\?</code>.
+            (You can, for example, execute SQL from external SQL files, and
+            save your interactive SQL commands to files).
+            Some specifics of these other commands are specified immediately
+            below, and the
+            <a class="link" href="sqltool-chapt.html#sqltool_report-sect" title="Generating Text or HTML Reports">Generating Text or HTML Reports</a>
+            section explains how to use the "\o" and "\H" special commands to
+            generate reports.
+        </p>
+<p>
+            Be aware that the <code class="literal">\!</code> Special Command does
+            not work for external programs that read from standard input.
+            You can invoke non-interactive and graphical interactive programs,
+            but not command-line interactive programs.
+        </p>
+<p>
+            SqlTool executes <code class="literal">\!</code> programs directly, it does
+            not run an operating system shell (this is to avoid OS-specific
+            code in SqlTool).
+            Because of this, you can give as many command-line arguments
+            as you wish, but you can't use shell wildcards or redirection.
+        </p>
+<p>
+            The \w command can be used to store any command in your SQL
+            history to a file.
+            Just restore the command to the edit buffer
+            with a command like "\-4" before you give the \w command.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N106CC"></a>Edit Buffer / History Commands</h2>
+</div>
+</div>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Edit Buffer / History Commands</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">:?</span>
+</p>
+</td><td>
+                help
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:b</span>
+</p>
+</td><td>
+                List the current contents of the edit buffer.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:h</span>
+</p>
+</td><td>
+                Shows the Command History.
+                For each command which has been executed (up to the max
+                history length), the SQL command history will show the
+                command; its command number (#); and also how many commands
+                <span class="emphasis"><em>back</em></span> it is (as a negative number).
+                : commands are never added to the history list.
+                You can then use either form of the command identifier to
+                recall a command to the edit buffer (the command described
+                next) or as the target of any of the following : commands.
+                This last is accomplished in a manner very similar to the
+                vi editor.
+                You specify the target command number between the colon
+                and the command.
+                As an example, if you gave the command
+                <code class="literal">:s/X/Y/</code>, that would perform the
+                substitution on the contents of the edit buffer; but if you
+                gave the command <code class="literal">:-3 s/X/Y/</code>, that would
+                perform the substitution on the command 3 back in the
+                command history (and copy the output to the edit buffer).
+                Also, just like vi, you can identify the command to recall
+                by using a regular expression inside of slashes, like
+                <code class="literal">:/blue/ s/X/Y/</code> to operate on the last
+                command you ran which contains "blue".
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:13  OR  :-2  OR   :/blue/</span>
+</p>
+</td><td>
+<p>
+                Recalls a command from Command history to the edit buffer.
+                Enter ":" followed by the positive command number from
+                Command history, like ":13"...  or ":" followed by a negative
+                number like ":-2" for two commands back in the Command
+                history... or ":" followed by a regular expression inside
+                slashes, like ":/blue/" to recall the last command which
+                contains "blue".
+                The specified command  will be written to the edit buffer
+                so that you can execute it or edit it using the commands below.
+                </p>
+<p>
+                As described under the :h command immediately above,
+                you can follow the command number here with
+                any of the commands below to perform the given operation
+                on the specified command from history instead of on the
+                edit buffer contents.
+                So, for example, ":4;" would load command 4 from history
+                then execute it (see the ":;" command below).
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:;</span>
+</p>
+</td><td>
+                Executes the SQL, Special or PL statement in the edit buffer
+                (by default).
+                This is an extremely useful command.
+                It's easy to remember because it consists of ":", meaning
+                <span class="emphasis"><em>Edit Buffer Command</em></span>, plus a
+                line-terminating ";", (which generally means to execute an
+                SQL statement, though in this case it will also execute a
+                special or PL command).
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:a</span>
+</p>
+</td><td>
+<p>
+                Enter append mode with the contents of the edit buffer (by
+                default) as the current command.
+                When you hit ENTER, things will be nearly exactly the same
+                as if you
+                physically re-typed the command that is in the edit buffer.
+                Whatever lines you type next will be appended to the immediate
+                command.
+                As always, you then have the choice of hitting ENTER to
+                execute a Special or PL command, entering a blank line to
+                store back to the edit buffer, or end a SQL statement with
+                semi-colon and ENTER to execute it.
+                </p>
+<p>
+                You can, optionally, put a string after the :a, in which
+                case things will be exactly as just described except the
+                additional text will also be appended to the new immediate
+                command.
+                If you put a string after the :a which ends with ;, then
+                the resultant new immediate command will just be executed
+                right away, as if you typed in and entered the entire thing.
+                </p>
+<p>
+                If your edit buffer contains
+                <code class="literal">SELECT x FROM mytab</code> and you run
+                <code class="literal">a:le</code>, the resultant command will be
+                <code class="literal">SELECT x FROM mytable</code>.
+                If your edit buffer contains
+                <code class="literal">SELECT x FROM mytab</code> and you run
+                <code class="literal">a: ORDER BY y</code>, the resultant command will be
+                <code class="literal">SELECT x FROM mytab ORDER BY y</code>.
+                Notice that in the latter case the append text begins with a
+                space character.
+            </p>
+<p>
+                You may notice that you can't use the left-arrow or backspace
+                key to back up over the original text.
+                This is due to Java and portability constraints.
+                If you want to edit existing text, then you shouldn't use the
+                Append command.
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:s/from regex/to string/switches</span>
+</p>
+</td><td>
+<p>
+                The Substitution Command is the primary method for SqlTool
+                command editing-- it operates upon the current edit buffer
+                by default.
+                The "to string" and the "switches" are both optional (though
+                the final "/" is not).
+                To start with, I'll discuss the use and behavior if you don't
+                supply any substitution mode switches.
+                </p>
+<p>
+                Don't use "/" if it occurs in either "from string" or "to
+                string".
+                You can use any character that you want in place of "/", but
+                it must not occur in the <span class="emphasis"><em>from</em></span> or
+                <span class="emphasis"><em>to</em></span> strings.
+                Example
+                <div class="informalexample">
+<pre class="screen">    :s@from string@to string@</pre>
+</div>
+</p>
+<p>
+                The <span class="emphasis"><em>to string </em></span> is substituted for the first
+                occurrence of the (case-specific)
+                <span class="emphasis"><em>from string</em></span>.
+                The replacement will consider the entire SQL statement, even
+                if it is a multi-line statement.
+                </p>
+<p>
+                In the example above, the from regex was a plain string, but
+                it is interpreted as a regular expression so you can do
+                all kinds of powerful substitutions.
+                See the <code class="literal">perlre</code> man page, or the
+                <a class="link" href="http://http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html" target="_top">java.util.regex.Pattern</a>
+                API Spec for everything you need to know about extended
+                regular expressions.
+                </p>
+<p>
+                Don't end a <span class="emphasis"><em>to</em></span> string with ";" in attempt
+                to make a command execute.
+                There is a substitution mode switch to use for that purpose.
+                </p>
+<p>
+                You can use any combination of the substitution mode switches.
+                <div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>
+                        Use "i" to make the searches for
+                        <span class="emphasis"><em>from regex</em></span> case insensitive.
+                    </p>
+</li>
+<li>
+<p>
+                        Use "g" to substitute Globally, i.e., to subsitute
+                        <span class="emphasis"><em>all</em></span> occurrences of the
+                        <span class="emphasis"><em>from regex</em></span> instead of only the
+                        first occurrence found.
+                    </p>
+</li>
+<li>
+<p>
+                        Use ";" to execute the command immediately after the
+                        substitution is performed.
+                    </p>
+</li>
+<li>
+<p>
+                        Use "m" for ^ and $ to match each line-break in a
+                        multi-line edit buffer, instead of just at the very
+                        beginning and every end of the entire buffer.
+                    </p>
+</li>
+</ul>
+</div>
+            
+</p>
+<p>
+                If you specify a command number (from the command history),
+                you end up with a feature very reminiscent of vi, but even
+                more powerful, since the Perl/Java regular expression are
+                a superset of the vi regular expressions.
+                As an example,
+                <div class="informalexample">
+<pre class="screen">    :24 s/pin/needle/g;</pre>
+</div> would start with command number 24 from
+                command history, substitute "needle" for all occurrences of
+                "pin", then execute the result of that substitution
+                (and this final statement will of course be copied to the
+                edit buffer and to command history).
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:w /path/to/file.sql</span>
+</p>
+</td><td>
+                This appends the contents of the current buffer (by default)
+                to the specified file.
+                Since what is being written are Special, PL, or SQL commands,
+                you are effectively creating an SQL script.
+            </td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+            I find the ":/regex/"  and ":/regex/;" constructs particularly
+            handy for every-day usage.
+            <div class="informalexample">
+<pre class="screen">    :/\\d/;</pre>
+</div>re-executes the last \d command that you gave
+            (The extra "\" is needed to escape the special meaning of "\"
+            in regular expressions).
+            It's great to be able to recall and execute the last "insert"
+            command, for example, without needing to check the history or
+            keep track of how many commands back it was.  To re-execute
+            the last insert command, just run ":/insert/;".
+            If you want to be safe about it, do it in two steps to verify
+            that you didn't accidentally recall some other command which
+            happened to contain the string "insert", like
+            <div class="informalexample">
+<pre class="screen">    :/insert/
+    :;</pre>
+</div>(Executing the last only if you are
+            satisfied when SqlTool reports what command it restored).
+            Often, of course, you will want to change the command before
+            re-executing, and that's when you combine the :s and :a commands.
+        </p>
+<p>
+            We'll finish up with a couple fine points about Edit/Buffer
+            commands.
+            You generally can't use PL variables in Edit/Buffer commands, to
+            eliminate possible ambiguities and complexities when modifying
+            commands.
+            The :w command is an exception to this rule, since it can be
+            useful to use variables to determine the output file, and this
+            command does not do any "editing".
+        </p>
+<p>
+            The :? help explains how you can change the default regular
+            expression matching behavior (case sensitivity, etc.), but
+            you can always use syntax like "(?i)" inside of your regular
+            expression, as described in the Java API spec for class
+            <code class="classname"><a class="classname" href="http://http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html" target="_top">
+              java.util.regex.Pattern</a></code>.
+            History-command-matching with the /regex/ construct is
+            purposefully liberal, matching any portion of the command,
+            case sensitive, etc., but you can still use the method just
+            described to modify this behavior.  In this case, you could
+            use "(?-i)" at the beginning of your regular expression to
+            be case-sensitive.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_interactive_pl_commands-sect"></a>PL Commands</h2>
+</div>
+</div>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Essential PL Command</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">* VARNAME = value</span>
+</p>
+</td><td>
+<p>
+                Set the value of a variable.
+                If the variable doesn't exist yet, it will be created.
+                The most common use for this is so that you can later use
+                it in SQL statements, print statements, and PL conditionals,
+                by using the <code class="literal">*{VARNAME}</code> or
+                <code class="literal">*{:VARNAME}</code> construct.
+                The only difference between <code class="literal">*{literal}</code> and
+                <code class="literal">*{:VARNAME}</code> is that the former produces an
+                error if VARNAME is not set, whereas the latter will expand
+                to a zero-length string if VARNAME is not set.
+            </p>
+<p>
+                If you put variable definitions into the SQL file
+                <code class="filename">auto.sql</code> in your home directory, those
+                variables will always be available for interactive use.
+            </p>
+<p>
+                PL variables can be expanded within all commands other than
+                : edit/history commands.
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* load VARNAME /file/path.txt</span>
+</p>
+</td><td>
+                Sets VARNAME to the content of the specified ASCII file.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* prepare VARNAME</span>
+</p>
+</td><td>
+                Indicate that next command should be a SQL INSERT or UPDATE
+                command containing one question mark.
+                The value of VARNAME will be substuted for the ? variable.
+                This does work for CLOB columns.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* VARNAME _</span>
+</p>
+</td><td>
+                When next SQL command is run, instead of displaying the rows,
+                just store the very first column value to variable VARNAME.
+                This works for CLOB columns too.
+                It also works with Oracle XML type columns if you use
+                column labels and the <code class="literal">getclobval</code> function.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* VARNAME ~</span>
+</p>
+</td><td>
+<p>
+                Exactly the same as
+                <pre class="programlisting">    * VARNAME ~</pre>
+                except that the fetched results will be displayed in addition
+                to setting the variable.
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* dump VARNAME /file/path.txt</span>
+</p>
+</td><td>
+                Store the value of VARNAME to the specified ASCII file.
+            </td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N107C2"></a>? Variable</h3>
+</div>
+</div>
+</div>
+<p>
+            You don't set the ? variable.
+            It is just like the Bourne shell variable $? in that it is always
+            automatically set to the first value of a result set (or the
+            return value of other SQL commands).
+            It works just like the <code class="literal">* VARNAME ~</code>
+            command described above, but it all happens automatically.
+            You can, of course, dereference ? like any PL variable, but it
+            does not list with the <code class="literal">list</code> and
+            <code class="literal">listvalues</code> commands.
+            You can see the value whenever you want by running
+            <div class="informalexample">
+<pre class="programlisting">    \p *{?}</pre>
+</div>
+          
+</p>
+<p>
+            Note that PL commands are used to upload and download column
+            values to/from local ASCII files, but the corresponding actions
+            for binary files use the special \b commands.
+            This is because PL variables are used for ASCII values and
+            you can store any number of column values in PL variables.
+            This is not true for binary column values.
+            The \b commands work with a single binary byte buffer.
+        </p>
+<p>
+            See the <a class="link" href="sqltool-chapt.html#sqltool_pl-sect" title="SqlTool Procedural Language">SqlTool Procedural Language</a> section
+            below for information on using variables in other ways, and
+            information on the other PL commands and features.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_binary_files-sect"></a>
+                Storing and retrieving binary files</h3>
+</div>
+</div>
+</div>
+<p>
+            You can upload binary files such as photographs, audio files,
+            or serialized Java objects into database columns.
+            SqlTool keeps one binary buffer which you can load from files
+            with the \bl command, or from a database query by doing a
+            one-row query for any non-displayable type (including
+            <code class="literal">BLOB</code>, <code class="literal">OBJECT</code>, and
+            <code class="literal">OTHER</code>).
+            In the latter case, the data returned for the first
+            non-displayable column of the first result row will be stored
+            into the binary buffer.
+        </p>
+<p>
+            Once you have data in the binary buffer, you can upload it
+            to a database column (including <code class="literal">BLOB</code>,
+            <code class="literal">OBJECT</code>, and <code class="literal">OTHER</code> type
+            columns), or save it to a file.
+            The former is accomplished by the special command \bp followed
+            by a <span class="emphasis"><em>prepared</em></span> SQL query containing one
+            question mark place-holder to indicate where the data gets
+            inserted.
+            The latter is accomplished with the \bd command.
+        </p>
+<p>
+            You can also store the output from normal, displayable column
+            into the binary buffer by using the special command \b.
+            The very first column value from the first result row of the
+            next SQL command will be stored to the binary byte buffer.
+        </p>
+<div class="example">
+<a name="N107FC"></a>
+<p class="title">
+<b>Example&nbsp;1.2.&nbsp;Inserting binary data into database from a file</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    \bl /tmp/favoritesong.mp3
+    \bp
+    INSERT INTO musictbl (id, stream) VALUES(3112, ?);</pre>
+</div>
+</div>
+<br class="example-break">
+<div class="example">
+<a name="N10801"></a>
+<p class="title">
+<b>Example&nbsp;1.3.&nbsp;Downloading binary data from database to a file</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    SELECT stream FROM musictbl WHERE id = 3112;
+    \bd /tmp/favoritesong.mp3</pre>
+</div>
+</div>
+<br class="example-break">
+<p>
+            You can also store and retrieve text column values to/from
+            ASCII files, as documented in the
+            <a class="link" href="sqltool-chapt.html#sqltool_interactive_pl_commands-sect" title="PL Commands">Essential PL Command</a>
+            section.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1080C"></a>Command History</h3>
+</div>
+</div>
+</div>
+<p>
+            The SQL history shown by the \h command, and used by other commands,
+            is truncated to 100 entries, since its utility comes from being
+            able to quickly view the history list.
+            You can change the history length by setting the system property
+            <code class="literal">sqltool.historyLength</code> to the desire integer
+            value (using any of the System Property mechanisms provided by
+            Java).
+            If there is any demand, I'll make the setting of this value more
+            convenient.
+        </p>
+<p>
+            The SQL history list contains all executed commands other than
+            Edit Buffer commands and comments, even if the command has a
+            syntax error or fails upon execution.
+            The reason for including bad commands is so that you can
+            recall and fix them if you wish to.
+            The same applies to the edit buffer.
+            If you copy a command to the edit buffer by entering blank
+            line, or if you edit the edit buffer, that edit buffer value
+            will never make it into the command history until and if
+            you execute it.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10816"></a>Shell scripting and command-line piping</h3>
+</div>
+</div>
+</div>
+<p>
+            You normally use non-interactive mode for input piping.
+            You specify "-" as the SQL file name.
+            See the <a class="link" href="sqltool-chapt.html#sqltool_scripting-sect" title="Piping and shell scripting">Piping and shell scripting</a>
+            subsection of the Non-Interactive chapter.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1081F"></a>Emulating Non-Interactive mode</h3>
+</div>
+</div>
+</div>
+<p>
+            You can run SqlTool <span class="emphasis"><em>interactively</em></span>, but
+            have SqlTool behave exactly as if it were processing an SQL
+            file (i.e., no command-line prompts, error-handling
+            that defaults to fail-upon-error, etc.).
+            Just specify "-" as the SQL file name in the command line.
+            This is a good way to test what SqlTool will do when it
+            encounters any specific command in an SQL file.
+            See the <a class="link" href="sqltool-chapt.html#sqltool_scripting-sect" title="Piping and shell scripting">Piping and shell scripting</a>
+            subsection of the Non-Interactive chapter for an example.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_nonint-sect"></a>Non-Interactive</h2>
+</div>
+</div>
+</div>
+<p>
+            Read the <a class="link" href="sqltool-chapt.html#sqltool_int-sect" title="Interactive Usage">Interactive Usage</a>
+            section if you have not already,
+            because much of what is in this section builds upon that.
+            You can skip all discussion about Command History and the
+            edit buffer if you will not use those interactive features.
+        </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            If you're doing data updates, remember to issue a commit command
+            or use the <code class="literal">--autoCommit</code> switch.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            As you'll see, SqlTool has many features that are very
+            convenient for scripting.  But what really makes it superior for
+            automation tasks (as compared to SQL tools from other vendors)
+            is the ability to reliably detect errors and to control JDBC
+            transactions.
+            SqlTool is designed so that you can reliably determine if errors
+            occurred within SQL scripts themselves, and from the invoking
+            environment (for example, from a perl, Bash, or Python script,
+            or a simple cron tab invocation).
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_sqlswitch-sect"></a>Giving SQL on the Command Line</h3>
+</div>
+</div>
+</div>
+<p>
+                If you just have a couple Commands to run, you can run them
+                directly from the comand-line or from a shell script without an
+                SQL file, like this.
+              <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar --sql="SQL statement;" urlid</pre>
+</div>
+            
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>The <code class="literal">--sql</code> switch automatically implies
+                <code class="literal">--noinput</code>, so if you want to execute the
+                specified SQL before <span class="emphasis"><em>and in addition to</em></span> an
+                interactive session (or stdin piping), then you must also give
+                the <span class="emphasis"><em>--stdinput</em></span> switch.
+              </p>
+</td>
+</tr>
+</table>
+</div>
+            
+</p>
+<p>
+                Since SqlTool transmits SQL statements to the database engine
+                only when a line is terminated with ";", if you want feedback
+                from multiple SQL statements in an --sql expression, you will
+                need to use functionality of your OS shell to include
+                linebreaks after the semicolons in the expression.
+                With any Bourne-compatible shell, you can include linebreaks in
+                the SQL statements like this.
+                <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar --sql='
+        SQL statement number one;
+        SQL statement
+            number two;
+        SQL statement three;
+    ' urlid</pre>
+</div>
+            
+</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                The multi-line examples in this section will only work as-is
+                with a Bourne-compatible shell.
+                With some ugliness they can be converted to C shell.
+                For Windows, you are better off to stick with SQL files for
+                multi-line input.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+                If you don't need feedback, just separate the SQL commands
+                with semicolons and the entire expression will be
+                <a class="link" href="sqltool-chapt.html#sqltool_chunk-sect" title="Chunking">chunked</a>.
+            </p>
+<p>
+                The <span class="emphasis"><em>--sql</em></span> switch is very useful for
+                setting shell variables to the output of SQL Statements, like
+                this.
+                <div class="informalexample">
+<pre class="programlisting">    # A shell script
+    USERCOUNT=`java -jar $HSQLDB_HOME/lib/sqltool.jar --sql='
+        select count(*) from usertbl;
+    ' urlid` || {
+        # Handle the SqlTool error
+    }
+    echo "There are $USERCOUNT users registered in the database."
+    [ "$USECOUNT" -gt 3 ] &amp;&amp; {   # If there are more than 3 users registered
+        # Some conditional shell scripting</pre>
+</div>
+            
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10871"></a>SQL Files</h3>
+</div>
+</div>
+</div>
+<p>
+                Just give paths to sql text file(s) on the command line after
+                the <span class="emphasis"><em>urlid</em></span>.
+            </p>
+<p>
+                Often, you will want to redirect output to a file, like
+                <div class="informalexample">
+<pre class="screen"> java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql... &gt; /tmp/file.log 2&gt;&amp;1</pre>
+</div>
+</p>
+<p>
+                You can also execute SQL files from an interactive session with
+                the "\i"' Special Command,
+                but be aware that the default behavior in an interactive
+                session is to continue upon errors.
+                If the SQL file was written without any concern for error
+                handling, then the file will continue to execute after errors
+                occur.
+                You could run <code class="literal">\c false</code> before
+                <code class="literal">\i filename</code>, but then your SqlTool session
+                will exit if an error is encountered in the SQL file.
+                If you have an SQL file without error handling, and you want
+                to abort that file when an error occurs, but not exit
+                SqlTool, the easiest way to accomplish this is usually to add
+                <code class="literal">\c false</code> to the top of the script.
+            </p>
+<p>
+                If you specify multiple SQL files on the command-line, the
+                default behavior is to exit SqlTool immediately if any of
+                the SQL files encounters an error.
+            </p>
+<p>
+                
+<span class="bold"><strong>
+                SQL files themselves have ultimate control over error handling.
+                </strong></span>
+                Regardless of what command-line options are set, or what
+                commands you give interactively, if a SQL file gives error
+                handling statements, they will take precedence.
+            </p>
+<p>
+                You can also use \i in SQL files.
+                This results in nested SQL files.
+            </p>
+<p>
+                You can use the following SQL file,
+                <code class="filename"><a class="filename" href="apa.html#sample.sql-link">
+                  sample/sample.sql</a></code>,
+                from your HyperSQL distribution
+                <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+                It contains SQL as well as Special Commands making good
+                use of most of the Special Commands documented below.
+            </p>
+<pre class="programlisting">/*
+    $Id: sample.sql 3637 2010-06-07 00:59:13Z unsaved $
+    Exemplifies use of SqlTool.
+    PCTASK Table creation
+*/
+
+/* Ignore error for these two statements */
+\c true
+DROP TABLE pctasklist;
+DROP TABLE pctask;
+\c false
+
+\p Creating table pctask
+CREATE TABLE pctask (
+    id integer identity,
+    name varchar(40),
+    description varchar(256),
+    url varchar(80),
+    UNIQUE (name)
+);
+
+\p Creating table pctasklist
+CREATE TABLE pctasklist (
+    id integer identity,
+    host varchar(20) not null,
+    tasksequence int not null,
+    pctask integer,
+    assigndate timestamp default current_timestamp,
+    completedate timestamp,
+    show boolean default true,
+    FOREIGN KEY (pctask) REFERENCES pctask,
+    UNIQUE (host, tasksequence)
+);
+
+\p Granting privileges
+GRANT select ON pctask TO public;
+GRANT all ON pctask TO tomcat;
+GRANT select ON pctasklist TO public;
+GRANT all ON pctasklist TO tomcat;
+
+\p Inserting test records
+INSERT INTO pctask (name, description, url) VALUES (
+    'task one', 'Description for task 1', 'http://cnn.com');
+INSERT INTO pctasklist (host, tasksequence, pctask) VALUES (
+    'admc-masq', 101, (SELECT id FROM pctask WHERE name = 'task one'));
+
+commit;
+</pre>
+<p>
+                You can execute this SQL file with a Memory Only database with
+                a command like
+              <div class="informalexample">
+<pre class="programlisting">    java -jar $HSQLDB_HOME/lib/sqltool.jar  --sql='
+        create user tomcat password "x";
+    ' mem path/to/hsqldb/sample/sample.sql</pre>
+</div>
+            This shows how you can mix SQL on the command line, and SQL inside
+            an SQL file.
+            </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                The example above uses Bourne shell syntax.
+                C shell syntax would be similar.
+                You would need to use an SQL file to accomplish this on Windows.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+                (The <code class="literal">--sql="create...;"</code> arguments create an
+                account which the script uses).
+                You should see error messages between the
+                <code class="literal">Continue-on-error...true</code> and
+                <code class="literal">Continue-on-error...false</code>.  The script
+                purposefully runs commands that might fail there.
+                The reason the script does this is to perform
+                database-independent conditional table removals.
+                (The SQL clause <code class="literal">IF EXISTS</code> is more graceful
+                and succinct, so you may want to use that if you don't need to
+                support databases which don't support
+                <code class="literal">IF EXISTS</code>).
+                If an error occurs when continue-on-error is false, the
+                script would abort immedately.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_scripting-sect"></a>Piping and shell scripting</h3>
+</div>
+</div>
+</div>
+<p>
+                You can of course, redirect output
+                <span class="emphasis"><em>from</em></span> SqlTool to a file
+                or another program.
+                <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql &gt; file.txt 2&gt;&amp;1
+
+java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql 2&gt;&amp;1 | someprogram...</pre>
+</div>
+</p>
+<p>
+                You can type commands in to SqlTool while being in
+                non-interactive mode by supplying "-" as the file name.
+                This is a good way to test how SqlTool will behave when
+                processing your SQL files.
+                <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid -</pre>
+</div>
+</p>
+<p>
+                This is how you have SqlTool read its input from another
+                program:
+                <div class="example">
+<a name="N108CC"></a>
+<p class="title">
+<b>Example&nbsp;1.4.&nbsp;Piping input into SqlTool</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    echo "Some SQL commands with '$VARIABLES';" |
+    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid -</pre>
+</div>
+</div>
+<br class="example-break">
+            For a shell not as graceful as the Bourne-compatible shells, you
+            would need to type this all on the same line (or use a
+            line-continuation trick).
+            </p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+              Beware of null stdin to SqlTool (or SqlFile).
+              At least with Java 6 on UNIX, <code class="classname">System.in</code>
+              returns megabytes of garbage for reads if stdin is closed.
+              I consider this an obvious bug.
+              Therefore, unlike any other program you would invoke from scripts,
+              check stdin before running any Java program that will read from
+              it.
+              I consider this a big ugly bug in Java.
+              This is not just theoretical, because many remote execution
+              environments will have stdin closed off.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+                Make sure that you also read the
+                <a class="link" href="sqltool-chapt.html#sqltool_sqlswitch-sect" title="Giving SQL on the Command Line">Giving SQL on the Command Line</a>
+                section.
+                The <code class="literal">--sql</code> switch is a great facility to use
+                with shell scripts.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N108E1"></a>Optimally Compatible SQL Files</h3>
+</div>
+</div>
+</div>
+<p>
+                If you want your SQL scripts optimally compatible among other
+                SQL tools, then don't use any Special or PL Commands.
+                SqlTool has default behavior which I think is far superior to
+                the other SQL tools, but you will have to disable these
+                defaults in order to have optimally compatible behavior.
+            </p>
+<p>
+                These switches provide compatibilty at the cost of poor
+                control and error detection.
+                <div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>
+                            --continueOnErr=true
+                        </p>
+<p>
+                            The output will still contain error messages about
+                            everything that SqlTool doesn't like
+                            (malformatted commands, SQL command failures,
+                            empty SQL commands), but SqlTool will continue to
+                            run.
+                            Errors will not cause rollbacks (but that won't
+                            matter because of the following setting).
+                        </p>
+</li>
+<li>--autoCommit</li>
+</ul>
+</div>
+            
+</p>
+<p>
+                You don't have to worry about accidental expansion of
+                PL variables, since SqlTool will never expand PL variables
+                if you don't set any variables on the command line, or give
+                any "* " PL commands.
+                (And you could not have "* " commands in a compatible SQL
+                file).
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N108F4"></a>Comments</h3>
+</div>
+</div>
+</div>
+<p>
+                Comments of the form <code class="literal">/*...*/</code> or
+                <code class="literal">--</code> behave as a SQL programmer would
+                expect, in all contexts other than in interactive
+                edit/history commands.
+            </p>
+<p>
+                If a comment occurs outside of an SQL statement, SqlTool
+                will not send the comment to the database (to improve
+                performance).
+                Raw mode can be used to send just comments to the database.
+                In order to proactively catch accidents, SqlTool will complain
+                if you attempt to send an empty SQL statement (i.e., just
+                whitespace) to the database, even in raw mode.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10901"></a>Special Commands and Edit Buffer Commands in SQL Files</h3>
+</div>
+</div>
+</div>
+<p>
+                Don't use Edit Buffer / History Commands in your sql files,
+                because they won't work.
+                Edit Buffer / History Commands are for interactive use only.
+                (But, see the
+                <a class="link" href="sqltool-chapt.html#sqltool_raw-sect" title="Raw Mode">Raw Mode</a> section
+                for an exception).
+                You can, of course, use any SqlTool command at all
+                interactively.
+                I just wanted to group together the commands most useful to
+                script-writers.
+            </p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">\q [abort message]</span>
+</p>
+</td><td>
+<p>
+                    Be aware that the \q command will cause SqlTool to
+                    completely exit.
+                    If a script <code class="filename">x.sql</code> has a \q command in
+                    it, then it doesn't matter if the script is executed like
+          <pre class="screen">    java -jar .../sqltool.jar urlid a.sql x.sql z.sql</pre>
+                    or if you use
+                    \i to read it in interactively, or if another SQL file
+                    uses \i to nest it.
+                    If \q is encountered, SqlTool will quit.
+                    See the <a class="link" href="sqltool-chapt.html#sqltool_pl-sect" title="SqlTool Procedural Language">SqlTool Procedural Language</a>
+                    section for commands to abort an SQL file (or even parts
+                    of an SQL file) without causing SqlTool to exit.
+                </p>
+<p>
+                    \q takes an optional argument, which is an abort message.
+                    If you give an abort message, the message is displayed to
+                    the user and SqlTool will exit with a failure status.
+                    If you give no abort message, then SqlTool will exit
+                    quietly with successful status.
+                    As a result, <pre class="programlisting">    \q</pre>
+                    means to make an immediate but graceful exit, whereas
+                    <pre class="programlisting">    \q Message</pre>
+                    means to abort immediately.
+                </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\p [text to print]</span>
+</p>
+</td><td>
+                    Print the given string to stdout.
+                    Just give "\p" alone to print a blank line.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\i /path/to/file.sql</span>
+</p>
+</td><td>
+                    Include another SQL file at this location.
+                    You can use this to nest SQL files.
+                    For database installation scripts I often have a master
+                    SQL file which includes all of the other SQL files in the
+                    correct sequence.
+                    Be aware that the current continue-upon-error behavior
+                    will apply to included files until such point as the SQL
+                    file runs its own error handling commands.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\o [file/path.txt]</span>
+</p>
+</td><td>
+<p>
+                    Tee output to the specified file (or stop doing so).
+                    See the
+                    <a class="link" href="sqltool-chapt.html#sqltool_report-sect" title="Generating Text or HTML Reports">Generating Text or HTML Reports</a>
+                    section.
+                </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\=</span>
+</p>
+</td><td>
+                    A database-independent way to commit your SQL session.
+                    Useful for database which have no <code class="literal">COMMIT</code>
+                    SQL statement.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\a [true|false]</span>
+</p>
+</td><td>
+                    This turns on and off SQL transaction autocommits.
+                    Auto-commit defaults to false, but you can change that
+                    behavior by using the <code class="literal">--autoCommit</code>
+                    command-line switch.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\c [true|false]</span>
+</p>
+</td><td>
+<p>
+                    A "true" setting tells SqlTool to Continue when errors are
+                    encountered.
+                    The current transaction will not be rolled back upon SQL
+                    errors, so if \c is true, then run the
+                    <code class="literal">ROLLCACK;</code> command yourself if that's
+                    what you want to happen.
+                    The default for interactive use is to continue upon error,
+                    but the default for non-interactive use is to abort upon
+                    error.
+                    You can override this behavior by using the
+                    <code class="literal">--continueOnErr</code> command-line switch.
+                    </p>
+<p>
+                    With database setup scripts, I usually find it convenient
+                    to set "true" before dropping tables (so that things will
+                    continue if the tables aren't there), then set it back to
+                    false so that real errors are caught.
+                    <code class="literal">DROP TABLE tablename IF EXISTS;</code>
+                    is a more elegant, but less portable, way to accomplish
+                    the same thing.
+                    </p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                        It depends on what you want your SQL files to do, of
+                        course, but I usually want my SQL files to abort when
+                        an error is encountered, without necessarily killing
+                        the SqlTool session.
+                        If this is the behavior that you want, then
+                        put an explicit <code class="literal">\c false</code>
+                        at the top of your SQL file and turn on
+                        continue-upon-error only for sections where you really
+                        want to permit errors, or where you are using PL
+                        commands to handle errors manually.
+                        This will give the desired behavior whether your
+                        script is called by
+                        somebody interactively, from the SqlTool command-line,
+                        or included in another SQL file (i.e. nested).
+                    </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                        The default settings are usually best for people who
+                        don't want to put in any explicit \c or error handling
+                        code at all.
+                        If you run SQL files from the SqlTool command line,
+                        then any errors will cause SqlTool to roll back and
+                        abort immediately.
+                        If you run SqlTool interactively and invoke SQL files
+                        with \i commands, the scripts will continue to run
+                        upon errors (and will not roll back).
+                        This behavior was chosen because there are lots of
+                        SQL files out there that produce errors which can be
+                        ignored; but we don't want to ignore errors that a
+                        user won't see.
+                        I reiterate that any and all of this behavior can (and
+                        often should) be changed by Special Commands run in
+                        your interactive shell or in the SQL files.
+                        Only you know whether errors in your SQL files can
+                        safely be ignored.
+                    </p>
+</td>
+</tr>
+</table>
+</div>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10965"></a>Automation</h3>
+</div>
+</div>
+</div>
+<p>
+                SqlTool is ideal for mission-critical automation because,
+                unlike other SQL tools, SqlTool returns a dependable exit
+                status and gives you control over error handling and SQL
+                transactions.
+                Autocommit is off by default, so you can build a completely
+                dependable solution by intelligently using \c commands
+                (Continue upon Errors) and commit statements, and by
+                verifying exit statuses.
+            </p>
+<p>
+                Using the SqlTool Procedural Language, you have ultimate
+                control over program flow, and you can use variables for
+                database input and output as well as for many other purposes.
+                See the <a class="link" href="sqltool-chapt.html#sqltool_pl-sect" title="SqlTool Procedural Language">SqlTool Procedural Language</a>
+                section.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10970"></a>Getting Interactive Functionality with SQL Files</h3>
+</div>
+</div>
+</div>
+<p>
+                Some script developers may run into cases where they want to
+                run with sql files but they alwo want SqlTool's interactive
+                behavior.
+                For example, they may want to do command recall in the sql file,
+                or they may want to log SqlTool's command-line prompts (which
+                are not printed in non-interactive mode).
+                In this case, do not give the sql file(s) as an argument to
+                SqlTool, but pipe them in instead, like
+                <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar urlid &lt; filepath1.sql &gt; /tmp/log.html 2</pre>
+</div>
+                or
+              <div class="informalexample">
+<pre class="screen">cat filepath1.sql... |
+java -jar $HSQLDB_HOME/lib/sqltool.jar urlid &gt; /tmp/log.html 2&gt;&amp;1</pre>
+</div>
+            For a shell not as graceful as the Bourne-compatible shells, you
+            would need to type this all on the same line (or use a
+            line-continuation trick).
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_charencoding-sect"></a>
+                Character Encoding</h3>
+</div>
+</div>
+</div>
+<p>
+              There are several levels of encoding settings.
+              First there are your platform defaults.
+              These can be changed, temporarily or permanently, with system
+              settings or environmental variables.
+              Java system properties may be used to change the encodings for
+              the JVM run.
+              Finally, can specify a different encoding in your RC file, as
+              documented in the
+              <a class="link" href="sqltool-chapt.html#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a>
+              section, though these will not effect stdin or stdout (as
+              explained there).
+              Programmatic users of <code class="classname">SqlFile</code> have
+              complete control over encoding by setting up
+              <code class="classname">Reader</code>s and
+              <code class="classname">PrintWriter</code>s,
+              or by using constructors with an <code class="literal">encoding</code>
+              parameter.
+              Developers should understand that where a
+              <code class="filename">SqlFile</code> constructor takes a
+              <code class="classname">Reader</code> or a
+              <code class="classname">PrintWriter</code> parameter, we will not apply
+              encoding settings to them, leaving that up to you.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_report-sect"></a>Generating Text or HTML Reports</h2>
+</div>
+</div>
+</div>
+<p>
+            This section is about making a file containing the output of
+            database queries.
+            You can generate reports by using operating system facilities
+            such as redirection, tee, and cutting and pasting.
+            But it is much easier to use the "\o" and "\H" special commands.
+        </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            I've neglected the \H feature, because I don't know of anybody
+            using it.
+            Be aware that it writes very old-fashioned HTML, with no attention
+            to encoding, metadata, style sheets, etc.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="procedure">
+<a name="N109A7"></a>
+<p class="title">
+<b>Procedure&nbsp;1.4.&nbsp;Writing query output to an external file</b>
+</p>
+<ol type="1">
+<li>
+<p>
+                By default, everthing will be done in plain text.
+                If you want your report to be in HTML format, then give the
+                special command <code class="literal">\H</code>.
+                If you do so, you will probably want to use filenames with an
+                suffix of ".html" or ".htm" instead of ".txt" in the next step.
+            </p>
+</li>
+<li>
+<p>
+                Run the command <code class="literal">\o path/to/reportfile.txt</code>.
+                From this point on, output from your queries will be appended
+                to the specified file.
+                (I.e. another <span class="emphasis"><em>copy</em></span> of the output is
+                generated.)
+                This way you can continue to monitor or use output as usual as
+                the report is generated.
+            </p>
+</li>
+<li>
+<p>
+                When you want SqlTool to stop writing to the file, run
+                <code class="literal">\o</code> (or just quit SqlTool if you have no
+                other work to do).
+            </p>
+</li>
+<li>
+<p>
+                If you turned on HTML mode with <code class="literal">\H</code> before,
+                you can run <code class="literal">\H</code> again to turn it back off,
+                if you wish.
+            </p>
+</li>
+</ol>
+</div>
+<p>
+            It is not just the output of "SELECT" statements that will make
+            it into the report file, but
+            <div class="itemizedlist">
+<p class="title">
+<b>Kinds of output that get teed to \o files</b>
+</p>
+<ul type="disc">
+<li>
+                    Output of SELECT statements.
+                </li>
+<li>
+                    Output of all "\d" Special Commands.
+                    (I.e., "\dt", "\dv", etc., and "\d OBJECTNAME").
+                </li>
+<li>
+                    Output of "\p" Special Commands.
+                    You will want to use this to add titles, and perhaps
+                    spacing, for the output of individual queries.
+                </li>
+</ul>
+</div>
+            Other output will go to your screen or stdout, but will not make
+            it into the report file.
+            Be aware that no error messages will go into the report file.
+            If SqlTool is run non-interactively (including if you give any
+            SQL file(s) on the command line), SqlTool will abort with an error
+            status if errors are encountered.
+            The right way to handle errors is to check the SqlTool exit status.
+            (The described error-handling behavior can be modified with
+            SqlTool command-line switches and Special Commands).
+        </p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            Remember that \o <span class="emphasis"><em>appends</em></span> to the named file.
+            If you want a new file, then use a new file name or remove the
+            pre-existing target file ahead of time.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            So that I don't end up with a bunch of junk in my report file, I
+            usually leave \o off while I perfect my SQL.  With \o off,
+            I perfect the SQL query until it produces on my screen exactly
+            what I want saved to file.
+            At this point I turn on \o and run ":/select/;" to repeat the
+            last SQL command containing the given string ("select" in this
+            example).
+            If I have several complex queries to run, I turn \o off and
+            repeat until I'm finished.
+            (Every time you turn \o on, it will append to the file, just
+            like we need).
+            </p>
+<p>
+            Usually it doesn't come to mind that I need a wider screen until
+            a query produces lines that are too long.
+            In this case, stretch your window and repeat the last command with
+            the ":;" Edit Buffer Command.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_pl-sect"></a>SqlTool Procedural Language</h2>
+</div>
+<div>
+<h3 class="subtitle">Aka PL</h3>
+</div>
+</div>
+</div>
+<p>
+            Most importantly, run <code class="filename">SqlTool</code> interactively
+            and give the "*?" command to see what PL commands are available to
+            you.
+            I've tried to design the language features to be intuitive.
+            Readers experience with significant shell scripting in any
+            language can probably learn everything they need to know by
+            looking at (and running!) the sample script
+            <code class="filename"><a class="filename" href="apa.html#pl.sql-link">
+              sample/pl.sql</a></code> in your HyperSQL distribution
+            <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup> and
+            using the <code class="varname">*?</code> command from within an interactive
+            SqlTool session as a reference.  (By
+            <span class="emphasis"><em>significant</em></span> shell scripting, I mean to the
+            extent of using variables, for loops, etc.).
+        </p>
+<p>
+            PL variables will only be expanded after you run a PL command (or
+            set variable(s) from the command-line).
+            We only want to turn on variable expansion if the user wants
+            variable expansion.
+            People who don't use PL don't have to worry about strings getting
+            accidentally expanded.
+        </p>
+<p>
+            All other PL commands imply the "*" command, so you only need to
+            use the "*" statement if your script uses PL variables
+            and it is possible that no variables may be set before-hand (and
+            no PL commands have been run previously).
+            In this case, without "*", your script would silently use a
+            literal value like "*{x}" instead of trying to expand it.
+            With a preceding "*" command, PL will notice that the variable
+            <code class="literal">x</code> has not been set and will generate an error.
+            (If x had been set here will be no issue because setting a
+            variable automatically turns on PL variable expansion).
+        </p>
+<p>
+            PL is also used to upload and download column values to/from
+            local ASCII files, analogously to the special \b commands
+            for binary files.
+            This is explained above in the Interactive
+            <a class="link" href="sqltool-chapt.html#sqltool_interactive_pl_commands-sect" title="PL Commands">Essential PL Command</a>
+            section above.
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10A08"></a>Variables</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+                    Use the <code class="literal">* list</code> command to list some or
+                    all variables; or <code class="literal">* listvalues</code> to also
+                    see the values.
+                </li>
+<li>
+                    You can set variables using the
+                    <code class="literal">* VARNAME = value</code> command.
+                    This document explains elsewhere how you can set a values
+                    to the contents of files, and to the return value of SQL
+                    statements and fetches.
+                </li>
+<li>
+                    You can also set variables using the
+                    <code class="literal">--setvar</code> command-line switch.
+                    I give a very brief but useful example of this below.
+                </li>
+<li>
+                    SqlTool does not allow for setting system variables.
+                    As explained below, they are expanded in the same way as
+                    PL variables.
+                </li>
+<li>
+                    Variables are always expanded in SQL, Special, and PL
+                    commands if they are written like
+                    <code class="literal">*{VARNAME}</code>
+                    (assuming that a PL command has been run previously).
+                    Your SQL scripts can give good feedback by echoing the
+                    value of variables with the "\p" special command.
+                    Use the construct <code class="literal">*{:VARNAME}</code> to
+                    expand the variable, but to expand to a zero-length
+                    string instead of fail if VARNAME is not set.
+                </li>
+<li>
+                    Java system variables work the same exact way, except you
+                    use <code class="literal">$</code> instead of <code class="varname">*</code>
+                    to dereference, like so:  <code class="literal">${user.name}</code>.
+                </li>
+<li>
+                    Variables are normally written like
+                    <code class="varname">*VARNAME</code> in logical expressions to
+                    prevent them from being evaluated too early.
+                    See below about logical expressions.
+                </li>
+<li>
+<p>
+                    You can't do math with expression variables, but you
+                    can get functionality like the traditional
+                    <code class="literal">for (i = 0; i &lt; x; i++)</code> by appending
+                    to a variable and testing the string length, like
+                    <pre class="programlisting">    * while (*i &lt; ${x})
+        * i = *{i}.</pre>
+                    
+<code class="literal">i</code> will be a growing line of dots.
+                </p>
+</li>
+<li>
+<p>
+                Variable names must not contain white space, or
+                the characters "}" or "=".
+                </p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_macro-sect"></a>Macros</h3>
+</div>
+</div>
+</div>
+<p>
+                Macros are just shortcut commands that you can run in place of
+                the full commands which they stand for.
+                Macros stand for SQL, Special or PL commands, whereas PL
+                variables can only be used for elements within a command.
+                It is very easy to define, list, and use macros.
+                Run the command "/?" to see how.
+                If you often run a particular query, then for the effort of
+                about 5 extra keystrokes, you can define a macro for it so
+                that you can enter just "/q;" to run it, whether the original
+                query is 1 line or 40 lines.  (You can use any name in place
+                of "q", and the target command can be any kind of SQL,
+                special, or PL command).
+            </p>
+<p>
+                When you run/use a macro, you can append to the macro value.
+                <span class="emphasis"><em>appendage</em></span> in the "/?" listing shows
+                where you can append additional text to the original command.
+                So, if you define
+                <pre class="programlisting">    sql&gt; /= myworkers  SELECT name FROM employees</pre>
+                , you could narrow the query variously during different macro
+                invocations, like
+                <pre class="programlisting">    sql&gt; /myworkers WHERE dept = 20;
+    sql&gt; /myworkers WHERE name like 'Karen%';</pre>
+                
+</p>
+<p>
+                Just like when recalling a command from history, you use ";"
+                to execute even Special and PL macro commands.
+                <pre class="programlisting">    sql&gt; /= notate  Work completed by
+    sql&gt; /notate Blaine;</pre>
+                If you don't type the ;, you will just recall the command
+                to the buffer (from which you can execute or edit it, if
+                you wish to).
+            </p>
+<p>
+                To make a macro for a mult-line SQL statement, you use the
+                "/= name :" construct.
+                First, get the target command into the command buffer.
+                If you have already run the command, then run ":h" to see the
+                command number and load it to the buffer like ":13".
+                If you haven't run the command yet, then just enter the
+                command, but end it with a blank line (and no semi-colon).
+                You can check the buffer with ":b" to make sure it is what
+                you want.
+                Then just run "/= name :" to define a macro with name "name".
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10A67"></a>PL Sample</h3>
+</div>
+</div>
+</div>
+<p>
+                Here is a short SQL file that gives the specified user write
+                permissions on some application tables.
+            </p>
+<div class="example">
+<a name="N10A6C"></a>
+<p class="title">
+<b>Example&nbsp;1.5.&nbsp;Simple SQL file using PL</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">    /*
+       grantwrite.sql
+
+       Run SqlTool like this:
+           java -jar path/to/sqltool.jar -setvar=USER=debbie grantwrite.sql
+     */
+
+    /* Explicitly turn on PL variable expansion, in case no variables have
+       been set yet.  (Only the case if user did not set USER).
+    */
+    *
+
+    GRANT all ON book TO *{USER};
+    GRANT all ON category TO *{USER};</pre>
+</div>
+</div>
+<br class="example-break">
+<p>
+                Note that this script will work for any (existing) user just
+                by supplying a different user name on the command-line.
+                I.e., no need to modify the tested and proven script.
+                There is no need for a <code class="literal">commit</code> statement
+                in this SQL file since no DML is done.
+                If the script is accidentally run without setting the
+                USER variable, SqlTool will give a very clear notificaton of
+                that.
+            </p>
+<p>
+                The purpose of the plain "*" command is just
+                so that the *{USER} variables will be expanded.
+                (This would not be necessary if the USER variable, or any
+                other variable, were set, but we don't want to depend upon
+                that).
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10A78"></a>Logical Expressions</h3>
+</div>
+</div>
+</div>
+<p>
+                Logical expressions occur only inside of logical expression
+                parentheses in PL statements.
+                For example, <code class="literal">if (*var1 &gt; astring)</code> and
+                <code class="literal">while (*checkvar)</code>.
+                (The parentheses after "foreach" do not enclose a logical
+                expression, they just enclose a list).
+            </p>
+<p>
+                There is a critical difference between
+                <code class="literal">*{VARNAME}</code> and <code class="varname">*VARNAME</code>
+                inside logical expressions.
+                <code class="literal">*{VARNAME}</code> is expanded one time when the
+                parser first encounters the logical expression.
+                <code class="varname">*VARNAME</code> is re-expanded every time that the
+                expression is evaluated.
+                So, you would never want to code
+                <code class="literal">* while (*{X} &lt; 5)</code> because the statement
+                will always be true or always be false.
+                (I.e. the following block will loop infinitely or will never
+                run).
+            </p>
+<p>
+                Don't use quotes or whitespace of any kind in
+                <code class="literal">*{VARNAME}</code> variables in expressions.
+                (They would expand and then the expression would most likely
+                no longer be a valid expression as listed in the table below).
+                Quotes and whitespace are fine in <code class="varname">*VARNAME</code>
+                variables, but it is the entire value that will be used in
+                evaluations, regardless of whether quotes match up, etc.
+                I.e. quotes and whitespace are not <span class="emphasis"><em>special</em></span>
+                to the token evaluator.
+            </p>
+<div class="variablelist">
+<p class="title">
+<b>Logical Operators</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN</span>
+</p>
+</td><td>
+                    The token may be a literal, a <code class="literal">*{VARNAME}</code>
+                    which is expanded early, or a <code class="varname">*VARNAME</code>
+                    which is expanded late.
+                    (You usually do not want to use
+                    <code class="literal">*{VARNAME}</code> in logical expressions).
+                    False if the token is not set, empty, or "0".
+                    True otherwise.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 == TOKEN2</span>
+</p>
+</td><td>
+                    True if the two tokens are equivalent "strings".
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 &lt;&gt; TOKEN2</span>
+</p>
+</td><td>
+                    Ditto.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 &gt;&lt; TOKEN2</span>
+</p>
+</td><td>
+                    Ditto.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 &gt; TOKEN2</span>
+</p>
+</td><td>
+                    True if the TOKEN1 string is longer than TOKEN2 or is
+                    the same length but is greater according to a string sort.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 &lt; TOKEN2</span>
+</p>
+</td><td>
+                    Similarly to TOKEN1 &gt; TOKEN2.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">! LOGICAL_EXPRESSION</span>
+</p>
+</td><td>
+                    Logical negation of any of the expressions listed above.
+                </td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+                
+<code class="varname">*VARNAME</code>s in logical expressions, where the
+                VARNAME variable is not set, evaluate to an empty string.
+                Therefore <code class="literal">(*UNSETVAR = 0)</code> would be false,
+                even though <code class="literal">(*UNSETVAR)</code> by itself is false
+                and <code class="literal">(0)</code> by itself is false.
+                Another way of saying this is that <code class="varname">*VARNAME</code>
+                in a logical
+                expression is equivalent to *{:VARNAME} out of a logical
+                expression.
+            </p>
+<p>
+                When developing scripts, you definitely use SqlTool
+                interactively to verify that SqlTool evaluates logical
+                expressions as you expect.
+                Just run <code class="literal">* if</code> commands that print something
+                (i.e. \p) if the test expression is true.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10AEB"></a>Flow Control</h3>
+</div>
+</div>
+</div>
+<p>
+                Flow control works by conditionally executing blocks of
+                Commands according to conditions specified by logical
+                expressions.
+            </p>
+<p>
+                The conditionally executed blocks are called
+                <span class="emphasis"><em>PL Blocks</em></span>.
+                These PL Blocks always occur between a PL flow control
+                statement (like <code class="literal">* foreach, *while, * if</code>)
+                and a corresponding <code class="literal">* end</code> PL Command
+                (like <code class="literal">* end foreach</code>).
+            </p>
+<p>
+                The values of control variables for foreach and while PL
+                blocks will change as expected.
+            </p>
+<p>
+                There are <code class="literal">* break</code> and
+                <code class="literal">* continue</code>, which work as any shell
+                scripter would expect them to.
+                The <code class="literal">* break</code> command can also be used to
+                quit the current SQL file without triggering any error
+                processing.
+                (I.e. processing will continue with the next line in the
+                <span class="emphasis"><em>including</em></span> SQL file or interactive
+                session, or with the next SQL file if you supplied multiple on
+                the command-line).
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B0E"></a>Example</h3>
+</div>
+</div>
+</div>
+<p>
+                Below is the example SQL file
+                <code class="filename"><a class="filename" href="apa.html#pl.sql-link">sample/pl.sql</a></code>,
+                which shows how to use most PL
+                features <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+                If you have a question about how to use a particular
+                PL feature, check this file in your distrubition before asking
+                for help.
+                Definitely give it a run, like
+                <pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar mem $HSQLDB_HOME/pl.jar</pre>
+            
+</p>
+<div class="example">
+<a name="N10B1D"></a>
+<p class="title">
+<b>Example&nbsp;1.6.&nbsp;SQL File showing use of most PL features</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">/*
+    $Id: pl.sql 3353 2009-12-15 19:52:13Z unsaved $
+    SQL File to illustrate the use of SqlTool PL features.
+    Invoke like
+        java -jar .../hsqldb.jar .../pl.sql mem
+                                                         -- blaine
+*/
+
+* if (! *MYTABLE)
+    \p MYTABLE variable not set!
+    /* You could use \q to Quit SqlTool, but it's often better to just
+       break out of the current SQL file.
+       If people invoke your script from SqlTool interactively (with
+       \i yourscriptname.sql) any \q will kill their SqlTool session. */
+    \p Use arguments "--setvar=MYTABLE=mytablename" for SqlTool
+    * break
+* end if
+
+/* Turning on Continue-upon-errors so that we can check for errors ourselves.*/
+\c true
+
+\p
+\p Loading up a table named '*{MYTABLE}'...
+
+/* This sets the PL variable 'retval' to the return status of the following
+   SQL command */
+* retval ~
+CREATE TABLE *{MYTABLE} (
+    i int,
+    s varchar(20);
+);
+\p CREATE status is *{retval}
+\p
+
+/* Validate our return status.  In logical expressions, unset variables like
+   *unsetvar are equivalent to empty string, which is not equal to 0
+   (though both do evaluate to false on their own, i.e. (*retval) is false
+   and (0) is false */
+* if (*retval != 0)
+    \p Our CREATE TABLE command failed.
+    * break
+* end if
+
+/* Default Continue-on-error behavior is what you usually want */
+\c false
+\p
+
+/* Insert data with a foreach loop.
+   These values could be from a read of another table or from variables
+   set on the command line like
+*/
+\p Inserting some data int our new table (you should see 3 row update messages)
+* foreach VALUE (12 22 24 15)
+    * if (*VALUE &gt; 23)
+        \p Skipping *{VALUE} because it is greater than 23
+        * continue
+        \p YOU WILL NEVER SEE THIS LINE, because we just 'continued'.
+    * end if
+    INSERT INTO *{MYTABLE} VALUES (*{VALUE}, 'String of *{VALUE}');
+* end foreach
+\p
+
+* themax ~
+/* Can put Special Commands and comments between "* VARNAME ~" and the target 
+   SQL statement. */
+\p We're saving the max value for later.  You'll still see query output here:
+SELECT MAX(i) FROM *{MYTABLE};
+
+/* This is usually unnecessary because if the SELECT failed, retval would
+   be undefined and the following print statement would make SqlTool exit with
+   a failure status */
+* if (! *themax)
+    \p Failed to get the max value.
+    /* It's possible that the query succeeded but themax is "0".
+       You can check for that if you need to. */
+    * break
+    \p YOU WILL NEVER SEE THIS LINE, because we just 'broke'.
+* end if
+
+\p
+\p ##############################################################
+\p The results of our work:
+SELECT * FROM *{MYTABLE};
+\p MAX value is *{themax}
+
+\p
+\p Everything worked.
+</pre>
+</div>
+</div>
+<br class="example-break">
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_chunk-sect"></a>Chunking</h2>
+</div>
+</div>
+</div>
+<p>
+            We hereby call the ability to transmit multiple SQL commands to
+            the database in one transmission <span class="emphasis"><em>chunking</em></span>.
+            Normally it's best to send SQL statements to the database
+            one-at-a-time.
+            That way, the database can give you or your program feedback about
+            each statement.
+            But there are situations where it is more important to transmit
+            multiple-statements-at-a-time than to get feedback for each
+            statement individually.
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B2C"></a>Why?</h3>
+</div>
+</div>
+</div>
+<p>
+                The first general reason to chunk SQL commands is performance.
+                For standalone databases, the most common performance
+                bottleneck is network latency.
+                Chunking SQL commands can dramatically reduce network traffic.
+            </p>
+<p>
+              The second reason is that there are a couple SQL commands which
+              require the terminating ";" to be sent to the database engine.
+              For simplicity and efficiency, it's usually better for general
+              JDBC clients like SqlTool to strip off the final delimiter.
+              Raw commands retains everything that the user types.
+            </p>
+<p>
+                The third general reason to chunk SQL commands is if your
+                database requires you to send multiple commands in one
+                transmission.
+                This is usually the case with the following types of commands:
+                <div class="itemizedlist">
+<ul type="disc">
+<li>
+                        Nested SQL commands, like the nested CREATE SCHEMA
+                        variant, and most stored procedure, function, and
+                        trigger definitions.
+                    </li>
+<li>
+                        Commands containing non-quoted programming language to
+                        be interpreted by the database engine.
+                        Definitions of stored procedures, function, and triggers
+                        often contain code like this.
+                    </li>
+</ul>
+</div>
+            
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B3D"></a>How?</h3>
+</div>
+</div>
+</div>
+<p>
+                Use raw mode.
+                Go to the
+                <a class="link" href="sqltool-chapt.html#sqltool_raw-sect" title="Raw Mode">Raw Mode</a> section
+                to see how.
+                You can enter any text at all, exactly how you want it to
+                be sent to the database engine.
+                Therefore, in addition to chunking SQL commands, you can
+                give commands for non-SQL extensions to the database.
+                For example, you could enter JavaScript code to be used
+                in a stored procedure.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_raw-sect"></a>Raw Mode</h2>
+</div>
+</div>
+</div>
+<p>
+            You begin raw mode by issuing the Special Command "\.".
+            You can then enter as much text in any format you want.
+            When you are finished, enter a line consisting of only ".;"
+            to store the input to the edit buffer and send it to the
+            database server for execution.
+        </p>
+<p>
+            This paragraph applies only to interactive usage.
+            Interactive users may may end the raw input with ":."
+            instead of ".;".
+            This will just save the input to the edit buffer so that you can
+            edit it and send it to the database manually.
+            You can look at the edit buffer with the ":b" Buffer Command.
+            You would normally use the command ":;" to
+            send the buffer to the database after you are satisfied with it.
+            You'll notice that your prompt will be the "raw" prompt
+            between entering "\." and terminating the raw input with ".;"
+            or ":.".
+        </p>
+<p>
+            Just by running commands beginning with
+            <code class="literal">BEGIN</code>, <code class="literal">DECLARE</code>,
+            <code class="literal">CREATE function</code>,
+            or <code class="literal">CREATE procedure</code>, your SqlTool session will
+            automatically be changed to Raw mode, exactly as if you had entered
+            "\.".
+            That's because these commands are universally used to define
+            stored procedures or functions, and these commands require raw mode
+            (as explained in the previous section).
+        </p>
+<p>
+          
+<div class="example">
+<a name="N10B5F"></a>
+<p class="title">
+<b>Example&nbsp;1.7.&nbsp;Interactive Raw Mode example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    sql&gt; \.
+    Enter RAW SQL.  No \, :, * commands.
+    End with a line containing only ".;" to send to database,
+    or ":." to store to edit buffer for editing or saving.
+    -----------------------------------------------------------
+    raw&gt; line one;
+    raw&gt; line two;
+    raw&gt; line three;
+    raw&gt; :.
+    Raw SQL chunk moved into buffer.  Run ":;" to execute the chunk.
+    sql&gt; :;
+    Executing command from buffer:
+    line one;
+    line two;
+    line three;
+
+    SQL Error at 'stdin' line 13:
+    "line one;
+    line two;
+    line three;"
+    Unexpected token: LINE in statement [line]
+    sql&gt;</pre>
+</div>
+</div>
+<br class="example-break">
+            The error message "Unexpected token: LINE in statement [line]"
+            comes from the database engine, not SqlTool.
+            All three lines were transmitted to the database engine.
+        </p>
+<p>
+            Edit Buffer Commands are not available when running SqlTool
+            non-interactively.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_embedded-langs-sect"></a>SQL/PSM, SQL/JRT, and PL/SQL</h2>
+</div>
+</div>
+</div>
+<p>
+          This section covers database-engine-embedded languages, which are
+          often used in the definition of stored procedures, stored functions,
+          and triggers.
+          <code class="literal">SQL/PSM</code>, <code class="literal">SQL/JRT</code>,
+          and <code class="literal">PL/SQ:</code> are well known examples.
+          We prefer <code class="literal">SQL/PSM</code> and <code class="literal">SQL/JRT</code>
+          because unlike the alternatives, they are based on open SQL
+          specifications.
+        </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            PL/SQL is <span class="bold"><strong>not</strong></span> the same as
+            PL.  PL is the procedural language of SqlFile and is
+            independent of your back-end database.
+            PL commands always begin with *.
+            PL/SQL is an Oracle-specific extension processed on the server side.
+            You can not intermix PL and any server-embedded language
+            (except for setting a PL variable to the output of execution),
+            because when you enter server language to SqlTool, that input is
+            not processed by SqlFile.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            Use <a class="link" href="sqltool-chapt.html#sqltool_raw-sect" title="Raw Mode">Raw Mode</a> to send
+            server-language code blocks to the database engine.
+            You do not need to enter the "\." command to enter raw mode.
+            Just begin a new SqlTool command line with "DECLARE",
+            "BEGIN", "CREATE FUNCTION", or "CREATE PROCEDURE",
+            and SqlTool will automatically put you into raw mode.
+            See the <a class="link" href="sqltool-chapt.html#sqltool_raw-sect" title="Raw Mode">Raw Mode</a>
+            section for details.
+        </p>
+<p>
+            The following sample SQL file resides at
+            <code class="filename"><a class="filename" href="apa.html#plsql.sql-link">sample/plsql.sql</a></code>
+            in your HyperSQL distribution
+            <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+            This script will only work with Oracle, only if you have
+            permission to create the table
+            "T1" in the default schema, and if that object does not
+            already exist.
+            <div class="example">
+<a name="N10B96"></a>
+<p class="title">
+<b>Example&nbsp;1.8.&nbsp;PL/SQL Example</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">/*
+ * $Id: plsql.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * This example is copied from the "Simple Programs in PL/SQL"
+ * example by Yu-May Chang, Jeff Ullman, Prof. Jennifer Widom at
+ * the Standord University Database Group's page
+ * http://www-db.stanford.edu/~ullman/fcdb/oracle/or-plsql.html .
+ * I have only removed some blank lines (in case somebody wants to
+ * copy this code interactively-- because you can't use blank
+ * lines inside of SQL commands in non-raw mode SqlTool when running
+ * it interactively); and, at the bottom I have  replaced the
+ * client-specific, non-standard command "run;" with SqlTool's
+ * corresponding command ".;" and added a plain SQL SELECT command
+ * to show whether the PL/SQL code worked.  - Blaine
+ */
+
+CREATE TABLE T1(
+    e INTEGER,
+    f INTEGER
+);
+
+DELETE FROM T1;
+
+INSERT INTO T1 VALUES(1, 3);
+
+INSERT INTO T1 VALUES(2, 4);
+
+/* Above is plain SQL; below is the PL/SQL program. */
+DECLARE
+
+    a NUMBER;
+
+    b NUMBER;
+
+BEGIN
+
+    SELECT e,f INTO a,b FROM T1 WHERE e&gt;1;
+
+    INSERT INTO T1 VALUES(b,a);
+
+END;
+
+.;
+/** The statement on the previous line, ".;" is SqlTool specific.
+ *  This command says to save the input up to this point to the
+ *  edit buffer and send it to the database server for execution.
+ *  I added the SELECT statement below to give imm
+ */
+
+/* This should show 3 rows, one containing values 4 and 2 (in this order)...*/
+SELECT * FROM t1;
+</pre>
+</div>
+</div>
+<br class="example-break">
+            Note that, inside of raw mode, you can use any kind of formatting
+            that your database engine needs or permits:  Whatever you enter--
+            blank lines, comments,
+            everything-- will be transmitted to the database engine.
+        </p>
+<p>
+          This file resides at
+          <code class="filename"><a class="filename" href="apa.html#sqljrt.sql-link">
+            testrun/sqltool/sqljrt.sql</a></code>
+          
+<div class="example">
+<a name="N10BA2"></a>
+<p class="title">
+<b>Example&nbsp;1.9.&nbsp;SQL/JRT Example</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">/*
+ * $Id: sqljrt.sql 3353 2009-12-15 19:52:13Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create function dehex(VARCHAR(80), INTEGER)
+    returns INTEGER
+    no sql
+    language java
+    external name 'CLASSPATH:java.lang.Integer.valueOf'
+.;
+
+CALL dehex('12', 16);
+*if (*? != 18)
+    \q SQL/JRT function failed
+*end if
+</pre>
+</div>
+</div>
+<br class="example-break">
+          This file resides at
+          <code class="filename"><a class="filename" href="apa.html#sqlpsm.sql-link">
+            testrun/sqltool/sqlpsm.sql</a></code>
+          
+<div class="example">
+<a name="N10BAC"></a>
+<p class="title">
+<b>Example&nbsp;1.10.&nbsp;SQL/PSM Example</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">/*
+ * $Id: sqlpsm.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create table customers(
+    id INTEGER default 0, firstname VARCHAR(50), lastname VARCHAR(50),
+    entrytime TIMESTAMP);
+
+create procedure new_customer(firstname varchar(50), lastname varchar(50))
+    modifies sql data
+    insert into customers values (
+        default, firstname, lastname, current_timestamp)
+.;
+
+SELECT count(*) FROM customers;
+*if (*? != 0)
+    \q SQL/PSM preparation failed
+*end if
+
+CALL new_customer('blaine', 'simpson');
+
+SELECT count(*) FROM customers;
+*if (*? != 1)
+    \q SQL/PSM procedure failed
+*end if
+</pre>
+</div>
+</div>
+<br class="example-break">
+        
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_dsv-sect"></a>Delimiter-Separated-Value Imports and Exports</h2>
+</div>
+</div>
+</div>
+<p>
+          SqlTool's DSV functionality encompasses what many users will
+          recognize as CSV export, as well as portable backup or transfer of
+          data.
+          Those familiar with Oracle's SQL*Loader will recognize the extreme
+          usefulness of the feature set.
+          Besides database- and platform-independent data backups, exports can
+          be used to deploy data sets with applications, to transfer data
+          among multiple database instances (even drastically different
+          database instances such as SQL Server and HyperSQL), and to properly
+          change control data sets with a content management system such as a
+          collaboration server or Subversion.
+          To jump way ahead for a moment to whet your appetite, here is a
+          sample <span class="emphasis"><em>import reject report</em></span> which will can be
+          generated automatically for you upon import just by setting the PL
+          variable <code class="varname">*DSV_REJECT_REPORT</code> (to the desired
+          destination HTML file name).
+          <div class="mediaobject" align="center">
+<img src="rejreport-sample.png" align="middle"><div class="caption">
+<p>A DSV Import reject report</p>
+</div>
+</div>
+          If you wish to, you can review the reject report before deciding
+          whether to commit or roll back the inserts.
+        </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            This feature is independent of HyperSQL Text Tables.
+            (See the Text Tables chapter of the
+              <a class="link" href="http://hsqldb.org/doc/2.0/guide/index.html" target="_top">
+                HyperSQL User Guide</a> for details about them).
+            a server-side feature of HyperSQL.
+            It makes no difference to SqlTool whether the source or target
+            table of your export/import is a memory, cache, or text table.
+            Indeed, like all features of SqlTool, it works fine with other
+            JDBC databases.
+            It works great, for example to migrate data from a table
+            of one type to a table of another type, or to another schema,
+            or to another database instance, or to another database system.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            This feature is what most business people call "CSV", but
+            these files are more accurately called <span class="emphasis"><em>Delimiter
+            Separated Value files</em></span> because the delimiter is
+            usually not a comma, and, more importantly, we purposefully
+            choose an effective delimiter instead of the CSV method of
+            using a delimiter which works in some cases and then use
+            quotes and back-slashes to escape occurrence of the delimiter
+            in the actual data.
+            Just by choosing a delimiter which never needs escaping, we
+            eliminate the whole mess, and the data in our files always
+            looks just like the corresponding data in the database.
+            To make this CSV / Delimiter-separated-value dintinction clear,
+            I use the suffix ".dsv" for my data files.
+            This leads me to stipulate the abbreviation DSV for the
+            <span class="emphasis"><em>Delimiter Separated Value</em></span> feature of HyperSQL.
+        </p>
+<p>
+            Use the <code class="literal">\x</code> command to eXport a table to a
+            DSV file, and the <code class="literal">\m</code> command to iMport a
+            DSV file into a pre-existing table.
+        </p>
+<p>
+            The row and column delimiters may be any String (or even a
+            regular expression for import), not just a single character.
+            And just as the delimiter capability is more general than
+            traditional CSV delimiters, the export function is also more
+            general than just a table data exporter.
+            Besides the trivial generalization that you may specify a
+            view or other virtual table name in place of a table name,
+            you can alternatively export the output of any query which
+            produces normal text output.
+            A benefit to this approach is that it allows you to export only
+            some columns of a table, and to specify a WHERE clause to narrow
+            down the rows to be exported (or perform any other SQL
+            transformation, mapping, join, etc.).
+            One specific use for this would be to exclude columns of
+            binary data (which can be exported by other means, such as
+            a PL loop to store binary values to files with the \bd command).
+        </p>
+<p>
+            Note that the import command will not create a new table.
+            This is because of the impossibility of guessing appropriate
+            types and constraints based only on column names and a data
+            sampling (which is all that a DSV-importer has access to).
+            Therefore, if you wish to populate a new table, create the
+            table before running the import.
+            The import file does not need to have data for all columns of a
+            table.
+            The only required columns are those required by database
+            constraints (non-null, indexes, keys, etc.)
+            One specific reason to omit columns is if you want values of
+            some columns to be created automatically by column DEFAULT
+            settings, triggers, HyperSQL identity sequences, etc.
+            Another reason would be to skip binary columns.
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10BE4"></a>Simple DSV exports and imports using default settings</h3>
+</div>
+</div>
+</div>
+<p>
+                Even if you need to change delimiters, table names, or file
+                names from the defaults, I suggest that you run one export
+                and import with default settings as a practice run.
+                A memory-only HyperSQL instance is ideal for test runs like this.
+            </p>
+<p>
+                This command exports the table <code class="literal">icf.projects</code>
+                to the file <code class="filename">projects.dsv</code> in the current
+                directory (where you invoked SqlTool from).
+                By default, the output file name will be the specified source
+                table name plus the extension <code class="literal">.dsv</code>.
+                <div class="example">
+<a name="N10BF4"></a>
+<p class="title">
+<b>Example&nbsp;1.11.&nbsp;DSV Export Example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    SET SCHEMA icf;
+    \x projects</pre>
+</div>
+</div>
+<br class="example-break">
+                We could also have run <code class="literal">\x icf.projects</code>
+                (which would have created a file named
+                <code class="filename">icf.projects.dsv</code>)
+                instead of changing the session schema.
+                In this example we have chosen to make the export file name
+                independent of the schema to facilitate importing it into
+                a different schema.
+            </p>
+<p>
+                Take a look at the output file.
+                Notice that the first line consists of column names, not
+                data.
+                This line is present because it will be needed if the file is
+                to used for a DSV import.
+                Notice the following characterstics about the export data.
+                The column delimiter is the pipe character "|".
+                The record delimiter is the default line delimiter character(s)
+                for your operating system.
+                The string used to represent database <code class="literal">NULL</code>s
+                is <code class="literal">[null]</code>.
+                See the next section for how to change these from their default
+                values.
+            </p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                You can not DSV import Array values where any Array elements
+                contain commas, for example an Array of VARCHARs which contain
+                one or more commas.
+                There is no such limitation on DSV exports, which you can use
+                for purposes other than SqlTool importing, or you could use
+                a script to change the commas to some other character.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+                This command imports the data from the file
+                <code class="filename">projects.dsv</code> in the current
+                directory (where you invoked SqlTool from) into the table
+                <code class="literal">newschema.projects</code>.
+                By default, the output table name will be the input filename
+                after removing optional leading directory and trailing final
+                extension.
+                <div class="example">
+<a name="N10C13"></a>
+<p class="title">
+<b>Example&nbsp;1.12.&nbsp;DSV Import Example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    SET SCHEMA newschema;
+    \m projects.dsv</pre>
+</div>
+</div>
+<br class="example-break">
+                If the DSV file was named with the target schema, you would
+                have skipped the <code class="literal">SET SCHEMA</code> command, like
+                <code class="literal">\m newschema.projects.dsv</code>.
+                In order to allow for more flexibility, the default input
+                input delimiters are not exactly the same as the output
+                delimiters.
+                The input delimiters are regular expressions.
+                The input column delimiter happens to be the regular expression
+                corresponding exatly to "|"; but the input record delimiter
+                matches UNIX, Windows, Mac, and HTTP line breaks.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C1F"></a>Specifying queries and options</h3>
+</div>
+</div>
+</div>
+<p>
+                For a hands on example of a DSM import which generates
+                an import report and uses some other options, change to
+                directory <code class="filename">HSQLDB/sample</code> and play
+                with the working script
+                <code class="filename"><a class="filename" href="apa.html#dsv-sample.sql-link">
+                  dsv-sample.sql</a></code>
+                <sup>[<a href="sqltool-chapt.html#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+                You can execute it like
+                <div class="informalexample">
+<pre class="screen">    java -jar ../lib/sqltool.jar mem dsv-sample.sql</pre>
+</div>
+                (assuming that you are using the supplied
+                <code class="filename">sqltool.rc</code> file or have have urlid
+                <code class="literal">mem</code> set up).
+            </p>
+<p>
+                The header line in the DSV file is required at this time.
+                (If there is user demand, it can be made optional for
+                exporting, but it will remain required for importing).
+            </p>
+<p>
+                Your export will fail if the output column or record delimiter,
+                or the null representation value occurs in the data being
+                exported.
+                You change these values by setting the PL variables
+                <code class="varname">*DSV_COL_DELIM</code>,
+                <code class="varname">*DSV_ROW_DELIM</code>,
+                <code class="varname">*DSV_NULL_REP</code>.
+                Notice that the asterisk is part of the variable names, to
+                indicate that these variables are used by SqlTool internally.
+                When specifying delimiters, you can use the escape seqpences
+                \n, \r, \f, \t, \\, and decimal, octal or hex specifications
+                like \20, \020, \0x20.
+                For example, to change the column delimiter to the tab character,
+                you would give the command
+                <div class="informalexample">
+<pre class="screen">    * *DSV_COL_DELIM = \t</pre>
+</div>
+            
+</p>
+<p>
+                The input (\m) delimiter values,
+                <code class="varname">*DSV_COL_SPLITTER</code> and
+                <code class="varname">*DSV_ROW_SPLITTER</code>, are set using normal
+                Perl/Java regexp syntax.
+                There are escapes for specifying special characters, and
+                anything else you would need.
+                Input vs. output row and column delimiters are easily
+                distinguished by containing "SPLITTER" for splitting input
+                (\m) files; or "DELIM" for the delimiters that we will write
+                (\x) among the data.
+            </p>
+<p>
+                For imports, you must always specify the source DSV file path.
+                If you want to <span class="emphasis"><em>export</em></span> to a different file
+                than one in the current directory named according to the source
+                table, set the PL variable <code class="varname">*DSV_TARGET_FILE</code>,
+                like
+                <div class="informalexample">
+<pre class="screen">    * *DSV_TARGET_FILE = /tmp/dtbl.dsv</pre>
+</div>
+            
+</p>
+<p>
+                For exports, you must always specify the source table name
+                or query.
+                If you want to <span class="emphasis"><em>import</em></span> to a table other
+                than that derived from
+                the input DSV file name, set the PL variable
+                <code class="varname">*DSV_TARGET_TABLE</code>.
+                The table name may contain a schema name prefix.
+            </p>
+<p>
+                You don't need to import all of the columns in a data file.
+                To designate the fields to be skipped, iether set the PL
+                PL variable <code class="varname">*DSV_SKIP_COLUMNS</code>, or replace
+                the column names in the header line to "-" (hyphen).
+                The value of <code class="varname">*DSV_SKIP_COLUMNS</code> is
+                case-insensitive, and multiple column names are separated with
+                white space and/or commas.
+            </p>
+<p>
+                You can specify a query instead of a tablename with the
+                \x command in order to filter or transform data from a table
+                or view, or to export the output of a join, etc.
+                You must set the PL variable <code class="varname">*DSV_TARGET_FILE</code>,
+                as explained above (since there is no table name from which to
+                automatically map a file name).
+                <div class="example">
+<a name="N10C72"></a>
+<p class="title">
+<b>Example&nbsp;1.13.&nbsp;DSV Export of an Arbitrary SELECT Statement</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    * *DSV_TARGET_FILE = outfile.txt
+    \x SELECT entrydate, 2 * aval "Double aval", modtime FROM bs.dtbl</pre>
+</div>
+</div>
+<br class="example-break">
+                Note that I specified the column label alias "Double aval"
+                so that the label for that column in the DSV file header will
+                not be blank.
+            </p>
+<p>
+                By default, imports will abort as soon as a error is
+                encountered during parsing the file or inserting data.
+                If you invoke SqlTool with a SQL script on the command line,
+                the failure will cause SqlTool to roll back and exit.
+                If run interactively, you can decide whether to commit or
+                roll back the rows that inserted before the failure.
+                You can modify this behavior with the \a and \c settings.
+            </p>
+<p>
+                If you set either a reject dsv file or a reject report file,
+                then failures during imports will be reported but will not
+                cause the import to abort.
+                When run in this way, SqlTool will give you a report at
+                the end about how many records were skipped, rejected, and
+                successfully inserted.
+                The reject dsv file is just a dsv file with exact copies of
+                the dsv records that failed to insert.
+                The reject report file is a HTML report which lists, for
+                every rejected record, why that record was rejected.
+                <code class="literal">\m?</code> will show you that the required PL
+                variables for this functionality are
+                <code class="varname">*DSV_REJECT_FILE</code>
+                and <code class="varname">*DSV_REJECT_REPORT</code>.
+                In both cases, you set the variable value to the path of the
+                file which SqlTool will create.
+            </p>
+<p>
+                To allow for user-friendly entry of headers, we require
+                that tables for DSV import/exports use standard column names.
+                I.e., no column names that require quoting.
+                The DSV import and export parsers are very smart and
+                user-friendly.
+                The data types of columns are checked so that the parser can
+                make safe assumptions about white space and blank entries in
+                the data.
+                If a column is a JDBC Boolean type, for example, then we
+                know that a field value of "  True " obviously means "True",
+                and that a field value of "" obviously means null.
+                Since we require vanilla style column names, we allow
+                white space anywhere in the header column.
+                We allow blank lines anywhere (where "lines" are delimited
+                by *DSV_ROW_DELIM).
+                By default, commented lines are ignored, and the comment
+                character can be changed from its default value.
+            </p>
+<p>
+                Run the command "\x?" or "\m?" to see the several system PL
+                variables which you can set to adjust reject file behavior,
+                commenting behavior, and other DSV features.
+            </p>
+<p>
+                You can also define some settings right in the DSV file,
+                and you can even specify multiple header lines in a single
+                DSV file.
+                I use this last feature to import data from one data set
+                into multple tables that are joined.
+                Since I don't have any more time to dedicate to explaining
+                all of these features, I'll give you some examples from
+                working DSV files and let you take it from there.
+        <div class="example">
+<a name="N10C8B"></a>
+<p class="title">
+<b>Example&nbsp;1.14.&nbsp;Sample DSV headerswitch settings</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">    # RCS keyword was here.
+
+    headerswitch{
+    itemdef:name|-|-|hardness|breakdc|-
+    simpleitemdef:itemdef_name|maxvalue|weight|-|-|maxhp
+    }</pre>
+</div>
+</div>
+<br class="example-break">
+            I'll just note that the prefixes for the header rows must be of
+            format target-table-name + :.
+            You can use * for target-table-name here, for the obvious purpose.
+        <div class="example">
+<a name="N10C91"></a>
+<p class="title">
+<b>Example&nbsp;1.15.&nbsp;DSV targettable setting</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">    targettable=t</pre>
+</div>
+</div>
+<br class="example-break">
+                This last example is from the SqlTool unit test file
+                <code class="filename">dsv-trimming.dsv</code>.
+                These special commands must be at the top of the file
+                (before any normal data or header lines).
+            </p>
+<p>
+                There is also the <code class="varname">*DSV_CONST_COLS</code> setting,
+                which you can use to automatically write static, constant
+                values to the specified columns of all inserted rows.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_unittest-sect"></a>Unit Testing SqlTool</h2>
+</div>
+</div>
+</div>
+<p>
+          The SqlTool unit tests reside at testrun/sqltool in the
+          HyperSQL source code repository.
+          Just run the <code class="filename">runtests.bash</code> script from
+          that directory to execute all of the tests.
+          As you can see, the test runner, unfortunately, requires a Bash
+          shell at this time.
+          Read the file <code class="filename">README.txt</code> to find out all
+          about it, including everything you'd need to know to test your
+          own scripts or to add more unit test scripts for SqlTool.
+        </p>
+</div>
+<div class="footnotes">
+<br>
+<hr align="left" width="100">
+<div class="footnote">
+<p>
+<sup>[<a href="#samplelocFn" name="ftn.samplelocFn" class="simpara">1</a>] </sup>
+            To reduce the time I will need to spend maintaining this document,
+            in this chapter I am giving the path to the
+            <code class="filename">sample</code> directory as it is in HyperSQL 2.0.x
+            distributions, namely, <code class="filename">HSQLDB_HOME/sample</code>.
+            Users of HSQLDB before 2.0.x should translate these sample
+            directory paths
+            to use <code class="filename">HSQLDB_HOME/src/org/hsqldb/sample/...</code>.
+            </p>
+</div>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3539 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="book-pref.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="test-utility-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Preface&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;2.&nbsp;Hsqldb Test Utility</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/util-guide/test-utility-chapt.html b/doc/util-guide/test-utility-chapt.html
new file mode 100644
index 0000000..cacce68
--- /dev/null
+++ b/doc/util-guide/test-utility-chapt.html
@@ -0,0 +1,203 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;2.&nbsp;Hsqldb Test Utility</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, Test, Utility">
+<meta name="keywords" content="HyperSQL, Hsqldb, Hypersonic, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="up" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="prev" href="sqltool-chapt.html" title="Chapter&nbsp;1.&nbsp;SqlTool">
+<link rel="next" href="dbm-chapt.html" title="Chapter&nbsp;3.&nbsp;Database Manager">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="sqltool-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;2.&nbsp;Hsqldb Test Utility</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="dbm-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;1.&nbsp;SqlTool&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Chapter&nbsp;3.&nbsp;Database Manager</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="test-utility-chapt"></a>Chapter&nbsp;2.&nbsp;Hsqldb Test Utility</h2>
+</div>
+</div>
+</div>
+<p>The <code class="classname">org.hsqldb.test</code> package contains a number
+    of tests for various functions of the database engine. Among these, the
+    <code class="classname">TestUtil</code> class performs the tests that are based on
+    scripts. To run the tests, you should compile the
+    <code class="filename">hsqldbtest.jar</code> target with Ant and JUnit.</p>
+<p>The <code class="classname">TestUtil</code> class should be run in the
+    /testrun/hsqldb directory of the distributed files. It then runs the set
+    of TestSelf*.txt files in the directory. To start the application in
+    Windows, change to the directory and type:</p>
+<pre class="screen"> java org.hsqldb.test.TestUtil</pre>
+<p>All files in the working directory with names matching TestSelf*.txt
+    are processed in alphabetical order.</p>
+<p>You can add your own scripts to test different series of SQL
+    queries. The format of the TestSelf*.txt file is simple text, with some
+    indentation and prefixes in the form of Java-style comments. The prefixes
+    indicate what the expected result should be.</p>
+<p>The class <code class="classname">org.hsqldb.test.TestScriptRunner</code> is
+    a more general program which you can use to test any script files which
+    you specify (with scripts of the same exact format as described below).
+    For example, <pre class="screen">java org.hsqldb.test.TestScriptRunner --urlid=mem script1.tsql script2.sql</pre>
+    You must have the HSQLDB classes, including the util and test classes, in
+    your <code class="varname">CLASSPATH</code>. The urlid must be set up in an RC file
+    as explained in the <a class="link" href="sqltool-chapt.html#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section. Use the
+    <code class="literal">rcfile=</code> argument to specify an RC file other than the
+    default of <code class="filename">testscriptrunner.rc</code> in the current
+    directory. To see all invocation possibilities, just run TestScriptRunner
+    with no arguments at all. TestScriptRunner can run tests sequentially (the
+    default) or in simultaneous asynchronous threads.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Comment lines must start with -- and are ignored</p>
+</li>
+<li>
+<p>Lines starting with spaces are the continuation of the previous
+        line (for long SQL statements)</p>
+</li>
+<li>
+<p>SQL statements with no prefix are simply executed.</p>
+</li>
+<li>
+<p>
+<span class="emphasis"><em>The remaining items in this list exemplify use of the
+        available command line-prefixes.</em></span>
+</p>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*s*/ option stands for silent. It is used for
+          executing quries regardless of results. Used for preparation of
+          tests, not for actual tests.</p>
+<pre class="programlisting">/*s*/ Any SQL statement - errors are ignored</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*c&lt;rows&gt;*/ option is for SELECT queries and
+          asserts the number of rows in the result matches the given
+          count.</p>
+<pre class="programlisting">/*c&lt;rows&gt;*/ SQL statement returning count of &lt;rows&gt;</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*u*/ option is for queries that return an update
+          count, such as DELETE and UPDATE. It asserts the update count
+          matches.</p>
+<pre class="programlisting">/*u&lt;count&gt;*/ SQL statement returning an update count equal to &lt;count&gt;</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*e*/ option asserts that the given query results in an
+          erros. It is mainly used for testing the error detection
+          capabilities of the engine. The SQL State of the expected error can
+          be defined, for example /*e42578*/, to verify the returned error.
+          This option can be used with syntactically valid queries to assert a
+          certain state in the database. For example a CREATE TABLE can be
+          used to assert the table of the same name already exists.</p>
+<pre class="programlisting">/*e*/ SQL statement that should produce an error when executing</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*r....*/ option asserts the SELECT query returns a
+          single row containing the given set of field values.</p>
+<pre class="programlisting">/*r&lt;string1&gt;,&lt;string2&gt;*/ SQL statement returning a single row ResultSet equal to the specified value</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The extended /*r...*/ option asserts the SELECT query
+          returns the given rows containing the given set of field
+          values.</p>
+<pre class="programlisting">/*r
+    &lt;string1&gt;,&lt;string2&gt;
+    &lt;string1&gt;,&lt;string2&gt;
+    &lt;string1&gt;,&lt;string2&gt;
+*/ SQL statement returning a multiple row ResultSet equal to the specified values</pre>
+</div>
+<p>(note that the result set lines are indented).</p>
+</li>
+<li>
+<p>The /*d*/ directive just displays the supplied
+        text.</p>
+<div class="informalexample">
+<pre class="programlisting">/*d*/ Some message</pre>
+</div>
+</li>
+<li>
+<p>The /*w MILLIS*/ directive causes the test to Wait for a
+        specified number of millisedonds.</p>
+<div class="informalexample">
+<pre class="programlisting">/*w 1000*/ Optional message</pre>
+</div>
+</li>
+<li>
+<p>The /*w ENFORCE_SEQUENCE WAITER_NAME*/ directive causes the
+        test to Wait for the specified <span class="emphasis"><em>Waiter</em></span>. A waiter
+        is just name that is used to associate a /*w*/ directive to its
+        corresponding /*p*/ directive. The ENFORCE_SEQUENCE argument must be
+        set to <code class="literal">true</code> or <code class="literal">false</code> to specify
+        whether to fail unless the /*p*/ command runs after the /*w*/ command
+        is waiting.</p>
+<div class="informalexample">
+<pre class="programlisting">/*w true script4*/ Optional message</pre>
+</div>
+</li>
+<li>
+<p>The /*p ENFORCE_SEQUENC WAITER_NAME*/ directive is the peer
+        directive to /*w*/, which causes a waiting thread to
+        Proceed.</p>
+<div class="informalexample">
+<pre class="programlisting">/*p true script4*/ Optional message</pre>
+</div>
+</li>
+<li>
+<p>All the options are lowercase letters. During development, an
+        uppercase can be used for a given test to exclude a test from the test
+        run. The utility will just report the test blocks that have been
+        excluded without running them. Once the code has been developed, the
+        option can be turned into lowercase to perform the actual test.</p>
+</li>
+</ul>
+</div>
+<p>See the TestSelf*.txt files in the /testrun/hsqldb/ directory for
+    actual examples.</p>
+<p>The String <code class="literal">${timestamp}</code> may be used in script
+    messages (like in /*d*/, /*w*/, /*p*/). It expands to the current time,
+    down to the second. For example, <div class="informalexample">
+<pre class="programlisting">/*d*/ It is now ${timestamp}</pre>
+</div>
+</p>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3539 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="sqltool-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="dbm-chapt.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;1.&nbsp;SqlTool&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Chapter&nbsp;3.&nbsp;Database Manager</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/util-guide/transfer-tool-chapt.html b/doc/util-guide/transfer-tool-chapt.html
new file mode 100644
index 0000000..ee78cf4
--- /dev/null
+++ b/doc/util-guide/transfer-tool-chapt.html
@@ -0,0 +1,123 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Chapter&nbsp;4.&nbsp;Transfer Tool</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="Hsqldb, Transfer">
+<meta name="keywords" content="HyperSQL, Hsqldb, Hypersonic, Database, JDBC, Java">
+<link rel="home" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="up" href="index.html" title="HyperSQL Utilities Guide">
+<link rel="prev" href="dbm-chapt.html" title="Chapter&nbsp;3.&nbsp;Database Manager">
+<link rel="next" href="apa.html" title="Appendix&nbsp;A.&nbsp;HyperSQL File Links">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table summary="Navigation header" width="100%">
+<tr>
+<td align="left" width="30%"><a accesskey="p" href="dbm-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="40%" style="font-weight:bold;">Chapter&nbsp;4.&nbsp;Transfer Tool</td><td align="right" width="30%">&nbsp;<a accesskey="n" href="apa.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="30%">Chapter&nbsp;3.&nbsp;Database Manager&nbsp;</td><td align="center" width="40%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="30%">&nbsp;Appendix&nbsp;A.&nbsp;HyperSQL File Links</td>
+</tr>
+</table>
+</div>
+<HR>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="transfer-tool-chapt"></a>Chapter&nbsp;4.&nbsp;Transfer Tool</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="transfer-tool-chapt.html#trantool_intro-sect">Brief Introduction</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="trantool_intro-sect"></a>Brief Introduction</h2>
+</div>
+</div>
+</div>
+<p>Transfer Tool is a GUI program for transferring SQL schema and
+      data from one JDBC source to another. Source and destination can be
+      different database engines or different databases on the same
+      server.</p>
+<p>Transfer Tool works in two different modes. Direct transfer
+      maintains a connection to both source and destination and performs the
+      transfer. Dump and Restore mode is invoked once to transfer the data
+      from the source to a text file (Dump), then again to transfer the data
+      from the text file to the destination (Restore). With Dump and Restore,
+      it is possible to make any changes to database object definitions and
+      data prior to restoring it to the target.</p>
+<p>Dump and Restore modes can be set via the command line with -d
+      (--dump) or -r (--restore) options. Alternatively the Transfer Tool can
+      be started with any of the three modes from the Database Manager's Tools
+      menu.</p>
+<p>The connection dialogue allows you to save the settings for the
+      connection you are about to make. You can then access the connection in
+      future sessions. These settings are shared with those from the Database
+      Manager tool. See the appendix on Database Manager for details of the
+      connection dialogue box.</p>
+<p>From version 1.8.0 Transfer Tool is no longer part of the
+      <code class="filename">hsqldb.jar</code>. You can build the
+      <code class="filename">hsqldbutil.jar</code> using the Ant command of the same
+      name, to build a jar that includes Transfer Tool and the Database
+      Manager.</p>
+<p>When collecting meta-data, Transfer Tool performs SELECT * FROM
+      &lt;table&gt; queries on all the tables in the source database. This may
+      take a long time with some database engines. When the source database is
+      HSQLDB, this means memory should be available for the result sets
+      returned from the queries. Therefore, the memory allocation of the java
+      process in which Transfer Tool is executed may have to be high.</p>
+<p>The current version of Transfer is far from ideal, as it has not
+      been actively developed for several years. The program also lacks the
+      ability to create UNIQUE constraints and creates UNIQUE indexes instead.
+      However, some bugs have been fixed in the latest version and the program
+      can be used with most of the supported databases. The best way to use
+      the program is the DUMP and RESTORE modes, which allow you to manually
+      change the SQL statements in the dump file before restoring to a
+      database. A useful idea is to dump and restore the database definition
+      separately from the database data.</p>
+</div>
+</div>
+<HR xmlns:xi="http://www.w3.org/2001/XInclude">
+<P xmlns:xi="http://www.w3.org/2001/XInclude" class="svnrev">$Revision: 3539 $</P>
+<div class="navfooter">
+<hr>
+<table summary="Navigation footer" width="100%">
+<tr>
+<td align="left" width="40%"><a accesskey="p" href="dbm-chapt.html"><img src="../images/db/prev.png" alt="Prev"></a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="apa.html"><img src="../images/db/next.png" alt="Next"></a></td>
+</tr>
+<tr>
+<td valign="top" align="left" width="40%">Chapter&nbsp;3.&nbsp;Database Manager&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html"><img src="../images/db/home.png" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;Appendix&nbsp;A.&nbsp;HyperSQL File Links</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/util-guide/util-guide.html b/doc/util-guide/util-guide.html
new file mode 100644
index 0000000..4cb3b95
--- /dev/null
+++ b/doc/util-guide/util-guide.html
@@ -0,0 +1,6971 @@
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>HyperSQL Utilities Guide</title>
+<link href="../docbook.css" rel="stylesheet" type="text/css">
+<meta content="DocBook XSL-NS Stylesheets V1.74.0" name="generator">
+<meta name="keywords" content="HyperSQL, Hsqldb, Hypersonic, Database, JDBC, Java">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="book" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="N10002"></a>HyperSQL Utilities Guide</h1>
+</div>
+<table xmlns:xi="http://www.w3.org/2001/XInclude" class="titlead" cellspacing="0">
+<tr>
+<td>
+<div>
+<div class="authorgroup">
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="orgname">The HSQLB Development Group</span>
+</h3>
+</div>
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+<div class="editor">
+<h4 class="editedby">Edited by</h4>
+<h3 class="editor">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3539 $</p>
+</div>
+<div>
+<div class="legalnotice">
+<a name="N10037"></a>
+<p>Copyright 2002-2009 The HSQL Development Group. Permission is
+      granted to distribute this document without any alteration under the
+      terms of the HSQLDB license.</p>
+</div>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-03-17 11:47:21 -0400 (Wed, 17 Mar 2010) $</p>
+</div>
+</td><td class="sponsorad">
+<div xml:base="../doc-src/branding-frag.xhtml" class="branding">
+<img src="../images/hypersql_logo.png"></div>
+</td>
+</tr>
+</table>
+</div>
+<hr>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="preface"><a href="#book-pref">Preface</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#altformats-sect">Available formats for this document</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#sqltool-chapt">1. SqlTool</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#sqltool_book_purpose-sect">Purpose, Coverage, Changes in Behavior</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N100FB">Platforms and SqlTool versions covered</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1011D">Recent Functional Changes</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10188">New Features</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_baremin-sect">The Bare Minimum</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N102AE">Embedding</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N102C3">Non-displayable Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N102E3">Desktop shortcuts</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10344">Loading sample data</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N10360">Satisfying SqlTool's CLASSPATH Requirements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#sqltool_olderaccess-sect">
+          Accessing older HSQLDB Databases with SqlTool</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N103BC">App-specific Classes, Embedding, and non-HyperSQL Databases</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10403">Distributing SqlTool with your Apps</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10429">SqlTool Client PCs</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_auth-sect">RC File Authentication Setup</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_dsswitch-sect">Switching Data Sources</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_ilauth-sect">Using Inline RC Authentication</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_logging-sect">Logging</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_int-sect">Interactive Usage</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10578">SqlTool Command-Line Editing</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1059C">Command Types</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N105B5">Command Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N105FB">Special Commands</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N106CC">Edit Buffer / History Commands</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_interactive_pl_commands-sect">PL Commands</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N107C2">? Variable</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_binary_files-sect">
+                Storing and retrieving binary files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1080C">Command History</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10816">Shell scripting and command-line piping</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1081F">Emulating Non-Interactive mode</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_nonint-sect">Non-Interactive</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#sqltool_sqlswitch-sect">Giving SQL on the Command Line</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10871">SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_scripting-sect">Piping and shell scripting</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N108E1">Optimally Compatible SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N108F4">Comments</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10901">Special Commands and Edit Buffer Commands in SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10965">Automation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10970">Getting Interactive Functionality with SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_charencoding-sect">
+                Character Encoding</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_report-sect">Generating Text or HTML Reports</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_pl-sect">SqlTool Procedural Language</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10A08">Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_macro-sect">Macros</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10A67">PL Sample</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10A78">Logical Expressions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10AEB">Flow Control</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B0E">Example</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_chunk-sect">Chunking</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10B2C">Why?</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B3D">How?</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_raw-sect">Raw Mode</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_embedded-langs-sect">SQL/PSM, SQL/JRT, and PL/SQL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_dsv-sect">Delimiter-Separated-Value Imports and Exports</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10BE4">Simple DSV exports and imports using default settings</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C1F">Specifying queries and options</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_unittest-sect">Unit Testing SqlTool</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#test-utility-chapt">2. Hsqldb Test Utility</a></span>
+</dt>
+<dt>
+<span class="chapter"><a href="#dbm-chapt">3. Database Manager</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#dbm_intro-sect">Brief Introduction</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm_tree-sect">Auto tree-update</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm-autoconn-sect">Automatic Connection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm_rcfile-sect">RC File</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm_wold-sect">Using the current DatabaseManagers with an older HSQLDB
+      distribution.</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm_applet-sect">DatabaseManagerSwing as an Applet</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="chapter"><a href="#transfer-tool-chapt">4. Transfer Tool</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#trantool_intro-sect">Brief Introduction</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="appendix"><a href="#N10E8E">A. HyperSQL File Links</a></span>
+</dt>
+</dl>
+</div>
+<div class="list-of-tables">
+<p>
+<b>List of Tables</b>
+</p>
+<dl>
+<dt>1. <a href="#altformats-tbl">Available formats of this document</a>
+</dt>
+</dl>
+</div>
+<div class="list-of-examples">
+<p>
+<b>List of Examples</b>
+</p>
+<dl>
+<dt>1.1. <a href="#N10459">Sample RC File</a>
+</dt>
+<dt>1.2. <a href="#N107FC">Inserting binary data into database from a file</a>
+</dt>
+<dt>1.3. <a href="#N10801">Downloading binary data from database to a file</a>
+</dt>
+<dt>1.4. <a href="#N108CC">Piping input into SqlTool</a>
+</dt>
+<dt>1.5. <a href="#N10A6C">Simple SQL file using PL</a>
+</dt>
+<dt>1.6. <a href="#N10B1D">SQL File showing use of most PL features</a>
+</dt>
+<dt>1.7. <a href="#N10B5F">Interactive Raw Mode example</a>
+</dt>
+<dt>1.8. <a href="#N10B96">PL/SQL Example</a>
+</dt>
+<dt>1.9. <a href="#N10BA2">SQL/JRT Example</a>
+</dt>
+<dt>1.10. <a href="#N10BAC">SQL/PSM Example</a>
+</dt>
+<dt>1.11. <a href="#N10BF4">DSV Export Example</a>
+</dt>
+<dt>1.12. <a href="#N10C13">DSV Import Example</a>
+</dt>
+<dt>1.13. <a href="#N10C72">DSV Export of an Arbitrary SELECT Statement</a>
+</dt>
+<dt>1.14. <a href="#N10C8B">Sample DSV headerswitch settings</a>
+</dt>
+<dt>1.15. <a href="#N10C91">DSV targettable setting</a>
+</dt>
+</dl>
+</div>
+<div class="preface" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="book-pref"></a>Preface</h2>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#altformats-sect">Available formats for this document</a></span>
+</dt>
+</dl>
+</div>
+<p>If you notice any mistakes in this document, please email the author
+    listed at the beginning of the chapter. If you have problems with the
+    procedures themselves, please use the HSQLDB support facilities which are
+    listed at <a class="link" href="http://hsqldb.org/web/hsqlSupport.html" target="_top">http://hsqldb.org/web/hsqlSupport.html</a>.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="altformats-sect"></a>Available formats for this document</h2>
+</div>
+</div>
+</div>
+<p>This document is available in several formats.</p>
+<p>
+      You may be reading this document right now at http://hsqldb.org/doc/2.0, or in
+      a distribution somewhere else.
+      I hereby call the document distribution from which you are reading 
+      this, your <span class="emphasis"><em>current distro</em></span>.
+  </p>
+<p>
+      http://hsqldb.org/doc/2.0 hosts the latest production versions of all available formats.
+      If you want a different format of the same <span class="emphasis"><em>version</em></span>
+      of the document you are reading now, then you should try your
+      current distro.
+      If you want the latest production version, you should try http://hsqldb.org/doc/2.0.
+  </p>
+<p>
+      Sometimes, distributions other than http://hsqldb.org/doc/2.0 do not host all
+      available formats.
+      So, if you can't access the format that you want in your current
+      distro, you have no choice but to use the newest production version at 
+      http://hsqldb.org/doc/2.0.
+  </p>
+<p>
+    
+<div class="table">
+<a name="altformats-tbl"></a>
+<p class="title">
+<b>Table&nbsp;1.&nbsp;Available formats of this document</b>
+</p>
+<div class="table-contents">
+<table summary="Available formats of this document" cellspacing="0" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; border-left: 0.5pt solid ; border-right: 0.5pt solid ; ">
+<colgroup>
+<col align="left">
+<col align="left">
+<col align="left">
+</colgroup>
+<thead>
+<tr>
+<th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">format</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">your distro</th><th style="border-bottom: 0.5pt solid ; " align="left">at http://hsqldb.org/doc/2.0</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              Chunked HTML
+          </td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              <a class="link" href="index.html" target="_top">index.html</a>
+          </td><td style="border-bottom: 0.5pt solid ; " align="left">
+          <a class="link" href="http://hsqldb.org/doc/2.0/util-guide/" target="_top">http://hsqldb.org/doc/2.0/util-guide/</a>
+          </td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              All-in-one HTML
+          </td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left">
+              <a class="link" href="util-guide.html" target="_top">util-guide.html</a>
+          </td><td style="border-bottom: 0.5pt solid ; " align="left">
+        <a class="link" href="http://hsqldb.org/doc/2.0/util-guide/util-guide.html" target="_top">http://hsqldb.org/doc/2.0/util-guide/util-guide.html</a>
+          </td>
+</tr>
+<tr>
+<td style="border-right: 0.5pt solid ; " align="left">
+              PDF
+          </td><td style="border-right: 0.5pt solid ; " align="left">
+              <a class="link" href="util-guide.pdf" target="_top">util-guide.pdf</a>
+          </td><td style="" align="left">
+          <a class="link" href="http://hsqldb.org/doc/2.0/util-guide/util-guide.pdf" target="_top">http://hsqldb.org/doc/2.0/util-guide/util-guide.pdf</a>
+          </td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<br class="table-break">
+    If you are reading this document now with a standalone PDF reader, the
+    <span class="guilabel">your distro</span> links may not work.
+  </p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="sqltool-chapt"></a>Chapter&nbsp;1.&nbsp;SqlTool</h2>
+</div>
+<div>
+<h3 class="subtitle">
+<i>SqlTool Manual</i>
+</h3>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+<div>
+<p class="releaseinfo">$Revision: 3607 $</p>
+</div>
+<div>
+<p class="pubdate">$Date: 2010-06-01 07:18:26 -0400 (Tue, 01 Jun 2010) $</p>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#sqltool_book_purpose-sect">Purpose, Coverage, Changes in Behavior</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N100FB">Platforms and SqlTool versions covered</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1011D">Recent Functional Changes</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10188">New Features</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_baremin-sect">The Bare Minimum</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N102AE">Embedding</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N102C3">Non-displayable Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N102E3">Desktop shortcuts</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10344">Loading sample data</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N10360">Satisfying SqlTool's CLASSPATH Requirements</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#sqltool_olderaccess-sect">
+          Accessing older HSQLDB Databases with SqlTool</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N103BC">App-specific Classes, Embedding, and non-HyperSQL Databases</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10403">Distributing SqlTool with your Apps</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10429">SqlTool Client PCs</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_auth-sect">RC File Authentication Setup</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_dsswitch-sect">Switching Data Sources</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_ilauth-sect">Using Inline RC Authentication</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_logging-sect">Logging</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_int-sect">Interactive Usage</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10578">SqlTool Command-Line Editing</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1059C">Command Types</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#N105B5">Command Types</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N105FB">Special Commands</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N106CC">Edit Buffer / History Commands</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_interactive_pl_commands-sect">PL Commands</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N107C2">? Variable</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_binary_files-sect">
+                Storing and retrieving binary files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1080C">Command History</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10816">Shell scripting and command-line piping</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N1081F">Emulating Non-Interactive mode</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_nonint-sect">Non-Interactive</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#sqltool_sqlswitch-sect">Giving SQL on the Command Line</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10871">SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_scripting-sect">Piping and shell scripting</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N108E1">Optimally Compatible SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N108F4">Comments</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10901">Special Commands and Edit Buffer Commands in SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10965">Automation</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10970">Getting Interactive Functionality with SQL Files</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_charencoding-sect">
+                Character Encoding</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_report-sect">Generating Text or HTML Reports</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_pl-sect">SqlTool Procedural Language</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10A08">Variables</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_macro-sect">Macros</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10A67">PL Sample</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10A78">Logical Expressions</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10AEB">Flow Control</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B0E">Example</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_chunk-sect">Chunking</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10B2C">Why?</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10B3D">How?</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_raw-sect">Raw Mode</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_embedded-langs-sect">SQL/PSM, SQL/JRT, and PL/SQL</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#sqltool_dsv-sect">Delimiter-Separated-Value Imports and Exports</a></span>
+</dt>
+<dd>
+<dl>
+<dt>
+<span class="section"><a href="#N10BE4">Simple DSV exports and imports using default settings</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#N10C1F">Specifying queries and options</a></span>
+</dt>
+</dl>
+</dd>
+<dt>
+<span class="section"><a href="#sqltool_unittest-sect">Unit Testing SqlTool</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_book_purpose-sect"></a>Purpose, Coverage, Changes in Behavior</h2>
+</div>
+</div>
+</div>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+        Due to many important improvements to SqlTool, both in terms of
+        stability and features, all users of SqlTool are advised to use the
+        latest version of SqlTool, even if your database instances run with an
+        older HSQLDB version.
+        How to do this is documented in the
+      <a class="link" href="#sqltool_olderaccess-sect" title="Accessing older HSQLDB Databases with SqlTool">
+          Accessing older HSQLDB Databases with SqlTool</a>
+        section below.
+      </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            This document explains how to use SqlTool, the main purpose of
+            which is to read your SQL text file or stdin, and execute the SQL
+            commands therein against a JDBC database.
+            There are also a great number of features to facilitate both
+            interactive use and automation.
+            The following paragraphs explain in a general way why SqlTool is
+            better than any existing tool for text-mode interactive SQL work,
+            and for automated SQL tasks.
+            Two important benefits which SqlTool shares with other pure Java
+            JDBC tools is that users can use a consistent interface and
+            syntax to interact with a huge variety of databases-- any
+            database which supports JDBC; plus the tool itself runs on any
+            Java platform.
+            Instead of using <code class="filename">isql</code> for Sybase,
+            <code class="filename">psql</code> for Postgresql,
+            <code class="filename">Sql*plus</code> for Oracle, etc., you can
+            use SqlTool for all of them.
+            As far as I know, SqlTool is the only production-ready, pure
+            Java, command-line, generic JDBC client.
+            Several databases come with a command-line client with limited
+            JDBC abilities (usually designed for use with just their specific
+            database).
+      </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+          The SqlTool commands and settings are intuitive once you are
+          famililar with the usage idioms.
+          This Guide does not attempt to list every SqlTool command and
+          option available.
+          When you want to know what SqlTool commands or options are available
+          for a specific purpose, you need to list the commands of the
+          appropriate type with the relevant "?" command.
+          For example, as explained below, to see all Special commands, you
+          would run <code class="literal">\?</code>; and to see all DSV export options,
+          you run \x?.
+      </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+          SqlTool is purposefully not a Gui tool like Toad or DatabaseManager.
+          There are many use cases where a Gui SQL tool would be better.
+          Where automation is involved in any way, you really need a text
+          client to at least test things properly and usually to prototype
+          and try things out.
+          A command-line tool is really better for executing SQL scripts,
+          any form of automation, direct-to-file fetching, and remote client
+          usage.
+          To clarify this last, if you have to do your SQL client work on a
+          work server on the other side of a VPN connection, you will quickly
+          appreciate the speed difference between text data transmission
+          and graphical data transmission, even if using VNC or Remote Console.
+          Another case would be where you are doing some repetitive or
+          very structured work where variables or language features would
+          be useful.
+          Gui proponents may disagree with me, but scripting (of any sort)
+          is more efficient than repetitive copy &amp; pasting with a Gui
+          editor.
+          SqlTool starts up very quickly, and it takes up a tiny fraction of
+          the RAM required to run a comparably complex Gui like Toad.
+        </p>
+<p>
+          SqlTool is superior for interactive use because over many years it
+          has evolved lots of features proven to be efficient for day-to-day
+          use.
+          Four concise help commands (\?, :?, *?, and /?) list all available
+          commands of the corresponding type.
+          SqlTool doesn't support up-arrow or other OOB escapes (due to basic
+          Java I/O limitations), but it more than makes up for this limitation
+          with macros, user variables, command-line history and recall, and
+          command-line editing with extended Perl/Java regular expressions.
+          The \d commands deliver JDBC metadata information as consistently as
+          possible (in several cases, database-specific work-arounds are used
+          to obtain the underlying data even though the database doesn't
+          provide metadata according to the JDBC specs).
+          Unlike server-side language features, the same feature set works
+          for any database server.
+          Database access details may be supplied on the command line, but
+          day-to-day users will want to centralize JDBC connection details
+          into a single, protected RC file.
+          You can put connection details (username, password, URL, and other
+          optional settings) for scores of target databases into your RC file,
+          then connect to any of them whenever you want by just giving
+          SqlTool the ID ("urlid") for that database.
+          When you Execute SqlTool interactively, it behaves by default
+          exactly as you would want it to.
+          If errors occur, you are given specific error messages and you
+          can decide whether to roll back your session.
+          You can easily change this behavior to auto-commit,
+          exit-upon-error, etc., for the current session or for all
+          interactive invocations.
+          You can import or export delimiter-separated-value files.
+          If you need to run a specific statement repeatedly, perhaps changing
+          the WHERE clause each time, it is very simple to define a macro.
+        </p>
+<p>
+          When you Execute SqlTool with a SQL script, it also behaves by
+          default exactly as you would want it to.
+          If any error is encountered, the connection will be rolled back,
+          then SqlTool will exit with an error exit value.
+          If you wish, you can detect and handle error (or other) conditions
+          yourself.
+          For scripts expected to produce errors (like many scripts provided
+          by database vendors), you can have SqlTool continue-upon-error.
+          For SQL script-writers, you will have access to portable scripting
+          features which you've had to live without until now.
+          You can use variables set on the command line or in your script.
+          You can handle specific errors based on the output of SQL commands
+          or of your variables.
+          You can chain SQL scripts, invoke external programs, dump data
+          to files, use prepared statements,
+          Finally, you have a procedural language with <code class="literal">if</code>,
+          <code class="literal">foreach</code>, <code class="literal">while</code>,
+          <code class="literal">continue</code>, and <code class="literal">break</code> statements.
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N100FB"></a>Platforms and SqlTool versions covered</h3>
+</div>
+</div>
+</div>
+<p>
+            SqlTool runs on any Java 1.5 or later platform.
+            I know that SqlTool works well with Sun and OpenJDK JVMs.
+            I haven't run other vendors' JVMs in years (IBM, JRockit, etc.).
+            As my use with OpenJDK proves that I don't depend on Sun-specific
+            classes, I expect it to work well with other (1.5-compatible) Java
+            implementations.
+        </p>
+<p>
+            SqlTool no longer writes any files without being explicitly
+            instructed to.
+            Therefore, it should work fine on read-only systems, and you'll
+            never have orphaned temp files left around.
+        </p>
+<p>
+            The command-line examples in this chapter work as given on all
+            platforms (if you substitute in a normalized path in place of
+            <code class="literal">$HSQLDB_HOME</code>), except where noted otherwise.
+            When doing any significant command-line work on Windows
+            (especially shell scripting), you're better off to completely
+            avoid paths with spaces or funny characters.
+            If you can't avoid it, use double-quotes and expect problems.
+            As with any Java program, file or directory paths on the command
+            line after "java" can use forward slashes instead of back slashes
+            (this goes for System properties and the
+            <code class="varname">CLASSPATH</code> variable too).
+            I use forward slashes because they can be used consistently, and
+            I don't have to contort my fingers to type them :).
+        </p>
+<p>
+            If you are using SqlTool from a HyperSQL distribution of version
+            1.8.x or earlier, you should use the documentation with that
+            distribution, because this manual documents many new features,
+            several significant changes to interactive-only commands, and
+            a few changes effecting backwards-compatibility (see next
+            section about that).
+            This document is now updated for the current versions of SqlTool
+            and SqlFile at the time I am writing this (versions
+            3406 and 3604 correspondingly-- SqlFile is the
+            class which actually processes the SQL content for SqlTool).
+            Therefore, if you are using a version of SqlTool or SqlFile that
+            is more than a couple revisions greater, you should find a newer
+            version of this document.
+            (The imprecision is due to content-independent revision increments
+            at build time, and the likelihood of one or two
+            behavior-independent bug fixes after public releases).
+            The startup banner will report both versions when you run SqlTool
+            interactively.
+            (Dotted version numbers of SqlTool and SqlFile definitely indicate
+            ancient versions).
+        </p>
+<p>
+            This guide covers SqlTool as bundled with HSQLDB after 1.8.x.
+            <sup>[<a href="#ftn.samplelocFn" name="samplelocFn" class="footnote">1</a>]</sup>
+        
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1011D"></a>Recent Functional Changes</h3>
+</div>
+</div>
+</div>
+<p>This section lists changes to SqlTool since the last
+              major release of HSQLDB which may effect the portability
+              of SQL scripts.
+              For this revision of this document, this list consists of
+              script-impacting changes made to SqlTool
+              <span class="emphasis"><em>after</em></span> the final 1.8.0.0 HSQLDB release.
+              I'm specifically not listing changes to interactive(:)-only
+              commands ( with one legacy exception which is listed below),i
+              since these commands can't be used in SQL scripts;
+              and I'm specifically not listing backwards-compatible feature
+              additions and enhancements.
+              The reason for limiting the change list to only portability-
+              impacting changes is that a list of all enhancements since
+              just 1.8.1.1 would be pages long.
+            </p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+                 SqlTool is now bundled in the supplied file
+                 <code class="literal">sqltool.jar</code> instead of
+                 <code class="filename">hsqldb.jar</code>.
+                 Therefore, the usage idiom
+                 <code class="literal">java -jar .../hsqldb.jar</code> has changed to
+                 <code class="literal">java -jar .../sqltool.jar</code>.
+                 (depending on where you get your HyperSQL resources from,
+                 these files may be named with a version label, like
+                 <code class="filename">sqltool-1.2.3.4.jar</code>).
+                </li>
+<li>
+                 The package of SqlTool and support classes has been changed
+                 from <code class="classname">org.hsqldb.util</code> to
+                 <code class="classname">org.hsqldb.cmdline</code>.
+                 There is no change to <code class="literal">java -jar...</code> command-lines,
+                 but you will need to change the package name in SqlTool
+                 command lines of the form <code class="literal">java... org.hsqldb...</code>.
+                 This later usage is necessary if you need to modify the
+                 classpath for any reason, such as for embedding, to use a
+                 logging config file, or to use a non-HSQLDB JDBC driver.
+                </li>
+<li>
+                  SqlTool now consistently outputs \r\n line breaks when
+                  on \r\n-linebreak platforms, like Windows.
+                  This includes output written to stdout, \w files,
+                  and \o files.
+                </li>
+<li>
+                  Time type values are always output with the date as
+                  well as the time.
+                  This was required in order to produce consistent output
+                  for the wildly varying formats provided by different
+                  database vendors.
+                </li>
+<li>
+                  DSV input now takes JDBC Timestamp format with date and
+                  optionally time of day.
+                </li>
+<li>
+                  The command ":;" is now strictly an interactive command.
+                  If you want to repeat a command in an SQL scripts, just
+                  repeat the exact text of the command.
+                  Non-interactive use now has no dependency on command history.
+                </li>
+<li>
+                  The command ":w" has replace the command \w.
+                  Unlike writing "output" to a file with \w, :w is used to
+                  write SQL "commands", and this is an interactive feature.
+                </li>
+<li>
+                  Shell scripts using raw mode (e.g. PL/SQL scripts) must
+                  terminate the raw code with a line containing ".;", which
+                  will also send the code to the database for execution.
+                  (The old "." command has been changed to ":." to make it
+                  very clear that that command is now an interactive command).
+                </li>
+<li>
+                  You must use raw mode to <span class="emphasis"><em>chunk</em></span> SQL
+                  statements to your DB server.
+                  I.e., with previous versions of SqlTool, SQL statements
+                  were only sent to the DB server when a semi-colon is read
+                  at the end of a line.
+                  SqlTool now has a much more powerful parser, and individual
+                  SQL statements are sent to the DB server as soon as they
+                  are terminated with a semi-colon, regardless of line
+                  delimiters.
+                  Therefore, to send multiple SQL statements to the DB server
+                  in one transmittal, you must use raw mode.
+                </li>
+<li>
+                  The --sql argument will never automatically append a
+                  semicolon to the text you provide.
+                  If you want to execute a command ending with a semi--
+                  then type a semi.
+                </li>
+<li>
+                  Default encoding used is now the platform's default encoding
+                  instead of <code class="literal">US-ASCII</code>.
+                </li>
+<li>
+                  To minimize side-effects (especialy for instance-based
+                  programmatic usage), the only System properties used are
+                  those predefined by the JVM (incl.
+                  <code class="literal">javax.net.ssl.*</code>.
+                  Properties of the form <code class="literal">sqlfile.*</code> and
+                  <code class="literal">sqltool.*</code> are specifically no longer
+                  supported.
+                  (Less invasive configuration systems are provided to serve
+                  the same purposes).
+                </li>
+<li>
+                  SqlTool no longer displays the usage banner if none of
+                  inline-RC, urlid, SQL files are supplied, because that now
+                  starts up SqlTool with no JDBC Connection.
+                  To see the usage banner, use the <code class="literal">--help</code>
+                  command-line switch.
+                </li>
+<li>
+                  Requires Java 1.5 in order to build or run.
+                </li>
+<li>
+                  Update and row counts are not displayed in non-interactive
+                  mode.
+                  The count values are readily available in a format more
+                  suitable for scripting uses through PL variables (like with
+                  <code class="literal">*{?}</code> or <code class="literal">* VARNAME _</code>).
+                </li>
+</ul>
+</div>
+<p>
+                Although it doesn't effect scripts, I will mention a
+                significant recent change to interactive commands which could
+                confuse existing power users.
+                Special and PL commands are now stored to the edit buffer
+                and to command history, so they can be recalled and edited
+                just like SQL commands.  Now, all commands other than
+                edit/history : commands are stored to the buffer and history.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10188"></a>New Features</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+                    DSV column and row delimiters are now specified
+                    separately for input and output.
+                    This allows the input delimiters to be regular expressions.
+                    (Which in turn, allows for the next item).
+                </li>
+<li>
+                    The new default DSM import row delimiter works for
+                    standard UNIX, Windows, Mac lines.
+                    This makes DSV files portable across these platforms.
+                    (If using a change control system like Subversion, CVS,
+                    or whatever, you can now change control your .dsv files
+                    as native ASCII files).
+                </li>
+<li>
+                    Both <code class="literal">/* This kind */</code> and
+                    <code class="literal">-- This kind</code> of comments are now
+                    handled generally and intuitively, in SQL statements
+                    and in SqlTool-specific commands.
+                    (There were previously several limitations to where they
+                    could be used).
+                </li>
+<li>
+                    At the cost of adding another
+                    <span class="emphasis"><em>command type</em></span>, command aliases were
+                    replaced by / <span class="emphasis"><em>macros</em></span>.
+                    Usage (i.e., execution) is basically the same, but the new
+                    macros are much easier to define and list; and macros can
+                    be used for both PL and Special commands now (not just
+                    for SQL statements).
+                </li>
+<li>
+                    Reports Transaction Isolation level and JDBC Connection
+                    Read/Write or Read-Only state connection or request
+                    (with \j).
+                </li>
+<li>
+                    New \t command to report database exection duration times.
+                </li>
+<li>
+                    New \v command to set or report the Connection's
+                    Transaction Isolation LeVel.
+                </li>
+<li>
+                    
+<code class="literal">\d object filter</code> commands now use the
+                    filter as a regular expression, where possible, and
+                    filter may have optional prefix / to mean to match the
+                    filter against all output (not just the object name).
+                </li>
+<li>
+                    
+<code class="literal">\dX filter</code> commands now use the
+                    filter as a regular expression, where possible.
+                </li>
+<li>
+                    New <code class="varname">*DSV_TRIM_ALL</code> to automatically
+                    handle import of
+                    data which is both positional and character-delimited.
+                </li>
+<li>
+                    New \l command to log user-specified messages with
+                    <code class="classname">java.util.logging</code> or Log4j
+                    logging facility.
+                    Nothing at all is written directly to stderr.
+                </li>
+<li>
+                    All warnings and messages now use logging facility.
+                    This allows for declarative fine control of what gets
+                    logged and where the messages go to, as well as allowing
+                    for embedded apps to manage SqlTool apps in an integrated
+                    fashion with other app log entries.
+                </li>
+<li>
+                    New *DSV_RECORDS_PER_COMMIT setting to support
+                    user-specified tuning of large DSV imports.
+                </li>
+<li>
+                    (Optional) DSV log report can be customized with style
+                    sheets.
+                </li>
+<li>
+                    You can interactively (or in SQL scripts) switch JDBC data
+                    sources (with \j).
+                    SqlTool can be started and used without any data source,
+                    though you'll obviously need to connect to a data source
+                    before issuing SQL commands.
+                </li>
+<li>
+                  Array types are now supported, including in DSV imports and
+                  exports, with the exception that DSV imports do not support
+                  element values containing commas.
+                </li>
+</ul>
+</div>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_baremin-sect"></a>The Bare Minimum</h2>
+</div>
+<div>
+<h3 class="subtitle">The Bare Minimum You Need to Know to Run SqlTool</h3>
+</div>
+</div>
+</div>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            If you are using an Oracle database server, it will commit your
+            current transaction if you cleanly disconnect, regardless of
+            whether you have set auto-commit or not.
+            This will occur if you exit SqlTool (or any other client) in
+            the normal way (as opposed to killing the process or using
+            Ctrl-C, etc.).
+            This is mentioned in this section only for brevity, so I don't
+            need to mention it in the main text in the many places where
+            auto-commit is discussed.
+            This behavior has nothing to do with SqlTool.
+            It is a quirk of Oracle.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            If you want to use SqlTool, then you either have an SQL text file,
+            or you want to interactively type in SQL commands.
+            If neither case applies to you, then you are probably
+            looking at the wrong program.
+        </p>
+<div class="procedure">
+<a name="N101E0"></a>
+<p class="title">
+<b>Procedure&nbsp;1.1.&nbsp;To run SqlTool...</b>
+</p>
+<ol type="1">
+<li>
+<p>
+                    Copy the file
+                    <code class="filename"><a class="filename" href="#sqltool.rc-link">
+                    sample/sqltool.rc</a></code>
+                    <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup>
+                    of your HyperSQL distribution to your home directory and
+                    secure access to it if your computer is accessible
+                    to anybody else (most likely from the network).
+                    This file will work as-is for a Memory Only database
+                    instance; or if your target is a HyperSQL Server
+                    running on your local computer with default settings
+                    and the password for the "SA" account is blank
+                    (the SA password is blank when new HyperSQL database
+                    instances are created).
+                    Edit the file if you need to change the target Server URL,
+                    username, password, character set, JDBC driver, or TLS
+                    trust store as documented in the
+                    <a class="link" href="#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a>
+                    section.
+                    You could, alternatively, use the
+                    <code class="literal">--inlineRc</code> command-line switch or the
+                    \j special command to connect up to a data source, as
+                    documented below.
+                </p>
+</li>
+<li>
+<p>
+                    Find out where your <code class="filename">sqltool.jar</code> file
+                    resides.
+                    It typically resides at
+            <code class="varname">HSQLDB_HOME</code><code class="filename">/lib/sqltool.jar</code>
+                    where <code class="varname">HSQLDB_HOME</code> is the
+                    "hsqldb" directory inside the root level of your HyperSQL
+                    software installation.
+                    (For example, if you extract
+                    <code class="filename">hsqldb-9.1.0.zip</code> into
+                    <code class="filename">c:\temp</code>,
+                    your <code class="varname">HSQLDB_HOME</code> would be
+                    <code class="filename">c:/temp/hsqldb-9.1.0/hsqldb</code>.
+                    Your file may also have a version label in the file name,
+                    like <code class="filename">sqltool-1.2.3.4.jar</code>.
+                    The forward slashes work just fine on Windows).
+                    For this reason, I'm going to use
+                    "$HSQLDB_HOME/lib/sqltool.jar" as the path to
+                    <code class="filename">sqltool.jar</code> for my examples, but
+                    understand that you need to use the actual path to your
+                    own <code class="filename">sqltool.jar</code> file.
+                    (Unix users may set a real env. variable if they wish,
+                    in which case the examples may be used verbatim;
+                    Window users may do the same, but will need to dereference
+                    the variables like <code class="literal">%THIS%</code> instead of
+                    like <code class="literal">$THIS</code>).
+                </p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    My examples assume there are no spaces or funky characters
+                    in your file paths.
+                    This avoids bugs with the Windows cmd shell and makes for
+                    simpler syntax all-around.
+                    If you insist on using directories with spaces or shell
+                    metacharacters (including standard Windows home directories
+                    like <code class="filename">C:\Documents and Settings\blaine</code>),
+                    you will need to double-quote arguments containing these
+                    paths.
+                    (On UNIX you can alternatively use single-quotes to avoid
+                    variable dereferencing at the same time).
+                </p>
+</td>
+</tr>
+</table>
+</div>
+</li>
+<li>
+<p>
+                    If you are just starting with SqlTool, you are best off
+                    running your SqlTool command from a shell
+                    <span class="emphasis"><em>command-line</em></span> (as opposed to by
+                    using icons or the Windows'
+                    <span class="guimenuitem">Start/Run...</span> or
+                    <span class="guimenuitem">Start/Start Search</span>).
+                    This way, you will be sure to see error messages if you
+                    type the command wrong or if SqlTool can't start up for
+                    some reason.
+                    On recent versions of Windows, you can get a shell by
+                    running <code class="literal">cmd</code> from
+                    <span class="guimenuitem">Start/Run...</span> or
+                    <span class="guimenuitem">Start/Start Search</span>).
+                    On UNIX or Linux, any real or virtual terminal will work.
+                    </p>
+<p>
+                    On your shell command line, run
+                    <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar --help</pre>
+</div>
+                    to see what command-line arguments are available.
+                    Note that you don't need to worry about setting the
+                    <code class="varname">CLASSPATH</code>
+                    when you use the <code class="literal">-jar</code> switch
+                    to <code class="filename">java</code>.
+              </p>
+<p>
+                To run SqlTool without a JDBC connection, run
+                    <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar</pre>
+</div>
+                You won't be able to execute any SQL, but you can play with
+                the SqlTool interface (including using PL features).
+              </p>
+<p>
+                To execute SQL, you'll need the classes for the target
+                database's JDBC driver (and database engine classes for
+                <em class="glossterm">in-process</em> databases).
+                As this section is titled <span class="emphasis"><em>The Bare Minimum</em></span>,
+                I'll just say that if you are running SqlTool from a HyperSQL
+                product installation, you are all set to connect to any kind of
+                HyperSQL database.
+                This is because SqlTool will look for the file
+                <code class="filename">hsqldb.jar</code> in the same directory as
+                <code class="filename">sqltool.jar</code>, and that file contains all of
+                the needed classes.
+                (SqlTool supports all JDBC databases and does not require a
+                HyperSQL installation, but these cases would take us beyond
+                <span class="emphasis"><em>the bare minimum</em></span>).
+                So, with <code class="filename">hsqldb.jar</code> in place, you can run
+                commands like
+                    <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar mem</pre>
+</div>
+                    for interactive use, or
+                    <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar --sql="SQL statement;" mem</pre>
+</div>
+                    or
+                    <div class="informalexample">
+<pre class="screen">     java -jar $HSQLDB_HOME/lib/sqltool.jar mem filepath1.sql...</pre>
+</div>
+                    where <code class="literal">mem</code> is an
+                    <span class="emphasis"><em>urlid</em></span>,
+                    and the following arguments are paths to text SQL files.
+                    For the filepaths, you can use whatever wildcards your
+                    operating system shell supports.
+                    </p>
+<p>
+                    The <span class="emphasis"><em>urlid</em></span> <code class="literal">mem
+                    </code>in these commands is a key
+                    into your RC file, as explained in the
+                    <a class="link" href="#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section.
+                    Since this is a <em class="glossterm">mem:</em> type catalog,
+                    you can use SqlTool
+                    with this urlid immediately with no database setup
+                    whatsoever (however, you can't persist any changes that
+                    you make to this database).
+                    The sample sqltool.rc file also defines the urlid
+                    "localhost-sa" for a local HyperSQL Listener.
+                    At the end of this section, I explain how you can load
+                    some sample data to play with, if you want to.
+                </p>
+</li>
+</ol>
+</div>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            If SqlTool fails to connect to the specified urlid and you don't
+            know why, add the invocation parameter <code class="literal">--debug</code>.
+            This will cause SqlTool to display a stack trace from where the
+            connection attempt fails.
+            (If a connection attempt fails with the interactive \j command,
+            details will always be displayed).
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            SqlTool does not <span class="emphasis"><em>commit</em></span> SQL changes by default.
+            (You can use the <code class="literal">--autoCommit</code> command-line
+            switch to have it auto-commit).
+            This leaves it to the user's disgression whether to commit or
+            rollback their modifications.
+            If you do want your changes committed, remember to run \= before
+            quitting SqlTool.
+            (Most databases also support the SQL command
+            <code class="literal">commit;</code>),
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            If you put a file named <code class="filename">auto.sql</code> into your
+            home directory, this file will be executed automatically every
+            time that you run SqlTool interactively (unless you invoke with
+            the <code class="literal">--noAutoFile</code> switch).
+        </p>
+<p>
+            To use a JDBC Driver other than the HyperSQL driver, you can't use
+            the <code class="literal">-jar</code> switch because you need to modify the
+            classpath.
+            You must add the <code class="filename">sqltool.jar</code> file and your JDBC
+            driver classes to your classpath,
+            and you must tell SqlTool what the JDBC driver class name is.
+            The latter can be accomplished by either using the "--driver"
+            switch, or setting "driver" in your config file.
+            The <a class="link" href="#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section.
+            explains the second method.  Here's an example of the first method
+            (after you have set the classpath appropriately).
+            <div class="informalexample">
+<pre class="screen">java org.hsqldb.cmdline.SqlTool --driver=oracle.jdbc.OracleDriver urlid</pre>
+</div>
+</p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            If the tables of query output on your screen are all messy
+            because of lines wrapping, the best and easiest solution
+            is usually to resize your terminal emulator window to make it
+            wider.
+            (With some terms you click &amp; drag the frame edges to resize,
+            with others you use a menu system where you can enter the number
+            of columns).
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N102AE"></a>Embedding</h3>
+</div>
+<div>
+<h4 class="subtitle">Using SqlTool to execute SQL files from your own Java
+            code</h4>
+</div>
+</div>
+</div>
+<p>
+            To repeat what is stated in the JavaDoc for the
+            <code class="classname"><a class="classname" href="#SqlTool.html-link">SqlTool</a></code>
+            class itself:
+            <span class="emphasis"><em>
+              Programmatic users will usually want to use the
+              objectMain(String[]) method if they want arguments and behavior
+              exactly like command-line SqlTool. If you don't need invocation
+              parameter parsing, <code class="filename">auto.sql</code> exection, etc.,
+              you will have more control and efficiency by using the SqlFile
+              class directly. The file
+              <code class="filename"><a class="filename" href="#SqlFileEmbedder.java-link">
+                src/org/hsqldb/sample/SqlFileEmbedder.java</a></code>
+              in the HyperSQL distribution provides an example for this latter
+              strategy. 
+            </em></span>
+          
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N102C3"></a>Non-displayable Types</h3>
+</div>
+</div>
+</div>
+<p>
+            There are some SQL types which SqlTool (being a text-based
+            program) can't display properly.
+            This includes the SQL types <code class="literal">BLOB</code>,
+            <code class="literal">JAVA_OBJECT</code>, <code class="literal">STRUCT</code>,
+            and <code class="literal">OTHER</code>.
+            When you run a query that returns any of these, SqlTool will
+            save the very first such value obtained to the binary buffer
+            and will not display any output from this query.
+            You can then save the binary value to a file, as explained in the
+          <a class="link" href="#sqltool_binary_files-sect" title="Storing and retrieving binary files">
+                Storing and retrieving binary files</a>
+            section.
+            </p>
+<p>
+            There are other types, such as <code class="literal">BINARY</code>, which
+            JDBC can make displayable (by using ResultSet.getString()), but
+            which you may very well want to retrieve in raw binary format.
+            You can use the \b command to retrieve any-column-type-at-all
+            in raw binary format (so you can later store the value to a
+            binary file).
+            </p>
+<p>
+            Another restriction which all text-based database clients have
+            is the practical inability for the user to type in binary data
+            such as photos, audio streams, and serialized Java objects.
+            You can use SqlTool to load any binary object into a database
+            by telling SqlTool to get the insert/update datum from a file.
+            This is also explained in the
+          <a class="link" href="#sqltool_binary_files-sect" title="Storing and retrieving binary files">
+                Storing and retrieving binary files</a>
+            section.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N102E3"></a>Desktop shortcuts</h3>
+</div>
+</div>
+</div>
+<p>
+                Desktop shortcuts and quick launch icons are useful, especially
+                if you often run SqlTool with the same set of arguments.
+                It's really easy to set up several of them-- one for each
+                way that you invoke SqlTool (i.e., each one would start
+                SqlTool with all the arguments for one of your typical startup
+                needs).
+                One typical setup is to have one shortcut for each database
+                account which you normally use (use a different
+                <code class="literal">urlid</code> argument in each shortcut's
+                <span class="guilabel">Target</span> specification.
+            </p>
+<p>
+                Desktop icon setup varies depending on your Desktop manager,
+                of course.
+                I'll explain how to set up a SqlTool startup icon in Windows
+                XP.
+                Linux and Mac users should be able to take it from there, since
+                it's easier with the common Linux and Mac desktops.
+            </p>
+<div class="procedure">
+<a name="N102F0"></a>
+<p class="title">
+<b>Procedure&nbsp;1.2.&nbsp;Creating a Desktop Shortcut for SqlTool</b>
+</p>
+<ol type="1">
+<li>
+<p>
+                    Right click in the main Windows background.
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">New</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">Shortcut</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    
+<span class="guibutton">Browse</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    Navigate to where your good JRE lives.  For recent Sun
+                    JRE's, it installs to
+                    <code class="filename">C:\Program Files\Java\*\bin</code>
+                    by default (the * will be a JDK or JRE identifier and
+                    version number).
+                </p>
+</li>
+<li>
+<p>
+                    Select <code class="filename">java.exe</code>.
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guibutton">OK</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">Next</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    Enter any name
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">Finish</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    Right click the new icon.
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guimenuitem">Properties</span>
+                
+</p>
+</li>
+<li>
+<p>
+                    Edit the <span class="guilabel">Target</span> field.
+                </p>
+</li>
+<li>
+<p>
+                    Leave the path to java.exe exactly as it is, including the
+                    quotes, but append to what is there.
+                    Beginning with a space, enter the command-line that you
+                    want run.
+                </p>
+</li>
+<li>
+<p>
+                    
+<span class="guibutton">Change Icon...</span> to a pretty icon.
+                </p>
+</li>
+<li>
+<p>
+                    If you want a quick-launch icon instead of (or in addition
+                    to) a desktop shortcut icon, click and drag it to your
+                    quick launch bar.  (You may or may not need to edit the
+                    Windows Toolbar properties to let you add new items).
+                </p>
+</li>
+</ol>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10344"></a>Loading sample data</h3>
+</div>
+</div>
+</div>
+<p>
+                If you want some sample database objects and data to play
+                with, execute the
+                <code class="filename"><a class="filename" href="#sampledata.sql-link">
+                  sample/sampledata.sql</a></code> SQL file
+                <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+                To separate the sample data from your regular data, you can
+                put it into its own schema by running this before you import:
+                <div class="informalexample">
+<pre class="programlisting">    CREATE SCHEMA sampledata AUTHORIZATION dba;
+    SET SCHEMA sampledata;</pre>
+</div>
+                Run it like this from an SqlTool session
+      <pre class="programlisting">    \i HSQLDB_HOME/sample/sampledata.sql</pre>
+                where <span class="bold"><strong>HSQLDB_HOME</strong></span> is the
+                base directory of your HSQLDB software installation
+                <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+            </p>
+<p>
+                For memory-only databases, you'll need to run this every
+                time that you run SqlTool.
+                For other (persistent) databases, the data will reside in
+                your database until you drop the tables.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N10360"></a>Satisfying SqlTool's CLASSPATH Requirements</h2>
+</div>
+</div>
+</div>
+<p>
+        As discussed earlier, only the single file
+        <code class="filename">sqltool.jar</code> is required to run SqlTool (the file
+        name may contain a version label like
+        <code class="filename">sqltool-1.2.3.4.jar</code>).
+        But it's useless as an SQL <span class="emphasis"><em>Tool</em></span> unless you can
+        connect to a JDBC data source, and for that you need the target
+        database's JDBC driver in the classpath.
+        For <em class="glossterm">in-process</em> catalogs, you'll also need the
+        database engine classes in the CLASSPATH.
+        The <a class="link" href="#sqltool_baremin-sect" title="The Bare Minimum">The Bare Minimum</a>
+        section explains that the easiest way to use SqlTool with any HyperSQL
+        database is to just use <code class="filename">sqltool.jar</code> in-place where
+        it resides in a HyperSQL installation.
+        This section explains how to satisfy the CLASSPATH requirements for
+        other setups and use cases.
+      </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_olderaccess-sect"></a>
+          Accessing older HSQLDB Databases with SqlTool</h3>
+</div>
+</div>
+</div>
+<p>
+          If you are using SqlTool to access non-HSQLDB database(s), then you
+          should use the latest and greatest-- just
+          grab the newest public release of SqlTool (like from the latest
+          public HyperSQL release) and skip this subsection.
+        </p>
+<p>
+          You are strongly encouraged to use the latest SqlTool release to
+          access older HSQLDB databases, to enjoy greatly improved SqlTool
+          robustness and features.
+          It is very easy to do this.
+          <div class="procedure">
+<ol type="1">
+<li>
+<p>
+            Obtain the latest <code class="filename">sqltool.jar</code> file.
+            One way to obtain the latest <code class="filename">sqltool.jar</code> file
+            is to download the latest HyperSQL distribution and extract that
+            single file
+            </p>
+</li>
+<li>
+<p>
+                Place (or copy) your new <code class="filename">sqltool.jar</code> file
+                right alongside the <code class="filename">hsqldb.jar</code> file for
+                your target database version.
+                If you don't have a local copy of the
+                <code class="filename">hsqldb.jar</code> file for your target database,
+                just copy it from your database server, or download the full
+                distribution for that server version and extract it.
+            </p>
+</li>
+<li>
+<p>
+                
+<span class="emphasis"><em>
+                  (If you have used older versions of SqlTool before, notice
+                  that you now invoke SqlTool by specifying the
+                  <code class="filename">sqltool.jar</code> file instead of the
+                  <code class="filename">hsqldb.jar</code>).
+                </em></span>
+                If your target database is a previous 2.x version of HyperSQL,
+                then you are finished and can use the new SqlTool for your older
+                database.  Users upgrading from a pre-2.x version please
+                continue...
+              </p>
+<p>
+                Run SqlTool like this.
+                <div class="informalexample">
+<pre class="screen">    java -jar path/to/sqltool.jar --driver=org.hsqldb.jdbcDriver...</pre>
+</div>
+                where you specify the pre-2.x JDBC driver name
+                <code class="classname">org.hsqldb.jdbcDriver</code>.
+                Give any other SqlTool parameters as you usually would.
+              </p>
+<p>
+                Once you have verified that you can access your database using
+                the <code class="literal">--driver</code> paramater as explained above,
+                edit your <code class="filename">sqltool.rc</code> file, and add a
+                new line
+                <div class="informalexample">
+<pre class="programlisting">    driver org.hsqldb.jdbcDriver</pre>
+</div>
+                after each urlid that is for a pre-2.x database.
+                Once you do this, you can invoke SqlTool as usual (i.e. you
+                no longer need the <code class="literal">--driver</code>
+                argument for your invocations).
+            </p>
+</li>
+</ol>
+</div>
+        
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N103BC"></a>App-specific Classes, Embedding, and non-HyperSQL Databases</h3>
+</div>
+</div>
+</div>
+<p>
+          For these situations, you need to add your custom, third-party, or
+          SQL driver classes to your Java CLASSPATH.
+          Java doesn't support adding arbitrary elements to the classpath when
+          you use the <code class="literal">-jar</code>, so you must set a classpath
+          containing <code class="filename">sqltool.jar</code> plus whatever else you
+          need, then invoke SqlTool without the <code class="literal">-jar</code> switch,
+          as briefly described at the end of the
+          <a class="link" href="#sqltool_baremin-sect" title="The Bare Minimum">The Bare Minimum</a>
+          section.
+          For embedded apps, invoke your own main class instead of SqlTool, and
+          you can invoke <code class="classname">SqlTool</code> or
+          <code class="classname">SqlFile</code> from your code base.
+        </p>
+<p>
+          To customize the classpath,
+          you need to set up your classpath by using your
+          operating system or shell variable <code class="varname">CLASSPATH</code> or
+          by using the <code class="filename">java</code> switch <code class="literal">-cp</code>
+          (or the equivalent <code class="literal">-classpath</code>).
+          I'm not going to take up space here to explain how to set up a
+          Java CLASSPATH.  That is a platform-dependent task that is
+          documented well in tons of Java introductions and tutorials.
+          What I'm responsible for telling you is <span class="emphasis"><em>what</em></span>
+          you need to add to your classpath.
+          For the non-embedded case where you have set up your CLASSPATH
+          environmental varialbe, you would invoke SqlTool like this.
+          <div class="informalexample">
+<pre class="screen">    java org.hsqldb.cmdline.SqlTool ...</pre>
+</div>
+            If you are using the <code class="literal">-cp</code> switch instead of a
+            <code class="varname">CLASSPATH</code> variable, stick it after
+            <code class="literal">java</code>.
+            After "<code class="literal">SqlTool</code>", give any SqlTool parameters
+            exactly as you would put after
+            <code class="literal">java -jar .../sqltool.jar</code> if you didn't need to
+            customize the CLASSPATH.
+            You can specify a JDBC driver class to use either with the
+            <code class="literal">--driver</code> switch to SqlTool, or in your
+            RC file stanza (the last method is usually more convenient).
+        </p>
+<p>
+          Note that without the <code class="literal">-jar</code> switch, SqlTool will
+          still automatically pull in HyperSQL JDBC driver or engine classes
+          from HyperSQL jar files in the same directory.
+          It's often a good practice to minimize your runtime classpath.
+          To prevent the possibility of pulling in classes from other HyperSQL
+          jar files, just copy <code class="filename">sqltool.jar</code> to some other
+          directory (which does not contain other HyperSQL jar files) and put
+          the path to that one in your classpath.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10403"></a>Distributing SqlTool with your Apps</h3>
+</div>
+</div>
+</div>
+<p>
+          You can distribute SqlTool along with your application, for
+          standalone or embedded invocation.
+          For embedded use, you will need to customize the classpath as
+          discussed in the previous item.
+          Either way, you should minimize your application footprint by
+          distributing only those HyperSQL jar files needed by your app.
+          You will obviously need <code class="filename">sqltool.jar</code> if you will
+          use the <code class="classname">SqlTool</code> or
+          <code class="classname">SqlFile</code> class in any way.
+          If your app will only connect to external HyperSQL listeners, then
+          build and include <code class="filename">hsqljdbc.jar</code>.
+          If your app will also <span class="emphasis"><em>run</em></span> a HyperSQL Listener,
+          you'll need to include <code class="filename">hsqldb.jar</code>.
+          If your app will connect directly to a
+          <em class="glossterm">in-process</em> catalog, then include
+          <code class="filename">hsqldbmain.jar</code>.
+          Note that you never need to include more than one of
+          <code class="filename">hsqldb.jar</code>, <code class="filename">hsqldbmain.jar</code>,
+          <code class="filename">hsqljdbc.jar</code>, since the former jars include
+          everything in the following jars.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10429"></a>SqlTool Client PCs</h3>
+</div>
+</div>
+</div>
+<p>
+          If you just want to be able to run SqlTool (interactively or
+          non-interactively) on a PC, and have no need for documentation, then
+          it's usually easiest to just copy 
+          <code class="filename">sqltool.jar</code> and <code class="filename">hsqldb.jar</code>
+          to the PCs (plus JDBC driver jars for any other target databases).
+          If you want to minize what you distribute, then build and
+          distribute <code class="filename">hsqljdbc.jar</code> or
+          <code class="filename">hsqldbmain.jar</code> instead of
+          <code class="filename">hsqldb.jar</code>, according to the criteria listed in
+          the previous sub-section.
+        </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_auth-sect"></a>RC File Authentication Setup</h2>
+</div>
+</div>
+</div>
+<p>
+            RC file authentication setup is accomplished by creating a text
+            RC configuration file.
+            In this section, when I say <span class="emphasis"><em>configuration</em></span>
+            or <span class="emphasis"><em>config</em></span> file, I mean an RC configuration
+            file.
+            RC files can be used by any JDBC client program that uses the
+            org.hsqldb.util.RCData class-- this includes
+            SqlTool, DatabaseManager, DatabaseManagerSwing.
+        </p>
+<p>
+            You can use it for your own JDBC client programs too.
+            There is example code showing how to do this at
+            <code class="filename"><a class="filename" href="#SqlFileEmbedder.java-link">
+              src/org/hsqldb/sample/SqlFileEmbedder.java</a></code>.
+        </p>
+<p>
+            The sample RC file shown here resides at
+            <code class="filename"><a class="filename" href="#sqltool.rc-link">sample/sqltool.rc</a></code>
+            in your HSQLDB distribution
+            <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+        </p>
+<div class="example">
+<a name="N10459"></a>
+<p class="title">
+<b>Example&nbsp;1.1.&nbsp;Sample RC File</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting"># $Id: sqltool.rc 3353 2009-12-15 19:52:13Z unsaved $
+
+# This is a sample RC configuration file used by SqlTool, DatabaseManager,
+# and any other program that uses the org.hsqldb.lib.RCData class.
+# See the documentation for SqlTool for various ways to use this file.
+
+# If you have the least concerns about security, then secure access to
+# your RC file.
+
+# You can run SqlTool right now by copying this file to your home directory
+# and running
+#    java -jar /path/to/sqltool.jar mem
+# This will access the first urlid definition below in order to use a 
+# personal Memory-Only database.
+# "url" values may, of course, contain JDBC connection properties, delimited
+# with semicolons.
+# As of revision 3347 of SqlFile, you can also connect to datasources defined
+# here from within an SqlTool session/file with the command "\j urlid".
+
+# You can use Java system property values in this file like this:  ${user.home}
+
+# The only feature added recently is the optional "transiso" setting,
+# which may be set to an all-caps transaction isolation level as listed
+# in the Java API Spec for java.sql.Connection.
+# Windows users are advised to use forward slashes instead of reverse slashes,
+# and to avoid paths containing spaces or other funny characters.  (This
+# recommendation applies to any Java app, not just SqlTool).
+
+# A personal Memory-Only (non-persistent) database.
+urlid mem
+url jdbc:hsqldb:mem:memdbid
+username SA
+password
+
+# A personal, local, persistent database.
+urlid personal
+url jdbc:hsqldb:file:${user.home}/db/personal;shutdown=true
+username SA
+password
+transiso TRANSACTION_READ_COMMITTED
+# When connecting directly to a file database like this, you should 
+# use the shutdown connection property like this to shut down the DB
+# properly when you exit the JVM.
+
+# This is for a hsqldb Server running with default settings on your local
+# computer (and for which you have not changed the password for "SA").
+urlid localhost-sa
+url jdbc:hsqldb:hsql://localhost
+username SA
+password
+
+
+
+# Template for a urlid for an Oracle database.
+# You will need to put the oracle.jdbc.OracleDriver class into your 
+# classpath.
+# In the great majority of cases, you want to use the file classes12.zip
+# (which you can get from the directory $ORACLE_HOME/jdbc/lib of any
+# Oracle installation compatible with your server).
+# Since you need to add to the classpath, you can't invoke SqlTool with
+# the jar switch, like "java -jar .../hsqldb.jar..." or 
+# "java -jar .../hsqlsqltool.jar...".
+# Put both the HSQLDB jar and classes12.zip in your classpath (and export!)
+# and run something like "java org.hsqldb.util.SqlTool...".
+
+#urlid cardiff2
+#url jdbc:oracle:thin:@aegir.admc.com:1522:TRAFFIC_SID
+#username blaine
+#password secretpassword
+#driver oracle.jdbc.OracleDriver
+
+
+
+# Template for a TLS-encrypted HSQLDB Server.
+# Remember that the hostname in hsqls (and https) JDBC URLs must match the
+# CN of the server certificate (the port and instance alias that follows 
+# are not part of the certificate at all).
+# You only need to set "truststore" if the server cert is not approved by
+# your system default truststore (which a commercial certificate probably
+# would be).
+
+#urlid tls
+#url jdbc:hsqldb:hsqls://db.admc.com:9001/lm2
+#username BLAINE
+#password asecret
+#truststore ${user.home}/ca/db/db-trust.store
+
+
+# Template for a Postgresql database
+#urlid blainedb
+#url jdbc:postgresql://idun.africawork.org/blainedb
+#username blaine
+#password losung1
+#driver org.postgresql.Driver
+
+# Template for a MySQL database.  MySQL has poor JDBC support.
+#urlid mysql-testdb
+#url jdbc:mysql://hostname:3306/dbname
+#username root
+#password hiddenpwd
+#driver com.mysql.jdbc.Driver
+
+# Note that "databases" in SQL Server and Sybase are traditionally used for
+# the same purpose as "schemas" with more SQL-compliant databases.
+
+# Template for a Microsoft SQL Server database
+#urlid msprojsvr
+#url jdbc:microsoft:sqlserver://hostname;DatabaseName=DbName;SelectMethod=Cursor
+# The SelectMethod setting is required to do more than one thing on a JDBC
+# session (I guess Microsoft thought nobody would really use Java for 
+# anything other than a "hello world" program).
+# This is for Microsoft's SQL Server 2000 driver (requires mssqlserver.jar
+# and msutil.jar).
+#driver com.microsoft.jdbc.sqlserver.SQLServerDriver
+#username myuser
+#password hiddenpwd
+
+# Template for a Sybase database
+#urlid sybase
+#url jdbc:sybase:Tds:hostname:4100/dbname
+#username blaine
+#password hiddenpwd
+# This is for the jConnect driver (requires jconn3.jar).
+#driver com.sybase.jdbc3.jdbc.SybDriver
+
+# Template for Embedded Derby / Java DB.
+#urlid derby1
+#url jdbc:derby:path/to/derby/directory;create=true
+#username ${user.name}
+#password any_noauthbydefault
+#driver org.apache.derby.jdbc.EmbeddedDriver
+# The embedded Derby driver requires derby.jar.
+# There'a also the org.apache.derby.jdbc.ClientDriver driver with URL
+# like jdbc:derby://&lt;server&gt;[:&lt;port&gt;]/databaseName, which requires
+# derbyclient.jar.
+# You can use \= to commit, since the Derby team decided (why???)
+# not to implement the SQL standard statement "commit"!!
+# Note that SqlTool can not shut down an embedded Derby database properly,
+# since that requires an additional SQL connection just for that purpose.
+# However, I've never lost data by not shutting it down properly.
+# Other than not supporting this quirk of Derby, SqlTool is miles ahead of ij.
+</pre>
+</div>
+</div>
+<br class="example-break">
+<p>
+            As noted in the comment (and as used in a couple examples), you
+            can use Java system properties like this: <code class="code">${user.home}</code>.
+            Windows users, please read the suggestion directed to you in the
+            file.
+        </p>
+<p>
+            You can put this file anywhere you want to, and specify the
+            location to SqlTool/DatabaseManager/DatabaseManagerSwing by
+            using the <code class="literal">--rcfile</code> argument.
+            If there is no reason to not use the default location (and there
+            are situations where you would not want to), then use the default
+            location and you won't have to give <code class="literal">--rcfile</code>
+            arguments to SqlTool/DatabaseManager/DatabaseManagerSwing.
+            The default location is <code class="filename">sqltool.rc</code> or
+            <code class="filename">dbmanager.rc</code> in your home directory
+            (corresponding to the program using it).
+            If you have any doubt about where your home directory is, just
+            run SqlTool with a phony urlid and it will tell you where it
+            expects the configuration file to be.
+            <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar x</pre>
+</div>
+</p>
+<p>
+            The config file consists of stanza(s) like this:
+        <div class="informalexample">
+<pre class="screen">    urlid web
+    url jdbc:hsqldb:hsql://localhost
+    username web
+    password webspassword</pre>
+</div>
+</p>
+<p>
+            These four settings are required for every urlid.
+            (There are optional settings also, which are described a couple
+            paragraphs down).
+            The URL may contain JDBC connection properties.
+            You can have as many blank lines and comments like
+        <div class="informalexample">
+<pre class="screen">    # This comment</pre>
+</div>
+        
+</p>
+<p>
+            in the file as you like.
+            The whole point is that the <span class="emphasis"><em>urlid</em></span> that you
+            give in your SqlTool/DatabaseManager command must match a
+            <span class="emphasis"><em>urlid </em></span> in your configuration file.
+        </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            Use whatever facilities are at  your disposal to protect your
+            configuration file.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            It should be readable, both locally and remotely, only to users
+            who run programs that need it.
+            On UNIX, this is easily accomplished by using <code class="literal">chmod/chown
+            </code> commands and making sure that it is protected from
+            anonymous remote access (like via NFS, FTP or Samba).
+        </p>
+<p>
+            You can also put the following optional settings into a urlid
+            stanza.  The setting will, of course, only apply to that urlid.
+        </p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">charset</span>
+</p>
+</td><td>
+                This is used by the SqlTool program, but not by the
+                DatabaseManager programs.
+                See the <a class="link" href="#sqltool_charencoding-sect" title="Character Encoding">
+                Character Encoding</a> section of the
+                <a class="link" href="#sqltool_nonint-sect" title="Non-Interactive">Non-Interactive</a>
+                section.
+                This is used for input and output files, not for stdin or
+                stdout, which are controlled by environmental variables and
+                Java system properties.
+                If you set no encoding for an urlid, input and outfiles will
+                use the same encoding as for stdin/stdout.
+                (As of right now, the charset setting here is not honored by
+                the \j command, but only when SqlTool loads an urlid specified
+                on the command-line).
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">driver</span>
+</p>
+</td><td>
+                Sets the JDBC driver class name.
+                You can, alternatively, set this for one
+                SqlTool/DatabaseManager invocation by using the command
+                line switch <span class="emphasis"><em>--driver</em></span>.
+                Defaults to <span class="emphasis"><em>org.hsqldb.jdbc.JDBCDriver</em></span>.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">truststore</span>
+</p>
+</td><td>
+                TLS trust keystore store file path as documented in the
+                TLS section of the Listeners chapter of the
+                <a class="link" href="http://hsqldb.org/doc/2.0/guide/index.html" target="_top">
+                  HyperSQL User Guide</a>
+                You usually only need to set this if the server is using a
+                non-publicly-certified certificate (like a self-signed
+                self-ca'd cert).
+                Relative paths will be resolved relative to the
+                <code class="varname">${user.dir}</code>
+                system property at JRE invocation time.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">transiso</span>
+</p>
+</td><td>
+                Specify the Transaction Isolation Level with an all-caps
+                string, exactly as listed in he Field Summary of the Java
+                API Spec for the class
+                <code class="classname">java.sql.Connection</code>.
+            </td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+            Property and SqlTool command-line switches override settings made
+            in the configuration file.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_dsswitch-sect"></a>Switching Data Sources</h2>
+</div>
+</div>
+</div>
+<p>
+          The \j command lets you switch JDBC Data Sources in your SQL files
+          (or interactively).
+          "\?" shows the syntax to make a connection by either RCData urlid
+          or by name + password + JDBC Url.
+          The urlid variant uses RC file of
+          <code class="filename">$HOME/sqltool.rc</code>.
+          We will add a way to specify an RC file if there is any demand for
+          that.
+        </p>
+<p>
+          You can start SqlTool without any JDBC Connection by specifying no
+          Inline RC and urlid of "-" (just a hyphen).
+          If you don't need to specify any SQL file paths, you can skip the
+          hypen, as in this example.
+            <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar --setVar=v1=one</pre>
+</div>
+          (The "-" is required when specifying one or more SQL files, in order
+          to distinguish urlid-spec from file-spec).
+          Consequently, if you invoke SqlTool with no parameters at all, you
+          will get a SqlTool session with no JDBC Connection.
+          You will obviously need to use \j before doing any database work.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_ilauth-sect"></a>Using Inline RC Authentication</h2>
+</div>
+</div>
+</div>
+<p>
+            Inline RC authentication setup is accomplished by using the
+            <code class="literal">--inlineRc</code> command-line switch on SqlTool.
+            The <code class="literal">--inlineRc</code> command-line switch takes
+            a comma-separated list of key/value elements.
+            The <code class="literal">url</code> and <code class="literal">user</code> elements
+            are required.  The rest are optional.
+            The <code class="literal">--inlineRc</code> switch is the only case where
+            you can give SQL file paths without a preceding urlid indicator
+            (an urlid or -).
+            The program knows not to look for an urlid if you give an inline.
+        </p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">url</code></span>
+</p>
+</td><td>
+                The JDBC URL of the database you wish to connect to.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">user</code></span>
+</p>
+</td><td>
+                The username to connect to the database as.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">charset</code></span>
+</p>
+</td><td>
+              Sets the character encoding. Overrides the platform default, or
+              what you have set by env variables or Java system properties.
+              (Does not effect stdin or stdout).
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">truststore</code></span>
+</p>
+</td><td>
+                The TLS trust keystore file path as documented in the TLS chapter.
+                Relative paths will be resolved relative to the current directory.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">transiso</code></span>
+</p>
+</td><td>
+                <code class="classname">java.sql.Connection</code> transaction
+                isolation level to connect with, as specified in the Java
+                API spec.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term"><code class="varname">password</code></span>
+</p>
+</td><td>
+<p>
+                You may only use this element to set empty password, like
+                <div class="informalexample">
+<pre class="screen">    password=</pre>
+</div>For any other password value, omit the
+                <code class="literal">password</code> element and you will be prompted
+                for the value.
+            </p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+            (Use the <code class="literal">--driver</code> switch instead of
+            <code class="literal">--inlineRc</code> to specify a JDBC driver class).
+            Here is an example of invoking SqlTool to connect to a standalone database.
+            <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar --inlineRc=url=jdbc:hsqldb:file:/home/dan/dandb,user=dan</pre>
+</div>
+        
+</p>
+<p>
+            For security reasons, you cannot specify a non-empty password as
+            an argument. You
+            will be prompted for a password as part of the login process.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_logging-sect"></a>Logging</h2>
+</div>
+</div>
+</div>
+<p>
+            Both the \l command and all warnings and error messages now use
+            a logging facility.
+            The logging facility hands off to Log4j if Log4j is found in the
+            classpath, and otherwise will hand off to
+            <code class="classname">java.util.logging</code>.
+            The default behavior of <code class="classname">java.util.logging</code>
+            should work fine for most users.
+            If you are using log4j and are redirecting with pipes, you may
+            want to configure a Console Appender with target of
+            <code class="literal">"System.err"</code> so that error output will go to
+            the error stream (all console output for
+            <code class="classname">java.util.logging</code> goes to stderr by default).
+            See the API specs for Log4j and for J2SE for how to configure
+            either product.
+            If you are embedding SqlTool in a product to process SQL files,
+            I suggest that you use log4j.
+            <code class="classname">java.util.logging</code> is neither scalable nor
+            well-designed.
+        </p>
+<p>
+            Run the command <code class="literal">\l?</code> to see how to use the
+            logging command <code class="literal">\l</code> in your SQL files (or
+            interactively), including what logging levels you may specify.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_int-sect"></a>Interactive Usage</h2>
+</div>
+</div>
+</div>
+<p>
+            Do read the
+            <a class="link" href="#sqltool_baremin-sect" title="The Bare Minimum">The Bare Minimum</a>
+            section before you read this section.
+        </p>
+<p>
+            You run SqlTool interactively by specifying no SQL filepaths on
+            the SqlTool command line.  Like this.
+            <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid</pre>
+</div>
+</p>
+<div class="procedure">
+<a name="N1055A"></a>
+<p class="title">
+<b>Procedure&nbsp;1.3.&nbsp;What happens when SqlTool is run interactively
+                (using all default settings)
+            </b>
+</p>
+<ol type="1">
+<li>
+<p>
+                SqlTool starts up and connects to the specified database,
+                using your SqlTool configuration file
+                (as explained in the
+                <a class="link" href="#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section).
+            </p>
+</li>
+<li>
+<p>
+                SQL file <code class="filename">auto.sql</code> in your home directory
+                is executed (if there is one),
+            </p>
+</li>
+<li>
+<p>
+                SqlTool displays a
+                banner showing the SqlTool and SqlFile version numbers and
+                describes the different command types that you can give, as
+                well as commands to list all of the specific commands available
+                to you.
+            </p>
+</li>
+</ol>
+</div>
+<p>
+            You exit your session by using the "\q" special command or ending
+            input (like with Ctrl-D or Ctrl-Z).
+        </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+          Any command may be preceded by space characters.
+          Special Commands, Edit Buffer Commands, PL Commands, Macros always
+          consist of just one line.
+        </p>
+<p>
+            These rules do not apply at all to
+            <a class="link" href="#sqltool_raw-sect" title="Raw Mode">Raw Mode</a>.
+            Raw mode is for use by advanced users when they want to completely
+            bypass SqlTool processing in order to enter a chunk of text for
+            direct transmission to the database engine.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10578"></a>SqlTool Command-Line Editing</h3>
+</div>
+</div>
+</div>
+<p>
+            If you are really comfortable with grep, perl, or vim, you will
+            instantly be an expert with SqlTool command-line editing.
+            Due to limitations of Java I/O, we can't use up-arrow recall,
+            which many people are used to from DosKey and Bash shell.
+            If you don't know how to use regular expressions, and don't want
+            to learn how to use them, then just forget command-recall.
+            <div class="itemizedlist">
+<p class="title">
+<b>Basic command entry (i.e., without regexps)</b>
+</p>
+<ul type="disc">
+<li>
+                    Just type in your command, and use the backspace-key to
+                    fix mistakes on the same line.
+                </li>
+<li>
+                    If you goof up a multi-line command, just hit the ENTER
+                    key twice to start over.  (The command will be moved to
+                    the buffer where it will do no harm).
+                </li>
+<li>
+                    Use the ":h" command to view your command history.
+                    You can use your terminal emulator scroll bar and copy
+                    and paste facility to repeat commands.
+                </li>
+<li>
+                    As long as you don't need to change text that is already
+                    in a command, you can easily repeat commands from the
+                    history like ":14;" to re-run command number 14 from
+                    history.
+                </li>
+<li>
+                    Expanding just a bit from the previous item, you can
+                    add on to a previous command by running a command like
+                    ":14a" (where the "a" means <span class="emphasis"><em>append</em></span>).
+                </li>
+<li>
+                   See the <a class="link" href="#sqltool_macro-sect" title="Macros">Macros</a>
+                    section about how to set and use macros.
+                </li>
+</ul>
+</div>
+        
+</p>
+<p>
+            If you use regular expressions to search through your command
+            history, or to modify commands, be aware that the command type
+            of commands in history are fixed.
+            You can search and modify the text after a \ or * prefix (if any),
+            but you can't search on or change a prefix (or add or remove one).
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1059C"></a>Command Types</h3>
+</div>
+</div>
+</div>
+<p>
+            When you are typing into SqlTool, you are always typing part of
+            the <span class="emphasis"><em>immediate command</em></span>.
+            If the immediate command is an SQL statement, it is executed as
+            soon as SqlTool reads in the trailing (unquoted) semi-colon.
+            Commands of the other command types are executed as soon as you
+            hit ENTER.
+            The interactive : commands can perform actions with or on the
+            edit buffer.
+            The <span class="emphasis"><em>edit buffer</em></span> usually contains a copy of
+            the last command executed, and you can always view it with the :b
+            command.
+            If you never use any : commands, you can entirely ignore the
+            edit buffer.
+            If you want to repeat commands or edit previous commands, you
+            will need to work with the edit buffer.
+            The immediate command contains whatever (and exactly what)
+            you type.
+            The command history and edit buffer may contain any type of
+            command other than comments and : commands
+            (i.e., : commands and comments are just not copied to the history
+            or to the edit buffer).
+          </p>
+<p>
+            Hopefully an example will clarify the difference between the
+            immediate command and the edit buffer.
+            If you type in the edit buffer Substitution command
+            "<code class="literal">:s/tbl/table/</code>", the :s command that you typed
+            is the immediate command (and it will never be stored to the
+            edit buffer or history, since it is a : command), but the purpose
+            of the substitution command is to modify the contents of the
+            edit buffer (perform a substitution on it)-- the goal being that
+            after your substitutions you would execute the buffer with the
+            "<code class="literal">:;</code>" command.
+            The ":a" command is special in that when you hit ENTER to execute
+            it, it copies the contents of the edit buffer to a new immediate
+            command and leaves you in a state where you are
+            <span class="emphasis"><em>appending</em></span> to that
+            <span class="emphasis"><em>immediate</em></span> command (nearly) exactly as if
+            you had just typed it in.
+        </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N105B5"></a>Command Types</h2>
+</div>
+</div>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Command types</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">SQL Statement</span>
+</p>
+</td><td>
+<p>
+                Any command that you enter which does not begin with "\", ":",
+                "* " or "/" is an SQL Statement.
+                The command is not terminated when you hit ENTER, like most
+                OS shells.
+                You terminate SQL Statements with either ";" or with a blank
+                line.
+                In the former case, the SQL Statement will be executed against
+                the SQL database and the command will go into the edit
+                buffer and SQL command history for editing or viewing later on.
+                In the former case,
+                <span class="emphasis"><em>execute against the SQL database</em></span> means
+                to transmit the SQL text to the database engine for execution.
+                In the latter case (you end an SQL Statement with a blank
+                line), the command will go to the edit buffer and SQL history,
+                but will not be executed (but you can execute it later from the
+                edit buffer).
+            </p>
+<p>
+                (Blank lines are only interpreted this way when SqlTool is
+                run interactively.
+                In SQL files, blank lines inside of SQL statements remain
+                part of the SQL statement).
+            </p>
+<p>
+                As a result of these termination rules, whenever you are
+                entering text that is not a Special Command, Edit Buffer /
+                History Command, or PL Command, you are always
+                <span class="emphasis"><em>appending</em></span> lines to an SQL Statement
+                or comment.
+                (In the case of the first line, you will be appending to an
+                empty SQL statement.  I.e. you will be starting a new SQL
+                Statement or comment).
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Special Command</span>
+</p>
+</td><td>
+                Run the command "\?" to list the Special Commands.
+                All of the Special Commands begin with "\".
+                I'll describe some of the most
+                useful Special Commands below.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Edit Buffer / History Command</span>
+</p>
+</td><td>
+                Run the command ":?" to list the Edit-Buffer/History Commands.
+                All of these commands begin with ":".
+                These commands use commands from the command history, or
+                operate upon the edit "buffer", so that
+                you can edit and/or (re-)execute previously entered commands.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">PL Command</span>
+</p>
+</td><td>
+<p>
+                Procedural Langage commands.
+                Run the command "*?" to list the PL Commands.
+                All of the PL Commands begin with "*".
+                PL commands are for setting and using scripting variables
+                and conditional and flow control statements like
+                <code class="literal">* if</code> and <code class="literal">* while</code>.
+                A few PL features (such as macros and updating and
+                selecing data directly from/to files) can be a real
+                convenience for nearly all users, so these features will be
+                discussed briefly in this section.
+                More detailed explanation of PL variables and the other
+                PL features, with examples, are covered in the
+                <a class="link" href="#sqltool_pl-sect" title="SqlTool Procedural Language">SqlTool Procedural Language</a> section.
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Macro Command</span>
+</p>
+</td><td>
+                Macro definition and usage commands.
+                Run the command "/?" to show the define, list, or use macros.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">Raw Mode</span>
+</p>
+</td><td>
+                The descriptions of command-types above do not apply to
+                <a class="link" href="#sqltool_raw-sect" title="Raw Mode">Raw Mode</a>.
+                In raw mode, SqlTool
+                doesn't interpret what you type at all.  It all just
+                goes into the edit buffer which you can send to the database
+                engine.
+                Beginners can safely ignore raw mode.
+                You will never encounter it unless you run the "\."
+                special command, or define a stored procedure or function.
+                See the
+                <a class="link" href="#sqltool_raw-sect" title="Raw Mode">Raw Mode</a> section
+                for the details.
+            </td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N105FB"></a>Special Commands</h2>
+</div>
+</div>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Essential Special Commands</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">\?</span>
+</p>
+</td><td>
+                help
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\q</span>
+</p>
+</td><td>
+                quit
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\j...</span>
+</p>
+</td><td>
+                View JDBC Data Source details or connect up to a JDBC Data
+                Source (replacing the current connection, if any).
+                Run \? to see the syntax for the different usages.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\i path/to/script.sql</span>
+</p>
+</td><td>
+                execute the specified SQL script, then continue again
+                interactively.
+                Since SqlTool is a Java program, you can safely use forward
+                slashes in your file paths, regardless of your operating
+                system.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\=</span>
+</p>
+</td><td>
+                commit the current SQL transaction.
+                Most users are used to typing the SQL statement
+                <code class="literal">commit;</code>, but this command is crucial for
+                those databases which don't support the statement.
+                It's obviously unnecessary if you have auto-commit mode on.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\x?</span>
+</p>
+</td><td>
+                List a summary of DSV eXporting, and all available DSV options.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\m?</span>
+</p>
+</td><td>
+                List a summary of DSV iMporting, and all available DSV options.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\d?</span>
+</p>
+</td><td>
+                List a summary of the \d commands below.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dt [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dv [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\ds [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\di [table_name]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dS [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\da [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dn [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\du [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\dr [filter_substring]</span>
+</p>
+</td><td></td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\d* [filter_substring]</span>
+</p>
+</td><td>
+<p>
+                Lists available objects of the given type.
+                <div class="itemizedlist">
+<ul type="disc">
+<li>t: non-system Tables</li>
+<li>v: Views</li>
+<li>s: Sequences</li>
+<li>i: Indexes</li>
+<li>S: System tables</li>
+<li>a: Aliases</li>
+<li>n: schema Names</li>
+<li>u: database Users</li>
+<li>r: Roles</li>
+<li>*: all table-like objects</li>
+</ul>
+</div>
+                If your database supports schemas, then the schema name will
+                also be listed.
+                </p>
+<p>
+                If you supply an optional <span class="emphasis"><em>filter substring</em></span>,
+                then only items which match the specified substring.
+                will be listed.
+                In most cases, the specified filter will be treated as a
+                regular expression matched against the candidate object names.
+                In order to take advantage of extreme server-side performance
+                benefits, however, in some cases the substring is passed to
+                the database server and the filter will processed by the server.
+                </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    The regexp test is case-sensitive!
+                    Even though in SQL queries and for the "\d objectname"
+                    command object names are usually case-insensitive, for
+                    the \dX commands, you must capitalize the filter
+                    substring exactly as it will appear in the special
+                    command output.
+                    This is an inconvenience, since the database engine
+                    will change names in SQL to default case unless you
+                    double-quote the name, but that is server-side
+                    functionality which cannot (portably) be reproduced by
+                    SqlTool.
+                    You can use spaces and other special characters in
+                    the string.
+                </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    Filter substrings ending with "." are special.
+                    If a substring ends with ".", then this means to narrow
+                    the search by the exact, case-sensitive schema name
+                    given.
+                    For example, if I run "\d* BLAINE.", this will list all
+                    table-like database objects in the "BLAINE" schema.
+                    The capitalization of the schema must be exactly the same
+                    as how the schema name is listed by the "\dn" command.
+                    You can use spaces and other special characters in
+                    the string.
+                    (I.e., enter the name exactly how you would enter it
+                    inside of double-quotes in an SQL command).
+                    This is an inconvenience, since the database engine
+                    will change names in SQL to default case unless you
+                    double-quote the name, but that is server-side
+                    functionality which cannot (portably) be reproduced by
+                    SqlTool.
+                </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    The filter string "." (just a plain dot) means the current
+                    session schema, for databases which support the concept
+                    according to the SQL standard (HyperSQL database does).
+                </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                    Indexes may not be searched for by
+                    <span class="emphasis"><em>substring</em></span>, only by
+                    exact target table name.
+                    So if <code class="literal">I1</code> is an index on table
+                    <code class="literal">T1</code>, then you list this index by running
+                    "\di T1".
+                    In addition, many database vendors will report on indexes
+                    only if a target table is identified.
+                    Therefore, "\di" with no argument will fail if your database
+                    vendor does not support it.
+                </p>
+</td>
+</tr>
+</table>
+</div>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\d objectname [[/]regexp]</span>
+</p>
+</td><td>
+<p>
+                Lists names of columns in the specified table or view.
+                <code class="literal">objectname</code> may be a base table name or
+                a schema.object name.
+                </p>
+<p>
+                If you supply a filter string, then only columns with a name
+                matching the given regular expression will be listd.
+                (If no special characters are used, this just means that
+                names containing the specified substring will match).
+                You'll find this filter is a great convenience compared to
+                other database utilities, where you have to list all columns
+                of large tables when you are only interested in one of them.
+                </p>
+<p>
+                To narrow the displayed information based on all column
+                outputs, instead of just the column names, just prefix the
+                expression with /.
+                For example, to list all INTERGER columns, you could run
+                <code class="literal">\d mytable /INTEGER</code>.
+                </p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                When working with real data (as opposed to learning or playing),
+                I often find it useful to run two SqlTool sessions in two
+                side-by-side terminal emulator windows.
+                I do all of my real work in one window, and use the other
+                mostly for \d commands.
+                This way I can refer to the data dictionary while writing SQL
+                commands, without having to scroll.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+            This list here includes only the <span class="emphasis"><em>essential</em></span>
+            Special Commands, but n.b. that there are other useful Special
+            Commands which you can list by running <code class="literal">\?</code>.
+            (You can, for example, execute SQL from external SQL files, and
+            save your interactive SQL commands to files).
+            Some specifics of these other commands are specified immediately
+            below, and the
+            <a class="link" href="#sqltool_report-sect" title="Generating Text or HTML Reports">Generating Text or HTML Reports</a>
+            section explains how to use the "\o" and "\H" special commands to
+            generate reports.
+        </p>
+<p>
+            Be aware that the <code class="literal">\!</code> Special Command does
+            not work for external programs that read from standard input.
+            You can invoke non-interactive and graphical interactive programs,
+            but not command-line interactive programs.
+        </p>
+<p>
+            SqlTool executes <code class="literal">\!</code> programs directly, it does
+            not run an operating system shell (this is to avoid OS-specific
+            code in SqlTool).
+            Because of this, you can give as many command-line arguments
+            as you wish, but you can't use shell wildcards or redirection.
+        </p>
+<p>
+            The \w command can be used to store any command in your SQL
+            history to a file.
+            Just restore the command to the edit buffer
+            with a command like "\-4" before you give the \w command.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="N106CC"></a>Edit Buffer / History Commands</h2>
+</div>
+</div>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Edit Buffer / History Commands</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">:?</span>
+</p>
+</td><td>
+                help
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:b</span>
+</p>
+</td><td>
+                List the current contents of the edit buffer.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:h</span>
+</p>
+</td><td>
+                Shows the Command History.
+                For each command which has been executed (up to the max
+                history length), the SQL command history will show the
+                command; its command number (#); and also how many commands
+                <span class="emphasis"><em>back</em></span> it is (as a negative number).
+                : commands are never added to the history list.
+                You can then use either form of the command identifier to
+                recall a command to the edit buffer (the command described
+                next) or as the target of any of the following : commands.
+                This last is accomplished in a manner very similar to the
+                vi editor.
+                You specify the target command number between the colon
+                and the command.
+                As an example, if you gave the command
+                <code class="literal">:s/X/Y/</code>, that would perform the
+                substitution on the contents of the edit buffer; but if you
+                gave the command <code class="literal">:-3 s/X/Y/</code>, that would
+                perform the substitution on the command 3 back in the
+                command history (and copy the output to the edit buffer).
+                Also, just like vi, you can identify the command to recall
+                by using a regular expression inside of slashes, like
+                <code class="literal">:/blue/ s/X/Y/</code> to operate on the last
+                command you ran which contains "blue".
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:13  OR  :-2  OR   :/blue/</span>
+</p>
+</td><td>
+<p>
+                Recalls a command from Command history to the edit buffer.
+                Enter ":" followed by the positive command number from
+                Command history, like ":13"...  or ":" followed by a negative
+                number like ":-2" for two commands back in the Command
+                history... or ":" followed by a regular expression inside
+                slashes, like ":/blue/" to recall the last command which
+                contains "blue".
+                The specified command  will be written to the edit buffer
+                so that you can execute it or edit it using the commands below.
+                </p>
+<p>
+                As described under the :h command immediately above,
+                you can follow the command number here with
+                any of the commands below to perform the given operation
+                on the specified command from history instead of on the
+                edit buffer contents.
+                So, for example, ":4;" would load command 4 from history
+                then execute it (see the ":;" command below).
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:;</span>
+</p>
+</td><td>
+                Executes the SQL, Special or PL statement in the edit buffer
+                (by default).
+                This is an extremely useful command.
+                It's easy to remember because it consists of ":", meaning
+                <span class="emphasis"><em>Edit Buffer Command</em></span>, plus a
+                line-terminating ";", (which generally means to execute an
+                SQL statement, though in this case it will also execute a
+                special or PL command).
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:a</span>
+</p>
+</td><td>
+<p>
+                Enter append mode with the contents of the edit buffer (by
+                default) as the current command.
+                When you hit ENTER, things will be nearly exactly the same
+                as if you
+                physically re-typed the command that is in the edit buffer.
+                Whatever lines you type next will be appended to the immediate
+                command.
+                As always, you then have the choice of hitting ENTER to
+                execute a Special or PL command, entering a blank line to
+                store back to the edit buffer, or end a SQL statement with
+                semi-colon and ENTER to execute it.
+                </p>
+<p>
+                You can, optionally, put a string after the :a, in which
+                case things will be exactly as just described except the
+                additional text will also be appended to the new immediate
+                command.
+                If you put a string after the :a which ends with ;, then
+                the resultant new immediate command will just be executed
+                right away, as if you typed in and entered the entire thing.
+                </p>
+<p>
+                If your edit buffer contains
+                <code class="literal">SELECT x FROM mytab</code> and you run
+                <code class="literal">a:le</code>, the resultant command will be
+                <code class="literal">SELECT x FROM mytable</code>.
+                If your edit buffer contains
+                <code class="literal">SELECT x FROM mytab</code> and you run
+                <code class="literal">a: ORDER BY y</code>, the resultant command will be
+                <code class="literal">SELECT x FROM mytab ORDER BY y</code>.
+                Notice that in the latter case the append text begins with a
+                space character.
+            </p>
+<p>
+                You may notice that you can't use the left-arrow or backspace
+                key to back up over the original text.
+                This is due to Java and portability constraints.
+                If you want to edit existing text, then you shouldn't use the
+                Append command.
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:s/from regex/to string/switches</span>
+</p>
+</td><td>
+<p>
+                The Substitution Command is the primary method for SqlTool
+                command editing-- it operates upon the current edit buffer
+                by default.
+                The "to string" and the "switches" are both optional (though
+                the final "/" is not).
+                To start with, I'll discuss the use and behavior if you don't
+                supply any substitution mode switches.
+                </p>
+<p>
+                Don't use "/" if it occurs in either "from string" or "to
+                string".
+                You can use any character that you want in place of "/", but
+                it must not occur in the <span class="emphasis"><em>from</em></span> or
+                <span class="emphasis"><em>to</em></span> strings.
+                Example
+                <div class="informalexample">
+<pre class="screen">    :s@from string@to string@</pre>
+</div>
+</p>
+<p>
+                The <span class="emphasis"><em>to string </em></span> is substituted for the first
+                occurrence of the (case-specific)
+                <span class="emphasis"><em>from string</em></span>.
+                The replacement will consider the entire SQL statement, even
+                if it is a multi-line statement.
+                </p>
+<p>
+                In the example above, the from regex was a plain string, but
+                it is interpreted as a regular expression so you can do
+                all kinds of powerful substitutions.
+                See the <code class="literal">perlre</code> man page, or the
+                <a class="link" href="http://http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html" target="_top">java.util.regex.Pattern</a>
+                API Spec for everything you need to know about extended
+                regular expressions.
+                </p>
+<p>
+                Don't end a <span class="emphasis"><em>to</em></span> string with ";" in attempt
+                to make a command execute.
+                There is a substitution mode switch to use for that purpose.
+                </p>
+<p>
+                You can use any combination of the substitution mode switches.
+                <div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>
+                        Use "i" to make the searches for
+                        <span class="emphasis"><em>from regex</em></span> case insensitive.
+                    </p>
+</li>
+<li>
+<p>
+                        Use "g" to substitute Globally, i.e., to subsitute
+                        <span class="emphasis"><em>all</em></span> occurrences of the
+                        <span class="emphasis"><em>from regex</em></span> instead of only the
+                        first occurrence found.
+                    </p>
+</li>
+<li>
+<p>
+                        Use ";" to execute the command immediately after the
+                        substitution is performed.
+                    </p>
+</li>
+<li>
+<p>
+                        Use "m" for ^ and $ to match each line-break in a
+                        multi-line edit buffer, instead of just at the very
+                        beginning and every end of the entire buffer.
+                    </p>
+</li>
+</ul>
+</div>
+            
+</p>
+<p>
+                If you specify a command number (from the command history),
+                you end up with a feature very reminiscent of vi, but even
+                more powerful, since the Perl/Java regular expression are
+                a superset of the vi regular expressions.
+                As an example,
+                <div class="informalexample">
+<pre class="screen">    :24 s/pin/needle/g;</pre>
+</div> would start with command number 24 from
+                command history, substitute "needle" for all occurrences of
+                "pin", then execute the result of that substitution
+                (and this final statement will of course be copied to the
+                edit buffer and to command history).
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">:w /path/to/file.sql</span>
+</p>
+</td><td>
+                This appends the contents of the current buffer (by default)
+                to the specified file.
+                Since what is being written are Special, PL, or SQL commands,
+                you are effectively creating an SQL script.
+            </td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+            I find the ":/regex/"  and ":/regex/;" constructs particularly
+            handy for every-day usage.
+            <div class="informalexample">
+<pre class="screen">    :/\\d/;</pre>
+</div>re-executes the last \d command that you gave
+            (The extra "\" is needed to escape the special meaning of "\"
+            in regular expressions).
+            It's great to be able to recall and execute the last "insert"
+            command, for example, without needing to check the history or
+            keep track of how many commands back it was.  To re-execute
+            the last insert command, just run ":/insert/;".
+            If you want to be safe about it, do it in two steps to verify
+            that you didn't accidentally recall some other command which
+            happened to contain the string "insert", like
+            <div class="informalexample">
+<pre class="screen">    :/insert/
+    :;</pre>
+</div>(Executing the last only if you are
+            satisfied when SqlTool reports what command it restored).
+            Often, of course, you will want to change the command before
+            re-executing, and that's when you combine the :s and :a commands.
+        </p>
+<p>
+            We'll finish up with a couple fine points about Edit/Buffer
+            commands.
+            You generally can't use PL variables in Edit/Buffer commands, to
+            eliminate possible ambiguities and complexities when modifying
+            commands.
+            The :w command is an exception to this rule, since it can be
+            useful to use variables to determine the output file, and this
+            command does not do any "editing".
+        </p>
+<p>
+            The :? help explains how you can change the default regular
+            expression matching behavior (case sensitivity, etc.), but
+            you can always use syntax like "(?i)" inside of your regular
+            expression, as described in the Java API spec for class
+            <code class="classname"><a class="classname" href="http://http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html" target="_top">
+              java.util.regex.Pattern</a></code>.
+            History-command-matching with the /regex/ construct is
+            purposefully liberal, matching any portion of the command,
+            case sensitive, etc., but you can still use the method just
+            described to modify this behavior.  In this case, you could
+            use "(?-i)" at the beginning of your regular expression to
+            be case-sensitive.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_interactive_pl_commands-sect"></a>PL Commands</h2>
+</div>
+</div>
+</div>
+<div class="variablelist">
+<p class="title">
+<b>Essential PL Command</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">* VARNAME = value</span>
+</p>
+</td><td>
+<p>
+                Set the value of a variable.
+                If the variable doesn't exist yet, it will be created.
+                The most common use for this is so that you can later use
+                it in SQL statements, print statements, and PL conditionals,
+                by using the <code class="literal">*{VARNAME}</code> or
+                <code class="literal">*{:VARNAME}</code> construct.
+                The only difference between <code class="literal">*{literal}</code> and
+                <code class="literal">*{:VARNAME}</code> is that the former produces an
+                error if VARNAME is not set, whereas the latter will expand
+                to a zero-length string if VARNAME is not set.
+            </p>
+<p>
+                If you put variable definitions into the SQL file
+                <code class="filename">auto.sql</code> in your home directory, those
+                variables will always be available for interactive use.
+            </p>
+<p>
+                PL variables can be expanded within all commands other than
+                : edit/history commands.
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* load VARNAME /file/path.txt</span>
+</p>
+</td><td>
+                Sets VARNAME to the content of the specified ASCII file.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* prepare VARNAME</span>
+</p>
+</td><td>
+                Indicate that next command should be a SQL INSERT or UPDATE
+                command containing one question mark.
+                The value of VARNAME will be substuted for the ? variable.
+                This does work for CLOB columns.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* VARNAME _</span>
+</p>
+</td><td>
+                When next SQL command is run, instead of displaying the rows,
+                just store the very first column value to variable VARNAME.
+                This works for CLOB columns too.
+                It also works with Oracle XML type columns if you use
+                column labels and the <code class="literal">getclobval</code> function.
+            </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* VARNAME ~</span>
+</p>
+</td><td>
+<p>
+                Exactly the same as
+                <pre class="programlisting">    * VARNAME ~</pre>
+                except that the fetched results will be displayed in addition
+                to setting the variable.
+            </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">* dump VARNAME /file/path.txt</span>
+</p>
+</td><td>
+                Store the value of VARNAME to the specified ASCII file.
+            </td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N107C2"></a>? Variable</h3>
+</div>
+</div>
+</div>
+<p>
+            You don't set the ? variable.
+            It is just like the Bourne shell variable $? in that it is always
+            automatically set to the first value of a result set (or the
+            return value of other SQL commands).
+            It works just like the <code class="literal">* VARNAME ~</code>
+            command described above, but it all happens automatically.
+            You can, of course, dereference ? like any PL variable, but it
+            does not list with the <code class="literal">list</code> and
+            <code class="literal">listvalues</code> commands.
+            You can see the value whenever you want by running
+            <div class="informalexample">
+<pre class="programlisting">    \p *{?}</pre>
+</div>
+          
+</p>
+<p>
+            Note that PL commands are used to upload and download column
+            values to/from local ASCII files, but the corresponding actions
+            for binary files use the special \b commands.
+            This is because PL variables are used for ASCII values and
+            you can store any number of column values in PL variables.
+            This is not true for binary column values.
+            The \b commands work with a single binary byte buffer.
+        </p>
+<p>
+            See the <a class="link" href="#sqltool_pl-sect" title="SqlTool Procedural Language">SqlTool Procedural Language</a> section
+            below for information on using variables in other ways, and
+            information on the other PL commands and features.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_binary_files-sect"></a>
+                Storing and retrieving binary files</h3>
+</div>
+</div>
+</div>
+<p>
+            You can upload binary files such as photographs, audio files,
+            or serialized Java objects into database columns.
+            SqlTool keeps one binary buffer which you can load from files
+            with the \bl command, or from a database query by doing a
+            one-row query for any non-displayable type (including
+            <code class="literal">BLOB</code>, <code class="literal">OBJECT</code>, and
+            <code class="literal">OTHER</code>).
+            In the latter case, the data returned for the first
+            non-displayable column of the first result row will be stored
+            into the binary buffer.
+        </p>
+<p>
+            Once you have data in the binary buffer, you can upload it
+            to a database column (including <code class="literal">BLOB</code>,
+            <code class="literal">OBJECT</code>, and <code class="literal">OTHER</code> type
+            columns), or save it to a file.
+            The former is accomplished by the special command \bp followed
+            by a <span class="emphasis"><em>prepared</em></span> SQL query containing one
+            question mark place-holder to indicate where the data gets
+            inserted.
+            The latter is accomplished with the \bd command.
+        </p>
+<p>
+            You can also store the output from normal, displayable column
+            into the binary buffer by using the special command \b.
+            The very first column value from the first result row of the
+            next SQL command will be stored to the binary byte buffer.
+        </p>
+<div class="example">
+<a name="N107FC"></a>
+<p class="title">
+<b>Example&nbsp;1.2.&nbsp;Inserting binary data into database from a file</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    \bl /tmp/favoritesong.mp3
+    \bp
+    INSERT INTO musictbl (id, stream) VALUES(3112, ?);</pre>
+</div>
+</div>
+<br class="example-break">
+<div class="example">
+<a name="N10801"></a>
+<p class="title">
+<b>Example&nbsp;1.3.&nbsp;Downloading binary data from database to a file</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    SELECT stream FROM musictbl WHERE id = 3112;
+    \bd /tmp/favoritesong.mp3</pre>
+</div>
+</div>
+<br class="example-break">
+<p>
+            You can also store and retrieve text column values to/from
+            ASCII files, as documented in the
+            <a class="link" href="#sqltool_interactive_pl_commands-sect" title="PL Commands">Essential PL Command</a>
+            section.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1080C"></a>Command History</h3>
+</div>
+</div>
+</div>
+<p>
+            The SQL history shown by the \h command, and used by other commands,
+            is truncated to 100 entries, since its utility comes from being
+            able to quickly view the history list.
+            You can change the history length by setting the system property
+            <code class="literal">sqltool.historyLength</code> to the desire integer
+            value (using any of the System Property mechanisms provided by
+            Java).
+            If there is any demand, I'll make the setting of this value more
+            convenient.
+        </p>
+<p>
+            The SQL history list contains all executed commands other than
+            Edit Buffer commands and comments, even if the command has a
+            syntax error or fails upon execution.
+            The reason for including bad commands is so that you can
+            recall and fix them if you wish to.
+            The same applies to the edit buffer.
+            If you copy a command to the edit buffer by entering blank
+            line, or if you edit the edit buffer, that edit buffer value
+            will never make it into the command history until and if
+            you execute it.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10816"></a>Shell scripting and command-line piping</h3>
+</div>
+</div>
+</div>
+<p>
+            You normally use non-interactive mode for input piping.
+            You specify "-" as the SQL file name.
+            See the <a class="link" href="#sqltool_scripting-sect" title="Piping and shell scripting">Piping and shell scripting</a>
+            subsection of the Non-Interactive chapter.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N1081F"></a>Emulating Non-Interactive mode</h3>
+</div>
+</div>
+</div>
+<p>
+            You can run SqlTool <span class="emphasis"><em>interactively</em></span>, but
+            have SqlTool behave exactly as if it were processing an SQL
+            file (i.e., no command-line prompts, error-handling
+            that defaults to fail-upon-error, etc.).
+            Just specify "-" as the SQL file name in the command line.
+            This is a good way to test what SqlTool will do when it
+            encounters any specific command in an SQL file.
+            See the <a class="link" href="#sqltool_scripting-sect" title="Piping and shell scripting">Piping and shell scripting</a>
+            subsection of the Non-Interactive chapter for an example.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_nonint-sect"></a>Non-Interactive</h2>
+</div>
+</div>
+</div>
+<p>
+            Read the <a class="link" href="#sqltool_int-sect" title="Interactive Usage">Interactive Usage</a>
+            section if you have not already,
+            because much of what is in this section builds upon that.
+            You can skip all discussion about Command History and the
+            edit buffer if you will not use those interactive features.
+        </p>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            If you're doing data updates, remember to issue a commit command
+            or use the <code class="literal">--autoCommit</code> switch.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            As you'll see, SqlTool has many features that are very
+            convenient for scripting.  But what really makes it superior for
+            automation tasks (as compared to SQL tools from other vendors)
+            is the ability to reliably detect errors and to control JDBC
+            transactions.
+            SqlTool is designed so that you can reliably determine if errors
+            occurred within SQL scripts themselves, and from the invoking
+            environment (for example, from a perl, Bash, or Python script,
+            or a simple cron tab invocation).
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_sqlswitch-sect"></a>Giving SQL on the Command Line</h3>
+</div>
+</div>
+</div>
+<p>
+                If you just have a couple Commands to run, you can run them
+                directly from the comand-line or from a shell script without an
+                SQL file, like this.
+              <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar --sql="SQL statement;" urlid</pre>
+</div>
+            
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>The <code class="literal">--sql</code> switch automatically implies
+                <code class="literal">--noinput</code>, so if you want to execute the
+                specified SQL before <span class="emphasis"><em>and in addition to</em></span> an
+                interactive session (or stdin piping), then you must also give
+                the <span class="emphasis"><em>--stdinput</em></span> switch.
+              </p>
+</td>
+</tr>
+</table>
+</div>
+            
+</p>
+<p>
+                Since SqlTool transmits SQL statements to the database engine
+                only when a line is terminated with ";", if you want feedback
+                from multiple SQL statements in an --sql expression, you will
+                need to use functionality of your OS shell to include
+                linebreaks after the semicolons in the expression.
+                With any Bourne-compatible shell, you can include linebreaks in
+                the SQL statements like this.
+                <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar --sql='
+        SQL statement number one;
+        SQL statement
+            number two;
+        SQL statement three;
+    ' urlid</pre>
+</div>
+            
+</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                The multi-line examples in this section will only work as-is
+                with a Bourne-compatible shell.
+                With some ugliness they can be converted to C shell.
+                For Windows, you are better off to stick with SQL files for
+                multi-line input.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+                If you don't need feedback, just separate the SQL commands
+                with semicolons and the entire expression will be
+                <a class="link" href="#sqltool_chunk-sect" title="Chunking">chunked</a>.
+            </p>
+<p>
+                The <span class="emphasis"><em>--sql</em></span> switch is very useful for
+                setting shell variables to the output of SQL Statements, like
+                this.
+                <div class="informalexample">
+<pre class="programlisting">    # A shell script
+    USERCOUNT=`java -jar $HSQLDB_HOME/lib/sqltool.jar --sql='
+        select count(*) from usertbl;
+    ' urlid` || {
+        # Handle the SqlTool error
+    }
+    echo "There are $USERCOUNT users registered in the database."
+    [ "$USECOUNT" -gt 3 ] &amp;&amp; {   # If there are more than 3 users registered
+        # Some conditional shell scripting</pre>
+</div>
+            
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10871"></a>SQL Files</h3>
+</div>
+</div>
+</div>
+<p>
+                Just give paths to sql text file(s) on the command line after
+                the <span class="emphasis"><em>urlid</em></span>.
+            </p>
+<p>
+                Often, you will want to redirect output to a file, like
+                <div class="informalexample">
+<pre class="screen"> java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql... &gt; /tmp/file.log 2&gt;&amp;1</pre>
+</div>
+</p>
+<p>
+                You can also execute SQL files from an interactive session with
+                the "\i"' Special Command,
+                but be aware that the default behavior in an interactive
+                session is to continue upon errors.
+                If the SQL file was written without any concern for error
+                handling, then the file will continue to execute after errors
+                occur.
+                You could run <code class="literal">\c false</code> before
+                <code class="literal">\i filename</code>, but then your SqlTool session
+                will exit if an error is encountered in the SQL file.
+                If you have an SQL file without error handling, and you want
+                to abort that file when an error occurs, but not exit
+                SqlTool, the easiest way to accomplish this is usually to add
+                <code class="literal">\c false</code> to the top of the script.
+            </p>
+<p>
+                If you specify multiple SQL files on the command-line, the
+                default behavior is to exit SqlTool immediately if any of
+                the SQL files encounters an error.
+            </p>
+<p>
+                
+<span class="bold"><strong>
+                SQL files themselves have ultimate control over error handling.
+                </strong></span>
+                Regardless of what command-line options are set, or what
+                commands you give interactively, if a SQL file gives error
+                handling statements, they will take precedence.
+            </p>
+<p>
+                You can also use \i in SQL files.
+                This results in nested SQL files.
+            </p>
+<p>
+                You can use the following SQL file,
+                <code class="filename"><a class="filename" href="#sample.sql-link">
+                  sample/sample.sql</a></code>,
+                from your HyperSQL distribution
+                <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+                It contains SQL as well as Special Commands making good
+                use of most of the Special Commands documented below.
+            </p>
+<pre class="programlisting">/*
+    $Id: sample.sql 3637 2010-06-07 00:59:13Z unsaved $
+    Exemplifies use of SqlTool.
+    PCTASK Table creation
+*/
+
+/* Ignore error for these two statements */
+\c true
+DROP TABLE pctasklist;
+DROP TABLE pctask;
+\c false
+
+\p Creating table pctask
+CREATE TABLE pctask (
+    id integer identity,
+    name varchar(40),
+    description varchar(256),
+    url varchar(80),
+    UNIQUE (name)
+);
+
+\p Creating table pctasklist
+CREATE TABLE pctasklist (
+    id integer identity,
+    host varchar(20) not null,
+    tasksequence int not null,
+    pctask integer,
+    assigndate timestamp default current_timestamp,
+    completedate timestamp,
+    show boolean default true,
+    FOREIGN KEY (pctask) REFERENCES pctask,
+    UNIQUE (host, tasksequence)
+);
+
+\p Granting privileges
+GRANT select ON pctask TO public;
+GRANT all ON pctask TO tomcat;
+GRANT select ON pctasklist TO public;
+GRANT all ON pctasklist TO tomcat;
+
+\p Inserting test records
+INSERT INTO pctask (name, description, url) VALUES (
+    'task one', 'Description for task 1', 'http://cnn.com');
+INSERT INTO pctasklist (host, tasksequence, pctask) VALUES (
+    'admc-masq', 101, (SELECT id FROM pctask WHERE name = 'task one'));
+
+commit;
+</pre>
+<p>
+                You can execute this SQL file with a Memory Only database with
+                a command like
+              <div class="informalexample">
+<pre class="programlisting">    java -jar $HSQLDB_HOME/lib/sqltool.jar  --sql='
+        create user tomcat password "x";
+    ' mem path/to/hsqldb/sample/sample.sql</pre>
+</div>
+            This shows how you can mix SQL on the command line, and SQL inside
+            an SQL file.
+            </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                The example above uses Bourne shell syntax.
+                C shell syntax would be similar.
+                You would need to use an SQL file to accomplish this on Windows.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+                (The <code class="literal">--sql="create...;"</code> arguments create an
+                account which the script uses).
+                You should see error messages between the
+                <code class="literal">Continue-on-error...true</code> and
+                <code class="literal">Continue-on-error...false</code>.  The script
+                purposefully runs commands that might fail there.
+                The reason the script does this is to perform
+                database-independent conditional table removals.
+                (The SQL clause <code class="literal">IF EXISTS</code> is more graceful
+                and succinct, so you may want to use that if you don't need to
+                support databases which don't support
+                <code class="literal">IF EXISTS</code>).
+                If an error occurs when continue-on-error is false, the
+                script would abort immedately.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_scripting-sect"></a>Piping and shell scripting</h3>
+</div>
+</div>
+</div>
+<p>
+                You can of course, redirect output
+                <span class="emphasis"><em>from</em></span> SqlTool to a file
+                or another program.
+                <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql &gt; file.txt 2&gt;&amp;1
+
+java -jar $HSQLDB_HOME/lib/sqltool.jar urlid file.sql 2&gt;&amp;1 | someprogram...</pre>
+</div>
+</p>
+<p>
+                You can type commands in to SqlTool while being in
+                non-interactive mode by supplying "-" as the file name.
+                This is a good way to test how SqlTool will behave when
+                processing your SQL files.
+                <div class="informalexample">
+<pre class="screen">    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid -</pre>
+</div>
+</p>
+<p>
+                This is how you have SqlTool read its input from another
+                program:
+                <div class="example">
+<a name="N108CC"></a>
+<p class="title">
+<b>Example&nbsp;1.4.&nbsp;Piping input into SqlTool</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    echo "Some SQL commands with '$VARIABLES';" |
+    java -jar $HSQLDB_HOME/lib/sqltool.jar urlid -</pre>
+</div>
+</div>
+<br class="example-break">
+            For a shell not as graceful as the Bourne-compatible shells, you
+            would need to type this all on the same line (or use a
+            line-continuation trick).
+            </p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+              Beware of null stdin to SqlTool (or SqlFile).
+              At least with Java 6 on UNIX, <code class="classname">System.in</code>
+              returns megabytes of garbage for reads if stdin is closed.
+              I consider this an obvious bug.
+              Therefore, unlike any other program you would invoke from scripts,
+              check stdin before running any Java program that will read from
+              it.
+              I consider this a big ugly bug in Java.
+              This is not just theoretical, because many remote execution
+              environments will have stdin closed off.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+                Make sure that you also read the
+                <a class="link" href="#sqltool_sqlswitch-sect" title="Giving SQL on the Command Line">Giving SQL on the Command Line</a>
+                section.
+                The <code class="literal">--sql</code> switch is a great facility to use
+                with shell scripts.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N108E1"></a>Optimally Compatible SQL Files</h3>
+</div>
+</div>
+</div>
+<p>
+                If you want your SQL scripts optimally compatible among other
+                SQL tools, then don't use any Special or PL Commands.
+                SqlTool has default behavior which I think is far superior to
+                the other SQL tools, but you will have to disable these
+                defaults in order to have optimally compatible behavior.
+            </p>
+<p>
+                These switches provide compatibilty at the cost of poor
+                control and error detection.
+                <div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>
+                            --continueOnErr=true
+                        </p>
+<p>
+                            The output will still contain error messages about
+                            everything that SqlTool doesn't like
+                            (malformatted commands, SQL command failures,
+                            empty SQL commands), but SqlTool will continue to
+                            run.
+                            Errors will not cause rollbacks (but that won't
+                            matter because of the following setting).
+                        </p>
+</li>
+<li>--autoCommit</li>
+</ul>
+</div>
+            
+</p>
+<p>
+                You don't have to worry about accidental expansion of
+                PL variables, since SqlTool will never expand PL variables
+                if you don't set any variables on the command line, or give
+                any "* " PL commands.
+                (And you could not have "* " commands in a compatible SQL
+                file).
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N108F4"></a>Comments</h3>
+</div>
+</div>
+</div>
+<p>
+                Comments of the form <code class="literal">/*...*/</code> or
+                <code class="literal">--</code> behave as a SQL programmer would
+                expect, in all contexts other than in interactive
+                edit/history commands.
+            </p>
+<p>
+                If a comment occurs outside of an SQL statement, SqlTool
+                will not send the comment to the database (to improve
+                performance).
+                Raw mode can be used to send just comments to the database.
+                In order to proactively catch accidents, SqlTool will complain
+                if you attempt to send an empty SQL statement (i.e., just
+                whitespace) to the database, even in raw mode.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10901"></a>Special Commands and Edit Buffer Commands in SQL Files</h3>
+</div>
+</div>
+</div>
+<p>
+                Don't use Edit Buffer / History Commands in your sql files,
+                because they won't work.
+                Edit Buffer / History Commands are for interactive use only.
+                (But, see the
+                <a class="link" href="#sqltool_raw-sect" title="Raw Mode">Raw Mode</a> section
+                for an exception).
+                You can, of course, use any SqlTool command at all
+                interactively.
+                I just wanted to group together the commands most useful to
+                script-writers.
+            </p>
+<div class="variablelist">
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">\q [abort message]</span>
+</p>
+</td><td>
+<p>
+                    Be aware that the \q command will cause SqlTool to
+                    completely exit.
+                    If a script <code class="filename">x.sql</code> has a \q command in
+                    it, then it doesn't matter if the script is executed like
+          <pre class="screen">    java -jar .../sqltool.jar urlid a.sql x.sql z.sql</pre>
+                    or if you use
+                    \i to read it in interactively, or if another SQL file
+                    uses \i to nest it.
+                    If \q is encountered, SqlTool will quit.
+                    See the <a class="link" href="#sqltool_pl-sect" title="SqlTool Procedural Language">SqlTool Procedural Language</a>
+                    section for commands to abort an SQL file (or even parts
+                    of an SQL file) without causing SqlTool to exit.
+                </p>
+<p>
+                    \q takes an optional argument, which is an abort message.
+                    If you give an abort message, the message is displayed to
+                    the user and SqlTool will exit with a failure status.
+                    If you give no abort message, then SqlTool will exit
+                    quietly with successful status.
+                    As a result, <pre class="programlisting">    \q</pre>
+                    means to make an immediate but graceful exit, whereas
+                    <pre class="programlisting">    \q Message</pre>
+                    means to abort immediately.
+                </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\p [text to print]</span>
+</p>
+</td><td>
+                    Print the given string to stdout.
+                    Just give "\p" alone to print a blank line.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\i /path/to/file.sql</span>
+</p>
+</td><td>
+                    Include another SQL file at this location.
+                    You can use this to nest SQL files.
+                    For database installation scripts I often have a master
+                    SQL file which includes all of the other SQL files in the
+                    correct sequence.
+                    Be aware that the current continue-upon-error behavior
+                    will apply to included files until such point as the SQL
+                    file runs its own error handling commands.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\o [file/path.txt]</span>
+</p>
+</td><td>
+<p>
+                    Tee output to the specified file (or stop doing so).
+                    See the
+                    <a class="link" href="#sqltool_report-sect" title="Generating Text or HTML Reports">Generating Text or HTML Reports</a>
+                    section.
+                </p>
+</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\=</span>
+</p>
+</td><td>
+                    A database-independent way to commit your SQL session.
+                    Useful for database which have no <code class="literal">COMMIT</code>
+                    SQL statement.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\a [true|false]</span>
+</p>
+</td><td>
+                    This turns on and off SQL transaction autocommits.
+                    Auto-commit defaults to false, but you can change that
+                    behavior by using the <code class="literal">--autoCommit</code>
+                    command-line switch.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">\c [true|false]</span>
+</p>
+</td><td>
+<p>
+                    A "true" setting tells SqlTool to Continue when errors are
+                    encountered.
+                    The current transaction will not be rolled back upon SQL
+                    errors, so if \c is true, then run the
+                    <code class="literal">ROLLCACK;</code> command yourself if that's
+                    what you want to happen.
+                    The default for interactive use is to continue upon error,
+                    but the default for non-interactive use is to abort upon
+                    error.
+                    You can override this behavior by using the
+                    <code class="literal">--continueOnErr</code> command-line switch.
+                    </p>
+<p>
+                    With database setup scripts, I usually find it convenient
+                    to set "true" before dropping tables (so that things will
+                    continue if the tables aren't there), then set it back to
+                    false so that real errors are caught.
+                    <code class="literal">DROP TABLE tablename IF EXISTS;</code>
+                    is a more elegant, but less portable, way to accomplish
+                    the same thing.
+                    </p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                        It depends on what you want your SQL files to do, of
+                        course, but I usually want my SQL files to abort when
+                        an error is encountered, without necessarily killing
+                        the SqlTool session.
+                        If this is the behavior that you want, then
+                        put an explicit <code class="literal">\c false</code>
+                        at the top of your SQL file and turn on
+                        continue-upon-error only for sections where you really
+                        want to permit errors, or where you are using PL
+                        commands to handle errors manually.
+                        This will give the desired behavior whether your
+                        script is called by
+                        somebody interactively, from the SqlTool command-line,
+                        or included in another SQL file (i.e. nested).
+                    </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Important">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Important]" src="../images/db/important.png"></td><th align="left">Important</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                        The default settings are usually best for people who
+                        don't want to put in any explicit \c or error handling
+                        code at all.
+                        If you run SQL files from the SqlTool command line,
+                        then any errors will cause SqlTool to roll back and
+                        abort immediately.
+                        If you run SqlTool interactively and invoke SQL files
+                        with \i commands, the scripts will continue to run
+                        upon errors (and will not roll back).
+                        This behavior was chosen because there are lots of
+                        SQL files out there that produce errors which can be
+                        ignored; but we don't want to ignore errors that a
+                        user won't see.
+                        I reiterate that any and all of this behavior can (and
+                        often should) be changed by Special Commands run in
+                        your interactive shell or in the SQL files.
+                        Only you know whether errors in your SQL files can
+                        safely be ignored.
+                    </p>
+</td>
+</tr>
+</table>
+</div>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10965"></a>Automation</h3>
+</div>
+</div>
+</div>
+<p>
+                SqlTool is ideal for mission-critical automation because,
+                unlike other SQL tools, SqlTool returns a dependable exit
+                status and gives you control over error handling and SQL
+                transactions.
+                Autocommit is off by default, so you can build a completely
+                dependable solution by intelligently using \c commands
+                (Continue upon Errors) and commit statements, and by
+                verifying exit statuses.
+            </p>
+<p>
+                Using the SqlTool Procedural Language, you have ultimate
+                control over program flow, and you can use variables for
+                database input and output as well as for many other purposes.
+                See the <a class="link" href="#sqltool_pl-sect" title="SqlTool Procedural Language">SqlTool Procedural Language</a>
+                section.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10970"></a>Getting Interactive Functionality with SQL Files</h3>
+</div>
+</div>
+</div>
+<p>
+                Some script developers may run into cases where they want to
+                run with sql files but they alwo want SqlTool's interactive
+                behavior.
+                For example, they may want to do command recall in the sql file,
+                or they may want to log SqlTool's command-line prompts (which
+                are not printed in non-interactive mode).
+                In this case, do not give the sql file(s) as an argument to
+                SqlTool, but pipe them in instead, like
+                <div class="informalexample">
+<pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar urlid &lt; filepath1.sql &gt; /tmp/log.html 2</pre>
+</div>
+                or
+              <div class="informalexample">
+<pre class="screen">cat filepath1.sql... |
+java -jar $HSQLDB_HOME/lib/sqltool.jar urlid &gt; /tmp/log.html 2&gt;&amp;1</pre>
+</div>
+            For a shell not as graceful as the Bourne-compatible shells, you
+            would need to type this all on the same line (or use a
+            line-continuation trick).
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_charencoding-sect"></a>
+                Character Encoding</h3>
+</div>
+</div>
+</div>
+<p>
+              There are several levels of encoding settings.
+              First there are your platform defaults.
+              These can be changed, temporarily or permanently, with system
+              settings or environmental variables.
+              Java system properties may be used to change the encodings for
+              the JVM run.
+              Finally, can specify a different encoding in your RC file, as
+              documented in the
+              <a class="link" href="#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a>
+              section, though these will not effect stdin or stdout (as
+              explained there).
+              Programmatic users of <code class="classname">SqlFile</code> have
+              complete control over encoding by setting up
+              <code class="classname">Reader</code>s and
+              <code class="classname">PrintWriter</code>s,
+              or by using constructors with an <code class="literal">encoding</code>
+              parameter.
+              Developers should understand that where a
+              <code class="filename">SqlFile</code> constructor takes a
+              <code class="classname">Reader</code> or a
+              <code class="classname">PrintWriter</code> parameter, we will not apply
+              encoding settings to them, leaving that up to you.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_report-sect"></a>Generating Text or HTML Reports</h2>
+</div>
+</div>
+</div>
+<p>
+            This section is about making a file containing the output of
+            database queries.
+            You can generate reports by using operating system facilities
+            such as redirection, tee, and cutting and pasting.
+            But it is much easier to use the "\o" and "\H" special commands.
+        </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            I've neglected the \H feature, because I don't know of anybody
+            using it.
+            Be aware that it writes very old-fashioned HTML, with no attention
+            to encoding, metadata, style sheets, etc.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="procedure">
+<a name="N109A7"></a>
+<p class="title">
+<b>Procedure&nbsp;1.4.&nbsp;Writing query output to an external file</b>
+</p>
+<ol type="1">
+<li>
+<p>
+                By default, everthing will be done in plain text.
+                If you want your report to be in HTML format, then give the
+                special command <code class="literal">\H</code>.
+                If you do so, you will probably want to use filenames with an
+                suffix of ".html" or ".htm" instead of ".txt" in the next step.
+            </p>
+</li>
+<li>
+<p>
+                Run the command <code class="literal">\o path/to/reportfile.txt</code>.
+                From this point on, output from your queries will be appended
+                to the specified file.
+                (I.e. another <span class="emphasis"><em>copy</em></span> of the output is
+                generated.)
+                This way you can continue to monitor or use output as usual as
+                the report is generated.
+            </p>
+</li>
+<li>
+<p>
+                When you want SqlTool to stop writing to the file, run
+                <code class="literal">\o</code> (or just quit SqlTool if you have no
+                other work to do).
+            </p>
+</li>
+<li>
+<p>
+                If you turned on HTML mode with <code class="literal">\H</code> before,
+                you can run <code class="literal">\H</code> again to turn it back off,
+                if you wish.
+            </p>
+</li>
+</ol>
+</div>
+<p>
+            It is not just the output of "SELECT" statements that will make
+            it into the report file, but
+            <div class="itemizedlist">
+<p class="title">
+<b>Kinds of output that get teed to \o files</b>
+</p>
+<ul type="disc">
+<li>
+                    Output of SELECT statements.
+                </li>
+<li>
+                    Output of all "\d" Special Commands.
+                    (I.e., "\dt", "\dv", etc., and "\d OBJECTNAME").
+                </li>
+<li>
+                    Output of "\p" Special Commands.
+                    You will want to use this to add titles, and perhaps
+                    spacing, for the output of individual queries.
+                </li>
+</ul>
+</div>
+            Other output will go to your screen or stdout, but will not make
+            it into the report file.
+            Be aware that no error messages will go into the report file.
+            If SqlTool is run non-interactively (including if you give any
+            SQL file(s) on the command line), SqlTool will abort with an error
+            status if errors are encountered.
+            The right way to handle errors is to check the SqlTool exit status.
+            (The described error-handling behavior can be modified with
+            SqlTool command-line switches and Special Commands).
+        </p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            Remember that \o <span class="emphasis"><em>appends</em></span> to the named file.
+            If you want a new file, then use a new file name or remove the
+            pre-existing target file ahead of time.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            So that I don't end up with a bunch of junk in my report file, I
+            usually leave \o off while I perfect my SQL.  With \o off,
+            I perfect the SQL query until it produces on my screen exactly
+            what I want saved to file.
+            At this point I turn on \o and run ":/select/;" to repeat the
+            last SQL command containing the given string ("select" in this
+            example).
+            If I have several complex queries to run, I turn \o off and
+            repeat until I'm finished.
+            (Every time you turn \o on, it will append to the file, just
+            like we need).
+            </p>
+<p>
+            Usually it doesn't come to mind that I need a wider screen until
+            a query produces lines that are too long.
+            In this case, stretch your window and repeat the last command with
+            the ":;" Edit Buffer Command.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_pl-sect"></a>SqlTool Procedural Language</h2>
+</div>
+<div>
+<h3 class="subtitle">Aka PL</h3>
+</div>
+</div>
+</div>
+<p>
+            Most importantly, run <code class="filename">SqlTool</code> interactively
+            and give the "*?" command to see what PL commands are available to
+            you.
+            I've tried to design the language features to be intuitive.
+            Readers experience with significant shell scripting in any
+            language can probably learn everything they need to know by
+            looking at (and running!) the sample script
+            <code class="filename"><a class="filename" href="#pl.sql-link">
+              sample/pl.sql</a></code> in your HyperSQL distribution
+            <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup> and
+            using the <code class="varname">*?</code> command from within an interactive
+            SqlTool session as a reference.  (By
+            <span class="emphasis"><em>significant</em></span> shell scripting, I mean to the
+            extent of using variables, for loops, etc.).
+        </p>
+<p>
+            PL variables will only be expanded after you run a PL command (or
+            set variable(s) from the command-line).
+            We only want to turn on variable expansion if the user wants
+            variable expansion.
+            People who don't use PL don't have to worry about strings getting
+            accidentally expanded.
+        </p>
+<p>
+            All other PL commands imply the "*" command, so you only need to
+            use the "*" statement if your script uses PL variables
+            and it is possible that no variables may be set before-hand (and
+            no PL commands have been run previously).
+            In this case, without "*", your script would silently use a
+            literal value like "*{x}" instead of trying to expand it.
+            With a preceding "*" command, PL will notice that the variable
+            <code class="literal">x</code> has not been set and will generate an error.
+            (If x had been set here will be no issue because setting a
+            variable automatically turns on PL variable expansion).
+        </p>
+<p>
+            PL is also used to upload and download column values to/from
+            local ASCII files, analogously to the special \b commands
+            for binary files.
+            This is explained above in the Interactive
+            <a class="link" href="#sqltool_interactive_pl_commands-sect" title="PL Commands">Essential PL Command</a>
+            section above.
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10A08"></a>Variables</h3>
+</div>
+</div>
+</div>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+                    Use the <code class="literal">* list</code> command to list some or
+                    all variables; or <code class="literal">* listvalues</code> to also
+                    see the values.
+                </li>
+<li>
+                    You can set variables using the
+                    <code class="literal">* VARNAME = value</code> command.
+                    This document explains elsewhere how you can set a values
+                    to the contents of files, and to the return value of SQL
+                    statements and fetches.
+                </li>
+<li>
+                    You can also set variables using the
+                    <code class="literal">--setvar</code> command-line switch.
+                    I give a very brief but useful example of this below.
+                </li>
+<li>
+                    SqlTool does not allow for setting system variables.
+                    As explained below, they are expanded in the same way as
+                    PL variables.
+                </li>
+<li>
+                    Variables are always expanded in SQL, Special, and PL
+                    commands if they are written like
+                    <code class="literal">*{VARNAME}</code>
+                    (assuming that a PL command has been run previously).
+                    Your SQL scripts can give good feedback by echoing the
+                    value of variables with the "\p" special command.
+                    Use the construct <code class="literal">*{:VARNAME}</code> to
+                    expand the variable, but to expand to a zero-length
+                    string instead of fail if VARNAME is not set.
+                </li>
+<li>
+                    Java system variables work the same exact way, except you
+                    use <code class="literal">$</code> instead of <code class="varname">*</code>
+                    to dereference, like so:  <code class="literal">${user.name}</code>.
+                </li>
+<li>
+                    Variables are normally written like
+                    <code class="varname">*VARNAME</code> in logical expressions to
+                    prevent them from being evaluated too early.
+                    See below about logical expressions.
+                </li>
+<li>
+<p>
+                    You can't do math with expression variables, but you
+                    can get functionality like the traditional
+                    <code class="literal">for (i = 0; i &lt; x; i++)</code> by appending
+                    to a variable and testing the string length, like
+                    <pre class="programlisting">    * while (*i &lt; ${x})
+        * i = *{i}.</pre>
+                    
+<code class="literal">i</code> will be a growing line of dots.
+                </p>
+</li>
+<li>
+<p>
+                Variable names must not contain white space, or
+                the characters "}" or "=".
+                </p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="sqltool_macro-sect"></a>Macros</h3>
+</div>
+</div>
+</div>
+<p>
+                Macros are just shortcut commands that you can run in place of
+                the full commands which they stand for.
+                Macros stand for SQL, Special or PL commands, whereas PL
+                variables can only be used for elements within a command.
+                It is very easy to define, list, and use macros.
+                Run the command "/?" to see how.
+                If you often run a particular query, then for the effort of
+                about 5 extra keystrokes, you can define a macro for it so
+                that you can enter just "/q;" to run it, whether the original
+                query is 1 line or 40 lines.  (You can use any name in place
+                of "q", and the target command can be any kind of SQL,
+                special, or PL command).
+            </p>
+<p>
+                When you run/use a macro, you can append to the macro value.
+                <span class="emphasis"><em>appendage</em></span> in the "/?" listing shows
+                where you can append additional text to the original command.
+                So, if you define
+                <pre class="programlisting">    sql&gt; /= myworkers  SELECT name FROM employees</pre>
+                , you could narrow the query variously during different macro
+                invocations, like
+                <pre class="programlisting">    sql&gt; /myworkers WHERE dept = 20;
+    sql&gt; /myworkers WHERE name like 'Karen%';</pre>
+                
+</p>
+<p>
+                Just like when recalling a command from history, you use ";"
+                to execute even Special and PL macro commands.
+                <pre class="programlisting">    sql&gt; /= notate  Work completed by
+    sql&gt; /notate Blaine;</pre>
+                If you don't type the ;, you will just recall the command
+                to the buffer (from which you can execute or edit it, if
+                you wish to).
+            </p>
+<p>
+                To make a macro for a mult-line SQL statement, you use the
+                "/= name :" construct.
+                First, get the target command into the command buffer.
+                If you have already run the command, then run ":h" to see the
+                command number and load it to the buffer like ":13".
+                If you haven't run the command yet, then just enter the
+                command, but end it with a blank line (and no semi-colon).
+                You can check the buffer with ":b" to make sure it is what
+                you want.
+                Then just run "/= name :" to define a macro with name "name".
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10A67"></a>PL Sample</h3>
+</div>
+</div>
+</div>
+<p>
+                Here is a short SQL file that gives the specified user write
+                permissions on some application tables.
+            </p>
+<div class="example">
+<a name="N10A6C"></a>
+<p class="title">
+<b>Example&nbsp;1.5.&nbsp;Simple SQL file using PL</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">    /*
+       grantwrite.sql
+
+       Run SqlTool like this:
+           java -jar path/to/sqltool.jar -setvar=USER=debbie grantwrite.sql
+     */
+
+    /* Explicitly turn on PL variable expansion, in case no variables have
+       been set yet.  (Only the case if user did not set USER).
+    */
+    *
+
+    GRANT all ON book TO *{USER};
+    GRANT all ON category TO *{USER};</pre>
+</div>
+</div>
+<br class="example-break">
+<p>
+                Note that this script will work for any (existing) user just
+                by supplying a different user name on the command-line.
+                I.e., no need to modify the tested and proven script.
+                There is no need for a <code class="literal">commit</code> statement
+                in this SQL file since no DML is done.
+                If the script is accidentally run without setting the
+                USER variable, SqlTool will give a very clear notificaton of
+                that.
+            </p>
+<p>
+                The purpose of the plain "*" command is just
+                so that the *{USER} variables will be expanded.
+                (This would not be necessary if the USER variable, or any
+                other variable, were set, but we don't want to depend upon
+                that).
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10A78"></a>Logical Expressions</h3>
+</div>
+</div>
+</div>
+<p>
+                Logical expressions occur only inside of logical expression
+                parentheses in PL statements.
+                For example, <code class="literal">if (*var1 &gt; astring)</code> and
+                <code class="literal">while (*checkvar)</code>.
+                (The parentheses after "foreach" do not enclose a logical
+                expression, they just enclose a list).
+            </p>
+<p>
+                There is a critical difference between
+                <code class="literal">*{VARNAME}</code> and <code class="varname">*VARNAME</code>
+                inside logical expressions.
+                <code class="literal">*{VARNAME}</code> is expanded one time when the
+                parser first encounters the logical expression.
+                <code class="varname">*VARNAME</code> is re-expanded every time that the
+                expression is evaluated.
+                So, you would never want to code
+                <code class="literal">* while (*{X} &lt; 5)</code> because the statement
+                will always be true or always be false.
+                (I.e. the following block will loop infinitely or will never
+                run).
+            </p>
+<p>
+                Don't use quotes or whitespace of any kind in
+                <code class="literal">*{VARNAME}</code> variables in expressions.
+                (They would expand and then the expression would most likely
+                no longer be a valid expression as listed in the table below).
+                Quotes and whitespace are fine in <code class="varname">*VARNAME</code>
+                variables, but it is the entire value that will be used in
+                evaluations, regardless of whether quotes match up, etc.
+                I.e. quotes and whitespace are not <span class="emphasis"><em>special</em></span>
+                to the token evaluator.
+            </p>
+<div class="variablelist">
+<p class="title">
+<b>Logical Operators</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN</span>
+</p>
+</td><td>
+                    The token may be a literal, a <code class="literal">*{VARNAME}</code>
+                    which is expanded early, or a <code class="varname">*VARNAME</code>
+                    which is expanded late.
+                    (You usually do not want to use
+                    <code class="literal">*{VARNAME}</code> in logical expressions).
+                    False if the token is not set, empty, or "0".
+                    True otherwise.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 == TOKEN2</span>
+</p>
+</td><td>
+                    True if the two tokens are equivalent "strings".
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 &lt;&gt; TOKEN2</span>
+</p>
+</td><td>
+                    Ditto.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 &gt;&lt; TOKEN2</span>
+</p>
+</td><td>
+                    Ditto.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 &gt; TOKEN2</span>
+</p>
+</td><td>
+                    True if the TOKEN1 string is longer than TOKEN2 or is
+                    the same length but is greater according to a string sort.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">TOKEN1 &lt; TOKEN2</span>
+</p>
+</td><td>
+                    Similarly to TOKEN1 &gt; TOKEN2.
+                </td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">! LOGICAL_EXPRESSION</span>
+</p>
+</td><td>
+                    Logical negation of any of the expressions listed above.
+                </td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+                
+<code class="varname">*VARNAME</code>s in logical expressions, where the
+                VARNAME variable is not set, evaluate to an empty string.
+                Therefore <code class="literal">(*UNSETVAR = 0)</code> would be false,
+                even though <code class="literal">(*UNSETVAR)</code> by itself is false
+                and <code class="literal">(0)</code> by itself is false.
+                Another way of saying this is that <code class="varname">*VARNAME</code>
+                in a logical
+                expression is equivalent to *{:VARNAME} out of a logical
+                expression.
+            </p>
+<p>
+                When developing scripts, you definitely use SqlTool
+                interactively to verify that SqlTool evaluates logical
+                expressions as you expect.
+                Just run <code class="literal">* if</code> commands that print something
+                (i.e. \p) if the test expression is true.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10AEB"></a>Flow Control</h3>
+</div>
+</div>
+</div>
+<p>
+                Flow control works by conditionally executing blocks of
+                Commands according to conditions specified by logical
+                expressions.
+            </p>
+<p>
+                The conditionally executed blocks are called
+                <span class="emphasis"><em>PL Blocks</em></span>.
+                These PL Blocks always occur between a PL flow control
+                statement (like <code class="literal">* foreach, *while, * if</code>)
+                and a corresponding <code class="literal">* end</code> PL Command
+                (like <code class="literal">* end foreach</code>).
+            </p>
+<p>
+                The values of control variables for foreach and while PL
+                blocks will change as expected.
+            </p>
+<p>
+                There are <code class="literal">* break</code> and
+                <code class="literal">* continue</code>, which work as any shell
+                scripter would expect them to.
+                The <code class="literal">* break</code> command can also be used to
+                quit the current SQL file without triggering any error
+                processing.
+                (I.e. processing will continue with the next line in the
+                <span class="emphasis"><em>including</em></span> SQL file or interactive
+                session, or with the next SQL file if you supplied multiple on
+                the command-line).
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B0E"></a>Example</h3>
+</div>
+</div>
+</div>
+<p>
+                Below is the example SQL file
+                <code class="filename"><a class="filename" href="#pl.sql-link">sample/pl.sql</a></code>,
+                which shows how to use most PL
+                features <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+                If you have a question about how to use a particular
+                PL feature, check this file in your distrubition before asking
+                for help.
+                Definitely give it a run, like
+                <pre class="screen">java -jar $HSQLDB_HOME/lib/sqltool.jar mem $HSQLDB_HOME/pl.jar</pre>
+            
+</p>
+<div class="example">
+<a name="N10B1D"></a>
+<p class="title">
+<b>Example&nbsp;1.6.&nbsp;SQL File showing use of most PL features</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">/*
+    $Id: pl.sql 3353 2009-12-15 19:52:13Z unsaved $
+    SQL File to illustrate the use of SqlTool PL features.
+    Invoke like
+        java -jar .../hsqldb.jar .../pl.sql mem
+                                                         -- blaine
+*/
+
+* if (! *MYTABLE)
+    \p MYTABLE variable not set!
+    /* You could use \q to Quit SqlTool, but it's often better to just
+       break out of the current SQL file.
+       If people invoke your script from SqlTool interactively (with
+       \i yourscriptname.sql) any \q will kill their SqlTool session. */
+    \p Use arguments "--setvar=MYTABLE=mytablename" for SqlTool
+    * break
+* end if
+
+/* Turning on Continue-upon-errors so that we can check for errors ourselves.*/
+\c true
+
+\p
+\p Loading up a table named '*{MYTABLE}'...
+
+/* This sets the PL variable 'retval' to the return status of the following
+   SQL command */
+* retval ~
+CREATE TABLE *{MYTABLE} (
+    i int,
+    s varchar(20);
+);
+\p CREATE status is *{retval}
+\p
+
+/* Validate our return status.  In logical expressions, unset variables like
+   *unsetvar are equivalent to empty string, which is not equal to 0
+   (though both do evaluate to false on their own, i.e. (*retval) is false
+   and (0) is false */
+* if (*retval != 0)
+    \p Our CREATE TABLE command failed.
+    * break
+* end if
+
+/* Default Continue-on-error behavior is what you usually want */
+\c false
+\p
+
+/* Insert data with a foreach loop.
+   These values could be from a read of another table or from variables
+   set on the command line like
+*/
+\p Inserting some data int our new table (you should see 3 row update messages)
+* foreach VALUE (12 22 24 15)
+    * if (*VALUE &gt; 23)
+        \p Skipping *{VALUE} because it is greater than 23
+        * continue
+        \p YOU WILL NEVER SEE THIS LINE, because we just 'continued'.
+    * end if
+    INSERT INTO *{MYTABLE} VALUES (*{VALUE}, 'String of *{VALUE}');
+* end foreach
+\p
+
+* themax ~
+/* Can put Special Commands and comments between "* VARNAME ~" and the target 
+   SQL statement. */
+\p We're saving the max value for later.  You'll still see query output here:
+SELECT MAX(i) FROM *{MYTABLE};
+
+/* This is usually unnecessary because if the SELECT failed, retval would
+   be undefined and the following print statement would make SqlTool exit with
+   a failure status */
+* if (! *themax)
+    \p Failed to get the max value.
+    /* It's possible that the query succeeded but themax is "0".
+       You can check for that if you need to. */
+    * break
+    \p YOU WILL NEVER SEE THIS LINE, because we just 'broke'.
+* end if
+
+\p
+\p ##############################################################
+\p The results of our work:
+SELECT * FROM *{MYTABLE};
+\p MAX value is *{themax}
+
+\p
+\p Everything worked.
+</pre>
+</div>
+</div>
+<br class="example-break">
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_chunk-sect"></a>Chunking</h2>
+</div>
+</div>
+</div>
+<p>
+            We hereby call the ability to transmit multiple SQL commands to
+            the database in one transmission <span class="emphasis"><em>chunking</em></span>.
+            Normally it's best to send SQL statements to the database
+            one-at-a-time.
+            That way, the database can give you or your program feedback about
+            each statement.
+            But there are situations where it is more important to transmit
+            multiple-statements-at-a-time than to get feedback for each
+            statement individually.
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B2C"></a>Why?</h3>
+</div>
+</div>
+</div>
+<p>
+                The first general reason to chunk SQL commands is performance.
+                For standalone databases, the most common performance
+                bottleneck is network latency.
+                Chunking SQL commands can dramatically reduce network traffic.
+            </p>
+<p>
+              The second reason is that there are a couple SQL commands which
+              require the terminating ";" to be sent to the database engine.
+              For simplicity and efficiency, it's usually better for general
+              JDBC clients like SqlTool to strip off the final delimiter.
+              Raw commands retains everything that the user types.
+            </p>
+<p>
+                The third general reason to chunk SQL commands is if your
+                database requires you to send multiple commands in one
+                transmission.
+                This is usually the case with the following types of commands:
+                <div class="itemizedlist">
+<ul type="disc">
+<li>
+                        Nested SQL commands, like the nested CREATE SCHEMA
+                        variant, and most stored procedure, function, and
+                        trigger definitions.
+                    </li>
+<li>
+                        Commands containing non-quoted programming language to
+                        be interpreted by the database engine.
+                        Definitions of stored procedures, function, and triggers
+                        often contain code like this.
+                    </li>
+</ul>
+</div>
+            
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10B3D"></a>How?</h3>
+</div>
+</div>
+</div>
+<p>
+                Use raw mode.
+                Go to the
+                <a class="link" href="#sqltool_raw-sect" title="Raw Mode">Raw Mode</a> section
+                to see how.
+                You can enter any text at all, exactly how you want it to
+                be sent to the database engine.
+                Therefore, in addition to chunking SQL commands, you can
+                give commands for non-SQL extensions to the database.
+                For example, you could enter JavaScript code to be used
+                in a stored procedure.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_raw-sect"></a>Raw Mode</h2>
+</div>
+</div>
+</div>
+<p>
+            You begin raw mode by issuing the Special Command "\.".
+            You can then enter as much text in any format you want.
+            When you are finished, enter a line consisting of only ".;"
+            to store the input to the edit buffer and send it to the
+            database server for execution.
+        </p>
+<p>
+            This paragraph applies only to interactive usage.
+            Interactive users may may end the raw input with ":."
+            instead of ".;".
+            This will just save the input to the edit buffer so that you can
+            edit it and send it to the database manually.
+            You can look at the edit buffer with the ":b" Buffer Command.
+            You would normally use the command ":;" to
+            send the buffer to the database after you are satisfied with it.
+            You'll notice that your prompt will be the "raw" prompt
+            between entering "\." and terminating the raw input with ".;"
+            or ":.".
+        </p>
+<p>
+            Just by running commands beginning with
+            <code class="literal">BEGIN</code>, <code class="literal">DECLARE</code>,
+            <code class="literal">CREATE function</code>,
+            or <code class="literal">CREATE procedure</code>, your SqlTool session will
+            automatically be changed to Raw mode, exactly as if you had entered
+            "\.".
+            That's because these commands are universally used to define
+            stored procedures or functions, and these commands require raw mode
+            (as explained in the previous section).
+        </p>
+<p>
+          
+<div class="example">
+<a name="N10B5F"></a>
+<p class="title">
+<b>Example&nbsp;1.7.&nbsp;Interactive Raw Mode example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    sql&gt; \.
+    Enter RAW SQL.  No \, :, * commands.
+    End with a line containing only ".;" to send to database,
+    or ":." to store to edit buffer for editing or saving.
+    -----------------------------------------------------------
+    raw&gt; line one;
+    raw&gt; line two;
+    raw&gt; line three;
+    raw&gt; :.
+    Raw SQL chunk moved into buffer.  Run ":;" to execute the chunk.
+    sql&gt; :;
+    Executing command from buffer:
+    line one;
+    line two;
+    line three;
+
+    SQL Error at 'stdin' line 13:
+    "line one;
+    line two;
+    line three;"
+    Unexpected token: LINE in statement [line]
+    sql&gt;</pre>
+</div>
+</div>
+<br class="example-break">
+            The error message "Unexpected token: LINE in statement [line]"
+            comes from the database engine, not SqlTool.
+            All three lines were transmitted to the database engine.
+        </p>
+<p>
+            Edit Buffer Commands are not available when running SqlTool
+            non-interactively.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_embedded-langs-sect"></a>SQL/PSM, SQL/JRT, and PL/SQL</h2>
+</div>
+</div>
+</div>
+<p>
+          This section covers database-engine-embedded languages, which are
+          often used in the definition of stored procedures, stored functions,
+          and triggers.
+          <code class="literal">SQL/PSM</code>, <code class="literal">SQL/JRT</code>,
+          and <code class="literal">PL/SQ:</code> are well known examples.
+          We prefer <code class="literal">SQL/PSM</code> and <code class="literal">SQL/JRT</code>
+          because unlike the alternatives, they are based on open SQL
+          specifications.
+        </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            PL/SQL is <span class="bold"><strong>not</strong></span> the same as
+            PL.  PL is the procedural language of SqlFile and is
+            independent of your back-end database.
+            PL commands always begin with *.
+            PL/SQL is an Oracle-specific extension processed on the server side.
+            You can not intermix PL and any server-embedded language
+            (except for setting a PL variable to the output of execution),
+            because when you enter server language to SqlTool, that input is
+            not processed by SqlFile.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            Use <a class="link" href="#sqltool_raw-sect" title="Raw Mode">Raw Mode</a> to send
+            server-language code blocks to the database engine.
+            You do not need to enter the "\." command to enter raw mode.
+            Just begin a new SqlTool command line with "DECLARE",
+            "BEGIN", "CREATE FUNCTION", or "CREATE PROCEDURE",
+            and SqlTool will automatically put you into raw mode.
+            See the <a class="link" href="#sqltool_raw-sect" title="Raw Mode">Raw Mode</a>
+            section for details.
+        </p>
+<p>
+            The following sample SQL file resides at
+            <code class="filename"><a class="filename" href="#plsql.sql-link">sample/plsql.sql</a></code>
+            in your HyperSQL distribution
+            <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+            This script will only work with Oracle, only if you have
+            permission to create the table
+            "T1" in the default schema, and if that object does not
+            already exist.
+            <div class="example">
+<a name="N10B96"></a>
+<p class="title">
+<b>Example&nbsp;1.8.&nbsp;PL/SQL Example</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">/*
+ * $Id: plsql.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * This example is copied from the "Simple Programs in PL/SQL"
+ * example by Yu-May Chang, Jeff Ullman, Prof. Jennifer Widom at
+ * the Standord University Database Group's page
+ * http://www-db.stanford.edu/~ullman/fcdb/oracle/or-plsql.html .
+ * I have only removed some blank lines (in case somebody wants to
+ * copy this code interactively-- because you can't use blank
+ * lines inside of SQL commands in non-raw mode SqlTool when running
+ * it interactively); and, at the bottom I have  replaced the
+ * client-specific, non-standard command "run;" with SqlTool's
+ * corresponding command ".;" and added a plain SQL SELECT command
+ * to show whether the PL/SQL code worked.  - Blaine
+ */
+
+CREATE TABLE T1(
+    e INTEGER,
+    f INTEGER
+);
+
+DELETE FROM T1;
+
+INSERT INTO T1 VALUES(1, 3);
+
+INSERT INTO T1 VALUES(2, 4);
+
+/* Above is plain SQL; below is the PL/SQL program. */
+DECLARE
+
+    a NUMBER;
+
+    b NUMBER;
+
+BEGIN
+
+    SELECT e,f INTO a,b FROM T1 WHERE e&gt;1;
+
+    INSERT INTO T1 VALUES(b,a);
+
+END;
+
+.;
+/** The statement on the previous line, ".;" is SqlTool specific.
+ *  This command says to save the input up to this point to the
+ *  edit buffer and send it to the database server for execution.
+ *  I added the SELECT statement below to give imm
+ */
+
+/* This should show 3 rows, one containing values 4 and 2 (in this order)...*/
+SELECT * FROM t1;
+</pre>
+</div>
+</div>
+<br class="example-break">
+            Note that, inside of raw mode, you can use any kind of formatting
+            that your database engine needs or permits:  Whatever you enter--
+            blank lines, comments,
+            everything-- will be transmitted to the database engine.
+        </p>
+<p>
+          This file resides at
+          <code class="filename"><a class="filename" href="#sqljrt.sql-link">
+            testrun/sqltool/sqljrt.sql</a></code>
+          
+<div class="example">
+<a name="N10BA2"></a>
+<p class="title">
+<b>Example&nbsp;1.9.&nbsp;SQL/JRT Example</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">/*
+ * $Id: sqljrt.sql 3353 2009-12-15 19:52:13Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create function dehex(VARCHAR(80), INTEGER)
+    returns INTEGER
+    no sql
+    language java
+    external name 'CLASSPATH:java.lang.Integer.valueOf'
+.;
+
+CALL dehex('12', 16);
+*if (*? != 18)
+    \q SQL/JRT function failed
+*end if
+</pre>
+</div>
+</div>
+<br class="example-break">
+          This file resides at
+          <code class="filename"><a class="filename" href="#sqlpsm.sql-link">
+            testrun/sqltool/sqlpsm.sql</a></code>
+          
+<div class="example">
+<a name="N10BAC"></a>
+<p class="title">
+<b>Example&nbsp;1.10.&nbsp;SQL/PSM Example</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">/*
+ * $Id: sqlpsm.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create table customers(
+    id INTEGER default 0, firstname VARCHAR(50), lastname VARCHAR(50),
+    entrytime TIMESTAMP);
+
+create procedure new_customer(firstname varchar(50), lastname varchar(50))
+    modifies sql data
+    insert into customers values (
+        default, firstname, lastname, current_timestamp)
+.;
+
+SELECT count(*) FROM customers;
+*if (*? != 0)
+    \q SQL/PSM preparation failed
+*end if
+
+CALL new_customer('blaine', 'simpson');
+
+SELECT count(*) FROM customers;
+*if (*? != 1)
+    \q SQL/PSM procedure failed
+*end if
+</pre>
+</div>
+</div>
+<br class="example-break">
+        
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_dsv-sect"></a>Delimiter-Separated-Value Imports and Exports</h2>
+</div>
+</div>
+</div>
+<p>
+          SqlTool's DSV functionality encompasses what many users will
+          recognize as CSV export, as well as portable backup or transfer of
+          data.
+          Those familiar with Oracle's SQL*Loader will recognize the extreme
+          usefulness of the feature set.
+          Besides database- and platform-independent data backups, exports can
+          be used to deploy data sets with applications, to transfer data
+          among multiple database instances (even drastically different
+          database instances such as SQL Server and HyperSQL), and to properly
+          change control data sets with a content management system such as a
+          collaboration server or Subversion.
+          To jump way ahead for a moment to whet your appetite, here is a
+          sample <span class="emphasis"><em>import reject report</em></span> which will can be
+          generated automatically for you upon import just by setting the PL
+          variable <code class="varname">*DSV_REJECT_REPORT</code> (to the desired
+          destination HTML file name).
+          <div class="mediaobject" align="center">
+<img src="rejreport-sample.png" align="middle"><div class="caption">
+<p>A DSV Import reject report</p>
+</div>
+</div>
+          If you wish to, you can review the reject report before deciding
+          whether to commit or roll back the inserts.
+        </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+            This feature is independent of HyperSQL Text Tables.
+            (See the Text Tables chapter of the
+              <a class="link" href="http://hsqldb.org/doc/2.0/guide/index.html" target="_top">
+                HyperSQL User Guide</a> for details about them).
+            a server-side feature of HyperSQL.
+            It makes no difference to SqlTool whether the source or target
+            table of your export/import is a memory, cache, or text table.
+            Indeed, like all features of SqlTool, it works fine with other
+            JDBC databases.
+            It works great, for example to migrate data from a table
+            of one type to a table of another type, or to another schema,
+            or to another database instance, or to another database system.
+        </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+            This feature is what most business people call "CSV", but
+            these files are more accurately called <span class="emphasis"><em>Delimiter
+            Separated Value files</em></span> because the delimiter is
+            usually not a comma, and, more importantly, we purposefully
+            choose an effective delimiter instead of the CSV method of
+            using a delimiter which works in some cases and then use
+            quotes and back-slashes to escape occurrence of the delimiter
+            in the actual data.
+            Just by choosing a delimiter which never needs escaping, we
+            eliminate the whole mess, and the data in our files always
+            looks just like the corresponding data in the database.
+            To make this CSV / Delimiter-separated-value dintinction clear,
+            I use the suffix ".dsv" for my data files.
+            This leads me to stipulate the abbreviation DSV for the
+            <span class="emphasis"><em>Delimiter Separated Value</em></span> feature of HyperSQL.
+        </p>
+<p>
+            Use the <code class="literal">\x</code> command to eXport a table to a
+            DSV file, and the <code class="literal">\m</code> command to iMport a
+            DSV file into a pre-existing table.
+        </p>
+<p>
+            The row and column delimiters may be any String (or even a
+            regular expression for import), not just a single character.
+            And just as the delimiter capability is more general than
+            traditional CSV delimiters, the export function is also more
+            general than just a table data exporter.
+            Besides the trivial generalization that you may specify a
+            view or other virtual table name in place of a table name,
+            you can alternatively export the output of any query which
+            produces normal text output.
+            A benefit to this approach is that it allows you to export only
+            some columns of a table, and to specify a WHERE clause to narrow
+            down the rows to be exported (or perform any other SQL
+            transformation, mapping, join, etc.).
+            One specific use for this would be to exclude columns of
+            binary data (which can be exported by other means, such as
+            a PL loop to store binary values to files with the \bd command).
+        </p>
+<p>
+            Note that the import command will not create a new table.
+            This is because of the impossibility of guessing appropriate
+            types and constraints based only on column names and a data
+            sampling (which is all that a DSV-importer has access to).
+            Therefore, if you wish to populate a new table, create the
+            table before running the import.
+            The import file does not need to have data for all columns of a
+            table.
+            The only required columns are those required by database
+            constraints (non-null, indexes, keys, etc.)
+            One specific reason to omit columns is if you want values of
+            some columns to be created automatically by column DEFAULT
+            settings, triggers, HyperSQL identity sequences, etc.
+            Another reason would be to skip binary columns.
+        </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10BE4"></a>Simple DSV exports and imports using default settings</h3>
+</div>
+</div>
+</div>
+<p>
+                Even if you need to change delimiters, table names, or file
+                names from the defaults, I suggest that you run one export
+                and import with default settings as a practice run.
+                A memory-only HyperSQL instance is ideal for test runs like this.
+            </p>
+<p>
+                This command exports the table <code class="literal">icf.projects</code>
+                to the file <code class="filename">projects.dsv</code> in the current
+                directory (where you invoked SqlTool from).
+                By default, the output file name will be the specified source
+                table name plus the extension <code class="literal">.dsv</code>.
+                <div class="example">
+<a name="N10BF4"></a>
+<p class="title">
+<b>Example&nbsp;1.11.&nbsp;DSV Export Example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    SET SCHEMA icf;
+    \x projects</pre>
+</div>
+</div>
+<br class="example-break">
+                We could also have run <code class="literal">\x icf.projects</code>
+                (which would have created a file named
+                <code class="filename">icf.projects.dsv</code>)
+                instead of changing the session schema.
+                In this example we have chosen to make the export file name
+                independent of the schema to facilitate importing it into
+                a different schema.
+            </p>
+<p>
+                Take a look at the output file.
+                Notice that the first line consists of column names, not
+                data.
+                This line is present because it will be needed if the file is
+                to used for a DSV import.
+                Notice the following characterstics about the export data.
+                The column delimiter is the pipe character "|".
+                The record delimiter is the default line delimiter character(s)
+                for your operating system.
+                The string used to represent database <code class="literal">NULL</code>s
+                is <code class="literal">[null]</code>.
+                See the next section for how to change these from their default
+                values.
+            </p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+                You can not DSV import Array values where any Array elements
+                contain commas, for example an Array of VARCHARs which contain
+                one or more commas.
+                There is no such limitation on DSV exports, which you can use
+                for purposes other than SqlTool importing, or you could use
+                a script to change the commas to some other character.
+            </p>
+</td>
+</tr>
+</table>
+</div>
+<p>
+                This command imports the data from the file
+                <code class="filename">projects.dsv</code> in the current
+                directory (where you invoked SqlTool from) into the table
+                <code class="literal">newschema.projects</code>.
+                By default, the output table name will be the input filename
+                after removing optional leading directory and trailing final
+                extension.
+                <div class="example">
+<a name="N10C13"></a>
+<p class="title">
+<b>Example&nbsp;1.12.&nbsp;DSV Import Example</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    SET SCHEMA newschema;
+    \m projects.dsv</pre>
+</div>
+</div>
+<br class="example-break">
+                If the DSV file was named with the target schema, you would
+                have skipped the <code class="literal">SET SCHEMA</code> command, like
+                <code class="literal">\m newschema.projects.dsv</code>.
+                In order to allow for more flexibility, the default input
+                input delimiters are not exactly the same as the output
+                delimiters.
+                The input delimiters are regular expressions.
+                The input column delimiter happens to be the regular expression
+                corresponding exatly to "|"; but the input record delimiter
+                matches UNIX, Windows, Mac, and HTTP line breaks.
+            </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h3 class="title">
+<a name="N10C1F"></a>Specifying queries and options</h3>
+</div>
+</div>
+</div>
+<p>
+                For a hands on example of a DSM import which generates
+                an import report and uses some other options, change to
+                directory <code class="filename">HSQLDB/sample</code> and play
+                with the working script
+                <code class="filename"><a class="filename" href="#dsv-sample.sql-link">
+                  dsv-sample.sql</a></code>
+                <sup>[<a href="#ftn.samplelocFn" class="footnoteref">1</a>]</sup>.
+                You can execute it like
+                <div class="informalexample">
+<pre class="screen">    java -jar ../lib/sqltool.jar mem dsv-sample.sql</pre>
+</div>
+                (assuming that you are using the supplied
+                <code class="filename">sqltool.rc</code> file or have have urlid
+                <code class="literal">mem</code> set up).
+            </p>
+<p>
+                The header line in the DSV file is required at this time.
+                (If there is user demand, it can be made optional for
+                exporting, but it will remain required for importing).
+            </p>
+<p>
+                Your export will fail if the output column or record delimiter,
+                or the null representation value occurs in the data being
+                exported.
+                You change these values by setting the PL variables
+                <code class="varname">*DSV_COL_DELIM</code>,
+                <code class="varname">*DSV_ROW_DELIM</code>,
+                <code class="varname">*DSV_NULL_REP</code>.
+                Notice that the asterisk is part of the variable names, to
+                indicate that these variables are used by SqlTool internally.
+                When specifying delimiters, you can use the escape seqpences
+                \n, \r, \f, \t, \\, and decimal, octal or hex specifications
+                like \20, \020, \0x20.
+                For example, to change the column delimiter to the tab character,
+                you would give the command
+                <div class="informalexample">
+<pre class="screen">    * *DSV_COL_DELIM = \t</pre>
+</div>
+            
+</p>
+<p>
+                The input (\m) delimiter values,
+                <code class="varname">*DSV_COL_SPLITTER</code> and
+                <code class="varname">*DSV_ROW_SPLITTER</code>, are set using normal
+                Perl/Java regexp syntax.
+                There are escapes for specifying special characters, and
+                anything else you would need.
+                Input vs. output row and column delimiters are easily
+                distinguished by containing "SPLITTER" for splitting input
+                (\m) files; or "DELIM" for the delimiters that we will write
+                (\x) among the data.
+            </p>
+<p>
+                For imports, you must always specify the source DSV file path.
+                If you want to <span class="emphasis"><em>export</em></span> to a different file
+                than one in the current directory named according to the source
+                table, set the PL variable <code class="varname">*DSV_TARGET_FILE</code>,
+                like
+                <div class="informalexample">
+<pre class="screen">    * *DSV_TARGET_FILE = /tmp/dtbl.dsv</pre>
+</div>
+            
+</p>
+<p>
+                For exports, you must always specify the source table name
+                or query.
+                If you want to <span class="emphasis"><em>import</em></span> to a table other
+                than that derived from
+                the input DSV file name, set the PL variable
+                <code class="varname">*DSV_TARGET_TABLE</code>.
+                The table name may contain a schema name prefix.
+            </p>
+<p>
+                You don't need to import all of the columns in a data file.
+                To designate the fields to be skipped, iether set the PL
+                PL variable <code class="varname">*DSV_SKIP_COLUMNS</code>, or replace
+                the column names in the header line to "-" (hyphen).
+                The value of <code class="varname">*DSV_SKIP_COLUMNS</code> is
+                case-insensitive, and multiple column names are separated with
+                white space and/or commas.
+            </p>
+<p>
+                You can specify a query instead of a tablename with the
+                \x command in order to filter or transform data from a table
+                or view, or to export the output of a join, etc.
+                You must set the PL variable <code class="varname">*DSV_TARGET_FILE</code>,
+                as explained above (since there is no table name from which to
+                automatically map a file name).
+                <div class="example">
+<a name="N10C72"></a>
+<p class="title">
+<b>Example&nbsp;1.13.&nbsp;DSV Export of an Arbitrary SELECT Statement</b>
+</p>
+<div class="example-contents">
+<pre class="screen">    * *DSV_TARGET_FILE = outfile.txt
+    \x SELECT entrydate, 2 * aval "Double aval", modtime FROM bs.dtbl</pre>
+</div>
+</div>
+<br class="example-break">
+                Note that I specified the column label alias "Double aval"
+                so that the label for that column in the DSV file header will
+                not be blank.
+            </p>
+<p>
+                By default, imports will abort as soon as a error is
+                encountered during parsing the file or inserting data.
+                If you invoke SqlTool with a SQL script on the command line,
+                the failure will cause SqlTool to roll back and exit.
+                If run interactively, you can decide whether to commit or
+                roll back the rows that inserted before the failure.
+                You can modify this behavior with the \a and \c settings.
+            </p>
+<p>
+                If you set either a reject dsv file or a reject report file,
+                then failures during imports will be reported but will not
+                cause the import to abort.
+                When run in this way, SqlTool will give you a report at
+                the end about how many records were skipped, rejected, and
+                successfully inserted.
+                The reject dsv file is just a dsv file with exact copies of
+                the dsv records that failed to insert.
+                The reject report file is a HTML report which lists, for
+                every rejected record, why that record was rejected.
+                <code class="literal">\m?</code> will show you that the required PL
+                variables for this functionality are
+                <code class="varname">*DSV_REJECT_FILE</code>
+                and <code class="varname">*DSV_REJECT_REPORT</code>.
+                In both cases, you set the variable value to the path of the
+                file which SqlTool will create.
+            </p>
+<p>
+                To allow for user-friendly entry of headers, we require
+                that tables for DSV import/exports use standard column names.
+                I.e., no column names that require quoting.
+                The DSV import and export parsers are very smart and
+                user-friendly.
+                The data types of columns are checked so that the parser can
+                make safe assumptions about white space and blank entries in
+                the data.
+                If a column is a JDBC Boolean type, for example, then we
+                know that a field value of "  True " obviously means "True",
+                and that a field value of "" obviously means null.
+                Since we require vanilla style column names, we allow
+                white space anywhere in the header column.
+                We allow blank lines anywhere (where "lines" are delimited
+                by *DSV_ROW_DELIM).
+                By default, commented lines are ignored, and the comment
+                character can be changed from its default value.
+            </p>
+<p>
+                Run the command "\x?" or "\m?" to see the several system PL
+                variables which you can set to adjust reject file behavior,
+                commenting behavior, and other DSV features.
+            </p>
+<p>
+                You can also define some settings right in the DSV file,
+                and you can even specify multiple header lines in a single
+                DSV file.
+                I use this last feature to import data from one data set
+                into multple tables that are joined.
+                Since I don't have any more time to dedicate to explaining
+                all of these features, I'll give you some examples from
+                working DSV files and let you take it from there.
+        <div class="example">
+<a name="N10C8B"></a>
+<p class="title">
+<b>Example&nbsp;1.14.&nbsp;Sample DSV headerswitch settings</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">    # RCS keyword was here.
+
+    headerswitch{
+    itemdef:name|-|-|hardness|breakdc|-
+    simpleitemdef:itemdef_name|maxvalue|weight|-|-|maxhp
+    }</pre>
+</div>
+</div>
+<br class="example-break">
+            I'll just note that the prefixes for the header rows must be of
+            format target-table-name + :.
+            You can use * for target-table-name here, for the obvious purpose.
+        <div class="example">
+<a name="N10C91"></a>
+<p class="title">
+<b>Example&nbsp;1.15.&nbsp;DSV targettable setting</b>
+</p>
+<div class="example-contents">
+<pre class="programlisting">    targettable=t</pre>
+</div>
+</div>
+<br class="example-break">
+                This last example is from the SqlTool unit test file
+                <code class="filename">dsv-trimming.dsv</code>.
+                These special commands must be at the top of the file
+                (before any normal data or header lines).
+            </p>
+<p>
+                There is also the <code class="varname">*DSV_CONST_COLS</code> setting,
+                which you can use to automatically write static, constant
+                values to the specified columns of all inserted rows.
+            </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="sqltool_unittest-sect"></a>Unit Testing SqlTool</h2>
+</div>
+</div>
+</div>
+<p>
+          The SqlTool unit tests reside at testrun/sqltool in the
+          HyperSQL source code repository.
+          Just run the <code class="filename">runtests.bash</code> script from
+          that directory to execute all of the tests.
+          As you can see, the test runner, unfortunately, requires a Bash
+          shell at this time.
+          Read the file <code class="filename">README.txt</code> to find out all
+          about it, including everything you'd need to know to test your
+          own scripts or to add more unit test scripts for SqlTool.
+        </p>
+</div>
+<div class="footnotes">
+<br>
+<hr align="left" width="100">
+<div class="footnote">
+<p>
+<sup>[<a href="#samplelocFn" name="ftn.samplelocFn" class="simpara">1</a>] </sup>
+            To reduce the time I will need to spend maintaining this document,
+            in this chapter I am giving the path to the
+            <code class="filename">sample</code> directory as it is in HyperSQL 2.0.x
+            distributions, namely, <code class="filename">HSQLDB_HOME/sample</code>.
+            Users of HSQLDB before 2.0.x should translate these sample
+            directory paths
+            to use <code class="filename">HSQLDB_HOME/src/org/hsqldb/sample/...</code>.
+            </p>
+</div>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="test-utility-chapt"></a>Chapter&nbsp;2.&nbsp;Hsqldb Test Utility</h2>
+</div>
+</div>
+</div>
+<p>The <code class="classname">org.hsqldb.test</code> package contains a number
+    of tests for various functions of the database engine. Among these, the
+    <code class="classname">TestUtil</code> class performs the tests that are based on
+    scripts. To run the tests, you should compile the
+    <code class="filename">hsqldbtest.jar</code> target with Ant and JUnit.</p>
+<p>The <code class="classname">TestUtil</code> class should be run in the
+    /testrun/hsqldb directory of the distributed files. It then runs the set
+    of TestSelf*.txt files in the directory. To start the application in
+    Windows, change to the directory and type:</p>
+<pre class="screen"> java org.hsqldb.test.TestUtil</pre>
+<p>All files in the working directory with names matching TestSelf*.txt
+    are processed in alphabetical order.</p>
+<p>You can add your own scripts to test different series of SQL
+    queries. The format of the TestSelf*.txt file is simple text, with some
+    indentation and prefixes in the form of Java-style comments. The prefixes
+    indicate what the expected result should be.</p>
+<p>The class <code class="classname">org.hsqldb.test.TestScriptRunner</code> is
+    a more general program which you can use to test any script files which
+    you specify (with scripts of the same exact format as described below).
+    For example, <pre class="screen">java org.hsqldb.test.TestScriptRunner --urlid=mem script1.tsql script2.sql</pre>
+    You must have the HSQLDB classes, including the util and test classes, in
+    your <code class="varname">CLASSPATH</code>. The urlid must be set up in an RC file
+    as explained in the <a class="link" href="#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section. Use the
+    <code class="literal">rcfile=</code> argument to specify an RC file other than the
+    default of <code class="filename">testscriptrunner.rc</code> in the current
+    directory. To see all invocation possibilities, just run TestScriptRunner
+    with no arguments at all. TestScriptRunner can run tests sequentially (the
+    default) or in simultaneous asynchronous threads.</p>
+<div class="itemizedlist">
+<ul type="disc">
+<li>
+<p>Comment lines must start with -- and are ignored</p>
+</li>
+<li>
+<p>Lines starting with spaces are the continuation of the previous
+        line (for long SQL statements)</p>
+</li>
+<li>
+<p>SQL statements with no prefix are simply executed.</p>
+</li>
+<li>
+<p>
+<span class="emphasis"><em>The remaining items in this list exemplify use of the
+        available command line-prefixes.</em></span>
+</p>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*s*/ option stands for silent. It is used for
+          executing quries regardless of results. Used for preparation of
+          tests, not for actual tests.</p>
+<pre class="programlisting">/*s*/ Any SQL statement - errors are ignored</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*c&lt;rows&gt;*/ option is for SELECT queries and
+          asserts the number of rows in the result matches the given
+          count.</p>
+<pre class="programlisting">/*c&lt;rows&gt;*/ SQL statement returning count of &lt;rows&gt;</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*u*/ option is for queries that return an update
+          count, such as DELETE and UPDATE. It asserts the update count
+          matches.</p>
+<pre class="programlisting">/*u&lt;count&gt;*/ SQL statement returning an update count equal to &lt;count&gt;</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*e*/ option asserts that the given query results in an
+          erros. It is mainly used for testing the error detection
+          capabilities of the engine. The SQL State of the expected error can
+          be defined, for example /*e42578*/, to verify the returned error.
+          This option can be used with syntactically valid queries to assert a
+          certain state in the database. For example a CREATE TABLE can be
+          used to assert the table of the same name already exists.</p>
+<pre class="programlisting">/*e*/ SQL statement that should produce an error when executing</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The /*r....*/ option asserts the SELECT query returns a
+          single row containing the given set of field values.</p>
+<pre class="programlisting">/*r&lt;string1&gt;,&lt;string2&gt;*/ SQL statement returning a single row ResultSet equal to the specified value</pre>
+</div>
+</li>
+<li>
+<div class="informalexample">
+<p>The extended /*r...*/ option asserts the SELECT query
+          returns the given rows containing the given set of field
+          values.</p>
+<pre class="programlisting">/*r
+    &lt;string1&gt;,&lt;string2&gt;
+    &lt;string1&gt;,&lt;string2&gt;
+    &lt;string1&gt;,&lt;string2&gt;
+*/ SQL statement returning a multiple row ResultSet equal to the specified values</pre>
+</div>
+<p>(note that the result set lines are indented).</p>
+</li>
+<li>
+<p>The /*d*/ directive just displays the supplied
+        text.</p>
+<div class="informalexample">
+<pre class="programlisting">/*d*/ Some message</pre>
+</div>
+</li>
+<li>
+<p>The /*w MILLIS*/ directive causes the test to Wait for a
+        specified number of millisedonds.</p>
+<div class="informalexample">
+<pre class="programlisting">/*w 1000*/ Optional message</pre>
+</div>
+</li>
+<li>
+<p>The /*w ENFORCE_SEQUENCE WAITER_NAME*/ directive causes the
+        test to Wait for the specified <span class="emphasis"><em>Waiter</em></span>. A waiter
+        is just name that is used to associate a /*w*/ directive to its
+        corresponding /*p*/ directive. The ENFORCE_SEQUENCE argument must be
+        set to <code class="literal">true</code> or <code class="literal">false</code> to specify
+        whether to fail unless the /*p*/ command runs after the /*w*/ command
+        is waiting.</p>
+<div class="informalexample">
+<pre class="programlisting">/*w true script4*/ Optional message</pre>
+</div>
+</li>
+<li>
+<p>The /*p ENFORCE_SEQUENC WAITER_NAME*/ directive is the peer
+        directive to /*w*/, which causes a waiting thread to
+        Proceed.</p>
+<div class="informalexample">
+<pre class="programlisting">/*p true script4*/ Optional message</pre>
+</div>
+</li>
+<li>
+<p>All the options are lowercase letters. During development, an
+        uppercase can be used for a given test to exclude a test from the test
+        run. The utility will just report the test blocks that have been
+        excluded without running them. Once the code has been developed, the
+        option can be turned into lowercase to perform the actual test.</p>
+</li>
+</ul>
+</div>
+<p>See the TestSelf*.txt files in the /testrun/hsqldb/ directory for
+    actual examples.</p>
+<p>The String <code class="literal">${timestamp}</code> may be used in script
+    messages (like in /*d*/, /*w*/, /*p*/). It expands to the current time,
+    down to the second. For example, <div class="informalexample">
+<pre class="programlisting">/*d*/ It is now ${timestamp}</pre>
+</div>
+</p>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="dbm-chapt"></a>Chapter&nbsp;3.&nbsp;Database Manager</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+<div class="author">
+<h3 class="author">
+<span class="firstname">Blaine</span> <span class="surname">Simpson</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#dbm_intro-sect">Brief Introduction</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm_tree-sect">Auto tree-update</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm-autoconn-sect">Automatic Connection</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm_rcfile-sect">RC File</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm_wold-sect">Using the current DatabaseManagers with an older HSQLDB
+      distribution.</a></span>
+</dt>
+<dt>
+<span class="section"><a href="#dbm_applet-sect">DatabaseManagerSwing as an Applet</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_intro-sect"></a>Brief Introduction</h2>
+</div>
+</div>
+</div>
+<p>The Database Manager tool is a simple GUI database query tool with
+      a tree display of the tables. Both AWT and SWING versions of the tool
+      are available and work almost identically. The AWT version class name is
+      org.hsqldb.util.DatabaseManager; the SWING version,
+      org.hsqldb.util.DatabaseManagerSwing. The SWING version has more
+      refinements than the AWT version.</p>
+<p>The AWT version of the database manager can be deployed as an
+      applet in a browser. A demo HTML file with an embedded Database Manager
+      is included in the /demo directory.</p>
+<p>When the Database Manager is started, a dialogue allows you to
+      enter the JDBC driver, URL, user and password for the new connection. A
+      drop-down box, Type, offers preset values for JDBC driver and URL for
+      most popular database engines, including HSQLDB. Once you have selected
+      an item from this drop-down box, you should edit the URL to specify the
+      details of the database or any additional properties to pass. You should
+      also enter the username and password before clicking on the OK
+      button.</p>
+<p>The connection dialogue allows you to save the settings for the
+      connection you are about to make. You can then access the connection in
+      future sessions. To save a connection setting, enter a name in the
+      Setting Name box before clicking on the OK button. Next time the
+      connection dialogue is displayed, the drop-down box labeled Recent will
+      include the name for all the saved connection settings. When you select
+      a name, the individual settings are displayed in the appropriate
+      boxes.</p>
+<p>The small Clr button next to the drop-down box allows you to clear
+      all the saved settings. If you want to modify an existing setting, first
+      select it from the drop-down box then modify any of the text boxes
+      before making the connection. The modified values will be saved.</p>
+<p>Most SWING menu items have context-sensitive tool tip help text
+      which will appear if you hold the mouse cursor still over the desired
+      menu item. (Assuming that you don't turn Tooltips off under the
+      <span class="guimenu">Help</span> menu.</p>
+<p>The database object tree in the SWING version allows you to
+      right click on the name of a table or column and choose from common SQL
+      statements for the object, for example SELECT * FROM thistable ... If
+      you click on one of the given choices, the sample statement is copied to
+      the command window, where you can modify and complete it.</p>
+<p>The DatabaseManagers do work with HSQLDB servers serving
+      TLS-encrypted JDBC data. See the TLS section of the Listeners chapter of
+      the <a class="link" href="distro_baseurl_DEFAULTVAL/guide/index.html" target="_top">
+      HyperSQL User Guide</a>
+</p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Tip">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Tip]" src="../images/db/tip.png"></td><th align="left">Tip</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>If you are using DatabaseManagerSwing with Oracle, you will
+        want to make sure that <span class="guimenuitem">Show row counts</span> and
+        <span class="guimenuitem">Show row counts</span> are both off
+        <span class="emphasis"><em>before connecting to the database</em></span>. You may also
+        want to turn off Auto tree-update, as described in the next
+        section.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_tree-sect"></a>Auto tree-update</h2>
+</div>
+</div>
+</div>
+<p>By default, the object tree in the left panel is refreshed when
+      you execute DDL which may update those objects. If you are on a slow
+      network or performance-challenged PC, use the <span class="guimenu">view</span> /
+      <span class="guimenuitem">Auto-refresh tree</span> menu item to turn it off.
+      You will then need to use the
+      <span class="guimenu">view</span><span class="guimenuitem">Refresh tree</span> menu item
+      every time that you want to refresh the tree.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Auto-refresh tree does not automatically show all updates to
+        database objects, it only refreshes when you submit DDL which may
+        update database objects. (This behavior is a compromise between
+        utility and performance).</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm-autoconn-sect"></a>Automatic Connection</h2>
+</div>
+</div>
+</div>
+<p>You can use command-line switches to supply connection
+      information. If you use these switch(es), then the connection dialog
+      window will be skipped and a JDBC connection will be established
+      immediately. Assuming that the <code class="filename">hsqldb.jar</code> (or an
+      alternative jar) are in your <code class="varname">CLASSPATH</code>, this command
+      will list the available command-line options. <div class="informalexample">
+<pre class="screen">    java org.hsqldb.util.DatabaseManagerSwing --help</pre>
+</div>
+</p>
+<p>It's convenient to skip the connection dialog window if you
+      always work with the same database account.</p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Use of the --password switch is not secure. Everything typed
+        on command-lines is generally available to other users on the
+        computer. The problem is compounded if you use a network connection to
+        obtain your command line. The RC File section explains how you can set
+        up automatic connections without supplying a password on the command
+        line.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_rcfile-sect"></a>RC File</h2>
+</div>
+</div>
+</div>
+<p>You can skip the connection dialog window securely by putting
+      the connection information into an RC file and then using the
+      <code class="literal">--urlid</code> switch to DatabaseManager or
+      DatabaseManagerSwing. This strategy is great for adding launch menu
+      items and/or launch icons to your desktop. You can set up one icon for
+      each of the database accounts which you regularly use.</p>
+<p>The default location for the RC file is
+      <code class="filename">dbmanager.rc</code> in your home directory. The <a class="link" href="#sqltool_auth-sect" title="RC File Authentication Setup">RC File Authentication Setup</a> section
+      explains how to put the connection information into this text file. If
+      you also run <a class="link" href="#sqltool-chapt" title="Chapter&nbsp;1.&nbsp;SqlTool">SqlTool</a>, then you can share the RC file with
+      SqlTool by using a sym-link (if your operating system supports sym
+      links), or by using the <code class="literal">--rcfile</code> switch for either
+      SqlTool or DatabaseManagerSwing.</p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Warning">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Warning]" src="../images/db/warning.png"></td><th align="left">Warning</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>Use your operating system facilities to prevent others from
+        reading your RC file, since it contains passwords.</p>
+</td>
+</tr>
+</table>
+</div>
+<p>To set up launch items/icons, first experiment on your command
+      line to find exactly what command works. For example, <div class="informalexample">
+<pre class="screen">java -cp /path/to/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing --urlid mem</pre>
+</div> Then, use your window manager to add an item that
+      runs this command.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_wold-sect"></a>Using the current DatabaseManagers with an older HSQLDB
+      distribution.</h2>
+</div>
+</div>
+</div>
+<p>This procedure will allow users of a legacy version of HSQLDB
+      to use all of the new features of the DatabaseManagers. You will also
+      get the new version of the SqlTool! This procedure works for distros
+      going back to 1.7.3.3 at least, probably much farther.</p>
+<p>These instructions assume that you are capable of running an
+      Ant build. See the Building Appendix of the <a class="link" href="distro_baseurl_DEFAULTVAL/guide/index.html" target="_top"> HyperSQL User
+      Guide</a>.</p>
+<div class="procedure">
+<ol type="1">
+<li>
+<p>Download and extract a current HSQLDB distribution. If you
+          don't want to use the source code, documentation, etc., you can use
+          a temporary directory and remove it afterwards.</p>
+</li>
+<li>
+<p>Cd to the build directory under the root directory where
+          you extracted the distribution to.</p>
+</li>
+<li>
+<p>Run <code class="literal">ant hsqldbutil</code>.</p>
+</li>
+<li>
+<p>If you're going to wipe out the build directory, copy
+          <code class="filename">hsqldbutil.jar</code> to a safe location
+          first.</p>
+</li>
+<li>
+<p>For now on, whenver you are going to run DatabaseManager*,
+          make sure that you have this <code class="filename">hsqldbutil.jar</code> as
+          the first item in your <code class="varname">CLASSPATH</code>.</p>
+</li>
+</ol>
+</div>
+<p>Here's a UNIX example where somebody wants to use the new
+      DatabaseManagerSwing with their older HSQLDB database, as well as with
+      Postgresql and a local application. <div class="informalexample">
+<pre class="screen">CLASSPATH=/path/to/hsqldbutil.jar:/home/bob/myapp/classes:/usr/local/lib/pg.jdbc3.jar
+export CLASSPATH
+java org.hsqldb.util.DatabaseManagerSwing --urlid urlid</pre>
+</div>
+</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="dbm_applet-sect"></a>DatabaseManagerSwing as an Applet</h2>
+</div>
+</div>
+</div>
+<p>DatabaseManagerSwing is also an applet. You can use it in HTML,
+      JSPs, etc. Be aware that in Applet mode, actions to load or save local
+      files will be disabled, and attempts to access any server other than the
+      HTML-serving-host will fail.</p>
+<p>Since the Applet can not store or load locally saved preferences,
+      the only way to have persistent preference settings is by using Applet
+      parameters. <div class="variablelist">
+<p class="title">
+<b>DatabaseManagerSwing Applet Parameters</b>
+</p>
+<table border="0">
+<col valign="top" align="left">
+<tbody>
+<tr>
+<td>
+<p>
+<span class="term">jdbcUrl</span>
+</p>
+</td><td>URL of a data source to auto-connect to. String
+              value.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">jdbcDriver</span>
+</p>
+</td><td>URL of a data source to auto-connect to. String value.
+              Defaults to
+              <code class="classname">org.hsqldb.driver.JDBCDriver</code>.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">jdbcUser</span>
+</p>
+</td><td>User name for data source to auto-connect to. String
+              value.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">jdbcPassword</span>
+</p>
+</td><td>Password for data source to auto-connect to. String
+              value. Defaults to zero-length string.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">schemaFilter</span>
+</p>
+</td><td>Display only object from this schema in the object
+              navigator. String value.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">laf</span>
+</p>
+</td><td>Look-and-feel. String value.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">loadSampleData</span>
+</p>
+</td><td>Auto-load sample data. Boolean value. Defaults to
+              false.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">autoRefresh</span>
+</p>
+</td><td>Auto-refresh the object navigator when DDL
+              modifications detected in user SQL commands. Boolean value.
+              Defaults to true.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">showRowCounts</span>
+</p>
+</td><td>Show number of rows in each table in the object
+              navigator. Boolean value. Defaults to false.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">showSysTables</span>
+</p>
+</td><td>Show system tables in the object navigator. Boolean
+              value. Defaults to false.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">showSchemas</span>
+</p>
+</td><td>Show object names like schema.name in object navigator.
+              Boolean value. Defaults to true.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">resultGrid</span>
+</p>
+</td><td>Show query results in Gui grid (as opposed to in plain
+              text). Boolean value. Defaults to true.</td>
+</tr>
+<tr>
+<td>
+<p>
+<span class="term">showToolTips</span>
+</p>
+</td><td>Show help hover-text. Boolean value. Defaults to
+              true.</td>
+</tr>
+</tbody>
+</table>
+</div>
+</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title">
+<a name="transfer-tool-chapt"></a>Chapter&nbsp;4.&nbsp;Transfer Tool</h2>
+</div>
+<div>
+<div class="authorgroup">
+<div class="author">
+<h3 class="author">
+<span class="firstname">Fred</span> <span class="surname">Toussi</span>
+</h3>
+<div class="affiliation">
+<span class="orgname">The HSQL Development Group<br>
+</span>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="toc">
+<p>
+<b>Table of Contents</b>
+</p>
+<dl>
+<dt>
+<span class="section"><a href="#trantool_intro-sect">Brief Introduction</a></span>
+</dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h2 class="title" style="clear: both">
+<a name="trantool_intro-sect"></a>Brief Introduction</h2>
+</div>
+</div>
+</div>
+<p>Transfer Tool is a GUI program for transferring SQL schema and
+      data from one JDBC source to another. Source and destination can be
+      different database engines or different databases on the same
+      server.</p>
+<p>Transfer Tool works in two different modes. Direct transfer
+      maintains a connection to both source and destination and performs the
+      transfer. Dump and Restore mode is invoked once to transfer the data
+      from the source to a text file (Dump), then again to transfer the data
+      from the text file to the destination (Restore). With Dump and Restore,
+      it is possible to make any changes to database object definitions and
+      data prior to restoring it to the target.</p>
+<p>Dump and Restore modes can be set via the command line with -d
+      (--dump) or -r (--restore) options. Alternatively the Transfer Tool can
+      be started with any of the three modes from the Database Manager's Tools
+      menu.</p>
+<p>The connection dialogue allows you to save the settings for the
+      connection you are about to make. You can then access the connection in
+      future sessions. These settings are shared with those from the Database
+      Manager tool. See the appendix on Database Manager for details of the
+      connection dialogue box.</p>
+<p>From version 1.8.0 Transfer Tool is no longer part of the
+      <code class="filename">hsqldb.jar</code>. You can build the
+      <code class="filename">hsqldbutil.jar</code> using the Ant command of the same
+      name, to build a jar that includes Transfer Tool and the Database
+      Manager.</p>
+<p>When collecting meta-data, Transfer Tool performs SELECT * FROM
+      &lt;table&gt; queries on all the tables in the source database. This may
+      take a long time with some database engines. When the source database is
+      HSQLDB, this means memory should be available for the result sets
+      returned from the queries. Therefore, the memory allocation of the java
+      process in which Transfer Tool is executed may have to be high.</p>
+<p>The current version of Transfer is far from ideal, as it has not
+      been actively developed for several years. The program also lacks the
+      ability to create UNIQUE constraints and creates UNIQUE indexes instead.
+      However, some bugs have been fixed in the latest version and the program
+      can be used with most of the supported databases. The best way to use
+      the program is the DUMP and RESTORE modes, which allow you to manually
+      change the SQL statements in the dump file before restoring to a
+      database. A useful idea is to dump and restore the database definition
+      separately from the database data.</p>
+</div>
+</div>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div>
+<div>
+<h1 class="title">
+<a name="N10E8E"></a>HyperSQL File Links</h1>
+</div>
+<div>
+<h3 class="subtitle">
+<i>HyperSQL Files referred to in this Guide</i>
+</h3>
+</div>
+</div>
+</div>
+<p>
+    HyperSQL files referred to in the text may be retrieved from the
+    canonical HyperSQL documentation site, http://hsqldb.org/doc/2.0, or from the
+    same location you are reading this page from.
+  </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<table border="0" summary="Note">
+<tr>
+<td valign="top" align="center" rowspan="2" width="25"><img alt="[Note]" src="../images/db/note.png"></td><th align="left">Note</th>
+</tr>
+<tr>
+<td valign="top" align="left">
+<p>
+    If you are reading this document with a standalone PDF reader,
+    only the http://hsqldb.org/doc/2.0/... links will function.
+  </p>
+</td>
+</tr>
+</table>
+</div>
+<div class="itemizedlist">
+<p class="title">
+<b>
+      Pairs of local + http://hsqldb.org/doc/2.0 links for referenced files.
+    </b>
+</p>
+<ul type="disc">
+<li>
+<a name="sqltool.rc-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/sqltool.rc" target="_top">../verbatim/sample/sqltool.rc</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/sqltool.rc" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/sqltool.rc</a>
+      
+</p>
+</li>
+<li>
+<a name="sampledata.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/sampledata.sql" target="_top">../verbatim/sample/sampledata.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/sampledata.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/sampledata.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="sample.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/sample.sql" target="_top">../verbatim/sample/sample.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/sample.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/sample.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="pl.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/pl.sql" target="_top">../verbatim/sample/pl.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/pl.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/pl.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="plsql.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/plsql.sql" target="_top">../verbatim/sample/plsql.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/plsql.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/plsql.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="dsv-sample.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/sample/dsv-sample.sql" target="_top">../verbatim/sample/dsv-sample.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/sample/dsv-sample.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/sample/dsv-sample.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="sqljrt.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/testrun/sqltool/sqljrt.sql" target="_top">../verbatim/testrun/sqltool/sqljrt.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/testrun/sqltool/sqljrt.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/testrun/sqltool/sqljrt.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="sqlpsm.sql-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/testrun/sqltool/sqlpsm.sql" target="_top">../verbatim/testrun/sqltool/sqlpsm.sql</a>
+      
+</p>
+<p>
+        
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/testrun/sqltool/sqlpsm.sql" target="_top">http://hsqldb.org/doc/2.0/verbatim/testrun/sqltool/sqlpsm.sql</a>
+      
+</p>
+</li>
+<li>
+<a name="SqlFileEmbedder.java-link"></a>
+<p>
+        Local:
+        <a class="link" href="../verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java" target="_top">../verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java</a>
+      
+</p>
+<p>
+      
+<a class="link" href="http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java" target="_top">http://hsqldb.org/doc/2.0/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java</a>
+      
+</p>
+</li>
+<li>
+<a name="SqlTool.html-link"></a>
+<p>
+        Local:
+        <a class="link" href="../apidocs/org/hsqldb/cmdline/SqlFile.html" target="_top">../apidocs/org/hsqldb/cmdline/SqlFile.html</a>
+      
+</p>
+<p>
+      
+<a class="link" href="http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jcmdline/SqlFile.html" target="_top">http://hsqldb.org/doc/2.0/apidocs/org/hsqldb/jcmdline/SqlFile.html</a>
+      
+</p>
+</li>
+</ul>
+</div>
+</div>
+</div>
+<HR>
+<P class="svnrev">$Revision: 3539 $</P>
+</body>
+</html>
diff --git a/doc/util-guide/util-guide.pdf b/doc/util-guide/util-guide.pdf
new file mode 100644
index 0000000..45f7dac
--- /dev/null
+++ b/doc/util-guide/util-guide.pdf
Binary files differ
diff --git a/doc/verbatim/sample/acl.txt b/doc/verbatim/sample/acl.txt
new file mode 100644
index 0000000..d3d57f9
--- /dev/null
+++ b/doc/verbatim/sample/acl.txt
@@ -0,0 +1,31 @@
+# $Id: acl.txt 826 2009-01-17 05:04:52Z unsaved $

+

+# Sample HyperSQL Network Listener ACL file.

+# Specify "allow" and "deny" rules

+# For address specifications, individual addresses, host names, and

+# network addresses with /bit suffix are allowed, but read the caveat about

+# host names below, under the sample "localhost" rule.

+

+# Blank lines ignored.

+   # Lines with # as the first non-whitespace character are ignored.

+

+

+allow 2001:db8::/32

+# Allow this 32-bit ipv4 subnet

+

+allow localhost

+# You should use numerical addresses in ACL files, unless you are certain that

+# the name will always be known to your network address resolution system

+# (assume that you will lose Internet connectivity at some time).

+# With a default name resolution setup on UNIX, you are safe to use names

+# defined in your /etc/hosts file.

+

+deny 192.168.101.253

+# Deny a single IP address.

+# In our example, 192.168.101.0/24 is our local, organizational network.

+# 192.168.101.253 is the IP address of our Intern's PC.

+# The Intern does not have permission to access our databases directly.

+

+allow 192.168.101.0/24

+

+# Any ipv4 or ipv6 candidate address not matched above will be denied

diff --git a/doc/verbatim/sample/dsv-sample.sql b/doc/verbatim/sample/dsv-sample.sql
new file mode 100644
index 0000000..5a040ea
--- /dev/null
+++ b/doc/verbatim/sample/dsv-sample.sql
@@ -0,0 +1,37 @@
+/*
+ * $Id: dsv-sample.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * Imports delimiter-separated-values, and generates an output 
+ * reject .dsv file, and a reject report.
+ *
+ * To execute, set up a SqlTool database urlid (see User Guide if you don't
+ * know how to do that); then (from this directory) execute this script like
+ *
+ *    java ../lib/hsqldb.jar mem dsv-sample.sql
+ *
+ * (replace "mem" with your urlid).
+ */
+
+CREATE TABLE sampletable(i INT, d DATE NOT NULL, b BOOLEAN);
+
+/* If you dont' set *DSV_TARGET_TABLE, it defaults to the base name of the
+   .dsv file. */
+* *DSV_TARGET_TABLE = sampletable
+
+\p WARNING:  Some records will be skipped, and some others will be rejected.
+\p This is on purpose, so you can work with a reject report.
+\p
+
+/* By default, no reject files are written, and the import will abort upon
+ * the first error encountered.  If you set either of these settings, the
+ * import will continue to completion if at all possible. */
+* *DSV_REJECT_FILE = ${java.io.tmpdir}/sample-reject.dsv
+* *DSV_REJECT_REPORT = ${java.io.tmpdir}/sample-reject.html
+\m sample.dsv
+
+/* Enable this line if you want to display all successfully imported data:
+SELECT * FROM sampletable;
+*/
+
+\p
+\p See import reject report at '*{*DSV_REJECT_REPORT}'.
diff --git a/doc/verbatim/sample/hsqldb.cfg b/doc/verbatim/sample/hsqldb.cfg
new file mode 100644
index 0000000..37889e8
--- /dev/null
+++ b/doc/verbatim/sample/hsqldb.cfg
@@ -0,0 +1,173 @@
+# $Id: hsqldb.cfg 3583 2010-05-16 01:49:52Z unsaved $
+
+# Sample configuration file for HyperSQL Server Listener.
+# See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide.
+
+# N.b.!!!!  You must place this in the right location for your type of UNIX.
+# See the init script "hsqldb" to see where this must be placed and
+# what it should be renamed to.
+
+# This file is "sourced" by a Bourne shell, so use Bourne shell syntax.
+
+# This file WILL NOT WORK until you set (at least) the non-commented
+# variables to the appropriate values for your system.
+# Life will be easier if you avoid all filepaths with spaces or any other
+# funny characters.  Don't ask for support if you ignore this advice.
+
+# The URLIDS setting below is new and REQUIRED.  This setting replaces the
+# server.urlid.X settings which used to be needed in your Server's
+# properties file.
+
+# -- Blaine (blaine dot simpson at admc dot com)
+
+JAVA_EXECUTABLE=/usr/bin/java
+
+# Unless you copied the jar files from another system, this typically
+# resides at $HSQLDB_HOME/lib/sqltool.jar, where $HSQLDB_HOME is your HSQLDB
+# software base directory.
+# The file name may actually have a version label in it, like
+# sqltool-1.2.3.jar (in which case, you must specify the full name here).
+# A 'hsqldb.jar' file (with or without version label) must reside in the same
+# directory as the specified sqltool.jar file.
+SQLTOOL_JAR_PATH=/opt/hsqldb-2.0.0/hsqldb/lib/sqltool.jar
+# For the sample value above, there must also exist a file
+# /opt/hsqldb-2.0.0/hsqldb/lib/hsqldb*.jar.
+
+# Where the file "server.properties" or "webserver.properties" resides.
+SERVER_HOME=/opt/hsqldb-2.0.0/hsqldb/data
+
+# What UNIX user the server will run as.
+# (The shutdown client is always run as root or the invoker of the init script).
+# Runs as root by default, but you should take the time to set database file
+# ownerships to another user and set that user name here.
+HSQLDB_OWNER=hsqldb
+
+# The HSQLDB jar file specified in HSQLDB_JAR_PATH above will automatically
+# be in the class path.  This arg specifies additional classpath elements.
+# To embed your own application, add your jar file(s) or class base
+# directories here, and add your main class to the INVOC_ADDL_ARGS setting
+# below.  Another common use-case for adding to your class path is to make
+# classes available to the DB engines for SQL/JRT functions and procedures.
+#SERVER_ADDL_CLASSPATH=/usr/local/dist/currencybank.jar
+
+# For startup or shutdown failures, you can save a lot of debugging time by
+# temporarily adjusting down MAX_START_SECS and MAX_TERMINATE_SECS to a
+# little over what it should take for successful startup and shutdown on
+# your system.
+
+# We require all Server/WebServer instances to be accessible within 
+# $MAX_START_SECS from when the Server/WebServer is started.
+# Defaults to 60.
+# Raise this is you are running lots of DB instances or have a slow server.
+#MAX_START_SECS=200
+
+# Max time to allow for JVM to die after all HSQLDB instances stopped.
+# Defaults to 60.  Set high because the script will always continue as soon as
+# the process has stopped.  The importance of this setting is, how long until
+# a non-stopping-JVM-problem will be detected.
+#MAX_TERMINATE_SECS=0
+
+# NEW AND IMPORTANT!!!
+# As noted at the top of this file, this setting replaces the old property
+# settings server.urlid.X.
+# Simply list the URLIDs for all DB instances which your *Server starts.
+# Usually, these will exactly mirror the server.database.X settings in your
+# server.properties or webserver.properties file.
+# Each urlid listed here must be defined to a NETWORK url with Admin privileges
+# in the AUTH_FILE specified below.  (Network type because we use this for
+# inter-process communication)
+# Separate multiple values with white space.  NO OTHER SPECIAL CHARACTERS!
+# Make sure to quote the entire value if it contains white space separator(s).
+URLIDS='localhostdb1'
+
+# These are urlids # ** IN ADDITION TO URLIDS **, for instances which the init
+# script should stop but not start.
+# Most users will not need this setting.  If you need it, you'll know it.
+# Defaults to none (i.e., only URLIDS will be stopped).
+#SHUTDOWN_URLIDS='ondemand'
+
+# SqlTool authentication file used only for shutdown.
+# The default value will be sqltool.rc in root's home directory, since it is 
+# root who runs the init script.
+# (See the SqlTool chapter of the HyperSQL Utilities Guide if you don't
+# understand this).
+#AUTH_FILE=/home/blaine/sqltool.rc
+
+# Typical users will leave this unset and it will default to
+# org.hsqldb.server.Server.  If you need to run the HSQLDB WebServer class
+# instead, due to a firewall or routing impediment, set this to
+# org.hsqldb.server.WebServer, see the docs about running WebServr, and
+# set up a "webserver.properties" file instead of a "server.properties".
+# The JVM that is started can invoke many classes (see the following item
+# about that), but this is the server that is used (1) to check status,
+# (2) to shut down the JVM.
+#TARGET_CLASS=org.hsqldb.server.WebServer
+
+# This is where you may specify both command-line parameters to TARGET_CLASS,
+# plus any number of additional progams to run (along with their command-line
+# parameters).  The MainInvoker program is used to embed these multiple
+# static main invocations into a single JVM, so see the API spec for
+# org.hsqldb.util.MainInvoker if you want to learn more.
+# N.b. You should only use this setting to set HSQLDB Server or WebServer
+# parameters if you run multiple instances of this class, since you can use the
+# server/webserver.properties file for a single instance.
+# Every additional class (in addition to the TARGET_CLASS)
+# must be preceded with an empty string, so that MainInvoker will know
+# you are giving a class name.  MainInvoker will invoke the normal 
+# static main(String[]) method of each such class.  
+# By default, MainInvoker will just run TARGET_CLASS with no args.
+# Example that runs just the TARGET_CLASS with the specified arguments:
+#INVOC_ADDL_ARGS='-silent false'   #but use server.properties property instead!
+# Example that runs the TARGET_CLASS plus a WebServer:
+#INVOC_ADDL_ARGS='"" org.hsqldb.server.WebServer'
+# Note the empty string preceding the class name.
+# Example that starts TARGET_CLASS with an argument + a WebServer +
+# your own application with its args (i.e., the HSQLDB Servers are
+# "embedded" in your application).  (Set SERVER_ADDL_CLASSPATH too).:
+#INVOC_ADDL_ARGS='-silent false "" org.hsqldb.server.WebServer "" com.acme.Stone --env prod localhost'
+#   but use server.properties for -silent option instead!
+# Example to run a non-TLS server in same JVM with a TLS server.  In this
+# case, TARGET_CLASS is Server which will run both in TLS mode by virtue of 
+# setting the tls, keyStore, and keyStorePassword settings in
+# server*.properties, as described below; plus an "additional" Server with
+# overridden 'tls' and 'port' settings:
+#INVOC_ADDL_ARGS="'' org.hsqldb.server.Server --port 9002 --tls false"
+# This is an important use case.  If you run more than one Server instance,
+# you can specify different parameters for each here, even though only one
+# server.properties file is supported.
+# Note that you use nested quotes to group arguments and to specify the
+# empty-string delimiter.
+
+# The TLS_* settings have been obsoleted.
+# To get your server running with TLS, set
+# system.javax.net.ssl.keyStore=/path/to/your/private.keystore
+# system.javax.net.ssl.keyStorePassword=secretPassword
+# server.ssl=true
+# IN server.properties or webserver.properties, and
+# MAKE THE FILE OWNER-READ-ONLY!
+# See the TLS Encryption section of the HyperSQL User Guide, paying attention
+# to the security warning(s).
+# If you are running with a private server cert, then you will also need to 
+# set "truststore" in the your SqlTool config file (location is set by the
+# AUTH_FILE variable in this file, or it must be at the default location for 
+# HSQLDB_OWNER).
+
+# Any JVM args for the invocation of the JDBC client used to verify DB
+# instances and to shut them down (SqlToolSprayer).
+# Server-side System Properties should normally be set with system.*
+# settings in the server/webserver.properties file.
+# This example specifies the location of a private trust store for TLS 
+# encryption.
+# For multiple args, put quotes around entire value.
+# If you are starting just a TLS_encrypted Listener, you need to uncomment
+# this so the init scripts uses TLS to connect.
+# If using a private keystore, you also need to set "truststore" settings in
+# the sqltool.rc file.
+#CLIENT_JVMARGS=-Djavax.net.debug=ssl
+# This sample value displays useful debugging information about TLS/SSL.
+
+# Any JVM args for the server.
+# For multiple args, put quotes around entire value.
+#SERVER_JVMARGS=-Xmx512m
+# You can set the "javax.net.debug" property on the server side here, in the
+# same exact way as shown for the client side above.
diff --git a/doc/verbatim/sample/pl.sql b/doc/verbatim/sample/pl.sql
new file mode 100644
index 0000000..e616108
--- /dev/null
+++ b/doc/verbatim/sample/pl.sql
@@ -0,0 +1,87 @@
+/*
+    $Id: pl.sql 3353 2009-12-15 19:52:13Z unsaved $
+    SQL File to illustrate the use of SqlTool PL features.
+    Invoke like
+        java -jar .../hsqldb.jar .../pl.sql mem
+                                                         -- blaine
+*/
+
+* if (! *MYTABLE)
+    \p MYTABLE variable not set!
+    /* You could use \q to Quit SqlTool, but it's often better to just
+       break out of the current SQL file.
+       If people invoke your script from SqlTool interactively (with
+       \i yourscriptname.sql) any \q will kill their SqlTool session. */
+    \p Use arguments "--setvar=MYTABLE=mytablename" for SqlTool
+    * break
+* end if
+
+/* Turning on Continue-upon-errors so that we can check for errors ourselves.*/
+\c true
+
+\p
+\p Loading up a table named '*{MYTABLE}'...
+
+/* This sets the PL variable 'retval' to the return status of the following
+   SQL command */
+* retval ~
+CREATE TABLE *{MYTABLE} (
+    i int,
+    s varchar(20);
+);
+\p CREATE status is *{retval}
+\p
+
+/* Validate our return status.  In logical expressions, unset variables like
+   *unsetvar are equivalent to empty string, which is not equal to 0
+   (though both do evaluate to false on their own, i.e. (*retval) is false
+   and (0) is false */
+* if (*retval != 0)
+    \p Our CREATE TABLE command failed.
+    * break
+* end if
+
+/* Default Continue-on-error behavior is what you usually want */
+\c false
+\p
+
+/* Insert data with a foreach loop.
+   These values could be from a read of another table or from variables
+   set on the command line like
+*/
+\p Inserting some data int our new table (you should see 3 row update messages)
+* foreach VALUE (12 22 24 15)
+    * if (*VALUE > 23)
+        \p Skipping *{VALUE} because it is greater than 23
+        * continue
+        \p YOU WILL NEVER SEE THIS LINE, because we just 'continued'.
+    * end if
+    INSERT INTO *{MYTABLE} VALUES (*{VALUE}, 'String of *{VALUE}');
+* end foreach
+\p
+
+* themax ~
+/* Can put Special Commands and comments between "* VARNAME ~" and the target 
+   SQL statement. */
+\p We're saving the max value for later.  You'll still see query output here:
+SELECT MAX(i) FROM *{MYTABLE};
+
+/* This is usually unnecessary because if the SELECT failed, retval would
+   be undefined and the following print statement would make SqlTool exit with
+   a failure status */
+* if (! *themax)
+    \p Failed to get the max value.
+    /* It's possible that the query succeeded but themax is "0".
+       You can check for that if you need to. */
+    * break
+    \p YOU WILL NEVER SEE THIS LINE, because we just 'broke'.
+* end if
+
+\p
+\p ##############################################################
+\p The results of our work:
+SELECT * FROM *{MYTABLE};
+\p MAX value is *{themax}
+
+\p
+\p Everything worked.
diff --git a/doc/verbatim/sample/plsql.sql b/doc/verbatim/sample/plsql.sql
new file mode 100644
index 0000000..af08686
--- /dev/null
+++ b/doc/verbatim/sample/plsql.sql
@@ -0,0 +1,51 @@
+/*
+ * $Id: plsql.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * This example is copied from the "Simple Programs in PL/SQL"
+ * example by Yu-May Chang, Jeff Ullman, Prof. Jennifer Widom at
+ * the Standord University Database Group's page
+ * http://www-db.stanford.edu/~ullman/fcdb/oracle/or-plsql.html .
+ * I have only removed some blank lines (in case somebody wants to
+ * copy this code interactively-- because you can't use blank
+ * lines inside of SQL commands in non-raw mode SqlTool when running
+ * it interactively); and, at the bottom I have  replaced the
+ * client-specific, non-standard command "run;" with SqlTool's
+ * corresponding command ".;" and added a plain SQL SELECT command
+ * to show whether the PL/SQL code worked.  - Blaine
+ */
+
+CREATE TABLE T1(
+    e INTEGER,
+    f INTEGER
+);
+
+DELETE FROM T1;
+
+INSERT INTO T1 VALUES(1, 3);
+
+INSERT INTO T1 VALUES(2, 4);
+
+/* Above is plain SQL; below is the PL/SQL program. */
+DECLARE
+
+    a NUMBER;
+
+    b NUMBER;
+
+BEGIN
+
+    SELECT e,f INTO a,b FROM T1 WHERE e>1;
+
+    INSERT INTO T1 VALUES(b,a);
+
+END;
+
+.;
+/** The statement on the previous line, ".;" is SqlTool specific.
+ *  This command says to save the input up to this point to the
+ *  edit buffer and send it to the database server for execution.
+ *  I added the SELECT statement below to give imm
+ */
+
+/* This should show 3 rows, one containing values 4 and 2 (in this order)...*/
+SELECT * FROM t1;
diff --git a/doc/verbatim/sample/sample.sql b/doc/verbatim/sample/sample.sql
new file mode 100644
index 0000000..a6de8a5
--- /dev/null
+++ b/doc/verbatim/sample/sample.sql
@@ -0,0 +1,47 @@
+/*
+    $Id: sample.sql 3637 2010-06-07 00:59:13Z unsaved $
+    Exemplifies use of SqlTool.
+    PCTASK Table creation
+*/
+
+/* Ignore error for these two statements */
+\c true
+DROP TABLE pctasklist;
+DROP TABLE pctask;
+\c false
+
+\p Creating table pctask
+CREATE TABLE pctask (
+    id integer identity,
+    name varchar(40),
+    description varchar(256),
+    url varchar(80),
+    UNIQUE (name)
+);
+
+\p Creating table pctasklist
+CREATE TABLE pctasklist (
+    id integer identity,
+    host varchar(20) not null,
+    tasksequence int not null,
+    pctask integer,
+    assigndate timestamp default current_timestamp,
+    completedate timestamp,
+    show boolean default true,
+    FOREIGN KEY (pctask) REFERENCES pctask,
+    UNIQUE (host, tasksequence)
+);
+
+\p Granting privileges
+GRANT select ON pctask TO public;
+GRANT all ON pctask TO tomcat;
+GRANT select ON pctasklist TO public;
+GRANT all ON pctasklist TO tomcat;
+
+\p Inserting test records
+INSERT INTO pctask (name, description, url) VALUES (
+    'task one', 'Description for task 1', 'http://cnn.com');
+INSERT INTO pctasklist (host, tasksequence, pctask) VALUES (
+    'admc-masq', 101, (SELECT id FROM pctask WHERE name = 'task one'));
+
+commit;
diff --git a/doc/verbatim/sample/sampledata.sql b/doc/verbatim/sample/sampledata.sql
new file mode 100644
index 0000000..1c59ea8
--- /dev/null
+++ b/doc/verbatim/sample/sampledata.sql
@@ -0,0 +1,822 @@
+/*
+ *  $Id: sampledata.sql 3353 2009-12-15 19:52:13Z unsaved $
+ *
+ *  Creates and populates database objects with sample data.
+ *  This file was created by grabbing the commands made by creating
+ *  sample data with the DatabaseManager utility.
+ */
+
+
+DROP TABLE Item IF EXISTS;
+DROP TABLE Invoice IF EXISTS;
+DROP TABLE Product IF EXISTS;
+DROP TABLE Customer IF EXISTS;
+CREATE TABLE Customer(ID INTEGER PRIMARY KEY,FirstName VARCHAR(20),LastName VARCHAR(30),Street VARCHAR(50),City VARCHAR(25));
+CREATE TABLE Product(ID INTEGER PRIMARY KEY,Name VARCHAR(30),Price DECIMAL);
+CREATE TABLE Invoice(ID INTEGER PRIMARY KEY,CustomerID INTEGER,Total DECIMAL, FOREIGN KEY (CustomerId) REFERENCES Customer(ID) ON DELETE CASCADE);
+CREATE TABLE Item(InvoiceID INTEGER,Item INTEGER,ProductID INTEGER,Quantity INTEGER,Cost DECIMAL,PRIMARY KEY(InvoiceID,Item), FOREIGN KEY (InvoiceId) REFERENCES Invoice (ID) ON DELETE CASCADE, FOREIGN KEY (ProductId) REFERENCES Product(ID) ON DELETE CASCADE);
+INSERT INTO Customer VALUES(0,'Laura','Steel','429 Seventh Av.','Dallas');
+INSERT INTO Product VALUES(0,'Iron Iron',54);
+INSERT INTO Customer VALUES(1,'Susanne','King','366 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(1,'Chair Shoe',248);
+INSERT INTO Customer VALUES(2,'Anne','Miller','20 Upland Pl.','Lyon');
+INSERT INTO Product VALUES(2,'Telephone Clock',248);
+INSERT INTO Customer VALUES(3,'Michael','Clancy','542 Upland Pl.','San Francisco');
+INSERT INTO Product VALUES(3,'Chair Chair',254);
+INSERT INTO Customer VALUES(4,'Sylvia','Ringer','365 College Av.','Dallas');
+INSERT INTO Product VALUES(4,'Ice Tea Shoe',128);
+INSERT INTO Customer VALUES(5,'Laura','Miller','294 Seventh Av.','Paris');
+INSERT INTO Product VALUES(5,'Clock Clock',236);
+INSERT INTO Customer VALUES(6,'Laura','White','506 Upland Pl.','Palo Alto');
+INSERT INTO Product VALUES(6,'Ice Tea Chair',98);
+INSERT INTO Customer VALUES(7,'James','Peterson','231 Upland Pl.','San Francisco');
+INSERT INTO Product VALUES(7,'Telephone Shoe',84);
+INSERT INTO Customer VALUES(8,'Andrew','Miller','288 - 20th Ave.','Seattle');
+INSERT INTO Product VALUES(8,'Ice Tea Clock',226);
+INSERT INTO Customer VALUES(9,'James','Schneider','277 Seventh Av.','Berne');
+INSERT INTO Product VALUES(9,'Clock Telephone',172);
+INSERT INTO Customer VALUES(10,'Anne','Fuller','135 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(10,'Telephone Ice Tea',204);
+INSERT INTO Customer VALUES(11,'Julia','White','412 Upland Pl.','Chicago');
+INSERT INTO Product VALUES(11,'Telephone Iron',88);
+INSERT INTO Customer VALUES(12,'George','Ott','381 Upland Pl.','Palo Alto');
+INSERT INTO Product VALUES(12,'Clock Ice Tea',168);
+INSERT INTO Customer VALUES(13,'Laura','Ringer','38 College Av.','New York');
+INSERT INTO Product VALUES(13,'Telephone Clock',180);
+INSERT INTO Customer VALUES(14,'Bill','Karsen','53 College Av.','Oslo');
+INSERT INTO Product VALUES(14,'Telephone Iron',124);
+INSERT INTO Customer VALUES(15,'Bill','Clancy','319 Upland Pl.','Seattle');
+INSERT INTO Product VALUES(15,'Ice Tea Chair',94);
+INSERT INTO Customer VALUES(16,'John','Fuller','195 Seventh Av.','New York');
+INSERT INTO Product VALUES(16,'Ice Tea Shoe',194);
+INSERT INTO Customer VALUES(17,'Laura','Ott','443 Seventh Av.','Lyon');
+INSERT INTO Product VALUES(17,'Clock Ice Tea',220);
+INSERT INTO Customer VALUES(18,'Sylvia','Fuller','158 - 20th Ave.','Paris');
+INSERT INTO Product VALUES(18,'Chair Clock',172);
+INSERT INTO Customer VALUES(19,'Susanne','Heiniger','86 - 20th Ave.','Dallas');
+INSERT INTO Product VALUES(19,'Ice Tea Ice Tea',110);
+INSERT INTO Customer VALUES(20,'Janet','Schneider','309 - 20th Ave.','Oslo');
+INSERT INTO Product VALUES(20,'Ice Tea Telephone',200);
+INSERT INTO Customer VALUES(21,'Julia','Clancy','18 Seventh Av.','Seattle');
+INSERT INTO Product VALUES(21,'Chair Chair',114);
+INSERT INTO Customer VALUES(22,'Bill','Ott','250 - 20th Ave.','Berne');
+INSERT INTO Product VALUES(22,'Iron Iron',66);
+INSERT INTO Customer VALUES(23,'Julia','Heiniger','358 College Av.','Boston');
+INSERT INTO Product VALUES(23,'Shoe Chair',76);
+INSERT INTO Customer VALUES(24,'James','Sommer','333 Upland Pl.','Olten');
+INSERT INTO Product VALUES(24,'Chair Shoe',72);
+INSERT INTO Customer VALUES(25,'Sylvia','Steel','269 College Av.','Paris');
+INSERT INTO Product VALUES(25,'Shoe Shoe',162);
+INSERT INTO Customer VALUES(26,'James','Clancy','195 Upland Pl.','Oslo');
+INSERT INTO Product VALUES(26,'Shoe Shoe',252);
+INSERT INTO Customer VALUES(27,'Bob','Sommer','509 College Av.','Seattle');
+INSERT INTO Product VALUES(27,'Telephone Iron',230);
+INSERT INTO Customer VALUES(28,'Susanne','White','74 - 20th Ave.','Lyon');
+INSERT INTO Product VALUES(28,'Clock Iron',30);
+INSERT INTO Customer VALUES(29,'Andrew','Smith','254 College Av.','New York');
+INSERT INTO Product VALUES(29,'Chair Telephone',112);
+INSERT INTO Customer VALUES(30,'Bill','Sommer','362 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(30,'Shoe Iron',232);
+INSERT INTO Customer VALUES(31,'Bob','Ringer','371 College Av.','Olten');
+INSERT INTO Product VALUES(31,'Ice Tea Telephone',48);
+INSERT INTO Customer VALUES(32,'Michael','Ott','339 College Av.','Boston');
+INSERT INTO Product VALUES(32,'Clock Iron',190);
+INSERT INTO Customer VALUES(33,'Mary','King','491 College Av.','Oslo');
+INSERT INTO Product VALUES(33,'Iron Chair',182);
+INSERT INTO Customer VALUES(34,'Julia','May','33 Upland Pl.','Seattle');
+INSERT INTO Product VALUES(34,'Chair Iron',256);
+INSERT INTO Customer VALUES(35,'George','Karsen','412 College Av.','Chicago');
+INSERT INTO Product VALUES(35,'Telephone Shoe',76);
+INSERT INTO Customer VALUES(36,'John','Steel','276 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(36,'Ice Tea Iron',32);
+INSERT INTO Customer VALUES(37,'Michael','Clancy','19 Seventh Av.','Dallas');
+INSERT INTO Product VALUES(37,'Clock Shoe',94);
+INSERT INTO Customer VALUES(38,'Andrew','Heiniger','347 College Av.','Lyon');
+INSERT INTO Product VALUES(38,'Clock Ice Tea',216);
+INSERT INTO Customer VALUES(39,'Mary','Karsen','202 College Av.','Chicago');
+INSERT INTO Product VALUES(39,'Ice Tea Shoe',154);
+INSERT INTO Customer VALUES(40,'Susanne','Miller','440 - 20th Ave.','Dallas');
+INSERT INTO Product VALUES(40,'Shoe Clock',28);
+INSERT INTO Customer VALUES(41,'Bill','King','546 College Av.','New York');
+INSERT INTO Product VALUES(41,'Clock Ice Tea',206);
+INSERT INTO Customer VALUES(42,'Robert','Ott','503 Seventh Av.','Oslo');
+INSERT INTO Product VALUES(42,'Iron Chair',198);
+INSERT INTO Customer VALUES(43,'Susanne','Smith','2 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(43,'Telephone Clock',94);
+INSERT INTO Customer VALUES(44,'Sylvia','Ott','361 College Av.','New York');
+INSERT INTO Product VALUES(44,'Ice Tea Ice Tea',96);
+INSERT INTO Customer VALUES(45,'Janet','May','396 Seventh Av.','Oslo');
+INSERT INTO Product VALUES(45,'Iron Ice Tea',180);
+INSERT INTO Customer VALUES(46,'Andrew','May','172 Seventh Av.','New York');
+INSERT INTO Product VALUES(46,'Ice Tea Clock',62);
+INSERT INTO Customer VALUES(47,'Janet','Fuller','445 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(47,'Ice Tea Iron',178);
+INSERT INTO Customer VALUES(48,'Robert','White','549 Seventh Av.','San Francisco');
+INSERT INTO Product VALUES(48,'Clock Clock',210);
+INSERT INTO Customer VALUES(49,'George','Fuller','534 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(49,'Iron Iron',22);
+INSERT INTO Invoice VALUES(0,0,0.0);
+INSERT INTO Invoice VALUES(1,33,0.0);
+INSERT INTO Invoice VALUES(2,23,0.0);
+INSERT INTO Invoice VALUES(3,21,0.0);
+INSERT INTO Invoice VALUES(4,30,0.0);
+INSERT INTO Invoice VALUES(5,34,0.0);
+INSERT INTO Invoice VALUES(6,19,0.0);
+INSERT INTO Invoice VALUES(7,26,0.0);
+INSERT INTO Invoice VALUES(8,29,0.0);
+INSERT INTO Invoice VALUES(9,38,0.0);
+INSERT INTO Invoice VALUES(10,24,0.0);
+INSERT INTO Invoice VALUES(11,24,0.0);
+INSERT INTO Invoice VALUES(12,23,0.0);
+INSERT INTO Invoice VALUES(13,39,0.0);
+INSERT INTO Invoice VALUES(14,35,0.0);
+INSERT INTO Invoice VALUES(15,39,0.0);
+INSERT INTO Invoice VALUES(16,45,0.0);
+INSERT INTO Invoice VALUES(17,46,0.0);
+INSERT INTO Invoice VALUES(18,4,0.0);
+INSERT INTO Invoice VALUES(19,9,0.0);
+INSERT INTO Invoice VALUES(20,19,0.0);
+INSERT INTO Invoice VALUES(21,8,0.0);
+INSERT INTO Invoice VALUES(22,40,0.0);
+INSERT INTO Invoice VALUES(23,36,0.0);
+INSERT INTO Invoice VALUES(24,15,0.0);
+INSERT INTO Invoice VALUES(25,31,0.0);
+INSERT INTO Invoice VALUES(26,27,0.0);
+INSERT INTO Invoice VALUES(27,24,0.0);
+INSERT INTO Invoice VALUES(28,35,0.0);
+INSERT INTO Invoice VALUES(29,46,0.0);
+INSERT INTO Invoice VALUES(30,13,0.0);
+INSERT INTO Invoice VALUES(31,22,0.0);
+INSERT INTO Invoice VALUES(32,20,0.0);
+INSERT INTO Invoice VALUES(33,40,0.0);
+INSERT INTO Invoice VALUES(34,33,0.0);
+INSERT INTO Invoice VALUES(35,4,0.0);
+INSERT INTO Invoice VALUES(36,42,0.0);
+INSERT INTO Invoice VALUES(37,39,0.0);
+INSERT INTO Invoice VALUES(38,46,0.0);
+INSERT INTO Invoice VALUES(39,5,0.0);
+INSERT INTO Invoice VALUES(40,4,0.0);
+INSERT INTO Invoice VALUES(41,19,0.0);
+INSERT INTO Invoice VALUES(42,38,0.0);
+INSERT INTO Invoice VALUES(43,13,0.0);
+INSERT INTO Invoice VALUES(44,32,0.0);
+INSERT INTO Invoice VALUES(45,42,0.0);
+INSERT INTO Invoice VALUES(46,24,0.0);
+INSERT INTO Invoice VALUES(47,45,0.0);
+INSERT INTO Invoice VALUES(48,22,0.0);
+INSERT INTO Invoice VALUES(49,32,0.0);
+INSERT INTO Item VALUES(0,12,1,11,1.5);
+INSERT INTO Item VALUES(0,11,12,4,1.5);
+INSERT INTO Item VALUES(0,10,4,8,1.5);
+INSERT INTO Item VALUES(0,9,35,4,1.5);
+INSERT INTO Item VALUES(0,8,0,23,1.5);
+INSERT INTO Item VALUES(0,7,7,10,1.5);
+INSERT INTO Item VALUES(0,6,16,9,1.5);
+INSERT INTO Item VALUES(0,5,12,15,1.5);
+INSERT INTO Item VALUES(0,4,47,1,1.5);
+INSERT INTO Item VALUES(0,3,1,9,1.5);
+INSERT INTO Item VALUES(0,2,47,3,1.5);
+INSERT INTO Item VALUES(0,1,14,19,1.5);
+INSERT INTO Item VALUES(0,0,7,12,1.5);
+INSERT INTO Item VALUES(1,6,25,19,1.5);
+INSERT INTO Item VALUES(1,5,25,9,1.5);
+INSERT INTO Item VALUES(1,4,16,16,1.5);
+INSERT INTO Item VALUES(1,3,38,8,1.5);
+INSERT INTO Item VALUES(1,2,19,6,1.5);
+INSERT INTO Item VALUES(1,1,0,9,1.5);
+INSERT INTO Item VALUES(1,0,40,8,1.5);
+INSERT INTO Item VALUES(2,16,36,24,1.5);
+INSERT INTO Item VALUES(2,15,0,18,1.5);
+INSERT INTO Item VALUES(2,14,48,19,1.5);
+INSERT INTO Item VALUES(2,13,12,1,1.5);
+INSERT INTO Item VALUES(2,12,21,15,1.5);
+INSERT INTO Item VALUES(2,11,42,21,1.5);
+INSERT INTO Item VALUES(2,10,49,11,1.5);
+INSERT INTO Item VALUES(2,9,18,7,1.5);
+INSERT INTO Item VALUES(2,8,39,2,1.5);
+INSERT INTO Item VALUES(2,7,30,5,1.5);
+INSERT INTO Item VALUES(2,6,43,8,1.5);
+INSERT INTO Item VALUES(2,5,30,4,1.5);
+INSERT INTO Item VALUES(2,4,38,18,1.5);
+INSERT INTO Item VALUES(2,3,19,13,1.5);
+INSERT INTO Item VALUES(2,2,11,9,1.5);
+INSERT INTO Item VALUES(2,1,25,3,1.5);
+INSERT INTO Item VALUES(2,0,4,18,1.5);
+INSERT INTO Item VALUES(3,17,30,17,1.5);
+INSERT INTO Item VALUES(3,16,19,11,1.5);
+INSERT INTO Item VALUES(3,15,23,18,1.5);
+INSERT INTO Item VALUES(3,14,17,22,1.5);
+INSERT INTO Item VALUES(3,13,41,2,1.5);
+INSERT INTO Item VALUES(3,12,41,22,1.5);
+INSERT INTO Item VALUES(3,11,7,11,1.5);
+INSERT INTO Item VALUES(3,10,10,17,1.5);
+INSERT INTO Item VALUES(3,9,29,17,1.5);
+INSERT INTO Item VALUES(3,8,49,9,1.5);
+INSERT INTO Item VALUES(3,7,26,4,1.5);
+INSERT INTO Item VALUES(3,6,13,18,1.5);
+INSERT INTO Item VALUES(3,5,30,10,1.5);
+INSERT INTO Item VALUES(3,4,20,12,1.5);
+INSERT INTO Item VALUES(3,3,0,22,1.5);
+INSERT INTO Item VALUES(3,2,49,3,1.5);
+INSERT INTO Item VALUES(3,1,1,20,1.5);
+INSERT INTO Item VALUES(3,0,11,21,1.5);
+INSERT INTO Item VALUES(4,5,37,24,1.5);
+INSERT INTO Item VALUES(4,4,9,18,1.5);
+INSERT INTO Item VALUES(4,3,23,20,1.5);
+INSERT INTO Item VALUES(4,2,41,23,1.5);
+INSERT INTO Item VALUES(4,1,35,15,1.5);
+INSERT INTO Item VALUES(4,0,28,9,1.5);
+INSERT INTO Item VALUES(5,13,18,17,1.5);
+INSERT INTO Item VALUES(5,12,8,15,1.5);
+INSERT INTO Item VALUES(5,11,38,23,1.5);
+INSERT INTO Item VALUES(5,10,28,18,1.5);
+INSERT INTO Item VALUES(5,9,37,9,1.5);
+INSERT INTO Item VALUES(5,8,20,3,1.5);
+INSERT INTO Item VALUES(5,7,2,4,1.5);
+INSERT INTO Item VALUES(5,6,7,9,1.5);
+INSERT INTO Item VALUES(5,5,46,15,1.5);
+INSERT INTO Item VALUES(5,4,32,14,1.5);
+INSERT INTO Item VALUES(5,3,24,12,1.5);
+INSERT INTO Item VALUES(5,2,20,18,1.5);
+INSERT INTO Item VALUES(5,1,9,23,1.5);
+INSERT INTO Item VALUES(5,0,9,5,1.5);
+INSERT INTO Item VALUES(6,11,44,1,1.5);
+INSERT INTO Item VALUES(6,10,16,13,1.5);
+INSERT INTO Item VALUES(6,9,19,2,1.5);
+INSERT INTO Item VALUES(6,8,41,19,1.5);
+INSERT INTO Item VALUES(6,7,26,10,1.5);
+INSERT INTO Item VALUES(6,6,37,22,1.5);
+INSERT INTO Item VALUES(6,5,14,20,1.5);
+INSERT INTO Item VALUES(6,4,31,20,1.5);
+INSERT INTO Item VALUES(6,3,30,2,1.5);
+INSERT INTO Item VALUES(6,2,23,8,1.5);
+INSERT INTO Item VALUES(6,1,38,21,1.5);
+INSERT INTO Item VALUES(6,0,15,20,1.5);
+INSERT INTO Item VALUES(7,18,23,5,1.5);
+INSERT INTO Item VALUES(7,17,40,1,1.5);
+INSERT INTO Item VALUES(7,16,7,12,1.5);
+INSERT INTO Item VALUES(7,15,24,17,1.5);
+INSERT INTO Item VALUES(7,14,47,14,1.5);
+INSERT INTO Item VALUES(7,13,32,23,1.5);
+INSERT INTO Item VALUES(7,12,40,16,1.5);
+INSERT INTO Item VALUES(7,11,19,13,1.5);
+INSERT INTO Item VALUES(7,10,7,1,1.5);
+INSERT INTO Item VALUES(7,9,9,21,1.5);
+INSERT INTO Item VALUES(7,8,42,19,1.5);
+INSERT INTO Item VALUES(7,7,2,22,1.5);
+INSERT INTO Item VALUES(7,6,14,4,1.5);
+INSERT INTO Item VALUES(7,5,24,10,1.5);
+INSERT INTO Item VALUES(7,4,2,13,1.5);
+INSERT INTO Item VALUES(7,3,30,2,1.5);
+INSERT INTO Item VALUES(7,2,27,17,1.5);
+INSERT INTO Item VALUES(7,1,23,12,1.5);
+INSERT INTO Item VALUES(7,0,43,16,1.5);
+INSERT INTO Item VALUES(8,9,21,23,1.5);
+INSERT INTO Item VALUES(8,8,38,7,1.5);
+INSERT INTO Item VALUES(8,7,6,5,1.5);
+INSERT INTO Item VALUES(8,6,15,19,1.5);
+INSERT INTO Item VALUES(8,5,24,18,1.5);
+INSERT INTO Item VALUES(8,4,15,8,1.5);
+INSERT INTO Item VALUES(8,3,41,16,1.5);
+INSERT INTO Item VALUES(8,2,11,8,1.5);
+INSERT INTO Item VALUES(8,1,44,16,1.5);
+INSERT INTO Item VALUES(8,0,34,15,1.5);
+INSERT INTO Item VALUES(9,19,48,23,1.5);
+INSERT INTO Item VALUES(9,18,3,12,1.5);
+INSERT INTO Item VALUES(9,17,13,17,1.5);
+INSERT INTO Item VALUES(9,16,24,10,1.5);
+INSERT INTO Item VALUES(9,15,48,23,1.5);
+INSERT INTO Item VALUES(9,14,15,8,1.5);
+INSERT INTO Item VALUES(9,13,42,13,1.5);
+INSERT INTO Item VALUES(9,12,25,23,1.5);
+INSERT INTO Item VALUES(9,11,12,16,1.5);
+INSERT INTO Item VALUES(9,10,38,11,1.5);
+INSERT INTO Item VALUES(9,9,13,6,1.5);
+INSERT INTO Item VALUES(9,8,24,11,1.5);
+INSERT INTO Item VALUES(9,7,2,22,1.5);
+INSERT INTO Item VALUES(9,6,18,10,1.5);
+INSERT INTO Item VALUES(9,5,6,2,1.5);
+INSERT INTO Item VALUES(9,4,36,16,1.5);
+INSERT INTO Item VALUES(9,3,4,14,1.5);
+INSERT INTO Item VALUES(9,2,29,12,1.5);
+INSERT INTO Item VALUES(9,1,18,21,1.5);
+INSERT INTO Item VALUES(9,0,45,8,1.5);
+INSERT INTO Item VALUES(10,9,5,10,1.5);
+INSERT INTO Item VALUES(10,8,22,11,1.5);
+INSERT INTO Item VALUES(10,7,4,13,1.5);
+INSERT INTO Item VALUES(10,6,18,14,1.5);
+INSERT INTO Item VALUES(10,5,5,24,1.5);
+INSERT INTO Item VALUES(10,4,10,24,1.5);
+INSERT INTO Item VALUES(10,3,46,1,1.5);
+INSERT INTO Item VALUES(10,2,7,9,1.5);
+INSERT INTO Item VALUES(10,1,33,17,1.5);
+INSERT INTO Item VALUES(10,0,20,1,1.5);
+INSERT INTO Item VALUES(11,8,20,1,1.5);
+INSERT INTO Item VALUES(11,7,48,22,1.5);
+INSERT INTO Item VALUES(11,6,0,12,1.5);
+INSERT INTO Item VALUES(11,5,19,2,1.5);
+INSERT INTO Item VALUES(11,4,47,16,1.5);
+INSERT INTO Item VALUES(11,3,32,21,1.5);
+INSERT INTO Item VALUES(11,2,0,3,1.5);
+INSERT INTO Item VALUES(11,1,21,21,1.5);
+INSERT INTO Item VALUES(11,0,45,10,1.5);
+INSERT INTO Item VALUES(12,18,9,4,1.5);
+INSERT INTO Item VALUES(12,17,31,15,1.5);
+INSERT INTO Item VALUES(12,16,0,9,1.5);
+INSERT INTO Item VALUES(12,15,22,16,1.5);
+INSERT INTO Item VALUES(12,14,25,11,1.5);
+INSERT INTO Item VALUES(12,13,36,21,1.5);
+INSERT INTO Item VALUES(12,12,13,12,1.5);
+INSERT INTO Item VALUES(12,11,28,16,1.5);
+INSERT INTO Item VALUES(12,10,46,19,1.5);
+INSERT INTO Item VALUES(12,9,25,22,1.5);
+INSERT INTO Item VALUES(12,8,48,2,1.5);
+INSERT INTO Item VALUES(12,7,48,7,1.5);
+INSERT INTO Item VALUES(12,6,31,15,1.5);
+INSERT INTO Item VALUES(12,5,37,17,1.5);
+INSERT INTO Item VALUES(12,4,20,11,1.5);
+INSERT INTO Item VALUES(12,3,0,18,1.5);
+INSERT INTO Item VALUES(12,2,6,5,1.5);
+INSERT INTO Item VALUES(12,1,41,19,1.5);
+INSERT INTO Item VALUES(12,0,1,24,1.5);
+INSERT INTO Item VALUES(13,21,40,1,1.5);
+INSERT INTO Item VALUES(13,20,5,19,1.5);
+INSERT INTO Item VALUES(13,19,42,18,1.5);
+INSERT INTO Item VALUES(13,18,0,16,1.5);
+INSERT INTO Item VALUES(13,17,32,18,1.5);
+INSERT INTO Item VALUES(13,16,22,23,1.5);
+INSERT INTO Item VALUES(13,15,0,20,1.5);
+INSERT INTO Item VALUES(13,14,1,12,1.5);
+INSERT INTO Item VALUES(13,13,10,20,1.5);
+INSERT INTO Item VALUES(13,12,17,3,1.5);
+INSERT INTO Item VALUES(13,11,14,3,1.5);
+INSERT INTO Item VALUES(13,10,45,24,1.5);
+INSERT INTO Item VALUES(13,9,24,10,1.5);
+INSERT INTO Item VALUES(13,8,48,11,1.5);
+INSERT INTO Item VALUES(13,7,29,24,1.5);
+INSERT INTO Item VALUES(13,6,19,8,1.5);
+INSERT INTO Item VALUES(13,5,22,19,1.5);
+INSERT INTO Item VALUES(13,4,26,21,1.5);
+INSERT INTO Item VALUES(13,3,32,2,1.5);
+INSERT INTO Item VALUES(13,2,13,20,1.5);
+INSERT INTO Item VALUES(13,1,1,1,1.5);
+INSERT INTO Item VALUES(13,0,16,10,1.5);
+INSERT INTO Item VALUES(14,13,11,23,1.5);
+INSERT INTO Item VALUES(14,12,4,20,1.5);
+INSERT INTO Item VALUES(14,11,25,15,1.5);
+INSERT INTO Item VALUES(14,10,44,16,1.5);
+INSERT INTO Item VALUES(14,9,13,16,1.5);
+INSERT INTO Item VALUES(14,8,23,7,1.5);
+INSERT INTO Item VALUES(14,7,43,4,1.5);
+INSERT INTO Item VALUES(14,6,26,18,1.5);
+INSERT INTO Item VALUES(14,5,11,8,1.5);
+INSERT INTO Item VALUES(14,4,41,17,1.5);
+INSERT INTO Item VALUES(14,3,34,11,1.5);
+INSERT INTO Item VALUES(14,2,15,18,1.5);
+INSERT INTO Item VALUES(14,1,9,22,1.5);
+INSERT INTO Item VALUES(14,0,42,18,1.5);
+INSERT INTO Item VALUES(15,2,24,6,1.5);
+INSERT INTO Item VALUES(15,1,13,21,1.5);
+INSERT INTO Item VALUES(15,0,17,12,1.5);
+INSERT INTO Item VALUES(16,15,12,3,1.5);
+INSERT INTO Item VALUES(16,14,0,19,1.5);
+INSERT INTO Item VALUES(16,13,20,1,1.5);
+INSERT INTO Item VALUES(16,12,18,2,1.5);
+INSERT INTO Item VALUES(16,11,24,7,1.5);
+INSERT INTO Item VALUES(16,10,43,8,1.5);
+INSERT INTO Item VALUES(16,9,11,10,1.5);
+INSERT INTO Item VALUES(16,8,13,17,1.5);
+INSERT INTO Item VALUES(16,7,8,17,1.5);
+INSERT INTO Item VALUES(16,6,44,7,1.5);
+INSERT INTO Item VALUES(16,5,11,15,1.5);
+INSERT INTO Item VALUES(16,4,10,24,1.5);
+INSERT INTO Item VALUES(16,3,0,3,1.5);
+INSERT INTO Item VALUES(16,2,20,15,1.5);
+INSERT INTO Item VALUES(16,1,36,20,1.5);
+INSERT INTO Item VALUES(16,0,18,15,1.5);
+INSERT INTO Item VALUES(17,19,46,12,1.5);
+INSERT INTO Item VALUES(17,18,5,9,1.5);
+INSERT INTO Item VALUES(17,17,7,5,1.5);
+INSERT INTO Item VALUES(17,16,8,16,1.5);
+INSERT INTO Item VALUES(17,15,35,10,1.5);
+INSERT INTO Item VALUES(17,14,18,2,1.5);
+INSERT INTO Item VALUES(17,13,41,5,1.5);
+INSERT INTO Item VALUES(17,12,22,16,1.5);
+INSERT INTO Item VALUES(17,11,45,10,1.5);
+INSERT INTO Item VALUES(17,10,10,12,1.5);
+INSERT INTO Item VALUES(17,9,8,15,1.5);
+INSERT INTO Item VALUES(17,8,49,8,1.5);
+INSERT INTO Item VALUES(17,7,6,15,1.5);
+INSERT INTO Item VALUES(17,6,43,6,1.5);
+INSERT INTO Item VALUES(17,5,44,1,1.5);
+INSERT INTO Item VALUES(17,4,23,2,1.5);
+INSERT INTO Item VALUES(17,3,24,4,1.5);
+INSERT INTO Item VALUES(17,2,44,11,1.5);
+INSERT INTO Item VALUES(17,1,19,19,1.5);
+INSERT INTO Item VALUES(17,0,16,8,1.5);
+INSERT INTO Item VALUES(18,18,10,1,1.5);
+INSERT INTO Item VALUES(18,17,8,1,1.5);
+INSERT INTO Item VALUES(18,16,31,12,1.5);
+INSERT INTO Item VALUES(18,15,44,20,1.5);
+INSERT INTO Item VALUES(18,14,28,20,1.5);
+INSERT INTO Item VALUES(18,13,14,12,1.5);
+INSERT INTO Item VALUES(18,12,37,12,1.5);
+INSERT INTO Item VALUES(18,11,30,8,1.5);
+INSERT INTO Item VALUES(18,10,34,18,1.5);
+INSERT INTO Item VALUES(18,9,2,2,1.5);
+INSERT INTO Item VALUES(18,8,1,24,1.5);
+INSERT INTO Item VALUES(18,7,15,14,1.5);
+INSERT INTO Item VALUES(18,6,29,4,1.5);
+INSERT INTO Item VALUES(18,5,15,6,1.5);
+INSERT INTO Item VALUES(18,4,28,6,1.5);
+INSERT INTO Item VALUES(18,3,19,8,1.5);
+INSERT INTO Item VALUES(18,2,40,12,1.5);
+INSERT INTO Item VALUES(18,1,33,12,1.5);
+INSERT INTO Item VALUES(18,0,32,1,1.5);
+INSERT INTO Item VALUES(19,4,36,24,1.5);
+INSERT INTO Item VALUES(19,3,49,23,1.5);
+INSERT INTO Item VALUES(19,2,4,22,1.5);
+INSERT INTO Item VALUES(19,1,31,2,1.5);
+INSERT INTO Item VALUES(19,0,12,7,1.5);
+INSERT INTO Item VALUES(20,11,15,8,1.5);
+INSERT INTO Item VALUES(20,10,25,11,1.5);
+INSERT INTO Item VALUES(20,9,12,8,1.5);
+INSERT INTO Item VALUES(20,8,44,18,1.5);
+INSERT INTO Item VALUES(20,7,9,9,1.5);
+INSERT INTO Item VALUES(20,6,20,2,1.5);
+INSERT INTO Item VALUES(20,5,8,14,1.5);
+INSERT INTO Item VALUES(20,4,30,13,1.5);
+INSERT INTO Item VALUES(20,3,25,14,1.5);
+INSERT INTO Item VALUES(20,2,24,22,1.5);
+INSERT INTO Item VALUES(20,1,29,6,1.5);
+INSERT INTO Item VALUES(20,0,47,15,1.5);
+INSERT INTO Item VALUES(21,11,20,11,1.5);
+INSERT INTO Item VALUES(21,10,19,14,1.5);
+INSERT INTO Item VALUES(21,9,35,17,1.5);
+INSERT INTO Item VALUES(21,8,44,19,1.5);
+INSERT INTO Item VALUES(21,7,8,9,1.5);
+INSERT INTO Item VALUES(21,6,26,7,1.5);
+INSERT INTO Item VALUES(21,5,27,18,1.5);
+INSERT INTO Item VALUES(21,4,49,22,1.5);
+INSERT INTO Item VALUES(21,3,30,13,1.5);
+INSERT INTO Item VALUES(21,2,31,17,1.5);
+INSERT INTO Item VALUES(21,1,38,19,1.5);
+INSERT INTO Item VALUES(21,0,9,10,1.5);
+INSERT INTO Item VALUES(22,9,23,1,1.5);
+INSERT INTO Item VALUES(22,8,3,2,1.5);
+INSERT INTO Item VALUES(22,7,21,6,1.5);
+INSERT INTO Item VALUES(22,6,4,11,1.5);
+INSERT INTO Item VALUES(22,5,24,5,1.5);
+INSERT INTO Item VALUES(22,4,5,21,1.5);
+INSERT INTO Item VALUES(22,3,22,5,1.5);
+INSERT INTO Item VALUES(22,2,12,20,1.5);
+INSERT INTO Item VALUES(22,1,30,11,1.5);
+INSERT INTO Item VALUES(22,0,9,6,1.5);
+INSERT INTO Item VALUES(23,16,8,11,1.5);
+INSERT INTO Item VALUES(23,15,13,17,1.5);
+INSERT INTO Item VALUES(23,14,44,2,1.5);
+INSERT INTO Item VALUES(23,13,14,17,1.5);
+INSERT INTO Item VALUES(23,12,4,17,1.5);
+INSERT INTO Item VALUES(23,11,41,8,1.5);
+INSERT INTO Item VALUES(23,10,4,18,1.5);
+INSERT INTO Item VALUES(23,9,20,18,1.5);
+INSERT INTO Item VALUES(23,8,6,17,1.5);
+INSERT INTO Item VALUES(23,7,39,3,1.5);
+INSERT INTO Item VALUES(23,6,16,1,1.5);
+INSERT INTO Item VALUES(23,5,32,14,1.5);
+INSERT INTO Item VALUES(23,4,23,19,1.5);
+INSERT INTO Item VALUES(23,3,40,19,1.5);
+INSERT INTO Item VALUES(23,2,33,18,1.5);
+INSERT INTO Item VALUES(23,1,26,8,1.5);
+INSERT INTO Item VALUES(23,0,48,22,1.5);
+INSERT INTO Item VALUES(24,15,39,17,1.5);
+INSERT INTO Item VALUES(24,14,1,13,1.5);
+INSERT INTO Item VALUES(24,13,15,21,1.5);
+INSERT INTO Item VALUES(24,12,0,8,1.5);
+INSERT INTO Item VALUES(24,11,1,4,1.5);
+INSERT INTO Item VALUES(24,10,27,4,1.5);
+INSERT INTO Item VALUES(24,9,21,8,1.5);
+INSERT INTO Item VALUES(24,8,5,18,1.5);
+INSERT INTO Item VALUES(24,7,7,13,1.5);
+INSERT INTO Item VALUES(24,6,40,3,1.5);
+INSERT INTO Item VALUES(24,5,35,16,1.5);
+INSERT INTO Item VALUES(24,4,15,17,1.5);
+INSERT INTO Item VALUES(24,3,17,23,1.5);
+INSERT INTO Item VALUES(24,2,38,10,1.5);
+INSERT INTO Item VALUES(24,1,46,18,1.5);
+INSERT INTO Item VALUES(24,0,43,14,1.5);
+INSERT INTO Item VALUES(25,8,38,3,1.5);
+INSERT INTO Item VALUES(25,7,16,8,1.5);
+INSERT INTO Item VALUES(25,6,21,18,1.5);
+INSERT INTO Item VALUES(25,5,10,5,1.5);
+INSERT INTO Item VALUES(25,4,47,10,1.5);
+INSERT INTO Item VALUES(25,3,19,4,1.5);
+INSERT INTO Item VALUES(25,2,13,8,1.5);
+INSERT INTO Item VALUES(25,1,43,13,1.5);
+INSERT INTO Item VALUES(25,0,5,15,1.5);
+INSERT INTO Item VALUES(26,16,30,4,1.5);
+INSERT INTO Item VALUES(26,15,8,6,1.5);
+INSERT INTO Item VALUES(26,14,26,6,1.5);
+INSERT INTO Item VALUES(26,13,13,10,1.5);
+INSERT INTO Item VALUES(26,12,27,20,1.5);
+INSERT INTO Item VALUES(26,11,18,3,1.5);
+INSERT INTO Item VALUES(26,10,34,16,1.5);
+INSERT INTO Item VALUES(26,9,1,23,1.5);
+INSERT INTO Item VALUES(26,8,40,13,1.5);
+INSERT INTO Item VALUES(26,7,4,16,1.5);
+INSERT INTO Item VALUES(26,6,7,23,1.5);
+INSERT INTO Item VALUES(26,5,38,4,1.5);
+INSERT INTO Item VALUES(26,4,46,7,1.5);
+INSERT INTO Item VALUES(26,3,16,3,1.5);
+INSERT INTO Item VALUES(26,2,33,7,1.5);
+INSERT INTO Item VALUES(26,1,43,21,1.5);
+INSERT INTO Item VALUES(26,0,42,16,1.5);
+INSERT INTO Item VALUES(27,2,19,1,1.5);
+INSERT INTO Item VALUES(27,1,45,15,1.5);
+INSERT INTO Item VALUES(27,0,24,15,1.5);
+INSERT INTO Item VALUES(28,8,28,6,1.5);
+INSERT INTO Item VALUES(28,7,28,8,1.5);
+INSERT INTO Item VALUES(28,6,33,16,1.5);
+INSERT INTO Item VALUES(28,5,49,4,1.5);
+INSERT INTO Item VALUES(28,4,45,17,1.5);
+INSERT INTO Item VALUES(28,3,6,3,1.5);
+INSERT INTO Item VALUES(28,2,44,22,1.5);
+INSERT INTO Item VALUES(28,1,15,13,1.5);
+INSERT INTO Item VALUES(28,0,35,13,1.5);
+INSERT INTO Item VALUES(29,8,35,6,1.5);
+INSERT INTO Item VALUES(29,7,5,1,1.5);
+INSERT INTO Item VALUES(29,6,4,16,1.5);
+INSERT INTO Item VALUES(29,5,31,13,1.5);
+INSERT INTO Item VALUES(29,4,4,7,1.5);
+INSERT INTO Item VALUES(29,3,7,21,1.5);
+INSERT INTO Item VALUES(29,2,17,23,1.5);
+INSERT INTO Item VALUES(29,1,38,12,1.5);
+INSERT INTO Item VALUES(29,0,33,17,1.5);
+INSERT INTO Item VALUES(30,6,14,23,1.5);
+INSERT INTO Item VALUES(30,5,43,23,1.5);
+INSERT INTO Item VALUES(30,4,34,2,1.5);
+INSERT INTO Item VALUES(30,3,33,2,1.5);
+INSERT INTO Item VALUES(30,2,10,18,1.5);
+INSERT INTO Item VALUES(30,1,16,19,1.5);
+INSERT INTO Item VALUES(30,0,14,7,1.5);
+INSERT INTO Item VALUES(31,10,0,3,1.5);
+INSERT INTO Item VALUES(31,9,14,15,1.5);
+INSERT INTO Item VALUES(31,8,7,5,1.5);
+INSERT INTO Item VALUES(31,7,38,3,1.5);
+INSERT INTO Item VALUES(31,6,26,16,1.5);
+INSERT INTO Item VALUES(31,5,1,4,1.5);
+INSERT INTO Item VALUES(31,4,8,14,1.5);
+INSERT INTO Item VALUES(31,3,12,10,1.5);
+INSERT INTO Item VALUES(31,2,4,3,1.5);
+INSERT INTO Item VALUES(31,1,4,23,1.5);
+INSERT INTO Item VALUES(31,0,33,10,1.5);
+INSERT INTO Item VALUES(32,2,1,14,1.5);
+INSERT INTO Item VALUES(32,1,30,13,1.5);
+INSERT INTO Item VALUES(32,0,35,11,1.5);
+INSERT INTO Item VALUES(33,15,38,7,1.5);
+INSERT INTO Item VALUES(33,14,44,13,1.5);
+INSERT INTO Item VALUES(33,13,25,16,1.5);
+INSERT INTO Item VALUES(33,12,16,23,1.5);
+INSERT INTO Item VALUES(33,11,5,7,1.5);
+INSERT INTO Item VALUES(33,10,24,9,1.5);
+INSERT INTO Item VALUES(33,9,29,5,1.5);
+INSERT INTO Item VALUES(33,8,3,15,1.5);
+INSERT INTO Item VALUES(33,7,43,10,1.5);
+INSERT INTO Item VALUES(33,6,17,16,1.5);
+INSERT INTO Item VALUES(33,5,8,11,1.5);
+INSERT INTO Item VALUES(33,4,24,1,1.5);
+INSERT INTO Item VALUES(33,3,48,1,1.5);
+INSERT INTO Item VALUES(33,2,36,16,1.5);
+INSERT INTO Item VALUES(33,1,10,21,1.5);
+INSERT INTO Item VALUES(33,0,36,5,1.5);
+INSERT INTO Item VALUES(34,14,46,7,1.5);
+INSERT INTO Item VALUES(34,13,30,14,1.5);
+INSERT INTO Item VALUES(34,12,43,21,1.5);
+INSERT INTO Item VALUES(34,11,4,17,1.5);
+INSERT INTO Item VALUES(34,10,41,16,1.5);
+INSERT INTO Item VALUES(34,9,8,17,1.5);
+INSERT INTO Item VALUES(34,8,3,1,1.5);
+INSERT INTO Item VALUES(34,7,21,22,1.5);
+INSERT INTO Item VALUES(34,6,32,7,1.5);
+INSERT INTO Item VALUES(34,5,45,13,1.5);
+INSERT INTO Item VALUES(34,4,27,1,1.5);
+INSERT INTO Item VALUES(34,3,44,15,1.5);
+INSERT INTO Item VALUES(34,2,28,22,1.5);
+INSERT INTO Item VALUES(34,1,4,3,1.5);
+INSERT INTO Item VALUES(34,0,10,22,1.5);
+INSERT INTO Item VALUES(35,13,19,17,1.5);
+INSERT INTO Item VALUES(35,12,7,23,1.5);
+INSERT INTO Item VALUES(35,11,44,9,1.5);
+INSERT INTO Item VALUES(35,10,17,11,1.5);
+INSERT INTO Item VALUES(35,9,19,1,1.5);
+INSERT INTO Item VALUES(35,8,0,1,1.5);
+INSERT INTO Item VALUES(35,7,22,15,1.5);
+INSERT INTO Item VALUES(35,6,5,4,1.5);
+INSERT INTO Item VALUES(35,5,33,5,1.5);
+INSERT INTO Item VALUES(35,4,14,17,1.5);
+INSERT INTO Item VALUES(35,3,27,10,1.5);
+INSERT INTO Item VALUES(35,2,14,4,1.5);
+INSERT INTO Item VALUES(35,1,3,9,1.5);
+INSERT INTO Item VALUES(35,0,20,17,1.5);
+INSERT INTO Item VALUES(36,11,44,9,1.5);
+INSERT INTO Item VALUES(36,10,47,11,1.5);
+INSERT INTO Item VALUES(36,9,31,18,1.5);
+INSERT INTO Item VALUES(36,8,4,21,1.5);
+INSERT INTO Item VALUES(36,7,39,19,1.5);
+INSERT INTO Item VALUES(36,6,39,20,1.5);
+INSERT INTO Item VALUES(36,5,25,8,1.5);
+INSERT INTO Item VALUES(36,4,40,5,1.5);
+INSERT INTO Item VALUES(36,3,10,8,1.5);
+INSERT INTO Item VALUES(36,2,1,6,1.5);
+INSERT INTO Item VALUES(36,1,15,23,1.5);
+INSERT INTO Item VALUES(36,0,18,13,1.5);
+INSERT INTO Item VALUES(37,21,6,9,1.5);
+INSERT INTO Item VALUES(37,20,14,1,1.5);
+INSERT INTO Item VALUES(37,19,19,20,1.5);
+INSERT INTO Item VALUES(37,18,26,22,1.5);
+INSERT INTO Item VALUES(37,17,38,18,1.5);
+INSERT INTO Item VALUES(37,16,27,8,1.5);
+INSERT INTO Item VALUES(37,15,32,12,1.5);
+INSERT INTO Item VALUES(37,14,12,3,1.5);
+INSERT INTO Item VALUES(37,13,32,3,1.5);
+INSERT INTO Item VALUES(37,12,24,23,1.5);
+INSERT INTO Item VALUES(37,11,30,5,1.5);
+INSERT INTO Item VALUES(37,10,1,18,1.5);
+INSERT INTO Item VALUES(37,9,47,16,1.5);
+INSERT INTO Item VALUES(37,8,46,9,1.5);
+INSERT INTO Item VALUES(37,7,24,19,1.5);
+INSERT INTO Item VALUES(37,6,34,12,1.5);
+INSERT INTO Item VALUES(37,5,1,14,1.5);
+INSERT INTO Item VALUES(37,4,13,20,1.5);
+INSERT INTO Item VALUES(37,3,26,7,1.5);
+INSERT INTO Item VALUES(37,2,36,8,1.5);
+INSERT INTO Item VALUES(37,1,15,20,1.5);
+INSERT INTO Item VALUES(37,0,41,24,1.5);
+INSERT INTO Item VALUES(38,19,4,7,1.5);
+INSERT INTO Item VALUES(38,18,28,20,1.5);
+INSERT INTO Item VALUES(38,17,32,4,1.5);
+INSERT INTO Item VALUES(38,16,40,18,1.5);
+INSERT INTO Item VALUES(38,15,47,10,1.5);
+INSERT INTO Item VALUES(38,14,20,7,1.5);
+INSERT INTO Item VALUES(38,13,8,7,1.5);
+INSERT INTO Item VALUES(38,12,1,18,1.5);
+INSERT INTO Item VALUES(38,11,19,18,1.5);
+INSERT INTO Item VALUES(38,10,4,18,1.5);
+INSERT INTO Item VALUES(38,9,27,20,1.5);
+INSERT INTO Item VALUES(38,8,40,10,1.5);
+INSERT INTO Item VALUES(38,7,15,1,1.5);
+INSERT INTO Item VALUES(38,6,5,19,1.5);
+INSERT INTO Item VALUES(38,5,48,17,1.5);
+INSERT INTO Item VALUES(38,4,45,14,1.5);
+INSERT INTO Item VALUES(38,3,27,19,1.5);
+INSERT INTO Item VALUES(38,2,4,8,1.5);
+INSERT INTO Item VALUES(38,1,45,13,1.5);
+INSERT INTO Item VALUES(38,0,48,14,1.5);
+INSERT INTO Item VALUES(39,3,20,17,1.5);
+INSERT INTO Item VALUES(39,2,39,16,1.5);
+INSERT INTO Item VALUES(39,1,24,6,1.5);
+INSERT INTO Item VALUES(39,0,10,12,1.5);
+INSERT INTO Item VALUES(40,20,4,16,1.5);
+INSERT INTO Item VALUES(40,19,7,23,1.5);
+INSERT INTO Item VALUES(40,18,33,11,1.5);
+INSERT INTO Item VALUES(40,17,4,20,1.5);
+INSERT INTO Item VALUES(40,16,27,16,1.5);
+INSERT INTO Item VALUES(40,15,22,12,1.5);
+INSERT INTO Item VALUES(40,14,4,24,1.5);
+INSERT INTO Item VALUES(40,13,6,8,1.5);
+INSERT INTO Item VALUES(40,12,35,13,1.5);
+INSERT INTO Item VALUES(40,11,27,2,1.5);
+INSERT INTO Item VALUES(40,10,6,11,1.5);
+INSERT INTO Item VALUES(40,9,40,17,1.5);
+INSERT INTO Item VALUES(40,8,11,4,1.5);
+INSERT INTO Item VALUES(40,7,31,1,1.5);
+INSERT INTO Item VALUES(40,6,28,12,1.5);
+INSERT INTO Item VALUES(40,5,32,18,1.5);
+INSERT INTO Item VALUES(40,4,18,13,1.5);
+INSERT INTO Item VALUES(40,3,26,10,1.5);
+INSERT INTO Item VALUES(40,2,4,5,1.5);
+INSERT INTO Item VALUES(40,1,45,24,1.5);
+INSERT INTO Item VALUES(40,0,46,24,1.5);
+INSERT INTO Item VALUES(41,11,48,15,1.5);
+INSERT INTO Item VALUES(41,10,24,20,1.5);
+INSERT INTO Item VALUES(41,9,26,21,1.5);
+INSERT INTO Item VALUES(41,8,9,22,1.5);
+INSERT INTO Item VALUES(41,7,22,18,1.5);
+INSERT INTO Item VALUES(41,6,17,11,1.5);
+INSERT INTO Item VALUES(41,5,9,21,1.5);
+INSERT INTO Item VALUES(41,4,16,22,1.5);
+INSERT INTO Item VALUES(41,3,29,20,1.5);
+INSERT INTO Item VALUES(41,2,36,2,1.5);
+INSERT INTO Item VALUES(41,1,47,19,1.5);
+INSERT INTO Item VALUES(41,0,5,24,1.5);
+INSERT INTO Item VALUES(42,4,48,15,1.5);
+INSERT INTO Item VALUES(42,3,40,14,1.5);
+INSERT INTO Item VALUES(42,2,40,19,1.5);
+INSERT INTO Item VALUES(42,1,18,21,1.5);
+INSERT INTO Item VALUES(42,0,48,9,1.5);
+INSERT INTO Item VALUES(43,16,38,12,1.5);
+INSERT INTO Item VALUES(43,15,48,7,1.5);
+INSERT INTO Item VALUES(43,14,3,18,1.5);
+INSERT INTO Item VALUES(43,13,44,22,1.5);
+INSERT INTO Item VALUES(43,12,40,24,1.5);
+INSERT INTO Item VALUES(43,11,49,23,1.5);
+INSERT INTO Item VALUES(43,10,35,1,1.5);
+INSERT INTO Item VALUES(43,9,7,23,1.5);
+INSERT INTO Item VALUES(43,8,44,8,1.5);
+INSERT INTO Item VALUES(43,7,11,15,1.5);
+INSERT INTO Item VALUES(43,6,24,1,1.5);
+INSERT INTO Item VALUES(43,5,33,6,1.5);
+INSERT INTO Item VALUES(43,4,32,22,1.5);
+INSERT INTO Item VALUES(43,3,6,18,1.5);
+INSERT INTO Item VALUES(43,2,2,15,1.5);
+INSERT INTO Item VALUES(43,1,18,19,1.5);
+INSERT INTO Item VALUES(43,0,15,22,1.5);
+INSERT INTO Item VALUES(44,8,28,23,1.5);
+INSERT INTO Item VALUES(44,7,49,17,1.5);
+INSERT INTO Item VALUES(44,6,14,15,1.5);
+INSERT INTO Item VALUES(44,5,41,22,1.5);
+INSERT INTO Item VALUES(44,4,12,3,1.5);
+INSERT INTO Item VALUES(44,3,3,14,1.5);
+INSERT INTO Item VALUES(44,2,17,14,1.5);
+INSERT INTO Item VALUES(44,1,34,17,1.5);
+INSERT INTO Item VALUES(44,0,33,20,1.5);
+INSERT INTO Item VALUES(45,14,3,16,1.5);
+INSERT INTO Item VALUES(45,13,47,8,1.5);
+INSERT INTO Item VALUES(45,12,32,13,1.5);
+INSERT INTO Item VALUES(45,11,31,22,1.5);
+INSERT INTO Item VALUES(45,10,41,24,1.5);
+INSERT INTO Item VALUES(45,9,26,18,1.5);
+INSERT INTO Item VALUES(45,8,9,2,1.5);
+INSERT INTO Item VALUES(45,7,6,24,1.5);
+INSERT INTO Item VALUES(45,6,39,5,1.5);
+INSERT INTO Item VALUES(45,5,45,17,1.5);
+INSERT INTO Item VALUES(45,4,3,14,1.5);
+INSERT INTO Item VALUES(45,3,14,11,1.5);
+INSERT INTO Item VALUES(45,2,46,8,1.5);
+INSERT INTO Item VALUES(45,1,11,6,1.5);
+INSERT INTO Item VALUES(45,0,44,6,1.5);
+INSERT INTO Item VALUES(46,17,12,23,1.5);
+INSERT INTO Item VALUES(46,16,46,21,1.5);
+INSERT INTO Item VALUES(46,15,40,11,1.5);
+INSERT INTO Item VALUES(46,14,24,10,1.5);
+INSERT INTO Item VALUES(46,13,36,20,1.5);
+INSERT INTO Item VALUES(46,12,21,24,1.5);
+INSERT INTO Item VALUES(46,11,1,4,1.5);
+INSERT INTO Item VALUES(46,10,11,24,1.5);
+INSERT INTO Item VALUES(46,9,7,4,1.5);
+INSERT INTO Item VALUES(46,8,8,22,1.5);
+INSERT INTO Item VALUES(46,7,49,9,1.5);
+INSERT INTO Item VALUES(46,6,41,18,1.5);
+INSERT INTO Item VALUES(46,5,25,9,1.5);
+INSERT INTO Item VALUES(46,4,17,5,1.5);
+INSERT INTO Item VALUES(46,3,21,19,1.5);
+INSERT INTO Item VALUES(46,2,30,14,1.5);
+INSERT INTO Item VALUES(46,1,12,24,1.5);
+INSERT INTO Item VALUES(46,0,5,21,1.5);
+INSERT INTO Item VALUES(47,13,33,8,1.5);
+INSERT INTO Item VALUES(47,12,12,20,1.5);
+INSERT INTO Item VALUES(47,11,35,10,1.5);
+INSERT INTO Item VALUES(47,10,45,2,1.5);
+INSERT INTO Item VALUES(47,9,32,9,1.5);
+INSERT INTO Item VALUES(47,8,16,2,1.5);
+INSERT INTO Item VALUES(47,7,28,14,1.5);
+INSERT INTO Item VALUES(47,6,8,10,1.5);
+INSERT INTO Item VALUES(47,5,40,8,1.5);
+INSERT INTO Item VALUES(47,4,15,1,1.5);
+INSERT INTO Item VALUES(47,3,1,4,1.5);
+INSERT INTO Item VALUES(47,2,17,6,1.5);
+INSERT INTO Item VALUES(47,1,23,13,1.5);
+INSERT INTO Item VALUES(47,0,23,15,1.5);
+INSERT INTO Item VALUES(48,10,41,10,1.5);
+INSERT INTO Item VALUES(48,9,35,17,1.5);
+INSERT INTO Item VALUES(48,8,5,12,1.5);
+INSERT INTO Item VALUES(48,7,30,19,1.5);
+INSERT INTO Item VALUES(48,6,11,17,1.5);
+INSERT INTO Item VALUES(48,5,24,16,1.5);
+INSERT INTO Item VALUES(48,4,48,4,1.5);
+INSERT INTO Item VALUES(48,3,10,2,1.5);
+INSERT INTO Item VALUES(48,2,23,10,1.5);
+INSERT INTO Item VALUES(48,1,26,23,1.5);
+INSERT INTO Item VALUES(48,0,6,23,1.5);
+INSERT INTO Item VALUES(49,16,24,18,1.5);
+INSERT INTO Item VALUES(49,15,19,24,1.5);
+INSERT INTO Item VALUES(49,14,23,5,1.5);
+INSERT INTO Item VALUES(49,13,6,22,1.5);
+INSERT INTO Item VALUES(49,12,21,17,1.5);
+INSERT INTO Item VALUES(49,11,40,15,1.5);
+INSERT INTO Item VALUES(49,10,30,16,1.5);
+INSERT INTO Item VALUES(49,9,7,24,1.5);
+INSERT INTO Item VALUES(49,8,48,24,1.5);
+INSERT INTO Item VALUES(49,7,6,21,1.5);
+INSERT INTO Item VALUES(49,6,29,15,1.5);
+INSERT INTO Item VALUES(49,5,16,1,1.5);
+INSERT INTO Item VALUES(49,4,47,14,1.5);
+INSERT INTO Item VALUES(49,3,17,19,1.5);
+INSERT INTO Item VALUES(49,2,29,6,1.5);
+INSERT INTO Item VALUES(49,1,22,16,1.5);
+INSERT INTO Item VALUES(49,0,18,6,1.5);
+UPDATE Product SET Price=ROUND(Price*.1,2);
+UPDATE Item SET Cost=Cost*(SELECT Price FROM Product prod WHERE ProductID=prod.ID);
+UPDATE Invoice SET Total=SELECT SUM(Cost*Quantity) FROM Item WHERE InvoiceID=Invoice.ID;
+
+COMMIT;
diff --git a/doc/verbatim/sample/server.properties b/doc/verbatim/sample/server.properties
new file mode 100644
index 0000000..8726b34
--- /dev/null
+++ b/doc/verbatim/sample/server.properties
@@ -0,0 +1,20 @@
+# Hsqldb Server cfg file.
+# See the HyperSQL Network Listeners chapter of the HyperSQL User Guide.
+
+# Each server.database.X setting defines a database "catalog".
+# I.e., an independent set of data.
+# Each server.database.X setting corresponds exactly to the jdbc:hsqldb:*
+# JDBC URL you would use if you wanted to get a direct (In-Process)
+# Connection to the catalog instead of "serving" it.
+
+server.database.0=file:db0/db0
+# I suggest that, for every file: catalog you define, you add the
+# connection property "ifexists=true" after the database instance
+# is created (which happens simply by starting the Server one time).
+# Just append ";ifexists=true" to the file: URL, like so:
+# server.database.0=file:db0/db0;ifexists=true
+
+# server.dbname.0 defaults to "" (i.e. server.dbname.n for n==0), but
+# the catalog definition n will be entirely ignored for n > 0 if you do not
+# set server.dbname.n.  I.e. dbname setting is required for n > 0, though it
+# may be set to blank (e.g. "server.dbname.3=")
diff --git a/doc/verbatim/sample/sqltool.rc b/doc/verbatim/sample/sqltool.rc
new file mode 100644
index 0000000..0a772a7
--- /dev/null
+++ b/doc/verbatim/sample/sqltool.rc
@@ -0,0 +1,141 @@
+# $Id: sqltool.rc 3353 2009-12-15 19:52:13Z unsaved $
+
+# This is a sample RC configuration file used by SqlTool, DatabaseManager,
+# and any other program that uses the org.hsqldb.lib.RCData class.
+# See the documentation for SqlTool for various ways to use this file.
+
+# If you have the least concerns about security, then secure access to
+# your RC file.
+
+# You can run SqlTool right now by copying this file to your home directory
+# and running
+#    java -jar /path/to/sqltool.jar mem
+# This will access the first urlid definition below in order to use a 
+# personal Memory-Only database.
+# "url" values may, of course, contain JDBC connection properties, delimited
+# with semicolons.
+# As of revision 3347 of SqlFile, you can also connect to datasources defined
+# here from within an SqlTool session/file with the command "\j urlid".
+
+# You can use Java system property values in this file like this:  ${user.home}
+
+# The only feature added recently is the optional "transiso" setting,
+# which may be set to an all-caps transaction isolation level as listed
+# in the Java API Spec for java.sql.Connection.
+# Windows users are advised to use forward slashes instead of reverse slashes,
+# and to avoid paths containing spaces or other funny characters.  (This
+# recommendation applies to any Java app, not just SqlTool).
+
+# A personal Memory-Only (non-persistent) database.
+urlid mem
+url jdbc:hsqldb:mem:memdbid
+username SA
+password
+
+# A personal, local, persistent database.
+urlid personal
+url jdbc:hsqldb:file:${user.home}/db/personal;shutdown=true
+username SA
+password
+transiso TRANSACTION_READ_COMMITTED
+# When connecting directly to a file database like this, you should 
+# use the shutdown connection property like this to shut down the DB
+# properly when you exit the JVM.
+
+# This is for a hsqldb Server running with default settings on your local
+# computer (and for which you have not changed the password for "SA").
+urlid localhost-sa
+url jdbc:hsqldb:hsql://localhost
+username SA
+password
+
+
+
+# Template for a urlid for an Oracle database.
+# You will need to put the oracle.jdbc.OracleDriver class into your 
+# classpath.
+# In the great majority of cases, you want to use the file classes12.zip
+# (which you can get from the directory $ORACLE_HOME/jdbc/lib of any
+# Oracle installation compatible with your server).
+# Since you need to add to the classpath, you can't invoke SqlTool with
+# the jar switch, like "java -jar .../hsqldb.jar..." or 
+# "java -jar .../hsqlsqltool.jar...".
+# Put both the HSQLDB jar and classes12.zip in your classpath (and export!)
+# and run something like "java org.hsqldb.util.SqlTool...".
+
+#urlid cardiff2
+#url jdbc:oracle:thin:@aegir.admc.com:1522:TRAFFIC_SID
+#username blaine
+#password secretpassword
+#driver oracle.jdbc.OracleDriver
+
+
+
+# Template for a TLS-encrypted HSQLDB Server.
+# Remember that the hostname in hsqls (and https) JDBC URLs must match the
+# CN of the server certificate (the port and instance alias that follows 
+# are not part of the certificate at all).
+# You only need to set "truststore" if the server cert is not approved by
+# your system default truststore (which a commercial certificate probably
+# would be).
+
+#urlid tls
+#url jdbc:hsqldb:hsqls://db.admc.com:9001/lm2
+#username BLAINE
+#password asecret
+#truststore ${user.home}/ca/db/db-trust.store
+
+
+# Template for a Postgresql database
+#urlid blainedb
+#url jdbc:postgresql://idun.africawork.org/blainedb
+#username blaine
+#password losung1
+#driver org.postgresql.Driver
+
+# Template for a MySQL database.  MySQL has poor JDBC support.
+#urlid mysql-testdb
+#url jdbc:mysql://hostname:3306/dbname
+#username root
+#password hiddenpwd
+#driver com.mysql.jdbc.Driver
+
+# Note that "databases" in SQL Server and Sybase are traditionally used for
+# the same purpose as "schemas" with more SQL-compliant databases.
+
+# Template for a Microsoft SQL Server database
+#urlid msprojsvr
+#url jdbc:microsoft:sqlserver://hostname;DatabaseName=DbName;SelectMethod=Cursor
+# The SelectMethod setting is required to do more than one thing on a JDBC
+# session (I guess Microsoft thought nobody would really use Java for 
+# anything other than a "hello world" program).
+# This is for Microsoft's SQL Server 2000 driver (requires mssqlserver.jar
+# and msutil.jar).
+#driver com.microsoft.jdbc.sqlserver.SQLServerDriver
+#username myuser
+#password hiddenpwd
+
+# Template for a Sybase database
+#urlid sybase
+#url jdbc:sybase:Tds:hostname:4100/dbname
+#username blaine
+#password hiddenpwd
+# This is for the jConnect driver (requires jconn3.jar).
+#driver com.sybase.jdbc3.jdbc.SybDriver
+
+# Template for Embedded Derby / Java DB.
+#urlid derby1
+#url jdbc:derby:path/to/derby/directory;create=true
+#username ${user.name}
+#password any_noauthbydefault
+#driver org.apache.derby.jdbc.EmbeddedDriver
+# The embedded Derby driver requires derby.jar.
+# There'a also the org.apache.derby.jdbc.ClientDriver driver with URL
+# like jdbc:derby://<server>[:<port>]/databaseName, which requires
+# derbyclient.jar.
+# You can use \= to commit, since the Derby team decided (why???)
+# not to implement the SQL standard statement "commit"!!
+# Note that SqlTool can not shut down an embedded Derby database properly,
+# since that requires an additional SQL connection just for that purpose.
+# However, I've never lost data by not shutting it down properly.
+# Other than not supporting this quirk of Derby, SqlTool is miles ahead of ij.
diff --git a/doc/verbatim/src/org/hsqldb/Tokens.java b/doc/verbatim/src/org/hsqldb/Tokens.java
new file mode 100644
index 0000000..3c0365e
--- /dev/null
+++ b/doc/verbatim/src/org/hsqldb/Tokens.java
@@ -0,0 +1,2302 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.OrderedIntHashSet;
+
+/**
+ * Defines and enumerates reserved and non-reserved SQL keywords.<p>
+ *
+ * @author  Nitin Chauhan (initial work)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class Tokens {
+
+    //
+    // SQL 200n reserved words full set
+    static final String        T_ABS              = "ABS";
+    public static final String T_ALL              = "ALL";
+    static final String        T_ALLOCATE         = "ALLOCATE";
+    public static final String T_ALTER            = "ALTER";
+    static final String        T_AND              = "AND";
+    static final String        T_ANY              = "ANY";
+    static final String        T_ARE              = "ARE";
+    public static final String T_ARRAY            = "ARRAY";
+    public static final String T_AS               = "AS";
+    static final String        T_ASENSITIVE       = "ASENSITIVE";
+    static final String        T_ASYMMETRIC       = "ASYMMETRIC";
+    static final String        T_AT               = "AT";
+    static final String        T_ATOMIC           = "ATOMIC";
+    public static final String T_AUTHORIZATION    = "AUTHORIZATION";
+    static final String        T_AVG              = "AVG";
+    static final String        T_BEGIN            = "BEGIN";
+    static final String        T_BETWEEN          = "BETWEEN";
+    public static final String T_BIGINT           = "BIGINT";
+    public static final String T_BINARY           = "BINARY";
+    static final String        T_BIT_LENGTH       = "BIT_LENGTH";
+    public static final String T_BLOB             = "BLOB";
+    public static final String T_BOOLEAN          = "BOOLEAN";
+    static final String        T_BOTH             = "BOTH";
+    static final String        T_BY               = "BY";
+    public static final String T_CALL             = "CALL";
+    static final String        T_CALLED           = "CALLED";
+    static final String        T_CARDINALITY      = "CARDINALITY";
+    public static final String T_CASCADED         = "CASCADED";
+    static final String        T_CASE             = "CASE";
+    static final String        T_CAST             = "CAST";
+    static final String        T_CEIL             = "CEIL";
+    static final String        T_CEILING          = "CEILING";
+    static final String        T_CHAR             = "CHAR";
+    static final String        T_CHAR_LENGTH      = "CHAR_LENGTH";
+    public static final String T_CHARACTER        = "CHARACTER";
+    static final String        T_CHARACTER_LENGTH = "CHARACTER_LENGTH";
+    public static final String T_CHECK            = "CHECK";
+    public static final String T_CLOB             = "CLOB";
+    static final String        T_CLOSE            = "CLOSE";
+    static final String        T_COALESCE         = "COALESCE";
+    static final String        T_COLLATE          = "COLLATE";
+    static final String        T_COLLECT          = "COLLECT";
+    static final String        T_COLUMN           = "COLUMN";
+    public static final String T_COMMIT           = "COMMIT";
+    static final String        T_CONDITION        = "CONDIITON";
+    public static final String T_CONNECT          = "CONNECT";
+    public static final String T_CONSTRAINT       = "CONSTRAINT";
+    static final String        T_CONVERT          = "CONVERT";
+    static final String        T_CORR             = "CORR";
+    static final String        T_CORRESPONDING    = "CORRESPONDING";
+    static final String        T_COUNT            = "COUNT";
+    static final String        T_COVAR_POP        = "COVAR_POP";
+    static final String        T_COVAR_SAMP       = "COVAR_SAMP";
+    public static final String T_CREATE           = "CREATE";
+    static final String        T_CROSS            = "CROSS";
+    static final String        T_CUBE             = "CUBE";
+    static final String        T_CUME_DIST        = "CUME_DIST";
+    static final String        T_CURRENT          = "CURRENT";
+    static final String        T_CURRENT_CATALOG  = "CURRENT_CATALOG";
+    static final String        T_CURRENT_DATE     = "CURRENT_DATE";
+    static final String T_CURRENT_DEFAULT_TRANSFORM_GROUP =
+        "CURRENT_DEFAULT_TRANSFORM_GROUP";
+    static final String T_CURRENT_PATH      = "CURRENT_PATH";
+    static final String T_CURRENT_ROLE      = "CURRENT_ROLE";
+    static final String T_CURRENT_SCHEMA    = "CURRENT_SCHEMA";
+    static final String T_CURRENT_TIME      = "CURRENT_TIME";
+    static final String T_CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP";
+    static final String T_CURRENT_TRANSFORM_GROUP_FOR_TYPE =
+        "CURRENT_TRANSFORM_GROUP_FOR_TYPE";
+    static final String        T_CURRENT_USER      = "CURRENT_USER";
+    static final String        T_CURSOR            = "CURSOR";
+    static final String        T_CYCLE             = "CYCLE";
+    public static final String T_DATE              = "DATE";
+    public static final String T_DAY               = "DAY";
+    static final String        T_DEALLOCATE        = "DEALLOCATE";
+    static final String        T_DEC               = "DEC";
+    public static final String T_DECIMAL           = "DECIMAL";
+    static final String        T_DECLARE           = "DECLARE";
+    public static final String T_DEFAULT           = "DEFAULT";
+    public static final String T_DELETE            = "DELETE";
+    static final String        T_DENSE_RANK        = "DENSE_RANK";
+    static final String        T_DEREF             = "DEREF";
+    static final String        T_DESCRIBE          = "DESCRIBE";
+    static final String        T_DETERMINISTIC     = "DETERMINISTIC";
+    static final String        T_DISCONNECT        = "DISCONNECT";
+    static final String        T_DISTINCT          = "DISTINCT";
+    public static final String T_DO                = "DO";
+    public static final String T_DOUBLE            = "DOUBLE";
+    static final String        T_DROP              = "DROP";
+    static final String        T_DYNAMIC           = "DYNAMIC";
+    static final String        T_EACH              = "EACH";
+    static final String        T_ELEMENT           = "ELEMENT";
+    static final String        T_ELSE              = "ELSE";
+    static final String        T_ELSEIF            = "ELSEIF";
+    static final String        T_END               = "END";
+    static final String        T_END_EXEC          = "END_EXEC";
+    static final String        T_ESCAPE            = "ESCAPE";
+    static final String        T_EVERY             = "EVERY";
+    static final String        T_EXCEPT            = "EXCEPT";
+    static final String        T_EXEC              = "EXEC";
+    public static final String T_EXECUTE           = "EXECUTE";
+    static final String        T_EXISTS            = "EXISTS";
+    static final String        T_EXP               = "EXP";
+    static final String        T_EXTERNAL          = "EXTERNAL";
+    static final String        T_EXTRACT           = "EXTRACT";
+    public static final String T_FALSE             = "FALSE";
+    static final String        T_FETCH             = "FETCH";
+    static final String        T_FILTER            = "FILTER";
+    static final String        T_FIRST_VALUE       = "FIRST_VALUE";
+    public static final String T_FLOAT             = "FLOAT";
+    static final String        T_FLOOR             = "FLOOR";
+    static final String        T_FOR               = "FOR";
+    public static final String T_FOREIGN           = "FOREIGN";
+    static final String        T_FREE              = "FREE";
+    static final String        T_FROM              = "FROM";
+    static final String        T_FULL              = "FULL";
+    public static final String T_FUNCTION          = "FUNCTION";
+    static final String        T_FUSION            = "FUSION";
+    public static final String T_GET               = "GET";
+    static final String        T_GLOBAL            = "GLOBAL";
+    public static final String T_GRANT             = "GRANT";
+    static final String        T_GROUP             = "GROUP";
+    static final String        T_GROUPING          = "GROUPING";
+    static final String        T_HANDLER           = "HANDLER";
+    static final String        T_HAVING            = "HAVING";
+    static final String        T_HOLD              = "HOLD";
+    public static final String T_HOUR              = "HOUR";
+    static final String        T_IDENTITY          = "IDENTITY";
+    static final String        T_IF                = "IF";
+    static final String        T_IMPORT            = "IMPORT";
+    static final String        T_IN                = "IN";
+    static final String        T_INDICATOR         = "INDICATOR";
+    static final String        T_INNER             = "INNER";
+    static final String        T_INOUT             = "INOUT";
+    static final String        T_INSENSITIVE       = "INSENSITIVE";
+    public static final String T_INSERT            = "INSERT";
+    static final String        T_INT               = "INT";
+    public static final String T_INTEGER           = "INTEGER";
+    static final String        T_INTERSECT         = "INTERSECT";
+    static final String        T_INTERSECTION      = "INTERSECTION";
+    public static final String T_INTERVAL          = "INTERVAL";
+    static final String        T_INTO              = "INTO";
+    static final String        T_ITERATE           = "ITERATE";
+    static final String        T_IS                = "IS";
+    static final String        T_JAR               = "JAR";              // SQL/JRT
+    static final String        T_JOIN              = "JOIN";
+    static final String        T_LAG               = "LAG";
+    public static final String T_LANGUAGE          = "LANGUAGE";
+    static final String        T_LARGE             = "LARGE";
+    static final String        T_LAST_VALUE        = "LAST_VALUE";
+    static final String        T_LATERAL           = "LATERAL";
+    static final String        T_LEAD              = "LEAD";
+    static final String        T_LEADING           = "LEADING";
+    static final String        T_LEAVE             = "LEAVE";
+    static final String        T_LEFT              = "LEFT";
+    static final String        T_LIKE              = "LIKE";
+    static final String        T_LIKE_REGX         = "LIKE_REGX";
+    static final String        T_LN                = "LN";
+    public static final String T_LOCAL             = "LOCAL";
+    static final String        T_LOCALTIME         = "LOCALTIME";
+    static final String        T_LOCALTIMESTAMP    = "LOCALTIMESTAMP";
+    public static final String T_LOOP              = "LOOP";
+    static final String        T_LOWER             = "LOWER";
+    static final String        T_MATCH             = "MATCH";
+    static final String        T_MAX               = "MAX";
+    static final String        T_MAX_CARDINALITY   = "MAX_CARDINALITY";
+    static final String        T_MEMBER            = "MEMBER";
+    static final String        T_MERGE             = "MERGE";
+    static final String        T_METHOD            = "METHOD";
+    static final String        T_MIN               = "MIN";
+    public static final String T_MINUTE            = "MINUTE";
+    static final String        T_MOD               = "MOD";
+    static final String        T_MODIFIES          = "MODIFIES";
+    static final String        T_MODULE            = "MODULE";
+    public static final String T_MONTH             = "MONTH";
+    public static final String T_MULTISET          = "MULTISET";
+    static final String        T_NATIONAL          = "NATIONAL";
+    static final String        T_NATURAL           = "NATURAL";
+    static final String        T_NCHAR             = "NCHAR";
+    static final String        T_NCLOB             = "NCLOB";
+    static final String        T_NEW               = "NEW";
+    public static final String T_NO                = "NO";
+    public static final String T_NONE              = "NONE";
+    static final String        T_NORMALIZE         = "NORMALIZE";
+    static final String        T_NOT               = "NOT";
+    static final String        T_NTH_VALUE         = "NTH_VALUE";
+    static final String        T_NTILE             = "NTILE";
+    public static final String T_NULL              = "NULL";
+    public static final String T_NULLIF            = "NULLIF";
+    public static final String T_NUMERIC           = "NUMERIC";
+    static final String        T_OCCURRENCES_REGEX = "OCCURRENCES_REGEX";
+    static final String        T_OCTET_LENGTH      = "OCTET_LENGTH";
+    static final String        T_OF                = "OF";
+    static final String        T_OFFSET            = "OFFSET";
+    static final String        T_OLD               = "OLD";
+    public static final String T_ON                = "ON";
+    public static final String T_ONLY              = "ONLY";
+    static final String        T_OPEN              = "OPEN";
+    static final String        T_OR                = "OR";
+    static final String        T_ORDER             = "ORDER";
+    static final String        T_OUT               = "OUT";
+    static final String        T_OUTER             = "OUTER";
+    static final String        T_OVER              = "OVER";
+    static final String        T_OVERLAPS          = "OVERLAPS";
+    static final String        T_OVERLAY           = "OVERLAY";
+    static final String        T_PARAMETER         = "PARAMETER";
+    static final String        T_PARTITION         = "PARTITION";
+    static final String        T_PERCENT_RANK      = "PERCENT_RANK";
+    static final String        T_PERCENTILE_CONT   = "PERCENTILE_CONT";
+    static final String        T_PERCENTILE_DISC   = "PERCENTILE_DISC";
+    static final String        T_POSITION          = "POSITION";
+    static final String        T_POSITION_REGEX    = "POSITION_REGEX";
+    static final String        T_POWER             = "POWER";
+    static final String        T_PRECISION         = "PRECISION";
+    static final String        T_PREPARE           = "PREPARE";
+    static final String        T_PRIMARY           = "PRIMARY";
+    public static final String T_PROCEDURE         = "PROCEDURE";
+    static final String        T_RANGE             = "RANGE";
+    static final String        T_RANK              = "RANK";
+    static final String        T_READS             = "READS";
+    public static final String T_REAL              = "REAL";
+    static final String        T_RECURSIVE         = "RECURSIVE";
+    static final String        T_REF               = "REF";
+    public static final String T_REFERENCES        = "REFERENCES";
+    static final String        T_REFERENCING       = "REFERENCING";
+    static final String        T_REGR_AVGX         = "REGR_AVGX";
+    static final String        T_REGR_AVGY         = "REGR_AVGY";
+    static final String        T_REGR_COUNT        = "REGR_COUNT";
+    static final String        T_REGR_INTERCEPT    = "REGR_INTERCEPT";
+    static final String        T_REGR_R2           = "REGR_R2";
+    static final String        T_REGR_SLOPE        = "REGR_SLOPE";
+    static final String        T_REGR_SXX          = "REGR_SXX";
+    static final String        T_REGR_SXY          = "REGR_SXY";
+    static final String        T_REGR_SYY          = "REGR_SYY";
+    static final String        T_RELEASE           = "RELEASE";
+    static final String        T_REPEAT            = "REPEAT";
+    static final String        T_RESIGNAL          = "RESIGNAL";
+    public static final String T_RESULT            = "RESULT";
+    static final String        T_RETURN            = "RETURN";
+    static final String        T_RETURNS           = "RETURNS";
+    static final String        T_REVOKE            = "REVOKE";
+    static final String        T_RIGHT             = "RIGHT";
+    static final String        T_ROLLBACK          = "ROLLBACK";
+    static final String        T_ROLLUP            = "ROLLUP";
+    public static final String T_ROW               = "ROW";
+    static final String        T_ROW_NUMBER        = "ROW_NUMBER";
+    public static final String T_ROWS              = "ROWS";
+    static final String        T_SAVEPOINT         = "SAVEPOINT";
+    static final String        T_SCOPE             = "SCOPE";
+    static final String        T_SCROLL            = "SCROLL";
+    static final String        T_SEARCH            = "SEARCH";
+    public static final String T_SECOND            = "SECOND";
+    public static final String T_SELECT            = "SELECT";
+    static final String        T_SENSITIVE         = "SENSITIVE";
+    static final String        T_SESSION_USER      = "SESSION_USER";
+    public static final String T_SET               = "SET";
+    static final String        T_SIGNAL            = "SIGNAL";
+    static final String        T_SIMILAR           = "SIMILAR";
+    public static final String T_SMALLINT          = "SMALLINT";
+    static final String        T_SOME              = "SOME";
+    public static final String T_SPECIFIC          = "SPECIFIC";
+    static final String        T_SPECIFICTYPE      = "SPECIFICTYPE";
+    public static final String T_SQL               = "SQL";
+    static final String        T_SQLEXCEPTION      = "SQLEXCEPTION";
+    static final String        T_SQLSTATE          = "SQLSTATE";
+    static final String        T_SQLWARNING        = "SQLWARNING";
+    static final String        T_SQRT              = "SQRT";
+    static final String        T_START             = "START";
+    static final String        T_STATIC            = "STATIC";
+    static final String        T_STDDEV_POP        = "STDDEV_POP";
+    static final String        T_STDDEV_SAMP       = "STDDEV_SAMP";
+    static final String        T_SUBMULTISET       = "SUBMULTISET";
+    static final String        T_SUBSTRING         = "SUBSTRING";
+    static final String        T_SUBSTRING_REGEX   = "SUBSTRING_REGEX";
+    static final String        T_SUM               = "SUM";
+    static final String        T_SYMMETRIC         = "SYMMETRIC";
+    static final String        T_SYSTEM            = "SYSTEM";
+    static final String        T_SYSTEM_USER       = "SYSTEM_USER";
+    public static final String T_TABLE             = "TABLE";
+    static final String        T_TABLESAMPLE       = "TABLESAMPLE";
+    static final String        T_THEN              = "THEN";
+    public static final String T_TIME              = "TIME";
+    public static final String T_TIMESTAMP         = "TIMESTAMP";
+    public static final String T_TIMEZONE_HOUR     = "TIMEZONE_HOUR";
+    public static final String T_TIMEZONE_MINUTE   = "TIMEZONE_MINUTE";
+    public static final String T_TO                = "TO";
+    static final String        T_TRAILING          = "TRAILING";
+    static final String        T_TRANSLATE         = "TRANSLATE";
+    static final String        T_TRANSLATE_REGEX   = "TRANSLATE_REGEX";
+    static final String        T_TRANSLATION       = "TRANSLATION";
+    static final String        T_TREAT             = "TREAT";
+    public static final String T_TRIGGER           = "TRIGGER";
+    static final String        T_TRIM              = "TRIM";
+    static final String        T_TRIM_ARRAY        = "TRIM_ARRAY";
+    public static final String T_TRUE              = "TRUE";
+    static final String        T_TRUNCATE          = "TRUNCATE";
+    static final String        T_UESCAPE           = "UESCAPE";
+    static final String        T_UNION             = "UNION";
+    public static final String T_UNIQUE            = "UNIQUE";
+    public static final String T_UNKNOWN           = "UNKNOWN";
+    static final String        T_UNNEST            = "UNNEST";
+    static final String        T_UNTIL             = "UNTIL";
+    public static final String T_UPDATE            = "UPDATE";
+    static final String        T_UPPER             = "UPPER";
+    public static final String T_USER              = "USER";
+    static final String        T_USING             = "USING";
+    static final String        T_VALUE             = "VALUE";
+    static final String        T_VALUES            = "VALUES";
+    static final String        T_VAR_POP           = "VAR_POP";
+    static final String        T_VAR_SAMP          = "VAR_SAMP";
+    public static final String T_VARBINARY         = "VARBINARY";
+    public static final String T_VARCHAR           = "VARCHAR";
+    static final String        T_VARYING           = "VARYING";
+    static final String        T_WHEN              = "WHEN";
+    static final String        T_WHENEVER          = "WHENEVER";
+    static final String        T_WHERE             = "WHERE";
+    public static final String T_WHILE             = "WHILE";
+    static final String        T_WIDTH_BUCKET      = "WIDTH_BUCKET";
+    static final String        T_WINDOW            = "WINDOW";
+    public static final String T_WITH              = "WITH";
+    static final String        T_WITHIN            = "WITHIN";
+    static final String        T_WITHOUT           = "WITHOUT";
+    public static final String T_YEAR              = "YEAR";
+
+    // ops
+    static final String        T_ASTERISK       = "*";
+    public static final String T_COMMA          = ",";
+    static final String        T_CIRCUMFLEX     = "^";
+    static final String        T_CLOSEBRACKET   = ")";
+    static final String        T_COLON          = ":";
+    static final String        T_CONCAT         = "||";
+    public static final String T_DIVIDE         = "/";
+    static final String        T_EQUALS         = "=";
+    static final String        T_GREATER        = ">";
+    static final String        T_GREATER_EQUALS = ">=";
+    public static final String T_LEFTBRACKET    = "[";
+    static final String        T_LESS           = "<";
+    static final String        T_LESS_EQUALS    = "<=";
+    static final String        T_PERCENT        = "%";
+    static final String        T_PLUS           = "+";
+    static final String        T_MINUS          = "-";
+    static final String        T_NOT_EQUALS     = "<>";
+    static final String        T_NOT_EQUALS_ALT = "!=";
+    static final String        T_OPENBRACKET    = "(";
+    static final String        T_QUESTION       = "?";
+    public static final String T_RIGHTBRACKET   = "]";
+    static final String        T_SEMICOLON      = ";";
+    static final String        T_DOUBLE_COLON   = "::";
+
+    // SQL:200n non-reserved word list
+    static final String        T_A                    = "A";
+    static final String        T_ABSOLUTE             = "ABSOLUTE";
+    static final String        T_ACTION               = "ACTION";
+    static final String        T_ADA                  = "ADA";
+    static final String        T_ADMIN                = "ADMIN";
+    static final String        T_AFTER                = "AFTER";
+    static final String        T_ALWAYS               = "ALWAYS";
+    static final String        T_ASC                  = "ASC";
+    static final String        T_ASSERTION            = "ASSERTION";
+    static final String        T_ASSIGNMENT           = "ASSIGNMENT";
+    static final String        T_ATTRIBUTE            = "ATTRIBUTE";
+    static final String        T_ATTRIBUTES           = "ATTRIBUTES";
+    static final String        T_BEFORE               = "BEFORE";
+    static final String        T_BERNOULLI            = "BERNOULLI";
+    static final String        T_BREADTH              = "BREADTH";
+    static final String        T_C                    = "C";
+    static final String        T_CASCADE              = "CASCADE";
+    public static final String T_CATALOG              = "CATALOG";
+    public static final String T_CATALOG_NAME         = "CATALOG_NAME";
+    static final String        T_CHAIN                = "CHAIN";
+    static final String T_CHARACTER_SET_CATALOG = "CHARACTER_SET_CATALOG";
+    static final String        T_CHARACTER_SET_NAME   = "CHARACTER_SET_NAME";
+    static final String        T_CHARACTER_SET_SCHEMA = "CHARACTER_SET_SCHEMA";
+    static final String        T_CHARACTERISTICS      = "CHARACTERISTICS";
+    static final String        T_CHARACTERS           = "CHARACTERS";
+    static final String        T_CLASS_ORIGIN         = "CLASS_ORIGIN";
+    static final String        T_COBOL                = "COBOL";
+    static final String        T_COLLATION            = "COLLATION";
+    static final String        T_COLLATION_CATALOG    = "COLLATION_CATALOG";
+    static final String        T_COLLATION_NAME       = "COLLATION_NAME";
+    static final String        T_COLLATION_SCHEMA     = "COLLATION_SCHEMA";
+    static final String        T_COLUMN_NAME          = "COLUMN_NAME";
+    static final String        T_COMMAND_FUNCTION     = "COMMAND_FUNCTION";
+    static final String T_COMMAND_FUNCTION_CODE = "COMMAND_FUNCTION_CODE";
+    public static final String T_COMMITTED            = "COMMITTED";
+    static final String        T_COMPARABLE           = "COMPARABLE";    // SQL/JRT
+    static final String        T_CONDITION_IDENTIFIER = "CONDIITON_IDENTIFIER";
+    static final String        T_CONDITION_NUMBER     = "CONDITION_NUMBER";
+    static final String        T_CONNECTION_NAME      = "CONNECTION_NAME";
+    static final String        T_CONSTRAINT_CATALOG   = "CONSTRAINT_CATALOG";
+    static final String        T_CONSTRAINT_NAME      = "CONSTRAINT_NAME";
+    static final String        T_CONSTRAINT_SCHEMA    = "CONSTRAINT_SCHEMA";
+    static final String        T_CONSTRAINTS          = "CONSTRAINTS";
+    static final String        T_CONSTRUCTOR          = "CONSTRUCTOR";
+    static final String        T_CONTAINS             = "CONTAINS";
+    static final String        T_CONTINUE             = "CONTINUE";
+    static final String        T_CURRENT_COLLATION    = "CURRENT_COLLATION";
+    static final String        T_CURSOR_NAME          = "CURSOR_NAME";
+    public static final String T_DATA                 = "DATA";
+    static final String T_DATETIME_INTERVAL_CODE = "DATETIME_INTERVAL_CODE";
+    static final String T_DATETIME_INTERVAL_PRECISION =
+        "DATETIME_INTERVAL_PRECISION";
+    public static final String T_DEFAULTS             = "DEFAULTS";
+    static final String        T_DEFERRABLE           = "DEFERRABLE";
+    static final String        T_DEFERRED             = "DEFERRED";
+    static final String        T_DEFINED              = "DEFINED";
+    static final String        T_DEFINER              = "DEFINER";
+    static final String        T_DEGREE               = "DEGREE";
+    static final String        T_DEPTH                = "DEPTH";
+    static final String        T_DERIVED              = "DERIVED";
+    static final String        T_DESC                 = "DESC";
+    static final String        T_DESCRIPTOR           = "DESCRIPTOR";
+    static final String        T_DIAGNOSTICS          = "DIAGNOSTICS";
+    static final String        T_DISPATCH             = "DISPATCH";
+    public static final String T_DOMAIN               = "DOMAIN";
+    static final String        T_DYNAMIC_FUNCTION     = "DYNAMIC_FUNCTION";
+    static final String T_DYNAMIC_FUNCTION_CODE = "DYNAMIC_FUNCTION_CODE";
+    static final String        T_EXCEPTION            = "EXCEPTION";
+    static final String        T_EXCLUDE              = "EXCLUDE";
+    static final String        T_EXCLUDING            = "EXCLUDING";
+    static final String        T_EXIT                 = "EXIT";
+    static final String        T_FINAL                = "FINAL";
+    static final String        T_FIRST                = "FIRST";
+    static final String        T_FOLLOWING            = "FOLLOWING";
+    static final String        T_FORTRAN              = "FORTRAN";
+    static final String        T_FOUND                = "FOUND";
+    public static final String T_G_FACTOR             = "G";
+    static final String        T_GENERAL              = "GENERAL";
+    static final String        T_GO                   = "GO";
+    static final String        T_GOTO                 = "GOTO";
+    static final String        T_GRANTED              = "GRANTED";
+    static final String        T_HIERARCHY            = "HIERARCHY";
+    static final String        T_IMPLEMENTATION       = "IMPLEMENTATION";
+    static final String        T_INCLUDING            = "INCLUDING";
+    public static final String T_INCREMENT            = "INCREMENT";
+    static final String        T_INITIALLY            = "INITIALLY";
+    static final String        T_INPUT                = "INPUT";
+    static final String        T_INSTANCE             = "INSTANCE";
+    static final String        T_INSTANTIABLE         = "INSTANTIABLE";
+    static final String        T_INSTEAD              = "INSTEAD";
+    static final String        T_INTERFACE            = "INTERFACE";     // SQL/JRT
+    static final String        T_INVOKER              = "INVOKER";
+    public static final String T_ISOLATION            = "ISOLATION";
+    public static final String T_JAVA                 = "JAVA";          // SQL/JRT
+    public static final String T_K_FACTOR             = "K";
+    static final String        T_KEY                  = "KEY";
+    static final String        T_KEY_MEMBER           = "KEY_MEMBER";
+    static final String        T_KEY_TYPE             = "KEY_TYPE";
+    static final String        T_LAST                 = "LAST";
+    static final String        T_LENGTH               = "LENGTH";
+    public static final String T_LEVEL                = "LEVEL";
+    public static final String T_LIBRARY              = "LIBRARY";
+    static final String        T_LOCATOR              = "LOCATOR";
+    public static final String T_M_FACTOR             = "M";
+    static final String        T_MAP                  = "MAP";
+    static final String        T_MATCHED              = "MATCHED";
+    static final String        T_MAXVALUE             = "MAXVALUE";
+    static final String        T_MESSAGE_LENGTH       = "MESSAGE_LENGTH";
+    static final String        T_MESSAGE_OCTET_LENGTH = "MESSAGE_OCTET_LENGTH";
+    static final String        T_MESSAGE_TEXT         = "MESSAGE_TEXT";
+    static final String        T_MINVALUE             = "MINVALUE";
+    static final String        T_MORE                 = "MORE";
+    static final String        T_MUMPS                = "MUMPS";
+    public static final String T_NAME                 = "NAME";
+    public static final String T_NAMES                = "NAMES";
+    static final String        T_NESTING              = "NESTING";
+    static final String        T_NEXT                 = "NEXT";
+    static final String        T_NORMALIZED           = "NORMALIZED";
+    static final String        T_NULLABLE             = "NULLABLE";
+    public static final String T_NULLS                = "NULLS";
+    static final String        T_NUMBER               = "NUMBER";
+    public static final String T_OBJECT               = "OBJECT";
+    static final String        T_OCTETS               = "OCTETS";
+    static final String        T_OPTION               = "OPTION";
+    static final String        T_OPTIONS              = "OPTIONS";
+    static final String        T_ORDERING             = "ORDERING";
+    static final String        T_ORDINALITY           = "ORDINALITY";
+    static final String        T_OTHERS               = "OTHERS";
+    public static final String T_OVERRIDING           = "OVERRIDING";
+    public static final String T_P_FACTOR             = "P";
+    static final String        T_PAD                  = "PAD";
+    static final String        T_PARAMETER_MODE       = "PARAMETER_MODE";
+    static final String        T_PARAMETER_NAME       = "PARAMETER_NAME";
+    static final String T_PARAMETER_ORDINAL_POSITION =
+        "PARAMETER_ORDINAL_POSITION";
+    static final String T_PARAMETER_SPECIFIC_CATALOG =
+        "PARAMETER_SPECIFIC_CATALOG";
+    static final String T_PARAMETER_SPEC_NAME = "PARAMETER_SPECIFIC_NAME";
+    static final String T_PARAMETER_SPEC_SCHEMA = "PARAMETER_SPECIFIC_SCHEMA";
+    static final String        T_PARTIAL              = "PARTIAL";
+    static final String        T_PASCAL               = "PASCAL";
+    public static final String T_PATH                 = "PATH";
+    static final String        T_PLACING              = "PLACING";
+    static final String        T_PLI                  = "PLI";
+    static final String        T_PRECEDING            = "PRECEDING";
+    static final String        T_PRESERVE             = "PRESERVE";
+    static final String        T_PRIOR                = "PRIOR";
+    static final String        T_PRIVILEGES           = "PRIVILEGES";
+    public static final String T_PUBLIC               = "PUBLIC";
+    public static final String T_READ                 = "READ";
+    static final String        T_RELATIVE             = "RELATIVE";
+    static final String        T_REPEATABLE           = "REPEATABLE";
+    static final String        T_RESTART              = "RESTART";
+    static final String        T_RETURNED_CARDINALITY = "RETURNED_CARDINALITY";
+    static final String        T_RETURNED_LENGTH      = "RETURNED_LENGTH";
+    static final String T_RETURNED_OCTET_LENGTH = "RETURNED_OCTET_LENGTH";
+    static final String        T_RETURNED_SQLSTATE    = "RETURNED_SQLSTATE";
+    public static final String T_ROLE                 = "ROLE";
+    public static final String T_ROUTINE              = "ROUTINE";
+    static final String        T_ROUTINE_CATALOG      = "ROUTINE_CATALOG";
+    static final String        T_ROUTINE_NAME         = "ROUTINE_NAME";
+    static final String        T_ROUTINE_SCHEMA       = "ROUTINE_SCHEMA";
+    static final String        T_ROW_COUNT            = "ROW_COUNT";
+    public static final String T_SCALE                = "SCALE";
+    public static final String T_SCHEMA               = "SCHEMA";
+    static final String        T_SCHEMA_NAME          = "SCHEMA_NAME";
+    static final String        T_SCOPE_CATALOG        = "SCOPE_CATALOG";
+    static final String        T_SCOPE_NAME           = "SCOPE_NAME";
+    static final String        T_SCOPE_SCHEMA         = "SCOPE_SCHEMA";
+    static final String        T_SECTION              = "SECTION";
+    static final String        T_SECURITY             = "SECURITY";
+    static final String        T_SELF                 = "SELF";
+    public static final String T_SEQUENCE             = "SEQUENCE";
+    public static final String T_SERIALIZABLE         = "SERIALIZABLE";
+    public static final String T_SERVER               = "SERVER";
+    static final String        T_SERVER_NAME          = "SERVER_NAME";
+    public static final String T_SESSION              = "SESSION";
+    static final String        T_SETS                 = "SETS";
+    static final String        T_SIMPLE               = "SIMPLE";
+    public static final String T_SIZE                 = "SIZE";
+    static final String        T_SOURCE               = "SOURCE";
+    static final String        T_SPACE                = "SPACE";
+    static final String        T_SPECIFIC_NAME        = "SPECIFIC_NAME";
+    static final String        T_SQLDATA              = "SQLDATA";       // SQL/JRT
+    static final String        T_STACKED              = "STACKED";
+    static final String        T_STATE                = "STATE";
+    static final String        T_STATEMENT            = "STATEMENT";
+    static final String        T_STRUCTURE            = "STRUCTURE";
+    static final String        T_STYLE                = "STYLE";
+    static final String        T_SUBCLASS_ORIGIN      = "SUBCLASS_ORIGIN";
+    public static final String T_T_FACTOR             = "T";
+    static final String        T_TABLE_NAME           = "TABLE_NAME";
+    static final String        T_TEMPORARY            = "TEMPORARY";
+    static final String        T_TIES                 = "TIES";
+    static final String        T_TOP_LEVEL_COUNT      = "TOP_LEVEL_COUNT";
+    public static final String T_TRANSACTION          = "TRANSACTION";
+    static final String        T_TRANSACT_COMMITTED = "TRANSACTIONS_COMMITTED";
+    static final String T_TRANSACTION_ROLLED_BACK = "TRANSACTIONS_ROLLED_BACK";
+    static final String        T_TRANSACT_ACTIVE      = "TRANSACTION_ACTIVE";
+    static final String        T_TRANSFORM            = "TRANSFORM";
+    static final String        T_TRANSFORMS           = "TRANSFORMS";
+    static final String        T_TRIGGER_CATALOG      = "TRIGGER_CATALOG";
+    static final String        T_TRIGGER_NAME         = "TRIGGER_NAME";
+    static final String        T_TRIGGER_SCHEMA       = "TRIGGER_SCHEMA";
+    public static final String T_TYPE                 = "TYPE";
+    static final String        T_UNBOUNDED            = "UNBOUNDED";
+    static final String        T_UNCOMMITTED          = "UNCOMMITTED";
+    static final String        T_UNDER                = "UNDER";
+    static final String        T_UNDO                 = "UNDO";
+    static final String        T_UNNAMED              = "UNNAMED";
+    public static final String T_USAGE                = "USAGE";
+    static final String T_USER_DEFINED_TYPE_CATALOG =
+        "USER_DEFINED_TYPE_CATALOG";
+    static final String T_USER_DEFINED_TYPE_CODE = "USER_DEFINED_TYPE_CODE";
+    static final String T_USER_DEFINED_TYPE_NAME = "USER_DEFINED_TYPE_NAME";
+    static final String T_USER_DEFINED_TYPE_SCHEMA =
+        "USER_DEFINED_TYPE_SCHEMA";
+    static final String        T_VIEW    = "VIEW";
+    static final String        T_WORK    = "WORK";
+    public static final String T_WRAPPER = "WRAPPER";
+    public static final String T_WRITE   = "WRITE";
+    public static final String T_ZONE    = "ZONE";
+
+    // other tokens
+    static final String        T_ADD                 = "ADD";
+    static final String        T_ALIAS               = "ALIAS";
+    static final String        T_AGGREGATE           = "AGGREGATE";
+    static final String        T_AUTOCOMMIT          = "AUTOCOMMIT";
+    public static final String T_BACKUP              = "BACKUP";
+    public static final String T_BIT                 = "BIT";
+    static final String        T_BITLENGTH           = "BITLENGTH";
+    public static final String T_CACHE               = "CACHE";
+    static final String        T_CACHED              = "CACHED";
+    static final String        T_CASEWHEN            = "CASEWHEN";
+    static final String        T_CHECKPOINT          = "CHECKPOINT";
+    static final String        T_CLASS               = "CLASS";
+    static final String        T_COMMENT             = "COMMENT";
+    static final String        T_COMPACT             = "COMPACT";
+    public static final String T_COMPRESSED          = "COMPRESSED";
+    public static final String T_CONTROL             = "CONTROL";
+    static final String        T_CURDATE             = "CURDATE";
+    static final String        T_CURTIME             = "CURTIME";
+    public static final String T_DATABASE            = "DATABASE";
+    public static final String T_DEFRAG              = "DEFRAG";
+    public static final String T_DELAY               = "DELAY";
+    static final String        T_EXPLAIN             = "EXPLAIN";
+    public static final String T_EVENT               = "EVENT";
+    static final String        T_FILE                = "FILE";
+    public static final String T_FILES               = "FILES";
+    static final String        T_FOLD                = "FOLD";
+    static final String        T_GENERATED           = "GENERATED";
+    static final String        T_HEADER              = "HEADER";
+    static final String        T_IFNULL              = "IFNULL";
+    static final String        T_IGNORECASE          = "IGNORECASE";
+    static final String        T_IMMEDIATELY         = "IMMEDIATELY";
+    public static final String T_INDEX               = "INDEX";
+    public static final String T_INITIAL             = "INITIAL";
+    public static final String T_INTEGRITY           = "INTEGRITY";
+    static final String        T_ISAUTOCOMMIT        = "ISAUTOCOMMIT";
+    static final String        T_ISREADONLYDATABASE  = "ISREADONLYDATABASE";
+    static final String T_ISREADONLYDATABASEFILES = "ISREADONLYDATABASEFILES";
+    static final String        T_ISREADONLYSESSION   = "ISREADONLYSESSION";
+    static final String        T_LIMIT               = "LIMIT";
+    public static final String T_LOB                 = "LOB";
+    public static final String T_LOCK                = "LOCK";
+    public static final String T_LOCKS               = "LOCKS";
+    static final String        T_MAXROWS             = "MAXROWS";
+    public static final String T_MEMORY              = "MEMORY";
+    public static final String T_MILLIS              = "MILLIS";
+    static final String        T_MINUS_EXCEPT        = "MINUS";
+    public static final String T_MVCC                = "MVCC";
+    public static final String T_MVLOCKS             = "MVLOCKS";
+    public static final String T_NIO                 = "NIO";
+    static final String        T_NOWAIT              = "NOWAIT";
+    static final String        T_NVL                 = "NVL";
+    static final String        T_OCTETLENGTH         = "OCTETLENGTH";
+    static final String        T_OFF                 = "OFF";
+    public static final String T_OTHER               = "OTHER";
+    public static final String T_PASSWORD            = "PASSWORD";
+    static final String        T_PLAN                = "PLAN";
+    static final String        T_PROPERTY            = "PROPERTY";
+    static final String        T_QUEUE               = "QUEUE";
+    static final String        T_READONLY            = "READONLY";
+    static final String        T_REFERENTIAL         = "REFERENTIAL";
+    static final String        T_RENAME              = "RENAME";
+    static final String        T_RESTRICT            = "RESTRICT";
+    static final String        T_SCRIPT              = "SCRIPT";
+    static final String        T_SCRIPTFORMAT        = "SCRIPTFORMAT";
+    static final String        T_BLOCKING            = "BLOCKING";
+    static final String        T_SHUTDOWN            = "SHUTDOWN";
+    static final String        T_SQL_TSI_DAY         = "SQL_TSI_DAY";
+    static final String        T_SQL_TSI_FRAC_SECOND = "SQL_TSI_FRAC_SECOND";
+    static final String        T_SQL_TSI_HOUR        = "SQL_TSI_HOUR";
+    static final String        T_SQL_TSI_MINUTE      = "SQL_TSI_MINUTE";
+    static final String        T_SQL_TSI_MONTH       = "SQL_TSI_MONTH";
+    static final String        T_SQL_TSI_QUARTER     = "SQL_TSI_QUARTER";
+    static final String        T_SQL_TSI_SECOND      = "SQL_TSI_SECOND";
+    static final String        T_SQL_TSI_WEEK        = "SQL_TSI_WEEK";
+    static final String        T_SQL_TSI_YEAR        = "SQL_TSI_YEAR";
+    static final String        T_SQL_BIGINT          = "SQL_BIGINT";
+    static final String        T_SQL_BINARY          = "SQL_BINARY";
+    static final String        T_SQL_BIT             = "SQL_BIT";
+    static final String        T_SQL_BLOB            = "SQL_BLOB";
+    static final String        T_SQL_BOOLEAN         = "SQL_BOOLEAN";
+    static final String        T_SQL_CHAR            = "SQL_CHAR";
+    static final String        T_SQL_CLOB            = "SQL_CLOB";
+    static final String        T_SQL_DATE            = "SQL_DATE";
+    static final String        T_SQL_DECIMAL         = "SQL_DECIMAL";
+    static final String        T_SQL_DATALINK        = "SQL_DATALINK";
+    static final String        T_SQL_DOUBLE          = "SQL_DOUBLE";
+    static final String        T_SQL_FLOAT           = "SQL_FLOAT";
+    static final String        T_SQL_INTEGER         = "SQL_INTEGER";
+    static final String        T_SQL_LONGVARBINARY   = "SQL_LONGVARBINARY";
+    static final String        T_SQL_LONGNVARCHAR    = "SQL_LONGNVARCHAR";
+    static final String        T_SQL_LONGVARCHAR     = "SQL_LONGVARCHAR";
+    static final String        T_SQL_NCHAR           = "SQL_NCHAR";
+    static final String        T_SQL_NCLOB           = "SQL_NCLOB";
+    static final String        T_SQL_NUMERIC         = "SQL_NUMERIC";
+    static final String        T_SQL_NVARCHAR        = "SQL_NVARCHAR";
+    static final String        T_SQL_REAL            = "SQL_REAL";
+    static final String        T_SQL_ROWID           = "SQL_ROWID";
+    static final String        T_SQL_SQLXML          = "SQL_SQLXML";
+    static final String        T_SQL_SMALLINT        = "SQL_SMALLINT";
+    static final String        T_SQL_TIME            = "SQL_TIME";
+    static final String        T_SQL_TIMESTAMP       = "SQL_TIMESTAMP";
+    static final String        T_SQL_TINYINT         = "SQL_TINYINT";
+    static final String        T_SQL_VARBINARY       = "SQL_VARBINARY";
+    static final String        T_SQL_VARCHAR         = "SQL_VARCHAR";
+    public static final String T_TEMP                = "TEMP";
+    public static final String T_TEXT                = "TEXT";
+    static final String        T_TIMESTAMPADD        = "TIMESTAMPADD";
+    static final String        T_TIMESTAMPDIFF       = "TIMESTAMPDIFF";
+    public static final String T_TINYINT             = "TINYINT";
+    static final String        T_TO_CHAR             = "TO_CHAR";
+    static final String        T_TODAY               = "TODAY";
+    static final String        T_TOP                 = "TOP";
+    public static final String T_VARCHAR_IGNORECASE  = "VARCHAR_IGNORECASE";
+    static final String        T_WRITE_DELAY         = "WRITE_DELAY";
+    public static final String T_YES                 = "YES";
+
+    //
+    public static final String T_DAY_NAME     = "DAY_NAME";
+    public static final String T_MONTH_NAME   = "MONTH_NAME";
+    public static final String T_QUARTER      = "QUARTER";
+    public static final String T_DAY_OF_WEEK  = "DAY_OF_WEEK";
+    public static final String T_DAY_OF_MONTH = "DAY_OF_MONTH";
+    public static final String T_DAY_OF_YEAR  = "DAY_OF_YEAR";
+    public static final String T_WEEK_OF_YEAR = "WEEK_OF_YEAR";
+    static final String        T_DAYNAME      = "DAYNAME";
+    static final String        T_MONTHNAME    = "MONTHNAME";
+    static final String        T_DAYOFMONTH   = "DAYOFMONTH";
+    static final String        T_DAYOFWEEK    = "DAYOFWEEK";
+    static final String        T_DAYOFYEAR    = "DAYOFYEAR";
+    static final String        T_WEEK         = "WEEK";
+
+    //
+    static final String        T_ACOS             = "ACOS";
+    static final String        T_ASCII            = "ASCII";
+    static final String        T_ASIN             = "ASIN";
+    static final String        T_ATAN             = "ATAN";
+    static final String        T_ATAN2            = "ATAN2";
+    static final String        T_BITAND           = "BITAND";
+    static final String        T_BITOR            = "BITOR";
+    static final String        T_BITXOR           = "BITXOR";
+    static final String        T_CONCAT_WORD      = "CONCAT";
+    static final String        T_COS              = "COS";
+    static final String        T_COT              = "COT";
+    static final String        T_CRYPT_KEY        = "CRYPT_KEY";
+    static final String        T_DATEADD          = "DATEADD";
+    static final String        T_DATEDIFF         = "DATEDIFF";
+    static final String        T_DECODE           = "DECODE";
+    static final String        T_DEGREES          = "DEGREES";
+    static final String        T_DIFFERENCE       = "DIFFERENCE";
+    static final String        T_DMOD             = "DMOD";
+    public static final String T_GC               = "GC";
+    static final String        T_GREATEST         = "GREATEST";
+    static final String        T_HEXTORAW         = "HEXTORAW";
+    static final String        T_LCASE            = "LCASE";
+    static final String        T_LEAST            = "LEAST";
+    static final String        T_LOCATE           = "LOCATE";
+    public static final String T_LOG              = "LOG";
+    static final String        T_LOG10            = "LOG10";
+    static final String        T_LTRIM            = "LTRIM";
+    static final String        T_NOW              = "NOW";
+    static final String        T_PI               = "PI";
+    static final String        T_RADIANS          = "RADIANS";
+    static final String        T_RAND             = "RAND";
+    static final String        T_RAWTOHEX         = "RAWTOHEX";
+    public static final String T_REGEXP_MATCHES   = "REGEXP_MATCHES";
+    static final String        T_REPLACE          = "REPLACE";
+    static final String        T_REVERSE          = "REVERSE";
+    static final String        T_ROUND            = "ROUND";
+    static final String        T_ROUNDMAGIC       = "ROUNDMAGIC";
+    static final String        T_RTRIM            = "RTRIM";
+    public static final String T_SECONDS_MIDNIGHT = "SECONDS_SINCE_MIDNIGHT";
+    static final String        T_SIGN             = "SIGN";
+    static final String        T_SIN              = "SIN";
+    static final String        T_SOUNDEX          = "SOUNDEX";
+    static final String        T_SUBSTR           = "SUBSTR";
+    static final String        T_SYSDATE          = "SYSDATE";
+    static final String        T_TAN              = "TAN";
+    static final String        T_UCASE            = "UCASE";
+
+    //
+    static final String T_ISOLATION_LEVEL         = "ISOLATION_LEVEL";
+    static final String T_SESSION_ISOLATION_LEVEL = "SESSION_ISOLATION_LEVEL";
+    static final String T_DATABASE_ISOLATION_LEVEL =
+        "DATABASE_ISOLATION_LEVEL";
+    static final String T_TRANSACTION_CONTROL = "TRANSACTION_CONTROL";
+    static final String T_TIMEZONE            = "TIMEZONE";
+    static final String T_SESSION_TIMEZONE    = "SESSION_TIMEZONE";
+    static final String T_DATABASE_TIMEZONE   = "DATABASE_TIMEZONE";
+    static final String T_DATABASE_VERSION    = "DATABASE_VERSION";
+
+    //
+    //SQL 200n Standard reserved keywords - full set
+    public static final int ABS                              = 1;
+    public static final int ALL                              = 2;
+    public static final int ALLOCATE                         = 3;
+    public static final int ALTER                            = 4;
+    public static final int AND                              = 5;
+    public static final int ANY                              = 6;
+    public static final int ARE                              = 7;
+    public static final int ARRAY                            = 8;
+    public static final int AS                               = 9;
+    public static final int ASENSITIVE                       = 10;
+    public static final int ASYMMETRIC                       = 11;
+    public static final int AT                               = 12;
+    public static final int ATOMIC                           = 13;
+    public static final int AUTHORIZATION                    = 14;
+    public static final int AVG                              = 15;
+    public static final int BEGIN                            = 16;
+    public static final int BETWEEN                          = 17;
+    public static final int BIGINT                           = 18;
+    public static final int BINARY                           = 19;
+    public static final int BLOB                             = 20;
+    public static final int BOOLEAN                          = 21;
+    public static final int BOTH                             = 22;
+    public static final int BY                               = 23;
+    public static final int CALL                             = 24;
+    public static final int CALLED                           = 25;
+    public static final int CARDINALITY                      = 26;
+    public static final int CASCADED                         = 27;
+    public static final int CASE                             = 28;
+    public static final int CAST                             = 29;
+    public static final int CEIL                             = 30;
+    public static final int CEILING                          = 31;
+    public static final int CHAR                             = 32;
+    public static final int CHAR_LENGTH                      = 33;
+    public static final int CHARACTER                        = 34;
+    public static final int CHARACTER_LENGTH                 = 35;
+    public static final int CHECK                            = 36;
+    public static final int CLOB                             = 37;
+    public static final int CLOSE                            = 38;
+    public static final int COALESCE                         = 39;
+    public static final int COLLATE                          = 40;
+    public static final int COLLECT                          = 41;
+    public static final int COLUMN                           = 42;
+    public static final int COMMIT                           = 43;
+    public static final int COMPARABLE                       = 44;
+    public static final int CONDITION                        = 45;
+    public static final int CONNECT                          = 46;
+    public static final int CONSTRAINT                       = 47;
+    public static final int CONVERT                          = 48;
+    public static final int CORR                             = 49;
+    public static final int CORRESPONDING                    = 50;
+    public static final int COUNT                            = 51;
+    public static final int COVAR_POP                        = 52;
+    public static final int COVAR_SAMP                       = 53;
+    public static final int CREATE                           = 54;
+    public static final int CROSS                            = 55;
+    public static final int CUBE                             = 56;
+    public static final int CUME_DIST                        = 57;
+    public static final int CURRENT                          = 58;
+    public static final int CURRENT_CATALOG                  = 59;
+    public static final int CURRENT_DATE                     = 60;
+    public static final int CURRENT_DEFAULT_TRANSFORM_GROUP  = 61;
+    public static final int CURRENT_PATH                     = 62;
+    public static final int CURRENT_ROLE                     = 63;
+    public static final int CURRENT_SCHEMA                   = 64;
+    public static final int CURRENT_TIME                     = 65;
+    public static final int CURRENT_TIMESTAMP                = 66;
+    public static final int CURRENT_TRANSFORM_GROUP_FOR_TYPE = 67;
+    public static final int CURRENT_USER                     = 68;
+    public static final int CURSOR                           = 69;
+    public static final int CYCLE                            = 70;
+    public static final int DATE                             = 71;
+    public static final int DAY                              = 72;
+    public static final int DEALLOCATE                       = 73;
+    public static final int DEC                              = 74;
+    public static final int DECIMAL                          = 75;
+    public static final int DECLARE                          = 76;
+    public static final int DEFAULT                          = 77;
+    public static final int DELETE                           = 78;
+    public static final int DENSE_RANK                       = 79;
+    public static final int DEREF                            = 80;
+    public static final int DESCRIBE                         = 81;
+    public static final int DETERMINISTIC                    = 82;
+    public static final int DISCONNECT                       = 83;
+    public static final int DISTINCT                         = 84;
+    public static final int DO                               = 85;
+    public static final int DOUBLE                           = 86;
+    public static final int DROP                             = 87;
+    public static final int DYNAMIC                          = 88;
+    public static final int EACH                             = 89;
+    public static final int ELEMENT                          = 90;
+    public static final int ELSE                             = 91;
+    public static final int ELSEIF                           = 92;
+    public static final int END                              = 93;
+    public static final int END_EXEC                         = 94;
+    public static final int ESCAPE                           = 95;
+    public static final int EVERY                            = 96;
+    public static final int EXCEPT                           = 97;
+    public static final int EXEC                             = 98;
+    public static final int EXECUTE                          = 99;
+    public static final int EXISTS                           = 100;
+    public static final int EXIT                             = 101;
+    public static final int EXP                              = 102;
+    public static final int EXTERNAL                         = 103;
+    public static final int EXTRACT                          = 104;
+    public static final int FALSE                            = 105;
+    public static final int FETCH                            = 106;
+    public static final int FILTER                           = 107;
+    public static final int FIRST_VALUE                      = 108;
+    public static final int FLOAT                            = 109;
+    public static final int FLOOR                            = 110;
+    public static final int FOR                              = 111;
+    public static final int FOREIGN                          = 112;
+    public static final int FREE                             = 113;
+    public static final int FROM                             = 114;
+    public static final int FULL                             = 115;
+    public static final int FUNCTION                         = 116;
+    public static final int FUSION                           = 117;
+    public static final int GET                              = 118;
+    public static final int GLOBAL                           = 119;
+    public static final int GRANT                            = 120;
+    public static final int GROUP                            = 121;
+    public static final int GROUPING                         = 122;
+    public static final int HANDLER                          = 123;
+    public static final int HAVING                           = 124;
+    public static final int HOLD                             = 125;
+    public static final int HOUR                             = 126;
+    public static final int IDENTITY                         = 127;
+    public static final int IMPORT                           = 128;
+    public static final int IN                               = 129;
+    public static final int INDICATOR                        = 130;
+    public static final int INNER                            = 131;
+    public static final int INOUT                            = 132;
+    public static final int INSENSITIVE                      = 133;
+    public static final int INSERT                           = 134;
+    public static final int INT                              = 135;
+    public static final int INTEGER                          = 136;
+    public static final int INTERSECT                        = 137;
+    public static final int INTERSECTION                     = 138;
+    public static final int INTERVAL                         = 139;
+    public static final int INTO                             = 140;
+    public static final int IS                               = 141;
+    public static final int ITERATE                          = 142;
+    public static final int JOIN                             = 143;
+    public static final int LAG                              = 144;
+    public static final int LANGUAGE                         = 145;
+    public static final int LARGE                            = 146;
+    public static final int LAST_VALUE                       = 147;
+    public static final int LATERAL                          = 148;
+    public static final int LEAD                             = 149;
+    public static final int LEADING                          = 150;
+    public static final int LEAVE                            = 151;
+    public static final int LEFT                             = 152;
+    public static final int LIKE                             = 153;
+    public static final int LIKE_REGEX                       = 154;
+    public static final int LN                               = 155;
+    public static final int LOCAL                            = 156;
+    public static final int LOCALTIME                        = 157;
+    public static final int LOCALTIMESTAMP                   = 158;
+    public static final int LOOP                             = 159;
+    public static final int LOWER                            = 160;
+    public static final int MATCH                            = 161;
+    public static final int MAX                              = 162;
+    public static final int MAX_CARDINALITY                  = 163;
+    public static final int MEMBER                           = 164;
+    public static final int MERGE                            = 165;
+    public static final int METHOD                           = 166;
+    public static final int MIN                              = 167;
+    public static final int MINUTE                           = 168;
+    public static final int MOD                              = 169;
+    public static final int MODIFIES                         = 170;
+    public static final int MODULE                           = 171;
+    public static final int MONTH                            = 172;
+    public static final int MULTISET                         = 173;
+    public static final int NATIONAL                         = 174;
+    public static final int NATURAL                          = 175;
+    public static final int NCHAR                            = 176;
+    public static final int NCLOB                            = 177;
+    public static final int NEW                              = 178;
+    public static final int NO                               = 179;
+    public static final int NONE                             = 180;
+    public static final int NORMALIZE                        = 181;
+    public static final int NOT                              = 182;
+    public static final int NTH_VALUE                        = 183;
+    public static final int NTILE                            = 184;
+    public static final int NULL                             = 185;
+    public static final int NULLIF                           = 186;
+    public static final int NUMERIC                          = 187;
+    public static final int OCCURRENCES_REGEX                = 188;
+    public static final int OCTET_LENGTH                     = 189;
+    public static final int OF                               = 190;
+    public static final int OFFSET                           = 191;
+    public static final int OLD                              = 192;
+    public static final int ON                               = 193;
+    public static final int ONLY                             = 194;
+    public static final int OPEN                             = 195;
+    public static final int OR                               = 196;
+    public static final int ORDER                            = 197;
+    public static final int OUT                              = 198;
+    public static final int OUTER                            = 199;
+    public static final int OVER                             = 200;
+    public static final int OVERLAPS                         = 201;
+    public static final int OVERLAY                          = 202;
+    public static final int PARAMETER                        = 203;
+    public static final int PARTITION                        = 204;
+    public static final int PERCENT_RANK                     = 205;
+    public static final int PERCENTILE_CONT                  = 206;
+    public static final int PERCENTILE_DISC                  = 207;
+    public static final int POSITION                         = 208;
+    public static final int POSITION_REGEX                   = 209;
+    public static final int POWER                            = 210;
+    public static final int PRECISION                        = 211;
+    public static final int PREPARE                          = 212;
+    public static final int PRIMARY                          = 213;
+    public static final int PROCEDURE                        = 214;
+    public static final int RANGE                            = 215;
+    public static final int RANK                             = 216;
+    public static final int READS                            = 217;
+    public static final int REAL                             = 218;
+    public static final int RECURSIVE                        = 219;
+    public static final int REF                              = 220;
+    public static final int REFERENCES                       = 221;
+    public static final int REFERENCING                      = 222;
+    public static final int REGR_AVGX                        = 223;
+    public static final int REGR_AVGY                        = 224;
+    public static final int REGR_COUNT                       = 225;
+    public static final int REGR_INTERCEPT                   = 226;
+    public static final int REGR_R2                          = 227;
+    public static final int REGR_SLOPE                       = 228;
+    public static final int REGR_SXX                         = 229;
+    public static final int REGR_SXY                         = 230;
+    public static final int REGR_SYY                         = 231;
+    public static final int RELEASE                          = 232;
+    public static final int REPEAT                           = 233;
+    public static final int RESIGNAL                         = 234;
+    public static final int RESULT                           = 235;
+    public static final int RETURN                           = 236;
+    public static final int RETURNS                          = 237;
+    public static final int REVOKE                           = 238;
+    public static final int RIGHT                            = 239;
+    public static final int ROLLBACK                         = 240;
+    public static final int ROLLUP                           = 241;
+    public static final int ROW                              = 242;
+    public static final int ROW_NUMBER                       = 243;
+    public static final int ROWS                             = 244;
+    public static final int SAVEPOINT                        = 245;
+    public static final int SCOPE                            = 246;
+    public static final int SCROLL                           = 247;
+    public static final int SEARCH                           = 248;
+    public static final int SECOND                           = 249;
+    public static final int SELECT                           = 250;
+    public static final int SENSITIVE                        = 251;
+    public static final int SESSION_USER                     = 252;
+    public static final int SET                              = 253;
+    public static final int SIGNAL                           = 254;
+    public static final int SIMILAR                          = 255;
+    public static final int SMALLINT                         = 256;
+    public static final int SOME                             = 257;
+    public static final int SPECIFIC                         = 258;
+    public static final int SPECIFICTYPE                     = 259;
+    public static final int SQL                              = 260;
+    public static final int SQLEXCEPTION                     = 261;
+    public static final int SQLSTATE                         = 262;
+    public static final int SQLWARNING                       = 263;
+    public static final int SQRT                             = 264;
+    public static final int STACKED                          = 265;
+    public static final int START                            = 266;
+    public static final int STATIC                           = 267;
+    public static final int STDDEV_POP                       = 268;
+    public static final int STDDEV_SAMP                      = 269;
+    public static final int SUBMULTISET                      = 270;
+    public static final int SUBSTRING                        = 271;
+    public static final int SUBSTRING_REGEX                  = 272;
+    public static final int SUM                              = 273;
+    public static final int SYMMETRIC                        = 274;
+    public static final int SYSTEM                           = 275;
+    public static final int SYSTEM_USER                      = 276;
+    public static final int TABLE                            = 277;
+    public static final int TABLESAMPLE                      = 278;
+    public static final int THEN                             = 279;
+    public static final int TIME                             = 280;
+    public static final int TIMESTAMP                        = 281;
+    public static final int TIMEZONE_HOUR                    = 282;
+    public static final int TIMEZONE_MINUTE                  = 283;
+    public static final int TO                               = 284;
+    public static final int TRAILING                         = 285;
+    public static final int TRANSLATE                        = 286;
+    public static final int TRANSLATE_REGEX                  = 287;
+    public static final int TRANSLATION                      = 288;
+    public static final int TREAT                            = 289;
+    public static final int TRIGGER                          = 290;
+    public static final int TRIM                             = 291;
+    public static final int TRIM_ARRAY                       = 292;
+    public static final int TRUE                             = 293;
+    public static final int TRUNCATE                         = 294;
+    public static final int UESCAPE                          = 295;
+    public static final int UNDO                             = 296;
+    public static final int UNION                            = 297;
+    public static final int UNIQUE                           = 298;
+    public static final int UNKNOWN                          = 299;
+    public static final int UNNEST                           = 300;
+    public static final int UNTIL                            = 301;
+    public static final int UPDATE                           = 302;
+    public static final int UPPER                            = 303;
+    public static final int USER                             = 304;
+    public static final int USING                            = 305;
+    public static final int VALUE                            = 306;
+    public static final int VALUES                           = 307;
+    public static final int VAR_POP                          = 308;
+    public static final int VAR_SAMP                         = 309;
+    public static final int VARBINARY                        = 310;
+    public static final int VARCHAR                          = 311;
+    public static final int VARYING                          = 312;
+    public static final int WHEN                             = 313;
+    public static final int WHENEVER                         = 314;
+    public static final int WHERE                            = 315;
+    public static final int WIDTH_BUCKET                     = 316;
+    public static final int WINDOW                           = 317;
+    public static final int WITH                             = 318;
+    public static final int WITHIN                           = 319;
+    public static final int WITHOUT                          = 320;
+    public static final int WHILE                            = 321;
+    public static final int YEAR                             = 322;
+
+    //
+    //SQL 200n Standard non-reserved keywords - full set
+    public static final int A                           = 330;
+    public static final int ABSOLUTE                    = 331;
+    public static final int ACTION                      = 332;
+    public static final int ADA                         = 333;
+    public static final int ADD                         = 334;
+    public static final int ADMIN                       = 335;
+    public static final int AFTER                       = 336;
+    public static final int ALWAYS                      = 337;
+    public static final int ASC                         = 338;
+    public static final int ASSERTION                   = 339;
+    public static final int ASSIGNMENT                  = 340;
+    public static final int ATTRIBUTE                   = 341;
+    public static final int ATTRIBUTES                  = 342;
+    public static final int BEFORE                      = 343;
+    public static final int BERNOULLI                   = 344;
+    public static final int BREADTH                     = 345;
+    public static final int C                           = 346;
+    public static final int CASCADE                     = 347;
+    public static final int CATALOG                     = 348;
+    public static final int CATALOG_NAME                = 349;
+    public static final int CHAIN                       = 350;
+    public static final int CHARACTER_SET_CATALOG       = 351;
+    public static final int CHARACTER_SET_NAME          = 352;
+    public static final int CHARACTER_SET_SCHEMA        = 353;
+    public static final int CHARACTERISTICS             = 354;
+    public static final int CHARACTERS                  = 355;
+    public static final int CLASS_ORIGIN                = 356;
+    public static final int COBOL                       = 357;
+    public static final int COLLATION                   = 358;
+    public static final int COLLATION_CATALOG           = 359;
+    public static final int COLLATION_NAME              = 360;
+    public static final int COLLATION_SCHEMA            = 361;
+    public static final int COLUMN_NAME                 = 362;
+    public static final int COMMAND_FUNCTION            = 363;
+    public static final int COMMAND_FUNCTION_CODE       = 364;
+    public static final int COMMITTED                   = 365;
+    public static final int CONDITION_IDENTIFIER        = 366;
+    public static final int CONDITION_NUMBER            = 367;
+    public static final int CONNECTION                  = 368;
+    public static final int CONNECTION_NAME             = 369;
+    public static final int CONSTRAINT_CATALOG          = 370;
+    public static final int CONSTRAINT_NAME             = 371;
+    public static final int CONSTRAINT_SCHEMA           = 372;
+    public static final int CONSTRAINTS                 = 373;
+    public static final int CONSTRUCTOR                 = 374;
+    public static final int CONTAINS                    = 375;
+    public static final int CONTINUE                    = 376;
+    public static final int CURSOR_NAME                 = 377;
+    public static final int DATA                        = 378;
+    public static final int DATETIME_INTERVAL_CODE      = 379;
+    public static final int DATETIME_INTERVAL_PRECISION = 380;
+    public static final int DEFAULTS                    = 381;
+    public static final int DEFERRABLE                  = 382;
+    public static final int DEFERRED                    = 383;
+    public static final int DEFINED                     = 384;
+    public static final int DEFINER                     = 385;
+    public static final int DEGREE                      = 386;
+    public static final int DEPTH                       = 387;
+    public static final int DERIVED                     = 388;
+    public static final int DESC                        = 389;
+    public static final int DESCRIPTOR                  = 390;
+    public static final int DIAGNOSTICS                 = 391;
+    public static final int DISPATCH                    = 392;
+    public static final int DOMAIN                      = 393;
+    public static final int DYNAMIC_FUNCTION            = 394;
+    public static final int DYNAMIC_FUNCTION_CODE       = 395;
+    public static final int EQUALS                      = 396;
+    public static final int EXCEPTION                   = 397;
+    public static final int EXCLUDE                     = 398;
+    public static final int EXCLUDING                   = 399;
+    public static final int FINAL                       = 400;
+    public static final int FIRST                       = 401;
+    public static final int FOLLOWING                   = 402;
+    public static final int FORTRAN                     = 403;
+    public static final int FOUND                       = 404;
+    public static final int G                           = 405;
+    public static final int GENERAL                     = 406;
+    public static final int GENERATED                   = 407;
+    public static final int GO                          = 408;
+    public static final int GOTO                        = 409;
+    public static final int GRANTED                     = 410;
+    public static final int HIERARCHY                   = 411;
+    public static final int IF                          = 412;
+    public static final int IGNORE                      = 413;
+    public static final int IMMEDIATE                   = 414;
+    public static final int IMPLEMENTATION              = 415;
+    public static final int INCLUDING                   = 416;
+    public static final int INCREMENT                   = 417;
+    public static final int INITIALLY                   = 418;
+    public static final int INPUT                       = 419;
+    public static final int INSTANCE                    = 420;
+    public static final int INSTANTIABLE                = 421;
+    public static final int INSTEAD                     = 422;
+    public static final int INVOKER                     = 423;
+    public static final int ISOLATION                   = 424;
+    public static final int JAVA                        = 425;
+    public static final int K                           = 426;
+    public static final int KEY                         = 427;
+    public static final int KEY_MEMBER                  = 428;
+    public static final int KEY_TYPE                    = 429;
+    public static final int LAST                        = 430;
+    public static final int LENGTH                      = 431;
+    public static final int LEVEL                       = 432;
+    public static final int LIBRARY                     = 433;
+    public static final int LOCATOR                     = 434;
+    public static final int M                           = 435;
+    public static final int MAP                         = 436;
+    public static final int MATCHED                     = 437;
+    public static final int MAXVALUE                    = 438;
+    public static final int MESSAGE_LENGTH              = 439;
+    public static final int MESSAGE_OCTET_LENGTH        = 440;
+    public static final int MESSAGE_TEXT                = 441;
+    public static final int MINVALUE                    = 442;
+    public static final int MORE                        = 443;
+    public static final int MUMPS                       = 444;
+    public static final int NAME                        = 445;
+    public static final int NAMES                       = 446;
+    public static final int NESTING                     = 447;
+    public static final int NEXT                        = 448;
+    public static final int NORMALIZED                  = 449;
+    public static final int NULLABLE                    = 450;
+    public static final int NULLS                       = 451;
+    public static final int NUMBER                      = 452;
+    public static final int OBJECT                      = 453;
+    public static final int OCTETS                      = 454;
+    public static final int OPTION                      = 455;
+    public static final int OPTIONS                     = 456;
+    public static final int ORDERING                    = 457;
+    public static final int ORDINALITY                  = 458;
+    public static final int OTHERS                      = 459;
+    public static final int OUTPUT                      = 460;
+    public static final int OVERRIDING                  = 461;
+    public static final int P                           = 462;
+    public static final int PAD                         = 463;
+    public static final int PARAMETER_MODE              = 464;
+    public static final int PARAMETER_NAME              = 465;
+    public static final int PARAMETER_ORDINAL_POSITION  = 466;
+    public static final int PARAMETER_SPECIFIC_CATALOG  = 467;
+    public static final int PARAMETER_SPECIFIC_NAME     = 468;
+    public static final int PARAMETER_SPECIFIC_SCHEMA   = 469;
+    public static final int PARTIAL                     = 470;
+    public static final int PASCAL                      = 471;
+    public static final int PATH                        = 472;
+    public static final int PLACING                     = 473;
+    public static final int PLI                         = 474;
+    public static final int PRECEDING                   = 475;
+    public static final int PRESERVE                    = 476;
+    public static final int PRIOR                       = 477;
+    public static final int PRIVILEGES                  = 478;
+    public static final int PUBLIC                      = 479;
+    public static final int READ                        = 480;
+    public static final int RELATIVE                    = 481;
+    public static final int REPEATABLE                  = 482;
+    public static final int RESPECT                     = 483;
+    public static final int RESTART                     = 484;
+    public static final int RESTRICT                    = 485;
+    public static final int RETURNED_CARDINALITY        = 486;
+    public static final int RETURNED_LENGTH             = 487;
+    public static final int RETURNED_OCTET_LENGTH       = 488;
+    public static final int RETURNED_SQLSTATE           = 489;
+    public static final int ROLE                        = 490;
+    public static final int ROUTINE                     = 491;
+    public static final int ROUTINE_CATALOG             = 492;
+    public static final int ROUTINE_NAME                = 493;
+    public static final int ROUTINE_SCHEMA              = 494;
+    public static final int ROW_COUNT                   = 495;
+    public static final int SCALE                       = 496;
+    public static final int SCHEMA                      = 497;
+    public static final int SCHEMA_NAME                 = 498;
+    public static final int SCOPE_CATALOG               = 499;
+    public static final int SCOPE_NAME                  = 500;
+    public static final int SCOPE_SCHEMA                = 501;
+    public static final int SECTION                     = 502;
+    public static final int SECURITY                    = 503;
+    public static final int SELF                        = 504;
+    public static final int SEQUENCE                    = 505;
+    public static final int SERIALIZABLE                = 506;
+    public static final int SERVER_NAME                 = 507;
+    public static final int SESSION                     = 508;
+    public static final int SERVER                      = 509;
+    public static final int SETS                        = 510;
+    public static final int SIMPLE                      = 511;
+    public static final int SIZE                        = 512;
+    public static final int SOURCE                      = 513;
+    public static final int SPACE                       = 514;
+    public static final int SPECIFIC_NAME               = 515;
+    public static final int STATE                       = 516;
+    public static final int STATEMENT                   = 517;
+    public static final int STRUCTURE                   = 518;
+    public static final int STYLE                       = 519;
+    public static final int SUBCLASS_ORIGIN             = 520;
+    public static final int T                           = 521;
+    public static final int TABLE_NAME                  = 522;
+    public static final int TEMPORARY                   = 523;
+    public static final int TIES                        = 524;
+    public static final int TOP_LEVEL_COUNT             = 525;
+    public static final int TRANSACTION                 = 526;
+    public static final int TRANSACTION_ACTIVE          = 527;
+    public static final int TRANSACTIONS_COMMITTED      = 528;
+    public static final int TRANSACTIONS_ROLLED_BACK    = 529;
+    public static final int TRANSFORM                   = 530;
+    public static final int TRANSFORMS                  = 531;
+    public static final int TRIGGER_CATALOG             = 532;
+    public static final int TRIGGER_NAME                = 533;
+    public static final int TRIGGER_SCHEMA              = 534;
+    public static final int TYPE                        = 535;
+    public static final int UNBOUNDED                   = 536;
+    public static final int UNCOMMITTED                 = 537;
+    public static final int UNDER                       = 538;
+    public static final int UNNAMED                     = 539;
+    public static final int USAGE                       = 540;
+    public static final int USER_DEFINED_TYPE_CATALOG   = 541;
+    public static final int USER_DEFINED_TYPE_CODE      = 542;
+    public static final int USER_DEFINED_TYPE_NAME      = 543;
+    public static final int USER_DEFINED_TYPE_SCHEMA    = 544;
+    public static final int VIEW                        = 545;
+    public static final int WORK                        = 546;
+    public static final int WRITE                       = 547;
+    public static final int WRAPPER                     = 548;
+    public static final int ZONE                        = 549;
+
+    // other token values used as switch cases
+    static final int ALIAS        = 551;
+    static final int AGGREGATE    = 552;
+    static final int AUTOCOMMIT   = 553;
+    static final int BACKUP       = 554;
+    static final int BIT          = 555;
+    static final int BLOCKING     = 556;
+    static final int CACHE        = 557;
+    static final int CACHED       = 558;
+    static final int CASEWHEN     = 559;
+    static final int CHECKPOINT   = 560;
+    static final int CLASS        = 561;
+    static final int COMMENT      = 562;
+    static final int COMPACT      = 563;
+    static final int COMPRESSED   = 564;
+    static final int CONTROL      = 565;
+    static final int DATABASE     = 566;
+    static final int DEFRAG       = 567;
+    static final int DELAY        = 568;
+    static final int EVENT        = 569;
+    static final int EXPLAIN      = 570;
+    static final int FILE         = 571;
+    static final int FILES        = 572;
+    static final int GC           = 573;
+    static final int HEADER       = 574;
+    static final int IGNORECASE   = 575;
+    static final int IMMEDIATELY  = 576;
+    static final int INTEGRITY    = 577;
+    static final int INDEX        = 578;
+    static final int INITIAL      = 579;
+    static final int LIMIT        = 580;
+    static final int LOCK         = 581;
+    static final int LOCKS        = 582;
+    static final int MAXROWS      = 583;
+    static final int MEMORY       = 584;
+    static final int MILLIS       = 585;
+    static final int MINUS_EXCEPT = 586;
+    static final int OFF          = 587;
+    static final int PASSWORD     = 588;
+    static final int PLAN         = 589;
+    static final int PROPERTY     = 590;
+    static final int READONLY     = 591;
+    static final int REFERENTIAL  = 592;
+    static final int RENAME       = 593;
+    static final int SCRIPT       = 594;
+    static final int SCRIPTFORMAT = 595;
+    static final int SHUTDOWN     = 596;
+    static final int TEMP         = 597;
+    static final int TEXT         = 598;
+    static final int WRITE_DELAY  = 599;
+
+    //
+    static final int        ACOS                    = 601;
+    static final int        ASCII                   = 602;
+    static final int        ASIN                    = 603;
+    static final int        ATAN                    = 604;
+    static final int        ATAN2                   = 605;
+    static final int        BIT_LENGTH              = 606;
+    static final int        BITAND                  = 607;
+    static final int        BITLENGTH               = 608;
+    static final int        BITOR                   = 609;
+    static final int        BITXOR                  = 610;
+    static final int        CONCAT_WORD             = 611;
+    static final int        COS                     = 612;
+    static final int        COT                     = 613;
+    static final int        CRYPT_KEY               = 614;
+    static final int        CURDATE                 = 615;
+    static final int        CURTIME                 = 616;
+    static final int        DATEADD                 = 617;
+    static final int        DATEDIFF                = 618;
+    public static final int DAY_NAME                = 619;
+    public static final int DAY_OF_MONTH            = 620;
+    public static final int DAY_OF_WEEK             = 621;
+    public static final int DAY_OF_YEAR             = 622;
+    static final int        DAYNAME                 = 623;
+    static final int        DAYOFMONTH              = 624;
+    static final int        DAYOFWEEK               = 625;
+    static final int        DAYOFYEAR               = 626;
+    static final int        DECODE                  = 627;
+    static final int        DEGREES                 = 628;
+    static final int        DIFFERENCE              = 629;
+    static final int        DMOD                    = 630;
+    static final int        HEXTORAW                = 631;
+    static final int        IFNULL                  = 632;
+    static final int        ISAUTOCOMMIT            = 633;
+    static final int        ISREADONLYDATABASE      = 634;
+    static final int        ISREADONLYDATABASEFILES = 635;
+    static final int        ISREADONLYSESSION       = 636;
+    static final int        LCASE                   = 637;
+    static final int        LEAST                   = 638;
+    static final int        LOCATE                  = 639;
+    static final int        LOB                     = 640;
+    static final int        LOG                     = 641;
+    static final int        LOG10                   = 642;
+    static final int        LTRIM                   = 643;
+    static final int        GREATEST                = 644;
+    public static final int MONTH_NAME              = 645;
+    static final int        MONTHNAME               = 646;
+    static final int        MVCC                    = 647;
+    static final int        MVLOCKS                 = 648;
+    static final int        NIO                     = 649;
+    static final int        NOW                     = 650;
+    static final int        OCTETLENGTH             = 651;
+    static final int        PI                      = 652;
+    public static final int QUARTER                 = 653;
+    static final int        RADIANS                 = 654;
+    static final int        RAND                    = 655;
+    static final int        RAWTOHEX                = 656;
+    static final int        REGEXP_MATCHES          = 657;
+    static final int        REPLACE                 = 658;
+    static final int        REVERSE                 = 659;
+    static final int        ROUND                   = 660;
+    static final int        ROUNDMAGIC              = 661;
+    static final int        RTRIM                   = 662;
+    public static final int SECONDS_MIDNIGHT        = 663;
+    static final int        SIGN                    = 664;
+    static final int        SIN                     = 665;
+    static final int        SOUNDEX                 = 666;
+    static final int        SPACE_WORD              = 667;
+    static final int        SUBSTR                  = 668;
+    static final int        SYSDATE                 = 669;
+    static final int        TAN                     = 670;
+    static final int        TIMESTAMPADD            = 671;
+    static final int        TIMESTAMPDIFF           = 672;
+    static final int        TO_CHAR                 = 673;
+    static final int        TODAY                   = 674;
+    static final int        TOP                     = 675;
+    static final int        UCASE                   = 676;
+    static final int        WEEK                    = 677;
+    public static final int WEEK_OF_YEAR            = 678;
+
+    //
+    static final int ISOLATION_LEVEL          = 681;
+    static final int SESSION_ISOLATION_LEVEL  = 682;
+    static final int DATABASE_ISOLATION_LEVEL = 683;
+    static final int TRANSACTION_CONTROL      = 684;
+    static final int TIMEZONE                 = 685;
+    static final int SESSION_TIMEZONE         = 686;
+    static final int DATABASE_TIMEZONE        = 687;
+    static final int DATABASE_VERSION         = 688;
+
+    //
+    static final int        ASTERISK         = 771;
+    static final int        CLOSEBRACKET     = 772;
+    static final int        COLON            = 773;
+    static final int        COMMA            = 774;
+    static final int        CONCAT           = 775;
+    static final int        DIVIDE           = 776;
+    static final int        DOUBLE_COLON_OP  = 777;
+    static final int        DOUBLE_PERIOD_OP = 778;
+    static final int        GREATER          = 779;
+    static final int        GREATER_EQUALS   = 780;
+    static final int        LEFTBRACKET      = 781;
+    static final int        LESS             = 782;
+    static final int        LESS_EQUALS      = 783;
+    public static final int MINUS            = 784;
+    static final int        NOT_EQUALS       = 785;
+    static final int        OPENBRACKET      = 786;
+    static final int        PLUS             = 787;
+    static final int        QUESTION         = 788;
+    static final int        RIGHT_ARROW_OP   = 789;
+    static final int        RIGHTBRACKET     = 790;
+    static final int        SEMICOLON        = 791;
+
+    //
+    static final int SQL_BIGINT        = 801;
+    static final int SQL_BINARY        = 802;
+    static final int SQL_BIT           = 803;
+    static final int SQL_BLOB          = 804;
+    static final int SQL_BOOLEAN       = 805;
+    static final int SQL_CHAR          = 806;
+    static final int SQL_CLOB          = 807;
+    static final int SQL_DATE          = 808;
+    static final int SQL_DECIMAL       = 809;
+    static final int SQL_DATALINK      = 810;
+    static final int SQL_DOUBLE        = 811;
+    static final int SQL_FLOAT         = 812;
+    static final int SQL_INTEGER       = 813;
+    static final int SQL_LONGVARBINARY = 814;
+    static final int SQL_LONGNVARCHAR  = 815;
+    static final int SQL_LONGVARCHAR   = 816;
+    static final int SQL_NCHAR         = 817;
+    static final int SQL_NCLOB         = 818;
+    static final int SQL_NUMERIC       = 819;
+    static final int SQL_NVARCHAR      = 820;
+    static final int SQL_REAL          = 821;
+    static final int SQL_ROWID         = 822;
+    static final int SQL_SQLXML        = 823;
+    static final int SQL_SMALLINT      = 824;
+    static final int SQL_TIME          = 825;
+    static final int SQL_TIMESTAMP     = 826;
+    static final int SQL_TINYINT       = 827;
+    static final int SQL_VARBINARY     = 828;
+    static final int SQL_VARCHAR       = 829;
+
+    //
+    static final int SQL_TSI_FRAC_SECOND = 831;
+    static final int SQL_TSI_SECOND      = 832;
+    static final int SQL_TSI_MINUTE      = 833;
+    static final int SQL_TSI_HOUR        = 834;
+    static final int SQL_TSI_DAY         = 835;
+    static final int SQL_TSI_WEEK        = 836;
+    static final int SQL_TSI_MONTH       = 837;
+    static final int SQL_TSI_QUARTER     = 838;
+    static final int SQL_TSI_YEAR        = 839;
+
+    //
+    static final int X_KEYSET      = 841;
+    static final int X_OPTION      = 842;
+    static final int X_REPEAT      = 843;
+    static final int X_POS_INTEGER = 844;
+
+    //
+    public static final int X_VALUE                    = 845;
+    public static final int X_IDENTIFIER               = 846;
+    public static final int X_DELIMITED_IDENTIFIER     = 847;
+    public static final int X_ENDPARSE                 = 848;
+    public static final int X_STARTPARSE               = 849;
+    public static final int X_REMARK                   = 850;
+    public static final int X_NULL                     = 851;
+    public static final int X_LOB_SIZE                 = 852;
+    public static final int X_MALFORMED_STRING         = 853;
+    public static final int X_MALFORMED_NUMERIC        = 854;
+    public static final int X_MALFORMED_BIT_STRING     = 855;
+    public static final int X_MALFORMED_BINARY_STRING  = 856;
+    public static final int X_MALFORMED_UNICODE_STRING = 857;
+    public static final int X_MALFORMED_COMMENT        = 858;
+    public static final int X_MALFORMED_IDENTIFIER     = 859;
+    public static final int X_MALFORMED_UNICODE_ESCAPE = 860;
+
+    //
+    public static final int X_UNKNOWN_TOKEN = -1;
+    private static final IntValueHashMap reservedKeys =
+        new IntValueHashMap(351);
+
+    static {
+        reservedKeys.put(Tokens.T_ABS, ABS);
+        reservedKeys.put(Tokens.T_AGGREGATE, AGGREGATE);
+        reservedKeys.put(Tokens.T_ALL, ALL);
+        reservedKeys.put(Tokens.T_ALLOCATE, ALLOCATE);
+        reservedKeys.put(Tokens.T_ALTER, ALTER);
+        reservedKeys.put(Tokens.T_AND, AND);
+        reservedKeys.put(Tokens.T_ANY, ANY);
+        reservedKeys.put(Tokens.T_ARE, ARE);
+        reservedKeys.put(Tokens.T_ARRAY, ARRAY);
+        reservedKeys.put(Tokens.T_AS, AS);
+        reservedKeys.put(Tokens.T_ASENSITIVE, ASENSITIVE);
+        reservedKeys.put(Tokens.T_ASYMMETRIC, ASYMMETRIC);
+        reservedKeys.put(Tokens.T_AT, AT);
+        reservedKeys.put(Tokens.T_ATOMIC, ATOMIC);
+        reservedKeys.put(Tokens.T_AUTHORIZATION, AUTHORIZATION);
+        reservedKeys.put(Tokens.T_AVG, AVG);
+        reservedKeys.put(Tokens.T_BEGIN, BEGIN);
+        reservedKeys.put(Tokens.T_BETWEEN, BETWEEN);
+        reservedKeys.put(Tokens.T_BIGINT, BIGINT);
+        reservedKeys.put(Tokens.T_BINARY, BINARY);
+        reservedKeys.put(Tokens.T_BIT_LENGTH, BIT_LENGTH);
+        reservedKeys.put(Tokens.T_BLOB, BLOB);
+        reservedKeys.put(Tokens.T_BOOLEAN, BOOLEAN);
+        reservedKeys.put(Tokens.T_BOTH, BOTH);
+        reservedKeys.put(Tokens.T_BY, BY);
+        reservedKeys.put(Tokens.T_CALL, CALL);
+        reservedKeys.put(Tokens.T_CALLED, CALLED);
+        reservedKeys.put(Tokens.T_CARDINALITY, CARDINALITY);
+        reservedKeys.put(Tokens.T_CASCADED, CASCADED);
+        reservedKeys.put(Tokens.T_CASE, CASE);
+        reservedKeys.put(Tokens.T_CAST, CAST);
+        reservedKeys.put(Tokens.T_CEIL, CEIL);
+        reservedKeys.put(Tokens.T_CEILING, CEILING);
+        reservedKeys.put(Tokens.T_CHAR, CHAR);
+        reservedKeys.put(Tokens.T_CHAR_LENGTH, CHAR_LENGTH);
+        reservedKeys.put(Tokens.T_CHARACTER, CHARACTER);
+        reservedKeys.put(Tokens.T_CHARACTER_LENGTH, CHARACTER_LENGTH);
+        reservedKeys.put(Tokens.T_CHECK, CHECK);
+        reservedKeys.put(Tokens.T_CLOB, CLOB);
+        reservedKeys.put(Tokens.T_CLOSE, CLOSE);
+        reservedKeys.put(Tokens.T_COALESCE, COALESCE);
+        reservedKeys.put(Tokens.T_COLLATE, COLLATE);
+        reservedKeys.put(Tokens.T_COLLECT, COLLECT);
+        reservedKeys.put(Tokens.T_COLUMN, COLUMN);
+        reservedKeys.put(Tokens.T_COMMIT, COMMIT);
+        reservedKeys.put(Tokens.T_COMPARABLE, COMPARABLE);
+        reservedKeys.put(Tokens.T_CONDITION, CONDITION);
+        reservedKeys.put(Tokens.T_CONNECT, CONNECT);
+        reservedKeys.put(Tokens.T_CONSTRAINT, CONSTRAINT);
+        reservedKeys.put(Tokens.T_CONVERT, CONVERT);
+        reservedKeys.put(Tokens.T_CORR, CORR);
+        reservedKeys.put(Tokens.T_CORRESPONDING, CORRESPONDING);
+        reservedKeys.put(Tokens.T_COUNT, COUNT);
+        reservedKeys.put(Tokens.T_COVAR_POP, COVAR_POP);
+        reservedKeys.put(Tokens.T_COVAR_SAMP, COVAR_SAMP);
+        reservedKeys.put(Tokens.T_CREATE, CREATE);
+        reservedKeys.put(Tokens.T_CROSS, CROSS);
+        reservedKeys.put(Tokens.T_CUBE, CUBE);
+        reservedKeys.put(Tokens.T_CUME_DIST, CUME_DIST);
+        reservedKeys.put(Tokens.T_CURRENT, CURRENT);
+        reservedKeys.put(Tokens.T_CURRENT_CATALOG, CURRENT_CATALOG);
+        reservedKeys.put(Tokens.T_CURRENT_DATE, CURRENT_DATE);
+        reservedKeys.put(Tokens.T_CURRENT_DEFAULT_TRANSFORM_GROUP,
+                         CURRENT_DEFAULT_TRANSFORM_GROUP);
+        reservedKeys.put(Tokens.T_CURRENT_PATH, CURRENT_PATH);
+        reservedKeys.put(Tokens.T_CURRENT_ROLE, CURRENT_ROLE);
+        reservedKeys.put(Tokens.T_CURRENT_SCHEMA, CURRENT_SCHEMA);
+        reservedKeys.put(Tokens.T_CURRENT_TIME, CURRENT_TIME);
+        reservedKeys.put(Tokens.T_CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
+        reservedKeys.put(Tokens.T_DO, DO);
+        reservedKeys.put(Tokens.T_CURRENT_TRANSFORM_GROUP_FOR_TYPE,
+                         CURRENT_TRANSFORM_GROUP_FOR_TYPE);
+        reservedKeys.put(Tokens.T_CURRENT_USER, CURRENT_USER);
+        reservedKeys.put(Tokens.T_CURSOR, CURSOR);
+        reservedKeys.put(Tokens.T_CYCLE, CYCLE);
+        reservedKeys.put(Tokens.T_DATE, DATE);
+        reservedKeys.put(Tokens.T_DAY, DAY);
+        reservedKeys.put(Tokens.T_DEALLOCATE, DEALLOCATE);
+        reservedKeys.put(Tokens.T_DEC, DEC);
+        reservedKeys.put(Tokens.T_DECIMAL, DECIMAL);
+        reservedKeys.put(Tokens.T_DECLARE, DECLARE);
+        reservedKeys.put(Tokens.T_DEFAULT, DEFAULT);
+        reservedKeys.put(Tokens.T_DELETE, DELETE);
+        reservedKeys.put(Tokens.T_DENSE_RANK, DENSE_RANK);
+        reservedKeys.put(Tokens.T_DEREF, DEREF);
+        reservedKeys.put(Tokens.T_DESCRIBE, DESCRIBE);
+        reservedKeys.put(Tokens.T_DETERMINISTIC, DETERMINISTIC);
+        reservedKeys.put(Tokens.T_DISCONNECT, DISCONNECT);
+        reservedKeys.put(Tokens.T_DISTINCT, DISTINCT);
+        reservedKeys.put(Tokens.T_DOUBLE, DOUBLE);
+        reservedKeys.put(Tokens.T_DROP, DROP);
+        reservedKeys.put(Tokens.T_DYNAMIC, DYNAMIC);
+        reservedKeys.put(Tokens.T_EACH, EACH);
+        reservedKeys.put(Tokens.T_ELEMENT, ELEMENT);
+        reservedKeys.put(Tokens.T_ELSE, ELSE);
+        reservedKeys.put(Tokens.T_ELSEIF, ELSEIF);
+        reservedKeys.put(Tokens.T_END, END);
+        reservedKeys.put(Tokens.T_END_EXEC, END_EXEC);
+        reservedKeys.put(Tokens.T_ESCAPE, ESCAPE);
+        reservedKeys.put(Tokens.T_EVERY, EVERY);
+        reservedKeys.put(Tokens.T_EXCEPT, EXCEPT);
+        reservedKeys.put(Tokens.T_EXEC, EXEC);
+        reservedKeys.put(Tokens.T_EXECUTE, EXECUTE);
+        reservedKeys.put(Tokens.T_EXISTS, EXISTS);
+        reservedKeys.put(Tokens.T_EXIT, EXIT);
+        reservedKeys.put(Tokens.T_EXP, EXP);
+        reservedKeys.put(Tokens.T_EXTERNAL, EXTERNAL);
+        reservedKeys.put(Tokens.T_EXTRACT, EXTRACT);
+        reservedKeys.put(Tokens.T_FALSE, FALSE);
+        reservedKeys.put(Tokens.T_FETCH, FETCH);
+        reservedKeys.put(Tokens.T_FILTER, FILTER);
+        reservedKeys.put(Tokens.T_FIRST_VALUE, FIRST_VALUE);
+        reservedKeys.put(Tokens.T_FLOAT, FLOAT);
+        reservedKeys.put(Tokens.T_FLOOR, FLOOR);
+        reservedKeys.put(Tokens.T_FOR, FOR);
+        reservedKeys.put(Tokens.T_FOREIGN, FOREIGN);
+        reservedKeys.put(Tokens.T_FREE, FREE);
+        reservedKeys.put(Tokens.T_FROM, FROM);
+        reservedKeys.put(Tokens.T_FULL, FULL);
+        reservedKeys.put(Tokens.T_FUNCTION, FUNCTION);
+        reservedKeys.put(Tokens.T_FUSION, FUSION);
+        reservedKeys.put(Tokens.T_GET, GET);
+        reservedKeys.put(Tokens.T_GLOBAL, GLOBAL);
+        reservedKeys.put(Tokens.T_GRANT, GRANT);
+        reservedKeys.put(Tokens.T_GROUP, GROUP);
+        reservedKeys.put(Tokens.T_GROUPING, GROUPING);
+        reservedKeys.put(Tokens.T_HANDLER, HANDLER);
+        reservedKeys.put(Tokens.T_HAVING, HAVING);
+        reservedKeys.put(Tokens.T_HOLD, HOLD);
+        reservedKeys.put(Tokens.T_HOUR, HOUR);
+        reservedKeys.put(Tokens.T_IDENTITY, IDENTITY);
+        reservedKeys.put(Tokens.T_IF, IF);
+        reservedKeys.put(Tokens.T_IMPORT, IMPORT);
+        reservedKeys.put(Tokens.T_IN, IN);
+        reservedKeys.put(Tokens.T_INDICATOR, INDICATOR);
+        reservedKeys.put(Tokens.T_INNER, INNER);
+        reservedKeys.put(Tokens.T_INOUT, INOUT);
+        reservedKeys.put(Tokens.T_INSENSITIVE, INSENSITIVE);
+        reservedKeys.put(Tokens.T_INSERT, INSERT);
+        reservedKeys.put(Tokens.T_INT, INT);
+        reservedKeys.put(Tokens.T_INTEGER, INTEGER);
+        reservedKeys.put(Tokens.T_INTERSECT, INTERSECT);
+        reservedKeys.put(Tokens.T_INTERSECTION, INTERSECTION);
+        reservedKeys.put(Tokens.T_INTERVAL, INTERVAL);
+        reservedKeys.put(Tokens.T_INTO, INTO);
+        reservedKeys.put(Tokens.T_IS, IS);
+        reservedKeys.put(Tokens.T_ITERATE, ITERATE);
+        reservedKeys.put(Tokens.T_JOIN, JOIN);
+        reservedKeys.put(Tokens.T_LAG, LAG);
+        reservedKeys.put(Tokens.T_LANGUAGE, LANGUAGE);
+        reservedKeys.put(Tokens.T_LARGE, LARGE);
+        reservedKeys.put(Tokens.T_LAST_VALUE, LAST_VALUE);
+        reservedKeys.put(Tokens.T_LATERAL, LATERAL);
+        reservedKeys.put(Tokens.T_LEAD, LEAD);
+        reservedKeys.put(Tokens.T_LEADING, LEADING);
+        reservedKeys.put(Tokens.T_LEAVE, LEAVE);
+        reservedKeys.put(Tokens.T_LEFT, LEFT);
+        reservedKeys.put(Tokens.T_LIKE, LIKE);
+        reservedKeys.put(Tokens.T_LIKE_REGX, LIKE_REGEX);
+        reservedKeys.put(Tokens.T_LN, LN);
+        reservedKeys.put(Tokens.T_LOCAL, LOCAL);
+        reservedKeys.put(Tokens.T_LOCALTIME, LOCALTIME);
+        reservedKeys.put(Tokens.T_LOCALTIMESTAMP, LOCALTIMESTAMP);
+        reservedKeys.put(Tokens.T_LOOP, LOOP);
+        reservedKeys.put(Tokens.T_LOWER, LOWER);
+        reservedKeys.put(Tokens.T_MATCH, MATCH);
+        reservedKeys.put(Tokens.T_MAX, MAX);
+        reservedKeys.put(Tokens.T_MAX_CARDINALITY, MAX_CARDINALITY);
+        reservedKeys.put(Tokens.T_MEMBER, MEMBER);
+        reservedKeys.put(Tokens.T_MERGE, MERGE);
+        reservedKeys.put(Tokens.T_METHOD, METHOD);
+        reservedKeys.put(Tokens.T_MIN, MIN);
+        reservedKeys.put(Tokens.T_MINUTE, MINUTE);
+        reservedKeys.put(Tokens.T_MOD, MOD);
+        reservedKeys.put(Tokens.T_MODIFIES, MODIFIES);
+        reservedKeys.put(Tokens.T_MODULE, MODULE);
+        reservedKeys.put(Tokens.T_MONTH, MONTH);
+        reservedKeys.put(Tokens.T_MULTISET, MULTISET);
+        reservedKeys.put(Tokens.T_NATIONAL, NATIONAL);
+        reservedKeys.put(Tokens.T_NATURAL, NATURAL);
+        reservedKeys.put(Tokens.T_NCHAR, NCHAR);
+        reservedKeys.put(Tokens.T_NCLOB, NCLOB);
+        reservedKeys.put(Tokens.T_NEW, NEW);
+        reservedKeys.put(Tokens.T_NO, NO);
+        reservedKeys.put(Tokens.T_NONE, NONE);
+        reservedKeys.put(Tokens.T_NORMALIZE, NORMALIZE);
+        reservedKeys.put(Tokens.T_NOT, NOT);
+        reservedKeys.put(Tokens.T_NTH_VALUE, NTH_VALUE);
+        reservedKeys.put(Tokens.T_NTILE, NTILE);
+        reservedKeys.put(Tokens.T_NULL, NULL);
+        reservedKeys.put(Tokens.T_NULLIF, NULLIF);
+        reservedKeys.put(Tokens.T_NUMERIC, NUMERIC);
+        reservedKeys.put(Tokens.T_OCCURRENCES_REGEX, OCCURRENCES_REGEX);
+        reservedKeys.put(Tokens.T_OCTET_LENGTH, OCTET_LENGTH);
+        reservedKeys.put(Tokens.T_OF, OF);
+        reservedKeys.put(Tokens.T_OFFSET, OFFSET);
+        reservedKeys.put(Tokens.T_OLD, OLD);
+        reservedKeys.put(Tokens.T_ON, ON);
+        reservedKeys.put(Tokens.T_ONLY, ONLY);
+        reservedKeys.put(Tokens.T_OPEN, OPEN);
+        reservedKeys.put(Tokens.T_OR, OR);
+        reservedKeys.put(Tokens.T_ORDER, ORDER);
+        reservedKeys.put(Tokens.T_OUT, OUT);
+        reservedKeys.put(Tokens.T_OUTER, OUTER);
+        reservedKeys.put(Tokens.T_OVER, OVER);
+        reservedKeys.put(Tokens.T_OVERLAPS, OVERLAPS);
+        reservedKeys.put(Tokens.T_OVERLAY, OVERLAY);
+        reservedKeys.put(Tokens.T_PARAMETER, PARAMETER);
+        reservedKeys.put(Tokens.T_PARTITION, PARTITION);
+        reservedKeys.put(Tokens.T_PERCENT_RANK, PERCENT_RANK);
+        reservedKeys.put(Tokens.T_PERCENTILE_CONT, PERCENTILE_CONT);
+        reservedKeys.put(Tokens.T_PERCENTILE_DISC, PERCENTILE_DISC);
+        reservedKeys.put(Tokens.T_POSITION, POSITION);
+        reservedKeys.put(Tokens.T_POSITION_REGEX, POSITION_REGEX);
+        reservedKeys.put(Tokens.T_POWER, POWER);
+        reservedKeys.put(Tokens.T_PRECISION, PRECISION);
+        reservedKeys.put(Tokens.T_PREPARE, PREPARE);
+        reservedKeys.put(Tokens.T_PRIMARY, PRIMARY);
+        reservedKeys.put(Tokens.T_PROCEDURE, PROCEDURE);
+        reservedKeys.put(Tokens.T_RANGE, RANGE);
+        reservedKeys.put(Tokens.T_RANK, RANK);
+        reservedKeys.put(Tokens.T_READS, READS);
+        reservedKeys.put(Tokens.T_REAL, REAL);
+        reservedKeys.put(Tokens.T_RECURSIVE, RECURSIVE);
+        reservedKeys.put(Tokens.T_REF, REF);
+        reservedKeys.put(Tokens.T_REFERENCES, REFERENCES);
+        reservedKeys.put(Tokens.T_REFERENCING, REFERENCING);
+        reservedKeys.put(Tokens.T_REGR_AVGX, REGR_AVGX);
+        reservedKeys.put(Tokens.T_REGR_AVGY, REGR_AVGY);
+        reservedKeys.put(Tokens.T_REGR_COUNT, REGR_COUNT);
+        reservedKeys.put(Tokens.T_REGR_INTERCEPT, REGR_INTERCEPT);
+        reservedKeys.put(Tokens.T_REGR_R2, REGR_R2);
+        reservedKeys.put(Tokens.T_REGR_SLOPE, REGR_SLOPE);
+        reservedKeys.put(Tokens.T_REGR_SXX, REGR_SXX);
+        reservedKeys.put(Tokens.T_REGR_SXY, REGR_SXY);
+        reservedKeys.put(Tokens.T_REGR_SYY, REGR_SYY);
+        reservedKeys.put(Tokens.T_RELEASE, RELEASE);
+        reservedKeys.put(Tokens.T_REPEAT, REPEAT);
+        reservedKeys.put(Tokens.T_RESIGNAL, RESIGNAL);
+        reservedKeys.put(Tokens.T_RETURN, RETURN);
+        reservedKeys.put(Tokens.T_RETURNS, RETURNS);
+        reservedKeys.put(Tokens.T_REVOKE, REVOKE);
+        reservedKeys.put(Tokens.T_RIGHT, RIGHT);
+        reservedKeys.put(Tokens.T_ROLLBACK, ROLLBACK);
+        reservedKeys.put(Tokens.T_ROLLUP, ROLLUP);
+        reservedKeys.put(Tokens.T_ROW, ROW);
+        reservedKeys.put(Tokens.T_ROW_NUMBER, ROW_NUMBER);
+        reservedKeys.put(Tokens.T_ROWS, ROWS);
+        reservedKeys.put(Tokens.T_SAVEPOINT, SAVEPOINT);
+        reservedKeys.put(Tokens.T_SCOPE, SCOPE);
+        reservedKeys.put(Tokens.T_SCROLL, SCROLL);
+        reservedKeys.put(Tokens.T_SEARCH, SEARCH);
+        reservedKeys.put(Tokens.T_SECOND, SECOND);
+        reservedKeys.put(Tokens.T_SELECT, SELECT);
+        reservedKeys.put(Tokens.T_SENSITIVE, SENSITIVE);
+        reservedKeys.put(Tokens.T_SESSION_USER, SESSION_USER);
+        reservedKeys.put(Tokens.T_SET, SET);
+        reservedKeys.put(Tokens.T_SIGNAL, SIGNAL);
+        reservedKeys.put(Tokens.T_SIMILAR, SIMILAR);
+        reservedKeys.put(Tokens.T_SMALLINT, SMALLINT);
+        reservedKeys.put(Tokens.T_SOME, SOME);
+        reservedKeys.put(Tokens.T_SPECIFIC, SPECIFIC);
+        reservedKeys.put(Tokens.T_SPECIFICTYPE, SPECIFICTYPE);
+        reservedKeys.put(Tokens.T_SQL, SQL);
+        reservedKeys.put(Tokens.T_SQLEXCEPTION, SQLEXCEPTION);
+        reservedKeys.put(Tokens.T_SQLSTATE, SQLSTATE);
+        reservedKeys.put(Tokens.T_SQLWARNING, SQLWARNING);
+        reservedKeys.put(Tokens.T_SQRT, SQRT);
+        reservedKeys.put(Tokens.T_STACKED, STACKED);
+        reservedKeys.put(Tokens.T_START, START);
+        reservedKeys.put(Tokens.T_STATIC, STATIC);
+        reservedKeys.put(Tokens.T_STDDEV_POP, STDDEV_POP);
+        reservedKeys.put(Tokens.T_STDDEV_SAMP, STDDEV_SAMP);
+        reservedKeys.put(Tokens.T_SUBMULTISET, SUBMULTISET);
+        reservedKeys.put(Tokens.T_SUBSTRING, SUBSTRING);
+        reservedKeys.put(Tokens.T_SUBSTRING_REGEX, SUBSTRING_REGEX);
+        reservedKeys.put(Tokens.T_SUM, SUM);
+        reservedKeys.put(Tokens.T_SYMMETRIC, SYMMETRIC);
+        reservedKeys.put(Tokens.T_SYSTEM, SYSTEM);
+        reservedKeys.put(Tokens.T_SYSTEM_USER, SYSTEM_USER);
+        reservedKeys.put(Tokens.T_TABLE, TABLE);
+        reservedKeys.put(Tokens.T_TABLESAMPLE, TABLESAMPLE);
+        reservedKeys.put(Tokens.T_THEN, THEN);
+        reservedKeys.put(Tokens.T_TIME, TIME);
+        reservedKeys.put(Tokens.T_TIMESTAMP, TIMESTAMP);
+        reservedKeys.put(Tokens.T_TIMEZONE_HOUR, TIMEZONE_HOUR);
+        reservedKeys.put(Tokens.T_TIMEZONE_MINUTE, TIMEZONE_MINUTE);
+        reservedKeys.put(Tokens.T_TO, TO);
+        reservedKeys.put(Tokens.T_TRAILING, TRAILING);
+        reservedKeys.put(Tokens.T_TRANSLATE, TRANSLATE);
+        reservedKeys.put(Tokens.T_TRANSLATE_REGEX, TRANSLATE_REGEX);
+        reservedKeys.put(Tokens.T_TRANSLATION, TRANSLATION);
+        reservedKeys.put(Tokens.T_TREAT, TREAT);
+        reservedKeys.put(Tokens.T_TRIGGER, TRIGGER);
+        reservedKeys.put(Tokens.T_TRIM, TRIM);
+        reservedKeys.put(Tokens.T_TRIM_ARRAY, TRIM_ARRAY);
+        reservedKeys.put(Tokens.T_TRUE, TRUE);
+        reservedKeys.put(Tokens.T_TRUNCATE, TRUNCATE);
+        reservedKeys.put(Tokens.T_UESCAPE, UESCAPE);
+        reservedKeys.put(Tokens.T_UNDO, UNDO);
+        reservedKeys.put(Tokens.T_UNION, UNION);
+        reservedKeys.put(Tokens.T_UNIQUE, UNIQUE);
+        reservedKeys.put(Tokens.T_UNKNOWN, UNKNOWN);
+        reservedKeys.put(Tokens.T_UNNEST, UNNEST);
+        reservedKeys.put(Tokens.T_UNTIL, UNTIL);
+        reservedKeys.put(Tokens.T_UPDATE, UPDATE);
+        reservedKeys.put(Tokens.T_UPPER, UPPER);
+        reservedKeys.put(Tokens.T_USER, USER);
+        reservedKeys.put(Tokens.T_USING, USING);
+        reservedKeys.put(Tokens.T_VALUE, VALUE);
+        reservedKeys.put(Tokens.T_VALUES, VALUES);
+        reservedKeys.put(Tokens.T_VAR_POP, VAR_POP);
+        reservedKeys.put(Tokens.T_VAR_SAMP, VAR_SAMP);
+        reservedKeys.put(Tokens.T_VARBINARY, VARBINARY);
+        reservedKeys.put(Tokens.T_VARCHAR, VARCHAR);
+        reservedKeys.put(Tokens.T_VARYING, VARYING);
+        reservedKeys.put(Tokens.T_WHEN, WHEN);
+        reservedKeys.put(Tokens.T_WHENEVER, WHENEVER);
+        reservedKeys.put(Tokens.T_WHERE, WHERE);
+        reservedKeys.put(Tokens.T_WIDTH_BUCKET, WIDTH_BUCKET);
+        reservedKeys.put(Tokens.T_WINDOW, WINDOW);
+        reservedKeys.put(Tokens.T_WITH, WITH);
+        reservedKeys.put(Tokens.T_WITHIN, WITHIN);
+        reservedKeys.put(Tokens.T_WITHOUT, WITHOUT);
+        reservedKeys.put(Tokens.T_WHILE, WHILE);
+        reservedKeys.put(Tokens.T_YEAR, YEAR);
+    }
+
+    private static final IntValueHashMap commandSet = new IntValueHashMap(251);
+
+    static {
+        commandSet.put(T_ACTION, ACTION);
+        commandSet.put(T_ADD, ADD);
+        commandSet.put(T_ADMIN, ADMIN);
+        commandSet.put(T_AFTER, AFTER);
+        commandSet.put(T_ALIAS, ALIAS);
+        commandSet.put(T_ALWAYS, ALWAYS);
+        commandSet.put(T_ASC, ASC);
+        commandSet.put(T_AUTOCOMMIT, AUTOCOMMIT);
+        commandSet.put(T_BACKUP, BACKUP);
+        commandSet.put(T_BEFORE, BEFORE);
+        commandSet.put(T_BIT, BIT);
+        commandSet.put(T_BLOCKING, BLOCKING);
+        commandSet.put(T_CACHE, CACHE);
+        commandSet.put(T_CACHED, CACHED);
+        commandSet.put(T_CASCADE, CASCADE);
+        commandSet.put(T_CATALOG, CATALOG);
+        commandSet.put(T_CHARACTERISTICS, CHARACTERISTICS);
+        commandSet.put(T_CHECKPOINT, CHECKPOINT);
+        commandSet.put(T_CRYPT_KEY, CRYPT_KEY);
+        commandSet.put(T_CLASS, CLASS);
+        commandSet.put(T_COLLATE, COLLATE);
+        commandSet.put(T_COLLATION, COLLATION);
+        commandSet.put(T_COMMENT, COMMENT);
+        commandSet.put(T_COMMITTED, COMMITTED);
+        commandSet.put(T_COMPACT, COMPACT);
+        commandSet.put(T_COMPRESSED, COMPRESSED);
+        commandSet.put(T_CONDITION_IDENTIFIER, Tokens.CONDITION_IDENTIFIER);
+        commandSet.put(T_CONTAINS, CONTAINS);
+        commandSet.put(T_CONTINUE, CONTINUE);
+        commandSet.put(T_CONTROL, CONTROL);
+        commandSet.put(T_CURDATE, CURDATE);
+        commandSet.put(T_CURTIME, CURTIME);
+        commandSet.put(T_DATA, DATA);
+        commandSet.put(T_DATABASE, DATABASE);
+        commandSet.put(T_DEFAULTS, DEFAULTS);
+        commandSet.put(T_DEFRAG, DEFRAG);
+        commandSet.put(T_DELAY, DELAY);
+        commandSet.put(T_DESC, DESC);
+        commandSet.put(T_DOMAIN, DOMAIN);
+        commandSet.put(T_EVENT, EVENT);
+        commandSet.put(T_EXCLUDING, EXCLUDING);
+        commandSet.put(T_EXPLAIN, EXPLAIN);
+        commandSet.put(T_FILE, FILE);
+        commandSet.put(T_FILES, FILES);
+        commandSet.put(T_FINAL, FINAL);
+        commandSet.put(T_FIRST, FIRST);
+        commandSet.put(T_G_FACTOR, G);
+        commandSet.put(T_GC, GC);
+        commandSet.put(T_GENERATED, GENERATED);
+        commandSet.put(T_GRANTED, GRANTED);
+        commandSet.put(T_HEADER, HEADER);
+        commandSet.put(T_IF, Tokens.IF);
+        commandSet.put(T_IGNORECASE, IGNORECASE);
+        commandSet.put(T_IMMEDIATELY, IMMEDIATELY);
+        commandSet.put(T_INCLUDING, INCLUDING);
+        commandSet.put(T_INCREMENT, INCREMENT);
+        commandSet.put(T_INDEX, INDEX);
+        commandSet.put(T_INITIAL, INITIAL);
+        commandSet.put(T_INPUT, INPUT);
+        commandSet.put(T_INSTEAD, INSTEAD);
+        commandSet.put(T_INTEGRITY, INTEGRITY);
+        commandSet.put(T_ISAUTOCOMMIT, ISAUTOCOMMIT);
+        commandSet.put(T_ISOLATION, ISOLATION);
+        commandSet.put(T_ISREADONLYDATABASE, ISREADONLYDATABASE);
+        commandSet.put(T_ISREADONLYDATABASEFILES, ISREADONLYDATABASEFILES);
+        commandSet.put(T_ISREADONLYSESSION, ISREADONLYSESSION);
+        commandSet.put(T_JAVA, JAVA);
+        commandSet.put(T_K_FACTOR, K);
+        commandSet.put(T_KEY, KEY);
+        commandSet.put(T_LAST, LAST);
+        commandSet.put(T_LENGTH, LENGTH);
+        commandSet.put(T_LEVEL, LEVEL);
+        commandSet.put(T_LIBRARY, LIBRARY);
+        commandSet.put(T_LIMIT, LIMIT);
+        commandSet.put(T_LOB, LOB);
+        commandSet.put(T_LOCK, LOCK);
+        commandSet.put(T_LOCKS, LOCKS);
+        commandSet.put(T_M_FACTOR, M);
+        commandSet.put(T_MATCHED, MATCHED);
+        commandSet.put(T_MAXROWS, MAXROWS);
+        commandSet.put(T_MAXVALUE, MAXVALUE);
+        commandSet.put(T_MEMORY, MEMORY);
+        commandSet.put(T_MILLIS, MILLIS);
+        commandSet.put(T_MINUS_EXCEPT, MINUS_EXCEPT);
+        commandSet.put(T_MINVALUE, MINVALUE);
+        commandSet.put(T_MVCC, MVCC);
+        commandSet.put(T_MVLOCKS, MVLOCKS);
+        commandSet.put(T_NAME, NAME);
+        commandSet.put(T_NEXT, NEXT);
+        commandSet.put(T_NIO, NIO);
+        commandSet.put(T_NOW, NOW);
+        commandSet.put(T_NULLS, NULLS);
+        commandSet.put(T_OFF, OFF);
+        commandSet.put(T_OPTION, OPTION);
+        commandSet.put(T_ORDINALITY, ORDINALITY);
+        commandSet.put(T_OVERRIDING, OVERRIDING);
+        commandSet.put(T_P_FACTOR, P);
+        commandSet.put(T_PARTIAL, PARTIAL);
+        commandSet.put(T_PASSWORD, PASSWORD);
+        commandSet.put(T_PLACING, PLACING);
+        commandSet.put(T_PLAN, PLAN);
+        commandSet.put(T_PRESERVE, PRESERVE);
+        commandSet.put(T_PRIVILEGES, PRIVILEGES);
+        commandSet.put(T_PROPERTY, PROPERTY);
+        commandSet.put(T_READ, READ);
+        commandSet.put(T_READONLY, READONLY);
+        commandSet.put(T_REFERENTIAL, REFERENTIAL);
+        commandSet.put(T_RENAME, RENAME);
+        commandSet.put(T_REPEATABLE, REPEATABLE);
+        commandSet.put(T_RESTART, RESTART);
+        commandSet.put(T_RESTRICT, RESTRICT);
+        commandSet.put(T_RESULT, RESULT);
+        commandSet.put(T_ROLE, ROLE);
+        commandSet.put(T_ROUTINE, ROUTINE);
+        commandSet.put(T_SCALE, SCALE);
+        commandSet.put(T_SCHEMA, SCHEMA);
+        commandSet.put(T_SCRIPT, SCRIPT);
+        commandSet.put(T_SCRIPTFORMAT, SCRIPTFORMAT);
+        commandSet.put(T_SEQUENCE, SEQUENCE);
+        commandSet.put(T_SERIALIZABLE, SERIALIZABLE);
+        commandSet.put(T_SERVER, SERVER);
+        commandSet.put(T_SESSION, SESSION);
+        commandSet.put(T_SHUTDOWN, SHUTDOWN);
+        commandSet.put(T_SIMPLE, SIMPLE);
+        commandSet.put(T_SIZE, SIZE);
+        commandSet.put(T_SOURCE, SOURCE);
+        commandSet.put(T_SQL_BIGINT, SQL_BIGINT);
+        commandSet.put(T_SQL_BINARY, SQL_BINARY);
+        commandSet.put(T_SQL_BIT, SQL_BIT);
+        commandSet.put(T_SQL_BLOB, SQL_BLOB);
+        commandSet.put(T_SQL_BOOLEAN, SQL_BOOLEAN);
+        commandSet.put(T_SQL_CHAR, SQL_CHAR);
+        commandSet.put(T_SQL_CLOB, SQL_CLOB);
+        commandSet.put(T_SQL_DATALINK, SQL_DATALINK);
+        commandSet.put(T_SQL_DATE, SQL_DATE);
+        commandSet.put(T_SQL_DECIMAL, SQL_DECIMAL);
+        commandSet.put(T_SQL_DOUBLE, SQL_DOUBLE);
+        commandSet.put(T_SQL_FLOAT, SQL_FLOAT);
+        commandSet.put(T_SQL_INTEGER, SQL_INTEGER);
+        commandSet.put(T_SQL_LONGNVARCHAR, SQL_LONGNVARCHAR);
+        commandSet.put(T_SQL_LONGVARBINARY, SQL_LONGVARBINARY);
+        commandSet.put(T_SQL_LONGVARCHAR, SQL_LONGVARCHAR);
+        commandSet.put(T_SQL_NCHAR, SQL_NCHAR);
+        commandSet.put(T_SQL_NCLOB, SQL_NCLOB);
+        commandSet.put(T_SQL_NUMERIC, SQL_NUMERIC);
+        commandSet.put(T_SQL_NVARCHAR, SQL_NVARCHAR);
+        commandSet.put(T_SQL_REAL, SQL_REAL);
+        commandSet.put(T_SQL_ROWID, SQL_ROWID);
+        commandSet.put(T_SQL_SMALLINT, SQL_SMALLINT);
+        commandSet.put(T_SQL_SQLXML, SQL_SQLXML);
+        commandSet.put(T_SQL_TIME, SQL_TIME);
+        commandSet.put(T_SQL_TIMESTAMP, SQL_TIMESTAMP);
+        commandSet.put(T_SQL_TINYINT, SQL_TINYINT);
+        commandSet.put(T_SQL_VARBINARY, SQL_VARBINARY);
+        commandSet.put(T_SQL_VARCHAR, SQL_VARCHAR);
+        commandSet.put(T_SQL_TSI_DAY, SQL_TSI_DAY);
+        commandSet.put(T_SQL_TSI_FRAC_SECOND, SQL_TSI_FRAC_SECOND);
+        commandSet.put(T_SQL_TSI_HOUR, SQL_TSI_HOUR);
+        commandSet.put(T_SQL_TSI_MINUTE, SQL_TSI_MINUTE);
+        commandSet.put(T_SQL_TSI_MONTH, SQL_TSI_MONTH);
+        commandSet.put(T_SQL_TSI_QUARTER, SQL_TSI_QUARTER);
+        commandSet.put(T_SQL_TSI_SECOND, SQL_TSI_SECOND);
+        commandSet.put(T_SQL_TSI_WEEK, SQL_TSI_WEEK);
+        commandSet.put(T_SQL_TSI_YEAR, SQL_TSI_YEAR);
+        commandSet.put(T_STATEMENT, STATEMENT);
+        commandSet.put(T_STYLE, STYLE);
+        commandSet.put(T_T_FACTOR, T);
+        commandSet.put(T_TEMP, TEMP);
+        commandSet.put(T_TEMPORARY, TEMPORARY);
+        commandSet.put(T_TEXT, TEXT);
+        commandSet.put(T_TIMESTAMPADD, TIMESTAMPADD);
+        commandSet.put(T_TIMESTAMPDIFF, TIMESTAMPDIFF);
+        commandSet.put(T_TO_CHAR, TO_CHAR);
+        commandSet.put(T_TODAY, TODAY);
+        commandSet.put(T_TOP, TOP);
+        commandSet.put(T_TRANSACTION, TRANSACTION);
+        commandSet.put(T_TYPE, TYPE);
+        commandSet.put(T_UNCOMMITTED, UNCOMMITTED);
+        commandSet.put(T_USAGE, USAGE);
+        commandSet.put(T_VIEW, VIEW);
+        commandSet.put(T_WORK, WORK);
+        commandSet.put(T_WRAPPER, WRAPPER);
+        commandSet.put(T_WRITE, WRITE);
+        commandSet.put(T_WRITE_DELAY, WRITE_DELAY);
+        commandSet.put(T_ZONE, ZONE);
+
+        //
+        commandSet.put(T_ACOS, ACOS);
+        commandSet.put(T_ASCII, ASCII);
+        commandSet.put(T_ASIN, ASIN);
+        commandSet.put(T_ATAN, ATAN);
+        commandSet.put(T_ATAN2, ATAN2);
+        commandSet.put(T_BITAND, BITAND);
+        commandSet.put(T_BITLENGTH, BITLENGTH);
+        commandSet.put(T_BITOR, BITOR);
+        commandSet.put(T_BITXOR, BITXOR);
+        commandSet.put(T_CASEWHEN, Tokens.CASEWHEN);
+        commandSet.put(T_CONCAT_WORD, CONCAT_WORD);
+        commandSet.put(T_COS, COS);
+        commandSet.put(T_COT, COT);
+        commandSet.put(T_DATEADD, DATEADD);
+        commandSet.put(T_DATEDIFF, DATEDIFF);
+        commandSet.put(T_DAY_NAME, DAY_NAME);
+        commandSet.put(T_DAY_OF_MONTH, DAY_OF_MONTH);
+        commandSet.put(T_DAY_OF_WEEK, DAY_OF_WEEK);
+        commandSet.put(T_DAY_OF_YEAR, DAY_OF_YEAR);
+        commandSet.put(T_DAYNAME, DAYNAME);
+        commandSet.put(T_DAYOFMONTH, DAYOFMONTH);
+        commandSet.put(T_DAYOFWEEK, DAYOFWEEK);
+        commandSet.put(T_DAYOFYEAR, DAYOFYEAR);
+        commandSet.put(T_DECODE, DECODE);
+        commandSet.put(T_DEGREES, DEGREES);
+        commandSet.put(T_DIFFERENCE, DIFFERENCE);
+        commandSet.put(T_DMOD, DMOD);
+        commandSet.put(T_GREATEST, GREATEST);
+        commandSet.put(T_HEXTORAW, HEXTORAW);
+        commandSet.put(T_IFNULL, Tokens.IFNULL);
+        commandSet.put(T_LCASE, LCASE);
+        commandSet.put(T_LEAST, LEAST);
+        commandSet.put(T_LOCATE, LOCATE);
+        commandSet.put(T_LOG, LOG);
+        commandSet.put(T_LOG10, LOG10);
+        commandSet.put(T_LTRIM, LTRIM);
+        commandSet.put(T_MONTH_NAME, MONTH_NAME);
+        commandSet.put(T_MONTHNAME, MONTHNAME);
+        commandSet.put(T_NAMES, Tokens.NAMES);
+        commandSet.put(T_NVL, Tokens.IFNULL);
+        commandSet.put(T_OCTETLENGTH, OCTETLENGTH);
+        commandSet.put(T_PI, PI);
+        commandSet.put(T_QUARTER, QUARTER);
+        commandSet.put(T_RADIANS, RADIANS);
+        commandSet.put(T_RAND, RAND);
+        commandSet.put(T_RAWTOHEX, RAWTOHEX);
+        commandSet.put(T_REGEXP_MATCHES, REGEXP_MATCHES);
+        commandSet.put(T_REPLACE, REPLACE);
+        commandSet.put(T_REVERSE, REVERSE);
+        commandSet.put(T_ROUND, ROUND);
+        commandSet.put(T_ROUNDMAGIC, ROUNDMAGIC);
+        commandSet.put(T_RTRIM, RTRIM);
+        commandSet.put(T_SECONDS_MIDNIGHT, SECONDS_MIDNIGHT);
+        commandSet.put(T_SIGN, SIGN);
+        commandSet.put(T_SIN, SIN);
+        commandSet.put(T_SOUNDEX, SOUNDEX);
+        commandSet.put(T_SPACE, SPACE);
+        commandSet.put(T_SUBSTR, SUBSTR);
+        commandSet.put(T_SYSDATE, SYSDATE);
+        commandSet.put(T_TAN, TAN);
+        commandSet.put(T_UCASE, UCASE);
+        commandSet.put(T_WEEK, WEEK);
+        commandSet.put(T_WEEK_OF_YEAR, WEEK_OF_YEAR);
+
+        //
+        commandSet.put(T_ISOLATION_LEVEL, ISOLATION_LEVEL);
+        commandSet.put(T_SESSION_ISOLATION_LEVEL, SESSION_ISOLATION_LEVEL);
+        commandSet.put(T_DATABASE_ISOLATION_LEVEL, DATABASE_ISOLATION_LEVEL);
+        commandSet.put(T_TRANSACTION_CONTROL, TRANSACTION_CONTROL);
+        commandSet.put(T_TIMEZONE, TIMEZONE);
+        commandSet.put(T_SESSION_TIMEZONE, SESSION_TIMEZONE);
+        commandSet.put(T_DATABASE_TIMEZONE, DATABASE_TIMEZONE);
+        commandSet.put(T_DATABASE_VERSION, DATABASE_VERSION);
+
+        //
+        commandSet.put(T_ASTERISK, Tokens.ASTERISK);
+        commandSet.put(T_CLOSEBRACKET, CLOSEBRACKET);
+        commandSet.put(T_COLON, Tokens.COLON);
+        commandSet.put(T_COMMA, Tokens.COMMA);
+        commandSet.put(T_CONCAT, Tokens.CONCAT);
+        commandSet.put(T_DIVIDE, Tokens.DIVIDE);
+        commandSet.put(T_EQUALS, Tokens.EQUALS);
+        commandSet.put(T_GREATER, Tokens.GREATER);
+        commandSet.put(T_GREATER_EQUALS, Tokens.GREATER_EQUALS);
+        commandSet.put(T_LEFTBRACKET, LEFTBRACKET);
+        commandSet.put(T_LESS, Tokens.LESS);
+        commandSet.put(T_LESS_EQUALS, Tokens.LESS_EQUALS);
+        commandSet.put(T_MINUS, Tokens.MINUS);
+        commandSet.put(T_NOT_EQUALS, Tokens.NOT_EQUALS);
+        commandSet.put(T_NOT_EQUALS_ALT, Tokens.NOT_EQUALS);
+        commandSet.put(T_OPENBRACKET, OPENBRACKET);
+        commandSet.put(T_PLUS, Tokens.PLUS);
+        commandSet.put(T_QUESTION, Tokens.QUESTION);
+        commandSet.put(T_RIGHTBRACKET, RIGHTBRACKET);
+        commandSet.put(T_SEMICOLON, SEMICOLON);
+    }
+
+    static int get(String token) {
+
+        int type = reservedKeys.get(token, -1);
+
+        if (type == -1) {
+            return commandSet.get(token, -1);
+        }
+
+        return type;
+    }
+
+    public static boolean isCoreKeyword(int token) {
+        return coreReservedWords.contains(token);
+    }
+
+    public static boolean isKeyword(String token) {
+        return reservedKeys.containsKey(token);
+    }
+
+    public static int getKeywordID(String token, int defaultValue) {
+        return reservedKeys.get(token, defaultValue);
+    }
+
+    public static int getNonKeywordID(String token, int defaultValue) {
+        return commandSet.get(token, defaultValue);
+    }
+
+    public static String getKeyword(int token) {
+
+        String key = (String) reservedKeys.getKey(token);
+
+        if (key != null) {
+            return key;
+        }
+
+        key = (String) commandSet.getKey(token);
+
+        return key;
+    }
+
+    private static final OrderedIntHashSet coreReservedWords;
+
+    static {
+
+        // minimal set of identifier not allowed as table / column / alias names
+        // these are in effect interpreted as reserved words used by HSQLDB
+        coreReservedWords = new OrderedIntHashSet(128);
+
+        short[] keyword = {
+            ADMIN, AS, AND, ALL, ANY, AT, AVG, BY, BETWEEN, BOTH, CALL, CASE,
+            CAST, CORRESPONDING, CONVERT, COUNT, COALESCE, CREATE, CROSS,
+            DISTINCT, DROP, ELSE, END, EVERY, EXISTS, EXCEPT, FOR, FROM, FULL,
+            GRANT, GROUP, HAVING, INTO, IS, IN, INTERSECT, JOIN, INNER, LEFT,
+            LEADING, LIKE, MAX, MIN, NATURAL, NULLIF, NOT, ON, ORDER, OR,
+            OUTER, PRIMARY, REFERENCES, RIGHT, SELECT, SET, SOME, STDDEV_POP,
+            STDDEV_SAMP, SUM, TABLE, THEN, TO, TRAILING, TRIGGER, UNION,
+            UNIQUE, USING, VALUES, VAR_POP, VAR_SAMP, WHEN, WHERE, WITH,
+        };
+
+        for (int i = 0; i < keyword.length; i++) {
+            coreReservedWords.add(keyword[i]);
+        }
+    }
+
+    public static final short[] SQL_INTERVAL_FIELD_CODES = new short[] {
+        Tokens.YEAR, Tokens.MONTH, Tokens.DAY, Tokens.HOUR, Tokens.MINUTE,
+        Tokens.SECOND
+    };
+    public static final String[] SQL_INTERVAL_FIELD_NAMES = new String[] {
+        Tokens.T_YEAR, Tokens.T_MONTH, Tokens.T_DAY, Tokens.T_HOUR,
+        Tokens.T_MINUTE, Tokens.T_SECOND
+    };
+    private static final IntKeyHashMap sqlTSILookup = new IntKeyHashMap(10);
+
+    static {
+        sqlTSILookup.put(SQL_TSI_DAY, T_SQL_TSI_DAY);
+        sqlTSILookup.put(SQL_TSI_FRAC_SECOND, T_SQL_TSI_FRAC_SECOND);
+        sqlTSILookup.put(SQL_TSI_HOUR, T_SQL_TSI_HOUR);
+        sqlTSILookup.put(SQL_TSI_MINUTE, T_SQL_TSI_MINUTE);
+        sqlTSILookup.put(SQL_TSI_MONTH, T_SQL_TSI_MONTH);
+        sqlTSILookup.put(SQL_TSI_QUARTER, T_SQL_TSI_QUARTER);
+        sqlTSILookup.put(SQL_TSI_SECOND, T_SQL_TSI_SECOND);
+        sqlTSILookup.put(SQL_TSI_WEEK, T_SQL_TSI_WEEK);
+        sqlTSILookup.put(SQL_TSI_YEAR, T_SQL_TSI_YEAR);
+    }
+
+    public static String getSQLTSIString(int token) {
+        return (String) sqlTSILookup.get(token);
+    }
+}
diff --git a/doc/verbatim/src/org/hsqldb/Trigger.java b/doc/verbatim/src/org/hsqldb/Trigger.java
new file mode 100644
index 0000000..a3979be
--- /dev/null
+++ b/doc/verbatim/src/org/hsqldb/Trigger.java
@@ -0,0 +1,128 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+// fredt@users 20030727 - signature altered to support update triggers
+/*
+
+Contents of row1[] and row2[] in each type of trigger.
+
+AFTER INSERT
+ - row1[] contains single String object = "Statement-level".
+
+AFTER UPDATE
+ - row1[] contains single String object = "Statement-level".
+
+AFTER DELETE
+ - row1[] contains single String object = "Statement-level".
+
+BEFORE INSERT FOR EACH ROW
+ - row2[] contains data about to be inserted and this can
+be modified within the trigger such that modified data gets written to the
+database.
+
+AFTER INSERT FOR EACH ROW
+ - row2[] contains data just inserted into the table.
+
+BEFORE UPDATE FOR EACH ROW
+ - row1[] contains currently stored data and not the data that is about to be
+updated.
+
+ - row2[] contains the data that is about to be updated.
+
+AFTER UPDATE FOR EACH ROW
+ - row1[] contains old stored data.
+ - row2[] contains the new data.
+
+BEFORE DELETE FOR EACH ROW
+ - row1[] contains row data about to be deleted.
+
+AFTER DELETE FOR EACH ROW
+ - row1[] contains row data that has been deleted.
+
+List compiled by Andrew Knight (quozzbat@users)
+*/
+
+/**
+ * The interface an HSQLDB TRIGGER must implement. The user-supplied class that
+ * implements this must have a default constructor.
+ *
+ * @author Peter Hudson
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public interface Trigger {
+
+    // type of trigger
+    int INSERT_AFTER      = 0;
+    int DELETE_AFTER      = 1;
+    int UPDATE_AFTER      = 2;
+    int INSERT_AFTER_ROW  = 3;
+    int DELETE_AFTER_ROW  = 4;
+    int UPDATE_AFTER_ROW  = 5;
+    int INSERT_BEFORE_ROW = 6;
+    int DELETE_BEFORE_ROW = 7;
+    int UPDATE_BEFORE_ROW = 8;
+
+    /**
+     * The method invoked upon each triggered action.
+     *
+     * <p> type contains the integer index id for trigger type, e.g.
+     * TriggerDef.INSERT_AFTER
+     *
+     * <p> For all triggers defined as default FOR EACH STATEMENT both
+     *  oldRow and newRow are null.
+     *
+     * <p> For triggers defined as FOR EACH ROW, the following will apply:
+     *
+     * <p> When UPDATE triggers are fired, oldRow contains the existing values
+     * of the table row and newRow contains the new values.
+     *
+     * <p> For INSERT triggers, oldRow is null and newRow contains the table row
+     * to be inserted. For DELETE triggers, newRow is null and oldRow contains
+     * the table row to be deleted.
+     *
+     * <p> For error conditions, users can construct an HsqlException using one
+     * of the static methods of org.hsqldb.error.Error with a predefined
+     * SQL State from org.hsqldb.error.ErrorCode.
+     *
+     * @param type int
+     * @param trigName the name of the trigger
+     * @param tabName the name of the table upon which the triggered action is
+     *   occuring
+     * @param oldRow the old row
+     * @param newRow the new row
+     * @throws HsqlException
+     */
+    void fire(int type, String trigName, String tabName, Object[] oldRow,
+              Object[] newRow) throws HsqlException;
+}
diff --git a/doc/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java b/doc/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java
new file mode 100644
index 0000000..1fefc45
--- /dev/null
+++ b/doc/verbatim/src/org/hsqldb/sample/SqlFileEmbedder.java
@@ -0,0 +1,150 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import org.hsqldb.lib.RCData;
+import org.hsqldb.cmdline.SqlFile;
+import org.hsqldb.cmdline.SqlToolError;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Sample class which executes SQL files, by embedding SqlFile.
+ * <P/>
+ * Suitable for using as a template.
+ * <P/>
+ * This class also serves as an example of using RCData to allow your
+ * application users to store JDBC access information in a convenient
+ * text file.
+ *
+ * @see #main(String[])
+ * @see SqlFile
+ * @see RCData
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class SqlFileEmbedder {
+    private Connection conn;
+
+    /**
+     * For applications that use a persistent JDBC connection, this class can
+     * be used to encapsulate that connection.  (Just strip out the SqlFile
+     * stuff if you don't need that).
+     *
+     * @return The encapsulated JDBC Connection.
+     */
+    public Connection getConn() {
+        return conn;
+    }
+
+    /**
+     * Run<PRE>
+     *     java SqlFileEmbedder</PRE>
+     * to see Syntax message.
+     */
+    public static void main(String[] sa) throws Exception {
+        if (sa.length < 3) {
+            System.err.println("SYNTAX:  " + SqlFileEmbedder.class.getName()
+                    + " path/ro/file.rc URLID file1.sql...");
+            System.exit(2);
+        }
+        SqlFileEmbedder embedder =
+                new SqlFileEmbedder(new File(sa[0]), sa[1]);
+        String[] files = new String[sa.length - 2];
+        for (int i = 0; i < sa.length - 2; i++) {
+            files[i] = sa[i + 2];
+        }
+        try {
+            embedder.executeFiles(files);
+        } finally {
+            try {
+                embedder.getConn().close();
+            } catch (SQLException se) {
+                // Purposefully ignoring.
+                // We have done what we want and are now going to exit, so
+                // who cares.
+            }
+        }
+    }
+
+    /**
+     * Instantiates SqlFileEmbedder object and connects to specified database.
+     * <P/>
+     * N.b., you do not need to use RCData to use SqlFile.
+     * All SqlFile needs is a live Connection.
+     * I'm using RCData because it is a convenient way for a non-contained
+     * app (i.e. one that doesn't run in a 3rd party container) to get a
+     * Connection.
+     */
+    public SqlFileEmbedder(File rcFile, String urlid) throws Exception {
+        conn = (new RCData(rcFile, urlid)).getConnection();
+        conn.setAutoCommit(false);
+    }
+
+    /**
+     * Your own classes can use this method to execute SQL files.
+     * <P/>
+     * See source code for the main(String[]) method for an example of calling
+     * this method.
+     *
+     * @see #main(String[])
+     */
+    public void executeFiles(String[] fileStrings)
+            throws IOException, SqlToolError, SQLException {
+        Map<String, String> sqlVarMap = new HashMap<String, String>();
+        sqlVarMap.put("invoker", getClass().getName());
+        // This variable is pretty useless, but this should show you how to
+        // set variables which you can access inside of scripts like *{this}.
+
+        File file;
+        SqlFile sqlFile;
+        for (String fileString : fileStrings) {
+            file = new File(fileString);
+            if (!file.isFile())
+                throw new IOException("SQL file not present: "
+                        + file.getAbsolutePath());
+            sqlFile = new SqlFile(file);
+            sqlFile.setConnection(conn);
+            sqlFile.addUserVars(sqlVarMap);
+            sqlFile.execute();
+
+            // The only reason for the following two statements is so that
+            // changes made by one .sql file will effect the future SQL files.
+            // Has no effect if you only execute one SQL file.
+            conn = sqlFile.getConnection();
+            sqlVarMap = sqlFile.getUserVars();
+        }
+    }
+}
diff --git a/doc/verbatim/src/org/hsqldb/sample/Testdb.java b/doc/verbatim/src/org/hsqldb/sample/Testdb.java
new file mode 100644
index 0000000..f211469
--- /dev/null
+++ b/doc/verbatim/src/org/hsqldb/sample/Testdb.java
@@ -0,0 +1,203 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * Title:        Testdb
+ * Description:  simple hello world db example of a
+ *               standalone persistent db application
+ *
+ *               every time it runs it adds four more rows to sample_table
+ *               it does a query and prints the results to standard out
+ *
+ * Author: Karl Meissner karl@meissnersd.com
+ */
+public class Testdb {
+
+    Connection conn;                                                //our connnection to the db - presist for life of program
+
+    // we dont want this garbage collected until we are done
+    public Testdb(String db_file_name_prefix) throws Exception {    // note more general exception
+
+        // Load the HSQL Database Engine JDBC driver
+        // hsqldb.jar should be in the class path or made part of the current jar
+        Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+        // connect to the database.   This will load the db files and start the
+        // database if it is not alread running.
+        // db_file_name_prefix is used to open or create files that hold the state
+        // of the db.
+        // It can contain directory names relative to the
+        // current working directory
+        conn = DriverManager.getConnection("jdbc:hsqldb:"
+                                           + db_file_name_prefix,    // filenames
+                                           "SA",                     // username
+                                           "");                      // password
+    }
+
+    public void shutdown() throws SQLException {
+
+        Statement st = conn.createStatement();
+
+        // db writes out to files and performs clean shuts down
+        // otherwise there will be an unclean shutdown
+        // when program ends
+        st.execute("SHUTDOWN");
+        conn.close();    // if there are no other open connection
+    }
+
+//use for SQL command SELECT
+    public synchronized void query(String expression) throws SQLException {
+
+        Statement st = null;
+        ResultSet rs = null;
+
+        st = conn.createStatement();         // statement objects can be reused with
+
+        // repeated calls to execute but we
+        // choose to make a new one each time
+        rs = st.executeQuery(expression);    // run the query
+
+        // do something with the result set.
+        dump(rs);
+        st.close();    // NOTE!! if you close a statement the associated ResultSet is
+
+        // closed too
+        // so you should copy the contents to some other object.
+        // the result set is invalidated also  if you recycle an Statement
+        // and try to execute some other query before the result set has been
+        // completely examined.
+    }
+
+//use for SQL commands CREATE, DROP, INSERT and UPDATE
+    public synchronized void update(String expression) throws SQLException {
+
+        Statement st = null;
+
+        st = conn.createStatement();    // statements
+
+        int i = st.executeUpdate(expression);    // run the query
+
+        if (i == -1) {
+            System.out.println("db error : " + expression);
+        }
+
+        st.close();
+    }    // void update()
+
+    public static void dump(ResultSet rs) throws SQLException {
+
+        // the order of the rows in a cursor
+        // are implementation dependent unless you use the SQL ORDER statement
+        ResultSetMetaData meta   = rs.getMetaData();
+        int               colmax = meta.getColumnCount();
+        int               i;
+        Object            o = null;
+
+        // the result set is a cursor into the data.  You can only
+        // point to one row at a time
+        // assume we are pointing to BEFORE the first row
+        // rs.next() points to next row and returns true
+        // or false if there is no next row, which breaks the loop
+        for (; rs.next(); ) {
+            for (i = 0; i < colmax; ++i) {
+                o = rs.getObject(i + 1);    // Is SQL the first column is indexed
+
+                // with 1 not 0
+                System.out.print(o.toString() + " ");
+            }
+
+            System.out.println(" ");
+        }
+    }                                       //void dump( ResultSet rs )
+
+    public static void main(String[] args) {
+
+        Testdb db = null;
+
+        try {
+            db = new Testdb("db_file");
+        } catch (Exception ex1) {
+            ex1.printStackTrace();    // could not start db
+
+            return;                   // bye bye
+        }
+
+        try {
+
+            //make an empty table
+            //
+            // by declaring the id column IDENTITY, the db will automatically
+            // generate unique values for new rows- useful for row keys
+            db.update(
+                "CREATE TABLE sample_table ( id INTEGER IDENTITY, str_col VARCHAR(256), num_col INTEGER)");
+        } catch (SQLException ex2) {
+
+            //ignore
+            //ex2.printStackTrace();  // second time we run program
+            //  should throw execption since table
+            // already there
+            //
+            // this will have no effect on the db
+        }
+
+        try {
+
+            // add some rows - will create duplicates if run more then once
+            // the id column is automatically generated
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Ford', 100)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Toyota', 200)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Honda', 300)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('GM', 400)");
+
+            // do a query
+            db.query("SELECT * FROM sample_table WHERE num_col < 250");
+
+            // at end of program
+            db.shutdown();
+        } catch (SQLException ex3) {
+            ex3.printStackTrace();
+        }
+    }    // main()
+}    // class Testdb
+
diff --git a/doc/verbatim/src/org/hsqldb/sample/TriggerSample.java b/doc/verbatim/src/org/hsqldb/sample/TriggerSample.java
new file mode 100644
index 0000000..42831c6
--- /dev/null
+++ b/doc/verbatim/src/org/hsqldb/sample/TriggerSample.java
@@ -0,0 +1,506 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.Trigger;
+import org.hsqldb.lib.StringUtil;
+
+// peterhudson@users 20020130 - patch 478657 by peterhudson - new class
+// fredt@users 20030727 - signature altered
+// boucherb@users 20040315 - sample updated
+
+/**
+ * <P>Sample code for use of triggers in hsqldb.
+ *
+ * This class org.hsqldb.sample package, but a typical implementation is in
+ * users's class hierarchy.
+ *
+ * SQL to invoke is:<p>
+ * CREATE TRIGGER triggerSample BEFORE|AFTER INSERT|UPDATE|DELETE
+ * ON myTable [FOR EACH ROW] [QUEUE n] [NOWAIT] CALL "myPackage.trigClass"<br>
+ *
+ * This will create a thread that will wait for its firing event to occur;
+ * when this happens, the trigger's thread runs the 'trigClass.fire'
+ * Note that this is still in the same Java Virtual Machine as the
+ * database, so make sure the fired method does not hang.<p>
+ *
+ * There is a queue of events waiting to be run by each trigger thread.
+ * This is particularly useful for 'FOR EACH ROW' triggers, when a large
+ * number of trigger events occur in rapid succession, without the trigger
+ * thread getting a chance to run. If the queue becomes full, subsequent
+ * additions to it cause the database engine to suspend awaiting space
+ * in the queue. Take great care to avoid this situation if the trigger
+ * action involves accessing the database, as deadlock will occur.
+ * This can be avoided either by ensuring the QUEUE parameter makes a large
+ * enough queue, or by using the NOWAIT parameter, which causes a new
+ * trigger event to overwrite the most recent event in the queue.
+ * The default queue size is 1024.<p>
+ *
+ * Ensure that "myPackage.trigClass" is present in the classpath which
+ * you use to start hsql.<p>
+ *
+ * If the method wants to access the database, it must establish
+ * a JDBC connection.<p>
+ *
+ * When the 'fire' method is called, it is passed the following arguments: <p>
+ *
+ * fire (int type, String trigName, String tabName, Object oldRow[],
+ *       Object[] newRow) <p>
+ *
+ * where 'type' is one of the values enumerated in the Trigger interface and
+ * the 'oldRow'/'newRow' pair represents the rows acted on. The first
+ * length - 1 array slots contain column values and the final slot contains
+ * either null or the value of the internally assigned row identity, if
+ * the concerned table has no primary key. The final slot must _never_ be
+ * modified. <p>
+ *
+ * The mapping of row classes to database types is specified in
+ * /doc/hsqlSyntax.html#Datatypes. <p>
+ *
+ * To be done:<p>
+ *
+ * <ol>
+ * <li> Implement the "jdbc:default:connection: URL to provide transparent
+ *      and portable access to internal connections for use in triggers and
+ *      stored procedures. <p>
+ *
+ * <li> Implement declaritive column to trigger method argument
+ *      mapping, conditional execution (WHEN clause), etc. <p>
+ *
+ * <li> Investigate and refine synchronous and asynchronous trigger models. <p>
+ *
+ *      Because certain combinations of trigger create parameters cause the
+ *      individual triggered actions of a multirow update to run in different
+ *      threads, it is possible for an 'after' trigger to run before its
+ *      corresponding 'before' trigger; the acceptability and implications
+ *      of this needs to be investigated, documented and the behaviour of
+ *      the engine fully specified.
+ *
+ * <li> Investigate and implement the SQL 200n specified execution stack under
+ *      arbitrary triggered action and SQL-invoked routine call graphs.
+ * </ol>
+ *
+ * @author Peter Hudson
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+public class TriggerSample implements Trigger {
+
+    static final PrintWriter out  = new PrintWriter(System.out);
+    static final String      drv  = "org.hsqldb.jdbc.JDBCDriver";
+    static final String      url  = "jdbc:hsqldb:mem:trigger-sample";
+    static final String      usr  = "SA";
+    static final String      pwd  = "";
+    static final String      impl = TriggerSample.class.getName();
+    static final String      tn   = "trig_test";
+    static final String drop_test_table_stmt = "DROP TABLE " + tn
+        + " IF EXISTS";
+    static final String create_test_table_stmt = "CREATE TABLE " + tn
+        + "(id INTEGER PRIMARY KEY, value VARCHAR(20))";
+    static final String drop_audit_table_stmt = "DROP TABLE audit IF EXISTS";
+    static final String create_audit_table_stmt = "CREATE TABLE audit("
+        + "id  INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1), "
+        + "op  VARCHAR(6), " + "tn  VARCHAR(20), " + "ors LONGVARCHAR, "
+        + "nrs LONGVARCHAR, " + "ts  TIMESTAMP DEFAULT CURRENT_TIMESTAMP)";
+    static final String audit_insert_stmt =
+        "INSERT INTO audit(op, tn, ors, nrs) VALUES(?, ?, ?, ?)";
+
+    /**
+     * A sample HSQLDB Trigger interface implementation. <p>
+     *
+     * This sample prints information about the firing trigger and records
+     * actions in an audit table. <p>
+     *
+     * The techniques used here are simplified dramatically for demonstration
+     * purposes and are in no way recommended as a model upon which to build
+     * actual installations involving triggered actions.
+     *
+     * @param typ trigger type
+     * @param trn trigger name
+     * @param tn  table name
+     * @param or  old row
+     * @param nr  new row
+     */
+    public void fire(int typ, String trn, String tn, Object[] or,
+                     Object[] nr) {
+
+        synchronized (TriggerSample.class) {
+            String ors = or == null ? "null"
+                                    : StringUtil.arrayToString(or);
+            String nrs = nr == null ? "null"
+                                    : StringUtil.arrayToString(nr);
+
+            out.println("----------------------------------------");
+            out.println(getTriggerDescriptor(trn, typ, tn));
+            out.println("old row : " + ors);
+            out.println("new row : " + nrs);
+            out.flush();
+
+            if ("TRIG_TEST".equals(tn)) {
+                switch (typ) {
+
+                    case INSERT_BEFORE_ROW : {
+
+                        // Business rule: ID shall be less than 11.
+                        // (Marti DiBergi, we love you ;-)
+                        // You can cast row[i] given your knowledge of what
+                        // the table format is:
+                        final int ID = ((Number) nr[0]).intValue();
+
+                        doAssert(ID < 11, "ID < 11");
+
+                        break;
+                    }
+                    case UPDATE_BEFORE_ROW : {
+
+                        // Business rule:  ignore update of VALUE 'unchangable'.
+                        if ("unchangable".equals(or[1])) {
+                            nr[1] = or[1];    // short-circuit the update
+                        }
+
+                        // !!!Warning!!!
+                        // The engine does not check the class of substituted
+                        // values; it's up to you to use the correct class.
+                        // For example, this will cause database curruption:
+                        //  nr[1] = new Integer(5);
+                        break;
+                    }
+                }
+            }
+
+            doAuditStep(typ, tn, ors, nrs);
+        }
+    }
+
+    private static void doAssert(boolean b, String msg) {
+
+        if (b) {
+
+            // do nothing
+        } else {
+            throw org.hsqldb.error.Error.error(ErrorCode.GENERAL_ERROR,
+                                               msg);
+        }
+    }
+
+    private static void doAuditStep(int typ, String tn, String ors,
+                                    String nrs) {
+
+        Connection        conn;
+        PreparedStatement stmt;
+
+        switch (typ) {
+
+            case INSERT_AFTER_ROW :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER_ROW : {
+                try {
+                    conn = getConnection();
+                    stmt = conn.prepareStatement(audit_insert_stmt);
+
+                    stmt.setString(1, getOperationSpec(typ));
+                    stmt.setString(2, tn);
+                    stmt.setString(3, ors);
+                    stmt.setString(4, nrs);
+                    stmt.executeUpdate();
+                    conn.close();
+                } catch (SQLException se) {
+                    se.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public static String getWhenSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_BEFORE_ROW :
+            case UPDATE_BEFORE_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "BEFORE";
+            }
+            case INSERT_AFTER :
+            case INSERT_AFTER_ROW :
+            case UPDATE_AFTER :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER :
+            case DELETE_AFTER_ROW : {
+                return "AFTER";
+            }
+            default : {
+                return "";
+            }
+        }
+    }
+
+    public static String getOperationSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_AFTER :
+            case INSERT_AFTER_ROW :
+            case INSERT_BEFORE_ROW : {
+                return "INSERT";
+            }
+            case UPDATE_AFTER :
+            case UPDATE_AFTER_ROW :
+            case UPDATE_BEFORE_ROW : {
+                return "UPDATE";
+            }
+            case DELETE_AFTER :
+            case DELETE_AFTER_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "DELETE";
+            }
+            default : {
+                return "";
+            }
+        }
+    }
+
+    public static String getQueueSpec(int qs) {
+        return (qs < 0) ? ""
+                        : ("QUEUE " + qs);
+    }
+
+    public static String getForEachSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_BEFORE_ROW :
+            case INSERT_AFTER_ROW :
+            case UPDATE_BEFORE_ROW :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "FOR EACH ROW";
+            }
+            default : {
+                return "FOR EACH STATEMENT";
+            }
+        }
+    }
+
+    public static String getTriggerDDL(String trn, int typ, String tab,
+                                       int qs,
+                                       String impl) throws SQLException {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("CREATE TRIGGER ");
+        sb.append(trn);
+        sb.append(' ');
+        sb.append(getWhenSpec(typ));
+        sb.append(' ');
+        sb.append(getOperationSpec(typ));
+        sb.append(" ON ");
+        sb.append(tab);
+        sb.append(' ');
+        sb.append(getForEachSpec(typ));
+        sb.append(' ');
+        sb.append(getQueueSpec(qs));
+        sb.append(" CALL \"");
+        sb.append(impl);
+        sb.append("\"");
+
+        return sb.toString();
+    }
+
+    public static String getTriggerDescriptor(String trn, int typ,
+            String tab) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("TRIGGER : ");
+        sb.append(trn);
+        sb.append(' ');
+        sb.append(getWhenSpec(typ));
+        sb.append(' ');
+        sb.append(getOperationSpec(typ));
+        sb.append(" ON ");
+        sb.append(tab);
+        sb.append(' ');
+        sb.append(getForEachSpec(typ));
+
+        return sb.toString();
+    }
+
+    private static Connection getConnection() throws SQLException {
+
+        try {
+            Class.forName(drv).newInstance();
+
+            return DriverManager.getConnection(url, usr, pwd);
+        } catch (SQLException se) {
+            throw se;
+        } catch (Exception e) {
+            throw new SQLException(e.toString());
+        }
+    }
+
+    private static void createTrigger(Statement stmt, String trn,
+                                      int typ) throws SQLException {
+        stmt.execute(getTriggerDDL(trn, typ, tn, 0, impl));
+    }
+
+    private static void setup() throws SQLException {
+
+        Connection conn = getConnection();
+        Statement  stmt = conn.createStatement();
+
+        stmt.execute(drop_test_table_stmt);
+        stmt.execute(create_test_table_stmt);
+        stmt.execute(drop_audit_table_stmt);
+        stmt.execute(create_audit_table_stmt);
+        createTrigger(stmt, "tibr_" + tn, INSERT_BEFORE_ROW);
+        createTrigger(stmt, "tia_" + tn, INSERT_AFTER);
+        createTrigger(stmt, "tiar_" + tn, INSERT_AFTER_ROW);
+        createTrigger(stmt, "tubr_" + tn, UPDATE_BEFORE_ROW);
+        createTrigger(stmt, "tua_" + tn, UPDATE_AFTER);
+        createTrigger(stmt, "tuar_" + tn, UPDATE_AFTER_ROW);
+        createTrigger(stmt, "tdbr_" + tn, DELETE_BEFORE_ROW);
+        createTrigger(stmt, "tda_" + tn, DELETE_AFTER);
+        createTrigger(stmt, "tdar_" + tn, DELETE_AFTER_ROW);
+        stmt.close();
+        conn.close();
+    }
+
+    private static void doSomeWork() throws SQLException {
+
+        Connection conn = getConnection();
+        Statement  stmt = conn.createStatement();
+
+        conn.setAutoCommit(false);
+        stmt.execute("INSERT INTO trig_test VALUES (1, 'hello')");
+        stmt.execute("INSERT INTO trig_test VALUES (2, 'now what?')");
+        stmt.execute("INSERT INTO trig_test VALUES (3, 'unchangable')");
+        stmt.execute("INSERT INTO trig_test VALUES (4, 'goodbye')");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.execute("UPDATE trig_test SET value = 'all done'");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.execute("DELETE FROM trig_test");
+        conn.rollback();
+        dumpTable("trig_test");
+
+        try {
+            stmt.execute("INSERT INTO trig_test VALUES(11, 'whatever')");
+        } catch (SQLException se) {
+            se.printStackTrace();
+        }
+
+        stmt.execute("INSERT INTO trig_test VALUES(10, 'whatever')");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.close();
+        conn.close();
+    }
+
+    private static void dumpTable(String tn) throws SQLException {
+
+        Connection        conn  = getConnection();
+        Statement         stmt  = conn.createStatement();
+        ResultSet         rs    = stmt.executeQuery("select * from " + tn);
+        ResultSetMetaData rsmd  = rs.getMetaData();
+        int               count = rsmd.getColumnCount();
+
+        out.println();
+        out.println("****************************************");
+        out.println("DUMP FOR TABLE: " + tn);
+        out.println("****************************************");
+        out.flush();
+
+        while (rs.next()) {
+            out.print("[");
+
+            for (int i = 1; i <= count; i++) {
+                out.print(rs.getString(i));
+
+                if (i < count) {
+                    out.print(" : ");
+                }
+            }
+
+            out.println("]");
+        }
+
+        out.println();
+        out.flush();
+        rs.close();
+        stmt.close();
+        conn.close();
+    }
+
+    private static void runSample() throws SQLException {
+
+        setup();
+        doSomeWork();
+        dumpTable("audit");
+    }
+
+    public static void main(String[] args) throws SQLException {
+        runSample();
+    }
+}
+/*
+    test SQL
+    CREATE CACHED TABLE trig_test (int_field     integer)
+    CREATE TRIGGER ins_before BEFORE INSERT ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER ins_after  AFTER  INSERT ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_before BEFORE UPDATE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_after  AFTER  UPDATE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_before_row BEFORE UPDATE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_after_row  AFTER  UPDATE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_before BEFORE DELETE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_after  AFTER  DELETE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_before_row BEFORE DELETE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_after_row  AFTER  DELETE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    INSERT INTO trig_test VALUES (1)
+    INSERT INTO trig_test VALUES (2)
+    INSERT INTO trig_test VALUES (3)
+    UPDATE trig_test SET int_field = int_field + 3
+    DELETE FROM trig_test
+ */
diff --git a/doc/verbatim/src/org/hsqldb/server/Servlet.java b/doc/verbatim/src/org/hsqldb/server/Servlet.java
new file mode 100644
index 0000000..e26635a
--- /dev/null
+++ b/doc/verbatim/src/org/hsqldb/server/Servlet.java
@@ -0,0 +1,320 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Session;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.rowio.RowInputBinary;
+import org.hsqldb.rowio.RowOutputBinary;
+
+// fredt@users 20020130 - patch 475586 by wreissen@users
+// fredt@users 20020328 - patch 1.7.0 by fredt - error trapping
+// fredt@users 20030630 - patch 1.7.2 - new protocol, persistent sessions
+// fredt@users 20041112 - patch by Willian Crick - use web_inf directory
+
+/**
+ * Servlet can act as an interface between the client and the database for the
+ * the client / server mode of HSQL Database Engine. It uses the HTTP protocol
+ * for communication. This class is not required if the included HSQLDB
+ * Weberver is used on the server host. But if the host is running a J2EE
+ * application server or a servlet container such as Tomcat, the Servlet class
+ * can be hosted on this server / container to serve external requests from
+ * external hosts.<p>
+ * The remote applet / application should
+ * use the normal JDBC interfaces to connect to the URL of this servlet. An
+ * example URL is:
+ * <pre>
+ * jdbc:hsqldb:http://myhost.com:8080/servlet/org.hsqldb.server.Servlet
+ * </pre>
+ * The database path/name is taken from the servlet engine property:
+ * <pre>
+ * hsqldb.server.database
+ * </pre>
+ * <p>
+ * If the database is deployed in the WEB-INF directory of the servlet container,
+ * the property:
+ * <pre>
+ *  hsqldb.server.use_web-inf_path
+ * </pre>
+ * should be set "true" in the web.xml file of the servlet container.
+ * In this case, the database path should begin with a "/".
+ *
+ * JDBC connections via the HTTP protocol are persistent
+ * in the JDBC sense. The JDBC Connection that is established can support
+ * transactions spanning several Statement calls and real PreparedStatement
+ * calls are supported. This class has been rewritten to support the new
+ * features.<p>
+ * (fredt@users)<p>
+ *
+ * Extensively rewritten for HSQLDB.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class Servlet extends javax.servlet.http.HttpServlet {
+
+    private static final int BUFFER_SIZE = 256;
+    private String           dbType;
+    private String           dbPath;
+    private String           errorStr;
+    private RowOutputBinary  rowOut;
+    private RowInputBinary   rowIn;
+    private int              iQueries;
+
+    public void init(ServletConfig config) {
+
+        try {
+            super.init(config);
+
+            rowOut = new RowOutputBinary(BUFFER_SIZE, 1);
+            rowIn  = new RowInputBinary(rowOut);
+        } catch (ServletException e) {
+            log(e.toString());
+        }
+
+        String dbStr = getInitParameter("hsqldb.server.database");
+
+        if (dbStr == null) {
+            dbStr = ".";
+        }
+
+// begin WEB-INF patch */
+        String useWebInfStr =
+            getInitParameter("hsqldb.server.use_web-inf_path");
+
+        if (!dbStr.equals(".") && "true".equalsIgnoreCase(useWebInfStr)) {
+            dbStr = getServletContext().getRealPath("/") + "WEB-INF/" + dbStr;
+        }
+
+// end WEB-INF patch
+        HsqlProperties dbURL = DatabaseURL.parseURL(dbStr, false, false);
+
+        log("Database filename = " + dbStr);
+
+        if (dbURL == null) {
+            errorStr = "Bad Database name";
+        } else {
+            dbPath = dbURL.getProperty("database");
+            dbType = dbURL.getProperty("connection_type");
+
+            try {
+
+// loosecannon1@users 1.7.2 patch properties on the JDBC URL
+                DatabaseManager.getDatabase(dbType, dbPath, dbURL);
+            } catch (HsqlException e) {
+                errorStr = e.getMessage();
+            }
+        }
+
+        log(errorStr);
+        log("Initialization completed.");
+    }
+
+    private static long lModified = 0;
+
+    protected long getLastModified(HttpServletRequest req) {
+
+        // this is made so that the cache of the http server is not used
+        // maybe there is some other way
+        return lModified++;
+    }
+
+    public void doGet(HttpServletRequest request,
+                      HttpServletResponse response)
+                      throws IOException, ServletException {
+
+        String query = request.getQueryString();
+
+        if ((query == null) || (query.length() == 0)) {
+            response.setContentType("text/html");
+
+// fredt@users 20020130 - patch 1.7.0 by fredt
+// to avoid caching on the browser
+            response.setHeader("Pragma", "no-cache");
+
+            PrintWriter out = response.getWriter();
+
+            out.println(
+                "<html><head><title>HSQL Database Engine Servlet</title>");
+            out.println("</head><body><h1>HSQL Database Engine Servlet</h1>");
+            out.println("The servlet is running.<p>");
+
+            if (errorStr == null) {
+                out.println("The database is also running.<p>");
+                out.println("Database name: " + dbType + dbPath + "<p>");
+                out.println("Queries processed: " + iQueries + "<p>");
+            } else {
+                out.println("<h2>The database is not running!</h2>");
+                out.println("The error message is:<p>");
+                out.println(errorStr);
+            }
+
+            out.println("</body></html>");
+        }
+    }
+
+    public void doPost(HttpServletRequest request,
+                       HttpServletResponse response)
+                       throws IOException, ServletException {
+
+        synchronized (this) {
+            DataInputStream  inStream = null;
+            DataOutputStream dataOut  = null;
+
+            try {
+
+                // fredt@users - the servlet container, Resin does not return all
+                // the bytes with one call to input.read(b,0,len) when len > 8192
+                // bytes, the loop in the Result.read() method handles this
+                inStream = new DataInputStream(request.getInputStream());
+
+                int  databaseID = inStream.readInt();
+                long sessionID  = inStream.readLong();
+                int  mode       = inStream.readByte();
+                Session session = DatabaseManager.getSession(databaseID,
+                    sessionID);
+                Result resultIn = Result.newResult(session, mode, inStream,
+                                                   rowIn);
+
+                resultIn.setDatabaseId(databaseID);
+                resultIn.setSessionId(sessionID);
+
+                Result resultOut;
+
+                if (resultIn.getType() == ResultConstants.CONNECT) {
+                    try {
+                        session = DatabaseManager.newSession(
+                            dbType, dbPath, resultIn.getMainString(),
+                            resultIn.getSubString(), new HsqlProperties(),
+                            resultIn.getZoneString(),
+                            resultIn.getUpdateCount());
+
+                        resultIn.readAdditionalResults(null, inStream, rowIn);
+
+                        resultOut = Result.newConnectionAcknowledgeResponse(
+                            session.getDatabase(), session.getId(),
+                            session.getDatabase().getDatabaseID());
+                    } catch (HsqlException e) {
+                        resultOut = Result.newErrorResult(e);
+                    }
+                } else {
+                    int  dbId      = resultIn.getDatabaseId();
+                    long sessionId = resultIn.getSessionId();
+
+                    session = DatabaseManager.getSession(dbId, sessionId);
+
+                    resultIn.readAdditionalResults(session, inStream, rowIn);
+
+                    resultOut = session.execute(resultIn);
+                }
+
+                //
+                response.setContentType("application/octet-stream");
+                response.setContentLength(rowOut.size());
+
+                //
+                dataOut = new DataOutputStream(response.getOutputStream());
+
+                resultOut.write(dataOut, rowOut);
+
+                iQueries++;
+            } catch (HsqlException e) {}
+            finally {
+                if (dataOut != null) {
+                    dataOut.close();
+                }
+
+                if (inStream != null) {
+                    inStream.close();
+                }
+            }
+        }
+
+        // Trace.printSystemOut("Queries processed: "+iQueries+"  \n");
+    }
+}
diff --git a/doc/verbatim/src/org/hsqldb/server/WebServer.java b/doc/verbatim/src/org/hsqldb/server/WebServer.java
new file mode 100644
index 0000000..b3ce0d7
--- /dev/null
+++ b/doc/verbatim/src/org/hsqldb/server/WebServer.java
@@ -0,0 +1,270 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.resources.BundleHandler;
+
+// fredt@users 20020215 - patch 1.7.0 by fredt
+// method rorganised to use new HsqlServerProperties class
+// unsaved@users 20021113 - patch 1.7.2 - SSL support
+// boucherb@users 20030510 - patch 1.7.2 - SSL support moved to factory interface
+// boucherb@users 20030510 - patch 1.7.2 - moved all common code to Server
+// boucherb@users 20030510 - patch 1.7.2 - general lint removal
+
+/**
+ *  The HSQLDB HTTP protocol network database server. <p>
+ *
+ *  WebServer has two distinct functions:<p>
+ *
+ *  The primary function is to allow client/server access to HSQLDB databases
+ *  via the HTTP protocol. This protocol is less efficient than the HSQL
+ *  protocol used by the Server class and should be used only in situations
+ *  where sandboxes or firewalls between the client and the server do not
+ *  allow the use of the HSQL protocol. One example is client/server access by
+ *  an applet running in browsers on remote hosts and accessing the database
+ *  engine on the HTTP server from which the applet originated. From version
+ *  1.7.2, HTTP database connections are persistent and support transactions.
+ *  Similar to HSQL connections, they should be explicitly closed to free the
+ *  server resources. <p>
+ *
+ *  The secondary function of WebServer is to act as a simple general purpose
+ *  HTTP server. It is aimed to support the minimum requirements set out by
+ *  the HTTP/1.0 standard. The HEAD and GET methods can be used to query and
+ *  retreive static files from the HTTP server.<p>
+ *
+ *  Both the database server and HTTP server functions of WebServer can be
+ *  configured with the webserver.properties file. It contains entries for the
+ *  database server similar to those for the HSQL protocol Server class. In
+ *  addition, a list mapping different file endings to their mime types may be
+ *  included in this file. (fredt@users) <p>
+ *
+ * From the command line, the options are as follows: <p>
+ * <pre>
+ * +-----------------+-------------+----------+------------------------------+
+ * |    OPTION       |    TYPE     | DEFAULT  |         DESCRIPTION          |
+ * +-----------------+-------------+----------+------------------------------|
+ * | --help          |             |          | prints this message          |
+ * | --address       | name|number | any      | server inet address          |
+ * | --port          | number      | 80       | port at which server listens |
+ * | --database.i    | [type]spec  | 0=test   | path of database i           |
+ * | --dbname.i      | alias       |          | url alias for database i     |
+ * | --silent        | true|false  | true     | false => display all queries |
+ * | --trace         | true|false  | false    | display JDBC trace messages  |
+ * | --no_system_exit| true|false  | false    | do not issue System.exit()   |
+ * +-----------------+-------------+----------+------------------------------+
+ * </pre>
+ *
+ *  Example of the webserver.properties file:
+ *
+ * <pre>
+ * server.port=80
+ * server.database.0=test
+ * server.dbname.0=...
+ * ...
+ * server.database.n=...
+ * server.dbname.n=...
+ * server.silent=true
+ *
+ * .htm=text/html
+ * .html=text/html
+ * .txt=text/plain
+ * .gif=image/gif
+ * .class=application/octet-stream
+ * .jpg=image/jpeg
+ * .jgep=image/jpeg
+ * .zip=application/x-zip-compressed
+ * </pre>
+ *
+ * <ul>
+ *   <li>For server.root, use '/'  as the separator, even for DOS/Windows.
+ *   <li>File extensions for mime types must be lowercase and start with '.'
+ * </ul>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class WebServer extends Server {
+
+    /**
+     * Handle to resource bundle providing i18n for things like
+     * HTTP error pages.
+     */
+    static int webBundleHandle = BundleHandler.getBundleHandle("webserver",
+        null);
+
+    public WebServer() {
+        super(ServerConstants.SC_PROTOCOL_HTTP);
+    }
+
+    /**
+     *  Starts a new WebServer.
+     *
+     * @param  args the "command line" parameters with which to start
+     *      the WebServer.  "-?" will cause the command line arguments
+     *      help to be printed to the standard output
+     */
+    public static void main(String[] args) {
+
+        String propsPath =
+            FileUtil.getFileUtil().canonicalOrAbsolutePath("webserver");
+        ServerProperties fileProps = ServerConfiguration.getPropertiesFromFile(
+            ServerConstants.SC_PROTOCOL_HTTP, propsPath);
+        ServerProperties props =
+            fileProps == null
+            ? new ServerProperties(ServerConstants.SC_PROTOCOL_HTTP)
+            : fileProps;
+        HsqlProperties stringProps = null;
+
+        stringProps = HsqlProperties.argArrayToProps(args,
+                ServerConstants.SC_KEY_PREFIX);
+
+        if (stringProps.getErrorKeys().length != 0) {
+            printHelp("webserver.help");
+
+            return;
+        }
+
+        props.addProperties(stringProps);
+        ServerConfiguration.translateDefaultDatabaseProperty(props);
+
+        // Standard behaviour when started from the command line
+        // is to halt the VM when the server shuts down.  This may, of
+        // course, be overridden by whatever, if any, security policy
+        // is in place.
+        ServerConfiguration.translateDefaultNoSystemExitProperty(props);
+
+        // finished setting up properties;
+        Server server = new WebServer();
+
+        try {
+            server.setProperties(props);
+            props.validate();
+
+            // This must be called after setProperties, because stringProps
+            // isn't populated until then.
+        } catch (Exception e) {
+            server.printError("Failed to set properties");
+            server.printStackTrace(e);
+
+            return;
+        }
+
+        // now messages go to the channel specified in properties
+        server.print("Startup sequence initiated from main() method");
+
+        if (fileProps != null) {
+            server.print("Loaded properties from [" + propsPath
+                         + ".properties]");
+        } else {
+            server.print("Could not load properties from file");
+            server.print("Using cli/default properties only");
+        }
+
+        server.start();
+    }
+
+    /**
+     * Retrieves the name of the web page served when no page is specified.
+     * This attribute is relevant only when server protocol is HTTP(S).
+     *
+     * @return the name of the web page served when no page is specified
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Used when server protocol is HTTP(S)"
+     */
+    public String getDefaultWebPage() {
+        return serverProperties.getProperty(
+            ServerConstants.SC_KEY_WEB_DEFAULT_PAGE);
+    }
+
+    /**
+     * Retrieves a String object describing the command line and
+     * properties options for this Server.
+     *
+     * @return the command line and properties options help for this Server
+     */
+    public String getHelpString() {
+        return BundleHandler.getString(serverBundleHandle, "webserver.help");
+    }
+
+    /**
+     * Retrieves this server's product name.  <p>
+     *
+     * Typically, this will be something like: "HSQLDB xxx server".
+     *
+     * @return the product name of this server
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Of Server"
+     */
+    public String getProductName() {
+        return "HSQLDB web server";
+    }
+
+    /**
+     * Retrieves a string respresentaion of the network protocol
+     * this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.
+     *
+     * @return string respresentation of this server's protocol
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Used to handle connections"
+     */
+    public String getProtocol() {
+        return isTls() ? "HTTPS"
+                       : "HTTP";
+    }
+
+    /**
+     * Retrieves the root context (directory) from which web content
+     * is served.  This property is relevant only when the server
+     * protocol is HTTP(S).  Although unlikely, it may be that in the future
+     * other contexts, such as jar urls may be supported, so that pages can
+     * be served from the contents of a jar or from the JVM class path.
+     *
+     * @return the root context (directory) from which web content is served
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Context (directory)"
+     */
+    public String getWebRoot() {
+        return serverProperties.getProperty(ServerConstants.SC_KEY_WEB_ROOT);
+    }
+}
diff --git a/doc/verbatim/src/org/hsqldb/test/TestBase.java b/doc/verbatim/src/org/hsqldb/test/TestBase.java
new file mode 100644
index 0000000..1ecb4c9
--- /dev/null
+++ b/doc/verbatim/src/org/hsqldb/test/TestBase.java
@@ -0,0 +1,155 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.lang.reflect.Constructor;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import org.hsqldb.server.Server;
+import org.hsqldb.server.WebServer;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * HSQLDB TestBugBase Junit test case. <p>
+ *
+ * @author  boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public abstract class TestBase extends TestCase {
+
+    //  change the url to reflect your preferred db location and name
+    String  serverProps;
+    String  url;
+    String  user     = "sa";
+    String  password = "";
+    Server  server;
+    boolean isNetwork = true;
+    boolean isHTTP    = false;
+
+    public TestBase(String name) {
+        super(name);
+    }
+
+    public TestBase(String name, String url, boolean isNetwork,
+                    boolean isHTTP) {
+
+        super(name);
+
+        this.isNetwork = isNetwork;
+        this.url       = url;
+        this.isHTTP    = isHTTP;
+    }
+
+    protected void setUp() {
+
+        if (isNetwork) {
+            if (url == null) {
+                url = isHTTP ? "jdbc:hsqldb:http://localhost/test"
+                             : "jdbc:hsqldb:hsql://localhost/test";
+            }
+
+            server = isHTTP ? new WebServer()
+                            : new Server();
+
+            server.setDatabaseName(0, "test");
+            server.setDatabasePath(0, "mem:test;sql.enforce_strict_size=true");
+            server.setLogWriter(null);
+            server.setErrWriter(null);
+            server.start();
+        } else {
+            if (url == null) {
+                url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
+            }
+        }
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println(this + ".setUp() error: " + e.getMessage());
+        }
+    }
+
+    protected void tearDown() {
+
+        if (isNetwork) {
+            server.stop();
+
+            server = null;
+        }
+    }
+
+    Connection newConnection() throws SQLException {
+        return DriverManager.getConnection(url, user, password);
+    }
+
+    public static void runWithResult(Class testCaseClass, String testName) {
+
+        try {
+            Constructor ctor = testCaseClass.getConstructor(new Class[]{
+                String.class });
+            TestBase theTest = (TestBase) ctor.newInstance(new Object[]{
+                testName });
+
+            theTest.runWithResult();
+        } catch (Exception ex) {
+            System.err.println("couldn't execute test:");
+            ex.printStackTrace(System.err);
+        }
+    }
+
+    public void runWithResult() {
+
+        TestResult result   = run();
+        String     testName = this.getClass().getName();
+
+        if (testName.startsWith("org.hsqldb.test.")) {
+            testName = testName.substring(16);
+        }
+
+        testName += "." + getName();
+
+        int failureCount = result.failureCount();
+
+        System.out.println(testName + " failure count: " + failureCount);
+
+        java.util.Enumeration failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.err.println(failures.nextElement());
+        }
+    }
+}
diff --git a/doc/verbatim/testrun/sqltool/sqljrt.sql b/doc/verbatim/testrun/sqltool/sqljrt.sql
new file mode 100644
index 0000000..2068480
--- /dev/null
+++ b/doc/verbatim/testrun/sqltool/sqljrt.sql
@@ -0,0 +1,17 @@
+/*
+ * $Id: sqljrt.sql 3353 2009-12-15 19:52:13Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create function dehex(VARCHAR(80), INTEGER)
+    returns INTEGER
+    no sql
+    language java
+    external name 'CLASSPATH:java.lang.Integer.valueOf'
+.;
+
+CALL dehex('12', 16);
+*if (*? != 18)
+    \q SQL/JRT function failed
+*end if
diff --git a/doc/verbatim/testrun/sqltool/sqlpsm.sql b/doc/verbatim/testrun/sqltool/sqlpsm.sql
new file mode 100644
index 0000000..7462e4d
--- /dev/null
+++ b/doc/verbatim/testrun/sqltool/sqlpsm.sql
@@ -0,0 +1,27 @@
+/*
+ * $Id: sqlpsm.sql 826 2009-01-17 05:04:52Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create table customers(
+    id INTEGER default 0, firstname VARCHAR(50), lastname VARCHAR(50),
+    entrytime TIMESTAMP);
+
+create procedure new_customer(firstname varchar(50), lastname varchar(50))
+    modifies sql data
+    insert into customers values (
+        default, firstname, lastname, current_timestamp)
+.;
+
+SELECT count(*) FROM customers;
+*if (*? != 0)
+    \q SQL/PSM preparation failed
+*end if
+
+CALL new_customer('blaine', 'simpson');
+
+SELECT count(*) FROM customers;
+*if (*? != 1)
+    \q SQL/PSM procedure failed
+*end if
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..df6a11f
--- /dev/null
+++ b/index.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>HSQLDB</title></head>
+<body>
+<img style="width: 223px; height: 47px;" alt="HyperSQL logo" src="doc-src/images/hypersql_logo.png">
+<h3><br>
+</h3>
+<h3>HyperSQL version 2.0.0 Distribution</h3>
+<p>HSQLDB (HyperSQL DataBase) is a relational
+database engine written in Java. Version 2.0 is the result of nearly
+5 years
+development since the last major version. It offers many features and
+adheres
+closely to the latest SQL and JDBC 4 standards.</p>
+<p>This
+is the first GA Release for version 2.0.</p>
+<h4>SUPPORTWARE</h4>
+The development and maintenance of&nbsp; HyperSQL has been possible
+because of financial contributions by business users. We need renewed
+contributions. Please subscribe to SupporWare at&nbsp; <a href="http://hsqldb.org/web/supportware">http://hsqldb.org/web/supportware</a>
+.
+<h4>PACKAGE CONTENTS</h4>
+<p>This download contains the
+following files and directories: </p>
+<p><b>bin</b></p>
+<p>This directory contains some
+Windows utility wrapper scripts, and some HTML pages with HSQLDB
+embedded as an
+applet.</p>
+<h4>build</h4>
+<p>This directory contains the ant
+build.xml script plus MSDOS CMD files for build. See the <a href="doc/guide/building-app.html">Building HyperSQL Jars</a>
+appendix of the
+HyperSQL User Guide for details. </p>
+<h4>classes</h4>
+<p>When the jar is rebuilt, this
+directory contains the *.class files generated by the ANT build tool.
+It does
+not exist in the distribution zip.</p>
+<h4>doc</h4>
+<p>A set of HTML, PDF and text
+documents covering different aspects of HSQLDB and some of its
+utilities.</p>
+<p><a href="doc/guide/index.html">HyperSQL
+User Guide</a> in HTML format. <br>
+<a href="doc/guide/guide.pdf">HyperSQL User Guide</a>
+in PDF format. </p>
+<p><a href="doc/util-guide/index.html">HyperSQL
+Utilities Guide</a> in HTML format.<br>
+<a href="doc/util-guide/util-guide.html">HyperSQL
+Utilities Guide</a> in PDF
+format. </p>
+<p>The <a href="doc/apidocs/index.html">JavaDoc</a>
+for public classes, including the JDBC documentation. </p>
+<p>(in future) Chronological list of
+minor changes and bug fixes since the release of version 2.0.0 <a href="doc/changelist_2_0_0.txt">changelist_2_0_0.txt</a>
+</p>
+<p>The license texts for the source and binaries, based on the
+BSD license. <a href="doc/hsqldb_lic.txt">hsqldb_lic.txt</a>
+is for sources developed entirely by the HSQL Development Group. <a href="doc/hypersonic_lic.txt">hypersonic_lic.txt</a>
+is for sources that contain code from the closed HypersonicSQL project.</p>
+<h4>lib</h4>
+<p>The jar needed for running HyperSQL
+and its GUI utilities (hsqldb.jar) has been pre-built in this
+directory. The jar is
+compatible with Java version 1.6. The jar for SqlTool (sqltool.jar) is
+also in this directory. The extra zip file in the directory is needed
+only for
+recompiling hsqldb and is not required for deployment. </p>
+<h4>src</h4>
+<p>All source code is in this
+directory. </p>
+<h4>testrun</h4>
+<p>Contains test scripts for the
+database engine and SqlTool. These scripts are run by separate test
+utilities
+for the engine and SqlTool</p>
+<h4>CHANGES</h4>
+<ul>
+<li>There are very many new features in the new version. Most
+of these do not affect existing features in version 1.8.x.</li>
+<li>For use with existing applications, the main differences
+are as follows:</li>
+<li>Transaction isolation is always enforced - READ COMMITTED
+and SERIALIZABLE modes are supported.</li>
+<li>GENERATE BY DEFAULT AS IDENTITY does not create a primary
+key. A primary key must be declared explicitly.</li>
+<li>Column sizes are enforced, although you can change this and
+other properties to some extent.</li>
+</ul>
+<h4>UPDATES</h4>
+We constantly fix reported issues. Please check the web site regularly
+for&nbsp;latest updated version and latest information.
+<h4>SUPPORT</h4>
+<p>Support for HyperSQL is available
+from <a href="http://hsqldb.org/support">http://hsqldb.org/support</a>
+in
+various forms, including a mailing list and user forums. The web site
+features
+the latest bugfix versions of the software, FAQ and other useful
+resources.</p>
+<p>Fred Toussi (fredt (at)
+users.sourceforge.net)<br>
+Blaine Simpson (blaine dot simpson (at) admc dot com)</p>
+<p><a href="http://hsqldb.org">http://hsqldb.org</a>&nbsp;</p>
+</body></html>
diff --git a/lib/hsqldb.jar b/lib/hsqldb.jar
new file mode 100644
index 0000000..2da29ed
--- /dev/null
+++ b/lib/hsqldb.jar
Binary files differ
diff --git a/lib/servlet-2_3-fcs-classfiles.zip b/lib/servlet-2_3-fcs-classfiles.zip
new file mode 100644
index 0000000..c450772
--- /dev/null
+++ b/lib/servlet-2_3-fcs-classfiles.zip
Binary files differ
diff --git a/lib/sqltool.jar b/lib/sqltool.jar
new file mode 100644
index 0000000..23c2e81
--- /dev/null
+++ b/lib/sqltool.jar
Binary files differ
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..3849661
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,9 @@
+Readme File

+$Date: 2010-06-06 20:59:13 -0400 (Sun, 06 Jun 2010) $

+This package contains HyperSQL v. 2.0.0

+

+HyperSQL is a relational database engine and a set of tools written in Java.

+HyperSQL is also known as HSQLDB.

+

+The file "index.html" explains the contents of this distribution and has

+links to documentation and support resources.

diff --git a/sample/StartupParameters.plist b/sample/StartupParameters.plist
new file mode 100644
index 0000000..c82bb64
--- /dev/null
+++ b/sample/StartupParameters.plist
@@ -0,0 +1,21 @@
+/*
+     $Id: StartupParameters.plist 59 2007-04-17 01:08:09Z unsaved $
+     Startup Item parameter file that works on at least one Mac OS X system.
+
+     I don't know which of the "Uses" services are available on all Mac's.
+     I just know that my system has them, and this list causes HSQLDB
+     to start late enough without resorting to "Latest" (which could cause
+     problems for people who also start up apps that use HSQLDB).
+*/
+{
+  Description   = "HSQLDB Database Server";
+  Provides      = ("Hsqldb");
+  Requires      = ("Resolver");
+  Uses          = ("Disks", "Network", "Core Services", "TIM", "NetInfo", "Resolver");
+  Messages =
+  {
+    start = "Starting Hsqldb";
+    stop  = "Stopping Hsqldb";
+    restart  = "Restarting Hsqldb";
+  };
+}
diff --git a/sample/acl.txt b/sample/acl.txt
new file mode 100644
index 0000000..9bfc706
--- /dev/null
+++ b/sample/acl.txt
@@ -0,0 +1,31 @@
+# $Id: acl.txt 536 2008-12-05 14:55:10Z unsaved $

+

+# Sample HyperSQL Network Listener ACL file.

+# Specify "allow" and "deny" rules

+# For address specifications, individual addresses, host names, and

+# network addresses with /bit suffix are allowed, but read the caveat about

+# host names below, under the sample "localhost" rule.

+

+# Blank lines ignored.

+   # Lines with # as the first non-whitespace character are ignored.

+

+

+allow 2001:db8::/32

+# Allow this 32-bit ipv4 subnet

+

+allow localhost

+# You should use numerical addresses in ACL files, unless you are certain that

+# the name will always be known to your network address resolution system

+# (assume that you will lose Internet connectivity at some time).

+# With a default name resolution setup on UNIX, you are safe to use names

+# defined in your /etc/hosts file.

+

+deny 192.168.101.253

+# Deny a single IP address.

+# In our example, 192.168.101.0/24 is our local, organizational network.

+# 192.168.101.253 is the IP address of our Intern's PC.

+# The Intern does not have permission to access our databases directly.

+

+allow 192.168.101.0/24

+

+# Any ipv4 or ipv6 candidate address not matched above will be denied

diff --git a/sample/dsv-sample.sql b/sample/dsv-sample.sql
new file mode 100644
index 0000000..f9d188e
--- /dev/null
+++ b/sample/dsv-sample.sql
@@ -0,0 +1,37 @@
+/*
+ * $Id: dsv-sample.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Imports delimiter-separated-values, and generates an output 
+ * reject .dsv file, and a reject report.
+ *
+ * To execute, set up a SqlTool database urlid (see User Guide if you don't
+ * know how to do that); then (from this directory) execute this script like
+ *
+ *    java ../lib/hsqldb.jar mem dsv-sample.sql
+ *
+ * (replace "mem" with your urlid).
+ */
+
+CREATE TABLE sampletable(i INT, d DATE NOT NULL, b BOOLEAN);
+
+/* If you dont' set *DSV_TARGET_TABLE, it defaults to the base name of the
+   .dsv file. */
+* *DSV_TARGET_TABLE = sampletable
+
+\p WARNING:  Some records will be skipped, and some others will be rejected.
+\p This is on purpose, so you can work with a reject report.
+\p
+
+/* By default, no reject files are written, and the import will abort upon
+ * the first error encountered.  If you set either of these settings, the
+ * import will continue to completion if at all possible. */
+* *DSV_REJECT_FILE = ${java.io.tmpdir}/sample-reject.dsv
+* *DSV_REJECT_REPORT = ${java.io.tmpdir}/sample-reject.html
+\m sample.dsv
+
+/* Enable this line if you want to display all successfully imported data:
+SELECT * FROM sampletable;
+*/
+
+\p
+\p See import reject report at '*{*DSV_REJECT_REPORT}'.
diff --git a/sample/hsqldb.cfg b/sample/hsqldb.cfg
new file mode 100644
index 0000000..37889e8
--- /dev/null
+++ b/sample/hsqldb.cfg
@@ -0,0 +1,173 @@
+# $Id: hsqldb.cfg 3583 2010-05-16 01:49:52Z unsaved $
+
+# Sample configuration file for HyperSQL Server Listener.
+# See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide.
+
+# N.b.!!!!  You must place this in the right location for your type of UNIX.
+# See the init script "hsqldb" to see where this must be placed and
+# what it should be renamed to.
+
+# This file is "sourced" by a Bourne shell, so use Bourne shell syntax.
+
+# This file WILL NOT WORK until you set (at least) the non-commented
+# variables to the appropriate values for your system.
+# Life will be easier if you avoid all filepaths with spaces or any other
+# funny characters.  Don't ask for support if you ignore this advice.
+
+# The URLIDS setting below is new and REQUIRED.  This setting replaces the
+# server.urlid.X settings which used to be needed in your Server's
+# properties file.
+
+# -- Blaine (blaine dot simpson at admc dot com)
+
+JAVA_EXECUTABLE=/usr/bin/java
+
+# Unless you copied the jar files from another system, this typically
+# resides at $HSQLDB_HOME/lib/sqltool.jar, where $HSQLDB_HOME is your HSQLDB
+# software base directory.
+# The file name may actually have a version label in it, like
+# sqltool-1.2.3.jar (in which case, you must specify the full name here).
+# A 'hsqldb.jar' file (with or without version label) must reside in the same
+# directory as the specified sqltool.jar file.
+SQLTOOL_JAR_PATH=/opt/hsqldb-2.0.0/hsqldb/lib/sqltool.jar
+# For the sample value above, there must also exist a file
+# /opt/hsqldb-2.0.0/hsqldb/lib/hsqldb*.jar.
+
+# Where the file "server.properties" or "webserver.properties" resides.
+SERVER_HOME=/opt/hsqldb-2.0.0/hsqldb/data
+
+# What UNIX user the server will run as.
+# (The shutdown client is always run as root or the invoker of the init script).
+# Runs as root by default, but you should take the time to set database file
+# ownerships to another user and set that user name here.
+HSQLDB_OWNER=hsqldb
+
+# The HSQLDB jar file specified in HSQLDB_JAR_PATH above will automatically
+# be in the class path.  This arg specifies additional classpath elements.
+# To embed your own application, add your jar file(s) or class base
+# directories here, and add your main class to the INVOC_ADDL_ARGS setting
+# below.  Another common use-case for adding to your class path is to make
+# classes available to the DB engines for SQL/JRT functions and procedures.
+#SERVER_ADDL_CLASSPATH=/usr/local/dist/currencybank.jar
+
+# For startup or shutdown failures, you can save a lot of debugging time by
+# temporarily adjusting down MAX_START_SECS and MAX_TERMINATE_SECS to a
+# little over what it should take for successful startup and shutdown on
+# your system.
+
+# We require all Server/WebServer instances to be accessible within 
+# $MAX_START_SECS from when the Server/WebServer is started.
+# Defaults to 60.
+# Raise this is you are running lots of DB instances or have a slow server.
+#MAX_START_SECS=200
+
+# Max time to allow for JVM to die after all HSQLDB instances stopped.
+# Defaults to 60.  Set high because the script will always continue as soon as
+# the process has stopped.  The importance of this setting is, how long until
+# a non-stopping-JVM-problem will be detected.
+#MAX_TERMINATE_SECS=0
+
+# NEW AND IMPORTANT!!!
+# As noted at the top of this file, this setting replaces the old property
+# settings server.urlid.X.
+# Simply list the URLIDs for all DB instances which your *Server starts.
+# Usually, these will exactly mirror the server.database.X settings in your
+# server.properties or webserver.properties file.
+# Each urlid listed here must be defined to a NETWORK url with Admin privileges
+# in the AUTH_FILE specified below.  (Network type because we use this for
+# inter-process communication)
+# Separate multiple values with white space.  NO OTHER SPECIAL CHARACTERS!
+# Make sure to quote the entire value if it contains white space separator(s).
+URLIDS='localhostdb1'
+
+# These are urlids # ** IN ADDITION TO URLIDS **, for instances which the init
+# script should stop but not start.
+# Most users will not need this setting.  If you need it, you'll know it.
+# Defaults to none (i.e., only URLIDS will be stopped).
+#SHUTDOWN_URLIDS='ondemand'
+
+# SqlTool authentication file used only for shutdown.
+# The default value will be sqltool.rc in root's home directory, since it is 
+# root who runs the init script.
+# (See the SqlTool chapter of the HyperSQL Utilities Guide if you don't
+# understand this).
+#AUTH_FILE=/home/blaine/sqltool.rc
+
+# Typical users will leave this unset and it will default to
+# org.hsqldb.server.Server.  If you need to run the HSQLDB WebServer class
+# instead, due to a firewall or routing impediment, set this to
+# org.hsqldb.server.WebServer, see the docs about running WebServr, and
+# set up a "webserver.properties" file instead of a "server.properties".
+# The JVM that is started can invoke many classes (see the following item
+# about that), but this is the server that is used (1) to check status,
+# (2) to shut down the JVM.
+#TARGET_CLASS=org.hsqldb.server.WebServer
+
+# This is where you may specify both command-line parameters to TARGET_CLASS,
+# plus any number of additional progams to run (along with their command-line
+# parameters).  The MainInvoker program is used to embed these multiple
+# static main invocations into a single JVM, so see the API spec for
+# org.hsqldb.util.MainInvoker if you want to learn more.
+# N.b. You should only use this setting to set HSQLDB Server or WebServer
+# parameters if you run multiple instances of this class, since you can use the
+# server/webserver.properties file for a single instance.
+# Every additional class (in addition to the TARGET_CLASS)
+# must be preceded with an empty string, so that MainInvoker will know
+# you are giving a class name.  MainInvoker will invoke the normal 
+# static main(String[]) method of each such class.  
+# By default, MainInvoker will just run TARGET_CLASS with no args.
+# Example that runs just the TARGET_CLASS with the specified arguments:
+#INVOC_ADDL_ARGS='-silent false'   #but use server.properties property instead!
+# Example that runs the TARGET_CLASS plus a WebServer:
+#INVOC_ADDL_ARGS='"" org.hsqldb.server.WebServer'
+# Note the empty string preceding the class name.
+# Example that starts TARGET_CLASS with an argument + a WebServer +
+# your own application with its args (i.e., the HSQLDB Servers are
+# "embedded" in your application).  (Set SERVER_ADDL_CLASSPATH too).:
+#INVOC_ADDL_ARGS='-silent false "" org.hsqldb.server.WebServer "" com.acme.Stone --env prod localhost'
+#   but use server.properties for -silent option instead!
+# Example to run a non-TLS server in same JVM with a TLS server.  In this
+# case, TARGET_CLASS is Server which will run both in TLS mode by virtue of 
+# setting the tls, keyStore, and keyStorePassword settings in
+# server*.properties, as described below; plus an "additional" Server with
+# overridden 'tls' and 'port' settings:
+#INVOC_ADDL_ARGS="'' org.hsqldb.server.Server --port 9002 --tls false"
+# This is an important use case.  If you run more than one Server instance,
+# you can specify different parameters for each here, even though only one
+# server.properties file is supported.
+# Note that you use nested quotes to group arguments and to specify the
+# empty-string delimiter.
+
+# The TLS_* settings have been obsoleted.
+# To get your server running with TLS, set
+# system.javax.net.ssl.keyStore=/path/to/your/private.keystore
+# system.javax.net.ssl.keyStorePassword=secretPassword
+# server.ssl=true
+# IN server.properties or webserver.properties, and
+# MAKE THE FILE OWNER-READ-ONLY!
+# See the TLS Encryption section of the HyperSQL User Guide, paying attention
+# to the security warning(s).
+# If you are running with a private server cert, then you will also need to 
+# set "truststore" in the your SqlTool config file (location is set by the
+# AUTH_FILE variable in this file, or it must be at the default location for 
+# HSQLDB_OWNER).
+
+# Any JVM args for the invocation of the JDBC client used to verify DB
+# instances and to shut them down (SqlToolSprayer).
+# Server-side System Properties should normally be set with system.*
+# settings in the server/webserver.properties file.
+# This example specifies the location of a private trust store for TLS 
+# encryption.
+# For multiple args, put quotes around entire value.
+# If you are starting just a TLS_encrypted Listener, you need to uncomment
+# this so the init scripts uses TLS to connect.
+# If using a private keystore, you also need to set "truststore" settings in
+# the sqltool.rc file.
+#CLIENT_JVMARGS=-Djavax.net.debug=ssl
+# This sample value displays useful debugging information about TLS/SSL.
+
+# Any JVM args for the server.
+# For multiple args, put quotes around entire value.
+#SERVER_JVMARGS=-Xmx512m
+# You can set the "javax.net.debug" property on the server side here, in the
+# same exact way as shown for the client side above.
diff --git a/sample/hsqldb.init b/sample/hsqldb.init
new file mode 100755
index 0000000..4b498e6
--- /dev/null
+++ b/sample/hsqldb.init
@@ -0,0 +1,498 @@
+#!/bin/sh
+# For boot-up and system shutdown, most UNIXes explicitly run a shell
+# interpreter.  In that case, the interpreter line above is ignored.
+# There are a few UNIXes (notably Darwin) that require the interpreter line.
+
+# Copyright (c) 2001-2008, The HSQL Development Group
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of the HSQL Development Group nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 
+# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+# $Id: hsqldb.init 3396 2009-12-23 16:12:18Z unsaved $
+
+# UNIX init script for HSQLDB.
+
+# IMPORTANT!  Users running multiple HSQLDB ***Server processes*** must use a 
+# unique "SERVICE" name for each Server process.  Most users will run just one 
+# server instance, possibly serving lots of database instances.  Multi-server
+# runners must change the value on the following line, and, if your system 
+# uses chkconfig or insserv, you must change the value of "hsqldb" to the 
+# same thing (as SERVICE) in the chkconfig and/or insserv blocks a few
+# lines down from here (incl. in the pidfile and config file paths).  (Sorry 
+# to say, but you need to repeat this procedure after every HSQLDB upgrade).
+SERVICE=hsqldb
+# This is the one setting which users will commonly change in this file.
+# It's impossible to determine this script name (in a portable way) at boot-up 
+# time, since ${0} is entirely different for init scripts, depending on UNIX 
+# version.
+
+# See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide for how to
+# use this file.
+# This block only used by chkconfig systems (incl. SuSE Linux).
+# chkconfig: 345 87 13
+# description: HyperSQL Database, A High Performance Java Database Server
+# pidfile: /var/run/hsqldb.pid
+# config: /etc/sysconfig/hsqldb
+
+# This block only used by insserv systems (incl. SuSE Linux).
+### BEGIN INIT INFO
+# Provides:          hsqldb
+# Required-Start:    $syslog $remote_fs $network $named
+# Required-Stop:
+# Default-Start:     3 5
+# Default-Stop:      0 1 2 6
+# Short-Description: HyperSQL Database Server
+# Description:       HyperSQL Database, A High Performance Java Database Server
+### END INIT INFO
+
+# UNIX System-V and Linux users should copy this script to the common
+# init script directory (/etc/init.d/ on most systems) with name "hsqldb",
+# or whatever you have SERVICE set to (no ".init" suffix!).
+
+# N.b.  Being a system script, this script does not use inherited variables.
+# If you want to adjust a setting, edit the config file.
+
+# Strategy of this init script is to avoid shell-specific functionality,
+# and use only lowest-common-denominator Bourne capabilities.
+# We don't include OS-specific functions, and we don't use shell-
+# implementation-specific functionality like "echo ...\c" or "echo -n...".
+# Since some Bourne shells don't support shell functions at all, we don't
+# even define any local functions.
+
+# This script has been generalized to the point that it can now "start"
+# any combination of classes with the normal static main methods.
+# You can supply invocation arguments to the
+# TARGET_CLASS invocation, and can start as many other classes as you
+# wish by using the INVOC_ADDL_ARGS setting (this includes running
+# multiple HSQLDB Servers of various types).
+
+# Template config file can be obtained from the HyperSQL distribution.
+# On the day I write this, I have it located at "sample/hsqldb.cfg" in the
+# distro, but that could change.  You need to copy then edit it before it
+# will work.
+# Recommended locations for runtime configuration file:
+#   Darwin, SunOS, Solaris:  /etc/hsqldb.conf
+#              (However, Sunfreeware.com builds use /usr/local/etc).
+#   Linux:  /etc/sysconfig
+#   FreeBSD:  /usr/local/etc/hsqldb.cfg
+# (Replace the base name "hsqldb" with whatever you have SERVICE set to at
+# the top of this file).
+# You can put it at any of these locations and it will be used.  For
+# your sanity, only put a file at one of these locations.
+
+#  -- blaine.simpson@admc.com
+
+set +u
+
+# Following function is Copyright Apache 2.0 by Axis Data Management Corp.
+# and code is copied verbatim from
+# http://pub.admc.com/scripts/bin/minsleep-nov.fnc
+# Sleeps until process dies or file appears.
+# 2nd parameter is assumed to be a PID if it is an integer.
+minsleep() {
+    [ $# -eq 2 ] || {
+        echo 'SYNTAX:  minsleep MAXSECS PID|PATH   (for integers MAXSECS and PID)' 1>&2
+        return 2
+    }
+    TARGET_PID= TARGET_PATH=
+    MAXSECS=$1; shift
+    case "$1" in *[^0-9]*) TARGET_PATH="$1";; *) TARGET_PID="$1";; esac; shift
+    _secs=0
+    while [ $_secs -lt $MAXSECS ]; do
+        _secs=`expr $_secs + 1`
+        if [ -n "$TARGET_PID" ]; then
+            kill -0 $TARGET_PID > /dev/null 2>&1 || return 0  # Target proc died
+        elif [ -s "$TARGET_PATH" ]; then
+            return 0  # Target process died
+        fi
+        sleep 1
+    done
+    return 1  # Timed out
+}
+
+# This is only used for recursive invocations.
+# Will not necessarily be set correctly at system bootup invocations
+# (where it is sometimes invoked like "sh... /path/to/hsqldb start"),
+# but, in those cases there will be no recursion.
+INVOC_PATH=`dirname "$0"` || {
+    echo "'dirname' failed" 1>&2
+    exit 2
+}
+[ -n "$INVOC_PATH" ] && INVOC_PATH="${INVOC_PATH}/"
+
+SYNTAX_MSG="SYNTAX:  ${INVOC_PATH}${SERVICE} start|stop|stopcompact|restart|restartcmpacted|status"
+
+# You can override any of these default values in your config file:
+
+# Max time for background su command to start up and echo pid.
+# (0 works for moderately fast servers).
+SU_ECHO_SECS=30
+# File used as semaphore.  If file is removed, a running pid checker
+# process will exit.
+PIDCHECKER_FLAGFILE=/tmp/pidchecker.run
+# The following settings get overridden by optional setting in the config file.
+# Max time for JVM to die after all HSQLDB instances stopped.
+MAX_TERMINATE_SECS=60
+# We require all Server/WebServer instances to be accessible within 
+# $MAX_START_SECS from when the Server/WebServer is started.
+MAX_START_SECS=60
+# Class to start
+TARGET_CLASS=org.hsqldb.server.Server
+
+CLIENT_JVMARGS=
+SERVER_JVMARGS=
+CFGFILE=
+LOGFILE=
+PIDFILE=
+BASEDIR=
+AUTH_FILE=
+SHUTDOWN_OPTION=
+SERVER_ADDL_CLASSPATH=
+INVOC_ADDL_ARGS=
+case "`uname`" in
+    Darwin)     # I.e. Mac OS X.  I don't know about older Mac OSes.
+        LOGFILE=/var/log/${SERVICE}.log
+        PIDFILE=/var/run/${SERVICE}.pid
+    ;;
+    Linux)
+        LOGFILE=/var/log/${SERVICE}.log
+        PIDFILE=/var/run/${SERVICE}.pid
+    ;;
+    FreeBSD)
+        LOGFILE=/var/log/${SERVICE}.log
+        PIDFILE=/var/run/${SERVICE}.pid
+    ;;
+    SunOS)
+        LOGFILE=/var/log/${SERVICE}.log
+        PIDFILE=/etc/${SERVICE}.pid
+    ;;
+    *)
+        LOGFILE=/var/log/${SERVICE}.log
+        PIDFILE=/etc/${SERVICE}.pid
+    ;;
+esac
+
+for candidate in /etc/sysconfig/${SERVICE} /etc/${SERVICE}.conf /etc/${SERVICE}.cfg  \
+    /usr/local/etc/${SERVICE}.cfg; do
+    [ -f $candidate ] && {
+        CFGFILE=$candidate
+        break
+    }
+done
+[ -n "$CFGFILE" ] || {
+    echo "No global config file found in any of allowed locations" 1>&2
+    exit 11
+}
+
+# Sanity check
+[ -n "$LOGFILE" ] && [ -n "$PIDFILE" ] || {
+    echo "Internal problem in init script" 1>&2
+    exit 11
+}
+
+[ $# -eq 1 ] || {
+    echo "$SYNTAX_MSG" 1>&2
+    exit 4
+}
+
+# It would be nice to permit some uses, like "status" by non-root users,
+# but for now our goal is a superuser init script.
+[ -w / ] || {   # Very portable, but perhaps not perfect, test for superuser.
+    echo "Only 'root' may use this init script" 1>&2
+    exit 4
+}
+
+# Use bsd-style enable/disable if it's in place.
+BSDCFG=
+[ -r /etc/rc.conf ] && [ -f /etc/rc.conf ] && {
+    . /etc/rc.conf
+    BSDCFG=1
+}
+[ -r /etc/rc.conf.local ] && [ -f /etc/rc.conf.local ] && {
+    . /etc/rc.conf.local
+    BSDCFG=1
+}
+[ -n "$BSDCFG" ] && {
+    case "$hsqldb_enable" in [Yy][Ee][Ss]);; [Oo][Nn]);; [Tt][Rr][Uu][Ee]);;
+        *) exit 0;;  # Don't run if not enabled for BSD startup
+    esac
+}
+
+COMMAND="$1"; shift
+
+[ -r "$CFGFILE" ] || {
+    echo "Unable to read config file '$CFGFILE'" 1>&2
+    exit 2
+}
+[ -f "$CFGFILE" ] || {
+    echo "'$CFGFILE' is not a regular file" 1>&2
+    exit 2
+}
+HSQLDB_OWNER=
+JAVA_EXECUTABLE=
+SQLTOOL_JAR_PATH=
+SERVER_HOME=
+SHUTDOWN_URLIDS=
+URLIDS=
+. "$CFGFILE"
+# Suffix delimiter to $SERVER_ADDL_CLASSPATH, if it is set.
+[ -n "$SERVER_ADDL_CLASSPATH" ] &&
+SERVER_ADDL_CLASSPATH="${SERVER_ADDL_CLASSPATH}:"
+# Validate that config file sets all required variables.
+[ -n "$JAVA_EXECUTABLE" ] && [ -n "$SQLTOOL_JAR_PATH" ] &&
+[ -n "$SERVER_HOME" ] && [ -n "$URLIDS" ] || {
+    echo "Config file '$CFGFILE' does not set one or more of following variables
+    JAVA_EXECUTABLE, SQLTOOL_JAR_PATH, SERVER_HOME, URLIDS" 1>&2
+    exit 2
+}
+[ -d "$SERVER_HOME" ] || {
+    echo "SERVER_HOME variable in '$CFGFILE' is set to a non-directory." 1>&2
+    exit 2
+}
+[ -f "$JAVA_EXECUTABLE" ] && [ -f "$SQLTOOL_JAR_PATH" ] || {
+    echo "JAVA_EXECUTABLE or SQLTOOL_JAR_PATH in '$CFGFILE' is set to a non-file." 1>&2
+    exit 2
+}
+
+[ -r "$SQLTOOL_JAR_PATH" ] || {
+    echo "'$SQLTOOL_JAR_PATH' isn't readable" 1>&2
+    exit 2
+}
+[ -x "$JAVA_EXECUTABLE" ] || {
+    echo "No Java executable found at '$JAVA_EXECUTABLE'" 1>&2
+    exit 2
+}
+
+# "chown" lives here on some UNIXes.
+PATH="$PATH:/usr/sbin"
+
+# Make a good effort (but not bullet-proof) check on permissions of the
+# auth file.  Unfortunately, if auth-file is not specified, this depends
+# upon both (a) $HOME being set; and (b) SqlToolSprayer and SqlTool defaults.
+# On the other hand, it works great if AUTH_FILE is set explicitly by user.
+if [ -z "$AUTH_FILE" ] && [ -z "$HOME" ]; then
+    : # Lousy init environment didn't set $HOME, so can't find dflt cfg file.
+else
+    _AUTH_TEST_PATH="$AUTH_FILE"
+    [ -n "${_AUTH_TEST_PATH}" ] || _AUTH_TEST_PATH="$HOME/sqltool.rc"
+    [ -f "$_AUTH_TEST_PATH" ] || {
+        echo "No auth file found at '$_AUTH_TEST_PATH'" 1>&2
+        exit 2
+    }
+    [ -r "$_AUTH_TEST_PATH" ] || {
+        echo "Auth file '$_AUTH_TEST_PATH' not readable" 1>&2
+        exit 2
+    }
+    ls -ld "$_AUTH_TEST_PATH" | grep '^-..------' > /dev/null 2>&1 || {
+        echo "Fix permissions on '$_AUTH_TEST_PATH' like 'chmod 600 $_AUTH_TEST_PATH'" 1>&2
+        exit 2
+    }
+fi
+
+# Set HSQLDB_PID according to pid file.
+HSQLDB_PID=
+[ -r "$PIDFILE" ]  && {
+    [ -f "$PIDFILE" ] || {
+        echo "'$PIDFILE' is not a regular file" 1>&2
+        exit 6
+    }
+    [ -w "$PIDFILE" ] || {
+        echo "'$PIDFILE' is not writable" 1>&2
+        exit 6
+    }
+    HSQLDB_PID="`cat $PIDFILE`" || {
+        echo "Failed to read pid file '$PIDFILE'" 1>&2
+        exit 6
+    }
+    case "$HSQLDB_PID" in
+        *[a-zA-Z/!@#$%*+=_~]*) HSQLDB_PID=;;
+        *'^'*) HSQLDB_PID=;;
+    esac
+    [ -n "$HSQLDB_PID" ] || {
+        echo "Pid file '$PIDFILE' does not contain a valid process identifier" 1>&2
+        exit 6
+    }
+    kill -0 "$HSQLDB_PID" > /dev/null 2>&1 || {
+        echo 'Removing stale pid file'
+        rm -f "$PIDFILE" || {
+            echo "Failed to remove pid file '$PIDFILE'" 1>&2
+            exit 6
+        }
+        HSQLDB_PID=
+    }
+    #echo "PID is ($HSQLDB_PID)"
+}
+
+case "$COMMAND" in
+    status)
+        [ -n "$HSQLDB_PID" ] || {
+            echo "I don't know of any running ${SERVICE} server."
+            exit 0
+        }
+        echo "There is an ${SERVICE} server loaded from $SQLTOOL_JAR_PATH
+running with pid $HSQLDB_PID."
+        # I would give a nice ps command here, were ps not so damned 
+        # OS-specific.
+        AUTH_FILE_SWITCH=
+        # N.b., there will be a problem if there are special characters or
+        # spaces inside of $AUTH_FILE.
+        [ -n "$AUTH_FILE" ] &&
+        AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE"
+        # Might as well set CLASSPATH for a cleaner command.
+        CLASSPATH="$SQLTOOL_JAR_PATH"
+        export CLASSPATH
+        export PATH   # Required only for some funny init environments.
+        exec "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \
+            "-Dsqltoolsprayer.monfile=$PIDFILE" \
+            org.hsqldb.cmdline.SqlToolSprayer 'CALL true;' $URLIDS > /dev/null
+    ;;
+    start)
+        [ -n "$TLS_KEYSTORE" ] || [ -n "$TLS_PASSWORD" ] &&
+            echo "WARNING:  The TLS_* settings have been obsoleted.
+See the comments in the new sample 'hsqldb.cfg' file." 1>&2
+        [ -n "$HSQLDB_PID" ] && {
+        echo "There is already a ${SERVICE} server running with pid $HSQLDB_PID." 1>&2
+            exit 1
+        }
+        if [ -n "$HSQLDB_OWNER" ]; then
+            touch "$PIDFILE" || {
+                echo "Failed to create pid file" 1>&2
+                exit 1
+            }
+            chown "$HSQLDB_OWNER" "$PIDFILE" || {
+                echo "Failed to chown pid file to '$HSQLDB_OWNER'" 1>&2
+                exit 1
+            }
+            # Some OSes choke if there are newlines in this string.
+            # N.b.!!!  The shell of the -c command is the target user's default
+            # login shell, so keep this command shell-independent!
+            nohup su "$HSQLDB_OWNER" -c "cd '$SERVER_HOME' && echo "'$$'" > '$PIDFILE' && exec '$JAVA_EXECUTABLE' $SERVER_JVMARGS -classpath '${SERVER_ADDL_CLASSPATH}${SQLTOOL_JAR_PATH}' org.hsqldb.util.MainInvoker $TARGET_CLASS $INVOC_ADDL_ARGS" >> "$LOGFILE" 2>&1 &
+        else
+            cd "$SERVER_HOME" || {
+                echo "Failed to cd to '$SERVER_HOME'" 1>&2
+                exit 1
+            }
+            export JAVA_EXECUTABLE
+            export SQLTOOL_JAR_PATH
+            export PIDFILE
+            export SERVER_JVMARGS
+            export TARGET_CLASS
+            export INVOC_ADDL_ARGS
+            nohup sh -c '
+                echo $$ > "$PIDFILE" || {
+                    echo "Failed to write pid to pid file" 1>&2
+                    exit 1
+                }
+                eval exec "$JAVA_EXECUTABLE" $SERVER_JVMARGS -classpath "${SERVER_ADDL_CLASSPATH}${SQLTOOL_JAR_PATH}"  org.hsqldb.util.MainInvoker $TARGET_CLASS $INVOC_ADDL_ARGS
+            ' >> "$LOGFILE" 2>&1 &
+        fi
+        minsleep $SU_ECHO_SECS "$PIDFILE"
+        # Make sure bg commands have time to echo pid.
+        AUTH_FILE_SWITCH=
+        # N.b., there will be a problem if there are special characters or
+        # spaces inside of $AUTH_FILE.
+        [ -n "$AUTH_FILE" ] &&
+        AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE"
+        # Might as well set CLASSPATH for a cleaner command.
+        CLASSPATH="$SQLTOOL_JAR_PATH"
+        export CLASSPATH
+        export PATH   # Required only for some funny init environments.
+        # There are many reasons why we could fail to read the pid file,
+        # but regardless of why, the pid file does not contain a valid pid.
+        touch "$PIDCHECKER_FLAGFILE" || {
+            echo "Failed to touch file '$PIDCHECKER_FLAGFILE'" 1>&2
+            exit 1
+        }
+        export PIDCHECKER_FLAGFILE
+        export PIDFILE
+        (
+            while true; do
+                # Could possibly use minsleep to simplify this, but I don't
+                # want to take the time to test the function export behavior.
+                # -a and -e tests are not portable.
+                [ -f "$PIDCHECKER_FLAGFILE" ] || exit 0
+                kill -0 "`cat $PIDFILE`" > /dev/null 2>&1 || {
+                    rm -f "$PIDFILE" "$PIDCHECKER_FLAGFILE"
+                    exit 1
+                }
+                sleep 1
+            done
+        ) &
+        "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \
+            "-Dsqltoolsprayer.monfile=$PIDFILE" \
+            "-Dsqltoolsprayer.maxtime=${MAX_START_SECS}000" \
+            org.hsqldb.cmdline.SqlToolSprayer 'CALL true;' $URLIDS > /dev/null && {
+            rm -f "$PIDCHECKER_FLAGFILE"
+            echo "$TARGET_CLASS started with pid `cat $PIDFILE`"
+            exit 0
+        }
+        rm -f "$PIDCHECKER_FLAGFILE"
+        echo "Failed to start $TARGET_CLASS.
+See log file '$LOGFILE'." 1>&2
+        exit 1
+    ;;
+    stop|stopcompact)
+        [ "$COMMAND" = stopcompact ] && SHUTDOWN_OPTION='compact'
+        [ -n "$HSQLDB_PID" ] || {
+            echo "I don't know of any running ${SERVICE} server." 1>&2
+            exit 1
+        }
+        AUTH_FILE_SWITCH=
+        # N.b., there will be a problem if there are special characters or
+        # spaces inside of $AUTH_FILE.
+        [ -n "$AUTH_FILE" ] &&
+        AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE"
+        # Might as well set CLASSPATH for a cleaner command.
+        CLASSPATH="$SQLTOOL_JAR_PATH"
+        export CLASSPATH
+        export PATH   # Required only for some funny init environments.
+        "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \
+            org.hsqldb.cmdline.SqlToolSprayer "shutdown ${SHUTDOWN_OPTION};" \
+            $URLIDS $SHUTDOWN_URLIDS || exit 1
+        minsleep $MAX_TERMINATE_SECS $HSQLDB_PID || {
+            echo "WARNING:  ${SERVICE} is still running!" 1>&2
+            exit 1
+        }
+        rm -f "$PIDFILE" || {
+            echo "Failed to remove pid file '$PIDFILE'" 1>&2
+            exit 1
+        }
+        echo "Successful shutdown ${SHUTDOWN_OPTION} (for the $TARGET_CLASS process)!"
+        exit 0
+    ;;
+    restart|restartcompacted)
+        STOP_COMMAND=stop
+        [ "$COMMAND" = restartcompacted ] && STOP_COMMAND=stopcompact
+        "${INVOC_PATH}"${SERVICE} $STOP_COMMAND || exit $?
+        exec "${INVOC_PATH}"/${SERVICE} start
+    ;;
+    *)
+        echo "$SYNTAX_MSG" 1>&2
+        exit 5
+    ;;
+esac
diff --git a/sample/j-sample.sql b/sample/j-sample.sql
new file mode 100644
index 0000000..a084d17
--- /dev/null
+++ b/sample/j-sample.sql
@@ -0,0 +1,38 @@
+/*
+    $Id: j-sample.sql 3605 2010-06-01 02:21:36Z unsaved $
+    Exemplifies use of SqlTool's \j command to specify the JDBC connection
+    parameters right in the SQL file.
+
+    Invoke like this:
+
+        java -jar .../sqltool.jar - .../j-sample.sql
+
+    (give the file paths to wherever these two files reside).
+    Or start up SqlTool like this:
+
+        java -jar .../sqltool.jar
+
+    and then execute this script like
+
+        \i .../j-sample.sql
+*/
+
+-- Abort this script when errors occur.
+-- That's the default if the script is invoked from command-line, but not if
+-- invoked by \i.
+\c false
+ 
+-- Note the new feature in HyperSQL 2, whereby you can set an SA password
+-- by just specifying that as the password for the very first connection to
+-- that database
+\j SA fred jdbc:hsqldb:mem:fred
+--  FORMAT:  \j <USERAME> <PASSWORD> <JDBC_URL>
+
+\p You have conkected successfully
+\p
+
+CREATE TABLE t(i BIGINT, vc VARCHAR(20));
+INSERT INTO t VALUES(1, 'one');
+INSERT INTO t VALUES(2, 'two');
+
+SELECT * FROM t;
diff --git a/sample/load_binding_lu.sql b/sample/load_binding_lu.sql
new file mode 100644
index 0000000..13be042
--- /dev/null
+++ b/sample/load_binding_lu.sql
@@ -0,0 +1,31 @@
+/*
+    $Id: load_binding_lu.sql 610 2008-12-22 15:54:18Z unsaved $
+    Load BINDING Lookup Text Table
+*/
+
+\p Creating table BINDING_TMPTXT
+CREATE TEMP TEXT TABLE binding_tmptxt (
+    id integer,
+    name varchar(12)
+);
+
+\p Setting text file source
+SET TABLE binding_tmptxt SOURCE "binding_lu.ttbl;ignore_first=true;fs=|";
+
+\p rows in binding_tmptxt:
+select count(*) from binding_tmptxt;
+\p PRE rows in binding_lu:
+select count(*) from binding_lu;
+
+INSERT INTO binding_lu (
+    id,
+    name
+) SELECT
+    id,
+    name
+FROM BINDING_TMPTXT;
+
+commit;
+
+\p POST rows in binding_lu:
+select count(*) from binding_lu;
diff --git a/sample/pl.sql b/sample/pl.sql
new file mode 100644
index 0000000..21d5264
--- /dev/null
+++ b/sample/pl.sql
@@ -0,0 +1,87 @@
+/*
+    $Id: pl.sql 3348 2009-12-15 14:24:19Z unsaved $
+    SQL File to illustrate the use of SqlTool PL features.
+    Invoke like
+        java -jar .../hsqldb.jar .../pl.sql mem
+                                                         -- blaine
+*/
+
+* if (! *MYTABLE)
+    \p MYTABLE variable not set!
+    /* You could use \q to Quit SqlTool, but it's often better to just
+       break out of the current SQL file.
+       If people invoke your script from SqlTool interactively (with
+       \i yourscriptname.sql) any \q will kill their SqlTool session. */
+    \p Use arguments "--setvar=MYTABLE=mytablename" for SqlTool
+    * break
+* end if
+
+/* Turning on Continue-upon-errors so that we can check for errors ourselves.*/
+\c true
+
+\p
+\p Loading up a table named '*{MYTABLE}'...
+
+/* This sets the PL variable 'retval' to the return status of the following
+   SQL command */
+* retval ~
+CREATE TABLE *{MYTABLE} (
+    i int,
+    s varchar(20);
+);
+\p CREATE status is *{retval}
+\p
+
+/* Validate our return status.  In logical expressions, unset variables like
+   *unsetvar are equivalent to empty string, which is not equal to 0
+   (though both do evaluate to false on their own, i.e. (*retval) is false
+   and (0) is false */
+* if (*retval != 0)
+    \p Our CREATE TABLE command failed.
+    * break
+* end if
+
+/* Default Continue-on-error behavior is what you usually want */
+\c false
+\p
+
+/* Insert data with a foreach loop.
+   These values could be from a read of another table or from variables
+   set on the command line like
+*/
+\p Inserting some data int our new table (you should see 3 row update messages)
+* foreach VALUE (12 22 24 15)
+    * if (*VALUE > 23)
+        \p Skipping *{VALUE} because it is greater than 23
+        * continue
+        \p YOU WILL NEVER SEE THIS LINE, because we just 'continued'.
+    * end if
+    INSERT INTO *{MYTABLE} VALUES (*{VALUE}, 'String of *{VALUE}');
+* end foreach
+\p
+
+* themax ~
+/* Can put Special Commands and comments between "* VARNAME ~" and the target 
+   SQL statement. */
+\p We're saving the max value for later.  You'll still see query output here:
+SELECT MAX(i) FROM *{MYTABLE};
+
+/* This is usually unnecessary because if the SELECT failed, retval would
+   be undefined and the following print statement would make SqlTool exit with
+   a failure status */
+* if (! *themax)
+    \p Failed to get the max value.
+    /* It's possible that the query succeeded but themax is "0".
+       You can check for that if you need to. */
+    * break
+    \p YOU WILL NEVER SEE THIS LINE, because we just 'broke'.
+* end if
+
+\p
+\p ##############################################################
+\p The results of our work:
+SELECT * FROM *{MYTABLE};
+\p MAX value is *{themax}
+
+\p
+\p Everything worked.
diff --git a/sample/plsql.sql b/sample/plsql.sql
new file mode 100644
index 0000000..2e8c42a
--- /dev/null
+++ b/sample/plsql.sql
@@ -0,0 +1,51 @@
+/*
+ * $Id: plsql.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * This example is copied from the "Simple Programs in PL/SQL"
+ * example by Yu-May Chang, Jeff Ullman, Prof. Jennifer Widom at
+ * the Standord University Database Group's page
+ * http://www-db.stanford.edu/~ullman/fcdb/oracle/or-plsql.html .
+ * I have only removed some blank lines (in case somebody wants to
+ * copy this code interactively-- because you can't use blank
+ * lines inside of SQL commands in non-raw mode SqlTool when running
+ * it interactively); and, at the bottom I have  replaced the
+ * client-specific, non-standard command "run;" with SqlTool's
+ * corresponding command ".;" and added a plain SQL SELECT command
+ * to show whether the PL/SQL code worked.  - Blaine
+ */
+
+CREATE TABLE T1(
+    e INTEGER,
+    f INTEGER
+);
+
+DELETE FROM T1;
+
+INSERT INTO T1 VALUES(1, 3);
+
+INSERT INTO T1 VALUES(2, 4);
+
+/* Above is plain SQL; below is the PL/SQL program. */
+DECLARE
+
+    a NUMBER;
+
+    b NUMBER;
+
+BEGIN
+
+    SELECT e,f INTO a,b FROM T1 WHERE e>1;
+
+    INSERT INTO T1 VALUES(b,a);
+
+END;
+
+.;
+/** The statement on the previous line, ".;" is SqlTool specific.
+ *  This command says to save the input up to this point to the
+ *  edit buffer and send it to the database server for execution.
+ *  I added the SELECT statement below to give imm
+ */
+
+/* This should show 3 rows, one containing values 4 and 2 (in this order)...*/
+SELECT * FROM t1;
diff --git a/sample/sample.c b/sample/sample.c
new file mode 100644
index 0000000..fd105ed
--- /dev/null
+++ b/sample/sample.c
@@ -0,0 +1,348 @@
+/*
+ * @(#)$Id: sample.c 3635 2010-06-07 00:18:34Z unsaved $
+ *
+ * HyperSQL Database Engine
+ *
+ * Copyright (c) 2009, The HSQL Development Group
+ */
+
+
+#include <stdio.h>
+#ifdef _WINDOWS
+#include <windows.h>
+#endif
+#include <sqlext.h>
+// sqlext.h pulls in all other ODBC header files that we need
+#include <string.h>
+#include <stdlib.h>
+
+extern int detectOdbcFailure(SQLRETURN rv, SQLHENV c, char* failMsg);
+extern int print_ret(char* msg, int retval);
+extern int print2_ret(char* msg, char* msg2, int retval);
+
+/**
+ * This test HyperSQL client uses the ODBC DSN "tstdsn" to connect up to a
+ * HyperSQL server.  Just configure your own DSN to use the HyperSQL ODBC
+ * driver, specifying the HyperSQL server host name, database name, user,
+ * password, etc.
+ *
+ * Sample C program accessing HyperSQL.
+ *
+ * ODBC C API ref at
+ *  http://msdn.microsoft.com/en-us/library/ms714562(VS.85).aspx .
+ * Summary of functions at
+ *  http://msdn.microsoft.com/en-us/library/ms712628(VS.85).aspx
+ *
+ * To build on UNIX with unixODBC:<PRE><CODE>
+ *     gcc -lodbc -o sample sample.c
+ * </CODE></PRE>
+ *
+ * To build in Windows with MSVC++ (Express variant is free):<PRE><CODE>
+ *      cl /nologo /D _WINDOWS /D ODBCVER=0x0351 /c sample.c
+ *      link odbc32.lib /nologo /machine:x86 sample.obj /out:sample.exe
+ * </CODE></PRE>
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+int main(int argc, char** argv) {
+    SQLRETURN odbcret;
+    SQLHENV sqlhenv;
+    SQLHENV conn;
+    SQLHSTMT stmt;
+    char *cp;
+    long in_idval;
+    const int cstrmax = 100;
+    char *in_vcval = malloc(cstrmax);
+    long out_idval;
+    char *out_vcval = malloc(cstrmax);
+    char *out_etimeval = malloc(cstrmax);
+    SQLLEN ntsval = SQL_NTS;
+    int detect;
+
+    // I. CONNECT
+    odbcret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlhenv);
+    if (odbcret != SQL_SUCCESS && odbcret != SQL_SUCCESS_WITH_INFO)
+        return print_ret("Failed to allocate an ODBC environment handle", 1);
+
+    odbcret =
+        SQLSetEnvAttr(sqlhenv, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, 0);
+    if (odbcret != SQL_SUCCESS && odbcret != SQL_SUCCESS_WITH_INFO)
+        return print_ret("Failed to set ODBC version 3.0", 2);
+
+    odbcret = SQLAllocHandle(SQL_HANDLE_DBC, sqlhenv, &conn);
+    if (odbcret != SQL_SUCCESS && odbcret != SQL_SUCCESS_WITH_INFO)
+        return print_ret("Failed to allocate an ODBC connection handle", 3);
+
+    odbcret = SQLSetConnectAttr(
+            conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+    if (odbcret != SQL_SUCCESS && odbcret != SQL_SUCCESS_WITH_INFO)
+        return print_ret("Failed to allocate an ODBC connection handle", 3);
+    // May also want to set timeout values in the same way
+
+    // Can override the DSN-defined user name and/or password here:
+    detect = detectOdbcFailure(
+            SQLConnect(conn, (SQLCHAR*) "tstdsn", SQL_NTS, (SQLCHAR*) NULL, 0,
+                (SQLCHAR*) NULL, 0),
+            conn, "Connection failure");
+    if (detect) return detect;
+
+
+    // II. PREPARE OBJECTS FOR USE
+    detect = detectOdbcFailure(
+            SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt), conn,
+            "Failed to allocate an ODBC statement handle");
+    if (detect) return detect;
+
+    // Just using this char pointer because some non-ANSI compilers won't let
+    // us declare a char array/pointer here.
+    cp = "DROP TABLE tsttbl IF EXISTS";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "DROP statement failed");
+    if (detect) return detect;
+
+    // Some recent change to the HyperSQL server or to unixODBC
+    // has made this commit necessary, at least on UNIX.  Some other
+    // transaction control command would probably be more
+    // appropriate here.
+    detect = detectOdbcFailure(SQLEndTran(SQL_HANDLE_DBC, conn, SQL_COMMIT),
+            conn, "COMMIT failed");
+    if (detect) return detect;
+
+    cp = "CREATE TABLE tsttbl(\n\
+    id BIGINT generated BY DEFAULT AS IDENTITY,\n\
+    vc VARCHAR(20),\n\
+    entrytime TIMESTAMP DEFAULT current_timestamp NOT NULL\n\
+)";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "CREATE TABLE statement failed");
+    if (detect) return detect;
+
+    detect = detectOdbcFailure(SQLCloseCursor(stmt), conn,
+            "Failed to close Cursor for re-use");
+    if (detect) return detect;
+
+
+    // III. INSERT DATA
+    // Non-parameter INSERT
+    cp = "INSERT INTO tsttbl (id, vc) values (1, 'one')";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "1st Insertion failed");
+    if (detect) return detect;
+
+#ifdef _WINDOWS
+    // TODO:  PROBLEM with Parameterized INPUT in Windows (works fine on UNIX).
+    // For some reason, even if we are do a Prepare/Execute (and our
+    // driver is set to always use server-side Preparation), the client side
+    // is doing the substitution... and doing a bad Lob of it too.
+    // Therefore, we do all INSERTs statically for Windows here:
+    cp = "INSERT INTO tsttbl (id, vc) values (2, 'two')";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "2nd Insertion failed");
+    if (detect) return detect;
+    cp = "INSERT INTO tsttbl (id, vc) values (3, 'three')";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "3rd Insertion failed");
+    if (detect) return detect;
+    cp = "INSERT INTO tsttbl (id, vc) values (4, 'four')";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "4th Insertion failed");
+    if (detect) return detect;
+    cp = "INSERT INTO tsttbl (id, vc) values (5, 'five')";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "5th Insertion failed");
+    if (detect) return detect;
+#else
+    // Parameterized INSERT
+    cp = "INSERT INTO tsttbl (id, vc) values (?, ?)";
+    detect = detectOdbcFailure(SQLPrepare(stmt, (SQLCHAR*) cp, SQL_NTS), conn,
+        "Preparation of Insertion stmt failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT,
+            0, 0, &in_idval, 0, NULL), conn,
+            "Bind of 'id' input failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR,
+            20, 0, in_vcval, cstrmax, &ntsval), conn,
+            "Bind of 'vc' input failed");
+    if (detect) return detect;
+
+    in_idval = 2;
+    strcpy(in_vcval, "two");
+    detect = detectOdbcFailure(SQLExecute(stmt), conn,
+            "Insertion of 2nd row failed");
+    if (detect) return detect;
+    in_idval = 3;
+    strcpy(in_vcval, "three");
+    detect = detectOdbcFailure(SQLExecute(stmt), conn,
+            "Insertion of 3rd row failed");
+    if (detect) return detect;
+    in_idval = 4;
+    strcpy(in_vcval, "four");
+    detect = detectOdbcFailure(SQLExecute(stmt), conn,
+            "Insertion of 4th row failed");
+    if (detect) return detect;
+    in_idval = 5;
+    strcpy(in_vcval, "five");
+    detect = detectOdbcFailure(SQLExecute(stmt), conn,
+            "Insertion of 5th row failed");
+    if (detect) return detect;
+#endif
+
+    detect = detectOdbcFailure(SQLEndTran(SQL_HANDLE_DBC, conn, SQL_COMMIT),
+            conn, "COMMIT failed");
+    if (detect) return detect;
+    
+    detect = detectOdbcFailure(SQLCloseCursor(stmt), conn,
+            "Failed to close Cursor for re-use");
+    if (detect) return detect;
+
+
+    // IV. QUERIES
+    // Non-Parameter QUERY
+    cp = "SELECT * FROM tsttbl WHERE id < 3";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "Non-parameter query failed");
+    // Would return SQL_NO_DATA if no rows inserted.
+    // Don't need to bind until before fetches are performed.
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 1, SQL_C_SLONG, &out_idval, 0, NULL), conn,
+            "Bind of 'id' output failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 2, SQL_C_CHAR, out_vcval, cstrmax, &ntsval),
+            conn, "Bind of 'vc' output failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 3, SQL_C_CHAR, out_etimeval, cstrmax, &ntsval),
+            conn, "Bind of 'entrytime' output failed");
+    if (detect) return detect;
+
+    while ((odbcret = SQLFetch(stmt)) != SQL_NO_DATA) {
+        if (detectOdbcFailure(odbcret, conn, "Fetch failed")) return detect;
+        printf("%dl|%s|%s\n", out_idval, out_vcval, out_etimeval);
+    }
+    
+    detect = detectOdbcFailure(SQLCloseCursor(stmt), conn,
+            "Failed to close Cursor for re-use");
+    if (detect) return detect;
+
+#if _WINDOWS
+    // Input parameters not working on Windows.  See comment above.
+    cp = "SELECT * FROM tsttbl WHERE id > 3";
+    detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn,
+            "Non-parameter query failed");
+    // Would return SQL_NO_DATA if no rows inserted.
+    // Don't need to bind until before fetches are performed.
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 1, SQL_C_SLONG, &out_idval, 0, NULL), conn,
+            "Bind of 'id' output failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 2, SQL_C_CHAR, out_vcval, cstrmax, &ntsval),
+            conn, "Bind of 'vc' output failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 3, SQL_C_CHAR, out_etimeval, cstrmax, &ntsval),
+            conn, "Bind of 'entrytime' output failed");
+    if (detect) return detect;
+
+    while ((odbcret = SQLFetch(stmt)) != SQL_NO_DATA) {
+        if (detectOdbcFailure(odbcret, conn, "Fetch failed")) return detect;
+        printf("%dl|%s|%s\n", out_idval, out_vcval, out_etimeval);
+    }
+#else
+
+    // Parameterized QUERY
+    cp = "SELECT * FROM tsttbl WHERE id > ?";
+    detect = detectOdbcFailure(SQLPrepare(stmt, (SQLCHAR*) cp, SQL_NTS), conn,
+        "Preparation of Query stmt failed");
+    if (detect) return detect;
+    in_idval = 3;
+    detect = detectOdbcFailure(
+            SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT,
+            0, 0, &in_idval, 0, NULL), conn,
+            "Bind of 'id' input failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(SQLExecute(stmt), conn,
+            "Parameterized query failed");
+    // Would return SQL_NO_DATA if no rows selected
+    // Don't need to bind until before fetches are performed.
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 1, SQL_C_SLONG, &out_idval, 0, NULL), conn,
+            "Bind of 'id' output failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 2, SQL_C_CHAR, out_vcval, cstrmax, &ntsval),
+            conn, "Bind of 'vc' output failed");
+    if (detect) return detect;
+    detect = detectOdbcFailure(
+            SQLBindCol(stmt, 3, SQL_C_CHAR, out_etimeval, cstrmax, &ntsval),
+            conn, "Bind of 'entrytime' output failed");
+    if (detect) return detect;
+#endif
+
+    while ((odbcret = SQLFetch(stmt)) != SQL_NO_DATA) {
+        if (detectOdbcFailure(odbcret, conn, "Fetch failed")) return detect;
+        printf("%dl|%s|%s\n", out_idval, out_vcval, out_etimeval);
+    }
+    
+    detect = detectOdbcFailure(SQLCloseCursor(stmt), conn,
+            "Failed to close Cursor");
+    if (detect) return detect;
+
+    SQLDisconnect(conn);
+    SQLFreeHandle(SQL_HANDLE_DBC, conn);
+    SQLFreeHandle(SQL_HANDLE_ENV, sqlhenv);
+    //return print_ret("Success", 0);
+    return 0;
+}
+
+/**
+ * Displays error message and prepare for program exit.
+ */
+int barf(SQLHENV c, char* failMsg) {
+    char sqlhmsg[200], sqlhstat[10];
+    SQLSMALLINT junksmall;
+    SQLINTEGER errint;
+
+    SQLGetDiagRec(SQL_HANDLE_DBC, c, 1, sqlhstat, &errint,
+            sqlhmsg, 100, &junksmall);
+    return print2_ret(failMsg, sqlhmsg, 1);
+}
+
+/**
+ * Displays error message and prepare for program exit if the given
+ * rv indicates ODBC failure.
+ */
+int detectOdbcFailure(SQLRETURN rv, SQLHENV c, char* failMsg) {
+    if (rv == SQL_SUCCESS || rv == SQL_SUCCESS_WITH_INFO) return 0;
+    return barf(c, failMsg);
+}
+
+/**
+ * 2-param wrapper for print2_ret() function.
+ */
+int print_ret(char* msg, int retval) {
+    return print2_ret(msg, (char*) NULL, retval);
+}
+
+/**
+ * Displays message to stderr and returns given value.
+ *
+ * Function name here is a hack, because I don't remember how to overload C
+ * functions (in a portable way).
+ */
+int print2_ret(char* msg, char* msg2, int retval) {
+    fputs(msg, stderr);
+    fputc('\n', stderr);
+    if (msg2 != NULL) {
+        fputs(msg2, stderr);
+        fputc('\n', stderr);
+    }
+    return retval;
+}
diff --git a/sample/sample.dsv b/sample/sample.dsv
new file mode 100644
index 0000000..4cea471
--- /dev/null
+++ b/sample/sample.dsv
@@ -0,0 +1,16 @@
+# Comment lines like this are permitted by default, as are
+
+# blank lines.  Header line follows:
+i|d|b
+
+# Two good rows:
+1|2007-01-02|true
+2|2007-01-03|false
+
+# This should cause a parse error:
+3|not a date|true
+
+# This should cause a database error:
+4||true
+
+5|2007-01-04|false
diff --git a/sample/sample.php b/sample/sample.php
new file mode 100755
index 0000000..d6fd84d
--- /dev/null
+++ b/sample/sample.php
@@ -0,0 +1,75 @@
+#!/usr/bin/php5
+<?php
+
+# $Id: sample.php 3633 2010-06-06 23:56:41Z unsaved $
+
+# Sample PHP script accessing HyperSQL through the ODBC extension module.
+# (Therefore, you need to have the PHP ODBC module installed).
+
+# This test HyperSQL client uses the ODBC DSN "tstdsn" to connect up to a
+# HyperSQL server.  Just configure your own DSN to use the HyperSQL ODBC
+# driver, specifying the HyperSQL server host name, database name, user,
+# password, etc.
+
+# Author:  Blaine Simpson  (blaine dot simpson at admc dot com)
+
+
+# Empty strings for the username or password parameter here will defer
+# to the ODBC manager for those values.  I.e. the blanks here do not mean to
+# send blanks to the database server.
+$conn_id = odbc_connect('tstdsn', '', '');
+if (!$conn_id) exit('Connection Failed: ' . $conn_id . "\n");
+
+if (!odbc_autocommit($conn_id, FALSE))
+    exit("Failed to turn off AutoCommit mode\n");
+
+if (!odbc_exec($conn_id, "DROP TABLE tsttbl IF EXISTS"))
+    exit("DROP command failed\n");
+
+if (!odbc_exec($conn_id,
+"CREATE TABLE tsttbl(
+    id BIGINT generated BY DEFAULT AS IDENTITY,
+    vc VARCHAR(20),
+    entrytime TIMESTAMP DEFAULT current_timestamp NOT NULL
+)"))
+    exit("CREATE TABLE command failed\n");
+
+
+# First do a non-parameterized insert
+if (!odbc_exec($conn_id, "INSERT INTO tsttbl(id, vc) VALUES(1, 'one')"))
+    exit("Insertion of first row failed\n");
+
+# Now parameterized inserts
+$stmt = odbc_prepare($conn_id, "INSERT INTO tsttbl(id, vc) VALUES(?, ?)");
+if (!$stmt) exit("Preparation of INSERT statement failed \n");
+
+# With (default) debug mode, the following statements will generate
+# annoying "cursor updatability" warnings.
+$rv = odbc_execute($stmt, array(2, 'two'));
+if ($rv != 1) exit("2nd Insertion failed with  value $rv\n");
+$rv = odbc_execute($stmt, array(3, 'three'));
+if ($rv != 1) exit("3rd Insertion failed with  value $rv\n");
+$rv = odbc_execute($stmt, array(4, 'four'));
+if ($rv != 1) exit("4th Insertion failed with  value $rv\n");
+$rv = odbc_execute($stmt, array(5, 'five'));
+if ($rv != 1) exit("5th Insertion failed with  value $rv\n");
+odbc_commit($conn_id);
+
+# A non-parameterized query
+$rs = odbc_exec($conn_id, "SELECT * FROM tsttbl WHERE id < 3");
+if (!$rs) exit("Error in SQL\n");
+
+$rownum = 0;
+while (odbc_fetch_row($rs)) {
+    $rownum++;
+    echo "$rownum: " .  odbc_result($rs, "id")
+        . '|' . odbc_result($rs, "vc")
+        . '|' . odbc_result($rs, "entrytime") . "\n";
+}
+
+# You need to use the PDO_ODBC extension to parameterize queries (selects).
+# If you want an example of this, just ask.
+
+odbc_close($conn_id);
+
+?>
diff --git a/sample/sample.pl b/sample/sample.pl
new file mode 100755
index 0000000..a51b290
--- /dev/null
+++ b/sample/sample.pl
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+
+# $Id: sample.pl 3633 2010-06-06 23:56:41Z unsaved $
+
+# Sample Perl script accessing HyperSQL through the Perl DBI and DBD/ODBC
+# modules.
+
+# This test HyperSQL client uses the ODBC DSN "tstdsn" to connect up to a
+# HyperSQL server.  Just configure your own DSN to use the HyperSQL ODBC
+# driver, specifying the HyperSQL server host name, database name, user,
+# password, etc.
+
+# Author:  Blaine Simpson  (blaine dot simpson at admc dot com)
+
+
+use strict;
+use DBI;
+
+use vars qw:$dsn $dbh $sth $row $retval %conAttr:;
+
+$conAttr{AutoCommit} = 0;
+
+# In addition to the DSN name, you can override or supply additional DSN
+# settings, such as "Uid" and "Pwd"; or define the DSN from scratch, starting
+# with Driver.  These settings are delimited with "; ".  See pyodbc docs.
+$dsn = "dbi:ODBC:dsn=tstdsn";
+
+#$dbh = DBI->connect($dsn, undef, undef)
+$dbh = DBI->connect($dsn, undef, undef, \%conAttr)
+    or die("Failed to connect: ($DBI::err) $DBI::errstr\n");
+
+$dbh->do("DROP TABLE tsttbl IF EXISTS");
+$dbh->do(
+    "CREATE TABLE tsttbl(\n"
+    . "    id BIGINT generated BY DEFAULT AS IDENTITY,\n"
+    . "    vc VARCHAR(20),\n"
+    . "    entrytime TIMESTAMP DEFAULT current_timestamp NOT NULL\n"
+    . ")");
+
+# First a simple/non-parameterized Insertion
+$retval = $dbh->do("INSERT INTO tsttbl (id, vc) values (1, 'one')");
+die "First insertion inserted $retval rows instead of 1\n" unless $retval eq 1;
+
+# Now same thing with parameters
+$sth = $dbh->prepare("INSERT INTO tsttbl (id, vc) values (?, ?)")
+    or die("Failed to prepare Insertion statement: ($DBI::err) $DBI::errstr\n");
+$retval = $sth->execute(2, 'two')
+    or die("2nd insertion failed: ($DBI::err) $DBI::errstr\n");
+die "2nd insertion inserted $retval rows instead of 1\n" unless $retval eq 1;
+
+# The disabled testa re due to known bug with driver.
+# The misleading warnings withe "SQL-HY000" may be ignored.
+$retval = $sth->execute(3, 'three');
+    #or die("3rd insertion failed: ($DBI::err) $DBI::errstr\n");
+#die "3rd insertion inserted $retval rows instead of 1\n" unless $retval eq 1;
+$retval = $sth->execute(4, 'four');
+    #or die("4th insertion failed: ($DBI::err) $DBI::errstr\n");
+#die "4th insertion inserted $retval rows instead of 1\n" unless $retval eq 1;
+$retval = $sth->execute(5, 'five');
+    #or die("5th insertion failed: ($DBI::err) $DBI::errstr\n");
+#die "5th insertion inserted $retval rows instead of 1\n" unless $retval eq 1;
+$dbh->commit;
+    # Some recent change to the HyperSQL server or to unixODBC has made this
+    # necessary, at least on UNIX.  Some other transaction control command
+    # would probably be more appropriate here.
+
+# Now a simple/non-parameterized Query
+$sth = $dbh->prepare("SELECT * FROM tsttbl WHERE id < 3")
+    or die("Failed to prepare SELECT statement: ($DBI::err) $DBI::errstr\n");
+$sth->execute()
+    or die("Execution of non-param. query failed : ($DBI::err) $DBI::errstr\n");
+
+while ($row = $sth->fetch()) {
+    print(join '|', @$row);
+    print("\n");
+}
+$sth->finish();
+
+$dbh->do('rollback');
+
+# Now a parameterized Query
+$sth = $dbh->prepare("SELECT * FROM tsttbl WHERE id > ?")
+    or die("Failed to prepare SELECT statement: ($DBI::err) $DBI::errstr\n");
+# Use bind_param for variety
+$sth->bind_param(1, 3);
+$sth->execute()
+    or die("Exec. of parameterized query failed : ($DBI::err) $DBI::errstr\n");
+
+while ($row = $sth->fetch()) {
+    print(join '|', @$row);
+    print("\n");
+}
+$sth->finish();
+
+$dbh->disconnect();
+
+exit(0);
diff --git a/sample/sample.py b/sample/sample.py
new file mode 100755
index 0000000..9948a24
--- /dev/null
+++ b/sample/sample.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+
+# $Id: sample.py 3633 2010-06-06 23:56:41Z unsaved $
+
+# Sample Python script accessing HyperSQL through the Python pyodbc module.
+
+# This test HyperSQL client uses the ODBC DSN "tstdsn-a" to connect up to a
+# HyperSQL server.  Just configure your own DSN to use the HyperSQL ODBC
+# driver, specifying the HyperSQL server host name, database name, user,
+# password, etc.
+
+# N.b. there is some dependency or bug which requires pyodbc to use the
+# ANSI variant of the HyperSQL ODBC Driver.  Using the normal Unicode
+# variant will generate the following error message when you try to connect:
+#    pyodbc.Error: ('0', '[0] [unixODBC]c (202) (SQLDriverConnectW)')
+# It is quite possible that this issue will be taken care of when we fix a
+# high-priority bug to do with switching between SQLDriverConnect and
+# SQLDriverConnectW on UNIX.
+
+# Author:  Blaine Simpson  (blaine dot simpson at admc dot com)
+
+import pyodbc
+
+# Get a connection handle.
+# In addition to the DSN name, you can override or supply additional DSN
+# settings, such as "Uid" and "Pwd"; or define the DSN from scratch, starting
+# with Driver.  These settings are delimited with "; ".  See pyodbc docs.
+conn = pyodbc.connect("DSN=tstdsn-a")
+try:
+    conn.autocommit = 0
+
+    cursor = conn.cursor();
+
+    cursor.execute("DROP TABLE tsttbl IF EXISTS");
+    conn.commit();  # Some recent change to the HyperSQL server or to unixODBC
+                    # has made this necessary, at least on UNIX.  Some other
+                    # transaction control command would probably be more
+                    # appropriate here.
+
+    cursor.execute(
+        "CREATE TABLE tsttbl(\n"
+        + "    id BIGINT generated BY DEFAULT AS IDENTITY,\n"
+        + "    vc VARCHAR(20),\n"
+        + "    entrytime TIMESTAMP DEFAULT current_timestamp NOT NULL\n"
+        + ")");
+
+    # First a simple/non-parameterized Insertion
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (1, 'one')");
+    if retval != 1:
+        raise Exception(('1st insertion inserted ' + repr(retval)
+            + ' rows instead of 1'))
+    # Now parameterized.  Unfortunately, the Python DB API and pyodbc API do
+    # not allow re-use of a parsed statement.  Cursor must be reparsed for
+    # each usage.
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)",
+            2, 'two');
+    if retval != 1:
+        raise Exception(('2nd insertion inserted ' + repr(retval)
+            + ' rows instead of 2'))
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)",
+            3, 'three');
+    if retval != 1:
+        raise Exception(('3rd insertion inserted ' + repr(retval)
+            + ' rows instead of 3'))
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)",
+            4, 'four');
+    if retval != 1:
+        raise Exception(('4th insertion inserted ' + repr(retval)
+            + ' rows instead of 4'))
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)",
+            5, 'five');
+    if retval != 1:
+        raise Exception(('5th insertion inserted ' + repr(retval)
+            + ' rows instead of 5'))
+    conn.commit();
+
+    # Non-parameterized query
+    for row in cursor.execute(
+            "SELECT * FROM tsttbl WHERE id < 3"):
+        print row
+
+    # Non-parameterized query.  As noted above, can't re-use parsed cursor.
+    for row in cursor.execute(
+            "SELECT * FROM tsttbl WHERE id > ?", 3):
+        # For variety, we format the files ourselves this time
+        print repr(row.ID) + '|' + row.VC + '|' + repr(row.ENTRYTIME)
+
+except Exception as e:
+    conn.rollback();
+    raise e
+
+finally:
+    conn.close();
diff --git a/sample/sample.sql b/sample/sample.sql
new file mode 100644
index 0000000..0f738e1
--- /dev/null
+++ b/sample/sample.sql
@@ -0,0 +1,47 @@
+/*
+    $Id: sample.sql 3605 2010-06-01 02:21:36Z unsaved $
+    Exemplifies use of SqlTool.
+    PCTASK Table creation
+*/
+
+/* Ignore error for these two statements */
+\c true
+DROP TABLE pctasklist;
+DROP TABLE pctask;
+\c false
+
+\p Creating table pctask
+CREATE TABLE pctask (
+    id integer identity,
+    name varchar(40),
+    description varchar(256),
+    url varchar(80),
+    UNIQUE (name)
+);
+
+\p Creating table pctasklist
+CREATE TABLE pctasklist (
+    id integer identity,
+    host varchar(20) not null,
+    tasksequence int not null,
+    pctask integer,
+    assigndate timestamp default current_timestamp,
+    completedate timestamp,
+    show boolean default true,
+    FOREIGN KEY (pctask) REFERENCES pctask,
+    UNIQUE (host, tasksequence)
+);
+
+\p Granting privileges
+GRANT select ON pctask TO public;
+GRANT all ON pctask TO tomcat;
+GRANT select ON pctasklist TO public;
+GRANT all ON pctasklist TO tomcat;
+
+\p Inserting test records
+INSERT INTO pctask (name, description, url) VALUES (
+    'task one', 'Description for task 1', 'http://cnn.com');
+INSERT INTO pctasklist (host, tasksequence, pctask) VALUES (
+    'admc-masq', 101, (SELECT id FROM pctask WHERE name = 'task one'));
+
+commit;
diff --git a/sample/sampledata.sql b/sample/sampledata.sql
new file mode 100644
index 0000000..833d143
--- /dev/null
+++ b/sample/sampledata.sql
@@ -0,0 +1,822 @@
+/*
+ *  $Id: sampledata.sql 3348 2009-12-15 14:24:19Z unsaved $
+ *
+ *  Creates and populates database objects with sample data.
+ *  This file was created by grabbing the commands made by creating
+ *  sample data with the DatabaseManager utility.
+ */
+
+
+DROP TABLE Item IF EXISTS;
+DROP TABLE Invoice IF EXISTS;
+DROP TABLE Product IF EXISTS;
+DROP TABLE Customer IF EXISTS;
+CREATE TABLE Customer(ID INTEGER PRIMARY KEY,FirstName VARCHAR(20),LastName VARCHAR(30),Street VARCHAR(50),City VARCHAR(25));
+CREATE TABLE Product(ID INTEGER PRIMARY KEY,Name VARCHAR(30),Price DECIMAL);
+CREATE TABLE Invoice(ID INTEGER PRIMARY KEY,CustomerID INTEGER,Total DECIMAL, FOREIGN KEY (CustomerId) REFERENCES Customer(ID) ON DELETE CASCADE);
+CREATE TABLE Item(InvoiceID INTEGER,Item INTEGER,ProductID INTEGER,Quantity INTEGER,Cost DECIMAL,PRIMARY KEY(InvoiceID,Item), FOREIGN KEY (InvoiceId) REFERENCES Invoice (ID) ON DELETE CASCADE, FOREIGN KEY (ProductId) REFERENCES Product(ID) ON DELETE CASCADE);
+INSERT INTO Customer VALUES(0,'Laura','Steel','429 Seventh Av.','Dallas');
+INSERT INTO Product VALUES(0,'Iron Iron',54);
+INSERT INTO Customer VALUES(1,'Susanne','King','366 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(1,'Chair Shoe',248);
+INSERT INTO Customer VALUES(2,'Anne','Miller','20 Upland Pl.','Lyon');
+INSERT INTO Product VALUES(2,'Telephone Clock',248);
+INSERT INTO Customer VALUES(3,'Michael','Clancy','542 Upland Pl.','San Francisco');
+INSERT INTO Product VALUES(3,'Chair Chair',254);
+INSERT INTO Customer VALUES(4,'Sylvia','Ringer','365 College Av.','Dallas');
+INSERT INTO Product VALUES(4,'Ice Tea Shoe',128);
+INSERT INTO Customer VALUES(5,'Laura','Miller','294 Seventh Av.','Paris');
+INSERT INTO Product VALUES(5,'Clock Clock',236);
+INSERT INTO Customer VALUES(6,'Laura','White','506 Upland Pl.','Palo Alto');
+INSERT INTO Product VALUES(6,'Ice Tea Chair',98);
+INSERT INTO Customer VALUES(7,'James','Peterson','231 Upland Pl.','San Francisco');
+INSERT INTO Product VALUES(7,'Telephone Shoe',84);
+INSERT INTO Customer VALUES(8,'Andrew','Miller','288 - 20th Ave.','Seattle');
+INSERT INTO Product VALUES(8,'Ice Tea Clock',226);
+INSERT INTO Customer VALUES(9,'James','Schneider','277 Seventh Av.','Berne');
+INSERT INTO Product VALUES(9,'Clock Telephone',172);
+INSERT INTO Customer VALUES(10,'Anne','Fuller','135 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(10,'Telephone Ice Tea',204);
+INSERT INTO Customer VALUES(11,'Julia','White','412 Upland Pl.','Chicago');
+INSERT INTO Product VALUES(11,'Telephone Iron',88);
+INSERT INTO Customer VALUES(12,'George','Ott','381 Upland Pl.','Palo Alto');
+INSERT INTO Product VALUES(12,'Clock Ice Tea',168);
+INSERT INTO Customer VALUES(13,'Laura','Ringer','38 College Av.','New York');
+INSERT INTO Product VALUES(13,'Telephone Clock',180);
+INSERT INTO Customer VALUES(14,'Bill','Karsen','53 College Av.','Oslo');
+INSERT INTO Product VALUES(14,'Telephone Iron',124);
+INSERT INTO Customer VALUES(15,'Bill','Clancy','319 Upland Pl.','Seattle');
+INSERT INTO Product VALUES(15,'Ice Tea Chair',94);
+INSERT INTO Customer VALUES(16,'John','Fuller','195 Seventh Av.','New York');
+INSERT INTO Product VALUES(16,'Ice Tea Shoe',194);
+INSERT INTO Customer VALUES(17,'Laura','Ott','443 Seventh Av.','Lyon');
+INSERT INTO Product VALUES(17,'Clock Ice Tea',220);
+INSERT INTO Customer VALUES(18,'Sylvia','Fuller','158 - 20th Ave.','Paris');
+INSERT INTO Product VALUES(18,'Chair Clock',172);
+INSERT INTO Customer VALUES(19,'Susanne','Heiniger','86 - 20th Ave.','Dallas');
+INSERT INTO Product VALUES(19,'Ice Tea Ice Tea',110);
+INSERT INTO Customer VALUES(20,'Janet','Schneider','309 - 20th Ave.','Oslo');
+INSERT INTO Product VALUES(20,'Ice Tea Telephone',200);
+INSERT INTO Customer VALUES(21,'Julia','Clancy','18 Seventh Av.','Seattle');
+INSERT INTO Product VALUES(21,'Chair Chair',114);
+INSERT INTO Customer VALUES(22,'Bill','Ott','250 - 20th Ave.','Berne');
+INSERT INTO Product VALUES(22,'Iron Iron',66);
+INSERT INTO Customer VALUES(23,'Julia','Heiniger','358 College Av.','Boston');
+INSERT INTO Product VALUES(23,'Shoe Chair',76);
+INSERT INTO Customer VALUES(24,'James','Sommer','333 Upland Pl.','Olten');
+INSERT INTO Product VALUES(24,'Chair Shoe',72);
+INSERT INTO Customer VALUES(25,'Sylvia','Steel','269 College Av.','Paris');
+INSERT INTO Product VALUES(25,'Shoe Shoe',162);
+INSERT INTO Customer VALUES(26,'James','Clancy','195 Upland Pl.','Oslo');
+INSERT INTO Product VALUES(26,'Shoe Shoe',252);
+INSERT INTO Customer VALUES(27,'Bob','Sommer','509 College Av.','Seattle');
+INSERT INTO Product VALUES(27,'Telephone Iron',230);
+INSERT INTO Customer VALUES(28,'Susanne','White','74 - 20th Ave.','Lyon');
+INSERT INTO Product VALUES(28,'Clock Iron',30);
+INSERT INTO Customer VALUES(29,'Andrew','Smith','254 College Av.','New York');
+INSERT INTO Product VALUES(29,'Chair Telephone',112);
+INSERT INTO Customer VALUES(30,'Bill','Sommer','362 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(30,'Shoe Iron',232);
+INSERT INTO Customer VALUES(31,'Bob','Ringer','371 College Av.','Olten');
+INSERT INTO Product VALUES(31,'Ice Tea Telephone',48);
+INSERT INTO Customer VALUES(32,'Michael','Ott','339 College Av.','Boston');
+INSERT INTO Product VALUES(32,'Clock Iron',190);
+INSERT INTO Customer VALUES(33,'Mary','King','491 College Av.','Oslo');
+INSERT INTO Product VALUES(33,'Iron Chair',182);
+INSERT INTO Customer VALUES(34,'Julia','May','33 Upland Pl.','Seattle');
+INSERT INTO Product VALUES(34,'Chair Iron',256);
+INSERT INTO Customer VALUES(35,'George','Karsen','412 College Av.','Chicago');
+INSERT INTO Product VALUES(35,'Telephone Shoe',76);
+INSERT INTO Customer VALUES(36,'John','Steel','276 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(36,'Ice Tea Iron',32);
+INSERT INTO Customer VALUES(37,'Michael','Clancy','19 Seventh Av.','Dallas');
+INSERT INTO Product VALUES(37,'Clock Shoe',94);
+INSERT INTO Customer VALUES(38,'Andrew','Heiniger','347 College Av.','Lyon');
+INSERT INTO Product VALUES(38,'Clock Ice Tea',216);
+INSERT INTO Customer VALUES(39,'Mary','Karsen','202 College Av.','Chicago');
+INSERT INTO Product VALUES(39,'Ice Tea Shoe',154);
+INSERT INTO Customer VALUES(40,'Susanne','Miller','440 - 20th Ave.','Dallas');
+INSERT INTO Product VALUES(40,'Shoe Clock',28);
+INSERT INTO Customer VALUES(41,'Bill','King','546 College Av.','New York');
+INSERT INTO Product VALUES(41,'Clock Ice Tea',206);
+INSERT INTO Customer VALUES(42,'Robert','Ott','503 Seventh Av.','Oslo');
+INSERT INTO Product VALUES(42,'Iron Chair',198);
+INSERT INTO Customer VALUES(43,'Susanne','Smith','2 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(43,'Telephone Clock',94);
+INSERT INTO Customer VALUES(44,'Sylvia','Ott','361 College Av.','New York');
+INSERT INTO Product VALUES(44,'Ice Tea Ice Tea',96);
+INSERT INTO Customer VALUES(45,'Janet','May','396 Seventh Av.','Oslo');
+INSERT INTO Product VALUES(45,'Iron Ice Tea',180);
+INSERT INTO Customer VALUES(46,'Andrew','May','172 Seventh Av.','New York');
+INSERT INTO Product VALUES(46,'Ice Tea Clock',62);
+INSERT INTO Customer VALUES(47,'Janet','Fuller','445 Upland Pl.','Dallas');
+INSERT INTO Product VALUES(47,'Ice Tea Iron',178);
+INSERT INTO Customer VALUES(48,'Robert','White','549 Seventh Av.','San Francisco');
+INSERT INTO Product VALUES(48,'Clock Clock',210);
+INSERT INTO Customer VALUES(49,'George','Fuller','534 - 20th Ave.','Olten');
+INSERT INTO Product VALUES(49,'Iron Iron',22);
+INSERT INTO Invoice VALUES(0,0,0.0);
+INSERT INTO Invoice VALUES(1,33,0.0);
+INSERT INTO Invoice VALUES(2,23,0.0);
+INSERT INTO Invoice VALUES(3,21,0.0);
+INSERT INTO Invoice VALUES(4,30,0.0);
+INSERT INTO Invoice VALUES(5,34,0.0);
+INSERT INTO Invoice VALUES(6,19,0.0);
+INSERT INTO Invoice VALUES(7,26,0.0);
+INSERT INTO Invoice VALUES(8,29,0.0);
+INSERT INTO Invoice VALUES(9,38,0.0);
+INSERT INTO Invoice VALUES(10,24,0.0);
+INSERT INTO Invoice VALUES(11,24,0.0);
+INSERT INTO Invoice VALUES(12,23,0.0);
+INSERT INTO Invoice VALUES(13,39,0.0);
+INSERT INTO Invoice VALUES(14,35,0.0);
+INSERT INTO Invoice VALUES(15,39,0.0);
+INSERT INTO Invoice VALUES(16,45,0.0);
+INSERT INTO Invoice VALUES(17,46,0.0);
+INSERT INTO Invoice VALUES(18,4,0.0);
+INSERT INTO Invoice VALUES(19,9,0.0);
+INSERT INTO Invoice VALUES(20,19,0.0);
+INSERT INTO Invoice VALUES(21,8,0.0);
+INSERT INTO Invoice VALUES(22,40,0.0);
+INSERT INTO Invoice VALUES(23,36,0.0);
+INSERT INTO Invoice VALUES(24,15,0.0);
+INSERT INTO Invoice VALUES(25,31,0.0);
+INSERT INTO Invoice VALUES(26,27,0.0);
+INSERT INTO Invoice VALUES(27,24,0.0);
+INSERT INTO Invoice VALUES(28,35,0.0);
+INSERT INTO Invoice VALUES(29,46,0.0);
+INSERT INTO Invoice VALUES(30,13,0.0);
+INSERT INTO Invoice VALUES(31,22,0.0);
+INSERT INTO Invoice VALUES(32,20,0.0);
+INSERT INTO Invoice VALUES(33,40,0.0);
+INSERT INTO Invoice VALUES(34,33,0.0);
+INSERT INTO Invoice VALUES(35,4,0.0);
+INSERT INTO Invoice VALUES(36,42,0.0);
+INSERT INTO Invoice VALUES(37,39,0.0);
+INSERT INTO Invoice VALUES(38,46,0.0);
+INSERT INTO Invoice VALUES(39,5,0.0);
+INSERT INTO Invoice VALUES(40,4,0.0);
+INSERT INTO Invoice VALUES(41,19,0.0);
+INSERT INTO Invoice VALUES(42,38,0.0);
+INSERT INTO Invoice VALUES(43,13,0.0);
+INSERT INTO Invoice VALUES(44,32,0.0);
+INSERT INTO Invoice VALUES(45,42,0.0);
+INSERT INTO Invoice VALUES(46,24,0.0);
+INSERT INTO Invoice VALUES(47,45,0.0);
+INSERT INTO Invoice VALUES(48,22,0.0);
+INSERT INTO Invoice VALUES(49,32,0.0);
+INSERT INTO Item VALUES(0,12,1,11,1.5);
+INSERT INTO Item VALUES(0,11,12,4,1.5);
+INSERT INTO Item VALUES(0,10,4,8,1.5);
+INSERT INTO Item VALUES(0,9,35,4,1.5);
+INSERT INTO Item VALUES(0,8,0,23,1.5);
+INSERT INTO Item VALUES(0,7,7,10,1.5);
+INSERT INTO Item VALUES(0,6,16,9,1.5);
+INSERT INTO Item VALUES(0,5,12,15,1.5);
+INSERT INTO Item VALUES(0,4,47,1,1.5);
+INSERT INTO Item VALUES(0,3,1,9,1.5);
+INSERT INTO Item VALUES(0,2,47,3,1.5);
+INSERT INTO Item VALUES(0,1,14,19,1.5);
+INSERT INTO Item VALUES(0,0,7,12,1.5);
+INSERT INTO Item VALUES(1,6,25,19,1.5);
+INSERT INTO Item VALUES(1,5,25,9,1.5);
+INSERT INTO Item VALUES(1,4,16,16,1.5);
+INSERT INTO Item VALUES(1,3,38,8,1.5);
+INSERT INTO Item VALUES(1,2,19,6,1.5);
+INSERT INTO Item VALUES(1,1,0,9,1.5);
+INSERT INTO Item VALUES(1,0,40,8,1.5);
+INSERT INTO Item VALUES(2,16,36,24,1.5);
+INSERT INTO Item VALUES(2,15,0,18,1.5);
+INSERT INTO Item VALUES(2,14,48,19,1.5);
+INSERT INTO Item VALUES(2,13,12,1,1.5);
+INSERT INTO Item VALUES(2,12,21,15,1.5);
+INSERT INTO Item VALUES(2,11,42,21,1.5);
+INSERT INTO Item VALUES(2,10,49,11,1.5);
+INSERT INTO Item VALUES(2,9,18,7,1.5);
+INSERT INTO Item VALUES(2,8,39,2,1.5);
+INSERT INTO Item VALUES(2,7,30,5,1.5);
+INSERT INTO Item VALUES(2,6,43,8,1.5);
+INSERT INTO Item VALUES(2,5,30,4,1.5);
+INSERT INTO Item VALUES(2,4,38,18,1.5);
+INSERT INTO Item VALUES(2,3,19,13,1.5);
+INSERT INTO Item VALUES(2,2,11,9,1.5);
+INSERT INTO Item VALUES(2,1,25,3,1.5);
+INSERT INTO Item VALUES(2,0,4,18,1.5);
+INSERT INTO Item VALUES(3,17,30,17,1.5);
+INSERT INTO Item VALUES(3,16,19,11,1.5);
+INSERT INTO Item VALUES(3,15,23,18,1.5);
+INSERT INTO Item VALUES(3,14,17,22,1.5);
+INSERT INTO Item VALUES(3,13,41,2,1.5);
+INSERT INTO Item VALUES(3,12,41,22,1.5);
+INSERT INTO Item VALUES(3,11,7,11,1.5);
+INSERT INTO Item VALUES(3,10,10,17,1.5);
+INSERT INTO Item VALUES(3,9,29,17,1.5);
+INSERT INTO Item VALUES(3,8,49,9,1.5);
+INSERT INTO Item VALUES(3,7,26,4,1.5);
+INSERT INTO Item VALUES(3,6,13,18,1.5);
+INSERT INTO Item VALUES(3,5,30,10,1.5);
+INSERT INTO Item VALUES(3,4,20,12,1.5);
+INSERT INTO Item VALUES(3,3,0,22,1.5);
+INSERT INTO Item VALUES(3,2,49,3,1.5);
+INSERT INTO Item VALUES(3,1,1,20,1.5);
+INSERT INTO Item VALUES(3,0,11,21,1.5);
+INSERT INTO Item VALUES(4,5,37,24,1.5);
+INSERT INTO Item VALUES(4,4,9,18,1.5);
+INSERT INTO Item VALUES(4,3,23,20,1.5);
+INSERT INTO Item VALUES(4,2,41,23,1.5);
+INSERT INTO Item VALUES(4,1,35,15,1.5);
+INSERT INTO Item VALUES(4,0,28,9,1.5);
+INSERT INTO Item VALUES(5,13,18,17,1.5);
+INSERT INTO Item VALUES(5,12,8,15,1.5);
+INSERT INTO Item VALUES(5,11,38,23,1.5);
+INSERT INTO Item VALUES(5,10,28,18,1.5);
+INSERT INTO Item VALUES(5,9,37,9,1.5);
+INSERT INTO Item VALUES(5,8,20,3,1.5);
+INSERT INTO Item VALUES(5,7,2,4,1.5);
+INSERT INTO Item VALUES(5,6,7,9,1.5);
+INSERT INTO Item VALUES(5,5,46,15,1.5);
+INSERT INTO Item VALUES(5,4,32,14,1.5);
+INSERT INTO Item VALUES(5,3,24,12,1.5);
+INSERT INTO Item VALUES(5,2,20,18,1.5);
+INSERT INTO Item VALUES(5,1,9,23,1.5);
+INSERT INTO Item VALUES(5,0,9,5,1.5);
+INSERT INTO Item VALUES(6,11,44,1,1.5);
+INSERT INTO Item VALUES(6,10,16,13,1.5);
+INSERT INTO Item VALUES(6,9,19,2,1.5);
+INSERT INTO Item VALUES(6,8,41,19,1.5);
+INSERT INTO Item VALUES(6,7,26,10,1.5);
+INSERT INTO Item VALUES(6,6,37,22,1.5);
+INSERT INTO Item VALUES(6,5,14,20,1.5);
+INSERT INTO Item VALUES(6,4,31,20,1.5);
+INSERT INTO Item VALUES(6,3,30,2,1.5);
+INSERT INTO Item VALUES(6,2,23,8,1.5);
+INSERT INTO Item VALUES(6,1,38,21,1.5);
+INSERT INTO Item VALUES(6,0,15,20,1.5);
+INSERT INTO Item VALUES(7,18,23,5,1.5);
+INSERT INTO Item VALUES(7,17,40,1,1.5);
+INSERT INTO Item VALUES(7,16,7,12,1.5);
+INSERT INTO Item VALUES(7,15,24,17,1.5);
+INSERT INTO Item VALUES(7,14,47,14,1.5);
+INSERT INTO Item VALUES(7,13,32,23,1.5);
+INSERT INTO Item VALUES(7,12,40,16,1.5);
+INSERT INTO Item VALUES(7,11,19,13,1.5);
+INSERT INTO Item VALUES(7,10,7,1,1.5);
+INSERT INTO Item VALUES(7,9,9,21,1.5);
+INSERT INTO Item VALUES(7,8,42,19,1.5);
+INSERT INTO Item VALUES(7,7,2,22,1.5);
+INSERT INTO Item VALUES(7,6,14,4,1.5);
+INSERT INTO Item VALUES(7,5,24,10,1.5);
+INSERT INTO Item VALUES(7,4,2,13,1.5);
+INSERT INTO Item VALUES(7,3,30,2,1.5);
+INSERT INTO Item VALUES(7,2,27,17,1.5);
+INSERT INTO Item VALUES(7,1,23,12,1.5);
+INSERT INTO Item VALUES(7,0,43,16,1.5);
+INSERT INTO Item VALUES(8,9,21,23,1.5);
+INSERT INTO Item VALUES(8,8,38,7,1.5);
+INSERT INTO Item VALUES(8,7,6,5,1.5);
+INSERT INTO Item VALUES(8,6,15,19,1.5);
+INSERT INTO Item VALUES(8,5,24,18,1.5);
+INSERT INTO Item VALUES(8,4,15,8,1.5);
+INSERT INTO Item VALUES(8,3,41,16,1.5);
+INSERT INTO Item VALUES(8,2,11,8,1.5);
+INSERT INTO Item VALUES(8,1,44,16,1.5);
+INSERT INTO Item VALUES(8,0,34,15,1.5);
+INSERT INTO Item VALUES(9,19,48,23,1.5);
+INSERT INTO Item VALUES(9,18,3,12,1.5);
+INSERT INTO Item VALUES(9,17,13,17,1.5);
+INSERT INTO Item VALUES(9,16,24,10,1.5);
+INSERT INTO Item VALUES(9,15,48,23,1.5);
+INSERT INTO Item VALUES(9,14,15,8,1.5);
+INSERT INTO Item VALUES(9,13,42,13,1.5);
+INSERT INTO Item VALUES(9,12,25,23,1.5);
+INSERT INTO Item VALUES(9,11,12,16,1.5);
+INSERT INTO Item VALUES(9,10,38,11,1.5);
+INSERT INTO Item VALUES(9,9,13,6,1.5);
+INSERT INTO Item VALUES(9,8,24,11,1.5);
+INSERT INTO Item VALUES(9,7,2,22,1.5);
+INSERT INTO Item VALUES(9,6,18,10,1.5);
+INSERT INTO Item VALUES(9,5,6,2,1.5);
+INSERT INTO Item VALUES(9,4,36,16,1.5);
+INSERT INTO Item VALUES(9,3,4,14,1.5);
+INSERT INTO Item VALUES(9,2,29,12,1.5);
+INSERT INTO Item VALUES(9,1,18,21,1.5);
+INSERT INTO Item VALUES(9,0,45,8,1.5);
+INSERT INTO Item VALUES(10,9,5,10,1.5);
+INSERT INTO Item VALUES(10,8,22,11,1.5);
+INSERT INTO Item VALUES(10,7,4,13,1.5);
+INSERT INTO Item VALUES(10,6,18,14,1.5);
+INSERT INTO Item VALUES(10,5,5,24,1.5);
+INSERT INTO Item VALUES(10,4,10,24,1.5);
+INSERT INTO Item VALUES(10,3,46,1,1.5);
+INSERT INTO Item VALUES(10,2,7,9,1.5);
+INSERT INTO Item VALUES(10,1,33,17,1.5);
+INSERT INTO Item VALUES(10,0,20,1,1.5);
+INSERT INTO Item VALUES(11,8,20,1,1.5);
+INSERT INTO Item VALUES(11,7,48,22,1.5);
+INSERT INTO Item VALUES(11,6,0,12,1.5);
+INSERT INTO Item VALUES(11,5,19,2,1.5);
+INSERT INTO Item VALUES(11,4,47,16,1.5);
+INSERT INTO Item VALUES(11,3,32,21,1.5);
+INSERT INTO Item VALUES(11,2,0,3,1.5);
+INSERT INTO Item VALUES(11,1,21,21,1.5);
+INSERT INTO Item VALUES(11,0,45,10,1.5);
+INSERT INTO Item VALUES(12,18,9,4,1.5);
+INSERT INTO Item VALUES(12,17,31,15,1.5);
+INSERT INTO Item VALUES(12,16,0,9,1.5);
+INSERT INTO Item VALUES(12,15,22,16,1.5);
+INSERT INTO Item VALUES(12,14,25,11,1.5);
+INSERT INTO Item VALUES(12,13,36,21,1.5);
+INSERT INTO Item VALUES(12,12,13,12,1.5);
+INSERT INTO Item VALUES(12,11,28,16,1.5);
+INSERT INTO Item VALUES(12,10,46,19,1.5);
+INSERT INTO Item VALUES(12,9,25,22,1.5);
+INSERT INTO Item VALUES(12,8,48,2,1.5);
+INSERT INTO Item VALUES(12,7,48,7,1.5);
+INSERT INTO Item VALUES(12,6,31,15,1.5);
+INSERT INTO Item VALUES(12,5,37,17,1.5);
+INSERT INTO Item VALUES(12,4,20,11,1.5);
+INSERT INTO Item VALUES(12,3,0,18,1.5);
+INSERT INTO Item VALUES(12,2,6,5,1.5);
+INSERT INTO Item VALUES(12,1,41,19,1.5);
+INSERT INTO Item VALUES(12,0,1,24,1.5);
+INSERT INTO Item VALUES(13,21,40,1,1.5);
+INSERT INTO Item VALUES(13,20,5,19,1.5);
+INSERT INTO Item VALUES(13,19,42,18,1.5);
+INSERT INTO Item VALUES(13,18,0,16,1.5);
+INSERT INTO Item VALUES(13,17,32,18,1.5);
+INSERT INTO Item VALUES(13,16,22,23,1.5);
+INSERT INTO Item VALUES(13,15,0,20,1.5);
+INSERT INTO Item VALUES(13,14,1,12,1.5);
+INSERT INTO Item VALUES(13,13,10,20,1.5);
+INSERT INTO Item VALUES(13,12,17,3,1.5);
+INSERT INTO Item VALUES(13,11,14,3,1.5);
+INSERT INTO Item VALUES(13,10,45,24,1.5);
+INSERT INTO Item VALUES(13,9,24,10,1.5);
+INSERT INTO Item VALUES(13,8,48,11,1.5);
+INSERT INTO Item VALUES(13,7,29,24,1.5);
+INSERT INTO Item VALUES(13,6,19,8,1.5);
+INSERT INTO Item VALUES(13,5,22,19,1.5);
+INSERT INTO Item VALUES(13,4,26,21,1.5);
+INSERT INTO Item VALUES(13,3,32,2,1.5);
+INSERT INTO Item VALUES(13,2,13,20,1.5);
+INSERT INTO Item VALUES(13,1,1,1,1.5);
+INSERT INTO Item VALUES(13,0,16,10,1.5);
+INSERT INTO Item VALUES(14,13,11,23,1.5);
+INSERT INTO Item VALUES(14,12,4,20,1.5);
+INSERT INTO Item VALUES(14,11,25,15,1.5);
+INSERT INTO Item VALUES(14,10,44,16,1.5);
+INSERT INTO Item VALUES(14,9,13,16,1.5);
+INSERT INTO Item VALUES(14,8,23,7,1.5);
+INSERT INTO Item VALUES(14,7,43,4,1.5);
+INSERT INTO Item VALUES(14,6,26,18,1.5);
+INSERT INTO Item VALUES(14,5,11,8,1.5);
+INSERT INTO Item VALUES(14,4,41,17,1.5);
+INSERT INTO Item VALUES(14,3,34,11,1.5);
+INSERT INTO Item VALUES(14,2,15,18,1.5);
+INSERT INTO Item VALUES(14,1,9,22,1.5);
+INSERT INTO Item VALUES(14,0,42,18,1.5);
+INSERT INTO Item VALUES(15,2,24,6,1.5);
+INSERT INTO Item VALUES(15,1,13,21,1.5);
+INSERT INTO Item VALUES(15,0,17,12,1.5);
+INSERT INTO Item VALUES(16,15,12,3,1.5);
+INSERT INTO Item VALUES(16,14,0,19,1.5);
+INSERT INTO Item VALUES(16,13,20,1,1.5);
+INSERT INTO Item VALUES(16,12,18,2,1.5);
+INSERT INTO Item VALUES(16,11,24,7,1.5);
+INSERT INTO Item VALUES(16,10,43,8,1.5);
+INSERT INTO Item VALUES(16,9,11,10,1.5);
+INSERT INTO Item VALUES(16,8,13,17,1.5);
+INSERT INTO Item VALUES(16,7,8,17,1.5);
+INSERT INTO Item VALUES(16,6,44,7,1.5);
+INSERT INTO Item VALUES(16,5,11,15,1.5);
+INSERT INTO Item VALUES(16,4,10,24,1.5);
+INSERT INTO Item VALUES(16,3,0,3,1.5);
+INSERT INTO Item VALUES(16,2,20,15,1.5);
+INSERT INTO Item VALUES(16,1,36,20,1.5);
+INSERT INTO Item VALUES(16,0,18,15,1.5);
+INSERT INTO Item VALUES(17,19,46,12,1.5);
+INSERT INTO Item VALUES(17,18,5,9,1.5);
+INSERT INTO Item VALUES(17,17,7,5,1.5);
+INSERT INTO Item VALUES(17,16,8,16,1.5);
+INSERT INTO Item VALUES(17,15,35,10,1.5);
+INSERT INTO Item VALUES(17,14,18,2,1.5);
+INSERT INTO Item VALUES(17,13,41,5,1.5);
+INSERT INTO Item VALUES(17,12,22,16,1.5);
+INSERT INTO Item VALUES(17,11,45,10,1.5);
+INSERT INTO Item VALUES(17,10,10,12,1.5);
+INSERT INTO Item VALUES(17,9,8,15,1.5);
+INSERT INTO Item VALUES(17,8,49,8,1.5);
+INSERT INTO Item VALUES(17,7,6,15,1.5);
+INSERT INTO Item VALUES(17,6,43,6,1.5);
+INSERT INTO Item VALUES(17,5,44,1,1.5);
+INSERT INTO Item VALUES(17,4,23,2,1.5);
+INSERT INTO Item VALUES(17,3,24,4,1.5);
+INSERT INTO Item VALUES(17,2,44,11,1.5);
+INSERT INTO Item VALUES(17,1,19,19,1.5);
+INSERT INTO Item VALUES(17,0,16,8,1.5);
+INSERT INTO Item VALUES(18,18,10,1,1.5);
+INSERT INTO Item VALUES(18,17,8,1,1.5);
+INSERT INTO Item VALUES(18,16,31,12,1.5);
+INSERT INTO Item VALUES(18,15,44,20,1.5);
+INSERT INTO Item VALUES(18,14,28,20,1.5);
+INSERT INTO Item VALUES(18,13,14,12,1.5);
+INSERT INTO Item VALUES(18,12,37,12,1.5);
+INSERT INTO Item VALUES(18,11,30,8,1.5);
+INSERT INTO Item VALUES(18,10,34,18,1.5);
+INSERT INTO Item VALUES(18,9,2,2,1.5);
+INSERT INTO Item VALUES(18,8,1,24,1.5);
+INSERT INTO Item VALUES(18,7,15,14,1.5);
+INSERT INTO Item VALUES(18,6,29,4,1.5);
+INSERT INTO Item VALUES(18,5,15,6,1.5);
+INSERT INTO Item VALUES(18,4,28,6,1.5);
+INSERT INTO Item VALUES(18,3,19,8,1.5);
+INSERT INTO Item VALUES(18,2,40,12,1.5);
+INSERT INTO Item VALUES(18,1,33,12,1.5);
+INSERT INTO Item VALUES(18,0,32,1,1.5);
+INSERT INTO Item VALUES(19,4,36,24,1.5);
+INSERT INTO Item VALUES(19,3,49,23,1.5);
+INSERT INTO Item VALUES(19,2,4,22,1.5);
+INSERT INTO Item VALUES(19,1,31,2,1.5);
+INSERT INTO Item VALUES(19,0,12,7,1.5);
+INSERT INTO Item VALUES(20,11,15,8,1.5);
+INSERT INTO Item VALUES(20,10,25,11,1.5);
+INSERT INTO Item VALUES(20,9,12,8,1.5);
+INSERT INTO Item VALUES(20,8,44,18,1.5);
+INSERT INTO Item VALUES(20,7,9,9,1.5);
+INSERT INTO Item VALUES(20,6,20,2,1.5);
+INSERT INTO Item VALUES(20,5,8,14,1.5);
+INSERT INTO Item VALUES(20,4,30,13,1.5);
+INSERT INTO Item VALUES(20,3,25,14,1.5);
+INSERT INTO Item VALUES(20,2,24,22,1.5);
+INSERT INTO Item VALUES(20,1,29,6,1.5);
+INSERT INTO Item VALUES(20,0,47,15,1.5);
+INSERT INTO Item VALUES(21,11,20,11,1.5);
+INSERT INTO Item VALUES(21,10,19,14,1.5);
+INSERT INTO Item VALUES(21,9,35,17,1.5);
+INSERT INTO Item VALUES(21,8,44,19,1.5);
+INSERT INTO Item VALUES(21,7,8,9,1.5);
+INSERT INTO Item VALUES(21,6,26,7,1.5);
+INSERT INTO Item VALUES(21,5,27,18,1.5);
+INSERT INTO Item VALUES(21,4,49,22,1.5);
+INSERT INTO Item VALUES(21,3,30,13,1.5);
+INSERT INTO Item VALUES(21,2,31,17,1.5);
+INSERT INTO Item VALUES(21,1,38,19,1.5);
+INSERT INTO Item VALUES(21,0,9,10,1.5);
+INSERT INTO Item VALUES(22,9,23,1,1.5);
+INSERT INTO Item VALUES(22,8,3,2,1.5);
+INSERT INTO Item VALUES(22,7,21,6,1.5);
+INSERT INTO Item VALUES(22,6,4,11,1.5);
+INSERT INTO Item VALUES(22,5,24,5,1.5);
+INSERT INTO Item VALUES(22,4,5,21,1.5);
+INSERT INTO Item VALUES(22,3,22,5,1.5);
+INSERT INTO Item VALUES(22,2,12,20,1.5);
+INSERT INTO Item VALUES(22,1,30,11,1.5);
+INSERT INTO Item VALUES(22,0,9,6,1.5);
+INSERT INTO Item VALUES(23,16,8,11,1.5);
+INSERT INTO Item VALUES(23,15,13,17,1.5);
+INSERT INTO Item VALUES(23,14,44,2,1.5);
+INSERT INTO Item VALUES(23,13,14,17,1.5);
+INSERT INTO Item VALUES(23,12,4,17,1.5);
+INSERT INTO Item VALUES(23,11,41,8,1.5);
+INSERT INTO Item VALUES(23,10,4,18,1.5);
+INSERT INTO Item VALUES(23,9,20,18,1.5);
+INSERT INTO Item VALUES(23,8,6,17,1.5);
+INSERT INTO Item VALUES(23,7,39,3,1.5);
+INSERT INTO Item VALUES(23,6,16,1,1.5);
+INSERT INTO Item VALUES(23,5,32,14,1.5);
+INSERT INTO Item VALUES(23,4,23,19,1.5);
+INSERT INTO Item VALUES(23,3,40,19,1.5);
+INSERT INTO Item VALUES(23,2,33,18,1.5);
+INSERT INTO Item VALUES(23,1,26,8,1.5);
+INSERT INTO Item VALUES(23,0,48,22,1.5);
+INSERT INTO Item VALUES(24,15,39,17,1.5);
+INSERT INTO Item VALUES(24,14,1,13,1.5);
+INSERT INTO Item VALUES(24,13,15,21,1.5);
+INSERT INTO Item VALUES(24,12,0,8,1.5);
+INSERT INTO Item VALUES(24,11,1,4,1.5);
+INSERT INTO Item VALUES(24,10,27,4,1.5);
+INSERT INTO Item VALUES(24,9,21,8,1.5);
+INSERT INTO Item VALUES(24,8,5,18,1.5);
+INSERT INTO Item VALUES(24,7,7,13,1.5);
+INSERT INTO Item VALUES(24,6,40,3,1.5);
+INSERT INTO Item VALUES(24,5,35,16,1.5);
+INSERT INTO Item VALUES(24,4,15,17,1.5);
+INSERT INTO Item VALUES(24,3,17,23,1.5);
+INSERT INTO Item VALUES(24,2,38,10,1.5);
+INSERT INTO Item VALUES(24,1,46,18,1.5);
+INSERT INTO Item VALUES(24,0,43,14,1.5);
+INSERT INTO Item VALUES(25,8,38,3,1.5);
+INSERT INTO Item VALUES(25,7,16,8,1.5);
+INSERT INTO Item VALUES(25,6,21,18,1.5);
+INSERT INTO Item VALUES(25,5,10,5,1.5);
+INSERT INTO Item VALUES(25,4,47,10,1.5);
+INSERT INTO Item VALUES(25,3,19,4,1.5);
+INSERT INTO Item VALUES(25,2,13,8,1.5);
+INSERT INTO Item VALUES(25,1,43,13,1.5);
+INSERT INTO Item VALUES(25,0,5,15,1.5);
+INSERT INTO Item VALUES(26,16,30,4,1.5);
+INSERT INTO Item VALUES(26,15,8,6,1.5);
+INSERT INTO Item VALUES(26,14,26,6,1.5);
+INSERT INTO Item VALUES(26,13,13,10,1.5);
+INSERT INTO Item VALUES(26,12,27,20,1.5);
+INSERT INTO Item VALUES(26,11,18,3,1.5);
+INSERT INTO Item VALUES(26,10,34,16,1.5);
+INSERT INTO Item VALUES(26,9,1,23,1.5);
+INSERT INTO Item VALUES(26,8,40,13,1.5);
+INSERT INTO Item VALUES(26,7,4,16,1.5);
+INSERT INTO Item VALUES(26,6,7,23,1.5);
+INSERT INTO Item VALUES(26,5,38,4,1.5);
+INSERT INTO Item VALUES(26,4,46,7,1.5);
+INSERT INTO Item VALUES(26,3,16,3,1.5);
+INSERT INTO Item VALUES(26,2,33,7,1.5);
+INSERT INTO Item VALUES(26,1,43,21,1.5);
+INSERT INTO Item VALUES(26,0,42,16,1.5);
+INSERT INTO Item VALUES(27,2,19,1,1.5);
+INSERT INTO Item VALUES(27,1,45,15,1.5);
+INSERT INTO Item VALUES(27,0,24,15,1.5);
+INSERT INTO Item VALUES(28,8,28,6,1.5);
+INSERT INTO Item VALUES(28,7,28,8,1.5);
+INSERT INTO Item VALUES(28,6,33,16,1.5);
+INSERT INTO Item VALUES(28,5,49,4,1.5);
+INSERT INTO Item VALUES(28,4,45,17,1.5);
+INSERT INTO Item VALUES(28,3,6,3,1.5);
+INSERT INTO Item VALUES(28,2,44,22,1.5);
+INSERT INTO Item VALUES(28,1,15,13,1.5);
+INSERT INTO Item VALUES(28,0,35,13,1.5);
+INSERT INTO Item VALUES(29,8,35,6,1.5);
+INSERT INTO Item VALUES(29,7,5,1,1.5);
+INSERT INTO Item VALUES(29,6,4,16,1.5);
+INSERT INTO Item VALUES(29,5,31,13,1.5);
+INSERT INTO Item VALUES(29,4,4,7,1.5);
+INSERT INTO Item VALUES(29,3,7,21,1.5);
+INSERT INTO Item VALUES(29,2,17,23,1.5);
+INSERT INTO Item VALUES(29,1,38,12,1.5);
+INSERT INTO Item VALUES(29,0,33,17,1.5);
+INSERT INTO Item VALUES(30,6,14,23,1.5);
+INSERT INTO Item VALUES(30,5,43,23,1.5);
+INSERT INTO Item VALUES(30,4,34,2,1.5);
+INSERT INTO Item VALUES(30,3,33,2,1.5);
+INSERT INTO Item VALUES(30,2,10,18,1.5);
+INSERT INTO Item VALUES(30,1,16,19,1.5);
+INSERT INTO Item VALUES(30,0,14,7,1.5);
+INSERT INTO Item VALUES(31,10,0,3,1.5);
+INSERT INTO Item VALUES(31,9,14,15,1.5);
+INSERT INTO Item VALUES(31,8,7,5,1.5);
+INSERT INTO Item VALUES(31,7,38,3,1.5);
+INSERT INTO Item VALUES(31,6,26,16,1.5);
+INSERT INTO Item VALUES(31,5,1,4,1.5);
+INSERT INTO Item VALUES(31,4,8,14,1.5);
+INSERT INTO Item VALUES(31,3,12,10,1.5);
+INSERT INTO Item VALUES(31,2,4,3,1.5);
+INSERT INTO Item VALUES(31,1,4,23,1.5);
+INSERT INTO Item VALUES(31,0,33,10,1.5);
+INSERT INTO Item VALUES(32,2,1,14,1.5);
+INSERT INTO Item VALUES(32,1,30,13,1.5);
+INSERT INTO Item VALUES(32,0,35,11,1.5);
+INSERT INTO Item VALUES(33,15,38,7,1.5);
+INSERT INTO Item VALUES(33,14,44,13,1.5);
+INSERT INTO Item VALUES(33,13,25,16,1.5);
+INSERT INTO Item VALUES(33,12,16,23,1.5);
+INSERT INTO Item VALUES(33,11,5,7,1.5);
+INSERT INTO Item VALUES(33,10,24,9,1.5);
+INSERT INTO Item VALUES(33,9,29,5,1.5);
+INSERT INTO Item VALUES(33,8,3,15,1.5);
+INSERT INTO Item VALUES(33,7,43,10,1.5);
+INSERT INTO Item VALUES(33,6,17,16,1.5);
+INSERT INTO Item VALUES(33,5,8,11,1.5);
+INSERT INTO Item VALUES(33,4,24,1,1.5);
+INSERT INTO Item VALUES(33,3,48,1,1.5);
+INSERT INTO Item VALUES(33,2,36,16,1.5);
+INSERT INTO Item VALUES(33,1,10,21,1.5);
+INSERT INTO Item VALUES(33,0,36,5,1.5);
+INSERT INTO Item VALUES(34,14,46,7,1.5);
+INSERT INTO Item VALUES(34,13,30,14,1.5);
+INSERT INTO Item VALUES(34,12,43,21,1.5);
+INSERT INTO Item VALUES(34,11,4,17,1.5);
+INSERT INTO Item VALUES(34,10,41,16,1.5);
+INSERT INTO Item VALUES(34,9,8,17,1.5);
+INSERT INTO Item VALUES(34,8,3,1,1.5);
+INSERT INTO Item VALUES(34,7,21,22,1.5);
+INSERT INTO Item VALUES(34,6,32,7,1.5);
+INSERT INTO Item VALUES(34,5,45,13,1.5);
+INSERT INTO Item VALUES(34,4,27,1,1.5);
+INSERT INTO Item VALUES(34,3,44,15,1.5);
+INSERT INTO Item VALUES(34,2,28,22,1.5);
+INSERT INTO Item VALUES(34,1,4,3,1.5);
+INSERT INTO Item VALUES(34,0,10,22,1.5);
+INSERT INTO Item VALUES(35,13,19,17,1.5);
+INSERT INTO Item VALUES(35,12,7,23,1.5);
+INSERT INTO Item VALUES(35,11,44,9,1.5);
+INSERT INTO Item VALUES(35,10,17,11,1.5);
+INSERT INTO Item VALUES(35,9,19,1,1.5);
+INSERT INTO Item VALUES(35,8,0,1,1.5);
+INSERT INTO Item VALUES(35,7,22,15,1.5);
+INSERT INTO Item VALUES(35,6,5,4,1.5);
+INSERT INTO Item VALUES(35,5,33,5,1.5);
+INSERT INTO Item VALUES(35,4,14,17,1.5);
+INSERT INTO Item VALUES(35,3,27,10,1.5);
+INSERT INTO Item VALUES(35,2,14,4,1.5);
+INSERT INTO Item VALUES(35,1,3,9,1.5);
+INSERT INTO Item VALUES(35,0,20,17,1.5);
+INSERT INTO Item VALUES(36,11,44,9,1.5);
+INSERT INTO Item VALUES(36,10,47,11,1.5);
+INSERT INTO Item VALUES(36,9,31,18,1.5);
+INSERT INTO Item VALUES(36,8,4,21,1.5);
+INSERT INTO Item VALUES(36,7,39,19,1.5);
+INSERT INTO Item VALUES(36,6,39,20,1.5);
+INSERT INTO Item VALUES(36,5,25,8,1.5);
+INSERT INTO Item VALUES(36,4,40,5,1.5);
+INSERT INTO Item VALUES(36,3,10,8,1.5);
+INSERT INTO Item VALUES(36,2,1,6,1.5);
+INSERT INTO Item VALUES(36,1,15,23,1.5);
+INSERT INTO Item VALUES(36,0,18,13,1.5);
+INSERT INTO Item VALUES(37,21,6,9,1.5);
+INSERT INTO Item VALUES(37,20,14,1,1.5);
+INSERT INTO Item VALUES(37,19,19,20,1.5);
+INSERT INTO Item VALUES(37,18,26,22,1.5);
+INSERT INTO Item VALUES(37,17,38,18,1.5);
+INSERT INTO Item VALUES(37,16,27,8,1.5);
+INSERT INTO Item VALUES(37,15,32,12,1.5);
+INSERT INTO Item VALUES(37,14,12,3,1.5);
+INSERT INTO Item VALUES(37,13,32,3,1.5);
+INSERT INTO Item VALUES(37,12,24,23,1.5);
+INSERT INTO Item VALUES(37,11,30,5,1.5);
+INSERT INTO Item VALUES(37,10,1,18,1.5);
+INSERT INTO Item VALUES(37,9,47,16,1.5);
+INSERT INTO Item VALUES(37,8,46,9,1.5);
+INSERT INTO Item VALUES(37,7,24,19,1.5);
+INSERT INTO Item VALUES(37,6,34,12,1.5);
+INSERT INTO Item VALUES(37,5,1,14,1.5);
+INSERT INTO Item VALUES(37,4,13,20,1.5);
+INSERT INTO Item VALUES(37,3,26,7,1.5);
+INSERT INTO Item VALUES(37,2,36,8,1.5);
+INSERT INTO Item VALUES(37,1,15,20,1.5);
+INSERT INTO Item VALUES(37,0,41,24,1.5);
+INSERT INTO Item VALUES(38,19,4,7,1.5);
+INSERT INTO Item VALUES(38,18,28,20,1.5);
+INSERT INTO Item VALUES(38,17,32,4,1.5);
+INSERT INTO Item VALUES(38,16,40,18,1.5);
+INSERT INTO Item VALUES(38,15,47,10,1.5);
+INSERT INTO Item VALUES(38,14,20,7,1.5);
+INSERT INTO Item VALUES(38,13,8,7,1.5);
+INSERT INTO Item VALUES(38,12,1,18,1.5);
+INSERT INTO Item VALUES(38,11,19,18,1.5);
+INSERT INTO Item VALUES(38,10,4,18,1.5);
+INSERT INTO Item VALUES(38,9,27,20,1.5);
+INSERT INTO Item VALUES(38,8,40,10,1.5);
+INSERT INTO Item VALUES(38,7,15,1,1.5);
+INSERT INTO Item VALUES(38,6,5,19,1.5);
+INSERT INTO Item VALUES(38,5,48,17,1.5);
+INSERT INTO Item VALUES(38,4,45,14,1.5);
+INSERT INTO Item VALUES(38,3,27,19,1.5);
+INSERT INTO Item VALUES(38,2,4,8,1.5);
+INSERT INTO Item VALUES(38,1,45,13,1.5);
+INSERT INTO Item VALUES(38,0,48,14,1.5);
+INSERT INTO Item VALUES(39,3,20,17,1.5);
+INSERT INTO Item VALUES(39,2,39,16,1.5);
+INSERT INTO Item VALUES(39,1,24,6,1.5);
+INSERT INTO Item VALUES(39,0,10,12,1.5);
+INSERT INTO Item VALUES(40,20,4,16,1.5);
+INSERT INTO Item VALUES(40,19,7,23,1.5);
+INSERT INTO Item VALUES(40,18,33,11,1.5);
+INSERT INTO Item VALUES(40,17,4,20,1.5);
+INSERT INTO Item VALUES(40,16,27,16,1.5);
+INSERT INTO Item VALUES(40,15,22,12,1.5);
+INSERT INTO Item VALUES(40,14,4,24,1.5);
+INSERT INTO Item VALUES(40,13,6,8,1.5);
+INSERT INTO Item VALUES(40,12,35,13,1.5);
+INSERT INTO Item VALUES(40,11,27,2,1.5);
+INSERT INTO Item VALUES(40,10,6,11,1.5);
+INSERT INTO Item VALUES(40,9,40,17,1.5);
+INSERT INTO Item VALUES(40,8,11,4,1.5);
+INSERT INTO Item VALUES(40,7,31,1,1.5);
+INSERT INTO Item VALUES(40,6,28,12,1.5);
+INSERT INTO Item VALUES(40,5,32,18,1.5);
+INSERT INTO Item VALUES(40,4,18,13,1.5);
+INSERT INTO Item VALUES(40,3,26,10,1.5);
+INSERT INTO Item VALUES(40,2,4,5,1.5);
+INSERT INTO Item VALUES(40,1,45,24,1.5);
+INSERT INTO Item VALUES(40,0,46,24,1.5);
+INSERT INTO Item VALUES(41,11,48,15,1.5);
+INSERT INTO Item VALUES(41,10,24,20,1.5);
+INSERT INTO Item VALUES(41,9,26,21,1.5);
+INSERT INTO Item VALUES(41,8,9,22,1.5);
+INSERT INTO Item VALUES(41,7,22,18,1.5);
+INSERT INTO Item VALUES(41,6,17,11,1.5);
+INSERT INTO Item VALUES(41,5,9,21,1.5);
+INSERT INTO Item VALUES(41,4,16,22,1.5);
+INSERT INTO Item VALUES(41,3,29,20,1.5);
+INSERT INTO Item VALUES(41,2,36,2,1.5);
+INSERT INTO Item VALUES(41,1,47,19,1.5);
+INSERT INTO Item VALUES(41,0,5,24,1.5);
+INSERT INTO Item VALUES(42,4,48,15,1.5);
+INSERT INTO Item VALUES(42,3,40,14,1.5);
+INSERT INTO Item VALUES(42,2,40,19,1.5);
+INSERT INTO Item VALUES(42,1,18,21,1.5);
+INSERT INTO Item VALUES(42,0,48,9,1.5);
+INSERT INTO Item VALUES(43,16,38,12,1.5);
+INSERT INTO Item VALUES(43,15,48,7,1.5);
+INSERT INTO Item VALUES(43,14,3,18,1.5);
+INSERT INTO Item VALUES(43,13,44,22,1.5);
+INSERT INTO Item VALUES(43,12,40,24,1.5);
+INSERT INTO Item VALUES(43,11,49,23,1.5);
+INSERT INTO Item VALUES(43,10,35,1,1.5);
+INSERT INTO Item VALUES(43,9,7,23,1.5);
+INSERT INTO Item VALUES(43,8,44,8,1.5);
+INSERT INTO Item VALUES(43,7,11,15,1.5);
+INSERT INTO Item VALUES(43,6,24,1,1.5);
+INSERT INTO Item VALUES(43,5,33,6,1.5);
+INSERT INTO Item VALUES(43,4,32,22,1.5);
+INSERT INTO Item VALUES(43,3,6,18,1.5);
+INSERT INTO Item VALUES(43,2,2,15,1.5);
+INSERT INTO Item VALUES(43,1,18,19,1.5);
+INSERT INTO Item VALUES(43,0,15,22,1.5);
+INSERT INTO Item VALUES(44,8,28,23,1.5);
+INSERT INTO Item VALUES(44,7,49,17,1.5);
+INSERT INTO Item VALUES(44,6,14,15,1.5);
+INSERT INTO Item VALUES(44,5,41,22,1.5);
+INSERT INTO Item VALUES(44,4,12,3,1.5);
+INSERT INTO Item VALUES(44,3,3,14,1.5);
+INSERT INTO Item VALUES(44,2,17,14,1.5);
+INSERT INTO Item VALUES(44,1,34,17,1.5);
+INSERT INTO Item VALUES(44,0,33,20,1.5);
+INSERT INTO Item VALUES(45,14,3,16,1.5);
+INSERT INTO Item VALUES(45,13,47,8,1.5);
+INSERT INTO Item VALUES(45,12,32,13,1.5);
+INSERT INTO Item VALUES(45,11,31,22,1.5);
+INSERT INTO Item VALUES(45,10,41,24,1.5);
+INSERT INTO Item VALUES(45,9,26,18,1.5);
+INSERT INTO Item VALUES(45,8,9,2,1.5);
+INSERT INTO Item VALUES(45,7,6,24,1.5);
+INSERT INTO Item VALUES(45,6,39,5,1.5);
+INSERT INTO Item VALUES(45,5,45,17,1.5);
+INSERT INTO Item VALUES(45,4,3,14,1.5);
+INSERT INTO Item VALUES(45,3,14,11,1.5);
+INSERT INTO Item VALUES(45,2,46,8,1.5);
+INSERT INTO Item VALUES(45,1,11,6,1.5);
+INSERT INTO Item VALUES(45,0,44,6,1.5);
+INSERT INTO Item VALUES(46,17,12,23,1.5);
+INSERT INTO Item VALUES(46,16,46,21,1.5);
+INSERT INTO Item VALUES(46,15,40,11,1.5);
+INSERT INTO Item VALUES(46,14,24,10,1.5);
+INSERT INTO Item VALUES(46,13,36,20,1.5);
+INSERT INTO Item VALUES(46,12,21,24,1.5);
+INSERT INTO Item VALUES(46,11,1,4,1.5);
+INSERT INTO Item VALUES(46,10,11,24,1.5);
+INSERT INTO Item VALUES(46,9,7,4,1.5);
+INSERT INTO Item VALUES(46,8,8,22,1.5);
+INSERT INTO Item VALUES(46,7,49,9,1.5);
+INSERT INTO Item VALUES(46,6,41,18,1.5);
+INSERT INTO Item VALUES(46,5,25,9,1.5);
+INSERT INTO Item VALUES(46,4,17,5,1.5);
+INSERT INTO Item VALUES(46,3,21,19,1.5);
+INSERT INTO Item VALUES(46,2,30,14,1.5);
+INSERT INTO Item VALUES(46,1,12,24,1.5);
+INSERT INTO Item VALUES(46,0,5,21,1.5);
+INSERT INTO Item VALUES(47,13,33,8,1.5);
+INSERT INTO Item VALUES(47,12,12,20,1.5);
+INSERT INTO Item VALUES(47,11,35,10,1.5);
+INSERT INTO Item VALUES(47,10,45,2,1.5);
+INSERT INTO Item VALUES(47,9,32,9,1.5);
+INSERT INTO Item VALUES(47,8,16,2,1.5);
+INSERT INTO Item VALUES(47,7,28,14,1.5);
+INSERT INTO Item VALUES(47,6,8,10,1.5);
+INSERT INTO Item VALUES(47,5,40,8,1.5);
+INSERT INTO Item VALUES(47,4,15,1,1.5);
+INSERT INTO Item VALUES(47,3,1,4,1.5);
+INSERT INTO Item VALUES(47,2,17,6,1.5);
+INSERT INTO Item VALUES(47,1,23,13,1.5);
+INSERT INTO Item VALUES(47,0,23,15,1.5);
+INSERT INTO Item VALUES(48,10,41,10,1.5);
+INSERT INTO Item VALUES(48,9,35,17,1.5);
+INSERT INTO Item VALUES(48,8,5,12,1.5);
+INSERT INTO Item VALUES(48,7,30,19,1.5);
+INSERT INTO Item VALUES(48,6,11,17,1.5);
+INSERT INTO Item VALUES(48,5,24,16,1.5);
+INSERT INTO Item VALUES(48,4,48,4,1.5);
+INSERT INTO Item VALUES(48,3,10,2,1.5);
+INSERT INTO Item VALUES(48,2,23,10,1.5);
+INSERT INTO Item VALUES(48,1,26,23,1.5);
+INSERT INTO Item VALUES(48,0,6,23,1.5);
+INSERT INTO Item VALUES(49,16,24,18,1.5);
+INSERT INTO Item VALUES(49,15,19,24,1.5);
+INSERT INTO Item VALUES(49,14,23,5,1.5);
+INSERT INTO Item VALUES(49,13,6,22,1.5);
+INSERT INTO Item VALUES(49,12,21,17,1.5);
+INSERT INTO Item VALUES(49,11,40,15,1.5);
+INSERT INTO Item VALUES(49,10,30,16,1.5);
+INSERT INTO Item VALUES(49,9,7,24,1.5);
+INSERT INTO Item VALUES(49,8,48,24,1.5);
+INSERT INTO Item VALUES(49,7,6,21,1.5);
+INSERT INTO Item VALUES(49,6,29,15,1.5);
+INSERT INTO Item VALUES(49,5,16,1,1.5);
+INSERT INTO Item VALUES(49,4,47,14,1.5);
+INSERT INTO Item VALUES(49,3,17,19,1.5);
+INSERT INTO Item VALUES(49,2,29,6,1.5);
+INSERT INTO Item VALUES(49,1,22,16,1.5);
+INSERT INTO Item VALUES(49,0,18,6,1.5);
+UPDATE Product SET Price=ROUND(Price*.1,2);
+UPDATE Item SET Cost=Cost*(SELECT Price FROM Product prod WHERE ProductID=prod.ID);
+UPDATE Invoice SET Total=SELECT SUM(Cost*Quantity) FROM Item WHERE InvoiceID=Invoice.ID;
+
+COMMIT;
diff --git a/sample/server.properties b/sample/server.properties
new file mode 100644
index 0000000..8726b34
--- /dev/null
+++ b/sample/server.properties
@@ -0,0 +1,20 @@
+# Hsqldb Server cfg file.
+# See the HyperSQL Network Listeners chapter of the HyperSQL User Guide.
+
+# Each server.database.X setting defines a database "catalog".
+# I.e., an independent set of data.
+# Each server.database.X setting corresponds exactly to the jdbc:hsqldb:*
+# JDBC URL you would use if you wanted to get a direct (In-Process)
+# Connection to the catalog instead of "serving" it.
+
+server.database.0=file:db0/db0
+# I suggest that, for every file: catalog you define, you add the
+# connection property "ifexists=true" after the database instance
+# is created (which happens simply by starting the Server one time).
+# Just append ";ifexists=true" to the file: URL, like so:
+# server.database.0=file:db0/db0;ifexists=true
+
+# server.dbname.0 defaults to "" (i.e. server.dbname.n for n==0), but
+# the catalog definition n will be entirely ignored for n > 0 if you do not
+# set server.dbname.n.  I.e. dbname setting is required for n > 0, though it
+# may be set to blank (e.g. "server.dbname.3=")
diff --git a/sample/sqltool.rc b/sample/sqltool.rc
new file mode 100644
index 0000000..a8f7f50
--- /dev/null
+++ b/sample/sqltool.rc
@@ -0,0 +1,141 @@
+# $Id: sqltool.rc 3348 2009-12-15 14:24:19Z unsaved $
+
+# This is a sample RC configuration file used by SqlTool, DatabaseManager,
+# and any other program that uses the org.hsqldb.lib.RCData class.
+# See the documentation for SqlTool for various ways to use this file.
+
+# If you have the least concerns about security, then secure access to
+# your RC file.
+
+# You can run SqlTool right now by copying this file to your home directory
+# and running
+#    java -jar /path/to/sqltool.jar mem
+# This will access the first urlid definition below in order to use a 
+# personal Memory-Only database.
+# "url" values may, of course, contain JDBC connection properties, delimited
+# with semicolons.
+# As of revision 3347 of SqlFile, you can also connect to datasources defined
+# here from within an SqlTool session/file with the command "\j urlid".
+
+# You can use Java system property values in this file like this:  ${user.home}
+
+# The only feature added recently is the optional "transiso" setting,
+# which may be set to an all-caps transaction isolation level as listed
+# in the Java API Spec for java.sql.Connection.
+# Windows users are advised to use forward slashes instead of reverse slashes,
+# and to avoid paths containing spaces or other funny characters.  (This
+# recommendation applies to any Java app, not just SqlTool).
+
+# A personal Memory-Only (non-persistent) database.
+urlid mem
+url jdbc:hsqldb:mem:memdbid
+username SA
+password
+
+# A personal, local, persistent database.
+urlid personal
+url jdbc:hsqldb:file:${user.home}/db/personal;shutdown=true
+username SA
+password
+transiso TRANSACTION_READ_COMMITTED
+# When connecting directly to a file database like this, you should 
+# use the shutdown connection property like this to shut down the DB
+# properly when you exit the JVM.
+
+# This is for a hsqldb Server running with default settings on your local
+# computer (and for which you have not changed the password for "SA").
+urlid localhost-sa
+url jdbc:hsqldb:hsql://localhost
+username SA
+password
+
+
+
+# Template for a urlid for an Oracle database.
+# You will need to put the oracle.jdbc.OracleDriver class into your 
+# classpath.
+# In the great majority of cases, you want to use the file classes12.zip
+# (which you can get from the directory $ORACLE_HOME/jdbc/lib of any
+# Oracle installation compatible with your server).
+# Since you need to add to the classpath, you can't invoke SqlTool with
+# the jar switch, like "java -jar .../hsqldb.jar..." or 
+# "java -jar .../hsqlsqltool.jar...".
+# Put both the HSQLDB jar and classes12.zip in your classpath (and export!)
+# and run something like "java org.hsqldb.util.SqlTool...".
+
+#urlid cardiff2
+#url jdbc:oracle:thin:@aegir.admc.com:1522:TRAFFIC_SID
+#username blaine
+#password secretpassword
+#driver oracle.jdbc.OracleDriver
+
+
+
+# Template for a TLS-encrypted HSQLDB Server.
+# Remember that the hostname in hsqls (and https) JDBC URLs must match the
+# CN of the server certificate (the port and instance alias that follows 
+# are not part of the certificate at all).
+# You only need to set "truststore" if the server cert is not approved by
+# your system default truststore (which a commercial certificate probably
+# would be).
+
+#urlid tls
+#url jdbc:hsqldb:hsqls://db.admc.com:9001/lm2
+#username BLAINE
+#password asecret
+#truststore ${user.home}/ca/db/db-trust.store
+
+
+# Template for a Postgresql database
+#urlid blainedb
+#url jdbc:postgresql://idun.africawork.org/blainedb
+#username blaine
+#password losung1
+#driver org.postgresql.Driver
+
+# Template for a MySQL database.  MySQL has poor JDBC support.
+#urlid mysql-testdb
+#url jdbc:mysql://hostname:3306/dbname
+#username root
+#password hiddenpwd
+#driver com.mysql.jdbc.Driver
+
+# Note that "databases" in SQL Server and Sybase are traditionally used for
+# the same purpose as "schemas" with more SQL-compliant databases.
+
+# Template for a Microsoft SQL Server database
+#urlid msprojsvr
+#url jdbc:microsoft:sqlserver://hostname;DatabaseName=DbName;SelectMethod=Cursor
+# The SelectMethod setting is required to do more than one thing on a JDBC
+# session (I guess Microsoft thought nobody would really use Java for 
+# anything other than a "hello world" program).
+# This is for Microsoft's SQL Server 2000 driver (requires mssqlserver.jar
+# and msutil.jar).
+#driver com.microsoft.jdbc.sqlserver.SQLServerDriver
+#username myuser
+#password hiddenpwd
+
+# Template for a Sybase database
+#urlid sybase
+#url jdbc:sybase:Tds:hostname:4100/dbname
+#username blaine
+#password hiddenpwd
+# This is for the jConnect driver (requires jconn3.jar).
+#driver com.sybase.jdbc3.jdbc.SybDriver
+
+# Template for Embedded Derby / Java DB.
+#urlid derby1
+#url jdbc:derby:path/to/derby/directory;create=true
+#username ${user.name}
+#password any_noauthbydefault
+#driver org.apache.derby.jdbc.EmbeddedDriver
+# The embedded Derby driver requires derby.jar.
+# There'a also the org.apache.derby.jdbc.ClientDriver driver with URL
+# like jdbc:derby://<server>[:<port>]/databaseName, which requires
+# derbyclient.jar.
+# You can use \= to commit, since the Derby team decided (why???)
+# not to implement the SQL standard statement "commit"!!
+# Note that SqlTool can not shut down an embedded Derby database properly,
+# since that requires an additional SQL connection just for that purpose.
+# However, I've never lost data by not shutting it down properly.
+# Other than not supporting this quirk of Derby, SqlTool is miles ahead of ij.
diff --git a/src/org/hibernate/dialect/HSQLDialect.java b/src/org/hibernate/dialect/HSQLDialect.java
new file mode 100644
index 0000000..a646914
--- /dev/null
+++ b/src/org/hibernate/dialect/HSQLDialect.java
@@ -0,0 +1,374 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.dialect;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.io.Serializable;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.JDBCException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.dialect.lock.*;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An SQL dialect compatible with HSQLDB (HyperSQL).
+ * <p/>
+ * Note this version supports HSQLDB version 1.8 and higher, only.
+ * <p/>
+ * Enhancements to version 3.5.0 GA to provide basic support for both HSQLDB 1.8.x and 2.0
+ * Should work with Hibernate 3.2 and later
+ *
+ * @author Christoph Sturm
+ * @author Phillip Baird
+ */
+public class HSQLDialect extends Dialect {
+
+        private static final Logger log = LoggerFactory.getLogger( HSQLDialect.class );
+
+        public HSQLDialect() {
+                super();
+                registerColumnType( Types.BIGINT, "bigint" );
+                registerColumnType( Types.BINARY, "binary" );
+                registerColumnType( Types.BIT, "bit" );
+                registerColumnType( Types.CHAR, "char(1)" );
+                registerColumnType( Types.DATE, "date" );
+                registerColumnType( Types.DECIMAL, "decimal($p,$s)" );
+                registerColumnType( Types.DOUBLE, "double" );
+                registerColumnType( Types.FLOAT, "float" );
+                registerColumnType( Types.INTEGER, "integer" );
+                registerColumnType( Types.LONGVARBINARY, "longvarbinary" );
+                registerColumnType( Types.LONGVARCHAR, "longvarchar" );
+                registerColumnType( Types.SMALLINT, "smallint" );
+                registerColumnType( Types.TINYINT, "tinyint" );
+                registerColumnType( Types.TIME, "time" );
+                registerColumnType( Types.TIMESTAMP, "timestamp" );
+                registerColumnType( Types.VARCHAR, "varchar($l)" );
+                registerColumnType( Types.VARBINARY, "varbinary($l)" );
+                registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+                //HSQL 1.8.x has no Blob/Clob support .... but just put these here for now!
+                registerColumnType( Types.BLOB, "longvarbinary" );
+                registerColumnType( Types.CLOB, "longvarchar" );
+                registerColumnType( Types.LONGVARBINARY, "longvarbinary" );
+                registerColumnType( Types.LONGVARCHAR, "longvarchar" );
+
+                registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.INTEGER ) );
+                registerFunction( "char", new StandardSQLFunction( "char", Hibernate.CHARACTER ) );
+                registerFunction( "lower", new StandardSQLFunction( "lower" ) );
+                registerFunction( "upper", new StandardSQLFunction( "upper" ) );
+                registerFunction( "lcase", new StandardSQLFunction( "lcase" ) );
+                registerFunction( "ucase", new StandardSQLFunction( "ucase" ) );
+                registerFunction( "soundex", new StandardSQLFunction( "soundex", Hibernate.STRING ) );
+                registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
+                registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
+                registerFunction( "reverse", new StandardSQLFunction( "reverse" ) );
+                registerFunction( "space", new StandardSQLFunction( "space", Hibernate.STRING ) );
+                registerFunction( "rawtohex", new StandardSQLFunction( "rawtohex" ) );
+                registerFunction( "hextoraw", new StandardSQLFunction( "hextoraw" ) );
+
+                registerFunction( "user", new NoArgSQLFunction( "user", Hibernate.STRING ) );
+                registerFunction( "database", new NoArgSQLFunction( "database", Hibernate.STRING ) );
+
+                registerFunction( "current_date", new NoArgSQLFunction( "current_date", Hibernate.DATE, false ) );
+                registerFunction( "curdate", new NoArgSQLFunction( "curdate", Hibernate.DATE ) );
+                registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", Hibernate.TIMESTAMP, false ) );
+                registerFunction( "now", new NoArgSQLFunction( "now", Hibernate.TIMESTAMP ) );
+                registerFunction( "current_time", new NoArgSQLFunction( "current_time", Hibernate.TIME, false ) );
+                registerFunction( "curtime", new NoArgSQLFunction( "curtime", Hibernate.TIME ) );
+                registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) );
+                registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", Hibernate.INTEGER ) );
+                registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", Hibernate.INTEGER ) );
+                registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", Hibernate.INTEGER ) );
+                registerFunction( "month", new StandardSQLFunction( "month", Hibernate.INTEGER ) );
+                registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) );
+                registerFunction( "week", new StandardSQLFunction( "week", Hibernate.INTEGER ) );
+                registerFunction( "quarter", new StandardSQLFunction( "quarter", Hibernate.INTEGER ) );
+                registerFunction( "hour", new StandardSQLFunction( "hour", Hibernate.INTEGER ) );
+                registerFunction( "minute", new StandardSQLFunction( "minute", Hibernate.INTEGER ) );
+                registerFunction( "second", new StandardSQLFunction( "second", Hibernate.INTEGER ) );
+                registerFunction( "dayname", new StandardSQLFunction( "dayname", Hibernate.STRING ) );
+                registerFunction( "monthname", new StandardSQLFunction( "monthname", Hibernate.STRING ) );
+
+                registerFunction( "abs", new StandardSQLFunction( "abs" ) );
+                registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) );
+
+                registerFunction( "acos", new StandardSQLFunction( "acos", Hibernate.DOUBLE ) );
+                registerFunction( "asin", new StandardSQLFunction( "asin", Hibernate.DOUBLE ) );
+                registerFunction( "atan", new StandardSQLFunction( "atan", Hibernate.DOUBLE ) );
+                registerFunction( "cos", new StandardSQLFunction( "cos", Hibernate.DOUBLE ) );
+                registerFunction( "cot", new StandardSQLFunction( "cot", Hibernate.DOUBLE ) );
+                registerFunction( "exp", new StandardSQLFunction( "exp", Hibernate.DOUBLE ) );
+                registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE ) );
+                registerFunction( "log10", new StandardSQLFunction( "log10", Hibernate.DOUBLE ) );
+                registerFunction( "sin", new StandardSQLFunction( "sin", Hibernate.DOUBLE ) );
+                registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE ) );
+                registerFunction( "tan", new StandardSQLFunction( "tan", Hibernate.DOUBLE ) );
+                registerFunction( "pi", new NoArgSQLFunction( "pi", Hibernate.DOUBLE ) );
+                registerFunction( "rand", new StandardSQLFunction( "rand", Hibernate.FLOAT ) );
+
+                registerFunction( "radians", new StandardSQLFunction( "radians", Hibernate.DOUBLE ) );
+                registerFunction( "degrees", new StandardSQLFunction( "degrees", Hibernate.DOUBLE ) );
+                registerFunction( "roundmagic", new StandardSQLFunction( "roundmagic" ) );
+
+                registerFunction( "ceiling", new StandardSQLFunction( "ceiling" ) );
+                registerFunction( "floor", new StandardSQLFunction( "floor" ) );
+
+                // Multi-param dialect functions...
+                registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER ) );
+
+                // function templates
+                registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
+
+                getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
+        }
+
+        public String getAddColumnString() {
+                return "add column";
+        }
+
+        public boolean supportsIdentityColumns() {
+                return true;
+        }
+
+        public String getIdentityColumnString() {
+                return "generated by default as identity (start with 1)"; //not null is implicit
+        }
+
+        public String getIdentitySelectString() {
+                return "call identity()";
+        }
+
+        public String getIdentityInsertString() {
+                return "null";
+        }
+
+        public String getForUpdateString() {
+                return "";
+        }
+
+        public boolean supportsUnique() {
+                return false;
+        }
+
+        public boolean supportsLimit() {
+                return true;
+        }
+
+        public String getLimitString(String sql, boolean hasOffset) {
+                return new StringBuffer( sql.length()+20 )
+                                .append( sql )
+                                .append( hasOffset ? " limit ? offset ?" : " limit ?" )
+                                .toString();
+        }
+
+        public boolean bindLimitParametersFirst() {
+                return true;
+        }
+
+        public boolean supportsIfExistsAfterTableName() {
+                return true;
+        }
+
+        public boolean supportsColumnCheck() {
+                return false;
+        }
+
+        public boolean supportsSequences() {
+                return true;
+        }
+
+        public boolean supportsPooledSequences() {
+                return true;
+        }
+
+        protected String getCreateSequenceString(String sequenceName) {
+                return "create sequence " + sequenceName;
+        }
+
+        protected String getDropSequenceString(String sequenceName) {
+                return "drop sequence " + sequenceName;
+        }
+
+        public String getSelectSequenceNextValString(String sequenceName) {
+                return "next value for " + sequenceName;
+        }
+
+        public String getSequenceNextValString(String sequenceName) {
+                return "call next value for " + sequenceName;
+        }
+
+        public String getQuerySequencesString() {
+                // this assumes schema support, which is present in 1.8.0 and later...
+                return "select sequence_name from information_schema.system_sequences";
+        }
+
+        public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+                return EXTRACTER;
+        }
+
+        private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+
+                /**
+                 * Extract the name of the violated constraint from the given SQLException.
+                 *
+                 * @param sqle The exception that was the result of the constraint violation.
+                 * @return The extracted constraint name.
+                 */
+                public String extractConstraintName(SQLException sqle) {
+                        String constraintName = null;
+
+                        int errorCode = JDBCExceptionHelper.extractErrorCode( sqle );
+
+                        if ( errorCode == -8 ) {
+                                constraintName = extractUsingTemplate(
+                                                "Integrity constraint violation ", " table:", sqle.getMessage()
+                                );
+                        }
+                        else if ( errorCode == -9 ) {
+                                constraintName = extractUsingTemplate(
+                                                "Violation of unique index: ", " in statement [", sqle.getMessage()
+                                );
+                        }
+                        else if ( errorCode == -104 ) {
+                                constraintName = extractUsingTemplate(
+                                                "Unique constraint violation: ", " in statement [", sqle.getMessage()
+                                );
+                        }
+                        else if ( errorCode == -177 ) {
+                                constraintName = extractUsingTemplate(
+                                                "Integrity constraint violation - no parent ", " table:", sqle.getMessage()
+                                );
+                        }
+
+                        return constraintName;
+                }
+
+        };
+
+        /**
+         * HSQL does not really support temp tables; just take advantage of the
+         * fact that it is a single user db...
+         */
+        public boolean supportsTemporaryTables() {
+                return true;
+        }
+
+        // current timestamp support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        /**
+         * Does this dialect support a way to retrieve the database's current
+         * timestamp value?
+         *
+         * @return True if the current timestamp can be retrieved; false otherwise.
+         */
+        public boolean supportsCurrentTimestampSelection() {
+                return true;
+        }
+
+        /**
+         * Should the value returned by {@link #getCurrentTimestampSelectString}
+         * be treated as callable.  Typically this indicates that JDBC escape
+         * syntax is being used...
+         *
+         * @return True if the {@link #getCurrentTimestampSelectString} return
+         * is callable; false otherwise.
+         */
+        public boolean isCurrentTimestampSelectStringCallable() {
+                return true;
+        }
+
+        /**
+         * Retrieve the command used to retrieve the current timestamp from the
+         * database.
+         *
+         * @return The command.
+         */
+        public String getCurrentTimestampSelectString() {
+                return "call current_timestamp";
+        }
+
+        /**
+         * The name of the database-specific SQL function for retrieving the
+         * current timestamp.
+         *
+         * @return The function name.
+         */
+        public String getCurrentTimestampSQLFunctionName() {
+                // the standard SQL function name is current_timestamp...
+                return "current_timestamp";
+        }
+
+        public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+                // HSQLDB only supports READ_UNCOMMITTED transaction isolation
+                if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+                        return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+                }
+                else if ( lockMode==LockMode.OPTIMISTIC) {
+                        return new OptimisticLockingStrategy( lockable, lockMode);
+                }
+                else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+                        return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+                }
+                return new ReadUncommittedLockingStrategy( lockable, lockMode );
+
+        }
+
+        public static class ReadUncommittedLockingStrategy extends SelectLockingStrategy {
+                public ReadUncommittedLockingStrategy(Lockable lockable, LockMode lockMode) {
+                        super( lockable, lockMode );
+                }
+
+                public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session)
+                                throws StaleObjectStateException, JDBCException {
+                        if ( getLockMode().greaterThan( LockMode.READ ) ) {
+                                log.warn( "HSQLDB supports only READ_UNCOMMITTED isolation" );
+                        }
+                        super.lock( id, version, object, timeout, session );
+                }
+        }
+
+
+        // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        public boolean supportsEmptyInList() {
+                return false;
+        }
+
+        public boolean supportsLobValueChangePropogation() {
+                return false;
+        }
+}
diff --git a/src/org/hsqldb/ClientConnection.java b/src/org/hsqldb/ClientConnection.java
new file mode 100644
index 0000000..38be527
--- /dev/null
+++ b/src/org/hsqldb/ClientConnection.java
@@ -0,0 +1,614 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultLob;
+import org.hsqldb.rowio.RowInputBinary;
+import org.hsqldb.rowio.RowOutputBinary;
+import org.hsqldb.rowio.RowOutputInterface;
+import org.hsqldb.server.HsqlSocketFactory;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.TimestampData;
+
+/**
+ * Base remote session proxy implementation. Uses instances of Result to
+ * transmit and recieve data. This implementation utilises the updated HSQL
+ * protocol.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class ClientConnection implements SessionInterface {
+
+    /**
+     * Specifies the Compatibility version required for both Servers and
+     * network JDBC Clients built with this baseline.  Must remain public
+     * for Server to have visibility to it.
+     *
+     * Update this value only when the current version of HSQLDB does not
+     * have inter-compatibility with Server and network JDBC Driver of
+     * the previous HSQLDB version.
+     *
+     * Must specify all 4 version segments (any segment may be the value 0,
+     * however). The string elements at (position p from right counted from 0)
+     * are multiplied by 100 to power p and added up, then negated, to form the
+     * integer representation of version string.
+     */
+    public static final String NETWORK_COMPATIBILITY_VERSION     = "1.9.0.0";
+    public static final int    NETWORK_COMPATIBILITY_VERSION_INT = -1090000;
+
+    //
+    static final int             BUFFER_SIZE = 0x1000;
+    final byte[]                 mainBuffer  = new byte[BUFFER_SIZE];
+    private boolean              isClosed;
+    private Socket               socket;
+    protected DataOutputStream   dataOutput;
+    protected DataInputStream    dataInput;
+    protected RowOutputInterface rowOut;
+    protected RowInputBinary     rowIn;
+    private Result               resultOut;
+    private long                 sessionID;
+    private long                 lobIDSequence;
+
+    //
+    private boolean  isReadOnlyDefault = false;
+    private boolean  isAutoCommit      = true;
+    private int      zoneSeconds;
+    private Scanner  scanner;
+    private String   zoneString;
+    private Calendar calendar;
+
+    //
+    String         host;
+    int            port;
+    String         path;
+    String         database;
+    boolean        isTLS;
+    int            databaseID;
+    String         clientPropertiesString;
+    HsqlProperties clientProperties;
+
+    /**
+     * Establishes a connection to the server.
+     */
+    public ClientConnection(String host, int port, String path,
+                            String database, boolean isTLS, String user,
+                            String password, int timeZoneSeconds) {
+
+        this.host        = host;
+        this.port        = port;
+        this.path        = path;
+        this.database    = database;
+        this.isTLS       = isTLS;
+        this.zoneSeconds = timeZoneSeconds;
+        this.zoneString  = TimeZone.getDefault().getID();
+
+        initStructures();
+
+        Result login = Result.newConnectionAttemptRequest(user, password,
+            database, zoneString, timeZoneSeconds);
+
+        initConnection(host, port, isTLS);
+
+        Result resultIn = execute(login);
+
+        if (resultIn.isError()) {
+            throw Error.error(resultIn);
+        }
+
+        sessionID              = resultIn.getSessionId();
+        databaseID             = resultIn.getDatabaseId();
+        clientPropertiesString = resultIn.getMainString();
+    }
+
+    /**
+     * resultOut is reused to trasmit all remote calls for session management.
+     * Here the structure is preset for sending attributes.
+     */
+    private void initStructures() {
+
+        RowOutputBinary rowOutTemp = new RowOutputBinary(mainBuffer);
+
+        rowOut    = rowOutTemp;
+        rowIn     = new RowInputBinary(rowOutTemp);
+        resultOut = Result.newSessionAttributesResult();
+    }
+
+    protected void initConnection(String host, int port, boolean isTLS) {
+        openConnection(host, port, isTLS);
+    }
+
+    protected void openConnection(String host, int port, boolean isTLS) {
+
+        try {
+            socket = HsqlSocketFactory.getInstance(isTLS).createSocket(host,
+                                                   port);
+
+            socket.setTcpNoDelay(true);
+
+            dataOutput = new DataOutputStream(socket.getOutputStream());
+            dataInput = new DataInputStream(
+                new BufferedInputStream(socket.getInputStream()));
+
+            handshake();
+        } catch (Exception e) {
+
+            // The details from "e" should not be thrown away here.  This is
+            // very useful info for end users to diagnose the runtime problem.
+            throw new HsqlException(e, Error.getStateString(ErrorCode.X_08001),
+                                    -ErrorCode.X_08001);
+        }
+    }
+
+    protected void closeConnection() {
+
+        try {
+            if (socket != null) {
+                socket.close();
+            }
+        } catch (Exception e) {}
+
+        socket = null;
+    }
+
+    public synchronized Result execute(Result r) {
+
+        try {
+            r.setSessionId(sessionID);
+            r.setDatabaseId(databaseID);
+            write(r);
+
+            return read();
+        } catch (Throwable e) {
+            throw Error.error(ErrorCode.X_08006, e.toString());
+        }
+    }
+
+    public synchronized RowSetNavigatorClient getRows(long navigatorId,
+            int offset, int size) {
+
+        try {
+            resultOut.setResultType(ResultConstants.REQUESTDATA);
+            resultOut.setResultId(navigatorId);
+            resultOut.setUpdateCount(offset);
+            resultOut.setFetchSize(size);
+
+            Result result = execute(resultOut);
+
+            return (RowSetNavigatorClient) result.getNavigator();
+        } catch (Throwable e) {
+            throw Error.error(ErrorCode.X_08006, e.toString());
+        }
+    }
+
+    public synchronized void closeNavigator(long navigatorId) {
+
+        try {
+            resultOut.setResultType(ResultConstants.CLOSE_RESULT);
+            resultOut.setResultId(navigatorId);
+            execute(resultOut);
+        } catch (Throwable e) {}
+    }
+
+    public synchronized void close() {
+
+        if (isClosed) {
+            return;
+        }
+
+        isClosed = true;
+
+        try {
+            resultOut.setResultType(ResultConstants.DISCONNECT);
+            execute(resultOut);
+        } catch (Exception e) {}
+
+        try {
+            closeConnection();
+        } catch (Exception e) {}
+    }
+
+    public synchronized Object getAttribute(int id) {
+
+        resultOut.setResultType(ResultConstants.GETSESSIONATTR);
+        resultOut.setStatementType(id);
+
+        Result in = execute(resultOut);
+
+        if (in.isError()) {
+            throw Error.error(in);
+        }
+
+        Object[] data = in.getSingleRowData();
+
+        switch (id) {
+
+            case SessionInterface.INFO_AUTOCOMMIT :
+                return data[SessionInterface.INFO_BOOLEAN];
+
+            case SessionInterface.INFO_CONNECTION_READONLY :
+                return data[SessionInterface.INFO_BOOLEAN];
+
+            case SessionInterface.INFO_ISOLATION :
+                return data[SessionInterface.INFO_INTEGER];
+
+            case SessionInterface.INFO_CATALOG :
+                return data[SessionInterface.INFO_VARCHAR];
+        }
+
+        return null;
+    }
+
+    public synchronized void setAttribute(int id, Object value) {
+
+        resultOut.setResultType(ResultConstants.SETSESSIONATTR);
+
+        Object[] data = resultOut.getSingleRowData();
+
+        data[SessionInterface.INFO_ID] = ValuePool.getInt(id);
+
+        switch (id) {
+
+            case SessionInterface.INFO_AUTOCOMMIT :
+            case SessionInterface.INFO_CONNECTION_READONLY :
+                data[SessionInterface.INFO_BOOLEAN] = value;
+                break;
+
+            case SessionInterface.INFO_ISOLATION :
+                data[SessionInterface.INFO_INTEGER] = value;
+                break;
+
+            case SessionInterface.INFO_CATALOG :
+                data[SessionInterface.INFO_VARCHAR] = value;
+                break;
+        }
+
+        Result resultIn = execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw Error.error(resultIn);
+        }
+    }
+
+    public synchronized boolean isReadOnlyDefault() {
+
+        Object info = getAttribute(SessionInterface.INFO_CONNECTION_READONLY);
+
+        isReadOnlyDefault = ((Boolean) info).booleanValue();
+
+        return isReadOnlyDefault;
+    }
+
+    public synchronized void setReadOnlyDefault(boolean mode) {
+
+        if (mode != isReadOnlyDefault) {
+            setAttribute(SessionInterface.INFO_CONNECTION_READONLY,
+                         mode ? Boolean.TRUE
+                              : Boolean.FALSE);
+
+            isReadOnlyDefault = mode;
+        }
+    }
+
+    public synchronized boolean isAutoCommit() {
+
+        Object info = getAttribute(SessionInterface.INFO_AUTOCOMMIT);
+
+        isAutoCommit = ((Boolean) info).booleanValue();
+
+        return isAutoCommit;
+    }
+
+    public synchronized void setAutoCommit(boolean mode) {
+
+        if (mode != isAutoCommit) {
+            setAttribute(SessionInterface.INFO_AUTOCOMMIT, mode ? Boolean.TRUE
+                                                                : Boolean
+                                                                .FALSE);
+
+            isAutoCommit = mode;
+        }
+    }
+
+    public synchronized void setIsolationDefault(int level) {
+        setAttribute(SessionInterface.INFO_ISOLATION, ValuePool.getInt(level));
+    }
+
+    public synchronized int getIsolation() {
+
+        Object info = getAttribute(SessionInterface.INFO_ISOLATION);
+
+        return ((Integer) info).intValue();
+    }
+
+    public synchronized boolean isClosed() {
+        return isClosed;
+    }
+
+    public Session getSession() {
+        return null;
+    }
+
+    public synchronized void startPhasedTransaction() {}
+
+    public synchronized void prepareCommit() {
+
+        resultOut.setAsTransactionEndRequest(ResultConstants.PREPARECOMMIT,
+                                             null);
+
+        Result in = execute(resultOut);
+
+        if (in.isError()) {
+            throw Error.error(in);
+        }
+    }
+
+    public synchronized void commit(boolean chain) {
+
+        resultOut.setAsTransactionEndRequest(ResultConstants.TX_COMMIT, null);
+
+        Result in = execute(resultOut);
+
+        if (in.isError()) {
+            throw Error.error(in);
+        }
+    }
+
+    public synchronized void rollback(boolean chain) {
+
+        resultOut.setAsTransactionEndRequest(ResultConstants.TX_ROLLBACK,
+                                             null);
+
+        Result in = execute(resultOut);
+
+        if (in.isError()) {
+            throw Error.error(in);
+        }
+    }
+
+    public synchronized void rollbackToSavepoint(String name) {
+
+        resultOut.setAsTransactionEndRequest(
+            ResultConstants.TX_SAVEPOINT_NAME_ROLLBACK, name);
+
+        Result in = execute(resultOut);
+
+        if (in.isError()) {
+            throw Error.error(in);
+        }
+    }
+
+    public synchronized void savepoint(String name) {
+
+        Result result = Result.newSetSavepointRequest(name);
+        Result in     = execute(result);
+
+        if (in.isError()) {
+            throw Error.error(in);
+        }
+    }
+
+    public synchronized void releaseSavepoint(String name) {
+
+        resultOut.setAsTransactionEndRequest(
+            ResultConstants.TX_SAVEPOINT_NAME_RELEASE, name);
+
+        Result in = execute(resultOut);
+
+        if (in.isError()) {
+            throw Error.error(in);
+        }
+    }
+
+    public void addWarning(HsqlException warning) {}
+
+    public synchronized long getId() {
+        return sessionID;
+    }
+
+    /**
+     * Used by pooled connections to reset the server-side session to a new
+     * one. In case of failure, the connection is closed.
+     *
+     * When the Connection.close() method is called, a pooled connection calls
+     * this method instead of HSQLClientConnection.close(). It can then
+     * reuse the HSQLClientConnection object with no further initialisation.
+     *
+     */
+    public synchronized void resetSession() {
+
+        Result login    = Result.newResetSessionRequest();
+        Result resultIn = execute(login);
+
+        if (resultIn.isError()) {
+            isClosed = true;
+
+            closeConnection();
+
+            throw Error.error(resultIn);
+        }
+
+        sessionID  = resultIn.getSessionId();
+        databaseID = resultIn.getDatabaseId();
+    }
+
+    protected void write(Result r) throws IOException, HsqlException {
+        r.write(dataOutput, rowOut);
+    }
+
+    protected Result read() throws IOException, HsqlException {
+
+        Result result = Result.newResult(dataInput, rowIn);
+
+        result.readAdditionalResults(this, dataInput, rowIn);
+        rowOut.setBuffer(mainBuffer);
+        rowIn.resetRow(mainBuffer.length);
+
+        return result;
+    }
+
+    /**
+     * Never called on this class
+     */
+    public synchronized String getInternalConnectionURL() {
+        return null;
+    }
+
+    public synchronized long getLobId() {
+        return lobIDSequence++;
+    }
+
+    public BlobDataID createBlob(long length) {
+
+        BlobDataID blob = new BlobDataID(getLobId());
+
+        return blob;
+    }
+
+    public ClobDataID createClob(long length) {
+
+        ClobDataID clob = new ClobDataID(getLobId());
+
+        return clob;
+    }
+
+    /**
+     * Does nothing here
+     */
+    public void allocateResultLob(ResultLob resultLob,
+                                  InputStream dataInput) {}
+
+    public Scanner getScanner() {
+
+        if (scanner == null) {
+            scanner = new Scanner();
+        }
+
+        return scanner;
+    }
+
+    public Calendar getCalendar() {
+
+        if (calendar == null) {
+            TimeZone zone = TimeZone.getTimeZone(zoneString);
+
+            calendar = new GregorianCalendar(zone);
+        }
+
+        return calendar;
+    }
+
+    public TimestampData getCurrentDate() {
+
+        long currentMillis = System.currentTimeMillis();
+        long seconds = HsqlDateTime.getCurrentDateMillis(currentMillis) / 1000;
+
+        return new TimestampData(seconds);
+    }
+
+    public int getZoneSeconds() {
+        return zoneSeconds;
+    }
+
+    public int getStreamBlockSize() {
+        return 512 * 1024;
+    }
+
+    public HsqlProperties getClientProperties() {
+
+        if (clientProperties == null) {
+            if (clientPropertiesString.length() > 0) {
+                HsqlProperties.delimitedArgPairsToProps(clientPropertiesString,
+                        "=", ";", null);
+            } else {
+                clientProperties = new HsqlProperties();
+            }
+        }
+
+        return clientProperties;
+    }
+
+    /**
+     * Converts specified encoded integer to a Network Compatibility Version
+     * String. The tranmitted integer is negative to distinguish it from
+     * 7 bit ASCII characters.
+     */
+    static public String toNetCompVersionString(int i) {
+
+        StringBuffer sb = new StringBuffer();
+
+        i *= -1;
+
+        sb.append(i / 1000000);
+
+        i %= 1000000;
+
+        sb.append('.');
+        sb.append(i / 10000);
+
+        i %= 10000;
+
+        sb.append('.');
+        sb.append(i / 100);
+
+        i %= 100;
+
+        sb.append('.');
+        sb.append(i);
+
+        return sb.toString();
+    }
+
+    protected void handshake() throws IOException {
+        dataOutput.writeInt(NETWORK_COMPATIBILITY_VERSION_INT);
+        dataOutput.flush();
+    }
+}
diff --git a/src/org/hsqldb/ClientConnectionHTTP.java b/src/org/hsqldb/ClientConnectionHTTP.java
new file mode 100644
index 0000000..ed005f1
--- /dev/null
+++ b/src/org/hsqldb/ClientConnectionHTTP.java
@@ -0,0 +1,115 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.hsqldb.lib.InOutUtil;
+import org.hsqldb.result.Result;
+
+/**
+ * HTTP protocol session proxy implementation. Uses the updated HSQLDB HTTP
+ * sub protocol.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class ClientConnectionHTTP extends ClientConnection {
+
+    static final String ENCODING = "8859_1";
+    static final int    IDLENGTH = 12;    // length of int + long for db and session IDs
+
+    public ClientConnectionHTTP(String host, int port, String path,
+                                String database, boolean isTLS, String user,
+                                String password, int timeZoneSeconds) {
+        super(host, port, path, database, isTLS, user, password,
+              timeZoneSeconds);
+    }
+
+    protected void initConnection(String host, int port, boolean isTLS) {}
+
+    public synchronized Result execute(Result r) {
+
+        super.openConnection(host, port, isTLS);
+
+        Result result = super.execute(r);
+
+        super.closeConnection();
+
+        return result;
+    }
+
+    protected void write(Result r) throws IOException, HsqlException {
+
+        dataOutput.write("POST ".getBytes(ENCODING));
+        dataOutput.write(path.getBytes(ENCODING));
+        dataOutput.write(" HTTP/1.0\r\n".getBytes(ENCODING));
+        dataOutput.write(
+            "Content-Type: application/octet-stream\r\n".getBytes(ENCODING));
+        dataOutput.write(("Content-Length: " + rowOut.size() + IDLENGTH
+                          + "\r\n").getBytes(ENCODING));
+        dataOutput.write("\r\n".getBytes(ENCODING));
+        dataOutput.writeInt(r.getDatabaseId());
+        dataOutput.writeLong(r.getSessionId());
+        r.write(dataOutput, rowOut);
+    }
+
+    protected Result read() throws IOException, HsqlException {
+
+        // fredt - for WebServer 4 lines should be skipped
+        // for Servlet, number of lines depends on Servlet container
+        // stop skipping after the blank line
+        rowOut.reset();
+
+        for (;;) {
+            int count = InOutUtil.readLine(dataInput, (OutputStream) rowOut);
+
+            if (count <= 2) {
+                break;
+            }
+        }
+
+        //
+        Result result = Result.newResult(dataInput, rowIn);
+
+        result.readAdditionalResults(this, dataInput, rowIn);
+
+        return result;
+    }
+
+    protected void handshake() throws IOException {
+
+        // We depend on the HTTP wrappings to assure end-to-end handshaking
+    }
+}
diff --git a/src/org/hsqldb/Collation.java b/src/org/hsqldb/Collation.java
new file mode 100644
index 0000000..a7bb17b
--- /dev/null
+++ b/src/org/hsqldb/Collation.java
@@ -0,0 +1,300 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.text.Collator;
+import java.util.Locale;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.rights.Grantee;
+
+/**
+ * Implementation of collation support for CHAR and VARCHAR data.
+ *
+ * @author Frand Schoenheit frank.schoenheit@sun.com
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.8.0
+ */
+public class Collation implements SchemaObject {
+
+    public static final HashMap nameToJavaName = new HashMap(101);
+
+    static {
+        nameToJavaName.put("Afrikaans", "af-ZA");
+        nameToJavaName.put("Amharic", "am-ET");
+        nameToJavaName.put("Arabic", "ar");
+        nameToJavaName.put("Assamese", "as-IN");
+        nameToJavaName.put("Azerbaijani_Latin", "az-AZ");
+        nameToJavaName.put("Azerbaijani_Cyrillic", "az-cyrillic");
+        nameToJavaName.put("Belarusian", "be-BY");
+        nameToJavaName.put("Bulgarian", "bg-BG");
+        nameToJavaName.put("Bengali", "bn-IN");
+        nameToJavaName.put("Tibetan", "bo-CN");
+        nameToJavaName.put("Bosnian", "bs-BA");
+        nameToJavaName.put("Catalan", "ca-ES");
+        nameToJavaName.put("Czech", "cs-CZ");
+        nameToJavaName.put("Welsh", "cy-GB");
+        nameToJavaName.put("Danish", "da-DK");
+        nameToJavaName.put("German", "de-DE");
+        nameToJavaName.put("Greek", "el-GR");
+        nameToJavaName.put("Latin1_General", "en-US");
+        nameToJavaName.put("English", "en-US");
+        nameToJavaName.put("Spanish", "es-ES");
+        nameToJavaName.put("Estonian", "et-EE");
+        nameToJavaName.put("Basque", "eu");
+        nameToJavaName.put("Finnish", "fi-FI");
+        nameToJavaName.put("French", "fr-FR");
+        nameToJavaName.put("Guarani", "gn-PY");
+        nameToJavaName.put("Gujarati", "gu-IN");
+        nameToJavaName.put("Hausa", "ha-NG");
+        nameToJavaName.put("Hebrew", "he-IL");
+        nameToJavaName.put("Hindi", "hi-IN");
+        nameToJavaName.put("Croatian", "hr-HR");
+        nameToJavaName.put("Hungarian", "hu-HU");
+        nameToJavaName.put("Armenian", "hy-AM");
+        nameToJavaName.put("Indonesian", "id-ID");
+        nameToJavaName.put("Igbo", "ig-NG");
+        nameToJavaName.put("Icelandic", "is-IS");
+        nameToJavaName.put("Italian", "it-IT");
+        nameToJavaName.put("Inuktitut", "iu-CA");
+        nameToJavaName.put("Japanese", "ja-JP");
+        nameToJavaName.put("Georgian", "ka-GE");
+        nameToJavaName.put("Kazakh", "kk-KZ");
+        nameToJavaName.put("Khmer", "km-KH");
+        nameToJavaName.put("Kannada", "kn-IN");
+        nameToJavaName.put("Korean", "ko-KR");
+        nameToJavaName.put("Konkani", "kok-IN");
+        nameToJavaName.put("Kashmiri", "ks");
+        nameToJavaName.put("Kirghiz", "ky-KG");
+        nameToJavaName.put("Lao", "lo-LA");
+        nameToJavaName.put("Lithuanian", "lt-LT");
+        nameToJavaName.put("Latvian", "lv-LV");
+        nameToJavaName.put("Maori", "mi-NZ");
+        nameToJavaName.put("Macedonian", "mk-MK");
+        nameToJavaName.put("Malayalam", "ml-IN");
+        nameToJavaName.put("Mongolian", "mn-MN");
+        nameToJavaName.put("Manipuri", "mni-IN");
+        nameToJavaName.put("Marathi", "mr-IN");
+        nameToJavaName.put("Malay", "ms-MY");
+        nameToJavaName.put("Maltese", "mt-MT");
+        nameToJavaName.put("Burmese", "my-MM");
+        nameToJavaName.put("Danish_Norwegian", "nb-NO");
+        nameToJavaName.put("Nepali", "ne-NP");
+        nameToJavaName.put("Dutch", "nl-NL");
+        nameToJavaName.put("Norwegian", "nn-NO");
+        nameToJavaName.put("Oriya", "or-IN");
+        nameToJavaName.put("Punjabi", "pa-IN");
+        nameToJavaName.put("Polish", "pl-PL");
+        nameToJavaName.put("Pashto", "ps-AF");
+        nameToJavaName.put("Portuguese", "pt-PT");
+        nameToJavaName.put("Romanian", "ro-RO");
+        nameToJavaName.put("Russian", "ru-RU");
+        nameToJavaName.put("Sanskrit", "sa-IN");
+        nameToJavaName.put("Sindhi", "sd-IN");
+        nameToJavaName.put("Slovak", "sk-SK");
+        nameToJavaName.put("Slovenian", "sl-SI");
+        nameToJavaName.put("Somali", "so-SO");
+        nameToJavaName.put("Albanian", "sq-AL");
+        nameToJavaName.put("Serbian_Cyrillic", "sr-YU");
+        nameToJavaName.put("Serbian_Latin", "sh-BA");
+        nameToJavaName.put("Swedish", "sv-SE");
+        nameToJavaName.put("Swahili", "sw-KE");
+        nameToJavaName.put("Tamil", "ta-IN");
+        nameToJavaName.put("Telugu", "te-IN");
+        nameToJavaName.put("Tajik", "tg-TJ");
+        nameToJavaName.put("Thai", "th-TH");
+        nameToJavaName.put("Turkmen", "tk-TM");
+        nameToJavaName.put("Tswana", "tn-BW");
+        nameToJavaName.put("Turkish", "tr-TR");
+        nameToJavaName.put("Tatar", "tt-RU");
+        nameToJavaName.put("Ukrainian", "uk-UA");
+        nameToJavaName.put("Urdu", "ur-PK");
+        nameToJavaName.put("Uzbek_Latin", "uz-UZ");
+        nameToJavaName.put("Venda", "ven-ZA");
+        nameToJavaName.put("Vietnamese", "vi-VN");
+        nameToJavaName.put("Yoruba", "yo-NG");
+        nameToJavaName.put("Chinese", "zh-CN");
+        nameToJavaName.put("Zulu", "zu-ZA");
+    }
+
+    final static Collation defaultCollation = new Collation();
+    final HsqlName         name;
+    Collator               collator;
+    Locale                 locale;
+    boolean                equalIsIdentical = true;
+
+    public Collation() {
+
+        locale = Locale.ENGLISH;
+
+        String language = locale.getDisplayLanguage(Locale.ENGLISH);
+
+        name = HsqlNameManager.newInfoSchemaObjectName(language, true,
+                SchemaObject.COLLATION);
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public static Collation getDefaultInstance() {
+        return defaultCollation;
+    }
+
+    public static org.hsqldb.lib.Iterator getCollationsIterator() {
+        return nameToJavaName.keySet().iterator();
+    }
+
+    public static org.hsqldb.lib.Iterator getLocalesIterator() {
+        return nameToJavaName.values().iterator();
+    }
+
+    public void setCollationAsLocale() {
+
+        Locale locale   = Locale.getDefault();
+        String language = locale.getDisplayLanguage(Locale.ENGLISH);
+
+        try {
+            setCollation(language);
+        } catch (HsqlException e) {}
+    }
+
+    void setCollation(String newName) {
+
+        String jname = (String) Collation.nameToJavaName.get(newName);
+
+        if (jname == null) {
+            throw Error.error(ErrorCode.X_42501, newName);
+        }
+
+        name.rename(newName, true);
+
+        String[] parts    = StringUtil.split(jname, "-");
+        String   language = parts[0];
+        String   country  = parts.length == 2 ? parts[1]
+                                              : "";
+
+        locale           = new Locale(language, country);
+        collator         = Collator.getInstance(locale);
+        equalIsIdentical = false;
+    }
+
+    /**
+     * Returns true if two equal strings always contain identical sequence of
+     * characters for the current collation, e.g. English language.
+     */
+    public boolean isEqualAlwaysIdentical() {
+        return collator == null;
+    }
+
+    /**
+     * returns -1, 0 or +1
+     */
+    public int compare(String a, String b) {
+
+        int i;
+
+        if (collator == null) {
+            i = a.compareTo(b);
+        } else {
+            i = collator.compare(a, b);
+        }
+
+        return (i == 0) ? 0
+                        : (i < 0 ? -1
+                                 : 1);
+    }
+
+    public int compareIgnoreCase(String a, String b) {
+
+        int i;
+
+        if (collator == null) {
+            i = JavaSystem.compareIngnoreCase(a, b);
+        } else {
+            i = collator.compare(toUpperCase(a), toUpperCase(b));
+        }
+
+        return (i == 0) ? 0
+                        : (i < 0 ? -1
+                                 : 1);
+    }
+
+    public String toUpperCase(String s) {
+        return s.toUpperCase(locale);
+    }
+
+    public String toLowerCase(String s) {
+        return s.toLowerCase(locale);
+    }
+
+    public int getType() {
+        return SchemaObject.COLLATION;
+    }
+
+    public HsqlName getSchemaName() {
+        return SqlInvariants.INFORMATION_SCHEMA_HSQLNAME;
+    }
+
+    public HsqlName getCatalogName() {
+        return null;
+    }
+
+    public Grantee getOwner() {
+        return SqlInvariants.INFORMATION_SCHEMA_HSQLNAME.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+        return new OrderedHashSet();
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public String getSQL() {
+        return "";
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+}
diff --git a/src/org/hsqldb/ColumnBase.java b/src/org/hsqldb/ColumnBase.java
new file mode 100644
index 0000000..5ff9b13
--- /dev/null
+++ b/src/org/hsqldb/ColumnBase.java
@@ -0,0 +1,141 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.types.Type;
+
+/**
+ * Base implementation of variables, columns of result or table.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ColumnBase {
+
+    private String    name;
+    private String    table;
+    private String    schema;
+    private String    catalog;
+    private boolean   isWriteable;
+    private boolean   isSearchable;
+    protected byte     parameterMode;
+    protected boolean isIdentity;
+    protected byte     nullability;
+    protected Type    dataType;
+
+    ColumnBase() {}
+
+    public ColumnBase(String catalog, String schema, String table,
+                      String name) {
+
+        this.catalog = catalog;
+        this.schema  = schema;
+        this.table   = table;
+        this.name    = name;
+    }
+
+    public String getNameString() {
+        return name;
+    }
+
+    public String getTableNameString() {
+        return table;
+    }
+
+    public String getSchemaNameString() {
+        return schema;
+    }
+
+    public String getCatalogNameString() {
+        return catalog;
+    }
+
+    public void setIdentity(boolean value) {
+        isIdentity = value;
+    }
+
+    public boolean isIdentity() {
+        return isIdentity;
+    }
+
+    protected void setType(ColumnBase other) {
+        nullability = other.nullability;
+        dataType    = other.dataType;
+    }
+
+    public void setType(Type type) {
+        this.dataType = type;
+    }
+
+    public boolean isNullable() {
+        return !isIdentity && nullability == SchemaObject.Nullability.NULLABLE;
+    }
+
+    protected void setNullable(boolean value) {
+        nullability = value ? SchemaObject.Nullability.NULLABLE
+                            : SchemaObject.Nullability.NO_NULLS;
+    }
+
+    public byte getNullability() {
+        return isIdentity ? SchemaObject.Nullability.NO_NULLS
+                          : nullability;
+    }
+
+    public void setNullability(byte value) {
+        nullability = value;
+    }
+
+    public boolean isWriteable() {
+        return isWriteable;
+    }
+
+    public boolean isSearchable() {
+        return isSearchable;
+    }
+
+    public void setWriteable(boolean value) {
+        isWriteable = value;
+    }
+
+    public Type getDataType() {
+        return dataType;
+    }
+
+    public byte getParameterMode() {
+        return parameterMode;
+    }
+
+    public void setParameterMode(byte mode) {
+        this.parameterMode = mode;
+    }
+}
diff --git a/src/org/hsqldb/ColumnSchema.java b/src/org/hsqldb/ColumnSchema.java
new file mode 100644
index 0000000..b1600b6
--- /dev/null
+++ b/src/org/hsqldb/ColumnSchema.java
@@ -0,0 +1,382 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of SQL table column metadata.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class ColumnSchema extends ColumnBase implements SchemaObject {
+
+    public final static ColumnSchema[] emptyArray = new ColumnSchema[]{};
+
+    //
+    private HsqlName       columnName;
+    private boolean        isPrimaryKey;
+    private Expression     defaultExpression;
+    private Expression     generatingExpression;
+    private NumberSequence sequence;
+    private OrderedHashSet references = new OrderedHashSet();
+    private Expression     accessor;
+
+    /**
+     * Creates a column defined in DDL statement.
+     */
+    public ColumnSchema(HsqlName name, Type type, boolean isNullable,
+                        boolean isPrimaryKey, Expression defaultExpression) {
+
+        columnName             = name;
+        nullability = isNullable ? SchemaObject.Nullability.NULLABLE
+                                 : SchemaObject.Nullability.NO_NULLS;
+        this.dataType          = type;
+        this.isPrimaryKey      = isPrimaryKey;
+        this.defaultExpression = defaultExpression;
+
+        setReferences();
+    }
+
+    public int getType() {
+        return columnName.type;
+    }
+
+    public HsqlName getName() {
+        return columnName;
+    }
+
+    public String getNameString() {
+        return columnName.name;
+    }
+
+    public String getTableNameString() {
+        return columnName.parent == null ? null
+                                         : columnName.parent.name;
+    }
+
+    public HsqlName getSchemaName() {
+        return columnName.schema;
+    }
+
+    public String getSchemaNameString() {
+        return columnName.schema == null ? null
+                                         : columnName.schema.name;
+    }
+
+    public HsqlName getCatalogName() {
+        return columnName.schema == null ? null
+                                         : columnName.schema.schema;
+    }
+
+    public String getCatalogNameString() {
+
+        return columnName.schema == null ? null
+                                         : columnName.schema.schema == null
+                                           ? null
+                                           : columnName.schema.schema.name;
+    }
+
+    public Grantee getOwner() {
+        return columnName.schema == null ? null
+                                         : columnName.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+        return references;
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject table) {
+
+        if (generatingExpression == null) {
+            return;
+        }
+
+        generatingExpression.resetColumnReferences();
+        generatingExpression.resolveCheckOrGenExpression(session,
+                ((Table) table).defaultRanges, false);
+
+        if (dataType.typeComparisonGroup
+                != generatingExpression.getDataType().typeComparisonGroup) {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        setReferences();
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        switch (parameterMode) {
+
+            case SchemaObject.ParameterModes.PARAM_IN :
+                sb.append(Tokens.T_IN).append(' ');
+                break;
+
+            case SchemaObject.ParameterModes.PARAM_OUT :
+                sb.append(Tokens.T_OUT).append(' ');
+                break;
+
+            case SchemaObject.ParameterModes.PARAM_INOUT :
+                sb.append(Tokens.T_INOUT).append(' ');
+                break;
+        }
+
+        if (columnName != null) {
+            sb.append(columnName.statementName);
+            sb.append(' ');
+        }
+
+        sb.append(dataType.getTypeDefinition());
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    public void setType(Type type) {
+
+        this.dataType = type;
+
+        setReferences();
+    }
+
+    public void setName(HsqlName name) {
+        this.columnName = name;
+    }
+
+    void setIdentity(NumberSequence sequence) {
+        this.sequence = sequence;
+        isIdentity    = sequence != null;
+    }
+
+    void setType(ColumnSchema other) {
+        nullability = other.nullability;
+        dataType    = other.dataType;
+    }
+
+    public NumberSequence getIdentitySequence() {
+        return sequence;
+    }
+
+    /**
+     *  Is column nullable.
+     *
+     * @return boolean
+     */
+    public boolean isNullable() {
+
+        boolean isNullable = super.isNullable();
+
+        if (isNullable) {
+            if (dataType.isDomainType()) {
+                return dataType.userTypeModifier.isNullable();
+            }
+        }
+
+        return isNullable;
+    }
+
+    public byte getNullability() {
+        return isPrimaryKey ? SchemaObject.Nullability.NO_NULLS
+                            : super.getNullability();
+    }
+
+    public boolean isGenerated() {
+        return generatingExpression != null;
+    }
+
+    public boolean hasDefault() {
+        return getDefaultExpression() != null;
+    }
+
+    /**
+     * Is column writeable or always generated
+     *
+     * @return boolean
+     */
+    public boolean isWriteable() {
+        return !isGenerated();
+    }
+
+    public void setWriteable(boolean value) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "ColumnSchema");
+    }
+
+    public boolean isSearchable() {
+        return Types.isSearchable(dataType.typeCode);
+    }
+
+    /**
+     *  Is this single column primary key of the table.
+     *
+     * @return boolean
+     */
+    public boolean isPrimaryKey() {
+        return isPrimaryKey;
+    }
+
+    /**
+     *  Set primary key.
+     *
+     */
+    void setPrimaryKey(boolean value) {
+        isPrimaryKey = value;
+    }
+
+    /**
+     *  Returns default value in the session context.
+     */
+    public Object getDefaultValue(Session session) {
+
+        return defaultExpression == null ? null
+                                         : defaultExpression.getValue(session,
+                                         dataType);
+    }
+
+    /**
+     *  Returns generated value in the session context.
+     */
+    public Object getGeneratedValue(Session session) {
+
+        return generatingExpression == null ? null
+                                            : generatingExpression.getValue(
+                                            session, dataType);
+    }
+
+    /**
+     *  Returns SQL for default value.
+     */
+    public String getDefaultSQL() {
+
+        String ddl = null;
+
+        ddl = defaultExpression == null ? null
+                                        : defaultExpression.getSQL();
+
+        return ddl;
+    }
+
+    /**
+     *  Returns default expression for the column.
+     */
+    Expression getDefaultExpression() {
+
+        if (defaultExpression == null) {
+            if (dataType.isDomainType()) {
+                return dataType.userTypeModifier.getDefaultClause();
+            }
+
+            return null;
+        } else {
+            return defaultExpression;
+        }
+    }
+
+    void setDefaultExpression(Expression expr) {
+        defaultExpression = expr;
+    }
+
+    /**
+     *  Returns generated expression for the column.
+     */
+    public Expression getGeneratingExpression() {
+        return generatingExpression;
+    }
+
+    void setGeneratingExpression(Expression expr) {
+        generatingExpression = expr;
+    }
+
+    public ColumnSchema duplicate() {
+
+        ColumnSchema copy = new ColumnSchema(columnName, dataType,
+                                             isNullable(), isPrimaryKey,
+                                             defaultExpression);
+
+        copy.setGeneratingExpression(generatingExpression);
+        copy.setIdentity(sequence);
+
+        return copy;
+    }
+
+    public Expression getAccessor() {
+
+        if (accessor == null) {
+            accessor = new ExpressionColumnAccessor(this);
+        }
+
+        return accessor;
+    }
+
+    private void setReferences() {
+
+        references.clear();
+
+        if (dataType.isDomainType() || dataType.isDistinctType()) {
+            HsqlName name = ((SchemaObject) dataType).getName();
+
+            references.add(name);
+        }
+
+        if (generatingExpression != null) {
+            generatingExpression.collectObjectNames(references);
+
+            Iterator it = references.iterator();
+
+            while (it.hasNext()) {
+                HsqlName name = (HsqlName) it.next();
+
+                if (name.type == SchemaObject.COLUMN
+                        || name.type == SchemaObject.TABLE) {
+                    it.remove();
+                }
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/Constraint.java b/src/org/hsqldb/Constraint.java
new file mode 100644
index 0000000..ab427cb
--- /dev/null
+++ b/src/org/hsqldb/Constraint.java
@@ -0,0 +1,1044 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.RangeVariable.RangeIteratorBase;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.types.Type;
+
+// fredt@users 20020225 - patch 1.7.0 by boucherb@users - named constraints
+// fredt@users 20020320 - doc 1.7.0 - update
+// tony_lai@users 20020820 - patch 595156 - violation of Integrity constraint name
+
+/**
+ * Implementation of a table constraint with references to the indexes used
+ * by the constraint.<p>
+ *
+ * Partly based on Hypersonic code.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public final class Constraint implements SchemaObject {
+
+    ConstraintCore   core;
+    private HsqlName name;
+    int              constType;
+    boolean          isForward;
+
+    //
+    Expression      check;
+    private boolean isNotNull;
+    int             notNullColumnIndex;
+    RangeVariable   rangeVariable;
+
+    // for temp constraints only
+    OrderedHashSet mainColSet;
+    OrderedHashSet refColSet;
+
+    //
+    final public static Constraint[] emptyArray = new Constraint[]{};
+
+    private Constraint() {}
+
+    /**
+     *  Constructor declaration for PK and UNIQUE
+     */
+    public Constraint(HsqlName name, Table t, Index index, int type) {
+
+        this.name      = name;
+        constType      = type;
+        core           = new ConstraintCore();
+        core.mainTable = t;
+        core.mainIndex = index;
+        core.mainCols  = index.getColumns();
+
+        for (int i = 0; i < core.mainCols.length; i++) {
+            Type dataType = t.getColumn(core.mainCols[i]).getDataType();
+
+            if (dataType.isLobType()) {
+                throw Error.error(ErrorCode.X_42534);
+            }
+        }
+    }
+
+    public Constraint(HsqlName name, Table table, int[] cols, int type) {
+
+        this.name      = name;
+        constType      = type;
+        core           = new ConstraintCore();
+        core.mainTable = table;
+        core.mainCols  = cols;
+    }
+
+    /**
+     *  Constructor for main constraints (foreign key references in PK table)
+     */
+    public Constraint(HsqlName name, Constraint fkconstraint) {
+
+        this.name = name;
+        constType = SchemaObject.ConstraintTypes.MAIN;
+        core      = fkconstraint.core;
+    }
+
+    /**
+     * General constructor for foreign key constraints.
+     *
+     * @param name name of constraint
+     * @param refCols list of referencing columns
+     * @param mainTableName referenced table
+     * @param mainCols list of referenced columns
+     * @param type constraint type
+     * @param deleteAction triggered action on delete
+     * @param updateAction triggered action on update
+     *
+     */
+    public Constraint(HsqlName name, HsqlName refTableName,
+                      OrderedHashSet refCols, HsqlName mainTableName,
+                      OrderedHashSet mainCols, int type, int deleteAction,
+                      int updateAction, int matchType) {
+
+        this.name          = name;
+        constType          = type;
+        mainColSet         = mainCols;
+        refColSet          = refCols;
+        core               = new ConstraintCore();
+        core.refTableName  = refTableName;
+        core.mainTableName = mainTableName;
+        core.deleteAction  = deleteAction;
+        core.updateAction  = updateAction;
+        core.matchType     = matchType;
+
+        switch (core.deleteAction) {
+
+            case SchemaObject.ReferentialAction.CASCADE :
+            case SchemaObject.ReferentialAction.SET_DEFAULT :
+            case SchemaObject.ReferentialAction.SET_NULL :
+                core.hasDeleteAction = true;
+        }
+
+        switch (core.updateAction) {
+
+            case SchemaObject.ReferentialAction.CASCADE :
+            case SchemaObject.ReferentialAction.SET_DEFAULT :
+            case SchemaObject.ReferentialAction.SET_NULL :
+                core.hasUpdateAction = true;
+        }
+    }
+
+    public Constraint(HsqlName name, OrderedHashSet mainCols, int type) {
+
+        this.name  = name;
+        constType  = type;
+        mainColSet = mainCols;
+        core       = new ConstraintCore();
+    }
+
+    public Constraint(HsqlName uniqueName, HsqlName mainName,
+                      HsqlName refName, Table mainTable, Table refTable,
+                      int[] mainCols, int[] refCols, Index mainIndex,
+                      Index refIndex, int deleteAction,
+                      int updateAction) throws HsqlException {
+
+        this.name         = refName;
+        constType         = SchemaObject.ConstraintTypes.FOREIGN_KEY;
+        core              = new ConstraintCore();
+        core.uniqueName   = uniqueName;
+        core.mainName     = mainName;
+        core.refName      = refName;
+        core.mainTable    = mainTable;
+        core.refTable     = refTable;
+        core.mainCols     = mainCols;
+        core.refCols      = refCols;
+        core.mainIndex    = mainIndex;
+        core.refIndex     = refIndex;
+        core.deleteAction = deleteAction;
+        core.updateAction = updateAction;
+    }
+
+    Constraint duplicate() {
+
+        Constraint copy = new Constraint();
+
+        copy.core      = core.duplicate();
+        copy.name      = name;
+        copy.constType = constType;
+        copy.isForward = isForward;
+
+        //
+        copy.check              = check;
+        copy.isNotNull          = isNotNull;
+        copy.notNullColumnIndex = notNullColumnIndex;
+        copy.rangeVariable      = rangeVariable;
+
+        return copy;
+    }
+
+    void setColumnsIndexes(Table table) {
+
+        if (constType == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+            if (mainColSet == null) {
+                core.mainCols = core.mainTable.getPrimaryKey();
+
+                if (core.mainCols == null) {
+                    throw Error.error(ErrorCode.X_42581);
+                }
+            } else if (core.mainCols == null) {
+                core.mainCols = core.mainTable.getColumnIndexes(mainColSet);
+            }
+
+            if (core.refCols == null) {
+                core.refCols = table.getColumnIndexes(refColSet);
+            }
+
+            for (int i = 0; i < core.refCols.length; i++) {
+                Type dataType = table.getColumn(core.refCols[i]).getDataType();
+
+                if (dataType.isLobType()) {
+                    throw Error.error(ErrorCode.X_42534);
+                }
+            }
+        } else if (mainColSet != null) {
+            core.mainCols = table.getColumnIndexes(mainColSet);
+
+            for (int i = 0; i < core.mainCols.length; i++) {
+                Type dataType =
+                    table.getColumn(core.mainCols[i]).getDataType();
+
+                if (dataType.isLobType()) {
+                    throw Error.error(ErrorCode.X_42534);
+                }
+            }
+        }
+    }
+
+    public int getType() {
+        return SchemaObject.CONSTRAINT;
+    }
+
+    /**
+     * Returns the HsqlName.
+     */
+    public HsqlName getName() {
+        return name;
+    }
+
+    public HsqlName getCatalogName() {
+        return name.schema.schema;
+    }
+
+    public HsqlName getSchemaName() {
+        return name.schema;
+    }
+
+    public Grantee getOwner() {
+        return name.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+
+        switch (constType) {
+
+            case SchemaObject.ConstraintTypes.CHECK :
+                OrderedHashSet refs = new OrderedHashSet();
+
+                check.collectObjectNames(refs);
+
+                for (int j = refs.size() - 1; j >= 0; j--) {
+                    HsqlName name = (HsqlName) refs.get(j);
+
+                    if (name.type == SchemaObject.COLUMN
+                            || name.type == SchemaObject.TABLE) {
+                        refs.remove(j);
+                    }
+                }
+
+                return refs;
+
+            case SchemaObject.ConstraintTypes.FOREIGN_KEY :
+                OrderedHashSet set = new OrderedHashSet();
+
+                set.add(core.uniqueName);
+
+                return set;
+        }
+
+        return new OrderedHashSet();
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        switch (getConstraintType()) {
+
+            case SchemaObject.ConstraintTypes.PRIMARY_KEY :
+                if (getMainColumns().length > 1
+                        || (getMainColumns().length == 1
+                            && !getName().isReservedName())) {
+                    if (!getName().isReservedName()) {
+                        sb.append(Tokens.T_CONSTRAINT).append(' ');
+                        sb.append(getName().statementName).append(' ');
+                    }
+
+                    sb.append(Tokens.T_PRIMARY).append(' ').append(
+                        Tokens.T_KEY);
+                    sb.append(
+                        getMain().getColumnListSQL(
+                            getMainColumns(), getMainColumns().length));
+                }
+                break;
+
+            case SchemaObject.ConstraintTypes.UNIQUE :
+                if (!getName().isReservedName()) {
+                    sb.append(Tokens.T_CONSTRAINT).append(' ');
+                    sb.append(getName().statementName);
+                    sb.append(' ');
+                }
+
+                sb.append(Tokens.T_UNIQUE);
+
+                int[] col = getMainColumns();
+
+                sb.append(getMain().getColumnListSQL(col, col.length));
+                break;
+
+            case SchemaObject.ConstraintTypes.FOREIGN_KEY :
+                if (isForward) {
+                    sb.append(Tokens.T_ALTER).append(' ').append(
+                        Tokens.T_TABLE).append(' ');
+                    sb.append(
+                        getRef().getName().getSchemaQualifiedStatementName());
+                    sb.append(' ').append(Tokens.T_ADD).append(' ');
+                    getFKStatement(sb);
+                } else {
+                    getFKStatement(sb);
+                }
+                break;
+
+            case SchemaObject.ConstraintTypes.CHECK :
+                if (isNotNull()) {
+                    break;
+                }
+
+                if (!getName().isReservedName()) {
+                    sb.append(Tokens.T_CONSTRAINT).append(' ');
+                    sb.append(getName().statementName).append(' ');
+                }
+
+                sb.append(Tokens.T_CHECK).append('(');
+                sb.append(check.getSQL());
+                sb.append(')');
+
+                // should not throw as it is already tested OK
+                break;
+        }
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    /**
+     * Generates the foreign key declaration for a given Constraint object.
+     */
+    private void getFKStatement(StringBuffer sb) {
+
+        if (!getName().isReservedName()) {
+            sb.append(Tokens.T_CONSTRAINT).append(' ');
+            sb.append(getName().statementName);
+            sb.append(' ');
+        }
+
+        sb.append(Tokens.T_FOREIGN).append(' ').append(Tokens.T_KEY);
+
+        int[] col = getRefColumns();
+
+        sb.append(getRef().getColumnListSQL(col, col.length));
+        sb.append(' ').append(Tokens.T_REFERENCES).append(' ');
+        sb.append(getMain().getName().getSchemaQualifiedStatementName());
+
+        col = getMainColumns();
+
+        sb.append(getMain().getColumnListSQL(col, col.length));
+
+        if (getDeleteAction() != SchemaObject.ReferentialAction.NO_ACTION) {
+            sb.append(' ').append(Tokens.T_ON).append(' ').append(
+                Tokens.T_DELETE).append(' ');
+            sb.append(getDeleteActionString());
+        }
+
+        if (getUpdateAction() != SchemaObject.ReferentialAction.NO_ACTION) {
+            sb.append(' ').append(Tokens.T_ON).append(' ').append(
+                Tokens.T_UPDATE).append(' ');
+            sb.append(getUpdateActionString());
+        }
+    }
+
+    public HsqlName getMainTableName() {
+        return core.mainTableName;
+    }
+
+    public HsqlName getMainName() {
+        return core.mainName;
+    }
+
+    public HsqlName getRefName() {
+        return core.refName;
+    }
+
+    public HsqlName getUniqueName() {
+        return core.uniqueName;
+    }
+
+    /**
+     *  Returns the type of constraint
+     */
+    public int getConstraintType() {
+        return constType;
+    }
+
+    /**
+     *  Returns the main table
+     */
+    public Table getMain() {
+        return core.mainTable;
+    }
+
+    /**
+     *  Returns the main index
+     */
+    Index getMainIndex() {
+        return core.mainIndex;
+    }
+
+    /**
+     *  Returns the reference table
+     */
+    public Table getRef() {
+        return core.refTable;
+    }
+
+    /**
+     *  Returns the reference index
+     */
+    Index getRefIndex() {
+        return core.refIndex;
+    }
+
+    /**
+     * Returns the foreign key action rule.
+     */
+    private static String getActionString(int action) {
+
+        switch (action) {
+
+            case SchemaObject.ReferentialAction.RESTRICT :
+                return Tokens.T_RESTRICT;
+
+            case SchemaObject.ReferentialAction.CASCADE :
+                return Tokens.T_CASCADE;
+
+            case SchemaObject.ReferentialAction.SET_DEFAULT :
+                return Tokens.T_SET + ' ' + Tokens.T_DEFAULT;
+
+            case SchemaObject.ReferentialAction.SET_NULL :
+                return Tokens.T_SET + ' ' + Tokens.T_NULL;
+
+            default :
+                return Tokens.T_NO + ' ' + Tokens.T_ACTION;
+        }
+    }
+
+    /**
+     *  The ON DELETE triggered action of (foreign key) constraint
+     */
+    public int getDeleteAction() {
+        return core.deleteAction;
+    }
+
+    public String getDeleteActionString() {
+        return getActionString(core.deleteAction);
+    }
+
+    /**
+     *  The ON UPDATE triggered action of (foreign key) constraint
+     */
+    public int getUpdateAction() {
+        return core.updateAction;
+    }
+
+    public String getUpdateActionString() {
+        return getActionString(core.updateAction);
+    }
+
+    public boolean hasTriggeredAction() {
+
+        if (constType == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+            switch (core.deleteAction) {
+
+                case SchemaObject.ReferentialAction.CASCADE :
+                case SchemaObject.ReferentialAction.SET_DEFAULT :
+                case SchemaObject.ReferentialAction.SET_NULL :
+                    return true;
+            }
+
+            switch (core.updateAction) {
+
+                case SchemaObject.ReferentialAction.CASCADE :
+                case SchemaObject.ReferentialAction.SET_DEFAULT :
+                case SchemaObject.ReferentialAction.SET_NULL :
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    public int getDeferability() {
+        return SchemaObject.Deferable.NOT_DEFERRABLE;
+    }
+
+    /**
+     *  Returns the main table column index array
+     */
+    public int[] getMainColumns() {
+        return core.mainCols;
+    }
+
+    /**
+     *  Returns the reference table column index array
+     */
+    public int[] getRefColumns() {
+        return core.refCols;
+    }
+
+    /**
+     * Returns the SQL for the expression in CHECK clause
+     */
+    public String getCheckSQL() {
+        return check.getSQL();
+    }
+
+    /**
+     * Returns true if the expression in CHECK is a simple IS NOT NULL
+     */
+    public boolean isNotNull() {
+        return isNotNull;
+    }
+
+    boolean hasColumnOnly(int colIndex) {
+
+        switch (constType) {
+
+            case SchemaObject.ConstraintTypes.CHECK :
+                return rangeVariable.usedColumns[colIndex] && ArrayUtil
+                    .countTrueElements(rangeVariable.usedColumns) == 1;
+
+            case SchemaObject.ConstraintTypes.PRIMARY_KEY :
+            case SchemaObject.ConstraintTypes.UNIQUE :
+                return core.mainCols.length == 1
+                       && core.mainCols[0] == colIndex;
+
+            case SchemaObject.ConstraintTypes.MAIN :
+                return core.mainCols.length == 1
+                       && core.mainCols[0] == colIndex
+                       && core.mainTable == core.refTable;
+
+            case SchemaObject.ConstraintTypes.FOREIGN_KEY :
+                return core.refCols.length == 1 && core.refCols[0] == colIndex
+                       && core.mainTable == core.refTable;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Constraint");
+        }
+    }
+
+    boolean hasColumnPlus(int colIndex) {
+
+        switch (constType) {
+
+            case SchemaObject.ConstraintTypes.CHECK :
+                return rangeVariable.usedColumns[colIndex] && ArrayUtil
+                    .countTrueElements(rangeVariable.usedColumns) > 1;
+
+            case SchemaObject.ConstraintTypes.PRIMARY_KEY :
+            case SchemaObject.ConstraintTypes.UNIQUE :
+                return core.mainCols.length != 1
+                       && ArrayUtil.find(core.mainCols, colIndex) != -1;
+
+            case SchemaObject.ConstraintTypes.MAIN :
+                return ArrayUtil.find(core.mainCols, colIndex) != -1
+                       && (core.mainCols.length != 1
+                           || core.mainTable != core.refTable);
+
+            case SchemaObject.ConstraintTypes.FOREIGN_KEY :
+                return ArrayUtil.find(core.refCols, colIndex) != -1
+                       && (core.mainCols.length != 1
+                           || core.mainTable == core.refTable);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Constraint");
+        }
+    }
+
+    boolean hasColumn(int colIndex) {
+
+        switch (constType) {
+
+            case SchemaObject.ConstraintTypes.CHECK :
+                return rangeVariable.usedColumns[colIndex];
+
+            case SchemaObject.ConstraintTypes.PRIMARY_KEY :
+            case SchemaObject.ConstraintTypes.UNIQUE :
+            case SchemaObject.ConstraintTypes.MAIN :
+                return ArrayUtil.find(core.mainCols, colIndex) != -1;
+
+            case SchemaObject.ConstraintTypes.FOREIGN_KEY :
+                return ArrayUtil.find(core.refCols, colIndex) != -1;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Constraint");
+        }
+    }
+
+// fredt@users 20020225 - patch 1.7.0 by fredt - duplicate constraints
+
+    /**
+     * Compares this with another constraint column set. This is used only for
+     * UNIQUE constraints.
+     */
+    boolean isUniqueWithColumns(int[] cols) {
+
+        if (constType != SchemaObject.ConstraintTypes.UNIQUE
+                || core.mainCols.length != cols.length) {
+            return false;
+        }
+
+        return ArrayUtil.haveEqualSets(core.mainCols, cols, cols.length);
+    }
+
+    /**
+     * Compares this with another constraint column set. This implementation
+     * only checks FOREIGN KEY constraints.
+     */
+    boolean isEquivalent(Table mainTable, int[] mainCols, Table refTable,
+                         int[] refCols) {
+
+        if (constType != SchemaObject.ConstraintTypes.MAIN
+                && constType != SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+            return false;
+        }
+
+        if (mainTable != core.mainTable || refTable != core.refTable) {
+            return false;
+        }
+
+        return ArrayUtil.areEqualSets(core.mainCols, mainCols)
+               && ArrayUtil.areEqualSets(core.refCols, refCols);
+    }
+
+    /**
+     * Used to update constrains to reflect structural changes in a table. Prior
+     * checks must ensure that this method does not throw.
+     *
+     * @param session Session
+     * @param oldTable reference to the old version of the table
+     * @param newTable referenct to the new version of the table
+     * @param colIndex index at which table column is added or removed
+     * @param adjust -1, 0, +1 to indicate if column is added or removed
+     * @
+     */
+    void updateTable(Session session, Table oldTable, Table newTable,
+                     int colIndex, int adjust) {
+
+        if (oldTable == core.mainTable) {
+            core.mainTable = newTable;
+
+            if (core.mainIndex != null) {
+                core.mainIndex =
+                    core.mainTable.getIndex(core.mainIndex.getName().name);
+                core.mainCols = ArrayUtil.toAdjustedColumnArray(core.mainCols,
+                        colIndex, adjust);
+
+                core.mainIndex.setTable(newTable);
+            }
+        }
+
+        if (oldTable == core.refTable) {
+            core.refTable = newTable;
+
+            if (core.refIndex != null) {
+                core.refIndex =
+                    core.refTable.getIndex(core.refIndex.getName().name);
+                core.refCols = ArrayUtil.toAdjustedColumnArray(core.refCols,
+                        colIndex, adjust);
+
+                core.refIndex.setTable(newTable);
+            }
+        }
+
+        // CHECK
+        if (constType == SchemaObject.ConstraintTypes.CHECK) {
+            recompile(session, newTable);
+        }
+    }
+
+    /**
+     * Checks for foreign key or check constraint violation when
+     * inserting a row into the child table.
+     */
+    void checkInsert(Session session, Table table, Object[] data,
+                     boolean isNew) {
+
+        switch (constType) {
+
+            case SchemaObject.ConstraintTypes.CHECK :
+                if (!isNotNull) {
+                    checkCheckConstraint(session, table, data);
+                }
+
+                return;
+
+            case SchemaObject.ConstraintTypes.FOREIGN_KEY :
+                PersistentStore store =
+                    session.sessionData.getRowStore(core.mainTable);
+
+                if (ArrayUtil.hasNull(data, core.refCols)) {
+                    if (core.matchType == OpTypes.MATCH_SIMPLE) {
+                        return;
+                    }
+
+                    if (core.refCols.length == 1) {
+                        return;
+                    }
+
+                    if (ArrayUtil.hasAllNull(data, core.refCols)) {
+                        return;
+                    }
+
+                    // core.matchType == OpTypes.MATCH_FULL
+                } else if (core.mainIndex.existsParent(session, store, data,
+                                                       core.refCols)) {
+                    return;
+                }
+
+                throw getException(data);
+        }
+    }
+
+    /*
+     * Tests a row against this CHECK constraint.
+     */
+    void checkCheckConstraint(Session session, Table table, Object[] data) {
+
+/*
+        if (session.compiledStatementExecutor.rangeIterators[1] == null) {
+            session.compiledStatementExecutor.rangeIterators[1] =
+                rangeVariable.getIterator(session);
+        }
+*/
+        RangeIteratorBase it =
+            session.sessionContext.getCheckIterator(rangeVariable);
+
+        it.currentData = data;
+
+        boolean nomatch = Boolean.FALSE.equals(check.getValue(session));
+
+        it.currentData = null;
+
+        if (nomatch) {
+            String[] info = new String[] {
+                name.name, table.getName().name
+            };
+
+            throw Error.error(null, ErrorCode.X_23513, ErrorCode.CONSTRAINT,
+                              info);
+        }
+    }
+
+    void checkCheckConstraint(Session session, Table table, Object data) {
+
+        session.sessionData.currentValue = data;
+
+        boolean nomatch = Boolean.FALSE.equals(check.getValue(session));
+
+        session.sessionData.currentValue = null;
+
+        if (nomatch) {
+            if (table == null) {
+                throw Error.error(ErrorCode.X_23513, name.name);
+            } else {
+                String[] info = new String[] {
+                    name.name, table.getName().name
+                };
+
+                throw Error.error(null, ErrorCode.X_23513,
+                                  ErrorCode.CONSTRAINT, info);
+            }
+        }
+    }
+
+    public HsqlException getException(Object[] data) {
+
+        switch (this.constType) {
+
+            case SchemaObject.ConstraintTypes.CHECK : {
+                String[] info = new String[]{ name.name };
+
+                return Error.error(null, ErrorCode.X_23513,
+                                   ErrorCode.CONSTRAINT, info);
+            }
+            case SchemaObject.ConstraintTypes.FOREIGN_KEY : {
+                StringBuffer sb = new StringBuffer();
+
+                for (int i = 0; i < core.refCols.length; i++) {
+                    Object o = data[core.refCols[i]];
+
+                    sb.append(core.refTable.getColumnTypes()[core.refCols[i]]
+                        .convertToString(o));
+                    sb.append(',');
+                }
+
+                String[] info = new String[] {
+                    getName().statementName,
+                    core.refTable.getName().statementName, sb.toString()
+                };
+
+                return Error.error(null, ErrorCode.X_23503,
+                                   ErrorCode.CONSTRAINT, info);
+            }
+            case SchemaObject.ConstraintTypes.PRIMARY_KEY :
+            case SchemaObject.ConstraintTypes.UNIQUE : {
+                StringBuffer sb = new StringBuffer();
+
+                for (int i = 0; i < core.mainCols.length; i++) {
+                    Object o = data[core.mainCols[i]];
+
+                    sb.append(core.mainTable.colTypes[core.mainCols[i]]
+                        .convertToString(o));
+                    sb.append(',');
+                }
+
+                return Error.error(null, ErrorCode.X_23505,
+                                   ErrorCode.CONSTRAINT, new String[] {
+                    getName().statementName,
+                    core.mainTable.getName().statementName, sb.toString()
+                });
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Constraint");
+        }
+    }
+
+// fredt@users 20020225 - patch 1.7.0 - cascading deletes
+
+    /**
+     * New method to find any referencing row for a foreign key (finds row in
+     * child table). If ON DELETE CASCADE is specified for this constraint, then
+     * the method finds the first row among the rows of the table ordered by the
+     * index and doesn't throw. Without ON DELETE CASCADE, the method attempts
+     * to finds any row that exists. If no
+     * row is found, null is returned. (fredt@users)
+     *
+     * @param session Session
+     * @param row array of objects for a database row
+     * @param delete should we allow 'ON DELETE CASCADE' or 'ON UPDATE CASCADE'
+     * @return iterator
+     * @
+     */
+    RowIterator findFkRef(Session session, Object[] row) {
+
+        if (row == null || ArrayUtil.hasNull(row, core.mainCols)) {
+            return core.refIndex.emptyIterator();
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(core.refTable);
+
+        return core.refIndex.findFirstRow(session, store, row, core.mainCols);
+    }
+
+    /**
+     * Check used before creating a new foreign key cosntraint, this method
+     * checks all rows of a table to ensure they all have a corresponding
+     * row in the main table.
+     */
+    void checkReferencedRows(Session session, Table table) {
+
+        RowIterator it = table.rowIterator(session);
+
+        while (true) {
+            Row row = it.getNextRow();
+
+            if (row == null) {
+                break;
+            }
+
+            Object[] rowData = row.getData();
+
+            checkInsert(session, table, rowData, false);
+        }
+    }
+
+    public Expression getCheckExpression() {
+        return check;
+    }
+
+    public OrderedHashSet getCheckColumnExpressions() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        check.collectAllExpressions(set, Expression.columnExpressionSet,
+                                    Expression.emptyExpressionSet);
+
+        return set;
+    }
+
+    void recompile(Session session, Table newTable) {
+
+        String    ddl     = check.getSQL();
+        Scanner   scanner = new Scanner(ddl);
+        ParserDQL parser  = new ParserDQL(session, scanner);
+
+        parser.read();
+
+        parser.isCheckOrTriggerCondition = true;
+
+        Expression condition = parser.XreadBooleanValueExpression();
+
+        check = condition;
+
+        // this workaround is here to stop LIKE optimisation (for proper scripting)
+        QuerySpecification s = Expression.getCheckSelect(session, newTable,
+            check);
+
+        rangeVariable = s.rangeVariables[0];
+
+        rangeVariable.setForCheckConstraint();
+    }
+
+    void prepareCheckConstraint(Session session, Table table,
+                                boolean checkValues) {
+
+        // to ensure no subselects etc. are in condition
+        check.checkValidCheckConstraint();
+
+        if (table == null) {
+            check.resolveTypes(session, null);
+        } else {
+            QuerySpecification s = Expression.getCheckSelect(session, table,
+                check);
+            Result r = s.getResult(session, 1);
+
+            if (r.getNavigator().getSize() != 0) {
+                String[] info = new String[] {
+                    table.getName().name, ""
+                };
+
+                throw Error.error(null, ErrorCode.X_23513,
+                                  ErrorCode.CONSTRAINT, info);
+            }
+
+            rangeVariable = s.rangeVariables[0];
+
+            // removes reference to the Index object in range variable
+            rangeVariable.setForCheckConstraint();
+        }
+
+        if (check.getType() == OpTypes.NOT
+                && check.getLeftNode().getType() == OpTypes.IS_NULL
+                && check.getLeftNode().getLeftNode().getType()
+                   == OpTypes.COLUMN) {
+            notNullColumnIndex =
+                check.getLeftNode().getLeftNode().getColumnIndex();
+            isNotNull = true;
+        }
+    }
+}
diff --git a/src/org/hsqldb/ConstraintCore.java b/src/org/hsqldb/ConstraintCore.java
new file mode 100644
index 0000000..6edafa5
--- /dev/null
+++ b/src/org/hsqldb/ConstraintCore.java
@@ -0,0 +1,137 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.index.Index;
+
+/**
+ * This class consists of the data structure for a Constraint. This
+ * structure is shared between two Constraint Objects that together form a
+ * foreign key constraint. This simplifies structural modifications to a
+ * table. When changes to the column indexes are applied to the table's
+ * Constraint Objects, they are reflected in the Constraint Objects of any
+ * other table that shares a foreign key constraint with the modified
+ * table.
+ *
+ * New class partly based on Hypersonic code
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.1
+ */
+class ConstraintCore {
+
+    // refName and mainName are for foreign keys only
+    HsqlName refName;
+    HsqlName mainName;
+    HsqlName uniqueName;
+    HsqlName refTableName;
+    HsqlName mainTableName;
+
+    // Main is the sole table in a UNIQUE or PRIMARY constraint
+    // Or the table that is referenced by FOREIGN KEY ... REFERENCES
+    Table mainTable;
+    int[] mainCols;
+    Index mainIndex;
+
+    // Ref is the table that has a reference to the main table
+    Table   refTable;
+    int[]   refCols;
+    Index   refIndex;
+    int     deleteAction;
+    int     updateAction;
+    boolean hasUpdateAction;
+    boolean hasDeleteAction;
+    int     matchType;
+
+    //
+    ConstraintCore duplicate() {
+
+        ConstraintCore copy = new ConstraintCore();
+
+        copy.refName      = refName;
+        copy.mainName     = mainName;
+        copy.uniqueName   = uniqueName;
+        copy.mainTable    = mainTable;
+        copy.mainCols     = mainCols;
+        copy.mainIndex    = mainIndex;
+        copy.refTable     = refTable;
+        copy.refCols      = refCols;
+        copy.refIndex     = refIndex;
+        copy.deleteAction = deleteAction;
+        copy.updateAction = updateAction;
+        copy.matchType    = matchType;
+
+        return copy;
+    }
+}
diff --git a/src/org/hsqldb/Database.java b/src/org/hsqldb/Database.java
new file mode 100644
index 0000000..038e590
--- /dev/null
+++ b/src/org/hsqldb/Database.java
@@ -0,0 +1,654 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.dbinfo.DatabaseInformation;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.persist.LobManager;
+import org.hsqldb.persist.Logger;
+import org.hsqldb.persist.PersistentStoreCollectionDatabase;
+import org.hsqldb.result.Result;
+import org.hsqldb.rights.GranteeManager;
+import org.hsqldb.rights.User;
+import org.hsqldb.rights.UserManager;
+import org.hsqldb.types.Type;
+
+// incorporates following contributions
+// boucherb@users - javadoc comments
+// Brendan Ryan - data files in Jar
+// Ocke Jansen oj@openoffice.org - file access api
+
+/**
+ * Database is the root class for HSQL Database Engine database. <p>
+ *
+ * It holds the data structures that form an HSQLDB database instance.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class Database {
+
+    int                   databaseID;
+    String                databaseUniqueName;
+    String                databaseType;
+    private final String  canonicalPath;
+    public HsqlProperties urlProperties;
+    private final String  path;
+    DatabaseInformation   dbInfo;
+
+    /** indicates the state of the database */
+    private int   dbState;
+    public Logger logger;
+
+    /** true means that all tables are readonly. */
+    boolean databaseReadOnly;
+
+    /**
+     * true means that all CACHED and TEXT tables are readonly.
+     *  MEMORY tables are updatable but updates are not persisted.
+     */
+    private boolean filesReadOnly;
+
+    /** true means filesReadOnly but CACHED and TEXT tables are disallowed */
+    private boolean               filesInJar;
+    public boolean                sqlEnforceRefs;
+    public boolean                sqlEnforceSize;
+    public boolean                sqlEnforceNames;
+    private boolean               isReferentialIntegrity;
+    public HsqlDatabaseProperties databaseProperties;
+    private final boolean         shutdownOnNoConnection;
+    int                           resultMaxMemoryRows;
+
+    // schema invarient objects
+    public UserManager     userManager;
+    public GranteeManager  granteeManager;
+    public HsqlNameManager nameManager;
+
+    // session related objects
+    public SessionManager     sessionManager;
+    public TransactionManager txManager;
+    public int defaultIsolationLevel = SessionInterface.TX_READ_COMMITTED;
+
+    // schema objects
+    public SchemaManager schemaManager;
+
+    //
+    public PersistentStoreCollectionDatabase persistentStoreCollection;
+
+    //
+    public LobManager lobManager;
+    public Collation  collation;
+
+    //
+    public static final int DATABASE_ONLINE       = 1;
+    public static final int DATABASE_OPENING      = 2;
+    public static final int DATABASE_CLOSING      = 3;
+    public static final int DATABASE_SHUTDOWN     = 4;
+    public static final int CLOSEMODE_IMMEDIATELY = 1;
+    public static final int CLOSEMODE_NORMAL      = 2;
+    public static final int CLOSEMODE_COMPACT     = 3;
+    public static final int CLOSEMODE_SCRIPT      = 4;
+
+    /**
+     *  Constructs a new Database object.
+     *
+     * @param type is the type of the database: "mem:", "file:", "res:"
+     * @param path is the given path to the database files
+     * @param canonicalPath is the canonical path
+     * @param props property overrides placed on the connect URL
+     * @exception  HsqlException if the specified name and path
+     *      combination is illegal or unavailable, or the database files the
+     *      name and path resolves to are in use by another process
+     */
+    Database(String type, String path, String canonicalPath,
+             HsqlProperties props) {
+
+        setState(Database.DATABASE_SHUTDOWN);
+
+        this.databaseType  = type;
+        this.path          = path;
+        this.canonicalPath = canonicalPath;
+        this.urlProperties = props;
+
+        if (databaseType == DatabaseURL.S_RES) {
+            filesInJar    = true;
+            filesReadOnly = true;
+        }
+
+        logger = new Logger(this);
+        shutdownOnNoConnection =
+            urlProperties.isPropertyTrue(HsqlDatabaseProperties.url_shutdown);
+        lobManager = new LobManager(this);
+    }
+
+    /**
+     * Opens this database.  The database should be opened after construction.
+     */
+    synchronized void open() {
+
+        if (!isShutdown()) {
+            return;
+        }
+
+        reopen();
+    }
+
+    /**
+     * Opens this database.  The database should be opened after construction.
+     * or reopened by the close(int closemode) method during a
+     * "shutdown compact". Closes the log if there is an error.
+     */
+    void reopen() {
+
+        boolean isNew = false;
+
+        setState(DATABASE_OPENING);
+
+        try {
+            nameManager    = new HsqlNameManager(this);
+            granteeManager = new GranteeManager(this);
+            userManager    = new UserManager(this);
+            schemaManager  = new SchemaManager(this);
+            persistentStoreCollection =
+                new PersistentStoreCollectionDatabase();
+            isReferentialIntegrity = true;
+            sessionManager         = new SessionManager(this);
+            collation              = collation.getDefaultInstance();
+            dbInfo = DatabaseInformation.newDatabaseInformation(this);
+            txManager              = new TransactionManager2PL(this);
+
+            lobManager.createSchema();
+            sessionManager.getSysLobSession().setSchema(
+                SqlInvariants.LOBS_SCHEMA);
+
+            schemaManager.setSchemaChangeTimestamp();
+
+            // completed metadata
+            logger.openPersistence();
+
+            isNew = logger.isNewDatabase;
+
+            if (isNew) {
+                String username = urlProperties.getProperty("user", "SA");
+
+                String password = urlProperties.getProperty("password", "");
+
+                userManager.createFirstUser(username, password);
+                schemaManager.createPublicSchema();
+                lobManager.initialiseLobSpace();
+                logger.checkpoint(false);
+            }
+
+            lobManager.open();
+            dbInfo.setWithContent(true);
+        } catch (Throwable e) {
+            logger.closePersistence(Database.CLOSEMODE_IMMEDIATELY);
+            logger.releaseLock();
+            setState(DATABASE_SHUTDOWN);
+            clearStructures();
+            DatabaseManager.removeDatabase(this);
+
+            if (!(e instanceof HsqlException)) {
+                e = Error.error(ErrorCode.GENERAL_ERROR, e);
+            }
+
+            logger.logSevereEvent("could not reopen database", e);
+
+            throw (HsqlException) e;
+        }
+
+        setState(DATABASE_ONLINE);
+    }
+
+    /**
+     * Clears the data structuress, making them elligible for garbage collection.
+     */
+    void clearStructures() {
+
+        if (schemaManager != null) {
+            schemaManager.clearStructures();
+        }
+
+        granteeManager = null;
+        userManager    = null;
+        nameManager    = null;
+        schemaManager  = null;
+        sessionManager = null;
+        dbInfo         = null;
+    }
+
+    /**
+     *  Returns the database ID.
+     */
+    public int getDatabaseID() {
+        return this.databaseID;
+    }
+
+    /**
+     * Returns a unique String identifier for the database.
+     */
+    public String getUniqueName() {
+        return databaseUniqueName;
+    }
+
+    public void setUniqueName(String name) {
+        databaseUniqueName = name;
+    }
+
+    /**
+     *  Returns the type of the database: "mem", "file", "res"
+     */
+    public String getType() {
+        return databaseType;
+    }
+
+    /**
+     *  Returns the path of the database
+     */
+    public String getPath() {
+        return path;
+    }
+
+    public HsqlName getCatalogName() {
+        return nameManager.getCatalogName();
+    }
+
+    /**
+     *  Returns the database properties.
+     */
+    public HsqlDatabaseProperties getProperties() {
+        return databaseProperties;
+    }
+
+    /**
+     * Returns the SessionManager for the database.
+     */
+    public SessionManager getSessionManager() {
+        return sessionManager;
+    }
+
+    public boolean isReadOnly() {
+        return databaseReadOnly;
+    }
+
+    /**
+     *  Returns true if database has been shut down, false otherwise
+     */
+    synchronized boolean isShutdown() {
+        return dbState == DATABASE_SHUTDOWN;
+    }
+
+    /**
+     *  Constructs a new Session that operates within (is connected to) the
+     *  context of this Database object. <p>
+     *
+     *  If successful, the new Session object initially operates on behalf of
+     *  the user specified by the supplied user name.
+     *
+     * Throws if username or password is invalid.
+     */
+    synchronized Session connect(String username, String password,
+                                 String zoneString, int timeZoneSeconds) {
+
+        if (username.equalsIgnoreCase("SA")) {
+            username = "SA";
+        }
+
+        User user = userManager.getUser(username, password);
+        Session session = sessionManager.newSession(this, user,
+            databaseReadOnly, false, zoneString, timeZoneSeconds);
+
+        return session;
+    }
+
+    /**
+     *  Puts this Database object in global read-only mode. After
+     *  this call, all existing and future sessions are limited to read-only
+     *  transactions. Any following attempts to update the state of the
+     *  database will result in throwing an HsqlException.
+     */
+    public void setReadOnly() {
+        databaseReadOnly = true;
+        filesReadOnly    = true;
+    }
+
+    /**
+     * After this call all CACHED and TEXT tables will be set to read-only
+     * mode. Changes to MEMORY tables will NOT
+     * be stored or updated in the script file. This mode is intended for
+     * use with read-only media where data should not be persisted.
+     */
+    public void setFilesReadOnly() {
+        filesReadOnly = true;
+    }
+
+    /**
+     * Is this in filesReadOnly mode?
+     */
+    public boolean isFilesReadOnly() {
+        return filesReadOnly;
+    }
+
+    /**
+     * Is this in filesInJar mode?
+     */
+    public boolean isFilesInJar() {
+        return filesInJar;
+    }
+
+    /**
+     *  Returns the UserManager for this Database.
+     */
+    public UserManager getUserManager() {
+        return userManager;
+    }
+
+    /**
+     *  Returns the GranteeManager for this Database.
+     */
+    public GranteeManager getGranteeManager() {
+        return granteeManager;
+    }
+
+    /**
+     *  Sets the isReferentialIntegrity attribute.
+     */
+    public void setReferentialIntegrity(boolean ref) {
+        isReferentialIntegrity = ref;
+    }
+
+    /**
+     *  Is referential integrity currently enforced?
+     */
+    public boolean isReferentialIntegrity() {
+        return isReferentialIntegrity;
+    }
+
+    public int getResultMaxMemoryRows() {
+        return resultMaxMemoryRows;
+    }
+
+    public void setResultMaxMemoryRows(int size) {
+        resultMaxMemoryRows = size;
+    }
+
+    public void setStrictNames(boolean mode) {
+        sqlEnforceNames = mode;
+    }
+
+    public void setStrictColumnSize(boolean mode) {
+        sqlEnforceSize = mode;
+    }
+
+    public void setStrictReferences(boolean mode) {
+        sqlEnforceRefs = mode;
+    }
+
+    public int getDefaultIsolationLevel() {
+        return defaultIsolationLevel;
+    }
+
+    /**
+     *  Called by the garbage collector on this Databases object when garbage
+     *  collection determines that there are no more references to it.
+     */
+    protected void finalize() {
+
+        if (getState() != DATABASE_ONLINE) {
+            return;
+        }
+
+        try {
+            close(CLOSEMODE_IMMEDIATELY);
+        } catch (HsqlException e) {    // it's too late now
+        }
+    }
+
+    void closeIfLast() {
+
+        if (shutdownOnNoConnection && sessionManager.isEmpty()
+                && dbState == this.DATABASE_ONLINE) {
+            try {
+                close(CLOSEMODE_NORMAL);
+            } catch (HsqlException e) {}
+        }
+    }
+
+    /**
+     *  Closes this Database using the specified mode. <p>
+     *
+     * <ol>
+     *  <LI> closemode -1 performs SHUTDOWN IMMEDIATELY, equivalent
+     *       to a poweroff or crash.
+     *
+     *  <LI> closemode 0 performs a normal SHUTDOWN that
+     *      checkpoints the database normally.
+     *
+     *  <LI> closemode 1 performs a shutdown compact that scripts
+     *       out the contents of any CACHED tables to the log then
+     *       deletes the existing *.data file that contains the data
+     *       for all CACHED table before the normal checkpoint process
+     *       which in turn creates a new, compact *.data file.
+     * </ol>
+     */
+    public void close(int closemode) {
+
+        HsqlException he = null;
+
+        setState(DATABASE_CLOSING);
+        sessionManager.closeAllSessions();
+        sessionManager.clearAll();
+
+        if (filesReadOnly) {
+            closemode = CLOSEMODE_IMMEDIATELY;
+        }
+
+        /**
+         * @todo  fredt - impact of possible error conditions in closing the log
+         * should be investigated for the CLOSEMODE_COMPACT mode
+         */
+        logger.closePersistence(closemode);
+        lobManager.close();
+
+        try {
+            if (closemode == CLOSEMODE_COMPACT) {
+                clearStructures();
+                reopen();
+                setState(DATABASE_CLOSING);
+                logger.closePersistence(CLOSEMODE_NORMAL);
+                lobManager.close();
+            }
+        } catch (Throwable t) {
+            if (t instanceof HsqlException) {
+                he = (HsqlException) t;
+            } else {
+                he = Error.error(ErrorCode.GENERAL_ERROR, t.toString());
+            }
+        }
+
+        logger.releaseLock();
+        setState(DATABASE_SHUTDOWN);
+        clearStructures();
+
+        // fredt - this could change to avoid removing a db from the
+        // DatabaseManager repository if there are pending getDatabase()
+        // calls
+        DatabaseManager.removeDatabase(this);
+
+        if (he != null) {
+            throw he;
+        }
+    }
+
+    private synchronized void setState(int state) {
+        dbState = state;
+    }
+
+    synchronized int getState() {
+        return dbState;
+    }
+
+    String getStateString() {
+
+        int state = getState();
+
+        switch (state) {
+
+            case DATABASE_CLOSING :
+                return "DATABASE_CLOSING";
+
+            case DATABASE_ONLINE :
+                return "DATABASE_ONLINE";
+
+            case DATABASE_OPENING :
+                return "DATABASE_OPENING";
+
+            case DATABASE_SHUTDOWN :
+                return "DATABASE_SHUTDOWN";
+
+            default :
+                return "UNKNOWN";
+        }
+    }
+
+    public String[] getSettingsSQL() {
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        if (!getCatalogName().name.equals(
+                HsqlNameManager.DEFAULT_CATALOG_NAME)) {
+            String name = getCatalogName().statementName;
+
+            list.add("ALTER CATALOG PUBLIC RENAME TO " + name);
+        }
+
+        if (collation.collator != null) {
+            String name = collation.getName().statementName;
+
+            list.add("SET DATABASE COLLATION " + name);
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    /**
+     * Returns the schema and authorisation statements for the database.
+     */
+    public Result getScript(boolean indexRoots) {
+
+        Result r = Result.newSingleColumnResult("COMMAND", Type.SQL_VARCHAR);
+
+        // properties
+        String[] list = logger.getPropertiesSQL();
+
+        addRows(r, list);
+
+        list = getSettingsSQL();
+
+        addRows(r, list);
+
+        list = getGranteeManager().getSQL();
+
+        addRows(r, list);
+
+        // schemas and schema objects such as tables, sequences, etc.
+        list = schemaManager.getSQLArray();
+
+        addRows(r, list);
+
+        // optional comments on tables etc.
+        list = schemaManager.getCommentsArray();
+
+        addRows(r, list);
+
+        // user session start schema names
+        list = getUserManager().getInitialSchemaSQL();
+
+        addRows(r, list);
+
+        // grantee rights
+        list = getGranteeManager().getRightstSQL();
+
+        addRows(r, list);
+
+        // index roots
+        if (indexRoots) {
+            list = schemaManager.getIndexRootsSQL();
+
+            addRows(r, list);
+        }
+
+        // text headers
+        list = schemaManager.getTablePropsSQL(!indexRoots);
+
+        addRows(r, list);
+
+        return r;
+    }
+
+    private static void addRows(Result r, String[] sql) {
+
+        if (sql == null) {
+            return;
+        }
+
+        for (int i = 0; i < sql.length; i++) {
+            String[] s = new String[1];
+
+            s[0] = sql[i];
+
+            r.initialiseNavigator().add(s);
+        }
+    }
+
+    public String getURI() {
+        return databaseType + canonicalPath;
+    }
+
+    public String getCanonicalPath() {
+        return canonicalPath;
+    }
+
+    public HsqlProperties getURLProperties() {
+        return urlProperties;
+    }
+}
diff --git a/src/org/hsqldb/DatabaseManager.java b/src/org/hsqldb/DatabaseManager.java
new file mode 100644
index 0000000..abba419
--- /dev/null
+++ b/src/org/hsqldb/DatabaseManager.java
@@ -0,0 +1,481 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.util.Vector;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.HsqlTimer;
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.server.Server;
+import org.hsqldb.server.ServerConstants;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Handles initial attempts to connect to HSQLDB databases within the JVM
+ * (or a classloader within the JVM). Opens the database if it is not open
+ * or connects to it if it is already open. This allows the same database to
+ * be used by different instances of Server and by direct connections.<p>
+ *
+ * Maintains a map of Server instances and notifies each server when its
+ * database has shut down.<p>
+ *
+ * Maintains a reference to the timer used for file locks and logging.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.7.2
+ */
+public class DatabaseManager {
+
+    // Database and Server registry
+
+    /** provides unique ID's for the Databases currently in registry */
+    private static int dbIDCounter;
+
+    /** name to Database mapping for mem: databases */
+    static final HashMap memDatabaseMap = new HashMap();
+
+    /** File to Database mapping for file: databases */
+    static final HashMap fileDatabaseMap = new HashMap();
+
+    /** File to Database mapping for res: databases */
+    static final HashMap resDatabaseMap = new HashMap();
+
+    /** id number to Database for Databases currently in registry */
+    static final IntKeyHashMap databaseIDMap = new IntKeyHashMap();
+
+    /**
+     * Returns a vector containing the URI (type + path) for all the databases.
+     */
+    public static Vector getDatabaseURIs() {
+
+        Vector   v  = new Vector();
+        Iterator it = databaseIDMap.values().iterator();
+
+        while (it.hasNext()) {
+            Database db = (Database) it.next();
+
+            v.addElement(db.getURI());
+        }
+
+        return v;
+    }
+
+    /**
+     * Closes all the databases using the given mode.<p>
+     *
+     * CLOSEMODE_IMMEDIATELY = -1;
+     * CLOSEMODE_NORMAL      = 0;
+     * CLOSEMODE_COMPACT     = 1;
+     * CLOSEMODE_SCRIPT      = 2;
+     */
+    public static void closeDatabases(int mode) {
+
+        Iterator it = databaseIDMap.values().iterator();
+
+        while (it.hasNext()) {
+            Database db = (Database) it.next();
+
+            try {
+                db.close(mode);
+            } catch (HsqlException e) {}
+        }
+    }
+
+    /**
+     * Used by server to open a new session
+     */
+    public static Session newSession(int dbID, String user, String password,
+                                     String zoneString, int timeZoneSeconds) {
+
+        Database db = (Database) databaseIDMap.get(dbID);
+
+        if (db == null) {
+            return null;
+        }
+
+        Session session = db.connect(user, password, zoneString,
+                                     timeZoneSeconds);
+
+        session.isNetwork = true;
+
+        return session;
+    }
+
+    /**
+     * Used by in-process connections and by Servlet
+     */
+    public static Session newSession(String type, String path, String user,
+                                     String password, HsqlProperties props,
+                                     String zoneString, int timeZoneSeconds) {
+
+        Database db = getDatabase(type, path, props);
+
+        if (db == null) {
+            return null;
+        }
+
+        return db.connect(user, password, zoneString, timeZoneSeconds);
+    }
+
+    /**
+     * Returns an existing session. Used with repeat HTTP connections
+     * belonging to the same JDBC Conenction / HSQL Session pair.
+     */
+    public static Session getSession(int dbId, long sessionId) {
+
+        Database db = (Database) databaseIDMap.get(dbId);
+
+        return db == null ? null
+                          : db.sessionManager.getSession(sessionId);
+    }
+
+    /**
+     * Used by server to open or create a database
+     */
+
+// loosecannon1@users 1.7.2 patch properties on the JDBC URL
+    public static int getDatabase(String type, String path, Server server,
+                                  HsqlProperties props) {
+
+        Database db = getDatabase(type, path, props);
+
+        registerServer(server, db);
+
+        return db.databaseID;
+    }
+
+    /**
+     * This has to be improved once a threading model is in place.
+     * Current behaviour:
+     *
+     * Attempts to connect to different databases do not block. Two db's can
+     * open simultaneously.
+     *
+     * Attempts to connect to a db while it is opening or closing will block
+     * until the db is open or closed. At this point the db state is either
+     * DATABASE_ONLINE (after db.open() has returned) which allows a new
+     * connection to be made, or the state is DATABASE_SHUTDOWN which means
+     * the db can be reopened for the new connection).
+     *
+     */
+
+// loosecannon1@users 1.7.2 patch properties on the JDBC URL
+    public static Database getDatabase(String type, String path,
+                                       HsqlProperties props) {
+
+        // If the (type, path) pair does not correspond to a registered
+        // instance, then getDatabaseObject() returns a newly constructed
+        // and registered Database instance.
+        // The database state will be DATABASE_SHUTDOWN,
+        // which means that the switch below will attempt to
+        // open the database instance.
+        Database db = getDatabaseObject(type, path, props);
+
+        synchronized (db) {
+            switch (db.getState()) {
+
+                case Database.DATABASE_ONLINE :
+                    break;
+
+                case Database.DATABASE_SHUTDOWN :
+
+                    // if the database was shutdown while this attempt
+                    // was waiting, add the database back to the registry
+                    if (lookupDatabaseObject(type, path) == null) {
+                        addDatabaseObject(type, path, db);
+                    }
+
+                    db.open();
+                    break;
+
+                // This state will currently not be reached as Database.Close() is
+                // called while a lock is held on the database.
+                // If we remove the lock from this method and a database is
+                // being shutdown by a thread and in the meantime another thread
+                // attempts to connect to the db. The threads could belong to
+                // different server instances or be in-process.
+                case Database.DATABASE_CLOSING :
+
+                // this case will not be reached as the state is set and
+                // cleared within the db.open() call above, which is called
+                // from this synchronized block
+                // it is here simply as a placeholder for future development
+                case Database.DATABASE_OPENING :
+                    throw Error.error(ErrorCode.LOCK_FILE_ACQUISITION_FAILURE,
+                                      ErrorCode.M_DatabaseManager_getDatabase);
+            }
+        }
+
+        return db;
+    }
+
+// loosecannon1@users 1.7.2 patch properties on the JDBC URL
+    private static synchronized Database getDatabaseObject(String type,
+            String path, HsqlProperties props) {
+
+        Database db;
+        String   key = path;
+        HashMap  databaseMap;
+
+        if (type == DatabaseURL.S_FILE) {
+            databaseMap = fileDatabaseMap;
+            key         = filePathToKey(path);
+            db          = (Database) databaseMap.get(key);
+
+            if (db == null) {
+                if (databaseMap.size() > 0) {
+                    Iterator it = databaseMap.keySet().iterator();
+
+                    while (it.hasNext()) {
+                        String current = (String) it.next();
+
+                        if (key.equalsIgnoreCase(current)) {
+                            key = current;
+
+                            break;
+                        }
+                    }
+                }
+            }
+        } else if (type == DatabaseURL.S_RES) {
+            databaseMap = resDatabaseMap;
+        } else if (type == DatabaseURL.S_MEM) {
+            databaseMap = memDatabaseMap;
+        } else {
+            throw Error.runtimeError(ErrorCode.U_S0500, "DatabaseManager");
+        }
+
+        db = (Database) databaseMap.get(key);
+
+        if (db == null) {
+            db            = new Database(type, path, key, props);
+            db.databaseID = dbIDCounter;
+
+            databaseIDMap.put(dbIDCounter, db);
+
+            dbIDCounter++;
+
+            databaseMap.put(key, db);
+        }
+
+        return db;
+    }
+
+    /**
+     * Looks up database of a given type and path in the registry. Returns
+     * null if there is none.
+     */
+    public static synchronized Database lookupDatabaseObject(String type,
+            String path) {
+
+        Object  key = path;
+        HashMap databaseMap;
+
+        if (type == DatabaseURL.S_FILE) {
+            databaseMap = fileDatabaseMap;
+            key         = filePathToKey(path);
+        } else if (type == DatabaseURL.S_RES) {
+            databaseMap = resDatabaseMap;
+        } else if (type == DatabaseURL.S_MEM) {
+            databaseMap = memDatabaseMap;
+        } else {
+            throw (Error.runtimeError(ErrorCode.U_S0500, "DatabaseManager"));
+        }
+
+        return (Database) databaseMap.get(key);
+    }
+
+    /**
+     * Adds a database to the registry.
+     */
+    private static synchronized void addDatabaseObject(String type,
+            String path, Database db) {
+
+        Object  key = path;
+        HashMap databaseMap;
+
+        if (type == DatabaseURL.S_FILE) {
+            databaseMap = fileDatabaseMap;
+            key         = filePathToKey(path);
+        } else if (type == DatabaseURL.S_RES) {
+            databaseMap = resDatabaseMap;
+        } else if (type == DatabaseURL.S_MEM) {
+            databaseMap = memDatabaseMap;
+        } else {
+            throw Error.runtimeError(ErrorCode.U_S0500, "DatabaseManager");
+        }
+
+        databaseIDMap.put(db.databaseID, db);
+        databaseMap.put(key, db);
+    }
+
+    /**
+     * Removes the database from registry.
+     */
+    static void removeDatabase(Database database) {
+
+        int     dbID = database.databaseID;
+        String  type = database.getType();
+        String  path = database.getPath();
+        Object  key  = path;
+        HashMap databaseMap;
+
+        notifyServers(database);
+
+        if (type == DatabaseURL.S_FILE) {
+            databaseMap = fileDatabaseMap;
+            key         = filePathToKey(path);
+        } else if (type == DatabaseURL.S_RES) {
+            databaseMap = resDatabaseMap;
+        } else if (type == DatabaseURL.S_MEM) {
+            databaseMap = memDatabaseMap;
+        } else {
+            throw (Error.runtimeError(ErrorCode.U_S0500, "DatabaseManager"));
+        }
+
+        databaseIDMap.remove(dbID);
+        databaseMap.remove(key);
+
+        if (databaseIDMap.isEmpty()) {
+            ValuePool.resetPool();
+        }
+    }
+
+    /**
+     * Maintains a map of servers to sets of databases.
+     * Servers register each of their databases.
+     * When a database is shutdown, all the servers accessing it are notified.
+     * The database is then removed form the sets for all servers and the
+     * servers that have no other database are removed from the map.
+     */
+    static HashMap serverMap = new HashMap();
+
+    /**
+     * Deregisters a server completely.
+     */
+    public static void deRegisterServer(Server server) {
+        serverMap.remove(server);
+    }
+
+    /**
+     * Deregisters a server as serving a given database. Not yet used.
+     */
+    private static void deRegisterServer(Server server, Database db) {
+
+        Iterator it = serverMap.values().iterator();
+
+        for (; it.hasNext(); ) {
+            HashSet databases = (HashSet) it.next();
+
+            databases.remove(db);
+
+            if (databases.isEmpty()) {
+                it.remove();
+            }
+        }
+    }
+
+    /**
+     * Registers a server as serving a given database.
+     */
+    private static void registerServer(Server server, Database db) {
+
+        if (!serverMap.containsKey(server)) {
+            serverMap.put(server, new HashSet());
+        }
+
+        HashSet databases = (HashSet) serverMap.get(server);
+
+        databases.add(db);
+    }
+
+    /**
+     * Notifies all servers that serve the database that the database has been
+     * shutdown.
+     */
+    private static void notifyServers(Database db) {
+
+        Iterator it = serverMap.keySet().iterator();
+
+        for (; it.hasNext(); ) {
+            Server  server    = (Server) it.next();
+            HashSet databases = (HashSet) serverMap.get(server);
+
+            if (databases.contains(db)) {
+                server.notify(ServerConstants.SC_DATABASE_SHUTDOWN,
+                              db.databaseID);
+            }
+        }
+    }
+
+    static boolean isServerDB(Database db) {
+
+        Iterator it = serverMap.keySet().iterator();
+
+        for (; it.hasNext(); ) {
+            Server  server    = (Server) it.next();
+            HashSet databases = (HashSet) serverMap.get(server);
+
+            if (databases.contains(db)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    // Timer
+    private static final HsqlTimer timer = new HsqlTimer();
+
+    public static HsqlTimer getTimer() {
+        return timer;
+    }
+
+    // converts file path to database lookup key, converting any
+    // thrown exception to an HsqlException in the process
+    private static String filePathToKey(String path) {
+
+        try {
+            return FileUtil.getFileUtil().canonicalPath(path);
+        } catch (Exception e) {
+            return path;
+        }
+    }
+}
diff --git a/src/org/hsqldb/DatabaseURL.java b/src/org/hsqldb/DatabaseURL.java
new file mode 100644
index 0000000..8f2a4a8
--- /dev/null
+++ b/src/org/hsqldb/DatabaseURL.java
@@ -0,0 +1,341 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.util.Locale;
+
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.server.ServerConstants;
+
+/*
+ * Parses a connection URL into parts.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+
+// patch 1.9.0 by Blaine Simpson - IPv6 support
+public class DatabaseURL {
+
+    static final String        S_DOT               = ".";
+    public static final String S_MEM               = "mem:";
+    public static final String S_FILE              = "file:";
+    public static final String S_RES               = "res:";
+    public static final String S_ALIAS             = "alias:";
+    public static final String S_HSQL              = "hsql://";
+    public static final String S_HSQLS             = "hsqls://";
+    public static final String S_HTTP              = "http://";
+    public static final String S_HTTPS             = "https://";
+    public static final String S_URL_PREFIX        = "jdbc:hsqldb:";
+    public static final String url_connection_type = "connection_type";
+    public static final String url_database        = "database";
+
+    /**
+     * Returns true if type represents an in-process connection to a file backed
+     * database.
+     */
+    public static boolean isFileBasedDatabaseType(String type) {
+
+        if (type == S_FILE || type == S_RES) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true if type represents an in-process connection to database.
+     */
+    public static boolean isInProcessDatabaseType(String type) {
+
+        if (type == S_FILE || type == S_RES || type == S_MEM) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses the url into components that are returned in a properties object.
+     *
+     * <p> The following components are isolated:
+     *
+     * <p>
+     * <ul> url: the original url
+     *
+     * <p> connection_type: a static string that indicate the protocol. If the
+     * url does not begin with a valid protocol, null is returned by this method
+     * instead of the properties object.
+     *
+     * <p> host: name of host in networked modes in lowercase
+     *
+     * <p> port: port number in networked mode, or 0 if not present
+     *
+     * <p> path: path of the resource on server in networked modes, minimum
+     * (slash) with path elements appended apart from servlet path which is
+     * (slash) plus the name of the servlet
+     *
+     * <p> database: database name. For memory, networked modes,
+     * this is returned in lowercase, for file: and res: databases the original case of
+     * characters is preserved. Returns empty string if name is not present in
+     * the url.
+     *
+     * <p> for each protocol if port number is not in the url
+     *
+     * <p> Additional connection properties specified as key/value pairs.
+     * </ul>
+     *
+     * @return null returned if the part that should represent the port is not
+     *   an integer or the part for database name is empty. Empty
+     *   HsqlProperties returned if if url does not begin with valid protocol
+     *   and could refer to another JDBC driver.
+     * @param url String
+     * @param hasPrefix indicates URL prefix is present
+     * @param noPath indicates empty path and verbatim use of path elements as
+     * database
+     */
+    public static HsqlProperties parseURL(String url, boolean hasPrefix,
+                                          boolean noPath) {
+
+        String         urlImage   = url.toLowerCase(Locale.ENGLISH);
+        HsqlProperties props      = new HsqlProperties();
+        HsqlProperties extraProps = null;
+        String         arguments  = null;
+        int            pos        = 0;
+
+        if (hasPrefix) {
+            if (urlImage.startsWith(S_URL_PREFIX)) {
+                pos = S_URL_PREFIX.length();
+            } else {
+                return props;
+            }
+        }
+
+        String  type = null;
+        int     port = 0;
+        String  database;
+        String  path;
+        boolean isNetwork = false;
+
+        props.setProperty("url", url);
+
+        int postUrlPos = url.length();
+
+        // postUrlPos is the END position in url String,
+        // wrt what remains to be processed.
+        // I.e., if postUrlPos is 100, url no longer needs to examined at
+        // index 100 or later.
+        int semiPos = url.indexOf(';', pos);
+
+        if (semiPos > -1) {
+            arguments  = url.substring(semiPos + 1, urlImage.length());
+            postUrlPos = semiPos;
+            extraProps = HsqlProperties.delimitedArgPairsToProps(arguments,
+                    "=", ";", null);
+
+            // validity checks are performed by engine
+            props.addProperties(extraProps);
+        }
+
+        if (postUrlPos == pos + 1 && urlImage.startsWith(S_DOT, pos)) {
+            type = S_DOT;
+        } else if (urlImage.startsWith(S_MEM, pos)) {
+            type = S_MEM;
+        } else if (urlImage.startsWith(S_FILE, pos)) {
+            type = S_FILE;
+        } else if (urlImage.startsWith(S_RES, pos)) {
+            type = S_RES;
+        } else if (urlImage.startsWith(S_ALIAS, pos)) {
+            type = S_ALIAS;
+        } else if (urlImage.startsWith(S_HSQL, pos)) {
+            type      = S_HSQL;
+            port      = ServerConstants.SC_DEFAULT_HSQL_SERVER_PORT;
+            isNetwork = true;
+        } else if (urlImage.startsWith(S_HSQLS, pos)) {
+            type      = S_HSQLS;
+            port      = ServerConstants.SC_DEFAULT_HSQLS_SERVER_PORT;
+            isNetwork = true;
+        } else if (urlImage.startsWith(S_HTTP, pos)) {
+            type      = S_HTTP;
+            port      = ServerConstants.SC_DEFAULT_HTTP_SERVER_PORT;
+            isNetwork = true;
+        } else if (urlImage.startsWith(S_HTTPS, pos)) {
+            type      = S_HTTPS;
+            port      = ServerConstants.SC_DEFAULT_HTTPS_SERVER_PORT;
+            isNetwork = true;
+        }
+
+        if (type == null) {
+            type = S_FILE;
+        } else if (type == S_DOT) {
+            type = S_MEM;
+
+            // keep pos
+        } else {
+            pos += type.length();
+        }
+
+        props.setProperty("connection_type", type);
+
+        if (isNetwork) {
+
+            // First capture 3 segments:  host + port + path
+            String pathSeg  = null;
+            String hostSeg  = null;
+            String portSeg  = null;
+            int    slashPos = url.indexOf('/', pos);
+
+            if (slashPos > 0 && slashPos < postUrlPos) {
+                pathSeg = url.substring(slashPos, postUrlPos);
+
+                // N.b. pathSeg necessarily begins with /.
+                postUrlPos = slashPos;
+            }
+
+            // Assertion
+            if (postUrlPos <= pos) {
+                return null;
+            }
+
+            // Processing different for ipv6 host address and all others:
+            if (url.charAt(pos) == '[') {
+
+                // ipv6
+                int endIpv6 = url.indexOf(']', pos + 2);
+
+                // Notice 2 instead of 1 to require non-empty addr segment
+                if (endIpv6 < 0 || endIpv6 >= postUrlPos) {
+                    return null;
+
+                    // Wish could throw something with a useful message for user
+                    // here.
+                }
+
+                hostSeg = urlImage.substring(pos + 1, endIpv6);
+
+                if (postUrlPos > endIpv6 + 1) {
+                    portSeg = url.substring(endIpv6 + 1, postUrlPos);
+                }
+            } else {
+
+                // non-ipv6
+                int colPos = url.indexOf(':', pos + 1);
+
+                // Notice + 1 to require non-empty addr segment
+                hostSeg = urlImage.substring(pos, (colPos > 0) ? colPos
+                                                               : postUrlPos);
+
+                if (colPos > -1 && postUrlPos > colPos + 1) {
+
+                    // portSeg will be non-empty, but could contain just ":"
+                    portSeg = url.substring(colPos, postUrlPos);
+                }
+            }
+
+            // At this point, the entire url has been parsed into
+            // hostSeg + portSeg + pathSeg.
+            if (portSeg != null) {
+                if (portSeg.length() < 2 || portSeg.charAt(0) != ':') {
+
+                    // Wish could throw something with a useful message for user
+                    // here.
+                    return null;
+                }
+
+                try {
+                    port = Integer.parseInt(portSeg.substring(1));
+                } catch (NumberFormatException e) {
+
+                    // System.err.println("NFE for (" + portSeg + ')'); debug
+                    return null;
+                }
+            }
+
+            if (noPath) {
+                path     = "";
+                database = pathSeg;
+            } else if (pathSeg == null) {
+                path     = "/";
+                database = "";
+            } else {
+                int lastSlashPos = pathSeg.lastIndexOf('/');
+
+                if (lastSlashPos < 1) {
+                    path = "/";
+                    database =
+                        pathSeg.substring(1).toLowerCase(Locale.ENGLISH);
+                } else {
+                    path     = pathSeg.substring(0, lastSlashPos);
+                    database = pathSeg.substring(lastSlashPos + 1);
+                }
+            }
+
+            /* Just for debug.  Remove once stable:
+            System.err.println("Host seg (" + hostSeg + "), Port val (" + port
+                    + "), Path val (" + pathSeg + "), path (" + path
+                    + "), db (" + database + ')');
+             */
+            props.setProperty("port", port);
+            props.setProperty("host", hostSeg);
+            props.setProperty("path", path);
+
+            if (!noPath && extraProps != null) {
+                String filePath = extraProps.getProperty("filepath");
+
+                if (filePath != null && database.length() != 0) {
+                    database += ";" + filePath;
+                }
+            }
+        } else {
+            if (type == S_MEM) {
+                database = urlImage.substring(pos, postUrlPos);
+            } else if (type == S_RES) {
+                database = url.substring(pos, postUrlPos);
+
+                if (database.indexOf('/') != 0) {
+                    database = '/' + database;
+                }
+            } else {
+                database = url.substring(pos, postUrlPos);
+            }
+
+            if (database.length() == 0) {
+                return null;
+            }
+        }
+
+        props.setProperty("database", database);
+
+        return props;
+    }
+}
diff --git a/src/org/hsqldb/Expression.java b/src/org/hsqldb/Expression.java
new file mode 100644
index 0000000..7ad3e05
--- /dev/null
+++ b/src/org/hsqldb/Expression.java
@@ -0,0 +1,1914 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.HsqlNameManager.SimpleName;
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayListIdentity;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.lib.Set;
+import org.hsqldb.navigator.RowSetNavigatorData;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+import org.hsqldb.types.ArrayType;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.NullType;
+import org.hsqldb.types.Type;
+
+/**
+ * Expression class.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class Expression implements Cloneable {
+
+    public static final int LEFT   = 0;
+    public static final int RIGHT  = 1;
+    public static final int UNARY  = 1;
+    public static final int BINARY = 2;
+
+    //
+    //
+    static final Expression[] emptyArray = new Expression[]{};
+
+    //
+    static final Expression EXPR_TRUE  = new ExpressionLogical(true);
+    static final Expression EXPR_FALSE = new ExpressionLogical(false);
+
+    //
+    static final OrderedIntHashSet aggregateFunctionSet =
+        new OrderedIntHashSet();
+
+    static {
+        aggregateFunctionSet.add(OpTypes.COUNT);
+        aggregateFunctionSet.add(OpTypes.SUM);
+        aggregateFunctionSet.add(OpTypes.MIN);
+        aggregateFunctionSet.add(OpTypes.MAX);
+        aggregateFunctionSet.add(OpTypes.AVG);
+        aggregateFunctionSet.add(OpTypes.EVERY);
+        aggregateFunctionSet.add(OpTypes.SOME);
+        aggregateFunctionSet.add(OpTypes.STDDEV_POP);
+        aggregateFunctionSet.add(OpTypes.STDDEV_SAMP);
+        aggregateFunctionSet.add(OpTypes.VAR_POP);
+        aggregateFunctionSet.add(OpTypes.VAR_SAMP);
+        aggregateFunctionSet.add(OpTypes.USER_AGGREGATE);
+    }
+
+    static final OrderedIntHashSet columnExpressionSet =
+        new OrderedIntHashSet();
+
+    static {
+        columnExpressionSet.add(OpTypes.COLUMN);
+    }
+
+    static final OrderedIntHashSet subqueryExpressionSet =
+        new OrderedIntHashSet();
+
+    static {
+        subqueryExpressionSet.add(OpTypes.ROW_SUBQUERY);
+        subqueryExpressionSet.add(OpTypes.TABLE_SUBQUERY);
+    }
+
+    static final OrderedIntHashSet subqueryAggregateExpressionSet =
+        new OrderedIntHashSet();
+
+    static {
+        subqueryAggregateExpressionSet.add(OpTypes.COUNT);
+        subqueryAggregateExpressionSet.add(OpTypes.SUM);
+        subqueryAggregateExpressionSet.add(OpTypes.MIN);
+        subqueryAggregateExpressionSet.add(OpTypes.MAX);
+        subqueryAggregateExpressionSet.add(OpTypes.AVG);
+        subqueryAggregateExpressionSet.add(OpTypes.EVERY);
+        subqueryAggregateExpressionSet.add(OpTypes.SOME);
+        subqueryAggregateExpressionSet.add(OpTypes.STDDEV_POP);
+        subqueryAggregateExpressionSet.add(OpTypes.STDDEV_SAMP);
+        subqueryAggregateExpressionSet.add(OpTypes.VAR_POP);
+        subqueryAggregateExpressionSet.add(OpTypes.VAR_SAMP);
+        subqueryAggregateExpressionSet.add(OpTypes.USER_AGGREGATE);
+
+        //
+        subqueryAggregateExpressionSet.add(OpTypes.TABLE_SUBQUERY);
+        subqueryAggregateExpressionSet.add(OpTypes.ROW_SUBQUERY);
+    }
+
+    static final OrderedIntHashSet functionExpressionSet =
+        new OrderedIntHashSet();
+
+    static {
+        functionExpressionSet.add(OpTypes.SQL_FUNCTION);
+        functionExpressionSet.add(OpTypes.FUNCTION);
+    }
+
+    static final OrderedIntHashSet emptyExpressionSet =
+        new OrderedIntHashSet();
+
+    // type
+    protected int opType;
+
+    // type qualifier
+    protected int exprSubType;
+
+    //
+    SimpleName alias;
+
+    // aggregate
+    private boolean isAggregate;
+
+    // VALUE
+    protected Object       valueData;
+    protected Expression[] nodes;
+    Type[]                 nodeDataTypes;
+
+    // QUERY - in single value selects, IN, EXISTS etc.
+    SubQuery subQuery;
+
+    // for query and value lists, etc
+    boolean isCorrelated;
+
+    // for COLUMN
+    int columnIndex = -1;
+
+    // data type
+    protected Type dataType;
+
+    //
+    int queryTableColumnIndex = -1;    // >= 0 when it is used for order by
+
+    // index of a session-dependent field
+    int parameterIndex = -1;
+
+    //
+    int rangePosition = -1;
+
+    //
+    boolean isColumnEqual;
+
+    Expression(int type) {
+        opType = type;
+        nodes  = emptyArray;
+    }
+
+    // IN condition optimisation
+
+    /**
+     * Creates a SUBQUERY expression.
+     */
+    Expression(int type, SubQuery sq) {
+
+        switch (type) {
+
+            case OpTypes.ARRAY :
+                opType = OpTypes.ARRAY;
+                break;
+
+            case OpTypes.ARRAY_SUBQUERY :
+                opType = OpTypes.ARRAY_SUBQUERY;
+                break;
+
+            case OpTypes.TABLE_SUBQUERY :
+                opType = OpTypes.TABLE_SUBQUERY;
+                break;
+
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.SCALAR_SUBQUERY :
+                opType = OpTypes.ROW_SUBQUERY;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+
+        nodes    = emptyArray;
+        subQuery = sq;
+    }
+
+    /**
+     * ROW, ARRAY etc.
+     */
+    Expression(int type, Expression[] list) {
+
+        this(type);
+
+        this.nodes = list;
+    }
+
+    static String getContextSQL(Expression expression) {
+
+        if (expression == null) {
+            return null;
+        }
+
+        String ddl = expression.getSQL();
+
+        switch (expression.opType) {
+
+            case OpTypes.VALUE :
+            case OpTypes.COLUMN :
+            case OpTypes.ROW :
+            case OpTypes.FUNCTION :
+            case OpTypes.SQL_FUNCTION :
+            case OpTypes.ALTERNATIVE :
+            case OpTypes.CASEWHEN :
+            case OpTypes.CAST :
+                return ddl;
+        }
+
+        StringBuffer sb = new StringBuffer();
+
+        ddl = sb.append('(').append(ddl).append(')').toString();
+
+        return ddl;
+    }
+
+    /**
+     * For use with CHECK constraints. Under development.
+     *
+     * Currently supports a subset of expressions and is suitable for CHECK
+     * search conditions that refer only to the inserted/updated row.
+     *
+     * For full DDL reporting of VIEW select queries and CHECK search
+     * conditions, future improvements here are dependent upon improvements to
+     * SELECT query parsing, so that it is performed in a number of passes.
+     * An early pass should result in the query turned into an Expression tree
+     * that contains the information in the original SQL without any
+     * alterations, and with tables and columns all resolved. This Expression
+     * can then be preserved for future use. Table and column names that
+     * are not user-defined aliases should be kept as the HsqlName structures
+     * so that table or column renaming is reflected in the precompiled
+     * query.
+     */
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                if (valueData == null) {
+                    return Tokens.T_NULL;
+                }
+
+                return dataType.convertToSQLString(valueData);
+
+            case OpTypes.ROW :
+                sb.append('(');
+
+                for (int i = 0; i < nodes.length; i++) {
+                    if (i > 0) {
+                        sb.append(',');
+                    }
+
+                    sb.append(nodes[i].getSQL());
+                }
+
+                sb.append(')');
+
+                return sb.toString();
+
+            //
+            case OpTypes.TABLE :
+                for (int i = 0; i < nodes.length; i++) {
+                    if (i > 0) {
+                        sb.append(',');
+                    }
+
+                    sb.append(nodes[i].getSQL());
+                }
+
+                return sb.toString();
+        }
+
+        switch (opType) {
+
+            case OpTypes.ARRAY :
+                sb.append(Tokens.T_ARRAY).append('[');
+
+                for (int i = 0; i < nodes.length; i++) {
+                    if (i > 0) {
+                        sb.append(',');
+                    }
+
+                    sb.append(nodes[i].getSQL());
+                }
+
+                sb.append(']');
+                break;
+
+            case OpTypes.ARRAY_SUBQUERY :
+
+            //
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY :
+                sb.append('(');
+                sb.append(')');
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                sb.append("VALUE = ").append(valueData);
+                sb.append(", TYPE = ").append(dataType.getNameString());
+
+                return sb.toString();
+
+            case OpTypes.ARRAY :
+                sb.append("ARRAY ");
+
+                return sb.toString();
+
+            case OpTypes.ARRAY_SUBQUERY :
+                sb.append("ARRAY SUBQUERY");
+
+                return sb.toString();
+
+            //
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY :
+                sb.append("QUERY ");
+                sb.append(subQuery.queryExpression.describe(session, blanks));
+
+                return sb.toString();
+
+            case OpTypes.ROW :
+                sb.append("ROW = ");
+
+                for (int i = 0; i < nodes.length; i++) {
+                    sb.append(nodes[i].describe(session, blanks + 1));
+                    sb.append(' ');
+                }
+                break;
+
+            case OpTypes.TABLE :
+                sb.append("VALUELIST ");
+
+                for (int i = 0; i < nodes.length; i++) {
+                    sb.append(nodes[i].describe(session, blanks + 1));
+                    sb.append(' ');
+                }
+                break;
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Set the data type
+     */
+    void setDataType(Session session, Type type) {
+
+        if (opType == OpTypes.VALUE) {
+            valueData = type.convertToType(session, valueData, dataType);
+        }
+
+        dataType = type;
+    }
+
+    public boolean equals(Expression other) {
+
+        if (other == this) {
+            return true;
+        }
+
+        if (other == null) {
+            return false;
+        }
+
+        if (opType != other.opType || exprSubType != other.exprSubType
+                || !equals(dataType, other.dataType)) {
+            return false;
+        }
+
+        switch (opType) {
+
+            case OpTypes.SIMPLE_COLUMN :
+                return this.columnIndex == other.columnIndex;
+
+            case OpTypes.VALUE :
+                return equals(valueData, other.valueData);
+
+            case OpTypes.ARRAY :
+
+            //
+            case OpTypes.ARRAY_SUBQUERY :
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY :
+                return (subQuery.queryExpression.isEquivalent(
+                    other.subQuery.queryExpression));
+
+            default :
+                return equals(nodes, other.nodes)
+                       && equals(subQuery, other.subQuery);
+        }
+    }
+
+    public boolean equals(Object other) {
+
+        if (other == this) {
+            return true;
+        }
+
+        if (other instanceof Expression) {
+            return equals((Expression) other);
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+
+        int val = opType + exprSubType;
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                val += nodes[i].hashCode();
+            }
+        }
+
+        return val;
+    }
+
+    static boolean equals(Object o1, Object o2) {
+
+        if (o1 == o2) {
+            return true;
+        }
+
+        return (o1 == null) ? o2 == null
+                            : o1.equals(o2);
+    }
+
+    static boolean equals(Expression[] row1, Expression[] row2) {
+
+        if (row1 == row2) {
+            return true;
+        }
+
+        if (row1.length != row2.length) {
+            return false;
+        }
+
+        int len = row1.length;
+
+        for (int i = 0; i < len; i++) {
+            Expression e1     = row1[i];
+            Expression e2     = row2[i];
+            boolean    equals = (e1 == null) ? e2 == null
+                                             : e1.equals(e2);
+
+            if (!equals) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * For GROUP only.
+     */
+    boolean isComposedOf(Expression exprList[], int start, int end,
+                         OrderedIntHashSet excludeSet) {
+
+        if (opType == OpTypes.VALUE) {
+            return true;
+        }
+
+        if (excludeSet.contains(opType)) {
+            return true;
+        }
+
+        for (int i = start; i < end; i++) {
+            if (equals(exprList[i])) {
+                return true;
+            }
+        }
+
+        switch (opType) {
+
+            case OpTypes.LIKE :
+            case OpTypes.MATCH_SIMPLE :
+            case OpTypes.MATCH_PARTIAL :
+            case OpTypes.MATCH_FULL :
+            case OpTypes.MATCH_UNIQUE_SIMPLE :
+            case OpTypes.MATCH_UNIQUE_PARTIAL :
+            case OpTypes.MATCH_UNIQUE_FULL :
+            case OpTypes.UNIQUE :
+            case OpTypes.EXISTS :
+            case OpTypes.ARRAY :
+            case OpTypes.ARRAY_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY :
+            case OpTypes.ROW_SUBQUERY :
+
+            //
+            case OpTypes.COUNT :
+            case OpTypes.SUM :
+            case OpTypes.MIN :
+            case OpTypes.MAX :
+            case OpTypes.AVG :
+            case OpTypes.EVERY :
+            case OpTypes.SOME :
+            case OpTypes.STDDEV_POP :
+            case OpTypes.STDDEV_SAMP :
+            case OpTypes.VAR_POP :
+            case OpTypes.VAR_SAMP :
+                return false;
+        }
+
+        if (nodes.length == 0) {
+            return false;
+        }
+
+        boolean result = true;
+
+        for (int i = 0; i < nodes.length; i++) {
+            result &= (nodes[i] == null
+                       || nodes[i].isComposedOf(exprList, start, end,
+                                                excludeSet));
+        }
+
+        return result;
+    }
+
+    /**
+     * For HAVING only.
+     */
+    boolean isComposedOf(OrderedHashSet expressions,
+                         OrderedIntHashSet excludeSet) {
+
+        if (opType == OpTypes.VALUE || opType == OpTypes.DYNAMIC_PARAM
+                || opType == OpTypes.PARAMETER || opType == OpTypes.VARIABLE) {
+            return true;
+        }
+
+        if (excludeSet.contains(opType)) {
+            return true;
+        }
+
+        for (int i = 0; i < expressions.size(); i++) {
+            if (equals(expressions.get(i))) {
+                return true;
+            }
+        }
+
+        switch (opType) {
+
+            case OpTypes.COUNT :
+            case OpTypes.SUM :
+            case OpTypes.MIN :
+            case OpTypes.MAX :
+            case OpTypes.AVG :
+            case OpTypes.EVERY :
+            case OpTypes.SOME :
+            case OpTypes.STDDEV_POP :
+            case OpTypes.STDDEV_SAMP :
+            case OpTypes.VAR_POP :
+            case OpTypes.VAR_SAMP :
+                return false;
+        }
+
+/*
+        case OpCodes.LIKE :
+        case OpCodes.ALL :
+        case OpCodes.ANY :
+        case OpCodes.IN :
+        case OpCodes.MATCH_SIMPLE :
+        case OpCodes.MATCH_PARTIAL :
+        case OpCodes.MATCH_FULL :
+        case OpCodes.MATCH_UNIQUE_SIMPLE :
+        case OpCodes.MATCH_UNIQUE_PARTIAL :
+        case OpCodes.MATCH_UNIQUE_FULL :
+        case OpCodes.UNIQUE :
+        case OpCodes.EXISTS :
+        case OpCodes.TABLE_SUBQUERY :
+        case OpCodes.ROW_SUBQUERY :
+*/
+        if (nodes.length == 0) {
+            return false;
+        }
+
+        boolean result = true;
+
+        for (int i = 0; i < nodes.length; i++) {
+            result &= (nodes[i] == null
+                       || nodes[i].isComposedOf(expressions, excludeSet));
+        }
+
+        return result;
+    }
+
+    Expression replaceColumnReferences(RangeVariable range,
+                                       Expression[] list) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            nodes[i] = nodes[i].replaceColumnReferences(range, list);
+        }
+
+        if (subQuery != null && subQuery.queryExpression != null) {
+            subQuery.queryExpression.replaceColumnReference(range, list);
+        }
+
+        return this;
+    }
+
+    void replaceRangeVariables(RangeVariable[] ranges,
+                               RangeVariable[] newRanges) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            nodes[i].replaceRangeVariables(ranges, newRanges);
+        }
+
+        if (subQuery != null && subQuery.queryExpression != null) {
+            subQuery.queryExpression.replaceRangeVariables(ranges, newRanges);
+        }
+    }
+
+    void resetColumnReferences() {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            nodes[i].resetColumnReferences();
+        }
+    }
+
+    void convertToSimpleColumn(OrderedHashSet expressions,
+                               OrderedHashSet replacements) {
+
+        if (opType == OpTypes.VALUE) {
+            return;
+        }
+
+        int index = expressions.getIndex(this);
+
+        if (index != -1) {
+            Expression e = (Expression) replacements.get(index);
+
+            nodes         = emptyArray;
+            opType        = OpTypes.SIMPLE_COLUMN;
+            columnIndex   = e.columnIndex;
+            rangePosition = e.rangePosition;
+
+            return;
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            nodes[i].convertToSimpleColumn(expressions, replacements);
+        }
+    }
+
+    boolean isAggregate() {
+        return isAggregate;
+    }
+
+    void setAggregate() {
+        isAggregate = true;
+    }
+
+    boolean isSelfAggregate() {
+        return false;
+    }
+
+    /**
+     * Set the column alias
+     */
+    void setAlias(SimpleName name) {
+        alias = name;
+    }
+
+    /**
+     * Get the column alias
+     */
+    String getAlias() {
+
+        if (alias != null) {
+            return alias.name;
+        }
+
+        return "";
+    }
+
+    SimpleName getSimpleName() {
+
+        if (alias != null) {
+            return alias;
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the type of expression
+     */
+    public int getType() {
+        return opType;
+    }
+
+    /**
+     * Returns the left node
+     */
+    Expression getLeftNode() {
+        return nodes.length > 0 ? nodes[LEFT]
+                                : null;
+    }
+
+    /**
+     * Returns the right node
+     */
+    Expression getRightNode() {
+        return nodes.length > 1 ? nodes[RIGHT]
+                                : null;
+    }
+
+    void setLeftNode(Expression e) {
+        nodes[LEFT] = e;
+    }
+
+    void setRightNode(Expression e) {
+        nodes[RIGHT] = e;
+    }
+
+    void setSubType(int i) {
+        exprSubType = i;
+    }
+
+    /**
+     * Returns the range variable for a COLUMN expression
+     */
+    RangeVariable getRangeVariable() {
+        return null;
+    }
+
+    /**
+     * return the expression for an alias used in an ORDER BY clause
+     */
+    Expression replaceAliasInOrderBy(Expression[] columns, int length) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            nodes[i] = nodes[i].replaceAliasInOrderBy(columns, length);
+        }
+
+        return this;
+    }
+
+    /**
+     * Find a range variable with the given table alias
+     */
+    int findMatchingRangeVariableIndex(RangeVariable[] rangeVarArray) {
+        return -1;
+    }
+
+    /**
+     * collects all range variables in expression tree
+     */
+    void collectRangeVariables(RangeVariable[] rangeVariables, Set set) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].collectRangeVariables(rangeVariables, set);
+            }
+        }
+
+        if (subQuery != null && subQuery.queryExpression != null) {
+            HsqlList unresolvedExpressions =
+                subQuery.queryExpression.getUnresolvedExpressions();
+
+            if (unresolvedExpressions != null) {
+                for (int i = 0; i < unresolvedExpressions.size(); i++) {
+                    Expression e = (Expression) unresolvedExpressions.get(i);
+
+                    e.collectRangeVariables(rangeVariables, set);
+                }
+            }
+        }
+    }
+
+    /**
+     * collects all schema objects
+     */
+    void collectObjectNames(Set set) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].collectObjectNames(set);
+            }
+        }
+
+        if (subQuery != null) {
+            if (subQuery.queryExpression != null) {
+                subQuery.queryExpression.collectObjectNames(set);
+            }
+        }
+    }
+
+    /**
+     * return true if given RangeVariable is used in expression tree
+     */
+    boolean hasReference(RangeVariable range) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                if (nodes[i].hasReference(range)) {
+                    return true;
+                }
+            }
+        }
+
+        if (subQuery != null && subQuery.queryExpression != null) {
+            if (subQuery.queryExpression.hasReference(range)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * resolve tables and collect unresolved column expressions
+     */
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            HsqlList unresolvedSet) {
+        return resolveColumnReferences(rangeVarArray, rangeVarArray.length,
+                                       unresolvedSet, true);
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+
+        if (opType == OpTypes.VALUE) {
+            return unresolvedSet;
+        }
+
+        switch (opType) {
+
+            case OpTypes.CASEWHEN :
+                acceptsSequences = false;
+                break;
+
+            case OpTypes.TABLE : {
+                HsqlList localSet = null;
+
+                for (int i = 0; i < nodes.length; i++) {
+                    if (nodes[i] == null) {
+                        continue;
+                    }
+
+                    localSet = nodes[i].resolveColumnReferences(
+                        RangeVariable.emptyArray, localSet);
+                }
+
+                if (localSet != null) {
+                    isCorrelated = true;
+
+                    if (subQuery != null) {
+                        subQuery.setCorrelated();
+                    }
+
+                    for (int i = 0; i < localSet.size(); i++) {
+                        Expression e = (Expression) localSet.get(i);
+
+                        unresolvedSet =
+                            e.resolveColumnReferences(rangeVarArray,
+                                                      unresolvedSet);
+                    }
+
+                    unresolvedSet = Expression.resolveColumnSet(rangeVarArray,
+                            rangeVarArray.length, localSet, unresolvedSet);
+                }
+
+                return unresolvedSet;
+            }
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            unresolvedSet = nodes[i].resolveColumnReferences(rangeVarArray,
+                    rangeCount, unresolvedSet, acceptsSequences);
+        }
+
+        switch (opType) {
+
+            case OpTypes.ARRAY :
+                break;
+
+            case OpTypes.ARRAY_SUBQUERY :
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY : {
+                QueryExpression queryExpression = subQuery.queryExpression;
+
+                if (!queryExpression.areColumnsResolved()) {
+                    isCorrelated = true;
+
+                    subQuery.setCorrelated();
+
+                    // take to enclosing context
+                    if (unresolvedSet == null) {
+                        unresolvedSet = new ArrayListIdentity();
+                    }
+
+                    unresolvedSet.addAll(
+                        queryExpression.getUnresolvedExpressions());
+                }
+
+                break;
+            }
+            default :
+        }
+
+        return unresolvedSet;
+    }
+
+    public OrderedHashSet getUnkeyedColumns(OrderedHashSet unresolvedSet) {
+
+        if (opType == OpTypes.VALUE) {
+            return unresolvedSet;
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            unresolvedSet = nodes[i].getUnkeyedColumns(unresolvedSet);
+        }
+
+        switch (opType) {
+
+            case OpTypes.ARRAY :
+            case OpTypes.ARRAY_SUBQUERY :
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY :
+                if (subQuery != null) {
+                    if (unresolvedSet == null) {
+                        unresolvedSet = new OrderedHashSet();
+                    }
+
+                    unresolvedSet.add(this);
+                }
+                break;
+        }
+
+        return unresolvedSet;
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                break;
+
+            case OpTypes.TABLE :
+
+                /** @todo - should it fall through */
+                break;
+
+            case OpTypes.ROW :
+                nodeDataTypes = new Type[nodes.length];
+
+                for (int i = 0; i < nodes.length; i++) {
+                    if (nodes[i] != null) {
+                        nodeDataTypes[i] = nodes[i].dataType;
+                    }
+                }
+                break;
+
+            case OpTypes.ARRAY : {
+                boolean hasUndefined = false;
+
+                for (int i = 0; i < nodes.length; i++) {
+                    if (nodes[i].dataType == null) {
+                        hasUndefined = true;
+                    } else {
+                        dataType = Type.getAggregateType(dataType,
+                                                         nodes[i].dataType);
+                    }
+                }
+
+                if (hasUndefined) {
+                    for (int i = 0; i < nodes.length; i++) {
+                        if (nodes[i].dataType == null) {
+                            nodes[i].dataType = dataType;
+                        }
+                    }
+                }
+
+                dataType = new ArrayType(dataType, nodes.length);
+
+                return;
+            }
+            case OpTypes.ARRAY_SUBQUERY : {
+                QueryExpression queryExpression = subQuery.queryExpression;
+
+                queryExpression.resolveTypes(session);
+                subQuery.prepareTable(session);
+
+                nodeDataTypes = queryExpression.getColumnTypes();
+                dataType      = nodeDataTypes[0];
+
+                if (nodeDataTypes.length > 1) {
+                    throw Error.error(ErrorCode.X_42564);
+                }
+
+                dataType = new ArrayType(dataType, nodes.length);
+
+                break;
+            }
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY : {
+                QueryExpression queryExpression = subQuery.queryExpression;
+
+                queryExpression.resolveTypes(session);
+                subQuery.prepareTable(session);
+
+                nodeDataTypes = queryExpression.getColumnTypes();
+                dataType      = nodeDataTypes[0];
+
+                break;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+
+    void setAsConstantValue(Session session) {
+
+        valueData = getValue(session);
+        opType    = OpTypes.VALUE;
+        nodes     = emptyArray;
+    }
+
+    void setAsConstantValue(Object value) {
+
+        valueData = value;
+        opType    = OpTypes.VALUE;
+        nodes     = emptyArray;
+    }
+
+    void prepareTable(Session session, Expression row, int degree) {
+
+        if (nodeDataTypes != null) {
+            return;
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            Expression e = nodes[i];
+
+            if (e.opType == OpTypes.ROW) {
+                if (degree != e.nodes.length) {
+                    throw Error.error(ErrorCode.X_42564);
+                }
+            } else if (degree == 1) {
+                nodes[i]       = new Expression(OpTypes.ROW);
+                nodes[i].nodes = new Expression[]{ e };
+            } else {
+                throw Error.error(ErrorCode.X_42564);
+            }
+        }
+
+        nodeDataTypes = new Type[degree];
+
+        for (int j = 0; j < degree; j++) {
+            Type type = row == null ? null
+                                    : row.nodes[j].dataType;
+
+            for (int i = 0; i < nodes.length; i++) {
+                type = Type.getAggregateType(nodes[i].nodes[j].dataType, type);
+            }
+
+            if (type == null) {
+                throw Error.error(ErrorCode.X_42567);
+            }
+
+            nodeDataTypes[j] = type;
+
+            if (row != null && row.nodes[j].isUnresolvedParam()) {
+                row.nodes[j].dataType = type;
+            }
+
+            for (int i = 0; i < nodes.length; i++) {
+                if (nodes[i].nodes[j].isUnresolvedParam()) {
+                    nodes[i].nodes[j].dataType = nodeDataTypes[j];
+
+                    continue;
+                }
+
+                if (nodes[i].nodes[j].opType == OpTypes.VALUE) {
+                    if (nodes[i].nodes[j].valueData == null) {
+                        nodes[i].nodes[j].dataType = nodeDataTypes[j];
+                    }
+                }
+            }
+
+            if (nodeDataTypes[j].isCharacterType()
+                    && !((CharacterType) nodeDataTypes[j])
+                        .isEqualIdentical()) {
+
+                // collation issues
+            }
+        }
+    }
+
+    /**
+     * Details of IN condition optimisation for 1.9.0
+     * Predicates with SELECT are QUERY expressions
+     *
+     * Predicates with IN list
+     *
+     * Parser adds a SubQuery to the list for each predicate
+     * At type resolution IN lists that are entirely fixed constant or parameter
+     * values are selected for possible optimisation. The flags:
+     *
+     * IN expression right side isCorrelated == true if there are non-constant,
+     * non-param expressions in the list (Expressions may have to be resolved
+     * against the full set of columns of the query, so must be re-evaluated
+     * for each row and evaluated after all the joins have been made)
+     *
+     * VALUELIST expression isFixedConstantValueList == true when all
+     * expressions are fixed constant and none is a param. With this flag,
+     * a single-column VALUELIST can be accessed as a HashMap.
+     *
+     * Predicates may be optimised as joins if isCorrelated == false
+     *
+     */
+    void insertValuesIntoSubqueryTable(Session session,
+                                       PersistentStore store) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            Object[] data = nodes[i].getRowValue(session);
+
+            for (int j = 0; j < nodeDataTypes.length; j++) {
+                data[j] = nodeDataTypes[j].convertToType(session, data[j],
+                        nodes[i].nodes[j].dataType);
+            }
+
+            Row row = (Row) store.getNewCachedObject(session, data);
+
+            try {
+                store.indexRow(session, row);
+            } catch (HsqlException e) {}
+        }
+    }
+
+    /**
+     * Returns the name of a column as string
+     *
+     * @return column name
+     */
+    String getColumnName() {
+        return getAlias();
+    }
+
+    ColumnSchema getColumn() {
+        return null;
+    }
+
+    /**
+     * Returns the column index in the table
+     */
+    int getColumnIndex() {
+        return columnIndex;
+    }
+
+    /**
+     * Returns the data type
+     */
+    Type getDataType() {
+        return dataType;
+    }
+
+    Type getNodeDataType(int i) {
+
+        if (nodeDataTypes == null) {
+            if (i > 0) {
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+            }
+
+            return dataType;
+        } else {
+            return nodeDataTypes[i];
+        }
+    }
+
+    Type[] getNodeDataTypes() {
+
+        if (nodeDataTypes == null) {
+            return new Type[]{ dataType };
+        } else {
+            return nodeDataTypes;
+        }
+    }
+
+    int getDegree() {
+
+        switch (opType) {
+
+            case OpTypes.ROW :
+                return nodes.length;
+
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY :
+                if (subQuery == null) {
+
+                    // todo
+                }
+
+                return subQuery.queryExpression.getColumnCount();
+
+            default :
+                return 1;
+        }
+    }
+
+    public Table getTable() {
+        return subQuery == null ? null
+                                : subQuery.getTable();
+    }
+
+    public void materialise(Session session) {
+
+        if (subQuery == null) {
+            return;
+        }
+
+        if (subQuery.isCorrelated()) {
+            subQuery.materialiseCorrelated(session);
+        } else {
+            subQuery.materialise(session);
+        }
+    }
+
+    Object getValue(Session session, Type type) {
+
+        Object o = getValue(session);
+
+        if (o == null || dataType == type) {
+            return o;
+        }
+
+        return type.convertToType(session, o, dataType);
+    }
+
+    public Object getConstantValueNoCheck(Session session) {
+
+        try {
+            return getValue(session);
+        } catch (HsqlException e) {
+            return null;
+        }
+    }
+
+    public Object[] getRowValue(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.ROW : {
+                Object[] data = new Object[nodes.length];
+
+                for (int i = 0; i < nodes.length; i++) {
+                    data[i] = nodes[i].getValue(session);
+                }
+
+                return data;
+            }
+            case OpTypes.ROW_SUBQUERY :
+            case OpTypes.TABLE_SUBQUERY : {
+                return subQuery.queryExpression.getValues(session);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+
+    public Object getValue(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                return valueData;
+
+            case OpTypes.SIMPLE_COLUMN : {
+                Object[] data =
+                    session.sessionContext.rangeIterators[rangePosition]
+                        .getCurrent();
+
+                return data[columnIndex];
+            }
+            case OpTypes.ROW : {
+                if (nodes.length == 1) {
+                    return nodes[0].getValue(session);
+                }
+
+                Object[] row = new Object[nodes.length];
+
+                for (int i = 0; i < nodes.length; i++) {
+                    row[i] = nodes[i].getValue(session);
+                }
+
+                return row;
+            }
+            case OpTypes.ARRAY : {
+                Object[] array = new Object[nodes.length];
+
+                for (int i = 0; i < nodes.length; i++) {
+                    array[i] = nodes[i].getValue(session);
+                }
+
+                return array;
+            }
+            case OpTypes.ARRAY_SUBQUERY : {
+                subQuery.materialiseCorrelated(session);
+
+                RowSetNavigatorData nav   = subQuery.getNavigator(session);
+                int                 size  = nav.getSize();
+                Object[]            array = new Object[size];
+
+                nav.beforeFirst();
+
+                for (int i = 0; nav.hasNext(); i++) {
+                    Object[] data = nav.getNextRowData();
+
+                    array[i] = data[0];
+                }
+
+                return array;
+            }
+            case OpTypes.TABLE_SUBQUERY :
+            case OpTypes.ROW_SUBQUERY : {
+                subQuery.materialiseCorrelated(session);
+
+                Object[] value = subQuery.getValues(session);
+
+                if (value.length == 1) {
+                    return ((Object[]) value)[0];
+                }
+
+                return value;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+
+    public Result getResult(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.ARRAY : {
+                RowSetNavigatorData navigator = subQuery.getNavigator(session);
+                Object[]            array = new Object[navigator.getSize()];
+
+                navigator.beforeFirst();
+
+                for (int i = 0; navigator.hasNext(); i++) {
+                    Object[] data = navigator.getNext();
+
+                    array[i] = data[0];
+                }
+
+                return Result.newPSMResult(array);
+            }
+            case OpTypes.TABLE_SUBQUERY : {
+                subQuery.materialiseCorrelated(session);
+
+                RowSetNavigatorData navigator = subQuery.getNavigator(session);
+                Result              result    = Result.newResult(navigator);
+
+                result.metaData = subQuery.queryExpression.getMetaData();
+
+                return result;
+            }
+            default : {
+                Object value = getValue(session);
+
+                return Result.newPSMResult(value);
+            }
+        }
+    }
+
+    boolean testCondition(Session session) {
+        return Boolean.TRUE.equals(getValue(session));
+    }
+
+    static int countNulls(Object[] a) {
+
+        int nulls = 0;
+
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] == null) {
+                nulls++;
+            }
+        }
+
+        return nulls;
+    }
+
+    public boolean isIndexable(RangeVariable range) {
+        return false;
+    }
+
+    static void convertToType(Session session, Object[] data, Type[] dataType,
+                              Type[] newType) {
+
+        for (int i = 0; i < data.length; i++) {
+            data[i] = newType[i].convertToType(session, data[i], dataType[i]);
+        }
+    }
+
+    /**
+     * Returns a Select object that can be used for checking the contents
+     * of an existing table against the given CHECK search condition.
+     */
+    static QuerySpecification getCheckSelect(Session session, Table t,
+            Expression e) {
+
+        CompileContext     compileContext = new CompileContext(session, null);
+        QuerySpecification s = new QuerySpecification(compileContext);
+        RangeVariable[] ranges = new RangeVariable[]{
+            new RangeVariable(t, null, null, null, compileContext) };
+
+        e.resolveCheckOrGenExpression(session, ranges, true);
+
+        s.exprColumns    = new Expression[1];
+        s.exprColumns[0] = EXPR_TRUE;
+        s.rangeVariables = ranges;
+
+        if (Type.SQL_BOOLEAN != e.getDataType()) {
+            throw Error.error(ErrorCode.X_42568);
+        }
+
+        Expression condition = new ExpressionLogical(OpTypes.NOT, e);
+
+        s.queryCondition = condition;
+
+        s.resolveReferences(session);
+        s.resolveTypes(session);
+
+        return s;
+    }
+
+    public void resolveCheckOrGenExpression(Session session,
+            RangeVariable[] ranges, boolean isCheck) {
+
+        boolean        nonDeterministic = false;
+        OrderedHashSet set              = new OrderedHashSet();
+        HsqlList       unresolved = resolveColumnReferences(ranges, null);
+
+        ExpressionColumn.checkColumnsResolved(unresolved);
+        resolveTypes(session, null);
+        collectAllExpressions(set, Expression.subqueryAggregateExpressionSet,
+                              Expression.emptyExpressionSet);
+
+        if (!set.isEmpty()) {
+            throw Error.error(ErrorCode.X_42512);
+        }
+
+        collectAllExpressions(set, Expression.functionExpressionSet,
+                              Expression.emptyExpressionSet);
+
+        for (int i = 0; i < set.size(); i++) {
+            Expression current = (Expression) set.get(i);
+
+            if (current.opType == OpTypes.FUNCTION) {
+                if (!((FunctionSQLInvoked) current).isDeterministic()) {
+                    throw Error.error(ErrorCode.X_42512);
+                }
+            }
+
+            if (current.opType == OpTypes.SQL_FUNCTION) {
+                if (!((FunctionSQL) current).isDeterministic()) {
+                    if (isCheck) {
+                        nonDeterministic = true;
+
+                        continue;
+                    }
+
+                    throw Error.error(ErrorCode.X_42512);
+                }
+            }
+        }
+
+        if (isCheck && nonDeterministic) {
+            HsqlArrayList list = new HsqlArrayList();
+
+            RangeVariableResolver.decomposeAndConditions(this, list);
+
+            for (int i = 0; i < list.size(); i++) {
+                nonDeterministic = true;
+
+                Expression e = (Expression) list.get(i);
+                Expression e1;
+
+                if (e instanceof ExpressionLogical) {
+                    boolean b = ((ExpressionLogical) e).convertToSmaller();
+
+                    if (!b) {
+                        break;
+                    }
+
+                    e1 = e.getRightNode();
+                    e  = e.getLeftNode();
+
+                    if (!e.dataType.isDateTimeType()) {
+                        nonDeterministic = true;
+
+                        break;
+                    }
+
+                    if (e.hasNonDeterministicFunction()) {
+                        nonDeterministic = true;
+
+                        break;
+                    }
+
+                    // both sides are actually consistent regarding timeZone
+                    // e.dataType.isDateTimeTypeWithZone();
+                    if (e1 instanceof ExpressionArithmetic) {
+                        if (opType == OpTypes.ADD) {
+                            if (e1.getRightNode()
+                                    .hasNonDeterministicFunction()) {
+                                e1.swapLeftAndRightNodes();
+                            }
+                        } else if (opType == OpTypes.SUBTRACT) {}
+                        else {
+                            break;
+                        }
+
+                        if (e1.getRightNode().hasNonDeterministicFunction()) {
+                            break;
+                        }
+
+                        e1 = e1.getLeftNode();
+                    }
+
+                    if (e1.opType == OpTypes.SQL_FUNCTION) {
+                        FunctionSQL function = (FunctionSQL) e1;
+
+                        switch (function.funcType) {
+
+                            case FunctionSQL.FUNC_CURRENT_DATE :
+                            case FunctionSQL.FUNC_CURRENT_TIMESTAMP :
+                            case FunctionSQL.FUNC_LOCALTIMESTAMP :
+                                nonDeterministic = false;
+
+                                continue;
+                            default :
+                                break;
+                        }
+
+                        break;
+                    }
+
+                    break;
+                } else {
+                    break;
+                }
+            }
+
+            if (nonDeterministic) {
+                throw Error.error(ErrorCode.X_42512);
+            }
+        }
+
+        set.clear();
+        collectObjectNames(set);
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName name = (HsqlName) set.get(i);
+
+            switch (name.type) {
+
+                case SchemaObject.COLUMN : {
+                    if (isCheck) {
+                        break;
+                    }
+
+                    int colIndex = ranges[0].rangeTable.findColumn(name.name);
+                    ColumnSchema column =
+                        ranges[0].rangeTable.getColumn(colIndex);
+
+                    if (column.isGenerated()) {
+                        throw Error.error(ErrorCode.X_42512);
+                    }
+
+                    break;
+                }
+                case SchemaObject.SEQUENCE : {
+                    throw Error.error(ErrorCode.X_42512);
+                }
+                case SchemaObject.SPECIFIC_ROUTINE : {
+                    Routine routine =
+                        (Routine) session.database.schemaManager
+                            .getSchemaObject(name);
+
+                    if (!routine.isDeterministic()) {
+                        throw Error.error(ErrorCode.X_42512);
+                    }
+
+                    int impact = routine.getDataImpact();
+
+                    if (impact == Routine.READS_SQL
+                            || impact == Routine.MODIFIES_SQL) {
+                        throw Error.error(ErrorCode.X_42512);
+                    }
+                }
+            }
+        }
+
+        set.clear();
+    }
+
+    boolean isUnresolvedParam() {
+        return false;
+    }
+
+    boolean isDynamicParam() {
+        return false;
+    }
+
+    boolean hasNonDeterministicFunction() {
+
+        OrderedHashSet list = null;
+
+        list = collectAllExpressions(list, Expression.functionExpressionSet,
+                                     Expression.emptyExpressionSet);
+
+        if (list == null) {
+            return false;
+        }
+
+        for (int j = 0; j < list.size(); j++) {
+            Expression current = (Expression) list.get(j);
+
+            if (current.opType == OpTypes.FUNCTION) {
+                if (!((FunctionSQLInvoked) current).isDeterministic()) {
+                    return true;
+                }
+            } else if (current.opType == OpTypes.SQL_FUNCTION) {
+                if (!((FunctionSQL) current).isDeterministic()) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    void swapLeftAndRightNodes() {
+
+        Expression temp = nodes[LEFT];
+
+        nodes[LEFT]  = nodes[RIGHT];
+        nodes[RIGHT] = temp;
+    }
+
+    void setAttributesAsColumn(ColumnSchema column, boolean isWritable) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+    }
+
+    String getValueClassName() {
+
+        Type type = dataType == null ? NullType.getNullType()
+                                     : dataType;
+
+        return type.getJDBCClassName();
+    }
+
+    /**
+     * collect all expressions of a set of expression types appearing anywhere
+     * in a select statement and its subselects, etc.
+     */
+    OrderedHashSet collectAllExpressions(OrderedHashSet set,
+                                         OrderedIntHashSet typeSet,
+                                         OrderedIntHashSet stopAtTypeSet) {
+
+        if (stopAtTypeSet.contains(opType)) {
+            return set;
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                set = nodes[i].collectAllExpressions(set, typeSet,
+                                                     stopAtTypeSet);
+            }
+        }
+
+        if (typeSet.contains(opType)) {
+            if (set == null) {
+                set = new OrderedHashSet();
+            }
+
+            set.add(this);
+        }
+
+        if (subQuery != null && subQuery.queryExpression != null) {
+            set = subQuery.queryExpression.collectAllExpressions(set, typeSet,
+                    stopAtTypeSet);
+        }
+
+        return set;
+    }
+
+    public OrderedHashSet getSubqueries() {
+        return collectAllSubqueries(null);
+    }
+
+    OrderedHashSet collectAllSubqueries(OrderedHashSet set) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                set = nodes[i].collectAllSubqueries(set);
+            }
+        }
+
+        if (subQuery != null) {
+            if (set == null) {
+                set = new OrderedHashSet();
+            }
+
+            set.add(subQuery);
+
+            if (subQuery.queryExpression != null) {
+                OrderedHashSet tempSet =
+                    subQuery.queryExpression.getSubqueries();
+
+                set = OrderedHashSet.addAll(set, tempSet);
+            }
+        }
+
+        return set;
+    }
+
+    /**
+     * isCorrelated
+     */
+    public boolean isCorrelated() {
+
+        if (subQuery == null) {
+            return false;
+        }
+
+        return subQuery.isCorrelated();
+    }
+
+    /**
+     * checkValidCheckConstraint
+     */
+    public void checkValidCheckConstraint() {
+
+        OrderedHashSet set = null;
+
+        set = collectAllExpressions(set, subqueryAggregateExpressionSet,
+                                    emptyExpressionSet);
+
+        if (set != null && !set.isEmpty()) {
+            throw Error.error(ErrorCode.X_0A000,
+                              "subquery in check constraint");
+        }
+    }
+
+    static HsqlList resolveColumnSet(RangeVariable[] rangeVars,
+                                     int rangeCount, HsqlList sourceSet,
+                                     HsqlList targetSet) {
+
+        if (sourceSet == null) {
+            return targetSet;
+        }
+
+        for (int i = 0; i < sourceSet.size(); i++) {
+            Expression e = (Expression) sourceSet.get(i);
+
+            targetSet = e.resolveColumnReferences(rangeVars, rangeCount,
+                                                  targetSet, true);
+        }
+
+        return targetSet;
+    }
+
+    Expression getIndexableExpression(RangeVariable rangeVar) {
+        return null;
+    }
+
+    public Expression duplicate() {
+
+        Expression e = null;
+
+        try {
+            e       = (Expression) super.clone();
+            e.nodes = nodes.clone();
+
+            for (int i = 0; i < nodes.length; i++) {
+                if (nodes[i] != null) {
+                    e.nodes[i] = nodes[i].duplicate();
+                }
+            }
+        } catch (CloneNotSupportedException ex) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+
+        return e;
+    }
+
+    void replaceNode(Expression existing, Expression replacement) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == existing) {
+                replacement.alias = nodes[i].alias;
+                nodes[i]          = replacement;
+
+                return;
+            }
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+    }
+
+    public Object updateAggregatingValue(Session session, Object currValue) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+    }
+
+    public Object getAggregatedValue(Session session, Object currValue) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+    }
+}
diff --git a/src/org/hsqldb/ExpressionAccessor.java b/src/org/hsqldb/ExpressionAccessor.java
new file mode 100644
index 0000000..6fdfded
--- /dev/null
+++ b/src/org/hsqldb/ExpressionAccessor.java
@@ -0,0 +1,200 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.types.Type;
+
+/**
+ * database object component access
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class ExpressionAccessor extends Expression {
+
+    ExpressionAccessor(Expression left, Expression right) {
+
+        super(OpTypes.ARRAY_ACCESS);
+
+        nodes = new Expression[] {
+            left, right
+        };
+    }
+
+    public ColumnSchema getColumn() {
+        return nodes[LEFT].getColumn();
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            unresolvedSet = nodes[i].resolveColumnReferences(rangeVarArray,
+                    rangeCount, unresolvedSet, acceptsSequences);
+        }
+
+        return unresolvedSet;
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        if (nodes[LEFT].dataType == null) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        if (!nodes[LEFT].dataType.isArrayType()) {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        dataType = nodes[LEFT].dataType.collectionBaseType();
+
+        if (nodes[RIGHT].opType == OpTypes.DYNAMIC_PARAM) {
+            nodes[RIGHT].dataType = Type.SQL_INTEGER;
+        }
+    }
+
+    public Object getValue(Session session) {
+
+        Object[] array = (Object[]) nodes[LEFT].getValue(session);
+
+        if (array == null) {
+            return null;
+        }
+
+        Number index = (Number) nodes[RIGHT].getValue(session);
+
+        if (index == null) {
+            return null;
+        }
+
+        if (index.intValue() < 1 || index.intValue() > array.length) {
+            throw Error.error(ErrorCode.X_2202E);
+        }
+
+        return array[index.intValue() - 1];
+    }
+
+    /**
+     * Assignment result
+     */
+    public Object[] getUpdatedArray(Session session, Object[] array,
+                                    Object value, boolean copy) {
+
+        if (array == null) {
+            throw Error.error(ErrorCode.X_2200E);
+        }
+
+        Number index = (Number) nodes[RIGHT].getValue(session);
+
+        if (index == null) {
+            throw Error.error(ErrorCode.X_2202E);
+        }
+
+        int i = index.intValue() - 1;
+
+        if (i < 0) {
+            throw Error.error(ErrorCode.X_2202E);
+        }
+
+        if (i >= nodes[LEFT].dataType.arrayLimitCardinality()) {
+            throw Error.error(ErrorCode.X_2202E);
+        }
+
+        Object[] newArray = array;
+
+        if (i >= array.length) {
+            newArray = new Object[i + 1];
+
+            System.arraycopy(array, 0, newArray, 0, array.length);
+        } else if (copy) {
+            newArray = new Object[array.length];
+
+            System.arraycopy(array, 0, newArray, 0, array.length);
+        }
+
+        newArray[i] = value;
+
+        return newArray;
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb   = new StringBuffer(64);
+        String       left = getContextSQL(nodes[LEFT]);
+
+        sb.append(left).append('[');
+        sb.append(nodes[RIGHT].getSQL()).append(']');
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        sb.append("ARRAY ACCESS");
+
+        if (getLeftNode() != null) {
+            sb.append(" array=[");
+            sb.append(nodes[LEFT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        if (getRightNode() != null) {
+            sb.append(" array_index=[");
+            sb.append(nodes[RIGHT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/ExpressionAggregate.java b/src/org/hsqldb/ExpressionAggregate.java
new file mode 100644
index 0000000..1b093d6
--- /dev/null
+++ b/src/org/hsqldb/ExpressionAggregate.java
@@ -0,0 +1,279 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayListIdentity;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Implementation of aggregate operations
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ExpressionAggregate extends Expression {
+
+    boolean isDistinctAggregate;
+
+    ExpressionAggregate(int type, boolean distinct, Expression e) {
+
+        super(type);
+
+        nodes               = new Expression[UNARY];
+        isDistinctAggregate = distinct;
+        nodes[LEFT]         = e;
+    }
+
+    boolean isSelfAggregate() {
+        return true;
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb   = new StringBuffer(64);
+        String       left = getContextSQL(nodes.length > 0 ? nodes[LEFT]
+                                                           : null);
+
+        switch (opType) {
+
+            case OpTypes.COUNT :
+                sb.append(' ').append(Tokens.T_COUNT).append('(');
+                break;
+
+            case OpTypes.SUM :
+                sb.append(' ').append(Tokens.T_SUM).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.MIN :
+                sb.append(' ').append(Tokens.T_MIN).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.MAX :
+                sb.append(' ').append(Tokens.T_MAX).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.AVG :
+                sb.append(' ').append(Tokens.T_AVG).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.EVERY :
+                sb.append(' ').append(Tokens.T_EVERY).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.SOME :
+                sb.append(' ').append(Tokens.T_SOME).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.STDDEV_POP :
+                sb.append(' ').append(Tokens.T_STDDEV_POP).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.STDDEV_SAMP :
+                sb.append(' ').append(Tokens.T_STDDEV_SAMP).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.VAR_POP :
+                sb.append(' ').append(Tokens.T_VAR_POP).append('(');
+                sb.append(left).append(')');
+                break;
+
+            case OpTypes.VAR_SAMP :
+                sb.append(' ').append(Tokens.T_VAR_SAMP).append('(');
+                sb.append(left).append(')');
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionAggregate");
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        switch (opType) {
+
+            case OpTypes.COUNT :
+                sb.append("COUNT ");
+                break;
+
+            case OpTypes.SUM :
+                sb.append("SUM ");
+                break;
+
+            case OpTypes.MIN :
+                sb.append("MIN ");
+                break;
+
+            case OpTypes.MAX :
+                sb.append("MAX ");
+                break;
+
+            case OpTypes.AVG :
+                sb.append("AVG ");
+                break;
+
+            case OpTypes.EVERY :
+                sb.append(Tokens.T_EVERY).append(' ');
+                break;
+
+            case OpTypes.SOME :
+                sb.append(Tokens.T_SOME).append(' ');
+                break;
+
+            case OpTypes.STDDEV_POP :
+                sb.append(Tokens.T_STDDEV_POP).append(' ');
+                break;
+
+            case OpTypes.STDDEV_SAMP :
+                sb.append(Tokens.T_STDDEV_SAMP).append(' ');
+                break;
+
+            case OpTypes.VAR_POP :
+                sb.append(Tokens.T_VAR_POP).append(' ');
+                break;
+
+            case OpTypes.VAR_SAMP :
+                sb.append(Tokens.T_VAR_SAMP).append(' ');
+                break;
+        }
+
+        if (getLeftNode() != null) {
+            sb.append(" arg=[");
+            sb.append(nodes[LEFT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        return sb.toString();
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+
+        if (unresolvedSet == null) {
+            unresolvedSet = new ArrayListIdentity();
+        }
+
+        unresolvedSet.add(this);
+
+        return unresolvedSet;
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        if (nodes[LEFT].isUnresolvedParam()) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        if (isDistinctAggregate) {
+            if (nodes[LEFT].dataType.isLobType()) {
+                throw Error.error(ErrorCode.X_42534);
+            }
+        }
+
+        dataType = SetFunction.getType(opType, nodes[LEFT].dataType);
+    }
+
+    public boolean equals(Object other) {
+
+        if (!(other instanceof ExpressionAggregate)) {
+            return false;
+        }
+
+        return opType == ((ExpressionAggregate) other).opType
+               && exprSubType == ((ExpressionAggregate) other).exprSubType
+               && isDistinctAggregate
+                  == ((ExpressionAggregate) other)
+                      .isDistinctAggregate && equals(nodes,
+                          ((ExpressionAggregate) other).nodes);
+    }
+
+    public Object updateAggregatingValue(Session session, Object currValue) {
+
+        if (currValue == null) {
+            currValue = new SetFunction(opType, nodes[LEFT].dataType,
+                                        isDistinctAggregate);
+        }
+
+        Object newValue = nodes[LEFT].opType == OpTypes.ASTERISK
+                          ? ValuePool.INTEGER_1
+                          : nodes[LEFT].getValue(session);
+
+        ((SetFunction) currValue).add(session, newValue);
+
+        return currValue;
+    }
+
+    /**
+     * Get the result of a SetFunction or an ordinary value
+     *
+     * @param currValue instance of set function or value
+     * @param session context
+     * @return object
+     */
+    public Object getAggregatedValue(Session session, Object currValue) {
+
+        if (currValue == null) {
+            return opType == OpTypes.COUNT ? ValuePool.INTEGER_0
+                                           : null;
+        }
+
+        return ((SetFunction) currValue).getValue(session);
+    }
+}
diff --git a/src/org/hsqldb/ExpressionArithmetic.java b/src/org/hsqldb/ExpressionArithmetic.java
new file mode 100644
index 0000000..b541891
--- /dev/null
+++ b/src/org/hsqldb/ExpressionArithmetic.java
@@ -0,0 +1,474 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of arithmetic and concatenation operations
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ExpressionArithmetic extends Expression {
+
+    ExpressionArithmetic(int type, Expression left, Expression right) {
+
+        super(type);
+
+        nodes        = new Expression[BINARY];
+        nodes[LEFT]  = left;
+        nodes[RIGHT] = right;
+
+        switch (opType) {
+
+            case OpTypes.ADD :
+            case OpTypes.SUBTRACT :
+            case OpTypes.MULTIPLY :
+            case OpTypes.DIVIDE :
+            case OpTypes.CONCAT :
+                return;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+
+    ExpressionArithmetic(int type, Expression e) {
+
+        super(type);
+
+        nodes       = new Expression[UNARY];
+        nodes[LEFT] = e;
+
+        switch (opType) {
+
+            case OpTypes.NEGATE :
+                return;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                if (valueData == null) {
+                    return Tokens.T_NULL;
+                }
+
+                if (dataType == null) {
+                    throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+                }
+
+                return dataType.convertToSQLString(valueData);
+        }
+
+        String left  = getContextSQL(nodes.length > 0 ? nodes[LEFT]
+                                                      : null);
+        String right = getContextSQL(nodes.length > 1 ? nodes[RIGHT]
+                                                      : null);
+
+        switch (opType) {
+
+            case OpTypes.CAST :
+                sb.append(' ').append(Tokens.T_CAST).append('(');
+                sb.append(left).append(' ').append(Tokens.T_AS).append(' ');
+                sb.append(dataType.getTypeDefinition());
+                sb.append(')');
+                break;
+
+            case OpTypes.NEGATE :
+                sb.append('-').append(left);
+                break;
+
+            case OpTypes.ADD :
+                sb.append(left).append('+').append(right);
+                break;
+
+            case OpTypes.SUBTRACT :
+                sb.append(left).append('-').append(right);
+                break;
+
+            case OpTypes.MULTIPLY :
+                sb.append(left).append('*').append(right);
+                break;
+
+            case OpTypes.DIVIDE :
+                sb.append(left).append('/').append(right);
+                break;
+
+            case OpTypes.CONCAT :
+                sb.append(left).append("||").append(right);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                sb.append("VALUE = ").append(valueData);
+                sb.append(", TYPE = ").append(dataType.getNameString());
+
+                return sb.toString();
+
+            case OpTypes.ROW :
+
+            //
+            case OpTypes.TABLE :
+                sb.append("VALUELIST ");
+                sb.append(" TYPE = ").append(dataType.getNameString());
+
+                for (int i = 0; i < nodes.length; i++) {
+                    sb.append(nodes[i].describe(session, blanks + blanks));
+                    sb.append(' ');
+                }
+                break;
+
+            case OpTypes.NEGATE :
+                sb.append("NEGATE ");
+                break;
+
+            case OpTypes.ADD :
+                sb.append("ADD ");
+                break;
+
+            case OpTypes.SUBTRACT :
+                sb.append("SUBTRACT ");
+                break;
+
+            case OpTypes.MULTIPLY :
+                sb.append("MULTIPLY ");
+                break;
+
+            case OpTypes.DIVIDE :
+                sb.append("DIVIDE ");
+                break;
+
+            case OpTypes.CONCAT :
+                sb.append("CONCAT ");
+                break;
+
+            case OpTypes.CAST :
+                sb.append("CAST ");
+                sb.append(dataType.getTypeDefinition());
+                sb.append(' ');
+                break;
+        }
+
+        if (getLeftNode() != null) {
+            sb.append(" arg_left=[");
+            sb.append(nodes[LEFT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        if (getRightNode() != null) {
+            sb.append(" arg_right=[");
+            sb.append(nodes[RIGHT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        return sb.toString();
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+
+        if (opType == OpTypes.VALUE) {
+            return unresolvedSet;
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            unresolvedSet = nodes[i].resolveColumnReferences(rangeVarArray,
+                    rangeCount, unresolvedSet, acceptsSequences);
+        }
+
+        return unresolvedSet;
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                break;
+
+            case OpTypes.NEGATE :
+                if (nodes[LEFT].isUnresolvedParam()
+                        || nodes[LEFT].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                dataType = nodes[LEFT].dataType;
+
+                if (!dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                if (nodes[LEFT].opType == OpTypes.VALUE) {
+                    setAsConstantValue(session);
+                }
+                break;
+
+            case OpTypes.ADD :
+
+                // special case for concat using +
+                if ((nodes[LEFT].dataType != null && nodes[LEFT].dataType
+                        .isCharacterType()) || (nodes[RIGHT].dataType != null
+                                                && nodes[RIGHT].dataType
+                                                    .isCharacterType())) {
+                    opType = OpTypes.CONCAT;
+
+                    resolveTypesForConcat(session, parent);
+
+                    break;
+                }
+
+            // fall through
+            case OpTypes.SUBTRACT :
+            case OpTypes.MULTIPLY :
+            case OpTypes.DIVIDE :
+                resolveTypesForArithmetic(session);
+                break;
+
+            case OpTypes.CONCAT :
+                resolveTypesForConcat(session, parent);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+
+    void resolveTypesForArithmetic(Session session) {
+
+        if (nodes[LEFT].isUnresolvedParam()
+                && nodes[RIGHT].isUnresolvedParam()) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        if (nodes[LEFT].isUnresolvedParam()) {
+            nodes[LEFT].dataType = nodes[RIGHT].dataType;
+        } else if (nodes[RIGHT].isUnresolvedParam()) {
+            nodes[RIGHT].dataType = nodes[LEFT].dataType;
+        }
+
+        if (nodes[LEFT].dataType == null || nodes[RIGHT].dataType == null) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        // datetime subtract - type predetermined
+        if (nodes[LEFT].dataType.isDateTimeType()
+                && nodes[RIGHT].dataType.isDateTimeType()) {
+            if (dataType == null) {
+                throw Error.error(ErrorCode.X_42566);
+            } else if (!dataType.isIntervalType()
+                       || nodes[LEFT].dataType.typeCode
+                          != nodes[RIGHT].dataType.typeCode) {
+                throw Error.error(ErrorCode.X_42562);
+            }
+        } else {
+            dataType =
+                nodes[LEFT].dataType.getCombinedType(nodes[RIGHT].dataType,
+                    opType);
+
+            if (dataType.isDateTimeType()) {
+                if (nodes[LEFT].dataType.isIntervalType()) {
+                    if (opType != OpTypes.ADD) {
+                        throw Error.error(ErrorCode.X_42563);
+                    }
+
+                    Expression temp = nodes[LEFT];
+
+                    nodes[LEFT]  = nodes[RIGHT];
+                    nodes[RIGHT] = temp;
+                }
+            }
+        }
+
+        if (nodes[LEFT].opType == OpTypes.VALUE
+                && nodes[RIGHT].opType == OpTypes.VALUE) {
+            setAsConstantValue(session);
+        }
+    }
+
+    void resolveTypesForConcat(Session session, Expression parent) {
+
+        if (dataType != null) {
+            return;
+        }
+
+        if (nodes[LEFT].isUnresolvedParam()) {
+            nodes[LEFT].dataType = nodes[RIGHT].dataType;
+        } else if (nodes[RIGHT].isUnresolvedParam()) {
+            nodes[RIGHT].dataType = nodes[LEFT].dataType;
+        }
+
+        if (nodes[LEFT].dataType == null || nodes[RIGHT].dataType == null) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        if (nodes[LEFT].dataType.isBinaryType()
+                ^ nodes[RIGHT].dataType.isBinaryType()) {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        if (nodes[LEFT].dataType.isArrayType()) {
+            Expression e = nodes[RIGHT];
+
+            if (e.opType == OpTypes.ARRAY_ACCESS) {
+                if (parent == null) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                nodes[RIGHT]  = e.getLeftNode();
+                e.nodes[LEFT] = this;
+
+                parent.replaceNode(this, e);
+            }
+        }
+
+        if (nodes[LEFT].dataType.isArrayType()
+                ^ nodes[RIGHT].dataType.isArrayType()) {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        // conversion of right argument to character for backward compatibility
+        if (nodes[LEFT].dataType.isCharacterType()
+                && !nodes[RIGHT].dataType.isCharacterType()) {
+            Type newType = CharacterType.getCharacterType(Types.SQL_VARCHAR,
+                nodes[RIGHT].dataType.displaySize());
+
+            nodes[RIGHT] = ExpressionOp.getCastExpression(session,
+                    nodes[RIGHT], newType);
+        }
+
+        if (nodes[RIGHT].dataType.isCharacterType()
+                && !nodes[LEFT].dataType.isCharacterType()) {
+            Type newType = CharacterType.getCharacterType(Types.SQL_VARCHAR,
+                nodes[LEFT].dataType.displaySize());
+
+            nodes[LEFT] = ExpressionOp.getCastExpression(session, nodes[LEFT],
+                    newType);
+        }
+
+        dataType = nodes[LEFT].dataType.getCombinedType(nodes[RIGHT].dataType,
+                OpTypes.CONCAT);
+
+        if (nodes[LEFT].opType == OpTypes.VALUE
+                && nodes[RIGHT].opType == OpTypes.VALUE) {
+            setAsConstantValue(session);
+        }
+    }
+
+    public Object getValue(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                return valueData;
+
+            case OpTypes.SIMPLE_COLUMN : {
+                Object[] data =
+                    (Object[]) session.sessionContext
+                        .rangeIterators[rangePosition].getCurrent();
+
+                return data[columnIndex];
+            }
+            case OpTypes.NEGATE :
+                return ((NumberType) dataType).negate(
+                    nodes[LEFT].getValue(session, nodes[LEFT].dataType));
+        }
+
+        Object a = nodes[LEFT].getValue(session);
+        Object b = nodes[RIGHT].getValue(session);
+
+        switch (opType) {
+
+            case OpTypes.ADD :
+                return dataType.add(a, b, nodes[RIGHT].dataType);
+
+            case OpTypes.SUBTRACT :
+                return dataType.subtract(a, b, nodes[RIGHT].dataType);
+
+            case OpTypes.MULTIPLY :
+                return dataType.multiply(a, b);
+
+            case OpTypes.DIVIDE :
+                return dataType.divide(a, b);
+
+            case OpTypes.CONCAT :
+                return dataType.concat(session, a, b);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+}
diff --git a/src/org/hsqldb/ExpressionColumn.java b/src/org/hsqldb/ExpressionColumn.java
new file mode 100644
index 0000000..4386efd
--- /dev/null
+++ b/src/org/hsqldb/ExpressionColumn.java
@@ -0,0 +1,946 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.HsqlNameManager.SimpleName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayListIdentity;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.Set;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of column, variable, parameter, etc. access operations.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ExpressionColumn extends Expression {
+
+    public final static ExpressionColumn[] emptyArray =
+        new ExpressionColumn[]{};
+
+    //
+    ColumnSchema  column;
+    String        schema;
+    String        tableName;
+    String        columnName;
+    RangeVariable rangeVariable;
+
+    //
+    NumberSequence sequence;
+    boolean        isWritable;    // = false; true if column of writable table
+
+    //
+    boolean isParam;
+
+    //
+    boolean strictReference;
+
+    /**
+     * Creates a OpCodes.COLUMN expression
+     */
+    ExpressionColumn(String schema, String table, String column,
+                     boolean strictReference) {
+
+        super(OpTypes.COLUMN);
+
+        this.schema          = schema;
+        this.tableName       = table;
+        this.columnName      = column;
+        this.strictReference = strictReference;
+    }
+
+    ExpressionColumn(ColumnSchema column) {
+
+        super(OpTypes.COLUMN);
+
+        this.column   = column;
+        this.dataType = column.getDataType();
+        columnName    = column.getName().name;
+    }
+
+    ExpressionColumn(RangeVariable rangeVar, int index) {
+
+        super(OpTypes.COLUMN);
+
+        columnIndex = index;
+
+        setAutoAttributesAsColumn(rangeVar, columnIndex);
+    }
+
+    /**
+     * Creates a temporary OpCodes.COLUMN expression
+     */
+    ExpressionColumn(Expression e, int colIndex, int rangePosition) {
+
+        super(OpTypes.SIMPLE_COLUMN);
+
+        dataType           = e.dataType;
+        columnIndex        = colIndex;
+        alias              = e.alias;
+        this.rangePosition = rangePosition;
+    }
+
+    ExpressionColumn() {
+        super(OpTypes.ASTERISK);
+    }
+
+    ExpressionColumn(int type) {
+
+        super(type);
+
+        if (type == OpTypes.DYNAMIC_PARAM) {
+            isParam = true;
+        }
+    }
+
+    ExpressionColumn(Expression[] nodes, String name) {
+
+        super(OpTypes.COALESCE);
+
+        this.nodes      = nodes;
+        this.columnName = name;
+    }
+
+    /**
+     * Creates an OpCodes.ASTERISK expression
+     */
+    ExpressionColumn(String schema, String table) {
+
+        super(OpTypes.MULTICOLUMN);
+
+        this.schema = schema;
+        tableName   = table;
+    }
+
+    /**
+     * Creates a OpCodes.SEQUENCE expression
+     */
+    ExpressionColumn(NumberSequence sequence) {
+
+        super(OpTypes.SEQUENCE);
+
+        this.sequence = sequence;
+        dataType      = sequence.getDataType();
+    }
+
+    void setAutoAttributesAsColumn(RangeVariable range, int i) {
+
+        columnIndex   = i;
+        column        = range.getColumn(i);
+        dataType      = column.getDataType();
+        columnName    = range.getColumnAlias(i);
+        tableName     = range.getTableAlias();
+        rangeVariable = range;
+
+        rangeVariable.addColumn(columnIndex);
+    }
+
+    void setAttributesAsColumn(RangeVariable range, int i) {
+
+        if (range.variables != null) {
+            columnIndex   = i;
+            column        = range.getColumn(i);
+            dataType      = column.getDataType();
+            rangeVariable = range;
+        } else {
+            columnIndex   = i;
+            column        = range.getColumn(i);
+            dataType      = column.getDataType();
+            rangeVariable = range;
+
+            rangeVariable.addColumn(columnIndex);
+        }
+    }
+
+    void setAttributesAsColumn(ColumnSchema column, boolean isWritable) {
+
+        this.column     = column;
+        dataType        = column.getDataType();
+        this.isWritable = isWritable;
+    }
+
+    SimpleName getSimpleName() {
+
+        if (alias != null) {
+            return alias;
+        }
+
+        if (column != null) {
+            return column.getName();
+        }
+
+        if (opType == OpTypes.COALESCE) {
+            return nodes[LEFT].getSimpleName();
+        }
+
+        return null;
+    }
+
+    String getAlias() {
+
+        if (alias != null) {
+            return alias.name;
+        }
+
+        if (opType == OpTypes.COLUMN) {
+            return columnName;
+        }
+
+        if (opType == OpTypes.COALESCE) {
+            return columnName;
+        }
+
+        return "";
+    }
+
+    public String getBaseColumnName() {
+
+        if (opType == OpTypes.COLUMN && rangeVariable != null) {
+            return rangeVariable.getTable().getColumn(
+                columnIndex).getName().name;
+        }
+
+        return null;
+    }
+
+    public HsqlName getBaseColumnHsqlName() {
+        return column.getName();
+    }
+
+    void collectObjectNames(Set set) {
+
+        switch (opType) {
+
+            case OpTypes.SEQUENCE :
+                HsqlName name = sequence.getName();
+
+                set.add(name);
+
+                return;
+
+            case OpTypes.MULTICOLUMN :
+            case OpTypes.DYNAMIC_PARAM :
+            case OpTypes.ASTERISK :
+            case OpTypes.SIMPLE_COLUMN :
+            case OpTypes.COALESCE :
+                break;
+
+            case OpTypes.PARAMETER :
+            case OpTypes.VARIABLE :
+                break;
+
+            case OpTypes.COLUMN :
+                set.add(column.getName());
+
+                if (column.getName().parent != null) {
+                    set.add(column.getName().parent);
+                }
+
+                return;
+        }
+    }
+
+    String getColumnName() {
+
+        if (opType == OpTypes.COLUMN && column != null) {
+            return column.getName().name;
+        }
+
+        return getAlias();
+    }
+
+    ColumnSchema getColumn() {
+        return column;
+    }
+
+    String getSchemaName() {
+        return schema;
+    }
+
+    RangeVariable getRangeVariable() {
+        return rangeVariable;
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+
+        switch (opType) {
+
+            case OpTypes.SEQUENCE :
+                if (!acceptsSequences) {
+                    throw Error.error(ErrorCode.X_42598);
+                }
+                break;
+
+            case OpTypes.MULTICOLUMN :
+            case OpTypes.DYNAMIC_PARAM :
+            case OpTypes.ASTERISK :
+            case OpTypes.SIMPLE_COLUMN :
+            case OpTypes.COALESCE :
+                break;
+
+            case OpTypes.PARAMETER :
+            case OpTypes.VARIABLE :
+            case OpTypes.COLUMN : {
+                boolean resolved       = false;
+                boolean tableQualified = tableName != null;
+
+                if (rangeVariable != null) {
+                    return unresolvedSet;
+                }
+
+                for (int i = 0; i < rangeCount; i++) {
+                    RangeVariable rangeVar = rangeVarArray[i];
+
+                    if (rangeVar == null) {
+                        continue;
+                    }
+
+                    if (resolved) {
+                        if (resolvesDuplicateColumnReference(rangeVar)) {
+                            if (strictReference) {
+                                String message = getColumnName();
+
+                                if (alias != null) {
+                                    StringBuffer sb =
+                                        new StringBuffer(message);
+
+                                    sb.append(' ').append(Tokens.T_AS).append(
+                                        ' ').append(alias.getStatementName());
+
+                                    message = sb.toString();
+                                }
+
+                                throw Error.error(ErrorCode.X_42580, message);
+                            }
+                        }
+                    } else {
+                        if (resolveColumnReference(rangeVar)) {
+                            if (tableQualified) {
+                                return unresolvedSet;
+                            }
+
+                            resolved = true;
+
+                            continue;
+                        }
+                    }
+                }
+
+                if (resolved) {
+                    return unresolvedSet;
+                }
+
+                if (unresolvedSet == null) {
+                    unresolvedSet = new ArrayListIdentity();
+                }
+
+                unresolvedSet.add(this);
+            }
+        }
+
+        return unresolvedSet;
+    }
+
+    public boolean resolveColumnReference(RangeVariable rangeVar) {
+
+        if (tableName == null) {
+            Expression e = rangeVar.getColumnExpression(columnName);
+
+            if (e != null) {
+                opType   = e.opType;
+                nodes    = e.nodes;
+                dataType = e.dataType;
+
+                return true;
+            }
+
+            if (rangeVar.variables != null) {
+                int colIndex = rangeVar.findColumn(columnName);
+
+                if (colIndex == -1) {
+                    return false;
+                }
+
+                ColumnSchema column = rangeVar.getColumn(colIndex);
+
+                if (column.getParameterMode()
+                        == SchemaObject.ParameterModes.PARAM_OUT) {
+                    return false;
+                } else {
+                    opType = rangeVar.isVariable ? OpTypes.VARIABLE
+                                                 : OpTypes.PARAMETER;
+
+                    setAttributesAsColumn(rangeVar, colIndex);
+
+                    return true;
+                }
+            }
+        }
+
+        if (!rangeVar.resolvesTableName(this)) {
+            return false;
+        }
+
+        int colIndex = rangeVar.findColumn(columnName);
+
+        if (colIndex != -1) {
+            setAttributesAsColumn(rangeVar, colIndex);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    boolean resolvesDuplicateColumnReference(RangeVariable rangeVar) {
+
+        if (tableName == null) {
+            Expression e = rangeVar.getColumnExpression(columnName);
+
+            if (e != null) {
+                return false;
+            }
+
+            if (rangeVar.variables != null) {
+                int colIndex = rangeVar.findColumn(columnName);
+
+                if (colIndex == -1) {
+                    return false;
+                }
+
+                ColumnSchema column = rangeVar.getColumn(colIndex);
+
+                if (column.getParameterMode()
+                        == SchemaObject.ParameterModes.PARAM_OUT) {
+                    return false;
+                } else {
+                    return true;
+                }
+            }
+        }
+
+        if (!rangeVar.resolvesTableName(this)) {
+            return false;
+        }
+
+        int colIndex = rangeVar.findColumn(columnName);
+
+        if (colIndex != -1) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        switch (opType) {
+
+            case OpTypes.DEFAULT :
+                if (parent != null && parent.opType != OpTypes.ROW) {
+                    throw Error.error(ErrorCode.X_42544);
+                }
+                break;
+
+            case OpTypes.COALESCE : {
+                Type type = null;
+
+                for (int i = 0; i < nodes.length; i++) {
+                    type = Type.getAggregateType(nodes[i].dataType, type);
+                }
+
+                dataType = type;
+
+                break;
+            }
+        }
+    }
+
+    public Object getValue(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.DEFAULT :
+                return null;
+
+            case OpTypes.VARIABLE : {
+                return session.sessionContext.routineVariables[columnIndex];
+            }
+            case OpTypes.PARAMETER : {
+                return session.sessionContext.routineArguments[columnIndex];
+            }
+            case OpTypes.COLUMN : {
+                Object[] data =
+                    (Object[]) session.sessionContext
+                        .rangeIterators[rangeVariable.rangePosition]
+                        .getCurrent();
+                Object value = data[columnIndex];
+
+                if (dataType != column.dataType) {
+                    value = dataType.convertToType(session, value,
+                                                   column.dataType);
+                }
+
+                return value;
+            }
+            case OpTypes.SIMPLE_COLUMN : {
+                Object[] data =
+                    (Object[]) session.sessionContext
+                        .rangeIterators[rangePosition].getCurrent();
+
+                return data[columnIndex];
+            }
+            case OpTypes.COALESCE : {
+                Object value = null;
+
+                for (int i = 0; i < nodes.length; i++) {
+                    value = nodes[i].getValue(session, dataType);
+
+                    if (value != null) {
+                        return value;
+                    }
+                }
+
+                return value;
+            }
+            case OpTypes.DYNAMIC_PARAM : {
+                return session.sessionContext.dynamicArguments[parameterIndex];
+            }
+            case OpTypes.SEQUENCE : {
+                return session.sessionData.getSequenceValue(sequence);
+            }
+            case OpTypes.ASTERISK :
+            case OpTypes.MULTICOLUMN :
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionColumn");
+        }
+    }
+
+    public String getSQL() {
+
+        switch (opType) {
+
+            case OpTypes.DEFAULT :
+                return Tokens.T_DEFAULT;
+
+            case OpTypes.DYNAMIC_PARAM :
+                return Tokens.T_QUESTION;
+
+            case OpTypes.ASTERISK :
+                return "*";
+
+            case OpTypes.COALESCE :
+                return alias.getStatementName();
+
+            case OpTypes.VARIABLE :
+            case OpTypes.PARAMETER :
+            case OpTypes.COLUMN : {
+                if (column == null) {
+                    if (alias != null) {
+                        return alias.getStatementName();
+                    } else {
+                        return columnName;
+                    }
+                }
+
+                if (rangeVariable.tableAlias == null) {
+                    return column.getName().getSchemaQualifiedStatementName();
+                } else {
+                    StringBuffer sb = new StringBuffer();
+
+                    sb.append(rangeVariable.tableAlias.getStatementName());
+                    sb.append('.');
+                    sb.append(column.getName().statementName);
+
+                    return sb.toString();
+                }
+            }
+            case OpTypes.MULTICOLUMN : {
+                if (nodes.length == 0) {
+                    return "*";
+                }
+
+                StringBuffer sb = new StringBuffer();
+
+                for (int i = 0; i < nodes.length; i++) {
+                    Expression e = nodes[i];
+
+                    if (i > 0) {
+                        sb.append(',');
+                    }
+
+                    String s = e.getSQL();
+
+                    sb.append(s);
+                }
+
+                return sb.toString();
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionColumn");
+        }
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        switch (opType) {
+
+            case OpTypes.DEFAULT :
+                sb.append(Tokens.T_DEFAULT);
+                break;
+
+            case OpTypes.ASTERISK :
+                sb.append("OpTypes.ASTERISK ");
+                break;
+
+            case OpTypes.VARIABLE :
+                sb.append("VARIABLE: ");
+                sb.append(column.getName().name);
+                break;
+
+            case OpTypes.PARAMETER :
+                sb.append(Tokens.T_PARAMETER).append(": ");
+                sb.append(column.getName().name);
+                break;
+
+            case OpTypes.COALESCE :
+                sb.append(Tokens.T_COLUMN).append(": ");
+                sb.append(columnName);
+
+                if (alias != null) {
+                    sb.append(" AS ").append(alias.name);
+                }
+                break;
+
+            case OpTypes.COLUMN :
+                sb.append(Tokens.T_COLUMN).append(": ");
+                sb.append(column.getName().getSchemaQualifiedStatementName());
+
+                if (alias != null) {
+                    sb.append(" AS ").append(alias.name);
+                }
+                break;
+
+            case OpTypes.DYNAMIC_PARAM :
+                sb.append("DYNAMIC PARAM: ");
+                sb.append(", TYPE = ").append(dataType.getNameString());
+                break;
+
+            case OpTypes.SEQUENCE :
+                sb.append(Tokens.T_SEQUENCE).append(": ");
+                sb.append(sequence.getName().name);
+                break;
+
+            case OpTypes.MULTICOLUMN :
+
+            // shouldn't get here
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Returns the table name used in query
+     *
+     * @return table name
+     */
+    String getTableName() {
+
+        if (opType == OpTypes.MULTICOLUMN) {
+            return tableName;
+        }
+
+        if (opType == OpTypes.COLUMN) {
+            if (rangeVariable == null) {
+                return tableName;
+            } else {
+                return rangeVariable.getTable().getName().name;
+            }
+        }
+
+        return "";
+    }
+
+    static void checkColumnsResolved(HsqlList set) {
+
+        if (set != null && !set.isEmpty()) {
+            StringBuffer sb = new StringBuffer();
+            Expression   e  = (Expression) set.get(0);
+
+            if (e instanceof ExpressionColumn) {
+                ExpressionColumn c = (ExpressionColumn) e;
+
+                if (c.schema != null) {
+                    sb.append(c.schema + '.');
+                }
+
+                if (c.tableName != null) {
+                    sb.append(c.tableName + '.');
+                }
+
+                throw Error.error(ErrorCode.X_42501,
+                                  sb.toString() + c.getColumnName());
+            } else {
+                throw Error.error(ErrorCode.X_42501);
+            }
+        }
+    }
+
+    public OrderedHashSet getUnkeyedColumns(OrderedHashSet unresolvedSet) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            unresolvedSet = nodes[i].getUnkeyedColumns(unresolvedSet);
+        }
+
+        if (opType == OpTypes.COLUMN
+                && !rangeVariable.hasKeyedColumnInGroupBy) {
+            if (unresolvedSet == null) {
+                unresolvedSet = new OrderedHashSet();
+            }
+
+            unresolvedSet.add(this);
+        }
+
+        return unresolvedSet;
+    }
+
+    /**
+     * collects all range variables in expression tree
+     */
+    void collectRangeVariables(RangeVariable[] rangeVariables, Set set) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].collectRangeVariables(rangeVariables, set);
+            }
+        }
+
+        if (rangeVariable != null) {
+            for (int i = 0; i < rangeVariables.length; i++) {
+                if (rangeVariables[i] == rangeVariable) {
+                    set.add(rangeVariable);
+
+                    break;
+                }
+            }
+        }
+    }
+
+    Expression replaceAliasInOrderBy(Expression[] columns, int length) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            nodes[i] = nodes[i].replaceAliasInOrderBy(columns, length);
+        }
+
+        switch (opType) {
+
+            case OpTypes.COALESCE :
+            case OpTypes.COLUMN : {
+                for (int i = 0; i < length; i++) {
+                    SimpleName aliasName = columns[i].alias;
+                    String     alias     = aliasName == null ? null
+                                                             : aliasName.name;
+
+                    if (schema == null && tableName == null
+                            && columnName.equals(alias)) {
+                        return columns[i];
+                    }
+                }
+
+                for (int i = 0; i < length; i++) {
+                    if (columns[i] instanceof ExpressionColumn) {
+                        if (this.equals(columns[i])) {
+                            return columns[i];
+                        }
+
+                        if (tableName == null && schema == null
+                                && columnName
+                                    .equals(((ExpressionColumn) columns[i])
+                                        .columnName)) {
+                            return columns[i];
+                        }
+                    }
+                }
+            }
+            default :
+        }
+
+        return this;
+    }
+
+    Expression replaceColumnReferences(RangeVariable range,
+                                       Expression[] list) {
+
+        if (opType == OpTypes.COLUMN && rangeVariable == range) {
+            return list[columnIndex];
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            nodes[i] = nodes[i].replaceColumnReferences(range, list);
+        }
+
+        return this;
+    }
+
+    int findMatchingRangeVariableIndex(RangeVariable[] rangeVarArray) {
+
+        for (int i = 0; i < rangeVarArray.length; i++) {
+            RangeVariable rangeVar = rangeVarArray[i];
+
+            if (rangeVar.resolvesTableName(this)) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * return true if given RangeVariable is used in expression tree
+     */
+    boolean hasReference(RangeVariable range) {
+
+        if (range == rangeVariable) {
+            return true;
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                if (nodes[i].hasReference(range)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * SIMPLE_COLUMN expressions can be of different Java types
+     */
+    public boolean equals(Expression other) {
+
+        if (other == this) {
+            return true;
+        }
+
+        if (other == null) {
+            return false;
+        }
+
+        if (opType != ((Expression) other).opType) {
+            return false;
+        }
+
+        switch (opType) {
+
+            case OpTypes.SIMPLE_COLUMN :
+                return this.columnIndex == ((Expression) other).columnIndex;
+
+            case OpTypes.COALESCE :
+                return nodes == ((Expression) other).nodes;
+
+            case OpTypes.COLUMN :
+                return column == ((Expression) other).getColumn();
+
+            default :
+                return false;
+        }
+    }
+
+    void replaceRangeVariables(RangeVariable[] ranges,
+                               RangeVariable[] newRanges) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            nodes[i].replaceRangeVariables(ranges, newRanges);
+        }
+
+        for (int i = 0; i < ranges.length; i++) {
+            if (rangeVariable == ranges[i]) {
+                rangeVariable = newRanges[i];
+
+                break;
+            }
+        }
+    }
+
+    void resetColumnReferences() {
+        rangeVariable = null;
+        columnIndex   = -1;
+    }
+
+    public boolean isIndexable(RangeVariable range) {
+
+        if (opType == OpTypes.COLUMN) {
+            return rangeVariable == range;
+        }
+
+        return false;
+    }
+
+    public boolean isUnresolvedParam() {
+        return isParam && dataType == null;
+    }
+
+    boolean isDynamicParam() {
+        return isParam;
+    }
+}
diff --git a/src/org/hsqldb/ExpressionColumnAccessor.java b/src/org/hsqldb/ExpressionColumnAccessor.java
new file mode 100644
index 0000000..02bbe93
--- /dev/null
+++ b/src/org/hsqldb/ExpressionColumnAccessor.java
@@ -0,0 +1,171 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.Set;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of column used as assignment target.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class ExpressionColumnAccessor extends Expression {
+
+    ColumnSchema column;
+
+    ExpressionColumnAccessor(ColumnSchema column) {
+
+        super(OpTypes.COLUMN);
+
+        this.column   = column;
+        this.dataType = column.getDataType();
+    }
+
+    String getAlias() {
+        return column.getNameString();
+    }
+
+    void collectObjectNames(Set set) {
+
+        set.add(column.getName());
+
+        if (column.getName().parent != null) {
+            set.add(column.getName().parent);
+        }
+    }
+
+    String getColumnName() {
+        return column.getNameString();
+    }
+
+    ColumnSchema getColumn() {
+        return column;
+    }
+
+    RangeVariable getRangeVariable() {
+        return null;
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+        return unresolvedSet;
+    }
+
+    public void resolveTypes(Session session, Expression parent) {}
+
+    public Object getValue(Session session) {
+        return null;
+    }
+
+    public String getSQL() {
+        return column.getName().statementName;
+    }
+
+    protected String describe(Session session, int blanks) {
+        return column.getName().name;
+    }
+
+    public OrderedHashSet getUnkeyedColumns(OrderedHashSet unresolvedSet) {
+        return unresolvedSet;
+    }
+
+    /**
+     * collects all range variables in expression tree
+     */
+    void collectRangeVariables(RangeVariable[] rangeVariables, Set set) {}
+
+    Expression replaceAliasInOrderBy(Expression[] columns, int length) {
+        return this;
+    }
+
+    Expression replaceColumnReferences(RangeVariable range,
+                                       Expression[] list) {
+        return this;
+    }
+
+    int findMatchingRangeVariableIndex(RangeVariable[] rangeVarArray) {
+        return -1;
+    }
+
+    /**
+     * return true if given RangeVariable is used in expression tree
+     */
+    boolean hasReference(RangeVariable range) {
+        return false;
+    }
+
+    /**
+     * SIMPLE_COLUMN expressions can be of different Java types
+     */
+    public boolean equals(Expression other) {
+
+        if (other == this) {
+            return true;
+        }
+
+        if (other == null) {
+            return false;
+        }
+
+        if (opType != ((Expression) other).opType) {
+            return false;
+        }
+
+        return column == ((Expression) other).getColumn();
+    }
+
+    void replaceRangeVariables(RangeVariable[] ranges,
+                               RangeVariable[] newRanges) {}
+
+    void resetColumnReferences() {}
+
+    public boolean isIndexable(RangeVariable range) {
+        return false;
+    }
+
+    public boolean isUnresolvedParam() {
+        return false;
+    }
+
+    boolean isDynamicParam() {
+        return false;
+    }
+
+    public Type getDataType() {
+        return column.getDataType();
+    }
+}
diff --git a/src/org/hsqldb/ExpressionLike.java b/src/org/hsqldb/ExpressionLike.java
new file mode 100644
index 0000000..cc3d775
--- /dev/null
+++ b/src/org/hsqldb/ExpressionLike.java
@@ -0,0 +1,378 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.Set;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of LIKE operations
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class ExpressionLike extends ExpressionLogical {
+
+    private final static int ESCAPE  = 2;
+    private final static int TERNARY = 3;
+    private Like             likeObject;
+
+    /**
+     * Creates a LIKE expression
+     */
+    ExpressionLike(Expression left, Expression right, Expression escape,
+                   boolean noOptimisation) {
+
+        super(OpTypes.LIKE);
+
+        nodes               = new Expression[TERNARY];
+        nodes[LEFT]         = left;
+        nodes[RIGHT]        = right;
+        nodes[ESCAPE]       = escape;
+        likeObject          = new Like();
+        this.noOptimisation = noOptimisation;
+    }
+
+    private ExpressionLike(ExpressionLike other) {
+
+        super(OpTypes.LIKE);
+
+        this.nodes      = other.nodes;
+        this.likeObject = other.likeObject;
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                unresolvedSet = nodes[i].resolveColumnReferences(rangeVarArray,
+                        rangeCount, unresolvedSet, acceptsSequences);
+            }
+        }
+
+        return unresolvedSet;
+    }
+
+    public Object getValue(Session session) {
+
+        if (opType != OpTypes.LIKE) {
+            return super.getValue(session);
+        }
+
+        Object leftValue   = nodes[LEFT].getValue(session);
+        Object rightValue  = nodes[RIGHT].getValue(session);
+        Object escapeValue = nodes[ESCAPE] == null ? null
+                                                   : nodes[ESCAPE].getValue(
+                                                       session);
+
+        if (likeObject.isVariable) {
+            synchronized (likeObject) {
+                likeObject.setPattern(session, rightValue, escapeValue,
+                                      nodes[ESCAPE] != null);
+
+                return likeObject.compare(session, leftValue);
+            }
+        }
+
+        return likeObject.compare(session, leftValue);
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        boolean isEscapeFixedConstant = true;
+
+        if (nodes[ESCAPE] != null) {
+            if (nodes[ESCAPE].isUnresolvedParam()) {
+                throw Error.error(ErrorCode.X_42567);
+            }
+
+            nodes[ESCAPE].resolveTypes(session, this);
+
+            isEscapeFixedConstant = nodes[ESCAPE].opType == OpTypes.VALUE;
+
+            if (isEscapeFixedConstant) {
+                nodes[ESCAPE].setAsConstantValue(session);
+
+                if (nodes[ESCAPE].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (nodes[ESCAPE].valueData != null) {
+                    long length;
+
+                    switch (nodes[ESCAPE].dataType.typeCode) {
+
+                        case Types.SQL_CHAR :
+                        case Types.SQL_VARCHAR :
+                            length =
+                                ((String) nodes[ESCAPE].valueData).length();
+                            break;
+
+                        case Types.SQL_BINARY :
+                        case Types.SQL_VARBINARY :
+                            length =
+                                ((BinaryData) nodes[ESCAPE].valueData).length(
+                                    session);
+                            break;
+
+                        default :
+                            throw Error.error(ErrorCode.X_42563);
+                    }
+
+                    if (length != 1) {
+                        throw Error.error(ErrorCode.X_22019);
+                    }
+                }
+            }
+        }
+
+        if (nodes[LEFT].dataType == null && nodes[RIGHT].dataType == null) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        if (nodes[LEFT].isUnresolvedParam()) {
+            nodes[LEFT].dataType = nodes[RIGHT].dataType.isBinaryType()
+                                   ? (Type) Type.SQL_VARBINARY_DEFAULT
+                                   : (Type) Type.SQL_VARCHAR_DEFAULT;
+        } else if (nodes[RIGHT].isUnresolvedParam()) {
+            nodes[RIGHT].dataType = nodes[LEFT].dataType.isBinaryType()
+                                    ? (Type) Type.SQL_VARBINARY_DEFAULT
+                                    : (Type) Type.SQL_VARCHAR_DEFAULT;
+        }
+
+        if (nodes[LEFT].dataType == null || nodes[RIGHT].dataType == null) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        if (nodes[LEFT].dataType.isCharacterType()
+                && nodes[RIGHT].dataType.isCharacterType()
+                && (nodes[ESCAPE] == null
+                    || nodes[ESCAPE].dataType.isCharacterType())) {
+            boolean ignoreCase =
+                nodes[LEFT].dataType.typeCode == Types.VARCHAR_IGNORECASE
+                || nodes[RIGHT].dataType.typeCode == Types.VARCHAR_IGNORECASE;
+
+            likeObject.setIgnoreCase(ignoreCase);
+        } else if (nodes[LEFT].dataType.isBinaryType()
+                   && nodes[RIGHT].dataType.isBinaryType()
+                   && (nodes[ESCAPE] == null
+                       || nodes[ESCAPE].dataType.isBinaryType())) {
+            likeObject.isBinary = true;
+        } else {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        likeObject.dataType = nodes[LEFT].dataType;
+
+        boolean isRightArgFixedConstant = nodes[RIGHT].opType == OpTypes.VALUE;
+
+        if (isRightArgFixedConstant && isEscapeFixedConstant
+                && nodes[LEFT].opType == OpTypes.VALUE) {
+            setAsConstantValue(session);
+
+            likeObject = null;
+
+            return;
+        }
+
+        if (isRightArgFixedConstant && isEscapeFixedConstant) {
+            likeObject.isVariable = false;
+        } else {
+            return;
+        }
+
+        Object pattern = isRightArgFixedConstant
+                         ? nodes[RIGHT].getValue(session)
+                         : null;
+        boolean constantEscape = isEscapeFixedConstant
+                                 && nodes[ESCAPE] != null;
+        Object escape = constantEscape
+                        ? nodes[ESCAPE].getValue(session)
+                        : null;
+
+        likeObject.setPattern(session, pattern, escape, nodes[ESCAPE] != null);
+
+        if (noOptimisation) {
+            return;
+        }
+
+        if (likeObject.isEquivalentToUnknownPredicate()) {
+            this.setAsConstantValue(null);
+
+            likeObject = null;
+        } else if (likeObject.isEquivalentToEqualsPredicate()) {
+            opType = OpTypes.EQUAL;
+            nodes[RIGHT] = new ExpressionValue(likeObject.getRangeLow(),
+                                               Type.SQL_VARCHAR);
+            likeObject = null;
+        } else if (likeObject.isEquivalentToNotNullPredicate()) {
+            Expression notNull = new ExpressionLogical(OpTypes.IS_NULL,
+                nodes[LEFT]);
+
+            opType      = OpTypes.NOT;
+            nodes       = new Expression[UNARY];
+            nodes[LEFT] = notNull;
+            likeObject  = null;
+        } else {
+            if (nodes[LEFT].opType != OpTypes.COLUMN) {
+                return;
+            }
+
+            if (!nodes[LEFT].dataType.isCharacterType()) {
+                return;
+            }
+
+            boolean between = false;
+            boolean like    = false;
+            boolean larger  = false;
+
+            if (likeObject.isEquivalentToBetweenPredicate()) {
+
+                // X LIKE 'abc%' <=> X >= 'abc' AND X <= 'abc' || max_collation_char
+                larger  = likeObject.hasCollation;
+                between = !larger;
+                like    = larger;
+            } else if (likeObject
+                    .isEquivalentToBetweenPredicateAugmentedWithLike()) {
+
+                // X LIKE 'abc%...' <=> X >= 'abc' AND X <= 'abc' || max_collation_char AND X LIKE 'abc%...'
+                larger  = likeObject.hasCollation;
+                between = !larger;
+                like    = true;
+            }
+
+            if (!between && !larger) {
+                return;
+            }
+
+            Expression leftBound =
+                new ExpressionValue(likeObject.getRangeLow(),
+                                    Type.SQL_VARCHAR);
+            Expression rightBound =
+                new ExpressionValue(likeObject.getRangeHigh(session),
+                                    Type.SQL_VARCHAR);
+
+            if (between && !like) {
+                Expression leftOld = nodes[LEFT];
+
+                nodes = new Expression[BINARY];
+                nodes[LEFT] = new ExpressionLogical(OpTypes.GREATER_EQUAL,
+                                                    leftOld, leftBound);
+                nodes[RIGHT] = new ExpressionLogical(OpTypes.SMALLER_EQUAL,
+                                                     leftOld, rightBound);
+                opType     = OpTypes.AND;
+                likeObject = null;
+            } else if (between && like) {
+                Expression gte = new ExpressionLogical(OpTypes.GREATER_EQUAL,
+                                                       nodes[LEFT], leftBound);
+                Expression lte = new ExpressionLogical(OpTypes.SMALLER_EQUAL,
+                                                       nodes[LEFT],
+                                                       rightBound);
+                ExpressionLike newLike = new ExpressionLike(this);
+
+                nodes        = new Expression[BINARY];
+                likeObject   = null;
+                nodes[LEFT]  = new ExpressionLogical(OpTypes.AND, gte, lte);
+                nodes[RIGHT] = newLike;
+                opType       = OpTypes.AND;
+            } else if (larger) {
+                Expression gte = new ExpressionLogical(OpTypes.GREATER_EQUAL,
+                                                       nodes[LEFT], leftBound);
+                ExpressionLike newLike = new ExpressionLike(this);
+
+                nodes        = new Expression[BINARY];
+                likeObject   = null;
+                nodes[LEFT]  = gte;
+                nodes[RIGHT] = newLike;
+                opType       = OpTypes.AND;
+            }
+        }
+    }
+
+    public String getSQL() {
+
+        if (likeObject == null) {
+            return super.getSQL();
+        }
+
+        String       left  = getContextSQL(nodes[LEFT]);
+        String       right = getContextSQL(nodes[RIGHT]);
+        StringBuffer sb    = new StringBuffer();
+
+        sb.append(left).append(' ').append(Tokens.T_LIKE).append(' ');
+        sb.append(right);
+
+        /** @todo fredt - scripting of non-ascii escapes needs changes to general script logging */
+        if (nodes[ESCAPE] != null) {
+            sb.append(' ').append(Tokens.T_ESCAPE).append(' ');
+            sb.append(nodes[ESCAPE].getSQL());
+            sb.append(' ');
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        if (likeObject == null) {
+            return super.describe(session, blanks);
+        }
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        sb.append("LIKE ");
+
+        sb.append(likeObject.describe(session));
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/ExpressionLogical.java b/src/org/hsqldb/ExpressionLogical.java
new file mode 100644
index 0000000..a7d3b7f
--- /dev/null
+++ b/src/org/hsqldb/ExpressionLogical.java
@@ -0,0 +1,1886 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.types.DTIType;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.Type;
+
+/**
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ExpressionLogical extends Expression {
+
+    boolean noOptimisation;
+    boolean isQuantified;
+
+    /**
+     * For LIKE
+     */
+    ExpressionLogical(int type) {
+
+        super(type);
+
+        dataType = Type.SQL_BOOLEAN;
+    }
+
+    /**
+     * For boolean constants
+     */
+    ExpressionLogical(boolean b) {
+
+        super(OpTypes.VALUE);
+
+        dataType  = Type.SQL_BOOLEAN;
+        valueData = b ? Boolean.TRUE
+                      : Boolean.FALSE;
+    }
+
+    /*
+     * Create an equality expressions using existing columns and
+     * range variables. The expression is fully resolved in constructor.
+     */
+    ExpressionLogical(RangeVariable leftRangeVar, int colIndexLeft,
+                      RangeVariable rightRangeVar, int colIndexRight) {
+
+        super(OpTypes.EQUAL);
+
+        ExpressionColumn leftExpression = new ExpressionColumn(leftRangeVar,
+            colIndexLeft);
+        ExpressionColumn rightExpression = new ExpressionColumn(rightRangeVar,
+            colIndexRight);
+
+        nodes        = new Expression[BINARY];
+        dataType     = Type.SQL_BOOLEAN;
+        nodes[LEFT]  = leftExpression;
+        nodes[RIGHT] = rightExpression;
+    }
+
+    /**
+     * Creates an equality expression
+     */
+    ExpressionLogical(Expression left, Expression right) {
+
+        super(OpTypes.EQUAL);
+
+        nodes        = new Expression[BINARY];
+        nodes[LEFT]  = left;
+        nodes[RIGHT] = right;
+
+        if (left.opType == OpTypes.COLUMN && right.opType == OpTypes.COLUMN) {
+            isColumnEqual = true;
+        }
+
+        dataType = Type.SQL_BOOLEAN;
+    }
+
+    /**
+     * Creates a binary operation expression
+     */
+    ExpressionLogical(int type, Expression left, Expression right) {
+
+        super(type);
+
+        nodes        = new Expression[BINARY];
+        nodes[LEFT]  = left;
+        nodes[RIGHT] = right;
+
+        switch (opType) {
+
+            case OpTypes.EQUAL :
+                if (left.opType == OpTypes.COLUMN
+                        && right.opType == OpTypes.COLUMN) {
+                    isColumnEqual = true;
+                }
+
+            // fall through
+            case OpTypes.GREATER_EQUAL :
+            case OpTypes.GREATER :
+            case OpTypes.SMALLER :
+            case OpTypes.SMALLER_EQUAL :
+            case OpTypes.NOT_EQUAL :
+            case OpTypes.OVERLAPS :
+            case OpTypes.NOT_DISTINCT :
+            case OpTypes.IN :
+            case OpTypes.MATCH_SIMPLE :
+            case OpTypes.MATCH_PARTIAL :
+            case OpTypes.MATCH_FULL :
+            case OpTypes.MATCH_UNIQUE_SIMPLE :
+            case OpTypes.MATCH_UNIQUE_PARTIAL :
+            case OpTypes.MATCH_UNIQUE_FULL :
+            case OpTypes.AND :
+            case OpTypes.OR :
+                dataType = Type.SQL_BOOLEAN;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+    }
+
+    /**
+     * Creates a unary operation expression
+     */
+    ExpressionLogical(int type, Expression e) {
+
+        super(type);
+
+        nodes       = new Expression[UNARY];
+        nodes[LEFT] = e;
+
+        switch (opType) {
+
+            case OpTypes.UNIQUE :
+            case OpTypes.EXISTS :
+            case OpTypes.IS_NULL :
+            case OpTypes.NOT :
+                dataType = Type.SQL_BOOLEAN;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+    }
+
+    /**
+     * Creates a column not null expression for check constraints
+     */
+    ExpressionLogical(ColumnSchema column) {
+
+        super(OpTypes.NOT);
+
+        nodes    = new Expression[UNARY];
+        dataType = Type.SQL_BOOLEAN;
+
+        Expression e = new ExpressionColumn(column);
+
+        e           = new ExpressionLogical(OpTypes.IS_NULL, e);
+        nodes[LEFT] = e;
+    }
+
+    // logical ops
+    static Expression andExpressions(Expression e1, Expression e2) {
+
+        if (e1 == null) {
+            return e2;
+        }
+
+        if (e2 == null) {
+            return e1;
+        }
+
+        if (ExpressionLogical.EXPR_FALSE.equals(e1)
+                || ExpressionLogical.EXPR_FALSE.equals(e2)) {
+            return ExpressionLogical.EXPR_FALSE;
+        }
+
+        return new ExpressionLogical(OpTypes.AND, e1, e2);
+    }
+
+    static Expression orExpressions(Expression e1, Expression e2) {
+
+        if (e1 == null) {
+            return e2;
+        }
+
+        if (e2 == null) {
+            return e1;
+        }
+
+        return new ExpressionLogical(OpTypes.OR, e1, e2);
+    }
+
+    public void addLeftColumnsForAllAny(RangeVariable range,
+                                        OrderedIntHashSet set) {
+
+        if (nodes.length == 0) {
+            return;
+        }
+
+        for (int j = 0; j < nodes[LEFT].nodes.length; j++) {
+            int index = nodes[LEFT].nodes[j].getColumnIndex();
+
+            if (index < 0
+                    || nodes[LEFT].nodes[j].getRangeVariable() != range) {
+                set.clear();
+
+                return;
+            }
+
+            set.add(index);
+        }
+    }
+
+    public void setSubType(int type) {
+
+        exprSubType = type;
+
+        if (exprSubType == OpTypes.ALL_QUANTIFIED
+                || exprSubType == OpTypes.ANY_QUANTIFIED) {
+            isQuantified = true;
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        if (opType == OpTypes.VALUE) {
+            return super.getSQL();
+        }
+
+        String left  = getContextSQL(nodes[LEFT]);
+        String right = getContextSQL(nodes.length > 1 ? nodes[RIGHT]
+                                                      : null);
+
+        switch (opType) {
+
+            case OpTypes.NOT :
+                if (nodes[LEFT].opType == OpTypes.IS_NULL) {
+                    sb.append(getContextSQL(nodes[LEFT].nodes[LEFT])).append(
+                        ' ').append(Tokens.T_IS).append(' ').append(
+                        Tokens.T_NOT).append(' ').append(Tokens.T_NULL);
+
+                    return sb.toString();
+                }
+
+                if (nodes[LEFT].opType == OpTypes.NOT_DISTINCT) {
+                    sb.append(getContextSQL(nodes[LEFT].nodes[LEFT])).append(
+                        ' ').append(Tokens.T_IS).append(' ').append(
+                        Tokens.T_DISTINCT).append(' ').append(
+                        Tokens.T_FROM).append(' ').append(
+                        getContextSQL(nodes[LEFT].nodes[RIGHT]));
+
+                    return sb.toString();
+                }
+
+                sb.append(Tokens.T_NOT).append(' ').append(left);
+
+                return sb.toString();
+
+            case OpTypes.NOT_DISTINCT :
+                sb.append(Tokens.T_NOT).append(' ').append(
+                    getContextSQL(nodes[LEFT].nodes[LEFT])).append(' ').append(
+                    Tokens.T_IS).append(' ').append(Tokens.T_DISTINCT).append(
+                    ' ').append(Tokens.T_FROM).append(' ').append(
+                    getContextSQL(nodes[LEFT].nodes[RIGHT]));
+
+                return sb.toString();
+
+            case OpTypes.IS_NULL :
+                sb.append(left).append(' ').append(Tokens.T_IS).append(
+                    ' ').append(Tokens.T_NULL);
+
+                return sb.toString();
+
+            case OpTypes.UNIQUE :
+                sb.append(' ').append(Tokens.T_UNIQUE).append(' ');
+                break;
+
+            case OpTypes.EXISTS :
+                sb.append(' ').append(Tokens.T_EXISTS).append(' ');
+                break;
+
+            case OpTypes.EQUAL :
+                sb.append(left).append('=').append(right);
+
+                return sb.toString();
+
+            case OpTypes.GREATER_EQUAL :
+                sb.append(left).append(">=").append(right);
+
+                return sb.toString();
+
+            case OpTypes.GREATER :
+                sb.append(left).append('>').append(right);
+
+                return sb.toString();
+
+            case OpTypes.SMALLER :
+                sb.append(left).append('<').append(right);
+
+                return sb.toString();
+
+            case OpTypes.SMALLER_EQUAL :
+                sb.append(left).append("<=").append(right);
+
+                return sb.toString();
+
+            case OpTypes.NOT_EQUAL :
+                if (Tokens.T_NULL.equals(right)) {
+                    sb.append(left).append(" IS NOT ").append(right);
+                } else {
+                    sb.append(left).append("!=").append(right);
+                }
+
+                return sb.toString();
+
+            case OpTypes.AND :
+                sb.append(left).append(' ').append(Tokens.T_AND).append(
+                    ' ').append(right);
+
+                return sb.toString();
+
+            case OpTypes.OR :
+                sb.append(left).append(' ').append(Tokens.T_OR).append(
+                    ' ').append(right);
+
+                return sb.toString();
+
+            case OpTypes.IN :
+                sb.append(left).append(' ').append(Tokens.T_IN).append(
+                    ' ').append(right);
+
+                return sb.toString();
+
+            case OpTypes.MATCH_SIMPLE :
+                sb.append(left).append(' ').append(Tokens.T_MATCH).append(
+                    ' ').append(right);
+
+                return sb.toString();
+
+            case OpTypes.MATCH_PARTIAL :
+                sb.append(left).append(' ').append(Tokens.T_MATCH).append(
+                    ' ').append(Tokens.PARTIAL).append(right);
+
+                return sb.toString();
+
+            case OpTypes.MATCH_FULL :
+                sb.append(left).append(' ').append(Tokens.T_MATCH).append(
+                    ' ').append(Tokens.FULL).append(right);
+
+                return sb.toString();
+
+            case OpTypes.MATCH_UNIQUE_SIMPLE :
+                sb.append(left).append(' ').append(Tokens.T_MATCH).append(
+                    ' ').append(Tokens.UNIQUE).append(right);
+
+                return sb.toString();
+
+            case OpTypes.MATCH_UNIQUE_PARTIAL :
+                sb.append(left).append(' ').append(Tokens.T_MATCH).append(
+                    ' ').append(Tokens.UNIQUE).append(' ').append(
+                    Tokens.PARTIAL).append(right);
+
+                return sb.toString();
+
+            case OpTypes.MATCH_UNIQUE_FULL :
+                sb.append(left).append(' ').append(Tokens.T_MATCH).append(
+                    ' ').append(Tokens.UNIQUE).append(' ').append(
+                    Tokens.FULL).append(right);
+
+                return sb.toString();
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                sb.append("VALUE = ").append(valueData);
+                sb.append(", TYPE = ").append(dataType.getNameString());
+
+                return sb.toString();
+
+            case OpTypes.NOT :
+                if (nodes[LEFT].opType == OpTypes.NOT_DISTINCT) {
+                    sb.append(Tokens.T_DISTINCT);
+
+                    return sb.toString();
+                }
+
+                sb.append(Tokens.T_NOT);
+                break;
+
+            case OpTypes.NOT_DISTINCT :
+                sb.append(Tokens.T_NOT).append(' ').append(Tokens.T_DISTINCT);
+                break;
+
+            case OpTypes.EQUAL :
+                sb.append("EQUAL");
+                break;
+
+            case OpTypes.GREATER_EQUAL :
+                sb.append("GREATER_EQUAL");
+                break;
+
+            case OpTypes.GREATER :
+                sb.append("GREATER");
+                break;
+
+            case OpTypes.SMALLER :
+                sb.append("SMALLER");
+                break;
+
+            case OpTypes.SMALLER_EQUAL :
+                sb.append("SMALLER_EQUAL");
+                break;
+
+            case OpTypes.NOT_EQUAL :
+                sb.append("NOT_EQUAL");
+                break;
+
+            case OpTypes.AND :
+                sb.append(Tokens.T_AND);
+                break;
+
+            case OpTypes.OR :
+                sb.append(Tokens.T_OR);
+                break;
+
+            case OpTypes.MATCH_SIMPLE :
+            case OpTypes.MATCH_PARTIAL :
+            case OpTypes.MATCH_FULL :
+            case OpTypes.MATCH_UNIQUE_SIMPLE :
+            case OpTypes.MATCH_UNIQUE_PARTIAL :
+            case OpTypes.MATCH_UNIQUE_FULL :
+                sb.append(Tokens.T_MATCH);
+                break;
+
+            case OpTypes.IS_NULL :
+                sb.append(Tokens.T_IS).append(' ').append(Tokens.T_NULL);
+                break;
+
+            case OpTypes.UNIQUE :
+                sb.append(Tokens.T_UNIQUE);
+                break;
+
+            case OpTypes.EXISTS :
+                sb.append(Tokens.T_EXISTS);
+                break;
+
+            case OpTypes.OVERLAPS :
+                sb.append(Tokens.T_OVERLAPS);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+
+        if (getLeftNode() != null) {
+            sb.append(" arg_left=[");
+            sb.append(nodes[LEFT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        if (getRightNode() != null) {
+            sb.append(" arg_right=[");
+            sb.append(nodes[RIGHT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        return sb.toString();
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        // parametric ALL / ANY
+        if (isQuantified) {
+            if (nodes[RIGHT].opType == OpTypes.TABLE) {
+                if (nodes[RIGHT] instanceof ExpressionTable) {
+                    if (nodes[RIGHT].nodes[LEFT].opType
+                            == OpTypes.DYNAMIC_PARAM) {
+                        nodes[LEFT].resolveTypes(session, this);
+
+                        nodes[RIGHT].nodes[LEFT].dataType =
+                            Type.getDefaultArrayType(
+                                nodes[LEFT].dataType.typeCode);
+                    }
+                }
+            }
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                break;
+
+            case OpTypes.NOT_DISTINCT :
+            case OpTypes.EQUAL :
+            case OpTypes.GREATER_EQUAL :
+            case OpTypes.GREATER :
+            case OpTypes.SMALLER :
+            case OpTypes.SMALLER_EQUAL :
+            case OpTypes.NOT_EQUAL :
+                resolveTypesForComparison(session, parent);
+                break;
+
+            case OpTypes.AND : {
+                resolveTypesForLogicalOp();
+
+                if (nodes[LEFT].opType == OpTypes.VALUE) {
+                    if (nodes[RIGHT].opType == OpTypes.VALUE) {
+                        setAsConstantValue(session);
+                    } else {
+                        Object value = nodes[LEFT].getValue(session);
+
+                        if (value == null || Boolean.FALSE.equals(value)) {
+                            setAsConstantValue(Boolean.FALSE);
+                        }
+                    }
+                } else if (nodes[RIGHT].opType == OpTypes.VALUE) {
+                    Object value = nodes[RIGHT].getValue(session);
+
+                    if (value == null || Boolean.FALSE.equals(value)) {
+                        setAsConstantValue(Boolean.FALSE);
+                    }
+                }
+
+                break;
+            }
+            case OpTypes.OR : {
+                resolveTypesForLogicalOp();
+
+                if (nodes[LEFT].opType == OpTypes.VALUE) {
+                    if (nodes[RIGHT].opType == OpTypes.VALUE) {
+                        setAsConstantValue(session);
+                    } else {
+                        Object value = nodes[LEFT].getValue(session);
+
+                        if (Boolean.TRUE.equals(value)) {
+                            setAsConstantValue(Boolean.TRUE);
+                        }
+                    }
+                } else if (nodes[RIGHT].opType == OpTypes.VALUE) {
+                    Object value = nodes[RIGHT].getValue(session);
+
+                    if (Boolean.TRUE.equals(value)) {
+                        setAsConstantValue(Boolean.TRUE);
+                    }
+                }
+
+                break;
+            }
+            case OpTypes.IS_NULL :
+                if (nodes[LEFT].isUnresolvedParam()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                if (nodes[LEFT].opType == OpTypes.VALUE) {
+                    setAsConstantValue(session);
+                }
+                break;
+
+            case OpTypes.NOT :
+                if (nodes[LEFT].isUnresolvedParam()) {
+                    nodes[LEFT].dataType = Type.SQL_BOOLEAN;
+
+                    break;
+                }
+
+                if (nodes[LEFT].opType == OpTypes.VALUE) {
+                    if (nodes[LEFT].dataType.isBooleanType()) {
+                        setAsConstantValue(session);
+
+                        break;
+                    } else {
+                        throw Error.error(ErrorCode.X_42563);
+                    }
+                }
+
+                if (nodes[LEFT].dataType == null
+                        || !nodes[LEFT].dataType.isBooleanType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = Type.SQL_BOOLEAN;
+                break;
+
+            case OpTypes.OVERLAPS :
+                resolveTypesForOverlaps();
+                break;
+
+            case OpTypes.IN :
+                resolveTypesForIn(session);
+                break;
+
+            case OpTypes.MATCH_SIMPLE :
+            case OpTypes.MATCH_PARTIAL :
+            case OpTypes.MATCH_FULL :
+            case OpTypes.MATCH_UNIQUE_SIMPLE :
+            case OpTypes.MATCH_UNIQUE_PARTIAL :
+            case OpTypes.MATCH_UNIQUE_FULL :
+                resolveTypesForAllAny(session);
+                break;
+
+            case OpTypes.UNIQUE :
+            case OpTypes.EXISTS :
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+    }
+
+    private void resolveTypesForLogicalOp() {
+
+        if (nodes[LEFT].isUnresolvedParam()) {
+            nodes[LEFT].dataType = Type.SQL_BOOLEAN;
+        }
+
+        if (nodes[RIGHT].isUnresolvedParam()) {
+            nodes[RIGHT].dataType = Type.SQL_BOOLEAN;
+        }
+
+        if (nodes[LEFT].dataType == null || nodes[RIGHT].dataType == null) {
+            throw Error.error(ErrorCode.X_42571);
+        }
+
+        if (nodes[LEFT].opType == OpTypes.ROW
+                || nodes[RIGHT].opType == OpTypes.ROW) {
+            throw Error.error(ErrorCode.X_42565);
+        }
+
+        if (Type.SQL_BOOLEAN != nodes[LEFT].dataType
+                || Type.SQL_BOOLEAN != nodes[RIGHT].dataType) {
+            throw Error.error(ErrorCode.X_42568);
+        }
+    }
+
+    private void resolveTypesForComparison(Session session,
+                                           Expression parent) {
+
+        if (opType == OpTypes.NOT_DISTINCT
+                || exprSubType == OpTypes.ALL_QUANTIFIED
+                || exprSubType == OpTypes.ANY_QUANTIFIED) {
+            resolveTypesForAllAny(session);
+            checkRowComparison();
+
+            return;
+        }
+
+        if (nodes[LEFT].opType == OpTypes.ROW
+                || nodes[RIGHT].opType == OpTypes.ROW) {
+            if (nodes[LEFT].opType != OpTypes.ROW
+                    || nodes[RIGHT].opType != OpTypes.ROW
+                    || nodes[LEFT].nodes.length != nodes[RIGHT].nodes.length) {
+                throw Error.error(ErrorCode.X_42564);
+            }
+
+            resolveRowTypes();
+            checkRowComparison();
+
+            return;
+        } else {
+            if (nodes[LEFT].isUnresolvedParam()) {
+                nodes[LEFT].dataType = nodes[RIGHT].dataType;
+            } else if (nodes[RIGHT].isUnresolvedParam()) {
+                nodes[RIGHT].dataType = nodes[LEFT].dataType;
+            }
+
+            if (nodes[LEFT].dataType == null) {
+                nodes[LEFT].dataType = nodes[RIGHT].dataType;
+            } else if (nodes[RIGHT].dataType == null) {
+                nodes[RIGHT].dataType = nodes[LEFT].dataType;
+            }
+
+            if (nodes[LEFT].dataType == null
+                    || nodes[RIGHT].dataType == null) {
+                throw Error.error(ErrorCode.X_42567);
+            }
+
+            if (nodes[LEFT].dataType.typeComparisonGroup
+                    != nodes[RIGHT].dataType.typeComparisonGroup) {
+                if (convertDateTimeLiteral(session, nodes[LEFT],
+                                           nodes[RIGHT])) {
+
+                    // compatibility for BIT with number and BOOLEAN - convert bit to other type
+                } else if (nodes[LEFT].dataType.isBitType()) {
+                    if (nodes[RIGHT].dataType.canConvertFrom(
+                            nodes[LEFT].dataType)) {
+                        nodes[LEFT] = ExpressionOp.getCastExpression(session,
+                                nodes[LEFT], nodes[RIGHT].dataType);
+                    }
+                } else if (nodes[RIGHT].dataType.isBitType()) {
+                    if (nodes[LEFT].dataType.canConvertFrom(
+                            nodes[RIGHT].dataType)) {
+                        nodes[RIGHT] = ExpressionOp.getCastExpression(session,
+                                nodes[RIGHT], nodes[LEFT].dataType);
+                    }
+                } else {
+                    throw Error.error(ErrorCode.X_42562);
+                }
+            } else if (nodes[LEFT].dataType.isDateTimeType()) {
+                if (nodes[LEFT].dataType.isDateTimeTypeWithZone()
+                        ^ nodes[RIGHT].dataType.isDateTimeTypeWithZone()) {
+                    nodes[LEFT] = new ExpressionOp(nodes[LEFT]);
+                }
+            }
+
+            if (opType == OpTypes.EQUAL || opType == OpTypes.NOT_EQUAL) {}
+            else {
+                if (nodes[LEFT].dataType.isArrayType()
+                        || nodes[LEFT].dataType.isLobType()
+                        || nodes[RIGHT].dataType.isLobType()) {
+                    throw Error.error(ErrorCode.X_42534);
+                }
+            }
+
+            if (nodes[LEFT].opType == OpTypes.VALUE
+                    && nodes[RIGHT].opType == OpTypes.VALUE) {
+                setAsConstantValue(session);
+            }
+        }
+    }
+
+    private void resolveRowTypes() {
+
+        for (int i = 0; i < nodes[LEFT].nodeDataTypes.length; i++) {
+            Type leftType  = nodes[LEFT].nodeDataTypes[i];
+            Type rightType = nodes[RIGHT].nodeDataTypes[i];
+
+            if (leftType == null) {
+                leftType = nodes[LEFT].nodeDataTypes[i] = rightType;
+            } else if (nodes[RIGHT].dataType == null) {
+                rightType = nodes[RIGHT].nodeDataTypes[i] = leftType;
+            }
+
+            if (leftType == null || rightType == null) {
+                throw Error.error(ErrorCode.X_42567);
+            }
+
+            if (leftType.typeComparisonGroup
+                    != rightType.typeComparisonGroup) {
+                throw Error.error(ErrorCode.X_42562);
+            } else if (leftType.isDateTimeType()) {
+                if (leftType.isDateTimeTypeWithZone()
+                        ^ rightType.isDateTimeTypeWithZone()) {
+                    nodes[LEFT].nodes[i] =
+                        new ExpressionOp(nodes[LEFT].nodes[i]);
+                    nodes[LEFT].nodeDataTypes[i] =
+                        nodes[LEFT].nodes[i].dataType;
+                }
+            }
+        }
+    }
+
+    void checkRowComparison() {
+
+        if (opType == OpTypes.EQUAL || opType == OpTypes.NOT_EQUAL) {
+            return;
+        }
+
+        for (int i = 0; i < nodes[LEFT].nodeDataTypes.length; i++) {
+            Type leftType  = nodes[LEFT].nodeDataTypes[i];
+            Type rightType = nodes[RIGHT].nodeDataTypes[i];
+
+            if (leftType.isArrayType() || leftType.isLobType()
+                    || rightType.isLobType()) {
+                throw Error.error(ErrorCode.X_42534);
+            }
+        }
+    }
+
+    /**
+     * for compatibility, convert a datetime character string to a datetime
+     * value for comparison
+     */
+    private boolean convertDateTimeLiteral(Session session, Expression a,
+                                           Expression b) {
+
+        if (a.dataType.isDateTimeType()) {}
+        else if (b.dataType.isDateTimeType()) {
+            Expression c = a;
+
+            a = b;
+            b = c;
+        } else {
+            return false;
+        }
+
+        if (a.dataType.isDateTimeTypeWithZone()) {
+            return false;
+        }
+
+        if (b.opType == OpTypes.VALUE && b.dataType.isCharacterType()) {
+            b.valueData = a.dataType.castToType(session, b.valueData,
+                                                b.dataType);
+            b.dataType = a.dataType;
+
+            return true;
+        }
+
+        return false;
+    }
+
+    void resolveTypesForOverlaps() {
+
+        if (nodes[LEFT].nodes[0].isUnresolvedParam()) {
+            nodes[LEFT].nodes[0].dataType = nodes[RIGHT].nodes[0].dataType;
+        }
+
+        if (nodes[RIGHT].nodes[0].isUnresolvedParam()) {
+            nodes[RIGHT].nodes[0].dataType = nodes[LEFT].nodes[0].dataType;
+        }
+
+        if (nodes[LEFT].nodes[0].dataType == null) {
+            nodes[LEFT].nodes[0].dataType = nodes[RIGHT].nodes[0].dataType =
+                Type.SQL_TIMESTAMP;
+        }
+
+        if (nodes[LEFT].nodes[1].isUnresolvedParam()) {
+            nodes[LEFT].nodes[1].dataType = nodes[RIGHT].nodes[0].dataType;
+        }
+
+        if (nodes[RIGHT].nodes[1].isUnresolvedParam()) {
+            nodes[RIGHT].nodes[1].dataType = nodes[LEFT].nodes[0].dataType;
+        }
+
+        if (!DTIType
+                .isValidDatetimeRange(nodes[LEFT].nodes[0]
+                    .dataType, nodes[LEFT].nodes[1].dataType) || !DTIType
+                        .isValidDatetimeRange(nodes[RIGHT].nodes[0]
+                            .dataType, nodes[RIGHT].nodes[1].dataType)) {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        if (!DTIType.isValidDatetimeRange(nodes[LEFT].nodes[0].dataType,
+                                          nodes[LEFT].nodes[1].dataType)) {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        nodes[LEFT].nodeDataTypes[0]  = nodes[LEFT].nodes[0].dataType;
+        nodes[LEFT].nodeDataTypes[1]  = nodes[LEFT].nodes[1].dataType;
+        nodes[RIGHT].nodeDataTypes[0] = nodes[RIGHT].nodes[0].dataType;
+        nodes[RIGHT].nodeDataTypes[1] = nodes[RIGHT].nodes[1].dataType;
+    }
+
+    void resolveTypesForAllAny(Session session) {
+
+        int degree = nodes[LEFT].getDegree();
+
+        if (degree == 1 && nodes[LEFT].opType != OpTypes.ROW) {
+            nodes[LEFT] = new Expression(OpTypes.ROW,
+                                         new Expression[]{ nodes[LEFT] });
+        }
+
+        if (nodes[RIGHT].opType == OpTypes.TABLE) {
+            nodes[RIGHT].prepareTable(session, nodes[LEFT], degree);
+            nodes[RIGHT].subQuery.prepareTable(session);
+
+            if (nodes[RIGHT].isCorrelated) {
+                nodes[RIGHT].subQuery.setCorrelated();
+            }
+        }
+
+        if (degree != nodes[RIGHT].nodeDataTypes.length) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        if (nodes[RIGHT].opType == OpTypes.TABLE) {}
+
+        nodes[LEFT].nodeDataTypes = new Type[nodes[LEFT].nodes.length];
+
+        for (int i = 0; i < nodes[LEFT].nodeDataTypes.length; i++) {
+            Type type = nodes[LEFT].nodes[i].dataType;
+
+            if (type == null) {
+                type = nodes[RIGHT].nodeDataTypes[i];
+            }
+
+            if (type == null) {
+                throw Error.error(ErrorCode.X_42567);
+            }
+
+            nodes[LEFT].nodeDataTypes[i]  = type;
+            nodes[LEFT].nodes[i].dataType = type;
+        }
+    }
+
+    void resolveTypesForIn(Session session) {
+        resolveTypesForAllAny(session);
+    }
+
+    public Object getValue(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                return valueData;
+
+            case OpTypes.SIMPLE_COLUMN : {
+                Object[] data =
+                    (Object[]) session.sessionContext
+                        .rangeIterators[rangePosition].getCurrent();
+
+                return data[columnIndex];
+            }
+            case OpTypes.NEGATE :
+                return ((NumberType) dataType).negate(
+                    nodes[LEFT].getValue(session, nodes[LEFT].dataType));
+
+            case OpTypes.IS_NULL :
+                return nodes[LEFT].getValue(session) == null ? Boolean.TRUE
+                                                             : Boolean.FALSE;
+
+            case OpTypes.OVERLAPS : {
+                Object[] left  = nodes[LEFT].getRowValue(session);
+                Object[] right = nodes[RIGHT].getRowValue(session);
+
+                return DateTimeType.overlaps(session, left,
+                                             nodes[LEFT].nodeDataTypes, right,
+                                             nodes[RIGHT].nodeDataTypes);
+            }
+            case OpTypes.IN : {
+                return testInCondition(session,
+                                       nodes[LEFT].getRowValue(session));
+            }
+            case OpTypes.MATCH_SIMPLE :
+            case OpTypes.MATCH_PARTIAL :
+            case OpTypes.MATCH_FULL :
+            case OpTypes.MATCH_UNIQUE_SIMPLE :
+            case OpTypes.MATCH_UNIQUE_PARTIAL :
+            case OpTypes.MATCH_UNIQUE_FULL : {
+                return testMatchCondition(session,
+                                          nodes[LEFT].getRowValue(session));
+            }
+            case OpTypes.UNIQUE : {
+                nodes[LEFT].materialise(session);
+
+                return nodes[LEFT].subQuery.hasUniqueNotNullRows(session)
+                       ? Boolean.TRUE
+                       : Boolean.FALSE;
+            }
+            case OpTypes.EXISTS : {
+                return testExistsCondition(session);
+            }
+            case OpTypes.NOT : {
+                Boolean result = (Boolean) nodes[LEFT].getValue(session);
+
+                return result == null ? null
+                                      : result.booleanValue() ? Boolean.FALSE
+                                                              : Boolean.TRUE;
+            }
+            case OpTypes.AND : {
+                Boolean r1 = (Boolean) nodes[LEFT].getValue(session);
+
+                if (Boolean.FALSE.equals(r1)) {
+                    return Boolean.FALSE;
+                }
+
+                Boolean r2 = (Boolean) nodes[RIGHT].getValue(session);
+
+                if (Boolean.FALSE.equals(r2)) {
+                    return Boolean.FALSE;
+                }
+
+                if (r1 == null || r2 == null) {
+                    return null;
+                }
+
+                return Boolean.TRUE;
+            }
+            case OpTypes.OR : {
+                Boolean r1 = (Boolean) nodes[LEFT].getValue(session);
+
+                if (Boolean.TRUE.equals(r1)) {
+                    return Boolean.TRUE;
+                }
+
+                Boolean r2 = (Boolean) nodes[RIGHT].getValue(session);
+
+                if (Boolean.TRUE.equals(r2)) {
+                    return Boolean.TRUE;
+                }
+
+                if (r1 == null || r2 == null) {
+                    return null;
+                }
+
+                return Boolean.FALSE;
+            }
+            case OpTypes.NOT_DISTINCT :
+            case OpTypes.EQUAL :
+            case OpTypes.GREATER :
+            case OpTypes.GREATER_EQUAL :
+            case OpTypes.SMALLER_EQUAL :
+            case OpTypes.SMALLER :
+            case OpTypes.NOT_EQUAL : {
+                if (exprSubType == OpTypes.ANY_QUANTIFIED
+                        || exprSubType == OpTypes.ALL_QUANTIFIED) {
+                    return testAllAnyCondition(
+                        session, (Object[]) nodes[LEFT].getRowValue(session));
+                }
+
+                Object o1 = nodes[LEFT].getValue(session);
+                Object o2 = nodes[RIGHT].getValue(session);
+
+                if (o1 instanceof Object[]) {
+                    if (!(o2 instanceof Object[])) {
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "ExpressionLogical");
+                    }
+
+                    return compareValues(session, (Object[]) o1,
+                                         (Object[]) o2);
+                } else {
+                    if (o2 instanceof Object[]) {
+                        o2 = ((Object[]) o2)[0];
+                    }
+
+                    return compareValues(session, o1, o2);
+                }
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+    }
+
+    /**
+     * For MATCH SIMPLE and FULL expressions, nulls in left are handled
+     * prior to calling this method
+     */
+    private Boolean compareValues(Session session, Object left, Object right) {
+
+        int result = 0;
+
+        if (left == null || right == null) {
+            return null;
+        }
+
+        result = nodes[LEFT].dataType.compare(session, left, right);
+
+        switch (opType) {
+
+            case OpTypes.EQUAL :
+                return result == 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.NOT_EQUAL :
+                return result != 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.GREATER :
+                return result > 0 ? Boolean.TRUE
+                                  : Boolean.FALSE;
+
+            case OpTypes.GREATER_EQUAL :
+                return result >= 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.SMALLER_EQUAL :
+                return result <= 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.SMALLER :
+                return result < 0 ? Boolean.TRUE
+                                  : Boolean.FALSE;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+    }
+
+    /**
+     * For MATCH SIMPLE and FULL expressions, nulls in left are handled
+     * prior to calling this method
+     */
+    private Boolean compareValues(Session session, Object[] left,
+                                  Object[] right) {
+
+        int     result  = 0;
+        boolean hasNull = false;
+
+        if (left == null || right == null) {
+            return null;
+        }
+
+        Object[] leftList  = (Object[]) left;
+        Object[] rightList = (Object[]) right;
+
+        for (int i = 0; i < nodes[LEFT].nodes.length; i++) {
+            if (leftList[i] == null) {
+                if (opType == OpTypes.MATCH_PARTIAL
+                        || opType == OpTypes.MATCH_UNIQUE_PARTIAL) {
+                    continue;
+                }
+
+                hasNull = true;
+            }
+
+            if (rightList[i] == null) {
+                hasNull = true;
+            }
+
+            Object leftValue  = leftList[i];
+            Object rightValue = rightList[i];
+            Type[] types      = nodes[LEFT].nodeDataTypes;
+
+            result = types[i].compare(session, leftValue, rightValue);
+
+            if (result != 0) {
+                break;
+            }
+        }
+
+        switch (opType) {
+
+            case OpTypes.MATCH_SIMPLE :
+            case OpTypes.MATCH_UNIQUE_SIMPLE :
+            case OpTypes.MATCH_PARTIAL :
+            case OpTypes.MATCH_UNIQUE_PARTIAL :
+            case OpTypes.MATCH_FULL :
+            case OpTypes.MATCH_UNIQUE_FULL :
+            case OpTypes.NOT_DISTINCT :
+                return result == 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.IN :
+            case OpTypes.EQUAL :
+                if (hasNull) {
+                    return null;
+                }
+
+                return result == 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.NOT_EQUAL :
+                if (hasNull) {
+                    return null;
+                }
+
+                return result != 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.GREATER :
+                if (hasNull) {
+                    return null;
+                }
+
+                return result > 0 ? Boolean.TRUE
+                                  : Boolean.FALSE;
+
+            case OpTypes.GREATER_EQUAL :
+                if (hasNull) {
+                    return null;
+                }
+
+                return result >= 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.SMALLER_EQUAL :
+                if (hasNull) {
+                    return null;
+                }
+
+                return result <= 0 ? Boolean.TRUE
+                                   : Boolean.FALSE;
+
+            case OpTypes.SMALLER :
+                if (hasNull) {
+                    return null;
+                }
+
+                return result < 0 ? Boolean.TRUE
+                                  : Boolean.FALSE;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+    }
+
+    /**
+     * Returns the result of testing a VALUE_LIST expression
+     */
+    private Boolean testInCondition(Session session, Object[] data) {
+
+        if (data == null) {
+            return null;
+        }
+
+        if (Expression.countNulls(data) != 0) {
+            return null;
+        }
+
+        if (nodes[RIGHT].opType == OpTypes.TABLE) {
+            final int length = nodes[RIGHT].nodes.length;
+
+            for (int i = 0; i < length; i++) {
+                Object[] rowData = nodes[RIGHT].nodes[i].getRowValue(session);
+
+                if (Boolean.TRUE.equals(compareValues(session, data,
+                                                      rowData))) {
+                    return Boolean.TRUE;
+                }
+            }
+
+            return Boolean.FALSE;
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionLogical");
+    }
+
+    private Boolean testMatchCondition(Session session, Object[] data) {
+
+        int nulls;
+
+        if (data == null) {
+            return Boolean.TRUE;
+        }
+
+        nulls = countNulls(data);
+
+        if (nulls != 0) {
+            switch (opType) {
+
+                case OpTypes.MATCH_SIMPLE :
+                case OpTypes.MATCH_UNIQUE_SIMPLE :
+                    return Boolean.TRUE;
+
+                case OpTypes.MATCH_PARTIAL :
+                case OpTypes.MATCH_UNIQUE_PARTIAL :
+                    if (nulls == data.length) {
+                        return Boolean.TRUE;
+                    }
+                    break;
+
+                case OpTypes.MATCH_FULL :
+                case OpTypes.MATCH_UNIQUE_FULL :
+                    return nulls == data.length ? Boolean.TRUE
+                                                : Boolean.FALSE;
+            }
+        }
+
+        if (nodes[RIGHT].opType == OpTypes.TABLE) {
+            final int length   = nodes[RIGHT].nodes.length;
+            boolean   hasMatch = false;
+
+            for (int i = 0; i < length; i++) {
+                Object[] rowData = nodes[RIGHT].nodes[i].getRowValue(session);
+                Boolean  result  = compareValues(session, data, rowData);
+
+                if (result == null || !result.booleanValue()) {
+                    continue;
+                }
+
+                switch (opType) {
+
+                    case OpTypes.MATCH_SIMPLE :
+                    case OpTypes.MATCH_PARTIAL :
+                    case OpTypes.MATCH_FULL :
+                        return Boolean.TRUE;
+
+                    case OpTypes.MATCH_UNIQUE_SIMPLE :
+                    case OpTypes.MATCH_UNIQUE_PARTIAL :
+                    case OpTypes.MATCH_UNIQUE_FULL :
+                        if (hasMatch) {
+                            return Boolean.FALSE;
+                        }
+
+                        hasMatch = true;
+                }
+            }
+
+            return hasMatch ? Boolean.TRUE
+                            : Boolean.FALSE;
+        } else if (nodes[RIGHT].opType == OpTypes.TABLE_SUBQUERY) {
+            PersistentStore store =
+                session.sessionData.getRowStore(nodes[RIGHT].getTable());
+
+            nodes[RIGHT].materialise(session);
+            convertToType(session, data, nodes[LEFT].nodeDataTypes,
+                          nodes[RIGHT].nodeDataTypes);
+
+            if (nulls != 0
+                    && (opType == OpTypes.MATCH_PARTIAL
+                        || opType == OpTypes.MATCH_UNIQUE_PARTIAL)) {
+                boolean     hasMatch = false;
+                RowIterator it = nodes[RIGHT].getTable().rowIterator(session);
+
+                while (it.hasNext()) {
+                    Object[] rowData = it.getNextRow().getData();
+                    Boolean  result  = compareValues(session, data, rowData);
+
+                    if (result == null) {
+                        continue;
+                    }
+
+                    if (result.booleanValue()) {
+                        if (opType == OpTypes.MATCH_PARTIAL) {
+                            return Boolean.TRUE;
+                        }
+
+                        if (hasMatch) {
+                            return Boolean.FALSE;
+                        }
+
+                        hasMatch = true;
+                    }
+                }
+
+                return hasMatch ? Boolean.TRUE
+                                : Boolean.FALSE;
+            }
+
+            RowIterator it =
+                nodes[RIGHT].getTable().getPrimaryIndex().findFirstRow(session,
+                    store, data);
+            boolean result = it.hasNext();
+
+            if (!result) {
+                return Boolean.FALSE;
+            }
+
+            switch (opType) {
+
+                case OpTypes.MATCH_SIMPLE :
+                case OpTypes.MATCH_PARTIAL :
+                case OpTypes.MATCH_FULL :
+                    return Boolean.TRUE;
+            }
+
+            it.getNextRow();
+
+            result = it.hasNext();
+
+            if (!result) {
+                return Boolean.TRUE;
+            }
+
+            Object[] rowData = it.getNextRow().getData();
+            Boolean returnValue =
+                Boolean.TRUE.equals(compareValues(session, data, rowData))
+                ? Boolean.FALSE
+                : Boolean.TRUE;
+
+            return returnValue;
+        }
+
+        throw Error.error(ErrorCode.X_42564);
+    }
+
+    private Boolean testExistsCondition(Session session) {
+
+        nodes[LEFT].materialise(session);
+
+        return nodes[LEFT].getTable().isEmpty(session) ? Boolean.FALSE
+                                                       : Boolean.TRUE;
+    }
+
+    private Boolean testAllAnyCondition(Session session, Object[] o) {
+
+        SubQuery subquery = nodes[RIGHT].subQuery;
+
+        subquery.materialiseCorrelated(session);
+
+        Boolean result = getAllAnyValue(session, o, subquery);
+
+        return result;
+    }
+
+    private Boolean getAllAnyValue(Session session, Object[] data,
+                                   SubQuery subquery) {
+
+        Table           table = subquery.getTable();
+        boolean         empty = table.isEmpty(session);
+        Index           index = table.getFullIndex();
+        RowIterator     it;
+        Row             firstrow;
+        PersistentStore store   = session.sessionData.getRowStore(table);
+        Row             lastrow = index.lastRow(session, store).getNextRow();
+        Object[]        lastdata;
+        Object[]        firstdata;
+
+        switch (exprSubType) {
+
+            case OpTypes.ANY_QUANTIFIED : {
+                if (empty) {
+                    return Boolean.FALSE;
+                }
+
+                if (countNulls(data) == data.length) {
+                    return null;
+                }
+
+                lastdata = lastrow.getData();
+
+                if (countNulls(lastdata) == data.length) {
+                    return null;
+                }
+
+                convertToType(session, data, nodes[LEFT].nodeDataTypes,
+                              nodes[RIGHT].nodeDataTypes);
+
+                if (opType == OpTypes.EQUAL) {
+                    it = index.findFirstRow(session, store, data);
+
+                    return it.hasNext() ? Boolean.TRUE
+                                        : Boolean.FALSE;
+                }
+
+                it        = index.findFirstRowNotNull(session, store);
+                firstrow  = it.getNextRow();
+                firstdata = firstrow.getData();
+
+                Boolean comparefirst = compareValues(session, data, firstdata);
+                Boolean comparelast  = compareValues(session, data, lastdata);
+
+                switch (opType) {
+
+                    case OpTypes.NOT_EQUAL :
+                        return Boolean.TRUE.equals(comparefirst)
+                               || Boolean.TRUE.equals(
+                                   comparelast) ? Boolean.TRUE
+                                                : Boolean.FALSE;
+
+                    case OpTypes.GREATER :
+                        return comparefirst;
+
+                    case OpTypes.GREATER_EQUAL :
+                        return comparefirst;
+
+                    case OpTypes.SMALLER :
+                        return comparelast;
+
+                    case OpTypes.SMALLER_EQUAL :
+                        return comparelast;
+                }
+
+                break;
+            }
+            case OpTypes.ALL_QUANTIFIED : {
+                if (empty) {
+                    return Boolean.TRUE;
+                }
+
+                if (countNulls(data) == data.length) {
+                    return null;
+                }
+
+                it        = index.firstRow(session, store);
+                firstrow  = it.getNextRow();
+                firstdata = firstrow.getData();
+
+                if (countNulls(firstdata) == data.length) {
+                    return null;
+                }
+
+                convertToType(session, data, nodes[LEFT].nodeDataTypes,
+                              nodes[RIGHT].nodeDataTypes);
+
+                it = index.findFirstRow(session, store, data);
+
+                if (opType == OpTypes.EQUAL) {
+                    if (it.hasNext()) {
+                        return subquery.getTable().getRowCount(store) == 1
+                               ? Boolean.TRUE
+                               : Boolean.FALSE;
+                    } else {
+                        return Boolean.FALSE;
+                    }
+                }
+
+                if (opType == OpTypes.NOT_EQUAL) {
+                    return it.hasNext() ? Boolean.FALSE
+                                        : Boolean.TRUE;
+                }
+
+                lastdata = lastrow.getData();
+
+                Boolean comparefirst = compareValues(session, data, firstdata);
+                Boolean comparelast  = compareValues(session, data, lastdata);
+
+                switch (opType) {
+
+                    case OpTypes.GREATER :
+                        return comparelast;
+
+                    case OpTypes.GREATER_EQUAL :
+                        return comparelast;
+
+                    case OpTypes.SMALLER :
+                        return comparefirst;
+
+                    case OpTypes.SMALLER_EQUAL :
+                        return comparefirst;
+                }
+
+                break;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Converts an OR containing an AND to an AND
+     */
+    void distributeOr() {
+
+        if (opType != OpTypes.OR) {
+            return;
+        }
+
+        if (nodes[LEFT].opType == OpTypes.AND) {
+            opType = OpTypes.AND;
+
+            Expression temp = new ExpressionLogical(OpTypes.OR,
+                nodes[LEFT].nodes[RIGHT], nodes[RIGHT]);
+
+            nodes[LEFT].opType       = OpTypes.OR;
+            nodes[LEFT].nodes[RIGHT] = nodes[RIGHT];
+            nodes[RIGHT]             = temp;
+        } else if (nodes[RIGHT].opType == OpTypes.AND) {
+            Expression temp = nodes[LEFT];
+
+            nodes[LEFT]  = nodes[RIGHT];
+            nodes[RIGHT] = temp;
+
+            distributeOr();
+
+            return;
+        }
+
+        ((ExpressionLogical) nodes[LEFT]).distributeOr();
+        ((ExpressionLogical) nodes[RIGHT]).distributeOr();
+    }
+
+    /**
+     *
+     */
+    public boolean isIndexable(RangeVariable rangeVar) {
+
+        boolean result;
+
+        switch (opType) {
+
+            case OpTypes.AND : {
+                result = nodes[LEFT].isIndexable(rangeVar)
+                         || nodes[RIGHT].isIndexable(rangeVar);
+
+                return result;
+            }
+            case OpTypes.OR : {
+                result = nodes[LEFT].isIndexable(rangeVar)
+                         && nodes[RIGHT].isIndexable(rangeVar);
+
+                return result;
+            }
+            default : {
+                Expression temp = getIndexableExpression(rangeVar);
+
+                return temp != null;
+            }
+        }
+    }
+
+    Expression getIndexableExpression(RangeVariable rangeVar) {
+
+        switch (opType) {
+
+            case OpTypes.IS_NULL :
+                return nodes[LEFT].opType == OpTypes.COLUMN
+                       && nodes[LEFT].isIndexable(rangeVar) ? this
+                                                            : null;
+
+            case OpTypes.NOT :
+                return nodes[LEFT].opType == OpTypes.IS_NULL
+                       && nodes[LEFT].nodes[LEFT].opType == OpTypes.COLUMN
+                       && nodes[LEFT].nodes[LEFT].isIndexable(rangeVar) ? this
+                                                                        : null;
+
+            case OpTypes.EQUAL :
+                if (exprSubType == OpTypes.ANY_QUANTIFIED) {
+                    if (nodes[RIGHT].isCorrelated) {
+                        return null;
+                    }
+
+                    for (int node = 0; node < nodes[LEFT].nodes.length;
+                            node++) {
+                        if (nodes[LEFT].nodes[node].opType == OpTypes.COLUMN
+                                && nodes[LEFT].nodes[node].isIndexable(
+                                    rangeVar)) {
+                            return this;
+                        }
+                    }
+
+                    return null;
+                }
+
+            // fall through
+            case OpTypes.GREATER :
+            case OpTypes.GREATER_EQUAL :
+            case OpTypes.SMALLER :
+            case OpTypes.SMALLER_EQUAL :
+                if (exprSubType != 0) {
+                    return null;
+                }
+
+                if (nodes[LEFT].opType == OpTypes.COLUMN
+                        && nodes[LEFT].isIndexable(rangeVar)) {
+                    if (nodes[RIGHT].hasReference(rangeVar)) {
+                        return null;
+                    }
+
+                    return this;
+                }
+
+                if (nodes[LEFT].hasReference(rangeVar)) {
+                    return null;
+                }
+
+                if (nodes[RIGHT].opType == OpTypes.COLUMN
+                        && nodes[RIGHT].isIndexable(rangeVar)) {
+                    swapCondition();
+
+                    return this;
+                }
+
+                return null;
+
+            case OpTypes.OR :
+                if (isIndexable(rangeVar)) {
+                    return this;
+                }
+
+                return null;
+
+            default :
+                return null;
+        }
+    }
+
+    /**
+     * Called only on comparison expressions after reordering which have
+     * a COLUMN left leaf
+     */
+    boolean isSimpleBound() {
+
+        if (opType == OpTypes.IS_NULL) {
+            return true;
+        }
+
+        if (nodes[RIGHT] != null) {
+            if (nodes[RIGHT].opType == OpTypes.VALUE) {
+
+                // also true for all parameters
+                return true;
+            }
+
+            if (nodes[RIGHT].opType == OpTypes.SQL_FUNCTION) {
+                if (((FunctionSQL) nodes[RIGHT]).isValueFunction()) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    boolean convertToSmaller() {
+
+        switch (opType) {
+
+            case OpTypes.GREATER_EQUAL :
+            case OpTypes.GREATER :
+                swapCondition();
+
+                return true;
+
+            case OpTypes.SMALLER_EQUAL :
+            case OpTypes.SMALLER :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    /**
+     * Swap the condition with its complement
+     */
+    void swapCondition() {
+
+        int i = OpTypes.EQUAL;
+
+        switch (opType) {
+
+            case OpTypes.GREATER_EQUAL :
+                i = OpTypes.SMALLER_EQUAL;
+                break;
+
+            case OpTypes.SMALLER_EQUAL :
+                i = OpTypes.GREATER_EQUAL;
+                break;
+
+            case OpTypes.SMALLER :
+                i = OpTypes.GREATER;
+                break;
+
+            case OpTypes.GREATER :
+                i = OpTypes.SMALLER;
+                break;
+
+            case OpTypes.NOT_DISTINCT :
+                i = OpTypes.NOT_DISTINCT;
+                break;
+
+            case OpTypes.EQUAL :
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "ExpressionLogical");
+        }
+
+        opType = i;
+
+        Expression e = nodes[LEFT];
+
+        nodes[LEFT]  = nodes[RIGHT];
+        nodes[RIGHT] = e;
+    }
+
+    boolean reorderComparison(Session session) {
+
+        Expression colExpression    = null;
+        Expression nonColExpression = null;
+        boolean    left             = false;
+        boolean    replaceColumn    = false;
+        int        operation        = 0;
+
+        if (nodes[LEFT].opType == OpTypes.ADD) {
+            operation = OpTypes.SUBTRACT;
+            left      = true;
+        } else if (nodes[LEFT].opType == OpTypes.SUBTRACT) {
+            operation = OpTypes.ADD;
+            left      = true;
+        } else if (nodes[RIGHT].opType == OpTypes.ADD) {
+            operation = OpTypes.SUBTRACT;
+        } else if (nodes[RIGHT].opType == OpTypes.SUBTRACT) {
+            operation = OpTypes.ADD;
+        }
+
+        if (operation == 0) {
+            return false;
+        }
+
+        if (left) {
+            if (nodes[LEFT].nodes[LEFT].opType == OpTypes.COLUMN) {
+                colExpression    = nodes[LEFT].nodes[LEFT];
+                nonColExpression = nodes[LEFT].nodes[RIGHT];
+            } else if (nodes[LEFT].nodes[RIGHT].opType == OpTypes.COLUMN) {
+                replaceColumn    = operation == OpTypes.ADD;
+                colExpression    = nodes[LEFT].nodes[RIGHT];
+                nonColExpression = nodes[LEFT].nodes[LEFT];
+            }
+        } else {
+            if (nodes[RIGHT].nodes[LEFT].opType == OpTypes.COLUMN) {
+                colExpression    = nodes[RIGHT].nodes[LEFT];
+                nonColExpression = nodes[RIGHT].nodes[RIGHT];
+            } else if (nodes[RIGHT].nodes[RIGHT].opType == OpTypes.COLUMN) {
+                replaceColumn    = operation == OpTypes.ADD;
+                colExpression    = nodes[RIGHT].nodes[RIGHT];
+                nonColExpression = nodes[RIGHT].nodes[LEFT];
+            }
+        }
+
+        if (colExpression == null) {
+            return false;
+        }
+
+        Expression           otherExpression = left ? nodes[RIGHT]
+                                                    : nodes[LEFT];
+        ExpressionArithmetic newArg          = null;
+
+        if (!replaceColumn) {
+            newArg = new ExpressionArithmetic(operation, otherExpression,
+                                              nonColExpression);
+
+            newArg.resolveTypesForArithmetic(session);
+        }
+
+        if (left) {
+            if (replaceColumn) {
+                nodes[RIGHT]             = colExpression;
+                nodes[LEFT].nodes[RIGHT] = otherExpression;
+
+                ((ExpressionArithmetic) nodes[LEFT]).resolveTypesForArithmetic(
+                    session);
+            } else {
+                nodes[LEFT]  = colExpression;
+                nodes[RIGHT] = newArg;
+            }
+        } else {
+            if (replaceColumn) {
+                nodes[LEFT]               = colExpression;
+                nodes[RIGHT].nodes[RIGHT] = otherExpression;
+
+                ((ExpressionArithmetic) nodes[RIGHT])
+                    .resolveTypesForArithmetic(session);
+            } else {
+                nodes[RIGHT] = colExpression;
+                nodes[LEFT]  = newArg;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/ExpressionOp.java b/src/org/hsqldb/ExpressionOp.java
new file mode 100644
index 0000000..2e22c97
--- /dev/null
+++ b/src/org/hsqldb/ExpressionOp.java
@@ -0,0 +1,577 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of CAST, CASE, LIMIT and ZONE operations.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+public class ExpressionOp extends Expression {
+
+    static final ExpressionOp limitOneExpression = new ExpressionOp(
+        OpTypes.LIMIT,
+        new ExpressionValue(ValuePool.INTEGER_0, Type.SQL_INTEGER),
+        new ExpressionValue(ValuePool.INTEGER_1, Type.SQL_INTEGER));
+
+    /**
+     * Creates a special binary operation expression
+     */
+    ExpressionOp(int type, Expression left, Expression right) {
+
+        super(type);
+
+        nodes        = new Expression[BINARY];
+        nodes[LEFT]  = left;
+        nodes[RIGHT] = right;
+
+        switch (opType) {
+
+            case OpTypes.ALTERNATIVE :
+            case OpTypes.CASEWHEN :
+            case OpTypes.LIMIT :
+            case OpTypes.ZONE_MODIFIER :
+                return;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionOp");
+        }
+    }
+
+    /**
+     * creates a CAST expression
+     */
+    ExpressionOp(Expression e, Type dataType) {
+
+        super(OpTypes.CAST);
+
+        nodes         = new Expression[UNARY];
+        nodes[LEFT]   = e;
+        this.dataType = dataType;
+        this.alias    = e.alias;
+    }
+
+    /**
+     * creates a special conversion for time / timestamp comparison
+     */
+    ExpressionOp(Expression e) {
+
+        super(e.dataType.isDateTimeTypeWithZone() ? OpTypes.CAST
+                                                  : OpTypes.ZONE_MODIFIER);
+
+        switch (e.dataType.typeCode) {
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                nodes                = new Expression[UNARY];
+                nodes[LEFT] = new ExpressionOp(OpTypes.ZONE_MODIFIER, e, null);
+                nodes[LEFT].dataType = e.dataType;
+                dataType = DateTimeType.getDateTimeType(Types.SQL_TIME,
+                        e.dataType.scale);
+                break;
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                nodes                = new Expression[UNARY];
+                nodes[LEFT] = new ExpressionOp(OpTypes.ZONE_MODIFIER, e, null);
+                nodes[LEFT].dataType = e.dataType;
+                dataType = DateTimeType.getDateTimeType(Types.SQL_TIMESTAMP,
+                        e.dataType.scale);
+                break;
+
+            case Types.SQL_TIME :
+                nodes                = new Expression[BINARY];
+                nodes[LEFT]          = e;
+                nodes[LEFT].dataType = e.dataType;
+                dataType =
+                    DateTimeType.getDateTimeType(Types.SQL_TIME_WITH_TIME_ZONE,
+                                                 e.dataType.scale);
+                break;
+
+            case Types.SQL_TIMESTAMP :
+                nodes                = new Expression[BINARY];
+                nodes[LEFT]          = e;
+                nodes[LEFT].dataType = e.dataType;
+                dataType = DateTimeType.getDateTimeType(
+                    Types.SQL_TIMESTAMP_WITH_TIME_ZONE, e.dataType.scale);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionOp");
+        }
+
+        this.alias = e.alias;
+    }
+
+    public static Expression getCastExpression(Session session, Expression e,
+            Type dataType) {
+
+        if (e.getType() == OpTypes.VALUE) {
+            Object value = dataType.castToType(session, e.getValue(session),
+                                               e.getDataType());
+
+            return new ExpressionValue(value, dataType);
+        }
+
+        return new ExpressionOp(e, dataType);
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb    = new StringBuffer(64);
+        String       left  = getContextSQL(nodes.length > 0 ? nodes[LEFT]
+                                                            : null);
+        String       right = getContextSQL(nodes.length > 1 ? nodes[RIGHT]
+                                                            : null);
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                if (valueData == null) {
+                    return Tokens.T_NULL;
+                }
+
+                if (dataType == null) {
+                    throw Error.runtimeError(ErrorCode.U_S0500,
+                                             "ExpressionOp");
+                }
+
+                return dataType.convertToSQLString(valueData);
+
+            case OpTypes.CAST :
+                sb.append(' ').append(Tokens.T_CAST).append('(');
+                sb.append(left).append(' ').append(Tokens.T_AS).append(' ');
+                sb.append(dataType.getTypeDefinition());
+                sb.append(')');
+
+                return sb.toString();
+
+            case OpTypes.CASEWHEN :
+                sb.append(' ').append(Tokens.T_CASEWHEN).append('(');
+                sb.append(left).append(',').append(right).append(')');
+
+                return sb.toString();
+
+            case OpTypes.ALTERNATIVE :
+                sb.append(left).append(',').append(right);
+
+                return sb.toString();
+
+            case OpTypes.LIMIT :
+                if (left != null) {
+                    sb.append(' ').append(Tokens.T_OFFSET).append(' ');
+                    sb.append(left).append(' ');
+                }
+
+                if (right != null) {
+                    sb.append(' ').append(Tokens.T_FETCH).append(' ');
+                    sb.append(Tokens.T_FIRST);
+                    sb.append(right).append(' ').append(right).append(' ');
+                    sb.append(Tokens.T_ROWS).append(' ').append(Tokens.T_ONLY);
+                    sb.append(' ');
+                }
+                break;
+
+            case OpTypes.ZONE_MODIFIER :
+                sb.append(left).append(' ').append(Tokens.T_AT).append(' ');
+
+                if (nodes[RIGHT] == null) {
+                    sb.append(Tokens.T_LOCAL).append(' ');
+
+                    break;
+                }
+
+                sb.append(right);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionOp");
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                sb.append("VALUE = ").append(valueData);
+                sb.append(", TYPE = ").append(dataType.getNameString());
+
+                return sb.toString();
+
+            case OpTypes.TABLE :
+                sb.append("VALUELIST ");
+
+                for (int i = 0; i < nodes.length; i++) {
+                    sb.append(nodes[i].describe(session, blanks + 1));
+                    sb.append(' ');
+                }
+                break;
+
+            case OpTypes.CAST :
+                sb.append("CAST ");
+                sb.append(dataType.getTypeDefinition());
+                sb.append(' ');
+                break;
+
+            case OpTypes.CASEWHEN :
+                sb.append("CASEWHEN ");
+                break;
+        }
+
+        if (getLeftNode() != null) {
+            sb.append(" arg_left=[");
+            sb.append(nodes[LEFT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        if (getRightNode() != null) {
+            sb.append(" arg_right=[");
+            sb.append(nodes[RIGHT].describe(session, blanks + 1));
+            sb.append(']');
+        }
+
+        return sb.toString();
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+
+        if (opType == OpTypes.VALUE) {
+            return unresolvedSet;
+        }
+
+        switch (opType) {
+
+            case OpTypes.CASEWHEN :
+                acceptsSequences = false;
+                break;
+        }
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            unresolvedSet = nodes[i].resolveColumnReferences(rangeVarArray,
+                    rangeCount, unresolvedSet, acceptsSequences);
+        }
+
+        return unresolvedSet;
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                break;
+
+            case OpTypes.CAST : {
+                nodes[LEFT].resolveTypes(session, this);
+
+                Type type = nodes[LEFT].dataType;
+
+                if (type != null && !dataType.canConvertFrom(type)) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                if (nodes[LEFT].opType == OpTypes.VALUE) {
+                    Expression replacement = nodes[LEFT];
+
+                    setAsConstantValue(session);
+
+                    replacement.dataType  = dataType;
+                    replacement.valueData = valueData;
+
+                    if (parent != null) {
+                        parent.replaceNode(this, replacement);
+                    }
+
+                    break;
+                }
+
+                if (nodes[LEFT].opType == OpTypes.DYNAMIC_PARAM) {
+                    nodes[LEFT].dataType = dataType;
+
+                    if (parent != null && !parent.isSelfAggregate()) {
+//                        parent.replaceNode(this, nodes[LEFT]);
+                    }
+
+                    break;
+                }
+
+                if (dataType.equals(nodes[LEFT].dataType)) {
+
+                    // issues with aggregates
+                    break;
+                }
+
+                break;
+            }
+            case OpTypes.ZONE_MODIFIER :
+                nodes[LEFT].resolveTypes(session, this);
+
+                if (nodes[LEFT].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (nodes[RIGHT] != null) {
+                    nodes[RIGHT].resolveTypes(session, this);
+
+                    if (nodes[RIGHT].dataType == null) {
+                        nodes[RIGHT].dataType =
+                            Type.SQL_INTERVAL_HOUR_TO_MINUTE;
+                    }
+
+                    if (nodes[RIGHT].dataType.typeCode
+                            != Types.SQL_INTERVAL_HOUR_TO_MINUTE) {
+                        throw Error.error(ErrorCode.X_42563);
+                    }
+                }
+
+                switch (nodes[LEFT].dataType.typeCode) {
+
+                    case Types.SQL_TIME :
+                        dataType = DateTimeType.getDateTimeType(
+                            Types.SQL_TIME_WITH_TIME_ZONE,
+                            nodes[LEFT].dataType.scale);
+                        break;
+
+                    case Types.SQL_TIMESTAMP :
+                        dataType = DateTimeType.getDateTimeType(
+                            Types.SQL_TIMESTAMP_WITH_TIME_ZONE,
+                            nodes[LEFT].dataType.scale);
+                        break;
+
+                    case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                    case Types.SQL_TIME_WITH_TIME_ZONE :
+                        dataType = nodes[LEFT].dataType;
+                        break;
+
+                    default :
+                        throw Error.error(ErrorCode.X_42563);
+                }
+
+                // no constant optimisation as value dependent on session zone
+                break;
+
+            case OpTypes.CASEWHEN :
+
+                // We use CASEWHEN as parent type.
+                // In the parent, left node is the condition, and right node is
+                // the leaf, tagged as type ALTERNATIVE; its left node is
+                // case 1 (how to get the value when the condition in
+                // the parent evaluates to true), while its right node is case 2
+                // (how to get the value when the condition in
+                // the parent evaluates to false).
+                resolveTypesForCaseWhen(session);
+                break;
+
+            case OpTypes.LIMIT :
+                for (int i = 0; i < nodes.length; i++) {
+                    if (nodes[i] != null) {
+                        nodes[i].resolveTypes(session, this);
+
+                        if (nodes[i].dataType == null) {
+                            nodes[i].dataType = Type.SQL_INTEGER;
+                        }
+                    }
+                }
+                break;
+
+            case OpTypes.ALTERNATIVE :
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionOp");
+        }
+    }
+
+    /**
+     * For CASE WHEN and its special cases section 9.3 of the SQL standard
+     * on type aggregation is implemented.
+     */
+    void resolveTypesForCaseWhen(Session session) {
+
+        if (dataType != null) {
+            return;
+        }
+
+        Expression expr = this;
+
+        while (expr.opType == OpTypes.CASEWHEN) {
+            expr.nodes[LEFT].resolveTypes(session, expr);
+
+            if (expr.nodes[LEFT].isUnresolvedParam()) {
+                expr.nodes[LEFT].dataType = Type.SQL_BOOLEAN;
+            }
+
+            expr.nodes[RIGHT].nodes[LEFT].resolveTypes(session, nodes[RIGHT]);
+            expr.nodes[RIGHT].nodes[RIGHT].resolveTypes(session, nodes[RIGHT]);
+
+            expr = expr.nodes[RIGHT].nodes[RIGHT];
+        }
+
+        expr = this;
+
+        while (expr.opType == OpTypes.CASEWHEN) {
+            dataType =
+                Type.getAggregateType(expr.nodes[RIGHT].nodes[LEFT].dataType,
+                                      dataType);
+            dataType =
+                Type.getAggregateType(expr.nodes[RIGHT].nodes[RIGHT].dataType,
+                                      dataType);
+            expr = expr.nodes[RIGHT].nodes[RIGHT];
+        }
+
+        expr = this;
+
+        while (expr.opType == OpTypes.CASEWHEN) {
+            if (expr.nodes[RIGHT].nodes[LEFT].dataType == null) {
+                expr.nodes[RIGHT].nodes[LEFT].dataType = dataType;
+            }
+
+            if (expr.nodes[RIGHT].nodes[RIGHT].dataType == null) {
+                expr.nodes[RIGHT].nodes[RIGHT].dataType = dataType;
+            }
+
+            if (expr.nodes[RIGHT].dataType == null) {
+                expr.nodes[RIGHT].dataType = dataType;
+            }
+
+            expr = expr.nodes[RIGHT].nodes[RIGHT];
+        }
+
+        if (dataType == null) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+    }
+
+    public Object getValue(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                return valueData;
+
+            case OpTypes.SIMPLE_COLUMN : {
+                Object[] data =
+                    (Object[]) session.sessionContext
+                        .rangeIterators[rangePosition].getCurrent();
+
+                return data[columnIndex];
+            }
+            case OpTypes.ORDER_BY :
+                return nodes[LEFT].getValue(session);
+
+            case OpTypes.CAST : {
+                Object value =
+                    dataType.castToType(session,
+                                        nodes[LEFT].getValue(session),
+                                        nodes[LEFT].dataType);
+
+                if (dataType.userTypeModifier != null) {
+                    Constraint[] constraints =
+                        dataType.userTypeModifier.getConstraints();
+
+                    for (int i = 0; i < constraints.length; i++) {
+                        constraints[i].checkCheckConstraint(session, null,
+                                                            value);
+                    }
+                }
+
+                return value;
+            }
+            case OpTypes.CASEWHEN : {
+                Boolean result = (Boolean) nodes[LEFT].getValue(session);
+
+                if (Boolean.TRUE.equals(result)) {
+                    return nodes[RIGHT].nodes[LEFT].getValue(session,
+                            dataType);
+                } else {
+                    return nodes[RIGHT].nodes[RIGHT].getValue(session,
+                            dataType);
+                }
+            }
+            case OpTypes.ZONE_MODIFIER : {
+                Object leftValue  = nodes[LEFT].getValue(session);
+                Object rightValue = nodes[RIGHT] == null ? null
+                                                         : nodes[RIGHT]
+                                                             .getValue(
+                                                                 session);
+
+                if (leftValue == null) {
+                    return null;
+                }
+
+                if (nodes[RIGHT] != null && rightValue == null) {
+                    return null;
+                }
+
+                long zoneSeconds = nodes[RIGHT] == null
+                                   ? session.getZoneSeconds()
+                                   : ((IntervalType) nodes[RIGHT].dataType)
+                                       .getSeconds(rightValue);
+
+                return ((DateTimeType) dataType).changeZone(leftValue,
+                        nodes[LEFT].dataType, (int) zoneSeconds,
+                        session.getZoneSeconds());
+            }
+            case OpTypes.LIMIT :
+
+            // fall through
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionOp");
+        }
+    }
+}
diff --git a/src/org/hsqldb/ExpressionOrderBy.java b/src/org/hsqldb/ExpressionOrderBy.java
new file mode 100644
index 0000000..4eb092b
--- /dev/null
+++ b/src/org/hsqldb/ExpressionOrderBy.java
@@ -0,0 +1,137 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * Implementation of ORDER BY operations
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ExpressionOrderBy extends Expression {
+
+    private boolean isDescending;
+    private boolean isNullsLast;
+
+    ExpressionOrderBy(Expression e) {
+
+        super(OpTypes.ORDER_BY);
+
+        nodes       = new Expression[UNARY];
+        nodes[LEFT] = e;
+    }
+
+    /**
+     * Set an ORDER BY column expression DESC
+     */
+    void setDescending() {
+        isDescending = true;
+    }
+
+    /**
+     * Is an ORDER BY column expression DESC
+     */
+    boolean isDescending() {
+        return isDescending;
+    }
+
+    /**
+     * Set an ORDER BY column NULL ordering
+     */
+    void setNullsLast() {
+        isNullsLast = true;
+    }
+
+    /**
+     * Is an ORDER BY column NULL ordering
+     */
+    boolean isNullsLast() {
+        return isNullsLast;
+    }
+
+    public Object getValue(Session session) {
+        return nodes[LEFT].getValue(session);
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        nodes[LEFT].resolveTypes(session, parent);
+
+        if (nodes[LEFT].isUnresolvedParam()) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        dataType = nodes[LEFT].dataType;
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_ORDER).append(' ').append(Tokens.T_BY).append(' ');
+
+        if (nodes[LEFT].alias != null) {
+            sb.append(nodes[LEFT].alias.name);
+        } else {
+            sb.append(nodes[LEFT].getSQL());
+        }
+
+        if (isDescending) {
+            sb.append(' ').append(Tokens.T_DESC);
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        sb.append(getLeftNode().describe(session, blanks));
+
+        if (isDescending) {
+            sb.append(Tokens.T_DESC).append(' ');
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/ExpressionTable.java b/src/org/hsqldb/ExpressionTable.java
new file mode 100644
index 0000000..c16c622
--- /dev/null
+++ b/src/org/hsqldb/ExpressionTable.java
@@ -0,0 +1,224 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.navigator.RowSetNavigatorData;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.RowType;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of table conversion.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class ExpressionTable extends Expression {
+
+    boolean isTable;
+    boolean ordinality = false;
+
+    /**
+     * Creates an UNNEST ARRAY or MULTISET expression
+     */
+    ExpressionTable(Expression e, SubQuery sq, boolean ordinality) {
+
+        super(OpTypes.TABLE);
+
+        nodes           = new Expression[]{ e };
+        this.subQuery   = sq;
+        this.ordinality = ordinality;
+    }
+
+    public String getSQL() {
+
+        if (isTable) {
+            return Tokens.T_TABLE;
+        } else {
+            return Tokens.T_UNNEST;
+        }
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        if (isTable) {
+            sb.append(Tokens.T_TABLE).append(' ');
+        } else {
+            sb.append(Tokens.T_UNNEST).append(' ');
+        }
+
+        sb.append(nodes[LEFT].describe(session, blanks));
+
+        return sb.toString();
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        if (nodes[LEFT].dataType.isRowType()) {
+            isTable       = true;
+            nodeDataTypes = ((RowType) nodes[LEFT].dataType).getTypesArray();
+
+            subQuery.prepareTable(session);
+
+            subQuery.getTable().columnList =
+                ((FunctionSQLInvoked) nodes[LEFT]).routine.getTable()
+                    .columnList;
+        } else {
+            isTable = false;
+
+            int columnCount = ordinality ? 2
+                                         : 1;
+
+            nodeDataTypes       = new Type[columnCount];
+            nodeDataTypes[LEFT] = nodes[LEFT].dataType.collectionBaseType();
+
+            if (ordinality) {
+                nodeDataTypes[RIGHT] = Type.SQL_INTEGER;
+            }
+
+            subQuery.prepareTable(session);
+        }
+    }
+
+    public Result getResult(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.TABLE : {
+                RowSetNavigatorData navigator = subQuery.getNavigator(session);
+                Result              result    = Result.newResult(navigator);
+
+                result.metaData = subQuery.queryExpression.getMetaData();
+
+                return result;
+            }
+            default : {
+                throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionTable");
+            }
+        }
+    }
+
+    public Object[] getRowValue(Session session) {
+
+        switch (opType) {
+
+            case OpTypes.TABLE : {
+                return subQuery.queryExpression.getValues(session);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+
+    Object getValue(Session session, Type type) {
+
+        switch (opType) {
+
+            case OpTypes.TABLE : {
+                materialise(session);
+
+                Object[] value = subQuery.getValues(session);
+
+                if (value.length == 1) {
+                    return ((Object[]) value)[0];
+                }
+
+                return value;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Expression");
+        }
+    }
+
+    public Object getValue(Session session) {
+        return valueData;
+    }
+
+    void insertValuesIntoSubqueryTable(Session session,
+                                       PersistentStore store) {
+
+        if (isTable) {
+            Result          result = nodes[LEFT].getResult(session);
+            RowSetNavigator nav    = result.navigator;
+            int             size   = nav.getSize();
+
+            while (nav.hasNext()) {
+                Object[] data = nav.getNext();
+                Row      row  = (Row) store.getNewCachedObject(session, data);
+
+                try {
+                    store.indexRow(session, row);
+                } catch (HsqlException e) {}
+            }
+        } else {
+            Object[] array = (Object[]) nodes[LEFT].getValue(session);
+
+            for (int i = 0; i < array.length; i++) {
+                Object[] data;
+
+                if (ordinality) {
+                    data = new Object[] {
+                        array[i], ValuePool.getInt(i)
+                    };
+                } else {
+                    data = new Object[]{ array[i] };
+                }
+
+                Row row = (Row) store.getNewCachedObject(session, data);
+
+                try {
+                    store.indexRow(session, row);
+                } catch (HsqlException e) {}
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/ExpressionValue.java b/src/org/hsqldb/ExpressionValue.java
new file mode 100644
index 0000000..6790991
--- /dev/null
+++ b/src/org/hsqldb/ExpressionValue.java
@@ -0,0 +1,111 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of value access operations.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ExpressionValue extends Expression {
+
+    /**
+     * Creates a VALUE expression
+     */
+    ExpressionValue(Object o, Type datatype) {
+
+        super(OpTypes.VALUE);
+
+        nodes     = Expression.emptyArray;
+        dataType  = datatype;
+        valueData = o;
+    }
+
+    public String getSQL() {
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                if (valueData == null) {
+                    return Tokens.T_NULL;
+                }
+
+                return dataType.convertToSQLString(valueData);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionValue");
+        }
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        switch (opType) {
+
+            case OpTypes.VALUE :
+                sb.append("VALUE = ").append(valueData);
+                sb.append(", TYPE = ").append(dataType.getNameString());
+
+                return sb.toString();
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionValue");
+        }
+    }
+
+    Object getValue(Session session, Type type) {
+
+        if (dataType == type || valueData == null) {
+            return valueData;
+        }
+
+        return type.convertToType(session, valueData, dataType);
+    }
+
+    public Object getValue(Session session) {
+        return valueData;
+    }
+}
diff --git a/src/org/hsqldb/FunctionCustom.java b/src/org/hsqldb/FunctionCustom.java
new file mode 100644
index 0000000..42669f0
--- /dev/null
+++ b/src/org/hsqldb/FunctionCustom.java
@@ -0,0 +1,2157 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.IntKeyIntValueHashMap;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.persist.Crypto;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.store.BitMap;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.DTIType;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of HSQLDB functions that are not defined by the
+ * SQL standard.<p>
+ *
+ * Some functions are translated into equivalent SQL Standard functions.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class FunctionCustom extends FunctionSQL {
+
+    public static final String[] openGroupNumericFunctions = {
+        "ABS", "ACOS", "ASIN", "ATAN", "ATAN2", "BITAND", "BITOR", "BITXOR",
+        "CEILING", "COS", "COT", "DEGREES", "EXP", "FLOOR", "LOG", "LOG10",
+        "MOD", "PI", "POWER", "RADIANS", "RAND", "ROUND", "ROUNDMAGIC", "SIGN",
+        "SIN", "SQRT", "TAN", "TRUNCATE"
+    };
+    public static final String[] openGroupStringFunctions = {
+        "ASCII", "CHAR", "CONCAT", "DIFFERENCE", "HEXTORAW", "INSERT", "LCASE",
+        "LEFT", "LENGTH", "LOCATE", "LTRIM", "RAWTOHEX", "REPEAT", "REPLACE",
+        "RIGHT", "RTRIM", "SOUNDEX", "SPACE", "SUBSTR", "UCASE",
+    };
+    public static final String[] openGroupDateTimeFunctions = {
+        "CURDATE", "CURTIME", "DATEDIFF", "DAYNAME", "DAYOFMONTH", "DAYOFWEEK",
+        "DAYOFYEAR", "HOUR", "MINUTE", "MONTH", "MONTHNAME", "NOW", "QUARTER",
+        "SECOND", "SECONDS_SINCE_MIDNIGHT", "TIMESTAMPADD", "TIMESTAMPDIFF",
+        "TO_CHAR", "WEEK", "YEAR"
+    };
+    public static final String[] openGroupSystemFunctions = {
+        "DATABASE", "IFNULL", "USER"
+    };
+
+    //
+    private final static int FUNC_ISAUTOCOMMIT             = 71;
+    private final static int FUNC_ISREADONLYSESSION        = 72;
+    private final static int FUNC_ISREADONLYDATABASE       = 73;
+    private final static int FUNC_ISREADONLYDATABASEFILES  = 74;
+    private final static int FUNC_DATABASE                 = 75;
+    private final static int FUNC_IDENTITY                 = 76;
+    private final static int FUNC_SYSDATE                  = 77;
+    private final static int FUNC_TIMESTAMPADD             = 78;
+    private final static int FUNC_TIMESTAMPDIFF            = 79;
+    private final static int FUNC_TRUNCATE                 = 80;
+    private final static int FUNC_TO_CHAR                  = 81;
+    private final static int FUNC_TIMESTAMP                = 82;
+    private final static int FUNC_CRYPT_KEY                = 83;
+    private final static int FUNC_ISOLATION_LEVEL          = 85;
+    private final static int FUNC_SESSION_ISOLATION_LEVEL  = 86;
+    private final static int FUNC_DATABASE_ISOLATION_LEVEL = 87;
+    private final static int FUNC_TRANSACTION_CONTROL      = 88;
+    private final static int FUNC_TIMEZONE                 = 89;
+    private final static int FUNC_SESSION_TIMEZONE         = 90;
+    private final static int FUNC_DATABASE_TIMEZONE        = 91;
+    private final static int FUNC_DATABASE_VERSION         = 92;
+
+    //
+    private static final int FUNC_ACOS             = 101;
+    private static final int FUNC_ASIN             = 102;
+    private static final int FUNC_ATAN             = 103;
+    private static final int FUNC_ATAN2            = 104;
+    private static final int FUNC_COS              = 105;
+    private static final int FUNC_COT              = 106;
+    private static final int FUNC_DEGREES          = 107;
+    private static final int FUNC_LOG10            = 110;
+    private static final int FUNC_PI               = 111;
+    private static final int FUNC_RADIANS          = 112;
+    private static final int FUNC_RAND             = 113;
+    private static final int FUNC_ROUND            = 114;
+    private static final int FUNC_SIGN             = 115;
+    private static final int FUNC_SIN              = 116;
+    private static final int FUNC_TAN              = 117;
+    private static final int FUNC_BITAND           = 118;
+    private static final int FUNC_BITOR            = 119;
+    private static final int FUNC_BITXOR           = 120;
+    private static final int FUNC_ROUNDMAGIC       = 121;
+    private static final int FUNC_ASCII            = 122;
+    private static final int FUNC_CHAR             = 123;
+    private static final int FUNC_CONCAT           = 124;
+    private static final int FUNC_DIFFERENCE       = 125;
+    private static final int FUNC_HEXTORAW         = 126;
+    private static final int FUNC_LEFT             = 128;
+    private static final int FUNC_LOCATE           = 130;
+    private static final int FUNC_LTRIM            = 131;
+    private static final int FUNC_RAWTOHEX         = 132;
+    private static final int FUNC_REPEAT           = 133;
+    private static final int FUNC_REPLACE          = 134;
+    private static final int FUNC_REVERSE          = 135;
+    private static final int FUNC_RIGHT            = 136;
+    private static final int FUNC_RTRIM            = 137;
+    private static final int FUNC_SOUNDEX          = 138;
+    private static final int FUNC_SPACE            = 139;
+    private static final int FUNC_SUBSTR           = 140;
+    private static final int FUNC_DATEADD          = 141;
+    private static final int FUNC_DATEDIFF         = 142;
+    private static final int FUNC_SECONDS_MIDNIGHT = 143;
+    private static final int FUNC_REGEXP_MATCHES   = 144;
+
+    //
+    static final IntKeyIntValueHashMap customRegularFuncMap =
+        new IntKeyIntValueHashMap();
+
+    static {
+        customRegularFuncMap.put(Tokens.LENGTH, FUNC_CHAR_LENGTH);
+        customRegularFuncMap.put(Tokens.BITLENGTH, FUNC_BIT_LENGTH);
+        customRegularFuncMap.put(Tokens.OCTETLENGTH, FUNC_OCTET_LENGTH);
+        customRegularFuncMap.put(Tokens.LCASE, FUNC_FOLD_LOWER);
+        customRegularFuncMap.put(Tokens.UCASE, FUNC_FOLD_UPPER);
+        customRegularFuncMap.put(Tokens.LOG, FUNC_LN);
+
+        //
+        customRegularFuncMap.put(Tokens.CURDATE, FUNC_CURRENT_DATE);
+        customRegularFuncMap.put(Tokens.CURTIME, FUNC_LOCALTIME);
+        customRegularFuncMap.put(Tokens.SUBSTR, FUNC_SUBSTRING_CHAR);
+
+        //
+        customRegularFuncMap.put(Tokens.CRYPT_KEY, FUNC_CRYPT_KEY);
+
+        //
+        customRegularFuncMap.put(Tokens.YEAR, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.MONTH, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.DAY, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.HOUR, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.MINUTE, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.SECOND, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.DAYNAME, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.MONTHNAME, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.DAYOFMONTH, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.DAYOFWEEK, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.DAYOFYEAR, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.QUARTER, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.WEEK, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.SECONDS_MIDNIGHT, FUNC_EXTRACT);
+        customRegularFuncMap.put(Tokens.LTRIM, FUNC_TRIM_CHAR);
+        customRegularFuncMap.put(Tokens.RTRIM, FUNC_TRIM_CHAR);
+        customRegularFuncMap.put(Tokens.LEFT, FUNC_LEFT);
+
+        //
+        customRegularFuncMap.put(Tokens.IDENTITY, FUNC_IDENTITY);
+        customRegularFuncMap.put(Tokens.TIMESTAMPADD, FUNC_TIMESTAMPADD);
+        customRegularFuncMap.put(Tokens.TIMESTAMPDIFF, FUNC_TIMESTAMPDIFF);
+        customRegularFuncMap.put(Tokens.TRUNCATE, FUNC_TRUNCATE);
+        customRegularFuncMap.put(Tokens.TO_CHAR, FUNC_TO_CHAR);
+        customRegularFuncMap.put(Tokens.TIMESTAMP, FUNC_TIMESTAMP);
+
+        //
+        nonDeterministicFuncSet.add(FUNC_IDENTITY);
+        nonDeterministicFuncSet.add(FUNC_TIMESTAMPADD);
+        nonDeterministicFuncSet.add(FUNC_TIMESTAMP);
+
+        //
+        customRegularFuncMap.put(Tokens.LOCATE, FUNC_POSITION_CHAR);
+        customRegularFuncMap.put(Tokens.INSERT, FUNC_OVERLAY_CHAR);
+        customRegularFuncMap.put(Tokens.REVERSE, FUNC_REVERSE);
+
+        //
+        //
+        customRegularFuncMap.put(Tokens.DATABASE, FUNC_DATABASE);
+        customRegularFuncMap.put(Tokens.ISAUTOCOMMIT, FUNC_ISAUTOCOMMIT);
+        customRegularFuncMap.put(Tokens.ISREADONLYSESSION,
+                                 FUNC_ISREADONLYSESSION);
+        customRegularFuncMap.put(Tokens.ISREADONLYDATABASE,
+                                 FUNC_ISREADONLYDATABASE);
+        customRegularFuncMap.put(Tokens.ISREADONLYDATABASEFILES,
+                                 FUNC_ISREADONLYDATABASEFILES);
+        customRegularFuncMap.put(Tokens.ISOLATION_LEVEL, FUNC_ISOLATION_LEVEL);
+        customRegularFuncMap.put(Tokens.SESSION_ISOLATION_LEVEL,
+                                 FUNC_SESSION_ISOLATION_LEVEL);
+        customRegularFuncMap.put(Tokens.DATABASE_ISOLATION_LEVEL,
+                                 FUNC_DATABASE_ISOLATION_LEVEL);
+        customRegularFuncMap.put(Tokens.TRANSACTION_CONTROL,
+                                 FUNC_TRANSACTION_CONTROL);
+        customRegularFuncMap.put(Tokens.TIMEZONE, FUNC_TIMEZONE);
+        customRegularFuncMap.put(Tokens.SESSION_TIMEZONE,
+                                 FUNC_SESSION_TIMEZONE);
+        customRegularFuncMap.put(Tokens.DATABASE_TIMEZONE,
+                                 FUNC_DATABASE_TIMEZONE);
+        customRegularFuncMap.put(Tokens.DATABASE_VERSION,
+                                 FUNC_DATABASE_VERSION);
+
+        //
+        nonDeterministicFuncSet.add(FUNC_DATABASE);
+        nonDeterministicFuncSet.add(FUNC_ISAUTOCOMMIT);
+        nonDeterministicFuncSet.add(FUNC_ISREADONLYSESSION);
+        nonDeterministicFuncSet.add(FUNC_ISREADONLYDATABASE);
+        nonDeterministicFuncSet.add(FUNC_ISREADONLYDATABASEFILES);
+        nonDeterministicFuncSet.add(FUNC_ISOLATION_LEVEL);
+        nonDeterministicFuncSet.add(FUNC_SESSION_ISOLATION_LEVEL);
+        nonDeterministicFuncSet.add(FUNC_DATABASE_ISOLATION_LEVEL);
+        nonDeterministicFuncSet.add(FUNC_TRANSACTION_CONTROL);
+        nonDeterministicFuncSet.add(FUNC_TIMEZONE);
+        nonDeterministicFuncSet.add(FUNC_SESSION_TIMEZONE);
+        nonDeterministicFuncSet.add(FUNC_DATABASE_TIMEZONE);
+
+        //
+        customRegularFuncMap.put(Tokens.ACOS, FUNC_ACOS);
+        customRegularFuncMap.put(Tokens.ASIN, FUNC_ASIN);
+        customRegularFuncMap.put(Tokens.ATAN, FUNC_ATAN);
+        customRegularFuncMap.put(Tokens.ATAN2, FUNC_ATAN2);
+        customRegularFuncMap.put(Tokens.COS, FUNC_COS);
+        customRegularFuncMap.put(Tokens.COT, FUNC_COT);
+        customRegularFuncMap.put(Tokens.DEGREES, FUNC_DEGREES);
+        customRegularFuncMap.put(Tokens.LOG10, FUNC_LOG10);
+        customRegularFuncMap.put(Tokens.PI, FUNC_PI);
+        customRegularFuncMap.put(Tokens.RADIANS, FUNC_RADIANS);
+        customRegularFuncMap.put(Tokens.RAND, FUNC_RAND);
+        customRegularFuncMap.put(Tokens.ROUND, FUNC_ROUND);
+        customRegularFuncMap.put(Tokens.REGEXP_MATCHES, FUNC_REGEXP_MATCHES);
+        customRegularFuncMap.put(Tokens.SIGN, FUNC_SIGN);
+        customRegularFuncMap.put(Tokens.SIN, FUNC_SIN);
+        customRegularFuncMap.put(Tokens.TAN, FUNC_TAN);
+        customRegularFuncMap.put(Tokens.BITAND, FUNC_BITAND);
+        customRegularFuncMap.put(Tokens.BITOR, FUNC_BITOR);
+        customRegularFuncMap.put(Tokens.BITXOR, FUNC_BITXOR);
+        customRegularFuncMap.put(Tokens.ROUNDMAGIC, FUNC_ROUNDMAGIC);
+        customRegularFuncMap.put(Tokens.ASCII, FUNC_ASCII);
+        customRegularFuncMap.put(Tokens.CHAR, FUNC_CHAR);
+        customRegularFuncMap.put(Tokens.CONCAT_WORD, FUNC_CONCAT);
+        customRegularFuncMap.put(Tokens.DIFFERENCE, FUNC_DIFFERENCE);
+        customRegularFuncMap.put(Tokens.HEXTORAW, FUNC_HEXTORAW);
+        customRegularFuncMap.put(Tokens.RAWTOHEX, FUNC_RAWTOHEX);
+        customRegularFuncMap.put(Tokens.REPEAT, FUNC_REPEAT);
+        customRegularFuncMap.put(Tokens.REPLACE, FUNC_REPLACE);
+        customRegularFuncMap.put(Tokens.RIGHT, FUNC_RIGHT);
+        customRegularFuncMap.put(Tokens.SOUNDEX, FUNC_SOUNDEX);
+        customRegularFuncMap.put(Tokens.SPACE, FUNC_SPACE);
+        customRegularFuncMap.put(Tokens.DATEADD, FUNC_DATEADD);
+        customRegularFuncMap.put(Tokens.DATEDIFF, FUNC_DATEDIFF);
+    }
+
+    static final IntKeyIntValueHashMap customValueFuncMap =
+        new IntKeyIntValueHashMap();
+
+    static {
+        customValueFuncMap.put(Tokens.SYSDATE, FUNC_LOCALTIMESTAMP);
+        customValueFuncMap.put(Tokens.TODAY, FUNC_CURRENT_DATE);
+        customValueFuncMap.put(Tokens.NOW, FUNC_LOCALTIMESTAMP);
+    }
+
+    private int     extractSpec;
+    private String  matchPattern;
+    private Pattern pattern;
+
+    public static FunctionSQL newCustomFunction(String token, int tokenType) {
+
+        int id = customRegularFuncMap.get(tokenType, -1);
+
+        if (id == -1) {
+            id = customValueFuncMap.get(tokenType, -1);
+        }
+
+        if (id == -1) {
+            return null;
+        }
+
+        switch (tokenType) {
+
+            case Tokens.BITLENGTH :
+            case Tokens.LCASE :
+            case Tokens.LENGTH :
+            case Tokens.LOG :
+            case Tokens.OCTETLENGTH :
+            case Tokens.TODAY :
+            case Tokens.SYSDATE :
+            case Tokens.UCASE :
+                return new FunctionSQL(id);
+
+            case Tokens.NOW : {
+                FunctionSQL function = new FunctionSQL(id);
+
+                function.parseList = optionalNoParamList;
+
+                return function;
+            }
+            case Tokens.CURDATE :
+            case Tokens.CURTIME : {
+                FunctionSQL function = new FunctionSQL(id);
+
+                function.parseList = emptyParamList;
+
+                return function;
+            }
+            case Tokens.SUBSTR : {
+                FunctionSQL function = new FunctionSQL(id);
+
+                function.parseList = tripleParamList;
+
+                return function;
+            }
+            case Tokens.LOCATE :
+                FunctionSQL function = new FunctionSQL(id);
+
+                function.parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.COMMA,
+                    Tokens.QUESTION, Tokens.X_OPTION, 2, Tokens.COMMA,
+                    Tokens.QUESTION, Tokens.CLOSEBRACKET
+                };
+
+                return function;
+        }
+
+        FunctionCustom function = new FunctionCustom(id);
+
+        if (id == FUNC_TRIM_CHAR) {
+            switch (tokenType) {
+
+                case Tokens.LTRIM :
+                    function.extractSpec = Tokens.LEADING;
+                    break;
+
+                case Tokens.RTRIM :
+                    function.extractSpec = Tokens.TRAILING;
+                    break;
+            }
+        }
+
+        if (id == FUNC_EXTRACT) {
+            switch (tokenType) {
+
+                case Tokens.DAYNAME :
+                    function.extractSpec = Tokens.DAY_NAME;
+                    break;
+
+                case Tokens.MONTHNAME :
+                    function.extractSpec = Tokens.MONTH_NAME;
+                    break;
+
+                case Tokens.DAYOFMONTH :
+                    function.extractSpec = Tokens.DAY_OF_MONTH;
+                    break;
+
+                case Tokens.DAYOFWEEK :
+                    function.extractSpec = Tokens.DAY_OF_WEEK;
+                    break;
+
+                case Tokens.DAYOFYEAR :
+                    function.extractSpec = Tokens.DAY_OF_YEAR;
+                    break;
+
+                default :
+                    function.extractSpec = tokenType;
+            }
+        }
+
+        if (function.name == null) {
+            function.name = token;
+        }
+
+        return function;
+    }
+
+    public static boolean isRegularFunction(int tokenType) {
+        return customRegularFuncMap.get(tokenType, -1) != -1;
+    }
+
+    public static boolean isValueFunction(int tokenType) {
+        return customValueFuncMap.get(tokenType, -1) != -1;
+    }
+
+    private FunctionCustom(int id) {
+
+        super();
+
+        this.funcType   = id;
+        isDeterministic = !nonDeterministicFuncSet.contains(id);
+
+        switch (id) {
+
+            case FUNC_CONCAT :
+            case FUNC_LEFT :
+                parseList = doubleParamList;
+                break;
+
+            case FUNC_DATABASE :
+                parseList = emptyParamList;
+                break;
+
+            case FUNC_ISAUTOCOMMIT :
+            case FUNC_ISREADONLYSESSION :
+            case FUNC_ISREADONLYDATABASE :
+            case FUNC_ISREADONLYDATABASEFILES :
+            case FUNC_ISOLATION_LEVEL :
+            case FUNC_SESSION_ISOLATION_LEVEL :
+            case FUNC_DATABASE_ISOLATION_LEVEL :
+            case FUNC_TRANSACTION_CONTROL :
+            case FUNC_TIMEZONE :
+            case FUNC_SESSION_TIMEZONE :
+            case FUNC_DATABASE_TIMEZONE :
+            case FUNC_DATABASE_VERSION :
+                parseList = emptyParamList;
+                break;
+
+            case FUNC_EXTRACT :
+                name      = Tokens.T_EXTRACT;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_TRIM_CHAR :
+                name      = Tokens.T_TRIM;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_OVERLAY_CHAR :
+                name      = Tokens.T_OVERLAY;
+                parseList = quadParamList;
+                break;
+
+            case FUNC_IDENTITY :
+                name      = Tokens.T_IDENTITY;
+                parseList = emptyParamList;
+                break;
+
+            case FUNC_TIMESTAMPADD :
+                name      = Tokens.T_TIMESTAMPADD;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.X_KEYSET, 9,
+                    Tokens.SQL_TSI_FRAC_SECOND, Tokens.SQL_TSI_SECOND,
+                    Tokens.SQL_TSI_MINUTE, Tokens.SQL_TSI_HOUR,
+                    Tokens.SQL_TSI_DAY, Tokens.SQL_TSI_WEEK,
+                    Tokens.SQL_TSI_MONTH, Tokens.SQL_TSI_QUARTER,
+                    Tokens.SQL_TSI_YEAR, Tokens.COMMA, Tokens.QUESTION,
+                    Tokens.COMMA, Tokens.QUESTION, Tokens.CLOSEBRACKET
+                };
+                break;
+
+            case FUNC_TIMESTAMPDIFF :
+                name      = Tokens.T_TIMESTAMPDIFF;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.X_KEYSET, 9,
+                    Tokens.SQL_TSI_FRAC_SECOND, Tokens.SQL_TSI_SECOND,
+                    Tokens.SQL_TSI_MINUTE, Tokens.SQL_TSI_HOUR,
+                    Tokens.SQL_TSI_DAY, Tokens.SQL_TSI_WEEK,
+                    Tokens.SQL_TSI_MONTH, Tokens.SQL_TSI_QUARTER,
+                    Tokens.SQL_TSI_YEAR, Tokens.COMMA, Tokens.QUESTION,
+                    Tokens.COMMA, Tokens.QUESTION, Tokens.CLOSEBRACKET
+                };
+                break;
+
+            case FUNC_TRUNCATE :
+                parseList = doubleParamList;
+                break;
+
+            case FUNC_TO_CHAR :
+                parseList = doubleParamList;
+                break;
+
+            case FUNC_TIMESTAMP :
+                name      = Tokens.T_TIMESTAMP;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.X_OPTION, 2,
+                    Tokens.COMMA, Tokens.QUESTION, Tokens.CLOSEBRACKET
+                };
+                break;
+
+            case FUNC_PI :
+                parseList = emptyParamList;
+                break;
+
+            case FUNC_RAND :
+                parseList = optionalSingleParamList;
+                break;
+
+            case FUNC_ACOS :
+            case FUNC_ASIN :
+            case FUNC_ATAN :
+            case FUNC_COS :
+            case FUNC_COT :
+            case FUNC_DEGREES :
+            case FUNC_SIN :
+            case FUNC_TAN :
+            case FUNC_LOG10 :
+            case FUNC_RADIANS :
+            case FUNC_ROUNDMAGIC :
+            case FUNC_SIGN :
+            case FUNC_SOUNDEX :
+            case FUNC_ASCII :
+            case FUNC_CHAR :
+            case FUNC_HEXTORAW :
+            case FUNC_RAWTOHEX :
+            case FUNC_REVERSE :
+            case FUNC_SPACE :
+                parseList = singleParamList;
+                break;
+
+            case FUNC_ATAN2 :
+            case FUNC_ROUND :
+            case FUNC_BITAND :
+            case FUNC_BITOR :
+            case FUNC_BITXOR :
+            case FUNC_DIFFERENCE :
+            case FUNC_REPEAT :
+            case FUNC_RIGHT :
+            case FUNC_REGEXP_MATCHES :
+                parseList = doubleParamList;
+                break;
+
+            case FUNC_CRYPT_KEY :
+                parseList = doubleParamList;
+                break;
+
+            case FUNC_DATEADD :
+            case FUNC_DATEDIFF :
+            case FUNC_REPLACE :
+                parseList = tripleParamList;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "FunctionCustom");
+        }
+    }
+
+    public void setArguments(Expression[] nodes) {
+
+        switch (funcType) {
+
+            case FUNC_OVERLAY_CHAR : {
+                Expression start  = nodes[1];
+                Expression length = nodes[2];
+
+                nodes[1] = nodes[3];
+                nodes[2] = start;
+                nodes[3] = length;
+
+                break;
+            }
+            case FUNC_EXTRACT : {
+                Expression[] newNodes = new Expression[2];
+
+                newNodes[0] =
+                    new ExpressionValue(ValuePool.getInt(extractSpec),
+                                        Type.SQL_INTEGER);
+                newNodes[1] = nodes[0];
+                nodes       = newNodes;
+
+                break;
+            }
+            case FUNC_TRIM_CHAR : {
+                Expression[] newNodes = new Expression[3];
+
+                newNodes[0] =
+                    new ExpressionValue(ValuePool.getInt(extractSpec),
+                                        Type.SQL_INTEGER);
+                newNodes[1] = new ExpressionValue(" ", Type.SQL_CHAR);
+                newNodes[2] = nodes[0];
+                nodes       = newNodes;
+            }
+        }
+
+        super.setArguments(nodes);
+    }
+
+    public Expression getFunctionExpression() {
+
+        switch (funcType) {
+
+            case FUNC_CONCAT :
+                return new ExpressionArithmetic(OpTypes.CONCAT,
+                                                nodes[Expression.LEFT],
+                                                nodes[Expression.RIGHT]);
+        }
+
+        return super.getFunctionExpression();
+    }
+
+    Object getValue(Session session, Object[] data) {
+
+        switch (funcType) {
+
+            case FUNC_EXTRACT :
+            case FUNC_TRIM_CHAR :
+            case FUNC_OVERLAY_CHAR :
+                return super.getValue(session, data);
+
+            case FUNC_DATABASE :
+                return session.getDatabase().getPath();
+
+            case FUNC_ISAUTOCOMMIT :
+                return session.isAutoCommit() ? Boolean.TRUE
+                                              : Boolean.FALSE;
+
+            case FUNC_ISREADONLYSESSION :
+                return session.isReadOnlyDefault() ? Boolean.TRUE
+                                                   : Boolean.FALSE;
+
+            case FUNC_ISREADONLYDATABASE :
+                return session.getDatabase().databaseReadOnly ? Boolean.TRUE
+                                                              : Boolean.FALSE;
+
+            case FUNC_ISREADONLYDATABASEFILES :
+                return session.getDatabase().isFilesReadOnly() ? Boolean.TRUE
+                                                               : Boolean.FALSE;
+
+            case FUNC_ISOLATION_LEVEL : {
+                return Session.getIsolationString(session.isolationLevel);
+            }
+            case FUNC_SESSION_ISOLATION_LEVEL :
+                return Session.getIsolationString(
+                    session.isolationLevelDefault);
+
+            case FUNC_DATABASE_ISOLATION_LEVEL :
+                return Session.getIsolationString(
+                    session.database.getDefaultIsolationLevel());
+
+            case FUNC_TRANSACTION_CONTROL :
+                switch (session.database.txManager.getTransactionControl()) {
+
+                    case TransactionManager.MVCC :
+                        return Tokens.T_MVCC;
+
+                    case TransactionManager.MVLOCKS :
+                        return Tokens.T_MVLOCKS;
+
+                    case TransactionManager.LOCKS :
+                    default :
+                        return Tokens.T_LOCKS;
+                }
+            case FUNC_TIMEZONE :
+                return new IntervalSecondData(session.getZoneSeconds(), 0);
+
+            case FUNC_SESSION_TIMEZONE :
+                return new IntervalSecondData(session.sessionTimeZoneSeconds,
+                                              0);
+
+            case FUNC_DATABASE_TIMEZONE :
+                int sec =
+                    HsqlDateTime.getZoneSeconds(HsqlDateTime.tempCalDefault);
+
+                return new IntervalSecondData(sec, 0);
+
+            case FUNC_DATABASE_VERSION :
+                return HsqlDatabaseProperties.THIS_FULL_VERSION;
+
+            case FUNC_IDENTITY : {
+                Number id = session.getLastIdentity();
+
+                if (id instanceof Long) {
+                    return id;
+                } else {
+                    return ValuePool.getLong(id.longValue());
+                }
+            }
+            case FUNC_TIMESTAMPADD : {
+                if (data[1] == null || data[2] == null) {
+                    return null;
+                }
+
+                data[1] = Type.SQL_BIGINT.convertToType(session, data[1],
+                        nodes[1].getDataType());
+
+                int           part = ((Number) nodes[0].valueData).intValue();
+                long          units  = ((Number) data[1]).longValue();
+                TimestampData source = (TimestampData) data[2];
+                IntervalType  t;
+                Object        o;
+
+                switch (part) {
+
+                    case Tokens.SQL_TSI_FRAC_SECOND : {
+                        long seconds = units / DTIType.limitNanoseconds;
+                        int  nanos = (int) (units % DTIType.limitNanoseconds);
+
+                        t = Type.SQL_INTERVAL_SECOND_MAX_FRACTION;
+                        o = new IntervalSecondData(seconds, nanos, t);
+
+                        return dataType.add(source, o, t);
+                    }
+                    case Tokens.SQL_TSI_SECOND :
+                        t = Type.SQL_INTERVAL_SECOND_MAX_PRECISION;
+                        o = IntervalSecondData.newIntervalSeconds(units, t);
+
+                        return dataType.add(source, o, t);
+
+                    case Tokens.SQL_TSI_MINUTE :
+                        t = Type.SQL_INTERVAL_MINUTE_MAX_PRECISION;
+                        o = IntervalSecondData.newIntervalMinute(units, t);
+
+                        return dataType.add(source, o, t);
+
+                    case Tokens.SQL_TSI_HOUR :
+                        t = Type.SQL_INTERVAL_HOUR_MAX_PRECISION;
+                        o = IntervalSecondData.newIntervalHour(units, t);
+
+                        return dataType.add(source, o, t);
+
+                    case Tokens.SQL_TSI_DAY :
+                        t = Type.SQL_INTERVAL_DAY_MAX_PRECISION;
+                        o = IntervalSecondData.newIntervalDay(units, t);
+
+                        return dataType.add(source, o, t);
+
+                    case Tokens.SQL_TSI_WEEK :
+                        t = Type.SQL_INTERVAL_DAY_MAX_PRECISION;
+                        o = IntervalSecondData.newIntervalDay(units * 7, t);
+
+                        return dataType.add(source, o, t);
+
+                    case Tokens.SQL_TSI_MONTH :
+                        t = Type.SQL_INTERVAL_MONTH_MAX_PRECISION;
+                        o = IntervalMonthData.newIntervalMonth(units, t);
+
+                        return dataType.add(source, o, t);
+
+                    case Tokens.SQL_TSI_QUARTER :
+                        t = Type.SQL_INTERVAL_MONTH_MAX_PRECISION;
+                        o = IntervalMonthData.newIntervalMonth(units * 3, t);
+
+                        return dataType.add(source, o, t);
+
+                    case Tokens.SQL_TSI_YEAR :
+                        t = Type.SQL_INTERVAL_YEAR_MAX_PRECISION;
+                        o = IntervalMonthData.newIntervalMonth(units * 12, t);
+
+                        return dataType.add(source, o, t);
+
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "FunctionCustom");
+                }
+            }
+            case FUNC_TIMESTAMPDIFF : {
+                if (data[1] == null || data[2] == null) {
+                    return null;
+                }
+
+                int           part = ((Number) nodes[0].valueData).intValue();
+                TimestampData a    = (TimestampData) data[2];
+                TimestampData b    = (TimestampData) data[1];
+
+                if (nodes[2].dataType.isDateTimeTypeWithZone()) {
+                    a = (TimestampData) Type.SQL_TIMESTAMP.convertToType(
+                        session, a, Type.SQL_TIMESTAMP_WITH_TIME_ZONE);
+                }
+
+                if (nodes[1].dataType.isDateTimeTypeWithZone()) {
+                    b = (TimestampData) Type.SQL_TIMESTAMP.convertToType(
+                        session, b, Type.SQL_TIMESTAMP_WITH_TIME_ZONE);
+                }
+
+                IntervalType t;
+
+                switch (part) {
+
+                    case Tokens.SQL_TSI_FRAC_SECOND :
+                        t = Type.SQL_INTERVAL_SECOND_MAX_PRECISION;
+
+                        IntervalSecondData interval =
+                            (IntervalSecondData) t.subtract(a, b, null);
+
+                        return new Long(
+                            DTIType.limitNanoseconds * interval.getSeconds()
+                            + interval.getNanos());
+
+                    case Tokens.SQL_TSI_SECOND :
+                        t = Type.SQL_INTERVAL_SECOND_MAX_PRECISION;
+
+                        return new Long(t.convertToLong(t.subtract(a, b,
+                                null)));
+
+                    case Tokens.SQL_TSI_MINUTE :
+                        t = Type.SQL_INTERVAL_MINUTE_MAX_PRECISION;
+
+                        return new Long(t.convertToLong(t.subtract(a, b,
+                                null)));
+
+                    case Tokens.SQL_TSI_HOUR :
+                        t = Type.SQL_INTERVAL_HOUR_MAX_PRECISION;
+
+                        return new Long(t.convertToLong(t.subtract(a, b,
+                                null)));
+
+                    case Tokens.SQL_TSI_DAY :
+                        t = Type.SQL_INTERVAL_DAY_MAX_PRECISION;
+
+                        return new Long(t.convertToLong(t.subtract(a, b,
+                                null)));
+
+                    case Tokens.SQL_TSI_WEEK :
+                        t = Type.SQL_INTERVAL_DAY_MAX_PRECISION;
+
+                        return new Long(t.convertToLong(t.subtract(a, b, null))
+                                        / 7);
+
+                    case Tokens.SQL_TSI_MONTH :
+                        t = Type.SQL_INTERVAL_MONTH_MAX_PRECISION;
+
+                        return new Long(t.convertToLong(t.subtract(a, b,
+                                null)));
+
+                    case Tokens.SQL_TSI_QUARTER :
+                        t = Type.SQL_INTERVAL_MONTH_MAX_PRECISION;
+
+                        return new Long(t.convertToLong(t.subtract(a, b, null))
+                                        / 3);
+
+                    case Tokens.SQL_TSI_YEAR :
+                        t = Type.SQL_INTERVAL_YEAR_MAX_PRECISION;
+
+                        return new Long(t.convertToLong(t.subtract(a, b,
+                                null)));
+
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "FunctionCustom");
+                }
+            }
+            case FUNC_SECONDS_MIDNIGHT : {
+                if (data[0] == null) {
+                    return null;
+                }
+            }
+
+            // fall through
+            case FUNC_TRUNCATE : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                data[1] = Type.SQL_INTEGER.convertToType(session, data[1],
+                        nodes[1].getDataType());
+
+                return ((NumberType) dataType).truncate(data[0],
+                        ((Number) data[1]).intValue());
+            }
+            case FUNC_TO_CHAR : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                SimpleDateFormat format = session.getSimpleDateFormatGMT();
+                String javaPattern =
+                    HsqlDateTime.toJavaDatePattern((String) data[1]);
+
+                try {
+                    format.applyPattern(javaPattern);
+                } catch (Exception e) {
+                    throw Error.error(ErrorCode.X_22511);
+                }
+
+                Date date =
+                    (Date) ((DateTimeType) nodes[0].dataType)
+                        .convertSQLToJavaGMT(session, data[0]);
+
+                return format.format(date);
+            }
+            case FUNC_TIMESTAMP : {
+                boolean unary = nodes[1] == null;
+
+                if (data[0] == null) {
+                    return null;
+                }
+
+                if (unary) {
+                    return Type.SQL_TIMESTAMP.convertToType(session, data[0],
+                            nodes[0].dataType);
+                }
+
+                if (data[1] == null) {
+                    return null;
+                }
+
+                TimestampData date =
+                    (TimestampData) Type.SQL_DATE.convertToType(session,
+                        data[0], nodes[0].dataType);
+                TimeData time = (TimeData) Type.SQL_TIME.convertToType(session,
+                    data[1], nodes[1].dataType);
+
+                return new TimestampData(date.getSeconds()
+                                         + time.getSeconds(), time.getNanos());
+            }
+            case FUNC_PI :
+                return new Double(Math.PI);
+
+            case FUNC_RAND : {
+                if (nodes[0] == null) {
+                    return new Double(session.random());
+                } else {
+                    data[0] = Type.SQL_BIGINT.convertToType(session, data[0],
+                            nodes[0].getDataType());
+
+                    long seed = ((Number) data[0]).longValue();
+
+                    return new Double(session.random(seed));
+                }
+            }
+            case FUNC_ACOS : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.acos(d));
+            }
+            case FUNC_ASIN : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.asin(d));
+            }
+            case FUNC_ATAN : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.atan(d));
+            }
+            case FUNC_COS : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.cos(d));
+            }
+            case FUNC_COT : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+                double c = 1.0 / java.lang.Math.tan(d);
+
+                return new Double(c);
+            }
+            case FUNC_DEGREES : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.toDegrees(d));
+            }
+            case FUNC_SIN : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.sin(d));
+            }
+            case FUNC_TAN : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.tan(d));
+            }
+            case FUNC_LOG10 : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.log10(d));
+            }
+            case FUNC_RADIANS : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+
+                return new Double(java.lang.Math.toRadians(d));
+            }
+
+            //
+            case FUNC_SIGN : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                int val =
+                    ((NumberType) nodes[0].dataType).compareToZero(data[0]);
+
+                return ValuePool.getInt(val);
+            }
+            case FUNC_ATAN2 : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double a = NumberType.toDouble(data[0]);
+                double b = NumberType.toDouble(data[1]);
+
+                return new Double(java.lang.Math.atan2(a, b));
+            }
+            case FUNC_ASCII : {
+                String arg;
+
+                if (data[0] == null) {
+                    return null;
+                }
+
+                if (nodes[0].dataType.isLobType()) {
+                    arg = ((ClobData) data[0]).getSubString(session, 0, 1);
+                } else {
+                    arg = (String) data[0];
+                }
+
+                if (arg.length() == 0) {
+                    return null;
+                }
+
+                return ValuePool.getInt(arg.charAt(0));
+            }
+            case FUNC_CHAR :
+                if (data[0] == null) {
+                    return null;
+                }
+
+                data[0] = Type.SQL_INTEGER.convertToType(session, data[0],
+                        nodes[0].getDataType());
+
+                int arg = ((Number) data[0]).intValue();
+
+                if (Character.isValidCodePoint(arg)
+                        && Character.isValidCodePoint((char) arg)) {
+                    return String.valueOf((char) arg);
+                }
+
+                throw Error.error(ErrorCode.X_22511);
+            case FUNC_ROUNDMAGIC :
+            case FUNC_ROUND : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                double d = NumberType.toDouble(data[0]);
+                int    e = ((Number) data[1]).intValue();
+                double f = Math.pow(10., e);
+
+                return new Double(Math.round(d * f) / f);
+            }
+            case FUNC_SOUNDEX : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                String s = (String) data[0];
+
+                return new String(soundex(s), 0, 4);
+            }
+            case FUNC_BITAND :
+            case FUNC_BITOR :
+            case FUNC_BITXOR : {
+                for (int i = 0; i < data.length; i++) {
+                    if (data[i] == null) {
+                        return null;
+                    }
+                }
+
+                if (nodes[0].dataType.isIntegralType()) {
+                    data[0] = Type.SQL_BIGINT.convertToType(session, data[0],
+                            nodes[0].getDataType());
+                    data[1] = Type.SQL_BIGINT.convertToType(session, data[1],
+                            nodes[1].getDataType());
+
+                    long v = 0;
+                    long a = ((Number) data[0]).longValue();
+                    long b = ((Number) data[1]).longValue();
+
+                    switch (funcType) {
+
+                        case FUNC_BITAND :
+                            v = a & b;
+                            break;
+
+                        case FUNC_BITOR :
+                            v = a | b;
+                            break;
+
+                        case FUNC_BITXOR :
+                            v = a ^ b;
+                            break;
+                    }
+
+                    switch (dataType.typeCode) {
+
+                        case Types.SQL_NUMERIC :
+                        case Types.SQL_DECIMAL :
+                            return BigDecimal.valueOf(v);
+
+                        case Types.SQL_BIGINT :
+                            return ValuePool.getLong(v);
+
+                        case Types.SQL_INTEGER :
+                            return ValuePool.getInt((int) v);
+
+                        case Types.SQL_SMALLINT :
+                            return ValuePool.getInt((int) v & 0xffff);
+
+                        case Types.TINYINT :
+                            return ValuePool.getInt((int) v & 0xff);
+
+                        default :
+                            throw Error.error(ErrorCode.X_42561);
+                    }
+                } else {
+                    byte[] a = ((BinaryData) data[0]).getBytes();
+                    byte[] b = ((BinaryData) data[1]).getBytes();
+                    byte[] v;
+
+                    switch (funcType) {
+
+                        case FUNC_BITAND :
+                            v = BitMap.and(a, b);
+                            break;
+
+                        case FUNC_BITOR :
+                            v = BitMap.or(a, b);
+                            break;
+
+                        case FUNC_BITXOR :
+                            v = BitMap.xor(a, b);
+                            break;
+
+                        default :
+                            throw Error.error(ErrorCode.X_42561);
+                    }
+
+                    return new BinaryData(v, dataType.precision);
+                }
+            }
+            case FUNC_DIFFERENCE : {
+                for (int i = 0; i < data.length; i++) {
+                    if (data[i] == null) {
+                        return null;
+                    }
+                }
+
+                char[] s1 = soundex((String) data[0]);
+                char[] s2 = soundex((String) data[1]);
+                int    e  = 0;
+
+                if (s1[0] == s2[0]) {
+                    e++;
+                }
+
+                if (e == 4) {
+                    return ValuePool.getInt(e);
+                }
+
+                int js = 1;
+
+                for (int i = 1; i < 4; i++) {
+                    for (int j = js; j < 4; j++) {
+                        if (s1[j] == s2[i]) {
+                            e++;
+                            i++;
+                            js++;
+                        }
+                    }
+                }
+
+                e = 0;
+
+                return ValuePool.getInt(e);
+            }
+            case FUNC_HEXTORAW : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                return dataType.convertToType(session, data[0],
+                                              nodes[0].dataType);
+            }
+            case FUNC_RAWTOHEX : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                return nodes[0].dataType.convertToString(data[0]);
+            }
+            case FUNC_REPEAT : {
+                for (int i = 0; i < data.length; i++) {
+                    if (data[i] == null) {
+                        return null;
+                    }
+                }
+
+                data[1] = Type.SQL_INTEGER.convertToType(session, data[1],
+                        nodes[1].getDataType());
+
+                String       string = (String) data[0];
+                int          i      = ((Number) data[1]).intValue();
+                StringBuffer sb     = new StringBuffer(string.length() * i);
+
+                while (i-- > 0) {
+                    sb.append(string);
+                }
+
+                return sb.toString();
+            }
+            case FUNC_REPLACE : {
+                for (int i = 0; i < data.length; i++) {
+                    if (data[i] == null) {
+                        return null;
+                    }
+                }
+
+                String       string  = (String) data[0];
+                String       find    = (String) data[1];
+                String       replace = (String) data[2];
+                StringBuffer sb      = new StringBuffer();
+                int          start   = 0;
+
+                while (true) {
+                    int i = string.indexOf(find, start);
+
+                    if (i == -1) {
+                        sb.append(string.substring(start));
+
+                        break;
+                    }
+
+                    sb.append(string.substring(start, i));
+                    sb.append(replace);
+
+                    start = i + find.length();
+                }
+
+                return sb.toString();
+            }
+            case FUNC_LEFT :
+            case FUNC_RIGHT : {
+                for (int i = 0; i < data.length; i++) {
+                    if (data[i] == null) {
+                        return null;
+                    }
+                }
+
+                int count = ((Number) data[1]).intValue();
+
+                return ((CharacterType) dataType).substring(session, data[0],
+                        0, count, true, funcType == FUNC_RIGHT);
+            }
+            case FUNC_SPACE : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                data[0] = Type.SQL_INTEGER.convertToType(session, data[0],
+                        nodes[0].getDataType());
+
+                int    count = ((Number) data[0]).intValue();
+                char[] array = new char[count];
+
+                ArrayUtil.fillArray(array, 0, ' ');
+
+                return String.valueOf(array);
+            }
+            case FUNC_REVERSE : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                StringBuffer sb = new StringBuffer((String) data[0]);
+
+                sb = sb.reverse();
+
+                return sb.toString();
+            }
+            case FUNC_REGEXP_MATCHES : {
+                for (int i = 0; i < data.length; i++) {
+                    if (data[i] == null) {
+                        return null;
+                    }
+                }
+
+                if (!data[1].equals(matchPattern)) {
+                    matchPattern = (String) data[1];
+                    pattern      = Pattern.compile(matchPattern);
+                }
+
+                Matcher matcher = pattern.matcher((String) data[0]);
+
+                return matcher.matches() ? Boolean.TRUE
+                                         : Boolean.FALSE;
+            }
+            case FUNC_CRYPT_KEY : {
+                byte[] bytes = Crypto.getNewKey((String) data[0],
+                                                (String) data[1]);
+
+                return StringConverter.byteArrayToHexString(bytes);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "FunctionCustom");
+        }
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        switch (funcType) {
+
+            case FUNC_EXTRACT :
+            case FUNC_TRIM_CHAR :
+            case FUNC_OVERLAY_CHAR :
+                super.resolveTypes(session, parent);
+
+                return;
+
+            case FUNC_DATABASE :
+                dataType = Type.SQL_VARCHAR_DEFAULT;
+
+                return;
+
+            case FUNC_ISAUTOCOMMIT :
+            case FUNC_ISREADONLYSESSION :
+            case FUNC_ISREADONLYDATABASE :
+            case FUNC_ISREADONLYDATABASEFILES :
+                dataType = Type.SQL_BOOLEAN;
+
+                return;
+
+            case FUNC_ISOLATION_LEVEL :
+            case FUNC_SESSION_ISOLATION_LEVEL :
+            case FUNC_DATABASE_ISOLATION_LEVEL :
+            case FUNC_TRANSACTION_CONTROL :
+            case FUNC_DATABASE_VERSION :
+                dataType = Type.SQL_VARCHAR_DEFAULT;
+
+                return;
+
+            case FUNC_TIMEZONE :
+            case FUNC_SESSION_TIMEZONE :
+            case FUNC_DATABASE_TIMEZONE :
+                dataType = Type.SQL_INTERVAL_HOUR_TO_MINUTE;
+
+                return;
+
+            case FUNC_IDENTITY :
+                dataType = Type.SQL_BIGINT;
+
+                return;
+
+            case FUNC_DATEADD : {
+                int part;
+
+                if (!nodes[0].dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                if ("yy".equalsIgnoreCase((String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_YEAR;
+                } else if ("mm".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_MONTH;
+                } else if ("dd".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_DAY;
+                } else if ("hh".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_HOUR;
+                } else if ("mi".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_MINUTE;
+                } else if ("ss".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_SECOND;
+                } else if ("ms".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_FRAC_SECOND;
+                } else {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                nodes[0].valueData = ValuePool.getInt(part);
+                nodes[0].dataType  = Type.SQL_INTEGER;
+                funcType           = FUNC_TIMESTAMPADD;
+            }
+
+            // fall through
+            case FUNC_TIMESTAMPADD :
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_BIGINT;
+                }
+
+                if (nodes[2].dataType == null) {
+                    nodes[2].dataType = Type.SQL_TIMESTAMP;
+                }
+
+                if (!nodes[1].dataType.isIntegralType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                if (nodes[2].dataType.typeCode != Types.SQL_DATE
+                        && nodes[2].dataType.typeCode != Types.SQL_TIMESTAMP
+                        && nodes[2].dataType.typeCode
+                           != Types.SQL_TIMESTAMP_WITH_TIME_ZONE) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = nodes[2].dataType;
+
+                return;
+
+            case FUNC_DATEDIFF : {
+                int part;
+
+                if (!nodes[0].dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                if ("yy".equalsIgnoreCase((String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_YEAR;
+                } else if ("mm".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_MONTH;
+                } else if ("dd".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_DAY;
+                } else if ("hh".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_HOUR;
+                } else if ("mi".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_MINUTE;
+                } else if ("ss".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_SECOND;
+                } else if ("ms".equalsIgnoreCase(
+                        (String) nodes[0].valueData)) {
+                    part = Tokens.SQL_TSI_FRAC_SECOND;
+                } else {
+                    throw Error.error(ErrorCode.X_22511,
+                                      (String) nodes[0].valueData);
+                }
+
+                nodes[0].valueData = ValuePool.getInt(part);
+                nodes[0].dataType  = Type.SQL_INTEGER;
+                funcType           = FUNC_TIMESTAMPDIFF;
+            }
+
+            // fall through
+            case FUNC_TIMESTAMPDIFF : {
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = nodes[2].dataType;
+                }
+
+                if (nodes[2].dataType == null) {
+                    nodes[2].dataType = nodes[1].dataType;
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_TIMESTAMP;
+                    nodes[2].dataType = Type.SQL_TIMESTAMP;
+                }
+
+                switch (nodes[1].dataType.typeCode) {
+
+                    case Types.SQL_DATE :
+                        if (nodes[2].dataType.typeCode != Types.SQL_DATE) {
+                            throw Error.error(ErrorCode.X_42563);
+                        }
+
+                        switch (((Integer) nodes[0].valueData).intValue()) {
+
+                            case Tokens.SQL_TSI_DAY :
+                            case Tokens.SQL_TSI_WEEK :
+                            case Tokens.SQL_TSI_MONTH :
+                            case Tokens.SQL_TSI_QUARTER :
+                            case Tokens.SQL_TSI_YEAR :
+                                break;
+
+                            default :
+                                throw Error.error(ErrorCode.X_42563);
+                        }
+                        break;
+
+                    case Types.SQL_TIMESTAMP :
+                    case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                        if (nodes[2].dataType.typeCode != Types.SQL_TIMESTAMP
+                                && nodes[2].dataType.typeCode
+                                   != Types.SQL_TIMESTAMP_WITH_TIME_ZONE) {
+                            throw Error.error(ErrorCode.X_42563);
+                        }
+                        break;
+
+                    default :
+                        throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = Type.SQL_BIGINT;
+
+                return;
+            }
+            case FUNC_TRUNCATE : {
+                if (nodes[0].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_INTEGER;
+                } else if (!nodes[1].dataType.isIntegralType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                if (!nodes[0].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = nodes[0].dataType;
+
+                return;
+            }
+            case FUNC_TO_CHAR : {
+                if (nodes[0].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (nodes[1].dataType == null
+                        || !nodes[1].dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (!nodes[0].dataType.isExactNumberType()
+                        && !nodes[0].dataType.isDateTimeType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                // fixed maximum as format is a variable
+                dataType = CharacterType.getCharacterType(Types.SQL_VARCHAR,
+                        40);
+
+                if (nodes[1].opType == OpTypes.VALUE) {
+                    nodes[1].setAsConstantValue(session);
+                }
+
+                return;
+            }
+            case FUNC_TIMESTAMP : {
+                Type argType = nodes[0].dataType;
+
+                if (nodes[1] == null) {
+                    if (argType == null) {
+                        argType = nodes[0].dataType = Type.SQL_VARCHAR_DEFAULT;
+                    }
+
+                    if (argType.isCharacterType()
+                            || argType.typeCode == Types.SQL_TIMESTAMP
+                            || argType.typeCode
+                               == Types.SQL_TIMESTAMP_WITH_TIME_ZONE) {}
+                    else {
+                        throw Error.error(ErrorCode.X_42561);
+                    }
+                } else {
+                    if (argType == null) {
+                        if (nodes[1].dataType == null) {
+                            argType = nodes[0].dataType = nodes[1].dataType =
+                                Type.SQL_VARCHAR_DEFAULT;
+                        } else {
+                            if (nodes[1].dataType.isCharacterType()) {
+                                argType = nodes[0].dataType =
+                                    Type.SQL_VARCHAR_DEFAULT;
+                            } else {
+                                argType = nodes[0].dataType = Type.SQL_DATE;
+                            }
+                        }
+                    }
+
+                    if (nodes[1].dataType == null) {
+                        if (argType.isCharacterType()) {
+                            nodes[1].dataType = Type.SQL_VARCHAR_DEFAULT;
+                        } else if (argType.typeCode == Types.SQL_DATE) {
+                            nodes[1].dataType = Type.SQL_TIME;
+                        }
+                    }
+
+                    if ((argType.typeCode == Types.SQL_DATE && nodes[1]
+                            .dataType.typeCode == Types.SQL_TIME) || argType
+                                .isCharacterType() && nodes[1].dataType
+                                .isCharacterType()) {}
+                    else {
+                        throw Error.error(ErrorCode.X_42561);
+                    }
+                }
+
+                dataType = Type.SQL_TIMESTAMP;
+
+                return;
+            }
+            case FUNC_PI :
+                dataType = Type.SQL_DOUBLE;
+                break;
+
+            case FUNC_RAND : {
+                if (nodes[0] != null) {
+                    if (nodes[0].dataType == null) {
+                        nodes[0].dataType = Type.SQL_BIGINT;
+                    } else if (!nodes[0].dataType.isExactNumberType()) {
+                        throw Error.error(ErrorCode.X_42563);
+                    }
+                }
+
+                dataType = Type.SQL_DOUBLE;
+
+                break;
+            }
+            case FUNC_ROUND :
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_INTEGER;
+                }
+
+                if (!nodes[1].dataType.isExactNumberType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+            // fall through
+            case FUNC_ACOS :
+            case FUNC_ASIN :
+            case FUNC_ATAN :
+            case FUNC_COS :
+            case FUNC_COT :
+            case FUNC_DEGREES :
+            case FUNC_SIN :
+            case FUNC_TAN :
+            case FUNC_LOG10 :
+            case FUNC_RADIANS :
+            case FUNC_ROUNDMAGIC : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_DOUBLE;
+                }
+
+                if (!nodes[0].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = Type.SQL_DOUBLE;
+
+                break;
+            }
+            case FUNC_SIGN : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_DOUBLE;
+                }
+
+                if (!nodes[0].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = Type.SQL_INTEGER;
+
+                break;
+            }
+            case FUNC_ATAN2 : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_DOUBLE;
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_DOUBLE;
+                }
+
+                if (!nodes[0].dataType.isNumberType()
+                        || !nodes[1].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = Type.SQL_DOUBLE;
+
+                break;
+            }
+            case FUNC_SOUNDEX : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR;
+                }
+
+                if (!nodes[0].dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = Type.getType(Types.SQL_VARCHAR, 0, 4, 0);
+
+                break;
+            }
+            case FUNC_BITAND :
+            case FUNC_BITOR :
+            case FUNC_BITXOR : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = nodes[1].dataType;
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = nodes[0].dataType;
+                }
+
+                for (int i = 0; i < nodes.length; i++) {
+                    if (nodes[i].dataType == null) {
+                        nodes[i].dataType = Type.SQL_INTEGER;
+                    }
+                }
+
+                dataType =
+                    nodes[0].dataType.getAggregateType(nodes[1].dataType);
+
+                switch (dataType.typeCode) {
+
+                    case Types.SQL_BIGINT :
+                    case Types.SQL_INTEGER :
+                    case Types.SQL_SMALLINT :
+                    case Types.TINYINT :
+                        break;
+
+                    case Types.SQL_BIT :
+                    case Types.SQL_BIT_VARYING :
+                        break;
+
+                    default :
+                        throw Error.error(ErrorCode.X_42561);
+                }
+
+                break;
+            }
+            case FUNC_ASCII : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR;
+                }
+
+                if (!nodes[0].dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = Type.SQL_INTEGER;
+
+                break;
+            }
+            case FUNC_CHAR : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_INTEGER;
+                }
+
+                if (!nodes[0].dataType.isExactNumberType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = Type.getType(Types.SQL_VARCHAR, 0, 1, 0);
+
+                break;
+            }
+            case FUNC_DIFFERENCE : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR;
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_VARCHAR;
+                }
+
+                dataType = Type.SQL_INTEGER;
+
+                break;
+            }
+            case FUNC_HEXTORAW : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR;
+                }
+
+                if (!nodes[0].dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = nodes[0].dataType.precision == 0
+                           ? Type.SQL_VARBINARY_DEFAULT
+                           : Type.getType(Types.SQL_VARBINARY, 0,
+                                          nodes[0].dataType.precision / 2, 0);
+
+                break;
+            }
+            case FUNC_RAWTOHEX : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARBINARY;
+                }
+
+                if (!nodes[0].dataType.isBinaryType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = nodes[0].dataType.precision == 0
+                           ? Type.SQL_VARCHAR_DEFAULT
+                           : Type.getType(Types.SQL_VARCHAR, 0,
+                                          nodes[0].dataType.precision * 2, 0);
+
+                break;
+            }
+            case FUNC_REPEAT : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR;
+                }
+
+                boolean isChar = nodes[0].dataType.isCharacterType();
+
+                if (!isChar && !nodes[0].dataType.isBinaryType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                if (!nodes[1].dataType.isExactNumberType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = isChar ? (Type) Type.SQL_VARCHAR_DEFAULT
+                                  : (Type) Type.SQL_VARBINARY_DEFAULT;
+
+                break;
+            }
+            case FUNC_REPLACE : {
+                for (int i = 0; i < nodes.length; i++) {
+                    if (nodes[i].dataType == null) {
+                        nodes[i].dataType = Type.SQL_VARCHAR;
+                    } else if (!nodes[i].dataType.isCharacterType()) {
+                        throw Error.error(ErrorCode.X_42561);
+                    }
+                }
+
+                dataType = Type.SQL_VARCHAR_DEFAULT;
+
+                break;
+            }
+            case FUNC_LEFT :
+            case FUNC_RIGHT :
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR;
+                }
+
+                if (!nodes[0].dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_INTEGER;
+                }
+
+                if (!nodes[1].dataType.isExactNumberType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = nodes[0].dataType.precision == 0
+                           ? Type.SQL_VARCHAR_DEFAULT
+                           : Type.getType(Types.SQL_VARCHAR, 0,
+                                          nodes[0].dataType.precision, 0);
+                break;
+
+            case FUNC_SPACE :
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_INTEGER;
+                }
+
+                if (!nodes[0].dataType.isIntegralType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = Type.SQL_VARCHAR_DEFAULT;
+                break;
+
+            case FUNC_REVERSE :
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR_DEFAULT;
+                }
+
+                dataType = nodes[0].dataType;
+
+                if (!dataType.isCharacterType() || dataType.isLobType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+                break;
+
+            case FUNC_REGEXP_MATCHES :
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR_DEFAULT;
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_VARCHAR_DEFAULT;
+                }
+
+                if (!nodes[0].dataType.isCharacterType()
+                        || !nodes[1].dataType.isCharacterType()
+                        || nodes[1].dataType.isLobType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                dataType = Type.SQL_BOOLEAN;
+                break;
+
+            case FUNC_CRYPT_KEY :
+                for (int i = 0; i < nodes.length; i++) {
+                    if (nodes[i].dataType == null) {
+                        nodes[i].dataType = Type.SQL_VARCHAR;
+                    } else if (!nodes[i].dataType.isCharacterType()) {
+                        throw Error.error(ErrorCode.X_42561);
+                    }
+                }
+
+                dataType = Type.SQL_VARCHAR_DEFAULT;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "FunctionCustom");
+        }
+    }
+
+    public String getSQL() {
+
+        switch (funcType) {
+
+            case FUNC_EXTRACT :
+            case FUNC_TRIM_CHAR :
+            case FUNC_OVERLAY_CHAR :
+                return super.getSQL();
+
+            case FUNC_DATABASE :
+            case FUNC_ISAUTOCOMMIT :
+            case FUNC_ISREADONLYSESSION :
+            case FUNC_ISREADONLYDATABASE :
+            case FUNC_ISREADONLYDATABASEFILES :
+            case FUNC_ISOLATION_LEVEL :
+            case FUNC_SESSION_ISOLATION_LEVEL :
+            case FUNC_DATABASE_ISOLATION_LEVEL :
+            case FUNC_TRANSACTION_CONTROL :
+            case FUNC_TIMEZONE :
+            case FUNC_SESSION_TIMEZONE :
+            case FUNC_DATABASE_TIMEZONE :
+            case FUNC_DATABASE_VERSION :
+            case FUNC_PI :
+            case FUNC_IDENTITY :
+                return new StringBuffer(name).append(
+                    Tokens.T_OPENBRACKET).append(
+                    Tokens.T_CLOSEBRACKET).toString();
+
+            case FUNC_TIMESTAMPADD : {
+                String token = Tokens.getSQLTSIString(
+                    ((Number) nodes[0].getValue(null)).intValue());
+
+                return new StringBuffer(Tokens.T_TIMESTAMPADD).append(
+                    Tokens.T_OPENBRACKET).append(token)                  //
+                    .append(Tokens.T_COMMA).append(nodes[1].getSQL())    //
+                    .append(Tokens.T_COMMA).append(nodes[2].getSQL())    //
+                    .append(Tokens.T_CLOSEBRACKET).toString();
+            }
+            case FUNC_TIMESTAMPDIFF : {
+                String token = Tokens.getSQLTSIString(
+                    ((Number) nodes[0].getValue(null)).intValue());
+
+                return new StringBuffer(Tokens.T_TIMESTAMPDIFF).append(
+                    Tokens.T_OPENBRACKET).append(token)                  //
+                    .append(Tokens.T_COMMA).append(nodes[1].getSQL())    //
+                    .append(Tokens.T_COMMA).append(nodes[2].getSQL())    //
+                    .append(Tokens.T_CLOSEBRACKET).toString();
+            }
+            case FUNC_RAND : {
+                StringBuffer sb = new StringBuffer(name).append('(');
+
+                if (nodes[0] != null) {
+                    sb.append(nodes[0].getSQL());
+                }
+
+                sb.append(')');
+
+                return sb.toString();
+            }
+            case FUNC_ASCII :
+            case FUNC_ACOS :
+            case FUNC_ASIN :
+            case FUNC_ATAN :
+            case FUNC_CHAR :
+            case FUNC_COS :
+            case FUNC_COT :
+            case FUNC_DEGREES :
+            case FUNC_SIN :
+            case FUNC_TAN :
+            case FUNC_LOG10 :
+            case FUNC_RADIANS :
+            case FUNC_ROUNDMAGIC :
+            case FUNC_SIGN :
+            case FUNC_SOUNDEX :
+            case FUNC_SPACE :
+            case FUNC_REVERSE :
+            case FUNC_HEXTORAW :
+            case FUNC_RAWTOHEX : {
+                return new StringBuffer(name).append('(')                //
+                    .append(nodes[0].getSQL()).append(')').toString();
+            }
+            case FUNC_ATAN2 :
+            case FUNC_BITAND :
+            case FUNC_BITOR :
+            case FUNC_BITXOR :
+            case FUNC_DIFFERENCE :
+            case FUNC_REPEAT :
+            case FUNC_LEFT :
+            case FUNC_RIGHT :
+            case FUNC_ROUND :
+            case FUNC_CRYPT_KEY :
+            case FUNC_TRUNCATE :
+            case FUNC_TIMESTAMP :
+            case FUNC_TO_CHAR :
+            case FUNC_REGEXP_MATCHES : {
+                return new StringBuffer(name).append('(')                //
+                    .append(nodes[0].getSQL()).append(Tokens.T_COMMA)    //
+                    .append(nodes[1].getSQL()).append(')').toString();
+            }
+            case FUNC_REPLACE : {
+                return new StringBuffer(name).append('(')                //
+                    .append(nodes[0].getSQL()).append(Tokens.T_COMMA)    //
+                    .append(nodes[1].getSQL()).append(Tokens.T_COMMA)    //
+                    .append(nodes[2].getSQL()).append(')').toString();
+            }
+            default :
+                return super.getSQL();
+        }
+    }
+
+    /**
+     * Returns a four character code representing the sound of the given
+     * <code>String</code>. Non-ASCCI characters in the
+     * input <code>String</code> are ignored. <p>
+     *
+     * This method was rewritten for HSQLDB to comply with the description at
+     * <a href="http://www.archives.gov/genealogy/census/soundex.html">
+     * http://www.archives.gov/genealogy/census/soundex.html </a>.<p>
+     * @param s the <code>String</code> for which to calculate the 4 character
+     *      <code>SOUNDEX</code> value
+     * @return the 4 character <code>SOUNDEX</code> value for the given
+     *      <code>String</code>
+     */
+    public static char[] soundex(String s) {
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.toUpperCase(Locale.ENGLISH);
+
+        int    len       = s.length();
+        char[] b         = new char[] {
+            '0', '0', '0', '0'
+        };
+        char   lastdigit = '0';
+
+        for (int i = 0, j = 0; i < len && j < 4; i++) {
+            char c = s.charAt(i);
+            char newdigit;
+
+            if ("AEIOUY".indexOf(c) != -1) {
+                newdigit = '7';
+            } else if (c == 'H' || c == 'W') {
+                newdigit = '8';
+            } else if ("BFPV".indexOf(c) != -1) {
+                newdigit = '1';
+            } else if ("CGJKQSXZ".indexOf(c) != -1) {
+                newdigit = '2';
+            } else if (c == 'D' || c == 'T') {
+                newdigit = '3';
+            } else if (c == 'L') {
+                newdigit = '4';
+            } else if (c == 'M' || c == 'N') {
+                newdigit = '5';
+            } else if (c == 'R') {
+                newdigit = '6';
+            } else {
+                continue;
+            }
+
+            if (j == 0) {
+                b[j++]    = c;
+                lastdigit = newdigit;
+            } else if (newdigit <= '6') {
+                if (newdigit != lastdigit) {
+                    b[j++]    = newdigit;
+                    lastdigit = newdigit;
+                }
+            } else if (newdigit == '7') {
+                lastdigit = newdigit;
+            }
+        }
+
+        return b;
+    }
+}
diff --git a/src/org/hsqldb/FunctionSQL.java b/src/org/hsqldb/FunctionSQL.java
new file mode 100644
index 0000000..7977105
--- /dev/null
+++ b/src/org/hsqldb/FunctionSQL.java
@@ -0,0 +1,1990 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BinaryType;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.DTIType;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of SQL standard function calls
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class FunctionSQL extends Expression {
+
+    protected final static int FUNC_POSITION_CHAR                    = 1;     // numeric
+    private final static int   FUNC_POSITION_BINARY                  = 2;
+    private final static int   FUNC_OCCURENCES_REGEX                 = 3;
+    private final static int   FUNC_POSITION_REGEX                   = 4;
+    protected final static int FUNC_EXTRACT                          = 5;
+    protected final static int FUNC_BIT_LENGTH                       = 6;
+    protected final static int FUNC_CHAR_LENGTH                      = 7;
+    protected final static int FUNC_OCTET_LENGTH                     = 8;
+    private final static int   FUNC_CARDINALITY                      = 9;
+    private final static int   FUNC_MAX_CARDINALITY                  = 10;
+    private final static int   FUNC_TRIM_ARRAY                       = 11;
+    private final static int   FUNC_ABS                              = 12;
+    private final static int   FUNC_MOD                              = 13;
+    protected final static int FUNC_LN                               = 14;
+    private final static int   FUNC_EXP                              = 15;
+    private final static int   FUNC_POWER                            = 16;
+    private final static int   FUNC_SQRT                             = 17;
+    private final static int   FUNC_FLOOR                            = 20;
+    private final static int   FUNC_CEILING                          = 21;
+    private final static int   FUNC_WIDTH_BUCKET                     = 22;
+    protected final static int FUNC_SUBSTRING_CHAR                   = 23;    // string
+    private final static int   FUNC_SUBSTRING_REG_EXPR               = 24;
+    private final static int   FUNC_SUBSTRING_REGEX                  = 25;
+    protected final static int FUNC_FOLD_LOWER                       = 26;
+    protected final static int FUNC_FOLD_UPPER                       = 27;
+    private final static int   FUNC_TRANSCODING                      = 28;
+    private final static int   FUNC_TRANSLITERATION                  = 29;
+    private final static int   FUNC_REGEX_TRANSLITERATION            = 30;
+    protected final static int FUNC_TRIM_CHAR                        = 31;
+    final static int           FUNC_OVERLAY_CHAR                     = 32;
+    private final static int   FUNC_CHAR_NORMALIZE                   = 33;
+    private final static int   FUNC_SUBSTRING_BINARY                 = 40;
+    private final static int   FUNC_TRIM_BINARY                      = 41;
+    private final static int   FUNC_OVERLAY_BINARY                   = 42;
+    protected final static int FUNC_CURRENT_DATE                     = 43;    // datetime
+    protected final static int FUNC_CURRENT_TIME                     = 44;
+    protected final static int FUNC_CURRENT_TIMESTAMP                = 50;
+    protected final static int FUNC_LOCALTIME                        = 51;
+    protected final static int FUNC_LOCALTIMESTAMP                   = 52;
+    private final static int   FUNC_CURRENT_CATALOG                  = 53;    // general
+    private final static int   FUNC_CURRENT_DEFAULT_TRANSFORM_GROUP  = 54;
+    private final static int   FUNC_CURRENT_PATH                     = 55;
+    private final static int   FUNC_CURRENT_ROLE                     = 56;
+    private final static int   FUNC_CURRENT_SCHEMA                   = 57;
+    private final static int   FUNC_CURRENT_TRANSFORM_GROUP_FOR_TYPE = 58;
+    private final static int   FUNC_CURRENT_USER                     = 59;
+    private final static int   FUNC_SESSION_USER                     = 60;
+    private final static int   FUNC_SYSTEM_USER                      = 61;
+    protected final static int FUNC_USER                             = 62;
+    private final static int   FUNC_VALUE                            = 63;
+
+    //
+    static final short[] noParamList             = new short[]{};
+    static final short[] emptyParamList          = new short[] {
+        Tokens.OPENBRACKET, Tokens.CLOSEBRACKET
+    };
+    static final short[] optionalNoParamList     = new short[] {
+        Tokens.X_OPTION, 2, Tokens.OPENBRACKET, Tokens.CLOSEBRACKET
+    };
+    static final short[] optionalSingleParamList = new short[] {
+        Tokens.OPENBRACKET, Tokens.X_OPTION, 1, Tokens.QUESTION,
+        Tokens.CLOSEBRACKET
+    };
+    static final short[] singleParamList          = new short[] {
+        Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.CLOSEBRACKET
+    };
+    static final short[] optionalIntegerParamList = new short[] {
+        Tokens.X_OPTION, 3, Tokens.OPENBRACKET, Tokens.X_POS_INTEGER,
+        Tokens.CLOSEBRACKET
+    };
+    static final short[] doubleParamList = new short[] {
+        Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.COMMA, Tokens.QUESTION,
+        Tokens.CLOSEBRACKET
+    };
+    static final short[] tripleParamList = new short[] {
+        Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.COMMA, Tokens.QUESTION,
+        Tokens.COMMA, Tokens.QUESTION, Tokens.CLOSEBRACKET
+    };
+    static final short[] quadParamList = new short[] {
+        Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.COMMA, Tokens.QUESTION,
+        Tokens.COMMA, Tokens.QUESTION, Tokens.COMMA, Tokens.QUESTION,
+        Tokens.CLOSEBRACKET
+    };
+
+    //
+    static IntValueHashMap   valueFuncMap            = new IntValueHashMap();
+    static IntValueHashMap   regularFuncMap          = new IntValueHashMap();
+    static OrderedIntHashSet nonDeterministicFuncSet = new OrderedIntHashSet();
+
+    static {
+        regularFuncMap.put(Tokens.T_POSITION, FUNC_POSITION_CHAR);
+        /*
+        regularFuncMap.put(Token.T_OCCURENCES_REGEX, FUNC_OCCURENCES_REGEX);
+        */
+        regularFuncMap.put(Tokens.T_POSITION_REGEX, FUNC_POSITION_REGEX);
+        regularFuncMap.put(Tokens.T_EXTRACT, FUNC_EXTRACT);
+        regularFuncMap.put(Tokens.T_BIT_LENGTH, FUNC_BIT_LENGTH);
+        regularFuncMap.put(Tokens.T_CHAR_LENGTH, FUNC_CHAR_LENGTH);
+        regularFuncMap.put(Tokens.T_CHARACTER_LENGTH, FUNC_CHAR_LENGTH);
+        regularFuncMap.put(Tokens.T_OCTET_LENGTH, FUNC_OCTET_LENGTH);
+        regularFuncMap.put(Tokens.T_CARDINALITY, FUNC_CARDINALITY);
+        regularFuncMap.put(Tokens.T_MAX_CARDINALITY, FUNC_MAX_CARDINALITY);
+        regularFuncMap.put(Tokens.T_TRIM_ARRAY, FUNC_TRIM_ARRAY);
+        regularFuncMap.put(Tokens.T_ABS, FUNC_ABS);
+        regularFuncMap.put(Tokens.T_MOD, FUNC_MOD);
+        regularFuncMap.put(Tokens.T_LN, FUNC_LN);
+        regularFuncMap.put(Tokens.T_EXP, FUNC_EXP);
+        regularFuncMap.put(Tokens.T_POWER, FUNC_POWER);
+        regularFuncMap.put(Tokens.T_SQRT, FUNC_SQRT);
+        regularFuncMap.put(Tokens.T_FLOOR, FUNC_FLOOR);
+        regularFuncMap.put(Tokens.T_CEILING, FUNC_CEILING);
+        regularFuncMap.put(Tokens.T_CEIL, FUNC_CEILING);
+        regularFuncMap.put(Tokens.T_WIDTH_BUCKET, FUNC_WIDTH_BUCKET);
+        regularFuncMap.put(Tokens.T_SUBSTRING, FUNC_SUBSTRING_CHAR);
+        /*
+        regularFuncMap.put(Token.T_SUBSTRING_REG_EXPR,
+                           FUNC_SUBSTRING_REG_EXPR);
+        */
+        regularFuncMap.put(Tokens.T_SUBSTRING_REGEX, FUNC_SUBSTRING_REGEX);
+        regularFuncMap.put(Tokens.T_LOWER, FUNC_FOLD_LOWER);
+        regularFuncMap.put(Tokens.T_UPPER, FUNC_FOLD_UPPER);
+        /*
+        regularFuncMap.put(Token.T_TRANSCODING, FUNC_TRANSCODING);
+        regularFuncMap.put(Token.T_TRANSLITERATION, FUNC_TRANSLITERATION);
+        regularFuncMap.put(Token.T_TRASLATION,
+                           FUNC_REGEX_TRANSLITERATION);
+        */
+        regularFuncMap.put(Tokens.T_TRIM, FUNC_TRIM_CHAR);
+        regularFuncMap.put(Tokens.T_OVERLAY, FUNC_OVERLAY_CHAR);
+        /*
+        regularFuncMap.put(Token.T_NORMALIZE, FUNC_CHAR_NORMALIZE);
+        */
+        regularFuncMap.put(Tokens.T_TRIM, FUNC_TRIM_BINARY);
+    }
+
+    static {
+        valueFuncMap.put(Tokens.T_CURRENT_DATE, FUNC_CURRENT_DATE);
+        valueFuncMap.put(Tokens.T_CURRENT_TIME, FUNC_CURRENT_TIME);
+        valueFuncMap.put(Tokens.T_CURRENT_TIMESTAMP, FUNC_CURRENT_TIMESTAMP);
+        valueFuncMap.put(Tokens.T_LOCALTIME, FUNC_LOCALTIME);
+        valueFuncMap.put(Tokens.T_LOCALTIMESTAMP, FUNC_LOCALTIMESTAMP);
+        valueFuncMap.put(Tokens.T_CURRENT_CATALOG, FUNC_CURRENT_CATALOG);
+        /*
+        valueFuncMap.put(Token.T_CURRENT_DEFAULT_TRANSFORM_GROUP,
+                FUNC_CURRENT_DEFAULT_TRANSFORM_GROUP);
+        */
+        valueFuncMap.put(Tokens.T_CURRENT_PATH, FUNC_CURRENT_PATH);
+        valueFuncMap.put(Tokens.T_CURRENT_ROLE, FUNC_CURRENT_ROLE);
+        valueFuncMap.put(Tokens.T_CURRENT_SCHEMA, FUNC_CURRENT_SCHEMA);
+        /*
+        valueFuncMap.put(Token.T_CURRENT_TRANSFORM_GROUP_FOR_TYPE,
+                FUNC_CURRENT_TRANSFORM_GROUP_FOR_TYPE);
+        */
+        valueFuncMap.put(Tokens.T_CURRENT_USER, FUNC_CURRENT_USER);
+        valueFuncMap.put(Tokens.T_SESSION_USER, FUNC_SESSION_USER);
+        valueFuncMap.put(Tokens.T_SYSTEM_USER, FUNC_SYSTEM_USER);
+        valueFuncMap.put(Tokens.T_USER, FUNC_USER);
+        valueFuncMap.put(Tokens.T_VALUE, FUNC_VALUE);
+
+        //
+        nonDeterministicFuncSet.addAll(valueFuncMap.values());
+    }
+
+    //
+    int     funcType;
+    boolean isDeterministic;
+    String  name;
+    short[] parseList;
+    short[] parseListAlt;
+    boolean isSQLValueFunction;
+
+    public static FunctionSQL newSQLFunction(String token,
+            CompileContext context) {
+
+        int     id              = regularFuncMap.get(token, -1);
+        boolean isValueFunction = false;
+
+        if (id == -1) {
+            id              = valueFuncMap.get(token, -1);
+            isValueFunction = true;
+        }
+
+        if (id == -1) {
+            return null;
+        }
+
+        FunctionSQL function = new FunctionSQL(id);
+
+        if (id == FUNC_VALUE) {
+            if (context.currentDomain == null) {
+                return null;
+            }
+
+            function.dataType = context.currentDomain;
+        } else {
+            function.isSQLValueFunction = isValueFunction;
+        }
+
+        return function;
+    }
+
+    protected FunctionSQL() {
+
+        super(OpTypes.SQL_FUNCTION);
+
+        nodes = Expression.emptyArray;
+    }
+
+    protected FunctionSQL(int id) {
+
+        this();
+
+        this.funcType   = id;
+        isDeterministic = !nonDeterministicFuncSet.contains(id);
+
+        switch (id) {
+
+            case FUNC_POSITION_CHAR :
+            case FUNC_POSITION_BINARY :
+                name      = Tokens.T_POSITION;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.IN,
+                    Tokens.QUESTION, Tokens.X_OPTION, 5, Tokens.USING,
+                    Tokens.X_KEYSET, 2, Tokens.CHARACTERS, Tokens.OCTETS,
+                    Tokens.CLOSEBRACKET
+                };
+                break;
+
+            case FUNC_OCCURENCES_REGEX :
+            case FUNC_POSITION_REGEX :
+                break;
+
+            case FUNC_EXTRACT :
+                name      = Tokens.T_EXTRACT;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.X_KEYSET, 17, Tokens.YEAR,
+                    Tokens.MONTH, Tokens.DAY, Tokens.HOUR, Tokens.MINUTE,
+                    Tokens.SECOND, Tokens.DAY_OF_WEEK, Tokens.WEEK_OF_YEAR,
+                    Tokens.QUARTER, Tokens.DAY_OF_YEAR, Tokens.DAY_OF_MONTH,
+                    Tokens.WEEK_OF_YEAR, Tokens.DAY_NAME, Tokens.MONTH_NAME,
+                    Tokens.SECONDS_MIDNIGHT, Tokens.TIMEZONE_HOUR,
+                    Tokens.TIMEZONE_MINUTE, Tokens.FROM, Tokens.QUESTION,
+                    Tokens.CLOSEBRACKET
+                };
+                break;
+
+            case FUNC_CHAR_LENGTH :
+                name      = Tokens.T_CHAR_LENGTH;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.X_OPTION, 5,
+                    Tokens.USING, Tokens.X_KEYSET, 2, Tokens.CHARACTERS,
+                    Tokens.OCTETS, Tokens.CLOSEBRACKET
+                };
+                break;
+
+            case FUNC_BIT_LENGTH :
+                name      = Tokens.T_BIT_LENGTH;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_OCTET_LENGTH :
+                name      = Tokens.T_OCTET_LENGTH;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_CARDINALITY :
+                name      = Tokens.T_CARDINALITY;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_MAX_CARDINALITY :
+                name      = Tokens.T_MAX_CARDINALITY;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_TRIM_ARRAY :
+                name      = Tokens.T_TRIM_ARRAY;
+                parseList = doubleParamList;
+                break;
+
+            case FUNC_ABS :
+                name      = Tokens.T_ABS;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_MOD :
+                name      = Tokens.T_MOD;
+                parseList = doubleParamList;
+                break;
+
+            case FUNC_LN :
+                name      = Tokens.T_LN;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_EXP :
+                name      = Tokens.T_EXP;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_POWER :
+                name      = Tokens.T_POWER;
+                parseList = doubleParamList;
+                break;
+
+            case FUNC_SQRT :
+                name      = Tokens.T_SQRT;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_FLOOR :
+                name      = Tokens.T_FLOOR;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_CEILING :
+                name      = Tokens.T_CEILING;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_WIDTH_BUCKET :
+                name      = Tokens.T_WIDTH_BUCKET;
+                parseList = quadParamList;
+                break;
+
+            case FUNC_SUBSTRING_CHAR :
+            case FUNC_SUBSTRING_BINARY :
+                name      = Tokens.T_SUBSTRING;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.FROM,
+                    Tokens.QUESTION, Tokens.X_OPTION, 2, Tokens.FOR,
+                    Tokens.QUESTION, Tokens.X_OPTION, 5, Tokens.USING,
+                    Tokens.X_KEYSET, 2, Tokens.CHARACTERS, Tokens.OCTETS,
+                    Tokens.CLOSEBRACKET
+                };
+                parseListAlt = new short[] {
+                    Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.COMMA,
+                    Tokens.QUESTION, Tokens.X_OPTION, 2, Tokens.COMMA,
+                    Tokens.QUESTION, Tokens.CLOSEBRACKET
+                };
+                break;
+
+            /*
+            case FUNCTION_SUBSTRING_REG_EXPR :
+                break;
+            case FUNCTION_SUBSTRING_REGEX :
+                break;
+            */
+            case FUNC_FOLD_LOWER :
+                name      = Tokens.T_LOWER;
+                parseList = singleParamList;
+                break;
+
+            case FUNC_FOLD_UPPER :
+                name      = Tokens.T_UPPER;
+                parseList = singleParamList;
+                break;
+
+            /*
+            case FUNCTION_TRANSCODING :
+                break;
+            case FUNCTION_TRANSLITERATION :
+                break;
+            case FUNCTION_REGEX_TRANSLITERATION :
+                break;
+             */
+            case FUNC_TRIM_CHAR :
+            case FUNC_TRIM_BINARY :
+                name      = Tokens.T_TRIM;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.X_OPTION, 11,    //
+                    Tokens.X_OPTION, 5,                         //
+                    Tokens.X_KEYSET, 3, Tokens.LEADING, Tokens.TRAILING,
+                    Tokens.BOTH,                                //
+                    Tokens.X_OPTION, 1, Tokens.QUESTION,        //
+                    Tokens.FROM, Tokens.QUESTION, Tokens.CLOSEBRACKET
+                };
+                break;
+
+            /*
+            case FUNCTION_CHAR_NORMALIZE :
+                break;
+            */
+            case FUNC_OVERLAY_CHAR :
+            case FUNC_OVERLAY_BINARY :
+                name      = Tokens.T_OVERLAY;
+                parseList = new short[] {
+                    Tokens.OPENBRACKET, Tokens.QUESTION, Tokens.PLACING,
+                    Tokens.QUESTION, Tokens.FROM, Tokens.QUESTION,
+                    Tokens.X_OPTION, 2, Tokens.FOR, Tokens.QUESTION,
+                    Tokens.X_OPTION, 2, Tokens.USING, Tokens.CHARACTERS,
+                    Tokens.CLOSEBRACKET
+                };
+                break;
+
+            case FUNC_CURRENT_CATALOG :
+                name      = Tokens.T_CURRENT_CATALOG;
+                parseList = noParamList;
+                break;
+
+            /*
+            case FUNC_CURRENT_DEFAULT_TRANSFORM_GROUP :
+                break;
+            case FUNC_CURRENT_PATH :
+                break;
+            */
+            case FUNC_CURRENT_ROLE :
+                name      = Tokens.T_CURRENT_ROLE;
+                parseList = noParamList;
+                break;
+
+            case FUNC_CURRENT_SCHEMA :
+                name      = Tokens.T_CURRENT_SCHEMA;
+                parseList = noParamList;
+                break;
+
+            /*
+            case FUNC_CURRENT_TRANSFORM_GROUP_FOR_TYPE :
+                break;
+            */
+            case FUNC_CURRENT_USER :
+                name      = Tokens.T_CURRENT_USER;
+                parseList = noParamList;
+                break;
+
+            case FUNC_SESSION_USER :
+                name      = Tokens.T_SESSION_USER;
+                parseList = noParamList;
+                break;
+
+            case FUNC_SYSTEM_USER :
+                name      = Tokens.T_SYSTEM_USER;
+                parseList = noParamList;
+                break;
+
+            case FUNC_USER :
+                name      = Tokens.T_USER;
+                parseList = optionalNoParamList;
+                break;
+
+            case FUNC_VALUE :
+                name      = Tokens.T_VALUE;
+                parseList = noParamList;
+                break;
+
+            case FUNC_CURRENT_DATE :
+                name      = Tokens.T_CURRENT_DATE;
+                parseList = noParamList;
+                break;
+
+            case FUNC_CURRENT_TIME :
+                name      = Tokens.T_CURRENT_TIME;
+                parseList = optionalIntegerParamList;
+                break;
+
+            case FUNC_CURRENT_TIMESTAMP :
+                name      = Tokens.T_CURRENT_TIMESTAMP;
+                parseList = optionalIntegerParamList;
+                break;
+
+            case FUNC_LOCALTIME :
+                name      = Tokens.T_LOCALTIME;
+                parseList = optionalIntegerParamList;
+                break;
+
+            case FUNC_LOCALTIMESTAMP :
+                name      = Tokens.T_LOCALTIMESTAMP;
+                parseList = optionalIntegerParamList;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "FunctionSQL");
+        }
+    }
+
+    public void setArguments(Expression[] newNodes) {
+        this.nodes = newNodes;
+    }
+
+    public Expression getFunctionExpression() {
+        return this;
+    }
+
+    /**
+     * Evaluates and returns this Function in the context of the session.<p>
+     */
+    public Object getValue(Session session) {
+
+        Object[] data = new Object[nodes.length];
+
+        for (int i = 0; i < nodes.length; i++) {
+            Expression e = nodes[i];
+
+            if (e != null) {
+                data[i] = e.getValue(session, e.dataType);
+            }
+        }
+
+        return getValue(session, data);
+    }
+
+    Object getValue(Session session, Object[] data) {
+
+        switch (funcType) {
+
+            case FUNC_POSITION_CHAR : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                long result =
+                    ((CharacterType) nodes[1].dataType).position(
+                        session, data[1], data[0], nodes[0].dataType, 0) + 1;
+
+                if (nodes[2] != null
+                        && ((Number) nodes[2].valueData).intValue()
+                           == Tokens.OCTETS) {
+                    result *= 2;
+                }
+
+                return ValuePool.getLong(result);
+            }
+            case FUNC_POSITION_BINARY : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                long result =
+                    ((BinaryType) nodes[1].dataType).position(
+                        session, (BlobData) data[1], (BlobData) data[0],
+                        nodes[0].dataType, 0) + 1;
+
+                if (nodes[2] != null
+                        && ((Number) nodes[2].valueData).intValue()
+                           == Tokens.OCTETS) {
+                    result *= 2;
+                }
+
+                return ValuePool.getLong(result);
+            }
+            /*
+            case FUNC_OCCURENCES_REGEX :
+            case FUNC_POSITION_REGEX :
+            */
+            case FUNC_EXTRACT : {
+                if (data[1] == null) {
+                    return null;
+                }
+
+                int part = ((Number) nodes[0].valueData).intValue();
+
+                part = DTIType.getFieldNameTypeForToken(part);
+
+                switch (part) {
+
+                    case Types.SQL_INTERVAL_SECOND : {
+                        return ((DTIType) nodes[1].dataType).getSecondPart(
+                            data[1]);
+                    }
+                    case DTIType.MONTH_NAME :
+                    case DTIType.DAY_NAME : {
+                        return ((DateTimeType) nodes[1].dataType)
+                            .getPartString(session, data[1], part);
+                    }
+                    default : {
+                        int value =
+                            ((DTIType) nodes[1].dataType).getPart(session,
+                                data[1], part);
+
+                        return ValuePool.getInt(value);
+                    }
+                }
+            }
+            case FUNC_CHAR_LENGTH : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                long result = ((CharacterType) nodes[0].dataType).size(session,
+                    data[0]);
+
+                return ValuePool.getLong(result);
+            }
+            case FUNC_BIT_LENGTH : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                long result;
+
+                if (nodes[0].dataType.isBinaryType()) {
+                    result = ((BlobData) data[0]).bitLength(session);
+                } else {
+                    result =
+                        16 * ((CharacterType) nodes[0].dataType).size(session,
+                            data[0]);
+                }
+
+                return ValuePool.getLong(result);
+            }
+            case FUNC_OCTET_LENGTH : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                long result;
+
+                if (nodes[0].dataType.isBinaryType()) {
+                    result = ((BlobData) data[0]).length(session);
+                } else {
+                    result =
+                        2 * ((CharacterType) nodes[0].dataType).size(session,
+                            data[0]);
+                }
+
+                return ValuePool.getLong(result);
+            }
+            case FUNC_CARDINALITY : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                int result = nodes[0].dataType.cardinality(session, data[0]);
+
+                return ValuePool.getInt(result);
+            }
+            case FUNC_MAX_CARDINALITY : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                int result = nodes[0].dataType.arrayLimitCardinality();
+
+                return ValuePool.getInt(result);
+            }
+            case FUNC_TRIM_ARRAY : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                if (data[1] == null) {
+                    return null;
+                }
+
+                Object[] array  = (Object[]) data[0];
+                int      length = ((Number) data[1]).intValue();
+
+                if (length < 0 || length > array.length) {
+                    throw Error.error(ErrorCode.X_2202E);
+                }
+
+                Object[] newArray = new Object[array.length - length];
+
+                System.arraycopy(array, 0, newArray, 0, newArray.length);
+
+                return newArray;
+            }
+            case FUNC_ABS : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                return dataType.absolute(data[0]);
+            }
+            case FUNC_MOD : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                // result type is the same as nodes[1]
+                return ((NumberType) dataType).modulo(data[0], data[1],
+                                                      nodes[0].dataType);
+            }
+            case FUNC_LN : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double d = ((Number) data[0]).doubleValue();
+
+                if (d <= 0) {
+                    throw Error.error(ErrorCode.X_2201E);
+                }
+
+                d = Math.log(d);
+
+                return ValuePool.getDouble(Double.doubleToLongBits(d));
+            }
+            case FUNC_EXP : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double val = Math.exp(((Number) data[0]).doubleValue());
+
+                return ValuePool.getDouble(Double.doubleToLongBits(val));
+            }
+            case FUNC_POWER : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                double base     = ((Number) data[0]).doubleValue();
+                double exponent = ((Number) data[1]).doubleValue();
+                double val;
+
+                if (exponent < 0) {
+                    throw Error.error(ErrorCode.X_2201F);
+                }
+
+                if (base == 0) {
+                    if (exponent < 0) {
+                        throw Error.error(ErrorCode.X_2201F);
+                    } else if (exponent == 0) {
+                        val = 1;
+                    } else {
+                        val = 0;
+                    }
+                } else {
+                    val = Math.pow(base, exponent);
+                }
+
+                return ValuePool.getDouble(Double.doubleToLongBits(val));
+            }
+            case FUNC_SQRT : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                double val = Math.sqrt(((Number) data[0]).doubleValue());
+
+                return ValuePool.getDouble(Double.doubleToLongBits(val));
+            }
+            case FUNC_FLOOR : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                return ((NumberType) dataType).floor(data[0]);
+            }
+            case FUNC_CEILING : {
+                if (data[0] == null) {
+                    return null;
+                }
+
+                return ((NumberType) dataType).ceiling(data[0]);
+            }
+            case FUNC_WIDTH_BUCKET : {
+                return null;
+            }
+            case FUNC_SUBSTRING_CHAR : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                Object value;
+
+                value = Type.SQL_BIGINT.convertToType(session, data[1],
+                                                      nodes[1].dataType);
+
+                long offset = ((Number) value).longValue() - 1;
+                long length = 0;
+
+                if (nodes[2] != null) {
+                    if (data[2] == null) {
+                        return null;
+                    }
+
+                    value = Type.SQL_BIGINT.convertToType(session, data[2],
+                                                          nodes[2].dataType);
+                    length = ((Number) value).longValue();
+                }
+
+                if (nodes.length > 3 && nodes[3] != null
+                        && ((Number) nodes[2].valueData).intValue()
+                           == Tokens.OCTETS) {
+
+                    // not clear what the rules on USING OCTECTS are with UTF
+                }
+
+                return ((CharacterType) dataType).substring(session, data[0],
+                        offset, length, nodes[2] != null, false);
+            }
+            /*
+            case FUNCTION_SUBSTRING_REG_EXPR :
+                break;
+            case FUNCTION_SUBSTRING_REGEX :
+                break;
+            */
+            case FUNC_FOLD_LOWER :
+                if (data[0] == null) {
+                    return null;
+                }
+
+                return ((CharacterType) dataType).lower(session, data[0]);
+
+            case FUNC_FOLD_UPPER :
+                if (data[0] == null) {
+                    return null;
+                }
+
+                return ((CharacterType) dataType).upper(session, data[0]);
+
+            /*
+            case FUNCTION_TRANSCODING :
+                break;
+            case FUNCTION_TRANSLITERATION :
+                break;
+            case FUNCTION_REGEX_TRANSLITERATION :
+                break;
+             */
+            case FUNC_TRIM_CHAR : {
+                if (data[1] == null || data[2] == null) {
+                    return null;
+                }
+
+                boolean leading  = false;
+                boolean trailing = false;
+
+                switch (((Number) nodes[0].valueData).intValue()) {
+
+                    case Tokens.BOTH :
+                        leading = trailing = true;
+                        break;
+
+                    case Tokens.LEADING :
+                        leading = true;
+                        break;
+
+                    case Tokens.TRAILING :
+                        trailing = true;
+                        break;
+
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "FunctionSQL");
+                }
+
+                String string = (String) data[1];
+
+                if (string.length() != 1) {
+                    throw Error.error(ErrorCode.X_22027);
+                }
+
+                int character = string.charAt(0);
+
+                return ((CharacterType) dataType).trim(session, data[2],
+                                                       character, leading,
+                                                       trailing);
+            }
+            case FUNC_OVERLAY_CHAR : {
+                if (data[0] == null || data[1] == null || data[2] == null) {
+                    return null;
+                }
+
+                Object value;
+
+                value = Type.SQL_BIGINT.convertToType(session, data[2],
+                                                      nodes[2].dataType);
+
+                long offset = ((Number) value).longValue() - 1;
+                long length = 0;
+
+                if (nodes[3] != null) {
+                    if (data[3] == null) {
+                        return null;
+                    }
+
+                    value = Type.SQL_BIGINT.convertToType(session, data[3],
+                                                          nodes[3].dataType);
+                    length = ((Number) value).longValue();
+                }
+
+                return ((CharacterType) dataType).overlay(null, data[0],
+                        data[1], offset, length, nodes[3] != null);
+            }
+            /*
+            case FUNCTION_CHAR_NORMALIZE :
+                break;
+            */
+            case FUNC_SUBSTRING_BINARY : {
+                if (data[0] == null || data[1] == null) {
+                    return null;
+                }
+
+                Object value;
+
+                value = Type.SQL_BIGINT.convertToType(session, data[1],
+                                                      nodes[1].dataType);
+
+                long offset = ((Number) value).longValue() - 1;
+                long length = 0;
+
+                if (nodes[2] != null) {
+                    if (data[2] == null) {
+                        return null;
+                    }
+
+                    value = Type.SQL_BIGINT.convertToType(session, data[2],
+                                                          nodes[2].dataType);
+                    length = ((Number) value).intValue();
+                }
+
+                return ((BinaryType) dataType).substring(session,
+                        (BlobData) data[0], offset, length, nodes[2] != null);
+            }
+            case FUNC_TRIM_BINARY : {
+                if (data[1] == null || data[2] == null) {
+                    return null;
+                }
+
+                boolean leading  = false;
+                boolean trailing = false;
+                int     spec     = ((Number) nodes[0].valueData).intValue();
+
+                switch (spec) {
+
+                    case Tokens.BOTH :
+                        leading = trailing = true;
+                        break;
+
+                    case Tokens.LEADING :
+                        leading = true;
+                        break;
+
+                    case Tokens.TRAILING :
+                        trailing = true;
+                        break;
+
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "FunctionSQL");
+                }
+
+                BlobData string = (BlobData) data[1];
+
+                if (string.length(session) != 1) {
+                    throw Error.error(ErrorCode.X_22027);
+                }
+
+                byte[] bytes = string.getBytes();
+
+                return ((BinaryType) dataType).trim(session,
+                                                    (BlobData) data[3],
+                                                    bytes[0], leading,
+                                                    trailing);
+            }
+            case FUNC_OVERLAY_BINARY : {
+                if (data[0] == null || data[1] == null || data[2] == null) {
+                    return null;
+                }
+
+                Object value;
+
+                value = Type.SQL_BIGINT.convertToType(session, data[2],
+                                                      nodes[2].dataType);
+
+                long offset = ((Number) value).longValue() - 1;
+                long length = 0;
+
+                if (nodes[3] != null) {
+                    if (data[3] == null) {
+                        return null;
+                    }
+
+                    value = Type.SQL_BIGINT.convertToType(session, data[3],
+                                                          nodes[3].dataType);
+                    length = ((Number) value).longValue();
+                }
+
+                return ((BinaryType) dataType).overlay(session,
+                                                       (BlobData) data[0],
+                                                       (BlobData) data[1],
+                                                       offset, length,
+                                                       nodes[3] != null);
+            }
+            case FUNC_CURRENT_CATALOG :
+                return session.database.getCatalogName().name;
+
+            /*
+            case FUNC_CURRENT_DEFAULT_TRANSFORM_GROUP :
+            case FUNC_CURRENT_PATH :
+            */
+            case FUNC_CURRENT_ROLE :
+                return session.getRole() == null ? null
+                                                 : session.getRole()
+                                                     .getNameString();
+
+            case FUNC_CURRENT_SCHEMA :
+                return session.getCurrentSchemaHsqlName().name;
+
+            /*
+            case FUNC_CURRENT_TRANSFORM_GROUP_FOR_TYPE :
+            */
+            case FUNC_CURRENT_USER :
+                return session.getUser().getNameString();
+
+            case FUNC_SESSION_USER :
+                return session.getUser().getNameString();
+
+            case FUNC_SYSTEM_USER :
+                return session.getUser().getNameString();
+
+            case FUNC_USER :
+                return session.getUser().getNameString();
+
+            case FUNC_VALUE :
+                return session.sessionData.currentValue;
+
+            case FUNC_CURRENT_DATE :
+                return session.getCurrentDate();
+
+            case FUNC_CURRENT_TIME :
+                return dataType.convertToTypeLimits(
+                    session, session.getCurrentTime(true));
+
+            case FUNC_CURRENT_TIMESTAMP :
+                return dataType.convertToTypeLimits(
+                    session, session.getCurrentTimestamp(true));
+
+            case FUNC_LOCALTIME :
+                return dataType.convertToTypeLimits(
+                    session, session.getCurrentTime(false));
+
+            case FUNC_LOCALTIMESTAMP :
+                return dataType.convertToTypeLimits(
+                    session, session.getCurrentTimestamp(false));
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "FunctionSQL");
+        }
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] != null) {
+                nodes[i].resolveTypes(session, this);
+            }
+        }
+
+        switch (funcType) {
+
+            case FUNC_POSITION_CHAR :
+            case FUNC_POSITION_BINARY : {
+                if (nodes[0].dataType == null) {
+                    if (nodes[1].dataType == null) {
+                        throw Error.error(ErrorCode.X_42567);
+                    }
+
+                    if (nodes[1].dataType.typeCode == Types.SQL_CLOB
+                            || nodes[1].dataType.isBinaryType()) {
+                        nodes[0].dataType = nodes[1].dataType;
+                    } else {
+                        nodes[0].dataType = Type.SQL_VARCHAR;
+                    }
+                }
+
+                if (nodes[1].dataType == null) {
+                    if (nodes[0].dataType.typeCode == Types.SQL_CLOB
+                            || nodes[0].dataType.isBinaryType()) {
+                        nodes[1].dataType = nodes[0].dataType;
+                    } else {
+                        nodes[1].dataType = Type.SQL_VARCHAR;
+                    }
+                }
+
+                if (nodes[0].dataType.isCharacterType()
+                        && nodes[1].dataType.isCharacterType()) {
+                    funcType = FUNC_POSITION_CHAR;
+                } else if (nodes[0].dataType.isBinaryType()
+                           && nodes[1].dataType.isBinaryType()) {
+                    if (nodes[0].dataType.isBitType()
+                            || nodes[1].dataType.isBitType()) {
+                        throw Error.error(ErrorCode.X_42563);
+                    }
+
+                    funcType = FUNC_POSITION_BINARY;
+                } else {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = Type.SQL_BIGINT;
+
+                break;
+            }
+            /*
+            case FUNC_OCCURENCES_REGEX :
+            case FUNC_POSITION_REGEX :
+            */
+            case FUNC_EXTRACT : {
+                if (nodes[1].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (!nodes[1].dataType.isDateTimeType()
+                        && !nodes[1].dataType.isIntervalType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                int     part = ((Number) nodes[0].valueData).intValue();
+                DTIType type = (DTIType) nodes[1].dataType;
+
+                part     = DTIType.getFieldNameTypeForToken(part);
+                dataType = type.getExtractType(part);
+
+                break;
+            }
+            case FUNC_BIT_LENGTH : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_BIT_VARYING_MAX_LENGTH;
+                }
+
+                if (!nodes[0].dataType.isCharacterType()
+                        && !nodes[0].dataType.isBinaryType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = Type.SQL_BIGINT;
+
+                break;
+            }
+            case FUNC_CHAR_LENGTH :
+                if (!nodes[0].dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+            // fall through
+            case FUNC_OCTET_LENGTH : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR;
+                }
+
+                if (!nodes[0].dataType.isCharacterType()
+                        && !nodes[0].dataType.isBinaryType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = Type.SQL_BIGINT;
+
+                break;
+            }
+            case FUNC_CARDINALITY : {
+                if (nodes[0].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (!nodes[0].dataType.isArrayType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = Type.SQL_INTEGER;
+
+                break;
+            }
+            case FUNC_MAX_CARDINALITY : {
+                if (nodes[0].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (!nodes[0].dataType.isArrayType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = Type.SQL_INTEGER;
+
+                break;
+            }
+            case FUNC_TRIM_ARRAY : {
+                if (nodes[0].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (!nodes[0].dataType.isArrayType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_INTEGER;
+                }
+
+                if (!nodes[1].dataType.isIntegralType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = nodes[0].dataType;
+
+                break;
+            }
+            case FUNC_MOD : {
+                if (nodes[0].dataType == null) {
+                    nodes[1].dataType = nodes[0].dataType;
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[0].dataType = nodes[1].dataType;
+                }
+
+                if (nodes[0].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (!nodes[0].dataType.isNumberType()
+                        || !nodes[1].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                nodes[0].dataType =
+                    ((NumberType) nodes[0].dataType).getIntegralType();
+                nodes[1].dataType =
+                    ((NumberType) nodes[1].dataType).getIntegralType();
+                dataType = nodes[1].dataType;
+
+                break;
+            }
+            case FUNC_POWER : {
+                if (nodes[0].dataType == null) {
+                    nodes[1].dataType = nodes[0].dataType;
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[0].dataType = nodes[1].dataType;
+                }
+
+                if (nodes[0].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (!nodes[0].dataType.isNumberType()
+                        || !nodes[1].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                nodes[0].dataType = Type.SQL_DOUBLE;
+                nodes[1].dataType = Type.SQL_DOUBLE;
+                dataType          = Type.SQL_DOUBLE;
+
+                break;
+            }
+            case FUNC_LN :
+            case FUNC_EXP :
+            case FUNC_SQRT : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_DOUBLE;
+                }
+
+                if (!nodes[0].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                nodes[0].dataType = Type.SQL_DOUBLE;
+                dataType          = Type.SQL_DOUBLE;
+
+                break;
+            }
+            case FUNC_ABS :
+                if (nodes[0].dataType != null
+                        && nodes[0].dataType.isIntervalType()) {
+                    dataType = nodes[0].dataType;
+
+                    break;
+                }
+
+            // fall through
+            case FUNC_FLOOR :
+            case FUNC_CEILING : {
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_DOUBLE;
+                }
+
+                if (!nodes[0].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = nodes[0].dataType;
+
+                if (dataType.typeCode == Types.SQL_DECIMAL
+                        || dataType.typeCode == Types.SQL_NUMERIC) {
+                    if (dataType.scale > 0) {
+                        dataType = NumberType.getNumberType(dataType.typeCode,
+                                                            dataType.precision
+                                                            + 1, 0);
+                    }
+                }
+
+                break;
+            }
+            case FUNC_WIDTH_BUCKET : {
+                if (nodes[0].dataType == null || nodes[1].dataType == null
+                        || nodes[2].dataType == null
+                        || nodes[3].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (!nodes[0].dataType.isNumberType()
+                        || !nodes[1].dataType.isNumberType()
+                        || !nodes[2].dataType.isNumberType()
+                        || !nodes[3].dataType.isIntegralType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                dataType = nodes[3].dataType;
+
+                break;
+            }
+            case FUNC_SUBSTRING_CHAR :
+            case FUNC_SUBSTRING_BINARY : {
+                if (nodes[0].dataType == null) {
+
+                    // in 20.6 parameter not allowed as type cannot be determined as binary or char
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                if (nodes[1].dataType == null) {
+                    nodes[1].dataType = Type.SQL_NUMERIC;
+                }
+
+                if (!nodes[1].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                if (nodes[2] != null) {
+                    if (nodes[2].dataType == null) {
+                        nodes[2].dataType = Type.SQL_NUMERIC;
+                    }
+
+                    if (!nodes[2].dataType.isNumberType()) {
+                        throw Error.error(ErrorCode.X_42563);
+                    }
+
+                    nodes[2].dataType =
+                        ((NumberType) nodes[2].dataType).getIntegralType();
+                }
+
+                dataType = nodes[0].dataType;
+
+                if (dataType.isCharacterType()) {
+                    funcType = FUNC_SUBSTRING_CHAR;
+
+                    if (dataType.typeCode == Types.SQL_CHAR) {
+                        dataType =
+                            CharacterType.getCharacterType(Types.SQL_VARCHAR,
+                                                           dataType.precision);
+                    }
+                } else if (dataType.isBinaryType()) {
+                    funcType = FUNC_SUBSTRING_BINARY;
+                } else {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                if (nodes.length > 3 && nodes[3] != null) {
+
+                    // always boolean constant if defined
+                }
+
+                break;
+            }
+            /*
+            case FUNCTION_SUBSTRING_REG_EXPR :
+                break;
+            case FUNCTION_SUBSTRING_REGEX :
+                break;
+            */
+            case FUNC_FOLD_LOWER :
+            case FUNC_FOLD_UPPER :
+                if (nodes[0].dataType == null) {
+                    nodes[0].dataType = Type.SQL_VARCHAR_DEFAULT;
+                }
+
+                dataType = nodes[0].dataType;
+
+                if (!dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+                break;
+
+            /*
+            case FUNCTION_TRANSCODING :
+                break;
+            case FUNCTION_TRANSLITERATION :
+                break;
+            case FUNCTION_REGEX_TRANSLITERATION :
+                break;
+             */
+            case FUNC_TRIM_CHAR :
+            case FUNC_TRIM_BINARY :
+                if (nodes[0] == null) {
+                    nodes[0] =
+                        new ExpressionValue(ValuePool.getInt(Tokens.BOTH),
+                                            Type.SQL_INTEGER);
+                }
+
+                if (nodes[2].dataType == null) {
+                    throw Error.error(ErrorCode.X_42567);
+                }
+
+                dataType = nodes[2].dataType;
+
+                if (dataType.isCharacterType()) {
+                    funcType = FUNC_TRIM_CHAR;
+
+                    if (dataType.typeCode == Types.SQL_CHAR) {
+                        dataType =
+                            CharacterType.getCharacterType(Types.SQL_VARCHAR,
+                                                           dataType.precision);
+                    }
+
+                    if (nodes[1] == null) {
+                        nodes[1] = new ExpressionValue(" ", Type.SQL_CHAR);
+                    }
+                } else if (dataType.isBinaryType()) {
+                    funcType = FUNC_TRIM_BINARY;
+
+                    if (nodes[1] == null) {
+                        nodes[1] = new ExpressionValue(
+                            new BinaryData(new byte[]{ 0 }, false),
+                            Type.SQL_BINARY);
+                    }
+                } else {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+                break;
+
+            case FUNC_OVERLAY_CHAR :
+            case FUNC_OVERLAY_BINARY : {
+                if (nodes[0].dataType == null) {
+                    if (nodes[1].dataType == null) {
+                        throw Error.error(ErrorCode.X_42567);
+                    }
+
+                    if (nodes[1].dataType.typeCode == Types.SQL_CLOB
+                            || nodes[1].dataType.isBinaryType()) {
+                        nodes[0].dataType = nodes[1].dataType;
+                    } else {
+                        nodes[0].dataType = Type.SQL_VARCHAR;
+                    }
+                }
+
+                if (nodes[1].dataType == null) {
+                    if (nodes[0].dataType.typeCode == Types.SQL_CLOB
+                            || nodes[0].dataType.isBinaryType()) {
+                        nodes[1].dataType = nodes[0].dataType;
+                    } else {
+                        nodes[1].dataType = Type.SQL_VARCHAR;
+                    }
+                }
+
+                if (nodes[0].dataType.isCharacterType()
+                        && nodes[1].dataType.isCharacterType()) {
+                    funcType = FUNC_OVERLAY_CHAR;
+
+                    if (nodes[0].dataType.typeCode == Types.SQL_CLOB
+                            || nodes[1].dataType.typeCode == Types.SQL_CLOB) {
+                        dataType = CharacterType.getCharacterType(
+                            Types.SQL_CLOB,
+                            nodes[0].dataType.precision
+                            + nodes[1].dataType.precision);
+                    } else {
+                        dataType = CharacterType.getCharacterType(
+                            Types.SQL_VARCHAR,
+                            nodes[0].dataType.precision
+                            + nodes[1].dataType.precision);
+                    }
+                } else if (nodes[0].dataType.isBinaryType()
+                           && nodes[1].dataType.isBinaryType()) {
+                    funcType = FUNC_OVERLAY_BINARY;
+
+                    if (nodes[0].dataType.typeCode == Types.SQL_BLOB
+                            || nodes[1].dataType.typeCode == Types.SQL_BLOB) {
+                        dataType = BinaryType.getBinaryType(
+                            Types.SQL_BLOB,
+                            nodes[0].dataType.precision
+                            + nodes[1].dataType.precision);
+                    } else {
+                        dataType = BinaryType.getBinaryType(
+                            Types.SQL_VARBINARY,
+                            nodes[0].dataType.precision
+                            + nodes[1].dataType.precision);
+                    }
+                } else {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                if (nodes[2].dataType == null) {
+                    nodes[2].dataType = Type.SQL_NUMERIC;
+                }
+
+                if (!nodes[2].dataType.isNumberType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                nodes[2].dataType =
+                    ((NumberType) nodes[2].dataType).getIntegralType();
+
+                if (nodes[3] != null) {
+                    if (nodes[3].dataType == null) {
+                        nodes[3].dataType = Type.SQL_NUMERIC;
+                    }
+
+                    if (!nodes[3].dataType.isNumberType()) {
+                        throw Error.error(ErrorCode.X_42563);
+                    }
+
+                    nodes[3].dataType =
+                        ((NumberType) nodes[3].dataType).getIntegralType();
+                }
+
+                break;
+            }
+            /*
+            case FUNCTION_CHAR_NORMALIZE :
+                break;
+            */
+            case FUNC_CURRENT_CATALOG :
+            case FUNC_CURRENT_DEFAULT_TRANSFORM_GROUP :
+            case FUNC_CURRENT_PATH :
+            case FUNC_CURRENT_ROLE :
+            case FUNC_CURRENT_SCHEMA :
+            case FUNC_CURRENT_TRANSFORM_GROUP_FOR_TYPE :
+            case FUNC_CURRENT_USER :
+            case FUNC_SESSION_USER :
+            case FUNC_SYSTEM_USER :
+            case FUNC_USER :
+                dataType = SqlInvariants.SQL_IDENTIFIER;
+                break;
+
+            case FUNC_VALUE :
+                break;
+
+            case FUNC_CURRENT_DATE :
+                dataType = CharacterType.SQL_DATE;
+                break;
+
+            case FUNC_CURRENT_TIME : {
+                int precision = DateTimeType.defaultTimeFractionPrecision;
+
+                if (nodes[0] != null) {
+                    precision = ((Integer) nodes[0].valueData).intValue();
+                }
+
+                dataType =
+                    DateTimeType.getDateTimeType(Types.SQL_TIME_WITH_TIME_ZONE,
+                                                 precision);
+
+                break;
+            }
+            case FUNC_CURRENT_TIMESTAMP : {
+                int precision = DateTimeType.defaultTimestampFractionPrecision;
+
+                if (nodes.length > 0 && nodes[0] != null) {
+                    precision = ((Integer) nodes[0].valueData).intValue();
+                }
+
+                dataType = DateTimeType.getDateTimeType(
+                    Types.SQL_TIMESTAMP_WITH_TIME_ZONE, precision);
+
+                break;
+            }
+            case FUNC_LOCALTIME : {
+                int precision = DateTimeType.defaultTimeFractionPrecision;
+
+                if (nodes.length > 0 && nodes[0] != null) {
+                    precision = ((Integer) nodes[0].valueData).intValue();
+                }
+
+                dataType = DateTimeType.getDateTimeType(Types.SQL_TIME,
+                        precision);
+
+                break;
+            }
+            case FUNC_LOCALTIMESTAMP : {
+                int precision = DateTimeType.defaultTimestampFractionPrecision;
+
+                if (nodes.length > 0 && nodes[0] != null) {
+                    precision = ((Integer) nodes[0].valueData).intValue();
+                }
+
+                dataType = DateTimeType.getDateTimeType(Types.SQL_TIMESTAMP,
+                        precision);
+
+                break;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "FunctionSQL");
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        switch (funcType) {
+
+            case FUNC_POSITION_CHAR :
+            case FUNC_POSITION_BINARY : {
+                sb.append(Tokens.T_POSITION).append('(')                 //
+                    .append(nodes[0].getSQL()).append(' ')               //
+                    .append(Tokens.T_IN).append(' ')                     //
+                    .append(nodes[1].getSQL());
+
+                if (nodes[2] != null
+                        && Boolean.TRUE.equals(nodes[2].valueData)) {
+                    sb.append(' ').append(Tokens.T_USING).append(' ').append(
+                        Tokens.T_OCTETS);
+                }
+
+                sb.append(')');
+
+                break;
+            }
+            case FUNC_OCCURENCES_REGEX :
+                break;
+
+            case FUNC_POSITION_REGEX :
+                break;
+
+            case FUNC_EXTRACT : {
+                int type = ((Integer) nodes[0].valueData).intValue();
+
+                type = DTIType.getFieldNameTypeForToken(type);
+
+                String token = DTIType.getFieldNameTokenForType(type);
+
+                sb.append(Tokens.T_EXTRACT).append('(').append(token)    //
+                    .append(' ').append(Tokens.T_FROM).append(' ')       //
+                    .append(nodes[1].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_CHAR_LENGTH : {
+                sb.append(Tokens.T_CHAR_LENGTH).append('(')              //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_BIT_LENGTH : {
+                sb.append(Tokens.T_BIT_LENGTH).append('(')               //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_OCTET_LENGTH : {
+                sb.append(Tokens.T_OCTET_LENGTH).append('(')             //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_CARDINALITY : {
+                sb.append(Tokens.T_CARDINALITY).append('(')              //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_MAX_CARDINALITY : {
+                sb.append(Tokens.T_MAX_CARDINALITY).append('(')          //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_TRIM_ARRAY : {
+                sb.append(Tokens.T_TRIM_ARRAY).append('(')               //
+                    .append(nodes[0].getSQL()).append(',')               //
+                    .append(nodes[1].getSQL()).append(')');              //
+
+                break;
+            }
+            case FUNC_ABS : {
+                sb.append(Tokens.T_ABS).append('(')                      //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_MOD : {
+                sb.append(Tokens.T_MOD).append('(')                      //
+                    .append(nodes[0].getSQL()).append(',')               //
+                    .append(nodes[1].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_LN : {
+                sb.append(Tokens.T_LN).append('(')                       //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_EXP : {
+                sb.append(Tokens.T_EXP).append('(')                      //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_POWER : {
+                sb.append(Tokens.T_POWER).append('(')                    //
+                    .append(nodes[0].getSQL()).append(',')               //
+                    .append(nodes[1].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_SQRT : {
+                sb.append(Tokens.T_SQRT).append('(')                     //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_FLOOR : {
+                sb.append(Tokens.T_FLOOR).append('(')                    //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_CEILING : {
+                sb.append(Tokens.T_CEILING).append('(')                  //
+                    .append(nodes[0].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_WIDTH_BUCKET : {
+                sb.append(Tokens.T_WIDTH_BUCKET).append('(')             //
+                    .append(nodes[0].getSQL()).append(',')               //
+                    .append(nodes[1].getSQL()).append(',')               //
+                    .append(nodes[2].getSQL()).append(',')               //
+                    .append(nodes[3].getSQL()).append(')');
+
+                break;
+            }
+            case FUNC_SUBSTRING_CHAR :
+            case FUNC_SUBSTRING_BINARY :
+                sb.append(Tokens.T_SUBSTRING).append('(')                //
+                    .append(nodes[0].getSQL()).append(' ')               //
+                    .append(Tokens.T_FROM).append(' ')                   //
+                    .append(nodes[1].getSQL());
+
+                if (nodes[2] != null) {
+                    sb.append(' ').append(Tokens.T_FOR).append(' ')      //
+                        .append(nodes[2].getSQL());
+                }
+
+                if (nodes.length > 3 && nodes[3] != null) {
+                    if (Boolean.TRUE.equals(nodes[3].valueData)) {
+                        sb.append(' ').append(Tokens.T_USING).append(
+                            ' ').append(Tokens.T_OCTETS);
+                    }
+                }
+
+                sb.append(')');
+                break;
+
+            /*
+            case FUNCTION_SUBSTRING_REGEX :
+                break;
+            */
+            case FUNC_FOLD_LOWER :
+                sb.append(Tokens.T_LOWER).append('(').append(
+                    nodes[0].getSQL()).append(')');
+                break;
+
+            case FUNC_FOLD_UPPER :
+                sb.append(Tokens.T_UPPER).append('(').append(
+                    nodes[0].getSQL()).append(')');
+                break;
+
+            /*
+            case FUNCTION_TRANSCODING :
+                break;
+            case FUNCTION_TRANSLITERATION :
+                break;
+            case FUNCTION_REGEX_TRANSLITERATION :
+                break;
+             */
+            case FUNC_OVERLAY_CHAR :
+            case FUNC_OVERLAY_BINARY :
+                sb.append(Tokens.T_OVERLAY).append('(')                  //
+                    .append(nodes[0].getSQL()).append(' ')               //
+                    .append(Tokens.T_PLACING).append(' ')                //
+                    .append(nodes[1].getSQL()).append(' ')               //
+                    .append(Tokens.T_FROM).append(' ')                   //
+                    .append(nodes[2].getSQL());
+
+                if (nodes[3] != null) {
+                    sb.append(' ').append(Tokens.T_FOR).append(' ').append(
+                        nodes[3].getSQL());
+                }
+
+                if (nodes[4] != null) {
+                    if (Boolean.TRUE.equals(nodes[4].valueData)) {
+                        sb.append(' ').append(Tokens.T_USING).append(
+                            ' ').append(Tokens.T_OCTETS);
+                    }
+                }
+
+                sb.append(')');
+                break;
+
+            /*
+            case FUNCTION_NORMALIZE :
+                break;
+            */
+            case FUNC_TRIM_CHAR :
+            case FUNC_TRIM_BINARY :
+                String spec = null;
+
+                switch (((Number) nodes[0].valueData).intValue()) {
+
+                    case Tokens.BOTH :
+                        spec = Tokens.T_BOTH;
+                        break;
+
+                    case Tokens.LEADING :
+                        spec = Tokens.T_LEADING;
+                        break;
+
+                    case Tokens.TRAILING :
+                        spec = Tokens.T_TRAILING;
+                        break;
+                }
+
+                sb.append(Tokens.T_TRIM).append('(')                     //
+                    .append(spec).append(' ')                            //
+                    .append(nodes[1].getSQL()).append(' ')               //
+                    .append(Tokens.T_FROM).append(' ')                   //
+                    .append(nodes[2].getSQL()).append(')');
+                break;
+
+            case FUNC_CURRENT_CATALOG :
+            case FUNC_CURRENT_DEFAULT_TRANSFORM_GROUP :
+            case FUNC_CURRENT_PATH :
+            case FUNC_CURRENT_ROLE :
+            case FUNC_CURRENT_SCHEMA :
+            case FUNC_CURRENT_TRANSFORM_GROUP_FOR_TYPE :
+            case FUNC_CURRENT_USER :
+            case FUNC_SESSION_USER :
+            case FUNC_SYSTEM_USER :
+            case FUNC_USER :
+            case FUNC_CURRENT_DATE :
+            case FUNC_VALUE :
+                return name;
+
+            case FUNC_LOCALTIME :
+            case FUNC_CURRENT_TIME : {
+                int precision = DateTimeType.defaultTimeFractionPrecision;
+
+                if (nodes.length > 0 && nodes[0] != null) {
+                    precision = ((Number) nodes[0].valueData).intValue();
+                }
+
+                if (precision == DateTimeType.defaultTimeFractionPrecision) {
+                    return name;
+                }
+
+                sb.append(name).append(Tokens.T_OPENBRACKET).append(precision);
+                sb.append(Tokens.T_CLOSEBRACKET);
+
+                return sb.toString();
+            }
+            case FUNC_LOCALTIMESTAMP :
+            case FUNC_CURRENT_TIMESTAMP : {
+                int precision = DateTimeType.defaultTimestampFractionPrecision;
+
+                if (nodes.length > 0 && nodes[0] != null) {
+                    precision = ((Number) nodes[0].valueData).intValue();
+                }
+
+                if (precision
+                        == DateTimeType.defaultTimestampFractionPrecision) {
+                    return name;
+                }
+
+                sb.append(name).append(Tokens.T_OPENBRACKET).append(precision);
+                sb.append(Tokens.T_CLOSEBRACKET);
+
+                return sb.toString();
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "FunctionSQL");
+        }
+
+        return sb.toString();
+    }
+
+    public boolean equals(Object other) {
+
+        if (other instanceof FunctionSQL
+                && funcType == ((FunctionSQL) other).funcType) {
+            return super.equals(other);
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+        return opType + funcType;
+    }
+
+    /**
+     * Returns a String representation of this object. <p>
+     */
+    public String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        sb.append("FUNCTION ").append("=[\n");
+        sb.append(name).append("(");
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                continue;
+            }
+
+            sb.append("[").append(nodes[i].describe(session,
+                    blanks)).append("]");
+        }
+
+        sb.append(") returns ").append(dataType.getNameString());
+        sb.append("]\n");
+
+        return sb.toString();
+    }
+
+    public boolean isDeterministic() {
+        return isDeterministic;
+    }
+
+    public boolean isValueFunction() {
+        return isSQLValueFunction;
+    }
+}
diff --git a/src/org/hsqldb/FunctionSQLInvoked.java b/src/org/hsqldb/FunctionSQLInvoked.java
new file mode 100644
index 0000000..5f58e96
--- /dev/null
+++ b/src/org/hsqldb/FunctionSQLInvoked.java
@@ -0,0 +1,333 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayListIdentity;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.Set;
+import org.hsqldb.result.Result;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of SQL-invoked user-defined function calls - PSM and JRT
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class FunctionSQLInvoked extends Expression {
+
+    RoutineSchema routineSchema;
+    Routine       routine;
+
+    FunctionSQLInvoked(RoutineSchema routineSchema) {
+
+        super(routineSchema.isAggregate() ? OpTypes.USER_AGGREGATE
+                                          : OpTypes.FUNCTION);
+
+        this.routineSchema = routineSchema;
+    }
+
+    public void setArguments(Expression[] newNodes) {
+        this.nodes = newNodes;
+    }
+
+    public HsqlList resolveColumnReferences(RangeVariable[] rangeVarArray,
+            int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) {
+
+        if (isSelfAggregate()) {
+            if (unresolvedSet == null) {
+                unresolvedSet = new ArrayListIdentity();
+            }
+
+            unresolvedSet.add(this);
+
+            return unresolvedSet;
+        } else {
+            return super.resolveColumnReferences(rangeVarArray, rangeCount,
+                                                 unresolvedSet,
+                                                 acceptsSequences);
+        }
+    }
+
+    public void resolveTypes(Session session, Expression parent) {
+
+        Type[] types = new Type[nodes.length];
+
+        for (int i = 0; i < nodes.length; i++) {
+            Expression e = nodes[i];
+
+            e.resolveTypes(session, this);
+
+            types[i] = e.dataType;
+        }
+
+        routine = routineSchema.getSpecificRoutine(types);
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i].dataType == null) {
+                nodes[i].dataType = routine.getParameterTypes()[i];
+            }
+        }
+
+        dataType = routine.getReturnType();
+    }
+
+    private Object getValueInternal(Session session, Object[] aggregateData) {
+
+        boolean  isValue       = false;
+        int      variableCount = routine.getVariableCount();
+        Result   result;
+        int      extraArg = routine.javaMethodWithConnection ? 1
+                                                             : 0;
+        Object[] data     = ValuePool.emptyObjectArray;
+        boolean  push     = true;
+
+        if (extraArg + nodes.length > 0) {
+            if (opType == OpTypes.USER_AGGREGATE) {
+                data = new Object[routine.getParameterCount()];
+
+                for (int i = 0; i < aggregateData.length; i++) {
+                    data[i + 1] = aggregateData[i];
+                }
+            } else {
+                data = new Object[nodes.length + extraArg];
+            }
+
+            if (extraArg > 0) {
+                data[0] = session.getInternalConnection();
+            }
+        }
+
+        Type[] dataTypes = routine.getParameterTypes();
+
+        for (int i = 0; i < nodes.length; i++) {
+            Expression e     = nodes[i];
+            Object     value = e.getValue(session, dataTypes[i]);
+
+            if (value == null) {
+                if (routine.isNullInputOutput()) {
+                    return null;
+                }
+
+                if (!routine.getParameter(i).isNullable()) {
+                    return Result.newErrorResult(
+                        Error.error(ErrorCode.X_39004));
+                }
+            }
+
+            if (routine.isPSM()) {
+                data[i] = value;
+            } else {
+                data[i + extraArg] = e.dataType.convertSQLToJava(session,
+                        value);
+            }
+        }
+
+        if (push) {
+            session.sessionContext.push();
+        }
+
+        if (routine.isPSM()) {
+            try {
+                session.sessionContext.routineArguments = data;
+                session.sessionContext.routineVariables =
+                    ValuePool.emptyObjectArray;
+
+                if (variableCount > 0) {
+                    session.sessionContext.routineVariables =
+                        new Object[variableCount];
+                }
+
+                result = routine.statement.execute(session);
+
+                if (aggregateData != null) {
+                    for (int i = 0; i < aggregateData.length; i++) {
+                        aggregateData[i] = data[i + 1];
+                    }
+                }
+            } catch (Throwable e) {
+                result = Result.newErrorResult(e);
+            }
+        } else {
+            if (opType == OpTypes.USER_AGGREGATE) {
+                data = routine.convertArgsToJava(session, data);
+            }
+
+            result = routine.invokeJavaMethod(session, data);
+
+            if (opType == OpTypes.USER_AGGREGATE) {
+                Object[] callResult = new Object[data.length];
+
+                routine.convertArgsToSQL(session, callResult, data);
+
+                for (int i = 0; i < aggregateData.length; i++) {
+                    aggregateData[i] = callResult[i + 1];
+                }
+            }
+        }
+
+        if (push) {
+            session.sessionContext.pop();
+        }
+
+        if (result.isError()) {
+            throw result.getException();
+        }
+
+        if (isValue) {
+            return result.valueData;
+        } else {
+            return result;
+        }
+    }
+
+    public Object getValue(Session session) {
+
+        if (opType == OpTypes.SIMPLE_COLUMN) {
+            Object[] data =
+                session.sessionContext.rangeIterators[rangePosition]
+                    .getCurrent();
+
+            return data[columnIndex];
+        }
+
+        Object returnValue = getValueInternal(session, null);
+
+        if (returnValue instanceof Result) {
+            Result result = (Result) returnValue;
+
+            if (result.isError()) {
+                throw result.getException();
+            } else if (result.isSimpleValue()) {
+                returnValue = result.getValueObject();
+            } else if (result.isData()) {
+                returnValue = result;
+            } else {
+                throw Error.error(ErrorCode.X_2F005, routine.getName().name);
+            }
+        }
+
+        return returnValue;
+    }
+
+    public Result getResult(Session session) {
+
+        Object value = getValueInternal(session, null);
+
+        if (value instanceof Result) {
+            return (Result) value;
+        }
+
+        return Result.newPSMResult(value);
+    }
+
+    void collectObjectNames(Set set) {
+        set.add(routine.getSpecificName());
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(routineSchema.getName().getSchemaQualifiedStatementName());
+        sb.append('(');
+
+        int nodeCount = nodes.length;
+
+        if (opType == OpTypes.USER_AGGREGATE) {
+            nodeCount = 1;
+        }
+
+        for (int i = 0; i < nodeCount; i++) {
+            if (i != 0) {
+                sb.append(',');
+            }
+
+            sb.append(nodes[i].getSQL());
+        }
+
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public String describe(Session session, int blanks) {
+        return super.describe(session, blanks);
+    }
+
+    boolean isSelfAggregate() {
+        return routineSchema.isAggregate();
+    }
+
+    public boolean isDeterministic() {
+        return routine.isDeterministic();
+    }
+
+    public Object updateAggregatingValue(Session session, Object currValue) {
+
+        Object[] array = (Object[]) currValue;
+
+        if (array == null) {
+            array = new Object[3];
+        }
+
+        array[0] = Boolean.FALSE;
+
+        getValueInternal(session, array);
+
+        return array;
+    }
+
+    public Object getAggregatedValue(Session session, Object currValue) {
+
+        Object[] array = (Object[]) currValue;
+
+        if (array == null) {
+            array = new Object[3];
+        }
+
+        array[0] = Boolean.TRUE;
+
+        Result result = (Result) getValueInternal(session, array);
+        Object returnValue;
+
+        if (result.isError()) {
+            throw result.getException();
+        } else {
+            return result.getValueObject();
+        }
+    }
+}
diff --git a/src/org/hsqldb/HsqlDateTime.java b/src/org/hsqldb/HsqlDateTime.java
new file mode 100644
index 0000000..41eae8d
--- /dev/null
+++ b/src/org/hsqldb/HsqlDateTime.java
@@ -0,0 +1,556 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringUtil;
+
+// fredt@users 20020414 - patch 828957 by tjcrowder@users - JDK 1.3 compatibility
+
+/**
+ * collection of static methods to convert Date and Timestamp strings
+ * into corresponding Java objects and perform other Calendar related
+ * operation.<p>
+ *
+ * Was reviewed for 1.7.2 resulting in centralising all DATETIME related
+ * operstions.<p>
+ *
+ * From version 1.9.0, HSQLDB supports TIME ZONE with datetime types. The
+ * values are stored internally as UTC seconds from 1970, regardless of the
+ * time zone of the JVM, and converted as and when required, to the local
+ * timezone.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class HsqlDateTime {
+
+    /**
+     * A reusable static value for today's date. Should only be accessed
+     * by getToday()
+     */
+    private static Locale        defaultLocale = Locale.UK;
+    private static long          currentDateMillis;
+    public static final Calendar tempCalDefault = new GregorianCalendar();
+    public static final Calendar tempCalGMT =
+        new GregorianCalendar(TimeZone.getTimeZone("GMT"), defaultLocale);
+    private static final Date   tempDate        = new Date(0);
+    private static final String sdfdPattern     = "yyyy-MM-dd";
+    static SimpleDateFormat     sdfd = new SimpleDateFormat(sdfdPattern);
+    private static final String sdftPattern     = "HH:mm:ss";
+    static SimpleDateFormat     sdft = new SimpleDateFormat(sdftPattern);
+    private static final String sdftsPattern    = "yyyy-MM-dd HH:mm:ss";
+    static SimpleDateFormat     sdfts = new SimpleDateFormat(sdftsPattern);
+    private static final String sdftsSysPattern = "yyyy-MM-dd HH:mm:ss.SSS";
+    static SimpleDateFormat sdftsSys = new SimpleDateFormat(sdftsSysPattern);
+
+    static {
+        tempCalGMT.setLenient(false);
+        sdfd.setCalendar(new GregorianCalendar(TimeZone.getTimeZone("GMT"),
+                                               defaultLocale));
+        sdfd.setLenient(false);
+        sdft.setCalendar(new GregorianCalendar(TimeZone.getTimeZone("GMT"),
+                                               defaultLocale));
+        sdft.setLenient(false);
+        sdfts.setCalendar(new GregorianCalendar(TimeZone.getTimeZone("GMT"),
+                defaultLocale));
+        sdfts.setLenient(false);
+    }
+
+    static {
+        currentDateMillis = getNormalisedDate(System.currentTimeMillis());
+    }
+
+    public static long getDateSeconds(String s) {
+
+        try {
+            synchronized (sdfd) {
+                java.util.Date d = sdfd.parse(s);
+
+                return d.getTime() / 1000;
+            }
+        } catch (Exception e) {
+            throw Error.error(ErrorCode.X_22007);
+        }
+    }
+
+    public static String getDateString(long seconds) {
+
+        synchronized (sdfd) {
+            sysDate.setTime(seconds * 1000);
+
+            return sdfd.format(sysDate);
+        }
+    }
+
+    public static long getTimestampSeconds(String s) {
+
+        try {
+            synchronized (sdfts) {
+                java.util.Date d = sdfts.parse(s);
+
+                return d.getTime() / 1000;
+            }
+        } catch (Exception e) {
+            throw Error.error(ErrorCode.X_22007);
+        }
+    }
+
+    public static void getTimestampString(StringBuffer sb, long seconds,
+                                          int nanos, int scale) {
+
+        synchronized (sdfts) {
+            tempDate.setTime(seconds * 1000);
+            sb.append(sdfts.format(tempDate));
+
+            if (scale > 0) {
+                sb.append('.');
+                sb.append(StringUtil.toZeroPaddedString(nanos, 9, scale));
+            }
+        }
+    }
+
+    public static String getTimestampString(long millis) {
+
+        synchronized (sdfts) {
+            sysDate.setTime(millis);
+
+            return sdfts.format(sysDate);
+        }
+    }
+
+    public static synchronized long getCurrentDateMillis(long millis) {
+
+        if (millis - currentDateMillis >= 24 * 3600 * 1000) {
+            currentDateMillis = getNormalisedDate(millis);
+        }
+
+        return currentDateMillis;
+    }
+
+    private static java.util.Date sysDate = new java.util.Date();
+
+    public static String getSytemTimeString() {
+
+        synchronized (sdftsSys) {
+            sysDate.setTime(System.currentTimeMillis());
+
+            return sdftsSys.format(sysDate);
+        }
+    }
+
+    public static void resetToDate(Calendar cal) {
+
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+    }
+
+    public static void resetToTime(Calendar cal) {
+
+        cal.set(Calendar.YEAR, 1970);
+        cal.set(Calendar.MONTH, 0);
+        cal.set(Calendar.DATE, 1);
+        cal.set(Calendar.MILLISECOND, 0);
+    }
+
+    public static long convertMillisToCalendar(Calendar calendar,
+            long millis) {
+
+        calendar.clear();
+
+        synchronized (tempCalGMT) {
+            tempCalGMT.setTimeInMillis(millis);
+            calendar.set(tempCalGMT.get(Calendar.YEAR),
+                         tempCalGMT.get(Calendar.MONTH),
+                         tempCalGMT.get(Calendar.DAY_OF_MONTH),
+                         tempCalGMT.get(Calendar.HOUR_OF_DAY),
+                         tempCalGMT.get(Calendar.MINUTE),
+                         tempCalGMT.get(Calendar.SECOND));
+
+            return calendar.getTimeInMillis();
+        }
+    }
+
+    public static long convertMillisFromCalendar(Calendar calendar,
+            long millis) {
+
+        synchronized (tempCalGMT) {
+            tempCalGMT.clear();
+            calendar.setTimeInMillis(millis);
+            tempCalGMT.set(calendar.get(Calendar.YEAR),
+                           calendar.get(Calendar.MONTH),
+                           calendar.get(Calendar.DAY_OF_MONTH),
+                           calendar.get(Calendar.HOUR_OF_DAY),
+                           calendar.get(Calendar.MINUTE),
+                           calendar.get(Calendar.SECOND));
+
+            return tempCalGMT.getTimeInMillis();
+        }
+    }
+
+    /**
+     * Sets the time in the given Calendar using the given milliseconds value; wrapper method to
+     * allow use of more efficient JDK1.4 method on JDK1.4 (was protected in earlier versions).
+     *
+     * @param       cal                             the Calendar
+     * @param       millis                  the time value in milliseconds
+     */
+    public static void setTimeInMillis(Calendar cal, long millis) {
+
+//#ifdef JAVA4
+        // Use method directly
+        cal.setTimeInMillis(millis);
+
+//#else
+/*
+        // Have to go indirect
+        synchronized (tempDate) {
+            tempDate.setTime(millis);
+            cal.setTime(tempDate);
+        }
+*/
+
+//#endif JAVA4
+    }
+
+    /**
+     * Gets the time from the given Calendar as a milliseconds value; wrapper method to
+     * allow use of more efficient JDK1.4 method on JDK1.4 (was protected in earlier versions).
+     *
+     * @param       cal                             the Calendar
+     * @return      the time value in milliseconds
+     */
+    public static long getTimeInMillis(Calendar cal) {
+
+//#ifdef JAVA4
+        // Use method directly
+        return cal.getTimeInMillis();
+
+//#else
+/*
+        // Have to go indirect
+        return cal.getTime().getTime();
+*/
+
+//#endif JAVA4
+    }
+
+    public static long convertToNormalisedTime(long t) {
+        return convertToNormalisedTime(t, tempCalGMT);
+    }
+
+    public static long convertToNormalisedTime(long t, Calendar cal) {
+
+        synchronized (cal) {
+            setTimeInMillis(cal, t);
+            resetToDate(cal);
+
+            long t1 = getTimeInMillis(cal);
+
+            return t - t1;
+        }
+    }
+
+    public static long convertToNormalisedDate(long t, Calendar cal) {
+
+        synchronized (cal) {
+            setTimeInMillis(cal, t);
+            resetToDate(cal);
+
+            return getTimeInMillis(cal);
+        }
+    }
+
+    public static long getNormalisedTime(long t) {
+
+        Calendar cal = tempCalGMT;
+
+        synchronized (cal) {
+            setTimeInMillis(cal, t);
+            resetToTime(cal);
+
+            return getTimeInMillis(cal);
+        }
+    }
+
+    public static long getNormalisedTime(Calendar cal, long t) {
+
+        synchronized (cal) {
+            setTimeInMillis(cal, t);
+            resetToTime(cal);
+
+            return getTimeInMillis(cal);
+        }
+    }
+
+    public static long getNormalisedDate(long d) {
+
+        synchronized (tempCalGMT) {
+            setTimeInMillis(tempCalGMT, d);
+            resetToDate(tempCalGMT);
+
+            return getTimeInMillis(tempCalGMT);
+        }
+    }
+
+    public static long getNormalisedDate(Calendar cal, long d) {
+
+        synchronized (cal) {
+            setTimeInMillis(cal, d);
+            resetToDate(cal);
+
+            return getTimeInMillis(cal);
+        }
+    }
+
+    public static int getZoneSeconds(Calendar cal) {
+        return (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET))
+               / 1000;
+    }
+
+    public static int getZoneMillis(Calendar cal, long millis) {
+
+//#ifdef JAVA4
+        // get zone for the specific date
+        return cal.getTimeZone().getOffset(millis);
+
+//#else
+/*
+        // get zone for the specific date
+        setTimeInMillis(cal, millis);
+        return (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET) );
+*/
+
+//#endif JAVA4
+    }
+
+    /**
+     * Returns the indicated part of the given <code>java.util.Date</code> object.
+     * @param m the millisecond time value from which to extract the indicated part
+     * @param part an integer code corresponding to the desired date part
+     * @return the indicated part of the given <code>java.util.Date</code> object
+     */
+    public static int getDateTimePart(long m, int part) {
+
+        synchronized (tempCalGMT) {
+            tempCalGMT.setTimeInMillis(m);
+
+            return tempCalGMT.get(part);
+        }
+    }
+
+    //J-
+
+    private static final char[][] dateTokens     = {
+        { 'R', 'R', 'R', 'R' }, { 'I', 'Y', 'Y', 'Y' }, { 'Y', 'Y', 'Y', 'Y' },
+        { 'I', 'Y' }, { 'Y', 'Y' },
+        { 'B', 'C' }, { 'B', '.', 'C', '.' }, { 'A', 'D' }, { 'A', '.', 'D', '.' },
+        { 'M', 'O', 'N' }, { 'M', 'O', 'N', 'T', 'H' },
+        { 'D', 'A', 'Y' }, { 'D', 'Y' },
+        { 'I', 'W' }, { 'D', 'D' }, { 'D', 'D', 'D' },
+        { 'H', 'H', '2', '4' }, { 'H', 'H', '1', '2' }, { 'H', 'H' },
+        { 'M', 'I' },
+        { 'S', 'S' },
+        { 'A', 'M' }, { 'P', 'M' }, { 'A', '.', 'M', '.' }, { 'P', '.', 'M', '.' },
+        { 'F', 'F' }
+    };
+
+    private static final String[] javaDateTokens = {
+        "yyyy", "yyyy", "yyyy",
+        "yy", "yy",
+        "G", "G", "G", "G",
+        "MMM", "MMMMM",
+        "EEEE", "EE",
+        "w", "dd", "D",
+        "HH", "KK", "KK",
+        "mm", "ss",
+        "aaa", "aaa", "aaa", "aaa",
+        "S"
+    };
+
+    //J+
+
+    /** Indicates end-of-input */
+    private static final char e = 0xffff;
+
+    /**
+     * Converts the given format into a pattern accepted by <code>java.text.SimpleDataFormat</code>
+     *
+     * @param format
+     */
+    public static String toJavaDatePattern(String format) {
+
+        int          len = format.length();
+        char         ch;
+        StringBuffer sb        = new StringBuffer(len);
+        Tokenizer    tokenizer = new Tokenizer();
+
+        for (int i = 0; i <= len; i++) {
+            ch = (i == len) ? e
+                            : format.charAt(i);
+
+            if (!tokenizer.next(ch, dateTokens)) {
+                int index = tokenizer.getLastMatch();
+
+                if (index >= 0) {
+                    sb.setLength(sb.length() - tokenizer.length());
+                    sb.append(javaDateTokens[index]);
+                }
+
+                tokenizer.reset();
+
+                if (tokenizer.isConsumed()) {
+                    continue;
+                }
+            }
+
+            sb.append(ch);
+        }
+
+        sb.setLength(sb.length() - 1);
+
+        String javaPattern = sb.toString();
+
+        return javaPattern;
+    }
+
+    /**
+     * This class can match 64 tokens at maximum.
+     */
+    static class Tokenizer {
+
+        private int     last;
+        private int     offset;
+        private long    state;
+        private boolean consumed;
+
+        public Tokenizer() {
+            reset();
+        }
+
+        /**
+         * Resets for next reuse.
+         *
+         */
+        public void reset() {
+
+            last   = -1;
+            offset = -1;
+            state  = 0;
+        }
+
+        /**
+         * Returns a length of a token to match.
+         */
+        public int length() {
+            return offset;
+        }
+
+        /**
+         * Returns an index of the last matched token.
+         */
+        public int getLastMatch() {
+            return last;
+        }
+
+        /**
+         * Indicates whethe the last character has been consumed by the matcher.
+         */
+        public boolean isConsumed() {
+            return consumed;
+        }
+
+        /**
+         * Checks whether the specified bit is not set.
+         *
+         * @param bit
+         */
+        private boolean isZeroBit(int bit) {
+            return (state & (1L << bit)) == 0;
+        }
+
+        /**
+         * Sets the specified bit.
+         * @param bit
+         */
+        private void setBit(int bit) {
+            state |= (1L << bit);
+        }
+
+        /**
+         * Matches the specified character against tokens.
+         *
+         * @param ch
+         * @param tokens
+         */
+        public boolean next(char ch, char[][] tokens) {
+
+            // Use local variable for performance
+            int index = ++offset;
+            int len   = offset + 1;
+            int left  = 0;
+
+            consumed = false;
+
+            for (int i = tokens.length; --i >= 0; ) {
+                if (isZeroBit(i)) {
+                    if (tokens[i][index] == ch) {
+                        consumed = true;
+
+                        if (tokens[i].length == len) {
+                            setBit(i);
+
+                            last = i;
+                        } else {
+                            ++left;
+                        }
+                    } else {
+                        setBit(i);
+                    }
+                }
+            }
+
+            return left > 0;
+        }
+    }
+}
diff --git a/src/org/hsqldb/HsqlException.java b/src/org/hsqldb/HsqlException.java
new file mode 100644
index 0000000..52739dc
--- /dev/null
+++ b/src/org/hsqldb/HsqlException.java
@@ -0,0 +1,169 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.result.Result;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * Class encapsulating all exceptions that can be thrown within the engine.
+ * Instances are used to create instances of java.sql.SQLException and returned
+ * to JDBC callers.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class HsqlException extends RuntimeException {
+
+    //
+    public final static HsqlException[] emptyArray = new HsqlException[]{};
+    public final static HsqlException noDataCondition =
+        Error.error(ErrorCode.N_02000);
+
+    //
+    private String message;
+    private String state;
+    private int    code;
+    private int    level;
+    private int    statementGroup;
+    private int    statementCode;
+
+    /**
+     * @param message String
+     * @param state XOPEN / SQL code for exception
+     * @param code number code in HSQLDB
+     */
+    public HsqlException(Throwable t, String message, String state, int code) {
+
+        super(t);
+
+        this.message = message;
+        this.state   = state;
+        this.code    = code;
+    }
+
+    /**
+     * @param r containing the members
+     */
+    public HsqlException(Result r) {
+
+        this.message = r.getMainString();
+        this.state   = r.getSubString();
+        this.code    = r.getErrorCode();
+    }
+
+    public HsqlException(Throwable t, String errorState, int errorCode) {
+
+        super(t);
+
+        this.message = t.toString();
+        this.state   = errorState;
+        this.code    = errorCode;
+    }
+
+    /**
+     * @return message
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    /**
+     * @return SQL State
+     */
+    public String getSQLState() {
+        return state;
+    }
+
+    /**
+     * @return vendor specific error code
+     */
+    public int getErrorCode() {
+        return code;
+    }
+
+    public void setLevel(int level) {
+        this.level = level;
+    }
+
+    public int getLevel() {
+        return level;
+    }
+
+    public int getStatementCode() {
+        return statementCode;
+    }
+
+    public void setStatementType(int group, int code) {
+        statementGroup = group;
+        statementCode  = code;
+    }
+
+    public static class HsqlRuntimeMemoryError extends OutOfMemoryError {
+        HsqlRuntimeMemoryError() {}
+    }
+
+    public int hashCode() {
+        return code;
+    }
+
+    public boolean equals(Object other) {
+
+        if (other instanceof HsqlException) {
+            HsqlException o = (HsqlException) other;
+
+            return code == o.code && equals(state, o.state)
+                   && equals(message, o.message);
+        }
+
+        return false;
+    }
+
+    private static boolean equals(Object a, Object b) {
+
+        if (a == b) {
+            return true;
+        }
+
+        if (a == null || b == null) {
+            return false;
+        }
+
+        return a.equals(b);
+    }
+}
diff --git a/src/org/hsqldb/HsqlNameManager.java b/src/org/hsqldb/HsqlNameManager.java
new file mode 100644
index 0000000..75ee320
--- /dev/null
+++ b/src/org/hsqldb/HsqlNameManager.java
@@ -0,0 +1,563 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * Provides Name Management for SQL objects. <p>
+ *
+ * This class now includes the HsqlName class introduced in 1.7.1 and improves
+ * auto-naming with multiple databases in the engine.<p>
+ *
+ * Methods check user defined names and issue system generated names
+ * for SQL objects.<p>
+ *
+ * This class does not deal with the type of the SQL object for which it
+ * is used.<p>
+ *
+ * Some names beginning with SYS_ are reserved for system generated names.
+ * These are defined in isReserveName(String name) and created by the
+ * makeAutoName(String type) factory method<p>
+ *
+ * sysNumber is used to generate system-generated names. It is
+ * set to the largest integer encountered in names that use the
+ * SYS_xxxxxxx_INTEGER format. As the DDL is processed before any ALTER
+ * command, any new system generated name will have a larger integer suffix
+ * than all the existing names.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public final class HsqlNameManager {
+
+    public static final String DEFAULT_CATALOG_NAME = "PUBLIC";
+    private static final HsqlNameManager staticManager =
+        new HsqlNameManager(null);
+
+    static {
+        staticManager.serialNumber = Integer.MIN_VALUE;
+    }
+
+    private static final HsqlName[] autoColumnNames       = new HsqlName[32];
+    private static final String[]   autoNoNameColumnNames = new String[32];
+
+    static {
+        for (int i = 0; i < autoColumnNames.length; i++) {
+            autoColumnNames[i] = new HsqlName(staticManager, "C" + (i + 1), 0,
+                                              false);
+            autoNoNameColumnNames[i] = String.valueOf(i);
+        }
+    }
+
+    private int      serialNumber = 1;        // 0 is reserved in lookups
+    private int      sysNumber    = 10000;    // avoid name clash in older scripts
+    private HsqlName catalogName;
+
+    public HsqlNameManager(Database database) {
+        catalogName = new HsqlName(this, DEFAULT_CATALOG_NAME,
+                                   SchemaObject.CATALOG, false);
+    }
+
+    public HsqlName getCatalogName() {
+        return catalogName;
+    }
+
+    public static HsqlName newSystemObjectName(String name, int type) {
+        return new HsqlName(staticManager, name, type, false);
+    }
+
+    public static HsqlName newInfoSchemaColumnName(String name,
+            HsqlName table) {
+
+        HsqlName hsqlName = new HsqlName(staticManager, name, false,
+                                         SchemaObject.COLUMN);
+
+        hsqlName.schema = SqlInvariants.INFORMATION_SCHEMA_HSQLNAME;
+        hsqlName.parent = table;
+
+        return hsqlName;
+    }
+
+    public static HsqlName newInfoSchemaTableName(String name) {
+
+        HsqlName hsqlName = new HsqlName(staticManager, name,
+                                         SchemaObject.TABLE, false);
+
+        hsqlName.schema = SqlInvariants.INFORMATION_SCHEMA_HSQLNAME;
+
+        return hsqlName;
+    }
+
+    public static HsqlName newInfoSchemaObjectName(String name,
+            boolean isQuoted, int type) {
+
+        HsqlName hsqlName = new HsqlName(staticManager, name, type, isQuoted);
+
+        hsqlName.schema = SqlInvariants.INFORMATION_SCHEMA_HSQLNAME;
+
+        return hsqlName;
+    }
+
+    public HsqlName newHsqlName(HsqlName schema, String name, int type) {
+
+        HsqlName hsqlName = new HsqlName(this, name, type, false);
+
+        hsqlName.schema = schema;
+
+        return hsqlName;
+    }
+
+    //
+    public HsqlName newHsqlName(String name, boolean isquoted, int type) {
+        return new HsqlName(this, name, isquoted, type);
+    }
+
+    public HsqlName newHsqlName(HsqlName schema, String name,
+                                boolean isquoted, int type) {
+
+        HsqlName hsqlName = new HsqlName(this, name, isquoted, type);
+
+        hsqlName.schema = schema;
+
+        return hsqlName;
+    }
+
+    public HsqlName newHsqlName(HsqlName schema, String name,
+                                boolean isquoted, int type, HsqlName parent) {
+
+        HsqlName hsqlName = new HsqlName(this, name, isquoted, type);
+
+        hsqlName.schema = schema;
+        hsqlName.parent = parent;
+
+        return hsqlName;
+    }
+
+    public HsqlName newColumnSchemaHsqlName(HsqlName table, SimpleName name) {
+        return newColumnHsqlName(table, name.name, name.isNameQuoted);
+    }
+
+    public HsqlName newColumnHsqlName(HsqlName table, String name,
+                                      boolean isquoted) {
+
+        HsqlName hsqlName = new HsqlName(this, name, isquoted,
+                                         SchemaObject.COLUMN);
+
+        hsqlName.schema = table.schema;
+        hsqlName.parent = table;
+
+        return hsqlName;
+    }
+
+    /**
+     * Same name string but different objects and serial number
+     */
+    public HsqlName getSubqueryTableName() {
+
+        HsqlName hsqlName = new HsqlName(this, SqlInvariants.SYSTEM_SUBQUERY,
+                                         false, SchemaObject.TABLE);
+
+        hsqlName.schema = SqlInvariants.SYSTEM_SCHEMA_HSQLNAME;
+
+        return hsqlName;
+    }
+
+    /**
+     * Auto names are used for autogenerated indexes or anonymous constraints.
+     */
+    public HsqlName newAutoName(String prefix, HsqlName schema,
+                                HsqlName parent, int type) {
+
+        HsqlName name = newAutoName(prefix, (String) null, schema, parent,
+                                    type);
+
+        return name;
+    }
+
+    public HsqlName newSpecificRoutineName(HsqlName name) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(name.name).append('_').append(++sysNumber);
+
+        HsqlName hsqlName = new HsqlName(this, sb.toString(),
+                                         SchemaObject.SPECIFIC_ROUTINE,
+                                         name.isNameQuoted);
+
+        hsqlName.parent = name;
+        hsqlName.schema = name.schema;
+
+        return hsqlName;
+    }
+
+    /**
+     * Column index i is 0 based, returns 1 based numbered column.
+     */
+    static public HsqlName getAutoColumnName(int i) {
+
+        if (i < autoColumnNames.length) {
+            return autoColumnNames[i];
+        }
+
+        return new HsqlName(staticManager, "C_" + (i + 1), 0, false);
+    }
+
+    /**
+     * Column index i is 0 based, returns 1 based numbered column.
+     */
+    static public String getAutoColumnNameString(int i) {
+
+        if (i < autoColumnNames.length) {
+            return autoColumnNames[i].name;
+        }
+
+        return "C" + (i + 1);
+    }
+
+    static public String getAutoNoNameColumnString(int i) {
+
+        if (i < autoColumnNames.length) {
+            return autoNoNameColumnNames[i];
+        }
+
+        return String.valueOf(i);
+    }
+
+    static public String getAutoSavepointNameString(long i, int j) {
+
+        StringBuffer sb = new StringBuffer("S");
+
+        sb.append(i).append('_').append(j);
+
+        return sb.toString();
+    }
+
+    /**
+     * Auto names are used for autogenerated indexes or anonymous constraints.
+     */
+    public HsqlName newAutoName(String prefix, String namepart,
+                                HsqlName schema, HsqlName parent, int type) {
+
+        StringBuffer sb = new StringBuffer();
+
+        if (prefix != null) {
+            if (prefix.length() != 0) {
+                sb.append("SYS_");
+                sb.append(prefix);
+                sb.append('_');
+
+                if (namepart != null) {
+                    sb.append(namepart);
+                    sb.append('_');
+                }
+
+                sb.append(++sysNumber);
+            }
+        } else {
+            sb.append(namepart);
+        }
+
+        HsqlName name = new HsqlName(this, sb.toString(), type, false);
+
+        name.schema = schema;
+        name.parent = parent;
+
+        return name;
+    }
+
+    void resetNumbering() {
+        sysNumber    = 0;
+        serialNumber = 0;
+    }
+
+    public static SimpleName getSimpleName(String name, boolean isNameQuoted) {
+        return new SimpleName(name, isNameQuoted);
+    }
+
+    public static class SimpleName {
+
+        public String  name;
+        public boolean isNameQuoted;
+
+        private SimpleName() {}
+
+        private SimpleName(String name, boolean isNameQuoted) {
+            this.name         = name;
+            this.isNameQuoted = isNameQuoted;
+        }
+
+        public int hashCode() {
+            return name.hashCode();
+        }
+
+        public boolean equals(Object other) {
+
+            if (other instanceof SimpleName) {
+                return ((SimpleName) other).isNameQuoted == isNameQuoted
+                       && ((SimpleName) other).name.equals(name);
+            }
+
+            return false;
+        }
+
+        public String getStatementName() {
+
+            return isNameQuoted
+                   ? StringConverter.toQuotedString(name, '"', true)
+                   : name;
+        }
+    }
+
+    public static final class HsqlName extends SimpleName {
+
+        static HsqlName[] emptyArray = new HsqlName[]{};
+
+        //
+        HsqlNameManager   manager;
+        public String     statementName;
+        public String     comment;
+        public HsqlName   schema;
+        public HsqlName   parent;
+        public Grantee    owner;
+        public final int  type;
+        private final int hashCode;
+
+        private HsqlName(HsqlNameManager man, int type) {
+
+            manager   = man;
+            this.type = type;
+            hashCode  = manager.serialNumber++;
+        }
+
+        private HsqlName(HsqlNameManager man, String name, boolean isquoted,
+                         int type) {
+
+            this(man, type);
+
+            rename(name, isquoted);
+        }
+
+        /** for auto names and system-defined names */
+        private HsqlName(HsqlNameManager man, String name, int type,
+                         boolean isQuoted) {
+
+            this(man, type);
+
+            this.name         = this.statementName = name;
+            this.isNameQuoted = isQuoted;
+
+            if (isNameQuoted) {
+                statementName = StringConverter.toQuotedString(name, '"',
+                        true);
+            }
+        }
+
+        public String getStatementName() {
+            return statementName;
+        }
+
+        public String getSchemaQualifiedStatementName() {
+
+            if (type == SchemaObject.COLUMN) {
+                if (parent == null
+                        || SqlInvariants.SYSTEM_SUBQUERY.equals(parent.name)) {
+                    return statementName;
+                }
+
+                StringBuffer sb = new StringBuffer();
+
+                if (schema != null) {
+                    sb.append(schema.getStatementName());
+                    sb.append('.');
+                }
+
+                sb.append(parent.getStatementName());
+                sb.append('.');
+                sb.append(statementName);
+
+                return sb.toString();
+            }
+
+            if (schema == null) {
+                return statementName;
+            }
+
+            StringBuffer sb = new StringBuffer();
+
+            if (schema != null) {
+                sb.append(schema.getStatementName());
+                sb.append('.');
+            }
+
+            sb.append(statementName);
+
+            return sb.toString();
+        }
+
+        public void rename(HsqlName name) {
+            rename(name.name, name.isNameQuoted);
+        }
+
+        public void rename(String name, boolean isquoted) {
+
+            if (name.length() > 128) {
+                throw Error.error(ErrorCode.X_42501, name);
+            }
+
+            this.name          = name;
+            this.statementName = name;
+            this.isNameQuoted  = isquoted;
+
+            if (isNameQuoted) {
+                statementName = StringConverter.toQuotedString(name, '"',
+                        true);
+            }
+
+            if (name.startsWith("SYS_")) {
+                int length = name.lastIndexOf('_') + 1;
+
+                try {
+                    int temp = Integer.parseInt(name.substring(length));
+
+                    if (temp > manager.sysNumber) {
+                        manager.sysNumber = temp;
+                    }
+                } catch (NumberFormatException e) {}
+            }
+        }
+
+        void rename(String prefix, String name, boolean isquoted) {
+
+            StringBuffer sbname = new StringBuffer(prefix);
+
+            sbname.append('_');
+            sbname.append(name);
+            rename(sbname.toString(), isquoted);
+        }
+
+        public void setSchemaIfNull(HsqlName schema) {
+
+            if (this.schema == null) {
+                this.schema = schema;
+            }
+        }
+
+        public boolean equals(Object other) {
+
+            if (other instanceof HsqlName) {
+                return hashCode == ((HsqlName) other).hashCode;
+            }
+
+            return false;
+        }
+
+        /**
+         * hash code for this object is its unique serial number.
+         */
+        public int hashCode() {
+            return hashCode;
+        }
+
+        /**
+         * "SYS_IDX_" is used for auto-indexes on referring FK columns or
+         * unique constraints.
+         * "SYS_PK_" is for the primary key constraints
+         * "SYS_CT_" is for unique and check constraints
+         * "SYS_REF_" is for FK constraints in referenced tables
+         * "SYS_FK_" is for FK constraints in referencing tables
+         *
+         */
+        static final String[] sysPrefixes = new String[] {
+            "SYS_IDX_", "SYS_PK_", "SYS_REF_", "SYS_CT_", "SYS_FK_",
+        };
+
+        static int sysPrefixLength(String name) {
+
+            for (int i = 0; i < sysPrefixes.length; i++) {
+                if (name.startsWith(sysPrefixes[i])) {
+                    return sysPrefixes[i].length();
+                }
+            }
+
+            return 0;
+        }
+
+        static boolean isReservedName(String name) {
+            return sysPrefixLength(name) > 0;
+        }
+
+        boolean isReservedName() {
+            return isReservedName(name);
+        }
+
+        public String toString() {
+
+            return getClass().getName() + super.hashCode()
+                   + "[this.hashCode()=" + this.hashCode + ", name=" + name
+                   + ", name.hashCode()=" + name.hashCode()
+                   + ", isNameQuoted=" + isNameQuoted + "]";
+        }
+
+        public int compareTo(Object o) {
+            return hashCode - o.hashCode();
+        }
+
+        /**
+         * Returns true if the identifier consists of all uppercase letters
+         * digits and underscore, beginning with a letter and is not in the
+         * keyword list.
+         */
+        static boolean isRegularIdentifier(String name) {
+
+            for (int i = 0, length = name.length(); i < length; i++) {
+                int c = name.charAt(i);
+
+                if (c >= 'A' && c <= 'Z') {
+                    continue;
+                } else if (c == '_' && i > 0) {
+                    continue;
+                } else if (c >= '0' && c <= '9') {
+                    continue;
+                }
+
+                return false;
+            }
+
+            return !Tokens.isKeyword(name);
+        }
+    }
+}
diff --git a/src/org/hsqldb/Like.java b/src/org/hsqldb/Like.java
new file mode 100644
index 0000000..fadec6a
--- /dev/null
+++ b/src/org/hsqldb/Like.java
@@ -0,0 +1,424 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlByteArrayOutputStream;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.Type;
+
+/**
+ * Reusable object for processing LIKE queries.
+ *
+ * Enhanced in successive versions of HSQLDB.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+
+// boucherb@users 20030930 - patch 1.7.2 - optimize into joins if possible
+// fredt@users 20031006 - patch 1.7.2 - reuse Like objects for all rows
+// fredt@users 1.9.0 - LIKE for binary strings
+// fredt@users 1.9.0 - CompareAt() changes for performance suggested by Gary Frost
+class Like {
+
+    private final static BinaryData maxByteValue =
+        new BinaryData(new byte[]{ -128 }, false);
+    private char[]   cLike;
+    private int[]    wildCardType;
+    private int      iLen;
+    private boolean  isIgnoreCase;
+    private int      iFirstWildCard;
+    private boolean  isNull;
+    int              escapeChar;
+    boolean          hasCollation;
+    static final int UNDERSCORE_CHAR = 1;
+    static final int PERCENT_CHAR    = 2;
+    boolean          isVariable      = true;
+    boolean          isBinary        = false;
+    Type             dataType;
+
+    Like() {}
+
+    void setParams(boolean collation) {
+        hasCollation = collation;
+    }
+
+    void setIgnoreCase(boolean flag) {
+        isIgnoreCase = flag;
+    }
+
+    private Object getStartsWith() {
+
+        if (iLen == 0) {
+            return isBinary ? (Object) BinaryData.zeroLengthBinary
+                            : "";
+        }
+
+        StringBuffer              sb = null;
+        HsqlByteArrayOutputStream os = null;
+
+        if (isBinary) {
+            os = new HsqlByteArrayOutputStream();
+        } else {
+            sb = new StringBuffer();
+        }
+
+        int i = 0;
+
+        for (; i < iLen && wildCardType[i] == 0; i++) {
+            if (isBinary) {
+                os.writeByte(cLike[i]);
+            } else {
+                sb.append(cLike[i]);
+            }
+        }
+
+        if (i == 0) {
+            return null;
+        }
+
+        return isBinary ? (Object) new BinaryData(os.toByteArray(), false)
+                        : sb.toString();
+    }
+
+    Boolean compare(Session session, Object o) {
+
+        if (o == null) {
+            return null;
+        }
+
+        if (isNull) {
+            return null;
+        }
+
+        if (isIgnoreCase) {
+            o = ((CharacterType) dataType).upper(session, o);
+        }
+
+        return compareAt(o, 0, 0, iLen, getLength(session, o), cLike, wildCardType)
+               ? Boolean.TRUE
+               : Boolean.FALSE;
+    }
+
+    char getChar(Object o, int i) {
+
+        char c;
+
+        if (isBinary) {
+            c = (char) ((BinaryData) o).getBytes()[i];
+        } else {
+            c = ((String) o).charAt(i);
+        }
+
+        return c;
+    }
+
+    int getLength(SessionInterface session, Object o) {
+
+        int l;
+
+        if (isBinary) {
+            l = (int) ((BinaryData) o).length(session);
+        } else {
+            l = ((String) o).length();
+        }
+
+        return l;
+    }
+
+    private boolean compareAt(Object o, int i, int j, int iLen, int jLen,
+                              char cLike[], int[] wildCardType) {
+
+        for (; i < iLen; i++) {
+            switch (wildCardType[i]) {
+
+                case 0 :                  // general character
+                    if ((j >= jLen) || (cLike[i] != getChar(o, j++))) {
+                        return false;
+                    }
+                    break;
+
+                case UNDERSCORE_CHAR :    // underscore: do not test this character
+                    if (j++ >= jLen) {
+                        return false;
+                    }
+                    break;
+
+                case PERCENT_CHAR :       // percent: none or any character(s)
+                    if (++i >= iLen) {
+                        return true;
+                    }
+
+                    while (j < jLen) {
+                        if ((cLike[i] == getChar(o, j))
+                                && compareAt(o, i, j, iLen, jLen, cLike,
+                                             wildCardType)) {
+                            return true;
+                        }
+
+                        j++;
+                    }
+
+                    return false;
+            }
+        }
+
+        if (j != jLen) {
+            return false;
+        }
+
+        return true;
+    }
+
+    void setPattern(Session session, Object pattern, Object escape,
+                    boolean hasEscape) {
+
+        isNull = pattern == null;
+
+        if (!hasEscape) {
+            escapeChar = -1;
+        } else {
+            if (escape == null) {
+                isNull = true;
+
+                return;
+            } else {
+                int length = getLength(session, escape);
+
+                if (length != 1) {
+                    if (isBinary) {
+                        throw Error.error(ErrorCode.X_2200D);
+                    } else {
+                        throw Error.error(ErrorCode.X_22019);
+                    }
+                }
+
+                escapeChar = getChar(escape, 0);
+            }
+        }
+
+        if (isNull) {
+            return;
+        }
+
+        if (isIgnoreCase) {
+            pattern = (String) ((CharacterType) dataType).upper(null, pattern);
+        }
+
+        iLen           = 0;
+        iFirstWildCard = -1;
+
+        int l = getLength(session, pattern);
+
+        cLike        = new char[l];
+        wildCardType = new int[l];
+
+        boolean bEscaping = false,
+                bPercent  = false;
+
+        for (int i = 0; i < l; i++) {
+            char c = getChar(pattern, i);
+
+            if (!bEscaping) {
+                if (escapeChar == c) {
+                    bEscaping = true;
+
+                    continue;
+                } else if (c == '_') {
+                    wildCardType[iLen] = UNDERSCORE_CHAR;
+
+                    if (iFirstWildCard == -1) {
+                        iFirstWildCard = iLen;
+                    }
+                } else if (c == '%') {
+                    if (bPercent) {
+                        continue;
+                    }
+
+                    bPercent           = true;
+                    wildCardType[iLen] = PERCENT_CHAR;
+
+                    if (iFirstWildCard == -1) {
+                        iFirstWildCard = iLen;
+                    }
+                } else {
+                    bPercent = false;
+                }
+            } else {
+                if (c == escapeChar || c == '_' || c == '%') {
+                    bPercent  = false;
+                    bEscaping = false;
+                } else {
+                    throw Error.error(ErrorCode.X_22025);
+                }
+            }
+
+            cLike[iLen++] = c;
+        }
+
+        if (bEscaping) {
+            throw Error.error(ErrorCode.X_22025);
+        }
+
+        for (int i = 0; i < iLen - 1; i++) {
+            if ((wildCardType[i] == PERCENT_CHAR)
+                    && (wildCardType[i + 1] == UNDERSCORE_CHAR)) {
+                wildCardType[i]     = UNDERSCORE_CHAR;
+                wildCardType[i + 1] = PERCENT_CHAR;
+            }
+        }
+    }
+
+    boolean hasWildcards() {
+        return iFirstWildCard != -1;
+    }
+
+    boolean isEquivalentToUnknownPredicate() {
+        return isNull;
+    }
+
+    boolean isEquivalentToEqualsPredicate() {
+        return !isVariable && iFirstWildCard == -1;
+    }
+
+    boolean isEquivalentToNotNullPredicate() {
+
+        if (isVariable || isNull || !hasWildcards()) {
+            return false;
+        }
+
+        for (int i = 0; i < wildCardType.length; i++) {
+            if (wildCardType[i] != PERCENT_CHAR) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    boolean isEquivalentToBetweenPredicate() {
+
+        return !isVariable && iFirstWildCard > 0
+               && iFirstWildCard == wildCardType.length - 1
+               && cLike[iFirstWildCard] == '%';
+    }
+
+    boolean isEquivalentToBetweenPredicateAugmentedWithLike() {
+        return !isVariable && iFirstWildCard > 0
+               && cLike[iFirstWildCard] == '%';
+    }
+
+    Object getRangeLow() {
+        return getStartsWith();
+    }
+
+    Object getRangeHigh(Session session) {
+
+        Object o = getStartsWith();
+
+        if (o == null) {
+            return null;
+        }
+
+        if (isBinary) {
+            return new BinaryData(session, (BinaryData) o, maxByteValue);
+        } else {
+            return dataType.concat(session, o, "\uffff");
+        }
+    }
+
+    public String describe(Session session) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(super.toString()).append("[\n");
+        sb.append("escapeChar=").append(escapeChar).append('\n');
+        sb.append("isNull=").append(isNull).append('\n');
+
+//        sb.append("optimised=").append(optimised).append('\n');
+        sb.append("isIgnoreCase=").append(isIgnoreCase).append('\n');
+        sb.append("iLen=").append(iLen).append('\n');
+        sb.append("iFirstWildCard=").append(iFirstWildCard).append('\n');
+        sb.append("cLike=");
+        sb.append(StringUtil.arrayToString(cLike));
+        sb.append('\n');
+        sb.append("wildCardType=");
+        sb.append(StringUtil.arrayToString(wildCardType));
+        sb.append(']');
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/NumberSequence.java b/src/org/hsqldb/NumberSequence.java
new file mode 100644
index 0000000..9da5717
--- /dev/null
+++ b/src/org/hsqldb/NumberSequence.java
@@ -0,0 +1,714 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.math.BigDecimal;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Maintains a sequence of numbers.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version  1.9.0
+ * @since 1.7.2
+ */
+public final class NumberSequence implements SchemaObject {
+
+    public final static NumberSequence[] emptyArray = new NumberSequence[]{};
+
+    //
+    private HsqlName name;
+
+    // present value
+    private long currValue;
+
+    // last value
+    private long lastValue;
+
+    // limit state
+    private boolean limitReached;
+
+    // original start value - used in CREATE and ALTER commands
+    private long    startValue;
+    private long    minValue;
+    private long    maxValue;
+    private long    increment;
+    private Type    dataType;
+    private boolean isCycle;
+    private boolean isAlways;
+    private boolean restartValueDefault;
+
+    public NumberSequence() {
+
+        try {
+            setDefaults(null, Type.SQL_BIGINT);
+        } catch (HsqlException e) {}
+    }
+
+    public NumberSequence(HsqlName name, Type type) {
+        setDefaults(name, type);
+    }
+
+    public void setDefaults(HsqlName name, Type type) {
+
+        this.name = name;
+        this.dataType  = type;
+        this.name = name;
+
+        long min;
+        long max;
+
+        switch (dataType.typeCode) {
+
+            case Types.TINYINT :
+                max = Byte.MAX_VALUE;
+                min = Byte.MIN_VALUE;
+                break;
+
+            case Types.SQL_SMALLINT :
+                max = Short.MAX_VALUE;
+                min = Short.MIN_VALUE;
+                break;
+
+            case Types.SQL_INTEGER :
+                max = Integer.MAX_VALUE;
+                min = Integer.MIN_VALUE;
+                break;
+
+            case Types.SQL_BIGINT :
+                max = Long.MAX_VALUE;
+                min = Long.MIN_VALUE;
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                if (type.scale == 0) {
+                    max = Long.MAX_VALUE;
+                    min = Long.MIN_VALUE;
+
+                    break;
+                }
+
+            // fall through
+            default :
+                throw Error.error(ErrorCode.X_42563);
+        }
+
+        minValue  = min;
+        maxValue  = max;
+        increment = 1;
+    }
+
+    /**
+     * constructor with initial value and increment;
+     */
+    public NumberSequence(HsqlName name, long value, long increment,
+                          Type type) {
+
+        this(name, type);
+
+        setStartValue(value);
+        setIncrement(increment);
+    }
+
+    public int getType() {
+        return SchemaObject.SEQUENCE;
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public HsqlName getCatalogName() {
+        return name.schema.schema;
+    }
+
+    public HsqlName getSchemaName() {
+        return name.schema;
+    }
+
+    public Grantee getOwner() {
+        return name.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+        return new OrderedHashSet();
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer(128);
+
+        if (name == null) {
+            sb.append(Tokens.T_GENERATED).append(' ');
+
+            if (isAlways()) {
+                sb.append(Tokens.T_ALWAYS);
+            } else {
+                sb.append(Tokens.T_BY).append(' ').append(Tokens.T_DEFAULT);
+            }
+
+            sb.append(' ').append(Tokens.T_AS).append(' ').append(
+                Tokens.T_IDENTITY).append(Tokens.T_OPENBRACKET);
+        } else {
+            sb.append(Tokens.T_CREATE).append(' ');
+            sb.append(Tokens.T_SEQUENCE).append(' ');
+            sb.append(getName().getSchemaQualifiedStatementName()).append(' ');
+            sb.append(Tokens.T_AS).append(' ');
+            sb.append(getDataType().getNameString()).append(' ');
+        }
+
+        //
+        sb.append(Tokens.T_START).append(' ');
+        sb.append(Tokens.T_WITH).append(' ');
+        sb.append(startValue);
+
+        if (getIncrement() != 1) {
+            sb.append(' ').append(Tokens.T_INCREMENT).append(' ');
+            sb.append(Tokens.T_BY).append(' ');
+            sb.append(getIncrement());
+        }
+
+        if (!hasDefaultMinMax()) {
+            sb.append(' ').append(Tokens.T_MINVALUE).append(' ');
+            sb.append(getMinValue());
+            sb.append(' ').append(Tokens.T_MAXVALUE).append(' ');
+            sb.append(getMaxValue());
+        }
+
+        if (isCycle()) {
+            sb.append(' ').append(Tokens.T_CYCLE);
+        }
+
+        if (name == null) {
+            sb.append(Tokens.T_CLOSEBRACKET);
+        }
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    public String getRestartSQL() {
+
+        StringBuffer sb = new StringBuffer(128);
+
+        sb.append(Tokens.T_ALTER).append(' ');
+        sb.append(Tokens.T_SEQUENCE);
+        sb.append(' ').append(name.getSchemaQualifiedStatementName());
+        sb.append(' ').append(Tokens.T_RESTART);
+        sb.append(' ').append(Tokens.T_WITH).append(' ').append(peek());
+
+        return sb.toString();
+    }
+
+    public static String getRestartSQL(Table t) {
+
+        String colname = t.getColumn(t.identityColumn).getName().statementName;
+        NumberSequence seq = t.identitySequence;
+        StringBuffer   sb  = new StringBuffer(128);
+
+        sb.append(Tokens.T_ALTER).append(' ').append(Tokens.T_TABLE);
+        sb.append(' ').append(t.getName().getSchemaQualifiedStatementName());
+        sb.append(' ').append(Tokens.T_ALTER).append(' ');
+        sb.append(Tokens.T_COLUMN);
+        sb.append(' ').append(colname);
+        sb.append(' ').append(Tokens.T_RESTART);
+        sb.append(' ').append(Tokens.T_WITH).append(' ').append(seq.peek());
+
+        return sb.toString();
+    }
+
+    public Type getDataType() {
+        return dataType;
+    }
+
+    public long getIncrement() {
+        return increment;
+    }
+
+    public synchronized long getStartValue() {
+        return startValue;
+    }
+
+    public synchronized long getMinValue() {
+        return minValue;
+    }
+
+    public synchronized long getMaxValue() {
+        return maxValue;
+    }
+
+    public synchronized boolean isCycle() {
+        return isCycle;
+    }
+
+    public synchronized boolean isAlways() {
+        return isAlways;
+    }
+
+    public synchronized boolean hasDefaultMinMax() {
+
+        long min;
+        long max;
+
+        switch (dataType.typeCode) {
+
+            case Types.TINYINT :
+                max = Byte.MAX_VALUE;
+                min = Byte.MIN_VALUE;
+                break;
+
+            case Types.SQL_SMALLINT :
+                max = Short.MAX_VALUE;
+                min = Short.MIN_VALUE;
+                break;
+
+            case Types.SQL_INTEGER :
+                max = Integer.MAX_VALUE;
+                min = Integer.MIN_VALUE;
+                break;
+
+            case Types.SQL_BIGINT :
+                max = Long.MAX_VALUE;
+                min = Long.MIN_VALUE;
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                max = Long.MAX_VALUE;
+                min = Long.MIN_VALUE;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberSequence");
+        }
+
+        return minValue == min && maxValue == max;
+    }
+
+    synchronized void setStartValue(long value) {
+
+        if (value < minValue || value > maxValue) {
+            throw Error.error(ErrorCode.X_42597);
+        }
+
+        startValue = value;
+        currValue  = lastValue = startValue;
+    }
+
+    synchronized void setMinValue(long value) {
+
+        checkInTypeRange(value);
+
+        if (value >= maxValue || currValue < value) {
+            throw Error.error(ErrorCode.X_42597);
+        }
+
+        minValue = value;
+    }
+
+    synchronized void setDefaultMinValue() {
+        minValue = getDefaultMinOrMax(false);
+    }
+
+    synchronized void setMaxValue(long value) {
+
+        checkInTypeRange(value);
+
+        if (value <= minValue || currValue > value) {
+            throw Error.error(ErrorCode.X_42597);
+        }
+
+        maxValue = value;
+    }
+
+    synchronized void setDefaultMaxValue() {
+        maxValue = getDefaultMinOrMax(true);
+    }
+
+    synchronized void setIncrement(long value) {
+
+        if (value < Short.MIN_VALUE / 2 || value > Short.MAX_VALUE / 2) {
+            throw Error.error(ErrorCode.X_42597);
+        }
+
+        increment = value;
+    }
+
+    synchronized void setCurrentValueNoCheck(long value) {
+
+        checkInTypeRange(value);
+
+        currValue = lastValue = value;
+    }
+
+    synchronized void setStartValueNoCheck(long value) {
+
+        checkInTypeRange(value);
+
+        startValue = value;
+        currValue  = lastValue = startValue;
+    }
+
+    synchronized void setStartValueDefault() {
+        restartValueDefault = true;
+    }
+
+    synchronized void setMinValueNoCheck(long value) {
+
+        checkInTypeRange(value);
+
+        minValue = value;
+    }
+
+    synchronized void setMaxValueNoCheck(long value) {
+
+        checkInTypeRange(value);
+
+        maxValue = value;
+    }
+
+    synchronized void setCycle(boolean value) {
+        isCycle = value;
+    }
+
+    synchronized void setAlways(boolean value) {
+        isAlways = value;
+    }
+
+    private long getDefaultMinOrMax(boolean isMax) {
+
+        long min;
+        long max;
+
+        switch (dataType.typeCode) {
+
+            case Types.TINYINT :
+                max = Byte.MAX_VALUE;
+                min = Byte.MIN_VALUE;
+                break;
+
+            case Types.SQL_SMALLINT :
+                max = Short.MAX_VALUE;
+                min = Short.MIN_VALUE;
+                break;
+
+            case Types.SQL_INTEGER :
+                max = Integer.MAX_VALUE;
+                min = Integer.MIN_VALUE;
+                break;
+
+            case Types.SQL_BIGINT :
+                max = Long.MAX_VALUE;
+                min = Long.MIN_VALUE;
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                max = Long.MAX_VALUE;
+                min = Long.MIN_VALUE;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberSequence");
+        }
+
+        return isMax ? max
+                     : min;
+    }
+
+    private void checkInTypeRange(long value) {
+
+        long min;
+        long max;
+
+        switch (dataType.typeCode) {
+
+            case Types.TINYINT :
+                max = Byte.MAX_VALUE;
+                min = Byte.MIN_VALUE;
+                break;
+
+            case Types.SQL_SMALLINT :
+                max = Short.MAX_VALUE;
+                min = Short.MIN_VALUE;
+                break;
+
+            case Types.SQL_INTEGER :
+                max = Integer.MAX_VALUE;
+                min = Integer.MIN_VALUE;
+                break;
+
+            case Types.SQL_BIGINT :
+                max = Long.MAX_VALUE;
+                min = Long.MIN_VALUE;
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                max = Long.MAX_VALUE;
+                min = Long.MIN_VALUE;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberSequence");
+        }
+
+        if (value < min || value > max) {
+            throw Error.error(ErrorCode.X_42597);
+        }
+    }
+
+    synchronized void checkValues() {
+
+        if (restartValueDefault) {
+            currValue           = lastValue = startValue;
+            restartValueDefault = false;
+        }
+
+        if (minValue >= maxValue || startValue < minValue
+                || startValue > maxValue || currValue < minValue
+                || currValue > maxValue) {
+            throw Error.error(ErrorCode.X_42597);
+        }
+    }
+
+    synchronized NumberSequence duplicate() {
+
+        NumberSequence copy = new NumberSequence();
+
+        copy.name       = name;
+        copy.startValue = startValue;
+        copy.currValue  = currValue;
+        copy.lastValue  = lastValue;
+        copy.increment  = increment;
+        copy.dataType   = dataType;
+        copy.minValue   = minValue;
+        copy.maxValue   = maxValue;
+        copy.isCycle    = isCycle;
+        copy.isAlways   = isAlways;
+
+        return copy;
+    }
+
+    synchronized void reset(NumberSequence other) {
+
+        name       = other.name;
+        startValue = other.startValue;
+        currValue  = other.currValue;
+        lastValue  = other.lastValue;
+        increment  = other.increment;
+        dataType   = other.dataType;
+        minValue   = other.minValue;
+        maxValue   = other.maxValue;
+        isCycle    = other.isCycle;
+        isAlways   = other.isAlways;
+    }
+
+    /**
+     * getter for a given value
+     */
+    synchronized long userUpdate(long value) {
+
+        if (value == currValue) {
+            currValue += increment;
+
+            return value;
+        }
+
+        if (increment > 0) {
+            if (value > currValue) {
+                currValue += ((value - currValue + increment) / increment)
+                             * increment;
+            }
+        } else {
+            if (value < currValue) {
+                currValue += ((value - currValue + increment) / increment)
+                             * increment;
+            }
+        }
+
+        return value;
+    }
+
+    /**
+     * Updates are necessary for text tables
+     * For memory tables, the logged and scripted RESTART WITH will override
+     * this.
+     * No checks as values may have overridden the sequnece defaults
+     */
+    synchronized long systemUpdate(long value) {
+
+        if (value == currValue) {
+            currValue += increment;
+
+            return value;
+        }
+
+        if (increment > 0) {
+            if (value > currValue) {
+                currValue = value + increment;
+            }
+        } else {
+            if (value < currValue) {
+                currValue = value + increment;
+            }
+        }
+
+        return value;
+    }
+
+    synchronized Object getValueObject() {
+
+        long   value = getValue();
+        Object result;
+
+        switch (dataType.typeCode) {
+
+            default :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+                result = ValuePool.getInt((int) value);
+                break;
+
+            case Types.SQL_BIGINT :
+                result = ValuePool.getLong(value);
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                result = ValuePool.getBigDecimal(new BigDecimal(value));
+                break;
+        }
+
+        return result;
+    }
+
+    /**
+     * principal getter for the next sequence value
+     */
+    synchronized public long getValue() {
+
+        if (limitReached) {
+            throw Error.error(ErrorCode.X_2200H);
+        }
+
+        long nextValue;
+
+        if (increment > 0) {
+            if (currValue > maxValue - increment) {
+                if (isCycle) {
+                    nextValue = minValue;
+                } else {
+                    limitReached = true;
+                    nextValue    = minValue;
+                }
+            } else {
+                nextValue = currValue + increment;
+            }
+        } else {
+            if (currValue < minValue - increment) {
+                if (isCycle) {
+                    nextValue = maxValue;
+                } else {
+                    limitReached = true;
+                    nextValue    = minValue;
+                }
+            } else {
+                nextValue = currValue + increment;
+            }
+        }
+
+        long result = currValue;
+
+        currValue = nextValue;
+
+        return result;
+    }
+
+    /**
+     * reset to start value
+     */
+    synchronized void reset() {
+
+        // no change if called before getValue() or called twice
+        lastValue = currValue = startValue;
+    }
+
+    /**
+     * get next value without incrementing
+     */
+    synchronized public long peek() {
+        return currValue;
+    }
+
+    /**
+     * reset the wasUsed flag
+     */
+    synchronized boolean resetWasUsed() {
+
+        boolean result = lastValue != currValue;
+
+        lastValue = currValue;
+
+        return result;
+    }
+
+    /**
+     * reset to new initial value
+     */
+    synchronized public void reset(long value) {
+
+        if (value < minValue || value > maxValue) {
+            throw Error.error(ErrorCode.X_42597);
+        }
+
+        startValue = currValue = lastValue = value;
+    }
+}
diff --git a/src/org/hsqldb/OpTypes.java b/src/org/hsqldb/OpTypes.java
new file mode 100644
index 0000000..ce0364c
--- /dev/null
+++ b/src/org/hsqldb/OpTypes.java
@@ -0,0 +1,108 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+public interface OpTypes {
+
+    int VALUE                = 1,     // constant value
+        COLUMN               = 2,     // references
+        COALESCE             = 3,
+        DEFAULT              = 4,
+        SIMPLE_COLUMN        = 5,
+        VARIABLE             = 6,
+        PARAMETER            = 7,
+        DYNAMIC_PARAM        = 8,
+        ASTERISK             = 9,
+        SEQUENCE             = 10,
+        ARRAY                = 19,
+        MULTISET             = 20,
+        SCALAR_SUBQUERY      = 21,    // query based row or table
+        ROW_SUBQUERY         = 22,
+        TABLE_SUBQUERY       = 23,
+        ROW                  = 25,    // rows
+        TABLE                = 26,
+        FUNCTION             = 27,
+        SQL_FUNCTION         = 28,
+        ROUTINE_FUNCTION     = 29,
+        NEGATE               = 31,    // arithmetic operations
+        ADD                  = 32,
+        SUBTRACT             = 33,
+        MULTIPLY             = 34,
+        DIVIDE               = 35,
+        CONCAT               = 36,    // concatenation
+        EQUAL                = 41,    // logical - comparison
+        GREATER_EQUAL        = 42,
+        GREATER              = 43,
+        SMALLER              = 44,
+        SMALLER_EQUAL        = 45,
+        NOT_EQUAL            = 46,
+        IS_NULL              = 47,
+        NOT                  = 48,    // logical operations
+        AND                  = 49,
+        OR                   = 50,
+        ALL_QUANTIFIED       = 51,    // logical - quantified comparison
+        ANY_QUANTIFIED       = 52,
+        LIKE                 = 53,    // logical - predicates
+        IN                   = 54,
+        EXISTS               = 55,
+        OVERLAPS             = 56,
+        UNIQUE               = 57,
+        NOT_DISTINCT         = 58,
+        MATCH_SIMPLE         = 59,
+        MATCH_PARTIAL        = 60,
+        MATCH_FULL           = 61,
+        MATCH_UNIQUE_SIMPLE  = 62,
+        MATCH_UNIQUE_PARTIAL = 63,
+        MATCH_UNIQUE_FULL    = 64,
+        COUNT                = 71,    // aggregate functions
+        SUM                  = 72,
+        MIN                  = 73,
+        MAX                  = 74,
+        AVG                  = 75,
+        EVERY                = 76,
+        SOME                 = 77,
+        STDDEV_POP           = 78,
+        STDDEV_SAMP          = 79,
+        VAR_POP              = 80,
+        VAR_SAMP             = 81,
+        CAST                 = 91,    // other operations
+        ZONE_MODIFIER        = 92,
+        CASEWHEN             = 93,
+        ORDER_BY             = 94,
+        LIMIT                = 95,
+        ALTERNATIVE          = 96,
+        MULTICOLUMN          = 97,
+        USER_AGGREGATE       = 98,
+        ARRAY_ACCESS         = 99,
+        ARRAY_SUBQUERY       = 100
+    ;
+}
diff --git a/src/org/hsqldb/ParserBase.java b/src/org/hsqldb/ParserBase.java
new file mode 100644
index 0000000..f5fa0e4
--- /dev/null
+++ b/src/org/hsqldb/ParserBase.java
@@ -0,0 +1,825 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.math.BigDecimal;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.IntKeyIntValueHashMap;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ParserBase {
+
+    private Scanner scanner;
+    protected Token token;
+
+    //
+    protected boolean       isRecording;
+    protected HsqlArrayList recordedStatement;
+    private final Token     dummyToken = new Token();
+
+    //
+    protected boolean isCheckOrTriggerCondition;
+    protected boolean isSchemaDefinition;
+    protected int     parsePosition;
+    static final BigDecimal LONG_MAX_VALUE_INCREMENT =
+        BigDecimal.valueOf(Long.MAX_VALUE).add(BigDecimal.valueOf(1));
+
+    /**
+     * Constructs a new BaseParser object with the given context.
+     *
+     * @param t the token source from which to parse commands
+     */
+    ParserBase(Scanner t) {
+        scanner = t;
+        token   = scanner.token;
+    }
+
+    public Scanner getScanner() {
+        return scanner;
+    }
+
+    public int getParsePosition() {
+        return parsePosition;
+    }
+
+    public void setParsePosition(int parsePosition) {
+        this.parsePosition = parsePosition;
+    }
+
+    /**
+     *  Resets this parse context with the given SQL character sequence.
+     *
+     * Internal structures are reset as though a new parser were created
+     * with the given sql and the originally specified database and session
+     *
+     * @param sql a new SQL character sequence to replace the current one
+     */
+    void reset(String sql) {
+
+        scanner.reset(sql);
+
+        //
+        parsePosition             = 0;
+        isCheckOrTriggerCondition = false;
+        isSchemaDefinition        = false;
+        isRecording               = false;
+        recordedStatement         = null;
+    }
+
+    int getPosition() {
+        return scanner.getTokenPosition();
+    }
+
+    void rewind(int position) {
+
+        if (position == scanner.getTokenPosition()) {
+            return;
+        }
+
+        scanner.position(position);
+
+        if (isRecording) {
+            int i = recordedStatement.size() - 1;
+
+            for (; i >= 0; i--) {
+                Token token = (Token) recordedStatement.get(i);
+
+                if (token.position < position) {
+                    break;
+                }
+            }
+
+            recordedStatement.setSize(i + 1);
+        }
+
+        read();
+    }
+
+    String getLastPart() {
+        return scanner.getPart(parsePosition, scanner.getTokenPosition());
+    }
+
+    String getLastPart(int position) {
+        return scanner.getPart(position, scanner.getTokenPosition());
+    }
+
+    String getLastPartAndCurrent(int position) {
+        return scanner.getPart(position, scanner.getPosition());
+    }
+
+    String getStatement(int startPosition, short[] startTokens) {
+
+        while (true) {
+            if (token.tokenType == Tokens.SEMICOLON) {
+                break;
+            } else if (token.tokenType == Tokens.X_ENDPARSE) {
+                break;
+            } else {
+                if (ArrayUtil.find(startTokens, token.tokenType) != -1) {
+                    break;
+                }
+            }
+
+            read();
+        }
+
+        String sql = scanner.getPart(startPosition,
+                                     scanner.getTokenPosition());
+
+        return sql;
+    }
+
+    String getStatementForRoutine(int startPosition, short[] startTokens) {
+
+        int tokenIndex   = 0;;
+        int semiIndex    = -1;
+        int semiPosition = -1;
+
+        while (true) {
+            if (token.tokenType == Tokens.SEMICOLON) {
+                semiPosition = scanner.getTokenPosition();
+                semiIndex    = tokenIndex;
+            } else if (token.tokenType == Tokens.X_ENDPARSE) {
+                if (semiIndex > 0 && semiIndex == tokenIndex - 1) {
+                    rewind(semiPosition);
+                }
+
+                break;
+            } else {
+                if (ArrayUtil.find(startTokens, token.tokenType) != -1) {
+                    break;
+                }
+            }
+
+            read();
+
+            tokenIndex++;
+        }
+
+        String sql = scanner.getPart(startPosition,
+                                     scanner.getTokenPosition());
+
+        return sql;
+    }
+
+    //
+    void startRecording() {
+
+        recordedStatement = new HsqlArrayList();
+
+        recordedStatement.add(token.duplicate());
+
+        isRecording = true;
+    }
+
+    Token getRecordedToken() {
+
+        if (isRecording) {
+            return (Token) recordedStatement.get(recordedStatement.size() - 1);
+        } else {
+            return dummyToken;
+        }
+    }
+
+    Token[] getRecordedStatement() {
+
+        isRecording = false;
+
+        recordedStatement.remove(recordedStatement.size() - 1);
+
+        Token[] tokens = new Token[recordedStatement.size()];
+
+        recordedStatement.toArray(tokens);
+
+        recordedStatement = null;
+
+        return tokens;
+    }
+
+    void read() {
+
+        scanner.scanNext();
+
+        if (token.isMalformed) {
+            int errorCode = -1;
+
+            switch (token.tokenType) {
+
+                case Tokens.X_MALFORMED_BINARY_STRING :
+                    errorCode = ErrorCode.X_42587;
+                    break;
+
+                case Tokens.X_MALFORMED_BIT_STRING :
+                    errorCode = ErrorCode.X_42588;
+                    break;
+
+                case Tokens.X_MALFORMED_UNICODE_STRING :
+                    errorCode = ErrorCode.X_42586;
+                    break;
+
+                case Tokens.X_MALFORMED_STRING :
+                    errorCode = ErrorCode.X_42584;
+                    break;
+
+                case Tokens.X_UNKNOWN_TOKEN :
+                    errorCode = ErrorCode.X_42582;
+                    break;
+
+                case Tokens.X_MALFORMED_NUMERIC :
+                    errorCode = ErrorCode.X_42585;
+                    break;
+
+                case Tokens.X_MALFORMED_COMMENT :
+                    errorCode = ErrorCode.X_42589;
+                    break;
+
+                case Tokens.X_MALFORMED_IDENTIFIER :
+                    errorCode = ErrorCode.X_42583;
+                    break;
+            }
+
+            throw Error.error(errorCode);
+        }
+
+        if (isRecording) {
+            Token dup = token.duplicate();
+
+            dup.position = scanner.getTokenPosition();
+
+            recordedStatement.add(dup);
+        }
+    }
+
+    boolean isReservedKey() {
+        return scanner.token.isReservedIdentifier;
+    }
+
+    boolean isCoreReservedKey() {
+        return scanner.token.isCoreReservedIdentifier;
+    }
+
+    boolean isNonReservedIdentifier() {
+
+        return !scanner.token.isReservedIdentifier
+               && (scanner.token.isUndelimitedIdentifier
+                   || scanner.token.isDelimitedIdentifier);
+    }
+
+    void checkIsNonReservedIdentifier() {
+
+        if (!isNonReservedIdentifier()) {
+            throw unexpectedToken();
+        }
+    }
+
+    boolean isNonCoreReservedIdentifier() {
+
+        return !scanner.token.isCoreReservedIdentifier
+               && (scanner.token.isUndelimitedIdentifier
+                   || scanner.token.isDelimitedIdentifier);
+    }
+
+    void checkIsNonCoreReservedIdentifier() {
+
+        if (!isNonCoreReservedIdentifier()) {
+            throw unexpectedToken();
+        }
+    }
+
+    boolean isIdentifier() {
+        return scanner.token.isUndelimitedIdentifier
+               || scanner.token.isDelimitedIdentifier;
+    }
+
+    void checkIsIdentifier() {
+
+        if (!isIdentifier()) {
+            throw unexpectedToken();
+        }
+    }
+
+    boolean isDelimitedIdentifier() {
+        return scanner.token.isDelimitedIdentifier;
+    }
+
+    void checkIsDelimitedIdentifier() {
+
+        if (token.tokenType != Tokens.X_DELIMITED_IDENTIFIER) {
+            throw Error.error(ErrorCode.X_42569);
+        }
+    }
+
+    void checkIsNotQuoted() {
+
+        if (token.tokenType == Tokens.X_DELIMITED_IDENTIFIER) {
+            throw unexpectedToken();
+        }
+    }
+
+    void checkIsValue() {
+
+        if (token.tokenType != Tokens.X_VALUE) {
+            throw unexpectedToken();
+        }
+    }
+
+    void checkIsValue(int dataTypeCode) {
+
+        if (token.tokenType != Tokens.X_VALUE
+                || token.dataType.typeCode != dataTypeCode) {
+            throw unexpectedToken();
+        }
+    }
+
+    void checkIsThis(int type) {
+
+        if (token.tokenType != type) {
+            throw unexpectedToken();
+        }
+    }
+
+    boolean isUndelimitedSimpleName() {
+        return token.isUndelimitedIdentifier && token.namePrefix == null;
+    }
+
+    boolean isDelimitedSimpleName() {
+        return token.isDelimitedIdentifier && token.namePrefix == null;
+    }
+
+    boolean isSimpleName() {
+        return isNonCoreReservedIdentifier() && token.namePrefix == null;
+    }
+
+    void checkIsSimpleName() {
+
+        if (!isSimpleName()) {
+            throw unexpectedToken();
+        }
+    }
+
+    void readUnquotedIdentifier(String ident) {
+
+        checkIsSimpleName();
+
+        if (!token.tokenString.equals(ident)) {
+            throw unexpectedToken();
+        }
+
+        read();
+    }
+
+    String readQuotedString() {
+
+        checkIsValue();
+
+        if (token.dataType.typeCode != Types.SQL_CHAR) {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        String value = token.tokenString;
+
+        read();
+
+        return value;
+    }
+
+    void readThis(int tokenId) {
+
+        if (token.tokenType != tokenId) {
+            String required = Tokens.getKeyword(tokenId);
+
+            throw unexpectedTokenRequire(required);
+        }
+
+        read();
+    }
+
+    boolean readIfThis(int tokenId) {
+
+        if (token.tokenType == tokenId) {
+            read();
+
+            return true;
+        }
+
+        return false;
+    }
+
+    Integer readIntegerObject() {
+
+        int value = readInteger();
+
+        return ValuePool.getInt(value);
+    }
+
+    int readInteger() {
+
+        boolean minus = false;
+
+        if (token.tokenType == Tokens.MINUS) {
+            minus = true;
+
+            read();
+        }
+
+        checkIsValue();
+
+        if (minus && token.dataType.typeCode == Types.SQL_BIGINT
+                && ((Number) token.tokenValue).longValue()
+                   == -(long) Integer.MIN_VALUE) {
+            read();
+
+            return Integer.MIN_VALUE;
+        }
+
+        if (token.dataType.typeCode != Types.SQL_INTEGER) {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        int val = ((Number) token.tokenValue).intValue();
+
+        if (minus) {
+            val = -val;
+        }
+
+        read();
+
+        return val;
+    }
+
+    long readBigint() {
+
+        boolean minus = false;
+
+        if (token.tokenType == Tokens.MINUS) {
+            minus = true;
+
+            read();
+        }
+
+        checkIsValue();
+
+        if (minus && token.dataType.typeCode == Types.SQL_NUMERIC
+                && LONG_MAX_VALUE_INCREMENT.equals(token.tokenValue)) {
+            read();
+
+            return Long.MIN_VALUE;
+        }
+
+        if (token.dataType.typeCode != Types.SQL_INTEGER
+                && token.dataType.typeCode != Types.SQL_BIGINT) {
+            throw Error.error(ErrorCode.X_42563);
+        }
+
+        long val = ((Number) token.tokenValue).longValue();
+
+        if (minus) {
+            val = -val;
+        }
+
+        read();
+
+        return val;
+    }
+
+    Expression readDateTimeIntervalLiteral() {
+
+        int pos = getPosition();
+
+        switch (token.tokenType) {
+
+            case Tokens.DATE : {
+                read();
+
+                if (token.tokenType != Tokens.X_VALUE
+                        || token.dataType.typeCode != Types.SQL_CHAR) {
+                    break;
+                }
+
+                String s = token.tokenString;
+
+                read();
+
+                Object date = scanner.newDate(s);
+
+                return new ExpressionValue(date, Type.SQL_DATE);
+            }
+            case Tokens.TIME : {
+                read();
+
+                if (token.tokenType != Tokens.X_VALUE
+                        || token.dataType.typeCode != Types.SQL_CHAR) {
+                    break;
+                }
+
+                String s = token.tokenString;
+
+                read();
+
+                TimeData value    = scanner.newTime(s);
+                Type     dataType = scanner.dateTimeType;
+
+                return new ExpressionValue(value, dataType);
+            }
+            case Tokens.TIMESTAMP : {
+                read();
+
+                if (token.tokenType != Tokens.X_VALUE
+                        || token.dataType.typeCode != Types.SQL_CHAR) {
+                    break;
+                }
+
+                String s = token.tokenString;
+
+                read();
+
+                Object date     = scanner.newTimestamp(s);
+                Type   dataType = scanner.dateTimeType;
+
+                return new ExpressionValue(date, dataType);
+            }
+            case Tokens.INTERVAL : {
+                boolean minus = false;
+
+                read();
+
+                if (token.tokenType == Tokens.MINUS) {
+                    read();
+
+                    minus = true;
+                } else if (token.tokenType == Tokens.PLUS) {
+                    read();
+                }
+
+                if (token.tokenType != Tokens.X_VALUE
+                        || token.dataType.typeCode != Types.SQL_CHAR) {
+                    break;
+                }
+
+                String s = token.tokenString;
+
+                read();
+
+                IntervalType dataType = readIntervalType(false);
+                Object       interval = scanner.newInterval(s, dataType);
+
+                dataType = (IntervalType) scanner.dateTimeType;
+
+                if (minus) {
+                    interval = dataType.negate(interval);
+                }
+
+                return new ExpressionValue(interval, dataType);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ParserBase");
+        }
+
+        rewind(pos);
+
+        return null;
+    }
+
+    IntervalType readIntervalType(boolean maxPrecisionDefault) {
+
+        int precision = maxPrecisionDefault ? IntervalType.maxIntervalPrecision
+                                            : -1;
+        int scale = -1;
+        int startToken;
+        int endToken;
+
+        startToken = endToken = token.tokenType;
+
+        read();
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            read();
+
+            precision = readInteger();
+
+            if (precision <= 0) {
+                throw Error.error(ErrorCode.X_42592);
+            }
+
+            if (token.tokenType == Tokens.COMMA) {
+                if (startToken != Tokens.SECOND) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                scale = readInteger();
+
+                if (scale < 0) {
+                    throw Error.error(ErrorCode.X_42592);
+                }
+            }
+
+            readThis(Tokens.CLOSEBRACKET);
+        }
+
+        if (token.tokenType == Tokens.TO) {
+            read();
+
+            endToken = token.tokenType;
+
+            read();
+        }
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            if (endToken != Tokens.SECOND || endToken == startToken) {
+                throw unexpectedToken();
+            }
+
+            read();
+
+            scale = readInteger();
+
+            if (scale < 0) {
+                throw Error.error(ErrorCode.X_42592);
+            }
+
+            readThis(Tokens.CLOSEBRACKET);
+        }
+
+        int startIndex = ArrayUtil.find(Tokens.SQL_INTERVAL_FIELD_CODES,
+                                        startToken);
+        int endIndex = ArrayUtil.find(Tokens.SQL_INTERVAL_FIELD_CODES,
+                                      endToken);
+
+        return IntervalType.getIntervalType(startIndex, endIndex, precision,
+                                            scale);
+    }
+
+    static int getExpressionType(int tokenT) {
+
+        int type = expressionTypeMap.get(tokenT, -1);
+
+        if (type == -1) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "ParserBase");
+        }
+
+        return type;
+    }
+
+    private static final IntKeyIntValueHashMap expressionTypeMap =
+        new IntKeyIntValueHashMap(37);
+
+    static {
+
+        // comparison
+        expressionTypeMap.put(Tokens.EQUALS, OpTypes.EQUAL);
+        expressionTypeMap.put(Tokens.GREATER, OpTypes.GREATER);
+        expressionTypeMap.put(Tokens.LESS, OpTypes.SMALLER);
+        expressionTypeMap.put(Tokens.GREATER_EQUALS, OpTypes.GREATER_EQUAL);
+        expressionTypeMap.put(Tokens.LESS_EQUALS, OpTypes.SMALLER_EQUAL);
+        expressionTypeMap.put(Tokens.NOT_EQUALS, OpTypes.NOT_EQUAL);
+
+        // aggregates
+        expressionTypeMap.put(Tokens.COUNT, OpTypes.COUNT);
+        expressionTypeMap.put(Tokens.MAX, OpTypes.MAX);
+        expressionTypeMap.put(Tokens.MIN, OpTypes.MIN);
+        expressionTypeMap.put(Tokens.SUM, OpTypes.SUM);
+        expressionTypeMap.put(Tokens.AVG, OpTypes.AVG);
+        expressionTypeMap.put(Tokens.EVERY, OpTypes.EVERY);
+        expressionTypeMap.put(Tokens.ANY, OpTypes.SOME);
+        expressionTypeMap.put(Tokens.SOME, OpTypes.SOME);
+        expressionTypeMap.put(Tokens.STDDEV_POP, OpTypes.STDDEV_POP);
+        expressionTypeMap.put(Tokens.STDDEV_SAMP, OpTypes.STDDEV_SAMP);
+        expressionTypeMap.put(Tokens.VAR_POP, OpTypes.VAR_POP);
+        expressionTypeMap.put(Tokens.VAR_SAMP, OpTypes.VAR_SAMP);
+    }
+
+    HsqlException unexpectedToken(String tokenS) {
+        return Error.parseError(ErrorCode.X_42581, tokenS,
+                                scanner.getLineNumber());
+    }
+
+    HsqlException unexpectedTokenRequire(String required) {
+
+        if (token.tokenType == Tokens.X_ENDPARSE) {
+            return Error.parseError(ErrorCode.X_42590,
+                                    ErrorCode.TOKEN_REQUIRED,
+                                    scanner.getLineNumber(), new Object[] {
+                "", required
+            });
+        }
+
+        String tokenS;
+
+        if (token.charsetSchema != null) {
+            tokenS = token.charsetSchema;
+        } else if (token.charsetName != null) {
+            tokenS = token.charsetName;
+        } else if (token.namePrePrefix != null) {
+            tokenS = token.namePrePrefix;
+        } else if (token.namePrefix != null) {
+            tokenS = token.namePrefix;
+        } else {
+            tokenS = token.tokenString;
+        }
+
+        return Error.parseError(ErrorCode.X_42581, ErrorCode.TOKEN_REQUIRED,
+                                scanner.getLineNumber(), new Object[] {
+            tokenS, required
+        });
+    }
+
+    HsqlException unexpectedToken() {
+
+        if (token.tokenType == Tokens.X_ENDPARSE) {
+            return Error.parseError(ErrorCode.X_42590, null,
+                                    scanner.getLineNumber());
+        }
+
+        String tokenS;
+
+        if (token.charsetSchema != null) {
+            tokenS = token.charsetSchema;
+        } else if (token.charsetName != null) {
+            tokenS = token.charsetName;
+        } else if (token.namePrePrefix != null) {
+            tokenS = token.namePrePrefix;
+        } else if (token.namePrefix != null) {
+            tokenS = token.namePrefix;
+        } else {
+            tokenS = token.tokenString;
+        }
+
+        return Error.parseError(ErrorCode.X_42581, tokenS,
+                                scanner.getLineNumber());
+    }
+
+    HsqlException tooManyIdentifiers() {
+
+        String tokenS;
+
+        if (token.namePrePrePrefix != null) {
+            tokenS = token.namePrePrePrefix;
+        } else if (token.namePrePrefix != null) {
+            tokenS = token.namePrePrefix;
+        } else if (token.namePrefix != null) {
+            tokenS = token.namePrefix;
+        } else {
+            tokenS = token.tokenString;
+        }
+
+        return Error.parseError(ErrorCode.X_42551, tokenS,
+                                scanner.getLineNumber());
+    }
+
+    HsqlException unsupportedFeature() {
+        return Error.error(ErrorCode.X_0A501, token.tokenString);
+    }
+
+    HsqlException unsupportedFeature(String string) {
+        return Error.error(ErrorCode.X_0A501, string);
+    }
+
+    public Number convertToNumber(String s, NumberType type) {
+        return scanner.convertToNumber(s, type);
+    }
+}
diff --git a/src/org/hsqldb/ParserCommand.java b/src/org/hsqldb/ParserCommand.java
new file mode 100644
index 0000000..82094c7
--- /dev/null
+++ b/src/org/hsqldb/ParserCommand.java
@@ -0,0 +1,1894 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Charset;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Parser for session and management statements
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ParserCommand extends ParserDDL {
+
+    ParserCommand(Session session, Scanner t) {
+        super(session, t);
+    }
+
+    Statement compileStatement(int props) {
+
+        Statement cs = compilePart(props);
+
+        if (token.tokenType == Tokens.X_ENDPARSE) {
+            if (cs.getSchemaName() == null) {
+                cs.setSchemaHsqlName(session.getCurrentSchemaHsqlName());
+            }
+
+            return cs;
+        }
+
+        throw unexpectedToken();
+    }
+
+    HsqlArrayList compileStatements(String sql, Result cmd) {
+
+        HsqlArrayList list = new HsqlArrayList();
+        Statement     cs   = null;
+
+        reset(sql);
+
+        while (true) {
+            if (token.tokenType == Tokens.X_ENDPARSE) {
+                break;
+            }
+
+            cs = compilePart(cmd.getExecuteProperties());
+
+            if (!cs.isExplain
+                    && cs.getParametersMetaData().getColumnCount() > 0) {
+                throw Error.error(ErrorCode.X_42575);
+            }
+
+            list.add(cs);
+        }
+
+        int returnType = cmd.getStatementType();
+
+        if (returnType != StatementTypes.RETURN_ANY) {
+            int group = cs.getGroup();
+
+            if (group == StatementTypes.X_SQL_DATA) {
+                if (returnType == StatementTypes.RETURN_COUNT) {
+                    throw Error.error(ErrorCode.X_07503);
+                }
+            } else if (returnType == StatementTypes.RETURN_RESULT) {
+                throw Error.error(ErrorCode.X_07504);
+            }
+        }
+
+        return list;
+    }
+
+    private Statement compilePart(int props) {
+
+        Statement cs;
+
+        compileContext.reset();
+        setParsePosition(getPosition());
+
+        if (token.tokenType == Tokens.X_STARTPARSE) {
+            read();
+        }
+
+        switch (token.tokenType) {
+
+            // DQL
+            case Tokens.WITH :
+            case Tokens.OPENBRACKET :
+            case Tokens.SELECT :
+            case Tokens.TABLE : {
+                cs = compileCursorSpecification(props);
+
+                break;
+            }
+            case Tokens.VALUES : {
+                cs = compileShortCursorSpecification(props);
+
+                break;
+            }
+
+            // DML
+            case Tokens.INSERT : {
+                cs = compileInsertStatement(RangeVariable.emptyArray);
+
+                break;
+            }
+            case Tokens.UPDATE : {
+                cs = compileUpdateStatement(RangeVariable.emptyArray);
+
+                break;
+            }
+            case Tokens.MERGE : {
+                cs = compileMergeStatement(RangeVariable.emptyArray);
+
+                break;
+            }
+            case Tokens.DELETE : {
+                cs = compileDeleteStatement(RangeVariable.emptyArray);
+
+                break;
+            }
+            case Tokens.TRUNCATE : {
+                cs = compileDeleteStatement(RangeVariable.emptyArray);
+
+                break;
+            }
+
+            // PROCEDURE
+            case Tokens.CALL : {
+                cs = compileCallStatement(
+                    session.sessionContext.sessionVariablesRange, false);
+
+                break;
+            }
+
+            // SQL SESSION
+            case Tokens.SET :
+                cs = compileSet();
+                break;
+
+            case Tokens.START :
+                cs = compileStartTransaction();
+                break;
+
+            case Tokens.COMMIT :
+                cs = compileCommit();
+                break;
+
+            case Tokens.ROLLBACK :
+                cs = compileRollback();
+                break;
+
+            case Tokens.SAVEPOINT :
+                cs = compileSavepoint();
+                break;
+
+            case Tokens.RELEASE :
+                cs = compileReleaseSavepoint();
+                break;
+
+            // DDL
+            case Tokens.CREATE :
+                cs = compileCreate();
+                break;
+
+            case Tokens.ALTER :
+                cs = compileAlter();
+                break;
+
+            case Tokens.DROP :
+                cs = compileDrop();
+                break;
+
+            case Tokens.GRANT :
+            case Tokens.REVOKE :
+                cs = compileGrantOrRevoke();
+                break;
+
+            case Tokens.COMMENT :
+                cs = compileComment();
+                break;
+
+            // HSQL SESSION
+            case Tokens.LOCK :
+                cs = compileLock();
+                break;
+
+            case Tokens.CONNECT :
+                cs = compileConnect();
+                break;
+
+            case Tokens.DISCONNECT :
+                cs = compileDisconnect();
+                break;
+
+            // HSQL COMMAND
+            case Tokens.SCRIPT :
+                cs = compileScript();
+                break;
+
+            case Tokens.SHUTDOWN :
+                cs = compileShutdown();
+                break;
+
+            case Tokens.BACKUP :
+                cs = compileBackup();
+                break;
+
+            case Tokens.CHECKPOINT :
+                cs = compileCheckpoint();
+                break;
+
+            case Tokens.EXPLAIN :
+                cs = compileExplainPlan();
+                break;
+
+            case Tokens.DECLARE :
+                cs = compileDeclare();
+                break;
+
+            default :
+                throw unexpectedToken();
+        }
+
+        if (cs.type != StatementTypes.SET_SESSION_AUTHORIZATION) {
+            cs.setSQL(getLastPart());
+        }
+
+        if (token.tokenType == Tokens.SEMICOLON) {
+            read();
+        } else if (token.tokenType == Tokens.X_ENDPARSE) {}
+
+        return cs;
+    }
+
+    private Statement compileDeclare() {
+
+        Statement    cs;
+        ColumnSchema variables[];
+
+        cs = compileDeclareLocalTableOrNull();
+
+        if (cs != null) {
+            return cs;
+        }
+
+        variables = readLocalVariableDeclarationOrNull();
+
+        if (variables != null) {
+            Object[] args = new Object[]{ variables };
+
+            cs = new StatementSession(StatementTypes.DECLARE_VARIABLE, args);
+
+            return cs;
+        }
+
+        cs = compileDeclareCursor();
+
+        return cs;
+    }
+
+    private Statement compileScript() {
+
+        String name = null;
+
+        read();
+
+        if (token.tokenType == Tokens.X_VALUE) {
+            name = readQuotedString();
+        }
+
+        Object[] args = new Object[]{ name };
+        Statement cs = new StatementCommand(StatementTypes.DATABASE_SCRIPT,
+                                            args);
+        HsqlName[] names =
+            database.schemaManager.getCatalogAndBaseTableNames();
+
+        cs.readTableNames = names;
+
+        return cs;
+    }
+
+    private Statement compileConnect() {
+
+        String userName;
+        String password = null;
+
+        read();
+        readThis(Tokens.USER);
+        checkIsSimpleName();
+
+        userName = token.tokenString;
+
+        read();
+        readThis(Tokens.PASSWORD);
+
+        password = readPassword();
+
+        Expression[] args = new Expression[] {
+            new ExpressionValue(userName, Type.SQL_VARCHAR),
+            new ExpressionValue(password, Type.SQL_VARCHAR)
+        };
+        Statement cs =
+            new StatementSession(StatementTypes.SET_SESSION_AUTHORIZATION,
+                                 args);
+
+        return cs;
+    }
+
+    private StatementCommand compileSetDefault() {
+
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.INITIAL : {
+                read();
+                readThis(Tokens.SCHEMA);
+
+                HsqlName schema = database.schemaManager.getSchemaHsqlName(
+                    token.tokenString);
+
+                read();
+
+                Object[] args = new Object[]{ schema };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_DEFAULT_INITIAL_SCHEMA, args);
+            }
+            case Tokens.RESULT : {
+                read();
+                readThis(Tokens.MEMORY);
+                readThis(Tokens.ROWS);
+
+                Integer  size = readIntegerObject();
+                Object[] args = new Object[]{ size };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_RESULT_MEMORY_ROWS, args);
+            }
+            case Tokens.TABLE : {
+                read();
+                readThis(Tokens.TYPE);
+
+                int type = TableBase.MEMORY_TABLE;
+
+                switch (token.tokenType) {
+
+                    case Tokens.MEMORY :
+                        break;
+
+                    case Tokens.CACHED :
+                        type = TableBase.CACHED_TABLE;
+                        break;
+
+                    default :
+                        throw unexpectedToken();
+                }
+
+                read();
+
+                Object[] args = new Object[]{ ValuePool.getInt(type) };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_DEFAULT_TABLE_TYPE, args);
+            }
+            case Tokens.ISOLATION : {
+                read();
+                readThis(Tokens.LEVEL);
+
+                int level;
+
+                switch (token.tokenType) {
+
+                    case Tokens.READ :
+                        read();
+                        readThis(Tokens.COMMITTED);
+
+                        level = SessionInterface.TX_READ_COMMITTED;
+                        break;
+
+                    case Tokens.SERIALIZABLE :
+                        read();
+
+                        level = SessionInterface.TX_SERIALIZABLE;
+                        break;
+
+                    default :
+                        throw unexpectedToken();
+                }
+
+                read();
+
+                Object[] args = new Object[]{ ValuePool.getInt(level) };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_DEFAULT_ISOLATION_LEVEL, args);
+            }
+            default :
+                throw unexpectedToken();
+        }
+    }
+
+    private StatementCommand compileSetProperty() {
+
+        read();
+
+        String                 property;
+        Object                 value;
+        HsqlDatabaseProperties props = database.getProperties();
+
+        checkIsSimpleName();
+        checkIsDelimitedIdentifier();
+
+        property = token.tokenString;
+
+        boolean isboolean  = props.isBoolean(token.tokenString);
+        boolean isintegral = props.isIntegral(token.tokenString);
+        boolean isstring   = props.isString(token.tokenString);
+
+        if (!(isboolean || isintegral || isstring)) {
+            throw Error.error(ErrorCode.X_42555, property);
+        }
+
+        int typeCode = isboolean ? Types.SQL_BOOLEAN
+                                 : isintegral ? Types.SQL_INTEGER
+                                              : Types.SQL_CHAR;
+
+        read();
+
+        if (token.tokenType == Tokens.TRUE) {
+            value = Boolean.TRUE;
+
+            if (!isboolean) {
+                throw Error.error(ErrorCode.X_42563, token.tokenString);
+            }
+        } else if (token.tokenType == Tokens.FALSE) {
+            value = Boolean.FALSE;
+
+            if (!isboolean) {
+                throw Error.error(ErrorCode.X_42563, token.tokenString);
+            }
+        } else {
+            checkIsValue();
+
+            value = token.tokenValue;
+
+            if (token.dataType.typeCode != typeCode) {
+                throw Error.error(ErrorCode.X_42563, token.tokenString);
+            }
+        }
+
+        read();
+
+        Object[] args = new Object[] {
+            property, value
+        };
+
+        return new StatementCommand(StatementTypes.SET_DATABASE_PROPERTY,
+                                    args);
+    }
+
+    private Statement compileSet() {
+
+        int position = super.getPosition();
+
+        session.setScripting(false);
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.CATALOG : {
+                read();
+
+                Expression e = XreadValueSpecificationOrNull();
+
+                if (e == null) {
+                    HsqlName name = readSchemaName();
+                    Object[] args = new Object[]{ name };
+
+                    return new StatementSession(StatementTypes.SET_CATALOG,
+                                                args);
+                }
+
+                if (!e.getDataType().isCharacterType()) {
+                    throw Error.error(ErrorCode.X_0P000);
+                }
+
+                if (e.getType() != OpTypes.VALUE
+                        && (e.getType() != OpTypes.SQL_FUNCTION
+                            || !((FunctionSQL) e).isValueFunction())) {
+                    throw Error.error(ErrorCode.X_0P000);
+                }
+
+                Expression[] args = new Expression[]{ e };
+
+                return new StatementSession(StatementTypes.SET_CATALOG, args);
+            }
+            case Tokens.SCHEMA : {
+                read();
+
+                Expression e = XreadValueSpecificationOrNull();
+
+                if (e == null) {
+                    HsqlName name = readSchemaName();
+                    Object[] args = new Object[]{ name };
+
+                    return new StatementSession(StatementTypes.SET_SCHEMA,
+                                                args);
+                }
+
+                if (!e.getDataType().isCharacterType()) {
+                    throw Error.error(ErrorCode.X_0P000);
+                }
+
+                if (e.getType() != OpTypes.VALUE
+                        && (e.getType() != OpTypes.SQL_FUNCTION
+                            || !((FunctionSQL) e).isValueFunction())) {
+                    throw Error.error(ErrorCode.X_0P000);
+                }
+
+                Expression[] args = new Expression[]{ e };
+
+                return new StatementSession(StatementTypes.SET_SCHEMA, args);
+            }
+            case Tokens.TIME : {
+                read();
+
+                return compileSetTimeZone();
+            }
+            case Tokens.ROLE : {
+                read();
+
+                return compileSetRole();
+            }
+            case Tokens.SESSION : {
+                read();
+
+                return compileSessionSettings();
+            }
+            case Tokens.TRANSACTION : {
+                read();
+
+                Object[] args = processTransactionCharacteristics();
+
+                if (args[0] == null && args[1] == null) {
+                    throw unexpectedToken();
+                }
+
+                return new StatementSession(StatementTypes.SET_TRANSACTION,
+                                            args);
+            }
+            case Tokens.AUTOCOMMIT : {
+                read();
+
+                Boolean  mode = processTrueOrFalseObject();
+                Object[] args = new Object[]{ mode };
+
+                return new StatementSession(
+                    StatementTypes.SET_SESSION_AUTOCOMMIT, args);
+            }
+
+            // deprecated
+            case Tokens.READONLY : {
+                read();
+
+                Boolean  readonly = processTrueOrFalseObject();
+                Object[] args     = new Object[]{ readonly };
+
+                return new StatementSession(
+                    StatementTypes.SET_SESSION_CHARACTERISTICS, args);
+            }
+            case Tokens.IGNORECASE : {
+                read();
+
+                Boolean  mode = processTrueOrFalseObject();
+                Object[] args = new Object[]{ mode };
+
+                return new StatementSession(
+                    StatementTypes.SET_SESSION_SQL_IGNORECASE, args);
+            }
+            case Tokens.MAXROWS : {
+                read();
+
+                Integer  size = readIntegerObject();
+                Object[] args = new Object[]{ size };
+
+                return new StatementSession(
+                    StatementTypes.SET_SESSION_RESULT_MAX_ROWS, args);
+            }
+
+            // for backward compatibility
+            case Tokens.DEFAULT : {
+                read();
+                readThis(Tokens.TABLE);
+                readThis(Tokens.TYPE);
+
+                int type = TableBase.MEMORY_TABLE;
+
+                switch (token.tokenType) {
+
+                    case Tokens.MEMORY :
+                        break;
+
+                    case Tokens.CACHED :
+                        type = TableBase.CACHED_TABLE;
+                        break;
+
+                    default :
+                        throw unexpectedToken();
+                }
+
+                read();
+
+                Object[] args = new Object[]{ ValuePool.getInt(type) };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_DEFAULT_TABLE_TYPE, args);
+            }
+            case Tokens.TABLE : {
+                read();
+
+                Table    t    = readTableName();
+                Object[] args = new Object[] {
+                    t.getName(), null
+                };
+
+                switch (token.tokenType) {
+
+                    default : {
+                        throw unexpectedToken();
+                    }
+                    case Tokens.SOURCE :
+                        read();
+
+                        return compileTextTableSource(t);
+
+                    case Tokens.READ : {
+                        read();
+
+                        boolean readonly = false;
+
+                        if (token.tokenType == Tokens.WRITE) {
+                            read();
+                        } else {
+                            readThis(Tokens.ONLY);
+
+                            readonly = true;
+                        }
+
+                        args[1] = Boolean.valueOf(readonly);
+
+                        return new StatementCommand(
+                            StatementTypes.SET_TABLE_READONLY, args, null,
+                            t.getName());
+                    }
+
+                    // deprecated
+                    case Tokens.READONLY : {
+                        read();
+
+                        Boolean readonly = processTrueOrFalseObject();
+
+                        args[1] = readonly;
+
+                        return new StatementCommand(
+                            StatementTypes.SET_TABLE_READONLY, args, null,
+                            t.getName());
+                    }
+                    case Tokens.INDEX : {
+                        String value;
+
+                        read();
+                        checkIsValue();
+
+                        value = token.tokenString;
+
+                        read();
+
+                        args[1] = value;
+
+                        return new StatementCommand(
+                            StatementTypes.SET_TABLE_INDEX, args);
+                    }
+                    case Tokens.TYPE : {
+                        read();
+
+                        int newType;
+
+                        if (token.tokenType == Tokens.CACHED) {
+                            newType = TableBase.CACHED_TABLE;
+                        } else if (token.tokenType == Tokens.MEMORY) {
+                            newType = TableBase.MEMORY_TABLE;
+                        } else {
+                            throw super.unexpectedToken();
+                        }
+
+                        read();
+
+                        args[1] = new Integer(newType);
+
+                        return new StatementCommand(
+                            StatementTypes.SET_TABLE_TYPE, args, null,
+                            t.getName());
+                    }
+                }
+            }
+/*
+            case Tokens.CHECKPOINT : {
+                read();
+                readThis(Tokens.DEFRAG);
+
+                int      size = readInteger();
+                Object[] args = new Object[]{ new Integer(size) };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_FILES_DEFRAG, args, null,
+                    null);
+            }
+*/
+            case Tokens.WRITE_DELAY : {
+                read();
+
+                int delay = 0;
+
+                if (token.tokenType == Tokens.TRUE) {
+                    delay = database.getProperties().getDefaultWriteDelay();
+
+                    read();
+                } else if (token.tokenType == Tokens.FALSE) {
+                    delay = 0;
+
+                    read();
+                } else {
+                    delay = this.readInteger();
+
+                    if (delay < 0) {
+                        delay = 0;
+                    }
+
+                    if (token.tokenType == Tokens.MILLIS) {
+                        read();
+                    } else {
+                        delay *= 1000;
+                    }
+                }
+
+                Object[] args = new Object[]{ new Integer(delay) };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_FILES_WRITE_DELAY, args, null,
+                    null);
+            }
+            case Tokens.PASSWORD : {
+                String password;
+
+                read();
+
+                password = readPassword();
+
+                Object[] args = new Object[] {
+                    null, password
+                };
+
+                return new StatementCommand(StatementTypes.SET_USER_PASSWORD,
+                                            args);
+            }
+            case Tokens.INITIAL : {
+                read();
+                readThis(Tokens.SCHEMA);
+
+                HsqlName schema;
+
+                if (token.tokenType == Tokens.DEFAULT) {
+                    schema = null;
+                } else {
+                    schema = database.schemaManager.getSchemaHsqlName(
+                        token.tokenString);
+                }
+
+                read();
+
+                Object[] args = new Object[] {
+                    null, schema
+                };
+
+                return new StatementCommand(
+                    StatementTypes.SET_USER_INITIAL_SCHEMA, args);
+            }
+            case Tokens.FILES : {
+                return compileSetFilesProperty();
+            }
+            case Tokens.DATABASE : {
+                return compileSetDatabaseProperty();
+            }
+            case Tokens.PROPERTY : {
+                return compileSetProperty();
+            }
+            default : {
+                rewind(position);
+
+                return compileSetStatement(
+                    session.sessionContext.sessionVariablesRange);
+            }
+        }
+    }
+
+    StatementCommand compileSetDatabaseProperty() {
+
+        read();
+
+        String name;
+
+        checkDatabaseUpdateAuthorisation();
+
+        switch (token.tokenType) {
+
+            case Tokens.COLLATION : {
+                read();
+                checkIsSimpleName();
+
+                name = token.tokenString;
+
+                read();
+
+                Object[] args = new Object[]{ name };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_SQL_COLLATION, args, null,
+                    null);
+            }
+            case Tokens.DEFAULT : {
+                return compileSetDefault();
+            }
+            case Tokens.EVENT : {
+                read();
+                readThis(Tokens.LOG);
+                readThis(Tokens.LEVEL);
+
+                Integer  value = readIntegerObject();
+                Object[] args  = new Object[]{ value };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_FILES_EVENT_LOG, args, null,
+                    null);
+            }
+            case Tokens.GC : {
+                read();
+
+                Integer  size = readIntegerObject();
+                Object[] args = new Object[]{ size };
+
+                return new StatementCommand(StatementTypes.SET_DATABASE_GC,
+                                            args, null, null);
+            }
+            case Tokens.REFERENTIAL : {
+                read();
+                readThis(Tokens.INTEGRITY);
+
+                boolean  mode = processTrueOrFalse();
+                Object[] args = new Object[]{ Boolean.valueOf(mode) };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_SQL_REFERENTIAL_INTEGRITY,
+                    args, null, null);
+            }
+            case Tokens.SQL : {
+                read();
+
+                int     type = 0;
+                Boolean flag = null;
+
+                switch (token.tokenType) {
+
+                    case Tokens.REFERENCES :
+                        read();
+
+                        type = StatementTypes.SET_DATABASE_SQL_REFERENCES;
+                        flag = processTrueOrFalseObject();
+                        break;
+
+
+                    case Tokens.SIZE :
+                        read();
+
+                        type = StatementTypes.SET_DATABASE_SQL_STRICT_SIZE;
+                        flag = processTrueOrFalseObject();
+                        break;
+
+                    case Tokens.NAMES :
+                        read();
+
+                        type = StatementTypes.SET_DATABASE_SQL_STRICT_NAMES;
+                        flag = processTrueOrFalseObject();
+                        break;
+
+                    default :
+                        unexpectedToken();
+                }
+
+                Object[] args = new Object[]{ flag };
+
+                return new StatementCommand(type, args, null, null);
+            }
+            case Tokens.TEXT : {
+                read();
+                readThis(Tokens.TABLE);
+                readThis(Tokens.DEFAULTS);
+
+                String   source = readQuotedString();
+                Object[] args   = new Object[]{ source };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_TEXT_SOURCE, args, null, null);
+            }
+            case Tokens.TRANSACTION : {
+                read();
+                readThis(Tokens.CONTROL);
+
+                int mode = TransactionManager.LOCKS;
+
+                switch (token.tokenType) {
+
+                    case Tokens.MVCC :
+                        read();
+
+                        mode = TransactionManager.MVCC;
+                        break;
+
+                    case Tokens.MVLOCKS :
+                        read();
+
+                        mode = TransactionManager.MVLOCKS;
+                        break;
+
+                    case Tokens.LOCKS :
+                        read();
+
+                        mode = TransactionManager.LOCKS;
+                        break;
+                }
+
+                Object[] args = new Object[]{ ValuePool.getInt(mode) };
+                StatementCommand cs = new StatementCommand(
+                    StatementTypes.SET_DATABASE_TRANSACTION_CONTROL, args,
+                    null, null);
+                HsqlName[] names =
+                    database.schemaManager.getCatalogAndBaseTableNames();
+
+                cs.writeTableNames = names;
+
+                return cs;
+            }
+            case Tokens.UNIQUE : {
+                read();
+                readThis(Tokens.NAME);
+                isUndelimitedSimpleName();
+
+                name = token.tokenString;
+
+                read();
+
+                /** @todo - only digits, letters and underscore */
+                if (name.length() != 16) {
+                    throw Error.error(ErrorCode.X_42555);
+                }
+
+                if (!Charset.isInSet(name, Charset.unquotedIdentifier)
+                        || !Charset.startsWith(name,
+                                               Charset.uppercaseLetters)) {
+                    throw Error.error(ErrorCode.X_42501);
+                }
+
+                Object[] args = new Object[]{ name };
+
+                return new StatementCommand(
+                    StatementTypes.SET_DATABASE_UNIQUE_NAME, args, null, null);
+            }
+            default : {
+                throw unexpectedToken();
+            }
+        }
+    }
+
+    StatementCommand compileSetFilesProperty() {
+
+        read();
+
+        String  name;
+        int     type  = 0;
+        Boolean flag  = null;
+        Integer value = null;
+
+        checkDatabaseUpdateAuthorisation();
+
+        switch (token.tokenType) {
+
+            case Tokens.LOCK : {
+                read();
+
+                flag = processTrueOrFalseObject();
+                type = StatementTypes.SET_DATABASE_FILES_LOCK;
+
+                break;
+            }
+            case Tokens.CACHE : {
+                read();
+
+                if (readIfThis(Tokens.SIZE)) {
+                    value = readIntegerObject();
+                    type  = StatementTypes.SET_DATABASE_FILES_CACHE_SIZE;
+                } else if (readIfThis(Tokens.ROWS)) {
+                    value = readIntegerObject();
+                    type  = StatementTypes.SET_DATABASE_FILES_CACHE_ROWS;
+                }
+
+                break;
+            }
+            case Tokens.SCALE : {
+                read();
+
+                value = readIntegerObject();
+                type  = StatementTypes.SET_DATABASE_FILES_SCALE;
+
+                break;
+            }
+            case Tokens.LOB : {
+                read();
+                readThis(Tokens.SCALE);
+
+                value = readIntegerObject();
+                type  = StatementTypes.SET_DATABASE_FILES_LOBS_SCALE;
+
+                break;
+            }
+            case Tokens.DEFRAG : {
+                read();
+
+                type  = StatementTypes.SET_DATABASE_FILES_DEFRAG;
+                value = readIntegerObject();
+
+                break;
+            }
+            case Tokens.NIO : {
+                read();
+
+                type = StatementTypes.SET_DATABASE_FILES_NIO;
+                flag = processTrueOrFalseObject();
+
+                break;
+            }
+            case Tokens.BACKUP : {
+                read();
+
+                type = StatementTypes.SET_DATABASE_FILES_BACKUP_INCREMENT;
+
+                readThis(Tokens.INCREMENT);
+
+                flag = processTrueOrFalseObject();
+
+                break;
+            }
+            case Tokens.LOG : {
+                read();
+
+                if (token.tokenType == Tokens.SIZE) {
+                    readThis(Tokens.SIZE);
+
+                    type  = StatementTypes.SET_DATABASE_FILES_LOG_SIZE;
+                    value = readIntegerObject();
+                } else {
+                    type = StatementTypes.SET_DATABASE_FILES_LOG;
+                    flag = processTrueOrFalseObject();
+                }
+
+                break;
+            }
+            case Tokens.TEMP : {
+                read();
+                readThis(Tokens.PATH);
+
+                type  = StatementTypes.SET_DATABASE_FILES_TEMP_PATH;
+                value = readIntegerObject();
+
+                break;
+            }
+            case Tokens.WRITE : {
+                read();
+                readThis(Tokens.DELAY);
+
+                type = StatementTypes.SET_DATABASE_FILES_WRITE_DELAY;
+
+                int delay = 0;
+
+                if (token.tokenType == Tokens.TRUE) {
+                    delay = database.getProperties().getDefaultWriteDelay();
+
+                    read();
+                } else if (token.tokenType == Tokens.FALSE) {
+                    delay = 0;
+
+                    read();
+                } else {
+                    delay = this.readInteger();
+
+                    if (delay < 0) {
+                        delay = 0;
+                    }
+
+                    if (token.tokenType == Tokens.MILLIS) {
+                        read();
+                    } else {
+                        delay *= 1000;
+                    }
+                }
+
+                value = new Integer(delay);
+
+                break;
+            }
+            default :
+                throw unexpectedToken();
+        }
+
+        Object[] args = new Object[]{ flag == null ? (Object) value
+                                                   : (Object) flag };
+
+        return new StatementCommand(type, args, database.getCatalogName(),
+                                    null);
+    }
+
+    Object[] processTransactionCharacteristics() {
+
+        int      level    = 0;
+        boolean  readonly = false;
+        Object[] args     = new Object[2];
+
+        outerloop:
+        while (true) {
+            switch (token.tokenType) {
+
+                case Tokens.READ : {
+                    if (args[0] != null) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    if (token.tokenType == Tokens.ONLY) {
+                        read();
+
+                        readonly = true;
+                    } else {
+                        readThis(Tokens.WRITE);
+
+                        readonly = false;
+                    }
+
+                    args[0] = Boolean.valueOf(readonly);
+
+                    break;
+                }
+                case Tokens.ISOLATION : {
+                    if (args[1] != null) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.LEVEL);
+
+                    switch (token.tokenType) {
+
+                        case Tokens.SERIALIZABLE :
+                            read();
+
+                            level = SessionInterface.TX_SERIALIZABLE;
+                            break;
+
+                        case Tokens.READ :
+                            read();
+
+                            if (token.tokenType == Tokens.COMMITTED) {
+                                read();
+
+                                level = SessionInterface.TX_READ_COMMITTED;
+                            } else if (token.tokenType == Tokens.UNCOMMITTED) {
+                                read();
+
+                                level = SessionInterface.TX_READ_UNCOMMITTED;
+                            } else {
+                                throw unexpectedToken();
+                            }
+                            break;
+
+                        case Tokens.REPEATABLE :
+                            read();
+                            readThis(Tokens.READ);
+
+                            level = SessionInterface.TX_REPEATABLE_READ;
+                            break;
+
+                        default :
+                            throw unexpectedToken();
+                    }
+
+                    args[1] = new Integer(level);
+
+                    break;
+                }
+                case Tokens.COMMA : {
+                    if (args[0] == null && args[1] == null) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    break;
+                }
+                default : {
+                    break outerloop;
+                }
+            }
+        }
+
+        if (!readonly && level == 1) {
+            throw unexpectedToken(Tokens.T_WRITE);
+        }
+
+        return args;
+    }
+
+    /**
+     * Retrieves boolean value corresponding to the next token.
+     *
+     * @return   true if next token is "TRUE"; false if next token is "FALSE"
+     * @throws  HsqlException if the next token is neither "TRUE" or "FALSE"
+     */
+    private boolean processTrueOrFalse() {
+
+        if (token.namePrefix != null) {
+            throw unexpectedToken();
+        }
+
+        if (token.tokenType == Tokens.TRUE) {
+            read();
+
+            return true;
+        } else if (token.tokenType == Tokens.FALSE) {
+            read();
+
+            return false;
+        } else {
+            throw unexpectedToken();
+        }
+    }
+
+    private Boolean processTrueOrFalseObject() {
+
+        if (token.namePrefix != null) {
+            throw unexpectedToken();
+        }
+
+        if (token.tokenType == Tokens.TRUE) {
+            read();
+
+            return Boolean.TRUE;
+        } else if (token.tokenType == Tokens.FALSE) {
+            read();
+
+            return Boolean.FALSE;
+        } else {
+            throw unexpectedToken();
+        }
+    }
+
+    /**
+     * Responsible for  handling the execution of COMMIT [WORK]
+     *
+     * @throws  HsqlException
+     */
+    private Statement compileCommit() {
+
+        boolean chain = false;
+
+        read();
+        readIfThis(Tokens.WORK);
+
+        if (token.tokenType == Tokens.AND) {
+            read();
+
+            if (token.tokenType == Tokens.NO) {
+                read();
+            } else {
+                chain = true;
+            }
+
+            readThis(Tokens.CHAIN);
+        }
+
+        String    sql  = getLastPart();
+        Object[]  args = new Object[]{ Boolean.valueOf(chain) };
+        Statement cs = new StatementSession(StatementTypes.COMMIT_WORK, args);
+
+        return cs;
+    }
+
+    private Statement compileStartTransaction() {
+
+        read();
+        readThis(Tokens.TRANSACTION);
+
+        Object[] args = processTransactionCharacteristics();
+        Statement cs = new StatementSession(StatementTypes.START_TRANSACTION,
+                                            args);
+
+        return cs;
+    }
+
+    private Statement compileLock() {
+
+        read();
+        readThis(Tokens.TABLE);
+
+        OrderedHashSet readSet  = new OrderedHashSet();
+        OrderedHashSet writeSet = new OrderedHashSet();
+
+        outerloop:
+        while (true) {
+            Table table = readTableName();
+
+            switch (token.tokenType) {
+
+                case Tokens.READ :
+                    read();
+                    readSet.add(table.getName());
+                    break;
+
+                case Tokens.WRITE :
+                    read();
+                    writeSet.add(table.getName());
+                    break;
+
+                default :
+                    throw unexpectedToken();
+            }
+
+            if (token.tokenType == Tokens.COMMA) {
+                read();
+
+                continue;
+            }
+
+            break outerloop;
+        }
+
+        HsqlName[] writeTableNames = new HsqlName[writeSet.size()];
+
+        writeSet.toArray(writeTableNames);
+        readSet.removeAll(writeTableNames);
+
+        HsqlName[] readTableNames = new HsqlName[readSet.size()];
+
+        readSet.toArray(readTableNames);
+
+        Statement cs =
+            new StatementSession(StatementTypes.TRANSACTION_LOCK_TABLE,
+                                 readTableNames, writeTableNames);
+
+        return cs;
+    }
+
+    private Statement compileRollback() {
+
+        boolean chain     = false;
+        String  savepoint = null;
+
+        read();
+
+        if (token.tokenType == Tokens.TO) {
+            read();
+            readThis(Tokens.SAVEPOINT);
+            checkIsSimpleName();
+
+            savepoint = token.tokenString;
+
+            read();
+
+            String   sql  = getLastPart();
+            Object[] args = new Object[]{ savepoint };
+            Statement cs =
+                new StatementSession(StatementTypes.ROLLBACK_SAVEPOINT, args);
+
+            return cs;
+        } else {
+            if (token.tokenType == Tokens.WORK) {
+                read();
+            }
+
+            if (token.tokenType == Tokens.AND) {
+                read();
+
+                if (token.tokenType == Tokens.NO) {
+                    read();
+                } else {
+                    chain = true;
+                }
+
+                readThis(Tokens.CHAIN);
+            }
+        }
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ Boolean.valueOf(chain) };
+        Statement cs = new StatementSession(StatementTypes.ROLLBACK_WORK,
+                                            args);
+
+        return cs;
+    }
+
+    private Statement compileSavepoint() {
+
+        String name;
+
+        read();
+        checkIsSimpleName();
+
+        name = token.tokenString;
+
+        read();
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ name };
+
+        return new StatementSession(StatementTypes.SAVEPOINT, args);
+    }
+
+    private Statement compileReleaseSavepoint() {
+
+        read();
+        readThis(Tokens.SAVEPOINT);
+
+        String name = token.tokenString;
+
+        read();
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ name };
+
+        return new StatementSession(StatementTypes.RELEASE_SAVEPOINT, args);
+    }
+
+    private Statement compileSessionSettings() {
+
+        switch (token.tokenType) {
+
+            case Tokens.CHARACTERISTICS : {
+                read();
+                readThis(Tokens.AS);
+                readThis(Tokens.TRANSACTION);
+
+                Object[] args = processTransactionCharacteristics();
+
+                return new StatementSession(
+                    StatementTypes.SET_SESSION_CHARACTERISTICS, args);
+            }
+            case Tokens.AUTHORIZATION : {
+                read();
+
+                Expression e = XreadValueSpecificationOrNull();
+
+                if (e == null) {
+                    throw Error.error(ErrorCode.X_42584);
+                }
+
+                e.resolveTypes(session, null);
+
+                if (e.isUnresolvedParam()) {
+                    e.dataType = Type.SQL_VARCHAR;
+                }
+
+                if (e.dataType == null || !e.dataType.isCharacterType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                Expression[] args = new Expression[] {
+                    e, null
+                };
+
+                return new StatementSession(
+                    StatementTypes.SET_SESSION_AUTHORIZATION, args);
+            }
+            case Tokens.RESULT : {
+                read();
+                readThis(Tokens.MEMORY);
+                readThis(Tokens.ROWS);
+
+                Integer  size = readIntegerObject();
+                Object[] args = new Object[]{ size };
+
+                return new StatementCommand(
+                    StatementTypes.SET_SESSION_RESULT_MEMORY_ROWS, args);
+            }
+            default :
+                throw unexpectedToken();
+        }
+    }
+
+    private Statement compileSetRole() {
+
+        Expression e;
+
+        if (token.tokenType == Tokens.NONE) {
+            read();
+
+            e = new ExpressionValue(null, Type.SQL_VARCHAR);
+        } else {
+            e = XreadValueSpecificationOrNull();
+
+            if (e == null) {
+                throw Error.error(ErrorCode.X_2A000);
+            }
+
+            if (!e.getDataType().isCharacterType()) {
+                throw Error.error(ErrorCode.X_0P000);
+            }
+
+            if (e.getType() != OpTypes.VALUE
+                    && (e.getType() != OpTypes.SQL_FUNCTION
+                        || !((FunctionSQL) e).isValueFunction())) {
+                throw Error.error(ErrorCode.X_0P000);
+            }
+        }
+
+        String sql = getLastPart();
+
+        return new StatementSession(StatementTypes.SET_ROLE,
+                                    new Expression[]{ e });
+    }
+
+    private Statement compileSetTimeZone() {
+
+        Expression e;
+
+        readThis(Tokens.ZONE);
+
+        if (token.tokenType == Tokens.LOCAL) {
+            read();
+
+            e = new ExpressionValue(null, Type.SQL_INTERVAL_HOUR_TO_MINUTE);
+        } else {
+            e = XreadIntervalValueExpression();
+
+            HsqlList unresolved =
+                e.resolveColumnReferences(RangeVariable.emptyArray, null);
+
+            ExpressionColumn.checkColumnsResolved(unresolved);
+            e.resolveTypes(session, null);
+
+            if (e.dataType == null) {
+                throw Error.error(ErrorCode.X_42563);
+            }
+
+            if (e.dataType.typeCode != Types.SQL_INTERVAL_HOUR_TO_MINUTE) {
+                throw Error.error(ErrorCode.X_42563);
+            }
+        }
+
+        String sql = getLastPart();
+
+        return new StatementSession(StatementTypes.SET_TIME_ZONE,
+                                    new Expression[]{ e });
+    }
+
+    private Statement compileShutdown() {
+
+        int closemode;
+
+        session.checkAdmin();
+
+        closemode = Database.CLOSEMODE_NORMAL;
+
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.IMMEDIATELY :
+                closemode = Database.CLOSEMODE_IMMEDIATELY;
+
+                read();
+                break;
+
+            case Tokens.COMPACT :
+                closemode = Database.CLOSEMODE_COMPACT;
+
+                read();
+                break;
+
+            case Tokens.SCRIPT :
+                closemode = Database.CLOSEMODE_SCRIPT;
+
+                read();
+                break;
+
+            // only semicolon is accepted here
+        }
+
+        if (token.tokenType == Tokens.SEMICOLON) {
+            read();
+        }
+
+        if (token.tokenType != Tokens.X_ENDPARSE) {
+            throw unexpectedToken();
+        }
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ new Integer(closemode) };
+        Statement cs = new StatementCommand(StatementTypes.DATABASE_SHUTDOWN,
+                                            args, null, null);
+
+        return cs;
+    }
+
+    private Statement compileBackup() {
+
+        read();
+        readThis(Tokens.DATABASE);
+        readThis(Tokens.TO);
+
+        String  path         = readQuotedString();
+        Boolean blockingMode = null;    // Default to non-blocking
+        Boolean scriptMode   = null;    // Default to non-script
+        Boolean compression  = null;    // Defaults to compressed
+
+        outerLoop:
+        while (true) {
+            switch (token.tokenType) {
+
+                case Tokens.BLOCKING :
+                    if (blockingMode != null) {
+                        throw unexpectedToken();
+                    }
+
+                    blockingMode = Boolean.TRUE;
+
+                    read();
+                    break;
+
+                case Tokens.SCRIPT :
+                    if (scriptMode != null) {
+                        throw unexpectedToken();
+                    }
+
+                    scriptMode = Boolean.TRUE;
+
+                    read();
+                    break;
+
+                case Tokens.COMPRESSED :
+                    if (compression != null) {
+                        throw unexpectedToken();
+                    }
+
+                    compression = Boolean.TRUE;
+
+                    read();
+                    break;
+
+                case Tokens.NOT :
+                    read();
+
+                    if (token.tokenType == Tokens.COMPRESSED) {
+                        if (compression != null) {
+                            throw unexpectedToken();
+                        }
+
+                        compression = Boolean.FALSE;
+
+                        read();
+                    } else if (token.tokenType == Tokens.BLOCKING) {
+                        blockingMode = Boolean.FALSE;
+
+                        read();
+                    } else {
+                        throw unexpectedToken();
+                    }
+                    break;
+
+                default :
+                    break outerLoop;
+            }
+        }
+
+        /**
+         * @todo: This block is TEMPORARY.  Will be removed when we implement
+         * Non-Blocking and SCRIPT mode.
+         */
+        if (scriptMode != null) {
+            throw unsupportedFeature("SCRIPT");
+        }
+
+        scriptMode = Boolean.FALSE;
+
+        if (blockingMode == null) {
+            throw unexpectedTokenRequire("BLOCKING");
+        }
+
+        if (compression == null) {
+            compression = Boolean.TRUE;
+        }
+
+        Object[] args = new Object[] {
+            path, blockingMode, scriptMode, compression,
+        };
+        Statement cs = new StatementCommand(StatementTypes.DATABASE_BACKUP,
+                                            args);
+        HsqlName[] names =
+            database.schemaManager.getCatalogAndBaseTableNames();
+
+        cs.writeTableNames = names;
+
+        return cs;
+    }
+
+    private Statement compileCheckpoint() {
+
+        boolean defrag = false;
+
+        read();
+
+        if (token.tokenType == Tokens.DEFRAG) {
+            defrag = true;
+
+            read();
+        } else if (token.tokenType == Tokens.SEMICOLON) {
+            read();
+
+            // only semicolon is accepted here
+        }
+
+        if (token.tokenType != Tokens.X_ENDPARSE) {
+            throw unexpectedToken();
+        }
+
+        String sql = getLastPart();
+
+        return getCheckpointStatement(database, defrag);
+    }
+
+    public static Statement getCheckpointStatement(Database database,
+            boolean defrag) {
+
+        Object[] args = new Object[]{ Boolean.valueOf(defrag) };
+        Statement cs = new StatementCommand(StatementTypes.DATABASE_CHECKPOINT,
+                                            args);
+        HsqlName[] names =
+            database.schemaManager.getCatalogAndBaseTableNames();
+
+        cs.writeTableNames = names;
+
+        return cs;
+    }
+
+    private Statement compileDisconnect() {
+
+        read();
+
+        String sql = Tokens.T_DISCONNECT;
+        Statement cs = new StatementSession(StatementTypes.DISCONNECT,
+                                            (Object[]) null);
+
+        return cs;
+    }
+
+    private Statement compileExplainPlan() {
+
+        Statement cs;
+
+        read();
+        readThis(Tokens.PLAN);
+        readThis(Tokens.FOR);
+
+        cs = compilePart(ResultProperties.defaultPropsValue);
+
+        cs.setDescribe();
+
+        return cs;
+    }
+
+    private Statement compileTextTableSource(Table t) {
+
+        boolean  isSourceHeader = false;
+        boolean  isDesc         = false;
+        String   source;
+        Object[] args = new Object[5];
+
+        args[0] = t.getName();
+
+        if (!t.isText()) {
+            Exception e = Error.error(ErrorCode.X_S0522);
+        }
+
+        // SET TABLE <table> SOURCE ON
+        if (token.tokenType == Tokens.ON) {
+            read();
+
+            String sql = getLastPart();
+
+            args[1] = Boolean.TRUE;
+
+            return new StatementCommand(StatementTypes.SET_TABLE_SOURCE, args,
+                                        null, t.getName());
+        } else if (token.tokenType == Tokens.OFF) {
+            read();
+
+            String sql = getLastPart();
+
+            args[1] = Boolean.FALSE;
+
+            return new StatementCommand(StatementTypes.SET_TABLE_SOURCE, args,
+                                        null, t.getName());
+        } else if (token.tokenType == Tokens.HEADER) {
+            read();
+
+            isSourceHeader = true;
+        }
+
+        if (token.tokenType == Tokens.X_DELIMITED_IDENTIFIER) {
+            source = token.tokenString;
+
+            read();
+        } else {
+            source = readQuotedString();
+        }
+
+        if (!isSourceHeader && token.tokenType == Tokens.DESC) {
+            isDesc = true;
+
+            read();
+        }
+
+        String sql = getLastPart();
+
+        args[2] = source;
+        args[3] = Boolean.valueOf(isDesc);
+        args[4] = Boolean.valueOf(isSourceHeader);
+
+        int type = isSourceHeader ? StatementTypes.SET_TABLE_SOURCE_HEADER
+                                  : StatementTypes.SET_TABLE_SOURCE;
+
+        return new StatementCommand(type, args, null, t.getName());
+    }
+}
diff --git a/src/org/hsqldb/ParserDDL.java b/src/org/hsqldb/ParserDDL.java
new file mode 100644
index 0000000..de493c2
--- /dev/null
+++ b/src/org/hsqldb/ParserDDL.java
@@ -0,0 +1,5033 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.lang.reflect.Method;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.rights.GranteeManager;
+import org.hsqldb.rights.Right;
+import org.hsqldb.rights.User;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Charset;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.UserTypeModifier;
+
+/**
+ * Parser for DDL statements
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ParserDDL extends ParserRoutine {
+
+    final static int[]   schemaCommands             = new int[] {
+        Tokens.CREATE, Tokens.GRANT
+    };
+    final static short[] startStatementTokens       = new short[] {
+        Tokens.CREATE, Tokens.GRANT, Tokens.ALTER, Tokens.DROP
+    };
+    final static short[] startStatementTokensSchema = new short[] {
+        Tokens.CREATE, Tokens.GRANT,
+    };
+
+    ParserDDL(Session session, Scanner scanner) {
+        super(session, scanner);
+    }
+
+    void reset(String sql) {
+        super.reset(sql);
+    }
+
+    StatementSchema compileCreate() {
+
+        int     tableType = TableBase.MEMORY_TABLE;
+        boolean isTable   = false;
+
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.GLOBAL :
+                read();
+                readThis(Tokens.TEMPORARY);
+                readIfThis(Tokens.MEMORY);
+                readThis(Tokens.TABLE);
+
+                isTable   = true;
+                tableType = TableBase.TEMP_TABLE;
+                break;
+
+            case Tokens.TEMP :
+                read();
+                readThis(Tokens.TABLE);
+
+                isTable   = true;
+                tableType = TableBase.TEMP_TABLE;
+                break;
+
+            case Tokens.TEMPORARY :
+                read();
+                readThis(Tokens.TABLE);
+
+                isTable   = true;
+                tableType = TableBase.TEMP_TABLE;
+                break;
+
+            case Tokens.MEMORY :
+                read();
+                readThis(Tokens.TABLE);
+
+                isTable = true;
+                break;
+
+            case Tokens.CACHED :
+                read();
+                readThis(Tokens.TABLE);
+
+                isTable   = true;
+                tableType = TableBase.CACHED_TABLE;
+                break;
+
+            case Tokens.TEXT :
+                read();
+                readThis(Tokens.TABLE);
+
+                isTable   = true;
+                tableType = TableBase.TEXT_TABLE;
+                break;
+
+            case Tokens.TABLE :
+                read();
+
+                isTable   = true;
+                tableType = database.schemaManager.getDefaultTableType();
+                break;
+
+            default :
+        }
+
+        if (isTable) {
+            return compileCreateTable(tableType);
+        }
+
+        switch (token.tokenType) {
+
+            // other objects
+            case Tokens.ALIAS :
+                return compileCreateAlias();
+
+            case Tokens.SEQUENCE :
+                return compileCreateSequence();
+
+            case Tokens.SCHEMA :
+                return compileCreateSchema();
+
+            case Tokens.TRIGGER :
+                return compileCreateTrigger();
+
+            case Tokens.USER :
+                return compileCreateUser();
+
+            case Tokens.ROLE :
+                return compileCreateRole();
+
+            case Tokens.VIEW :
+                return compileCreateView(false);
+
+            case Tokens.DOMAIN :
+                return compileCreateDomain();
+
+            case Tokens.TYPE :
+                return compileCreateType();
+
+            case Tokens.CHARACTER :
+                return compileCreateCharacterSet();
+
+            // index
+            case Tokens.UNIQUE :
+                read();
+                checkIsThis(Tokens.INDEX);
+
+                return compileCreateIndex(true);
+
+            case Tokens.INDEX :
+                return compileCreateIndex(false);
+
+            case Tokens.AGGREGATE :
+            case Tokens.FUNCTION :
+            case Tokens.PROCEDURE :
+                return compileCreateProcedureOrFunction();
+
+            default : {
+                throw unexpectedToken();
+            }
+        }
+    }
+
+    void processAlter() {
+
+        session.setScripting(true);
+        readThis(Tokens.ALTER);
+
+        switch (token.tokenType) {
+
+            case Tokens.TABLE : {
+                read();
+                processAlterTable();
+
+                break;
+            }
+            case Tokens.DOMAIN : {
+                read();
+                processAlterDomain();
+
+                break;
+            }
+            default : {
+                throw unexpectedToken();
+            }
+        }
+    }
+
+    Statement compileAlter() {
+
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.INDEX : {
+                read();
+
+                HsqlName name = readNewSchemaObjectName(SchemaObject.INDEX,
+                    true);
+
+                readThis(Tokens.RENAME);
+                readThis(Tokens.TO);
+
+                return compileRenameObject(name, SchemaObject.INDEX);
+            }
+            case Tokens.SCHEMA : {
+                read();
+
+                HsqlName name = readSchemaName();
+
+                readThis(Tokens.RENAME);
+                readThis(Tokens.TO);
+
+                return compileRenameObject(name, SchemaObject.SCHEMA);
+            }
+            case Tokens.CATALOG : {
+                read();
+                checkIsSimpleName();
+
+                String name = token.tokenString;
+
+                checkValidCatalogName(name);
+                read();
+                readThis(Tokens.RENAME);
+                readThis(Tokens.TO);
+
+                return compileRenameObject(database.getCatalogName(),
+                                           SchemaObject.CATALOG);
+            }
+            case Tokens.SEQUENCE : {
+                return compileAlterSequence();
+            }
+            case Tokens.TABLE : {
+                return compileAlterTable();
+            }
+            case Tokens.USER : {
+                return compileAlterUser();
+            }
+            case Tokens.DOMAIN : {
+                return compileAlterDomain();
+            }
+            case Tokens.VIEW : {
+                return compileCreateView(true);
+            }
+            default : {
+                throw unexpectedToken();
+            }
+        }
+    }
+
+/*
+    CompiledStatementInterface compileAlter() {
+
+        CompiledStatementInterface cs = null;
+        read();
+        String sql = getStatement(getParsePosition(), endStatementTokensAlter);
+
+        cs = new CompiledStatementSchema(sql, StatementCodes.ALTER_TYPE, null);
+
+        return cs;
+    }
+*/
+    Statement compileDrop() {
+
+        int      objectTokenType;
+        int      objectType;
+        int      statementType;
+        boolean  canCascade  = false;
+        boolean  cascade     = false;
+        boolean  useIfExists = false;
+        boolean  ifExists    = false;
+        HsqlName writeName   = null;
+        HsqlName catalogName = database.getCatalogName();
+
+        read();
+
+        objectTokenType = this.token.tokenType;
+
+        switch (objectTokenType) {
+
+            case Tokens.INDEX : {
+                read();
+
+                statementType = StatementTypes.DROP_INDEX;
+                objectType    = SchemaObject.INDEX;
+                useIfExists   = true;
+                writeName     = catalogName;
+
+                break;
+            }
+            case Tokens.ASSERTION : {
+                read();
+
+                statementType = StatementTypes.DROP_ASSERTION;
+                objectType    = SchemaObject.ASSERTION;
+                canCascade    = true;
+
+                break;
+            }
+            case Tokens.SPECIFIC : {
+                read();
+
+                switch (token.tokenType) {
+
+                    case Tokens.ROUTINE :
+                    case Tokens.PROCEDURE :
+                    case Tokens.FUNCTION :
+                        read();
+                        break;
+
+                    default :
+                        throw unexpectedToken();
+                }
+
+                statementType = StatementTypes.DROP_ROUTINE;
+                objectType    = SchemaObject.SPECIFIC_ROUTINE;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+
+                break;
+            }
+            case Tokens.PROCEDURE : {
+                read();
+
+                statementType = StatementTypes.DROP_ROUTINE;
+                objectType    = SchemaObject.PROCEDURE;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+
+                break;
+            }
+            case Tokens.FUNCTION : {
+                read();
+
+                statementType = StatementTypes.DROP_ROUTINE;
+                objectType    = SchemaObject.FUNCTION;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+
+                break;
+            }
+            case Tokens.SCHEMA : {
+                read();
+
+                statementType = StatementTypes.DROP_SCHEMA;
+                objectType    = SchemaObject.SCHEMA;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+
+                break;
+            }
+            case Tokens.SEQUENCE : {
+                read();
+
+                statementType = StatementTypes.DROP_SEQUENCE;
+                objectType    = SchemaObject.SEQUENCE;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+
+                break;
+            }
+            case Tokens.TRIGGER : {
+                read();
+
+                statementType = StatementTypes.DROP_TRIGGER;
+                objectType    = SchemaObject.TRIGGER;
+                writeName     = catalogName;
+                canCascade    = false;
+                useIfExists   = true;
+
+                break;
+            }
+            case Tokens.USER : {
+                read();
+
+                statementType = StatementTypes.DROP_USER;
+                objectType    = SchemaObject.GRANTEE;
+                writeName     = catalogName;
+                canCascade    = true;
+
+                break;
+            }
+            case Tokens.ROLE : {
+                read();
+
+                statementType = StatementTypes.DROP_ROLE;
+                objectType    = SchemaObject.GRANTEE;
+                writeName     = catalogName;
+                canCascade    = true;
+
+                break;
+            }
+            case Tokens.DOMAIN :
+                read();
+
+                statementType = StatementTypes.DROP_DOMAIN;
+                objectType    = SchemaObject.DOMAIN;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+                break;
+
+            case Tokens.TYPE :
+                read();
+
+                statementType = StatementTypes.DROP_TYPE;
+                objectType    = SchemaObject.TYPE;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+                break;
+
+            case Tokens.CHARACTER :
+                read();
+                readThis(Tokens.SET);
+
+                statementType = StatementTypes.DROP_CHARACTER_SET;
+                objectType    = SchemaObject.CHARSET;
+                writeName     = catalogName;
+                canCascade    = false;
+                useIfExists   = true;
+                break;
+
+            case Tokens.VIEW :
+                read();
+
+                statementType = StatementTypes.DROP_VIEW;
+                objectType    = SchemaObject.VIEW;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+                break;
+
+            case Tokens.TABLE :
+                read();
+
+                statementType = StatementTypes.DROP_TABLE;
+                objectType    = SchemaObject.TABLE;
+                writeName     = catalogName;
+                canCascade    = true;
+                useIfExists   = true;
+                break;
+
+            default :
+                throw unexpectedToken();
+        }
+
+        if (useIfExists && token.tokenType == Tokens.IF) {
+            int position = getPosition();
+
+            read();
+
+            if (token.tokenType == Tokens.EXISTS) {
+                read();
+
+                ifExists = true;
+            } else {
+                rewind(position);
+            }
+        }
+
+        checkIsIdentifier();
+
+        HsqlName name = null;
+
+        switch (objectTokenType) {
+
+            case Tokens.USER : {
+                checkIsSimpleName();
+                checkDatabaseUpdateAuthorisation();
+
+                Grantee grantee =
+                    database.getUserManager().get(token.tokenString);
+
+                name = grantee.getName();
+
+                read();
+
+                break;
+            }
+            case Tokens.ROLE : {
+                checkIsSimpleName();
+                checkDatabaseUpdateAuthorisation();
+
+                Grantee role =
+                    database.getGranteeManager().getRole(token.tokenString);
+
+                name = role.getName();
+
+                read();
+
+                break;
+            }
+            case Tokens.SCHEMA : {
+                name      = readNewSchemaName();
+                writeName = catalogName;
+
+                break;
+            }
+            case Tokens.TABLE : {
+                boolean isModule = token.namePrePrefix == null
+                                   && Tokens.T_MODULE.equals(token.namePrefix);
+
+                name = readNewSchemaObjectName(objectType, false);
+
+                if (isModule) {
+                    Object[] args = new Object[] {
+                        name, Boolean.valueOf(ifExists)
+                    };
+
+                    return new StatementSession(StatementTypes.DROP_TABLE,
+                                                args);
+                }
+
+                break;
+            }
+            default :
+                name = readNewSchemaObjectName(objectType, false);
+        }
+
+        if (!ifExists && useIfExists && token.tokenType == Tokens.IF) {
+            read();
+            readThis(Tokens.EXISTS);
+
+            ifExists = true;
+        }
+
+        if (canCascade) {
+            if (token.tokenType == Tokens.CASCADE) {
+                cascade = true;
+
+                read();
+            } else if (token.tokenType == Tokens.RESTRICT) {
+                read();
+            }
+        }
+
+        Object[] args = new Object[] {
+            name, new Integer(objectType), Boolean.valueOf(cascade),
+            Boolean.valueOf(ifExists)
+        };
+        String sql = getLastPart();
+        Statement cs = new StatementSchema(sql, statementType, args, null,
+                                           writeName);
+
+        return cs;
+    }
+
+    private void processAlterTable() {
+
+        String   tableName = token.tokenString;
+        HsqlName schema    = session.getSchemaHsqlName(token.namePrefix);
+
+        checkSchemaUpdateAuthorisation(schema);
+
+        Table t = database.schemaManager.getUserTable(session, tableName,
+            schema.name);
+
+        if (t.isView()) {
+            throw Error.error(ErrorCode.X_42501, tableName);
+        }
+
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.RENAME : {
+                read();
+                readThis(Tokens.TO);
+                processAlterTableRename(t);
+
+                return;
+            }
+            case Tokens.ADD : {
+                read();
+
+                HsqlName cname = null;
+
+                if (token.tokenType == Tokens.CONSTRAINT) {
+                    read();
+
+                    cname = readNewDependentSchemaObjectName(t.getName(),
+                            SchemaObject.CONSTRAINT);
+
+                    database.schemaManager.checkSchemaObjectNotExists(cname);
+                }
+
+                switch (token.tokenType) {
+
+                    case Tokens.FOREIGN :
+                        read();
+                        readThis(Tokens.KEY);
+                        processAlterTableAddForeignKeyConstraint(t, cname);
+
+                        return;
+
+                    case Tokens.UNIQUE :
+                        read();
+                        processAlterTableAddUniqueConstraint(t, cname);
+
+                        return;
+
+                    case Tokens.CHECK :
+                        read();
+                        processAlterTableAddCheckConstraint(t, cname);
+
+                        return;
+
+                    case Tokens.PRIMARY :
+                        read();
+                        readThis(Tokens.KEY);
+                        processAlterTableAddPrimaryKey(t, cname);
+
+                        return;
+
+                    case Tokens.COLUMN :
+                        if (cname != null) {
+                            throw unexpectedToken();
+                        }
+
+                        read();
+                        checkIsSimpleName();
+                        processAlterTableAddColumn(t);
+
+                        return;
+
+                    default :
+                        if (cname != null) {
+                            throw unexpectedToken();
+                        }
+
+                        checkIsSimpleName();
+                        processAlterTableAddColumn(t);
+
+                        return;
+                }
+            }
+            case Tokens.DROP : {
+                read();
+
+                switch (token.tokenType) {
+
+                    case Tokens.PRIMARY : {
+                        boolean cascade = false;
+
+                        read();
+                        readThis(Tokens.KEY);
+
+                        if (token.tokenType == Tokens.CASCADE) {
+                            read();
+
+                            cascade = true;
+                        }
+
+                        if (t.hasPrimaryKey()) {
+                            processAlterTableDropConstraint(
+                                t, t.getPrimaryConstraint().getName().name,
+                                cascade);
+                        } else {
+                            throw Error.error(ErrorCode.X_42501);
+                        }
+
+                        return;
+                    }
+                    case Tokens.CONSTRAINT : {
+                        boolean cascade = false;
+
+                        read();
+
+                        SchemaObject object = readSchemaObjectName(t.getName(),
+                            SchemaObject.CONSTRAINT);
+
+                        if (token.tokenType == Tokens.RESTRICT) {
+                            read();
+                        } else if (token.tokenType == Tokens.CASCADE) {
+                            read();
+
+                            cascade = true;
+                        }
+
+                        processAlterTableDropConstraint(
+                            t, object.getName().name, cascade);
+
+//                        read();
+                        return;
+                    }
+                    case Tokens.COLUMN :
+                        read();
+
+                    // fall through
+                    default : {
+                        checkIsSimpleName();
+
+                        String  name    = token.tokenString;
+                        boolean cascade = false;
+
+                        read();
+
+                        if (token.tokenType == Tokens.RESTRICT) {
+                            read();
+                        } else if (token.tokenType == Tokens.CASCADE) {
+                            read();
+
+                            cascade = true;
+                        }
+
+                        processAlterTableDropColumn(t, name, cascade);
+
+                        return;
+                    }
+                }
+            }
+            case Tokens.ALTER : {
+                read();
+
+                if (token.tokenType == Tokens.COLUMN) {
+                    read();
+                }
+
+                int          columnIndex = t.getColumnIndex(token.tokenString);
+                ColumnSchema column      = t.getColumn(columnIndex);
+
+                read();
+                processAlterColumn(t, column, columnIndex);
+
+                return;
+            }
+            default : {
+                throw unexpectedToken();
+            }
+        }
+    }
+
+    Statement compileAlterTable() {
+
+        read();
+
+        String   tableName = token.tokenString;
+        HsqlName schema    = session.getSchemaHsqlName(token.namePrefix);
+        Table t = database.schemaManager.getUserTable(session, tableName,
+            schema.name);
+
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.RENAME : {
+                read();
+                readThis(Tokens.TO);
+
+                return compileRenameObject(t.getName(), SchemaObject.TABLE);
+            }
+            case Tokens.ADD : {
+                read();
+
+                HsqlName cname = null;
+
+                if (token.tokenType == Tokens.CONSTRAINT) {
+                    read();
+
+                    cname = readNewDependentSchemaObjectName(t.getName(),
+                            SchemaObject.CONSTRAINT);
+                }
+
+                switch (token.tokenType) {
+
+                    case Tokens.FOREIGN :
+                        read();
+                        readThis(Tokens.KEY);
+
+                        return compileAlterTableAddForeignKeyConstraint(t,
+                                cname);
+
+                    case Tokens.UNIQUE :
+                        read();
+
+                        return compileAlterTableAddUniqueConstraint(t, cname);
+
+                    case Tokens.CHECK :
+                        read();
+
+                        return compileAlterTableAddCheckConstraint(t, cname);
+
+                    case Tokens.PRIMARY :
+                        read();
+                        readThis(Tokens.KEY);
+
+                        return compileAlterTableAddPrimaryKey(t, cname);
+
+                    case Tokens.COLUMN :
+                        if (cname != null) {
+                            throw unexpectedToken();
+                        }
+
+                        read();
+                        checkIsSimpleName();
+
+                        return compileAlterTableAddColumn(t);
+
+                    default :
+                        if (cname != null) {
+                            throw unexpectedToken();
+                        }
+
+                        checkIsSimpleName();
+
+                        return compileAlterTableAddColumn(t);
+                }
+            }
+            case Tokens.DROP : {
+                read();
+
+                switch (token.tokenType) {
+
+                    case Tokens.PRIMARY : {
+                        boolean cascade = false;
+
+                        read();
+                        readThis(Tokens.KEY);
+
+                        return compileAlterTableDropPrimaryKey(t);
+                    }
+                    case Tokens.CONSTRAINT : {
+                        read();
+
+                        return compileAlterTableDropConstraint(t);
+                    }
+                    case Tokens.COLUMN :
+                        read();
+
+                    // fall through
+                    default : {
+                        checkIsSimpleName();
+
+                        String  name    = token.tokenString;
+                        boolean cascade = false;
+
+                        read();
+
+                        if (token.tokenType == Tokens.RESTRICT) {
+                            read();
+                        } else if (token.tokenType == Tokens.CASCADE) {
+                            read();
+
+                            cascade = true;
+                        }
+
+                        return compileAlterTableDropColumn(t, name, cascade);
+                    }
+                }
+            }
+            case Tokens.ALTER : {
+                read();
+
+                if (token.tokenType == Tokens.COLUMN) {
+                    read();
+                }
+
+                int          columnIndex = t.getColumnIndex(token.tokenString);
+                ColumnSchema column      = t.getColumn(columnIndex);
+
+                read();
+
+                return compileAlterColumn(t, column, columnIndex);
+            }
+            default : {
+                throw unexpectedToken();
+            }
+        }
+    }
+
+    private Statement compileAlterTableDropConstraint(Table t) {
+
+        boolean cascade = false;
+        SchemaObject object = readSchemaObjectName(t.getSchemaName(),
+            SchemaObject.CONSTRAINT);
+
+        if (token.tokenType == Tokens.RESTRICT) {
+            read();
+        } else if (token.tokenType == Tokens.CASCADE) {
+            read();
+
+            cascade = true;
+        }
+
+        Object[] args = new Object[] {
+            object.getName(), ValuePool.getInt(SchemaObject.CONSTRAINT),
+            Boolean.valueOf(cascade), Boolean.valueOf(false)
+        };
+        String sql = getLastPart();
+        Statement cs = new StatementSchema(sql,
+                                           StatementTypes.DROP_CONSTRAINT,
+                                           args);
+
+        cs.writeTableNames = getReferenceArray(t.getName(), cascade);
+
+        return cs;
+    }
+
+    private Statement compileAlterTableDropPrimaryKey(Table t) {
+
+        boolean cascade = false;
+
+        if (token.tokenType == Tokens.RESTRICT) {
+            read();
+        } else if (token.tokenType == Tokens.CASCADE) {
+            read();
+
+            cascade = true;
+        }
+
+        if (!t.hasPrimaryKey()) {
+            throw Error.error(ErrorCode.X_42501);
+        }
+
+        SchemaObject object = t.getPrimaryConstraint();
+        Object[]     args   = new Object[] {
+            object.getName(), ValuePool.getInt(SchemaObject.CONSTRAINT),
+            Boolean.valueOf(cascade), Boolean.valueOf(false)
+        };
+        String sql = getLastPart();
+        Statement cs = new StatementSchema(sql,
+                                           StatementTypes.DROP_CONSTRAINT,
+                                           args);
+
+        cs.writeTableNames = getReferenceArray(t.getName(), cascade);
+
+        return cs;
+    }
+
+    HsqlName[] getReferenceArray(HsqlName objectName, boolean cascade) {
+
+        if (cascade) {
+            OrderedHashSet names = new OrderedHashSet();
+
+            database.schemaManager.getCascadingReferencingObjectNames(
+                objectName, names);
+
+            Iterator it = names.iterator();
+
+            while (it.hasNext()) {
+                HsqlName name = (HsqlName) it.next();
+
+                if (name.type != SchemaObject.TABLE) {
+                    it.remove();
+                }
+            }
+
+            names.add(objectName);
+
+            HsqlName[] array = new HsqlName[names.size()];
+
+            names.toArray(array);
+
+            return array;
+        } else {
+            return new HsqlName[]{ objectName };
+        }
+    }
+
+    StatementSession compileDeclareLocalTableOrNull() {
+
+        int position = super.getPosition();
+
+        try {
+            readThis(Tokens.DECLARE);
+            readThis(Tokens.LOCAL);
+            readThis(Tokens.TEMPORARY);
+            readThis(Tokens.TABLE);
+        } catch (Exception e) {
+
+            // may be cursor
+            rewind(position);
+
+            return null;
+        }
+
+        if (token.namePrePrefix != null) {
+            throw unexpectedToken();
+        }
+
+        if (token.namePrePrefix == null
+                && (token.namePrefix == null
+                    || Tokens.T_MODULE.equals(token.namePrefix))) {
+
+            // valid name
+        } else {
+            throw unexpectedToken();
+        }
+
+        HsqlName name = readNewSchemaObjectName(SchemaObject.TABLE, false);
+
+        name.schema = SqlInvariants.MODULE_HSQLNAME;
+
+        Table table = TableUtil.newTable(database, TableBase.TEMP_TABLE, name);
+        StatementSchema cs          = compileCreateTableBody(table);
+        HsqlArrayList   constraints = (HsqlArrayList) cs.arguments[1];
+
+        for (int i = 0; i < constraints.size(); i++) {
+            Constraint c = (Constraint) constraints.get(i);
+
+            if (c.getConstraintType()
+                    == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+                throw unexpectedToken(Tokens.T_FOREIGN);
+            }
+        }
+
+        StatementSession ss =
+            new StatementSession(StatementTypes.DECLARE_SESSION_TABLE,
+                                 cs.arguments);
+
+        return ss;
+    }
+
+    StatementSchema compileCreateTable(int type) {
+
+        HsqlName name = readNewSchemaObjectName(SchemaObject.TABLE, false);
+
+        name.setSchemaIfNull(session.getCurrentSchemaHsqlName());
+
+        Table table = TableUtil.newTable(database, type, name);
+
+        return compileCreateTableBody(table);
+    }
+
+    StatementSchema compileCreateTableBody(Table table) {
+
+        HsqlArrayList tempConstraints = new HsqlArrayList();
+
+        if (token.tokenType == Tokens.AS) {
+            return readTableAsSubqueryDefinition(table);
+        }
+
+        int position = getPosition();
+
+        readThis(Tokens.OPENBRACKET);
+
+        {
+            Constraint c = new Constraint(null, null,
+                                          SchemaObject.ConstraintTypes.TEMP);
+
+            tempConstraints.add(c);
+        }
+
+        boolean start     = true;
+        boolean startPart = true;
+        boolean end       = false;
+
+        while (!end) {
+            switch (token.tokenType) {
+
+                case Tokens.LIKE : {
+                    ColumnSchema[] likeColumns = readLikeTable(table);
+
+                    for (int i = 0; i < likeColumns.length; i++) {
+                        table.addColumn(likeColumns[i]);
+                    }
+
+                    start     = false;
+                    startPart = false;
+
+                    break;
+                }
+                case Tokens.CONSTRAINT :
+                case Tokens.PRIMARY :
+                case Tokens.FOREIGN :
+                case Tokens.UNIQUE :
+                case Tokens.CHECK :
+                    if (!startPart) {
+                        throw unexpectedToken();
+                    }
+
+                    readConstraint(table, tempConstraints);
+
+                    start     = false;
+                    startPart = false;
+                    break;
+
+                case Tokens.COMMA :
+                    if (startPart) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    startPart = true;
+                    break;
+
+                case Tokens.CLOSEBRACKET :
+                    read();
+
+                    end = true;
+                    break;
+
+                default :
+                    if (!startPart) {
+                        throw unexpectedToken();
+                    }
+
+                    checkIsSchemaObjectName();
+
+                    HsqlName hsqlName =
+                        database.nameManager.newColumnHsqlName(table.getName(),
+                            token.tokenString, isDelimitedIdentifier());
+
+                    read();
+
+                    ColumnSchema newcolumn = readColumnDefinitionOrNull(table,
+                        hsqlName, tempConstraints);
+
+                    if (newcolumn == null) {
+                        if (start) {
+                            rewind(position);
+
+                            return readTableAsSubqueryDefinition(table);
+                        } else {
+                            throw Error.error(ErrorCode.X_42000);
+                        }
+                    }
+
+                    table.addColumn(newcolumn);
+
+                    start     = false;
+                    startPart = false;
+            }
+        }
+
+        if (token.tokenType == Tokens.ON) {
+            if (!table.isTemp()) {
+                throw unexpectedToken();
+            }
+
+            read();
+            readThis(Tokens.COMMIT);
+
+            if (token.tokenType == Tokens.DELETE) {}
+            else if (token.tokenType == Tokens.PRESERVE) {
+                table.persistenceScope = TableBase.SCOPE_SESSION;
+            }
+
+            read();
+            readThis(Tokens.ROWS);
+        }
+
+        Object[] args = new Object[] {
+            table, tempConstraints, null
+        };
+        String   sql  = getLastPart();
+
+        return new StatementSchema(sql, StatementTypes.CREATE_TABLE, args);
+    }
+
+    private ColumnSchema[] readLikeTable(Table table) {
+
+        read();
+
+        boolean           generated = false;
+        boolean           identity  = false;
+        boolean           defaults  = false;
+        Table             likeTable = readTableName();
+        OrderedIntHashSet set       = new OrderedIntHashSet();
+
+        while (true) {
+            boolean including = token.tokenType == Tokens.INCLUDING;
+
+            if (!including && token.tokenType != Tokens.EXCLUDING) {
+                break;
+            }
+
+            read();
+
+            switch (token.tokenType) {
+
+                case Tokens.GENERATED :
+                    if (!set.add(token.tokenType)) {
+                        throw unexpectedToken();
+                    }
+
+                    generated = including;
+                    break;
+
+                case Tokens.IDENTITY :
+                    if (!set.add(token.tokenType)) {
+                        throw unexpectedToken();
+                    }
+
+                    identity = including;
+                    break;
+
+                case Tokens.DEFAULTS :
+                    if (!set.add(token.tokenType)) {
+                        throw unexpectedToken();
+                    }
+
+                    defaults = including;
+                    break;
+
+                default :
+                    throw unexpectedToken();
+            }
+
+            read();
+        }
+
+        ColumnSchema[] columnList =
+            new ColumnSchema[likeTable.getColumnCount()];
+
+        for (int i = 0; i < columnList.length; i++) {
+            ColumnSchema column = likeTable.getColumn(i).duplicate();
+            HsqlName name =
+                database.nameManager.newColumnSchemaHsqlName(table.getName(),
+                    column.getName());
+
+            column.setName(name);
+            column.setNullable(true);
+            column.setPrimaryKey(false);
+
+            if (identity) {
+                if (column.isIdentity()) {
+                    column.setIdentity(
+                        column.getIdentitySequence().duplicate());
+                }
+            } else {
+                column.setIdentity(null);
+            }
+
+            if (!defaults) {
+                column.setDefaultExpression(null);
+            }
+
+            if (!generated) {
+                column.setGeneratingExpression(null);
+            }
+
+            columnList[i] = column;
+        }
+
+        return columnList;
+    }
+
+    StatementSchema readTableAsSubqueryDefinition(Table table) {
+
+        HsqlName   readName    = null;
+        boolean    withData    = true;
+        HsqlName[] columnNames = null;
+        Statement  statement   = null;
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            columnNames = readColumnNames(table.getName());
+        }
+
+        readThis(Tokens.AS);
+        readThis(Tokens.OPENBRACKET);
+
+        QueryExpression queryExpression = XreadQueryExpression();
+
+        queryExpression.setReturningResult();
+        queryExpression.resolve(session);
+        readThis(Tokens.CLOSEBRACKET);
+        readThis(Tokens.WITH);
+
+        if (token.tokenType == Tokens.NO) {
+            read();
+
+            withData = false;
+        } else if (table.getTableType() == TableBase.TEXT_TABLE) {
+            throw unexpectedTokenRequire(Tokens.T_NO);
+        }
+
+        readThis(Tokens.DATA);
+
+        if (token.tokenType == Tokens.ON) {
+            if (!table.isTemp()) {
+                throw unexpectedToken();
+            }
+
+            read();
+            readThis(Tokens.COMMIT);
+
+            if (token.tokenType == Tokens.DELETE) {}
+            else if (token.tokenType == Tokens.PRESERVE) {
+                table.persistenceScope = TableBase.SCOPE_SESSION;
+            }
+
+            read();
+            readThis(Tokens.ROWS);
+        }
+
+        if (columnNames == null) {
+            columnNames = queryExpression.getResultColumnNames();
+        } else {
+            if (columnNames.length != queryExpression.getColumnCount()) {
+                throw Error.error(ErrorCode.X_42593);
+            }
+        }
+
+        TableUtil.setColumnsInSchemaTable(table, columnNames,
+                                          queryExpression.getColumnTypes());
+        table.createPrimaryKey();
+
+        if (withData) {
+            statement = new StatementQuery(session, queryExpression,
+                                           compileContext);
+            readName = statement.getTableNamesForRead()[0];
+        }
+
+        Object[] args = new Object[] {
+            table, null, statement
+        };
+        String   sql  = getLastPart();
+        StatementSchema st = new StatementSchema(sql,
+            StatementTypes.CREATE_TABLE, args, readName, null);
+
+        return st;
+    }
+
+    /**
+     * Adds a list of temp constraints to a new table
+     */
+    static Table addTableConstraintDefinitions(Session session, Table table,
+            HsqlArrayList tempConstraints, HsqlArrayList constraintList,
+            boolean addToSchema) {
+
+        Constraint c        = (Constraint) tempConstraints.get(0);
+        String     namePart = c.getName() == null ? null
+                                                  : c.getName().name;
+        HsqlName indexName = session.database.nameManager.newAutoName("IDX",
+            namePart, table.getSchemaName(), table.getName(),
+            SchemaObject.INDEX);
+
+        c.setColumnsIndexes(table);
+        table.createPrimaryKey(indexName, c.core.mainCols, true);
+
+        if (c.core.mainCols != null) {
+            Constraint newconstraint = new Constraint(c.getName(), table,
+                table.getPrimaryIndex(),
+                SchemaObject.ConstraintTypes.PRIMARY_KEY);
+
+            table.addConstraint(newconstraint);
+
+            if (addToSchema) {
+                session.database.schemaManager.addSchemaObject(newconstraint);
+            }
+        }
+
+        for (int i = 1; i < tempConstraints.size(); i++) {
+            c = (Constraint) tempConstraints.get(i);
+
+            switch (c.constType) {
+
+                case SchemaObject.ConstraintTypes.UNIQUE : {
+                    c.setColumnsIndexes(table);
+
+                    if (table.getUniqueConstraintForColumns(c.core.mainCols)
+                            != null) {
+                        throw Error.error(ErrorCode.X_42522);
+                    }
+
+                    // create an autonamed index
+                    indexName = session.database.nameManager.newAutoName("IDX",
+                            c.getName().name, table.getSchemaName(),
+                            table.getName(), SchemaObject.INDEX);
+
+                    Index index = table.createAndAddIndexStructure(session,
+                        indexName, c.core.mainCols, null, null, true, true,
+                        false);
+                    Constraint newconstraint = new Constraint(c.getName(),
+                        table, index, SchemaObject.ConstraintTypes.UNIQUE);
+
+                    table.addConstraint(newconstraint);
+
+                    if (addToSchema) {
+                        session.database.schemaManager.addSchemaObject(
+                            newconstraint);
+                    }
+
+                    break;
+                }
+                case SchemaObject.ConstraintTypes.FOREIGN_KEY : {
+                    addForeignKey(session, table, c, constraintList);
+
+                    break;
+                }
+                case SchemaObject.ConstraintTypes.CHECK : {
+                    try {
+                        c.prepareCheckConstraint(session, table, false);
+                    } catch (HsqlException e) {
+                        if (session.isProcessingScript()) {
+                            break;
+                        }
+
+                        throw e;
+                    }
+
+                    table.addConstraint(c);
+
+                    if (c.isNotNull()) {
+                        ColumnSchema column =
+                            table.getColumn(c.notNullColumnIndex);
+
+                        column.setNullable(false);
+                        table.setColumnTypeVars(c.notNullColumnIndex);
+                    }
+
+                    if (addToSchema) {
+                        session.database.schemaManager.addSchemaObject(c);
+                    }
+
+                    break;
+                }
+            }
+        }
+
+        return table;
+    }
+
+    static void addForeignKey(Session session, Table table, Constraint c,
+                              HsqlArrayList constraintList) {
+
+        HsqlName mainTableName = c.getMainTableName();
+
+        if (mainTableName == table.getName()) {
+            c.core.mainTable = table;
+        } else {
+            Table mainTable =
+                session.database.schemaManager.findUserTable(session,
+                    mainTableName.name, mainTableName.schema.name);
+
+            if (mainTable == null) {
+                if (constraintList == null) {
+                    throw Error.error(ErrorCode.X_42501, mainTableName.name);
+                }
+
+                constraintList.add(c);
+
+                return;
+            }
+
+            c.core.mainTable = mainTable;
+        }
+
+        c.setColumnsIndexes(table);
+
+        Constraint uniqueConstraint =
+            c.core.mainTable.getUniqueConstraintForColumns(c.core.mainCols,
+                c.core.refCols);
+
+        if (uniqueConstraint == null) {
+            throw Error.error(ErrorCode.X_42523);
+        }
+
+        Index      mainIndex  = uniqueConstraint.getMainIndex();
+        TableWorks tableWorks = new TableWorks(session, table);
+
+        tableWorks.checkCreateForeignKey(c);
+
+        boolean isForward = c.core.mainTable.getSchemaName()
+                            != table.getSchemaName();
+        int offset = session.database.schemaManager.getTableIndex(table);
+
+        if (offset != -1
+                && offset
+                   < session.database.schemaManager.getTableIndex(
+                       c.core.mainTable)) {
+            isForward = true;
+        }
+
+        HsqlName refIndexName = session.database.nameManager.newAutoName("IDX",
+            table.getSchemaName(), table.getName(), SchemaObject.INDEX);
+        Index index = table.createAndAddIndexStructure(session, refIndexName,
+            c.core.refCols, null, null, false, true, isForward);
+        HsqlName mainName = session.database.nameManager.newAutoName("REF",
+            c.getName().name, table.getSchemaName(), table.getName(),
+            SchemaObject.INDEX);
+
+        c.core.uniqueName = uniqueConstraint.getName();
+        c.core.mainName   = mainName;
+        c.core.mainIndex  = mainIndex;
+        c.core.refTable   = table;
+        c.core.refName    = c.getName();
+        c.core.refIndex   = index;
+        c.isForward       = isForward;
+
+        table.addConstraint(c);
+        c.core.mainTable.addConstraint(new Constraint(mainName, c));
+        session.database.schemaManager.addSchemaObject(c);
+    }
+
+    private Constraint readFKReferences(Table refTable,
+                                        HsqlName constraintName,
+                                        OrderedHashSet refColSet) {
+
+        HsqlName       mainTableName;
+        OrderedHashSet mainColSet = null;
+
+        readThis(Tokens.REFERENCES);
+
+        HsqlName schema;
+
+        if (token.namePrefix == null) {
+            schema = refTable.getSchemaName();
+        } else {
+            schema =
+                database.schemaManager.getSchemaHsqlName(token.namePrefix);
+        }
+
+        if (refTable.getSchemaName() == schema
+                && refTable.getName().name.equals(token.tokenString)) {
+            mainTableName = refTable.getName();
+
+            read();
+        } else {
+            mainTableName = readFKTableName(schema);
+        }
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            mainColSet = readColumnNames(false);
+        } else {
+
+            // columns are resolved in the calling method
+            if (mainTableName == refTable.getName()) {
+
+                // fredt - FK statement is part of CREATE TABLE and is self-referencing
+                // reference must be to same table being created
+            } else {
+/*
+                if (!mainTable.hasPrimaryKey()) {
+                    throw Trace.error(Trace.CONSTRAINT_NOT_FOUND,
+                                      Trace.TABLE_HAS_NO_PRIMARY_KEY);
+
+                }
+*/
+            }
+        }
+
+        int matchType = OpTypes.MATCH_SIMPLE;
+
+        if (token.tokenType == Tokens.MATCH) {
+            read();
+
+            switch (token.tokenType) {
+
+                case Tokens.SIMPLE :
+                    read();
+                    break;
+
+                case Tokens.PARTIAL :
+                    throw super.unsupportedFeature();
+                case Tokens.FULL :
+                    read();
+
+                    matchType = OpTypes.MATCH_FULL;
+                    break;
+
+                default :
+                    throw unexpectedToken();
+            }
+        }
+
+        // -- In a while loop we parse a maximium of two
+        // -- "ON" statements following the foreign key
+        // -- definition this can be
+        // -- ON [UPDATE|DELETE] [NO ACTION|RESTRICT|CASCADE|SET [NULL|DEFAULT]]
+        int deleteAction      = SchemaObject.ReferentialAction.NO_ACTION;
+        int updateAction      = SchemaObject.ReferentialAction.NO_ACTION;
+        OrderedIntHashSet set = new OrderedIntHashSet();
+
+        while (token.tokenType == Tokens.ON) {
+            read();
+
+            if (!set.add(token.tokenType)) {
+                throw unexpectedToken();
+            }
+
+            if (token.tokenType == Tokens.DELETE) {
+                read();
+
+                if (token.tokenType == Tokens.SET) {
+                    read();
+
+                    switch (token.tokenType) {
+
+                        case Tokens.DEFAULT : {
+                            read();
+
+                            deleteAction =
+                                SchemaObject.ReferentialAction.SET_DEFAULT;
+
+                            break;
+                        }
+                        case Tokens.NULL :
+                            read();
+
+                            deleteAction =
+                                SchemaObject.ReferentialAction.SET_NULL;
+                            break;
+
+                        default :
+                            throw unexpectedToken();
+                    }
+                } else if (token.tokenType == Tokens.CASCADE) {
+                    read();
+
+                    deleteAction = SchemaObject.ReferentialAction.CASCADE;
+                } else if (token.tokenType == Tokens.RESTRICT) {
+                    read();
+                } else {
+                    readThis(Tokens.NO);
+                    readThis(Tokens.ACTION);
+                }
+            } else if (token.tokenType == Tokens.UPDATE) {
+                read();
+
+                if (token.tokenType == Tokens.SET) {
+                    read();
+
+                    switch (token.tokenType) {
+
+                        case Tokens.DEFAULT : {
+                            read();
+
+                            deleteAction =
+                                SchemaObject.ReferentialAction.SET_DEFAULT;
+
+                            break;
+                        }
+                        case Tokens.NULL :
+                            read();
+
+                            deleteAction =
+                                SchemaObject.ReferentialAction.SET_NULL;
+                            break;
+
+                        default :
+                            throw unexpectedToken();
+                    }
+                } else if (token.tokenType == Tokens.CASCADE) {
+                    read();
+
+                    updateAction = SchemaObject.ReferentialAction.CASCADE;
+                } else if (token.tokenType == Tokens.RESTRICT) {
+                    read();
+                } else {
+                    readThis(Tokens.NO);
+                    readThis(Tokens.ACTION);
+                }
+            } else {
+                throw unexpectedToken();
+            }
+        }
+
+        if (constraintName == null) {
+            constraintName = database.nameManager.newAutoName("FK",
+                    refTable.getSchemaName(), refTable.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        return new Constraint(constraintName, refTable.getName(), refColSet,
+                              mainTableName, mainColSet,
+                              SchemaObject.ConstraintTypes.FOREIGN_KEY,
+                              deleteAction, updateAction, matchType);
+    }
+
+    private HsqlName readFKTableName(HsqlName schema) {
+
+        HsqlName name;
+
+        checkIsSchemaObjectName();
+
+        Table table = database.schemaManager.findUserTable(session,
+            token.tokenString, schema.name);
+
+        if (table == null) {
+            name = database.nameManager.newHsqlName(schema, token.tokenString,
+                    isDelimitedIdentifier(), SchemaObject.TABLE);
+        } else {
+            name = table.getName();
+        }
+
+        read();
+
+        return name;
+    }
+
+    StatementSchema compileCreateView(boolean alter) {
+
+        read();
+
+        HsqlName name = readNewSchemaObjectName(SchemaObject.VIEW, true);
+
+        name.setSchemaIfNull(session.getCurrentSchemaHsqlName());
+        checkSchemaUpdateAuthorisation(name.schema);
+
+        HsqlName[] colList = null;
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            colList = readColumnNames(name);
+        }
+
+        readThis(Tokens.AS);
+        startRecording();
+
+        int             position = getPosition();
+        QueryExpression queryExpression;
+
+        try {
+            queryExpression = XreadQueryExpression();
+        } catch (HsqlException e) {
+            queryExpression = XreadJoinedTable();
+        }
+
+        Token[] tokenisedStatement = getRecordedStatement();
+        int     check              = SchemaObject.ViewCheckModes.CHECK_NONE;
+
+        if (token.tokenType == Tokens.WITH) {
+            read();
+
+            check = SchemaObject.ViewCheckModes.CHECK_CASCADE;
+
+            if (readIfThis(Tokens.LOCAL)) {
+                check = SchemaObject.ViewCheckModes.CHECK_LOCAL;
+            } else {
+                readIfThis(Tokens.CASCADED);
+            }
+
+            readThis(Tokens.CHECK);
+            readThis(Tokens.OPTION);
+        }
+
+        View view = new View(database, name, colList, check);
+
+        queryExpression.setView(view);
+        queryExpression.resolve(session);
+        view.setStatement(Token.getSQL(tokenisedStatement));
+
+        String          fullSQL = getLastPart();
+        Object[]        args    = new Object[]{ view };
+        int             type    = alter ? StatementTypes.ALTER_VIEW
+                                        : StatementTypes.CREATE_VIEW;
+        StatementSchema cs      = new StatementSchema(fullSQL, type, args);
+        StatementQuery s = new StatementQuery(session, queryExpression,
+                                              compileContext);
+
+        cs.readTableNames = s.readTableNames;
+
+        return cs;
+    }
+
+    StatementSchema compileCreateSequence() {
+
+        read();
+
+        /*
+                CREATE SEQUENCE <name>
+                [AS {INTEGER | BIGINT}]
+                [START WITH <value>]
+                [INCREMENT BY <value>]
+        */
+        HsqlName name = readNewSchemaObjectName(SchemaObject.SEQUENCE, false);
+        NumberSequence sequence = new NumberSequence(name, Type.SQL_INTEGER);
+
+        readSequenceOptions(sequence, true, false);
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ sequence };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_SEQUENCE, args);
+    }
+
+    StatementSchema compileCreateDomain() {
+
+        UserTypeModifier userTypeModifier = null;
+        HsqlName         name;
+
+        read();
+
+        name = readNewSchemaObjectName(SchemaObject.DOMAIN, false);
+
+        readIfThis(Tokens.AS);
+
+        Type       type          = readTypeDefinition(false).duplicate();
+        Expression defaultClause = null;
+
+        if (readIfThis(Tokens.DEFAULT)) {
+            defaultClause = readDefaultClause(type);
+        }
+
+        userTypeModifier = new UserTypeModifier(name, SchemaObject.DOMAIN,
+                type);
+
+        userTypeModifier.setDefaultClause(defaultClause);
+
+        type.userTypeModifier = userTypeModifier;
+
+        HsqlArrayList tempConstraints = new HsqlArrayList();
+
+        compileContext.currentDomain = type;
+
+        while (true) {
+            boolean end = false;
+
+            switch (token.tokenType) {
+
+                case Tokens.CONSTRAINT :
+                case Tokens.CHECK :
+                    readConstraint(type, tempConstraints);
+                    break;
+
+                default :
+                    end = true;
+                    break;
+            }
+
+            if (end) {
+                break;
+            }
+        }
+
+        compileContext.currentDomain = null;
+
+        for (int i = 0; i < tempConstraints.size(); i++) {
+            Constraint c = (Constraint) tempConstraints.get(i);
+
+            c.prepareCheckConstraint(session, null, false);
+            userTypeModifier.addConstraint(c);
+        }
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ type };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_DOMAIN, args);
+    }
+
+    StatementSchema compileCreateType() {
+
+        read();
+
+        HsqlName name = readNewSchemaObjectName(SchemaObject.TYPE, false);
+
+        readThis(Tokens.AS);
+
+        Type type = readTypeDefinition(false).duplicate();
+
+        readIfThis(Tokens.FINAL);
+
+        UserTypeModifier userTypeModifier = new UserTypeModifier(name,
+            SchemaObject.TYPE, type);
+
+        type.userTypeModifier = userTypeModifier;
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ type };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_TYPE, args);
+    }
+
+    StatementSchema compileCreateCharacterSet() {
+
+        read();
+        readThis(Tokens.SET);
+
+        HsqlName name = readNewSchemaObjectName(SchemaObject.CHARSET, false);
+
+        readIfThis(Tokens.AS);
+        readThis(Tokens.GET);
+
+        String schema = session.getSchemaName(token.namePrefix);
+        Charset source =
+            (Charset) database.schemaManager.getSchemaObject(token.tokenString,
+                schema, SchemaObject.CHARSET);
+
+        read();
+
+        if (token.tokenType == Tokens.COLLATION) {
+            read();
+            readThis(Tokens.FROM);
+            readThis(Tokens.DEFAULT);
+        }
+
+        Charset charset = new Charset(name);
+
+        charset.base = source.getName();
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ charset };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_CHARACTER_SET,
+                                   args);
+    }
+
+    StatementSchema compileCreateAlias() {
+
+        HsqlName  name     = null;
+        Routine[] routines = null;
+        String    alias;
+        String    methodFQN = null;
+
+        if (!session.isProcessingScript()) {
+            throw super.unsupportedFeature();
+        }
+
+        read();
+
+        try {
+            alias = token.tokenString;
+
+            read();
+            readThis(Tokens.FOR);
+
+            methodFQN = token.tokenString;
+
+            read();
+        } catch (HsqlException e) {
+            alias = null;
+        }
+
+        if (alias != null) {
+            HsqlName schema =
+                database.schemaManager.getDefaultSchemaHsqlName();
+
+            name = database.nameManager.newHsqlName(schema, alias,
+                    SchemaObject.FUNCTION);
+
+            Method[] methods = Routine.getMethods(methodFQN);
+
+            routines = Routine.newRoutines(session, methods);
+        }
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[] {
+            name, routines
+        };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_ALIAS, args);
+    }
+
+    StatementSchema compileCreateTrigger() {
+
+        Table          table;
+        Boolean        isForEachRow = null;
+        boolean        isNowait     = false;
+        boolean        hasQueueSize = false;
+        int            queueSize    = 0;
+        int            beforeOrAfterType;
+        int            operationType;
+        String         className;
+        TriggerDef     td;
+        HsqlName       name;
+        HsqlName       otherName           = null;
+        OrderedHashSet columns             = null;
+        int[]          updateColumnIndexes = null;
+
+        read();
+
+        name = readNewSchemaObjectName(SchemaObject.TRIGGER, true);
+
+        switch (token.tokenType) {
+
+            case Tokens.INSTEAD :
+                beforeOrAfterType = TriggerDef.getTiming(Tokens.INSTEAD);
+
+                read();
+                readThis(Tokens.OF);
+                break;
+
+            case Tokens.BEFORE :
+            case Tokens.AFTER :
+                beforeOrAfterType = TriggerDef.getTiming(token.tokenType);
+
+                read();
+                break;
+
+            default :
+                throw unexpectedToken();
+        }
+
+        switch (token.tokenType) {
+
+            case Tokens.INSERT :
+            case Tokens.DELETE :
+                operationType = TriggerDef.getOperationType(token.tokenType);
+
+                read();
+                break;
+
+            case Tokens.UPDATE :
+                operationType = TriggerDef.getOperationType(token.tokenType);
+
+                read();
+
+                if (token.tokenType == Tokens.OF
+                        && beforeOrAfterType != TriggerDef.INSTEAD) {
+                    read();
+
+                    columns = new OrderedHashSet();
+
+                    readColumnNameList(columns, null, false);
+                }
+                break;
+
+            default :
+                throw unexpectedToken();
+        }
+
+        readThis(Tokens.ON);
+
+        table = readTableName();
+
+        if (token.tokenType == Tokens.BEFORE) {
+            read();
+            checkIsSimpleName();
+
+            otherName = readNewSchemaObjectName(SchemaObject.TRIGGER, true);
+        }
+
+        name.setSchemaIfNull(table.getSchemaName());
+        checkSchemaUpdateAuthorisation(name.schema);
+
+        if (beforeOrAfterType == TriggerDef.INSTEAD) {
+            if (!table.isView()
+                    || ((View) table).getCheckOption()
+                       == SchemaObject.ViewCheckModes.CHECK_CASCADE) {
+                throw Error.error(ErrorCode.X_42538, name.schema.name);
+            }
+        } else {
+            if (table.isView()) {
+                throw Error.error(ErrorCode.X_42538, name.schema.name);
+            }
+        }
+
+        if (name.schema != table.getSchemaName()) {
+            throw Error.error(ErrorCode.X_42505, name.schema.name);
+        }
+
+        name.parent = table.getName();
+
+        database.schemaManager.checkSchemaObjectNotExists(name);
+
+        if (columns != null) {
+            updateColumnIndexes = table.getColumnIndexes(columns);
+
+            for (int i = 0; i < updateColumnIndexes.length; i++) {
+                if (updateColumnIndexes[i] == -1) {
+                    throw Error.error(ErrorCode.X_42544,
+                                      (String) columns.get(i));
+                }
+            }
+        }
+
+        Expression      condition    = null;
+        String          oldTableName = null;
+        String          newTableName = null;
+        String          oldRowName   = null;
+        String          newRowName   = null;
+        Table[]         transitions  = new Table[4];
+        RangeVariable[] rangeVars    = new RangeVariable[4];
+        String          conditionSQL = null;
+
+        if (token.tokenType == Tokens.REFERENCING) {
+            read();
+
+            if (token.tokenType != Tokens.OLD
+                    && token.tokenType != Tokens.NEW) {
+                throw unexpectedToken();
+            }
+
+            while (true) {
+                if (token.tokenType == Tokens.OLD) {
+                    if (operationType == StatementTypes.INSERT) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    if (token.tokenType == Tokens.TABLE) {
+                        if (Boolean.TRUE.equals(isForEachRow)
+                                || oldTableName != null
+                                || beforeOrAfterType == TriggerDef.BEFORE) {
+                            throw unexpectedToken();
+                        }
+
+                        read();
+                        readIfThis(Tokens.AS);
+                        checkIsSimpleName();
+                        read();
+
+                        oldTableName = token.tokenString;
+
+                        String n = oldTableName;
+
+                        if (n.equals(newTableName) || n.equals(oldRowName)
+                                || n.equals(newRowName)) {
+                            throw unexpectedToken();
+                        }
+
+                        isForEachRow = Boolean.FALSE;
+
+                        HsqlName hsqlName = database.nameManager.newHsqlName(
+                            table.getSchemaName(), n, isDelimitedIdentifier(),
+                            SchemaObject.TRANSITION);
+                        Table transition = new Table(table, hsqlName);
+                        RangeVariable range = new RangeVariable(transition,
+                            null, null, null, compileContext);
+
+                        transitions[TriggerDef.OLD_TABLE] = transition;
+                        rangeVars[TriggerDef.OLD_TABLE]   = range;
+                    } else {
+                        if (Boolean.FALSE.equals(isForEachRow)
+                                || oldRowName != null) {
+                            throw unexpectedToken();
+                        }
+
+                        readIfThis(Tokens.ROW);
+                        readIfThis(Tokens.AS);
+                        checkIsSimpleName();
+
+                        oldRowName = token.tokenString;
+
+                        read();
+
+                        String n = oldRowName;
+
+                        if (n.equals(newTableName) || n.equals(oldTableName)
+                                || n.equals(newRowName)) {
+                            throw unexpectedToken();
+                        }
+
+                        isForEachRow = Boolean.TRUE;
+
+                        HsqlName hsqlName = database.nameManager.newHsqlName(
+                            table.getSchemaName(), n, isDelimitedIdentifier(),
+                            SchemaObject.TRANSITION);
+                        Table transition = new Table(table, hsqlName);
+                        RangeVariable range = new RangeVariable(transition,
+                            null, null, null, compileContext);
+
+                        transitions[TriggerDef.OLD_ROW] = transition;
+                        rangeVars[TriggerDef.OLD_ROW]   = range;
+                    }
+                } else if (token.tokenType == Tokens.NEW) {
+                    if (operationType == StatementTypes.DELETE_WHERE) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    if (token.tokenType == Tokens.TABLE) {
+                        if (Boolean.TRUE.equals(isForEachRow)
+                                || newTableName != null
+                                || beforeOrAfterType == TriggerDef.BEFORE) {
+                            throw unexpectedToken();
+                        }
+
+                        read();
+                        readIfThis(Tokens.AS);
+                        checkIsSimpleName();
+
+                        newTableName = token.tokenString;
+
+                        read();
+
+                        isForEachRow = Boolean.FALSE;
+
+                        String n = newTableName;
+
+                        if (n.equals(oldTableName) || n.equals(oldRowName)
+                                || n.equals(newRowName)) {
+                            throw unexpectedToken();
+                        }
+
+                        HsqlName hsqlName = database.nameManager.newHsqlName(
+                            table.getSchemaName(), n, isDelimitedIdentifier(),
+                            SchemaObject.TRANSITION);
+                        Table transition = new Table(table, hsqlName);
+                        RangeVariable range = new RangeVariable(transition,
+                            null, null, null, compileContext);
+
+                        transitions[TriggerDef.NEW_TABLE] = transition;
+                        rangeVars[TriggerDef.NEW_TABLE]   = range;
+                    } else {
+                        if (Boolean.FALSE.equals(isForEachRow)
+                                || newRowName != null) {
+                            throw unexpectedToken();
+                        }
+
+                        readIfThis(Tokens.ROW);
+                        readIfThis(Tokens.AS);
+                        checkIsSimpleName();
+
+                        newRowName = token.tokenString;
+
+                        read();
+
+                        isForEachRow = Boolean.TRUE;
+
+                        String n = newRowName;
+
+                        if (n.equals(oldTableName) || n.equals(newTableName)
+                                || n.equals(oldRowName)) {
+                            throw unexpectedToken();
+                        }
+
+                        HsqlName hsqlName = database.nameManager.newHsqlName(
+                            table.getSchemaName(), n, isDelimitedIdentifier(),
+                            SchemaObject.TRANSITION);
+                        Table transition = new Table(table, hsqlName);
+                        RangeVariable range = new RangeVariable(transition,
+                            null, null, null, compileContext);
+
+                        transitions[TriggerDef.NEW_ROW] = transition;
+                        rangeVars[TriggerDef.NEW_ROW]   = range;
+                    }
+                } else {
+                    break;
+                }
+            }
+        }
+
+        if (Boolean.TRUE.equals(isForEachRow)
+                && token.tokenType != Tokens.FOR) {
+            throw unexpectedTokenRequire(Tokens.T_FOR);
+        }
+
+        if (token.tokenType == Tokens.FOR) {
+            read();
+            readThis(Tokens.EACH);
+
+            if (token.tokenType == Tokens.ROW) {
+                if (Boolean.FALSE.equals(isForEachRow)) {
+                    throw unexpectedToken();
+                }
+
+                isForEachRow = Boolean.TRUE;
+            } else if (token.tokenType == Tokens.STATEMENT) {
+                if (Boolean.TRUE.equals(isForEachRow)
+                        || beforeOrAfterType == TriggerDef.BEFORE) {
+                    throw unexpectedToken();
+                }
+
+                isForEachRow = Boolean.FALSE;
+            } else {
+                throw unexpectedToken();
+            }
+
+            read();
+        }
+
+        //
+        if (rangeVars[TriggerDef.OLD_TABLE] != null) {}
+
+        if (rangeVars[TriggerDef.NEW_TABLE] != null) {}
+
+        //
+        if (Tokens.T_QUEUE.equals(token.tokenString)) {
+            read();
+
+            queueSize    = readInteger();
+            hasQueueSize = true;
+        }
+
+        if (Tokens.T_NOWAIT.equals(token.tokenString)) {
+            read();
+
+            isNowait = true;
+        }
+
+        if (token.tokenType == Tokens.WHEN
+                && beforeOrAfterType != TriggerDef.INSTEAD) {
+            read();
+            readThis(Tokens.OPENBRACKET);
+
+            int position = getPosition();
+
+            isCheckOrTriggerCondition = true;
+            condition                 = XreadBooleanValueExpression();
+            conditionSQL              = getLastPart(position);
+            isCheckOrTriggerCondition = false;
+
+            readThis(Tokens.CLOSEBRACKET);
+
+            HsqlList unresolved = condition.resolveColumnReferences(rangeVars,
+                null);
+
+            ExpressionColumn.checkColumnsResolved(unresolved);
+            condition.resolveTypes(session, null);
+
+            if (condition.getDataType() != Type.SQL_BOOLEAN) {
+                throw Error.error(ErrorCode.X_42568);
+            }
+        }
+
+        if (isForEachRow == null) {
+            isForEachRow = Boolean.FALSE;
+        }
+
+        if (token.tokenType == Tokens.CALL) {
+            int position = getPosition();
+
+            try {
+                read();
+                checkIsSimpleName();
+                checkIsDelimitedIdentifier();
+
+                className = token.tokenString;
+
+                read();
+
+                td = new TriggerDef(name, beforeOrAfterType, operationType,
+                                    isForEachRow.booleanValue(), table,
+                                    transitions, rangeVars, condition,
+                                    conditionSQL, updateColumnIndexes,
+                                    className, isNowait, queueSize);
+
+                String   sql  = getLastPart();
+                Object[] args = new Object[] {
+                    td, otherName
+                };
+
+                return new StatementSchema(sql, StatementTypes.CREATE_TRIGGER,
+                                           args, null, table.getName());
+            } catch (HsqlException e) {
+                rewind(position);
+            }
+        }
+
+        //
+        if (hasQueueSize) {
+            throw unexpectedToken(Tokens.T_QUEUE);
+        }
+
+        if (isNowait) {
+            throw unexpectedToken(Tokens.T_NOWAIT);
+        }
+
+        Routine routine = compileTriggerRoutine(table, rangeVars,
+            beforeOrAfterType, operationType);
+
+        td = new TriggerDefSQL(name, beforeOrAfterType, operationType,
+                               isForEachRow.booleanValue(), table,
+                               transitions, rangeVars, condition,
+                               conditionSQL, updateColumnIndexes, routine);
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[] {
+            td, otherName
+        };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_TRIGGER, args,
+                                   null, table.getName());
+    }
+
+    Routine compileTriggerRoutine(Table table, RangeVariable[] ranges,
+                                  int beforeOrAfter, int operation) {
+
+        int impact = (beforeOrAfter == TriggerDef.BEFORE) ? Routine.READS_SQL
+                                                          : Routine
+                                                              .MODIFIES_SQL;
+        Routine routine = new Routine(table, ranges, impact, beforeOrAfter,
+                                      operation);
+
+        startRecording();
+
+        Statement statement = compileSQLProcedureStatementOrNull(routine,
+            null);
+
+        if (statement == null) {
+            throw unexpectedToken();
+        }
+
+        Token[] tokenisedStatement = getRecordedStatement();
+        String  sql                = Token.getSQL(tokenisedStatement);
+
+        statement.setSQL(sql);
+        routine.setProcedure(statement);
+        routine.resolve(session);
+
+        return routine;
+    }
+
+    /**
+     * Responsible for handling the creation of table columns during the process
+     * of executing CREATE TABLE or ADD COLUMN etc. statements.
+     *
+     * @param table this table
+     * @param hsqlName column name
+     * @param constraintList list of constraints
+     * @return a Column object with indicated attributes
+     */
+    ColumnSchema readColumnDefinitionOrNull(Table table, HsqlName hsqlName,
+            HsqlArrayList constraintList) {
+
+        boolean        isGenerated     = false;
+        boolean        isIdentity      = false;
+        boolean        isPKIdentity    = false;
+        boolean        generatedAlways = false;
+        Expression     generateExpr    = null;
+        boolean        isNullable      = true;
+        Expression     defaultExpr     = null;
+        Type           typeObject      = null;
+        NumberSequence sequence        = null;
+
+        if (token.tokenType == Tokens.GENERATED) {
+            read();
+            readThis(Tokens.ALWAYS);
+
+            isGenerated     = true;
+            generatedAlways = true;
+
+            // not yet
+            throw unexpectedToken(Tokens.T_GENERATED);
+        } else if (token.tokenType == Tokens.IDENTITY) {
+            read();
+
+            isIdentity   = true;
+            isPKIdentity = true;
+            typeObject   = Type.SQL_INTEGER;
+            sequence     = new NumberSequence(null, 0, 1, typeObject);
+        } else if (token.tokenType == Tokens.COMMA) {
+            return null;
+        } else if (token.tokenType == Tokens.CLOSEBRACKET) {
+            return null;
+        } else {
+            typeObject = readTypeDefinition(true);
+        }
+
+        if (isGenerated || isIdentity) {}
+        else if (token.tokenType == Tokens.DEFAULT) {
+            read();
+
+            defaultExpr = readDefaultClause(typeObject);
+        } else if (token.tokenType == Tokens.GENERATED && !isIdentity) {
+            read();
+
+            if (token.tokenType == Tokens.BY) {
+                read();
+                readThis(Tokens.DEFAULT);
+            } else {
+                readThis(Tokens.ALWAYS);
+
+                generatedAlways = true;
+            }
+
+            readThis(Tokens.AS);
+
+            if (token.tokenType == Tokens.IDENTITY) {
+                read();
+
+                sequence = new NumberSequence(null, typeObject);
+
+                sequence.setAlways(generatedAlways);
+
+                if (token.tokenType == Tokens.OPENBRACKET) {
+                    read();
+                    readSequenceOptions(sequence, false, false);
+                    readThis(Tokens.CLOSEBRACKET);
+                }
+
+                isIdentity = true;
+            } else if (token.tokenType == Tokens.OPENBRACKET) {
+                if (!generatedAlways) {
+                    throw super.unexpectedTokenRequire(Tokens.T_ALWAYS);
+                }
+
+                isGenerated = true;
+            }
+        } else if (token.tokenType == Tokens.IDENTITY && !isIdentity) {
+            read();
+
+            isIdentity   = true;
+            isPKIdentity = true;
+            sequence     = new NumberSequence(null, 0, 1, typeObject);
+        }
+
+        if (isGenerated) {
+            readThis(Tokens.OPENBRACKET);
+
+            generateExpr = XreadValueExpression();
+
+            readThis(Tokens.CLOSEBRACKET);
+        }
+
+        ColumnSchema column = new ColumnSchema(hsqlName, typeObject,
+                                               isNullable, false, defaultExpr);
+
+        column.setGeneratingExpression(generateExpr);
+        readColumnConstraints(table, column, constraintList);
+
+        if (token.tokenType == Tokens.IDENTITY && !isIdentity) {
+            read();
+
+            isIdentity   = true;
+            isPKIdentity = true;
+            sequence     = new NumberSequence(null, 0, 1, typeObject);
+        }
+
+        if (isIdentity) {
+            column.setIdentity(sequence);
+        }
+
+        if (isPKIdentity && !column.isPrimaryKey()) {
+            OrderedHashSet set = new OrderedHashSet();
+
+            set.add(column.getName().name);
+
+            HsqlName constName = database.nameManager.newAutoName("PK",
+                table.getSchemaName(), table.getName(),
+                SchemaObject.CONSTRAINT);
+            Constraint c =
+                new Constraint(constName, set,
+                               SchemaObject.ConstraintTypes.PRIMARY_KEY);
+
+            constraintList.set(0, c);
+            column.setPrimaryKey(true);
+        }
+
+        return column;
+    }
+
+    private void readSequenceOptions(NumberSequence sequence,
+                                     boolean withType, boolean isAlter) {
+
+        OrderedIntHashSet set = new OrderedIntHashSet();
+
+        while (true) {
+            boolean end = false;
+
+            if (set.contains(token.tokenType)) {
+                throw unexpectedToken();
+            }
+
+            switch (token.tokenType) {
+
+                case Tokens.AS : {
+                    if (withType) {
+                        read();
+
+                        Type type = readTypeDefinition(true);
+
+                        sequence.setDefaults(sequence.getName(), type);
+
+                        break;
+                    }
+
+                    throw unexpectedToken();
+                }
+                case Tokens.START : {
+                    set.add(token.tokenType);
+                    read();
+                    readThis(Tokens.WITH);
+
+                    long value = readBigint();
+
+                    sequence.setStartValueNoCheck(value);
+
+                    break;
+                }
+                case Tokens.RESTART : {
+                    if (!isAlter) {
+                        end = true;
+
+                        break;
+                    }
+
+                    set.add(token.tokenType);
+                    read();
+
+                    if (readIfThis(Tokens.WITH)) {
+                        long value = readBigint();
+
+                        sequence.setCurrentValueNoCheck(value);
+                    } else {
+                        sequence.setStartValueDefault();
+                    }
+
+                    break;
+                }
+                case Tokens.INCREMENT : {
+                    set.add(token.tokenType);
+                    read();
+                    readThis(Tokens.BY);
+
+                    long value = readBigint();
+
+                    sequence.setIncrement(value);
+
+                    break;
+                }
+                case Tokens.NO :
+                    read();
+
+                    if (token.tokenType == Tokens.MAXVALUE) {
+                        sequence.setDefaultMaxValue();
+                    } else if (token.tokenType == Tokens.MINVALUE) {
+                        sequence.setDefaultMinValue();
+                    } else if (token.tokenType == Tokens.CYCLE) {
+                        sequence.setCycle(false);
+                    } else {
+                        throw unexpectedToken();
+                    }
+
+                    set.add(token.tokenType);
+                    read();
+                    break;
+
+                case Tokens.MAXVALUE : {
+                    set.add(token.tokenType);
+                    read();
+
+                    long value = readBigint();
+
+                    sequence.setMaxValueNoCheck(value);
+
+                    break;
+                }
+                case Tokens.MINVALUE : {
+                    set.add(token.tokenType);
+                    read();
+
+                    long value = readBigint();
+
+                    sequence.setMinValueNoCheck(value);
+
+                    break;
+                }
+                case Tokens.CYCLE :
+                    set.add(token.tokenType);
+                    read();
+                    sequence.setCycle(true);
+                    break;
+
+                default :
+                    end = true;
+                    break;
+            }
+
+            if (end) {
+                break;
+            }
+        }
+
+        sequence.checkValues();
+    }
+
+    /**
+     * Reads and adds a table constraint definition to the list
+     *
+     * @param schemaObject table or domain
+     * @param constraintList list of constraints
+     */
+    private void readConstraint(SchemaObject schemaObject,
+                                HsqlArrayList constraintList) {
+
+        HsqlName constName = null;
+
+        if (token.tokenType == Tokens.CONSTRAINT) {
+            read();
+
+            constName =
+                readNewDependentSchemaObjectName(schemaObject.getName(),
+                                                 SchemaObject.CONSTRAINT);
+        }
+
+        switch (token.tokenType) {
+
+            case Tokens.PRIMARY : {
+                if (schemaObject.getName().type != SchemaObject.TABLE) {
+                    throw this.unexpectedTokenRequire(Tokens.T_CHECK);
+                }
+
+                read();
+                readThis(Tokens.KEY);
+
+                Constraint mainConst;
+
+                mainConst = (Constraint) constraintList.get(0);
+
+                if (mainConst.constType
+                        == SchemaObject.ConstraintTypes.PRIMARY_KEY) {
+                    throw Error.error(ErrorCode.X_42532);
+                }
+
+                if (constName == null) {
+                    constName = database.nameManager.newAutoName("PK",
+                            schemaObject.getSchemaName(),
+                            schemaObject.getName(), SchemaObject.CONSTRAINT);
+                }
+
+                OrderedHashSet set = readColumnNames(false);
+                Constraint c =
+                    new Constraint(constName, set,
+                                   SchemaObject.ConstraintTypes.PRIMARY_KEY);
+
+                constraintList.set(0, c);
+
+                break;
+            }
+            case Tokens.UNIQUE : {
+                if (schemaObject.getName().type != SchemaObject.TABLE) {
+                    throw this.unexpectedTokenRequire(Tokens.T_CHECK);
+                }
+
+                read();
+
+                OrderedHashSet set = readColumnNames(false);
+
+                if (constName == null) {
+                    constName = database.nameManager.newAutoName("CT",
+                            schemaObject.getSchemaName(),
+                            schemaObject.getName(), SchemaObject.CONSTRAINT);
+                }
+
+                Constraint c =
+                    new Constraint(constName, set,
+                                   SchemaObject.ConstraintTypes.UNIQUE);
+
+                constraintList.add(c);
+
+                break;
+            }
+            case Tokens.FOREIGN : {
+                if (schemaObject.getName().type != SchemaObject.TABLE) {
+                    throw this.unexpectedTokenRequire(Tokens.T_CHECK);
+                }
+
+                read();
+                readThis(Tokens.KEY);
+
+                OrderedHashSet set = readColumnNames(false);
+                Constraint c = readFKReferences((Table) schemaObject,
+                                                constName, set);
+
+                constraintList.add(c);
+
+                break;
+            }
+            case Tokens.CHECK : {
+                read();
+
+                if (constName == null) {
+                    constName = database.nameManager.newAutoName("CT",
+                            schemaObject.getSchemaName(),
+                            schemaObject.getName(), SchemaObject.CONSTRAINT);
+                }
+
+                Constraint c =
+                    new Constraint(constName, null,
+                                   SchemaObject.ConstraintTypes.CHECK);
+
+                readCheckConstraintCondition(c);
+                constraintList.add(c);
+
+                break;
+            }
+            default : {
+                if (constName != null) {
+                    throw super.unexpectedToken();
+                }
+            }
+        }
+    }
+
+    /**
+     * Reads column constraints
+     */
+    void readColumnConstraints(Table table, ColumnSchema column,
+                               HsqlArrayList constraintList) {
+
+        boolean end                  = false;
+        boolean hasNotNullConstraint = false;
+        boolean hasNullNoiseWord     = false;
+        boolean hasPrimaryKey        = false;
+
+        while (true) {
+            HsqlName constName = null;
+
+            if (token.tokenType == Tokens.CONSTRAINT) {
+                read();
+
+                constName = readNewDependentSchemaObjectName(table.getName(),
+                        SchemaObject.CONSTRAINT);
+            }
+
+            switch (token.tokenType) {
+
+                case Tokens.PRIMARY : {
+                    if (hasNullNoiseWord || hasPrimaryKey) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.KEY);
+
+                    Constraint existingConst =
+                        (Constraint) constraintList.get(0);
+
+                    if (existingConst.constType
+                            == SchemaObject.ConstraintTypes.PRIMARY_KEY) {
+                        throw Error.error(ErrorCode.X_42532);
+                    }
+
+                    OrderedHashSet set = new OrderedHashSet();
+
+                    set.add(column.getName().name);
+
+                    if (constName == null) {
+                        constName = database.nameManager.newAutoName("PK",
+                                table.getSchemaName(), table.getName(),
+                                SchemaObject.CONSTRAINT);
+                    }
+
+                    Constraint c = new Constraint(
+                        constName, set,
+                        SchemaObject.ConstraintTypes.PRIMARY_KEY);
+
+                    constraintList.set(0, c);
+                    column.setPrimaryKey(true);
+
+                    hasPrimaryKey = true;
+
+                    break;
+                }
+                case Tokens.UNIQUE : {
+                    read();
+
+                    OrderedHashSet set = new OrderedHashSet();
+
+                    set.add(column.getName().name);
+
+                    if (constName == null) {
+                        constName = database.nameManager.newAutoName("CT",
+                                table.getSchemaName(), table.getName(),
+                                SchemaObject.CONSTRAINT);
+                    }
+
+                    Constraint c =
+                        new Constraint(constName, set,
+                                       SchemaObject.ConstraintTypes.UNIQUE);
+
+                    constraintList.add(c);
+
+                    break;
+                }
+                case Tokens.FOREIGN : {
+                    read();
+                    readThis(Tokens.KEY);
+                }
+
+                // fall through
+                case Tokens.REFERENCES : {
+                    OrderedHashSet set = new OrderedHashSet();
+
+                    set.add(column.getName().name);
+
+                    Constraint c = readFKReferences(table, constName, set);
+
+                    constraintList.add(c);
+
+                    break;
+                }
+                case Tokens.CHECK : {
+                    read();
+
+                    if (constName == null) {
+                        constName = database.nameManager.newAutoName("CT",
+                                table.getSchemaName(), table.getName(),
+                                SchemaObject.CONSTRAINT);
+                    }
+
+                    Constraint c =
+                        new Constraint(constName, null,
+                                       SchemaObject.ConstraintTypes.CHECK);
+
+                    readCheckConstraintCondition(c);
+
+                    OrderedHashSet set = c.getCheckColumnExpressions();
+
+                    for (int i = 0; i < set.size(); i++) {
+                        ExpressionColumn e = (ExpressionColumn) set.get(i);
+
+                        if (column.getName().name.equals(e.getColumnName())) {
+                            if (e.getSchemaName() != null
+                                    && e.getSchemaName()
+                                       != table.getSchemaName().name) {
+                                throw Error.error(ErrorCode.X_42505);
+                            }
+                        } else {
+                            throw Error.error(ErrorCode.X_42501);
+                        }
+                    }
+
+                    constraintList.add(c);
+
+                    break;
+                }
+                case Tokens.NOT : {
+                    if (hasNotNullConstraint || hasNullNoiseWord) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.NULL);
+
+                    if (constName == null) {
+                        constName = database.nameManager.newAutoName("CT",
+                                table.getSchemaName(), table.getName(),
+                                SchemaObject.CONSTRAINT);
+                    }
+
+                    Constraint c =
+                        new Constraint(constName, null,
+                                       SchemaObject.ConstraintTypes.CHECK);
+
+                    c.check = new ExpressionLogical(column);
+
+                    constraintList.add(c);
+
+                    hasNotNullConstraint = true;
+
+                    break;
+                }
+                case Tokens.NULL : {
+                    if (hasNotNullConstraint || hasNullNoiseWord
+                            || hasPrimaryKey) {
+                        throw unexpectedToken();
+                    }
+
+                    if (constName != null) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    hasNullNoiseWord = true;
+
+                    break;
+                }
+                default :
+                    end = true;
+                    break;
+            }
+
+            if (end) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Responsible for handling check constraints section of CREATE TABLE ...
+     *
+     * @param c check constraint
+     */
+    void readCheckConstraintCondition(Constraint c) {
+
+        readThis(Tokens.OPENBRACKET);
+        startRecording();
+
+        isCheckOrTriggerCondition = true;
+
+        Expression condition = XreadBooleanValueExpression();
+
+        isCheckOrTriggerCondition = false;
+
+        Token[] tokens = getRecordedStatement();
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        c.check = condition;
+    }
+
+    /**
+     * Process a bracketed column list as used in the declaration of SQL
+     * CONSTRAINTS and return an array containing the indexes of the columns
+     * within the table.
+     *
+     * @param table table that contains the columns
+     * @param ascOrDesc boolean
+     * @return array of column indexes
+     */
+    private int[] readColumnList(Table table, boolean ascOrDesc) {
+
+        OrderedHashSet set = readColumnNames(ascOrDesc);
+
+        return table.getColumnIndexes(set);
+    }
+
+    StatementSchema compileCreateIndex(boolean unique) {
+
+        Table    table;
+        HsqlName indexHsqlName;
+
+        read();
+
+        indexHsqlName = readNewSchemaObjectName(SchemaObject.INDEX, true);
+
+        readThis(Tokens.ON);
+
+        table = readTableName();
+
+        HsqlName tableSchema = table.getSchemaName();
+
+        indexHsqlName.setSchemaIfNull(tableSchema);
+
+        indexHsqlName.parent = table.getName();
+
+        if (indexHsqlName.schema != tableSchema) {
+            throw Error.error(ErrorCode.X_42505);
+        }
+
+        indexHsqlName.schema = table.getSchemaName();
+
+        int[]    indexColumns = readColumnList(table, true);
+        String   sql          = getLastPart();
+        Object[] args         = new Object[] {
+            table, indexColumns, indexHsqlName, Boolean.valueOf(unique)
+        };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_INDEX, args,
+                                   null, table.getName());
+    }
+
+    StatementSchema compileCreateSchema() {
+
+        HsqlName schemaName    = null;
+        String   authorisation = null;
+
+        read();
+
+        if (token.tokenType != Tokens.AUTHORIZATION) {
+            schemaName = readNewSchemaName();
+        }
+
+        if (token.tokenType == Tokens.AUTHORIZATION) {
+            read();
+            checkIsSimpleName();
+
+            authorisation = token.tokenString;
+
+            read();
+
+            if (schemaName == null) {
+                Grantee owner =
+                    database.getGranteeManager().get(authorisation);
+
+                if (owner == null) {
+                    throw Error.error(ErrorCode.X_28501, authorisation);
+                }
+
+                schemaName =
+                    database.nameManager.newHsqlName(owner.getName().name,
+                                                     isDelimitedIdentifier(),
+                                                     SchemaObject.SCHEMA);
+
+                SqlInvariants.checkSchemaNameNotSystem(token.tokenString);
+            }
+        }
+
+        if (SqlInvariants.PUBLIC_ROLE_NAME.equals(authorisation)) {
+            throw Error.error(ErrorCode.X_28502, authorisation);
+        }
+
+        Grantee owner = authorisation == null ? session.getGrantee()
+                                              : database.getGranteeManager()
+                                                  .get(authorisation);
+
+        if (owner == null) {
+            throw Error.error(ErrorCode.X_28501, authorisation);
+        }
+
+        if (!session.getGrantee().isSchemaCreator()) {
+            throw Error.error(ErrorCode.X_0L000,
+                              session.getGrantee().getNameString());
+        }
+
+        if (database.schemaManager.schemaExists(schemaName.name)) {
+            throw Error.error(ErrorCode.X_42504, schemaName.name);
+        }
+
+        if (schemaName.name.equals(SqlInvariants.LOBS_SCHEMA)) {
+            schemaName = SqlInvariants.LOBS_SCHEMA_HSQLNAME;
+            owner      = schemaName.owner;
+        }
+
+        String        sql  = getLastPart();
+        Object[]      args = new Object[] {
+            schemaName, owner
+        };
+        HsqlArrayList list = new HsqlArrayList();
+        StatementSchema cs = new StatementSchema(sql,
+            StatementTypes.CREATE_SCHEMA, args, null, null);
+
+        cs.setSchemaHsqlName(schemaName);
+        list.add(cs);
+        getCompiledStatementBody(list);
+
+        StatementSchema[] array = new StatementSchema[list.size()];
+
+        list.toArray(array);
+
+        boolean swapped;
+
+        do {
+            swapped = false;
+
+            for (int i = 0; i < array.length - 1; i++) {
+                if (array[i].order > array[i + 1].order) {
+                    StatementSchema temp = array[i + 1];
+
+                    array[i + 1] = array[i];
+                    array[i]     = temp;
+                    swapped      = true;
+                }
+            }
+        } while (swapped);
+
+        return new StatementSchemaDefinition(array);
+    }
+
+    void getCompiledStatementBody(HsqlList list) {
+
+        int    position;
+        String sql;
+        int    statementType;
+
+        for (boolean end = false; !end; ) {
+            StatementSchema cs = null;
+
+            position = getPosition();
+
+            switch (token.tokenType) {
+
+                case Tokens.CREATE :
+                    read();
+
+                    switch (token.tokenType) {
+
+                        // not in schema definition
+                        case Tokens.SCHEMA :
+                        case Tokens.USER :
+                        case Tokens.UNIQUE :
+                            throw unexpectedToken();
+                        case Tokens.INDEX :
+                            statementType = StatementTypes.CREATE_INDEX;
+                            sql = getStatement(position,
+                                               startStatementTokensSchema);
+                            cs = new StatementSchema(sql, statementType, null);
+                            break;
+
+                        case Tokens.SEQUENCE :
+                            cs     = compileCreateSequence();
+                            cs.sql = getLastPart(position);
+                            break;
+
+                        case Tokens.ROLE :
+                            cs     = compileCreateRole();
+                            cs.sql = getLastPart(position);
+                            break;
+
+                        case Tokens.DOMAIN :
+                            statementType = StatementTypes.CREATE_DOMAIN;
+                            sql = getStatement(position,
+                                               startStatementTokensSchema);
+                            cs = new StatementSchema(sql, statementType, null);
+                            break;
+
+                        case Tokens.TYPE :
+                            cs     = compileCreateType();
+                            cs.sql = getLastPart(position);
+                            break;
+
+                        case Tokens.CHARACTER :
+                            cs     = compileCreateCharacterSet();
+                            cs.sql = getLastPart(position);
+                            break;
+
+                        // no supported
+                        case Tokens.ASSERTION :
+                            throw unexpectedToken();
+                        case Tokens.TABLE :
+                        case Tokens.MEMORY :
+                        case Tokens.CACHED :
+                        case Tokens.TEMP :
+                        case Tokens.GLOBAL :
+                        case Tokens.TEMPORARY :
+                        case Tokens.TEXT :
+                            statementType = StatementTypes.CREATE_TABLE;
+                            sql = getStatement(position,
+                                               startStatementTokensSchema);
+                            cs = new StatementSchema(sql, statementType, null);
+                            break;
+
+                        case Tokens.TRIGGER :
+                            statementType = StatementTypes.CREATE_TRIGGER;
+                            sql = getStatement(position,
+                                               startStatementTokensSchema);
+                            cs = new StatementSchema(sql, statementType, null);
+                            break;
+
+                        case Tokens.VIEW :
+                            statementType = StatementTypes.CREATE_VIEW;
+                            sql = getStatement(position,
+                                               startStatementTokensSchema);
+                            cs = new StatementSchema(sql, statementType, null);
+                            break;
+
+                        case Tokens.FUNCTION :
+                            statementType = StatementTypes.CREATE_ROUTINE;
+                            sql = getStatementForRoutine(
+                                position, startStatementTokensSchema);
+                            cs = new StatementSchema(sql, statementType, null);
+                            break;
+
+                        case Tokens.PROCEDURE :
+                            statementType = StatementTypes.CREATE_ROUTINE;
+                            sql = getStatementForRoutine(
+                                position, startStatementTokensSchema);
+                            cs = new StatementSchema(sql, statementType, null);
+                            break;
+
+                        default :
+                            throw unexpectedToken();
+                    }
+                    break;
+
+                case Tokens.GRANT :
+                    cs     = compileGrantOrRevoke();
+                    cs.sql = getLastPart(position);
+                    break;
+
+                case Tokens.SEMICOLON :
+                    read();
+
+                    end = true;
+                    break;
+
+                case Tokens.X_ENDPARSE :
+                    end = true;
+                    break;
+
+                default :
+                    throw unexpectedToken();
+            }
+
+            if (cs != null) {
+                cs.isSchemaDefinition = true;
+
+                list.add(cs);
+            }
+        }
+    }
+
+    StatementSchema compileCreateRole() {
+
+        read();
+
+        HsqlName name = readNewUserIdentifier();
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ name };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_ROLE, args);
+    }
+
+    StatementSchema compileCreateUser() {
+
+        HsqlName name;
+        String   password;
+        boolean  admin   = false;
+        Grantee  grantor = session.getGrantee();
+
+        read();
+
+        name = readNewUserIdentifier();
+
+        readThis(Tokens.PASSWORD);
+
+        password = readPassword();
+
+        if (token.tokenType == Tokens.ADMIN) {
+            read();
+
+            admin = true;
+        }
+
+        checkDatabaseUpdateAuthorisation();
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[] {
+            name, password, grantor, Boolean.valueOf(admin)
+        };
+
+        return new StatementSchema(sql, StatementTypes.CREATE_USER, args);
+    }
+
+    HsqlName readNewUserIdentifier() {
+
+        checkIsSimpleName();
+
+        String  tokenS   = token.tokenString;
+        boolean isQuoted = isDelimitedIdentifier();
+
+        if (tokenS.equalsIgnoreCase("SA")) {
+            tokenS   = "SA";
+            isQuoted = false;
+        }
+
+        HsqlName name = database.nameManager.newHsqlName(tokenS, isQuoted,
+            SchemaObject.GRANTEE);
+
+        read();
+
+        return name;
+    }
+
+    String readPassword() {
+
+        String tokenS = token.tokenString;
+
+        read();
+
+        return tokenS;
+    }
+
+    Statement compileRenameObject(HsqlName name, int objectType) {
+
+        HsqlName newName = readNewSchemaObjectName(objectType, true);
+        String   sql     = getLastPart();
+        Object[] args    = new Object[] {
+            name, newName
+        };
+
+        return new StatementSchema(sql, StatementTypes.RENAME_OBJECT, args);
+    }
+
+    /**
+     * Responsible for handling tail of ALTER TABLE ... RENAME ...
+     * @param table table
+     */
+    void processAlterTableRename(Table table) {
+
+        HsqlName name = readNewSchemaObjectName(SchemaObject.TABLE, true);
+
+        name.setSchemaIfNull(table.getSchemaName());
+
+        if (table.getSchemaName() != name.schema) {
+            throw Error.error(ErrorCode.X_42505);
+        }
+
+        database.schemaManager.renameSchemaObject(table.getName(), name);
+    }
+
+    void processAlterTableAddUniqueConstraint(Table table, HsqlName name) {
+
+        if (name == null) {
+            name = database.nameManager.newAutoName("CT",
+                    table.getSchemaName(), table.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        int[] cols = this.readColumnList(table, false);
+
+        session.commit(false);
+
+        TableWorks tableWorks = new TableWorks(session, table);
+
+        tableWorks.addUniqueConstraint(cols, name);
+    }
+
+    Statement compileAlterTableAddUniqueConstraint(Table table,
+            HsqlName name) {
+
+        if (name == null) {
+            name = database.nameManager.newAutoName("CT",
+                    table.getSchemaName(), table.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        int[]    cols = this.readColumnList(table, false);
+        String   sql  = getLastPart();
+        Object[] args = new Object[] {
+            cols, name
+        };
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, args,
+                                   null, table.getName());
+    }
+
+    void processAlterTableAddForeignKeyConstraint(Table table, HsqlName name) {
+
+        if (name == null) {
+            name = database.nameManager.newAutoName("FK",
+                    table.getSchemaName(), table.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        OrderedHashSet set           = readColumnNames(false);
+        Constraint     c             = readFKReferences(table, name, set);
+        HsqlName       mainTableName = c.getMainTableName();
+
+        c.core.mainTable = database.schemaManager.getTable(session,
+                mainTableName.name, mainTableName.schema.name);
+
+        c.setColumnsIndexes(table);
+        session.commit(false);
+
+        TableWorks tableWorks = new TableWorks(session, table);
+
+        tableWorks.addForeignKey(c);
+    }
+
+    Statement compileAlterTableAddForeignKeyConstraint(Table table,
+            HsqlName name) {
+
+        if (name == null) {
+            name = database.nameManager.newAutoName("FK",
+                    table.getSchemaName(), table.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        OrderedHashSet set           = readColumnNames(false);
+        Constraint     c             = readFKReferences(table, name, set);
+        HsqlName       mainTableName = c.getMainTableName();
+
+        c.core.mainTable = database.schemaManager.getTable(session,
+                mainTableName.name, mainTableName.schema.name);
+
+        c.setColumnsIndexes(table);
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ c };
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, args,
+                                   c.core.mainTableName, table.getName());
+    }
+
+    void processAlterTableAddCheckConstraint(Table table, HsqlName name) {
+
+        Constraint check;
+
+        if (name == null) {
+            name = database.nameManager.newAutoName("CT",
+                    table.getSchemaName(), table.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        check = new Constraint(name, null, SchemaObject.ConstraintTypes.CHECK);
+
+        readCheckConstraintCondition(check);
+        session.commit(false);
+
+        TableWorks tableWorks = new TableWorks(session, table);
+
+        tableWorks.addCheckConstraint(check);
+    }
+
+    Statement compileAlterTableAddCheckConstraint(Table table, HsqlName name) {
+
+        Constraint check;
+
+        if (name == null) {
+            name = database.nameManager.newAutoName("CT",
+                    table.getSchemaName(), table.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        check = new Constraint(name, null, SchemaObject.ConstraintTypes.CHECK);
+
+        readCheckConstraintCondition(check);
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ check };
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, args,
+                                   null, table.getName());
+    }
+
+    void processAlterTableAddColumn(Table table) {
+
+        int           colIndex = table.getColumnCount();
+        HsqlArrayList list     = new HsqlArrayList();
+        Constraint constraint =
+            new Constraint(null, null, SchemaObject.ConstraintTypes.TEMP);
+
+        list.add(constraint);
+        checkIsSchemaObjectName();
+
+        HsqlName hsqlName =
+            database.nameManager.newColumnHsqlName(table.getName(),
+                token.tokenString, isDelimitedIdentifier());
+
+        read();
+
+        ColumnSchema column = readColumnDefinitionOrNull(table, hsqlName,
+            list);
+
+        if (column == null) {
+            throw Error.error(ErrorCode.X_42000);
+        }
+
+        if (token.tokenType == Tokens.BEFORE) {
+            read();
+
+            colIndex = table.getColumnIndex(token.tokenString);
+
+            read();
+        }
+
+        TableWorks tableWorks = new TableWorks(session, table);
+
+        session.commit(false);
+        tableWorks.addColumn(column, colIndex, list);
+
+        return;
+    }
+
+    Statement compileAlterTableAddColumn(Table table) {
+
+        int           colIndex = table.getColumnCount();
+        HsqlArrayList list     = new HsqlArrayList();
+        Constraint constraint =
+            new Constraint(null, null, SchemaObject.ConstraintTypes.TEMP);
+
+        list.add(constraint);
+        checkIsSchemaObjectName();
+
+        HsqlName hsqlName =
+            database.nameManager.newColumnHsqlName(table.getName(),
+                token.tokenString, isDelimitedIdentifier());
+
+        read();
+
+        ColumnSchema column = readColumnDefinitionOrNull(table, hsqlName,
+            list);
+
+        if (column == null) {
+            throw Error.error(ErrorCode.X_42000);
+        }
+
+        if (token.tokenType == Tokens.BEFORE) {
+            read();
+
+            colIndex = table.getColumnIndex(token.tokenString);
+
+            read();
+        }
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[] {
+            column, new Integer(colIndex), list
+        };
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, args,
+                                   null, table.getName());
+    }
+
+    void processAlterTableAddPrimaryKey(Table table, HsqlName name) {
+
+        if (name == null) {
+            name = session.database.nameManager.newAutoName("PK",
+                    table.getSchemaName(), table.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        OrderedHashSet set = readColumnNames(false);
+        Constraint constraint =
+            new Constraint(name, set,
+                           SchemaObject.ConstraintTypes.PRIMARY_KEY);
+
+        constraint.setColumnsIndexes(table);
+        session.commit(false);
+
+        TableWorks tableWorks = new TableWorks(session, table);
+
+        tableWorks.addPrimaryKey(constraint, name);
+    }
+
+    Statement compileAlterTableAddPrimaryKey(Table table, HsqlName name) {
+
+        if (name == null) {
+            name = session.database.nameManager.newAutoName("PK",
+                    table.getSchemaName(), table.getName(),
+                    SchemaObject.CONSTRAINT);
+        }
+
+        OrderedHashSet set = readColumnNames(false);
+        Constraint constraint =
+            new Constraint(name, set,
+                           SchemaObject.ConstraintTypes.PRIMARY_KEY);
+
+        constraint.setColumnsIndexes(table);
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[]{ constraint };
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, args,
+                                   null, table.getName());
+    }
+
+    /**
+     * Responsible for handling tail of ALTER TABLE ... DROP COLUMN ...
+     */
+    void processAlterTableDropColumn(Table table, String colName,
+                                     boolean cascade) {
+
+        int colindex = table.getColumnIndex(colName);
+
+        if (table.getColumnCount() == 1) {
+            throw Error.error(ErrorCode.X_42591);
+        }
+
+        session.commit(false);
+
+        TableWorks tableWorks = new TableWorks(session, table);
+
+        tableWorks.dropColumn(colindex, cascade);
+    }
+
+    Statement compileAlterTableDropColumn(Table table, String colName,
+                                          boolean cascade) {
+
+        HsqlName writeName = null;
+        int      colindex  = table.getColumnIndex(colName);
+
+        if (table.getColumnCount() == 1) {
+            throw Error.error(ErrorCode.X_42591);
+        }
+
+        Object[] args = new Object[] {
+            table.getColumn(colindex).getName(),
+            ValuePool.getInt(SchemaObject.CONSTRAINT),
+            Boolean.valueOf(cascade), Boolean.valueOf(false)
+        };
+
+        if (!table.isTemp()) {
+            writeName = table.getName();
+        }
+
+        return new StatementSchema(null, StatementTypes.DROP_COLUMN, args,
+                                   null, writeName);
+    }
+
+    /**
+     * Responsible for handling tail of ALTER TABLE ... DROP CONSTRAINT ...
+     */
+    void processAlterTableDropConstraint(Table table, String name,
+                                         boolean cascade) {
+
+        session.commit(false);
+
+        TableWorks tableWorks = new TableWorks(session, table);
+
+        tableWorks.dropConstraint(name, cascade);
+
+        return;
+    }
+
+    void processAlterColumn(Table table, ColumnSchema column,
+                            int columnIndex) {
+
+        int position = getPosition();
+
+        switch (token.tokenType) {
+
+            case Tokens.RENAME : {
+                read();
+                readThis(Tokens.TO);
+                processAlterColumnRename(table, column);
+
+                return;
+            }
+            case Tokens.DROP : {
+                read();
+
+                if (token.tokenType == Tokens.DEFAULT) {
+                    read();
+
+                    TableWorks tw = new TableWorks(session, table);
+
+                    tw.setColDefaultExpression(columnIndex, null);
+
+                    return;
+                } else if (token.tokenType == Tokens.GENERATED) {
+                    read();
+                    column.setIdentity(null);
+                    table.setColumnTypeVars(columnIndex);
+
+                    return;
+                } else {
+                    throw unexpectedToken();
+                }
+            }
+            case Tokens.SET : {
+                read();
+
+                switch (token.tokenType) {
+
+                    case Tokens.DATA : {
+                        read();
+                        readThis(Tokens.TYPE);
+                        processAlterColumnDataType(table, column);
+
+                        return;
+                    }
+                    case Tokens.DEFAULT : {
+                        read();
+
+                        //ALTER TABLE .. ALTER COLUMN .. SET DEFAULT
+                        TableWorks tw   = new TableWorks(session, table);
+                        Type       type = column.getDataType();
+                        Expression expr = this.readDefaultClause(type);
+
+                        tw.setColDefaultExpression(columnIndex, expr);
+
+                        return;
+                    }
+                    case Tokens.NOT : {
+
+                        //ALTER TABLE .. ALTER COLUMN .. SET NOT NULL
+                        read();
+                        readThis(Tokens.NULL);
+                        session.commit(false);
+
+                        TableWorks tw = new TableWorks(session, table);
+
+                        tw.setColNullability(column, false);
+
+                        return;
+                    }
+                    case Tokens.NULL : {
+                        read();
+
+                        //ALTER TABLE .. ALTER COLUMN .. SET NULL
+                        session.commit(false);
+
+                        TableWorks tw = new TableWorks(session, table);
+
+                        tw.setColNullability(column, true);
+
+                        return;
+                    }
+                    default :
+                        rewind(position);
+                        read();
+                        break;
+                }
+            }
+            default :
+        }
+
+        if (token.tokenType == Tokens.SET
+                || token.tokenType == Tokens.RESTART) {
+            if (!column.isIdentity()) {
+                throw Error.error(ErrorCode.X_42535);
+            }
+
+            processAlterColumnSequenceOptions(column);
+
+            return;
+        } else {
+            processAlterColumnType(table, column, true);
+
+            return;
+        }
+    }
+
+    Statement compileAlterColumn(Table table, ColumnSchema column,
+                                 int columnIndex) {
+
+        int position = getPosition();
+
+        switch (token.tokenType) {
+
+            case Tokens.RENAME : {
+                read();
+                readThis(Tokens.TO);
+
+                return compileAlterColumnRename(table, column);
+            }
+            case Tokens.DROP : {
+                read();
+
+                if (token.tokenType == Tokens.DEFAULT) {
+                    read();
+
+                    return compileAlterColumnDropDefault(table, column,
+                                                         columnIndex);
+                } else if (token.tokenType == Tokens.GENERATED) {
+                    read();
+
+                    return compileAlterColumnDropGenerated(table, column,
+                                                           columnIndex);
+                } else {
+                    throw unexpectedToken();
+                }
+            }
+            case Tokens.SET : {
+                read();
+
+                switch (token.tokenType) {
+
+                    case Tokens.DATA : {
+                        read();
+                        readThis(Tokens.TYPE);
+
+                        return compileAlterColumnDataType(table, column);
+                    }
+                    case Tokens.DEFAULT : {
+                        read();
+
+                        //ALTER TABLE .. ALTER COLUMN .. SET DEFAULT
+                        Type       type = column.getDataType();
+                        Expression expr = this.readDefaultClause(type);
+
+                        return compileAlterColumnSetDefault(table, column,
+                                                            expr);
+                    }
+                    case Tokens.NOT : {
+
+                        //ALTER TABLE .. ALTER COLUMN .. SET NOT NULL
+                        read();
+                        readThis(Tokens.NULL);
+
+                        return compileAlterColumnSetNullability(table, column,
+                                false);
+                    }
+                    case Tokens.NULL : {
+                        read();
+
+                        return compileAlterColumnSetNullability(table, column,
+                                true);
+                    }
+                    default :
+                        rewind(position);
+                        read();
+                        break;
+                }
+            }
+
+            // fall through
+            default :
+        }
+
+        if (token.tokenType == Tokens.SET
+                || token.tokenType == Tokens.RESTART) {
+            if (!column.isIdentity()) {
+                throw Error.error(ErrorCode.X_42535);
+            }
+
+            return compileAlterColumnSequenceOptions(table, column);
+        } else {
+            return compileAlterColumnType(table, column);
+        }
+    }
+
+    private Statement compileAlterColumnDataType(Table table,
+            ColumnSchema column) {
+
+        HsqlName writeName  = null;
+        Type     typeObject = readTypeDefinition(false);
+        String   sql        = getLastPart();
+        Object[] args       = new Object[] {
+            table, column, typeObject
+        };
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, null,
+                                   null, table.getName());
+    }
+
+    private Statement compileAlterColumnType(Table table,
+            ColumnSchema column) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, null,
+                                   table.getName());
+    }
+
+    private Statement compileAlterColumnSequenceOptions(Table table,
+            ColumnSchema column) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, null,
+                                   table.getName());
+    }
+
+    private Statement compileAlterColumnSetNullability(Table table,
+            ColumnSchema column, boolean b) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, null,
+                                   table.getName());
+    }
+
+    private Statement compileAlterColumnSetDefault(Table table,
+            ColumnSchema column, Expression expr) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, null,
+                                   table.getName());
+    }
+
+    private Statement compileAlterColumnDropGenerated(Table table,
+            ColumnSchema column, int columnIndex) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, null,
+                                   table.getName());
+    }
+
+    private Statement compileAlterColumnDropDefault(Table table,
+            ColumnSchema column, int columnIndex) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_TABLE, null,
+                                   table.getName());
+    }
+
+    Statement compileAlterSequence() {
+
+        read();
+
+        HsqlName schema = session.getSchemaHsqlName(token.namePrefix);
+        NumberSequence sequence =
+            database.schemaManager.getSequence(token.tokenString, schema.name,
+                                               true);
+
+        read();
+
+        if (token.tokenType == Tokens.RENAME) {
+            read();
+            readThis(Tokens.TO);
+
+            return compileRenameObject(sequence.getName(),
+                                       SchemaObject.SEQUENCE);
+        }
+
+        NumberSequence copy = sequence.duplicate();
+
+        readSequenceOptions(copy, false, true);
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[] {
+            sequence, copy
+        };
+
+        return new StatementSchema(sql, StatementTypes.ALTER_SEQUENCE, args);
+    }
+
+    void processAlterColumnSequenceOptions(ColumnSchema column) {
+
+        OrderedIntHashSet set      = new OrderedIntHashSet();
+        NumberSequence    sequence = column.getIdentitySequence().duplicate();
+
+        while (true) {
+            boolean end = false;
+
+            switch (token.tokenType) {
+
+                case Tokens.RESTART : {
+                    if (!set.add(token.tokenType)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.WITH);
+
+                    long value = readBigint();
+
+                    sequence.setStartValue(value);
+
+                    break;
+                }
+                case Tokens.SET :
+                    read();
+
+                    switch (token.tokenType) {
+
+                        case Tokens.INCREMENT : {
+                            if (!set.add(token.tokenType)) {
+                                throw unexpectedToken();
+                            }
+
+                            read();
+                            readThis(Tokens.BY);
+
+                            long value = readBigint();
+
+                            sequence.setIncrement(value);
+
+                            break;
+                        }
+                        case Tokens.NO :
+                            read();
+
+                            if (token.tokenType == Tokens.MAXVALUE) {
+                                sequence.setDefaultMaxValue();
+                            } else if (token.tokenType == Tokens.MINVALUE) {
+                                sequence.setDefaultMinValue();
+                            } else if (token.tokenType == Tokens.CYCLE) {
+                                sequence.setCycle(false);
+                            } else {
+                                throw unexpectedToken();
+                            }
+
+                            if (!set.add(token.tokenType)) {
+                                throw unexpectedToken();
+                            }
+
+                            read();
+                            break;
+
+                        case Tokens.MAXVALUE : {
+                            if (!set.add(token.tokenType)) {
+                                throw unexpectedToken();
+                            }
+
+                            read();
+
+                            long value = readBigint();
+
+                            sequence.setMaxValueNoCheck(value);
+
+                            break;
+                        }
+                        case Tokens.MINVALUE : {
+                            if (!set.add(token.tokenType)) {
+                                throw unexpectedToken();
+                            }
+
+                            read();
+
+                            long value = readBigint();
+
+                            sequence.setMinValueNoCheck(value);
+
+                            break;
+                        }
+                        case Tokens.CYCLE :
+                            if (!set.add(token.tokenType)) {
+                                throw unexpectedToken();
+                            }
+
+                            read();
+                            sequence.setCycle(true);
+                            break;
+
+                        default :
+                            throw super.unexpectedToken();
+                    }
+                    break;
+
+                default :
+                    end = true;
+                    break;
+            }
+
+            if (end) {
+                break;
+            }
+        }
+
+        sequence.checkValues();
+        column.getIdentitySequence().reset(sequence);
+    }
+
+    /**
+     * Should allow only limited changes to column type
+     */
+    private void processAlterColumnDataType(Table table, ColumnSchema oldCol) {
+        processAlterColumnType(table, oldCol, false);
+    }
+
+    /**
+     * Allows changes to type of column or addition of an IDENTITY generator.
+     * IDENTITY is not removed if it does not appear in new column definition
+     * Constraint definitions are not allowed
+     */
+    private void processAlterColumnType(Table table, ColumnSchema oldCol,
+                                        boolean fullDefinition) {
+
+        ColumnSchema newCol;
+
+        if (oldCol.isGenerated()) {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        if (fullDefinition) {
+            HsqlArrayList list = new HsqlArrayList();
+            Constraint    c    = table.getPrimaryConstraint();
+
+            if (c == null) {
+                c = new Constraint(null, null,
+                                   SchemaObject.ConstraintTypes.TEMP);
+            }
+
+            list.add(c);
+
+            newCol = readColumnDefinitionOrNull(table, oldCol.getName(), list);
+
+            if (newCol == null) {
+                throw Error.error(ErrorCode.X_42000);
+            }
+
+            if (oldCol.isIdentity() && newCol.isIdentity()) {
+                throw Error.error(ErrorCode.X_42525);
+            }
+
+            if (list.size() > 1) {
+                throw Error.error(ErrorCode.X_42524);
+            }
+        } else {
+            Type type = readTypeDefinition(true);
+
+            if (oldCol.isIdentity()) {
+                if (!type.isIntegralType()) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+            }
+
+            newCol = oldCol.duplicate();
+
+            newCol.setType(type);
+        }
+
+        TableWorks tw = new TableWorks(session, table);
+
+        tw.retypeColumn(oldCol, newCol);
+    }
+
+    /**
+     * Responsible for handling tail of ALTER COLUMN ... RENAME ...
+     */
+    private void processAlterColumnRename(Table table, ColumnSchema column) {
+
+        checkIsSimpleName();
+
+        if (table.findColumn(token.tokenString) > -1) {
+            throw Error.error(ErrorCode.X_42504, token.tokenString);
+        }
+
+        database.schemaManager.checkColumnIsReferenced(table.getName(),
+                column.getName());
+        session.commit(false);
+        table.renameColumn(column, token.tokenString, isDelimitedIdentifier());
+        read();
+    }
+
+    private Statement compileAlterColumnRename(Table table,
+            ColumnSchema column) {
+
+        checkIsSimpleName();
+
+        HsqlName name = readNewSchemaObjectName(SchemaObject.COLUMN, true);
+
+        if (table.findColumn(name.name) > -1) {
+            throw Error.error(ErrorCode.X_42504, name.name);
+        }
+
+        database.schemaManager.checkColumnIsReferenced(table.getName(),
+                column.getName());
+
+        String   sql  = getLastPart();
+        Object[] args = new Object[] {
+            column.getName(), name
+        };
+
+        return new StatementSchema(sql, StatementTypes.RENAME_OBJECT, args);
+    }
+
+    Statement compileAlterSchemaRename() {
+
+        HsqlName name = readSchemaName();
+
+        checkSchemaUpdateAuthorisation(name);
+        readThis(Tokens.RENAME);
+        readThis(Tokens.TO);
+
+        HsqlName newName = readNewSchemaName();
+        String   sql     = getLastPart();
+        Object[] args    = new Object[] {
+            name, newName
+        };
+
+        return new StatementSchema(sql, StatementTypes.RENAME_OBJECT, args);
+    }
+
+    Statement compileAlterUser() {
+
+        read();
+
+        String   password;
+        User     userObject;
+        HsqlName userName = readNewUserIdentifier();
+
+        userObject = database.getUserManager().get(userName.name);
+
+        if (userName.name.equals(Tokens.T_PUBLIC)) {
+            throw Error.error(ErrorCode.X_42503);
+        }
+
+        readThis(Tokens.SET);
+
+        if (token.tokenType == Tokens.PASSWORD) {
+            read();
+
+            password = readPassword();
+
+            Object[] args = new Object[] {
+                userObject, password
+            };
+
+            return new StatementCommand(StatementTypes.SET_USER_PASSWORD,
+                                        args);
+        } else if (token.tokenType == Tokens.INITIAL) {
+            read();
+            readThis(Tokens.SCHEMA);
+
+            HsqlName schemaName;
+
+            if (token.tokenType == Tokens.DEFAULT) {
+                schemaName = null;
+            } else {
+                schemaName = database.schemaManager.getSchemaHsqlName(
+                    token.tokenString);
+            }
+
+            read();
+
+            Object[] args = new Object[] {
+                userObject, schemaName
+            };
+
+            return new StatementCommand(StatementTypes.SET_USER_INITIAL_SCHEMA,
+                                        args);
+        } else {
+            throw unexpectedToken();
+        }
+    }
+
+    void processAlterDomain() {
+
+        HsqlName schema = session.getSchemaHsqlName(token.namePrefix);
+
+        checkSchemaUpdateAuthorisation(schema);
+
+        Type domain = database.schemaManager.getDomain(token.tokenString,
+            schema.name, true);
+
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.RENAME : {
+                read();
+                readThis(Tokens.TO);
+
+                HsqlName newName = readNewSchemaObjectName(SchemaObject.DOMAIN,
+                    true);
+
+                newName.setSchemaIfNull(schema);
+
+                if (domain.getSchemaName() != newName.schema) {
+                    throw Error.error(ErrorCode.X_42505, newName.schema.name);
+                }
+
+                checkSchemaUpdateAuthorisation(schema);
+                database.schemaManager.renameSchemaObject(domain.getName(),
+                        newName);
+
+                return;
+            }
+            case Tokens.DROP : {
+                read();
+
+                if (token.tokenType == Tokens.DEFAULT) {
+                    read();
+                    domain.userTypeModifier.removeDefaultClause();
+
+                    return;
+                } else if (token.tokenType == Tokens.CONSTRAINT) {
+                    read();
+                    checkIsSchemaObjectName();
+
+                    HsqlName name = database.schemaManager.getSchemaObjectName(
+                        domain.getSchemaName(), token.tokenString,
+                        SchemaObject.CONSTRAINT, true);
+
+                    read();
+                    database.schemaManager.removeSchemaObject(name);
+
+                    return;
+                } else {
+                    throw unexpectedToken();
+                }
+            }
+            case Tokens.SET : {
+                read();
+                readThis(Tokens.DEFAULT);
+
+                Expression e = readDefaultClause(domain);
+
+                domain.userTypeModifier.setDefaultClause(e);
+
+                return;
+            }
+            case Tokens.ADD : {
+                read();
+
+                if (token.tokenType == Tokens.CONSTRAINT
+                        || token.tokenType == Tokens.CHECK) {
+                    HsqlArrayList tempConstraints = new HsqlArrayList();
+
+                    readConstraint(domain, tempConstraints);
+
+                    Constraint c = (Constraint) tempConstraints.get(0);
+
+                    domain.userTypeModifier.addConstraint(c);
+                    database.schemaManager.addSchemaObject(c);
+
+                    return;
+                }
+            }
+        }
+
+        throw unexpectedToken();
+    }
+
+    Statement compileAlterDomain() {
+
+        read();
+
+        HsqlName schema = session.getSchemaHsqlName(token.namePrefix);
+        Type domain = database.schemaManager.getDomain(token.tokenString,
+            schema.name, true);
+
+        read();
+
+        switch (token.tokenType) {
+
+            case Tokens.RENAME : {
+                read();
+                readThis(Tokens.TO);
+
+                return compileRenameObject(domain.getName(),
+                                           SchemaObject.DOMAIN);
+            }
+            case Tokens.DROP : {
+                read();
+
+                if (token.tokenType == Tokens.DEFAULT) {
+                    read();
+
+                    return compileAlterDomainDropDefault(domain);
+                } else if (token.tokenType == Tokens.CONSTRAINT) {
+                    read();
+                    checkIsSchemaObjectName();
+
+                    HsqlName name = database.schemaManager.getSchemaObjectName(
+                        domain.getSchemaName(), token.tokenString,
+                        SchemaObject.CONSTRAINT, true);
+
+                    read();
+
+                    return compileAlterDomainDropConstraint(domain, name);
+                } else {
+                    throw unexpectedToken();
+                }
+            }
+            case Tokens.SET : {
+                read();
+                readThis(Tokens.DEFAULT);
+
+                Expression e = readDefaultClause(domain);
+
+                return compileAlterDomainSetDefault(domain, e);
+            }
+            case Tokens.ADD : {
+                read();
+
+                if (token.tokenType == Tokens.CONSTRAINT
+                        || token.tokenType == Tokens.CHECK) {
+                    HsqlArrayList tempConstraints = new HsqlArrayList();
+
+                    readConstraint(domain, tempConstraints);
+
+                    Constraint c = (Constraint) tempConstraints.get(0);
+
+                    return compileAlterDomainAddConstraint(domain, c);
+                }
+            }
+        }
+
+        throw unexpectedToken();
+    }
+
+    private Statement compileAlterDomainAddConstraint(Type domain,
+            Constraint c) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_DOMAIN, null,
+                                   null);
+    }
+
+    private Statement compileAlterDomainSetDefault(Type domain, Expression e) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_DOMAIN, null,
+                                   null);
+    }
+
+    private Statement compileAlterDomainDropConstraint(Type domain,
+            HsqlName name) {
+
+        String sql = super.getStatement(getParsePosition(),
+                                        startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_DOMAIN, null,
+                                   null);
+    }
+
+    private Statement compileAlterDomainDropDefault(Type domain) {
+
+        String sql = getStatement(getParsePosition(), startStatementTokens);
+
+        return new StatementSchema(sql, StatementTypes.ALTER_DOMAIN, null,
+                                   null);
+    }
+
+    private boolean isGrantToken() {
+
+        switch (token.tokenType) {
+
+            case Tokens.ALL :
+            case Tokens.INSERT :
+            case Tokens.UPDATE :
+            case Tokens.SELECT :
+            case Tokens.DELETE :
+            case Tokens.USAGE :
+            case Tokens.EXECUTE :
+            case Tokens.REFERENCES :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    StatementSchema compileGrantOrRevoke() {
+
+        boolean grant = token.tokenType == Tokens.GRANT;
+
+        read();
+
+        if (isGrantToken()
+                || (!grant
+                    && (token.tokenType == Tokens.GRANT
+                        || token.tokenType == Tokens.HIERARCHY))) {
+            return compileRightGrantOrRevoke(grant);
+        } else {
+            return compileRoleGrantOrRevoke(grant);
+        }
+    }
+
+    private StatementSchema compileRightGrantOrRevoke(boolean grant) {
+
+        OrderedHashSet granteeList = new OrderedHashSet();
+        Grantee        grantor     = null;
+        Right          right       = null;
+
+//        SchemaObject   schemaObject;
+        HsqlName objectName    = null;
+        boolean  isTable       = false;
+        boolean  isUsage       = false;
+        boolean  isExec        = false;
+        boolean  isAll         = false;
+        boolean  isGrantOption = false;
+        boolean  cascade       = false;
+
+        if (!grant) {
+            if (token.tokenType == Tokens.GRANT) {
+                read();
+                readThis(Tokens.OPTION);
+                readThis(Tokens.FOR);
+
+                isGrantOption = true;
+
+                // throw not suppoerted
+            } else if (token.tokenType == Tokens.HIERARCHY) {
+                throw unsupportedFeature();
+/*
+                read();
+                readThis(Token.OPTION);
+                readThis(Token.FOR);
+*/
+            }
+        }
+
+        // ALL means all the rights the grantor can grant
+        if (token.tokenType == Tokens.ALL) {
+            read();
+
+            if (token.tokenType == Tokens.PRIVILEGES) {
+                read();
+            }
+
+            right = Right.fullRights;
+            isAll = true;
+        } else {
+            right = new Right();
+
+            boolean loop = true;
+
+            while (loop) {
+                checkIsNotQuoted();
+
+                int rightType =
+                    GranteeManager.getCheckSingleRight(token.tokenString);
+                int            grantType = token.tokenType;
+                OrderedHashSet columnSet = null;
+
+                read();
+
+                switch (grantType) {
+
+                    case Tokens.REFERENCES :
+                    case Tokens.SELECT :
+                    case Tokens.INSERT :
+                    case Tokens.UPDATE :
+                        if (token.tokenType == Tokens.OPENBRACKET) {
+                            columnSet = readColumnNames(false);
+                        }
+
+                    // fall through
+                    case Tokens.DELETE :
+                    case Tokens.TRIGGER :
+                        if (right == null) {
+                            right = new Right();
+                        }
+
+                        right.set(rightType, columnSet);
+
+                        isTable = true;
+                        break;
+
+                    case Tokens.USAGE :
+                        if (isTable) {
+                            throw unexpectedToken();
+                        }
+
+                        right   = Right.fullRights;
+                        isUsage = true;
+                        loop    = false;
+
+                        continue;
+                    case Tokens.EXECUTE :
+                        if (isTable) {
+                            throw unexpectedToken();
+                        }
+
+                        right  = Right.fullRights;
+                        isExec = true;
+                        loop   = false;
+
+                        continue;
+                }
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+
+                    continue;
+                }
+
+                break;
+            }
+        }
+
+        readThis(Tokens.ON);
+
+        int objectType = 0;
+
+        switch (token.tokenType) {
+
+            case Tokens.CLASS :
+                if (!isExec && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                if (!isSimpleName() || !isDelimitedIdentifier()) {
+                    throw Error.error(ErrorCode.X_42569);
+                }
+
+                objectType = SchemaObject.FUNCTION;
+                objectName = readNewSchemaObjectName(SchemaObject.FUNCTION,
+                                                     false);
+                break;
+
+            case Tokens.SPECIFIC : {
+                if (!isExec && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                switch (token.tokenType) {
+
+                    case Tokens.ROUTINE :
+                    case Tokens.PROCEDURE :
+                    case Tokens.FUNCTION :
+                        read();
+                        break;
+
+                    default :
+                        throw unexpectedToken();
+                }
+
+                objectType = SchemaObject.SPECIFIC_ROUTINE;
+
+                break;
+            }
+            case Tokens.FUNCTION :
+                if (!isExec && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                objectType = SchemaObject.FUNCTION;
+                break;
+
+            case Tokens.PROCEDURE :
+                if (!isExec && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                objectType = SchemaObject.PROCEDURE;
+                break;
+
+            case Tokens.ROUTINE :
+                if (!isExec && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                objectType = SchemaObject.ROUTINE;
+                break;
+
+            case Tokens.TYPE :
+                if (!isUsage && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                objectType = SchemaObject.TYPE;
+                break;
+
+            case Tokens.DOMAIN :
+                if (!isUsage && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                objectType = SchemaObject.DOMAIN;
+                break;
+
+            case Tokens.SEQUENCE :
+                if (!isUsage && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                objectType = SchemaObject.SEQUENCE;
+                break;
+
+            case Tokens.CHARACTER :
+                if (!isUsage && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                read();
+                readThis(Tokens.SET);
+
+                objectType = SchemaObject.CHARSET;
+                break;
+
+            case Tokens.TABLE :
+            default :
+                if (!isTable && !isAll) {
+                    throw unexpectedToken();
+                }
+
+                readIfThis(Tokens.TABLE);
+
+                objectType = SchemaObject.TABLE;
+        }
+
+        objectName = readNewSchemaObjectName(objectType, false);
+
+        if (grant) {
+            readThis(Tokens.TO);
+        } else {
+            readThis(Tokens.FROM);
+        }
+
+        while (true) {
+            checkIsSimpleName();
+            granteeList.add(token.tokenString);
+            read();
+
+            if (token.tokenType == Tokens.COMMA) {
+                read();
+            } else {
+                break;
+            }
+        }
+
+        if (grant) {
+            if (token.tokenType == Tokens.WITH) {
+                read();
+                readThis(Tokens.GRANT);
+                readThis(Tokens.OPTION);
+
+                isGrantOption = true;
+            }
+
+            /** @todo - implement */
+            if (token.tokenType == Tokens.GRANTED) {
+                read();
+                readThis(Tokens.BY);
+
+                if (token.tokenType == Tokens.CURRENT_USER) {
+                    read();
+
+                    //
+                } else {
+                    readThis(Tokens.CURRENT_ROLE);
+
+                    if (session.getRole() == null) {
+                        throw Error.error(ErrorCode.X_0P000);
+                    }
+
+                    grantor = session.getRole();
+                }
+            }
+        } else {
+            if (token.tokenType == Tokens.CASCADE) {
+                cascade = true;
+
+                read();
+            } else {
+                readThis(Tokens.RESTRICT);
+            }
+        }
+
+        int      typee = grant ? StatementTypes.GRANT
+                               : StatementTypes.REVOKE;
+        Object[] args  = new Object[] {
+            granteeList, objectName, right, grantor, Boolean.valueOf(cascade),
+            Boolean.valueOf(isGrantOption)
+        };
+        String          sql = getLastPart();
+        StatementSchema cs  = new StatementSchema(sql, typee, args);
+
+        return cs;
+    }
+
+    private StatementSchema compileRoleGrantOrRevoke(boolean grant) {
+
+        Grantee        grantor     = session.getGrantee();
+        OrderedHashSet roleList    = new OrderedHashSet();
+        OrderedHashSet granteeList = new OrderedHashSet();
+        boolean        cascade     = false;
+
+        if (!grant && token.tokenType == Tokens.ADMIN) {
+            throw unsupportedFeature();
+/*
+            read();
+            readThis(Token.OPTION);
+            readThis(Token.FOR);
+*/
+        }
+
+        while (true) {
+            checkIsSimpleName();
+            roleList.add(token.tokenString);
+            read();
+
+            if (token.tokenType == Tokens.COMMA) {
+                read();
+
+                continue;
+            }
+
+            break;
+        }
+
+        if (grant) {
+            readThis(Tokens.TO);
+        } else {
+            readThis(Tokens.FROM);
+        }
+
+        while (true) {
+            checkIsSimpleName();
+            granteeList.add(token.tokenString);
+            read();
+
+            if (token.tokenType == Tokens.COMMA) {
+                read();
+            } else {
+                break;
+            }
+        }
+
+        if (grant) {
+            if (token.tokenType == Tokens.WITH) {
+                throw unsupportedFeature();
+/*
+                read();
+                readThis(Token.ADMIN);
+                readThis(Token.OPTION);
+*/
+            }
+        }
+
+        if (token.tokenType == Tokens.GRANTED) {
+            read();
+            readThis(Tokens.BY);
+
+            if (token.tokenType == Tokens.CURRENT_USER) {
+                read();
+
+                //
+            } else {
+                readThis(Tokens.CURRENT_ROLE);
+
+                if (session.getRole() == null) {
+                    throw Error.error(ErrorCode.X_0P000);
+                }
+
+                grantor = session.getRole();
+            }
+        }
+
+        if (!grant) {
+            if (token.tokenType == Tokens.CASCADE) {
+                cascade = true;
+
+                read();
+            } else {
+                readThis(Tokens.RESTRICT);
+            }
+        }
+
+        int             type = grant ? StatementTypes.GRANT_ROLE
+                                     : StatementTypes.REVOKE_ROLE;
+        Object[]        args = new Object[] {
+            granteeList, roleList, grantor, Boolean.valueOf(cascade)
+        };
+        String          sql  = getLastPart();
+        StatementSchema cs   = new StatementSchema(sql, type, args);
+
+        return cs;
+    }
+
+    void checkSchemaUpdateAuthorisation(HsqlName schema) {
+
+        if (session.isProcessingLog) {
+            return;
+        }
+
+        SqlInvariants.checkSchemaNameNotSystem(schema.name);
+
+        if (isSchemaDefinition) {
+            if (schema != session.getCurrentSchemaHsqlName()) {
+                throw Error.error(ErrorCode.X_42505);
+            }
+        } else {
+            session.getGrantee().checkSchemaUpdateOrGrantRights(schema.name);
+        }
+
+        session.checkDDLWrite();
+    }
+
+    void checkDatabaseUpdateAuthorisation() {
+        session.checkAdmin();
+        session.checkDDLWrite();
+    }
+
+    StatementSchema compileComment() {
+
+        HsqlName name;
+        int      type;
+
+        readThis(Tokens.COMMENT);
+        readThis(Tokens.ON);
+
+        switch (token.tokenType) {
+
+            case Tokens.ROUTINE :
+            case Tokens.TABLE : {
+                type = token.tokenType == Tokens.ROUTINE ? SchemaObject.ROUTINE
+                                                         : SchemaObject.TABLE;
+
+                read();
+                checkIsSchemaObjectName();
+
+                name = database.nameManager.newHsqlName(token.tokenString,
+                        token.isDelimitedIdentifier, type);
+
+                if (token.namePrefix == null) {
+                    name.schema = session.getCurrentSchemaHsqlName();
+                } else {
+                    name.schema = database.nameManager.newHsqlName(
+                        token.namePrefix, token.isDelimitedPrefix,
+                        SchemaObject.SCHEMA);
+                }
+
+                read();
+
+                break;
+            }
+            case Tokens.COLUMN : {
+                read();
+                checkIsSchemaObjectName();
+
+                name = database.nameManager.newHsqlName(token.tokenString,
+                        token.isDelimitedIdentifier, SchemaObject.COLUMN);
+
+                if (token.namePrefix == null) {
+                    throw Error.error(ErrorCode.X_42501);
+                }
+
+                name.parent =
+                    database.nameManager.newHsqlName(token.namePrefix,
+                                                     token.isDelimitedPrefix,
+                                                     SchemaObject.TABLE);
+
+                if (token.namePrePrefix == null) {
+                    name.parent.schema = session.getCurrentSchemaHsqlName();
+                } else {
+                    name.parent.schema = database.nameManager.newHsqlName(
+                        token.namePrePrefix, token.isDelimitedPrePrefix,
+                        SchemaObject.TABLE);
+                }
+
+                read();
+
+                break;
+            }
+            default :
+                throw unexpectedToken();
+        }
+
+        readThis(Tokens.IS);
+
+        String   comment   = readQuotedString();
+        Object[] arguments = new Object[] {
+            name, comment
+        };
+
+        return new StatementSchema(null, StatementTypes.COMMENT, arguments);
+    }
+}
diff --git a/src/org/hsqldb/ParserDML.java b/src/org/hsqldb/ParserDML.java
new file mode 100644
index 0000000..2027169
--- /dev/null
+++ b/src/org/hsqldb/ParserDML.java
@@ -0,0 +1,1196 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.LongDeque;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.types.Type;
+
+/**
+ * Parser for DML statements
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ParserDML extends ParserDQL {
+
+    ParserDML(Session session, Scanner t) {
+        super(session, t);
+    }
+
+    /**
+     * Retrieves an INSERT Statement from this parse context.
+     */
+    StatementDMQL compileInsertStatement(RangeVariable[] outerRanges) {
+
+        read();
+        readThis(Tokens.INTO);
+
+        boolean[] columnCheckList;
+        int[]     columnMap;
+        int       colCount;
+        Table     table             = readTableName();
+        boolean   overridingUser    = false;
+        boolean   overridingSystem  = false;
+        boolean   assignsToIdentity = false;
+
+        columnCheckList = null;
+        columnMap       = table.getColumnMap();
+        colCount        = table.getColumnCount();
+
+        int position = getPosition();
+
+        if (!table.isInsertable() && !table.isTriggerInsertable()
+                && !session.isProcessingScript) {
+            throw Error.error(ErrorCode.X_42545);
+        }
+
+        Table baseTable = table.isTriggerInsertable() ? table
+                                                      : table.getBaseTable();
+
+        switch (token.tokenType) {
+
+            case Tokens.DEFAULT : {
+                read();
+                readThis(Tokens.VALUES);
+
+                Expression insertExpression = new Expression(OpTypes.ROW,
+                    new Expression[]{});
+
+                insertExpression = new Expression(OpTypes.TABLE,
+                                                  new Expression[]{
+                                                      insertExpression });
+                columnCheckList = table.getNewColumnCheckList();
+
+                for (int i = 0; i < table.colDefaults.length; i++) {
+                    if (table.colDefaults[i] == null
+                            && table.identityColumn != i) {
+                        if (!table.getColumn(i).isGenerated()) {
+                            throw Error.error(ErrorCode.X_42544);
+                        }
+                    }
+                }
+
+                StatementDMQL cs = new StatementInsert(session, table,
+                                                       columnMap,
+                                                       insertExpression,
+                                                       columnCheckList,
+                                                       compileContext);
+
+                return cs;
+            }
+            case Tokens.OPENBRACKET : {
+                int brackets = readOpenBrackets();
+
+                if (brackets == 1) {
+                    boolean isQuery = false;
+
+                    switch (token.tokenType) {
+
+                        case Tokens.WITH :
+                        case Tokens.SELECT :
+                        case Tokens.TABLE : {
+                            rewind(position);
+
+                            isQuery = true;
+
+                            break;
+                        }
+                        default :
+                    }
+
+                    if (isQuery) {
+                        break;
+                    }
+
+                    OrderedHashSet columnNames = new OrderedHashSet();
+
+                    readSimpleColumnNames(columnNames, table);
+                    readThis(Tokens.CLOSEBRACKET);
+
+                    colCount  = columnNames.size();
+                    columnMap = table.getColumnIndexes(columnNames);
+
+                    if (token.tokenType != Tokens.VALUES
+                            && token.tokenType != Tokens.OVERRIDING) {
+                        break;
+                    }
+
+                    // fall through
+                } else {
+                    rewind(position);
+
+                    break;
+                }
+            }
+
+            // fall through
+            case Tokens.OVERRIDING : {
+                if (token.tokenType == Tokens.OVERRIDING) {
+                    read();
+
+                    if (token.tokenType == Tokens.USER) {
+                        read();
+
+                        overridingUser = true;
+                    } else if (token.tokenType == Tokens.SYSTEM) {
+                        read();
+
+                        overridingSystem = true;
+                    } else {
+                        unexpectedToken();
+                    }
+
+                    readThis(Tokens.VALUE);
+
+                    if (token.tokenType != Tokens.VALUES) {
+                        break;
+                    }
+                }
+            }
+
+            // fall through
+            case Tokens.VALUES : {
+                read();
+
+                columnCheckList = table.getColumnCheckList(columnMap);
+
+                Expression insertExpressions =
+                    XreadContextuallyTypedTable(colCount);
+                HsqlList unresolved =
+                    insertExpressions.resolveColumnReferences(outerRanges,
+                        null);
+
+                ExpressionColumn.checkColumnsResolved(unresolved);
+                insertExpressions.resolveTypes(session, null);
+                setParameterTypes(insertExpressions, table, columnMap);
+
+                if (table != baseTable) {
+                    int[] baseColumnMap = table.getBaseTableColumnMap();
+                    int[] newColumnMap  = new int[columnMap.length];
+
+                    ArrayUtil.projectRow(baseColumnMap, columnMap,
+                                         newColumnMap);
+
+                    columnMap = newColumnMap;
+                }
+
+                Expression[] rowList = insertExpressions.nodes;
+
+                for (int j = 0; j < rowList.length; j++) {
+                    Expression[] rowArgs = rowList[j].nodes;
+
+                    for (int i = 0; i < rowArgs.length; i++) {
+                        Expression e = rowArgs[i];
+                        ColumnSchema column =
+                            baseTable.getColumn(columnMap[i]);
+
+                        if (column.isIdentity()) {
+                            assignsToIdentity = true;
+
+                            if (e.getType() != OpTypes.DEFAULT) {
+                                if (table.identitySequence.isAlways()) {
+                                    if (!overridingUser && !overridingSystem) {
+                                        throw Error.error(ErrorCode.X_42543);
+                                    }
+                                }
+
+                                if (overridingUser) {
+                                    rowArgs[i] =
+                                        new ExpressionColumn(OpTypes.DEFAULT);
+                                }
+                            }
+                        } else if (column.hasDefault()) {}
+                        else if (column.isGenerated()) {
+                            if (e.getType() != OpTypes.DEFAULT) {
+                                throw Error.error(ErrorCode.X_42541);
+                            }
+                        } else {
+                            if (e.getType() == OpTypes.DEFAULT) {
+                                throw Error.error(ErrorCode.X_42544);
+                            }
+                        }
+
+                        if (e.isUnresolvedParam()) {
+                            e.setAttributesAsColumn(column, true);
+                        }
+                    }
+                }
+
+                if (!assignsToIdentity
+                        && (overridingUser || overridingSystem)) {
+                    unexpectedTokenRequire(Tokens.T_OVERRIDING);
+                }
+
+                StatementDMQL cs = new StatementInsert(session, table,
+                                                       columnMap,
+                                                       insertExpressions,
+                                                       columnCheckList,
+                                                       compileContext);
+
+                return cs;
+            }
+            case Tokens.WITH :
+            case Tokens.SELECT :
+            case Tokens.TABLE : {
+                break;
+            }
+            default : {
+                throw unexpectedToken();
+            }
+        }
+
+        columnCheckList = table.getColumnCheckList(columnMap);
+
+        if (baseTable != null && table != baseTable) {
+            int[] baseColumnMap = table.getBaseTableColumnMap();
+            int[] newColumnMap  = new int[columnMap.length];
+
+            ArrayUtil.projectRow(baseColumnMap, columnMap, newColumnMap);
+
+            columnMap = newColumnMap;
+        }
+
+        int enforcedDefaultIndex = table.getIdentityColumnIndex();
+        int overrideIndex        = -1;
+
+        if (enforcedDefaultIndex != -1
+                && ArrayUtil.find(columnMap, enforcedDefaultIndex) > -1) {
+            if (table.identitySequence.isAlways()) {
+                if (!overridingUser && !overridingSystem) {
+                    throw Error.error(ErrorCode.X_42543);
+                }
+            }
+
+            if (overridingUser) {
+                overrideIndex = enforcedDefaultIndex;
+            }
+        } else if (overridingUser || overridingSystem) {
+            unexpectedTokenRequire(Tokens.T_OVERRIDING);
+        }
+
+        Type[] types = new Type[columnMap.length];
+
+        ArrayUtil.projectRow(baseTable.getColumnTypes(), columnMap, types);
+
+        QueryExpression queryExpression = XreadQueryExpression();
+
+        queryExpression.setReturningResult();
+        queryExpression.resolve(session, outerRanges, types);
+
+        if (colCount != queryExpression.getColumnCount()) {
+            throw Error.error(ErrorCode.X_42546);
+        }
+
+        StatementDMQL cs = new StatementInsert(session, table, columnMap,
+                                               columnCheckList,
+                                               queryExpression,
+                                               compileContext, overrideIndex);
+
+        return cs;
+    }
+
+    private static void setParameterTypes(Expression tableExpression,
+                                          Table table, int[] columnMap) {
+
+        for (int i = 0; i < tableExpression.nodes.length; i++) {
+            Expression[] list = tableExpression.nodes[i].nodes;
+
+            for (int j = 0; j < list.length; j++) {
+                if (list[j].isUnresolvedParam()) {
+                    list[j].setAttributesAsColumn(
+                        table.getColumn(columnMap[j]), true);
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a DELETE-type Statement from this parse context.
+     */
+    StatementDMQL compileDeleteStatement(RangeVariable[] outerRanges) {
+
+        Expression condition       = null;
+        boolean    truncate        = false;
+        boolean    restartIdentity = false;
+        int        statementType;
+
+        switch (token.tokenType) {
+
+            case Tokens.TRUNCATE : {
+                read();
+                readThis(Tokens.TABLE);
+
+                truncate      = true;
+                statementType = StatementTypes.TRUNCATE;
+
+                break;
+            }
+            case Tokens.DELETE : {
+                read();
+                readThis(Tokens.FROM);
+
+                statementType = StatementTypes.DELETE_WHERE;
+
+                break;
+            }
+            default :
+                throw unexpectedToken();
+        }
+
+        RangeVariable[] rangeVariables = {
+            readSimpleRangeVariable(statementType) };
+        Table table     = rangeVariables[0].getTable();
+        Table baseTable = table.getBaseTable();
+
+        if (truncate) {
+            if (table != baseTable) {
+                throw Error.error(ErrorCode.X_42545);
+            }
+
+            if (table.isTriggerDeletable()) {
+
+                // redundant
+                throw Error.error(ErrorCode.X_42545);
+            }
+
+            switch (token.tokenType) {
+
+                case Tokens.CONTINUE : {
+                    read();
+                    readThis(Tokens.IDENTITY);
+
+                    break;
+                }
+                case Tokens.RESTART : {
+                    read();
+                    readThis(Tokens.IDENTITY);
+
+                    restartIdentity = true;
+
+                    break;
+                }
+            }
+
+            if (table.fkMainConstraints.length > 0) {
+                throw Error.error(ErrorCode.X_23504);
+            }
+        }
+
+        if (!truncate && token.tokenType == Tokens.WHERE) {
+            read();
+
+            condition = XreadBooleanValueExpression();
+
+            HsqlList unresolved =
+                condition.resolveColumnReferences(outerRanges, null);
+
+            unresolved = Expression.resolveColumnSet(rangeVariables,
+                    rangeVariables.length, unresolved, null);
+
+            ExpressionColumn.checkColumnsResolved(unresolved);
+            condition.resolveTypes(session, null);
+
+            if (condition.isUnresolvedParam()) {
+                condition.dataType = Type.SQL_BOOLEAN;
+            }
+
+            if (condition.getDataType() != Type.SQL_BOOLEAN) {
+                throw Error.error(ErrorCode.X_42568);
+            }
+        }
+
+        if (baseTable == null) {
+
+            //
+        } else if (table != baseTable) {
+            QuerySpecification baseSelect =
+                ((TableDerived) table).getQueryExpression().getMainSelect();
+            RangeVariable[] newRangeVariables =
+                (RangeVariable[]) ArrayUtil.duplicateArray(
+                    baseSelect.rangeVariables);
+
+            newRangeVariables[0] = baseSelect.rangeVariables[0].duplicate();
+
+            Expression[] newBaseExprColumns =
+                new Expression[baseSelect.indexLimitData];
+
+            for (int i = 0; i < baseSelect.indexLimitData; i++) {
+                Expression e = baseSelect.exprColumns[i].duplicate();
+
+                newBaseExprColumns[i] = e;
+
+                e.replaceRangeVariables(baseSelect.rangeVariables,
+                                        newRangeVariables);
+            }
+
+            Expression baseQueryCondition = baseSelect.queryCondition;
+
+            if (baseQueryCondition != null) {
+                baseQueryCondition = baseQueryCondition.duplicate();
+
+                baseQueryCondition.replaceRangeVariables(rangeVariables,
+                        newRangeVariables);
+            }
+
+            if (condition != null) {
+                condition =
+                    condition.replaceColumnReferences(rangeVariables[0],
+                                                      newBaseExprColumns);
+            }
+
+            rangeVariables = newRangeVariables;
+            condition = ExpressionLogical.andExpressions(baseQueryCondition,
+                    condition);
+        }
+
+        if (condition != null) {
+            rangeVariables[0].addJoinCondition(condition);
+
+            RangeVariableResolver resolver =
+                new RangeVariableResolver(rangeVariables, null,
+                                          compileContext);
+
+            resolver.processConditions(session);
+
+            rangeVariables = resolver.rangeVariables;
+        }
+
+        StatementDMQL cs = new StatementDML(session, table, rangeVariables,
+                                            compileContext, restartIdentity,
+                                            statementType);
+
+        return cs;
+    }
+
+    /**
+     * Creates an UPDATE-type Statement from this parse context.
+     */
+    StatementDMQL compileUpdateStatement(RangeVariable[] outerRanges) {
+
+        read();
+
+        Expression[]   updateExpressions;
+        int[]          columnMap;
+        boolean[]      columnCheckList;
+        OrderedHashSet targetSet    = new OrderedHashSet();
+        LongDeque      colIndexList = new LongDeque();
+        HsqlArrayList  exprList     = new HsqlArrayList();
+        RangeVariable[] rangeVariables = {
+            readSimpleRangeVariable(StatementTypes.UPDATE_WHERE) };
+        Table table     = rangeVariables[0].rangeTable;
+        Table baseTable = table.getBaseTable();
+
+        readThis(Tokens.SET);
+        readSetClauseList(rangeVariables, targetSet, colIndexList, exprList);
+
+        columnMap = new int[colIndexList.size()];
+
+        colIndexList.toArray(columnMap);
+
+        Expression[] targets = new Expression[targetSet.size()];
+
+        targetSet.toArray(targets);
+
+        for (int i = 0; i < targets.length; i++) {
+            this.resolveOuterReferencesAndTypes(outerRanges, targets[i]);
+        }
+
+        columnCheckList   = table.getColumnCheckList(columnMap);
+        updateExpressions = new Expression[exprList.size()];
+
+        exprList.toArray(updateExpressions);
+
+        Expression condition = null;
+
+        if (token.tokenType == Tokens.WHERE) {
+            read();
+
+            condition = XreadBooleanValueExpression();
+
+            HsqlList unresolved =
+                condition.resolveColumnReferences(outerRanges, null);
+
+            unresolved = Expression.resolveColumnSet(rangeVariables,
+                    rangeVariables.length, unresolved, null);
+
+            ExpressionColumn.checkColumnsResolved(unresolved);
+            condition.resolveTypes(session, null);
+
+            if (condition.isUnresolvedParam()) {
+                condition.dataType = Type.SQL_BOOLEAN;
+            }
+
+            if (condition.getDataType() != Type.SQL_BOOLEAN) {
+                throw Error.error(ErrorCode.X_42568);
+            }
+        }
+
+        resolveUpdateExpressions(table, rangeVariables, columnMap,
+                                 updateExpressions, outerRanges);
+
+        if (table != baseTable) {
+            QuerySpecification baseSelect =
+                ((TableDerived) table).getQueryExpression().getMainSelect();
+            RangeVariable[] newRangeVariables =
+                (RangeVariable[]) ArrayUtil.duplicateArray(
+                    baseSelect.rangeVariables);
+
+            newRangeVariables[0] = baseSelect.rangeVariables[0].duplicate();
+
+            Expression[] newBaseExprColumns =
+                new Expression[baseSelect.indexLimitData];
+
+            for (int i = 0; i < baseSelect.indexLimitData; i++) {
+                Expression e = baseSelect.exprColumns[i].duplicate();
+
+                newBaseExprColumns[i] = e;
+
+                e.replaceRangeVariables(baseSelect.rangeVariables,
+                                        newRangeVariables);
+            }
+
+            Expression baseQueryCondition = baseSelect.queryCondition;
+
+            if (baseQueryCondition != null) {
+                baseQueryCondition = baseQueryCondition.duplicate();
+
+                baseQueryCondition.replaceRangeVariables(rangeVariables,
+                        newRangeVariables);
+            }
+
+            if (condition != null) {
+                condition =
+                    condition.replaceColumnReferences(rangeVariables[0],
+                                                      newBaseExprColumns);
+            }
+
+            for (int i = 0; i < updateExpressions.length; i++) {
+                updateExpressions[i] =
+                    updateExpressions[i].replaceColumnReferences(
+                        rangeVariables[0], newBaseExprColumns);
+            }
+
+            rangeVariables = newRangeVariables;
+            condition = ExpressionLogical.andExpressions(baseQueryCondition,
+                    condition);
+        }
+
+        if (condition != null) {
+            rangeVariables[0].addJoinCondition(condition);
+
+            RangeVariableResolver resolver =
+                new RangeVariableResolver(rangeVariables, null,
+                                          compileContext);
+
+            resolver.processConditions(session);
+
+            rangeVariables = resolver.rangeVariables;
+        }
+
+        if (baseTable != null && table != baseTable) {
+            int[] baseColumnMap = table.getBaseTableColumnMap();
+            int[] newColumnMap  = new int[columnMap.length];
+
+            ArrayUtil.projectRow(baseColumnMap, columnMap, newColumnMap);
+
+            columnMap = newColumnMap;
+
+            for (int i = 0; i < columnMap.length; i++) {
+                if (baseTable.colGenerated[columnMap[i]]) {
+                    throw Error.error(ErrorCode.X_42513);
+                }
+            }
+        }
+
+        StatementDMQL cs = new StatementDML(session, targets, table,
+                                            rangeVariables, columnMap,
+                                            updateExpressions,
+                                            columnCheckList, compileContext);
+
+        return cs;
+    }
+
+    void resolveUpdateExpressions(Table targetTable,
+                                  RangeVariable[] rangeVariables,
+                                  int[] columnMap,
+                                  Expression[] colExpressions,
+                                  RangeVariable[] outerRanges) {
+
+        HsqlList unresolved           = null;
+        int      enforcedDefaultIndex = -1;
+
+        if (targetTable.hasIdentityColumn()
+                && targetTable.identitySequence.isAlways()) {
+            enforcedDefaultIndex = targetTable.getIdentityColumnIndex();
+        }
+
+        for (int i = 0, ix = 0; i < columnMap.length; ix++) {
+            Expression expr = colExpressions[ix];
+            Expression e;
+
+            // no generated column can be updated
+            if (targetTable.colGenerated[columnMap[i]]) {
+                throw Error.error(ErrorCode.X_42513);
+            }
+
+            if (expr.getType() == OpTypes.ROW) {
+                Expression[] elements = expr.nodes;
+
+                for (int j = 0; j < elements.length; j++, i++) {
+                    e = elements[j];
+
+                    if (enforcedDefaultIndex == columnMap[i]) {
+                        if (e.getType() != OpTypes.DEFAULT) {
+                            throw Error.error(ErrorCode.X_42541);
+                        }
+                    }
+
+                    if (e.isUnresolvedParam()) {
+                        e.setAttributesAsColumn(
+                            targetTable.getColumn(columnMap[i]), true);
+                    } else if (e.getType() == OpTypes.DEFAULT) {
+                        if (targetTable.colDefaults[columnMap[i]] == null
+                                && targetTable.identityColumn
+                                   != columnMap[i]) {
+                            throw Error.error(ErrorCode.X_42544);
+                        }
+                    } else {
+                        unresolved = expr.resolveColumnReferences(outerRanges,
+                                null);
+                        unresolved =
+                            Expression.resolveColumnSet(rangeVariables,
+                                                        rangeVariables.length,
+                                                        unresolved, null);
+
+                        ExpressionColumn.checkColumnsResolved(unresolved);
+
+                        unresolved = null;
+
+                        e.resolveTypes(session, null);
+                    }
+                }
+            } else if (expr.getType() == OpTypes.ROW_SUBQUERY) {
+                unresolved = expr.resolveColumnReferences(outerRanges, null);
+                unresolved = Expression.resolveColumnSet(rangeVariables,
+                        rangeVariables.length, unresolved, null);
+
+                ExpressionColumn.checkColumnsResolved(unresolved);
+                expr.resolveTypes(session, null);
+
+                int count = expr.subQuery.queryExpression.getColumnCount();
+
+                for (int j = 0; j < count; j++, i++) {
+                    if (enforcedDefaultIndex == columnMap[i]) {
+                        throw Error.error(ErrorCode.X_42541);
+                    }
+                }
+            } else {
+                e = expr;
+
+                if (enforcedDefaultIndex == columnMap[i]) {
+                    if (e.getType() != OpTypes.DEFAULT) {
+                        throw Error.error(ErrorCode.X_42541);
+                    }
+                }
+
+                if (e.isUnresolvedParam()) {
+                    e.setAttributesAsColumn(
+                        targetTable.getColumn(columnMap[i]), true);
+                } else if (e.getType() == OpTypes.DEFAULT) {
+                    if (targetTable.colDefaults[columnMap[i]] == null
+                            && targetTable.identityColumn != columnMap[i]) {
+                        throw Error.error(ErrorCode.X_42544);
+                    }
+                } else {
+                    unresolved = expr.resolveColumnReferences(outerRanges,
+                            null);
+                    unresolved = Expression.resolveColumnSet(rangeVariables,
+                            rangeVariables.length, unresolved, null);
+
+                    ExpressionColumn.checkColumnsResolved(unresolved);
+                    e.resolveTypes(session, null);
+                }
+
+                i++;
+            }
+        }
+    }
+
+    void readSetClauseList(RangeVariable[] rangeVars, OrderedHashSet targets,
+                           LongDeque colIndexList, HsqlArrayList expressions) {
+
+        while (true) {
+            int degree;
+
+            if (token.tokenType == Tokens.OPENBRACKET) {
+                read();
+
+                int oldCount = targets.size();
+
+                readTargetSpecificationList(targets, rangeVars, colIndexList);
+
+                degree = targets.size() - oldCount;
+
+                readThis(Tokens.CLOSEBRACKET);
+            } else {
+                Expression target = XreadTargetSpecification(rangeVars,
+                    colIndexList);
+
+                if (!targets.add(target)) {
+                    ColumnSchema col = target.getColumn();
+
+                    throw Error.error(ErrorCode.X_42579, col.getName().name);
+                }
+
+                degree = 1;
+            }
+
+            readThis(Tokens.EQUALS);
+
+            int position = getPosition();
+            int brackets = readOpenBrackets();
+
+            if (token.tokenType == Tokens.SELECT) {
+                rewind(position);
+
+                SubQuery sq = XreadSubqueryBody(false, OpTypes.ROW_SUBQUERY);
+
+                if (degree != sq.queryExpression.getColumnCount()) {
+                    throw Error.error(ErrorCode.X_42546);
+                }
+
+                Expression e = new Expression(OpTypes.ROW_SUBQUERY, sq);
+
+                expressions.add(e);
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+
+                    continue;
+                }
+
+                break;
+            }
+
+            if (brackets > 0) {
+                rewind(position);
+            }
+
+            if (degree > 1) {
+                readThis(Tokens.OPENBRACKET);
+
+                Expression e = readRow();
+
+                readThis(Tokens.CLOSEBRACKET);
+
+                int rowDegree = e.getType() == OpTypes.ROW ? e.nodes.length
+                                                           : 1;
+
+                if (degree != rowDegree) {
+                    throw Error.error(ErrorCode.X_42546);
+                }
+
+                expressions.add(e);
+            } else {
+                Expression e = XreadValueExpressionWithContext();
+
+                expressions.add(e);
+            }
+
+            if (token.tokenType == Tokens.COMMA) {
+                read();
+
+                continue;
+            }
+
+            break;
+        }
+    }
+
+    /**
+     * Retrieves a MERGE Statement from this parse context.
+     */
+    StatementDMQL compileMergeStatement(RangeVariable[] outerRanges) {
+
+        boolean[]     insertColumnCheckList;
+        int[]         insertColumnMap = null;
+        int[]         updateColumnMap = null;
+        int[]         baseUpdateColumnMap;
+        Table         table;
+        RangeVariable targetRange;
+        RangeVariable sourceRange;
+        Expression    mergeCondition;
+        Expression[]  targets           = null;
+        HsqlArrayList updateList        = new HsqlArrayList();
+        Expression[]  updateExpressions = Expression.emptyArray;
+        HsqlArrayList insertList        = new HsqlArrayList();
+        Expression    insertExpression  = null;
+
+        read();
+        readThis(Tokens.INTO);
+
+        targetRange = readSimpleRangeVariable(StatementTypes.MERGE);
+        table       = targetRange.rangeTable;
+
+        readThis(Tokens.USING);
+
+        sourceRange = readTableOrSubquery();
+
+        // parse ON search conditions
+        readThis(Tokens.ON);
+
+        mergeCondition = XreadBooleanValueExpression();
+
+        if (mergeCondition.getDataType() != Type.SQL_BOOLEAN) {
+            throw Error.error(ErrorCode.X_42568);
+        }
+
+        RangeVariable[] fullRangeVars   = new RangeVariable[] {
+            sourceRange, targetRange
+        };
+        RangeVariable[] sourceRangeVars = new RangeVariable[]{ sourceRange };
+        RangeVariable[] targetRangeVars = new RangeVariable[]{ targetRange };
+
+        // parse WHEN clause(s) and convert lists to arrays
+        insertColumnMap       = table.getColumnMap();
+        insertColumnCheckList = table.getNewColumnCheckList();
+
+        OrderedHashSet updateTargetSet    = new OrderedHashSet();
+        OrderedHashSet insertColNames     = new OrderedHashSet();
+        LongDeque      updateColIndexList = new LongDeque();
+
+        readMergeWhen(updateColIndexList, insertColNames, updateTargetSet,
+                      insertList, updateList, targetRangeVars, sourceRange);
+
+        if (insertList.size() > 0) {
+            int colCount = insertColNames.size();
+
+            if (colCount != 0) {
+                insertColumnMap = table.getColumnIndexes(insertColNames);
+                insertColumnCheckList =
+                    table.getColumnCheckList(insertColumnMap);
+            }
+
+            insertExpression = (Expression) insertList.get(0);
+
+            setParameterTypes(insertExpression, table, insertColumnMap);
+        }
+
+        if (updateList.size() > 0) {
+            targets = new Expression[updateTargetSet.size()];
+
+            updateTargetSet.toArray(targets);
+
+            for (int i = 0; i < targets.length; i++) {
+                this.resolveOuterReferencesAndTypes(outerRanges, targets[i]);
+            }
+
+            updateExpressions = new Expression[updateList.size()];
+
+            updateList.toArray(updateExpressions);
+
+            updateColumnMap = new int[updateColIndexList.size()];
+
+            updateColIndexList.toArray(updateColumnMap);
+        }
+
+        if (updateExpressions.length != 0) {
+            Table baseTable = table.getBaseTable();
+
+            baseUpdateColumnMap = updateColumnMap;
+
+            if (table != baseTable) {
+                baseUpdateColumnMap = new int[updateColumnMap.length];
+
+                ArrayUtil.projectRow(table.getBaseTableColumnMap(),
+                                     updateColumnMap, baseUpdateColumnMap);
+            }
+
+            resolveUpdateExpressions(table, sourceRangeVars, updateColumnMap,
+                                     updateExpressions, outerRanges);
+        }
+
+        HsqlList unresolved = null;
+
+        unresolved = mergeCondition.resolveColumnReferences(fullRangeVars,
+                null);
+
+        ExpressionColumn.checkColumnsResolved(unresolved);
+        mergeCondition.resolveTypes(session, null);
+
+        if (mergeCondition.isUnresolvedParam()) {
+            mergeCondition.dataType = Type.SQL_BOOLEAN;
+        }
+
+        if (mergeCondition.getDataType() != Type.SQL_BOOLEAN) {
+            throw Error.error(ErrorCode.X_42568);
+        }
+
+        RangeVariableResolver resolver =
+            new RangeVariableResolver(fullRangeVars, mergeCondition,
+                                      compileContext);
+
+        resolver.processConditions(session);
+
+        fullRangeVars = resolver.rangeVariables;
+
+        if (insertExpression != null) {
+            unresolved =
+                insertExpression.resolveColumnReferences(sourceRangeVars,
+                    unresolved);
+
+            ExpressionColumn.checkColumnsResolved(unresolved);
+            insertExpression.resolveTypes(session, null);
+        }
+
+        StatementDMQL cs = new StatementDML(session, targets, fullRangeVars,
+                                            insertColumnMap, updateColumnMap,
+                                            insertColumnCheckList,
+                                            mergeCondition, insertExpression,
+                                            updateExpressions, compileContext);
+
+        return cs;
+    }
+
+    /**
+     * Parses a WHEN clause from a MERGE statement. This can be either a
+     * WHEN MATCHED or WHEN NOT MATCHED clause, or both, and the appropriate
+     * values will be updated.
+     *
+     * If the var that is to hold the data is not null, then we already
+     * encountered this type of clause, which is only allowed once, and at least
+     * one is required.
+     */
+    private void readMergeWhen(LongDeque updateColIndexList,
+                               OrderedHashSet insertColumnNames,
+                               OrderedHashSet updateTargetSet,
+                               HsqlArrayList insertExpressions,
+                               HsqlArrayList updateExpressions,
+                               RangeVariable[] targetRangeVars,
+                               RangeVariable sourceRangeVar) {
+
+        Table table       = targetRangeVars[0].rangeTable;
+        int   columnCount = table.getColumnCount();
+
+        readThis(Tokens.WHEN);
+
+        if (token.tokenType == Tokens.MATCHED) {
+            if (updateExpressions.size() != 0) {
+                throw Error.error(ErrorCode.X_42547);
+            }
+
+            read();
+            readThis(Tokens.THEN);
+            readThis(Tokens.UPDATE);
+            readThis(Tokens.SET);
+            readSetClauseList(targetRangeVars, updateTargetSet,
+                              updateColIndexList, updateExpressions);
+        } else if (token.tokenType == Tokens.NOT) {
+            if (insertExpressions.size() != 0) {
+                throw Error.error(ErrorCode.X_42548);
+            }
+
+            read();
+            readThis(Tokens.MATCHED);
+            readThis(Tokens.THEN);
+            readThis(Tokens.INSERT);
+
+            // parse INSERT statement
+            // optional column list
+            int brackets = readOpenBrackets();
+
+            if (brackets == 1) {
+                readSimpleColumnNames(insertColumnNames, targetRangeVars[0]);
+
+                columnCount = insertColumnNames.size();
+
+                readThis(Tokens.CLOSEBRACKET);
+
+                brackets = 0;
+            }
+
+            readThis(Tokens.VALUES);
+
+            Expression e = XreadContextuallyTypedTable(columnCount);
+
+            if (e.nodes.length != 1) {
+                throw Error.error(ErrorCode.X_21000);
+            }
+
+            insertExpressions.add(e);
+        } else {
+            throw unexpectedToken();
+        }
+
+        if (token.tokenType == Tokens.WHEN) {
+            readMergeWhen(updateColIndexList, insertColumnNames,
+                          updateTargetSet, insertExpressions,
+                          updateExpressions, targetRangeVars, sourceRangeVar);
+        }
+    }
+
+    /**
+     * Retrieves a CALL Statement from this parse context.
+     */
+
+    // to do call argument name and type resolution
+    StatementDMQL compileCallStatement(RangeVariable[] outerRanges,
+                                       boolean isStrictlyProcedure) {
+
+        read();
+
+        if (isIdentifier()) {
+            checkValidCatalogName(token.namePrePrefix);
+
+            RoutineSchema routineSchema =
+                (RoutineSchema) database.schemaManager.findSchemaObject(
+                    token.tokenString,
+                    session.getSchemaName(token.namePrefix),
+                    SchemaObject.PROCEDURE);
+
+            if (routineSchema != null) {
+                read();
+
+                HsqlArrayList list = new HsqlArrayList();
+
+                readThis(Tokens.OPENBRACKET);
+
+                if (token.tokenType == Tokens.CLOSEBRACKET) {
+                    read();
+                } else {
+                    while (true) {
+                        Expression e = XreadValueExpression();
+
+                        list.add(e);
+
+                        if (token.tokenType == Tokens.COMMA) {
+                            read();
+                        } else {
+                            readThis(Tokens.CLOSEBRACKET);
+
+                            break;
+                        }
+                    }
+                }
+
+                Expression[] arguments = new Expression[list.size()];
+
+                list.toArray(arguments);
+
+                Routine routine =
+                    routineSchema.getSpecificRoutine(arguments.length);
+
+                compileContext.addProcedureCall(routine);
+
+                HsqlList unresolved = null;
+
+                for (int i = 0; i < arguments.length; i++) {
+                    Expression e = arguments[i];
+
+                    if (e.isUnresolvedParam()) {
+                        e.setAttributesAsColumn(
+                            routine.getParameter(i),
+                            routine.getParameter(i).isWriteable());
+                    } else {
+                        int paramMode =
+                            routine.getParameter(i).getParameterMode();
+
+                        unresolved =
+                            arguments[i].resolveColumnReferences(outerRanges,
+                                unresolved);
+
+                        if (paramMode
+                                != SchemaObject.ParameterModes.PARAM_IN) {
+                            if (e.getType() != OpTypes.VARIABLE) {
+                                throw Error.error(ErrorCode.X_42603);
+                            }
+                        }
+                    }
+                }
+
+                ExpressionColumn.checkColumnsResolved(unresolved);
+
+                for (int i = 0; i < arguments.length; i++) {
+                    arguments[i].resolveTypes(session, null);
+
+                    if (!routine.getParameter(
+                            i).getDataType().canBeAssignedFrom(
+                            arguments[i].getDataType())) {
+                        throw Error.error(ErrorCode.X_42561);
+                    }
+                }
+
+                StatementDMQL cs = new StatementProcedure(session, routine,
+                    arguments, compileContext);
+
+                return cs;
+            }
+        }
+
+        if (isStrictlyProcedure) {
+            throw Error.error(ErrorCode.X_42501, token.tokenString);
+        }
+
+        Expression expression = this.XreadValueExpression();
+        HsqlList unresolved = expression.resolveColumnReferences(outerRanges,
+            null);
+
+        ExpressionColumn.checkColumnsResolved(unresolved);
+        expression.resolveTypes(session, null);
+
+//        expression.paramMode = PARAM_OUT;
+        StatementDMQL cs = new StatementProcedure(session, expression,
+            compileContext);
+
+        return cs;
+    }
+
+    void resolveOuterReferencesAndTypes(RangeVariable[] rangeVars,
+                                        Expression e) {
+
+        HsqlList unresolved = e.resolveColumnReferences(rangeVars,
+            rangeVars.length, null, false);
+
+        unresolved = Expression.resolveColumnSet(rangeVars, rangeVars.length,
+                unresolved, null);
+
+        ExpressionColumn.checkColumnsResolved(unresolved);
+        e.resolveTypes(session, null);
+    }
+}
diff --git a/src/org/hsqldb/ParserDQL.java b/src/org/hsqldb/ParserDQL.java
new file mode 100644
index 0000000..cedc047
--- /dev/null
+++ b/src/org/hsqldb/ParserDQL.java
@@ -0,0 +1,5493 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.HsqlNameManager.SimpleName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.LongDeque;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntKeyHashMap;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.store.BitMap;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.ArrayType;
+import org.hsqldb.types.BlobType;
+import org.hsqldb.types.Charset;
+import org.hsqldb.types.DTIType;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Parser for DQL statements
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+public class ParserDQL extends ParserBase {
+
+    protected Database             database;
+    protected Session              session;
+    protected final CompileContext compileContext;
+    HsqlException                  lastError;
+
+    /**
+     *  Constructs a new Parser object with the given context.
+     *
+     * @param  session the connected context
+     * @param  t the token source from which to parse commands
+     */
+    ParserDQL(Session session, Scanner t) {
+
+        super(t);
+
+        this.session   = session;
+        database       = session.getDatabase();
+        compileContext = new CompileContext(session, this);
+    }
+
+    /**
+     *  Resets this parse context with the given SQL character sequence.
+     *
+     * @param sql a new SQL character sequence to replace the current one
+     */
+    void reset(String sql) {
+
+        super.reset(sql);
+        compileContext.reset();
+
+        lastError = null;
+    }
+
+    void checkIsSchemaObjectName() {
+
+        if (database.sqlEnforceNames) {
+            checkIsNonReservedIdentifier();
+        } else {
+            checkIsNonCoreReservedIdentifier();
+        }
+    }
+
+    Type readTypeDefinition(boolean includeUserTypes) {
+
+        int     typeNumber = Integer.MIN_VALUE;
+        boolean hasLength  = false;
+        boolean hasScale   = false;
+
+        checkIsIdentifier();
+
+        if (token.namePrefix == null) {
+            typeNumber = Type.getTypeNr(token.tokenString);
+        }
+
+        if (typeNumber == Integer.MIN_VALUE) {
+            if (includeUserTypes) {
+                checkIsSchemaObjectName();
+
+                String schemaName = session.getSchemaName(token.namePrefix);
+                Type type = database.schemaManager.getDomain(token.tokenString,
+                    schemaName, false);
+
+                if (type != null) {
+                    getRecordedToken().setExpression(type);
+                    compileContext.addSchemaObject(type);
+                    read();
+
+                    return type;
+                }
+            }
+
+            throw Error.error(ErrorCode.X_42509, token.tokenString);
+        }
+
+        read();
+
+        switch (typeNumber) {
+
+            case Types.SQL_CHAR :
+                if (token.tokenType == Tokens.VARYING) {
+                    read();
+
+                    typeNumber = Types.SQL_VARCHAR;
+                } else if (token.tokenType == Tokens.LARGE) {
+                    readThis(Tokens.OBJECT);
+                    read();
+
+                    typeNumber = Types.SQL_CLOB;
+                }
+                break;
+
+            case Types.SQL_DOUBLE :
+                if (token.tokenType == Tokens.PRECISION) {
+                    read();
+                }
+                break;
+
+            case Types.SQL_BINARY :
+                if (token.tokenType == Tokens.VARYING) {
+                    read();
+
+                    typeNumber = Types.SQL_VARBINARY;
+                } else if (token.tokenType == Tokens.LARGE) {
+                    readThis(Tokens.OBJECT);
+                    read();
+
+                    typeNumber = Types.SQL_BLOB;
+                }
+                break;
+
+            case Types.SQL_BIT :
+                if (token.tokenType == Tokens.VARYING) {
+                    read();
+
+                    typeNumber = Types.SQL_BIT_VARYING;
+                }
+                break;
+
+            case Types.SQL_INTERVAL :
+                return readIntervalType(false);
+
+            default :
+        }
+
+        long length = typeNumber == Types.SQL_TIMESTAMP
+                      ? DTIType.defaultTimestampFractionPrecision
+                      : 0;
+        int scale = 0;
+
+        if (Types.requiresPrecision(typeNumber)
+                && token.tokenType != Tokens.OPENBRACKET
+                && database.sqlEnforceSize && !session.isProcessingScript) {
+            throw Error.error(ErrorCode.X_42599,
+                              Type.getDefaultType(typeNumber).getNameString());
+        }
+
+        if (Types.acceptsPrecision(typeNumber)) {
+            if (token.tokenType == Tokens.OPENBRACKET) {
+                int multiplier = 1;
+
+                read();
+
+                switch (token.tokenType) {
+
+                    case Tokens.X_VALUE :
+                        if (token.dataType.typeCode != Types.SQL_INTEGER
+                                && token.dataType.typeCode
+                                   != Types.SQL_BIGINT) {
+                            throw unexpectedToken();
+                        }
+                        break;
+
+                    case Tokens.X_LOB_SIZE :
+                        if (typeNumber == Types.SQL_BLOB
+                                || typeNumber == Types.SQL_CLOB) {
+                            switch (token.lobMultiplierType) {
+
+                                case Tokens.K :
+                                    multiplier = 1024;
+                                    break;
+
+                                case Tokens.M :
+                                    multiplier = 1024 * 1024;
+                                    break;
+
+                                case Tokens.G :
+                                    multiplier = 1024 * 1024 * 1024;
+                                    break;
+
+                                case Tokens.P :
+                                case Tokens.T :
+                                default :
+                                    throw unexpectedToken();
+                            }
+
+                            break;
+                        } else {
+                            throw unexpectedToken(token.getFullString());
+                        }
+                    default :
+                        throw unexpectedToken();
+                }
+
+                hasLength = true;
+                length    = ((Number) token.tokenValue).longValue();
+
+                if (length < 0
+                        || (length == 0
+                            && !Types.acceptsZeroPrecision(typeNumber))) {
+                    throw Error.error(ErrorCode.X_42592);
+                }
+
+                length *= multiplier;
+
+                read();
+
+                if (typeNumber == Types.SQL_CHAR
+                        || typeNumber == Types.SQL_VARCHAR
+                        || typeNumber == Types.SQL_CLOB) {
+                    if (token.tokenType == Tokens.CHARACTERS) {
+                        read();
+                    } else if (token.tokenType == Tokens.OCTETS) {
+                        read();
+
+                        length /= 2;
+                    }
+                }
+
+                if (Types.acceptsScaleCreateParam(typeNumber)
+                        && token.tokenType == Tokens.COMMA) {
+                    read();
+
+                    scale = readInteger();
+
+                    if (scale < 0) {
+                        throw Error.error(ErrorCode.X_42592);
+                    }
+
+                    hasScale = true;
+                }
+
+                readThis(Tokens.CLOSEBRACKET);
+            } else if (typeNumber == Types.SQL_BIT) {
+                length = 1;
+            } else if (typeNumber == Types.SQL_BLOB
+                       || typeNumber == Types.SQL_CLOB) {
+                length = BlobType.defaultBlobSize;
+            } else if (database.sqlEnforceSize) {
+
+                // BIT is always BIT(1), regardless of sqlEnforceSize
+                if (typeNumber == Types.SQL_CHAR
+                        || typeNumber == Types.SQL_BINARY) {
+                    length = 1;
+                }
+            }
+
+            if (typeNumber == Types.SQL_TIMESTAMP
+                    || typeNumber == Types.SQL_TIME) {
+                if (length > DTIType.maxFractionPrecision) {
+                    throw Error.error(ErrorCode.X_42592);
+                }
+
+                scale  = (int) length;
+                length = 0;
+
+                if (token.tokenType == Tokens.WITH) {
+                    read();
+                    readThis(Tokens.TIME);
+                    readThis(Tokens.ZONE);
+
+                    if (typeNumber == Types.SQL_TIMESTAMP) {
+                        typeNumber = Types.SQL_TIMESTAMP_WITH_TIME_ZONE;
+                    } else {
+                        typeNumber = Types.SQL_TIME_WITH_TIME_ZONE;
+                    }
+                } else if (token.tokenType == Tokens.WITHOUT) {
+                    read();
+                    readThis(Tokens.TIME);
+                    readThis(Tokens.ZONE);
+                }
+            }
+        }
+
+        switch (typeNumber) {
+
+            case Types.LONGVARCHAR : {
+                typeNumber = Types.SQL_VARCHAR;
+
+                if (!hasLength) {
+                    length = 1024 * 1024;
+                }
+
+                break;
+            }
+            case Types.LONGVARBINARY : {
+                typeNumber = Types.SQL_VARBINARY;
+
+                if (!hasLength) {
+                    length = 1024 * 1024;
+                }
+
+                break;
+            }
+            case Types.SQL_CHAR :
+            case Types.SQL_BINARY :
+                break;
+
+            case Types.SQL_VARCHAR :
+            case Types.SQL_VARBINARY :
+                if (!hasLength) {
+                    length = 32 * 1024;
+                }
+                break;
+
+            case Types.SQL_DECIMAL :
+            case Types.SQL_NUMERIC :
+                if (!hasLength && !hasScale && !database.sqlEnforceSize) {
+                    length = NumberType.defaultNumericPrecision;
+                    scale  = NumberType.defaultNumericScale;
+                }
+                break;
+        }
+
+        if (session.ignoreCase && typeNumber == Types.SQL_VARCHAR) {
+            typeNumber = Types.VARCHAR_IGNORECASE;
+        }
+
+        Type typeObject = Type.getType(typeNumber, 0, length, scale);
+
+        if (typeObject.isCharacterType()) {
+            if (token.tokenType == Tokens.CHARACTER) {
+                read();
+                readThis(Tokens.SET);
+                checkIsSchemaObjectName();
+
+                String schemaName = session.getSchemaName(token.namePrefix);
+                Charset charset =
+                    (Charset) database.schemaManager.getSchemaObject(
+                        token.tokenString, schemaName, SchemaObject.CHARSET);
+
+                read();
+            }
+        }
+
+        if (token.tokenType == Tokens.ARRAY) {
+            if (typeObject.isLobType()) {
+                throw unexpectedToken();
+            }
+
+            read();
+
+            int maxCardinality = Type.defaultArrayCardinality;
+
+            if (token.tokenType == Tokens.LEFTBRACKET) {
+                read();
+
+                maxCardinality = readInteger();
+
+                if (scale < 0) {
+                    throw Error.error(ErrorCode.X_42592);
+                }
+
+                readThis(Tokens.RIGHTBRACKET);
+            }
+
+            typeObject = new ArrayType(typeObject, maxCardinality);
+        }
+
+        return typeObject;
+    }
+
+    void readSimpleColumnNames(OrderedHashSet columns,
+                               RangeVariable rangeVar) {
+
+        while (true) {
+            ColumnSchema col = readSimpleColumnName(rangeVar);
+
+            if (!columns.add(col.getName().name)) {
+                throw Error.error(ErrorCode.X_42579, col.getName().name);
+            }
+
+            if (readIfThis(Tokens.COMMA)) {
+                continue;
+            }
+
+            if (token.tokenType == Tokens.CLOSEBRACKET) {
+                break;
+            }
+
+            throw unexpectedToken();
+        }
+    }
+
+    void readTargetSpecificationList(OrderedHashSet targets,
+                                     RangeVariable[] rangeVars,
+                                     LongDeque colIndexList) {
+
+        while (true) {
+            Expression target = XreadTargetSpecification(rangeVars,
+                colIndexList);
+
+            if (!targets.add(target)) {
+                ColumnSchema col = target.getColumn();
+
+                throw Error.error(ErrorCode.X_42579, col.getName().name);
+            }
+
+            if (readIfThis(Tokens.COMMA)) {
+                continue;
+            }
+
+            if (token.tokenType == Tokens.CLOSEBRACKET) {
+                break;
+            }
+
+            if (token.tokenType == Tokens.FROM) {
+                break;
+            }
+
+            throw unexpectedToken();
+        }
+    }
+
+    void readSimpleColumnNames(OrderedHashSet columns, Table table) {
+
+        while (true) {
+            ColumnSchema col = readSimpleColumnName(table);
+
+            if (!columns.add(col.getName().name)) {
+                throw Error.error(ErrorCode.X_42577, col.getName().name);
+            }
+
+            if (readIfThis(Tokens.COMMA)) {
+                continue;
+            }
+
+            if (token.tokenType == Tokens.CLOSEBRACKET) {
+                break;
+            }
+
+            throw unexpectedToken();
+        }
+    }
+
+    HsqlName[] readColumnNames(HsqlName tableName) {
+
+        BitMap         quotedFlags = new BitMap(32);
+        OrderedHashSet set         = readColumnNames(quotedFlags, false);
+        HsqlName[]     colList     = new HsqlName[set.size()];
+
+        for (int i = 0; i < colList.length; i++) {
+            String  name   = (String) set.get(i);
+            boolean quoted = quotedFlags.isSet(i);
+
+            colList[i] = database.nameManager.newHsqlName(tableName.schema,
+                    name, quoted, SchemaObject.COLUMN, tableName);
+        }
+
+        return colList;
+    }
+
+    OrderedHashSet readColumnNames(boolean readAscDesc) {
+        return readColumnNames(null, readAscDesc);
+    }
+
+    OrderedHashSet readColumnNames(BitMap quotedFlags, boolean readAscDesc) {
+
+        readThis(Tokens.OPENBRACKET);
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        readColumnNameList(set, quotedFlags, readAscDesc);
+        readThis(Tokens.CLOSEBRACKET);
+
+        return set;
+    }
+
+    void readColumnNameList(OrderedHashSet set, BitMap quotedFlags,
+                            boolean readAscDesc) {
+
+        int i = 0;
+
+        while (true) {
+            if (session.isProcessingScript) {
+
+                // for old scripts
+                if (!isSimpleName()) {
+                    token.isDelimitedIdentifier = true;
+                }
+            } else {
+                checkIsSimpleName();
+            }
+
+            if (!set.add(token.tokenString)) {
+                throw Error.error(ErrorCode.X_42577, token.tokenString);
+            }
+
+            if (quotedFlags != null && isDelimitedIdentifier()) {
+                quotedFlags.set(i);
+            }
+
+            read();
+
+            i++;
+
+            if (readAscDesc) {
+                if (token.tokenType == Tokens.ASC
+                        || token.tokenType == Tokens.DESC) {
+                    read();
+                }
+            }
+
+            if (readIfThis(Tokens.COMMA)) {
+                continue;
+            }
+
+            break;
+        }
+    }
+
+    SimpleName[] readColumnNameList(OrderedHashSet set) {
+
+        BitMap columnNameQuoted = new BitMap(32);
+
+        readThis(Tokens.OPENBRACKET);
+        readColumnNameList(set, columnNameQuoted, false);
+        readThis(Tokens.CLOSEBRACKET);
+
+        SimpleName[] columnNameList = new SimpleName[set.size()];
+
+        for (int i = 0; i < set.size(); i++) {
+            SimpleName name =
+                HsqlNameManager.getSimpleName((String) set.get(i),
+                                              columnNameQuoted.isSet(i));
+
+            columnNameList[i] = name;
+        }
+
+        return columnNameList;
+    }
+
+    int XreadUnionType() {
+
+        int unionType = QueryExpression.NOUNION;
+
+        switch (token.tokenType) {
+
+            case Tokens.UNION :
+                read();
+
+                unionType = QueryExpression.UNION;
+
+                if (token.tokenType == Tokens.ALL) {
+                    unionType = QueryExpression.UNION_ALL;
+
+                    read();
+                } else if (token.tokenType == Tokens.DISTINCT) {
+                    read();
+                }
+                break;
+
+            case Tokens.INTERSECT :
+                read();
+
+                unionType = QueryExpression.INTERSECT;
+
+                if (token.tokenType == Tokens.ALL) {
+                    unionType = QueryExpression.INTERSECT_ALL;
+
+                    read();
+                } else if (token.tokenType == Tokens.DISTINCT) {
+                    read();
+                }
+                break;
+
+            case Tokens.EXCEPT :
+            case Tokens.MINUS_EXCEPT :
+                read();
+
+                unionType = QueryExpression.EXCEPT;
+
+                if (token.tokenType == Tokens.ALL) {
+                    unionType = QueryExpression.EXCEPT_ALL;
+
+                    read();
+                } else if (token.tokenType == Tokens.DISTINCT) {
+                    read();
+                }
+                break;
+
+            default :
+                break;
+        }
+
+        return unionType;
+    }
+
+    void XreadUnionCorrespondingClause(QueryExpression queryExpression) {
+
+        if (token.tokenType == Tokens.CORRESPONDING) {
+            read();
+            queryExpression.setUnionCorresoponding();
+
+            if (token.tokenType == Tokens.BY) {
+                read();
+
+                OrderedHashSet names = readColumnNames(false);
+
+                queryExpression.setUnionCorrespondingColumns(names);
+            }
+        }
+    }
+
+    QueryExpression XreadQueryExpression() {
+
+        if (token.tokenType == Tokens.WITH) {
+            read();
+
+            if (token.tokenType == Tokens.RECURSIVE) {
+                throw super.unsupportedFeature();
+            }
+
+            compileContext.initSubqueryNames();
+
+            while (true) {
+                checkIsSimpleName();
+
+                HsqlName[] nameList = null;
+                HsqlName queryName =
+                    database.nameManager.newHsqlName(token.tokenString,
+                                                     isDelimitedIdentifier(),
+                                                     SchemaObject.SUBQUERY);
+
+                queryName.schema = SqlInvariants.SYSTEM_SUBQUERY_HSQLNAME;
+
+                read();
+
+                if (token.tokenType == Tokens.OPENBRACKET) {
+                    nameList = readColumnNames(queryName);
+                }
+
+                readThis(Tokens.AS);
+                readThis(Tokens.OPENBRACKET);
+
+                SubQuery subQuery = XreadTableNamedSubqueryBody(queryName,
+                    nameList);
+
+                readThis(Tokens.CLOSEBRACKET);
+                compileContext.registerSubquery(queryName.name, subQuery);
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+
+                    continue;
+                }
+
+                break;
+            }
+        }
+
+        QueryExpression queryExpression = XreadQueryExpressionBody();
+        SortAndSlice    sortAndSlice    = XreadOrderByExpression();
+
+        if (queryExpression.sortAndSlice == null) {
+            queryExpression.addSortAndSlice(sortAndSlice);
+        } else {
+            if (queryExpression.sortAndSlice.hasLimit()) {
+                if (sortAndSlice.hasLimit()) {
+                    throw Error.error(ErrorCode.X_42549);
+                }
+
+                for (int i = 0; i < sortAndSlice.exprList.size(); i++) {
+                    Expression e = (Expression) sortAndSlice.exprList.get(i);
+
+                    queryExpression.sortAndSlice.addOrderExpression(e);
+                }
+            } else {
+                queryExpression.addSortAndSlice(sortAndSlice);
+            }
+        }
+
+        return queryExpression;
+    }
+
+    QueryExpression XreadQueryExpressionBody() {
+
+        QueryExpression queryExpression = XreadQueryTerm();
+
+        while (true) {
+            switch (token.tokenType) {
+
+                case Tokens.UNION :
+                case Tokens.EXCEPT :
+                case Tokens.MINUS_EXCEPT : {
+                    queryExpression = XreadSetOperation(queryExpression);
+
+                    break;
+                }
+                default : {
+                    return queryExpression;
+                }
+            }
+        }
+    }
+
+    QueryExpression XreadQueryTerm() {
+
+        QueryExpression queryExpression = XreadQueryPrimary();
+
+        while (true) {
+            if (token.tokenType == Tokens.INTERSECT) {
+                queryExpression = XreadSetOperation(queryExpression);
+            } else {
+                return queryExpression;
+            }
+        }
+    }
+
+    private QueryExpression XreadSetOperation(
+            QueryExpression queryExpression) {
+
+        queryExpression = new QueryExpression(compileContext, queryExpression);
+
+        int unionType = XreadUnionType();
+
+        XreadUnionCorrespondingClause(queryExpression);
+
+        QueryExpression rightQueryExpression = XreadQueryTerm();
+
+        queryExpression.addUnion(rightQueryExpression, unionType);
+
+        return queryExpression;
+    }
+
+    QueryExpression XreadQueryPrimary() {
+
+        switch (token.tokenType) {
+
+            case Tokens.TABLE :
+            case Tokens.VALUES :
+            case Tokens.SELECT : {
+                QuerySpecification select = XreadSimpleTable();
+
+                return select;
+            }
+            case Tokens.OPENBRACKET : {
+                read();
+
+                QueryExpression queryExpression = XreadQueryExpressionBody();
+                SortAndSlice    sortAndSlice    = XreadOrderByExpression();
+
+                readThis(Tokens.CLOSEBRACKET);
+
+                if (queryExpression.sortAndSlice == null) {
+                    queryExpression.addSortAndSlice(sortAndSlice);
+                } else {
+                    if (queryExpression.sortAndSlice.hasLimit()) {
+                        if (sortAndSlice.hasLimit()) {
+                            throw Error.error(ErrorCode.X_42549);
+                        }
+
+                        for (int i = 0; i < sortAndSlice.exprList.size();
+                                i++) {
+                            Expression e =
+                                (Expression) sortAndSlice.exprList.get(i);
+
+                            queryExpression.sortAndSlice.addOrderExpression(e);
+                        }
+                    } else {
+                        queryExpression.addSortAndSlice(sortAndSlice);
+                    }
+                }
+
+                return queryExpression;
+            }
+            default : {
+                throw unexpectedToken();
+            }
+        }
+    }
+
+    QuerySpecification XreadSimpleTable() {
+
+        QuerySpecification select;
+
+        switch (token.tokenType) {
+
+            case Tokens.TABLE : {
+                read();
+
+                Table table = readTableName();
+
+                select = new QuerySpecification(session, table,
+                                                compileContext);
+
+                break;
+            }
+            case Tokens.VALUES : {
+                read();
+
+                SubQuery sq = XreadRowValueExpressionList();
+
+                select = new QuerySpecification(session, sq.getTable(),
+                                                compileContext);
+
+                break;
+            }
+            case Tokens.SELECT : {
+                select = XreadQuerySpecification();
+
+                break;
+            }
+            default : {
+                throw unexpectedToken();
+            }
+        }
+
+        return select;
+    }
+
+    QuerySpecification XreadQuerySpecification() {
+
+        QuerySpecification select = XreadSelect();
+
+        XreadTableExpression(select);
+
+        return select;
+    }
+
+    void XreadTableExpression(QuerySpecification select) {
+        XreadFromClause(select);
+        readWhereGroupHaving(select);
+    }
+
+    QuerySpecification XreadSelect() {
+
+        QuerySpecification select = new QuerySpecification(compileContext);
+
+        readThis(Tokens.SELECT);
+
+        if (token.tokenType == Tokens.TOP || token.tokenType == Tokens.LIMIT) {
+            SortAndSlice sortAndSlice = XreadTopOrLimit();
+
+            if (sortAndSlice != null) {
+                select.addSortAndSlice(sortAndSlice);
+            }
+        }
+
+        if (token.tokenType == Tokens.DISTINCT) {
+            select.isDistinctSelect = true;
+
+            read();
+        } else if (token.tokenType == Tokens.ALL) {
+            read();
+        }
+
+        while (true) {
+            Expression e = XreadValueExpression();
+
+            if (token.tokenType == Tokens.AS) {
+                read();
+                checkIsNonCoreReservedIdentifier();
+            }
+
+            if (isNonCoreReservedIdentifier()) {
+                e.setAlias(HsqlNameManager.getSimpleName(token.tokenString,
+                        isDelimitedIdentifier()));
+                read();
+            }
+
+            select.addSelectColumnExpression(e);
+
+            if (token.tokenType == Tokens.FROM) {
+                break;
+            }
+
+            if (token.tokenType == Tokens.INTO) {
+                break;
+            }
+
+            if (readIfThis(Tokens.COMMA)) {
+                continue;
+            }
+
+            throw unexpectedToken();
+        }
+
+        return select;
+    }
+
+    void XreadFromClause(QuerySpecification select) {
+
+        readThis(Tokens.FROM);
+
+        while (true) {
+            XreadTableReference(select);
+
+            if (readIfThis(Tokens.COMMA)) {
+                continue;
+            }
+
+            break;
+        }
+    }
+
+    void XreadTableReference(QuerySpecification select) {
+
+        boolean       natural = false;
+        RangeVariable range   = readTableOrSubquery();
+
+        select.addRangeVariable(range);
+
+        while (true) {
+            int     type  = token.tokenType;
+            boolean left  = false;
+            boolean right = false;
+            boolean end   = false;
+
+            type = token.tokenType;
+
+            switch (token.tokenType) {
+
+                case Tokens.INNER :
+                    read();
+                    readThis(Tokens.JOIN);
+                    break;
+
+                case Tokens.CROSS :
+                    if (natural) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.JOIN);
+                    break;
+
+                case Tokens.UNION :
+                    if (natural) {
+                        throw unexpectedToken();
+                    }
+
+                    int position = getPosition();
+
+                    read();
+
+                    if (token.tokenType == Tokens.JOIN) {
+                        read();
+
+                        break;
+                    } else {
+                        rewind(position);
+
+                        end = true;
+
+                        break;
+                    }
+                case Tokens.NATURAL :
+                    if (natural) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    natural = true;
+
+                    continue;
+                case Tokens.LEFT :
+                    read();
+                    readIfThis(Tokens.OUTER);
+                    readThis(Tokens.JOIN);
+
+                    left = true;
+                    break;
+
+                case Tokens.RIGHT :
+                    read();
+                    readIfThis(Tokens.OUTER);
+                    readThis(Tokens.JOIN);
+
+                    right = true;
+                    break;
+
+                case Tokens.FULL :
+                    read();
+                    readIfThis(Tokens.OUTER);
+                    readThis(Tokens.JOIN);
+
+                    left  = true;
+                    right = true;
+                    break;
+
+                case Tokens.JOIN :
+                    read();
+
+                    type = Tokens.INNER;
+                    break;
+
+                case Tokens.COMMA :
+                    if (natural) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    type = Tokens.COMMA;
+                    break;
+
+                default :
+                    if (natural) {
+                        throw unexpectedToken();
+                    }
+
+                    end = true;
+                    break;
+            }
+
+            if (end) {
+                break;
+            }
+
+            range = readTableOrSubquery();
+
+            Expression condition = null;
+
+            switch (type) {
+
+                case Tokens.COMMA :
+                    range.isBoundary = true;
+
+                    select.addRangeVariable(range);
+                    break;
+
+                case Tokens.CROSS :
+                    select.addRangeVariable(range);
+                    break;
+
+                case Tokens.UNION :
+                    select.addRangeVariable(range);
+
+                    condition = Expression.EXPR_FALSE;
+
+                    range.setJoinType(true, true);
+                    break;
+
+                case Tokens.LEFT :
+                case Tokens.RIGHT :
+                case Tokens.INNER :
+                case Tokens.FULL : {
+                    if (natural) {
+                        OrderedHashSet columns =
+                            range.getUniqueColumnNameSet();
+
+                        condition = select.getEquiJoinExpressions(columns,
+                                range, false);
+
+                        select.addRangeVariable(range);
+                    } else if (token.tokenType == Tokens.USING) {
+                        read();
+
+                        OrderedHashSet columns = new OrderedHashSet();
+
+                        readThis(Tokens.OPENBRACKET);
+                        readSimpleColumnNames(columns, range);
+                        readThis(Tokens.CLOSEBRACKET);
+
+                        condition = select.getEquiJoinExpressions(columns,
+                                range, true);
+
+                        select.addRangeVariable(range);
+                    } else if (token.tokenType == Tokens.ON) {
+                        read();
+
+                        condition = XreadBooleanValueExpression();
+
+                        select.addRangeVariable(range);
+                    } else {
+                        throw unexpectedToken();
+                    }
+
+                    range.setJoinType(left, right);
+
+                    break;
+                }
+            }
+
+            range.addJoinCondition(condition);
+
+            natural = false;
+        }
+    }
+
+    Expression getRowExpression(OrderedHashSet columnNames) {
+
+        Expression[] elements = new Expression[columnNames.size()];
+
+        for (int i = 0; i < elements.length; i++) {
+            String name = (String) columnNames.get(i);
+
+            elements[i] = new ExpressionColumn(null, null, name, false);
+        }
+
+        return new Expression(OpTypes.ROW, elements);
+    }
+
+    void readWhereGroupHaving(QuerySpecification select) {
+
+        // where
+        if (token.tokenType == Tokens.WHERE) {
+            read();
+
+            Expression e = XreadBooleanValueExpression();
+
+            select.addQueryCondition(e);
+        }
+
+        // group by
+        if (token.tokenType == Tokens.GROUP) {
+            read();
+            readThis(Tokens.BY);
+
+            while (true) {
+                Expression e = XreadValueExpression();
+
+                select.addGroupByColumnExpression(e);
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+
+                    continue;
+                }
+
+                break;
+            }
+        }
+
+        // having
+        if (token.tokenType == Tokens.HAVING) {
+            read();
+
+            Expression e = XreadBooleanValueExpression();
+
+            select.addHavingExpression(e);
+        }
+    }
+
+    SortAndSlice XreadOrderByExpression() {
+
+        SortAndSlice sortAndSlice = null;
+
+        if (token.tokenType == Tokens.ORDER) {
+            read();
+            readThis(Tokens.BY);
+
+            sortAndSlice = XreadOrderBy();
+        }
+
+        if (token.tokenType == Tokens.LIMIT || token.tokenType == Tokens.FETCH
+                || token.tokenType == Tokens.OFFSET) {
+            if (sortAndSlice == null) {
+                sortAndSlice = new SortAndSlice();
+            }
+
+            XreadLimit(sortAndSlice);
+        }
+
+        return sortAndSlice == null ? SortAndSlice.noSort
+                                    : sortAndSlice;
+    }
+
+    private SortAndSlice XreadTopOrLimit() {
+
+        Expression e1 = null;
+        Expression e2 = null;
+
+        if (token.tokenType == Tokens.LIMIT) {
+            int position = getPosition();
+
+            read();
+
+            e1 = XreadSimpleValueSpecificationOrNull();
+
+            if (e1 == null) {
+                rewind(position);
+
+                return null;
+            }
+
+            e2 = XreadSimpleValueSpecificationOrNull();
+
+            if (e2 == null) {
+                throw Error.error(ErrorCode.X_42563,
+                                  ErrorCode.M_INVALID_LIMIT);
+            }
+        } else if (token.tokenType == Tokens.TOP) {
+            int position = getPosition();
+
+            read();
+
+            e2 = XreadSimpleValueSpecificationOrNull();
+
+            if (e2 == null) {
+                rewind(position);
+
+                return null;
+            }
+
+            e1 = new ExpressionValue(ValuePool.INTEGER_0, Type.SQL_INTEGER);
+        }
+
+        boolean valid = true;
+
+        if (e1.isUnresolvedParam()) {
+            e1.setDataType(session, Type.SQL_INTEGER);
+        } else {
+            valid = (e1.getDataType().typeCode == Types.SQL_INTEGER
+                     && ((Integer) e1.getValue(null)).intValue() >= 0);
+        }
+
+        if (e2.isUnresolvedParam()) {
+            e2.setDataType(session, Type.SQL_INTEGER);
+        } else {
+            valid &= (e2.getDataType().typeCode == Types.SQL_INTEGER
+                      && ((Integer) e2.getValue(null)).intValue() >= 0);
+        }
+
+        if (valid) {
+            SortAndSlice sortAndSlice = new SortAndSlice();
+
+            sortAndSlice.addLimitCondition(new ExpressionOp(OpTypes.LIMIT, e1,
+                    e2));
+
+            return sortAndSlice;
+        }
+
+        throw Error.error(ErrorCode.X_42563, ErrorCode.M_INVALID_LIMIT);
+    }
+
+    private void XreadLimit(SortAndSlice sortAndSlice) {
+
+        Expression e1 = null;
+        Expression e2 = null;
+
+        if (token.tokenType == Tokens.OFFSET) {
+            read();
+
+            e1 = XreadSimpleValueSpecificationOrNull();
+
+            if (e1 == null) {
+                throw Error.error(ErrorCode.X_42563,
+                                  ErrorCode.M_INVALID_LIMIT);
+            }
+
+            if (token.tokenType == Tokens.ROW
+                    || token.tokenType == Tokens.ROWS) {
+                read();
+            }
+        }
+
+        if (token.tokenType == Tokens.LIMIT) {
+            read();
+
+            e2 = XreadSimpleValueSpecificationOrNull();
+
+            if (e2 == null) {
+                throw Error.error(ErrorCode.X_42563,
+                                  ErrorCode.M_INVALID_LIMIT);
+            }
+
+            if (e1 == null && token.tokenType == Tokens.OFFSET) {
+                read();
+
+                e1 = XreadSimpleValueSpecificationOrNull();
+            }
+        } else if (token.tokenType == Tokens.FETCH) {
+            read();
+
+            if (token.tokenType == Tokens.FIRST
+                    || token.tokenType == Tokens.NEXT) {
+                read();
+            }
+
+            e2 = XreadSimpleValueSpecificationOrNull();
+
+            if (e2 == null) {
+                e2 = new ExpressionValue(ValuePool.INTEGER_1,
+                                         Type.SQL_INTEGER);
+            }
+
+            if (token.tokenType == Tokens.ROW
+                    || token.tokenType == Tokens.ROWS) {
+                read();
+            }
+
+            readThis(Tokens.ONLY);
+        }
+
+        if (e1 == null) {
+            e1 = new ExpressionValue(ValuePool.INTEGER_0, Type.SQL_INTEGER);
+        }
+
+        boolean valid = true;
+
+        if (e1.isUnresolvedParam()) {
+            e1.setDataType(session, Type.SQL_INTEGER);
+        } else {
+            valid = (e1.getDataType().typeCode == Types.SQL_INTEGER
+                     && ((Integer) e1.getValue(null)).intValue() >= 0);
+        }
+
+        if (e2 != null) {
+            if (e2.isUnresolvedParam()) {
+                e2.setDataType(session, Type.SQL_INTEGER);
+            } else {
+                valid &= (e2.getDataType().typeCode == Types.SQL_INTEGER);
+
+                Integer value = ((Integer) e2.getValue(null));
+
+                valid &= (value.intValue() >= 0);
+            }
+        }
+
+        if (valid) {
+            sortAndSlice.addLimitCondition(new ExpressionOp(OpTypes.LIMIT, e1,
+                    e2));
+
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42563, ErrorCode.M_INVALID_LIMIT);
+    }
+
+    private SortAndSlice XreadOrderBy() {
+
+        SortAndSlice sortAndSlice = new SortAndSlice();
+
+        while (true) {
+            Expression        e = XreadValueExpression();
+            ExpressionOrderBy o = new ExpressionOrderBy(e);
+
+            if (token.tokenType == Tokens.DESC) {
+                o.setDescending();
+                read();
+            } else if (token.tokenType == Tokens.ASC) {
+                read();
+            }
+
+            if (token.tokenType == Tokens.NULLS) {
+                read();
+
+                if (token.tokenType == Tokens.FIRST) {
+                    read();
+                } else if (token.tokenType == Tokens.LAST) {
+                    read();
+                    o.setNullsLast();
+                } else {
+                    throw unexpectedToken();
+                }
+            }
+
+            sortAndSlice.addOrderExpression(o);
+
+            if (token.tokenType == Tokens.COMMA) {
+                read();
+
+                continue;
+            }
+
+            break;
+        }
+
+        return sortAndSlice;
+    }
+
+    protected RangeVariable readSimpleRangeVariable(int operation) {
+
+        Table      table = readTableName();
+        SimpleName alias = null;
+
+        if (operation != StatementTypes.TRUNCATE) {
+            if (token.tokenType == Tokens.AS) {
+                read();
+                checkIsNonCoreReservedIdentifier();
+            }
+
+            if (isNonCoreReservedIdentifier()) {
+                alias = HsqlNameManager.getSimpleName(token.tokenString,
+                                                      isDelimitedIdentifier());
+
+                read();
+            }
+        }
+
+        if (table.isView) {
+            switch (operation) {
+
+                case StatementTypes.MERGE :
+                    if (table.isTriggerUpdatable()
+                            && table.isTriggerDeletable()) {
+                        break;
+                    }
+
+                    if (table.isUpdatable() && table.isInsertable()) {
+                        break;
+                    }
+
+                    throw Error.error(ErrorCode.X_42545);
+                case StatementTypes.UPDATE_WHERE :
+                    if (table.isTriggerUpdatable()) {
+                        break;
+                    }
+
+                    if (table.isUpdatable()) {
+                        break;
+                    }
+
+                    throw Error.error(ErrorCode.X_42545);
+                case StatementTypes.DELETE_WHERE :
+                    if (table.isTriggerDeletable()) {
+                        break;
+                    }
+
+                    if (table.isUpdatable()) {
+                        break;
+                    }
+
+                    throw Error.error(ErrorCode.X_42545);
+            }
+
+            table = ((View) table).getSubqueryTable();
+        }
+
+        RangeVariable range = new RangeVariable(table, alias, null, null,
+            compileContext);
+
+        return range;
+    }
+
+    protected Table readNamedSubqueryOrNull() {
+
+        if (!isSimpleName()) {
+            return null;
+        }
+
+        SubQuery sq = compileContext.getNamedSubQuery(token.tokenString);
+
+        if (sq == null) {
+            return null;
+        }
+
+        read();
+
+        return sq.getTable();
+    }
+
+    /**
+     * Creates a RangeVariable from the parse context. <p>
+     */
+    protected RangeVariable readTableOrSubquery() {
+
+        Table          table          = null;
+        SimpleName     alias          = null;
+        SimpleName[]   columnNameList = null;
+        OrderedHashSet columnList     = null;
+
+        switch (token.tokenType) {
+
+            case Tokens.OPENBRACKET : {
+                Expression e = XreadTableSubqueryOrJoinedTable();
+
+                table = e.getTable();
+
+                break;
+            }
+            case Tokens.UNNEST : {
+                Expression e = XreadCollectionDerivedTable();
+
+                table = e.getTable();
+
+                break;
+            }
+            case Tokens.LATERAL : {
+                Expression e = XreadLateralDerivedTable();
+
+                table = e.getTable();
+
+                break;
+            }
+            case Tokens.TABLE : {
+                Expression e = XreadTableFunctionDerivedTable();
+
+                table = e.getTable();
+
+                break;
+            }
+            default : {
+                table = readNamedSubqueryOrNull();
+
+                if (table == null) {
+                    table = readTableName();
+                }
+
+                if (table.isView()) {
+                    table = ((View) table).getSubqueryTable();
+                }
+            }
+        }
+
+        boolean hasAs = false;
+
+        if (token.tokenType == Tokens.AS) {
+            read();
+            checkIsNonCoreReservedIdentifier();
+
+            hasAs = true;
+        }
+
+        if (isNonCoreReservedIdentifier()) {
+            boolean limit = token.tokenType == Tokens.LIMIT
+                            || token.tokenType == Tokens.OFFSET
+                            || token.tokenType == Tokens.FETCH;
+            boolean minus    = token.tokenType == Tokens.MINUS_EXCEPT;
+            int     position = getPosition();
+
+            alias = HsqlNameManager.getSimpleName(token.tokenString,
+                                                  isDelimitedIdentifier());
+
+            read();
+
+            if (token.tokenType == Tokens.OPENBRACKET) {
+                columnList     = new OrderedHashSet();
+                columnNameList = readColumnNameList(columnList);
+            } else if (!hasAs && limit) {
+                if (token.tokenType == Tokens.COLON
+                        || token.tokenType == Tokens.QUESTION
+                        || token.tokenType == Tokens.X_VALUE) {
+                    alias = null;
+
+                    rewind(position);
+                }
+            } else if (!hasAs && minus) {
+                rewind(position);
+            }
+        }
+
+        RangeVariable range = new RangeVariable(table, alias, columnList,
+            columnNameList, compileContext);
+
+        return range;
+    }
+
+    private Expression readAggregate() {
+
+        int        tokenT = token.tokenType;
+        Expression e;
+
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        e = readAggregateExpression(tokenT);
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return e;
+    }
+
+    private Expression readAggregateExpression(int tokenT) {
+
+        int     type     = ParserDQL.getExpressionType(tokenT);
+        boolean distinct = false;
+        boolean all      = false;
+
+        if (token.tokenType == Tokens.DISTINCT) {
+            distinct = true;
+
+            read();
+        } else if (token.tokenType == Tokens.ALL) {
+            all = true;
+
+            read();
+        }
+
+        Expression e = XreadValueExpression();
+
+        switch (type) {
+
+            case OpTypes.COUNT :
+                if (e.getType() == OpTypes.MULTICOLUMN) {
+                    if (((ExpressionColumn) e).tableName != null) {
+                        throw unexpectedToken();
+                    }
+
+                    if (all || distinct) {
+                        throw unexpectedToken();
+                    }
+
+                    e.opType = OpTypes.ASTERISK;
+
+                    break;
+                } else {
+                    break;
+                }
+            case OpTypes.STDDEV_POP :
+            case OpTypes.STDDEV_SAMP :
+            case OpTypes.VAR_POP :
+            case OpTypes.VAR_SAMP :
+                if (all || distinct) {
+                    throw Error.error(ErrorCode.X_42582, all ? Tokens.T_ALL
+                                                             : Tokens
+                                                             .T_DISTINCT);
+                }
+                break;
+
+            default :
+                if (e.getType() == OpTypes.ASTERISK) {
+                    throw unexpectedToken();
+                }
+        }
+
+        Expression aggregateExp = new ExpressionAggregate(type, distinct, e);
+
+        return aggregateExp;
+    }
+
+//--------------------------------------
+    // returns null
+    // := <unsigned literal> | <general value specification>
+    Expression XreadValueSpecificationOrNull() {
+
+        Expression e     = null;
+        boolean    minus = false;
+
+        switch (token.tokenType) {
+
+            case Tokens.PLUS :
+                read();
+                break;
+
+            case Tokens.MINUS :
+                read();
+
+                minus = true;
+                break;
+        }
+
+        e = XreadUnsignedValueSpecificationOrNull();
+
+        if (e == null) {
+            return null;
+        }
+
+        if (minus) {
+            e = new ExpressionArithmetic(OpTypes.NEGATE, e);
+        }
+
+        return e;
+    }
+
+    // returns null
+    // <unsigned literl> | <general value specification>
+    Expression XreadUnsignedValueSpecificationOrNull() {
+
+        Expression e;
+
+        switch (token.tokenType) {
+
+            case Tokens.TRUE :
+                read();
+
+                return Expression.EXPR_TRUE;
+
+            case Tokens.FALSE :
+                read();
+
+                return Expression.EXPR_FALSE;
+
+            case Tokens.DEFAULT :
+                if (compileContext.contextuallyTypedExpression) {
+                    read();
+
+                    e = new ExpressionColumn(OpTypes.DEFAULT);
+
+                    return e;
+                }
+                break;
+
+            case Tokens.NULL :
+                e = new ExpressionValue(null, null);
+
+                read();
+
+                return e;
+
+            case Tokens.X_VALUE :
+                e = new ExpressionValue(token.tokenValue, token.dataType);
+
+                read();
+
+                return e;
+
+            case Tokens.X_DELIMITED_IDENTIFIER :
+            case Tokens.X_IDENTIFIER :
+                if (!token.isHostParameter) {
+                    return null;
+                }
+
+                return null;
+
+            case Tokens.COLON :
+                read();
+
+                if (token.tokenType == Tokens.X_DELIMITED_IDENTIFIER
+                        || token.tokenType == Tokens.X_IDENTIFIER) {}
+                else {
+                    throw unexpectedToken(Tokens.T_COLON);
+                }
+
+            // fall through
+            case Tokens.QUESTION :
+                e = new ExpressionColumn(OpTypes.DYNAMIC_PARAM);
+
+                compileContext.addParameter(e, getPosition());
+                read();
+
+                return e;
+
+            case Tokens.COLLATION :
+                return XreadCurrentCollationSpec();
+
+            case Tokens.VALUE :
+            case Tokens.CURRENT_CATALOG :
+            case Tokens.CURRENT_DEFAULT_TRANSFORM_GROUP :
+            case Tokens.CURRENT_PATH :
+            case Tokens.CURRENT_ROLE :
+            case Tokens.CURRENT_SCHEMA :
+            case Tokens.CURRENT_TRANSFORM_GROUP_FOR_TYPE :
+            case Tokens.CURRENT_USER :
+            case Tokens.SESSION_USER :
+            case Tokens.SYSTEM_USER :
+            case Tokens.USER :
+                FunctionSQL function =
+                    FunctionSQL.newSQLFunction(token.tokenString,
+                                               compileContext);
+
+                if (function == null) {
+                    return null;
+                }
+
+                return readSQLFunction(function);
+
+            // read SQL parameter reference
+        }
+
+        return null;
+    }
+
+    // <unsigned literl> | <dynamic parameter> | <variable>
+    Expression XreadSimpleValueSpecificationOrNull() {
+
+        Expression e;
+
+        switch (token.tokenType) {
+
+            case Tokens.X_VALUE :
+                e = new ExpressionValue(token.tokenValue, token.dataType);
+
+                read();
+
+                return e;
+
+            case Tokens.COLON :
+                read();
+
+                if (token.tokenType == Tokens.X_DELIMITED_IDENTIFIER
+                        || token.tokenType == Tokens.X_IDENTIFIER) {}
+                else {
+                    throw unexpectedToken(Tokens.T_COLON);
+                }
+
+            // fall through
+            case Tokens.QUESTION :
+                e = new ExpressionColumn(OpTypes.DYNAMIC_PARAM);
+
+                compileContext.addParameter(e, getPosition());
+                read();
+
+                return e;
+
+            case Tokens.X_IDENTIFIER :
+            case Tokens.X_DELIMITED_IDENTIFIER :
+                checkValidCatalogName(token.namePrePrePrefix);
+
+                return new ExpressionColumn(token.namePrePrefix,
+                                            token.namePrefix,
+                                            token.tokenString,
+                                            database.sqlEnforceRefs);
+
+            default :
+                return null;
+        }
+    }
+
+    // combined <value expression primary> and <predicate>
+    // exclusively called
+    // <explicit row value constructor> needed for predicate
+    Expression XreadAllTypesValueExpressionPrimary(boolean boole) {
+
+        Expression e = null;
+
+        switch (token.tokenType) {
+
+            case Tokens.EXISTS :
+            case Tokens.UNIQUE :
+                if (boole) {
+                    return XreadPredicate();
+                }
+                break;
+
+            case Tokens.ROW :
+                if (boole) {
+                    break;
+                }
+
+                read();
+                readThis(Tokens.OPENBRACKET);
+
+                e = XreadRowElementList(true);
+
+                readThis(Tokens.CLOSEBRACKET);
+                break;
+
+            default :
+                e = XreadSimpleValueExpressionPrimary();
+
+                if (e != null) {
+                    e = XreadArrayElementReference(e);
+                }
+        }
+
+        if (e == null && token.tokenType == Tokens.OPENBRACKET) {
+            read();
+
+            e = XreadRowElementList(true);
+
+            readThis(Tokens.CLOSEBRACKET);
+        }
+
+        if (boole && e != null) {
+            e = XreadPredicateRightPart(e);
+        }
+
+        return e;
+    }
+
+    // doesn't return null
+    // <value expression primary> ::= <parenthesized value expression>
+    // | <nonparenthesized value expression primary>
+    Expression XreadValueExpressionPrimary() {
+
+        Expression e;
+
+        e = XreadSimpleValueExpressionPrimary();
+
+        if (e != null) {
+            e = XreadArrayElementReference(e);
+
+            return e;
+        }
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            read();
+
+            e = XreadValueExpression();
+
+            readThis(Tokens.CLOSEBRACKET);
+        } else {
+            return null;
+        }
+
+        return e;
+    }
+
+    // returns null
+    //  <row value special case> :== this
+    // <boolean predicand> :== this | <parenthesized boolean value expression>
+    Expression XreadSimpleValueExpressionPrimary() {
+
+        Expression e;
+
+        e = XreadUnsignedValueSpecificationOrNull();
+
+        if (e != null) {
+            return e;
+        }
+
+        switch (token.tokenType) {
+
+            case Tokens.OPENBRACKET :
+                int position = getPosition();
+
+                read();
+
+                int subqueryPosition = getPosition();
+
+                readOpenBrackets();
+
+                switch (token.tokenType) {
+
+                    case Tokens.TABLE :
+                    case Tokens.VALUES :
+                    case Tokens.SELECT :
+                        SubQuery sq = null;
+
+                        rewind(subqueryPosition);
+
+                        try {
+                            sq = XreadSubqueryBody(false,
+                                                   OpTypes.SCALAR_SUBQUERY);
+
+                            readThis(Tokens.CLOSEBRACKET);
+                        } catch (HsqlException ex) {
+                            ex.setLevel(compileContext.subqueryDepth);
+
+                            if (lastError == null
+                                    || lastError.getLevel() < ex.getLevel()) {
+                                lastError = ex;
+                            }
+
+                            rewind(position);
+
+                            return null;
+                        }
+
+                        if (sq.queryExpression.isSingleColumn()) {
+                            return new Expression(OpTypes.SCALAR_SUBQUERY, sq);
+                        } else {
+                            return new Expression(OpTypes.ROW_SUBQUERY, sq);
+                        }
+                    default :
+                        rewind(position);
+
+                        return null;
+                }
+            case Tokens.ASTERISK :
+                e = new ExpressionColumn(token.namePrePrefix,
+                                         token.namePrefix);
+
+                getRecordedToken().setExpression(e);
+                read();
+
+                return e;
+
+            case Tokens.LEAST :
+                return readLeastExpression();
+
+            case Tokens.GREATEST :
+                return readGreatestExpression();
+
+            case Tokens.DECODE :
+                return readDecodeExpression();
+
+            case Tokens.CASEWHEN :
+                return readCaseWhenExpression();
+
+            case Tokens.CASE :
+                return readCaseExpression();
+
+            case Tokens.NULLIF :
+                return readNullIfExpression();
+
+            case Tokens.COALESCE :
+            case Tokens.IFNULL :
+                return readCoalesceExpression();
+
+            case Tokens.CAST :
+            case Tokens.CONVERT :
+                return readCastExpression();
+
+            case Tokens.DATE :
+            case Tokens.TIME :
+            case Tokens.TIMESTAMP :
+            case Tokens.INTERVAL :
+                e = readDateTimeIntervalLiteral();
+
+                if (e != null) {
+                    return e;
+                }
+                break;
+
+            case Tokens.ARRAY :
+                return readCollection(OpTypes.ARRAY);
+
+            case Tokens.ANY :
+            case Tokens.SOME :
+            case Tokens.EVERY :
+            case Tokens.COUNT :
+            case Tokens.MAX :
+            case Tokens.MIN :
+            case Tokens.SUM :
+            case Tokens.AVG :
+            case Tokens.STDDEV_POP :
+            case Tokens.STDDEV_SAMP :
+            case Tokens.VAR_POP :
+            case Tokens.VAR_SAMP :
+                return readAggregate();
+
+            case Tokens.NEXT :
+                return readSequenceExpression();
+
+            case Tokens.LEFT :
+            case Tokens.RIGHT :
+
+                // CLI function names
+                break;
+
+            case Tokens.TABLE : {
+                read();
+                readThis(Tokens.OPENBRACKET);
+
+                SubQuery sq = XreadTableSubqueryBody(false);
+
+                readThis(Tokens.CLOSEBRACKET);
+
+                return new Expression(OpTypes.TABLE_SUBQUERY, sq);
+            }
+            default :
+                if (isCoreReservedKey()) {
+                    throw unexpectedToken();
+                }
+        }
+
+        e = readColumnOrFunctionExpression();
+
+        return e;
+    }
+
+    // OK - composite production -
+    // <numeric primary> <charactr primary> <binary primary> <datetime primary> <interval primary>
+    Expression XreadAllTypesPrimary(boolean boole) {
+
+        Expression e = null;
+
+        switch (token.tokenType) {
+
+            case Tokens.SUBSTRING :
+            case Tokens.SUBSTRING_REGEX :
+            case Tokens.LOWER :
+            case Tokens.UPPER :
+            case Tokens.TRANSLATE_REGEX :
+            case Tokens.TRIM :
+            case Tokens.OVERLAY :
+            case Tokens.NORMALIZE :
+
+            //
+            case Tokens.POSITION :
+            case Tokens.OCCURRENCES_REGEX :
+            case Tokens.POSITION_REGEX :
+            case Tokens.EXTRACT :
+            case Tokens.CHAR_LENGTH :
+            case Tokens.CHARACTER_LENGTH :
+            case Tokens.OCTET_LENGTH :
+            case Tokens.CARDINALITY :
+            case Tokens.ABS :
+            case Tokens.MOD :
+            case Tokens.LN :
+            case Tokens.EXP :
+            case Tokens.POWER :
+            case Tokens.SQRT :
+            case Tokens.FLOOR :
+            case Tokens.CEILING :
+            case Tokens.CEIL :
+            case Tokens.WIDTH_BUCKET :
+                FunctionSQL function =
+                    FunctionSQL.newSQLFunction(token.tokenString,
+                                               compileContext);
+
+                if (function == null) {
+                    throw unsupportedFeature();
+                }
+
+                e = readSQLFunction(function);
+
+                if (e != null) {
+                    break;
+                }
+            default :
+                e = XreadAllTypesValueExpressionPrimary(boole);
+        }
+
+        e = XreadModifier(e);
+
+        return e;
+    }
+
+    Expression XreadModifier(Expression e) {
+
+        switch (token.tokenType) {
+
+            case Tokens.AT : {
+                read();
+
+                Expression e1 = null;
+
+                if (token.tokenType == Tokens.LOCAL) {
+                    read();
+                } else {
+                    readThis(Tokens.TIME);
+                    readThis(Tokens.ZONE);
+
+                    e1 = XreadValueExpressionPrimary();
+
+                    switch (token.tokenType) {
+
+                        case Tokens.YEAR :
+                        case Tokens.MONTH :
+                        case Tokens.DAY :
+                        case Tokens.HOUR :
+                        case Tokens.MINUTE :
+                        case Tokens.SECOND : {
+                            IntervalType type = readIntervalType(false);
+
+                            if (e1.getType() == OpTypes.SUBTRACT) {
+                                e1.dataType = type;
+                            } else {
+                                e1 = new ExpressionOp(e1, type);
+                            }
+                        }
+                    }
+                }
+
+                e = new ExpressionOp(OpTypes.ZONE_MODIFIER, e, e1);
+
+                break;
+            }
+            case Tokens.YEAR :
+            case Tokens.MONTH :
+            case Tokens.DAY :
+            case Tokens.HOUR :
+            case Tokens.MINUTE :
+            case Tokens.SECOND : {
+                IntervalType type = readIntervalType(true);
+
+                if (e.getType() == OpTypes.SUBTRACT) {
+                    e.dataType = type;
+                } else {
+                    e = new ExpressionOp(e, type);
+                }
+
+                break;
+            }
+            case Tokens.COLLATE : {
+                read();
+
+                SchemaObject collation =
+                    database.schemaManager.getSchemaObject(token.namePrefix,
+                        token.tokenString, SchemaObject.COLLATION);
+            }
+        }
+
+        return e;
+    }
+
+    Expression XreadValueExpressionWithContext() {
+
+        Expression e;
+
+        compileContext.contextuallyTypedExpression = true;
+        e = XreadValueExpressionOrNull();
+        compileContext.contextuallyTypedExpression = false;
+
+        return e;
+    }
+
+    Expression XreadValueExpressionOrNull() {
+
+        Expression e = XreadAllTypesCommonValueExpression(true);
+
+        if (e == null) {
+            return null;
+        }
+
+        return e;
+    }
+
+    /**
+     *     <value expression> ::=
+     *   <common value expression>
+     *   | <boolean value expression>
+     *   | <row value expression>
+     *
+     */
+    Expression XreadValueExpression() {
+
+        Expression e = XreadAllTypesCommonValueExpression(true);
+
+        if (token.tokenType == Tokens.LEFTBRACKET) {
+            read();
+
+            Expression e1 = XreadNumericValueExpression();
+
+            readThis(Tokens.RIGHTBRACKET);
+
+            e = new ExpressionAccessor(e, e1);
+        }
+
+        return e;
+    }
+
+    // union of <numeric | datetime | string | interval value expression>
+    Expression XreadRowOrCommonValueExpression() {
+        return XreadAllTypesCommonValueExpression(false);
+    }
+
+    // union of <numeric | datetime | string | interval | boolean value expression>
+    // no <row value expression> and no <predicate>
+    Expression XreadAllTypesCommonValueExpression(boolean boole) {
+
+        Expression e    = XreadAllTypesTerm(boole);
+        int        type = 0;
+        boolean    end  = false;
+
+        while (true) {
+            switch (token.tokenType) {
+
+                case Tokens.PLUS :
+                    type  = OpTypes.ADD;
+                    boole = false;
+                    break;
+
+                case Tokens.MINUS :
+                    type  = OpTypes.SUBTRACT;
+                    boole = false;
+                    break;
+
+                case Tokens.CONCAT :
+                    type  = OpTypes.CONCAT;
+                    boole = false;
+                    break;
+
+                case Tokens.OR :
+                    if (boole) {
+                        type = OpTypes.OR;
+
+                        break;
+                    }
+
+                // fall through
+                default :
+                    end = true;
+                    break;
+            }
+
+            if (end) {
+                break;
+            }
+
+            read();
+
+            Expression a = e;
+
+            e = XreadAllTypesTerm(boole);
+            e = boole ? (Expression) new ExpressionLogical(type, a, e)
+                      : new ExpressionArithmetic(type, a, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadAllTypesTerm(boolean boole) {
+
+        Expression e    = XreadAllTypesFactor(boole);
+        int        type = 0;
+        boolean    end  = false;
+
+        while (true) {
+            switch (token.tokenType) {
+
+                case Tokens.ASTERISK :
+                    type  = OpTypes.MULTIPLY;
+                    boole = false;
+                    break;
+
+                case Tokens.DIVIDE :
+                    type  = OpTypes.DIVIDE;
+                    boole = false;
+                    break;
+
+                case Tokens.AND :
+                    if (boole) {
+                        type = OpTypes.AND;
+
+                        break;
+                    }
+
+                // fall through
+                default :
+                    end = true;
+                    break;
+            }
+
+            if (end) {
+                break;
+            }
+
+            read();
+
+            Expression a = e;
+
+            e = XreadAllTypesFactor(boole);
+
+            if (e == null) {
+                throw unexpectedToken();
+            }
+
+            e = boole ? (Expression) new ExpressionLogical(type, a, e)
+                      : new ExpressionArithmetic(type, a, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadAllTypesFactor(boolean boole) {
+
+        Expression e;
+        boolean    minus   = false;
+        boolean    not     = false;
+        boolean    unknown = false;
+
+        switch (token.tokenType) {
+
+            case Tokens.PLUS :
+                read();
+
+                boole = false;
+                break;
+
+            case Tokens.MINUS :
+                read();
+
+                boole = false;
+                minus = true;
+                break;
+
+            case Tokens.NOT :
+                if (boole) {
+                    read();
+
+                    not = true;
+                }
+                break;
+        }
+
+        e = XreadAllTypesPrimary(boole);
+
+        if (boole && token.tokenType == Tokens.IS) {
+            read();
+
+            if (token.tokenType == Tokens.NOT) {
+                read();
+
+                not = !not;
+            }
+
+            if (token.tokenType == Tokens.TRUE) {
+                read();
+            } else if (token.tokenType == Tokens.FALSE) {
+                read();
+
+                not = !not;
+            } else if (token.tokenType == Tokens.UNKNOWN) {
+                read();
+
+                unknown = true;
+            } else {
+                throw unexpectedToken();
+            }
+        }
+
+        if (unknown) {
+            e = new ExpressionLogical(OpTypes.IS_NULL, e);
+        } else if (minus) {
+            e = new ExpressionArithmetic(OpTypes.NEGATE, e);
+        } else if (not) {
+            e = new ExpressionLogical(OpTypes.NOT, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadStringValueExpression() {
+
+        return XreadCharacterValueExpression();
+
+//        XreadBinaryValueExpression();
+    }
+
+    Expression XreadCharacterValueExpression() {
+
+        Expression   e         = XreadCharacterPrimary();
+        SchemaObject collation = readCollateClauseOrNull();
+
+        while (token.tokenType == Tokens.CONCAT) {
+            read();
+
+            Expression a = e;
+
+            e         = XreadCharacterPrimary();
+            collation = readCollateClauseOrNull();
+            e         = new ExpressionArithmetic(OpTypes.CONCAT, a, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadCharacterPrimary() {
+
+        switch (token.tokenType) {
+
+            case Tokens.SUBSTRING :
+
+//            case Token.SUBSTRING_REGEX :
+            case Tokens.LOWER :
+            case Tokens.UPPER :
+
+//            case Token.TRANSLATE_REGEX :
+            case Tokens.TRIM :
+            case Tokens.OVERLAY :
+
+//            case Token.NORMALIZE :
+                FunctionSQL function =
+                    FunctionSQL.newSQLFunction(token.tokenString,
+                                               compileContext);
+                Expression e = readSQLFunction(function);
+
+                if (e != null) {
+                    return e;
+                }
+            default :
+        }
+
+        return XreadValueExpressionPrimary();
+    }
+
+    Expression XreadNumericPrimary() {
+
+        switch (token.tokenType) {
+
+            case Tokens.POSITION :
+
+//            case Token.OCCURRENCES_REGEX :
+//            case Token.POSITION_REGEX :
+            case Tokens.EXTRACT :
+            case Tokens.CHAR_LENGTH :
+            case Tokens.CHARACTER_LENGTH :
+            case Tokens.OCTET_LENGTH :
+            case Tokens.CARDINALITY :
+            case Tokens.ABS :
+            case Tokens.MOD :
+            case Tokens.LN :
+            case Tokens.EXP :
+            case Tokens.POWER :
+            case Tokens.SQRT :
+            case Tokens.FLOOR :
+            case Tokens.CEILING :
+            case Tokens.CEIL :
+
+//            case Token.WIDTH_BUCKET :
+                FunctionSQL function =
+                    FunctionSQL.newSQLFunction(token.tokenString,
+                                               compileContext);
+
+                if (function == null) {
+                    throw super.unexpectedToken();
+                }
+
+                Expression e = readSQLFunction(function);
+
+                if (e != null) {
+                    return e;
+                }
+            default :
+        }
+
+        return XreadValueExpressionPrimary();
+    }
+
+    Expression XreadNumericValueExpression() {
+
+        Expression e = XreadTerm();
+
+        while (true) {
+            int type;
+
+            if (token.tokenType == Tokens.PLUS) {
+                type = OpTypes.ADD;
+            } else if (token.tokenType == Tokens.MINUS) {
+                type = OpTypes.SUBTRACT;
+            } else {
+                break;
+            }
+
+            read();
+
+            Expression a = e;
+
+            e = XreadTerm();
+            e = new ExpressionArithmetic(type, a, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadTerm() {
+
+        Expression e = XreadFactor();
+        int        type;
+
+        while (true) {
+            if (token.tokenType == Tokens.ASTERISK) {
+                type = OpTypes.MULTIPLY;
+            } else if (token.tokenType == Tokens.DIVIDE) {
+                type = OpTypes.DIVIDE;
+            } else {
+                break;
+            }
+
+            read();
+
+            Expression a = e;
+
+            e = XreadFactor();
+
+            if (e == null) {
+                throw unexpectedToken();
+            }
+
+            e = new ExpressionArithmetic(type, a, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadFactor() {
+
+        Expression e;
+        boolean    minus = false;
+
+        if (token.tokenType == Tokens.PLUS) {
+            read();
+        } else if (token.tokenType == Tokens.MINUS) {
+            read();
+
+            minus = true;
+        }
+
+        e = XreadNumericPrimary();
+
+        if (e == null) {
+            return null;
+        }
+
+        if (minus) {
+            e = new ExpressionArithmetic(OpTypes.NEGATE, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadDatetimeValueExpression() {
+
+        Expression e = XreadDateTimeIntervalTerm();
+
+        while (true) {
+            int type;
+
+            if (token.tokenType == Tokens.PLUS) {
+                type = OpTypes.ADD;
+            } else if (token.tokenType == Tokens.MINUS) {
+                type = OpTypes.SUBTRACT;
+            } else {
+                break;
+            }
+
+            read();
+
+            Expression a = e;
+
+            e = XreadDateTimeIntervalTerm();
+            e = new ExpressionArithmetic(type, a, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadIntervalValueExpression() {
+
+        Expression e = XreadDateTimeIntervalTerm();
+
+        while (true) {
+            int type;
+
+            if (token.tokenType == Tokens.PLUS) {
+                type = OpTypes.ADD;
+            } else if (token.tokenType == Tokens.MINUS) {
+                type = OpTypes.SUBTRACT;
+            } else {
+                break;
+            }
+
+            read();
+
+            Expression a = e;
+
+            e = XreadDateTimeIntervalTerm();
+            e = new ExpressionArithmetic(type, a, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadDateTimeIntervalTerm() {
+
+        switch (token.tokenType) {
+
+            case Tokens.CURRENT_DATE :
+            case Tokens.CURRENT_TIME :
+            case Tokens.CURRENT_TIMESTAMP :
+            case Tokens.LOCALTIME :
+            case Tokens.LOCALTIMESTAMP :
+
+            //
+            case Tokens.ABS :
+                FunctionSQL function =
+                    FunctionSQL.newSQLFunction(token.tokenString,
+                                               compileContext);
+
+                if (function == null) {
+                    throw super.unexpectedToken();
+                }
+
+                return readSQLFunction(function);
+
+            default :
+        }
+
+        return XreadValueExpressionPrimary();
+    }
+
+    // returns null
+    Expression XreadDateTimeValueFunctionOrNull() {
+
+        FunctionSQL function = null;
+
+        switch (token.tokenType) {
+
+            case Tokens.CURRENT_DATE :
+            case Tokens.CURRENT_TIME :
+            case Tokens.CURRENT_TIMESTAMP :
+            case Tokens.LOCALTIME :
+            case Tokens.LOCALTIMESTAMP :
+                function = FunctionSQL.newSQLFunction(token.tokenString,
+                                                      compileContext);
+                break;
+
+            case Tokens.NOW :
+            case Tokens.TODAY :
+                function = FunctionCustom.newCustomFunction(token.tokenString,
+                        token.tokenType);
+                break;
+
+            default :
+                return null;
+        }
+
+        if (function == null) {
+            throw super.unexpectedToken();
+        }
+
+        return readSQLFunction(function);
+    }
+
+    Expression XreadBooleanValueExpression() {
+
+        try {
+            Expression e = XreadBooleanTermOrNull();
+
+            if (e == null) {
+                throw Error.error(ErrorCode.X_42568);
+            }
+
+            while (true) {
+                int type;
+
+                if (token.tokenType == Tokens.OR) {
+                    type = OpTypes.OR;
+                } else {
+                    break;
+                }
+
+                read();
+
+                Expression a = e;
+
+                e = XreadBooleanTermOrNull();
+
+                if (e == null) {
+                    throw Error.error(ErrorCode.X_42568);
+                }
+
+                e = new ExpressionLogical(type, a, e);
+            }
+
+            if (e == null) {
+                throw Error.error(ErrorCode.X_42568);
+            }
+
+            return e;
+        } catch (HsqlException ex) {
+            ex.setLevel(compileContext.subqueryDepth);
+
+            if (lastError == null || lastError.getLevel() < ex.getLevel()) {
+                lastError = ex;
+            }
+
+            throw lastError;
+        }
+    }
+
+    Expression XreadBooleanTermOrNull() {
+
+        Expression e = XreadBooleanFactorOrNull();
+
+        if (e == null) {
+            return null;
+        }
+
+        int type;
+
+        while (true) {
+            if (token.tokenType == Tokens.AND) {
+                type = OpTypes.AND;
+            } else {
+                break;
+            }
+
+            read();
+
+            Expression a = e;
+
+            e = XreadBooleanFactorOrNull();
+
+            if (e == null) {
+                throw unexpectedToken();
+            }
+
+            e = new ExpressionLogical(type, a, e);
+        }
+
+        return e;
+    }
+
+    Expression XreadBooleanFactorOrNull() {
+
+        Expression e;
+        boolean    not     = false;
+        boolean    unknown = false;
+
+        if (token.tokenType == Tokens.NOT) {
+            read();
+
+            not = true;
+        }
+
+        e = XreadBooleanPrimaryOrNull();
+
+        if (e == null) {
+            return null;
+        }
+
+        if (token.tokenType == Tokens.IS) {
+            read();
+
+            if (token.tokenType == Tokens.NOT) {
+                read();
+
+                not = !not;
+            }
+
+            if (token.tokenType == Tokens.TRUE) {
+                read();
+            } else if (token.tokenType == Tokens.FALSE) {
+                not = !not;
+
+                read();
+            } else if (token.tokenType == Tokens.UNKNOWN) {
+                unknown = true;
+
+                read();
+            } else {
+                throw unexpectedToken();
+            }
+        }
+
+        if (unknown) {
+            e = new ExpressionLogical(OpTypes.IS_NULL, e);
+        }
+
+        if (not) {
+            e = new ExpressionLogical(OpTypes.NOT, e);
+        }
+
+        return e;
+    }
+
+    // <boolean primary> ::= <predicate> | <boolean predicand>
+    Expression XreadBooleanPrimaryOrNull() {
+
+        Expression e = null;
+        int        position;
+
+        switch (token.tokenType) {
+
+            case Tokens.EXISTS :
+            case Tokens.UNIQUE :
+                return XreadPredicate();
+
+            case Tokens.ROW :
+                read();
+                readThis(Tokens.OPENBRACKET);
+
+                e = XreadRowElementList(true);
+
+                readThis(Tokens.CLOSEBRACKET);
+                break;
+
+            default :
+                position = getPosition();
+
+                try {
+                    e = XreadAllTypesCommonValueExpression(false);
+                } catch (HsqlException ex) {
+                    ex.setLevel(compileContext.subqueryDepth);
+
+                    if (lastError == null
+                            || lastError.getLevel() < ex.getLevel()) {
+                        lastError = ex;
+                    }
+
+                    rewind(position);
+                }
+        }
+
+        if (e == null && token.tokenType == Tokens.OPENBRACKET) {
+            read();
+
+            position = getPosition();
+
+            try {
+                e = XreadRowElementList(true);
+
+                readThis(Tokens.CLOSEBRACKET);
+            } catch (HsqlException ex) {
+                ex.setLevel(compileContext.subqueryDepth);
+
+                if (lastError == null
+                        || lastError.getLevel() < ex.getLevel()) {
+                    lastError = ex;
+                }
+
+                rewind(position);
+
+                e = XreadBooleanValueExpression();
+
+                readThis(Tokens.CLOSEBRACKET);
+            }
+        }
+
+        if (e != null) {
+            e = XreadPredicateRightPart(e);
+        }
+
+        return e;
+    }
+
+    // similar to <value expression primary>
+    Expression XreadBooleanPredicand() {
+
+        Expression e;
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            read();
+
+            e = XreadBooleanValueExpression();
+
+            readThis(Tokens.CLOSEBRACKET);
+
+            return e;
+        } else {
+            e = XreadSimpleValueExpressionPrimary();
+
+            if (e != null) {
+                e = XreadArrayElementReference(e);
+            }
+
+            return e;
+        }
+    }
+
+    Expression XreadPredicate() {
+
+        switch (token.tokenType) {
+
+            case Tokens.EXISTS : {
+                read();
+
+                Expression s = XreadTableSubqueryForPredicate(OpTypes.EXISTS);
+
+                return new ExpressionLogical(OpTypes.EXISTS, s);
+            }
+            case Tokens.UNIQUE : {
+                read();
+
+                Expression s = XreadTableSubqueryForPredicate(OpTypes.UNIQUE);
+
+                return new ExpressionLogical(OpTypes.UNIQUE, s);
+            }
+            default : {
+                Expression a = XreadRowValuePredicand();
+
+                return XreadPredicateRightPart(a);
+            }
+        }
+    }
+
+    Expression XreadPredicateRightPart(final Expression l) {
+
+        boolean           hasNot = false;
+        ExpressionLogical e      = null;
+        Expression        r;
+
+        if (token.tokenType == Tokens.NOT) {
+            read();
+
+            hasNot = true;
+        }
+
+        switch (token.tokenType) {
+
+            case Tokens.IS : {
+                if (hasNot) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                if (token.tokenType == Tokens.NOT) {
+                    hasNot = true;
+
+                    read();
+                }
+
+                if (token.tokenType == Tokens.DISTINCT) {
+                    read();
+                    readThis(Tokens.FROM);
+
+                    r      = XreadRowValuePredicand();
+                    e      = new ExpressionLogical(OpTypes.NOT_DISTINCT, l, r);
+                    hasNot = !hasNot;
+
+                    break;
+                }
+
+                if (token.tokenType == Tokens.NULL
+                        || token.tokenType == Tokens.UNKNOWN) {
+                    read();
+
+                    e = new ExpressionLogical(OpTypes.IS_NULL, l);
+
+                    break;
+                }
+
+                throw unexpectedToken();
+            }
+            case Tokens.LIKE : {
+                e                = XreadLikePredicateRightPart(l);
+                e.noOptimisation = isCheckOrTriggerCondition;
+
+                break;
+            }
+            case Tokens.BETWEEN : {
+                e = XreadBetweenPredicateRightPart(l);
+
+                break;
+            }
+            case Tokens.IN : {
+                e                = XreadInPredicateRightPart(l);
+                e.noOptimisation = isCheckOrTriggerCondition;
+
+                break;
+            }
+            case Tokens.OVERLAPS : {
+                if (hasNot) {
+                    throw unexpectedToken();
+                }
+
+                e = XreadOverlapsPredicateRightPart(l);
+
+                break;
+            }
+            case Tokens.EQUALS :
+            case Tokens.GREATER_EQUALS :
+            case Tokens.GREATER :
+            case Tokens.LESS :
+            case Tokens.LESS_EQUALS :
+            case Tokens.NOT_EQUALS : {
+                if (hasNot) {
+                    throw unexpectedToken();
+                }
+
+                int type = getExpressionType(token.tokenType);
+
+                read();
+
+                switch (token.tokenType) {
+
+                    case Tokens.ANY :
+                    case Tokens.SOME :
+                    case Tokens.ALL :
+                        e = XreadQuantifiedComparisonRightPart(type, l);
+                        break;
+
+                    default : {
+                        Expression row = XreadRowValuePredicand();
+
+                        e = new ExpressionLogical(type, l, row);
+
+                        break;
+                    }
+                }
+
+                break;
+            }
+            case Tokens.MATCH : {
+                e = XreadMatchPredicateRightPart(l);
+
+                break;
+            }
+            default : {
+                if (hasNot) {
+                    throw unexpectedToken();
+                }
+
+                return l;
+            }
+        }
+
+        if (hasNot) {
+            e = new ExpressionLogical(OpTypes.NOT, e);
+        }
+
+        return e;
+    }
+
+    private ExpressionLogical XreadBetweenPredicateRightPart(
+            final Expression a) {
+
+        boolean symmetric = false;
+
+        read();
+
+        if (token.tokenType == Tokens.ASYMMETRIC) {
+            read();
+        } else if (token.tokenType == Tokens.SYMMETRIC) {
+            symmetric = true;
+
+            read();
+        }
+
+        Expression left = XreadRowValuePredicand();
+
+        readThis(Tokens.AND);
+
+        Expression right = XreadRowValuePredicand();
+
+        if (a.isUnresolvedParam() && left.isUnresolvedParam()) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        if (a.isUnresolvedParam() && right.isUnresolvedParam()) {
+            throw Error.error(ErrorCode.X_42567);
+        }
+
+        Expression l = new ExpressionLogical(OpTypes.GREATER_EQUAL, a, left);
+        Expression r = new ExpressionLogical(OpTypes.SMALLER_EQUAL, a, right);
+        ExpressionLogical leftToRight = new ExpressionLogical(OpTypes.AND, l,
+            r);
+
+        if (symmetric) {
+            l = new ExpressionLogical(OpTypes.SMALLER_EQUAL, a, left);
+            r = new ExpressionLogical(OpTypes.GREATER_EQUAL, a, right);
+
+            Expression rightToLeft = new ExpressionLogical(OpTypes.AND, l, r);
+
+            return new ExpressionLogical(OpTypes.OR, leftToRight, rightToLeft);
+        } else {
+            return leftToRight;
+        }
+    }
+
+    private ExpressionLogical XreadQuantifiedComparisonRightPart(int exprType,
+            Expression l) {
+
+        int        tokenT      = token.tokenType;
+        int        exprSubType = 0;
+        Expression e;
+
+        switch (token.tokenType) {
+
+            case Tokens.ANY :
+            case Tokens.SOME :
+                exprSubType = OpTypes.ANY_QUANTIFIED;
+                break;
+
+            case Tokens.ALL :
+                exprSubType = OpTypes.ALL_QUANTIFIED;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ParserDQL");
+        }
+
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        int position = getPosition();
+
+        readOpenBrackets();
+
+        switch (token.tokenType) {
+
+            case Tokens.TABLE :
+            case Tokens.VALUES :
+            case Tokens.SELECT :
+                rewind(position);
+
+                SubQuery sq = XreadSubqueryBody(false, OpTypes.IN);
+
+                e = new Expression(OpTypes.TABLE_SUBQUERY, sq);
+
+                readThis(Tokens.CLOSEBRACKET);
+                break;
+
+            default :
+                rewind(position);
+
+                e = readAggregateExpression(tokenT);
+
+                readThis(Tokens.CLOSEBRACKET);
+        }
+
+        ExpressionLogical r = new ExpressionLogical(exprType, l, e);
+
+        r.setSubType(exprSubType);
+
+        return r;
+    }
+
+    private ExpressionLogical XreadInPredicateRightPart(Expression l) {
+
+        int        degree = l.getDegree();
+        Expression e      = null;
+
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        int position = getPosition();
+        int brackets = readOpenBrackets();
+
+        switch (token.tokenType) {
+
+            case Tokens.UNNEST :
+                e = XreadCollectionDerivedTable();
+
+                e.getTable().getSubQuery().setUniqueRows();
+                readThis(Tokens.CLOSEBRACKET);
+                this.readCloseBrackets(brackets);
+                break;
+
+            case Tokens.TABLE :
+            case Tokens.VALUES :
+            case Tokens.SELECT : {
+                rewind(position);
+
+                SubQuery sq = XreadSubqueryBody(false, OpTypes.IN);
+
+                e = new Expression(OpTypes.TABLE_SUBQUERY, sq);
+
+                readThis(Tokens.CLOSEBRACKET);
+
+                break;
+            }
+            default : {
+                rewind(position);
+
+                e = XreadInValueListConstructor(degree);
+
+                readThis(Tokens.CLOSEBRACKET);
+
+                break;
+            }
+        }
+
+        ExpressionLogical r;
+
+        if (isCheckOrTriggerCondition) {
+            r = new ExpressionLogical(OpTypes.IN, l, e);
+        } else {
+            r = new ExpressionLogical(OpTypes.EQUAL, l, e);
+
+            r.setSubType(OpTypes.ANY_QUANTIFIED);
+        }
+
+        return r;
+    }
+
+    Expression XreadInValueList(int degree) {
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        while (true) {
+            Expression e = XreadValueExpression();
+
+            if (e.getType() != OpTypes.ROW) {
+                e = new Expression(OpTypes.ROW, new Expression[]{ e });
+            }
+
+            list.add(e);
+
+            if (token.tokenType == Tokens.COMMA) {
+                read();
+
+                continue;
+            }
+
+            break;
+        }
+
+        Expression[] array = new Expression[list.size()];
+
+        list.toArray(array);
+
+        Expression e = new Expression(OpTypes.TABLE, array);
+
+        for (int i = 0; i < array.length; i++) {
+            if (array[i].getType() != OpTypes.ROW) {
+                array[i] = new Expression(OpTypes.ROW,
+                                          new Expression[]{ array[i] });
+            }
+
+            Expression[] args = array[i].nodes;
+
+            if (args.length != degree) {
+
+                // SQL error message
+                throw unexpectedToken();
+            }
+
+            for (int j = 0; j < degree; j++) {
+                if (args[j].getType() == OpTypes.ROW) {
+
+                    // SQL error message
+                    throw unexpectedToken();
+                }
+            }
+        }
+
+        return e;
+    }
+
+    private ExpressionLogical XreadLikePredicateRightPart(Expression a) {
+
+        read();
+
+        Expression b      = XreadStringValueExpression();
+        Expression escape = null;
+
+        if (token.tokenString.equals(Tokens.T_ESCAPE)) {
+            read();
+
+            escape = XreadStringValueExpression();
+        }
+
+        return new ExpressionLike(a, b, escape,
+                                  this.isCheckOrTriggerCondition);
+    }
+
+    private ExpressionLogical XreadMatchPredicateRightPart(Expression a) {
+
+        boolean isUnique  = false;
+        int     matchType = OpTypes.MATCH_SIMPLE;
+
+        read();
+
+        if (token.tokenType == Tokens.UNIQUE) {
+            read();
+
+            isUnique = true;
+        }
+
+        if (token.tokenType == Tokens.SIMPLE) {
+            read();
+
+            matchType = isUnique ? OpTypes.MATCH_UNIQUE_SIMPLE
+                                 : OpTypes.MATCH_SIMPLE;
+        } else if (token.tokenType == Tokens.PARTIAL) {
+            read();
+
+            matchType = isUnique ? OpTypes.MATCH_UNIQUE_PARTIAL
+                                 : OpTypes.MATCH_PARTIAL;
+        } else if (token.tokenType == Tokens.FULL) {
+            read();
+
+            matchType = isUnique ? OpTypes.MATCH_UNIQUE_FULL
+                                 : OpTypes.MATCH_FULL;
+        }
+
+        int        mode = isUnique ? OpTypes.TABLE_SUBQUERY
+                                   : OpTypes.IN;
+        Expression s    = XreadTableSubqueryForPredicate(mode);
+
+        return new ExpressionLogical(matchType, a, s);
+    }
+
+    private ExpressionLogical XreadOverlapsPredicateRightPart(Expression l) {
+
+        if (l.getType() != OpTypes.ROW) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        if (l.nodes.length != 2) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        read();
+
+        if (token.tokenType != Tokens.OPENBRACKET) {
+            throw unexpectedToken();
+        }
+
+        Expression r = XreadRowValuePredicand();
+
+        if (r.nodes.length != 2) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        return new ExpressionLogical(OpTypes.OVERLAPS, l, r);
+    }
+
+    Expression XreadRowValueExpression() {
+
+        Expression e = XreadExplicitRowValueConstructorOrNull();
+
+        if (e != null) {
+            return e;
+        }
+
+        return XreadRowValueSpecialCase();
+    }
+
+    Expression XreadTableRowValueConstructor() {
+
+        Expression e = XreadExplicitRowValueConstructorOrNull();
+
+        if (e != null) {
+            return e;
+        }
+
+        return XreadRowValueSpecialCase();
+    }
+
+    //  union of <row value expression> |
+    // <boolean predicand> | <non parenthesized value expression primary> |
+    //  translated to <explicit row value constructor>
+    // <value expression primary> | <non parenthesized value expression primary> |
+    Expression XreadRowValuePredicand() {
+        return XreadRowOrCommonValueExpression();
+    }
+
+    Expression XreadRowValueSpecialCase() {
+
+        Expression e = XreadSimpleValueExpressionPrimary();
+
+        if (e != null) {
+            e = XreadArrayElementReference(e);
+        }
+
+        return e;
+    }
+
+    // <row value constructor>
+    // ISSUE - XreadCommonValueExpression and XreadBooleanValueExpression should merge
+    Expression XreadRowValueConstructor() {
+
+        Expression e;
+
+        e = XreadExplicitRowValueConstructorOrNull();
+
+        if (e != null) {
+            return e;
+        }
+
+        e = XreadRowOrCommonValueExpression();
+
+        if (e != null) {
+            return e;
+        }
+
+        return XreadBooleanValueExpression();
+    }
+
+    // returns null
+    // must be called in conjusnction with <parenthesized ..
+    Expression XreadExplicitRowValueConstructorOrNull() {
+
+        Expression e;
+
+        switch (token.tokenType) {
+
+            case Tokens.OPENBRACKET : {
+                read();
+
+                int position = getPosition();
+                int brackets = readOpenBrackets();
+
+                switch (token.tokenType) {
+
+                    case Tokens.TABLE :
+                    case Tokens.VALUES :
+                    case Tokens.SELECT :
+                        rewind(position);
+
+                        SubQuery sq = XreadSubqueryBody(false,
+                                                        OpTypes.ROW_SUBQUERY);
+
+                        readThis(Tokens.CLOSEBRACKET);
+
+                        return new Expression(OpTypes.ROW_SUBQUERY, sq);
+
+                    default :
+                        rewind(position);
+
+                        e = XreadRowElementList(true);
+
+                        readThis(Tokens.CLOSEBRACKET);
+
+                        return e;
+                }
+            }
+            case Tokens.ROW : {
+                read();
+                readThis(Tokens.OPENBRACKET);
+
+                e = XreadRowElementList(false);
+
+                readThis(Tokens.CLOSEBRACKET);
+
+                return e;
+            }
+        }
+
+        return null;
+    }
+
+    Expression XreadRowElementList(boolean multiple) {
+
+        Expression    e;
+        HsqlArrayList list = new HsqlArrayList();
+
+        while (true) {
+            e = XreadValueExpression();
+
+            list.add(e);
+
+            if (token.tokenType == Tokens.COMMA) {
+                read();
+
+                continue;
+            }
+
+            if (multiple && list.size() == 1) {
+                return e;
+            }
+
+            break;
+        }
+
+        Expression[] array = new Expression[list.size()];
+
+        list.toArray(array);
+
+        return new Expression(OpTypes.ROW, array);
+    }
+
+    Expression XreadCurrentCollationSpec() {
+        throw Error.error(ErrorCode.X_0A000);
+    }
+
+    Expression XreadRowSubquery() {
+
+        readThis(Tokens.OPENBRACKET);
+
+        SubQuery sq = XreadSubqueryBody(false, OpTypes.ROW_SUBQUERY);
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return new Expression(OpTypes.ROW_SUBQUERY, sq);
+    }
+
+    Expression XreadTableSubqueryForPredicate(int mode) {
+
+        readThis(Tokens.OPENBRACKET);
+
+        SubQuery sq = XreadSubqueryBody(false, mode);
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return new Expression(OpTypes.TABLE_SUBQUERY, sq);
+    }
+
+    Expression XreadTableSubqueryOrJoinedTable() {
+
+        boolean joinedTable = false;
+        int     position;
+
+        readThis(Tokens.OPENBRACKET);
+
+        position = getPosition();
+
+        readOpenBrackets();
+
+        switch (token.tokenType) {
+
+            case Tokens.TABLE :
+            case Tokens.VALUES :
+            case Tokens.SELECT :
+            case Tokens.WITH :
+                break;
+
+            default :
+                joinedTable = true;
+        }
+
+        rewind(position);
+
+        if (joinedTable) {
+            SubQuery sq = XreadJoinedTableAsSubquery();
+
+            readThis(Tokens.CLOSEBRACKET);
+
+            return new Expression(OpTypes.TABLE_SUBQUERY, sq);
+        } else {
+            SubQuery sq = XreadTableSubqueryBody(true);
+
+            readThis(Tokens.CLOSEBRACKET);
+
+            return new Expression(OpTypes.TABLE_SUBQUERY, sq);
+        }
+    }
+
+    SubQuery XreadJoinedTableAsSubquery() {
+
+        int position = getPosition();
+
+        compileContext.subqueryDepth++;
+
+        QueryExpression queryExpression = XreadJoinedTable();
+
+        queryExpression.resolve(session);
+
+        if (((QuerySpecification) queryExpression).rangeVariables.length < 2) {
+            throw unexpectedTokenRequire(Tokens.T_JOIN);
+        }
+
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth,
+                                   queryExpression, OpTypes.TABLE_SUBQUERY);
+
+        sq.sql = getLastPart(position);
+
+        sq.prepareTable(session);
+
+        compileContext.subqueryDepth--;
+
+        return sq;
+    }
+
+    QueryExpression XreadJoinedTable() {
+
+        QuerySpecification select = new QuerySpecification(compileContext);
+        Expression         e      = new ExpressionColumn(OpTypes.MULTICOLUMN);
+
+        select.addSelectColumnExpression(e);
+        XreadTableReference(select);
+
+        return select;
+    }
+
+    SubQuery XreadTableNamedSubqueryBody(HsqlName name,
+                                         HsqlName[] columnNames) {
+
+        SubQuery sq = XreadSubqueryBody(true, OpTypes.TABLE_SUBQUERY);
+
+        sq.prepareTable(session, name, columnNames);
+
+        return sq;
+    }
+
+    SubQuery XreadTableSubqueryBody(boolean resolve) {
+
+        SubQuery sq = XreadSubqueryBody(resolve, OpTypes.TABLE_SUBQUERY);
+
+        if (resolve) {
+            sq.prepareTable(session);
+        }
+
+        return sq;
+    }
+
+    SubQuery XreadSubqueryBody(boolean resolve, int mode) {
+
+        int position = getPosition();
+
+        compileContext.subqueryDepth++;
+
+        QueryExpression queryExpression = XreadQueryExpression();
+
+        if (resolve) {
+            queryExpression.resolve(session);
+        } else {
+            queryExpression.resolveReferences(session);
+        }
+
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth,
+                                   queryExpression, mode);
+
+        sq.sql = getLastPart(position);
+
+        compileContext.subqueryDepth--;
+
+        return sq;
+    }
+
+    SubQuery XreadViewSubquery(View view) {
+
+        compileContext.subqueryDepth++;
+
+        QueryExpression queryExpression;
+
+        try {
+            queryExpression = XreadQueryExpression();
+        } catch (HsqlException e) {
+            queryExpression = XreadJoinedTable();
+        }
+
+        queryExpression.setView(view);
+        queryExpression.resolve(session);
+
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth,
+                                   queryExpression, view);
+
+        compileContext.subqueryDepth--;
+
+        return sq;
+    }
+
+    Expression XreadContextuallyTypedTable(int degree) {
+
+        Expression   e       = readRow();
+        Expression[] list    = e.nodes;
+        boolean      isTable = false;
+
+        if (degree == 1) {
+            if (e.getType() == OpTypes.ROW) {
+                e.opType = OpTypes.TABLE;
+
+                for (int i = 0; i < list.length; i++) {
+                    if (list[i].getType() != OpTypes.ROW) {
+                        list[i] = new Expression(OpTypes.ROW,
+                                                 new Expression[]{ list[i] });
+                    } else if (list[i].nodes.length != degree) {
+                        throw Error.error(ErrorCode.X_42564);
+                    }
+                }
+
+                return e;
+            } else {
+                e = new Expression(OpTypes.ROW, new Expression[]{ e });
+                e = new Expression(OpTypes.TABLE, new Expression[]{ e });
+
+                return e;
+            }
+        }
+
+        if (e.getType() != OpTypes.ROW) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        for (int i = 0; i < list.length; i++) {
+            if (list[i].getType() == OpTypes.ROW) {
+                isTable = true;
+
+                break;
+            }
+        }
+
+        if (isTable) {
+            e.opType = OpTypes.TABLE;
+
+            for (int i = 0; i < list.length; i++) {
+                if (list[i].getType() != OpTypes.ROW) {
+                    throw Error.error(ErrorCode.X_42564);
+                }
+
+                Expression[] args = list[i].nodes;
+
+                if (args.length != degree) {
+                    throw Error.error(ErrorCode.X_42564);
+                }
+
+                for (int j = 0; j < degree; j++) {
+                    if (args[j].getType() == OpTypes.ROW) {
+                        throw Error.error(ErrorCode.X_42564);
+                    }
+                }
+            }
+        } else {
+            if (list.length != degree) {
+                throw Error.error(ErrorCode.X_42564);
+            }
+
+            e = new Expression(OpTypes.TABLE, new Expression[]{ e });
+        }
+
+        return e;
+    }
+
+    private Expression XreadInValueListConstructor(int degree) {
+
+        int position = getPosition();
+
+        compileContext.subqueryDepth++;
+
+        Expression e = XreadInValueList(degree);
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth, e,
+                                   OpTypes.IN);
+
+        sq.sql = getLastPart(position);
+
+        compileContext.subqueryDepth--;
+
+        return e;
+    }
+
+    private SubQuery XreadRowValueExpressionList() {
+
+        compileContext.subqueryDepth++;
+
+        Expression e = XreadRowValueExpressionListBody();
+        HsqlList unresolved =
+            e.resolveColumnReferences(RangeVariable.emptyArray, null);
+
+        ExpressionColumn.checkColumnsResolved(unresolved);
+        e.resolveTypes(session, null);
+        e.prepareTable(session, null, e.nodes[0].nodes.length);
+
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth, e,
+                                   OpTypes.TABLE);
+
+        sq.prepareTable(session);
+
+        compileContext.subqueryDepth--;
+
+        return sq;
+    }
+
+    Expression XreadRowValueExpressionListBody() {
+
+        Expression r = null;
+
+        while (true) {
+            int        brackets = readOpenBrackets();
+            Expression e        = readRow();
+
+            readCloseBrackets(brackets);
+
+            if (r == null) {
+                r = new Expression(OpTypes.ROW, new Expression[]{ e });
+            } else {
+                r.nodes = (Expression[]) ArrayUtil.resizeArray(r.nodes,
+                        r.nodes.length + 1);
+                r.nodes[r.nodes.length - 1] = e;
+            }
+
+            if (token.tokenType != Tokens.COMMA) {
+                break;
+            }
+
+            read();
+        }
+
+        Expression[] list   = r.nodes;
+        int          degree = 1;
+
+        if (list[0].getType() == OpTypes.ROW) {
+            degree = list[0].nodes.length;
+        }
+
+        r.opType = OpTypes.TABLE;
+
+        for (int i = 0; i < list.length; i++) {
+            if (list[i].getType() == OpTypes.ROW) {
+                if (list[i].nodes.length != degree) {
+                    throw Error.error(ErrorCode.X_42564);
+                }
+            } else {
+                if (degree != 1) {
+                    throw Error.error(ErrorCode.X_42564);
+                }
+
+                list[i] = new Expression(OpTypes.ROW,
+                                         new Expression[]{ list[i] });
+            }
+        }
+
+        return r;
+    }
+
+    Expression XreadTargetSpecification(RangeVariable[] rangeVars,
+                                        LongDeque colIndexList) {
+
+        ColumnSchema column = null;
+        int          index  = -1;
+
+        checkIsIdentifier();
+
+        if (token.namePrePrePrefix != null) {
+            checkValidCatalogName(token.namePrePrePrefix);
+        }
+
+        for (int i = 0; i < rangeVars.length; i++) {
+            if (rangeVars[i] == null) {
+                continue;
+            }
+
+            index = rangeVars[i].findColumn(token.tokenString);
+
+            if (index > -1 && rangeVars[i].resolvesTableName(token.namePrefix)
+                    && rangeVars[i].resolvesSchemaName(token.namePrePrefix)) {
+                column = rangeVars[i].getColumn(index);
+
+                read();
+
+                break;
+            }
+        }
+
+        if (column == null) {
+            throw Error.error(ErrorCode.X_42501, token.tokenString);
+        }
+
+        colIndexList.add(index);
+
+        if (token.tokenType == Tokens.LEFTBRACKET) {
+            if (!column.getDataType().isArrayType()) {
+                throw unexpectedToken();
+            }
+
+            read();
+
+            Expression e = XreadNumericValueExpression();
+
+            if (e == null) {
+                throw Error.error(ErrorCode.X_42501, token.tokenString);
+            }
+
+            e = new ExpressionAccessor(column.getAccessor(), e);
+
+            readThis(Tokens.RIGHTBRACKET);
+
+            return e;
+        }
+
+        return column.getAccessor();
+    }
+
+    Expression XreadCollectionDerivedTable() {
+
+        boolean ordinality = false;
+        int     position   = getPosition();
+
+        readThis(Tokens.UNNEST);
+        readThis(Tokens.OPENBRACKET);
+
+        compileContext.subqueryDepth++;
+
+        Expression e = XreadValueExpression();
+
+        compileContext.subqueryDepth--;
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        if (token.tokenType == Tokens.WITH) {
+            read();
+            readThis(Tokens.ORDINALITY);
+
+            ordinality = true;
+        }
+
+        e = new ExpressionTable(e, null, ordinality);
+
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth, e,
+                                   OpTypes.TABLE_SUBQUERY);
+
+        sq.createTable();
+
+        sq.sql = getLastPart(position);
+
+        return e;
+    }
+
+    Expression XreadTableFunctionDerivedTable() {
+
+        int position = getPosition();
+
+        readThis(Tokens.TABLE);
+        readThis(Tokens.OPENBRACKET);
+
+        compileContext.subqueryDepth++;
+
+        Expression e = this.XreadValueExpression();
+
+        if (e.getType() != OpTypes.FUNCTION) {
+            throw this.unexpectedToken(Tokens.T_TABLE);
+        }
+
+        compileContext.subqueryDepth--;
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        e = new ExpressionTable(e, null, false);
+
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth, e,
+                                   OpTypes.TABLE_SUBQUERY);
+
+        sq.createTable();
+
+        sq.sql = getLastPart(position);
+
+        return e;
+    }
+
+    Expression XreadLateralDerivedTable() {
+
+        readThis(Tokens.LATERAL);
+        readThis(Tokens.OPENBRACKET);
+
+        int position = getPosition();
+
+        compileContext.subqueryDepth++;
+
+        QueryExpression queryExpression = XreadQueryExpression();
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth,
+                                   queryExpression, OpTypes.TABLE_SUBQUERY);
+
+        sq.createTable();
+
+        sq.sql = getLastPart(position);
+
+        compileContext.subqueryDepth--;
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return new Expression(OpTypes.TABLE_SUBQUERY, sq);
+    }
+
+    Expression XreadArrayConstructor() {
+
+        readThis(Tokens.OPENBRACKET);
+
+        int position = getPosition();
+
+        compileContext.subqueryDepth++;
+
+        QueryExpression queryExpression = XreadQueryExpression();
+
+        queryExpression.resolveReferences(session);
+
+        SubQuery sq = new SubQuery(database, compileContext.subqueryDepth,
+                                   queryExpression, OpTypes.TABLE_SUBQUERY);
+
+        sq.sql = getLastPart(position);
+
+        compileContext.subqueryDepth--;
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return new Expression(OpTypes.ARRAY_SUBQUERY, sq);
+    }
+
+    // Additional Common Elements
+    SchemaObject readCollateClauseOrNull() {
+
+        if (token.tokenType == Tokens.COLLATE) {
+            read();
+
+            SchemaObject collation =
+                database.schemaManager.getSchemaObject(token.namePrefix,
+                    token.tokenString, SchemaObject.COLLATION);
+
+            return collation;
+        }
+
+        return null;
+    }
+
+    Expression XreadArrayElementReference(Expression e) {
+
+        if (token.tokenType == Tokens.LEFTBRACKET) {
+            read();
+
+            Expression e1 = XreadNumericValueExpression();
+
+            readThis(Tokens.RIGHTBRACKET);
+
+            e = new ExpressionAccessor(e, e1);
+        }
+
+        return e;
+    }
+
+    Expression readRow() {
+
+        Expression r = null;
+
+        while (true) {
+            Expression e = XreadValueExpressionWithContext();
+
+            if (r == null) {
+                r = e;
+            } else if (r.getType() == OpTypes.ROW) {
+                if (e.getType() == OpTypes.ROW
+                        && r.nodes[0].getType() != OpTypes.ROW) {
+                    r = new Expression(OpTypes.ROW, new Expression[] {
+                        r, e
+                    });
+                } else {
+                    r.nodes = (Expression[]) ArrayUtil.resizeArray(r.nodes,
+                            r.nodes.length + 1);
+                    r.nodes[r.nodes.length - 1] = e;
+                }
+            } else {
+                r = new Expression(OpTypes.ROW, new Expression[] {
+                    r, e
+                });
+            }
+
+            if (token.tokenType != Tokens.COMMA) {
+                break;
+            }
+
+            read();
+        }
+
+        return r;
+    }
+
+    Expression readCaseExpression() {
+
+        Expression predicand = null;
+
+        read();
+
+        if (token.tokenType != Tokens.WHEN) {
+            predicand = XreadRowValuePredicand();
+        }
+
+        return readCaseWhen(predicand);
+    }
+
+    /**
+     * Reads part of a CASE .. WHEN  expression
+     */
+    private Expression readCaseWhen(final Expression l) {
+
+        readThis(Tokens.WHEN);
+
+        Expression condition = null;
+
+        if (l == null) {
+            condition = XreadBooleanValueExpression();
+        } else {
+            while (true) {
+                Expression newCondition = XreadPredicateRightPart(l);
+
+                if (l == newCondition) {
+                    newCondition =
+                        new ExpressionLogical(l, XreadRowValuePredicand());
+                }
+
+                if (condition == null) {
+                    condition = newCondition;
+                } else {
+                    condition = new ExpressionLogical(OpTypes.OR, condition,
+                                                      newCondition);
+                }
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+                } else {
+                    break;
+                }
+            }
+        }
+
+        readThis(Tokens.THEN);
+
+        Expression current  = XreadValueExpression();
+        Expression elseExpr = null;
+
+        if (token.tokenType == Tokens.WHEN) {
+            elseExpr = readCaseWhen(l);
+        } else if (token.tokenType == Tokens.ELSE) {
+            read();
+
+            elseExpr = XreadValueExpression();
+
+            readThis(Tokens.END);
+            readIfThis(Tokens.CASE);
+        } else {
+            elseExpr = new ExpressionValue((Object) null, Type.SQL_ALL_TYPES);
+
+            readThis(Tokens.END);
+            readIfThis(Tokens.CASE);
+        }
+
+        Expression alternatives = new ExpressionOp(OpTypes.ALTERNATIVE,
+            current, elseExpr);
+        Expression casewhen = new ExpressionOp(OpTypes.CASEWHEN, condition,
+                                               alternatives);
+
+        return casewhen;
+    }
+
+    /**
+     * reads a CASEWHEN expression
+     */
+    private Expression readCaseWhenExpression() {
+
+        Expression l = null;
+
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        l = XreadBooleanValueExpression();
+
+        readThis(Tokens.COMMA);
+
+        Expression thenelse = XreadRowValueExpression();
+
+        readThis(Tokens.COMMA);
+
+        thenelse = new ExpressionOp(OpTypes.ALTERNATIVE, thenelse,
+                                    XreadValueExpression());
+        l = new ExpressionOp(OpTypes.CASEWHEN, l, thenelse);
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return l;
+    }
+
+    /**
+     * Reads a CAST or CONVERT expression
+     */
+    private Expression readCastExpression() {
+
+        boolean isConvert = token.tokenType == Tokens.CONVERT;
+
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        Expression l = this.XreadValueExpressionOrNull();
+
+        if (isConvert) {
+            readThis(Tokens.COMMA);
+        } else {
+            readThis(Tokens.AS);
+        }
+
+        Type typeObject = readTypeDefinition(true);
+
+        if (l.isUnresolvedParam()) {
+            l.setDataType(session, typeObject);
+        } else {
+            l = new ExpressionOp(l, typeObject);
+        }
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return l;
+    }
+
+    /**
+     * reads a Column or Function expression
+     */
+    private Expression readColumnOrFunctionExpression() {
+
+        String  name           = token.tokenString;
+        boolean isSimpleQuoted = isDelimitedSimpleName();
+        String  prefix         = token.namePrefix;
+        String  prePrefix      = token.namePrePrefix;
+        String  prePrePrefix   = token.namePrePrePrefix;
+        Token   recordedToken  = getRecordedToken();
+
+        checkIsIdentifier();
+
+        if (isUndelimitedSimpleName()) {
+            FunctionSQL function =
+                FunctionCustom.newCustomFunction(token.tokenString,
+                                                 token.tokenType);
+
+            if (function != null) {
+                int pos = getPosition();
+
+                try {
+                    Expression e = readSQLFunction(function);
+
+                    if (e != null) {
+                        return e;
+                    }
+                } catch (HsqlException ex) {
+                    ex.setLevel(compileContext.subqueryDepth);
+
+                    if (lastError == null
+                            || lastError.getLevel() < ex.getLevel()) {
+                        lastError = ex;
+                    }
+
+                    rewind(pos);
+                }
+            } else if (isReservedKey()) {
+                function = FunctionSQL.newSQLFunction(name, compileContext);
+
+                if (function != null) {
+                    Expression e = readSQLFunction(function);
+
+                    if (e != null) {
+                        return e;
+                    }
+                }
+            }
+        }
+
+        read();
+
+        if (token.tokenType != Tokens.OPENBRACKET) {
+            checkValidCatalogName(prePrePrefix);
+
+            Expression column = new ExpressionColumn(prePrefix, prefix, name,
+                database.sqlEnforceRefs);
+
+            return column;
+        }
+
+        if (prePrePrefix != null) {
+            throw Error.error(ErrorCode.X_42551, prePrePrefix);
+        }
+
+        checkValidCatalogName(prePrefix);
+
+        prefix = session.getSchemaName(prefix);
+
+        RoutineSchema routineSchema =
+            (RoutineSchema) database.schemaManager.findSchemaObject(name,
+                prefix, SchemaObject.FUNCTION);
+
+        if (routineSchema == null && isSimpleQuoted) {
+            HsqlName schema =
+                database.schemaManager.getDefaultSchemaHsqlName();
+
+            routineSchema =
+                (RoutineSchema) database.schemaManager.findSchemaObject(name,
+                    schema.name, SchemaObject.FUNCTION);
+
+            if (routineSchema == null) {
+                Routine.createRoutines(session, schema, name);
+
+                routineSchema =
+                    (RoutineSchema) database.schemaManager.findSchemaObject(
+                        name, schema.name, SchemaObject.FUNCTION);
+            }
+        }
+
+        if (routineSchema == null) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        readThis(Tokens.OPENBRACKET);
+
+        if (token.tokenType == Tokens.CLOSEBRACKET) {
+            read();
+        } else {
+            while (true) {
+                Expression e = XreadValueExpression();
+
+                list.add(e);
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+                } else {
+                    readThis(Tokens.CLOSEBRACKET);
+
+                    break;
+                }
+            }
+        }
+
+        FunctionSQLInvoked function  = new FunctionSQLInvoked(routineSchema);
+        Expression[]       arguments = new Expression[list.size()];
+
+        list.toArray(arguments);
+        function.setArguments(arguments);
+        compileContext.addFunctionCall(function);
+        recordedToken.setExpression(routineSchema);
+
+        return function;
+    }
+
+    Expression readCollection(int type) {
+
+        read();
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            return XreadArrayConstructor();
+        } else {
+            readThis(Tokens.LEFTBRACKET);
+
+            HsqlArrayList list = new HsqlArrayList();
+
+            for (int i = 0; ; i++) {
+                if (token.tokenType == Tokens.RIGHTBRACKET) {
+                    read();
+
+                    break;
+                }
+
+                if (i > 0) {
+                    readThis(Tokens.COMMA);
+                }
+
+                Expression e = XreadValueExpressionOrNull();
+
+                list.add(e);
+            }
+
+            Expression[] array = new Expression[list.size()];
+
+            list.toArray(array);
+
+            return new Expression(OpTypes.ARRAY, array);
+        }
+    }
+
+    private Expression readDecodeExpression() {
+
+        // turn into a CASEWHEN
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        Expression casewhen    = null;
+        Expression alternative = null;
+        Expression main        = XreadValueExpression();
+
+        readThis(Tokens.COMMA);
+
+        do {
+            Expression v = XreadValueExpression();
+
+            if (token.tokenType == Tokens.COMMA) {
+                readThis(Tokens.COMMA);
+            } else {
+                alternative.setRightNode(v);
+
+                break;
+            }
+
+            Expression l = new ExpressionLogical(main, v);
+            Expression r = XreadValueExpression();
+            Expression a = new ExpressionOp(OpTypes.ALTERNATIVE, r, null);
+            Expression c = new ExpressionOp(OpTypes.CASEWHEN, l, a);
+
+            if (casewhen == null) {
+                casewhen = c;
+            } else {
+                alternative.setRightNode(c);
+            }
+
+            alternative = a;
+
+            if (token.tokenType == Tokens.COMMA) {
+                readThis(Tokens.COMMA);
+            } else {
+                alternative.setRightNode(new ExpressionValue(null, null));;
+
+                break;
+            }
+        } while (true);
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return casewhen;
+    }
+
+    private Expression readLeastExpression() {
+
+        // turn into a CASEWHEN
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        Expression casewhen = null;
+
+        do {
+            casewhen = readValue(casewhen, OpTypes.SMALLER);
+
+            if (token.tokenType == Tokens.COMMA) {
+                readThis(Tokens.COMMA);
+            } else {
+                break;
+            }
+        } while (true);
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return casewhen;
+    }
+
+    private Expression readGreatestExpression() {
+
+        // turn into a CASEWHEN
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        Expression casewhen = null;
+
+        do {
+            casewhen = readValue(casewhen, OpTypes.GREATER);
+
+            if (token.tokenType == Tokens.COMMA) {
+                readThis(Tokens.COMMA);
+            } else {
+                break;
+            }
+        } while (true);
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return casewhen;
+    }
+
+    private Expression readValue(Expression e, int opType) {
+
+        Expression r = XreadValueExpression();
+
+        if (e == null) {
+            return r;
+        }
+
+        Expression l = new ExpressionLogical(opType, e, r);
+        Expression a = new ExpressionOp(OpTypes.ALTERNATIVE, e, r);
+
+        return new ExpressionOp(OpTypes.CASEWHEN, l, a);
+    }
+
+    /**
+     * Reads a NULLIF expression
+     */
+    private Expression readNullIfExpression() {
+
+        // turn into a CASEWHEN
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        Expression c = XreadValueExpression();
+
+        readThis(Tokens.COMMA);
+
+        Expression thenelse =
+            new ExpressionOp(OpTypes.ALTERNATIVE,
+                             new ExpressionValue((Object) null, (Type) null),
+                             c);
+
+        c = new ExpressionLogical(c, XreadValueExpression());
+        c = new ExpressionOp(OpTypes.CASEWHEN, c, thenelse);
+
+        readThis(Tokens.CLOSEBRACKET);
+
+        return c;
+    }
+
+    /**
+     * Reads a COALESE or IFNULL expression
+     */
+    private Expression readCoalesceExpression() {
+
+        Expression c = null;
+
+        // turn into a CASEWHEN
+        read();
+        readThis(Tokens.OPENBRACKET);
+
+        Expression leaf = null;
+
+        while (true) {
+            Expression current = XreadValueExpression();
+
+            if (leaf != null && token.tokenType == Tokens.CLOSEBRACKET) {
+                readThis(Tokens.CLOSEBRACKET);
+                leaf.setLeftNode(current);
+
+                break;
+            }
+
+            Expression condition = new ExpressionLogical(OpTypes.IS_NULL,
+                current);
+            Expression alternatives = new ExpressionOp(OpTypes.ALTERNATIVE,
+                new ExpressionValue((Object) null, (Type) null), current);
+            Expression casewhen = new ExpressionOp(OpTypes.CASEWHEN,
+                                                   condition, alternatives);
+
+            if (c == null) {
+                c = casewhen;
+            } else {
+                leaf.setLeftNode(casewhen);
+            }
+
+            leaf = alternatives;
+
+            readThis(Tokens.COMMA);
+        }
+
+        return c;
+    }
+
+    Expression readSQLFunction(FunctionSQL function) {
+
+        int position = getPosition();
+
+        read();
+
+        short[] parseList = function.parseList;
+
+        if (parseList.length == 0) {
+            return function;
+        }
+
+        HsqlArrayList exprList      = new HsqlArrayList();
+        boolean       isOpenBracket = token.tokenType == Tokens.OPENBRACKET;
+
+        try {
+            readExpression(exprList, parseList, 0, parseList.length, false);
+        } catch (HsqlException e) {
+            if (!isOpenBracket) {
+                rewind(position);
+
+                return null;
+            }
+
+            if (function.parseListAlt == null) {
+                throw e;
+            }
+
+            rewind(position);
+            read();
+
+            parseList = function.parseListAlt;
+            exprList  = new HsqlArrayList();
+
+            readExpression(exprList, parseList, 0, parseList.length, false);
+        }
+
+        Expression[] expr = new Expression[exprList.size()];
+
+        exprList.toArray(expr);
+        function.setArguments(expr);
+
+        return function.getFunctionExpression();
+    }
+
+    void readExpression(HsqlArrayList exprList, short[] parseList, int start,
+                        int count, boolean isOption) {
+
+        for (int i = start; i < start + count; i++) {
+            int exprType = parseList[i];
+
+            switch (exprType) {
+
+                case Tokens.QUESTION : {
+                    Expression e = null;
+
+                    e = XreadAllTypesCommonValueExpression(false);
+
+                    exprList.add(e);
+
+                    continue;
+                }
+                case Tokens.X_POS_INTEGER : {
+                    Expression e     = null;
+                    Integer    value = readIntegerObject();
+
+                    if (value.intValue() < 0) {
+                        throw Error.error(ErrorCode.X_42592);
+                    }
+
+                    e = new ExpressionValue(value, Type.SQL_INTEGER);
+
+                    exprList.add(e);
+
+                    continue;
+                }
+                case Tokens.X_OPTION : {
+                    i++;
+
+                    int expressionCount  = exprList.size();
+                    int position         = getPosition();
+                    int elementCount     = parseList[i++];
+                    int initialExprIndex = exprList.size();
+
+                    try {
+                        readExpression(exprList, parseList, i, elementCount,
+                                       true);
+                    } catch (HsqlException ex) {
+                        ex.setLevel(compileContext.subqueryDepth);
+
+                        if (lastError == null
+                                || lastError.getLevel() < ex.getLevel()) {
+                            lastError = ex;
+                        }
+
+                        rewind(position);
+                        exprList.setSize(expressionCount);
+
+                        for (int j = i; j < i + elementCount; j++) {
+                            if (parseList[j] == Tokens.QUESTION
+                                    || parseList[j] == Tokens.X_KEYSET
+                                    || parseList[j] == Tokens.X_POS_INTEGER) {
+                                exprList.add(null);
+                            }
+                        }
+
+                        i += elementCount - 1;
+
+                        continue;
+                    }
+
+                    if (initialExprIndex == exprList.size()) {
+                        exprList.add(null);
+                    }
+
+                    i += elementCount - 1;
+
+                    continue;
+                }
+                case Tokens.X_REPEAT : {
+                    i++;
+
+                    int elementCount = parseList[i++];
+                    int parseIndex   = i;
+
+                    while (true) {
+                        int initialExprIndex = exprList.size();
+
+                        readExpression(exprList, parseList, parseIndex,
+                                       elementCount, true);
+
+                        if (exprList.size() == initialExprIndex) {
+                            break;
+                        }
+                    }
+
+                    i += elementCount - 1;
+
+                    continue;
+                }
+                case Tokens.X_KEYSET : {
+                    int        elementCount = parseList[++i];
+                    Expression e            = null;
+
+                    if (ArrayUtil.find(parseList, token.tokenType, i
+                                       + 1, elementCount) == -1) {
+                        if (!isOption) {
+                            throw unexpectedToken();
+                        }
+                    } else {
+                        e = new ExpressionValue(
+                            ValuePool.getInt(token.tokenType),
+                            Type.SQL_INTEGER);
+
+                        read();
+                    }
+
+                    exprList.add(e);
+
+                    i += elementCount;
+
+                    continue;
+                }
+                case Tokens.OPENBRACKET :
+                case Tokens.CLOSEBRACKET :
+                case Tokens.COMMA :
+                default :
+                    if (token.tokenType != exprType) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    continue;
+            }
+        }
+    }
+
+    private Expression readSequenceExpression() {
+
+        read();
+        readThis(Tokens.VALUE);
+        readThis(Tokens.FOR);
+        checkIsSchemaObjectName();
+
+        String schema = session.getSchemaName(token.namePrefix);
+        NumberSequence sequence =
+            database.schemaManager.getSequence(token.tokenString, schema,
+                                               true);
+        Token recordedToken = getRecordedToken();
+
+        read();
+
+        Expression e = new ExpressionColumn(sequence);
+
+        recordedToken.setExpression(sequence);
+        compileContext.addSequence(sequence);
+
+        return e;
+    }
+
+    HsqlName readNewSchemaName() {
+
+        checkIsSchemaObjectName();
+        checkValidCatalogName(token.namePrefix);
+        SqlInvariants.checkSchemaNameNotSystem(token.tokenString);
+
+        HsqlName name = database.nameManager.newHsqlName(token.tokenString,
+            isDelimitedIdentifier(), SchemaObject.SCHEMA);
+
+        read();
+
+        return name;
+    }
+
+    HsqlName readNewSchemaObjectName(int type, boolean checkSchema) {
+
+        checkIsSchemaObjectName();
+
+        HsqlName hsqlName = database.nameManager.newHsqlName(token.tokenString,
+            isDelimitedIdentifier(), type);
+
+        if (token.namePrefix != null) {
+            switch (type) {
+
+                case SchemaObject.LABEL :
+                case SchemaObject.VARIABLE :
+                case SchemaObject.GRANTEE :
+                case SchemaObject.CATALOG :
+                    throw unexpectedToken();
+                case SchemaObject.CURSOR : {
+                    if (token.namePrePrefix == null
+                            && Tokens.T_MODULE.equals(token.namePrefix)
+                            && !token.isDelimitedPrefix) {}
+                    else {
+                        throw unexpectedTokenRequire(Tokens.T_MODULE);
+                    }
+
+                    break;
+                }
+                case SchemaObject.SCHEMA : {
+                    checkValidCatalogName(token.namePrefix);
+
+                    if (token.namePrePrefix != null) {
+                        throw tooManyIdentifiers();
+                    }
+
+                    break;
+                }
+                case SchemaObject.SERVER :
+                case SchemaObject.WRAPPER : {
+                    checkValidCatalogName(token.namePrefix);
+
+                    if (token.namePrePrefix != null) {
+                        throw tooManyIdentifiers();
+                    }
+
+                    break;
+                }
+                case SchemaObject.COLUMN : {
+                    if (token.namePrefix != null) {
+                        throw tooManyIdentifiers();
+                    }
+
+                    break;
+                }
+                default : {
+                    checkValidCatalogName(token.namePrePrefix);
+
+                    HsqlName schemaName;
+
+                    if (checkSchema) {
+                        schemaName =
+                            session.getSchemaHsqlName(token.namePrefix);
+                    } else {
+                        schemaName =
+                            session.database.schemaManager.findSchemaHsqlName(
+                                token.namePrefix);
+
+                        if (schemaName == null) {
+                            schemaName = database.nameManager.newHsqlName(
+                                token.namePrefix, isDelimitedIdentifier(),
+                                SchemaObject.SCHEMA);
+                        }
+                    }
+
+                    hsqlName.setSchemaIfNull(schemaName);
+
+                    break;
+                }
+            }
+        }
+
+        read();
+
+        return hsqlName;
+    }
+
+    HsqlName readNewDependentSchemaObjectName(HsqlName parentName, int type) {
+
+        HsqlName name = readNewSchemaObjectName(type, true);
+
+        name.parent = parentName;
+
+        name.setSchemaIfNull(parentName.schema);
+
+        if (name.schema != null && parentName.schema != null
+                && name.schema != parentName.schema) {
+            throw Error.error(ErrorCode.X_42505, token.namePrefix);
+        }
+
+        return name;
+    }
+
+    HsqlName readSchemaName() {
+
+        checkIsSchemaObjectName();
+        checkValidCatalogName(token.namePrefix);
+
+        HsqlName schema = session.getSchemaHsqlName(token.tokenString);
+
+        read();
+
+        return schema;
+    }
+
+    SchemaObject readSchemaObjectName(int type) {
+
+        checkIsSchemaObjectName();
+        checkValidCatalogName(token.namePrePrefix);
+
+        SchemaObject object =
+            database.schemaManager.getSchemaObject(token.tokenString,
+                token.namePrefix, type);
+
+        read();
+
+        return object;
+    }
+
+    SchemaObject readSchemaObjectName(HsqlName schemaName, int type) {
+
+        checkIsSchemaObjectName();
+
+        SchemaObject object =
+            database.schemaManager.getSchemaObject(token.tokenString,
+                schemaName.name, type);
+
+        if (token.namePrefix != null) {
+            if (!token.namePrefix.equals(schemaName.name)) {
+
+                // todo - better error message
+                throw Error.error(ErrorCode.X_42505, token.namePrefix);
+            }
+
+            if (token.namePrePrefix != null) {
+                if (!token.namePrePrefix.equals(
+                        database.getCatalogName().name)) {
+
+                    // todo - better error message
+                    throw Error.error(ErrorCode.X_42505, token.namePrefix);
+                }
+            }
+        }
+
+        read();
+
+        return object;
+    }
+
+    Table readTableName() {
+
+        checkIsIdentifier();
+
+        if (token.namePrePrefix != null) {
+            checkValidCatalogName(token.namePrePrefix);
+        }
+
+        Table table = database.schemaManager.getTable(session,
+            token.tokenString, token.namePrefix);
+
+        getRecordedToken().setExpression(table);
+        read();
+
+        return table;
+    }
+
+    ColumnSchema readSimpleColumnName(RangeVariable rangeVar) {
+
+        ColumnSchema column = null;
+
+        checkIsIdentifier();
+
+        if (token.namePrefix != null) {
+            throw tooManyIdentifiers();
+        }
+
+        int index = rangeVar.findColumn(token.tokenString);
+
+        if (index > -1 && rangeVar.resolvesTableName(token.namePrefix)
+                && rangeVar.resolvesSchemaName(token.namePrePrefix)) {
+            column = rangeVar.getTable().getColumn(index);
+
+            read();
+
+            return column;
+        }
+
+        throw Error.error(ErrorCode.X_42501, token.tokenString);
+    }
+
+    ColumnSchema readSimpleColumnName(Table table) {
+
+        checkIsIdentifier();
+
+        if (token.namePrefix != null) {
+            throw tooManyIdentifiers();
+        }
+
+        int index = table.findColumn(token.tokenString);
+
+        if (index == -1) {
+            throw Error.error(ErrorCode.X_42501, token.tokenString);
+        }
+
+        ColumnSchema column = table.getColumn(index);
+
+        read();
+
+        return column;
+    }
+
+    StatementDMQL compileDeclareCursor() {
+
+        int sensitivity   = ResultConstants.SQL_ASENSITIVE;
+        int scrollability = ResultConstants.SQL_NONSCROLLABLE;
+        int holdability   = ResultConstants.SQL_NONHOLDABLE;
+        int returnability = ResultConstants.SQL_WITHOUT_RETURN;
+
+        readThis(Tokens.DECLARE);
+        readNewSchemaObjectName(SchemaObject.CURSOR, true);
+
+        switch (token.tokenType) {
+
+            case Tokens.SENSITIVE :
+                read();
+
+                sensitivity = ResultConstants.SQL_SENSITIVE;
+                break;
+
+            case Tokens.INSENSITIVE :
+                read();
+
+                sensitivity = ResultConstants.SQL_INSENSITIVE;
+                break;
+
+            case Tokens.ASENSITIVE :
+                read();
+                break;
+        }
+
+        if (token.tokenType == Tokens.NO) {
+            readThis(Tokens.SCROLL);
+        } else {
+            if (token.tokenType == Tokens.SCROLL) {
+                read();
+
+                scrollability = ResultConstants.SQL_SCROLLABLE;
+            }
+        }
+
+        readThis(Tokens.CURSOR);
+
+        for (int round = 0; round < 2; round++) {
+            if (token.tokenType == Tokens.WITH) {
+                read();
+
+                if (round == 0 && token.tokenType == Tokens.HOLD) {
+                    read();
+
+                    holdability = ResultConstants.SQL_HOLDABLE;
+                } else {
+                    readThis(Tokens.RETURN);
+
+                    round++;
+
+                    returnability = ResultConstants.SQL_WITH_RETURN;
+                }
+            } else if (token.tokenType == Tokens.WITHOUT) {
+                read();
+
+                if (round == 0 && token.tokenType == Tokens.HOLD) {
+                    read();
+                } else {
+                    readThis(Tokens.RETURN);
+
+                    round++;
+                }
+            }
+        }
+
+        readThis(Tokens.FOR);
+
+        int props = ResultProperties.getProperties(sensitivity,
+            ResultConstants.SQL_UPDATABLE, scrollability, holdability,
+            returnability);
+        StatementDMQL cs = compileCursorSpecification(props);
+
+        return cs;
+    }
+
+    /**
+     * Retrieves a SELECT or other query expression Statement from this parse context.
+     */
+    StatementDMQL compileCursorSpecification(int props) {
+
+        OrderedHashSet  colNames        = null;
+        QueryExpression queryExpression = XreadQueryExpression();
+
+        if (token.tokenType == Tokens.FOR) {
+            read();
+
+            if (token.tokenType == Tokens.READ) {
+                read();
+                readThis(Tokens.ONLY);
+            } else {
+                readThis(Tokens.UPDATE);
+
+                props = ResultProperties.addUpdatable(props, true);
+
+                if (token.tokenType == Tokens.OF) {
+                    readThis(Tokens.OF);
+
+                    colNames = new OrderedHashSet();
+
+                    readColumnNameList(colNames, null, false);
+                }
+            }
+        }
+
+        if (ResultProperties.isUpdatable(props)) {
+            queryExpression.isUpdatable = true;
+        }
+
+        queryExpression.setReturningResult();
+        queryExpression.resolve(session);
+
+        StatementDMQL cs = new StatementQuery(session, queryExpression,
+                                              compileContext);
+
+        return cs;
+    }
+
+    StatementDMQL compileShortCursorSpecification(int props) {
+
+        QueryExpression queryExpression = XreadQueryExpression();
+
+        if (ResultProperties.isUpdatable(props)) {
+            queryExpression.isUpdatable = true;
+        }
+
+        queryExpression.setReturningResult();
+        queryExpression.resolve(session);
+
+        StatementDMQL cs = new StatementQuery(session, queryExpression,
+                                              compileContext);
+
+        return cs;
+    }
+
+    int readCloseBrackets(int limit) {
+
+        int count = 0;
+
+        while (count < limit && token.tokenType == Tokens.CLOSEBRACKET) {
+            read();
+
+            count++;
+        }
+
+        return count;
+    }
+
+    int readOpenBrackets() {
+
+        int count = 0;
+
+        while (token.tokenType == Tokens.OPENBRACKET) {
+            count++;
+
+            read();
+        }
+
+        return count;
+    }
+
+    void checkValidCatalogName(String name) {
+
+        if (name != null && !name.equals(database.getCatalogName().name)) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+    }
+
+    void rewind(int position) {
+        super.rewind(position);
+        compileContext.rewind(position);
+    }
+
+    public static final class CompileContext {
+
+        final Session    session;
+        final ParserBase parser;
+
+        //
+        private int           subqueryDepth;
+        private HsqlArrayList namedSubqueries;
+
+        //
+        private OrderedIntKeyHashMap parameters = new OrderedIntKeyHashMap();
+        private HsqlArrayList        subQueryList   = new HsqlArrayList(true);
+        private HsqlArrayList        usedSequences  = new HsqlArrayList(true);
+        private HsqlArrayList        usedRoutines   = new HsqlArrayList(true);
+        private HsqlArrayList        rangeVariables = new HsqlArrayList(true);
+        private HsqlArrayList        usedObjects    = new HsqlArrayList(true);
+        Type                         currentDomain;
+        boolean                      contextuallyTypedExpression;
+        Routine                      callProcedure;
+
+        //
+        private int rangeVarIndex = 0;
+
+        public CompileContext(Session session, ParserBase parser) {
+
+            this.session = session;
+            this.parser  = parser;
+
+            reset();
+        }
+
+        public void reset() {
+
+            rangeVarIndex = 0;
+
+            rangeVariables.clear();
+            subQueryList.clear();
+
+            subqueryDepth = 0;
+
+            parameters.clear();
+            usedSequences.clear();
+            usedRoutines.clear();
+
+            callProcedure = null;
+
+            usedObjects.clear();
+
+            //
+            currentDomain               = null;
+            contextuallyTypedExpression = false;
+        }
+
+        public void rewind(int position) {
+
+            for (int i = rangeVariables.size() - 1; i >= 0; i--) {
+                RangeVariable range = (RangeVariable) rangeVariables.get(i);
+
+                if (range.parsePosition > position) {
+                    rangeVariables.remove(i);
+                }
+            }
+
+//            rangeVarIndex = rangeVariables.size();
+            for (int i = subQueryList.size() - 1; i >= 0; i--) {
+                SubQuery subQuery = (SubQuery) subQueryList.get(i);
+
+                if (subQuery.parsePosition >= position) {
+                    subQueryList.remove(i);
+                }
+            }
+
+            Iterator it = parameters.keySet().iterator();
+
+            while (it.hasNext()) {
+                int pos = it.nextInt();
+
+                if (pos >= position) {
+                    it.remove();
+                }
+            }
+        }
+
+        public void registerRangeVariable(RangeVariable range) {
+
+            range.parsePosition = parser == null ? 0
+                                                 : parser.getPosition();
+            range.rangePosition = getNextRangeVarIndex();
+            range.level         = subqueryDepth;
+
+            rangeVariables.add(range);
+        }
+
+        public int getNextRangeVarIndex() {
+            return rangeVarIndex++;
+        }
+
+        public int getRangeVarCount() {
+            return rangeVarIndex;
+        }
+
+        public RangeVariable[] getRangeVariables() {
+
+            RangeVariable[] array = new RangeVariable[rangeVariables.size()];
+
+            rangeVariables.toArray(array);
+
+            return array;
+        }
+
+        public NumberSequence[] getSequences() {
+
+            if (usedSequences.size() == 0) {
+                return NumberSequence.emptyArray;
+            }
+
+            NumberSequence[] array = new NumberSequence[usedSequences.size()];
+
+            usedSequences.toArray(array);
+
+            return array;
+        }
+
+        public Routine[] getRoutines() {
+
+            if (callProcedure == null && usedRoutines.size() == 0) {
+                return Routine.emptyArray;
+            }
+
+            OrderedHashSet set = new OrderedHashSet();
+
+            for (int i = 0; i < usedRoutines.size(); i++) {
+                FunctionSQLInvoked function =
+                    (FunctionSQLInvoked) usedRoutines.get(i);
+
+                set.add(function.routine);
+            }
+
+            if (callProcedure != null) {
+                set.add(callProcedure);
+            }
+
+            Routine[] array = new Routine[set.size()];
+
+            set.toArray(array);
+
+            return array;
+        }
+
+        private void initSubqueryNames() {
+
+            if (namedSubqueries == null) {
+                namedSubqueries = new HsqlArrayList();
+            }
+
+            if (namedSubqueries.size() <= subqueryDepth) {
+                namedSubqueries.setSize(subqueryDepth + 1);
+            }
+
+            HashMappedList set =
+                (HashMappedList) namedSubqueries.get(subqueryDepth);
+
+            if (set == null) {
+                set = new HashMappedList();
+
+                namedSubqueries.set(subqueryDepth, set);
+            } else {
+                set.clear();
+            }
+        }
+
+        private void registerSubquery(String name, SubQuery subquery) {
+
+            HashMappedList set =
+                (HashMappedList) namedSubqueries.get(subqueryDepth);
+            boolean added = set.add(name, subquery);
+
+            if (!added) {
+                throw Error.error(ErrorCode.X_42504);
+            }
+        }
+
+        private SubQuery getNamedSubQuery(String name) {
+
+            if (namedSubqueries == null) {
+                return null;
+            }
+
+            for (int i = subqueryDepth; i >= 0; i--) {
+                if (namedSubqueries.size() <= i) {
+                    continue;
+                }
+
+                HashMappedList set = (HashMappedList) namedSubqueries.get(i);
+
+                if (set == null) {
+                    continue;
+                }
+
+                SubQuery sq = (SubQuery) set.get(name);
+
+                if (sq != null) {
+                    return sq;
+                }
+            }
+
+            return null;
+        }
+
+        private void addParameter(Expression e, int position) {
+            parameters.put(position, e);
+        }
+
+        private void addSchemaObject(SchemaObject object) {
+            usedObjects.add(object);
+        }
+
+        private void addSequence(SchemaObject object) {
+            usedSequences.add(object);
+        }
+
+        void addFunctionCall(FunctionSQLInvoked function) {
+            usedRoutines.add(function);
+        }
+
+        void addProcedureCall(Routine procedure) {
+            callProcedure = procedure;
+        }
+
+        ExpressionColumn[] getParameters() {
+
+            if (parameters.size() == 0) {
+                return ExpressionColumn.emptyArray;
+            }
+
+            ExpressionColumn[] result =
+                new ExpressionColumn[parameters.size()];
+
+            parameters.valuesToArray(result);
+            parameters.clear();
+
+            return result;
+        }
+
+        void clearParameters() {
+            parameters.clear();
+        }
+
+        public OrderedHashSet getSchemaObjectNames() {
+
+            OrderedHashSet set = new OrderedHashSet();
+
+            for (int i = 0; i < usedSequences.size(); i++) {
+                SchemaObject object = (SchemaObject) usedSequences.get(i);
+
+                set.add(object.getName());
+            }
+
+            for (int i = 0; i < usedObjects.size(); i++) {
+                SchemaObject object = (SchemaObject) usedObjects.get(i);
+
+                set.add(object.getName());
+            }
+
+            for (int i = 0; i < rangeVariables.size(); i++) {
+                RangeVariable range = (RangeVariable) rangeVariables.get(i);
+                HsqlName      name  = range.rangeTable.getName();
+
+                if (name.schema != SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                    set.add(range.rangeTable.getName());
+                    set.addAll(range.getColumnNames());
+                } else if (name.type == SchemaObject.TRANSITION) {
+                    set.addAll(range.getColumnNames());
+                }
+            }
+
+            Routine[] routines = getRoutines();
+
+            for (int i = 0; i < routines.length; i++) {
+                set.add(routines[i].getSpecificName());
+            }
+
+            return set;
+        }
+    }
+}
diff --git a/src/org/hsqldb/ParserRoutine.java b/src/org/hsqldb/ParserRoutine.java
new file mode 100644
index 0000000..ae9e2fd
--- /dev/null
+++ b/src/org/hsqldb/ParserRoutine.java
@@ -0,0 +1,1737 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.LongDeque;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Parser for SQL stored procedures and functions - PSM
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ParserRoutine extends ParserDML {
+
+    ParserRoutine(Session session, Scanner t) {
+        super(session, t);
+    }
+
+    /**
+     *  Reads a DEFAULT clause expression.
+     */
+    /*
+     for datetime, the default must have the same fields
+     */
+    Expression readDefaultClause(Type dataType) {
+
+        Expression e     = null;
+        boolean    minus = false;
+
+        if (token.tokenType == Tokens.NULL) {
+            read();
+
+            return new ExpressionValue(null, dataType);
+        }
+
+        if (dataType.isDateTimeType() || dataType.isIntervalType()) {
+            switch (token.tokenType) {
+
+                case Tokens.DATE :
+                case Tokens.TIME :
+                case Tokens.TIMESTAMP :
+                case Tokens.INTERVAL : {
+                    e = readDateTimeIntervalLiteral();
+
+                    if (e.dataType.typeCode != dataType.typeCode) {
+
+                        // error message
+                        throw unexpectedToken();
+                    }
+
+                    Object defaultValue = e.getValue(session, dataType);
+
+                    return new ExpressionValue(defaultValue, dataType);
+                }
+                case Tokens.X_VALUE :
+                    break;
+
+                default :
+                    e = XreadDateTimeValueFunctionOrNull();
+                    break;
+            }
+        } else if (dataType.isNumberType()) {
+            if (token.tokenType == Tokens.MINUS) {
+                read();
+
+                minus = true;
+            }
+        } else if (dataType.isCharacterType()) {
+            switch (token.tokenType) {
+
+                case Tokens.USER :
+                case Tokens.CURRENT_USER :
+                case Tokens.CURRENT_ROLE :
+                case Tokens.SESSION_USER :
+                case Tokens.SYSTEM_USER :
+                case Tokens.CURRENT_CATALOG :
+                case Tokens.CURRENT_SCHEMA :
+                case Tokens.CURRENT_PATH :
+                    FunctionSQL function =
+                        FunctionSQL.newSQLFunction(token.tokenString,
+                                                   compileContext);
+
+                    e = readSQLFunction(function);
+                    break;
+
+                default :
+            }
+        } else if (dataType.isBooleanType()) {
+            switch (token.tokenType) {
+
+                case Tokens.TRUE :
+                    read();
+
+                    return Expression.EXPR_TRUE;
+
+                case Tokens.FALSE :
+                    read();
+
+                    return Expression.EXPR_FALSE;
+            }
+        } else if (dataType.isArrayType()) {
+            e = readCollection(OpTypes.ARRAY);
+
+            if (e.nodes.length > 0) {
+                throw Error.error(ErrorCode.X_42562);
+            }
+
+            resolveOuterReferencesAndTypes(RangeVariable.emptyArray, e);
+
+            return e;
+        }
+
+        if (e != null) {
+            e.resolveTypes(session, null);
+
+            if (dataType.typeComparisonGroup
+                    != e.getDataType().typeComparisonGroup) {
+                throw Error.error(ErrorCode.X_42562);
+            }
+
+            return e;
+        }
+
+        if (token.tokenType == Tokens.X_VALUE) {
+            Object value = dataType.convertToType(session, token.tokenValue,
+                                                  token.dataType);
+
+            read();
+
+            if (minus) {
+                value = dataType.negate(value);
+            }
+
+            return new ExpressionValue(value, dataType);
+        } else {
+            throw unexpectedToken();
+        }
+    }
+
+    Statement compileSelectSingleRowStatement(RangeVariable[] rangeVars) {
+
+        OrderedHashSet     variableNames = new OrderedHashSet();
+        QuerySpecification select        = XreadSelect();
+        Type[]             targetTypes;
+        LongDeque          colIndexList = new LongDeque();
+
+        readThis(Tokens.INTO);
+        readTargetSpecificationList(variableNames, rangeVars, colIndexList);
+        XreadTableExpression(select);
+        select.setReturningResult();
+
+        int[] columnMap = new int[colIndexList.size()];
+
+        colIndexList.toArray(columnMap);
+
+        Expression[] variables = new Expression[variableNames.size()];
+
+        variableNames.toArray(variables);
+
+        targetTypes = new Type[variables.length];
+
+        for (int i = 0; i < variables.length; i++) {
+            if (variables[i].getColumn().getParameterMode()
+                    == SchemaObject.ParameterModes.PARAM_IN) {
+
+                // todo - use more specific error message
+                throw Error.error(ErrorCode.X_0U000);
+            }
+
+            targetTypes[i] = variables[i].getDataType();
+        }
+
+        select.resolve(session, rangeVars, targetTypes);
+
+        if (select.getColumnCount() != variables.length) {
+            throw Error.error(ErrorCode.X_42564, Tokens.T_INTO);
+        }
+
+        Statement statement = new StatementSet(session, variables, select,
+                                               columnMap, compileContext);
+
+        return statement;
+    }
+
+    /**
+     * Creates SET Statement for PSM or session variables from this parse context.
+     */
+    Statement compileSetStatement(RangeVariable rangeVars[]) {
+
+        read();
+
+        OrderedHashSet targetSet    = new OrderedHashSet();
+        HsqlArrayList  exprList     = new HsqlArrayList();
+        LongDeque      colIndexList = new LongDeque();
+
+        readSetClauseList(rangeVars, targetSet, colIndexList, exprList);
+
+        if (exprList.size() > 1) {
+            throw Error.error(ErrorCode.X_42602);
+        }
+
+        Expression expression = (Expression) exprList.get(0);
+
+        if (expression.getDegree() != targetSet.size()) {
+            throw Error.error(ErrorCode.X_42546, Tokens.T_SET);
+        }
+
+        int[] columnMap = new int[colIndexList.size()];
+
+        colIndexList.toArray(columnMap);
+
+        Expression[] targets = new Expression[targetSet.size()];
+
+        targetSet.toArray(targets);
+
+        for (int i = 0; i < targets.length; i++) {
+            this.resolveOuterReferencesAndTypes(rangeVars, targets[i]);
+        }
+
+        resolveOuterReferencesAndTypes(rangeVars, expression);
+
+        for (int i = 0; i < targets.length; i++) {
+            if (targets[i].getColumn().getParameterMode()
+                    == SchemaObject.ParameterModes.PARAM_IN) {
+
+                // todo - use more specific error message
+                throw Error.error(ErrorCode.X_0U000);
+            }
+
+            if (!targets[i].getDataType().canBeAssignedFrom(
+                    expression.getNodeDataType(i))) {
+                throw Error.error(ErrorCode.X_42561);
+            }
+        }
+
+        StatementSet cs = new StatementSet(session, targets, expression,
+                                           columnMap, compileContext);
+
+        return cs;
+    }
+
+    /**
+     * Creates SET Statement for a trigger row from this parse context.
+     */
+    StatementDMQL compileTriggerSetStatement(Table table,
+            RangeVariable[] rangeVars) {
+
+        read();
+
+        Expression[]   updateExpressions;
+        int[]          columnMap;
+        OrderedHashSet targetSet = new OrderedHashSet();
+        HsqlArrayList  exprList  = new HsqlArrayList();
+        RangeVariable[] targetRangeVars = new RangeVariable[]{
+            rangeVars[TriggerDef.NEW_ROW] };
+        LongDeque colIndexList = new LongDeque();
+
+        readSetClauseList(targetRangeVars, targetSet, colIndexList, exprList);
+
+        columnMap = new int[colIndexList.size()];
+
+        colIndexList.toArray(columnMap);
+
+        Expression[] targets = new Expression[targetSet.size()];
+
+        targetSet.toArray(targets);
+
+        for (int i = 0; i < targets.length; i++) {
+            this.resolveOuterReferencesAndTypes(RangeVariable.emptyArray,
+                                                targets[i]);
+        }
+
+        updateExpressions = new Expression[exprList.size()];
+
+        exprList.toArray(updateExpressions);
+        resolveUpdateExpressions(table, rangeVars, columnMap,
+                                 updateExpressions, RangeVariable.emptyArray);
+
+        StatementDMQL cs = new StatementSet(session, targets, table,
+                                            rangeVars, columnMap,
+                                            updateExpressions, compileContext);
+
+        return cs;
+    }
+
+    // SQL-invoked routine
+    StatementSchema compileCreateProcedureOrFunction() {
+
+        int     routineType;
+        boolean isAggregate = false;
+
+        if (token.tokenType == Tokens.AGGREGATE) {
+            isAggregate = true;
+
+            read();
+
+            if (token.tokenType == Tokens.PROCEDURE) {
+                throw super.unexpectedToken();
+            }
+        }
+
+        routineType = token.tokenType == Tokens.PROCEDURE
+                      ? SchemaObject.PROCEDURE
+                      : SchemaObject.FUNCTION;
+
+        HsqlName name;
+
+        read();
+
+        name = readNewSchemaObjectName(routineType, false);
+
+        Routine routine = new Routine(routineType);
+
+        routine.setName(name);
+        routine.setAggregate(isAggregate);
+        readThis(Tokens.OPENBRACKET);
+
+        if (token.tokenType == Tokens.CLOSEBRACKET) {
+            read();
+        } else {
+            while (true) {
+                ColumnSchema newcolumn = readRoutineParameter(routine, true);
+
+                routine.addParameter(newcolumn);
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+                } else {
+                    readThis(Tokens.CLOSEBRACKET);
+
+                    break;
+                }
+            }
+        }
+
+        if (routineType != SchemaObject.PROCEDURE) {
+            readThis(Tokens.RETURNS);
+
+            if (token.tokenType == Tokens.TABLE) {
+                read();
+
+                TableDerived table =
+                    new TableDerived(database, name, TableBase.FUNCTION_TABLE);
+
+                readThis(Tokens.OPENBRACKET);
+
+                for (int i = 0; ; i++) {
+                    ColumnSchema newcolumn = readRoutineParameter(routine,
+                        false);
+
+                    if (newcolumn.getName() == null) {
+                        throw super.unexpectedToken();
+                    }
+
+                    table.addColumn(newcolumn);
+
+                    if (token.tokenType == Tokens.COMMA) {
+                        read();
+                    } else {
+                        readThis(Tokens.CLOSEBRACKET);
+
+                        break;
+                    }
+                }
+
+                table.createPrimaryKey();
+                routine.setReturnTable(table);
+            } else {
+                Type type = readTypeDefinition(true);
+
+                routine.setReturnType(type);
+            }
+        }
+
+        readRoutineCharacteristics(routine);
+
+        if (token.tokenType == Tokens.EXTERNAL) {
+            if (routine.getLanguage() != Routine.LANGUAGE_JAVA) {
+                throw unexpectedToken();
+            }
+
+            read();
+            readThis(Tokens.NAME);
+            checkIsValue(Types.SQL_CHAR);
+            routine.setMethodURL((String) token.tokenValue);
+            read();
+
+            if (token.tokenType == Tokens.PARAMETER) {
+                read();
+                readThis(Tokens.STYLE);
+                readThis(Tokens.JAVA);
+            }
+        } else {
+            startRecording();
+
+            Statement statement = compileSQLProcedureStatementOrNull(routine,
+                null);
+
+            if (statement == null) {
+                throw unexpectedToken();
+            }
+
+            Token[] tokenisedStatement = getRecordedStatement();
+            String  sql                = Token.getSQL(tokenisedStatement);
+
+            statement.setSQL(sql);
+            routine.setProcedure(statement);
+        }
+
+        Object[] args = new Object[]{ routine };
+        String   sql  = getLastPart();
+        StatementSchema cs = new StatementSchema(sql,
+            StatementTypes.CREATE_ROUTINE, args);
+
+        return cs;
+    }
+
+    private void readRoutineCharacteristics(Routine routine) {
+
+        OrderedIntHashSet set = new OrderedIntHashSet();
+        boolean           end = false;
+
+        while (!end) {
+            switch (token.tokenType) {
+
+                case Tokens.LANGUAGE : {
+                    if (!set.add(Tokens.LANGUAGE)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    if (token.tokenType == Tokens.JAVA) {
+                        read();
+                        routine.setLanguage(Routine.LANGUAGE_JAVA);
+                    } else if (token.tokenType == Tokens.SQL) {
+                        read();
+                        routine.setLanguage(Routine.LANGUAGE_SQL);
+                    } else {
+                        throw unexpectedToken();
+                    }
+
+                    break;
+                }
+                case Tokens.PARAMETER : {
+                    if (!set.add(Tokens.PARAMETER)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.STYLE);
+
+                    if (token.tokenType == Tokens.JAVA) {
+                        read();
+                        routine.setParameterStyle(Routine.PARAM_STYLE_JAVA);
+                    } else {
+                        readThis(Tokens.SQL);
+                        routine.setParameterStyle(Routine.PARAM_STYLE_SQL);
+                    }
+
+                    break;
+                }
+                case Tokens.SPECIFIC : {
+                    if (!set.add(Tokens.SPECIFIC)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    HsqlName name =
+                        readNewSchemaObjectName(SchemaObject.SPECIFIC_ROUTINE,
+                                                false);
+
+                    routine.setSpecificName(name);
+
+                    break;
+                }
+                case Tokens.DETERMINISTIC : {
+                    if (!set.add(Tokens.DETERMINISTIC)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    routine.setDeterministic(true);
+
+                    break;
+                }
+                case Tokens.NOT : {
+                    if (!set.add(Tokens.DETERMINISTIC)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.DETERMINISTIC);
+                    routine.setDeterministic(false);
+
+                    break;
+                }
+                case Tokens.MODIFIES : {
+                    if (!set.add(Tokens.SQL)) {
+                        throw unexpectedToken();
+                    }
+
+                    if (routine.getType() == SchemaObject.FUNCTION) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.SQL);
+                    readThis(Tokens.DATA);
+                    routine.setDataImpact(Routine.MODIFIES_SQL);
+
+                    break;
+                }
+                case Tokens.NO : {
+                    if (!set.add(Tokens.SQL)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.SQL);
+                    routine.setDataImpact(Routine.NO_SQL);
+
+                    break;
+                }
+                case Tokens.READS : {
+                    if (!set.add(Tokens.SQL)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.SQL);
+                    readThis(Tokens.DATA);
+                    routine.setDataImpact(Routine.READS_SQL);
+
+                    break;
+                }
+                case Tokens.CONTAINS : {
+                    if (!set.add(Tokens.SQL)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.SQL);
+                    routine.setDataImpact(Routine.CONTAINS_SQL);
+
+                    break;
+                }
+                case Tokens.RETURNS : {
+                    if (!set.add(Tokens.NULL) || routine.isProcedure()) {
+                        throw unexpectedToken();
+                    }
+
+                    if (routine.isAggregate()) {
+                        throw Error.error(ErrorCode.X_42604,
+                                          token.tokenString);
+                    }
+
+                    read();
+                    readThis(Tokens.NULL);
+                    readThis(Tokens.ON);
+                    readThis(Tokens.NULL);
+                    readThis(Tokens.INPUT);
+                    routine.setNullInputOutput(true);
+
+                    break;
+                }
+                case Tokens.CALLED : {
+                    if (!set.add(Tokens.NULL) || routine.isProcedure()) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.ON);
+                    readThis(Tokens.NULL);
+                    readThis(Tokens.INPUT);
+                    routine.setNullInputOutput(false);
+
+                    break;
+                }
+                case Tokens.DYNAMIC : {
+                    if (!set.add(Tokens.RESULT) || routine.isFunction()) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.RESULT);
+                    readThis(Tokens.SETS);
+                    readBigint();
+
+                    break;
+                }
+                case Tokens.NEW : {
+                    if (routine.getType() == SchemaObject.FUNCTION
+                            || !set.add(Tokens.SAVEPOINT)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.SAVEPOINT);
+                    readThis(Tokens.LEVEL);
+                    routine.setNewSavepointLevel(true);
+
+                    break;
+                }
+                case Tokens.OLD : {
+                    if (routine.getType() == SchemaObject.FUNCTION
+                            || !set.add(Tokens.SAVEPOINT)) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+                    readThis(Tokens.SAVEPOINT);
+                    readThis(Tokens.LEVEL);
+                    routine.setNewSavepointLevel(false);
+
+                    throw super.unsupportedFeature(Tokens.T_OLD);
+
+                    // break;
+                }
+                default :
+                    end = true;
+                    break;
+            }
+        }
+    }
+
+/*
+    <SQL control statement> ::=
+    <call statement>
+    | <return statement>
+
+    <compound statement>
+    <case statement>
+    <if statement>
+    <iterate statement>
+    <leave statement>
+    <loop statement>
+    <while statement>
+    <repeat statement>
+   <for statement>
+   <assignment statement> SET (,,,) = (,,,) or SET a = b
+
+
+*/
+    private Object[] readLocalDeclarationList(Routine routine,
+            StatementCompound context) {
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        while (token.tokenType == Tokens.DECLARE) {
+            Object var = readLocalVariableDeclarationOrNull();
+
+            if (var == null) {
+                var = compileLocalHandlerDeclarationOrNull(routine, context);
+            }
+
+            if (var instanceof ColumnSchema[]) {
+                list.addAll((Object[]) var);
+            } else {
+                list.add(var);
+            }
+        }
+
+        Object[] declarations = new Object[list.size()];
+
+        list.toArray(declarations);
+
+        return declarations;
+    }
+
+    ColumnSchema[] readLocalVariableDeclarationOrNull() {
+
+        int        position = super.getPosition();
+        Type       type;
+        HsqlName[] names = HsqlName.emptyArray;
+
+        try {
+            readThis(Tokens.DECLARE);
+
+            if (isReservedKey()) {
+                rewind(position);
+
+                return null;
+            }
+
+            while (true) {
+                names = (HsqlName[]) ArrayUtil.resizeArray(names,
+                        names.length + 1);
+                names[names.length - 1] =
+                    super.readNewSchemaObjectName(SchemaObject.VARIABLE,
+                                                  false);
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+                } else {
+                    break;
+                }
+            }
+
+            type = readTypeDefinition(true);
+        } catch (Exception e) {
+
+            // may be cursor
+            rewind(position);
+
+            return null;
+        }
+
+        Expression def = null;
+
+        if (token.tokenType == Tokens.DEFAULT) {
+            read();
+
+            def = readDefaultClause(type);
+        }
+
+        ColumnSchema[] variable = new ColumnSchema[names.length];
+
+        for (int i = 0; i < names.length; i++) {
+            variable[i] = new ColumnSchema(names[i], type, true, false, def);
+
+            variable[i].setParameterMode(
+                SchemaObject.ParameterModes.PARAM_INOUT);
+        }
+
+        readThis(Tokens.SEMICOLON);
+
+        return variable;
+    }
+
+    private StatementHandler compileLocalHandlerDeclarationOrNull(
+            Routine routine, StatementCompound context) {
+
+        int handlerType;
+
+        readThis(Tokens.DECLARE);
+
+        switch (token.tokenType) {
+
+            case Tokens.CONTINUE :
+                read();
+
+                handlerType = StatementHandler.CONTINUE;
+                break;
+
+            case Tokens.EXIT :
+                read();
+
+                handlerType = StatementHandler.EXIT;
+                break;
+
+            case Tokens.UNDO :
+                read();
+
+                handlerType = StatementHandler.UNDO;
+                break;
+
+            default :
+                throw unexpectedToken();
+        }
+
+        readThis(Tokens.HANDLER);
+        readThis(Tokens.FOR);
+
+        StatementHandler handler = new StatementHandler(handlerType);
+        boolean          end     = false;
+        boolean          start   = true;
+
+        while (!end) {
+            int conditionType = StatementHandler.NONE;
+
+            switch (token.tokenType) {
+
+                case Tokens.COMMA :
+                    if (start) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    start = true;
+                    break;
+
+                case Tokens.SQLSTATE :
+                    conditionType = StatementHandler.SQL_STATE;
+
+                // fall through
+                case Tokens.SQLEXCEPTION :
+                    if (conditionType == StatementHandler.NONE) {
+                        conditionType = StatementHandler.SQL_EXCEPTION;
+                    }
+
+                // fall through
+                case Tokens.SQLWARNING :
+                    if (conditionType == StatementHandler.NONE) {
+                        conditionType = StatementHandler.SQL_WARNING;
+                    }
+
+                // fall through
+                case Tokens.NOT :
+                    if (conditionType == StatementHandler.NONE) {
+                        conditionType = StatementHandler.SQL_NOT_FOUND;
+                    }
+
+                    if (!start) {
+                        throw unexpectedToken();
+                    }
+
+                    start = false;
+
+                    read();
+
+                    if (conditionType == StatementHandler.SQL_NOT_FOUND) {
+                        readThis(Tokens.FOUND);
+                    } else if (conditionType == StatementHandler.SQL_STATE) {
+                        String sqlState = parseSQLStateValue();
+
+                        handler.addConditionState(sqlState);
+
+                        break;
+                    }
+
+                    handler.addConditionType(conditionType);
+                    break;
+
+                default :
+                    if (start) {
+                        throw unexpectedToken();
+                    }
+
+                    end = true;
+                    break;
+            }
+        }
+
+        if (token.tokenType == Tokens.SEMICOLON) {
+            read();
+        } else {
+            Statement e = compileSQLProcedureStatementOrNull(routine, context);
+
+            if (e == null) {
+                throw unexpectedToken();
+            }
+
+            readThis(Tokens.SEMICOLON);
+            handler.addStatement(e);
+        }
+
+        return handler;
+    }
+
+    String parseSQLStateValue() {
+
+        readIfThis(Tokens.VALUE);
+        checkIsValue(Types.SQL_CHAR);
+
+        String sqlState = token.tokenString;
+
+        if (token.tokenString.length() != 5) {
+            throw Error.error(ErrorCode.X_42607);
+        }
+
+        read();
+
+        return sqlState;
+    }
+
+    private Statement compileCompoundStatement(Routine routine,
+            StatementCompound context, HsqlName label) {
+
+        final boolean atomic = true;
+
+        readThis(Tokens.BEGIN);
+        readThis(Tokens.ATOMIC);
+
+        StatementCompound statement =
+            new StatementCompound(StatementTypes.BEGIN_END, label);
+
+        statement.setAtomic(atomic);
+        statement.setRoot(routine);
+        statement.setParent(context);
+
+        Object[] declarations = readLocalDeclarationList(routine, context);
+
+        statement.setLocalDeclarations(declarations);
+
+        Statement[] statements = compileSQLProcedureStatementList(routine,
+            statement);
+
+        statement.setStatements(statements);
+        readThis(Tokens.END);
+
+        if (isSimpleName() && !isReservedKey()) {
+            if (label == null) {
+                throw unexpectedToken();
+            }
+
+            if (!label.name.equals(token.tokenString)) {
+                throw Error.error(ErrorCode.X_42508, token.tokenString);
+            }
+
+            read();
+        }
+
+        return statement;
+    }
+
+    private Statement[] compileSQLProcedureStatementList(Routine routine,
+            StatementCompound context) {
+
+        Statement     e;
+        HsqlArrayList list = new HsqlArrayList();
+
+        while (true) {
+            e = compileSQLProcedureStatementOrNull(routine, context);
+
+            if (e == null) {
+                break;
+            }
+
+            readThis(Tokens.SEMICOLON);
+            list.add(e);
+        }
+
+        if (list.size() == 0) {
+            throw unexpectedToken();
+        }
+
+        Statement[] statements = new Statement[list.size()];
+
+        list.toArray(statements);
+
+        return statements;
+    }
+
+    Statement compileSQLProcedureStatementOrNull(Routine routine,
+            StatementCompound context) {
+
+        Statement cs    = null;
+        HsqlName  label = null;
+        RangeVariable[] rangeVariables = context == null
+                                         ? routine.getParameterRangeVariables()
+                                         : context.getRangeVariables();
+
+        if (!routine.isTrigger() && isSimpleName() && !isReservedKey()) {
+            label = readNewSchemaObjectName(SchemaObject.LABEL, false);
+
+            readThis(Tokens.COLON);
+        }
+
+        compileContext.reset();
+
+        switch (token.tokenType) {
+
+            // data
+            case Tokens.SELECT : {
+                if (routine.dataImpact == Routine.CONTAINS_SQL) {
+                    throw Error.error(ErrorCode.X_42608,
+                                      routine.getDataImpactString());
+                }
+
+                if (label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileSelectSingleRowStatement(rangeVariables);
+
+                break;
+            }
+
+            // data change
+            case Tokens.INSERT :
+                if (routine.dataImpact != Routine.MODIFIES_SQL) {
+                    throw Error.error(ErrorCode.X_42608,
+                                      routine.getDataImpactString());
+                }
+
+                if (label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileInsertStatement(rangeVariables);
+                break;
+
+            case Tokens.UPDATE :
+                if (routine.dataImpact != Routine.MODIFIES_SQL) {
+                    throw Error.error(ErrorCode.X_42608,
+                                      routine.getDataImpactString());
+                }
+
+                if (label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileUpdateStatement(rangeVariables);
+                break;
+
+            case Tokens.DELETE :
+            case Tokens.TRUNCATE :
+                if (routine.dataImpact != Routine.MODIFIES_SQL) {
+                    throw Error.error(ErrorCode.X_42608,
+                                      routine.getDataImpactString());
+                }
+
+                if (label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileDeleteStatement(rangeVariables);
+                break;
+
+            case Tokens.MERGE :
+                if (routine.dataImpact != Routine.MODIFIES_SQL) {
+                    throw Error.error(ErrorCode.X_42608,
+                                      routine.getDataImpactString());
+                }
+
+                if (label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileMergeStatement(rangeVariables);
+                break;
+
+            case Tokens.SET :
+                if (label != null) {
+                    throw unexpectedToken();
+                }
+
+                if (routine.isTrigger()) {
+                    if (routine.triggerOperation
+                            == StatementTypes.DELETE_WHERE) {
+                        throw unexpectedToken();
+                    }
+
+                    if (routine.triggerType != TriggerDef.BEFORE) {
+                        throw unexpectedToken();
+                    }
+
+                    cs = compileTriggerSetStatement(routine.triggerTable,
+                                                    rangeVariables);
+                } else {
+                    cs = compileSetStatement(rangeVariables);
+                }
+                break;
+
+            // control
+            case Tokens.CALL : {
+                if (label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileCallStatement(rangeVariables, true);
+
+                Routine proc = ((StatementProcedure) cs).procedure;
+
+                if (proc != null) {
+                    switch (routine.dataImpact) {
+
+                        case Routine.CONTAINS_SQL : {
+                            if (proc.dataImpact == Routine.READS_SQL
+                                    || proc.dataImpact
+                                       == Routine.MODIFIES_SQL) {
+                                throw Error.error(
+                                    ErrorCode.X_42608,
+                                    routine.getDataImpactString());
+                            }
+                        }
+                        case Routine.READS_SQL : {
+                            if (routine.dataImpact == Routine.MODIFIES_SQL) {
+                                throw Error.error(
+                                    ErrorCode.X_42608,
+                                    routine.getDataImpactString());
+                            }
+                        }
+                    }
+                }
+
+                break;
+            }
+            case Tokens.RETURN : {
+                if (routine.isTrigger() || label != null) {
+                    throw unexpectedToken();
+                }
+
+                read();
+
+                cs = compileReturnValue(routine, context);
+
+                break;
+            }
+            case Tokens.BEGIN : {
+                cs = compileCompoundStatement(routine, context, label);
+
+                break;
+            }
+            case Tokens.WHILE : {
+                if (routine.isTrigger()) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileWhile(routine, context, label);
+
+                break;
+            }
+            case Tokens.REPEAT : {
+                if (routine.isTrigger()) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileRepeat(routine, context, label);
+
+                break;
+            }
+            case Tokens.LOOP : {
+                if (routine.isTrigger()) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileLoop(routine, context, label);
+
+                break;
+            }
+            case Tokens.FOR : {
+                if (routine.isTrigger()) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileFor(routine, context, label);
+
+                break;
+            }
+            case Tokens.ITERATE : {
+                if (routine.isTrigger() || label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileIterate();
+
+                break;
+            }
+            case Tokens.LEAVE : {
+                if (routine.isTrigger() || label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileLeave(routine, context);
+
+                break;
+            }
+            case Tokens.IF : {
+                cs = compileIf(routine, context);
+
+                break;
+            }
+            case Tokens.CASE : {
+                cs = compileCase(routine, context);
+
+                break;
+            }
+            case Tokens.SIGNAL : {
+                if (routine.isTrigger() || label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileSignal(routine, context, label);
+
+                break;
+            }
+            case Tokens.RESIGNAL : {
+                if (routine.isTrigger() || label != null) {
+                    throw unexpectedToken();
+                }
+
+                cs = compileResignal(routine, context, label);
+
+                break;
+            }
+            default :
+                return null;
+        }
+
+        cs.setRoot(routine);
+        cs.setParent(context);
+
+        return cs;
+    }
+
+    private Statement compileReturnValue(Routine routine,
+                                         StatementCompound context) {
+
+        Expression e = XreadValueExpressionOrNull();
+
+        if (e == null) {
+            checkIsValue();
+
+            if (token.tokenValue == null) {
+                e = new ExpressionValue(null, null);
+            }
+        }
+
+        resolveOuterReferencesAndTypes(routine, context, e);
+
+        if (routine.isProcedure()) {
+            throw Error.error(ErrorCode.X_42602);
+        }
+
+        return new StatementExpression(session, compileContext,
+                                       StatementTypes.RETURN, e);
+    }
+
+    private Statement compileIterate() {
+
+        readThis(Tokens.ITERATE);
+
+        HsqlName label = readNewSchemaObjectName(SchemaObject.LABEL, false);
+
+        return new StatementSimple(StatementTypes.ITERATE, label);
+    }
+
+    private Statement compileLeave(Routine routine,
+                                   StatementCompound context) {
+
+        readThis(Tokens.LEAVE);
+
+        HsqlName label = readNewSchemaObjectName(SchemaObject.LABEL, false);
+
+        return new StatementSimple(StatementTypes.LEAVE, label);
+    }
+
+    private Statement compileWhile(Routine routine, StatementCompound context,
+                                   HsqlName label) {
+
+        readThis(Tokens.WHILE);
+
+        Expression e = XreadBooleanValueExpression();
+
+        resolveOuterReferencesAndTypes(routine, context, e);
+
+        StatementExpression condition = new StatementExpression(session,
+            compileContext, StatementTypes.CONDITION, e);
+
+        readThis(Tokens.DO);
+
+        Statement[] statements = compileSQLProcedureStatementList(routine,
+            context);
+
+        readThis(Tokens.END);
+        readThis(Tokens.WHILE);
+
+        if (isSimpleName() && !isReservedKey()) {
+            if (label == null) {
+                throw unexpectedToken();
+            }
+
+            if (!label.name.equals(token.tokenString)) {
+                throw Error.error(ErrorCode.X_42508, token.tokenString);
+            }
+
+            read();
+        }
+
+        StatementCompound statement =
+            new StatementCompound(StatementTypes.WHILE, label);
+
+        statement.setStatements(statements);
+        statement.setCondition(condition);
+
+        return statement;
+    }
+
+    private Statement compileRepeat(Routine routine,
+                                    StatementCompound context,
+                                    HsqlName label) {
+
+        readThis(Tokens.REPEAT);
+
+        Statement[] statements = compileSQLProcedureStatementList(routine,
+            context);
+
+        readThis(Tokens.UNTIL);
+
+        Expression e = XreadBooleanValueExpression();
+
+        resolveOuterReferencesAndTypes(routine, context, e);
+
+        StatementExpression condition = new StatementExpression(session,
+            compileContext, StatementTypes.CONDITION, e);
+
+        readThis(Tokens.END);
+        readThis(Tokens.REPEAT);
+
+        if (isSimpleName() && !isReservedKey()) {
+            if (label == null) {
+                throw unexpectedToken();
+            }
+
+            if (!label.name.equals(token.tokenString)) {
+                throw Error.error(ErrorCode.X_42508, token.tokenString);
+            }
+
+            read();
+        }
+
+        StatementCompound statement =
+            new StatementCompound(StatementTypes.REPEAT, label);
+
+        statement.setStatements(statements);
+        statement.setCondition(condition);
+
+        return statement;
+    }
+
+    private Statement compileLoop(Routine routine, StatementCompound context,
+                                  HsqlName label) {
+
+        readThis(Tokens.LOOP);
+
+        Statement[] statements = compileSQLProcedureStatementList(routine,
+            context);
+
+        readThis(Tokens.END);
+        readThis(Tokens.LOOP);
+
+        if (isSimpleName() && !isReservedKey()) {
+            if (label == null) {
+                throw unexpectedToken();
+            }
+
+            if (!label.name.equals(token.tokenString)) {
+                throw Error.error(ErrorCode.X_42508, token.tokenString);
+            }
+
+            read();
+        }
+
+        StatementCompound result = new StatementCompound(StatementTypes.LOOP,
+            label);
+
+        result.setStatements(statements);
+
+        return result;
+    }
+
+    private Statement compileFor(Routine routine, StatementCompound context,
+                                 HsqlName label) {
+
+        readThis(Tokens.FOR);
+
+        Statement cursorStatement =
+            compileCursorSpecification(ResultProperties.defaultPropsValue);
+
+        readThis(Tokens.DO);
+
+        Statement[] statements = compileSQLProcedureStatementList(routine,
+            context);
+
+        readThis(Tokens.END);
+        readThis(Tokens.FOR);
+
+        if (isSimpleName() && !isReservedKey()) {
+            if (label == null) {
+                throw unexpectedToken();
+            }
+
+            if (!label.name.equals(token.tokenString)) {
+                throw Error.error(ErrorCode.X_42508, token.tokenString);
+            }
+
+            read();
+        }
+
+        StatementCompound result = new StatementCompound(StatementTypes.FOR,
+            label);
+
+        result.setLoopStatement(cursorStatement);
+        result.setStatements(statements);
+
+        return result;
+    }
+
+    private Statement compileIf(Routine routine, StatementCompound context) {
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        readThis(Tokens.IF);
+
+        Expression e = XreadBooleanValueExpression();
+
+        resolveOuterReferencesAndTypes(routine, context, e);
+
+        Statement statement = new StatementExpression(session, compileContext,
+            StatementTypes.CONDITION, e);
+
+        list.add(statement);
+        readThis(Tokens.THEN);
+
+        Statement[] statements = compileSQLProcedureStatementList(routine,
+            context);
+
+        for (int i = 0; i < statements.length; i++) {
+            list.add(statements[i]);
+        }
+
+        while (token.tokenType == Tokens.ELSEIF) {
+            read();
+
+            e = XreadBooleanValueExpression();
+
+            resolveOuterReferencesAndTypes(routine, context, e);
+
+            statement = new StatementExpression(session, compileContext,
+                                                StatementTypes.CONDITION, e);
+
+            list.add(statement);
+            readThis(Tokens.THEN);
+
+            statements = compileSQLProcedureStatementList(routine, context);
+
+            for (int i = 0; i < statements.length; i++) {
+                list.add(statements[i]);
+            }
+        }
+
+        if (token.tokenType == Tokens.ELSE) {
+            read();
+
+            e = Expression.EXPR_TRUE;
+            statement = new StatementExpression(session, compileContext,
+                                                StatementTypes.CONDITION, e);
+
+            list.add(statement);
+
+            statements = compileSQLProcedureStatementList(routine, context);
+
+            for (int i = 0; i < statements.length; i++) {
+                list.add(statements[i]);
+            }
+        }
+
+        readThis(Tokens.END);
+        readThis(Tokens.IF);
+
+        statements = new Statement[list.size()];
+
+        list.toArray(statements);
+
+        StatementCompound result = new StatementCompound(StatementTypes.IF,
+            null);
+
+        result.setStatements(statements);
+
+        return result;
+    }
+
+    private Statement compileCase(Routine routine, StatementCompound context) {
+
+        HsqlArrayList list      = new HsqlArrayList();
+        Expression    condition = null;
+        Statement     statement;
+        Statement[]   statements;
+
+        readThis(Tokens.CASE);
+
+        if (token.tokenType == Tokens.WHEN) {
+            list = readCaseWhen(routine, context);
+        } else {
+            list = readSimpleCaseWhen(routine, context);
+        }
+
+        if (token.tokenType == Tokens.ELSE) {
+            read();
+
+            condition = Expression.EXPR_TRUE;
+            statement = new StatementExpression(session, compileContext,
+                                                StatementTypes.CONDITION,
+                                                condition);
+
+            list.add(statement);
+
+            statements = compileSQLProcedureStatementList(routine, context);
+
+            for (int i = 0; i < statements.length; i++) {
+                list.add(statements[i]);
+            }
+        }
+
+        readThis(Tokens.END);
+        readThis(Tokens.CASE);
+
+        statements = new Statement[list.size()];
+
+        list.toArray(statements);
+
+        StatementCompound result = new StatementCompound(StatementTypes.IF,
+            null);
+
+        result.setStatements(statements);
+
+        return result;
+    }
+
+    private HsqlArrayList readSimpleCaseWhen(Routine routine,
+            StatementCompound context) {
+
+        HsqlArrayList list      = new HsqlArrayList();
+        Expression    condition = null;
+        Statement     statement;
+        Statement[]   statements;
+        Expression    predicand = XreadRowValuePredicand();
+
+        do {
+            readThis(Tokens.WHEN);
+
+            do {
+                Expression newCondition = XreadPredicateRightPart(predicand);
+
+                if (predicand == newCondition) {
+                    newCondition =
+                        new ExpressionLogical(predicand,
+                                              XreadRowValuePredicand());
+                }
+
+                resolveOuterReferencesAndTypes(routine, context, newCondition);
+
+                if (condition == null) {
+                    condition = newCondition;
+                } else {
+                    condition = new ExpressionLogical(OpTypes.OR, condition,
+                                                      newCondition);
+                }
+
+                if (token.tokenType == Tokens.COMMA) {
+                    read();
+                } else {
+                    break;
+                }
+            } while (true);
+
+            statement = new StatementExpression(session, compileContext,
+                                                StatementTypes.CONDITION,
+                                                condition);
+
+            list.add(statement);
+            readThis(Tokens.THEN);
+
+            statements = compileSQLProcedureStatementList(routine, context);
+
+            for (int i = 0; i < statements.length; i++) {
+                list.add(statements[i]);
+            }
+
+            if (token.tokenType != Tokens.WHEN) {
+                break;
+            }
+        } while (true);
+
+        return list;
+    }
+
+    private HsqlArrayList readCaseWhen(Routine routine,
+                                       StatementCompound context) {
+
+        HsqlArrayList list      = new HsqlArrayList();
+        Expression    condition = null;
+        Statement     statement;
+        Statement[]   statements;
+
+        do {
+            readThis(Tokens.WHEN);
+
+            condition = XreadBooleanValueExpression();
+
+            resolveOuterReferencesAndTypes(routine, context, condition);
+
+            statement = new StatementExpression(session, compileContext,
+                                                StatementTypes.CONDITION,
+                                                condition);
+
+            list.add(statement);
+            readThis(Tokens.THEN);
+
+            statements = compileSQLProcedureStatementList(routine, context);
+
+            for (int i = 0; i < statements.length; i++) {
+                list.add(statements[i]);
+            }
+
+            if (token.tokenType != Tokens.WHEN) {
+                break;
+            }
+        } while (true);
+
+        return list;
+    }
+
+    private Statement compileSignal(Routine routine,
+                                    StatementCompound context,
+                                    HsqlName label) {
+
+        readThis(Tokens.SIGNAL);
+        readThis(Tokens.SQLSTATE);
+
+        String sqlState = parseSQLStateValue();
+        StatementSimple cs = new StatementSimple(StatementTypes.SIGNAL,
+            sqlState);
+
+        return cs;
+    }
+
+    private Statement compileResignal(Routine routine,
+                                      StatementCompound context,
+                                      HsqlName label) {
+
+        String sqlState = null;
+
+        readThis(Tokens.RESIGNAL);
+
+        if (readIfThis(Tokens.SQLSTATE)) {
+            sqlState = parseSQLStateValue();
+        }
+
+        StatementSimple cs = new StatementSimple(StatementTypes.RESIGNAL,
+            sqlState);
+
+        return cs;
+    }
+
+    private ColumnSchema readRoutineParameter(Routine routine,
+            boolean isParam) {
+
+        HsqlName hsqlName      = null;
+        byte     parameterMode = SchemaObject.ParameterModes.PARAM_IN;
+
+        if (isParam) {
+            switch (token.tokenType) {
+
+                case Tokens.IN :
+                    read();
+                    break;
+
+                case Tokens.OUT :
+                    if (routine.getType() != SchemaObject.PROCEDURE) {
+                        throw unexpectedToken();
+                    }
+
+                    read();
+
+                    parameterMode = SchemaObject.ParameterModes.PARAM_OUT;
+                    break;
+
+                case Tokens.INOUT :
+                    if (routine.getType() != SchemaObject.PROCEDURE) {
+                        if (!routine.isAggregate()) {
+                            throw unexpectedToken();
+                        }
+                    }
+
+                    read();
+
+                    parameterMode = SchemaObject.ParameterModes.PARAM_INOUT;
+                    break;
+
+                default :
+            }
+        }
+
+        if (!isReservedKey()) {
+            hsqlName = readNewDependentSchemaObjectName(routine.getName(),
+                    SchemaObject.PARAMETER);
+        }
+
+        Type typeObject = readTypeDefinition(true);
+        ColumnSchema column = new ColumnSchema(hsqlName, typeObject, true,
+                                               false, null);
+
+        if (isParam) {
+            column.setParameterMode(parameterMode);
+        }
+
+        return column;
+    }
+
+    void resolveOuterReferencesAndTypes(Routine routine,
+                                        StatementCompound context,
+                                        Expression e) {
+
+        RangeVariable[] rangeVars = routine.getParameterRangeVariables();
+
+        if (context != null) {
+            rangeVars = context.getRangeVariables();
+        }
+
+        resolveOuterReferencesAndTypes(rangeVars, e);
+    }
+}
diff --git a/src/org/hsqldb/QueryExpression.java b/src/org/hsqldb/QueryExpression.java
new file mode 100644
index 0000000..85ba024
--- /dev/null
+++ b/src/org/hsqldb/QueryExpression.java
@@ -0,0 +1,926 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayListIdentity;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.lib.Set;
+import org.hsqldb.navigator.RowSetNavigatorData;
+import org.hsqldb.navigator.RowSetNavigatorDataTable;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of an SQL query expression
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+
+/**
+ * @todo 1.9.0 - review these
+ * - work out usage of getMainSelect etc and add relevant methods
+ * - Result metadata for the final result of QueryExpression
+ *
+ */
+public class QueryExpression {
+
+    public static final int NOUNION       = 0,
+                            UNION         = 1,
+                            UNION_ALL     = 2,
+                            INTERSECT     = 3,
+                            INTERSECT_ALL = 4,
+                            EXCEPT_ALL    = 5,
+                            EXCEPT        = 6,
+                            UNION_TERM    = 7;
+
+    //
+    int                     columnCount;
+    private QueryExpression leftQueryExpression;
+    private QueryExpression rightQueryExpression;
+    SortAndSlice            sortAndSlice;
+    private int             unionType;
+    private boolean         unionCorresponding;
+    private OrderedHashSet  unionCorrespondingColumns;
+    int[]                   unionColumnMap;
+    Type[]                  unionColumnTypes;
+    boolean                 isFullOrder;
+
+    //
+    HsqlList unresolvedExpressions;
+
+    //
+    boolean isResolved;
+
+    //
+    int persistenceScope = TableBase.SCOPE_STATEMENT;
+
+    //
+    ResultMetaData resultMetaData;
+    boolean[]      accessibleColumns;
+
+    //
+    View    view;
+    boolean isMergeable;
+    boolean isUpdatable;
+    boolean isInsertable;
+    boolean isCheckable;
+    boolean isTopLevel;
+    boolean acceptsSequences;
+
+    //
+    public TableBase resultTable;
+    public Index     mainIndex;
+    public Index     fullIndex;
+    public Index     orderIndex;
+    public Index     idIndex;
+
+    //
+    CompileContext compileContext;
+
+    QueryExpression(CompileContext compileContext) {
+        this.compileContext = compileContext;
+        sortAndSlice        = SortAndSlice.noSort;
+    }
+
+    public QueryExpression(CompileContext compileContext,
+                           QueryExpression leftQueryExpression) {
+
+        this(compileContext);
+
+        sortAndSlice             = SortAndSlice.noSort;
+        this.leftQueryExpression = leftQueryExpression;
+    }
+
+    void addUnion(QueryExpression queryExpression, int unionType) {
+
+        sortAndSlice              = SortAndSlice.noSort;
+        this.rightQueryExpression = queryExpression;
+        this.unionType            = unionType;
+
+        setFullOrder();
+    }
+
+    void addSortAndSlice(SortAndSlice sortAndSlice) {
+        this.sortAndSlice      = sortAndSlice;
+        sortAndSlice.sortUnion = true;
+    }
+
+    public void setUnionCorresoponding() {
+        unionCorresponding = true;
+    }
+
+    public void setUnionCorrespondingColumns(OrderedHashSet names) {
+        unionCorrespondingColumns = names;
+    }
+
+    public void setFullOrder() {
+
+        isFullOrder = true;
+
+        if (leftQueryExpression == null) {
+            if (isResolved) {
+                ((QuerySpecification) this).createFullIndex(null);
+            }
+
+            return;
+        }
+
+        leftQueryExpression.setFullOrder();
+        rightQueryExpression.setFullOrder();
+    }
+
+    public void resolve(Session session) {
+
+        resolveReferences(session);
+        ExpressionColumn.checkColumnsResolved(unresolvedExpressions);
+        resolveTypes(session);
+    }
+
+    public void resolve(Session session, RangeVariable[] outerRanges,
+                        Type[] targetTypes) {
+
+        resolveReferences(session);
+
+        if (unresolvedExpressions != null) {
+            for (int i = 0; i < unresolvedExpressions.size(); i++) {
+                Expression e    = (Expression) unresolvedExpressions.get(i);
+                HsqlList   list = e.resolveColumnReferences(outerRanges, null);
+
+                ExpressionColumn.checkColumnsResolved(list);
+            }
+        }
+
+        resolveTypesPartOne(session);
+
+        for (int i = 0; i < unionColumnTypes.length && i < targetTypes.length;
+                i++) {
+            if (unionColumnTypes[i] == null) {
+                unionColumnTypes[i] = targetTypes[i];
+            }
+        }
+
+        resolveTypesPartTwo(session);
+    }
+
+    public void resolveReferences(Session session) {
+
+        leftQueryExpression.resolveReferences(session);
+        rightQueryExpression.resolveReferences(session);
+        addUnresolvedExpressions(leftQueryExpression.unresolvedExpressions);
+        addUnresolvedExpressions(rightQueryExpression.unresolvedExpressions);
+
+        if (!unionCorresponding) {
+            columnCount = leftQueryExpression.getColumnCount();
+
+            int rightCount = rightQueryExpression.getColumnCount();
+
+            if (columnCount != rightCount) {
+                throw Error.error(ErrorCode.X_42594);
+            }
+
+            unionColumnTypes = new Type[columnCount];
+            leftQueryExpression.unionColumnMap =
+                rightQueryExpression.unionColumnMap = new int[columnCount];
+
+            ArrayUtil.fillSequence(leftQueryExpression.unionColumnMap);
+            resolveColumnRefernecesInUnionOrderBy();
+
+            return;
+        }
+
+        String[] leftNames  = leftQueryExpression.getColumnNames();
+        String[] rightNames = rightQueryExpression.getColumnNames();
+
+        if (unionCorrespondingColumns == null) {
+            unionCorrespondingColumns = new OrderedHashSet();
+
+            OrderedIntHashSet leftColumns  = new OrderedIntHashSet();
+            OrderedIntHashSet rightColumns = new OrderedIntHashSet();
+
+            for (int i = 0; i < leftNames.length; i++) {
+                String name  = leftNames[i];
+                int    index = ArrayUtil.find(rightNames, name);
+
+                if (name.length() > 0 && index != -1) {
+                    if (!leftQueryExpression.accessibleColumns[i]) {
+                        throw Error.error(ErrorCode.X_42578);
+                    }
+
+                    if (!rightQueryExpression.accessibleColumns[index]) {
+                        throw Error.error(ErrorCode.X_42578);
+                    }
+
+                    leftColumns.add(i);
+                    rightColumns.add(index);
+                    unionCorrespondingColumns.add(name);
+                }
+            }
+
+            if (unionCorrespondingColumns.isEmpty()) {
+                throw Error.error(ErrorCode.X_42578);
+            }
+
+            leftQueryExpression.unionColumnMap  = leftColumns.toArray();
+            rightQueryExpression.unionColumnMap = rightColumns.toArray();
+        } else {
+            leftQueryExpression.unionColumnMap =
+                new int[unionCorrespondingColumns.size()];
+            rightQueryExpression.unionColumnMap =
+                new int[unionCorrespondingColumns.size()];
+
+            for (int i = 0; i < unionCorrespondingColumns.size(); i++) {
+                String name  = (String) unionCorrespondingColumns.get(i);
+                int    index = ArrayUtil.find(leftNames, name);
+
+                if (index == -1) {
+                    throw Error.error(ErrorCode.X_42501);
+                }
+
+                if (!leftQueryExpression.accessibleColumns[index]) {
+                    throw Error.error(ErrorCode.X_42578);
+                }
+
+                leftQueryExpression.unionColumnMap[i] = index;
+                index = ArrayUtil.find(rightNames, name);
+
+                if (index == -1) {
+                    throw Error.error(ErrorCode.X_42501);
+                }
+
+                if (!rightQueryExpression.accessibleColumns[index]) {
+                    throw Error.error(ErrorCode.X_42578);
+                }
+
+                rightQueryExpression.unionColumnMap[i] = index;
+            }
+        }
+
+        columnCount      = unionCorrespondingColumns.size();
+        unionColumnTypes = new Type[columnCount];
+
+        resolveColumnRefernecesInUnionOrderBy();
+    }
+
+    /**
+     * Only simple column reference or column position allowed
+     */
+    void resolveColumnRefernecesInUnionOrderBy() {
+
+        int orderCount = sortAndSlice.getOrderLength();
+
+        if (orderCount == 0) {
+            return;
+        }
+
+        String[] unionColumnNames = getColumnNames();
+
+        for (int i = 0; i < orderCount; i++) {
+            Expression sort = (Expression) sortAndSlice.exprList.get(i);
+            Expression e    = sort.getLeftNode();
+
+            if (e.getType() == OpTypes.VALUE) {
+                if (e.getDataType().typeCode == Types.SQL_INTEGER) {
+                    int index = ((Integer) e.getValue(null)).intValue();
+
+                    if (0 < index && index <= unionColumnNames.length) {
+                        sort.getLeftNode().queryTableColumnIndex = index - 1;
+
+                        continue;
+                    }
+                }
+            } else if (e.getType() == OpTypes.COLUMN) {
+                int index = ArrayUtil.find(unionColumnNames,
+                                           e.getColumnName());
+
+                if (index >= 0) {
+                    sort.getLeftNode().queryTableColumnIndex = index;
+
+                    continue;
+                }
+            }
+
+            throw Error.error(ErrorCode.X_42576);
+        }
+
+        sortAndSlice.prepare(null);
+    }
+
+    private void addUnresolvedExpressions(HsqlList expressions) {
+
+        if (expressions == null) {
+            return;
+        }
+
+        if (unresolvedExpressions == null) {
+            unresolvedExpressions = new ArrayListIdentity();
+        }
+
+        unresolvedExpressions.addAll(expressions);
+    }
+
+    public void resolveTypes(Session session) {
+
+        if (isResolved) {
+            return;
+        }
+
+        resolveTypesPartOne(session);
+        resolveTypesPartTwo(session);
+
+        isResolved = true;
+    }
+
+    void resolveTypesPartOne(Session session) {
+
+        ArrayUtil.projectRowReverse(leftQueryExpression.unionColumnTypes,
+                                    leftQueryExpression.unionColumnMap,
+                                    unionColumnTypes);
+        leftQueryExpression.resolveTypesPartOne(session);
+        ArrayUtil.projectRow(leftQueryExpression.unionColumnTypes,
+                             leftQueryExpression.unionColumnMap,
+                             unionColumnTypes);
+        ArrayUtil.projectRowReverse(rightQueryExpression.unionColumnTypes,
+                                    rightQueryExpression.unionColumnMap,
+                                    unionColumnTypes);
+        rightQueryExpression.resolveTypesPartOne(session);
+        ArrayUtil.projectRow(rightQueryExpression.unionColumnTypes,
+                             rightQueryExpression.unionColumnMap,
+                             unionColumnTypes);
+    }
+
+    void resolveTypesPartTwo(Session session) {
+
+        ArrayUtil.projectRowReverse(leftQueryExpression.unionColumnTypes,
+                                    leftQueryExpression.unionColumnMap,
+                                    unionColumnTypes);
+        leftQueryExpression.resolveTypesPartTwo(session);
+        ArrayUtil.projectRowReverse(rightQueryExpression.unionColumnTypes,
+                                    rightQueryExpression.unionColumnMap,
+                                    unionColumnTypes);
+        rightQueryExpression.resolveTypesPartTwo(session);
+
+        //
+        if (unionCorresponding) {
+            resultMetaData = leftQueryExpression.getMetaData().getNewMetaData(
+                leftQueryExpression.unionColumnMap);
+
+            createTable(session);
+        }
+
+        if (sortAndSlice.hasOrder()) {
+            QueryExpression queryExpression = this;
+
+            while (true) {
+                if (queryExpression.leftQueryExpression == null
+                        || queryExpression.unionCorresponding) {
+                    sortAndSlice.setIndex(session,
+                                          queryExpression.resultTable);
+
+                    break;
+                }
+
+                queryExpression = queryExpression.leftQueryExpression;
+            }
+        }
+
+        ResultMetaData meta = getMetaData();
+/*
+        // disallow lobs
+        for (int i = 0, count = meta.getColumnCount(); i < count; i++) {
+            Type dataType = meta.columnTypes[i];
+
+            if (dataType.isLobType()) {
+                throw Error.error(ErrorCode.X_42534);
+            }
+        }
+*/
+    }
+
+    public Object[] getValues(Session session) {
+
+        Result r    = getResult(session, 2);
+        int    size = r.getNavigator().getSize();
+
+        if (size == 0) {
+            return new Object[r.metaData.getColumnCount()];
+        } else if (size == 1) {
+            return r.getSingleRowData();
+        } else {
+            throw Error.error(ErrorCode.X_21000);
+        }
+    }
+
+    public Object[] getSingleRowValues(Session session) {
+
+        Result r    = getResult(session, 2);
+        int    size = r.getNavigator().getSize();
+
+        if (size == 0) {
+            return null;
+        } else if (size == 1) {
+            return r.getSingleRowData();
+        } else {
+            throw Error.error(ErrorCode.X_21000);
+        }
+    }
+
+    public Object getValue(Session session) {
+
+        Object[] values = getValues(session);
+
+        return values[0];
+    }
+
+    Result getResult(Session session, int maxRows) {
+
+        int    currentMaxRows = unionType == UNION_ALL ? maxRows
+                                                       : 0;
+        Result first = leftQueryExpression.getResult(session, currentMaxRows);
+        RowSetNavigatorData navigator =
+            (RowSetNavigatorData) first.getNavigator();
+        Result second = rightQueryExpression.getResult(session,
+            currentMaxRows);
+        RowSetNavigatorData rightNavigator =
+            (RowSetNavigatorData) second.getNavigator();
+
+        if (unionCorresponding) {
+            RowSetNavigatorData rowSet;
+            boolean memory =
+                session.resultMaxMemoryRows == 0
+                || (navigator.getSize() < session.resultMaxMemoryRows
+                    && rightNavigator.getSize() < session.resultMaxMemoryRows);
+
+            if (memory) {
+                rowSet = new RowSetNavigatorData(session, this);
+            } else {
+                rowSet = new RowSetNavigatorDataTable(session, this);
+            }
+
+            rowSet.copy(navigator, leftQueryExpression.unionColumnMap);
+
+            navigator = rowSet;
+
+            first.setNavigator(navigator);
+
+            first.metaData = this.getMetaData();
+
+            if (memory) {
+                rowSet = new RowSetNavigatorData(session, this);
+            } else {
+                rowSet = new RowSetNavigatorDataTable(session, this);
+            }
+
+            rowSet.copy(rightNavigator, rightQueryExpression.unionColumnMap);
+
+            rightNavigator = rowSet;
+        }
+
+        switch (unionType) {
+
+            case UNION :
+                navigator.union(rightNavigator);
+                break;
+
+            case UNION_ALL :
+                navigator.unionAll(rightNavigator);
+                break;
+
+            case INTERSECT :
+                navigator.intersect(rightNavigator);
+                break;
+
+            case INTERSECT_ALL :
+                navigator.intersectAll(rightNavigator);
+                break;
+
+            case EXCEPT :
+                navigator.except(rightNavigator);
+                break;
+
+            case EXCEPT_ALL :
+                navigator.exceptAll(rightNavigator);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "QueryExpression");
+        }
+
+        if (sortAndSlice.hasOrder()) {
+            navigator.sortUnion(sortAndSlice);
+        }
+
+        if (sortAndSlice.hasLimit()) {
+            navigator.trim(sortAndSlice.getLimitStart(session),
+                           sortAndSlice.getLimitCount(session, maxRows));
+        }
+
+        navigator.reset();
+
+        return first;
+    }
+
+    public OrderedHashSet getSubqueries() {
+
+        OrderedHashSet subqueries = leftQueryExpression.getSubqueries();
+
+        return OrderedHashSet.addAll(subqueries,
+                                     rightQueryExpression.getSubqueries());
+    }
+
+    public boolean isSingleColumn() {
+        return leftQueryExpression.isSingleColumn();
+    }
+
+    public ResultMetaData getMetaData() {
+
+        if (resultMetaData != null) {
+            return resultMetaData;
+        }
+
+        return leftQueryExpression.getMetaData();
+    }
+
+    public QuerySpecification getMainSelect() {
+
+        if (leftQueryExpression == null) {
+            return (QuerySpecification) this;
+        }
+
+        return leftQueryExpression.getMainSelect();
+    }
+
+    /** @todo 1.9.0 review */
+    public String describe(Session session, int blanks) {
+
+        StringBuffer sb;
+        String       temp;
+        String       b = ValuePool.spaceString.substring(0, blanks);
+
+        sb = new StringBuffer();
+
+        switch (unionType) {
+
+            case UNION :
+                temp = Tokens.T_UNION;
+                break;
+
+            case UNION_ALL :
+                temp = Tokens.T_UNION + ' ' + Tokens.T_ALL;
+                break;
+
+            case INTERSECT :
+                temp = Tokens.T_INTERSECT;
+                break;
+
+            case INTERSECT_ALL :
+                temp = Tokens.T_INTERSECT + ' ' + Tokens.T_ALL;
+                break;
+
+            case EXCEPT :
+                temp = Tokens.T_EXCEPT;
+                break;
+
+            case EXCEPT_ALL :
+                temp = Tokens.T_EXCEPT + ' ' + Tokens.T_ALL;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "QueryExpression");
+        }
+
+        sb.append(b).append(temp).append("\n");
+        sb.append(b).append("Left Query=[\n");
+        sb.append(b).append(leftQueryExpression.describe(session, blanks + 2));
+        sb.append(b).append("]\n");
+        sb.append(b).append("Right Query=[\n");
+        sb.append(b).append(rightQueryExpression.describe(session,
+                blanks + 2));
+        sb.append(b).append("]\n");
+
+        return sb.toString();
+    }
+
+    public HsqlList getUnresolvedExpressions() {
+        return unresolvedExpressions;
+    }
+
+    public boolean areColumnsResolved() {
+        return unresolvedExpressions == null
+               || unresolvedExpressions.isEmpty();
+    }
+
+    String[] getColumnNames() {
+
+        if (unionCorrespondingColumns == null) {
+            return leftQueryExpression.getColumnNames();
+        }
+
+        String[] names = new String[unionCorrespondingColumns.size()];
+
+        unionCorrespondingColumns.toArray(names);
+
+        return names;
+    }
+
+    public Type[] getColumnTypes() {
+        return unionColumnTypes;
+    }
+
+    public int getColumnCount() {
+
+        if (unionCorrespondingColumns == null) {
+            int left  = leftQueryExpression.getColumnCount();
+            int right = rightQueryExpression.getColumnCount();
+
+            if (left != right) {
+                throw Error.error(ErrorCode.X_42594);
+            }
+
+            return left;
+        }
+
+        return unionCorrespondingColumns.size();
+    }
+
+    public OrderedHashSet collectAllExpressions(OrderedHashSet set,
+            OrderedIntHashSet typeSet, OrderedIntHashSet stopAtTypeSet) {
+
+        set = leftQueryExpression.collectAllExpressions(set, typeSet,
+                stopAtTypeSet);
+
+        if (rightQueryExpression != null) {
+            set = rightQueryExpression.collectAllExpressions(set, typeSet,
+                    stopAtTypeSet);
+        }
+
+        return set;
+    }
+
+    public void collectObjectNames(Set set) {
+
+        leftQueryExpression.collectObjectNames(set);
+
+        if (rightQueryExpression != null) {
+            rightQueryExpression.collectObjectNames(set);
+        }
+    }
+
+    public HashMappedList getColumns() {
+
+        this.getResultTable();
+
+        return ((TableDerived) getResultTable()).columnList;
+    }
+
+    /**
+     * Used prior to type resolution
+     */
+    public void setView(View view) {
+
+        this.isUpdatable      = true;
+        this.view             = view;
+        this.acceptsSequences = true;
+        this.isTopLevel       = true;
+    }
+
+    /**
+     * Used in views after full type resolution
+     */
+    public void setTableColumnNames(HashMappedList list) {
+
+        if (resultTable != null) {
+            ((TableDerived) resultTable).columnList = list;
+
+            return;
+        }
+
+        leftQueryExpression.setTableColumnNames(list);
+    }
+
+    void createTable(Session session) {
+
+        createResultTable(session);
+
+        mainIndex = resultTable.getPrimaryIndex();
+
+        if (sortAndSlice.hasOrder()) {
+            orderIndex = resultTable.createAndAddIndexStructure(session, null,
+                    sortAndSlice.sortOrder, sortAndSlice.sortDescending,
+                    sortAndSlice.sortNullsLast, false, false, false);
+        }
+
+        int[] fullCols = new int[columnCount];
+
+        ArrayUtil.fillSequence(fullCols);
+
+        fullIndex = resultTable.createAndAddIndexStructure(session, null,
+                fullCols, null, null, false, false, false);
+        resultTable.fullIndex = fullIndex;
+    }
+
+    void createResultTable(Session session) {
+
+        HsqlName       tableName;
+        HashMappedList columnList;
+        int            tableType;
+
+        tableName = session.database.nameManager.getSubqueryTableName();
+        tableType = persistenceScope == TableBase.SCOPE_STATEMENT
+                    ? TableBase.SYSTEM_SUBQUERY
+                    : TableBase.RESULT_TABLE;
+        columnList = leftQueryExpression.getUnionColumns();
+
+        try {
+            resultTable = new TableDerived(session.database, tableName,
+                                           tableType, unionColumnTypes,
+                                           columnList, null, null);
+        } catch (Exception e) {}
+    }
+
+    public void setColumnsDefined() {
+
+        if (leftQueryExpression != null) {
+            leftQueryExpression.setColumnsDefined();
+        }
+    }
+
+    /**
+     * Not for views. Only used on root node.
+     */
+    public void setReturningResult() {
+
+        if (compileContext.getSequences().length > 0) {
+            throw Error.error(ErrorCode.X_42598);
+        }
+
+        isTopLevel = true;
+
+        setReturningResultSet();
+    }
+
+    /**
+     * Sets the scope to SESSION for the QueryExpression object that creates
+     * the table
+     */
+    void setReturningResultSet() {
+
+        if (unionCorresponding) {
+            persistenceScope = TableBase.SCOPE_SESSION;
+
+            return;
+        }
+
+        leftQueryExpression.setReturningResultSet();
+    }
+
+    private HashMappedList getUnionColumns() {
+
+        if (unionCorresponding || leftQueryExpression == null) {
+            HashMappedList columns = ((TableDerived) resultTable).columnList;
+            HashMappedList list    = new HashMappedList();
+
+            for (int i = 0; i < unionColumnMap.length; i++) {
+                ColumnSchema column = (ColumnSchema) columns.get(i);
+
+                list.add(column.getName().name, column);
+            }
+
+            return list;
+        }
+
+        return leftQueryExpression.getUnionColumns();
+    }
+
+    public HsqlName[] getResultColumnNames() {
+
+        if (resultTable == null) {
+            return leftQueryExpression.getResultColumnNames();
+        }
+
+        HashMappedList list = ((TableDerived) resultTable).columnList;
+        HsqlName[]     resultColumnNames = new HsqlName[list.size()];
+
+        for (int i = 0; i < resultColumnNames.length; i++) {
+            resultColumnNames[i] = ((ColumnSchema) list.get(i)).getName();
+        }
+
+        return resultColumnNames;
+    }
+
+    public TableBase getResultTable() {
+
+        if (resultTable != null) {
+            return resultTable;
+        }
+
+        if (leftQueryExpression != null) {
+            return leftQueryExpression.getResultTable();
+        }
+
+        return null;
+    }
+
+    //
+    public Table getBaseTable() {
+        return null;
+    }
+
+    public boolean isUpdatable() {
+        return isUpdatable;
+    }
+
+    public boolean isInsertable() {
+        return isInsertable;
+    }
+
+    public int[] getBaseTableColumnMap() {
+        return null;
+    }
+
+    public Expression getCheckCondition() {
+        return null;
+    }
+
+    public boolean hasReference(RangeVariable range) {
+
+        if (leftQueryExpression.hasReference(range)) {
+            return true;
+        }
+
+        if (rightQueryExpression.hasReference(range)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    void getBaseTableNames(OrderedHashSet set) {
+        leftQueryExpression.getBaseTableNames(set);
+        rightQueryExpression.getBaseTableNames(set);
+    }
+
+    boolean isEquivalent(QueryExpression other) {
+
+        return leftQueryExpression.isEquivalent(other.leftQueryExpression)
+               && unionType == other.unionType
+               && (rightQueryExpression == null
+                   ? other.rightQueryExpression == null
+                   : rightQueryExpression.isEquivalent(
+                       other.rightQueryExpression));
+    }
+
+    public void replaceColumnReference(RangeVariable range,
+                                       Expression[] list) {
+        leftQueryExpression.replaceColumnReference(range, list);
+        rightQueryExpression.replaceColumnReference(range, list);
+    }
+
+    public void replaceRangeVariables(RangeVariable[] ranges,
+                                      RangeVariable[] newRanges) {
+        leftQueryExpression.replaceRangeVariables(ranges, newRanges);
+        rightQueryExpression.replaceRangeVariables(ranges, newRanges);
+    }
+}
diff --git a/src/org/hsqldb/QuerySpecification.java b/src/org/hsqldb/QuerySpecification.java
new file mode 100644
index 0000000..bbae160
--- /dev/null
+++ b/src/org/hsqldb/QuerySpecification.java
@@ -0,0 +1,2285 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.HsqlNameManager.SimpleName;
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.RangeVariable.RangeIteratorRight;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayListIdentity;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.lib.Set;
+import org.hsqldb.navigator.RangeIterator;
+import org.hsqldb.navigator.RowSetNavigatorData;
+import org.hsqldb.navigator.RowSetNavigatorDataTable;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of an SQL query specification, including SELECT.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ *
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+public class QuerySpecification extends QueryExpression {
+
+    private final static int[] defaultLimits = new int[] {
+        0, Integer.MAX_VALUE, Integer.MAX_VALUE
+    };
+
+    //
+    public int            resultRangePosition;
+    public boolean        isDistinctSelect;
+    public boolean        isAggregated;
+    public boolean        isGrouped;
+    RangeVariable[]       rangeVariables;
+    private HsqlArrayList rangeVariableList;
+    Expression            queryCondition;
+    Expression            checkQueryCondition;
+    private Expression    havingCondition;
+    Expression            rowExpression;
+    Expression[]          exprColumns;
+    private HsqlArrayList exprColumnList;
+    public int            indexLimitVisible;
+    private int           indexLimitRowId;
+    private int           groupByColumnCount;    // columns in 'group by'
+    private int           havingColumnCount;     // columns in 'having' (0 or 1)
+    private int           indexStartHaving;
+    public int            indexStartOrderBy;
+    public int            indexStartAggregates;
+    private int           indexLimitExpressions;
+    public int            indexLimitData;
+    private boolean       hasRowID;
+    private boolean       isSimpleCount;
+    private boolean       hasMemoryRow;
+
+    //
+    public boolean  isUniqueResultRows;
+    private boolean simpleLimit = true;          // true if maxrows can be uses as is
+
+    //
+    Type[]                    columnTypes;
+    private ArrayListIdentity aggregateSet;
+
+    //
+    private ArrayListIdentity resolvedSubqueryExpressions = null;
+
+    //
+    //
+    private boolean[] aggregateCheck;
+
+    //
+    private OrderedHashSet tempSet = new OrderedHashSet();
+
+    //
+    int[]                  columnMap;
+    private Table          baseTable;
+    private OrderedHashSet conditionTables;      // for view super-view references
+
+    //
+    public Index groupIndex;
+
+    //
+    QuerySpecification(Session session, Table table,
+                       CompileContext compileContext) {
+
+        this(compileContext);
+
+        RangeVariable range = new RangeVariable(table, null, null, null,
+            compileContext);
+
+        range.addTableColumns(exprColumnList, 0, null);
+
+        indexLimitVisible = exprColumnList.size();
+
+        addRangeVariable(range);
+
+        isMergeable = false;
+
+        resolveReferences(session);
+        resolveTypes(session);
+
+        sortAndSlice = SortAndSlice.noSort;
+    }
+
+    QuerySpecification(CompileContext compileContext) {
+
+        super(compileContext);
+
+        this.compileContext = compileContext;
+        resultRangePosition = compileContext.getNextRangeVarIndex();
+        rangeVariableList   = new HsqlArrayList();
+        exprColumnList      = new HsqlArrayList();
+        sortAndSlice        = SortAndSlice.noSort;
+        isMergeable         = true;
+    }
+
+    void addRangeVariable(RangeVariable rangeVar) {
+        rangeVariableList.add(rangeVar);
+    }
+
+    // range variable sub queries are resolves fully
+    private void resolveRangeVariables(Session session) {
+
+        if (rangeVariables == null
+                || rangeVariables.length < rangeVariableList.size()) {
+            rangeVariables = new RangeVariable[rangeVariableList.size()];
+
+            rangeVariableList.toArray(rangeVariables);
+        }
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            rangeVariables[i].resolveRangeTable(session, rangeVariables, i);
+        }
+    }
+
+    void addSelectColumnExpression(Expression e) {
+
+        if (e.getType() == OpTypes.ROW) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        if (indexLimitVisible > 0) {
+            if (e.opType == OpTypes.MULTICOLUMN) {
+                if (((ExpressionColumn) e).getTableName() == null) {
+                    throw Error.error(ErrorCode.X_42578);
+                }
+            }
+
+            Expression first = ((Expression) exprColumnList.get(0));
+
+            if (first.opType == OpTypes.MULTICOLUMN
+                    && ((ExpressionColumn) first).getTableName() == null) {
+                throw Error.error(ErrorCode.X_42578);
+            }
+        }
+
+        exprColumnList.add(e);
+
+        indexLimitVisible++;
+    }
+
+    void addQueryCondition(Expression e) {
+        queryCondition = e;
+    }
+
+    void addGroupByColumnExpression(Expression e) {
+
+        if (e.getType() == OpTypes.ROW) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        exprColumnList.add(e);
+
+        isGrouped = true;
+
+        groupByColumnCount++;
+    }
+
+    void addHavingExpression(Expression e) {
+
+        exprColumnList.add(e);
+
+        havingCondition   = e;
+        havingColumnCount = 1;
+    }
+
+    void addSortAndSlice(SortAndSlice sortAndSlice) {
+        this.sortAndSlice = sortAndSlice;
+    }
+
+    public void resolveReferences(Session session) {
+
+        resolveRangeVariables(session);
+        resolveColumnReferencesForAsterisk();
+        finaliseColumns();
+        resolveColumnReferences();
+
+        unionColumnTypes = new Type[indexLimitVisible];
+
+        setReferenceableColumns();
+    }
+
+    /**
+     * Resolves all column expressions in the GROUP BY clause and beyond.
+     * Replaces any alias column expression in the ORDER BY cluase
+     * with the actual select column expression.
+     */
+    private void resolveColumnReferences() {
+
+        if (isDistinctSelect || isGrouped) {
+            acceptsSequences = false;
+        }
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            Expression e = rangeVariables[i].getJoinCondition();
+
+            if (e == null) {
+                continue;
+            }
+
+            resolveColumnReferencesAndAllocate(e, i + 1, false);
+        }
+
+        resolveColumnReferencesAndAllocate(queryCondition,
+                                           rangeVariables.length, false);
+
+        if (resolvedSubqueryExpressions != null) {
+
+            // subqueries in conditions not to be converted to SIMPLE_COLUMN
+            resolvedSubqueryExpressions.setSize(0);
+        }
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            resolveColumnReferencesAndAllocate(exprColumns[i],
+                                               rangeVariables.length,
+                                               acceptsSequences);
+        }
+
+        for (int i = indexLimitVisible; i < indexStartHaving; i++) {
+            exprColumns[i] = resolveColumnReferencesInGroupBy(exprColumns[i]);
+        }
+
+        for (int i = indexStartHaving; i < indexStartOrderBy; i++) {
+            resolveColumnReferencesAndAllocate(exprColumns[i],
+                                               rangeVariables.length, false);
+        }
+
+        resolveColumnRefernecesInOrderBy(sortAndSlice);
+    }
+
+    void resolveColumnRefernecesInOrderBy(SortAndSlice sortAndSlice) {
+
+        // replace the aliases with expressions
+        // replace column names with expressions and resolve the table columns
+        int orderCount = sortAndSlice.getOrderLength();
+
+        for (int i = 0; i < orderCount; i++) {
+            ExpressionOrderBy e =
+                (ExpressionOrderBy) sortAndSlice.exprList.get(i);
+
+            replaceColumnIndexInOrderBy(e);
+
+            if (e.getLeftNode().queryTableColumnIndex != -1) {
+                continue;
+            }
+
+            if (sortAndSlice.sortUnion) {
+                if (e.getLeftNode().getType() != OpTypes.COLUMN) {
+                    throw Error.error(ErrorCode.X_42576);
+                }
+            }
+
+            e.replaceAliasInOrderBy(exprColumns, indexLimitVisible);
+            resolveColumnReferencesAndAllocate(e, rangeVariables.length,
+                                               false);
+
+            if (isAggregated || isGrouped) {
+                boolean check = e.getLeftNode().isComposedOf(exprColumns, 0,
+                    indexLimitVisible + groupByColumnCount,
+                    Expression.aggregateFunctionSet);
+
+                if (!check) {
+                    throw Error.error(ErrorCode.X_42576);
+                }
+            }
+        }
+
+        sortAndSlice.prepare(this);
+    }
+
+    private boolean resolveColumnReferences(Expression e, int rangeCount,
+            boolean withSequences) {
+
+        if (e == null) {
+            return true;
+        }
+
+        int oldSize = unresolvedExpressions == null ? 0
+                                                    : unresolvedExpressions
+                                                        .size();
+
+        unresolvedExpressions = e.resolveColumnReferences(rangeVariables,
+                rangeCount, unresolvedExpressions, withSequences);
+
+        int newSize = unresolvedExpressions == null ? 0
+                                                    : unresolvedExpressions
+                                                        .size();
+
+        return oldSize == newSize;
+    }
+
+    private void resolveColumnReferencesForAsterisk() {
+
+        for (int pos = 0; pos < indexLimitVisible; ) {
+            Expression e = (Expression) (exprColumnList.get(pos));
+
+            if (e.getType() == OpTypes.MULTICOLUMN) {
+                exprColumnList.remove(pos);
+
+                String tablename = ((ExpressionColumn) e).getTableName();
+
+                if (tablename == null) {
+                    addAllJoinedColumns(e);
+                } else {
+                    int rangeIndex =
+                        e.findMatchingRangeVariableIndex(rangeVariables);
+
+                    if (rangeIndex == -1) {
+                        throw Error.error(ErrorCode.X_42501, tablename);
+                    }
+
+                    RangeVariable range   = rangeVariables[rangeIndex];
+                    HashSet       exclude = getAllNamedJoinColumns();
+
+                    range.addTableColumns(e, exclude);
+                }
+
+                for (int i = 0; i < e.nodes.length; i++) {
+                    exprColumnList.add(pos, e.nodes[i]);
+
+                    pos++;
+                }
+
+                indexLimitVisible += e.nodes.length - 1;
+            } else {
+                pos++;
+            }
+        }
+    }
+
+    private void resolveColumnReferencesAndAllocate(Expression expression,
+            int count, boolean withSequences) {
+
+        if (expression == null) {
+            return;
+        }
+
+        HsqlList list = expression.resolveColumnReferences(rangeVariables,
+            count, null, withSequences);
+
+        if (list != null) {
+            for (int i = 0; i < list.size(); i++) {
+                Expression e = (Expression) list.get(i);
+                boolean    resolved;
+
+                if (e.isSelfAggregate()) {
+                    resolved = resolveColumnReferences(e.getLeftNode(), count,
+                                                       false);
+                } else {
+                    resolved = resolveColumnReferences(e, count,
+                                                       withSequences);
+                }
+
+                if (resolved) {
+                    if (e.isSelfAggregate()) {
+                        if (aggregateSet == null) {
+                            aggregateSet = new ArrayListIdentity();
+                        }
+
+                        aggregateSet.add(e);
+
+                        isAggregated = true;
+
+                        expression.setAggregate();
+                    }
+
+                    if (resolvedSubqueryExpressions == null) {
+                        resolvedSubqueryExpressions = new ArrayListIdentity();
+                    }
+
+                    resolvedSubqueryExpressions.add(e);
+                } else {
+                    if (unresolvedExpressions == null) {
+                        unresolvedExpressions = new ArrayListIdentity();
+                    }
+
+                    unresolvedExpressions.add(e);
+                }
+            }
+        }
+    }
+
+    private Expression resolveColumnReferencesInGroupBy(
+            Expression expression) {
+
+        if (expression == null) {
+            return null;
+        }
+
+        HsqlList list = expression.resolveColumnReferences(rangeVariables,
+            rangeVariables.length, null, false);
+
+        if (list != null) {
+
+            // if not resolved, resolve as simple alias
+            if (expression.getType() == OpTypes.COLUMN) {
+                Expression resolved =
+                    expression.replaceAliasInOrderBy(exprColumns,
+                                                     indexLimitVisible);
+
+                if (resolved != expression) {
+                    return resolved;
+                }
+            }
+
+            // resolve and allocate to throw exception
+            resolveColumnReferencesAndAllocate(expression,
+                                               rangeVariables.length, false);
+        }
+
+        return expression;
+    }
+
+    private HashSet getAllNamedJoinColumns() {
+
+        HashSet set = null;
+
+        for (int i = 0; i < rangeVariableList.size(); i++) {
+            RangeVariable range = (RangeVariable) rangeVariableList.get(i);
+
+            if (range.namedJoinColumns != null) {
+                if (set == null) {
+                    set = new HashSet();
+                }
+
+                set.addAll(range.namedJoinColumns);
+            }
+        }
+
+        return set;
+    }
+
+    public Expression getEquiJoinExpressions(OrderedHashSet nameSet,
+            RangeVariable rightRange, boolean fullList) {
+
+        HashSet        set             = new HashSet();
+        Expression     result          = null;
+        OrderedHashSet joinColumnNames = new OrderedHashSet();
+
+        for (int i = 0; i < rangeVariableList.size(); i++) {
+            RangeVariable  range = (RangeVariable) rangeVariableList.get(i);
+            HashMappedList columnList = range.rangeTable.columnList;
+
+            for (int j = 0; j < columnList.size(); j++) {
+                ColumnSchema column       = (ColumnSchema) columnList.get(j);
+                String       name         = range.getColumnAlias(j);
+                boolean      columnInList = nameSet.contains(name);
+                boolean namedJoin = range.namedJoinColumns != null
+                                    && range.namedJoinColumns.contains(name);
+                boolean repeated = !namedJoin && !set.add(name);
+
+                if (repeated && (!fullList || columnInList)) {
+                    throw Error.error(ErrorCode.X_42578, name);
+                }
+
+                if (!columnInList) {
+                    continue;
+                }
+
+                joinColumnNames.add(name);
+
+                int leftPosition =
+                    range.rangeTable.getColumnIndex(column.getNameString());
+                int rightPosition = rightRange.rangeTable.getColumnIndex(name);
+                Expression e = new ExpressionLogical(range, leftPosition,
+                                                     rightRange,
+                                                     rightPosition);
+
+                result = ExpressionLogical.andExpressions(result, e);
+
+                ExpressionColumn col = range.getColumnExpression(name);
+
+                if (col == null) {
+                    col = new ExpressionColumn(new Expression[] {
+                        e.getLeftNode(), e.getRightNode()
+                    }, name);
+
+                    range.addNamedJoinColumnExpression(name, col);
+                } else {
+                    col.nodes = (Expression[]) ArrayUtil.resizeArray(col.nodes,
+                            col.nodes.length + 1);
+                    col.nodes[col.nodes.length - 1] = e.getRightNode();
+                }
+
+                rightRange.addNamedJoinColumnExpression(name, col);
+            }
+        }
+
+        if (fullList && !joinColumnNames.containsAll(nameSet)) {
+            throw Error.error(ErrorCode.X_42501);
+        }
+
+        rightRange.addNamedJoinColumns(joinColumnNames);
+
+        return result;
+    }
+
+    private void addAllJoinedColumns(Expression e) {
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            rangeVariables[i].addTableColumns(list);
+        }
+
+        Expression[] nodes = new Expression[list.size()];
+
+        list.toArray(nodes);
+
+        e.nodes = nodes;
+    }
+
+    private void finaliseColumns() {
+
+        indexLimitRowId   = indexLimitVisible;
+        indexStartHaving  = indexLimitRowId + groupByColumnCount;
+        indexStartOrderBy = indexStartHaving + havingColumnCount;
+        indexStartAggregates = indexStartOrderBy
+                               + sortAndSlice.getOrderLength();
+        indexLimitData = indexLimitExpressions = indexStartAggregates;
+        exprColumns    = new Expression[indexLimitExpressions];
+
+        exprColumnList.toArray(exprColumns);
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            exprColumns[i].queryTableColumnIndex = i;
+        }
+
+        if (sortAndSlice.hasOrder()) {
+            for (int i = 0; i < sortAndSlice.getOrderLength(); i++) {
+                exprColumns[indexStartOrderBy + i] =
+                    (Expression) sortAndSlice.exprList.get(i);
+            }
+        }
+
+        rowExpression = new Expression(OpTypes.ROW, exprColumns);
+    }
+
+    private void replaceColumnIndexInOrderBy(Expression orderBy) {
+
+        Expression e = orderBy.getLeftNode();
+
+        if (e.getType() != OpTypes.VALUE) {
+            return;
+        }
+
+        if (e.getDataType().typeCode == Types.SQL_INTEGER) {
+            int i = ((Integer) e.getValue(null)).intValue();
+
+            if (0 < i && i <= indexLimitVisible) {
+                orderBy.setLeftNode(exprColumns[i - 1]);
+
+                return;
+            }
+        }
+
+        throw Error.error(ErrorCode.X_42576);
+    }
+
+    void collectRangeVariables(RangeVariable[] rangeVars, Set set) {
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            exprColumns[i].collectRangeVariables(rangeVars, set);
+        }
+
+        if (queryCondition != null) {
+            queryCondition.collectRangeVariables(rangeVars, set);
+        }
+
+        if (havingCondition != null) {
+            havingCondition.collectRangeVariables(rangeVars, set);
+        }
+    }
+
+    public boolean hasReference(RangeVariable range) {
+
+        if (unresolvedExpressions == null) {
+            return false;
+        }
+
+        for (int i = 0; i < unresolvedExpressions.size(); i++) {
+            if (((Expression) unresolvedExpressions.get(i)).hasReference(
+                    range)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Sets the types of all the expressions used in this SELECT list.
+     */
+    public void resolveExpressionTypes(Session session, Expression parent) {
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            Expression e = exprColumns[i];
+
+            e.resolveTypes(session, parent);
+
+            if (e.getType() == OpTypes.ROW) {
+                throw Error.error(ErrorCode.X_42564);
+            }
+        }
+
+        for (int i = 0, len = rangeVariables.length; i < len; i++) {
+            Expression e = rangeVariables[i].getJoinCondition();
+
+            if (e != null) {
+                e.resolveTypes(session, null);
+
+                if (e.getDataType() != Type.SQL_BOOLEAN) {
+                    throw Error.error(ErrorCode.X_42568);
+                }
+            }
+        }
+
+        if (queryCondition != null) {
+            queryCondition.resolveTypes(session, null);
+
+            if (queryCondition.getDataType() != Type.SQL_BOOLEAN) {
+                throw Error.error(ErrorCode.X_42568);
+            }
+        }
+
+        if (havingCondition != null) {
+            havingCondition.resolveTypes(session, null);
+
+            if (havingCondition.getDataType() != Type.SQL_BOOLEAN) {
+                throw Error.error(ErrorCode.X_42568);
+            }
+        }
+    }
+
+    private void resolveAggregates() {
+
+        tempSet.clear();
+
+        if (isAggregated) {
+            aggregateCheck = new boolean[indexStartAggregates];
+
+            tempSet.addAll(aggregateSet);
+
+            indexLimitData = indexLimitExpressions = exprColumns.length
+                    + tempSet.size();
+            exprColumns = (Expression[]) ArrayUtil.resizeArray(exprColumns,
+                    indexLimitExpressions);
+
+            for (int i = indexStartAggregates, j = 0;
+                    i < indexLimitExpressions; i++, j++) {
+                Expression e = (Expression) tempSet.get(j);
+
+                exprColumns[i]          = e.duplicate();
+                exprColumns[i].nodes    = e.nodes;    // keep original nodes
+                exprColumns[i].dataType = e.dataType;
+            }
+
+            tempSet.clear();
+        }
+    }
+
+    public boolean areColumnsResolved() {
+        return unresolvedExpressions == null
+               || unresolvedExpressions.isEmpty();
+    }
+
+    private void setRangeVariableConditions(Session session) {
+
+        RangeVariableResolver rangeResolver =
+            new RangeVariableResolver(rangeVariables, queryCondition,
+                                      compileContext);
+
+        rangeResolver.processConditions(session);
+
+        rangeVariables = rangeResolver.rangeVariables;
+    }
+
+    public void resolveTypes(Session session) {
+
+        if (isResolved) {
+            return;
+        }
+
+        resolveTypesPartOne(session);
+        resolveTypesPartTwo(session);
+        ArrayUtil.copyArray(resultTable.colTypes, unionColumnTypes,
+                            unionColumnTypes.length);
+
+        for (int i = 0; i < indexStartHaving; i++) {
+            if (exprColumns[i].dataType == null) {
+                throw Error.error(ErrorCode.X_42567);
+            }
+        }
+    }
+
+    void resolveTypesPartOne(Session session) {
+
+        resolveExpressionTypes(session, rowExpression);
+        resolveAggregates();
+
+        for (int i = 0; i < unionColumnTypes.length; i++) {
+            unionColumnTypes[i] = Type.getAggregateType(unionColumnTypes[i],
+                    exprColumns[i].getDataType());
+        }
+    }
+
+    void resolveTypesPartTwo(Session session) {
+
+        resolveGroups();
+
+        for (int i = 0; i < unionColumnTypes.length; i++) {
+            Type type = unionColumnTypes[i];
+
+            if (type == null) {
+                throw Error.error(ErrorCode.X_42567);
+            }
+
+            exprColumns[i].setDataType(session, type);
+        }
+
+        for (int i = 0; i < indexStartHaving; i++) {
+            if (exprColumns[i].dataType == null) {
+                throw Error.error(ErrorCode.X_42567);
+            }
+        }
+
+        checkLobUsage();
+        setMergeability();
+        setUpdatability();
+        createResultMetaData();
+        createTable(session);
+
+        if (isMergeable) {
+            mergeQuery();
+        }
+
+        setRangeVariableConditions(session);
+
+        if (isAggregated && !isGrouped && !sortAndSlice.hasOrder()
+                && !sortAndSlice.hasLimit() && aggregateSet.size() == 1
+                && indexLimitVisible == 1) {
+            Expression e      = exprColumns[indexStartAggregates];
+            int        opType = e.getType();
+
+            switch (opType) {
+
+                case OpTypes.MAX :
+                case OpTypes.MIN : {
+                    SortAndSlice slice = new SortAndSlice();
+
+                    slice.isGenerated = true;
+
+                    slice.addLimitCondition(ExpressionOp.limitOneExpression);
+
+                    if (slice.prepareSpecial(session, this)) {
+                        this.sortAndSlice = slice;
+                    }
+
+                    break;
+                }
+                case OpTypes.COUNT : {
+                    if (rangeVariables.length == 1 && queryCondition == null
+                            && e.getLeftNode().getType() == OpTypes.ASTERISK) {
+                        isSimpleCount = true;
+                    }
+                }
+            }
+        }
+
+        sortAndSlice.setSortRange(this);
+
+        isResolved = true;
+    }
+
+    void checkLobUsage() {
+
+        if (!isDistinctSelect && !isGrouped) {
+            return;
+        }
+
+        for (int i = 0; i < indexStartHaving; i++) {
+            if (exprColumns[i].dataType.isLobType()) {
+                throw Error.error(ErrorCode.X_42534);
+            }
+        }
+    }
+
+    private void resolveGroups() {
+
+        // - 1.9.0 is standard compliant but has more extended support for
+        //   referencing columns
+        // - check there is no direct aggregate expression in group by
+        // - check each expression in select list can be
+        //   decomposed into the expressions in group by or any aggregates
+        //   this allows direct function of group by expressions, but
+        //   doesn't allow indirect functions. e.g.
+        //     select 2*abs(cola) , sum(colb) from t group by abs(cola) // ok
+        //     select 2*(cola + 10) , sum(colb) from t group by cola + 10 // ok
+        //     select abs(cola) , sum(colb) from t group by cola // ok
+        //     select 2*cola + 20 , sum(colb) from t group by cola + 10 // not allowed although correct
+        //     select cola , sum(colb) from t group by abs(cola) // not allowed because incorrect
+        // - group by can introduce invisible, derived columns into the query table
+        // - check the having expression can be decomposed into
+        //   select list expresions plus group by expressions
+        // - having cannot introduce additional, derived columns
+        // - having cannot reference columns not in the select or group by list
+        // - if there is any aggregate in select list but no group by, no
+        //   non-aggregates is allowed
+        // - check order by columns
+        // - if distinct select, order by must be composed of the select list columns
+        // - if grouped by, then order by should be decomposed into the
+        //   select list plus group by list
+        // - references to column aliases are allowed only in order by (Standard
+        //   compliance) and take precendence over references to non-alias
+        //   column names.
+        // - references to table / correlation and column list in correlation
+        //   names are handled according to the Standard
+        //  fredt@users
+        tempSet.clear();
+
+        if (isGrouped) {
+            for (int i = indexLimitVisible;
+                    i < indexLimitVisible + groupByColumnCount; i++) {
+                exprColumns[i].collectAllExpressions(
+                    tempSet, Expression.aggregateFunctionSet,
+                    Expression.subqueryExpressionSet);
+
+                if (!tempSet.isEmpty()) {
+                    throw Error.error(ErrorCode.X_42572,
+                                      ((Expression) tempSet.get(0)).getSQL());
+                }
+            }
+
+            for (int i = 0; i < indexLimitVisible; i++) {
+                if (!exprColumns[i].isComposedOf(
+                        exprColumns, indexLimitVisible,
+                        indexLimitVisible + groupByColumnCount,
+                        Expression.subqueryAggregateExpressionSet)) {
+                    tempSet.add(exprColumns[i]);
+                }
+            }
+
+            if (!tempSet.isEmpty() && !resolveForGroupBy(tempSet)) {
+                throw Error.error(ErrorCode.X_42574,
+                                  ((Expression) tempSet.get(0)).getSQL());
+            }
+        } else if (isAggregated) {
+            for (int i = 0; i < indexLimitVisible; i++) {
+                exprColumns[i].collectAllExpressions(
+                    tempSet, Expression.columnExpressionSet,
+                    Expression.aggregateFunctionSet);
+
+                if (!tempSet.isEmpty()) {
+                    throw Error.error(ErrorCode.X_42574,
+                                      ((Expression) tempSet.get(0)).getSQL());
+                }
+            }
+        }
+
+        tempSet.clear();
+
+        if (havingCondition != null) {
+            if (unresolvedExpressions != null) {
+                tempSet.addAll(unresolvedExpressions);
+            }
+
+            for (int i = indexLimitVisible;
+                    i < indexLimitVisible + groupByColumnCount; i++) {
+                tempSet.add(exprColumns[i]);
+            }
+
+            if (!havingCondition.isComposedOf(
+                    tempSet, Expression.subqueryAggregateExpressionSet)) {
+                throw Error.error(ErrorCode.X_42573);
+            }
+
+            tempSet.clear();
+        }
+
+        if (isDistinctSelect) {
+            int orderCount = sortAndSlice.getOrderLength();
+
+            for (int i = 0; i < orderCount; i++) {
+                Expression e = (Expression) sortAndSlice.exprList.get(i);
+
+                if (e.queryTableColumnIndex != -1) {
+                    continue;
+                }
+
+                if (!e.isComposedOf(exprColumns, 0, indexLimitVisible,
+                                    Expression.emptyExpressionSet)) {
+                    throw Error.error(ErrorCode.X_42576);
+                }
+            }
+        }
+
+        if (isGrouped) {
+            int orderCount = sortAndSlice.getOrderLength();
+
+            for (int i = 0; i < orderCount; i++) {
+                Expression e = (Expression) sortAndSlice.exprList.get(i);
+
+                if (e.queryTableColumnIndex != -1) {
+                    continue;
+                }
+
+                if (!e.isAggregate()
+                        && !e.isComposedOf(
+                            exprColumns, 0,
+                            indexLimitVisible + groupByColumnCount,
+                            Expression.emptyExpressionSet)) {
+                    throw Error.error(ErrorCode.X_42576);
+                }
+            }
+        }
+
+        if (isDistinctSelect || isGrouped) {
+            simpleLimit = false;
+        }
+
+        if (!isAggregated) {
+            return;
+        }
+
+        OrderedHashSet expressions       = new OrderedHashSet();
+        OrderedHashSet columnExpressions = new OrderedHashSet();
+
+        for (int i = indexStartAggregates; i < indexLimitExpressions; i++) {
+            Expression e = exprColumns[i];
+            Expression c = new ExpressionColumn(e, i, resultRangePosition);
+
+            expressions.add(e);
+            columnExpressions.add(c);
+        }
+
+        for (int i = 0; i < indexStartHaving; i++) {
+            if (exprColumns[i].isAggregate()) {
+                continue;
+            }
+
+            Expression e = exprColumns[i];
+
+            if (expressions.add(e)) {
+                Expression c = new ExpressionColumn(e, i, resultRangePosition);
+
+                columnExpressions.add(c);
+            }
+        }
+
+        // order by with aggregate
+        int orderCount = sortAndSlice.getOrderLength();
+
+        for (int i = 0; i < orderCount; i++) {
+            Expression e = (Expression) sortAndSlice.exprList.get(i);
+
+            if (e.getLeftNode().isAggregate()) {
+                e.setAggregate();
+            }
+        }
+
+        for (int i = indexStartOrderBy; i < indexStartAggregates; i++) {
+            if (exprColumns[i].getLeftNode().isAggregate()) {
+                exprColumns[i].setAggregate();
+            }
+        }
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            Expression e = exprColumns[i];
+
+            if (!e.isAggregate() && !e.isCorrelated() ) {
+                continue;
+            }
+
+            aggregateCheck[i] = true;
+
+            if (e.isAggregate()) {
+                e.convertToSimpleColumn(expressions, columnExpressions);
+            }
+        }
+
+        for (int i = 0; i < aggregateSet.size(); i++) {
+            Expression e = (Expression) aggregateSet.get(i);
+
+            e.convertToSimpleColumn(expressions, columnExpressions);
+        }
+
+        if (resolvedSubqueryExpressions != null) {
+            for (int i = 0; i < resolvedSubqueryExpressions.size(); i++) {
+                Expression e = (Expression) resolvedSubqueryExpressions.get(i);
+
+                e.convertToSimpleColumn(expressions, columnExpressions);
+            }
+        }
+    }
+
+    boolean resolveForGroupBy(HsqlList unresolvedSet) {
+
+        for (int i = indexLimitVisible;
+                i < indexLimitVisible + groupByColumnCount; i++) {
+            Expression e = exprColumns[i];
+
+            if (e.getType() == OpTypes.COLUMN) {
+                RangeVariable range    = e.getRangeVariable();
+                int           colIndex = e.getColumnIndex();
+
+                range.columnsInGroupBy[colIndex] = true;
+            }
+        }
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            RangeVariable range = rangeVariables[i];
+
+            range.hasKeyedColumnInGroupBy =
+                range.rangeTable.getUniqueNotNullColumnGroup(
+                    range.columnsInGroupBy) != null;
+        }
+
+        OrderedHashSet set = null;
+
+        for (int i = 0; i < unresolvedSet.size(); i++) {
+            Expression e = (Expression) unresolvedSet.get(i);
+
+            set = e.getUnkeyedColumns(set);
+        }
+
+        return set == null;
+    }
+
+    int[] getLimits(Session session, int maxRows) {
+
+        int     skipRows   = 0;
+        int     limitRows  = Integer.MAX_VALUE;
+        int     limitFetch = Integer.MAX_VALUE;
+        boolean hasLimits  = false;
+
+        if (sortAndSlice.hasLimit()) {
+            Integer value =
+                (Integer) sortAndSlice.limitCondition.getLeftNode().getValue(
+                    session);
+
+            if (value == null || value.intValue() < 0) {
+                throw Error.error(ErrorCode.X_2201X);
+            }
+
+            skipRows  = value.intValue();
+            hasLimits = skipRows != 0;
+
+            if (sortAndSlice.limitCondition.getRightNode() != null) {
+                value =
+                    (Integer) sortAndSlice.limitCondition.getRightNode()
+                        .getValue(session);
+
+                if (value == null || value.intValue() <= 0) {
+                    throw Error.error(ErrorCode.X_2201W);
+                }
+
+                if (value.intValue() == 0) {
+                    limitRows = Integer.MAX_VALUE;
+                } else {
+                    limitRows = value.intValue();
+                    hasLimits = true;
+                }
+            }
+        }
+
+        if (maxRows != 0) {
+            if (maxRows < limitRows) {
+                limitRows = maxRows;
+            }
+
+            hasLimits = true;
+        }
+
+        if (hasLimits && simpleLimit
+                && (!sortAndSlice.hasOrder() || sortAndSlice.skipSort)
+                && (!sortAndSlice.hasLimit() || sortAndSlice.skipFullResult)) {
+            if (limitFetch - skipRows > limitRows) {
+                limitFetch = skipRows + limitRows;
+            }
+        }
+
+        return hasLimits ? new int[] {
+            skipRows, limitRows, limitFetch
+        }
+                         : defaultLimits;
+    }
+
+    /**
+     * Returns the result of executing this Select.
+     *
+     * @param maxrows may be 0 to indicate no limit on the number of rows.
+     * Positive values limit the size of the result set.
+     * @return the result of executing this Select
+     */
+    Result getResult(Session session, int maxrows) {
+
+        Result r = getSingleResult(session, maxrows);
+
+        r.getNavigator().reset();
+
+        return r;
+    }
+
+    private Result getSingleResult(Session session, int maxRows) {
+
+        int[]               limits    = getLimits(session, maxRows);
+        Result              r         = buildResult(session, limits[2]);
+        RowSetNavigatorData navigator = (RowSetNavigatorData) r.getNavigator();
+
+        if (isDistinctSelect) {
+            navigator.removeDuplicates();
+        }
+
+        if (sortAndSlice.hasOrder()) {
+            navigator.sortOrder();
+        }
+
+        if (limits != defaultLimits) {
+            navigator.trim(limits[0], limits[1]);
+        }
+
+        return r;
+    }
+
+    private Result buildResult(Session session, int limitcount) {
+
+        RowSetNavigatorData navigator = new RowSetNavigatorData(session,
+            (QuerySpecification) this);
+        Result result = Result.newResult(navigator);
+
+        result.metaData = resultMetaData;
+
+        if (isUpdatable) {
+            result.rsProperties = ResultProperties.updatablePropsValue;
+        }
+
+        if (this.isSimpleCount) {
+            Object[]        data  = new Object[indexLimitData];
+            Table           table = rangeVariables[0].getTable();
+            PersistentStore store = table.getRowStore(session);
+            int             count = table.getIndex(0).size(session, store);
+
+            data[0] = data[indexStartAggregates] = ValuePool.getInt(count);
+
+            navigator.add(data);
+
+            return result;
+        }
+
+        int fullJoinIndex = 0;
+        RangeIterator[] rangeIterators =
+            new RangeIterator[rangeVariables.length];
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            rangeIterators[i] = rangeVariables[i].getIterator(session);
+        }
+
+        for (int currentIndex = 0; ; ) {
+            if (currentIndex < fullJoinIndex) {
+
+                // finished current span
+                // or finished outer rows on right navigator
+                boolean end = true;
+
+                for (int i = fullJoinIndex + 1; i < rangeVariables.length;
+                        i++) {
+                    if (rangeVariables[i].isRightJoin) {
+                        fullJoinIndex = i;
+                        currentIndex  = i;
+                        end           = false;
+
+                        ((RangeIteratorRight) rangeIterators[i])
+                            .setOnOuterRows();
+
+                        break;
+                    }
+                }
+
+                if (end) {
+                    break;
+                }
+            }
+
+            RangeIterator it = rangeIterators[currentIndex];
+
+            if (it.next()) {
+                if (currentIndex < rangeVariables.length - 1) {
+                    currentIndex++;
+
+                    continue;
+                }
+            } else {
+                it.reset();
+
+                currentIndex--;
+
+                continue;
+            }
+
+            session.sessionData.startRowProcessing();
+
+            Object[] data = new Object[indexLimitData];
+
+            for (int i = 0; i < indexStartAggregates; i++) {
+                if (isAggregated && aggregateCheck[i]) {
+                    continue;
+                } else {
+                    data[i] = exprColumns[i].getValue(session);
+                }
+            }
+
+            for (int i = indexLimitVisible; i < indexLimitRowId; i++) {
+                if (i == indexLimitVisible) {
+                    data[i] = it.getRowidObject();
+                } else {
+                    data[i] = it.getCurrentRow();
+                }
+            }
+
+            Object[] groupData = null;
+
+            if (isAggregated || isGrouped) {
+                groupData = navigator.getGroupData(data);
+
+                if (groupData != null) {
+                    data = groupData;
+                }
+            }
+
+            for (int i = indexStartAggregates; i < indexLimitExpressions;
+                    i++) {
+                data[i] = exprColumns[i].updateAggregatingValue(session,
+                        data[i]);
+            }
+
+            if (groupData == null) {
+                navigator.add(data);
+            } else if (isAggregated) {
+                navigator.update(groupData, data);
+            }
+
+            int rowCount = navigator.getSize();
+
+            if (rowCount == session.resultMaxMemoryRows && !isAggregated
+                    && !hasMemoryRow) {
+                navigator = new RowSetNavigatorDataTable(session, this,
+                        navigator);
+
+                result.setNavigator(navigator);
+            }
+
+            if (isAggregated || isGrouped) {
+                if (!sortAndSlice.isGenerated) {
+                    continue;
+                }
+            }
+
+            if (rowCount >= limitcount) {
+                break;
+            }
+        }
+
+        navigator.reset();
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            rangeIterators[i].reset();
+        }
+
+        if (!isGrouped && !isAggregated) {
+            return result;
+        }
+
+        if (isAggregated) {
+            if (!isGrouped && navigator.getSize() == 0) {
+                Object[] data = new Object[exprColumns.length];
+
+                navigator.add(data);
+            }
+
+            navigator.reset();
+            session.sessionContext.setRangeIterator(navigator);
+
+            while (navigator.next()) {
+                Object[] data = navigator.getCurrent();
+
+                for (int i = indexStartAggregates; i < indexLimitExpressions;
+                        i++) {
+                    data[i] = exprColumns[i].getAggregatedValue(session,
+                            data[i]);
+                }
+
+                for (int i = 0; i < indexStartAggregates; i++) {
+                    if (aggregateCheck[i]) {
+                        data[i] = exprColumns[i].getValue(session);
+                    }
+                }
+            }
+        }
+
+        navigator.reset();
+
+        if (havingCondition != null) {
+            while (navigator.hasNext()) {
+                Object[] data = (Object[]) navigator.getNext();
+
+                if (!Boolean.TRUE.equals(
+                        data[indexLimitVisible + groupByColumnCount])) {
+                    navigator.remove();
+                }
+            }
+
+            navigator.reset();
+        }
+
+        return result;
+    }
+
+    void setReferenceableColumns() {
+
+        accessibleColumns = new boolean[indexLimitVisible];
+
+        IntValueHashMap aliases = new IntValueHashMap();
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            Expression expression = exprColumns[i];
+            String     alias      = expression.getAlias();
+
+            if (alias.length() == 0) {
+                SimpleName name = HsqlNameManager.getAutoColumnName(i);
+
+                expression.setAlias(name);
+
+                continue;
+            }
+
+            int index = aliases.get(alias, -1);
+
+            if (index == -1) {
+                aliases.put(alias, i);
+
+                accessibleColumns[i] = true;
+            } else {
+                accessibleColumns[index] = false;
+            }
+        }
+    }
+
+    void setColumnAliases(SimpleName[] names) {
+
+        if (names.length != indexLimitVisible) {
+            throw Error.error(ErrorCode.X_42593);
+        }
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            exprColumns[i].setAlias(names[i]);
+        }
+    }
+
+    private void createResultMetaData() {
+
+        columnTypes = new Type[indexLimitData];
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            Expression e = exprColumns[i];
+
+            columnTypes[i] = e.getDataType();
+        }
+
+        for (int i = indexLimitVisible; i < indexLimitRowId; i++) {
+            if (i == indexLimitVisible) {
+                columnTypes[i] = Type.SQL_BIGINT;
+            } else {
+                columnTypes[i] = Type.SQL_ALL_TYPES;
+            }
+        }
+
+        for (int i = indexLimitRowId; i < indexLimitData; i++) {
+            Expression e = exprColumns[i];
+
+            columnTypes[i] = e.getDataType();
+        }
+
+        resultMetaData = ResultMetaData.newResultMetaData(columnTypes,
+                columnMap, indexLimitVisible, indexLimitRowId);
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            Expression e = exprColumns[i];
+
+            resultMetaData.columnTypes[i] = e.getDataType();
+
+            if (i < indexLimitVisible) {
+                ColumnBase column = e.getColumn();
+
+                if (column != null) {
+                    resultMetaData.columns[i]      = column;
+                    resultMetaData.columnLabels[i] = e.getAlias();
+
+                    continue;
+                }
+
+                column = new ColumnBase();
+
+                column.setType(e.getDataType());
+
+                resultMetaData.columns[i]      = column;
+                resultMetaData.columnLabels[i] = e.getAlias();
+            }
+        }
+    }
+
+    void createTable(Session session) {
+
+        createResultTable(session);
+
+        mainIndex = resultTable.getPrimaryIndex();
+
+        if (sortAndSlice.hasOrder() && !sortAndSlice.skipSort) {
+            orderIndex = resultTable.createAndAddIndexStructure(session, null,
+                    sortAndSlice.sortOrder, sortAndSlice.sortDescending,
+                    sortAndSlice.sortNullsLast, false, false, false);
+        }
+
+        if (isDistinctSelect || isFullOrder) {
+            createFullIndex(session);
+        }
+
+        if (isGrouped) {
+            int[] groupCols = new int[groupByColumnCount];
+
+            for (int i = 0; i < groupByColumnCount; i++) {
+                groupCols[i] = indexLimitVisible + i;
+            }
+
+            groupIndex = resultTable.createAndAddIndexStructure(session, null,
+                    groupCols, null, null, false, false, false);
+        } else if (isAggregated) {
+            groupIndex = mainIndex;
+        }
+
+        if (isUpdatable && view == null) {
+            int[] idCols = new int[]{ indexLimitVisible };
+
+            idIndex = resultTable.createAndAddIndexStructure(session, null,
+                    idCols, null, null, false, false, false);
+        }
+    }
+
+    void createFullIndex(Session session) {
+
+        int[] fullCols = new int[indexLimitVisible];
+
+        ArrayUtil.fillSequence(fullCols);
+
+        fullIndex = resultTable.createAndAddIndexStructure(session, null,
+                fullCols, null, null, false, false, false);
+        resultTable.fullIndex = fullIndex;
+    }
+
+    void createResultTable(Session session) {
+
+        HsqlName       tableName;
+        HashMappedList columnList;
+        int            tableType;
+
+        tableName = session.database.nameManager.getSubqueryTableName();
+        tableType = persistenceScope == TableBase.SCOPE_STATEMENT
+                    ? TableBase.SYSTEM_SUBQUERY
+                    : TableBase.RESULT_TABLE;
+        columnList = new HashMappedList();
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            Expression e          = exprColumns[i];
+            SimpleName simpleName = e.getSimpleName();
+            String     nameString = simpleName.name;
+            HsqlName name =
+                session.database.nameManager.newColumnSchemaHsqlName(tableName,
+                    simpleName);
+
+            if (!accessibleColumns[i]) {
+                nameString = HsqlNameManager.getAutoNoNameColumnString(i);
+            }
+
+            ColumnSchema column = new ColumnSchema(name, e.dataType, true,
+                                                   false, null);
+
+            columnList.add(nameString, column);
+        }
+
+        try {
+            resultTable = new TableDerived(session.database, tableName,
+                                           tableType, columnTypes, columnList,
+                                           null, null);
+        } catch (Exception e) {}
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+        int          limit;
+
+        sb.append(Tokens.T_SELECT).append(' ');
+
+        limit = indexLimitVisible;
+
+        for (int i = 0; i < limit; i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+
+            sb.append(exprColumns[i].getSQL());
+        }
+
+        sb.append(Tokens.T_FROM);
+
+        limit = rangeVariables.length;
+
+        for (int i = 0; i < limit; i++) {
+            RangeVariable rangeVar = rangeVariables[i];
+
+            if (i > 0) {
+                if (rangeVar.isLeftJoin && rangeVar.isRightJoin) {
+                    sb.append(Tokens.T_FULL).append(' ');
+                } else if (rangeVar.isLeftJoin) {
+                    sb.append(Tokens.T_LEFT).append(' ');
+                } else if (rangeVar.isRightJoin) {
+                    sb.append(Tokens.T_RIGHT).append(' ');
+                }
+
+                sb.append(Tokens.T_JOIN).append(' ');
+            }
+
+            sb.append(rangeVar.getTable().getName().statementName);
+        }
+
+        if (isGrouped) {
+            sb.append(' ').append(Tokens.T_GROUP).append(' ').append(
+                Tokens.T_BY);
+
+            limit = indexLimitVisible + groupByColumnCount;
+
+            for (int i = indexLimitVisible; i < limit; i++) {
+                sb.append(exprColumns[i].getSQL());
+
+                if (i < limit - 1) {
+                    sb.append(',');
+                }
+            }
+        }
+
+        if (havingCondition != null) {
+            sb.append(' ').append(Tokens.T_HAVING).append(' ');
+            sb.append(havingCondition.getSQL());
+        }
+
+        if (sortAndSlice.hasOrder()) {
+            limit = indexStartOrderBy + sortAndSlice.getOrderLength();
+
+            sb.append(' ').append(Tokens.T_ORDER).append(Tokens.T_BY).append(
+                ' ');
+
+            for (int i = indexStartOrderBy; i < limit; i++) {
+                sb.append(exprColumns[i].getSQL());
+
+                if (i < limit - 1) {
+                    sb.append(',');
+                }
+            }
+        }
+
+        if (sortAndSlice.hasLimit()) {
+            sb.append(sortAndSlice.limitCondition.getLeftNode().getSQL());
+        }
+
+        return sb.toString();
+    }
+
+    public ResultMetaData getMetaData() {
+        return resultMetaData;
+    }
+
+    public String describe(Session session, int blanks) {
+
+        StringBuffer sb;
+        String       temp;
+        String       b = ValuePool.spaceString.substring(0, blanks);
+
+        sb = new StringBuffer();
+
+        sb.append(b).append("isDistinctSelect=[").append(
+            isDistinctSelect).append("]\n");
+        sb.append(b).append("isGrouped=[").append(isGrouped).append("]\n");
+        sb.append(b).append("isAggregated=[").append(isAggregated).append(
+            "]\n");
+        sb.append(b).append("columns=[");
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            int index = i;
+
+            if (exprColumns[i].getType() == OpTypes.SIMPLE_COLUMN) {
+                index = exprColumns[i].columnIndex;
+            }
+
+            sb.append(b).append(exprColumns[index].describe(session, 2));
+        }
+
+        sb.append("\n");
+        sb.append(b).append("]\n");
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            sb.append(b).append("[");
+            sb.append("range variable ").append(i + 1).append("\n");
+            sb.append(rangeVariables[i].describe(session, blanks + 2));
+            sb.append(b).append("]");
+        }
+
+        sb.append(b).append("]\n");
+
+        temp = queryCondition == null ? "null"
+                                      : queryCondition.describe(session,
+                                      blanks);
+
+        if (isGrouped) {
+            sb.append(b).append("groupColumns=[");
+
+            for (int i = indexLimitRowId;
+                    i < indexLimitRowId + groupByColumnCount; i++) {
+                int index = i;
+
+                if (exprColumns[i].getType() == OpTypes.SIMPLE_COLUMN) {
+                    index = exprColumns[i].columnIndex;
+                }
+
+                sb.append(exprColumns[index].describe(session, blanks));
+            }
+
+            sb.append(b).append("]\n");
+        }
+
+        if (havingCondition != null) {
+            temp = havingCondition.describe(session, blanks);
+
+            sb.append(b).append("havingCondition=[").append(temp).append(
+                "]\n");
+        }
+
+        if (sortAndSlice.hasOrder()) {
+            sb.append(b).append("order by=[\n");
+
+            for (int i = 0; i < sortAndSlice.exprList.size(); i++) {
+                sb.append(b).append(
+                    ((Expression) sortAndSlice.exprList.get(i)).describe(
+                        session, blanks));
+                sb.append(b).append("\n]");
+            }
+
+            sb.append(b).append("]\n");
+        }
+
+        if (sortAndSlice.hasLimit()) {
+            if (sortAndSlice.limitCondition.getLeftNode() != null) {
+                sb.append(b).append("offset=[").append(
+                    sortAndSlice.limitCondition.getLeftNode().describe(
+                        session, 0)).append("]\n");
+            }
+
+            if (sortAndSlice.limitCondition.getRightNode() != null) {
+                sb.append(b).append("limit=[").append(
+                    sortAndSlice.limitCondition.getRightNode().describe(
+                        session, 0)).append("]\n");
+            }
+        }
+
+        return sb.toString();
+    }
+
+    void setMergeability() {
+
+        if (isGrouped || isDistinctSelect) {
+            isMergeable = false;
+
+            return;
+        }
+
+        if (sortAndSlice.hasLimit() || sortAndSlice.hasOrder()) {
+            isMergeable = false;
+
+            return;
+        }
+
+        if (rangeVariables.length != 1) {
+            isMergeable = false;
+
+            return;
+        }
+    }
+
+    void setUpdatability() {
+
+        if (!isUpdatable) {
+            return;
+        }
+
+        isUpdatable = false;
+
+        if (!isMergeable) {
+            return;
+        }
+
+        if (!isTopLevel) {
+            return;
+        }
+
+        if (isAggregated) {
+            return;
+        }
+
+        if (sortAndSlice.hasLimit() || sortAndSlice.hasOrder()) {
+            return;
+        }
+
+        RangeVariable rangeVar  = rangeVariables[0];
+        Table         table     = rangeVar.getTable();
+        Table         baseTable = table.getBaseTable();
+
+        if (baseTable == null) {
+            return;
+        }
+
+        isInsertable = table.isInsertable();
+        isUpdatable  = table.isUpdatable();
+
+        if (!isInsertable && !isUpdatable) {
+            return;
+        }
+
+        IntValueHashMap columns = new IntValueHashMap();
+        boolean[]       checkList;
+        int[]           baseColumnMap = table.getBaseTableColumnMap();
+        int[]           columnMap     = new int[indexLimitVisible];
+
+        if (queryCondition != null) {
+            tempSet.clear();
+            collectSubQueriesAndReferences(tempSet, queryCondition);
+
+            if (tempSet.contains(table.getName())
+                    || tempSet.contains(baseTable.getName())) {
+                isUpdatable  = false;
+                isInsertable = false;
+
+                return;
+            }
+        }
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            Expression expression = exprColumns[i];
+
+            if (expression.getType() == OpTypes.COLUMN) {
+                String name = expression.getColumn().getName().name;
+
+                if (columns.containsKey(name)) {
+                    columns.put(name, 1);
+
+                    continue;
+                }
+
+                columns.put(name, 0);
+            } else {
+                tempSet.clear();
+                collectSubQueriesAndReferences(tempSet, expression);
+
+                if (tempSet.contains(table.getName())) {
+                    isUpdatable  = false;
+                    isInsertable = false;
+
+                    return;
+                }
+            }
+        }
+
+        isUpdatable = false;
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            if (accessibleColumns[i]) {
+                Expression expression = exprColumns[i];
+
+                if (expression.getType() == OpTypes.COLUMN) {
+                    String name = expression.getColumn().getName().name;
+
+                    if (columns.get(name) == 0) {
+                        int index = table.findColumn(name);
+
+                        columnMap[i] = baseColumnMap[index];
+
+                        if (columnMap[i] != -1) {
+                            isUpdatable = true;
+                        }
+
+                        continue;
+                    }
+                }
+            }
+
+            columnMap[i] = -1;
+            isInsertable = false;
+        }
+
+        if (isInsertable) {
+            checkList = baseTable.getColumnCheckList(columnMap);
+
+            for (int i = 0; i < checkList.length; i++) {
+                if (checkList[i]) {
+                    continue;
+                }
+
+                ColumnSchema column = baseTable.getColumn(i);
+
+                if (column.isIdentity() || column.isGenerated()
+                        || column.hasDefault() || column.isNullable()) {}
+                else {
+                    isInsertable = false;
+
+                    break;
+                }
+            }
+        }
+
+        if (!isUpdatable) {
+            isInsertable = false;
+        }
+
+        if (isUpdatable) {
+            this.columnMap = columnMap;
+            this.baseTable = baseTable;
+
+            if (view != null) {
+                return;
+            }
+
+            indexLimitRowId++;
+
+            hasRowID = true;
+
+            if (!baseTable.isFileBased()) {
+                indexLimitRowId++;
+
+                hasMemoryRow = true;
+            }
+
+            indexLimitData = indexLimitRowId;
+        }
+    }
+
+    void mergeQuery() {
+
+        RangeVariable rangeVar            = rangeVariables[0];
+        Table         table               = rangeVar.getTable();
+        Expression    localQueryCondition = queryCondition;
+
+        if (table instanceof TableDerived) {
+            QueryExpression baseQueryExpression =
+                ((TableDerived) table).getQueryExpression();
+
+            if (baseQueryExpression == null || !baseQueryExpression.isMergeable) {
+                isMergeable = false;
+
+                return;
+            }
+
+            QuerySpecification baseSelect =
+                baseQueryExpression.getMainSelect();
+
+            if (baseQueryExpression.view == null) {
+                rangeVariables[0] = baseSelect.rangeVariables[0];
+
+                rangeVariables[0].resetConditions();
+
+                Expression[] newExprColumns = new Expression[indexLimitData];
+
+                for (int i = 0; i < indexLimitData; i++) {
+                    Expression e = exprColumns[i];
+
+                    newExprColumns[i] = e.replaceColumnReferences(rangeVar,
+                            baseSelect.exprColumns);
+                }
+
+                exprColumns = newExprColumns;
+
+                if (localQueryCondition != null) {
+                    localQueryCondition =
+                        localQueryCondition.replaceColumnReferences(rangeVar,
+                            baseSelect.exprColumns);
+                }
+
+                Expression baseQueryCondition = baseSelect.queryCondition;
+
+                checkQueryCondition = baseSelect.checkQueryCondition;
+                queryCondition =
+                    ExpressionLogical.andExpressions(baseQueryCondition,
+                                                     localQueryCondition);
+            } else {
+                RangeVariable[] newRangeVariables = new RangeVariable[1];
+
+                newRangeVariables[0] =
+                    baseSelect.rangeVariables[0].duplicate();
+
+                Expression[] newBaseExprColumns =
+                    new Expression[baseSelect.indexLimitData];
+
+                for (int i = 0; i < baseSelect.indexLimitData; i++) {
+                    Expression e = baseSelect.exprColumns[i].duplicate();
+
+                    newBaseExprColumns[i] = e;
+
+                    e.replaceRangeVariables(baseSelect.rangeVariables,
+                                            newRangeVariables);
+                }
+
+                for (int i = 0; i < indexLimitData; i++) {
+                    Expression e = exprColumns[i];
+
+                    exprColumns[i] = e.replaceColumnReferences(rangeVar,
+                            newBaseExprColumns);
+                }
+
+                Expression baseQueryCondition = baseSelect.queryCondition;
+
+                if (baseQueryCondition != null) {
+                    baseQueryCondition = baseQueryCondition.duplicate();
+
+                    baseQueryCondition.replaceRangeVariables(
+                        baseSelect.rangeVariables, newRangeVariables);
+                }
+
+                if (localQueryCondition != null) {
+                    localQueryCondition =
+                        localQueryCondition.replaceColumnReferences(rangeVar,
+                            newBaseExprColumns);
+                }
+
+                checkQueryCondition = baseSelect.checkQueryCondition;
+
+                if (checkQueryCondition != null) {
+                    checkQueryCondition = checkQueryCondition.duplicate();
+
+                    checkQueryCondition.replaceRangeVariables(
+                        baseSelect.rangeVariables, newRangeVariables);
+                }
+
+                queryCondition =
+                    ExpressionLogical.andExpressions(baseQueryCondition,
+                                                     localQueryCondition);
+                rangeVariables = newRangeVariables;
+            }
+        }
+
+        if (view != null) {
+            switch (view.getCheckOption()) {
+
+                case SchemaObject.ViewCheckModes.CHECK_LOCAL :
+                    if (!isUpdatable) {
+                        throw Error.error(ErrorCode.X_42537);
+                    }
+
+                    checkQueryCondition = localQueryCondition;
+                    break;
+
+                case SchemaObject.ViewCheckModes.CHECK_CASCADE :
+                    if (!isUpdatable) {
+                        throw Error.error(ErrorCode.X_42537);
+                    }
+
+                    checkQueryCondition = queryCondition;
+                    break;
+            }
+        }
+
+        if (isAggregated) {
+            isMergeable = false;
+        }
+    }
+
+    static void collectSubQueriesAndReferences(OrderedHashSet set,
+            Expression expression) {
+
+        expression.collectAllExpressions(set,
+                                         Expression.subqueryExpressionSet,
+                                         Expression.emptyExpressionSet);
+
+        int size = set.size();
+
+        for (int i = 0; i < size; i++) {
+            Expression e = (Expression) set.get(i);
+
+            e.collectObjectNames(set);
+        }
+    }
+
+    public OrderedHashSet getSubqueries() {
+
+        OrderedHashSet set = null;
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            set = exprColumns[i].collectAllSubqueries(set);
+        }
+
+        if (queryCondition != null) {
+            set = queryCondition.collectAllSubqueries(set);
+        }
+
+        if (havingCondition != null) {
+            set = havingCondition.collectAllSubqueries(set);
+        }
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            OrderedHashSet temp = rangeVariables[i].getSubqueries();
+
+            set = OrderedHashSet.addAll(set, temp);
+        }
+
+        return set;
+    }
+
+    public Table getBaseTable() {
+        return baseTable;
+    }
+
+    public OrderedHashSet collectAllSubqueries(OrderedHashSet set) {
+        return set;
+    }
+
+    public OrderedHashSet collectAllExpressions(OrderedHashSet set,
+            OrderedIntHashSet typeSet, OrderedIntHashSet stopAtTypeSet) {
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            set = exprColumns[i].collectAllExpressions(set, typeSet,
+                    stopAtTypeSet);
+        }
+
+        if (queryCondition != null) {
+            set = queryCondition.collectAllExpressions(set, typeSet,
+                    stopAtTypeSet);
+        }
+
+        if (havingCondition != null) {
+            set = havingCondition.collectAllExpressions(set, typeSet,
+                    stopAtTypeSet);
+        }
+
+        return set;
+    }
+
+    public void collectObjectNames(Set set) {
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            exprColumns[i].collectObjectNames(set);
+        }
+
+        if (queryCondition != null) {
+            queryCondition.collectObjectNames(set);
+        }
+
+        if (havingCondition != null) {
+            havingCondition.collectObjectNames(set);
+        }
+
+        for (int i = 0, len = rangeVariables.length; i < len; i++) {
+            HsqlName name = rangeVariables[i].getTable().getName();
+
+            set.add(name);
+        }
+    }
+
+    public void replaceColumnReference(RangeVariable range,
+                                       Expression[] list) {
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            exprColumns[i].replaceColumnReferences(range, list);
+        }
+
+        if (queryCondition != null) {
+            queryCondition.replaceColumnReferences(range, list);
+        }
+
+        if (havingCondition != null) {
+            havingCondition.replaceColumnReferences(range, list);
+        }
+
+        for (int i = 0, len = rangeVariables.length; i < len; i++) {
+
+            //
+        }
+    }
+
+    public void replaceRangeVariables(RangeVariable[] ranges,
+                                      RangeVariable[] newRanges) {
+
+        for (int i = 0; i < indexStartAggregates; i++) {
+            exprColumns[i].replaceRangeVariables(ranges, newRanges);
+        }
+
+        if (queryCondition != null) {
+            queryCondition.replaceRangeVariables(ranges, newRanges);
+        }
+
+        if (havingCondition != null) {
+            havingCondition.replaceRangeVariables(ranges, newRanges);
+        }
+
+        for (int i = 0, len = rangeVariables.length; i < len; i++) {
+            rangeVariables[i].getSubqueries();
+        }
+    }
+
+    /**
+     * Not for views. Only used on root node.
+     */
+    public void setReturningResult() {
+
+        setReturningResultSet();
+
+        acceptsSequences = true;
+        isTopLevel       = true;
+    }
+
+    void setReturningResultSet() {
+        persistenceScope = TableBase.SCOPE_SESSION;
+    }
+
+    public boolean isSingleColumn() {
+        return indexLimitVisible == 1;
+    }
+
+    public String[] getColumnNames() {
+
+        String[] names = new String[indexLimitVisible];
+
+        for (int i = 0; i < indexLimitVisible; i++) {
+            names[i] = exprColumns[i].getAlias();
+        }
+
+        return names;
+    }
+
+    public Type[] getColumnTypes() {
+
+        if (columnTypes.length == indexLimitVisible) {
+            return columnTypes;
+        }
+
+        Type[] types = new Type[indexLimitVisible];
+
+        ArrayUtil.copyArray(columnTypes, types, types.length);
+
+        return types;
+    }
+
+    public int getColumnCount() {
+        return indexLimitVisible;
+    }
+
+    public int[] getBaseTableColumnMap() {
+        return columnMap;
+    }
+
+    public Expression getCheckCondition() {
+        return queryCondition;
+    }
+
+    void getBaseTableNames(OrderedHashSet set) {
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            Table    rangeTable = rangeVariables[i].rangeTable;
+            HsqlName name       = rangeTable.getName();
+
+            if (rangeTable.isReadOnly() || rangeTable.isTemp()) {
+                continue;
+            }
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            set.add(name);
+        }
+    }
+
+    /**
+     * returns true if almost equivalent
+     */
+    boolean isEquivalent(QueryExpression other) {
+
+        if (!(other instanceof QuerySpecification)) {
+            return false;
+        }
+
+        QuerySpecification otherSpec = (QuerySpecification) other;
+
+        if (!Expression.equals(exprColumns, otherSpec.exprColumns)) {
+            return false;
+        }
+
+        if (!Expression.equals(queryCondition, otherSpec.queryCondition)) {
+            return false;
+        }
+
+        if (rangeVariables.length != otherSpec.rangeVariables.length) {
+            return false;
+        }
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            if (rangeVariables[i].getTable()
+                    != otherSpec.rangeVariables[i].getTable()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/RangeVariable.java b/src/org/hsqldb/RangeVariable.java
new file mode 100644
index 0000000..377d19b
--- /dev/null
+++ b/src/org/hsqldb/RangeVariable.java
@@ -0,0 +1,1576 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.SimpleName;
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.navigator.RangeIterator;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ * Metadata for range variables, including conditions.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+public final class RangeVariable implements Cloneable {
+
+    static final RangeVariable[] emptyArray = new RangeVariable[]{};
+
+    //
+    final Table            rangeTable;
+    final SimpleName       tableAlias;
+    private OrderedHashSet columnAliases;
+    private SimpleName[]   columnAliasNames;
+    private OrderedHashSet columnNames;
+    OrderedHashSet         namedJoinColumns;
+    HashMap                namedJoinColumnExpressions;
+    private Object[]       emptyData;
+    boolean[]              columnsInGroupBy;
+    boolean                hasKeyedColumnInGroupBy;
+    boolean[]              usedColumns;
+    boolean[]              updatedColumns;
+
+    //
+    RangeVariableConditions[] joinConditions;
+    RangeVariableConditions[] whereConditions;
+    int                       subRangeCount;
+
+    // non-index conditions
+    Expression joinCondition;
+
+    //
+    boolean isLeftJoin;     // table joined with LEFT / FULL OUTER JOIN
+    boolean isRightJoin;    // table joined with RIGHT / FULL OUTER JOIN
+    boolean isBoundary;
+
+    //
+    int level;
+
+    //
+    int rangePosition;
+
+    //
+    int parsePosition;
+
+    // for variable and argument lists
+    HashMappedList variables;
+
+    // variable v.s. argument
+    boolean isVariable;
+
+    //
+    boolean isGenerated;
+
+    RangeVariable(HashMappedList variables, boolean isVariable) {
+
+        this.variables   = variables;
+        this.isVariable  = isVariable;
+        rangeTable       = null;
+        tableAlias       = null;
+        emptyData        = null;
+        columnsInGroupBy = null;
+        usedColumns      = null;
+        joinConditions = new RangeVariableConditions[]{
+            new RangeVariableConditions(this, true) };
+        whereConditions = new RangeVariableConditions[]{
+            new RangeVariableConditions(this, false) };
+    }
+
+    RangeVariable(Table table, SimpleName alias, OrderedHashSet columnList,
+                  SimpleName[] columnNameList, CompileContext compileContext) {
+
+        rangeTable       = table;
+        tableAlias       = alias;
+        columnAliases    = columnList;
+        columnAliasNames = columnNameList;
+        joinConditions = new RangeVariableConditions[]{
+            new RangeVariableConditions(this, true) };
+        whereConditions = new RangeVariableConditions[]{
+            new RangeVariableConditions(this, false) };
+
+        compileContext.registerRangeVariable(this);
+
+        SubQuery subQuery = rangeTable.getSubQuery();
+
+        if (subQuery == null || subQuery.isResolved()) {
+            setRangeTableVariables();
+        }
+    }
+
+    RangeVariable(Table table, int position) {
+
+        rangeTable       = table;
+        tableAlias       = null;
+        emptyData        = rangeTable.getEmptyRowData();
+        columnsInGroupBy = rangeTable.getNewColumnCheckList();
+        usedColumns      = rangeTable.getNewColumnCheckList();
+        rangePosition    = position;
+        joinConditions = new RangeVariableConditions[]{
+            new RangeVariableConditions(this, true) };
+        whereConditions = new RangeVariableConditions[]{
+            new RangeVariableConditions(this, false) };
+    }
+
+    public void setRangeTableVariables() {
+
+        if (columnAliasNames != null
+                && rangeTable.getColumnCount() != columnAliasNames.length) {
+            throw Error.error(ErrorCode.X_42593);
+        }
+
+        emptyData                    = rangeTable.getEmptyRowData();
+        columnsInGroupBy             = rangeTable.getNewColumnCheckList();
+        usedColumns                  = rangeTable.getNewColumnCheckList();
+        joinConditions[0].rangeIndex = rangeTable.getPrimaryIndex();
+    }
+
+    public RangeVariable duplicate() {
+
+        RangeVariable r = null;
+
+        try {
+            r = (RangeVariable) super.clone();
+        } catch (CloneNotSupportedException ex) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
+        }
+
+        r.resetConditions();
+
+        return r;
+    }
+
+    void setJoinType(boolean isLeft, boolean isRight) {
+
+        isLeftJoin  = isLeft;
+        isRightJoin = isRight;
+
+        if (isRightJoin) {
+            whereConditions[0].rangeIndex = rangeTable.getPrimaryIndex();
+        }
+    }
+
+    public void addNamedJoinColumns(OrderedHashSet columns) {
+        namedJoinColumns = columns;
+    }
+
+    public void addColumn(int columnIndex) {
+        usedColumns[columnIndex] = true;
+    }
+
+    public void addAllColumns() {}
+
+    void addNamedJoinColumnExpression(String name, Expression e) {
+
+        if (namedJoinColumnExpressions == null) {
+            namedJoinColumnExpressions = new HashMap();
+        }
+
+        namedJoinColumnExpressions.put(name, e);
+    }
+
+    ExpressionColumn getColumnExpression(String name) {
+
+        return namedJoinColumnExpressions == null ? null
+                                                  : (ExpressionColumn) namedJoinColumnExpressions
+                                                  .get(name);
+    }
+
+    Table getTable() {
+        return rangeTable;
+    }
+
+    boolean hasIndexCondition() {
+        return joinConditions.length == 1
+               && joinConditions[0].indexedColumnCount > 0;
+    }
+
+    /**
+     * Used for sort
+     */
+    Index getSortIndex() {
+
+        if (joinConditions.length == 1) {
+            return joinConditions[0].rangeIndex;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Used for sort
+     */
+    boolean setSortIndex(Index index, boolean reversed) {
+
+        if (joinConditions.length == 1) {
+            if (joinConditions[0].indexedColumnCount == 0) {
+                joinConditions[0].rangeIndex = index;
+                joinConditions[0].reversed   = reversed;
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    boolean reverseOrder() {
+
+        joinConditions[0].reverseIndexCondition();
+
+        return true;
+    }
+
+    public OrderedHashSet getColumnNames() {
+
+        if (columnNames == null) {
+            columnNames = new OrderedHashSet();
+
+            rangeTable.getColumnNames(this.usedColumns, columnNames);
+        }
+
+        return columnNames;
+    }
+
+    public OrderedHashSet getUniqueColumnNameSet() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        if (columnAliases != null) {
+            set.addAll(columnAliases);
+
+            return set;
+        }
+
+        for (int i = 0; i < rangeTable.columnList.size(); i++) {
+            String  name  = rangeTable.getColumn(i).getName().name;
+            boolean added = set.add(name);
+
+            if (!added) {
+                throw Error.error(ErrorCode.X_42578, name);
+            }
+        }
+
+        return set;
+    }
+
+    /**
+     * Retruns index for column
+     *
+     * @param columnName name of column
+     * @return int index or -1 if not found
+     */
+    public int findColumn(String columnName) {
+
+        if (namedJoinColumnExpressions != null
+                && namedJoinColumnExpressions.containsKey(columnName)) {
+            return -1;
+        }
+
+        if (variables != null) {
+            return variables.getIndex(columnName);
+        } else if (columnAliases != null) {
+            return columnAliases.getIndex(columnName);
+        } else {
+            return rangeTable.findColumn(columnName);
+        }
+    }
+
+    ColumnSchema getColumn(String columnName) {
+
+        int index = findColumn(columnName);
+
+        return index < 0 ? null
+                         : rangeTable.getColumn(index);
+    }
+
+    ColumnSchema getColumn(int i) {
+
+        if (variables == null) {
+            return rangeTable.getColumn(i);
+        } else {
+            return (ColumnSchema) variables.get(i);
+        }
+    }
+
+    String getColumnAlias(int i) {
+
+        SimpleName name = getColumnAliasName(i);
+
+        return name.name;
+    }
+
+    public SimpleName getColumnAliasName(int i) {
+
+        if (columnAliases == null) {
+            return rangeTable.getColumn(i).getName();
+        } else {
+            return columnAliasNames[i];
+        }
+    }
+
+    boolean hasColumnAlias() {
+        return columnAliases != null;
+    }
+
+    String getTableAlias() {
+
+        SimpleName name = getTableAliasName();
+
+        return name.name;
+    }
+
+    SimpleName getTableAliasName() {
+        return tableAlias == null ? rangeTable.getName()
+                                  : tableAlias;
+    }
+
+    boolean resolvesTableName(ExpressionColumn e) {
+
+        if (e.tableName == null) {
+            return true;
+        }
+
+        if (e.schema == null) {
+            if (tableAlias == null) {
+                if (e.tableName.equals(rangeTable.getName().name)) {
+                    return true;
+                }
+            } else if (e.tableName.equals(tableAlias.name)) {
+                return true;
+            }
+        } else {
+            if (tableAlias == null) {
+                if (e.tableName.equals(rangeTable.getName().name)
+                        && e.schema.equals(rangeTable.getSchemaName().name)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public boolean resolvesTableName(String name) {
+
+        if (name == null) {
+            return true;
+        }
+
+        if (tableAlias == null) {
+            if (name.equals(rangeTable.getName().name)) {
+                return true;
+            }
+        } else if (name.equals(tableAlias.name)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    boolean resolvesSchemaName(String name) {
+
+        if (name == null) {
+            return true;
+        }
+
+        if (tableAlias != null) {
+            return false;
+        }
+
+        return name.equals(rangeTable.getSchemaName().name);
+    }
+
+    /**
+     * Add all columns to a list of expressions
+     */
+    void addTableColumns(HsqlArrayList exprList) {
+
+        if (namedJoinColumns != null) {
+            int count    = exprList.size();
+            int position = 0;
+
+            for (int i = 0; i < count; i++) {
+                Expression e          = (Expression) exprList.get(i);
+                String     columnName = e.getColumnName();
+
+                if (namedJoinColumns.contains(columnName)) {
+                    if (position != i) {
+                        exprList.remove(i);
+                        exprList.add(position, e);
+                    }
+
+                    e = getColumnExpression(columnName);
+
+                    exprList.set(position, e);
+
+                    position++;
+                }
+            }
+        }
+
+        addTableColumns(exprList, exprList.size(), namedJoinColumns);
+    }
+
+    /**
+     * Add all columns to a list of expressions
+     */
+    int addTableColumns(HsqlArrayList expList, int position, HashSet exclude) {
+
+        Table table = getTable();
+        int   count = table.getColumnCount();
+
+        for (int i = 0; i < count; i++) {
+            ColumnSchema column = table.getColumn(i);
+            String columnName = columnAliases == null ? column.getName().name
+                                                      : (String) columnAliases
+                                                          .get(i);
+
+            if (exclude != null && exclude.contains(columnName)) {
+                continue;
+            }
+
+            Expression e = new ExpressionColumn(this, i);
+
+            expList.add(position++, e);
+        }
+
+        return position;
+    }
+
+    void addTableColumns(Expression expression, HashSet exclude) {
+
+        HsqlArrayList list  = new HsqlArrayList();
+        Table         table = getTable();
+        int           count = table.getColumnCount();
+
+        for (int i = 0; i < count; i++) {
+            ColumnSchema column = table.getColumn(i);
+            String columnName = columnAliases == null ? column.getName().name
+                                                      : (String) columnAliases
+                                                          .get(i);
+
+            if (exclude != null && exclude.contains(columnName)) {
+                continue;
+            }
+
+            Expression e = new ExpressionColumn(this, i);
+
+            list.add(e);
+        }
+
+        Expression[] nodes = new Expression[list.size()];
+
+        list.toArray(nodes);
+
+        expression.nodes = nodes;
+    }
+
+    /**
+     * Removes reference to Index to avoid possible memory leaks after alter
+     * table or drop index
+     */
+    void setForCheckConstraint() {
+        joinConditions[0].rangeIndex = null;
+    }
+
+    /**
+     * used before condition processing
+     */
+    Expression getJoinCondition() {
+        return joinCondition;
+    }
+
+    void addJoinCondition(Expression e) {
+        joinCondition = ExpressionLogical.andExpressions(joinCondition, e);
+    }
+
+    void resetConditions() {
+
+        Index index = joinConditions[0].rangeIndex;
+
+        joinConditions = new RangeVariableConditions[]{
+            new RangeVariableConditions(this, true) };
+        joinConditions[0].rangeIndex = index;
+        whereConditions = new RangeVariableConditions[]{
+            new RangeVariableConditions(this, false) };
+    }
+
+    OrderedHashSet getSubqueries() {
+
+        OrderedHashSet set = null;
+
+        if (joinCondition != null) {
+            set = joinCondition.collectAllSubqueries(set);
+        }
+
+        if (rangeTable instanceof TableDerived) {
+            QueryExpression baseQueryExpression =
+                ((TableDerived) rangeTable).getQueryExpression();
+
+            if (((TableDerived) rangeTable).view != null) {
+                if (set == null) {
+                    set = new OrderedHashSet();
+                }
+
+                set.addAll(((TableDerived) rangeTable).view.getSubqueries());
+            } else if (baseQueryExpression == null) {
+                set = OrderedHashSet.add(set, rangeTable.getSubQuery());
+            } else {
+                OrderedHashSet temp = baseQueryExpression.getSubqueries();
+
+                set = OrderedHashSet.addAll(set, temp);
+                set = OrderedHashSet.add(set, rangeTable.getSubQuery());
+            }
+        }
+
+        return set;
+    }
+
+    public void replaceColumnReference(RangeVariable range,
+                                       Expression[] list) {
+
+        if (joinCondition != null) {
+            joinCondition.replaceColumnReferences(range, list);
+        }
+    }
+
+    public void replaceRangeVariables(RangeVariable[] ranges,
+                                      RangeVariable[] newRanges) {
+
+        if (joinCondition != null) {
+            joinCondition.replaceRangeVariables(ranges, newRanges);
+        }
+    }
+
+    public void resolveRangeTable(Session session,
+                                  RangeVariable[] rangeVariables,
+                                  int rangeCount) {
+
+        Table    table    = rangeTable;
+        SubQuery subQuery = table.getSubQuery();
+
+        if (subQuery != null && !subQuery.isResolved()) {
+            if (subQuery.dataExpression != null) {
+                HsqlList unresolved =
+                    subQuery.dataExpression.resolveColumnReferences(
+                        RangeVariable.emptyArray, null);
+
+                if (unresolved != null) {
+                    unresolved =
+                        subQuery.dataExpression.resolveColumnReferences(
+                            rangeVariables, rangeCount, null, true);
+                }
+
+                if (unresolved != null) {
+                    throw Error.error(
+                        ErrorCode.X_42501,
+                        ((Expression) unresolved.get(0)).getSQL());
+                }
+
+                subQuery.dataExpression.resolveTypes(session, null);
+                setRangeTableVariables();
+            }
+
+            if (subQuery.queryExpression != null) {
+                subQuery.queryExpression.resolveReferences(session);
+
+                HsqlList list =
+                    subQuery.queryExpression.getUnresolvedExpressions();
+
+                // todo resove against i ranges
+                HsqlList unresolved =
+                    Expression.resolveColumnSet(rangeVariables, rangeCount,
+                                                list, null);
+
+                if (unresolved != null) {
+                    throw Error.error(
+                        ErrorCode.X_42501,
+                        ((Expression) unresolved.get(0)).getSQL());
+                }
+
+                subQuery.queryExpression.resolveTypes(session);
+                subQuery.prepareTable(session);
+                subQuery.setCorrelated();
+                setRangeTableVariables();
+            }
+        }
+    }
+
+    /**
+     * Retreives a String representation of this obejct. <p>
+     *
+     * The returned String describes this object's table, alias
+     * access mode, index, join mode, Start, End and And conditions.
+     *
+     * @return a String representation of this object
+     */
+    public String describe(Session session, int blanks) {
+
+        RangeVariableConditions[] conditionsArray = joinConditions;
+        StringBuffer              sb;
+        String b = ValuePool.spaceString.substring(0, blanks);
+
+        sb = new StringBuffer();
+
+        String temp = "INNER";
+
+        if (isLeftJoin) {
+            temp = "LEFT OUTER";
+
+            if (isRightJoin) {
+                temp = "FULL";
+            }
+        } else if (isRightJoin) {
+            temp = "RIGHT OUTER";
+        }
+
+        sb.append(b).append("join type=").append(temp).append("\n");
+        sb.append(b).append("table=").append(rangeTable.getName().name).append(
+            "\n");
+
+        if (tableAlias != null) {
+            sb.append(b).append("alias=").append(tableAlias.name).append("\n");
+        }
+
+        boolean fullScan = !conditionsArray[0].hasIndexCondition();
+
+        sb.append(b).append("access=").append(fullScan ? "FULL SCAN"
+                                                       : "INDEX PRED").append(
+                                                       "\n");
+
+        for (int i = 0; i < conditionsArray.length; i++) {
+            RangeVariableConditions conditions = this.joinConditions[i];
+
+            if (i > 0) {
+                sb.append(b).append("OR condition = [");
+            } else {
+                sb.append(b).append("condition = [");
+            }
+
+            sb.append(conditions.describe(session, blanks + 2));
+            sb.append(b).append("]\n");
+        }
+
+        return sb.toString();
+    }
+
+    public RangeIteratorMain getIterator(Session session) {
+
+        RangeIteratorMain it;
+
+        if (this.isRightJoin) {
+            it = new RangeIteratorRight(session, this, null);
+        } else {
+            it = new RangeIteratorMain(session, this);
+        }
+
+        session.sessionContext.setRangeIterator(it);
+
+        return it;
+    }
+
+    public static RangeIterator getIterator(Session session,
+            RangeVariable[] rangeVars) {
+
+        if (rangeVars.length == 1) {
+            return rangeVars[0].getIterator(session);
+        }
+
+        RangeIteratorMain[] iterators =
+            new RangeIteratorMain[rangeVars.length];
+
+        for (int i = 0; i < rangeVars.length; i++) {
+            iterators[i] = rangeVars[i].getIterator(session);
+        }
+
+        return new RangeIteratorJoined(iterators);
+    }
+
+    public static class RangeIteratorBase implements RangeIterator {
+
+        Session         session;
+        int             rangePosition;
+        RowIterator     it;
+        PersistentStore store;
+        Object[]        currentData;
+        Row             currentRow;
+        boolean         isBeforeFirst;
+        RangeVariable   rangeVar;
+
+        RangeIteratorBase() {}
+
+        public RangeIteratorBase(Session session, PersistentStore store,
+                                 TableBase t, int position) {
+
+            this.session       = session;
+            this.rangePosition = position;
+            this.store         = store;
+            it                 = t.rowIterator(store);
+            isBeforeFirst      = true;
+        }
+
+        public boolean isBeforeFirst() {
+            return isBeforeFirst;
+        }
+
+        public boolean next() {
+
+            if (isBeforeFirst) {
+                isBeforeFirst = false;
+            } else {
+                if (it == null) {
+                    return false;
+                }
+            }
+
+            currentRow = it.getNextRow();
+
+            if (currentRow == null) {
+                return false;
+            } else {
+                currentData = currentRow.getData();
+
+                return true;
+            }
+        }
+
+        public Row getCurrentRow() {
+            return currentRow;
+        }
+
+        public Object[] getCurrent() {
+            return currentData;
+        }
+
+        public void setCurrent(Object[] data) {
+            currentData = data;
+        }
+
+        public long getRowId() {
+
+            return currentRow == null ? 0
+                                      : ((long) rangeVar.rangeTable.getId() << 32)
+                                        + ((long) currentRow.getPos());
+        }
+
+        public Object getRowidObject() {
+            return currentRow == null ? null
+                                      : ValuePool.getLong(getRowId());
+        }
+
+        public void remove() {}
+
+        public void reset() {
+
+            if (it != null) {
+                it.release();
+            }
+
+            it            = null;
+            currentRow    = null;
+            isBeforeFirst = true;
+        }
+
+        public int getRangePosition() {
+            return rangePosition;
+        }
+
+        public RangeVariable getRange() {
+            return rangeVar;
+        }
+
+        public Row getNextRow() {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
+        }
+
+        public boolean hasNext() {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
+        }
+
+        public Object[] getNext() {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
+        }
+
+        public boolean setRowColumns(boolean[] columns) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
+        }
+
+        public void release() {
+
+            if (it != null) {
+                it.release();
+            }
+        }
+    }
+
+    public static class RangeIteratorMain extends RangeIteratorBase {
+
+        boolean                   hasLeftOuterRow;
+        boolean                   isFullIterator;
+        RangeVariableConditions[] conditions;
+        RangeVariableConditions[] whereConditions;
+        RangeVariableConditions[] joinConditions;
+        int                       condIndex = 0;
+
+        //
+        OrderedIntHashSet lookup;
+
+        //
+        Object[] currentJoinData = null;
+
+        RangeIteratorMain() {
+            super();
+        }
+
+        private RangeIteratorMain(Session session, RangeVariable rangeVar) {
+
+            this.rangePosition = rangeVar.rangePosition;
+            this.store         = rangeVar.rangeTable.getRowStore(session);
+            this.session       = session;
+            this.rangeVar      = rangeVar;
+            currentData        = rangeVar.emptyData;
+            isBeforeFirst      = true;
+
+            if (rangeVar.isRightJoin) {
+                lookup = new OrderedIntHashSet();
+            }
+
+            conditions = rangeVar.joinConditions;
+
+            if (rangeVar.whereConditions[0].hasIndexCondition()) {
+                conditions = rangeVar.whereConditions;
+            }
+
+            whereConditions = rangeVar.whereConditions;
+            joinConditions  = rangeVar.joinConditions;
+        }
+
+        public boolean isBeforeFirst() {
+            return isBeforeFirst;
+        }
+
+        public boolean next() {
+
+            while (condIndex < conditions.length) {
+                if (isBeforeFirst) {
+                    isBeforeFirst = false;
+
+                    initialiseIterator();
+                }
+
+                boolean result = findNext();
+
+                if (result) {
+                    return true;
+                }
+
+                reset();
+
+                condIndex++;
+            }
+
+            condIndex = 0;
+
+            return false;
+        }
+
+        public void remove() {}
+
+        public void reset() {
+
+            if (it != null) {
+                it.release();
+            }
+
+            it            = null;
+            currentData   = rangeVar.emptyData;
+            currentRow    = null;
+            isBeforeFirst = true;
+        }
+
+        public int getRangePosition() {
+            return rangeVar.rangePosition;
+        }
+
+        /**
+         */
+        protected void initialiseIterator() {
+
+            if (condIndex == 0) {
+                hasLeftOuterRow = rangeVar.isLeftJoin;
+            }
+
+            if (conditions[condIndex].isFalse) {
+                it = conditions[condIndex].rangeIndex.emptyIterator();
+
+                return;
+            }
+
+            SubQuery subQuery = rangeVar.rangeTable.getSubQuery();
+
+            if (subQuery != null) {
+                subQuery.materialiseCorrelated(session);
+            }
+
+            if (conditions[condIndex].indexCond == null) {
+                it = conditions[condIndex].reversed
+                     ? conditions[condIndex].rangeIndex.lastRow(session, store)
+                     : conditions[condIndex].rangeIndex.firstRow(session,
+                        store);
+            } else {
+                getFirstRow();
+
+                if (!conditions[condIndex].isJoin) {
+                    hasLeftOuterRow = false;
+                }
+            }
+        }
+
+        private void getFirstRow() {
+
+            if (currentJoinData == null
+                    || currentJoinData.length
+                       < conditions[condIndex].indexedColumnCount) {
+                currentJoinData =
+                    new Object[conditions[condIndex].indexedColumnCount];
+            }
+
+            for (int i = 0; i < conditions[condIndex].indexedColumnCount;
+                    i++) {
+                int range = 0;
+                int opType = i == conditions[condIndex].indexedColumnCount - 1
+                             ? conditions[condIndex].opType
+                             : conditions[condIndex].indexCond[i].getType();
+
+                if (opType == OpTypes.IS_NULL || opType == OpTypes.NOT
+                        || opType == OpTypes.MAX) {
+                    currentJoinData[i] = null;
+
+                    continue;
+                }
+
+                Type valueType =
+                    conditions[condIndex].indexCond[i].getRightNode()
+                        .getDataType();
+                Object value =
+                    conditions[condIndex].indexCond[i].getRightNode().getValue(
+                        session);
+                Type targetType =
+                    conditions[condIndex].indexCond[i].getLeftNode()
+                        .getDataType();
+
+                if (targetType != valueType) {
+                    range = targetType.compareToTypeRange(value);
+
+                    if (range == 0) {
+                        if (targetType.typeComparisonGroup
+                                != valueType.typeComparisonGroup) {
+                            value = targetType.convertToType(session, value,
+                                                             valueType);
+                        }
+                    }
+                }
+
+                if (i == 0) {
+                    int exprType =
+                        conditions[condIndex].indexCond[0].getType();
+
+                    if (range < 0) {
+                        switch (exprType) {
+
+                            case OpTypes.GREATER_EQUAL :
+                            case OpTypes.GREATER :
+                                value = null;
+                                break;
+
+                            default :
+                                it = conditions[condIndex].rangeIndex
+                                    .emptyIterator();
+
+                                return;
+                        }
+                    } else if (range > 0) {
+                        switch (exprType) {
+
+                            case OpTypes.NOT :
+                                value = null;
+                                break;
+
+                            default :
+                                it = conditions[condIndex].rangeIndex
+                                    .emptyIterator();
+
+                                return;
+                        }
+                    }
+                }
+
+                currentJoinData[i] = value;
+            }
+
+            it = conditions[condIndex].rangeIndex.findFirstRow(session, store,
+                    currentJoinData, conditions[condIndex].indexedColumnCount,
+                    conditions[condIndex].opType,
+                    conditions[condIndex].reversed, null);
+        }
+
+        /**
+         * Advances to the next available value. <p>
+         *
+         * @return true if a next value is available upon exit
+         */
+        protected boolean findNext() {
+
+            boolean result = false;
+
+            while (true) {
+                currentRow = it.getNextRow();
+
+                if (currentRow == null) {
+                    break;
+                }
+
+                currentData = currentRow.getData();
+
+                if (conditions[condIndex].indexEndCondition != null
+                        && !conditions[condIndex].indexEndCondition
+                            .testCondition(session)) {
+                    if (!conditions[condIndex].isJoin) {
+                        hasLeftOuterRow = false;
+                    }
+
+                    break;
+                }
+
+                if (joinConditions[condIndex].nonIndexCondition != null
+                        && !joinConditions[condIndex].nonIndexCondition
+                            .testCondition(session)) {
+                    continue;
+                }
+
+                if (whereConditions[condIndex].nonIndexCondition != null
+                        && !whereConditions[condIndex].nonIndexCondition
+                            .testCondition(session)) {
+                    hasLeftOuterRow = false;
+
+                    addFoundRow();
+
+                    continue;
+                }
+
+                Expression e = conditions[condIndex].excludeConditions;
+
+                if (e != null && e.testCondition(session)) {
+                    continue;
+                }
+
+                addFoundRow();
+
+                hasLeftOuterRow = false;
+
+                return true;
+            }
+
+            it.release();
+
+            currentRow  = null;
+            currentData = rangeVar.emptyData;
+
+            if (hasLeftOuterRow && condIndex == conditions.length - 1) {
+                result =
+                    (whereConditions[condIndex].nonIndexCondition == null
+                     || whereConditions[condIndex].nonIndexCondition
+                         .testCondition(session));
+                hasLeftOuterRow = false;
+            }
+
+            return result;
+        }
+
+        protected void addFoundRow() {
+
+            if (rangeVar.isRightJoin) {
+                lookup.add(currentRow.getPos());
+            }
+        }
+    }
+
+    public static class RangeIteratorRight extends RangeIteratorMain {
+
+        private RangeIteratorRight(Session session, RangeVariable rangeVar,
+                                   RangeIteratorMain main) {
+
+            super(session, rangeVar);
+
+            isFullIterator = true;
+        }
+
+        boolean isOnRightOuterRows;
+
+        public void setOnOuterRows() {
+
+            conditions         = rangeVar.whereConditions;
+            isOnRightOuterRows = true;
+            hasLeftOuterRow    = false;
+            condIndex          = 0;
+
+            initialiseIterator();
+        }
+
+        public boolean next() {
+
+            if (isOnRightOuterRows) {
+                if (it == null) {
+                    return false;
+                }
+
+                return findNextRight();
+            } else {
+                return super.next();
+            }
+        }
+
+        protected boolean findNextRight() {
+
+            boolean result = false;
+
+            while (true) {
+                currentRow = it.getNextRow();
+
+                if (currentRow == null) {
+                    break;
+                }
+
+                currentData = currentRow.getData();
+
+                if (conditions[condIndex].indexEndCondition != null
+                        && !conditions[condIndex].indexEndCondition
+                            .testCondition(session)) {
+                    break;
+                }
+
+                if (conditions[condIndex].nonIndexCondition != null
+                        && !conditions[condIndex].nonIndexCondition
+                            .testCondition(session)) {
+                    continue;
+                }
+
+                if (!lookupAndTest()) {
+                    continue;
+                }
+
+                result = true;
+
+                break;
+            }
+
+            if (result) {
+                return true;
+            }
+
+            it.release();
+
+            currentRow  = null;
+            currentData = rangeVar.emptyData;
+
+            return result;
+        }
+
+        private boolean lookupAndTest() {
+
+            boolean result = !lookup.contains(currentRow.getPos());
+
+            if (result) {
+                currentData = currentRow.getData();
+
+                if (conditions[condIndex].nonIndexCondition != null
+                        && !conditions[condIndex].nonIndexCondition
+                            .testCondition(session)) {
+                    result = false;
+                }
+            }
+
+            return result;
+        }
+    }
+
+    public static class RangeIteratorJoined extends RangeIteratorBase {
+
+        RangeIteratorMain[] rangeIterators;
+        int                 currentIndex = 0;
+
+        public RangeIteratorJoined(RangeIteratorMain[] rangeIterators) {
+            this.rangeIterators = rangeIterators;
+            isBeforeFirst       = true;
+        }
+
+        public boolean isBeforeFirst() {
+            return isBeforeFirst;
+        }
+
+        public boolean next() {
+
+            while (currentIndex >= 0) {
+                RangeIteratorMain it = rangeIterators[currentIndex];
+
+                if (it.next()) {
+                    if (currentIndex < rangeIterators.length - 1) {
+                        currentIndex++;
+
+                        continue;
+                    }
+
+                    currentRow  = rangeIterators[currentIndex].currentRow;
+                    currentData = currentRow.getData();
+
+                    return true;
+                } else {
+                    it.reset();
+
+                    currentIndex--;
+
+                    continue;
+                }
+            }
+
+            currentData =
+                rangeIterators[rangeIterators.length - 1].rangeVar.emptyData;
+            currentRow = null;
+
+            for (int i = 0; i < rangeIterators.length; i++) {
+                rangeIterators[i].reset();
+            }
+
+            return false;
+        }
+
+        public void remove() {}
+
+        public void release() {
+
+            if (it != null) {
+                it.release();
+            }
+
+            for (int i = 0; i < rangeIterators.length; i++) {
+                rangeIterators[i].reset();
+            }
+        }
+
+        public void reset() {
+
+            super.reset();
+
+            for (int i = 0; i < rangeIterators.length; i++) {
+                rangeIterators[i].reset();
+            }
+        }
+
+        public int getRangePosition() {
+            return 0;
+        }
+
+        public RangeVariable getRange() {
+            return null;
+        }
+    }
+
+    public static class RangeVariableConditions {
+
+        final RangeVariable rangeVar;
+        Expression[]        indexCond;
+        Expression[]        indexEndCond;
+        Expression          indexEndCondition;
+        int                 indexedColumnCount;
+        Index               rangeIndex;
+        final boolean       isJoin;
+        Expression          excludeConditions;
+        Expression          nonIndexCondition;
+        int                 opType;
+        int                 opTypeEnd;
+        boolean             isFalse;
+        boolean             reversed;
+
+        RangeVariableConditions(RangeVariable rangeVar, boolean isJoin) {
+            this.rangeVar = rangeVar;
+            this.isJoin   = isJoin;
+        }
+
+        RangeVariableConditions(RangeVariableConditions base) {
+
+            this.rangeVar     = base.rangeVar;
+            this.isJoin       = base.isJoin;
+            nonIndexCondition = base.nonIndexCondition;
+        }
+
+        boolean hasIndexCondition() {
+            return indexedColumnCount > 0;
+        }
+
+        void addCondition(Expression e) {
+
+            if (e == null) {
+                return;
+            }
+
+            nonIndexCondition =
+                ExpressionLogical.andExpressions(nonIndexCondition, e);
+
+            if (Expression.EXPR_FALSE.equals(nonIndexCondition)) {
+                isFalse = true;
+            }
+
+            if (rangeIndex == null || rangeIndex.getColumnCount() == 0) {
+                return;
+            }
+
+            if (indexedColumnCount == 0) {
+                return;
+            }
+
+            if (e.getIndexableExpression(rangeVar) == null) {
+                return;
+            }
+
+            int colIndex = e.getLeftNode().getColumnIndex();
+
+            switch (e.getType()) {
+
+                case OpTypes.GREATER :
+                case OpTypes.GREATER_EQUAL : {
+
+                    // replaces existing condition
+                    if (opType == OpTypes.NOT) {
+                        if (rangeIndex.getColumns()[indexedColumnCount - 1]
+                                == colIndex) {
+                            nonIndexCondition =
+                                ExpressionLogical.andExpressions(
+                                    nonIndexCondition,
+                                    indexCond[indexedColumnCount - 1]);
+                            indexCond[indexedColumnCount - 1] = e;
+                            opType                            = e.opType;
+                        }
+                    } else {
+                        addToIndexConditions(e);
+                    }
+
+                    break;
+                }
+                case OpTypes.SMALLER :
+                case OpTypes.SMALLER_EQUAL : {
+                    if (opType == OpTypes.GREATER
+                            || opType == OpTypes.GREATER_EQUAL
+                            || opType == OpTypes.NOT) {
+                        if (opTypeEnd != OpTypes.MAX) {
+                            break;
+                        }
+
+                        if (rangeIndex.getColumns()[indexedColumnCount - 1]
+                                == colIndex) {
+                            indexEndCond[indexedColumnCount - 1] = e;
+                            indexEndCondition =
+                                ExpressionLogical.andExpressions(
+                                    indexEndCondition, e);
+                            opTypeEnd = e.getType();
+                        }
+                    }
+
+                    break;
+                }
+                default :
+            }
+        }
+
+        boolean addToIndexConditions(Expression e) {
+
+            if (opType == OpTypes.EQUAL || opType == OpTypes.IS_NULL) {
+                if (indexedColumnCount < rangeIndex.getColumnCount()) {
+                    if (rangeIndex.getColumns()[indexedColumnCount]
+                            == e.getLeftNode().getColumnIndex()) {
+                        indexCond[indexedColumnCount] = e;
+
+                        indexedColumnCount++;
+
+                        opType    = e.opType;
+                        opTypeEnd = OpTypes.MAX;
+
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        /**
+         *
+         * @param exprList list of expressions
+         * @param index Index to use
+         * @param colCount number of columns searched
+         */
+        void addIndexCondition(Expression[] exprList, Index index,
+                               int colCount) {
+
+            rangeIndex = index;
+            opType     = exprList[0].getType();
+
+            switch (opType) {
+
+                case OpTypes.NOT :
+                    indexCond    = exprList;
+                    indexEndCond = new Expression[exprList.length];
+                    opTypeEnd    = OpTypes.MAX;
+                    break;
+
+                case OpTypes.GREATER :
+                case OpTypes.GREATER_EQUAL :
+                    indexCond    = exprList;
+                    indexEndCond = new Expression[exprList.length];
+                    opTypeEnd    = OpTypes.MAX;
+                    break;
+
+                case OpTypes.SMALLER :
+                case OpTypes.SMALLER_EQUAL : {
+                    Expression e = exprList[0].getLeftNode();
+
+                    e = new ExpressionLogical(OpTypes.IS_NULL, e);
+                    e               = new ExpressionLogical(OpTypes.NOT, e);
+                    indexCond       = new Expression[]{ e };
+                    indexEndCond    = new Expression[exprList.length];
+                    indexEndCond[0] = indexEndCondition = exprList[0];
+                    opTypeEnd       = opType;
+                    opType          = OpTypes.NOT;
+
+                    break;
+                }
+                case OpTypes.IS_NULL :
+                case OpTypes.EQUAL : {
+                    indexCond    = exprList;
+                    indexEndCond = new Expression[exprList.length];
+
+                    for (int i = 0; i < colCount; i++) {
+                        Expression e = exprList[i];
+
+                        indexEndCond[i] = e;
+                        indexEndCondition =
+                            ExpressionLogical.andExpressions(indexEndCondition,
+                                                             e);
+                        opType = e.getType();
+                    }
+
+                    opTypeEnd = opType;
+
+                    break;
+                }
+                default :
+                    Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
+            }
+
+            indexedColumnCount = colCount;
+        }
+
+        void reverseIndexCondition() {
+
+            if (opType == OpTypes.EQUAL || opType == OpTypes.IS_NULL) {
+                return;
+            }
+
+            indexEndCondition = null;
+
+            for (int i = 0; i < indexedColumnCount; i++) {
+                Expression e = indexCond[i];
+
+                indexCond[i]    = indexEndCond[i];
+                indexEndCond[i] = e;
+                indexEndCondition =
+                    ExpressionLogical.andExpressions(indexEndCondition, e);
+            }
+
+            opType   = opTypeEnd;
+            reversed = true;
+        }
+
+        String describe(Session session, int blanks) {
+
+            StringBuffer sb = new StringBuffer();
+            String       b  = ValuePool.spaceString.substring(0, blanks);
+
+            sb.append(b).append("index=").append(
+                rangeIndex.getName().name).append("\n");
+
+            if (hasIndexCondition()) {
+                if (indexedColumnCount > 0) {
+                    sb.append(b).append("start conditions=[");
+
+                    for (int j = 0; j < indexedColumnCount; j++) {
+                        if (indexCond != null && indexCond[j] != null) {
+                            sb.append(indexCond[j].describe(session, blanks));
+                        }
+                    }
+
+                    sb.append("]\n");
+                }
+
+                if (indexEndCondition != null) {
+                    String temp = indexEndCondition.describe(session, blanks);
+
+                    sb.append(b).append("end condition=[").append(temp).append(
+                        "]\n");
+                }
+            }
+
+            if (nonIndexCondition != null) {
+                String temp = nonIndexCondition.describe(session, blanks);
+
+                sb.append(b).append("other condition=[").append(temp).append(
+                    "]\n");
+            }
+
+            return sb.toString();
+        }
+    }
+}
diff --git a/src/org/hsqldb/RangeVariableResolver.java b/src/org/hsqldb/RangeVariableResolver.java
new file mode 100644
index 0000000..e9cfcb5
--- /dev/null
+++ b/src/org/hsqldb/RangeVariableResolver.java
@@ -0,0 +1,1058 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.RangeVariable.RangeVariableConditions;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.IntKeyIntValueHashMap;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.MultiValueHashMap;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+
+/**
+ * Determines how JOIN and WHERE expressions are used in query
+ * processing and which indexes are used for table access.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+public class RangeVariableResolver {
+
+    Session         session;
+    RangeVariable[] rangeVariables;
+    Expression      conditions;
+    OrderedHashSet  rangeVarSet = new OrderedHashSet();
+    CompileContext  compileContext;
+
+    //
+    HsqlArrayList[] tempJoinExpressions;
+    HsqlArrayList[] joinExpressions;
+    HsqlArrayList[] whereExpressions;
+    HsqlArrayList   queryExpressions = new HsqlArrayList();
+
+    //
+    Expression[] inExpressions;
+    boolean[]    inInJoin;
+    int          inExpressionCount = 0;
+
+    //
+    boolean hasOuterJoin = false;
+
+    //
+    OrderedIntHashSet     colIndexSetEqual = new OrderedIntHashSet();
+    IntKeyIntValueHashMap colIndexSetOther = new IntKeyIntValueHashMap();
+    OrderedHashSet        tempSet          = new OrderedHashSet();
+    MultiValueHashMap     tempMap          = new MultiValueHashMap();
+
+    RangeVariableResolver(RangeVariable[] rangeVars, Expression conditions,
+                          CompileContext compileContext) {
+
+        this.rangeVariables = rangeVars;
+        this.conditions     = conditions;
+        this.compileContext = compileContext;
+
+        for (int i = 0; i < rangeVars.length; i++) {
+            RangeVariable range = rangeVars[i];
+
+            rangeVarSet.add(range);
+
+            if (range.isLeftJoin || range.isRightJoin) {
+                hasOuterJoin = true;
+            }
+        }
+
+        inExpressions       = new Expression[rangeVars.length];
+        inInJoin            = new boolean[rangeVars.length];
+        tempJoinExpressions = new HsqlArrayList[rangeVars.length];
+
+        for (int i = 0; i < rangeVars.length; i++) {
+            tempJoinExpressions[i] = new HsqlArrayList();
+        }
+
+        joinExpressions = new HsqlArrayList[rangeVars.length];
+
+        for (int i = 0; i < rangeVars.length; i++) {
+            joinExpressions[i] = new HsqlArrayList();
+        }
+
+        whereExpressions = new HsqlArrayList[rangeVars.length];
+
+        for (int i = 0; i < rangeVars.length; i++) {
+            whereExpressions[i] = new HsqlArrayList();
+        }
+    }
+
+    void processConditions(Session session) {
+
+        this.session = session;
+
+        decomposeAndConditions(conditions, queryExpressions);
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            if (rangeVariables[i].joinCondition == null) {
+                continue;
+            }
+
+            decomposeAndConditions(rangeVariables[i].joinCondition,
+                                   tempJoinExpressions[i]);
+        }
+
+        conditions = null;
+
+        assignToLists();
+
+        if (!hasOuterJoin) {
+
+//            getIndexableColumn(whereExpressions[0], 0);
+        }
+
+        expandConditions();
+        assignToRangeVariables();
+    }
+
+    /**
+     * Divides AND and OR conditions and assigns
+     */
+    static Expression decomposeAndConditions(Expression e,
+            HsqlArrayList conditions) {
+
+        if (e == null) {
+            return Expression.EXPR_TRUE;
+        }
+
+        Expression arg1 = e.getLeftNode();
+        Expression arg2 = e.getRightNode();
+        int        type = e.getType();
+
+        if (type == OpTypes.AND) {
+            arg1 = decomposeAndConditions(arg1, conditions);
+            arg2 = decomposeAndConditions(arg2, conditions);
+
+            if (arg1 == Expression.EXPR_TRUE) {
+                return arg2;
+            }
+
+            if (arg2 == Expression.EXPR_TRUE) {
+                return arg1;
+            }
+
+            e.setLeftNode(arg1);
+            e.setRightNode(arg2);
+
+            return e;
+        } else if (type == OpTypes.EQUAL) {
+            if (arg1.getType() == OpTypes.ROW
+                    && arg2.getType() == OpTypes.ROW) {
+                for (int i = 0; i < arg1.nodes.length; i++) {
+                    Expression part = new ExpressionLogical(arg1.nodes[i],
+                        arg2.nodes[i]);
+
+                    part.resolveTypes(null, null);
+                    conditions.add(part);
+                }
+
+                return Expression.EXPR_TRUE;
+            }
+        }
+
+        if (e != Expression.EXPR_TRUE) {
+            conditions.add(e);
+        }
+
+        return Expression.EXPR_TRUE;
+    }
+
+    /**
+     * Divides AND and OR conditions and assigns
+     */
+    static Expression decomposeOrConditions(Expression e,
+            HsqlArrayList conditions) {
+
+        if (e == null) {
+            return Expression.EXPR_FALSE;
+        }
+
+        Expression arg1 = e.getLeftNode();
+        Expression arg2 = e.getRightNode();
+        int        type = e.getType();
+
+        if (type == OpTypes.OR) {
+            arg1 = decomposeOrConditions(arg1, conditions);
+            arg2 = decomposeOrConditions(arg2, conditions);
+
+            if (arg1 == Expression.EXPR_FALSE) {
+                return arg2;
+            }
+
+            if (arg2 == Expression.EXPR_FALSE) {
+                return arg1;
+            }
+
+            e = new ExpressionLogical(OpTypes.OR, arg1, arg2);
+
+            return e;
+        }
+
+        if (e != Expression.EXPR_FALSE) {
+            conditions.add(e);
+        }
+
+        return Expression.EXPR_FALSE;
+    }
+
+    /**
+     * Assigns the conditions to separate lists
+     */
+    void assignToLists() {
+
+        int lastOuterIndex = -1;
+        int lastRightIndex = -1;
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            if (rangeVariables[i].isLeftJoin) {
+                lastOuterIndex = i;
+            }
+
+            if (rangeVariables[i].isRightJoin) {
+                lastOuterIndex = i;
+                lastRightIndex = i;
+            }
+
+            if (lastOuterIndex == i) {
+                joinExpressions[i].addAll(tempJoinExpressions[i]);
+            } else {
+                for (int j = 0; j < tempJoinExpressions[i].size(); j++) {
+                    assignToJoinLists(
+                        (Expression) tempJoinExpressions[i].get(j),
+                        joinExpressions, lastOuterIndex + 1);
+                }
+            }
+        }
+
+        for (int i = 0; i < queryExpressions.size(); i++) {
+            assignToWhereLists((Expression) queryExpressions.get(i),
+                               whereExpressions, lastRightIndex);
+        }
+    }
+
+    /**
+     * Assigns a single condition to the relevant list of conditions
+     *
+     * Parameter first indicates the first range variable to which condition
+     * can be assigned
+     */
+    void assignToJoinLists(Expression e, HsqlArrayList[] expressionLists,
+                           int first) {
+
+        tempSet.clear();
+        e.collectRangeVariables(rangeVariables, tempSet);
+
+        int index = rangeVarSet.getLargestIndex(tempSet);
+
+        // condition is independent of tables if no range variable is found
+        if (index == -1) {
+            index = 0;
+        }
+
+        // condition is assigned to first non-outer range variable
+        if (index < first) {
+            index = first;
+        }
+
+        expressionLists[index].add(e);
+    }
+
+    /**
+     * Assigns a single condition to the relevant list of conditions
+     *
+     * Parameter first indicates the first range variable to which condition
+     * can be assigned
+     */
+    void assignToWhereLists(Expression e, HsqlArrayList[] expressionLists,
+                            int first) {
+
+        tempSet.clear();
+        e.collectRangeVariables(rangeVariables, tempSet);
+
+        int index = rangeVarSet.getLargestIndex(tempSet);
+
+        // condition is independent of tables if no range variable is found
+        if (index == -1) {
+            index = 0;
+        }
+
+        // condition is assigned to first non-outer range variable
+        if (index < first) {
+            index = first;
+        }
+
+        expressionLists[index].add(e);
+    }
+
+    void expandConditions() {
+
+        expandConditions(joinExpressions, true);
+
+        if (hasOuterJoin) {
+            return;
+        }
+
+        expandConditions(whereExpressions, false);
+    }
+
+    void expandConditions(HsqlArrayList[] array, boolean isJoin) {
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            HsqlArrayList list = array[i];
+
+            tempMap.clear();
+            tempSet.clear();
+
+            boolean hasChain = false;
+
+            for (int j = 0; j < list.size(); j++) {
+                Expression e = (Expression) list.get(j);
+
+                if (!e.isColumnEqual) {
+                    continue;
+                }
+
+                if (e.getLeftNode().getRangeVariable()
+                        == e.getRightNode().getRangeVariable()) {
+                    continue;
+                }
+
+                if (e.getLeftNode().getRangeVariable() == rangeVariables[i]) {
+                    tempMap.put(e.getLeftNode().getColumn(), e.getRightNode());
+
+                    if (!tempSet.add(e.getLeftNode().getColumn())) {
+                        hasChain = true;
+                    }
+                } else if (e.getRightNode().getRangeVariable()
+                           == rangeVariables[i]) {
+                    tempMap.put(e.getRightNode().getColumn(), e.getLeftNode());
+
+                    if (!tempSet.add(e.getRightNode().getColumn())) {
+                        hasChain = true;
+                    }
+                }
+            }
+
+            if (hasChain) {
+                Iterator keyIt = tempMap.keySet().iterator();
+
+                while (keyIt.hasNext()) {
+                    Object   key = keyIt.next();
+                    Iterator it  = tempMap.get(key);
+
+                    tempSet.clear();
+
+                    while (it.hasNext()) {
+                        tempSet.add(it.next());
+                    }
+
+                    while (tempSet.size() > 1) {
+                        Expression e1 =
+                            (Expression) tempSet.remove(tempSet.size() - 1);
+
+                        for (int j = 0; j < tempSet.size(); j++) {
+                            Expression e2 = (Expression) tempSet.get(j);
+
+                            closeJoinChain(array, e1, e2);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    void closeJoinChain(HsqlArrayList[] array, Expression e1, Expression e2) {
+
+        int        idx1  = rangeVarSet.getIndex(e1.getRangeVariable());
+        int        idx2  = rangeVarSet.getIndex(e2.getRangeVariable());
+        int        index = idx1 > idx2 ? idx1
+                                       : idx2;
+        Expression e     = new ExpressionLogical(e1, e2);
+
+        for (int i = 0; i < array[index].size(); i++) {
+            if (e.equals(array[index].get(i))) {
+                return;
+            }
+        }
+
+        array[index].add(e);
+    }
+
+    /**
+     * Assigns conditions to range variables and converts suitable IN conditions
+     * to table lookup.
+     */
+    void assignToRangeVariables() {
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            boolean hasIndex = false;
+            boolean isOuter = rangeVariables[i].isLeftJoin
+                              || rangeVariables[i].isRightJoin;
+            RangeVariableConditions conditions;
+
+            if (isOuter) {
+                conditions = rangeVariables[i].joinConditions[0];
+
+                assignToRangeVariable(rangeVariables[i], conditions, i,
+                                      joinExpressions[i]);
+
+                // index only on one condition -- right and full can have index
+                conditions = rangeVariables[i].joinConditions[0];
+
+                if (conditions.hasIndexCondition()) {
+                    hasIndex = true;
+                }
+
+                conditions = rangeVariables[i].whereConditions[0];
+
+                if (rangeVariables[i].isRightJoin) {
+                    assignToRangeVariable(conditions, whereExpressions[i]);
+                } else if (hasIndex) {
+                    assignToRangeVariable(conditions, whereExpressions[i]);
+                } else {
+                    assignToRangeVariable(rangeVariables[i], conditions, i,
+                                          whereExpressions[i]);
+                }
+            } else {
+                conditions = rangeVariables[i].joinConditions[0];
+
+                if (hasOuterJoin) {
+                    assignToRangeVariable(rangeVariables[i].whereConditions[0],
+                                          whereExpressions[i]);
+                } else {
+                    joinExpressions[i].addAll(whereExpressions[i]);
+                }
+
+                assignToRangeVariable(rangeVariables[i], conditions, i,
+                                      joinExpressions[i]);
+            }
+        }
+
+        if (inExpressionCount != 0) {
+            setInConditionsAsTables();
+        }
+    }
+
+    void assignToRangeVariable(RangeVariableConditions conditions,
+                               HsqlArrayList exprList) {
+
+        for (int j = 0, size = exprList.size(); j < size; j++) {
+            Expression e = (Expression) exprList.get(j);
+
+            conditions.addCondition(e);
+        }
+    }
+
+    Expression getIndexableColumn(HsqlArrayList exprList, int start) {
+
+        for (int j = start, size = exprList.size(); j < size; j++) {
+            Expression e = (Expression) exprList.get(j);
+
+            if (e.getType() != OpTypes.EQUAL) {
+                continue;
+            }
+
+            if (e.exprSubType == OpTypes.ALL_QUANTIFIED) {
+                continue;
+            }
+
+            if (e.exprSubType == OpTypes.ANY_QUANTIFIED) {
+
+                // can process in the future
+                continue;
+            }
+
+            tempSet.clear();
+            e.collectRangeVariables(rangeVariables, tempSet);
+
+            if (tempSet.size() != 1) {
+                continue;
+            }
+
+            RangeVariable range = (RangeVariable) tempSet.get(0);
+
+            e = e.getIndexableExpression(range);
+
+            if (e == null) {
+                continue;
+            }
+
+            e = e.getLeftNode();
+
+            if (e.getType() != OpTypes.COLUMN) {
+                continue;
+            }
+
+            int colIndex = e.getColumnIndex();
+
+            if (range.rangeTable.canGetIndexForColumn(session, colIndex)) {
+                return e;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Assigns a set of conditions to a range variable.
+     */
+    void assignToRangeVariable(RangeVariable rangeVar,
+                               RangeVariableConditions conditions,
+                               int rangeVarIndex, HsqlArrayList exprList) {
+
+        if (exprList.isEmpty()) {
+            return;
+        }
+
+        setIndexConditions(conditions, exprList, rangeVarIndex, true);
+    }
+
+    private void setIndexConditions(RangeVariableConditions conditions,
+                                    HsqlArrayList exprList, int rangeVarIndex,
+                                    boolean includeOr) {
+
+        boolean hasIndex;
+
+        colIndexSetEqual.clear();
+        colIndexSetOther.clear();
+
+        for (int j = 0, size = exprList.size(); j < size; j++) {
+            Expression e = (Expression) exprList.get(j);
+
+            if (e == null) {
+                continue;
+            }
+
+            // repeat check required for OR
+            if (!e.isIndexable(conditions.rangeVar)) {
+                continue;
+            }
+
+            int type = e.getType();
+
+            switch (type) {
+
+                case OpTypes.OR : {
+                    continue;
+                }
+                case OpTypes.COLUMN : {
+                    continue;
+                }
+                case OpTypes.EQUAL : {
+                    if (e.exprSubType == OpTypes.ANY_QUANTIFIED
+                            || e.exprSubType == OpTypes.ALL_QUANTIFIED) {
+                        continue;
+                    }
+
+                    if (e.getLeftNode().getRangeVariable()
+                            != conditions.rangeVar) {
+                        continue;
+                    }
+
+                    int colIndex = e.getLeftNode().getColumnIndex();
+
+                    colIndexSetEqual.add(colIndex);
+
+                    break;
+                }
+                case OpTypes.IS_NULL : {
+                    if (e.getLeftNode().getRangeVariable()
+                            != conditions.rangeVar) {
+                        continue;
+                    }
+
+                    int colIndex = e.getLeftNode().getColumnIndex();
+
+                    colIndexSetEqual.add(colIndex);
+
+                    break;
+                }
+                case OpTypes.NOT : {
+                    if (e.getLeftNode().getLeftNode().getRangeVariable()
+                            != conditions.rangeVar) {
+                        continue;
+                    }
+
+                    int colIndex =
+                        e.getLeftNode().getLeftNode().getColumnIndex();
+                    int count = colIndexSetOther.get(colIndex, 0);
+
+                    colIndexSetOther.put(colIndex, count + 1);
+
+                    break;
+                }
+                case OpTypes.SMALLER :
+                case OpTypes.SMALLER_EQUAL :
+                case OpTypes.GREATER :
+                case OpTypes.GREATER_EQUAL : {
+                    if (e.getLeftNode().getRangeVariable()
+                            != conditions.rangeVar) {
+                        continue;
+                    }
+
+                    int colIndex = e.getLeftNode().getColumnIndex();
+                    int count    = colIndexSetOther.get(colIndex, 0);
+
+                    colIndexSetOther.put(colIndex, count + 1);
+
+                    break;
+                }
+                default : {
+                    Error.runtimeError(ErrorCode.U_S0500,
+                                       "RangeVariableResolver");
+                }
+            }
+        }
+
+        setEqaulityConditions(conditions, exprList);
+
+        hasIndex = conditions.hasIndexCondition();
+
+        if (!hasIndex) {
+            setNonEqualityConditions(conditions, exprList);
+        }
+
+        hasIndex = conditions.hasIndexCondition();
+
+        // no index found
+        boolean isOR = false;
+
+        if (!hasIndex && includeOr) {
+            for (int j = 0, size = exprList.size(); j < size; j++) {
+                Expression e = (Expression) exprList.get(j);
+
+                if (e == null) {
+                    continue;
+                }
+
+                if (e.getType() == OpTypes.OR) {
+
+                    //
+                    hasIndex = ((ExpressionLogical) e).isIndexable(
+                        conditions.rangeVar);
+
+                    if (hasIndex) {
+                        hasIndex = setOrConditions(conditions,
+                                                   (ExpressionLogical) e,
+                                                   rangeVarIndex);
+                    }
+
+                    if (hasIndex) {
+                        exprList.set(j, null);
+
+                        isOR = true;
+
+                        break;
+                    }
+                } else if (e.getType() == OpTypes.EQUAL
+                           && e.exprSubType == OpTypes.ANY_QUANTIFIED) {
+                    if (e.getRightNode().isCorrelated()) {
+                        continue;
+                    }
+
+                    OrderedIntHashSet set = new OrderedIntHashSet();
+
+                    ((ExpressionLogical) e).addLeftColumnsForAllAny(
+                        conditions.rangeVar, set);
+
+                    Index index =
+                        conditions.rangeVar.rangeTable.getIndexForColumns(
+                            session, set, false);
+
+                    // code to disable IN optimisation
+                    // index = null;
+                    if (index != null
+                            && inExpressions[rangeVarIndex] == null) {
+                        inExpressions[rangeVarIndex] = e;
+                        inInJoin[rangeVarIndex]      = conditions.isJoin;
+
+                        inExpressionCount++;
+
+                        exprList.set(j, null);
+
+                        break;
+                    }
+                }
+            }
+        }
+
+        for (int i = 0, size = exprList.size(); i < size; i++) {
+            Expression e = (Expression) exprList.get(i);
+
+            if (e == null) {
+                continue;
+            }
+
+            if (isOR) {
+                for (int j = 0; j < conditions.rangeVar.joinConditions.length;
+                        j++) {
+                    if (conditions.isJoin) {
+                        conditions.rangeVar.joinConditions[j]
+                            .nonIndexCondition =
+                                ExpressionLogical
+                                    .andExpressions(e, conditions.rangeVar
+                                        .joinConditions[j].nonIndexCondition);
+                    } else {
+                        conditions.rangeVar.whereConditions[j]
+                            .nonIndexCondition =
+                                ExpressionLogical
+                                    .andExpressions(e, conditions.rangeVar
+                                        .whereConditions[j].nonIndexCondition);
+                    }
+                }
+            } else {
+                conditions.addCondition(e);
+            }
+        }
+    }
+
+    private boolean setOrConditions(RangeVariableConditions conditions,
+                                    ExpressionLogical orExpression,
+                                    int rangeVarIndex) {
+
+        HsqlArrayList orExprList = new HsqlArrayList();
+
+        decomposeOrConditions(orExpression, orExprList);
+
+        RangeVariableConditions[] conditionsArray =
+            new RangeVariableConditions[orExprList.size()];
+
+        for (int i = 0; i < orExprList.size(); i++) {
+            HsqlArrayList exprList = new HsqlArrayList();
+            Expression    e        = (Expression) orExprList.get(i);
+
+            decomposeAndConditions(e, exprList);
+
+            RangeVariableConditions c =
+                new RangeVariableConditions(conditions);
+
+            setIndexConditions(c, exprList, rangeVarIndex, false);
+
+            conditionsArray[i] = c;
+
+            if (!c.hasIndexCondition()) {
+
+                // deep OR
+                return false;
+            }
+        }
+
+        Expression e = null;
+
+        for (int i = 0; i < conditionsArray.length; i++) {
+            RangeVariableConditions c = conditionsArray[i];
+
+            conditionsArray[i].excludeConditions = e;
+
+            if (i > 1) {
+                Expression lastExpr = conditionsArray[i - 1].excludeConditions;
+
+                e = new ExpressionLogical(OpTypes.OR, e, lastExpr);
+            }
+
+            if (c.indexCond != null) {
+                for (int k = 0; k < c.indexedColumnCount; k++) {
+                    e = ExpressionLogical.andExpressions(e, c.indexCond[k]);
+                }
+            }
+
+            e = ExpressionLogical.andExpressions(e, c.indexEndCondition);
+            e = ExpressionLogical.andExpressions(e, c.nonIndexCondition);
+        }
+
+        if (e != null) {
+
+//            return false;
+        }
+
+        if (conditions.isJoin) {
+            conditions.rangeVar.joinConditions = conditionsArray;
+            conditionsArray = new RangeVariableConditions[orExprList.size()];
+
+            ArrayUtil.fillArray(conditionsArray,
+                                conditions.rangeVar.whereConditions[0]);
+
+            conditions.rangeVar.whereConditions = conditionsArray;
+        } else {
+            conditions.rangeVar.whereConditions = conditionsArray;
+            conditionsArray = new RangeVariableConditions[orExprList.size()];
+
+            ArrayUtil.fillArray(conditionsArray,
+                                conditions.rangeVar.joinConditions[0]);
+
+            conditions.rangeVar.joinConditions = conditionsArray;
+        }
+
+        return true;
+    }
+
+    private void setEqaulityConditions(RangeVariableConditions conditions,
+                                       HsqlArrayList exprList) {
+
+        Index idx = conditions.rangeVar.rangeTable.getIndexForColumns(session,
+            colIndexSetEqual, false);
+
+        if (idx == null) {
+            return;
+        }
+
+        int[]        cols                = idx.getColumns();
+        int          colCount            = cols.length;
+        Expression[] firstRowExpressions = new Expression[cols.length];
+
+        for (int j = 0; j < exprList.size(); j++) {
+            Expression e = (Expression) exprList.get(j);
+
+            if (e == null) {
+                continue;
+            }
+
+            int type = e.getType();
+
+            if (type == OpTypes.EQUAL || type == OpTypes.IS_NULL) {
+                if (e.getLeftNode().getRangeVariable()
+                        != conditions.rangeVar) {
+                    continue;
+                }
+
+                int offset = ArrayUtil.find(cols,
+                                            e.getLeftNode().getColumnIndex());
+
+                if (offset != -1 && firstRowExpressions[offset] == null) {
+                    firstRowExpressions[offset] = e;
+
+                    exprList.set(j, null);
+
+                    continue;
+                }
+            }
+        }
+
+        boolean hasNull = false;
+
+        for (int i = 0; i < firstRowExpressions.length; i++) {
+            Expression e = firstRowExpressions[i];
+
+            if (e == null) {
+                if (colCount == cols.length) {
+                    colCount = i;
+                }
+
+                hasNull = true;
+
+                continue;
+            }
+
+            if (hasNull) {
+                conditions.addCondition(e);
+
+                firstRowExpressions[i] = null;
+            }
+        }
+
+        conditions.addIndexCondition(firstRowExpressions, idx, colCount);
+    }
+
+    private void setNonEqualityConditions(RangeVariableConditions conditions,
+                                          HsqlArrayList exprList) {
+
+        if (colIndexSetOther.isEmpty()) {
+            return;
+        }
+
+        int      currentCount = 0;
+        int      currentIndex = 0;
+        Iterator it           = colIndexSetOther.keySet().iterator();
+
+        while (it.hasNext()) {
+            int colIndex = it.nextInt();
+            int colCount = colIndexSetOther.get(colIndex);
+
+            if (colCount > currentCount) {
+                currentIndex = colIndex;
+            }
+        }
+
+        Index idx = conditions.rangeVar.rangeTable.getIndexForColumn(session,
+            currentIndex);
+
+        if (idx == null) {
+            it = colIndexSetOther.keySet().iterator();
+
+            while (it.hasNext()) {
+                int colIndex = it.nextInt();
+
+                if (colIndex != currentIndex) {
+                    idx = conditions.rangeVar.rangeTable.getIndexForColumn(
+                        session, colIndex);
+
+                    if (idx != null) {
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (idx == null) {
+            return;
+        }
+
+        int[] cols = idx.getColumns();
+
+        for (int j = 0; j < exprList.size(); j++) {
+            Expression e = (Expression) exprList.get(j);
+
+            if (e == null) {
+                continue;
+            }
+
+            boolean isIndexed = false;
+
+            switch (e.getType()) {
+
+                case OpTypes.NOT : {
+                    if (e.getLeftNode().getType() == OpTypes.IS_NULL
+                            && cols[0]
+                               == e.getLeftNode().getLeftNode()
+                                   .getColumnIndex()) {
+                        isIndexed = true;
+                    }
+
+                    break;
+                }
+                case OpTypes.SMALLER :
+                case OpTypes.SMALLER_EQUAL :
+                case OpTypes.GREATER :
+                case OpTypes.GREATER_EQUAL : {
+                    if (cols[0] == e.getLeftNode().getColumnIndex()) {
+                        if (e.getRightNode() != null
+                                && !e.getRightNode().isCorrelated()) {
+                            isIndexed = true;
+                        }
+                    }
+
+                    break;
+                }
+            }
+
+            if (isIndexed) {
+                Expression[] firstRowExpressions =
+                    new Expression[idx.getColumnCount()];
+
+                firstRowExpressions[0] = e;
+
+                conditions.addIndexCondition(firstRowExpressions, idx, 1);
+                exprList.set(j, null);
+
+                break;
+            }
+        }
+    }
+
+    /**
+     * Converts an IN conditions into a JOIN
+     */
+    void setInConditionsAsTables() {
+
+        for (int i = rangeVariables.length - 1; i >= 0; i--) {
+            RangeVariable     rangeVar = rangeVariables[i];
+            ExpressionLogical in       = (ExpressionLogical) inExpressions[i];
+
+            if (in != null) {
+                OrderedIntHashSet set = new OrderedIntHashSet();
+
+                in.addLeftColumnsForAllAny(rangeVar, set);
+
+                Index index = rangeVar.rangeTable.getIndexForColumns(session,
+                    set, false);
+                int colCount = 0;
+
+                for (int j = 0; j < index.getColumnCount(); j++) {
+                    if (set.contains(index.getColumns()[j])) {
+                        colCount++;
+                    }
+                }
+
+                RangeVariable newRangeVar =
+                    new RangeVariable(in.getRightNode().getTable(), null,
+                                      null, null, compileContext);
+
+                newRangeVar.isGenerated = true;
+
+                RangeVariable[] newList =
+                    new RangeVariable[rangeVariables.length + 1];
+
+                ArrayUtil.copyAdjustArray(rangeVariables, newList,
+                                          newRangeVar, i, 1);
+
+                rangeVariables = newList;
+
+                // make two columns as arg
+                Expression[] exprList = new Expression[index.getColumnCount()];
+
+                for (int j = 0; j < colCount; j++) {
+                    int leftIndex  = index.getColumns()[j];
+                    int rightIndex = set.getIndex(leftIndex);
+                    Expression e = new ExpressionLogical(rangeVar, leftIndex,
+                                                         newRangeVar,
+                                                         rightIndex);
+
+                    exprList[j] = e;
+                }
+
+                boolean isOuter = rangeVariables[i].isLeftJoin
+                                  || rangeVariables[i].isRightJoin;
+                RangeVariableConditions conditions =
+                    !inInJoin[i] && isOuter ? rangeVar.whereConditions[0]
+                                            : rangeVar.joinConditions[0];
+
+                conditions.addIndexCondition(exprList, index, colCount);
+
+                if (isOuter) {
+                    conditions.addCondition(in);
+                }
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/Routine.java b/src/org/hsqldb/Routine.java
new file mode 100644
index 0000000..cffbf56
--- /dev/null
+++ b/src/org/hsqldb/Routine.java
@@ -0,0 +1,1069 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.HsqlNameManager.SimpleName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.jdbc.JDBCResultSet;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.result.Result;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.store.BitMap;
+import org.hsqldb.types.RowType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of specific routine
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ *
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class Routine implements SchemaObject {
+
+    public final static int NO_SQL       = 1;
+    public final static int CONTAINS_SQL = 2;
+    public final static int READS_SQL    = 3;
+    public final static int MODIFIES_SQL = 4;
+
+    //
+    public final static int LANGUAGE_JAVA = 1;
+    public final static int LANGUAGE_SQL  = 2;
+
+    //
+    public static final int PARAM_STYLE_JAVA = 1;
+    public static final int PARAM_STYLE_SQL  = 2;
+
+    //
+    final static Routine[] emptyArray = new Routine[]{};
+
+    //
+    RoutineSchema    routineSchema;
+    private HsqlName name;
+    private HsqlName specificName;
+    Type[]           parameterTypes;
+    int              typeGroups;
+    Type             returnType;
+    Type[]           tableType;
+    Table            returnTable;
+    final int        routineType;
+    int              language   = LANGUAGE_SQL;
+    int              dataImpact = CONTAINS_SQL;
+    int              parameterStyle;
+    boolean          isDeterministic;
+    boolean          isNullInputOutput;
+    boolean          isNewSavepointLevel = true;
+    boolean          isPSM;
+    boolean          returnsTable;
+    Statement        statement;
+
+    //
+    boolean isAggregate;
+
+    //
+    private String  methodName;
+    Method          javaMethod;
+    boolean         javaMethodWithConnection;
+    private boolean isLibraryRoutine;
+
+    //
+    HashMappedList  parameterList = new HashMappedList();
+    int             scopeVariableCount;
+    RangeVariable[] ranges;
+
+    //
+    int variableCount;
+
+    //
+    OrderedHashSet references;
+
+    //
+    Table triggerTable;
+    int   triggerType;
+    int   triggerOperation;
+
+    public Routine(int type) {
+
+        routineType = type;
+        returnType  = Type.SQL_ALL_TYPES;
+        ranges = new RangeVariable[]{
+            new RangeVariable(parameterList, false) };
+    }
+
+    public Routine(Table table, RangeVariable[] ranges, int impact,
+                   int triggerType, int operationType) {
+
+        routineType           = SchemaObject.TRIGGER;
+        returnType            = Type.SQL_ALL_TYPES;
+        dataImpact            = impact;
+        this.ranges           = ranges;
+        this.triggerTable     = table;
+        this.triggerType      = triggerType;
+        this.triggerOperation = operationType;
+    }
+
+    public int getType() {
+        return routineType;
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public HsqlName getSchemaName() {
+        return name.schema;
+    }
+
+    public HsqlName getCatalogName() {
+        return name.schema.schema;
+    }
+
+    public Grantee getOwner() {
+        return name.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+        return references;
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {
+
+        ParserRoutine p = new ParserRoutine(session,
+                                            new Scanner(statement.getSQL()));
+
+        p.read();
+        p.startRecording();
+
+        Statement statement = p.compileSQLProcedureStatementOrNull(this, null);
+        Token[]   tokenisedStatement = p.getRecordedStatement();
+        String    sql                = Token.getSQL(tokenisedStatement);
+
+        statement.setSQL(sql);
+        setProcedure(statement);
+        statement.resolve(session);
+        setReferences();
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_CREATE).append(' ');
+
+        if (isAggregate) {
+            sb.append(Tokens.T_AGGREGATE).append(' ');
+        }
+
+        if (routineType == SchemaObject.PROCEDURE) {
+            sb.append(Tokens.T_PROCEDURE);
+        } else {
+            sb.append(Tokens.T_FUNCTION);
+        }
+
+        sb.append(' ');
+        sb.append(name.getSchemaQualifiedStatementName());
+        sb.append('(');
+
+        for (int i = 0; i < parameterList.size(); i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+
+            ColumnSchema param = (ColumnSchema) parameterList.get(i);
+
+            // in - out
+            sb.append(param.getSQL());
+        }
+
+        sb.append(')');
+        sb.append(' ');
+
+        if (routineType == SchemaObject.FUNCTION) {
+            sb.append(Tokens.T_RETURNS);
+            sb.append(' ');
+
+            if (returnsTable) {
+                sb.append(Tokens.T_TABLE);
+                sb.append(returnTable.getColumnListWithTypeSQL());
+            } else {
+                sb.append(returnType.getTypeDefinition());
+            }
+
+            sb.append(' ');
+        }
+
+        // SPECIFIC
+        if (specificName != null) {
+            sb.append(Tokens.T_SPECIFIC);
+            sb.append(' ');
+            sb.append(specificName.getStatementName());
+            sb.append(' ');
+        }
+
+        //
+        sb.append(Tokens.T_LANGUAGE);
+        sb.append(' ');
+
+        if (language == LANGUAGE_JAVA) {
+            sb.append(Tokens.T_JAVA);
+        } else {
+            sb.append(Tokens.T_SQL);
+        }
+
+        sb.append(' ');
+
+        //
+        if (!isDeterministic) {
+            sb.append(Tokens.T_NOT);
+            sb.append(' ');
+        }
+
+        sb.append(Tokens.T_DETERMINISTIC);
+        sb.append(' ');
+
+        //
+        sb.append(getDataImpactString());
+        sb.append(' ');
+
+        //
+        if (routineType == SchemaObject.FUNCTION) {
+            if (isNullInputOutput) {
+                sb.append(Tokens.T_RETURNS).append(' ').append(Tokens.T_NULL);
+            } else {
+                sb.append(Tokens.T_CALLED);
+            }
+
+            sb.append(' ').append(Tokens.T_ON).append(' ');
+            sb.append(Tokens.T_NULL).append(' ').append(Tokens.T_INPUT);
+            sb.append(' ');
+        } else {
+            if (isNewSavepointLevel) {
+                sb.append(Tokens.T_NEW);
+            } else {
+                sb.append(Tokens.T_OLD);
+            }
+
+            sb.append(' ').append(Tokens.T_SAVEPOINT).append(' ');
+            sb.append(Tokens.T_LEVEL).append(' ');
+        }
+
+        if (language == LANGUAGE_JAVA) {
+            sb.append(Tokens.T_EXTERNAL).append(' ').append(Tokens.T_NAME);
+            sb.append(' ').append('\'').append(methodName).append('\'');
+        } else {
+            sb.append(statement.getSQL());
+        }
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    public void addParameter(ColumnSchema param) {
+
+        HsqlName name = param.getName();
+        String paramName =
+            name == null
+            ? HsqlNameManager.getAutoNoNameColumnString(parameterList.size())
+            : name.name;
+
+        parameterList.add(paramName, param);
+    }
+
+    public void setLanguage(int lang) {
+        language = lang;
+        isPSM    = language == LANGUAGE_SQL;
+    }
+
+    public int getLanguage() {
+        return language;
+    }
+
+    boolean isPSM() {
+        return isPSM;
+    }
+
+    public void setDataImpact(int impact) {
+        dataImpact = impact;
+    }
+
+    public int getDataImpact() {
+        return dataImpact;
+    }
+
+    public String getDataImpactString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        switch (this.dataImpact) {
+
+            case NO_SQL :
+                sb.append(Tokens.T_NO).append(' ').append(Tokens.T_SQL);
+                break;
+
+            case CONTAINS_SQL :
+                sb.append(Tokens.T_CONTAINS).append(' ').append(Tokens.T_SQL);
+                break;
+
+            case READS_SQL :
+                sb.append(Tokens.T_READS).append(' ').append(
+                    Tokens.T_SQL).append(' ').append(Tokens.T_DATA);
+                break;
+
+            case MODIFIES_SQL :
+                sb.append(Tokens.T_MODIFIES).append(' ').append(
+                    Tokens.T_SQL).append(' ').append(Tokens.T_DATA);
+                break;
+        }
+
+        return sb.toString();
+    }
+
+    public void setReturnType(Type type) {
+        returnType = type;
+    }
+
+    public Type getReturnType() {
+        return returnType;
+    }
+
+    public void setTableType(Type[] types) {
+        tableType = types;
+    }
+
+    public Type[] getTableType() {
+        return tableType;
+    }
+
+    public Table getTable() {
+        return returnTable;
+    }
+
+    public void setProcedure(Statement statement) {
+        this.statement = statement;
+    }
+
+    public Statement getProcedure() {
+        return statement;
+    }
+
+    public void setSpecificName(HsqlName name) {
+        specificName = name;
+    }
+
+    public void setName(HsqlName name) {
+        this.name = name;
+    }
+
+    public HsqlName getSpecificName() {
+        return specificName;
+    }
+
+    public void setDeterministic(boolean value) {
+        isDeterministic = value;
+    }
+
+    public boolean isDeterministic() {
+        return isDeterministic;
+    }
+
+    public void setNullInputOutput(boolean value) {
+        isNullInputOutput = value;
+    }
+
+    public boolean isNullInputOutput() {
+        return isNullInputOutput;
+    }
+
+    public void setNewSavepointLevel(boolean value) {
+        isNewSavepointLevel = value;
+    }
+
+    public void setParameterStyle(int style) {
+        parameterStyle = style;
+    }
+
+    public void setMethodURL(String url) {
+        this.methodName = url;
+    }
+
+    public Method getMethod() {
+        return javaMethod;
+    }
+
+    public void setMethod(Method method) {
+        this.javaMethod = method;
+    }
+
+    public void setReturnTable(TableDerived table) {
+
+        this.returnTable  = table;
+        this.returnsTable = true;
+
+        SimpleName[] names = new SimpleName[table.getColumnCount()];
+        Type[]       types = table.getColumnTypes();
+
+        returnType = new RowType(types);
+    }
+
+    public boolean returnsTable() {
+        return returnsTable;
+    }
+
+    public void setAggregate(boolean isAggregate) {
+        this.isAggregate = isAggregate;
+    }
+
+    public boolean isAggregate() {
+        return isAggregate;
+    }
+
+    public void resolve(Session session) {
+
+        setLanguage(language);
+
+        if (language == Routine.LANGUAGE_SQL) {
+            if (dataImpact == NO_SQL) {
+                throw Error.error(ErrorCode.X_42604);
+            }
+
+            if (parameterStyle == PARAM_STYLE_JAVA) {
+                throw Error.error(ErrorCode.X_42604);
+            }
+        }
+
+        if (language == Routine.LANGUAGE_SQL) {
+            if (parameterStyle != 0 && parameterStyle != PARAM_STYLE_SQL) {
+                throw Error.error(ErrorCode.X_42604);
+            }
+        }
+
+        parameterTypes = new Type[parameterList.size()];
+        typeGroups     = 0;
+
+        for (int i = 0; i < parameterTypes.length; i++) {
+            ColumnSchema param = (ColumnSchema) parameterList.get(i);
+
+            parameterTypes[i] = param.dataType;
+
+            if (i < 4) {
+                BitMap.setByte(typeGroups,
+                               (byte) param.dataType.typeComparisonGroup,
+                               i * 8);
+            }
+        }
+
+        if (statement != null) {
+            statement.resolve(session);
+
+            if (dataImpact == CONTAINS_SQL) {
+                checkNoSQLData(session.database, statement.getReferences());
+            }
+        }
+
+        if (methodName != null && javaMethod == null) {
+            boolean[] hasConnection = new boolean[1];
+
+            javaMethod = getMethod(methodName, this, hasConnection,
+                                   returnsTable);
+
+            if (javaMethod == null) {
+                throw Error.error(ErrorCode.X_46103);
+            }
+
+            javaMethodWithConnection = hasConnection[0];
+
+            String className = javaMethod.getDeclaringClass().getName();
+
+            if (className.equals("java.lang.Math")) {
+                isLibraryRoutine = true;
+            }
+        }
+
+        if (isAggregate) {
+            if (parameterTypes.length != 4) {
+                throw Error.error(ErrorCode.X_42610);
+            }
+
+            boolean check = parameterTypes[1].typeCode == Types.BOOLEAN;
+
+            //
+            ColumnSchema param = (ColumnSchema) parameterList.get(0);
+
+            check &= param.getParameterMode()
+                     == SchemaObject.ParameterModes.PARAM_IN;
+            param = (ColumnSchema) parameterList.get(1);
+            check &= param.getParameterMode()
+                     == SchemaObject.ParameterModes.PARAM_IN;
+            param = (ColumnSchema) parameterList.get(2);
+            check &= param.getParameterMode()
+                     == SchemaObject.ParameterModes.PARAM_INOUT;
+            param = (ColumnSchema) parameterList.get(3);
+            check &= param.getParameterMode()
+                     == SchemaObject.ParameterModes.PARAM_INOUT;
+
+            if (!check) {
+                throw Error.error(ErrorCode.X_42610);
+            }
+        }
+
+        setReferences();
+    }
+
+    private void setReferences() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0; i < parameterTypes.length; i++) {
+            ColumnSchema param = (ColumnSchema) parameterList.get(i);
+
+            set.addAll(param.getReferences());
+        }
+
+        if (statement != null) {
+            set.addAll(statement.getReferences());
+        }
+
+        references = set;
+    }
+
+    public boolean isTrigger() {
+        return routineType == SchemaObject.TRIGGER;
+    }
+
+    public boolean isProcedure() {
+        return routineType == SchemaObject.PROCEDURE;
+    }
+
+    public boolean isFunction() {
+        return routineType == SchemaObject.FUNCTION;
+    }
+
+    public ColumnSchema getParameter(int i) {
+        return (ColumnSchema) parameterList.get(i);
+    }
+
+    Type[] getParameterTypes() {
+        return parameterTypes;
+    }
+
+    int getParameterSignature() {
+        return typeGroups;
+    }
+
+    public int getParameterCount() {
+        return parameterTypes.length;
+    }
+
+    public int getParameterCount(int type) {
+
+        int count = 0;
+
+        for (int i = 0; i < parameterList.size(); i++) {
+            ColumnSchema col = (ColumnSchema) parameterList.get(i);
+
+            if (col.getParameterMode() == type) {
+                count++;
+            }
+        }
+
+        return count;
+    }
+
+    public int getParameterIndex(String name) {
+        return parameterList.getIndex(name);
+    }
+
+    public RangeVariable[] getParameterRangeVariables() {
+        return ranges;
+    }
+
+    public int getVariableCount() {
+        return variableCount;
+    }
+
+    public boolean isLibraryRoutine() {
+        return isLibraryRoutine;
+    }
+
+    public HsqlName[] getTableNamesForRead() {
+
+        if (statement == null) {
+            return HsqlName.emptyArray;
+        }
+
+        return statement.getTableNamesForRead();
+    }
+
+    public HsqlName[] getTableNamesForWrite() {
+
+        if (statement == null) {
+            return HsqlName.emptyArray;
+        }
+
+        return statement.getTableNamesForWrite();
+    }
+
+    Object[] convertArgsToJava(Session session, Object[] callArguments) {
+
+        int      extraArg = javaMethodWithConnection ? 1
+                                                     : 0;
+        Object[] data     = new Object[callArguments.length + extraArg];
+        Type[]   types    = getParameterTypes();
+
+        for (int i = 0; i < callArguments.length; i++) {
+            Object       value = callArguments[i];
+            ColumnSchema param = getParameter(i);
+
+            if (param.parameterMode == SchemaObject.ParameterModes.PARAM_IN) {
+                data[i + extraArg] = types[i].convertSQLToJava(session, value);
+            } else {
+                Object jdbcValue = types[i].convertSQLToJava(session, value);
+                Class  cl        = types[i].getJDBCClass();
+                Object array     = java.lang.reflect.Array.newInstance(cl, 1);
+
+                java.lang.reflect.Array.set(array, 0, jdbcValue);
+
+                data[i + extraArg] = array;
+            }
+        }
+
+        return data;
+    }
+
+    void convertArgsToSQL(Session session, Object[] callArguments,
+                          Object[] data) {
+
+        int    extraArg = javaMethodWithConnection ? 1
+                                                   : 0;
+        Type[] types    = getParameterTypes();
+
+        for (int i = 0; i < callArguments.length; i++) {
+            Object       value = data[i + extraArg];
+            ColumnSchema param = getParameter(i);
+
+            if (param.parameterMode != SchemaObject.ParameterModes.PARAM_IN) {
+                value = java.lang.reflect.Array.get(value, 0);
+            }
+
+            callArguments[i] = types[i].convertJavaToSQL(session, value);
+        }
+    }
+
+    Result invokeJavaMethod(Session session, Object[] data) {
+
+        Result result;
+
+        try {
+            if (dataImpact == Routine.NO_SQL) {
+                session.sessionContext.isReadOnly = Boolean.TRUE;
+
+                session.setNoSQL();
+            } else if (dataImpact == Routine.CONTAINS_SQL) {
+                session.sessionContext.isReadOnly = Boolean.TRUE;
+            } else if (dataImpact == Routine.READS_SQL) {
+                session.sessionContext.isReadOnly = Boolean.TRUE;
+            }
+
+            Object returnValue = javaMethod.invoke(null, data);
+
+            if (returnsTable()) {
+                if (returnValue instanceof JDBCResultSet) {
+                    result = ((JDBCResultSet) returnValue).result;
+                } else {
+
+                    // convert ResultSet to table
+                    throw Error.runtimeError(ErrorCode.U_S0500,
+                                             "FunctionSQLInvoked");
+                }
+            } else {
+                returnValue = returnType.convertJavaToSQL(session,
+                        returnValue);
+                result = Result.newPSMResult(returnValue);
+            }
+        } catch (InvocationTargetException e) {
+            result = Result.newErrorResult(
+                Error.error(ErrorCode.X_46000, getName().name), null);
+        } catch (IllegalAccessException e) {
+            result = Result.newErrorResult(
+                Error.error(ErrorCode.X_46000, getName().name), null);
+        } catch (Throwable e) {
+            result = Result.newErrorResult(
+                Error.error(ErrorCode.X_46000, getName().name), null);
+        }
+
+        return result;
+    }
+
+    static Method getMethod(String name, Routine routine,
+                            boolean[] hasConnection, boolean returnsTable) {
+
+        int i = name.indexOf(':');
+
+        if (i != -1) {
+            if (!name.substring(0, i).equals(SqlInvariants.CLASSPATH_NAME)) {
+                throw Error.error(ErrorCode.X_46102, name);
+            }
+
+            name = name.substring(i + 1);
+        }
+
+        Method[] methods       = getMethods(name);
+        int      firstMismatch = -1;
+
+        for (i = 0; i < methods.length; i++) {
+            int offset = 0;
+
+            hasConnection[0] = false;
+
+            Method  method = methods[i];
+            Class[] params = method.getParameterTypes();
+
+            if (params.length > 0
+                    && params[0].equals(java.sql.Connection.class)) {
+                offset           = 1;
+                hasConnection[0] = true;
+            }
+
+            if (params.length - offset != routine.parameterTypes.length) {
+                continue;
+            }
+
+            if (returnsTable) {
+                if (!java.sql.ResultSet.class.isAssignableFrom(
+                        method.getReturnType())) {
+                    continue;
+                }
+            } else {
+                Type methodReturnType =
+                    Types.getParameterSQLType(method.getReturnType());
+
+                if (methodReturnType == null) {
+                    continue;
+                }
+
+                if (methodReturnType.typeCode != routine.returnType.typeCode) {
+                    continue;
+                }
+            }
+
+            for (int j = 0; j < routine.parameterTypes.length; j++) {
+                boolean isInOut = false;
+                Class   param   = params[j + offset];
+
+                if (param.isArray()) {
+                    if (!byte[].class.equals(param)) {
+                        param = param.getComponentType();
+
+                        if (param.isPrimitive()) {
+                            method = null;
+
+                            break;
+                        }
+
+                        isInOut = true;
+                    }
+                }
+
+                Type methodParamType = Types.getParameterSQLType(param);
+
+                if (methodParamType == null) {
+                    method = null;
+
+                    break;
+                }
+
+                boolean result = routine.parameterTypes[j].typeComparisonGroup
+                                 == methodParamType.typeComparisonGroup;
+
+                // exact type for number
+                if (result && routine.parameterTypes[j].isNumberType()) {
+                    result = routine.parameterTypes[j].typeCode
+                             == methodParamType.typeCode;
+                }
+
+                if (isInOut
+                        && routine.getParameter(j).parameterMode
+                           == SchemaObject.ParameterModes.PARAM_IN) {
+                    result = false;
+                }
+
+                if (!result) {
+                    method = null;
+
+                    if (j + offset > firstMismatch) {
+                        firstMismatch = j + offset;
+                    }
+
+                    break;
+                }
+            }
+
+            if (method != null) {
+                for (int j = 0; j < routine.parameterTypes.length; j++) {
+                    routine.getParameter(j).setNullable(
+                        !params[j + offset].isPrimitive());
+                }
+
+                return method;
+            }
+        }
+
+        if (firstMismatch >= 0) {
+            ColumnSchema param = routine.getParameter(firstMismatch);
+
+            throw Error.error(ErrorCode.X_46511, param.getNameString());
+        }
+
+        return null;
+    }
+
+    static Method[] getMethods(String name) {
+
+        int i = name.lastIndexOf('.');
+
+        if (i == -1) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        String   className  = name.substring(0, i);
+        String   methodname = name.substring(i + 1);
+        Class    cl;
+        Method[] methods = null;
+
+        try {
+            cl = Class.forName(className, true,
+                               Thread.currentThread().getContextClassLoader());
+        } catch (Throwable t1) {
+            try {
+                cl = Class.forName(className);
+            } catch (Throwable t) {
+                throw Error.error(t, ErrorCode.X_42501,
+                                  ErrorCode.M_Message_Pair, new Object[] {
+                    t.getMessage(), className
+                });
+            }
+        }
+
+        try {
+            methods = cl.getMethods();
+        } catch (Throwable t) {
+            throw Error.error(t, ErrorCode.X_42501, ErrorCode.M_Message_Pair,
+                              new Object[] {
+                t.getMessage(), className
+            });
+        }
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        for (i = 0; i < methods.length; i++) {
+            int    offset    = 0;
+            Method method    = methods[i];
+            int    modifiers = method.getModifiers();
+
+            if (!method.getName().equals(methodname)
+                    || !Modifier.isStatic(modifiers)
+                    || !Modifier.isPublic(modifiers)) {
+                continue;
+            }
+
+            Class[] params = methods[i].getParameterTypes();
+
+            if (params.length > 0
+                    && params[0].equals(java.sql.Connection.class)) {
+                offset = 1;
+            }
+
+            for (int j = offset; j < params.length; j++) {
+                Class param = params[j];
+
+                if (param.isArray()) {
+                    if (!byte[].class.equals(param)) {
+                        param = param.getComponentType();
+
+                        if (param.isPrimitive()) {
+                            method = null;
+
+                            break;
+                        }
+                    }
+                }
+
+                Type methodParamType = Types.getParameterSQLType(param);
+
+                if (methodParamType == null) {
+                    method = null;
+
+                    break;
+                }
+            }
+
+            if (method == null) {
+                continue;
+            }
+
+            if (java.sql.ResultSet.class.isAssignableFrom(
+                    method.getReturnType())) {
+                list.add(methods[i]);
+            } else {
+                Type methodReturnType =
+                    Types.getParameterSQLType(method.getReturnType());
+
+                if (methodReturnType != null) {
+                    list.add(methods[i]);
+                }
+            }
+        }
+
+        methods = new Method[list.size()];
+
+        list.toArray(methods);
+
+        return methods;
+    }
+
+    public static Routine[] newRoutines(Session session, Method[] methods) {
+
+        Routine[] routines = new Routine[methods.length];
+
+        for (int i = 0; i < methods.length; i++) {
+            Method method = methods[i];
+
+            routines[i] = newRoutine(session, method);
+        }
+
+        return routines;
+    }
+
+    /**
+     * Returns a new function Routine object based solely on a Java Method object.
+     */
+    public static Routine newRoutine(Session session, Method method) {
+
+        Routine      routine   = new Routine(SchemaObject.FUNCTION);
+        int          offset    = 0;
+        Class[]      params    = method.getParameterTypes();
+        String       className = method.getDeclaringClass().getName();
+        StringBuffer sb        = new StringBuffer();
+
+        sb.append("CLASSPATH:");
+        sb.append(method.getDeclaringClass().getName()).append('.');
+        sb.append(method.getName());
+
+        if (params.length > 0 && params[0].equals(java.sql.Connection.class)) {
+            offset = 1;
+        }
+
+        String name = sb.toString();
+
+        if (className.equals("java.lang.Math")) {
+            routine.isLibraryRoutine = true;
+        }
+
+        for (int j = offset; j < params.length; j++) {
+            Type methodParamType = Types.getParameterSQLType(params[j]);
+            ColumnSchema param = new ColumnSchema(null, methodParamType,
+                                                  !params[j].isPrimitive(),
+                                                  false, null);
+
+            routine.addParameter(param);
+        }
+
+        routine.setLanguage(Routine.LANGUAGE_JAVA);
+        routine.setMethod(method);
+        routine.setMethodURL(name);
+        routine.setDataImpact(Routine.NO_SQL);
+
+        Type methodReturnType =
+            Types.getParameterSQLType(method.getReturnType());
+
+        routine.javaMethodWithConnection = offset == 1;;
+
+        routine.setReturnType(methodReturnType);
+        routine.resolve(session);
+
+        return routine;
+    }
+
+    public static void createRoutines(Session session, HsqlName schema,
+                                      String name) {
+
+        Method[]  methods  = Routine.getMethods(name);
+        Routine[] routines = Routine.newRoutines(session, methods);
+        HsqlName routineName = session.database.nameManager.newHsqlName(schema,
+            name, true, SchemaObject.FUNCTION);
+
+        for (int i = 0; i < routines.length; i++) {
+            routines[i].setName(routineName);
+            session.database.schemaManager.addSchemaObject(routines[i]);
+        }
+    }
+
+    static void checkNoSQLData(Database database, OrderedHashSet set) {
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName name = (HsqlName) set.get(i);
+
+            if (name.type == SchemaObject.SPECIFIC_ROUTINE) {
+                Routine routine =
+                    (Routine) database.schemaManager.getSchemaObject(name);
+
+                if (routine.dataImpact == Routine.READS_SQL) {
+                    throw Error.error(ErrorCode.X_42608,
+                                      Tokens.T_READS + " " + Tokens.T_SQL);
+                } else if (routine.dataImpact == Routine.MODIFIES_SQL) {
+                    throw Error.error(ErrorCode.X_42608,
+                                      Tokens.T_MODIFIES + " " + Tokens.T_SQL);
+                } else if (name.type == SchemaObject.TABLE) {
+                    throw Error.error(ErrorCode.X_42608,
+                                      Tokens.T_READS + " " + Tokens.T_SQL);
+                }
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/RoutineSchema.java b/src/org/hsqldb/RoutineSchema.java
new file mode 100644
index 0000000..89a546c
--- /dev/null
+++ b/src/org/hsqldb/RoutineSchema.java
@@ -0,0 +1,339 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of SQL procedure and functions
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ *
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RoutineSchema implements SchemaObject {
+
+    Routine[]        routines = Routine.emptyArray;
+    int              routineType;
+    private HsqlName name;
+
+    public RoutineSchema(int type, HsqlName name) {
+        routineType = type;
+        this.name   = name;
+    }
+
+    public int getType() {
+        return routineType;
+    }
+
+    public HsqlName getCatalogName() {
+        return name.schema.schema;
+    }
+
+    public HsqlName getSchemaName() {
+        return name.schema;
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public Grantee getOwner() {
+        return name.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0; i < routines.length; i++) {
+            set.addAll(routines[i].getReferences());
+        }
+
+        return set;
+    }
+
+    public OrderedHashSet getComponents() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        set.addAll(routines);
+
+        return set;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public String getSQL() {
+        return null;
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    public String[] getSQLArray() {
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        for (int i = 0; i < routines.length; i++) {
+            list.add(routines[i].getSQL());
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public void addSpecificRoutine(Database database, Routine routine) {
+
+        int    signature = routine.getParameterSignature();
+        Type[] types     = routine.getParameterTypes();
+
+        for (int i = 0; i < this.routines.length; i++) {
+            if (routines[i].parameterTypes.length == types.length) {
+                if (routineType == SchemaObject.PROCEDURE) {
+                    throw Error.error(ErrorCode.X_42605);
+                }
+
+                if (routines[i].isAggregate() != routine.isAggregate()) {
+                    throw Error.error(ErrorCode.X_42605);
+                }
+
+                boolean match = true;
+
+                for (int j = 0; j < types.length; j++) {
+                    if (!routines[i].parameterTypes[j].equals(types[j])) {
+                        match = false;
+
+                        break;
+                    }
+                }
+
+                if (match) {
+                    throw Error.error(ErrorCode.X_42605);
+                }
+            }
+        }
+
+        if (routine.getSpecificName() == null) {
+            HsqlName specificName =
+                database.nameManager.newSpecificRoutineName(name);
+
+            routine.setSpecificName(specificName);
+        } else {
+            routine.getSpecificName().parent = name;
+            routine.getSpecificName().schema = name.schema;
+        }
+
+        routine.setName(name);
+
+        routine.routineSchema = this;
+        routines = (Routine[]) ArrayUtil.resizeArray(routines,
+                routines.length + 1);
+        routines[routines.length - 1] = routine;
+    }
+
+    public void removeSpecificRoutine(Routine routine) {
+
+        for (int i = 0; i < this.routines.length; i++) {
+            if (routines[i] == routine) {
+                routines = (Routine[]) ArrayUtil.toAdjustedArray(routines,
+                        null, i, -1);
+
+                break;
+            }
+        }
+    }
+
+    public Routine[] getSpecificRoutines() {
+        return routines;
+    }
+
+    public Routine getSpecificRoutine(Type[] types) {
+
+        int matchIndex = -1;
+
+        outerLoop:
+        for (int i = 0; i < this.routines.length; i++) {
+            int matchCount = 0;
+
+            if (routines[i].isAggregate()) {
+                if (types.length == 1) {
+                    if (types[0] == null) {
+                        return routines[i];
+                    }
+
+                    int typeDifference = types[0].precedenceDegree(
+                        routines[i].parameterTypes[0]);
+
+                    if (typeDifference < -NumberType.DOUBLE_WIDTH) {
+                        if (matchIndex == -1) {
+                            continue;
+                        }
+
+                        int oldDiff = types[0].precedenceDegree(
+                            routines[matchIndex].parameterTypes[0]);
+                        int newDiff = types[0].precedenceDegree(
+                            routines[i].parameterTypes[0]);
+
+                        if (oldDiff == newDiff) {
+                            continue outerLoop;
+                        }
+
+                        if (newDiff < oldDiff) {
+                            matchIndex = i;
+                        }
+
+                        continue outerLoop;
+                    } else if (typeDifference == 0) {
+                        return routines[i];
+                    } else {
+                        matchIndex = i;
+
+                        continue outerLoop;
+                    }
+                }
+
+                // treat routine as non-aggregate
+            }
+
+            if (routines[i].parameterTypes.length != types.length) {
+                continue;
+            }
+
+            if (types.length == 0) {
+                return this.routines[i];
+            }
+
+            for (int j = 0; j < types.length; j++) {
+                int typeDifference;
+
+                // parameters
+                if (types[j] == null) {
+                    continue;
+                }
+
+                typeDifference =
+                    types[j].precedenceDegree(routines[i].parameterTypes[j]);
+
+                if (typeDifference < -NumberType.DOUBLE_WIDTH) {
+
+                    // accept numeric type narrowing
+                    continue outerLoop;
+                } else if (typeDifference == 0) {
+                    if (matchCount == j) {
+                        matchCount = j + 1;
+                    }
+                }
+            }
+
+            if (matchCount == types.length) {
+                return routines[i];
+            }
+
+            if (matchIndex == -1) {
+                matchIndex = i;
+
+                continue;
+            }
+
+            for (int j = 0; j < types.length; j++) {
+                if (types[j] == null) {
+                    continue;
+                }
+
+                int oldDiff = types[j].precedenceDegree(
+                    routines[matchIndex].parameterTypes[j]);
+                int newDiff =
+                    types[j].precedenceDegree(routines[i].parameterTypes[j]);
+
+                if (oldDiff == newDiff) {
+                    continue;
+                }
+
+                if (newDiff < oldDiff) {
+                    matchIndex = i;
+                }
+
+                continue outerLoop;
+            }
+        }
+
+        if (matchIndex < 0) {
+            StringBuffer sb = new StringBuffer();
+
+            sb.append(name.getSchemaQualifiedStatementName());
+            sb.append(Tokens.T_OPENBRACKET);
+
+            for (int i = 0; i < types.length; i++) {
+                if (i != 0) {
+                    sb.append(Tokens.T_COMMA);
+                }
+
+                sb.append(types[i].getNameString());
+            }
+
+            sb.append(Tokens.T_CLOSEBRACKET);
+
+            throw Error.error(ErrorCode.X_42609, sb.toString());
+        }
+
+        return routines[matchIndex];
+    }
+
+    public Routine getSpecificRoutine(int paramCount) {
+
+        for (int i = 0; i < this.routines.length; i++) {
+            if (routines[i].parameterTypes.length == paramCount) {
+                return routines[i];
+            }
+        }
+
+        throw Error.error(ErrorCode.X_42501);
+    }
+
+    public boolean isAggregate() {
+        return routines[0].isAggregate;
+    }
+}
diff --git a/src/org/hsqldb/Row.java b/src/org/hsqldb/Row.java
new file mode 100644
index 0000000..a1afaed
--- /dev/null
+++ b/src/org/hsqldb/Row.java
@@ -0,0 +1,178 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.lib.IntLookup;
+import org.hsqldb.persist.CachedObject;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/**
+ * Base class for a database row object.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge dot net)
+ * @version 1.9.0
+ */
+public class Row implements CachedObject {
+
+    int                       position;
+    Object[]                  rowData;
+    public volatile RowAction rowAction;
+    protected TableBase       table;
+
+    public RowAction getAction() {
+        return rowAction;
+    }
+
+    /**
+     *  Default constructor used only in subclasses.
+     */
+    public Row(TableBase table, Object[] data) {
+        this.table   = table;
+        this.rowData = data;
+    }
+
+    /**
+     * Returns the array of fields in the database row.
+     */
+    public Object[] getData() {
+        return rowData;
+    }
+
+    boolean isDeleted(Session session, PersistentStore store) {
+
+        Row       row    = (Row) store.get(this, false);
+        RowAction action = row.rowAction;
+
+        if (action == null) {
+            return false;
+        }
+
+        return !action.canRead(session, TransactionManager.ACTION_READ);
+    }
+
+    public void setChanged() {}
+
+    public void setStorageSize(int size) {}
+
+    public int getStorageSize() {
+        return 0;
+    }
+
+    public boolean isMemory() {
+        return true;
+    }
+
+    public void updateAccessCount(int count) {}
+
+    public int getAccessCount() {
+        return 0;
+    }
+
+    public int getPos() {
+        return position;
+    }
+
+    public long getId() {
+        return ((long) table.getId() << 32) + (long) position;
+    }
+
+    public void setPos(int pos) {
+        position = pos;
+    }
+
+    public boolean hasChanged() {
+        return false;
+    }
+
+    public boolean isKeepInMemory() {
+        return true;
+    }
+
+    public boolean keepInMemory(boolean keep) {
+        return true;
+    }
+
+    public boolean isInMemory() {
+        return true;
+    }
+
+    public void setInMemory(boolean in) {}
+
+    public void delete(PersistentStore store) {}
+
+    public void restore() {}
+
+    public void destroy() {}
+
+    public int getRealSize(RowOutputInterface out) {
+        return 0;
+    }
+
+    public TableBase getTable() {
+        return table;
+    }
+
+    public void write(RowOutputInterface out) {}
+
+    public void write(RowOutputInterface out, IntLookup lookup) {}
+
+    /**
+     * Lifetime scope of this method is limited depends on the operations
+     * performed. Rows deleted completely can equal rows produced later.
+     * This can return invalid results if used with deleted rows.
+     *
+     * @param obj row to compare
+     * @return boolean
+     */
+    public boolean equals(Object obj) {
+
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj instanceof Row) {
+            return ((Row) obj).position == position;
+        }
+
+        return false;
+    }
+
+    /**
+     * Hash code is always valid.
+     *
+     * @return file position of row
+     */
+    public int hashCode() {
+        return position;
+    }
+}
diff --git a/src/org/hsqldb/RowAVL.java b/src/org/hsqldb/RowAVL.java
new file mode 100644
index 0000000..7e09ec3
--- /dev/null
+++ b/src/org/hsqldb/RowAVL.java
@@ -0,0 +1,213 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.index.NodeAVL;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.persist.PersistentStore;
+
+// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
+// fredt@users 20020920 - patch 1.7.1 - refactoring to cut mamory footprint
+// fredt@users 20021215 - doc 1.7.2 - javadoc comments
+
+/**
+ * Base class for a database row object implementing rows for
+ * memory resident tables.<p>
+ *
+ * Subclass RowAVLDisk implements rows for CACHED and TEXT tables.<p>
+ * New class derived from Hypersonic SQL code and enhanced in HSQLDB.<p>
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class RowAVL extends Row {
+
+    public NodeAVL nPrimaryNode;
+
+    /**
+     *  Default constructor used only in subclasses.
+     */
+    protected RowAVL(TableBase table, Object[] data) {
+        super(table, data);
+    }
+
+    /**
+     *  Constructor for MEMORY table Row. The result is a Row with Nodes that
+     *  are not yet linked with other Nodes in the AVL indexes.
+     */
+    public RowAVL(TableBase table, Object[] data, int position) {
+
+        super(table, data);
+
+        this.position = position;
+
+        setNewNodes();
+    }
+
+    public void setNewNodes() {
+
+        int indexCount = table.getIndexCount();
+
+        nPrimaryNode = new NodeAVL(this);
+
+        NodeAVL n = nPrimaryNode;
+
+        for (int i = 1; i < indexCount; i++) {
+            n.nNext = new NodeAVL(this);
+            n       = n.nNext;
+        }
+    }
+
+    /**
+     * Returns the Node for a given Index, using the ordinal position of the
+     * Index within the Table Object.
+     */
+    public NodeAVL getNode(int index) {
+
+        NodeAVL n = nPrimaryNode;
+
+        while (index-- > 0) {
+            n = n.nNext;
+        }
+
+        return n;
+    }
+
+    /**
+     *  Returns the Node for the next Index on this database row, given the
+     *  Node for any Index.
+     */
+    NodeAVL getNextNode(NodeAVL n) {
+
+        if (n == null) {
+            n = nPrimaryNode;
+        } else {
+            n = n.nNext;
+        }
+
+        return n;
+    }
+
+    public NodeAVL insertNode(int index) {
+
+        NodeAVL backnode = getNode(index - 1);
+        NodeAVL newnode  = new NodeAVL(this);
+
+        newnode.nNext  = backnode.nNext;
+        backnode.nNext = newnode;
+
+        return newnode;
+    }
+
+    public void clearNonPrimaryNodes() {
+
+        NodeAVL n = nPrimaryNode.nNext;
+
+        while (n != null) {
+            n.delete();
+
+            n.iBalance = 0;
+            n          = n.nNext;
+        }
+    }
+
+    public void delete(PersistentStore store) {
+
+        NodeAVL n = nPrimaryNode;
+
+        while (n != null) {
+            n.delete();
+
+            n = n.nNext;
+        }
+    }
+
+    public void restore() {}
+
+    public void destroy() {
+
+        JavaSystem.memoryRecords++;
+
+        clearNonPrimaryNodes();
+
+        NodeAVL n = nPrimaryNode.nNext;
+
+        while (n != null) {
+            NodeAVL last = n;
+
+            n          = n.nNext;
+            last.nNext = null;
+        }
+
+        nPrimaryNode = null;
+    }
+}
diff --git a/src/org/hsqldb/RowAVLDisk.java b/src/org/hsqldb/RowAVLDisk.java
new file mode 100644
index 0000000..34ae794
--- /dev/null
+++ b/src/org/hsqldb/RowAVLDisk.java
@@ -0,0 +1,433 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb;
+
+import java.io.IOException;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.NodeAVL;
+import org.hsqldb.index.NodeAVLDisk;
+import org.hsqldb.lib.IntLookup;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
+// fredt@users 20020920 - patch 1.7.1 - refactoring to cut memory footprint
+// fredt@users 20021205 - patch 1.7.2 - enhancements
+// fredt@users 20021215 - doc 1.7.2 - javadoc comments
+// boucherb@users - 20040411 - doc 1.7.2 - javadoc comments
+
+/**
+ *  In-memory representation of a disk-based database row object with  methods
+ *  for serialization and de-serialization. <p>
+ *
+ *  A CachedRow is normally part of a circular double linked list which
+ *  contains all of the Rows currently in the Cache for the database. It is
+ *  unlinked from this list when it is freed from the Cache to make way for
+ *  other rows.<p>
+ *
+ *  New class derived from Hypersonic SQL code and enhanced in HSQLDB. <p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge dot net)
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class RowAVLDisk extends RowAVL {
+
+    public static final int NO_POS = -1;
+
+    //
+    int     storageSize;
+    int     keepCount;
+    boolean isInMemory;
+    int     accessCount;
+
+    /**
+     *  Flag indicating unwritten data.
+     */
+    protected boolean hasDataChanged;
+
+    /**
+     *  Flag indicating Node data has changed.
+     */
+    boolean hasNodesChanged;
+
+    /**
+     *  Constructor for new Rows.  Variable hasDataChanged is set to true in
+     *  order to indicate the data needs saving.
+     *
+     * @param t table
+     * @param o row data
+     */
+    public RowAVLDisk(TableBase t, Object[] o) {
+
+        super(t, o);
+
+        setNewNodes();
+
+        hasDataChanged = hasNodesChanged = true;
+    }
+
+    /**
+     *  Constructor when read from the disk into the Cache.
+     *
+     * @param t table
+     * @param in data source
+     * @throws IOException
+     */
+    public RowAVLDisk(TableBase t, RowInputInterface in) throws IOException {
+
+        super(t, null);
+
+        position    = in.getPos();
+        storageSize = in.getSize();
+
+        int indexcount = t.getIndexCount();
+
+        nPrimaryNode = new NodeAVLDisk(this, in, 0);
+
+        NodeAVL n = nPrimaryNode;
+
+        for (int i = 1; i < indexcount; i++) {
+            n.nNext = new NodeAVLDisk(this, in, i);
+            n       = n.nNext;
+        }
+
+        rowData = in.readData(table.getColumnTypes());
+    }
+
+    public NodeAVL insertNode(int index) {
+        return null;
+    }
+
+    private void readRowInfo(RowInputInterface in) throws IOException {
+
+        // for use when additional transaction info is attached to rows
+    }
+
+    /**
+     * Sets flag for Node data change.
+     */
+    public synchronized void setNodesChanged() {
+        hasNodesChanged = true;
+    }
+
+    public void updateAccessCount(int count) {
+        accessCount = count;
+    }
+
+    public int getAccessCount() {
+        return accessCount;
+    }
+
+    public int getStorageSize() {
+        return storageSize;
+    }
+
+    public boolean isMemory() {
+        return false;
+    }
+
+    /**
+     * Sets the file position for the row
+     *
+     * @param pos position in data file
+     */
+    public void setPos(int pos) {
+
+        position = pos;
+
+        NodeAVL n = nPrimaryNode;
+
+        while (n != null) {
+            ((NodeAVLDisk) n).iData = position;
+            n                       = n.nNext;
+        }
+    }
+
+    /**
+     * Sets flag for row data change.
+     */
+    public synchronized void setChanged() {
+        hasDataChanged = true;
+    }
+
+    /**
+     * Returns true if Node data has changed.
+     *
+     * @return boolean
+     */
+    public synchronized boolean hasChanged() {
+        return hasNodesChanged || hasDataChanged;
+    }
+
+    /**
+     * Returns the Table to which this Row belongs.
+     *
+     * @return Table
+     */
+    public TableBase getTable() {
+        return table;
+    }
+
+    public void setStorageSize(int size) {
+        storageSize = size;
+    }
+
+    /**
+     * Returns true if any of the Nodes for this row is a root node.
+     * Used only in Cache.java to avoid removing the row from the cache.
+     *
+     * @return boolean
+     */
+    public synchronized boolean isKeepInMemory() {
+        return keepCount > 0;
+    }
+
+    /**
+     * Only unlinks nodes. Is not a destroy() method
+     */
+    public void delete(PersistentStore store) {
+
+        RowAVLDisk row = this;
+
+        if (!row.keepInMemory(true)) {
+            row = (RowAVLDisk) store.get(row, true);
+        }
+
+        super.delete(store);
+        row.keepInMemory(false);
+    }
+
+    public void destroy() {
+        nPrimaryNode = null;
+        table        = null;
+    }
+
+    public synchronized boolean keepInMemory(boolean keep) {
+
+        if (!isInMemory) {
+            return false;
+        }
+
+        if (keep) {
+            keepCount++;
+        } else {
+            keepCount--;
+
+            if (keepCount < 0) {
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "RowAVLDisk - keep count");
+            }
+        }
+
+        return true;
+    }
+
+    public synchronized boolean isInMemory() {
+        return isInMemory;
+    }
+
+    public synchronized void setInMemory(boolean in) {
+
+        isInMemory = in;
+
+        if (in) {
+            return;
+        }
+
+        NodeAVL n = nPrimaryNode;
+
+        while (n != null) {
+            n.setInMemory(in);
+
+            n = n.nNext;
+        }
+    }
+
+    /**
+     * used in CachedDataRow
+     */
+    public void setNewNodes() {
+
+        int indexcount = table.getIndexCount();
+
+        nPrimaryNode = new NodeAVLDisk(this, 0);
+
+        NodeAVL n = nPrimaryNode;
+
+        for (int i = 1; i < indexcount; i++) {
+            n.nNext = new NodeAVLDisk(this, i);
+            n       = n.nNext;
+        }
+    }
+
+    public int getRealSize(RowOutputInterface out) {
+
+        int size = out.getSize((RowAVLDisk) this)
+                   + table.getIndexCount() * NodeAVLDisk.SIZE_IN_BYTE;
+
+        return size;
+    }
+
+    /**
+     * Used exclusively by Cache to save the row to disk. New implementation in
+     * 1.7.2 writes out only the Node data if the table row data has not
+     * changed. This situation accounts for the majority of invocations as for
+     * each row deleted or inserted, the Nodes for several other rows will
+     * change.
+     */
+    public void write(RowOutputInterface out) {
+
+        try {
+            writeNodes(out);
+
+            if (hasDataChanged) {
+                out.writeData(rowData, table.colTypes);
+                out.writeEnd();
+
+                hasDataChanged = false;
+            }
+        } catch (IOException e) {}
+    }
+
+    public void write(RowOutputInterface out, IntLookup lookup) {
+
+        out.writeSize(storageSize);
+
+        NodeAVL rownode = nPrimaryNode;
+
+        while (rownode != null) {
+            ((NodeAVLDisk) rownode).write(out, lookup);
+
+            rownode = rownode.nNext;
+        }
+
+        out.writeData(getData(), table.colTypes);
+        out.writeEnd();
+    }
+
+    /**
+     *  Writes the Nodes, immediately after the row size.
+     *
+     * @param out
+     *
+     * @throws IOException
+     */
+    private void writeNodes(RowOutputInterface out) throws IOException {
+
+        out.writeSize(storageSize);
+
+        NodeAVL n = nPrimaryNode;
+
+        while (n != null) {
+            n.write(out);
+
+            n = n.nNext;
+        }
+
+        hasNodesChanged = false;
+    }
+
+    /**
+     * Lifetime scope of this method depends on the operations performed on
+     * any cached tables since this row or the parameter were constructed.
+     * If only deletes or only inserts have been performed, this method
+     * remains valid. Otherwise it can return invalid results.
+     *
+     * @param obj row to compare
+     * @return boolean
+     */
+    public boolean equals(Object obj) {
+
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj instanceof RowAVLDisk) {
+            return ((RowAVLDisk) obj).position == position;
+        }
+
+        return false;
+    }
+
+    /**
+     * Hash code is valid only until a modification to the cache
+     *
+     * @return file position of row
+     */
+    public int hashCode() {
+        return position;
+    }
+}
diff --git a/src/org/hsqldb/RowAVLDiskData.java b/src/org/hsqldb/RowAVLDiskData.java
new file mode 100644
index 0000000..08bab9a
--- /dev/null
+++ b/src/org/hsqldb/RowAVLDiskData.java
@@ -0,0 +1,226 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.io.IOException;
+
+import org.hsqldb.index.NodeAVL;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+// fredt@users 20021205 - path 1.7.2 - enhancements
+// fredt@users 20021215 - doc 1.7.2 - javadoc comments
+
+/**
+ * Implementation of rows for tables with memory resident indexes and
+ * disk-based data, such as TEXT tables.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @version 1.7.0
+ */
+public class RowAVLDiskData extends RowAVL {
+
+    PersistentStore store;
+    int             accessCount;
+    boolean         hasDataChanged;
+    int             storageSize;
+
+    /**
+     *  Constructor for new rows.
+     */
+    public RowAVLDiskData(PersistentStore store, TableBase t, Object[] o) {
+
+        super(t, o);
+
+        setNewNodes();
+
+        hasDataChanged = true;
+        this.store     = store;
+    }
+
+    /**
+     *  Constructor when read from the disk into the Cache. The link with
+     *  the Nodes is made separetly.
+     */
+    public RowAVLDiskData(PersistentStore store, TableBase t,
+                          RowInputInterface in) throws IOException {
+
+        super(t, (Object[]) null);
+
+        setNewNodes();
+
+        position       = in.getPos();
+        storageSize    = in.getSize();
+        rowData        = in.readData(table.getColumnTypes());
+        hasDataChanged = false;
+        this.store     = store;
+    }
+
+    public void setData(Object[] data) {
+        this.rowData = data;
+    }
+
+    public Object[] getData() {
+
+        if (rowData == null) {
+            store.get(this, false);
+        } else {
+            accessCount++;
+        }
+
+        return rowData;
+    }
+
+    /**
+     *  Used when data is read from the disk into the Cache the first time.
+     *  New Nodes are created which are then indexed.
+     */
+    public void setNewNodes() {
+
+        int index = table.getIndexCount();
+
+        nPrimaryNode = new NodeAVL(this);
+
+        NodeAVL n = nPrimaryNode;
+
+        for (int i = 1; i < index; i++) {
+            n.nNext = new NodeAVL(this);
+            n       = n.nNext;
+        }
+    }
+
+    public NodeAVL insertNode(int index) {
+
+        NodeAVL backnode = getNode(index - 1);
+        NodeAVL newnode  = new NodeAVL(this);
+
+        newnode.nNext  = backnode.nNext;
+        backnode.nNext = newnode;
+
+        return newnode;
+    }
+
+    /**
+     *  Used when data is re-read from the disk into the Cache. The Row is
+     *  already indexed so it is linked with the Node in the primary index.
+     *  the Nodes is made separetly.
+     */
+    void setPrimaryNode(NodeAVL primary) {
+        nPrimaryNode = primary;
+    }
+
+    public int getRealSize(RowOutputInterface out) {
+        return out.getSize((RowAVL) this);
+    }
+
+    /**
+     *  Writes the data to disk. Unlike CachedRow, hasChanged is never set
+     *  to true when changes are made to the Nodes. (Nodes are in-memory).
+     *  The only time this is used is when a new Row is added to the Caches.
+     */
+    public void write(RowOutputInterface out) {
+
+        out.writeSize(storageSize);
+        out.writeData(getData(), table.colTypes);
+        out.writeEnd();
+
+        hasDataChanged = false;
+    }
+
+    public boolean hasChanged() {
+        return hasDataChanged;
+    }
+
+    public void updateAccessCount(int count) {
+        accessCount = count;
+    }
+
+    public int getAccessCount() {
+        return accessCount;
+    }
+
+    public int getStorageSize() {
+        return storageSize;
+    }
+
+    public void setStorageSize(int size) {
+        storageSize = size;
+    }
+    /**
+     * Sets the file position for the row and registers the row with
+     * the table.
+     *
+     * @param pos position in data file
+     */
+    public void setPos(int pos) {
+        position = pos;
+    }
+
+    public boolean isMemory() {
+        return true;
+    }
+
+    /**
+     * With the current implementation of TEXT table updates and inserts,
+     * the lifetime scope of this method extends until redefinition of table
+     * data source or shutdown.
+     *
+     * @param obj the reference object with which to compare.
+     * @return <code>true</code> if this object is the same as the obj argument;
+     *   <code>false</code> otherwise.
+     */
+    public boolean equals(Object obj) {
+        return obj == this;
+    }
+
+    public boolean isInMemory() {
+        return rowData != null;
+    }
+
+    public boolean isKeepInMemory() {
+        return false;
+    }
+
+    public boolean keepInMemory(boolean keep) {
+        return true;
+    }
+
+    public void setInMemory(boolean in) {
+
+        if (!in) {
+            rowData = null;
+        }
+    }
+}
diff --git a/src/org/hsqldb/RowAction.java b/src/org/hsqldb/RowAction.java
new file mode 100644
index 0000000..02000d6
--- /dev/null
+++ b/src/org/hsqldb/RowAction.java
@@ -0,0 +1,890 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.persist.PersistentStore;
+
+/**
+ * Represents the chain of insert / delete / rollback / commit actions on a row.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge dot net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class RowAction extends RowActionBase {
+
+    //
+    final TableBase       table;
+    final PersistentStore store;
+    Row                   memoryRow;
+    int                   rowId;
+    boolean               isMemory;
+    RowAction             updatedAction;
+
+    public static RowAction addInsertAction(Session session, TableBase table,
+            Row row) {
+
+        RowAction action = new RowAction(session, table, ACTION_INSERT, row,
+                                         null);
+
+        row.rowAction = action;
+
+        return action;
+    }
+
+    public static RowAction addDeleteAction(Session session, TableBase table,
+            Row row, int[] colMap) {
+
+        RowAction action = row.rowAction;
+
+        if (action == null) {
+            action = new RowAction(session, table, ACTION_DELETE, row, colMap);
+            row.rowAction = action;
+
+            return action;
+        }
+
+        return action.addDeleteAction(session, colMap);
+    }
+
+    public static boolean addRefAction(Session session, Row row,
+                                       int[] colMap) {
+
+        RowAction action = row.rowAction;
+
+        if (action == null) {
+            action = new RowAction(session, row.getTable(), ACTION_REF, row,
+                                   colMap);
+            row.rowAction = action;
+
+            return true;
+        }
+
+        return action.addRefAction(session, colMap);
+    }
+
+    public RowAction(Session session, TableBase table, byte type, Row row,
+                     int[] colMap) {
+
+        this.session         = session;
+        this.type            = type;
+        this.actionTimestamp = session.actionTimestamp;
+        this.table           = table;
+        this.store           = session.sessionData.getRowStore(table);
+        this.isMemory        = row.isMemory();
+        this.memoryRow       = row;
+        this.rowId           = row.getPos();
+        this.changeColumnMap = colMap;
+    }
+
+    private RowAction(RowAction other) {
+
+        this.session         = other.session;
+        this.type            = other.type;
+        this.actionTimestamp = other.actionTimestamp;
+        this.table           = other.table;
+        this.store           = other.store;
+        this.isMemory        = other.isMemory;
+        this.memoryRow       = other.memoryRow;
+        this.rowId           = other.rowId;
+        this.changeColumnMap = other.changeColumnMap;
+    }
+
+    synchronized public int getType() {
+        return type;
+    }
+
+    synchronized RowAction addDeleteAction(Session session, int[] colMap) {
+
+        if (type == ACTION_NONE) {
+            setAsAction(session, ACTION_DELETE);
+
+            changeColumnMap = colMap;
+        } else {
+            RowActionBase action = this;
+
+            while (true) {
+                if (action.type == ACTION_INSERT) {
+                    if (action.commitTimestamp == 0
+                            && session != action.session) {
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "RowAction");
+                    }
+                } else if (action.type == ACTION_DELETE) {
+                    if (session != action.session) {
+                        session.tempSet.add(action.session);
+
+                        return null;
+                    }
+                } else if (action.type == ACTION_REF) {
+                    if (session != action.session
+                            && action.commitTimestamp == 0) {
+                        if (colMap == null
+                                || ArrayUtil.haveCommonElement(
+                                    colMap, action.changeColumnMap)) {
+                            session.tempSet.add(action.session);
+
+                            return null;
+                        }
+                    }
+                }
+
+                if (action.next == null) {
+                    break;
+                }
+
+                action = action.next;
+            }
+
+            RowActionBase newAction = new RowActionBase(session,
+                ACTION_DELETE);
+
+            newAction.changeColumnMap = colMap;
+            action.next               = newAction;
+        }
+
+        return this;
+    }
+
+    synchronized boolean addRefAction(Session session, int[] colMap) {
+
+        if (type == ACTION_NONE) {
+            setAsAction(session, ACTION_REF);
+
+            changeColumnMap = colMap;
+
+            return true;
+        }
+
+        RowActionBase action = this;
+
+        do {
+            if (session == action.session) {
+                if (action.type == ACTION_REF
+                        && action.changeColumnMap == colMap
+                        && action.commitTimestamp == 0) {
+                    return false;
+                }
+
+                if (action.type == ACTION_INSERT) {
+                    if (action.commitTimestamp == 0) {
+                        return false;
+                    }
+                }
+            } else {
+                if (action.type == ACTION_DELETE
+                        && action.commitTimestamp == 0) {
+                    if (action.changeColumnMap == null
+                            || ArrayUtil.haveCommonElement(
+                                colMap, action.changeColumnMap)) {
+                        session.tempSet.add(action.session);
+
+                        return false;
+                    }
+                }
+            }
+
+            if (action.next == null) {
+                break;
+            }
+
+            action = action.next;
+        } while (true);
+
+        RowActionBase newAction = new RowActionBase(session, ACTION_REF);
+
+        newAction.changeColumnMap = colMap;
+        action.next               = newAction;
+
+        return true;
+    }
+
+    public boolean checkDeleteActions() {
+        return false;
+    }
+
+    public synchronized RowAction duplicate(Row newRow) {
+
+        RowAction action = new RowAction(session, table, type, newRow,
+                                         changeColumnMap);
+
+        return action;
+    }
+
+    synchronized void setAsAction(Session session, byte type) {
+
+        this.session    = session;
+        this.type       = type;
+        actionTimestamp = session.actionTimestamp;
+        changeColumnMap = null;
+    }
+
+    synchronized void setAsAction(RowActionBase action) {
+        super.setAsAction(action);
+    }
+
+    public void setAsNoOp() {
+
+//        memoryRow       = null;
+        session         = null;
+        actionTimestamp = 0;
+        commitTimestamp = 0;
+        rolledback      = false;
+        deleteComplete  = false;
+        changeColumnMap = null;
+        prepared        = false;
+        type            = ACTION_NONE;
+        next            = null;
+    }
+
+    private void setAsDeleteFinal(long timestamp) {
+
+        actionTimestamp = 0;
+        commitTimestamp = timestamp;
+        rolledback      = false;
+        deleteComplete  = false;
+        prepared        = false;
+        changeColumnMap = null;
+        type            = ACTION_DELETE_FINAL;
+        next            = null;
+    }
+
+    /** for two-phased pre-commit */
+    synchronized void prepareCommit(Session session) {
+
+        RowActionBase action = this;
+
+        do {
+            if (action.session == session && action.commitTimestamp == 0) {
+                action.prepared = true;
+            }
+
+            action = action.next;
+        } while (action != null);
+    }
+
+    synchronized int commit(Session session) {
+
+        RowActionBase action     = this;
+        int           actiontype = ACTION_NONE;
+
+        do {
+            if (action.session == session && action.commitTimestamp == 0) {
+                action.commitTimestamp = session.actionTimestamp;
+                action.prepared        = false;
+
+                if (action.type == ACTION_INSERT) {
+                    actiontype = action.type;
+                } else if (action.type == ACTION_DELETE) {
+                    if (actiontype == ACTION_INSERT) {
+
+                        // ACTION_INSERT + ACTION_DELETE
+                        actiontype = ACTION_INSERT_DELETE;
+                    } else {
+                        actiontype = action.type;
+                    }
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        return actiontype;
+    }
+
+    public boolean isDeleted() {
+
+        RowActionBase action = this;
+
+        do {
+            if (action.commitTimestamp != 0) {
+                if (action.type == ACTION_DELETE
+                        || action.type == ACTION_DELETE_FINAL) {
+                    return true;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        return false;
+    }
+
+    /**
+     * returns type of commit performed on timestamp. ACTION_NONE if none.
+     * assumes rolled-back actions have already been merged
+     */
+    synchronized int getCommitTypeOn(long timestamp) {
+
+        RowActionBase action     = this;
+        int           actionType = ACTION_NONE;
+
+        do {
+            if (action.commitTimestamp == timestamp) {
+                if (action.type == ACTION_INSERT) {
+                    actionType = action.type;
+                } else if (action.type == ACTION_DELETE) {
+                    if (actionType == ACTION_INSERT) {
+
+                        // ACTION_INSERT + ACTION_DELETE
+                        actionType = ACTION_INSERT_DELETE;
+                    } else {
+                        actionType = action.type;
+                    }
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        return actionType;
+    }
+
+    /**
+     * returns false if another committed session has altered the same row
+     */
+    synchronized boolean canCommit(Session session, OrderedHashSet set) {
+
+        RowActionBase action;
+        long          timestamp       = session.transactionTimestamp;
+        long          commitTimestamp = 0;
+        final boolean readCommitted = session.isolationLevel
+                                      == SessionInterface.TX_READ_COMMITTED;
+        boolean hasDelete = false;
+
+        action = this;
+
+        if (readCommitted) {
+            do {
+                if (action.session == session
+                        && action.type == ACTION_DELETE) {
+
+                    // for READ_COMMITTED, use action timestamp for later conflicts
+                    if (action.commitTimestamp == 0) {
+                        timestamp = action.actionTimestamp;
+                    }
+                }
+
+                action = action.next;
+            } while (action != null);
+
+            action = this;
+        }
+
+        do {
+            if (action.session == session) {
+                if (action.type == ACTION_DELETE) {
+                    hasDelete = true;
+                }
+            } else {
+                if (action.rolledback || action.type != ACTION_DELETE) {
+                    action = action.next;
+
+                    continue;
+                }
+
+                if (action.prepared) {
+                    return false;
+                }
+
+                if (action.commitTimestamp == 0) {
+                    set.add(action.session);
+                } else if (action.commitTimestamp > commitTimestamp) {
+                    commitTimestamp = action.commitTimestamp;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        if (!hasDelete) {
+            return true;
+        }
+
+        return commitTimestamp < timestamp;
+    }
+
+    synchronized void complete(Session session) {
+
+        RowActionBase action;
+
+        action = this;
+
+        do {
+            if (action.session == session) {
+                if (action.actionTimestamp == 0) {
+                    action.actionTimestamp = session.actionTimestamp;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+    }
+
+    /**
+     * returns false if cannot complete
+     * when READ COMMITTED, false result always means repeat action and adds
+     * to set parameter the sessions to wait on (may be no wait)
+     */
+    synchronized boolean complete(Session session, OrderedHashSet set) {
+
+        RowActionBase action;
+        boolean readCommitted = session.isolationLevel
+                                == SessionInterface.TX_READ_COMMITTED;
+        boolean result = true;
+
+        action = this;
+
+        do {
+            if (action.rolledback || action.type == ACTION_NONE) {
+                action = action.next;
+
+                continue;
+            }
+
+            if (action.session == session) {
+
+                //
+            } else {
+                if (action.prepared) {
+                    set.add(action.session);
+
+                    return false;
+                }
+
+                if (readCommitted) {
+                    if (action.commitTimestamp > session.actionTimestamp) {
+
+                        // 2.0 -- investigate
+                        // can redo - if deletes
+                        // can redo - if dup, but will likely fail at retry
+                        // can redo - if ref, but will likely fail at retry
+                        set.add(session);
+
+                        result = false;
+                    } else if (action.commitTimestamp == 0) {
+                        set.add(action.session);
+
+                        result = false;
+                    }
+                } else if (action.commitTimestamp
+                           > session.transactionTimestamp) {
+                    return false;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        return result;
+    }
+
+    synchronized int getActionType(long timestamp) {
+
+        int           actionType = ACTION_NONE;
+        RowActionBase action     = this;
+
+        do {
+            if (action.actionTimestamp == timestamp) {
+                if (action.type == ACTION_DELETE) {
+                    if (actionType == ACTION_INSERT) {
+                        actionType = ACTION_INSERT_DELETE;
+                    } else {
+                        actionType = action.type;
+                    }
+                } else if (action.type == ACTION_INSERT) {
+                    actionType = action.type;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        return actionType;
+    }
+
+    public synchronized int getPos() {
+        return rowId;
+    }
+
+    synchronized void setPos(int pos) {
+        rowId = pos;
+    }
+
+    private int getRollbackType(Session session) {
+
+        int           actionType = ACTION_NONE;
+        RowActionBase action     = this;
+
+        do {
+            if (action.session == session && action.rolledback) {
+                if (action.type == ACTION_DELETE) {
+                    if (actionType == ACTION_INSERT) {
+                        actionType = ACTION_INSERT_DELETE;
+                    } else {
+                        actionType = action.type;
+                    }
+                } else if (action.type == ACTION_INSERT) {
+                    actionType = action.type;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        return actionType;
+    }
+
+    /**
+     * Rollback actions for a session including and after the given timestamp
+     */
+    synchronized void rollback(Session session, long timestamp) {
+
+        RowActionBase action = this;
+
+        do {
+            if (action.session == session && action.commitTimestamp == 0) {
+                if (action.actionTimestamp >= timestamp) {
+                    action.commitTimestamp = session.actionTimestamp;
+                    action.rolledback      = true;
+                    action.prepared        = false;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+    }
+
+    /**
+     * merge rolled back actions
+     */
+    synchronized int mergeRollback(Session session, long timestamp, Row row) {
+
+        RowActionBase action         = this;
+        RowActionBase head           = null;
+        RowActionBase tail           = null;
+        int           rollbackAction = getRollbackType(session);
+
+        do {
+            if (action.session == session && action.rolledback) {
+                if (tail != null) {
+                    tail.next = null;
+                }
+            } else {
+                if (head == null) {
+                    head = tail = action;
+                } else {
+                    tail.next = action;
+                    tail      = action;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        if (head == null) {
+            switch (rollbackAction) {
+
+                case ACTION_INSERT :
+                case ACTION_INSERT_DELETE :
+                    setAsDeleteFinal(timestamp);
+                    break;
+
+                case ACTION_DELETE :
+                case ACTION_NONE :
+                default :
+                    setAsNoOp();
+                    break;
+            }
+        } else {
+            if (head != this) {
+                setAsAction(head);
+            }
+        }
+
+        return rollbackAction;
+    }
+
+    /**
+     * merge session actions committed on given timestamp.
+     *
+     * may be called more than once on same action
+     *
+     */
+    synchronized void mergeToTimestamp(long timestamp) {
+
+        RowActionBase action     = this;
+        RowActionBase head       = null;
+        RowActionBase tail       = null;
+        int           commitType = getCommitTypeOn(timestamp);
+
+        if (type == ACTION_DELETE_FINAL || type == ACTION_NONE) {
+            return;
+        }
+
+        if (commitType == ACTION_DELETE
+                || commitType == ACTION_INSERT_DELETE) {
+            setAsDeleteFinal(timestamp);
+
+            return;
+        }
+
+        do {
+            boolean expired = false;;
+
+            if (action.commitTimestamp != 0) {
+                if (action.commitTimestamp <= timestamp) {
+                    expired = true;
+                } else if (action.type == ACTION_REF) {
+                    expired = true;
+                }
+            }
+
+            if (expired) {
+                if (tail != null) {
+                    tail.next = null;
+                }
+            } else {
+                if (head == null) {
+                    head = tail = action;
+                } else {
+                    tail.next = action;
+                    tail      = action;
+                }
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        if (head == null) {
+            switch (commitType) {
+
+                case ACTION_DELETE :
+                case ACTION_INSERT_DELETE :
+                    setAsDeleteFinal(timestamp);
+                    break;
+
+                case ACTION_NONE :
+                case ACTION_INSERT :
+                default :
+                    setAsNoOp();
+                    break;
+            }
+        } else if (head != this) {
+            setAsAction(head);
+        }
+
+        mergeExpiredRefActions();
+    }
+
+    synchronized boolean canRead(Session session, int mode) {
+
+        long threshold;
+        int  actionType = ACTION_NONE;
+
+        if (type == ACTION_DELETE_FINAL) {
+            return false;
+        }
+
+        if (type == ACTION_NONE) {
+            return true;
+        }
+
+        RowActionBase action = this;
+
+        if (session == null) {
+            threshold = Long.MAX_VALUE;
+        } else {
+            switch (session.isolationLevel) {
+
+                case SessionInterface.TX_READ_UNCOMMITTED :
+                    threshold = Long.MAX_VALUE;
+                    break;
+
+                case SessionInterface.TX_READ_COMMITTED :
+                    threshold = session.actionTimestamp;
+                    break;
+
+                case SessionInterface.TX_REPEATABLE_READ :
+                case SessionInterface.TX_SERIALIZABLE :
+                default :
+                    threshold = session.transactionTimestamp;
+                    break;
+            }
+        }
+
+        do {
+            if (action.type == ACTION_REF) {
+                action = action.next;
+
+                continue;
+            }
+
+            if (action.rolledback) {
+                if (action.type == ACTION_INSERT) {
+                    actionType = ACTION_DELETE;
+                }
+
+                action = action.next;
+
+                continue;
+            }
+
+            if (session == action.session) {
+                if (action.type == ACTION_DELETE) {
+                    actionType = action.type;
+                } else if (action.type == ACTION_INSERT) {
+                    actionType = action.type;
+                }
+
+                action = action.next;
+
+                continue;
+            } else if (action.commitTimestamp == 0) {
+                if (action.type == ACTION_NONE) {
+                    throw Error.runtimeError(ErrorCode.U_S0500, "RowAction");
+                } else if (action.type == ACTION_INSERT) {
+                    if (mode == TransactionManager.ACTION_READ) {
+                        actionType = action.ACTION_DELETE;
+                    } else if (mode == TransactionManager.ACTION_DUP) {
+                        if (action.changeColumnMap == null) {
+                            actionType = ACTION_INSERT;
+                        } else {
+                            actionType = ACTION_DELETE;
+                        }
+                    } else if (mode == TransactionManager.ACTION_REF) {
+                        actionType = ACTION_DELETE;
+                    }
+
+                    break;
+                } else if (action.type == ACTION_DELETE) {
+                    if (mode == TransactionManager.ACTION_DUP) {
+
+                        //
+                    } else if (mode == TransactionManager.ACTION_REF) {
+                        actionType = ACTION_DELETE;
+                    }
+                }
+
+                action = action.next;
+
+                continue;
+            } else if (action.commitTimestamp < threshold) {
+                if (action.type == ACTION_DELETE) {
+                    if (actionType == ACTION_INSERT) {
+                        actionType = action.type;
+                    } else {
+                        actionType = action.type;
+                    }
+                } else if (action.type == ACTION_INSERT) {
+                    actionType = action.type;
+                }
+            } else {
+                if (action.type == ACTION_INSERT) {
+                    actionType = ACTION_DELETE;
+                }
+            }
+
+            action = action.next;
+
+            continue;
+        } while (action != null);
+
+        if (actionType == ACTION_NONE || actionType == ACTION_INSERT) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean hasCurrentRefAction() {
+
+        RowActionBase action = this;
+
+        do {
+            if (action.type == ACTION_REF && action.commitTimestamp == 0) {
+                return true;
+            }
+
+            action = action.next;
+        } while (action != null);
+
+        return false;
+    }
+
+    /** eliminate all expired updatedAction in chain */
+    private RowAction mergeExpiredRefActions() {
+
+        if (updatedAction != null) {
+            updatedAction = updatedAction.mergeExpiredRefActions();
+        }
+
+        if (hasCurrentRefAction()) {
+            return this;
+        }
+
+        return updatedAction;
+    }
+
+    synchronized String dump() {
+
+        StringBuilder sb     = new StringBuilder();
+        RowActionBase action = this;
+
+        do {
+            if (action == this && memoryRow != null) {
+                sb.append("" + memoryRow.getId());
+            }
+
+            sb.append(" " + action.session.getId() + ' ' + action.type + ' '
+                      + action.actionTimestamp + ' ' + action.commitTimestamp);
+
+            if (action.commitTimestamp != 0) {
+                if (action.rolledback) {
+                    sb.append("r");
+                } else {
+                    sb.append("c");
+                }
+            }
+
+            sb.append(" - ");
+
+            action = action.next;
+        } while (action != null);
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/RowActionBase.java b/src/org/hsqldb/RowActionBase.java
new file mode 100644
index 0000000..9c253a5
--- /dev/null
+++ b/src/org/hsqldb/RowActionBase.java
@@ -0,0 +1,95 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+/**
+ * Represents a single insert / delete / rollback / commit action on a row.
+ *
+ * type = type of action
+ * actionTimestamp = timestamp of end of SQL action; 0 if action not complete
+ * commitTimestamp = timestamp of commit or rollback; 0 if not committed/rolledback
+ * rolledBack = flag for rolled back actions
+ * next = next action in linked list;
+ *
+ * timestamps are not in any order
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge dot net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+class RowActionBase {
+
+    public static final byte ACTION_NONE          = 0;
+    public static final byte ACTION_INSERT        = 1;
+    public static final byte ACTION_DELETE        = 2;
+    public static final byte ACTION_DELETE_FINAL  = 3;
+    public static final byte ACTION_INSERT_DELETE = 4;
+    public static final byte ACTION_REF           = 5;
+    public static final byte ACTION_CHECK         = 6;
+    public static final byte ACTION_DEBUG         = 7;
+
+    //
+    RowActionBase            next;
+    Session                  session;
+    long                     actionTimestamp;
+    long                     commitTimestamp;
+    byte                     type;
+    boolean                  deleteComplete;
+    boolean                  rolledback;
+    boolean                  prepared;
+    int[]                    changeColumnMap;
+
+    RowActionBase() {}
+
+    /**
+     * constructor, used for delete actions only
+     */
+    RowActionBase(Session session, byte type) {
+
+        this.session    = session;
+        this.type       = type;
+        actionTimestamp = session.actionTimestamp;
+    }
+
+    void setAsAction(RowActionBase action) {
+
+        next            = action.next;
+        session         = action.session;
+        actionTimestamp = action.actionTimestamp;
+        commitTimestamp = action.commitTimestamp;
+        type            = action.type;
+        deleteComplete  = action.deleteComplete;
+        rolledback      = action.rolledback;
+        prepared        = action.prepared;
+        changeColumnMap = action.changeColumnMap;
+    }
+}
diff --git a/src/org/hsqldb/Scanner.java b/src/org/hsqldb/Scanner.java
new file mode 100644
index 0000000..20c1a48
--- /dev/null
+++ b/src/org/hsqldb/Scanner.java
@@ -0,0 +1,2522 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.math.BigDecimal;
+import java.util.Locale;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.CharArrayWriter;
+import org.hsqldb.lib.HsqlByteArrayOutputStream;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.store.BitMap;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BinaryType;
+import org.hsqldb.types.BitType;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.DTIType;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Scans for SQL tokens.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class Scanner {
+
+    /*
+    <delimiter token> ::=
+    <character string literal>
+    | <date string>
+    | <time string>
+    | <timestamp string>
+    | <interval string>
+    | <delimited identifier>
+    | <SQL special character>
+    | <not equals operator>
+    | <greater than or equals operator>
+    | <less than or equals operator>
+    | <concatenation operator>
+    | <right arrow>
+    | <left bracket trigraph>
+    | <right bracket trigraph>
+    | <double colon>
+    | <double period>
+
+    */
+    //J-
+    final static char[] specials = new char[] {
+        '"',
+        '%',
+        '&',
+        '\'',
+        '(',
+        ')',
+        '*',
+        '+',
+        ',',
+        '-',
+        '.',
+        '/',
+        '\\',
+        ':',
+        ';',
+        '<',
+        '=',
+        '>',
+        '?',
+        '[',
+        ']',
+        '^',
+        '_',
+        '|',
+        '{',
+        '}'
+    };
+    final static String[] multi = new String[] {
+        "??(",
+        "??)",
+        "<>",
+        ">=",
+        "<=",
+        "||",
+        "->",
+        "::",
+        "..",
+        "--",
+        "/*",
+        "*/",
+    };
+
+    final static char[] whitespace = {
+        // SQL extras
+        0x9,
+        0xA,
+        0xB,
+        0xC,
+        0xD,
+        0x20,
+        0x85,
+        // U Zs
+        0x0020,
+        0x00A0,
+        0x1680,
+        0x180E,
+        0x2000,
+        0x2001,
+        0x2002,
+        0x2003,
+        0x2004,
+        0x2005,
+        0x2006,
+        0x2007,
+        0x2008,
+        0x2009,
+        0x200A,
+        0x202F,
+        0x205F,
+        0x3000,
+        // U Zl
+        0x2028,
+        // U Zp
+        0x2029,
+    };
+
+//J+
+    final static OrderedIntHashSet whiteSpaceSet = new OrderedIntHashSet(32);
+
+    static {
+        for (int i = 0; i < whitespace.length; i++) {
+            whiteSpaceSet.add(whitespace[i]);
+        }
+    }
+
+    // single token types
+    String  sqlString;
+    int     currentPosition;
+    int     tokenPosition;
+    int     limit;
+    Token   token = new Token();
+    boolean nullAndBooleanAsValue;
+
+    //
+    private boolean hasNonSpaceSeparator;
+    private int     eolPosition;
+    private int     lineNumber;
+    private int     eolCode;
+
+    //
+    private static final int maxPooledStringLength =
+        ValuePool.getMaxStringLength();
+
+    //
+    char[]          charBuffer = new char[256];
+    CharArrayWriter charWriter = new CharArrayWriter(charBuffer);
+
+    //
+    byte[] byteBuffer = new byte[256];
+    HsqlByteArrayOutputStream byteOutputStream =
+        new HsqlByteArrayOutputStream(byteBuffer);
+
+    public Scanner() {}
+
+    Scanner(String sql) {
+        reset(sql);
+    }
+
+    public void reset(String sql) {
+
+        sqlString            = sql;
+        currentPosition      = 0;
+        tokenPosition        = 0;
+        limit                = sqlString.length();
+        hasNonSpaceSeparator = false;
+        eolPosition          = -1;
+        lineNumber           = 1;
+
+        token.reset();
+
+        token.tokenType = Tokens.X_STARTPARSE;
+    }
+
+    void resetState() {
+
+        tokenPosition = currentPosition;
+
+        token.reset();
+    }
+
+    public void setNullAndBooleanAsValue() {
+        nullAndBooleanAsValue = true;
+    }
+
+    public void scanNext() {
+
+        if (currentPosition == limit) {
+            resetState();
+
+            token.tokenType = Tokens.X_ENDPARSE;
+
+            return;
+        }
+
+        if (scanSeparator()) {
+
+//            token.isDelimiter = true;
+        }
+
+        if (currentPosition == limit) {
+            resetState();
+
+            token.tokenType = Tokens.X_ENDPARSE;
+
+            return;
+        }
+
+        boolean needsDelimiter = !token.isDelimiter;
+
+        scanToken();
+
+        if (needsDelimiter && !token.isDelimiter) {
+
+//            token.tokenType = Token.X_UNKNOWN_TOKEN;
+        }
+
+        if (token.isMalformed) {
+            token.fullString = getPart(tokenPosition, currentPosition);
+        }
+    }
+
+    public void scanEnd() {
+
+        if (currentPosition == limit) {
+            resetState();
+
+            token.tokenType = Tokens.X_ENDPARSE;
+        }
+    }
+
+    public Token getToken() {
+        return token;
+    }
+
+    public String getString() {
+        return token.tokenString;
+    }
+
+    public int getTokenType() {
+        return token.tokenType;
+    }
+
+    public Object getValue() {
+        return token.tokenValue;
+    }
+
+    public Type getDataType() {
+        return token.dataType;
+    }
+
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    int getTokenPosition() {
+        return tokenPosition;
+    }
+
+    int getPosition() {
+        return tokenPosition;
+    }
+
+    void position(int position) {
+        currentPosition = tokenPosition = position;
+    }
+
+    String getPart(int start, int end) {
+        return sqlString.substring(start, end);
+    }
+
+    private int charAt(int i) {
+
+        if (i >= limit) {
+            return -1;
+        }
+
+        return sqlString.charAt(i);
+    }
+
+    void scanBinaryString() {
+
+        byteOutputStream.reset(byteBuffer);
+
+        while (true) {
+            scanBinaryStringPart();
+
+            if (token.isMalformed) {
+                return;
+            }
+
+            if (scanSeparator() && charAt(currentPosition) == '\'') {
+                continue;
+            }
+
+            break;
+        }
+
+        token.tokenValue = new BinaryData(byteOutputStream.toByteArray(),
+                                          false);
+
+        byteOutputStream.reset(byteBuffer);
+    }
+
+    /**
+     * returns hex value of a hex character, or 16 if not a hex character
+     */
+    static int getHexValue(int c) {
+
+        if (c >= '0' && c <= '9') {
+            c -= '0';
+        } else if (c > 'z') {
+            c = 16;
+        } else if (c >= 'a') {
+            c -= ('a' - 10);
+        } else if (c > 'Z') {
+            c = 16;
+        } else if (c >= 'A') {
+            c -= ('A' - 10);
+        } else {
+            c = -1;
+        }
+
+        return c;
+    }
+
+    public void scanBinaryStringWithQuote() {
+
+        resetState();
+        scanSeparator();
+
+        if (charAt(currentPosition) != '\'') {
+            token.tokenType   = Tokens.X_MALFORMED_BINARY_STRING;
+            token.isMalformed = true;
+
+            return;
+        }
+
+        scanBinaryString();
+    }
+
+    void scanBinaryStringPart() {
+
+        boolean complete = false;
+        boolean hi       = true;
+        byte    b        = 0;
+
+        currentPosition++;
+
+        for (; currentPosition < limit; currentPosition++) {
+            int c = sqlString.charAt(currentPosition);
+
+            if (c == ' ') {
+                continue;
+            }
+
+            if (c == '\'') {
+                complete = true;
+
+                currentPosition++;
+
+                break;
+            }
+
+            c = getHexValue(c);
+
+            if (c == -1) {
+
+                // bad character
+                token.tokenType   = Tokens.X_MALFORMED_BINARY_STRING;
+                token.isMalformed = true;
+
+                return;
+            }
+
+            if (hi) {
+                b  = (byte) (c << 4);
+                hi = false;
+            } else {
+                b += (byte) c;
+
+                byteOutputStream.writeByte(b);
+
+                hi = true;
+            }
+        }
+
+        if (!hi) {
+
+            // odd nibbles
+            token.tokenType   = Tokens.X_MALFORMED_BINARY_STRING;
+            token.isMalformed = true;
+
+            return;
+        }
+
+        if (!complete) {
+
+            // no end quote
+            token.tokenType   = Tokens.X_MALFORMED_BINARY_STRING;
+            token.isMalformed = true;
+
+            return;
+        }
+    }
+
+    void scanBitString() {
+
+        BitMap map = new BitMap(32);
+
+        while (true) {
+            scanBitStringPart(map);
+
+            if (token.isMalformed) {
+                return;
+            }
+
+            if (scanSeparator() && charAt(currentPosition) == '\'') {
+                continue;
+            }
+
+            break;
+        }
+
+        token.tokenValue = BinaryData.getBitData(map.getBytes(), map.size());
+    }
+
+    public void scanBitStringWithQuote() {
+
+        resetState();
+        scanSeparator();
+
+        if (charAt(currentPosition) != '\'') {
+            token.tokenType   = Tokens.X_MALFORMED_BIT_STRING;
+            token.isMalformed = true;
+
+            return;
+        }
+
+        scanBitString();
+    }
+
+    void scanBitStringPart(BitMap map) {
+
+        boolean complete = false;
+        int     bitIndex = map.size();
+
+        currentPosition++;
+
+        for (; currentPosition < limit; currentPosition++) {
+            char c = sqlString.charAt(currentPosition);
+
+            if (c == ' ') {
+                continue;
+            }
+
+            if (c == '\'') {
+                complete = true;
+
+                currentPosition++;
+
+                break;
+            }
+
+            if (c == '0') {
+                bitIndex++;
+            } else if (c == '1') {
+                map.set(bitIndex);
+
+                bitIndex++;
+            } else {
+                token.tokenType   = Tokens.X_MALFORMED_BIT_STRING;
+                token.isMalformed = true;
+
+                return;
+            }
+        }
+
+        if (!complete) {
+            token.tokenType   = Tokens.X_MALFORMED_BIT_STRING;
+            token.isMalformed = true;
+
+            return;
+        }
+
+        map.setSize(bitIndex);
+    }
+
+    void convertUnicodeString(int escape) {
+
+        charWriter.reset(charBuffer);
+
+        int position = 0;
+
+        for (;;) {
+            int nextIndex = token.tokenString.indexOf(escape, position);
+
+            if (nextIndex < 0) {
+                nextIndex = token.tokenString.length();
+            }
+
+            charWriter.write(token.tokenString, position,
+                             nextIndex - position);
+
+            if (nextIndex == token.tokenString.length()) {
+                break;
+            }
+
+            nextIndex++;
+
+            if (nextIndex == token.tokenString.length()) {
+                token.tokenType   = Tokens.X_MALFORMED_UNICODE_STRING;
+                token.isMalformed = true;
+
+                return;
+            }
+
+            if (token.tokenString.charAt(nextIndex) == escape) {
+                charWriter.write(escape);
+
+                nextIndex++;
+
+                position = nextIndex;
+
+                continue;
+            }
+
+            if (nextIndex > token.tokenString.length() - 4) {
+                token.tokenType   = Tokens.X_MALFORMED_UNICODE_STRING;
+                token.isMalformed = true;
+
+                return;
+            }
+
+            int hexCount = 4;
+            int hexIndex = 0;
+            int hexValue = 0;
+
+            if (token.tokenString.charAt(nextIndex) == '+') {
+                nextIndex++;
+
+                if (nextIndex > token.tokenString.length() - 6) {
+                    token.tokenType   = Tokens.X_MALFORMED_UNICODE_STRING;
+                    token.isMalformed = true;
+
+                    return;
+                }
+
+                hexIndex = 2;
+                hexCount = 8;
+            }
+
+            for (; hexIndex < hexCount; hexIndex++) {
+                int character = token.tokenString.charAt(position++);
+
+                character = getHexValue(character);
+
+                if (character == -1) {
+                    token.tokenType   = Tokens.X_MALFORMED_UNICODE_STRING;
+                    token.isMalformed = true;
+
+                    return;
+                }
+
+                hexValue |= character << ((hexCount - hexIndex - 1) * 4);
+            }
+
+            if (hexCount == 8) {
+                charWriter.write(hexValue >>> 16);
+            }
+
+            charWriter.write(hexValue & (hexValue & 0xffff));
+
+            token.tokenValue = charWriter.toString();
+        }
+    }
+
+    /**
+     * Only for identifiers that are part of known token sequences
+     */
+    public boolean scanSpecialIdentifier(String identifier) {
+
+        int length = identifier.length();
+
+        if (limit - currentPosition < length) {
+            return false;
+        }
+
+        for (int i = 0; i < length; i++) {
+            int character = identifier.charAt(i);
+
+            if (character == sqlString.charAt(currentPosition + i)) {
+                continue;
+            }
+
+            if (character
+                    == Character.toUpperCase(sqlString.charAt(currentPosition
+                        + i))) {
+                continue;
+            }
+
+            return false;
+        }
+
+        currentPosition += length;
+
+        return true;
+    }
+
+    private int scanEscapeDefinition() {
+
+        int c = charAt(currentPosition);
+
+        if (c == '\'') {
+            currentPosition++;
+
+            if (!scanWhitespace()) {
+                c = charAt(currentPosition);
+
+                if (getHexValue(c) == -1) {
+                    if (c != '+' && c != '\'' && c != '\"') {
+                        int escape = c;
+
+                        currentPosition++;
+
+                        c = charAt(currentPosition);
+
+                        if (c == '\'') {
+                            currentPosition++;
+
+                            return escape;
+                        }
+                    }
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    private void scanUnicodeString() {
+
+        int escape = '\\';
+
+        scanCharacterString();
+        scanSeparator();
+
+        int c = charAt(currentPosition);
+
+        if (c == 'u' || c == 'U') {
+            if (scanSpecialIdentifier(Tokens.T_UESCAPE)) {
+                scanSeparator();
+
+                escape = scanEscapeDefinition();
+
+                if (escape == -1) {
+                    token.tokenType   = Tokens.X_MALFORMED_UNICODE_ESCAPE;
+                    token.isMalformed = true;
+
+                    return;
+                }
+            }
+        }
+
+        convertUnicodeString(escape);
+    }
+
+    private boolean scanUnicodeIdentifier() {
+
+        int escape = '\\';
+
+        scanStringPart('"');
+
+        if (token.isMalformed) {
+            return false;
+        }
+
+        token.tokenString = charWriter.toString();
+
+        int c = charAt(currentPosition);
+
+        if (c == 'u' || c == 'U') {
+            if (scanSpecialIdentifier(Tokens.T_UESCAPE)) {
+                scanSeparator();
+
+                escape = scanEscapeDefinition();
+
+                if (escape == -1) {
+                    token.tokenType   = Tokens.X_MALFORMED_UNICODE_ESCAPE;
+                    token.isMalformed = true;
+
+                    return false;
+                }
+            }
+        }
+
+        convertUnicodeString(escape);
+
+        return !token.isMalformed;
+    }
+
+    boolean shiftPrefixes() {
+
+        if (token.namePrePrePrefix != null) {
+            return false;
+        }
+
+        token.namePrePrePrefix        = token.namePrePrefix;
+        token.isDelimitedPrePrePrefix = token.isDelimitedPrePrefix;
+        token.namePrePrefix           = token.namePrefix;
+        token.isDelimitedPrePrefix    = token.isDelimitedPrefix;
+        token.namePrefix              = token.tokenString;
+        token.isDelimitedPrefix = (token.tokenType
+                                   == Tokens.X_DELIMITED_IDENTIFIER);
+
+        return true;
+    }
+
+    private void scanIdentifierChain() {
+
+        int c = charAt(currentPosition);
+
+        switch (c) {
+
+            case '"' :
+                charWriter.reset(charBuffer);
+                scanStringPart('"');
+
+                if (token.isMalformed) {
+                    return;
+                }
+
+                token.tokenType   = Tokens.X_DELIMITED_IDENTIFIER;
+                token.tokenString = charWriter.toString();
+                token.isDelimiter = true;
+                break;
+
+            case 'u' :
+            case 'U' :
+                if (charAt(currentPosition + 1) == '&') {
+                    if (charAt(currentPosition + 1) == '"') {
+                        currentPosition += 3;
+
+                        boolean result = scanUnicodeIdentifier();
+
+                        if (!result) {
+                            return;
+                        }
+
+                        token.tokenType   = Tokens.X_DELIMITED_IDENTIFIER;
+                        token.isDelimiter = false;
+
+                        break;
+                    }
+                }
+
+            // fall through
+            default :
+                boolean result = scanUndelimitedIdentifier();
+
+                if (!result) {
+                    return;
+                }
+
+                token.tokenType   = Tokens.X_IDENTIFIER;
+                token.isDelimiter = false;
+        }
+
+        c = charAt(currentPosition);
+
+        if (c == '.') {
+            currentPosition++;
+
+            c = charAt(currentPosition);
+
+            if (c == '*') {
+                currentPosition++;
+
+                shiftPrefixes();
+
+                token.tokenString = Tokens.T_ASTERISK;
+                token.tokenType   = Tokens.ASTERISK;
+            } else {
+                shiftPrefixes();
+                scanIdentifierChain();
+            }
+        }
+    }
+
+    public boolean scanUndelimitedIdentifier() {
+
+        if (currentPosition == limit) {
+            return false;
+        }
+
+        char start = sqlString.charAt(currentPosition);
+
+        if (!Character.isLetter(start)) {
+            token.tokenString = Character.toString(start);
+            token.tokenType   = Tokens.X_UNKNOWN_TOKEN;
+            token.isMalformed = true;
+
+            return false;
+        }
+
+        int i = currentPosition + 1;
+
+        for (; i < limit; i++) {
+            char c = sqlString.charAt(i);
+
+            if (c == '_' || Character.isLetterOrDigit(c)) {
+                continue;
+            }
+
+            break;
+        }
+
+        token.tokenString = sqlString.substring(currentPosition,
+                i).toUpperCase(Locale.ENGLISH);
+        currentPosition = i;
+
+        if (nullAndBooleanAsValue) {
+            int tokenLength = currentPosition - tokenPosition;
+
+            if (tokenLength == 4 || tokenLength == 5) {
+                switch (start) {
+
+                    case 'T' :
+                    case 't' :
+                        if (Tokens.T_TRUE.equals(token.tokenString)) {
+                            token.tokenString = Tokens.T_TRUE;
+                            token.tokenType   = Tokens.X_VALUE;
+                            token.tokenValue  = Boolean.TRUE;
+                            token.dataType    = Type.SQL_BOOLEAN;
+
+                            return false;
+                        }
+                        break;
+
+                    case 'F' :
+                    case 'f' :
+                        if (Tokens.T_FALSE.equals(token.tokenString)) {
+                            token.tokenString = Tokens.T_FALSE;
+                            token.tokenType   = Tokens.X_VALUE;
+                            token.tokenValue  = Boolean.FALSE;
+                            token.dataType    = Type.SQL_BOOLEAN;
+
+                            return false;
+                        }
+                        break;
+
+                    case 'N' :
+                    case 'n' :
+                        if (Tokens.T_NULL.equals(token.tokenString)) {
+                            token.tokenString = Tokens.T_NULL;
+                            token.tokenType   = Tokens.X_VALUE;
+                            token.tokenValue  = null;
+
+                            return false;
+                        }
+                        break;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    void scanNumber() {
+
+        int     c;
+        boolean hasDigit      = false;
+        boolean hasPoint      = false;
+        int     exponentIndex = -1;
+
+        token.tokenType = Tokens.X_VALUE;
+        token.dataType  = Type.SQL_INTEGER;
+
+        int tokenStart = currentPosition;
+
+        for (; currentPosition < limit; currentPosition++) {
+            boolean end = false;
+
+            c = charAt(currentPosition);
+
+            switch (c) {
+
+                case '0' :
+                case '1' :
+                case '2' :
+                case '3' :
+                case '4' :
+                case '5' :
+                case '6' :
+                case '7' :
+                case '8' :
+                case '9' :
+                    hasDigit = true;
+                    break;
+
+                case '.' :
+                    token.dataType = Type.SQL_NUMERIC;
+
+                    if (hasPoint || exponentIndex != -1) {
+                        token.tokenString = sqlString.substring(tokenStart,
+                                currentPosition + 1);
+                        token.tokenType   = Tokens.X_MALFORMED_NUMERIC;
+                        token.isMalformed = true;
+
+                        return;
+                    }
+
+                    hasPoint = true;
+                    break;
+
+                case 'E' :
+                case 'e' :
+                    token.dataType = Type.SQL_DOUBLE;
+
+                    if (exponentIndex != -1 || !hasDigit) {
+                        token.tokenString = sqlString.substring(tokenStart,
+                                currentPosition + 1);
+                        token.tokenType   = Tokens.X_MALFORMED_NUMERIC;
+                        token.isMalformed = true;
+
+                        return;
+                    }
+
+                    hasPoint      = true;
+                    exponentIndex = currentPosition;
+                    break;
+
+                case '-' :
+                case '+' :
+                    if (exponentIndex != currentPosition - 1) {
+                        end = true;
+                    }
+                    break;
+
+                case 'K' :
+                case 'k' :
+                case 'M' :
+                case 'm' :
+                case 'G' :
+                case 'g' :
+                case 'T' :
+                case 't' :
+                case 'P' :
+                case 'p' :
+                    if (!hasDigit || hasPoint) {
+                        token.tokenType   = Tokens.X_MALFORMED_NUMERIC;
+                        token.isMalformed = true;
+
+                        return;
+                    }
+
+                    String s = Character.toString((char) c).toUpperCase(
+                        Locale.ENGLISH);
+
+                    token.lobMultiplierType = Tokens.getNonKeywordID(s,
+                            Tokens.X_MALFORMED_NUMERIC);
+
+                    if (token.lobMultiplierType
+                            == Tokens.X_MALFORMED_NUMERIC) {
+                        token.tokenType   = Tokens.X_MALFORMED_NUMERIC;
+                        token.isMalformed = true;
+
+                        return;
+                    }
+
+                    try {
+                        token.tokenValue = ValuePool.getInt(
+                            Integer.parseInt(
+                                sqlString.substring(
+                                    tokenStart, currentPosition)));
+                        token.tokenType = Tokens.X_LOB_SIZE;
+
+                        currentPosition++;
+
+                        token.fullString = getPart(tokenPosition,
+                                                   currentPosition);
+                    } catch (NumberFormatException e) {
+                        token.tokenType   = Tokens.X_MALFORMED_NUMERIC;
+                        token.isMalformed = true;
+                    }
+
+                    return;
+
+                default :
+                    end = true;
+                    break;
+            }
+
+            if (end) {
+                break;
+            }
+        }
+
+        token.tokenString = sqlString.substring(tokenStart, currentPosition);
+
+        switch (token.dataType.typeCode) {
+
+            case Types.SQL_INTEGER :
+
+                // fredt -  -Integer.MIN_VALUE or -Long.MIN_VALUE are promoted
+                // to a wider type.
+                if (token.tokenString.length() < 11) {
+                    try {
+                        token.tokenValue = ValuePool.getInt(
+                            Integer.parseInt(token.tokenString));
+
+                        return;
+                    } catch (Exception e1) {}
+                }
+
+                if (this.token.tokenString.length() < 20) {
+                    try {
+                        token.dataType = Type.SQL_BIGINT;
+                        token.tokenValue = ValuePool.getLong(
+                            Long.parseLong(token.tokenString));
+
+                        return;
+                    } catch (Exception e2) {}
+                }
+
+                token.dataType = Type.SQL_NUMERIC;
+
+            // fall through
+            case Types.SQL_NUMERIC :
+                try {
+                    BigDecimal decimal = new BigDecimal(token.tokenString);
+
+                    token.tokenValue = decimal;
+                    token.dataType = NumberType.getNumberType(Types.NUMERIC,
+                            JavaSystem.precision(decimal), decimal.scale());
+                } catch (Exception e2) {
+                    token.tokenType   = Tokens.X_MALFORMED_NUMERIC;
+                    token.isMalformed = true;
+
+                    return;
+                }
+
+                return;
+
+            case Types.SQL_DOUBLE :
+                try {
+                    double d = JavaSystem.parseDouble(token.tokenString);
+                    long   l = Double.doubleToLongBits(d);
+
+                    token.tokenValue = ValuePool.getDouble(l);
+                } catch (Exception e2) {
+                    token.tokenType   = Tokens.X_MALFORMED_NUMERIC;
+                    token.isMalformed = true;
+
+                    return;
+                }
+
+                return;
+        }
+    }
+
+    boolean scanSeparator() {
+
+        boolean result = false;
+
+        while (true) {
+            boolean whiteSpace = scanWhitespace();
+
+            result |= whiteSpace;
+
+            if (scanCommentAsInlineSeparator()) {
+                result               = true;
+                hasNonSpaceSeparator = true;
+
+                continue;
+            }
+
+            break;
+        }
+
+//        token.isDelimiter |= result;
+        return result;
+    }
+
+    boolean scanCommentAsInlineSeparator() {
+
+        int character = charAt(currentPosition);
+
+        if (character == '-' && charAt(currentPosition + 1) == '-') {
+            int pos = sqlString.indexOf('\r', currentPosition + 2);
+
+            if (pos == -1) {
+                pos = sqlString.indexOf('\n', currentPosition + 2);
+            } else if (charAt(pos + 1) == '\n') {
+                pos++;
+            }
+
+            if (pos == -1) {
+                currentPosition = limit;
+            } else {
+                currentPosition = pos + 1;
+            }
+
+            return true;
+        } else if (character == '/' && charAt(currentPosition + 1) == '*') {
+            int pos = sqlString.indexOf("*/", currentPosition + 2);
+
+            if (pos == -1) {
+                token.tokenString = sqlString.substring(currentPosition,
+                        currentPosition + 2);
+                token.tokenType   = Tokens.X_MALFORMED_COMMENT;
+                token.isMalformed = true;
+
+                return false;
+            }
+
+            currentPosition = pos + 2;
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean scanWhitespace() {
+
+        boolean result = false;
+
+        for (; currentPosition < limit; currentPosition++) {
+            char c = sqlString.charAt(currentPosition);
+
+            if (c == ' ') {
+                result = true;
+
+                continue;
+            }
+
+            if (whiteSpaceSet.contains(c)) {
+                hasNonSpaceSeparator = true;
+                result               = true;
+
+                setLineNumber(c);
+
+                continue;
+            }
+
+            break;
+        }
+
+        return result;
+    }
+
+    private void setLineNumber(int c) {
+
+        if (c == '\r' || c == '\n') {
+            if (currentPosition == eolPosition + 1) {
+                if (c == '\n' && eolCode != c) {
+
+                    //
+                } else {
+                    lineNumber++;
+                }
+            } else {
+                lineNumber++;
+            }
+
+            eolPosition = currentPosition;
+            eolCode     = c;
+        }
+    }
+
+    void scanCharacterString() {
+
+        charWriter.reset(charBuffer);
+
+        while (true) {
+            scanStringPart('\'');
+
+            if (token.isMalformed) {
+                return;
+            }
+
+            if (scanSeparator() && charAt(currentPosition) == '\'') {
+                continue;
+            }
+
+            break;
+        }
+
+        token.tokenString = charWriter.toString();
+        token.tokenValue  = token.tokenString;
+    }
+
+    public void scanStringPart(char quoteChar) {
+
+        currentPosition++;
+
+        for (;;) {
+            int nextIndex = sqlString.indexOf(quoteChar, currentPosition);
+
+            if (nextIndex < 0) {
+                token.tokenString = sqlString.substring(currentPosition,
+                        limit);
+                token.tokenType = quoteChar == '\'' ? Tokens.X_MALFORMED_STRING
+                                                    : Tokens
+                                                    .X_MALFORMED_IDENTIFIER;
+                token.isMalformed = true;
+
+                return;
+            }
+
+            if (charAt(nextIndex + 1) == quoteChar) {
+                nextIndex += 1;
+
+                charWriter.write(sqlString, currentPosition,
+                                 nextIndex - currentPosition);
+
+                currentPosition = nextIndex + 1;
+
+                continue;
+            } else {
+                charWriter.write(sqlString, currentPosition,
+                                 nextIndex - currentPosition);
+
+                currentPosition = nextIndex + 1;
+
+                break;
+            }
+        }
+    }
+
+    /**
+     * token [separator]  , nondelimiter {delimiter | separator}
+     */
+    void scanToken() {
+
+        int character = charAt(currentPosition);
+
+        resetState();
+
+        token.tokenType = Tokens.X_IDENTIFIER;
+
+        switch (character) {
+
+/*
+            case '%' :
+            case '^' :
+            case '&' :
+            case ':' :
+            case '{' :
+            case '}' :
+                break;
+*/
+            case '[' :
+                token.tokenString = Tokens.T_LEFTBRACKET;
+                token.tokenType   = Tokens.LEFTBRACKET;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case ']' :
+                token.tokenString = Tokens.T_RIGHTBRACKET;
+                token.tokenType   = Tokens.RIGHTBRACKET;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '(' :
+                token.tokenString = Tokens.T_OPENBRACKET;
+                token.tokenType   = Tokens.OPENBRACKET;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case ')' :
+                token.tokenString = Tokens.T_CLOSEBRACKET;
+                token.tokenType   = Tokens.CLOSEBRACKET;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case ',' :
+                token.tokenString = Tokens.T_COMMA;
+                token.tokenType   = Tokens.COMMA;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '*' :
+                token.tokenString = Tokens.T_ASTERISK;
+                token.tokenType   = Tokens.ASTERISK;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '=' :
+                token.tokenString = Tokens.T_EQUALS;
+                token.tokenType   = Tokens.EQUALS;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case ';' :
+                token.tokenString = Tokens.T_SEMICOLON;
+                token.tokenType   = Tokens.SEMICOLON;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '+' :
+                token.tokenString = Tokens.T_PLUS;
+                token.tokenType   = Tokens.PLUS;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case ':' :
+                if (charAt(currentPosition + 1) == ':') {
+                    currentPosition   += 2;
+                    token.tokenString = Tokens.T_DOUBLE_COLON;
+                    token.tokenType   = Tokens.COLON;
+                    token.isDelimiter = true;
+
+                    return;
+                } else {
+                    token.tokenString = Tokens.T_COLON;
+                    token.tokenType   = Tokens.COLON;
+
+                    currentPosition++;
+
+                    token.isDelimiter = true;
+
+                    return;
+                }
+            case '?' :
+                if (charAt(currentPosition + 1) == '?') {
+                    if (charAt(currentPosition + 2) == '(') {
+                        token.tokenString = Tokens.T_OPENBRACKET;
+                        token.tokenType   = Tokens.OPENBRACKET;
+                        currentPosition   += 3;
+                        token.isDelimiter = true;
+
+                        return;
+                    } else if (charAt(currentPosition + 2) == ')') {
+                        token.tokenString = Tokens.T_CLOSEBRACKET;
+                        token.tokenType   = Tokens.CLOSEBRACKET;
+                        currentPosition   += 3;
+                        token.isDelimiter = true;
+
+                        return;
+                    }
+                }
+
+                token.tokenString = Tokens.T_QUESTION;
+                token.tokenType   = Tokens.QUESTION;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '!' :
+                if (charAt(currentPosition + 1) == '=') {
+                    token.tokenString = Tokens.T_NOT_EQUALS;
+                    token.tokenType   = Tokens.NOT_EQUALS;
+                    currentPosition   += 2;
+                    token.isDelimiter = true;
+
+                    return;
+                }
+
+                token.tokenString = sqlString.substring(currentPosition,
+                        currentPosition + 2);
+                token.tokenType   = Tokens.X_UNKNOWN_TOKEN;
+                token.isDelimiter = true;
+
+                return;
+
+            case '<' :
+                if (charAt(currentPosition + 1) == '>') {
+                    token.tokenString = Tokens.T_NOT_EQUALS;
+                    token.tokenType   = Tokens.NOT_EQUALS;
+                    currentPosition   += 2;
+                    token.isDelimiter = true;
+
+                    return;
+                }
+
+                if (charAt(currentPosition + 1) == '=') {
+                    token.tokenString = Tokens.T_LESS_EQUALS;
+                    token.tokenType   = Tokens.LESS_EQUALS;
+                    currentPosition   += 2;
+                    token.isDelimiter = true;
+
+                    return;
+                }
+
+                token.tokenString = Tokens.T_LESS;
+                token.tokenType   = Tokens.LESS;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '>' :
+                if (charAt(currentPosition + 1) == '=') {
+                    token.tokenString = Tokens.T_GREATER_EQUALS;
+                    token.tokenType   = Tokens.GREATER_EQUALS;
+                    currentPosition   += 2;
+                    token.isDelimiter = true;
+
+                    return;
+                }
+
+                token.tokenString = Tokens.T_GREATER;
+                token.tokenType   = Tokens.GREATER;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '|' :
+                if (charAt(currentPosition + 1) == '|') {
+                    token.tokenString = Tokens.T_CONCAT;
+                    token.tokenType   = Tokens.CONCAT;
+                    currentPosition   += 2;
+                    token.isDelimiter = true;
+
+                    return;
+                }
+
+                token.tokenString = sqlString.substring(currentPosition,
+                        currentPosition + 2);
+                token.tokenType   = Tokens.X_UNKNOWN_TOKEN;
+                token.isDelimiter = true;
+
+                return;
+
+            case '/' :
+                if (charAt(currentPosition + 1) == '/') {
+                    int pos = sqlString.indexOf('\r', currentPosition + 2);
+
+                    if (pos == -1) {
+                        pos = sqlString.indexOf('\n', currentPosition + 2);
+                    }
+
+                    if (pos == -1) {
+                        pos = limit;
+                    }
+
+                    token.tokenString = sqlString.substring(currentPosition
+                            + 2, pos);
+                    token.tokenType   = Tokens.X_REMARK;
+                    token.isDelimiter = true;
+
+                    return;
+                } else if (charAt(currentPosition + 1) == '*') {
+                    int pos = sqlString.indexOf("*/", currentPosition + 2);
+
+                    if (pos == -1) {
+                        token.tokenString =
+                            sqlString.substring(currentPosition,
+                                                currentPosition + 2);
+                        token.tokenType   = Tokens.X_UNKNOWN_TOKEN;
+                        token.isDelimiter = true;
+
+                        return;
+                    }
+
+                    token.tokenString = sqlString.substring(currentPosition
+                            + 2, pos);
+                    token.tokenType   = Tokens.X_REMARK;
+                    token.isDelimiter = true;
+
+                    return;
+                }
+
+                token.tokenString = Tokens.T_DIVIDE;
+                token.tokenType   = Tokens.DIVIDE;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '-' :
+                if (charAt(currentPosition + 1) == '-') {
+                    int pos = sqlString.indexOf('\r', currentPosition + 2);
+
+                    if (pos == -1) {
+                        pos = sqlString.indexOf('\n', currentPosition + 2);
+                    }
+
+                    if (pos == -1) {
+                        pos = limit;
+                    }
+
+                    token.tokenString = sqlString.substring(currentPosition
+                            + 2, pos);
+                    token.tokenType   = Tokens.X_REMARK;
+                    token.isDelimiter = true;
+
+                    return;
+                }
+
+                token.tokenString = Tokens.T_MINUS;
+                token.tokenType   = Tokens.MINUS;
+
+                currentPosition++;
+
+                token.isDelimiter = true;
+
+                return;
+
+            case '\"' :
+                token.tokenType = Tokens.X_DELIMITED_IDENTIFIER;
+                break;
+
+            case '\'' :
+                scanCharacterString();
+
+                if (token.isMalformed) {
+                    return;
+                }
+
+                token.dataType = CharacterType.getCharacterType(Types.SQL_CHAR,
+                        token.tokenString.length());
+                token.tokenType   = Tokens.X_VALUE;
+                token.isDelimiter = true;
+
+                return;
+
+            case 'x' :
+            case 'X' :
+                if (charAt(currentPosition + 1) == '\'') {
+                    currentPosition++;
+
+                    scanBinaryString();
+
+                    if (token.isMalformed) {
+                        return;
+                    }
+
+                    token.dataType = BinaryType.getBinaryType(
+                        Types.SQL_VARBINARY,
+                        ((BinaryData) token.tokenValue).length(null));
+                    token.tokenType = Tokens.X_VALUE;
+
+                    return;
+                }
+                break;
+
+            case 'b' :
+            case 'B' :
+                if (charAt(currentPosition + 1) == '\'') {
+                    currentPosition++;
+
+                    scanBitString();
+
+                    if (token.isMalformed) {
+                        return;
+                    }
+
+                    token.dataType = BitType.getBitType(
+                        Types.SQL_BIT,
+                        ((BinaryData) token.tokenValue).bitLength(null));
+                    token.tokenType = Tokens.X_VALUE;
+
+                    return;
+                }
+                break;
+
+            case 'n' :
+            case 'N' :
+                if (charAt(currentPosition + 1) == '\'') {
+                    currentPosition++;
+
+                    scanCharacterString();
+
+                    if (token.isMalformed) {
+                        return;
+                    }
+
+                    token.dataType = CharacterType.getCharacterType(
+                        Types.SQL_CHAR, token.tokenString.length());
+                    token.tokenType = Tokens.X_VALUE;
+
+                    return;
+                }
+                break;
+
+            case 'u' :
+            case 'U' :
+                if (charAt(currentPosition + 1) == '&') {
+                    if (charAt(currentPosition + 2) == '\'') {
+                        currentPosition += 2;
+                        token.dataType  = Type.SQL_CHAR;
+                        token.tokenType = Tokens.X_VALUE;
+
+                        scanUnicodeString();
+
+                        if (token.isMalformed) {
+                            return;
+                        }
+
+                        token.dataType = CharacterType.getCharacterType(
+                            Types.SQL_CHAR,
+                            ((String) token.tokenValue).length());
+
+                        return;
+                    }
+                }
+                break;
+
+            case '_' :
+
+                /**
+                 * @todo 1.9.0 - review following
+                 * identifier chain must not have catalog identifier
+                 * character set specification to be included in the token.dataType
+                 */
+                currentPosition++;
+
+                scanIdentifierChain();
+
+                if (token.isMalformed) {
+                    return;
+                }
+
+                if (token.tokenType != Tokens.X_IDENTIFIER
+                        || token.namePrePrefix != null) {
+
+                    /** @todo 1.9.0 - review message malformed character set identifier */
+                    token.tokenType   = Tokens.X_MALFORMED_STRING;
+                    token.isMalformed = true;
+
+                    return;
+                }
+
+                token.charsetSchema = token.namePrefix;
+                token.charsetName   = token.tokenString;
+
+                scanSeparator();
+
+                if (charAt(currentPosition) == '\'') {
+                    scanCharacterString();
+
+                    token.tokenType = Tokens.X_VALUE;
+                    token.dataType = CharacterType.getCharacterType(
+                        Types.SQL_CHAR, token.tokenString.length());
+                    token.isDelimiter = true;
+
+                    return;
+                }
+                break;
+
+            case '0' :
+            case '1' :
+            case '2' :
+            case '3' :
+            case '4' :
+            case '5' :
+            case '6' :
+            case '7' :
+            case '8' :
+            case '9' :
+            case '.' :
+                token.tokenType = Tokens.X_VALUE;
+
+                scanNumber();
+
+                return;
+        }
+
+        scanIdentifierChain();
+
+        if (token.tokenType == Tokens.X_IDENTIFIER) {
+            token.isUndelimitedIdentifier = true;
+            token.tokenType = Tokens.getKeywordID(token.tokenString,
+                                                  Tokens.X_IDENTIFIER);
+
+            if (token.tokenType == Tokens.X_IDENTIFIER) {
+                token.tokenType = Tokens.getNonKeywordID(token.tokenString,
+                        Tokens.X_IDENTIFIER);
+            } else {
+                token.isReservedIdentifier = true;
+                token.isCoreReservedIdentifier =
+                    Tokens.isCoreKeyword(token.tokenType);
+            }
+        } else if (token.tokenType == Tokens.X_DELIMITED_IDENTIFIER) {
+            token.isDelimitedIdentifier = true;
+        }
+    }
+
+    public boolean scanNull() {
+
+        scanSeparator();
+
+        int character = charAt(currentPosition);
+
+        if (character == 'N' || character == 'n') {
+            if (scanSpecialIdentifier(Tokens.T_NULL)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    //
+    private void scanNext(int error) {
+
+        scanNext();
+
+        if (token.isMalformed) {
+            throw Error.error(error);
+        }
+    }
+
+    /**
+     * Reads the type part of the INTERVAL
+     */
+    IntervalType scanIntervalType() {
+
+        int       precision = -1;
+        int       scale     = -1;
+        int       startToken;
+        int       endToken;
+        final int errorCode = ErrorCode.X_22006;
+
+        startToken = endToken = token.tokenType;
+
+        scanNext(errorCode);
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            scanNext(errorCode);
+
+            if (token.dataType == null
+                    || token.dataType.typeCode != Types.SQL_INTEGER) {
+                throw Error.error(errorCode);
+            }
+
+            precision = ((Number) this.token.tokenValue).intValue();
+
+            scanNext(errorCode);
+
+            if (token.tokenType == Tokens.COMMA) {
+                if (startToken != Tokens.SECOND) {
+                    throw Error.error(errorCode);
+                }
+
+                scanNext(errorCode);
+
+                if (token.dataType == null
+                        || token.dataType.typeCode != Types.SQL_INTEGER) {
+                    throw Error.error(errorCode);
+                }
+
+                scale = ((Number) token.tokenValue).intValue();
+
+                scanNext(errorCode);
+            }
+
+            if (token.tokenType != Tokens.CLOSEBRACKET) {
+                throw Error.error(errorCode);
+            }
+
+            scanNext(errorCode);
+        }
+
+        if (token.tokenType == Tokens.TO) {
+            scanNext(errorCode);
+
+            endToken = token.tokenType;
+
+            scanNext(errorCode);
+        }
+
+        if (token.tokenType == Tokens.OPENBRACKET) {
+            if (endToken != Tokens.SECOND || endToken == startToken) {
+                throw Error.error(errorCode);
+            }
+
+            scanNext(errorCode);
+
+            if (token.dataType == null
+                    || token.dataType.typeCode != Types.SQL_INTEGER) {
+                throw Error.error(errorCode);
+            }
+
+            scale = ((Number) token.tokenValue).intValue();
+
+            scanNext(errorCode);
+
+            if (token.tokenType != Tokens.CLOSEBRACKET) {
+                throw Error.error(errorCode);
+            }
+
+            scanNext(errorCode);
+        }
+
+        int startIndex = ArrayUtil.find(Tokens.SQL_INTERVAL_FIELD_CODES,
+                                        startToken);
+        int endIndex = ArrayUtil.find(Tokens.SQL_INTERVAL_FIELD_CODES,
+                                      endToken);
+
+        return IntervalType.getIntervalType(startIndex, endIndex, precision,
+                                            scale);
+    }
+
+    private String intervalString;
+    private int    intervalPosition;
+    private int    intervalPrecision;
+    private int    fractionPrecision;
+    Type           dateTimeType;
+
+    public TimestampData newDate(String s) {
+
+        intervalPosition  = 0;
+        fractionPrecision = 0;
+        dateTimeType      = null;
+        intervalString    = s;
+
+        scanDateParts(2);
+
+        if (intervalPosition != s.length()) {
+            throw Error.error(ErrorCode.X_22007);
+        }
+
+        long seconds = HsqlDateTime.getDateSeconds(s);
+
+        return new TimestampData(seconds);
+    }
+
+    /**
+     * @todo 1.9.0 - review the following
+     *      - misses nano fractions
+     *      - misses displacement
+     *      - doesn't allow single digit components
+     */
+    public TimestampData newTimestamp(String s) {
+
+        long    zoneSeconds = 0;
+        long    seconds;
+        int     fraction = 0;
+        int     endIndex = s.length();
+        boolean negate;
+        boolean hasZone = false;
+
+        intervalPosition  = 0;
+        fractionPrecision = 0;
+        dateTimeType      = null;
+        intervalString    = s;
+
+        scanDateParts(5);
+
+        try {
+            seconds = HsqlDateTime.getTimestampSeconds(s.substring(0,
+                    intervalPosition));
+        } catch (Throwable e) {
+            throw Error.error(ErrorCode.X_22007);
+        }
+
+        int position;
+
+        fraction = scanIntervalFraction(DTIType.maxFractionPrecision);
+        position = intervalPosition;
+        negate   = scanIntervalSign();
+
+        if (negate || position != intervalPosition) {
+            zoneSeconds = scanIntervalValue(Type.SQL_INTERVAL_HOUR_TO_MINUTE);
+            hasZone     = true;
+
+            if (negate) {
+                zoneSeconds = -zoneSeconds;
+            }
+        }
+
+        if (zoneSeconds >= DTIType.yearToSecondFactors[2]
+                || zoneSeconds > DTIType.timezoneSecondsLimit
+                || -zoneSeconds > DTIType.timezoneSecondsLimit) {
+            throw Error.error(ErrorCode.X_22009);
+        }
+
+        if (intervalPosition != endIndex) {
+            throw Error.error(ErrorCode.X_22007);
+        }
+
+        int type = hasZone ? Types.SQL_TIMESTAMP_WITH_TIME_ZONE
+                           : Types.SQL_TIMESTAMP;
+
+        dateTimeType = DateTimeType.getDateTimeType(type, fractionPrecision);
+
+        if (hasZone) {
+            seconds -= zoneSeconds;
+        }
+
+        return new TimestampData(seconds, fraction, (int) zoneSeconds);
+    }
+
+    void scanDateParts(int lastPart) {
+
+        byte[]    separators    = DTIType.yearToSecondSeparators;
+        int       i             = intervalPosition;
+        final int firstPart     = 0;
+        int       currentPart   = firstPart;
+        int       currentDigits = 0;
+
+        for (; currentPart <= lastPart; ) {
+            boolean endOfPart = false;
+
+            if (i == intervalString.length()) {
+                if (currentPart == lastPart) {
+                    endOfPart = true;
+                } else {
+
+                    // parts missing
+                    throw Error.error(ErrorCode.X_22007);
+                }
+            } else {
+                int character = intervalString.charAt(i);
+
+                if (character >= '0' && character <= '9') {
+                    currentDigits++;
+                    i++;
+                } else if (character == separators[currentPart]) {
+                    endOfPart = true;
+
+                    if (currentPart != lastPart) {
+                        i++;
+                    }
+                } else if (currentPart == lastPart) {
+                    endOfPart = true;
+                } else {
+                    throw Error.error(ErrorCode.X_22007);
+                }
+            }
+
+            if (endOfPart) {
+                if (currentPart == firstPart) {
+                    if (currentDigits != 4) {
+                        throw Error.error(ErrorCode.X_22007);
+                    }
+                } else {
+                    if (currentDigits != 2) {
+                        throw Error.error(ErrorCode.X_22007);
+                    }
+                }
+
+                currentPart++;
+
+                currentDigits = 0;
+
+                if (i == intervalString.length()) {
+                    break;
+                }
+            }
+        }
+
+        intervalPosition = i;
+    }
+
+    public TimeData newTime(String s) {
+
+        intervalPosition  = 0;
+        fractionPrecision = 0;
+        dateTimeType      = null;
+        intervalString    = s;
+
+        long    seconds = scanIntervalValue(Type.SQL_INTERVAL_HOUR_TO_SECOND);
+        int     fraction = scanIntervalFraction(DTIType.maxFractionPrecision);
+        long    zoneSeconds = 0;
+        int     position    = intervalPosition;
+        boolean hasZone     = false;
+        boolean negate      = scanIntervalSign();
+
+        if (position != intervalPosition) {
+            zoneSeconds = scanIntervalValue(Type.SQL_INTERVAL_HOUR_TO_MINUTE);
+            hasZone     = true;
+        }
+
+        if (intervalPosition != s.length()) {
+            throw Error.error(ErrorCode.X_22009);
+        }
+
+        if (seconds >= DTIType.yearToSecondFactors[2]) {
+            throw Error.error(ErrorCode.X_22008);
+        }
+
+        if (zoneSeconds > DTIType.timezoneSecondsLimit) {
+            throw Error.error(ErrorCode.X_22009);
+        }
+
+        if (negate) {
+            zoneSeconds = -zoneSeconds;
+        }
+
+        int type = hasZone ? Types.SQL_TIME_WITH_TIME_ZONE
+                           : Types.SQL_TIME;
+
+        dateTimeType = DateTimeType.getDateTimeType(type, fractionPrecision);
+
+        if (hasZone) {
+            seconds -= zoneSeconds;
+        }
+
+        return new TimeData((int) seconds, fraction, (int) zoneSeconds);
+    }
+
+    public Object newInterval(String s, IntervalType type) {
+
+        intervalPosition = 0;
+        intervalString   = s;
+
+        boolean negate   = scanIntervalSign();
+        long    units    = scanIntervalValue(type);
+        int     fraction = 0;
+
+        if (type.endIntervalType == Types.SQL_INTERVAL_SECOND) {
+            fraction = scanIntervalFraction(type.scale);
+        }
+
+        if (intervalPosition != s.length()) {
+            throw Error.error(ErrorCode.X_22006);
+        }
+
+        if (negate) {
+            units    = -units;
+            fraction = -fraction;
+        }
+
+        dateTimeType = type;
+
+        if (type.defaultPrecision) {
+            dateTimeType = IntervalType.getIntervalType(type.typeCode,
+                    type.startIntervalType, type.endIntervalType,
+                    intervalPrecision, fractionPrecision, false);
+        }
+
+        if (type.endPartIndex <= DTIType.INTERVAL_MONTH_INDEX) {
+            return new IntervalMonthData(units);
+        } else {
+            return new IntervalSecondData(units, fraction);
+        }
+    }
+
+    public long scanIntervalValue(IntervalType type) {
+
+        byte[] separators    = DTIType.yearToSecondSeparators;
+        int[]  factors       = DTIType.yearToSecondFactors;
+        int[]  limits        = DTIType.yearToSecondLimits;
+        int    firstPart     = type.startPartIndex;
+        int    lastPart      = type.endPartIndex;
+        long   totalValue    = 0;
+        int    currentValue  = 0;
+        int    i             = intervalPosition;
+        int    currentPart   = firstPart;
+        int    currentDigits = 0;
+
+        for (; currentPart <= lastPart; ) {
+            boolean endOfPart = false;
+
+            if (i == intervalString.length()) {
+                if (currentPart == lastPart) {
+                    endOfPart = true;
+                } else {
+                    throw Error.error(ErrorCode.X_22006);
+                }
+            } else {
+                int character = intervalString.charAt(i);
+
+                if (character >= '0' && character <= '9') {
+                    int digit = character - '0';
+
+                    currentValue *= 10;
+                    currentValue += digit;
+
+                    currentDigits++;
+                    i++;
+                } else if (character == separators[currentPart]) {
+                    endOfPart = true;
+
+                    if (currentPart != lastPart) {
+                        i++;
+                    }
+                } else if (currentPart == lastPart) {
+                    endOfPart = true;
+                } else {
+                    throw Error.error(ErrorCode.X_22006);
+                }
+            }
+
+            if (endOfPart) {
+                if (currentPart == firstPart) {
+                    if (!type.defaultPrecision
+                            && currentDigits > type.precision) {
+                        throw Error.error(ErrorCode.X_22015);
+                    }
+
+                    if (currentDigits == 0) {
+                        throw Error.error(ErrorCode.X_22006);
+                    }
+
+                    int factor = factors[currentPart];
+
+                    totalValue        += (long) currentValue * factor;
+                    intervalPrecision = currentDigits;
+                } else {
+                    if (currentValue >= limits[currentPart]) {
+                        throw Error.error(ErrorCode.X_22015);
+                    }
+
+                    if (currentDigits != 2) {
+                        throw Error.error(ErrorCode.X_22006);
+                    }
+
+                    totalValue += currentValue * factors[currentPart];
+                }
+
+                currentPart++;
+
+                currentValue  = 0;
+                currentDigits = 0;
+
+                if (i == intervalString.length()) {
+                    break;
+                }
+            }
+        }
+
+        intervalPosition = i;
+
+        return totalValue;
+    }
+
+    boolean scanIntervalSign() {
+
+        boolean negate = false;
+
+        if (intervalPosition == intervalString.length()) {
+            return false;
+        }
+
+        if (intervalString.charAt(intervalPosition) == '-') {
+            negate = true;
+
+            intervalPosition++;
+        } else if (intervalString.charAt(intervalPosition) == '+') {
+            intervalPosition++;
+        }
+
+        return negate;
+    }
+
+    int scanIntervalFraction(int decimalPrecision) {
+
+        if (intervalPosition == intervalString.length()) {
+            return 0;
+        }
+
+        if (intervalString.charAt(intervalPosition) != '.') {
+            return 0;
+        }
+
+        intervalPosition++;
+
+        int currentValue  = 0;
+        int currentDigits = 0;
+
+        for (; intervalPosition < intervalString.length(); ) {
+            int character = intervalString.charAt(intervalPosition);
+
+            if (character >= '0' && character <= '9') {
+                int digit = character - '0';
+
+                currentValue *= 10;
+                currentValue += digit;
+
+                intervalPosition++;
+                currentDigits++;
+
+                if (currentDigits == DTIType.maxFractionPrecision) {
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+
+        fractionPrecision = currentDigits;
+        currentValue      *= DTIType.nanoScaleFactors[currentDigits];
+        currentValue = DTIType.normaliseFraction(currentValue,
+                decimalPrecision);
+
+        return currentValue;
+    }
+
+    void scanIntervalSpaces() {
+
+        for (; intervalPosition < intervalString.length();
+                intervalPosition++) {
+            if (intervalString.charAt(intervalPosition) != ' ') {
+                break;
+            }
+        }
+    }
+
+    /*
+     * synchronized methods for use with shared Scanner objects used for type
+     *  conversion
+     */
+    public synchronized Number convertToNumber(String s,
+            NumberType numberType) {
+
+        Number  number;
+        boolean minus = false;
+        Type    type;
+
+        reset(s);
+        resetState();
+        scanWhitespace();
+        scanToken();
+        scanWhitespace();
+
+        if (token.tokenType == Tokens.PLUS) {
+            scanToken();
+            scanWhitespace();
+        } else if (token.tokenType == Tokens.MINUS) {
+            minus = true;
+
+            scanToken();
+            scanWhitespace();
+        }
+
+        if (!hasNonSpaceSeparator && token.tokenType == Tokens.X_VALUE
+                && token.tokenValue instanceof Number) {
+            number = (Number) token.tokenValue;
+            type   = token.dataType;
+
+            if (minus) {
+                number = (Number) token.dataType.negate(number);
+            }
+
+            scanEnd();
+
+            if (token.tokenType == Tokens.X_ENDPARSE) {
+                number = (Number) numberType.convertToType(null, number, type);
+
+                return number;
+            }
+        }
+
+        throw Error.error(ErrorCode.X_22018);
+    }
+
+    public synchronized BinaryData convertToBinary(String s) {
+
+        boolean hi = true;
+        byte    b  = 0;
+
+        reset(s);
+        resetState();
+        byteOutputStream.reset(byteBuffer);
+
+        for (; currentPosition < limit; currentPosition++, hi = !hi) {
+            int c = sqlString.charAt(currentPosition);
+
+            c = getHexValue(c);
+
+            if (c == -1) {
+
+                // bad character
+                token.tokenType   = Tokens.X_MALFORMED_BINARY_STRING;
+                token.isMalformed = true;
+
+                break;
+            }
+
+            if (hi) {
+                b = (byte) (c << 4);
+            } else {
+                b += (byte) c;
+
+                byteOutputStream.writeByte(b);
+            }
+        }
+
+        if (!hi) {
+
+            // odd nibbles
+            token.tokenType   = Tokens.X_MALFORMED_BINARY_STRING;
+            token.isMalformed = true;
+        }
+
+        if (token.isMalformed) {
+            throw Error.error(ErrorCode.X_22018);
+        }
+
+        BinaryData data = new BinaryData(byteOutputStream.toByteArray(),
+                                         false);
+
+        byteOutputStream.reset(byteBuffer);
+
+        return data;
+    }
+
+    public synchronized BinaryData convertToBit(String s) {
+
+        BitMap map      = new BitMap(32);
+        int    bitIndex = map.size();
+
+        reset(s);
+        resetState();
+        byteOutputStream.reset(byteBuffer);
+
+        for (; currentPosition < limit; currentPosition++) {
+            int c = sqlString.charAt(currentPosition);
+
+            if (c == '0') {
+                bitIndex++;
+            } else if (c == '1') {
+                map.set(bitIndex);
+
+                bitIndex++;
+            } else {
+                token.tokenType   = Tokens.X_MALFORMED_BIT_STRING;
+                token.isMalformed = true;
+
+                throw Error.error(ErrorCode.X_22018);
+            }
+        }
+
+        map.setSize(bitIndex);
+
+        return BinaryData.getBitData(map.getBytes(), map.size());
+    }
+
+    // should perform range checks etc.
+    public synchronized Object convertToDatetimeInterval(
+            SessionInterface session, String s, DTIType type) {
+
+        Object       value;
+        IntervalType intervalType  = null;
+        int          dateTimeToken = -1;
+        int          errorCode     = type.isDateTimeType() ? ErrorCode.X_22007
+                                                           : ErrorCode.X_22006;
+
+        reset(s);
+        resetState();
+        scanToken();
+        scanWhitespace();
+
+        switch (token.tokenType) {
+
+            case Tokens.INTERVAL :
+            case Tokens.DATE :
+            case Tokens.TIME :
+            case Tokens.TIMESTAMP :
+                dateTimeToken = token.tokenType;
+
+                scanToken();
+
+                if (token.tokenType != Tokens.X_VALUE
+                        || token.dataType.typeCode != Types.SQL_CHAR) {
+
+                    // error datetime bad literal
+                    throw Error.error(errorCode);
+                }
+
+                s = token.tokenString;
+
+                scanNext(ErrorCode.X_22007);
+
+                if (type.isIntervalType()) {
+                    intervalType = scanIntervalType();
+                }
+
+                if (token.tokenType != Tokens.X_ENDPARSE) {
+                    throw Error.error(errorCode);
+                }
+
+            // fall through
+            default :
+        }
+
+        switch (type.typeCode) {
+
+            case Types.SQL_DATE : {
+                if (dateTimeToken != -1 && dateTimeToken != Tokens.DATE) {
+                    throw Error.error(errorCode);
+                }
+
+                value = newDate(s);
+
+                return type.convertToType(session, value, Type.SQL_DATE);
+            }
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE : {
+                if (dateTimeToken != -1 && dateTimeToken != Tokens.TIME) {
+                    throw Error.error(errorCode);
+                }
+
+                Object o = newTime(s);
+
+                return type.convertToType(session, o, dateTimeType);
+            }
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                if (dateTimeToken != -1 && dateTimeToken != Tokens.TIMESTAMP) {
+                    throw Error.error(errorCode);
+                }
+
+                value = newTimestamp(s);
+
+                return type.convertToType(session, value, dateTimeType);
+            }
+            default :
+                if (dateTimeToken != -1 && dateTimeToken != Tokens.INTERVAL) {
+                    throw Error.error(errorCode);
+                }
+
+                if (type.isIntervalType()) {
+                    value = newInterval(s, (IntervalType) type);
+
+                    if (intervalType != null) {
+                        if (intervalType.startIntervalType != type
+                                .startIntervalType || intervalType
+                                .endIntervalType != type.endIntervalType) {
+                            throw Error.error(errorCode);
+                        }
+                    }
+
+                    return type.convertToType(session, value, dateTimeType);
+                }
+
+                throw Error.runtimeError(ErrorCode.U_S0500, "Scanner");
+        }
+    }
+}
diff --git a/src/org/hsqldb/Schema.java b/src/org/hsqldb/Schema.java
new file mode 100644
index 0000000..a7939bb
--- /dev/null
+++ b/src/org/hsqldb/Schema.java
@@ -0,0 +1,367 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.WrapperIterator;
+import org.hsqldb.rights.Grantee;
+
+public final class Schema implements SchemaObject {
+
+    private HsqlName name;
+    SchemaObjectSet  triggerLookup;
+    SchemaObjectSet  constraintLookup;
+    SchemaObjectSet  indexLookup;
+    SchemaObjectSet  tableLookup;
+    SchemaObjectSet  sequenceLookup;
+    SchemaObjectSet  typeLookup;
+    SchemaObjectSet  charsetLookup;
+    SchemaObjectSet  collationLookup;
+    SchemaObjectSet  procedureLookup;
+    SchemaObjectSet  functionLookup;
+    SchemaObjectSet  specificRoutineLookup;
+    SchemaObjectSet  assertionLookup;
+    HashMappedList   tableList;
+    HashMappedList   sequenceList;
+    Grantee          owner;
+    long             changeTimestamp;
+
+    public Schema(HsqlName name, Grantee owner) {
+
+        this.name        = name;
+        triggerLookup    = new SchemaObjectSet(SchemaObject.TRIGGER);
+        indexLookup      = new SchemaObjectSet(SchemaObject.INDEX);
+        constraintLookup = new SchemaObjectSet(SchemaObject.CONSTRAINT);
+        tableLookup      = new SchemaObjectSet(SchemaObject.TABLE);
+        sequenceLookup   = new SchemaObjectSet(SchemaObject.SEQUENCE);
+        typeLookup       = new SchemaObjectSet(SchemaObject.TYPE);
+        charsetLookup    = new SchemaObjectSet(SchemaObject.CHARSET);
+        collationLookup  = new SchemaObjectSet(SchemaObject.COLLATION);
+        procedureLookup  = new SchemaObjectSet(SchemaObject.PROCEDURE);
+        functionLookup   = new SchemaObjectSet(SchemaObject.FUNCTION);
+        specificRoutineLookup =
+            new SchemaObjectSet(SchemaObject.SPECIFIC_ROUTINE);
+        assertionLookup = new SchemaObjectSet(SchemaObject.ASSERTION);
+        tableList       = (HashMappedList) tableLookup.map;
+        sequenceList    = (HashMappedList) sequenceLookup.map;
+        this.owner      = owner;
+        name.owner      = owner;
+    }
+
+    public int getType() {
+        return SchemaObject.SCHEMA;
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public HsqlName getSchemaName() {
+        return null;
+    }
+
+    public HsqlName getCatalogName() {
+        return null;
+    }
+
+    public Grantee getOwner() {
+        return owner;
+    }
+
+    public OrderedHashSet getReferences() {
+        return new OrderedHashSet();
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public long getChangeTimestamp() {
+        return changeTimestamp;
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer(128);
+
+        sb.append(Tokens.T_CREATE).append(' ');
+        sb.append(Tokens.T_SCHEMA).append(' ');
+        sb.append(getName().statementName).append(' ');
+        sb.append(Tokens.T_AUTHORIZATION).append(' ');
+        sb.append(getOwner().getStatementName());
+
+        return sb.toString();
+    }
+
+    static String getSetSchemaSQL(HsqlName schemaName) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_SET).append(' ');
+        sb.append(Tokens.T_SCHEMA).append(' ');
+        sb.append(schemaName.statementName);
+
+        return sb.toString();
+    }
+
+    public String[] getSQLArray(OrderedHashSet resolved,
+                                OrderedHashSet unresolved) {
+
+        HsqlArrayList list      = new HsqlArrayList();
+        String        setSchema = getSetSchemaSQL(name);
+
+        list.add(setSchema);
+
+        //
+        String[] subList;
+
+        subList = sequenceLookup.getSQL(resolved, unresolved);
+
+        list.addAll(subList);
+
+        subList = tableLookup.getSQL(resolved, unresolved);
+
+        list.addAll(subList);
+
+        subList = functionLookup.getSQL(resolved, unresolved);
+
+        list.addAll(subList);
+
+        subList = procedureLookup.getSQL(resolved, unresolved);
+
+        list.addAll(subList);
+
+        subList = assertionLookup.getSQL(resolved, unresolved);
+
+        list.addAll(subList);
+
+//
+        if (list.size() == 1) {
+            return new String[]{};
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public String[] getSequenceRestartSQL() {
+
+        HsqlArrayList list = new HsqlArrayList();
+        Iterator      it   = sequenceLookup.map.values().iterator();
+
+        while (it.hasNext()) {
+            NumberSequence sequence = (NumberSequence) it.next();
+            String         ddl      = sequence.getRestartSQL();
+
+            list.add(ddl);
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public String[] getTriggerSQL() {
+
+        HsqlArrayList list = new HsqlArrayList();
+        Iterator      it   = tableLookup.map.values().iterator();
+
+        while (it.hasNext()) {
+            Table    table = (Table) it.next();
+            String[] ddl   = table.getTriggerSQL();
+
+            list.addAll(ddl);
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public void addSimpleObjects(OrderedHashSet unresolved) {
+
+        Iterator it = specificRoutineLookup.map.values().iterator();
+
+        while (it.hasNext()) {
+            Routine routine = (Routine) it.next();
+
+            if (routine.dataImpact == Routine.NO_SQL
+                    || routine.dataImpact == Routine.CONTAINS_SQL) {
+                unresolved.add(routine);
+            }
+        }
+
+        unresolved.addAll(typeLookup.map.values());
+        unresolved.addAll(charsetLookup.map.values());
+        unresolved.addAll(collationLookup.map.values());
+    }
+
+    boolean isEmpty() {
+
+        return sequenceLookup.isEmpty() && tableLookup.isEmpty()
+               && typeLookup.isEmpty() && charsetLookup.isEmpty()
+               && collationLookup.isEmpty() && specificRoutineLookup.isEmpty();
+    }
+
+    public SchemaObjectSet getObjectSet(int type) {
+
+        switch (type) {
+
+            case SchemaObject.SEQUENCE :
+                return sequenceLookup;
+
+            case SchemaObject.TABLE :
+            case SchemaObject.VIEW :
+                return tableLookup;
+
+            case SchemaObject.CHARSET :
+                return charsetLookup;
+
+            case SchemaObject.COLLATION :
+                return collationLookup;
+
+            case SchemaObject.PROCEDURE :
+                return procedureLookup;
+
+            case SchemaObject.FUNCTION :
+                return functionLookup;
+
+            case SchemaObject.ROUTINE :
+                return functionLookup;
+
+            case SchemaObject.SPECIFIC_ROUTINE :
+                return specificRoutineLookup;
+
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+                return typeLookup;
+
+            case SchemaObject.ASSERTION :
+                return assertionLookup;
+
+            case SchemaObject.TRIGGER :
+                return triggerLookup;
+
+            case SchemaObject.INDEX :
+                return indexLookup;
+
+            case SchemaObject.CONSTRAINT :
+                return constraintLookup;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Schema");
+        }
+    }
+
+    Iterator schemaObjectIterator(int type) {
+
+        switch (type) {
+
+            case SchemaObject.SEQUENCE :
+                return sequenceLookup.map.values().iterator();
+
+            case SchemaObject.TABLE :
+            case SchemaObject.VIEW :
+                return tableLookup.map.values().iterator();
+
+            case SchemaObject.CHARSET :
+                return charsetLookup.map.values().iterator();
+
+            case SchemaObject.COLLATION :
+                return collationLookup.map.values().iterator();
+
+            case SchemaObject.PROCEDURE :
+                return procedureLookup.map.values().iterator();
+
+            case SchemaObject.FUNCTION :
+                return functionLookup.map.values().iterator();
+
+            case SchemaObject.ROUTINE :
+                Iterator functions = functionLookup.map.values().iterator();
+
+                return new WrapperIterator(
+                    functions, procedureLookup.map.values().iterator());
+
+            case SchemaObject.SPECIFIC_ROUTINE :
+                return specificRoutineLookup.map.values().iterator();
+
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+                return typeLookup.map.values().iterator();
+
+            case SchemaObject.ASSERTION :
+                return assertionLookup.map.values().iterator();
+
+            case SchemaObject.TRIGGER :
+                return triggerLookup.map.values().iterator();
+
+            case SchemaObject.INDEX :
+                return indexLookup.map.values().iterator();
+
+            case SchemaObject.CONSTRAINT :
+                return constraintLookup.map.values().iterator();
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Schema");
+        }
+    }
+
+    void clearStructures() {
+
+        tableList.clear();
+        sequenceList.clear();
+
+        triggerLookup    = null;
+        indexLookup      = null;
+        constraintLookup = null;
+        procedureLookup  = null;
+        functionLookup   = null;
+        sequenceLookup   = null;
+        tableLookup      = null;
+        typeLookup       = null;
+    }
+}
diff --git a/src/org/hsqldb/SchemaManager.java b/src/org/hsqldb/SchemaManager.java
new file mode 100644
index 0000000..d79a9ac
--- /dev/null
+++ b/src/org/hsqldb/SchemaManager.java
@@ -0,0 +1,2124 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.MultiValueHashMap;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.lib.WrapperIterator;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.types.Type;
+
+/**
+ * Manages all SCHEMA related database objects
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version  1.9.0
+ * @since 1.8.0
+ */
+public class SchemaManager {
+
+    Database          database;
+    HsqlName          defaultSchemaHsqlName;
+    HashMappedList    schemaMap        = new HashMappedList();
+    MultiValueHashMap referenceMap     = new MultiValueHashMap();
+    int               defaultTableType = TableBase.MEMORY_TABLE;
+    long              schemaChangeTimestamp;
+
+    public SchemaManager(Database database) {
+
+        this.database         = database;
+        defaultSchemaHsqlName = SqlInvariants.INFORMATION_SCHEMA_HSQLNAME;
+
+        Schema schema =
+            new Schema(SqlInvariants.INFORMATION_SCHEMA_HSQLNAME,
+                       SqlInvariants.INFORMATION_SCHEMA_HSQLNAME.owner);
+
+        schemaMap.put(schema.getName().name, schema);
+
+        try {
+            schema.typeLookup.add(SqlInvariants.CARDINAL_NUMBER);
+            schema.typeLookup.add(SqlInvariants.YES_OR_NO);
+            schema.typeLookup.add(SqlInvariants.CHARACTER_DATA);
+            schema.typeLookup.add(SqlInvariants.SQL_IDENTIFIER);
+            schema.typeLookup.add(SqlInvariants.TIME_STAMP);
+            schema.charsetLookup.add(SqlInvariants.SQL_TEXT);
+            schema.charsetLookup.add(SqlInvariants.SQL_IDENTIFIER_CHARSET);
+            schema.charsetLookup.add(SqlInvariants.SQL_CHARACTER);
+        } catch (HsqlException e) {}
+    }
+
+    public void setSchemaChangeTimestamp() {
+        schemaChangeTimestamp = database.txManager.getGlobalChangeTimestamp();
+    }
+
+    public long getSchemaChangeTimestamp() {
+        return schemaChangeTimestamp;
+    }
+
+    // pre-defined
+    public HsqlName getSQLJSchemaHsqlName() {
+        return SqlInvariants.SQLJ_SCHEMA_HSQLNAME;
+    }
+
+    // SCHEMA management
+    public void createPublicSchema() {
+
+        HsqlName name = database.nameManager.newHsqlName(null,
+            SqlInvariants.PUBLIC_SCHEMA, SchemaObject.SCHEMA);
+        Schema schema = new Schema(name,
+                                   database.getGranteeManager().getDBARole());
+
+        defaultSchemaHsqlName = schema.getName();
+
+        schemaMap.put(schema.getName().name, schema);
+    }
+
+    /**
+     * Creates a schema belonging to the given grantee.
+     */
+    public void createSchema(HsqlName name, Grantee owner) {
+
+        SqlInvariants.checkSchemaNameNotSystem(name.name);
+
+        Schema schema = new Schema(name, owner);
+
+        schemaMap.add(name.name, schema);
+    }
+
+    public void dropSchema(Session session, String name, boolean cascade) {
+
+        Schema schema = (Schema) schemaMap.get(name);
+
+        if (schema == null) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        if (SqlInvariants.isLobsSchemaName(name)) {
+            throw Error.error(ErrorCode.X_42503, name);
+        }
+
+        if (!cascade && !schema.isEmpty()) {
+            throw Error.error(ErrorCode.X_2B000);
+        }
+
+        OrderedHashSet externalReferences = new OrderedHashSet();
+
+        getCascadingSchemaReferences(schema.getName(), externalReferences);
+        removeSchemaObjects(externalReferences);
+
+        Iterator tableIterator =
+            schema.schemaObjectIterator(SchemaObject.TABLE);
+
+        while (tableIterator.hasNext()) {
+            Table        table = ((Table) tableIterator.next());
+            Constraint[] list  = table.getFKConstraints();
+
+            for (int i = 0; i < list.length; i++) {
+                Constraint constraint = list[i];
+
+                if (constraint.getMain().getSchemaName() != schema.getName()) {
+                    constraint.getMain().removeConstraint(
+                        constraint.getMainName().name);
+                }
+            }
+
+            removeTable(session, table);
+        }
+
+        Iterator sequenceIterator =
+            schema.schemaObjectIterator(SchemaObject.SEQUENCE);
+
+        while (sequenceIterator.hasNext()) {
+            NumberSequence sequence =
+                ((NumberSequence) sequenceIterator.next());
+
+            database.getGranteeManager().removeDbObject(sequence.getName());
+        }
+
+        schema.clearStructures();
+        schemaMap.remove(name);
+
+        if (defaultSchemaHsqlName.name.equals(name)) {
+            HsqlName hsqlName = database.nameManager.newHsqlName(name, false,
+                SchemaObject.SCHEMA);
+
+            schema = new Schema(hsqlName,
+                                database.getGranteeManager().getDBARole());
+            defaultSchemaHsqlName = schema.getName();
+
+            schemaMap.put(schema.getName().name, schema);
+        }
+
+        // these are called last and in this particular order
+        database.getUserManager().removeSchemaReference(name);
+        database.getSessionManager().removeSchemaReference(schema);
+    }
+
+    public void renameSchema(HsqlName name, HsqlName newName) {
+
+        Schema schema = (Schema) schemaMap.get(name.name);
+        Schema exists = (Schema) schemaMap.get(newName.name);
+
+        if (schema == null) {
+            throw Error.error(ErrorCode.X_42501, name.name);
+        }
+
+        if (exists != null) {
+            throw Error.error(ErrorCode.X_42504, newName.name);
+        }
+
+        SqlInvariants.checkSchemaNameNotSystem(name.name);
+        SqlInvariants.checkSchemaNameNotSystem(newName.name);
+
+        int index = schemaMap.getIndex(name.name);
+
+        schema.getName().rename(newName);
+        schemaMap.set(index, newName.name, schema);
+    }
+
+    public void clearStructures() {
+
+        Iterator it = schemaMap.values().iterator();
+
+        while (it.hasNext()) {
+            Schema schema = (Schema) it.next();
+
+            schema.clearStructures();
+        }
+    }
+
+    public Iterator allSchemaNameIterator() {
+        return schemaMap.keySet().iterator();
+    }
+
+    public HsqlName getUserSchemaHsqlName(String name) {
+
+        Schema schema = (Schema) schemaMap.get(name);
+
+        if (schema == null) {
+            throw Error.error(ErrorCode.X_3F000, name);
+        }
+
+        if (schema.getName() == SqlInvariants.INFORMATION_SCHEMA_HSQLNAME) {
+            throw Error.error(ErrorCode.X_3F000, name);
+        }
+
+        return schema.getName();
+    }
+
+    public Grantee toSchemaOwner(String name) {
+
+        // Note that INFORMATION_SCHEMA and DEFINITION_SCHEMA aren't in the
+        // backing map.
+        // This may not be the most elegant solution, but it is the safest
+        // (without doing a code review for implications of adding
+        // them to the map).
+        if (SqlInvariants.INFORMATION_SCHEMA_HSQLNAME.name.equals(name)) {
+            return SqlInvariants.INFORMATION_SCHEMA_HSQLNAME.owner;
+        }
+
+        Schema schema = (Schema) schemaMap.get(name);
+
+        return schema == null ? null
+                              : schema.getOwner();
+    }
+
+    public HsqlName getDefaultSchemaHsqlName() {
+        return defaultSchemaHsqlName;
+    }
+
+    public void setDefaultSchemaHsqlName(HsqlName name) {
+        defaultSchemaHsqlName = name;
+    }
+
+    public boolean schemaExists(String name) {
+        return SqlInvariants.INFORMATION_SCHEMA.equals(name)
+               || schemaMap.containsKey(name);
+    }
+
+    public HsqlName findSchemaHsqlName(String name) {
+
+        Schema schema = ((Schema) schemaMap.get(name));
+
+        if (schema == null) {
+            return null;
+        }
+
+        return schema.getName();
+    }
+
+    /**
+     * If schemaName is null, return the default schema name, else return
+     * the HsqlName object for the schema. If schemaName does not exist,
+     * throw.
+     */
+    public HsqlName getSchemaHsqlName(String name) {
+
+        if (name == null) {
+            return defaultSchemaHsqlName;
+        }
+
+        if (SqlInvariants.INFORMATION_SCHEMA.equals(name)) {
+            return SqlInvariants.INFORMATION_SCHEMA_HSQLNAME;
+        }
+
+        Schema schema = ((Schema) schemaMap.get(name));
+
+        if (schema == null) {
+            throw Error.error(ErrorCode.X_3F000, name);
+        }
+
+        return schema.getName();
+    }
+
+    /**
+     * Same as above, but return string
+     */
+    public String getSchemaName(String name) {
+        return getSchemaHsqlName(name).name;
+    }
+
+    public Schema findSchema(String name) {
+        return ((Schema) schemaMap.get(name));
+    }
+
+    /**
+     * Iterator includes DEFINITION_SCHEMA
+     */
+    public Iterator fullSchemaNamesIterator() {
+        return schemaMap.keySet().iterator();
+    }
+
+    /**
+     * is a grantee the authorization of any schema
+     */
+    boolean isSchemaAuthorisation(Grantee grantee) {
+
+        Iterator schemas = allSchemaNameIterator();
+
+        while (schemas.hasNext()) {
+            String schemaName = (String) schemas.next();
+
+            if (grantee.equals(toSchemaOwner(schemaName))) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * drop all schemas with the given authorisation
+     */
+    public void dropSchemas(Session session, Grantee grantee,
+                            boolean cascade) {
+
+        HsqlArrayList list = getSchemas(grantee);
+        Iterator      it   = list.iterator();
+
+        while (it.hasNext()) {
+            Schema schema = (Schema) it.next();
+
+            dropSchema(session, schema.getName().name, cascade);
+        }
+    }
+
+    public HsqlArrayList getSchemas(Grantee grantee) {
+
+        HsqlArrayList list = new HsqlArrayList();
+        Iterator      it   = schemaMap.values().iterator();
+
+        while (it.hasNext()) {
+            Schema schema = (Schema) it.next();
+
+            if (grantee.equals(schema.getOwner())) {
+                list.add(schema);
+            }
+        }
+
+        return list;
+    }
+
+    public boolean hasSchemas(Grantee grantee) {
+
+        Iterator it = schemaMap.values().iterator();
+
+        while (it.hasNext()) {
+            Schema schema = (Schema) it.next();
+
+            if (grantee.equals(schema.getOwner())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     *  Returns an HsqlArrayList containing references to all non-system
+     *  tables and views. This includes all tables and views registered with
+     *  this Database.
+     */
+    public HsqlArrayList getAllTables() {
+
+        Iterator      schemas   = allSchemaNameIterator();
+        HsqlArrayList alltables = new HsqlArrayList();
+
+        while (schemas.hasNext()) {
+            String name = (String) schemas.next();
+
+            if (SqlInvariants.isLobsSchemaName(name)) {
+                continue;
+            }
+
+            if (SqlInvariants.isSystemSchemaName(name)) {
+                continue;
+            }
+
+            HashMappedList current = getTables(name);
+
+            alltables.addAll(current.values());
+        }
+
+        return alltables;
+    }
+
+    public HashMappedList getTables(String schema) {
+
+        Schema temp = (Schema) schemaMap.get(schema);
+
+        return temp.tableList;
+    }
+
+    public HsqlName[] getCatalogAndBaseTableNames() {
+
+        OrderedHashSet names  = new OrderedHashSet();
+        HsqlArrayList  tables = getAllTables();
+
+        for (int i = 0; i < tables.size(); i++) {
+            Table table = (Table) tables.get(i);
+
+            if (!table.isTemp()) {
+                names.add(table.getName());
+            }
+        }
+
+        names.add(database.getCatalogName());
+
+        HsqlName[] array = new HsqlName[names.size()];
+
+        names.toArray(array);
+
+        return array;
+    }
+
+    private SchemaObjectSet getSchemaObjectSet(Schema schema, int type) {
+
+        SchemaObjectSet set = null;
+
+        switch (type) {
+
+            case SchemaObject.SEQUENCE :
+                set = schema.sequenceLookup;
+                break;
+
+            case SchemaObject.TABLE :
+            case SchemaObject.VIEW :
+                set = schema.tableLookup;
+                break;
+
+            case SchemaObject.CHARSET :
+                set = schema.charsetLookup;
+                break;
+
+            case SchemaObject.COLLATION :
+                set = schema.collationLookup;
+                break;
+
+            case SchemaObject.PROCEDURE :
+                set = schema.procedureLookup;
+                break;
+
+            case SchemaObject.FUNCTION :
+                set = schema.functionLookup;
+                break;
+
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+                set = schema.typeLookup;
+                break;
+
+            case SchemaObject.INDEX :
+                set = schema.indexLookup;
+                break;
+
+            case SchemaObject.CONSTRAINT :
+                set = schema.constraintLookup;
+                break;
+
+            case SchemaObject.TRIGGER :
+                set = schema.triggerLookup;
+                break;
+
+            case SchemaObject.SPECIFIC_ROUTINE :
+                set = schema.specificRoutineLookup;
+        }
+
+        return set;
+    }
+
+    public void checkSchemaObjectNotExists(HsqlName name) {
+
+        Schema          schema = (Schema) schemaMap.get(name.schema.name);
+        SchemaObjectSet set    = getSchemaObjectSet(schema, name.type);
+
+        set.checkAdd(name);
+    }
+
+    /**
+     *  Returns the specified user-defined table or view visible within the
+     *  context of the specified Session, or any system table of the given
+     *  name. It excludes any temp tables created in other Sessions.
+     *  Throws if the table does not exist in the context.
+     */
+    public Table getTable(Session session, String name, String schema) {
+
+        Table t = null;
+
+        if (Tokens.T_MODULE.equals(schema)) {
+            t = findSessionTable(session, name, null);
+
+            if (t == null) {
+                throw Error.error(ErrorCode.X_42501, name);
+            }
+        }
+
+        if (schema == null) {
+            t = findSessionTable(session, name, null);
+        }
+
+        if (t == null) {
+            schema = session.getSchemaName(schema);
+            t      = findUserTable(session, name, schema);
+        }
+
+        if (t == null) {
+            if (SqlInvariants.INFORMATION_SCHEMA.equals(schema)
+                    && database.dbInfo != null) {
+                t = database.dbInfo.getSystemTable(session, name);
+            }
+        }
+
+        if (t == null) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        return t;
+    }
+
+    public Table getUserTable(Session session, HsqlName name) {
+        return getUserTable(session, name.name, name.schema.name);
+    }
+
+    /**
+     *  Returns the specified user-defined table or view visible within the
+     *  context of the specified Session. It excludes system tables and
+     *  any temp tables created in different Sessions.
+     *  Throws if the table does not exist in the context.
+     */
+    public Table getUserTable(Session session, String name, String schema) {
+
+        Table t = findUserTable(session, name, schema);
+
+        if (t == null) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        return t;
+    }
+
+    /**
+     *  Returns the specified user-defined table or view visible within the
+     *  context of the specified schema. It excludes system tables.
+     *  Returns null if the table does not exist in the context.
+     */
+    public Table findUserTable(Session session, String name,
+                               String schemaName) {
+
+        Schema schema = (Schema) schemaMap.get(schemaName);
+
+        if (schema == null) {
+            return null;
+        }
+
+        int i = schema.tableList.getIndex(name);
+
+        if (i == -1) {
+            return null;
+        }
+
+        return (Table) schema.tableList.get(i);
+    }
+
+    /**
+     *  Returns the specified session context table.
+     *  Returns null if the table does not exist in the context.
+     */
+    public Table findSessionTable(Session session, String name,
+                                  String schemaName) {
+        return session.findSessionTable(name);
+    }
+
+    /**
+     * Drops the specified user-defined view or table from this Database object.
+     *
+     * <p> The process of dropping a table or view includes:
+     * <OL>
+     * <LI> checking that the specified Session's currently connected User has
+     * the right to perform this operation and refusing to proceed if not by
+     * throwing.
+     * <LI> checking for referential constraints that conflict with this
+     * operation and refusing to proceed if they exist by throwing.</LI>
+     * <LI> removing the specified Table from this Database object.
+     * <LI> removing any exported foreign keys Constraint objects held by any
+     * tables referenced by the table to be dropped. This is especially
+     * important so that the dropped Table ceases to be referenced, eventually
+     * allowing its full garbage collection.
+     * <LI>
+     * </OL>
+     *
+     * <p>
+     *
+     * @param session the connected context in which to perform this operation
+     * @param table if true and if the Table to drop does not exist, fail
+     *   silently, else throw
+     * @param cascade true if the name argument refers to a View
+     */
+    public void dropTableOrView(Session session, Table table,
+                                boolean cascade) {
+
+// ft - concurrent
+        session.commit(false);
+
+        if (table.isView()) {
+            removeSchemaObject(table.getName(), cascade);
+        } else {
+            dropTable(session, table, cascade);
+        }
+    }
+
+    private void dropTable(Session session, Table table, boolean cascade) {
+
+        Schema schema    = (Schema) schemaMap.get(table.getSchemaName().name);
+        int    dropIndex = schema.tableList.getIndex(table.getName().name);
+        OrderedHashSet externalConstraints =
+            table.getDependentExternalConstraints();
+        OrderedHashSet externalReferences = new OrderedHashSet();
+
+        getCascadingReferencingObjectNames(table.getName(),
+                                           externalReferences);
+
+        if (!cascade) {
+            for (int i = 0; i < externalConstraints.size(); i++) {
+                Constraint c         = (Constraint) externalConstraints.get(i);
+                HsqlName   tablename = c.getRef().getName();
+                HsqlName   refname   = c.getRefName();
+
+                if (c.getConstraintType()
+                        == SchemaObject.ConstraintTypes.MAIN) {
+                    throw Error.error(ErrorCode.X_42533,
+                                      refname.schema.name + '.'
+                                      + tablename.name + '.' + refname.name);
+                }
+            }
+
+            if (!externalReferences.isEmpty()) {
+                int i = 0;
+
+                for (; i < externalReferences.size(); i++) {
+                    HsqlName name = (HsqlName) externalReferences.get(i);
+
+                    if (name.parent == table.getName()) {
+                        continue;
+                    }
+
+                    throw Error.error(ErrorCode.X_42502,
+                                      name.getSchemaQualifiedStatementName());
+                }
+            }
+        }
+
+        OrderedHashSet tableSet          = new OrderedHashSet();
+        OrderedHashSet constraintNameSet = new OrderedHashSet();
+        OrderedHashSet indexNameSet      = new OrderedHashSet();
+
+        // only columns with refs
+        OrderedHashSet childReferences = table.getReferences();
+        SchemaObject[] triggers        = table.getTriggers();
+
+        for (int i = 0; i < triggers.length; i++) {
+            childReferences.add(triggers[i].getName());
+        }
+
+        for (int i = 0; i < externalConstraints.size(); i++) {
+            Constraint c = (Constraint) externalConstraints.get(i);
+            Table      t = c.getMain();
+
+            if (t != table) {
+                tableSet.add(t);
+            }
+
+            t = c.getRef();
+
+            if (t != table) {
+                tableSet.add(t);
+            }
+
+            constraintNameSet.add(c.getMainName());
+            constraintNameSet.add(c.getRefName());
+            indexNameSet.add(c.getRefIndex().getName());
+        }
+
+        TableWorks tw = new TableWorks(session, table);
+
+        tableSet = tw.makeNewTables(tableSet, constraintNameSet, indexNameSet);
+
+        tw.setNewTablesInSchema(tableSet);
+        tw.updateConstraints(tableSet, constraintNameSet);
+        removeSchemaObjects(externalReferences);
+        removeSchemaObjects(childReferences);
+        removeReferencedObject(table.getName());
+        removeReferencingObject(table);
+        schema.tableList.remove(dropIndex);
+        schema.indexLookup.removeParent(table.getName());
+        schema.constraintLookup.removeParent(table.getName());
+        removeTable(session, table);
+        recompileDependentObjects(tableSet);
+    }
+
+    private void removeTable(Session session, Table table) {
+
+        database.getGranteeManager().removeDbObject(table.getName());
+        table.releaseTriggers();
+
+        if (table.hasLobColumn()) {
+            RowIterator it = table.rowIterator(session);
+
+            while (it.hasNext()) {
+                Row      row  = it.getNextRow();
+                Object[] data = row.getData();
+
+                session.sessionData.adjustLobUsageCount(table, data, -1);
+            }
+        }
+
+        database.persistentStoreCollection.releaseStore(table);
+    }
+
+    public void setTable(int index, Table table) {
+
+        Schema schema = (Schema) schemaMap.get(table.getSchemaName().name);
+
+        schema.tableList.set(index, table.getName().name, table);
+    }
+
+    /**
+     *  Returns index of a table or view in the HashMappedList that
+     *  contains the table objects for this Database.
+     *
+     * @param  table the Table object
+     * @return  the index of the specified table or view, or -1 if not found
+     */
+    public int getTableIndex(Table table) {
+
+        Schema schema = (Schema) schemaMap.get(table.getSchemaName().name);
+
+        if (schema == null) {
+            return -1;
+        }
+
+        HsqlName name = table.getName();
+
+        return schema.tableList.getIndex(name.name);
+    }
+
+    public void recompileDependentObjects(OrderedHashSet tableSet) {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0; i < tableSet.size(); i++) {
+            Table table = (Table) tableSet.get(i);
+
+            set.addAll(getReferencingObjectNames(table.getName()));
+        }
+
+        Session session = database.sessionManager.getSysSession();
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName name = (HsqlName) set.get(i);
+
+            switch (name.type) {
+
+                case SchemaObject.VIEW :
+                case SchemaObject.CONSTRAINT :
+                case SchemaObject.ASSERTION :
+                case SchemaObject.ROUTINE :
+                case SchemaObject.PROCEDURE :
+                case SchemaObject.FUNCTION :
+                case SchemaObject.SPECIFIC_ROUTINE :
+                    SchemaObject object = getSchemaObject(name);
+
+                    object.compile(session, null);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * After addition or removal of columns and indexes all views that
+     * reference the table should be recompiled.
+     */
+    public void recompileDependentObjects(Table table) {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        getCascadingReferencingObjectNames(table.getName(), set);
+
+        Session session = database.sessionManager.getSysSession();
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName name = (HsqlName) set.get(i);
+
+            switch (name.type) {
+
+                case SchemaObject.VIEW :
+                case SchemaObject.CONSTRAINT :
+                case SchemaObject.ASSERTION :
+                case SchemaObject.ROUTINE :
+                case SchemaObject.PROCEDURE :
+                case SchemaObject.FUNCTION :
+                case SchemaObject.SPECIFIC_ROUTINE :
+                    SchemaObject object = getSchemaObject(name);
+
+                    object.compile(session, null);
+                    break;
+            }
+        }
+
+        HsqlArrayList list = getAllTables();
+
+        for (int i = 0; i < list.size(); i++) {
+            Table t = (Table) list.get(i);
+
+            t.verifyConstraintsIntegrity();
+        }
+    }
+
+    public NumberSequence getSequence(String name, String schemaName,
+                                      boolean raise) {
+
+        Schema schema = (Schema) schemaMap.get(schemaName);
+
+        if (schema != null) {
+            NumberSequence object =
+                (NumberSequence) schema.sequenceList.get(name);
+
+            if (object != null) {
+                return object;
+            }
+        }
+
+        if (raise) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        return null;
+    }
+
+    public Type getUserDefinedType(String name, String schemaName,
+                                   boolean raise) {
+
+        Schema schema = (Schema) schemaMap.get(schemaName);
+
+        if (schema != null) {
+            SchemaObject object = schema.typeLookup.getObject(name);
+
+            if (object != null) {
+                return (Type) object;
+            }
+        }
+
+        if (raise) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        return null;
+    }
+
+    public Type getDomain(String name, String schemaName, boolean raise) {
+
+        Schema schema = (Schema) schemaMap.get(schemaName);
+
+        if (schema != null) {
+            SchemaObject object = schema.typeLookup.getObject(name);
+
+            if (object != null && ((Type) object).isDomainType()) {
+                return (Type) object;
+            }
+        }
+
+        if (raise) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        return null;
+    }
+
+    public Type getDistinctType(String name, String schemaName,
+                                boolean raise) {
+
+        Schema schema = (Schema) schemaMap.get(schemaName);
+
+        if (schema != null) {
+            SchemaObject object = schema.typeLookup.getObject(name);
+
+            if (object != null && ((Type) object).isDomainType()) {
+                return (Type) object;
+            }
+        }
+
+        if (raise) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        return null;
+    }
+
+    public SchemaObject getSchemaObject(String name, String schemaName,
+                                        int type) {
+
+        SchemaObject object = findSchemaObject(name, schemaName, type);
+
+        if (object == null) {
+            throw Error.error(SchemaObjectSet.getGetErrorCode(type), name);
+        }
+
+        return object;
+    }
+
+    public SchemaObject findSchemaObject(String name, String schemaName,
+                                         int type) {
+
+        Schema schema = (Schema) schemaMap.get(schemaName);
+
+        if (schema == null) {
+            return null;
+        }
+
+        SchemaObjectSet set = null;
+        HsqlName        objectName;
+        Table           table;
+
+        switch (type) {
+
+            case SchemaObject.SEQUENCE :
+                return schema.sequenceLookup.getObject(name);
+
+            case SchemaObject.TABLE :
+            case SchemaObject.VIEW :
+                return schema.tableLookup.getObject(name);
+
+            case SchemaObject.CHARSET :
+                if (name.equals("SQL_IDENTIFIER")) {
+                    return SqlInvariants.SQL_IDENTIFIER_CHARSET;
+                }
+
+                if (name.equals("SQL_TEXT")) {
+                    return SqlInvariants.SQL_TEXT;
+                }
+
+                if (name.equals("LATIN1")) {
+                    return SqlInvariants.LATIN1;
+                }
+
+                if (name.equals("ASCII_GRAPHIC")) {
+                    return SqlInvariants.ASCII_GRAPHIC;
+                }
+
+                return schema.charsetLookup.getObject(name);
+
+            case SchemaObject.COLLATION :
+                return schema.collationLookup.getObject(name);
+
+            case SchemaObject.PROCEDURE :
+                return schema.procedureLookup.getObject(name);
+
+            case SchemaObject.FUNCTION :
+                return schema.functionLookup.getObject(name);
+
+            case SchemaObject.ROUTINE : {
+                SchemaObject object = schema.procedureLookup.getObject(name);
+
+                if (object == null) {
+                    object = schema.functionLookup.getObject(name);
+                }
+
+                return object;
+            }
+            case SchemaObject.SPECIFIC_ROUTINE :
+                return schema.specificRoutineLookup.getObject(name);
+
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+                return schema.typeLookup.getObject(name);
+
+            case SchemaObject.INDEX :
+                set        = schema.indexLookup;
+                objectName = set.getName(name);
+
+                if (objectName == null) {
+                    return null;
+                }
+
+                table = (Table) schema.tableList.get(objectName.parent.name);
+
+                return table.getIndex(name);
+
+            case SchemaObject.CONSTRAINT :
+                set        = schema.constraintLookup;
+                objectName = set.getName(name);
+
+                if (objectName == null) {
+                    return null;
+                }
+
+                table = (Table) schema.tableList.get(objectName.parent.name);
+
+                if (table == null) {
+                    return null;
+                }
+
+                return table.getConstraint(name);
+
+            case SchemaObject.TRIGGER :
+                set        = schema.indexLookup;
+                objectName = set.getName(name);
+
+                if (objectName == null) {
+                    return null;
+                }
+
+                table = (Table) schema.tableList.get(objectName.parent.name);
+
+                return table.getTrigger(name);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SchemaManager");
+        }
+    }
+
+    // INDEX management
+
+    /**
+     * Returns the table that has an index with the given name and schema.
+     */
+    Table findUserTableForIndex(Session session, String name,
+                                String schemaName) {
+
+        Schema   schema    = (Schema) schemaMap.get(schemaName);
+        HsqlName indexName = schema.indexLookup.getName(name);
+
+        if (indexName == null) {
+            return null;
+        }
+
+        return findUserTable(session, indexName.parent.name, schemaName);
+    }
+
+    /**
+     * Drops the index with the specified name.
+     */
+    void dropIndex(Session session, HsqlName name) {
+
+        Table t = getTable(session, name.parent.name, name.parent.schema.name);
+        TableWorks tw = new TableWorks(session, t);
+
+        tw.dropIndex(name.name);
+    }
+
+    /**
+     * Drops the index with the specified name.
+     */
+    void dropConstraint(Session session, HsqlName name, boolean cascade) {
+
+        Table t = getTable(session, name.parent.name, name.parent.schema.name);
+        TableWorks tw = new TableWorks(session, t);
+
+        tw.dropConstraint(name.name, cascade);
+    }
+
+    void removeDependentObjects(HsqlName name) {
+
+        Schema schema = (Schema) schemaMap.get(name.schema.name);
+
+        schema.indexLookup.removeParent(name);
+        schema.constraintLookup.removeParent(name);
+        schema.triggerLookup.removeParent(name);
+    }
+
+    /**
+     *  Removes any foreign key Constraint objects (exported keys) held by any
+     *  tables referenced by the specified table. <p>
+     *
+     *  This method is called as the last step of a successful call to
+     *  dropTable() in order to ensure that the dropped Table ceases to be
+     *  referenced when enforcing referential integrity.
+     *
+     * @param  toDrop The table to which other tables may be holding keys.
+     *      This is a table that is in the process of being dropped.
+     */
+    void removeExportedKeys(Table toDrop) {
+
+        // toDrop.schema may be null because it is not registerd
+        Schema schema = (Schema) schemaMap.get(toDrop.getSchemaName().name);
+
+        for (int i = 0; i < schema.tableList.size(); i++) {
+            Table        table       = (Table) schema.tableList.get(i);
+            Constraint[] constraints = table.getConstraints();
+
+            for (int j = constraints.length - 1; j >= 0; j--) {
+                Table refTable = constraints[j].getRef();
+
+                if (toDrop == refTable) {
+                    table.removeConstraint(j);
+                }
+            }
+        }
+    }
+
+    public Iterator databaseObjectIterator(String schemaName, int type) {
+
+        Schema schema = (Schema) schemaMap.get(schemaName);
+
+        return schema.schemaObjectIterator(type);
+    }
+
+    public Iterator databaseObjectIterator(int type) {
+
+        Iterator it      = schemaMap.values().iterator();
+        Iterator objects = new WrapperIterator();
+
+        while (it.hasNext()) {
+            Schema temp = (Schema) it.next();
+
+            objects = new WrapperIterator(objects,
+                                          temp.schemaObjectIterator(type));
+        }
+
+        return objects;
+    }
+
+    // references
+    private void addReferences(SchemaObject object) {
+
+        OrderedHashSet set = object.getReferences();
+
+        if (set == null) {
+            return;
+        }
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName referenced = (HsqlName) set.get(i);
+            HsqlName name       = object.getName();
+
+            if (object instanceof Routine) {
+                name = ((Routine) object).getSpecificName();
+            }
+
+            referenceMap.put(referenced, name);
+        }
+    }
+
+    private void removeReferencedObject(HsqlName referenced) {
+        referenceMap.remove(referenced);
+    }
+
+    private void removeReferencingObject(SchemaObject object) {
+
+        OrderedHashSet set = object.getReferences();
+
+        if (set == null) {
+            return;
+        }
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName referenced = (HsqlName) set.get(i);
+            HsqlName name       = object.getName();
+
+            if (object instanceof Routine) {
+                name = ((Routine) object).getSpecificName();
+            }
+
+            referenceMap.remove(referenced, name);
+
+            if (name.parent != null) {
+                referenceMap.remove(referenced, name.parent);
+            }
+        }
+    }
+
+    OrderedHashSet getReferencingObjectNames(HsqlName object) {
+
+        OrderedHashSet set = new OrderedHashSet();
+        Iterator       it  = referenceMap.get(object);
+
+        while (it.hasNext()) {
+            HsqlName name = (HsqlName) it.next();
+
+            set.add(name);
+        }
+
+        return set;
+    }
+
+    public OrderedHashSet getReferencingObjectNames(HsqlName table,
+            HsqlName column) {
+
+        OrderedHashSet set = new OrderedHashSet();
+        Iterator       it  = referenceMap.get(table);
+
+        while (it.hasNext()) {
+            HsqlName       name       = (HsqlName) it.next();
+            SchemaObject   object     = getSchemaObject(name);
+            OrderedHashSet references = object.getReferences();
+
+            if (references.contains(column)) {
+                set.add(name);
+            }
+        }
+
+        return set;
+    }
+
+    private boolean isReferenced(HsqlName object) {
+        return referenceMap.containsKey(object);
+    }
+
+    //
+    public void getCascadingReferencingObjectNames(HsqlName object,
+            OrderedHashSet set) {
+
+        OrderedHashSet newSet = new OrderedHashSet();
+        Iterator       it     = referenceMap.get(object);
+
+        while (it.hasNext()) {
+            HsqlName name  = (HsqlName) it.next();
+            boolean  added = set.add(name);
+
+            if (added) {
+                newSet.add(name);
+            }
+        }
+
+        for (int i = 0; i < newSet.size(); i++) {
+            HsqlName name = (HsqlName) newSet.get(i);
+
+            getCascadingReferencingObjectNames(name, set);
+        }
+    }
+
+    //
+    private void getCascadingSchemaReferences(HsqlName schema,
+            OrderedHashSet set) {
+
+        Iterator mainIterator = referenceMap.keySet().iterator();
+
+        while (mainIterator.hasNext()) {
+            HsqlName name = (HsqlName) mainIterator.next();
+
+            if (name.schema != schema) {
+                continue;
+            }
+
+            getCascadingReferencingObjectNames(name, set);
+        }
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName name = (HsqlName) set.get(i);
+
+            if (name.schema == schema) {
+                set.remove(i);
+
+                i--;
+            }
+        }
+    }
+
+    //
+    public HsqlName getSchemaObjectName(HsqlName schemaName, String name,
+                                        int type, boolean raise) {
+
+        Schema          schema = (Schema) schemaMap.get(schemaName.name);
+        SchemaObjectSet set    = null;
+
+        if (schema == null) {
+            if (raise) {
+                throw Error.error(SchemaObjectSet.getGetErrorCode(type));
+            } else {
+                return null;
+            }
+        }
+
+        if (type == SchemaObject.ROUTINE) {
+            set = schema.functionLookup;
+
+            SchemaObject object = schema.functionLookup.getObject(name);
+
+            if (object == null) {
+                set    = schema.procedureLookup;
+                object = schema.procedureLookup.getObject(name);
+            }
+        } else {
+            set = getSchemaObjectSet(schema, type);
+        }
+
+        if (raise) {
+            set.checkExists(name);
+        }
+
+        return set.getName(name);
+    }
+
+    public SchemaObject getSchemaObject(HsqlName name) {
+
+        Schema schema = (Schema) schemaMap.get(name.schema.name);
+
+        if (schema == null) {
+            return null;
+        }
+
+        switch (name.type) {
+
+            case SchemaObject.SEQUENCE :
+                return (SchemaObject) schema.sequenceList.get(name.name);
+
+            case SchemaObject.TABLE :
+            case SchemaObject.VIEW :
+                return (SchemaObject) schema.tableList.get(name.name);
+
+            case SchemaObject.CHARSET :
+                return schema.charsetLookup.getObject(name.name);
+
+            case SchemaObject.COLLATION :
+                return schema.collationLookup.getObject(name.name);
+
+            case SchemaObject.PROCEDURE :
+                return schema.procedureLookup.getObject(name.name);
+
+            case SchemaObject.FUNCTION :
+                return schema.functionLookup.getObject(name.name);
+
+            case RoutineSchema.SPECIFIC_ROUTINE :
+                return schema.specificRoutineLookup.getObject(name.name);
+
+            case RoutineSchema.ROUTINE :
+                SchemaObject object =
+                    schema.functionLookup.getObject(name.name);
+
+                if (object == null) {
+                    object = schema.procedureLookup.getObject(name.name);
+                }
+
+                return object;
+
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+                return schema.typeLookup.getObject(name.name);
+
+            case SchemaObject.TRIGGER : {
+                name = schema.triggerLookup.getName(name.name);
+
+                if (name == null) {
+                    return null;
+                }
+
+                HsqlName tableName = name.parent;
+                Table    table = (Table) schema.tableList.get(tableName.name);
+
+                return table.getTrigger(name.name);
+            }
+            case SchemaObject.CONSTRAINT : {
+                name = schema.constraintLookup.getName(name.name);
+
+                if (name == null) {
+                    return null;
+                }
+
+                HsqlName tableName = name.parent;
+                Table    table = (Table) schema.tableList.get(tableName.name);
+
+                return table.getConstraint(name.name);
+            }
+            case SchemaObject.ASSERTION :
+                return null;
+
+            case SchemaObject.INDEX :
+                name = schema.indexLookup.getName(name.name);
+
+                if (name == null) {
+                    return null;
+                }
+
+                HsqlName tableName = name.parent;
+                Table    table = (Table) schema.tableList.get(tableName.name);
+
+                return table.getIndex(name.name);
+        }
+
+        return null;
+    }
+
+    public void checkColumnIsReferenced(HsqlName tableName, HsqlName name) {
+
+        OrderedHashSet set = getReferencingObjectNames(tableName, name);
+
+        if (!set.isEmpty()) {
+            HsqlName objectName = (HsqlName) set.get(0);
+
+            throw Error.error(ErrorCode.X_42502,
+                              objectName.getSchemaQualifiedStatementName());
+        }
+    }
+
+    public void checkObjectIsReferenced(HsqlName name) {
+
+        OrderedHashSet set     = getReferencingObjectNames(name);
+        HsqlName       refName = null;
+
+        for (int i = 0; i < set.size(); i++) {
+            refName = (HsqlName) set.get(i);
+
+            // except columns of same table
+            if (refName.parent != name) {
+                break;
+            }
+
+            refName = null;
+        }
+
+        if (refName == null) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42502,
+                          refName.getSchemaQualifiedStatementName());
+    }
+
+    public void checkSchemaNameCanChange(HsqlName name) {
+
+        Iterator it      = referenceMap.values().iterator();
+        HsqlName refName = null;
+
+        mainLoop:
+        while (it.hasNext()) {
+            refName = (HsqlName) it.next();
+
+            switch (refName.type) {
+
+                case SchemaObject.VIEW :
+                case SchemaObject.ROUTINE :
+                case SchemaObject.FUNCTION :
+                case SchemaObject.PROCEDURE :
+                case SchemaObject.TRIGGER :
+                case SchemaObject.SPECIFIC_ROUTINE :
+                    if (refName.schema == name) {
+                        break mainLoop;
+                    }
+                    break;
+
+                default :
+                    break;
+            }
+
+            refName = null;
+        }
+
+        if (refName == null) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42502,
+                          refName.getSchemaQualifiedStatementName());
+    }
+
+    public void addSchemaObject(SchemaObject object) {
+
+        HsqlName        name   = object.getName();
+        Schema          schema = (Schema) schemaMap.get(name.schema.name);
+        SchemaObjectSet set    = getSchemaObjectSet(schema, name.type);
+
+        switch (name.type) {
+
+            case SchemaObject.PROCEDURE :
+            case SchemaObject.FUNCTION : {
+                RoutineSchema routine =
+                    (RoutineSchema) set.getObject(name.name);
+
+                if (routine == null) {
+                    routine = new RoutineSchema(name.type, name);
+
+                    routine.addSpecificRoutine(database, (Routine) object);
+                    set.checkAdd(name);
+
+                    SchemaObjectSet specificSet = getSchemaObjectSet(schema,
+                        SchemaObject.SPECIFIC_ROUTINE);
+
+                    specificSet.checkAdd(((Routine) object).getSpecificName());
+                    set.add(routine);
+                    specificSet.add(object);
+                } else {
+                    SchemaObjectSet specificSet = getSchemaObjectSet(schema,
+                        SchemaObject.SPECIFIC_ROUTINE);
+                    HsqlName specificName =
+                        ((Routine) object).getSpecificName();
+
+                    if (specificName != null) {
+                        specificSet.checkAdd(specificName);
+                    }
+
+                    routine.addSpecificRoutine(database, (Routine) object);
+                    specificSet.add(object);
+                }
+
+                addReferences(object);
+
+                return;
+            }
+            case SchemaObject.TABLE : {
+                OrderedHashSet refs = object.getReferences();
+
+                for (int i = 0; i < refs.size(); i++) {
+                    HsqlName ref = (HsqlName) refs.get(i);
+
+                    if (ref.type == SchemaObject.COLUMN) {
+                        int index = ((Table) object).findColumn(ref.name);
+                        ColumnSchema column =
+                            ((Table) object).getColumn(index);
+
+                        addSchemaObject(column);
+                    }
+                }
+
+                break;
+            }
+            case SchemaObject.COLUMN : {
+                if (object.getReferences().isEmpty()) {
+                    return;
+                }
+
+                break;
+            }
+        }
+
+        if (set != null) {
+            set.add(object);
+        }
+
+        addReferences(object);
+    }
+
+    public void removeSchemaObject(HsqlName name, boolean cascade) {
+
+        OrderedHashSet objectSet = new OrderedHashSet();
+
+        switch (name.type) {
+
+            case SchemaObject.ROUTINE :
+            case SchemaObject.PROCEDURE :
+            case SchemaObject.FUNCTION : {
+                RoutineSchema routine = (RoutineSchema) getSchemaObject(name);
+
+                if (routine != null) {
+                    Routine[] specifics = routine.getSpecificRoutines();
+
+                    for (int i = 0; i < specifics.length; i++) {
+                        getCascadingReferencingObjectNames(
+                            specifics[i].getSpecificName(), objectSet);
+                    }
+                }
+            }
+            break;
+
+            case SchemaObject.SEQUENCE :
+            case SchemaObject.TABLE :
+            case SchemaObject.VIEW :
+            case SchemaObject.TYPE :
+            case SchemaObject.CHARSET :
+            case SchemaObject.COLLATION :
+            case SchemaObject.SPECIFIC_ROUTINE :
+                getCascadingReferencingObjectNames(name, objectSet);
+                break;
+
+            case SchemaObject.DOMAIN :
+                OrderedHashSet set = getReferencingObjectNames(name);
+                Iterator       it  = set.iterator();
+
+                while (it.hasNext()) {
+                    HsqlName ref = (HsqlName) it.next();
+
+                    if (ref.type == SchemaObject.COLUMN) {
+                        it.remove();
+                    }
+                }
+
+                if (!set.isEmpty()) {
+                    HsqlName objectName = (HsqlName) set.get(0);
+
+                    throw Error.error(
+                        ErrorCode.X_42502,
+                        objectName.getSchemaQualifiedStatementName());
+                }
+                break;
+        }
+
+        if (objectSet.isEmpty()) {
+            removeSchemaObject(name);
+
+            return;
+        }
+
+        if (!cascade) {
+            HsqlName objectName = (HsqlName) objectSet.get(0);
+
+            throw Error.error(ErrorCode.X_42502,
+                              objectName.getSchemaQualifiedStatementName());
+        }
+
+        objectSet.add(name);
+        removeSchemaObjects(objectSet);
+    }
+
+    public void removeSchemaObjects(OrderedHashSet set) {
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName name = (HsqlName) set.get(i);
+
+            removeSchemaObject(name);
+        }
+    }
+
+    public void removeSchemaObject(HsqlName name) {
+
+        Schema          schema = (Schema) schemaMap.get(name.schema.name);
+        SchemaObject    object = null;
+        SchemaObjectSet set    = null;
+
+        switch (name.type) {
+
+            case SchemaObject.SEQUENCE :
+                set    = schema.sequenceLookup;
+                object = set.getObject(name.name);
+                break;
+
+            case SchemaObject.TABLE :
+            case SchemaObject.VIEW : {
+                set    = schema.tableLookup;
+                object = set.getObject(name.name);
+
+                break;
+            }
+            case SchemaObject.COLUMN : {
+                Table table = (Table) getSchemaObject(name.parent);
+
+                if (table != null) {
+                    object = table.getColumn(table.getColumnIndex(name.name));
+                }
+
+                break;
+            }
+            case SchemaObject.CHARSET :
+                set    = schema.charsetLookup;
+                object = set.getObject(name.name);
+                break;
+
+            case SchemaObject.COLLATION :
+                set    = schema.collationLookup;
+                object = set.getObject(name.name);
+                break;
+
+            case SchemaObject.PROCEDURE : {
+                set = schema.procedureLookup;
+
+                RoutineSchema routine =
+                    (RoutineSchema) set.getObject(name.name);
+
+                object = routine;
+
+                Routine[] specifics = routine.getSpecificRoutines();
+
+                for (int i = 0; i < specifics.length; i++) {
+                    removeSchemaObject(specifics[i].getSpecificName());
+                }
+
+                break;
+            }
+            case SchemaObject.FUNCTION : {
+                set = schema.functionLookup;
+
+                RoutineSchema routine =
+                    (RoutineSchema) set.getObject(name.name);
+
+                object = routine;
+
+                Routine[] specifics = routine.getSpecificRoutines();
+
+                for (int i = 0; i < specifics.length; i++) {
+                    removeSchemaObject(specifics[i].getSpecificName());
+                }
+
+                break;
+            }
+            case SchemaObject.SPECIFIC_ROUTINE : {
+                set = schema.specificRoutineLookup;
+
+                Routine routine = (Routine) set.getObject(name.name);
+
+                object = routine;
+
+                routine.routineSchema.removeSpecificRoutine(routine);
+
+                if (routine.routineSchema.getSpecificRoutines().length == 0) {
+                    removeSchemaObject(routine.getName());
+                }
+
+                break;
+            }
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+                set    = schema.typeLookup;
+                object = set.getObject(name.name);
+                break;
+
+            case SchemaObject.INDEX :
+                set = schema.indexLookup;
+                break;
+
+            case SchemaObject.CONSTRAINT : {
+                set = schema.constraintLookup;
+
+                if (name.parent.type == SchemaObject.TABLE) {
+                    Table table =
+                        (Table) schema.tableList.get(name.parent.name);
+
+                    object = table.getConstraint(name.name);
+
+                    table.removeConstraint(name.name);
+                } else if (name.parent.type == SchemaObject.DOMAIN) {
+                    Type type =
+                        (Type) schema.typeLookup.getObject(name.parent.name);
+
+                    object = type.userTypeModifier.getConstraint(name.name);
+
+                    type.userTypeModifier.removeConstraint(name.name);
+                }
+
+                break;
+            }
+            case SchemaObject.TRIGGER : {
+                set = schema.triggerLookup;
+
+                Table table = (Table) schema.tableList.get(name.parent.name);
+
+                object = table.getTrigger(name.name);
+
+                if (object != null) {
+                    table.removeTrigger((TriggerDef) object);
+                }
+
+                break;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SchemaManager");
+        }
+
+        if (object != null) {
+            database.getGranteeManager().removeDbObject(name);
+            removeReferencingObject(object);
+        }
+
+        if (set != null) {
+            set.remove(name.name);
+        }
+
+        removeReferencedObject(name);
+    }
+
+    public void renameSchemaObject(HsqlName name, HsqlName newName) {
+
+        if (name.schema != newName.schema) {
+            throw Error.error(ErrorCode.X_42505, newName.schema.name);
+        }
+
+        checkObjectIsReferenced(name);
+
+        Schema          schema = (Schema) schemaMap.get(name.schema.name);
+        SchemaObjectSet set    = getSchemaObjectSet(schema, name.type);
+
+        set.rename(name, newName);
+    }
+
+    public String[] getSQLArray() {
+
+        OrderedHashSet resolved   = new OrderedHashSet();
+        OrderedHashSet unresolved = new OrderedHashSet();
+        HsqlArrayList  list       = new HsqlArrayList();
+        Iterator       schemas    = schemaMap.values().iterator();
+
+        schemas = schemaMap.values().iterator();
+
+        while (schemas.hasNext()) {
+            Schema schema = (Schema) schemas.next();
+
+            if (SqlInvariants.isSystemSchemaName(schema.getName().name)) {
+                continue;
+            }
+
+            if (SqlInvariants.isLobsSchemaName(schema.getName().name)) {
+                continue;
+            }
+
+            list.add(schema.getSQL());
+            schema.addSimpleObjects(unresolved);
+        }
+
+        while (true) {
+            Iterator it = unresolved.iterator();
+
+            if (!it.hasNext()) {
+                break;
+            }
+
+            OrderedHashSet newResolved = new OrderedHashSet();
+
+            SchemaObjectSet.addAllSQL(resolved, unresolved, list, it,
+                                      newResolved);
+            unresolved.removeAll(newResolved);
+
+            if (newResolved.size() == 0) {
+                break;
+            }
+        }
+
+        schemas = schemaMap.values().iterator();
+
+        while (schemas.hasNext()) {
+            Schema schema = (Schema) schemas.next();
+
+            if (SqlInvariants.isLobsSchemaName(schema.getName().name)) {
+                continue;
+            }
+
+            if (SqlInvariants.isSystemSchemaName(schema.getName().name)) {
+                continue;
+            }
+
+            list.addAll(schema.getSQLArray(resolved, unresolved));
+        }
+
+        while (true) {
+            Iterator it = unresolved.iterator();
+
+            if (!it.hasNext()) {
+                break;
+            }
+
+            OrderedHashSet newResolved = new OrderedHashSet();
+
+            SchemaObjectSet.addAllSQL(resolved, unresolved, list, it,
+                                      newResolved);
+            unresolved.removeAll(newResolved);
+
+            if (newResolved.size() == 0) {
+                break;
+            }
+        }
+
+        schemas = schemaMap.values().iterator();
+
+        while (schemas.hasNext()) {
+            Schema schema = (Schema) schemas.next();
+
+            if (SqlInvariants.isLobsSchemaName(schema.getName().name)) {
+                continue;
+            }
+
+            if (SqlInvariants.isSystemSchemaName(schema.getName().name)) {
+                continue;
+            }
+
+            String[] t = schema.getTriggerSQL();
+
+            if (t.length > 0) {
+                list.add(Schema.getSetSchemaSQL(schema.getName()));
+                list.addAll(t);
+            }
+
+            list.addAll(schema.getSequenceRestartSQL());
+        }
+
+        schemas = schemaMap.values().iterator();
+
+        while (schemas.hasNext()) {
+            Schema schema = (Schema) schemas.next();
+
+            list.addAll(schema.getSequenceRestartSQL());
+        }
+
+        if (defaultSchemaHsqlName != null) {
+            StringBuffer sb = new StringBuffer();
+
+            sb.append(Tokens.T_SET).append(' ').append(Tokens.T_DATABASE);
+            sb.append(' ').append(Tokens.T_DEFAULT).append(' ');
+            sb.append(Tokens.T_INITIAL).append(' ').append(Tokens.T_SCHEMA);
+            sb.append(' ').append(defaultSchemaHsqlName.statementName);
+            list.add(sb.toString());
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public String[] getTablePropsSQL(boolean withHeader) {
+
+        HsqlArrayList tableList = getAllTables();
+        HsqlArrayList list      = new HsqlArrayList();
+
+        for (int i = 0; i < tableList.size(); i++) {
+            Table t = (Table) tableList.get(i);
+
+            if (t.isText()) {
+                String[] ddl = t.getSQLForTextSource(withHeader);
+
+                list.addAll(ddl);
+            } else {
+                String ddl = t.getSQLForReadOnly();
+
+                if (ddl != null) {
+                    list.add(ddl);
+                }
+            }
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public String[] getIndexRootsSQL() {
+
+        Session       sysSession = database.sessionManager.getSysSession();
+        int[][]       rootsArray = getIndexRoots(sysSession);
+        HsqlArrayList tableList  = getAllTables();
+        HsqlArrayList list       = new HsqlArrayList();
+
+        for (int i = 0; i < rootsArray.length; i++) {
+            Table t = (Table) tableList.get(i);
+
+            if (rootsArray[i] != null && rootsArray[i].length > 0
+                    && rootsArray[i][0] != -1) {
+                String ddl =
+                    ((Table) tableList.get(i)).getIndexRootsSQL(rootsArray[i]);
+
+                list.add(ddl);
+            }
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public String[] getCommentsArray() {
+
+        HsqlArrayList tableList = getAllTables();
+        HsqlArrayList list      = new HsqlArrayList();
+        StringBuffer  sb        = new StringBuffer();
+
+        for (int i = 0; i < tableList.size(); i++) {
+            Table table = (Table) tableList.get(i);
+
+            if (table.getTableType() == Table.SYSTEM_TABLE) {
+                continue;
+            }
+
+            int colCount = table.getColumnCount();
+
+            for (int j = 0; j < colCount; j++) {
+                ColumnSchema column = table.getColumn(j);
+
+                if (column.getName().comment == null) {
+                    continue;
+                }
+
+                sb.setLength(0);
+                sb.append(Tokens.T_COMMENT).append(' ').append(Tokens.T_ON);
+                sb.append(' ').append(Tokens.T_COLUMN).append(' ');
+                sb.append(table.getName().getSchemaQualifiedStatementName());
+                sb.append('.').append(column.getName().statementName);
+                sb.append(' ').append(Tokens.T_IS).append(' ');
+                sb.append(
+                    StringConverter.toQuotedString(
+                        column.getName().comment, '\'', true));
+                list.add(sb.toString());
+            }
+
+            if (table.getName().comment == null) {
+                continue;
+            }
+
+            sb.setLength(0);
+            sb.append(Tokens.T_COMMENT).append(' ').append(Tokens.T_ON);
+            sb.append(' ').append(Tokens.T_TABLE).append(' ');
+            sb.append(table.getName().getSchemaQualifiedStatementName());
+            sb.append(' ').append(Tokens.T_IS).append(' ');
+            sb.append(StringConverter.toQuotedString(table.getName().comment,
+                    '\'', true));
+            list.add(sb.toString());
+        }
+
+        Iterator it = databaseObjectIterator(SchemaObject.ROUTINE);
+
+        while (it.hasNext()) {
+            SchemaObject object = (SchemaObject) it.next();
+
+            if (object.getName().comment == null) {
+                continue;
+            }
+
+            sb.setLength(0);
+            sb.append(Tokens.T_COMMENT).append(' ').append(Tokens.T_ON);
+            sb.append(' ').append(Tokens.T_ROUTINE).append(' ');
+            sb.append(object.getName().getSchemaQualifiedStatementName());
+            sb.append(' ').append(Tokens.T_IS).append(' ');
+            sb.append(StringConverter.toQuotedString(object.getName().comment,
+                    '\'', true));
+            list.add(sb.toString());
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    int[][] tempIndexRoots;
+
+    public void setTempIndexRoots(int[][] roots) {
+        tempIndexRoots = roots;
+    }
+
+    public int[][] getIndexRoots(Session session) {
+
+        if (tempIndexRoots != null) {
+            int[][] roots = tempIndexRoots;
+
+            tempIndexRoots = null;
+
+            return roots;
+        }
+
+        HsqlArrayList allTables = getAllTables();
+        HsqlArrayList list      = new HsqlArrayList();
+
+        for (int i = 0, size = allTables.size(); i < size; i++) {
+            Table t = (Table) allTables.get(i);
+
+            if (t.getTableType() == TableBase.CACHED_TABLE) {
+                int[] roots = t.getIndexRootsArray();
+
+                list.add(roots);
+            } else {
+                list.add(null);
+            }
+        }
+
+        int[][] array = new int[list.size()][];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    /**
+     * called after the completion of defrag
+     */
+    public void setIndexRoots(int[][] roots) {
+
+        HsqlArrayList allTables = database.schemaManager.getAllTables();
+
+        for (int i = 0, size = allTables.size(); i < size; i++) {
+            Table t = (Table) allTables.get(i);
+
+            if (t.getTableType() == TableBase.CACHED_TABLE) {
+                int[] rootsArray = roots[i];
+
+                if (roots != null) {
+                    t.setIndexRoots(rootsArray);
+                }
+            }
+        }
+    }
+
+    public void setDefaultTableType(int type) {
+        defaultTableType = type;
+    }
+
+    public int getDefaultTableType() {
+        return defaultTableType;
+    }
+}
diff --git a/src/org/hsqldb/SchemaObject.java b/src/org/hsqldb/SchemaObject.java
new file mode 100644
index 0000000..8513196
--- /dev/null
+++ b/src/org/hsqldb/SchemaObject.java
@@ -0,0 +1,154 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.lib.OrderedHashSet;
+
+/**
+ * SQL schema object interface
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface SchemaObject {
+
+    int CATALOG          = 1;
+    int SCHEMA           = 2;
+    int TABLE            = 3;
+    int VIEW             = 4;
+    int CONSTRAINT       = 5;
+    int ASSERTION        = 6;
+    int SEQUENCE         = 7;
+    int TRIGGER          = 8;
+    int COLUMN           = 9;
+    int TRANSITION       = 10;
+    int GRANTEE          = 11;
+    int TYPE             = 12;
+    int DOMAIN           = 13;
+    int CHARSET          = 14;
+    int COLLATION        = 15;
+    int FUNCTION         = 16;
+    int PROCEDURE        = 17;
+    int ROUTINE          = 18;
+    int CURSOR           = 19;
+    int INDEX            = 20;
+    int LABEL            = 21;
+    int VARIABLE         = 22;
+    int PARAMETER        = 23;
+    int SPECIFIC_ROUTINE = 24;
+    int WRAPPER          = 25;
+    int SERVER           = 26;
+    int SUBQUERY         = 27;
+
+    //
+    SchemaObject[] emptyArray = new SchemaObject[]{};
+
+    int getType();
+
+    HsqlName getName();
+
+    HsqlName getSchemaName();
+
+    HsqlName getCatalogName();
+
+    Grantee getOwner();
+
+    OrderedHashSet getReferences();
+
+    OrderedHashSet getComponents();
+
+    void compile(Session session, SchemaObject parentObject);
+
+    String getSQL();
+
+    long getChangeTimestamp();
+
+    interface ConstraintTypes {
+
+        int FOREIGN_KEY = 0;
+        int MAIN        = 1;
+        int UNIQUE      = 2;
+        int CHECK       = 3;
+        int PRIMARY_KEY = 4;
+        int TEMP        = 5;
+    }
+
+    /*
+     SQL CLI codes
+
+     Referential Constraint 0 CASCADE
+     Referential Constraint 1 RESTRICT
+     Referential Constraint 2 SET NULL
+     Referential Constraint 3 NO ACTION
+     Referential Constraint 4 SET DEFAULT
+     */
+    interface ReferentialAction {
+
+        int CASCADE     = 0;
+        int RESTRICT    = 1;
+        int SET_NULL    = 2;
+        int NO_ACTION   = 3;
+        int SET_DEFAULT = 4;
+    }
+
+    interface Deferable {
+
+        int NOT_DEFERRABLE = 0;
+        int INIT_DEFERRED  = 1;
+        int INIT_IMMEDIATE = 2;
+    }
+
+    interface ViewCheckModes {
+
+        int CHECK_NONE    = 0;
+        int CHECK_LOCAL   = 1;
+        int CHECK_CASCADE = 2;
+    }
+
+    interface ParameterModes {
+
+        byte PARAM_UNKNOWN = 0;    // java.sql.ParameterMetaData.parameterModeUnknown
+        byte PARAM_IN    = 1;      // java.sql.ParameterMetaData.parameterModeIn
+        byte PARAM_OUT   = 4;      // java.sql.ParameterMetaData.parameterModeInOut
+        byte PARAM_INOUT = 2;      // java.sql.ParameterMetaData.parameterModeOut
+    }
+
+    interface Nullability {
+
+        byte NO_NULLS         = 0;    // java.sql.ResultSetMetaData.columnNoNulls
+        byte NULLABLE         = 1;    // java.sql.ResultSetMetaData.columnNullable
+        byte NULLABLE_UNKNOWN = 2;    // java.sql.ResultSetMetaData.columnNullableUnknown
+    }
+}
diff --git a/src/org/hsqldb/SchemaObjectSet.java b/src/org/hsqldb/SchemaObjectSet.java
new file mode 100644
index 0000000..8758af6
--- /dev/null
+++ b/src/org/hsqldb/SchemaObjectSet.java
@@ -0,0 +1,546 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Collection of SQL schema objects of a specific type in a schema
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class SchemaObjectSet {
+
+    HashMap       map;
+    int           type;
+
+    SchemaObjectSet(int type) {
+
+        this.type = type;
+
+        switch (type) {
+
+            case SchemaObject.VIEW :
+            case SchemaObject.TABLE :
+            case SchemaObject.SEQUENCE :
+            case SchemaObject.CHARSET :
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+            case SchemaObject.COLLATION :
+            case SchemaObject.PROCEDURE :
+            case SchemaObject.FUNCTION :
+            case SchemaObject.SPECIFIC_ROUTINE :
+            case SchemaObject.ASSERTION :
+            case SchemaObject.TRIGGER :
+                map = new HashMappedList();
+                break;
+
+            case SchemaObject.COLUMN :
+            case SchemaObject.CONSTRAINT :
+            case SchemaObject.INDEX :
+                map = new HashMap();
+                break;
+        }
+    }
+
+    HsqlName getName(String name) {
+
+        switch (type) {
+
+            case SchemaObject.VIEW :
+            case SchemaObject.TABLE :
+            case SchemaObject.SEQUENCE :
+            case SchemaObject.CHARSET :
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+            case SchemaObject.COLLATION :
+            case SchemaObject.PROCEDURE :
+            case SchemaObject.SPECIFIC_ROUTINE :
+            case SchemaObject.FUNCTION :
+            case SchemaObject.ASSERTION :
+            case SchemaObject.TRIGGER :
+                SchemaObject object = ((SchemaObject) map.get(name));
+
+                return object == null ? null
+                                      : object.getName();
+
+            case SchemaObject.COLUMN :
+            case SchemaObject.CONSTRAINT :
+            case SchemaObject.INDEX : {
+                return (HsqlName) map.get(name);
+            }
+            default :
+                return (HsqlName) map.get(name);
+        }
+    }
+
+    public SchemaObject getObject(String name) {
+
+        switch (type) {
+
+            case SchemaObject.VIEW :
+            case SchemaObject.TABLE :
+            case SchemaObject.SEQUENCE :
+            case SchemaObject.CHARSET :
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+            case SchemaObject.COLLATION :
+            case SchemaObject.PROCEDURE :
+            case SchemaObject.SPECIFIC_ROUTINE :
+            case SchemaObject.FUNCTION :
+            case SchemaObject.ASSERTION :
+            case SchemaObject.TRIGGER :
+            case SchemaObject.COLUMN :
+                return (SchemaObject) map.get(name);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SchemaObjectSet");
+        }
+    }
+
+    public boolean contains(String name) {
+        return map.containsKey(name);
+    }
+
+    void checkAdd(HsqlName name) {
+
+        if (map.containsKey(name.name)) {
+            int code = getAddErrorCode(name.type);
+
+            throw Error.error(code, name.name);
+        }
+    }
+
+    boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    void checkExists(String name) {
+
+        if (!map.containsKey(name)) {
+            int code = getGetErrorCode(type);
+
+            throw Error.error(code, name);
+        }
+    }
+
+    public void add(SchemaObject object) {
+
+        HsqlName name = object.getName();
+
+        if (type == SchemaObject.SPECIFIC_ROUTINE) {
+            name = ((Routine) object).getSpecificName();
+        }
+
+        if (map.containsKey(name.name)) {
+            int code = getAddErrorCode(name.type);
+
+            throw Error.error(code, name.name);
+        }
+
+        Object value = object;
+
+        switch (name.type) {
+
+            case SchemaObject.CONSTRAINT :
+            case SchemaObject.INDEX :
+                value = name;
+        }
+
+        map.put(name.name, value);
+    }
+
+    void remove(String name) {
+        map.remove(name);
+    }
+
+    void removeParent(HsqlName parent) {
+
+        Iterator it = map.values().iterator();
+
+        while (it.hasNext()) {
+            if (type == SchemaObject.TRIGGER
+                    || type == SchemaObject.SPECIFIC_ROUTINE) {
+                SchemaObject object = (SchemaObject) it.next();
+
+                if (object.getName().parent == parent) {
+                    it.remove();
+                }
+            } else {
+                HsqlName name = (HsqlName) it.next();
+
+                if (name.parent == parent) {
+                    it.remove();
+                }
+            }
+        }
+    }
+
+    void rename(HsqlName name, HsqlName newName) {
+
+        if (map.containsKey(newName.name)) {
+            int code = getAddErrorCode(name.type);
+
+            throw Error.error(code, newName.name);
+        }
+
+        switch (newName.type) {
+
+            case SchemaObject.VIEW :
+            case SchemaObject.TABLE :
+            case SchemaObject.SEQUENCE :
+            case SchemaObject.CHARSET :
+            case SchemaObject.COLLATION :
+            case SchemaObject.PROCEDURE :
+            case SchemaObject.FUNCTION :
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+            case SchemaObject.ASSERTION :
+            case SchemaObject.TRIGGER : {
+                int i = ((HashMappedList) map).getIndex(name.name);
+
+                if (i == -1) {
+                    int code = getGetErrorCode(name.type);
+
+                    throw Error.error(code, name.name);
+                }
+
+                SchemaObject object =
+                    (SchemaObject) ((HashMappedList) map).get(i);
+
+                object.getName().rename(newName);
+                ((HashMappedList) map).setKey(i, name.name);
+
+                break;
+            }
+            case SchemaObject.COLUMN :
+            case SchemaObject.CONSTRAINT :
+            case SchemaObject.INDEX : {
+                map.remove(name.name);
+                name.rename(newName);
+                map.put(name.name, name);
+
+                break;
+            }
+        }
+    }
+
+    static int getAddErrorCode(int type) {
+
+        int code;
+
+        switch (type) {
+
+            case SchemaObject.VIEW :
+            case SchemaObject.TABLE :
+            case SchemaObject.COLUMN :
+            case SchemaObject.SEQUENCE :
+            case SchemaObject.CHARSET :
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+            case SchemaObject.COLLATION :
+            case SchemaObject.PROCEDURE :
+            case SchemaObject.FUNCTION :
+            case SchemaObject.SPECIFIC_ROUTINE :
+            case SchemaObject.CONSTRAINT :
+            case SchemaObject.ASSERTION :
+            case SchemaObject.INDEX :
+            case SchemaObject.TRIGGER :
+                code = ErrorCode.X_42504;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SchemaObjectSet");
+        }
+
+        return code;
+    }
+
+    static int getGetErrorCode(int type) {
+
+        int code;
+
+        switch (type) {
+
+            case SchemaObject.VIEW :
+            case SchemaObject.TABLE :
+            case SchemaObject.COLUMN :
+            case SchemaObject.SEQUENCE :
+            case SchemaObject.CHARSET :
+            case SchemaObject.DOMAIN :
+            case SchemaObject.TYPE :
+            case SchemaObject.CONSTRAINT :
+            case SchemaObject.COLLATION :
+            case SchemaObject.PROCEDURE :
+            case SchemaObject.FUNCTION :
+            case SchemaObject.SPECIFIC_ROUTINE :
+            case SchemaObject.ASSERTION :
+            case SchemaObject.INDEX :
+            case SchemaObject.TRIGGER :
+                code = ErrorCode.X_42501;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SchemaObjectSet");
+        }
+
+        return code;
+    }
+
+    public static String getName(int type) {
+
+        switch (type) {
+
+            case SchemaObject.VIEW :
+                return Tokens.T_VIEW;
+
+            case SchemaObject.COLUMN :
+                return Tokens.T_COLUMN;
+
+            case SchemaObject.TABLE :
+                return Tokens.T_TABLE;
+
+            case SchemaObject.SEQUENCE :
+                return Tokens.T_SEQUENCE;
+
+            case SchemaObject.CHARSET :
+                return Tokens.T_CHARACTER + ' ' + Tokens.T_SET;
+
+            case SchemaObject.DOMAIN :
+                return Tokens.T_DOMAIN;
+
+            case SchemaObject.TYPE :
+                return Tokens.T_TYPE;
+
+            case SchemaObject.CONSTRAINT :
+                return Tokens.T_CONSTRAINT;
+
+            case SchemaObject.COLLATION :
+                return Tokens.T_COLLATION;
+
+            case SchemaObject.PROCEDURE :
+                return Tokens.T_PROCEDURE;
+
+            case SchemaObject.FUNCTION :
+                return Tokens.T_FUNCTION;
+
+            case SchemaObject.ASSERTION :
+                return Tokens.T_ASSERTION;
+
+            case SchemaObject.INDEX :
+                return Tokens.T_INDEX;
+
+            case SchemaObject.TRIGGER :
+                return Tokens.T_TRIGGER;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SchemaObjectSet");
+        }
+    }
+
+    String[] getSQL(OrderedHashSet resolved, OrderedHashSet unresolved) {
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        if (!(map instanceof HashMappedList)) {
+            return null;
+        }
+
+        if (map.isEmpty()) {
+            return ValuePool.emptyStringArray;
+        }
+
+        Iterator it = map.values().iterator();
+
+        if (type == SchemaObject.FUNCTION || type == SchemaObject.PROCEDURE) {
+            OrderedHashSet set = new OrderedHashSet();
+
+            while (it.hasNext()) {
+                RoutineSchema routineSchema = (RoutineSchema) it.next();
+
+                for (int i = 0; i < routineSchema.routines.length; i++) {
+                    Routine routine = routineSchema.routines[i];
+
+                    if (routine.dataImpact == Routine.NO_SQL
+                            || routine.dataImpact == Routine.CONTAINS_SQL) {}
+                    else {
+                        set.add(routine);
+                    }
+                }
+            }
+
+            it = set.iterator();
+        }
+
+        addAllSQL(resolved, unresolved, list, it, null);
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    static void addAllSQL(OrderedHashSet resolved, OrderedHashSet unresolved,
+                          HsqlArrayList list, Iterator it,
+                          OrderedHashSet newResolved) {
+
+        while (it.hasNext()) {
+            SchemaObject   object     = (SchemaObject) it.next();
+            OrderedHashSet references = object.getReferences();
+            boolean        isResolved = true;
+
+            for (int j = 0; j < references.size(); j++) {
+                HsqlName name = (HsqlName) references.get(j);
+
+                if (SqlInvariants.isSchemaNameSystem(name)) {
+                    continue;
+                }
+
+                switch (name.type) {
+
+                    case SchemaObject.TABLE :
+                        if (!resolved.contains(name)) {
+                            isResolved = false;
+                        }
+                        break;
+
+                    case SchemaObject.COLUMN : {
+                        if (object.getType() == SchemaObject.TABLE) {
+                            int index = ((Table) object).findColumn(name.name);
+                            ColumnSchema column =
+                                ((Table) object).getColumn(index);
+
+                            if (!isChildObjectResolved(column, resolved)) {
+                                isResolved = false;
+                            }
+
+                            break;
+                        }
+
+                        if (!resolved.contains(name.parent)) {
+                            isResolved = false;
+                        }
+
+                        break;
+                    }
+                    case SchemaObject.CONSTRAINT : {
+                        if (name.parent == object.getName()) {
+                            Constraint constraint =
+                                ((Table) object).getConstraint(name.name);
+
+                            if (constraint.getConstraintType()
+                                    == SchemaObject.ConstraintTypes.CHECK) {
+                                if (!isChildObjectResolved(constraint,
+                                                           resolved)) {
+                                    isResolved = false;
+                                }
+                            }
+                        }
+
+                        // only UNIQUE constraint referenced by FK in table
+                        break;
+                    }
+                    case SchemaObject.CHARSET :
+                        if (name.schema == null) {
+                            continue;
+                        }
+                    case SchemaObject.TYPE :
+                    case SchemaObject.DOMAIN :
+                    case SchemaObject.FUNCTION :
+                    case SchemaObject.PROCEDURE :
+                    case SchemaObject.SPECIFIC_ROUTINE :
+                        if (!resolved.contains(name)) {
+                            isResolved = false;
+                        }
+                    default :
+                }
+            }
+
+            if (!isResolved) {
+                unresolved.add(object);
+
+                continue;
+            }
+
+            HsqlName name;
+
+            if (object.getType() == SchemaObject.FUNCTION) {
+                name = ((Routine) object).getSpecificName();
+            } else {
+                name = object.getName();
+            }
+
+            resolved.add(name);
+
+            if (newResolved != null) {
+                newResolved.add(object);
+            }
+
+            if (object.getType() == SchemaObject.TABLE) {
+                list.addAll(((Table) object).getSQL(resolved, unresolved));
+            } else {
+                list.add(object.getSQL());
+            }
+        }
+    }
+
+    static boolean isChildObjectResolved(SchemaObject object,
+                                         OrderedHashSet resolved) {
+
+        OrderedHashSet refs = object.getReferences();
+
+        for (int i = 0; i < refs.size(); i++) {
+            HsqlName name = (HsqlName) refs.get(i);
+
+            if (SqlInvariants.isSchemaNameSystem(name)) {
+                continue;
+            }
+
+            if (!resolved.contains(name)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/Server.java b/src/org/hsqldb/Server.java
new file mode 100644
index 0000000..07e882a
--- /dev/null
+++ b/src/org/hsqldb/Server.java
@@ -0,0 +1,36 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+public class Server
+    extends org.hsqldb.server.Server {
+}
diff --git a/src/org/hsqldb/Session.java b/src/org/hsqldb/Session.java
new file mode 100644
index 0000000..e05bc64
--- /dev/null
+++ b/src/org/hsqldb/Session.java
@@ -0,0 +1,2145 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.Random;
+import java.util.TimeZone;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.jdbc.JDBCConnection;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.CountUpDownLatch;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlDeque;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultLob;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.rights.User;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of SQL sessions.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class Session implements SessionInterface {
+
+    //
+    private volatile boolean isClosed;
+
+    //
+    public Database    database;
+    private final User sessionUser;
+    private User       user;
+    private Grantee    role;
+
+    // transaction support
+    boolean          isReadOnlyDefault;
+    int isolationLevelDefault       = SessionInterface.TX_READ_COMMITTED;
+    int              isolationLevel = SessionInterface.TX_READ_COMMITTED;
+    int              actionIndex;
+    long             actionTimestamp;
+    long             transactionTimestamp;
+    boolean          isPreTransaction;
+    boolean          isTransaction;
+    boolean          isBatch;
+    volatile boolean abortTransaction;
+    volatile boolean redoAction;
+    HsqlArrayList    rowActionList;
+    volatile boolean tempUnlocked;
+    OrderedHashSet   waitedSessions;
+    OrderedHashSet   waitingSessions;
+    OrderedHashSet   tempSet;
+    CountUpDownLatch latch = new CountUpDownLatch();
+    Statement        lockStatement;
+
+    // current settings
+    final String       zoneString;
+    final int          sessionTimeZoneSeconds;
+    int                timeZoneSeconds;
+    boolean            isNetwork;
+    private int        sessionMaxRows;
+    private Number     lastIdentity = ValuePool.INTEGER_0;
+    private final long sessionId;
+    int                sessionTxId = -1;
+    private boolean    script;
+    boolean            ignoreCase;
+
+    // internal connection
+    private JDBCConnection intConnection;
+
+    // schema
+    public HsqlName currentSchema;
+    public HsqlName loggedSchema;
+
+    // query processing
+    ParserCommand         parser;
+    boolean               isProcessingScript;
+    boolean               isProcessingLog;
+    public SessionContext sessionContext;
+    int                   resultMaxMemoryRows;
+
+    //
+    public SessionData sessionData;
+
+    //
+    public StatementManager statementManager;
+
+    /** @todo 1.9.0 fredt - clarify in which circumstances Session has to disconnect */
+    Session getSession() {
+        return this;
+    }
+
+    /**
+     * Constructs a new Session object.
+     *
+     * @param  db the database to which this represents a connection
+     * @param  user the initial user
+     * @param  autocommit the initial autocommit value
+     * @param  readonly the initial readonly value
+     * @param  id the session identifier, as known to the database
+     */
+    Session(Database db, User user, boolean autocommit, boolean readonly,
+            long id, String zoneString, int timeZoneSeconds) {
+
+        sessionId                   = id;
+        database                    = db;
+        this.user                   = user;
+        this.sessionUser            = user;
+        this.zoneString             = zoneString;
+        this.sessionTimeZoneSeconds = timeZoneSeconds;
+        this.timeZoneSeconds        = timeZoneSeconds;
+        rowActionList               = new HsqlArrayList(true);
+        waitedSessions              = new OrderedHashSet();
+        waitingSessions             = new OrderedHashSet();
+        tempSet                     = new OrderedHashSet();
+        isolationLevelDefault       = database.getDefaultIsolationLevel();
+        isolationLevel              = isolationLevelDefault;
+        sessionContext              = new SessionContext(this);
+        sessionContext.isAutoCommit = ValuePool.getBoolean(autocommit);
+        sessionContext.isReadOnly   = ValuePool.getBoolean(readonly);
+        parser                      = new ParserCommand(this, new Scanner());
+
+        setResultMemoryRowCount(database.getResultMaxMemoryRows());
+        resetSchema();
+
+        sessionData      = new SessionData(database, this);
+        statementManager = new StatementManager(database);
+    }
+
+    void resetSchema() {
+        loggedSchema  = null;
+        currentSchema = user.getInitialOrDefaultSchema();
+    }
+
+    /**
+     *  Retrieves the session identifier for this Session.
+     *
+     * @return the session identifier for this Session
+     */
+    public long getId() {
+        return sessionId;
+    }
+
+    /**
+     * Closes this Session.
+     */
+    public synchronized void close() {
+
+        if (isClosed) {
+            return;
+        }
+
+        rollback(false);
+
+        try {
+            database.logger.writeToLog(this, Tokens.T_DISCONNECT);
+        } catch (HsqlException e) {}
+
+        sessionData.closeAllNavigators();
+        sessionData.persistentStoreCollection.clearAllTables();
+        sessionData.closeResultCache();
+        statementManager.reset();
+        database.sessionManager.removeSession(this);
+        database.closeIfLast();
+
+        // keep sessionContext and sessionData
+        database                  = null;
+        user                      = null;
+        rowActionList             = null;
+        sessionContext.savepoints = null;
+        intConnection             = null;
+        lastIdentity              = null;
+        isClosed                  = true;
+    }
+
+    /**
+     * Retrieves whether this Session is closed.
+     *
+     * @return true if this Session is closed
+     */
+    public boolean isClosed() {
+        return isClosed;
+    }
+
+    public synchronized void setIsolationDefault(int level) {
+
+        if (level == SessionInterface.TX_READ_UNCOMMITTED) {
+            isReadOnlyDefault = true;
+        }
+
+        if (level == isolationLevelDefault) {
+            return;
+        }
+
+        isolationLevelDefault = level;
+
+        if (!isInMidTransaction()) {
+            isolationLevel = isolationLevelDefault;
+        }
+
+        database.logger.writeToLog(this, getSessionIsolationSQL());
+    }
+
+    /**
+     * sets ISOLATION for the next transaction only
+     */
+    public void setIsolation(int level) {
+
+        if (isInMidTransaction()) {
+            throw Error.error(ErrorCode.X_25001);
+        }
+
+        if (level == SessionInterface.TX_READ_UNCOMMITTED) {
+            sessionContext.isReadOnly = Boolean.TRUE;
+        }
+
+        if (isolationLevel != level) {
+            isolationLevel = level;
+
+            database.logger.writeToLog(this, getTransactionIsolationSQL());
+        }
+    }
+
+    public synchronized int getIsolation() {
+        return isolationLevel;
+    }
+
+    /**
+     * Setter for iLastIdentity attribute.
+     *
+     * @param  i the new value
+     */
+    void setLastIdentity(Number i) {
+        lastIdentity = i;
+    }
+
+    /**
+     * Getter for iLastIdentity attribute.
+     *
+     * @return the current value
+     */
+    public Number getLastIdentity() {
+        return lastIdentity;
+    }
+
+    /**
+     * Retrieves the Database instance to which this
+     * Session represents a connection.
+     *
+     * @return the Database object to which this Session is connected
+     */
+    public Database getDatabase() {
+        return database;
+    }
+
+    /**
+     * Retrieves the name, as known to the database, of the
+     * user currently controlling this Session.
+     *
+     * @return the name of the user currently connected within this Session
+     */
+    public String getUsername() {
+        return user.getNameString();
+    }
+
+    /**
+     * Retrieves the User object representing the user currently controlling
+     * this Session.
+     *
+     * @return this Session's User object
+     */
+    public User getUser() {
+        return (User) user;
+    }
+
+    public Grantee getGrantee() {
+        return user;
+    }
+
+    public Grantee getRole() {
+        return role;
+    }
+
+    /**
+     * Sets this Session's User object to the one specified by the
+     * user argument.
+     *
+     * @param  user the new User object for this session
+     */
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    public void setRole(Grantee role) {
+        this.role = role;
+    }
+
+    int getMaxRows() {
+        return sessionContext.currentMaxRows;
+    }
+
+    /**
+     * The SQL command SET MAXROWS n will override the Statement.setMaxRows(n)
+     * for the next direct statement only
+     *
+     * NB this is dedicated to the SET MAXROWS sql statement and should not
+     * otherwise be called. (fredt@users)
+     */
+    void setSQLMaxRows(int rows) {
+        sessionMaxRows = rows;
+    }
+
+    /**
+     * Checks whether this Session's current User has the privileges of
+     * the ADMIN role.
+     */
+    void checkAdmin() {
+        user.checkAdmin();
+    }
+
+    /**
+     * This is used for reading - writing to existing tables.
+     * @throws  HsqlException
+     */
+    void checkReadWrite() {
+
+        if (sessionContext.isReadOnly.booleanValue()) {
+            throw Error.error(ErrorCode.X_25006);
+        }
+    }
+
+    /**
+     * This is used for creating new database objects such as tables.
+     * @throws  HsqlException
+     */
+    void checkDDLWrite() {
+
+        checkReadWrite();
+
+        if (isProcessingScript || isProcessingLog) {
+            return;
+        }
+    }
+
+    public long getActionTimestamp() {
+        return actionTimestamp;
+    }
+
+    /**
+     *  Adds a delete action to the row and the transaction manager.
+     *
+     * @param  table the table of the row
+     * @param  row the deleted row
+     * @throws  HsqlException
+     */
+    void addDeleteAction(Table table, Row row, int[] colMap) {
+
+//        tempActionHistory.add("add delete action " + actionTimestamp);
+        if (abortTransaction) {
+
+//            throw Error.error(ErrorCode.X_40001);
+        }
+
+        database.txManager.addDeleteAction(this, table, row, colMap);
+    }
+
+    void addInsertAction(Table table, Row row) {
+
+//        tempActionHistory.add("add insert to transaction " + actionTimestamp);
+        database.txManager.addInsertAction(this, table, row);
+
+        // abort only after adding so that the new row gets removed from indexes
+        if (abortTransaction) {
+
+//            throw Error.error(ErrorCode.X_40001);
+        }
+    }
+
+    /**
+     *  Setter for the autocommit attribute.
+     *
+     * @param  autocommit the new value
+     * @throws  HsqlException
+     */
+    public synchronized void setAutoCommit(boolean autocommit) {
+
+        if (isClosed) {
+            return;
+        }
+
+        if (sessionContext.isAutoCommit.booleanValue() != autocommit) {
+            commit(false);
+
+            sessionContext.isAutoCommit = ValuePool.getBoolean(autocommit);
+        }
+    }
+
+    public void beginAction(Statement cs) {
+
+        actionIndex = rowActionList.size();
+
+        database.txManager.beginAction(this, cs);
+        database.txManager.beginActionResume(this);
+    }
+
+    public void endAction(Result result) {
+
+//        tempActionHistory.add("endAction " + actionTimestamp);
+        sessionData.persistentStoreCollection.clearStatementTables();
+
+        if (result.mode == ResultConstants.ERROR) {
+            sessionData.persistentStoreCollection.clearResultTables(
+                actionTimestamp);
+            database.txManager.rollbackAction(this);
+        } else {
+            database.txManager.completeActions(this);
+        }
+
+//        tempActionHistory.add("endAction ends " + actionTimestamp);
+    }
+
+    public boolean hasLocks(Statement statement) {
+
+        if (lockStatement == statement) {
+            if (isolationLevel == SessionInterface.TX_REPEATABLE_READ
+                    || isolationLevel == SessionInterface.TX_SERIALIZABLE) {
+                return true;
+            }
+
+            if (statement.getTableNamesForRead().length == 0) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public void startTransaction() {
+        database.txManager.beginTransaction(this);
+    }
+
+    public synchronized void startPhasedTransaction() {}
+
+    /**
+     * @todo - fredt - for two phased pre-commit - after this call, further
+     * state changing calls should fail
+     */
+    public synchronized void prepareCommit() {
+
+        if (isClosed) {
+            throw Error.error(ErrorCode.X_08003);
+        }
+
+        if (!database.txManager.prepareCommitActions(this)) {
+
+//            tempActionHistory.add("commit aborts " + actionTimestamp);
+            rollback(false);
+
+            throw Error.error(ErrorCode.X_40001);
+        }
+    }
+
+    /**
+     * Commits any uncommited transaction this Session may have open
+     *
+     * @throws  HsqlException
+     */
+    public synchronized void commit(boolean chain) {
+
+//        tempActionHistory.add("commit " + actionTimestamp);
+        if (isClosed) {
+            return;
+        }
+
+        if (sessionContext.depth > 0) {
+            return;
+        }
+
+        if (!isTransaction) {
+            sessionContext.isReadOnly =
+                ValuePool.getBoolean(isReadOnlyDefault);
+            isolationLevel = isolationLevelDefault;
+
+            return;
+        }
+
+        if (!database.txManager.commitTransaction(this)) {
+
+//            tempActionHistory.add("commit aborts " + actionTimestamp);
+            rollback(false);
+
+            throw Error.error(ErrorCode.X_40001);
+        }
+
+        endTransaction(true);
+
+        if (database != null && database.logger.needsCheckpointReset()) {
+            Statement checkpoint =
+                ParserCommand.getCheckpointStatement(database, false);
+
+            executeCompiledStatement(checkpoint, ValuePool.emptyObjectArray);
+        }
+    }
+
+    /**
+     * Rolls back any uncommited transaction this Session may have open.
+     *
+     * @throws  HsqlException
+     */
+    public synchronized void rollback(boolean chain) {
+
+        //        tempActionHistory.add("rollback " + actionTimestamp);
+        if (isClosed) {
+            return;
+        }
+
+        if (sessionContext.depth > 0) {
+            return;
+        }
+
+        if (!isTransaction) {
+            sessionContext.isReadOnly =
+                ValuePool.getBoolean(isReadOnlyDefault);
+            isolationLevel = isolationLevelDefault;
+
+            return;
+        }
+
+        try {
+            database.logger.writeToLog(this, Tokens.T_ROLLBACK);
+        } catch (HsqlException e) {}
+
+        database.txManager.rollback(this);
+        endTransaction(false);
+    }
+
+    private void endTransaction(boolean commit) {
+
+        sessionContext.savepoints.clear();
+        sessionContext.savepointTimestamps.clear();
+        rowActionList.clear();
+        sessionData.persistentStoreCollection.clearTransactionTables();
+        sessionData.closeAllTransactionNavigators();
+
+        sessionContext.isReadOnly = ValuePool.getBoolean(isReadOnlyDefault);
+        isolationLevel            = isolationLevelDefault;
+        lockStatement             = null;
+/* debug 190
+        tempActionHistory.add("commit ends " + actionTimestamp);
+        tempActionHistory.clear();
+//*/
+    }
+
+    /**
+     * Clear structures and reset variables to original.
+     */
+    public synchronized void resetSession() {
+
+        rollback(false);
+        sessionData.closeAllNavigators();
+        sessionData.persistentStoreCollection.clearAllTables();
+        sessionData.closeResultCache();
+        statementManager.reset();
+
+        lastIdentity = ValuePool.INTEGER_0;
+
+        setResultMemoryRowCount(database.getResultMaxMemoryRows());
+
+        user = sessionUser;
+
+        resetSchema();
+        setZoneSeconds(sessionTimeZoneSeconds);
+
+        sessionMaxRows = 0;
+        ignoreCase     = false;
+    }
+
+    /**
+     *  Registers a transaction SAVEPOINT. A new SAVEPOINT with the
+     *  name of an existing one replaces the old SAVEPOINT.
+     *
+     * @param  name name of the savepoint
+     * @throws  HsqlException if there is no current transaction
+     */
+    public synchronized void savepoint(String name) {
+
+        int index = sessionContext.savepoints.getIndex(name);
+
+        if (index != -1) {
+            sessionContext.savepoints.remove(name);
+            sessionContext.savepointTimestamps.remove(index);
+        }
+
+        sessionContext.savepoints.add(name,
+                                      ValuePool.getInt(rowActionList.size()));
+        sessionContext.savepointTimestamps.addLast(actionTimestamp);
+
+        try {
+            database.logger.writeToLog(this, getSavepointSQL(name));
+        } catch (HsqlException e) {}
+    }
+
+    /**
+     *  Performs a partial transaction ROLLBACK to savepoint.
+     *
+     * @param  name name of savepoint
+     * @throws  HsqlException
+     */
+    public synchronized void rollbackToSavepoint(String name) {
+
+        if (isClosed) {
+            return;
+        }
+
+        int index = sessionContext.savepoints.getIndex(name);
+
+        if (index < 0) {
+            throw Error.error(ErrorCode.X_3B001, name);
+        }
+
+        database.txManager.rollbackSavepoint(this, index);
+
+        try {
+            database.logger.writeToLog(this, getSavepointRollbackSQL(name));
+        } catch (HsqlException e) {}
+    }
+
+    /**
+     * Performs a partial transaction ROLLBACK of current savepoint level.
+     *
+     * @throws  HsqlException
+     */
+    public synchronized void rollbackToSavepoint() {
+
+        if (isClosed) {
+            return;
+        }
+
+        String name = (String) sessionContext.savepoints.getKey(0);
+
+        database.txManager.rollbackSavepoint(this, 0);
+
+        try {
+            database.logger.writeToLog(this, getSavepointRollbackSQL(name));
+        } catch (HsqlException e) {}
+    }
+
+    /**
+     * Releases a savepoint
+     *
+     * @param  name name of savepoint
+     * @throws  HsqlException if name does not correspond to a savepoint
+     */
+    public synchronized void releaseSavepoint(String name) {
+
+        // remove this and all later savepoints
+        int index = sessionContext.savepoints.getIndex(name);
+
+        if (index < 0) {
+            throw Error.error(ErrorCode.X_3B001, name);
+        }
+
+        while (sessionContext.savepoints.size() > index) {
+            sessionContext.savepoints.remove(sessionContext.savepoints.size()
+                                             - 1);
+            sessionContext.savepointTimestamps.removeLast();
+        }
+    }
+
+    public boolean isInMidTransaction() {
+        return isTransaction;
+    }
+
+    public void setNoSQL() {
+        sessionContext.noSQL = Boolean.TRUE;
+    }
+
+    public void setIgnoreCase(boolean mode) {
+        ignoreCase = mode;
+    }
+
+    /**
+     * sets READ ONLY for next transaction / subtransaction only
+     *
+     * @param  readonly the new value
+     */
+    public void setReadOnly(boolean readonly) {
+
+        if (!readonly && database.databaseReadOnly) {
+            throw Error.error(ErrorCode.DATABASE_IS_READONLY);
+        }
+
+        if (isInMidTransaction()) {
+            throw Error.error(ErrorCode.X_25001);
+        }
+
+        sessionContext.isReadOnly = ValuePool.getBoolean(readonly);
+    }
+
+    public synchronized void setReadOnlyDefault(boolean readonly) {
+
+        if (!readonly && database.databaseReadOnly) {
+            throw Error.error(ErrorCode.DATABASE_IS_READONLY);
+        }
+
+        isReadOnlyDefault = readonly;
+
+        if (!isInMidTransaction()) {
+            sessionContext.isReadOnly =
+                ValuePool.getBoolean(isReadOnlyDefault);
+        }
+    }
+
+    /**
+     *  Getter for readonly attribute.
+     *
+     * @return the current value
+     */
+    public boolean isReadOnly() {
+        return sessionContext.isReadOnly.booleanValue();
+    }
+
+    public synchronized boolean isReadOnlyDefault() {
+        return isReadOnlyDefault;
+    }
+
+    /**
+     *  Getter for autoCommit attribute.
+     *
+     * @return the current value
+     */
+    public synchronized boolean isAutoCommit() {
+        return sessionContext.isAutoCommit.booleanValue();
+    }
+
+    public synchronized int getStreamBlockSize() {
+        return 512 * 1024;
+    }
+
+    /**
+     *  A switch to set scripting on the basis of type of statement executed.
+     *  Afterwards the method reponsible for logging uses
+     *  isScripting() to determine if logging is required for the executed
+     *  statement. (fredt@users)
+     *
+     * @param  script The new scripting value
+     */
+    void setScripting(boolean script) {
+        this.script = script;
+    }
+
+    /**
+     * Getter for scripting attribute.
+     *
+     * @return  scripting for the last statement.
+     */
+    boolean isScripting() {
+        return script;
+    }
+
+    /**
+     * Retrieves an internal Connection object equivalent to the one
+     * that created this Session.
+     *
+     * @return  internal connection.
+     */
+    JDBCConnection getInternalConnection() {
+
+        if (intConnection == null) {
+            intConnection = new JDBCConnection(this);
+        }
+
+        return intConnection;
+    }
+
+// boucherb@users 20020810 metadata 1.7.2
+//----------------------------------------------------------------
+    private final long connectTime = System.currentTimeMillis();
+
+// more effecient for MetaData concerns than checkAdmin
+
+    /**
+     * Getter for admin attribute.
+     *
+     * @return the current value
+     */
+    public boolean isAdmin() {
+        return user.isAdmin();
+    }
+
+    /**
+     * Getter for connectTime attribute.
+     *
+     * @return the value
+     */
+    public long getConnectTime() {
+        return connectTime;
+    }
+
+    /**
+     * Count of acctions in current transaction.
+     *
+     * @return the current value
+     */
+    public int getTransactionSize() {
+        return rowActionList.size();
+    }
+
+    public long getTransactionTimestamp() {
+        return transactionTimestamp;
+    }
+
+    public Statement compileStatement(String sql, int props) {
+
+        parser.reset(sql);
+
+        Statement cs = parser.compileStatement(props);
+
+        return cs;
+    }
+
+    /**
+     * Executes the command encapsulated by the cmd argument.
+     *
+     * @param cmd the command to execute
+     * @return the result of executing the command
+     */
+    public synchronized Result execute(Result cmd) {
+
+        if (isClosed) {
+            return Result.newErrorResult(Error.error(ErrorCode.X_08503));
+        }
+
+        sessionContext.currentMaxRows = 0;
+        isBatch                       = false;
+
+        JavaSystem.gc();
+
+        switch (cmd.mode) {
+
+            case ResultConstants.LARGE_OBJECT_OP : {
+                return performLOBOperation((ResultLob) cmd);
+            }
+            case ResultConstants.EXECUTE : {
+                int maxRows = cmd.getUpdateCount();
+
+                if (maxRows == -1) {
+                    sessionContext.currentMaxRows = 0;
+                } else {
+                    sessionContext.currentMaxRows = maxRows;
+                }
+
+                Statement cs = cmd.statement;
+
+                if (cs == null
+                        || cs.compileTimestamp
+                           < database.schemaManager.schemaChangeTimestamp) {
+                    long csid = cmd.getStatementID();
+
+                    cs = statementManager.getStatement(this, csid);
+
+                    if (cs == null) {
+
+                        // invalid sql has been removed already
+                        return Result.newErrorResult(
+                            Error.error(ErrorCode.X_07502));
+                    }
+                }
+
+                Object[] pvals  = (Object[]) cmd.valueData;
+                Result   result = executeCompiledStatement(cs, pvals);
+
+                result = performPostExecute(cmd, result);
+
+                return result;
+            }
+            case ResultConstants.BATCHEXECUTE : {
+                isBatch = true;
+
+                Result result = executeCompiledBatchStatement(cmd);
+
+                result = performPostExecute(cmd, result);
+
+                return result;
+            }
+            case ResultConstants.EXECDIRECT : {
+                Result result = executeDirectStatement(cmd);
+
+                result = performPostExecute(cmd, result);
+
+                return result;
+            }
+            case ResultConstants.BATCHEXECDIRECT : {
+                isBatch = true;
+
+                Result result = executeDirectBatchStatement(cmd);
+
+                result = performPostExecute(cmd, result);
+
+                return result;
+            }
+            case ResultConstants.PREPARE : {
+                Statement cs;
+
+                try {
+                    cs = statementManager.compile(this, cmd);
+                } catch (Throwable t) {
+                    String errorString = cmd.getMainString();
+
+                    if (database.getProperties().getErrorLevel()
+                            == HsqlDatabaseProperties.NO_MESSAGE) {
+                        errorString = null;
+                    }
+
+                    return Result.newErrorResult(t, errorString);
+                }
+
+                Result result = Result.newPrepareResponse(cs);
+
+                if (cs.getType() == StatementTypes.SELECT_CURSOR
+                        || cs.getType() == StatementTypes.CALL) {
+                    sessionData.setResultSetProperties(cmd, result);
+                }
+
+                result = performPostExecute(cmd, result);
+
+                return result;
+            }
+            case ResultConstants.CLOSE_RESULT : {
+                closeNavigator(cmd.getResultId());
+
+                return Result.updateZeroResult;
+            }
+            case ResultConstants.UPDATE_RESULT : {
+                Result result = this.executeResultUpdate(cmd);
+
+                result = performPostExecute(cmd, result);
+
+                return result;
+            }
+            case ResultConstants.FREESTMT : {
+                statementManager.freeStatement(cmd.getStatementID());
+
+                return Result.updateZeroResult;
+            }
+            case ResultConstants.GETSESSIONATTR : {
+                int id = cmd.getStatementType();
+
+                return getAttributesResult(id);
+            }
+            case ResultConstants.SETSESSIONATTR : {
+                return setAttributes(cmd);
+            }
+            case ResultConstants.ENDTRAN : {
+                switch (cmd.getActionType()) {
+
+                    case ResultConstants.TX_COMMIT :
+                        try {
+                            commit(false);
+                        } catch (Throwable t) {
+                            return Result.newErrorResult(t);
+                        }
+                        break;
+
+                    case ResultConstants.TX_COMMIT_AND_CHAIN :
+                        try {
+                            commit(true);
+                        } catch (Throwable t) {
+                            return Result.newErrorResult(t);
+                        }
+                        break;
+
+                    case ResultConstants.TX_ROLLBACK :
+                        rollback(false);
+                        break;
+
+                    case ResultConstants.TX_ROLLBACK_AND_CHAIN :
+                        rollback(true);
+                        break;
+
+                    case ResultConstants.TX_SAVEPOINT_NAME_RELEASE :
+                        try {
+                            String name = cmd.getMainString();
+
+                            releaseSavepoint(name);
+                        } catch (Throwable t) {
+                            return Result.newErrorResult(t);
+                        }
+                        break;
+
+                    case ResultConstants.TX_SAVEPOINT_NAME_ROLLBACK :
+                        try {
+                            rollbackToSavepoint(cmd.getMainString());
+                        } catch (Throwable t) {
+                            return Result.newErrorResult(t);
+                        }
+                        break;
+                }
+
+                return Result.updateZeroResult;
+            }
+            case ResultConstants.SETCONNECTATTR : {
+                switch (cmd.getConnectionAttrType()) {
+
+                    case ResultConstants.SQL_ATTR_SAVEPOINT_NAME :
+                        try {
+                            savepoint(cmd.getMainString());
+                        } catch (Throwable t) {
+                            return Result.newErrorResult(t);
+                        }
+
+                    // case ResultConstants.SQL_ATTR_AUTO_IPD
+                    //   - always true
+                    // default: throw - case never happens
+                }
+
+                return Result.updateZeroResult;
+            }
+            case ResultConstants.REQUESTDATA : {
+                return sessionData.getDataResultSlice(cmd.getResultId(),
+                                                      cmd.getUpdateCount(),
+                                                      cmd.getFetchSize());
+            }
+            case ResultConstants.DISCONNECT : {
+                close();
+
+                return Result.updateZeroResult;
+            }
+            default : {
+                return Result.newErrorResult(
+                    Error.runtimeError(ErrorCode.U_S0500, "Session"));
+            }
+        }
+    }
+
+    private Result performPostExecute(Result command, Result result) {
+
+        if (result.mode == ResultConstants.DATA) {
+            result = sessionData.getDataResultHead(command, result, isNetwork);
+        }
+
+        if (sqlWarnings != null && sqlWarnings.size() > 0) {
+            if (result.mode == ResultConstants.UPDATECOUNT) {
+                result = new Result(ResultConstants.UPDATECOUNT,
+                                    result.getUpdateCount());
+            }
+
+            HsqlException[] warnings = getAndClearWarnings();
+
+            result.addWarnings(warnings);
+        }
+
+        return result;
+    }
+
+    public RowSetNavigatorClient getRows(long navigatorId, int offset,
+                                         int blockSize) {
+        return sessionData.getRowSetSlice(navigatorId, offset, blockSize);
+    }
+
+    public synchronized void closeNavigator(long id) {
+        sessionData.closeNavigator(id);
+    }
+
+    public Result executeDirectStatement(Result cmd) {
+
+        String        sql = cmd.getMainString();
+        HsqlArrayList list;
+        int           maxRows = cmd.getUpdateCount();
+
+        if (maxRows == -1) {
+            sessionContext.currentMaxRows = 0;
+        } else if (sessionMaxRows == 0) {
+            sessionContext.currentMaxRows = maxRows;
+        } else {
+            sessionContext.currentMaxRows = sessionMaxRows;
+            sessionMaxRows                = 0;
+        }
+
+        try {
+            list = parser.compileStatements(sql, cmd);
+        } catch (Exception e) {
+            return Result.newErrorResult(e);
+        }
+
+        Result result = null;
+
+        for (int i = 0; i < list.size(); i++) {
+            Statement cs = (Statement) list.get(i);
+
+            cs.setGeneratedColumnInfo(cmd.getGeneratedResultType(),
+                                      cmd.getGeneratedResultMetaData());
+
+            result = executeCompiledStatement(cs, ValuePool.emptyObjectArray);
+
+            if (result.mode == ResultConstants.ERROR) {
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    public Result executeDirectStatement(String sql, int props) {
+
+        Statement cs;
+
+        parser.reset(sql);
+
+        try {
+            cs = parser.compileStatement(props);
+        } catch (HsqlException e) {
+            return Result.newErrorResult(e);
+        }
+
+        Result result = executeCompiledStatement(cs,
+            ValuePool.emptyObjectArray);
+
+        return result;
+    }
+
+    public Result executeCompiledStatement(Statement cs, Object[] pvals) {
+
+        Result r;
+
+        if (abortTransaction) {
+            rollback(false);
+
+            return Result.newErrorResult(Error.error(ErrorCode.X_40001));
+        }
+
+        if (sessionContext.depth > 0) {
+            if (sessionContext.noSQL || cs.isAutoCommitStatement()) {
+                return Result.newErrorResult(Error.error(ErrorCode.X_46000));
+            }
+        }
+
+        if (cs.isAutoCommitStatement()) {
+            if (isReadOnly()) {
+                return Result.newErrorResult(Error.error(ErrorCode.X_25006));
+            }
+
+            try {
+
+                /** special autocommit for backward compatibility */
+                commit(false);
+            } catch (HsqlException e) {
+                database.logger.logInfoEvent("Exception at commit");
+            }
+        }
+
+        sessionContext.currentStatement = cs;
+
+        if (!cs.isTransactionStatement()) {
+            r                               = cs.execute(this);
+            sessionContext.currentStatement = null;
+
+            return r;
+        }
+
+        while (true) {
+            actionIndex = rowActionList.size();
+
+            database.txManager.beginAction(this, cs);
+
+            if (abortTransaction) {
+                rollback(false);
+
+                sessionContext.currentStatement = null;
+
+                return Result.newErrorResult(Error.error(ErrorCode.X_40001));
+            }
+
+            try {
+                latch.await();
+            } catch (InterruptedException e) {
+
+                // System.out.println("interrupted");
+            }
+
+            if (abortTransaction) {
+                rollback(false);
+
+                sessionContext.currentStatement = null;
+
+                return Result.newErrorResult(Error.error(ErrorCode.X_40001));
+            }
+
+            database.txManager.beginActionResume(this);
+
+            //        tempActionHistory.add("sql execute " + cs.sql + " " + actionTimestamp + " " + rowActionList.size());
+            sessionContext.setDynamicArguments(pvals);
+
+            r             = cs.execute(this);
+            lockStatement = sessionContext.currentStatement;
+
+            //        tempActionHistory.add("sql execute end " + actionTimestamp + " " + rowActionList.size());
+            endAction(r);
+
+            if (abortTransaction) {
+                rollback(false);
+
+                sessionContext.currentStatement = null;
+
+                return Result.newErrorResult(Error.error(ErrorCode.X_40001));
+            }
+
+            if (redoAction) {
+                redoAction = false;
+
+                try {
+                    latch.await();
+                } catch (InterruptedException e) {
+
+                    //
+                    System.out.println("interrupted");
+                }
+            } else {
+                break;
+            }
+        }
+
+        if (sessionContext.depth == 0
+                && (sessionContext.isAutoCommit.booleanValue()
+                    || cs.isAutoCommitStatement())) {
+            try {
+                if (r.mode == ResultConstants.ERROR) {
+                    rollback(false);
+                } else {
+                    commit(false);
+                }
+            } catch (Exception e) {
+                sessionContext.currentStatement = null;
+
+                return Result.newErrorResult(Error.error(ErrorCode.X_40001,
+                        e));
+            }
+        }
+
+        sessionContext.currentStatement = null;
+
+        return r;
+    }
+
+    private Result executeCompiledBatchStatement(Result cmd) {
+
+        long      csid;
+        Statement cs;
+        int[]     updateCounts;
+        int       count;
+
+        csid = cmd.getStatementID();
+        cs   = statementManager.getStatement(this, csid);
+
+        if (cs == null) {
+
+            // invalid sql has been removed already
+            return Result.newErrorResult(Error.error(ErrorCode.X_07501));
+        }
+
+        count = 0;
+
+        RowSetNavigator nav = cmd.initialiseNavigator();
+
+        updateCounts = new int[nav.getSize()];
+
+        Result generatedResult = null;
+
+        if (cs.hasGeneratedColumns()) {
+            generatedResult =
+                Result.newDataResult(cs.generatedResultMetaData());
+        }
+
+        Result error = null;
+
+        while (nav.hasNext()) {
+            Object[] pvals = (Object[]) nav.getNext();
+            Result   in    = executeCompiledStatement(cs, pvals);
+
+            // On the client side, iterate over the vals and throw
+            // a BatchUpdateException if a batch status value of
+            // esultConstants.EXECUTE_FAILED is encountered in the result
+            if (in.isUpdateCount()) {
+                if (cs.hasGeneratedColumns()) {
+                    RowSetNavigator navgen =
+                        in.getChainedResult().getNavigator();
+
+                    while (navgen.hasNext()) {
+                        Object[] generatedRow = navgen.getNext();
+
+                        generatedResult.getNavigator().add(generatedRow);
+                    }
+                }
+
+                updateCounts[count++] = in.getUpdateCount();
+            } else if (in.isData()) {
+
+                // FIXME:  we don't have what it takes yet
+                // to differentiate between things like
+                // stored procedure calls to methods with
+                // void return type and select statements with
+                // a single row/column containg null
+                updateCounts[count++] = ResultConstants.SUCCESS_NO_INFO;
+            } else if (in.mode == ResultConstants.ERROR) {
+                updateCounts = ArrayUtil.arraySlice(updateCounts, 0, count);
+                error        = in;
+
+                break;
+            } else {
+                throw Error.runtimeError(ErrorCode.U_S0500, "Session");
+            }
+        }
+
+        return Result.newBatchedExecuteResponse(updateCounts, generatedResult,
+                error);
+    }
+
+    private Result executeDirectBatchStatement(Result cmd) {
+
+        int[] updateCounts;
+        int   count;
+
+        count = 0;
+
+        RowSetNavigator nav = cmd.initialiseNavigator();
+
+        updateCounts = new int[nav.getSize()];
+
+        Result error = null;
+
+        while (nav.hasNext()) {
+            Result   in;
+            Object[] data = (Object[]) nav.getNext();
+            String   sql  = (String) data[0];
+
+            try {
+                in = executeDirectStatement(
+                    sql, ResultProperties.defaultPropsValue);
+            } catch (Throwable t) {
+                in = Result.newErrorResult(t);
+
+                // if (t instanceof OutOfMemoryError) {
+                // System.gc();
+                // }
+                // "in" alread equals "err"
+                // maybe test for OOME and do a gc() ?
+                // t.printStackTrace();
+            }
+
+            if (in.isUpdateCount()) {
+                updateCounts[count++] = in.getUpdateCount();
+            } else if (in.isData()) {
+
+                // FIXME:  we don't have what it takes yet
+                // to differentiate between things like
+                // stored procedure calls to methods with
+                // void return type and select statements with
+                // a single row/column containg null
+                updateCounts[count++] = ResultConstants.SUCCESS_NO_INFO;
+            } else if (in.mode == ResultConstants.ERROR) {
+                updateCounts = ArrayUtil.arraySlice(updateCounts, 0, count);
+                error        = in;
+
+                break;
+            } else {
+                throw Error.runtimeError(ErrorCode.U_S0500, "Session");
+            }
+        }
+
+        return Result.newBatchedExecuteResponse(updateCounts, null, error);
+    }
+
+    /**
+     * Retrieves the result of inserting, updating or deleting a row
+     * from an updatable result.
+     *
+     * @return the result of executing the statement
+     */
+    private Result executeResultUpdate(Result cmd) {
+
+        long   id         = cmd.getResultId();
+        int    actionType = cmd.getActionType();
+        Result result     = sessionData.getDataResult(id);
+
+        if (result == null) {
+            return Result.newErrorResult(Error.error(ErrorCode.X_24501));
+        }
+
+        Object[]        pvals     = (Object[]) cmd.valueData;
+        Type[]          types     = cmd.metaData.columnTypes;
+        StatementQuery  statement = (StatementQuery) result.getStatement();
+        QueryExpression qe        = statement.queryExpression;
+        Table           baseTable = qe.getBaseTable();
+        int[]           columnMap = qe.getBaseTableColumnMap();
+
+        sessionContext.rowUpdateStatement.setRowActionProperties(result,
+                actionType, baseTable, types, columnMap);
+
+        Result resultOut =
+            executeCompiledStatement(sessionContext.rowUpdateStatement, pvals);
+
+        return resultOut;
+    }
+
+// session DATETIME functions
+    long                  currentDateSCN;
+    long                  currentTimestampSCN;
+    long                  currentMillis;
+    private TimestampData currentDate;
+    private TimestampData currentTimestamp;
+    private TimestampData localTimestamp;
+    private TimeData      currentTime;
+    private TimeData      localTime;
+
+    /**
+     * Returns the current date, unchanged for the duration of the current
+     * execution unit (statement).<p>
+     *
+     * SQL standards require that CURRENT_DATE, CURRENT_TIME and
+     * CURRENT_TIMESTAMP are all evaluated at the same point of
+     * time in the duration of each SQL statement, no matter how long the
+     * SQL statement takes to complete.<p>
+     *
+     * When this method or a corresponding method for CURRENT_TIME or
+     * CURRENT_TIMESTAMP is first called in the scope of a system change
+     * number, currentMillis is set to the current system time. All further
+     * CURRENT_XXXX calls in this scope will use this millisecond value.
+     * (fredt@users)
+     */
+    public synchronized TimestampData getCurrentDate() {
+
+        resetCurrentTimestamp();
+
+        if (currentDate == null) {
+            currentDate = (TimestampData) Type.SQL_DATE.getValue(currentMillis
+                    / 1000, 0, getZoneSeconds());
+        }
+
+        return currentDate;
+    }
+
+    /**
+     * Returns the current time, unchanged for the duration of the current
+     * execution unit (statement)
+     */
+    synchronized TimeData getCurrentTime(boolean withZone) {
+
+        resetCurrentTimestamp();
+
+        if (withZone) {
+            if (currentTime == null) {
+                int seconds =
+                    (int) (HsqlDateTime.getNormalisedTime(currentMillis))
+                    / 1000;
+                int nanos = (int) (currentMillis % 1000) * 1000000;
+
+                currentTime = new TimeData(seconds, nanos, getZoneSeconds());
+            }
+
+            return currentTime;
+        } else {
+            if (localTime == null) {
+                int seconds =
+                    (int) (HsqlDateTime.getNormalisedTime(
+                        currentMillis + getZoneSeconds() * 1000)) / 1000;
+                int nanos = (int) (currentMillis % 1000) * 1000000;
+
+                localTime = new TimeData(seconds, nanos, 0);
+            }
+
+            return localTime;
+        }
+    }
+
+    /**
+     * Returns the current timestamp, unchanged for the duration of the current
+     * execution unit (statement)
+     */
+    synchronized TimestampData getCurrentTimestamp(boolean withZone) {
+
+        resetCurrentTimestamp();
+
+        if (withZone) {
+            if (currentTimestamp == null) {
+                int nanos = (int) (currentMillis % 1000) * 1000000;
+
+                currentTimestamp = new TimestampData((currentMillis / 1000),
+                                                     nanos, getZoneSeconds());
+            }
+
+            return currentTimestamp;
+        } else {
+            if (localTimestamp == null) {
+                int nanos = (int) (currentMillis % 1000) * 1000000;
+
+                localTimestamp = new TimestampData(currentMillis / 1000
+                                                   + getZoneSeconds(), nanos,
+                                                       0);
+            }
+
+            return localTimestamp;
+        }
+    }
+
+    private void resetCurrentTimestamp() {
+
+        if (currentTimestampSCN != actionTimestamp) {
+            currentTimestampSCN = actionTimestamp;
+            currentMillis       = System.currentTimeMillis();
+            currentDate         = null;
+            currentTimestamp    = null;
+            localTimestamp      = null;
+            currentTime         = null;
+            localTime           = null;
+        }
+    }
+
+    public int getZoneSeconds() {
+        return timeZoneSeconds;
+    }
+
+    public void setZoneSeconds(int seconds) {
+
+        if (seconds == sessionTimeZoneSeconds) {
+            calendar        = null;
+            timeZoneSeconds = sessionTimeZoneSeconds;
+        } else {
+            TimeZone zone = TimeZone.getDefault();
+
+            zone.setRawOffset(seconds * 1000);
+
+            calendar        = new GregorianCalendar(zone);
+            timeZoneSeconds = seconds;
+        }
+    }
+
+    private Result getAttributesResult(int id) {
+
+        Result   r    = Result.newSessionAttributesResult();
+        Object[] data = r.getSingleRowData();
+
+        data[SessionInterface.INFO_ID] = ValuePool.getInt(id);
+
+        switch (id) {
+
+            case SessionInterface.INFO_ISOLATION :
+                data[SessionInterface.INFO_INTEGER] =
+                    ValuePool.getInt(isolationLevel);
+                break;
+
+            case SessionInterface.INFO_AUTOCOMMIT :
+                data[SessionInterface.INFO_BOOLEAN] =
+                    sessionContext.isAutoCommit;
+                break;
+
+            case SessionInterface.INFO_CONNECTION_READONLY :
+                data[SessionInterface.INFO_BOOLEAN] =
+                    sessionContext.isReadOnly;
+                break;
+
+            case SessionInterface.INFO_CATALOG :
+                data[SessionInterface.INFO_VARCHAR] =
+                    database.getCatalogName().name;
+                break;
+        }
+
+        return r;
+    }
+
+    private Result setAttributes(Result r) {
+
+        Object[] row = r.getSessionAttributes();
+        int      id  = ((Integer) row[SessionInterface.INFO_ID]).intValue();
+
+        try {
+            switch (id) {
+
+                case SessionInterface.INFO_AUTOCOMMIT : {
+                    boolean value =
+                        ((Boolean) row[SessionInterface.INFO_BOOLEAN])
+                            .booleanValue();
+
+                    this.setAutoCommit(value);
+
+                    break;
+                }
+                case SessionInterface.INFO_CONNECTION_READONLY : {
+                    boolean value =
+                        ((Boolean) row[SessionInterface.INFO_BOOLEAN])
+                            .booleanValue();
+
+                    this.setReadOnlyDefault(value);
+
+                    break;
+                }
+                case SessionInterface.INFO_ISOLATION : {
+                    int value =
+                        ((Integer) row[SessionInterface.INFO_INTEGER])
+                            .intValue();
+
+                    this.setIsolation(value);
+
+                    break;
+                }
+                case SessionInterface.INFO_CATALOG : {
+                    String value =
+                        ((String) row[SessionInterface.INFO_VARCHAR]);
+
+                    this.setCatalog(value);
+                }
+            }
+        } catch (HsqlException e) {
+            return Result.newErrorResult(e);
+        }
+
+        return Result.updateZeroResult;
+    }
+
+    public synchronized Object getAttribute(int id) {
+
+        switch (id) {
+
+            case SessionInterface.INFO_ISOLATION :
+                return ValuePool.getInt(isolationLevel);
+
+            case SessionInterface.INFO_AUTOCOMMIT :
+                return sessionContext.isAutoCommit;
+
+            case SessionInterface.INFO_CONNECTION_READONLY :
+                return sessionContext.isReadOnly;
+
+            case SessionInterface.INFO_CATALOG :
+                return database.getCatalogName().name;
+        }
+
+        return null;
+    }
+
+    public synchronized void setAttribute(int id, Object object) {
+
+        switch (id) {
+
+            case SessionInterface.INFO_AUTOCOMMIT : {
+                boolean value = ((Boolean) object).booleanValue();
+
+                this.setAutoCommit(value);
+
+                break;
+            }
+            case SessionInterface.INFO_CONNECTION_READONLY : {
+                boolean value = ((Boolean) object).booleanValue();
+
+                this.setReadOnlyDefault(value);
+
+                break;
+            }
+            case SessionInterface.INFO_ISOLATION : {
+                int value = ((Integer) object).intValue();
+
+                this.setIsolation(value);
+
+                break;
+            }
+            case SessionInterface.INFO_CATALOG : {
+                String value = ((String) object);
+
+                this.setCatalog(value);
+            }
+        }
+    }
+
+    // lobs
+    public BlobDataID createBlob(long length) {
+
+        long lobID = database.lobManager.createBlob(length);
+
+        if (lobID == 0) {
+            throw Error.error(ErrorCode.X_0F502);
+        }
+
+        sessionData.addToCreatedLobs(lobID);
+
+        return new BlobDataID(lobID);
+    }
+
+    public ClobDataID createClob(long length) {
+
+        long lobID = database.lobManager.createClob(length);
+
+        if (lobID == 0) {
+            throw Error.error(ErrorCode.X_0F502);
+        }
+
+        sessionData.addToCreatedLobs(lobID);
+
+        return new ClobDataID(lobID);
+    }
+
+    public void registerResultLobs(Result result) {
+        sessionData.registerLobForResult(result);
+    }
+
+    public void allocateResultLob(ResultLob result, InputStream inputStream) {
+        sessionData.allocateLobForResult(result, inputStream);
+    }
+
+    Result performLOBOperation(ResultLob cmd) {
+
+        long id        = cmd.getLobID();
+        int  operation = cmd.getSubType();
+
+        switch (operation) {
+
+            case ResultLob.LobResultTypes.REQUEST_GET_LOB : {
+                return database.lobManager.getLob(id, cmd.getOffset(),
+                                                  cmd.getBlockLength());
+            }
+            case ResultLob.LobResultTypes.REQUEST_GET_LENGTH : {
+                return database.lobManager.getLength(id);
+            }
+            case ResultLob.LobResultTypes.REQUEST_GET_BYTES : {
+                return database.lobManager.getBytes(
+                    id, cmd.getOffset(), (int) cmd.getBlockLength());
+            }
+            case ResultLob.LobResultTypes.REQUEST_SET_BYTES : {
+                return database.lobManager.setBytes(id, cmd.getByteArray(),
+                                                    cmd.getOffset());
+            }
+            case ResultLob.LobResultTypes.REQUEST_GET_CHARS : {
+                return database.lobManager.getChars(
+                    id, cmd.getOffset(), (int) cmd.getBlockLength());
+            }
+            case ResultLob.LobResultTypes.REQUEST_SET_CHARS : {
+                return database.lobManager.setChars(id, cmd.getOffset(),
+                                                    cmd.getCharArray());
+            }
+            case ResultLob.LobResultTypes.REQUEST_TRUNCATE : {
+                throw Error.error(ErrorCode.X_0A501);
+            }
+            case ResultLob.LobResultTypes.REQUEST_CREATE_BYTES :
+            case ResultLob.LobResultTypes.REQUEST_CREATE_CHARS :
+            case ResultLob.LobResultTypes.REQUEST_GET_BYTE_PATTERN_POSITION :
+            case ResultLob.LobResultTypes.REQUEST_GET_CHAR_PATTERN_POSITION : {
+                throw Error.error(ErrorCode.X_0A501);
+            }
+            default : {
+                throw Error.runtimeError(ErrorCode.U_S0500, "Session");
+            }
+        }
+    }
+
+    // DatabaseMetaData.getURL should work as specified for
+    // internal connections too.
+    public String getInternalConnectionURL() {
+        return DatabaseURL.S_URL_PREFIX + database.getURI();
+    }
+
+    boolean isProcessingScript() {
+        return isProcessingScript;
+    }
+
+    boolean isProcessingLog() {
+        return isProcessingLog;
+    }
+
+    // schema object methods
+    public void setSchema(String schema) {
+        currentSchema = database.schemaManager.getSchemaHsqlName(schema);
+    }
+
+    public void setCatalog(String catalog) {
+
+        if (database.getCatalogName().name.equals(catalog)) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_3D000);
+    }
+
+    /**
+     * If schemaName is null, return the current schema name, else return
+     * the HsqlName object for the schema. If schemaName does not exist,
+     * throw.
+     */
+    HsqlName getSchemaHsqlName(String name) {
+        return name == null ? currentSchema
+                            : database.schemaManager.getSchemaHsqlName(name);
+    }
+
+    /**
+     * Same as above, but return string
+     */
+    public String getSchemaName(String name) {
+        return name == null ? currentSchema.name
+                            : database.schemaManager.getSchemaName(name);
+    }
+
+    public void setCurrentSchemaHsqlName(HsqlName name) {
+        currentSchema = name;
+    }
+
+    public HsqlName getCurrentSchemaHsqlName() {
+        return currentSchema;
+    }
+
+// session tables
+    HashMappedList sessionTables;
+
+    public void addSessionTable(Table table) {
+
+        if (sessionTables == null) {
+            sessionTables = new HashMappedList();
+        }
+
+        if (sessionTables.containsKey(table.getName().name)) {
+            throw Error.error(ErrorCode.X_42504);
+        }
+
+        sessionTables.add(table.getName().name, table);
+    }
+
+    public void setSessionTables(Table[] tables) {}
+
+    public Table findSessionTable(String name) {
+
+        if (sessionTables == null) {
+            return null;
+        }
+
+        return (Table) sessionTables.get(name);
+    }
+
+    public void dropSessionTable(String name) {
+        sessionTables.remove(name);
+    }
+
+//
+    public int getResultMemoryRowCount() {
+        return resultMaxMemoryRows;
+    }
+
+    public void setResultMemoryRowCount(int count) {
+
+        if (database.logger.getTempDirectoryPath() != null) {
+            if (count < 0) {
+                count = 0;
+            }
+
+            resultMaxMemoryRows = count;
+        }
+    }
+
+    // warnings
+    HsqlDeque sqlWarnings;
+
+    public void addWarning(HsqlException warning) {
+
+        if (sqlWarnings == null) {
+            sqlWarnings = new HsqlDeque();
+        }
+
+        if (sqlWarnings.size() > 9) {
+            sqlWarnings.removeFirst();
+        }
+
+        int index = sqlWarnings.indexOf(warning);
+
+        if (index >= 0) {
+            sqlWarnings.remove(index);
+        }
+
+        sqlWarnings.add(warning);
+    }
+
+    public HsqlException[] getAndClearWarnings() {
+
+        if (sqlWarnings == null) {
+            return HsqlException.emptyArray;
+        }
+
+        HsqlException[] array = new HsqlException[sqlWarnings.size()];
+
+        sqlWarnings.toArray(array);
+        sqlWarnings.clear();
+
+        return array;
+    }
+
+    public HsqlException getLastWarning() {
+
+        if (sqlWarnings == null || sqlWarnings.size() == 0) {
+            return null;
+        }
+
+        return (HsqlException) sqlWarnings.getLast();
+    }
+
+    public void clearWarnings() {
+
+        if (sqlWarnings != null) {
+            sqlWarnings.clear();
+        }
+    }
+
+    // session zone
+    Calendar calendar;
+
+    public Calendar getCalendar() {
+
+        if (calendar == null) {
+            if (zoneString == null) {
+                calendar = new GregorianCalendar();
+            } else {
+                TimeZone zone = TimeZone.getTimeZone(zoneString);
+
+                calendar = new GregorianCalendar(zone);
+            }
+        }
+
+        return calendar;
+    }
+
+    // services
+    Scanner          secondaryScanner;
+    SimpleDateFormat simpleDateFormat;
+    SimpleDateFormat simpleDateFormatGMT;
+    Random           randomGenerator = new Random();
+    long             seed            = -1;
+
+    //
+    public double random(long seed) {
+
+        if (this.seed != seed) {
+            randomGenerator.setSeed(seed);
+
+            this.seed = seed;
+        }
+
+        return randomGenerator.nextDouble();
+    }
+
+    public double random() {
+        return randomGenerator.nextDouble();
+    }
+
+    public Scanner getScanner() {
+
+        if (secondaryScanner == null) {
+            secondaryScanner = new Scanner();
+        }
+
+        return secondaryScanner;
+    }
+
+    // properties
+    HsqlProperties clientProperties;
+
+    public HsqlProperties getClientProperties() {
+
+        if (clientProperties == null) {
+            clientProperties = new HsqlProperties();
+
+            clientProperties.setProperty(
+                HsqlDatabaseProperties.jdbc_translate_dti_types,
+                database.getProperties().isPropertyTrue(
+                    HsqlDatabaseProperties.jdbc_translate_dti_types));
+        }
+
+        return clientProperties;
+    }
+
+    public SimpleDateFormat getSimpleDateFormatGMT() {
+
+        if (simpleDateFormatGMT == null) {
+            simpleDateFormatGMT = new SimpleDateFormat("MMMM", Locale.ENGLISH);
+
+            Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+
+            simpleDateFormatGMT.setCalendar(cal);
+        }
+
+        return simpleDateFormatGMT;
+    }
+
+    // SEQUENCE current values
+    void logSequences() {
+
+        OrderedHashSet set = sessionData.sequenceUpdateSet;
+
+        if (set == null || set.isEmpty()) {
+            return;
+        }
+
+        for (int i = 0, size = set.size(); i < size; i++) {
+            NumberSequence sequence = (NumberSequence) set.get(i);
+
+            database.logger.writeSequenceStatement(this, sequence);
+        }
+
+        sessionData.sequenceUpdateSet.clear();
+    }
+
+    //
+    static String getSavepointSQL(String name) {
+
+        StringBuffer sb = new StringBuffer(Tokens.T_SAVEPOINT);
+
+        sb.append(' ').append('"').append(name).append('"');
+
+        return sb.toString();
+    }
+
+    static String getSavepointRollbackSQL(String name) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_ROLLBACK).append(' ').append(Tokens.T_TO).append(
+            ' ');
+        sb.append(Tokens.T_SAVEPOINT).append(' ');
+        sb.append('"').append(name).append('"');
+
+        return sb.toString();
+    }
+
+    String getStartTransactionSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_START).append(' ').append(Tokens.T_TRANSACTION);
+
+        if (isolationLevel != isolationLevelDefault) {
+            sb.append(' ');
+            appendIsolationSQL(sb, isolationLevel);
+        }
+
+        return sb.toString();
+    }
+
+    String getTransactionIsolationSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_SET).append(' ').append(Tokens.T_TRANSACTION);
+        sb.append(' ');
+        appendIsolationSQL(sb, isolationLevel);
+
+        return sb.toString();
+    }
+
+    String getSessionIsolationSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_SET).append(' ').append(Tokens.T_SESSION);
+        sb.append(' ').append(Tokens.T_CHARACTERISTICS).append(' ');
+        sb.append(Tokens.T_AS).append(' ').append(Tokens.T_TRANSACTION).append(
+            ' ');
+        appendIsolationSQL(sb, isolationLevelDefault);
+
+        return sb.toString();
+    }
+
+    static void appendIsolationSQL(StringBuffer sb, int isolationLevel) {
+
+        sb.append(Tokens.T_ISOLATION).append(' ');
+        sb.append(Tokens.T_LEVEL).append(' ');
+        sb.append(getIsolationString(isolationLevel));
+    }
+
+    static String getIsolationString(int isolationLevel) {
+
+        switch (isolationLevel) {
+
+            case SessionInterface.TX_READ_UNCOMMITTED :
+            case SessionInterface.TX_READ_COMMITTED :
+                StringBuffer sb = new StringBuffer();
+
+                sb.append(Tokens.T_READ).append(' ');
+                sb.append(Tokens.T_COMMITTED);
+
+                return sb.toString();
+
+            case SessionInterface.TX_REPEATABLE_READ :
+            case SessionInterface.TX_SERIALIZABLE :
+            default :
+                return Tokens.T_SERIALIZABLE;
+        }
+    }
+
+    String getSetSchemaStatement() {
+        return "SET SCHEMA " + currentSchema.statementName;
+    }
+}
diff --git a/src/org/hsqldb/SessionContext.java b/src/org/hsqldb/SessionContext.java
new file mode 100644
index 0000000..c8570e0
--- /dev/null
+++ b/src/org/hsqldb/SessionContext.java
@@ -0,0 +1,233 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.RangeVariable.RangeIteratorBase;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.LongDeque;
+import org.hsqldb.navigator.RangeIterator;
+import org.hsqldb.store.ValuePool;
+
+/*
+ * Session execution context and temporary data structures
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class SessionContext {
+
+    Session session;
+
+    //
+    Boolean isAutoCommit;
+    Boolean isReadOnly;
+    Boolean noSQL;
+    int     currentMaxRows;
+
+    //
+    HashMappedList  sessionVariables;
+    RangeVariable[] sessionVariablesRange;
+
+    //
+    private HsqlArrayList stack;
+    public Object[]       routineArguments = ValuePool.emptyObjectArray;
+    public Object[]       routineVariables = ValuePool.emptyObjectArray;
+    Object[]              dynamicArguments = ValuePool.emptyObjectArray;
+    public int            depth;
+
+    //
+    HashMappedList savepoints;
+    LongDeque      savepointTimestamps;
+
+    // range variable data
+    RangeIterator[] rangeIterators;
+
+    //
+    public Statement currentStatement;
+
+    /**
+     * Reusable set of all FK constraints that have so far been enforced while
+     * a cascading insert or delete is in progress.
+     */
+    HashSet               constraintPath;
+    StatementResultUpdate rowUpdateStatement = new StatementResultUpdate();
+
+    /**
+     * Creates a new instance of CompiledStatementExecutor.
+     *
+     * @param session the context in which to perform the execution
+     */
+    SessionContext(Session session) {
+
+        this.session             = session;
+        rangeIterators           = new RangeIterator[4];
+        savepoints               = new HashMappedList(4);
+        savepointTimestamps      = new LongDeque();
+        sessionVariables         = new HashMappedList();
+        sessionVariablesRange    = new RangeVariable[1];
+        sessionVariablesRange[0] = new RangeVariable(sessionVariables, true);
+        isAutoCommit             = Boolean.FALSE;
+        isReadOnly               = Boolean.FALSE;
+        noSQL                    = Boolean.FALSE;
+    }
+
+    public void push() {
+
+        if (stack == null) {
+            stack = new HsqlArrayList(true);
+        }
+
+        stack.add(dynamicArguments);
+        stack.add(routineArguments);
+        stack.add(routineVariables);
+        stack.add(rangeIterators);
+        stack.add(savepoints);
+        stack.add(savepointTimestamps);
+        stack.add(isAutoCommit);
+        stack.add(isReadOnly);
+        stack.add(noSQL);
+        stack.add(ValuePool.getInt(currentMaxRows));
+
+        rangeIterators      = new RangeIterator[4];
+        savepoints          = new HashMappedList(4);
+        savepointTimestamps = new LongDeque();
+        isAutoCommit        = Boolean.FALSE;
+        currentMaxRows      = 0;
+
+        depth++;
+    }
+
+    public void pop() {
+
+        currentMaxRows = ((Integer) stack.remove(stack.size() - 1)).intValue();
+        noSQL               = (Boolean) stack.remove(stack.size() - 1);
+        isReadOnly          = (Boolean) stack.remove(stack.size() - 1);
+        isAutoCommit        = (Boolean) stack.remove(stack.size() - 1);
+        savepointTimestamps = (LongDeque) stack.remove(stack.size() - 1);
+        savepoints          = (HashMappedList) stack.remove(stack.size() - 1);
+        rangeIterators      = (RangeIterator[]) stack.remove(stack.size() - 1);
+        routineVariables    = (Object[]) stack.remove(stack.size() - 1);
+        routineArguments    = (Object[]) stack.remove(stack.size() - 1);
+        dynamicArguments    = (Object[]) stack.remove(stack.size() - 1);
+
+        depth--;
+    }
+
+    public void pushDynamicArguments(Object[] args) {
+
+        push();
+
+        dynamicArguments = args;
+    }
+
+    public void setDynamicArguments(Object[] args) {
+        dynamicArguments = args;
+    }
+
+    void clearStructures(StatementDMQL cs) {
+
+        int count = cs.rangeIteratorCount;
+
+        if (count > rangeIterators.length) {
+            count = rangeIterators.length;
+        }
+
+        for (int i = 0; i < count; i++) {
+            if (rangeIterators[i] != null) {
+                rangeIterators[i].reset();
+
+                rangeIterators[i] = null;
+            }
+        }
+    }
+
+    public RangeIteratorBase getCheckIterator(RangeVariable rangeVariable) {
+
+        RangeIterator it = rangeIterators[1];
+
+        if (it == null) {
+            it                = rangeVariable.getIterator(session);
+            rangeIterators[1] = it;
+        }
+
+        return (RangeIteratorBase) it;
+    }
+
+    public void setRangeIterator(RangeIterator iterator) {
+
+        int position = iterator.getRangePosition();
+
+        if (position >= rangeIterators.length) {
+            rangeIterators =
+                (RangeIterator[]) ArrayUtil.resizeArray(rangeIterators,
+                    position + 1);
+        }
+
+        rangeIterators[iterator.getRangePosition()] = iterator;
+    }
+
+    /**
+     * For cascade operations
+     */
+    public HashSet getConstraintPath() {
+
+        if (constraintPath == null) {
+            constraintPath = new HashSet();
+        } else {
+            constraintPath.clear();
+        }
+
+        return constraintPath;
+    }
+
+    public void addSessionVariable(ColumnSchema variable) {
+
+        int index = sessionVariables.size();
+
+        if (!sessionVariables.add(variable.getName().name, variable)) {
+            throw Error.error(ErrorCode.X_42504);
+        }
+
+        Object[] vars = new Object[sessionVariables.size()];
+
+        ArrayUtil.copyArray(routineVariables, vars, routineVariables.length);
+
+        routineVariables        = vars;
+        routineVariables[index] = variable.getDefaultValue(session);
+    }
+}
diff --git a/src/org/hsqldb/SessionData.java b/src/org/hsqldb/SessionData.java
new file mode 100644
index 0000000..5a2abc0
--- /dev/null
+++ b/src/org/hsqldb/SessionData.java
@@ -0,0 +1,526 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.io.InputStream;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.CountdownInputStream;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.LongKeyHashMap;
+import org.hsqldb.lib.LongKeyLongValueHashMap;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.ReaderInputStream;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.persist.DataFileCacheSession;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.persist.PersistentStoreCollectionSession;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultLob;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.LobData;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobDataID;
+
+/*
+ * Session semi-persistent data structures
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class SessionData {
+
+    private final Database           database;
+    private final Session            session;
+    PersistentStoreCollectionSession persistentStoreCollection;
+
+    // large results
+    LongKeyHashMap       resultMap;
+    DataFileCacheSession resultCache;
+
+    // VALUE
+    Object currentValue;
+
+    // SEQUENCE
+    HashMap        sequenceMap;
+    OrderedHashSet sequenceUpdateSet;
+
+    public SessionData(Database database, Session session) {
+
+        this.database = database;
+        this.session  = session;
+        persistentStoreCollection =
+            new PersistentStoreCollectionSession(session);
+    }
+
+    // transitional feature
+    public PersistentStore getRowStore(TableBase table) {
+
+        if (table.tableType == TableBase.SYSTEM_TABLE) {
+            if (session.isAdmin()) {
+                return table.store;
+            }
+
+            return persistentStoreCollection.getStore(table);
+        }
+
+        if (table.store != null) {
+            return table.store;
+        }
+
+        if (table.isSessionBased) {
+            return persistentStoreCollection.getStore(table);
+        }
+
+        return database.persistentStoreCollection.getStore(table);
+    }
+
+    public PersistentStore getSubqueryRowStore(TableBase table) {
+
+        PersistentStore store = persistentStoreCollection.getStore(table);
+
+        store.removeAll();
+
+        return store;
+    }
+
+    public PersistentStore getNewResultRowStore(TableBase table,
+            boolean isCached) {
+
+        try {
+            PersistentStore store = session.database.logger.newStore(session,
+                persistentStoreCollection, table, isCached);
+
+            return store;
+        } catch (HsqlException e) {}
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "SessionData");
+    }
+
+    // result
+    void setResultSetProperties(Result command, Result result) {
+
+        int required = command.rsProperties;
+        int returned = result.rsProperties;
+
+        if (required != returned) {
+            if (ResultProperties.isReadOnly(required)) {
+                returned = ResultProperties.addHoldable(returned,
+                        ResultProperties.isHoldable(required));
+            } else {
+                if (ResultProperties.isUpdatable(returned)) {
+                    if (ResultProperties.isHoldable(required)) {
+                        session.addWarning(Error.error(ErrorCode.W_36503));
+                    }
+                } else {
+                    returned = ResultProperties.addHoldable(returned,
+                            ResultProperties.isHoldable(required));
+
+                    session.addWarning(Error.error(ErrorCode.W_36502));
+                }
+            }
+
+            if (ResultProperties.isSensitive(required)) {
+                session.addWarning(Error.error(ErrorCode.W_36501));
+            }
+
+            returned = ResultProperties.addScrollable(returned,
+                    ResultProperties.isScrollable(required));
+            result.rsProperties = returned;
+        }
+    }
+
+    Result getDataResultHead(Result command, Result result,
+                             boolean isNetwork) {
+
+        int fetchSize = command.getFetchSize();
+
+        result.setResultId(session.actionTimestamp);
+
+        int required = command.rsProperties;
+        int returned = result.rsProperties;
+
+        if (required != returned) {
+            if (ResultProperties.isReadOnly(required)) {
+                returned = ResultProperties.addHoldable(returned,
+                        ResultProperties.isHoldable(required));
+            } else {
+                if (ResultProperties.isReadOnly(returned)) {
+                    returned = ResultProperties.addHoldable(returned,
+                            ResultProperties.isHoldable(required));
+
+                    // add warning for concurrency conflict
+                } else {
+                    if (session.isAutoCommit()) {
+                        returned = ResultProperties.addHoldable(returned,
+                                ResultProperties.isHoldable(required));
+                    } else {
+                        returned = ResultProperties.addHoldable(returned,
+                                false);
+                    }
+                }
+            }
+
+            returned = ResultProperties.addScrollable(returned,
+                    ResultProperties.isScrollable(required));
+            result.rsProperties = returned;
+        }
+
+        boolean hold = false;
+        boolean copy = false;
+
+        if (ResultProperties.isUpdatable(result.rsProperties)) {
+            hold = true;
+        }
+
+        if (isNetwork) {
+            if (fetchSize != 0
+                    && result.getNavigator().getSize() > fetchSize) {
+                copy = true;
+                hold = true;
+            }
+        } else {
+            if (!result.getNavigator().isMemory()) {
+                hold = true;
+            }
+        }
+
+        if (hold) {
+            if (resultMap == null) {
+                resultMap = new LongKeyHashMap();
+            }
+
+            resultMap.put(result.getResultId(), result);
+        }
+
+        if (copy) {
+            result = Result.newDataHeadResult(session, result, 0, fetchSize);
+        }
+
+        return result;
+    }
+
+    Result getDataResultSlice(long id, int offset, int count) {
+
+        RowSetNavigatorClient navigator = getRowSetSlice(id, offset, count);
+
+        return Result.newDataRowsResult(navigator);
+    }
+
+    Result getDataResult(long id) {
+
+        Result result = (Result) resultMap.get(id);
+
+        return result;
+    }
+
+    RowSetNavigatorClient getRowSetSlice(long id, int offset, int count) {
+
+        Result          result = (Result) resultMap.get(id);
+        RowSetNavigator source = result.getNavigator();
+
+        if (offset + count > source.getSize()) {
+            count = source.getSize() - offset;
+        }
+
+        return new RowSetNavigatorClient(source, offset, count);
+    }
+
+    public void closeNavigator(long id) {
+
+        Result result = (Result) resultMap.remove(id);
+
+        result.getNavigator().close();
+    }
+
+    public void closeAllNavigators() {
+
+        if (resultMap == null) {
+            return;
+        }
+
+        Iterator it = resultMap.values().iterator();
+
+        while (it.hasNext()) {
+            Result result = (Result) it.next();
+
+            result.getNavigator().close();
+        }
+
+        resultMap.clear();
+    }
+
+    public void closeAllTransactionNavigators() {
+
+        if (resultMap == null) {
+            return;
+        }
+
+        Iterator it = resultMap.values().iterator();
+
+        while (it.hasNext()) {
+            Result result = (Result) it.next();
+
+            if (!ResultProperties.isHoldable(result.rsProperties)) {
+                result.getNavigator().close();
+                it.remove();
+            }
+        }
+
+        resultMap.clear();
+    }
+
+    public DataFileCacheSession getResultCache() {
+
+        if (resultCache == null) {
+            String path = database.logger.getTempDirectoryPath();
+
+            if (path == null) {
+                return null;
+            }
+
+            try {
+                resultCache =
+                    new DataFileCacheSession(database,
+                                             path + "/session_"
+                                             + Long.toString(session.getId()));
+
+                resultCache.open(false);
+            } catch (Throwable t) {
+                return null;
+            }
+        }
+
+        return resultCache;
+    }
+
+    synchronized void closeResultCache() {
+
+        if (resultCache != null) {
+            try {
+                resultCache.close(false);
+            } catch (HsqlException e) {}
+
+            resultCache = null;
+        }
+    }
+
+    // lobs in results
+    LongKeyLongValueHashMap resultLobs = new LongKeyLongValueHashMap();
+
+    // lobs in transaction
+    boolean hasLobOps;
+
+    public void addToCreatedLobs(long lobID) {
+        hasLobOps = true;
+    }
+
+    public void adjustLobUsageCount(Object value, int adjust) {
+
+        if (session.isProcessingLog || session.isProcessingScript) {
+            return;
+        }
+
+        if (value == null) {
+            return;
+        }
+
+        database.lobManager.adjustUsageCount(((LobData) value).getId(),
+                                             adjust);
+
+        hasLobOps = true;
+    }
+
+    public void adjustLobUsageCount(TableBase table, Object[] data,
+                                    int adjust) {
+
+        if (!table.hasLobColumn) {
+            return;
+        }
+
+        if (session.isProcessingLog || session.isProcessingScript) {
+            return;
+        }
+
+        for (int j = 0; j < table.columnCount; j++) {
+            if (table.colTypes[j].isLobType()) {
+                Object value = data[j];
+
+                if (value == null) {
+                    continue;
+                }
+
+                database.lobManager.adjustUsageCount(((LobData) value).getId(),
+                                                     adjust);
+
+                hasLobOps = true;
+            }
+        }
+    }
+
+    /**
+     * allocate storage for a new LOB
+     */
+    public void allocateLobForResult(ResultLob result,
+                                     InputStream inputStream) {
+
+        long                 resultLobId = result.getLobID();
+        CountdownInputStream countStream;
+
+        switch (result.getSubType()) {
+
+            case ResultLob.LobResultTypes.REQUEST_CREATE_BYTES : {
+                long blobId;
+                long blobLength = result.getBlockLength();
+
+                if (inputStream == null) {
+                    blobId      = resultLobId;
+                    inputStream = result.getInputStream();
+                } else {
+                    BlobData blob = session.createBlob(blobLength);
+
+                    blobId = blob.getId();
+
+                    resultLobs.put(resultLobId, blobId);
+                }
+
+                countStream = new CountdownInputStream(inputStream);
+
+                countStream.setCount(blobLength);
+                database.lobManager.setBytesForNewBlob(
+                    blobId, countStream, result.getBlockLength());
+
+                break;
+            }
+            case ResultLob.LobResultTypes.REQUEST_CREATE_CHARS : {
+                long clobId;
+                long clobLength = result.getBlockLength();
+
+                if (inputStream == null) {
+                    clobId = resultLobId;
+
+                    if (result.getReader() != null) {
+                        inputStream =
+                            new ReaderInputStream(result.getReader());
+                    } else {
+                        inputStream = result.getInputStream();
+                    }
+                } else {
+                    ClobData clob = session.createClob(clobLength);
+
+                    clobId = clob.getId();
+
+                    resultLobs.put(resultLobId, clobId);
+                }
+
+                countStream = new CountdownInputStream(inputStream);
+
+                countStream.setCount(clobLength * 2);
+                database.lobManager.setCharsForNewClob(
+                    clobId, countStream, result.getBlockLength());
+
+                break;
+            }
+        }
+    }
+
+    public void registerLobForResult(Result result) {
+
+        RowSetNavigator navigator = result.getNavigator();
+
+        if (navigator == null) {
+            registerLobsForRow((Object[]) result.valueData);
+        } else {
+            while (navigator.next()) {
+                Object[] data = navigator.getCurrent();
+
+                registerLobsForRow(data);
+            }
+
+            navigator.reset();
+        }
+
+        resultLobs.clear();
+    }
+
+    private void registerLobsForRow(Object[] data) {
+
+        for (int i = 0; i < data.length; i++) {
+            if (data[i] instanceof BlobDataID) {
+                BlobData blob = (BlobDataID) data[i];
+                long     id   = resultLobs.get(blob.getId());
+
+                data[i] = database.lobManager.getBlob(id);
+            } else if (data[i] instanceof ClobDataID) {
+                ClobData clob = (ClobDataID) data[i];
+                long     id   = resultLobs.get(clob.getId());
+
+                data[i] = database.lobManager.getClob(id);
+            }
+        }
+    }
+
+    //
+    public void startRowProcessing() {
+
+        if (sequenceMap != null) {
+            sequenceMap.clear();
+        }
+    }
+
+    public Object getSequenceValue(NumberSequence sequence) {
+
+        if (sequenceMap == null) {
+            sequenceMap       = new HashMap();
+            sequenceUpdateSet = new OrderedHashSet();
+        }
+
+        HsqlName key   = sequence.getName();
+        Object   value = sequenceMap.get(key);
+
+        if (value == null) {
+            value = sequence.getValueObject();
+
+            sequenceMap.put(key, value);
+            sequenceUpdateSet.add(sequence);
+        }
+
+        return value;
+    }
+}
diff --git a/src/org/hsqldb/SessionInterface.java b/src/org/hsqldb/SessionInterface.java
new file mode 100644
index 0000000..960f5f3
--- /dev/null
+++ b/src/org/hsqldb/SessionInterface.java
@@ -0,0 +1,139 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.io.InputStream;
+import java.util.Calendar;
+
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultLob;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.TimestampData;
+
+/**
+ * Interface to Session and its remote proxy objects. Used by the
+ * implementations of JDBC interfaces to communicate with the database at
+ * the session level.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public interface SessionInterface {
+
+    int INFO_ID      = 0;                // used
+    int INFO_INTEGER = 1;                // used
+    int INFO_BOOLEAN = 2;                // used
+    int INFO_VARCHAR = 3;                // used
+    int INFO_LIMIT   = 4;
+
+    //
+    int INFO_ISOLATION           = 0;    // used
+    int INFO_AUTOCOMMIT          = 1;    // used
+    int INFO_CONNECTION_READONLY = 2;    // used
+    int INFO_CATALOG             = 3;    // used
+
+    //
+    int TX_READ_UNCOMMITTED = 1;
+    int TX_READ_COMMITTED   = 2;
+    int TX_REPEATABLE_READ  = 4;
+    int TX_SERIALIZABLE     = 8;
+
+    Result execute(Result r);
+
+    RowSetNavigatorClient getRows(long navigatorId, int offset, int size);
+
+    void closeNavigator(long id);
+
+    void close();
+
+    boolean isClosed();
+
+    boolean isReadOnlyDefault();
+
+    void setReadOnlyDefault(boolean readonly);
+
+    boolean isAutoCommit();
+
+    void setAutoCommit(boolean autoCommit);
+
+    int getIsolation();
+
+    void setIsolationDefault(int level);
+
+    void startPhasedTransaction();
+
+    void prepareCommit();
+
+    void commit(boolean chain);
+
+    void rollback(boolean chain);
+
+    void rollbackToSavepoint(String name);
+
+    void savepoint(String name);
+
+    void releaseSavepoint(String name);
+
+    void addWarning(HsqlException warning);
+
+    Object getAttribute(int id);
+
+    void setAttribute(int id, Object value);
+
+    long getId();
+
+    void resetSession();
+
+    String getInternalConnectionURL();
+
+    BlobDataID createBlob(long length);
+
+    ClobDataID createClob(long length);
+
+    void allocateResultLob(ResultLob result, InputStream dataInput);
+
+    Scanner getScanner();
+
+    Calendar getCalendar();
+
+    TimestampData getCurrentDate();
+
+    int getZoneSeconds();
+
+    int getStreamBlockSize();
+
+    HsqlProperties getClientProperties();
+}
diff --git a/src/org/hsqldb/SessionManager.java b/src/org/hsqldb/SessionManager.java
new file mode 100644
index 0000000..43743b8
--- /dev/null
+++ b/src/org/hsqldb/SessionManager.java
@@ -0,0 +1,279 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.LongKeyHashMap;
+import org.hsqldb.rights.User;
+
+/**
+ * Container that maintains a map of session id's to Session objects.
+ * Responsible for managing opening and closing of sessions.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class SessionManager {
+
+    long                   sessionIdCount = 0;
+    private LongKeyHashMap sessionMap     = new LongKeyHashMap();
+    private Session        sysSession;
+    private Session        sysLobSession;
+
+    /**
+     * @todo:
+     * Eliminate the Database-centric nature of SessionManager.
+     * e.g. Sessions should be able to migrate from one Database instance
+     * to another using session control language moderated by SessionManager
+     */
+
+    /**
+     * Constructs an new SessionManager handling the specified Database.
+     * Creates a SYS User.
+     */
+    public SessionManager(Database db) {
+
+        User sysUser = db.getUserManager().getSysUser();
+
+        sysSession = new Session(db, sysUser, false, false, sessionIdCount++,
+                                 null, 0);
+        sysLobSession = new Session(db, sysUser, true, false,
+                                    sessionIdCount++, null, 0);
+    }
+
+    /**
+     *  @todo:
+     * It should be possible to create an initially 'disconnected' Session that
+     * can execute general commands using a SessionCommandInterpreter.
+     *
+     * EXAMPLES: Open a Session to start a Server, add/remove
+     *          databases hosted by an existing Server, connect to a
+     *          Database...
+     *
+     * REQUIRES:  auth scheme independent of any particular Database instance
+     *           e.g. provide service to use /etc/passwd and /etc/groups,
+     *                JAAS-plugin, etc.
+     */
+
+    /**
+     * Binds the specified Session object into this SessionManager's active
+     * Session registry. This method is typically called internally as
+     * the final step, when a successful connection has been made.
+     *
+     * @param db the database to which the new Session is initially connected
+     * @param user the Session User
+     * @param readonly the ReadOnly attribute for the new Session
+     * @param forLog true when session is for reading a log
+     * @param timeZoneSeconds the session time zone second interval
+     * @return Session
+     */
+    public synchronized Session newSession(Database db, User user,
+                                           boolean readonly, boolean forLog,
+                                           String zoneString,
+                                           int timeZoneSeconds) {
+
+        Session s = new Session(db, user, !forLog, readonly, sessionIdCount,
+                                zoneString, timeZoneSeconds);
+
+        s.isProcessingLog = forLog;
+
+        sessionMap.put(sessionIdCount, s);
+
+        sessionIdCount++;
+
+        return s;
+    }
+
+    /**
+     * Retrieves a new SYS Session.
+     */
+    public Session getSysSessionForScript(Database db) {
+
+        Session session = new Session(db, db.getUserManager().getSysUser(),
+                                      false, false, 0, null, 0);
+
+        session.isProcessingScript = true;
+
+        return session;
+    }
+
+    public Session getSysLobSession() {
+        return sysLobSession;
+    }
+
+    /**
+     * Retrieves the common SYS Session.
+     */
+    public Session getSysSession() {
+
+        sysSession.currentSchema =
+            sysSession.database.schemaManager.getDefaultSchemaHsqlName();
+        sysSession.isProcessingScript = false;
+        sysSession.isProcessingLog    = false;
+
+        sysSession.setUser(sysSession.database.getUserManager().getSysUser());
+
+        return sysSession;
+    }
+
+    /**
+     * Retrieves the common SYS Session.
+     */
+    public Session getSysSession(String schema, User user) {
+
+        sysSession.currentSchema =
+            sysSession.database.schemaManager.getSchemaHsqlName(schema);
+        sysSession.isProcessingScript = false;
+        sysSession.isProcessingLog    = false;
+
+        sysSession.setUser(user);
+
+        return sysSession;
+    }
+
+    public Session newSysSession(HsqlName schema, User user) {
+
+        Session session = new Session(sysSession.database, user, false, false,
+                                      0, null, 0);
+
+        session.currentSchema = schema;
+
+        return session;
+    }
+
+    /**
+     * Closes all Sessions registered with this SessionManager.
+     */
+    public synchronized void closeAllSessions() {
+
+        // don't disconnect system user; need it to save database
+        Session[] sessions = getAllSessions();
+
+        for (int i = 0; i < sessions.length; i++) {
+            sessions[i].close();
+        }
+    }
+
+    /**
+     *  Removes the session from management and disconnects.
+     */
+    synchronized void removeSession(Session session) {
+        sessionMap.remove(session.getId());
+    }
+
+    /**
+     * Removes all Sessions registered with this SessionManager.
+     */
+    synchronized void clearAll() {
+        sessionMap.clear();
+    }
+
+    /**
+     * Returns true if no session exists beyond the sys session.
+     */
+    synchronized boolean isEmpty() {
+        return sessionMap.isEmpty();
+    }
+
+    /**
+     * Retrieves a list of the Sessions in this container that
+     * are visible to the specified Session, given the access rights of
+     * the Session User.
+     */
+    public synchronized Session[] getVisibleSessions(Session session) {
+        return session.isAdmin() ? getAllSessions()
+                                 : new Session[]{ session };
+    }
+
+    /**
+     * Retrieves the Session with the specified Session identifier or null
+     * if no such Session is registered with this SessionManager.
+     */
+    synchronized Session getSession(long id) {
+        return (Session) sessionMap.get(id);
+    }
+
+    public synchronized Session[] getAllSessions() {
+
+        Session[] sessions = new Session[sessionMap.size()];
+        Iterator  it       = sessionMap.values().iterator();
+
+        for (int i = 0; it.hasNext(); i++) {
+            sessions[i] = (Session) it.next();
+        }
+
+        return sessions;
+    }
+
+    public synchronized boolean isUserActive(String userName) {
+
+        Iterator it = sessionMap.values().iterator();
+
+        for (int i = 0; it.hasNext(); i++) {
+            Session session = (Session) it.next();
+
+            if (userName.equals(session.getUser().getNameString())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public synchronized void removeSchemaReference(Schema schema) {
+
+        Iterator it = sessionMap.values().iterator();
+
+        for (int i = 0; it.hasNext(); i++) {
+            Session session = (Session) it.next();
+
+            if (session.getCurrentSchemaHsqlName() == schema.getName()) {
+                session.resetSchema();
+            }
+        }
+    }
+
+    public synchronized void resetLoggedSchemas() {
+
+        Iterator it = sessionMap.values().iterator();
+
+        for (int i = 0; it.hasNext(); i++) {
+            Session session = (Session) it.next();
+
+            session.loggedSchema = null;
+        }
+
+        this.sysLobSession.loggedSchema = null;
+    }
+}
diff --git a/src/org/hsqldb/SetFunction.java b/src/org/hsqldb/SetFunction.java
new file mode 100644
index 0000000..d2411af
--- /dev/null
+++ b/src/org/hsqldb/SetFunction.java
@@ -0,0 +1,583 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.DTIType;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Implementation of SQL set functions (currently only aggregate functions).
+ * This reduces temporary Object creation by SUM and AVG functions for
+ * INTEGER and narrower types.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ *
+ */
+public class SetFunction implements Serializable {
+
+    private HashSet distinctValues;
+    private boolean isDistinct;
+
+    //
+    private int  setType;
+    private int  dataType;
+    private Type type;
+
+    //
+    private int count;
+
+    //
+    private boolean    hasNull;
+    private boolean    every = true;
+    private boolean    some  = false;
+    private long       currentLong;
+    private double     currentDouble;
+    private BigDecimal currentBigDecimal;
+    private Object     currentValue;
+
+    SetFunction(int setType, Type type, boolean isDistinct) {
+
+        this.setType = setType;
+        this.type    = type;
+
+        if (isDistinct) {
+            this.isDistinct = true;
+            distinctValues  = new HashSet();
+        }
+
+        if (setType == OpTypes.VAR_SAMP || setType == OpTypes.STDDEV_SAMP) {
+            this.sample = true;
+        }
+
+        if (type != null) {
+            dataType = type.typeCode;
+
+            if (type.isIntervalType()) {
+                dataType = Types.SQL_INTERVAL;
+            }
+        }
+    }
+
+    void add(Session session, Object item) {
+
+        if (item == null) {
+            hasNull = true;
+
+            return;
+        }
+
+        if (isDistinct && !distinctValues.add(item)) {
+            return;
+        }
+
+        count++;
+
+        switch (setType) {
+
+            case OpTypes.COUNT :
+                return;
+
+            case OpTypes.AVG :
+            case OpTypes.SUM : {
+                switch (dataType) {
+
+                    case Types.TINYINT :
+                    case Types.SQL_SMALLINT :
+                    case Types.SQL_INTEGER :
+                        currentLong += ((Number) item).intValue();
+
+                        return;
+
+                    case Types.SQL_INTERVAL :
+                        if (item instanceof IntervalSecondData) {
+                            addLong(((IntervalSecondData) item).units);
+
+                            currentLong += ((IntervalSecondData) item).nanos;
+
+                            if (Math.abs(currentLong)
+                                    >= DTIType.nanoScaleFactors[0]) {
+                                addLong(currentLong
+                                        / DTIType.nanoScaleFactors[0]);
+
+                                currentLong %= DTIType.nanoScaleFactors[0];
+                            }
+                        } else if (item instanceof IntervalMonthData) {
+                            addLong(((IntervalMonthData) item).units);
+                        }
+
+                        return;
+
+                    case Types.SQL_BIGINT :
+                        addLong(((Number) item).longValue());
+
+                        return;
+
+                    case Types.SQL_REAL :
+                    case Types.SQL_FLOAT :
+                    case Types.SQL_DOUBLE :
+                        currentDouble += ((Number) item).doubleValue();
+
+                        return;
+
+                    case Types.SQL_NUMERIC :
+                    case Types.SQL_DECIMAL :
+                        if (currentBigDecimal == null) {
+                            currentBigDecimal = (BigDecimal) item;
+                        } else {
+                            currentBigDecimal =
+                                currentBigDecimal.add((BigDecimal) item);
+                        }
+
+                        return;
+
+                    default :
+                        throw Error.error(ErrorCode.X_42563);
+                }
+            }
+            case OpTypes.MIN : {
+                if (currentValue == null) {
+                    currentValue = item;
+
+                    return;
+                }
+
+                if (type.compare(session, currentValue, item) > 0) {
+                    currentValue = item;
+                }
+
+                return;
+            }
+            case OpTypes.MAX : {
+                if (currentValue == null) {
+                    currentValue = item;
+
+                    return;
+                }
+
+                if (type.compare(session, currentValue, item) < 0) {
+                    currentValue = item;
+                }
+
+                return;
+            }
+            case OpTypes.EVERY :
+                if (!(item instanceof Boolean)) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                every = every && ((Boolean) item).booleanValue();
+
+                return;
+
+            case OpTypes.SOME :
+                if (!(item instanceof Boolean)) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+
+                some = some || ((Boolean) item).booleanValue();
+
+                return;
+
+            case OpTypes.STDDEV_POP :
+            case OpTypes.STDDEV_SAMP :
+            case OpTypes.VAR_POP :
+            case OpTypes.VAR_SAMP :
+                addDataPoint((Number) item);
+
+                return;
+
+            case OpTypes.USER_AGGREGATE :
+                currentValue = item;
+                return;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SetFunction");
+        }
+    }
+
+    Object getValue(Session session) {
+
+        if (hasNull) {
+            session.addWarning(Error.error(ErrorCode.W_01003));
+        }
+
+        if (setType == OpTypes.COUNT) {
+            return ValuePool.getInt(count);
+        }
+
+        if (count == 0) {
+            return null;
+        }
+
+        switch (setType) {
+
+            case OpTypes.AVG : {
+                switch (dataType) {
+
+                    case Types.TINYINT :
+                    case Types.SQL_SMALLINT :
+                    case Types.SQL_INTEGER :
+                        return new Long(currentLong / count);
+
+                    case Types.SQL_BIGINT : {
+                        long value = getLongSum().divide(
+                            BigInteger.valueOf(count)).longValue();
+
+                        return new Long(value);
+                    }
+                    case Types.SQL_REAL :
+                    case Types.SQL_FLOAT :
+                    case Types.SQL_DOUBLE :
+                        return new Double(currentDouble / count);
+
+                    case Types.SQL_NUMERIC :
+                    case Types.SQL_DECIMAL :
+                        return currentBigDecimal.divide(new BigDecimal(count),
+                                                        BigDecimal.ROUND_DOWN);
+
+                    case Types.SQL_INTERVAL : {
+                        BigInteger bi =
+                            getLongSum().divide(BigInteger.valueOf(count));
+
+                        if (!NumberType.isInLongLimits(bi)) {
+                            throw Error.error(ErrorCode.X_22015);
+                        }
+
+                        if (((IntervalType) type).isDaySecondIntervalType()) {
+                            return new IntervalSecondData(bi.longValue(),
+                                                          currentLong,
+                                                          (IntervalType) type,
+                                                          true);
+                        } else {
+                            return IntervalMonthData.newIntervalMonth(
+                                bi.longValue(), (IntervalType) type);
+                        }
+                    }
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "SetFunction");
+                }
+            }
+            case OpTypes.SUM : {
+                switch (dataType) {
+
+                    case Types.TINYINT :
+                    case Types.SQL_SMALLINT :
+                    case Types.SQL_INTEGER :
+                        return new Long(currentLong);
+
+                    case Types.SQL_BIGINT :
+                        return new BigDecimal(getLongSum());
+
+                    case Types.SQL_REAL :
+                    case Types.SQL_FLOAT :
+                    case Types.SQL_DOUBLE :
+                        return new Double(currentDouble);
+
+                    case Types.SQL_NUMERIC :
+                    case Types.SQL_DECIMAL :
+                        return currentBigDecimal;
+
+                    case Types.SQL_INTERVAL : {
+                        BigInteger bi = getLongSum();
+
+                        if (!NumberType.isInLongLimits(bi)) {
+                            throw Error.error(ErrorCode.X_22015);
+                        }
+
+                        if (((IntervalType) type).isDaySecondIntervalType()) {
+                            return new IntervalSecondData(bi.longValue(),
+                                                          currentLong,
+                                                          (IntervalType) type,
+                                                          true);
+                        } else {
+                            return IntervalMonthData.newIntervalMonth(
+                                bi.longValue(), (IntervalType) type);
+                        }
+                    }
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "SetFunction");
+                }
+            }
+            case OpTypes.MIN :
+            case OpTypes.MAX :
+                return currentValue;
+
+            case OpTypes.EVERY :
+                return every ? Boolean.TRUE
+                             : Boolean.FALSE;
+
+            case OpTypes.SOME :
+                return some ? Boolean.TRUE
+                            : Boolean.FALSE;
+
+            case OpTypes.STDDEV_POP :
+            case OpTypes.STDDEV_SAMP :
+                return getStdDev();
+
+            case OpTypes.VAR_POP :
+            case OpTypes.VAR_SAMP :
+                return getVariance();
+
+            case OpTypes.USER_AGGREGATE :
+                return currentValue;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SetFunction");
+        }
+    }
+
+    /**
+     * During parsing and before an instance of SetFunction is created,
+     * getType is called with type parameter set to correct type when main
+     * SELECT statements contain aggregates.
+     *
+     */
+    static Type getType(int setType, Type type) {
+
+        if (setType == OpTypes.COUNT) {
+            return Type.SQL_INTEGER;
+        }
+
+        int dataType = type.isIntervalType() ? Types.SQL_INTERVAL
+                                             : type.typeCode;
+
+        switch (setType) {
+
+            case OpTypes.AVG : {
+                switch (dataType) {
+
+                    case Types.TINYINT :
+                    case Types.SQL_SMALLINT :
+                    case Types.SQL_INTEGER :
+                    case Types.SQL_BIGINT :
+                    case Types.SQL_REAL :
+                    case Types.SQL_FLOAT :
+                    case Types.SQL_DOUBLE :
+                    case Types.SQL_NUMERIC :
+                    case Types.SQL_DECIMAL :
+                    case Types.SQL_INTERVAL :
+                        return type;
+
+                    default :
+                        throw Error.error(ErrorCode.X_42563);
+                }
+            }
+            case OpTypes.SUM : {
+                switch (dataType) {
+
+                    case Types.TINYINT :
+                    case Types.SQL_SMALLINT :
+                    case Types.SQL_INTEGER :
+                        return Type.SQL_BIGINT;
+
+                    case Types.SQL_BIGINT :
+                        return Type.SQL_DECIMAL_BIGINT_SQR;
+
+                    case Types.SQL_REAL :
+                    case Types.SQL_FLOAT :
+                    case Types.SQL_DOUBLE :
+                        return Type.SQL_DOUBLE;
+
+                    case Types.SQL_NUMERIC :
+                    case Types.SQL_DECIMAL :
+                        return Type.getType(type.typeCode, 0,
+                                            type.precision * 2, type.scale);
+
+                    case Types.SQL_INTERVAL :
+                        return IntervalType.newIntervalType(
+                            type.typeCode, DTIType.maxIntervalPrecision,
+                            type.scale);
+
+                    default :
+                        throw Error.error(ErrorCode.X_42563);
+                }
+            }
+            case OpTypes.MIN :
+            case OpTypes.MAX :
+                if (type.isArrayType() || type.isLobType()) {
+                    throw Error.error(ErrorCode.X_42563);
+                }
+                return type;
+
+            case OpTypes.EVERY :
+            case OpTypes.SOME :
+                if (type.isBooleanType()) {
+                    return Type.SQL_BOOLEAN;
+                }
+                break;
+
+            case OpTypes.STDDEV_POP :
+            case OpTypes.STDDEV_SAMP :
+            case OpTypes.VAR_POP :
+            case OpTypes.VAR_SAMP :
+                if (type.isNumberType()) {
+                    return Type.SQL_DOUBLE;
+                }
+                break;
+
+            case OpTypes.USER_AGGREGATE :
+                return type;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "SetFunction");
+        }
+
+        throw Error.error(ErrorCode.X_42563);
+    }
+
+    // long sum - originally a separate class
+
+    /**
+     * Maintain the sum of multiple long values without creating a new
+     * BigInteger object for each addition.
+     */
+    static final BigInteger multiplier =
+        BigInteger.valueOf(0x0000000100000000L);
+
+//        BigInteger bigint = BigInteger.ZERO;
+    long hi;
+    long lo;
+
+    void addLong(long value) {
+
+        if (value == 0) {}
+        else if (value > 0) {
+            hi += value >> 32;
+            lo += value & 0x00000000ffffffffL;
+        } else {
+            if (value == Long.MIN_VALUE) {
+                hi -= 0x000000080000000L;
+            } else {
+                long temp = ~value + 1;
+
+                hi -= temp >> 32;
+                lo -= temp & 0x00000000ffffffffL;
+            }
+        }
+
+//            bigint = bigint.add(BigInteger.valueOf(value));
+    }
+
+    BigInteger getLongSum() {
+
+        BigInteger biglo  = BigInteger.valueOf(lo);
+        BigInteger bighi  = BigInteger.valueOf(hi);
+        BigInteger result = (bighi.multiply(multiplier)).add(biglo);
+
+/*
+            if ( result.compareTo(bigint) != 0 ){
+                 throw Trace.error(Trace.GENERAL_ERROR, "longSum mismatch");
+            }
+*/
+        return result;
+    }
+
+    // end long sum
+    // statistics support - written by Campbell
+    // this section was orginally an independent class
+    private double  sk;
+    private double  vk;
+    private long    n;
+    private boolean initialized;
+    private boolean sample;
+
+    private void addDataPoint(Number x) {    // optimized
+
+        double xi;
+        double xsi;
+        long   nm1;
+
+        if (x == null) {
+            return;
+        }
+
+        xi = x.doubleValue();
+
+        if (!initialized) {
+            n           = 1;
+            sk          = xi;
+            vk          = 0.0;
+            initialized = true;
+
+            return;
+        }
+
+        n++;
+
+        nm1 = (n - 1);
+        xsi = (sk - (xi * nm1));
+        vk  += ((xsi * xsi) / n) / nm1;
+        sk  += xi;
+    }
+
+    private Number getVariance() {
+
+        if (!initialized) {
+            return null;
+        }
+
+        return sample ? (n == 1) ? null    // NULL (not NaN) is correct in this case
+                                 : new Double(vk / (double) (n - 1))
+                      : new Double(vk / (double) (n));
+    }
+
+    private Number getStdDev() {
+
+        if (!initialized) {
+            return null;
+        }
+
+        return sample ? (n == 1) ? null    // NULL (not NaN) is correct in this case
+                                 : new Double(Math.sqrt(vk / (double) (n - 1)))
+                      : new Double(Math.sqrt(vk / (double) (n)));
+    }
+
+    // end statistics support
+}
diff --git a/src/org/hsqldb/SortAndSlice.java b/src/org/hsqldb/SortAndSlice.java
new file mode 100644
index 0000000..d963789
--- /dev/null
+++ b/src/org/hsqldb/SortAndSlice.java
@@ -0,0 +1,322 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.types.Type;
+
+/*
+ * Implementation of ORDER BY and LIMIT properties of query expressions.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+public final class SortAndSlice {
+
+    final static SortAndSlice noSort = new SortAndSlice();
+
+    //
+    public int[]     sortOrder;
+    public boolean[] sortDescending;
+    public boolean[] sortNullsLast;
+    boolean          sortUnion;
+    HsqlArrayList    exprList = new HsqlArrayList();
+    Expression       limitCondition;
+    int              columnCount;
+    boolean          hasNullsLast;
+    public boolean   skipSort       = false;    // true when result can be used as is
+    public boolean   skipFullResult = false;    // true when result can be sliced as is
+    int[]          columnIndexes;
+    public Index   index;
+    public boolean isGenerated;
+
+    SortAndSlice() {}
+
+    public boolean hasOrder() {
+        return exprList.size() != 0;
+    }
+
+    public boolean hasLimit() {
+        return limitCondition != null;
+    }
+
+    public int getOrderLength() {
+        return exprList.size();
+    }
+
+    public void addOrderExpression(Expression e) {
+        exprList.add(e);
+    }
+
+    public void addLimitCondition(Expression expression) {
+        limitCondition = expression;
+    }
+
+    public void prepare(QuerySpecification select) {
+
+        columnCount = exprList.size();
+
+        if (columnCount == 0) {
+            return;
+        }
+
+        sortOrder      = new int[columnCount];
+        sortDescending = new boolean[columnCount];
+        sortNullsLast  = new boolean[columnCount];
+
+        for (int i = 0; i < columnCount; i++) {
+            ExpressionOrderBy sort = (ExpressionOrderBy) exprList.get(i);
+
+            if (sort.getLeftNode().queryTableColumnIndex == -1) {
+                sortOrder[i] = select.indexStartOrderBy + i;
+            } else {
+                sortOrder[i] = sort.getLeftNode().queryTableColumnIndex;
+            }
+
+            sortDescending[i] = sort.isDescending();
+            sortNullsLast[i]  = sort.isNullsLast();
+            hasNullsLast      |= sortNullsLast[i];
+        }
+
+        if (select == null || hasNullsLast) {
+            return;
+        }
+
+        if (select.isDistinctSelect || select.isGrouped
+                || select.isAggregated) {
+            return;
+        }
+
+        int[] colIndexes = new int[columnCount];
+
+        for (int i = 0; i < columnCount; i++) {
+            Expression e = ((Expression) exprList.get(i)).getLeftNode();
+
+            if (e.getType() != OpTypes.COLUMN) {
+                return;
+            }
+
+            if (((ExpressionColumn) e).getRangeVariable()
+                    != select.rangeVariables[0]) {
+                return;
+            }
+
+            colIndexes[i] = e.columnIndex;
+        }
+
+        this.columnIndexes = colIndexes;
+    }
+
+    void setSortRange(QuerySpecification select) {
+
+        if (isGenerated) {
+            return;
+        }
+
+        if (columnCount == 0) {
+            if (limitCondition == null) {
+                return;
+            }
+
+            if (select.isDistinctSelect || select.isGrouped
+                    || select.isAggregated) {
+                return;
+            }
+
+            skipFullResult = true;
+
+            return;
+        }
+
+        for (int i = 0; i < columnCount; i++) {
+            ExpressionOrderBy sort     = (ExpressionOrderBy) exprList.get(i);
+            Type              dataType = sort.getLeftNode().getDataType();
+
+            if (dataType.isArrayType() || dataType.isLobType()) {
+                throw Error.error(ErrorCode.X_42534);
+            }
+        }
+
+        if (columnIndexes == null) {
+            return;
+        }
+
+        int[] colIndexes;
+        Index rangeIndex = select.rangeVariables[0].getSortIndex();
+
+        if (rangeIndex == null) {
+            return;
+        }
+
+        colIndexes = rangeIndex.getColumns();
+
+        int     count         = ArrayUtil.countTrueElements(sortDescending);
+        boolean allDescending = count == columnCount;
+
+        if (!allDescending && count > 0) {
+            return;
+        }
+
+        if (!select.rangeVariables[0].hasIndexCondition()) {
+            Table table = select.rangeVariables[0].getTable();
+            Index index = table.getFullIndexForColumns(columnIndexes);
+
+            if (index != null) {
+                if (select.rangeVariables[0].setSortIndex(index,
+                        allDescending)) {
+                    skipSort       = true;
+                    skipFullResult = true;
+                }
+            }
+        } else if (ArrayUtil.haveEqualArrays(columnIndexes, colIndexes,
+                                             columnIndexes.length)) {
+            if (allDescending) {
+                boolean reversed = select.rangeVariables[0].reverseOrder();
+
+                if (!reversed) {
+                    return;
+                }
+            }
+
+            skipSort       = true;
+            skipFullResult = true;
+        }
+    }
+
+    public boolean prepareSpecial(Session session, QuerySpecification select) {
+
+        Expression e      = select.exprColumns[select.indexStartAggregates];
+        int        opType = e.getType();
+
+        e = e.getLeftNode();
+
+        if (e.getType() != OpTypes.COLUMN) {
+            return false;
+        }
+
+        if (((ExpressionColumn) e).getRangeVariable()
+                != select.rangeVariables[0]) {
+            return false;
+        }
+
+        Index rangeIndex = select.rangeVariables[0].getSortIndex();
+
+        if (rangeIndex == null) {
+            return false;
+        }
+
+        int[] colIndexes = rangeIndex.getColumns();
+
+        if (select.rangeVariables[0].hasIndexCondition()) {
+            if (colIndexes[0] != ((ExpressionColumn) e).getColumnIndex()) {
+                return false;
+            }
+
+            if (opType == OpTypes.MAX) {
+                select.rangeVariables[0].reverseOrder();
+            }
+        } else {
+            Table table = select.rangeVariables[0].getTable();
+            Index index = table.getIndexForColumn(
+                session, ((ExpressionColumn) e).getColumnIndex());
+
+            if (index == null) {
+                return false;
+            }
+
+            if (!select.rangeVariables[0].setSortIndex(index,
+                    opType == OpTypes.MAX)) {
+                return false;
+            }
+        }
+
+        columnCount      = 1;
+        sortOrder        = new int[columnCount];
+        sortDescending   = new boolean[columnCount];
+        sortNullsLast    = new boolean[columnCount];
+        columnIndexes    = new int[columnCount];
+        columnIndexes[0] = e.columnIndex;
+        skipSort         = true;
+        skipFullResult   = true;
+
+        return true;
+    }
+
+    public int getLimitStart(Session session) {
+
+        if (limitCondition != null) {
+            Integer limit =
+                (Integer) limitCondition.getLeftNode().getValue(session);
+
+            if (limit != null) {
+                return limit.intValue();
+            }
+        }
+
+        return 0;
+    }
+
+    public int getLimitCount(Session session, int rowCount) {
+
+        int limitCount = 0;
+
+        if (limitCondition != null) {
+            Integer limit =
+                (Integer) limitCondition.getRightNode().getValue(session);
+
+            if (limit != null) {
+                limitCount = limit.intValue();
+            }
+        }
+
+        if (rowCount != 0 && (limitCount == 0 || rowCount < limitCount)) {
+            limitCount = rowCount;
+        }
+
+        return limitCount;
+    }
+
+    public void setIndex(Session session, TableBase table) {
+
+        try {
+            index = table.createAndAddIndexStructure(session, null, sortOrder,
+                    sortDescending, sortNullsLast, false, false, false);
+        } catch (Throwable t) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "SortAndSlice");
+        }
+    }
+}
diff --git a/src/org/hsqldb/SqlInvariants.java b/src/org/hsqldb/SqlInvariants.java
new file mode 100644
index 0000000..0baf4ce
--- /dev/null
+++ b/src/org/hsqldb/SqlInvariants.java
@@ -0,0 +1,273 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.Charset;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+import org.hsqldb.types.UserTypeModifier;
+
+/**
+ * Invariant schema objects.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class SqlInvariants {
+
+    /**
+     * The role name reserved for authorization of INFORMATION_SCHEMA and
+     * system objects.
+     */
+    public static final String SYSTEM_AUTHORIZATION_NAME = "_SYSTEM";
+
+    /** The role name reserved for ADMIN users. */
+    public static final String DBA_ADMIN_ROLE_NAME = "DBA";
+
+    /** The role name allowing schema creation for users. */
+    public static final String SCHEMA_CREATE_ROLE_NAME = "CREATE_SCHEMA";
+
+    /** The role name allowing switching authorisation for users. */
+    public static final String CHANGE_AUTH_ROLE_NAME = "CHANGE_AUTHORIZATION";
+
+    //
+    public static final String SYSTEM_SUBQUERY = "SYSTEM_SUBQUERY";
+
+    /** The role name reserved for the special PUBLIC pseudo-user. */
+    public static final String   PUBLIC_ROLE_NAME   = "PUBLIC";
+    public static final String   SYSTEM_SCHEMA      = "SYSTEM_SCHEMA";
+    public static final String   LOBS_SCHEMA        = "SYSTEM_LOBS";
+    public static final String   DEFINITION_SCHEMA  = "DEFINITION_SCHEMA";
+    public static final String   INFORMATION_SCHEMA = "INFORMATION_SCHEMA";
+    public static final String   SQLJ_SCHEMA        = "SQLJ";
+    public static final String   PUBLIC_SCHEMA      = "PUBLIC";
+    public static final String   CLASSPATH_NAME     = "CLASSPATH";
+    public static final String   MODULE             = "MODULE";
+    public static final HsqlName INFORMATION_SCHEMA_HSQLNAME;
+    public static final HsqlName SYSTEM_SCHEMA_HSQLNAME;
+    public static final HsqlName LOBS_SCHEMA_HSQLNAME;
+    public static final HsqlName SQLJ_SCHEMA_HSQLNAME;
+    public static final HsqlName SYSTEM_SUBQUERY_HSQLNAME;
+    public static final HsqlName MODULE_HSQLNAME;
+
+    static {
+        INFORMATION_SCHEMA_HSQLNAME =
+            HsqlNameManager.newSystemObjectName(INFORMATION_SCHEMA,
+                SchemaObject.SCHEMA);
+        SYSTEM_SCHEMA_HSQLNAME =
+            HsqlNameManager.newSystemObjectName(SYSTEM_SCHEMA,
+                SchemaObject.SCHEMA);
+        LOBS_SCHEMA_HSQLNAME = HsqlNameManager.newSystemObjectName(LOBS_SCHEMA,
+                SchemaObject.SCHEMA);
+        SQLJ_SCHEMA_HSQLNAME = HsqlNameManager.newSystemObjectName(SQLJ_SCHEMA,
+                SchemaObject.SCHEMA);
+        SYSTEM_SUBQUERY_HSQLNAME =
+            HsqlNameManager.newSystemObjectName(SYSTEM_SUBQUERY,
+                SchemaObject.TABLE);
+        MODULE_HSQLNAME =
+            HsqlNameManager.newSystemObjectName(MODULE, SchemaObject.SCHEMA);
+
+        SYSTEM_SUBQUERY_HSQLNAME.setSchemaIfNull(SYSTEM_SCHEMA_HSQLNAME);
+    }
+
+    public static final Charset SQL_TEXT;
+    public static final Charset SQL_IDENTIFIER_CHARSET;
+    public static final Charset SQL_CHARACTER;
+    public static final Charset ASCII_GRAPHIC;    // == GRAPHIC_IRV
+    public static final Charset GRAPHIC_IRV;
+    public static final Charset ASCII_FULL;       // == ISO8BIT
+    public static final Charset ISO8BIT;
+    public static final Charset LATIN1;
+    public static final Charset UTF32;
+    public static final Charset UTF16;
+    public static final Charset UTF8;
+
+    static {
+        HsqlName name;
+
+        name = HsqlNameManager.newInfoSchemaObjectName("SQL_TEXT", false,
+                SchemaObject.CHARSET);
+        SQL_TEXT = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("SQL_IDENTIFIER",
+                false, SchemaObject.CHARSET);
+        SQL_IDENTIFIER_CHARSET = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("SQL_CHARACTER", false,
+                SchemaObject.CHARSET);
+        SQL_CHARACTER = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("LATIN1", false,
+                SchemaObject.CHARSET);
+        LATIN1 = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("ASCII_GRAPHIC", false,
+                SchemaObject.CHARSET);
+        ASCII_GRAPHIC = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("GRAPHIC_IRV", false,
+                SchemaObject.CHARSET);
+        GRAPHIC_IRV = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("ASCII_FULL", false,
+                SchemaObject.CHARSET);
+        ASCII_FULL = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("ISO8BIT", false,
+                SchemaObject.CHARSET);
+        ISO8BIT = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("UTF32", false,
+                SchemaObject.CHARSET);
+        UTF32 = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("UTF16", false,
+                SchemaObject.CHARSET);
+        UTF16 = new Charset(name);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("UTF8", false,
+                SchemaObject.CHARSET);
+        UTF8 = new Charset(name);
+        /*
+         * Foundattion 4.2.1
+         * Character sets defined by standards or by SQL-implementations reside
+         * in the Information Schema (named INFORMATION_SCHEMA) in each catalog,
+         * as do collations defined by standards and collations,
+         * transliterations, and transcodings defined by SQL implementations.
+         */
+    }
+
+    public static final Type CARDINAL_NUMBER;
+    public static final Type YES_OR_NO;
+    public static final Type CHARACTER_DATA;
+    public static final Type SQL_IDENTIFIER;
+    public static final Type TIME_STAMP;
+
+    static {
+        HsqlName name;
+
+        name = HsqlNameManager.newInfoSchemaObjectName("CARDINAL_NUMBER",
+                false, SchemaObject.DOMAIN);
+        CARDINAL_NUMBER = new NumberType(Types.SQL_BIGINT, 0, 0);
+        CARDINAL_NUMBER.userTypeModifier = new UserTypeModifier(name,
+                SchemaObject.DOMAIN, CARDINAL_NUMBER);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("YES_OR_NO", false,
+                SchemaObject.DOMAIN);
+        YES_OR_NO = new CharacterType(Types.SQL_VARCHAR, 3);
+        YES_OR_NO.userTypeModifier = new UserTypeModifier(name,
+                SchemaObject.DOMAIN, YES_OR_NO);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("CHARACTER_DATA",
+                false, SchemaObject.DOMAIN);
+        CHARACTER_DATA = new CharacterType(Types.SQL_VARCHAR, (1 << 16));
+        CHARACTER_DATA.userTypeModifier = new UserTypeModifier(name,
+                SchemaObject.DOMAIN, CHARACTER_DATA);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("SQL_IDENTIFIER",
+                false, SchemaObject.DOMAIN);
+        SQL_IDENTIFIER = new CharacterType(Types.SQL_VARCHAR, 128);
+        SQL_IDENTIFIER.userTypeModifier = new UserTypeModifier(name,
+                SchemaObject.DOMAIN, SQL_IDENTIFIER);
+
+        //
+        name = HsqlNameManager.newInfoSchemaObjectName("TIME_STAMP", false,
+                SchemaObject.DOMAIN);
+        TIME_STAMP = new DateTimeType(Types.SQL_TIMESTAMP,
+                                      Types.SQL_TIMESTAMP, 6);
+        TIME_STAMP.userTypeModifier = new UserTypeModifier(name,
+                SchemaObject.DOMAIN, TIME_STAMP);
+    }
+
+    public static final void checkSchemaNameNotSystem(String name) {
+
+        if (isSystemSchemaName(name)) {
+            throw Error.error(ErrorCode.X_42503, name);
+        }
+    }
+
+    public static final boolean isSystemSchemaName(String name) {
+
+        if (SqlInvariants.DEFINITION_SCHEMA.equals(name)
+                || SqlInvariants.INFORMATION_SCHEMA.equals(name)
+                || SqlInvariants.SYSTEM_SCHEMA.equals(name)
+                || SqlInvariants.SQLJ_SCHEMA.equals(name)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public static final boolean isLobsSchemaName(String name) {
+
+        if (SqlInvariants.LOBS_SCHEMA.equals(name)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public static final boolean isSchemaNameSystem(HsqlName name) {
+
+        if (name.schema != null) {
+            name = name.schema;
+        }
+
+        if (SqlInvariants.INFORMATION_SCHEMA_HSQLNAME.equals(name)
+                || SqlInvariants.SYSTEM_SCHEMA_HSQLNAME.equals(name)
+                || SqlInvariants.SQLJ_SCHEMA_HSQLNAME.equals(name)) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/Statement.java b/src/org/hsqldb/Statement.java
new file mode 100644
index 0000000..230a93e
--- /dev/null
+++ b/src/org/hsqldb/Statement.java
@@ -0,0 +1,237 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.result.ResultProperties;
+
+/**
+ * Base class for compiled statement objects.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public abstract class Statement {
+
+    final static int META_RESET_VIEWS      = 1;
+    final static int META_RESET_STATEMENTS = 2;
+
+    //
+    final static Statement[] emptyArray = new Statement[]{};
+
+    //
+    final int type;
+    int       group;
+    boolean   isLogged = true;
+    boolean   isValid  = true;
+
+    /** the default schema name used to resolve names in the sql */
+    HsqlName schemaName;
+
+    /** root in PSM */
+    Routine root;
+
+    /** parent in PSM */
+    StatementCompound parent;
+    boolean           isError;
+    boolean           isTransactionStatement;
+    boolean           isExplain;
+    int               metaDataImpact;
+
+    /** SQL string for the statement */
+    String sql;
+
+    /** id in StatementManager */
+    long id;
+
+    /** compileTimestamp */
+    long compileTimestamp;
+
+    /** table names read - for concurrency control */
+    HsqlName[] readTableNames = HsqlName.emptyArray;
+
+    /** table names written - for concurrency control */
+    HsqlName[] writeTableNames = HsqlName.emptyArray;;
+
+    //
+    OrderedHashSet references;
+
+    public abstract Result execute(Session session);
+
+    public void setParameters(ExpressionColumn[] params) {}
+
+    Statement(int type) {
+        this.type = type;
+    }
+
+    Statement(int type, int group) {
+        this.type  = type;
+        this.group = group;
+    }
+
+    public final boolean isError() {
+        return isError;
+    }
+
+    public boolean isTransactionStatement() {
+        return isTransactionStatement;
+    }
+
+    public boolean isAutoCommitStatement() {
+        return false;
+    }
+
+    public void setCompileTimestamp(long ts) {
+        compileTimestamp = ts;
+    }
+
+    public long getCompileTimestamp() {
+        return compileTimestamp;
+    }
+
+    public final void setSQL(String sql) {
+        this.sql = sql;
+    }
+
+    public String getSQL() {
+        return sql;
+    }
+
+    public OrderedHashSet getReferences() {
+        return references;
+    }
+
+    public final void setDescribe() {
+        isExplain = true;
+    }
+
+    public abstract String describe(Session session);
+
+    public HsqlName getSchemaName() {
+        return schemaName;
+    }
+
+    public final void setSchemaHsqlName(HsqlName name) {
+        schemaName = name;
+    }
+
+    public final void setID(long csid) {
+        id = csid;
+    }
+
+    public final long getID() {
+        return id;
+    }
+
+    public final int getType() {
+        return type;
+    }
+
+    public final int getGroup() {
+        return group;
+    }
+
+    public final boolean isValid() {
+        return isValid;
+    }
+
+    public final boolean isLogged() {
+        return isLogged;
+    }
+
+    public void clearVariables() {}
+
+    public void resolve(Session session) {}
+
+    public RangeVariable[] getRangeVariables() {
+        return RangeVariable.emptyArray;
+    }
+
+    public final HsqlName[] getTableNamesForRead() {
+        return readTableNames;
+    }
+
+    public final HsqlName[] getTableNamesForWrite() {
+        return writeTableNames;
+    }
+
+    public boolean isCatalogChange() {
+
+        switch (group) {
+
+            case StatementTypes.X_SQL_SCHEMA_DEFINITION :
+            case StatementTypes.X_SQL_SCHEMA_MANIPULATION :
+            case StatementTypes.X_HSQLDB_SCHEMA_MANIPULATION :
+                return true;
+
+            case StatementTypes.X_HSQLDB_DATABASE_OPERATION :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    public void setParent(StatementCompound statement) {
+        this.parent = statement;
+    }
+
+    public void setRoot(Routine root) {
+        this.root = root;
+    }
+
+    public boolean hasGeneratedColumns() {
+        return false;
+    }
+
+    public ResultMetaData generatedResultMetaData() {
+        return null;
+    }
+
+    public void setGeneratedColumnInfo(int mode, ResultMetaData meta) {}
+
+    public ResultMetaData getResultMetaData() {
+        return ResultMetaData.emptyResultMetaData;
+    }
+
+    public ResultMetaData getParametersMetaData() {
+        return ResultMetaData.emptyParamMetaData;
+    }
+
+    public int getResultProperties() {
+        return ResultProperties.defaultPropsValue;
+    }
+}
diff --git a/src/org/hsqldb/StatementCommand.java b/src/org/hsqldb/StatementCommand.java
new file mode 100644
index 0000000..5d18f00
--- /dev/null
+++ b/src/org/hsqldb/StatementCommand.java
@@ -0,0 +1,829 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.rights.User;
+import org.hsqldb.scriptio.ScriptWriterText;
+
+/**
+ * Implementation of Statement for SQL commands.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementCommand extends Statement {
+
+    Expression[] expressions;
+    Object[]     parameters;
+
+    StatementCommand(int type, Object[] args) {
+        this(type, args, null, null);
+    }
+
+    StatementCommand(int type, Object[] args, HsqlName readName,
+                     HsqlName writeName) {
+
+        super(type);
+
+        this.isTransactionStatement = true;
+        this.parameters             = args;
+
+        if (readName != null && readName != writeName) {
+            this.readTableNames = new HsqlName[]{ readName };
+        }
+
+        if (writeName != null) {
+            this.writeTableNames = new HsqlName[]{ writeName };
+        }
+
+        switch (type) {
+
+            case StatementTypes.DATABASE_CHECKPOINT :
+                group    = StatementTypes.X_HSQLDB_DATABASE_OPERATION;
+                isLogged = false;
+                break;
+
+            case StatementTypes.DATABASE_BACKUP :
+            case StatementTypes.DATABASE_SCRIPT :
+                group    = StatementTypes.X_HSQLDB_DATABASE_OPERATION;
+                isLogged = false;
+                break;
+
+            case StatementTypes.SET_DATABASE_UNIQUE_NAME :
+            case StatementTypes.SET_DATABASE_FILES_WRITE_DELAY :
+            case StatementTypes.SET_DATABASE_FILES_TEMP_PATH :
+                this.isTransactionStatement = false;
+                group                       = StatementTypes.X_HSQLDB_SETTING;
+                break;
+
+//
+            case StatementTypes.SET_DATABASE_DEFAULT_INITIAL_SCHEMA :
+            case StatementTypes.SET_DATABASE_DEFAULT_TABLE_TYPE :
+            case StatementTypes.SET_DATABASE_FILES_CACHE_ROWS :
+            case StatementTypes.SET_DATABASE_FILES_CACHE_SIZE :
+            case StatementTypes.SET_DATABASE_FILES_SCALE :
+            case StatementTypes.SET_DATABASE_FILES_DEFRAG :
+            case StatementTypes.SET_DATABASE_FILES_EVENT_LOG :
+            case StatementTypes.SET_DATABASE_FILES_LOBS_SCALE :
+            case StatementTypes.SET_DATABASE_FILES_LOCK :
+            case StatementTypes.SET_DATABASE_FILES_LOG :
+            case StatementTypes.SET_DATABASE_FILES_LOG_SIZE :
+            case StatementTypes.SET_DATABASE_FILES_NIO :
+            case StatementTypes.SET_DATABASE_FILES_SCRIPT_FORMAT :
+            case StatementTypes.SET_DATABASE_PROPERTY :
+            case StatementTypes.SET_DATABASE_RESULT_MEMORY_ROWS :
+            case StatementTypes.SET_DATABASE_SQL_REFERENTIAL_INTEGRITY :
+            case StatementTypes.SET_DATABASE_SQL_STRICT_NAMES :
+            case StatementTypes.SET_DATABASE_SQL_STRICT_SIZE :
+            case StatementTypes.SET_DATABASE_SQL_REFERENCES :
+            case StatementTypes.SET_DATABASE_TRANSACTION_CONTROL :
+            case StatementTypes.SET_DATABASE_DEFAULT_ISOLATION_LEVEL :
+            case StatementTypes.SET_DATABASE_GC :
+
+//
+            case StatementTypes.SET_DATABASE_SQL_COLLATION :
+            case StatementTypes.SET_DATABASE_FILES_BACKUP_INCREMENT :
+            case StatementTypes.SET_DATABASE_SCRIPT_FORMAT :
+            case StatementTypes.SET_DATABASE_TEXT_SOURCE :
+                group                       = StatementTypes.X_HSQLDB_SETTING;
+                this.isTransactionStatement = true;
+                break;
+
+            case StatementTypes.SET_TABLE_SOURCE_HEADER :
+                isLogged = false;
+            case StatementTypes.SET_TABLE_SOURCE :
+                metaDataImpact              = Statement.META_RESET_VIEWS;
+                group = StatementTypes.X_HSQLDB_SCHEMA_MANIPULATION;
+                this.isTransactionStatement = true;
+                break;
+
+            case StatementTypes.SET_TABLE_READONLY :
+                metaDataImpact              = Statement.META_RESET_VIEWS;
+                group = StatementTypes.X_HSQLDB_SCHEMA_MANIPULATION;
+                this.isTransactionStatement = true;
+                break;
+
+            case StatementTypes.DATABASE_SHUTDOWN :
+                isLogged                    = false;
+                group = StatementTypes.X_HSQLDB_DATABASE_OPERATION;
+                this.isTransactionStatement = false;
+                break;
+
+            case StatementTypes.SET_TABLE_TYPE :
+                group = StatementTypes.X_HSQLDB_SCHEMA_MANIPULATION;
+                this.isTransactionStatement = true;
+                break;
+
+            case StatementTypes.SET_TABLE_INDEX :
+                group                       = StatementTypes.X_HSQLDB_SETTING;
+                this.isTransactionStatement = false;
+                isLogged                    = false;
+                break;
+
+            case StatementTypes.SET_USER_INITIAL_SCHEMA :
+            case StatementTypes.SET_USER_PASSWORD :
+                group                       = StatementTypes.X_HSQLDB_SETTING;
+                this.isTransactionStatement = false;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "StatementCommand");
+        }
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        try {
+            result = getResult(session);
+        } catch (Throwable t) {
+            result = Result.newErrorResult(t, null);
+        }
+
+        if (result.isError()) {
+            result.getException().setStatementType(group, type);
+
+            return result;
+        }
+
+        try {
+            if (isLogged) {
+                session.database.logger.writeToLog(session, sql);
+            }
+        } catch (Throwable e) {
+            return Result.newErrorResult(e, sql);
+        }
+
+        return result;
+    }
+
+    Result getResult(Session session) {
+
+        if (this.isExplain) {
+            return Result.newSingleColumnStringResult("OPERATION",
+                    describe(session));
+        }
+
+        switch (type) {
+
+            case StatementTypes.DATABASE_BACKUP : {
+                String  path       = ((String) parameters[0]);
+                boolean blocking   = ((Boolean) parameters[1]).booleanValue();
+                boolean script     = ((Boolean) parameters[2]).booleanValue();
+                boolean compressed = ((Boolean) parameters[3]).booleanValue();
+
+                try {
+                    session.checkAdmin();
+
+                    if (!session.database.getType().equals(
+                            DatabaseURL.S_FILE)) {
+
+                        // Do not enforce this constraint for SCRIPT type
+                        // backup.
+                        return Result.newErrorResult(
+                            Error.error(ErrorCode.DATABASE_IS_NON_FILE));
+
+                        // If we were to back up res: type DB's, could use
+                        // DatabasURL.isFileBasedDataType(), but I see no
+                        // point to back up one of these.
+                    }
+
+                    if (session.database.isReadOnly()) {
+
+                        // Do not enforce this constraint for SCRIPT type
+                        // backup.
+                        return Result.newErrorResult(
+                            Error.error(ErrorCode.DATABASE_IS_MEMORY_ONLY),
+                            null);
+                    }
+
+                    if (session.database.logger.isStoredFileAccess) {
+                        return Result.newErrorResult(
+                            Error.error(ErrorCode.DATABASE_IS_NON_FILE), null);
+                    }
+
+                    session.database.logger.backup(path,
+                                                   session.database.getPath(),
+                                                   script, blocking,
+                                                   compressed);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.DATABASE_CHECKPOINT : {
+                boolean defrag = ((Boolean) parameters[0]).booleanValue();
+
+                try {
+                    session.database.logger.checkpoint(defrag);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_BACKUP_INCREMENT : {
+                try {
+                    boolean mode = ((Boolean) parameters[0]).booleanValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setIncrementBackup(mode);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_CACHE_ROWS : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setCacheMaxRows(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_CACHE_SIZE : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setCacheSize(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_LOBS_SCALE : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    if (session.isProcessingScript) {
+                        session.database.logger.setLobFileScaleNoCheck(value);
+                    } else {
+                        session.database.logger.setLobFileScale(value);
+                    }
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_SCALE : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+
+                    if (session.isProcessingScript) {
+                        session.database.logger.setCacheFileScaleNoCheck(value);
+                    } else {
+                        session.database.logger.setCacheFileScale(value);
+                    }
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_DEFRAG : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setDefagLimit(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_EVENT_LOG : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setEventLogLevel(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_LOCK : {
+                try {
+
+                    // no-op - to remove from release version
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_NIO : {
+                try {
+                    boolean value = ((Boolean) parameters[0]).booleanValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setNioDataFile(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_LOG : {
+                try {
+                    boolean value = ((Boolean) parameters[0]).booleanValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setLogData(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_LOG_SIZE : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setLogSize(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_TEMP_PATH : {
+                try {
+                    String value = (String) parameters[0];
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+
+                    // no action
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_FILES_WRITE_DELAY : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setWriteDelay(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_SQL_COLLATION : {
+                try {
+                    String name = (String) parameters[0];
+
+                    /** @todo 1.9.0 - ensure no data in character columns */
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.collation.setCollation(name);
+                    session.database.schemaManager.setSchemaChangeTimestamp();
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_SQL_REFERENTIAL_INTEGRITY : {
+                boolean mode = ((Boolean) parameters[0]).booleanValue();
+
+                session.database.setReferentialIntegrity(mode);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_DATABASE_SQL_STRICT_NAMES : {
+                boolean mode = ((Boolean) parameters[0]).booleanValue();
+
+                session.database.setStrictNames(mode);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_DATABASE_SQL_STRICT_SIZE : {
+                boolean mode = ((Boolean) parameters[0]).booleanValue();
+
+                session.database.setStrictColumnSize(mode);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_DATABASE_SQL_REFERENCES : {
+                boolean mode = ((Boolean) parameters[0]).booleanValue();
+
+                session.database.setStrictReferences(mode);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_DATABASE_DEFAULT_INITIAL_SCHEMA : {
+                HsqlName schema = (HsqlName) parameters[0];
+
+                //
+                session.database.schemaManager.setDefaultSchemaHsqlName(
+                    schema);
+                session.database.schemaManager.setSchemaChangeTimestamp();
+
+                //
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_DATABASE_DEFAULT_TABLE_TYPE : {
+                Integer type = (Integer) parameters[0];
+
+                //
+                session.database.schemaManager.setDefaultTableType(
+                    type.intValue());
+
+                //
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_DATABASE_SCRIPT_FORMAT : {
+                try {
+                    int value = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.logger.setScriptType(value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_TRANSACTION_CONTROL : {
+                try {
+                    int mode = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.txManager.setTransactionControl(session,
+                            mode);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_DEFAULT_ISOLATION_LEVEL : {
+                try {
+                    int mode = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+
+                    session.database.defaultIsolationLevel = mode;
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_GC : {
+                try {
+                    int count = ((Integer) parameters[0]).intValue();
+
+                    session.checkAdmin();
+
+                    JavaSystem.gcFrequency = count;
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_PROPERTY : {
+                try {
+                    String property = (String) parameters[0];
+                    Object value    = parameters[1];
+
+                    // command is a no-op from 1.9
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+
+                    /*
+                    HsqlDatabaseProperties p =
+                        session.database.getProperties();
+
+                    p.setDatabaseProperty(property,
+                                          value.toString().toLowerCase());
+                    */
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_RESULT_MEMORY_ROWS : {
+                int size = ((Integer) parameters[0]).intValue();
+
+                session.database.getProperties().setProperty(
+                    HsqlDatabaseProperties.hsqldb_result_max_memory_rows,
+                    size);
+                session.database.setResultMaxMemoryRows(size);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_DATABASE_TEXT_SOURCE : {
+                try {
+                    String         source = (String) parameters[0];
+                    HsqlProperties props  = null;
+
+                    if (source.length() > 0) {
+                        props = HsqlProperties.delimitedArgPairsToProps(source,
+                                "=", ";", null);
+
+                        if (props.getErrorKeys().length > 0) {
+                            throw Error.error(ErrorCode.TEXT_TABLE_SOURCE,
+                                              props.getErrorKeys()[0]);
+                        }
+                    }
+
+                    session.database.logger.setDefaultTextTableProperties(
+                        source, props);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_DATABASE_UNIQUE_NAME : {
+                try {
+                    String name = (String) parameters[0];
+
+                    session.database.setUniqueName(name);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.DATABASE_SCRIPT : {
+                ScriptWriterText dsw  = null;
+                String           name = (String) parameters[0];
+
+                if (name == null) {
+                    return session.database.getScript(false);
+                } else {
+                    try {
+                        dsw = new ScriptWriterText(session.database, name,
+                                                   true, true, true);
+
+                        dsw.writeAll();
+                        dsw.close();
+                    } catch (HsqlException e) {
+                        return Result.newErrorResult(e, sql);
+                    }
+
+                    return Result.updateZeroResult;
+                }
+            }
+            case StatementTypes.DATABASE_SHUTDOWN : {
+                try {
+                    int mode = ((Integer) parameters[0]).intValue();
+
+                    session.database.close(mode);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_TABLE_INDEX : {
+                try {
+                    HsqlName name  = (HsqlName) parameters[0];
+                    String   value = (String) parameters[1];
+                    Table table =
+                        session.database.schemaManager.getTable(session,
+                            name.name, name.schema.name);
+
+                    table.setIndexRoots(session, value);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_TABLE_READONLY : {
+                try {
+                    HsqlName name = (HsqlName) parameters[0];
+                    Table table =
+                        session.database.schemaManager.getTable(session,
+                            name.name, name.schema.name);
+                    boolean mode = ((Boolean) parameters[1]).booleanValue();
+
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    table.setDataReadOnly(mode);
+                    session.database.schemaManager.setSchemaChangeTimestamp();
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_TABLE_SOURCE :
+            case StatementTypes.SET_TABLE_SOURCE_HEADER : {
+                try {
+                    HsqlName name = (HsqlName) parameters[0];
+                    Table table =
+                        session.database.schemaManager.getTable(session,
+                            name.name, name.schema.name);
+
+                    if (!table.isText()) {
+                        Exception e = Error.error(ErrorCode.X_S0522);
+
+                        return Result.newErrorResult(e, sql);
+                    }
+
+                    if (parameters[1] != null) {
+                        boolean mode =
+                            ((Boolean) parameters[1]).booleanValue();
+
+                        if (mode) {
+                            ((TextTable) table).connect(session);
+                        } else {
+                            ((TextTable) table).disconnect();
+                        }
+
+                        session.database.schemaManager.setSchemaChangeTimestamp();
+
+                        return Result.updateZeroResult;
+                    }
+
+                    String  source = (String) parameters[2];
+                    boolean isDesc = ((Boolean) parameters[3]).booleanValue();
+                    boolean isHeader =
+                        ((Boolean) parameters[4]).booleanValue();
+
+                    if (isHeader) {
+                        ((TextTable) table).setHeader(source);
+                    } else {
+                        ((TextTable) table).setDataSource(session, source,
+                                                          isDesc, false);
+                    }
+
+                    return Result.updateZeroResult;
+                } catch (Throwable e) {
+                    if (!(e instanceof HsqlException)) {
+                        e = Error.error(ErrorCode.GENERAL_IO_ERROR,
+                                        e.getMessage());
+                    }
+
+                    if (session.isProcessingLog()
+                            || session.isProcessingScript()) {
+                        session.addWarning((HsqlException) e);
+                        session.database.logger.logWarningEvent(
+                            "Problem processing SET TABLE SOURCE", e);
+
+                        return Result.updateZeroResult;
+                    } else {
+                        return Result.newErrorResult(e, sql);
+                    }
+                }
+            }
+            case StatementTypes.SET_TABLE_TYPE : {
+                try {
+                    HsqlName name = (HsqlName) parameters[0];
+                    int      type = ((Integer) parameters[1]).intValue();
+
+                    //
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+
+                    Table table =
+                        session.database.schemaManager.getUserTable(session,
+                            name.name, name.schema.name);
+
+                    session.setScripting(true);
+
+                    TableWorks tw = new TableWorks(session, table);
+
+                    tw.setTableType(session, type);
+                    session.database.schemaManager.setSchemaChangeTimestamp();
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_USER_INITIAL_SCHEMA : {
+                try {
+                    User     user   = (User) parameters[0];
+                    HsqlName schema = (HsqlName) parameters[1];
+
+                    session.checkDDLWrite();
+
+                    if (user == null) {
+                        user = session.getUser();
+                    } else {
+                        session.checkAdmin();
+                        session.checkDDLWrite();
+
+                        user = session.database.userManager.get(
+                            user.getNameString());
+                    }
+
+                    if (schema != null) {
+                        schema =
+                            session.database.schemaManager.getSchemaHsqlName(
+                                schema.name);
+                    }
+
+                    //
+                    user.setInitialSchema(schema);
+                    session.database.schemaManager.setSchemaChangeTimestamp();
+
+                    //
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_USER_PASSWORD : {
+                try {
+                    User   user = parameters[0] == null ? session.getUser()
+                                                        : (User) parameters[0];
+                    String password = (String) parameters[1];
+
+                    session.checkDDLWrite();
+                    session.setScripting(true);
+                    user.setPassword(password);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "StatemntCommand");
+        }
+    }
+
+    public boolean isAutoCommitStatement() {
+        return isTransactionStatement;
+    }
+
+    public String describe(Session session) {
+        return sql;
+    }
+}
diff --git a/src/org/hsqldb/StatementCompound.java b/src/org/hsqldb/StatementCompound.java
new file mode 100644
index 0000000..82a2c6d
--- /dev/null
+++ b/src/org/hsqldb/StatementCompound.java
@@ -0,0 +1,750 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+
+/**
+ * Implementation of Statement for PSM compound statements.
+
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementCompound extends Statement {
+
+    final boolean       isLoop;
+    HsqlName            label;
+    StatementHandler[]  handlers = StatementHandler.emptyExceptionHandlerArray;
+    boolean             hasUndoHandler;
+    Statement           loopCursor;
+    Statement[]         statements;
+    StatementExpression condition;
+    boolean             isAtomic;
+
+    //
+    ColumnSchema[]  variables = ColumnSchema.emptyArray;
+    HashMappedList  scopeVariables;
+    RangeVariable[] rangeVariables = RangeVariable.emptyArray;
+
+    //
+    public static final StatementCompound[] emptyStatementArray =
+        new StatementCompound[]{};
+
+    StatementCompound(int type, HsqlName label) {
+
+        super(type, StatementTypes.X_SQL_CONTROL);
+
+        this.label             = label;
+        isTransactionStatement = false;
+
+        switch (type) {
+
+            case StatementTypes.LOOP :
+            case StatementTypes.WHILE :
+            case StatementTypes.REPEAT :
+                isLoop = true;
+                break;
+
+            case StatementTypes.BEGIN_END :
+            case StatementTypes.IF :
+                isLoop = false;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "StatementCompound");
+        }
+    }
+
+    public String getSQL() {
+
+/*
+        StringBuffer sb = new StringBuffer();
+
+        if (label != null) {
+            sb.append(label.getStatementName()).append(':').append(' ');
+        }
+
+        switch (type) {
+
+            case StatementTypes.LOOP :
+                sb.append(Tokens.T_LOOP).append(' ');
+
+                for (int i = 0; i < statements.length; i++) {
+                    sb.append(statements[i].getSQL()).append(';');
+                }
+
+                sb.append(Tokens.T_END).append(' ').append(Tokens.T_LOOP);
+                break;
+
+            case StatementTypes.WHILE :
+                sb.append(Tokens.T_WHILE).append(' ');
+                sb.append(condition.getSQL()).append(' ').append(Tokens.T_DO);
+                sb.append(' ');
+
+                for (int i = 0; i < statements.length; i++) {
+                    sb.append(statements[i].getSQL()).append(';');
+                }
+
+                sb.append(Tokens.T_END).append(' ').append(Tokens.T_WHILE);
+                break;
+
+            case StatementTypes.REPEAT :
+                sb.append(Tokens.T_REPEAT).append(' ');
+
+                for (int i = 0; i < statements.length; i++) {
+                    sb.append(statements[i].getSQL()).append(';');
+                }
+
+                sb.append(Tokens.T_UNTIL).append(' ');
+                sb.append(condition.getSQL()).append(' ');
+                sb.append(Tokens.T_END).append(' ').append(Tokens.T_REPEAT);
+                break;
+
+            case StatementTypes.BEGIN_END :
+                sb.append(Tokens.T_BEGIN).append(' ').append(Tokens.T_ATOMIC);
+                sb.append(' ');
+
+                for (int i = 0; i < handlers.length; i++) {
+                    sb.append(handlers[i].getSQL()).append(';');
+                }
+
+                for (int i = 0; i < variables.length; i++) {
+                    sb.append(Tokens.T_DECLARE).append(' ');
+                    sb.append(variables[i].getSQL());
+
+                    if (variables[i].hasDefault()) {
+                        sb.append(' ').append(Tokens.T_DEFAULT).append(' ');
+                        sb.append(variables[i].getDefaultSQL());
+                    }
+
+                    sb.append(';');
+                }
+
+                for (int i = 0; i < statements.length; i++) {
+                    sb.append(statements[i].getSQL()).append(';');
+                }
+
+                sb.append(Tokens.T_END);
+                break;
+
+            case StatementTypes.IF :
+                for (int i = 0; i < statements.length; i++) {
+                    if (statements[i].type == StatementTypes.CONDITION) {
+                        if (i != 0) {
+                            sb.append(Tokens.T_ELSE).append(' ');
+                        }
+
+                        sb.append(Tokens.T_IF).append(' ');
+                        sb.append(statements[i].getSQL()).append(' ');
+                        sb.append(Tokens.T_THEN).append(' ');
+                    } else {
+                        sb.append(statements[i].getSQL()).append(';');
+                    }
+                }
+
+                sb.append(Tokens.T_END).append(' ').append(Tokens.T_IF);
+                break;
+        }
+
+        return sb.toString();
+*/
+        return sql;
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        sb.append(Tokens.T_STATEMENT);
+
+        return sb.toString();
+    }
+
+    public void setLocalDeclarations(Object[] declarations) {
+
+        int varCount     = 0;
+        int handlerCount = 0;
+
+        for (int i = 0; i < declarations.length; i++) {
+            if (declarations[i] instanceof ColumnSchema) {
+                varCount++;
+            } else {
+                handlerCount++;
+            }
+        }
+
+        variables    = new ColumnSchema[varCount];
+        handlers     = new StatementHandler[handlerCount];
+        varCount     = 0;
+        handlerCount = 0;
+
+        for (int i = 0; i < declarations.length; i++) {
+            if (declarations[i] instanceof ColumnSchema) {
+                variables[varCount++] = (ColumnSchema) declarations[i];
+            } else {
+                StatementHandler handler = (StatementHandler) declarations[i];
+
+                handler.setParent(this);
+
+                handlers[handlerCount++] = handler;
+
+                if (handler.handlerType == StatementHandler.UNDO) {
+                    hasUndoHandler = true;
+                }
+            }
+        }
+
+        setVariables();
+        setHandlers();
+    }
+
+    public void setLoopStatement(Statement cursorStatement) {
+        loopCursor = cursorStatement;
+    }
+
+    void setStatements(Statement[] statements) {
+
+        for (int i = 0; i < statements.length; i++) {
+            statements[i].setParent(this);
+        }
+
+        this.statements = statements;
+    }
+
+    public void setCondition(StatementExpression condition) {
+        this.condition = condition;
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        switch (type) {
+
+            case StatementTypes.BEGIN_END : {
+                initialiseVariables(session);
+
+                result = executeBlock(session);
+
+                break;
+            }
+            case StatementTypes.LOOP :
+            case StatementTypes.WHILE :
+            case StatementTypes.REPEAT : {
+                result = executeLoop(session);
+
+                break;
+            }
+            case StatementTypes.IF : {
+                result = executeIf(session);
+
+                break;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "StatementCompound");
+        }
+
+        if (result.isError()) {
+            result.getException().setStatementType(group, type);
+        }
+
+        return result;
+    }
+
+    private Result executeBlock(Session session) {
+
+        Result  result = Result.updateZeroResult;
+        boolean push   = !root.isTrigger();
+
+        if (push) {
+            session.sessionContext.push();
+
+            if (hasUndoHandler) {
+                String name = HsqlNameManager.getAutoSavepointNameString(
+                    session.actionTimestamp, session.sessionContext.depth);
+
+                session.savepoint(name);
+            }
+        }
+
+        for (int i = 0; i < statements.length; i++) {
+            result = statements[i].execute(session);
+            result = handleCondition(session, result);
+
+            if (result.isError()) {
+                break;
+            }
+
+            if (result.getType() == ResultConstants.VALUE
+                    || result.getType() == ResultConstants.DATA) {
+                break;
+            }
+        }
+
+        if (result.getType() == ResultConstants.VALUE) {
+            if (result.getErrorCode() == StatementTypes.LEAVE) {
+                if (result.getMainString() == null) {
+                    result = Result.updateZeroResult;
+                } else if (label != null
+                           && label.name.equals(result.getMainString())) {
+                    result = Result.updateZeroResult;
+                }
+            }
+        }
+
+        if (push) {
+            session.sessionContext.pop();
+        }
+
+        return result;
+    }
+
+    private Result handleCondition(Session session, Result result) {
+
+        String sqlState = null;
+
+        if (result.isError()) {
+            sqlState = result.getSubString();
+        } else if (session.getLastWarning() != null) {
+            sqlState = session.getLastWarning().getSQLState();
+        } else {
+            return result;
+        }
+
+        if (sqlState != null) {
+            for (int i = 0; i < handlers.length; i++) {
+                StatementHandler handler = handlers[i];
+
+                session.clearWarnings();
+
+                /**
+                 * @todo - if condition is "transaction rollback" promote to
+                 * top call level without any further action
+                 * if condition is system related promote to top level
+                 * schema manipulation conditions are never handled
+                 */
+                if (handler.handlesCondition(result.getSubString())) {
+                    session.resetSchema();
+
+                    switch (handler.handlerType) {
+
+                        case StatementHandler.CONTINUE :
+                            result = Result.updateZeroResult;
+                            break;
+
+                        case StatementHandler.UNDO :
+                            session.rollbackToSavepoint();
+
+                            result = Result.newPSMResult(StatementTypes.LEAVE,
+                                                         label.name, null);
+                            break;
+
+                        case StatementHandler.EXIT :
+                            result = Result.newPSMResult(StatementTypes.LEAVE,
+                                                         null, null);
+                            break;
+                    }
+
+                    Result actionResult = handler.statement.execute(session);
+
+                    if (actionResult.isError()) {
+                        result = actionResult;
+
+                        handleCondition(session, result);
+                    } else {
+                        return result;
+                    }
+                }
+            }
+
+            if (parent != null) {
+
+                // unhandled exception condition
+                return parent.handleCondition(session, result);
+            }
+        }
+
+        return result;
+    }
+
+    private Result executeLoop(Session session) {
+
+        Result result = Result.updateZeroResult;
+
+        while (true) {
+            if (type == StatementTypes.WHILE) {
+                result = condition.execute(session);
+
+                if (result.isError()) {
+                    break;
+                }
+
+                if (!Boolean.TRUE.equals(result.getValueObject())) {
+                    result = Result.updateZeroResult;
+
+                    break;
+                }
+            }
+
+            for (int i = 0; i < statements.length; i++) {
+                result = statements[i].execute(session);
+
+                if (result.isError()) {
+                    break;
+                }
+
+                if (result.getType() == ResultConstants.VALUE) {
+                    break;
+                }
+
+                if (result.getType() == ResultConstants.DATA) {
+                    break;
+                }
+
+            }
+
+            if (result.isError()) {
+                break;
+            }
+
+            if (result.getType() == ResultConstants.VALUE) {
+                if (result.getErrorCode() == StatementTypes.ITERATE) {
+                    if (result.getMainString() == null) {
+                        continue;
+                    }
+
+                    if (label != null
+                            && label.name.equals(result.getMainString())) {
+                        continue;
+                    }
+
+                    break;
+                }
+
+                if (result.getErrorCode() == StatementTypes.LEAVE) {
+                    if (result.getMainString() == null) {
+                        result = Result.updateZeroResult;
+                    }
+
+                    if (label != null
+                            && label.name.equals(result.getMainString())) {
+                        result = Result.updateZeroResult;
+                    }
+
+                    break;
+                }
+
+                // return
+                break;
+            }
+
+            if (result.getType() == ResultConstants.DATA) {
+                break;
+            }
+
+            if (type == StatementTypes.REPEAT) {
+                result = condition.execute(session);
+
+                if (result.isError()) {
+                    break;
+                }
+
+                if (Boolean.TRUE.equals(result.getValueObject())) {
+                    result = Result.updateZeroResult;
+
+                    break;
+                }
+            }
+        }
+
+        return result;
+    }
+
+    private Result executeIf(Session session) {
+
+        Result  result  = Result.updateZeroResult;
+        boolean execute = false;
+
+        for (int i = 0; i < statements.length; i++) {
+            if (statements[i].getType() == StatementTypes.CONDITION) {
+                if (execute) {
+                    break;
+                }
+
+                result = statements[i].execute(session);
+
+                if (result.isError()) {
+                    break;
+                }
+
+                Object value = result.getValueObject();
+
+                execute = Boolean.TRUE.equals(value);
+
+                i++;
+            }
+
+            result = Result.updateZeroResult;
+
+            if (!execute) {
+                continue;
+            }
+
+            result = statements[i].execute(session);
+
+            if (result.isError()) {
+                break;
+            }
+
+            if (result.getType() == ResultConstants.VALUE) {
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    public void resolve(Session session) {
+
+        for (int i = 0; i < statements.length; i++) {
+            if (statements[i].getType() == StatementTypes.LEAVE
+                    || statements[i].getType() == StatementTypes.ITERATE) {
+                if (!findLabel((StatementSimple) statements[i])) {
+                    throw Error.error(
+                        ErrorCode.X_42508,
+                        ((StatementSimple) statements[i]).label.name);
+                }
+
+                continue;
+            }
+
+            if (statements[i].getType() == StatementTypes.RETURN) {
+                if (!root.isFunction()) {
+                    throw Error.error(ErrorCode.X_42602, Tokens.T_RETURN);
+                }
+            }
+        }
+
+        for (int i = 0; i < statements.length; i++) {
+            statements[i].resolve(session);
+        }
+
+        for (int i = 0; i < handlers.length; i++) {
+            handlers[i].resolve(session);
+        }
+
+        OrderedHashSet writeTableNamesSet = new OrderedHashSet();
+        OrderedHashSet readTableNamesSet  = new OrderedHashSet();
+        OrderedHashSet set                = new OrderedHashSet();
+
+        for (int i = 0; i < variables.length; i++) {
+            set.addAll(variables[i].getReferences());
+        }
+
+        if (condition != null) {
+            set.addAll(condition.getReferences());
+            readTableNamesSet.addAll(condition.getTableNamesForRead());
+        }
+
+        for (int i = 0; i < statements.length; i++) {
+            set.addAll(statements[i].getReferences());
+            readTableNamesSet.addAll(statements[i].getTableNamesForRead());
+            writeTableNamesSet.addAll(statements[i].getTableNamesForWrite());
+        }
+
+        for (int i = 0; i < handlers.length; i++) {
+            set.addAll(handlers[i].getReferences());
+            readTableNamesSet.addAll(handlers[i].getTableNamesForRead());
+            writeTableNamesSet.addAll(handlers[i].getTableNamesForWrite());
+        }
+
+        readTableNamesSet.removeAll(writeTableNamesSet);
+
+        readTableNames = new HsqlName[readTableNamesSet.size()];
+
+        readTableNamesSet.toArray(readTableNames);
+
+        writeTableNames = new HsqlName[writeTableNamesSet.size()];
+
+        writeTableNamesSet.toArray(writeTableNames);
+
+        references = set;
+    }
+
+    public void setRoot(Routine routine) {
+
+        root = routine;
+/*
+        if (condition != null) {
+            condition.setRoot(routine);
+        }
+
+        for (int i = 0; i < statements.length; i++) {
+            statements[i].setRoot(routine);
+        }
+*/
+    }
+
+    public String describe(Session session) {
+        return "";
+    }
+
+    public OrderedHashSet getReferences() {
+        return references;
+    }
+
+    public void setAtomic(boolean atomic) {
+        this.isAtomic = atomic;
+    }
+
+    //
+    private void setVariables() {
+
+        if (variables.length == 0) {
+            if (parent == null) {
+                rangeVariables = root.getParameterRangeVariables();
+            } else {
+                rangeVariables = parent.rangeVariables;
+            }
+
+            return;
+        }
+
+        HashMappedList list = new HashMappedList();
+
+        if (parent != null) {
+            for (int i = 0; i < parent.scopeVariables.size(); i++) {
+                list.add(parent.scopeVariables.getKey(i),
+                         parent.scopeVariables.get(i));
+            }
+        }
+
+        for (int i = 0; i < variables.length; i++) {
+            String  name  = variables[i].getName().name;
+            boolean added = list.add(name, variables[i]);
+
+            if (!added) {
+                throw Error.error(ErrorCode.X_42606, name);
+            }
+
+            if (root.getParameterIndex(name) != -1) {
+                throw Error.error(ErrorCode.X_42606, name);
+            }
+        }
+
+        RangeVariable range = new RangeVariable(list, true);
+
+        rangeVariables     = new RangeVariable[] {
+            root.getParameterRangeVariables()[0], range
+        };
+        root.variableCount = list.size();
+    }
+
+    private void setHandlers() {
+
+        if (handlers.length == 0) {
+            return;
+        }
+
+        HashSet           statesSet = new HashSet();
+        OrderedIntHashSet typesSet  = new OrderedIntHashSet();
+
+        for (int i = 0; i < handlers.length; i++) {
+            int[] types = handlers[i].getConditionTypes();
+
+            for (int j = 0; j < types.length; j++) {
+                if (!typesSet.add(types[j])) {
+                    throw Error.error(ErrorCode.X_42601);
+                }
+            }
+
+            String[] states = handlers[i].getConditionStates();
+
+            for (int j = 0; j < states.length; j++) {
+                if (!statesSet.add(states[j])) {
+                    throw Error.error(ErrorCode.X_42601);
+                }
+            }
+        }
+    }
+
+    private boolean findLabel(StatementSimple statement) {
+
+        if (label != null && statement.label.name.equals(label.name)) {
+            if (!isLoop && statement.getType() == StatementTypes.ITERATE) {
+                return false;
+            }
+
+            return true;
+        }
+
+        if (parent == null) {
+            return false;
+        }
+
+        return parent.findLabel(statement);
+    }
+
+    private void initialiseVariables(Session session) {
+
+        Object[] vars   = session.sessionContext.routineVariables;
+        int      offset = parent == null ? 0
+                                         : parent.scopeVariables.size();
+
+        for (int i = 0; i < variables.length; i++) {
+            try {
+                vars[offset + i] = variables[i].getDefaultValue(session);
+            } catch (HsqlException e) {}
+        }
+    }
+
+    public RangeVariable[] getRangeVariables() {
+        return rangeVariables;
+    }
+}
diff --git a/src/org/hsqldb/StatementDML.java b/src/org/hsqldb/StatementDML.java
new file mode 100644
index 0000000..56eb0e8
--- /dev/null
+++ b/src/org/hsqldb/StatementDML.java
@@ -0,0 +1,1318 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.navigator.RangeIterator;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.navigator.RowSetNavigatorDataChange;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of Statement for DML statements.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+
+// support for MERGE statement originally contributed by Justin Spadea (jzs9783@users dot sourceforge.net)
+public class StatementDML extends StatementDMQL {
+
+    Expression[]  targets;
+    Expression    updatableTableCheck;
+    RangeVariable checkRangeVariable;
+    boolean       isTruncate;
+
+    public StatementDML(int type, int group, HsqlName schemaName) {
+        super(type, group, schemaName);
+    }
+
+    /**
+     * Instantiate this as a DELETE statement
+     */
+    StatementDML(Session session, Table targetTable,
+                 RangeVariable[] rangeVars, CompileContext compileContext,
+                 boolean restartIdentity, int type) {
+
+        super(StatementTypes.DELETE_WHERE, StatementTypes.X_SQL_DATA_CHANGE,
+              session.getCurrentSchemaHsqlName());
+
+        this.targetTable = targetTable;
+        this.baseTable   = targetTable.getBaseTable() == null ? targetTable
+                                                              : targetTable
+                                                              .getBaseTable();
+        this.targetRangeVariables = rangeVars;
+        this.restartIdentity      = restartIdentity;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+
+        if (type == StatementTypes.TRUNCATE) {
+            isTruncate = true;
+        }
+
+        targetRangeVariables[0].addAllColumns();
+    }
+
+    /**
+     * Instantiate this as an UPDATE statement.
+     */
+    StatementDML(Session session, Expression[] targets, Table targetTable,
+                 RangeVariable rangeVars[], int[] updateColumnMap,
+                 Expression[] colExpressions, boolean[] checkColumns,
+                 CompileContext compileContext) {
+
+        super(StatementTypes.UPDATE_WHERE, StatementTypes.X_SQL_DATA_CHANGE,
+              session.getCurrentSchemaHsqlName());
+
+        this.targets     = targets;
+        this.targetTable = targetTable;
+        this.baseTable   = targetTable.getBaseTable() == null ? targetTable
+                                                              : targetTable
+                                                              .getBaseTable();
+        this.updateColumnMap      = updateColumnMap;
+        this.updateExpressions    = colExpressions;
+        this.updateCheckColumns   = checkColumns;
+        this.targetRangeVariables = rangeVars;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+        setupChecks();
+        targetRangeVariables[0].addAllColumns();
+    }
+
+    /**
+     * Instantiate this as a MERGE statement.
+     */
+    StatementDML(Session session, Expression[] targets,
+                 RangeVariable[] targetRangeVars, int[] insertColMap,
+                 int[] updateColMap, boolean[] checkColumns,
+                 Expression mergeCondition, Expression insertExpr,
+                 Expression[] updateExpr, CompileContext compileContext) {
+
+        super(StatementTypes.MERGE, StatementTypes.X_SQL_DATA_CHANGE,
+              session.getCurrentSchemaHsqlName());
+
+        this.targets     = targets;
+        this.sourceTable = targetRangeVars[0].rangeTable;
+        this.targetTable = targetRangeVars[1].rangeTable;
+        this.baseTable   = targetTable.getBaseTable() == null ? targetTable
+                                                              : targetTable
+                                                              .getBaseTable();
+        this.insertCheckColumns   = checkColumns;
+        this.insertColumnMap      = insertColMap;
+        this.updateColumnMap      = updateColMap;
+        this.insertExpression     = insertExpr;
+        this.updateExpressions    = updateExpr;
+        this.targetRangeVariables = targetRangeVars;
+        this.condition            = mergeCondition;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+        setupChecks();
+    }
+
+    /**
+     * Instantiate this as a CURSOR operation statement.
+     */
+    StatementDML() {
+        super(StatementTypes.UPDATE_CURSOR, StatementTypes.X_SQL_DATA_CHANGE,
+              null);
+    }
+
+    void setupChecks() {
+
+        if (targetTable != baseTable) {
+            QuerySpecification select =
+                ((TableDerived) targetTable).getQueryExpression()
+                    .getMainSelect();
+
+            this.updatableTableCheck = select.checkQueryCondition;
+            this.checkRangeVariable  = select.rangeVariables[0];
+        }
+    }
+
+    Result getResult(Session session) {
+
+        Result result = null;
+
+        switch (type) {
+
+            case StatementTypes.UPDATE_WHERE :
+                result = executeUpdateStatement(session);
+                break;
+
+            case StatementTypes.MERGE :
+                result = executeMergeStatement(session);
+                break;
+
+            case StatementTypes.DELETE_WHERE :
+                if (isTruncate) {
+                    result = executeDeleteTruncateStatement(session);
+                } else {
+                    result = executeDeleteStatement(session);
+                }
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "StatementDML");
+        }
+
+        return result;
+    }
+
+    // this fk references -> other  :  other read lock
+    void collectTableNamesForRead(OrderedHashSet set) {
+
+        if (baseTable.isView()) {
+            getTriggerTableNames(set, false);
+        } else if (!baseTable.isTemp()) {
+            for (int i = 0; i < baseTable.fkConstraints.length; i++) {
+                Constraint constraint = baseTable.fkConstraints[i];
+
+                if (type == StatementTypes.UPDATE_WHERE
+                        || type == StatementTypes.MERGE) {
+                    if (ArrayUtil.haveCommonElement(constraint.getRefColumns(),
+                                                    updateColumnMap)) {
+                        set.add(
+                            baseTable.fkConstraints[i].getMain().getName());
+                    }
+                } else if (type == StatementTypes.INSERT) {
+                    set.add(baseTable.fkConstraints[i].getMain().getName());
+                }
+            }
+
+            if (type == StatementTypes.UPDATE_WHERE
+                    || type == StatementTypes.MERGE) {
+                baseTable.collectFKReadLocks(updateColumnMap, set);
+            } else if (type == StatementTypes.DELETE_WHERE) {
+                baseTable.collectFKReadLocks(null, set);
+            }
+
+            getTriggerTableNames(set, false);
+        }
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            Table    rangeTable = rangeVariables[i].rangeTable;
+            HsqlName name       = rangeTable.getName();
+
+            if (rangeTable.isReadOnly() || rangeTable.isTemp()) {
+                continue;
+            }
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            set.add(name);
+        }
+
+        for (int i = 0; i < subqueries.length; i++) {
+            if (subqueries[i].queryExpression != null) {
+                subqueries[i].queryExpression.getBaseTableNames(set);
+            }
+        }
+
+        for (int i = 0; i < routines.length; i++) {
+            set.addAll(routines[i].getTableNamesForRead());
+        }
+    }
+
+    void collectTableNamesForWrite(OrderedHashSet set) {
+
+        // other fk references this :  if constraint trigger action  : other write lock
+        if (baseTable.isView()) {
+            getTriggerTableNames(set, true);
+        } else if (!baseTable.isTemp()) {
+            set.add(baseTable.getName());
+
+            if (type == StatementTypes.UPDATE_WHERE
+                    || type == StatementTypes.MERGE) {
+                baseTable.collectFKWriteLocks(updateColumnMap, set);
+            } else if (type == StatementTypes.DELETE_WHERE) {
+                baseTable.collectFKWriteLocks(null, set);
+            }
+
+            getTriggerTableNames(set, true);
+        }
+    }
+
+    void getTriggerTableNames(OrderedHashSet set, boolean write) {
+
+        for (int i = 0; i < baseTable.triggerList.length; i++) {
+            TriggerDef td = baseTable.triggerList[i];
+
+            switch (type) {
+
+                case StatementTypes.INSERT :
+                    if (td.getStatementType() == StatementTypes.INSERT) {
+                        break;
+                    }
+
+                    continue;
+                case StatementTypes.UPDATE_WHERE :
+                    if (td.getStatementType() == StatementTypes.UPDATE_WHERE) {
+                        break;
+                    }
+
+                    continue;
+                case StatementTypes.DELETE_WHERE :
+                    if (td.getStatementType() == StatementTypes.DELETE_WHERE) {
+                        break;
+                    }
+
+                    continue;
+                case StatementTypes.MERGE :
+                    if (td.getStatementType() == StatementTypes.INSERT
+                            || td.getStatementType()
+                               == StatementTypes.UPDATE_WHERE) {
+                        break;
+                    }
+
+                    continue;
+                default :
+                    throw Error.runtimeError(ErrorCode.U_S0500,
+                                             "StatementDML");
+            }
+
+            if (td.routine != null) {
+                if (write) {
+                    set.addAll(td.routine.getTableNamesForWrite());
+                } else {
+                    set.addAll(td.routine.getTableNamesForRead());
+                }
+            }
+        }
+    }
+
+    /**
+     * Executes an UPDATE statement.
+     *
+     * @return Result object
+     */
+    Result executeUpdateStatement(Session session) {
+
+        int                       count          = 0;
+        Expression[]              colExpressions = updateExpressions;
+        RowSetNavigatorDataChange rowset = new RowSetNavigatorDataChange();
+        Type[]                    colTypes       = baseTable.getColumnTypes();
+        RangeIterator it = RangeVariable.getIterator(session,
+            targetRangeVariables);
+
+        while (it.next()) {
+            session.sessionData.startRowProcessing();
+
+            Row      row  = it.getCurrentRow();
+            Object[] data = row.getData();
+            Object[] newData = getUpdatedData(session, targets, baseTable,
+                                              updateColumnMap, colExpressions,
+                                              colTypes, data);
+
+            if (updatableTableCheck != null) {
+                it.setCurrent(newData);
+
+                boolean check = updatableTableCheck.testCondition(session);
+
+                if (!check) {
+                    it.release();
+
+                    throw Error.error(ErrorCode.X_44000);
+                }
+            }
+
+            rowset.addRow(session, row, newData, colTypes, updateColumnMap);
+        }
+
+        it.release();
+/* debug 190
+        if (rowset.size() == 0) {
+            System.out.println(targetTable.getName().name + " zero update: session "
+                               + session.getId());
+        } else if (rowset.size() >1) {
+           System.out.println("multiple update: session "
+                              + session.getId() + ", " + rowset.size());
+       }
+
+//* debug 190 */
+        rowset.beforeFirst();
+
+        count = update(session, baseTable, rowset);
+
+        if (count == 1) {
+            return Result.updateOneResult;
+        } else if (count == 0) {
+            return Result.updateZeroResult;
+        }
+
+        return new Result(ResultConstants.UPDATECOUNT, count);
+    }
+
+    static Object[] getUpdatedData(Session session, Expression[] targets,
+                                   Table targetTable, int[] columnMap,
+                                   Expression[] colExpressions,
+                                   Type[] colTypes, Object[] oldData) {
+
+        Object[] data = targetTable.getEmptyRowData();
+
+        System.arraycopy(oldData, 0, data, 0, data.length);
+
+        for (int i = 0, ix = 0; i < columnMap.length; ) {
+            Expression expr = colExpressions[ix++];
+
+            if (expr.getType() == OpTypes.ROW) {
+                Object[] values = expr.getRowValue(session);
+
+                for (int j = 0; j < values.length; j++, i++) {
+                    int        colIndex = columnMap[i];
+                    Expression e        = expr.nodes[j];
+
+                    // transitional - still supporting null for identity generation
+                    if (targetTable.identityColumn == colIndex) {
+                        if (e.getType() == OpTypes.VALUE
+                                && e.valueData == null) {
+                            continue;
+                        }
+                    }
+
+                    if (e.getType() == OpTypes.DEFAULT) {
+                        if (targetTable.identityColumn == colIndex) {
+                            continue;
+                        }
+
+                        data[colIndex] =
+                            targetTable.colDefaults[colIndex].getValue(
+                                session);
+
+                        continue;
+                    }
+
+                    data[colIndex] = colTypes[colIndex].convertToType(session,
+                            values[j], e.dataType);
+                }
+            } else if (expr.getType() == OpTypes.ROW_SUBQUERY) {
+                Object[] values = expr.getRowValue(session);
+
+                for (int j = 0; j < values.length; j++, i++) {
+                    int colIndex = columnMap[i];
+                    Type colType =
+                        expr.subQuery.queryExpression.getMetaData()
+                            .columnTypes[j];
+
+                    data[colIndex] = colTypes[colIndex].convertToType(session,
+                            values[j], colType);
+                }
+            } else {
+                int colIndex = columnMap[i];
+
+                if (expr.getType() == OpTypes.DEFAULT) {
+                    if (targetTable.identityColumn == colIndex) {
+                        i++;
+
+                        continue;
+                    }
+
+                    data[colIndex] =
+                        targetTable.colDefaults[colIndex].getValue(session);
+
+                    i++;
+
+                    continue;
+                }
+
+                Object value = expr.getValue(session);
+
+                if (targets[i].getType() == OpTypes.ARRAY_ACCESS) {
+                    data[colIndex] =
+                        ((ExpressionAccessor) targets[i]).getUpdatedArray(
+                            session, (Object[]) data[colIndex], value, true);
+                } else {
+                    data[colIndex] = colTypes[colIndex].convertToType(session,
+                            value, expr.dataType);
+                }
+
+                i++;
+            }
+        }
+
+        return data;
+    }
+
+    /**
+     * Executes a MERGE statement.
+     *
+     * @return Result object
+     */
+    Result executeMergeStatement(Session session) {
+
+        Type[]          colTypes           = baseTable.getColumnTypes();
+        Result          resultOut          = null;
+        RowSetNavigator generatedNavigator = null;
+
+        if (generatedIndexes != null) {
+            resultOut = Result.newUpdateCountResult(generatedResultMetaData,
+                    0);
+            generatedNavigator = resultOut.getChainedResult().getNavigator();
+        }
+
+        int count = 0;
+
+        // data generated for non-matching rows
+        RowSetNavigatorClient newData = new RowSetNavigatorClient(8);
+
+        // rowset for update operation
+        RowSetNavigatorDataChange updateRowSet =
+            new RowSetNavigatorDataChange();
+        RangeVariable[] joinRangeIterators = targetRangeVariables;
+
+        // populate insert and update lists
+        RangeIterator[] rangeIterators =
+            new RangeIterator[joinRangeIterators.length];
+
+        for (int i = 0; i < joinRangeIterators.length; i++) {
+            rangeIterators[i] = joinRangeIterators[i].getIterator(session);
+        }
+
+        for (int currentIndex = 0; currentIndex >= 0; ) {
+            RangeIterator it          = rangeIterators[currentIndex];
+            boolean       beforeFirst = it.isBeforeFirst();
+
+            if (it.next()) {
+                if (currentIndex < joinRangeIterators.length - 1) {
+                    currentIndex++;
+
+                    continue;
+                }
+            } else {
+                if (currentIndex == 1 && beforeFirst
+                        && insertExpression != null) {
+                    Object[] data =
+                        getInsertData(session, colTypes,
+                                      insertExpression.nodes[0].nodes);
+
+                    if (data != null) {
+                        newData.add(data);
+                    }
+                }
+
+                it.reset();
+
+                currentIndex--;
+
+                continue;
+            }
+
+            // row matches!
+            if (updateExpressions.length != 0) {
+                Row row = it.getCurrentRow();    // this is always the second iterator
+                Object[] data = getUpdatedData(session, targets, baseTable,
+                                               updateColumnMap,
+                                               updateExpressions, colTypes,
+                                               row.getData());
+
+                try {
+                    updateRowSet.addRow(session, row, data, colTypes,
+                                        updateColumnMap);
+                } catch (HsqlException e) {
+                    for (int i = 0; i < joinRangeIterators.length; i++) {
+                        rangeIterators[i].reset();
+                    }
+
+                    throw Error.error(ErrorCode.X_21000);
+                }
+            }
+        }
+
+        for (int i = 0; i < joinRangeIterators.length; i++) {
+            rangeIterators[i].reset();
+        }
+
+        // run the transaction as a whole, updating and inserting where needed
+        // update any matched rows
+        if (updateExpressions.length != 0) {
+            count = update(session, baseTable, updateRowSet);
+        }
+
+        // insert any non-matched rows
+        if (newData.getSize() > 0) {
+            insertRowSet(session, generatedNavigator, newData);
+
+            count += newData.getSize();
+        }
+
+        if (insertExpression != null
+                && baseTable.triggerLists[Trigger.INSERT_AFTER].length > 0) {
+            baseTable.fireTriggers(session, Trigger.INSERT_AFTER, newData);
+        }
+
+        if (resultOut == null) {
+            if (count == 1) {
+                return Result.updateOneResult;
+            }
+
+            return new Result(ResultConstants.UPDATECOUNT, count);
+        } else {
+            resultOut.setUpdateCount(count);
+
+            return resultOut;
+        }
+    }
+
+    void insertRowSet(Session session, RowSetNavigator generatedNavigator,
+                      RowSetNavigator newData) {
+
+        PersistentStore store         = baseTable.getRowStore(session);
+        RangeIterator   checkIterator = null;
+
+        if (updatableTableCheck != null) {
+            checkIterator = checkRangeVariable.getIterator(session);
+        }
+
+        newData.beforeFirst();
+
+        if (baseTable.triggerLists[Trigger.INSERT_BEFORE_ROW].length > 0) {
+            while (newData.hasNext()) {
+                Object[] data = (Object[]) newData.getNext();
+
+                baseTable.fireTriggers(session, Trigger.INSERT_BEFORE_ROW,
+                                       null, data, null);
+            }
+
+            newData.beforeFirst();
+        }
+
+        while (newData.hasNext()) {
+            Object[] data = (Object[]) newData.getNext();
+
+            baseTable.insertSingleRow(session, store, data, null);
+
+            if (checkIterator != null) {
+                checkIterator.setCurrent(data);
+
+                boolean check = updatableTableCheck.testCondition(session);
+
+                if (!check) {
+                    throw Error.error(ErrorCode.X_44000);
+                }
+            }
+
+            if (generatedNavigator != null) {
+                Object[] generatedValues = getGeneratedColumns(data);
+
+                generatedNavigator.add(generatedValues);
+            }
+        }
+
+        newData.beforeFirst();
+
+        while (newData.hasNext()) {
+            Object[] data = (Object[]) newData.getNext();
+
+            performIntegrityChecks(session, baseTable, null, data, null);
+        }
+
+        newData.beforeFirst();
+
+        if (baseTable.triggerLists[Trigger.INSERT_AFTER_ROW].length > 0) {
+            while (newData.hasNext()) {
+                Object[] data = (Object[]) newData.getNext();
+
+                baseTable.fireTriggers(session, Trigger.INSERT_AFTER_ROW,
+                                       null, data, null);
+            }
+
+            newData.beforeFirst();
+        }
+    }
+
+    Result insertSingleRow(Session session, PersistentStore store,
+                           Object[] data) {
+
+        if (baseTable.triggerLists[Trigger.INSERT_BEFORE_ROW].length > 0) {
+            baseTable.fireTriggers(session, Trigger.INSERT_BEFORE_ROW, null,
+                                   data, null);
+        }
+
+        baseTable.insertSingleRow(session, store, data, null);
+        performIntegrityChecks(session, baseTable, null, data, null);
+
+        if (session.database.isReferentialIntegrity()) {
+            for (int i = 0, size = baseTable.fkConstraints.length; i < size;
+                    i++) {
+                baseTable.fkConstraints[i].checkInsert(session, baseTable,
+                                                       data, true);
+            }
+        }
+
+        if (baseTable.triggerLists[Trigger.INSERT_AFTER_ROW].length > 0) {
+            baseTable.fireTriggers(session, Trigger.INSERT_AFTER_ROW, null,
+                                   data, null);
+        }
+
+        if (baseTable.triggerLists[Trigger.INSERT_AFTER].length > 0) {
+            baseTable.fireTriggers(session, Trigger.INSERT_AFTER,
+                                   (RowSetNavigator) null);
+        }
+
+        return Result.updateOneResult;
+    }
+
+    Object[] getInsertData(Session session, Type[] colTypes,
+                           Expression[] rowArgs) {
+
+        Object[] data = baseTable.getNewRowData(session);
+
+        session.sessionData.startRowProcessing();
+
+        for (int i = 0; i < rowArgs.length; i++) {
+            Expression e        = rowArgs[i];
+            int        colIndex = insertColumnMap[i];
+
+            if (e.opType == OpTypes.DEFAULT) {
+                if (baseTable.identityColumn == colIndex) {
+                    continue;
+                }
+
+                if (baseTable.colDefaults[colIndex] != null) {
+                    data[colIndex] =
+                        baseTable.colDefaults[colIndex].getValue(session);
+
+                    continue;
+                }
+
+                continue;
+            }
+
+            Object value = e.getValue(session);
+            Type   type  = colTypes[colIndex];
+
+            if (colTypes[colIndex] != e.dataType) {
+                value = type.convertToType(session, value, e.dataType);
+            }
+
+            data[colIndex] = value;
+        }
+
+        return data;
+    }
+
+    /**
+     * Highest level multiple row update method.<p>
+     *
+     * Following clauses from SQL Standard section 11.8 are enforced 9) Let ISS
+     * be the innermost SQL-statement being executed. 10) If evaluation of these
+     * General Rules during the execution of ISS would cause an update of some
+     * site to a value that is distinct from the value to which that site was
+     * previously updated during the execution of ISS, then an exception
+     * condition is raised: triggered data change violation. 11) If evaluation
+     * of these General Rules during the execution of ISS would cause deletion
+     * of a row containing a site that is identified for replacement in that
+     * row, then an exception condition is raised: triggered data change
+     * violation.
+     *
+     * @param session Session
+     * @param table Table
+     * @param updateList RowSetNavigatorDataChange
+     * @return int
+     */
+    int update(Session session, Table table,
+               RowSetNavigatorDataChange navigator) {
+
+        int rowCount = navigator.getSize();
+
+        // set identity column where null and check columns
+        for (int i = 0; i < rowCount; i++) {
+            navigator.next();
+
+            Object[] data = navigator.getCurrentChangedData();
+
+            /**
+             * @todo 1.9.0 - make optional using database property -
+             * this means the identity column can be set to null to force
+             * creation of a new identity value
+             */
+            table.setIdentityColumn(session, data);
+            table.setGeneratedColumns(session, data);
+        }
+
+        navigator.beforeFirst();
+
+        if (table.fkMainConstraints.length > 0) {
+            HashSet path = session.sessionContext.getConstraintPath();
+
+            for (int i = 0; i < rowCount; i++) {
+                Row      row  = navigator.getNextRow();
+                Object[] data = navigator.getCurrentChangedData();
+
+                performReferentialActions(session, table, navigator, row,
+                                          data, this.updateColumnMap, path);
+                path.clear();
+            }
+
+            navigator.beforeFirst();
+        }
+
+        for (int i = 0; i < navigator.getSize(); i++) {
+            Row      row            = navigator.getNextRow();
+            Object[] data           = navigator.getCurrentChangedData();
+            int[]    changedColumns = navigator.getCurrentChangedColumns();
+            Table    currentTable   = ((Table) row.getTable());
+
+            if (currentTable.triggerLists[Trigger.UPDATE_BEFORE_ROW].length
+                    > 0) {
+                currentTable.fireTriggers(session, Trigger.UPDATE_BEFORE_ROW,
+                                          row.getData(), data, changedColumns);
+                currentTable.enforceRowConstraints(session, data);
+            }
+        }
+
+        if (table.isView) {
+            return rowCount;
+        }
+
+        navigator.beforeFirst();
+
+        for (int i = 0; i < navigator.getSize(); i++) {
+            Row   row            = navigator.getNextRow();
+            Table currentTable   = ((Table) row.getTable());
+            int[] changedColumns = navigator.getCurrentChangedColumns();
+
+            session.addDeleteAction(currentTable, row, changedColumns);
+        }
+
+        navigator.beforeFirst();
+
+        for (int i = 0; i < navigator.getSize(); i++) {
+            Row             row          = navigator.getNextRow();
+            Object[]        data         = navigator.getCurrentChangedData();
+            Table           currentTable = ((Table) row.getTable());
+            int[] changedColumns = navigator.getCurrentChangedColumns();
+            PersistentStore store        = currentTable.getRowStore(session);
+
+            if (data == null) {
+                continue;
+            }
+
+            Row newRow = currentTable.insertSingleRow(session, store, data,
+                changedColumns);
+
+//            newRow.rowAction.updatedAction = row.rowAction;
+        }
+
+        navigator.beforeFirst();
+
+        OrderedHashSet extraUpdateTables = null;
+        boolean hasAfterRowTriggers =
+            table.triggerLists[Trigger.UPDATE_AFTER_ROW].length > 0;
+
+        for (int i = 0; i < navigator.getSize(); i++) {
+            Row      row            = navigator.getNextRow();
+            Table    currentTable   = ((Table) row.getTable());
+            Object[] changedData    = navigator.getCurrentChangedData();
+            int[]    changedColumns = navigator.getCurrentChangedColumns();
+
+            performIntegrityChecks(session, currentTable, row.getData(),
+                                   changedData, changedColumns);
+
+            if (currentTable != table) {
+                if (extraUpdateTables == null) {
+                    extraUpdateTables = new OrderedHashSet();
+                }
+
+                extraUpdateTables.add(currentTable);
+
+                if (currentTable.triggerLists[Trigger.UPDATE_AFTER_ROW].length
+                        > 0) {
+                    hasAfterRowTriggers = true;
+                }
+            }
+        }
+
+        navigator.beforeFirst();
+
+        if (hasAfterRowTriggers) {
+            for (int i = 0; i < navigator.getSize(); i++) {
+                Row      row            = navigator.getNextRow();
+                Object[] changedData    = navigator.getCurrentChangedData();
+                int[]    changedColumns = navigator.getCurrentChangedColumns();
+                Table    currentTable   = ((Table) row.getTable());
+
+                currentTable.fireTriggers(session, Trigger.UPDATE_AFTER_ROW,
+                                          row.getData(), changedData,
+                                          changedColumns);
+            }
+
+            navigator.beforeFirst();
+        }
+
+        baseTable.fireTriggers(session, Trigger.UPDATE_AFTER, navigator);
+
+        if (extraUpdateTables != null) {
+            for (int i = 0; i < extraUpdateTables.size(); i++) {
+                Table currentTable = (Table) extraUpdateTables.get(i);
+
+                currentTable.fireTriggers(session, Trigger.UPDATE_AFTER,
+                                          navigator);
+            }
+        }
+
+        return rowCount;
+    }
+
+    /**
+     * Executes a DELETE statement.
+     *
+     * @return the result of executing the statement
+     */
+    Result executeDeleteStatement(Session session) {
+
+        int count = 0;
+        RangeIterator it = RangeVariable.getIterator(session,
+            targetRangeVariables);
+        RowSetNavigatorDataChange navigator = new RowSetNavigatorDataChange();
+
+        while (it.next()) {
+            Row currentRow = it.getCurrentRow();
+
+            navigator.addRow(currentRow);
+        }
+
+        it.release();
+
+        if (navigator.getSize() > 0) {
+            count = delete(session, baseTable, navigator);
+        } else {
+            return Result.updateZeroResult;
+        }
+
+        if (count == 1) {
+            return Result.updateOneResult;
+        }
+
+        return new Result(ResultConstants.UPDATECOUNT, count);
+    }
+
+    Result executeDeleteTruncateStatement(Session session) {
+
+        PersistentStore store = targetTable.getRowStore(session);
+        RowIterator     it    = targetTable.getPrimaryIndex().firstRow(store);
+
+        try {
+            while (it.hasNext()) {
+                Row row = it.getNextRow();
+
+                session.addDeleteAction((Table) row.getTable(), row, null);
+            }
+
+            if (restartIdentity && targetTable.identitySequence != null) {
+                targetTable.identitySequence.reset();
+            }
+        } finally {
+            it.release();
+        }
+
+        return Result.updateOneResult;
+    }
+
+    /**
+     *  Highest level multiple row delete method. Corresponds to an SQL
+     *  DELETE.
+     */
+    int delete(Session session, Table table,
+               RowSetNavigatorDataChange navigator) {
+
+        int rowCount = navigator.getSize();
+
+        navigator.beforeFirst();
+
+        if (table.fkMainConstraints.length > 0) {
+            HashSet path = session.sessionContext.getConstraintPath();
+
+            for (int i = 0; i < rowCount; i++) {
+                navigator.next();
+
+                Row row = navigator.getCurrentRow();
+
+                performReferentialActions(session, table, navigator, row,
+                                          null, null, path);
+                path.clear();
+            }
+
+            navigator.beforeFirst();
+        }
+
+        while (navigator.hasNext()) {
+            navigator.next();
+
+            Row      row            = navigator.getCurrentRow();
+            Object[] changedData    = navigator.getCurrentChangedData();
+            int[]    changedColumns = navigator.getCurrentChangedColumns();
+            Table    currentTable   = ((Table) row.getTable());
+
+            if (changedData == null) {
+                currentTable.fireTriggers(session, Trigger.DELETE_BEFORE_ROW,
+                                          row.getData(), null, null);
+            } else {
+                currentTable.fireTriggers(session, Trigger.UPDATE_BEFORE_ROW,
+                                          row.getData(), changedData,
+                                          changedColumns);
+            }
+        }
+
+        if (table.isView) {
+            return rowCount;
+        }
+
+        navigator.beforeFirst();
+
+        boolean hasUpdate = false;
+
+        for (int i = 0; i < navigator.getSize(); i++) {
+            Row      row          = navigator.getNextRow();
+            Object[] data         = navigator.getCurrentChangedData();
+            Table    currentTable = ((Table) row.getTable());
+
+            session.addDeleteAction(currentTable, row, null);
+
+            if (data != null) {
+                hasUpdate = true;
+            }
+        }
+
+        navigator.beforeFirst();
+
+        if (hasUpdate) {
+            for (int i = 0; i < navigator.getSize(); i++) {
+                Row             row          = navigator.getNextRow();
+                Object[]        data = navigator.getCurrentChangedData();
+                Table           currentTable = ((Table) row.getTable());
+                int[] changedColumns = navigator.getCurrentChangedColumns();
+                PersistentStore store = currentTable.getRowStore(session);
+
+                if (data == null) {
+                    continue;
+                }
+
+                Row newRow = currentTable.insertSingleRow(session, store,
+                    data, changedColumns);
+
+//                newRow.rowAction.updatedAction = row.rowAction;
+            }
+
+            navigator.beforeFirst();
+        }
+
+        OrderedHashSet extraUpdateTables = null;
+        OrderedHashSet extraDeleteTables = null;
+        boolean hasAfterRowTriggers =
+            table.triggerLists[Trigger.DELETE_AFTER_ROW].length > 0;
+
+        if (rowCount != navigator.getSize()) {
+            while (navigator.hasNext()) {
+                navigator.next();
+
+                Row      row            = navigator.getCurrentRow();
+                Object[] changedData    = navigator.getCurrentChangedData();
+                int[]    changedColumns = navigator.getCurrentChangedColumns();
+                Table    currentTable   = ((Table) row.getTable());
+
+                if (changedData != null) {
+                    performIntegrityChecks(session, currentTable,
+                                           row.getData(), changedData,
+                                           changedColumns);
+                }
+
+                if (currentTable != table) {
+                    if (changedData == null) {
+                        if (currentTable.triggerLists[Trigger.DELETE_AFTER_ROW]
+                                .length > 0) {
+                            hasAfterRowTriggers = true;
+                        }
+
+                        if (extraDeleteTables == null) {
+                            extraDeleteTables = new OrderedHashSet();
+                        }
+
+                        extraDeleteTables.add(currentTable);
+                    } else {
+                        if (currentTable.triggerLists[Trigger.UPDATE_AFTER_ROW]
+                                .length > 0) {
+                            hasAfterRowTriggers = true;
+                        }
+
+                        if (extraUpdateTables == null) {
+                            extraUpdateTables = new OrderedHashSet();
+                        }
+
+                        extraUpdateTables.add(currentTable);
+                    }
+                }
+            }
+
+            navigator.beforeFirst();
+        }
+
+        if (hasAfterRowTriggers) {
+            while (navigator.hasNext()) {
+                navigator.next();
+
+                Row      row          = navigator.getCurrentRow();
+                Object[] changedData  = navigator.getCurrentChangedData();
+                Table    currentTable = ((Table) row.getTable());
+
+                if (changedData == null) {
+                    currentTable.fireTriggers(session,
+                                              Trigger.DELETE_AFTER_ROW,
+                                              row.getData(), null, null);
+                } else {
+                    currentTable.fireTriggers(session,
+                                              Trigger.UPDATE_AFTER_ROW,
+                                              row.getData(), changedData,
+                                              null);
+                }
+            }
+
+            navigator.beforeFirst();
+        }
+
+        table.fireTriggers(session, Trigger.DELETE_AFTER, navigator);
+
+        if (extraUpdateTables != null) {
+            for (int i = 0; i < extraUpdateTables.size(); i++) {
+                Table currentTable = (Table) extraUpdateTables.get(i);
+
+                currentTable.fireTriggers(session, Trigger.UPDATE_AFTER,
+                                          navigator);
+            }
+        }
+
+        if (extraDeleteTables != null) {
+            for (int i = 0; i < extraDeleteTables.size(); i++) {
+                Table currentTable = (Table) extraDeleteTables.get(i);
+
+                currentTable.fireTriggers(session, Trigger.DELETE_AFTER,
+                                          navigator);
+            }
+        }
+
+        return rowCount;
+    }
+
+    static void performIntegrityChecks(Session session, Table table,
+                                       Object[] oldData, Object[] newData,
+                                       int[] updatedColumns) {
+
+        if (newData == null) {
+            return;
+        }
+
+        for (int i = 0, size = table.checkConstraints.length; i < size; i++) {
+            table.checkConstraints[i].checkInsert(session, table, newData,
+                                                  oldData == null);
+        }
+
+        if (!session.database.isReferentialIntegrity()) {
+            return;
+        }
+
+        for (int i = 0, size = table.fkConstraints.length; i < size; i++) {
+            boolean    check = oldData == null;
+            Constraint c     = table.fkConstraints[i];
+
+            if (!check) {
+                check = ArrayUtil.haveCommonElement(c.getRefColumns(),
+                                                    updatedColumns);
+            }
+
+            if (check) {
+                c.checkInsert(session, table, newData, oldData == null);
+            }
+        }
+    }
+
+    static void performReferentialActions(Session session, Table table,
+                                          RowSetNavigatorDataChange navigator,
+                                          Row row, Object[] data,
+                                          int[] changedCols, HashSet path) {
+
+        if (!session.database.isReferentialIntegrity()) {
+            return;
+        }
+
+        boolean delete = data == null;
+
+        for (int i = 0, size = table.fkMainConstraints.length; i < size; i++) {
+            Constraint c      = table.fkMainConstraints[i];
+            int        action = delete ? c.core.deleteAction
+                                       : c.core.updateAction;
+
+            if (!delete) {
+                if (!ArrayUtil.haveCommonElement(changedCols,
+                                                 c.core.mainCols)) {
+                    continue;
+                }
+
+                if (c.core.mainIndex.compareRowNonUnique(
+                        session, row.getData(), data, c.core.mainCols) == 0) {
+                    continue;
+                }
+            }
+
+            RowIterator refiterator = c.findFkRef(session, row.getData());
+
+            if (!refiterator.hasNext()) {
+                refiterator.release();
+
+                continue;
+            }
+
+            while (refiterator.hasNext()) {
+                Row      refRow  = refiterator.getNextRow();
+                Object[] refData = null;
+
+                /** @todo use MATCH */
+                if (c.core.refIndex.compareRowNonUnique(
+                        session, refRow.getData(), row.getData(),
+                        c.core.mainCols) != 0) {
+                    break;
+                }
+
+                if (delete && refRow.getId() == row.getId()) {
+                    continue;
+                }
+
+                switch (action) {
+
+                    case SchemaObject.ReferentialAction.CASCADE : {
+                        if (delete) {
+                            if (navigator.addRow(refRow)) {
+                                performReferentialActions(session,
+                                                          c.core.refTable,
+                                                          navigator, refRow,
+                                                          null, null, path);
+                            }
+
+                            continue;
+                        }
+
+                        refData = c.core.refTable.getEmptyRowData();
+
+                        System.arraycopy(refRow.getData(), 0, refData, 0,
+                                         refData.length);
+
+                        for (int j = 0; j < c.core.refCols.length; j++) {
+                            refData[c.core.refCols[j]] =
+                                data[c.core.mainCols[j]];
+                        }
+
+                        break;
+                    }
+                    case SchemaObject.ReferentialAction.SET_NULL : {
+                        refData = c.core.refTable.getEmptyRowData();
+
+                        System.arraycopy(refRow.getData(), 0, refData, 0,
+                                         refData.length);
+
+                        for (int j = 0; j < c.core.refCols.length; j++) {
+                            refData[c.core.refCols[j]] = null;
+                        }
+
+                        break;
+                    }
+                    case SchemaObject.ReferentialAction.SET_DEFAULT : {
+                        refData = c.core.refTable.getEmptyRowData();
+
+                        System.arraycopy(refRow.getData(), 0, refData, 0,
+                                         refData.length);
+
+                        for (int j = 0; j < c.core.refCols.length; j++) {
+                            ColumnSchema col =
+                                c.core.refTable.getColumn(c.core.refCols[j]);
+
+                            refData[c.core.refCols[j]] =
+                                col.getDefaultValue(session);
+                        }
+
+                        break;
+                    }
+                    case SchemaObject.ReferentialAction.NO_ACTION :
+                    case SchemaObject.ReferentialAction.RESTRICT : {
+                        if (navigator.containsDeletedRow(refRow)) {
+                            continue;
+                        }
+
+                        int errorCode = c.core.deleteAction
+                                        == SchemaObject.ReferentialAction
+                                            .NO_ACTION ? ErrorCode.X_23504
+                                                       : ErrorCode.X_23001;
+                        String[] info = new String[] {
+                            c.core.refName.name, c.core.refTable.getName().name
+                        };
+
+                        refiterator.release();
+
+                        throw Error.error(null, errorCode,
+                                          ErrorCode.CONSTRAINT, info);
+                    }
+                    default :
+                        continue;
+                }
+
+                refData = navigator.addRow(session, refRow, refData,
+                                           table.getColumnTypes(),
+                                           c.core.refCols);
+
+                if (!path.add(c)) {
+                    continue;
+                }
+
+                performReferentialActions(session, c.core.refTable, navigator,
+                                          refRow, refData, c.core.refCols,
+                                          path);
+                path.remove(c);
+            }
+
+            refiterator.release();
+        }
+    }
+}
diff --git a/src/org/hsqldb/StatementDMQL.java b/src/org/hsqldb/StatementDMQL.java
new file mode 100644
index 0000000..da12d7a
--- /dev/null
+++ b/src/org/hsqldb/StatementDMQL.java
@@ -0,0 +1,818 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArraySort;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Statement implementation for DML and base DQL statements.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+
+// fredt@users 20040404 - patch 1.7.2 - fixed type resolution for parameters
+// boucherb@users 200404xx - patch 1.7.2 - changed parameter naming scheme for SQLCI client usability/support
+// fredt@users 20050609 - 1.8.0 - fixed EXPLAIN PLAN by implementing describe(Session)
+// fredt@users - 1.9.0 - support for generated column reporting
+// fredt@users - 1.9.0 - support for multi-row inserts
+public abstract class StatementDMQL extends Statement {
+
+    public static final String PCOL_PREFIX        = "@p";
+    static final String        RETURN_COLUMN_NAME = "@p0";
+
+    /** target table for INSERT_XXX, UPDATE and DELETE and MERGE */
+    Table targetTable;
+    Table baseTable;
+
+    /** column map of query expression */
+    int[]           baseColumnMap;
+    RangeVariable[] targetRangeVariables = RangeVariable.emptyArray;
+
+    /** source table for MERGE */
+    Table sourceTable;
+
+    /** condition expression for UPDATE, MERGE and DELETE */
+    Expression condition;
+
+    /** for TRUNCATE variation of DELETE */
+    boolean restartIdentity;
+
+    /** column map for INSERT operation direct or via MERGE */
+    int[] insertColumnMap = ValuePool.emptyIntArray;
+
+    /** column map for UPDATE operation direct or via MERGE */
+    int[] updateColumnMap     = ValuePool.emptyIntArray;
+    int[] baseUpdateColumnMap = ValuePool.emptyIntArray;
+
+    /** Column value Expressions for UPDATE and MERGE. */
+    Expression[] updateExpressions = Expression.emptyArray;
+
+    /** Column value Expressions for MERGE */
+    Expression[][] multiColumnValues;
+
+    /** INSERT_VALUES */
+    Expression insertExpression;
+
+    /**
+     * Flags indicating which columns' values will/will not be
+     * explicitly set.
+     */
+    boolean[] insertCheckColumns;
+    boolean[] updateCheckColumns;
+
+    /**
+     * Select to be evaluated when this is an INSERT_SELECT or
+     * SELECT statement
+     */
+    QueryExpression queryExpression;
+
+    /**
+     * Parse-order array of Expression objects, all of type PARAMETER ,
+     * involved in some way in any INSERT_XXX, UPDATE, DELETE, SELECT or
+     * CALL CompiledStatement
+     */
+    ExpressionColumn[] parameters;
+
+    /**
+     * int[] contains column indexes for generated values
+     */
+    int[] generatedIndexes;
+
+    /**
+     * ResultMetaData for generated values
+     */
+    ResultMetaData generatedResultMetaData;
+
+    /**
+     * ResultMetaData for parameters
+     */
+    ResultMetaData parameterMetaData;
+
+    /**
+     * Subqueries inverse usage depth order
+     */
+    SubQuery[] subqueries = SubQuery.emptySubqueryArray;
+
+    /**
+     * Total number of RangeIterator objects used
+     */
+    int rangeIteratorCount;
+
+    /**
+     * Database objects used
+     */
+    NumberSequence[] sequences;
+    Routine[]        routines;
+    RangeVariable[]  rangeVariables;
+
+    StatementDMQL(int type, int group, HsqlName schemaName) {
+
+        super(type, group);
+
+        this.schemaName             = schemaName;
+        this.isTransactionStatement = true;
+    }
+
+    void setBaseIndexColumnMap() {
+
+        if (targetTable != baseTable) {
+            baseColumnMap = targetTable.getBaseTableColumnMap();
+        }
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        if (targetTable != null && session.isReadOnly()
+                && !targetTable.isTemp()) {
+            HsqlException e = Error.error(ErrorCode.X_25006);
+
+            return Result.newErrorResult(e);
+        }
+
+        if (isExplain) {
+            return getExplainResult(session);
+        }
+
+        try {
+            if (subqueries.length > 0) {
+                materializeSubQueries(session);
+            }
+
+            result = getResult(session);
+        } catch (Throwable t) {
+            result = Result.newErrorResult(t, null);
+
+            result.getException().setStatementType(group, type);
+        }
+
+        session.sessionContext.clearStructures(this);
+
+        return result;
+    }
+
+    private Result getExplainResult(Session session) {
+
+        Result result = Result.newSingleColumnStringResult("OPERATION",
+            describe(session));
+        OrderedHashSet set = getReferences();
+
+        result.navigator.add(new Object[]{ "Object References" });
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName name = (HsqlName) set.get(i);
+
+            result.navigator.add(new Object[]{
+                name.getSchemaQualifiedStatementName() });
+        }
+
+        result.navigator.add(new Object[]{ "Read Locks" });
+
+        for (int i = 0; i < readTableNames.length; i++) {
+            HsqlName name = readTableNames[i];
+
+            result.navigator.add(new Object[]{
+                name.getSchemaQualifiedStatementName() });
+        }
+
+        result.navigator.add(new Object[]{ "WriteLocks" });
+
+        for (int i = 0; i < writeTableNames.length; i++) {
+            HsqlName name = writeTableNames[i];
+
+            result.navigator.add(new Object[]{
+                name.getSchemaQualifiedStatementName() });
+        }
+
+        return result;
+    }
+
+    abstract Result getResult(Session session);
+
+    abstract void collectTableNamesForRead(OrderedHashSet set);
+
+    abstract void collectTableNamesForWrite(OrderedHashSet set);
+
+    Object[] getGeneratedColumns(Object[] data) {
+
+        if (generatedIndexes == null) {
+            return null;
+        }
+
+        Object[] values = new Object[generatedIndexes.length];
+
+        for (int i = 0; i < generatedIndexes.length; i++) {
+            values[i] = data[generatedIndexes[i]];
+        }
+
+        return values;
+    }
+
+    public boolean hasGeneratedColumns() {
+        return generatedIndexes != null;
+    }
+
+    public ResultMetaData generatedResultMetaData() {
+        return generatedResultMetaData;
+    }
+
+    boolean[] getInsertOrUpdateColumnCheckList() {
+
+        switch (type) {
+
+            case StatementTypes.INSERT :
+                return insertCheckColumns;
+
+            case StatementTypes.UPDATE_WHERE :
+                return updateCheckColumns;
+
+            case StatementTypes.MERGE :
+                boolean[] check =
+                    (boolean[]) ArrayUtil.duplicateArray(insertCheckColumns);
+
+                ArrayUtil.orBooleanArray(updateCheckColumns, check);
+
+                return check;
+        }
+
+        return null;
+    }
+
+    private void setParameters() {
+
+        for (int i = 0; i < parameters.length; i++) {
+            parameters[i].parameterIndex = i;
+        }
+    }
+
+    void materializeSubQueries(Session session) {
+
+        HashSet subqueryPopFlags = new HashSet();
+
+        for (int i = 0; i < subqueries.length; i++) {
+            SubQuery sq = subqueries[i];
+
+            // VIEW working tables may be reused in a single query but they are filled only once
+            if (!subqueryPopFlags.add(sq)) {
+                continue;
+            }
+
+            if (!sq.isCorrelated()) {
+                sq.materialise(session);
+            }
+        }
+    }
+
+    SubQuery[] getSubqueries(Session session) {
+
+        OrderedHashSet subQueries = null;
+
+        for (int i = 0; i < targetRangeVariables.length; i++) {
+            if (targetRangeVariables[i] == null) {
+                continue;
+            }
+
+            OrderedHashSet set = targetRangeVariables[i].getSubqueries();
+
+            subQueries = OrderedHashSet.addAll(subQueries, set);
+        }
+
+        for (int i = 0; i < updateExpressions.length; i++) {
+            subQueries = updateExpressions[i].collectAllSubqueries(subQueries);
+        }
+
+        if (insertExpression != null) {
+            subQueries = insertExpression.collectAllSubqueries(subQueries);
+        }
+
+        if (condition != null) {
+            subQueries = condition.collectAllSubqueries(subQueries);
+        }
+
+        if (queryExpression != null) {
+            OrderedHashSet set = queryExpression.getSubqueries();
+
+            subQueries = OrderedHashSet.addAll(subQueries, set);
+        }
+
+        if (subQueries == null || subQueries.size() == 0) {
+            return SubQuery.emptySubqueryArray;
+        }
+
+        SubQuery[] subQueryArray = new SubQuery[subQueries.size()];
+
+        subQueries.toArray(subQueryArray);
+        ArraySort.sort(subQueryArray, 0, subQueryArray.length,
+                       subQueryArray[0]);
+
+        for (int i = 0; i < subQueryArray.length; i++) {
+            subQueryArray[i].prepareTable(session);
+        }
+
+        return subQueryArray;
+    }
+
+    void setDatabseObjects(Session session, CompileContext compileContext) {
+
+        parameters = compileContext.getParameters();
+
+        setParameters();
+        setParameterMetaData();
+
+        subqueries         = getSubqueries(session);
+        rangeIteratorCount = compileContext.getRangeVarCount();
+        rangeVariables     = compileContext.getRangeVariables();
+        sequences          = compileContext.getSequences();
+        routines           = compileContext.getRoutines();
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        collectTableNamesForWrite(set);
+
+        if (set.size() > 0) {
+            writeTableNames = new HsqlName[set.size()];
+
+            set.toArray(writeTableNames);
+            set.clear();
+        }
+
+        collectTableNamesForRead(set);
+        set.removeAll(writeTableNames);
+
+        if (set.size() > 0) {
+            readTableNames = new HsqlName[set.size()];
+
+            set.toArray(readTableNames);
+        }
+
+        references = compileContext.getSchemaObjectNames();
+
+        if (targetTable != null) {
+            references.add(targetTable.getName());
+        }
+    }
+
+    /**
+     * Determines if the authorizations are adequate
+     * to execute the compiled object. Completion requires the list of
+     * all database objects in a compiled statement.
+     */
+    void checkAccessRights(Session session) {
+
+        if (targetTable != null && !targetTable.isTemp()) {
+            if (targetTable.getOwner().isSystem()) {
+                if (!session.getUser().isSystem()) {
+                    throw Error.error(ErrorCode.X_42501,
+                                      targetTable.getName().name);
+                }
+            }
+
+            if (!session.isProcessingScript) {
+                targetTable.checkDataReadOnly();
+            }
+
+            session.checkReadWrite();
+        }
+
+        if (session.isAdmin()) {
+            return;
+        }
+
+        for (int i = 0; i < sequences.length; i++) {
+            session.getGrantee().checkAccess(sequences[i]);
+        }
+
+        for (int i = 0; i < routines.length; i++) {
+            if (routines[i].isLibraryRoutine()) {
+                continue;
+            }
+
+            session.getGrantee().checkAccess(routines[i]);
+        }
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            RangeVariable range = rangeVariables[i];
+
+            if (range.rangeTable.getSchemaName()
+                    == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            session.getGrantee().checkSelect(range.rangeTable,
+                                             range.usedColumns);
+        }
+
+        switch (type) {
+
+            case StatementTypes.CALL : {
+                break;
+            }
+            case StatementTypes.INSERT : {
+                session.getGrantee().checkInsert(targetTable,
+                                                 insertCheckColumns);
+
+                break;
+            }
+            case StatementTypes.SELECT_CURSOR :
+                break;
+
+            case StatementTypes.DELETE_WHERE : {
+                session.getGrantee().checkDelete(targetTable);
+
+                break;
+            }
+            case StatementTypes.UPDATE_WHERE : {
+                session.getGrantee().checkUpdate(targetTable,
+                                                 updateCheckColumns);
+
+                break;
+            }
+            case StatementTypes.MERGE : {
+                session.getGrantee().checkInsert(targetTable,
+                                                 insertCheckColumns);
+                session.getGrantee().checkUpdate(targetTable,
+                                                 updateCheckColumns);
+
+                break;
+            }
+        }
+    }
+
+    Result getWriteAccessResult(Session session) {
+
+        try {
+            if (targetTable != null && !targetTable.isTemp()) {
+                session.checkReadWrite();
+            }
+        } catch (HsqlException e) {
+            return Result.newErrorResult(e);
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the metadata, which is empty if the CompiledStatement does not
+     * generate a Result.
+     */
+    public ResultMetaData getResultMetaData() {
+
+        switch (type) {
+
+            case StatementTypes.DELETE_WHERE :
+            case StatementTypes.INSERT :
+            case StatementTypes.UPDATE_WHERE :
+            case StatementTypes.MERGE :
+                return ResultMetaData.emptyResultMetaData;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "StatementDMQL");
+        }
+    }
+
+    /** @todo 1.9.0 - build the metadata only once and reuse */
+
+    /**
+     * Returns the metadata for the placeholder parameters.
+     */
+    public ResultMetaData getParametersMetaData() {
+        return parameterMetaData;
+    }
+
+    void setParameterMetaData() {
+
+        int     offset;
+        int     idx;
+        boolean hasReturnValue;
+
+        offset = 0;
+
+        if (parameters.length == 0) {
+            parameterMetaData = ResultMetaData.emptyParamMetaData;
+
+            return;
+        }
+
+// NO:  Not yet
+//        hasReturnValue = (type == CALL && !expression.isProcedureCall());
+//
+//        if (hasReturnValue) {
+//            outlen++;
+//            offset = 1;
+//        }
+        parameterMetaData =
+            ResultMetaData.newParameterMetaData(parameters.length);
+
+// NO: Not yet
+//        if (hasReturnValue) {
+//            e = expression;
+//            out.sName[0]       = DIProcedureInfo.RETURN_COLUMN_NAME;
+//            out.sClassName[0]  = e.getValueClassName();
+//            out.colType[0]     = e.getDataType();
+//            out.colSize[0]     = e.getColumnSize();
+//            out.colScale[0]    = e.getColumnScale();
+//            out.nullability[0] = e.nullability;
+//            out.isIdentity[0]  = false;
+//            out.paramMode[0]   = expression.PARAM_OUT;
+//        }
+        for (int i = 0; i < parameters.length; i++) {
+            idx = i + offset;
+
+            // always i + 1.  We currently use the convention of @p0 to name the
+            // return value OUT parameter
+            parameterMetaData.columnLabels[idx] = StatementDMQL.PCOL_PREFIX
+                                                  + (i + 1);
+            parameterMetaData.columnTypes[idx] = parameters[i].dataType;
+
+            byte parameterMode = SchemaObject.ParameterModes.PARAM_IN;
+
+            if (parameters[i].column != null
+                    && parameters[i].column.getParameterMode()
+                       != SchemaObject.ParameterModes.PARAM_UNKNOWN) {
+                parameterMode = parameters[i].column.getParameterMode();
+            }
+
+            parameterMetaData.paramModes[idx] = parameterMode;
+            parameterMetaData.paramNullable[idx] =
+                parameters[i].column == null
+                ? SchemaObject.Nullability.NULLABLE
+                : parameters[i].column.getNullability();
+        }
+    }
+
+    /**
+     * Retrieves a String representation of this object.
+     */
+    public String describe(Session session) {
+
+        try {
+            return describeImpl(session);
+        } catch (Throwable e) {
+            e.printStackTrace();
+
+            return e.toString();
+        }
+    }
+
+    /**
+     * Provides the toString() implementation.
+     */
+    String describeImpl(Session session) throws Exception {
+
+        StringBuffer sb;
+
+        sb = new StringBuffer();
+
+        int blanks = 0;
+
+        switch (type) {
+
+            case StatementTypes.SELECT_CURSOR : {
+                sb.append(queryExpression.describe(session, 0));
+                appendParms(sb).append('\n');
+                appendSubqueries(session, sb, 2);
+
+                return sb.toString();
+            }
+            case StatementTypes.INSERT : {
+                if (queryExpression == null) {
+                    sb.append("INSERT VALUES");
+                    sb.append('[').append('\n');
+                    appendMultiColumns(sb, insertColumnMap).append('\n');
+                    appendTable(sb).append('\n');
+                    appendParms(sb).append('\n');
+                    appendSubqueries(session, sb, 2).append(']');
+
+                    return sb.toString();
+                } else {
+                    sb.append("INSERT SELECT");
+                    sb.append('[').append('\n');
+                    appendColumns(sb, insertColumnMap).append('\n');
+                    appendTable(sb).append('\n');
+                    sb.append(queryExpression.describe(session,
+                                                       blanks)).append('\n');
+                    appendParms(sb).append('\n');
+                    appendSubqueries(session, sb, 2).append(']');
+
+                    return sb.toString();
+                }
+            }
+            case StatementTypes.UPDATE_WHERE : {
+                sb.append("UPDATE");
+                sb.append('[').append('\n');
+                appendColumns(sb, updateColumnMap).append('\n');
+                appendTable(sb).append('\n');
+                appendCondition(session, sb);
+
+                for (int i = 0; i < targetRangeVariables.length; i++) {
+                    sb.append(targetRangeVariables[i].describe(session,
+                            blanks)).append('\n');
+                }
+
+                appendParms(sb).append('\n');
+                appendSubqueries(session, sb, 2).append(']');
+
+                return sb.toString();
+            }
+            case StatementTypes.DELETE_WHERE : {
+                sb.append("DELETE");
+                sb.append('[').append('\n');
+                appendTable(sb).append('\n');
+                appendCondition(session, sb);
+
+                for (int i = 0; i < targetRangeVariables.length; i++) {
+                    sb.append(targetRangeVariables[i].describe(session,
+                            blanks)).append('\n');
+                }
+
+                appendParms(sb).append('\n');
+                appendSubqueries(session, sb, 2).append(']');
+
+                return sb.toString();
+            }
+            case StatementTypes.CALL : {
+                sb.append("CALL");
+                sb.append('[').append(']');
+
+                return sb.toString();
+            }
+            case StatementTypes.MERGE : {
+                sb.append("MERGE");
+                sb.append('[').append('\n');
+                appendMultiColumns(sb, insertColumnMap).append('\n');
+                appendColumns(sb, updateColumnMap).append('\n');
+                appendTable(sb).append('\n');
+                appendCondition(session, sb);
+
+                for (int i = 0; i < targetRangeVariables.length; i++) {
+                    sb.append(targetRangeVariables[i].describe(session,
+                            blanks)).append('\n');
+                }
+
+                appendParms(sb).append('\n');
+                appendSubqueries(session, sb, 2).append(']');
+
+                return sb.toString();
+            }
+            default : {
+                return "UNKNOWN";
+            }
+        }
+    }
+
+    private StringBuffer appendSubqueries(Session session, StringBuffer sb,
+                                          int blanks) {
+
+        sb.append("SUBQUERIES[");
+
+        for (int i = 0; i < subqueries.length; i++) {
+            sb.append("\n[level=").append(subqueries[i].level).append('\n');
+
+            if (subqueries[i].queryExpression != null) {
+                sb.append(subqueries[i].queryExpression.describe(session,
+                        blanks));
+            }
+
+            sb.append("]");
+        }
+
+        sb.append(']');
+
+        return sb;
+    }
+
+    private StringBuffer appendTable(StringBuffer sb) {
+
+        sb.append("TABLE[").append(targetTable.getName().name).append(']');
+
+        return sb;
+    }
+
+    private StringBuffer appendSourceTable(StringBuffer sb) {
+
+        sb.append("SOURCE TABLE[").append(sourceTable.getName().name).append(
+            ']');
+
+        return sb;
+    }
+
+    private StringBuffer appendColumns(StringBuffer sb, int[] columnMap) {
+
+        if (columnMap == null || updateExpressions.length == 0) {
+            return sb;
+        }
+
+        sb.append("COLUMNS=[");
+
+        for (int i = 0; i < columnMap.length; i++) {
+            sb.append('\n').append(columnMap[i]).append(':').append(
+                ' ').append(
+                targetTable.getColumn(columnMap[i]).getNameString());
+        }
+
+        for (int i = 0; i < updateExpressions.length; i++) {
+            sb.append('[').append(updateExpressions[i]).append(']');
+        }
+
+        sb.append(']');
+
+        return sb;
+    }
+
+    private StringBuffer appendMultiColumns(StringBuffer sb, int[] columnMap) {
+
+        if (columnMap == null || multiColumnValues == null) {
+            return sb;
+        }
+
+        sb.append("COLUMNS=[");
+
+        for (int j = 0; j < multiColumnValues.length; j++) {
+            for (int i = 0; i < columnMap.length; i++) {
+                sb.append('\n').append(columnMap[i]).append(':').append(
+                    ' ').append(
+                    targetTable.getColumn(columnMap[i]).getName().name).append(
+                    '[').append(multiColumnValues[j][i]).append(']');
+            }
+        }
+
+        sb.append(']');
+
+        return sb;
+    }
+
+    private StringBuffer appendParms(StringBuffer sb) {
+
+        sb.append("PARAMETERS=[");
+
+        for (int i = 0; i < parameters.length; i++) {
+            sb.append('\n').append('@').append(i).append('[').append(
+                parameters[i].describe(null, 0)).append(']');
+        }
+
+        sb.append(']');
+
+        return sb;
+    }
+
+    private StringBuffer appendCondition(Session session, StringBuffer sb) {
+
+        return condition == null ? sb.append("CONDITION[]\n")
+                                 : sb.append("CONDITION[").append(
+                                     condition.describe(session, 0)).append(
+                                     "]\n");
+    }
+
+    public void resolve(Session session) {}
+
+    public RangeVariable[] getRangeVariables() {
+        return rangeVariables;
+    }
+
+    public final boolean isCatalogChange() {
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/StatementExpression.java b/src/org/hsqldb/StatementExpression.java
new file mode 100644
index 0000000..c1d565d
--- /dev/null
+++ b/src/org/hsqldb/StatementExpression.java
@@ -0,0 +1,188 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArraySort;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.result.Result;
+
+/**
+ * Implementation of Statement for PSM statements with expressions.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementExpression extends StatementDMQL {
+
+    Expression expression;
+
+    /**
+     * for RETURN and flow control
+     */
+    StatementExpression(Session session, CompileContext compileContext,
+                        int type, Expression expression) {
+
+        super(type, StatementTypes.X_SQL_CONTROL, null);
+
+        switch (type) {
+
+            case StatementTypes.RETURN :
+            case StatementTypes.CONDITION :
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "");
+        }
+
+        isTransactionStatement = false;
+        this.expression        = expression;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        switch (type) {
+
+            case StatementTypes.RETURN :
+                return sql;
+
+            case StatementTypes.CONDITION :
+                sb.append(expression.getSQL());
+                break;
+        }
+
+        return sb.toString();
+    }
+
+    SubQuery[] getSubqueries(Session session) {
+
+        OrderedHashSet subQueries = null;
+
+        if (expression != null) {
+            subQueries = expression.collectAllSubqueries(subQueries);
+        }
+
+        if (subQueries == null || subQueries.size() == 0) {
+            return SubQuery.emptySubqueryArray;
+        }
+
+        SubQuery[] subQueryArray = new SubQuery[subQueries.size()];
+
+        subQueries.toArray(subQueryArray);
+        ArraySort.sort(subQueryArray, 0, subQueryArray.length,
+                       subQueryArray[0]);
+
+        for (int i = 0; i < subqueries.length; i++) {
+            subQueryArray[i].prepareTable(session);
+        }
+
+        return subQueryArray;
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        sb.append(Tokens.T_STATEMENT);
+
+        return sb.toString();
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        try {
+            if (subqueries.length > 0) {
+                materializeSubQueries(session);
+            }
+
+            result = getResult(session);
+        } catch (Throwable t) {
+            result = Result.newErrorResult(t, null);
+        }
+
+        if (result.isError()) {
+            result.getException().setStatementType(group, type);
+        }
+
+        return result;
+    }
+
+    Result getResult(Session session) {
+
+        switch (type) {
+
+            case StatementTypes.RETURN :
+            case StatementTypes.CONDITION :
+                return expression.getResult(session);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "");
+        }
+    }
+
+    public void resolve(Session session) {}
+
+    String describeImpl(Session session) throws Exception {
+        return getSQL();
+    }
+
+    void collectTableNamesForRead(OrderedHashSet set) {
+
+        for (int i = 0; i < subqueries.length; i++) {
+            if (subqueries[i].queryExpression != null) {
+                subqueries[i].queryExpression.getBaseTableNames(set);
+            }
+        }
+
+        for (int i = 0; i < routines.length; i++) {
+            set.addAll(routines[i].getTableNamesForRead());
+        }
+    }
+
+    void collectTableNamesForWrite(OrderedHashSet set) {}
+}
diff --git a/src/org/hsqldb/StatementHandler.java b/src/org/hsqldb/StatementHandler.java
new file mode 100644
index 0000000..648b5ca
--- /dev/null
+++ b/src/org/hsqldb/StatementHandler.java
@@ -0,0 +1,227 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.result.Result;
+
+/**
+ * Implementation of Statement for condition handler objects.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementHandler extends Statement {
+
+    public static final int NONE          = 0;
+    public static final int SQL_EXCEPTION = 1;
+    public static final int SQL_WARNING   = 2;
+    public static final int SQL_NOT_FOUND = 3;
+    public static final int SQL_STATE     = 4;
+
+    //
+    public static final int CONTINUE = 5;
+    public static final int EXIT     = 6;
+    public static final int UNDO     = 7;
+
+    //
+    public final int handlerType;
+
+    //
+    OrderedIntHashSet conditionGroups = new OrderedIntHashSet();
+    OrderedHashSet    conditionStates = new OrderedHashSet();
+    Statement         statement;
+
+    //
+    public static final StatementHandler[] emptyExceptionHandlerArray =
+        new StatementHandler[]{};
+
+    StatementHandler(int handlerType) {
+
+        super(StatementTypes.HANDLER, StatementTypes.X_SQL_CONTROL);
+
+        this.handlerType = handlerType;
+    }
+
+    public void addConditionState(String sqlState) {
+
+        boolean result = conditionStates.add(sqlState);
+
+        result &= conditionGroups.isEmpty();
+
+        if (!result) {
+            throw Error.error(ErrorCode.X_42604);
+        }
+    }
+
+    public void addConditionType(int conditionType) {
+
+        boolean result = conditionGroups.add(conditionType);
+
+        result &= conditionStates.isEmpty();
+
+        if (!result) {
+            throw Error.error(ErrorCode.X_42604);
+        }
+    }
+
+    public void addStatement(Statement s) {
+        statement = s;
+    }
+
+    public boolean handlesConditionType(int type) {
+        return conditionGroups.contains(type);
+    }
+
+    public boolean handlesCondition(String sqlState) {
+
+        if (conditionStates.contains(sqlState)) {
+            return true;
+        }
+
+        String conditionClass = sqlState.substring(0, 2);
+
+        if (conditionStates.contains(conditionClass)) {
+            return true;
+        }
+
+        if (conditionClass.equals("01")) {
+            return conditionGroups.contains(SQL_WARNING);
+        }
+
+        if (conditionClass.equals("02")) {
+            return conditionGroups.contains(SQL_NOT_FOUND);
+        }
+
+        return conditionGroups.contains(SQL_EXCEPTION);
+    }
+
+    public int[] getConditionTypes() {
+        return conditionGroups.toArray();
+    }
+
+    public String[] getConditionStates() {
+        return (String[]) conditionStates.toArray(
+            new String[conditionStates.size()]);
+    }
+
+    public void resolve(Session session) {
+
+        if (statement != null) {
+            statement.resolve(session);
+
+            readTableNames  = statement.getTableNamesForRead();
+            writeTableNames = statement.getTableNamesForWrite();
+        }
+    }
+
+    public Result execute(Session session) {
+
+        if (statement != null) {
+            return statement.execute(session);
+        } else {
+            return Result.updateZeroResult;
+        }
+    }
+
+    public String describe(Session session) {
+        return "";
+    }
+
+    public OrderedHashSet getReferences() {
+
+        if (statement == null) {
+            return new OrderedHashSet();
+        }
+
+        return statement.getReferences();
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer(64);
+        String       s;
+
+        s = handlerType == CONTINUE ? Tokens.T_CONTINUE
+                                    : handlerType == EXIT ? Tokens.T_EXIT
+                                                          : Tokens.T_UNDO;
+
+        sb.append(Tokens.T_DECLARE).append(' ').append(s).append(' ');
+        sb.append(Tokens.T_HANDLER).append(' ').append(Tokens.T_FOR);
+        sb.append(' ');
+
+        for (int i = 0; i < conditionStates.size(); i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+
+            sb.append(Tokens.T_SQLSTATE).append(' ');
+            sb.append('\'').append(conditionStates.get(i)).append('\'');
+        }
+
+        for (int i = 0; i < conditionGroups.size(); i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+
+            switch (conditionGroups.get(i)) {
+
+                case SQL_EXCEPTION :
+                    sb.append(Tokens.T_SQLEXCEPTION);
+                    break;
+
+                case SQL_WARNING :
+                    sb.append(Tokens.T_SQLWARNING);
+                    break;
+
+                case SQL_NOT_FOUND :
+                    sb.append(Tokens.T_NOT).append(' ').append(Tokens.FOUND);
+                    break;
+            }
+        }
+
+        if (statement != null) {
+            sb.append(' ').append(statement.getSQL());
+        }
+
+        return sb.toString();
+    }
+
+    public boolean isCatalogChange() {
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/StatementInsert.java b/src/org/hsqldb/StatementInsert.java
new file mode 100644
index 0000000..0160a03
--- /dev/null
+++ b/src/org/hsqldb/StatementInsert.java
@@ -0,0 +1,283 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.navigator.RangeIterator;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of Statement for INSERT statements.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementInsert extends StatementDML {
+
+    int            generatedType;
+    ResultMetaData generatedInputMetaData;
+    boolean        isSimpleInsert;
+    int            overrideUserValue = -1;
+
+    /**
+     * Instantiate this as an INSERT_VALUES statement.
+     */
+    StatementInsert(Session session, Table targetTable, int[] columnMap,
+                    Expression insertExpression, boolean[] checkColumns,
+                    CompileContext compileContext) {
+
+        super(StatementTypes.INSERT, StatementTypes.X_SQL_DATA_CHANGE,
+              session.getCurrentSchemaHsqlName());
+
+        this.targetTable = targetTable;
+        this.baseTable   = targetTable.isTriggerInsertable() ? targetTable
+                                                             : targetTable
+                                                             .getBaseTable();
+        this.insertColumnMap    = columnMap;
+        this.insertCheckColumns = checkColumns;
+        this.insertExpression   = insertExpression;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+        setupChecks();
+
+        isSimpleInsert = insertExpression != null
+                         && insertExpression.nodes.length == 1
+                         && updatableTableCheck == null;
+    }
+
+    /**
+     * Instantiate this as an INSERT_SELECT statement.
+     */
+    StatementInsert(Session session, Table targetTable, int[] columnMap,
+                    boolean[] checkColumns, QueryExpression queryExpression,
+                    CompileContext compileContext, int override) {
+
+        super(StatementTypes.INSERT, StatementTypes.X_SQL_DATA_CHANGE,
+              session.getCurrentSchemaHsqlName());
+
+        this.targetTable = targetTable;
+        this.baseTable   = targetTable.isTriggerInsertable() ? targetTable
+                                                             : targetTable
+                                                             .getBaseTable();
+        this.insertColumnMap    = columnMap;
+        this.insertCheckColumns = checkColumns;
+        this.queryExpression    = queryExpression;
+        this.overrideUserValue  = override;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+        setupChecks();
+    }
+
+    /**
+     * Executes an INSERT_SELECT or INSERT_VALUESstatement.  It is assumed that
+     * the argument is of the correct type.
+     *
+     * @return the result of executing the statement
+     */
+    Result getResult(Session session) {
+
+        Result          resultOut          = null;
+        RowSetNavigator generatedNavigator = null;
+        PersistentStore store              = baseTable.getRowStore(session);
+
+        if (generatedIndexes != null) {
+            resultOut = Result.newUpdateCountResult(generatedResultMetaData,
+                    0);
+            generatedNavigator = resultOut.getChainedResult().getNavigator();
+        }
+
+        if (isSimpleInsert) {
+            Type[] colTypes = baseTable.getColumnTypes();
+            Object[] data = getInsertData(session, colTypes,
+                                          insertExpression.nodes[0].nodes);
+
+            return insertSingleRow(session, store, data);
+        }
+
+        RowSetNavigator newDataNavigator = queryExpression == null
+                                           ? getInsertValuesNavigator(session)
+                                           : getInsertSelectNavigator(session);
+
+        if (newDataNavigator.getSize() > 0) {
+            insertRowSet(session, generatedNavigator, newDataNavigator);
+        }
+
+        if (baseTable.triggerLists[Trigger.INSERT_AFTER].length > 0) {
+            baseTable.fireTriggers(session, Trigger.INSERT_AFTER,
+                                   newDataNavigator);
+        }
+
+        if (resultOut == null) {
+            resultOut = new Result(ResultConstants.UPDATECOUNT,
+                                   newDataNavigator.getSize());
+        } else {
+            resultOut.setUpdateCount(newDataNavigator.getSize());
+        }
+
+        return resultOut;
+    }
+
+    RowSetNavigator getInsertSelectNavigator(Session session) {
+
+        Type[] colTypes  = baseTable.getColumnTypes();
+        int[]  columnMap = insertColumnMap;
+
+        //
+        Result                result = queryExpression.getResult(session, 0);
+        RowSetNavigator       nav         = result.initialiseNavigator();
+        Type[]                sourceTypes = result.metaData.columnTypes;
+        RowSetNavigatorClient newData     = new RowSetNavigatorClient(2);
+
+        while (nav.hasNext()) {
+            Object[] data       = baseTable.getNewRowData(session);
+            Object[] sourceData = (Object[]) nav.getNext();
+
+            for (int i = 0; i < columnMap.length; i++) {
+                int j = columnMap[i];
+
+                if (j == this.overrideUserValue) {
+                    continue;
+                }
+
+                Type sourceType = sourceTypes[i];
+
+                data[j] = colTypes[j].convertToType(session, sourceData[i],
+                                                    sourceType);
+            }
+
+            newData.add(data);
+        }
+
+        return newData;
+    }
+
+    RowSetNavigator getInsertValuesNavigator(Session session) {
+
+        Type[] colTypes = baseTable.getColumnTypes();
+
+        //
+        Expression[]          list    = insertExpression.nodes;
+        RowSetNavigatorClient newData = new RowSetNavigatorClient(list.length);
+
+        for (int j = 0; j < list.length; j++) {
+            Expression[] rowArgs = list[j].nodes;
+            Object[]     data    = getInsertData(session, colTypes, rowArgs);
+
+            newData.add(data);
+        }
+
+        return newData;
+    }
+
+    /**
+     * @todo - fredt - this does not work with different prepare calls
+     * with the same SQL statement, but different generated column requests
+     * To fix, add comment encapsulating the generated column list to SQL
+     * to differentiate between the two invocations
+     */
+    public void setGeneratedColumnInfo(int generate, ResultMetaData meta) {
+
+        // can support INSERT_SELECT also
+        if (type != StatementTypes.INSERT) {
+            return;
+        }
+
+        int colIndex = baseTable.getIdentityColumnIndex();
+
+        if (colIndex == -1) {
+            return;
+        }
+
+        generatedType          = generate;
+        generatedInputMetaData = meta;
+
+        switch (generate) {
+
+            case ResultConstants.RETURN_NO_GENERATED_KEYS :
+                return;
+
+            case ResultConstants.RETURN_GENERATED_KEYS_COL_INDEXES :
+                int[] columnIndexes = meta.getGeneratedColumnIndexes();
+
+                if (columnIndexes.length != 1) {
+                    return;
+                }
+
+                if (columnIndexes[0] != colIndex) {
+                    return;
+                }
+
+            // fall through
+            case ResultConstants.RETURN_GENERATED_KEYS :
+                generatedIndexes = new int[]{ colIndex };
+                break;
+
+            case ResultConstants.RETURN_GENERATED_KEYS_COL_NAMES :
+                String[] columnNames = meta.getGeneratedColumnNames();
+
+                if (columnNames.length != 1) {
+                    return;
+                }
+
+                if (baseTable.findColumn(columnNames[0]) != colIndex) {
+                    return;
+                }
+
+                generatedIndexes = new int[]{ colIndex };
+                break;
+        }
+
+        generatedResultMetaData =
+            ResultMetaData.newResultMetaData(generatedIndexes.length);
+
+        for (int i = 0; i < generatedIndexes.length; i++) {
+            ColumnSchema column = baseTable.getColumn(generatedIndexes[i]);
+
+            generatedResultMetaData.columns[i] = column;
+        }
+
+        generatedResultMetaData.prepareData();
+
+        isSimpleInsert = false;
+    }
+}
diff --git a/src/org/hsqldb/StatementManager.java b/src/org/hsqldb/StatementManager.java
new file mode 100644
index 0000000..e48c7fe
--- /dev/null
+++ b/src/org/hsqldb/StatementManager.java
@@ -0,0 +1,312 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.LongKeyHashMap;
+import org.hsqldb.lib.LongValueHashMap;
+import org.hsqldb.result.Result;
+
+/**
+ * This class manages the reuse of Statement objects for prepared
+ * statements for a Session instance.<p>
+ *
+ * A compiled statement is registered by a session to be managed. Once
+ * registered, it is linked with one or more sessions.<p>
+ *
+ * The sql statement text distinguishes different compiled statements and acts
+ * as lookup key when a session initially looks for an existing instance of
+ * the compiled sql statement.<p>
+ *
+ * Once a session is linked with a statement, it uses the uniqe compiled
+ * statement id for the sql statement to access the statement.<p>
+ *
+ * Changes to database structure via DDL statements, will result in all
+ * registered Statement objects to become invalidated. This is done by
+ * comparing the schema change and compile timestamps. When a session
+ * subsequently attempts to use an invalidated Statement via its id, it will
+ * reinstantiate the Statement using its sql statement still held by this class.<p>
+ *
+ * This class keeps count of the number of time each registered compiled
+ * statement is linked to a session. It unregisters a compiled statement when
+ * no session remains linked to it.<p>
+ *
+ * Modified by fredt@users from the original by boucherb@users to simplify,
+ * support multiple identical prepared statements per session, and avoid
+ * memory leaks. Modified further to support schemas. Changed implementation
+ * in 1.9 as a session object<p>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ *
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public final class StatementManager {
+
+    /**
+     * The Database for which this object is managing
+     * CompiledStatement objects.
+     */
+    private Database database;
+
+    /** Map: Schema id (int) => {Map: SQL String => Compiled Statement id (long)} */
+    private IntKeyHashMap schemaMap;
+
+    /** Map: Compiled Statement id (int) => SQL String */
+    private LongKeyHashMap sqlLookup;
+
+    /** Map: Compiled statment id (int) => CompiledStatement object. */
+    private LongKeyHashMap csidMap;
+
+    /**
+     * Monotonically increasing counter used to assign unique ids to compiled
+     * statements.
+     */
+    private long next_cs_id;
+
+    /**
+     * Constructs a new instance of <code>CompiledStatementManager</code>.
+     *
+     * @param database the Database instance for which this object is to
+     *      manage compiled statement objects.
+     */
+    StatementManager(Database database) {
+
+        this.database = database;
+        schemaMap     = new IntKeyHashMap();
+        sqlLookup     = new LongKeyHashMap();
+        csidMap       = new LongKeyHashMap();
+        next_cs_id    = 0;
+    }
+
+    /**
+     * Clears all internal data structures, removing any references to compiled statements.
+     */
+    synchronized void reset() {
+
+        schemaMap.clear();
+        sqlLookup.clear();
+        csidMap.clear();
+
+        next_cs_id = 0;
+    }
+
+    /**
+     * Retrieves the next compiled statement identifier in the sequence.
+     *
+     * @return the next compiled statement identifier in the sequence.
+     */
+    private long nextID() {
+
+        next_cs_id++;
+
+        return next_cs_id;
+    }
+
+    /**
+     * Retrieves the registered compiled statement identifier associated with
+     * the specified SQL String, or a value less than zero, if no such
+     * statement has been registered.
+     *
+     * @param schema the schema id
+     * @param sql the SQL String
+     * @return the compiled statement identifier associated with the
+     *      specified SQL String
+     */
+    private long getStatementID(HsqlName schema, String sql) {
+
+        LongValueHashMap sqlMap =
+            (LongValueHashMap) schemaMap.get(schema.hashCode());
+
+        if (sqlMap == null) {
+            return -1;
+        }
+
+        return sqlMap.get(sql, -1);
+    }
+
+    /**
+     * Returns an existing CompiledStatement object with the given
+     * statement identifier. Returns null if the CompiledStatement object
+     * has been invalidated and cannot be recompiled
+     *
+     * @param session the session
+     * @param csid the identifier of the requested CompiledStatement object
+     * @return the requested CompiledStatement object
+     */
+    public synchronized Statement getStatement(Session session, long csid) {
+
+        Statement cs = (Statement) csidMap.get(csid);
+
+        if (cs == null) {
+            return null;
+        }
+
+        if (cs.getCompileTimestamp()
+                < database.schemaManager.getSchemaChangeTimestamp()) {
+            String   sql       = (String) sqlLookup.get(csid);
+            HsqlName oldSchema = session.getCurrentSchemaHsqlName();
+
+            // revalidate with the original schema
+            try {
+                HsqlName schema = cs.getSchemaName();
+
+                session.setSchema(schema.name);
+
+                StatementInsert si = null;
+
+                if (cs.generatedResultMetaData() != null) {
+                    si = (StatementInsert) cs;
+                }
+
+                cs = session.compileStatement(sql, cs.getResultProperties());
+
+                cs.setID(csid);
+                cs.setCompileTimestamp(
+                    database.txManager.getGlobalChangeTimestamp());
+
+                if (si != null) {
+                    cs.setGeneratedColumnInfo(si.generatedType,
+                                              si.generatedInputMetaData);
+                }
+
+                csidMap.put(csid, cs);
+            } catch (Throwable t) {
+                freeStatement(csid);
+
+                return null;
+            } finally {
+                session.setSchema(oldSchema.name);
+            }
+        }
+
+        return cs;
+    }
+
+    /**
+     * Registers a compiled statement to be managed.
+     *
+     * The only caller should be a Session that is attempting to prepare
+     * a statement for the first time or process a statement that has been
+     * invalidated due to DDL changes.
+     *
+     * @param csid existing id or negative if the statement is not yet managed
+     * @param cs The CompiledStatement to add
+     * @return The compiled statement id assigned to the CompiledStatement
+     *  object
+     */
+    private long registerStatement(long csid, Statement cs) {
+
+        if (csid < 0) {
+            csid = nextID();
+
+            int schemaid = cs.getSchemaName().hashCode();
+            LongValueHashMap sqlMap =
+                (LongValueHashMap) schemaMap.get(schemaid);
+
+            if (sqlMap == null) {
+                sqlMap = new LongValueHashMap();
+
+                schemaMap.put(schemaid, sqlMap);
+            }
+
+            sqlMap.put(cs.getSQL(), csid);
+            sqlLookup.put(csid, cs.getSQL());
+        }
+
+        cs.setID(csid);
+        cs.setCompileTimestamp(database.txManager.getGlobalChangeTimestamp());
+        csidMap.put(csid, cs);
+
+        return csid;
+    }
+
+    /**
+     * Removes one (or all) of the links between a session and a compiled
+     * statement. If the statement is not linked with any other session, it is
+     * removed from management.
+     *
+     * @param csid the compiled statment identifier
+     * @param sessionID the session identifier
+     * @param freeAll if true, remove all links to the session
+     */
+    synchronized void freeStatement(long csid) {
+
+        if (csid == -1) {
+
+            // statement was never added
+            return;
+        }
+
+        Statement cs = (Statement) csidMap.remove(csid);
+
+        if (cs != null) {
+            int schemaid = cs.getSchemaName().hashCode();
+            LongValueHashMap sqlMap =
+                (LongValueHashMap) schemaMap.get(schemaid);
+            String sql = (String) sqlLookup.remove(csid);
+
+            sqlMap.remove(sql);
+        }
+    }
+
+    /**
+     * Compiles an SQL statement and returns a CompiledStatement Object
+     *
+     * @param session the session
+     * @throws Throwable
+     * @return CompiledStatement
+     */
+    synchronized Statement compile(Session session,
+                                   Result cmd) throws Throwable {
+
+        String    sql  = cmd.getMainString();
+        long      csid = getStatementID(session.currentSchema, sql);
+        Statement cs   = (Statement) csidMap.get(csid);
+        int       props;
+
+        if (cs == null || !cs.isValid()
+                || cs.getCompileTimestamp()
+                   < database.schemaManager.getSchemaChangeTimestamp()) {
+            props = cmd.getExecuteProperties();
+            cs    = session.compileStatement(sql, props);
+            csid  = registerStatement(csid, cs);
+        }
+
+        cs.setGeneratedColumnInfo(cmd.getGeneratedResultType(),
+                                  cmd.getGeneratedResultMetaData());
+
+        return cs;
+    }
+}
diff --git a/src/org/hsqldb/StatementProcedure.java b/src/org/hsqldb/StatementProcedure.java
new file mode 100644
index 0000000..12c0c6c
--- /dev/null
+++ b/src/org/hsqldb/StatementProcedure.java
@@ -0,0 +1,363 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArraySort;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of Statement for callable procedures.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementProcedure extends StatementDMQL {
+
+    /** Expression to evaluate */
+    Expression expression;
+
+    /** Routine to execute */
+    Routine procedure;
+
+    /** arguments to Routine */
+    Expression[]   arguments = Expression.emptyArray;
+    ResultMetaData resultMetaData;
+
+    /**
+     * Constructor for CALL statements for expressions.
+     */
+    StatementProcedure(Session session, Expression expression,
+                       CompileContext compileContext) {
+
+        super(StatementTypes.CALL, StatementTypes.X_SQL_DATA,
+              session.getCurrentSchemaHsqlName());
+
+        this.expression = expression;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+
+        if (procedure != null) {
+            session.getGrantee().checkAccess(procedure);
+        }
+    }
+
+    /**
+     * Constructor for CALL statements for procedures.
+     */
+    StatementProcedure(Session session, Routine procedure,
+                       Expression[] arguments, CompileContext compileContext) {
+
+        super(StatementTypes.CALL, StatementTypes.X_SQL_DATA,
+              session.getCurrentSchemaHsqlName());
+
+        this.procedure = procedure;
+        this.arguments = arguments;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+    }
+
+    Result getResult(Session session) {
+        return expression == null ? getProcedureResult(session)
+                                  : getExpressionResult(session);
+    }
+
+    Result getProcedureResult(Session session) {
+
+        Object[] data = ValuePool.emptyObjectArray;
+
+        if (arguments.length > 0) {
+            data = new Object[arguments.length];
+        }
+
+        for (int i = 0; i < arguments.length; i++) {
+            Expression e     = arguments[i];
+            Object     value = e.getValue(session);
+
+            if (e != null) {
+                Type targetType = procedure.getParameter(i).getDataType();
+
+                data[i] = targetType.convertToType(session, value,
+                                                   e.getDataType());
+            }
+        }
+
+        session.sessionContext.push();
+
+        session.sessionContext.routineArguments = data;
+        session.sessionContext.routineVariables = ValuePool.emptyObjectArray;
+
+        Result result = Result.updateZeroResult;
+
+        if (procedure.isPSM()) {
+            result = executePSMProcedure(session);
+        } else {
+            result = executeJavaProcedure(session);
+        }
+
+        Object[] callArguments = session.sessionContext.routineArguments;
+
+        session.sessionContext.pop();
+
+        if (result.isError()) {
+            return result;
+        }
+
+        if (result.isSimpleValue()) {
+            result = Result.updateZeroResult;
+        }
+
+        boolean returnParams = false;
+
+        for (int i = 0; i < procedure.getParameterCount(); i++) {
+            ColumnSchema param = procedure.getParameter(i);
+            int          mode  = param.getParameterMode();
+
+            if (mode != SchemaObject.ParameterModes.PARAM_IN) {
+                if (this.arguments[i].isDynamicParam()) {
+                    int paramIndex = arguments[i].parameterIndex;
+
+                    session.sessionContext.dynamicArguments[paramIndex] =
+                        callArguments[i];
+                    returnParams = true;
+                } else {
+                    int varIndex = arguments[i].getColumnIndex();
+
+                    session.sessionContext.routineVariables[varIndex] =
+                        callArguments[i];
+                }
+            }
+        }
+
+        if (returnParams) {
+            result = Result.newCallResponse(
+                this.getParametersMetaData().getParameterTypes(), this.id,
+                session.sessionContext.dynamicArguments);
+        }
+
+        return result;
+    }
+
+    Result executePSMProcedure(Session session) {
+
+        int variableCount = procedure.getVariableCount();
+
+        if (variableCount > 0) {
+            session.sessionContext.routineVariables =
+                new Object[variableCount];
+        }
+
+        Result result = procedure.statement.execute(session);
+
+        if (!result.isError()) {
+            result = Result.updateZeroResult;
+        }
+
+        return result;
+    }
+
+    Result executeJavaProcedure(Session session) {
+
+        Result   result        = Result.updateZeroResult;
+        int      extraArg      = procedure.javaMethodWithConnection ? 1
+                                                                    : 0;
+        Object[] callArguments = session.sessionContext.routineArguments;
+        Object[] data          = new Object[callArguments.length + extraArg];
+
+        data = procedure.convertArgsToJava(session, callArguments);
+
+        if (procedure.javaMethodWithConnection) {
+            data[0] = session.getInternalConnection();
+        }
+
+        result = procedure.invokeJavaMethod(session, data);
+
+        procedure.convertArgsToSQL(session, callArguments, data);
+
+        return result;
+    }
+
+    Result getExpressionResult(Session session) {
+
+        Object o;    // expression return value
+        Result r;
+
+        session.sessionData.startRowProcessing();
+
+        o = expression.getValue(session);
+
+        if (o instanceof Result) {
+            return (Result) o;
+        }
+
+        if (resultMetaData == null) {
+            getResultMetaData();
+        }
+
+        r = Result.newSingleColumnResult(resultMetaData);
+
+        Object[] row;
+
+        if (expression.getDataType().isArrayType()) {
+            row    = new Object[1];
+            row[0] = o;
+        } else if (o instanceof Object[]) {
+            row = (Object[]) o;
+        } else {
+            row    = new Object[1];
+            row[0] = o;
+        }
+
+        r.getNavigator().add(row);
+
+        return r;
+    }
+
+    SubQuery[] getSubqueries(Session session) {
+
+        OrderedHashSet subQueries = null;
+
+        if (expression != null) {
+            subQueries = expression.collectAllSubqueries(subQueries);
+        }
+
+        for (int i = 0; i < arguments.length; i++) {
+            subQueries = arguments[i].collectAllSubqueries(subQueries);
+        }
+
+        if (subQueries == null || subQueries.size() == 0) {
+            return SubQuery.emptySubqueryArray;
+        }
+
+        SubQuery[] subQueryArray = new SubQuery[subQueries.size()];
+
+        subQueries.toArray(subQueryArray);
+        ArraySort.sort(subQueryArray, 0, subQueryArray.length,
+                       subQueryArray[0]);
+
+        for (int i = 0; i < subqueries.length; i++) {
+            subQueryArray[i].prepareTable(session);
+        }
+
+        return subQueryArray;
+    }
+
+    public ResultMetaData getResultMetaData() {
+
+        if (resultMetaData != null) {
+            return resultMetaData;
+        }
+
+        switch (type) {
+
+            case StatementTypes.CALL : {
+                if (expression == null) {
+                    return ResultMetaData.emptyResultMetaData;
+                }
+
+                // TODO:
+                //
+                // 1.) standard to register metadata for columns of
+                // the primary result set, if any, generated by call
+                //
+                // 2.) Represent the return value, if any (which is
+                // not, in truth, a result set), as an OUT parameter
+                //
+                // For now, I've reverted a bunch of code I had in place
+                // and instead simply reflect things as the are, describing
+                // a single column result set that communicates
+                // the return value.  If the expression generating the
+                // return value has a void return type, a result set
+                // is described whose single column is of type NULL
+                ResultMetaData md = ResultMetaData.newResultMetaData(1);
+                ColumnBase column =
+                    new ColumnBase(null, null, null,
+                                   StatementDMQL.RETURN_COLUMN_NAME);
+
+                column.setType(expression.getDataType());
+
+                md.columns[0] = column;
+
+                md.prepareData();
+
+                resultMetaData = md;
+
+                return md;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "StatementProcedure");
+        }
+    }
+
+    /**
+     * Returns the metadata for the placeholder parameters.
+     */
+    public ResultMetaData getParametersMetaData() {
+
+        /** @todo - change the auto-names to the names of params */
+        return super.getParametersMetaData();
+    }
+
+    void collectTableNamesForRead(OrderedHashSet set) {
+
+        if (expression == null) {
+            set.addAll(procedure.getTableNamesForRead());
+        } else {
+            for (int i = 0; i < subqueries.length; i++) {
+                if (subqueries[i].queryExpression != null) {
+                    subqueries[i].queryExpression.getBaseTableNames(set);
+                }
+            }
+
+            for (int i = 0; i < routines.length; i++) {
+                set.addAll(routines[i].getTableNamesForRead());
+            }
+        }
+    }
+
+    void collectTableNamesForWrite(OrderedHashSet set) {
+
+        if (expression == null) {
+            set.addAll(procedure.getTableNamesForWrite());
+        }
+    }
+}
diff --git a/src/org/hsqldb/StatementQuery.java b/src/org/hsqldb/StatementQuery.java
new file mode 100644
index 0000000..58a43a2
--- /dev/null
+++ b/src/org/hsqldb/StatementQuery.java
@@ -0,0 +1,110 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.result.ResultProperties;
+
+/**
+ * Implementation of Statement for query expressions.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementQuery extends StatementDMQL {
+
+    StatementQuery(Session session, QueryExpression queryExpression,
+                   CompileContext compileContext) {
+
+        super(StatementTypes.SELECT_CURSOR, StatementTypes.X_SQL_DATA,
+              session.getCurrentSchemaHsqlName());
+
+        this.queryExpression = queryExpression;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+    }
+
+    Result getResult(Session session) {
+
+        Result result = queryExpression.getResult(session,
+            session.getMaxRows());
+
+        result.setStatement(this);
+
+        return result;
+    }
+
+    public ResultMetaData getResultMetaData() {
+
+        switch (type) {
+
+            case StatementTypes.SELECT_CURSOR :
+                return queryExpression.getMetaData();
+
+            case StatementTypes.SELECT_SINGLE :
+                return queryExpression.getMetaData();
+
+            default :
+                throw Error.runtimeError(
+                    ErrorCode.U_S0500,
+                    "CompiledStatement.getResultMetaData()");
+        }
+    }
+
+    void collectTableNamesForRead(OrderedHashSet set) {
+
+        queryExpression.getBaseTableNames(set);
+
+        for (int i = 0; i < subqueries.length; i++) {
+            if (subqueries[i].queryExpression != null) {
+                subqueries[i].queryExpression.getBaseTableNames(set);
+            }
+        }
+
+        for (int i = 0; i < routines.length; i++) {
+            set.addAll(routines[i].getTableNamesForRead());
+        }
+    }
+
+    void collectTableNamesForWrite(OrderedHashSet set) {}
+
+    public int getResultProperties() {
+        return ResultProperties.defaultPropsValue;
+    }
+}
diff --git a/src/org/hsqldb/StatementResultUpdate.java b/src/org/hsqldb/StatementResultUpdate.java
new file mode 100644
index 0000000..3c747f0
--- /dev/null
+++ b/src/org/hsqldb/StatementResultUpdate.java
@@ -0,0 +1,217 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.navigator.RowSetNavigatorData;
+import org.hsqldb.navigator.RowSetNavigatorDataChange;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.types.Type;
+
+public class StatementResultUpdate extends StatementDML {
+
+    int    actionType;
+    Type[] types;
+    Result result;
+
+    StatementResultUpdate() {
+
+        super();
+
+        isTransactionStatement = true;
+    }
+
+    public String describe(Session session) {
+        return "";
+    }
+
+    public Result execute(Session session) {
+
+        try {
+            return getResult(session);
+        } catch (Throwable e) {
+            return Result.newErrorResult(e, null);
+        }
+    }
+
+    Result getResult(Session session) {
+
+        checkAccessRights(session);
+
+        Object[]        args = session.sessionContext.dynamicArguments;
+        Row             row;
+        PersistentStore store = baseTable.getRowStore(session);
+
+        switch (actionType) {
+
+            case ResultConstants.UPDATE_CURSOR : {
+                row = getRow(session, args);
+
+                /**
+                 * @todo - in 2PL mode isDeleted() always returns false.
+                 * While write lock prevents delete by other transactions,
+                 * same-transaction deletes are not caught
+                 */
+                if (row == null || row.isDeleted(session, store)) {
+                    throw Error.error(ErrorCode.X_24521);
+                }
+
+                RowSetNavigatorDataChange list =
+                    new RowSetNavigatorDataChange();
+                Object[] data =
+                    (Object[]) ArrayUtil.duplicateArray(row.getData());
+                boolean[] columnCheck = baseTable.getNewColumnCheckList();
+
+                for (int i = 0; i < baseColumnMap.length; i++) {
+                    if (types[i] == Type.SQL_ALL_TYPES) {
+                        continue;
+                    }
+
+                    data[baseColumnMap[i]]        = args[i];
+                    columnCheck[baseColumnMap[i]] = true;
+                }
+
+                int[] colMap = ArrayUtil.booleanArrayToIntIndexes(columnCheck);
+
+                list.addRow(session, row, data, baseTable.getColumnTypes(),
+                            colMap);
+                update(session, baseTable, list);
+
+                break;
+            }
+            case ResultConstants.DELETE_CURSOR : {
+                row = getRow(session, args);
+
+                if (row == null || row.isDeleted(session, store)) {
+                    throw Error.error(ErrorCode.X_24521);
+                }
+
+                RowSetNavigatorDataChange navigator =
+                    new RowSetNavigatorDataChange();
+
+                navigator.addRow(row);
+                delete(session, baseTable, navigator);
+
+                break;
+            }
+            case ResultConstants.INSERT_CURSOR : {
+                Object[] data = baseTable.getNewRowData(session);
+
+                for (int i = 0; i < data.length; i++) {
+                    data[baseColumnMap[i]] = args[i];
+                }
+
+                return insertSingleRow(session, store, data);
+            }
+        }
+
+        return Result.updateOneResult;
+    }
+
+    Row getRow(Session session, Object[] args) {
+
+        int             rowIdIndex = result.metaData.getColumnCount();
+        Long            rowId      = (Long) args[rowIdIndex];
+        PersistentStore store = baseTable.getRowStore(session);
+        Row             row        = null;
+
+        if (rowIdIndex + 2 == result.metaData.getExtendedColumnCount()) {
+            Object[] data =
+                ((RowSetNavigatorData) result.getNavigator()).getData(
+                    rowId.longValue());
+
+            if (data != null) {
+                row = (Row) data[rowIdIndex + 1];
+            }
+        } else {
+            int id = (int) rowId.longValue();
+
+            row = (Row) store.get(id, false);
+        }
+
+        this.result = null;
+
+        return row;
+    }
+
+    void setRowActionProperties(Result result, int action, Table table,
+                                Type[] types, int[] columnMap) {
+
+        this.result        = result;
+        this.actionType    = action;
+        this.baseTable     = table;
+        this.types         = types;
+        this.baseColumnMap = columnMap;
+    }
+
+    void checkAccessRights(Session session) {
+
+        switch (type) {
+
+            case StatementTypes.CALL : {
+                break;
+            }
+            case StatementTypes.INSERT : {
+                session.getGrantee().checkInsert(targetTable,
+                                                 insertCheckColumns);
+
+                break;
+            }
+            case StatementTypes.SELECT_CURSOR :
+                break;
+
+            case StatementTypes.DELETE_WHERE : {
+                session.getGrantee().checkDelete(targetTable);
+
+                break;
+            }
+            case StatementTypes.UPDATE_WHERE : {
+                session.getGrantee().checkUpdate(targetTable,
+                                                 updateCheckColumns);
+
+                break;
+            }
+            case StatementTypes.MERGE : {
+                session.getGrantee().checkInsert(targetTable,
+                                                 insertCheckColumns);
+                session.getGrantee().checkUpdate(targetTable,
+                                                 updateCheckColumns);
+
+                break;
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/StatementSchema.java b/src/org/hsqldb/StatementSchema.java
new file mode 100644
index 0000000..9764e9c
--- /dev/null
+++ b/src/org/hsqldb/StatementSchema.java
@@ -0,0 +1,1322 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.result.Result;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.rights.GranteeManager;
+import org.hsqldb.rights.Right;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Charset;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of Statement for DDL statements.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementSchema extends Statement {
+
+    int      order;
+    Object[] arguments = ValuePool.emptyObjectArray;
+    boolean  isSchemaDefinition;
+    Token[]  statementTokens;
+
+    StatementSchema() {
+
+        super(StatementTypes.CREATE_SCHEMA,
+              StatementTypes.X_SQL_SCHEMA_DEFINITION);
+
+        isTransactionStatement = true;
+    }
+
+    StatementSchema(String sql, int type, HsqlName readName,
+                    HsqlName writeName) {
+        this(sql, type, null, readName, writeName);
+    }
+
+    StatementSchema(String sql, int type, Object[] args) {
+        this(sql, type, args, null, null);
+    }
+
+    StatementSchema(String sql, int type, Object[] args, HsqlName readName,
+                    HsqlName writeName) {
+
+        super(type);
+
+        isTransactionStatement = true;
+        this.sql               = sql;
+
+        if (args != null) {
+            arguments = args;
+        }
+
+        if (readName != null && readName != writeName) {
+            readTableNames = new HsqlName[]{ readName };
+        }
+
+        if (writeName != null) {
+            writeTableNames = new HsqlName[]{ writeName };
+        }
+
+        switch (type) {
+
+            case StatementTypes.RENAME_OBJECT :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                break;
+
+            case StatementTypes.ALTER_DOMAIN :
+            case StatementTypes.ALTER_ROUTINE :
+            case StatementTypes.ALTER_SEQUENCE :
+            case StatementTypes.ALTER_TYPE :
+            case StatementTypes.ALTER_TABLE :
+            case StatementTypes.ALTER_TRANSFORM :
+            case StatementTypes.ALTER_VIEW :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                break;
+
+            case StatementTypes.DROP_ASSERTION :
+            case StatementTypes.DROP_CHARACTER_SET :
+            case StatementTypes.DROP_COLLATION :
+            case StatementTypes.DROP_TYPE :
+            case StatementTypes.DROP_DOMAIN :
+            case StatementTypes.DROP_ROLE :
+            case StatementTypes.DROP_USER :
+            case StatementTypes.DROP_ROUTINE :
+            case StatementTypes.DROP_SCHEMA :
+            case StatementTypes.DROP_SEQUENCE :
+            case StatementTypes.DROP_TABLE :
+            case StatementTypes.DROP_TRANSFORM :
+            case StatementTypes.DROP_TRANSLATION :
+            case StatementTypes.DROP_TRIGGER :
+            case StatementTypes.DROP_CAST :
+            case StatementTypes.DROP_ORDERING :
+            case StatementTypes.DROP_VIEW :
+            case StatementTypes.DROP_INDEX :
+            case StatementTypes.DROP_CONSTRAINT :
+            case StatementTypes.DROP_COLUMN :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                break;
+
+            case StatementTypes.GRANT :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                order = 10;
+                break;
+
+            case StatementTypes.GRANT_ROLE :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                order = 10;
+                break;
+
+            case StatementTypes.REVOKE :
+            case StatementTypes.REVOKE_ROLE :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                break;
+
+            case StatementTypes.CREATE_SCHEMA :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                break;
+
+            case StatementTypes.CREATE_ROLE :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_ROUTINE :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 7;
+                break;
+
+            case StatementTypes.CREATE_SEQUENCE :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_TABLE :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 2;
+                break;
+
+            case StatementTypes.CREATE_TRANSFORM :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_TRANSLATION :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_TRIGGER :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 7;
+                break;
+
+            case StatementTypes.CREATE_CAST :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 2;
+                break;
+
+            case StatementTypes.CREATE_TYPE :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_ORDERING :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_VIEW :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 5;
+                break;
+
+            case StatementTypes.CREATE_USER :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_ASSERTION :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 9;
+                break;
+
+            case StatementTypes.CREATE_CHARACTER_SET :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_COLLATION :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_DOMAIN :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 1;
+                break;
+
+            case StatementTypes.CREATE_ALIAS :
+                group = StatementTypes.X_SQL_SCHEMA_DEFINITION;
+                order = 8;
+                break;
+
+            case StatementTypes.CREATE_INDEX :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                order = 4;
+                break;
+
+            case StatementTypes.COMMENT :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                order = 11;
+                break;
+
+            case StatementTypes.CHECK :
+                group           = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                statementTokens = (Token[]) args[0];
+                break;
+
+            case StatementTypes.LOG_SCHEMA_STATEMENT :
+                group = StatementTypes.X_SQL_SCHEMA_MANIPULATION;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "StatemntSchema");
+        }
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        try {
+            result = getResult(session);
+        } catch (Throwable t) {
+            result = Result.newErrorResult(t, null);
+        }
+
+        if (result.isError()) {
+            result.getException().setStatementType(group, type);
+
+            return result;
+        }
+
+        session.database.schemaManager.setSchemaChangeTimestamp();
+
+        try {
+            if (isLogged) {
+                session.database.logger.writeToLog(session, sql);
+            }
+        } catch (Throwable e) {
+            return Result.newErrorResult(e, sql);
+        }
+
+        return result;
+    }
+
+    Result getResult(Session session) {
+
+        SchemaManager schemaManager = session.database.schemaManager;
+
+        if (this.isExplain) {
+            return Result.newSingleColumnStringResult("OPERATION",
+                    describe(session));
+        }
+
+        switch (type) {
+
+            case StatementTypes.RENAME_OBJECT : {
+                HsqlName     name    = (HsqlName) arguments[0];
+                HsqlName     newName = (HsqlName) arguments[1];
+                SchemaObject object;
+
+                if (name.type == SchemaObject.CATALOG) {
+                    try {
+                        session.checkAdmin();
+                        session.checkDDLWrite();
+                        name.rename(newName);
+
+                        break;
+                    } catch (HsqlException e) {
+                        return Result.newErrorResult(e, sql);
+                    }
+                } else if (name.type == SchemaObject.SCHEMA) {
+
+                    /**
+                     * @todo 1.9.0 - review for schemas referenced in
+                     *  external view or trigger definitions
+                     */
+                    checkSchemaUpdateAuthorisation(session, name);
+                    schemaManager.checkSchemaNameCanChange(name);
+                    schemaManager.renameSchema(name, newName);
+
+                    break;
+                }
+
+                try {
+                    name.setSchemaIfNull(session.getCurrentSchemaHsqlName());
+
+                    if (name.type == SchemaObject.COLUMN) {
+                        Table table = schemaManager.getUserTable(session,
+                            name.parent);
+                        int index = table.getColumnIndex(name.name);
+
+                        object = table.getColumn(index);
+                    } else {
+                        object = schemaManager.getSchemaObject(name);
+
+                        if (object == null) {
+                            throw Error.error(ErrorCode.X_42501, name.name);
+                        }
+
+                        name = object.getName();
+                    }
+
+                    checkSchemaUpdateAuthorisation(session, name.schema);
+                    newName.setSchemaIfNull(name.schema);
+
+                    if (name.schema != newName.schema) {
+                        HsqlException e = Error.error(ErrorCode.X_42505);
+
+                        return Result.newErrorResult(e, sql);
+                    }
+
+                    newName.parent = name.parent;
+
+                    switch (object.getType()) {
+
+                        case SchemaObject.COLUMN :
+                            HsqlName parent = object.getName().parent;
+
+                            schemaManager.checkColumnIsReferenced(
+                                parent, object.getName());
+
+                            Table table = schemaManager.getUserTable(session,
+                                parent);
+
+                            table.renameColumn((ColumnSchema) object, newName);
+                            break;
+
+                        default :
+                            schemaManager.renameSchemaObject(name, newName);
+                    }
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.ALTER_SEQUENCE : {
+                try {
+                    NumberSequence sequence = (NumberSequence) arguments[0];
+                    NumberSequence settings = (NumberSequence) arguments[1];
+
+                    checkSchemaUpdateAuthorisation(session,
+                                                   sequence.getSchemaName());
+                    sequence.reset(settings);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.ALTER_DOMAIN :
+            case StatementTypes.ALTER_ROUTINE :
+            case StatementTypes.ALTER_TYPE :
+            case StatementTypes.ALTER_TABLE :
+            case StatementTypes.ALTER_TRANSFORM : {
+                try {
+                    session.parser.reset(sql);
+                    session.parser.read();
+                    session.parser.processAlter();
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.ALTER_VIEW : {
+                View view = (View) arguments[0];
+
+                try {
+                    checkSchemaUpdateAuthorisation(session,
+                                                   view.getSchemaName());
+
+                    View oldView =
+                        (View) schemaManager.getSchemaObject(view.getName());
+
+                    if (oldView == null) {
+                        throw Error.error(ErrorCode.X_42501,
+                                          view.getName().name);
+                    }
+
+                    view.setName(oldView.getName());
+                    view.compile(session, null);
+
+                    OrderedHashSet dependents =
+                        schemaManager.getReferencingObjectNames(
+                            oldView.getName());
+
+                    if (dependents.getCommonElementCount(view.getReferences())
+                            > 0) {
+                        throw Error.error(ErrorCode.X_42502);
+                    }
+
+                    int i = schemaManager.getTableIndex(oldView);
+
+                    schemaManager.setTable(i, view);
+
+                    OrderedHashSet set = new OrderedHashSet();
+
+                    set.add(view);
+
+                    try {
+                        schemaManager.recompileDependentObjects(set);
+                    } catch (HsqlException e) {
+                        schemaManager.setTable(i, oldView);
+                        schemaManager.recompileDependentObjects(set);
+                    }
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.DROP_COLUMN : {
+                try {
+                    HsqlName name       = (HsqlName) arguments[0];
+                    int      objectType = ((Integer) arguments[1]).intValue();
+                    boolean  cascade = ((Boolean) arguments[2]).booleanValue();
+                    boolean ifExists = ((Boolean) arguments[3]).booleanValue();
+                    Table table = schemaManager.getUserTable(session,
+                        name.parent);
+                    int colindex = table.getColumnIndex(name.name);
+
+                    if (table.getColumnCount() == 1) {
+                        throw Error.error(ErrorCode.X_42591);
+                    }
+
+                    checkSchemaUpdateAuthorisation(session,
+                                                   table.getSchemaName());
+                    session.commit(false);
+
+                    TableWorks tableWorks = new TableWorks(session, table);
+
+                    tableWorks.dropColumn(colindex, cascade);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.DROP_ASSERTION :
+            case StatementTypes.DROP_CHARACTER_SET :
+            case StatementTypes.DROP_COLLATION :
+            case StatementTypes.DROP_TYPE :
+            case StatementTypes.DROP_DOMAIN :
+            case StatementTypes.DROP_ROLE :
+            case StatementTypes.DROP_USER :
+            case StatementTypes.DROP_ROUTINE :
+            case StatementTypes.DROP_SCHEMA :
+            case StatementTypes.DROP_SEQUENCE :
+            case StatementTypes.DROP_TABLE :
+            case StatementTypes.DROP_TRANSFORM :
+            case StatementTypes.DROP_TRANSLATION :
+            case StatementTypes.DROP_TRIGGER :
+            case StatementTypes.DROP_CAST :
+            case StatementTypes.DROP_ORDERING :
+            case StatementTypes.DROP_VIEW :
+            case StatementTypes.DROP_INDEX :
+            case StatementTypes.DROP_CONSTRAINT : {
+                try {
+                    HsqlName name       = (HsqlName) arguments[0];
+                    int      objectType = ((Integer) arguments[1]).intValue();
+                    boolean  cascade = ((Boolean) arguments[2]).booleanValue();
+                    boolean ifExists = ((Boolean) arguments[3]).booleanValue();
+
+                    switch (type) {
+
+                        case StatementTypes.DROP_ROLE :
+                        case StatementTypes.DROP_USER :
+                            session.checkAdmin();
+                            session.checkDDLWrite();
+                            break;
+
+                        case StatementTypes.DROP_SCHEMA :
+                            checkSchemaUpdateAuthorisation(session, name);
+
+                            if (!schemaManager.schemaExists(name.name)) {
+                                if (ifExists) {
+                                    return Result.updateZeroResult;
+                                }
+                            }
+                            break;
+
+                        default :
+                            if (name.schema == null) {
+                                name.schema =
+                                    session.getCurrentSchemaHsqlName();
+                            } else {
+                                if (!schemaManager.schemaExists(
+                                        name.schema.name)) {
+                                    if (ifExists) {
+                                        return Result.updateZeroResult;
+                                    }
+                                }
+                            }
+
+                            name.schema = schemaManager.getUserSchemaHsqlName(
+                                name.schema.name);
+
+                            checkSchemaUpdateAuthorisation(session,
+                                                           name.schema);
+
+                            SchemaObject object =
+                                schemaManager.getSchemaObject(name);
+
+                            if (object == null) {
+                                if (ifExists) {
+                                    return Result.updateZeroResult;
+                                }
+
+                                throw Error.error(ErrorCode.X_42501,
+                                                  name.name);
+                            }
+
+                            if (name.type == SchemaObject.SPECIFIC_ROUTINE) {
+                                name = ((Routine) object).getSpecificName();
+                            } else {
+                                name = object.getName();
+                            }
+                    }
+
+                    if (!cascade) {
+                        schemaManager.checkObjectIsReferenced(name);
+                    }
+
+                    switch (type) {
+
+                        case StatementTypes.DROP_ROLE :
+                            dropRole(session, name, cascade);
+                            break;
+
+                        case StatementTypes.DROP_USER :
+                            dropUser(session, name, cascade);
+                            break;
+
+                        case StatementTypes.DROP_SCHEMA :
+                            dropSchema(session, name, cascade);
+                            break;
+
+                        case StatementTypes.DROP_ASSERTION :
+                            break;
+
+                        case StatementTypes.DROP_CHARACTER_SET :
+                        case StatementTypes.DROP_COLLATION :
+                        case StatementTypes.DROP_SEQUENCE :
+                        case StatementTypes.DROP_TRIGGER :
+                            dropObject(session, name, cascade);
+                            break;
+
+                        case StatementTypes.DROP_TYPE :
+                            dropType(session, name, cascade);
+                            break;
+
+                        case StatementTypes.DROP_DOMAIN :
+                            dropDomain(session, name, cascade);
+                            break;
+
+                        case StatementTypes.DROP_ROUTINE :
+                            dropRoutine(session, name, cascade);
+                            break;
+
+                        case StatementTypes.DROP_TABLE :
+                        case StatementTypes.DROP_VIEW :
+                            dropTable(session, name, cascade);
+                            break;
+
+                        case StatementTypes.DROP_TRANSFORM :
+                        case StatementTypes.DROP_TRANSLATION :
+                        case StatementTypes.DROP_CAST :
+                        case StatementTypes.DROP_ORDERING :
+                            break;
+
+                        case StatementTypes.DROP_INDEX :
+                            checkSchemaUpdateAuthorisation(session,
+                                                           name.schema);
+                            schemaManager.dropIndex(session, name);
+                            break;
+
+                        case StatementTypes.DROP_CONSTRAINT :
+                            checkSchemaUpdateAuthorisation(session,
+                                                           name.schema);
+                            schemaManager.dropConstraint(session, name,
+                                                         cascade);
+                            break;
+                    }
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.GRANT :
+            case StatementTypes.REVOKE : {
+                try {
+                    boolean        grant       = type == StatementTypes.GRANT;
+                    OrderedHashSet granteeList = (OrderedHashSet) arguments[0];
+                    HsqlName       name        = (HsqlName) arguments[1];
+
+                    this.setSchemaName(session, null, name);
+
+                    name = schemaManager.getSchemaObjectName(name.schema,
+                            name.name, name.type, true);
+
+                    SchemaObject schemaObject =
+                        schemaManager.getSchemaObject(name);
+                    Right   right   = (Right) arguments[2];
+                    Grantee grantor = (Grantee) arguments[3];
+                    boolean cascade = ((Boolean) arguments[4]).booleanValue();
+                    boolean isGrantOption =
+                        ((Boolean) arguments[5]).booleanValue();
+
+                    if (grantor == null) {
+                        grantor = isSchemaDefinition ? schemaName.owner
+                                                     : session.getGrantee();
+                    }
+
+                    GranteeManager gm = session.database.granteeManager;
+
+                    switch (schemaObject.getType()) {
+
+                        case SchemaObject.CHARSET :
+                            System.out.println("grant charset!");
+                            break;
+
+                        case SchemaObject.VIEW :
+                        case SchemaObject.TABLE : {
+                            Table t = (Table) schemaObject;
+
+                            right.setColumns(t);
+
+                            if (t.getTableType() == TableBase.TEMP_TABLE
+                                    && !right.isFull()) {
+                                return Result.newErrorResult(
+                                    Error.error(ErrorCode.X_42595), sql);
+                            }
+                        }
+                    }
+
+                    if (grant) {
+                        gm.grant(granteeList, schemaObject, right, grantor,
+                                 isGrantOption);
+                    } else {
+                        gm.revoke(granteeList, schemaObject, right, grantor,
+                                  isGrantOption, cascade);
+                    }
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.GRANT_ROLE :
+            case StatementTypes.REVOKE_ROLE : {
+                try {
+                    boolean        grant = type == StatementTypes.GRANT_ROLE;
+                    OrderedHashSet granteeList = (OrderedHashSet) arguments[0];
+                    OrderedHashSet roleList    = (OrderedHashSet) arguments[1];
+                    Grantee        grantor     = (Grantee) arguments[2];
+                    boolean cascade = ((Boolean) arguments[3]).booleanValue();
+                    GranteeManager gm = session.database.granteeManager;
+
+                    gm.checkGranteeList(granteeList);
+
+                    for (int i = 0; i < granteeList.size(); i++) {
+                        String grantee = (String) granteeList.get(i);
+
+                        gm.checkRoleList(grantee, roleList, grantor, grant);
+                    }
+
+                    if (grant) {
+                        for (int i = 0; i < granteeList.size(); i++) {
+                            String grantee = (String) granteeList.get(i);
+
+                            for (int j = 0; j < roleList.size(); j++) {
+                                String roleName = (String) roleList.get(j);
+
+                                gm.grant(grantee, roleName, grantor);
+                            }
+                        }
+                    } else {
+                        for (int i = 0; i < granteeList.size(); i++) {
+                            String grantee = (String) granteeList.get(i);
+
+                            for (int j = 0; j < roleList.size(); j++) {
+                                gm.revoke(grantee, (String) roleList.get(j),
+                                          grantor);
+                            }
+                        }
+                    }
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_ASSERTION : {
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.CREATE_CHARACTER_SET : {
+                Charset charset = (Charset) arguments[0];
+
+                try {
+                    setOrCheckObjectName(session, null, charset.getName(),
+                                         true);
+                    schemaManager.addSchemaObject(charset);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_COLLATION : {
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.CREATE_ROLE : {
+                try {
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+
+                    HsqlName name = (HsqlName) arguments[0];
+
+                    session.database.getGranteeManager().addRole(name);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_USER : {
+                HsqlName name     = (HsqlName) arguments[0];
+                String   password = (String) arguments[1];
+                Grantee  grantor  = (Grantee) arguments[2];
+                boolean  admin    = ((Boolean) arguments[3]).booleanValue();
+
+                try {
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+                    session.database.getUserManager().createUser(name,
+                            password);
+
+                    if (admin) {
+                        session.database.getGranteeManager().grant(name.name,
+                                SqlInvariants.DBA_ADMIN_ROLE_NAME, grantor);
+                    }
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_SCHEMA : {
+                HsqlName name  = (HsqlName) arguments[0];
+                Grantee  owner = (Grantee) arguments[1];
+
+                try {
+                    session.checkDDLWrite();
+
+                    if (schemaManager.schemaExists(name.name)) {
+                        if (session.isProcessingScript
+                                && SqlInvariants.PUBLIC_SCHEMA.equals(
+                                    name.name)) {}
+                        else {
+                            throw Error.error(ErrorCode.X_42504, name.name);
+                        }
+                    } else {
+                        schemaManager.createSchema(name, owner);
+
+                        // always include authorization
+                        Schema schema = schemaManager.findSchema(name.name);
+
+                        this.sql = schema.getSQL();
+
+                        if (session.isProcessingScript()
+                                && session.database.getProperties()
+                                    .isVersion18()) {
+                            session.setSchema(schema.getName().name);
+                        }
+                    }
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_ROUTINE : {
+                Routine routine = (Routine) arguments[0];
+
+                try {
+                    routine.resolve(session);
+                    setOrCheckObjectName(session, null, routine.getName(),
+                                         false);
+                    schemaManager.addSchemaObject(routine);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_ALIAS : {
+                HsqlName  name     = (HsqlName) arguments[0];
+                Routine[] routines = (Routine[]) arguments[1];
+
+                try {
+                    session.checkAdmin();
+                    session.checkDDLWrite();
+
+                    if (name != null) {
+                        for (int i = 0; i < routines.length; i++) {
+                            routines[i].setName(name);
+                            schemaManager.addSchemaObject(routines[i]);
+                        }
+                    }
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_SEQUENCE : {
+                NumberSequence sequence = (NumberSequence) arguments[0];
+
+                try {
+                    setOrCheckObjectName(session, null, sequence.getName(),
+                                         true);
+                    schemaManager.addSchemaObject(sequence);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_DOMAIN : {
+                Type type = (Type) arguments[0];
+                Constraint[] constraints =
+                    type.userTypeModifier.getConstraints();
+
+                try {
+                    setOrCheckObjectName(session, null, type.getName(), true);
+
+                    for (int i = 0; i < constraints.length; i++) {
+                        Constraint c = constraints[i];
+
+                        setOrCheckObjectName(session, type.getName(),
+                                             c.getName(), true);
+                        schemaManager.addSchemaObject(c);
+                    }
+
+                    schemaManager.addSchemaObject(type);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_TABLE : {
+                Table         table              = (Table) arguments[0];
+                HsqlArrayList tempConstraints = (HsqlArrayList) arguments[1];
+                StatementDMQL statement = (StatementDMQL) arguments[2];
+                HsqlArrayList foreignConstraints = null;
+
+                try {
+                    setOrCheckObjectName(session, null, table.getName(), true);
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+
+                try {
+                    if (isSchemaDefinition) {
+                        foreignConstraints = new HsqlArrayList();
+                    }
+
+                    if (tempConstraints != null) {
+                        table =
+                            ParserDDL.addTableConstraintDefinitions(session,
+                                table, tempConstraints, foreignConstraints,
+                                true);
+                        arguments[1] = foreignConstraints;
+                    }
+
+                    table.compile(session, null);
+                    schemaManager.addSchemaObject(table);
+
+                    if (statement != null) {
+                        Result result = statement.execute(session);
+
+                        table.insertIntoTable(session, result);
+                    }
+
+                    if (table.hasLobColumn) {
+                        RowIterator it = table.rowIterator(session);
+
+                        while (it.hasNext()) {
+                            Row      row  = it.getNextRow();
+                            Object[] data = row.getData();
+
+                            session.sessionData.adjustLobUsageCount(table,
+                                    data, 1);
+                        }
+                    }
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    schemaManager.removeExportedKeys(table);
+                    schemaManager.removeDependentObjects(table.getName());
+
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_TRANSFORM :
+                return Result.updateZeroResult;
+
+            case StatementTypes.CREATE_TRANSLATION :
+                return Result.updateZeroResult;
+
+            case StatementTypes.CREATE_TRIGGER : {
+                TriggerDef trigger   = (TriggerDef) arguments[0];
+                HsqlName   otherName = (HsqlName) arguments[1];
+
+                try {
+                    checkSchemaUpdateAuthorisation(session,
+                                                   trigger.getSchemaName());
+                    schemaManager.checkSchemaObjectNotExists(
+                        trigger.getName());
+
+                    if (otherName != null) {
+                        if (schemaManager.getSchemaObject(otherName) == null) {
+                            throw Error.error(ErrorCode.X_42501,
+                                              otherName.name);
+                        }
+                    }
+
+                    trigger.table.addTrigger(trigger, otherName);
+                    schemaManager.addSchemaObject(trigger);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_CAST :
+                return Result.updateZeroResult;
+
+            case StatementTypes.CREATE_TYPE : {
+                Type type = (Type) arguments[0];
+
+                try {
+                    setOrCheckObjectName(session, null, type.getName(), true);
+                    schemaManager.addSchemaObject(type);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_ORDERING :
+                return Result.updateZeroResult;
+
+            case StatementTypes.CREATE_VIEW : {
+                View view = (View) arguments[0];
+
+                try {
+                    checkSchemaUpdateAuthorisation(session,
+                                                   view.getSchemaName());
+                    schemaManager.checkSchemaObjectNotExists(view.getName());
+                    view.compile(session, null);
+                    schemaManager.addSchemaObject(view);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.CREATE_INDEX : {
+                Table    table;
+                HsqlName name;
+                int[]    indexColumns;
+                boolean  unique;
+
+                table        = (Table) arguments[0];
+                indexColumns = (int[]) arguments[1];
+                name         = (HsqlName) arguments[2];
+                unique       = ((Boolean) arguments[3]).booleanValue();
+
+                try {
+                    /*
+                            Index index        = table.getIndexForColumns(indexColumns);
+
+                            if (index != null
+                                    && ArrayUtil.areEqual(indexColumns, index.getColumns(),
+                                                          indexColumns.length, unique)) {
+                                if (index.isUnique() || !unique) {
+                                    return;
+                                }
+                            }
+                    */
+                    setOrCheckObjectName(session, table.getName(), name, true);
+
+                    TableWorks tableWorks = new TableWorks(session, table);
+
+                    tableWorks.addIndex(indexColumns, name, unique);
+
+                    break;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.COMMENT : {
+                HsqlName name    = (HsqlName) arguments[0];
+                String   comment = (String) arguments[1];
+
+                switch (name.type) {
+
+                    case SchemaObject.COLUMN : {
+                        Table table = (Table) schemaManager.getSchemaObject(
+                            name.parent.name, name.parent.schema.name,
+                            SchemaObject.TABLE);
+
+                        if (!session.getGrantee().isFullyAccessibleByRole(
+                                table.getName())) {
+                            throw Error.error(ErrorCode.X_42501);
+                        }
+
+                        int index = table.getColumnIndex(name.name);
+
+                        if (index < 0) {
+                            throw Error.error(ErrorCode.X_42501);
+                        }
+
+                        ColumnSchema column = table.getColumn(index);
+
+                        column.getName().comment = comment;
+
+                        break;
+                    }
+                    case SchemaObject.ROUTINE : {
+                        RoutineSchema routine =
+                            (RoutineSchema) schemaManager.getSchemaObject(
+                                name.name, name.schema.name,
+                                SchemaObject.ROUTINE);
+
+                        if (!session.getGrantee().isFullyAccessibleByRole(
+                                routine.getName())) {
+                            throw Error.error(ErrorCode.X_42501);
+                        }
+
+                        routine.getName().comment = comment;
+
+                        break;
+                    }
+                    case SchemaObject.TABLE : {
+                        Table table =
+                            (Table) schemaManager.getSchemaObject(name.name,
+                                name.schema.name, SchemaObject.TABLE);
+
+                        if (!session.getGrantee().isFullyAccessibleByRole(
+                                table.getName())) {
+                            throw Error.error(ErrorCode.X_42501);
+                        }
+
+                        table.getName().comment = comment;
+
+                        break;
+                    }
+                }
+
+                break;
+            }
+
+            // for logging only
+            case StatementTypes.LOG_SCHEMA_STATEMENT :
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "CompiledStateemntSchema");
+        }
+
+        return Result.updateZeroResult;
+    }
+
+    private void dropType(Session session, HsqlName name, boolean cascade) {
+
+        checkSchemaUpdateAuthorisation(session, name.schema);
+
+        Type distinct =
+            (Type) session.database.schemaManager.getSchemaObject(name);
+
+        session.database.schemaManager.removeSchemaObject(name, cascade);
+
+        distinct.userTypeModifier = null;
+    }
+
+    private static void dropDomain(Session session, HsqlName name,
+                                   boolean cascade) {
+
+        Type domain =
+            (Type) session.database.schemaManager.getSchemaObject(name);
+        OrderedHashSet set =
+            session.database.schemaManager.getReferencingObjectNames(
+                domain.getName());
+
+        if (!cascade && set.size() > 0) {
+            HsqlName objectName = (HsqlName) set.get(0);
+
+            throw Error.error(ErrorCode.X_42502,
+                              objectName.getSchemaQualifiedStatementName());
+        }
+
+        Constraint[] constraints = domain.userTypeModifier.getConstraints();
+
+        set = new OrderedHashSet();
+
+        for (int i = 0; i < constraints.length; i++) {
+            set.add(constraints[i].getName());
+        }
+
+        session.database.schemaManager.removeSchemaObjects(set);
+        session.database.schemaManager.removeSchemaObject(domain.getName(),
+                cascade);
+
+        domain.userTypeModifier = null;
+    }
+
+    private static void dropRole(Session session, HsqlName name,
+                                 boolean cascade) {
+
+        Grantee role = session.database.getGranteeManager().getRole(name.name);
+
+        if (!cascade && session.database.schemaManager.hasSchemas(role)) {
+            HsqlArrayList list =
+                session.database.schemaManager.getSchemas(role);
+            Schema schema = (Schema) list.get(0);
+
+            throw Error.error(ErrorCode.X_42502,
+                              schema.getName().statementName);
+        }
+
+        session.database.schemaManager.dropSchemas(session, role, cascade);
+        session.database.getGranteeManager().dropRole(name.name);
+    }
+
+    private static void dropUser(Session session, HsqlName name,
+                                 boolean cascade) {
+
+        Grantee grantee = session.database.getUserManager().get(name.name);
+
+        if (session.database.getSessionManager().isUserActive(name.name)) {
+            throw Error.error(ErrorCode.X_42539);
+        }
+
+        if (!cascade && session.database.schemaManager.hasSchemas(grantee)) {
+            HsqlArrayList list =
+                session.database.schemaManager.getSchemas(grantee);
+            Schema schema = (Schema) list.get(0);
+
+            throw Error.error(ErrorCode.X_42502,
+                              schema.getName().statementName);
+        }
+
+        session.database.schemaManager.dropSchemas(session, grantee, cascade);
+        session.database.getUserManager().dropUser(name.name);
+    }
+
+    private void dropSchema(Session session, HsqlName name, boolean cascade) {
+
+        HsqlName schema =
+            session.database.schemaManager.getUserSchemaHsqlName(name.name);
+
+        checkSchemaUpdateAuthorisation(session, schema);
+        session.database.schemaManager.dropSchema(session, name.name, cascade);
+    }
+
+    private void dropRoutine(Session session, HsqlName name, boolean cascade) {
+        checkSchemaUpdateAuthorisation(session, name.schema);
+        session.database.schemaManager.removeSchemaObject(name, cascade);
+    }
+
+    private void dropObject(Session session, HsqlName name, boolean cascade) {
+
+        name = session.database.schemaManager.getSchemaObjectName(name.schema,
+                name.name, name.type, true);
+
+        session.database.schemaManager.removeSchemaObject(name, cascade);
+    }
+
+    private void dropTable(Session session, HsqlName name, boolean cascade) {
+
+        Table table = session.database.schemaManager.findUserTable(session,
+            name.name, name.schema.name);
+
+        session.database.schemaManager.dropTableOrView(session, table,
+                cascade);
+    }
+
+    void checkSchemaUpdateAuthorisation(Session session, HsqlName schema) {
+
+        if (session.isProcessingLog) {
+            return;
+        }
+
+        if (SqlInvariants.isSystemSchemaName(schema.name)) {
+            throw Error.error(ErrorCode.X_42503);
+        }
+
+        if (session.parser.isSchemaDefinition) {
+            if (schema == session.getCurrentSchemaHsqlName()) {
+                return;
+            }
+
+            Error.error(ErrorCode.X_42505, schema.name);
+        }
+
+        session.getGrantee().checkSchemaUpdateOrGrantRights(schema.name);
+        session.checkDDLWrite();
+    }
+
+    void setOrCheckObjectName(Session session, HsqlName parent, HsqlName name,
+                              boolean check) {
+
+        if (name.schema == null) {
+            name.schema = schemaName == null
+                          ? session.getCurrentSchemaHsqlName()
+                          : schemaName;
+        } else {
+            name.schema = session.getSchemaHsqlName(name.schema.name);
+
+            if (name.schema == null) {
+                throw Error.error(ErrorCode.X_42505);
+            }
+
+            if (isSchemaDefinition && schemaName != name.schema) {
+                throw Error.error(ErrorCode.X_42505);
+            }
+        }
+
+        name.parent = parent;
+
+        if (!isSchemaDefinition) {
+            checkSchemaUpdateAuthorisation(session, name.schema);
+        }
+
+        if (check) {
+            session.database.schemaManager.checkSchemaObjectNotExists(name);
+        }
+    }
+
+    void setSchemaName(Session session, HsqlName parent, HsqlName name) {
+
+        if (name.schema == null) {
+            name.schema = schemaName == null
+                          ? session.getCurrentSchemaHsqlName()
+                          : schemaName;
+        } else {
+            name.schema = session.getSchemaHsqlName(name.schema.name);
+
+            if (name.schema == null) {
+                throw Error.error(ErrorCode.X_42505);
+            }
+
+            if (isSchemaDefinition && schemaName != name.schema) {
+                throw Error.error(ErrorCode.X_42505);
+            }
+        }
+    }
+
+    public boolean isAutoCommitStatement() {
+        return true;
+    }
+
+    public String describe(Session session) {
+        return sql;
+    }
+}
diff --git a/src/org/hsqldb/StatementSchemaDefinition.java b/src/org/hsqldb/StatementSchemaDefinition.java
new file mode 100644
index 0000000..0bcf516
--- /dev/null
+++ b/src/org/hsqldb/StatementSchemaDefinition.java
@@ -0,0 +1,241 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.result.Result;
+
+/**
+ * Implementation of Statement for CREATE SCHEMA statements.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementSchemaDefinition extends StatementSchema {
+
+    StatementSchema[] statements;
+
+    StatementSchemaDefinition(StatementSchema[] statements) {
+
+        super();
+
+        this.statements = statements;
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        try {
+            result = getResult(session);
+        } catch (Throwable t) {
+            result = Result.newErrorResult(t, null);
+        }
+
+        if (result.isError()) {
+            result.getException().setStatementType(group, type);
+        }
+
+        return result;
+    }
+
+    Result getResult(Session session) {
+
+        HsqlName schemaDefinitionName = statements[0].getSchemaName();
+
+        if (this.isExplain) {
+            return Result.newSingleColumnStringResult("OPERATION",
+                    describe(session));
+        }
+
+        StatementSchema cs;
+        Result          result      = statements[0].execute(session);
+        HsqlArrayList   constraints = new HsqlArrayList();
+        StatementSchema log = new StatementSchema(null,
+            StatementTypes.LOG_SCHEMA_STATEMENT, null);
+
+        if (statements.length == 1 || result.isError()) {
+            return result;
+        }
+
+        HsqlName oldSessionSchema = session.getCurrentSchemaHsqlName();
+
+        for (int i = 1; i < statements.length; i++) {
+            try {
+                session.setSchema(schemaDefinitionName.name);
+            } catch (HsqlException e) {}
+
+            statements[i].setSchemaHsqlName(schemaDefinitionName);
+            session.parser.reset(statements[i].getSQL());
+
+            try {
+                session.parser.read();
+
+                switch (statements[i].getType()) {
+
+                    case StatementTypes.GRANT :
+                    case StatementTypes.GRANT_ROLE :
+                        result = statements[i].execute(session);
+                        break;
+
+                    case StatementTypes.CREATE_TABLE :
+                        cs                    = session.parser.compileCreate();
+                        cs.isSchemaDefinition = true;
+
+                        cs.setSchemaHsqlName(schemaDefinitionName);
+
+                        if (session.parser.token.tokenType
+                                != Tokens.X_ENDPARSE) {
+                            throw session.parser.unexpectedToken();
+                        }
+
+                        cs.isLogged = false;
+                        result      = cs.execute(session);
+
+                        HsqlName name = ((Table) cs.arguments[0]).getName();
+                        Table table =
+                            (Table) session.database.schemaManager
+                                .getSchemaObject(name);
+
+                        constraints.addAll((HsqlArrayList) cs.arguments[1]);
+                        ((HsqlArrayList) cs.arguments[1]).clear();
+
+                        //
+                        log.sql = table.getSQL();
+
+                        log.execute(session);
+                        break;
+
+                    case StatementTypes.CREATE_ROLE :
+                    case StatementTypes.CREATE_SEQUENCE :
+                    case StatementTypes.CREATE_TYPE :
+                    case StatementTypes.CREATE_CHARACTER_SET :
+                    case StatementTypes.CREATE_COLLATION :
+                        result = statements[i].execute(session);
+                        break;
+
+                    case StatementTypes.CREATE_INDEX :
+                    case StatementTypes.CREATE_TRIGGER :
+                    case StatementTypes.CREATE_VIEW :
+                    case StatementTypes.CREATE_DOMAIN :
+                    case StatementTypes.CREATE_ROUTINE :
+                        cs                    = session.parser.compileCreate();
+                        cs.isSchemaDefinition = true;
+
+                        cs.setSchemaHsqlName(schemaDefinitionName);
+
+                        if (session.parser.token.tokenType
+                                != Tokens.X_ENDPARSE) {
+                            throw session.parser.unexpectedToken();
+                        }
+
+                        result = cs.execute(session);
+                        break;
+
+                    case StatementTypes.CREATE_ASSERTION :
+                    case StatementTypes.CREATE_TRANSFORM :
+                    case StatementTypes.CREATE_TRANSLATION :
+                    case StatementTypes.CREATE_CAST :
+                    case StatementTypes.CREATE_ORDERING :
+                        throw session.parser.unsupportedFeature();
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500, "");
+                }
+
+                if (result.isError()) {
+                    break;
+                }
+            } catch (HsqlException e) {
+                result = Result.newErrorResult(e, statements[i].getSQL());
+
+                break;
+            }
+        }
+
+        if (!result.isError()) {
+            try {
+                for (int i = 0; i < constraints.size(); i++) {
+                    Constraint c = (Constraint) constraints.get(i);
+                    Table table =
+                        session.database.schemaManager.getUserTable(session,
+                            c.core.refTableName);
+
+                    ParserDDL.addForeignKey(session, table, c, null);
+
+                    log.sql = c.getSQL();
+
+                    log.execute(session);
+                }
+            } catch (HsqlException e) {
+                result = Result.newErrorResult(e, sql);
+            }
+        }
+
+        if (result.isError()) {
+            try {
+                session.database.schemaManager.dropSchema(session,
+                        schemaDefinitionName.name, true);
+                session.database.logger.writeToLog(
+                    session, getDropSchemaStatement(schemaDefinitionName));
+            } catch (HsqlException e) {}
+        }
+
+        try {
+            session.setCurrentSchemaHsqlName(oldSessionSchema);
+        } catch (Exception e) {}
+
+        return result;
+    }
+
+/*
+    if (constraintList != null && constraintList.size() > 0) {
+        try {
+            for (int i = 0; i < constraintList.size(); i++) {
+                Constraint c = (Constraint) constraintList.get(i);
+                Table table = database.schemaManager.getUserTable(session,
+                    c.core.refTableName);
+
+                addForeignKey(table, c);
+            }
+        } finally {
+            constraintList.clear();
+        }
+    }
+*/
+    String getDropSchemaStatement(HsqlName schema) {
+        return "DROP SCHEMA " + schema.statementName + " " + Tokens.T_CASCADE;
+    }
+}
diff --git a/src/org/hsqldb/StatementSession.java b/src/org/hsqldb/StatementSession.java
new file mode 100644
index 0000000..fb3fc3f
--- /dev/null
+++ b/src/org/hsqldb/StatementSession.java
@@ -0,0 +1,698 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.result.Result;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.rights.User;
+import org.hsqldb.types.DTIType;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of Statement for SQL session statements.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementSession extends Statement {
+
+    Expression[] expressions;
+    Object[]     parameters;
+
+    StatementSession(int type, Expression[] args) {
+
+        super(type);
+
+        this.expressions       = args;
+        isTransactionStatement = false;
+
+        switch (type) {
+
+            case StatementTypes.SET_PATH :
+            case StatementTypes.SET_TIME_ZONE :
+            case StatementTypes.SET_NAMES :
+            case StatementTypes.SET_ROLE :
+            case StatementTypes.SET_SCHEMA :
+            case StatementTypes.SET_CATALOG :
+            case StatementTypes.SET_SESSION_AUTHORIZATION :
+            case StatementTypes.SET_COLLATION :
+                group = StatementTypes.X_SQL_SESSION;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "StateemntSession");
+        }
+    }
+
+    StatementSession(int type, Object[] args) {
+
+        super(type);
+
+        this.parameters        = args;
+        isTransactionStatement = false;
+        isLogged               = false;
+
+        switch (type) {
+
+            // logged by statement
+            case StatementTypes.SET_SCHEMA :
+                group    = StatementTypes.X_SQL_SESSION;
+                isLogged = true;
+                break;
+
+            case StatementTypes.DECLARE_VARIABLE :
+                group    = StatementTypes.X_HSQLDB_SESSION;
+                isLogged = true;
+                break;
+
+            // cursor
+            case StatementTypes.ALLOCATE_CURSOR :
+                group = StatementTypes.X_SQL_DATA;
+                break;
+
+            case StatementTypes.ALLOCATE_DESCRIPTOR :
+            case StatementTypes.DEALLOCATE_DESCRIPTOR :
+            case StatementTypes.DEALLOCATE_PREPARE :
+                group = StatementTypes.X_DYNAMIC;
+                break;
+
+            //
+            case StatementTypes.DYNAMIC_DELETE_CURSOR :
+                group = StatementTypes.X_SQL_DATA_CHANGE;
+                break;
+
+            case StatementTypes.DYNAMIC_CLOSE :
+            case StatementTypes.DYNAMIC_FETCH :
+            case StatementTypes.DYNAMIC_OPEN :
+                group = StatementTypes.X_SQL_DATA;
+                break;
+
+            //
+            case StatementTypes.OPEN :
+            case StatementTypes.FETCH :
+            case StatementTypes.FREE_LOCATOR :
+            case StatementTypes.GET_DESCRIPTOR :
+            case StatementTypes.HOLD_LOCATOR :
+                group = StatementTypes.X_SQL_DATA;
+                break;
+
+            //
+            case StatementTypes.PREPARABLE_DYNAMIC_DELETE_CURSOR :
+            case StatementTypes.PREPARABLE_DYNAMIC_UPDATE_CURSOR :
+            case StatementTypes.PREPARE :
+                group = StatementTypes.X_DYNAMIC;
+                break;
+
+            // logged by session
+            case StatementTypes.DISCONNECT :
+                group = StatementTypes.X_SQL_CONNECTION;
+                break;
+
+            //
+            case StatementTypes.SET_CONNECTION :
+            case StatementTypes.SET_CONSTRAINT :
+            case StatementTypes.SET_DESCRIPTOR :
+            case StatementTypes.SET_SESSION_CHARACTERISTICS :
+            case StatementTypes.SET_TRANSFORM_GROUP :
+            case StatementTypes.SET_SESSION_RESULT_MAX_ROWS :
+            case StatementTypes.SET_SESSION_RESULT_MEMORY_ROWS :
+            case StatementTypes.SET_SESSION_AUTOCOMMIT :
+            case StatementTypes.SET_SESSION_SQL_IGNORECASE :
+                group = StatementTypes.X_HSQLDB_SESSION;
+                break;
+
+            // logged by session if necessary
+            case StatementTypes.COMMIT_WORK :
+            case StatementTypes.RELEASE_SAVEPOINT :
+            case StatementTypes.ROLLBACK_SAVEPOINT :
+            case StatementTypes.ROLLBACK_WORK :
+            case StatementTypes.SAVEPOINT :
+            case StatementTypes.SET_TRANSACTION :
+            case StatementTypes.START_TRANSACTION :
+                group = StatementTypes.X_SQL_TRANSACTION;
+                break;
+
+            case StatementTypes.DECLARE_SESSION_TABLE :
+            case StatementTypes.DROP_TABLE :
+                group = StatementTypes.X_SQL_SESSION;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "StatementSession");
+        }
+    }
+
+    StatementSession(int type, HsqlName[] readNames, HsqlName[] writeNames) {
+
+        super(type);
+
+        this.isTransactionStatement = true;
+        this.readTableNames         = readNames;
+        writeTableNames             = writeNames;
+
+        switch (type) {
+
+            case StatementTypes.TRANSACTION_LOCK_TABLE :
+                group = StatementTypes.X_HSQLDB_TRANSACTION;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "StatementSession");
+        }
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        try {
+            result = getResult(session);
+        } catch (Throwable t) {
+            result = Result.newErrorResult(t, null);
+        }
+
+        if (result.isError()) {
+            result.getException().setStatementType(group, type);
+
+            return result;
+        }
+
+        try {
+            if (isLogged) {
+                session.database.logger.writeToLog(session, sql);
+            }
+        } catch (Throwable e) {
+            return Result.newErrorResult(e, sql);
+        }
+
+        return result;
+    }
+
+    Result getResult(Session session) {
+
+        boolean startTransaction = false;
+
+        if (this.isExplain) {
+            return Result.newSingleColumnStringResult("OPERATION",
+                    describe(session));
+        }
+
+        switch (type) {
+
+            // cursor
+            case StatementTypes.ALLOCATE_CURSOR :
+            case StatementTypes.ALLOCATE_DESCRIPTOR :
+                return Result.updateZeroResult;
+
+            //
+            case StatementTypes.COMMIT_WORK : {
+                try {
+                    boolean chain = parameters != null;
+
+                    session.commit(chain);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.DEALLOCATE_DESCRIPTOR :
+            case StatementTypes.DEALLOCATE_PREPARE :
+                return Result.updateZeroResult;
+
+            case StatementTypes.DISCONNECT :
+                session.close();
+
+                return Result.updateZeroResult;
+
+            //
+            case StatementTypes.DYNAMIC_CLOSE :
+            case StatementTypes.DYNAMIC_DELETE_CURSOR :
+            case StatementTypes.DYNAMIC_FETCH :
+            case StatementTypes.DYNAMIC_OPEN :
+
+            //
+            case StatementTypes.FETCH :
+            case StatementTypes.FREE_LOCATOR :
+            case StatementTypes.GET_DESCRIPTOR :
+            case StatementTypes.HOLD_LOCATOR :
+
+            //
+            case StatementTypes.OPEN :
+            case StatementTypes.PREPARABLE_DYNAMIC_DELETE_CURSOR :
+            case StatementTypes.PREPARABLE_DYNAMIC_UPDATE_CURSOR :
+            case StatementTypes.PREPARE :
+                return Result.updateZeroResult;
+
+            case StatementTypes.TRANSACTION_LOCK_TABLE : {
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.RELEASE_SAVEPOINT : {
+                String savepoint = (String) parameters[0];
+
+                try {
+                    session.releaseSavepoint(savepoint);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.ROLLBACK_WORK : {
+                boolean chain = ((Boolean) parameters[0]).booleanValue();
+
+                session.rollback(chain);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.ROLLBACK_SAVEPOINT : {
+                String savepoint = (String) parameters[0];
+
+                try {
+                    session.rollbackToSavepoint(savepoint);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SAVEPOINT : {
+                String savepoint = (String) parameters[0];
+
+                session.savepoint(savepoint);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_CATALOG : {
+                String name;
+
+                try {
+                    name = (String) expressions[0].getValue(session);
+                    name = (String) Type.SQL_VARCHAR.trim(session, name, ' ',
+                                                          true, true);
+
+                    if (session.database.getCatalogName().name.equals(name)) {
+                        return Result.updateZeroResult;
+                    }
+
+                    return Result.newErrorResult(
+                        Error.error(ErrorCode.X_3D000), sql);
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_CONNECTION :
+            case StatementTypes.SET_CONSTRAINT :
+            case StatementTypes.SET_DESCRIPTOR :
+                return Result.updateZeroResult;
+
+            case StatementTypes.SET_TIME_ZONE : {
+                Object value = null;
+
+                if (expressions[0].getType() == OpTypes.VALUE
+                        && expressions[0].getConstantValueNoCheck(session)
+                           == null) {
+                    session.setZoneSeconds(session.sessionTimeZoneSeconds);
+
+                    return Result.updateZeroResult;
+                }
+
+                try {
+                    value = expressions[0].getValue(session);
+                } catch (HsqlException e) {}
+
+                if (value instanceof Result) {
+                    Result result = (Result) value;
+
+                    if (result.isData()) {
+                        Object[] data =
+                            (Object[]) result.getNavigator().getNext();
+                        boolean single = !result.getNavigator().next();
+
+                        if (single && data != null && data[0] != null) {
+                            value = data[0];
+
+                            result.getNavigator().close();
+                        } else {
+                            result.getNavigator().close();
+
+                            return Result.newErrorResult(
+                                Error.error(ErrorCode.X_22009), sql);
+                        }
+                    } else {
+                        return Result.newErrorResult(
+                            Error.error(ErrorCode.X_22009), sql);
+                    }
+                } else {
+                    if (value == null) {
+                        return Result.newErrorResult(
+                            Error.error(ErrorCode.X_22009), sql);
+                    }
+                }
+
+                long seconds = ((IntervalSecondData) value).getSeconds();
+
+                if (-DTIType.timezoneSecondsLimit <= seconds
+                        && seconds <= DTIType.timezoneSecondsLimit) {
+                    session.setZoneSeconds((int) seconds);
+
+                    return Result.updateZeroResult;
+                }
+
+                return Result.newErrorResult(Error.error(ErrorCode.X_22009),
+                                             sql);
+            }
+            case StatementTypes.SET_NAMES :
+                return Result.updateZeroResult;
+
+            case StatementTypes.SET_PATH :
+                return Result.updateZeroResult;
+
+            case StatementTypes.SET_ROLE : {
+                String  name;
+                Grantee role = null;
+
+                try {
+                    name = (String) expressions[0].getValue(session);
+
+                    if (name != null) {
+                        name = (String) Type.SQL_VARCHAR.trim(session, name,
+                                                              ' ', true, true);
+                        role = session.database.granteeManager.getRole(name);
+                    }
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(
+                        Error.error(ErrorCode.X_0P000), sql);
+                }
+
+                if (session.isInMidTransaction()) {
+                    return Result.newErrorResult(
+                        Error.error(ErrorCode.X_25001), sql);
+                }
+
+                if (role == null) {
+                    session.setRole(null);
+                }
+
+                if (session.getGrantee().hasRole(role)) {
+                    session.setRole(role);
+
+                    return Result.updateZeroResult;
+                } else {
+                    return Result.newErrorResult(
+                        Error.error(ErrorCode.X_0P000), sql);
+                }
+            }
+            case StatementTypes.SET_SCHEMA : {
+                String   name;
+                HsqlName schema;
+
+                try {
+                    if (expressions == null) {
+                        name = ((HsqlName) parameters[0]).name;
+                    } else {
+                        name = (String) expressions[0].getValue(session);
+                    }
+
+                    name = (String) Type.SQL_VARCHAR.trim(session, name, ' ',
+                                                          true, true);
+                    schema =
+                        session.database.schemaManager.getSchemaHsqlName(name);
+
+                    session.setSchema(schema.name);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_SESSION_AUTHORIZATION : {
+                if (session.isInMidTransaction()) {
+                    return Result.newErrorResult(
+                        Error.error(ErrorCode.X_25001), sql);
+                }
+
+                try {
+                    String user;
+                    String password = null;
+
+                    user = (String) expressions[0].getValue(session);
+                    user = (String) Type.SQL_VARCHAR.trim(session, user, ' ',
+                                                          true, true);
+
+                    if (expressions[1] != null) {
+                        password = (String) expressions[1].getValue(session);
+                    }
+
+                    User userObject;
+
+                    if (password == null) {
+                        userObject = session.database.userManager.get(user);
+                    } else {
+                        userObject =
+                            session.database.getUserManager().getUser(user,
+                                password);
+                    }
+
+                    if (userObject == null) {
+                        throw Error.error(ErrorCode.X_28501);
+                    }
+
+                    sql = userObject.getConnectUserSQL();
+
+                    if (userObject == session.getGrantee()) {
+                        return Result.updateZeroResult;
+                    }
+
+                    if (session.getGrantee().canChangeAuthorisation()) {
+                        session.setUser((User) userObject);
+                        session.setRole(null);
+                        session.resetSchema();
+
+                        return Result.updateZeroResult;
+                    }
+
+                    /** @todo may need different error code */
+                    throw Error.error(ErrorCode.X_28000);
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_SESSION_CHARACTERISTICS : {
+                try {
+                    if (parameters[0] != null) {
+                        boolean readonly =
+                            ((Boolean) parameters[0]).booleanValue();
+
+                        session.setReadOnlyDefault(readonly);
+                    }
+
+                    if (parameters[1] != null) {
+                        int level = ((Integer) parameters[1]).intValue();
+
+                        session.setIsolationDefault(level);
+                    }
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_COLLATION :
+                return Result.updateZeroResult;
+
+            case StatementTypes.SET_TRANSFORM_GROUP :
+                return Result.updateZeroResult;
+
+            case StatementTypes.START_TRANSACTION :
+                startTransaction = true;
+
+            // fall through
+            case StatementTypes.SET_TRANSACTION : {
+                try {
+                    if (parameters[0] != null) {
+                        boolean readonly =
+                            ((Boolean) parameters[0]).booleanValue();
+
+                        session.setReadOnly(readonly);
+                    }
+
+                    if (parameters[1] != null) {
+                        int level = ((Integer) parameters[1]).intValue();
+
+                        session.setIsolation(level);
+                    }
+
+                    if (startTransaction) {
+                        session.startTransaction();
+                    }
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+
+            //
+            case StatementTypes.SET_SESSION_AUTOCOMMIT : {
+                boolean mode = ((Boolean) parameters[0]).booleanValue();
+
+                try {
+                    session.setAutoCommit(mode);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.DECLARE_VARIABLE : {
+                ColumnSchema[] variables = (ColumnSchema[]) parameters[0];
+
+                try {
+                    for (int i = 0; i < variables.length; i++) {
+                        session.sessionContext.addSessionVariable(
+                            variables[i]);
+                    }
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.SET_SESSION_RESULT_MAX_ROWS : {
+                int size = ((Integer) parameters[0]).intValue();
+
+                session.setSQLMaxRows(size);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_SESSION_RESULT_MEMORY_ROWS : {
+                int size = ((Integer) parameters[0]).intValue();
+
+                session.setResultMemoryRowCount(size);
+
+                return Result.updateZeroResult;
+            }
+            case StatementTypes.SET_SESSION_SQL_IGNORECASE : {
+                try {
+                    boolean mode = ((Boolean) parameters[0]).booleanValue();
+
+                    session.setIgnoreCase(mode);
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.DECLARE_SESSION_TABLE : {
+                Table         table           = (Table) parameters[0];
+                HsqlArrayList tempConstraints = (HsqlArrayList) parameters[1];
+                StatementDMQL statement       = (StatementDMQL) parameters[2];
+
+                try {
+                    if (tempConstraints != null) {
+                        table =
+                            ParserDDL.addTableConstraintDefinitions(session,
+                                table, tempConstraints, null, false);
+                    }
+
+                    table.compile(session, null);
+                    session.addSessionTable(table);
+
+                    if (statement != null) {
+                        Result result = statement.execute(session);
+
+                        table.insertIntoTable(session, result);
+                    }
+
+                    if (table.hasLobColumn) {
+                        RowIterator it = table.rowIterator(session);
+
+                        while (it.hasNext()) {
+                            Row      row  = it.getNextRow();
+                            Object[] data = row.getData();
+
+                            session.sessionData.adjustLobUsageCount(table,
+                                    data, 1);
+                        }
+                    }
+
+                    return Result.updateZeroResult;
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e, sql);
+                }
+            }
+            case StatementTypes.DROP_TABLE : {
+                HsqlName name     = (HsqlName) parameters[0];
+                Boolean  ifExists = (Boolean) parameters[1];
+                Table    table    = session.findSessionTable(name.name);
+
+                if (table == null) {
+                    if (ifExists.booleanValue()) {
+                        return Result.updateZeroResult;
+                    } else {
+                        throw Error.error(ErrorCode.X_42501, name.name);
+                    }
+                }
+
+                session.dropSessionTable(name.name);
+
+                return Result.updateZeroResult;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "StatementSession");
+        }
+    }
+
+    public boolean isAutoCommitStatement() {
+        return false;
+    }
+
+    public String describe(Session session) {
+        return sql;
+    }
+
+    public boolean isCatalogChange() {
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/StatementSet.java b/src/org/hsqldb/StatementSet.java
new file mode 100644
index 0000000..a13ffa9
--- /dev/null
+++ b/src/org/hsqldb/StatementSet.java
@@ -0,0 +1,411 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.ParserDQL.CompileContext;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArraySort;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.result.Result;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of Statement for PSM and trigger assignment.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementSet extends StatementDMQL {
+
+    Expression expression;
+
+    //
+    Expression[] targets;
+    int[]        variableIndexes;
+    Type[]       sourceTypes;
+
+    //
+    final int               operationType;
+    public final static int TRIGGER_SET  = 1;
+    public final static int SELECT_INTO  = 2;
+    public final static int VARIABLE_SET = 3;
+
+    /**
+     * Trigger SET statement.
+     */
+    StatementSet(Session session, Expression[] targets, Table table,
+                 RangeVariable rangeVars[], int[] indexes,
+                 Expression[] colExpressions, CompileContext compileContext) {
+
+        super(StatementTypes.ASSIGNMENT, StatementTypes.X_SQL_DATA_CHANGE,
+              session.getCurrentSchemaHsqlName());
+
+        this.operationType        = TRIGGER_SET;
+        this.targets              = targets;
+        this.targetTable          = table;
+        this.baseTable            = targetTable.getBaseTable();
+        this.updateColumnMap      = indexes;
+        this.updateExpressions    = colExpressions;
+        this.updateCheckColumns   = targetTable.getColumnCheckList(indexes);
+        this.targetRangeVariables = rangeVars;
+        isTransactionStatement    = false;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+    }
+
+    /**
+     * PSM and session variable SET
+     */
+    StatementSet(Session session, Expression[] targets, Expression e,
+                 int[] indexes, CompileContext compileContext) {
+
+        super(StatementTypes.ASSIGNMENT, StatementTypes.X_SQL_CONTROL, null);
+
+        this.operationType     = VARIABLE_SET;
+        this.targets           = targets;
+        this.expression        = e;
+        variableIndexes        = indexes;
+        sourceTypes            = expression.getNodeDataTypes();
+        isTransactionStatement = false;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+    }
+
+    /**
+     * Single row SELECT INTO
+     */
+    StatementSet(Session session, Expression[] targets, QueryExpression query,
+                 int[] indexes, CompileContext compileContext) {
+
+        super(StatementTypes.ASSIGNMENT, StatementTypes.X_SQL_CONTROL, null);
+
+        this.operationType     = SELECT_INTO;
+        this.queryExpression   = query;
+        this.targets           = targets;
+        variableIndexes        = indexes;
+        sourceTypes            = query.getColumnTypes();
+        isTransactionStatement = false;
+
+        setDatabseObjects(session, compileContext);
+        checkAccessRights(session);
+    }
+
+    SubQuery[] getSubqueries(Session session) {
+
+        OrderedHashSet subQueries = null;
+
+        if (expression != null) {
+            subQueries = expression.collectAllSubqueries(subQueries);
+        }
+
+        if (subQueries == null || subQueries.size() == 0) {
+            return SubQuery.emptySubqueryArray;
+        }
+
+        SubQuery[] subQueryArray = new SubQuery[subQueries.size()];
+
+        subQueries.toArray(subQueryArray);
+        ArraySort.sort(subQueryArray, 0, subQueryArray.length,
+                       subQueryArray[0]);
+
+        for (int i = 0; i < subqueries.length; i++) {
+            subQueryArray[i].prepareTable(session);
+        }
+
+        return subQueryArray;
+    }
+
+    Result getResult(Session session) {
+
+        Result result = null;
+
+        switch (operationType) {
+
+            case StatementSet.TRIGGER_SET :
+                result = executeSetStatement(session);
+                break;
+
+            case StatementSet.SELECT_INTO : {
+                Object[] values = queryExpression.getSingleRowValues(session);
+
+                if (values == null) {
+                    result = Result.updateZeroResult;
+
+                    break;
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    values[i] =
+                        targets[i].getColumn().getDataType().convertToType(
+                            session, values[i], sourceTypes[i]);
+                }
+
+                result = executeAssignment(session, values);
+
+                break;
+            }
+            case StatementSet.VARIABLE_SET : {
+                Object[] values = getExpressionValues(session);
+
+                if (values == null) {
+                    result = Result.updateZeroResult;
+
+                    break;
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    Type targetType;
+
+                    if (targets[i].getType() == OpTypes.ARRAY_ACCESS) {
+                        targetType =
+                            targets[i].getLeftNode().getColumn().getDataType()
+                                .collectionBaseType();
+                    } else {
+                        targetType = targets[i].getColumn().getDataType();
+                    }
+
+                    values[i] = targetType.convertToType(session, values[i],
+                                                         sourceTypes[i]);
+                }
+
+                result = executeAssignment(session, values);
+
+                break;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "StatementSet");
+        }
+
+        return result;
+    }
+
+    public void resolve(Session session) {
+
+        references = new OrderedHashSet();
+
+        switch (operationType) {
+
+            case StatementSet.TRIGGER_SET :
+                for (int i = 0; i < updateExpressions.length; i++) {
+                    updateExpressions[i].collectObjectNames(references);
+                }
+                break;
+
+            case StatementSet.SELECT_INTO :
+            case StatementSet.VARIABLE_SET : {
+                if (expression != null) {
+                    expression.collectObjectNames(references);
+                }
+
+                if (queryExpression != null) {
+                    queryExpression.collectObjectNames(references);
+                }
+
+                break;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "StatementSet");
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        switch (operationType) {
+
+            case StatementSet.TRIGGER_SET :
+                return sql;
+
+            case StatementSet.VARIABLE_SET : {
+
+                /** @todo - cover row assignment */
+                sb.append(Tokens.T_SET).append(' ');
+                sb.append(targets[0].getColumn().getName().statementName);
+                sb.append(' ').append('=').append(' ').append(
+                    expression.getSQL());
+
+                break;
+            }
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        sb.append(Tokens.T_STATEMENT);
+
+        return sb.toString();
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        try {
+            if (subqueries.length > 0) {
+                materializeSubQueries(session);
+            }
+
+            result = getResult(session);
+        } catch (Throwable t) {
+            result = Result.newErrorResult(t, null);
+        }
+
+        if (result.isError()) {
+            result.getException().setStatementType(group, type);
+        }
+
+        return result;
+    }
+
+    public String describe(Session session) {
+        return "";
+    }
+
+    Result executeSetStatement(Session session) {
+
+        Table        table          = targetTable;
+        int[]        colMap         = updateColumnMap;    // column map
+        Expression[] colExpressions = updateExpressions;
+        Type[]       colTypes       = table.getColumnTypes();
+        int index = targetRangeVariables[TriggerDef.NEW_ROW].rangePosition;
+        Object[] oldData =
+            session.sessionContext.rangeIterators[index].getCurrent();
+        Object[] data = StatementDML.getUpdatedData(session, targets, table,
+            colMap, colExpressions, colTypes, oldData);
+
+        ArrayUtil.copyArray(data, oldData, data.length);
+
+        return Result.updateOneResult;
+    }
+
+    // this fk references -> other  :  other read lock
+    void collectTableNamesForRead(OrderedHashSet set) {
+
+        for (int i = 0; i < rangeVariables.length; i++) {
+            Table    rangeTable = rangeVariables[i].rangeTable;
+            HsqlName name       = rangeTable.getName();
+
+            if (rangeTable.isReadOnly() || rangeTable.isTemp()) {
+                continue;
+            }
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            set.add(name);
+        }
+
+        for (int i = 0; i < subqueries.length; i++) {
+            if (subqueries[i].queryExpression != null) {
+                subqueries[i].queryExpression.getBaseTableNames(set);
+            }
+        }
+
+        for (int i = 0; i < routines.length; i++) {
+            set.addAll(routines[i].getTableNamesForRead());
+        }
+    }
+
+    void collectTableNamesForWrite(OrderedHashSet set) {}
+
+    Object[] getExpressionValues(Session session) {
+
+        Object[] values;
+
+        if (expression.getType() == OpTypes.ROW) {
+            values = expression.getRowValue(session);
+        } else if (expression.getType() == OpTypes.ROW_SUBQUERY) {
+            values = expression.subQuery.queryExpression.getSingleRowValues(
+                session);
+
+            if (values == null) {
+
+                // todo - verify semantics
+                return null;
+            }
+        } else {
+            values    = new Object[1];
+            values[0] = expression.getValue(session);
+        }
+
+        return values;
+    }
+
+    Result executeAssignment(Session session, Object[] values) {
+
+        for (int j = 0; j < values.length; j++) {
+            Object[] data = ValuePool.emptyObjectArray;
+
+            switch (targets[j].getColumn().getType()) {
+
+                case SchemaObject.PARAMETER :
+                    data = session.sessionContext.routineArguments;
+                    break;
+
+                case SchemaObject.VARIABLE :
+                    data = session.sessionContext.routineVariables;
+                    break;
+            }
+
+            int colIndex = variableIndexes[j];
+
+            if (targets[j].getType() == OpTypes.ARRAY_ACCESS) {
+                data[colIndex] =
+                    ((ExpressionAccessor) targets[j]).getUpdatedArray(session,
+                        (Object[]) data[colIndex], values[j], true);
+            } else {
+                data[colIndex] = values[j];
+            }
+        }
+
+        return Result.updateZeroResult;
+    }
+}
diff --git a/src/org/hsqldb/StatementSimple.java b/src/org/hsqldb/StatementSimple.java
new file mode 100644
index 0000000..531a9e5
--- /dev/null
+++ b/src/org/hsqldb/StatementSimple.java
@@ -0,0 +1,209 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.result.Result;
+
+/**
+ * Implementation of Statement for simple PSM control statements.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class StatementSimple extends Statement {
+
+    String   sqlState;
+    HsqlName label;
+
+    //
+    ColumnSchema[] variables;
+    int[]          variableIndexes;
+
+    StatementSimple(int type, HsqlName label) {
+
+        super(type, StatementTypes.X_SQL_CONTROL);
+
+        references             = new OrderedHashSet();
+        isTransactionStatement = false;
+        this.label             = label;
+    }
+
+    StatementSimple(int type, String sqlState) {
+
+        super(type, StatementTypes.X_SQL_CONTROL);
+
+        references             = new OrderedHashSet();
+        isTransactionStatement = false;
+        this.sqlState          = sqlState;
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        switch (type) {
+
+            /** @todo 1.9.0 - add the exception */
+            case StatementTypes.SIGNAL :
+                sb.append(Tokens.T_SIGNAL);
+                break;
+
+            case StatementTypes.RESIGNAL :
+                sb.append(Tokens.T_RESIGNAL);
+                break;
+
+            case StatementTypes.ITERATE :
+                sb.append(Tokens.T_ITERATE).append(' ').append(label);
+                break;
+
+            case StatementTypes.LEAVE :
+                sb.append(Tokens.T_LEAVE).append(' ').append(label);
+                break;
+        }
+
+        return sb.toString();
+    }
+
+    protected String describe(Session session, int blanks) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('\n');
+
+        for (int i = 0; i < blanks; i++) {
+            sb.append(' ');
+        }
+
+        sb.append(Tokens.T_STATEMENT);
+
+        return sb.toString();
+    }
+
+    public Result execute(Session session) {
+
+        Result result;
+
+        try {
+            result = getResult(session);
+        } catch (Throwable t) {
+            result = Result.newErrorResult(t, null);
+        }
+
+        if (result.isError()) {
+            result.getException().setStatementType(group, type);
+        }
+
+        return result;
+    }
+
+    Result getResult(Session session) {
+
+        switch (type) {
+
+            /** @todo - check sqlState against allowed values */
+            case StatementTypes.SIGNAL :
+            case StatementTypes.RESIGNAL :
+                HsqlException ex = Error.error("sql routine error", sqlState,
+                                               -1);
+
+                return Result.newErrorResult(ex);
+
+            case StatementTypes.ITERATE :
+            case StatementTypes.LEAVE :
+                return Result.newPSMResult(type, label.name, null);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "");
+        }
+    }
+
+    public void resolve(Session session) {
+
+        boolean resolved = false;
+
+        switch (type) {
+
+            case StatementTypes.SIGNAL :
+            case StatementTypes.RESIGNAL :
+                resolved = true;
+                break;
+
+            case StatementTypes.ITERATE : {
+                StatementCompound statement = parent;
+
+                while (statement != null) {
+                    if (statement.isLoop) {
+                        if (label == null) {
+                            resolved = true;
+
+                            break;
+                        }
+
+                        if (statement.label != null
+                                && label.name.equals(statement.label.name)) {
+                            resolved = true;
+
+                            break;
+                        }
+                    }
+
+                    statement = statement.parent;
+                }
+
+                break;
+            }
+            case StatementTypes.LEAVE :
+                resolved = true;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "");
+        }
+
+        if (!resolved) {
+            throw Error.error(ErrorCode.X_42602);
+        }
+    }
+
+    public String describe(Session session) {
+        return "";
+    }
+
+    public boolean isCatalogChange() {
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/StatementTypes.java b/src/org/hsqldb/StatementTypes.java
new file mode 100644
index 0000000..07ac594
--- /dev/null
+++ b/src/org/hsqldb/StatementTypes.java
@@ -0,0 +1,273 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+/*
+ * Codes based on SQL Standards for different types of statement.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface StatementTypes {
+
+    int ALLOCATE_CURSOR                  = 1;
+    int ALLOCATE_DESCRIPTOR              = 2;
+    int ALTER_DOMAIN                     = 3;
+    int ALTER_ROUTINE                    = 17;
+    int ALTER_SEQUENCE                   = 134;
+    int ALTER_TYPE                       = 60;
+    int ALTER_TABLE                      = 4;
+    int ALTER_TRANSFORM                  = 127;
+    int CREATE_ASSERTION                 = 6;
+    int CALL                             = 7;
+    int CREATE_CHARACTER_SET             = 8;
+    int CLOSE_CURSOR                     = 9;
+    int CREATE_COLLATION                 = 10;
+    int COMMIT_WORK                      = 11;
+    int CONNECT                          = 13;
+    int DEALLOCATE_DESCRIPTOR            = 15;
+    int DEALLOCATE_PREPARE               = 16;
+    int DELETE_CURSOR                    = 18;
+    int DELETE_WHERE                     = 19;
+    int DESCRIBE                         = 20;
+    int SELECT_DIRECT_SINGLE             = 21;    // identifier is SELECT
+    int DISCONNECT                       = 22;
+    int CREATE_DOMAIN                    = 23;
+    int DROP_ASSERTION                   = 24;
+    int DROP_CHARACTER_SET               = 25;
+    int DROP_COLLATION                   = 26;
+    int DROP_TYPE                        = 35;
+    int DROP_DOMAIN                      = 27;
+    int DROP_ROLE                        = 29;
+    int DROP_ROUTINE                     = 30;
+    int DROP_SCHEMA                      = 31;
+    int DROP_SEQUENCE                    = 135;
+    int DROP_TABLE                       = 32;
+    int DROP_TRANSFORM                   = 116;
+    int DROP_TRANSLATION                 = 33;
+    int DROP_TRIGGER                     = 34;
+    int DROP_CAST                        = 78;
+    int DROP_ORDERING                    = 115;
+    int DROP_VIEW                        = 36;
+    int DYNAMIC_CLOSE                    = 37;
+    int DYNAMIC_DELETE_CURSOR            = 38;
+    int DYNAMIC_FETCH                    = 39;
+    int DYNAMIC_OPEN                     = 40;
+    int SELECT_CURSOR                    = 85;
+    int SELECT_SINGLE_DYNAMIC            = 41;    // identifier is SELECT
+    int DYNAMIC_UPDATE_CURSOR            = 42;
+    int EXECUTE_IMMEDIATE                = 43;
+    int EXECUTE                          = 44;
+    int FETCH                            = 45;
+    int FREE_LOCATOR                     = 98;
+    int GET_DESCRIPTOR                   = 47;
+    int HOLD_LOCATOR                     = 99;
+    int GRANT                            = 48;
+    int GRANT_ROLE                       = 49;
+    int INSERT                           = 50;
+    int MERGE                            = 128;
+    int OPEN                             = 53;
+    int PREPARABLE_DYNAMIC_DELETE_CURSOR = 54;
+    int PREPARABLE_DYNAMIC_UPDATE_CURSOR = 55;
+    int PREPARE                          = 56;
+    int RELEASE_SAVEPOINT                = 57;
+    int RETURN                           = 58;
+    int REVOKE                           = 59;
+    int REVOKE_ROLE                      = 129;
+    int CREATE_ROLE                      = 61;
+    int ROLLBACK_WORK                    = 62;
+    int SAVEPOINT                        = 63;
+    int CREATE_SCHEMA                    = 64;
+    int CREATE_ROUTINE                   = 14;
+    int SELECT_SINGLE                    = 65;    // identifier is SELECT
+    int CREATE_SEQUENCE                  = 133;
+    int SET_CATALOG                      = 66;
+    int SET_CONNECTION                   = 67;
+    int SET_CONSTRAINT                   = 68;
+    int SET_DESCRIPTOR                   = 70;
+    int SET_TIME_ZONE                    = 71;
+    int SET_NAMES                        = 72;
+    int SET_PATH                         = 69;
+    int SET_ROLE                         = 73;
+    int SET_SCHEMA                       = 74;
+    int SET_SESSION_AUTHORIZATION        = 76;
+    int SET_SESSION_CHARACTERISTICS      = 109;
+    int SET_COLLATION                    = 136;
+    int SET_TRANSFORM_GROUP              = 118;
+    int SET_TRANSACTION                  = 75;
+    int START_TRANSACTION                = 111;
+    int CREATE_TABLE                     = 77;
+    int CREATE_TRANSFORM                 = 117;
+    int CREATE_TRANSLATION               = 79;
+    int CREATE_TRIGGER                   = 80;
+    int UPDATE_CURSOR                    = 81;
+    int UPDATE_WHERE                     = 82;
+    int CREATE_CAST                      = 52;
+    int CREATE_TYPE                      = 83;
+    int CREATE_ORDERING                  = 114;
+    int CREATE_VIEW                      = 84;
+    int ASSIGNMENT                       = 5;     // PSM
+    int CASE                             = 86;
+    int BEGIN_END                        = 12;
+    int DROP_MODULE                      = 28;
+    int FOR                              = 46;
+    int IF                               = 88;
+    int ITERATE                          = 102;
+    int LEAVE                            = 89;
+    int LOOP                             = 90;
+    int RESIGNAL                         = 91;
+    int REPEAT                           = 95;
+    int SIGNAL                           = 92;
+    int CREATE_MODULE                    = 51;
+    int WHILE                            = 97;
+
+    //
+    int ALTER_FOREIGN_TABLE         = 104;
+    int ALTER_USER_MAPPING          = 123;
+    int DROP_FOREIGN_DATA_WRAPPER   = 121;
+    int DROP_SERVER                 = 110;
+    int DROP_FOREIGN_TABLE          = 105;
+    int DROP_ROUTINE_MAPPING        = 131;
+    int DROP_USER_MAPPING           = 124;
+    int CREATE_FOREIGN_DATA_WRAPPER = 119;
+    int CREATE_SERVER               = 107;
+    int CREATE_FOREIGN_TABLE        = 103;
+    int IMPORT_FOREIGN_SCHEMA       = 125;
+    int CREATE_ROUTINE_MAPPING      = 132;
+    int SET_PASSTHROUGH             = 126;
+    int CREATE_USER_MAPPING         = 122;
+
+    // hsqldb database
+    int DATABASE_BACKUP     = 1001;
+    int DATABASE_CHECKPOINT = 1002;
+    int DATABASE_SHUTDOWN   = 1003;
+    int DATABASE_SCRIPT     = 1004;
+
+    // hsqldb database settings
+    int SET_DATABASE_FILES_BACKUP_INCREMENT    = 1011;
+    int SET_DATABASE_FILES_CACHE_ROWS          = 1012;
+    int SET_DATABASE_FILES_CACHE_SIZE          = 1013;
+    int SET_DATABASE_FILES_DEFRAG              = 1014;
+    int SET_DATABASE_FILES_EVENT_LOG           = 1015;
+    int SET_DATABASE_FILES_LOBS_SCALE          = 1016;
+    int SET_DATABASE_FILES_LOCK                = 1017;
+    int SET_DATABASE_FILES_LOG                 = 1018;
+    int SET_DATABASE_FILES_LOG_SIZE            = 1019;
+    int SET_DATABASE_FILES_NIO                 = 1020;
+    int SET_DATABASE_FILES_READ_ONLY           = 1021;
+    int SET_DATABASE_FILES_READ_ONLY_FILES     = 1022;
+    int SET_DATABASE_FILES_SCALE               = 1023;
+    int SET_DATABASE_FILES_SCRIPT_FORMAT       = 1024;
+    int SET_DATABASE_FILES_TEMP_PATH           = 1025;
+    int SET_DATABASE_FILES_WRITE_DELAY         = 1026;
+    int SET_DATABASE_DEFAULT_INITIAL_SCHEMA    = 1031;
+    int SET_DATABASE_DEFAULT_TABLE_TYPE        = 1032;
+    int SET_DATABASE_GC                        = 1033;
+    int SET_DATABASE_PROPERTY                  = 1034;
+    int SET_DATABASE_READ_ONLY                 = 1035;
+    int SET_DATABASE_READ_ONLY_FILES           = 1036;
+    int SET_DATABASE_RESULT_MEMORY_ROWS        = 1037;
+    int SET_DATABASE_SCRIPT_FORMAT             = 1038;
+    int SET_DATABASE_SQL_COLLATION             = 1039;
+    int SET_SESSION_SQL_IGNORECASE             = 1040;
+    int SET_DATABASE_SQL_REFERENTIAL_INTEGRITY = 1041;
+    int SET_DATABASE_SQL_STRICT_NAMES          = 1042;
+    int SET_DATABASE_SQL_STRICT_SIZE           = 1043;
+    int SET_DATABASE_SQL_REFERENCES            = 1044;
+    int SET_DATABASE_TEXT_SOURCE               = 1045;
+    int SET_DATABASE_TRANSACTION_CONTROL       = 1046;
+    int SET_DATABASE_DEFAULT_ISOLATION_LEVEL   = 1047;
+    int SET_DATABASE_UNIQUE_NAME               = 1048;
+
+    // hsqldb user settings
+    int SET_USER_INITIAL_SCHEMA = 1061;
+    int SET_USER_PASSWORD       = 1062;
+
+    // hsqldb session
+    int TRANSACTION_LOCK_TABLE         = 1063;
+    int SET_SESSION_AUTOCOMMIT         = 1064;
+    int SET_SESSION_RESULT_MAX_ROWS    = 1065;
+    int SET_SESSION_RESULT_MEMORY_ROWS = 1066;
+    int ROLLBACK_SAVEPOINT             = 1067;
+    int DECLARE_SESSION_TABLE          = 1068;
+
+    // hsqldb schema
+    int ALTER_VIEW              = 1071;
+    int COMMENT                 = 1072;
+    int CREATE_ALIAS            = 1073;
+    int CREATE_INDEX            = 1074;
+    int CREATE_USER             = 1075;
+    int DECLARE_VARIABLE        = 1076;
+    int DROP_COLUMN             = 1077;
+    int DROP_INDEX              = 1078;
+    int DROP_CONSTRAINT         = 1079;
+    int DROP_USER               = 1080;
+    int EXPLAIN_PLAN            = 1081;
+    int RENAME_OBJECT           = 1082;
+    int SET_TABLE_INDEX         = 1083;
+    int SET_TABLE_READONLY      = 1084;
+    int SET_TABLE_SOURCE        = 1085;
+    int SET_TABLE_SOURCE_HEADER = 1086;
+    int SET_TABLE_TYPE          = 1087;
+    int LOG_SCHEMA_STATEMENT    = 1088;
+
+    // hsqldb sql implementation
+    int CONDITION = 1101;                         // element of IF
+    int HANDLER   = 1102;
+    int DDL       = 1103;
+    int CHECK     = 1104;
+    int TRUNCATE  = 1105;
+
+    // hsqldb groups
+    int X_SQL_SCHEMA_DEFINITION      = 2001;
+    int X_SQL_SCHEMA_MANIPULATION    = 2002;
+    int X_SQL_DATA                   = 2003;
+    int X_SQL_DATA_CHANGE            = 2004;
+    int X_SQL_TRANSACTION            = 2005;
+    int X_SQL_CONNECTION             = 2006;
+    int X_SQL_CONTROL                = 2007;
+    int X_SQL_SESSION                = 2008;
+    int X_SQL_DIAGNOSTICS            = 2009;
+    int X_SQL_DYNAMIC                = 2010;
+    int X_HSQLDB_SESSION             = 2011;
+    int X_HSQLDB_SCHEMA_MANIPULATION = 2012;
+    int X_HSQLDB_SETTING             = 2013;
+    int X_HSQLDB_DATABASE_OPERATION  = 2014;
+    int X_HSQLDB_TRANSACTION         = 2015;
+    int X_DYNAMIC                    = 2016;
+
+    // Expected types of Result returned for an SQL statement
+    int RETURN_ANY    = 0;
+    int RETURN_COUNT  = 1;
+    int RETURN_RESULT = 2;
+}
diff --git a/src/org/hsqldb/SubQuery.java b/src/org/hsqldb/SubQuery.java
new file mode 100644
index 0000000..4609597
--- /dev/null
+++ b/src/org/hsqldb/SubQuery.java
@@ -0,0 +1,366 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.util.Comparator;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.HsqlNameManager.SimpleName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.navigator.RowSetNavigatorData;
+import org.hsqldb.navigator.RowSetNavigatorDataTable;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+
+/**
+ * Represents an SQL view or anonymous subquery (inline virtual table
+ * descriptor) nested within an SQL statement. <p>
+ *
+ * Implements {@link org.hsqldb.lib.ObjectComparator ObjectComparator} to
+ * provide the correct order of materialization for nested views / subqueries.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ */
+class SubQuery implements Comparator {
+
+    int                  level;
+    private boolean      isResolved;
+    private boolean      isCorrelated;
+    private boolean      isExistsPredicate;
+    private boolean      uniqueRows;
+    private boolean      fullOrder;
+    QueryExpression      queryExpression;
+    Database             database;
+    private TableDerived table;
+    View                 view;
+    View                 parentView;
+    String               sql;
+
+    // IN condition optimisation
+    Expression dataExpression;
+    boolean    isDataExpression;
+
+    //
+    SimpleName[] columnNames;
+
+    //
+    int parsePosition;
+
+    //
+    public final static SubQuery[] emptySubqueryArray = new SubQuery[]{};
+
+    SubQuery(Database database, int level, QueryExpression queryExpression,
+             int mode) {
+
+        this.level           = level;
+        this.queryExpression = queryExpression;
+        this.database        = database;
+
+        switch (mode) {
+
+            case OpTypes.EXISTS :
+                isExistsPredicate = true;
+                break;
+
+            case OpTypes.IN :
+                uniqueRows = true;
+
+                if (queryExpression != null) {
+                    queryExpression.setFullOrder();
+                }
+                break;
+
+            case OpTypes.UNIQUE :
+                fullOrder = true;
+
+                if (queryExpression != null) {
+                    queryExpression.setFullOrder();
+                }
+        }
+    }
+
+    SubQuery(Database database, int level, QueryExpression queryExpression,
+             View view) {
+
+        this.level           = level;
+        this.queryExpression = queryExpression;
+        this.database        = database;
+        this.view            = view;
+    }
+
+    SubQuery(Database database, int level, Expression dataExpression,
+             int mode) {
+
+        this.level              = level;
+        this.database           = database;
+        this.dataExpression     = dataExpression;
+        dataExpression.subQuery = this;
+        isDataExpression        = true;
+
+        switch (mode) {
+
+            case OpTypes.IN :
+                uniqueRows = true;
+                break;
+        }
+    }
+
+    public boolean isResolved() {
+        return isResolved;
+    }
+
+    public boolean isCorrelated() {
+        return isCorrelated;
+    }
+
+    public void setCorrelated() {
+        isCorrelated = true;
+    }
+
+    public void setUniqueRows() {
+        uniqueRows = true;
+    }
+
+    public TableDerived getTable() {
+        return table;
+    }
+
+    public void createTable() {
+
+        HsqlName name = database.nameManager.getSubqueryTableName();
+
+        table = new TableDerived(database, name, TableBase.SYSTEM_SUBQUERY,
+                                 queryExpression, this);
+    }
+
+    public void prepareTable(Session session, HsqlName name,
+                             HsqlName[] columns) {
+
+        if (isResolved) {
+            return;
+        }
+
+        if (table == null) {
+            table = new TableDerived(database, name,
+                                     TableBase.SYSTEM_SUBQUERY,
+                                     queryExpression, this);
+        }
+
+        if (columns != null && queryExpression != null) {
+            queryExpression.getMainSelect().setColumnAliases(columns);
+        }
+
+        table.columnList  = queryExpression.getColumns();
+        table.columnCount = queryExpression.getColumnCount();
+
+        TableUtil.setTableIndexesForSubquery(table, uniqueRows || fullOrder,
+                                             uniqueRows);
+
+        isResolved = true;
+    }
+
+    public void prepareTable(Session session) {
+
+        if (isResolved) {
+            return;
+        }
+
+        if (view == null) {
+            if (table == null) {
+                HsqlName name = database.nameManager.getSubqueryTableName();
+
+                table = new TableDerived(database, name,
+                                         TableBase.SYSTEM_SUBQUERY,
+                                         queryExpression, this);
+            }
+
+            if (isDataExpression) {
+                TableUtil.addAutoColumns(table, dataExpression.nodeDataTypes);
+                TableUtil.setTableIndexesForSubquery(table,
+                                                     uniqueRows || fullOrder,
+                                                     uniqueRows);
+            } else {
+                table.columnList  = queryExpression.getColumns();
+                table.columnCount = queryExpression.getColumnCount();
+
+                TableUtil.setTableIndexesForSubquery(table,
+                                                     uniqueRows || fullOrder,
+                                                     uniqueRows);
+            }
+        } else {
+            table = new TableDerived(database, view.getName(),
+                                     TableBase.VIEW_TABLE, queryExpression,
+                                     this);
+            table.columnList  = view.columnList;
+            table.columnCount = table.columnList.size();
+
+            table.createPrimaryKey();
+        }
+
+        isResolved = true;
+    }
+
+    public void setColumnNames(SimpleName[] names) {
+        columnNames = names;
+    }
+
+    public SimpleName[] gtColumnNames() {
+        return columnNames;
+    }
+
+    public void materialiseCorrelated(Session session) {
+
+        if (isCorrelated) {
+            materialise(session);
+        }
+    }
+
+    /**
+     * Fills the table with a result set
+     */
+    public void materialise(Session session) {
+
+        PersistentStore store;
+
+        // table constructors
+        if (isDataExpression) {
+            store = session.sessionData.getSubqueryRowStore(table);
+
+            dataExpression.insertValuesIntoSubqueryTable(session, store);
+
+            return;
+        }
+
+        Result result = queryExpression.getResult(session,
+            isExistsPredicate ? 1
+                              : 0);
+
+        if (uniqueRows) {
+            RowSetNavigatorData navigator =
+                ((RowSetNavigatorData) result.getNavigator());
+
+            navigator.removeDuplicates();
+        }
+
+        store = session.sessionData.getSubqueryRowStore(table);
+
+        table.insertResult(session, store, result);
+        result.getNavigator().close();
+    }
+
+    public boolean hasUniqueNotNullRows(Session session) {
+
+        RowSetNavigatorData navigator = new RowSetNavigatorDataTable(session,
+            table);
+        boolean result = navigator.hasUniqueNotNullRows();
+
+        return result;
+    }
+
+    public Object[] getValues(Session session) {
+
+        RowIterator it = table.rowIterator(session);
+
+        if (it.hasNext()) {
+            Row row = it.getNextRow();
+
+            if (it.hasNext()) {
+                throw Error.error(ErrorCode.X_21000);
+            }
+
+            return row.getData();
+        } else {
+            return new Object[table.getColumnCount()];
+        }
+    }
+
+    public Object getValue(Session session) {
+
+        Object[] data = getValues(session);
+
+        return data[0];
+    }
+
+    public RowSetNavigatorData getNavigator(Session session) {
+
+        RowSetNavigatorData navigator = new RowSetNavigatorDataTable(session,
+            table);
+
+        return navigator;
+    }
+
+    /**
+     * This results in the following sort order:
+     *
+     * view subqueries, then other subqueries
+     *
+     *    view subqueries:
+     *        views sorted by creation order (earlier declaration first)
+     *
+     *    other subqueries:
+     *        subqueries sorted by depth within select query (deep == higher level)
+     *
+     */
+    public int compare(Object a, Object b) {
+
+        SubQuery sqa = (SubQuery) a;
+        SubQuery sqb = (SubQuery) b;
+
+        if (sqa.parentView == null && sqb.parentView == null) {
+            return sqb.level - sqa.level;
+        } else if (sqa.parentView != null && sqb.parentView != null) {
+            int ia = database.schemaManager.getTableIndex(sqa.parentView);
+            int ib = database.schemaManager.getTableIndex(sqb.parentView);
+
+            if (ia == -1) {
+                ia = database.schemaManager.getTables(
+                    sqa.parentView.getSchemaName().name).size();
+            }
+
+            if (ib == -1) {
+                ib = database.schemaManager.getTables(
+                    sqb.parentView.getSchemaName().name).size();
+            }
+
+            int diff = ia - ib;
+
+            return diff == 0 ? sqb.level - sqa.level
+                             : diff;
+        } else {
+            return sqa.parentView == null ? 1
+                                          : -1;
+        }
+    }
+}
diff --git a/src/org/hsqldb/Table.java b/src/org/hsqldb/Table.java
new file mode 100644
index 0000000..e018d68
--- /dev/null
+++ b/src/org/hsqldb/Table.java
@@ -0,0 +1,2769 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.RangeVariable.RangeIteratorBase;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.OrderedIntHashSet;
+import org.hsqldb.lib.Set;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.persist.CachedObject;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.Result;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ * Holds the data structures and methods for creation of a database table.
+ *
+ *
+ * Extensively rewritten and extended in successive versions of HSQLDB.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class Table extends TableBase implements SchemaObject {
+
+    public static final Table[] emptyArray = new Table[]{};
+
+    // main properties
+    private HsqlName tableName;
+    protected long   changeTimestamp;
+
+    //
+    public HashMappedList columnList;          // columns in table
+    int                   identityColumn;      // -1 means no such column
+    NumberSequence        identitySequence;    // next value of identity column
+
+// -----------------------------------------------------------------------
+    Constraint[]    constraintList;            // constrainst for the table
+    Constraint[]    fkConstraints;             //
+    Constraint[]    fkMainConstraints;
+    Constraint[]    checkConstraints;
+    TriggerDef[]    triggerList;
+    TriggerDef[][]  triggerLists;              // array of trigger lists
+    Expression[]    colDefaults;               // expressions of DEFAULT values
+    private boolean hasDefaultValues;          // shortcut for above
+    boolean[]       colGenerated;              // generated columns
+    private boolean hasGeneratedValues;        // shortcut for above
+    boolean[]       colRefFK;                  // foreign key columns
+    boolean[]       colMainFK;                 // columns referenced by foreign key
+    boolean         hasReferentialAction;      // has set null, set default or cascade
+    private boolean hasDomainColumns;          // shortcut
+    private boolean hasNotNullColumns;         // shortcut
+    protected int[] defaultColumnMap;          // holding 0,1,2,3,...
+    RangeVariable[] defaultRanges;
+
+    //
+    public Table(Database database, HsqlName name, int type) {
+
+        this.database = database;
+        tableName     = name;
+        persistenceId = database.persistentStoreCollection.getNextId();
+
+        switch (type) {
+
+            case SYSTEM_SUBQUERY :
+                persistenceScope = SCOPE_STATEMENT;
+                isSessionBased   = true;
+                break;
+
+            case SYSTEM_TABLE :
+                persistenceScope = SCOPE_FULL;
+                isSchemaBased    = true;
+                break;
+
+            case CACHED_TABLE :
+                if (DatabaseURL.isFileBasedDatabaseType(database.getType())) {
+                    persistenceScope = SCOPE_FULL;
+                    isSchemaBased    = true;
+                    isCached         = true;
+                    isLogged         = !database.isFilesReadOnly();
+
+                    break;
+                }
+
+                type = MEMORY_TABLE;
+
+            // fall through
+            case MEMORY_TABLE :
+                persistenceScope = SCOPE_FULL;
+                isSchemaBased    = true;
+                isLogged         = !database.isFilesReadOnly();
+                break;
+
+            case TEMP_TABLE :
+                persistenceScope = SCOPE_TRANSACTION;
+                isTemp           = true;
+                isSchemaBased    = true;
+                isSessionBased   = true;
+                break;
+
+            case TEMP_TEXT_TABLE :
+                persistenceScope = SCOPE_SESSION;
+
+                if (!DatabaseURL.isFileBasedDatabaseType(database.getType())) {
+                    throw Error.error(ErrorCode.DATABASE_IS_MEMORY_ONLY);
+                }
+
+                isSchemaBased  = true;
+                isSessionBased = true;
+                isTemp         = true;
+                isText         = true;
+                isReadOnly     = true;
+                break;
+
+            case TEXT_TABLE :
+                persistenceScope = SCOPE_FULL;
+
+                if (!DatabaseURL.isFileBasedDatabaseType(database.getType())) {
+                    throw Error.error(ErrorCode.DATABASE_IS_MEMORY_ONLY);
+                }
+
+                isSchemaBased = true;
+                isText        = true;
+                break;
+
+            case VIEW_TABLE :
+                persistenceScope = SCOPE_STATEMENT;
+                isSchemaBased    = true;
+                isSessionBased   = true;
+                isView           = true;
+                break;
+
+            case RESULT_TABLE :
+                persistenceScope = SCOPE_SESSION;
+                isSessionBased   = true;
+                break;
+
+            case TableBase.FUNCTION_TABLE :
+                persistenceScope = SCOPE_SESSION;
+                isSessionBased   = true;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Table");
+        }
+
+        // type may have changed above for CACHED tables
+        tableType         = type;
+        primaryKeyCols    = null;
+        primaryKeyTypes   = null;
+        identityColumn    = -1;
+        columnList        = new HashMappedList();
+        indexList         = Index.emptyArray;
+        constraintList    = Constraint.emptyArray;
+        fkConstraints     = Constraint.emptyArray;
+        fkMainConstraints = Constraint.emptyArray;
+        checkConstraints  = Constraint.emptyArray;
+        triggerList       = TriggerDef.emptyArray;
+        triggerLists      = new TriggerDef[TriggerDef.NUM_TRIGS][];
+
+        for (int i = 0; i < TriggerDef.NUM_TRIGS; i++) {
+            triggerLists[i] = TriggerDef.emptyArray;
+        }
+
+        if (database.isFilesReadOnly() && isFileBased()) {
+            this.isReadOnly = true;
+        }
+
+        if (isSchemaBased && !isTemp) {
+            createDefaultStore();
+        }
+    }
+
+    /** trigger transition table */
+    public Table(Table table, HsqlName name) {
+
+        persistenceScope    = SCOPE_STATEMENT;
+        name.schema         = SqlInvariants.SYSTEM_SCHEMA_HSQLNAME;
+        this.tableName      = name;
+        this.database       = table.database;
+        this.tableType      = RESULT_TABLE;
+        this.columnList     = table.columnList;
+        this.columnCount    = table.columnCount;
+        this.indexList      = Index.emptyArray;
+        this.constraintList = Constraint.emptyArray;
+
+        createPrimaryKey();
+    }
+
+    public void createDefaultStore() {
+
+        store = database.logger.newStore(null,
+                                         database.persistentStoreCollection,
+                                         this, true);
+    }
+
+    public int getType() {
+        return SchemaObject.TABLE;
+    }
+
+    /**
+     *  Returns the HsqlName object fo the table
+     */
+    public final HsqlName getName() {
+        return tableName;
+    }
+
+    public final void setName(HsqlName name) {
+        tableName = name;
+    }
+
+    /**
+     * Returns the catalog name or null, depending on a database property.
+     */
+    public HsqlName getCatalogName() {
+        return database.getCatalogName();
+    }
+
+    /**
+     * Returns the schema name.
+     */
+    public HsqlName getSchemaName() {
+        return tableName.schema;
+    }
+
+    public Grantee getOwner() {
+        return tableName.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0; i < colTypes.length; i++) {
+            ColumnSchema   column = getColumn(i);
+            OrderedHashSet refs   = column.getReferences();
+
+            if (!refs.isEmpty()) {
+                set.add(column.getName());
+            }
+        }
+
+        return set;
+    }
+
+    public OrderedHashSet getComponents() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        set.addAll(constraintList);
+        set.addAll(triggerList);
+
+        for (int i = 0; i < indexList.length; i++) {
+            if (!indexList[i].isConstraint()) {
+                set.add(indexList[i]);
+            }
+        }
+
+        return set;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {
+
+        for (int i = 0; i < columnCount; i++) {
+            ColumnSchema column = getColumn(i);
+
+            column.compile(session, this);
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_CREATE).append(' ');
+
+        if (isTemp()) {
+            sb.append(Tokens.T_GLOBAL).append(' ');
+            sb.append(Tokens.T_TEMPORARY).append(' ');
+        } else if (isText()) {
+            sb.append(Tokens.T_TEXT).append(' ');
+        } else if (isCached()) {
+            sb.append(Tokens.T_CACHED).append(' ');
+        } else {
+            sb.append(Tokens.T_MEMORY).append(' ');
+        }
+
+        sb.append(Tokens.T_TABLE).append(' ');
+        sb.append(getName().getSchemaQualifiedStatementName());
+        sb.append('(');
+
+        int[]      pk      = getPrimaryKey();
+        Constraint pkConst = getPrimaryConstraint();
+
+        for (int j = 0; j < columnCount; j++) {
+            ColumnSchema column  = getColumn(j);
+            String       colname = column.getName().statementName;
+            Type         type    = column.getDataType();
+
+            if (j > 0) {
+                sb.append(',');
+            }
+
+            sb.append(colname);
+            sb.append(' ');
+            sb.append(type.getTypeDefinition());
+
+            String defaultString = column.getDefaultSQL();
+
+            if (defaultString != null) {
+                sb.append(' ').append(Tokens.T_DEFAULT).append(' ');
+                sb.append(defaultString);
+            }
+
+            if (column.isIdentity()) {
+                sb.append(' ').append(column.getIdentitySequence().getSQL());
+            }
+
+            if (!column.isNullable()) {
+                Constraint c = getNotNullConstraintForColumn(j);
+
+                if (c != null && !c.getName().isReservedName()) {
+                    sb.append(' ').append(Tokens.T_CONSTRAINT).append(
+                        ' ').append(c.getName().statementName);
+                }
+
+                sb.append(' ').append(Tokens.T_NOT).append(' ').append(
+                    Tokens.T_NULL);
+            }
+
+            if (column.isGenerated()) {
+                sb.append(' ').append(Tokens.T_GENERATED).append(' ');
+                sb.append(Tokens.T_ALWAYS).append(' ').append(
+                    Tokens.T_AS).append(Tokens.T_OPENBRACKET);
+                sb.append(column.getGeneratingExpression().getSQL());
+                sb.append(Tokens.T_CLOSEBRACKET);
+            }
+
+            if (pk.length == 1 && j == pk[0]
+                    && pkConst.getName().isReservedName()) {
+                sb.append(' ').append(Tokens.T_PRIMARY).append(' ').append(
+                    Tokens.T_KEY);
+            }
+        }
+
+        Constraint[] constraintList = getConstraints();
+
+        for (int j = 0, vSize = constraintList.length; j < vSize; j++) {
+            Constraint c = constraintList[j];
+
+            if (!c.isForward) {
+                String d = c.getSQL();
+
+                if (d.length() > 0) {
+                    sb.append(',');
+                    sb.append(d);
+                }
+            }
+        }
+
+        sb.append(')');
+
+        if (onCommitPreserve()) {
+            sb.append(' ').append(Tokens.T_ON).append(' ');
+            sb.append(Tokens.T_COMMIT).append(' ').append(Tokens.T_PRESERVE);
+            sb.append(' ').append(Tokens.T_ROWS);
+        }
+
+        return sb.toString();
+    }
+
+    String[] getSQL(OrderedHashSet resolved, OrderedHashSet unresolved) {
+
+        for (int i = 0; i < constraintList.length; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.isForward) {
+                unresolved.add(c);
+            } else if (c.getConstraintType() == SchemaObject.ConstraintTypes
+                    .UNIQUE || c.getConstraintType() == SchemaObject
+                    .ConstraintTypes.PRIMARY_KEY) {
+                resolved.add(c.getName());
+            }
+        }
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        list.add(getSQL());
+
+        if (!isTemp && !isText && hasIdentityColumn()) {
+            list.add(NumberSequence.getRestartSQL(this));
+        }
+
+        for (int i = 0; i < indexList.length; i++) {
+            if (!indexList[i].isConstraint()
+                    && indexList[i].getColumnCount() > 0) {
+                list.add(indexList[i].getSQL());
+            }
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public String getSQLForReadOnly() {
+
+        if (isReadOnly) {
+            StringBuffer sb = new StringBuffer(64);
+
+            sb.append(Tokens.T_SET).append(' ').append(Tokens.T_TABLE).append(
+                ' ');
+            sb.append(getName().getSchemaQualifiedStatementName());
+            sb.append(' ').append(Tokens.T_READ).append(' ');
+            sb.append(Tokens.T_ONLY);
+
+            return sb.toString();
+        } else {
+            return null;
+        }
+    }
+
+    public String[] getSQLForTextSource(boolean withHeader) {
+
+        // readonly for TEXT tables only
+        if (isText()) {
+            HsqlArrayList list     = new HsqlArrayList();
+            boolean       readonly = isDataReadOnly();
+
+            if (readonly) {
+                list.add(getSQLForReadOnly());
+            }
+
+            // data source
+            String dataSource = ((TextTable) this).getDataSourceDDL();
+
+            if (dataSource != null) {
+                list.add(dataSource);
+            }
+
+            // header
+            String header = ((TextTable) this).getDataSourceHeader();
+
+            if (withHeader && header != null && !readonly) {
+                list.add(header);
+            }
+
+            String[] array = new String[list.size()];
+
+            list.toArray(array);
+
+            return array;
+        } else {
+            return null;
+        }
+    }
+
+    public String[] getTriggerSQL() {
+
+        String[] array = new String[triggerList.length];
+
+        for (int i = 0; i < triggerList.length; i++) {
+            array[i] = triggerList[i].getSQL();
+        }
+
+        return array;
+    }
+
+    public String getIndexRootsSQL(int[] roots) {
+
+        StringBuffer sb = new StringBuffer(128);
+
+        sb.append(Tokens.T_SET).append(' ').append(Tokens.T_TABLE).append(' ');
+        sb.append(getName().getSchemaQualifiedStatementName());
+        sb.append(' ').append(Tokens.T_INDEX).append(' ').append('\'');
+        sb.append(StringUtil.getList(roots, " ", ""));
+        sb.append('\'');
+
+        return sb.toString();
+    }
+
+    public String getColumnListSQL(int[] col, int len) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('(');
+
+        for (int i = 0; i < len; i++) {
+            sb.append(getColumn(col[i]).getName().statementName);
+
+            if (i < len - 1) {
+                sb.append(',');
+            }
+        }
+
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public String getColumnListWithTypeSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('(');
+
+        for (int j = 0; j < columnCount; j++) {
+            ColumnSchema column  = getColumn(j);
+            String       colname = column.getName().statementName;
+            Type         type    = column.getDataType();
+
+            if (j > 0) {
+                sb.append(',');
+            }
+
+            sb.append(colname);
+            sb.append(' ');
+            sb.append(type.getTypeDefinition());
+        }
+
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return changeTimestamp;
+    }
+
+    public boolean isConnected() {
+        return true;
+    }
+
+    /**
+     * compares two full table rows based on a set of columns
+     *
+     * @param a a full row
+     * @param b a full row
+     * @param cols array of column indexes to compare
+     * @param coltypes array of column types for the full row
+     *
+     * @return comparison result, -1,0,+1
+     */
+    public static int compareRows(Session session, Object[] a, Object[] b,
+                                  int[] cols, Type[] coltypes) {
+
+        int fieldcount = cols.length;
+
+        for (int j = 0; j < fieldcount; j++) {
+            int i = coltypes[cols[j]].compare(session, a[cols[j]], b[cols[j]]);
+
+            if (i != 0) {
+                return i;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Used to create row id's
+     */
+    public int getId() {
+        return tableName.hashCode();
+    }
+
+    public final boolean isText() {
+        return isText;
+    }
+
+    public final boolean isTemp() {
+        return isTemp;
+    }
+
+    public final boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public final boolean isView() {
+        return isView;
+    }
+
+    public boolean isCached() {
+        return isCached;
+    }
+
+    public boolean isDataReadOnly() {
+        return isReadOnly;
+    }
+
+    /**
+     * returns false if the table has to be recreated in order to add / drop
+     * indexes. Only CACHED tables return false.
+     */
+    final boolean isIndexingMutable() {
+        return !isIndexCached();
+    }
+
+    /**
+     *  Returns true if table is CACHED
+     */
+    boolean isIndexCached() {
+        return isCached;
+    }
+
+    /**
+     * Used by INSERT, DELETE, UPDATE operations
+     */
+    void checkDataReadOnly() {
+
+        if (isReadOnly) {
+            throw Error.error(ErrorCode.DATA_IS_READONLY);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// akede@users - 1.7.2 patch Files readonly
+    public void setDataReadOnly(boolean value) {
+
+        // Changing the Read-Only mode for the table is only allowed if the
+        // the database can realize it.
+        if (!value && database.isFilesReadOnly() && isFileBased()) {
+            throw Error.error(ErrorCode.DATA_IS_READONLY);
+        }
+
+        isReadOnly = value;
+    }
+
+    /**
+     * Text or Cached Tables are normally file based
+     */
+    public boolean isFileBased() {
+        return isCached || isText;
+    }
+
+    /**
+     *  Adds a constraint.
+     */
+    public void addConstraint(Constraint c) {
+
+        int index = c.getConstraintType()
+                    == SchemaObject.ConstraintTypes.PRIMARY_KEY ? 0
+                                                                : constraintList
+                                                                    .length;
+
+        constraintList =
+            (Constraint[]) ArrayUtil.toAdjustedArray(constraintList, c, index,
+                1);
+
+        updateConstraintLists();
+    }
+
+    void updateConstraintLists() {
+
+        int fkCount    = 0;
+        int mainCount  = 0;
+        int checkCount = 0;
+
+        hasReferentialAction = false;
+
+        for (int i = 0; i < constraintList.length; i++) {
+            switch (constraintList[i].getConstraintType()) {
+
+                case SchemaObject.ConstraintTypes.FOREIGN_KEY :
+                    fkCount++;
+                    break;
+
+                case SchemaObject.ConstraintTypes.MAIN :
+                    mainCount++;
+                    break;
+
+                case SchemaObject.ConstraintTypes.CHECK :
+                    if (constraintList[i].isNotNull()) {
+                        break;
+                    }
+
+                    checkCount++;
+                    break;
+            }
+        }
+
+        fkConstraints     = fkCount == 0 ? Constraint.emptyArray
+                                         : new Constraint[fkCount];
+        fkCount           = 0;
+        fkMainConstraints = mainCount == 0 ? Constraint.emptyArray
+                                           : new Constraint[mainCount];
+        mainCount         = 0;
+        checkConstraints  = checkCount == 0 ? Constraint.emptyArray
+                                            : new Constraint[checkCount];
+        checkCount        = 0;
+        colRefFK          = new boolean[columnCount];
+        colMainFK         = new boolean[columnCount];
+
+        for (int i = 0; i < constraintList.length; i++) {
+            switch (constraintList[i].getConstraintType()) {
+
+                case SchemaObject.ConstraintTypes.FOREIGN_KEY :
+                    fkConstraints[fkCount] = constraintList[i];
+
+                    ArrayUtil.intIndexesToBooleanArray(
+                        constraintList[i].getRefColumns(), colRefFK);
+
+                    fkCount++;
+                    break;
+
+                case SchemaObject.ConstraintTypes.MAIN :
+                    fkMainConstraints[mainCount] = constraintList[i];
+
+                    ArrayUtil.intIndexesToBooleanArray(
+                        constraintList[i].getMainColumns(), colMainFK);
+
+                    if (constraintList[i].hasTriggeredAction()) {
+                        hasReferentialAction = true;
+                    }
+
+                    mainCount++;
+                    break;
+
+                case SchemaObject.ConstraintTypes.CHECK :
+                    if (constraintList[i].isNotNull()) {
+                        break;
+                    }
+
+                    checkConstraints[checkCount] = constraintList[i];
+
+                    checkCount++;
+                    break;
+            }
+        }
+    }
+
+    void verifyConstraintsIntegrity() {
+
+        for (int i = 0; i < constraintList.length; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.getConstraintType() == SchemaObject.ConstraintTypes
+                    .FOREIGN_KEY || c.getConstraintType() == SchemaObject
+                    .ConstraintTypes.MAIN) {
+                if (c.getMain()
+                        != database.schemaManager.findUserTable(null,
+                            c.getMain().getName().name,
+                            c.getMain().getName().schema.name)) {
+                    throw Error.runtimeError(ErrorCode.U_S0500,
+                                             "FK mismatch : "
+                                             + c.getName().name);
+                }
+
+                if (c.getRef()
+                        != database.schemaManager.findUserTable(null,
+                            c.getRef().getName().name,
+                            c.getRef().getName().schema.name)) {
+                    throw Error.runtimeError(ErrorCode.U_S0500,
+                                             "FK mismatch : "
+                                             + c.getName().name);
+                }
+            }
+        }
+    }
+
+    /**
+     *  Returns the list of constraints.
+     */
+    public Constraint[] getConstraints() {
+        return constraintList;
+    }
+
+    /**
+     *  Returns the list of FK constraints.
+     */
+    public Constraint[] getFKConstraints() {
+        return fkConstraints;
+    }
+
+    /**
+     *  Returns the primary constraint.
+     */
+    public Constraint getPrimaryConstraint() {
+        return primaryKeyCols.length == 0 ? null
+                                          : constraintList[0];
+    }
+
+    /** columnMap is null for deletes */
+    void collectFKReadLocks(int[] columnMap, OrderedHashSet set) {
+
+        for (int i = 0; i < fkMainConstraints.length; i++) {
+            Constraint constraint  = fkMainConstraints[i];
+            Table      ref         = constraint.getRef();
+            int[]      mainColumns = constraint.getMainColumns();
+
+            if (ref == this) {
+                continue;
+            }
+
+            if (columnMap == null) {
+                if (constraint.core.hasDeleteAction) {
+                    int[] cols =
+                        constraint.core.deleteAction
+                        == SchemaObject.ReferentialAction.CASCADE ? null
+                                                                  : constraint
+                                                                      .getRefColumns();
+
+                    if (set.add(ref.getName())) {
+                        ref.collectFKReadLocks(cols, set);
+                    }
+                }
+            } else if (ArrayUtil.haveCommonElement(columnMap, mainColumns)) {
+                if (set.add(ref.getName())) {
+                    ref.collectFKReadLocks(constraint.getRefColumns(), set);
+                }
+            }
+        }
+    }
+
+    /** columnMap is null for deletes */
+    void collectFKWriteLocks(int[] columnMap, OrderedHashSet set) {
+
+        for (int i = 0; i < fkMainConstraints.length; i++) {
+            Constraint constraint  = fkMainConstraints[i];
+            Table      ref         = constraint.getRef();
+            int[]      mainColumns = constraint.getMainColumns();
+
+            if (ref == this) {
+                continue;
+            }
+
+            if (columnMap == null) {
+                if (constraint.core.hasDeleteAction) {
+                    int[] cols =
+                        constraint.core.deleteAction
+                        == SchemaObject.ReferentialAction.CASCADE ? null
+                                                                  : constraint
+                                                                      .getRefColumns();
+
+                    if (set.add(ref.getName())) {
+                        ref.collectFKWriteLocks(cols, set);
+                    }
+                }
+            } else if (ArrayUtil.haveCommonElement(columnMap, mainColumns)) {
+                if (constraint.core.hasUpdateAction) {
+                    if (set.add(ref.getName())) {
+                        ref.collectFKWriteLocks(constraint.getRefColumns(),
+                                                set);
+                    }
+                }
+            }
+        }
+    }
+
+    Constraint getNotNullConstraintForColumn(int colIndex) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.isNotNull() && c.notNullColumnIndex == colIndex) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the UNIQUE or PK constraint with the given column signature.
+     */
+    Constraint getUniqueConstraintForColumns(int[] cols) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.isUniqueWithColumns(cols)) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the UNIQUE or PK constraint with the given column signature.
+     * Modifies the composition of refTableCols if necessary.
+     */
+    Constraint getUniqueConstraintForColumns(int[] mainTableCols,
+            int[] refTableCols) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c    = constraintList[i];
+            int        type = c.getConstraintType();
+
+            if (type != SchemaObject.ConstraintTypes.UNIQUE
+                    && type != SchemaObject.ConstraintTypes.PRIMARY_KEY) {
+                continue;
+            }
+
+            int[] constraintCols = c.getMainColumns();
+
+            if (constraintCols.length != mainTableCols.length) {
+                continue;
+            }
+
+            if (ArrayUtil.areEqual(constraintCols, mainTableCols,
+                                   mainTableCols.length, true)) {
+                return c;
+            }
+
+            if (ArrayUtil.areEqualSets(constraintCols, mainTableCols)) {
+                int[] newRefTableCols = new int[mainTableCols.length];
+
+                for (int j = 0; j < mainTableCols.length; j++) {
+                    int pos = ArrayUtil.find(constraintCols, mainTableCols[j]);
+
+                    newRefTableCols[pos] = refTableCols[j];
+                }
+
+                for (int j = 0; j < mainTableCols.length; j++) {
+                    refTableCols[j] = newRefTableCols[j];
+                }
+
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     *  Returns any foreign key constraint equivalent to the column sets
+     */
+    Constraint getFKConstraintForColumns(Table tableMain, int[] mainCols,
+                                         int[] refCols) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.isEquivalent(tableMain, mainCols, this, refCols)) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     *  Returns any unique Constraint using this index
+     *
+     * @param  index
+     */
+    public Constraint getUniqueOrPKConstraintForIndex(Index index) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.getMainIndex() == index && (c
+                    .getConstraintType() == SchemaObject.ConstraintTypes
+                    .UNIQUE || c.getConstraintType() == SchemaObject
+                    .ConstraintTypes.PRIMARY_KEY)) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     *  Returns the next constraint of a given type
+     *
+     * @param  from
+     * @param  type
+     */
+    int getNextConstraintIndex(int from, int type) {
+
+        for (int i = from, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.getConstraintType() == type) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     *  Performs the table level checks and adds a column to the table at the
+     *  DDL level. Only used at table creation, not at alter column.
+     */
+    public void addColumn(ColumnSchema column) {
+
+        String name = column.getName().name;
+
+        if (findColumn(name) >= 0) {
+            throw Error.error(ErrorCode.X_42504, name);
+        }
+
+        if (column.isIdentity()) {
+            if (identityColumn != -1) {
+                throw Error.error(ErrorCode.X_42525, name);
+            }
+
+            identityColumn   = columnCount;
+            identitySequence = column.getIdentitySequence();
+        }
+
+        addColumnNoCheck(column);
+    }
+
+    public void addColumnNoCheck(ColumnSchema column) {
+
+        if (primaryKeyCols != null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Table");
+        }
+
+        columnList.add(column.getName().name, column);
+
+        columnCount++;
+
+        if (column.getDataType().isLobType()) {
+            hasLobColumn = true;
+        }
+    }
+
+    public boolean hasLobColumn() {
+        return hasLobColumn;
+    }
+
+    public boolean hasIdentityColumn() {
+        return identityColumn != -1;
+    }
+
+    public long getNextIdentity() {
+        return identitySequence.peek();
+    }
+
+    /**
+     * Match two valid, equal length, columns arrays for type of columns
+     *
+     * @param col column array from this Table
+     * @param other the other Table object
+     * @param othercol column array from the other Table
+     */
+    void checkColumnsMatch(int[] col, Table other, int[] othercol) {
+
+        for (int i = 0; i < col.length; i++) {
+            Type type      = colTypes[col[i]];
+            Type otherType = other.colTypes[othercol[i]];
+
+            if (type.typeComparisonGroup != otherType.typeComparisonGroup) {
+                throw Error.error(ErrorCode.X_42562);
+            }
+        }
+    }
+
+    void checkColumnsMatch(ColumnSchema column, int colIndex) {
+
+        Type type      = colTypes[colIndex];
+        Type otherType = column.getDataType();
+
+        if (type.typeComparisonGroup != otherType.typeComparisonGroup) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+    }
+
+    /**
+     * For removal or addition of columns, constraints and indexes
+     *
+     * Does not work in this form for FK's as Constraint.ConstraintCore
+     * is not transfered to a referencing or referenced table
+     */
+    Table moveDefinition(Session session, int newType, ColumnSchema column,
+                         Constraint constraint, Index index, int colIndex,
+                         int adjust, OrderedHashSet dropConstraints,
+                         OrderedHashSet dropIndexes) {
+
+        boolean newPK = false;
+
+        if (constraint != null
+                && constraint.constType
+                   == SchemaObject.ConstraintTypes.PRIMARY_KEY) {
+            newPK = true;
+        }
+
+        Table tn;
+
+        if (isText) {
+            tn = new TextTable(database, tableName, newType);
+            ((TextTable) tn).dataSource  = ((TextTable) this).dataSource;
+            ((TextTable) tn).isReversed  = ((TextTable) this).isReversed;
+            ((TextTable) tn).isConnected = ((TextTable) this).isConnected;
+        } else {
+            tn = new Table(database, tableName, newType);
+        }
+
+        if (tableType == TEMP_TABLE) {
+            tn.persistenceScope = persistenceScope;
+        }
+
+        for (int i = 0; i < columnCount; i++) {
+            ColumnSchema col = (ColumnSchema) columnList.get(i);
+
+            if (i == colIndex) {
+                if (column != null) {
+                    tn.addColumn(column);
+                }
+
+                if (adjust <= 0) {
+                    continue;
+                }
+            }
+
+            tn.addColumn(col);
+        }
+
+        if (columnCount == colIndex) {
+            tn.addColumn(column);
+        }
+
+        int[] pkCols = null;
+
+        if (hasPrimaryKey()
+                && !dropConstraints.contains(
+                    getPrimaryConstraint().getName())) {
+            pkCols = primaryKeyCols;
+            pkCols = ArrayUtil.toAdjustedColumnArray(pkCols, colIndex, adjust);
+        } else if (newPK) {
+            pkCols = constraint.getMainColumns();
+        }
+
+        tn.createPrimaryKey(getIndex(0).getName(), pkCols, false);
+
+        for (int i = 1; i < indexList.length; i++) {
+            Index idx = indexList[i];
+
+            if (dropIndexes.contains(idx.getName())) {
+                continue;
+            }
+
+            int[] colarr = ArrayUtil.toAdjustedColumnArray(idx.getColumns(),
+                colIndex, adjust);
+
+            idx = tn.createIndexStructure(idx.getName(), colarr,
+                                          idx.getColumnDesc(), null,
+                                          idx.isUnique(), idx.isConstraint(),
+                                          idx.isForward());
+
+            tn.addIndex(session, idx);
+        }
+
+        if (index != null) {
+            tn.addIndex(session, index);
+        }
+
+        HsqlArrayList newList = new HsqlArrayList();
+
+        if (newPK) {
+            constraint.core.mainIndex     = tn.indexList[0];
+            constraint.core.mainTable     = tn;
+            constraint.core.mainTableName = tn.tableName;
+
+            newList.add(constraint);
+        }
+
+        for (int i = 0; i < constraintList.length; i++) {
+            Constraint c = constraintList[i];
+
+            if (dropConstraints.contains(c.getName())) {
+                continue;
+            }
+
+            c = c.duplicate();
+
+            c.updateTable(session, this, tn, colIndex, adjust);
+            newList.add(c);
+        }
+
+        if (!newPK && constraint != null) {
+            constraint.updateTable(session, this, tn, -1, 0);
+            newList.add(constraint);
+        }
+
+        tn.constraintList = new Constraint[newList.size()];
+
+        newList.toArray(tn.constraintList);
+        tn.updateConstraintLists();
+        tn.setBestRowIdentifiers();
+
+        tn.triggerList  = triggerList;
+        tn.triggerLists = triggerLists;
+
+        return tn;
+    }
+
+    /**
+     * Used for drop / retype column.
+     */
+    void checkColumnInCheckConstraint(int colIndex) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.constType == SchemaObject.ConstraintTypes.CHECK
+                    && !c.isNotNull() && c.hasColumn(colIndex)) {
+                HsqlName name = c.getName();
+
+                throw Error.error(ErrorCode.X_42502,
+                                  name.getSchemaQualifiedStatementName());
+            }
+        }
+    }
+
+    /**
+     * Used for retype column. Checks whether column is in an FK or is
+     * referenced by a FK
+     * @param colIndex index
+     */
+    void checkColumnInFKConstraint(int colIndex) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.hasColumn(colIndex) && (c.getConstraintType() == SchemaObject
+                    .ConstraintTypes.MAIN || c
+                    .getConstraintType() == SchemaObject.ConstraintTypes
+                    .FOREIGN_KEY)) {
+                HsqlName name = c.getName();
+
+                throw Error.error(ErrorCode.X_42533,
+                                  name.getSchemaQualifiedStatementName());
+            }
+        }
+    }
+
+    /**
+     * Returns list of constraints dependent only on one column
+     */
+    OrderedHashSet getDependentConstraints(int colIndex) {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.hasColumnOnly(colIndex)) {
+                set.add(c);
+            }
+        }
+
+        return set;
+    }
+
+    /**
+     * Returns list of constraints dependent on more than one column
+     */
+    OrderedHashSet getContainingConstraints(int colIndex) {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.hasColumnPlus(colIndex)) {
+                set.add(c);
+            }
+        }
+
+        return set;
+    }
+
+    OrderedHashSet getContainingIndexNames(int colIndex) {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0, size = indexList.length; i < size; i++) {
+            Index index = indexList[i];
+
+            if (ArrayUtil.find(index.getColumns(), colIndex) != -1) {
+                set.add(index.getName());
+            }
+        }
+
+        return set;
+    }
+
+    /**
+     * Returns list of MAIN constraints dependent on this PK or UNIQUE constraint
+     */
+    OrderedHashSet getDependentConstraints(Constraint constraint) {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.getConstraintType() == SchemaObject.ConstraintTypes.MAIN) {
+                if (c.core.uniqueName == constraint.getName()) {
+                    set.add(c);
+                }
+            }
+        }
+
+        return set;
+    }
+
+    public OrderedHashSet getDependentExternalConstraints() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.getConstraintType() == SchemaObject.ConstraintTypes.MAIN
+                    || c.getConstraintType()
+                       == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+                if (c.core.mainTable != c.core.refTable) {
+                    set.add(c);
+                }
+            }
+        }
+
+        return set;
+    }
+
+    /**
+     * Used for column defaults and nullability. Checks whether column is in an
+     * FK with a given referential action type.
+     *
+     * @param colIndex index of column
+     * @param actionType referential action of the FK
+     */
+    void checkColumnInFKConstraint(int colIndex, int actionType) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.getConstraintType() == SchemaObject.ConstraintTypes
+                    .FOREIGN_KEY && c
+                    .hasColumn(colIndex) && (actionType == c
+                        .getUpdateAction() || actionType == c
+                        .getDeleteAction())) {
+                HsqlName name = c.getName();
+
+                throw Error.error(ErrorCode.X_42533,
+                                  name.getSchemaQualifiedStatementName());
+            }
+        }
+    }
+
+    /**
+     *  Returns the identity column index.
+     */
+    int getIdentityColumnIndex() {
+        return identityColumn;
+    }
+
+    /**
+     *  Returns the index of given column name or throws if not found
+     */
+    public int getColumnIndex(String name) {
+
+        int i = findColumn(name);
+
+        if (i == -1) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        return i;
+    }
+
+    /**
+     *  Returns the index of given column name or -1 if not found.
+     */
+    public int findColumn(String name) {
+
+        int index = columnList.getIndex(name);
+
+        return index;
+    }
+
+    /**
+     * Sets the SQL default value for a columm.
+     */
+    void setDefaultExpression(int columnIndex, Expression def) {
+
+        ColumnSchema column = getColumn(columnIndex);
+
+        column.setDefaultExpression(def);
+        setColumnTypeVars(columnIndex);
+    }
+
+    /**
+     * sets the flag for the presence of any default expression
+     */
+    void resetDefaultsFlag() {
+
+        hasDefaultValues = false;
+
+        for (int i = 0; i < colDefaults.length; i++) {
+            hasDefaultValues |= colDefaults[i] != null;
+        }
+
+        hasGeneratedValues = false;
+
+        for (int i = 0; i < colGenerated.length; i++) {
+            hasGeneratedValues |= colGenerated[i];
+        }
+
+        hasNotNullColumns = false;
+
+        for (int i = 0; i < colNotNull.length; i++) {
+            hasNotNullColumns |= colNotNull[i];
+        }
+    }
+
+    public int[] getBestRowIdentifiers() {
+        return bestRowIdentifierCols;
+    }
+
+    public boolean isBestRowIdentifiersStrict() {
+        return bestRowIdentifierStrict;
+    }
+
+    /**
+     *  Finds an existing index for a column
+     */
+    Index getIndexForColumn(Session session, int col) {
+
+        int i = bestIndexForColumn[col];
+
+        if (i > -1) {
+            return indexList[i];
+        }
+
+        switch (tableType) {
+
+//            case TableBase.MEMORY_TABLE :
+            case TableBase.SYSTEM_SUBQUERY :
+            case TableBase.SYSTEM_TABLE :
+            case TableBase.VIEW_TABLE :
+            case TableBase.TEMP_TABLE : {
+                Index index = createIndexForColumns(session, new int[]{ col });
+
+                return index;
+            }
+        }
+
+        return null;
+    }
+
+    boolean isIndexed(int colIndex) {
+        return bestIndexForColumn[colIndex] != -1;
+    }
+
+    int[] getUniqueNotNullColumnGroup(boolean[] usedColumns) {
+
+        for (int i = 0, count = constraintList.length; i < count; i++) {
+            Constraint constraint = constraintList[i];
+
+            if (constraint.constType == SchemaObject.ConstraintTypes.UNIQUE) {
+                int[] indexCols = constraint.getMainColumns();
+
+                if (ArrayUtil.areAllIntIndexesInBooleanArray(
+                        indexCols, colNotNull) && ArrayUtil
+                            .areAllIntIndexesInBooleanArray(
+                                indexCols, usedColumns)) {
+                    return indexCols;
+                }
+            } else if (constraint.constType
+                       == SchemaObject.ConstraintTypes.PRIMARY_KEY) {
+                int[] indexCols = constraint.getMainColumns();
+
+                if (ArrayUtil.areAllIntIndexesInBooleanArray(indexCols,
+                        usedColumns)) {
+                    return indexCols;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    boolean areColumnsNotNull(int[] indexes) {
+        return ArrayUtil.areAllIntIndexesInBooleanArray(indexes, colNotNull);
+    }
+
+    /**
+     *  Shortcut for creating default PK's.
+     */
+    public void createPrimaryKey() {
+        createPrimaryKey(null, null, false);
+    }
+
+    /**
+     *  Creates a single or multi-column primary key and index. sets the
+     *  colTypes array. Finalises the creation of the table. (fredt@users)
+     */
+    public void createPrimaryKey(HsqlName indexName, int[] columns,
+                                 boolean columnsNotNull) {
+
+        if (primaryKeyCols != null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Table");
+        }
+
+        if (columns == null) {
+            columns = ValuePool.emptyIntArray;
+        } else {
+            for (int i = 0; i < columns.length; i++) {
+                getColumn(columns[i]).setPrimaryKey(true);
+            }
+        }
+
+        primaryKeyCols = columns;
+
+        setColumnStructures();
+
+        primaryKeyTypes = new Type[primaryKeyCols.length];
+
+        ArrayUtil.projectRow(colTypes, primaryKeyCols, primaryKeyTypes);
+
+        primaryKeyColsSequence = new int[primaryKeyCols.length];
+
+        ArrayUtil.fillSequence(primaryKeyColsSequence);
+
+        HsqlName name = indexName;
+
+        if (name == null) {
+            name = database.nameManager.newAutoName("IDX", getSchemaName(),
+                    getName(), SchemaObject.INDEX);
+        }
+
+        createPrimaryIndex(primaryKeyCols, primaryKeyTypes, name);
+        setBestRowIdentifiers();
+    }
+
+    public void createPrimaryKeyConstraint(HsqlName indexName, int[] columns,
+                                           boolean columnsNotNull) {
+
+        createPrimaryKey(indexName, columns, columnsNotNull);
+
+        Constraint c =
+            new Constraint(indexName, this, getPrimaryIndex(),
+                           SchemaObject.ConstraintTypes.PRIMARY_KEY);
+
+        this.addConstraint(c);
+    }
+
+    void setColumnStructures() {
+
+        colTypes         = new Type[columnCount];
+        colDefaults      = new Expression[columnCount];
+        colNotNull       = new boolean[columnCount];
+        colGenerated     = new boolean[columnCount];
+        defaultColumnMap = new int[columnCount];
+        hasDomainColumns = false;
+
+        for (int i = 0; i < columnCount; i++) {
+            setColumnTypeVars(i);
+        }
+
+        resetDefaultsFlag();
+
+        defaultRanges = new RangeVariable[]{ new RangeVariable(this, 1) };
+    }
+
+    void setColumnTypeVars(int i) {
+
+        ColumnSchema column   = getColumn(i);
+        Type         dataType = column.getDataType();
+
+        if (dataType.isDomainType()) {
+            hasDomainColumns = true;
+        }
+
+        colTypes[i]         = dataType;
+        colNotNull[i]       = column.isPrimaryKey() || !column.isNullable();
+        defaultColumnMap[i] = i;
+
+        if (column.isIdentity()) {
+            identitySequence = column.getIdentitySequence();
+            identityColumn   = i;
+        } else if (identityColumn == i) {
+            identityColumn = -1;
+        }
+
+        colDefaults[i]  = column.getDefaultExpression();
+        colGenerated[i] = column.isGenerated();
+
+        resetDefaultsFlag();
+    }
+
+    /**
+     * Returns direct mapping array.
+     */
+    int[] getColumnMap() {
+        return defaultColumnMap;
+    }
+
+    /**
+     * Returns empty mapping array.
+     */
+    int[] getNewColumnMap() {
+        return new int[columnCount];
+    }
+
+    boolean[] getColumnCheckList(int[] columnIndexes) {
+
+        boolean[] columnCheckList = new boolean[columnCount];
+
+        for (int i = 0; i < columnIndexes.length; i++) {
+            int index = columnIndexes[i];
+
+            if (index > -1) {
+                columnCheckList[index] = true;
+            }
+        }
+
+        return columnCheckList;
+    }
+
+    int[] getColumnIndexes(OrderedHashSet set) {
+
+        int[] cols = new int[set.size()];
+
+        for (int i = 0; i < cols.length; i++) {
+            cols[i] = getColumnIndex((String) set.get(i));
+        }
+
+        return cols;
+    }
+
+    int[] getColumnIndexes(HashMappedList list) {
+
+        int[] cols = new int[list.size()];
+
+        for (int i = 0; i < cols.length; i++) {
+            cols[i] = ((Integer) list.get(i)).intValue();
+        }
+
+        return cols;
+    }
+
+    /**
+     *  Returns the Column object at the given index
+     */
+    public ColumnSchema getColumn(int i) {
+        return (ColumnSchema) columnList.get(i);
+    }
+
+    public OrderedHashSet getColumnNameSet(int[] columnIndexes) {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0; i < columnIndexes.length; i++) {
+            set.add(((ColumnSchema) columnList.get(i)).getName());
+        }
+
+        return set;
+    }
+
+    public OrderedHashSet getColumnNameSet(boolean[] columnCheckList) {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0; i < columnCheckList.length; i++) {
+            if (columnCheckList[i]) {
+                set.add(columnList.get(i));
+            }
+        }
+
+        return set;
+    }
+
+    public void getColumnNames(boolean[] columnCheckList, Set set) {
+
+        for (int i = 0; i < columnCheckList.length; i++) {
+            if (columnCheckList[i]) {
+                set.add(((ColumnSchema) columnList.get(i)).getName());
+            }
+        }
+    }
+
+    public OrderedHashSet getColumnNameSet() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0; i < columnCount; i++) {
+            set.add(((ColumnSchema) columnList.get(i)).getName());
+        }
+
+        return set;
+    }
+
+    /**
+     * Returns array for a new row with SQL DEFAULT value for each column n
+     * where exists[n] is false. This provides default values only where
+     * required and avoids evaluating these values where they will be
+     * overwritten.
+     */
+    Object[] getNewRowData(Session session) {
+
+        Object[] data = new Object[columnCount];
+        int      i;
+
+        if (hasDefaultValues) {
+            for (i = 0; i < columnCount; i++) {
+                Expression def = colDefaults[i];
+
+                if (def != null) {
+                    data[i] = def.getValue(session, colTypes[i]);
+                }
+            }
+        }
+
+        return data;
+    }
+
+    boolean hasTrigger(int trigVecIndex) {
+        return triggerLists[trigVecIndex].length != 0;
+    }
+
+    /**
+     * Adds a trigger.
+     */
+    void addTrigger(TriggerDef td, HsqlName otherName) {
+
+        int index = triggerList.length;
+
+        if (otherName != null) {
+            int pos = getTriggerIndex(otherName.name);
+
+            if (pos != -1) {
+                index = pos + 1;
+            }
+        }
+
+        triggerList = (TriggerDef[]) ArrayUtil.toAdjustedArray(triggerList,
+                td, index, 1);
+
+        TriggerDef[] list = triggerLists[td.triggerType];
+
+        index = list.length;
+
+        if (otherName != null) {
+            for (int i = 0; i < list.length; i++) {
+                TriggerDef trigger = list[i];
+
+                if (trigger.getName().name.equals(otherName.name)) {
+                    index = i + 1;
+
+                    break;
+                }
+            }
+        }
+
+        list = (TriggerDef[]) ArrayUtil.toAdjustedArray(list, td, index, 1);
+        triggerLists[td.triggerType] = list;
+    }
+
+    /**
+     * Returns a trigger.
+     */
+    TriggerDef getTrigger(String name) {
+
+        for (int i = triggerList.length - 1; i >= 0; i--) {
+            if (triggerList[i].getName().name.equals(name)) {
+                return triggerList[i];
+            }
+        }
+
+        return null;
+    }
+
+    public int getTriggerIndex(String name) {
+
+        for (int i = 0; i < triggerList.length; i++) {
+            if (triggerList[i].getName().name.equals(name)) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Drops a trigger.
+     */
+    void removeTrigger(TriggerDef trigger) {
+
+        TriggerDef td = null;
+
+        for (int i = 0; i < triggerList.length; i++) {
+            td = triggerList[i];
+
+            if (td.getName().name.equals(trigger.getName().name)) {
+                td.terminate();
+
+                triggerList =
+                    (TriggerDef[]) ArrayUtil.toAdjustedArray(triggerList,
+                        null, i, -1);
+
+                break;
+            }
+        }
+
+        if (td == null) {
+            return;
+        }
+
+        int index = td.triggerType;
+
+        // look in each trigger in list
+        for (int j = 0; j < triggerLists[index].length; j++) {
+            td = triggerLists[index][j];
+
+            if (td.getName().name.equals(trigger.getName().name)) {
+                td.terminate();
+
+                triggerLists[index] = (TriggerDef[]) ArrayUtil.toAdjustedArray(
+                    triggerLists[index], null, j, -1);
+
+                break;
+            }
+        }
+    }
+
+    /**
+     * Drops all triggers.
+     */
+    void releaseTriggers() {
+
+        // look in each trigger list of each type of trigger
+        for (int i = 0; i < TriggerDef.NUM_TRIGS; i++) {
+            for (int j = 0; j < triggerLists[i].length; j++) {
+                triggerLists[i][j].terminate();
+            }
+
+            triggerLists[i] = TriggerDef.emptyArray;
+        }
+    }
+
+    /**
+     * Returns the index of the Index object of the given name or -1 if not found.
+     */
+    int getIndexIndex(String indexName) {
+
+        Index[] indexes = indexList;
+
+        for (int i = 0; i < indexes.length; i++) {
+            if (indexName.equals(indexes[i].getName().name)) {
+                return i;
+            }
+        }
+
+        // no such index
+        return -1;
+    }
+
+    /**
+     * Returns the Index object of the given name or null if not found.
+     */
+    Index getIndex(String indexName) {
+
+        Index[] indexes = indexList;
+        int     i       = getIndexIndex(indexName);
+
+        return i == -1 ? null
+                       : indexes[i];
+    }
+
+    /**
+     *  Return the position of the constraint within the list
+     */
+    int getConstraintIndex(String constraintName) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            if (constraintList[i].getName().name.equals(constraintName)) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     *  return the named constriant
+     */
+    public Constraint getConstraint(String constraintName) {
+
+        int i = getConstraintIndex(constraintName);
+
+        return (i < 0) ? null
+                       : constraintList[i];
+    }
+
+    /**
+     *  Returns any unique Constraint using this index
+     *
+     * @param  index
+     * @return
+     */
+    public Constraint getUniqueConstraintForIndex(Index index) {
+
+        for (int i = 0, size = constraintList.length; i < size; i++) {
+            Constraint c = constraintList[i];
+
+            if (c.getMainIndex() == index) {
+                if (c.getConstraintType() == SchemaObject.ConstraintTypes
+                        .PRIMARY_KEY || c.getConstraintType() == SchemaObject
+                        .ConstraintTypes.UNIQUE) {
+                    return c;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * remove a named constraint
+     */
+    void removeConstraint(String name) {
+
+        int index = getConstraintIndex(name);
+
+        if (index != -1) {
+            removeConstraint(index);
+        }
+    }
+
+    void removeConstraint(int index) {
+
+        constraintList =
+            (Constraint[]) ArrayUtil.toAdjustedArray(constraintList, null,
+                index, -1);
+
+        updateConstraintLists();
+    }
+
+    void renameColumn(ColumnSchema column, String newName, boolean isquoted) {
+
+        String oldname = column.getName().name;
+        int    i       = getColumnIndex(oldname);
+
+        columnList.setKey(i, newName);
+        column.getName().rename(newName, isquoted);
+    }
+
+    void renameColumn(ColumnSchema column, HsqlName newName) {
+
+        String oldname = column.getName().name;
+        int    i       = getColumnIndex(oldname);
+
+        if (findColumn(newName.name) != -1) {
+            throw Error.error(ErrorCode.X_42504);
+        }
+
+        columnList.setKey(i, newName.name);
+        column.getName().rename(newName);
+    }
+
+    public TriggerDef[] getTriggers() {
+        return triggerList;
+    }
+
+    public boolean isWritable() {
+        return !isReadOnly && !database.databaseReadOnly
+               && !(database.isFilesReadOnly() && (isCached || isText));
+    }
+
+    public boolean isInsertable() {
+        return isWritable();
+    }
+
+    public boolean isUpdatable() {
+        return isWritable();
+    }
+
+    public boolean isTriggerInsertable() {
+        return false;
+    }
+
+    public boolean isTriggerUpdatable() {
+        return false;
+    }
+
+    public boolean isTriggerDeletable() {
+        return false;
+    }
+
+    public int[] getUpdatableColumns() {
+        return defaultColumnMap;
+    }
+
+    public Table getBaseTable() {
+        return this;
+    }
+
+    public int[] getBaseTableColumnMap() {
+        return defaultColumnMap;
+    }
+
+//
+
+    /**
+     *  Used to create an index automatically for system and temp tables.
+     */
+    Index createIndexForColumns(Session session, int[] columns) {
+
+        Index index = null;
+        HsqlName indexName = database.nameManager.newAutoName("IDX_T",
+            getSchemaName(), getName(), SchemaObject.INDEX);
+
+        try {
+            index = createAndAddIndexStructure(session, indexName, columns,
+                                               null, null, false, false,
+                                               false);
+        } catch (Throwable t) {
+            return null;
+        }
+
+        switch (tableType) {
+
+            case TableBase.TEMP_TABLE : {
+                Session sessions[] = database.sessionManager.getAllSessions();
+
+                for (int i = 0; i < sessions.length; i++) {
+                    sessions[i].sessionData.persistentStoreCollection
+                        .registerIndex((Table) this);
+                }
+
+                break;
+            }
+            case TableBase.SYSTEM_TABLE : {
+                session.sessionData.persistentStoreCollection.registerIndex(
+                    (Table) this);
+
+                break;
+            }
+        }
+
+        return index;
+    }
+
+    void fireTriggers(Session session, int trigVecIndex,
+                      RowSetNavigator rowSet) {
+
+        if (!database.isReferentialIntegrity()) {
+            return;
+        }
+
+        TriggerDef[] trigVec = triggerLists[trigVecIndex];
+
+        for (int i = 0, size = trigVec.length; i < size; i++) {
+            TriggerDef td         = trigVec[i];
+            boolean    sqlTrigger = td instanceof TriggerDefSQL;
+
+            if (td.hasOldTable()) {
+
+                //
+            }
+
+            td.pushPair(session, null, null);
+        }
+    }
+
+    /**
+     *  Fires all row-level triggers of the given set (trigger type)
+     *
+     */
+    void fireTriggers(Session session, int trigVecIndex, Object[] oldData,
+                      Object[] newData, int[] cols) {
+
+        if (!database.isReferentialIntegrity()) {
+            return;
+        }
+
+        TriggerDef[] trigVec = triggerLists[trigVecIndex];
+
+        for (int i = 0, size = trigVec.length; i < size; i++) {
+            TriggerDef td         = trigVec[i];
+            boolean    sqlTrigger = td instanceof TriggerDefSQL;
+
+            if (cols != null && td.getUpdateColumnIndexes() != null
+                    && !ArrayUtil.haveCommonElement(
+                        td.getUpdateColumnIndexes(), cols)) {
+                continue;
+            }
+
+            if (td.isForEachRow()) {
+                switch (td.triggerType) {
+
+                    case Trigger.INSERT_BEFORE_ROW :
+                        break;
+
+                    case Trigger.INSERT_AFTER_ROW :
+                        if (!sqlTrigger) {
+                            newData =
+                                (Object[]) ArrayUtil.duplicateArray(newData);
+                        }
+                        break;
+
+                    case Trigger.UPDATE_AFTER_ROW :
+                        if (!sqlTrigger) {
+                            oldData =
+                                (Object[]) ArrayUtil.duplicateArray(oldData);
+                            newData =
+                                (Object[]) ArrayUtil.duplicateArray(newData);
+                        }
+                        break;
+
+                    case Trigger.UPDATE_BEFORE_ROW :
+                    case Trigger.DELETE_BEFORE_ROW :
+                    case Trigger.DELETE_AFTER_ROW :
+                        if (!sqlTrigger) {
+                            oldData =
+                                (Object[]) ArrayUtil.duplicateArray(oldData);
+                        }
+                        break;
+                }
+
+                td.pushPair(session, oldData, newData);
+            } else {
+                td.pushPair(session, null, null);
+            }
+        }
+    }
+
+    /**
+     *  Enforce max field sizes according to SQL column definition.
+     *  SQL92 13.8
+     */
+    public void enforceRowConstraints(Session session, Object[] data) {
+
+        for (int i = 0; i < columnCount; i++) {
+            Type type = colTypes[i];
+
+            if (hasDomainColumns && type.isDomainType()) {
+                Constraint[] constraints =
+                    type.userTypeModifier.getConstraints();
+
+                for (int j = 0; j < constraints.length; j++) {
+                    constraints[j].checkCheckConstraint(session, this,
+                                                        (Object) data[i]);
+                }
+            }
+
+            if (colNotNull[i] && data[i] == null) {
+                Constraint c = getNotNullConstraintForColumn(i);
+
+                if (c == null) {
+                    c = this.getPrimaryConstraint();
+                }
+
+                String[] info = new String[] {
+                    c.getName().name, tableName.name
+                };
+
+                throw Error.error(null, ErrorCode.X_23502,
+                                  ErrorCode.CONSTRAINT, info);
+            }
+        }
+    }
+
+    public void enforceTypeLimits(Session session, Object[] data) {
+
+        for (int i = 0; i < columnCount; i++) {
+            data[i] = colTypes[i].convertToTypeLimits(session, data[i]);
+        }
+    }
+
+    boolean canGetIndexForColumn(Session session, int col) {
+
+        int i = bestIndexForColumn[col];
+
+        if (i > -1) {
+            return true;
+        }
+
+        switch (tableType) {
+
+//            case TableBase.MEMORY_TABLE :
+            case TableBase.SYSTEM_SUBQUERY :
+            case TableBase.SYSTEM_TABLE :
+            case TableBase.VIEW_TABLE :
+            case TableBase.TEMP_TABLE : {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     *  Finds an existing index for a column group
+     */
+    Index getIndexForColumns(Session session, int[] cols) {
+
+        int i = bestIndexForColumn[cols[0]];
+
+        if (i > -1) {
+            return indexList[i];
+        }
+
+        switch (tableType) {
+
+//            case TableBase.MEMORY_TABLE :
+            case TableBase.SYSTEM_SUBQUERY :
+            case TableBase.SYSTEM_TABLE :
+            case TableBase.VIEW_TABLE :
+            case TableBase.TEMP_TABLE : {
+                Index index = createIndexForColumns(session, cols);
+
+                return index;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     *  Finds an existing index for a full column group
+     */
+    Index getFullIndexForColumns(int[] cols) {
+
+        for (int i = 0; i < indexList.length; i++) {
+            if (ArrayUtil.haveEqualArrays(indexList[i].getColumns(), cols,
+                                          cols.length)) {
+                return indexList[i];
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Finds an existing index for a column set or create one for temporary
+     * tables
+     */
+    Index getIndexForColumns(Session session, OrderedIntHashSet set,
+                             boolean ordered) {
+
+        int   maxMatchCount = 0;
+        Index selected      = null;
+
+        if (set.isEmpty()) {
+            return null;
+        }
+
+        for (int i = 0, count = indexList.length; i < count; i++) {
+            Index currentindex = getIndex(i);
+            int[] indexcols    = currentindex.getColumns();
+            int matchCount = ordered ? set.getOrderedStartMatchCount(indexcols)
+                                     : set.getStartMatchCount(indexcols);
+
+            if (matchCount == 0) {
+                continue;
+            }
+
+            if (matchCount == indexcols.length) {
+                return currentindex;
+            }
+
+            if (matchCount > maxMatchCount) {
+                maxMatchCount = matchCount;
+                selected      = currentindex;
+            }
+        }
+
+        if (selected != null) {
+            return selected;
+        }
+
+        switch (tableType) {
+
+//            case TableBase.MEMORY_TABLE :
+            case TableBase.SYSTEM_SUBQUERY :
+            case TableBase.SYSTEM_TABLE :
+            case TableBase.VIEW_TABLE :
+            case TableBase.TEMP_TABLE : {
+                selected = createIndexForColumns(session, set.toArray());
+            }
+        }
+
+        return selected;
+    }
+
+    /**
+     *  Return the list of file pointers to root nodes for this table's
+     *  indexes.
+     */
+    public final int[] getIndexRootsArray() {
+
+        PersistentStore store =
+            database.persistentStoreCollection.getStore(this);
+        int[] roots = new int[indexList.length * 2 + 1];
+        int   i     = 0;
+
+        for (int index = 0; index < indexList.length; index++) {
+            CachedObject accessor = store.getAccessor(indexList[index]);
+
+            roots[i++] = accessor == null ? -1
+                                          : accessor.getPos();
+        }
+
+        for (int index = 0; index < indexList.length; index++) {
+            roots[i++] = indexList[index].sizeUnique(store);
+        }
+
+        roots[i] = indexList[0].size(null, store);
+
+        return roots;
+    }
+
+    /**
+     *  Sets the index roots of a cached/text table to specified file
+     *  pointers. If a
+     *  file pointer is -1 then the particular index root is null. A null index
+     *  root signifies an empty table. Accordingly, all index roots should be
+     *  null or all should be a valid file pointer/reference.
+     */
+    public void setIndexRoots(int[] roots) {
+
+        if (!isCached) {
+            throw Error.error(ErrorCode.X_42501, tableName.name);
+        }
+
+        PersistentStore store =
+            database.persistentStoreCollection.getStore(this);
+        int i = 0;
+
+        for (int index = 0; index < indexList.length; index++) {
+            store.setAccessor(indexList[index], roots[i++]);
+        }
+
+        int size = roots[indexList.length * 2];
+
+        for (int index = 0; index < indexList.length; index++) {
+            store.setElementCount(indexList[index], size, roots[i++]);
+        }
+    }
+
+    /**
+     *  Sets the index roots.
+     */
+    void setIndexRoots(Session session, String s) {
+
+        if (!isCached) {
+            throw Error.error(ErrorCode.X_42501, tableName.name);
+        }
+
+        ParserDQL p     = new ParserDQL(session, new Scanner(s));
+        int[]     roots = new int[getIndexCount() * 2 + 1];
+
+        p.read();
+
+        int i = 0;
+
+        for (int index = 0; index < getIndexCount(); index++) {
+            int v = p.readInteger();
+
+            roots[i++] = v;
+        }
+
+        try {
+            for (int index = 0; index < getIndexCount() + 1; index++) {
+                int v = p.readInteger();
+
+                roots[i++] = v;
+            }
+        } catch (Exception e) {
+            for (i = getIndexCount(); i < roots.length; i++) {
+                roots[i] = -1;
+            }
+        }
+
+        setIndexRoots(roots);
+    }
+
+    /**
+     *  Mid level method for inserting single rows. Performs constraint checks and
+     *  fires row level triggers.
+     */
+    Row insertSingleRow(Session session, PersistentStore store, Object[] data,
+                        int[] changedCols) {
+
+        if (identityColumn != -1) {
+            setIdentityColumn(session, data);
+        }
+
+        if (hasGeneratedValues) {
+            setGeneratedColumns(session, data);
+        }
+
+        if (hasDomainColumns || hasNotNullColumns) {
+            enforceRowConstraints(session, data);
+        }
+
+        if (isView) {
+
+            // may have domain column
+            return null;
+        }
+
+        Row row = (Row) store.getNewCachedObject(session, data);
+
+        store.indexRow(session, row);
+        session.addInsertAction(this, row);
+
+        return row;
+    }
+
+    /**
+     * Multi-row insert method. Used for CREATE TABLE AS ... queries.
+     */
+    void insertIntoTable(Session session, Result result) {
+
+        PersistentStore store = session.sessionData.getRowStore(this);
+        RowSetNavigator nav   = result.initialiseNavigator();
+
+        while (nav.hasNext()) {
+            Object[] data = (Object[]) nav.getNext();
+            Object[] newData =
+                (Object[]) ArrayUtil.resizeArrayIfDifferent(data, columnCount);
+
+            insertData(session, store, newData);
+        }
+    }
+
+    /**
+     *
+     */
+    public void insertNoCheckFromLog(Session session, Object[] data) {
+
+        systemUpdateIdentityValue(data);
+
+        PersistentStore store = session.sessionData.getRowStore(this);
+        Row             row   = (Row) store.getNewCachedObject(session, data);
+
+        store.indexRow(session, row);
+        session.addInsertAction(this, row);
+    }
+
+    /**
+     * Used for system table inserts. No checks. No identity
+     * columns.
+     */
+    public int insertSys(PersistentStore store, Result ins) {
+
+        RowSetNavigator nav   = ins.getNavigator();
+        int             count = 0;
+
+        while (nav.hasNext()) {
+            insertSys(store, (Object[]) nav.getNext());
+
+            count++;
+        }
+
+        return count;
+    }
+
+    /**
+     * Used for subquery inserts. No checks. No identity
+     * columns.
+     */
+    void insertResult(Session session, PersistentStore store, Result ins) {
+
+        RowSetNavigator nav = ins.initialiseNavigator();
+
+        while (nav.hasNext()) {
+            Object[] data = (Object[]) nav.getNext();
+            Object[] newData =
+                (Object[]) ArrayUtil.resizeArrayIfDifferent(data, columnCount);
+
+            insertData(session, store, newData);
+        }
+    }
+
+    /**
+     * Not for general use.
+     * Used by ScriptReader to unconditionally insert a row into
+     * the table when the .script file is read.
+     */
+    public void insertFromScript(Session session, PersistentStore store,
+                                 Object[] data) {
+        systemUpdateIdentityValue(data);
+        insertData(session, store, data);
+    }
+
+    /**
+     * For system operations outside transaction constrol
+     */
+    public void insertData(Session session, PersistentStore store,
+                           Object[] data) {
+
+        Row row = (Row) store.getNewCachedObject(null, data);
+
+        store.indexRow(session, row);
+    }
+
+    /**
+     * Used by the system tables only
+     */
+    public void insertSys(PersistentStore store, Object[] data) {
+
+        Row row = (Row) store.getNewCachedObject(null, data);
+
+        store.indexRow(null, row);
+    }
+
+    /**
+     * If there is an identity or generated column in the table, sets
+     * the value and/or adjusts the identiy value for the table.
+     */
+    protected void setIdentityColumn(Session session, Object[] data) {
+
+        if (identityColumn != -1) {
+            Number id = (Number) data[identityColumn];
+
+            if (id == null) {
+                id = (Number) identitySequence.getValueObject();
+                data[identityColumn] = id;
+            } else {
+                identitySequence.userUpdate(id.longValue());
+            }
+
+            if (session != null) {
+                session.setLastIdentity(id);
+            }
+        }
+    }
+
+    protected void setGeneratedColumns(Session session, Object[] data) {
+
+        if (hasGeneratedValues) {
+            for (int i = 0; i < colGenerated.length; i++) {
+                if (colGenerated[i]) {
+                    Expression e = getColumn(i).getGeneratingExpression();
+                    RangeIteratorBase range =
+                        session.sessionContext.getCheckIterator(
+                            defaultRanges[0]);
+
+                    range.currentData = data;
+                    data[i]           = e.getValue(session, colTypes[i]);
+                }
+            }
+        }
+    }
+
+    public void systemSetIdentityColumn(Session session, Object[] data) {
+
+        if (identityColumn != -1) {
+            Number id = (Number) data[identityColumn];
+
+            if (id == null) {
+                id = (Number) identitySequence.getValueObject();
+                data[identityColumn] = id;
+            } else {
+                identitySequence.userUpdate(id.longValue());
+            }
+        }
+    }
+
+    /**
+     * If there is an identity column in the table, sets
+     * the max identity value.
+     */
+    protected void systemUpdateIdentityValue(Object[] data) {
+
+        if (identityColumn != -1) {
+            Number id = (Number) data[identityColumn];
+
+            if (id != null) {
+                identitySequence.systemUpdate(id.longValue());
+            }
+        }
+    }
+
+    /**
+     * For log statements. Delete a single row.
+     */
+    public void deleteNoCheckFromLog(Session session, Object[] data) {
+
+        Row             row   = null;
+        PersistentStore store = session.sessionData.getRowStore(this);
+
+        if (hasPrimaryKey()) {
+            RowIterator it = getPrimaryIndex().findFirstRow(session, store,
+                data, primaryKeyColsSequence);
+
+            row = it.getNextRow();
+
+            it.release();
+        } else if (bestIndex == null) {
+            RowIterator it = rowIterator(session);
+
+            while (true) {
+                row = it.getNextRow();
+
+                if (row == null) {
+                    break;
+                }
+
+                if (Table.compareRows(
+                        session, row.getData(), data, defaultColumnMap,
+                        colTypes) == 0) {
+                    break;
+                }
+            }
+
+            it.release();
+        } else {
+            RowIterator it = bestIndex.findFirstRow(session, store, data);
+
+            while (true) {
+                row = it.getNextRow();
+
+                if (row == null) {
+                    break;
+                }
+
+                Object[] rowdata = row.getData();
+
+                // reached end of range
+                if (bestIndex.compareRowNonUnique(
+                        session, rowdata, data, bestIndex.getColumns()) != 0) {
+                    row = null;
+
+                    break;
+                }
+
+                if (Table.compareRows(
+                        session, rowdata, data, defaultColumnMap,
+                        colTypes) == 0) {
+                    break;
+                }
+            }
+
+            it.release();
+        }
+
+        if (row == null) {
+            return;
+        }
+
+        session.addDeleteAction(this, row, null);
+    }
+
+    public void clearAllData(Session session) {
+
+        super.clearAllData(session);
+
+        if (identitySequence != null) {
+            identitySequence.reset();
+        }
+    }
+
+    public void clearAllData(PersistentStore store) {
+
+        super.clearAllData(store);
+
+        if (identitySequence != null) {
+            identitySequence.reset();
+        }
+    }
+
+    /**
+     * Path used for INFORMATION_SCHEMA tables
+     */
+    public PersistentStore getRowStore(Session session) {
+
+        if (tableType == TableBase.SYSTEM_TABLE) {
+            database.dbInfo.getSystemTable(session, this.getName().name);
+
+            return session.sessionData.getRowStore(this);
+        }
+
+        return store == null ? session.sessionData.getRowStore(this)
+                             : store;
+    }
+
+    public SubQuery getSubQuery() {
+        return null;
+    }
+
+    public QueryExpression getQueryExpression() {
+        return null;
+    }
+}
diff --git a/src/org/hsqldb/TableBase.java b/src/org/hsqldb/TableBase.java
new file mode 100644
index 0000000..21cbc11
--- /dev/null
+++ b/src/org/hsqldb/TableBase.java
@@ -0,0 +1,544 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.types.Type;
+
+/**
+ * The  base of all HSQLDB table implementations.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class TableBase {
+
+    // types of table
+    public static final int SYSTEM_TABLE     = 1;
+    public static final int SYSTEM_SUBQUERY  = 2;
+    public static final int TEMP_TABLE       = 3;
+    public static final int MEMORY_TABLE     = 4;
+    public static final int CACHED_TABLE     = 5;
+    public static final int TEMP_TEXT_TABLE  = 6;
+    public static final int TEXT_TABLE       = 7;
+    public static final int VIEW_TABLE       = 8;
+    public static final int RESULT_TABLE     = 9;
+    public static final int TRANSITION_TABLE = 10;
+    public static final int FUNCTION_TABLE   = 11;
+
+    //
+    public static final int SCOPE_STATEMENT   = 21;
+    public static final int SCOPE_TRANSACTION = 22;
+    public static final int SCOPE_SESSION     = 23;
+    public static final int SCOPE_FULL        = 24;
+
+    //
+    public PersistentStore store;
+    public int             persistenceScope;
+    public long            persistenceId;
+
+    // columns in table
+    int[]  primaryKeyCols;                      // column numbers for primary key
+    Type[] primaryKeyTypes;
+    int[]  primaryKeyColsSequence;              // {0,1,2,...}
+
+    //
+    //
+    Index[]         indexList;                  // first index is the primary key index
+    public Database database;
+    int[]           bestRowIdentifierCols;      // column set for best index
+    boolean         bestRowIdentifierStrict;    // true if it has no nullable column
+    int[]           bestIndexForColumn;         // index of the 'best' index for each column
+    Index           bestIndex;                  // the best index overall - null if there is no user-defined index
+    Index         fullIndex;                    // index on all columns
+    boolean[]     colNotNull;                   // nullability
+    Type[]        colTypes;                     // types of columns
+    protected int columnCount;
+
+    //
+    int               tableType;
+    protected boolean isReadOnly;
+    protected boolean isTemp;
+    protected boolean isCached;
+    protected boolean isText;
+    boolean           isView;
+    public boolean    isSessionBased;
+    protected boolean isSchemaBased;
+    protected boolean isLogged;
+    private boolean   isTransactional = true;
+    boolean           hasLobColumn;
+
+    //
+    TableBase() {}
+
+    //
+    public TableBase(Session session, Database database, int scope, int type,
+                     Type[] colTypes) {
+
+        tableType        = type;
+        persistenceScope = scope;
+        isSessionBased   = true;
+        persistenceId    = database.persistentStoreCollection.getNextId();
+        this.database    = database;
+        this.colTypes    = colTypes;
+        columnCount      = colTypes.length;
+        primaryKeyCols   = new int[]{};
+        primaryKeyTypes  = new Type[]{};
+        indexList        = new Index[0];
+
+        createPrimaryIndex(primaryKeyCols, primaryKeyTypes, null);
+    }
+
+    public TableBase duplicate() {
+
+        TableBase copy = new TableBase();
+
+        copy.tableType        = tableType;
+        copy.persistenceScope = persistenceScope;
+        copy.isSessionBased   = isSessionBased;
+        copy.persistenceId    = database.persistentStoreCollection.getNextId();
+        copy.database         = database;
+        copy.colTypes         = colTypes;
+        copy.columnCount      = colTypes.length;
+        copy.primaryKeyCols   = primaryKeyCols;
+        copy.primaryKeyTypes  = primaryKeyTypes;
+        copy.indexList        = indexList;
+
+        return copy;
+    }
+
+    public final int getTableType() {
+        return tableType;
+    }
+
+    public long getPersistenceId() {
+        return persistenceId;
+    }
+
+    int getId() {
+        return 0;
+    }
+
+    public final boolean onCommitPreserve() {
+        return persistenceScope == TableBase.SCOPE_SESSION;
+    }
+
+    public final RowIterator rowIterator(Session session) {
+
+        PersistentStore store = session.sessionData.getRowStore(this);
+
+        return getPrimaryIndex().firstRow(session, store);
+    }
+
+    public final RowIterator rowIterator(PersistentStore store) {
+        return getPrimaryIndex().firstRow(store);
+    }
+
+    public final int getIndexCount() {
+        return indexList.length;
+    }
+
+    public final Index getPrimaryIndex() {
+        return indexList.length > 0 ? indexList[0]
+                                    : null;
+    }
+
+    public final Type[] getPrimaryKeyTypes() {
+        return primaryKeyTypes;
+    }
+
+    public final boolean hasPrimaryKey() {
+        return !(primaryKeyCols.length == 0);
+    }
+
+    public final int[] getPrimaryKey() {
+        return primaryKeyCols;
+    }
+
+    /**
+     *  Returns an array of Type indicating the SQL type of the columns
+     */
+    public final Type[] getColumnTypes() {
+        return colTypes;
+    }
+
+    /**
+     * Returns an index on all the columns
+     */
+    public Index getFullIndex() {
+        return fullIndex;
+    }
+
+    /**
+     *  Returns the Index object at the given index
+     */
+    public final Index getIndex(int i) {
+        return indexList[i];
+    }
+
+    /**
+     *  Returns the indexes
+     */
+    public final Index[] getIndexList() {
+        return indexList;
+    }
+
+    /**
+     * Returns empty boolean array.
+     */
+    public final boolean[] getNewColumnCheckList() {
+        return new boolean[getColumnCount()];
+    }
+
+    /**
+     *  Returns the count of all visible columns.
+     */
+    public int getColumnCount() {
+        return columnCount;
+    }
+
+    /**
+     *  Returns the count of all columns.
+     */
+    public final int getDataColumnCount() {
+        return colTypes.length;
+    }
+
+    public boolean isTransactional() {
+        return isTransactional;
+    }
+
+    public void setTransactional(boolean value) {
+        isTransactional = value;
+    }
+
+    /**
+     * This method is called whenever there is a change to table structure and
+     * serves two porposes: (a) to reset the best set of columns that identify
+     * the rows of the table (b) to reset the best index that can be used
+     * to find rows of the table given a column value.
+     *
+     * (a) gives most weight to a primary key index, followed by a unique
+     * address with the lowest count of nullable columns. Otherwise there is
+     * no best row identifier.
+     *
+     * (b) finds for each column an index with a corresponding first column.
+     * It uses any type of visible index and accepts the one with the largest
+     * column count.
+     *
+     * bestIndex is the user defined, primary key, the first unique index, or
+     * the first non-unique index. NULL if there is no user-defined index.
+     *
+     */
+    public final void setBestRowIdentifiers() {
+
+        int[]   briCols      = null;
+        int     briColsCount = 0;
+        boolean isStrict     = false;
+        int     nNullCount   = 0;
+
+        // ignore if called prior to completion of primary key construction
+        if (colNotNull == null) {
+            return;
+        }
+
+        bestIndex          = null;
+        bestIndexForColumn = new int[colTypes.length];
+
+        ArrayUtil.fillArray(bestIndexForColumn, -1);
+
+        for (int i = 0; i < indexList.length; i++) {
+            Index index     = indexList[i];
+            int[] cols      = index.getColumns();
+            int   colsCount = index.getVisibleColumns();
+
+            if (colsCount == 0) {
+                continue;
+            }
+
+            if (i == 0) {
+                isStrict = true;
+            }
+
+            if (bestIndexForColumn[cols[0]] == -1) {
+                bestIndexForColumn[cols[0]] = i;
+            } else {
+                Index existing = indexList[bestIndexForColumn[cols[0]]];
+
+                if (colsCount > existing.getColumns().length) {
+                    bestIndexForColumn[cols[0]] = i;
+                }
+            }
+
+            if (!index.isUnique()) {
+                if (bestIndex == null) {
+                    bestIndex = index;
+                }
+
+                continue;
+            }
+
+            int nnullc = 0;
+
+            for (int j = 0; j < colsCount; j++) {
+                if (colNotNull[cols[j]]) {
+                    nnullc++;
+                }
+            }
+
+            if (bestIndex != null) {
+                bestIndex = index;
+            }
+
+            if (nnullc == colsCount) {
+                if (briCols == null || briColsCount != nNullCount
+                        || colsCount < briColsCount) {
+
+                    //  nothing found before ||
+                    //  found but has null columns ||
+                    //  found but has more columns than this index
+                    briCols      = cols;
+                    briColsCount = colsCount;
+                    nNullCount   = colsCount;
+                    isStrict     = true;
+                }
+
+                continue;
+            } else if (isStrict) {
+                continue;
+            } else if (briCols == null || colsCount < briColsCount
+                       || nnullc > nNullCount) {
+
+                //  nothing found before ||
+                //  found but has more columns than this index||
+                //  found but has fewer not null columns than this index
+                briCols      = cols;
+                briColsCount = colsCount;
+                nNullCount   = nnullc;
+            }
+        }
+
+        if (briCols == null || briColsCount == briCols.length) {
+            bestRowIdentifierCols = briCols;
+        } else {
+            bestRowIdentifierCols = ArrayUtil.arraySlice(briCols, 0,
+                    briColsCount);
+        }
+
+        bestRowIdentifierStrict = isStrict;
+
+        if (indexList[0].getColumnCount() > 0) {
+            bestIndex = indexList[0];
+        }
+    }
+
+    public final void createPrimaryIndex(int[] pkcols, Type[] pktypes,
+                                         HsqlName name) {
+
+        long id = database.persistentStoreCollection.getNextId();
+        Index newIndex = database.logger.newIndex(name, id, this, pkcols,
+            null, null, pktypes, true, pkcols.length > 0, pkcols.length > 0,
+            false);
+
+        try {
+            addIndex(null, newIndex);
+        } catch (HsqlException e) {}
+    }
+
+    public final Index createAndAddIndexStructure(Session session,
+            HsqlName name, int[] columns, boolean[] descending,
+            boolean[] nullsLast, boolean unique, boolean constraint,
+            boolean forward) {
+
+        Index newindex = createIndexStructure(name, columns, descending,
+                                              nullsLast, unique, constraint,
+                                              forward);
+
+        addIndex(session, newindex);
+
+        return newindex;
+    }
+
+    final Index createIndexStructure(HsqlName name, int[] columns,
+                                     boolean[] descending,
+                                     boolean[] nullsLast, boolean unique,
+                                     boolean constraint, boolean forward) {
+
+        if (primaryKeyCols == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "createIndex");
+        }
+
+        int    s     = columns.length;
+        int[]  cols  = new int[s];
+        Type[] types = new Type[s];
+
+        for (int j = 0; j < s; j++) {
+            cols[j]  = columns[j];
+            types[j] = colTypes[cols[j]];
+        }
+
+        long id = database.persistentStoreCollection.getNextId();
+        Index newIndex = database.logger.newIndex(name, id, this, cols,
+            descending, nullsLast, types, false, unique, constraint, forward);
+
+        return newIndex;
+    }
+
+    /**
+     *  Performs Table structure modification and changes to the index nodes
+     *  to remove a given index from a MEMORY or TEXT table. Not for PK index.
+     *
+     */
+    public void dropIndex(int todrop) {
+
+        indexList = (Index[]) ArrayUtil.toAdjustedArray(indexList, null,
+                todrop, -1);
+
+        for (int i = 0; i < indexList.length; i++) {
+            indexList[i].setPosition(i);
+        }
+
+        setBestRowIdentifiers();
+
+        if (store != null) {
+            store.resetAccessorKeys(indexList);
+        }
+    }
+
+    final void addIndex(Session session, Index index) {
+
+        int i = 0;
+
+        for (; i < indexList.length; i++) {
+            Index current = indexList[i];
+            int order = index.getIndexOrderValue()
+                        - current.getIndexOrderValue();
+
+            if (order < 0) {
+                break;
+            }
+        }
+
+        indexList = (Index[]) ArrayUtil.toAdjustedArray(indexList, index, i,
+                1);
+
+        for (i = 0; i < indexList.length; i++) {
+            indexList[i].setPosition(i);
+        }
+
+        if (store != null) {
+            try {
+                store.resetAccessorKeys(indexList);
+            } catch (HsqlException e) {
+                indexList = (Index[]) ArrayUtil.toAdjustedArray(indexList,
+                        null, index.getPosition(), -1);
+
+                for (i = 0; i < indexList.length; i++) {
+                    indexList[i].setPosition(i);
+                }
+
+                throw e;
+            }
+        }
+
+        setBestRowIdentifiers();
+    }
+
+    final void removeIndex(int position) {
+        setBestRowIdentifiers();
+    }
+
+    public final void setIndexes(Index[] indexes) {
+        this.indexList = indexes;
+    }
+
+    public final Object[] getEmptyRowData() {
+        return new Object[getDataColumnCount()];
+    }
+
+    /**
+     *  Create new memory-resident index. For MEMORY and TEXT tables.
+     */
+    public final Index createIndex(Session session, HsqlName name,
+                                   int[] columns, boolean[] descending,
+                                   boolean[] nullsLast, boolean unique,
+                                   boolean constraint, boolean forward) {
+
+        Index newIndex = createAndAddIndexStructure(session, name, columns,
+            descending, nullsLast, unique, constraint, forward);
+
+        return newIndex;
+    }
+
+    public void clearAllData(Session session) {
+
+        PersistentStore store = session.sessionData.getRowStore(this);
+
+        store.removeAll();
+    }
+
+    public void clearAllData(PersistentStore store) {
+        store.removeAll();
+    }
+
+    /**
+     * @todo - this is wrong, as it returns true when table has no rows,
+     * but not where it has rows that are not visible by session
+     *  Returns true if the table has any rows at all.
+     */
+    public final boolean isEmpty(Session session) {
+
+        if (getIndexCount() == 0) {
+            return true;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(this);
+
+        return getIndex(0).isEmpty(store);
+    }
+
+    public int getRowCount(PersistentStore store) {
+        return getPrimaryIndex().size(null, store);
+    }
+
+    public PersistentStore getRowStore(Session session) {
+        return store == null ? session.sessionData.getRowStore(this)
+                             : store;
+    }
+}
diff --git a/src/org/hsqldb/TableDerived.java b/src/org/hsqldb/TableDerived.java
new file mode 100644
index 0000000..f3cb8b1
--- /dev/null
+++ b/src/org/hsqldb/TableDerived.java
@@ -0,0 +1,155 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ * Table with data derived from a query expression.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class TableDerived extends Table {
+
+    QueryExpression queryExpression;
+    View            view;
+    SubQuery        subQuery;
+
+    public TableDerived(Database database, HsqlName name, int type) {
+
+        super(database, name, type);
+
+        switch (type) {
+
+            case TableBase.FUNCTION_TABLE :
+            case TableBase.VIEW_TABLE :
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Table");
+        }
+    }
+
+    public TableDerived(Database database, HsqlName name, int type,
+                        QueryExpression queryExpression, SubQuery subQuery) {
+
+        super(database, name, type);
+
+        switch (type) {
+
+            case TableBase.SYSTEM_SUBQUERY :
+            case TableBase.VIEW_TABLE :
+            case TableBase.RESULT_TABLE :
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Table");
+        }
+
+        this.queryExpression = queryExpression;
+        this.subQuery        = subQuery;
+    }
+
+    public TableDerived(Database database, HsqlName name, int type,
+                        Type[] columnTypes, HashMappedList columnList,
+                        QueryExpression queryExpression, SubQuery subQuery) {
+
+        this(database, name, type, queryExpression, subQuery);
+
+        this.colTypes          = columnTypes;
+        this.columnList        = columnList;
+        columnCount            = columnList.size();
+        primaryKeyCols         = ValuePool.emptyIntArray;
+        primaryKeyTypes        = Type.emptyArray;
+        primaryKeyColsSequence = ValuePool.emptyIntArray;
+        colDefaults            = new Expression[columnCount];
+        colNotNull             = new boolean[columnCount];
+        defaultColumnMap       = new int[columnCount];
+
+        ArrayUtil.fillSequence(defaultColumnMap);
+
+        bestIndexForColumn = new int[colTypes.length];
+
+        ArrayUtil.fillArray(bestIndexForColumn, -1);
+        createPrimaryIndex(primaryKeyCols, primaryKeyTypes, null);
+    }
+
+    public int getId() {
+        return 0;
+    }
+
+    public boolean isWritable() {
+        return true;
+    }
+
+    public boolean isInsertable() {
+        return queryExpression == null ? false
+                                       : queryExpression.isInsertable();
+    }
+
+    public boolean isUpdatable() {
+        return queryExpression == null ? false
+                                       : queryExpression.isUpdatable();
+    }
+
+    public int[] getUpdatableColumns() {
+        return defaultColumnMap;
+    }
+
+    public Table getBaseTable() {
+        return queryExpression == null ? this
+                                       : queryExpression.getBaseTable();
+    }
+
+    public int[] getBaseTableColumnMap() {
+
+        return queryExpression == null ? null
+                                       : queryExpression
+                                           .getBaseTableColumnMap();
+    }
+
+    public SubQuery getSubQuery() {
+        return subQuery;
+    }
+
+    public QueryExpression getQueryExpression() {
+        return queryExpression;
+    }
+}
diff --git a/src/org/hsqldb/TableUtil.java b/src/org/hsqldb/TableUtil.java
new file mode 100644
index 0000000..980f0f6
--- /dev/null
+++ b/src/org/hsqldb/TableUtil.java
@@ -0,0 +1,131 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.types.Type;
+
+/*
+ * Utility functions to set up special tables.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class TableUtil {
+
+    static Table newTable(Database database, int type,
+                          HsqlName tableHsqlName) {
+
+        switch (type) {
+
+            case TableBase.TEMP_TEXT_TABLE :
+            case TableBase.TEXT_TABLE : {
+                return new TextTable(database, tableHsqlName, type);
+            }
+            default : {
+                return new Table(database, tableHsqlName, type);
+            }
+        }
+    }
+
+    static Table newLookupTable(Database database) {
+
+        TableDerived table;
+        HsqlName     name = database.nameManager.getSubqueryTableName();
+
+        table = new TableDerived(database, name, TableBase.SYSTEM_SUBQUERY,
+                                 null, null);
+
+        ColumnSchema column =
+            new ColumnSchema(HsqlNameManager.getAutoColumnName(0),
+                             Type.SQL_INTEGER, false, true, null);
+
+        table.addColumn(column);
+        table.createPrimaryKeyConstraint(table.getName(), new int[]{ 0 },
+                                         true);
+
+        return table;
+    }
+
+    static void setTableIndexesForSubquery(Table table,
+                                           boolean fullIndex,
+                                           boolean uniqueRows) {
+
+        int[] cols = null;
+
+        if (fullIndex) {
+            cols = new int[table.getColumnCount()];
+
+            ArrayUtil.fillSequence(cols);
+        }
+
+        table.createPrimaryKey(null, uniqueRows ? cols
+                                                : null, false);
+
+        if (uniqueRows) {
+            table.fullIndex = table.getPrimaryIndex();
+        } else if (fullIndex) {
+            table.fullIndex = table.createIndexForColumns(null, cols);
+        }
+    }
+
+    public static void addAutoColumns(Table table, Type[] colTypes) {
+
+        for (int i = 0; i < colTypes.length; i++) {
+            ColumnSchema column =
+                new ColumnSchema(HsqlNameManager.getAutoColumnName(i),
+                                 colTypes[i], true, false, null);
+
+            table.addColumnNoCheck(column);
+        }
+    }
+
+    public static void setColumnsInSchemaTable(Table table,
+            HsqlName[] columnNames, Type[] columnTypes) {
+
+        for (int i = 0; i < columnNames.length; i++) {
+            HsqlName columnName = columnNames[i];
+
+            columnName = table.database.nameManager.newColumnSchemaHsqlName(
+                table.getName(), columnName);
+
+            ColumnSchema column = new ColumnSchema(columnName, columnTypes[i],
+                                                   true, false, null);
+
+            table.addColumn(column);
+        }
+
+        table.setColumnStructures();
+    }
+}
diff --git a/src/org/hsqldb/TableWorks.java b/src/org/hsqldb/TableWorks.java
new file mode 100644
index 0000000..f7f9798
--- /dev/null
+++ b/src/org/hsqldb/TableWorks.java
@@ -0,0 +1,1264 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.types.Types;
+
+/**
+ * The methods in this class perform alterations to the structure of an
+ * existing table which may result in a new Table object
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class TableWorks {
+
+    OrderedHashSet   emptySet = new OrderedHashSet();
+    private Database database;
+    private Table    table;
+    private Session  session;
+
+    public TableWorks(Session session, Table table) {
+
+        this.database = table.database;
+        this.table    = table;
+        this.session  = session;
+    }
+
+    public Table getTable() {
+        return table;
+    }
+
+    void checkCreateForeignKey(Constraint c) {
+
+        boolean check =
+            c.core.updateAction == SchemaObject.ReferentialAction
+                .SET_DEFAULT || c.core.updateAction == SchemaObject
+                .ReferentialAction.SET_NULL || c.core
+                .updateAction == SchemaObject.ReferentialAction.CASCADE || c
+                .core.deleteAction == SchemaObject.ReferentialAction
+                .SET_DEFAULT || c.core.deleteAction == SchemaObject
+                .ReferentialAction.SET_NULL;
+
+        if (check) {
+            for (int i = 0; i < c.core.refCols.length; i++) {
+                ColumnSchema col = table.getColumn(c.core.refCols[i]);
+
+                if (col.isGenerated()) {
+                    throw Error.error(ErrorCode.X_42524, col.getNameString());
+                }
+            }
+        }
+
+        if (c.core.mainName == table.getName()) {
+            if (ArrayUtil.haveCommonElement(c.core.refCols, c.core.mainCols)) {
+                throw Error.error(ErrorCode.X_42527);
+            }
+        }
+
+        // column defaults
+        check =
+            c.core.updateAction == SchemaObject.ReferentialAction.SET_DEFAULT
+            || c.core.deleteAction
+               == SchemaObject.ReferentialAction.SET_DEFAULT;
+
+        if (check) {
+            for (int i = 0; i < c.core.refCols.length; i++) {
+                ColumnSchema col     = table.getColumn(c.core.refCols[i]);
+                Expression   defExpr = col.getDefaultExpression();
+
+                if (defExpr == null) {
+                    String columnName = col.getName().statementName;
+
+                    throw Error.error(ErrorCode.X_42521, columnName);
+                }
+            }
+        }
+
+        check = c.core.updateAction == SchemaObject.ReferentialAction.SET_NULL
+                || c.core.deleteAction
+                   == SchemaObject.ReferentialAction.SET_NULL;
+
+        if (check && !session.isProcessingScript) {
+            for (int i = 0; i < c.core.refCols.length; i++) {
+                ColumnSchema col = table.getColumn(c.core.refCols[i]);
+
+                if (!col.isNullable()) {
+                    String columnName = col.getName().statementName;
+
+                    throw Error.error(ErrorCode.X_42520, columnName);
+                }
+            }
+        }
+
+        database.schemaManager.checkSchemaObjectNotExists(c.getName());
+
+        // duplicate name check for a new table
+        if (table.getConstraint(c.getName().name) != null) {
+            throw Error.error(ErrorCode.X_42504, c.getName().statementName);
+        }
+
+        // existing FK check
+        if (table.getFKConstraintForColumns(
+                c.core.mainTable, c.core.mainCols, c.core.refCols) != null) {
+            throw Error.error(ErrorCode.X_42528, c.getName().statementName);
+        }
+
+        if (c.core.mainTable.isTemp() != table.isTemp()) {
+            throw Error.error(ErrorCode.X_42524, c.getName().statementName);
+        }
+
+        if (c.core.mainTable.getUniqueConstraintForColumns(
+                c.core.mainCols, c.core.refCols) == null) {
+            throw Error.error(ErrorCode.X_42529,
+                              c.getMain().getName().statementName);
+        }
+
+        // check after UNIQUE check
+        c.core.mainTable.checkColumnsMatch(c.core.mainCols, table,
+                                           c.core.refCols);
+
+        boolean[] checkList =
+            c.core.mainTable.getColumnCheckList(c.core.mainCols);
+
+//        Grantee   grantee   = table.getOwner();
+        Grantee grantee = session.getGrantee();
+
+        grantee.checkReferences(c.core.mainTable, checkList);
+    }
+
+    /**
+     * Creates a foreign key on an existing table. Foreign keys are enforced by
+     * indexes on both the referencing (child) and referenced (main) tables.
+     *
+     * <p> Since version 1.7.2, a unique constraint on the referenced columns
+     * must exist. The non-unique index on the referencing table is now always
+     * created whether or not a PK or unique constraint index on the columns
+     * exist. Foriegn keys on temp tables can reference other temp tables with
+     * the same rules above. Foreign keys on permanent tables cannot reference
+     * temp tables. Duplicate foreign keys are now disallowed.
+     *
+     * @param c the constraint object
+     */
+    void addForeignKey(Constraint c) {
+
+        checkModifyTable();
+        checkCreateForeignKey(c);
+
+        Constraint uniqueConstraint =
+            c.core.mainTable.getUniqueConstraintForColumns(c.core.mainCols,
+                c.core.refCols);
+        Index mainIndex = uniqueConstraint.getMainIndex();
+
+        uniqueConstraint.checkReferencedRows(session, table);
+
+        boolean isForward = false;
+
+        if (c.core.mainTable.getSchemaName() == table.getSchemaName()) {
+            int offset = database.schemaManager.getTableIndex(table);
+
+            if (offset != -1
+                    && offset
+                       < database.schemaManager.getTableIndex(
+                           c.core.mainTable)) {
+                isForward = true;
+            }
+        } else {
+            isForward = true;
+        }
+
+        HsqlName indexName = database.nameManager.newAutoName("IDX",
+            table.getSchemaName(), table.getName(), SchemaObject.INDEX);
+        Index refIndex = table.createIndexStructure(indexName, c.core.refCols,
+            null, null, false, true, isForward);
+        HsqlName mainName = database.nameManager.newAutoName("REF",
+            c.getName().name, table.getSchemaName(), table.getName(),
+            SchemaObject.INDEX);
+
+        c.core.uniqueName = uniqueConstraint.getName();
+        c.core.mainName   = mainName;
+        c.core.mainIndex  = mainIndex;
+        c.core.refTable   = table;
+        c.core.refName    = c.getName();
+        c.core.refIndex   = refIndex;
+        c.isForward       = isForward;
+
+        Table tn = table.moveDefinition(session, table.tableType, null, c,
+                                        refIndex, -1, 0, emptySet, emptySet);
+
+        moveData(table, tn, -1, 0);
+        database.schemaManager.addSchemaObject(c);
+        setNewTableInSchema(tn);
+
+        Table mainTable = database.schemaManager.getTable(session,
+            c.core.mainTable.getName().name,
+            c.core.mainTable.getSchemaName().name);
+
+        mainTable.addConstraint(new Constraint(mainName, c));
+        updateConstraints(tn, emptySet);
+        database.schemaManager.recompileDependentObjects(tn);
+
+        table = tn;
+    }
+
+    /**
+     * Checks if the attributes of the Column argument, c, are compatible with
+     * the operation of adding such a Column to the Table argument, table.
+     *
+     * @param col the Column to add to the Table, t
+     */
+    void checkAddColumn(ColumnSchema col) {
+
+        checkModifyTable();
+
+        if (table.isText() && !table.isEmpty(session)) {
+            throw Error.error(ErrorCode.X_S0521);
+        }
+
+        if (table.findColumn(col.getName().name) != -1) {
+            throw Error.error(ErrorCode.X_42504);
+        }
+
+        if (col.isPrimaryKey() && table.hasPrimaryKey()) {
+            throw Error.error(ErrorCode.X_42530);
+        }
+
+        if (col.isIdentity() && table.hasIdentityColumn()) {
+            throw Error.error(ErrorCode.X_42525);
+        }
+
+        if (!table.isEmpty(session) && !col.hasDefault()
+                && (!col.isNullable() || col.isPrimaryKey())
+                && !col.isIdentity()) {
+            throw Error.error(ErrorCode.X_42531);
+        }
+    }
+
+    void addColumn(ColumnSchema column, int colIndex,
+                   HsqlArrayList constraints) {
+
+        Index      index          = null;
+        Table      originalTable  = table;
+        Constraint mainConstraint = null;
+        boolean    addFK          = false;
+        boolean    addUnique      = false;
+        boolean    addCheck       = false;
+
+        checkAddColumn(column);
+
+        Constraint c = (Constraint) constraints.get(0);
+
+        if (c.getConstraintType()
+                == SchemaObject.ConstraintTypes.PRIMARY_KEY) {
+            if (column.getDataType().isLobType()) {
+                throw Error.error(ErrorCode.X_42534);
+            }
+
+            c.core.mainCols = new int[]{ colIndex };
+
+            database.schemaManager.checkSchemaObjectNotExists(c.getName());
+
+            if (table.hasPrimaryKey()) {
+                throw Error.error(ErrorCode.X_42530);
+            }
+
+            addUnique = true;
+        } else {
+            c = null;
+        }
+
+        table = table.moveDefinition(session, table.tableType, column, c,
+                                     null, colIndex, 1, emptySet, emptySet);
+
+        for (int i = 1; i < constraints.size(); i++) {
+            c = (Constraint) constraints.get(i);
+
+            switch (c.constType) {
+
+                case SchemaObject.ConstraintTypes.UNIQUE : {
+                    if (addUnique) {
+                        throw Error.error(ErrorCode.X_42522);
+                    }
+
+                    if (column.getDataType().isLobType()) {
+                        throw Error.error(ErrorCode.X_42534);
+                    }
+
+                    addUnique       = true;
+                    c.core.mainCols = new int[]{ colIndex };
+
+                    database.schemaManager.checkSchemaObjectNotExists(
+                        c.getName());
+
+                    HsqlName indexName =
+                        database.nameManager.newAutoName("IDX",
+                                                         c.getName().name,
+                                                         table.getSchemaName(),
+                                                         table.getName(),
+                                                         SchemaObject.INDEX);
+
+                    // create an autonamed index
+                    index = table.createAndAddIndexStructure(session,
+                            indexName, c.getMainColumns(), null, null, true,
+                            true, false);
+                    c.core.mainTable = table;
+                    c.core.mainIndex = index;
+
+                    table.addConstraint(c);
+
+                    break;
+                }
+                case SchemaObject.ConstraintTypes.FOREIGN_KEY : {
+                    if (addFK) {
+                        throw Error.error(ErrorCode.X_42528);
+                    }
+
+                    addFK          = true;
+                    c.core.refCols = new int[]{ colIndex };
+
+                    boolean isSelf = originalTable == c.core.mainTable;
+
+                    if (isSelf) {
+                        c.core.mainTable = table;
+                    }
+
+                    c.setColumnsIndexes(table);
+                    checkCreateForeignKey(c);
+
+                    Constraint uniqueConstraint =
+                        c.core.mainTable.getUniqueConstraintForColumns(
+                            c.core.mainCols, c.core.refCols);
+                    boolean isForward = c.core.mainTable.getSchemaName()
+                                        != table.getSchemaName();
+                    int offset =
+                        database.schemaManager.getTableIndex(originalTable);
+
+                    if (!isSelf
+                            && offset
+                               < database.schemaManager.getTableIndex(
+                                   c.core.mainTable)) {
+                        isForward = true;
+                    }
+
+                    HsqlName indexName =
+                        database.nameManager.newAutoName("IDX",
+                                                         c.getName().name,
+                                                         table.getSchemaName(),
+                                                         table.getName(),
+                                                         SchemaObject.INDEX);
+
+                    index = table.createAndAddIndexStructure(session,
+                            indexName, c.getRefColumns(), null, null, false,
+                            true, isForward);
+                    c.core.uniqueName = uniqueConstraint.getName();
+                    c.core.mainName = database.nameManager.newAutoName("REF",
+                            c.core.refName.name, table.getSchemaName(),
+                            table.getName(), SchemaObject.INDEX);
+                    c.core.mainIndex = uniqueConstraint.getMainIndex();
+                    c.core.refIndex  = index;
+                    c.isForward      = isForward;
+
+                    table.addConstraint(c);
+
+                    mainConstraint = new Constraint(c.core.mainName, c);
+
+                    break;
+                }
+                case SchemaObject.ConstraintTypes.CHECK :
+                    if (addCheck) {
+                        throw Error.error(ErrorCode.X_42528);
+                    }
+
+                    addCheck = true;
+
+                    c.prepareCheckConstraint(session, table, false);
+                    table.addConstraint(c);
+
+                    if (c.isNotNull()) {
+                        column.setNullable(false);
+                        table.setColumnTypeVars(colIndex);
+                    }
+                    break;
+            }
+        }
+
+        column.compile(session, table);
+        moveData(originalTable, table, colIndex, 1);
+
+        if (mainConstraint != null) {
+            mainConstraint.getMain().addConstraint(mainConstraint);
+        }
+
+        registerConstraintNames(constraints);
+        setNewTableInSchema(table);
+        updateConstraints(table, emptySet);
+        database.schemaManager.addSchemaObject(column);
+        database.schemaManager.recompileDependentObjects(table);
+        table.compile(session, null);
+    }
+
+    void updateConstraints(OrderedHashSet tableSet,
+                           OrderedHashSet dropConstraints) {
+
+        for (int i = 0; i < tableSet.size(); i++) {
+            Table t = (Table) tableSet.get(i);
+
+            updateConstraints(t, dropConstraints);
+        }
+    }
+
+    void updateConstraints(Table t, OrderedHashSet dropConstraints) {
+
+        for (int i = t.constraintList.length - 1; i >= 0; i--) {
+            Constraint c = t.constraintList[i];
+
+            if (dropConstraints.contains(c.getName())) {
+                t.removeConstraint(i);
+
+                continue;
+            }
+
+            if (c.getConstraintType()
+                    == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+                Table mainT = database.schemaManager.getUserTable(session,
+                    c.core.mainTable.getName());
+                Constraint mainC = mainT.getConstraint(c.getMainName().name);
+
+                mainC.core = c.core;
+            } else if (c.getConstraintType()
+                       == SchemaObject.ConstraintTypes.MAIN) {
+                Table refT = database.schemaManager.getUserTable(session,
+                    c.core.refTable.getName());
+                Constraint refC = refT.getConstraint(c.getRefName().name);
+
+                refC.core = c.core;
+            }
+        }
+    }
+
+    OrderedHashSet makeNewTables(OrderedHashSet tableSet,
+                                 OrderedHashSet dropConstraintSet,
+                                 OrderedHashSet dropIndexSet) {
+
+        OrderedHashSet newSet = new OrderedHashSet();
+
+        for (int i = 0; i < tableSet.size(); i++) {
+            Table      t  = (Table) tableSet.get(i);
+            TableWorks tw = new TableWorks(session, t);
+
+            tw.makeNewTable(dropConstraintSet, dropIndexSet);
+            newSet.add(tw.getTable());
+        }
+
+        return newSet;
+    }
+
+    /**
+     * Drops constriants and their indexes in table. Uses set of names.
+     */
+    void makeNewTable(OrderedHashSet dropConstraintSet,
+                      OrderedHashSet dropIndexSet) {
+
+        Table tn = table.moveDefinition(session, table.tableType, null, null,
+                                        null, -1, 0, dropConstraintSet,
+                                        dropIndexSet);
+
+        if (tn.indexList.length == table.indexList.length) {
+            database.persistentStoreCollection.releaseStore(tn);
+
+            return;
+        }
+
+        moveData(table, tn, -1, 0);
+
+        table = tn;
+    }
+
+    /**
+     * Because of the way indexes and column data are held in memory and on
+     * disk, it is necessary to recreate the table when an index is added to a
+     * non-empty cached table.
+     *
+     * <p> With empty tables, Index objects are simply added
+     *
+     * <p> With MEOMRY and TEXT tables, a new index is built up and nodes for
+     * earch row are interlinked (fredt@users)
+     *
+     * @param col int[]
+     * @param name HsqlName
+     * @param unique boolean
+     * @return new index
+     */
+    Index addIndex(int[] col, HsqlName name, boolean unique) {
+
+        Index newindex;
+
+        checkModifyTable();
+
+        if (table.isEmpty(session) || table.isIndexingMutable()) {
+            newindex = table.createIndex(session, name, col, null, null,
+                                         unique, false, false);
+        } else {
+            newindex = table.createIndexStructure(name, col, null, null,
+                                                  unique, false, false);
+
+            Table tn = table.moveDefinition(session, table.tableType, null,
+                                            null, newindex, -1, 0, emptySet,
+                                            emptySet);
+
+            // for all sessions move the data
+            moveData(table, tn, -1, 0);
+
+            table = tn;
+
+            setNewTableInSchema(table);
+            updateConstraints(table, emptySet);
+        }
+
+        database.schemaManager.addSchemaObject(newindex);
+        database.schemaManager.recompileDependentObjects(table);
+
+        return newindex;
+    }
+
+    void addPrimaryKey(Constraint constraint, HsqlName name) {
+
+        checkModifyTable();
+
+        if (table.hasPrimaryKey()) {
+            throw Error.error(ErrorCode.X_42532);
+        }
+
+        database.schemaManager.checkSchemaObjectNotExists(name);
+
+        Table tn = table.moveDefinition(session, table.tableType, null,
+                                        constraint, null, -1, 0, emptySet,
+                                        emptySet);
+
+        moveData(table, tn, -1, 0);
+
+        table = tn;
+
+        database.schemaManager.addSchemaObject(constraint);
+        setNewTableInSchema(table);
+        updateConstraints(table, emptySet);
+        database.schemaManager.recompileDependentObjects(table);
+    }
+
+    /**
+     * A unique constraint relies on a unique indexe on the table. It can cover
+     * a single column or multiple columns.
+     *
+     * <p> All unique constraint names are generated by Database.java as unique
+     * within the database. Duplicate constraints (more than one unique
+     * constriant on the same set of columns) are not allowed. (fredt@users)
+     *
+     * @param cols int[]
+     * @param name HsqlName
+     */
+    void addUniqueConstraint(int[] cols, HsqlName name) {
+
+        checkModifyTable();
+        database.schemaManager.checkSchemaObjectNotExists(name);
+
+        if (table.getUniqueConstraintForColumns(cols) != null) {
+            throw Error.error(ErrorCode.X_42522);
+        }
+
+        // create an autonamed index
+        HsqlName indexname = database.nameManager.newAutoName("IDX",
+            name.name, table.getSchemaName(), table.getName(),
+            SchemaObject.INDEX);
+        Index index = table.createIndexStructure(indexname, cols, null, null,
+            true, true, false);
+        Constraint constraint =
+            new Constraint(name, table, index,
+                           SchemaObject.ConstraintTypes.UNIQUE);
+        Table tn = table.moveDefinition(session, table.tableType, null,
+                                        constraint, index, -1, 0, emptySet,
+                                        emptySet);
+
+        moveData(table, tn, -1, 0);
+
+        table = tn;
+
+        database.schemaManager.addSchemaObject(constraint);
+        setNewTableInSchema(table);
+        updateConstraints(table, emptySet);
+        database.schemaManager.recompileDependentObjects(table);
+    }
+
+    void addCheckConstraint(Constraint c) {
+
+        database.schemaManager.checkSchemaObjectNotExists(c.getName());
+        c.prepareCheckConstraint(session, table, true);
+        table.addConstraint(c);
+
+        if (c.isNotNull()) {
+            ColumnSchema column = table.getColumn(c.notNullColumnIndex);
+
+            column.setNullable(false);
+            table.setColumnTypeVars(c.notNullColumnIndex);
+        }
+
+        database.schemaManager.addSchemaObject(c);
+    }
+
+    /**
+     * Because of the way indexes and column data are held in memory and on
+     * disk, it is necessary to recreate the table when an index is added to or
+     * removed from a non-empty table.
+     *
+     * <p> Originally, this method would break existing foreign keys as the
+     * table order in the DB was changed. The new table is now linked in place
+     * of the old table (fredt@users)
+     *
+     * @param indexName String
+     */
+    void dropIndex(String indexName) {
+
+        Index index;
+
+        checkModifyTable();
+
+        index = table.getIndex(indexName);
+
+        if (table.isIndexingMutable()) {
+            table.dropIndex(index.getPosition());
+        } else {
+            OrderedHashSet indexSet = new OrderedHashSet();
+
+            indexSet.add(table.getIndex(indexName).getName());
+
+            Table tn = table.moveDefinition(session, table.tableType, null,
+                                            null, null, -1, 0, emptySet,
+                                            indexSet);
+
+            moveData(table, tn, -1, 0);
+            updateConstraints(tn, emptySet);
+            setNewTableInSchema(tn);
+
+            table = tn;
+        }
+
+        if (!index.isConstraint()) {
+            database.schemaManager.removeSchemaObject(index.getName());
+        }
+
+        database.schemaManager.recompileDependentObjects(table);
+    }
+
+    void dropColumn(int colIndex, boolean cascade) {
+
+        OrderedHashSet constraintNameSet = new OrderedHashSet();
+        OrderedHashSet dependentConstraints =
+            table.getDependentConstraints(colIndex);
+        OrderedHashSet cascadingConstraints =
+            table.getContainingConstraints(colIndex);
+        OrderedHashSet indexNameSet = table.getContainingIndexNames(colIndex);
+        ColumnSchema   column       = table.getColumn(colIndex);
+        HsqlName       columnName   = column.getName();
+        OrderedHashSet referencingObjects =
+            database.schemaManager.getReferencingObjectNames(table.getName(),
+                columnName);
+
+        checkModifyTable();
+
+        if (!cascade) {
+            if (!cascadingConstraints.isEmpty()) {
+                Constraint c    = (Constraint) cascadingConstraints.get(0);
+                HsqlName   name = c.getName();
+
+                throw Error.error(ErrorCode.X_42536,
+                                  name.getSchemaQualifiedStatementName());
+            }
+
+            if (!referencingObjects.isEmpty()) {
+                mainLoop:
+                for (int i = 0; i < referencingObjects.size(); i++) {
+                    HsqlName name = (HsqlName) referencingObjects.get(i);
+
+                    if (name == columnName) {
+                        continue;
+                    }
+
+                    for (int j = 0; j < dependentConstraints.size(); j++) {
+                        Constraint c =
+                            (Constraint) dependentConstraints.get(j);;
+
+                        if (c.getName() == name) {
+                            continue mainLoop;
+                        }
+                    }
+
+                    throw Error.error(ErrorCode.X_42536,
+                                      name.getSchemaQualifiedStatementName());
+                }
+            }
+        }
+
+        dependentConstraints.addAll(cascadingConstraints);
+        cascadingConstraints.clear();
+
+        OrderedHashSet tableSet = new OrderedHashSet();
+
+        for (int i = 0; i < dependentConstraints.size(); i++) {
+            Constraint c = (Constraint) dependentConstraints.get(i);
+
+            if (c.constType == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+                tableSet.add(c.getMain());
+                constraintNameSet.add(c.getMainName());
+                constraintNameSet.add(c.getRefName());
+                indexNameSet.add(c.getRefIndex().getName());
+            }
+
+            if (c.constType == SchemaObject.ConstraintTypes.MAIN) {
+                tableSet.add(c.getRef());
+                constraintNameSet.add(c.getMainName());
+                constraintNameSet.add(c.getRefName());
+                indexNameSet.add(c.getRefIndex().getName());
+            }
+
+            constraintNameSet.add(c.getName());
+        }
+
+        tableSet = makeNewTables(tableSet, constraintNameSet, indexNameSet);
+
+        Table tn = table.moveDefinition(session, table.tableType, null, null,
+                                        null, colIndex, -1, constraintNameSet,
+                                        indexNameSet);
+
+        moveData(table, tn, colIndex, -1);
+        database.schemaManager.removeSchemaObjects(referencingObjects);
+        database.schemaManager.removeSchemaObjects(constraintNameSet);
+        database.schemaManager.removeSchemaObject(columnName);
+        setNewTableInSchema(tn);
+        setNewTablesInSchema(tableSet);
+        updateConstraints(tn, emptySet);
+        updateConstraints(tableSet, constraintNameSet);
+        database.schemaManager.recompileDependentObjects(tableSet);
+        database.schemaManager.recompileDependentObjects(tn);
+        tn.compile(session, null);
+
+        if (column.getDataType().isLobType()) {
+            RowIterator it = table.rowIterator(session);
+
+            while (it.hasNext()) {
+                Row      row  = it.getNextRow();
+                Object[] data = row.getData();
+
+                if (data[colIndex] != null) {
+                    session.sessionData.adjustLobUsageCount(data[colIndex],
+                            -1);
+                }
+            }
+        }
+
+        table = tn;
+    }
+
+    void registerConstraintNames(HsqlArrayList constraints) {
+
+        for (int i = 0; i < constraints.size(); i++) {
+            Constraint c = (Constraint) constraints.get(i);
+
+            switch (c.constType) {
+
+                case SchemaObject.ConstraintTypes.PRIMARY_KEY :
+                case SchemaObject.ConstraintTypes.UNIQUE :
+                case SchemaObject.ConstraintTypes.CHECK :
+                    database.schemaManager.addSchemaObject(c);
+            }
+        }
+    }
+
+    void dropConstraint(String name, boolean cascade) {
+
+        Constraint constraint = table.getConstraint(name);
+
+        if (constraint == null) {
+            throw Error.error(ErrorCode.X_42501, name);
+        }
+
+        switch (constraint.getConstraintType()) {
+
+            case SchemaObject.ConstraintTypes.MAIN :
+                throw Error.error(ErrorCode.X_28502);
+            case SchemaObject.ConstraintTypes.PRIMARY_KEY :
+            case SchemaObject.ConstraintTypes.UNIQUE : {
+                checkModifyTable();
+
+                OrderedHashSet dependentConstraints =
+                    table.getDependentConstraints(constraint);
+
+                // throw if unique constraint is referenced by foreign key
+                if (!cascade && !dependentConstraints.isEmpty()) {
+                    Constraint c = (Constraint) dependentConstraints.get(0);
+
+                    throw Error.error(
+                        ErrorCode.X_42533,
+                        c.getName().getSchemaQualifiedStatementName());
+                }
+
+                OrderedHashSet tableSet          = new OrderedHashSet();
+                OrderedHashSet constraintNameSet = new OrderedHashSet();
+                OrderedHashSet indexNameSet      = new OrderedHashSet();
+
+                for (int i = 0; i < dependentConstraints.size(); i++) {
+                    Constraint c = (Constraint) dependentConstraints.get(i);
+                    Table      t = c.getMain();
+
+                    if (t != table) {
+                        tableSet.add(t);
+                    }
+
+                    t = c.getRef();
+
+                    if (t != table) {
+                        tableSet.add(t);
+                    }
+
+                    constraintNameSet.add(c.getMainName());
+                    constraintNameSet.add(c.getRefName());
+                    indexNameSet.add(c.getRefIndex().getName());
+                }
+
+                constraintNameSet.add(constraint.getName());
+
+                if (constraint.getConstraintType()
+                        == SchemaObject.ConstraintTypes.UNIQUE) {
+                    indexNameSet.add(constraint.getMainIndex().getName());
+                }
+
+                Table tn = table.moveDefinition(session, table.tableType,
+                                                null, null, null, -1, 0,
+                                                constraintNameSet,
+                                                indexNameSet);
+
+                moveData(table, tn, -1, 0);
+
+                tableSet = makeNewTables(tableSet, constraintNameSet,
+                                         indexNameSet);
+
+                if (constraint.getConstraintType()
+                        == SchemaObject.ConstraintTypes.PRIMARY_KEY) {
+                    int[] cols = constraint.getMainColumns();
+
+                    for (int i = 0; i < cols.length; i++) {
+
+                        // todo - check if table arrays relect the not-null correctly
+                        tn.getColumn(cols[i]).setPrimaryKey(false);
+                        tn.setColumnTypeVars(cols[i]);
+                    }
+                }
+
+                //
+                database.schemaManager.removeSchemaObjects(constraintNameSet);
+                setNewTableInSchema(tn);
+                setNewTablesInSchema(tableSet);
+                updateConstraints(tn, emptySet);
+                updateConstraints(tableSet, constraintNameSet);
+                database.schemaManager.recompileDependentObjects(tableSet);
+                database.schemaManager.recompileDependentObjects(tn);
+
+                table = tn;
+
+                // handle cascadingConstraints and cascadingTables
+                break;
+            }
+            case SchemaObject.ConstraintTypes.FOREIGN_KEY : {
+                checkModifyTable();
+
+                OrderedHashSet constraints = new OrderedHashSet();
+                Table          mainTable   = constraint.getMain();
+                HsqlName       mainName    = constraint.getMainName();
+
+                constraints.add(mainName);
+                constraints.add(constraint.getRefName());
+
+                OrderedHashSet indexes = new OrderedHashSet();
+
+                indexes.add(constraint.getRefIndex().getName());
+
+                Table tn = table.moveDefinition(session, table.tableType,
+                                                null, null, null, -1, 0,
+                                                constraints, indexes);
+
+                moveData(table, tn, -1, 0);
+
+                //
+                database.schemaManager.removeSchemaObject(
+                    constraint.getName());
+                setNewTableInSchema(tn);
+
+                // if constraint references same table, nothing changes
+                mainTable.removeConstraint(mainName.name);
+                updateConstraints(tn, emptySet);
+                database.schemaManager.recompileDependentObjects(table);
+
+                table = tn;
+
+                break;
+            }
+            case SchemaObject.ConstraintTypes.CHECK :
+                database.schemaManager.removeSchemaObject(
+                    constraint.getName());
+
+                if (constraint.isNotNull()) {
+                    ColumnSchema column =
+                        table.getColumn(constraint.notNullColumnIndex);
+
+                    column.setNullable(false);
+                    table.setColumnTypeVars(constraint.notNullColumnIndex);
+                }
+                break;
+        }
+    }
+
+    /**
+     * Allows changing the type or addition of an IDENTITY sequence.
+     *
+     * @param oldCol Column
+     * @param newCol Column
+     */
+    void retypeColumn(ColumnSchema oldCol, ColumnSchema newCol) {
+
+        boolean allowed = true;
+        int     oldType = oldCol.getDataType().typeCode;
+        int     newType = newCol.getDataType().typeCode;
+
+        checkModifyTable();
+
+        if (!table.isEmpty(session) && oldType != newType) {
+            allowed =
+                newCol.getDataType().canConvertFrom(oldCol.getDataType());
+
+            switch (oldType) {
+
+                case Types.OTHER :
+                case Types.JAVA_OBJECT :
+                    allowed = false;
+                    break;
+            }
+        }
+
+        if (!allowed) {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        int colIndex = table.getColumnIndex(oldCol.getName().name);
+
+        // if there is a multi-column PK, do not change the PK attributes
+        if (newCol.isIdentity() && table.hasIdentityColumn()
+                && table.identityColumn != colIndex) {
+            throw Error.error(ErrorCode.X_42525);
+        }
+
+        if (table.getPrimaryKey().length > 1) {
+            newCol.setPrimaryKey(oldCol.isPrimaryKey());
+
+            if (ArrayUtil.find(table.getPrimaryKey(), colIndex) != -1) {}
+        } else if (table.hasPrimaryKey()) {
+            if (oldCol.isPrimaryKey()) {
+                newCol.setPrimaryKey(true);
+            } else if (newCol.isPrimaryKey()) {
+                throw Error.error(ErrorCode.X_42532);
+            }
+        } else if (newCol.isPrimaryKey()) {
+            throw Error.error(ErrorCode.X_42530);
+        }
+
+        // apply and return if only metadata change is required
+        boolean meta = newType == oldType;
+
+        meta &= oldCol.isNullable() == newCol.isNullable();
+        meta &= oldCol.getDataType().scale == newCol.getDataType().scale;
+        meta &= (oldCol.isIdentity() == newCol.isIdentity());
+        meta &=
+            (oldCol.getDataType().precision == newCol.getDataType().precision
+             || (oldCol.getDataType().precision
+                 < newCol.getDataType().precision && (oldType
+                     == Types.SQL_VARCHAR || oldType == Types.SQL_VARBINARY)));
+
+        if (meta) {
+
+            // size of some types may be increased with this command
+            // default expressions can change
+            oldCol.setType(newCol);
+            oldCol.setDefaultExpression(newCol.getDefaultExpression());
+
+            if (newCol.isIdentity()) {
+                oldCol.setIdentity(newCol.getIdentitySequence());
+            }
+
+            table.setColumnTypeVars(colIndex);
+            table.resetDefaultsFlag();
+
+            return;
+        }
+
+        database.schemaManager.checkColumnIsReferenced(table.getName(),
+                table.getColumn(colIndex).getName());
+        table.checkColumnInCheckConstraint(colIndex);
+        table.checkColumnInFKConstraint(colIndex);
+        checkConvertColDataType(oldCol, newCol);
+        retypeColumn(newCol, colIndex);
+    }
+
+    /**
+     *
+     * @param oldCol Column
+     * @param newCol Column
+     */
+    void checkConvertColDataType(ColumnSchema oldCol, ColumnSchema newCol) {
+
+        int         colIndex = table.getColumnIndex(oldCol.getName().name);
+        RowIterator it       = table.rowIterator(session);
+
+        while (it.hasNext()) {
+            Row    row = it.getNextRow();
+            Object o   = row.getData()[colIndex];
+
+            newCol.getDataType().convertToType(session, o,
+                                               oldCol.getDataType());
+        }
+    }
+
+    /**
+     *
+     * @param column Column
+     * @param colIndex int
+     */
+    private void retypeColumn(ColumnSchema column, int colIndex) {
+
+        Table tn = table.moveDefinition(session, table.tableType, column,
+                                        null, null, colIndex, 0, emptySet,
+                                        emptySet);
+
+        moveData(table, tn, colIndex, 0);
+        updateConstraints(tn, emptySet);
+        setNewTableInSchema(tn);
+        database.schemaManager.recompileDependentObjects(table);
+
+        table = tn;
+    }
+
+    /**
+     * performs the work for changing the nullability of a column
+     *
+     * @param column Column
+     * @param nullable boolean
+     */
+    void setColNullability(ColumnSchema column, boolean nullable) {
+
+        Constraint c        = null;
+        int        colIndex = table.getColumnIndex(column.getName().name);
+
+        if (column.isNullable() == nullable) {
+            return;
+        }
+
+        if (nullable) {
+            if (column.isPrimaryKey()) {
+                throw Error.error(ErrorCode.X_42526);
+            }
+
+            table.checkColumnInFKConstraint(
+                colIndex, SchemaObject.ReferentialAction.SET_NULL);
+            removeColumnNotNullConstraints(colIndex);
+        } else {
+            HsqlName constName = database.nameManager.newAutoName("CT",
+                table.getSchemaName(), table.getName(),
+                SchemaObject.CONSTRAINT);
+
+            c = new Constraint(constName, null,
+                               SchemaObject.ConstraintTypes.CHECK);
+            c.check = new ExpressionLogical(column);
+
+            c.prepareCheckConstraint(session, table, true);
+            column.setNullable(false);
+            table.addConstraint(c);
+            table.setColumnTypeVars(colIndex);
+            database.schemaManager.addSchemaObject(c);
+        }
+    }
+
+    /**
+     * performs the work for changing the default value of a column
+     *
+     * @param colIndex int
+     * @param def Expression
+     */
+    void setColDefaultExpression(int colIndex, Expression def) {
+
+        if (def == null) {
+            table.checkColumnInFKConstraint(
+                colIndex, SchemaObject.ReferentialAction.SET_DEFAULT);
+        }
+
+        table.setDefaultExpression(colIndex, def);
+    }
+
+    /**
+     * Changes the type of a table
+     *
+     * @param session Session
+     * @param newType int
+     * @return boolean
+     */
+    public boolean setTableType(Session session, int newType) {
+
+        int currentType = table.getTableType();
+
+        if (currentType == newType) {
+            return false;
+        }
+
+        switch (newType) {
+
+            case TableBase.CACHED_TABLE :
+                break;
+
+            case TableBase.MEMORY_TABLE :
+                break;
+
+            default :
+                return false;
+        }
+
+        Table tn;
+
+        try {
+            tn = table.moveDefinition(session, newType, null, null, null, -1,
+                                      0, emptySet, emptySet);
+
+            moveData(table, tn, -1, 0);
+            updateConstraints(tn, emptySet);
+        } catch (HsqlException e) {
+            return false;
+        }
+
+        setNewTableInSchema(tn);
+
+        table = tn;
+
+        database.schemaManager.recompileDependentObjects(table);
+
+        return true;
+    }
+
+    void setNewTablesInSchema(OrderedHashSet tableSet) {
+
+        for (int i = 0; i < tableSet.size(); i++) {
+            Table t = (Table) tableSet.get(i);
+
+            setNewTableInSchema(t);
+        }
+    }
+
+    void setNewTableInSchema(Table newTable) {
+
+        int i = database.schemaManager.getTableIndex(newTable);
+
+        if (i != -1) {
+            database.schemaManager.setTable(i, newTable);
+        }
+    }
+
+    void removeColumnNotNullConstraints(int colIndex) {
+
+        for (int i = table.constraintList.length - 1; i >= 0; i--) {
+            Constraint c = table.constraintList[i];
+
+            if (c.isNotNull()) {
+                if (c.notNullColumnIndex == colIndex) {
+                    database.schemaManager.removeSchemaObject(c.getName());
+                }
+            }
+        }
+
+        ColumnSchema column = table.getColumn(colIndex);
+
+        column.setNullable(true);
+        table.setColumnTypeVars(colIndex);
+    }
+
+    private void checkModifyTable() {
+
+        if (session.getUser().isSystem()) {
+            return;
+        }
+
+        if (session.isProcessingScript) {
+            return;
+        }
+
+        if (database.isFilesReadOnly() || table.isReadOnly()) {
+            throw Error.error(ErrorCode.DATA_IS_READONLY);
+        }
+
+        if (table.isText() && table.isConnected()) {
+            throw Error.error(ErrorCode.X_S0521);
+        }
+    }
+
+    void moveData(Table oldTable, Table newTable, int colIndex, int adjust) {
+
+        if (oldTable.getTableType() == Table.TEMP_TABLE) {
+            Session sessions[] = database.sessionManager.getAllSessions();
+
+            for (int i = 0; i < sessions.length; i++) {
+                sessions[i].sessionData.persistentStoreCollection.moveData(
+                    oldTable, newTable, colIndex, adjust);
+            }
+        } else {
+            PersistentStore oldStore =
+                database.persistentStoreCollection.getStore(oldTable);
+            PersistentStore newStore =
+                database.persistentStoreCollection.getStore(newTable);
+
+            newStore.moveData(session, oldStore, colIndex, adjust);
+            database.persistentStoreCollection.releaseStore(oldTable);
+        }
+    }
+}
diff --git a/src/org/hsqldb/TextTable.java b/src/org/hsqldb/TextTable.java
new file mode 100644
index 0000000..cafae1c
--- /dev/null
+++ b/src/org/hsqldb/TextTable.java
@@ -0,0 +1,408 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.persist.DataFileCache;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.persist.TextCache;
+import org.hsqldb.navigator.RowIterator;
+
+// tony_lai@users 20020820 - patch 595099 - user define PK name
+
+/**
+ * Subclass of Table to handle TEXT data source. <p>
+ *
+ * Extends Table to provide the notion of an SQL base table object whose
+ * data is read from and written to a text format data file.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.9.0
+ */
+public class TextTable extends org.hsqldb.Table {
+
+    String  dataSource  = "";
+    boolean isReversed  = false;
+    boolean isConnected = false;
+
+//    TextCache cache;
+
+    /**
+     * Constructs a new TextTable from the given arguments.
+     *
+     * @param db the owning database
+     * @param name the table's HsqlName
+     * @param type code (normal or temp text table)
+     */
+    TextTable(Database db, HsqlNameManager.HsqlName name, int type) {
+        super(db, name, type);
+    }
+
+    public boolean isConnected() {
+        return isConnected;
+    }
+
+    /**
+     * connects to the data source
+     */
+    public void connect(Session session) {
+        connect(session, isReadOnly);
+    }
+
+    /**
+     * connects to the data source
+     */
+    private void connect(Session session, boolean withReadOnlyData) {
+
+        // Open new cache:
+        if ((dataSource.length() == 0) || isConnected) {
+
+            // nothing to do
+            return;
+        }
+
+        PersistentStore store =
+            database.persistentStoreCollection.getStore(this);
+
+        this.store = store;
+
+        DataFileCache cache = null;
+
+        try {
+            cache = (TextCache) database.logger.openTextFilePersistence(this,
+                    dataSource, withReadOnlyData, isReversed);
+
+            store.setCache(cache);
+
+            // read and insert all the rows from the source file
+            Row row     = null;
+            int nextpos = 0;
+
+            if (((TextCache) cache).ignoreFirst) {
+                nextpos += ((TextCache) cache).readHeaderLine();
+            }
+
+            while (true) {
+                row = (Row) store.get(nextpos, false);
+
+                if (row == null) {
+                    break;
+                }
+
+                Object[] data = row.getData();
+
+                nextpos = row.getPos() + row.getStorageSize();
+
+                systemUpdateIdentityValue(data);
+                enforceRowConstraints(session, data);
+
+                for (int i = 0; i < indexList.length; i++) {
+                    indexList[i].insert(null, store, row);
+                }
+            }
+        } catch (Throwable t) {
+            int linenumber = cache == null ? 0
+                                           : ((TextCache) cache)
+                                               .getLineNumber();
+
+            clearAllData(session);
+
+            if (cache != null) {
+                database.logger.closeTextCache(this);
+                store.release();
+            }
+
+            // everything is in order here.
+            // At this point table should either have a valid (old) data
+            // source and cache or have an empty source and null cache.
+            throw Error.error(t, ErrorCode.TEXT_FILE, 0, new Object[] {
+                t.getMessage(), new Integer(linenumber)
+            });
+        }
+
+        isConnected = true;
+        isReadOnly  = withReadOnlyData;
+    }
+
+    /**
+     * disconnects from the data source
+     */
+    public void disconnect() {
+
+        this.store = null;
+
+        PersistentStore store =
+            database.persistentStoreCollection.getStore(this);
+
+        store.release();
+
+        isConnected = false;
+    }
+
+    /**
+     * This method does some of the work involved with managing the creation
+     * and openning of the cache, the rest is done in Log.java and
+     * TextCache.java.
+     *
+     * Better clarification of the role of the methods is needed.
+     */
+    private void openCache(Session session, String dataSourceNew,
+                           boolean isReversedNew, boolean isReadOnlyNew) {
+
+        String  dataSourceOld = dataSource;
+        boolean isReversedOld = isReversed;
+        boolean isReadOnlyOld = isReadOnly;
+
+        if (dataSourceNew == null) {
+            dataSourceNew = "";
+        }
+
+        disconnect();
+
+        dataSource = dataSourceNew;
+        isReversed = (isReversedNew && dataSource.length() > 0);
+
+        try {
+            connect(session, isReadOnlyNew);
+        } catch (HsqlException e) {
+            dataSource = dataSourceOld;
+            isReversed = isReversedOld;
+
+            connect(session, isReadOnlyOld);
+
+            throw e;
+        }
+    }
+
+    /**
+     * High level command to assign a data source to the table definition.
+     * Reassigns only if the data source or direction has changed.
+     */
+    protected void setDataSource(Session session, String dataSourceNew,
+                                 boolean isReversedNew, boolean createFile) {
+
+        if (getTableType() == Table.TEMP_TEXT_TABLE) {
+            ;
+        } else {
+            session.getGrantee().checkSchemaUpdateOrGrantRights(
+                getSchemaName().name);
+        }
+
+        dataSourceNew = dataSourceNew.trim();
+
+        if (createFile && FileUtil.getFileUtil().exists(dataSourceNew)) {
+            throw Error.error(ErrorCode.TEXT_SOURCE_EXISTS, dataSourceNew);
+        }
+
+        //-- Open if descending, direction changed, file changed, or not connected currently
+        if (isReversedNew || (isReversedNew != isReversed)
+                || !dataSource.equals(dataSourceNew) || !isConnected) {
+            openCache(session, dataSourceNew, isReversedNew, isReadOnly);
+        }
+
+        if (isReversed) {
+            isReadOnly = true;
+        }
+    }
+
+    public String getDataSource() {
+        return dataSource;
+    }
+
+    public boolean isDescDataSource() {
+        return isReversed;
+    }
+
+    public void setHeader(String header) {
+
+        PersistentStore store =
+            database.persistentStoreCollection.getStore(this);
+        TextCache cache = (TextCache) store.getCache();
+
+        if (cache != null && cache.ignoreFirst) {
+            cache.setHeader(header);
+
+            return;
+        }
+
+        throw Error.error(ErrorCode.TEXT_TABLE_HEADER);
+    }
+
+    public String getHeader() {
+
+        PersistentStore store =
+            database.persistentStoreCollection.getStore(this);
+        TextCache cache  = (TextCache) store.getCache();
+        String    header = cache == null ? null
+                                         : cache.getHeader();
+
+        return header == null ? null
+                              : StringConverter.toQuotedString(header, '\'',
+                              true);
+    }
+
+    /**
+     * Used by INSERT, DELETE, UPDATE operations. This class will return
+     * a more appropriate message when there is no data source.
+     */
+    void checkDataReadOnly() {
+
+        if (dataSource.length() == 0) {
+            throw Error.error(ErrorCode.TEXT_TABLE_UNKNOWN_DATA_SOURCE);
+        }
+
+        if (isReadOnly) {
+            throw Error.error(ErrorCode.DATA_IS_READONLY);
+        }
+    }
+
+    public boolean isDataReadOnly() {
+        return !isConnected() || super.isDataReadOnly()
+               || store.getCache().isDataReadOnly();
+    }
+
+    public void setDataReadOnly(boolean value) {
+
+        if (!value) {
+            if (isReversed) {
+                throw Error.error(ErrorCode.DATA_IS_READONLY);
+            }
+
+            if (database.isFilesReadOnly()) {
+                throw Error.error(ErrorCode.DATABASE_IS_READONLY);
+            }
+
+            if (isConnected()) {
+                store.getCache().close(true);
+                store.getCache().open(value);
+            }
+        }
+
+        isReadOnly = value;
+    }
+
+    boolean isIndexCached() {
+        return false;
+    }
+
+    void setIndexRoots(String s) {
+
+        // do nothing
+    }
+
+    String getDataSourceDDL() {
+
+        String dataSource = getDataSource();
+
+        if (dataSource == null) {
+            return null;
+        }
+
+        boolean      isDesc = isDescDataSource();
+        StringBuffer sb     = new StringBuffer(128);
+
+        sb.append(Tokens.T_SET).append(' ').append(Tokens.T_TABLE).append(' ');
+        sb.append(getName().getSchemaQualifiedStatementName());
+        sb.append(' ').append(Tokens.T_SOURCE).append(' ').append('\'');
+        sb.append(dataSource);
+        sb.append('\'');
+
+        if (isDesc) {
+            sb.append(' ').append(Tokens.T_DESC);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Generates the SET TABLE <tablename> SOURCE HEADER <string> statement for a
+     * text table;
+     */
+    String getDataSourceHeader() {
+
+        String header = getHeader();
+
+        if (header == null) {
+            return null;
+        }
+
+        StringBuffer sb = new StringBuffer(128);
+
+        sb.append(Tokens.T_SET).append(' ').append(Tokens.T_TABLE).append(' ');
+        sb.append(getName().getSchemaQualifiedStatementName());
+        sb.append(' ').append(Tokens.T_SOURCE).append(' ');
+        sb.append(Tokens.T_HEADER).append(' ');
+        sb.append(header);
+
+        return sb.toString();
+    }
+
+    void moveData(Session session, Table from, int colindex, int adjust) {
+
+        PersistentStore store = session.sessionData.getRowStore(this);
+
+        store.setCache(from.store.getCache());
+
+        RowIterator it = from.rowIterator(session);
+
+        try {
+            while (it.hasNext()) {
+                Row row = it.getNextRow();
+
+                store.indexRow(session, row);
+            }
+        } catch (Throwable t) {
+            store.release();
+
+            if (t instanceof HsqlException) {
+                throw (HsqlException) t;
+            }
+
+            throw new HsqlException(t, "", 0);
+        }
+    }
+
+    /**
+     * Adds commitPersistence() call
+     */
+    public void insertData(Session session, PersistentStore store,
+                           Object[] data) {
+
+        Row row = (Row) store.getNewCachedObject(null, data);
+
+        store.indexRow(null, row);
+        store.commitPersistence(row);
+    }
+}
diff --git a/src/org/hsqldb/Token.java b/src/org/hsqldb/Token.java
new file mode 100644
index 0000000..452c40d
--- /dev/null
+++ b/src/org/hsqldb/Token.java
@@ -0,0 +1,290 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.types.Type;
+
+public class Token {
+
+    String  tokenString = "";
+    int     tokenType   = Tokens.X_UNKNOWN_TOKEN;
+    Type    dataType;
+    Object  tokenValue;
+    String  namePrefix;
+    String  namePrePrefix;
+    String  namePrePrePrefix;
+    String  charsetSchema;
+    String  charsetName;
+    String  fullString;
+    int     lobMultiplierType = Tokens.X_UNKNOWN_TOKEN;
+    boolean isDelimiter;
+    boolean isDelimitedIdentifier;
+    boolean isDelimitedPrefix;
+    boolean isDelimitedPrePrefix;
+    boolean isDelimitedPrePrePrefix;
+    boolean isUndelimitedIdentifier;
+    boolean isReservedIdentifier;
+    boolean isCoreReservedIdentifier;
+    boolean isHostParameter;
+    boolean isMalformed;
+
+    //
+    int    position;
+    Object expression;
+
+    void reset() {
+
+        tokenString              = "";
+        tokenType                = Tokens.X_UNKNOWN_TOKEN;
+        dataType                 = null;
+        tokenValue               = null;
+        namePrefix               = null;
+        namePrePrefix            = null;
+        namePrePrePrefix         = null;
+        charsetSchema            = null;
+        charsetName              = null;
+        fullString               = null;
+        expression               = null;
+        lobMultiplierType        = Tokens.X_UNKNOWN_TOKEN;
+        isDelimiter              = false;
+        isDelimitedIdentifier    = false;
+        isDelimitedPrefix        = false;
+        isDelimitedPrePrefix     = false;
+        isDelimitedPrePrePrefix  = false;
+        isUndelimitedIdentifier  = false;
+        isReservedIdentifier     = false;
+        isCoreReservedIdentifier = false;
+        isHostParameter          = false;
+        isMalformed              = false;
+    }
+
+    Token duplicate() {
+
+        Token token = new Token();
+
+        token.tokenString              = tokenString;
+        token.tokenType                = tokenType;
+        token.dataType                 = dataType;
+        token.tokenValue               = tokenValue;
+        token.namePrefix               = namePrefix;
+        token.namePrePrefix            = namePrePrefix;
+        token.namePrePrePrefix         = namePrePrePrefix;
+        token.charsetSchema            = charsetSchema;
+        token.charsetName              = charsetName;
+        token.fullString               = fullString;
+        token.lobMultiplierType        = lobMultiplierType;
+        token.isDelimiter              = isDelimiter;
+        token.isDelimitedIdentifier    = isDelimitedIdentifier;
+        token.isDelimitedPrefix        = isDelimitedPrefix;
+        token.isDelimitedPrePrefix     = isDelimitedPrePrefix;
+        token.isDelimitedPrePrePrefix  = isDelimitedPrePrePrefix;
+        token.isUndelimitedIdentifier  = isUndelimitedIdentifier;
+        token.isReservedIdentifier     = isReservedIdentifier;
+        token.isCoreReservedIdentifier = isCoreReservedIdentifier;
+        token.isHostParameter          = isHostParameter;
+        token.isMalformed              = isMalformed;
+
+        return token;
+    }
+
+    public String getFullString() {
+        return fullString;
+    }
+
+    public void setExpression(Object expression) {
+        this.expression = expression;
+    }
+
+    String getSQL() {
+
+        if (expression instanceof ExpressionColumn) {
+            if (tokenType == Tokens.ASTERISK) {
+                StringBuffer sb         = new StringBuffer();
+                Expression   expression = (Expression) this.expression;
+
+                if (expression != null
+                        && expression.opType == OpTypes.MULTICOLUMN
+                        && expression.nodes.length > 0) {
+                    sb.append(' ');
+
+                    for (int i = 0; i < expression.nodes.length; i++) {
+                        Expression   e = expression.nodes[i];
+                        ColumnSchema c = e.getColumn();
+                        String       name;
+
+                        if (e.opType == OpTypes.COALESCE) {
+                            if (i > 0) {
+                                sb.append(',');
+                            }
+
+                            sb.append(e.getColumnName());
+
+                            continue;
+                        }
+
+                        if (e.getRangeVariable().tableAlias == null) {
+                            name = c.getName()
+                                .getSchemaQualifiedStatementName();
+                        } else {
+                            RangeVariable range = e.getRangeVariable();
+
+                            name = range.tableAlias.getStatementName() + '.'
+                                   + c.getName().statementName;
+                        }
+
+                        if (i > 0) {
+                            sb.append(',');
+                        }
+
+                        sb.append(name);
+                    }
+
+                    sb.append(' ');
+                } else {
+                    return tokenString;
+                }
+
+                return sb.toString();
+            }
+        } else if (expression instanceof Type) {
+            isDelimiter = false;
+
+            Type type = (Type) expression;
+
+            if (type.isDistinctType() || type.isDomainType()) {
+                return type.getName().getSchemaQualifiedStatementName();
+            }
+
+            return type.getNameString();
+        } else if (expression instanceof SchemaObject) {
+            isDelimiter = false;
+
+            return ((SchemaObject) expression).getName()
+                .getSchemaQualifiedStatementName();
+        }
+
+        if (namePrefix == null && isUndelimitedIdentifier) {
+            return tokenString;
+        }
+
+        if (tokenType == Tokens.X_VALUE) {
+            return dataType.convertToSQLString(tokenValue);
+        }
+
+        StringBuffer sb = new StringBuffer();
+
+        if (namePrePrefix != null) {
+            if (isDelimitedPrePrefix) {
+                sb.append('"');
+                sb.append(namePrePrefix);
+                sb.append('"');
+            } else {
+                sb.append(namePrePrefix);
+
+                isDelimiter = false;
+            }
+
+            sb.append('.');
+        }
+
+        if (namePrefix != null) {
+            if (isDelimitedPrefix) {
+                sb.append('"');
+                sb.append(namePrefix);
+                sb.append('"');
+            } else {
+                sb.append(namePrefix);
+
+                isDelimiter = false;
+            }
+
+            sb.append('.');
+        }
+
+        if (isDelimitedIdentifier) {
+            sb.append('"');
+            sb.append(tokenString);
+            sb.append('"');
+            sb.append(' ');
+        } else {
+            sb.append(tokenString);
+        }
+
+        return sb.toString();
+    }
+
+/*
+    for (int i = 0; i < tokens.length; i++) {
+        if (tokens[i].schemaObjectIdentifier instanceof Expression) {
+            ColumnSchema column =
+                ((Expression) tokens[i].schemaObjectIdentifier)
+                    .getColumn();
+
+            tokens[i].schemaObjectIdentifier = column.getName();
+        }
+    }
+*/
+    static String getSQL(Token[] statement) {
+
+        boolean      wasDelimiter = true;
+        StringBuffer sb           = new StringBuffer();
+
+        for (int i = 0; i < statement.length; i++) {
+            String sql = statement[i].getSQL();
+
+            if (!statement[i].isDelimiter && !wasDelimiter) {
+                sb.append(' ');
+            }
+
+            sb.append(sql);
+
+            wasDelimiter = statement[i].isDelimiter;
+        }
+
+        return sb.toString();
+    }
+
+    static Object[] getSimplifiedTokens(Token[] tokens) {
+
+        Object[] array = new Object[tokens.length];
+
+        for (int i = 0; i < tokens.length; i++) {
+            if (tokens[i].expression == null) {
+                array[i] = tokens[i].getSQL();
+            } else {
+                array[i] = tokens[i].expression;
+            }
+        }
+
+        return array;
+    }
+}
diff --git a/src/org/hsqldb/Tokens.java b/src/org/hsqldb/Tokens.java
new file mode 100644
index 0000000..3c0365e
--- /dev/null
+++ b/src/org/hsqldb/Tokens.java
@@ -0,0 +1,2302 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.OrderedIntHashSet;
+
+/**
+ * Defines and enumerates reserved and non-reserved SQL keywords.<p>
+ *
+ * @author  Nitin Chauhan (initial work)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class Tokens {
+
+    //
+    // SQL 200n reserved words full set
+    static final String        T_ABS              = "ABS";
+    public static final String T_ALL              = "ALL";
+    static final String        T_ALLOCATE         = "ALLOCATE";
+    public static final String T_ALTER            = "ALTER";
+    static final String        T_AND              = "AND";
+    static final String        T_ANY              = "ANY";
+    static final String        T_ARE              = "ARE";
+    public static final String T_ARRAY            = "ARRAY";
+    public static final String T_AS               = "AS";
+    static final String        T_ASENSITIVE       = "ASENSITIVE";
+    static final String        T_ASYMMETRIC       = "ASYMMETRIC";
+    static final String        T_AT               = "AT";
+    static final String        T_ATOMIC           = "ATOMIC";
+    public static final String T_AUTHORIZATION    = "AUTHORIZATION";
+    static final String        T_AVG              = "AVG";
+    static final String        T_BEGIN            = "BEGIN";
+    static final String        T_BETWEEN          = "BETWEEN";
+    public static final String T_BIGINT           = "BIGINT";
+    public static final String T_BINARY           = "BINARY";
+    static final String        T_BIT_LENGTH       = "BIT_LENGTH";
+    public static final String T_BLOB             = "BLOB";
+    public static final String T_BOOLEAN          = "BOOLEAN";
+    static final String        T_BOTH             = "BOTH";
+    static final String        T_BY               = "BY";
+    public static final String T_CALL             = "CALL";
+    static final String        T_CALLED           = "CALLED";
+    static final String        T_CARDINALITY      = "CARDINALITY";
+    public static final String T_CASCADED         = "CASCADED";
+    static final String        T_CASE             = "CASE";
+    static final String        T_CAST             = "CAST";
+    static final String        T_CEIL             = "CEIL";
+    static final String        T_CEILING          = "CEILING";
+    static final String        T_CHAR             = "CHAR";
+    static final String        T_CHAR_LENGTH      = "CHAR_LENGTH";
+    public static final String T_CHARACTER        = "CHARACTER";
+    static final String        T_CHARACTER_LENGTH = "CHARACTER_LENGTH";
+    public static final String T_CHECK            = "CHECK";
+    public static final String T_CLOB             = "CLOB";
+    static final String        T_CLOSE            = "CLOSE";
+    static final String        T_COALESCE         = "COALESCE";
+    static final String        T_COLLATE          = "COLLATE";
+    static final String        T_COLLECT          = "COLLECT";
+    static final String        T_COLUMN           = "COLUMN";
+    public static final String T_COMMIT           = "COMMIT";
+    static final String        T_CONDITION        = "CONDIITON";
+    public static final String T_CONNECT          = "CONNECT";
+    public static final String T_CONSTRAINT       = "CONSTRAINT";
+    static final String        T_CONVERT          = "CONVERT";
+    static final String        T_CORR             = "CORR";
+    static final String        T_CORRESPONDING    = "CORRESPONDING";
+    static final String        T_COUNT            = "COUNT";
+    static final String        T_COVAR_POP        = "COVAR_POP";
+    static final String        T_COVAR_SAMP       = "COVAR_SAMP";
+    public static final String T_CREATE           = "CREATE";
+    static final String        T_CROSS            = "CROSS";
+    static final String        T_CUBE             = "CUBE";
+    static final String        T_CUME_DIST        = "CUME_DIST";
+    static final String        T_CURRENT          = "CURRENT";
+    static final String        T_CURRENT_CATALOG  = "CURRENT_CATALOG";
+    static final String        T_CURRENT_DATE     = "CURRENT_DATE";
+    static final String T_CURRENT_DEFAULT_TRANSFORM_GROUP =
+        "CURRENT_DEFAULT_TRANSFORM_GROUP";
+    static final String T_CURRENT_PATH      = "CURRENT_PATH";
+    static final String T_CURRENT_ROLE      = "CURRENT_ROLE";
+    static final String T_CURRENT_SCHEMA    = "CURRENT_SCHEMA";
+    static final String T_CURRENT_TIME      = "CURRENT_TIME";
+    static final String T_CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP";
+    static final String T_CURRENT_TRANSFORM_GROUP_FOR_TYPE =
+        "CURRENT_TRANSFORM_GROUP_FOR_TYPE";
+    static final String        T_CURRENT_USER      = "CURRENT_USER";
+    static final String        T_CURSOR            = "CURSOR";
+    static final String        T_CYCLE             = "CYCLE";
+    public static final String T_DATE              = "DATE";
+    public static final String T_DAY               = "DAY";
+    static final String        T_DEALLOCATE        = "DEALLOCATE";
+    static final String        T_DEC               = "DEC";
+    public static final String T_DECIMAL           = "DECIMAL";
+    static final String        T_DECLARE           = "DECLARE";
+    public static final String T_DEFAULT           = "DEFAULT";
+    public static final String T_DELETE            = "DELETE";
+    static final String        T_DENSE_RANK        = "DENSE_RANK";
+    static final String        T_DEREF             = "DEREF";
+    static final String        T_DESCRIBE          = "DESCRIBE";
+    static final String        T_DETERMINISTIC     = "DETERMINISTIC";
+    static final String        T_DISCONNECT        = "DISCONNECT";
+    static final String        T_DISTINCT          = "DISTINCT";
+    public static final String T_DO                = "DO";
+    public static final String T_DOUBLE            = "DOUBLE";
+    static final String        T_DROP              = "DROP";
+    static final String        T_DYNAMIC           = "DYNAMIC";
+    static final String        T_EACH              = "EACH";
+    static final String        T_ELEMENT           = "ELEMENT";
+    static final String        T_ELSE              = "ELSE";
+    static final String        T_ELSEIF            = "ELSEIF";
+    static final String        T_END               = "END";
+    static final String        T_END_EXEC          = "END_EXEC";
+    static final String        T_ESCAPE            = "ESCAPE";
+    static final String        T_EVERY             = "EVERY";
+    static final String        T_EXCEPT            = "EXCEPT";
+    static final String        T_EXEC              = "EXEC";
+    public static final String T_EXECUTE           = "EXECUTE";
+    static final String        T_EXISTS            = "EXISTS";
+    static final String        T_EXP               = "EXP";
+    static final String        T_EXTERNAL          = "EXTERNAL";
+    static final String        T_EXTRACT           = "EXTRACT";
+    public static final String T_FALSE             = "FALSE";
+    static final String        T_FETCH             = "FETCH";
+    static final String        T_FILTER            = "FILTER";
+    static final String        T_FIRST_VALUE       = "FIRST_VALUE";
+    public static final String T_FLOAT             = "FLOAT";
+    static final String        T_FLOOR             = "FLOOR";
+    static final String        T_FOR               = "FOR";
+    public static final String T_FOREIGN           = "FOREIGN";
+    static final String        T_FREE              = "FREE";
+    static final String        T_FROM              = "FROM";
+    static final String        T_FULL              = "FULL";
+    public static final String T_FUNCTION          = "FUNCTION";
+    static final String        T_FUSION            = "FUSION";
+    public static final String T_GET               = "GET";
+    static final String        T_GLOBAL            = "GLOBAL";
+    public static final String T_GRANT             = "GRANT";
+    static final String        T_GROUP             = "GROUP";
+    static final String        T_GROUPING          = "GROUPING";
+    static final String        T_HANDLER           = "HANDLER";
+    static final String        T_HAVING            = "HAVING";
+    static final String        T_HOLD              = "HOLD";
+    public static final String T_HOUR              = "HOUR";
+    static final String        T_IDENTITY          = "IDENTITY";
+    static final String        T_IF                = "IF";
+    static final String        T_IMPORT            = "IMPORT";
+    static final String        T_IN                = "IN";
+    static final String        T_INDICATOR         = "INDICATOR";
+    static final String        T_INNER             = "INNER";
+    static final String        T_INOUT             = "INOUT";
+    static final String        T_INSENSITIVE       = "INSENSITIVE";
+    public static final String T_INSERT            = "INSERT";
+    static final String        T_INT               = "INT";
+    public static final String T_INTEGER           = "INTEGER";
+    static final String        T_INTERSECT         = "INTERSECT";
+    static final String        T_INTERSECTION      = "INTERSECTION";
+    public static final String T_INTERVAL          = "INTERVAL";
+    static final String        T_INTO              = "INTO";
+    static final String        T_ITERATE           = "ITERATE";
+    static final String        T_IS                = "IS";
+    static final String        T_JAR               = "JAR";              // SQL/JRT
+    static final String        T_JOIN              = "JOIN";
+    static final String        T_LAG               = "LAG";
+    public static final String T_LANGUAGE          = "LANGUAGE";
+    static final String        T_LARGE             = "LARGE";
+    static final String        T_LAST_VALUE        = "LAST_VALUE";
+    static final String        T_LATERAL           = "LATERAL";
+    static final String        T_LEAD              = "LEAD";
+    static final String        T_LEADING           = "LEADING";
+    static final String        T_LEAVE             = "LEAVE";
+    static final String        T_LEFT              = "LEFT";
+    static final String        T_LIKE              = "LIKE";
+    static final String        T_LIKE_REGX         = "LIKE_REGX";
+    static final String        T_LN                = "LN";
+    public static final String T_LOCAL             = "LOCAL";
+    static final String        T_LOCALTIME         = "LOCALTIME";
+    static final String        T_LOCALTIMESTAMP    = "LOCALTIMESTAMP";
+    public static final String T_LOOP              = "LOOP";
+    static final String        T_LOWER             = "LOWER";
+    static final String        T_MATCH             = "MATCH";
+    static final String        T_MAX               = "MAX";
+    static final String        T_MAX_CARDINALITY   = "MAX_CARDINALITY";
+    static final String        T_MEMBER            = "MEMBER";
+    static final String        T_MERGE             = "MERGE";
+    static final String        T_METHOD            = "METHOD";
+    static final String        T_MIN               = "MIN";
+    public static final String T_MINUTE            = "MINUTE";
+    static final String        T_MOD               = "MOD";
+    static final String        T_MODIFIES          = "MODIFIES";
+    static final String        T_MODULE            = "MODULE";
+    public static final String T_MONTH             = "MONTH";
+    public static final String T_MULTISET          = "MULTISET";
+    static final String        T_NATIONAL          = "NATIONAL";
+    static final String        T_NATURAL           = "NATURAL";
+    static final String        T_NCHAR             = "NCHAR";
+    static final String        T_NCLOB             = "NCLOB";
+    static final String        T_NEW               = "NEW";
+    public static final String T_NO                = "NO";
+    public static final String T_NONE              = "NONE";
+    static final String        T_NORMALIZE         = "NORMALIZE";
+    static final String        T_NOT               = "NOT";
+    static final String        T_NTH_VALUE         = "NTH_VALUE";
+    static final String        T_NTILE             = "NTILE";
+    public static final String T_NULL              = "NULL";
+    public static final String T_NULLIF            = "NULLIF";
+    public static final String T_NUMERIC           = "NUMERIC";
+    static final String        T_OCCURRENCES_REGEX = "OCCURRENCES_REGEX";
+    static final String        T_OCTET_LENGTH      = "OCTET_LENGTH";
+    static final String        T_OF                = "OF";
+    static final String        T_OFFSET            = "OFFSET";
+    static final String        T_OLD               = "OLD";
+    public static final String T_ON                = "ON";
+    public static final String T_ONLY              = "ONLY";
+    static final String        T_OPEN              = "OPEN";
+    static final String        T_OR                = "OR";
+    static final String        T_ORDER             = "ORDER";
+    static final String        T_OUT               = "OUT";
+    static final String        T_OUTER             = "OUTER";
+    static final String        T_OVER              = "OVER";
+    static final String        T_OVERLAPS          = "OVERLAPS";
+    static final String        T_OVERLAY           = "OVERLAY";
+    static final String        T_PARAMETER         = "PARAMETER";
+    static final String        T_PARTITION         = "PARTITION";
+    static final String        T_PERCENT_RANK      = "PERCENT_RANK";
+    static final String        T_PERCENTILE_CONT   = "PERCENTILE_CONT";
+    static final String        T_PERCENTILE_DISC   = "PERCENTILE_DISC";
+    static final String        T_POSITION          = "POSITION";
+    static final String        T_POSITION_REGEX    = "POSITION_REGEX";
+    static final String        T_POWER             = "POWER";
+    static final String        T_PRECISION         = "PRECISION";
+    static final String        T_PREPARE           = "PREPARE";
+    static final String        T_PRIMARY           = "PRIMARY";
+    public static final String T_PROCEDURE         = "PROCEDURE";
+    static final String        T_RANGE             = "RANGE";
+    static final String        T_RANK              = "RANK";
+    static final String        T_READS             = "READS";
+    public static final String T_REAL              = "REAL";
+    static final String        T_RECURSIVE         = "RECURSIVE";
+    static final String        T_REF               = "REF";
+    public static final String T_REFERENCES        = "REFERENCES";
+    static final String        T_REFERENCING       = "REFERENCING";
+    static final String        T_REGR_AVGX         = "REGR_AVGX";
+    static final String        T_REGR_AVGY         = "REGR_AVGY";
+    static final String        T_REGR_COUNT        = "REGR_COUNT";
+    static final String        T_REGR_INTERCEPT    = "REGR_INTERCEPT";
+    static final String        T_REGR_R2           = "REGR_R2";
+    static final String        T_REGR_SLOPE        = "REGR_SLOPE";
+    static final String        T_REGR_SXX          = "REGR_SXX";
+    static final String        T_REGR_SXY          = "REGR_SXY";
+    static final String        T_REGR_SYY          = "REGR_SYY";
+    static final String        T_RELEASE           = "RELEASE";
+    static final String        T_REPEAT            = "REPEAT";
+    static final String        T_RESIGNAL          = "RESIGNAL";
+    public static final String T_RESULT            = "RESULT";
+    static final String        T_RETURN            = "RETURN";
+    static final String        T_RETURNS           = "RETURNS";
+    static final String        T_REVOKE            = "REVOKE";
+    static final String        T_RIGHT             = "RIGHT";
+    static final String        T_ROLLBACK          = "ROLLBACK";
+    static final String        T_ROLLUP            = "ROLLUP";
+    public static final String T_ROW               = "ROW";
+    static final String        T_ROW_NUMBER        = "ROW_NUMBER";
+    public static final String T_ROWS              = "ROWS";
+    static final String        T_SAVEPOINT         = "SAVEPOINT";
+    static final String        T_SCOPE             = "SCOPE";
+    static final String        T_SCROLL            = "SCROLL";
+    static final String        T_SEARCH            = "SEARCH";
+    public static final String T_SECOND            = "SECOND";
+    public static final String T_SELECT            = "SELECT";
+    static final String        T_SENSITIVE         = "SENSITIVE";
+    static final String        T_SESSION_USER      = "SESSION_USER";
+    public static final String T_SET               = "SET";
+    static final String        T_SIGNAL            = "SIGNAL";
+    static final String        T_SIMILAR           = "SIMILAR";
+    public static final String T_SMALLINT          = "SMALLINT";
+    static final String        T_SOME              = "SOME";
+    public static final String T_SPECIFIC          = "SPECIFIC";
+    static final String        T_SPECIFICTYPE      = "SPECIFICTYPE";
+    public static final String T_SQL               = "SQL";
+    static final String        T_SQLEXCEPTION      = "SQLEXCEPTION";
+    static final String        T_SQLSTATE          = "SQLSTATE";
+    static final String        T_SQLWARNING        = "SQLWARNING";
+    static final String        T_SQRT              = "SQRT";
+    static final String        T_START             = "START";
+    static final String        T_STATIC            = "STATIC";
+    static final String        T_STDDEV_POP        = "STDDEV_POP";
+    static final String        T_STDDEV_SAMP       = "STDDEV_SAMP";
+    static final String        T_SUBMULTISET       = "SUBMULTISET";
+    static final String        T_SUBSTRING         = "SUBSTRING";
+    static final String        T_SUBSTRING_REGEX   = "SUBSTRING_REGEX";
+    static final String        T_SUM               = "SUM";
+    static final String        T_SYMMETRIC         = "SYMMETRIC";
+    static final String        T_SYSTEM            = "SYSTEM";
+    static final String        T_SYSTEM_USER       = "SYSTEM_USER";
+    public static final String T_TABLE             = "TABLE";
+    static final String        T_TABLESAMPLE       = "TABLESAMPLE";
+    static final String        T_THEN              = "THEN";
+    public static final String T_TIME              = "TIME";
+    public static final String T_TIMESTAMP         = "TIMESTAMP";
+    public static final String T_TIMEZONE_HOUR     = "TIMEZONE_HOUR";
+    public static final String T_TIMEZONE_MINUTE   = "TIMEZONE_MINUTE";
+    public static final String T_TO                = "TO";
+    static final String        T_TRAILING          = "TRAILING";
+    static final String        T_TRANSLATE         = "TRANSLATE";
+    static final String        T_TRANSLATE_REGEX   = "TRANSLATE_REGEX";
+    static final String        T_TRANSLATION       = "TRANSLATION";
+    static final String        T_TREAT             = "TREAT";
+    public static final String T_TRIGGER           = "TRIGGER";
+    static final String        T_TRIM              = "TRIM";
+    static final String        T_TRIM_ARRAY        = "TRIM_ARRAY";
+    public static final String T_TRUE              = "TRUE";
+    static final String        T_TRUNCATE          = "TRUNCATE";
+    static final String        T_UESCAPE           = "UESCAPE";
+    static final String        T_UNION             = "UNION";
+    public static final String T_UNIQUE            = "UNIQUE";
+    public static final String T_UNKNOWN           = "UNKNOWN";
+    static final String        T_UNNEST            = "UNNEST";
+    static final String        T_UNTIL             = "UNTIL";
+    public static final String T_UPDATE            = "UPDATE";
+    static final String        T_UPPER             = "UPPER";
+    public static final String T_USER              = "USER";
+    static final String        T_USING             = "USING";
+    static final String        T_VALUE             = "VALUE";
+    static final String        T_VALUES            = "VALUES";
+    static final String        T_VAR_POP           = "VAR_POP";
+    static final String        T_VAR_SAMP          = "VAR_SAMP";
+    public static final String T_VARBINARY         = "VARBINARY";
+    public static final String T_VARCHAR           = "VARCHAR";
+    static final String        T_VARYING           = "VARYING";
+    static final String        T_WHEN              = "WHEN";
+    static final String        T_WHENEVER          = "WHENEVER";
+    static final String        T_WHERE             = "WHERE";
+    public static final String T_WHILE             = "WHILE";
+    static final String        T_WIDTH_BUCKET      = "WIDTH_BUCKET";
+    static final String        T_WINDOW            = "WINDOW";
+    public static final String T_WITH              = "WITH";
+    static final String        T_WITHIN            = "WITHIN";
+    static final String        T_WITHOUT           = "WITHOUT";
+    public static final String T_YEAR              = "YEAR";
+
+    // ops
+    static final String        T_ASTERISK       = "*";
+    public static final String T_COMMA          = ",";
+    static final String        T_CIRCUMFLEX     = "^";
+    static final String        T_CLOSEBRACKET   = ")";
+    static final String        T_COLON          = ":";
+    static final String        T_CONCAT         = "||";
+    public static final String T_DIVIDE         = "/";
+    static final String        T_EQUALS         = "=";
+    static final String        T_GREATER        = ">";
+    static final String        T_GREATER_EQUALS = ">=";
+    public static final String T_LEFTBRACKET    = "[";
+    static final String        T_LESS           = "<";
+    static final String        T_LESS_EQUALS    = "<=";
+    static final String        T_PERCENT        = "%";
+    static final String        T_PLUS           = "+";
+    static final String        T_MINUS          = "-";
+    static final String        T_NOT_EQUALS     = "<>";
+    static final String        T_NOT_EQUALS_ALT = "!=";
+    static final String        T_OPENBRACKET    = "(";
+    static final String        T_QUESTION       = "?";
+    public static final String T_RIGHTBRACKET   = "]";
+    static final String        T_SEMICOLON      = ";";
+    static final String        T_DOUBLE_COLON   = "::";
+
+    // SQL:200n non-reserved word list
+    static final String        T_A                    = "A";
+    static final String        T_ABSOLUTE             = "ABSOLUTE";
+    static final String        T_ACTION               = "ACTION";
+    static final String        T_ADA                  = "ADA";
+    static final String        T_ADMIN                = "ADMIN";
+    static final String        T_AFTER                = "AFTER";
+    static final String        T_ALWAYS               = "ALWAYS";
+    static final String        T_ASC                  = "ASC";
+    static final String        T_ASSERTION            = "ASSERTION";
+    static final String        T_ASSIGNMENT           = "ASSIGNMENT";
+    static final String        T_ATTRIBUTE            = "ATTRIBUTE";
+    static final String        T_ATTRIBUTES           = "ATTRIBUTES";
+    static final String        T_BEFORE               = "BEFORE";
+    static final String        T_BERNOULLI            = "BERNOULLI";
+    static final String        T_BREADTH              = "BREADTH";
+    static final String        T_C                    = "C";
+    static final String        T_CASCADE              = "CASCADE";
+    public static final String T_CATALOG              = "CATALOG";
+    public static final String T_CATALOG_NAME         = "CATALOG_NAME";
+    static final String        T_CHAIN                = "CHAIN";
+    static final String T_CHARACTER_SET_CATALOG = "CHARACTER_SET_CATALOG";
+    static final String        T_CHARACTER_SET_NAME   = "CHARACTER_SET_NAME";
+    static final String        T_CHARACTER_SET_SCHEMA = "CHARACTER_SET_SCHEMA";
+    static final String        T_CHARACTERISTICS      = "CHARACTERISTICS";
+    static final String        T_CHARACTERS           = "CHARACTERS";
+    static final String        T_CLASS_ORIGIN         = "CLASS_ORIGIN";
+    static final String        T_COBOL                = "COBOL";
+    static final String        T_COLLATION            = "COLLATION";
+    static final String        T_COLLATION_CATALOG    = "COLLATION_CATALOG";
+    static final String        T_COLLATION_NAME       = "COLLATION_NAME";
+    static final String        T_COLLATION_SCHEMA     = "COLLATION_SCHEMA";
+    static final String        T_COLUMN_NAME          = "COLUMN_NAME";
+    static final String        T_COMMAND_FUNCTION     = "COMMAND_FUNCTION";
+    static final String T_COMMAND_FUNCTION_CODE = "COMMAND_FUNCTION_CODE";
+    public static final String T_COMMITTED            = "COMMITTED";
+    static final String        T_COMPARABLE           = "COMPARABLE";    // SQL/JRT
+    static final String        T_CONDITION_IDENTIFIER = "CONDIITON_IDENTIFIER";
+    static final String        T_CONDITION_NUMBER     = "CONDITION_NUMBER";
+    static final String        T_CONNECTION_NAME      = "CONNECTION_NAME";
+    static final String        T_CONSTRAINT_CATALOG   = "CONSTRAINT_CATALOG";
+    static final String        T_CONSTRAINT_NAME      = "CONSTRAINT_NAME";
+    static final String        T_CONSTRAINT_SCHEMA    = "CONSTRAINT_SCHEMA";
+    static final String        T_CONSTRAINTS          = "CONSTRAINTS";
+    static final String        T_CONSTRUCTOR          = "CONSTRUCTOR";
+    static final String        T_CONTAINS             = "CONTAINS";
+    static final String        T_CONTINUE             = "CONTINUE";
+    static final String        T_CURRENT_COLLATION    = "CURRENT_COLLATION";
+    static final String        T_CURSOR_NAME          = "CURSOR_NAME";
+    public static final String T_DATA                 = "DATA";
+    static final String T_DATETIME_INTERVAL_CODE = "DATETIME_INTERVAL_CODE";
+    static final String T_DATETIME_INTERVAL_PRECISION =
+        "DATETIME_INTERVAL_PRECISION";
+    public static final String T_DEFAULTS             = "DEFAULTS";
+    static final String        T_DEFERRABLE           = "DEFERRABLE";
+    static final String        T_DEFERRED             = "DEFERRED";
+    static final String        T_DEFINED              = "DEFINED";
+    static final String        T_DEFINER              = "DEFINER";
+    static final String        T_DEGREE               = "DEGREE";
+    static final String        T_DEPTH                = "DEPTH";
+    static final String        T_DERIVED              = "DERIVED";
+    static final String        T_DESC                 = "DESC";
+    static final String        T_DESCRIPTOR           = "DESCRIPTOR";
+    static final String        T_DIAGNOSTICS          = "DIAGNOSTICS";
+    static final String        T_DISPATCH             = "DISPATCH";
+    public static final String T_DOMAIN               = "DOMAIN";
+    static final String        T_DYNAMIC_FUNCTION     = "DYNAMIC_FUNCTION";
+    static final String T_DYNAMIC_FUNCTION_CODE = "DYNAMIC_FUNCTION_CODE";
+    static final String        T_EXCEPTION            = "EXCEPTION";
+    static final String        T_EXCLUDE              = "EXCLUDE";
+    static final String        T_EXCLUDING            = "EXCLUDING";
+    static final String        T_EXIT                 = "EXIT";
+    static final String        T_FINAL                = "FINAL";
+    static final String        T_FIRST                = "FIRST";
+    static final String        T_FOLLOWING            = "FOLLOWING";
+    static final String        T_FORTRAN              = "FORTRAN";
+    static final String        T_FOUND                = "FOUND";
+    public static final String T_G_FACTOR             = "G";
+    static final String        T_GENERAL              = "GENERAL";
+    static final String        T_GO                   = "GO";
+    static final String        T_GOTO                 = "GOTO";
+    static final String        T_GRANTED              = "GRANTED";
+    static final String        T_HIERARCHY            = "HIERARCHY";
+    static final String        T_IMPLEMENTATION       = "IMPLEMENTATION";
+    static final String        T_INCLUDING            = "INCLUDING";
+    public static final String T_INCREMENT            = "INCREMENT";
+    static final String        T_INITIALLY            = "INITIALLY";
+    static final String        T_INPUT                = "INPUT";
+    static final String        T_INSTANCE             = "INSTANCE";
+    static final String        T_INSTANTIABLE         = "INSTANTIABLE";
+    static final String        T_INSTEAD              = "INSTEAD";
+    static final String        T_INTERFACE            = "INTERFACE";     // SQL/JRT
+    static final String        T_INVOKER              = "INVOKER";
+    public static final String T_ISOLATION            = "ISOLATION";
+    public static final String T_JAVA                 = "JAVA";          // SQL/JRT
+    public static final String T_K_FACTOR             = "K";
+    static final String        T_KEY                  = "KEY";
+    static final String        T_KEY_MEMBER           = "KEY_MEMBER";
+    static final String        T_KEY_TYPE             = "KEY_TYPE";
+    static final String        T_LAST                 = "LAST";
+    static final String        T_LENGTH               = "LENGTH";
+    public static final String T_LEVEL                = "LEVEL";
+    public static final String T_LIBRARY              = "LIBRARY";
+    static final String        T_LOCATOR              = "LOCATOR";
+    public static final String T_M_FACTOR             = "M";
+    static final String        T_MAP                  = "MAP";
+    static final String        T_MATCHED              = "MATCHED";
+    static final String        T_MAXVALUE             = "MAXVALUE";
+    static final String        T_MESSAGE_LENGTH       = "MESSAGE_LENGTH";
+    static final String        T_MESSAGE_OCTET_LENGTH = "MESSAGE_OCTET_LENGTH";
+    static final String        T_MESSAGE_TEXT         = "MESSAGE_TEXT";
+    static final String        T_MINVALUE             = "MINVALUE";
+    static final String        T_MORE                 = "MORE";
+    static final String        T_MUMPS                = "MUMPS";
+    public static final String T_NAME                 = "NAME";
+    public static final String T_NAMES                = "NAMES";
+    static final String        T_NESTING              = "NESTING";
+    static final String        T_NEXT                 = "NEXT";
+    static final String        T_NORMALIZED           = "NORMALIZED";
+    static final String        T_NULLABLE             = "NULLABLE";
+    public static final String T_NULLS                = "NULLS";
+    static final String        T_NUMBER               = "NUMBER";
+    public static final String T_OBJECT               = "OBJECT";
+    static final String        T_OCTETS               = "OCTETS";
+    static final String        T_OPTION               = "OPTION";
+    static final String        T_OPTIONS              = "OPTIONS";
+    static final String        T_ORDERING             = "ORDERING";
+    static final String        T_ORDINALITY           = "ORDINALITY";
+    static final String        T_OTHERS               = "OTHERS";
+    public static final String T_OVERRIDING           = "OVERRIDING";
+    public static final String T_P_FACTOR             = "P";
+    static final String        T_PAD                  = "PAD";
+    static final String        T_PARAMETER_MODE       = "PARAMETER_MODE";
+    static final String        T_PARAMETER_NAME       = "PARAMETER_NAME";
+    static final String T_PARAMETER_ORDINAL_POSITION =
+        "PARAMETER_ORDINAL_POSITION";
+    static final String T_PARAMETER_SPECIFIC_CATALOG =
+        "PARAMETER_SPECIFIC_CATALOG";
+    static final String T_PARAMETER_SPEC_NAME = "PARAMETER_SPECIFIC_NAME";
+    static final String T_PARAMETER_SPEC_SCHEMA = "PARAMETER_SPECIFIC_SCHEMA";
+    static final String        T_PARTIAL              = "PARTIAL";
+    static final String        T_PASCAL               = "PASCAL";
+    public static final String T_PATH                 = "PATH";
+    static final String        T_PLACING              = "PLACING";
+    static final String        T_PLI                  = "PLI";
+    static final String        T_PRECEDING            = "PRECEDING";
+    static final String        T_PRESERVE             = "PRESERVE";
+    static final String        T_PRIOR                = "PRIOR";
+    static final String        T_PRIVILEGES           = "PRIVILEGES";
+    public static final String T_PUBLIC               = "PUBLIC";
+    public static final String T_READ                 = "READ";
+    static final String        T_RELATIVE             = "RELATIVE";
+    static final String        T_REPEATABLE           = "REPEATABLE";
+    static final String        T_RESTART              = "RESTART";
+    static final String        T_RETURNED_CARDINALITY = "RETURNED_CARDINALITY";
+    static final String        T_RETURNED_LENGTH      = "RETURNED_LENGTH";
+    static final String T_RETURNED_OCTET_LENGTH = "RETURNED_OCTET_LENGTH";
+    static final String        T_RETURNED_SQLSTATE    = "RETURNED_SQLSTATE";
+    public static final String T_ROLE                 = "ROLE";
+    public static final String T_ROUTINE              = "ROUTINE";
+    static final String        T_ROUTINE_CATALOG      = "ROUTINE_CATALOG";
+    static final String        T_ROUTINE_NAME         = "ROUTINE_NAME";
+    static final String        T_ROUTINE_SCHEMA       = "ROUTINE_SCHEMA";
+    static final String        T_ROW_COUNT            = "ROW_COUNT";
+    public static final String T_SCALE                = "SCALE";
+    public static final String T_SCHEMA               = "SCHEMA";
+    static final String        T_SCHEMA_NAME          = "SCHEMA_NAME";
+    static final String        T_SCOPE_CATALOG        = "SCOPE_CATALOG";
+    static final String        T_SCOPE_NAME           = "SCOPE_NAME";
+    static final String        T_SCOPE_SCHEMA         = "SCOPE_SCHEMA";
+    static final String        T_SECTION              = "SECTION";
+    static final String        T_SECURITY             = "SECURITY";
+    static final String        T_SELF                 = "SELF";
+    public static final String T_SEQUENCE             = "SEQUENCE";
+    public static final String T_SERIALIZABLE         = "SERIALIZABLE";
+    public static final String T_SERVER               = "SERVER";
+    static final String        T_SERVER_NAME          = "SERVER_NAME";
+    public static final String T_SESSION              = "SESSION";
+    static final String        T_SETS                 = "SETS";
+    static final String        T_SIMPLE               = "SIMPLE";
+    public static final String T_SIZE                 = "SIZE";
+    static final String        T_SOURCE               = "SOURCE";
+    static final String        T_SPACE                = "SPACE";
+    static final String        T_SPECIFIC_NAME        = "SPECIFIC_NAME";
+    static final String        T_SQLDATA              = "SQLDATA";       // SQL/JRT
+    static final String        T_STACKED              = "STACKED";
+    static final String        T_STATE                = "STATE";
+    static final String        T_STATEMENT            = "STATEMENT";
+    static final String        T_STRUCTURE            = "STRUCTURE";
+    static final String        T_STYLE                = "STYLE";
+    static final String        T_SUBCLASS_ORIGIN      = "SUBCLASS_ORIGIN";
+    public static final String T_T_FACTOR             = "T";
+    static final String        T_TABLE_NAME           = "TABLE_NAME";
+    static final String        T_TEMPORARY            = "TEMPORARY";
+    static final String        T_TIES                 = "TIES";
+    static final String        T_TOP_LEVEL_COUNT      = "TOP_LEVEL_COUNT";
+    public static final String T_TRANSACTION          = "TRANSACTION";
+    static final String        T_TRANSACT_COMMITTED = "TRANSACTIONS_COMMITTED";
+    static final String T_TRANSACTION_ROLLED_BACK = "TRANSACTIONS_ROLLED_BACK";
+    static final String        T_TRANSACT_ACTIVE      = "TRANSACTION_ACTIVE";
+    static final String        T_TRANSFORM            = "TRANSFORM";
+    static final String        T_TRANSFORMS           = "TRANSFORMS";
+    static final String        T_TRIGGER_CATALOG      = "TRIGGER_CATALOG";
+    static final String        T_TRIGGER_NAME         = "TRIGGER_NAME";
+    static final String        T_TRIGGER_SCHEMA       = "TRIGGER_SCHEMA";
+    public static final String T_TYPE                 = "TYPE";
+    static final String        T_UNBOUNDED            = "UNBOUNDED";
+    static final String        T_UNCOMMITTED          = "UNCOMMITTED";
+    static final String        T_UNDER                = "UNDER";
+    static final String        T_UNDO                 = "UNDO";
+    static final String        T_UNNAMED              = "UNNAMED";
+    public static final String T_USAGE                = "USAGE";
+    static final String T_USER_DEFINED_TYPE_CATALOG =
+        "USER_DEFINED_TYPE_CATALOG";
+    static final String T_USER_DEFINED_TYPE_CODE = "USER_DEFINED_TYPE_CODE";
+    static final String T_USER_DEFINED_TYPE_NAME = "USER_DEFINED_TYPE_NAME";
+    static final String T_USER_DEFINED_TYPE_SCHEMA =
+        "USER_DEFINED_TYPE_SCHEMA";
+    static final String        T_VIEW    = "VIEW";
+    static final String        T_WORK    = "WORK";
+    public static final String T_WRAPPER = "WRAPPER";
+    public static final String T_WRITE   = "WRITE";
+    public static final String T_ZONE    = "ZONE";
+
+    // other tokens
+    static final String        T_ADD                 = "ADD";
+    static final String        T_ALIAS               = "ALIAS";
+    static final String        T_AGGREGATE           = "AGGREGATE";
+    static final String        T_AUTOCOMMIT          = "AUTOCOMMIT";
+    public static final String T_BACKUP              = "BACKUP";
+    public static final String T_BIT                 = "BIT";
+    static final String        T_BITLENGTH           = "BITLENGTH";
+    public static final String T_CACHE               = "CACHE";
+    static final String        T_CACHED              = "CACHED";
+    static final String        T_CASEWHEN            = "CASEWHEN";
+    static final String        T_CHECKPOINT          = "CHECKPOINT";
+    static final String        T_CLASS               = "CLASS";
+    static final String        T_COMMENT             = "COMMENT";
+    static final String        T_COMPACT             = "COMPACT";
+    public static final String T_COMPRESSED          = "COMPRESSED";
+    public static final String T_CONTROL             = "CONTROL";
+    static final String        T_CURDATE             = "CURDATE";
+    static final String        T_CURTIME             = "CURTIME";
+    public static final String T_DATABASE            = "DATABASE";
+    public static final String T_DEFRAG              = "DEFRAG";
+    public static final String T_DELAY               = "DELAY";
+    static final String        T_EXPLAIN             = "EXPLAIN";
+    public static final String T_EVENT               = "EVENT";
+    static final String        T_FILE                = "FILE";
+    public static final String T_FILES               = "FILES";
+    static final String        T_FOLD                = "FOLD";
+    static final String        T_GENERATED           = "GENERATED";
+    static final String        T_HEADER              = "HEADER";
+    static final String        T_IFNULL              = "IFNULL";
+    static final String        T_IGNORECASE          = "IGNORECASE";
+    static final String        T_IMMEDIATELY         = "IMMEDIATELY";
+    public static final String T_INDEX               = "INDEX";
+    public static final String T_INITIAL             = "INITIAL";
+    public static final String T_INTEGRITY           = "INTEGRITY";
+    static final String        T_ISAUTOCOMMIT        = "ISAUTOCOMMIT";
+    static final String        T_ISREADONLYDATABASE  = "ISREADONLYDATABASE";
+    static final String T_ISREADONLYDATABASEFILES = "ISREADONLYDATABASEFILES";
+    static final String        T_ISREADONLYSESSION   = "ISREADONLYSESSION";
+    static final String        T_LIMIT               = "LIMIT";
+    public static final String T_LOB                 = "LOB";
+    public static final String T_LOCK                = "LOCK";
+    public static final String T_LOCKS               = "LOCKS";
+    static final String        T_MAXROWS             = "MAXROWS";
+    public static final String T_MEMORY              = "MEMORY";
+    public static final String T_MILLIS              = "MILLIS";
+    static final String        T_MINUS_EXCEPT        = "MINUS";
+    public static final String T_MVCC                = "MVCC";
+    public static final String T_MVLOCKS             = "MVLOCKS";
+    public static final String T_NIO                 = "NIO";
+    static final String        T_NOWAIT              = "NOWAIT";
+    static final String        T_NVL                 = "NVL";
+    static final String        T_OCTETLENGTH         = "OCTETLENGTH";
+    static final String        T_OFF                 = "OFF";
+    public static final String T_OTHER               = "OTHER";
+    public static final String T_PASSWORD            = "PASSWORD";
+    static final String        T_PLAN                = "PLAN";
+    static final String        T_PROPERTY            = "PROPERTY";
+    static final String        T_QUEUE               = "QUEUE";
+    static final String        T_READONLY            = "READONLY";
+    static final String        T_REFERENTIAL         = "REFERENTIAL";
+    static final String        T_RENAME              = "RENAME";
+    static final String        T_RESTRICT            = "RESTRICT";
+    static final String        T_SCRIPT              = "SCRIPT";
+    static final String        T_SCRIPTFORMAT        = "SCRIPTFORMAT";
+    static final String        T_BLOCKING            = "BLOCKING";
+    static final String        T_SHUTDOWN            = "SHUTDOWN";
+    static final String        T_SQL_TSI_DAY         = "SQL_TSI_DAY";
+    static final String        T_SQL_TSI_FRAC_SECOND = "SQL_TSI_FRAC_SECOND";
+    static final String        T_SQL_TSI_HOUR        = "SQL_TSI_HOUR";
+    static final String        T_SQL_TSI_MINUTE      = "SQL_TSI_MINUTE";
+    static final String        T_SQL_TSI_MONTH       = "SQL_TSI_MONTH";
+    static final String        T_SQL_TSI_QUARTER     = "SQL_TSI_QUARTER";
+    static final String        T_SQL_TSI_SECOND      = "SQL_TSI_SECOND";
+    static final String        T_SQL_TSI_WEEK        = "SQL_TSI_WEEK";
+    static final String        T_SQL_TSI_YEAR        = "SQL_TSI_YEAR";
+    static final String        T_SQL_BIGINT          = "SQL_BIGINT";
+    static final String        T_SQL_BINARY          = "SQL_BINARY";
+    static final String        T_SQL_BIT             = "SQL_BIT";
+    static final String        T_SQL_BLOB            = "SQL_BLOB";
+    static final String        T_SQL_BOOLEAN         = "SQL_BOOLEAN";
+    static final String        T_SQL_CHAR            = "SQL_CHAR";
+    static final String        T_SQL_CLOB            = "SQL_CLOB";
+    static final String        T_SQL_DATE            = "SQL_DATE";
+    static final String        T_SQL_DECIMAL         = "SQL_DECIMAL";
+    static final String        T_SQL_DATALINK        = "SQL_DATALINK";
+    static final String        T_SQL_DOUBLE          = "SQL_DOUBLE";
+    static final String        T_SQL_FLOAT           = "SQL_FLOAT";
+    static final String        T_SQL_INTEGER         = "SQL_INTEGER";
+    static final String        T_SQL_LONGVARBINARY   = "SQL_LONGVARBINARY";
+    static final String        T_SQL_LONGNVARCHAR    = "SQL_LONGNVARCHAR";
+    static final String        T_SQL_LONGVARCHAR     = "SQL_LONGVARCHAR";
+    static final String        T_SQL_NCHAR           = "SQL_NCHAR";
+    static final String        T_SQL_NCLOB           = "SQL_NCLOB";
+    static final String        T_SQL_NUMERIC         = "SQL_NUMERIC";
+    static final String        T_SQL_NVARCHAR        = "SQL_NVARCHAR";
+    static final String        T_SQL_REAL            = "SQL_REAL";
+    static final String        T_SQL_ROWID           = "SQL_ROWID";
+    static final String        T_SQL_SQLXML          = "SQL_SQLXML";
+    static final String        T_SQL_SMALLINT        = "SQL_SMALLINT";
+    static final String        T_SQL_TIME            = "SQL_TIME";
+    static final String        T_SQL_TIMESTAMP       = "SQL_TIMESTAMP";
+    static final String        T_SQL_TINYINT         = "SQL_TINYINT";
+    static final String        T_SQL_VARBINARY       = "SQL_VARBINARY";
+    static final String        T_SQL_VARCHAR         = "SQL_VARCHAR";
+    public static final String T_TEMP                = "TEMP";
+    public static final String T_TEXT                = "TEXT";
+    static final String        T_TIMESTAMPADD        = "TIMESTAMPADD";
+    static final String        T_TIMESTAMPDIFF       = "TIMESTAMPDIFF";
+    public static final String T_TINYINT             = "TINYINT";
+    static final String        T_TO_CHAR             = "TO_CHAR";
+    static final String        T_TODAY               = "TODAY";
+    static final String        T_TOP                 = "TOP";
+    public static final String T_VARCHAR_IGNORECASE  = "VARCHAR_IGNORECASE";
+    static final String        T_WRITE_DELAY         = "WRITE_DELAY";
+    public static final String T_YES                 = "YES";
+
+    //
+    public static final String T_DAY_NAME     = "DAY_NAME";
+    public static final String T_MONTH_NAME   = "MONTH_NAME";
+    public static final String T_QUARTER      = "QUARTER";
+    public static final String T_DAY_OF_WEEK  = "DAY_OF_WEEK";
+    public static final String T_DAY_OF_MONTH = "DAY_OF_MONTH";
+    public static final String T_DAY_OF_YEAR  = "DAY_OF_YEAR";
+    public static final String T_WEEK_OF_YEAR = "WEEK_OF_YEAR";
+    static final String        T_DAYNAME      = "DAYNAME";
+    static final String        T_MONTHNAME    = "MONTHNAME";
+    static final String        T_DAYOFMONTH   = "DAYOFMONTH";
+    static final String        T_DAYOFWEEK    = "DAYOFWEEK";
+    static final String        T_DAYOFYEAR    = "DAYOFYEAR";
+    static final String        T_WEEK         = "WEEK";
+
+    //
+    static final String        T_ACOS             = "ACOS";
+    static final String        T_ASCII            = "ASCII";
+    static final String        T_ASIN             = "ASIN";
+    static final String        T_ATAN             = "ATAN";
+    static final String        T_ATAN2            = "ATAN2";
+    static final String        T_BITAND           = "BITAND";
+    static final String        T_BITOR            = "BITOR";
+    static final String        T_BITXOR           = "BITXOR";
+    static final String        T_CONCAT_WORD      = "CONCAT";
+    static final String        T_COS              = "COS";
+    static final String        T_COT              = "COT";
+    static final String        T_CRYPT_KEY        = "CRYPT_KEY";
+    static final String        T_DATEADD          = "DATEADD";
+    static final String        T_DATEDIFF         = "DATEDIFF";
+    static final String        T_DECODE           = "DECODE";
+    static final String        T_DEGREES          = "DEGREES";
+    static final String        T_DIFFERENCE       = "DIFFERENCE";
+    static final String        T_DMOD             = "DMOD";
+    public static final String T_GC               = "GC";
+    static final String        T_GREATEST         = "GREATEST";
+    static final String        T_HEXTORAW         = "HEXTORAW";
+    static final String        T_LCASE            = "LCASE";
+    static final String        T_LEAST            = "LEAST";
+    static final String        T_LOCATE           = "LOCATE";
+    public static final String T_LOG              = "LOG";
+    static final String        T_LOG10            = "LOG10";
+    static final String        T_LTRIM            = "LTRIM";
+    static final String        T_NOW              = "NOW";
+    static final String        T_PI               = "PI";
+    static final String        T_RADIANS          = "RADIANS";
+    static final String        T_RAND             = "RAND";
+    static final String        T_RAWTOHEX         = "RAWTOHEX";
+    public static final String T_REGEXP_MATCHES   = "REGEXP_MATCHES";
+    static final String        T_REPLACE          = "REPLACE";
+    static final String        T_REVERSE          = "REVERSE";
+    static final String        T_ROUND            = "ROUND";
+    static final String        T_ROUNDMAGIC       = "ROUNDMAGIC";
+    static final String        T_RTRIM            = "RTRIM";
+    public static final String T_SECONDS_MIDNIGHT = "SECONDS_SINCE_MIDNIGHT";
+    static final String        T_SIGN             = "SIGN";
+    static final String        T_SIN              = "SIN";
+    static final String        T_SOUNDEX          = "SOUNDEX";
+    static final String        T_SUBSTR           = "SUBSTR";
+    static final String        T_SYSDATE          = "SYSDATE";
+    static final String        T_TAN              = "TAN";
+    static final String        T_UCASE            = "UCASE";
+
+    //
+    static final String T_ISOLATION_LEVEL         = "ISOLATION_LEVEL";
+    static final String T_SESSION_ISOLATION_LEVEL = "SESSION_ISOLATION_LEVEL";
+    static final String T_DATABASE_ISOLATION_LEVEL =
+        "DATABASE_ISOLATION_LEVEL";
+    static final String T_TRANSACTION_CONTROL = "TRANSACTION_CONTROL";
+    static final String T_TIMEZONE            = "TIMEZONE";
+    static final String T_SESSION_TIMEZONE    = "SESSION_TIMEZONE";
+    static final String T_DATABASE_TIMEZONE   = "DATABASE_TIMEZONE";
+    static final String T_DATABASE_VERSION    = "DATABASE_VERSION";
+
+    //
+    //SQL 200n Standard reserved keywords - full set
+    public static final int ABS                              = 1;
+    public static final int ALL                              = 2;
+    public static final int ALLOCATE                         = 3;
+    public static final int ALTER                            = 4;
+    public static final int AND                              = 5;
+    public static final int ANY                              = 6;
+    public static final int ARE                              = 7;
+    public static final int ARRAY                            = 8;
+    public static final int AS                               = 9;
+    public static final int ASENSITIVE                       = 10;
+    public static final int ASYMMETRIC                       = 11;
+    public static final int AT                               = 12;
+    public static final int ATOMIC                           = 13;
+    public static final int AUTHORIZATION                    = 14;
+    public static final int AVG                              = 15;
+    public static final int BEGIN                            = 16;
+    public static final int BETWEEN                          = 17;
+    public static final int BIGINT                           = 18;
+    public static final int BINARY                           = 19;
+    public static final int BLOB                             = 20;
+    public static final int BOOLEAN                          = 21;
+    public static final int BOTH                             = 22;
+    public static final int BY                               = 23;
+    public static final int CALL                             = 24;
+    public static final int CALLED                           = 25;
+    public static final int CARDINALITY                      = 26;
+    public static final int CASCADED                         = 27;
+    public static final int CASE                             = 28;
+    public static final int CAST                             = 29;
+    public static final int CEIL                             = 30;
+    public static final int CEILING                          = 31;
+    public static final int CHAR                             = 32;
+    public static final int CHAR_LENGTH                      = 33;
+    public static final int CHARACTER                        = 34;
+    public static final int CHARACTER_LENGTH                 = 35;
+    public static final int CHECK                            = 36;
+    public static final int CLOB                             = 37;
+    public static final int CLOSE                            = 38;
+    public static final int COALESCE                         = 39;
+    public static final int COLLATE                          = 40;
+    public static final int COLLECT                          = 41;
+    public static final int COLUMN                           = 42;
+    public static final int COMMIT                           = 43;
+    public static final int COMPARABLE                       = 44;
+    public static final int CONDITION                        = 45;
+    public static final int CONNECT                          = 46;
+    public static final int CONSTRAINT                       = 47;
+    public static final int CONVERT                          = 48;
+    public static final int CORR                             = 49;
+    public static final int CORRESPONDING                    = 50;
+    public static final int COUNT                            = 51;
+    public static final int COVAR_POP                        = 52;
+    public static final int COVAR_SAMP                       = 53;
+    public static final int CREATE                           = 54;
+    public static final int CROSS                            = 55;
+    public static final int CUBE                             = 56;
+    public static final int CUME_DIST                        = 57;
+    public static final int CURRENT                          = 58;
+    public static final int CURRENT_CATALOG                  = 59;
+    public static final int CURRENT_DATE                     = 60;
+    public static final int CURRENT_DEFAULT_TRANSFORM_GROUP  = 61;
+    public static final int CURRENT_PATH                     = 62;
+    public static final int CURRENT_ROLE                     = 63;
+    public static final int CURRENT_SCHEMA                   = 64;
+    public static final int CURRENT_TIME                     = 65;
+    public static final int CURRENT_TIMESTAMP                = 66;
+    public static final int CURRENT_TRANSFORM_GROUP_FOR_TYPE = 67;
+    public static final int CURRENT_USER                     = 68;
+    public static final int CURSOR                           = 69;
+    public static final int CYCLE                            = 70;
+    public static final int DATE                             = 71;
+    public static final int DAY                              = 72;
+    public static final int DEALLOCATE                       = 73;
+    public static final int DEC                              = 74;
+    public static final int DECIMAL                          = 75;
+    public static final int DECLARE                          = 76;
+    public static final int DEFAULT                          = 77;
+    public static final int DELETE                           = 78;
+    public static final int DENSE_RANK                       = 79;
+    public static final int DEREF                            = 80;
+    public static final int DESCRIBE                         = 81;
+    public static final int DETERMINISTIC                    = 82;
+    public static final int DISCONNECT                       = 83;
+    public static final int DISTINCT                         = 84;
+    public static final int DO                               = 85;
+    public static final int DOUBLE                           = 86;
+    public static final int DROP                             = 87;
+    public static final int DYNAMIC                          = 88;
+    public static final int EACH                             = 89;
+    public static final int ELEMENT                          = 90;
+    public static final int ELSE                             = 91;
+    public static final int ELSEIF                           = 92;
+    public static final int END                              = 93;
+    public static final int END_EXEC                         = 94;
+    public static final int ESCAPE                           = 95;
+    public static final int EVERY                            = 96;
+    public static final int EXCEPT                           = 97;
+    public static final int EXEC                             = 98;
+    public static final int EXECUTE                          = 99;
+    public static final int EXISTS                           = 100;
+    public static final int EXIT                             = 101;
+    public static final int EXP                              = 102;
+    public static final int EXTERNAL                         = 103;
+    public static final int EXTRACT                          = 104;
+    public static final int FALSE                            = 105;
+    public static final int FETCH                            = 106;
+    public static final int FILTER                           = 107;
+    public static final int FIRST_VALUE                      = 108;
+    public static final int FLOAT                            = 109;
+    public static final int FLOOR                            = 110;
+    public static final int FOR                              = 111;
+    public static final int FOREIGN                          = 112;
+    public static final int FREE                             = 113;
+    public static final int FROM                             = 114;
+    public static final int FULL                             = 115;
+    public static final int FUNCTION                         = 116;
+    public static final int FUSION                           = 117;
+    public static final int GET                              = 118;
+    public static final int GLOBAL                           = 119;
+    public static final int GRANT                            = 120;
+    public static final int GROUP                            = 121;
+    public static final int GROUPING                         = 122;
+    public static final int HANDLER                          = 123;
+    public static final int HAVING                           = 124;
+    public static final int HOLD                             = 125;
+    public static final int HOUR                             = 126;
+    public static final int IDENTITY                         = 127;
+    public static final int IMPORT                           = 128;
+    public static final int IN                               = 129;
+    public static final int INDICATOR                        = 130;
+    public static final int INNER                            = 131;
+    public static final int INOUT                            = 132;
+    public static final int INSENSITIVE                      = 133;
+    public static final int INSERT                           = 134;
+    public static final int INT                              = 135;
+    public static final int INTEGER                          = 136;
+    public static final int INTERSECT                        = 137;
+    public static final int INTERSECTION                     = 138;
+    public static final int INTERVAL                         = 139;
+    public static final int INTO                             = 140;
+    public static final int IS                               = 141;
+    public static final int ITERATE                          = 142;
+    public static final int JOIN                             = 143;
+    public static final int LAG                              = 144;
+    public static final int LANGUAGE                         = 145;
+    public static final int LARGE                            = 146;
+    public static final int LAST_VALUE                       = 147;
+    public static final int LATERAL                          = 148;
+    public static final int LEAD                             = 149;
+    public static final int LEADING                          = 150;
+    public static final int LEAVE                            = 151;
+    public static final int LEFT                             = 152;
+    public static final int LIKE                             = 153;
+    public static final int LIKE_REGEX                       = 154;
+    public static final int LN                               = 155;
+    public static final int LOCAL                            = 156;
+    public static final int LOCALTIME                        = 157;
+    public static final int LOCALTIMESTAMP                   = 158;
+    public static final int LOOP                             = 159;
+    public static final int LOWER                            = 160;
+    public static final int MATCH                            = 161;
+    public static final int MAX                              = 162;
+    public static final int MAX_CARDINALITY                  = 163;
+    public static final int MEMBER                           = 164;
+    public static final int MERGE                            = 165;
+    public static final int METHOD                           = 166;
+    public static final int MIN                              = 167;
+    public static final int MINUTE                           = 168;
+    public static final int MOD                              = 169;
+    public static final int MODIFIES                         = 170;
+    public static final int MODULE                           = 171;
+    public static final int MONTH                            = 172;
+    public static final int MULTISET                         = 173;
+    public static final int NATIONAL                         = 174;
+    public static final int NATURAL                          = 175;
+    public static final int NCHAR                            = 176;
+    public static final int NCLOB                            = 177;
+    public static final int NEW                              = 178;
+    public static final int NO                               = 179;
+    public static final int NONE                             = 180;
+    public static final int NORMALIZE                        = 181;
+    public static final int NOT                              = 182;
+    public static final int NTH_VALUE                        = 183;
+    public static final int NTILE                            = 184;
+    public static final int NULL                             = 185;
+    public static final int NULLIF                           = 186;
+    public static final int NUMERIC                          = 187;
+    public static final int OCCURRENCES_REGEX                = 188;
+    public static final int OCTET_LENGTH                     = 189;
+    public static final int OF                               = 190;
+    public static final int OFFSET                           = 191;
+    public static final int OLD                              = 192;
+    public static final int ON                               = 193;
+    public static final int ONLY                             = 194;
+    public static final int OPEN                             = 195;
+    public static final int OR                               = 196;
+    public static final int ORDER                            = 197;
+    public static final int OUT                              = 198;
+    public static final int OUTER                            = 199;
+    public static final int OVER                             = 200;
+    public static final int OVERLAPS                         = 201;
+    public static final int OVERLAY                          = 202;
+    public static final int PARAMETER                        = 203;
+    public static final int PARTITION                        = 204;
+    public static final int PERCENT_RANK                     = 205;
+    public static final int PERCENTILE_CONT                  = 206;
+    public static final int PERCENTILE_DISC                  = 207;
+    public static final int POSITION                         = 208;
+    public static final int POSITION_REGEX                   = 209;
+    public static final int POWER                            = 210;
+    public static final int PRECISION                        = 211;
+    public static final int PREPARE                          = 212;
+    public static final int PRIMARY                          = 213;
+    public static final int PROCEDURE                        = 214;
+    public static final int RANGE                            = 215;
+    public static final int RANK                             = 216;
+    public static final int READS                            = 217;
+    public static final int REAL                             = 218;
+    public static final int RECURSIVE                        = 219;
+    public static final int REF                              = 220;
+    public static final int REFERENCES                       = 221;
+    public static final int REFERENCING                      = 222;
+    public static final int REGR_AVGX                        = 223;
+    public static final int REGR_AVGY                        = 224;
+    public static final int REGR_COUNT                       = 225;
+    public static final int REGR_INTERCEPT                   = 226;
+    public static final int REGR_R2                          = 227;
+    public static final int REGR_SLOPE                       = 228;
+    public static final int REGR_SXX                         = 229;
+    public static final int REGR_SXY                         = 230;
+    public static final int REGR_SYY                         = 231;
+    public static final int RELEASE                          = 232;
+    public static final int REPEAT                           = 233;
+    public static final int RESIGNAL                         = 234;
+    public static final int RESULT                           = 235;
+    public static final int RETURN                           = 236;
+    public static final int RETURNS                          = 237;
+    public static final int REVOKE                           = 238;
+    public static final int RIGHT                            = 239;
+    public static final int ROLLBACK                         = 240;
+    public static final int ROLLUP                           = 241;
+    public static final int ROW                              = 242;
+    public static final int ROW_NUMBER                       = 243;
+    public static final int ROWS                             = 244;
+    public static final int SAVEPOINT                        = 245;
+    public static final int SCOPE                            = 246;
+    public static final int SCROLL                           = 247;
+    public static final int SEARCH                           = 248;
+    public static final int SECOND                           = 249;
+    public static final int SELECT                           = 250;
+    public static final int SENSITIVE                        = 251;
+    public static final int SESSION_USER                     = 252;
+    public static final int SET                              = 253;
+    public static final int SIGNAL                           = 254;
+    public static final int SIMILAR                          = 255;
+    public static final int SMALLINT                         = 256;
+    public static final int SOME                             = 257;
+    public static final int SPECIFIC                         = 258;
+    public static final int SPECIFICTYPE                     = 259;
+    public static final int SQL                              = 260;
+    public static final int SQLEXCEPTION                     = 261;
+    public static final int SQLSTATE                         = 262;
+    public static final int SQLWARNING                       = 263;
+    public static final int SQRT                             = 264;
+    public static final int STACKED                          = 265;
+    public static final int START                            = 266;
+    public static final int STATIC                           = 267;
+    public static final int STDDEV_POP                       = 268;
+    public static final int STDDEV_SAMP                      = 269;
+    public static final int SUBMULTISET                      = 270;
+    public static final int SUBSTRING                        = 271;
+    public static final int SUBSTRING_REGEX                  = 272;
+    public static final int SUM                              = 273;
+    public static final int SYMMETRIC                        = 274;
+    public static final int SYSTEM                           = 275;
+    public static final int SYSTEM_USER                      = 276;
+    public static final int TABLE                            = 277;
+    public static final int TABLESAMPLE                      = 278;
+    public static final int THEN                             = 279;
+    public static final int TIME                             = 280;
+    public static final int TIMESTAMP                        = 281;
+    public static final int TIMEZONE_HOUR                    = 282;
+    public static final int TIMEZONE_MINUTE                  = 283;
+    public static final int TO                               = 284;
+    public static final int TRAILING                         = 285;
+    public static final int TRANSLATE                        = 286;
+    public static final int TRANSLATE_REGEX                  = 287;
+    public static final int TRANSLATION                      = 288;
+    public static final int TREAT                            = 289;
+    public static final int TRIGGER                          = 290;
+    public static final int TRIM                             = 291;
+    public static final int TRIM_ARRAY                       = 292;
+    public static final int TRUE                             = 293;
+    public static final int TRUNCATE                         = 294;
+    public static final int UESCAPE                          = 295;
+    public static final int UNDO                             = 296;
+    public static final int UNION                            = 297;
+    public static final int UNIQUE                           = 298;
+    public static final int UNKNOWN                          = 299;
+    public static final int UNNEST                           = 300;
+    public static final int UNTIL                            = 301;
+    public static final int UPDATE                           = 302;
+    public static final int UPPER                            = 303;
+    public static final int USER                             = 304;
+    public static final int USING                            = 305;
+    public static final int VALUE                            = 306;
+    public static final int VALUES                           = 307;
+    public static final int VAR_POP                          = 308;
+    public static final int VAR_SAMP                         = 309;
+    public static final int VARBINARY                        = 310;
+    public static final int VARCHAR                          = 311;
+    public static final int VARYING                          = 312;
+    public static final int WHEN                             = 313;
+    public static final int WHENEVER                         = 314;
+    public static final int WHERE                            = 315;
+    public static final int WIDTH_BUCKET                     = 316;
+    public static final int WINDOW                           = 317;
+    public static final int WITH                             = 318;
+    public static final int WITHIN                           = 319;
+    public static final int WITHOUT                          = 320;
+    public static final int WHILE                            = 321;
+    public static final int YEAR                             = 322;
+
+    //
+    //SQL 200n Standard non-reserved keywords - full set
+    public static final int A                           = 330;
+    public static final int ABSOLUTE                    = 331;
+    public static final int ACTION                      = 332;
+    public static final int ADA                         = 333;
+    public static final int ADD                         = 334;
+    public static final int ADMIN                       = 335;
+    public static final int AFTER                       = 336;
+    public static final int ALWAYS                      = 337;
+    public static final int ASC                         = 338;
+    public static final int ASSERTION                   = 339;
+    public static final int ASSIGNMENT                  = 340;
+    public static final int ATTRIBUTE                   = 341;
+    public static final int ATTRIBUTES                  = 342;
+    public static final int BEFORE                      = 343;
+    public static final int BERNOULLI                   = 344;
+    public static final int BREADTH                     = 345;
+    public static final int C                           = 346;
+    public static final int CASCADE                     = 347;
+    public static final int CATALOG                     = 348;
+    public static final int CATALOG_NAME                = 349;
+    public static final int CHAIN                       = 350;
+    public static final int CHARACTER_SET_CATALOG       = 351;
+    public static final int CHARACTER_SET_NAME          = 352;
+    public static final int CHARACTER_SET_SCHEMA        = 353;
+    public static final int CHARACTERISTICS             = 354;
+    public static final int CHARACTERS                  = 355;
+    public static final int CLASS_ORIGIN                = 356;
+    public static final int COBOL                       = 357;
+    public static final int COLLATION                   = 358;
+    public static final int COLLATION_CATALOG           = 359;
+    public static final int COLLATION_NAME              = 360;
+    public static final int COLLATION_SCHEMA            = 361;
+    public static final int COLUMN_NAME                 = 362;
+    public static final int COMMAND_FUNCTION            = 363;
+    public static final int COMMAND_FUNCTION_CODE       = 364;
+    public static final int COMMITTED                   = 365;
+    public static final int CONDITION_IDENTIFIER        = 366;
+    public static final int CONDITION_NUMBER            = 367;
+    public static final int CONNECTION                  = 368;
+    public static final int CONNECTION_NAME             = 369;
+    public static final int CONSTRAINT_CATALOG          = 370;
+    public static final int CONSTRAINT_NAME             = 371;
+    public static final int CONSTRAINT_SCHEMA           = 372;
+    public static final int CONSTRAINTS                 = 373;
+    public static final int CONSTRUCTOR                 = 374;
+    public static final int CONTAINS                    = 375;
+    public static final int CONTINUE                    = 376;
+    public static final int CURSOR_NAME                 = 377;
+    public static final int DATA                        = 378;
+    public static final int DATETIME_INTERVAL_CODE      = 379;
+    public static final int DATETIME_INTERVAL_PRECISION = 380;
+    public static final int DEFAULTS                    = 381;
+    public static final int DEFERRABLE                  = 382;
+    public static final int DEFERRED                    = 383;
+    public static final int DEFINED                     = 384;
+    public static final int DEFINER                     = 385;
+    public static final int DEGREE                      = 386;
+    public static final int DEPTH                       = 387;
+    public static final int DERIVED                     = 388;
+    public static final int DESC                        = 389;
+    public static final int DESCRIPTOR                  = 390;
+    public static final int DIAGNOSTICS                 = 391;
+    public static final int DISPATCH                    = 392;
+    public static final int DOMAIN                      = 393;
+    public static final int DYNAMIC_FUNCTION            = 394;
+    public static final int DYNAMIC_FUNCTION_CODE       = 395;
+    public static final int EQUALS                      = 396;
+    public static final int EXCEPTION                   = 397;
+    public static final int EXCLUDE                     = 398;
+    public static final int EXCLUDING                   = 399;
+    public static final int FINAL                       = 400;
+    public static final int FIRST                       = 401;
+    public static final int FOLLOWING                   = 402;
+    public static final int FORTRAN                     = 403;
+    public static final int FOUND                       = 404;
+    public static final int G                           = 405;
+    public static final int GENERAL                     = 406;
+    public static final int GENERATED                   = 407;
+    public static final int GO                          = 408;
+    public static final int GOTO                        = 409;
+    public static final int GRANTED                     = 410;
+    public static final int HIERARCHY                   = 411;
+    public static final int IF                          = 412;
+    public static final int IGNORE                      = 413;
+    public static final int IMMEDIATE                   = 414;
+    public static final int IMPLEMENTATION              = 415;
+    public static final int INCLUDING                   = 416;
+    public static final int INCREMENT                   = 417;
+    public static final int INITIALLY                   = 418;
+    public static final int INPUT                       = 419;
+    public static final int INSTANCE                    = 420;
+    public static final int INSTANTIABLE                = 421;
+    public static final int INSTEAD                     = 422;
+    public static final int INVOKER                     = 423;
+    public static final int ISOLATION                   = 424;
+    public static final int JAVA                        = 425;
+    public static final int K                           = 426;
+    public static final int KEY                         = 427;
+    public static final int KEY_MEMBER                  = 428;
+    public static final int KEY_TYPE                    = 429;
+    public static final int LAST                        = 430;
+    public static final int LENGTH                      = 431;
+    public static final int LEVEL                       = 432;
+    public static final int LIBRARY                     = 433;
+    public static final int LOCATOR                     = 434;
+    public static final int M                           = 435;
+    public static final int MAP                         = 436;
+    public static final int MATCHED                     = 437;
+    public static final int MAXVALUE                    = 438;
+    public static final int MESSAGE_LENGTH              = 439;
+    public static final int MESSAGE_OCTET_LENGTH        = 440;
+    public static final int MESSAGE_TEXT                = 441;
+    public static final int MINVALUE                    = 442;
+    public static final int MORE                        = 443;
+    public static final int MUMPS                       = 444;
+    public static final int NAME                        = 445;
+    public static final int NAMES                       = 446;
+    public static final int NESTING                     = 447;
+    public static final int NEXT                        = 448;
+    public static final int NORMALIZED                  = 449;
+    public static final int NULLABLE                    = 450;
+    public static final int NULLS                       = 451;
+    public static final int NUMBER                      = 452;
+    public static final int OBJECT                      = 453;
+    public static final int OCTETS                      = 454;
+    public static final int OPTION                      = 455;
+    public static final int OPTIONS                     = 456;
+    public static final int ORDERING                    = 457;
+    public static final int ORDINALITY                  = 458;
+    public static final int OTHERS                      = 459;
+    public static final int OUTPUT                      = 460;
+    public static final int OVERRIDING                  = 461;
+    public static final int P                           = 462;
+    public static final int PAD                         = 463;
+    public static final int PARAMETER_MODE              = 464;
+    public static final int PARAMETER_NAME              = 465;
+    public static final int PARAMETER_ORDINAL_POSITION  = 466;
+    public static final int PARAMETER_SPECIFIC_CATALOG  = 467;
+    public static final int PARAMETER_SPECIFIC_NAME     = 468;
+    public static final int PARAMETER_SPECIFIC_SCHEMA   = 469;
+    public static final int PARTIAL                     = 470;
+    public static final int PASCAL                      = 471;
+    public static final int PATH                        = 472;
+    public static final int PLACING                     = 473;
+    public static final int PLI                         = 474;
+    public static final int PRECEDING                   = 475;
+    public static final int PRESERVE                    = 476;
+    public static final int PRIOR                       = 477;
+    public static final int PRIVILEGES                  = 478;
+    public static final int PUBLIC                      = 479;
+    public static final int READ                        = 480;
+    public static final int RELATIVE                    = 481;
+    public static final int REPEATABLE                  = 482;
+    public static final int RESPECT                     = 483;
+    public static final int RESTART                     = 484;
+    public static final int RESTRICT                    = 485;
+    public static final int RETURNED_CARDINALITY        = 486;
+    public static final int RETURNED_LENGTH             = 487;
+    public static final int RETURNED_OCTET_LENGTH       = 488;
+    public static final int RETURNED_SQLSTATE           = 489;
+    public static final int ROLE                        = 490;
+    public static final int ROUTINE                     = 491;
+    public static final int ROUTINE_CATALOG             = 492;
+    public static final int ROUTINE_NAME                = 493;
+    public static final int ROUTINE_SCHEMA              = 494;
+    public static final int ROW_COUNT                   = 495;
+    public static final int SCALE                       = 496;
+    public static final int SCHEMA                      = 497;
+    public static final int SCHEMA_NAME                 = 498;
+    public static final int SCOPE_CATALOG               = 499;
+    public static final int SCOPE_NAME                  = 500;
+    public static final int SCOPE_SCHEMA                = 501;
+    public static final int SECTION                     = 502;
+    public static final int SECURITY                    = 503;
+    public static final int SELF                        = 504;
+    public static final int SEQUENCE                    = 505;
+    public static final int SERIALIZABLE                = 506;
+    public static final int SERVER_NAME                 = 507;
+    public static final int SESSION                     = 508;
+    public static final int SERVER                      = 509;
+    public static final int SETS                        = 510;
+    public static final int SIMPLE                      = 511;
+    public static final int SIZE                        = 512;
+    public static final int SOURCE                      = 513;
+    public static final int SPACE                       = 514;
+    public static final int SPECIFIC_NAME               = 515;
+    public static final int STATE                       = 516;
+    public static final int STATEMENT                   = 517;
+    public static final int STRUCTURE                   = 518;
+    public static final int STYLE                       = 519;
+    public static final int SUBCLASS_ORIGIN             = 520;
+    public static final int T                           = 521;
+    public static final int TABLE_NAME                  = 522;
+    public static final int TEMPORARY                   = 523;
+    public static final int TIES                        = 524;
+    public static final int TOP_LEVEL_COUNT             = 525;
+    public static final int TRANSACTION                 = 526;
+    public static final int TRANSACTION_ACTIVE          = 527;
+    public static final int TRANSACTIONS_COMMITTED      = 528;
+    public static final int TRANSACTIONS_ROLLED_BACK    = 529;
+    public static final int TRANSFORM                   = 530;
+    public static final int TRANSFORMS                  = 531;
+    public static final int TRIGGER_CATALOG             = 532;
+    public static final int TRIGGER_NAME                = 533;
+    public static final int TRIGGER_SCHEMA              = 534;
+    public static final int TYPE                        = 535;
+    public static final int UNBOUNDED                   = 536;
+    public static final int UNCOMMITTED                 = 537;
+    public static final int UNDER                       = 538;
+    public static final int UNNAMED                     = 539;
+    public static final int USAGE                       = 540;
+    public static final int USER_DEFINED_TYPE_CATALOG   = 541;
+    public static final int USER_DEFINED_TYPE_CODE      = 542;
+    public static final int USER_DEFINED_TYPE_NAME      = 543;
+    public static final int USER_DEFINED_TYPE_SCHEMA    = 544;
+    public static final int VIEW                        = 545;
+    public static final int WORK                        = 546;
+    public static final int WRITE                       = 547;
+    public static final int WRAPPER                     = 548;
+    public static final int ZONE                        = 549;
+
+    // other token values used as switch cases
+    static final int ALIAS        = 551;
+    static final int AGGREGATE    = 552;
+    static final int AUTOCOMMIT   = 553;
+    static final int BACKUP       = 554;
+    static final int BIT          = 555;
+    static final int BLOCKING     = 556;
+    static final int CACHE        = 557;
+    static final int CACHED       = 558;
+    static final int CASEWHEN     = 559;
+    static final int CHECKPOINT   = 560;
+    static final int CLASS        = 561;
+    static final int COMMENT      = 562;
+    static final int COMPACT      = 563;
+    static final int COMPRESSED   = 564;
+    static final int CONTROL      = 565;
+    static final int DATABASE     = 566;
+    static final int DEFRAG       = 567;
+    static final int DELAY        = 568;
+    static final int EVENT        = 569;
+    static final int EXPLAIN      = 570;
+    static final int FILE         = 571;
+    static final int FILES        = 572;
+    static final int GC           = 573;
+    static final int HEADER       = 574;
+    static final int IGNORECASE   = 575;
+    static final int IMMEDIATELY  = 576;
+    static final int INTEGRITY    = 577;
+    static final int INDEX        = 578;
+    static final int INITIAL      = 579;
+    static final int LIMIT        = 580;
+    static final int LOCK         = 581;
+    static final int LOCKS        = 582;
+    static final int MAXROWS      = 583;
+    static final int MEMORY       = 584;
+    static final int MILLIS       = 585;
+    static final int MINUS_EXCEPT = 586;
+    static final int OFF          = 587;
+    static final int PASSWORD     = 588;
+    static final int PLAN         = 589;
+    static final int PROPERTY     = 590;
+    static final int READONLY     = 591;
+    static final int REFERENTIAL  = 592;
+    static final int RENAME       = 593;
+    static final int SCRIPT       = 594;
+    static final int SCRIPTFORMAT = 595;
+    static final int SHUTDOWN     = 596;
+    static final int TEMP         = 597;
+    static final int TEXT         = 598;
+    static final int WRITE_DELAY  = 599;
+
+    //
+    static final int        ACOS                    = 601;
+    static final int        ASCII                   = 602;
+    static final int        ASIN                    = 603;
+    static final int        ATAN                    = 604;
+    static final int        ATAN2                   = 605;
+    static final int        BIT_LENGTH              = 606;
+    static final int        BITAND                  = 607;
+    static final int        BITLENGTH               = 608;
+    static final int        BITOR                   = 609;
+    static final int        BITXOR                  = 610;
+    static final int        CONCAT_WORD             = 611;
+    static final int        COS                     = 612;
+    static final int        COT                     = 613;
+    static final int        CRYPT_KEY               = 614;
+    static final int        CURDATE                 = 615;
+    static final int        CURTIME                 = 616;
+    static final int        DATEADD                 = 617;
+    static final int        DATEDIFF                = 618;
+    public static final int DAY_NAME                = 619;
+    public static final int DAY_OF_MONTH            = 620;
+    public static final int DAY_OF_WEEK             = 621;
+    public static final int DAY_OF_YEAR             = 622;
+    static final int        DAYNAME                 = 623;
+    static final int        DAYOFMONTH              = 624;
+    static final int        DAYOFWEEK               = 625;
+    static final int        DAYOFYEAR               = 626;
+    static final int        DECODE                  = 627;
+    static final int        DEGREES                 = 628;
+    static final int        DIFFERENCE              = 629;
+    static final int        DMOD                    = 630;
+    static final int        HEXTORAW                = 631;
+    static final int        IFNULL                  = 632;
+    static final int        ISAUTOCOMMIT            = 633;
+    static final int        ISREADONLYDATABASE      = 634;
+    static final int        ISREADONLYDATABASEFILES = 635;
+    static final int        ISREADONLYSESSION       = 636;
+    static final int        LCASE                   = 637;
+    static final int        LEAST                   = 638;
+    static final int        LOCATE                  = 639;
+    static final int        LOB                     = 640;
+    static final int        LOG                     = 641;
+    static final int        LOG10                   = 642;
+    static final int        LTRIM                   = 643;
+    static final int        GREATEST                = 644;
+    public static final int MONTH_NAME              = 645;
+    static final int        MONTHNAME               = 646;
+    static final int        MVCC                    = 647;
+    static final int        MVLOCKS                 = 648;
+    static final int        NIO                     = 649;
+    static final int        NOW                     = 650;
+    static final int        OCTETLENGTH             = 651;
+    static final int        PI                      = 652;
+    public static final int QUARTER                 = 653;
+    static final int        RADIANS                 = 654;
+    static final int        RAND                    = 655;
+    static final int        RAWTOHEX                = 656;
+    static final int        REGEXP_MATCHES          = 657;
+    static final int        REPLACE                 = 658;
+    static final int        REVERSE                 = 659;
+    static final int        ROUND                   = 660;
+    static final int        ROUNDMAGIC              = 661;
+    static final int        RTRIM                   = 662;
+    public static final int SECONDS_MIDNIGHT        = 663;
+    static final int        SIGN                    = 664;
+    static final int        SIN                     = 665;
+    static final int        SOUNDEX                 = 666;
+    static final int        SPACE_WORD              = 667;
+    static final int        SUBSTR                  = 668;
+    static final int        SYSDATE                 = 669;
+    static final int        TAN                     = 670;
+    static final int        TIMESTAMPADD            = 671;
+    static final int        TIMESTAMPDIFF           = 672;
+    static final int        TO_CHAR                 = 673;
+    static final int        TODAY                   = 674;
+    static final int        TOP                     = 675;
+    static final int        UCASE                   = 676;
+    static final int        WEEK                    = 677;
+    public static final int WEEK_OF_YEAR            = 678;
+
+    //
+    static final int ISOLATION_LEVEL          = 681;
+    static final int SESSION_ISOLATION_LEVEL  = 682;
+    static final int DATABASE_ISOLATION_LEVEL = 683;
+    static final int TRANSACTION_CONTROL      = 684;
+    static final int TIMEZONE                 = 685;
+    static final int SESSION_TIMEZONE         = 686;
+    static final int DATABASE_TIMEZONE        = 687;
+    static final int DATABASE_VERSION         = 688;
+
+    //
+    static final int        ASTERISK         = 771;
+    static final int        CLOSEBRACKET     = 772;
+    static final int        COLON            = 773;
+    static final int        COMMA            = 774;
+    static final int        CONCAT           = 775;
+    static final int        DIVIDE           = 776;
+    static final int        DOUBLE_COLON_OP  = 777;
+    static final int        DOUBLE_PERIOD_OP = 778;
+    static final int        GREATER          = 779;
+    static final int        GREATER_EQUALS   = 780;
+    static final int        LEFTBRACKET      = 781;
+    static final int        LESS             = 782;
+    static final int        LESS_EQUALS      = 783;
+    public static final int MINUS            = 784;
+    static final int        NOT_EQUALS       = 785;
+    static final int        OPENBRACKET      = 786;
+    static final int        PLUS             = 787;
+    static final int        QUESTION         = 788;
+    static final int        RIGHT_ARROW_OP   = 789;
+    static final int        RIGHTBRACKET     = 790;
+    static final int        SEMICOLON        = 791;
+
+    //
+    static final int SQL_BIGINT        = 801;
+    static final int SQL_BINARY        = 802;
+    static final int SQL_BIT           = 803;
+    static final int SQL_BLOB          = 804;
+    static final int SQL_BOOLEAN       = 805;
+    static final int SQL_CHAR          = 806;
+    static final int SQL_CLOB          = 807;
+    static final int SQL_DATE          = 808;
+    static final int SQL_DECIMAL       = 809;
+    static final int SQL_DATALINK      = 810;
+    static final int SQL_DOUBLE        = 811;
+    static final int SQL_FLOAT         = 812;
+    static final int SQL_INTEGER       = 813;
+    static final int SQL_LONGVARBINARY = 814;
+    static final int SQL_LONGNVARCHAR  = 815;
+    static final int SQL_LONGVARCHAR   = 816;
+    static final int SQL_NCHAR         = 817;
+    static final int SQL_NCLOB         = 818;
+    static final int SQL_NUMERIC       = 819;
+    static final int SQL_NVARCHAR      = 820;
+    static final int SQL_REAL          = 821;
+    static final int SQL_ROWID         = 822;
+    static final int SQL_SQLXML        = 823;
+    static final int SQL_SMALLINT      = 824;
+    static final int SQL_TIME          = 825;
+    static final int SQL_TIMESTAMP     = 826;
+    static final int SQL_TINYINT       = 827;
+    static final int SQL_VARBINARY     = 828;
+    static final int SQL_VARCHAR       = 829;
+
+    //
+    static final int SQL_TSI_FRAC_SECOND = 831;
+    static final int SQL_TSI_SECOND      = 832;
+    static final int SQL_TSI_MINUTE      = 833;
+    static final int SQL_TSI_HOUR        = 834;
+    static final int SQL_TSI_DAY         = 835;
+    static final int SQL_TSI_WEEK        = 836;
+    static final int SQL_TSI_MONTH       = 837;
+    static final int SQL_TSI_QUARTER     = 838;
+    static final int SQL_TSI_YEAR        = 839;
+
+    //
+    static final int X_KEYSET      = 841;
+    static final int X_OPTION      = 842;
+    static final int X_REPEAT      = 843;
+    static final int X_POS_INTEGER = 844;
+
+    //
+    public static final int X_VALUE                    = 845;
+    public static final int X_IDENTIFIER               = 846;
+    public static final int X_DELIMITED_IDENTIFIER     = 847;
+    public static final int X_ENDPARSE                 = 848;
+    public static final int X_STARTPARSE               = 849;
+    public static final int X_REMARK                   = 850;
+    public static final int X_NULL                     = 851;
+    public static final int X_LOB_SIZE                 = 852;
+    public static final int X_MALFORMED_STRING         = 853;
+    public static final int X_MALFORMED_NUMERIC        = 854;
+    public static final int X_MALFORMED_BIT_STRING     = 855;
+    public static final int X_MALFORMED_BINARY_STRING  = 856;
+    public static final int X_MALFORMED_UNICODE_STRING = 857;
+    public static final int X_MALFORMED_COMMENT        = 858;
+    public static final int X_MALFORMED_IDENTIFIER     = 859;
+    public static final int X_MALFORMED_UNICODE_ESCAPE = 860;
+
+    //
+    public static final int X_UNKNOWN_TOKEN = -1;
+    private static final IntValueHashMap reservedKeys =
+        new IntValueHashMap(351);
+
+    static {
+        reservedKeys.put(Tokens.T_ABS, ABS);
+        reservedKeys.put(Tokens.T_AGGREGATE, AGGREGATE);
+        reservedKeys.put(Tokens.T_ALL, ALL);
+        reservedKeys.put(Tokens.T_ALLOCATE, ALLOCATE);
+        reservedKeys.put(Tokens.T_ALTER, ALTER);
+        reservedKeys.put(Tokens.T_AND, AND);
+        reservedKeys.put(Tokens.T_ANY, ANY);
+        reservedKeys.put(Tokens.T_ARE, ARE);
+        reservedKeys.put(Tokens.T_ARRAY, ARRAY);
+        reservedKeys.put(Tokens.T_AS, AS);
+        reservedKeys.put(Tokens.T_ASENSITIVE, ASENSITIVE);
+        reservedKeys.put(Tokens.T_ASYMMETRIC, ASYMMETRIC);
+        reservedKeys.put(Tokens.T_AT, AT);
+        reservedKeys.put(Tokens.T_ATOMIC, ATOMIC);
+        reservedKeys.put(Tokens.T_AUTHORIZATION, AUTHORIZATION);
+        reservedKeys.put(Tokens.T_AVG, AVG);
+        reservedKeys.put(Tokens.T_BEGIN, BEGIN);
+        reservedKeys.put(Tokens.T_BETWEEN, BETWEEN);
+        reservedKeys.put(Tokens.T_BIGINT, BIGINT);
+        reservedKeys.put(Tokens.T_BINARY, BINARY);
+        reservedKeys.put(Tokens.T_BIT_LENGTH, BIT_LENGTH);
+        reservedKeys.put(Tokens.T_BLOB, BLOB);
+        reservedKeys.put(Tokens.T_BOOLEAN, BOOLEAN);
+        reservedKeys.put(Tokens.T_BOTH, BOTH);
+        reservedKeys.put(Tokens.T_BY, BY);
+        reservedKeys.put(Tokens.T_CALL, CALL);
+        reservedKeys.put(Tokens.T_CALLED, CALLED);
+        reservedKeys.put(Tokens.T_CARDINALITY, CARDINALITY);
+        reservedKeys.put(Tokens.T_CASCADED, CASCADED);
+        reservedKeys.put(Tokens.T_CASE, CASE);
+        reservedKeys.put(Tokens.T_CAST, CAST);
+        reservedKeys.put(Tokens.T_CEIL, CEIL);
+        reservedKeys.put(Tokens.T_CEILING, CEILING);
+        reservedKeys.put(Tokens.T_CHAR, CHAR);
+        reservedKeys.put(Tokens.T_CHAR_LENGTH, CHAR_LENGTH);
+        reservedKeys.put(Tokens.T_CHARACTER, CHARACTER);
+        reservedKeys.put(Tokens.T_CHARACTER_LENGTH, CHARACTER_LENGTH);
+        reservedKeys.put(Tokens.T_CHECK, CHECK);
+        reservedKeys.put(Tokens.T_CLOB, CLOB);
+        reservedKeys.put(Tokens.T_CLOSE, CLOSE);
+        reservedKeys.put(Tokens.T_COALESCE, COALESCE);
+        reservedKeys.put(Tokens.T_COLLATE, COLLATE);
+        reservedKeys.put(Tokens.T_COLLECT, COLLECT);
+        reservedKeys.put(Tokens.T_COLUMN, COLUMN);
+        reservedKeys.put(Tokens.T_COMMIT, COMMIT);
+        reservedKeys.put(Tokens.T_COMPARABLE, COMPARABLE);
+        reservedKeys.put(Tokens.T_CONDITION, CONDITION);
+        reservedKeys.put(Tokens.T_CONNECT, CONNECT);
+        reservedKeys.put(Tokens.T_CONSTRAINT, CONSTRAINT);
+        reservedKeys.put(Tokens.T_CONVERT, CONVERT);
+        reservedKeys.put(Tokens.T_CORR, CORR);
+        reservedKeys.put(Tokens.T_CORRESPONDING, CORRESPONDING);
+        reservedKeys.put(Tokens.T_COUNT, COUNT);
+        reservedKeys.put(Tokens.T_COVAR_POP, COVAR_POP);
+        reservedKeys.put(Tokens.T_COVAR_SAMP, COVAR_SAMP);
+        reservedKeys.put(Tokens.T_CREATE, CREATE);
+        reservedKeys.put(Tokens.T_CROSS, CROSS);
+        reservedKeys.put(Tokens.T_CUBE, CUBE);
+        reservedKeys.put(Tokens.T_CUME_DIST, CUME_DIST);
+        reservedKeys.put(Tokens.T_CURRENT, CURRENT);
+        reservedKeys.put(Tokens.T_CURRENT_CATALOG, CURRENT_CATALOG);
+        reservedKeys.put(Tokens.T_CURRENT_DATE, CURRENT_DATE);
+        reservedKeys.put(Tokens.T_CURRENT_DEFAULT_TRANSFORM_GROUP,
+                         CURRENT_DEFAULT_TRANSFORM_GROUP);
+        reservedKeys.put(Tokens.T_CURRENT_PATH, CURRENT_PATH);
+        reservedKeys.put(Tokens.T_CURRENT_ROLE, CURRENT_ROLE);
+        reservedKeys.put(Tokens.T_CURRENT_SCHEMA, CURRENT_SCHEMA);
+        reservedKeys.put(Tokens.T_CURRENT_TIME, CURRENT_TIME);
+        reservedKeys.put(Tokens.T_CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
+        reservedKeys.put(Tokens.T_DO, DO);
+        reservedKeys.put(Tokens.T_CURRENT_TRANSFORM_GROUP_FOR_TYPE,
+                         CURRENT_TRANSFORM_GROUP_FOR_TYPE);
+        reservedKeys.put(Tokens.T_CURRENT_USER, CURRENT_USER);
+        reservedKeys.put(Tokens.T_CURSOR, CURSOR);
+        reservedKeys.put(Tokens.T_CYCLE, CYCLE);
+        reservedKeys.put(Tokens.T_DATE, DATE);
+        reservedKeys.put(Tokens.T_DAY, DAY);
+        reservedKeys.put(Tokens.T_DEALLOCATE, DEALLOCATE);
+        reservedKeys.put(Tokens.T_DEC, DEC);
+        reservedKeys.put(Tokens.T_DECIMAL, DECIMAL);
+        reservedKeys.put(Tokens.T_DECLARE, DECLARE);
+        reservedKeys.put(Tokens.T_DEFAULT, DEFAULT);
+        reservedKeys.put(Tokens.T_DELETE, DELETE);
+        reservedKeys.put(Tokens.T_DENSE_RANK, DENSE_RANK);
+        reservedKeys.put(Tokens.T_DEREF, DEREF);
+        reservedKeys.put(Tokens.T_DESCRIBE, DESCRIBE);
+        reservedKeys.put(Tokens.T_DETERMINISTIC, DETERMINISTIC);
+        reservedKeys.put(Tokens.T_DISCONNECT, DISCONNECT);
+        reservedKeys.put(Tokens.T_DISTINCT, DISTINCT);
+        reservedKeys.put(Tokens.T_DOUBLE, DOUBLE);
+        reservedKeys.put(Tokens.T_DROP, DROP);
+        reservedKeys.put(Tokens.T_DYNAMIC, DYNAMIC);
+        reservedKeys.put(Tokens.T_EACH, EACH);
+        reservedKeys.put(Tokens.T_ELEMENT, ELEMENT);
+        reservedKeys.put(Tokens.T_ELSE, ELSE);
+        reservedKeys.put(Tokens.T_ELSEIF, ELSEIF);
+        reservedKeys.put(Tokens.T_END, END);
+        reservedKeys.put(Tokens.T_END_EXEC, END_EXEC);
+        reservedKeys.put(Tokens.T_ESCAPE, ESCAPE);
+        reservedKeys.put(Tokens.T_EVERY, EVERY);
+        reservedKeys.put(Tokens.T_EXCEPT, EXCEPT);
+        reservedKeys.put(Tokens.T_EXEC, EXEC);
+        reservedKeys.put(Tokens.T_EXECUTE, EXECUTE);
+        reservedKeys.put(Tokens.T_EXISTS, EXISTS);
+        reservedKeys.put(Tokens.T_EXIT, EXIT);
+        reservedKeys.put(Tokens.T_EXP, EXP);
+        reservedKeys.put(Tokens.T_EXTERNAL, EXTERNAL);
+        reservedKeys.put(Tokens.T_EXTRACT, EXTRACT);
+        reservedKeys.put(Tokens.T_FALSE, FALSE);
+        reservedKeys.put(Tokens.T_FETCH, FETCH);
+        reservedKeys.put(Tokens.T_FILTER, FILTER);
+        reservedKeys.put(Tokens.T_FIRST_VALUE, FIRST_VALUE);
+        reservedKeys.put(Tokens.T_FLOAT, FLOAT);
+        reservedKeys.put(Tokens.T_FLOOR, FLOOR);
+        reservedKeys.put(Tokens.T_FOR, FOR);
+        reservedKeys.put(Tokens.T_FOREIGN, FOREIGN);
+        reservedKeys.put(Tokens.T_FREE, FREE);
+        reservedKeys.put(Tokens.T_FROM, FROM);
+        reservedKeys.put(Tokens.T_FULL, FULL);
+        reservedKeys.put(Tokens.T_FUNCTION, FUNCTION);
+        reservedKeys.put(Tokens.T_FUSION, FUSION);
+        reservedKeys.put(Tokens.T_GET, GET);
+        reservedKeys.put(Tokens.T_GLOBAL, GLOBAL);
+        reservedKeys.put(Tokens.T_GRANT, GRANT);
+        reservedKeys.put(Tokens.T_GROUP, GROUP);
+        reservedKeys.put(Tokens.T_GROUPING, GROUPING);
+        reservedKeys.put(Tokens.T_HANDLER, HANDLER);
+        reservedKeys.put(Tokens.T_HAVING, HAVING);
+        reservedKeys.put(Tokens.T_HOLD, HOLD);
+        reservedKeys.put(Tokens.T_HOUR, HOUR);
+        reservedKeys.put(Tokens.T_IDENTITY, IDENTITY);
+        reservedKeys.put(Tokens.T_IF, IF);
+        reservedKeys.put(Tokens.T_IMPORT, IMPORT);
+        reservedKeys.put(Tokens.T_IN, IN);
+        reservedKeys.put(Tokens.T_INDICATOR, INDICATOR);
+        reservedKeys.put(Tokens.T_INNER, INNER);
+        reservedKeys.put(Tokens.T_INOUT, INOUT);
+        reservedKeys.put(Tokens.T_INSENSITIVE, INSENSITIVE);
+        reservedKeys.put(Tokens.T_INSERT, INSERT);
+        reservedKeys.put(Tokens.T_INT, INT);
+        reservedKeys.put(Tokens.T_INTEGER, INTEGER);
+        reservedKeys.put(Tokens.T_INTERSECT, INTERSECT);
+        reservedKeys.put(Tokens.T_INTERSECTION, INTERSECTION);
+        reservedKeys.put(Tokens.T_INTERVAL, INTERVAL);
+        reservedKeys.put(Tokens.T_INTO, INTO);
+        reservedKeys.put(Tokens.T_IS, IS);
+        reservedKeys.put(Tokens.T_ITERATE, ITERATE);
+        reservedKeys.put(Tokens.T_JOIN, JOIN);
+        reservedKeys.put(Tokens.T_LAG, LAG);
+        reservedKeys.put(Tokens.T_LANGUAGE, LANGUAGE);
+        reservedKeys.put(Tokens.T_LARGE, LARGE);
+        reservedKeys.put(Tokens.T_LAST_VALUE, LAST_VALUE);
+        reservedKeys.put(Tokens.T_LATERAL, LATERAL);
+        reservedKeys.put(Tokens.T_LEAD, LEAD);
+        reservedKeys.put(Tokens.T_LEADING, LEADING);
+        reservedKeys.put(Tokens.T_LEAVE, LEAVE);
+        reservedKeys.put(Tokens.T_LEFT, LEFT);
+        reservedKeys.put(Tokens.T_LIKE, LIKE);
+        reservedKeys.put(Tokens.T_LIKE_REGX, LIKE_REGEX);
+        reservedKeys.put(Tokens.T_LN, LN);
+        reservedKeys.put(Tokens.T_LOCAL, LOCAL);
+        reservedKeys.put(Tokens.T_LOCALTIME, LOCALTIME);
+        reservedKeys.put(Tokens.T_LOCALTIMESTAMP, LOCALTIMESTAMP);
+        reservedKeys.put(Tokens.T_LOOP, LOOP);
+        reservedKeys.put(Tokens.T_LOWER, LOWER);
+        reservedKeys.put(Tokens.T_MATCH, MATCH);
+        reservedKeys.put(Tokens.T_MAX, MAX);
+        reservedKeys.put(Tokens.T_MAX_CARDINALITY, MAX_CARDINALITY);
+        reservedKeys.put(Tokens.T_MEMBER, MEMBER);
+        reservedKeys.put(Tokens.T_MERGE, MERGE);
+        reservedKeys.put(Tokens.T_METHOD, METHOD);
+        reservedKeys.put(Tokens.T_MIN, MIN);
+        reservedKeys.put(Tokens.T_MINUTE, MINUTE);
+        reservedKeys.put(Tokens.T_MOD, MOD);
+        reservedKeys.put(Tokens.T_MODIFIES, MODIFIES);
+        reservedKeys.put(Tokens.T_MODULE, MODULE);
+        reservedKeys.put(Tokens.T_MONTH, MONTH);
+        reservedKeys.put(Tokens.T_MULTISET, MULTISET);
+        reservedKeys.put(Tokens.T_NATIONAL, NATIONAL);
+        reservedKeys.put(Tokens.T_NATURAL, NATURAL);
+        reservedKeys.put(Tokens.T_NCHAR, NCHAR);
+        reservedKeys.put(Tokens.T_NCLOB, NCLOB);
+        reservedKeys.put(Tokens.T_NEW, NEW);
+        reservedKeys.put(Tokens.T_NO, NO);
+        reservedKeys.put(Tokens.T_NONE, NONE);
+        reservedKeys.put(Tokens.T_NORMALIZE, NORMALIZE);
+        reservedKeys.put(Tokens.T_NOT, NOT);
+        reservedKeys.put(Tokens.T_NTH_VALUE, NTH_VALUE);
+        reservedKeys.put(Tokens.T_NTILE, NTILE);
+        reservedKeys.put(Tokens.T_NULL, NULL);
+        reservedKeys.put(Tokens.T_NULLIF, NULLIF);
+        reservedKeys.put(Tokens.T_NUMERIC, NUMERIC);
+        reservedKeys.put(Tokens.T_OCCURRENCES_REGEX, OCCURRENCES_REGEX);
+        reservedKeys.put(Tokens.T_OCTET_LENGTH, OCTET_LENGTH);
+        reservedKeys.put(Tokens.T_OF, OF);
+        reservedKeys.put(Tokens.T_OFFSET, OFFSET);
+        reservedKeys.put(Tokens.T_OLD, OLD);
+        reservedKeys.put(Tokens.T_ON, ON);
+        reservedKeys.put(Tokens.T_ONLY, ONLY);
+        reservedKeys.put(Tokens.T_OPEN, OPEN);
+        reservedKeys.put(Tokens.T_OR, OR);
+        reservedKeys.put(Tokens.T_ORDER, ORDER);
+        reservedKeys.put(Tokens.T_OUT, OUT);
+        reservedKeys.put(Tokens.T_OUTER, OUTER);
+        reservedKeys.put(Tokens.T_OVER, OVER);
+        reservedKeys.put(Tokens.T_OVERLAPS, OVERLAPS);
+        reservedKeys.put(Tokens.T_OVERLAY, OVERLAY);
+        reservedKeys.put(Tokens.T_PARAMETER, PARAMETER);
+        reservedKeys.put(Tokens.T_PARTITION, PARTITION);
+        reservedKeys.put(Tokens.T_PERCENT_RANK, PERCENT_RANK);
+        reservedKeys.put(Tokens.T_PERCENTILE_CONT, PERCENTILE_CONT);
+        reservedKeys.put(Tokens.T_PERCENTILE_DISC, PERCENTILE_DISC);
+        reservedKeys.put(Tokens.T_POSITION, POSITION);
+        reservedKeys.put(Tokens.T_POSITION_REGEX, POSITION_REGEX);
+        reservedKeys.put(Tokens.T_POWER, POWER);
+        reservedKeys.put(Tokens.T_PRECISION, PRECISION);
+        reservedKeys.put(Tokens.T_PREPARE, PREPARE);
+        reservedKeys.put(Tokens.T_PRIMARY, PRIMARY);
+        reservedKeys.put(Tokens.T_PROCEDURE, PROCEDURE);
+        reservedKeys.put(Tokens.T_RANGE, RANGE);
+        reservedKeys.put(Tokens.T_RANK, RANK);
+        reservedKeys.put(Tokens.T_READS, READS);
+        reservedKeys.put(Tokens.T_REAL, REAL);
+        reservedKeys.put(Tokens.T_RECURSIVE, RECURSIVE);
+        reservedKeys.put(Tokens.T_REF, REF);
+        reservedKeys.put(Tokens.T_REFERENCES, REFERENCES);
+        reservedKeys.put(Tokens.T_REFERENCING, REFERENCING);
+        reservedKeys.put(Tokens.T_REGR_AVGX, REGR_AVGX);
+        reservedKeys.put(Tokens.T_REGR_AVGY, REGR_AVGY);
+        reservedKeys.put(Tokens.T_REGR_COUNT, REGR_COUNT);
+        reservedKeys.put(Tokens.T_REGR_INTERCEPT, REGR_INTERCEPT);
+        reservedKeys.put(Tokens.T_REGR_R2, REGR_R2);
+        reservedKeys.put(Tokens.T_REGR_SLOPE, REGR_SLOPE);
+        reservedKeys.put(Tokens.T_REGR_SXX, REGR_SXX);
+        reservedKeys.put(Tokens.T_REGR_SXY, REGR_SXY);
+        reservedKeys.put(Tokens.T_REGR_SYY, REGR_SYY);
+        reservedKeys.put(Tokens.T_RELEASE, RELEASE);
+        reservedKeys.put(Tokens.T_REPEAT, REPEAT);
+        reservedKeys.put(Tokens.T_RESIGNAL, RESIGNAL);
+        reservedKeys.put(Tokens.T_RETURN, RETURN);
+        reservedKeys.put(Tokens.T_RETURNS, RETURNS);
+        reservedKeys.put(Tokens.T_REVOKE, REVOKE);
+        reservedKeys.put(Tokens.T_RIGHT, RIGHT);
+        reservedKeys.put(Tokens.T_ROLLBACK, ROLLBACK);
+        reservedKeys.put(Tokens.T_ROLLUP, ROLLUP);
+        reservedKeys.put(Tokens.T_ROW, ROW);
+        reservedKeys.put(Tokens.T_ROW_NUMBER, ROW_NUMBER);
+        reservedKeys.put(Tokens.T_ROWS, ROWS);
+        reservedKeys.put(Tokens.T_SAVEPOINT, SAVEPOINT);
+        reservedKeys.put(Tokens.T_SCOPE, SCOPE);
+        reservedKeys.put(Tokens.T_SCROLL, SCROLL);
+        reservedKeys.put(Tokens.T_SEARCH, SEARCH);
+        reservedKeys.put(Tokens.T_SECOND, SECOND);
+        reservedKeys.put(Tokens.T_SELECT, SELECT);
+        reservedKeys.put(Tokens.T_SENSITIVE, SENSITIVE);
+        reservedKeys.put(Tokens.T_SESSION_USER, SESSION_USER);
+        reservedKeys.put(Tokens.T_SET, SET);
+        reservedKeys.put(Tokens.T_SIGNAL, SIGNAL);
+        reservedKeys.put(Tokens.T_SIMILAR, SIMILAR);
+        reservedKeys.put(Tokens.T_SMALLINT, SMALLINT);
+        reservedKeys.put(Tokens.T_SOME, SOME);
+        reservedKeys.put(Tokens.T_SPECIFIC, SPECIFIC);
+        reservedKeys.put(Tokens.T_SPECIFICTYPE, SPECIFICTYPE);
+        reservedKeys.put(Tokens.T_SQL, SQL);
+        reservedKeys.put(Tokens.T_SQLEXCEPTION, SQLEXCEPTION);
+        reservedKeys.put(Tokens.T_SQLSTATE, SQLSTATE);
+        reservedKeys.put(Tokens.T_SQLWARNING, SQLWARNING);
+        reservedKeys.put(Tokens.T_SQRT, SQRT);
+        reservedKeys.put(Tokens.T_STACKED, STACKED);
+        reservedKeys.put(Tokens.T_START, START);
+        reservedKeys.put(Tokens.T_STATIC, STATIC);
+        reservedKeys.put(Tokens.T_STDDEV_POP, STDDEV_POP);
+        reservedKeys.put(Tokens.T_STDDEV_SAMP, STDDEV_SAMP);
+        reservedKeys.put(Tokens.T_SUBMULTISET, SUBMULTISET);
+        reservedKeys.put(Tokens.T_SUBSTRING, SUBSTRING);
+        reservedKeys.put(Tokens.T_SUBSTRING_REGEX, SUBSTRING_REGEX);
+        reservedKeys.put(Tokens.T_SUM, SUM);
+        reservedKeys.put(Tokens.T_SYMMETRIC, SYMMETRIC);
+        reservedKeys.put(Tokens.T_SYSTEM, SYSTEM);
+        reservedKeys.put(Tokens.T_SYSTEM_USER, SYSTEM_USER);
+        reservedKeys.put(Tokens.T_TABLE, TABLE);
+        reservedKeys.put(Tokens.T_TABLESAMPLE, TABLESAMPLE);
+        reservedKeys.put(Tokens.T_THEN, THEN);
+        reservedKeys.put(Tokens.T_TIME, TIME);
+        reservedKeys.put(Tokens.T_TIMESTAMP, TIMESTAMP);
+        reservedKeys.put(Tokens.T_TIMEZONE_HOUR, TIMEZONE_HOUR);
+        reservedKeys.put(Tokens.T_TIMEZONE_MINUTE, TIMEZONE_MINUTE);
+        reservedKeys.put(Tokens.T_TO, TO);
+        reservedKeys.put(Tokens.T_TRAILING, TRAILING);
+        reservedKeys.put(Tokens.T_TRANSLATE, TRANSLATE);
+        reservedKeys.put(Tokens.T_TRANSLATE_REGEX, TRANSLATE_REGEX);
+        reservedKeys.put(Tokens.T_TRANSLATION, TRANSLATION);
+        reservedKeys.put(Tokens.T_TREAT, TREAT);
+        reservedKeys.put(Tokens.T_TRIGGER, TRIGGER);
+        reservedKeys.put(Tokens.T_TRIM, TRIM);
+        reservedKeys.put(Tokens.T_TRIM_ARRAY, TRIM_ARRAY);
+        reservedKeys.put(Tokens.T_TRUE, TRUE);
+        reservedKeys.put(Tokens.T_TRUNCATE, TRUNCATE);
+        reservedKeys.put(Tokens.T_UESCAPE, UESCAPE);
+        reservedKeys.put(Tokens.T_UNDO, UNDO);
+        reservedKeys.put(Tokens.T_UNION, UNION);
+        reservedKeys.put(Tokens.T_UNIQUE, UNIQUE);
+        reservedKeys.put(Tokens.T_UNKNOWN, UNKNOWN);
+        reservedKeys.put(Tokens.T_UNNEST, UNNEST);
+        reservedKeys.put(Tokens.T_UNTIL, UNTIL);
+        reservedKeys.put(Tokens.T_UPDATE, UPDATE);
+        reservedKeys.put(Tokens.T_UPPER, UPPER);
+        reservedKeys.put(Tokens.T_USER, USER);
+        reservedKeys.put(Tokens.T_USING, USING);
+        reservedKeys.put(Tokens.T_VALUE, VALUE);
+        reservedKeys.put(Tokens.T_VALUES, VALUES);
+        reservedKeys.put(Tokens.T_VAR_POP, VAR_POP);
+        reservedKeys.put(Tokens.T_VAR_SAMP, VAR_SAMP);
+        reservedKeys.put(Tokens.T_VARBINARY, VARBINARY);
+        reservedKeys.put(Tokens.T_VARCHAR, VARCHAR);
+        reservedKeys.put(Tokens.T_VARYING, VARYING);
+        reservedKeys.put(Tokens.T_WHEN, WHEN);
+        reservedKeys.put(Tokens.T_WHENEVER, WHENEVER);
+        reservedKeys.put(Tokens.T_WHERE, WHERE);
+        reservedKeys.put(Tokens.T_WIDTH_BUCKET, WIDTH_BUCKET);
+        reservedKeys.put(Tokens.T_WINDOW, WINDOW);
+        reservedKeys.put(Tokens.T_WITH, WITH);
+        reservedKeys.put(Tokens.T_WITHIN, WITHIN);
+        reservedKeys.put(Tokens.T_WITHOUT, WITHOUT);
+        reservedKeys.put(Tokens.T_WHILE, WHILE);
+        reservedKeys.put(Tokens.T_YEAR, YEAR);
+    }
+
+    private static final IntValueHashMap commandSet = new IntValueHashMap(251);
+
+    static {
+        commandSet.put(T_ACTION, ACTION);
+        commandSet.put(T_ADD, ADD);
+        commandSet.put(T_ADMIN, ADMIN);
+        commandSet.put(T_AFTER, AFTER);
+        commandSet.put(T_ALIAS, ALIAS);
+        commandSet.put(T_ALWAYS, ALWAYS);
+        commandSet.put(T_ASC, ASC);
+        commandSet.put(T_AUTOCOMMIT, AUTOCOMMIT);
+        commandSet.put(T_BACKUP, BACKUP);
+        commandSet.put(T_BEFORE, BEFORE);
+        commandSet.put(T_BIT, BIT);
+        commandSet.put(T_BLOCKING, BLOCKING);
+        commandSet.put(T_CACHE, CACHE);
+        commandSet.put(T_CACHED, CACHED);
+        commandSet.put(T_CASCADE, CASCADE);
+        commandSet.put(T_CATALOG, CATALOG);
+        commandSet.put(T_CHARACTERISTICS, CHARACTERISTICS);
+        commandSet.put(T_CHECKPOINT, CHECKPOINT);
+        commandSet.put(T_CRYPT_KEY, CRYPT_KEY);
+        commandSet.put(T_CLASS, CLASS);
+        commandSet.put(T_COLLATE, COLLATE);
+        commandSet.put(T_COLLATION, COLLATION);
+        commandSet.put(T_COMMENT, COMMENT);
+        commandSet.put(T_COMMITTED, COMMITTED);
+        commandSet.put(T_COMPACT, COMPACT);
+        commandSet.put(T_COMPRESSED, COMPRESSED);
+        commandSet.put(T_CONDITION_IDENTIFIER, Tokens.CONDITION_IDENTIFIER);
+        commandSet.put(T_CONTAINS, CONTAINS);
+        commandSet.put(T_CONTINUE, CONTINUE);
+        commandSet.put(T_CONTROL, CONTROL);
+        commandSet.put(T_CURDATE, CURDATE);
+        commandSet.put(T_CURTIME, CURTIME);
+        commandSet.put(T_DATA, DATA);
+        commandSet.put(T_DATABASE, DATABASE);
+        commandSet.put(T_DEFAULTS, DEFAULTS);
+        commandSet.put(T_DEFRAG, DEFRAG);
+        commandSet.put(T_DELAY, DELAY);
+        commandSet.put(T_DESC, DESC);
+        commandSet.put(T_DOMAIN, DOMAIN);
+        commandSet.put(T_EVENT, EVENT);
+        commandSet.put(T_EXCLUDING, EXCLUDING);
+        commandSet.put(T_EXPLAIN, EXPLAIN);
+        commandSet.put(T_FILE, FILE);
+        commandSet.put(T_FILES, FILES);
+        commandSet.put(T_FINAL, FINAL);
+        commandSet.put(T_FIRST, FIRST);
+        commandSet.put(T_G_FACTOR, G);
+        commandSet.put(T_GC, GC);
+        commandSet.put(T_GENERATED, GENERATED);
+        commandSet.put(T_GRANTED, GRANTED);
+        commandSet.put(T_HEADER, HEADER);
+        commandSet.put(T_IF, Tokens.IF);
+        commandSet.put(T_IGNORECASE, IGNORECASE);
+        commandSet.put(T_IMMEDIATELY, IMMEDIATELY);
+        commandSet.put(T_INCLUDING, INCLUDING);
+        commandSet.put(T_INCREMENT, INCREMENT);
+        commandSet.put(T_INDEX, INDEX);
+        commandSet.put(T_INITIAL, INITIAL);
+        commandSet.put(T_INPUT, INPUT);
+        commandSet.put(T_INSTEAD, INSTEAD);
+        commandSet.put(T_INTEGRITY, INTEGRITY);
+        commandSet.put(T_ISAUTOCOMMIT, ISAUTOCOMMIT);
+        commandSet.put(T_ISOLATION, ISOLATION);
+        commandSet.put(T_ISREADONLYDATABASE, ISREADONLYDATABASE);
+        commandSet.put(T_ISREADONLYDATABASEFILES, ISREADONLYDATABASEFILES);
+        commandSet.put(T_ISREADONLYSESSION, ISREADONLYSESSION);
+        commandSet.put(T_JAVA, JAVA);
+        commandSet.put(T_K_FACTOR, K);
+        commandSet.put(T_KEY, KEY);
+        commandSet.put(T_LAST, LAST);
+        commandSet.put(T_LENGTH, LENGTH);
+        commandSet.put(T_LEVEL, LEVEL);
+        commandSet.put(T_LIBRARY, LIBRARY);
+        commandSet.put(T_LIMIT, LIMIT);
+        commandSet.put(T_LOB, LOB);
+        commandSet.put(T_LOCK, LOCK);
+        commandSet.put(T_LOCKS, LOCKS);
+        commandSet.put(T_M_FACTOR, M);
+        commandSet.put(T_MATCHED, MATCHED);
+        commandSet.put(T_MAXROWS, MAXROWS);
+        commandSet.put(T_MAXVALUE, MAXVALUE);
+        commandSet.put(T_MEMORY, MEMORY);
+        commandSet.put(T_MILLIS, MILLIS);
+        commandSet.put(T_MINUS_EXCEPT, MINUS_EXCEPT);
+        commandSet.put(T_MINVALUE, MINVALUE);
+        commandSet.put(T_MVCC, MVCC);
+        commandSet.put(T_MVLOCKS, MVLOCKS);
+        commandSet.put(T_NAME, NAME);
+        commandSet.put(T_NEXT, NEXT);
+        commandSet.put(T_NIO, NIO);
+        commandSet.put(T_NOW, NOW);
+        commandSet.put(T_NULLS, NULLS);
+        commandSet.put(T_OFF, OFF);
+        commandSet.put(T_OPTION, OPTION);
+        commandSet.put(T_ORDINALITY, ORDINALITY);
+        commandSet.put(T_OVERRIDING, OVERRIDING);
+        commandSet.put(T_P_FACTOR, P);
+        commandSet.put(T_PARTIAL, PARTIAL);
+        commandSet.put(T_PASSWORD, PASSWORD);
+        commandSet.put(T_PLACING, PLACING);
+        commandSet.put(T_PLAN, PLAN);
+        commandSet.put(T_PRESERVE, PRESERVE);
+        commandSet.put(T_PRIVILEGES, PRIVILEGES);
+        commandSet.put(T_PROPERTY, PROPERTY);
+        commandSet.put(T_READ, READ);
+        commandSet.put(T_READONLY, READONLY);
+        commandSet.put(T_REFERENTIAL, REFERENTIAL);
+        commandSet.put(T_RENAME, RENAME);
+        commandSet.put(T_REPEATABLE, REPEATABLE);
+        commandSet.put(T_RESTART, RESTART);
+        commandSet.put(T_RESTRICT, RESTRICT);
+        commandSet.put(T_RESULT, RESULT);
+        commandSet.put(T_ROLE, ROLE);
+        commandSet.put(T_ROUTINE, ROUTINE);
+        commandSet.put(T_SCALE, SCALE);
+        commandSet.put(T_SCHEMA, SCHEMA);
+        commandSet.put(T_SCRIPT, SCRIPT);
+        commandSet.put(T_SCRIPTFORMAT, SCRIPTFORMAT);
+        commandSet.put(T_SEQUENCE, SEQUENCE);
+        commandSet.put(T_SERIALIZABLE, SERIALIZABLE);
+        commandSet.put(T_SERVER, SERVER);
+        commandSet.put(T_SESSION, SESSION);
+        commandSet.put(T_SHUTDOWN, SHUTDOWN);
+        commandSet.put(T_SIMPLE, SIMPLE);
+        commandSet.put(T_SIZE, SIZE);
+        commandSet.put(T_SOURCE, SOURCE);
+        commandSet.put(T_SQL_BIGINT, SQL_BIGINT);
+        commandSet.put(T_SQL_BINARY, SQL_BINARY);
+        commandSet.put(T_SQL_BIT, SQL_BIT);
+        commandSet.put(T_SQL_BLOB, SQL_BLOB);
+        commandSet.put(T_SQL_BOOLEAN, SQL_BOOLEAN);
+        commandSet.put(T_SQL_CHAR, SQL_CHAR);
+        commandSet.put(T_SQL_CLOB, SQL_CLOB);
+        commandSet.put(T_SQL_DATALINK, SQL_DATALINK);
+        commandSet.put(T_SQL_DATE, SQL_DATE);
+        commandSet.put(T_SQL_DECIMAL, SQL_DECIMAL);
+        commandSet.put(T_SQL_DOUBLE, SQL_DOUBLE);
+        commandSet.put(T_SQL_FLOAT, SQL_FLOAT);
+        commandSet.put(T_SQL_INTEGER, SQL_INTEGER);
+        commandSet.put(T_SQL_LONGNVARCHAR, SQL_LONGNVARCHAR);
+        commandSet.put(T_SQL_LONGVARBINARY, SQL_LONGVARBINARY);
+        commandSet.put(T_SQL_LONGVARCHAR, SQL_LONGVARCHAR);
+        commandSet.put(T_SQL_NCHAR, SQL_NCHAR);
+        commandSet.put(T_SQL_NCLOB, SQL_NCLOB);
+        commandSet.put(T_SQL_NUMERIC, SQL_NUMERIC);
+        commandSet.put(T_SQL_NVARCHAR, SQL_NVARCHAR);
+        commandSet.put(T_SQL_REAL, SQL_REAL);
+        commandSet.put(T_SQL_ROWID, SQL_ROWID);
+        commandSet.put(T_SQL_SMALLINT, SQL_SMALLINT);
+        commandSet.put(T_SQL_SQLXML, SQL_SQLXML);
+        commandSet.put(T_SQL_TIME, SQL_TIME);
+        commandSet.put(T_SQL_TIMESTAMP, SQL_TIMESTAMP);
+        commandSet.put(T_SQL_TINYINT, SQL_TINYINT);
+        commandSet.put(T_SQL_VARBINARY, SQL_VARBINARY);
+        commandSet.put(T_SQL_VARCHAR, SQL_VARCHAR);
+        commandSet.put(T_SQL_TSI_DAY, SQL_TSI_DAY);
+        commandSet.put(T_SQL_TSI_FRAC_SECOND, SQL_TSI_FRAC_SECOND);
+        commandSet.put(T_SQL_TSI_HOUR, SQL_TSI_HOUR);
+        commandSet.put(T_SQL_TSI_MINUTE, SQL_TSI_MINUTE);
+        commandSet.put(T_SQL_TSI_MONTH, SQL_TSI_MONTH);
+        commandSet.put(T_SQL_TSI_QUARTER, SQL_TSI_QUARTER);
+        commandSet.put(T_SQL_TSI_SECOND, SQL_TSI_SECOND);
+        commandSet.put(T_SQL_TSI_WEEK, SQL_TSI_WEEK);
+        commandSet.put(T_SQL_TSI_YEAR, SQL_TSI_YEAR);
+        commandSet.put(T_STATEMENT, STATEMENT);
+        commandSet.put(T_STYLE, STYLE);
+        commandSet.put(T_T_FACTOR, T);
+        commandSet.put(T_TEMP, TEMP);
+        commandSet.put(T_TEMPORARY, TEMPORARY);
+        commandSet.put(T_TEXT, TEXT);
+        commandSet.put(T_TIMESTAMPADD, TIMESTAMPADD);
+        commandSet.put(T_TIMESTAMPDIFF, TIMESTAMPDIFF);
+        commandSet.put(T_TO_CHAR, TO_CHAR);
+        commandSet.put(T_TODAY, TODAY);
+        commandSet.put(T_TOP, TOP);
+        commandSet.put(T_TRANSACTION, TRANSACTION);
+        commandSet.put(T_TYPE, TYPE);
+        commandSet.put(T_UNCOMMITTED, UNCOMMITTED);
+        commandSet.put(T_USAGE, USAGE);
+        commandSet.put(T_VIEW, VIEW);
+        commandSet.put(T_WORK, WORK);
+        commandSet.put(T_WRAPPER, WRAPPER);
+        commandSet.put(T_WRITE, WRITE);
+        commandSet.put(T_WRITE_DELAY, WRITE_DELAY);
+        commandSet.put(T_ZONE, ZONE);
+
+        //
+        commandSet.put(T_ACOS, ACOS);
+        commandSet.put(T_ASCII, ASCII);
+        commandSet.put(T_ASIN, ASIN);
+        commandSet.put(T_ATAN, ATAN);
+        commandSet.put(T_ATAN2, ATAN2);
+        commandSet.put(T_BITAND, BITAND);
+        commandSet.put(T_BITLENGTH, BITLENGTH);
+        commandSet.put(T_BITOR, BITOR);
+        commandSet.put(T_BITXOR, BITXOR);
+        commandSet.put(T_CASEWHEN, Tokens.CASEWHEN);
+        commandSet.put(T_CONCAT_WORD, CONCAT_WORD);
+        commandSet.put(T_COS, COS);
+        commandSet.put(T_COT, COT);
+        commandSet.put(T_DATEADD, DATEADD);
+        commandSet.put(T_DATEDIFF, DATEDIFF);
+        commandSet.put(T_DAY_NAME, DAY_NAME);
+        commandSet.put(T_DAY_OF_MONTH, DAY_OF_MONTH);
+        commandSet.put(T_DAY_OF_WEEK, DAY_OF_WEEK);
+        commandSet.put(T_DAY_OF_YEAR, DAY_OF_YEAR);
+        commandSet.put(T_DAYNAME, DAYNAME);
+        commandSet.put(T_DAYOFMONTH, DAYOFMONTH);
+        commandSet.put(T_DAYOFWEEK, DAYOFWEEK);
+        commandSet.put(T_DAYOFYEAR, DAYOFYEAR);
+        commandSet.put(T_DECODE, DECODE);
+        commandSet.put(T_DEGREES, DEGREES);
+        commandSet.put(T_DIFFERENCE, DIFFERENCE);
+        commandSet.put(T_DMOD, DMOD);
+        commandSet.put(T_GREATEST, GREATEST);
+        commandSet.put(T_HEXTORAW, HEXTORAW);
+        commandSet.put(T_IFNULL, Tokens.IFNULL);
+        commandSet.put(T_LCASE, LCASE);
+        commandSet.put(T_LEAST, LEAST);
+        commandSet.put(T_LOCATE, LOCATE);
+        commandSet.put(T_LOG, LOG);
+        commandSet.put(T_LOG10, LOG10);
+        commandSet.put(T_LTRIM, LTRIM);
+        commandSet.put(T_MONTH_NAME, MONTH_NAME);
+        commandSet.put(T_MONTHNAME, MONTHNAME);
+        commandSet.put(T_NAMES, Tokens.NAMES);
+        commandSet.put(T_NVL, Tokens.IFNULL);
+        commandSet.put(T_OCTETLENGTH, OCTETLENGTH);
+        commandSet.put(T_PI, PI);
+        commandSet.put(T_QUARTER, QUARTER);
+        commandSet.put(T_RADIANS, RADIANS);
+        commandSet.put(T_RAND, RAND);
+        commandSet.put(T_RAWTOHEX, RAWTOHEX);
+        commandSet.put(T_REGEXP_MATCHES, REGEXP_MATCHES);
+        commandSet.put(T_REPLACE, REPLACE);
+        commandSet.put(T_REVERSE, REVERSE);
+        commandSet.put(T_ROUND, ROUND);
+        commandSet.put(T_ROUNDMAGIC, ROUNDMAGIC);
+        commandSet.put(T_RTRIM, RTRIM);
+        commandSet.put(T_SECONDS_MIDNIGHT, SECONDS_MIDNIGHT);
+        commandSet.put(T_SIGN, SIGN);
+        commandSet.put(T_SIN, SIN);
+        commandSet.put(T_SOUNDEX, SOUNDEX);
+        commandSet.put(T_SPACE, SPACE);
+        commandSet.put(T_SUBSTR, SUBSTR);
+        commandSet.put(T_SYSDATE, SYSDATE);
+        commandSet.put(T_TAN, TAN);
+        commandSet.put(T_UCASE, UCASE);
+        commandSet.put(T_WEEK, WEEK);
+        commandSet.put(T_WEEK_OF_YEAR, WEEK_OF_YEAR);
+
+        //
+        commandSet.put(T_ISOLATION_LEVEL, ISOLATION_LEVEL);
+        commandSet.put(T_SESSION_ISOLATION_LEVEL, SESSION_ISOLATION_LEVEL);
+        commandSet.put(T_DATABASE_ISOLATION_LEVEL, DATABASE_ISOLATION_LEVEL);
+        commandSet.put(T_TRANSACTION_CONTROL, TRANSACTION_CONTROL);
+        commandSet.put(T_TIMEZONE, TIMEZONE);
+        commandSet.put(T_SESSION_TIMEZONE, SESSION_TIMEZONE);
+        commandSet.put(T_DATABASE_TIMEZONE, DATABASE_TIMEZONE);
+        commandSet.put(T_DATABASE_VERSION, DATABASE_VERSION);
+
+        //
+        commandSet.put(T_ASTERISK, Tokens.ASTERISK);
+        commandSet.put(T_CLOSEBRACKET, CLOSEBRACKET);
+        commandSet.put(T_COLON, Tokens.COLON);
+        commandSet.put(T_COMMA, Tokens.COMMA);
+        commandSet.put(T_CONCAT, Tokens.CONCAT);
+        commandSet.put(T_DIVIDE, Tokens.DIVIDE);
+        commandSet.put(T_EQUALS, Tokens.EQUALS);
+        commandSet.put(T_GREATER, Tokens.GREATER);
+        commandSet.put(T_GREATER_EQUALS, Tokens.GREATER_EQUALS);
+        commandSet.put(T_LEFTBRACKET, LEFTBRACKET);
+        commandSet.put(T_LESS, Tokens.LESS);
+        commandSet.put(T_LESS_EQUALS, Tokens.LESS_EQUALS);
+        commandSet.put(T_MINUS, Tokens.MINUS);
+        commandSet.put(T_NOT_EQUALS, Tokens.NOT_EQUALS);
+        commandSet.put(T_NOT_EQUALS_ALT, Tokens.NOT_EQUALS);
+        commandSet.put(T_OPENBRACKET, OPENBRACKET);
+        commandSet.put(T_PLUS, Tokens.PLUS);
+        commandSet.put(T_QUESTION, Tokens.QUESTION);
+        commandSet.put(T_RIGHTBRACKET, RIGHTBRACKET);
+        commandSet.put(T_SEMICOLON, SEMICOLON);
+    }
+
+    static int get(String token) {
+
+        int type = reservedKeys.get(token, -1);
+
+        if (type == -1) {
+            return commandSet.get(token, -1);
+        }
+
+        return type;
+    }
+
+    public static boolean isCoreKeyword(int token) {
+        return coreReservedWords.contains(token);
+    }
+
+    public static boolean isKeyword(String token) {
+        return reservedKeys.containsKey(token);
+    }
+
+    public static int getKeywordID(String token, int defaultValue) {
+        return reservedKeys.get(token, defaultValue);
+    }
+
+    public static int getNonKeywordID(String token, int defaultValue) {
+        return commandSet.get(token, defaultValue);
+    }
+
+    public static String getKeyword(int token) {
+
+        String key = (String) reservedKeys.getKey(token);
+
+        if (key != null) {
+            return key;
+        }
+
+        key = (String) commandSet.getKey(token);
+
+        return key;
+    }
+
+    private static final OrderedIntHashSet coreReservedWords;
+
+    static {
+
+        // minimal set of identifier not allowed as table / column / alias names
+        // these are in effect interpreted as reserved words used by HSQLDB
+        coreReservedWords = new OrderedIntHashSet(128);
+
+        short[] keyword = {
+            ADMIN, AS, AND, ALL, ANY, AT, AVG, BY, BETWEEN, BOTH, CALL, CASE,
+            CAST, CORRESPONDING, CONVERT, COUNT, COALESCE, CREATE, CROSS,
+            DISTINCT, DROP, ELSE, END, EVERY, EXISTS, EXCEPT, FOR, FROM, FULL,
+            GRANT, GROUP, HAVING, INTO, IS, IN, INTERSECT, JOIN, INNER, LEFT,
+            LEADING, LIKE, MAX, MIN, NATURAL, NULLIF, NOT, ON, ORDER, OR,
+            OUTER, PRIMARY, REFERENCES, RIGHT, SELECT, SET, SOME, STDDEV_POP,
+            STDDEV_SAMP, SUM, TABLE, THEN, TO, TRAILING, TRIGGER, UNION,
+            UNIQUE, USING, VALUES, VAR_POP, VAR_SAMP, WHEN, WHERE, WITH,
+        };
+
+        for (int i = 0; i < keyword.length; i++) {
+            coreReservedWords.add(keyword[i]);
+        }
+    }
+
+    public static final short[] SQL_INTERVAL_FIELD_CODES = new short[] {
+        Tokens.YEAR, Tokens.MONTH, Tokens.DAY, Tokens.HOUR, Tokens.MINUTE,
+        Tokens.SECOND
+    };
+    public static final String[] SQL_INTERVAL_FIELD_NAMES = new String[] {
+        Tokens.T_YEAR, Tokens.T_MONTH, Tokens.T_DAY, Tokens.T_HOUR,
+        Tokens.T_MINUTE, Tokens.T_SECOND
+    };
+    private static final IntKeyHashMap sqlTSILookup = new IntKeyHashMap(10);
+
+    static {
+        sqlTSILookup.put(SQL_TSI_DAY, T_SQL_TSI_DAY);
+        sqlTSILookup.put(SQL_TSI_FRAC_SECOND, T_SQL_TSI_FRAC_SECOND);
+        sqlTSILookup.put(SQL_TSI_HOUR, T_SQL_TSI_HOUR);
+        sqlTSILookup.put(SQL_TSI_MINUTE, T_SQL_TSI_MINUTE);
+        sqlTSILookup.put(SQL_TSI_MONTH, T_SQL_TSI_MONTH);
+        sqlTSILookup.put(SQL_TSI_QUARTER, T_SQL_TSI_QUARTER);
+        sqlTSILookup.put(SQL_TSI_SECOND, T_SQL_TSI_SECOND);
+        sqlTSILookup.put(SQL_TSI_WEEK, T_SQL_TSI_WEEK);
+        sqlTSILookup.put(SQL_TSI_YEAR, T_SQL_TSI_YEAR);
+    }
+
+    public static String getSQLTSIString(int token) {
+        return (String) sqlTSILookup.get(token);
+    }
+}
diff --git a/src/org/hsqldb/TransactionManager.java b/src/org/hsqldb/TransactionManager.java
new file mode 100644
index 0000000..915fac1
--- /dev/null
+++ b/src/org/hsqldb/TransactionManager.java
@@ -0,0 +1,111 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.lib.DoubleIntIndex;
+import org.hsqldb.persist.CachedObject;
+
+public interface TransactionManager {
+
+    //
+    public int LOCKS   = 0;
+    public int MVLOCKS = 1;
+    public int MVCC    = 2;
+
+    //
+    public int ACTION_READ = 0;
+    public int ACTION_DUP  = 1;
+    public int ACTION_REF  = 2;
+
+    public long getGlobalChangeTimestamp();
+
+    public RowAction addDeleteAction(Session session, Table table, Row row,
+                                     int[] colMap);
+
+    public void addInsertAction(Session session, Table table, Row row);
+
+    /**
+     * add session to the end of queue when a transaction starts
+     * (depending on isolation mode)
+     */
+    public void beginAction(Session session, Statement cs);
+
+    public void beginActionResume(Session session);
+
+    public void beginTransaction(Session session);
+
+    // functional unit - accessibility of rows
+    public boolean canRead(Session session, Row row, int mode, int[] colMap);
+
+    public boolean canRead(Session session, int id, int mode);
+
+    public boolean commitTransaction(Session session);
+
+    public void completeActions(Session session);
+
+    /**
+     * Convert row ID's for cached table rows in transactions
+     */
+    public void convertTransactionIDs(DoubleIntIndex lookup);
+
+    /**
+     * Return a lookup of all row ids for cached tables in transactions.
+     * For auto-defrag, as currently there will be no RowAction entries
+     * at the time of defrag.
+     */
+    public DoubleIntIndex getTransactionIDList();
+
+    public int getTransactionControl();
+
+    public boolean isMVRows();
+
+    public boolean prepareCommitActions(Session session);
+
+    public void rollback(Session session);
+
+    public void rollbackAction(Session session);
+
+    public void rollbackSavepoint(Session session, int index);
+
+    public void setTransactionControl(Session session, int mode);
+
+    /**
+     * add transaction info to a row just loaded from the cache. called only
+     * for CACHED tables
+     */
+    public void setTransactionInfo(CachedObject object);
+
+    /**
+     * remove the transaction info
+     */
+    public void removeTransactionInfo(CachedObject object);
+}
diff --git a/src/org/hsqldb/TransactionManager2PL.java b/src/org/hsqldb/TransactionManager2PL.java
new file mode 100644
index 0000000..d74fedb
--- /dev/null
+++ b/src/org/hsqldb/TransactionManager2PL.java
@@ -0,0 +1,363 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.lib.DoubleIntIndex;
+import org.hsqldb.persist.CachedObject;
+import org.hsqldb.persist.PersistentStore;
+
+/**
+ * Manages rows involved in transactions
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class TransactionManager2PL extends TransactionManagerCommon
+implements TransactionManager {
+
+    public TransactionManager2PL(Database db) {
+
+        database       = db;
+        hasPersistence = database.logger.isLogged();
+        lobSession     = database.sessionManager.getSysLobSession();
+        txModel        = LOCKS;
+    }
+
+    public long getGlobalChangeTimestamp() {
+        return globalChangeTimestamp.get();
+    }
+
+    public boolean isMVRows() {
+        return false;
+    }
+
+    public int getTransactionControl() {
+        return LOCKS;
+    }
+
+    public void setTransactionControl(Session session, int mode) {
+
+        writeLock.lock();
+
+        try {
+            switch (mode) {
+
+                case MVCC : {
+                    TransactionManagerMVCC manager =
+                        new TransactionManagerMVCC(database);
+
+                    manager.globalChangeTimestamp.set(
+                        globalChangeTimestamp.get());
+                    manager.liveTransactionTimestamps.addLast(
+                        session.transactionTimestamp);
+
+                    database.txManager = manager;
+
+                    break;
+                }
+                case MVLOCKS : {
+                    TransactionManagerMV2PL manager =
+                        new TransactionManagerMV2PL(database);
+
+                    manager.globalChangeTimestamp.set(
+                        globalChangeTimestamp.get());
+                    manager.liveTransactionTimestamps.addLast(
+                        session.transactionTimestamp);
+
+                    database.txManager = manager;
+
+                    break;
+                }
+                case LOCKS :
+                    break;
+            }
+
+            return;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public void completeActions(Session session) {
+        endActionTPL(session);
+    }
+
+    public boolean prepareCommitActions(Session session) {
+
+        session.actionTimestamp = nextChangeTimestamp();
+
+        return true;
+    }
+
+    public boolean commitTransaction(Session session) {
+
+        if (session.abortTransaction) {
+            return false;
+        }
+
+        int      limit = session.rowActionList.size();
+        Object[] list  = session.rowActionList.getArray();
+
+        writeLock.lock();
+
+        try {
+            endTransaction(session);
+
+            // new actionTimestamp used for commitTimestamp
+            session.actionTimestamp = nextChangeTimestamp();
+
+            for (int i = 0; i < limit; i++) {
+                RowAction action = (RowAction) list[i];
+
+                action.commit(session);
+            }
+
+            persistCommit(session, list, limit);
+            endTransactionTPL(session);
+        } finally {
+            writeLock.unlock();
+        }
+
+        session.tempSet.clear();
+
+        if (session != lobSession && lobSession.rowActionList.size() > 0) {
+            lobSession.isTransaction = true;
+            lobSession.actionIndex   = lobSession.rowActionList.size();
+
+            lobSession.commit(false);
+        }
+
+        return true;
+    }
+
+    public void rollback(Session session) {
+
+        session.abortTransaction = false;
+        session.actionTimestamp  = nextChangeTimestamp();
+
+        rollbackPartial(session, 0, session.transactionTimestamp);
+        endTransaction(session);
+        writeLock.lock();
+
+        try {
+            endTransactionTPL(session);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public void rollbackSavepoint(Session session, int index) {
+
+        long timestamp = session.sessionContext.savepointTimestamps.get(index);
+        Integer oi = (Integer) session.sessionContext.savepoints.get(index);
+        int     start  = oi.intValue();
+
+        while (session.sessionContext.savepoints.size() > index + 1) {
+            session.sessionContext.savepoints.remove(
+                session.sessionContext.savepoints.size() - 1);
+            session.sessionContext.savepointTimestamps.removeLast();
+        }
+
+        rollbackPartial(session, start, timestamp);
+    }
+
+    public void rollbackAction(Session session) {
+        rollbackPartial(session, session.actionIndex, session.actionTimestamp);
+        endActionTPL(session);
+    }
+
+    /**
+     * rollback the row actions from start index in list and
+     * the given timestamp
+     */
+    void rollbackPartial(Session session, int start, long timestamp) {
+
+        Object[] list  = session.rowActionList.getArray();
+        int      limit = session.rowActionList.size();
+
+        if (start == limit) {
+            return;
+        }
+
+        for (int i = limit - 1; i >= start; i--) {
+            RowAction action = (RowAction) list[i];
+
+            if (action == null || action.type == RowActionBase.ACTION_NONE
+                    || action.type == RowActionBase.ACTION_DELETE_FINAL) {
+                continue;
+            }
+
+            Row row = action.memoryRow;
+
+            if (row == null) {
+                row = (Row) action.store.get(action.getPos(), false);
+            }
+
+            if (row == null) {
+                continue;
+            }
+
+            action.rollback(session, timestamp);
+
+            int type = action.mergeRollback(session, timestamp, row);
+
+            action.store.rollbackRow(session, row, type, txModel);
+        }
+
+        session.rowActionList.setSize(start);
+    }
+
+    public RowAction addDeleteAction(Session session, Table table, Row row,
+                                     int[] colMap) {
+
+        RowAction action;
+
+        synchronized (row) {
+            action = RowAction.addDeleteAction(session, table, row, colMap);
+        }
+
+        session.rowActionList.add(action);
+
+        PersistentStore store = session.sessionData.getRowStore(table);
+
+        store.delete(session, row);
+
+        return action;
+    }
+
+    public void addInsertAction(Session session, Table table, Row row) {
+
+        RowAction action = row.rowAction;
+
+        if (action == null) {
+            System.out.println("null insert action " + session + " "
+                               + session.actionTimestamp);
+        }
+
+        session.rowActionList.add(action);
+    }
+
+// functional unit - accessibility of rows
+    public boolean canRead(Session session, Row row, int mode, int[] colMap) {
+        return true;
+    }
+
+    public boolean canRead(Session session, int id, int mode) {
+        return true;
+    }
+
+    /**
+     * add transaction info to a row just loaded from the cache. called only
+     * for CACHED tables
+     */
+    public void setTransactionInfo(CachedObject object) {}
+
+    public void removeTransactionInfo(CachedObject object) {}
+
+    public void beginTransaction(Session session) {
+
+        session.actionTimestamp      = nextChangeTimestamp();
+        session.transactionTimestamp = session.actionTimestamp;
+        session.isTransaction        = true;
+
+        transactionCount++;
+    }
+
+    /**
+     * add session to the end of queue when a transaction starts
+     * (depending on isolation mode)
+     */
+    public void beginAction(Session session, Statement cs) {
+
+        if (session.hasLocks(cs)) {
+            return;
+        }
+
+        writeLock.lock();
+
+        try {
+            boolean canProceed = setWaitedSessionsTPL(session, cs);
+
+            if (canProceed) {
+                if (session.tempSet.isEmpty()) {
+                    lockTablesTPL(session, cs);
+
+                    // we don't set other sessions that would now be waiting for this one too
+                    // next lock release will do it
+                } else {
+                    setWaitingSessionTPL(session);
+                }
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public void beginActionResume(Session session) {
+
+        session.actionTimestamp = nextChangeTimestamp();
+
+        if (!session.isTransaction) {
+            session.transactionTimestamp = session.actionTimestamp;
+            session.isTransaction        = true;
+
+            transactionCount++;
+        }
+
+        return;
+    }
+
+    void endTransaction(Session session) {
+
+        session.isTransaction = false;
+
+        transactionCount--;
+    }
+
+// functional unit - list actions and translate id's
+
+    /**
+     * Return a lookup of all row ids for cached tables in transactions.
+     */
+    public DoubleIntIndex getTransactionIDList() {
+
+        DoubleIntIndex lookup = new DoubleIntIndex(10, false);
+
+        return lookup;
+    }
+
+    /**
+     * Convert row ID's for cached table rows in transactions
+     */
+    public void convertTransactionIDs(DoubleIntIndex lookup) {}
+}
diff --git a/src/org/hsqldb/TransactionManagerCommon.java b/src/org/hsqldb/TransactionManagerCommon.java
new file mode 100644
index 0000000..b04672a
--- /dev/null
+++ b/src/org/hsqldb/TransactionManagerCommon.java
@@ -0,0 +1,801 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.DoubleIntIndex;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.IntKeyHashMapConcurrent;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.MultiValueHashMap;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.LongDeque;
+
+class TransactionManagerCommon {
+
+    Database   database;
+    Session    lobSession;
+    boolean    hasPersistence;
+    int        txModel;
+    HsqlName[] catalogNameList;
+
+    //
+    ReentrantReadWriteLock           lock      = new ReentrantReadWriteLock();
+    ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
+
+    // functional unit - sessions involved in live transactions
+
+    /** live transactions keeping committed transactions from being merged */
+    LongDeque liveTransactionTimestamps = new LongDeque();
+
+    /** live transactions keeping committed transactions from being merged */
+    AtomicLong globalChangeTimestamp = new AtomicLong(1);
+    int        transactionCount      = 0;
+
+    //
+    HashMap           tableWriteLocks = new HashMap();
+    MultiValueHashMap tableReadLocks  = new MultiValueHashMap();
+
+    // functional unit - cached table transactions
+
+    /** Map : rowID -> RowAction */
+    public IntKeyHashMapConcurrent rowActionMap;
+
+    void persistCommit(Session session, Object[] list, int limit) {
+
+        boolean deletedLobs = false;
+
+        for (int i = 0; i < limit; i++) {
+            RowAction action = (RowAction) list[i];
+
+            if (action.type == RowActionBase.ACTION_NONE) {
+                continue;
+            }
+
+            int type = action.getCommitTypeOn(session.actionTimestamp);
+            Row row  = action.memoryRow;
+
+            if (row == null) {
+                row = (Row) action.store.get(action.getPos(), false);
+            }
+
+            if (action.table.hasLobColumn) {
+                switch (type) {
+
+                    case RowActionBase.ACTION_INSERT :
+                        session.sessionData.adjustLobUsageCount(action.table,
+                                row.getData(), 1);
+                        break;
+
+                    case RowActionBase.ACTION_DELETE :
+                        session.sessionData.adjustLobUsageCount(action.table,
+                                row.getData(), -1);
+
+                        deletedLobs = true;
+                        break;
+
+                    case RowActionBase.ACTION_INSERT_DELETE :
+                    default :
+                }
+            }
+
+            try {
+                action.store.commitRow(session, row, type, txModel);
+
+                if (txModel == TransactionManager.LOCKS) {
+                    action.setAsNoOp();
+                    row.rowAction = null;
+                }
+            } catch (HsqlException e) {
+                database.logger.logWarningEvent("data commit failed", e);
+            }
+        }
+
+        try {
+            if (deletedLobs && transactionCount == 0) {
+                database.lobManager.deleteUnusedLobs();
+            }
+
+            session.logSequences();
+
+            if (limit > 0) {
+                database.logger.writeCommitStatement(session);
+            }
+        } catch (HsqlException e) {}
+    }
+
+    void finaliseRows(Session session, Object[] list, int start, int limit,
+                      boolean commit) {
+
+        boolean deletedLobs = false;
+
+        for (int i = start; i < limit; i++) {
+            RowAction action = (RowAction) list[i];
+
+            if (!action.isMemory) {
+                if (action.type == RowActionBase.ACTION_NONE) {
+                    ReentrantReadWriteLock.WriteLock mapLock =
+                        rowActionMap.getWriteLock();
+
+                    mapLock.lock();
+
+                    try {
+                        synchronized (action) {
+
+                            // remove only if not changed
+                            if (action.type == RowActionBase.ACTION_NONE) {
+                                rowActionMap.remove(action.getPos());
+                            }
+                        }
+                    } finally {
+                        mapLock.unlock();
+                    }
+                }
+            }
+
+            if (action.type == RowActionBase.ACTION_DELETE_FINAL
+                    && !action.deleteComplete) {
+                try {
+                    action.deleteComplete = true;
+
+                    if (action.table.getTableType() == TableBase.TEMP_TABLE) {
+                        continue;
+                    }
+
+                    Row row = action.memoryRow;
+
+                    if (row == null) {
+                        row = (Row) action.store.get(action.getPos(), false);
+                    }
+
+                    if (commit && action.table.hasLobColumn) {
+                        deletedLobs = true;
+                    }
+
+                    action.store.commitRow(session, row, action.type, txModel);
+                } catch (Exception e) {
+
+//                    throw unexpectedException(e.getMessage());
+                }
+            }
+        }
+
+        if (deletedLobs && transactionCount == 0 ) {
+            database.lobManager.deleteUnusedLobs();
+        }
+    }
+
+    /**
+     * merge a given list of transaction rollback action with given timestamp
+     */
+    void mergeRolledBackTransaction(Session session, long timestamp,
+                                    Object[] list, int start, int limit) {
+
+        for (int i = start; i < limit; i++) {
+            RowAction action = (RowAction) list[i];
+            Row       row    = action.memoryRow;
+
+            if (row == null) {
+                if (action.type == RowAction.ACTION_NONE) {
+                    continue;
+                }
+
+                row = (Row) action.store.get(action.getPos(), false);
+            }
+
+            if (row == null) {
+
+                // only if transaction has been merged
+                // shouldn't normally happen
+                continue;
+            }
+
+            synchronized (row) {
+                action.mergeRollback(session, timestamp, row);
+            }
+        }
+    }
+
+    /**
+     * merge a transaction committed at a given timestamp.
+     */
+    void mergeTransaction(Session session, Object[] list, int start,
+                          int limit, long timestamp) {
+
+        for (int i = start; i < limit; i++) {
+            RowAction rowact = (RowAction) list[i];
+
+            rowact.mergeToTimestamp(timestamp);
+        }
+    }
+
+    /**
+     * gets the next timestamp for an action
+     */
+    long nextChangeTimestamp() {
+        return globalChangeTimestamp.incrementAndGet();
+    }
+
+    boolean checkDeadlock(Session session, OrderedHashSet newWaits) {
+
+        int size = session.waitingSessions.size();
+
+        for (int i = 0; i < size; i++) {
+            Session current = (Session) session.waitingSessions.get(i);
+
+            if (newWaits.contains(current)) {
+                return false;
+            }
+
+            if (!checkDeadlock(current, newWaits)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    void endActionTPL(Session session) {
+
+        if (session.isolationLevel == SessionInterface.TX_REPEATABLE_READ
+                || session.isolationLevel
+                   == SessionInterface.TX_SERIALIZABLE) {
+            return;
+        }
+
+        if (session.sessionContext.currentStatement == null) {
+
+            // after java function / proc with db access
+            return;
+        }
+
+        if (session.sessionContext.depth > 0) {
+
+            // routine or trigger
+            return;
+        }
+
+        HsqlName[] readLocks =
+            session.sessionContext.currentStatement.getTableNamesForRead();
+
+        if (readLocks.length == 0) {
+            return;
+        }
+
+        writeLock.lock();
+
+        try {
+            unlockReadTablesTPL(session, readLocks);
+
+            final int waitingCount = session.waitingSessions.size();
+
+            if (waitingCount == 0) {
+                return;
+            }
+
+            boolean canUnlock = false;
+
+            // if write lock was used for read lock
+            for (int i = 0; i < readLocks.length; i++) {
+                if (tableWriteLocks.get(readLocks[i]) != session) {
+                    canUnlock = true;
+
+                    break;
+                }
+            }
+
+            if (!canUnlock) {
+                return;
+            }
+
+            canUnlock = false;
+
+            for (int i = 0; i < waitingCount; i++) {
+                Session current = (Session) session.waitingSessions.get(i);
+
+                if (ArrayUtil
+                        .containsAny(readLocks,
+                                     current.sessionContext.currentStatement
+                                         .getTableNamesForWrite())) {
+                    canUnlock = true;
+
+                    break;
+                }
+            }
+
+            if (!canUnlock) {
+                return;
+            }
+
+            resetLocks(session);
+            resetLatchesMidTransaction(session);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    void endTransactionTPL(Session session) {
+
+        unlockTablesTPL(session);
+
+        final int waitingCount = session.waitingSessions.size();
+
+        if (waitingCount == 0) {
+            return;
+        }
+
+        resetLocks(session);
+        resetLatches(session);
+    }
+
+    void resetLocks(Session session) {
+
+        final int waitingCount = session.waitingSessions.size();
+
+        for (int i = 0; i < waitingCount; i++) {
+            Session current = (Session) session.waitingSessions.get(i);
+
+            current.tempUnlocked = false;
+
+            long count = current.latch.getCount();
+
+            if (count == 1) {
+                boolean canProceed = setWaitedSessionsTPL(current,
+                    current.sessionContext.currentStatement);
+
+                if (canProceed) {
+                    if (current.tempSet.isEmpty()) {
+                        lockTablesTPL(current,
+                                      current.sessionContext.currentStatement);
+
+                        current.tempUnlocked = true;
+                    }
+                }
+            }
+        }
+
+        for (int i = 0; i < waitingCount; i++) {
+            Session current = (Session) session.waitingSessions.get(i);
+
+            if (current.tempUnlocked) {
+
+                //
+            } else if (current.abortTransaction) {
+
+                //
+            } else {
+
+                // this can introduce additional waits for the sessions
+                setWaitedSessionsTPL(current,
+                                     current.sessionContext.currentStatement);
+            }
+        }
+    }
+
+    void resetLatches(Session session) {
+
+        final int waitingCount = session.waitingSessions.size();
+
+        for (int i = 0; i < waitingCount; i++) {
+            Session current = (Session) session.waitingSessions.get(i);
+
+            if (!current.abortTransaction && current.tempSet.isEmpty()) {
+
+                // valid for top level statements
+//                boolean hasLocks = hasLocks(current, current.sessionContext.currentStatement);
+//                if (!hasLocks) {
+//                    System.out.println("trouble");
+//                    hasLocks(current, current.sessionContext.currentStatement);
+//                }
+            }
+
+            setWaitingSessionTPL(current);
+        }
+
+        session.waitingSessions.clear();
+    }
+
+    void resetLatchesMidTransaction(Session session) {
+
+        session.tempSet.clear();
+        session.tempSet.addAll(session.waitingSessions);
+        session.waitingSessions.clear();
+
+        final int waitingCount = session.tempSet.size();
+
+        for (int i = 0; i < waitingCount; i++) {
+            Session current = (Session) session.tempSet.get(i);
+
+            if (!current.abortTransaction && current.tempSet.isEmpty()) {
+
+                // valid for top level statements
+//                boolean hasLocks = hasLocks(current, current.sessionContext.currentStatement);
+//                if (!hasLocks) {
+//                    System.out.println("trouble");
+//                    hasLocks(current, current.sessionContext.currentStatement);
+//                }
+            }
+
+            setWaitingSessionTPL(current);
+        }
+
+        session.tempSet.clear();
+    }
+
+    boolean setWaitedSessionsTPL(Session session, Statement cs) {
+
+        session.tempSet.clear();
+
+        if (cs == null) {
+            return true;
+        }
+
+        if (session.abortTransaction) {
+            return false;
+        }
+
+        HsqlName[] nameList = cs.getTableNamesForWrite();
+
+        for (int i = 0; i < nameList.length; i++) {
+            HsqlName name = nameList[i];
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            Session holder = (Session) tableWriteLocks.get(name);
+
+            if (holder != null && holder != session) {
+                session.tempSet.add(holder);
+            }
+
+            Iterator it = tableReadLocks.get(name);
+
+            while (it.hasNext()) {
+                holder = (Session) it.next();
+
+                if (holder != session) {
+                    session.tempSet.add(holder);
+                }
+            }
+        }
+
+        nameList = cs.getTableNamesForRead();
+
+        if (txModel == TransactionManager.MVLOCKS && session.isReadOnly()) {
+            nameList = catalogNameList;
+        }
+
+        for (int i = 0; i < nameList.length; i++) {
+            HsqlName name = nameList[i];
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            Session holder = (Session) tableWriteLocks.get(name);
+
+            if (holder != null && holder != session) {
+                session.tempSet.add(holder);
+            }
+        }
+
+        if (session.tempSet.isEmpty()) {
+            return true;
+        }
+
+        if (checkDeadlock(session, session.tempSet)) {
+            return true;
+        }
+
+        session.tempSet.clear();
+
+        session.abortTransaction = true;
+
+        return false;
+    }
+
+    void setWaitingSessionTPL(Session session) {
+
+        int count = session.tempSet.size();
+
+        assert session.latch.getCount() <= count + 1;
+
+        for (int i = 0; i < count; i++) {
+            Session current = (Session) session.tempSet.get(i);
+
+            current.waitingSessions.add(session);
+        }
+
+        session.tempSet.clear();
+        session.latch.setCount(count);
+    }
+
+    void lockTablesTPL(Session session, Statement cs) {
+
+        if (cs == null || session.abortTransaction) {
+            return;
+        }
+
+        HsqlName[] nameList = cs.getTableNamesForWrite();
+
+        for (int i = 0; i < nameList.length; i++) {
+            HsqlName name = nameList[i];
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            tableWriteLocks.put(name, session);
+        }
+
+        nameList = cs.getTableNamesForRead();
+
+        for (int i = 0; i < nameList.length; i++) {
+            HsqlName name = nameList[i];
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            tableReadLocks.put(name, session);
+        }
+    }
+
+    void unlockTablesTPL(Session session) {
+
+        Iterator it = tableWriteLocks.values().iterator();
+
+        while (it.hasNext()) {
+            Session s = (Session) it.next();
+
+            if (s == session) {
+                it.setValue(null);
+            }
+        }
+
+        it = tableReadLocks.values().iterator();
+
+        while (it.hasNext()) {
+            Session s = (Session) it.next();
+
+            if (s == session) {
+                it.remove();
+            }
+        }
+    }
+
+    void unlockReadTablesTPL(Session session, HsqlName[] locks) {
+
+        for (int i = 0; i < locks.length; i++) {
+            tableReadLocks.remove(locks[i], session);
+        }
+    }
+
+    boolean hasLocks(Session session, Statement cs) {
+
+        if (cs == null) {
+            return true;
+        }
+
+        HsqlName[] nameList = cs.getTableNamesForWrite();
+
+        for (int i = 0; i < nameList.length; i++) {
+            HsqlName name = nameList[i];
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            Session holder = (Session) tableWriteLocks.get(name);
+
+            if (holder != null && holder != session) {
+                return false;
+            }
+
+            Iterator it = tableReadLocks.get(name);
+
+            while (it.hasNext()) {
+                holder = (Session) it.next();
+
+                if (holder != session) {
+                    return false;
+                }
+            }
+        }
+
+        nameList = cs.getTableNamesForRead();
+
+        for (int i = 0; i < nameList.length; i++) {
+            HsqlName name = nameList[i];
+
+            if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
+                continue;
+            }
+
+            Session holder = (Session) tableWriteLocks.get(name);
+
+            if (holder != null && holder != session) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    long getFirstLiveTransactionTimestamp() {
+
+        if (liveTransactionTimestamps.isEmpty()) {
+            return Long.MAX_VALUE;
+        }
+
+        return liveTransactionTimestamps.get(0);
+    }
+
+    /**
+     * Return an array of all row actions sorted by System Change No.
+     */
+    RowAction[] getRowActionList() {
+
+        writeLock.lock();
+
+        try {
+            Session[]   sessions = database.sessionManager.getAllSessions();
+            int[]       tIndex   = new int[sessions.length];
+            RowAction[] rowActions;
+            int         rowActionCount = 0;
+
+            {
+                int actioncount = 0;
+
+                for (int i = 0; i < sessions.length; i++) {
+                    actioncount += sessions[i].getTransactionSize();
+                }
+
+                rowActions = new RowAction[actioncount];
+            }
+
+            while (true) {
+                boolean found        = false;
+                long    minChangeNo  = Long.MAX_VALUE;
+                int     sessionIndex = 0;
+
+                // find the lowest available SCN across all sessions
+                for (int i = 0; i < sessions.length; i++) {
+                    int tSize = sessions[i].getTransactionSize();
+
+                    if (tIndex[i] < tSize) {
+                        RowAction current =
+                            (RowAction) sessions[i].rowActionList.get(
+                                tIndex[i]);
+
+                        if (current.actionTimestamp < minChangeNo) {
+                            minChangeNo  = current.actionTimestamp;
+                            sessionIndex = i;
+                        }
+
+                        found = true;
+                    }
+                }
+
+                if (!found) {
+                    break;
+                }
+
+                HsqlArrayList currentList =
+                    sessions[sessionIndex].rowActionList;
+
+                for (; tIndex[sessionIndex] < currentList.size(); ) {
+                    RowAction current =
+                        (RowAction) currentList.get(tIndex[sessionIndex]);
+
+                    // if the next change no is in this session, continue adding
+                    if (current.actionTimestamp == minChangeNo + 1) {
+                        minChangeNo++;
+                    }
+
+                    if (current.actionTimestamp == minChangeNo) {
+                        rowActions[rowActionCount++] = current;
+
+                        tIndex[sessionIndex]++;
+                    } else {
+                        break;
+                    }
+                }
+            }
+
+            return rowActions;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Return a lookup of all row ids for cached tables in transactions.
+     * For auto-defrag, as currently there will be no RowAction entries
+     * at the time of defrag.
+     */
+    DoubleIntIndex getTransactionIDList() {
+
+        writeLock.lock();
+
+        try {
+            int            size   = rowActionMap.size();
+            DoubleIntIndex lookup = new DoubleIntIndex(size, false);
+
+            lookup.setKeysSearchTarget();
+
+            Iterator it = this.rowActionMap.keySet().iterator();
+
+            for (; it.hasNext(); ) {
+                lookup.addUnique(it.nextInt(), 0);
+            }
+
+            return lookup;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Convert row ID's for cached table rows in transactions
+     */
+    void convertTransactionIDs(DoubleIntIndex lookup) {
+
+        writeLock.lock();
+
+        try {
+            RowAction[] list = new RowAction[rowActionMap.size()];
+            Iterator    it   = this.rowActionMap.values().iterator();
+
+            for (int i = 0; it.hasNext(); i++) {
+                list[i] = (RowAction) it.next();
+            }
+
+            rowActionMap.clear();
+
+            for (int i = 0; i < list.length; i++) {
+                int pos = lookup.lookupFirstEqual(list[i].getPos());
+
+                list[i].setPos(pos);
+                rowActionMap.put(pos, list[i]);
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+}
diff --git a/src/org/hsqldb/TransactionManagerMV2PL.java b/src/org/hsqldb/TransactionManagerMV2PL.java
new file mode 100644
index 0000000..5dc68f6
--- /dev/null
+++ b/src/org/hsqldb/TransactionManagerMV2PL.java
@@ -0,0 +1,514 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.DoubleIntIndex;
+import org.hsqldb.lib.HsqlDeque;
+import org.hsqldb.lib.IntKeyHashMapConcurrent;
+import org.hsqldb.lib.LongDeque;
+import org.hsqldb.persist.CachedObject;
+
+/**
+ * Manages rows involved in transactions
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class TransactionManagerMV2PL extends TransactionManagerCommon
+implements TransactionManager {
+
+    // functional unit - merged committed transactions
+    HsqlDeque committedTransactions          = new HsqlDeque();
+    LongDeque committedTransactionTimestamps = new LongDeque();
+
+    public TransactionManagerMV2PL(Database db) {
+
+        database        = db;
+        hasPersistence  = database.logger.isLogged();
+        lobSession      = database.sessionManager.getSysLobSession();
+        rowActionMap    = new IntKeyHashMapConcurrent(10000);
+        txModel         = MVLOCKS;
+        catalogNameList = new HsqlName[]{ database.getCatalogName() };
+    }
+
+    public long getGlobalChangeTimestamp() {
+        return globalChangeTimestamp.get();
+    }
+
+    public boolean isMVRows() {
+        return true;
+    }
+
+    public int getTransactionControl() {
+        return MVLOCKS;
+    }
+
+    public void setTransactionControl(Session session, int mode) {
+
+        writeLock.lock();
+
+        try {
+
+            // statement runs as transaction
+            if (liveTransactionTimestamps.size() == 1) {
+                switch (mode) {
+
+                    case MVCC : {
+                        TransactionManagerMVCC manager =
+                            new TransactionManagerMVCC(database);
+
+                        manager.globalChangeTimestamp.set(
+                            globalChangeTimestamp.get());
+                        manager.liveTransactionTimestamps.addLast(
+                            session.transactionTimestamp);
+
+                        database.txManager = manager;
+
+                        break;
+                    }
+                    case MVLOCKS :
+                        break;
+
+                    case LOCKS : {
+                        TransactionManager2PL manager =
+                            new TransactionManager2PL(database);
+
+                        manager.globalChangeTimestamp.set(
+                            globalChangeTimestamp.get());
+
+                        database.txManager = manager;
+
+                        break;
+                    }
+                }
+
+                return;
+            }
+        } finally {
+            writeLock.unlock();
+        }
+
+        throw Error.error(ErrorCode.X_25001);
+    }
+
+    public void completeActions(Session session) {
+        endActionTPL(session);
+    }
+
+    public boolean prepareCommitActions(Session session) {
+
+        Object[] list  = session.rowActionList.getArray();
+        int      limit = session.rowActionList.size();
+
+        writeLock.lock();
+
+        try {
+            session.actionTimestamp = nextChangeTimestamp();
+
+            for (int i = 0; i < limit; i++) {
+                RowAction action = (RowAction) list[i];
+
+                action.prepareCommit(session);
+            }
+
+            return true;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public boolean commitTransaction(Session session) {
+
+        if (session.abortTransaction) {
+            return false;
+        }
+
+        int      limit = session.rowActionList.size();
+        Object[] list  = session.rowActionList.getArray();
+
+        writeLock.lock();
+
+        try {
+            endTransaction(session);
+
+            // new actionTimestamp used for commitTimestamp
+            session.actionTimestamp = nextChangeTimestamp();
+
+            for (int i = 0; i < limit; i++) {
+                RowAction action = (RowAction) list[i];
+
+                action.commit(session);
+            }
+
+            persistCommit(session, list, limit);
+
+            // session.actionTimestamp is the committed tx timestamp
+            if (getFirstLiveTransactionTimestamp() > session.actionTimestamp) {
+                mergeTransaction(session, list, 0, limit,
+                                 session.actionTimestamp);
+                finaliseRows(session, list, 0, limit, true);
+            } else {
+                list = session.rowActionList.toArray();
+
+                addToCommittedQueue(session, list);
+            }
+
+            endTransactionTPL(session);
+        } finally {
+            writeLock.unlock();
+        }
+
+        session.tempSet.clear();
+
+        if (session != lobSession && lobSession.rowActionList.size() > 0) {
+            lobSession.isTransaction = true;
+            lobSession.actionIndex   = lobSession.rowActionList.size();
+
+            lobSession.commit(false);
+        }
+
+        return true;
+    }
+
+    public void rollback(Session session) {
+
+        writeLock.lock();
+
+        try {
+            session.abortTransaction = false;
+            session.actionTimestamp  = nextChangeTimestamp();
+
+            rollbackPartial(session, 0, session.transactionTimestamp);
+            endTransaction(session);
+            endTransactionTPL(session);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public void rollbackSavepoint(Session session, int index) {
+
+        long timestamp = session.sessionContext.savepointTimestamps.get(index);
+        Integer oi = (Integer) session.sessionContext.savepoints.get(index);
+        int     start  = oi.intValue();
+
+        while (session.sessionContext.savepoints.size() > index + 1) {
+            session.sessionContext.savepoints.remove(
+                session.sessionContext.savepoints.size() - 1);
+            session.sessionContext.savepointTimestamps.removeLast();
+        }
+
+        rollbackPartial(session, start, timestamp);
+    }
+
+    public void rollbackAction(Session session) {
+        rollbackPartial(session, session.actionIndex, session.actionTimestamp);
+        endActionTPL(session);
+    }
+
+    /**
+     * rollback the row actions from start index in list and
+     * the given timestamp
+     */
+    void rollbackPartial(Session session, int start, long timestamp) {
+
+        Object[] list  = session.rowActionList.getArray();
+        int      limit = session.rowActionList.size();
+
+        if (start == limit) {
+            return;
+        }
+
+        for (int i = start; i < limit; i++) {
+            RowAction action = (RowAction) list[i];
+
+            if (action != null) {
+                action.rollback(session, timestamp);
+            } else {
+                System.out.println("null action in rollback " + start);
+            }
+        }
+
+        // rolled back transactions can always be merged as they have never been
+        // seen by other sessions
+        mergeRolledBackTransaction(session, timestamp, list, start, limit);
+        finaliseRows(session, list, start, limit, false);
+        session.rowActionList.setSize(start);
+    }
+
+    public RowAction addDeleteAction(Session session, Table table, Row row,
+                                     int[] colMap) {
+
+        RowAction action;
+        boolean   newAction;
+
+        synchronized (row) {
+            newAction = row.rowAction == null;
+            action    = RowAction.addDeleteAction(session, table, row, colMap);
+        }
+
+        session.rowActionList.add(action);
+
+        if (newAction) {
+            if (!row.isMemory()) {
+                rowActionMap.put(action.getPos(), action);
+            }
+        }
+
+        return action;
+    }
+
+    public void addInsertAction(Session session, Table table, Row row) {
+
+        RowAction action = row.rowAction;
+
+        if (action == null) {
+            System.out.println("null insert action " + session + " "
+                               + session.actionTimestamp);
+        }
+
+        session.rowActionList.add(action);
+
+        if (!row.isMemory()) {
+            rowActionMap.put(action.getPos(), action);
+        }
+    }
+
+// functional unit - accessibility of rows
+    public boolean canRead(Session session, Row row, int mode, int[] colMap) {
+
+        RowAction action = row.rowAction;
+
+        if (action == null) {
+            return true;
+        }
+
+        return action.canRead(session, TransactionManager.ACTION_READ);
+    }
+
+    public boolean canRead(Session session, int id, int mode) {
+
+        RowAction action = (RowAction) rowActionMap.get(id);
+
+        return action == null ? true
+                              : action.canRead(session,
+                                               TransactionManager.ACTION_READ);
+    }
+
+    /**
+     * add transaction info to a row just loaded from the cache. called only
+     * for CACHED tables
+     */
+    public void setTransactionInfo(CachedObject object) {
+
+        Row       row    = (Row) object;
+        RowAction rowact = (RowAction) rowActionMap.get(row.position);
+
+        row.rowAction = rowact;
+    }
+
+    /**
+     * remove the transaction info
+     */
+    public void removeTransactionInfo(CachedObject object) {
+        rowActionMap.remove(object.getPos());
+    }
+
+    /**
+     * add a list of actions to the end of queue
+     */
+    void addToCommittedQueue(Session session, Object[] list) {
+
+        synchronized (committedTransactionTimestamps) {
+
+            // add the txList according to commit timestamp
+            committedTransactions.addLast(list);
+
+            // get session commit timestamp
+            committedTransactionTimestamps.addLast(session.actionTimestamp);
+/* debug 190
+            if (committedTransactions.size() > 64) {
+                System.out.println("******* excessive transaction queue");
+            }
+// debug 190 */
+        }
+    }
+
+    /**
+     * expire all committed transactions that are no longer in scope
+     */
+    void mergeExpiredTransactions(Session session) {
+
+        long timestamp = getFirstLiveTransactionTimestamp();
+
+        while (true) {
+            long     commitTimestamp = 0;
+            Object[] actions         = null;
+
+            synchronized (committedTransactionTimestamps) {
+                if (committedTransactionTimestamps.isEmpty()) {
+                    break;
+                }
+
+                commitTimestamp = committedTransactionTimestamps.getFirst();
+
+                if (commitTimestamp < timestamp) {
+                    committedTransactionTimestamps.removeFirst();
+
+                    actions = (Object[]) committedTransactions.removeFirst();
+                } else {
+                    break;
+                }
+            }
+
+            mergeTransaction(session, actions, 0, actions.length,
+                             commitTimestamp);
+            finaliseRows(session, actions, 0, actions.length, true);
+        }
+    }
+
+    public void beginTransaction(Session session) {
+
+        writeLock.lock();
+
+        try {
+            session.actionTimestamp      = nextChangeTimestamp();
+            session.transactionTimestamp = session.actionTimestamp;
+            session.isTransaction        = true;
+
+            liveTransactionTimestamps.addLast(session.transactionTimestamp);
+
+            transactionCount++;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * add session to the end of queue when a transaction starts
+     * (depending on isolation mode)
+     */
+    public void beginAction(Session session, Statement cs) {
+
+        if (session.hasLocks(cs)) {
+            return;
+        }
+
+        writeLock.lock();
+
+        try {
+            boolean canProceed = setWaitedSessionsTPL(session, cs);
+
+            if (canProceed) {
+                if (session.tempSet.isEmpty()) {
+                    lockTablesTPL(session, cs);
+
+                    // we dont set other sessions that would now be waiting for this one too
+                } else {
+                    setWaitingSessionTPL(session);
+                }
+            } else {
+                session.abortTransaction = true;
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * add session to the end of queue when a transaction starts
+     * (depending on isolation mode)
+     */
+    public void beginActionResume(Session session) {
+
+        writeLock.lock();
+
+        try {
+            session.actionTimestamp = nextChangeTimestamp();
+
+            if (!session.isTransaction) {
+                session.transactionTimestamp = session.actionTimestamp;
+                session.isTransaction        = true;
+
+                liveTransactionTimestamps.addLast(session.actionTimestamp);
+
+                transactionCount++;
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * remove session from queue when a transaction ends
+     * and expire any committed transactions
+     * that are no longer required. remove transactions ended before the first
+     * timestamp in liveTransactionsSession queue
+     */
+    void endTransaction(Session session) {
+
+        long timestamp = session.transactionTimestamp;
+
+        session.isTransaction = false;
+
+        int index = liveTransactionTimestamps.indexOf(timestamp);
+
+        if (index >= 0) {
+            transactionCount--;
+            liveTransactionTimestamps.remove(index);
+            mergeExpiredTransactions(session);
+        }
+
+    }
+
+// functional unit - list actions and translate id's
+
+    /**
+     * Return a lookup of all row ids for cached tables in transactions.
+     * For auto-defrag, as currently there will be no RowAction entries
+     * at the time of defrag.
+     */
+    public DoubleIntIndex getTransactionIDList() {
+        return super.getTransactionIDList();
+    }
+
+    /**
+     * Convert row ID's for cached table rows in transactions
+     */
+    public void convertTransactionIDs(DoubleIntIndex lookup) {
+        super.convertTransactionIDs(lookup);
+    }
+}
diff --git a/src/org/hsqldb/TransactionManagerMVCC.java b/src/org/hsqldb/TransactionManagerMVCC.java
new file mode 100644
index 0000000..69a38fc
--- /dev/null
+++ b/src/org/hsqldb/TransactionManagerMVCC.java
@@ -0,0 +1,865 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.DoubleIntIndex;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.HsqlDeque;
+import org.hsqldb.lib.IntKeyHashMapConcurrent;
+import org.hsqldb.lib.LongDeque;
+import org.hsqldb.persist.CachedObject;
+
+/**
+ * Manages rows involved in transactions
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class TransactionManagerMVCC extends TransactionManagerCommon
+implements TransactionManager {
+
+    // functional unit - merged committed transactions
+    HsqlDeque committedTransactions          = new HsqlDeque();
+    LongDeque committedTransactionTimestamps = new LongDeque();
+
+    // locks
+    boolean isLockedMode;
+    Session catalogWriteSession;
+
+    //
+    int redoCount = 0;
+
+    //
+    public TransactionManagerMVCC(Database db) {
+
+        database       = db;
+        hasPersistence = database.logger.isLogged();
+        lobSession     = database.sessionManager.getSysLobSession();
+        rowActionMap   = new IntKeyHashMapConcurrent(10000);
+        txModel        = MVCC;
+    }
+
+    public long getGlobalChangeTimestamp() {
+        return globalChangeTimestamp.get();
+    }
+
+    public boolean isMVRows() {
+        return true;
+    }
+
+    public int getTransactionControl() {
+        return MVCC;
+    }
+
+    public void setTransactionControl(Session session, int mode) {
+
+        writeLock.lock();
+
+        try {
+
+            // statement runs as transaction
+            if (liveTransactionTimestamps.size() == 1) {
+                switch (mode) {
+
+                    case MVCC :
+                        break;
+
+                    case MVLOCKS : {
+                        TransactionManagerMV2PL manager =
+                            new TransactionManagerMV2PL(database);
+
+                        manager.globalChangeTimestamp.set(
+                            globalChangeTimestamp.get());
+                        manager.liveTransactionTimestamps.addLast(
+                            session.transactionTimestamp);
+
+                        database.txManager = manager;
+
+                        break;
+                    }
+                    case LOCKS : {
+                        TransactionManager2PL manager =
+                            new TransactionManager2PL(database);
+
+                        manager.globalChangeTimestamp.set(
+                            globalChangeTimestamp.get());
+
+                        database.txManager = manager;
+
+                        break;
+                    }
+                }
+
+                return;
+            }
+        } finally {
+            writeLock.unlock();
+        }
+
+        throw Error.error(ErrorCode.X_25001);
+    }
+
+    public void completeActions(Session session) {}
+
+    public boolean prepareCommitActions(Session session) {
+
+        Object[] list  = session.rowActionList.getArray();
+        int      limit = session.rowActionList.size();
+
+        if (session.abortTransaction) {
+
+//            System.out.println("cascade fail " + session + " " + session.actionTimestamp);
+            return false;
+        }
+
+        writeLock.lock();
+
+        try {
+            for (int i = 0; i < limit; i++) {
+                RowAction rowact = (RowAction) list[i];
+
+                if (!rowact.canCommit(session, session.tempSet)) {
+
+//                System.out.println("commit conflicts " + session + " " + session.actionTimestamp);
+                    return false;
+                }
+            }
+
+            session.actionTimestamp = nextChangeTimestamp();
+
+            for (int i = 0; i < limit; i++) {
+                RowAction action = (RowAction) list[i];
+
+                action.prepareCommit(session);
+            }
+
+            for (int i = 0; i < session.tempSet.size(); i++) {
+                Session current = (Session) session.tempSet.get(i);
+
+                current.abortTransaction = true;
+            }
+
+            return true;
+        } finally {
+            writeLock.unlock();
+            session.tempSet.clear();
+        }
+    }
+
+    public boolean commitTransaction(Session session) {
+
+        if (session.abortTransaction) {
+            return false;
+        }
+
+        int      limit = session.rowActionList.size();
+        Object[] list  = session.rowActionList.getArray();
+
+        writeLock.lock();
+
+        try {
+            for (int i = 0; i < limit; i++) {
+                RowAction rowact = (RowAction) list[i];
+
+                if (!rowact.canCommit(session, session.tempSet)) {
+
+//                System.out.println("commit conflicts " + session + " " + session.actionTimestamp);
+                    return false;
+                }
+            }
+
+            endTransaction(session);
+
+            // new actionTimestamp used for commitTimestamp
+            session.actionTimestamp = nextChangeTimestamp();
+
+            for (int i = 0; i < limit; i++) {
+                RowAction action = (RowAction) list[i];
+
+                action.commit(session);
+            }
+
+            for (int i = 0; i < session.tempSet.size(); i++) {
+                Session current = (Session) session.tempSet.get(i);
+
+                current.abortTransaction = true;
+            }
+
+            persistCommit(session, list, limit);
+
+            // session.actionTimestamp is the committed tx timestamp
+            if (getFirstLiveTransactionTimestamp() > session.actionTimestamp) {
+                mergeTransaction(session, list, 0, limit,
+                                 session.actionTimestamp);
+                finaliseRows(session, list, 0, limit, true);
+            } else {
+                list = session.rowActionList.toArray();
+
+                addToCommittedQueue(session, list);
+            }
+
+            endTransactionTPL(session);
+
+            //
+            countDownLatches(session);
+        } finally {
+            writeLock.unlock();
+        }
+
+        session.tempSet.clear();
+
+        if (session != lobSession && lobSession.rowActionList.size() > 0) {
+            lobSession.isTransaction = true;
+            lobSession.actionIndex   = lobSession.rowActionList.size();
+
+            lobSession.commit(false);
+        }
+
+        return true;
+    }
+
+    public void rollback(Session session) {
+
+        writeLock.lock();
+
+        try {
+            session.abortTransaction = false;
+            session.actionTimestamp  = nextChangeTimestamp();
+
+            rollbackPartial(session, 0, session.transactionTimestamp);
+            endTransaction(session);
+            endTransactionTPL(session);
+            countDownLatches(session);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public void rollbackSavepoint(Session session, int index) {
+
+        long timestamp = session.sessionContext.savepointTimestamps.get(index);
+        Integer oi = (Integer) session.sessionContext.savepoints.get(index);
+        int     start  = oi.intValue();
+
+        while (session.sessionContext.savepoints.size() > index + 1) {
+            session.sessionContext.savepoints.remove(
+                session.sessionContext.savepoints.size() - 1);
+            session.sessionContext.savepointTimestamps.removeLast();
+        }
+
+        rollbackPartial(session, start, timestamp);
+    }
+
+    public void rollbackAction(Session session) {
+        rollbackPartial(session, session.actionIndex, session.actionTimestamp);
+    }
+
+    /**
+     * rollback the row actions from start index in list and
+     * the given timestamp
+     */
+    void rollbackPartial(Session session, int start, long timestamp) {
+
+        Object[] list  = session.rowActionList.getArray();
+        int      limit = session.rowActionList.size();
+
+        if (start == limit) {
+            return;
+        }
+
+        for (int i = start; i < limit; i++) {
+            RowAction action = (RowAction) list[i];
+
+            if (action != null) {
+                action.rollback(session, timestamp);
+            } else {
+                System.out.println("null action in rollback " + start);
+            }
+        }
+
+        // rolled back transactions can always be merged as they have never been
+        // seen by other sessions
+        writeLock.lock();
+
+        try {
+            mergeRolledBackTransaction(session, timestamp, list, start, limit);
+            finaliseRows(session, list, start, limit, false);
+        } finally {
+            writeLock.unlock();
+        }
+
+        session.rowActionList.setSize(start);
+    }
+
+    public RowAction addDeleteAction(Session session, Table table, Row row,
+                                     int[] colMap) {
+
+        RowAction action = addDeleteActionToRow(session, table, row, colMap);
+
+        if (action == null) {
+            writeLock.lock();
+
+            try {
+                rollbackAction(session);
+
+                if (session.isolationLevel == SessionInterface
+                        .TX_REPEATABLE_READ || session
+                        .isolationLevel == SessionInterface.TX_SERIALIZABLE) {
+                    session.tempSet.clear();
+
+                    session.abortTransaction = true;
+
+                    throw Error.error(ErrorCode.X_40501);
+                }
+
+                // can redo when conflicting action is already committed
+                if (row.rowAction != null && row.rowAction.isDeleted()) {
+                    session.tempSet.clear();
+
+                    session.redoAction = true;
+
+                    redoCount++;
+
+                    throw Error.error(ErrorCode.X_40501);
+                }
+
+                boolean canWait = checkDeadlock(session, session.tempSet);
+
+                if (canWait) {
+                    Session current = (Session) session.tempSet.get(0);
+
+                    session.redoAction = true;
+
+                    current.waitingSessions.add(session);
+                    session.waitedSessions.add(current);
+                    session.latch.countUp();
+                } else {
+                    session.redoAction       = false;
+                    session.abortTransaction = true;
+                }
+
+                session.tempSet.clear();
+
+                redoCount++;
+
+                throw Error.error(ErrorCode.X_40501);
+            } finally {
+                writeLock.unlock();
+            }
+        }
+
+        session.rowActionList.add(action);
+
+        return action;
+    }
+
+    public void addInsertAction(Session session, Table table, Row row) {
+
+        RowAction action = row.rowAction;
+
+        if (action == null) {
+            System.out.println("null insert action " + session + " "
+                               + session.actionTimestamp);
+        }
+
+        session.rowActionList.add(action);
+
+        if (!row.isMemory()) {
+            rowActionMap.put(action.getPos(), action);
+        }
+    }
+
+// functional unit - accessibility of rows
+    public boolean canRead(Session session, Row row, int mode, int[] colMap) {
+
+        RowAction action = row.rowAction;
+
+        if (mode == TransactionManager.ACTION_READ) {
+            if (action == null) {
+                return true;
+            }
+
+            return action.canRead(session, TransactionManager.ACTION_READ);
+        }
+
+        if (mode == ACTION_REF) {
+            boolean result;
+
+            if (action == null) {
+                result = true;
+            } else {
+                result = action.canRead(session,
+                                        TransactionManager.ACTION_READ);
+            }
+
+            return result;
+/*
+            if (result) {
+                synchronized (row) {
+                    if (row.isMemory()) {
+                        result = RowAction.addRefAction(session, row, colMap);
+                    } else {
+                        ReentrantReadWriteLock.WriteLock mapLock =
+                            rowActionMap.getWriteLock();
+
+                        mapLock.lock();
+
+                        try {
+                            action = row.rowAction;
+
+                            if (action == null) {
+                                action =
+                                    (RowAction) rowActionMap.get(row.getPos());
+                                row.rowAction = action;
+                            }
+
+                            result = RowAction.addRefAction(session, row,
+                                                            colMap);
+
+                            if (result && action == null) {
+                                rowActionMap.put(row.getPos(), action);
+                            }
+                        } finally {
+                            mapLock.unlock();
+                        }
+                    }
+                }
+
+                if (result) {
+                    session.rowActionList.add(row.rowAction);
+                } else {
+                    if (!session.tempSet.isEmpty()) {
+                        Session current = (Session) session.tempSet.get(0);
+
+                        session.redoAction = true;
+
+                        session.latch.countUp();
+                        current.waitingSessions.add(session);
+                        session.waitedSessions.add(current);
+                        session.tempSet.clear();
+
+                        throw Error.error(ErrorCode.X_40501);
+                    }
+                }
+
+                return true;
+            }
+
+            return false;
+*/
+        }
+
+        if (action == null) {
+            return true;
+        }
+
+        return action.canRead(session, mode);
+    }
+
+    public boolean canRead(Session session, int id, int mode) {
+
+        RowAction action = (RowAction) rowActionMap.get(id);
+
+        if (action == null) {
+            return true;
+        }
+
+        return action.canRead(session, mode);
+    }
+
+    /**
+     * add transaction info to a row just loaded from the cache. called only
+     * for CACHED tables
+     */
+    public void setTransactionInfo(CachedObject object) {
+
+        Row       row    = (Row) object;
+        RowAction rowact = (RowAction) rowActionMap.get(row.position);
+
+        row.rowAction = rowact;
+    }
+
+    /**
+     * remove the transaction info
+     */
+    public void removeTransactionInfo(CachedObject object) {
+        rowActionMap.remove(object.getPos());
+    }
+
+    /**
+     * add a list of actions to the end of queue
+     */
+    void addToCommittedQueue(Session session, Object[] list) {
+
+        synchronized (committedTransactionTimestamps) {
+
+            // add the txList according to commit timestamp
+            committedTransactions.addLast(list);
+
+            // get session commit timestamp
+            committedTransactionTimestamps.addLast(session.actionTimestamp);
+/* debug 190
+            if (committedTransactions.size() > 64) {
+                System.out.println("******* excessive transaction queue");
+            }
+// debug 190 */
+        }
+    }
+
+    /**
+     * expire all committed transactions that are no longer in scope
+     */
+    void mergeExpiredTransactions(Session session) {
+
+        long timestamp = getFirstLiveTransactionTimestamp();
+
+        while (true) {
+            long     commitTimestamp;
+            Object[] actions;
+
+            synchronized (committedTransactionTimestamps) {
+                if (committedTransactionTimestamps.isEmpty()) {
+                    break;
+                }
+
+                commitTimestamp = committedTransactionTimestamps.getFirst();
+
+                if (commitTimestamp < timestamp) {
+                    committedTransactionTimestamps.removeFirst();
+
+                    actions = (Object[]) committedTransactions.removeFirst();
+                } else {
+                    break;
+                }
+            }
+
+            mergeTransaction(session, actions, 0, actions.length,
+                             commitTimestamp);
+            finaliseRows(session, actions, 0, actions.length, true);
+        }
+    }
+
+    public void beginTransaction(Session session) {
+
+        writeLock.lock();
+
+        try {
+            session.actionTimestamp      = nextChangeTimestamp();
+            session.transactionTimestamp = session.actionTimestamp;
+            session.isTransaction        = true;
+
+            liveTransactionTimestamps.addLast(session.transactionTimestamp);
+            transactionCount++;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * add session to the end of queue when a transaction starts
+     * (depending on isolation mode)
+     */
+    public void beginAction(Session session, Statement cs) {
+
+        if (session.isTransaction) {
+            return;
+        }
+
+        if (cs == null) {
+            return;
+        }
+
+        writeLock.lock();
+
+        try {
+            session.isPreTransaction = true;
+
+            if (!isLockedMode && !cs.isCatalogChange()) {
+                return;
+            }
+
+            beingActionTPL(session, cs);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * add session to the end of queue when a transaction starts
+     * (depending on isolation mode)
+     */
+    public void beginActionResume(Session session) {
+
+        writeLock.lock();
+
+        try {
+            session.actionTimestamp = nextChangeTimestamp();
+
+            if (!session.isTransaction) {
+                session.transactionTimestamp = session.actionTimestamp;
+                session.isTransaction        = true;
+
+                liveTransactionTimestamps.addLast(session.actionTimestamp);
+                transactionCount++;
+            }
+
+            session.isPreTransaction = false;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    RowAction addDeleteActionToRow(Session session, Table table, Row row,
+                                   int[] colMap) {
+
+        RowAction action = null;
+
+        synchronized (row) {
+            if (row.isMemory()) {
+                action = RowAction.addDeleteAction(session, table, row,
+                                                   colMap);
+            } else {
+                ReentrantReadWriteLock.WriteLock mapLock =
+                    rowActionMap.getWriteLock();
+
+                mapLock.lock();
+
+                try {
+
+                    /* using rowActionMap as source */
+                    action = (RowAction) rowActionMap.get(row.getPos());
+
+                    if (action == null) {
+                        if (row.rowAction != null) {
+
+                            // test code
+                            action = row.rowAction;
+                        }
+
+                        action = RowAction.addDeleteAction(session, table,
+                                                           row, colMap);
+
+                        if (action != null) {
+                            rowActionMap.put(row.getPos(), action);
+                        }
+                    } else {
+                        if (row.rowAction != action) {
+
+                            // test code
+                            action = row.rowAction;
+                        }
+
+                        row.rowAction = action;
+                        action = RowAction.addDeleteAction(session, table,
+                                                           row, colMap);
+                    }
+/*
+
+                    action = row.rowAction;
+
+                    if (action == null) {
+                        action = (RowAction) rowActionMap.get(row.getPos());
+                    }
+
+                    if (action == null) {
+                        action = RowAction.addDeleteAction(session, table,
+                                                           row, colMap);
+
+                        if (action != null) {
+                            rowActionMap.put(row.getPos(), action);
+
+                            row.rowAction = action;
+                        }
+                    } else {
+
+                        // possibly from rowActionMap
+                        row.rowAction = action;
+                        action = action.addDeleteAction(session, colMap);
+                    }
+*/
+                } finally {
+                    mapLock.unlock();
+                }
+            }
+        }
+
+        return action;
+    }
+
+    /**
+     * remove session from queue when a transaction ends
+     * and expire any committed transactions
+     * that are no longer required. remove transactions ended before the first
+     * timestamp in liveTransactionsSession queue
+     */
+    void endTransaction(Session session) {
+
+        long timestamp = session.transactionTimestamp;
+
+        session.isTransaction = false;
+
+        int index = liveTransactionTimestamps.indexOf(timestamp);
+
+        if (index >= 0) {
+            transactionCount--;
+            liveTransactionTimestamps.remove(index);
+            mergeExpiredTransactions(session);
+        }
+
+    }
+
+// functional unit - list actions and translate id's
+
+    /**
+     * Return a lookup of all row ids for cached tables in transactions.
+     * For auto-defrag, as currently there will be no RowAction entries
+     * at the time of defrag.
+     */
+    public DoubleIntIndex getTransactionIDList() {
+        return super.getTransactionIDList();
+    }
+
+    /**
+     * Convert row ID's for cached table rows in transactions
+     */
+    public void convertTransactionIDs(DoubleIntIndex lookup) {
+        super.convertTransactionIDs(lookup);
+    }
+
+    private void countDownLatches(Session session) {
+
+        for (int i = 0; i < session.waitingSessions.size(); i++) {
+            Session current = (Session) session.waitingSessions.get(i);
+
+            current.waitedSessions.remove(session);
+            current.latch.countDown();
+        }
+
+        session.waitingSessions.clear();
+    }
+
+    void getTransactionSessions(HashSet set) {
+
+        Session[] sessions = database.sessionManager.getAllSessions();
+
+        for (int i = 0; i < sessions.length; i++) {
+            long timestamp = sessions[i].getTransactionTimestamp();
+
+            if (liveTransactionTimestamps.contains(timestamp)) {
+                set.add(sessions[i]);
+            } else if (sessions[i].isPreTransaction) {
+                set.add(sessions[i]);
+            }
+        }
+    }
+
+    void endTransactionTPL(Session session) {
+
+        if (catalogWriteSession != session) {
+            return;
+        }
+
+        catalogWriteSession = null;
+        isLockedMode        = false;
+    }
+
+    boolean beingActionTPL(Session session, Statement cs) {
+
+        if (cs == null) {
+            return true;
+        }
+
+        if (session.abortTransaction) {
+            return false;
+        }
+
+        session.tempSet.clear();
+
+        if (cs.isCatalogChange()) {
+            if (catalogWriteSession == null) {
+                getTransactionSessions(session.tempSet);
+                session.tempSet.remove(session);
+
+                if (session.tempSet.isEmpty()) {
+                    catalogWriteSession = session;
+                    isLockedMode        = true;
+                } else {
+                    catalogWriteSession = session;
+                    isLockedMode        = true;
+
+                    setWaitingSessionTPL(session);
+                }
+
+                return true;
+            } else {
+                catalogWriteSession.waitingSessions.add(session);
+                session.latch.countUp();
+
+                return true;
+            }
+        }
+
+        if (!isLockedMode) {
+            return true;
+        }
+
+        boolean needsLock = cs.getTableNamesForRead().length > 0
+                            || cs.getTableNamesForWrite().length > 0;
+
+        if (!needsLock) {
+            return true;
+        }
+
+        if (cs.getTableNamesForWrite().length > 0) {
+            if (cs.getTableNamesForWrite()[0].schema
+                    == SqlInvariants.LOBS_SCHEMA_HSQLNAME) {
+                return true;
+            }
+        } else if (cs.getTableNamesForRead().length > 0) {
+            if (cs.getTableNamesForRead()[0].schema
+                    == SqlInvariants.LOBS_SCHEMA_HSQLNAME) {
+                return true;
+            }
+        }
+
+        catalogWriteSession.waitingSessions.add(session);
+        session.latch.countUp();
+
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/Trigger.java b/src/org/hsqldb/Trigger.java
new file mode 100644
index 0000000..a3979be
--- /dev/null
+++ b/src/org/hsqldb/Trigger.java
@@ -0,0 +1,128 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+// fredt@users 20030727 - signature altered to support update triggers
+/*
+
+Contents of row1[] and row2[] in each type of trigger.
+
+AFTER INSERT
+ - row1[] contains single String object = "Statement-level".
+
+AFTER UPDATE
+ - row1[] contains single String object = "Statement-level".
+
+AFTER DELETE
+ - row1[] contains single String object = "Statement-level".
+
+BEFORE INSERT FOR EACH ROW
+ - row2[] contains data about to be inserted and this can
+be modified within the trigger such that modified data gets written to the
+database.
+
+AFTER INSERT FOR EACH ROW
+ - row2[] contains data just inserted into the table.
+
+BEFORE UPDATE FOR EACH ROW
+ - row1[] contains currently stored data and not the data that is about to be
+updated.
+
+ - row2[] contains the data that is about to be updated.
+
+AFTER UPDATE FOR EACH ROW
+ - row1[] contains old stored data.
+ - row2[] contains the new data.
+
+BEFORE DELETE FOR EACH ROW
+ - row1[] contains row data about to be deleted.
+
+AFTER DELETE FOR EACH ROW
+ - row1[] contains row data that has been deleted.
+
+List compiled by Andrew Knight (quozzbat@users)
+*/
+
+/**
+ * The interface an HSQLDB TRIGGER must implement. The user-supplied class that
+ * implements this must have a default constructor.
+ *
+ * @author Peter Hudson
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public interface Trigger {
+
+    // type of trigger
+    int INSERT_AFTER      = 0;
+    int DELETE_AFTER      = 1;
+    int UPDATE_AFTER      = 2;
+    int INSERT_AFTER_ROW  = 3;
+    int DELETE_AFTER_ROW  = 4;
+    int UPDATE_AFTER_ROW  = 5;
+    int INSERT_BEFORE_ROW = 6;
+    int DELETE_BEFORE_ROW = 7;
+    int UPDATE_BEFORE_ROW = 8;
+
+    /**
+     * The method invoked upon each triggered action.
+     *
+     * <p> type contains the integer index id for trigger type, e.g.
+     * TriggerDef.INSERT_AFTER
+     *
+     * <p> For all triggers defined as default FOR EACH STATEMENT both
+     *  oldRow and newRow are null.
+     *
+     * <p> For triggers defined as FOR EACH ROW, the following will apply:
+     *
+     * <p> When UPDATE triggers are fired, oldRow contains the existing values
+     * of the table row and newRow contains the new values.
+     *
+     * <p> For INSERT triggers, oldRow is null and newRow contains the table row
+     * to be inserted. For DELETE triggers, newRow is null and oldRow contains
+     * the table row to be deleted.
+     *
+     * <p> For error conditions, users can construct an HsqlException using one
+     * of the static methods of org.hsqldb.error.Error with a predefined
+     * SQL State from org.hsqldb.error.ErrorCode.
+     *
+     * @param type int
+     * @param trigName the name of the trigger
+     * @param tabName the name of the table upon which the triggered action is
+     *   occuring
+     * @param oldRow the old row
+     * @param newRow the new row
+     * @throws HsqlException
+     */
+    void fire(int type, String trigName, String tabName, Object[] oldRow,
+              Object[] newRow) throws HsqlException;
+}
diff --git a/src/org/hsqldb/TriggerDef.java b/src/org/hsqldb/TriggerDef.java
new file mode 100644
index 0000000..ab9224d
--- /dev/null
+++ b/src/org/hsqldb/TriggerDef.java
@@ -0,0 +1,672 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlDeque;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.rights.Grantee;
+
+// peterhudson@users 20020130 - patch 478657 by peterhudson - triggers support
+// fredt@users 20020130 - patch 1.7.0 by fredt
+// added new class as jdk 1.1 does not allow use of LinkedList
+// fredt@users 20030727 - signature and other alterations
+// fredt@users 20040430 - changes by mattshaw@users to allow termination of the
+// trigger thread -
+
+/**
+ *  Represents an HSQLDB Trigger definition. <p>
+ *
+ *  Provides services regarding HSLDB Trigger execution and metadata. <p>
+ *
+ *  Development of the trigger implementation sponsored by Logicscope
+ *  Realisations Ltd
+ *
+ * @author Peter Hudson - Logicscope Realisations Ltd
+ * @version  1.7.0 (1.0.0.3)
+ *      Revision History: 1.0.0.1 First release in hsqldb 1.61
+ *      1.0.0.2 'nowait' support to prevent deadlock 1.0.0.3 multiple row
+ *      queue for each trigger
+ */
+public class TriggerDef implements Runnable, SchemaObject {
+
+    static final int OLD_ROW   = 0;
+    static final int NEW_ROW   = 1;
+    static final int OLD_TABLE = 2;
+    static final int NEW_TABLE = 3;
+    static final int BEFORE    = 4;
+    static final int AFTER     = 5;
+    static final int INSTEAD   = 6;
+
+    //
+    static final int NUM_TRIGGER_OPS = 3;                      // {ins,del,upd}
+    static final int NUM_TRIGS       = NUM_TRIGGER_OPS * 3;    // {b}{fer}, {a},{fer, fes}
+
+    //
+    static final TriggerDef[] emptyArray = new TriggerDef[]{};
+    Table[]                   transitions;
+    RangeVariable[]           rangeVars;
+    Expression                condition;
+    boolean                   hasTransitionTables;
+    boolean                   hasTransitionRanges;
+    String                    conditionSQL;
+    String                    procedureSQL;
+    Routine                   routine;
+    int[]                     updateColumns;
+
+    // other variables
+    private HsqlName name;
+    long             changeTimestamp;
+    int              actionTiming;
+    int              operationType;
+    boolean          forEachRow;
+    boolean          nowait;                                   // block or overwrite if queue full
+    int              maxRowsQueued;                            // max size of queue of pending triggers
+    Table            table;
+    Trigger          trigger;
+    String           triggerClassName;
+    int              triggerType;
+    Thread           thread;
+
+    //protected boolean busy;               // firing trigger in progress
+    protected HsqlDeque        pendingQueue;                   // row triggers pending
+    protected int              rowsQueued;                     // rows in pendingQueue
+    protected boolean          valid     = true;               // parsing valid
+    protected volatile boolean keepGoing = true;
+
+    TriggerDef() {}
+
+    /**
+     *  Constructs a new TriggerDef object to represent an HSQLDB trigger
+     *  declared in an SQL CREATE TRIGGER statement.
+     *
+     *  Changes in 1.7.2 allow the queue size to be specified as 0. A zero
+     *  queue size causes the Trigger.fire() code to run in the main thread of
+     *  execution (fully inside the enclosing transaction). Otherwise, the code
+     *  is run in the Trigger's own thread.
+     *  (fredt@users)
+     *
+     * @param  name The trigger object's HsqlName
+     * @param  when whether the trigger fires
+     *      before, after or instead of the triggering event
+     * @param  operation the triggering operation;
+     *      currently insert, update, or delete
+     * @param  forEach indicates whether the trigger is fired for each row
+     *      (true) or statement (false)
+     * @param  table the Table object upon which the indicated operation
+     *      fires the trigger
+     * @param  triggerClassName the fully qualified named of the class implementing
+     *      the org.hsqldb.Trigger (trigger body) interface
+     * @param  noWait do not wait for available space on the pending queue; if
+     *      the pending queue does not have fewer than nQueueSize queued items,
+     *      then overwrite the current tail instead
+     * @param  queueSize the length to which the pending queue may grow before
+     *      further additions are either blocked or overwrite the tail entry,
+     *      as determined by noWait
+     */
+    public TriggerDef(HsqlNameManager.HsqlName name, int when, int operation,
+                      boolean forEach, Table table, Table[] transitions,
+                      RangeVariable[] rangeVars, Expression condition,
+                      String conditionSQL, int[] updateColumns,
+                      String triggerClassName, boolean noWait, int queueSize) {
+
+        this(name, when, operation, forEach, table, transitions, rangeVars,
+             condition, conditionSQL, updateColumns);
+
+        this.triggerClassName = triggerClassName;
+        this.nowait           = noWait;
+        this.maxRowsQueued    = queueSize;
+        rowsQueued            = 0;
+        pendingQueue          = new HsqlDeque();
+
+        Class cl = null;
+
+        try {
+            cl = Class.forName(triggerClassName, true,
+                               Thread.currentThread().getContextClassLoader());
+        } catch (Throwable t1) {
+            try {
+                cl = Class.forName(triggerClassName);
+            } catch (Throwable t) {}
+        }
+
+        if (cl == null) {
+            valid   = false;
+            trigger = new DefaultTrigger();
+        } else {
+            try {
+
+                // dynamically instantiate it
+                trigger = (Trigger) cl.newInstance();
+            } catch (Throwable t1) {
+                valid   = false;
+                trigger = new DefaultTrigger();
+            }
+        }
+    }
+
+    public TriggerDef(HsqlNameManager.HsqlName name, int when, int operation,
+                      boolean forEachRow, Table table, Table[] transitions,
+                      RangeVariable[] rangeVars, Expression condition,
+                      String conditionSQL, int[] updateColumns) {
+
+        this.name          = name;
+        this.actionTiming  = when;
+        this.operationType = operation;
+        this.forEachRow    = forEachRow;
+        this.table         = table;
+        this.transitions   = transitions;
+        this.rangeVars     = rangeVars;
+        this.condition     = condition == null ? Expression.EXPR_TRUE
+                                               : condition;
+        this.updateColumns = updateColumns;
+        this.conditionSQL  = conditionSQL;
+        hasTransitionRanges = transitions[OLD_ROW] != null
+                              || transitions[NEW_ROW] != null;
+        hasTransitionTables = transitions[OLD_TABLE] != null
+                              || transitions[NEW_TABLE] != null;
+
+        setUpIndexesAndTypes();
+    }
+
+    public boolean isValid() {
+        return valid;
+    }
+
+    public int getType() {
+        return SchemaObject.TRIGGER;
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public HsqlName getCatalogName() {
+        return name.schema.schema;
+    }
+
+    public HsqlName getSchemaName() {
+        return name.schema;
+    }
+
+    public Grantee getOwner() {
+        return name.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+        return new OrderedHashSet();
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    /**
+     *  Retrieves the SQL character sequence required to (re)create the
+     *  trigger, as a StringBuffer
+     *
+     * @return the SQL character sequence required to (re)create the
+     *  trigger
+     */
+    public String getSQL() {
+
+        StringBuffer sb = getSQLMain();
+
+        if (maxRowsQueued != 0) {
+            sb.append(Tokens.T_QUEUE).append(' ');
+            sb.append(maxRowsQueued).append(' ');
+
+            if (nowait) {
+                sb.append(Tokens.T_NOWAIT).append(' ');
+            }
+        }
+
+        sb.append(Tokens.T_CALL).append(' ');
+        sb.append(StringConverter.toQuotedString(triggerClassName, '"',
+                false));
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return changeTimestamp;
+    }
+
+    public StringBuffer getSQLMain() {
+
+        StringBuffer sb = new StringBuffer(256);
+
+        sb.append(Tokens.T_CREATE).append(' ');
+        sb.append(Tokens.T_TRIGGER).append(' ');
+        sb.append(name.getSchemaQualifiedStatementName()).append(' ');
+        sb.append(getActionTimingString()).append(' ');
+        sb.append(getEventTypeString()).append(' ');
+
+        if (updateColumns != null) {
+            sb.append(Tokens.T_OF).append(' ');
+
+            for (int i = 0; i < updateColumns.length; i++) {
+                if (i != 0) {
+                    sb.append(',');
+                }
+
+                HsqlName name = table.getColumn(updateColumns[i]).getName();
+
+                sb.append(name.statementName);
+            }
+
+            sb.append(' ');
+        }
+
+        sb.append(Tokens.T_ON).append(' ');
+        sb.append(table.getName().getSchemaQualifiedStatementName());
+        sb.append(' ');
+
+        if (hasTransitionRanges || hasTransitionTables) {
+            sb.append(Tokens.T_REFERENCING).append(' ');
+
+            if (transitions[OLD_ROW] != null) {
+                sb.append(Tokens.T_OLD).append(' ').append(Tokens.T_ROW);
+                sb.append(' ').append(Tokens.T_AS).append(' ');
+                sb.append(transitions[OLD_ROW].getName().statementName);
+                sb.append(' ');
+            }
+
+            if (transitions[NEW_ROW] != null) {
+                sb.append(Tokens.T_NEW).append(' ').append(Tokens.T_ROW);
+                sb.append(' ').append(Tokens.T_AS).append(' ');
+                sb.append(transitions[NEW_ROW].getName().statementName);
+                sb.append(' ');
+            }
+
+            if (transitions[OLD_TABLE] != null) {
+                sb.append(Tokens.T_OLD).append(' ').append(Tokens.T_TABLE);
+                sb.append(' ').append(Tokens.T_AS).append(' ');
+                sb.append(transitions[OLD_TABLE].getName().statementName);
+                sb.append(' ');
+            }
+
+            if (transitions[NEW_TABLE] != null) {
+                sb.append(Tokens.T_OLD).append(' ').append(Tokens.T_TABLE);
+                sb.append(' ').append(Tokens.T_AS).append(' ');
+                sb.append(transitions[NEW_TABLE].getName().statementName);
+                sb.append(' ');
+            }
+        }
+
+        if (forEachRow) {
+            sb.append(Tokens.T_FOR).append(' ');
+            sb.append(Tokens.T_EACH).append(' ');
+            sb.append(Tokens.T_ROW).append(' ');
+        }
+
+        if (condition != Expression.EXPR_TRUE) {
+            sb.append(Tokens.T_WHEN).append(' ');
+            sb.append(Tokens.T_OPENBRACKET).append(conditionSQL);
+            sb.append(Tokens.T_CLOSEBRACKET).append(' ');
+        }
+
+        return sb;
+    }
+
+    public String getClassName() {
+        return trigger.getClass().getName();
+    }
+
+    public String getActionTimingString() {
+
+        switch (this.actionTiming) {
+
+            case TriggerDef.BEFORE :
+                return Tokens.T_BEFORE;
+
+            case TriggerDef.AFTER :
+                return Tokens.T_AFTER;
+
+            case TriggerDef.INSTEAD :
+                return Tokens.T_INSTEAD + ' ' + Tokens.T_OF;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "TriggerDef");
+        }
+    }
+
+    public String getEventTypeString() {
+
+        switch (this.operationType) {
+
+            case StatementTypes.INSERT :
+                return Tokens.T_INSERT;
+
+            case StatementTypes.DELETE_WHERE :
+                return Tokens.T_DELETE;
+
+            case StatementTypes.UPDATE_WHERE :
+                return Tokens.T_UPDATE;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "TriggerDef");
+        }
+    }
+
+    public boolean isForEachRow() {
+        return forEachRow;
+    }
+
+    public String getConditionSQL() {
+        return conditionSQL;
+    }
+
+    public String getProcedureSQL() {
+        return procedureSQL;
+    }
+
+    public int[] getUpdateColumnIndexes() {
+        return updateColumns;
+    }
+
+    public boolean hasOldTable() {
+        return false;
+    }
+
+    public boolean hasNewTable() {
+        return false;
+    }
+
+    public String getOldTransitionRowName() {
+
+        return transitions[OLD_ROW] == null ? null
+                                            : transitions[OLD_ROW].getName()
+                                            .name;
+    }
+
+    public String getNewTransitionRowName() {
+
+        return transitions[NEW_ROW] == null ? null
+                                            : transitions[NEW_ROW].getName()
+                                            .name;
+    }
+
+    public String getOldTransitionTableName() {
+
+        return transitions[OLD_TABLE] == null ? null
+                                              : transitions[OLD_TABLE]
+                                              .getName().name;
+    }
+
+    public String getNewTransitionTableName() {
+
+        return transitions[NEW_TABLE] == null ? null
+                                              : transitions[NEW_TABLE]
+                                              .getName().name;
+    }
+
+    /**
+     *  Given the SQL creating the trigger, set up the index to the
+     *  HsqlArrayList[] and the associated GRANT type
+     */
+    void setUpIndexesAndTypes() {
+
+        triggerType = 0;
+
+        switch (operationType) {
+
+            case StatementTypes.INSERT :
+                triggerType = Trigger.INSERT_AFTER;
+                break;
+
+            case StatementTypes.DELETE_WHERE :
+                triggerType = Trigger.DELETE_AFTER;
+                break;
+
+            case StatementTypes.UPDATE_WHERE :
+                triggerType = Trigger.UPDATE_AFTER;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "TriggerDef");
+        }
+
+        if (forEachRow) {
+            triggerType += NUM_TRIGGER_OPS;
+        }
+
+        if (actionTiming == TriggerDef.BEFORE
+                || actionTiming == TriggerDef.INSTEAD) {
+            triggerType += NUM_TRIGGER_OPS;
+        }
+    }
+
+    /**
+     *  Return the type code for operation tokens
+     */
+    static int getOperationType(int token) {
+
+        switch (token) {
+
+            case Tokens.INSERT :
+                return StatementTypes.INSERT;
+
+            case Tokens.DELETE :
+                return StatementTypes.DELETE_WHERE;
+
+            case Tokens.UPDATE :
+                return StatementTypes.UPDATE_WHERE;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "TriggerDef");
+        }
+    }
+
+    static int getTiming(int token) {
+
+        switch (token) {
+
+            case Tokens.BEFORE :
+                return TriggerDef.BEFORE;
+
+            case Tokens.AFTER :
+                return TriggerDef.AFTER;
+
+            case Tokens.INSTEAD :
+                return TriggerDef.INSTEAD;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "TriggerDef");
+        }
+    }
+
+    public int getStatementType() {
+        return operationType;
+    }
+
+    /**
+     *  run method declaration <P>
+     *
+     *  the trigger JSP is run in its own thread here. Its job is simply to
+     *  wait until it is told by the main thread that it should fire the
+     *  trigger.
+     */
+    public void run() {
+
+        while (keepGoing) {
+            TriggerData triggerData = popPair();
+
+            if (triggerData != null) {
+                if (triggerData.username != null) {
+                    trigger.fire(this.triggerType, name.name,
+                                 table.getName().name, triggerData.oldRow,
+                                 triggerData.newRow);
+                }
+            }
+        }
+    }
+
+    /**
+     * start the thread if this is threaded
+     */
+    public synchronized void start() {
+
+        if (maxRowsQueued != 0) {
+            thread = new Thread(this);
+
+            thread.start();
+        }
+    }
+
+    /**
+     * signal the thread to stop
+     */
+    public synchronized void terminate() {
+
+        keepGoing = false;
+
+        notify();
+    }
+
+    /**
+     *  pop2 method declaration <P>
+     *
+     *  The consumer (trigger) thread waits for an event to be queued <P>
+     *
+     *  <B>Note: </B> This push/pop pairing assumes a single producer thread
+     *  and a single consumer thread _only_.
+     *
+     * @return  Description of the Return Value
+     */
+    synchronized TriggerData popPair() {
+
+        if (rowsQueued == 0) {
+            try {
+                wait();    // this releases the lock monitor
+            } catch (InterruptedException e) {
+
+                /* ignore and resume */
+            }
+        }
+
+        rowsQueued--;
+
+        notify();    // notify push's wait
+
+        if (pendingQueue.size() == 0) {
+            return null;
+        } else {
+            return (TriggerData) pendingQueue.removeFirst();
+        }
+    }
+
+    /**
+     *  The main thread tells the trigger thread to fire by this call.
+     *  If this Trigger is not threaded then the fire method is caled
+     *  immediately and executed by the main thread. Otherwise, the row
+     *  data objects are added to the queue to be used by the Trigger thread.
+     *
+     * @param  row1
+     * @param  row2
+     */
+    synchronized void pushPair(Session session, Object[] row1, Object[] row2) {
+
+        if (maxRowsQueued == 0) {
+            trigger.fire(triggerType, name.name, table.getName().name, row1,
+                         row2);
+
+            return;
+        }
+
+        if (rowsQueued >= maxRowsQueued) {
+            if (nowait) {
+                pendingQueue.removeLast();    // overwrite last
+            } else {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+
+                    /* ignore and resume */
+                }
+
+                rowsQueued++;
+            }
+        } else {
+            rowsQueued++;
+        }
+
+        pendingQueue.add(new TriggerData(session, row1, row2));
+        notify();    // notify pop's wait
+    }
+
+    public boolean isBusy() {
+        return rowsQueued != 0;
+    }
+
+    public Table getTable() {
+        return table;
+    }
+
+    public String getActionOrientationString() {
+        return forEachRow ? Tokens.T_ROW
+                          : Tokens.T_STATEMENT;
+    }
+
+    /**
+     * Class to store the data used to fire a trigger. The username attribute
+     * is not used but it allows developers to change the signature of the
+     * fire method of the Trigger class and pass the user name to the Trigger.
+     */
+    static class TriggerData {
+
+        public Object[] oldRow;
+        public Object[] newRow;
+        public String   username;
+
+        public TriggerData(Session session, Object[] oldRow, Object[] newRow) {
+
+            this.oldRow   = oldRow;
+            this.newRow   = newRow;
+            this.username = session.getUsername();
+        }
+    }
+
+    static class DefaultTrigger implements org.hsqldb.Trigger {
+
+        public void fire(int i, String name, String table, Object[] row1,
+                         Object[] row2) {
+
+            // do nothing
+        }
+    }
+}
diff --git a/src/org/hsqldb/TriggerDefSQL.java b/src/org/hsqldb/TriggerDefSQL.java
new file mode 100644
index 0000000..11b781e
--- /dev/null
+++ b/src/org/hsqldb/TriggerDefSQL.java
@@ -0,0 +1,126 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.result.Result;
+
+/**
+ * Implementation of SQL TRIGGER objects.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class TriggerDefSQL extends TriggerDef {
+
+    OrderedHashSet references;
+
+    public TriggerDefSQL(HsqlNameManager.HsqlName name, int when,
+                         int operation, boolean forEachRow, Table table,
+                         Table[] transitions, RangeVariable[] rangeVars,
+                         Expression condition, String conditionSQL,
+                         int[] updateColumns, Routine routine) {
+
+        super(name, when, operation, forEachRow, table, transitions,
+              rangeVars, condition, conditionSQL, updateColumns);
+
+        this.routine    = routine;
+        this.references = routine.getReferences();
+    }
+
+    public OrderedHashSet getReferences() {
+        return routine.getReferences();
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public String getClassName() {
+        return null;
+    }
+
+    public boolean hasOldTable() {
+        return transitions[OLD_TABLE] != null;
+    }
+
+    public boolean hasNewTable() {
+        return transitions[NEW_TABLE] != null;
+    }
+
+    synchronized void pushPair(Session session, Object[] oldData,
+                               Object[] newData) {
+
+        Result result = Result.updateZeroResult;
+
+        if (session.sessionContext.depth > 128) {
+            throw Error.error(ErrorCode.GENERAL_ERROR);
+        }
+
+        session.sessionContext.push();
+
+        if (transitions[OLD_ROW] != null) {
+            rangeVars[OLD_ROW].getIterator(session).setCurrent(oldData);
+        }
+
+        if (transitions[NEW_ROW] != null) {
+            rangeVars[NEW_ROW].getIterator(session).setCurrent(newData);
+        }
+
+        if (condition.testCondition(session)) {
+            session.sessionContext.routineVariables =
+                ValuePool.emptyObjectArray;
+            result = routine.statement.execute(session);
+        }
+
+        session.sessionContext.pop();
+
+        if (result.isError()) {
+            throw result.getException();
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = getSQLMain();
+
+        sb.append(routine.statement.getSQL());
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/View.java b/src/org/hsqldb/View.java
new file mode 100644
index 0000000..01cf9d3
--- /dev/null
+++ b/src/org/hsqldb/View.java
@@ -0,0 +1,320 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArraySort;
+import org.hsqldb.lib.OrderedHashSet;
+
+// fredt@users 20020420 - patch523880 by leptipre@users - VIEW support - modified
+// fredt@users 20031227 - remimplementated as compiled query
+
+/**
+ * Represents an SQL VIEW based on a query expression
+ *
+ * @author leptipre@users
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.7.0
+ */
+public class View extends TableDerived {
+
+    SubQuery       viewSubQuery;
+    private String statement;
+
+    //
+    private HsqlName[] columnNames;
+
+    /**
+     * List of subqueries in this view in order of materialization. Last
+     * element is the view itself.
+     */
+    SubQuery[] viewSubqueries;
+
+    /**
+     * Names of SCHEMA objects referenced in VIEW
+     */
+    private OrderedHashSet schemaObjectNames;
+
+    /**
+     * check option
+     */
+    private int check;
+
+    //
+    private Table baseTable;
+
+    //
+    Expression checkExpression;
+
+    //
+    boolean isTriggerInsertable;
+    boolean isTriggerUpdatable;
+    boolean isTriggerDeletable;
+
+    View(Database db, HsqlName name, HsqlName[] columnNames, int check) {
+
+        super(db, name, TableBase.VIEW_TABLE);
+
+        this.columnNames = columnNames;
+        this.check       = check;
+    }
+
+    public int getType() {
+        return SchemaObject.VIEW;
+    }
+
+    public OrderedHashSet getReferences() {
+        return schemaObjectNames;
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    /**
+     * Compiles the query expression and sets up the columns.
+     */
+    public void compile(Session session, SchemaObject parentObject) {
+
+        ParserDQL p = new ParserDQL(session, new Scanner(statement));
+
+        p.read();
+
+        viewSubQuery    = p.XreadViewSubquery(this);
+        queryExpression = viewSubQuery.queryExpression;
+
+        if (getColumnCount() == 0) {
+            if (columnNames == null) {
+                columnNames =
+                    viewSubQuery.queryExpression.getResultColumnNames();
+            }
+
+            if (columnNames.length
+                    != viewSubQuery.queryExpression.getColumnCount()) {
+                throw Error.error(ErrorCode.X_42593, getName().statementName);
+            }
+
+            TableUtil.setColumnsInSchemaTable(
+                this, columnNames, queryExpression.getColumnTypes());
+        }
+
+        //
+        OrderedHashSet set = queryExpression.getSubqueries();
+
+        if (set == null) {
+            viewSubqueries = new SubQuery[]{ viewSubQuery };
+        } else {
+            set.add(viewSubQuery);
+
+            viewSubqueries = new SubQuery[set.size()];
+
+            set.toArray(viewSubqueries);
+            ArraySort.sort(viewSubqueries, 0, viewSubqueries.length,
+                           viewSubqueries[0]);
+        }
+
+        for (int i = 0; i < viewSubqueries.length; i++) {
+            if (viewSubqueries[i].parentView == null) {
+                viewSubqueries[i].parentView = this;
+            }
+
+            viewSubqueries[i].prepareTable(session);
+        }
+
+        //
+        viewSubQuery.getTable().view       = this;
+        viewSubQuery.getTable().columnList = columnList;
+        schemaObjectNames = p.compileContext.getSchemaObjectNames();
+        baseTable                          = queryExpression.getBaseTable();
+
+        if (baseTable == null) {
+            return;
+        }
+
+        switch (check) {
+
+            case SchemaObject.ViewCheckModes.CHECK_NONE :
+                break;
+
+            case SchemaObject.ViewCheckModes.CHECK_LOCAL :
+                checkExpression = queryExpression.getCheckCondition();
+                break;
+
+            case SchemaObject.ViewCheckModes.CHECK_CASCADE :
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "View");
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer(128);
+
+        sb.append(Tokens.T_CREATE).append(' ').append(Tokens.T_VIEW);
+        sb.append(' ');
+        sb.append(getName().getSchemaQualifiedStatementName()).append(' ');
+        sb.append('(');
+
+        int count = getColumnCount();
+
+        for (int j = 0; j < count; j++) {
+            sb.append(getColumn(j).getName().statementName);
+
+            if (j < count - 1) {
+                sb.append(',');
+            }
+        }
+
+        sb.append(')').append(' ').append(Tokens.T_AS).append(' ');
+        sb.append(getStatement());
+
+        return sb.toString();
+    }
+
+    public int[] getUpdatableColumns() {
+        return queryExpression.getBaseTableColumnMap();
+    }
+
+    public long getChangeTimestamp() {
+        return changeTimestamp;
+    }
+
+    public boolean isTriggerInsertable() {
+        return isTriggerInsertable;
+    }
+
+    public boolean isTriggerUpdatable() {
+        return isTriggerUpdatable;
+    }
+
+    public boolean isTriggerDeletable() {
+        return isTriggerDeletable;
+    }
+
+    void addTrigger(TriggerDef td, HsqlName otherName) {
+
+        switch (td.operationType) {
+
+            case StatementTypes.INSERT :
+                if (isTriggerInsertable) {
+                    throw Error.error(ErrorCode.X_42545);
+                }
+
+                isTriggerInsertable = true;
+                break;
+
+            case StatementTypes.DELETE_WHERE :
+                if (isTriggerDeletable) {
+                    throw Error.error(ErrorCode.X_42545);
+                }
+
+                isTriggerDeletable = true;
+                break;
+
+            case StatementTypes.UPDATE_WHERE :
+                if (isTriggerUpdatable) {
+                    throw Error.error(ErrorCode.X_42545);
+                }
+
+                isTriggerUpdatable = true;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "View");
+        }
+
+        super.addTrigger(td, otherName);
+    }
+
+    void removeTrigger(TriggerDef td) {
+
+        switch (td.operationType) {
+
+            case StatementTypes.INSERT :
+                isTriggerInsertable = false;
+                break;
+
+            case StatementTypes.DELETE_WHERE :
+                isTriggerDeletable = false;
+                break;
+
+            case StatementTypes.UPDATE_WHERE :
+                isTriggerInsertable = false;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "View");
+        }
+
+        super.removeTrigger(td);
+    }
+
+    public int getCheckOption() {
+        return check;
+    }
+
+    /**
+     * Returns the query expression for the view.
+     */
+    public String getStatement() {
+        return statement;
+    }
+
+    public void setStatement(String sql) {
+        statement = sql;
+    }
+
+    /**
+     * Overridden to disable SET TABLE READONLY DDL for View objects.
+     */
+    public void setDataReadOnly(boolean value) {
+        throw Error.error(ErrorCode.X_28000);
+    }
+
+    public void collectAllFunctionExpressions(OrderedHashSet collector) {
+
+        // filter schemaObjectNames
+    }
+
+    public Table getSubqueryTable() {
+        return viewSubQuery.getTable();
+    }
+
+    public SubQuery[] getSubqueries() {
+        return viewSubqueries;
+    }
+}
diff --git a/src/org/hsqldb/cmdline/SqlFile.java b/src/org/hsqldb/cmdline/SqlFile.java
new file mode 100644
index 0000000..61581b5
--- /dev/null
+++ b/src/org/hsqldb/cmdline/SqlFile.java
@@ -0,0 +1,5524 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.cmdline;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.logging.Level;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.charset.Charset;
+import org.hsqldb.lib.AppendableException;
+import org.hsqldb.lib.RCData;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.lib.FrameworkLogger;
+import org.hsqldb.cmdline.sqltool.Token;
+import org.hsqldb.cmdline.sqltool.TokenList;
+import org.hsqldb.cmdline.sqltool.TokenSource;
+import org.hsqldb.cmdline.sqltool.SqlFileScanner;
+
+/* $Id: SqlFile.java 3628 2010-06-06 00:44:08Z unsaved $ */
+
+/**
+ * Encapsulation of SQL text and the environment under which it will executed
+ * with a JDBC Connection.
+ * 'SqlInputStream' would be a more precise name, but the content we are
+ * talking about here is what is colloqially known as the contents of
+ * "SQL file"s.
+ * <P>
+ * The file <CODE>src/org/hsqldb/sample/SqlFileEmbedder.java</CODE>
+ * in the HSQLDB distribution provides an example for using SqlFile to
+ * execute SQL files directly from your own Java classes.
+ * <P/><P>
+ * The complexities of passing userVars and macros maps are to facilitate
+ * strong scoping (among blocks and nested scripts).
+ * <P/><P>
+ * Some implementation comments and variable names use keywords based
+ * on the following definitions.  <UL>
+ * <LI> COMMAND = Statement || SpecialCommand || BufferCommand
+ * <LI>Statement = SQL statement like "SQL Statement;"
+ * <LI>SpecialCommand =  Special Command like "\x arg..."
+ * <LI>BufferCommand =  Editing/buffer command like ":s/this/that/"
+ * </UL>
+ * <P/><P>
+ * When entering SQL statements, you are always "appending" to the
+ * "immediate" command (not the "buffer", which is a different thing).
+ * All you can do to the immediate command is append new lines to it,
+ * execute it, or save it to buffer.
+ * When you are entering a buffer edit command like ":s/this/that/",
+ * your immediate command is the buffer-edit-command.  The buffer
+ * is the command string that you are editing.
+ * The buffer usually contains either an exact copy of the last command
+ * executed or sent to buffer by entering a blank line,
+ * but BUFFER commands can change the contents of the buffer.
+ * <P/><P>
+ * In general, the special commands mirror those of Postgresql's psql,
+ * but SqlFile handles command editing very differently than Postgresql
+ * does, in part because of Java's lack of support for raw tty I/O.
+ * The \p special command, in particular, is very different from psql's.
+ * <P/><P>
+ * Buffer commands are unique to SQLFile.  The ":" commands allow
+ * you to edit the buffer and to execute the buffer.
+ * <P/><P>
+ * \d commands are very poorly supported for Mysql because
+ * (a) Mysql lacks most of the most basic JDBC support elements, and
+ * the most basic role and schema features, and
+ * (b) to access the Mysql data dictionary, one must change the database
+ * instance (to do that would require work to restore the original state
+ * and could have disastrous effects upon transactions).
+ * <P/><P>
+ * The process*() methods, other than processBuffHist() ALWAYS execute
+ * on "buffer", and expect it to contain the method specific prefix
+ * (if any).
+ * <P/><P>
+ * The input/output Reader/Stream are generally managed by the caller.
+ * An exception is that the input reader may be closed automatically or on
+ * demand by the user, since in some cases this class builds the Reader.
+ * There is no corresponding functionality for output since the user always
+ * has control over that object (which may be null or System.out).
+ * <P/>
+ *
+ * @see <a href="../../../../util-guide/sqltool-chapt.html" target="guide">
+ *     The SqlTool chapter of the
+ *     HyperSQL Utilities Guide</a>
+ * @see org.hsqldb.sample.SqlFileEmbedder
+ * @version $Revision: 3628 $, $Date: 2010-06-05 20:44:08 -0400 (Sat, 05 Jun 2010) $
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+
+public class SqlFile {
+    private static FrameworkLogger logger =
+            FrameworkLogger.getLog(SqlFile.class);
+    private static final int DEFAULT_HISTORY_SIZE = 40;
+    private boolean          executing;
+    private boolean permitEmptySqlStatements;
+    private boolean          interactive;
+    private String           primaryPrompt    = "sql> ";
+    private static String    rawPrompt;
+    private static Method    createArrayOfMethod;
+    private String           contPrompt       = "  +> ";
+    private boolean          htmlMode;
+    private TokenList        history;
+    private String           nullRepToken;
+    private String           dsvTargetFile;
+    private String           dsvTargetTable;
+    private String           dsvConstCols;
+    private String           dsvRejectFile;
+    private String           dsvRejectReport;
+    private int              dsvRecordsPerCommit = 0;
+    /** Platform-specific line separator */
+    public static String     LS = System.getProperty("line.separator");
+    private int              maxHistoryLength = 1;
+    // TODO:  Implement PL variable to interactively change history length.
+    // Study to be sure this won't cause state inconsistencies.
+    private boolean          reportTimes;
+    private Reader           reader;
+    // Reader serves the auxiliary purpose of null meaning execute()
+    // has finished.
+    private String           inputStreamLabel;
+
+    static String            DEFAULT_FILE_ENCODING =
+                             System.getProperty("file.encoding");
+
+    /**
+     * N.b. javax.util.regex Optional capture groups (...)? are completely
+     * unpredictable wrt whether you get a null capture group vs. no capture.
+     * Must always check count!
+     */
+    private static Pattern   specialPattern =
+            Pattern.compile("(\\S+)(?:\\s+(.*\\S))?\\s*");
+    private static Pattern   plPattern  = Pattern.compile("(.*\\S)?\\s*");
+    private static Pattern   foreachPattern =
+            Pattern.compile("foreach\\s+(\\S+)\\s*\\(([^)]+)\\)\\s*");
+    private static Pattern   ifwhilePattern =
+            Pattern.compile("\\S+\\s*\\(([^)]*)\\)\\s*");
+    private static Pattern   varsetPattern =
+            Pattern.compile("(\\S+)\\s*([=_~])\\s*(?:(.*\\S)\\s*)?");
+    private static Pattern   substitutionPattern =
+            Pattern.compile("(\\S)(.+?)\\1(.*?)\\1(.+)?\\s*");
+            // Note that this pattern does not include the leading ":s".
+    private static Pattern   slashHistoryPattern =
+            Pattern.compile("\\s*/([^/]+)/\\s*(\\S.*)?");
+    private static Pattern   historyPattern =
+            Pattern.compile("\\s*(-?\\d+)?\\s*(\\S.*)?");
+            // Note that this pattern does not include the leading ":".
+    private static Pattern wincmdPattern;
+    private static Pattern useMacroPattern =
+            Pattern.compile("(\\w+)(\\s.*[^;])?(;?)");
+    private static Pattern editMacroPattern =
+            Pattern.compile("(\\w+)\\s*:(.*)");
+    private static Pattern spMacroPattern =
+            Pattern.compile("(\\w+)\\s+([*\\\\])(.*\\S)");
+    private static Pattern sqlMacroPattern =
+            Pattern.compile("(\\w+)\\s+(.*\\S)");
+    private static Pattern integerPattern = Pattern.compile("\\d+");
+    private static Pattern nameValPairPattern =
+            Pattern.compile("\\s*(\\w+)\\s*=(.*)");
+            // Specifically permits 0-length values, but not names.
+    private static Pattern dotPattern = Pattern.compile("(\\w*)\\.(\\w*)");
+    private static Pattern commitOccursPattern =
+            Pattern.compile("(?is)(?:set\\s+autocommit.*)|(commit\\s*)");
+    private static Pattern logPattern =
+        Pattern.compile("(?i)(FINER|WARNING|SEVERE|INFO|FINEST)\\s+(.*\\S)");
+    private static Pattern   arrayPattern =
+            Pattern.compile("ARRAY\\s*\\[\\s*(.*\\S)?\\s*\\]");
+
+    private static Map<String, Pattern> nestingPLCommands =
+            new HashMap<String, Pattern>();
+    static {
+        nestingPLCommands.put("if", ifwhilePattern);
+        nestingPLCommands.put("while", ifwhilePattern);
+        nestingPLCommands.put("foreach", foreachPattern);
+
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            wincmdPattern = Pattern.compile("([^\"]+)?(\"[^\"]*\")?");
+        }
+
+        rawPrompt = SqltoolRB.rawmode_prompt.getString() + "> ";
+        DSV_OPTIONS_TEXT = SqltoolRB.dsv_options.getString();
+        D_OPTIONS_TEXT = SqltoolRB.d_options.getString();
+        DSV_X_SYNTAX_MSG = SqltoolRB.dsv_x_syntax.getString();
+        DSV_M_SYNTAX_MSG = SqltoolRB.dsv_m_syntax.getString();
+        nobufferYetString = SqltoolRB.nobuffer_yet.getString();
+        try {
+            SqlFile.createArrayOfMethod = Connection.class.getDeclaredMethod(
+                    "createArrayOf", String.class, Object[].class);
+        } catch (Exception expectedException) {
+            // Purposeful no-op.  Leave createArrayOfMethod null.
+        }
+    }
+    // This can throw a runtime exception, but since the pattern
+    // Strings are constant, one test run of the program will tell
+    // if the patterns are good.
+
+    /**
+     * Encapsulate updating local variables which depend upon PL variables.
+     * <P>
+     * Right now this is called whenever the user variable map is changed.
+     * It would be more efficient to do it JIT by keeping track of when
+     * the vars may be "dirty" by a variable map change, and having all
+     * methods that use the settings call a conditional updater, but that
+     * is less reliable since there is no way to guarantee that the vars
+     * are not used without checking.
+     * UPDATE:  Could do what is needed by making a Map subclass with
+     * overridden setters which enforce dirtiness.
+     * <P/>
+     */
+    private void updateUserSettings() {
+        dsvSkipPrefix = SqlFile.convertEscapes(
+                shared.userVars.get("*DSV_SKIP_PREFIX"));
+        if (dsvSkipPrefix == null) {
+            dsvSkipPrefix = DEFAULT_SKIP_PREFIX;
+        }
+        dsvSkipCols = shared.userVars.get("*DSV_SKIP_COLS");
+        dsvTrimAll = Boolean.parseBoolean(
+                shared.userVars.get("*DSV_TRIM_ALL"));
+        dsvColDelim = SqlFile.convertEscapes(
+                shared.userVars.get("*DSV_COL_DELIM"));
+        if (dsvColDelim == null) {
+            dsvColDelim = SqlFile.convertEscapes(
+                    shared.userVars.get("*CSV_COL_DELIM"));
+        }
+        if (dsvColDelim == null) {
+            dsvColDelim = DEFAULT_COL_DELIM;
+        }
+        dsvColSplitter = shared.userVars.get("*DSV_COL_SPLITTER");
+        if (dsvColSplitter == null) {
+            dsvColSplitter = DEFAULT_COL_SPLITTER;
+        }
+
+        dsvRowDelim = SqlFile.convertEscapes(
+                shared.userVars.get("*DSV_ROW_DELIM"));
+        if (dsvRowDelim == null) {
+            dsvRowDelim = SqlFile.convertEscapes(
+                    shared.userVars.get("*CSV_ROW_DELIM"));
+        }
+        if (dsvRowDelim == null) {
+            dsvRowDelim = DEFAULT_ROW_DELIM;
+        }
+        dsvRowSplitter = shared.userVars.get("*DSV_ROW_SPLITTER");
+        if (dsvRowSplitter == null) {
+            dsvRowSplitter = DEFAULT_ROW_SPLITTER;
+        }
+
+        dsvTargetFile = shared.userVars.get("*DSV_TARGET_FILE");
+        if (dsvTargetFile == null) {
+            dsvTargetFile = shared.userVars.get("*CSV_FILEPATH");
+        }
+        dsvTargetTable = shared.userVars.get("*DSV_TARGET_TABLE");
+        if (dsvTargetTable == null) {
+            dsvTargetTable = shared.userVars.get("*CSV_TABLENAME");
+            // This just for legacy variable name.
+        }
+
+        dsvConstCols = shared.userVars.get("*DSV_CONST_COLS");
+        dsvRejectFile = shared.userVars.get("*DSV_REJECT_FILE");
+        dsvRejectReport = shared.userVars.get("*DSV_REJECT_REPORT");
+        if (shared.userVars.get("*DSV_RECORDS_PER_COMMIT") != null) try {
+            dsvRecordsPerCommit = Integer.parseInt(
+                    shared.userVars.get("*DSV_RECORDS_PER_COMMIT"));
+        } catch (NumberFormatException nfe) {
+            logger.error(SqltoolRB.reject_rpc.getString(
+                    shared.userVars.get("*DSV_RECORDS_PER_COMMIT")));
+            shared.userVars.remove("*DSV_REJECT_REPORT");
+            dsvRecordsPerCommit = 0;
+        }
+
+        nullRepToken = shared.userVars.get("*NULL_REP_TOKEN");
+        if (nullRepToken == null) {
+            nullRepToken = shared.userVars.get("*CSV_NULL_REP");
+        }
+        if (nullRepToken == null) {
+            nullRepToken = DEFAULT_NULL_REP;
+        }
+    }
+
+    /**
+     * Private class to "share" attributes among a family of SqlFile instances.
+     */
+    private static class SharedFields {
+        /* Since SqlTool can run against different versions of HSQLDB (plus
+         * against any JDBC database), it can't make assumptions about
+         * commands which may cause implicit commits, or commit state
+         * requirements with specific databases may have for specific SQL
+         * statements.  Therefore, we just assume that any statement other
+         * than COMMIT or SET AUTOCOMMIT causes an implicit COMMIT (the
+         * Java API spec mandates that setting AUTOCOMMIT causes an implicit
+         * COMMIT, regardless of whether turning AUTOCOMMIT on or off).
+         */
+        boolean possiblyUncommitteds;
+
+        Connection jdbcConn;
+
+        Map<String, String> userVars = new HashMap<String, String>();
+
+        Map<String, Token> macros = new HashMap<String, Token>();
+
+        PrintStream psStd;
+
+        SharedFields(PrintStream psStd) {
+            this.psStd = psStd;
+        }
+
+        String encoding;
+    }
+
+    private SharedFields shared;
+
+    private static final String DIVIDER =
+        "-----------------------------------------------------------------"
+        + "-----------------------------------------------------------------";
+    // Needs to be at least as wide as the widest field or header displayed.
+    private static String revnum =
+            "$Revision: 3628 $".substring("$Revision: ".length(),
+            "$Revision: 3628 $".length() - 2);
+
+    private static String DSV_OPTIONS_TEXT;
+    private static String D_OPTIONS_TEXT;
+
+    /**
+     * Convenience wrapper for the SqlFile(File, String) constructor
+     *
+     * @throws IOException
+     * @see #SqlFile(File, String)
+     */
+    public SqlFile(File inputFile) throws IOException {
+        this(inputFile, null);
+    }
+
+    /**
+     * Convenience wrapper for the SqlFile(File, String, boolean) constructor
+     *
+     * @param encoding is applied to both the given File and other files
+     *        read in or written out. Null will use your env+JVM settings.
+     * @throws IOException
+     * @see #SqlFile(File, String, boolean)
+     */
+    public SqlFile(File inputFile, String encoding) throws IOException {
+        this(inputFile, encoding, false);
+    }
+
+    /**
+     * Constructor for non-interactive usage with a SQL file, using the
+     * specified encoding and sending normal output to stdout.
+     *
+     * @param encoding is applied to the given File and other files
+     *        read in or written out. Null will use your env+JVM settings.
+     * @param interactive  If true, prompts are printed, the interactive
+     *                     Special commands are enabled, and
+     *                     continueOnError defaults to true.
+     * @throws IOException
+     * @see #SqlFile(Reader, String, PrintStream, String, boolean)
+     */
+    public SqlFile(File inputFile, String encoding, boolean interactive)
+            throws IOException {
+        this(new InputStreamReader(new FileInputStream(inputFile),
+                (encoding == null) ? DEFAULT_FILE_ENCODING : encoding),
+                inputFile.toString(), System.out, encoding, interactive);
+    }
+
+    /**
+     * Constructor for interactive usage with stdin/stdout
+     *
+     * @param encoding is applied to other files read in or written out (but
+     *                     not to stdin or stdout).
+     *                     Null will use your env+JVM settings.
+     * @param interactive  If true, prompts are printed, the interactive
+     *                     Special commands are enabled, and
+     *                     continueOnError defaults to true.
+     * @throws IOException
+     * @see #SqlFile(Reader, String, PrintStream, String, boolean)
+     */
+    public SqlFile(String encoding, boolean interactive) throws IOException {
+        this((encoding == null)
+                ? new InputStreamReader(System.in)
+                : new InputStreamReader(System.in, encoding),
+                "<stdin>", System.out, encoding, interactive);
+    }
+
+    /**
+     * Instantiate a SqlFile instance for SQL input from 'reader'.
+     *
+     * After any needed customization, the SQL can be executed by the
+     * execute method.
+     * <P>
+     * Most Special Commands and many Buffer commands are only for
+     * interactive use.
+     * </P> <P>
+     * This program never writes to an error stream (stderr or alternative).
+     * All meta messages and error messages are written using the logging
+     * facility.
+     * </P>
+     *
+     * @param reader       Source for the SQL to be executed.
+     *                     Caller is responsible for setting up encoding.
+     *                     (the 'encoding' parameter will NOT be applied
+     *                     to this reader).
+     * @param psStd        PrintStream for normal output.
+     *                     If null, normal output will be discarded.
+     *                     Caller is responsible for settingup encoding
+     *                     (the 'encoding' parameter will NOT be applied
+     *                     to this stream).
+     * @param interactive  If true, prompts are printed, the interactive
+     *                     Special commands are enabled, and
+     *                     continueOnError defaults to true.
+     * @throws IOException
+     * @see #execute()
+     */
+    public SqlFile(Reader reader, String inputStreamLabel,
+            PrintStream psStd, String encoding, boolean interactive)
+            throws IOException {
+        this(reader, inputStreamLabel);
+        try {
+            shared = new SharedFields(psStd);
+            setEncoding(encoding);
+            this.interactive = interactive;
+            continueOnError = this.interactive;
+
+            if (interactive) {
+                history = new TokenList();
+                maxHistoryLength = DEFAULT_HISTORY_SIZE;
+            }
+            updateUserSettings();
+            // Updates local vars basd on * shared.userVars
+            // even when (like now) these are all defaults.
+        } catch (IOException ioe) {
+            closeReader();
+            throw ioe;
+        } catch (RuntimeException re) {
+            closeReader();
+            throw re;
+        }
+    }
+
+    /**
+     * Wrapper for SqlFile(SqlFile, Reader, String)
+     *
+     * @see #SqlFile(SqlFile, Reader, String)
+     */
+    private SqlFile(SqlFile parentSqlFile, File inputFile) throws IOException {
+        this(parentSqlFile,
+                new InputStreamReader(new FileInputStream(inputFile),
+                (parentSqlFile.shared.encoding == null)
+                ? DEFAULT_FILE_ENCODING : parentSqlFile.shared.encoding),
+                inputFile.toString());
+    }
+
+    /**
+     * Constructor for recursion
+     */
+    private SqlFile(SqlFile parentSqlFile, Reader reader,
+            String inputStreamLabel) {
+        this(reader, inputStreamLabel);
+        try {
+            recursed = true;
+            shared = parentSqlFile.shared;
+            plMode = parentSqlFile.plMode;
+            interactive = false;
+            continueOnError = parentSqlFile.continueOnError;
+            // Nested input is non-interactive because it just can't work to
+            // have user append to edit buffer, and displaying prompts would
+            // be misleading and inappropriate; yet we will inherit the current
+            // continueOnError behavior.
+            updateUserSettings();
+            // Updates local vars basd on * shared.userVars
+        } catch (RuntimeException re) {
+            closeReader();
+            throw re;
+        }
+    }
+
+    /**
+     * Base Constructor which every other Constructor starts with
+     */
+    private SqlFile(Reader reader, String inputStreamLabel) {
+        logger.privlog(Level.FINER, "<init>ting SqlFile instance",
+                null, 2, FrameworkLogger.class);
+        if (reader == null)
+            throw new IllegalArgumentException("'reader' may not be null");
+        if (inputStreamLabel == null)
+            throw new IllegalArgumentException(
+                    "'inputStreamLabel' may not be null");
+
+        // Don't try to verify reader.ready() here, since we require it to be
+        // reayd to read only in execute(), plus in many caess it's useful for
+        // execute() to block.
+        this.reader = reader;
+        this.inputStreamLabel = inputStreamLabel;
+    }
+
+    public void setConnection(Connection jdbcConn) {
+        if (jdbcConn == null)
+            throw new IllegalArgumentException(
+                    "We don't yet support unsetting the JDBC Connection");
+        shared.jdbcConn = jdbcConn;
+    }
+
+    public Connection getConnection() {
+        return shared.jdbcConn;
+    }
+
+    public void setContinueOnError(boolean continueOnError) {
+        this.continueOnError = continueOnError;
+    }
+
+    public void setMaxHistoryLength(int maxHistoryLength) {
+        if (executing)
+            throw new IllegalStateException(
+                "Can't set maxHistoryLength after execute() has been called");
+        if (reader == null)
+            throw new IllegalStateException(
+                "Can't set maxHistoryLength execute() has run");
+        this.maxHistoryLength = maxHistoryLength;
+    }
+
+    public void addMacros(Map<String, Token> newMacros) {
+        shared.macros.putAll(newMacros);
+    }
+
+    public void addUserVars(Map<String, String> newUserVars) {
+        shared.userVars.putAll(newUserVars);
+    }
+
+    public Map<String, String> getUserVars() {
+        // Consider whether safer to return a deep copy.  Probably.
+        return shared.userVars;
+    }
+
+    public Map<String, Token> getMacros() {
+        // Consider whether safer to return a deep copy.  Probably.
+        return shared.macros;
+    }
+
+    /**
+     * This sets the instance variable and the corresponding PL variable.
+     *
+     * @param newEncoding may be null to revert to using defaults again.
+     */
+    private void setEncoding(String newEncoding)
+            throws UnsupportedEncodingException {
+        if (newEncoding == null) {
+            shared.encoding = null;
+            shared.userVars.remove("ENCODING");
+            return;
+        }
+        if (!Charset.isSupported(newEncoding))
+            throw new UnsupportedEncodingException(newEncoding);
+        shared.userVars.put("*ENCODING", newEncoding);
+        shared.encoding = newEncoding;
+    }
+
+    // So we can tell how to handle quit and break commands.
+    private boolean      recursed;
+    private PrintWriter pwQuery;
+    private PrintWriter pwDsv;
+    private boolean     continueOnError;
+    /*
+     * This is reset upon each execute() invocation (to true if interactive,
+     * false otherwise).
+     */
+    private SqlFileScanner      scanner;
+    private Token               buffer;
+    private boolean             preempt;
+    private String              lastSqlStatement;
+    private boolean             autoClose = true;
+
+    /**
+     * Specify whether the supplied or generated input Reader should
+     * automatically be closed by the execute() method.
+     * <P>
+     * execute() will close the Reader by default (i.e. 'autoClose' defaults
+     * to true).
+     * You may want to set this to false if you want to stop execution with
+     * \q or similar, then continue using the Reader or underlying Stream.
+     * </P> <P>
+     * The caller is always responsible for closing the output object (if any)
+     * used by SqlFile.
+     * </P>
+     */
+    public void setAutoClose(boolean autoClose) {
+        this.autoClose = autoClose;
+    }
+
+    /**
+     * Process all the commands from the file or Reader associated with
+     * "this" object.
+     * SQL commands in the content get executed against the current JDBC
+     * data source connection.
+     *
+     * @throws SQLExceptions thrown by JDBC driver.
+     *                       Only possible if in "\c false" mode.
+     * @throws SqlToolError  all other errors.
+     *               This includes including QuitNow, BreakException,
+     *               ContinueException for recursive calls only.
+     */
+    synchronized public void execute() throws SqlToolError, SQLException {
+        if (reader == null)
+            throw new IllegalStateException("Can't call execute() "
+                    + "more than once for a single SqlFile instance");
+
+        try {
+            scanner = new SqlFileScanner(reader);
+            scanner.setStdPrintStream(shared.psStd);
+            scanner.setRawLeadinPrompt(SqltoolRB.raw_leadin.getString());
+            if (interactive) {
+                stdprintln(SqltoolRB.SqlFile_banner.getString(revnum));
+                scanner.setRawPrompt(rawPrompt);
+                scanner.setSqlPrompt(contPrompt);
+                scanner.setSqltoolPrompt(primaryPrompt);
+                scanner.setInteractive(true);
+                if (shared.jdbcConn == null)
+                    stdprintln("To connect to a data source, use '\\j "
+                        + "urlid' or '\\j account password jdbc:url...'");
+                stdprint(primaryPrompt);
+            }
+            scanpass(scanner);
+        } finally {
+            try {
+                closeQueryOutputStream();
+                if (autoClose) closeReader();
+            } finally {
+                reader = null; // Encourage GC of buffers
+            }
+        }
+    }
+
+    /**
+     * Close the reader.
+     *
+     * The execute method will run this automatically, by default.
+     */
+    public void closeReader() {
+        if (reader == null) {
+            return;
+        }
+        try {
+            if (scanner != null) try {
+                scanner.yyclose();
+            } catch (IOException ioe) {
+                errprintln("Failed to close pipes");
+            }
+            try {
+                reader.close();
+            } catch (IOException ioe) {
+                // Purposefully empty.
+                // The reader will usually already be closed at this point.
+            }
+        } finally {
+            reader = null; // Encourage GC of buffers
+        }
+    }
+
+
+    /**
+     * Returns normalized nesting command String, like "if" or "foreach".
+     * If command is not a nesting command, returns null;
+     * If there's a proper command String, but the entire PL command is
+     * malformatted, throws.
+     */
+    private String nestingCommand(Token token) throws BadSpecial {
+        if (token.type != Token.PL_TYPE) return null;
+        // The scanner assures that val is non-null for PL_TYPEs.
+        String commandWord = token.val.replaceFirst("\\s.*", "");
+        if (!nestingPLCommands.containsKey(commandWord)) return null;
+        Pattern pattern = nestingPLCommands.get(commandWord);
+        if (pattern.matcher(token.val).matches()) return commandWord;
+        throw new BadSpecial(SqltoolRB.pl_malformat.getString());
+    }
+
+    synchronized protected void scanpass(TokenSource ts)
+                                     throws SqlToolError, SQLException {
+        boolean rollbackUncoms = true;
+        String nestingCommand;
+        Token token = null;
+
+        if (shared.userVars.size() > 0) {
+            plMode = true;
+        }
+
+        try {
+            while (true) try {
+                if (preempt) {
+                    token = buffer;
+                    preempt = false;
+                } else {
+                    token = ts.yylex();
+                    logger.finest("SqlFile got new token:  " + token);
+                }
+                if (token == null) break;
+
+                nestingCommand = nestingCommand(token);
+                if (nestingCommand != null) {
+                    if (token.nestedBlock == null) {
+                        token.nestedBlock = seekTokenSource(nestingCommand);
+                        /* This command (and the same recursive call inside
+                         * of the seekTokenSource() method) ensure that all
+                         * "blocks" are tokenized immediately as block
+                         * commands are encountered, and the blocks are
+                         * tokenized in their entirety all the way to the
+                         * leaves.
+                         */
+                    }
+                    processBlock(token);
+                        /* processBlock recurses through scanpass(),
+                         * which processes the nested commands which have
+                         * (in all cases) already beeen tokenized.
+                         */
+                    continue;
+                }
+
+                switch (token.type) {
+                    case Token.SYNTAX_ERR_TYPE:
+                        throw new SqlToolError(SqltoolRB.input_malformat.getString());
+                        // Will get here if Scanner can't match input to any
+                        // known command type.
+                        // An easy way to get here is to start a command with
+                        // quotes.
+                    case Token.UNTERM_TYPE:
+                        throw new SqlToolError(
+                                SqltoolRB.input_unterminated.getString(
+                                token.val));
+                    case Token.RAW_TYPE:
+                    case Token.RAWEXEC_TYPE:
+                        /*
+                         * A real problem in this block is that the Scanner
+                         * has already displayed the next prompt at this
+                         * point.  We handle this specially within this
+                         * block, but if we throw, the handler will not
+                         * know that the prompt has to be re-displayed.
+                         * I.e., KNOWN ISSUE:  For some errors caught during
+                         * raw command execution, interactive users will not
+                         * get a prompt to tell them to proceed.
+                         */
+                        if (token.val == null) token.val = "";
+                        /*
+                         * Don't have time know to figure out whether it would
+                         * ever be useful to send just (non-zero) whitespace
+                         * to the DB.  Prohibiting for now.
+                         */
+                        if (token.val.trim().length() < 1) {
+                            throw new SqlToolError(
+                                    SqltoolRB.raw_empty.getString());
+                        }
+                        int receivedType = token.type;
+                        token.type = Token.SQL_TYPE;
+                        if (setBuf(token) && receivedType == Token.RAW_TYPE
+                                && interactive) {
+                            stdprintln("");
+                            stdprintln(SqltoolRB.raw_movedtobuffer.getString());
+                            stdprint(primaryPrompt);
+                            // All of these stdprint*'s are to work around a
+                            // very complicated issue where the Scanner
+                            // has already displayed the next prompt before
+                            // we can display our status message.
+                        }
+                        if (receivedType == Token.RAWEXEC_TYPE) {
+                            historize();
+                            processSQL();
+                        }
+                        continue;
+                    case Token.MACRO_TYPE:
+                        processMacro(token);
+                        continue;
+                    case Token.PL_TYPE:
+                        setBuf(token);
+                        historize();
+                        processPL(null);
+                        continue;
+                    case Token.SPECIAL_TYPE:
+                        setBuf(token);
+                        historize();
+                        processSpecial(null);
+                        continue;
+                    case Token.EDIT_TYPE:
+                        // Scanner only returns EDIT_TYPEs in interactive mode
+                        processBuffHist(token);
+                        continue;
+                    case Token.BUFFER_TYPE:
+                        token.type = Token.SQL_TYPE;
+                        if (setBuf(token)) {
+                            stdprintln(
+                                    SqltoolRB.input_movedtobuffer.getString());
+                        }
+                        continue;
+                    case Token.SQL_TYPE:
+                        if (token.val == null) token.val = "";
+                        setBuf(token);
+                        historize();
+                        processSQL();
+                        continue;
+                    default:
+                        throw new RuntimeException(
+                                "Internal assertion failed.  "
+                                + "Unexpected token type: "
+                                + token.getTypeString());
+                }
+            } catch (BadSpecial bs) {
+                // BadSpecials ALWAYS have non-null getMessage().
+                if (token == null) {
+                    errprintln(SqltoolRB.errorat.getString(
+                            inputStreamLabel, "?", "?", bs.getMessage()));
+                } else {
+                    errprintln(SqltoolRB.errorat.getString(
+                            inputStreamLabel,
+                            Integer.toString(token.line),
+                            token.reconstitute(),
+                            bs.getMessage(), bs.getMessage()));
+                }
+                Throwable cause = bs.getCause();
+                if (cause != null) {
+                    errprintln(SqltoolRB.causereport.getString(
+                            cause.toString()));
+
+                }
+
+                if (!continueOnError) {
+                    throw new SqlToolError(bs);
+                }
+            } catch (SQLException se) {
+                //se.printStackTrace();
+                errprintln("SQL " + SqltoolRB.errorat.getString(
+                        inputStreamLabel,
+                        ((token == null) ? "?"
+                                         : Integer.toString(token.line)),
+                        lastSqlStatement,
+                        se.getMessage()));
+                // It's possible that we could have
+                // SQLException.getMessage() == null, but if so, I think
+                // it reasonable to show "null".  That's a DB inadequacy.
+
+                if (!continueOnError) {
+                    throw se;
+                }
+            } catch (BreakException be) {
+                String msg = be.getMessage();
+
+                if (recursed) {
+                    rollbackUncoms = false;
+                    // Recursion level will exit by rethrowing the BE.
+                    // We set rollbackUncoms to false because only the
+                    // top level should detect break errors and
+                    // possibly roll back.
+                } else if (msg == null || msg.equals("file")) {
+                    break;
+                } else {
+                    errprintln(SqltoolRB.break_unsatisfied.getString(msg));
+                }
+
+                if (recursed ||!continueOnError) {
+                    throw be;
+                }
+            } catch (ContinueException ce) {
+                String msg = ce.getMessage();
+
+                if (recursed) {
+                    rollbackUncoms = false;
+                } else {
+                    errprintln(SqltoolRB.continue_unsatisfied.getString(msg));
+                }
+
+                if (recursed ||!continueOnError) {
+                    throw ce;
+                }
+            } catch (QuitNow qn) {
+                throw qn;
+            } catch (SqlToolError ste) {
+                StringBuffer sb = new StringBuffer(SqltoolRB.errorat.getString(
+                    /* WARNING:  I have removed an extra LS appended to
+                     * non-null ste.getMessages() below because I believe that
+                     * it is unnecessary (and causes inconsistent blank lines
+                     * to be written).
+                     * If I am wrong and this is needed for Scanner display or
+                     * something, restore it.
+                     */
+                    ((token == null)
+                            ? (new String[] {
+                                inputStreamLabel, "?", "?",
+                                ((ste.getMessage() == null)
+                                        ? "" : ste.getMessage())
+                              })
+                            : (new String[] {
+                                inputStreamLabel, Integer.toString(token.line),
+                                ((token.val == null) ? "" : token.reconstitute()),
+                                ((ste.getMessage() == null)
+                                        ? "" : ste.getMessage())
+                              }))
+                ));
+                Throwable cause = ste.getCause();
+                errprintln((cause == null) ? sb.toString()
+                        : SqltoolRB.causereport.getString(cause.toString()));
+                if (!continueOnError) {
+                    throw ste;
+                }
+            }
+
+            rollbackUncoms = false;
+            // Exiting gracefully, so don't roll back.
+        } catch (IOException ioe) {
+            throw new SqlToolError(
+                    SqltoolRB.primaryinput_accessfail.getString(), ioe);
+        } catch (QuitNow qn) {
+            if (recursed) {
+                throw qn;
+                // Will rollback if conditions otherwise require.
+                // Otherwise top level will decide based upon qn.getMessage().
+            }
+            rollbackUncoms = (qn.getMessage() != null);
+
+            if (rollbackUncoms) {
+                errprintln(SqltoolRB.aborting.getString(qn.getMessage()));
+                throw new SqlToolError(qn.getMessage());
+            }
+
+            return;
+        } finally {
+            if (fetchingVar != null) {
+                errprintln(SqltoolRB.plvar_set_incomplete.getString(
+                        fetchingVar));
+                rollbackUncoms = true;
+            }
+            if (shared.jdbcConn != null) {
+                if (shared.jdbcConn.getAutoCommit())
+                    shared.possiblyUncommitteds = false;
+                if (rollbackUncoms && shared.possiblyUncommitteds) {
+                    errprintln(SqltoolRB.rollingback.getString());
+                    shared.jdbcConn.rollback();
+                    shared.possiblyUncommitteds = false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Utility nested Exception class for internal use only.
+     *
+     * Do not instantiate with null message.
+     */
+    private static class BadSpecial extends AppendableException {
+        static final long serialVersionUID = 7162440064026570590L;
+
+        BadSpecial(String s) {
+            super(s);
+            if (s == null)
+                throw new RuntimeException(
+                        "Must construct BadSpecials with non-null message");
+        }
+        BadSpecial(String s, Throwable t) {
+            super(s, t);
+            if (s == null)
+                throw new RuntimeException(
+                        "Must construct BadSpecials with non-null message");
+        }
+    }
+
+    /**
+     * Utility nested Exception class for internal use.
+     * This must extend SqlToolError because it has to percolate up from
+     * recursions of SqlTool.execute(), yet SqlTool.execute() is public.
+     * Therefore, external users have no reason to specifically handle
+     * QuitNow.
+     */
+    private class QuitNow extends SqlToolError {
+        static final long serialVersionUID = 1811094258670900488L;
+
+        public QuitNow(String s) {
+            super(s);
+        }
+
+        public QuitNow() {
+            super();
+        }
+    }
+
+    /**
+     * Utility nested Exception class for internal use.
+     * This must extend SqlToolError because it has to percolate up from
+     * recursions of SqlTool.execute(), yet SqlTool.execute() is public.
+     * Therefore, external users have no reason to specifically handle
+     * BreakException.
+     */
+    private class BreakException extends SqlToolError {
+        static final long serialVersionUID = 351150072817675994L;
+
+        public BreakException() {
+            super();
+        }
+
+        public BreakException(String s) {
+            super(s);
+        }
+    }
+
+    /**
+     * Utility nested Exception class for internal use.
+     * This must extend SqlToolError because it has to percolate up from
+     * recursions of SqlTool.execute(), yet SqlTool.execute() is public.
+     * Therefore, external users have no reason to specifically handle
+     * ContinueException.
+     */
+    private class ContinueException extends SqlToolError {
+        static final long serialVersionUID = 5064604160827106014L;
+
+        public ContinueException() {
+            super();
+        }
+
+        public ContinueException(String s) {
+            super(s);
+        }
+    }
+
+    /**
+     * Utility nested Exception class for internal use only.
+     */
+    private class BadSubst extends Exception {
+        static final long serialVersionUID = 7325933736897253269L;
+
+        BadSubst(String s) {
+            super(s);
+        }
+    }
+
+    /**
+     * Utility nested Exception class for internal use only.
+     */
+    private class RowError extends AppendableException {
+        static final long serialVersionUID = 754346434606022750L;
+
+        RowError(String s) {
+            super(s);
+        }
+
+        /* Unused so far
+        RowError(Throwable t) {
+            this(null, t);
+        }
+        */
+
+        RowError(String s, Throwable t) {
+            super(s, t);
+        }
+    }
+
+    /**
+     * Process a Buffer/History Command.
+     *
+     * Due to the nature of the goal here, we don't trim() "other" like
+     * we do for other kinds of commands.
+     *
+     * @param inString Complete command, less the leading ':' character.
+     * @throws SQLException  thrown by JDBC driver.
+     * @throws BadSpecial    special-command-specific errors.
+     * @throws SqlToolError  all other errors.
+     */
+    private void processBuffHist(Token token)
+    throws BadSpecial, SQLException, SqlToolError {
+        if (token.val.length() < 1) {
+            throw new BadSpecial(SqltoolRB.bufhist_unspecified.getString());
+        }
+
+        // First handle the simple cases where user may not specify a
+        // command number.
+        char commandChar = token.val.charAt(0);
+        String other       = token.val.substring(1);
+        if (other.trim().length() == 0) {
+            other = null;
+        }
+        switch (commandChar) {
+            case 'l' :
+            case 'b' :
+                enforce1charBH(other, 'l');
+                if (buffer == null) {
+                    stdprintln(nobufferYetString);
+                } else {
+                    stdprintln(SqltoolRB.editbuffer_contents.getString(
+                            buffer.reconstitute()));
+                }
+
+                return;
+
+            case 'h' :
+                enforce1charBH(other, 'h');
+                showHistory();
+
+                return;
+
+            case '?' :
+                stdprintln(SqltoolRB.buffer_help.getString());
+
+                return;
+        }
+
+        Integer histNum = null;
+        Matcher hm = slashHistoryPattern.matcher(token.val);
+        if (hm.matches()) {
+            histNum = historySearch(hm.group(1));
+            if (histNum == null) {
+                stdprintln(SqltoolRB.substitution_nomatch.getString());
+                return;
+            }
+        } else {
+            hm = historyPattern.matcher(token.val);
+            if (!hm.matches()) {
+                throw new BadSpecial(SqltoolRB.edit_malformat.getString());
+                // Empirically, I find that this pattern always captures two
+                // groups.  Unfortunately, there's no way to guarantee that :( .
+            }
+            histNum = ((hm.group(1) == null || hm.group(1).length() < 1)
+                    ? null : Integer.valueOf(hm.group(1)));
+        }
+        if (hm.groupCount() != 2) {
+            throw new BadSpecial(SqltoolRB.edit_malformat.getString());
+            // Empirically, I find that this pattern always captures two
+            // groups.  Unfortunately, there's no way to guarantee that :( .
+        }
+        commandChar = ((hm.group(2) == null || hm.group(2).length() < 1)
+                ? '\0' : hm.group(2).charAt(0));
+        other = ((commandChar == '\0') ? null : hm.group(2).substring(1));
+        if (other != null && other.length() < 1) other = null;
+        Token targetCommand = ((histNum == null)
+                ? null : commandFromHistory(histNum.intValue()));
+        // Every command below depends upon buffer content.
+
+        switch (commandChar) {
+            case '\0' :  // Special token set above.  Just history recall.
+                setBuf(targetCommand);
+                stdprintln(SqltoolRB.buffer_restored.getString(
+                        buffer.reconstitute()));
+                return;
+
+            case ';' :
+                enforce1charBH(other, ';');
+
+                if (targetCommand != null) setBuf(targetCommand);
+                if (buffer == null) throw new BadSpecial(
+                        SqltoolRB.nobuffer_yet.getString());
+                stdprintln(SqltoolRB.buffer_executing.getString(
+                        buffer.reconstitute()));
+                preempt = true;
+                return;
+
+            case 'a' :
+                if (targetCommand == null) targetCommand = buffer;
+                if (targetCommand == null) throw new BadSpecial(
+                        SqltoolRB.nobuffer_yet.getString());
+                boolean doExec = false;
+
+                if (other != null) {
+                    if (other.trim().charAt(other.trim().length() - 1) == ';') {
+                        other = other.substring(0, other.lastIndexOf(';'));
+                        if (other.trim().length() < 1)
+                            throw new BadSpecial(
+                                    SqltoolRB.append_empty.getString());
+                        doExec = true;
+                    }
+                }
+                Token newToken = new Token(targetCommand.type,
+                        targetCommand.val, targetCommand.line);
+                if (other != null) newToken.val += other;
+                setBuf(newToken);
+                if (doExec) {
+                    stdprintln(SqltoolRB.buffer_executing.getString(
+                            buffer.reconstitute()));
+                    preempt = true;
+                    return;
+                }
+
+                if (interactive) scanner.setMagicPrefix(
+                        newToken.reconstitute());
+
+                switch (newToken.type) {
+                    case Token.SQL_TYPE:
+                        scanner.setRequestedState(SqlFileScanner.SQL);
+                        break;
+                    case Token.SPECIAL_TYPE:
+                        scanner.setRequestedState(SqlFileScanner.SPECIAL);
+                        break;
+                    case Token.PL_TYPE:
+                        scanner.setRequestedState(SqlFileScanner.PL);
+                        break;
+                    default:
+                        throw new RuntimeException(
+                            "Internal assertion failed.  "
+                            + "Appending to unexpected type: "
+                            + newToken.getTypeString());
+                }
+                scanner.setCommandBuffer(newToken.val);
+
+                return;
+
+            case 'w' :
+                if (targetCommand == null) targetCommand = buffer;
+                if (targetCommand == null) throw new BadSpecial(
+                        SqltoolRB.nobuffer_yet.getString());
+                if (other == null) {
+                    throw new BadSpecial(SqltoolRB.destfile_demand.getString());
+                }
+                String targetFile = dereference(other.trim(), false);
+                // Dereference and trim the target file name
+                // This is the only case where we dereference a : command.
+
+                PrintWriter pw = null;
+                try {
+                    pw = new PrintWriter(
+                            new OutputStreamWriter(
+                            new FileOutputStream(targetFile, true),
+                            (shared.encoding == null)
+                            ? DEFAULT_FILE_ENCODING : shared.encoding)
+                            // Appendmode so can append to an SQL script.
+                    );
+
+                    pw.println(targetCommand.reconstitute(true));
+                    pw.flush();
+                } catch (Exception e) {
+                    throw new BadSpecial(SqltoolRB.file_appendfail.getString(
+                            targetFile), e);
+                } finally {
+                    if (pw != null) {
+                        try {
+                            pw.close();
+                        } finally {
+                            pw = null; // Encourage GC of buffers
+                        }
+                    }
+                }
+
+                return;
+
+            case 's' :
+                boolean modeExecute = false;
+                boolean modeGlobal = false;
+                if (targetCommand == null) targetCommand = buffer;
+                if (targetCommand == null) throw new BadSpecial(
+                        SqltoolRB.nobuffer_yet.getString());
+
+                try {
+                    if (other == null || other.length() < 3) {
+                        throw new BadSubst(
+                                SqltoolRB.substitution_malformat.getString());
+                    }
+                    Matcher m = substitutionPattern.matcher(other);
+                    if (!m.matches()) {
+                        throw new BadSubst(
+                                SqltoolRB.substitution_malformat.getString());
+                    }
+
+                    // Note that this pattern does not include the leading :.
+                    if (m.groupCount() < 3 || m.groupCount() > 4) {
+                        throw new RuntimeException(
+                                "Internal assertion failed.  "
+                                + "Matched substitution "
+                                + "pattern, but captured "
+                                + m.groupCount() + " groups");
+                    }
+                    String optionGroup = (
+                            (m.groupCount() > 3 && m.group(4) != null)
+                            ? (new String(m.group(4))) : null);
+
+                    if (optionGroup != null) {
+                        if (optionGroup.indexOf(';') > -1) {
+                            modeExecute = true;
+                            optionGroup = optionGroup.replaceFirst(";", "");
+                        }
+                        if (optionGroup.indexOf('g') > -1) {
+                            modeGlobal = true;
+                            optionGroup = optionGroup.replaceFirst("g", "");
+                        }
+                    }
+
+                    Matcher bufferMatcher = Pattern.compile("(?s"
+                            + ((optionGroup == null) ? "" : optionGroup)
+                            + ')' + m.group(2)).matcher(targetCommand.val);
+                    Token newBuffer = new Token(targetCommand.type,
+                            (modeGlobal
+                                ? bufferMatcher.replaceAll(m.group(3))
+                                : bufferMatcher.replaceFirst(m.group(3))),
+                                targetCommand.line);
+                    if (newBuffer.val.equals(targetCommand.val)) {
+                        stdprintln(SqltoolRB.substitution_nomatch.getString());
+                        return;
+                    }
+
+                    setBuf(newBuffer);
+                    stdprintln(modeExecute
+                            ? SqltoolRB.buffer_executing.getString(
+                                    buffer.reconstitute())
+                            : SqltoolRB.editbuffer_contents.getString(
+                                    buffer.reconstitute())
+                    );
+                } catch (PatternSyntaxException pse) {
+                    throw new BadSpecial(
+                            SqltoolRB.substitution_syntax.getString(), pse);
+                } catch (BadSubst badswitch) {
+                    throw new BadSpecial(
+                            SqltoolRB.substitution_syntax.getString());
+                }
+                if (modeExecute) preempt = true;
+
+                return;
+        }
+
+        throw new BadSpecial(SqltoolRB.buffer_unknown.getString(
+                Character.toString(commandChar)));
+    }
+
+    private boolean doPrepare;
+    private String  prepareVar;
+    private String  dsvColDelim;
+    private String  dsvColSplitter;
+    private String  dsvSkipPrefix;
+    private String  dsvRowDelim;
+    private String  dsvRowSplitter;
+    private String  dsvSkipCols;
+    private boolean dsvTrimAll;
+    private static String  DSV_X_SYNTAX_MSG;
+    private static String  DSV_M_SYNTAX_MSG;
+    private static String  nobufferYetString;
+
+    private void enforce1charSpecial(String tokenString, char command)
+            throws BadSpecial {
+        if (tokenString.length() != 1) {
+            throw new BadSpecial(SqltoolRB.special_extrachars.getString(
+                     Character.toString(command), tokenString.substring(1))); } }
+    private void enforce1charBH(String tokenString, char command)
+            throws BadSpecial {
+        if (tokenString != null) {
+            throw new BadSpecial(SqltoolRB.buffer_extrachars.getString(
+                    Character.toString(command), tokenString));
+        }
+    }
+
+    /**
+     * Process a Special Command.
+     *
+     * @param inString TRIMMED, no-null command (without leading \),
+     *                 or null to operate on buffer.
+     * @throws SQLException thrown by JDBC driver.
+     * @throws BadSpecial special-command-specific errors.
+     * @throws SqlToolError all other errors, plus QuitNow,
+     *                      BreakException, ContinueException.
+     */
+    private void processSpecial(String inString)
+    throws BadSpecial, QuitNow, SQLException, SqlToolError {
+        String string = (inString == null) ? buffer.val : inString;
+        if (string.length() < 1) {
+            throw new BadSpecial(SqltoolRB.special_unspecified.getString());
+        }
+        Matcher m = specialPattern.matcher(
+                plMode ? dereference(string, false) : string);
+        if (!m.matches()) {
+            throw new BadSpecial(SqltoolRB.special_malformat.getString());
+            // I think it's impossible to get here, since the pattern is
+            // so liberal.
+        }
+        if (m.groupCount() < 1 || m.groupCount() > 2) {
+            // Failed assertion
+            throw new RuntimeException(
+                    "Internal assertion failed.  Pattern matched, yet captured "
+                    + m.groupCount() + " groups");
+        }
+
+        String arg1 = m.group(1);
+        String other = ((m.groupCount() > 1) ? m.group(2) : null);
+
+        switch (arg1.charAt(0)) {
+            case 'q' :
+                enforce1charSpecial(arg1, 'q');
+                if (other != null) {
+                    throw new QuitNow(other);
+                }
+
+                throw new QuitNow();
+            case 'H' :
+                enforce1charSpecial(arg1, 'H');
+                htmlMode = !htmlMode;
+
+                stdprintln(SqltoolRB.html_mode.getString(
+                        Boolean.toString(htmlMode)));
+
+                return;
+
+            case 'm' :
+                if (arg1.equals("m?") ||
+                        (arg1.equals("m") && other != null
+                                 && other.equals("?"))) {
+                    stdprintln(DSV_OPTIONS_TEXT + LS + DSV_M_SYNTAX_MSG);
+                    return;
+                }
+                if (arg1.length() != 1 || other == null) {
+                    throw new BadSpecial(DSV_M_SYNTAX_MSG);
+                }
+                boolean noComments = other.charAt(other.length() - 1) == '*';
+                String skipPrefix = null;
+
+                if (noComments) {
+                    other = other.substring(0, other.length()-1).trim();
+                    if (other.length() < 1) {
+                        throw new BadSpecial(DSV_M_SYNTAX_MSG);
+                    }
+                } else {
+                    skipPrefix = dsvSkipPrefix;
+                }
+                int colonIndex = other.indexOf(" :");
+                if (colonIndex > -1 && colonIndex < other.length() - 2) {
+                    skipPrefix = other.substring(colonIndex + 2);
+                    other = other.substring(0, colonIndex).trim();
+                }
+
+                importDsv(other, skipPrefix);
+
+                return;
+
+            case 'x' :
+                requireConnection();
+                if (arg1.equals("x?") ||
+                        (arg1.equals("x") && other != null
+                                 && other.equals("?"))) {
+                    stdprintln(DSV_OPTIONS_TEXT + LS + DSV_X_SYNTAX_MSG);
+                    return;
+                }
+                try {
+                    if (arg1.length() != 1 || other == null) {
+                        throw new BadSpecial(DSV_X_SYNTAX_MSG);
+                    }
+
+                    String tableName = ((other.indexOf(' ') > 0) ? null
+                                                                 : other);
+
+                    if (dsvTargetFile == null && tableName == null) {
+                        throw new BadSpecial(
+                                SqltoolRB.dsv_targetfile_demand.getString());
+                    }
+                    File dsvFile = new File((dsvTargetFile == null)
+                                            ? (tableName + ".dsv")
+                                            : dsvTargetFile);
+
+                    pwDsv = new PrintWriter(new OutputStreamWriter(
+                            new FileOutputStream(dsvFile),
+                            (shared.encoding == null)
+                            ? DEFAULT_FILE_ENCODING : shared.encoding));
+
+                    ResultSet rs = shared.jdbcConn.createStatement()
+                            .executeQuery((tableName == null) ? other
+                                                : ("SELECT * FROM "
+                                                   + tableName));
+                    try {
+                        List<Integer> colList = new ArrayList<Integer>();
+                        int[] incCols = null;
+                        if (dsvSkipCols != null) {
+                            Set<String> skipCols = new HashSet<String>();
+                            for (String s : dsvSkipCols.split(dsvColDelim, -1)) {
+                            // Don't know if better to use dsvColDelim or
+                            // dsvColSplitter.  Going with former, since the
+                            // latter should not need to be set for eXporting
+                            // (only importing).
+                                skipCols.add(s.trim().toLowerCase());
+                            }
+                            ResultSetMetaData rsmd = rs.getMetaData();
+                            for (int i = 1; i <= rsmd.getColumnCount(); i++) {
+                                if (!skipCols.remove(rsmd.getColumnName(i)
+                                        .toLowerCase())) {
+                                    colList.add(Integer.valueOf(i));
+                                }
+                            }
+                            if (colList.size() < 1) {
+                                throw new BadSpecial(
+                                        SqltoolRB.dsv_nocolsleft.getString(
+                                        dsvSkipCols));
+                            }
+                            if (skipCols.size() > 0) {
+                                throw new BadSpecial(
+                                        SqltoolRB.dsv_skipcols_missing.getString(
+                                        skipCols.toString()));
+                            }
+                            incCols = new int[colList.size()];
+                            for (int i = 0; i < incCols.length; i++) {
+                                incCols[i] = colList.get(i).intValue();
+                            }
+                        }
+                        displayResultSet(null, rs, incCols, null);
+                    } finally {
+                        rs.close();
+                    }
+                    pwDsv.flush();
+                    stdprintln(SqltoolRB.file_wrotechars.getString(
+                            Long.toString(dsvFile.length()),
+                            dsvFile.toString()));
+                } catch (FileNotFoundException e) {
+                    throw new BadSpecial(SqltoolRB.file_writefail.getString(
+                            other), e);
+                } catch (UnsupportedEncodingException e) {
+                    throw new BadSpecial(SqltoolRB.file_writefail.getString(
+                            other), e);
+                } finally {
+                    // Reset all state changes
+                    if (pwDsv != null) {
+                        try {
+                            pwDsv.close();
+                        } finally {
+                            pwDsv = null; // Encourage GC of buffers
+                        }
+                    }
+                }
+
+                return;
+
+            case 'd' :
+                requireConnection();
+                if (arg1.equals("d?") ||
+                        (arg1.equals("d") && other != null
+                                 && other.equals("?"))) {
+                    stdprintln(D_OPTIONS_TEXT);
+                    return;
+                }
+                if (arg1.length() == 2) {
+                    listTables(arg1.charAt(1), other);
+
+                    return;
+                }
+
+                if (arg1.length() == 1 && other != null) try {
+                    int space = other.indexOf(' ');
+
+                    if (space < 0) {
+                        describe(other, null);
+                    } else {
+                        describe(other.substring(0, space),
+                                 other.substring(space + 1).trim());
+                    }
+
+                    return;
+                } catch (SQLException se) {
+                    throw new BadSpecial(
+                            SqltoolRB.metadata_fetch_fail.getString(), se);
+                }
+
+                throw new BadSpecial(SqltoolRB.special_d_like.getString());
+            case 'o' :
+                enforce1charSpecial(arg1, 'o');
+                if (other == null) {
+                    if (pwQuery == null) {
+                        throw new BadSpecial(
+                                SqltoolRB.outputfile_nonetoclose.getString());
+                    }
+
+                    closeQueryOutputStream();
+
+                    return;
+                }
+
+                if (pwQuery != null) {
+                    stdprintln(SqltoolRB.outputfile_reopening.getString());
+                    closeQueryOutputStream();
+                }
+
+                try {
+                    pwQuery = new PrintWriter(new OutputStreamWriter(
+                            new FileOutputStream(other, true),
+                            (shared.encoding == null)
+                            ? DEFAULT_FILE_ENCODING : shared.encoding));
+
+                    /* Opening in append mode, so it's possible that we will
+                     * be adding superfluous <HTML> and <BODY> tags.
+                     * I think that browsers can handle that */
+                    pwQuery.println((htmlMode
+                            ? ("<HTML>" + LS + "<!--")
+                            : "#") + " " + (new java.util.Date()) + ".  "
+                                    + SqltoolRB.outputfile_header.getString(
+                                    getClass().getName())
+                                    + (htmlMode ? (" -->" + LS + LS + "<BODY>")
+                                                : LS));
+                    pwQuery.flush();
+                } catch (Exception e) {
+                    throw new BadSpecial(SqltoolRB.file_writefail.getString(
+                            other), e);
+                }
+
+                return;
+
+            case 'i' :
+                enforce1charSpecial(arg1, 'i');
+                if (other == null) {
+                    throw new BadSpecial(
+                            SqltoolRB.sqlfile_name_demand.getString());
+                }
+
+                try {
+                    new SqlFile(this, new File(other)).execute();
+                } catch (ContinueException ce) {
+                    throw ce;
+                } catch (BreakException be) {
+                    String beMessage = be.getMessage();
+
+                    // Handle "file" and plain breaks (by doing nothing)
+                    if (beMessage != null &&!beMessage.equals("file")) {
+                        throw be;
+                    }
+                } catch (QuitNow qn) {
+                    throw qn;
+                } catch (Exception e) {
+                    throw new BadSpecial(
+                            SqltoolRB.sqlfile_execute_fail.getString(other), e);
+                }
+
+                return;
+
+            case 'p' :
+                enforce1charSpecial(arg1, 'p');
+                if (other == null) {
+                    stdprintln(true);
+                } else {
+                    stdprintln(other, true);
+                }
+
+                return;
+
+            case 'l' :
+                if ((arg1.equals("l?") && other == null)
+                        || (arg1.equals("l") && other != null
+                                && other.equals("?"))) {
+                    stdprintln(SqltoolRB.log_syntax.getString());
+                } else {
+                    enforce1charSpecial(arg1, 'l');
+                    Matcher logMatcher = ((other == null) ? null
+                            : logPattern.matcher(other.trim()));
+                    if (logMatcher == null || (!logMatcher.matches()))
+                        throw new BadSpecial(
+                                SqltoolRB.log_syntax_error.getString());
+                    String levelString = logMatcher.group(1);
+                    Level level = null;
+                    if (levelString.equalsIgnoreCase("FINER"))
+                        level = Level.FINER;
+                    else if (levelString.equalsIgnoreCase("WARNING"))
+                        level = Level.WARNING;
+                    else if (levelString.equalsIgnoreCase("SEVERE"))
+                        level = Level.SEVERE;
+                    else if (levelString.equalsIgnoreCase("INFO"))
+                        level = Level.INFO;
+                    else if (levelString.equalsIgnoreCase("FINEST"))
+                        level = Level.FINEST;
+                    if (level == null)
+                        throw new RuntimeException(
+                                "Internal assertion failed.  "
+                                + " Unexpected Level string: " + levelString);
+                    logger.enduserlog(level, logMatcher.group(2));
+                }
+
+                return;
+
+            case 'a' :
+                requireConnection();
+                enforce1charSpecial(arg1, 'a');
+                if (other != null) {
+                    shared.jdbcConn.setAutoCommit(
+                        Boolean.parseBoolean(other));
+                    shared.possiblyUncommitteds = false;
+                }
+
+                stdprintln(SqltoolRB.a_setting.getString(
+                        Boolean.toString(shared.jdbcConn.getAutoCommit())));
+
+                return; case 'j' : try {
+                enforce1charSpecial(arg1, 'j');
+                String urlid = null;
+                String acct = null;
+                String pwd = null;
+                String url = null;
+                boolean goalAutoCommit = false;
+                String[] tokens = (other == null)
+                        ? (new String[0]) : other.split("\\s+", 3);
+                switch (tokens.length) {
+                    case 0:
+                        break;
+                    case 1:
+                        urlid = tokens[0];
+                        break;
+                    case 2:
+                        acct = tokens[0];
+                        pwd = "";  // default password to ""
+                        url = tokens[1];
+                        break;
+                    case 3:
+                        acct = tokens[0];
+                        pwd = tokens[1];
+                        url = tokens[2];
+                        break;
+                }
+                if (tokens.length > 0) {
+                    // Close current connection
+                    if (shared.jdbcConn != null) try {
+                        goalAutoCommit = shared.jdbcConn.getAutoCommit();
+                        shared.jdbcConn.close();
+                        shared.possiblyUncommitteds = false;
+                        shared.jdbcConn = null;
+                        stdprintln(SqltoolRB.disconnect_success.getString());
+                    } catch (SQLException se) {
+                        throw new BadSpecial(
+                                SqltoolRB.disconnect_failure.getString(), se);
+                    }
+                }
+                if (urlid != null || acct != null) try {
+                    if (urlid != null) {
+                        shared.jdbcConn = new RCData(new File(
+                            SqlTool.DEFAULT_RCFILE), urlid).getConnection();
+                    } else if (acct != null) {
+                        shared.jdbcConn =
+                                DriverManager.getConnection(url, acct, pwd);
+                    }
+                    shared.possiblyUncommitteds = false;
+                    shared.jdbcConn.setAutoCommit(goalAutoCommit);
+                } catch (Exception e) {
+                    throw new BadSpecial("Failed to connect", e);
+                }
+                displayConnBanner();
+            } catch (Throwable t) {
+                t.printStackTrace();
+                return;
+            }
+                return;
+            case 'v' :
+                requireConnection();
+                enforce1charSpecial(arg1, 'v');
+                if (other != null) {
+                    if (integerPattern.matcher(other).matches()) {
+                        shared.jdbcConn.setTransactionIsolation(
+                                Integer.parseInt(other));
+                    } else {
+                        RCData.setTI(shared.jdbcConn, other);
+                    }
+                }
+
+                stdprintln(SqltoolRB.transiso_report.getString(
+                        (shared.jdbcConn.isReadOnly() ? "R/O " : "R/W "),
+                        RCData.tiToString(
+                                shared.jdbcConn.getTransactionIsolation())));
+
+                return;
+            case '=' :
+                requireConnection();
+                enforce1charSpecial(arg1, '=');
+                shared.jdbcConn.commit();
+                shared.possiblyUncommitteds = false;
+                stdprintln(SqltoolRB.committed.getString());
+
+                return;
+
+            case 'b' :
+                if (arg1.length() == 1) {
+                    if (other != null) {
+                        throw new BadSpecial(
+                                SqltoolRB.special_b_malformat.getString());
+                    }
+                    fetchBinary = true;
+
+                    return;
+                }
+
+                if (arg1.charAt(1) == 'p') {
+                    if (other != null) {
+                        throw new BadSpecial(
+                                SqltoolRB.special_b_malformat.getString());
+                    }
+                    doPrepare = true;
+
+                    return;
+                }
+
+                if ((arg1.charAt(1) != 'd' && arg1.charAt(1) != 'l')
+                        || other == null) {
+                    throw new BadSpecial(
+                            SqltoolRB.special_b_malformat.getString());
+                }
+
+                File otherFile = new File(other);
+
+                try {
+                    if (arg1.charAt(1) == 'd') {
+                        dump(otherFile);
+                    } else {
+                        binBuffer = SqlFile.loadBinary(otherFile);
+                        stdprintln(SqltoolRB.binary_loadedbytesinto.getString(
+                                binBuffer.length));
+                    }
+                } catch (BadSpecial bs) {
+                    throw bs;
+                } catch (IOException ioe) {
+                    throw new BadSpecial(SqltoolRB.binary_filefail.getString(
+                            other), ioe);
+                }
+
+                return;
+
+            case 't' :
+                enforce1charSpecial(arg1, '=');
+                if (other != null) {
+                    // But remember that we have to abort on some I/O errors.
+                    reportTimes = Boolean.parseBoolean(other);
+                }
+
+                stdprintln(SqltoolRB.exectime_reporting.getString(
+                        Boolean.toString(reportTimes)));
+                return;
+
+            case '*' :
+            case 'c' :
+                enforce1charSpecial(arg1, '=');
+                if (other != null) {
+                    // But remember that we have to abort on some I/O errors.
+                    continueOnError = Boolean.parseBoolean(other);
+                }
+
+                stdprintln(SqltoolRB.c_setting.getString(
+                        Boolean.toString(continueOnError)));
+
+                return;
+
+            case '?' :
+                stdprintln(SqltoolRB.special_help.getString());
+
+                return;
+
+            case '!' :
+                /* N.b. This DOES NOT HANDLE UNIX shell wildcards, since there
+                 * is no UNIX shell involved.
+                 * Doesn't make sense to incur overhead of a shell without
+                 * stdin capability.
+                 * Could pipe System.in to the forked process, but that's
+                 * probably not worth the effort due to Java's terrible
+                 * and inescapable System.in buffering.  I.e., the forked
+                 * program or shell wouldn't get stdin until user hits Enter.
+                 *
+                 * I'd like to execute the user's default shell if they
+                 * ran "\!" with no argument, but (a) there is no portable
+                 * way to determine the user's default or login shell; and
+                 * (b) shell is useless without stdin ability.
+                 */
+
+                InputStream stream;
+                byte[]      ba         = new byte[1024];
+                String      extCommand = ((arg1.length() == 1)
+                        ? "" : arg1.substring(1))
+                    + ((arg1.length() > 1 && other != null)
+                       ? " " : "") + ((other == null) ? "" : other);
+                if (extCommand.trim().length() < 1)
+                    throw new BadSpecial(SqltoolRB.bang_incomplete.getString());
+
+                Process proc = null;
+                try {
+                    Runtime runtime = Runtime.getRuntime();
+                    proc = ((wincmdPattern == null)
+                            ? runtime.exec(extCommand)
+                            : runtime.exec(genWinArgs(extCommand))
+                    );
+
+                    proc.getOutputStream().close();
+
+                    int i;
+
+                    stream = proc.getInputStream();
+
+                    while ((i = stream.read(ba)) > 0) {
+                        stdprint(new String(ba, 0, i));
+                    }
+
+                    stream.close();
+
+                    stream = proc.getErrorStream();
+
+                    String s;
+                    while ((i = stream.read(ba)) > 0) {
+                        s = new String(ba, 0, i);
+                        if (s.endsWith(LS)) {
+                            // This block just prevents logging of
+                            // double-line-breaks.
+                            if (s.length() == LS.length()) continue;
+                            s = s.substring(0, s.length() - LS.length());
+                        }
+                        logger.severe(s);
+                    }
+
+                    stream.close();
+                    stream = null;  // Encourage buffer GC
+
+                    if (proc.waitFor() != 0) {
+                        throw new BadSpecial(
+                                SqltoolRB.bang_command_fail.getString(
+                                extCommand));
+                    }
+                } catch (BadSpecial bs) {
+                    throw bs;
+                } catch (Exception e) {
+                    throw new BadSpecial(SqltoolRB.bang_command_fail.getString(
+                            extCommand), e);
+                } finally {
+                    if (proc != null) {
+                        proc.destroy();
+                    }
+                }
+
+                return;
+        }
+
+        throw new BadSpecial(SqltoolRB.special_unknown.getString(
+                Character.toString(arg1.charAt(0))));
+    }
+
+    private static final char[] nonVarChars = {
+        ' ', '\t', '=', '}', '\n', '\r', '\f'
+    };
+
+    /**
+     * Returns index specifying 1 past end of a variable name.
+     *
+     * @param inString String containing a variable name
+     * @param startIndex Index within inString where the variable name begins
+     * @return Index within inString, 1 past end of the variable name
+     */
+    static int pastName(String inString, int startIndex) {
+        String workString = inString.substring(startIndex);
+        int    e          = inString.length();  // Index 1 past end of var name.
+        int    nonVarIndex;
+
+        for (char nonVarChar : nonVarChars) {
+            nonVarIndex = workString.indexOf(nonVarChar);
+
+            if (nonVarIndex > -1 && nonVarIndex < e) {
+                e = nonVarIndex;
+            }
+        }
+
+        return startIndex + e;
+    }
+
+    /**
+     * Deference *{} PL variables and ${} System Property variables.
+     *
+     * @throws SqlToolError
+     */
+    private String dereference(String inString,
+                               boolean permitAlias) throws SqlToolError {
+        if (inString.length() < 1) return inString;
+
+        /* TODO:  Rewrite using java.util.regex. */
+        String       varName, varValue;
+        StringBuffer expandBuffer = new StringBuffer(inString);
+        int          b, e;    // begin and end of name.  end really 1 PAST name
+        int iterations;
+
+        if (permitAlias && inString.trim().charAt(0) == '/') {
+            int slashIndex = inString.indexOf('/');
+
+            e = SqlFile.pastName(inString.substring(slashIndex + 1), 0);
+
+            // In this case, e is the exact length of the var name.
+            if (e < 1) {
+                throw new SqlToolError(SqltoolRB.plalias_malformat.getString());
+            }
+
+            varName  = inString.substring(slashIndex + 1, slashIndex + 1 + e);
+            varValue = shared.userVars.get(varName);
+
+            if (varValue == null) {
+                throw new SqlToolError(
+                        SqltoolRB.plvar_undefined.getString(varName));
+            }
+
+            expandBuffer.replace(slashIndex, slashIndex + 1 + e,
+                                 shared.userVars.get(varName));
+        }
+
+        String s;
+        boolean permitUnset;
+        // Permit unset with:     ${:varname}
+        // Prohibit unset with :  ${varnam}
+
+        iterations = 0;
+        while (true) {
+            s = expandBuffer.toString();
+            b = s.indexOf("${");
+
+            if (b < 0) {
+                // No more unexpanded variable uses
+                break;
+            }
+
+            e = s.indexOf('}', b + 2);
+
+            if (e == b + 2) {
+                throw new SqlToolError(SqltoolRB.sysprop_empty.getString());
+            }
+
+            if (e < 0) {
+                throw new SqlToolError(
+                        SqltoolRB.sysprop_unterminated.getString());
+            }
+
+            permitUnset = (s.charAt(b + 2) == ':');
+
+            varName = s.substring(b + (permitUnset ? 3 : 2), e);
+            if (iterations++ > 10000)
+                throw new
+                    SqlToolError(SqltoolRB.var_infinite.getString(varName));
+
+            varValue = System.getProperty(varName);
+            if (varValue == null) {
+                if (permitUnset) {
+                    varValue = "";
+                } else {
+                    throw new SqlToolError(
+                            SqltoolRB.sysprop_undefined.getString(varName));
+                }
+            }
+
+            expandBuffer.replace(b, e + 1, varValue);
+        }
+
+        iterations = 0;
+        while (true) {
+            s = expandBuffer.toString();
+            b = s.indexOf("*{");
+
+            if (b < 0) {
+                // No more unexpanded variable uses
+                break;
+            }
+
+            e = s.indexOf('}', b + 2);
+
+            if (e == b + 2) {
+                throw new SqlToolError(SqltoolRB.plvar_nameempty.getString());
+            }
+
+            if (e < 0) {
+                throw new SqlToolError(
+                        SqltoolRB.plvar_unterminated.getString());
+            }
+
+            permitUnset = (s.charAt(b + 2) == ':');
+
+            varName = s.substring(b + (permitUnset ? 3 : 2), e);
+            if (iterations++ > 100000)
+                throw new SqlToolError(
+                        SqltoolRB.var_infinite.getString(varName));
+            // TODO:  Use a smarter algorithm to handle (or prohibit)
+            // recursion without this clumsy detection tactic.
+
+            varValue = shared.userVars.get(varName);
+            if (varValue == null) {
+                if (permitUnset) {
+                    varValue = "";
+                } else {
+                    throw new SqlToolError(
+                            SqltoolRB.plvar_undefined.getString(varName));
+                }
+            }
+
+            expandBuffer.replace(b, e + 1, varValue);
+        }
+
+        return expandBuffer.toString();
+    }
+
+    private boolean plMode;
+
+    //  PL variable name currently awaiting query output.
+    private String  fetchingVar;
+    private boolean silentFetch;
+    private boolean fetchBinary;
+
+    /**
+     * Process a block PL command like "if" of "foreach".
+     */
+    private void processBlock(Token token) throws BadSpecial, SqlToolError {
+        Matcher m = plPattern.matcher(dereference(token.val, false));
+        if (!m.matches()) {
+            throw new BadSpecial(SqltoolRB.pl_malformat.getString());
+            // I think it's impossible to get here, since the pattern is
+            // so liberal.
+        }
+        if (m.groupCount() < 1 || m.group(1) == null) {
+            plMode = true;
+            stdprintln(SqltoolRB.pl_expansionmode.getString("on"));
+            return;
+        }
+
+        String[] tokens = m.group(1).split("\\s+", -1);
+
+        // If user runs any PL command, we turn PL mode on.
+        plMode = true;
+
+        if (tokens[0].equals("foreach")) {
+            Matcher foreachM = foreachPattern.matcher(
+                    dereference(token.val, false));
+            if (!foreachM.matches()) {
+                throw new BadSpecial(SqltoolRB.foreach_malformat.getString());
+            }
+            if (foreachM.groupCount() != 2) {
+                throw new RuntimeException(
+                        "Internal assertion failed.  "
+                        + "foreach pattern matched, but captured "
+                        + foreachM.groupCount() + " groups");
+            }
+
+            String varName   = foreachM.group(1);
+            if (varName.indexOf(':') > -1) {
+                throw new BadSpecial(SqltoolRB.plvar_nocolon.getString());
+            }
+            String[] values = foreachM.group(2).split("\\s+", -1);
+
+            String origval = shared.userVars.get(varName);
+
+
+            try {
+                for (String val : values) {
+                    try {
+                        shared.userVars.put(varName, val);
+                        updateUserSettings();
+
+                        boolean origRecursed = recursed;
+                        recursed = true;
+                        try {
+                            scanpass(token.nestedBlock.dup());
+                        } finally {
+                            recursed = origRecursed;
+                        }
+                    } catch (ContinueException ce) {
+                        String ceMessage = ce.getMessage();
+
+                        if (ceMessage != null
+                                &&!ceMessage.equals("foreach")) {
+                            throw ce;
+                        }
+                    }
+                }
+            } catch (BreakException be) {
+                String beMessage = be.getMessage();
+
+                // Handle "foreach" and plain breaks (by doing nothing)
+                if (beMessage != null &&!beMessage.equals("foreach")) {
+                    throw be;
+                }
+            } catch (QuitNow qn) {
+                throw qn;
+            } catch (RuntimeException re) {
+                throw re;  // Unrecoverable
+            } catch (Exception e) {
+                throw new BadSpecial(SqltoolRB.pl_block_fail.getString(), e);
+            }
+
+            if (origval == null) {
+                shared.userVars.remove(varName);
+                updateUserSettings();
+            } else {
+                shared.userVars.put(varName, origval);
+            }
+
+            return;
+        }
+
+        if (tokens[0].equals("if") || tokens[0].equals("while")) {
+            Matcher ifwhileM= ifwhilePattern.matcher(
+                    dereference(token.val, false));
+            if (!ifwhileM.matches()) {
+                throw new BadSpecial(SqltoolRB.ifwhile_malformat.getString());
+            }
+            if (ifwhileM.groupCount() != 1) {
+                throw new RuntimeException(
+                        "Internal assertion failed.  "
+                        + "if/while pattern matched, but captured "
+                        + ifwhileM.groupCount() + " groups");
+            }
+
+            String[] values =
+                    ifwhileM.group(1).replaceAll("!([a-zA-Z0-9*])", "! $1").
+                        replaceAll("([a-zA-Z0-9*])!", "$1 !").split("\\s+", -1);
+
+            if (tokens[0].equals("if")) {
+                try {
+                    if (eval(values)) {
+                        boolean origRecursed = recursed;
+                        recursed = true;
+                        try {
+                            scanpass(token.nestedBlock.dup());
+                        } finally {
+                            recursed = origRecursed;
+                        }
+                    }
+                } catch (BreakException be) {
+                    String beMessage = be.getMessage();
+
+                    // Handle "if" and plain breaks (by doing nothing)
+                    if (beMessage == null ||!beMessage.equals("if")) {
+                        throw be;
+                    }
+                } catch (ContinueException ce) {
+                    throw ce;
+                } catch (QuitNow qn) {
+                    throw qn;
+                } catch (BadSpecial bs) {
+                    bs.appendMessage(SqltoolRB.if_malformat.getString());
+                    throw bs;
+                } catch (RuntimeException re) {
+                    throw re;  // Unrecoverable
+                } catch (Exception e) {
+                    throw new BadSpecial(
+                        SqltoolRB.pl_block_fail.getString(), e);
+                }
+            } else if (tokens[0].equals("while")) {
+                try {
+
+                    while (eval(values)) {
+                        try {
+                            boolean origRecursed = recursed;
+                            recursed = true;
+                            try {
+                                scanpass(token.nestedBlock.dup());
+                            } finally {
+                                recursed = origRecursed;
+                            }
+                        } catch (ContinueException ce) {
+                            String ceMessage = ce.getMessage();
+
+                            if (ceMessage != null &&!ceMessage.equals("while")) {
+                                throw ce;
+                            }
+                        }
+                    }
+                } catch (BreakException be) {
+                    String beMessage = be.getMessage();
+
+                    // Handle "while" and plain breaks (by doing nothing)
+                    if (beMessage != null &&!beMessage.equals("while")) {
+                        throw be;
+                    }
+                } catch (QuitNow qn) {
+                    throw qn;
+                } catch (BadSpecial bs) {
+                    bs.appendMessage(SqltoolRB.while_malformat.getString());
+                    throw bs;
+                } catch (RuntimeException re) {
+                    throw re;  // Unrecoverable
+                } catch (Exception e) {
+                    throw new BadSpecial(
+                            SqltoolRB.pl_block_fail.getString(), e);
+                }
+            } else {
+                // Assertion
+                throw new RuntimeException(
+                        SqltoolRB.pl_unknown.getString(tokens[0]));
+            }
+
+            return;
+        }
+
+        throw new BadSpecial(SqltoolRB.pl_unknown.getString(tokens[0]));
+    }
+
+    /**
+     * Process a Non-Block Process Language Command.
+     * Nesting not supported yet.
+     *
+     * @param inString  Trimmed non-null command without leading *
+     *                  (may be empty string "").
+     * @throws BadSpecial special-command-specific errors.
+     * @throws SqlToolError all other errors, plus BreakException and
+     *                      ContinueException.
+     */
+    private void processPL(String inString) throws BadSpecial, SqlToolError {
+        String string = (inString == null) ? buffer.val : inString;
+        Matcher m = plPattern.matcher(dereference(string, false));
+        if (!m.matches()) {
+            throw new BadSpecial(SqltoolRB.pl_malformat.getString());
+            // I think it's impossible to get here, since the pattern is
+            // so liberal.
+        }
+        if (m.groupCount() < 1 || m.group(1) == null) {
+            plMode = true;
+            stdprintln(SqltoolRB.pl_expansionmode.getString("on"));
+            return;
+        }
+
+        String[] tokens = m.group(1).split("\\s+", -1);
+
+        if (tokens[0].charAt(0) == '?') {
+            stdprintln(SqltoolRB.pl_help.getString());
+
+            return;
+        }
+
+        // If user runs any PL command, we turn PL mode on.
+        plMode = true;
+
+        if (tokens[0].equals("end")) {
+            throw new BadSpecial(SqltoolRB.end_noblock.getString());
+        }
+
+        if (tokens[0].equals("continue")) {
+            if (tokens.length > 1) {
+                if (tokens.length == 2 &&
+                        (tokens[1].equals("foreach") ||
+                         tokens[1].equals("while"))) {
+                    throw new ContinueException(tokens[1]);
+                }
+                throw new BadSpecial(SqltoolRB.continue_syntax.getString());
+            }
+
+            throw new ContinueException();
+        }
+
+        if (tokens[0].equals("break")) {
+            if (tokens.length > 1) {
+                if (tokens.length == 2 &&
+                        (tokens[1].equals("foreach") ||
+                         tokens[1].equals("if") ||
+                         tokens[1].equals("while") ||
+                         tokens[1].equals("file"))) {
+                    throw new BreakException(tokens[1]);
+                }
+                throw new BadSpecial(SqltoolRB.break_syntax.getString());
+            }
+
+            throw new BreakException();
+        }
+
+        if (tokens[0].equals("list") || tokens[0].equals("listvalues")
+                || tokens[0].equals("listsysprops")) {
+            boolean sysProps =tokens[0].equals("listsysprops");
+            String  s;
+            boolean doValues = (tokens[0].equals("listvalues") || sysProps);
+            // Always list System Property values.
+            // They are unlikely to be very long, like PL variables may be.
+
+            if (tokens.length == 1) {
+                stdprint(formatNicely(
+                        (sysProps ? System.getProperties() : shared.userVars),
+                        doValues));
+            } else {
+                if (doValues) {
+                    stdprintln(SqltoolRB.pl_list_parens.getString());
+                } else {
+                    stdprintln(SqltoolRB.pl_list_lengths.getString());
+                }
+
+                for (String token : tokens) {
+                    s = (String) (sysProps ? System.getProperties()
+                                           : shared.userVars).get(token);
+                    if (s == null) continue;
+                    stdprintln("    " + token + ": "
+                               + (doValues ? ("(" + s + ')')
+                                           : Integer.toString(s.length())));
+                }
+            }
+
+            return;
+        }
+
+        if (tokens[0].equals("dump") || tokens[0].equals("load")) {
+            if (tokens.length != 3) {
+                throw new BadSpecial(SqltoolRB.dumpload_malformat.getString());
+            }
+
+            String varName = tokens[1];
+
+            if (varName.indexOf(':') > -1) {
+                throw new BadSpecial(SqltoolRB.plvar_nocolon.getString());
+            }
+            File   dlFile    = new File(tokens[2]);
+
+            try {
+                if (tokens[0].equals("dump")) {
+                    dump(varName, dlFile);
+                } else {
+                    load(varName, dlFile, shared.encoding);
+                }
+            } catch (IOException ioe) {
+                throw new BadSpecial(SqltoolRB.dumpload_fail.getString(
+                        varName, dlFile.toString()), ioe);
+            }
+
+            return;
+        }
+
+        if (tokens[0].equals("prepare")) {
+            if (tokens.length != 2) {
+                throw new BadSpecial(SqltoolRB.prepare_malformat.getString());
+            }
+
+            if (shared.userVars.get(tokens[1]) == null) {
+                throw new BadSpecial(
+                        SqltoolRB.plvar_undefined.getString(tokens[1]));
+            }
+
+            prepareVar = tokens[1];
+            doPrepare  = true;
+
+            return;
+        }
+
+        m = varsetPattern.matcher(dereference(string, false));
+        if (!m.matches()) {
+            throw new BadSpecial(SqltoolRB.pl_unknown.getString(tokens[0]));
+        }
+        if (m.groupCount() < 2 || m.groupCount() > 3) {
+            // Assertion
+            throw new RuntimeException("varset pattern matched but captured "
+                    + m.groupCount() + " groups");
+        }
+
+        String varName  = m.group(1);
+
+        if (varName.indexOf(':') > -1) {
+            throw new BadSpecial(SqltoolRB.plvar_nocolon.getString());
+        }
+
+        switch (m.group(2).charAt(0)) {
+            case '_' :
+                silentFetch = true;
+            case '~' :
+                if (m.groupCount() > 2 && m.group(3) != null) {
+                    throw new BadSpecial(SqltoolRB.plvar_tildedash_nomoreargs.getString(
+                            m.group(3)));
+                }
+
+                shared.userVars.remove(varName);
+                updateUserSettings();
+
+                fetchingVar = varName;
+
+                return;
+
+            case '=' :
+                if (fetchingVar != null && fetchingVar.equals(varName)) {
+                    fetchingVar = null;
+                }
+
+                if (varName.equals("*ENCODING")) try {
+                    // Special case so we can proactively prohibit encodings
+                    // which will not work, so we'll always be confident
+                    // that 'encoding' value is always good.
+                    setEncoding(m.group(3));
+                    return;
+                } catch (UnsupportedEncodingException use) {
+                    throw new BadSpecial(
+                            SqltoolRB.encode_fail.getString(m.group(3)));
+                }
+                if (m.groupCount() > 2 && m.group(3) != null) {
+                    shared.userVars.put(varName, m.group(3));
+                } else {
+                    shared.userVars.remove(varName);
+                }
+                updateUserSettings();
+
+                return;
+        }
+
+        throw new BadSpecial(SqltoolRB.pl_unknown.getString(tokens[0]));
+        // I think this would already be caught in the setvar block above.
+    }
+
+    /**
+     * Wrapper methods so don't need to call x(..., false) in most cases.
+     */
+    /* Unused.  Enable when/if need.
+    private void stdprintln() {
+        stdprintln(false);
+    }
+    */
+
+    private void stdprint(String s) {
+        stdprint(s, false);
+    }
+
+    private void stdprintln(String s) {
+        stdprintln(s, false);
+    }
+
+    /**
+     * Encapsulates normal output.
+     *
+     * Conditionally HTML-ifies output.
+     */
+    private void stdprintln(boolean queryOutput) {
+        if (shared.psStd != null) if (htmlMode) {
+            shared.psStd.println("<BR>");
+        } else {
+            shared.psStd.println();
+        }
+
+        if (queryOutput && pwQuery != null) {
+            if (htmlMode) {
+                pwQuery.println("<BR>");
+            } else {
+                pwQuery.println();
+            }
+
+            pwQuery.flush();
+        }
+    }
+
+    /**
+     * Encapsulates error output.
+     *
+     * Conditionally HTML-ifies error output.
+     */
+    private void errprintln(String s) {
+        if (shared.psStd != null && htmlMode) {
+            shared.psStd.println("<DIV style='color:white; background: red; "
+                       + "font-weight: bold'>" + s + "</DIV>");
+        } else {
+            logger.privlog(Level.SEVERE, s, null, 5, SqlFile.class);
+            /* Only consistent way we can log source location is to log
+             * the caller of SqlFile.
+             * This seems acceptable, since the location being reported
+             * here is not the source of the problem anyways.  */
+        }
+    }
+
+    /**
+     * Encapsulates normal output.
+     *
+     * Conditionally HTML-ifies output.
+     */
+    private void stdprint(String s, boolean queryOutput) {
+        if (shared.psStd != null)
+            shared.psStd.print(htmlMode ? ("<P>" + s + "</P>") : s);
+
+        if (queryOutput && pwQuery != null) {
+            pwQuery.print(htmlMode ? ("<P>" + s + "</P>") : s);
+            pwQuery.flush();
+        }
+    }
+
+    /**
+     * Encapsulates normal output.
+     *
+     * Conditionally HTML-ifies output.
+     */
+    private void stdprintln(String s, boolean queryOutput) {
+        shared.psStd.println(htmlMode ? ("<P>" + s + "</P>")
+                               : s);
+
+        if (queryOutput && pwQuery != null) {
+            pwQuery.println(htmlMode ? ("<P>" + s + "</P>")
+                                     : s);
+            pwQuery.flush();
+        }
+    }
+
+    // Just because users may be used to seeing "[null]" in normal
+    // SqlFile output, we use the same default value for null in DSV
+    // files, but this DSV null representation can be changed to anything.
+    private static final String DEFAULT_NULL_REP = "[null]";
+    private static final String DEFAULT_ROW_DELIM = LS;
+    private static final String DEFAULT_ROW_SPLITTER = "\\r\\n|\\r|\\n";
+    private static final String DEFAULT_COL_DELIM = "|";
+    private static final String DEFAULT_COL_SPLITTER = "\\|";
+    private static final String DEFAULT_SKIP_PREFIX = "#";
+    private static final int    DEFAULT_ELEMENT   = 0,
+                                HSQLDB_ELEMENT    = 1,
+                                ORACLE_ELEMENT    = 2
+    ;
+
+    // These do not specify order listed, just inclusion.
+    private static final int[] listMDSchemaCols = { 1 };
+    private static final int[] listMDIndexCols  = {
+        2, 6, 3, 9, 4, 10, 11
+    };
+
+    /** Column numbering starting at 1. */
+    private static final int[][] listMDTableCols = {
+        {
+            2, 3
+        },    // Default
+        {
+            2, 3
+        },    // HSQLDB
+        {
+            2, 3
+        },    // Oracle
+    };
+
+    /**
+     * SYS and SYSTEM are the only base system accounts in Oracle, however,
+     * from an empirical perspective, all of these other accounts are
+     * system accounts because <UL>
+     * <LI> they are hidden from the casual user
+     * <LI> they are created by the installer at installation-time
+     * <LI> they are used automatically by the Oracle engine when the
+     *      specific Oracle sub-product is used
+     * <LI> the accounts should not be <I>messed with</I> by database users
+     * <LI> the accounts should certainly not be used if the specific
+     *      Oracle sub-product is going to be used.
+     * </UL>
+     *
+     * General advice:  If you aren't going to use an Oracle sub-product,
+     * then <B>don't install it!</B>
+     * Don't blindly accept default when running OUI.
+     *
+     * If users also see accounts that they didn't create with names like
+     * SCOTT, ADAMS, JONES, CLARK, BLAKE, OE, PM, SH, QS, QS_*, these
+     * contain sample data and the schemas can safely be removed.
+     */
+    private static final String[] oracleSysSchemas = {
+        "SYS", "SYSTEM", "OUTLN", "DBSNMP", "OUTLN", "MDSYS", "ORDSYS",
+        "ORDPLUGINS", "CTXSYS", "DSSYS", "PERFSTAT", "WKPROXY", "WKSYS",
+        "WMSYS", "XDB", "ANONYMOUS", "ODM", "ODM_MTR", "OLAPSYS", "TRACESVR",
+        "REPADMIN"
+    };
+
+    public String getCurrentSchema() throws BadSpecial, SqlToolError {
+        requireConnection();
+        Statement st = null;
+        ResultSet rs = null;
+        try {
+            st = shared.jdbcConn.createStatement();
+            rs = st.executeQuery("VALUES CURRENT_SCHEMA");
+            if (!rs.next())
+                throw new BadSpecial(SqltoolRB.no_vendor_schemaspt.getString());
+            String currentSchema = rs.getString(1);
+            if (currentSchema == null)
+                throw new BadSpecial(
+                        SqltoolRB.schemaname_retrieval_fail.getString());
+            return currentSchema;
+        } catch (SQLException se) {
+            throw new BadSpecial(SqltoolRB.no_vendor_schemaspt.getString());
+        } finally {
+            if (rs != null) try {
+                rs.close();
+            } catch (SQLException se) {
+                // Purposefully doing nothing
+            } finally {
+                rs = null;
+            }
+            if (st != null) try {
+                st.close();
+            } catch (SQLException se) {
+                // Purposefully doing nothing
+            } finally {
+                st = null;
+            }
+        }
+    }
+
+    /**
+     * Lists available database tables.
+     *
+     * Filter handling is admittedly inconsistent, both wrt pattern
+     * matching (java.util.regex vs. DB-implemented matching) and
+     * which columns the filter is matched against.
+     * The former is because, for performance and because the DB should
+     * know best how to supply the desired results, we need to let the
+     * database do filtering if at all possible.
+     * In many cases, the DB does not have a filter option, so we have
+     * to filter ourselves.
+     * For the latter, we have no control over which columsn the DB
+     * matches agains, plus the displayResultSet() method in this class
+     * can only match against all columns (only reason not to add
+     * column-specific filtering is to keep the complexity manageable).
+     *
+     * @throws BadSpecial usually wrap a cause (which cause is a
+     *                    SQLException in some cases).
+     * @throws SqlToolError passed through from other methods in this class.
+     */
+    private void listTables(char c, String inFilter) throws BadSpecial,
+            SqlToolError {
+        requireConnection();
+        String   schema  = null;
+        int[]    listSet = null;
+        String[] types   = null;
+
+        /** For workaround for \T for Oracle */
+        String[] additionalSchemas = null;
+
+        /** This is for specific non-getTable() queries */
+        Statement statement = null;
+        ResultSet rs        = null;
+        String    narrower  = "";
+        /*
+         * Doing case-sensitive filters now, for greater portability.
+        String                    filter = ((inFilter == null)
+                                          ? null : inFilter.toUpperCase());
+         */
+        String filter = inFilter;
+
+        try {
+            DatabaseMetaData md            = shared.jdbcConn.getMetaData();
+            String           dbProductName = md.getDatabaseProductName();
+            int              majorVersion  = 0;
+            int              minorVersion  = 0;
+
+            // We only use majorVersion and minorVersion for HyperSQL so far
+            // The calls avoided here avoid problems with non-confirmant drivers
+            if (dbProductName.indexOf("HSQL") > -1) try {
+                majorVersion  = md.getDatabaseMajorVersion();
+                minorVersion  = md.getDatabaseMinorVersion();
+            } catch (UnsupportedOperationException uoe) {
+                // It seems that Sun's JDBC/ODBC bridge throws here
+                majorVersion = 2;
+                minorVersion = 0;
+            }
+
+            //System.err.println("DB NAME = (" + dbProductName + ')');
+            // Database-specific table filtering.
+
+            /* 3 Types of actions:
+             *    1) Special handling.  Return from the "case" block directly.
+             *    2) Execute a specific query.  Set statement in the "case".
+             *    3) Otherwise, set filter info for dbmd.getTable() in the
+             *       "case".
+             */
+            types = new String[1];
+
+            switch (c) {
+                case '*' :
+                    types = null;
+                    break;
+
+                case 'S' :
+                    if (dbProductName.indexOf("Oracle") > -1) {
+                        errprintln(SqltoolRB.vendor_oracle_dS.getString());
+
+                        types[0]          = "TABLE";
+                        schema            = "SYS";
+                        additionalSchemas = oracleSysSchemas;
+                    } else {
+                        types[0] = "SYSTEM TABLE";
+                    }
+                    break;
+
+                case 's' :
+                    if (dbProductName.indexOf("HSQL") > -1) {
+                        //  HSQLDB does not consider Sequences as "tables",
+                        //  hence we do not list them in
+                        //  DatabaseMetaData.getTables().
+                        if (filter != null) {
+                            Matcher matcher = dotPattern.matcher(filter);
+                            if (matcher.matches()) {
+                                filter = (matcher.group(2).length() > 0)
+                                        ? matcher.group(2) : null;
+                                narrower = "\nWHERE sequence_schema = '"
+                                        + ((matcher.group(1).length() > 0)
+                                                ? matcher.group(1)
+                                                : getCurrentSchema()) + "'";
+                            }
+                        }
+
+                        statement = shared.jdbcConn.createStatement();
+
+                        statement.execute(
+                            "SELECT sequence_schema, sequence_name FROM "
+                            + "information_schema."
+                            + ((minorVersion> 8 || majorVersion > 1)
+                            ? "sequences" : "system_sequences") + narrower);
+                    } else {
+                        types[0] = "SEQUENCE";
+                    }
+                    break;
+
+                case 'r' :
+                    if (dbProductName.indexOf("HSQL") > -1) {
+                        statement = shared.jdbcConn.createStatement();
+
+                        statement.execute(
+                            "SELECT authorization_name FROM information_schema."
+                            + ((minorVersion> 8 || majorVersion > 1)
+                            ? "authorizations" : "system_authorizations")
+                            + "\nWHERE authorization_type = 'ROLE'\n"
+                            + "ORDER BY authorization_name");
+                    } else if (dbProductName.indexOf(
+                            "Adaptive Server Enterprise") > -1) {
+                        // This is the basic Sybase server.  Sybase also has
+                        // their "Anywhere", ASA (for embedded), and replication
+                        // databases, but I don't know the Metadata strings for
+                        // those.
+                        statement = shared.jdbcConn.createStatement();
+
+                        statement.execute(
+                            "SELECT name FROM syssrvroles ORDER BY name");
+                    } else if (dbProductName.indexOf(
+                            "Apache Derby") > -1) {
+                        throw new BadSpecial(
+                            SqltoolRB.vendor_derby_dr.getString());
+                    } else {
+                        throw new BadSpecial(
+                            SqltoolRB.vendor_nosup_d.getString("r"));
+                    }
+                    break;
+
+                case 'u' :
+                    if (dbProductName.indexOf("HSQL") > -1) {
+                        statement = shared.jdbcConn.createStatement();
+
+                        statement.execute("SELECT "
+                            + ((minorVersion> 8 || majorVersion > 1)
+                            ? "user_name" : "user") + ", admin FROM "
+                            + "information_schema.system_users\n"
+                            + "ORDER BY user_name");
+                    } else if (dbProductName.indexOf("Oracle") > -1) {
+                        statement = shared.jdbcConn.createStatement();
+
+                        statement.execute(
+                            "SELECT username, created FROM all_users "
+                            + "ORDER BY username");
+                    } else if (dbProductName.indexOf("PostgreSQL") > -1) {
+                        statement = shared.jdbcConn.createStatement();
+
+                        statement.execute(
+                            "SELECT usename, usesuper FROM pg_catalog.pg_user "
+                            + "ORDER BY usename");
+                    } else if (dbProductName.indexOf(
+                            "Adaptive Server Enterprise") > -1) {
+                        // This is the basic Sybase server.  Sybase also has
+                        // their "Anywhere", ASA (for embedded), and replication
+                        // databases, but I don't know the Metadata strings for
+                        // those.
+                        statement = shared.jdbcConn.createStatement();
+
+                        statement.execute(
+                            "SELECT name, accdate, fullname FROM syslogins "
+                            + "ORDER BY name");
+                    } else if (dbProductName.indexOf(
+                            "Apache Derby") > -1) {
+                        throw new BadSpecial(
+                            SqltoolRB.vendor_derby_du.getString());
+                    } else {
+                        throw new BadSpecial(
+                            SqltoolRB.vendor_nosup_d.getString("u"));
+                    }
+                    break;
+
+                case 'a' :
+                    if (dbProductName.indexOf("HSQL") > -1
+                        && (minorVersion < 9 && majorVersion < 2)) {
+                        // HSQLDB after 1.8 doesn't support any type of aliases
+                        //  Earlier HSQLDB Aliases are not the same things as
+                        //  the aliases listed in DatabaseMetaData.getTables().
+                        if (filter != null) {
+                            Matcher matcher = dotPattern.matcher(filter);
+                            if (matcher.matches()) {
+                                filter = (matcher.group(2).length() > 0)
+                                        ? matcher.group(2) : null;
+                                narrower = "\nWHERE alias_schema = '"
+                                        + ((matcher.group(1).length() > 0)
+                                                ? matcher.group(1)
+                                                : getCurrentSchema()) + "'";
+                            }
+                        }
+
+                        statement = shared.jdbcConn.createStatement();
+
+                        statement.execute(
+                            "SELECT alias_schem, alias FROM "
+                            + "information_schema.system_aliases" + narrower);
+                    } else {
+                        types[0] = "ALIAS";
+                    }
+                    break;
+
+                case 't' :
+                    excludeSysSchemas = (dbProductName.indexOf("Oracle")
+                                         > -1);
+                    types[0] = "TABLE";
+                    break;
+
+                case 'v' :
+                    types[0] = "VIEW";
+                    break;
+
+                case 'n' :
+                    rs = md.getSchemas();
+
+                    if (rs == null) {
+                        throw new BadSpecial(
+                            "Failed to get metadata from database");
+                    }
+
+                    displayResultSet(null, rs, listMDSchemaCols, filter);
+
+                    return;
+
+                case 'i' :
+
+                    // Some databases require to specify table, some don't.
+                    /*
+                    if (filter == null) {
+                        throw new BadSpecial("You must specify the index's "
+                                + "table as argument to \\di");
+                    }
+                     */
+                    String table = null;
+
+                    if (filter != null) {
+                        Matcher matcher = dotPattern.matcher(filter);
+                        if (matcher.matches()) {
+                            table = (matcher.group(2).length() > 0)
+                                    ? matcher.group(2) : null;
+                            schema = (matcher.group(1).length() > 0)
+                                    ? matcher.group(1) : getCurrentSchema();
+                        } else {
+                            table = filter;
+                        }
+                        filter = null;
+                    }
+
+                    // N.b. Oracle incorrectly reports the INDEX SCHEMA as
+                    // the TABLE SCHEMA.  The Metadata structure seems to
+                    // be designed with the assumption that the INDEX schema
+                    // will be the same as the TABLE schema.
+                    rs = md.getIndexInfo(null, schema, table, false, true);
+
+                    if (rs == null) {
+                        throw new BadSpecial(
+                            "Failed to get metadata from database");
+                    }
+
+                    displayResultSet(null, rs, listMDIndexCols, null);
+
+                    return;
+
+                default :
+                    throw new BadSpecial(SqltoolRB.special_d_unknown.getString(
+                            Character.toString(c)) + LS + D_OPTIONS_TEXT);
+            }
+
+            if (statement == null) {
+                if (dbProductName.indexOf("HSQL") > -1) {
+                    listSet = listMDTableCols[HSQLDB_ELEMENT];
+                } else if (dbProductName.indexOf("Oracle") > -1) {
+                    listSet = listMDTableCols[ORACLE_ELEMENT];
+                } else {
+                    listSet = listMDTableCols[DEFAULT_ELEMENT];
+                }
+
+
+                if (schema == null && filter != null) {
+                    Matcher matcher = dotPattern.matcher(filter);
+                    if (matcher.matches()) {
+                        filter = (matcher.group(2).length() > 0)
+                                ? matcher.group(2) : null;
+                        schema = (matcher.group(1).length() > 0)
+                                ? matcher.group(1)
+                                : getCurrentSchema();
+                    }
+                }
+            }
+
+            rs = ((statement == null)
+                  ? md.getTables(null, schema, null, types)
+                  : statement.getResultSet());
+
+            if (rs == null) {
+                throw new BadSpecial(SqltoolRB.metadata_fetch_fail.getString());
+            }
+
+            displayResultSet(null, rs, listSet, filter);
+
+            if (additionalSchemas != null) {
+                for (String additionalSchema : additionalSchemas) {
+                    /*
+                     * Inefficient, but we have to do each successful query
+                     * twice in order to prevent calling displayResultSet
+                     * for empty/non-existent schemas
+                     */
+                    rs = md.getTables(null, additionalSchema, null,
+                                      types);
+
+                    if (rs == null) {
+                        throw new BadSpecial(
+                                SqltoolRB.metadata_fetch_failfor.getString(
+                                additionalSchema));
+                    }
+
+                    if (!rs.next()) {
+                        continue;
+                    }
+
+                    displayResultSet(
+                        null,
+                        md.getTables(
+                            null, additionalSchema, null, types), listSet, filter);
+                }
+            }
+        } catch (SQLException se) {
+            throw new BadSpecial(SqltoolRB.metadata_fetch_fail.getString(), se);
+        } catch (NullPointerException npe) {
+            throw new BadSpecial(SqltoolRB.metadata_fetch_fail.getString(),
+                    npe);
+        } finally {
+            excludeSysSchemas = false;
+
+            if (rs != null) {
+                try {
+                    rs.close();
+                } catch (SQLException se) {
+                    // We already got what we want from it, or have/are
+                    // processing a more specific error.
+                }
+            }
+
+            if (statement != null) {
+                try {
+                    statement.close();
+                } catch (SQLException se) {
+                    // Purposefully doing nothing
+                }
+            }
+        }
+    }
+
+    private boolean excludeSysSchemas;
+
+    /**
+     * Process the contents of Edit Buffer as an SQL Statement
+     *
+     * @throws SQLException thrown by JDBC driver.
+     * @throws SqlToolError all other errors.
+     */
+    private void processSQL() throws SQLException, SqlToolError {
+        requireConnection();
+        if (buffer == null)
+            throw new RuntimeException(
+                    "Internal assertion failed.  No buffer in processSQL().");
+        if (buffer.type != Token.SQL_TYPE)
+            throw new RuntimeException(
+                    "Internal assertion failed.  "
+                    + "Token type " + buffer.getTypeString()
+                    + " in processSQL().");
+        // No reason to check autoCommit constantly.  If we need to roll
+        // back, we will check the autocommit state at that time.
+        lastSqlStatement    = (plMode ? dereference(buffer.val, true)
+                                      : buffer.val);
+        // N.b. "lastSqlStatement" is a misnomer only inside this method.
+        // Outside of this method, this var references the "last" SQL
+        // statement which we attempted to execute.
+        if ((!permitEmptySqlStatements) && buffer.val == null
+                || buffer.val.trim().length() < 1) {
+            throw new SqlToolError(SqltoolRB.sqlstatement_empty.getString());
+            // There is nothing inherently wrong with issuing
+            // an empty command, like to test DB server health.
+            // But, this check effectively catches many syntax
+            // errors early.
+        }
+        Statement statement = null;
+
+        long startTime = 0;
+        if (reportTimes) startTime = (new java.util.Date()).getTime();
+        try { // VERY outer block just to ensure we close "statement"
+        try { if (doPrepare) {
+            if (lastSqlStatement.indexOf('?') < 1) {
+                lastSqlStatement = null;
+                throw new SqlToolError(SqltoolRB.prepare_demandqm.getString());
+            }
+
+            doPrepare = false;
+
+            PreparedStatement ps =
+                    shared.jdbcConn.prepareStatement(lastSqlStatement);
+            statement = ps;
+
+            if (prepareVar == null) {
+                if (binBuffer == null) {
+                    lastSqlStatement = null;
+                    throw new SqlToolError(
+                            SqltoolRB.binbuffer_empty.getString());
+                }
+
+                ps.setBytes(1, binBuffer);
+            } else {
+                String val = shared.userVars.get(prepareVar);
+
+                if (val == null) {
+                    lastSqlStatement = null;
+                    throw new SqlToolError(
+                            SqltoolRB.plvar_undefined.getString(prepareVar));
+                }
+
+                prepareVar = null;
+
+                ps.setString(1, val);
+            }
+
+            ps.executeUpdate();
+        } else {
+            statement = shared.jdbcConn.createStatement();
+
+            statement.execute(lastSqlStatement);
+        } } finally {
+            if (reportTimes) {
+                long elapsed = (new java.util.Date().getTime()) - startTime;
+                //condlPrintln("</TABLE>", true);
+                condlPrintln(SqltoolRB.exectime_report.getString(
+                        (int) elapsed), false);
+            }
+        }
+
+        /* This catches about the only very safe way to know a COMMIT
+         * is not needed. */
+        try {
+            shared.possiblyUncommitteds = !shared.jdbcConn.getAutoCommit()
+                    && !commitOccursPattern.matcher(lastSqlStatement).matches();
+        } catch (java.sql.SQLException se) {
+            // If connection is closed by instance shutdown or whatever, we'll
+            // get here.
+            lastSqlStatement = null; // I forget what this is for
+            try {
+                shared.jdbcConn.close();
+            } catch (Exception anye) {
+                // Intentionally empty
+            }
+            shared.jdbcConn = null;
+            shared.possiblyUncommitteds = false;
+            stdprintln(SqltoolRB.disconnect_success.getString());
+            return;
+        }
+        ResultSet rs = null;
+        try {
+            rs = statement.getResultSet();
+            displayResultSet(statement, rs, null, null);
+        } finally {
+            if (rs != null) {
+                try {
+                    rs.close();
+                } catch (SQLException se) {
+                    // We already got what we want from it, or have/are
+                    // processing a more specific error.
+                }
+            }
+        }
+        } finally {
+            try {
+                if (statement != null) statement.close();
+            } catch (SQLException se) {
+                // Purposefully doing nothing
+            }
+        }
+        lastSqlStatement = null;
+    }
+
+    /**
+     * Display the given result set for user.
+     * The last 3 params are to narrow down records and columns where
+     * that can not be done with a where clause (like in metadata queries).
+     * <P/>
+     * Caller is responsible for closing any passed Statement or ResultSet.
+     *
+     * @param statement The SQL Statement that the result set is for.
+     *                  (This is so we can get the statement's update count.
+     *                  Can be null for non-update queries.)
+     * @param r         The ResultSet to display.
+     * @param incCols   Optional list of which columns to include (i.e., if
+     *                  given, then other columns will be skipped).
+     * @param filterRegex Optional filter.  Rows are skipped which to not
+     *                  contain this substring in ANY COLUMN.
+     *                  (Should add another param to specify targeted columns).
+     * @throws SQLException thrown by JDBC driver.
+     * @throws SqlToolError all other errors.
+     */
+    private void displayResultSet(Statement statement, ResultSet r,
+                                  int[] incCols,
+                                  String filterString) throws SQLException,
+                                  SqlToolError {
+        java.sql.Timestamp ts;
+        int dotAt;
+        int                updateCount = (statement == null) ? -1
+                                                             : statement
+                                                                 .getUpdateCount();
+        boolean            silent      = silentFetch;
+        boolean            binary      = fetchBinary;
+        Pattern            filter = null;
+
+        silentFetch = false;
+        fetchBinary = false;
+
+        if (filterString != null) try {
+            filter = Pattern.compile(filterString);
+        } catch (PatternSyntaxException pse) {
+            throw new SqlToolError(
+                    SqltoolRB.regex_malformat.getString(pse.getMessage()));
+        }
+
+        if (excludeSysSchemas) {
+            stdprintln(SqltoolRB.vendor_nosup_sysschemas.getString());
+        }
+
+        switch (updateCount) {
+            case -1 :
+                if (r == null) {
+                    stdprintln(SqltoolRB.noresult.getString(), true);
+
+                    break;
+                }
+
+                ResultSetMetaData m        = r.getMetaData();
+                int               cols     = m.getColumnCount();
+                int               incCount = (incCols == null) ? cols
+                                                               : incCols
+                                                                   .length;
+                String            val;
+                List<String[]>    rows        = new ArrayList<String[]>();
+                String[]          headerArray = null;
+                String[]          fieldArray;
+                int[]             maxWidth = new int[incCount];
+                int               insi;
+                boolean           skip;
+                boolean           isValNull;
+
+                // STEP 1: GATHER DATA
+                if (!htmlMode) {
+                    for (int i = 0; i < maxWidth.length; i++) {
+                        maxWidth[i] = 0;
+                    }
+                }
+
+                boolean[] rightJust = new boolean[incCount];
+                int[]     dataType  = new int[incCount];
+                boolean[] autonulls = new boolean[incCount];
+
+                insi        = -1;
+                headerArray = new String[incCount];
+
+                for (int i = 1; i <= cols; i++) {
+                    if (incCols != null) {
+                        skip = true;
+
+                        for (int j = 0; j < incCols.length; j++) {
+                            if (i == incCols[j]) {
+                                skip = false;
+                            }
+                        }
+
+                        if (skip) {
+                            continue;
+                        }
+                    }
+
+                    headerArray[++insi] = m.getColumnLabel(i);
+                    dataType[insi]      = m.getColumnType(i);
+                    rightJust[insi]     = false;
+                    autonulls[insi]     = true;
+                    // This is what we want for java.sql.Types.ARRAY :
+
+                    switch (dataType[insi]) {
+                        case java.sql.Types.BIGINT :
+                        case java.sql.Types.BIT :
+                        case java.sql.Types.DECIMAL :
+                        case java.sql.Types.DOUBLE :
+                        case java.sql.Types.FLOAT :
+                        case java.sql.Types.INTEGER :
+                        case java.sql.Types.NUMERIC :
+                        case java.sql.Types.REAL :
+                        case java.sql.Types.SMALLINT :
+                        case java.sql.Types.TINYINT :
+                            rightJust[insi] = true;
+                            break;
+
+                        case java.sql.Types.VARBINARY :
+                        case java.sql.Types.VARCHAR :
+                        case java.sql.Types.BLOB :
+                        case java.sql.Types.CLOB :
+                        case java.sql.Types.LONGVARBINARY :
+                        case java.sql.Types.LONGVARCHAR :
+                            autonulls[insi] = false;
+                            break;
+                    }
+
+                    if (htmlMode) {
+                        continue;
+                    }
+
+                    if (headerArray[insi] != null
+                            && headerArray[insi].length() > maxWidth[insi]) {
+                        maxWidth[insi] = headerArray[insi].length();
+                    }
+                }
+
+                boolean filteredOut;
+
+                while (r.next()) {
+                    fieldArray  = new String[incCount];
+                    insi        = -1;
+                    filteredOut = filter != null;
+
+                    for (int i = 1; i <= cols; i++) {
+                        // This is the only case where we can save a data
+                        // read by recognizing we don't need this datum early.
+                        if (incCols != null) {
+                            skip = true;
+
+                            for (int incCol : incCols) {
+                                if (i == incCol) {
+                                    skip = false;
+                                }
+                            }
+
+                            if (skip) {
+                                continue;
+                            }
+                        }
+
+                        // This row may still be ditched, but it is now
+                        // certain that we need to increment the fieldArray
+                        // index.
+                        ++insi;
+
+                        if (!SqlFile.canDisplayType(dataType[insi])) {
+                            binary = true;
+                        }
+
+                        val = null;
+                        isValNull = true;
+
+                        if (!binary) {
+                            /*
+                             * The special formatting for all time-related
+                             * fields is because the most popular current
+                             * databases are extremely inconsistent about
+                             * what resolution is returned for the same types.
+                             * In my experience so far, Dates MAY have
+                             * resolution down to second, but only TIMESTAMPs
+                             * support sub-second res. (and always can).
+                             * On top of that there is no consistency across
+                             * getObject().toString().  Oracle doesn't even
+                             * implement it for their custom TIMESTAMP type.
+                             */
+                            switch (dataType[insi]) {
+                                case org.hsqldb.types.Types.SQL_TIMESTAMP_WITH_TIME_ZONE:
+                                case org.hsqldb.types.Types.SQL_TIME_WITH_TIME_ZONE:
+                                case java.sql.Types.TIMESTAMP:
+                                case java.sql.Types.DATE:
+                                case java.sql.Types.TIME:
+                                    ts  = r.getTimestamp(i);
+                                    isValNull = r.wasNull();
+                                    val = ((ts == null) ? null : ts.toString());
+                                    // Following block truncates non-zero
+                                    // sub-seconds from time types OTHER than
+                                    // TIMESTAMP.
+                                    if (dataType[insi]
+                                            != java.sql.Types.TIMESTAMP
+                                            && dataType[insi]
+                                            != org.hsqldb.types.Types.SQL_TIMESTAMP_WITH_TIME_ZONE
+                                            && val != null) {
+                                        dotAt = val.lastIndexOf('.');
+                                        for (int z = dotAt + 1;
+                                                z < val.length(); z++) {
+                                            if (val.charAt(z) != '0') {
+                                                dotAt = 0;
+                                                break;
+                                            }
+                                        }
+                                        if (dotAt > 1) {
+                                            val = val.substring(0, dotAt);
+                                        }
+                                    }
+                                    break;
+                                default:
+                                    val = r.getString(i);
+                                    isValNull = r.wasNull();
+
+                                    // If we tried to get a String but it
+                                    // failed, try getting it with a String
+                                    // Stream
+                                    if (val == null) {
+                                        try {
+                                            val = streamToString(
+                                                r.getAsciiStream(i),
+                                                shared.encoding);
+                                            isValNull = r.wasNull();
+                                        } catch (Exception e) {
+                                            // This isn't an error.
+                                            // We are attempting to do a stream
+                                            // fetch if-and-only-if the column
+                                            // supports it.
+                                        }
+                                    }
+                            }
+                        }
+
+                        if (binary || (val == null &&!isValNull)) {
+                            if (pwDsv != null) {
+                                throw new SqlToolError(
+                                        SqltoolRB.dsv_bincol.getString());
+                            }
+
+                            // DB has a value but we either explicitly want
+                            // it as binary, or we failed to get it as String.
+                            try {
+                                binBuffer =
+                                    SqlFile.streamToBytes(r.getBinaryStream(i));
+                                isValNull = r.wasNull();
+                            } catch (IOException ioe) {
+                                throw new SqlToolError(
+                                    "Failed to read value using stream",
+                                    ioe);
+                            }
+
+                            stdprintln(SqltoolRB.binbuf_write.getString(
+                                       Integer.toString(binBuffer.length),
+                                       headerArray[insi],
+                                       SqlFile.sqlTypeToString(dataType[insi])
+                                    ));
+
+                            return;
+                        }
+
+                        if (excludeSysSchemas && val != null && i == 2) {
+                            for (String oracleSysSchema : oracleSysSchemas) {
+                                if (val.equals(oracleSysSchema)) {
+                                    filteredOut = true;
+
+                                    break;
+                                }
+                            }
+                        }
+
+                        shared.userVars.put("?",
+                                ((val == null) ? nullRepToken : val));
+                        if (fetchingVar != null) {
+                            shared.userVars.put(
+                                    fetchingVar, shared.userVars.get("?"));
+                            updateUserSettings();
+
+                            fetchingVar = null;
+                        }
+
+                        if (silent) {
+                            return;
+                        }
+
+                        // We do not omit rows here.  We collect information
+                        // so we can make the decision after all rows are
+                        // read in.
+                        if (filter != null
+                            && (val == null || filter.matcher(val).find())) {
+                            filteredOut = false;
+                        }
+
+                        ///////////////////////////////
+                        // A little tricky here.  fieldArray[] MUST get set.
+                        if (val == null && pwDsv == null) {
+                            if (dataType[insi] == java.sql.Types.VARCHAR) {
+                                fieldArray[insi] = (htmlMode ? "<I>null</I>"
+                                                             : nullRepToken);
+                            } else {
+                                fieldArray[insi] = "";
+                            }
+                        } else {
+                            fieldArray[insi] = val;
+                        }
+
+                        ///////////////////////////////
+                        if (htmlMode || pwDsv != null) {
+                            continue;
+                        }
+
+                        if (fieldArray[insi].length() > maxWidth[insi]) {
+                            maxWidth[insi] = fieldArray[insi].length();
+                        }
+                    }
+
+                    if (!filteredOut) {
+                        rows.add(fieldArray);
+                    }
+                }
+
+                // STEP 2: DISPLAY DATA  (= 2a OR 2b)
+                // STEP 2a (Non-DSV)
+                if (pwDsv == null) {
+                    condlPrintln("<TABLE border='1'>", true);
+
+                    if (incCount > 1) {
+                        condlPrint(SqlFile.htmlRow(COL_HEAD) + LS + PRE_TD, true);
+
+                        for (int i = 0; i < headerArray.length; i++) {
+                            condlPrint("<TD>" + headerArray[i] + "</TD>",
+                                       true);
+                            condlPrint(((i > 0) ? "  " : "")
+                                    + ((i < headerArray.length - 1
+                                        || rightJust[i])
+                                       ? StringUtil.toPaddedString(
+                                         headerArray[i], maxWidth[i],
+                                         ' ', !rightJust[i])
+                                       : headerArray[i])
+                                    , false);
+                        }
+
+                        condlPrintln(LS + PRE_TR + "</TR>", true);
+                        condlPrintln("", false);
+
+                        if (!htmlMode) {
+                            for (int i = 0; i < headerArray.length; i++) {
+                                condlPrint(((i > 0) ? "  "
+                                                    : "") + SqlFile.divider(
+                                                        maxWidth[i]), false);
+                            }
+
+                            condlPrintln("", false);
+                        }
+                    }
+
+                    for (int i = 0; i < rows.size(); i++) {
+                        condlPrint(SqlFile.htmlRow(((i % 2) == 0) ? COL_EVEN
+                                                          : COL_ODD) + LS
+                                                          + PRE_TD, true);
+
+                        fieldArray = rows.get(i);
+
+                        for (int j = 0; j < fieldArray.length; j++) {
+                            condlPrint("<TD>" + fieldArray[j] + "</TD>",
+                                       true);
+                            condlPrint(((j > 0) ? "  " : "")
+                                    + ((j < fieldArray.length - 1
+                                        || rightJust[j])
+                                       ? StringUtil.toPaddedString(
+                                         fieldArray[j], maxWidth[j],
+                                         ' ', !rightJust[j])
+                                       : fieldArray[j])
+                                    , false);
+                        }
+
+                        condlPrintln(LS + PRE_TR + "</TR>", true);
+                        condlPrintln("", false);
+                    }
+
+                    condlPrintln("</TABLE>", true);
+
+                    if (interactive && rows.size() != 1) {
+                        stdprintln(LS + SqltoolRB.rows_fetched.getString(
+                                rows.size()), true);
+                    }
+
+                    condlPrintln("<HR>", true);
+
+                    break;
+                }
+
+                // STEP 2b (DSV)
+                if (incCount > 0) {
+                    for (int i = 0; i < headerArray.length; i++) {
+                        dsvSafe(headerArray[i]);
+                        pwDsv.print(headerArray[i]);
+
+                        if (i < headerArray.length - 1) {
+                            pwDsv.print(dsvColDelim);
+                        }
+                    }
+
+                    pwDsv.print(dsvRowDelim);
+                }
+
+                for (String[] fArray : rows) {
+                    for (int j = 0; j < fArray.length; j++) {
+                        dsvSafe(fArray[j]);
+                        pwDsv.print((fArray[j] == null)
+                                    ? (autonulls[j] ? ""
+                                                    : nullRepToken)
+                                    : fArray[j]);
+
+                        if (j < fArray.length - 1) {
+                            pwDsv.print(dsvColDelim);
+                        }
+                    }
+
+                    pwDsv.print(dsvRowDelim);
+                }
+
+                stdprintln(SqltoolRB.rows_fetched_dsv.getString(rows.size()));
+                // Undecided about whether should display row count here when
+                // in non-interactive mode
+                break;
+
+            default :
+                shared.userVars.put("?", Integer.toString(updateCount));
+                if (fetchingVar != null) {
+                    shared.userVars.put(fetchingVar, shared.userVars.get("?"));
+                    updateUserSettings();
+                    fetchingVar = null;
+                }
+
+                if (updateCount != 0 && interactive) {
+                    stdprintln((updateCount == 1)
+                        ? SqltoolRB.row_update_singular.getString()
+                        : SqltoolRB.row_update_multiple.getString(updateCount));
+                }
+                break;
+        }
+    }
+
+    private static final int    COL_HEAD = 0,
+                                COL_ODD  = 1,
+                                COL_EVEN = 2
+    ;
+    private static final String PRE_TR   = "    ";
+    private static final String PRE_TD   = "        ";
+
+    /**
+     * Print a properly formatted HTML &lt;TR&gt; command for the given
+     * situation.
+     *
+     * @param colType Column type:  COL_HEAD, COL_ODD or COL_EVEN.
+     */
+    private static String htmlRow(int colType) {
+        switch (colType) {
+            case COL_HEAD :
+                return PRE_TR + "<TR style='font-weight: bold;'>";
+
+            case COL_ODD :
+                return PRE_TR
+                       + "<TR style='background: #94d6ef; font: normal "
+                       + "normal 10px/10px Arial, Helvitica, sans-serif;'>";
+
+            case COL_EVEN :
+                return PRE_TR
+                       + "<TR style='background: silver; font: normal "
+                       + "normal 10px/10px Arial, Helvitica, sans-serif;'>";
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns a divider of hypens of requested length.
+     *
+     * @param len Length of output String.
+     */
+    private static String divider(int len) {
+        return (len > DIVIDER.length()) ? DIVIDER
+                                        : DIVIDER.substring(0, len);
+    }
+
+    /**
+     * Display command history.
+     */
+    private void showHistory() throws BadSpecial {
+        if (history == null) {
+            throw new BadSpecial(SqltoolRB.history_unavailable.getString());
+        }
+        if (history.size() < 1) {
+            throw new BadSpecial(SqltoolRB.history_none.getString());
+        }
+        if (shared.psStd == null) return;
+          // Input can be dual-purpose, i.e. the script can be intended for
+          // both interactive and non-interactive usage.
+        Token token;
+        for (int i = 0; i < history.size(); i++) {
+            token = history.get(i);
+            shared.psStd.println("#" + (i + oldestHist) + " or "
+                    + (i - history.size()) + ':');
+            shared.psStd.println(token.reconstitute());
+        }
+        if (buffer != null) {
+            shared.psStd.println(SqltoolRB.editbuffer_contents.getString(
+                    buffer.reconstitute()));
+        }
+
+        shared.psStd.println();
+        shared.psStd.println(SqltoolRB.buffer_instructions.getString());
+    }
+
+    /**
+     * Return a Command from command history.
+     */
+    private Token commandFromHistory(int inIndex) throws BadSpecial {
+        int index = inIndex;  // Just to quiet compiler warnings.
+
+        if (history == null) {
+            throw new BadSpecial(SqltoolRB.history_unavailable.getString());
+        }
+        if (index == 0) {
+            throw new BadSpecial(SqltoolRB.history_number_req.getString());
+        }
+        if (index > 0) {
+            // Positive command# given
+            index -= oldestHist;
+            if (index < 0) {
+                throw new BadSpecial(
+                        SqltoolRB.history_backto.getString(oldestHist));
+            }
+            if (index >= history.size()) {
+                throw new BadSpecial(SqltoolRB.history_upto.getString(
+                       history.size() + oldestHist - 1));
+            }
+        } else {
+            // Negative command# given
+            index += history.size();
+            if (index < 0) {
+                throw new BadSpecial(
+                        SqltoolRB.history_back.getString(history.size()));
+            }
+        }
+        return history.get(index);
+    }
+
+    /**
+     * Search Command History for a regex match.
+     *
+     * @return Absolute command number, if any match.
+     */
+    private Integer historySearch(String findRegex) throws BadSpecial {
+        if (history == null) {
+            throw new BadSpecial(SqltoolRB.history_unavailable.getString());
+        }
+        Pattern pattern = null;
+        try {
+            pattern = Pattern.compile("(?ims)" + findRegex);
+        } catch (PatternSyntaxException pse) {
+            throw new BadSpecial(
+                    SqltoolRB.regex_malformat.getString(pse.getMessage()));
+        }
+        // Make matching more liberal.  Users can customize search behavior
+        // by using "(?-OPTIONS)" or (?OPTIONS) in their regexes.
+        for (int index = history.size() - 1; index >= 0; index--)
+            if (pattern.matcher((history.get(index)).val).find())
+                return Integer.valueOf(index + oldestHist);
+        return null;
+    }
+
+    /**
+     * Set buffer, unless the given token equals what is already in the
+     * buffer.
+     */
+    private boolean setBuf(Token newBuffer) {
+        if (buffer != null)
+        if (buffer != null && buffer.equals(newBuffer)) return false;
+        switch (newBuffer.type) {
+            case Token.SQL_TYPE:
+            case Token.PL_TYPE:
+            case Token.SPECIAL_TYPE:
+                break;
+            default:
+                throw new RuntimeException(
+                        "Internal assertion failed.  "
+                        + "Attempted to add command type "
+                        + newBuffer.getTypeString() + " to buffer");
+        }
+        buffer = new Token(newBuffer.type, new String(newBuffer.val),
+                newBuffer.line);
+        // System.err.println("Buffer is now (" + buffer + ')');
+        return true;
+    }
+
+    int oldestHist = 1;
+
+    /**
+     * Add a command onto the history list.
+     */
+    private boolean historize() {
+        if (history == null || buffer == null) {
+            return false;
+        }
+        if (history.size() > 0 &&
+                history.get(history.size() - 1).equals(buffer)) {
+            // Don't store two consecutive commands that are exactly the same.
+            return false;
+        }
+        history.add(buffer);
+        if (history.size() <= maxHistoryLength) {
+            return true;
+        }
+        history.remove(0);
+        oldestHist++;
+        return true;
+    }
+
+    /**
+     * Describe the columns of specified table.
+     *
+     * @param tableName  Table that will be described.
+     * @param filter  Optional regex to filter by.
+     *                By default, will match only against the column name.
+     *                Prefix with "/" to match against the entire output line.
+     */
+    private void describe(String tableName,
+                          String filterString) throws SQLException {
+        if (shared.jdbcConn == null)
+            throw new RuntimeException(
+                    "Somehow got to 'describe' even though we have no Conn");
+        /*
+         * Doing case-sensitive filters now, for greater portability.
+        String filter = ((inFilter == null) ? null : inFilter.toUpperCase());
+         */
+        Pattern   filter = null;
+        boolean   filterMatchesAll = false;  // match filter against all cols.
+        List<String[]> rows = new ArrayList<String[]>();
+        String[]  headerArray = {
+            SqltoolRB.describe_table_name.getString(),
+            SqltoolRB.describe_table_datatype.getString(),
+            SqltoolRB.describe_table_width.getString(),
+            SqltoolRB.describe_table_nonulls.getString(),
+        };
+        String[]  fieldArray;
+        int[]     maxWidth  = {
+            0, 0, 0, 0
+        };
+        boolean[] rightJust = {
+            false, false, true, false
+        };
+
+        if (filterString != null) try {
+            filterMatchesAll = (filterString.charAt(0) == '/');
+            filter = Pattern.compile(filterMatchesAll
+                    ? filterString.substring(1) : filterString);
+        } catch (PatternSyntaxException pse) {
+            throw new SQLException(SqltoolRB.regex_malformat.getString(
+                    pse.getMessage()));
+            // This is obviously not a SQLException.
+            // Perhaps change input parameter to a Pattern to require
+            // caller to compile the pattern?
+        }
+
+        for (int i = 0; i < headerArray.length; i++) {
+            if (htmlMode) {
+                continue;
+            }
+
+            if (headerArray[i].length() > maxWidth[i]) {
+                maxWidth[i] = headerArray[i].length();
+            }
+        }
+
+        ResultSet r         = null;
+        Statement statement = shared.jdbcConn.createStatement();
+
+        // STEP 1: GATHER DATA
+        try {
+            statement.execute("SELECT * FROM " + tableName + " WHERE 1 = 2");
+
+            r = statement.getResultSet();
+
+            ResultSetMetaData m    = r.getMetaData();
+            int               cols = m.getColumnCount();
+
+            for (int i = 0; i < cols; i++) {
+                fieldArray    = new String[4];
+                fieldArray[0] = m.getColumnName(i + 1);
+
+                if (filter != null && (!filterMatchesAll)
+                        && !filter.matcher(fieldArray[0]).find()) {
+                    continue;
+                }
+
+                fieldArray[1] = m.getColumnTypeName(i + 1);
+                fieldArray[2] = Integer.toString(m.getColumnDisplaySize(i + 1));
+                fieldArray[3] =
+                    ((m.isNullable(i + 1) == java.sql.ResultSetMetaData.columnNullable)
+                     ? (htmlMode ? "&nbsp;"
+                                 : "")
+                     : "*");
+
+                if (filter != null && filterMatchesAll
+                        && !filter.matcher(fieldArray[0]
+                            + ' ' + fieldArray[1] + ' ' + fieldArray[2] + ' '
+                            + fieldArray[3]).find()) {
+                    continue;
+                }
+
+                rows.add(fieldArray);
+
+                for (int j = 0; j < fieldArray.length; j++) {
+                    if (fieldArray[j].length() > maxWidth[j]) {
+                        maxWidth[j] = fieldArray[j].length();
+                    }
+                }
+            }
+
+            // STEP 2: DISPLAY DATA
+            condlPrint("<TABLE border='1'>" + LS + SqlFile.htmlRow(COL_HEAD) + LS
+                       + PRE_TD, true);
+
+            for (int i = 0; i < headerArray.length; i++) {
+                condlPrint("<TD>" + headerArray[i] + "</TD>", true);
+                condlPrint(((i > 0) ? "  " : "")
+                        + ((i < headerArray.length - 1 || rightJust[i])
+                           ? StringUtil.toPaddedString(
+                             headerArray[i], maxWidth[i], ' ', !rightJust[i])
+                           : headerArray[i])
+                        , false);
+            }
+
+            condlPrintln(LS + PRE_TR + "</TR>", true);
+            condlPrintln("", false);
+
+            if (!htmlMode) {
+                for (int i = 0; i < headerArray.length; i++) {
+                    condlPrint(((i > 0) ? "  "
+                                        : "") + SqlFile.divider(maxWidth[i]), false);
+                }
+
+                condlPrintln("", false);
+            }
+
+            for (int i = 0; i < rows.size(); i++) {
+                condlPrint(SqlFile.htmlRow(((i % 2) == 0) ? COL_EVEN
+                                                  : COL_ODD) + LS
+                                                  + PRE_TD, true);
+
+                fieldArray = rows.get(i);
+
+                for (int j = 0; j < fieldArray.length; j++) {
+                    condlPrint("<TD>" + fieldArray[j] + "</TD>", true);
+                    condlPrint(((j > 0) ? "  " : "")
+                            + ((j < fieldArray.length - 1 || rightJust[j])
+                               ? StringUtil.toPaddedString(
+                                 fieldArray[j], maxWidth[j], ' ', !rightJust[j])
+                               : fieldArray[j])
+                            , false);
+                }
+
+                condlPrintln(LS + PRE_TR + "</TR>", true);
+                condlPrintln("", false);
+            }
+
+            condlPrintln(LS + "</TABLE>" + LS + "<HR>", true);
+        } finally {
+            try {
+                if (r != null) {
+                    r.close();
+                }
+
+                statement.close();
+            } catch (SQLException se) {
+                // Purposefully doing nothing
+            }
+        }
+    }
+
+    private boolean eval(String[] inTokens) throws BadSpecial {
+        /* TODO:  Rewrite using java.util.regex.  */
+        // dereference *VARNAME variables.
+        // N.b. we work with a "copy" of the tokens.
+        boolean  negate = inTokens.length > 0 && inTokens[0].equals("!");
+        String[] tokens = new String[negate ? (inTokens.length - 1)
+                                            : inTokens.length];
+        String inToken;
+
+        for (int i = 0; i < tokens.length; i++) {
+            inToken = inTokens[i + (negate ? 1 : 0)];
+            if (inToken.length() > 1 && inToken.charAt(0) == '*') {
+                tokens[i] = shared.userVars.get(inToken.substring(1));
+            } else {
+                tokens[i] = inTokens[i + (negate ? 1 : 0)];
+            }
+
+            // Unset variables permitted in expressions as long as use
+            // the short *VARNAME form.
+            if (tokens[i] == null) {
+                tokens[i] = "";
+            }
+        }
+
+        if (tokens.length == 1) {
+            return (tokens[0].length() > 0 &&!tokens[0].equals("0")) ^ negate;
+        }
+
+        if (tokens.length == 3) {
+            if (tokens[1].equals("==")) {
+                return tokens[0].equals(tokens[2]) ^ negate;
+            }
+
+            if (tokens[1].equals("!=") || tokens[1].equals("<>")
+                    || tokens[1].equals("><")) {
+                return (!tokens[0].equals(tokens[2])) ^ negate;
+            }
+
+            if (tokens[1].equals(">")) {
+                return (tokens[0].length() > tokens[2].length() || ((tokens[0].length() == tokens[2].length()) && tokens[0].compareTo(tokens[2]) > 0))
+                       ^ negate;
+            }
+
+            if (tokens[1].equals("<")) {
+                return (tokens[2].length() > tokens[0].length() || ((tokens[2].length() == tokens[0].length()) && tokens[2].compareTo(tokens[0]) > 0))
+                       ^ negate;
+            }
+        }
+
+        throw new BadSpecial(SqltoolRB.logical_unrecognized.getString());
+    }
+
+    private void closeQueryOutputStream() {
+        if (pwQuery == null) {
+            return;
+        }
+
+        try {
+            if (htmlMode) {
+                pwQuery.println("</BODY></HTML>");
+                pwQuery.flush();
+            }
+        } finally {
+            try {
+                pwQuery.close();
+            } finally {
+                pwQuery = null; // Encourage GC of buffers
+            }
+        }
+    }
+
+    /**
+     * Print to psStd and possibly pwQuery iff current HTML mode matches
+     * supplied printHtml.
+     */
+    private void condlPrintln(String s, boolean printHtml) {
+        if ((printHtml &&!htmlMode) || (htmlMode &&!printHtml)) {
+            return;
+        }
+
+        if (shared.psStd != null) shared.psStd.println(s);
+
+        if (pwQuery != null) {
+            pwQuery.println(s);
+            pwQuery.flush();
+        }
+    }
+
+    /**
+     * Print to psStd and possibly pwQuery iff current HTML mode matches
+     * supplied printHtml.
+     */
+    private void condlPrint(String s, boolean printHtml) {
+        if ((printHtml &&!htmlMode) || (htmlMode &&!printHtml)) {
+            return;
+        }
+
+        if (shared.psStd != null) shared.psStd.print(s);
+
+        if (pwQuery != null) {
+            pwQuery.print(s);
+            pwQuery.flush();
+        }
+    }
+
+    private String formatNicely(Map<?, ?> map, boolean withValues) {
+        String       s;
+        StringBuffer sb = new StringBuffer();
+
+        if (withValues) {
+            SqlFile.appendLine(sb, SqltoolRB.pl_list_parens.getString());
+        } else {
+            SqlFile.appendLine(sb, SqltoolRB.pl_list_lengths.getString());
+        }
+
+        for (Map.Entry<Object, Object> entry
+                : new TreeMap<Object, Object>(map).entrySet()) {
+            s = (String) entry.getValue();
+
+            SqlFile.appendLine(sb, "    " + (String) entry.getKey() + ": " + (withValues ? ("(" + s + ')')
+                                                        : Integer.toString(
+                                                        s.length())));
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Ascii file dump.
+     *
+     * dumpFile must not be null.
+     */
+    private void dump(String varName,
+                      File dumpFile) throws IOException, BadSpecial {
+        String val = shared.userVars.get(varName);
+
+        if (val == null) {
+            throw new BadSpecial(SqltoolRB.plvar_undefined.getString(varName));
+        }
+
+        OutputStreamWriter osw = new OutputStreamWriter(
+                new FileOutputStream(dumpFile), (shared.encoding == null)
+                ? DEFAULT_FILE_ENCODING : shared.encoding);
+
+        try {
+            osw.write(val);
+
+            if (val.length() > 0) {
+                char lastChar = val.charAt(val.length() - 1);
+
+                if (lastChar != '\n' && lastChar != '\r') {
+                    osw.write(LS);
+                }
+            }
+
+            osw.flush();
+        } finally {
+            try {
+                osw.close();
+            } catch (IOException ioe) {
+                // Intentionally empty
+            } finally {
+                osw = null;  // Encourage GC of buffers
+            }
+        }
+
+        // Since opened in overwrite mode, since we didn't exception out,
+        // we can be confident that we wrote all the bytest in the file.
+        stdprintln(SqltoolRB.file_wrotechars.getString(
+                Long.toString(dumpFile.length()), dumpFile.toString()));
+    }
+
+    byte[] binBuffer;
+
+    /**
+     * Binary file dump
+     *
+     * dumpFile must not be null.
+     */
+    private void dump(File dumpFile) throws IOException, BadSpecial {
+        if (binBuffer == null) {
+            throw new BadSpecial(SqltoolRB.binbuffer_empty.getString());
+        }
+
+        int len = 0;
+        FileOutputStream fos = new FileOutputStream(dumpFile);
+
+        try {
+            fos.write(binBuffer);
+
+            len = binBuffer.length;
+
+            binBuffer = null;
+
+            fos.flush();
+        } finally {
+            try {
+                fos.close();
+            } catch (IOException ioe) {
+                // Intentionally empty
+            } finally {
+                fos = null; // Encourage GC of buffers
+            }
+        }
+        stdprintln(SqltoolRB.file_wrotechars.getString(
+                len, dumpFile.toString()));
+    }
+
+    /**
+     * As the name says...
+     * This method always closes the input stream.
+     */
+    public String streamToString(InputStream isIn, String cs)
+            throws IOException {
+        InputStream is = isIn;  // Compiler warning, when we can null the ref
+        byte[] ba = null;
+        int bytesread = 0;
+        int retval;
+        try {
+            try {
+                ba = new byte[is.available()];
+            } catch (RuntimeException re) {
+                throw new IOException(SqltoolRB.read_toobig.getString());
+            }
+            while (bytesread < ba.length &&
+                    (retval = is.read(
+                            ba, bytesread, ba.length - bytesread)) > 0) {
+                bytesread += retval;
+            }
+            if (bytesread != ba.length) {
+                throw new IOException(
+                        SqltoolRB.read_partial.getString(bytesread, ba.length));
+            }
+            try {
+                return (cs == null) ? (new String(ba))
+                                         : (new String(ba, cs));
+            } catch (UnsupportedEncodingException uee) {
+                throw new IOException(
+                        SqltoolRB.encode_fail.getString(uee.getMessage()));
+            } catch (RuntimeException re) {
+                throw new IOException(SqltoolRB.read_convertfail.getString());
+            }
+        } finally {
+            try {
+                is.close();
+            } catch (IOException ioe) {
+                // intentionally empty
+            } finally {
+                is = null;  // Encourage GC of buffers
+            }
+        }
+    }
+
+    /**
+     * Ascii file load.
+     */
+    private void load(String varName, File asciiFile, String cs)
+            throws IOException {
+        String string = streamToString(new FileInputStream(asciiFile), cs);
+        // The streamToString() method ensures that the Stream gets closed
+        shared.userVars.put(varName, string);
+        updateUserSettings();
+    }
+
+    /**
+     * As the name says...
+     */
+    public static byte[] streamToBytes(InputStream is) throws IOException {
+        byte[]                xferBuffer = new byte[10240];
+        byte[]                outBytes = null;
+        int                   i;
+        ByteArrayOutputStream baos       = new ByteArrayOutputStream();
+
+        try {
+            while ((i = is.read(xferBuffer)) > 0) {
+                baos.write(xferBuffer, 0, i);
+            }
+            outBytes = baos.toByteArray();
+        } finally {
+            baos = null;  // Encourage buffer GC
+        }
+        return outBytes;
+    }
+
+    /**
+     * Binary file load
+     *
+     * @return The bytes which are the content of the fil
+     */
+    public static byte[] loadBinary(File binFile) throws IOException {
+        byte[]                xferBuffer = new byte[10240];
+        byte[]                outBytes = null;
+        ByteArrayOutputStream baos;
+        int                   i;
+        FileInputStream       fis        = new FileInputStream(binFile);
+
+        try {
+            baos = new ByteArrayOutputStream();
+            while ((i = fis.read(xferBuffer)) > 0) {
+                baos.write(xferBuffer, 0, i);
+            }
+            outBytes = baos.toByteArray();
+        } finally {
+            try {
+                fis.close();
+            } catch (IOException ioe) {
+                // intentionally empty
+            } finally {
+                fis = null; // Encourage GC of buffers
+                baos = null; // Encourage GC of buffers
+            }
+        }
+
+        return outBytes;
+    }
+
+    /**
+     * This method is used to tell SqlFile whether this Sql Type must
+     * ALWAYS be loaded to the binary buffer without displaying.
+     * <P>
+     * N.b.:  If this returns "true" for a type, then the user can never
+     * "see" values for these columns.
+     * Therefore, if a type may-or-may-not-be displayable, better to return
+     * false here and let the user choose.
+     * In general, if there is a toString() operator for this Sql Type
+     * then return false, since the JDBC driver should know how to make the
+     * value displayable.
+     * </P>
+     *
+     * @see <A href="http://java.sun.com/docs/books/tutorial/jdbc/basics/retrieving.html">http://java.sun.com/docs/books/tutorial/jdbc/basics/retrieving.html</A>
+     *      The table on this page lists the most common SqlTypes, all of which
+     *      must implement toString()
+     * @see java.sql.Types
+     */
+    public static boolean canDisplayType(int i) {
+        /* I don't now about some of the more obscure types, like REF and
+         * DATALINK */
+        switch (i) {
+            //case java.sql.Types.BINARY :
+            case java.sql.Types.BLOB :
+            case java.sql.Types.JAVA_OBJECT :
+
+            //case java.sql.Types.LONGVARBINARY :
+            //case java.sql.Types.LONGVARCHAR :
+            case java.sql.Types.OTHER :
+            case java.sql.Types.STRUCT :
+
+                //case java.sql.Types.VARBINARY :
+                return false;
+        }
+
+        return true;
+    }
+
+    // won't compile with JDK 1.4 without these
+    private static final int JDBC3_BOOLEAN  = 16;
+    private static final int JDBC3_DATALINK = 70;
+
+    /**
+     * Return a String representation of the specified java.sql.Types type.
+     */
+    public static String sqlTypeToString(int i) {
+        switch (i) {
+            case java.sql.Types.ARRAY :
+                return "ARRAY";
+
+            case java.sql.Types.BIGINT :
+                return "BIGINT";
+
+            case java.sql.Types.BINARY :
+                return "BINARY";
+
+            case java.sql.Types.BIT :
+                return "BIT";
+
+            case java.sql.Types.BLOB :
+                return "BLOB";
+
+            case JDBC3_BOOLEAN :
+                return "BOOLEAN";
+
+            case java.sql.Types.CHAR :
+                return "CHAR";
+
+            case java.sql.Types.CLOB :
+                return "CLOB";
+
+            case JDBC3_DATALINK :
+                return "DATALINK";
+
+            case java.sql.Types.DATE :
+                return "DATE";
+
+            case java.sql.Types.DECIMAL :
+                return "DECIMAL";
+
+            case java.sql.Types.DISTINCT :
+                return "DISTINCT";
+
+            case java.sql.Types.DOUBLE :
+                return "DOUBLE";
+
+            case java.sql.Types.FLOAT :
+                return "FLOAT";
+
+            case java.sql.Types.INTEGER :
+                return "INTEGER";
+
+            case java.sql.Types.JAVA_OBJECT :
+                return "JAVA_OBJECT";
+
+            case java.sql.Types.LONGVARBINARY :
+                return "LONGVARBINARY";
+
+            case java.sql.Types.LONGVARCHAR :
+                return "LONGVARCHAR";
+
+            case java.sql.Types.NULL :
+                return "NULL";
+
+            case java.sql.Types.NUMERIC :
+                return "NUMERIC";
+
+            case java.sql.Types.OTHER :
+                return "OTHER";
+
+            case java.sql.Types.REAL :
+                return "REAL";
+
+            case java.sql.Types.REF :
+                return "REF";
+
+            case java.sql.Types.SMALLINT :
+                return "SMALLINT";
+
+            case java.sql.Types.STRUCT :
+                return "STRUCT";
+
+            case java.sql.Types.TIME :
+                return "TIME";
+
+            case java.sql.Types.TIMESTAMP :
+                return "TIMESTAMP";
+
+            case java.sql.Types.TINYINT :
+                return "TINYINT";
+
+            case java.sql.Types.VARBINARY :
+                return "VARBINARY";
+
+            case java.sql.Types.VARCHAR :
+                return "VARCHAR";
+
+            case org.hsqldb.types.Types.SQL_TIME_WITH_TIME_ZONE :
+                return "SQL_TIME_WITH_TIME_ZONE";
+
+            case org.hsqldb.types.Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return "SQL_TIMESTAMP_WITH_TIME_ZONE";
+        }
+
+        return "Unknown type " + i;
+    }
+
+    /**
+     * Validate that String is safe to write TO DSV file.
+     *
+     * @throws SqlToolError if validation fails.
+     */
+    public void dsvSafe(String s) throws SqlToolError {
+        if (pwDsv == null || dsvColDelim == null || dsvRowDelim == null
+                || nullRepToken == null) {
+            throw new RuntimeException(
+                "Assertion failed.  \n"
+                + "dsvSafe called when DSV settings are incomplete");
+        }
+
+        if (s == null) {
+            return;
+        }
+
+        if (s.indexOf(dsvColDelim) > 0) {
+            throw new SqlToolError(
+                    SqltoolRB.dsv_coldelim_present.getString(dsvColDelim));
+        }
+
+        if (s.indexOf(dsvRowDelim) > 0) {
+            throw new SqlToolError(
+                    SqltoolRB.dsv_rowdelim_present.getString(dsvRowDelim));
+        }
+
+        if (s.trim().equals(nullRepToken)) {
+            // The trim() is to avoid the situation where the contents of a
+            // field "looks like" the null-rep token.
+            throw new SqlToolError(
+                    SqltoolRB.dsv_nullrep_present.getString(nullRepToken));
+        }
+    }
+
+    /**
+     * Translates user-supplied escapes into the traditionaly corresponding
+     * corresponding binary characters.
+     *
+     * Allowed sequences:
+     * <UL>
+     *  <LI>\0\d+   (an octal digit)
+     *  <LI>\[0-9]\d*  (a decimal digit)
+     *  <LI>\[Xx][0-9]{2}  (a hex digit)
+     *  <LI>\n  Newline  (Ctrl-J)
+     *  <LI>\r  Carriage return  (Ctrl-M)
+     *  <LI>\t  Horizontal tab  (Ctrl-I)
+     *  <LI>\f  Form feed  (Ctrl-L)
+     * </UL>
+     *
+     * Java 1.4 String methods will make this into a 1 or 2 line task.
+     */
+    public static String convertEscapes(String inString) {
+        if (inString == null) {
+            return null;
+        }
+        return convertNumericEscapes(
+                convertEscapes(convertEscapes(convertEscapes(convertEscapes(
+                    convertEscapes(inString, "\\n", "\n"), "\\r", "\r"),
+                "\\t", "\t"), "\\\\", "\\"),
+            "\\f", "\f")
+        );
+    }
+
+    /**
+     * @param string  Non-null String to modify.
+     */
+    private static String convertNumericEscapes(String string) {
+        String workString = string;
+        int i = 0;
+
+        for (char dig = '0'; dig <= '9'; dig++) {
+            while ((i = workString.indexOf("\\" + dig, i)) > -1
+                    && i < workString.length() - 1) {
+                workString = convertNumericEscape(string, i);
+            }
+            while ((i = workString.indexOf("\\x" + dig, i)) > -1
+                    && i < workString.length() - 1) {
+                workString = convertNumericEscape(string, i);
+            }
+            while ((i = workString.indexOf("\\X" + dig, i)) > -1
+                    && i < workString.length() - 1) {
+                workString = convertNumericEscape(string, i);
+            }
+        }
+        return workString;
+    }
+
+    /**
+     * @offset  Position of the leading \.
+     */
+    private static String convertNumericEscape(String string, int offset) {
+        int post = -1;
+        int firstDigit = -1;
+        int radix = -1;
+        if (Character.toUpperCase(string.charAt(offset + 1)) == 'X') {
+            firstDigit = offset + 2;
+            radix = 16;
+            post = firstDigit + 2;
+            if (post > string.length()) post = string.length();
+        } else {
+            firstDigit = offset + 1;
+            radix = (Character.toUpperCase(string.charAt(firstDigit)) == '0')
+                    ? 8 : 10;
+            post = firstDigit + 1;
+            while (post < string.length()
+                    && Character.isDigit(string.charAt(post))) post++;
+        }
+        return string.substring(0, offset) + ((char)
+                Integer.parseInt(string.substring(firstDigit, post), radix))
+                + string.substring(post);
+    }
+
+    /**
+     * @param string  Non-null String to modify.
+     */
+    private static String convertEscapes(String string, String from, String to) {
+        String workString = string;
+        int i = 0;
+        int fromLen = from.length();
+
+        while ((i = workString.indexOf(from, i)) > -1
+                && i < workString.length() - 1) {
+            workString = workString.substring(0, i) + to
+                         + workString.substring(i + fromLen);
+        }
+        return workString;
+    }
+
+    /**
+     * Name is self-explanatory.
+     *
+     * If there is user demand, open file in random access mode so don't
+     * need to load 2 copies of the entire file into memory.
+     * This will be difficult because can't use standard Java language
+     * features to search through a character array for multi-character
+     * substrings.
+     *
+     * @throws SqlToolError  Would prefer to throw an internal exception,
+     *                       but we want this method to have external
+     *                       visibility.
+     */
+    public void importDsv(String filePath, String skipPrefix)
+            throws SqlToolError {
+        requireConnection();
+        /* To make string comparisons, contains() methods, etc. a little
+         * simpler and concise, just switch all column names to lower-case.
+         * This is ok since we acknowledge up front that DSV import/export
+         * assume no special characters or escaping in column names. */
+        Matcher matcher;
+        byte[] bfr  = null;
+        File   dsvFile = new File(filePath);
+        SortedMap<String, String> constColMap = null;
+        if (dsvConstCols != null) {
+            // We trim col. names, but not values.  Must allow users to
+            // specify values as spaces, empty string, null.
+            constColMap = new TreeMap<String, String>();
+            for (String constPair : dsvConstCols.split(dsvColSplitter, -1)) {
+                matcher = nameValPairPattern.matcher(constPair);
+                if (!matcher.matches()) {
+                    throw new SqlToolError(
+                            SqltoolRB.dsv_constcols_nullcol.getString());
+                }
+                constColMap.put(matcher.group(1).toLowerCase(),
+                        ((matcher.groupCount() < 2 || matcher.group(2) == null)
+                        ? "" : matcher.group(2)));
+            }
+        }
+        Set<String> skipCols = null;
+        if (dsvSkipCols != null) {
+            skipCols = new HashSet<String>();
+            for (String skipCol : dsvSkipCols.split(dsvColSplitter, -1)) {
+                skipCols.add(skipCol.trim().toLowerCase());
+            }
+        }
+
+        if (!dsvFile.canRead()) {
+            throw new SqlToolError(SqltoolRB.file_readfail.getString(
+                    dsvFile.toString()));
+        }
+
+        try {
+            bfr = new byte[(int) dsvFile.length()];
+        } catch (RuntimeException re) {
+            throw new SqlToolError(SqltoolRB.read_toobig.getString(), re);
+        }
+
+        int bytesread = 0;
+        int retval;
+        InputStream is = null;
+
+        try {
+            is = new FileInputStream(dsvFile);
+            while (bytesread < bfr.length &&
+                    (retval = is.read(bfr, bytesread, bfr.length - bytesread))
+                    > 0) {
+                bytesread += retval;
+            }
+
+        } catch (IOException ioe) {
+            throw new SqlToolError(ioe);
+        } finally {
+            if (is != null) try {
+                is.close();
+            } catch (IOException ioe) {
+                errprintln(
+                        SqltoolRB.inputfile_closefail.getString() + ": " + ioe);
+            } finally {
+                is = null;  // Encourage GC of buffers
+            }
+        }
+        if (bytesread != bfr.length) {
+            throw new SqlToolError(SqltoolRB.read_partial.getString(
+                    bytesread, bfr.length));
+        }
+
+        String dateString;
+        String[] lines = null;
+
+        try {
+            String string = new String(bfr, (shared.encoding == null)
+                    ? DEFAULT_FILE_ENCODING : shared.encoding);
+            lines = string.split(dsvRowSplitter, -1);
+        } catch (UnsupportedEncodingException uee) {
+            throw new SqlToolError(uee);
+        } catch (RuntimeException re) {
+            throw new SqlToolError(SqltoolRB.read_convertfail.getString(), re);
+        }
+
+        List<String> headerList = new ArrayList<String>();
+        String    tableName = dsvTargetTable;
+
+        // First read one until we get one header line
+        int lineCount = 0;
+        String trimmedLine = null;
+        boolean switching = false;
+        int headerOffset = 0;  //  Used to offset read-start of header record
+        String curLine = "dummy"; // Val will be replaced 4 lines down
+                                  // This is just to quiet compiler warning
+
+        while (true) {
+            if (lineCount >= lines.length)
+                throw new SqlToolError(SqltoolRB.dsv_header_none.getString());
+            curLine = lines[lineCount++];
+            trimmedLine = curLine.trim();
+            if (trimmedLine.length() < 1
+                    || (skipPrefix != null
+                            && trimmedLine.startsWith(skipPrefix))) {
+                continue;
+            }
+            if (trimmedLine.startsWith("targettable=")) {
+                if (tableName == null) {
+                    tableName = trimmedLine.substring(
+                            "targettable=".length()).trim();
+                }
+                continue;
+            }
+            if (trimmedLine.equals("headerswitch{")) {
+                if (tableName == null) {
+                    throw new SqlToolError(
+                            SqltoolRB.dsv_header_noswitchtarg.getString(
+                            lineCount));
+                }
+                switching = true;
+                continue;
+            }
+            if (trimmedLine.equals("}")) {
+                throw new SqlToolError(
+                        SqltoolRB.dsv_header_noswitchmatch.getString(lineCount));
+            }
+            if (!switching) {
+                break;
+            }
+            int colonAt = trimmedLine.indexOf(':');
+            if (colonAt < 1 || colonAt == trimmedLine.length() - 1) {
+                throw new SqlToolError(
+                        SqltoolRB.dsv_header_nonswitched.getString(lineCount));
+            }
+            String headerName = trimmedLine.substring(0, colonAt).trim();
+            // Need to be sure here that tableName is not null (in
+            // which case it would be determined later on by the file name).
+            if (headerName.equals("*")
+                    || headerName.equalsIgnoreCase(tableName)){
+                headerOffset = 1 + curLine.indexOf(':');
+                break;
+            }
+            // Skip non-matched header line
+        }
+
+        String headerLine = curLine.substring(headerOffset);
+        String colName;
+        String[] cols = headerLine.split(dsvColSplitter, -1);
+
+        for (String col : cols) {
+            if (col.length() < 1) {
+                throw new SqlToolError(SqltoolRB.dsv_nocolheader.getString(
+                        headerList.size() + 1, lineCount));
+            }
+
+            colName = col.trim().toLowerCase();
+            headerList.add(
+                (colName.equals("-")
+                        || (skipCols != null
+                                && skipCols.remove(colName))
+                        || (constColMap != null
+                                && constColMap.containsKey(colName))
+                )
+                ? ((String) null)
+                : colName);
+        }
+        if (skipCols != null && skipCols.size() > 0) {
+            throw new SqlToolError(SqltoolRB.dsv_skipcols_missing.getString(
+                    skipCols.toString()));
+        }
+
+        boolean oneCol = false;  // At least 1 non-null column
+        for (String header : headerList) {
+            if (header != null) {
+                oneCol = true;
+                break;
+            }
+        }
+        if (oneCol == false) {
+            // Difficult call, but I think in any real-world situation, the
+            // user will want to know if they are inserting records with no
+            // data from their input file.
+            throw new SqlToolError(
+                    SqltoolRB.dsv_nocolsleft.getString(dsvSkipCols));
+        }
+
+        int inputColHeadCount = headerList.size();
+
+        if (constColMap != null) {
+            headerList.addAll(constColMap.keySet());
+        }
+
+        String[]  headers   = headerList.toArray(new String[0]);
+        // headers contains input headers + all constCols, some of these
+        // values may be nulls.
+
+        if (tableName == null) {
+            tableName = dsvFile.getName();
+
+            int i = tableName.lastIndexOf('.');
+
+            if (i > 0) {
+                tableName = tableName.substring(0, i);
+            }
+        }
+
+        StringBuffer tmpSb = new StringBuffer();
+        List<String> tmpList = new ArrayList<String>();
+
+        int skippers = 0;
+        for (String header : headers) {
+            if (header == null) {
+                skippers++;
+                continue;
+            }
+            if (tmpSb.length() > 0) {
+                tmpSb.append(", ");
+            }
+
+            tmpSb.append(header);
+            tmpList.add(header);
+        }
+        boolean[] autonulls = new boolean[headers.length - skippers];
+        boolean[] parseDate = new boolean[autonulls.length];
+        boolean[] parseBool = new boolean[autonulls.length];
+        char[] readFormat = new char[autonulls.length];
+        String[] insertFieldName = tmpList.toArray(new String[] {});
+        // Remember that the headers array has all columns in DSV file,
+        // even skipped columns.
+        // The autonulls array only has columns that we will insert into.
+
+        StringBuffer sb = new StringBuffer("INSERT INTO " + tableName + " ("
+                                           + tmpSb + ") VALUES (");
+        StringBuffer typeQuerySb = new StringBuffer("SELECT " + tmpSb
+            + " FROM " + tableName + " WHERE 1 = 2");
+
+        try {
+            ResultSetMetaData rsmd =
+                    shared.jdbcConn.createStatement().executeQuery(
+                    typeQuerySb.toString()).getMetaData();
+
+            if (rsmd.getColumnCount() != autonulls.length) {
+                throw new SqlToolError(
+                        SqltoolRB.dsv_metadata_mismatch.getString());
+                // Don't know if it's possible to get here.
+                // If so, it's probably a SqlTool problem, not a user or
+                // data problem.
+                // Should be researched and either return a user-friendly
+                // message or a RuntimeExceptin.
+            }
+
+            for (int i = 0; i < autonulls.length; i++) {
+                autonulls[i] = true;
+                parseDate[i] = false;
+                parseBool[i] = false;
+                readFormat[i] = 's'; // regular Strings
+                switch(rsmd.getColumnType(i + 1)) {
+                    case java.sql.Types.BIT :
+                        autonulls[i] = true;
+                        readFormat[i] = 'b';
+                        break;
+                    case java.sql.Types.LONGVARBINARY :
+                    case java.sql.Types.VARBINARY :
+                    case java.sql.Types.BINARY :
+                        autonulls[i] = true;
+                        readFormat[i] = 'x';
+                        break;
+                    case java.sql.Types.BOOLEAN:
+                        parseBool[i] = true;
+                        break;
+                    case java.sql.Types.ARRAY :
+                        autonulls[i] = true;
+                        readFormat[i] = 'a';
+                        break;
+                    case java.sql.Types.VARCHAR :
+                    case java.sql.Types.BLOB :
+                    case java.sql.Types.CLOB :
+                    case java.sql.Types.LONGVARCHAR :
+                        autonulls[i] = false;
+                        // This means to preserve white space and to insert
+                        // "" for "".  Otherwise we trim white space and
+                        // insert null for \s*.
+                        break;
+                    case java.sql.Types.DATE:
+                    case java.sql.Types.TIME:
+                    case java.sql.Types.TIMESTAMP:
+                    case org.hsqldb.types.Types.SQL_TIMESTAMP_WITH_TIME_ZONE:
+                    case org.hsqldb.types.Types.SQL_TIME_WITH_TIME_ZONE:
+                        parseDate[i] = true;
+                }
+            }
+        } catch (SQLException se) {
+            throw new SqlToolError(SqltoolRB.query_metadatafail.getString(
+                    typeQuerySb.toString()), se);
+        }
+
+        for (int i = 0; i < autonulls.length; i++) {
+            if (i > 0) {
+                sb.append(", ");
+            }
+
+            sb.append('?');
+        }
+
+        // Initialize REJECT file(s)
+        int rejectCount = 0;
+        File rejectFile = null;
+        File rejectReportFile = null;
+        PrintWriter rejectWriter = null;
+        PrintWriter rejectReportWriter = null;
+        try {
+        if (dsvRejectFile != null) try {
+            rejectFile = new File(dsvRejectFile);
+            rejectWriter = new PrintWriter(
+                    new OutputStreamWriter(new FileOutputStream(rejectFile),
+                    (shared.encoding == null)
+                    ? DEFAULT_FILE_ENCODING : shared.encoding));
+            rejectWriter.print(headerLine + dsvRowDelim);
+        } catch (IOException ioe) {
+            throw new SqlToolError(SqltoolRB.dsv_rejectfile_setupfail.getString(
+                    dsvRejectFile), ioe);
+        }
+        if (dsvRejectReport != null) try {
+            rejectReportFile = new File(dsvRejectReport);
+            rejectReportWriter = new PrintWriter(new OutputStreamWriter(
+                    new FileOutputStream(rejectReportFile),
+                    (shared.encoding == null)
+                    ? DEFAULT_FILE_ENCODING : shared.encoding));
+            rejectReportWriter.println(SqltoolRB.rejectreport_top.getString(
+                    (new java.util.Date()).toString(),
+                    dsvFile.getPath(),
+                    ((rejectFile == null) ? SqltoolRB.none.getString()
+                                    : rejectFile.getPath()),
+                    ((rejectFile == null) ? null : rejectFile.getPath())));
+        } catch (IOException ioe) {
+            throw new SqlToolError(
+                    SqltoolRB.dsv_rejectreport_setupfail.getString(
+                    dsvRejectReport), ioe);
+        }
+
+        int recCount = 0;
+        int skipCount = 0;
+        PreparedStatement ps = null;
+        boolean importAborted = false;
+        boolean doResetAutocommit = false;
+        try {
+            doResetAutocommit = dsvRecordsPerCommit > 0
+                && shared.jdbcConn.getAutoCommit();
+            if (doResetAutocommit) shared.jdbcConn.setAutoCommit(false);
+        } catch (SQLException se) {
+            throw new SqlToolError(
+                    SqltoolRB.rpc_autocommit_failure.getString(), se);
+        }
+        // We're now assured that if dsvRecordsPerCommit is > 0, then
+        // autocommit is off.
+
+        try {
+            try {
+                ps = shared.jdbcConn.prepareStatement(sb.toString() + ')');
+            } catch (SQLException se) {
+                throw new SqlToolError(SqltoolRB.insertion_preparefail.getString(
+                        sb.toString()), se);
+            }
+            String[] dataVals = new String[autonulls.length];
+            // Length is number of cols to insert INTO, not nec. # in DSV file.
+            int      readColCount;
+            int      storeColCount;
+            Matcher  arMatcher;
+            String   currentFieldName = null;
+            String[] arVals;
+
+            // Insert data rows 1-row-at-a-time
+            while (lineCount < lines.length) try { try {
+                curLine = lines[lineCount++];
+                trimmedLine = curLine.trim();
+                if (trimmedLine.length() < 1) {
+                    continue;  // Silently skip blank lines
+                }
+                if (skipPrefix != null
+                        && trimmedLine.startsWith(skipPrefix)) {
+                    skipCount++;
+                    continue;
+                }
+                if (switching) {
+                    if (trimmedLine.equals("}")) {
+                        switching = false;
+                        continue;
+                    }
+                    int colonAt = trimmedLine.indexOf(':');
+                    if (colonAt < 1 || colonAt == trimmedLine.length() - 1) {
+                        throw new SqlToolError(SqltoolRB.dsv_header_matchernonhead.getString(
+                                        lineCount));
+                    }
+                    continue;
+                }
+                // Finished using "trimmed" line now.  Whitespace is
+                // meaningful hereafter.
+
+                // Finally we will attempt to add a record!
+                recCount++;
+                // Remember that recCount counts both inserts + rejects
+
+                readColCount = 0;
+                storeColCount = 0;
+                cols = curLine.split(dsvColSplitter, -1);
+
+                for (String col : cols) {
+                    if (readColCount == inputColHeadCount) {
+                        throw new RowError(SqltoolRB.dsv_colcount_mismatch.getString(
+                                inputColHeadCount, 1 + readColCount));
+                    }
+
+                    if (headers[readColCount++] != null) {
+                        dataVals[storeColCount++] = dsvTrimAll ? col.trim() : col;
+                    }
+                }
+                if (readColCount < inputColHeadCount) {
+                    throw new RowError(SqltoolRB.dsv_colcount_mismatch.getString(
+                            inputColHeadCount, readColCount));
+                }
+                /* Already checked for readColCount too high in prev. block */
+
+                if (constColMap != null) {
+                    for (String val : constColMap.values()) {
+                        dataVals[storeColCount++] = val;
+                    }
+                }
+                if (storeColCount != dataVals.length) {
+                    throw new RowError(SqltoolRB.dsv_insertcol_mismatch.getString(
+                            dataVals.length, storeColCount));
+                }
+
+                for (int i = 0; i < dataVals.length; i++) {
+                    currentFieldName = insertFieldName[i];
+                    if (autonulls[i]) dataVals[i] = dataVals[i].trim();
+                    // N.b. WE SPECIFICALLY DO NOT HANDLE TIMES WITHOUT
+                    // DATES, LIKE "3:14:00", BECAUSE, WHILE THIS MAY BE
+                    // USEFUL AND EFFICIENT, IT IS NOT PORTABLE.
+                    //System.err.println("ps.setString(" + i + ", "
+                    //      + dataVals[i] + ')');
+
+                    if (parseDate[i]) {
+                        if ((dataVals[i].length() < 1 && autonulls[i])
+                              || dataVals[i].equals(nullRepToken)) {
+                            ps.setTimestamp(i + 1, null);
+                        } else {
+                            dateString = (dataVals[i].indexOf(':') > 0)
+                                       ? dataVals[i]
+                                       : (dataVals[i] + " 0:00:00");
+                            // BEWARE:  This may not work for some foreign
+                            // date/time formats.
+                            try {
+                                ps.setTimestamp(i + 1,
+                                        java.sql.Timestamp.valueOf(dateString));
+                            } catch (IllegalArgumentException iae) {
+                                throw new RowError(SqltoolRB.time_bad.getString(
+                                        dateString), iae);
+                            }
+                        }
+                    } else if (parseBool[i]) {
+                        if ((dataVals[i].length() < 1 && autonulls[i])
+                              || dataVals[i].equals(nullRepToken)) {
+                            ps.setNull(i + 1, java.sql.Types.BOOLEAN);
+                        } else {
+                            try {
+                                ps.setBoolean(i + 1,
+                                        Boolean.parseBoolean(dataVals[i]));
+                                // Boolean... is equivalent to Java 4's
+                                // Boolean.parseBoolean().
+                            } catch (IllegalArgumentException iae) {
+                                throw new RowError(SqltoolRB.boolean_bad.getString(
+                                        dataVals[i]), iae);
+                            }
+                        }
+                    } else {
+                        switch (readFormat[i]) {
+                            case 'b':
+                                ps.setBytes(
+                                    i + 1,
+                                    (dataVals[i].length() < 1) ? null
+                                    : SqlFile.bitCharsToBytes(
+                                        dataVals[i]));
+                                break;
+                            case 'x':
+                                ps.setBytes(
+                                    i + 1,
+                                    (dataVals[i].length() < 1) ? null
+                                    : SqlFile.hexCharOctetsToBytes(
+                                        dataVals[i]));
+                                break;
+                            case 'a' :
+                                if (SqlFile.createArrayOfMethod == null) {
+                                    throw new SqlToolError(
+                                            //SqltoolRB.boolean_bad.getString(
+                                        "SqlTool requires += Java 1.6 at "
+                                        + "runtime in order to import Array "
+                                        + "values");
+                                }
+                                if (dataVals[i].length() < 1) {
+                                    ps.setArray(i + 1, null);
+                                    break;
+                                }
+                                arMatcher = arrayPattern.matcher(dataVals[i]);
+                                if (!arMatcher.matches()) {
+                                    throw new RowError(
+                                            //SqltoolRB.boolean_bad.getString(
+                                        "Malformatted ARRAY value: ("
+                                        + dataVals[i] + ')');
+                                }
+                                arVals = (arMatcher.group(1) == null)
+                                       ? (new String[0])
+                                       : arMatcher.group(1).split("\\s*,\\s*");
+                                // N.b. THIS DOES NOT HANDLE commas WITHIN
+                                // Array ELEMENT VALUES.
+                                try {
+                                    ps.setArray(i + 1, (java.sql.Array)
+                                            SqlFile.createArrayOfMethod.invoke(
+                                            shared.jdbcConn,
+                                            "VARCHAR", arVals));
+                                } catch (IllegalAccessException iae) {
+                                    throw new RuntimeException(iae);
+                                } catch (InvocationTargetException ite) {
+                                    if (ite.getCause() != null
+                                            &&  ite.getCause()
+                                            instanceof AbstractMethodError) {
+                                        throw new SqlToolError(
+                                            //SqltoolRB.boolean_bad.getString(
+                                            "SqlTool binary is not "
+                                            + "Array-compatible with your "
+                                            + "runtime JRE.  Array imports "
+                                            + "not possible.");
+                                    }
+                                    throw new RuntimeException(ite);
+                                }
+                                // createArrayOf method is Java-6-specific!
+                                break;
+                            default:
+                                ps.setString(
+                                    i + 1,
+                                    (((dataVals[i].length() < 1 && autonulls[i])
+                                      || dataVals[i].equals(nullRepToken))
+                                     ? null
+                                     : dataVals[i]));
+                        }
+                    }
+                    currentFieldName = null;
+                }
+
+                retval = ps.executeUpdate();
+
+                if (retval != 1) {
+                    throw new RowError(
+                            SqltoolRB.inputrec_modified.getString(retval));
+                }
+
+                if (dsvRecordsPerCommit > 0
+                    && (recCount - rejectCount) % dsvRecordsPerCommit == 0) {
+                    shared.jdbcConn.commit();
+                    shared.possiblyUncommitteds = false;
+                } else {
+                    shared.possiblyUncommitteds = true;
+                }
+            } catch (NumberFormatException nfe) {
+                throw new RowError(null, nfe);
+            } catch (SQLException se) {
+                throw new RowError(null, se);
+            } } catch (RowError re) {
+                rejectCount++;
+                if (rejectWriter != null || rejectReportWriter != null) {
+                    if (rejectWriter != null) {
+                        rejectWriter.print(curLine + dsvRowDelim);
+                    }
+                    if (rejectReportWriter != null) {
+                        genRejectReportRecord(rejectReportWriter,
+                                rejectCount, lineCount,
+                                currentFieldName, re.getMessage(),
+                                re.getCause());
+                    }
+                } else {
+                    importAborted = true;
+                    throw new SqlToolError(
+                            SqltoolRB.dsv_recin_fail.getString(
+                                    lineCount, currentFieldName)
+                            + ((re.getMessage() == null)
+                                    ? "" : ("  " + re.getMessage())),
+                            re.getCause());
+                }
+            }
+        } finally {
+            if (ps != null) try {
+                ps.close();
+            } catch (SQLException se) {
+                // We already got what we want from it, or have/are
+                // processing a more specific error.
+            } finally {
+                ps = null;  // Encourage GC of buffers
+            }
+            try {
+                if (dsvRecordsPerCommit > 0
+                    && (recCount - rejectCount) % dsvRecordsPerCommit != 0) {
+                    // To be consistent, if *DSV_RECORDS_PER_COMMIT is set, we
+                    // always commit all inserted records.
+                    // This little block commits any straggler commits since the
+                    // last commit.
+                    shared.jdbcConn.commit();
+                    shared.possiblyUncommitteds = false;
+                }
+                if (doResetAutocommit) shared.jdbcConn.setAutoCommit(true);
+            } catch (SQLException se) {
+                throw new SqlToolError(
+                        SqltoolRB.rpc_commit_failure.getString(), se);
+            }
+            String summaryString = null;
+            if (recCount > 0) {
+                summaryString = SqltoolRB.dsv_import_summary.getString(
+                        ((skipPrefix == null)
+                                  ? "" : ("'" + skipPrefix + "'-")),
+                        Integer.toString(skipCount),
+                        Integer.toString(rejectCount),
+                        Integer.toString(recCount - rejectCount),
+                        (importAborted ? "importAborted" : null));
+                stdprintln(summaryString);
+            }
+            try {
+                if (recCount > rejectCount && dsvRecordsPerCommit < 1
+                        && !shared.jdbcConn.getAutoCommit()) {
+                    stdprintln(SqltoolRB.insertions_notcommitted.getString());
+                }
+            } catch (SQLException se) {
+                stdprintln(SqltoolRB.autocommit_fetchfail.getString());
+                stdprintln(SqltoolRB.insertions_notcommitted.getString());
+                // No reason to throw here.  If user attempts to use the
+                // connection for anything significant, we will throw then.
+            }
+            if (rejectWriter != null) {
+                rejectWriter.flush();
+            }
+            if (rejectReportWriter != null && rejectCount > 0) {
+                rejectReportWriter.println(SqltoolRB.rejectreport_bottom.getString(
+                        summaryString, revnum));
+                rejectReportWriter.flush();
+            }
+            if (rejectCount == 0) {
+                if (rejectFile != null && rejectFile.exists()
+                        && !rejectFile.delete())
+                    errprintln(SqltoolRB.dsv_rejectfile_purgefail.getString(
+                            rejectFile.toString()));
+                if (rejectReportFile != null && !rejectReportFile.delete())
+                    errprintln(SqltoolRB.dsv_rejectreport_purgefail.getString(
+                            (rejectFile == null)
+                                    ? null : rejectFile.toString()));
+                // These are trivial errors.
+            }
+        }
+        } finally {
+            if (rejectWriter != null) {
+                try {
+                    rejectWriter.close();
+                } finally {
+                    rejectWriter = null;  // Encourage GC of buffers
+                }
+            }
+            if (rejectReportWriter != null) {
+                try {
+                    rejectReportWriter.close();
+                } finally {
+                    rejectReportWriter = null;  // Encourage GC of buffers
+                }
+            }
+        }
+    }
+
+    protected static void appendLine(StringBuffer sb, String s) {
+        sb.append(s + LS);
+    }
+
+    /**
+     * Does a poor-man's parse of a MSDOS command line and parses it
+     * into a WIndows cmd.exe invocation to approximate.
+     */
+    private static String[] genWinArgs(String monolithic) {
+        List<String> list = new ArrayList<String>();
+        list.add("cmd.exe");
+        list.add("/y");
+        list.add("/c");
+        Matcher m = wincmdPattern.matcher(monolithic);
+        while (m.find()) {
+            for (int i = 1; i <= m.groupCount(); i++) {
+                if (m.group(i) == null) continue;
+                if (m.group(i).length() > 1 && m.group(i).charAt(0) == '"') {
+                    list.add(m.group(i).substring(1, m.group(i).length() - 1));
+                    continue;
+                }
+                list.addAll(Arrays.asList(m.group(i).split("\\s+", -1)));
+            }
+        }
+        return list.toArray(new String[] {});
+    }
+
+    private void genRejectReportRecord(PrintWriter pw, int rCount,
+            int lCount, String field, String eMsg, Throwable cause) {
+        pw.println(SqltoolRB.rejectreport_row.getString(
+                ((rCount % 2 == 0) ? "even" : "odd") + "row",
+                Integer.toString(rCount),
+                Integer.toString(lCount),
+                ((field == null) ? "&nbsp;" : field),
+                (((eMsg == null) ? "" : eMsg)
+                        + ((eMsg == null || cause == null) ? "" : "<HR/>")
+                        + ((cause == null) ? "" : (
+                                (cause instanceof SQLException
+                                        && cause.getMessage() != null)
+                                    ? cause.getMessage()
+                                    : cause.toString()
+                                )
+                        )
+                )));
+    }
+
+    /**
+     * Parses input into command tokens, but does not perform the commands
+     * (unless you consider parsing blocks of nested commands to be
+     * "performing" a command).
+     *
+     * Throws only if I/O error or EOF encountered before end of entire file
+     * (encountered at any level of recursion).
+     *
+     * Exceptions thrown within this method percolate right up to the
+     * external call (in scanpass), regardless of ContinueOnErr setting.
+     * This is because it's impossible to know when to terminate blocks
+     * if there is a parsing error.
+     * Only a separate SqlFile invocation (incl. \i command) will cause
+     * a seekTokenSource exception to be handled at a level other than
+     * the very top.
+     */
+    private TokenList seekTokenSource(String nestingCommand)
+            throws BadSpecial, IOException {
+        Token token;
+        TokenList newTS = new TokenList();
+        Pattern endPattern = Pattern.compile("end\\s+" + nestingCommand);
+        String subNestingCommand;
+
+        while ((token = scanner.yylex()) != null) {
+            if (token.type == Token.PL_TYPE
+                    && endPattern.matcher(token.val).matches()) {
+                return newTS;
+            }
+            subNestingCommand = nestingCommand(token);
+            if (subNestingCommand != null) {
+                token.nestedBlock = seekTokenSource(subNestingCommand);
+            }
+            newTS.add(token);
+        }
+        throw new BadSpecial(
+                SqltoolRB.pl_block_unterminated.getString(nestingCommand));
+    }
+
+    /**
+     * We want leading space to be trimmed.
+     * Leading space should probably not be trimmed, but it is trimmed now
+     * (by the Scanner).
+     */
+    private void processMacro(Token defToken) throws BadSpecial {
+        Matcher matcher;
+        Token macroToken;
+
+        if (defToken.val.length() < 1) {
+            throw new BadSpecial(SqltoolRB.macro_tip.getString());
+        }
+        switch (defToken.val.charAt(0)) {
+            case '?':
+                stdprintln(SqltoolRB.macro_help.getString());
+                break;
+            case '=':
+                String defString = defToken.val;
+                defString = defString.substring(1).trim();
+                if (defString.length() < 1) {
+                    for (Map.Entry<String, Token> entry
+                            : shared.macros.entrySet()) {
+                        stdprintln(entry.getKey() + " = "
+                                + entry.getValue().reconstitute());
+                    }
+                    break;
+                }
+
+                int newType = -1;
+                StringBuffer newVal = new StringBuffer();
+                matcher = editMacroPattern.matcher(defString);
+                if (matcher.matches()) {
+                    if (buffer == null) {
+                        stdprintln(nobufferYetString);
+                        return;
+                    }
+                    newVal.append(buffer.val);
+                    if (matcher.groupCount() > 1 && matcher.group(2) != null
+                            && matcher.group(2).length() > 0)
+                        newVal.append(matcher.group(2));
+                    newType = buffer.type;
+                } else {
+                    matcher = spMacroPattern.matcher(defString);
+                    if (matcher.matches()) {
+                        newVal.append(matcher.group(3));
+                        newType = (matcher.group(2).equals("*")
+                                ?  Token.PL_TYPE : Token.SPECIAL_TYPE);
+                    } else {
+                        matcher = sqlMacroPattern.matcher(defString);
+                        if (!matcher.matches())
+                            throw new BadSpecial(
+                                    SqltoolRB.macro_malformat.getString());
+                        newVal.append(matcher.group(2));
+                        newType = Token.SQL_TYPE;
+                    }
+                }
+                if (newVal.length() < 1)
+                    throw new BadSpecial(SqltoolRB.macrodef_empty.getString());
+                if (newVal.charAt(newVal.length() - 1) == ';')
+                    throw new BadSpecial(SqltoolRB.macrodef_semi.getString());
+                shared.macros.put(matcher.group(1),
+                        new Token(newType, newVal, defToken.line));
+                break;
+            default:
+                matcher = useMacroPattern.matcher(defToken.val);
+                if (!matcher.matches())
+                    throw new BadSpecial(SqltoolRB.macro_malformat.getString());
+                macroToken = shared.macros.get(matcher.group(1));
+                if (macroToken == null)
+                    throw new BadSpecial(SqltoolRB.macro_undefined.getString(
+                            matcher.group(1)));
+                setBuf(macroToken);
+                buffer.line = defToken.line;
+                if (matcher.groupCount() > 1 && matcher.group(2) != null
+                        && matcher.group(2).length() > 0)
+                    buffer.val += matcher.group(2);
+                preempt = matcher.group(matcher.groupCount()).equals(";");
+        }
+    }
+
+    /**
+     * Convert a String to a byte array by interpreting every 2 characters as
+     * an octal byte value.
+     */
+    public static byte[] hexCharOctetsToBytes(String hexChars) {
+        int chars = hexChars.length();
+        if (chars != (chars / 2) * 2) {
+            throw new NumberFormatException("Hex character lists contains "
+                + "an odd number of characters: " + chars);
+        }
+        byte[] ba = new byte[chars/2];
+        int offset = 0;
+        char c;
+        int octet;
+        for (int i = 0; i < chars; i++) {
+            octet = 0;
+            c = hexChars.charAt(i);
+            if (c >= 'a' && c <= 'f') {
+                octet += 10 + c - 'a';
+            } else if (c >= 'A' && c <= 'F') {
+                octet += 10 + c - 'A';
+            } else if (c >= '0' && c <= '9') {
+                octet += c - '0';
+            } else {
+                throw new NumberFormatException(
+                    "Non-hex character in input at offset " + i + ": " + c);
+            }
+            octet = octet << 4;
+            c = hexChars.charAt(++i);
+            if (c >= 'a' && c <= 'f') {
+                octet += 10 + c - 'a';
+            } else if (c >= 'A' && c <= 'F') {
+                octet += 10 + c - 'A';
+            } else if (c >= '0' && c <= '9') {
+                octet += c - '0';
+            } else {
+                throw new NumberFormatException(
+                    "Non-hex character in input at offset " + i + ": " + c);
+            }
+
+            ba[offset++] = (byte) octet;
+        }
+        if (ba.length != offset) {
+            throw new RuntimeException(
+                    "Internal accounting problem.  Expected to fill buffer of "
+                    + "size "+ ba.length + ", but wrote only " + offset
+                    + " bytes");
+        }
+        return ba;
+    }
+
+    /**
+     * Just a stub for now.
+     */
+    public static byte[] bitCharsToBytes(String hexChars) {
+        if (hexChars == null) throw new NullPointerException();
+        // To shut up compiler warn
+        throw new NumberFormatException(
+                "Sorry.  Bit exporting not supported yet");
+    }
+
+    private void requireConnection() throws SqlToolError {
+        if (shared.jdbcConn == null)
+            throw new SqlToolError(SqltoolRB.no_required_conn.getString());
+    }
+
+    /**
+     * Returns a String report for the specified JDBC Connection.
+     *
+     * For databases with poor JDBC support, you won't get much detail.
+     */
+    public static String getBanner(Connection c) {
+        try {
+            DatabaseMetaData md = c.getMetaData();
+            return (md == null)
+                    ? null
+                    : SqltoolRB.jdbc_established.getString(
+                            md.getDatabaseProductName(),
+                            md.getDatabaseProductVersion(),
+                            md.getUserName(),
+                                    (c.isReadOnly() ? "R/O " : "R/W ")
+                                    + RCData.tiToString(
+                                    c.getTransactionIsolation()));
+        } catch (SQLException se) {
+            return null;
+        }
+    }
+
+    private void displayConnBanner() {
+        String msg = (shared.jdbcConn == null)
+                   ? SqltoolRB.disconnected_msg.getString()
+                   : SqlFile.getBanner(shared.jdbcConn);
+        stdprintln((msg == null)
+                  ? SqltoolRB.connected_fallbackmsg.getString()
+                  : msg);
+    }
+}
diff --git a/src/org/hsqldb/cmdline/SqlTool.java b/src/org/hsqldb/cmdline/SqlTool.java
new file mode 100644
index 0000000..7be6130
--- /dev/null
+++ b/src/org/hsqldb/cmdline/SqlTool.java
@@ -0,0 +1,693 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.cmdline;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import org.hsqldb.lib.FrameworkLogger;
+import org.hsqldb.lib.RCData;
+import org.hsqldb.cmdline.sqltool.Token;
+
+/* $Id: SqlTool.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/**
+ * A command-line JDBC SQL tool supporting both interactive and
+ * non-interactive usage.
+ * <P>
+ * See JavaDocs for the main method for syntax of how to run from the
+ * command-line.
+ * <P/> <P>
+ * Programmatic users will usually want to use the objectMain(String[]) method
+ * if they want arguments and behavior exactly like command-line SqlTool.
+ * But in many cases, you will have better control and efficiency by using
+ * the SqlFile class directly.  The file
+ * <CODE>src/org/hsqldb/sample/SqlFileEmbedder.java</CODE>
+ * in the HSQLDB distribution provides an example for this latter strategy.
+ * <P/>
+ *
+ * @see <a href="../../../../util-guide/sqltool-chapt.html" target="guide">
+ *     The SqlTool chapter of the
+ *     HyperSQL Utilities Guide</a>
+ * @see #main(String[])
+ * @see #objectMain(String[])
+ * @see SqlFile
+ * @see org.hsqldb.sample.SqlFileEmbedder
+ * @version $Revision: 3481 $, $Date: 2010-02-26 13:05:06 -0500 (Fri, 26 Feb 2010) $
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class SqlTool {
+    private static FrameworkLogger logger =
+            FrameworkLogger.getLog(SqlTool.class);
+    public static final String DEFAULT_RCFILE =
+        System.getProperty("user.home") + "/sqltool.rc";
+    // N.b. the following is static!
+    private static String  revnum =
+            "$Revision: 3481 $".substring("$Revision: ".length(),
+            "$Revision: 3481 $".length() - 2);
+
+    public static final int SQLTOOLERR_EXITVAL = 1;
+    public static final int SYNTAXERR_EXITVAL = 11;
+    public static final int RCERR_EXITVAL = 2;
+    public static final int SQLERR_EXITVAL = 3;
+    public static final int IOERR_EXITVAL = 4;
+    public static final int FILEERR_EXITVAL = 5;
+    public static final int INPUTERR_EXITVAL = 6;
+    public static final int CONNECTERR_EXITVAL = 7;
+
+    /**
+     * The configuration identifier to use when connection parameters are
+     * specified on the command line
+     */
+    private static String CMDLINE_ID = "cmdline";
+
+    /** Platform-specific line separator */
+    public static String LS = System.getProperty("line.separator");
+
+    /** Utility nested class for internal use. */
+    private static class BadCmdline extends Exception {
+        static final long serialVersionUID = -2134764796788108325L;
+        BadCmdline() {
+            // Purposefully empty
+        }
+    }
+
+    /** Utility object for internal use. */
+    private static BadCmdline bcl = new BadCmdline();
+
+    /** For trapping of exceptions inside this class.
+     * These are always handled inside this class.
+     */
+    private static class PrivateException extends Exception {
+        static final long serialVersionUID = -7765061479594523462L;
+
+        /* Unused at this time
+        PrivateException() {
+            super();
+        }
+        */
+
+        PrivateException(String s) {
+            super(s);
+        }
+    }
+
+    public static class SqlToolException extends Exception {
+        static final long serialVersionUID = 1424909871915188519L;
+
+        int exitValue = 1;
+        SqlToolException(String message, int exitValue) {
+            super(message);
+            this.exitValue = exitValue;
+        }
+        SqlToolException(int exitValue, String message) {
+            this(message, exitValue);
+        }
+        SqlToolException(int exitValue) {
+            super();
+            this.exitValue = exitValue;
+        }
+    }
+
+    /**
+     * Prompt the user for a password.
+     *
+     * @param username The user the password is for
+     * @return The password the user entered
+     */
+    private static String promptForPassword(String username)
+    throws PrivateException {
+
+        BufferedReader console;
+        String         password;
+
+        password = null;
+
+        try {
+            console = new BufferedReader(new InputStreamReader(System.in));
+
+            // Prompt for password
+            System.out.print(SqltoolRB.passwordFor_prompt.getString(
+                    RCData.expandSysPropVars(username)));
+
+            // Read the password from the command line
+            password = console.readLine();
+
+            if (password == null) {
+                password = "";
+            } else {
+                password = password.trim();
+            }
+        } catch (IOException e) {
+            throw new PrivateException(e.getMessage());
+        } finally {
+            console = null;  // Encourage GC of buffers
+        }
+
+        return password;
+    }
+
+    /**
+     * Parses a comma delimited string of name value pairs into a
+     * <code>Map</code> object.
+     *
+     * @param varString The string to parse
+     * @param varMap The map to save the paired values into
+     * @param lowerCaseKeys Set to <code>true</code> if the map keys should be
+     *        converted to lower case
+     */
+    private static void varParser(String varString, Map<String, String> varMap,
+                                  boolean lowerCaseKeys)
+                                  throws PrivateException {
+
+        int       equals;
+        String    var;
+        String    val;
+
+        if (varMap == null) {
+            throw new IllegalArgumentException(
+                    "varMap is null in SqlTool.varParser call");
+        }
+        if (varString == null) {
+            throw new IllegalArgumentException(
+                    "varString is null in SqlTool.varParser call");
+        }
+
+        for (String token : varString.split("\\s*,\\s*")) {
+            equals     = token.indexOf('=');
+
+            if (equals < 1) {
+                throw new PrivateException(
+                    SqltoolRB.SqlTool_varset_badformat.getString());
+            }
+
+            var = token.substring(0, equals).trim();
+            val = token.substring(equals + 1).trim();
+
+            if (var.length() < 1) {
+                throw new PrivateException(
+                    SqltoolRB.SqlTool_varset_badformat.getString());
+            }
+
+            if (lowerCaseKeys) {
+                var = var.toLowerCase();
+            }
+
+            varMap.put(var, val);
+        }
+    }
+
+    /**
+     * A static wrapper for objectMain, so that that method may be executed
+     * as a Java "program".
+     * <P>
+     * Throws only RuntimeExceptions or Errors, because this method is intended
+     * to System.exit() for all but disastrous system problems, for which
+     * the inconvenience of a stack trace would be the least of your worries.
+     * <P/> <P>
+     * If you don't want SqlTool to System.exit(), then use the method
+     * objectMain() instead of this method.
+     * <P/>
+     *
+     * @see #objectMain(String[])
+     */
+    public static void main(String[] args) {
+        try {
+            SqlTool.objectMain(args);
+        } catch (SqlToolException fr) {
+            System.err.println(
+                    (fr.getMessage() == null) ? fr : fr.getMessage());
+            System.exit(fr.exitValue);
+        }
+        System.exit(0);
+    }
+
+    /**
+     * Connect to a JDBC Database and execute the commands given on
+     * stdin or in SQL file(s).
+     * <P>
+     * This method is changed for HSQLDB 1.8.0.8 and later to never
+     * System.exit().
+     * Developers may catch Throwables to handle all fatal situations.
+     * </P>
+     *
+     * @param arg  Run "java... org.hsqldb.cmdline.SqlTool --help" for syntax.
+     * @throws SqlToolException  Upon any fatal error, with useful
+     *                          reason as the exception's message.
+     */
+    public static void objectMain(String[] arg) throws SqlToolException {
+        logger.finer("Invoking SqlTool");
+
+        /*
+         * The big picture is, we parse input args; load a RCData;
+         * get a JDBC Connection with the RCData; instantiate and
+         * execute as many SqlFiles as we need to.
+         */
+        String  rcFile           = null;
+        PipedReader  tmpReader   = null;
+        String  sqlText          = null;
+        String  driver           = null;
+        String  targetDb         = null;
+        String  varSettings      = null;
+        boolean debug            = false;
+        File[]  scriptFiles      = null;
+        int     i                = -1;
+        boolean listMode         = false;
+        boolean interactive      = false;
+        boolean noinput          = false;
+        boolean noautoFile       = false;
+        boolean autoCommit       = false;
+        Boolean coeOverride      = null;
+        Boolean stdinputOverride = null;
+        String  rcParams         = null;
+        String  rcUrl            = null;
+        String  rcUsername       = null;
+        String  rcPassword       = null;
+        String  rcCharset        = null;
+        String  rcTruststore     = null;
+        String  rcTransIso       = null;
+        Map<String, String> rcFields = null;
+        String  parameter;
+        SqlFile[] sqlFiles       = null;
+        Connection conn          = null;
+        Map<String, String> userVars = null;
+
+        try { // Try block to GC tmpReader
+        try { // Try block for BadCmdline
+            while ((i + 1 < arg.length) && arg[i + 1].startsWith("--")) {
+                i++;
+
+                if (arg[i].length() == 2) {
+                    break;             // "--"
+                }
+
+                parameter = arg[i].substring(2).toLowerCase();
+
+                if (parameter.equals("help")) {
+                    System.out.println(SqltoolRB.SqlTool_syntax.getString(
+                            revnum, RCData.DEFAULT_JDBC_DRIVER));
+                    return;
+                }
+                if (parameter.equals("abortonerr")) {
+                    if (coeOverride != null) {
+                        throw new SqlToolException(SYNTAXERR_EXITVAL,
+                                SqltoolRB.SqlTool_abort_continue_mutuallyexclusive.getString());
+                    }
+
+                    coeOverride = Boolean.FALSE;
+                } else if (parameter.equals("continueonerr")) {
+                    if (coeOverride != null) {
+                        throw new SqlToolException(SYNTAXERR_EXITVAL,
+                                SqltoolRB.SqlTool_abort_continue_mutuallyexclusive.getString());
+                    }
+
+                    coeOverride = Boolean.TRUE;
+                } else if (parameter.startsWith("continueonerr=")) {
+                    if (coeOverride != null) {
+                        throw new SqlToolException(SYNTAXERR_EXITVAL,
+                                SqltoolRB.SqlTool_abort_continue_mutuallyexclusive.getString());
+                    }
+
+                    coeOverride = Boolean.valueOf(
+                            arg[i].substring("--continueonerr=".length()));
+                } else if (parameter.equals("list")) {
+                    listMode = true;
+                } else if (parameter.equals("rcfile")) {
+                    if (++i == arg.length) {
+                        throw bcl;
+                    }
+
+                    rcFile = arg[i];
+                } else if (parameter.startsWith("rcfile=")) {
+                    rcFile = arg[i].substring("--rcfile=".length());
+                } else if (parameter.equals("setvar")) {
+                    if (++i == arg.length) {
+                        throw bcl;
+                    }
+
+                    varSettings = arg[i];
+                } else if (parameter.startsWith("setvar=")) {
+                    varSettings = arg[i].substring("--setvar=".length());
+                } else if (parameter.equals("sql")) {
+                    noinput = true;    // but turn back on if file "-" specd.
+
+                    if (++i == arg.length) {
+                        throw bcl;
+                    }
+
+                    sqlText = arg[i];
+                } else if (parameter.startsWith("sql=")) {
+                    noinput = true;    // but turn back on if file "-" specd.
+                    sqlText = arg[i].substring("--sql=".length());
+                } else if (parameter.equals("debug")) {
+                    debug = true;
+                } else if (parameter.equals("noautofile")) {
+                    noautoFile = true;
+                } else if (parameter.equals("autocommit")) {
+                    autoCommit = true;
+                } else if (parameter.equals("stdinput")) {
+                    noinput          = false;
+                    stdinputOverride = Boolean.TRUE;
+                } else if (parameter.equals("noinput")) {
+                    noinput          = true;
+                    stdinputOverride = Boolean.FALSE;
+                } else if (parameter.equals("driver")) {
+                    if (++i == arg.length) {
+                        throw bcl;
+                    }
+
+                    driver = arg[i];
+                } else if (parameter.startsWith("driver=")) {
+                    driver = arg[i].substring("--driver=".length());
+                } else if (parameter.equals("inlinerc")) {
+                    if (++i == arg.length) {
+                        throw bcl;
+                    }
+
+                    rcParams = arg[i];
+                } else if (parameter.startsWith("inlinerc=")) {
+                    rcParams = arg[i].substring("--inlinerc=".length());
+                } else {
+                    throw bcl;
+                }
+            }
+
+            if (!listMode && rcParams == null && ++i != arg.length) {
+                // If an inline RC file was specified, don't look for targetDb
+                targetDb = arg[i];
+                if (targetDb.equals("-")) targetDb = null;
+            }
+
+            int scriptIndex = 0;
+
+            if (sqlText != null) {
+                try {
+                    tmpReader = new PipedReader();
+                    PipedWriter tmpWriter = new PipedWriter(tmpReader);
+                    // My best guess is that the encoding here will be however
+                    // we read the SQL text from the command-line, which will
+                    // be the platform default encoding.  Therefore, don't
+                    // specify an encoding for this pipe.
+                    try {
+                        tmpWriter.write(sqlText + LS);
+                        tmpWriter.flush();
+                    } finally {
+                        try {
+                            tmpWriter.close();
+                        } finally {
+                            tmpWriter = null;  // Encourage GC of buffers
+                        }
+                    }
+                } catch (IOException ioe) {
+                    throw new SqlToolException(IOERR_EXITVAL,
+                            SqltoolRB.sqltempfile_fail.getString(
+                            ioe.toString()));
+                }
+            }
+
+            if (stdinputOverride != null) {
+                noinput = !stdinputOverride.booleanValue();
+            }
+
+            interactive = (!noinput) && (arg.length <= i + 1);
+
+            if (arg.length == i + 2 && arg[i + 1].equals("-")) {
+                if (stdinputOverride == null) {
+                    noinput = false;
+                }
+            } else if (arg.length > i + 1) {
+
+                // I.e., if there are any SQL files specified.
+                scriptFiles = new File[arg.length - i - 1
+                        + ((stdinputOverride == null
+                                ||!stdinputOverride.booleanValue()) ? 0 : 1)];
+
+                if (debug) {
+                    System.err.println("scriptFiles has "
+                                       + scriptFiles.length + " elements");
+                }
+
+                while (i + 1 < arg.length) {
+                    scriptFiles[scriptIndex++] = new File(arg[++i]);
+                }
+
+                if (stdinputOverride != null
+                        && stdinputOverride.booleanValue()) {
+                    scriptFiles[scriptIndex++] = null;
+                    noinput                    = true;
+                }
+            }
+        } catch (BadCmdline bcle) {
+            throw new SqlToolException(SYNTAXERR_EXITVAL,
+                    SqltoolRB.SqlTool_syntax.getString(
+                    revnum, RCData.DEFAULT_JDBC_DRIVER));
+        }
+
+        RCData conData = null;
+
+        // Use the inline RC file if it was specified
+        if (rcParams != null) {
+            rcFields = new HashMap<String, String>();
+
+            try {
+                varParser(rcParams, rcFields, true);
+            } catch (PrivateException e) {
+                throw new SqlToolException(SYNTAXERR_EXITVAL, e.getMessage());
+            }
+
+            rcUrl        = rcFields.remove("url");
+            rcUsername   = rcFields.remove("user");
+            rcCharset    = rcFields.remove("charset");
+            rcTruststore = rcFields.remove("truststore");
+            rcPassword   = rcFields.remove("password");
+            rcTransIso   = rcFields.remove("transiso");
+
+            // Don't ask for password if what we have already is invalid!
+            if (rcUrl == null || rcUrl.length() < 1)
+                throw new SqlToolException(RCERR_EXITVAL,
+                        SqltoolRB.rcdata_inlineurl_missing.getString());
+            // We now allow both null and "" user name, but we require password
+            // if the user name != null.
+            if (rcPassword != null && rcPassword.length() > 0)
+                throw new SqlToolException(RCERR_EXITVAL,
+                        SqltoolRB.rcdata_password_visible.getString());
+            if (rcFields.size() > 0) {
+                throw new SqlToolException(INPUTERR_EXITVAL,
+                        SqltoolRB.rcdata_inline_extravars.getString(
+                        rcFields.keySet().toString()));
+            }
+
+            if (rcUsername != null && rcPassword == null) try {
+                rcPassword   = promptForPassword(rcUsername);
+            } catch (PrivateException e) {
+                throw new SqlToolException(INPUTERR_EXITVAL,
+                        SqltoolRB.password_readfail.getString(e.getMessage()));
+            }
+            try {
+                conData = new RCData(CMDLINE_ID, rcUrl, rcUsername,
+                                     rcPassword, driver, rcCharset,
+                                     rcTruststore, null, rcTransIso);
+            } catch (RuntimeException re) {
+                throw re;  // Unrecoverable
+            } catch (Exception e) {
+                throw new SqlToolException(RCERR_EXITVAL,
+                        SqltoolRB.rcdata_genfromvalues_fail.getString());
+            }
+        } else if (listMode || targetDb != null) {
+            try {
+                conData = new RCData(new File((rcFile == null)
+                                              ? DEFAULT_RCFILE
+                                              : rcFile), targetDb);
+            } catch (RuntimeException re) {
+                throw re;  // Unrecoverable
+            } catch (Exception e) {
+                throw new SqlToolException(RCERR_EXITVAL,
+                        SqltoolRB.conndata_retrieval_fail.getString(
+                        targetDb, e.getMessage()));
+            }
+        }
+
+        //if (debug) {
+            //conData.report();
+        //}
+
+        if (listMode) {
+            // listMode has been handled above.
+            // Just returning here to prevent unexpected consequences if the
+            // user specifies both an inline RC (will will be ignored) and
+            // --list.
+            return;
+        }
+
+        if (interactive) System.out.print("SqlTool v. " + revnum + '.' + LS);
+
+        if (conData != null) try {
+            conn = conData.getConnection(
+                driver, System.getProperty("javax.net.ssl.trustStore"));
+
+            conn.setAutoCommit(autoCommit);
+
+            String conBanner;
+            if (interactive && (conBanner = SqlFile.getBanner(conn)) != null) {
+                System.out.println(conBanner);
+            }
+        } catch (RuntimeException re) {
+            throw re;  // Unrecoverable
+        } catch (Exception e) {
+            if (debug) logger.error(e.getClass().getName(), e);
+
+            // Let's not continue as if nothing is wrong.
+            String reportUser = (conData.username == null)
+                    ? "<DFLTUSER>" : conData.username;
+            throw new SqlToolException(CONNECTERR_EXITVAL,
+                    SqltoolRB.connection_fail.getString(conData.url,
+                    reportUser, e.getMessage()));
+        }
+
+        File[] emptyFileArray      = {};
+        File[] singleNullFileArray = { null };
+        File   autoFile            = null;
+
+        if (interactive &&!noautoFile) {
+            autoFile = new File(System.getProperty("user.home")
+                                + "/auto.sql");
+
+            if ((!autoFile.isFile()) ||!autoFile.canRead()) {
+                autoFile = null;
+            }
+        }
+
+        if (scriptFiles == null) {
+
+            // I.e., if no SQL files given on command-line.
+            // Input file list is either nothing or {null} to read stdin.
+            scriptFiles = (noinput ? emptyFileArray
+                                   : singleNullFileArray);
+        }
+
+        int numFiles = scriptFiles.length;
+
+        if (tmpReader != null) {
+            numFiles += 1;
+        }
+
+        if (autoFile != null) {
+            numFiles += 1;
+        }
+
+        sqlFiles = new SqlFile[numFiles];
+
+        if (varSettings != null) try {
+            userVars = new HashMap<String, String>();
+            varParser(varSettings, userVars, false);
+        } catch (PrivateException pe) {
+            throw new SqlToolException(RCERR_EXITVAL, pe.getMessage());
+        }
+
+        // We print version before execing this one.
+        int interactiveFileIndex = -1;
+        String encoding = (conData == null) ? null : conData.charset;
+
+        try {
+            int fileIndex = 0;
+
+            if (autoFile != null) {
+                sqlFiles[fileIndex++] = new SqlFile(autoFile, encoding);
+            }
+
+            if (tmpReader != null) {
+                sqlFiles[fileIndex++] =
+                    new SqlFile(tmpReader, "--sql", System.out, null, false);
+            }
+
+            for (File scriptFile : scriptFiles) {
+                if (interactiveFileIndex < 0 && interactive) {
+                    interactiveFileIndex = fileIndex;
+                }
+
+                sqlFiles[fileIndex++] = (scriptFile == null)
+                        ?  (new SqlFile(encoding, interactive))
+                        :  (new SqlFile(scriptFile,encoding, interactive));
+            }
+        } catch (IOException ioe) {
+            try {
+                if (conn != null) conn.close();
+            } catch (Exception e) {
+                // Can only report on so many errors at one time
+            }
+
+            throw new SqlToolException(FILEERR_EXITVAL, ioe.getMessage());
+        }
+        } finally {
+            // DO NOT close tmpReader, since SqlFile needs to read from it
+            // (and will auto-close it).
+            tmpReader = null;  // Encourage GC of buffers
+        }
+
+        Map<String, Token> macros = null;
+        try {
+            for (SqlFile sqlFile : sqlFiles) {
+                if (conn != null) sqlFile.setConnection(conn);
+                if (userVars != null) sqlFile.addUserVars(userVars);
+                if (macros != null) sqlFile.addMacros(macros);
+                if (coeOverride != null)
+                    sqlFile.setContinueOnError(coeOverride.booleanValue());
+
+                sqlFile.execute();
+                userVars = sqlFile.getUserVars();
+                macros = sqlFile.getMacros();
+                conn = sqlFile.getConnection();
+            }
+            // Following two Exception types are handled properly inside of
+            // SqlFile.  We just need to return an appropriate error status.
+        } catch (SqlToolError ste) {
+            throw new SqlToolException(SQLTOOLERR_EXITVAL);
+        } catch (SQLException se) {
+            // SqlTool will only throw an SQLException if it is in
+            // "\c false" mode.
+            throw new SqlToolException(SQLERR_EXITVAL);
+        } finally {
+            try {
+                if (conn != null) conn.close();
+            } catch (Exception e) {
+                // Purposefully doing nothing
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/cmdline/SqlToolError.java b/src/org/hsqldb/cmdline/SqlToolError.java
new file mode 100644
index 0000000..6828cc3
--- /dev/null
+++ b/src/org/hsqldb/cmdline/SqlToolError.java
@@ -0,0 +1,65 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.cmdline;
+
+import org.hsqldb.lib.AppendableException;
+
+/**
+ * Exceptions thrown by the SqlTool system externally to SqlFile.
+ * (As opposed to the nested Exceptions within those classes).
+ * This class is misnamed, because it is not only errors.
+ * When there is time, this file and class should be renamed.
+ * <P>
+ * This class has a misleading name and should really be renamed.
+ * It is Java Exception, not a Java Error.
+ * </P>
+ */
+public class SqlToolError extends AppendableException {
+
+    static final long serialVersionUID = 1792522673702223649L;
+
+    public SqlToolError(Throwable cause) {
+        super(null, cause);
+    }
+
+    public SqlToolError() {
+        // Purposefully empty
+    }
+
+    public SqlToolError(String s) {
+        super(s);
+    }
+
+    public SqlToolError(String string, Throwable cause) {
+        super(string, cause);
+    }
+}
diff --git a/src/org/hsqldb/cmdline/SqlToolSprayer.java b/src/org/hsqldb/cmdline/SqlToolSprayer.java
new file mode 100644
index 0000000..40cf3df
--- /dev/null
+++ b/src/org/hsqldb/cmdline/SqlToolSprayer.java
@@ -0,0 +1,179 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.cmdline;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+
+/* $Id: SqlToolSprayer.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/**
+ * Sql Tool Sprayer.
+ * Invokes SqlTool.objectMain() multiple times with the same SQL.
+ * Invokes for multiple urlids and/or retries.
+ *
+ * See JavaDocs for the main method for syntax of how to run.
+ *
+ * System properties used if set:
+ * <UL>
+ *      <LI>sqltoolsprayer.period (in ms.)</LI>
+ *      <LI>sqltoolsprayer.maxtime (in ms.)</LI>
+ *      <LI>sqltoolsprayer.rcfile (filepath)</LI>
+ * </UL>
+ *
+ * @see #main(String[])
+ * @version $Revision: 3481 $, $Date: 2010-02-26 13:05:06 -0500 (Fri, 26 Feb 2010) $
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class SqlToolSprayer {
+
+    public static String LS = System.getProperty("line.separator");
+    private static String SYNTAX_MSG =
+        "SYNTAX:  java [-D...] SqlToolSprayer 'SQL;' [urlid1 urlid2...]\n"
+        + "System properties you may use [default values]:\n"
+        + "    sqltoolsprayer.period (in ms.) [500]\n"
+        + "    sqltoolsprayer.maxtime (in ms.) [0]\n"
+        + "    sqltoolsprayer.monfile (filepath) [none]\n"
+        + "    sqltoolsprayer.rcfile (filepath) [none.  SqlTool default used.]";
+    static {
+        if (!LS.equals("\n")) {
+            SYNTAX_MSG = SYNTAX_MSG.replaceAll("\n", LS);
+        }
+    }
+
+    public static void main(String[] sa) {
+
+        if (sa.length < 1) {
+            System.err.println(SYNTAX_MSG);
+            System.exit(4);
+        }
+
+        long period = ((System.getProperty("sqltoolsprayer.period") == null)
+                       ? 500
+                       : Integer.parseInt(
+                           System.getProperty("sqltoolsprayer.period")));
+        long maxtime = ((System.getProperty("sqltoolsprayer.maxtime") == null)
+                        ? 0
+                        : Integer.parseInt(
+                            System.getProperty("sqltoolsprayer.maxtime")));
+        String rcFile   = System.getProperty("sqltoolsprayer.rcfile");
+        File monitorFile =
+            (System.getProperty("sqltoolsprayer.monfile") == null) ? null
+                                                                   : new File(
+                                                                       System.getProperty(
+                                                                           "sqltoolsprayer.monfile"));
+        ArrayList<String> urlids = new ArrayList<String>();
+
+        for (int i = 1; i < sa.length; i++) {
+            urlids.add(sa[i]);
+        }
+
+        if (urlids.size() < 1) {
+            System.err.println("No urlids specified.  Nothing to spray.");
+            System.exit(5);
+        }
+
+        boolean[] status = new boolean[urlids.size()];
+
+        String[] withRcArgs    = {
+            "--sql=" +  sa[0], "--rcfile=" + rcFile, null
+        };
+        String[] withoutRcArgs = {
+            "--sql=" + sa[0], null
+        };
+        String[] sqlToolArgs   = (rcFile == null) ? withoutRcArgs
+                                                  : withRcArgs;
+        boolean  onefailed     = false;
+        long     startTime     = (new Date()).getTime();
+
+        while (true) {
+            if (monitorFile != null && !monitorFile.exists()) {
+                System.err.println("Required file is gone:  " + monitorFile);
+                System.exit(2);
+            }
+
+            onefailed = false;
+
+            for (int i = 0; i < status.length; i++) {
+                if (status[i]) {
+                    continue;
+                }
+
+                sqlToolArgs[sqlToolArgs.length - 1] = urlids.get(i);
+                // System.err.println("ARGS:"
+                //      + java.util.Arrays.asList(sqlToolArgs));
+
+                try {
+                    SqlTool.objectMain(sqlToolArgs);
+
+                    status[i] = true;
+
+                    System.err.println("Success for instance '"
+                                       + urlids.get(i) + "'");
+                } catch (SqlTool.SqlToolException se) {
+                    onefailed = true;
+                }
+            }
+
+            if (!onefailed) {
+                break;
+            }
+
+            if (maxtime == 0 || (new Date()).getTime() > startTime + maxtime) {
+                break;
+            }
+
+            try {
+                Thread.sleep(period);
+            } catch (InterruptedException ie) {
+                // Purposefully doing nothing
+            }
+        }
+
+        ArrayList<String> failedUrlids = new ArrayList<String>();
+
+        // If all statuses true, then System.exit(0);
+        for (int i = 0; i < status.length; i++) {
+            if (status[i] != true) {
+                failedUrlids.add(urlids.get(i));
+            }
+        }
+
+        if (failedUrlids.size() > 0) {
+            System.err.println("Failed instances:   " + failedUrlids);
+            System.exit(1);
+        }
+
+        System.exit(0);
+    }
+}
diff --git a/src/org/hsqldb/cmdline/SqltoolRB.java b/src/org/hsqldb/cmdline/SqltoolRB.java
new file mode 100644
index 0000000..706eeec
--- /dev/null
+++ b/src/org/hsqldb/cmdline/SqltoolRB.java
@@ -0,0 +1,315 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.cmdline;
+
+import org.hsqldb.lib.ValidatingResourceBundle;
+import org.hsqldb.lib.RefCapableRBInterface;
+
+/* $Id: SqltoolRB.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/**
+ * Resource Bundle for SqlTool and associated classes.
+ *
+ * Purpose of this class is to wrap a RefCapablePropertyResourceBundle to
+ *  reliably detect any possible use of a missing property key as soon as
+ *  this class is clinitted.
+ * The reason for this is to allow us developers to detect all such errors
+ *  before end-users ever use this class.
+ * * IMPORTANT:  To add a new ResourceBundle element, add two new lines, one
+ * like <PRE>
+ *    static public final int NEWKEYID = keyCounter++;
+ * </PRE> and one line <PRE>
+ *      new Integer(KEY2), "key2",
+ * </PRE>
+ * Both should be inserted right after all of the other lines of the same type.
+ * NEWKEYID is obviously a new constant which you will use in calling code
+ * like SqltoolRB.NEWKEYID.
+ */
+public enum SqltoolRB implements RefCapableRBInterface {
+    SqlTool_syntax,
+    // SqlTool inline properties:
+    passwordFor_prompt,
+    SqlTool_varset_badformat,
+    SqlTool_abort_continue_mutuallyexclusive,
+    sqltempfile_fail,
+    rcdata_inlineurl_missing,
+    rcdata_inline_extravars,
+    rcdata_inlineusername_missing,
+    rcdata_password_visible,
+    password_readfail,
+    connection_fail,
+    rcdata_genfromvalues_fail,
+    conndata_retrieval_fail,
+    jdbc_established,
+
+    // SqlFile class, file references:
+    SqlFile_banner,
+    buffer_help,
+    special_help,
+    pl_help,
+    dsv_options,
+    d_options,
+    raw_leadin,
+    errorat,
+    rejectreport_top,
+    rejectreport_row,
+    rejectreport_bottom,
+    macro_help,
+
+    // SqlFile inline properties:
+    rawmode_prompt,
+    raw_movedtobuffer,
+    input_movedtobuffer,
+    sqlstatement_empty,
+    causereport,
+    break_unsatisfied,
+    continue_unsatisfied,
+    primaryinput_accessfail,
+    input_unterminated,
+    plvar_set_incomplete,
+    aborting,
+    rollingback,
+    special_unspecified,
+    bufhist_unspecified,
+    buffer_executing,
+    nobuffer_yet,
+    commandnum_malformat,
+    buffer_restored,
+    substitution_malformat,
+    substitution_nomatch,
+    substitution_syntax,
+    buffer_unknown,
+    special_extrachars,
+    buffer_extrachars,
+    special_malformat,
+    html_mode,
+    dsv_targetfile_demand,
+    file_wrotechars,
+    file_writefail,
+    special_d_like,
+    outputfile_nonetoclose,
+    outputfile_reopening,
+    outputfile_header,
+    destfile_demand,
+    buffer_empty,
+    file_appendfail,
+    sqlfile_name_demand,
+    sqlfile_execute_fail,
+    a_setting,
+    committed,
+    special_b_malformat,
+    binary_loadedbytesinto,
+    binary_filefail,
+    c_setting,
+    bang_incomplete,
+    bang_command_fail,
+    special_unknown,
+    dsv_m_syntax,
+    dsv_x_syntax,
+    raw_empty,
+    dsv_nocolsleft,
+    dsv_skipcols_missing,
+    plalias_malformat,
+    plvar_undefined,
+    sysprop_empty,
+    sysprop_unterminated,
+    sysprop_undefined,
+    var_infinite,
+    plvar_nameempty,
+    plvar_unterminated,
+    pl_malformat,
+    pl_expansionmode,
+    end_noblock,
+    continue_syntax,
+    break_syntax,
+    pl_list_parens,
+    pl_list_lengths,
+    dumpload_malformat,
+    plvar_nocolon,
+    plvar_tildedash_nomoreargs,
+    dumpload_fail,
+    prepare_malformat,
+    foreach_malformat,
+    pl_block_fail,
+    ifwhile_malformat,
+    if_malformat,
+    while_malformat,
+    pl_unknown,
+    pl_block_unterminated,
+    vendor_oracle_dS,
+    vendor_derby_dr,
+    vendor_nosup_d,
+    vendor_derby_du,
+    special_d_unknown,
+    metadata_fetch_fail,
+    metadata_fetch_failfor,
+    prepare_demandqm,
+    binbuffer_empty,
+    vendor_nosup_sysschemas,
+    noresult,
+    dsv_bincol,
+    binbuf_write,
+    rows_fetched,
+    rows_fetched_dsv,
+    row_update_singular,
+    row_update_multiple,
+    history_unavailable,
+    history_none,
+    editbuffer_contents,
+    buffer_instructions,
+    history_number_req,
+    history_backto,
+    history_upto,
+    history_back,
+    describe_table_name,
+    describe_table_datatype,
+    describe_table_width,
+    describe_table_nonulls,
+    logical_unrecognized,
+    read_toobig,
+    read_partial,
+    read_convertfail,
+    dsv_coldelim_present,
+    dsv_rowdelim_present,
+    dsv_nullrep_present,
+    dsv_constcols_nullcol,
+    file_readfail,
+    inputfile_closefail,
+    dsv_header_none,
+    dsv_header_noswitchtarg,
+    dsv_header_noswitchmatch,
+    dsv_header_nonswitched,
+    dsv_nocolheader,
+    dsv_metadata_mismatch,
+    query_metadatafail,
+    dsv_rejectfile_setupfail,
+    dsv_rejectreport_setupfail,
+    none,
+    insertion_preparefail,
+    dsv_header_matchernonhead,
+    dsv_colcount_mismatch,
+    dsv_insertcol_mismatch,
+    time_bad,
+    boolean_bad,
+    inputrec_modified,
+    dsv_recin_fail,
+    dsv_import_summary,
+    insertions_notcommitted,
+    autocommit_fetchfail,
+    dsv_rejectfile_purgefail,
+    dsv_rejectreport_purgefail,
+    edit_malformat,
+    input_malformat,
+    append_empty,
+    transiso_report,
+    exectime_reporting,
+    exectime_report,
+    regex_malformat,
+    encode_fail,
+    macro_tip,
+    macrodef_malformat,
+    macrodef_empty,
+    macrodef_semi,
+    macro_malformat,
+    macro_undefined,
+    log_syntax,
+    log_syntax_error,
+    reject_rpc,
+    rpc_autocommit_failure,
+    rpc_commit_failure,
+    disconnect_success,
+    disconnect_failure,
+    no_required_conn,
+    disconnected_msg,
+    connected_fallbackmsg,
+    no_vendor_schemaspt,
+    schemaname_retrieval_fail
+    ;
+
+    private static ValidatingResourceBundle vrb =
+            new ValidatingResourceBundle(
+                    SqltoolRB.class.getPackage().getName() + ".sqltool",
+                    SqltoolRB.class);
+    static {
+        vrb.setMissingPosValueBehavior(ValidatingResourceBundle.NOOP_BEHAVIOR);
+        vrb.setMissingPropertyBehavior(ValidatingResourceBundle.NOOP_BEHAVIOR);
+    }
+
+    public String getString() {
+        return vrb.getString(this);
+    }
+    public String toString() {
+        return ValidatingResourceBundle.resourceKeyFor(this);
+    }
+    public String getExpandedString() {
+        return vrb.getExpandedString(this);
+    }
+    public String getExpandedString(String... strings) {
+        return vrb.getExpandedString(this, strings);
+    }
+    public String getString(String... strings) {
+        return vrb.getString(this, strings);
+    }
+    public String getString(int i1) {
+        return vrb.getString(this, i1);
+    }
+    public String getString(int i1, int i2) {
+        return vrb.getString(this, i1, i2);
+    }
+    public String getString(int i1, int i2, int i3) {
+        return vrb.getString(this, i1, i2, i3);
+    }
+    public String getString(int i1, String s2) {
+        return vrb.getString(this, i1, s2);
+    }
+    public String getString(String s1, int i2) {
+        return vrb.getString(this, s1, i2);
+    }
+    public String getString(int i1, int i2, String s3) {
+        return vrb.getString(this, i1, i2, s3);
+    }
+    public String getString(int i1, String s2, int i3) {
+        return vrb.getString(this, i1, s2, i3);
+    }
+    public String getString(String s1, int i2, int i3) {
+        return vrb.getString(this, s1, i2, i3);
+    }
+    public String getString(int i1, String s2, String s3) {
+        return vrb.getString(this, i1, s3, s3);
+    }
+    public String getString(String s1, String s2, int i3) {
+        return vrb.getString(this, s1, s2, i3);
+    }
+    public String getString(String s1, int i2, String s3) {
+        return vrb.getString(this, s1, i2, s3);
+    }
+}
diff --git a/src/org/hsqldb/cmdline/package.html b/src/org/hsqldb/cmdline/package.html
new file mode 100644
index 0000000..bca63db
--- /dev/null
+++ b/src/org/hsqldb/cmdline/package.html
@@ -0,0 +1,8 @@
+<HTML>
+<BODY>
+Contains command-line utilities.
+See <a href="../../../../util-guide/sqltool-chapt.html" target="guide">
+  the SqlTool chapter of the
+  HyperSQL Utilities Guide</a>
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/cmdline/sqltool.flex b/src/org/hsqldb/cmdline/sqltool.flex
new file mode 100644
index 0000000..c986537
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool.flex
@@ -0,0 +1,394 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* @(#)$Id: sqltool.flex 3481 2010-02-26 18:05:06Z fredt $ */
+
+package org.hsqldb.cmdline.sqltool;
+
+import java.io.PrintStream;
+import org.hsqldb.lib.FrameworkLogger;
+
+%%
+// Defaults to Yylex
+%class SqlFileScanner
+%implements TokenSource
+%{
+    static private FrameworkLogger logger =
+            FrameworkLogger.getLog(SqlFileScanner.class);
+    private StringBuffer commandBuffer = new StringBuffer();
+    private boolean interactive;
+    private PrintStream psStd = System.out;
+    private String magicPrefix;
+    private int requestedState = YYINITIAL;
+    private String rawLeadinPrompt;
+    private boolean specialAppendState;
+    // This last is needed for very unique check needed when appending to
+    // a SQL command.  Only applies to interactive mode.
+
+    public void setRequestedState(int requestedState) {
+        this.requestedState = requestedState;
+    }
+
+    /**
+     * Really need a way to validate that this is called before using the
+     * scanner, like Spring's init-method property.
+     * For now, will just check explicitly before using.
+     */
+    public void setRawLeadinPrompt(String rawLeadinPrompt) {
+        this.rawLeadinPrompt = rawLeadinPrompt;
+    }
+
+    private void rawLeadinPrompt() {
+        if (!interactive) {
+            return;
+        }
+        if (rawLeadinPrompt == null) {
+            throw new RuntimeException("Internal assertion failed.  "
+                + "Scanner's message Resource Bundle not initialized properly");
+        }
+        psStd.println(rawLeadinPrompt);
+    }
+
+    // Trims only the end
+    private void trimBuffer() {
+        int len = commandBuffer.length();
+        commandBuffer.setLength(len -
+            ((len > 1 && commandBuffer.charAt(len - 2) == '\r') ? 2 : 1));
+    }
+
+    public void setCommandBuffer(String s) {
+        commandBuffer.setLength(0);
+        commandBuffer.append(s);
+    }
+
+    public void setInteractive(boolean interactive) {
+        this.interactive = interactive;
+    }
+
+    public void setMagicPrefix(String magicPrefix) {
+        this.magicPrefix = magicPrefix;
+    }
+    
+    public void setStdPrintStream(PrintStream psStd) {
+        this.psStd = psStd;
+    }
+
+    //private String sqlPrompt = "+sql> ";
+    private String sqlPrompt = null;
+    public void setSqlPrompt(String sqlPrompt)
+    {
+        this.sqlPrompt = sqlPrompt;
+    }
+    public String getSqlPrompt() {
+        return sqlPrompt;
+    }
+
+    //private String sqltoolPrompt = "sql> ";
+    private String sqltoolPrompt = null;
+    public void setSqltoolPrompt(String sqltoolPrompt)
+    {
+        this.sqltoolPrompt = sqltoolPrompt;
+    }
+    public String getSqltoolPrompt() {
+        return sqltoolPrompt;
+    }
+    //private String rawPrompt = "raw> ";
+    private String rawPrompt = null;
+    public void setRawPrompt(String rawPrompt)
+    {
+        this.rawPrompt = rawPrompt;
+    }
+    public String getRawPrompt() {
+        return rawPrompt;
+    }
+
+    private void debug(String id, String msg) {
+        logger.finest(id + ":  [" + msg + ']');
+    }
+
+    public String strippedYytext() {
+        String lineString = yytext();
+        int len = lineString.length();
+        len = len - ((len > 1 && lineString.charAt(len - 2) == '\r') ? 2 : 1);
+        return (lineString.substring(0, len));
+    }
+
+    // Trims only the end
+    public void pushbackTrim() {
+        String lineString = yytext();
+        int len = lineString.length();
+        yypushback((len > 1 && lineString.charAt(len - 2) == '\r') ? 2 : 1);
+    }
+
+    private void prompt(String s) {
+        if (!interactive) return;
+        psStd.print(s);
+    }
+
+    public void prompt() {
+        if (sqltoolPrompt != null) prompt(sqltoolPrompt);
+        specialAppendState = (interactive && magicPrefix != null);
+        // This tells scanner that if SQL input "looks" empty, it isn't.
+        if (interactive && magicPrefix != null) {
+            psStd.print(magicPrefix);
+            magicPrefix = null;
+        }
+    }
+%}
+
+%public
+//%int
+%line
+%column
+%eofclose
+%unicode
+%type Token
+%xstates SQL RAW SQL_SINGLE_QUOTED SQL_DOUBLE_QUOTED GOBBLE SPECIAL PL EDIT
+%xstates MACRO PROMPT_CHANGE_STATE
+/* Single-quotes Escaped with '',
+ * In Oracle, at least, no inner double-quotes (i.e. no escaping)
+ * SQL-Embedded comments are passed to SQL engine as part of SQL command */
+
+/* Expressions could be simplified by using "." instead of "[^\r\n]", but
+ * the JFlex docs say that "." means "[^n]", therefore this would mess up
+ * DOS-style line endings. */
+
+LINETERM_MAC = \r|\n|\r\n
+SQL_STARTER = [^\n\r\t\f \\*:\"\']
+TRADITIONAL_COMMENT = "/*" ~"*/"
+/* CURLY_COMMENT = "{" ~"}"   Purposefully not supporting */
+
+%%
+<PROMPT_CHANGE_STATE> {LINETERM_MAC} {
+    yybegin(requestedState);
+    prompt();
+}
+<GOBBLE> ~{LINETERM_MAC} {
+    yybegin(YYINITIAL);
+    debug("Gobbled", yytext());
+    prompt();
+}
+<SQL, SQL_SINGLE_QUOTED, SQL_DOUBLE_QUOTED, SPECIAL, PL, EDIT, MACRO> <<EOF>> {
+    yybegin(YYINITIAL);
+    return new Token(Token.UNTERM_TYPE, commandBuffer, yyline);
+}
+{TRADITIONAL_COMMENT} { /* Ignore top-level traditional comments */
+    debug ("/**/ Comment", yytext());
+}
+[ \f\t]+ { /* Ignore top-level whte space */
+    debug("Whitespace", yytext());
+}
+{LINETERM_MAC} {
+    prompt();
+}
+[--][^\n\r]* {
+    debug ("-- Comment", yytext());
+}
+; {
+    return new Token(Token.SQL_TYPE, yyline);
+}
+[Bb][Ee][Gg][Ii][Nn] [\f\t ]* {LINETERM_MAC} |
+[Cc][Rr][Ee][Aa][Tt][Ee] [\f\t ]+ [Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn] [^\n\r]* {LINETERM_MAC} |
+[Cc][Rr][Ee][Aa][Tt][Ee] [\f\t ]+ [Pp][Rr][Oo][Cc][Ee][Dd][Uu][Rr][Ee] [^\n\r]* {LINETERM_MAC} |
+[Dd][Ee][Cc][Ll][Aa][Rr][Ee] [\f\t ]* {LINETERM_MAC} {
+    /* These are commands which may contain nested commands and/or which
+     * require the closing semicolon to sent to the DB engine.
+     * The BEGIN and DECLARE needed for PL/SQL probably do not need to
+     * terminate the line, as we have it specified here, but I'd rather not be
+     * too liberal with proprietary SQL like this, because it's easy to
+     * envision other proprietary or non-proprietary commands beginning with
+     * DECLARE or BEGIN. */
+    setCommandBuffer(strippedYytext());
+    yybegin(RAW);
+    rawLeadinPrompt();
+    if (rawPrompt != null) prompt(rawPrompt);
+}
+\* {
+    commandBuffer.setLength(0);
+    yybegin(PL);
+}
+\\ {
+    commandBuffer.setLength(0);
+    yybegin(SPECIAL);
+}
+\: {
+    commandBuffer.setLength(0);
+    yybegin(EDIT);
+}
+\/ {
+    commandBuffer.setLength(0);
+    yybegin(MACRO);
+}
+<RAW> {
+    [\f\t ]*\.[\f\t ]* ; [\f\t ]* {LINETERM_MAC} {
+        yybegin(YYINITIAL);
+        prompt();
+        return new Token(Token.RAWEXEC_TYPE, commandBuffer, yyline);
+    }
+    [\f\t ]*\.[\f\t ]* {LINETERM_MAC} {
+        yybegin(YYINITIAL);
+        prompt();
+        return new Token(Token.RAW_TYPE, commandBuffer, yyline);
+    }
+    ~{LINETERM_MAC} {
+        if (commandBuffer.length() > 0) commandBuffer.append('\n');
+        commandBuffer.append(strippedYytext());
+        if (rawPrompt != null) prompt(rawPrompt);
+    }
+}
+<SPECIAL> {LINETERM_MAC} {
+    if (commandBuffer.toString().trim().equals(".")) {
+        commandBuffer.setLength(0);
+        yybegin(RAW);
+        rawLeadinPrompt();
+        if (rawPrompt != null) prompt(rawPrompt);
+    } else {
+        requestedState = YYINITIAL;
+        yybegin(PROMPT_CHANGE_STATE);
+        pushbackTrim();
+        return new Token(Token.SPECIAL_TYPE, commandBuffer, yyline);
+    }
+}
+<PL> {LINETERM_MAC} {
+    requestedState = YYINITIAL;
+    yybegin(PROMPT_CHANGE_STATE);
+    pushbackTrim();
+    return new Token(Token.PL_TYPE, commandBuffer, yyline);
+}
+<MACRO> {LINETERM_MAC} {
+    requestedState = YYINITIAL;
+    yybegin(PROMPT_CHANGE_STATE);
+    pushbackTrim();
+    return new Token(Token.MACRO_TYPE, commandBuffer, yyline);
+}
+<EDIT> {LINETERM_MAC} {
+    requestedState = YYINITIAL;
+    yybegin(PROMPT_CHANGE_STATE);
+    pushbackTrim();
+    return new Token(Token.EDIT_TYPE, commandBuffer, yyline);
+}
+<SPECIAL, PL, MACRO> {
+    // Purposefully not allowing comments within :Edit commands
+    {TRADITIONAL_COMMENT} {
+        /* embedded comment may disable opening closing \n */
+        debug("Spl. /**/ Comment", yytext());
+    }
+    "--" ~{LINETERM_MAC}  {
+        pushbackTrim();
+        /* embedded comment may disable opening quotes and closing ; */
+        debug("Spl. -- Comment", yytext());
+    }
+}
+<SPECIAL, EDIT, PL, MACRO> {
+    [^\n\r] {
+        commandBuffer.append(yytext());
+    }
+}
+{SQL_STARTER} {
+    setCommandBuffer(yytext());
+    yybegin(SQL);
+}
+<SQL> {
+    ^[\f\t ]* {LINETERM_MAC} {
+        if (interactive && !specialAppendState) {
+            requestedState = YYINITIAL;
+            yybegin(PROMPT_CHANGE_STATE);
+            pushbackTrim();
+            trimBuffer();
+            return new Token(Token.BUFFER_TYPE, commandBuffer, yyline);
+        }
+        specialAppendState = false;
+        commandBuffer.append(yytext());
+    }
+    {TRADITIONAL_COMMENT} {
+        specialAppendState = false;
+        commandBuffer.append(yytext());
+        /* embedded comment may disable opening quotes and closing ; */
+        debug("SQL /**/ Comment", yytext());
+    }
+    "--" ~{LINETERM_MAC} {
+        specialAppendState = false;
+        commandBuffer.append(yytext());
+        /* embedded comment may disable opening quotes and closing ; */
+        debug("SQL -- Comment", yytext());
+    }
+    {LINETERM_MAC} {
+        specialAppendState = false;
+        commandBuffer.append(yytext());
+        if (sqlPrompt != null) prompt(sqlPrompt);
+    }
+    [^\"\';] {
+        specialAppendState = false;
+        commandBuffer.append(yytext());
+    }
+    \' {
+        specialAppendState = false;
+        commandBuffer.append(yytext());
+        yybegin(SQL_SINGLE_QUOTED);
+    }
+    \" {
+        specialAppendState = false;
+        commandBuffer.append(yytext());
+        yybegin(SQL_DOUBLE_QUOTED);
+    }
+    ; {
+        specialAppendState = false;
+        yybegin(YYINITIAL);
+        return new Token(Token.SQL_TYPE, commandBuffer, yyline);
+    }
+}
+<SQL_SINGLE_QUOTED> {
+    [^\']+ {
+        commandBuffer.append(yytext());
+    }
+    \'\' {
+        commandBuffer.append(yytext());
+    }
+    \' {
+        commandBuffer.append(yytext());
+        debug("SQL '", yytext());
+        yybegin(SQL);
+    }
+}
+<SQL_DOUBLE_QUOTED> {
+    [^\"]+ {
+        commandBuffer.append(yytext());
+    }
+    \" {
+        commandBuffer.append(yytext());
+        yybegin(SQL);
+        debug("SQL \"", yytext());
+    }
+}
+[^\r\n] {
+    yybegin(GOBBLE);
+    return new Token(Token.SYNTAX_ERR_TYPE, yytext(), yyline);
+}
diff --git a/src/org/hsqldb/cmdline/sqltool.properties b/src/org/hsqldb/cmdline/sqltool.properties
new file mode 100644
index 0000000..feb0bdd
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool.properties
@@ -0,0 +1,242 @@
+# $Id: sqltool.properties 3424 2010-01-13 21:51:18Z unsaved $
+
+# Default Locale String resources for SqlTool.
+
+# IMPORTANT:  Make sure to use ISO-8859-1 encoding for any extended characters,
+# both in this file (actually any .properties file) and all referenced text
+# files.
+
+# GENERAL .properties SYNTAX:
+#   White space AT END OF LINES IS SIGNIFICANT
+#   White space at beginning of lines is not
+#   \ at very end of line makes the following line a continuation line (with
+#     no implied newline in the value.
+#     (Combined with the previous 2 rules, this means that white space before
+#     this \ is significant, and whitespace at beginning of continutation lines
+#     is not).
+#   \n does not work as an escape.  Use unicode \u000a for line breaks instead.
+
+# This file is loaded by RefCapablePropertyResourceBundle, so if any
+# property here has no value set, the value MUST be set in a file
+# located at sqltool/PROPERTYNAME.text
+# Property keys MAY NOT CONTAIN UNDERSCORE.  Underscores in Enum constants
+# will automatically be transated to dots.
+
+# These empty-vals tell RefCapablePropertyResourceBundle to look for text files:
+SqlTool.syntax=
+SqlFile.banner=
+buffer.help=
+special.help=
+pl.help=
+dsv.options=
+d.options=
+raw.leadin=
+errorat=
+rejectreport.top=
+rejectreport.row=
+rejectreport.bottom=
+macro.help=
+
+# Traditional inline .properties values:
+rawmode.prompt=raw
+SqlTool.varset.badformat=Variable settings not of format "name=value[,...]".
+SqlTool.abort.continue.mutuallyexclusive=Switches '--abortOnErr' and \
+                        '--continueOnErr' are mutually exclusive.
+sqltempfile.fail=Failed to write given sql to temp file.\u000aCause: %{1}
+rcdata.inlineurl.missing='url' element is required for inline RC arg.
+rcdata.inline.extravars=Unsupported inline element(s) supplied: %{1}.
+rcdata.inlineusername.missing='user' element is required for inline RC arg.
+rcdata.password.visible='password' element must have empty value.  \
+            For non-empty password, give no\u000a\
+            password element and you will be prompted for the value.
+password.readfail=Failed to read in password.\u000aCause: %{1}
+rcdata.genfromvalues.fail=Failed to generate RCData from given values.\u000aCause: %{1}
+conndata.retrieval.fail=Failed to retrieve connection info for urlid "%{1}".\u000aCause: %{2}
+jdbc.established=JDBC Connection established to a %{1} v. %{2} database\u000a\
+     as "%{3}" with %{4} Isolation.
+connection.fail=Failed to get a connection to '%{1}' as user "%{2}".\u000aCause: %{3}
+# Value for following line has trailing whitespace on purpose.
+passwordFor.prompt=Enter password for %{1}:  
+
+raw.movedtobuffer=Raw SQL chunk moved into edit buffer.  Run ":;" to execute the chunk.
+input.movedtobuffer=Current input moved into edit buffer.
+sqlstatement.empty=Empty SQL Statement.
+causereport=Cause: %{1}
+break.unsatisfied=Unsatisfied 'break' statement (type %{1}).
+continue.unsatisfied=Unsatisfied 'continue' statement%{1:+ (type '%1')}.
+input.unterminated=Unterminated input:  "%{1}"
+primaryinput.accessfail=Error accessing primary input.
+aborting=Aborting SqlTool:  %{1}
+plvar.set.incomplete=Never completed setting of variable '%{1}'.
+rollingback=Rolling back SQL transaction.
+bufhist.unspecified=No command specified.  Run ":?" to list Edit-Buffer/History Commands.
+special.unspecified=No command specified.  Run "\\?" to list Special Commands.
+buffer.executing=Executing command from edit buffer:\u000a"%{1}"\u000a
+nobuffer.yet=No edit buffer contents yet.
+commandnum.malformat=Malformatted command number "%{1}".
+buffer.restored=Restored following command to buffer.  Enter ":?" to list buffer commands.\u000a%{1}
+substitution.malformat=Malformatted substitution command.
+substitution.nomatch=Edit buffer unchanged due to no pattern match.
+substitution.syntax=Substitution syntax: ":s/from regex/to string/igm;".  \
+                     Optional modes i, g, m, ;.
+buffer.unknown=Unknown Edit-Buffer/History command ":%{1}".
+dsv.x.syntax=Export syntax:  "\\x table_or_view_name "  OR  "\\x SELECT statement".\u000a\
+(Do not end with ';', since the \\x command itself is not SQL).
+dsv.m.syntax=Import syntax:  \\m file/path.dsv [*]   (* means no comments in DSV file).
+special.extrachars=Extra characters after "\\%{1}" command:  %{2}
+buffer.extrachars=Extra characters after ":{%1}" command:  %{2}
+special.malformat=Malformatted special command.
+html.mode=HTML Mode is now set to %{1}.
+dsv.targetfile.demand=You must set PL variable '*DSV_TARGET_FILE' in order to use the query variant of \\x.
+file.wrotechars=Wrote %{1} characters to file '%{2}'.
+file.writefail=Failed to write to file '%{1}'.
+file.appendfail=Failed to append to file '%{1}'.
+destfile.demand=You must supply a destination file name.
+special.d.like=Describe commands must be like '\\dX' or like '\\d OBJECTNAME'.  '\\d?' to list.
+outputfile.nonetoclose=There is no query output file to close.
+outputfile.reopening=Closing current query output file and opening new one.
+outputfile.header=Query output from %{1}.
+buffer.empty=No command in edit buffer.
+sqlfile.name.demand=You must supply an SQL file name.
+sqlfile.execute.fail=Failed to execute contents of SQL file '%{1}'.
+a.setting=Auto-commit is set to %{1}.
+committed=Session committed.
+special.b.malformat=Malformatted binary command.
+binary.loadedbytesinto=Loaded %{1} bytes into Binary buffer.
+binary.filefail=Failed to load/dump binary data to file '%{1}'.
+c.setting=Continue-on-error is set to %{1}.
+bang.incomplete=You must follow ! with the external command to run.
+bang.command.fail=External command failed:\u000a"%{1}"
+special.unknown=Unknown Special command "\\%{1}".
+raw.empty=Raw statement aborted (no input given).
+dsv.nocolsleft=No remaining columns after omitting %{1:+"%1" and }"-" columns.
+dsv.skipcols.missing=The following skip column(s) not present:  %{1}.
+plalias.malformat=Malformed PL alias usage.
+plvar.undefined=Undefined PL variable "%{1}".
+var.infinite=Possible infinite variable regress involving '%{1}'.
+sysprop.empty=Empty System Property variable name.
+sysprop.unterminated=Unterminated System Property variable name.
+sysprop.undefined=Undefined System Property "%{1}".
+plvar.nameempty=Empty PL variable name.
+plvar.unterminated=Unterminated PL variable name.
+pl.malformat=Malformatted PL command.
+pl.expansionmode=PL variable expansion mode is now %{1}.
+end.noblock=Unmatched 'end' command.
+continue.syntax=PL 'continue' statement requires no argument or one of \
+                 'foreach', 'while'.
+break.syntax=PL 'break' statement requires no argument or one of \
+                 'foreach', 'if', 'while', 'file'.
+pl.list.parens=The outermost parentheses are not part of the values.
+pl.list.lengths=Showing variable names and length of values \
+                 (use 'listvalues' to see values).
+dumpload.malformat=Malformatted PL 'dump' or 'load' command.
+plvar.nocolon=PL variable names may not contain ':'.
+plvar.tildedash.nomoreargs=PL ~/_ set commands take no other args ("%{1}").
+dumpload.fail=Failed to dump/load variable '%{1}' to/from file '%{2}'.
+prepare.malformat=Malformatted PL 'prepare' command.
+foreach.malformat=Malformatted PL 'foreach' command.
+pl.block.fail=Failed to execute instructions from PL block.
+ifwhile.malformat=Malformatted PL 'if'/'while' command.
+if.malformat=Malformatted PL 'if' command.
+while.malformat=Malformatted PL 'while' command.
+pl.unknown=Unknown PL command "%{1}".
+pl.block.unterminated=Unterminated PL '%{1}' block
+vendor.oracle.dS=*** WARNING:\u000a\
+         *** Listing tables in system-supplied schemas since\u000a\
+         *** Oracle (TM) doesn't return a JDBC system table list.
+vendor.derby.dr=Derby has not implemented SQL Roles.
+vendor.nosup.d=SqlFile does not yet support \\d%{1} for your database vendor.
+vendor.derby.du=It's impossible to get a reliable user list from Derby.
+special.d.unknown=Unknown describe option: '%{1}'.
+metadata.fetch.fail=Failed to get metadata from database.
+metadata.fetch.failfor=Failed to get metadata from database for '%{1}'.
+prepare.demandqm=Prepared statements must contain one '?'.
+binbuffer.empty=Binary SqlFile buffer is empty.
+vendor.nosup.sysschemas=*** WARNING:\u000a\
+            *** Omitting tables from system-supplied schemas\u000a\
+            *** (because DB vendor doesn't differentiate them to JDBC).
+noresult=No result.
+dsv.bincol=Table has a binary column.  DSV files are text, not binary, files.
+binbuf.write=Read %{1} bytes from field '%{2}' (type %{3}) into binary buffer.
+rows.fetched=Fetched %{1} rows.
+rows.fetched.dsv=%{1} row(s) fetched from database.
+row.update.multiple=%{1} rows updated.
+row.update.singular=1 row updated.
+history.unavailable=Command history not available.
+history.none=No history yet.
+editbuffer.contents=Edit buffer contents:\u000a"%{1}"
+buffer.instructions=Copy a command to edit buffer like ":27" or ":-3".  \
+                    Re-execute buffer like ":;".
+history.number.req=You must specify a positive absolute command number, or \
+                    a negative number\u000ameaning X commands "back".
+history.backto=History only goes back to #%{1}.
+history.upto=History only goes up to #%{1}.
+history.back=History only goes back %{1} command(s).
+describe.table.name=name
+describe.table.datatype=datatype
+describe.table.width=width
+describe.table.nonulls=no-nulls
+logical.unrecognized=Unrecognized logical operation.
+read.toobig=Resource is too big to read in one gulp.\u000a\
+            Please run the program with more RAM (try Java -Xm* switches).
+read.partial=Didn't read all bytes.  Read in %{1} bytes out of %{2}.
+read.convertfail=Value too big to convert to String.  \
+                  Please run the program with more RAM (try Java -Xm* switches).
+dsv.coldelim.present=Table data contains our column delimiter '%{1}'.
+dsv.rowdelim.present=Table data contains our row delimiter '%{1}'.
+dsv.nullrep.present=Table data contains our null-representation token '%{1}'.
+dsv.constcols.nullcol=*DSV_CONST_COLS element has null column name.
+file.readfail=Can't read file '%{1}'.
+inputfile.closefail=Failed to close input file.
+dsv.header.none=No header record in input file.
+dsv.header.noswitchtarg=Headerswitch at DSV file line %{1}, but no target table specified yet.
+dsv.header.noswitchmatch=Reached close of headerswitch at DSV file line %{1} without matching a header.
+dsv.header.nonswitched=Header line inside switch without table matcher at DSV file line %{1}.
+dsv.nocolheader=No column header for column #%{1} at DSV file line %{2}.
+dsv.metadata.mismatch=Metadata mismatch for columns.
+query.metadatafail=Failed to get metadata for query by using:\u000a"%{1}"
+dsv.rejectfile.setupfail=Failed to set up reject file '%{1}'.
+dsv.rejectreport.setupfail=Failed to set up reject report file '%{1}'.
+none=None
+insertion.preparefail=Failed to prepare insertion setup string:\u000a"%{1}"
+dsv.header.matchernonhead=Non-Header line within table matcher block at DSV file line %{1}.
+dsv.colcount.mismatch=Header has %{1} columns, but input record has %{2} column values.
+dsv.insertcol.mismatch=Expected total of %{1} insert values, but gathered %{2}.
+dsv.nonskip.mismatch=Header has %{1} non-skip columns, but input record has %{2} insertion values.
+time.bad=Bad date/time value '%{1}'.
+boolean.bad=Bad boolean value '%{1}'.
+inputrec.modified=%{1} rows modified by this input record.
+dsv.recin.fail=Parse or insert of input line %{1} %{2:+, column '%2' }failed.
+dsv.import.summary=Import summary (%{1}skips / rejects / inserts):  \
+                    %{2} / %{3} / %{4}%{5:+ before aborting}.
+insertions.notcommitted=Insertions will be lost if you don't commit.
+autocommit.fetchfail=Failed to obtain connection autocommit value.
+dsv.rejectfile.purgefail=Failed to purge unnecessary reject file '%{1}'.
+dsv.rejectreport.purgefail=Failed to purge unnecessary reject report '%{1}'.
+edit.malformat=Edit/History command malformatted.
+input.malformat=Syntax error in input.
+append.empty=Use ':;' to repeat a command without appending
+transiso.report=Transaction Isolation Level is now %{1} %{2}
+exectime.reporting=Execution-time reporting is set to %{1}
+exectime.report=Took %{1} ms.
+regex.malformat=Malformed regex pattern: %{1}
+encode.fail=Unsupported encoding: %{1}
+macro.tip=Run /? for Macro help
+macrodef.malformat=Malformatted macro def. command
+macrodef.empty=No content specified for macro
+macrodef.semi=Macro values may not end with ';'
+macro.malformat=Malformatted macro command
+macro.undefined=No macro defined with name "%{1}".
+log.syntax=SYNTAX:  \\l LEVEL Message\u000a\
+    Where LEVEL is one of:  FINEST, FINER, INFO, WARNING, SEVERE
+log.syntax.error=Logging syntax error.  Run '\\l?' for help
+reject.rpc=Clearing *DSV_RECORDS_PER_COMMIT, since non-integer specified: %{1}
+rpc.autocommit.failure=Failed to set up autocommit for *DSV_RECORDS_PER_COMMIT option
+rpc.commit.failure=Failed to finalize commit status for *DSV_RECORDS_PER_COMMIT option
+disconnect.success=Disconnected from JDBC Data Source
+disconnect.failure=Failed to disconnect from JDBC Data Source
+no.required.conn=We are not connected to a Data Source, but one is required for this action
+disconnected.msg=<UNCONNECTED>
+connected.fallbackmsg=<CONNECTED>
+no.vendor.schemaspt=Database does not support SQL-standard SCHEMA operations
+schemaname.retrieval.fail=Failed to retrieve current SCHEMA name from database
diff --git a/src/org/hsqldb/cmdline/sqltool/SqlFile.banner.text b/src/org/hsqldb/cmdline/sqltool/SqlFile.banner.text
new file mode 100644
index 0000000..639faad
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/SqlFile.banner.text
@@ -0,0 +1,23 @@
+SqlFile processor v. %{1}.
+Distribution is permitted under the terms of the HSQLDB license.
+(c) 2004-2009 Blaine Simpson and the HSQL Development Group.
+
+    \q    to Quit.
+    \?    lists Special Commands.
+    :?    lists Edit-Buffer/History commands.
+    *?    lists PL commands.
+    /?    displays help on how to set and use macros (command aliases).
+
+SPECIAL Commands begin with '\' and execute when you hit ENTER.
+EDIT-BUFFER / HISTORY Commands begin with ':' and execute when you hit ENTER.
+PROCEDURAL LANGUAGE commands begin with '*' and end when you hit ENTER.
+MACRO executions and definitions begin with '/' and end when you hit ENTER.
+All other lines comprise SQL Statements (or comments).
+  SQL Statements are terminated by either unquoted ';' (which executes the
+  statement), or a blank line (which moves the statement into the edit buffer
+  without executing).
+After turning on variable expansion with command "*" (or any other PL
+command), PL variables may be used in most commands like so:  *{PLVARNAME}.
+Be aware when using regular expressions on commands, that the regex.s
+operate only on the command text after the * or \ prefix, if any.
+
diff --git a/src/org/hsqldb/cmdline/sqltool/SqlFile.banner_de.text b/src/org/hsqldb/cmdline/sqltool/SqlFile.banner_de.text
new file mode 100644
index 0000000..ba8cdbe
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/SqlFile.banner_de.text
@@ -0,0 +1,22 @@
+SqlFile processor v. %{1}.
+Die Weitergabe ist zulässig unter den Bedingungen der HSQLDB Lizenz.
+(c) 2004-2009 Blaine Simpson und die HSQL Development Group.
+
+    \q    beenden.
+    \?    Sonderbefehle auflisten.
+    :?    Edit-Puffer/Verlaufsbefehle auflisten.
+    *?    PL Befehle auflisten.
+    /?    Zeigt die Hilfe und wie Makros (Befehlsaliase) definiert und gelöscht werden.
+
+SONDERBEFEHLE fangen mit \ ab und werden mit ENTER ausgeführt.
+EDIT-PUFFER / VERLAUFSBEFEHLE  fangen mit einem ':' an und werden mit ENTER ausgeführt.
+PROCEDURAL LANGUAGE (PL) Befehle fangen mit einem '*' an  und werden mit ENTER beendet.
+MAKRO Ausführungen und Definitionen beginnen  mit einem '/' und werden mit ENTER beendet.
+Alle anderen Zeilen enthalten SQL-Anweisungen (oder Kommentare).
+	SQL-Anweisungen werden entweder durch ein ';' beendet (und dann ausgeführt)
+	oder mit einer Leerzeile (dadurch wird die Anweisung in den Edit-Puffer verschoben
+	und nicht ausgeführt).
+Nach einer Variablenexpansion mit dem Befehl '*' (oder jedem anderen PL-Befehl),
+können PL-Variablen in den meisten Befehlen wie folgt verwendet werden: *{PLVARNAME}
+Wenn Sie Reguläre Ausdrücke in Kommandos verwenden, beachten Sie bitte, daß diese
+im Befehlstext nur nach dem '*' oder '\' Präfix (falls vorhanden) wirken,
diff --git a/src/org/hsqldb/cmdline/sqltool/SqlFileScanner.java b/src/org/hsqldb/cmdline/sqltool/SqlFileScanner.java
new file mode 100644
index 0000000..4fcfbc9
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/SqlFileScanner.java
@@ -0,0 +1,1100 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* @(#)$Id: SqlFileScanner.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+package org.hsqldb.cmdline.sqltool;
+
+import java.io.PrintStream;
+import org.hsqldb.lib.FrameworkLogger;
+
+
+/**
+ * This class is a scanner generated by 
+ * <a href="http://www.jflex.de/">JFlex</a> 1.4.1
+ * on 12/18/09 5:41 PM from the specification file
+ * <tt>/home/blaine/hsqldb/src/org/hsqldb/cmdline/sqltool.flex</tt>
+ */
+public class SqlFileScanner implements TokenSource {
+
+  /** This character denotes the end of file */
+  public static final int YYEOF = -1;
+
+  /** initial size of the lookahead buffer */
+  private static final int ZZ_BUFFERSIZE = 16384;
+
+  /** lexical states */
+  public static final int SPECIAL = 12;
+  public static final int SQL_DOUBLE_QUOTED = 8;
+  public static final int SQL_SINGLE_QUOTED = 6;
+  public static final int GOBBLE = 10;
+  public static final int RAW = 4;
+  public static final int SQL = 2;
+  public static final int YYINITIAL = 0;
+  public static final int EDIT = 16;
+  public static final int PL = 14;
+  public static final int PROMPT_CHANGE_STATE = 20;
+  public static final int MACRO = 18;
+
+  /**
+   * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
+   * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
+   *                  at the beginning of a line
+   * l is of the form l = 2*k, k a non negative integer
+   */
+  private static final int ZZ_LEXSTATE[] = { 
+     0,  0,  1,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8, 
+     9,  9, 10, 10, 11, 11
+  };
+
+  /** 
+   * Translates characters to character classes
+   */
+  private static final String ZZ_CMAP_PACKED = 
+    "\11\0\1\6\1\2\1\0\1\6\1\1\22\0\1\6\1\0\1\3"+
+    "\4\0\1\33\2\0\1\5\2\0\1\7\1\32\1\4\12\0\1\31"+
+    "\1\10\5\0\1\20\1\11\1\16\1\26\1\12\1\22\1\13\1\0"+
+    "\1\14\2\0\1\27\1\0\1\15\1\24\1\25\1\0\1\17\1\0"+
+    "\1\21\1\23\6\0\1\30\4\0\1\20\1\11\1\16\1\26\1\12"+
+    "\1\22\1\13\1\0\1\14\2\0\1\27\1\0\1\15\1\24\1\25"+
+    "\1\0\1\17\1\0\1\21\1\23\uff8a\0";
+
+  /** 
+   * Translates characters to character classes
+   */
+  private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);
+
+  /** 
+   * Translates DFA states to action switch labels.
+   */
+  private static final int [] ZZ_ACTION = zzUnpackAction();
+
+  private static final String ZZ_ACTION_PACKED_0 =
+    "\14\0\1\1\2\2\1\3\1\4\1\5\1\6\1\7"+
+    "\1\10\3\1\1\11\1\12\1\13\2\14\1\15\2\13"+
+    "\1\16\1\17\2\20\1\13\1\0\2\21\1\0\1\22"+
+    "\1\23\1\22\1\24\2\25\1\22\2\26\2\22\2\27"+
+    "\2\30\2\31\2\32\7\0\2\33\10\0\2\34\2\35"+
+    "\1\0\2\36\1\37\3\0\1\40\1\41\3\0\2\42"+
+    "\23\0";
+
+  private static int [] zzUnpackAction() {
+    int [] result = new int[114];
+    int offset = 0;
+    offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackAction(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+
+  /** 
+   * Translates a state to a row index in the transition table
+   */
+  private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
+
+  private static final String ZZ_ROWMAP_PACKED_0 =
+    "\0\0\0\34\0\70\0\124\0\160\0\214\0\250\0\304"+
+    "\0\340\0\374\0\u0118\0\u0134\0\u0150\0\u016c\0\u0150\0\u0150"+
+    "\0\u0188\0\u0150\0\u01a4\0\u01c0\0\u0150\0\u01dc\0\u01f8\0\u0214"+
+    "\0\u0150\0\u0150\0\u0150\0\u0230\0\u0150\0\u0150\0\u024c\0\u0268"+
+    "\0\u0150\0\u0150\0\u0284\0\u0150\0\u02a0\0\u02bc\0\u02d8\0\u0150"+
+    "\0\u02f4\0\u0310\0\u032c\0\u0348\0\u0150\0\u0364\0\u0150\0\u0150"+
+    "\0\u0380\0\u0150\0\u039c\0\u03b8\0\u03d4\0\u0150\0\u03f0\0\u0150"+
+    "\0\u040c\0\u0150\0\u0428\0\u0150\0\u0444\0\u0460\0\u047c\0\u0498"+
+    "\0\u04b4\0\u04d0\0\u02a0\0\u04ec\0\u0150\0\u0508\0\u0524\0\u0540"+
+    "\0\u055c\0\u0578\0\u0594\0\u05b0\0\u05cc\0\u05e8\0\u0150\0\u0604"+
+    "\0\u0150\0\u0620\0\u063c\0\u0150\0\u0150\0\u0658\0\u0674\0\u0690"+
+    "\0\u0150\0\u0150\0\u06ac\0\u06c8\0\u06e4\0\u0700\0\u0150\0\u071c"+
+    "\0\u0738\0\u0754\0\u0770\0\u078c\0\u07a8\0\u07c4\0\u07e0\0\u07fc"+
+    "\0\u0818\0\u0834\0\u0850\0\u086c\0\u0888\0\u08a4\0\u08c0\0\u08dc"+
+    "\0\u08f8\0\u0914";
+
+  private static int [] zzUnpackRowMap() {
+    int [] result = new int[114];
+    int offset = 0;
+    offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackRowMap(String packed, int offset, int [] result) {
+    int i = 0;  /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int high = packed.charAt(i++) << 16;
+      result[j++] = high | packed.charAt(i++);
+    }
+    return j;
+  }
+
+  /** 
+   * The transition table of the DFA
+   */
+  private static final int [] ZZ_TRANS = zzUnpackTrans();
+
+  private static final String ZZ_TRANS_PACKED_0 =
+    "\1\15\1\16\1\17\1\20\1\21\1\22\1\23\1\24"+
+    "\1\25\1\26\4\15\1\27\7\15\1\30\1\15\1\31"+
+    "\1\32\1\15\1\20\1\33\1\34\1\35\1\36\1\37"+
+    "\2\33\1\40\1\41\22\33\1\42\1\33\1\43\1\44"+
+    "\1\36\1\37\1\33\1\45\1\40\1\41\22\33\1\42"+
+    "\1\46\1\47\1\50\3\46\1\4\23\46\1\51\1\46"+
+    "\33\52\1\53\3\54\1\55\30\54\1\7\1\56\1\57"+
+    "\31\7\1\60\1\61\1\62\1\60\1\63\2\60\1\64"+
+    "\25\60\1\65\1\66\1\60\1\63\2\60\1\64\25\60"+
+    "\1\67\1\70\32\60\1\71\1\72\1\60\1\63\2\60"+
+    "\1\64\24\60\1\0\1\73\1\74\67\0\1\17\36\0"+
+    "\1\75\34\0\1\23\25\0\1\24\2\0\31\24\12\0"+
+    "\1\76\40\0\1\77\26\0\1\100\23\0\1\35\36\0"+
+    "\1\101\35\0\1\102\26\0\1\44\32\0\1\43\1\44"+
+    "\3\0\1\103\25\0\1\46\1\47\1\50\31\46\2\0"+
+    "\1\50\31\0\1\46\1\104\1\105\3\46\1\51\1\46"+
+    "\1\106\23\46\33\52\34\0\1\60\3\54\1\0\30\54"+
+    "\2\0\1\57\33\0\1\62\36\0\1\107\35\0\1\110"+
+    "\26\0\1\66\33\0\1\70\33\0\1\72\33\0\1\74"+
+    "\31\0\5\75\1\111\26\75\13\0\1\112\32\0\1\113"+
+    "\37\0\1\114\15\0\5\101\1\115\26\101\1\102\1\116"+
+    "\1\117\31\102\2\0\1\105\31\0\1\46\1\120\1\121"+
+    "\3\46\1\106\25\46\5\107\1\122\26\107\1\110\1\123"+
+    "\1\124\31\110\4\75\1\125\1\111\26\75\14\0\1\126"+
+    "\37\0\1\127\42\0\1\130\4\0\4\101\1\131\1\115"+
+    "\26\101\2\0\1\117\33\0\1\121\31\0\4\107\1\132"+
+    "\1\122\26\107\2\0\1\124\46\0\1\133\37\0\1\134"+
+    "\32\0\1\135\14\0\1\136\1\137\3\0\1\133\37\0"+
+    "\1\140\40\0\1\141\16\0\1\137\37\0\1\142\37\0"+
+    "\1\133\27\0\1\142\13\0\1\143\2\0\1\144\31\0"+
+    "\1\145\27\0\1\146\31\0\1\147\42\0\1\150\25\0"+
+    "\1\151\33\0\1\152\36\0\1\153\24\0\1\154\35\0"+
+    "\1\155\45\0\1\156\31\0\1\157\32\0\1\160\25\0"+
+    "\1\161\35\0\1\162\14\0\1\161\1\136\1\137\31\161"+
+    "\12\0\1\161\21\0";
+
+  private static int [] zzUnpackTrans() {
+    int [] result = new int[2352];
+    int offset = 0;
+    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackTrans(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      value--;
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+
+  /* error codes */
+  private static final int ZZ_UNKNOWN_ERROR = 0;
+  private static final int ZZ_NO_MATCH = 1;
+  private static final int ZZ_PUSHBACK_2BIG = 2;
+
+  /* error messages for the codes above */
+  private static final String ZZ_ERROR_MSG[] = {
+    "Unkown internal scanner error",
+    "Error: could not match input",
+    "Error: pushback value was too large"
+  };
+
+  /**
+   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
+   */
+  private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
+
+  private static final String ZZ_ATTRIBUTE_PACKED_0 =
+    "\14\0\1\11\1\1\2\11\1\1\1\11\2\1\1\11"+
+    "\3\1\3\11\1\1\2\11\2\1\2\11\1\1\1\11"+
+    "\1\1\1\0\1\1\1\11\1\0\3\1\1\11\1\1"+
+    "\2\11\1\1\1\11\3\1\1\11\1\1\1\11\1\1"+
+    "\1\11\1\1\1\11\7\0\1\1\1\11\10\0\1\1"+
+    "\1\11\1\1\1\11\1\0\1\1\2\11\3\0\2\11"+
+    "\3\0\1\1\1\11\23\0";
+
+  private static int [] zzUnpackAttribute() {
+    int [] result = new int[114];
+    int offset = 0;
+    offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackAttribute(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+  /** the input device */
+  private java.io.Reader zzReader;
+
+  /** the current state of the DFA */
+  private int zzState;
+
+  /** the current lexical state */
+  private int zzLexicalState = YYINITIAL;
+
+  /** this buffer contains the current text to be matched and is
+      the source of the yytext() string */
+  private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
+
+  /** the textposition at the last accepting state */
+  private int zzMarkedPos;
+
+  /** the textposition at the last state to be included in yytext */
+  private int zzPushbackPos;
+
+  /** the current text position in the buffer */
+  private int zzCurrentPos;
+
+  /** startRead marks the beginning of the yytext() string in the buffer */
+  private int zzStartRead;
+
+  /** endRead marks the last character in the buffer, that has been read
+      from input */
+  private int zzEndRead;
+
+  /** number of newlines encountered up to the start of the matched text */
+  private int yyline;
+
+  /** the number of characters up to the start of the matched text */
+  private int yychar;
+
+  /**
+   * the number of characters from the last newline up to the start of the 
+   * matched text
+   */
+  private int yycolumn;
+
+  /** 
+   * zzAtBOL == true <=> the scanner is currently at the beginning of a line
+   */
+  private boolean zzAtBOL = true;
+
+  /** zzAtEOF == true <=> the scanner is at the EOF */
+  private boolean zzAtEOF;
+
+  /** denotes if the user-EOF-code has already been executed */
+  private boolean zzEOFDone;
+
+  /* user code: */
+    static private FrameworkLogger logger =
+            FrameworkLogger.getLog(SqlFileScanner.class);
+    private StringBuffer commandBuffer = new StringBuffer();
+    private boolean interactive;
+    private PrintStream psStd = System.out;
+    private String magicPrefix;
+    private int requestedState = YYINITIAL;
+    private String rawLeadinPrompt;
+    private boolean specialAppendState;
+    // This last is needed for very unique check needed when appending to
+    // a SQL command.  Only applies to interactive mode.
+
+    public void setRequestedState(int requestedState) {
+        this.requestedState = requestedState;
+    }
+
+    /**
+     * Really need a way to validate that this is called before using the
+     * scanner, like Spring's init-method property.
+     * For now, will just check explicitly before using.
+     */
+    public void setRawLeadinPrompt(String rawLeadinPrompt) {
+        this.rawLeadinPrompt = rawLeadinPrompt;
+    }
+
+    private void rawLeadinPrompt() {
+        if (!interactive) {
+            return;
+        }
+        if (rawLeadinPrompt == null) {
+            throw new RuntimeException("Internal assertion failed.  "
+                + "Scanner's message Resource Bundle not initialized properly");
+        }
+        psStd.println(rawLeadinPrompt);
+    }
+
+    // Trims only the end
+    private void trimBuffer() {
+        int len = commandBuffer.length();
+        commandBuffer.setLength(len -
+            ((len > 1 && commandBuffer.charAt(len - 2) == '\r') ? 2 : 1));
+    }
+
+    public void setCommandBuffer(String s) {
+        commandBuffer.setLength(0);
+        commandBuffer.append(s);
+    }
+
+    public void setInteractive(boolean interactive) {
+        this.interactive = interactive;
+    }
+
+    public void setMagicPrefix(String magicPrefix) {
+        this.magicPrefix = magicPrefix;
+    }
+    
+    public void setStdPrintStream(PrintStream psStd) {
+        this.psStd = psStd;
+    }
+
+    //private String sqlPrompt = "+sql> ";
+    private String sqlPrompt = null;
+    public void setSqlPrompt(String sqlPrompt)
+    {
+        this.sqlPrompt = sqlPrompt;
+    }
+    public String getSqlPrompt() {
+        return sqlPrompt;
+    }
+
+    //private String sqltoolPrompt = "sql> ";
+    private String sqltoolPrompt = null;
+    public void setSqltoolPrompt(String sqltoolPrompt)
+    {
+        this.sqltoolPrompt = sqltoolPrompt;
+    }
+    public String getSqltoolPrompt() {
+        return sqltoolPrompt;
+    }
+    //private String rawPrompt = "raw> ";
+    private String rawPrompt = null;
+    public void setRawPrompt(String rawPrompt)
+    {
+        this.rawPrompt = rawPrompt;
+    }
+    public String getRawPrompt() {
+        return rawPrompt;
+    }
+
+    private void debug(String id, String msg) {
+        logger.finest(id + ":  [" + msg + ']');
+    }
+
+    public String strippedYytext() {
+        String lineString = yytext();
+        int len = lineString.length();
+        len = len - ((len > 1 && lineString.charAt(len - 2) == '\r') ? 2 : 1);
+        return (lineString.substring(0, len));
+    }
+
+    // Trims only the end
+    public void pushbackTrim() {
+        String lineString = yytext();
+        int len = lineString.length();
+        yypushback((len > 1 && lineString.charAt(len - 2) == '\r') ? 2 : 1);
+    }
+
+    private void prompt(String s) {
+        if (!interactive) return;
+        psStd.print(s);
+    }
+
+    public void prompt() {
+        if (sqltoolPrompt != null) prompt(sqltoolPrompt);
+        specialAppendState = (interactive && magicPrefix != null);
+        // This tells scanner that if SQL input "looks" empty, it isn't.
+        if (interactive && magicPrefix != null) {
+            psStd.print(magicPrefix);
+            magicPrefix = null;
+        }
+    }
+
+
+  /**
+   * Creates a new scanner
+   * There is also a java.io.InputStream version of this constructor.
+   *
+   * @param   in  the java.io.Reader to read input from.
+   */
+  public SqlFileScanner(java.io.Reader in) {
+    this.zzReader = in;
+  }
+
+  /**
+   * Creates a new scanner.
+   * There is also java.io.Reader version of this constructor.
+   *
+   * @param   in  the java.io.Inputstream to read input from.
+   */
+  public SqlFileScanner(java.io.InputStream in) {
+    this(new java.io.InputStreamReader(in));
+  }
+
+  /** 
+   * Unpacks the compressed character translation table.
+   *
+   * @param packed   the packed character translation table
+   * @return         the unpacked character translation table
+   */
+  private static char [] zzUnpackCMap(String packed) {
+    char [] map = new char[0x10000];
+    int i = 0;  /* index in packed string  */
+    int j = 0;  /* index in unpacked array */
+    while (i < 132) {
+      int  count = packed.charAt(i++);
+      char value = packed.charAt(i++);
+      do map[j++] = value; while (--count > 0);
+    }
+    return map;
+  }
+
+
+  /**
+   * Refills the input buffer.
+   *
+   * @return      <code>false</code>, iff there was new input.
+   * 
+   * @exception   java.io.IOException  if any I/O-Error occurs
+   */
+  private boolean zzRefill() throws java.io.IOException {
+
+    /* first: make room (if you can) */
+    if (zzStartRead > 0) {
+      System.arraycopy(zzBuffer, zzStartRead,
+                       zzBuffer, 0,
+                       zzEndRead-zzStartRead);
+
+      /* translate stored positions */
+      zzEndRead-= zzStartRead;
+      zzCurrentPos-= zzStartRead;
+      zzMarkedPos-= zzStartRead;
+      zzPushbackPos-= zzStartRead;
+      zzStartRead = 0;
+    }
+
+    /* is the buffer big enough? */
+    if (zzCurrentPos >= zzBuffer.length) {
+      /* if not: blow it up */
+      char newBuffer[] = new char[zzCurrentPos*2];
+      System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
+      zzBuffer = newBuffer;
+    }
+
+    /* finally: fill the buffer with new input */
+    int numRead = zzReader.read(zzBuffer, zzEndRead,
+                                            zzBuffer.length-zzEndRead);
+
+    if (numRead < 0) {
+      return true;
+    }
+    else {
+      zzEndRead+= numRead;
+      return false;
+    }
+  }
+
+    
+  /**
+   * Closes the input stream.
+   */
+  public final void yyclose() throws java.io.IOException {
+    zzAtEOF = true;            /* indicate end of file */
+    zzEndRead = zzStartRead;  /* invalidate buffer    */
+
+    if (zzReader != null)
+      zzReader.close();
+  }
+
+
+  /**
+   * Resets the scanner to read from a new input stream.
+   * Does not close the old reader.
+   *
+   * All internal variables are reset, the old input stream 
+   * <b>cannot</b> be reused (internal buffer is discarded and lost).
+   * Lexical state is set to <tt>ZZ_INITIAL</tt>.
+   *
+   * @param reader   the new input stream 
+   */
+  public final void yyreset(java.io.Reader reader) {
+    zzReader = reader;
+    zzAtBOL  = true;
+    zzAtEOF  = false;
+    zzEndRead = zzStartRead = 0;
+    zzCurrentPos = zzMarkedPos = zzPushbackPos = 0;
+    yyline = yychar = yycolumn = 0;
+    zzLexicalState = YYINITIAL;
+  }
+
+
+  /**
+   * Returns the current lexical state.
+   */
+  public final int yystate() {
+    return zzLexicalState;
+  }
+
+
+  /**
+   * Enters a new lexical state
+   *
+   * @param newState the new lexical state
+   */
+  public final void yybegin(int newState) {
+    zzLexicalState = newState;
+  }
+
+
+  /**
+   * Returns the text matched by the current regular expression.
+   */
+  public final String yytext() {
+    return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead );
+  }
+
+
+  /**
+   * Returns the character at position <tt>pos</tt> from the 
+   * matched text. 
+   * 
+   * It is equivalent to yytext().charAt(pos), but faster
+   *
+   * @param pos the position of the character to fetch. 
+   *            A value from 0 to yylength()-1.
+   *
+   * @return the character at position pos
+   */
+  public final char yycharat(int pos) {
+    return zzBuffer[zzStartRead+pos];
+  }
+
+
+  /**
+   * Returns the length of the matched text region.
+   */
+  public final int yylength() {
+    return zzMarkedPos-zzStartRead;
+  }
+
+
+  /**
+   * Reports an error that occured while scanning.
+   *
+   * In a wellformed scanner (no or only correct usage of 
+   * yypushback(int) and a match-all fallback rule) this method 
+   * will only be called with things that "Can't Possibly Happen".
+   * If this method is called, something is seriously wrong
+   * (e.g. a JFlex bug producing a faulty scanner etc.).
+   *
+   * Usual syntax/scanner level error handling should be done
+   * in error fallback rules.
+   *
+   * @param   errorCode  the code of the errormessage to display
+   */
+  private void zzScanError(int errorCode) {
+    String message;
+    try {
+      message = ZZ_ERROR_MSG[errorCode];
+    }
+    catch (ArrayIndexOutOfBoundsException e) {
+      message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
+    }
+
+    throw new Error(message);
+  } 
+
+
+  /**
+   * Pushes the specified amount of characters back into the input stream.
+   *
+   * They will be read again by then next call of the scanning method
+   *
+   * @param number  the number of characters to be read again.
+   *                This number must not be greater than yylength()!
+   */
+  public void yypushback(int number)  {
+    if ( number > yylength() )
+      zzScanError(ZZ_PUSHBACK_2BIG);
+
+    zzMarkedPos -= number;
+  }
+
+
+  /**
+   * Contains user EOF-code, which will be executed exactly once,
+   * when the end of file is reached
+   */
+  private void zzDoEOF() throws java.io.IOException {
+    if (!zzEOFDone) {
+      zzEOFDone = true;
+      yyclose();
+    }
+  }
+
+
+  /**
+   * Resumes scanning until the next regular expression is matched,
+   * the end of input is encountered or an I/O-Error occurs.
+   *
+   * @return      the next token
+   * @exception   java.io.IOException  if any I/O-Error occurs
+   */
+  public Token yylex() throws java.io.IOException {
+    int zzInput;
+    int zzAction;
+
+    // cached fields:
+    int zzCurrentPosL;
+    int zzMarkedPosL;
+    int zzEndReadL = zzEndRead;
+    char [] zzBufferL = zzBuffer;
+    char [] zzCMapL = ZZ_CMAP;
+
+    int [] zzTransL = ZZ_TRANS;
+    int [] zzRowMapL = ZZ_ROWMAP;
+    int [] zzAttrL = ZZ_ATTRIBUTE;
+
+    while (true) {
+      zzMarkedPosL = zzMarkedPos;
+
+      boolean zzR = false;
+      for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL;
+                                                             zzCurrentPosL++) {
+        switch (zzBufferL[zzCurrentPosL]) {
+        case '\u000B':
+        case '\u000C':
+        case '\u0085':
+        case '\u2028':
+        case '\u2029':
+          yyline++;
+          yycolumn = 0;
+          zzR = false;
+          break;
+        case '\r':
+          yyline++;
+          yycolumn = 0;
+          zzR = true;
+          break;
+        case '\n':
+          if (zzR)
+            zzR = false;
+          else {
+            yyline++;
+            yycolumn = 0;
+          }
+          break;
+        default:
+          zzR = false;
+          yycolumn++;
+        }
+      }
+
+      if (zzR) {
+        // peek one character ahead if it is \n (if we have counted one line too much)
+        boolean zzPeek;
+        if (zzMarkedPosL < zzEndReadL)
+          zzPeek = zzBufferL[zzMarkedPosL] == '\n';
+        else if (zzAtEOF)
+          zzPeek = false;
+        else {
+          boolean eof = zzRefill();
+          zzEndReadL = zzEndRead;
+          zzMarkedPosL = zzMarkedPos;
+          zzBufferL = zzBuffer;
+          if (eof) 
+            zzPeek = false;
+          else 
+            zzPeek = zzBufferL[zzMarkedPosL] == '\n';
+        }
+        if (zzPeek) yyline--;
+      }
+      if (zzMarkedPosL > zzStartRead) {
+        switch (zzBufferL[zzMarkedPosL-1]) {
+        case '\n':
+        case '\u000B':
+        case '\u000C':
+        case '\u0085':
+        case '\u2028':
+        case '\u2029':
+          zzAtBOL = true;
+          break;
+        case '\r': 
+          if (zzMarkedPosL < zzEndReadL)
+            zzAtBOL = zzBufferL[zzMarkedPosL] != '\n';
+          else if (zzAtEOF)
+            zzAtBOL = false;
+          else {
+            boolean eof = zzRefill();
+            zzMarkedPosL = zzMarkedPos;
+            zzEndReadL = zzEndRead;
+            zzBufferL = zzBuffer;
+            if (eof) 
+              zzAtBOL = false;
+            else 
+              zzAtBOL = zzBufferL[zzMarkedPosL] != '\n';
+          }
+          break;
+        default:
+          zzAtBOL = false;
+        }
+      }
+      zzAction = -1;
+
+      zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
+  
+      if (zzAtBOL)
+        zzState = ZZ_LEXSTATE[zzLexicalState+1];
+      else
+        zzState = ZZ_LEXSTATE[zzLexicalState];
+
+
+      zzForAction: {
+        while (true) {
+    
+          if (zzCurrentPosL < zzEndReadL)
+            zzInput = zzBufferL[zzCurrentPosL++];
+          else if (zzAtEOF) {
+            zzInput = YYEOF;
+            break zzForAction;
+          }
+          else {
+            // store back cached positions
+            zzCurrentPos  = zzCurrentPosL;
+            zzMarkedPos   = zzMarkedPosL;
+            boolean eof = zzRefill();
+            // get translated positions and possibly new buffer
+            zzCurrentPosL  = zzCurrentPos;
+            zzMarkedPosL   = zzMarkedPos;
+            zzBufferL      = zzBuffer;
+            zzEndReadL     = zzEndRead;
+            if (eof) {
+              zzInput = YYEOF;
+              break zzForAction;
+            }
+            else {
+              zzInput = zzBufferL[zzCurrentPosL++];
+            }
+          }
+          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
+          if (zzNext == -1) break zzForAction;
+          zzState = zzNext;
+
+          int zzAttributes = zzAttrL[zzState];
+          if ( (zzAttributes & 1) == 1 ) {
+            zzAction = zzState;
+            zzMarkedPosL = zzCurrentPosL;
+            if ( (zzAttributes & 8) == 8 ) break zzForAction;
+          }
+
+        }
+      }
+
+      // store back cached position
+      zzMarkedPos = zzMarkedPosL;
+
+      switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
+        case 19: 
+          { commandBuffer.append(yytext());
+        debug("SQL '", yytext());
+        yybegin(SQL);
+          }
+        case 35: break;
+        case 9: 
+          { commandBuffer.setLength(0);
+    yybegin(SPECIAL);
+          }
+        case 36: break;
+        case 30: 
+          { pushbackTrim();
+        /* embedded comment may disable opening quotes and closing ; */
+        debug("Spl. -- Comment", yytext());
+          }
+        case 37: break;
+        case 10: 
+          { commandBuffer.setLength(0);
+    yybegin(EDIT);
+          }
+        case 38: break;
+        case 21: 
+          { yybegin(YYINITIAL);
+    debug("Gobbled", yytext());
+    prompt();
+          }
+        case 39: break;
+        case 31: 
+          { /* Ignore top-level traditional comments */
+    debug ("/**/ Comment", yytext());
+          }
+        case 40: break;
+        case 8: 
+          { return new Token(Token.SQL_TYPE, yyline);
+          }
+        case 41: break;
+        case 2: 
+          { prompt();
+          }
+        case 42: break;
+        case 22: 
+          { if (commandBuffer.toString().trim().equals(".")) {
+        commandBuffer.setLength(0);
+        yybegin(RAW);
+        rawLeadinPrompt();
+        if (rawPrompt != null) prompt(rawPrompt);
+    } else {
+        requestedState = YYINITIAL;
+        yybegin(PROMPT_CHANGE_STATE);
+        pushbackTrim();
+        return new Token(Token.SPECIAL_TYPE, commandBuffer, yyline);
+    }
+          }
+        case 43: break;
+        case 28: 
+          { specialAppendState = false;
+        commandBuffer.append(yytext());
+        /* embedded comment may disable opening quotes and closing ; */
+        debug("SQL -- Comment", yytext());
+          }
+        case 44: break;
+        case 17: 
+          { if (commandBuffer.length() > 0) commandBuffer.append('\n');
+        commandBuffer.append(strippedYytext());
+        if (rawPrompt != null) prompt(rawPrompt);
+          }
+        case 45: break;
+        case 26: 
+          { yybegin(requestedState);
+    prompt();
+          }
+        case 46: break;
+        case 4: 
+          { commandBuffer.setLength(0);
+    yybegin(MACRO);
+          }
+        case 47: break;
+        case 6: 
+          { /* Ignore top-level whte space */
+    debug("Whitespace", yytext());
+          }
+        case 48: break;
+        case 18: 
+          { commandBuffer.append(yytext());
+          }
+        case 49: break;
+        case 11: 
+          { specialAppendState = false;
+        commandBuffer.append(yytext());
+          }
+        case 50: break;
+        case 25: 
+          { requestedState = YYINITIAL;
+    yybegin(PROMPT_CHANGE_STATE);
+    pushbackTrim();
+    return new Token(Token.MACRO_TYPE, commandBuffer, yyline);
+          }
+        case 51: break;
+        case 16: 
+          { if (interactive && !specialAppendState) {
+            requestedState = YYINITIAL;
+            yybegin(PROMPT_CHANGE_STATE);
+            pushbackTrim();
+            trimBuffer();
+            return new Token(Token.BUFFER_TYPE, commandBuffer, yyline);
+        }
+        specialAppendState = false;
+        commandBuffer.append(yytext());
+          }
+        case 52: break;
+        case 29: 
+          { yybegin(YYINITIAL);
+        prompt();
+        return new Token(Token.RAWEXEC_TYPE, commandBuffer, yyline);
+          }
+        case 53: break;
+        case 27: 
+          { yybegin(YYINITIAL);
+        prompt();
+        return new Token(Token.RAW_TYPE, commandBuffer, yyline);
+          }
+        case 54: break;
+        case 14: 
+          { specialAppendState = false;
+        yybegin(YYINITIAL);
+        return new Token(Token.SQL_TYPE, commandBuffer, yyline);
+          }
+        case 55: break;
+        case 33: 
+          { /* embedded comment may disable opening closing \n */
+        debug("Spl. /**/ Comment", yytext());
+          }
+        case 56: break;
+        case 3: 
+          { yybegin(GOBBLE);
+    return new Token(Token.SYNTAX_ERR_TYPE, yytext(), yyline);
+          }
+        case 57: break;
+        case 20: 
+          { commandBuffer.append(yytext());
+        yybegin(SQL);
+        debug("SQL \"", yytext());
+          }
+        case 58: break;
+        case 1: 
+          { setCommandBuffer(yytext());
+    yybegin(SQL);
+          }
+        case 59: break;
+        case 23: 
+          { requestedState = YYINITIAL;
+    yybegin(PROMPT_CHANGE_STATE);
+    pushbackTrim();
+    return new Token(Token.PL_TYPE, commandBuffer, yyline);
+          }
+        case 60: break;
+        case 12: 
+          { specialAppendState = false;
+        commandBuffer.append(yytext());
+        if (sqlPrompt != null) prompt(sqlPrompt);
+          }
+        case 61: break;
+        case 24: 
+          { requestedState = YYINITIAL;
+    yybegin(PROMPT_CHANGE_STATE);
+    pushbackTrim();
+    return new Token(Token.EDIT_TYPE, commandBuffer, yyline);
+          }
+        case 62: break;
+        case 7: 
+          { debug ("-- Comment", yytext());
+          }
+        case 63: break;
+        case 15: 
+          { specialAppendState = false;
+        commandBuffer.append(yytext());
+        yybegin(SQL_SINGLE_QUOTED);
+          }
+        case 64: break;
+        case 5: 
+          { commandBuffer.setLength(0);
+    yybegin(PL);
+          }
+        case 65: break;
+        case 34: 
+          { /* These are commands which may contain nested commands and/or which
+     * require the closing semicolon to sent to the DB engine.
+     * The BEGIN and DECLARE needed for PL/SQL probably do not need to
+     * terminate the line, as we have it specified here, but I'd rather not be
+     * too liberal with proprietary SQL like this, because it's easy to
+     * envision other proprietary or non-proprietary commands beginning with
+     * DECLARE or BEGIN. */
+    setCommandBuffer(strippedYytext());
+    yybegin(RAW);
+    rawLeadinPrompt();
+    if (rawPrompt != null) prompt(rawPrompt);
+          }
+        case 66: break;
+        case 32: 
+          { specialAppendState = false;
+        commandBuffer.append(yytext());
+        /* embedded comment may disable opening quotes and closing ; */
+        debug("SQL /**/ Comment", yytext());
+          }
+        case 67: break;
+        case 13: 
+          { specialAppendState = false;
+        commandBuffer.append(yytext());
+        yybegin(SQL_DOUBLE_QUOTED);
+          }
+        case 68: break;
+        default: 
+          if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
+            zzAtEOF = true;
+            zzDoEOF();
+            switch (zzLexicalState) {
+            case SPECIAL: {
+              yybegin(YYINITIAL);
+    return new Token(Token.UNTERM_TYPE, commandBuffer, yyline);
+            }
+            case 115: break;
+            case SQL_DOUBLE_QUOTED: {
+              yybegin(YYINITIAL);
+    return new Token(Token.UNTERM_TYPE, commandBuffer, yyline);
+            }
+            case 116: break;
+            case SQL_SINGLE_QUOTED: {
+              yybegin(YYINITIAL);
+    return new Token(Token.UNTERM_TYPE, commandBuffer, yyline);
+            }
+            case 117: break;
+            case SQL: {
+              yybegin(YYINITIAL);
+    return new Token(Token.UNTERM_TYPE, commandBuffer, yyline);
+            }
+            case 118: break;
+            case EDIT: {
+              yybegin(YYINITIAL);
+    return new Token(Token.UNTERM_TYPE, commandBuffer, yyline);
+            }
+            case 119: break;
+            case PL: {
+              yybegin(YYINITIAL);
+    return new Token(Token.UNTERM_TYPE, commandBuffer, yyline);
+            }
+            case 120: break;
+            case MACRO: {
+              yybegin(YYINITIAL);
+    return new Token(Token.UNTERM_TYPE, commandBuffer, yyline);
+            }
+            case 121: break;
+            default:
+            return null;
+            }
+          } 
+          else {
+            zzScanError(ZZ_NO_MATCH);
+          }
+      }
+    }
+  }
+
+
+}
diff --git a/src/org/hsqldb/cmdline/sqltool/SqlTool.syntax.text b/src/org/hsqldb/cmdline/sqltool/SqlTool.syntax.text
new file mode 100644
index 0000000..2ad9760
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/SqlTool.syntax.text
@@ -0,0 +1,26 @@
+Syntax: java org.hsqldb.cmdline.SqlTool [--opt[=optval]...] urlid [file1.sql...]
+    urlid                    ID of connection settings in rcfile.
+                             '-' means to not connect to any data source
+    file1.sql...             SQL files to be executed [stdin]
+                             '-' means non-interactive stdin.
+OR: java org.hsqldb.cmdline.SqlTool [--opt[=optval]...]
+    (Precisely equivalent to the first case, with urlid of '-' and no SQL files)
+Options:
+    --help                   Displays this message
+    --autoCommit             Auto-commit JDBC DML commands
+    --continueOnErr=true|false  Continue (if true) or Abort (false) upon errors
+    --debug                  Print Debug info to stderr
+    --driver=a.b.c.Driver    JDBC driver class [%{2}]
+    --inlineRc=url=val1,user=val2[,asetting=val3...][,password=]
+                             Inline RC variables (use --driver for driver)
+    --list                   List urlids in the rc file
+    --noAutoFile             Do not execute auto.sql from home dir
+    --noInput                Do not read stdin (default if sql file given
+                             or --sql switch used).
+    --rcFile=/file/path.rc   Connect Info File [$HOME/sqltool.rc]
+    --setVar=NAME1=val1[,NAME2=val2...]   PL variables
+    --sql="SQL; Statements;" Execute given SQL instead of stdin (before
+                             SQL files if any are specified) where "SQL"
+                             consists of SQL command(s).  See the Guide.
+    --stdInput               Read stdin IN ADDITION to sql files/--sql input
+SqlTool v. %{1}.  The invocation samples assume you have set up 'CLASSPATH'.
diff --git a/src/org/hsqldb/cmdline/sqltool/SqlTool.syntax_de.text b/src/org/hsqldb/cmdline/sqltool/SqlTool.syntax_de.text
new file mode 100644
index 0000000..40bd31a
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/SqlTool.syntax_de.text
@@ -0,0 +1,23 @@
+Syntax: java org.hsqldb.cmdline.SqlTool [--opt[=optwert]...] urlid [datei1.sql...]
+Optionen:
+    --help                   Gibt diese Hilfe aus.
+    --list                   Zeigt urlids aus der RC-Datei an.
+    --noInput                Nicht von stdin lesen (Standardeinstellung wenn
+                             SQL-Datei angegeben oder der Schalter --sql benutzt wird).
+    --stdInput               Liest von stdin ZUSÄTZLICH zu SQL-Dateien/--sql Eingabe.
+    --inlineRc=url=val1,user=val2[,x=val3...][,password=]  Inline RC-Variablen
+    --debug                  Gibt Debug Infos auf stderr aus.
+    --noAutoFile             Führt die Datei auto.sql im Home-Verzeichniss nicht aus.
+    --autoCommit             Auto-commit JDBC DML Befehle
+    --sql="SQL; Anweisungen;" Führt die angegebene SQL-Anweisung aus statt von stdin zu lesen
+    						 (bevor SQL-Dateien - wenn angegeben - ausgeführt werden)
+    						  wobei 'SQL' aus SQL-Befehlen gebildet wird. Siehe Handbuch.
+    --rcFile=path/file.rc    Verwende Info-Datei [$HOME/sqltool.rc]
+    --continueOnErr=true|false Weiter (true) oder Abbrechen (false) nach Fehler.          
+    --setVar=NAME1=val1[,NAME2=val2...]   PL Variablen
+    --driver=a.b.c.Driver    JDBC Treiber Class [%{2}]
+    urlid                    ID von Url/Benutzername/Passwort in der RC-Datei
+    datei1.sql...            SQL Dateien auszuführen  [stdin]
+                             (Benutzen Sie '-' für Nicht-Interaktives stdin!).
+Lesen Sie das SqlTool Handbuch für unterstützte sqltool.* Systemeigenschaften.
+SqlTool v. %{1}.
diff --git a/src/org/hsqldb/cmdline/sqltool/Token.java b/src/org/hsqldb/cmdline/sqltool/Token.java
new file mode 100644
index 0000000..85400e3
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/Token.java
@@ -0,0 +1,147 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.cmdline.sqltool;
+
+/* @(#)$Id: Token.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+public class Token {
+    public static final int SQL_TYPE = 0;
+    public static final int SPECIAL_TYPE = 1;
+    public static final int PL_TYPE = 2;
+    public static final int EDIT_TYPE = 3;
+    public static final int RAW_TYPE = 4;
+    public static final int RAWEXEC_TYPE = 5;
+    public static final int SYNTAX_ERR_TYPE = 6;
+    public static final int UNTERM_TYPE = 7;
+    public static final int BUFFER_TYPE = 8;
+    public static final int MACRO_TYPE = 9;
+    public int line;
+    public TokenList nestedBlock = null;
+
+    public String[] typeString = {
+        "SQL", "SPECIAL", "PL", "EDIT", "RAW", "RAWEXEC", "SYNTAX",
+        "UNTERM", "BUFFER", "MACRO"
+    };
+    public char[] typeChar = {
+        'S', '\\', '*', 'E', 'R', 'X', '!', '<', '>', '/'
+    };
+
+    public String getTypeString() {
+        return typeString[type];
+    }
+    public char getTypeChar() {
+        return typeChar[type];
+    }
+
+    public String val;
+    public int type;
+    public Token(int inType, String inVal, int inLine) {
+        val = inVal; type = inType; line = inLine + 1;
+        switch (inType) {
+            case SPECIAL_TYPE:
+            case EDIT_TYPE:
+            case PL_TYPE:
+            case MACRO_TYPE:
+                // These types must be not null.  May be just whitespace.
+                // Will be trimmed.
+                if (val == null) throw new IllegalArgumentException(
+                        "Null String value for scanner token");
+                val = val.trim();  // Worry about efficiency later
+                break;
+
+            case SYNTAX_ERR_TYPE:
+            case BUFFER_TYPE:
+            case RAW_TYPE:
+            case RAWEXEC_TYPE:
+            case UNTERM_TYPE:
+                // These types must be not null.  May be just whitespace.
+                // Will NOT be trimmed.
+                if (val == null) throw new IllegalArgumentException(
+                        "Null String value for scanner token");
+                break;
+
+            case SQL_TYPE:
+                // These types may be anything (null, whitespace, etc.).
+                // Will NOT be trimmed
+                break;
+
+            default: throw new IllegalArgumentException(
+                "Internal error.  Unexpected scanner token type: " + inType);
+        }
+    }
+
+    public Token(int inType, StringBuffer inBuf, int inLine) {
+        this(inType, inBuf.toString(), inLine);
+    }
+
+    public Token(int inType, int inLine) {
+        this(inType, (String) null, inLine);
+    }
+
+    public String toString() { return "@" + line
+            + " TYPE=" + getTypeString() + ", VALUE=(" + val + ')';
+    }
+
+    /**
+     * Equality ignores the line number
+     */
+    public boolean equals(Token otherToken) {
+        if (type != otherToken.type) return false;
+        if (val == null && otherToken.val != null) return false;
+        if (val != null && otherToken.val == null) return false;
+        if (val != null && !val.equals(otherToken.val)) return false;
+        return true;
+    }
+
+    /*
+     * Convenience wrapper for brevity.
+     */
+    public String reconstitute() {
+        return reconstitute(false);
+    }
+
+    /*
+     * A command string generated from val and type which can hopefully be
+     * re-executed.
+     */
+    public String reconstitute(boolean semify) {
+        if (val == null) return "";
+        switch (type) {
+            case Token.SPECIAL_TYPE:
+            case Token.PL_TYPE:
+                return Character.toString(getTypeChar()) + val;
+            case Token.SQL_TYPE:
+                return val + (semify ? ";" : "");
+        }
+        return "? " + val;
+    }
+}
diff --git a/src/org/hsqldb/cmdline/sqltool/TokenList.java b/src/org/hsqldb/cmdline/sqltool/TokenList.java
new file mode 100644
index 0000000..ab1d253
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/TokenList.java
@@ -0,0 +1,60 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.cmdline.sqltool;
+
+import java.util.ArrayList;
+
+/* @(#)$Id: TokenList.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/**
+ * A list of SqlFile Tokens
+ */
+public class TokenList extends ArrayList<Token> implements TokenSource {
+    static final long serialVersionUID = 5441418591320947274L;
+
+    public TokenList() {
+        super();
+    }
+    public TokenList(TokenList inList) {
+        super(inList);
+    }
+    public Token yylex() {
+        if (size() < 1) return null;
+        //return remove(0);
+        // Java5
+        return remove(0);
+    }
+
+    public TokenList dup() {
+        return new TokenList(this);
+    }
+}
diff --git a/src/org/hsqldb/cmdline/sqltool/TokenSource.java b/src/org/hsqldb/cmdline/sqltool/TokenSource.java
new file mode 100644
index 0000000..61db25c
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/TokenSource.java
@@ -0,0 +1,40 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.cmdline.sqltool;
+
+import java.io.IOException;
+
+/* @(#)$Id: TokenSource.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+public interface TokenSource {
+    public Token yylex() throws IOException;
+}
diff --git a/src/org/hsqldb/cmdline/sqltool/buffer.help.text b/src/org/hsqldb/cmdline/sqltool/buffer.help.text
new file mode 100644
index 0000000..6dc2f53
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/buffer.help.text
@@ -0,0 +1,33 @@
+EDIT BUFFER AND HISTORY COMMANDS.  Not available for non-interactive use.
+    :?                Edit buffer / history Help
+    :b                List current contents of edit Buffer
+    :h                Show History of previous commands (plus buffer contents)
+    :X  (integer X)   Load command #X from Command history into the Edit buffer
+    :-Y  (integer -Y) Same an editY means Y commands back
+    :/regex/          Same as :-Y, except it means latest command in history
+                      matching the given regular expression
+The remaining edit/execute commands all operate on the Edit Buffer by default,
+but will also operate on any command from history if you interpose a command
+identifier right after the colon, like ":/blue/;" to re-execute the last
+command you ran which contains "blue", or ":w -3 /tmp/output.txt" to append
+the third command 'back' to a file.
+    :;                Execute edit buffer content (special, PL, or SQL command)
+    :a[text]          Enter append mode with a copy of the buffer contents
+    :s/from regex/to/ Substitute match of "from regex" with "to"
+    :s/from/to/[igm;] One or multiple Substitutions with specified options
+                from:  Standard regexp.  See 'perlre' man page or
+                       Java API spec for java.util.regex.Pattern.
+                to:    If empty, from's will be deleted (e.g. ":s/x//").
+                [igm;] Options work exactly as in Perl or java.util.regex,
+                       except ';' means to execute after substitution,
+                       'g' means Global (multiple) substitutions,
+                       and option 's' is always on.
+                /:     Can actually be any character which occurs in
+                       neither "to" string nor "from" string.
+                SUBSTITUTION MODE SWITCHES:
+                       i:  case Insensitive
+                       g:  Global (substitute ALL occurrences of "from" string)
+                       m:  ^ and $ match line breaks (like Perl m option)
+                       ;:  execute immediately after substitution
+    :w file/path.sql  Append current buffer contents to the specified file
+
diff --git a/src/org/hsqldb/cmdline/sqltool/buffer.help_de.text b/src/org/hsqldb/cmdline/sqltool/buffer.help_de.text
new file mode 100644
index 0000000..22cde3b
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/buffer.help_de.text
@@ -0,0 +1,31 @@
+EDITIER-PUFFER UND VERLAUFSBEFEHLE.  Nur während der interaktiven Benutzung vorhanden.
+    :?                Editier-Puffer/Verlauf - Hilfe
+    :h                Zeigt Befehlsverlauf (sowie Editier-Pufferinhalt) an
+    :b                Zeigt den aktuellen Inhalt des Editier-Puffer an
+    :X  (Ganzzahl X)  Lädt Befehl Nr. X aus dem Verlauf in den Editier-Puffer
+    :-Y (Ganzzahl -Y) Wie :X, nur geht -Y entsprechend Y Befehle zurück
+Die restlichen Editier/Verlaufsbefehle arbeiten standardmäßig alle im Editier-Puffer,
+sie können aber auch auf jeden Befehl im Verlaufsspeicher angewendet werden, wenn 
+Sie nach dem Doppelpunkt ein Muster angeben, welches auf den gesuchten Befehl zutrifft;
+wie z.B.: ":blau;" um den letzten Befehl der "blau" enthielt nochmal auszuführen.
+Oder "w -3 /tmp/befehl.txt" um den drittletzten Befehl an die Datei befehl.txt anzuhängen. 
+    :;                 Führt den Editier-Pufferinhalt aus (Spezial, PL oder SQL-Befehl)
+    :w datei/pfad.sql  Aktuellen Editier-Pufferinhalt an Datei anhängen.
+    :a[text]           In den Anhängemodus wechseln mit einer Kopie des Pufferinhaltes.
+    :s/von regex/zu/   Ersetzt alle Übereinstimmungen "von regex" mit  "zu".
+    :s/von/zu/[igm;]   Ein oder Mehrfachersetzung mit mehreren Optionen.
+                von:   Regulärer Ausdruck.  
+                	   Siehe auch 'perlre'-Manpage oder Java API Spezifikation für java.util.regex.Pattern!
+                zu:    Wenn leer - dann werden alle "von"`s gelöscht (z.b. ":s/x//").
+                [igm;] Diese Optionen arbeiten genau wie in Perl oder java.util.regex 
+                	   ausgenommen ';', bedeutet nach der Ersetzung ausführen.
+                       Die Option 'g' bedeutet das alle (Global) Treffer ersetzt werden;
+                       's' ist ist immer aktiv.
+                /:     Kann beliebiges Zeichen sein,
+                       welches weder im "von" noch "zu" Begriff vorkommt.
+                SUBSTITUTIONS-SCHALTER:
+                       i:  ignoriert Groß/Kleinschreibung
+                       g:  Global (alle Treffer ersetzen)
+                       m:  ^ und $ bezeieht sich auf den Zeilenanfang und Ende (siehe Perl 'm' Option)
+                       ;:  Ausführung nach der Ersetzung
+
diff --git a/src/org/hsqldb/cmdline/sqltool/d.options.text b/src/org/hsqldb/cmdline/sqltool/d.options.text
new file mode 100644
index 0000000..a8df060
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/d.options.text
@@ -0,0 +1,22 @@
+\dX [parameter...] where X is one of the following.
+    a:  list Aliases
+    i:  list Indexes (for some databases, must specify literal target table)
+    n:  list schema Names
+    r:  list Roles
+    s:  list Sequences
+    S:  list System tables
+    t:  list Tables
+    u:  list Users
+    v:  list Views
+    *:  list table-like objects
+In most cases, 'parameter...' is a case-specific SUBSTRING to narrow matches.
+The following details apply to those commands which list schema objects.
+By default, objects in all schemas will be listed (excepting some exclusions
+for system schemas or system objects), with filtering if specified.
+If a filter param is supplied and begins with a dot, then the search is
+narrowed to the session's current schema.
+If the filter param contains a dot in any other position, then the characters
+before the dot specify a literal and case-sensitive schema name.
+Some or all of these dot filters will not work if your database doesn't support
+schemas according to the SQL specifications.
+
diff --git a/src/org/hsqldb/cmdline/sqltool/d.options_de.text b/src/org/hsqldb/cmdline/sqltool/d.options_de.text
new file mode 100644
index 0000000..f428486
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/d.options_de.text
@@ -0,0 +1,12 @@
+\dX [Parameter...] wobei X eine der folgenden Möglichkeiten ist:
+    t:  Auflistung von Tabellen
+    v:  Auflistung von Views
+    s:  Auflistung von Sequenzen
+    i:  Auflistung von Indizes
+    S:  Auflistung von Systemtabellen
+    a:  Auflistung von Aliasse
+    n:  Auflistung von Schemanamen
+    u:  Auflistung von Benutzern
+    r:  Auflistung von Rollen
+    *:  Auflistung von tabellenähnlichen Objekten
+
diff --git a/src/org/hsqldb/cmdline/sqltool/dsv.options.text b/src/org/hsqldb/cmdline/sqltool/dsv.options.text
new file mode 100644
index 0000000..5992ded
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/dsv.options.text
@@ -0,0 +1,35 @@
+DSV stands for Delimiter-Separated-Values, which is just CSV (comma-
+separated-values) but always using a proper delimiter to prevent the
+need for quoting and escaping which CSV files have.
+All of the DSV PL variables are optional.  To see all PL var. values,
+run "* listvalues".  Set the values like:
+    * *DSV_COL_DELIM = ,
+Don't forget the * indicating a PL command PLUS the leading * in
+all of these variable names.  \x or \m below indicates where
+the setting is applicable.  Default value/behavior is in [square brackes].
+    *DSV_COL_SPLITTER  \m    Column input delimiter regexp.   ["\|"]
+    *DSV_COL_DELIM     \x    Column output delimiter.   ["|"]
+    *DSV_CONST_COLS    \m    Column values to write to every row.   [None]
+    *DSV_RECORDS_PER_COMMIT \m  Set to integer value (X).  Overrides current
+                             auto-commit setting and commits after every X
+                             successful inserts (and upon import completion).
+    *DSV_REJECT_FILE   \m    DSV file to be created with rejected records.
+                              [None*]
+    *DSV_REJECT_REPORT \m    HTML report to explain reject records [None*]
+    *DSV_ROW_SPLITTER  \m    Row input delimiter regexp.   ["\r\n|\r|\n"]
+    *DSV_ROW_DELIM     \x    Row output delimiter
+                              [OS-dependent (Java line.separator)]
+    *DSV_SKIP_COLS     \m\x  Skip columns from input DSV file or input table.
+    *DSV_SKIP_PREFIX   \m    Comment line prefix in DSV files.  ["#"]
+    *DSV_TARGET_FILE   \x    File which exports will write to
+                              [source table name + ".dsv"]
+    *DSV_TARGET_TABLE  \m    Table which imports will write to
+                              [DSV filename without extension]
+    *DSV_TRIM_ALL      \m    If set to "true", trim leading and trailing
+                             whitespace from all columns upon import [false]
+    *NULL_REP_TOKEN    \m\x  String to represent database null.   ["[null]"]
+* Imports will abort immediately upon the first import record failure, unless
+either *DSV_REJECT_FILE or *DSV_REJECT_REPORT (or both) are set.  (Whether
+SqlTool will roll back and quit depends on your settings for \c and \a).
+Auto-commit and *DSV_RECORDS_PER_COMMIT ensure that all successfully inserted
+records will commit, so rollbacks are impossible with either of these.
diff --git a/src/org/hsqldb/cmdline/sqltool/dsv.options_de.text b/src/org/hsqldb/cmdline/sqltool/dsv.options_de.text
new file mode 100644
index 0000000..ddc2903
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/dsv.options_de.text
@@ -0,0 +1,39 @@
+DSV bedeutet Delimiter-Separated-Values (dt. etwa:Trennzeichen-getrennte Werte).
+Es ist im Grunde genommen CSV (Comma Separated Values), DSV verwendet aber als Trennzeichen
+nur Zeichen welche sonst nicht im Text vorkommen. Auf diese Weise wird
+die bei CSV oft notwendige Maskierung von Trennzeichen im Text umgangen.    
+Alle DSV PL-Variablen sind optional.
+Um sich den Inhalt einer PL-Variable anzeigen zu lassen, geben Sie 
+"* listvalues" ein (ohne die "").
+Um einer Variable einen Wert zu zuweisen: "* *DSV_COL_DELIM = ,"
+Bitte vergessen Sie nicht, das erste * leitet eine PL-Variable ein und
+das zweite * steht am Beginn eines jeden Variablennamens.
+\x oder \m im folgenden zeigen an wo die Einstellung anwendbar ist.
+Der Standardwert/Verhalten steht in den [quadratischen Klammern].
+    *DSV_SKIP_PREFIX   \m      Das Vorzeichen, das eine Kommentarzeile in der Datei einleitet. ["#"]
+    *DSV_COL_SPLITTER  \m      Das Spaltentrennzeichen fürs Einlesen als Regex.   ["\|"]
+    *DSV_COL_DELIM     \x      Das Spaltentrennzeichen für die Ausgabe.   ["|"]
+    *DSV_ROW_SPLITTER  \m      Das Zeilentrennzeichen fürs Einlesen als Regex. ["\r\n|\r|\n"]
+    *DSV_ROW_DELIM     \x      Das Zeilentrennzeichen für die Ausgabe.
+                               [Betriebssystem-abhängig (Java-System Property line.separator)]
+    *NULL_REP_TOKEN    \m\x    Zeichenkette, um eine Datenbank-null darzustellen.
+                               ["[null]"]
+    *DSV_TARGET_FILE   \x      Der Name der Zieldatei. [Name Quelltabelle + ".dsv"]
+    *DSV_TARGET_TABLE  \m      Name der Tabelle in welche die Daten importiert werden.
+                               [DSV-Dateiname ohne Dateiendung]
+    *DSV_CONST_COLS    \m      Spalteninhalt, welcher in jede Reihe geschrieben wird.
+    *DSV_REJECT_FILE   \m      DSV-Datei, in die alle abgelehnten Datensätze geschrieben werden. [None*]
+    *DSV_REJECT_REPORT \m      HTML-Bericht mit den Gründen für abgelehnten Datensätze. [None*]
+    *DSV_SKIP_COLS     \m\x    Spalten aus der Eingabedatei/Tabelle welche ausgelassen werden.
+    *DSV_TRIM_ALL      \m      Wenn auf "true" gesetzt, werden alle führenden und abschließenden
+    						   Leerzeichen aus allen Spalten nach dem import entfernt. [false]
+    *DSV_RECORDS_PER_COMMIT \m Integer-Wert (X). Wird er gesetzt, so überschreibt er die aktuelle 
+    						   Autocommit Einstellung, es wird nun nach X erfolgreichen INSERTS
+    						   commitet (sowie nach Abschluss des Imports).
+* Das Importieren wird sofort nach dem ersten fehlerhaften Ipmort eines Datensatzes abgebrochen,
+es sei den die Variablen *DSV_REJECT_FILE und/oder *DSV_REJECT_REPORT sind gesetzt.
+(Die "Rollback"-Funktion (Rückgängig machen) des SqlTols hängt von der Verwendung der Optionen 
+\c und \z ab.) 
+Auto-commit und *DSV_RECORDS_PER_COMMIT stellen sicher das alle erfolgreich eingefügten Datensätze
+auch commitet werden - Rollbacks sind dann aber nicht mehr möglich.
+
diff --git a/src/org/hsqldb/cmdline/sqltool/errorat.text b/src/org/hsqldb/cmdline/sqltool/errorat.text
new file mode 100644
index 0000000..60c8b1e
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/errorat.text
@@ -0,0 +1,3 @@
+Error at '%{1}' line %{2}:
+%{3:+"%3"
+}%{4}
diff --git a/src/org/hsqldb/cmdline/sqltool/errorat_de.text b/src/org/hsqldb/cmdline/sqltool/errorat_de.text
new file mode 100644
index 0000000..eef4eab
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/errorat_de.text
@@ -0,0 +1,3 @@
+Fehler an '%{1}' Zeile %{2}:
+%{3:+"%3"
+}%{4}
diff --git a/src/org/hsqldb/cmdline/sqltool/macro.help.text b/src/org/hsqldb/cmdline/sqltool/macro.help.text
new file mode 100644
index 0000000..b2b4f6e
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/macro.help.text
@@ -0,0 +1,8 @@
+/?                     Display this help
+/=                     Display all macros
+/= name command...     Define a macro equal to the specified SQL command
+                         (do not type the terminating ";").
+/= name :[appendage]   Define a macro equal to the current buffer contents
+/name [appendage]      Expand macro to buffer
+/name [appendage];     Execute macro
+
diff --git a/src/org/hsqldb/cmdline/sqltool/macro.help_de.text b/src/org/hsqldb/cmdline/sqltool/macro.help_de.text
new file mode 100644
index 0000000..1568602
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/macro.help_de.text
@@ -0,0 +1,9 @@
+/?                     Zeigt diesen Hilfetext an
+/=                     Zeigt alle Makros
+/= Name Befehl...      Definieren Sie ein Makro zu dem angebenen
+                       SQL-Befehl.  (Kein ";" eingeben!).
+/= Name :[Anhang]      Definieren Sie ein Makro zum aktuellen
+                       Puffer-Inhalt
+/Name [Anhang]         Laden Sie das Makro in den Puffer
+/Name [Anhang];        Führen Sie das Makro aus
+
diff --git a/src/org/hsqldb/cmdline/sqltool/pl.help.text b/src/org/hsqldb/cmdline/sqltool/pl.help.text
new file mode 100644
index 0000000..2f67a4a
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/pl.help.text
@@ -0,0 +1,36 @@
+PROCEDURAL LANGUAGE COMMANDS
+    *?                            PL Help
+    *                             Expand PL variables from now on.
+                                  (this is also implied by all the following).
+    * VARNAME = Variable value    Set variable value
+    * VARNAME =                   Unset variable
+    * VARNAME ~                   Set variable value to the value of the very
+                                  next SQL value or count fetched (see details
+                                  at the bottom of this listing).
+    * VARNAME _                   Same as * VARNAME _, except the query is
+                                  done silently (i.e, no rows to screen)
+    * break [foreach|if|while|file] Exits a PL block or file early
+    * continue [foreach|while]    Exits a PL block iteration early
+    * dump VARNAME path.txt       Dump variable value to text file
+    * end foreach|if|while        Ends a PL block
+    * foreach VARNAME ([val1...]) Repeat the following PL block with the
+                                  variable set to each value in turn.
+    * if (logical expr)           Execute following PL block only if expr true
+    * list[values] [VARNAME1...]  List PL variable(s) (defaults to all)
+    * listsysprops [VARNAME1...]  List Java System property(s) (defaults to all)
+    * load VARNAME path.txt       Load variable value from text file
+    * prepare VARNAME             Use ? in next SQL statement to upload val.
+                                  (Just "?", "*{?}" would mean the auto var.).
+    * while (logical expr)        Repeat following PL block while expr true
+
+Use PL variable values (which have been set) like: *{VARNAME}.
+Use System Property values (which you may not set) like: ${property.name}.
+You may use /VARNAME instead iff /VARNAME is the first word of a SQL command.
+Use PL variables in logical expressions, like (*VARNAME == 1).
+Auto. variable ? is set to the very next SQL datum fetched (or update count).
+    Query:  The value of the first field of the first row returned.
+    other:  Return status of the command (for updates this will be
+            the number of rows updated).
+'* VARNAME ~' or '* VARNAME _' sets the specified variable's value exactly
+like ?.  (~ will echo the value, _ will do it silently).
+
diff --git a/src/org/hsqldb/cmdline/sqltool/pl.help_de.text b/src/org/hsqldb/cmdline/sqltool/pl.help_de.text
new file mode 100644
index 0000000..7fc4618
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/pl.help_de.text
@@ -0,0 +1,41 @@
+PROZEDUALE SPRACHE (PROCEDURAL LANGUAGE) BEFEHLE
+    *?                             PL Hilfe
+    *                              PL-Variablen ab sofort erweitern.  (Dies
+                                   ist auch bei alle folgenden Befehlen inbegriffen ).
+    * VARNAME = Variable Wert      Weist der Variable einen Wert zu.
+    * VARNAME =                    Löscht die Variable.
+    * VARNAME ~                    Weist der Variable als Wert den Inhalt der direkt
+                                   folgenden SQL-Anweiung oder eines Zählers zu (Bitte beachten
+                                   Sie auch die Hinweise am Ende der Auflistung ).
+    * VARNAME _                    Dasselbe wie * VARNAME _, nur das die Abfrage
+                                   keine Ausgabe erzeugt (d.h, es werden keine Zeilen angezeigt).
+    * list[values] [VARNAME1...]   Listet PL-Variable(n) auf (standardmäßig alle).
+    * listsysprops [VARNAME1...]   Listet die System-Properties von Java auf (standardmäßig alle).
+    * load VARNAME datei.txt       Lädt Variable aus einer Textatei.
+    * dump VARNAME datei.txt       Schreibt die Variable in eine Textdatei.
+    * prepare VARNAME              Verwenden Sie ? in der nächsten SQL-Anweisung
+                                   um die Variable an dieser Stelle einzusetzten (bei "*{?}" wird die Standardvariable verwendet).
+    * foreach VARNAME ([wert1...]) Wiederholt den folgenden PL-Block pro Wert mit der
+                                   Variable, wobei diese im PL-Block jeweils durch den Wert ersetzt wird.
+    * if (logical expr)            Führt den folgenden PL-Block nur aus wenn der Ausdruck
+                                   in Klammern wahr ist.
+    * while (logical expr)         Wiederholt den folgenden PL-Block solange wie der Ausdruck
+    							   in den Klammern wahr ist.
+    * end foreach|if|while         Beendent einen PL-Block.
+    * break [foreach|if|while|file]Unterbricht einen PL-Block vorzeitig. 
+    * continue [foreach|while]     Bricht einen Schleifendurch in einem PL-Block ab und fährt 
+    							   mit dem nächsten Durchlauf fort.
+
+Verwenden Sie PL-Variablen (die Sie gesetzt haben) wie folgt: *{VARNAME}.
+Verwenden Sie Systemeigenschaften (auch wenn Sie sie vlt. nicht gesetzt haben) so: ${property.name}.
+Sie können /VARNAME benutzen, wenn /VARNAME das erste Wort im SQL-Befehl ist.
+In logischen Ausdrücken verwenden Sie PL-Variablen so: (VARNAME == 1).
+Die automatische Variable ? bezieht sich immmer auf die jüngste SQL-Anweisung 
+(oder Updatezähler).
+    Abfrage:  Der Wert des ersten Feldes aus der ersten Reihe welche zurück gegeben wurde.
+    sonstige: Rückgabewert eines Befehls (bei Updates ist dies die Zahl
+              der aktualisierten Reihen).
+
+'* VARNAME ~' or '* VARNAME _' setzt den jeweiligen Wert der Variable exakt.
+genau wie  ?.  (~ zeigt den Wert, _ erzeugt keine Ausgabe).
+
diff --git a/src/org/hsqldb/cmdline/sqltool/raw.leadin.text b/src/org/hsqldb/cmdline/sqltool/raw.leadin.text
new file mode 100644
index 0000000..d899c9f
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/raw.leadin.text
@@ -0,0 +1,4 @@
+Enter RAW SQL.  No \, :, * commands.
+End with a line containing only ".;" to send to database,
+or ":." to store to edit buffer for editing or saving.
+-----------------------------------------------------------
diff --git a/src/org/hsqldb/cmdline/sqltool/raw.leadin_de.text b/src/org/hsqldb/cmdline/sqltool/raw.leadin_de.text
new file mode 100644
index 0000000..1917406
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/raw.leadin_de.text
@@ -0,0 +1,6 @@
+Geben Sie reines SQL (ROW-SQL) ein!  Keine '\', ':', '*' Befehle.
+Schließen Sie mit einer Leerzeile ab welche nur ".;" enthält
+um alles an die Datenbank zu senden;
+oder ":." um alles in den Editiert-Puffer für die Bearbeitung oder
+Speicherung zu laden. 
+-----------------------------------------------------------
diff --git a/src/org/hsqldb/cmdline/sqltool/rejectreport.bottom.text b/src/org/hsqldb/cmdline/sqltool/rejectreport.bottom.text
new file mode 100644
index 0000000..124e5ed
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/rejectreport.bottom.text
@@ -0,0 +1,8 @@
+        <TR><TD class='sum' colspan='4'>%{1}</TD></TR>
+    </TBODY>
+</TABLE>
+
+<DIV class='footnote'>SqlFile revision %{2}.</DIV>
+
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/cmdline/sqltool/rejectreport.bottom_de.text b/src/org/hsqldb/cmdline/sqltool/rejectreport.bottom_de.text
new file mode 100644
index 0000000..552c29e
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/rejectreport.bottom_de.text
@@ -0,0 +1,8 @@
+        <TR><TD class='sum' colspan='4'>%{1}</TD></TR>
+    </TBODY>
+</TABLE>
+
+<DIV class='footnote'>SqlFile Revision %{2}.</DIV>
+
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/cmdline/sqltool/rejectreport.row.text b/src/org/hsqldb/cmdline/sqltool/rejectreport.row.text
new file mode 100644
index 0000000..5cf57a9
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/rejectreport.row.text
@@ -0,0 +1,6 @@
+        <TR class='%{1}'>
+            <TD class='rejnum_col right'>%{2}</TD>
+            <TD class='inline_col right'>%{3}</TD>
+            <TD class='incol_col center'>%{4}</TD>
+            <TD><PRE class='reason'>%{5}</PRE></TD>
+        </TR>
diff --git a/src/org/hsqldb/cmdline/sqltool/rejectreport.top.text b/src/org/hsqldb/cmdline/sqltool/rejectreport.top.text
new file mode 100644
index 0000000..d76b59c
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/rejectreport.top.text
@@ -0,0 +1,60 @@
+<HTML>
+
+<!--   END USERS:  To customize, write your own CSS file named
+       "rejects_custom.css" and place it in same directory as
+       this file is read from.
+       Probably makes most sense to start by overriding the styles
+       that are set in the STYLE block below.
+       If you copy this file, email it to somebody, etc., remember
+       to send your rejects_custom.css file too, or it will appear
+       without customization in the new location.  - blaine
+-->
+
+<HEAD>
+    <TITLE>SqlTool DSV Reject Report</TITLE>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <STYLE>
+        th { background-color:DDEEEE; }
+        .right { text-align:right; }
+        td.reason { font-size:95%; font-weight:bold;}
+        th.reason { text-decoration:underline; color:red; }
+        .center { text-align:center; }
+        body { background:silver; }
+        span.headingval { font-weight:bold; font-style:courier; }
+        table { background-color:white; }
+        tr.oddrow { background-color:#EEEEEE; }
+        tr.evenrow { background-color:#EEFFFF; }
+        td.sum { border:3px solid #006363; font-weight:bold; }
+        div.footnote { margin:10px; font-size:90%;}
+    </STYLE>
+    <LINK rel='stylesheet' href='rejects_custom.css' type='text/css'>
+</HEAD>
+<BODY>
+
+<P>
+    Import performed <SPAN class='headingval'>%{1}</SPAN> with SqlTool.
+</P>
+<P>
+    Input DSV file: <SPAN class='headingval'>%{2}</SPAN>
+</P>
+<P>
+    Reject DSV file: <SPAN class='headingval'>%{3}</SPAN>
+</P>
+%{4:+
+<P>
+    The corresponding records in '%4'
+    are at line numbers of (reject # + 1), since the
+    header record occupies the first line.
+</P>
+}
+
+<TABLE border='1px' cellpadding='5px'>
+    <THEAD><TR>
+        <TH title="Number of this error">rej.&nbsp;#</TH>
+        <TH title="Line number in input .dsv file">input<BR/>line&nbsp;#</TH>
+        <TH title="Offending column.  Blank if unknown.">
+            bad&nbsp;column<BR/>(if&nbsp;known)</TH>
+        <TH title="Reason for failure, from DSV parser or database"
+            class='reason'>reason</TH>
+    </TR></THEAD>
+    <TBODY>
diff --git a/src/org/hsqldb/cmdline/sqltool/rejectreport.top_de.text b/src/org/hsqldb/cmdline/sqltool/rejectreport.top_de.text
new file mode 100644
index 0000000..fe02f87
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/rejectreport.top_de.text
@@ -0,0 +1,60 @@
+<HTML>
+
+<!--   BENUTZER: Zur Anpassung schreiben Sie bitte ihre eigene CSS-Datei
+	   mit dem Namen "rejects_custom.css" und speichern Sie im selben 
+	   Verzeichniss wie diese Datei.
+	   Es macht wohl den meisten Sinn, zuerst die Style-Elemente im
+	   STYLE-Block zu überschreiben.
+	   Wenn Sie diese Datei kopieren oder an jemanden mailen, so 
+	   vergessen Sie nicht auch ihre eigene CCS-Datei mit zu schicken.
+	   Oder die Seitendarstellung wird ohne ihre Anpassung erfolgen. - blaine (im engl. Orginaltext)
+-->
+
+<HEAD>
+    <TITLE>SqlTool DSV Reject-Report</TITLE>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <STYLE>
+        th { background-color:DDEEEE; }
+        .right { text-align:right; }
+        td.reason { font-size:95%; font-weight:bold;}
+        th.reason { text-decoration:underline; color:red; }
+        .center { text-align:center; }
+        body { background:silver; }
+        span.headingval { font-weight:bold; font-style:courier; }
+        table { background-color:white; }
+        tr.oddrow { background-color:#EEEEEE; }
+        tr.evenrow { background-color:#EEFFFF; }
+        td.sum { border:3px solid #006363; font-weight:bold; }
+        div.footnote { margin:10px; font-size:90%;}
+    </STYLE>
+    <LINK rel='stylesheet' href='rejects_custom.css' type='text/css'>
+</HEAD>
+<BODY>
+
+<P>
+    Import durchgeführt am <SPAN class='headingval'>%{1}</SPAN> mit SqlTool.
+</P>
+<P>
+    Import-DSV-Datei: <SPAN class='headingval'>%{2}</SPAN>
+</P>
+<P>
+    Reject-DSV-Datei: <SPAN class='headingval'>%{3}</SPAN>
+</P>
+%{4:+
+<P>
+    Die passenden Datensätze in '%4'
+    sind bei Zeilennummer von (Reject # +), seit  der
+    führende Datensatz die erste Zeile eingenommen hat.
+</P>
+}
+
+<TABLE border='1px' cellpadding='5px'>
+    <THEAD><TR>
+        <TH title="Nummer dieses Fehlers">rej.&nbsp;#</TH>
+        <TH title="Zeilennummer in der Import-DSV-Datei">Eingabe<BR/>Zeile&nbsp;#</TH>
+        <TH title="Fehlerhafte Spalte. Leer, wenn unbekannt.">
+            fehlerhafte&nbsp;Spalte<BR/>(wenn&nbsp;bekannt)</TH>
+        <TH title="Ursache für den Fehler, vom DSV-Parser oder der Datenbank"
+            class='reason'>Ursache</TH>
+    </TR></THEAD>
+    <TBODY>
diff --git a/src/org/hsqldb/cmdline/sqltool/special.help.text b/src/org/hsqldb/cmdline/sqltool/special.help.text
new file mode 100644
index 0000000..03d8277
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/special.help.text
@@ -0,0 +1,28 @@
+SPECIAL COMMANDS
+Filter substrings are case-sensitive!  Use "SCHEMANAME." to narrow to schema.
+    \?                   Special command Help
+    \.                   Enter raw SQL.  End with line containing only "."
+    \=                   Commit JDBC session
+    \! COMMAND [ARGS]    Execute external program (no support for stdin)
+    \a [true|false]      Auto-commit JDBC DML commands (for current conn)
+    \b                   save next result to Binary buffer (no display)
+    \bd file/path.bin    Dump Binary buffer to file
+    \bl file/path.bin    Load file into Binary buffer
+    \bp                  Use ? in next SQL statement to upload Binary buffer
+    \c [true|false]      Continue upon errors (a.o.t. abort upon error)
+    \d OBJECTNAME [regx] Describe table or view columns
+    \d{tvsiSanur*?} [substr]  List objects of specified type:
+  (Tbls/Views/Seqs/Indexes/SysTbls/Aliases/schemaNames/Users/Roles/table-like)
+    \H                   Toggle HTML output mode
+    \i file/path.sql     Include/execute commands from external file
+    \j [urlid]           display Jdbc connection details, or connect to 'urlid'
+    \j acct pwd jdbc:url establish connection to Jdbc data source at URL
+    \l LEVEL  A Message  Log message.  (list available levels with \l?)
+    \m file/path.dsv [*] iMport DSV text file records into a table (opts \m?)
+    \o [file/path.html]  Tee (or stop teeing) query output to specified file
+    \p [A Message]       Print string to stdout
+    \q [abort message]   Quit (or you can end input with Ctrl-Z or Ctrl-D)
+    \t [true|false]      report execution Times for all SQL commands
+    \v [TRAN_ISO_LVL]    view/set the connection transaction isolation leVel
+    \x {TABLE|SELECT...} eXport table or query to DSV text file (options \x?)
+
diff --git a/src/org/hsqldb/cmdline/sqltool/special.help_de.text b/src/org/hsqldb/cmdline/sqltool/special.help_de.text
new file mode 100644
index 0000000..b5155ce
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool/special.help_de.text
@@ -0,0 +1,28 @@
+Sonderbefehle.
+Bei Filterzeichenketten wird die Groß/Kleinschreibung beachtet . Verwenden Sie "SCHEMANAME.", 
+um auf ein Schema zu begrenzen.
+    \?                     Sonderbefehle Hilfe
+    \p [Eine Nachricht]    Gibt Nachricht auf stdout aus
+    \l LEVEL  Log-Meld.    Log-Meldung. (verfügbare Levels mit '\l?' anzeigen lassen.)
+    \i pfad/datei.sql      Befehle aus externer Datei ausführen/einbinden
+    \d{tvsiSanur*?} [Zeichenkette] Listet Objekte der spezifizierten Art:
+  (Tbln/Views/Seqs/Indexe/SysTbln/Aliase/SchemaNamen/Benutzer/Rollenn/tbl-ähnlich)
+    \d OBJEKTNAME [regx]   Beschreibt Spalten von Tabellen oder Views
+    \o [datei/pfad.html]   Leitet (oder stoppt dies) die Ausgabe der Abfrage in die angegebene Datei um.
+    \H                     Schaltet in den HTML-Ausgabe-Modus.
+    \! BEFEHL  [ARGE]      Führt externe Programme aus (stdin wird nicht unterstützt).
+    \c [true|false]        Weiter nach Fehler oder Abbruch nach Fehler.
+    \a [true|false]        Commitet automatisch JDBC DML Befehle.
+    \t [true|false]        Gibt die Ausführungszeiten für alle SQL-Befehle aus.
+    \v [TRAN_ISO_LEVEL]    Zeigt/Setzt das Level der Verbindungs-Transaktion-Isolation.
+    					   (connection transaction isolation)
+    \b                     Speichert die nächste Ergebnismenge im Binärpuffer (keine Ausgabe).
+    \bd pfad/datei.bin     Speichert den Binärpuffer in Datei.
+    \bl pfad/datei.bin     Lädt Datei in den Binärpuffer
+    \bp                    Verwenden Sie ? in der nächsten SQL-Anweisung um den Binärpuffer
+                           hochzuladen.
+    \.                     Geben Sie reines SQL ein (Raw-SQL). Schließen Sie mit einer Leerzeile ab, die nur einen "." enthält
+    \=                     Commitet JDBC Transaktionen.
+    \x {TABELLE|SELECT...} Exportiert Tabellen oder Abfragen in eine DSV-Textdatei (weitere Optionen: '\x?').
+    \m pfad/datei.dsv [*]  Importiert Datensätze aus einer DSV-Textdatei in eine Tabelle. (weitere Optionen '\m?').
+    \q [Abbruchmeldung]  Beendet das Programm (oder beenden Sie es mit STRG-Z oder STRG-D).
diff --git a/src/org/hsqldb/cmdline/sqltool_de.properties b/src/org/hsqldb/cmdline/sqltool_de.properties
new file mode 100644
index 0000000..1cc177e
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool_de.properties
@@ -0,0 +1,230 @@
+# $Id: sqltool_de.properties 3375 2009-12-18 23:27:07Z unsaved $
+
+# IMPORTANT:  Make sure to use ISO-8859-1 encoding for any extended characters,
+# both in this file (actually any .properties file) and all referenced text
+# files.
+
+# GENERAL .properties SYNTAX:
+#   White space AT END OF LINES IS SIGNIFICANT
+#   White space at beginning of lines is not
+#   \ at very end of line makes the following line a continuation line (with
+#     no implied newline in the value.
+#     (Combined with the previous 2 rules, this means that white space before
+#     this \ is significant, and whitespace at beginning of continutation lines
+#     is not).
+#   \n does not work as an escape.  Use unicode \u000a for line breaks instead.
+
+# German Locale String resources for SqlTool.
+# This file is loaded by RefCapablePropertyResourceBundle, so if any
+# property here has no value set, the value MUST be set in a file
+# located at sqltool/PROPERTYNAME.text
+
+# The empty val settings in sqltool.properties are inherited to the other
+# languages, so see the "sqltool.properties" file about that.
+# Property keys MAY NOT CONTAIN UNDERSCORE.  Underscores in Enum constants
+# will automatically be transated to dots.
+
+# Traditional inline .properties values:
+rawmode.prompt=row
+SqlTool.varset.badformat=Syntax der Variablen entspricht nicht dem Format "name=währung[,...]".
+SqlTool.abort.continue.mutuallyexclusive=Die Schalter '--abortOnErr' und \
+                        '--continueOnErr' schließen sich gegenseitig aus.
+sqltempfile.fail=Die angegebe SQL konnte nicht in der Datei gespeichert werden.\u000aUrsache: %{1}
+rcdata.inlineurl.missing=Das 'url' Element wird für inlineRC benötigt.
+rcdata.inline.extravars=Nicht unterstützte(s) inlineRC Element(e) angegeben: %{1}.
+rcdata.inlineusername.missing=Das 'user' Element wird für inlineRC benötigt.
+rcdata.password.visible=Das 'password' Element muß leer sein.  \
+            Um ein Passwort zu verwenden lassen Sie das\u000a\
+            'password' Element weg, sie werden dann separat danach gefragt!
+password.readfail=Fehler beim einlesen des Passwortes.\u000aUrsache: %{1}
+rcdata.genfromvalues.fail=RCData ließ sich aus den angegebenen Werten nicht erzeugen.\u000aUrsache: %{1}
+conndata.retrieval.fail=Konnte keine Verbindungsinformationen für urlid "%{1} finden".\u000aUrsache: %{2}
+jdbc.established=JDBC Verbindung hergestellt zu eine %{1} v. %{2} Datenbank\u000a\
+    als "%{3}" mit %{4} Isolation.
+connection.fail=Konnte keine Verbindung herstellen zu %{1} als Benutzer "%{3}"! \u000aUrsache: %{3}
+tempfile.removal.fail=Beim Versuch die temporäre Datei '%{1}' zu löschen trat ein Fehler auf.
+# Value for following line has trailing whitespace on purpose.
+passwordFor.prompt=Bitte Passwort angeben für %{1}!:  
+
+sqlfile.readfail=Die SQL Datei '%{1}' konnte nicht gelesen werden.
+raw.movedtobuffer=Raw-SQL Block in den Edit-Puffer verschoben. Geben Sie ":;" ein, um den Block auszuführen!
+input.movedtobuffer=Aktueller Befehl wurde in den Edit-Puffer verschoben.
+sqlstatement.empty=Leere SQL-Anweisung.
+causereport=Ursache: %{1}
+break.unsatisfied=Unzureichende 'break' Anweisung (%{1} Typ).
+continue.unsatisfied=Unzureichende 'continue' Anweisung%{1:+ (type '%1')}.
+input.unterminated=Unvollständige Eingabe:  "%{1}"
+primaryinput.accessfail=Fehler beim Zugriff auf die Primäreingabe.
+aborting=SqlTool abgebrochen:  %{1}
+plvar.set.incomplete=Einstellung der Variable '%{1}' ist unvollständig geblieben.
+rollingback=Die SQL-Transaktion wird rückgängig gemacht.
+bufhist.unspecified=Kein Befehl spezifiziert.  Rufen Sie ":?" auf, um die Kommandos für den Befehlszwischenspeicher und den Verlauf anzuzeigen!
+special.unspecified=Kein Befehl spezifiziert.  Rufen Sie "\\?" auf, um die Sonderbefehle aufzulisten!
+buffer.executing=Befehl aus dem Edit-Puffer ausgeführt:\u000a"%{1}"\u000a
+nobuffer.yet=Noch kein Pufferinhalt.
+commandnum.malformat=Fehlerhaft formatierter Befehl Nr. "%{1}".
+buffer.restored=Folgender Befehl wurde wieder hergestellt.\u000a\
+        ":?" eingeben, um die Pufferbefehle anzuzeigen.\u000a%{1}
+substitution.malformat=Fehlerhafte Ersetzungsanweisung.
+substitution.nomatch=Puffer unverändert, da der Musterabgleich fehlschlug.
+substitution.syntax=Syntax für Ersetzungen: ":s/von regex/zu string/igm;".  \
+                     Optionale Schalter: i, g, m, ;.
+buffer.unknown=Unbekannter Pufferbefehl ":%{1}".
+dsv.x.syntax=Exportsyntax:  "\\x Tabelle_oder_angezeigter_name "  OR  "\\x SELECT Anweisung".\u000a\
+(Nicht mit ';' beenden, da der \\x Befehl selbst keine SQL-Anweisung ist.
+dsv.m.syntax=Importsyntax:  \\m Datei/Pfad.dsv [*]   (* bedeutet keine Anmerkungen in der DSV Datei).
+special.extrachars=Extrazeichen nach "\\%{1}" Befehl:  %{2}
+buffer.extrachars=Extrazeichen nach ":%{1}" Befehl:  %{2}
+special.malformat=Fehlerhaft formatierter Sonderbefehl.
+html.mode=HTML-Modus ist jetzt gesetzt auf %{1}.
+dsv.targetfile.demand=Sie müssen die PL-Variable "*DSV_TARGET_FILE" setzten, um die fragliche Variante von \\x zu verwenden.
+file.wrotechars=Das Zeichen %{1} wurde in die Datei '%{2}' geschrieben.
+file.writefail=Konnte nicht in die Datei '%{1}' schreiben.
+file.appendfail=Konnnte nichts zur Datei '%{1}' hinzufügen.
+destfile.demand=Sie müssen einen Namen für die Zieldatei angeben.
+special.d.like=\\d Angezeigte Befehle müssen wie '\\dX' oder '\\d OBJECTNAME' sein.  '\\d?' eingeben für weitere Auflistungen.
+outputfile.nonetoclose=Für die Abfrage existiert keine Ausgabedatei welche geschlossen werden könnte.
+outputfile.reopening=Schließe Ausgabedatei der aktuellen Abfrage und öffne sie erneut.
+outputfile.header=Ausgabe der Abfrage von %{1}.
+buffer.empty=Kein Befehl im Edit-Puffer.
+sqlfile.name.demand=Geben Sie bitte einen SQL-Dateinamen an.
+sqlfile.execute.fail=Konnte den Inhalt der SQL-Datei '%{1} nicht ausführen.
+a.setting=Auto-Commit-Modus wird gesetzt auf %{1}.
+committed=Transaktion ausgeführt.
+special.b.malformat=Fehlerhaft formatierter Binärbefehl.
+binary.loadedbytesinto=%{1} Bytes in den Binärpuffer geladen.
+binary.filefail=Fehler beim schreiben der Binärdaten in Datei '%{1}'.
+c.setting="Nach-Fehler-fortfahren" (Continue-on-error) wird gesetzt auf %{1}.
+bang.incomplete=Nach dem externen Befehl muss ein '!' folgen um ihn auszuführen.
+bang.command.fail=Externer Befehl ist fehlgeschlagen:\u000a"%{1}"
+special.unknown=Unbekannter Sonderbefehl "\\%{1}".
+raw.empty=RAW-Anweisung wurde abgebrochen (keine Eingabe erhalten).
+dsv.nocolsleft=Keine weiteren Spalten verblieben, nachdem %{1:+"%1" und }"-" Spalten ausgelassen worden sind.
+dsv.skipcols.missing=Die folgende(n) Leerspalte(n) ist nicht vorhanden:  %{1}.
+plalias.malformat=Fehlerhafte Verwendung des PL-Alias.
+plvar.undefined=Unbestimmte PL-Variable "%{1}".
+var.infinite=Mögliche endlose Variable gehen zurück, einschliesslich '%{1}'.
+sysprop.empty=Leerer Systemvariablename.
+sysprop.unterminated=Unvollständiger Systemvariablenname.
+sysprop.undefined: Nicht gesetzte Systemeinstellung "%{1}".
+plvar.nameempty=Leerer PL-Variablenname.
+plvar.unterminated=Unvollständiger PL-Variablenname.
+pl.malformat=Fehlerhafter PL-Befehl.
+pl.expansionmode=Status der PL-Variablenexpansion ist nun %{1}.
+end.noblock=Fehlender Abschluss der 'end'-Anweisung.
+continue.syntax=PL 'continue' Anweisung erfordert kein Argument oder von \
+                 'foreach', 'while'.
+break.syntax=PL 'break' Anweisung erfordert kein Argument oder von \
+                 'foreach', 'if', 'while', 'file'.
+pl.list.parens=Die äußersten Klammern sind nicht Teil der Werte.
+pl.list.lengths=Zeigt den Variablennamen und die Länge der Werte. \
+            (Verwende 'listvalues', um die Werte zu sehen).
+dumpload.malformat=Fehlerhafter PL 'dump' oder 'load' Befehl.
+plvar.nocolon=PL Variablennamen dürfen nicht ':' enthalten.
+plvar.tildedash.nomoreargs=PL ~/_ Befehle akzeptieren keine anderen Argumente ("%{1}").
+dumpload.fail=Konnte Variable '%{1}'  nicht in/von Datei '%{2}' speichern/laden.
+prepare.malformat=Fehlerhafter PL 'prepare' Befehl.
+foreach.malformat=Fehlerhafter PL 'foreach' Befehl.
+pl.block.fail=Konnte die Anweisungen vom PL-Block nicht ausführen.
+ifwhile.malformat=Fehlerhafter PL 'if'/'while' Befehl.
+if.malformat=Fehlerhafter PL 'if' Befehl.
+while.malformat=Fehlerhafter PL 'while' Befehl.
+pl.unknown=Unbekannter PL-Befehl "%{1}".
+pl.block.unterminated=Nicht beendeter PL '%{1}' Block
+vendor.oracle.dS=*** WARNUNG:\u000a\
+    *** Liste Tabelle im Systemeigenen Schemata, da\u000a\
+    *** Oracle (TM) keine JDBC System-Tabellenliste zurückgibt.
+vendor.derby.dr=Derby verfügt nicht über SQL-Rollen.
+vendor.nosup.d=SqlFile unterstützt noch nicht \\d%{1} für Ihren Datenbanktyp.
+vendor.derby.du=Es ist unmöglich, eine zuverlässige Benutzerliste von Derby zu erhalten.
+special.d.unknown=Unbekannte \\d Wahl: '%{1}'.
+metadata.fetch.fail=Konnte die Metadaten der Datenbank nicht bekommen.
+metadata.fetch.failfor=Konnte die Metadaten der Datenbank für '%{1}' nicht bekommen.
+prepare.demandqm='Prepared statements' müssen ein '?' enthalten.
+binbuffer.empty=Binärpuffer ist leer.
+vendor.nosup.sysschemas=*** WARNUNG:\u000a\
+        *** Lasse Tabellen vom System eigenen Schemata wegfallen\u000a\
+        *** (weil DB-Distributor sie nicht von JDBC unterscheidet).
+noresult=Kein Resultat.
+dsv.bincol=Tabelle hat eine binäre Spalte. DSV Dateien sind Textdateien und keine Binärdateien.
+binbuf.write=Lese %{1} Bytes von Spalte '%{2}' (Typ %{3}) in den Binärpuffer.
+rows.fetched=%{1} Reihen geholt.
+rows.fetched.dsv=%{1} Reihen von der Datenbank geholt.
+row.update.multiple=%{1} Reihen aktualisierten.
+row.update.singular=1 Reihe aktualisierte.
+history.unavailable=Befehlsverlauf nicht vorhanden.
+history.none=Noch keinen Verlauf.
+editbuffer.contents=Edit-Pufferinhalt:\u000a"%{1}"
+buffer.instructions=Um einen Befehl in Puffer zu kopieren, geben Sie ":27" oder ":-3" ein.  \
+                    Um den Puffer erneut auszuführen ":;".
+history.number.req=Geben Sie bitte eine positive Ganzzahl als Befehlsnummer ein, oder eine \
+   negative Zahl,\u000aum X Befehle im Verlauf zurück zu gehen.
+history.backto=Befehlsverlauf geht nur zurück bis #%{1}.
+history.upto=Befehlsverlauf geht nur zurück bis #%{1}.
+history.back=Befehlsverlauf geht nur %{1} Befehl(e) zurück.
+describe.table.name=Name
+describe.table.datatype=Datentyp
+describe.table.width=Breite
+describe.table.nonulls=Keine Null-Werte
+logical.unrecognized=Unbekannte logische Operation.
+read.toobig=Datenmenge ist zu groß um alles auf einmal einzulesen.\u000a\
+    Lassen Sie das Programm bitte mit mehr Arbeitsspeicher laufen (Versuchen Sie den 'java -Xm*' Schalter).
+read.partial=Lese nicht alle Bytes. %{1} Bytes von %{2} werden gelesen.
+read.convertfail=Wert ist zu groß, um ihn in eine Zeichenkette umzuwandeln. \u000a\
+     Lassen Sie das Programm bitte mit mehr Arbeitsspeicher laufen (Versuchen Sie den Java -Xm* Schalter).
+dsv.coldelim.present=Tabellendaten enthalten unsere Spaltentrennzeichen '%{1}'.
+dsv.rowdelim.present=Tabellendaten enthalten unsere Zeilentrennzeichen '%{1}'.
+dsv.nullrep.present=Tabellendaten enthalten unser NULL-Zeichen '%{1}'.
+dsv.constcols.nullcol=*DSV_CONST_COLS Element hat null-Spalten-Namen.
+file.readfail=Die Datei '%{1} kann nicht gelesen werden.
+inputfile.closefail=Konnte Import-Datei nicht schließen.
+dsv.header.none=Keine Kopfzeile (Header) in der Import-Datei.
+dsv.header.noswitchtarg=Kopfzeichen in DSV-Datei Zeile %{1} erreicht ohne eine Zieltabelle spezifiziert zu haben.
+dsv.header.noswitchmatch=Ende eines Kopfzeichen in DSV-Datei Zeile %{1} erreicht, ohne dabei eine Kopfspalte definiert zu haben.
+dsv.header.nonswitched=Kopfzeile in Kopfzeichen ohne Tabellenbezug in DSV-Datei Zeile %{1}.
+dsv.nocolheader=Keine Spaltenüberschrift für Spalte #%{1} in DSV-Datei in Zeile %{2}.
+dsv.metadata.mismatch=Die Metadaten passen nicht zu den Spalten.
+query.metadatafail=Konnte für die Abfrage keine Metadaten finden, verwendete:\u000a"%{1}"
+dsv.rejectfile.setupfail=Konnte Reject-Datei '%{1}' nicht erstellen.
+dsv.rejectreport.setupfail=Konnte Reject-Report '%{1}' nicht erstellen.
+none=Nichts
+insertion.preparefail=Fehler beim Vorbereiten der Setup-Zeichenketten für Einfügen:\u000a"%{1}"
+dsv.header.matchernonhead=Nicht-Header-Zeile im Suchblock der Tabelle in der DSV-Datei in Zeile %{1}.
+dsv.colcount.mismatch=Die Kopfzeile hat %{1} Spalten, aber der Importdatensatz hat %{2} Spaltenwerte.
+dsv.insertcol.mismatch=Erwartete insgesamt %{1} Werte zum importieren, erfaßte aber %{2}.
+dsv.nonskip.mismatch=Die Kopfzeile hat %{1} nicht auszulassende Spalten, aber der Importdatensatz hat %{2} Werte zum Einfügen.
+time.bad=Falscher Datum/Zeitwert.
+boolean.bad=Falscher Boolean-Wert '%{1}'.
+inputrec.modified=%{1} Reihen geändert durch diesen Eingabedatensatz.
+dsv.recin.fail=Auswerten oder Einfügen der Eingabezeile %{1} %{2:+, Spalte '%2' } ist fehlgeschlagen.
+dsv.import.summary=Importzusammenfassung (%{1}Ausgelassen / Zurückgewiesen / Eingefügt):  \
+                    %{2} / %{3} / %{4}%{5:+ bevor abgebrochen}.
+insertions.notcommitted=Alle einzufügenden Datensätze gehen verloren, wenn du nicht commitest.
+autocommit.fetchfail=Fehler beim Erhalt des Autocommit-Wertes.
+dsv.rejectfile.purgefail:Fehler beim Löschen der nicht benötigten Reject-Datei '%{1}'.
+dsv.rejectreport.purgefail=Fehler beim Löschen des nicht benötigten Reject-Reportes '%{1}'.
+edit.malformat=Fehlerhafter Pufferbefehl.
+input.malformat=Syntaxfehler in der Eingabe.
+append.empty=Verwende ':,' (und nichts weiter) um einen Befehl zu wiederholen.
+transiso.report=Transactions-Isolations-Level ist jetzt %{1} %{2}
+exectime.reporting=Bericht zur Ausführungdauer auf %{1} gesetzt.
+exectime.report=Dauer: %{1} ms.
+regex.malformat=Falsches Regex-Muster: %{1}
+encode.fail=Ausgabe-Kodierung ist fehlgeschlagen: %{1}
+macro.tip=Rufen Sie /? auf für die Makro-Hilfe!
+macrodef.malformat=Fehlerhafter Makro-Definitions-Befehl.
+macrodef.empty=Dieses Makro ist leer.
+macrodef.semi=Makro-Werte können nicht mit ";" enden.
+macro.malformat=Falscher Makro-Befehl.
+macro.undefined=Es gibt kein definiertes Makro mit dem Namen "%{1}".
+errstream.deprecated:\
+    WARNUNG: Die SqlFile-execute-Methode mit dem Parameter "error stream" ist \u000a\
+    abgekündigt und sollte nicht mehr verwendet werden. Bitte passen Sie ihr Programm \u000a\
+    so an, das es eine der Logging-Möglichkeiten verwendet. \
+    Mache weiter....
+log.syntax=SYNTAX:  \\l LEVEL Nachricht\u000a\
+    Wobei LEVEL eines der folgend ist :  FINEST, FINER, INFO, WARNING, SEVERE
+log.syntax.error=Logging-Syntax-Fehler.  Rufen Sie '\\l?' auf um die Hilfe zu sehen!
+reject.rpc=Lösche *DSV_RECORDS_PER_COMMIT, da ein kein Ganzzahl-Wert angegeben wurde: %{1}.
+rpc.autocommit.failure=Fehler beim Einrichten der *DSV_RECORDS_PER_COMMIT Option.
+rpc.commit.failure=Fehler beim Abschließen des Commit-Status für die *DSV_RECORDS_PER_COMMIT Option.
diff --git a/src/org/hsqldb/cmdline/sqltool_nl.properties b/src/org/hsqldb/cmdline/sqltool_nl.properties
new file mode 100644
index 0000000..b3966e3
--- /dev/null
+++ b/src/org/hsqldb/cmdline/sqltool_nl.properties
@@ -0,0 +1,207 @@
+# $Id: sqltool_nl.properties 3375 2009-12-18 23:27:07Z unsaved $
+
+# IMPORTANT:  Make sure to use ISO-8859-1 encoding for any extended characters,
+# both in this file (actually any .properties file) and all referenced text
+# files.
+
+# GENERAL .properties SYNTAX:
+#   White space AT END OF LINES IS SIGNIFICANT
+#   White space at beginning of lines is not
+#   \ at very end of line makes the following line a continuation line (with
+#     no implied newline in the value.
+#     (Combined with the previous 2 rules, this means that white space before
+#     this \ is significant, and whitespace at beginning of continutation lines
+#     is not).
+#   \n does not work as an escape.  Use unicode \u000a for line breaks instead.
+
+# Default Locale String resources for SqlTool.
+# This file is loaded by RefCapablePropertyResourceBundle, so if any 
+# property here has no value set, the value MUST be set in a file
+# located at sqltool/PROPERTYNAME.text
+
+# The empty val settings in sqltool.properties are inherited to the other
+# languages, so see the "sqltool.properties" file about that.
+# Property keys MAY NOT CONTAIN UNDERSCORE.  Underscores in Enum constants
+# will automatically be transated to dots.
+
+# Traditional inline .properties values:
+rawmode.prompt=raw
+SqlTool.varset.badformat=Variabele settings zijn niet van het juiste formaat "naam=waarde[,...]".
+SqlTool.abort.continue.mutuallyexclusive=Opties '--abortOnErr' en \
+                        '--continueOnErr' kunnen niet gelijktijdig worden gebruikt.
+sqltempfile.fail=Het schrijven van de opgegeven sql naar een tijdelijk bestand is mislukt.\u000aReden: %{1}
+rcdata.inlineurl.missing=Het 'url' element is verplicht bij het gebruik van inline RC argument.
+rcdata.inline.extravars=Niet ondersteunde inline element(en) verstrekt: %{1}.
+rcdata.inlineusername.missing=Het 'user' element is verplicht bij het gebruik van inline RC argument.
+password.readfail=Wachtwoord lezen is mislukt.\u000aReden: %{1}
+sqltempfile.fail=Het schrijven van de opgegeven sql naar een tijdelijk bestand is mislukt.\u000aReden: %{1}
+rcdata.genfromvalues.fail=Het genereren van RCData uit de opgegeven waardes is mislukt.\u000aReden: %{1}
+conndata.retrieval.fail=Het ophalen van de verbindings informatie voor url identificatie "%{1}" is mislukt.\u000aReden: %{2}
+jdbc.established=JDBC verbinding totstand gekomen naar een  %{1} v. %{2} database als "%{3}".
+connection.fail=Het opzetten van een verbinding naar '%{1}' als gebruiker "%{2}" is mislukt.\u000aReden: %{3}
+tempfile.removal.fail=Fout opgetreden bij het verwijderen van het tijdelijke bestand '%1'.
+# Value for following line has trailing whitespace on purpose.
+passwordFor.prompt=Geef wachtwoord voor %{1}:  
+
+sqlfile.readfail=Kan SQL bestand niet lezen '%{1}'.
+raw.movedtobuffer=Ruw SQL fragment geplaatst in buffer.  Run ":;" om het fragment uit te voeren.
+input.movedtobuffer=Huidige input geplaatst in buffer.
+sqlstatement.empty=Leeg SQL Statement.
+causereport=Reden: %{1}
+break.unsatisfied=Onjuist geplaatst 'break' commando (type %{1}).
+continue.unsatisfied=Onjuist geplaatst 'continue' commando${1:+ (type '%1')}.
+input.unterminated=Onafgesloten input:  "%{1}"
+primaryinput.accessfail=Fout bij het benaderen van de primaire input.
+aborting=Voortijdig beeindigen van SqlTool:  %{1}
+plvar.set.incomplete=Het zetten van de variable '%{1}' is niet voltooid.
+inputreader.closefail=Het sluiten van de input lezer is mislukt.
+rollingback=Terugrollen van SQL transactie.
+special.unspecified=Speciaal commando van onbekend type?
+buffer.executing=Uitvoeren van commando uit buffer:\u000a"%{1}"\u000a
+executing=Uitvoeren commando:\u000a"%{1}"\u000a
+nobuffer.yet=Nog geen buffer.
+commandnum.malformat=Onjuist geformatteerd commando nummer "%{1}".
+buffer.restored=Navolgende commando teurggehaald naar de buffer.  Geef ":?" voor een lijst van de beschikbare buffer commando's.\u000a%{1}
+substitution.malformat=Onjuist geformatteerd vervangings commando
+substitution.nomatch=Buffer niet gewijzigd vanwege ontbreken patroon overeenkomst
+substitution.syntax=Substitutie syntax: ":s/van regular expression/naar string/igm;".  \
+                     Optionele modes i, g, m, ;.
+buffer.unknown=Onbekend Buffer commando ":%{1}".
+dsv.x.syntax=Export syntax:  "\\x tabel_of_view_naam "  OF  "\\x SELECT statement".\u000a\
+(Eindig niet met ';', omdat het \\x commando geen SQL is).
+dsv.m.syntax=Import syntax:  \\m file/path.dsv [*]   (* betekent geen commentaar in DSV bestand).
+special.extrachars=Extra characters na "\\%{1}" commando:  %{2}
+buffer.extrachars=Extra characters na ":{1}" commando:  %{2}
+special.malformat=Onjuist samengesteld special commando.
+html.mode=HTML Mode is nu gelijkgesteld aan %{1}.
+dsv.targetfile.demand=U moet de PL variabele '*DSV_TARGET_FILE' zetten om gebruik te maken van de query variant van \\x.
+file.wrotechars=%{1} karakters geschreven naar bestand '%{2}'.
+file.writefail=Fout bij het schrijven naar bestand '%{1}'.
+file.appendfail=Fout bij het toevoegen van informatie aan bestand '%{1}'.
+destfile.demand=U dient een bestemmings bestand naam op te geven.
+special.d.like=Describe commando's moeten zijn samengesteld als  '\\dX' of als '\\d OBJECTNAME'.  '\\d?' om een lijst te maken.
+outputfile.nonetoclose=Er is geen query uitvoer bestand om te sluiten.
+outputfile.reopening=Huidige query uitvoer bestand wordt gesloten en een nieuwe wordt geopend.
+outputfile.header=Query uitvoer van  %{1}.
+buffer.empty=Geen commando aanwezig in buffer.
+sqlfile.name.demand=U dient een SQL bestands naam te specificeren.
+sqlfile.execute.fail=Het uitvoeren van de inhoud van SQL bestand '%{1}' is mislukt.
+a.setting=Auto-commit is gezet op %{1}.
+committed=Sessie doorgevoerd.
+special.b.malformat=Onjuist samengesteld binair commando.
+binary.loadedbytesinto=%{1} bytes geladen in binaire buffer.
+binary.filefail=Hetladen/dumpen van binaire data naar bestand '%{1}' is mislukt.
+c.setting=Doorgaan-bij-fout is gezet op %{1}.
+bang.incomplete=U moet ! laten volgen door het uit te voeren externe commando .
+bang.command.fail=Uitvoering extern commando mislukt:\u000a"%{1}"
+special.unknown=Onbekend Speciaal commando "\\%{1}".
+raw.empty=Ruw statement afgebroken (geen input gespecificeerd).
+dsv.nocolsleft=Geen resterende kolommenna weglaten van  %{1:+"%1" en }"-" kolommen.
+dsv.skipcols.missing=De volgende over te slaan kolom(men) zijn niet aanwezig:  %{1}.
+plalias.malformat=Onjuist geformatteerd PL alias gebruik.
+plvar.undefined=Ongedefinieerde PL variabele "%{1}".
+var.infinite=Mogelijk oneindige variabele regressie samenhangend met '%{1}'.
+sysprop.empty=Lege Systeem eigenschap variabele naam.
+sysprop.unterminated=Onafgesloten Systeem Property variabele naam.
+sysprop.undefined=Ongedefinieerde Systeem Property "%{1}".
+plvar.nameempty=Lege PL variabele naam.
+plvar.unterminated=Onjuist afgesloten PL variabele naam.
+pl.malformat=Onjuist geformatteerd PL commando.
+pl.expansionmode=PL variabele expansie mode is nu %{1}.
+end.noblock=Het PL end statement is niet omgeven door enig PL blok.
+continue.syntax=Het PL 'continue' statement vereist geen argument ofwel een van  \
+                 'foreach', 'while'.
+break.syntax=Het PL 'break' statement vereist geen argument ofwel een van  \
+                 'foreach', 'if', 'while', 'file'.
+pl.list.parens=De buitenste haakjes zijn geen onderdeel van de waarden.
+pl.list.lengths=Weergave van variabele namen en de lengte van de waarden \
+                 (gebruik 'listvalues' om de waarden te zien).
+dumpload.malformat=Onjuist geformatteerd  PL 'dump' of 'load' commando.
+plvar.nocolon=PL variabele namen mogen geen ':' bevatten.
+plvar.tildedash.nomoreargs=PL ~/_ set commando's kennen geen andere argumenten ("%{1}").
+dumpload.fail=Het dumpen/laden van variabele '%{1}' naar/van bestand '%{2}' is mislukt.
+prepare.malformat=Onjuist geformatteerd PL 'prepare' commando.
+foreach.malformat=Onjuist geformatteerd PL 'foreach' commando.
+pl.tempfile.fail=Fout bij het schrijven naar het PL blok tijdelijke bestand.
+pl.block.fail=Fout bij het uitvoeren van instructies uit het PL blok.
+ifwhile.malformat=Onjuist geformatteerd PL 'if'/'while' commando.
+if.malformat=Onjuist geformatteerd PL 'if' commando.
+while.malformat=Onjuist geformatteerd PL 'while' commando.
+pl.unknown=Onbekend PL commando "%{1}".
+pl.block.unterminated=Onafgesloten PL '%{1}' blok
+end.syntax=Het PL 'end' statement vereist een van de volgende argumenten  \
+                 'foreach' of 'if' of 'while' (%{1}).
+vendor.oracle.dS=*** WAARSCHUWING:\u000a\
+         *** De tabellen in het systeem schema worden niet gelijst omdat \u000a\
+         *** Oracle TM) geen JDBC systeem tabel lijst teruggeeft.
+vendor.derby.dr=Derby heeft SQL Rollen niet geimplementeerd.
+vendor.nosup.d=SqlFile ondersteunt nog niet \\d%{1} van uw database leverancier.
+vendor.derby.du=Het is onmogelijk om een betrouwbare gebruikers lijst van Derby te verkrijgen.
+special.d.unknown=Onbekende beschrijvings optie: '%{1}'.
+metadata.fetch.fail=Ophalen van de metadata uit de database is mislukt.
+metadata.fetch.failfor=Ophalen metadata uit database voor '%{1}' is mislukt.
+prepare.demandqm=Prepared statements moeten een '?' bevatten.
+binbuffer.empty=Binaire SqlFile buffer is leeg.
+vendor.nosup.sysschemas=*** WAARSCHUWING:\u000a\
+            *** De tabellen in het systeem schema wordt niet gelijst \u000a\
+            *** (omdat de DB levernacier deze niet onderscheidt naar JDBC).
+noresult=Geen resultaat.
+dsv.bincol=Tabel heeft een binaire kolom.  DSV bestanden bevatten tekst, geen binaire informatie.
+binbuf.write=%{1} bytes gelezen van veld  '%{2}' (type %{3}) in de binaire buffer.
+rows.fetched=%{1} rijen opgehaald.
+rows.fetched.dsv=%{1} rij(en) opgehaald uit de database.
+row.update.multiple=%{1} rijen gewijzigd.
+row.update.singular=1 rij gewijzigd.
+history.unavailable=Commando historie niet beschikbaar.
+history.none=Nog geen historie beschikbaar.
+editbuffer.contents=Wijzig-Buffer inhoud:\u000a"%{1}"
+buffer.instructions=Plaats een commando in de buffer zoals ":27" or ":-3".  \
+                    Voor buffer inhoud hernieuwd uit middels ":;".
+history.number.req=U dient een positief commando nummer te specificeren, of \
+                    een negatief getal\u000ahetgeen X commandos "terug" betekent.
+history.backto=Historie gaat slechts terug tot #%{1}.
+history.upto=Historie gaat slechts tot #%{1}.
+history.back=Historie gaat slechts  %{1} commando(s) terug.
+describe.table.name=naam
+describe.table.datatype=datatype
+describe.table.width=breedte
+describe.table.nonulls=niet-nullen
+logical.unrecognized=Niet herkende logische operatie.
+read.toobig=Resource is te groot om een keer te kunnen verwerken.\u000a\
+            Draai het programma opnieuw met meer RAM (try Java -Xm* switches).:
+read.partial=Niet alle bytes zijn ingelezen.  %{1} bytes gelezen uit het beschikbare %{2} aantal.
+read.convertfail=Waarde te groot om te converteren naar een String.  \
+                  draai het programma opnieuw met meer RAM geheugen (probeer Java -Xm* parameters).
+dsv.coldelim.present=Gegevens uit tabel bevatten onze kolom delimiter '%{1}'.
+dsv.rowdelim.present=Gegevens uit tabel bevatten onze rij delimiter '%{1}'.
+dsv.nullrep.present=Gegevens uit tabel bevatten onze null-representation token '%{1}'.
+dsv.constcols.nullcol=*DSV_CONST_COLS element heeft null kolom naam.
+file.readfail=Kan bestand '%{1}' niet lezen.
+inputfile.closefail=Fout bij het sluiten van invoer bestand.
+dsv.header.none=Geen header record in invoer bestand.
+dsv.header.noswitchtarg=Headerswitch in DSV bestand regel ${1}, maar er is nog geen doel tabel gespecificeerd.
+dsv.header.noswitchmatch=Afsluiten van een headerswitch bereikt in DSV bestand regel %{1} zonder bijbehorende header.
+dsv.header.nonswitched=Header regel binnen switch zonder tabel matcher in DSV file regel %{1}.
+dsv.nocolheader=Geen kolomheader voor kolom #%{1} in DSV bestand regel %{2}.
+dsv.metadata.mismatch=Kolommen Metadata mismatch.
+query.metadatafail=Het ophalen van metadata voor query door gebruik van :\u000a"%{1}" is mislukt
+dsv.rejectfile.setupfail=Fout bij het opzetten van een afkeuringen bestand '%{1}'.
+dsv.rejectreport.setupfail=Het opzetten van het bestand met afkeuringen is mislukt '%{1}'.
+none=Geen
+block.disabled=BLOK GEDEACTIVEERD
+insertion.preparefail=Het voorbereiden van de toevoeg setup string:\u000a"%{1}" is mislukt
+dsv.header.matchernonhead=Niet Header gerelateerde regel in tabel matcher blok in DSV bestand regel %{1}.
+dsv.colcount.mismatch=Header heeft %{1} kolommen, maar invoer record heeft %{2} kolom waarden.
+dsv.nonskip.mismatch=Header heeft %{1} aantal niet over te slaan kolommen, maar het invoer record heeft %{2} invoeg waardes.
+time.bad=Onjuiste datum/tijd waarde '%{1}'.
+boolean.bad=Onjuiste boolean waarde '%{1}'.
+inputrec.modified=%{1} rijen gewijzigd door deze invoer regel.
+dsv.recin.fail=Het interpreteren of invoegen van invoer regel  %{1} %{2:+, kolom '%2' } is mislukt.
+dsv.import.summary=Import samenvatting (%{1}genegeerd / afkeuringen / toevoegingen):  %{2} \
+                    / %{3} / %{4}.
+dsv.import.summary=Import samenvatting (%{1}genegeerd / afkeuringen / toevoegingen):  \
+                    %{2} / %{3} / %{4}%{5:+ voor afbreken}.
+insertions.notcommitted=Toevoegingen zullen verloren gaan als U geen commit doorvoert.
+autocommit.fetchfail=Het verkrijgen van de connectie autocommit waarde is mislukt.
+dsv.rejectfile.purgefail=Het verwijderen van het onnodige afkeuringen bestand is mislukt '%{1}'.
+dsv.rejectreport.purgefail=Het verwijderen van het onnodige afkeuringen rapport is mislukt '%{1}'.
diff --git a/src/org/hsqldb/dbinfo/DITableInfo.java b/src/org/hsqldb/dbinfo/DITableInfo.java
new file mode 100644
index 0000000..c892f8c
--- /dev/null
+++ b/src/org/hsqldb/dbinfo/DITableInfo.java
@@ -0,0 +1,262 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.dbinfo;
+
+import java.util.Locale;
+
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.resources.BundleHandler;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Types;
+
+/**
+ * Provides extended information about HSQLDB tables and their
+ * columns/indices. <p>
+ *
+ * Current version has been reduced in scope.<p>
+ *
+ * @author boucherb@users
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+final class DITableInfo {
+
+    // related to DatabaseMetaData
+    int                bestRowTemporary   = 0;
+    int                bestRowTransaction = 1;
+    int                bestRowSession     = 2;
+    int                bestRowUnknown     = 0;
+    int                bestRowNotPseudo   = 1;
+    static final short tableIndexOther    = 3;
+
+    /** Used in buffer size and character octet length determinations. */
+    private static final int HALF_MAX_INT = Integer.MAX_VALUE >>> 1;
+
+    /** BundleHandler id for column remarks resource bundle. */
+    private int hnd_column_remarks = -1;
+
+    /** BundleHandler id for table remarks resource bundle. */
+    private int hnd_table_remarks = -1;
+
+    /** The Table object upon which this object is reporting. */
+    private Table table;
+
+    /**
+     * Creates a new DITableInfo object with the default Locale and reporting
+     * on no table.  It is absolutely essential the a valid Table object is
+     * assigned to this object, using the setTable method, before any Table,
+     * Column or Index oriented value retrieval methods are called; this class
+     * contains no assertions or exception handling related to a null or
+     * invalid table member attribute.
+     */
+    DITableInfo() {
+        setupBundles();
+    }
+
+    /**
+     * Sets the Locale for table and column remarks. <p>
+     */
+    void setupBundles() {
+
+        Locale oldLocale;
+
+        synchronized (BundleHandler.class) {
+            oldLocale = BundleHandler.getLocale();
+
+            BundleHandler.setLocale(Locale.getDefault());
+
+            hnd_column_remarks =
+                BundleHandler.getBundleHandle("column-remarks", null);
+            hnd_table_remarks = BundleHandler.getBundleHandle("table-remarks",
+                    null);
+
+            BundleHandler.setLocale(oldLocale);
+        }
+    }
+
+    /**
+     * Retrieves whether the best row identifier column is
+     * a pseudo column, like an Oracle ROWID. <p>
+     *
+     * Currently, this always returns an Integer whose value is
+     * DatabaseMetaData.bestRowNotPseudo, as HSQLDB does not support
+     * pseudo columns such as ROWID. <p>
+     *
+     * @return whether the best row identifier column is
+     * a pseudo column
+     */
+    Integer getBRIPseudo() {
+        return ValuePool.getInt(bestRowNotPseudo);
+    }
+
+    /**
+     * Retrieves the scope of the best row identifier. <p>
+     *
+     * This implements the rules described in
+     * DatabaseInformationMain.SYSTEM_BESTROWIDENTIFIER. <p>
+     *
+     * @return the scope of the best row identifier
+     */
+    Integer getBRIScope() {
+        return (table.isWritable()) ? ValuePool.getInt(bestRowTemporary)
+                                    : ValuePool.getInt(bestRowSession);
+    }
+
+    /**
+     * Retrieves the simple name of the specified column. <p>
+     *
+     * @param i zero-based column index
+     * @return the simple name of the specified column.
+     */
+    String getColName(int i) {
+        return table.getColumn(i).getName().name;
+    }
+
+    /**
+     * Retrieves the remarks, if any, recorded against the specified
+     * column. <p>
+     *
+     * @param i zero-based column index
+     * @return the remarks recorded against the specified column.
+     */
+    String getColRemarks(int i) {
+
+        String key;
+
+        if (table.getTableType() != TableBase.SYSTEM_TABLE) {
+            return null;
+        }
+
+        key = getName() + "_" + getColName(i);
+
+        return BundleHandler.getString(hnd_column_remarks, key);
+    }
+
+    /**
+     * Retrieves the HSQLDB-specific type of the table. <p>
+     *
+     * @return the HSQLDB-specific type of the table
+     */
+    String getHsqlType() {
+
+        switch (table.getTableType()) {
+
+            case TableBase.MEMORY_TABLE :
+            case TableBase.TEMP_TABLE :
+            case TableBase.SYSTEM_TABLE :
+                return "MEMORY";
+
+            case TableBase.CACHED_TABLE :
+                return "CACHED";
+
+            case TableBase.TEMP_TEXT_TABLE :
+            case TableBase.TEXT_TABLE :
+                return "TEXT";
+
+            case TableBase.VIEW_TABLE :
+            default :
+                return null;
+        }
+    }
+
+    /**
+     * Retrieves the simple name of the table. <p>
+     *
+     * @return the simple name of the table
+     */
+    String getName() {
+        return table.getName().name;
+    }
+
+    /**
+     * Retrieves the remarks (if any) recorded against the Table. <p>
+     *
+     * @return the remarks recorded against the Table
+     */
+    String getRemark() {
+
+        return (table.getTableType() == TableBase.SYSTEM_TABLE)
+               ? BundleHandler.getString(hnd_table_remarks, getName())
+               : table.getName().comment;
+    }
+
+    /**
+     * Retrieves the standard JDBC type of the table. <p>
+     *
+     * "TABLE" for user-defined tables, "VIEW" for user-defined views,
+     * and so on.
+     *
+     * @return the standard JDBC type of the table
+     */
+    String getJDBCStandardType() {
+
+        switch (table.getTableType()) {
+
+            case TableBase.VIEW_TABLE :
+                return "VIEW";
+
+            case TableBase.TEMP_TABLE :
+            case TableBase.TEMP_TEXT_TABLE :
+                return "GLOBAL TEMPORARY";
+
+            case TableBase.SYSTEM_TABLE :
+                return "SYSTEM TABLE";
+
+            default :
+                if (table.getOwner().isSystem() ) {
+                    return "SYSTEM TABLE";
+                }
+                return "TABLE";
+        }
+    }
+
+    /**
+     * Retrieves the Table object on which this object is currently
+     * reporting. <p>
+     *
+     * @return the Table object on which this object
+     *    is currently reporting
+     */
+    Table getTable() {
+        return this.table;
+    }
+
+    /**
+     * Assigns the Table object on which this object is to report. <p>
+     *
+     * @param table the Table object on which this object is to report
+     */
+    void setTable(Table table) {
+        this.table = table;
+    }
+}
diff --git a/src/org/hsqldb/dbinfo/DatabaseInformation.java b/src/org/hsqldb/dbinfo/DatabaseInformation.java
new file mode 100644
index 0000000..6d5b43a
--- /dev/null
+++ b/src/org/hsqldb/dbinfo/DatabaseInformation.java
@@ -0,0 +1,369 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.dbinfo;
+
+import java.lang.reflect.Constructor;
+
+import org.hsqldb.Database;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.lib.IntValueHashMap;
+
+// fredt@users - 1.7.2 - structural modifications to allow inheritance
+// boucherB@users 20020305 - completed inheritance work, including final access
+// boucherB@users 20020305 - javadoc updates/corrections
+// boucherB@users 20020305 - SYSTEM_VIEWS brought in line with SQL 200n
+// boucherb@users 20050514 - further SQL 200n metdata support
+
+/**
+ * Base class for system tables. Includes a factory method which returns the
+ * most complete implementation available in the jar. This base implementation
+ * knows the names of all system tables but returns null for any system table.
+ * <p>
+ * This class has been developed from scratch to replace the previous
+ * DatabaseInformation implementations. <p>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class DatabaseInformation {
+
+    // ids for system table names strictly in order of sysTableNames[]
+    protected static final int SYSTEM_BESTROWIDENTIFIER = 0;
+    protected static final int SYSTEM_COLUMNS           = 1;
+    protected static final int SYSTEM_CROSSREFERENCE    = 2;
+    protected static final int SYSTEM_INDEXINFO         = 3;
+    protected static final int SYSTEM_PRIMARYKEYS       = 4;
+    protected static final int SYSTEM_PROCEDURECOLUMNS  = 5;
+    protected static final int SYSTEM_PROCEDURES        = 6;
+    protected static final int SYSTEM_SCHEMAS           = 7;
+    protected static final int SYSTEM_TABLES            = 8;
+    protected static final int SYSTEM_TABLETYPES        = 9;
+    protected static final int SYSTEM_TYPEINFO          = 10;
+    protected static final int SYSTEM_UDTS              = 11;
+    protected static final int SYSTEM_USERS             = 12;    //-- ref in SqlFile only
+    protected static final int SYSTEM_VERSIONCOLUMNS    = 13;    //-- returns autogenerated columns
+    protected static final int SYSTEM_SEQUENCES = 14;            //-- same as SEQUENCES
+
+    // HSQLDB-specific
+    protected static final int SYSTEM_CACHEINFO             = 15;
+    protected static final int SYSTEM_COMMENTS              = 16;
+    protected static final int SYSTEM_CONNECTION_PROPERTIES = 17;
+    protected static final int SYSTEM_PROPERTIES            = 18;
+    protected static final int SYSTEM_SESSIONINFO           = 19;
+    protected static final int SYSTEM_SESSIONS              = 20;
+    protected static final int SYSTEM_TEXTTABLES            = 21;
+
+    // SQL 200n tables
+    protected static final int ADMINISTRABLE_ROLE_AUTHORIZATIONS = 22;
+    protected static final int APPLICABLE_ROLES                  = 23;
+    protected static final int ASSERTIONS                        = 24;
+    protected static final int AUTHORIZATIONS                    = 25;
+    protected static final int CHARACTER_SETS                    = 26;
+    protected static final int CHECK_CONSTRAINT_ROUTINE_USAGE    = 27;
+    protected static final int CHECK_CONSTRAINTS                 = 28;
+    protected static final int COLLATIONS                        = 29;
+    protected static final int COLUMN_COLUMN_USAGE               = 30;
+    protected static final int COLUMN_DOMAIN_USAGE               = 31;
+    protected static final int COLUMN_PRIVILEGES                 = 32;
+    protected static final int COLUMN_UDT_USAGE                  = 33;
+    protected static final int COLUMNS                           = 34;
+    protected static final int CONSTRAINT_COLUMN_USAGE           = 35;
+    protected static final int CONSTRAINT_TABLE_USAGE            = 36;
+    protected static final int DATA_TYPE_PRIVILEGES              = 37;
+    protected static final int DOMAIN_CONSTRAINTS                = 38;
+    protected static final int DOMAINS                           = 39;
+    protected static final int ENABLED_ROLES                     = 40;
+    protected static final int INFORMATION_SCHEMA_CATALOG_NAME   = 41;
+    protected static final int JAR_JAR_USAGE                     = 42;
+    protected static final int JARS                              = 43;
+    protected static final int KEY_COLUMN_USAGE                  = 44;
+    protected static final int METHOD_SPECIFICATIONS             = 45;
+    protected static final int MODULE_COLUMN_USAGE               = 46;
+    protected static final int MODULE_PRIVILEGES                 = 47;
+    protected static final int MODULE_TABLE_USAGE                = 48;
+    protected static final int MODULES                           = 49;
+    protected static final int PARAMETERS                        = 50;
+    protected static final int REFERENTIAL_CONSTRAINTS           = 51;
+    protected static final int ROLE_AUTHORIZATION_DESCRIPTORS    = 52;
+    protected static final int ROLE_COLUMN_GRANTS                = 53;
+    protected static final int ROLE_MODULE_GRANTS                = 54;
+    protected static final int ROLE_ROUTINE_GRANTS               = 55;
+    protected static final int ROLE_TABLE_GRANTS                 = 56;
+    protected static final int ROLE_UDT_GRANTS                   = 57;
+    protected static final int ROLE_USAGE_GRANTS                 = 58;
+    protected static final int ROUTINE_COLUMN_USAGE              = 59;
+    protected static final int ROUTINE_JAR_USAGE                 = 60;
+    protected static final int ROUTINE_PRIVILEGES                = 61;
+    protected static final int ROUTINE_ROUTINE_USAGE             = 62;
+    protected static final int ROUTINE_SEQUENCE_USAGE            = 63;
+    protected static final int ROUTINE_TABLE_USAGE               = 64;
+    protected static final int ROUTINES                          = 65;
+    protected static final int SCHEMATA                          = 66;
+    protected static final int SEQUENCES                         = 67;
+    protected static final int SQL_FEATURES                      = 68;
+    protected static final int SQL_IMPLEMENTATION_INFO           = 69;
+    protected static final int SQL_PACKAGES                      = 70;
+    protected static final int SQL_PARTS                         = 71;
+    protected static final int SQL_SIZING                        = 72;
+    protected static final int SQL_SIZING_PROFILES               = 73;
+    protected static final int TABLE_CONSTRAINTS                 = 74;
+    protected static final int TABLE_PRIVILEGES                  = 75;
+    protected static final int TABLES                            = 76;
+    protected static final int TRANSLATIONS                      = 77;
+    protected static final int TRIGGER_COLUMN_USAGE              = 78;
+    protected static final int TRIGGER_ROUTINE_USAGE             = 79;
+    protected static final int TRIGGER_SEQUENCE_USAGE            = 80;
+    protected static final int TRIGGER_TABLE_USAGE               = 81;
+    protected static final int TRIGGERED_UPDATE_COLUMNS          = 82;
+    protected static final int TRIGGERS                          = 83;
+    protected static final int TYPE_JAR_USAGE                    = 84;
+    protected static final int UDT_PRIVILEGES                    = 85;
+    protected static final int USAGE_PRIVILEGES                  = 86;
+    protected static final int USER_DEFINED_TYPES                = 87;
+    protected static final int VIEW_COLUMN_USAGE                 = 88;
+    protected static final int VIEW_ROUTINE_USAGE                = 89;
+    protected static final int VIEW_TABLE_USAGE                  = 90;
+    protected static final int VIEWS                             = 91;
+
+    /** system table names strictly in order of their ids */
+    protected static final String[] sysTableNames = {
+        "SYSTEM_BESTROWIDENTIFIER",                              //
+        "SYSTEM_COLUMNS",                                        //
+        "SYSTEM_CROSSREFERENCE",                                 //
+        "SYSTEM_INDEXINFO",                                      //
+        "SYSTEM_PRIMARYKEYS",                                    //
+        "SYSTEM_PROCEDURECOLUMNS",                               //
+        "SYSTEM_PROCEDURES",                                     //
+        "SYSTEM_SCHEMAS",                                        //
+        "SYSTEM_TABLES",                                         //
+        "SYSTEM_TABLETYPES",                                     //
+        "SYSTEM_TYPEINFO",                                       //
+        "SYSTEM_UDTS",                                           //
+        "SYSTEM_USERS",                                          //
+        "SYSTEM_VERSIONCOLUMNS",                                 //
+        "SYSTEM_SEQUENCES",                                      //
+
+        // HSQLDB-specific
+        "SYSTEM_CACHEINFO",                                      //
+        "SYSTEM_COMMENTS",
+        "SYSTEM_CONNECTION_PROPERTIES",                          //
+        "SYSTEM_PROPERTIES",                                     //
+        "SYSTEM_SESSIONINFO",                                    //
+        "SYSTEM_SESSIONS",                                       //
+        "SYSTEM_TEXTTABLES",                                     //
+
+        // SQL 200n
+        "ADMINISTRABLE_ROLE_AUTHORIZATIONS",                     //
+        "APPLICABLE_ROLES",                                      //
+        "ASSERTIONS",                                            //
+        "AUTHORIZATIONS",                                        //
+        "CHARACTER_SETS",                                        //
+        "CHECK_CONSTRAINT_ROUTINE_USAGE",                        //
+        "CHECK_CONSTRAINTS",                                     //
+        "COLLATIONS",                                            //
+        "COLUMN_COLUMN_USAGE",                                   //
+        "COLUMN_DOMAIN_USAGE",                                   //
+        "COLUMN_PRIVILEGES",                                     //
+        "COLUMN_UDT_USAGE",                                      //
+        "COLUMNS",                                               //
+        "CONSTRAINT_COLUMN_USAGE",                               //
+        "CONSTRAINT_TABLE_USAGE",                                //
+        "DATA_TYPE_PRIVILEGES",                                  //
+        "DOMAIN_CONSTRAINTS",                                    //
+        "DOMAINS",                                               //
+        "ENABLED_ROLES",                                         //
+        "INFORMATION_SCHEMA_CATALOG_NAME",                       //
+        "JAR_JAR_USAGE",                                         //
+        "JARS",                                                  //
+        "KEY_COLUMN_USAGE",                                      //
+        "METHOD_SPECIFICATIONS",                                 //
+        "MODULE_COLUMN_USAGE",                                   //
+        "MODULE_PRIVILEGES",                                     //
+        "MODULE_TABLE_USAGE",                                    //
+        "MODULES",                                               //
+        "PARAMETERS",                                            //
+        "REFERENTIAL_CONSTRAINTS",                               //
+        "ROLE_AUTHORIZATION_DESCRIPTORS",                        //
+        "ROLE_COLUMN_GRANTS",                                    //
+        "ROLE_MODULE_GRANTS",                                    //
+        "ROLE_ROUTINE_GRANTS",                                   //
+        "ROLE_TABLE_GRANTS",                                     //
+        "ROLE_UDT_GRANTS",                                       //
+        "ROLE_USAGE_GRANTS",                                     //
+        "ROUTINE_COLUMN_USAGE",                                  //
+        "ROUTINE_JAR_USAGE",                                     //
+        "ROUTINE_PRIVILEGES",                                    //
+        "ROUTINE_ROUTINE_USAGE",                                 //
+        "ROUTINE_SEQUENCE_USAGE",                                //
+        "ROUTINE_TABLE_USAGE",                                   //
+        "ROUTINES",                                              //
+        "SCHEMATA",                                              //
+        "SEQUENCES",                                             //
+        "SQL_FEATURES",                                          //
+        "SQL_IMPLEMENTATION_INFO",                               //
+        "SQL_PACKAGES",                                          //
+        "SQL_PARTS",                                             //
+        "SQL_SIZING",                                            //
+        "SQL_SIZING_PROFILES",                                   //
+        "TABLE_CONSTRAINTS",                                     //
+        "TABLE_PRIVILEGES",                                      //
+        "TABLES",                                                //
+        "TRANSLATIONS",                                          //
+        "TRIGGER_COLUMN_USAGE",                                  //
+        "TRIGGER_ROUTINE_USAGE",                                 //
+        "TRIGGER_SEQUENCE_USAGE",                                //
+        "TRIGGER_TABLE_USAGE",                                   //
+        "TRIGGERED_UPDATE_COLUMNS",                              //
+        "TRIGGERS",                                              //
+        "TYPE_JAR_USAGE",                                        //
+        "UDT_PRIVILEGES",                                        //
+        "USAGE_PRIVILEGES",                                      //
+        "USER_DEFINED_TYPES",                                    //
+        "VIEW_COLUMN_USAGE",                                     //
+        "VIEW_ROUTINE_USAGE",                                    //
+        "VIEW_TABLE_USAGE",                                      //
+        "VIEWS",                                                 //
+    };
+
+    /** Map: table name => table id */
+    protected static final IntValueHashMap sysTableNamesMap;
+
+    static {
+        synchronized (DatabaseInformation.class) {
+            sysTableNamesMap = new IntValueHashMap(97);
+
+            for (int i = 0; i < sysTableNames.length; i++) {
+                sysTableNamesMap.put(sysTableNames[i], i);
+            }
+        }
+    }
+
+    static int getSysTableID(String token) {
+        return sysTableNamesMap.get(token, -1);
+    }
+
+    /** Database for which to produce tables */
+    protected final Database database;
+
+    /**
+     * state flag -- if true, contentful tables are to be produced, else
+     * empty (surrogate) tables are to be produced.  This allows faster
+     * database startup where user views reference system tables and faster
+     * system table structural reflection for table metadata.
+     */
+    protected boolean withContent = false;
+
+    /**
+     * Factory method returns the fullest system table producer
+     * implementation available.  This instantiates implementations beginning
+     * with the most complete, finally choosing an empty table producer
+     * implemenation (this class) if no better instance can be constructed.
+     * @param db The Database object for which to produce system tables
+     * @return the fullest system table producer
+     *      implementation available
+     */
+    public static final DatabaseInformation newDatabaseInformation(
+            Database db) {
+
+        Class c = null;
+
+        try {
+            c = Class.forName("org.hsqldb.dbinfo.DatabaseInformationFull");
+        } catch (Exception e) {
+            try {
+                c = Class.forName("org.hsqldb.dbinfo.DatabaseInformationMain");
+            } catch (Exception e2) {
+                c = DatabaseInformation.class;
+            }
+        }
+
+        try {
+            Class[]     ctorParmTypes = new Class[]{ Database.class };
+            Object[]    ctorParms     = new Object[]{ db };
+            Constructor ctor = c.getDeclaredConstructor(ctorParmTypes);
+
+            return (DatabaseInformation) ctor.newInstance(ctorParms);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return new DatabaseInformation(db);
+    }
+
+    /**
+     * Constructs a new DatabaseInformation instance which knows the names of
+     * all system tables (isSystemTable()) but simpy returns null for all
+     * getSystemTable() requests. <p>
+     *
+     * @param db The Database object for which to produce system tables
+     */
+    DatabaseInformation(Database db) {
+        database = db;
+    }
+
+    /**
+     * Tests if the specified name is that of a system table. <p>
+     *
+     * @param name the name to test
+     * @return true if the specified name is that of a system table
+     */
+    final boolean isSystemTable(String name) {
+        return sysTableNamesMap.containsKey(name);
+    }
+
+    /**
+     * Retrieves a table with the specified name whose content may depend on
+     * the execution context indicated by the session argument as well as the
+     * current value of <code>withContent</code>. <p>
+     *
+     * @param session the context in which to produce the table
+     * @param name the name of the table to produce
+     * @return a table corresponding to the name and session arguments, or
+     *      <code>null</code> if there is no such table to be produced
+     */
+    public synchronized Table getSystemTable(Session session, String name) {
+        return null;
+    }
+
+    /**
+     * Switches this table producer between producing empty (surrogate)
+     * or contentful tables. <p>
+     *
+     * @param withContent if true, then produce contentful tables, else
+     *        produce emtpy (surrogate) tables
+     */
+    public synchronized final void setWithContent(boolean withContent) {
+        this.withContent = withContent;
+    }
+}
diff --git a/src/org/hsqldb/dbinfo/DatabaseInformationFull.java b/src/org/hsqldb/dbinfo/DatabaseInformationFull.java
new file mode 100644
index 0000000..68a0547
--- /dev/null
+++ b/src/org/hsqldb/dbinfo/DatabaseInformationFull.java
@@ -0,0 +1,7022 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.dbinfo;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+
+import org.hsqldb.Collation;
+import org.hsqldb.ColumnSchema;
+import org.hsqldb.Constraint;
+import org.hsqldb.Database;
+import org.hsqldb.Expression;
+import org.hsqldb.ExpressionColumn;
+import org.hsqldb.HsqlException;
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.NumberSequence;
+import org.hsqldb.Routine;
+import org.hsqldb.RoutineSchema;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.SchemaObjectSet;
+import org.hsqldb.Session;
+import org.hsqldb.SqlInvariants;
+import org.hsqldb.Table;
+import org.hsqldb.TextTable;
+import org.hsqldb.Tokens;
+import org.hsqldb.TriggerDef;
+import org.hsqldb.View;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.LineGroupReader;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.Set;
+import org.hsqldb.lib.WrapperIterator;
+import org.hsqldb.persist.DataFileCache;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.persist.TextCache;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.rights.Right;
+import org.hsqldb.scriptio.ScriptWriterBase;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.Charset;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+// fredt@users - 1.7.2 - structural modifications to allow inheritance
+// boucherb@users - 1.7.2 - 20020225
+// - factored out all reusable code into DIXXX support classes
+// - completed Fred's work on allowing inheritance
+// boucherb@users - 1.7.2 - 20020304 - bug fixes, refinements, better java docs
+// fredt@users - 1.8.0 - updated to report latest enhancements and changes
+// boucherb@users - 1.8.0 - 20050515 - further SQL 2003 metadata support
+// boucherb@users 20051207 - patch 1.8.x initial JDBC 4.0 support work
+// fredt@users - 1.9.0 - new tables + renaming + upgrade of some others to SQL/SCHEMATA
+// Revision 1.12  2006/07/12 11:42:09  boucherb
+//  - merging back remaining material overritten by Fred's type-system upgrades
+//  - rework to use grantee (versus user) orientation for certain system table content
+//  - update collation and character set reporting to correctly reflect SQL3 spec
+
+/**
+ * Provides definitions for most of the SQL Standard Schemata views that are
+ * supported by HSQLDB.<p>
+ *
+ * Provides definitions for some of HSQLDB's additional system vies.
+ *
+ * The definitions for the rest of system vies are provided by
+ * DatabaseInformationMain, which this class extends. <p>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+final class DatabaseInformationFull
+extends org.hsqldb.dbinfo.DatabaseInformationMain {
+
+    final static HashMappedList statementMap;
+
+    static {
+        synchronized (DatabaseInformationFull.class) {
+            final String resourceFileName =
+                "/org/hsqldb/resources/information-schema.sql";
+            final String[] starters = new String[]{ "/*" };
+            InputStream fis = DatabaseInformation.class.getResourceAsStream(
+                resourceFileName);
+            InputStreamReader reader = null;
+
+            try {
+                reader = new InputStreamReader(fis, "ISO-8859-1");
+            } catch (Exception e) {}
+
+            LineNumberReader lineReader = new LineNumberReader(reader);
+            LineGroupReader  lg = new LineGroupReader(lineReader, starters);
+
+            statementMap = lg.getAsMap();
+
+            lg.close();
+        }
+    }
+
+    /**
+     * Constructs a new DatabaseInformationFull instance. <p>
+     *
+     * @param db the database for which to produce system tables.
+     */
+    DatabaseInformationFull(Database db) {
+        super(db);
+    }
+
+    /**
+     * Retrieves the system table corresponding to the specified index. <p>
+     *
+     * @param tableIndex index identifying the system table to generate
+     * @return the system table corresponding to the specified index
+     */
+    protected Table generateTable(Session session, int tableIndex) {
+
+        switch (tableIndex) {
+
+            // HSQLDB-specific
+            case SYSTEM_CACHEINFO :
+                return SYSTEM_CACHEINFO(session);
+
+            case SYSTEM_COMMENTS :
+                return SYSTEM_COMMENTS(session);
+
+            case SYSTEM_SESSIONINFO :
+                return SYSTEM_SESSIONINFO(session);
+
+            case SYSTEM_PROPERTIES :
+                return SYSTEM_PROPERTIES(session);
+
+            case SYSTEM_SESSIONS :
+                return SYSTEM_SESSIONS(session);
+
+            case SYSTEM_TEXTTABLES :
+                return SYSTEM_TEXTTABLES(session);
+
+            // SQL views
+            case ADMINISTRABLE_ROLE_AUTHORIZATIONS :
+                return ADMINISTRABLE_ROLE_AUTHORIZATIONS(session);
+
+            case APPLICABLE_ROLES :
+                return APPLICABLE_ROLES(session);
+
+            case ASSERTIONS :
+                return ASSERTIONS(session);
+
+            case AUTHORIZATIONS :
+                return AUTHORIZATIONS(session);
+
+            case CHARACTER_SETS :
+                return CHARACTER_SETS(session);
+
+            case CHECK_CONSTRAINT_ROUTINE_USAGE :
+                return CHECK_CONSTRAINT_ROUTINE_USAGE(session);
+
+            case CHECK_CONSTRAINTS :
+                return CHECK_CONSTRAINTS(session);
+
+            case COLLATIONS :
+                return COLLATIONS(session);
+
+            case COLUMN_COLUMN_USAGE :
+                return COLUMN_COLUMN_USAGE(session);
+
+            case COLUMN_DOMAIN_USAGE :
+                return COLUMN_DOMAIN_USAGE(session);
+
+            case COLUMN_UDT_USAGE :
+                return COLUMN_UDT_USAGE(session);
+
+            case CONSTRAINT_COLUMN_USAGE :
+                return CONSTRAINT_COLUMN_USAGE(session);
+
+            case CONSTRAINT_TABLE_USAGE :
+                return CONSTRAINT_TABLE_USAGE(session);
+
+            case COLUMNS :
+                return COLUMNS(session);
+
+            case DATA_TYPE_PRIVILEGES :
+                return DATA_TYPE_PRIVILEGES(session);
+
+            case DOMAIN_CONSTRAINTS :
+                return DOMAIN_CONSTRAINTS(session);
+
+            case DOMAINS :
+                return DOMAINS(session);
+
+            case ENABLED_ROLES :
+                return ENABLED_ROLES(session);
+
+            case JAR_JAR_USAGE :
+                return JAR_JAR_USAGE(session);
+
+            case JARS :
+                return JARS(session);
+
+            case KEY_COLUMN_USAGE :
+                return KEY_COLUMN_USAGE(session);
+
+            case METHOD_SPECIFICATIONS :
+                return METHOD_SPECIFICATIONS(session);
+
+            case MODULE_COLUMN_USAGE :
+                return MODULE_COLUMN_USAGE(session);
+
+            case MODULE_PRIVILEGES :
+                return MODULE_PRIVILEGES(session);
+
+            case MODULE_TABLE_USAGE :
+                return MODULE_TABLE_USAGE(session);
+
+            case MODULES :
+                return MODULES(session);
+
+            case PARAMETERS :
+                return PARAMETERS(session);
+
+            case REFERENTIAL_CONSTRAINTS :
+                return REFERENTIAL_CONSTRAINTS(session);
+
+            case ROLE_AUTHORIZATION_DESCRIPTORS :
+                return ROLE_AUTHORIZATION_DESCRIPTORS(session);
+
+            case ROLE_COLUMN_GRANTS :
+                return ROLE_COLUMN_GRANTS(session);
+
+            case ROLE_ROUTINE_GRANTS :
+                return ROLE_ROUTINE_GRANTS(session);
+
+            case ROLE_TABLE_GRANTS :
+                return ROLE_TABLE_GRANTS(session);
+
+            case ROLE_USAGE_GRANTS :
+                return ROLE_USAGE_GRANTS(session);
+
+            case ROLE_UDT_GRANTS :
+                return ROLE_UDT_GRANTS(session);
+
+            case ROUTINE_COLUMN_USAGE :
+                return ROUTINE_COLUMN_USAGE(session);
+
+            case ROUTINE_JAR_USAGE :
+                return ROUTINE_JAR_USAGE(session);
+
+            case ROUTINE_PRIVILEGES :
+                return ROUTINE_PRIVILEGES(session);
+
+            case ROUTINE_ROUTINE_USAGE :
+                return ROUTINE_ROUTINE_USAGE(session);
+
+            case ROUTINE_SEQUENCE_USAGE :
+                return ROUTINE_SEQUENCE_USAGE(session);
+
+            case ROUTINE_TABLE_USAGE :
+                return ROUTINE_TABLE_USAGE(session);
+
+            case ROUTINES :
+                return ROUTINES(session);
+
+            case SCHEMATA :
+                return SCHEMATA(session);
+
+            case SEQUENCES :
+                return SEQUENCES(session);
+
+            case SQL_FEATURES :
+                return SQL_FEATURES(session);
+
+            case SQL_IMPLEMENTATION_INFO :
+                return SQL_IMPLEMENTATION_INFO(session);
+
+            case SQL_PACKAGES :
+                return SQL_PACKAGES(session);
+
+            case SQL_PARTS :
+                return SQL_PARTS(session);
+
+            case SQL_SIZING :
+                return SQL_SIZING(session);
+
+            case SQL_SIZING_PROFILES :
+                return SQL_SIZING_PROFILES(session);
+
+            case TABLE_CONSTRAINTS :
+                return TABLE_CONSTRAINTS(session);
+
+            case TABLES :
+                return TABLES(session);
+
+            case TRANSLATIONS :
+                return TRANSLATIONS(session);
+
+            case TRIGGERED_UPDATE_COLUMNS :
+                return TRIGGERED_UPDATE_COLUMNS(session);
+
+            case TRIGGER_COLUMN_USAGE :
+                return TRIGGER_COLUMN_USAGE(session);
+
+            case TRIGGER_ROUTINE_USAGE :
+                return TRIGGER_ROUTINE_USAGE(session);
+
+            case TRIGGER_SEQUENCE_USAGE :
+                return TRIGGER_SEQUENCE_USAGE(session);
+
+            case TRIGGER_TABLE_USAGE :
+                return TRIGGER_TABLE_USAGE(session);
+
+            case TRIGGERS :
+                return TRIGGERS(session);
+
+            case UDT_PRIVILEGES :
+                return UDT_PRIVILEGES(session);
+
+            case USAGE_PRIVILEGES :
+                return USAGE_PRIVILEGES(session);
+
+            case USER_DEFINED_TYPES :
+                return USER_DEFINED_TYPES(session);
+
+            case VIEW_COLUMN_USAGE :
+                return VIEW_COLUMN_USAGE(session);
+
+            case VIEW_ROUTINE_USAGE :
+                return VIEW_ROUTINE_USAGE(session);
+
+            case VIEW_TABLE_USAGE :
+                return VIEW_TABLE_USAGE(session);
+
+            case VIEWS :
+                return VIEWS(session);
+
+            default :
+                return super.generateTable(session, tableIndex);
+        }
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the current
+     * state of all row caching objects for the accessible
+     * tables defined within this database. <p>
+     *
+     * Currently, the row caching objects for which state is reported are: <p>
+     *
+     * <OL>
+     * <LI> the system-wide <code>Cache</code> object used by CACHED tables.
+     * <LI> any <code>TextCache</code> objects in use by [TEMP] TEXT tables.
+     * </OL> <p>
+     *
+     * Each row is a cache object state description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * CACHE_FILE          CHARACTER_DATA   absolute path of cache data file
+     * MAX_CACHE_SIZE      INTEGER   maximum allowable cached Row objects
+     * MAX_CACHE_BYTE_SIZE INTEGER   maximum allowable size of cached Row objects
+     * CACHE_LENGTH        INTEGER   number of data bytes currently cached
+     * CACHE_SIZE          INTEGER   number of rows currently cached
+     * FREE_BYTES          INTEGER   total bytes in available file allocation units
+     * FREE_COUNT          INTEGER   total # of allocation units available
+     * FREE_POS            INTEGER   largest file position allocated + 1
+     * </pre> <p>
+     *
+     * <b>Notes:</b> <p>
+     *
+     * <code>TextCache</code> objects do not maintain a free list because
+     * deleted rows are only marked deleted and never reused. As such, the
+     * columns FREE_BYTES, SMALLEST_FREE_ITEM, LARGEST_FREE_ITEM, and
+     * FREE_COUNT are always reported as zero for rows reporting on
+     * <code>TextCache</code> objects. <p>
+     *
+     * Currently, CACHE_SIZE, FREE_BYTES, SMALLEST_FREE_ITEM, LARGEST_FREE_ITEM,
+     * FREE_COUNT and FREE_POS are the only dynamically changing values.
+     * All others are constant for the life of a cache object. In a future
+     * release, other column values may also change over the life of a cache
+     * object, as SQL syntax may eventually be introduced to allow runtime
+     * modification of certain cache properties. <p>
+     *
+     * @return a description of the current state of all row caching
+     *      objects associated with the accessible tables of the database
+     */
+    Table SYSTEM_CACHEINFO(Session session) {
+
+        Table t = sysTables[SYSTEM_CACHEINFO];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_CACHEINFO]);
+
+            addColumn(t, "CACHE_FILE", CHARACTER_DATA);          // not null
+            addColumn(t, "MAX_CACHE_COUNT", CARDINAL_NUMBER);    // not null
+            addColumn(t, "MAX_CACHE_BYTES", CARDINAL_NUMBER);    // not null
+            addColumn(t, "CACHE_SIZE", CARDINAL_NUMBER);         // not null
+            addColumn(t, "CACHE_BYTES", CARDINAL_NUMBER);        // not null
+            addColumn(t, "FILE_FREE_BYTES", CARDINAL_NUMBER);    // not null
+            addColumn(t, "FILE_FREE_COUNT", CARDINAL_NUMBER);    // not null
+            addColumn(t, "FILE_FREE_POS", CARDINAL_NUMBER);      // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_CACHEINFO].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        // column number mappings
+        final int icache_file      = 0;
+        final int imax_cache_sz    = 1;
+        final int imax_cache_bytes = 2;
+        final int icache_size      = 3;
+        final int icache_length    = 4;
+        final int ifree_bytes      = 5;
+        final int ifree_count      = 6;
+        final int ifree_pos        = 7;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        DataFileCache   cache = null;
+        Object[]        row;
+        HashSet         cacheSet;
+        Iterator        caches;
+        Iterator        tables;
+        Table           table;
+        int             iFreeBytes;
+        int             iLargestFreeItem;
+        long            lSmallestFreeItem;
+
+        // Initialization
+        cacheSet = new HashSet();
+
+        // dynamic system tables are never cached
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            PersistentStore currentStore = session.sessionData.getRowStore(t);
+
+            if (session.getGrantee().isFullyAccessibleByRole(
+                    table.getName())) {
+                if (currentStore != null) {
+                    cache = currentStore.getCache();
+                }
+
+                if (cache != null) {
+                    cacheSet.add(cache);
+                }
+            }
+        }
+
+        caches = cacheSet.iterator();
+
+        // Do it.
+        while (caches.hasNext()) {
+            cache = (DataFileCache) caches.next();
+            row   = t.getEmptyRowData();
+            row[icache_file] = FileUtil.getFileUtil().canonicalOrAbsolutePath(
+                cache.getFileName());
+            row[imax_cache_sz]    = ValuePool.getLong(cache.capacity());
+            row[imax_cache_bytes] = ValuePool.getLong(cache.bytesCapacity());
+            row[icache_size] = ValuePool.getLong(cache.getCachedObjectCount());
+            row[icache_length] =
+                ValuePool.getLong(cache.getTotalCachedBlockSize());
+            row[ifree_bytes] =
+                ValuePool.getLong(cache.getTotalFreeBlockSize());
+            row[ifree_count] = ValuePool.getLong(cache.getFreeBlockCount());
+            row[ifree_pos]   = ValuePool.getLong(cache.getFileFreePos());
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    Table SYSTEM_COMMENTS(Session session) {
+
+        Table t = sysTables[SYSTEM_COMMENTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_COMMENTS]);
+
+            addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "OBJECT_TYPE", SQL_IDENTIFIER);
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COMMENT", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_COMMENTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int catalog     = 0;
+        final int schema      = 1;
+        final int name        = 2;
+        final int type        = 3;
+        final int column_name = 4;
+        final int remark      = 5;
+        Iterator  it;
+        Object[]  row;
+
+        //
+        DITableInfo ti = new DITableInfo();
+
+        it = allTables();
+
+        while (it.hasNext()) {
+            Table table = (Table) it.next();
+
+            if (!session.getGrantee().isAccessible(table)) {
+                continue;
+            }
+
+            ti.setTable(table);
+
+            int colCount = table.getColumnCount();
+
+            for (int i = 0; i < colCount; i++) {
+                ColumnSchema column = table.getColumn(i);
+
+                if (column.getName().comment == null) {
+                    continue;
+                }
+
+                row              = t.getEmptyRowData();
+                row[catalog]     = database.getCatalogName().name;
+                row[schema]      = table.getSchemaName().name;
+                row[name]        = table.getName().name;
+                row[type]        = "COLUMN";
+                row[column_name] = column.getName().name;
+                row[remark]      = column.getName().comment;
+
+                t.insertSys(store, row);
+            }
+
+            if (table.getTableType() != Table.SYSTEM_TABLE
+                    && table.getName().comment == null) {
+                continue;
+            }
+
+            row          = t.getEmptyRowData();
+            row[catalog] = database.getCatalogName().name;
+            row[schema]  = table.getSchemaName().name;
+            row[name]    = table.getName().name;
+            row[type] = table.isView()
+                        || table.getTableType() == Table.SYSTEM_TABLE ? "VIEW"
+                                                                      : "TABLE";
+            row[column_name] = null;
+            row[remark]      = ti.getRemark();
+
+            t.insertSys(store, row);
+        }
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (it.hasNext()) {
+            SchemaObject object = (SchemaObject) it.next();
+
+            if (!session.getGrantee().isAccessible(object)) {
+                continue;
+            }
+
+            if (object.getName().comment == null) {
+                continue;
+            }
+
+            row              = t.getEmptyRowData();
+            row[catalog]     = database.getCatalogName().name;
+            row[schema]      = object.getSchemaName().name;
+            row[name]        = object.getName().name;
+            row[type]        = "ROUTINE";
+            row[column_name] = null;
+            row[remark]      = object.getName().comment;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the capabilities
+     * and operating parameter properties for the engine hosting this
+     * database, as well as their applicability in terms of scope and
+     * name space. <p>
+     *
+     * Reported properties include certain predefined <code>Database</code>
+     * properties file values as well as certain database scope
+     * attributes. <p>
+     *
+     * It is intended that all <code>Database</code> attributes and
+     * properties that can be set via the database properties file,
+     * JDBC connection properties or SQL SET/ALTER statements will
+     * eventually be reported here or, where more applicable, in an
+     * ANSI/ISO conforming feature info base table in the defintion
+     * schema. <p>
+     *
+     * Currently, the database properties reported are: <p>
+     *
+     * <OL>
+     *     <LI>hsqldb.cache_file_scale - the scaling factor used to translate data and index structure file pointers
+     *     <LI>hsqldb.cache_scale - base-2 exponent scaling allowable cache row count
+     *     <LI>hsqldb.cache_size_scale - base-2 exponent scaling allowable cache byte count
+     *     <LI>hsqldb.cache_version -
+     *     <LI>hsqldb.catalogs - whether to report the database catalog (database uri)
+     *     <LI>hsqldb.compatible_version -
+     *     <LI>hsqldb.files_readonly - whether the database is in files_readonly mode
+     *     <LI>hsqldb.gc_interval - # new records forcing gc ({0|NULL}=>never)
+     *     <LI>hsqldb.max_nio_scale - scale factor for cache nio mapped buffers
+     *     <LI>hsqldb.nio_data_file - whether cache uses nio mapped buffers
+     *     <LI>hsqldb.original_version -
+     *     <LI>sql.enforce_strict_size - column length specifications enforced strictly (raise exception on overflow)?
+     *     <LI>textdb.all_quoted - default policy regarding whether to quote all character field values
+     *     <LI>textdb.cache_scale - base-2 exponent scaling allowable cache row count
+     *     <LI>textdb.cache_size_scale - base-2 exponent scaling allowable cache byte count
+     *     <LI>textdb.encoding - default TEXT table file encoding
+     *     <LI>textdb.fs - default field separator
+     *     <LI>textdb.vs - default varchar field separator
+     *     <LI>textdb.lvs - default long varchar field separator
+     *     <LI>textdb.ignore_first - default policy regarding whether to ignore the first line
+     *     <LI>textdb.quoted - default policy regarding treatement character field values that _may_ require quoting
+     *     <LI>IGNORECASE - create table VARCHAR_IGNORECASE?
+     *     <LI>LOGSIZSE - # bytes to which REDO log grows before auto-checkpoint
+     *     <LI>REFERENTIAL_INTEGITY - currently enforcing referential integrity?
+     *     <LI>SCRIPTFORMAT - 0 : TEXT, 1 : BINARY, ...
+     *     <LI>WRITEDELAY - does REDO log currently use buffered write strategy?
+     * </OL> <p>
+     *
+     * @return table describing database and session operating parameters
+     *      and capabilities
+     */
+    Table SYSTEM_PROPERTIES(Session session) {
+
+        Table t = sysTables[SYSTEM_PROPERTIES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_PROPERTIES]);
+
+            addColumn(t, "PROPERTY_SCOPE", CHARACTER_DATA);
+            addColumn(t, "PROPERTY_NAMESPACE", CHARACTER_DATA);
+            addColumn(t, "PROPERTY_NAME", CHARACTER_DATA);
+            addColumn(t, "PROPERTY_VALUE", CHARACTER_DATA);
+            addColumn(t, "PROPERTY_CLASS", CHARACTER_DATA);
+
+            // order PROPERTY_SCOPE, PROPERTY_NAMESPACE, PROPERTY_NAME
+            // true PK
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_PROPERTIES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, true);
+
+            return t;
+        }
+
+        // column number mappings
+        final int iscope = 0;
+        final int ins    = 1;
+        final int iname  = 2;
+        final int ivalue = 3;
+        final int iclass = 4;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        String scope;
+        String nameSpace;
+
+        // intermediate holders
+        Object[]               row;
+        HsqlDatabaseProperties props;
+
+        // First, we want the names and values for
+        // all JDBC capabilities constants
+        scope     = "SESSION";
+        props     = database.getProperties();
+        nameSpace = "database.properties";
+
+        // boolean properties
+        Iterator it = props.getUserDefinedPropertyData().iterator();
+
+        while (it.hasNext()) {
+            Object[] metaData = (Object[]) it.next();
+
+            row         = t.getEmptyRowData();
+            row[iscope] = scope;
+            row[ins]    = nameSpace;
+            row[iname]  = metaData[HsqlProperties.indexName];
+            row[ivalue] = props.getProperty((String) row[iname]);
+            row[iclass] = metaData[HsqlProperties.indexClass];
+
+            t.insertSys(store, row);
+        }
+
+        row         = t.getEmptyRowData();
+        row[iscope] = scope;
+        row[ins]    = nameSpace;
+        row[iname]  = "SCRIPT FORMAT";
+
+        try {
+            row[ivalue] =
+                ScriptWriterBase
+                    .LIST_SCRIPT_FORMATS[database.logger.getScriptType()];
+        } catch (Exception e) {}
+
+        row[iclass] = "String";
+
+        t.insertSys(store, row);
+
+        // write delay
+        row         = t.getEmptyRowData();
+        row[iscope] = scope;
+        row[ins]    = nameSpace;
+        row[iname]  = "WRITE DELAY";
+        row[ivalue] = "" + database.logger.getWriteDelay();
+        row[iclass] = "Integer";
+
+        t.insertSys(store, row);
+
+        // referential integrity
+        row         = t.getEmptyRowData();
+        row[iscope] = scope;
+        row[ins]    = nameSpace;
+        row[iname]  = "REFERENTIAL INTEGRITY";
+        row[ivalue] = database.isReferentialIntegrity() ? "true"
+                                                        : "false";
+        row[iclass] = "Boolean";
+
+        t.insertSys(store, row);
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing attributes
+     * for the calling session context.<p>
+     *
+     * The rows report the following {key,value} pairs:<p>
+     *
+     * <pre class="SqlCodeExample">
+     * KEY (VARCHAR)       VALUE (VARCHAR)
+     * ------------------- ---------------
+     * SESSION_ID          the id of the calling session
+     * AUTOCOMMIT          YES: session is in autocommit mode, else NO
+     * USER                the name of user connected in the calling session
+     * (was READ_ONLY)
+     * SESSION_READONLY    TRUE: session is in read-only mode, else FALSE
+     * (new)
+     * DATABASE_READONLY   TRUE: database is in read-only mode, else FALSE
+     * MAXROWS             the MAXROWS setting in the calling session
+     * DATABASE            the name of the database
+     * IDENTITY            the last identity value used by calling session
+     * </pre>
+     *
+     * <b>Note:</b>  This table <em>may</em> become deprecated in a future
+     * release, as the information it reports now duplicates information
+     * reported in the newer SYSTEM_SESSIONS and SYSTEM_PROPERTIES
+     * tables. <p>
+     *
+     * @return a <code>Table</code> object describing the
+     *        attributes of the connection associated
+     *        with the current execution context
+     */
+    Table SYSTEM_SESSIONINFO(Session session) {
+
+        Table t = sysTables[SYSTEM_SESSIONINFO];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_SESSIONINFO]);
+
+            addColumn(t, "KEY", CHARACTER_DATA);      // not null
+            addColumn(t, "VALUE", CHARACTER_DATA);    // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_SESSIONINFO].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Object[]        row;
+
+        row    = t.getEmptyRowData();
+        row[0] = "SESSION ID";
+        row[1] = String.valueOf(session.getId());
+
+        t.insertSys(store, row);
+
+        row    = t.getEmptyRowData();
+        row[0] = "AUTOCOMMIT";
+        row[1] = session.isAutoCommit() ? Tokens.T_TRUE
+                                        : Tokens.T_FALSE;
+
+        t.insertSys(store, row);
+
+        row    = t.getEmptyRowData();
+        row[0] = "USER";
+        row[1] = session.getUsername();
+
+        t.insertSys(store, row);
+
+        row    = t.getEmptyRowData();
+        row[0] = "SESSION READONLY";
+        row[1] = session.isReadOnlyDefault() ? Tokens.T_TRUE
+                                             : Tokens.T_FALSE;
+
+        t.insertSys(store, row);
+
+        row    = t.getEmptyRowData();
+        row[0] = "DATABASE READONLY";
+        row[1] = database.isReadOnly() ? Tokens.T_TRUE
+                                       : Tokens.T_FALSE;
+
+        t.insertSys(store, row);
+
+        row    = t.getEmptyRowData();
+        row[0] = "DATABASE";
+        row[1] = database.getURI();
+
+        t.insertSys(store, row);
+
+        row    = t.getEmptyRowData();
+        row[0] = "IDENTITY";
+        row[1] = String.valueOf(session.getLastIdentity());
+
+        t.insertSys(store, row);
+
+        row    = t.getEmptyRowData();
+        row[0] = "CURRENT SCHEMA";
+        row[1] = String.valueOf(session.getSchemaName(null));
+
+        t.insertSys(store, row);
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing all visible
+     * sessions. ADMIN users see *all* sessions
+     * while non-admin users see only their own session.<p>
+     *
+     * Each row is a session state description with the following columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * SESSION_ID         BIGINT    session identifier
+     * CONNECTED          TIMESTAMP time at which session was created
+     * USER_NAME          VARCHAR   db user name of current session user
+     * IS_ADMIN           BOOLEAN   is session user an admin user?
+     * AUTOCOMMIT         BOOLEAN   is session in autocommit mode?
+     * READONLY           BOOLEAN   is session in read-only mode?
+     * LAST_IDENTITY      BIGINT    last identity value used by this session
+     * TRANSACTION_SIZE   BIGINT   # of undo items in current transaction
+     * SCHEMA             VARCHAR   current schema for session
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing all visible
+     *      sessions
+     */
+    Table SYSTEM_SESSIONS(Session session) {
+
+        Table t = sysTables[SYSTEM_SESSIONS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_SESSIONS]);
+
+            addColumn(t, "SESSION_ID", CARDINAL_NUMBER);
+            addColumn(t, "CONNECTED", TIME_STAMP);
+            addColumn(t, "USER_NAME", SQL_IDENTIFIER);
+            addColumn(t, "IS_ADMIN", Type.SQL_BOOLEAN);
+            addColumn(t, "AUTOCOMMIT", Type.SQL_BOOLEAN);
+            addColumn(t, "READONLY", Type.SQL_BOOLEAN);
+
+            // Note: some sessions may have a NULL LAST_IDENTITY value
+            addColumn(t, "LAST_IDENTITY", CARDINAL_NUMBER);
+            addColumn(t, "TRANSACTION_SIZE", CARDINAL_NUMBER);
+            addColumn(t, "SCHEMA", SQL_IDENTIFIER);
+
+            // order:  SESSION_ID
+            // true primary key
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_SESSIONS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        // column number mappings
+        final int isid      = 0;
+        final int ict       = 1;
+        final int iuname    = 2;
+        final int iis_admin = 3;
+        final int iautocmt  = 4;
+        final int ireadonly = 5;
+        final int ilast_id  = 6;
+        final int it_size   = 7;
+        final int it_schema = 8;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // intermediate holders
+        Session[] sessions;
+        Session   s;
+        Object[]  row;
+
+        // Initialisation
+        sessions = database.sessionManager.getVisibleSessions(session);
+
+        // Do it.
+        for (int i = 0; i < sessions.length; i++) {
+            s              = sessions[i];
+            row            = t.getEmptyRowData();
+            row[isid]      = ValuePool.getLong(s.getId());
+            row[ict]       = new TimestampData(s.getConnectTime() / 1000);
+            row[iuname]    = s.getUsername();
+            row[iis_admin] = ValuePool.getBoolean(s.isAdmin());
+            row[iautocmt]  = ValuePool.getBoolean(s.isAutoCommit());
+            row[ireadonly] = ValuePool.getBoolean(s.isReadOnlyDefault());
+            row[ilast_id] =
+                ValuePool.getLong(((Number) s.getLastIdentity()).longValue());
+            row[it_size]   = ValuePool.getLong(s.getTransactionSize());
+            row[it_schema] = s.getCurrentSchemaHsqlName().name;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the TEXT TABLE objects
+     * defined within this database. The table contains one row for each row
+     * in the SYSTEM_TABLES table with a HSQLDB_TYPE of  TEXT . <p>
+     *
+     * Each row is a description of the attributes that defines its TEXT TABLE,
+     * with the following columns:
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_CAT                 VARCHAR   table's catalog name
+     * TABLE_SCHEM               VARCHAR   table's simple schema name
+     * TABLE_NAME                VARCHAR   table's simple name
+     * DATA_SOURCE_DEFINITION    VARCHAR   the "spec" proption of the table's
+     *                                     SET TABLE ... SOURCE DDL declaration
+     * FILE_PATH                 VARCHAR   absolute file path.
+     * FILE_ENCODING             VARCHAR   endcoding of table's text file
+     * FIELD_SEPARATOR           VARCHAR   default field separator
+     * VARCHAR_SEPARATOR         VARCAHR   varchar field separator
+     * LONGVARCHAR_SEPARATOR     VARCHAR   longvarchar field separator
+     * IS_IGNORE_FIRST           BOOLEAN   ignores first line of file?
+     * IS_QUOTED                 BOOLEAN   fields are quoted if necessary?
+     * IS_ALL_QUOTED             BOOLEAN   all fields are quoted?
+     * IS_DESC                   BOOLEAN   read rows starting at end of file?
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the text attributes
+     * of the accessible text tables defined within this database
+     *
+     */
+    Table SYSTEM_TEXTTABLES(Session session) {
+
+        Table t = sysTables[SYSTEM_TEXTTABLES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_TEXTTABLES]);
+
+            addColumn(t, "TABLE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "DATA_SOURCE_DEFINTION", CHARACTER_DATA);
+            addColumn(t, "FILE_PATH", CHARACTER_DATA);
+            addColumn(t, "FILE_ENCODING", CHARACTER_DATA);
+            addColumn(t, "FIELD_SEPARATOR", CHARACTER_DATA);
+            addColumn(t, "VARCHAR_SEPARATOR", CHARACTER_DATA);
+            addColumn(t, "LONGVARCHAR_SEPARATOR", CHARACTER_DATA);
+            addColumn(t, "IS_IGNORE_FIRST", Type.SQL_BOOLEAN);
+            addColumn(t, "IS_ALL_QUOTED", Type.SQL_BOOLEAN);
+            addColumn(t, "IS_QUOTED", Type.SQL_BOOLEAN);
+            addColumn(t, "IS_DESC", Type.SQL_BOOLEAN);
+
+            // ------------------------------------------------------------
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_TEXTTABLES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2,
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int itable_cat   = 0;
+        final int itable_schem = 1;
+        final int itable_name  = 2;
+        final int idsd         = 3;
+        final int ifile_path   = 4;
+        final int ifile_enc    = 5;
+        final int ifs          = 6;
+        final int ivfs         = 7;
+        final int ilvfs        = 8;
+        final int iif          = 9;
+        final int iiq          = 10;
+        final int iiaq         = 11;
+        final int iid          = 12;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // intermediate holders
+        Iterator tables;
+        Table    table;
+        Object[] row;
+
+        // Initialization
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            PersistentStore currentStore = session.sessionData.getRowStore(t);
+
+            if (!table.isText() || !isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            row               = t.getEmptyRowData();
+            row[itable_cat]   = database.getCatalogName().name;
+            row[itable_schem] = table.getSchemaName().name;
+            row[itable_name]  = table.getName().name;
+            row[idsd]         = ((TextTable) table).getDataSource();
+
+            TextCache cache = (TextCache) currentStore.getCache();
+
+            if (cache != null) {
+                row[ifile_path] =
+                    FileUtil.getFileUtil().canonicalOrAbsolutePath(
+                        cache.getFileName());
+                row[ifile_enc] = cache.stringEncoding;
+                row[ifs]       = cache.fs;
+                row[ivfs]      = cache.vs;
+                row[ilvfs]     = cache.lvs;
+                row[iif]       = ValuePool.getBoolean(cache.ignoreFirst);
+                row[iiq]       = ValuePool.getBoolean(cache.isQuoted);
+                row[iiaq]      = ValuePool.getBoolean(cache.isAllQuoted);
+                row[iid] = ((TextTable) table).isDescDataSource()
+                           ? Boolean.TRUE
+                           : Boolean.FALSE;
+            }
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+//------------------------------------------------------------------------------
+// SQL SCHEMATA VIEWS
+
+    /**
+     * Returns roles that are grantable by an admin user, which means all the
+     * roles
+     *
+     * @return Table
+     */
+    Table ADMINISTRABLE_ROLE_AUTHORIZATIONS(Session session) {
+
+        Table t = sysTables[ADMINISTRABLE_ROLE_AUTHORIZATIONS];
+
+        if (t == null) {
+            t = createBlankTable(
+                sysTableHsqlNames[ADMINISTRABLE_ROLE_AUTHORIZATIONS]);
+
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);
+            addColumn(t, "ROLE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "IS_GRANTABLE", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ADMINISTRABLE_ROLE_AUTHORIZATIONS].name,
+                false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        if (session.isAdmin()) {
+            insertRoles(session, t, session.getGrantee(), true);
+        }
+
+        return t;
+    }
+
+    /**
+     * APPLICABLE_ROLES<p>
+     *
+     * <b>Function</b><p>
+     *
+     * Identifies the applicable roles for the current user.<p>
+     *
+     * <b>Definition</b><p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE RECURSIVE VIEW APPLICABLE_ROLES ( GRANTEE, ROLE_NAME, IS_GRANTABLE ) AS
+     *      ( ( SELECT GRANTEE, ROLE_NAME, IS_GRANTABLE
+     *            FROM DEFINITION_SCHEMA.ROLE_AUTHORIZATION_DESCRIPTORS
+     *           WHERE ( GRANTEE IN ( CURRENT_USER, 'PUBLIC' )
+     *                OR GRANTEE IN ( SELECT ROLE_NAME
+     *                                  FROM ENABLED_ROLES ) ) )
+     *      UNION
+     *      ( SELECT RAD.GRANTEE, RAD.ROLE_NAME, RAD.IS_GRANTABLE
+     *          FROM DEFINITION_SCHEMA.ROLE_AUTHORIZATION_DESCRIPTORS RAD
+     *          JOIN APPLICABLE_ROLES R
+     *            ON RAD.GRANTEE = R.ROLE_NAME ) );
+     *
+     * GRANT SELECT ON TABLE APPLICABLE_ROLES
+     *    TO PUBLIC WITH GRANT OPTION;
+     * </pre>
+     */
+    Table APPLICABLE_ROLES(Session session) {
+
+        Table t = sysTables[APPLICABLE_ROLES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[APPLICABLE_ROLES]);
+
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);
+            addColumn(t, "ROLE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "IS_GRANTABLE", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[APPLICABLE_ROLES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        insertRoles(session, t, session.getGrantee(), session.isAdmin());
+
+        return t;
+    }
+
+    private void insertRoles(Session session, Table t, Grantee role,
+                             boolean isGrantable) {
+
+        final int       grantee      = 0;
+        final int       role_name    = 1;
+        final int       is_grantable = 2;
+        PersistentStore store        = session.sessionData.getRowStore(t);
+
+        if (isGrantable) {
+            Set      roles = database.getGranteeManager().getRoleNames();
+            Iterator it    = roles.iterator();
+
+            while (it.hasNext()) {
+                String   roleName = (String) it.next();
+                Object[] row      = t.getEmptyRowData();
+
+                row[grantee]      = role.getNameString();
+                row[role_name]    = roleName;
+                row[is_grantable] = "YES";
+
+                t.insertSys(store, row);
+            }
+        } else {
+            OrderedHashSet roles = role.getDirectRoles();
+
+            for (int i = 0; i < roles.size(); i++) {
+                String   roleName = (String) roles.get(i);
+                Object[] row      = t.getEmptyRowData();
+
+                row[grantee]      = role.getNameString();
+                row[role_name]    = roleName;
+                row[is_grantable] = Tokens.T_NO;
+
+                t.insertSys(store, row);
+
+                role = database.getGranteeManager().getRole(roleName);
+
+                insertRoles(session, t, role, isGrantable);
+            }
+        }
+    }
+
+    Table ASSERTIONS(Session session) {
+
+        Table t = sysTables[ASSERTIONS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ASSERTIONS]);
+
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "IS_DEFERRABLE", YES_OR_NO);
+            addColumn(t, "INITIALLY_DEFERRED", YES_OR_NO);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ASSERTIONS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        final int constraint_catalog = 0;
+        final int constraint_schema  = 1;
+        final int constraint_name    = 2;
+        final int is_deferrable      = 3;
+        final int initially_deferred = 4;
+
+        return t;
+    }
+
+    /**
+     *  SYSTEM_AUTHORIZATIONS<p>
+     *
+     *  <b>Function</b><p>
+     *
+     *  The AUTHORIZATIONS table has one row for each &lt;role name&gt; and
+     *  one row for each &lt;authorization identifier &gt; referenced in the
+     *  Information Schema. These are the &lt;role name&gt;s and
+     *  &lt;authorization identifier&gt;s that may grant privileges as well as
+     *  those that may create a schema, or currently own a schema created
+     *  through a &lt;schema definition&gt;. <p>
+     *
+     *  <b>Definition</b><p>
+     *
+     *  <pre class="SqlCodeExample">
+     *  CREATE TABLE AUTHORIZATIONS (
+     *       AUTHORIZATION_NAME INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *       AUTHORIZATION_TYPE INFORMATION_SCHEMA.CHARACTER_DATA
+     *           CONSTRAINT AUTHORIZATIONS_AUTHORIZATION_TYPE_NOT_NULL
+     *               NOT NULL
+     *           CONSTRAINT AUTHORIZATIONS_AUTHORIZATION_TYPE_CHECK
+     *               CHECK ( AUTHORIZATION_TYPE IN ( 'USER', 'ROLE' ) ),
+     *           CONSTRAINT AUTHORIZATIONS_PRIMARY_KEY
+     *               PRIMARY KEY (AUTHORIZATION_NAME)
+     *       )
+     *  </pre>
+     *
+     *  <b>Description</b><p>
+     *
+     *  <ol>
+     *  <li> The values of AUTHORIZATION_TYPE have the following meanings:<p>
+     *
+     *  <table border cellpadding="3">
+     *       <tr>
+     *           <td nowrap>USER</td>
+     *           <td nowrap>The value of AUTHORIZATION_NAME is a known
+     *                      &lt;user identifier&gt;.</td>
+     *       <tr>
+     *       <tr>
+     *           <td nowrap>NO</td>
+     *           <td nowrap>The value of AUTHORIZATION_NAME is a &lt;role
+     *                      name&gt; defined by a &lt;role definition&gt;.</td>
+     *       <tr>
+     *  </table> <p>
+     *  </ol>
+     *
+     * @return Table
+     */
+    Table AUTHORIZATIONS(Session session) {
+
+        Table t = sysTables[AUTHORIZATIONS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[AUTHORIZATIONS]);
+
+            addColumn(t, "AUTHORIZATION_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "AUTHORIZATION_TYPE", SQL_IDENTIFIER);    // not null
+
+            // true PK
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[AUTHORIZATIONS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        Iterator grantees;
+        Grantee  grantee;
+        Object[] row;
+
+        // initialization
+        grantees = session.getGrantee().visibleGrantees().iterator();
+
+        // Do it.
+        while (grantees.hasNext()) {
+            grantee = (Grantee) grantees.next();
+            row     = t.getEmptyRowData();
+            row[0]  = grantee.getNameString();
+            row[1]  = grantee.isRole() ? "ROLE"
+                                       : "USER";
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    Table CHARACTER_SETS(Session session) {
+
+        Table t = sysTables[CHARACTER_SETS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[CHARACTER_SETS]);
+
+            addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_REPERTOIRE", SQL_IDENTIFIER);
+            addColumn(t, "FORM_OF_USE", SQL_IDENTIFIER);
+            addColumn(t, "DEFAULT_COLLATE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "DEFAULT_COLLATE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "DEFAULT_COLLATE_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[CHARACTER_SETS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        final int character_set_catalog   = 0;
+        final int character_set_schema    = 1;
+        final int character_set_name      = 2;
+        final int character_repertoire    = 3;
+        final int form_of_use             = 4;
+        final int default_collate_catalog = 5;
+        final int default_collate_schema  = 6;
+        final int default_collate_name    = 7;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.CHARSET);
+
+        while (it.hasNext()) {
+            Charset charset = (Charset) it.next();
+
+            if (!session.getGrantee().isAccessible(charset)) {
+                continue;
+            }
+
+            Object[] data = t.getEmptyRowData();
+
+            data[character_set_catalog]   = database.getCatalogName().name;
+            data[character_set_schema]    = charset.getSchemaName().name;
+            data[character_set_name]      = charset.getName().name;
+            data[character_repertoire]    = "UCS";
+            data[form_of_use]             = "UTF16";
+            data[default_collate_catalog] = data[character_set_catalog];
+
+            if (charset.base == null) {
+                data[default_collate_schema] = data[character_set_schema];
+                data[default_collate_name]   = data[character_set_name];
+            } else {
+                data[default_collate_schema] = charset.base.schema.name;
+                data[default_collate_name]   = charset.base.name;
+            }
+
+            t.insertSys(store, data);
+        }
+
+        return t;
+    }
+
+    /**
+     * The CHECK_CONSTRAINT_ROUTINE_USAGE view has one row for each
+     * SQL-invoked routine identified as the subject routine of either a
+     * &lt;routine invocation&gt;, a &lt;method reference&gt;, a
+     * &lt;method invocation&gt;, or a &lt;static method invocation&gt;
+     * contained in an &lt;assertion definition&gt;, a &lt;domain
+     * constraint&gt;, or a &lt;table constraint definition&gt;. <p>
+     *
+     * <b>Definition:</b> <p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE SYSTEM_CHECK_ROUTINE_USAGE (
+     *      CONSTRAINT_CATALOG      VARCHAR NULL,
+     *      CONSTRAINT_SCHEMA       VARCHAR NULL,
+     *      CONSTRAINT_NAME         VARCHAR NOT NULL,
+     *      SPECIFIC_CATALOG        VARCHAR NULL,
+     *      SPECIFIC_SCHEMA         VARCHAR NULL,
+     *      SPECIFIC_NAME           VARCHAR NOT NULL,
+     *      UNIQUE( CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME,
+     *              SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME )
+     * )
+     * </pre>
+     *
+     * <b>Description:</b> <p>
+     *
+     * <ol>
+     * <li> The CHECK_ROUTINE_USAGE table has one row for each
+     *      SQL-invoked routine R identified as the subject routine of either a
+     *      &lt;routine invocation&gt;, a &lt;method reference&gt;, a &lt;method
+     *      invocation&gt;, or a &lt;static method invocation&gt; contained in
+     *      an &lt;assertion definition&gt; or in the &lt;check constraint
+     *      definition&gt; contained in either a &lt;domain constraint&gt; or a
+     *      &lt;table constraint definition&gt;. <p>
+     *
+     * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, and
+     *      CONSTRAINT_NAME are the catalog name, unqualified schema name, and
+     *      qualified identifier, respectively, of the assertion or check
+     *     constraint being described. <p>
+     *
+     * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA, and SPECIFIC_NAME
+     *      are the catalog name, unqualified schema name, and qualified
+     *      identifier, respectively, of the specific name of R. <p>
+     *
+     * </ol>
+     *
+     * @return Table
+     */
+    Table CHECK_CONSTRAINT_ROUTINE_USAGE(Session session) {
+
+        Table t = sysTables[CHECK_CONSTRAINT_ROUTINE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(
+                sysTableHsqlNames[CHECK_CONSTRAINT_ROUTINE_USAGE]);
+
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);      // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[CHECK_CONSTRAINT_ROUTINE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int constraint_catalog = 0;
+        final int constraint_schema  = 1;
+        final int constraint_name    = 2;
+        final int specific_catalog   = 3;
+        final int specific_schema    = 4;
+        final int specific_name      = 5;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        Iterator       constraints;
+        Constraint     constraint;
+        OrderedHashSet references;
+        RoutineSchema  routine;
+        Object[]       row;
+
+        constraints = database.schemaManager.databaseObjectIterator(
+            SchemaObject.CONSTRAINT);
+
+        while (constraints.hasNext()) {
+            HsqlName constraintName = (HsqlName) constraints.next();
+
+            if (constraintName.parent == null) {
+                continue;
+            }
+
+            if (!session.getGrantee().isFullyAccessibleByRole(
+                    constraintName.parent)) {
+                continue;
+            }
+
+            switch (constraintName.parent.type) {
+
+                case SchemaObject.TABLE : {
+                    Table table;
+
+                    try {
+                        table = (Table) database.schemaManager.getSchemaObject(
+                            constraintName.parent.name,
+                            constraintName.parent.schema.name,
+                            SchemaObject.TABLE);
+                    } catch (Exception e) {
+                        continue;
+                    }
+
+                    constraint = table.getConstraint(constraintName.name);
+
+                    if (constraint.getConstraintType()
+                            != SchemaObject.ConstraintTypes.CHECK) {
+                        continue;
+                    }
+
+                    break;
+                }
+                case SchemaObject.DOMAIN : {
+                    Type domain;
+
+                    try {
+                        domain = (Type) database.schemaManager.getSchemaObject(
+                            constraintName.parent.name,
+                            constraintName.parent.schema.name,
+                            SchemaObject.DOMAIN);
+                    } catch (Exception e) {
+                        continue;
+                    }
+
+                    constraint = domain.userTypeModifier.getConstraint(
+                        constraintName.name);
+                }
+                default :
+                    continue;
+            }
+
+            references = constraint.getReferences();
+
+            for (int i = 0; i < references.size(); i++) {
+                HsqlName name = (HsqlName) references.get(i);
+
+                if (name.type != SchemaObject.SPECIFIC_ROUTINE) {
+                    continue;
+                }
+
+                row                     = t.getEmptyRowData();
+                row[constraint_catalog] = database.getCatalogName();
+                row[constraint_schema]  = constraint.getSchemaName().name;
+                row[constraint_name]    = constraint.getName().name;
+                row[specific_catalog]   = database.getCatalogName();
+                row[specific_schema]    = name.schema.name;
+                row[specific_name]      = name.name;
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The CHECK_CONSTRAINTS view has one row for each domain
+     * constraint, table check constraint, and assertion. <p>
+     *
+     * <b>Definition:</b><p>
+     *
+     * <pre class="SqlCodeExample">
+     *      CONSTRAINT_CATALOG  VARCHAR NULL,
+     *      CONSTRAINT_SCHEMA   VARCHAR NULL,
+     *      CONSTRAINT_NAME     VARCHAR NOT NULL,
+     *      CHECK_CLAUSE        VARCHAR NOT NULL,
+     * </pre>
+     *
+     * <b>Description:</b><p>
+     *
+     * <ol>
+     * <li> A constraint is shown in this view if the authorization for the
+     *      schema that contains the constraint is the current user or is a role
+     *      assigned to the current user. <p>
+     *
+     * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA and
+     *      CONSTRAINT_NAME are the catalog name, unqualified schema name,
+     *      and qualified identifier, respectively, of the constraint being
+     *      described. <p>
+     *
+     * <li> Case: <p>
+     *
+     *      <table>
+     *          <tr>
+     *               <td valign="top" halign="left">a)</td>
+     *               <td> If the character representation of the
+     *                    &lt;search condition&gt; contained in the
+     *                    &lt;check constraint definition&gt;,
+     *                    &lt;domain constraint definition&gt;, or
+     *                    &lt;assertion definition&gt; that defined
+     *                    the check constraint being described can be
+     *                    represented without truncation, then the
+     *                    value of CHECK_CLAUSE is that character
+     *                    representation. </td>
+     *          </tr>
+     *          <tr>
+     *              <td align="top" halign="left">b)</td>
+     *              <td>Otherwise, the value of CHECK_CLAUSE is the
+     *                  null value.</td>
+     *          </tr>
+     *      </table>
+     * </ol>
+     *
+     * @return Table
+     */
+    Table CHECK_CONSTRAINTS(Session session) {
+
+        Table t = sysTables[CHECK_CONSTRAINTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[CHECK_CONSTRAINTS]);
+
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "CHECK_CLAUSE", CHARACTER_DATA);       // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[CHECK_CONSTRAINTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                2, 1, 0
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int constraint_catalog = 0;
+        final int constraint_schema  = 1;
+        final int constraint_name    = 2;
+        final int check_clause       = 3;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        // Intermediate holders
+        Iterator     tables;
+        Table        table;
+        Constraint[] tableConstraints;
+        int          constraintCount;
+        Constraint   constraint;
+        Object[]     row;
+
+        //
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView()
+                    || !session.getGrantee().isFullyAccessibleByRole(
+                        table.getName())) {
+                continue;
+            }
+
+            tableConstraints = table.getConstraints();
+            constraintCount  = tableConstraints.length;
+
+            for (int i = 0; i < constraintCount; i++) {
+                constraint = tableConstraints[i];
+
+                if (constraint.getConstraintType()
+                        != SchemaObject.ConstraintTypes.CHECK) {
+                    continue;
+                }
+
+                row                     = t.getEmptyRowData();
+                row[constraint_catalog] = database.getCatalogName().name;
+                row[constraint_schema]  = table.getSchemaName().name;
+                row[constraint_name]    = constraint.getName().name;
+
+                try {
+                    row[check_clause] = constraint.getCheckSQL();
+                } catch (Exception e) {}
+
+                t.insertSys(store, row);
+            }
+        }
+
+        Iterator it =
+            database.schemaManager.databaseObjectIterator(SchemaObject.DOMAIN);
+
+        while (it.hasNext()) {
+            Type domain = (Type) it.next();
+
+            if (!domain.isDomainType()) {
+                continue;
+            }
+
+            if (!session.getGrantee().isFullyAccessibleByRole(
+                    domain.getName())) {
+                continue;
+            }
+
+            tableConstraints = domain.userTypeModifier.getConstraints();
+            constraintCount  = tableConstraints.length;
+
+            for (int i = 0; i < constraintCount; i++) {
+                constraint              = tableConstraints[i];
+                row                     = t.getEmptyRowData();
+                row[constraint_catalog] = database.getCatalogName().name;
+                row[constraint_schema]  = domain.getSchemaName().name;
+                row[constraint_name]    = constraint.getName().name;
+
+                try {
+                    row[check_clause] = constraint.getCheckSQL();
+                } catch (Exception e) {}
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * COLLATIONS<p>
+     *
+     * <b>Function<b><p>
+     *
+     * The COLLATIONS view has one row for each character collation
+     * descriptor. <p>
+     *
+     * <b>Definition</b>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE COLLATIONS (
+     *      COLLATION_CATALOG INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *      COLLATION_SCHEMA INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *      COLLATION_NAME INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *      PAD_ATTRIBUTE INFORMATION_SCHEMA.CHARACTER_DATA
+     *          CONSTRAINT COLLATIONS_PAD_ATTRIBUTE_CHECK
+     *              CHECK ( PAD_ATTRIBUTE IN
+     *                  ( 'NO PAD', 'PAD SPACE' ) )
+     * )
+     * </pre>
+     *
+     * <b>Description</b><p>
+     *
+     * <ol>
+     *      <li>The values of COLLATION_CATALOG, COLLATION_SCHEMA, and
+     *          COLLATION_NAME are the catalog name, unqualified schema name,
+     *          and qualified identifier, respectively, of the collation being
+     *          described.<p>
+     *
+     *      <li>The values of PAD_ATTRIBUTE have the following meanings:<p>
+     *
+     *      <table border cellpadding="3">
+     *          <tr>
+     *              <td nowrap>NO PAD</td>
+     *              <td nowrap>The collation being described has the NO PAD
+     *                  characteristic.</td>
+     *          <tr>
+     *          <tr>
+     *              <td nowrap>PAD</td>
+     *              <td nowrap>The collation being described has the PAD SPACE
+     *                         characteristic.</td>
+     *          <tr>
+     *      </table> <p>
+     * </ol>
+     *
+     * @return Table
+     */
+    Table COLLATIONS(Session session) {
+
+        Table t = sysTables[COLLATIONS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[COLLATIONS]);
+
+            addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);    // not null
+            addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);      // not null
+            addColumn(t, "PAD_ATTRIBUTE", CHARACTER_DATA);
+
+            // false PK, as rows may have NULL COLLATION_CATALOG
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[COLLATIONS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        // Column number mappings
+        final int collation_catalog = 0;
+        final int collation_schema  = 1;
+        final int collation_name    = 2;
+        final int pad_attribute     = 3;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        Iterator collations;
+        String   collation;
+        String   collationSchema = SqlInvariants.PUBLIC_SCHEMA;
+        String   padAttribute    = "NO PAD";
+        Object[] row;
+
+        // Initialization
+        collations = Collation.nameToJavaName.keySet().iterator();
+
+        // Do it.
+        while (collations.hasNext()) {
+            row                    = t.getEmptyRowData();
+            collation              = (String) collations.next();
+            row[collation_catalog] = database.getCatalogName().name;
+            row[collation_schema]  = collationSchema;
+            row[collation_name]    = collation;
+            row[pad_attribute]     = padAttribute;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * For generated columns
+     * <p>
+     *
+     * @return Table
+     */
+    Table COLUMN_COLUMN_USAGE(Session session) {
+
+        Table t = sysTables[COLUMN_COLUMN_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[COLUMN_COLUMN_USAGE]);
+
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "DEPENDENT_COLUMN", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[COLUMN_COLUMN_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4
+            }, false);
+
+            return t;
+        }
+
+        final int table_catalog    = 0;
+        final int table_schema     = 1;
+        final int table_name       = 2;
+        final int column_name      = 3;
+        final int dependent_column = 4;
+
+        return t;
+    }
+
+    /**
+     * Domains are shown if the authorization is the user or a role given to the
+     * user.
+     *
+     * <p>
+     *
+     * @return Table
+     */
+    Table COLUMN_DOMAIN_USAGE(Session session) {
+
+        Table t = sysTables[COLUMN_DOMAIN_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[COLUMN_DOMAIN_USAGE]);
+
+            addColumn(t, "DOMAIN_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);     // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);    // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[COLUMN_DOMAIN_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        Result rs = sys.executeDirectStatement(
+            "SELECT DOMAIN_CATALOG, DOMAIN_SCHEMA, DOMAIN_NAME, TABLE_CATALOG, "
+            + "TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS "
+            + "WHERE DOMAIN_NAME IS NOT NULL;", ResultProperties.defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        return t;
+    }
+
+    /**
+     * UDT's are shown if the authorization is the user or a role given to the
+     * user.
+     *
+     * <p>
+     *
+     * @return Table
+     */
+    Table COLUMN_UDT_USAGE(Session session) {
+
+        Table t = sysTables[COLUMN_UDT_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[COLUMN_UDT_USAGE]);
+
+            addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);     // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);    // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[COLUMN_UDT_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        Result rs = sys.executeDirectStatement(
+            "SELECT UDT_CATALOG, UDT_SCHEMA, UDT_NAME, TABLE_CATALOG, "
+            + "TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS "
+            + "WHERE UDT_NAME IS NOT NULL;", ResultProperties.defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        return t;
+    }
+
+    Table COLUMNS(Session session) {
+
+        Table t = sysTables[COLUMNS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[COLUMNS]);
+
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);           //0
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ORDINAL_POSITION", CARDINAL_NUMBER);
+            addColumn(t, "COLUMN_DEFAULT", CHARACTER_DATA);
+            addColumn(t, "IS_NULLABLE", YES_OR_NO);
+            addColumn(t, "DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);      //10
+            addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
+            addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_SET_CATALOG", CHARACTER_DATA);
+            addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);        //20
+            addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);              //30
+            addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);    // (only for array tyes)
+            addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
+            addColumn(t, "IS_SELF_REFERENCING", YES_OR_NO);
+            addColumn(t, "IS_IDENTITY", YES_OR_NO);
+            addColumn(t, "IDENTITY_GENERATION", CHARACTER_DATA);     // ALWAYS / BY DEFAULT
+            addColumn(t, "IDENTITY_START", CHARACTER_DATA);
+            addColumn(t, "IDENTITY_INCREMENT", CHARACTER_DATA);
+            addColumn(t, "IDENTITY_MAXIMUM", CHARACTER_DATA);
+            addColumn(t, "IDENTITY_MINIMUM", CHARACTER_DATA);
+            addColumn(t, "IDENTITY_CYCLE", YES_OR_NO);               //40
+            addColumn(t, "IS_GENERATED", CHARACTER_DATA);            // ALWAYS / NEVER
+            addColumn(t, "GENERATION_EXPRESSION", CHARACTER_DATA);
+            addColumn(t, "IS_UPDATABLE", YES_OR_NO);
+            addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
+
+            // order: TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION
+            // added for unique: TABLE_CAT
+            // false PK, as TABLE_SCHEM and/or TABLE_CAT may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[COLUMNS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                3, 2, 1, 4
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int table_cat                  = 0;
+        final int table_schem                = 1;
+        final int table_name                 = 2;
+        final int column_name                = 3;
+        final int ordinal_position           = 4;
+        final int column_default             = 5;
+        final int is_nullable                = 6;
+        final int data_type                  = 7;
+        final int character_maximum_length   = 8;
+        final int character_octet_length     = 9;
+        final int numeric_precision          = 10;
+        final int numeric_precision_radix    = 11;
+        final int numeric_scale              = 12;
+        final int datetime_precision         = 13;
+        final int interval_type              = 14;
+        final int interval_precision         = 15;
+        final int character_set_catalog      = 16;
+        final int character_set_schema       = 17;
+        final int character_set_name         = 18;
+        final int collation_catalog          = 19;
+        final int collation_schema           = 20;
+        final int collation_name             = 21;
+        final int domain_catalog             = 22;
+        final int domain_schema              = 23;
+        final int domain_name                = 24;
+        final int udt_catalog                = 25;
+        final int udt_schema                 = 26;
+        final int udt_name                   = 27;
+        final int scope_catalog              = 28;
+        final int scope_schema               = 29;
+        final int scope_name                 = 30;
+        final int maximum_cardinality        = 31;
+        final int dtd_identifier             = 32;
+        final int is_self_referencing        = 33;
+        final int is_identity                = 34;
+        final int identity_generation        = 35;
+        final int identity_start             = 36;
+        final int identity_increment         = 37;
+        final int identity_maximum           = 38;
+        final int identity_minimum           = 39;
+        final int identity_cycle             = 40;
+        final int is_generated               = 41;
+        final int generation_expression      = 42;
+        final int is_updatable               = 43;
+        final int declared_data_type         = 44;
+        final int declared_numeric_precision = 45;
+        final int declared_numeric_scale     = 46;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // intermediate holders
+        int            columnCount;
+        Iterator       tables;
+        Table          table;
+        Object[]       row;
+        OrderedHashSet columnList;
+        Type           type;
+
+        // Initialization
+        tables = allTables();
+
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+            columnList =
+                session.getGrantee().getColumnsForAllPrivileges(table);
+
+            if (columnList.isEmpty()) {
+                continue;
+            }
+
+            columnCount = table.getColumnCount();
+
+            for (int i = 0; i < columnCount; i++) {
+                ColumnSchema column = table.getColumn(i);
+
+                type = column.getDataType();
+
+                if (!columnList.contains(column.getName())) {
+                    continue;
+                }
+
+                row                   = t.getEmptyRowData();
+                row[table_cat]        = database.getCatalogName().name;
+                row[table_schem]      = table.getSchemaName().name;
+                row[table_name]       = table.getName().name;
+                row[column_name]      = column.getName().name;
+                row[ordinal_position] = ValuePool.getLong(i + 1);
+                row[column_default]   = column.getDefaultSQL();
+                row[is_nullable]      = column.isNullable() ? "YES"
+                                                            : "NO";
+                row[data_type]        = type.getFullNameString();
+
+                // common type block
+                if (type.isCharacterType()) {
+                    row[character_maximum_length] =
+                        ValuePool.getLong(type.precision);
+                    row[character_octet_length] =
+                        ValuePool.getLong(type.precision * 2);
+                    row[character_set_catalog] =
+                        database.getCatalogName().name;
+                    row[character_set_schema] =
+                        ((CharacterType) type).getCharacterSet()
+                            .getSchemaName().name;
+                    row[character_set_name] =
+                        ((CharacterType) type).getCharacterSet().getName()
+                            .name;
+                    row[collation_catalog] = database.getCatalogName().name;
+                    row[collation_schema] =
+                        ((CharacterType) type).getCollation().getSchemaName()
+                            .name;
+                    row[collation_name] =
+                        ((CharacterType) type).getCollation().getName().name;
+                } else if (type.isNumberType()) {
+                    row[numeric_precision] = ValuePool.getLong(
+                        ((NumberType) type).getNumericPrecisionInRadix());
+                    row[declared_numeric_precision] = ValuePool.getLong(
+                        ((NumberType) type).getNumericPrecisionInRadix());
+
+                    if (type.isExactNumberType()) {
+                        row[numeric_scale] = row[declared_numeric_scale] =
+                            ValuePool.getLong(type.scale);
+                    }
+
+                    row[numeric_precision_radix] =
+                        ValuePool.getLong(type.getPrecisionRadix());
+                } else if (type.isBooleanType()) {
+
+                    //
+                } else if (type.isDateTimeType()) {
+                    row[datetime_precision] = ValuePool.getLong(type.scale);
+                } else if (type.isIntervalType()) {
+                    row[data_type] = "INTERVAL";
+                    row[interval_type] =
+                        ((IntervalType) type).getQualifier(type.typeCode);
+                    row[interval_precision] =
+                        ValuePool.getLong(type.precision);
+                    row[datetime_precision] = ValuePool.getLong(type.scale);
+                } else if (type.isBinaryType()) {
+                    row[character_maximum_length] =
+                        ValuePool.getLong(type.precision);
+                    row[character_octet_length] =
+                        ValuePool.getLong(type.precision);
+                } else if (type.isBitType()) {
+                    row[character_maximum_length] =
+                        ValuePool.getLong(type.precision);
+                    row[character_octet_length] =
+                        ValuePool.getLong(type.precision);
+                } else if (type.isArrayType()) {
+                    row[maximum_cardinality] =
+                        ValuePool.getLong(type.arrayLimitCardinality());
+                }
+
+                if (type.isDomainType()) {
+                    row[domain_catalog] = database.getCatalogName().name;
+                    row[domain_schema]  = type.getSchemaName().name;
+                    row[domain_name]    = type.getName().name;
+                }
+
+                if (type.isDistinctType()) {
+                    row[udt_catalog] = database.getCatalogName().name;
+                    row[udt_schema]  = type.getSchemaName().name;
+                    row[udt_name]    = type.getName().name;
+                }
+
+                row[scope_catalog]       = null;
+                row[scope_schema]        = null;
+                row[scope_name]          = null;
+                row[dtd_identifier]      = null;
+                row[is_self_referencing] = null;
+                row[is_identity]         = column.isIdentity() ? "YES"
+                                                               : "NO";
+
+                if (column.isIdentity()) {
+                    NumberSequence sequence = column.getIdentitySequence();
+
+                    row[identity_generation] = sequence.isAlways() ? "ALWAYS"
+                                                                   : "BY DEFAULT";
+                    row[identity_start] =
+                        Long.toString(sequence.getStartValue());
+                    row[identity_increment] =
+                        Long.toString(sequence.getIncrement());
+                    row[identity_maximum] =
+                        Long.toString(sequence.getMaxValue());
+                    row[identity_minimum] =
+                        Long.toString(sequence.getMinValue());
+                    row[identity_cycle] = sequence.isCycle() ? "YES"
+                                                             : "NO";
+                }
+
+                row[is_generated] = "NEVER";
+
+                if (column.isGenerated()) {
+                    row[is_generated] = "ALWAYS";
+                    row[generation_expression] =
+                        column.getGeneratingExpression().getSQL();
+                }
+
+                row[is_updatable]       = table.isWritable() ? "YES"
+                                                             : "NO";
+                row[declared_data_type] = row[data_type];
+
+                if (type.isNumberType()) {
+                    row[declared_numeric_precision] = row[numeric_precision];
+                    row[declared_numeric_scale]     = row[numeric_scale];
+                }
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The CONSTRAINT_COLUMN_USAGE view has one row for each column identified by
+     * a table constraint or assertion.<p>
+     *
+     * <b>Definition:</b><p>
+     *
+     *      TABLE_CATALOG       VARCHAR
+     *      TABLE_SCHEMA        VARCHAR
+     *      TABLE_NAME          VARCHAR
+     *      COLUMN_NAME         VARCHAR
+     *      CONSTRAINT_CATALOG  VARCHAR
+     *      CONSTRAINT_SCHEMA   VARCHAR
+     *      CONSTRAINT_NAME     VARCHAR
+     *
+     * </pre>
+     *
+     * <b>Description:</b> <p>
+     *
+     * <ol>
+     * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
+     *      COLUMN_NAME are the catalog name, unqualified schema name,
+     *      qualified identifier, and column name, respectively, of a column
+     *      identified by a &lt;column reference&gt; explicitly or implicitly
+     *      contained in the &lt;search condition&gt; of the constraint
+     *      being described.
+     *
+     * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, and
+     *      CONSTRAINT_NAME are the catalog name, unqualified schema name,
+     *      and qualified identifier, respectively, of the constraint being
+     *      described. <p>
+     *
+     * </ol>
+     *
+     * @return Table
+     */
+    Table CONSTRAINT_COLUMN_USAGE(Session session) {
+
+        Table t = sysTables[CONSTRAINT_COLUMN_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[CONSTRAINT_COLUMN_USAGE]);
+
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);         // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);        // not null
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[CONSTRAINT_COLUMN_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int table_catalog      = 0;
+        final int table_schems       = 1;
+        final int table_name         = 2;
+        final int column_name        = 3;
+        final int constraint_catalog = 4;
+        final int constraint_schema  = 5;
+        final int constraint_name    = 6;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        String constraintCatalog;
+        String constraintSchema;
+        String constraintName;
+
+        // Intermediate holders
+        Iterator     tables;
+        Table        table;
+        Constraint[] constraints;
+        int          constraintCount;
+        Constraint   constraint;
+        Iterator     iterator;
+        Object[]     row;
+
+        // Initialization
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView()
+                    || !session.getGrantee().isFullyAccessibleByRole(
+                        table.getName())) {
+                continue;
+            }
+
+            constraints       = table.getConstraints();
+            constraintCount   = constraints.length;
+            constraintCatalog = database.getCatalogName().name;
+            constraintSchema  = table.getSchemaName().name;
+
+            // process constraints
+            for (int i = 0; i < constraintCount; i++) {
+                constraint     = constraints[i];
+                constraintName = constraint.getName().name;
+
+                switch (constraint.getConstraintType()) {
+
+                    case SchemaObject.ConstraintTypes.CHECK : {
+                        OrderedHashSet expressions =
+                            constraint.getCheckColumnExpressions();
+
+                        if (expressions == null) {
+                            break;
+                        }
+
+                        iterator = expressions.iterator();
+
+                        // calculate distinct column references
+                        while (iterator.hasNext()) {
+                            ExpressionColumn expr =
+                                (ExpressionColumn) iterator.next();
+                            HsqlName name = expr.getBaseColumnHsqlName();
+
+                            if (name.type != SchemaObject.COLUMN) {
+                                continue;
+                            }
+
+                            row = t.getEmptyRowData();
+                            row[table_catalog] =
+                                database.getCatalogName().name;
+                            row[table_schems]       = name.schema.name;
+                            row[table_name]         = name.parent.name;
+                            row[column_name]        = name.name;
+                            row[constraint_catalog] = constraintCatalog;
+                            row[constraint_schema]  = constraintSchema;
+                            row[constraint_name]    = constraintName;
+
+                            try {
+                                t.insertSys(store, row);
+                            } catch (HsqlException e) {}
+                        }
+
+                        break;
+                    }
+                    case SchemaObject.ConstraintTypes.UNIQUE :
+                    case SchemaObject.ConstraintTypes.PRIMARY_KEY :
+                    case SchemaObject.ConstraintTypes.FOREIGN_KEY : {
+                        Table target = table;
+                        int[] cols   = constraint.getMainColumns();
+
+                        if (constraint.getConstraintType()
+                                == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+                            target = constraint.getMain();
+                        }
+
+/*
+                       checkme - it seems foreign key columns are not included
+                       but columns of the referenced unique constraint are included
+
+                        if (constraint.getType() == Constraint.FOREIGN_KEY) {
+                            for (int j = 0; j < cols.length; j++) {
+                                row = t.getEmptyRowData();
+
+                                Table mainTable = constraint.getMain();
+
+                                row[table_catalog] = database.getCatalog();
+                                row[table_schems] =
+                                    mainTable.getSchemaName().name;
+                                row[table_name] = mainTable.getName().name;
+                                row[column_name] = mainTable.getColumn(
+                                    cols[j]).columnName.name;
+                                row[constraint_catalog] = constraintCatalog;
+                                row[constraint_schema]  = constraintSchema;
+                                row[constraint_name]    = constraintName;
+
+                                try {
+                                    t.insertSys(row);
+                                } catch (HsqlException e) {}
+                            }
+
+                            cols = constraint.getRefColumns();
+                        }
+*/
+                        for (int j = 0; j < cols.length; j++) {
+                            row = t.getEmptyRowData();
+                            row[table_catalog] =
+                                database.getCatalogName().name;
+                            row[table_schems] = constraintSchema;
+                            row[table_name]   = target.getName().name;
+                            row[column_name] =
+                                target.getColumn(cols[j]).getName().name;
+                            row[constraint_catalog] = constraintCatalog;
+                            row[constraint_schema]  = constraintSchema;
+                            row[constraint_name]    = constraintName;
+
+                            try {
+                                t.insertSys(store, row);
+                            } catch (HsqlException e) {}
+                        }
+
+                        //
+                    }
+                }
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The CONSTRAINT_TABLE_USAGE view has one row for each table identified by a
+     * &lt;table name&gt; simply contained in a &lt;table reference&gt;
+     * contained in the &lt;search condition&gt; of a check constraint,
+     * domain constraint, or assertion. It has one row for each table
+     * containing / referenced by each PRIMARY KEY, UNIQUE and FOREIGN KEY
+     * constraint<p>
+     *
+     * <b>Definition:</b> <p>
+     *
+     * <pre class="SqlCodeExample">
+     *      CONSTRAINT_CATALOG      VARCHAR
+     *      CONSTRAINT_SCHEMA       VARCHAR
+     *      CONSTRAINT_NAME         VARCHAR
+     *      TABLE_CATALOG           VARCHAR
+     *      TABLE_SCHEMA            VARCHAR
+     *      TABLE_NAME              VARCHAR
+     * </pre>
+     *
+     * <b>Description:</b> <p>
+     *
+     * <ol>
+     * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, and
+     *      CONSTRAINT_NAME are the catalog name, unqualified schema name,
+     *       and qualified identifier, respectively, of the constraint being
+     *      described. <p>
+     *
+     * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, and TABLE_NAME are the
+     *      catalog name, unqualified schema name, and qualified identifier,
+     *      respectively, of a table identified by a &lt;table name&gt;
+     *      simply contained in a &lt;table reference&gt; contained in the
+     *      *lt;search condition&gt; of the constraint being described, or
+     *      its columns.
+     * </ol>
+     *
+     * @return Table
+     */
+    Table CONSTRAINT_TABLE_USAGE(Session session) {
+
+        Table t = sysTables[CONSTRAINT_TABLE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[CONSTRAINT_TABLE_USAGE]);
+
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);         // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[CONSTRAINT_TABLE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        //
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        Result rs = sys.executeDirectStatement(
+            "select DISTINCT CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, "
+            + "CONSTRAINT_NAME, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME "
+            + "from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE", ResultProperties
+                .defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        return t;
+    }
+
+    Table DATA_TYPE_PRIVILEGES(Session session) {
+
+        Table t = sysTables[DATA_TYPE_PRIVILEGES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[DATA_TYPE_PRIVILEGES]);
+
+            addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "OBJECT_TYPE", SQL_IDENTIFIER);
+            addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[DATA_TYPE_PRIVILEGES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        //
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        String sql = (String) statementMap.get("/*data_type_privileges*/");
+        Result rs =
+            sys.executeDirectStatement(sql,
+                                       ResultProperties.defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        return t;
+    }
+
+    /**
+     * a DEFINITION_SCHEMA table. Not in the INFORMATION_SCHEMA list
+     */
+/*
+    Table DATA_TYPE_DESCRIPTOR() {
+
+        Table t = sysTables[DATA_TYPE_DESCRIPTOR];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[DATA_TYPE_DESCRIPTOR]);
+
+            addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_TYPE", CHARACTER_DATA);
+            addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
+            addColumn(t, "DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
+            addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_NUMERIC_SCLAE", CARDINAL_NUMBER);
+            addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
+            addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "USER_DEFINED_TYPE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "USER_DEFINED_TYPE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "USER_DEFINED_TYPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);
+            t.createPrimaryKeyConstraint(null, new int[] {
+                0, 1, 2, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store =  session.sessionData.getRowStore(t);
+        final int       object_catalog             = 0;
+        final int       object_schema              = 1;
+        final int       object_name                = 2;
+        final int       object_type                = 3;
+        final int       dtd_identifier             = 4;
+        final int       data_type                  = 5;
+        final int       character_set_catalog      = 6;
+        final int       character_set_schema       = 7;
+        final int       character_set_name         = 8;
+        final int       character_maximum_length   = 9;
+        final int       character_octet_length     = 10;
+        final int       collation_catalog          = 11;
+        final int       collation_schema           = 12;
+        final int       collation_name             = 13;
+        final int       numeric_precision          = 14;
+        final int       numeric_precision_radix    = 15;
+        final int       numeric_scale              = 16;
+        final int       declared_data_type         = 17;
+        final int       declared_numeric_precision = 18;
+        final int       declared_numeric_scale     = 19;
+        final int       datetime_precision         = 20;
+        final int       interval_type              = 21;
+        final int       interval_precision         = 22;
+        final int       user_defined_type_catalog  = 23;
+        final int       user_defined_type_schema   = 24;
+        final int       user_defined_type_name     = 25;
+        final int       scope_catalog              = 26;
+        final int       scope_schema               = 27;
+        final int       scope_name                 = 28;
+        final int       maximum_cardinality        = 29;
+        return t;
+    }
+*/
+
+    /**
+     *
+     * @return Table
+     */
+    Table DOMAIN_CONSTRAINTS(Session session) {
+
+        Table t = sysTables[DOMAIN_CONSTRAINTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[DOMAIN_CONSTRAINTS]);
+
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "DOMAIN_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "IS_DEFERRABLE", YES_OR_NO);
+            addColumn(t, "INITIALLY_DEFERRED", YES_OR_NO);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[DOMAIN_CONSTRAINTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        final int constraint_catalog = 0;
+        final int constraint_schema  = 1;
+        final int constraint_name    = 2;
+        final int domain_catalog     = 3;
+        final int domain_schema      = 4;
+        final int domain_name        = 5;
+        final int is_deferrable      = 6;
+        final int initially_deferred = 7;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        //
+        Iterator it =
+            database.schemaManager.databaseObjectIterator(SchemaObject.DOMAIN);
+
+        while (it.hasNext()) {
+            Type domain = (Type) it.next();
+
+            if (!domain.isDomainType()) {
+                continue;
+            }
+
+            if (!session.getGrantee().isFullyAccessibleByRole(
+                    domain.getName())) {
+                continue;
+            }
+
+            Constraint[] constraints =
+                domain.userTypeModifier.getConstraints();
+
+            for (int i = 0; i < constraints.length; i++) {
+                Object[] data = t.getEmptyRowData();
+
+                data[constraint_catalog] = data[domain_catalog] =
+                    database.getCatalogName().name;
+                data[constraint_schema] = data[domain_schema] =
+                    domain.getSchemaName().name;
+                data[constraint_name]    = constraints[i].getName().name;
+                data[domain_name]        = domain.getName().name;
+                data[is_deferrable]      = Tokens.T_NO;
+                data[initially_deferred] = Tokens.T_NO;
+
+                t.insertSys(store, data);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The DOMAINS view has one row for each domain. <p>
+     *
+     *
+     * <pre class="SqlCodeExample">
+     *
+     * </pre>
+     *
+     * @return Table
+     */
+    Table DOMAINS(Session session) {
+
+        Table t = sysTables[DOMAINS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[DOMAINS]);
+
+            addColumn(t, "DOMAIN_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "DOMAIN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "DATA_TYPE", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
+            addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
+            addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DOMAIN_DEFAULT", CHARACTER_DATA);
+            addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);
+            addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
+            addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_NUMERIC_SCLAE", CARDINAL_NUMBER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[DOMAINS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        final int domain_catalog             = 0;
+        final int domain_schema              = 1;
+        final int domain_name                = 2;
+        final int data_type                  = 3;
+        final int character_maximum_length   = 4;
+        final int character_octet_length     = 5;
+        final int character_set_catalog      = 6;
+        final int character_set_schema       = 7;
+        final int character_set_name         = 8;
+        final int collation_catalog          = 9;
+        final int collation_schema           = 10;
+        final int collation_name             = 11;
+        final int numeric_precision          = 12;
+        final int numeric_precision_radix    = 13;
+        final int numeric_scale              = 14;
+        final int datetime_precision         = 15;
+        final int interval_type              = 16;
+        final int interval_precision         = 17;
+        final int domain_default             = 18;
+        final int maximum_cardinality        = 19;
+        final int dtd_identifier             = 20;
+        final int declared_data_type         = 21;
+        final int declared_numeric_precision = 22;
+        final int declared_numeric_scale     = 23;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        //
+        Iterator it =
+            database.schemaManager.databaseObjectIterator(SchemaObject.DOMAIN);
+
+        while (it.hasNext()) {
+            Type type = (Type) it.next();
+
+            if (!type.isDomainType()) {
+                continue;
+            }
+
+            if (!session.getGrantee().isAccessible(type)) {
+                continue;
+            }
+
+            Object[] row = t.getEmptyRowData();
+
+            row[domain_catalog] = database.getCatalogName().name;
+            row[domain_schema]  = type.getSchemaName().name;
+            row[domain_name]    = type.getName().name;
+            row[data_type]      = type.getFullNameString();
+
+            // common type block
+            if (type.isCharacterType()) {
+                row[character_maximum_length] =
+                    ValuePool.getLong(type.precision);
+                row[character_octet_length] = ValuePool.getLong(type.precision
+                        * 2);
+                row[character_set_catalog] = database.getCatalogName().name;
+                row[character_set_schema] =
+                    ((CharacterType) type).getCharacterSet().getSchemaName()
+                        .name;
+                row[character_set_name] =
+                    ((CharacterType) type).getCharacterSet().getName().name;
+                row[collation_catalog] = database.getCatalogName().name;
+                row[collation_schema] =
+                    ((CharacterType) type).getCollation().getSchemaName().name;
+                row[collation_name] =
+                    ((CharacterType) type).getCollation().getName().name;
+            } else if (type.isNumberType()) {
+                row[numeric_precision] = ValuePool.getLong(
+                    ((NumberType) type).getNumericPrecisionInRadix());
+                row[declared_numeric_precision] = ValuePool.getLong(
+                    ((NumberType) type).getNumericPrecisionInRadix());
+
+                if (type.isExactNumberType()) {
+                    row[numeric_scale] = row[declared_numeric_scale] =
+                        ValuePool.getLong(type.scale);
+                }
+
+                row[numeric_precision_radix] =
+                    ValuePool.getLong(type.getPrecisionRadix());
+            } else if (type.isBooleanType()) {
+
+                //
+            } else if (type.isDateTimeType()) {
+                row[datetime_precision] = ValuePool.getLong(type.scale);
+            } else if (type.isIntervalType()) {
+                row[data_type] = "INTERVAL";
+                row[interval_type] =
+                    ((IntervalType) type).getQualifier(type.typeCode);
+                row[interval_precision] = ValuePool.getLong(type.precision);
+                row[datetime_precision] = ValuePool.getLong(type.scale);
+            } else if (type.isBinaryType()) {
+                row[character_maximum_length] =
+                    ValuePool.getLong(type.precision);
+                row[character_octet_length] =
+                    ValuePool.getLong(type.precision);
+            } else if (type.isBitType()) {
+                row[character_maximum_length] =
+                    ValuePool.getLong(type.precision);
+                row[character_octet_length] =
+                    ValuePool.getLong(type.precision);
+            } else if (type.isArrayType()) {
+                row[maximum_cardinality] =
+                    ValuePool.getLong(type.arrayLimitCardinality());
+            }
+
+            // end common block
+            Expression defaultExpression =
+                type.userTypeModifier.getDefaultClause();
+
+            if (defaultExpression != null) {
+                row[domain_default] = defaultExpression.getSQL();
+            }
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * ENABLED_ROLES<p>
+     *
+     * <b>Function</b><p>
+     *
+     * Identify the enabled roles for the current SQL-session.<p>
+     *
+     * Definition<p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE RECURSIVE VIEW ENABLED_ROLES ( ROLE_NAME ) AS
+     *      VALUES ( CURRENT_ROLE )
+     *      UNION
+     *      SELECT RAD.ROLE_NAME
+     *        FROM DEFINITION_SCHEMA.ROLE_AUTHORIZATION_DESCRIPTORS RAD
+     *        JOIN ENABLED_ROLES R
+     *          ON RAD.GRANTEE = R.ROLE_NAME;
+     *
+     * GRANT SELECT ON TABLE ENABLED_ROLES
+     *    TO PUBLIC WITH GRANT OPTION;
+     * </pre>
+     */
+    Table ENABLED_ROLES(Session session) {
+
+        Table t = sysTables[ENABLED_ROLES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ENABLED_ROLES]);
+
+            addColumn(t, "ROLE_NAME", SQL_IDENTIFIER);
+
+            // true PK
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ENABLED_ROLES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        Iterator grantees;
+        Grantee  grantee;
+        Object[] row;
+
+        // initialization
+        grantees = session.getGrantee().getAllRoles().iterator();
+
+        while (grantees.hasNext()) {
+            grantee = (Grantee) grantees.next();
+            row     = t.getEmptyRowData();
+            row[0]  = grantee.getNameString();
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    Table JAR_JAR_USAGE(Session session) {
+
+        Table t = sysTables[JAR_JAR_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[JAR_JAR_USAGE]);
+
+            addColumn(t, "PATH_JAR_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "PATH_JAR_SCHAMA", SQL_IDENTIFIER);
+            addColumn(t, "PATH_JAR_NAME", SQL_IDENTIFIER);
+            addColumn(t, "JAR_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "JAR_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "JAR_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[JAR_JAR_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int path_jar_catalog = 0;
+        final int path_jar_schema  = 1;
+        final int path_jar_name    = 2;
+        final int jar_catalog      = 3;
+        final int jar_schema       = 4;
+        final int jar_name         = 5;
+
+        //
+        Iterator it;
+        Object[] row;
+
+        return t;
+    }
+
+    Table JARS(Session session) {
+
+        Table t = sysTables[JARS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[JARS]);
+
+            addColumn(t, "JAR_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "JAR_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "JAR_NAME", SQL_IDENTIFIER);
+            addColumn(t, "JAR_PATH", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[JARS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int jar_catalog = 0;
+        final int jar_schema  = 1;
+        final int jar_name    = 2;
+        final int jar_path    = 3;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        it;
+        Object[]        row;
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the
+     * primary key and unique constraint columns of each accessible table
+     * defined within this database. <p>
+     *
+     * Each row is a PRIMARY KEY or UNIQUE column description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * CONSTRAINT_CATALOG              VARCHAR NULL,
+     * CONSTRAINT_SCHEMA               VARCHAR NULL,
+     * CONSTRAINT_NAME                 VARCHAR NOT NULL,
+     * TABLE_CATALOG                   VARCHAR   table catalog
+     * TABLE_SCHEMA                    VARCHAR   table schema
+     * TABLE_NAME                      VARCHAR   table name
+     * COLUMN_NAME                     VARCHAR   column name
+     * ORDINAL_POSITION                INT
+     * POSITION_IN_UNIQUE_CONSTRAINT   INT
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the visible
+     *        primary key and unique columns of each accessible table
+     *        defined within this database.
+     */
+    Table KEY_COLUMN_USAGE(Session session) {
+
+        Table t = sysTables[KEY_COLUMN_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[KEY_COLUMN_USAGE]);
+
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);                   // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);                        // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);                       // not null
+            addColumn(t, "ORDINAL_POSITION", CARDINAL_NUMBER);                 // not null
+            addColumn(t, "POSITION_IN_UNIQUE_CONSTRAINT", CARDINAL_NUMBER);    // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[KEY_COLUMN_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                2, 1, 0, 6, 7
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        Iterator tables;
+        Object[] row;
+
+        // column number mappings
+        final int constraint_catalog            = 0;
+        final int constraint_schema             = 1;
+        final int constraint_name               = 2;
+        final int table_catalog                 = 3;
+        final int table_schema                  = 4;
+        final int table_name                    = 5;
+        final int column_name                   = 6;
+        final int ordinal_position              = 7;
+        final int position_in_unique_constraint = 8;
+
+        // Initialization
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        while (tables.hasNext()) {
+            Table  table        = (Table) tables.next();
+            String tableCatalog = database.getCatalogName().name;
+            String tableSchema  = table.getSchemaName().name;
+            String tableName    = table.getName().name;
+
+            /** @todo - requires access to the actual columns */
+            if (table.isView() || !isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            Constraint[] constraints = table.getConstraints();
+
+            for (int i = 0; i < constraints.length; i++) {
+                Constraint constraint = constraints[i];
+
+                if (constraint.getConstraintType() == SchemaObject
+                        .ConstraintTypes.PRIMARY_KEY || constraint
+                        .getConstraintType() == SchemaObject.ConstraintTypes
+                        .UNIQUE || constraint
+                        .getConstraintType() == SchemaObject.ConstraintTypes
+                        .FOREIGN_KEY) {
+                    String constraintName = constraint.getName().name;
+                    int[]  cols           = constraint.getMainColumns();
+                    int[]  uniqueColMap   = null;
+
+                    if (constraint.getConstraintType()
+                            == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+                        Table uniqueConstTable = constraint.getMain();
+                        Constraint uniqueConstraint =
+                            uniqueConstTable.getConstraint(
+                                constraint.getUniqueName().name);
+                        int[] uniqueConstIndexes =
+                            uniqueConstraint.getMainColumns();
+
+                        uniqueColMap = new int[cols.length];
+
+                        for (int j = 0; j < cols.length; j++) {
+                            uniqueColMap[j] =
+                                ArrayUtil.find(uniqueConstIndexes, cols[j]);
+                        }
+
+                        cols = constraint.getRefColumns();
+                    }
+
+                    for (int j = 0; j < cols.length; j++) {
+                        row                     = t.getEmptyRowData();
+                        row[constraint_catalog] = tableCatalog;
+                        row[constraint_schema]  = tableSchema;
+                        row[constraint_name]    = constraintName;
+                        row[table_catalog]      = tableCatalog;
+                        row[table_schema]       = tableSchema;
+                        row[table_name]         = tableName;
+                        row[column_name] =
+                            table.getColumn(cols[j]).getName().name;
+                        row[ordinal_position] = ValuePool.getLong(j + 1);
+
+                        if (constraint.getConstraintType()
+                                == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+                            row[position_in_unique_constraint] =
+                                ValuePool.getInt(uniqueColMap[j] + 1);
+                        }
+
+                        t.insertSys(store, row);
+                    }
+                }
+            }
+        }
+
+        return t;
+    }
+
+    Table METHOD_SPECIFICATION_PARAMETERS(Session session) {
+        return null;
+    }
+
+    Table METHOD_SPECIFICATIONS(Session session) {
+        return null;
+    }
+
+    Table MODULE_COLUMN_USAGE(Session session) {
+        return null;
+    }
+
+    Table MODULE_PRIVILEGES(Session session) {
+        return null;
+    }
+
+    Table MODULE_TABLE_USAGE(Session session) {
+        return null;
+    }
+
+    Table MODULES(Session session) {
+        return null;
+    }
+
+    Table PARAMETERS(Session session) {
+
+        Table t = sysTables[PARAMETERS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[PARAMETERS]);
+
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ORDINAL_POSITION", CARDINAL_NUMBER);
+            addColumn(t, "PARAMETER_MODE", CHARACTER_DATA);
+            addColumn(t, "IS_RESULT", YES_OR_NO);
+            addColumn(t, "AS_LOCATOR", YES_OR_NO);
+            addColumn(t, "PARAMETER_NAME", SQL_IDENTIFIER);
+
+            //
+            addColumn(t, "FROM_SQL_SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "FROM_SQL_SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "FROM_SQL_SPECIFIC_NAME", SQL_IDENTIFIER);
+
+            //
+            addColumn(t, "TO_SQL_SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TO_SQL_SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TO_SQL_SPECIFIC_NAME", SQL_IDENTIFIER);
+
+            //
+            addColumn(t, "DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_SET_CATALOG", CHARACTER_DATA);
+            addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
+            addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
+            addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);
+            addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
+            addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[PARAMETERS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int specific_cat             = 0;
+        final int specific_schem           = 1;
+        final int specific_name            = 2;
+        final int ordinal_position         = 3;
+        final int parameter_mode           = 4;
+        final int is_result                = 5;
+        final int as_locator               = 6;
+        final int parameter_name           = 7;
+        final int from_specific_catalog    = 8;
+        final int from_specific_schema     = 9;
+        final int from_specific_name       = 10;
+        final int to_specific_catalog      = 11;
+        final int to_specific_schema       = 12;
+        final int to_specific_name         = 13;
+        final int data_type                = 14;
+        final int character_maximum_length = 15;
+        final int character_octet_length   = 16;
+        final int character_set_catalog    = 17;
+        final int character_set_schema     = 18;
+        final int character_set_name       = 19;
+        final int collation_catalog        = 20;
+        final int collation_schema         = 21;
+        final int collation_name           = 22;
+        final int numeric_precision        = 23;
+        final int numeric_precision_radix  = 24;
+        final int numeric_scale            = 25;
+        final int datetime_precision       = 26;
+        final int interval_type            = 27;
+        final int interval_precision       = 28;
+        final int udt_catalog              = 29;
+        final int udt_schema               = 30;
+        final int udt_name                 = 31;
+        final int scope_catalog            = 32;
+        final int scope_schema             = 33;
+        final int scope_name               = 34;
+        final int maximum_cardinality      = 35;
+        final int dtd_identifier           = 36;
+
+        // intermediate holders
+        int           columnCount;
+        Iterator      routines;
+        RoutineSchema routineSchema;
+        Routine       routine;
+        Object[]      row;
+        Type          type;
+
+        // Initialization
+        routines = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (routines.hasNext()) {
+            routineSchema = (RoutineSchema) routines.next();
+
+            if (!session.getGrantee().isAccessible(routineSchema)) {
+                continue;
+            }
+
+            Routine[] specifics = routineSchema.getSpecificRoutines();
+
+            for (int i = 0; i < specifics.length; i++) {
+                routine     = specifics[i];
+                columnCount = routine.getParameterCount();
+
+                for (int j = 0; j < columnCount; j++) {
+                    ColumnSchema column = routine.getParameter(j);
+
+                    type                  = column.getDataType();
+                    row                   = t.getEmptyRowData();
+                    row[specific_cat]     = database.getCatalogName().name;
+                    row[specific_schem]   = routine.getSchemaName().name;
+                    row[specific_name]    = routine.getSpecificName().name;
+                    row[parameter_name]   = column.getName().name;
+                    row[ordinal_position] = ValuePool.getLong(j + 1);
+
+                    switch (column.getParameterMode()) {
+
+                        case SchemaObject.ParameterModes.PARAM_IN :
+                            row[parameter_mode] = "IN";
+                            break;
+
+                        case SchemaObject.ParameterModes.PARAM_OUT :
+                            row[parameter_mode] = "OUT";
+                            break;
+
+                        case SchemaObject.ParameterModes.PARAM_INOUT :
+                            row[parameter_mode] = "INOUT";
+                            break;
+                    }
+
+                    row[is_result]  = "NO";
+                    row[as_locator] = "NO";
+                    row[data_type]  = type.getFullNameString();
+
+                    // common type block
+                    if (type.isCharacterType()) {
+                        row[character_maximum_length] =
+                            ValuePool.getLong(type.precision);
+                        row[character_octet_length] =
+                            ValuePool.getLong(type.precision * 2);
+                        row[character_set_catalog] =
+                            database.getCatalogName().name;
+                        row[character_set_schema] =
+                            ((CharacterType) type).getCharacterSet()
+                                .getSchemaName().name;
+                        row[character_set_name] =
+                            ((CharacterType) type).getCharacterSet().getName()
+                                .name;
+                        row[collation_catalog] =
+                            database.getCatalogName().name;
+                        row[collation_schema] =
+                            ((CharacterType) type).getCollation()
+                                .getSchemaName().name;
+                        row[collation_name] =
+                            ((CharacterType) type).getCollation().getName()
+                                .name;
+                    } else if (type.isNumberType()) {
+                        row[numeric_precision] = ValuePool.getLong(
+                            ((NumberType) type).getNumericPrecisionInRadix());
+                        row[numeric_precision_radix] =
+                            ValuePool.getLong(type.getPrecisionRadix());
+                    } else if (type.isBooleanType()) {
+
+                        //
+                    } else if (type.isDateTimeType()) {
+                        row[datetime_precision] =
+                            ValuePool.getLong(type.scale);
+                    } else if (type.isIntervalType()) {
+                        row[data_type] = "INTERVAL";
+                        row[interval_type] =
+                            ((IntervalType) type).getQualifier(type.typeCode);
+                        row[interval_precision] =
+                            ValuePool.getLong(type.precision);
+                        row[datetime_precision] =
+                            ValuePool.getLong(type.scale);
+                    } else if (type.isBinaryType()) {
+                        row[character_maximum_length] =
+                            ValuePool.getLong(type.precision);
+                        row[character_octet_length] =
+                            ValuePool.getLong(type.precision);
+                    } else if (type.isBitType()) {
+                        row[character_maximum_length] =
+                            ValuePool.getLong(type.precision);
+                        row[character_octet_length] =
+                            ValuePool.getLong(type.precision);
+                    } else if (type.isArrayType()) {
+                        row[maximum_cardinality] =
+                            ValuePool.getLong(type.arrayLimitCardinality());
+                    }
+
+                    if (type.isDistinctType()) {
+                        row[udt_catalog] = database.getCatalogName().name;
+                        row[udt_schema]  = type.getSchemaName().name;
+                        row[udt_name]    = type.getName().name;
+                    }
+
+                    // end common block
+                    t.insertSys(store, row);
+                }
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * <ol>
+     * <li> A constraint is shown in this view if the user has table level
+     * privilege of at lease one of the types, INSERT, UPDATE, DELETE,
+     * REFERENCES or TRIGGER.
+     * </ol>
+     *
+     * @return Table
+     */
+    Table REFERENTIAL_CONSTRAINTS(Session session) {
+
+        Table t = sysTables[REFERENTIAL_CONSTRAINTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[REFERENTIAL_CONSTRAINTS]);
+
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);              // not null
+            addColumn(t, "UNIQUE_CONSTRAINT_CATALOG", SQL_IDENTIFIER);    // not null
+            addColumn(t, "UNIQUE_CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "UNIQUE_CONSTRAINT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "MATCH_OPTION", CHARACTER_DATA);                 // not null
+            addColumn(t, "UPDATE_RULE", CHARACTER_DATA);                  // not null
+            addColumn(t, "DELETE_RULE", CHARACTER_DATA);                  // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[REFERENTIAL_CONSTRAINTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2,
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int constraint_catalog        = 0;
+        final int constraint_schema         = 1;
+        final int constraint_name           = 2;
+        final int unique_constraint_catalog = 3;
+        final int unique_constraint_schema  = 4;
+        final int unique_constraint_name    = 5;
+        final int match_option              = 6;
+        final int update_rule               = 7;
+        final int delete_rule               = 8;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        tables;
+        Table           table;
+        Constraint[]    constraints;
+        Constraint      constraint;
+        Object[]        row;
+
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView()
+                    || !session.getGrantee().hasNonSelectTableRight(table)) {
+                continue;
+            }
+
+            constraints = table.getConstraints();
+
+            for (int i = 0; i < constraints.length; i++) {
+                constraint = constraints[i];
+
+                if (constraint.getConstraintType()
+                        != SchemaObject.ConstraintTypes.FOREIGN_KEY) {
+                    continue;
+                }
+
+                HsqlName uniqueName = constraint.getUniqueName();
+
+                row                     = t.getEmptyRowData();
+                row[constraint_catalog] = database.getCatalogName().name;
+                row[constraint_schema]  = constraint.getSchemaName().name;
+                row[constraint_name]    = constraint.getName().name;
+
+                if (isAccessibleTable(session, constraint.getMain())) {
+                    row[unique_constraint_catalog] =
+                        database.getCatalogName().name;
+                    row[unique_constraint_schema] = uniqueName.schema.name;
+                    row[unique_constraint_name]   = uniqueName.name;
+                }
+
+                row[match_option] = Tokens.T_NONE;
+                row[update_rule]  = constraint.getUpdateActionString();
+                row[delete_rule]  = constraint.getDeleteActionString();
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    Table ROLE_COLUMN_GRANTS(Session session) {
+
+        Table t = sysTables[ROLE_COLUMN_GRANTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROLE_COLUMN_GRANTS]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);           // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);           // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);        // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);       // not null
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);    // not null
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);           // not null
+
+            // order: COLUMN_NAME, PRIVILEGE
+            // for unique: GRANTEE, GRANTOR, TABLE_NAME, TABLE_SCHEMA, TABLE_CAT
+            // false PK, as TABLE_SCHEMA and/or TABLE_CAT may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROLE_COLUMN_GRANTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                5, 6, 1, 0, 4, 3, 2
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        Result rs = sys.executeDirectStatement(
+            "SELECT GRANTOR, GRANTEE, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, PRIVILEGE_TYPE, IS_GRANTABLE "
+            + "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES "
+            + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON GRANTEE = ROLE_NAME;", ResultProperties.defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        return t;
+    }
+
+    Table ROLE_ROUTINE_GRANTS(Session session) {
+
+        Table t = sysTables[ROLE_ROUTINE_GRANTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROLE_ROUTINE_GRANTS]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);          // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);          // not null
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROLE_ROUTINE_GRANTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        Result rs = sys.executeDirectStatement(
+            "SELECT GRANTOR, GRANTEE, SPECIFIC_CATALOG, SPECIFIC_SCHEMA, "
+            + "SPECIFIC_NAME, ROUTINE_CATALOG, ROUTINE_SCHEMA, ROUTINE_NAME, "
+            + "PRIVILEGE_TYPE, IS_GRANTABLE "
+            + "FROM INFORMATION_SCHEMA.ROUTINE_PRIVILEGES "
+            + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON GRANTEE = ROLE_NAME;", ResultProperties
+                .defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        // Column number mappings
+        final int grantor          = 0;
+        final int grantee          = 1;
+        final int table_name       = 2;
+        final int specific_catalog = 3;
+        final int specific_schema  = 4;
+        final int specific_name    = 5;
+        final int routine_catalog  = 6;
+        final int routine_schema   = 7;
+        final int routine_name     = 8;
+        final int privilege_type   = 9;
+        final int is_grantable     = 10;
+
+        //
+        return t;
+    }
+
+    Table ROLE_TABLE_GRANTS(Session session) {
+
+        Table t = sysTables[ROLE_TABLE_GRANTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROLE_TABLE_GRANTS]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);           // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);           // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);        // not null
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);    // not null
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);           // not null
+            addColumn(t, "WITH_HIERARCHY", YES_OR_NO);
+
+            // order:  TABLE_SCHEM, TABLE_NAME, and PRIVILEGE,
+            // added for unique:  GRANTEE, GRANTOR,
+            // false PK, as TABLE_SCHEM and/or TABLE_CAT may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROLE_TABLE_GRANTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                3, 4, 5, 0, 1
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        Result rs = sys.executeDirectStatement(
+            "SELECT GRANTOR, GRANTEE, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, "
+            + "PRIVILEGE_TYPE, IS_GRANTABLE, 'NO' "
+            + "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES "
+            + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON GRANTEE = ROLE_NAME;", ResultProperties
+                .defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        return t;
+    }
+
+    Table ROLE_UDT_GRANTS(Session session) {
+
+        Table t = sysTables[ROLE_UDT_GRANTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROLE_UDT_GRANTS]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);     // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);     // not null
+            addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "UDT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);     // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROLE_TABLE_GRANTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, null, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        Result rs = sys.executeDirectStatement(
+            "SELECT GRANTOR, GRANTEE, UDT_CATALOG, UDT_SCHEMA, UDT_NAME, "
+            + "PRIVILEGE_TYPE, IS_GRANTABLE "
+            + "FROM INFORMATION_SCHEMA.UDT_PRIVILEGES "
+            + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON GRANTEE = ROLE_NAME;", ResultProperties
+                .defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        return t;
+    }
+
+    Table ROLE_USAGE_GRANTS(Session session) {
+
+        Table t = sysTables[ROLE_USAGE_GRANTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROLE_USAGE_GRANTS]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);        // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);        // not null
+            addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "OBJECT_TYPE", CHARACTER_DATA);    // not null
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);        // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROLE_USAGE_GRANTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6, 7
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        Result rs = sys.executeDirectStatement(
+            "SELECT GRANTOR, GRANTEE, OBJECT_CATALOG, OBJECT_SCHEMA, OBJECT_NAME, "
+            + "OBJECT_TYPE, PRIVILEGE_TYPE, IS_GRANTABLE "
+            + "FROM INFORMATION_SCHEMA.USAGE_PRIVILEGES "
+            + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON GRANTEE = ROLE_NAME;", ResultProperties
+                .defaultPropsValue);
+
+        t.insertSys(store, rs);
+        sys.close();
+
+        return t;
+    }
+
+    Table ROUTINE_COLUMN_USAGE(Session session) {
+
+        Table t = sysTables[ROUTINE_COLUMN_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROUTINE_COLUMN_USAGE]);
+
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROUTINE_COLUMN_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                3, 4, 5, 0, 1, 2, 6, 7, 8, 9
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int specific_catalog = 0;
+        final int specific_schema  = 1;
+        final int specific_name    = 2;
+        final int routine_catalog  = 3;
+        final int routine_schema   = 4;
+        final int routine_name     = 5;
+        final int table_catalog    = 6;
+        final int table_schema     = 7;
+        final int table_name       = 8;
+        final int column_name      = 9;
+
+        //
+        Iterator it;
+        Object[] row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (it.hasNext()) {
+            RoutineSchema routine = (RoutineSchema) it.next();
+
+            if (!session.getGrantee().isAccessible(routine)) {
+                continue;
+            }
+
+            Routine[] specifics = routine.getSpecificRoutines();
+
+            for (int m = 0; m < specifics.length; m++) {
+                OrderedHashSet set = specifics[m].getReferences();
+
+                for (int i = 0; i < set.size(); i++) {
+                    HsqlName refName = (HsqlName) set.get(i);
+
+                    if (refName.type != SchemaObject.COLUMN) {
+                        continue;
+                    }
+
+                    if (!session.getGrantee().isAccessible(refName)) {
+                        continue;
+                    }
+
+                    row = t.getEmptyRowData();
+
+                    //
+                    row[specific_catalog] = database.getCatalogName().name;
+                    row[specific_schema]  = specifics[m].getSchemaName().name;
+                    row[specific_name] = specifics[m].getSpecificName().name;
+                    row[routine_catalog]  = database.getCatalogName().name;
+                    row[routine_schema]   = routine.getSchemaName().name;
+                    row[routine_name]     = routine.getName().name;
+                    row[table_catalog]    = database.getCatalogName().name;
+                    row[table_schema]     = refName.parent.schema.name;
+                    row[table_name]       = refName.parent.name;
+                    row[column_name]      = refName.name;
+
+                    try {
+                        t.insertSys(store, row);
+                    } catch (HsqlException e) {}
+                }
+            }
+        }
+
+        return t;
+    }
+
+    Table ROUTINE_PRIVILEGES(Session session) {
+
+        Table t = sysTables[ROUTINE_PRIVILEGES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROUTINE_PRIVILEGES]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);           // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);           // not null
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);     // not null
+            addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);      // not null
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);    // not null
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);           // not null
+
+            //
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROUTINE_PRIVILEGES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int grantor          = 0;
+        final int grantee          = 1;
+        final int specific_catalog = 2;
+        final int specific_schema  = 3;
+        final int specific_name    = 4;
+        final int routine_catalog  = 5;
+        final int routine_schema   = 6;
+        final int routine_name     = 7;
+        final int privilege_type   = 8;
+        final int is_grantable     = 9;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        Grantee granteeObject;
+        String  privilege;
+
+        // intermediate holders
+        Iterator      routines;
+        RoutineSchema routine;
+        Object[]      row;
+        OrderedHashSet grantees =
+            session.getGrantee().getGranteeAndAllRolesWithPublic();
+
+        routines = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (routines.hasNext()) {
+            routine = (RoutineSchema) routines.next();
+
+            for (int i = 0; i < grantees.size(); i++) {
+                granteeObject = (Grantee) grantees.get(i);
+
+                OrderedHashSet rights =
+                    granteeObject.getAllDirectPrivileges(routine);
+                OrderedHashSet grants =
+                    granteeObject.getAllGrantedPrivileges(routine);
+
+                if (!grants.isEmpty()) {
+                    grants.addAll(rights);
+
+                    rights = grants;
+                }
+
+                for (int j = 0; j < rights.size(); j++) {
+                    Right right          = (Right) rights.get(j);
+                    Right grantableRight = right.getGrantableRights();
+
+                    for (int k = 0; k < Right.privilegeTypes.length; k++) {
+                        if (!right.canAccessFully(Right.privilegeTypes[k])) {
+                            continue;
+                        }
+
+                        Routine[] specifics = routine.getSpecificRoutines();
+
+                        for (int m = 0; m < specifics.length; m++) {
+                            privilege = Right.privilegeNames[k];
+                            row       = t.getEmptyRowData();
+
+                            //
+                            row[grantor] = right.getGrantor().getName().name;
+                            row[grantee] = right.getGrantee().getName().name;
+                            row[specific_catalog] =
+                                database.getCatalogName().name;
+                            row[specific_schema] =
+                                specifics[m].getSchemaName().name;
+                            row[specific_name] =
+                                specifics[m].getSpecificName().name;
+                            row[routine_catalog] =
+                                database.getCatalogName().name;
+                            row[routine_schema] = routine.getSchemaName().name;
+                            row[routine_name]   = routine.getName().name;
+                            row[privilege_type] = privilege;
+                            row[is_grantable] =
+                                right.getGrantee() == routine.getOwner()
+                                || grantableRight.canAccessFully(
+                                    Right.privilegeTypes[k]) ? "YES"
+                                                             : "NO";
+
+                            try {
+                                t.insertSys(store, row);
+                            } catch (HsqlException e) {}
+                        }
+                    }
+                }
+            }
+        }
+
+        return t;
+    }
+
+    Table ROUTINE_JAR_USAGE(Session session) {
+
+        Table t = sysTables[ROUTINE_JAR_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROUTINE_JAR_USAGE]);
+
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
+            addColumn(t, "JAR_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "JAR_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "JAR_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROUTINE_JAR_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int specific_catalog = 0;
+        final int specific_schema  = 1;
+        final int specific_name    = 2;
+        final int jar_catalog      = 3;
+        final int jar_schema       = 4;
+        final int jar_name         = 5;
+
+        //
+        Iterator        it;
+        Object[]        row;
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (it.hasNext()) {
+            RoutineSchema routine = (RoutineSchema) it.next();
+
+            if (!session.getGrantee().isAccessible(routine)) {
+                continue;
+            }
+
+            Routine[] specifics = routine.getSpecificRoutines();
+
+            for (int m = 0; m < specifics.length; m++) {
+                if (specifics[m].getLanguage() != Routine.LANGUAGE_JAVA) {
+                    continue;
+                }
+
+                row                   = t.getEmptyRowData();
+                row[specific_catalog] = database.getCatalogName().name;
+                row[specific_schema]  = routine.getSchemaName().name;
+                row[specific_name]    = routine.getName().name;
+                row[jar_catalog]      = database.getCatalogName().name;
+                row[jar_schema] =
+                    database.schemaManager.getSQLJSchemaHsqlName();
+                row[jar_name] = "CLASSPATH";
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * needs to provide list of specific referenced routines
+     */
+    Table ROUTINE_ROUTINE_USAGE(Session session) {
+
+        Table t = sysTables[ROUTINE_ROUTINE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROUTINE_ROUTINE_USAGE]);
+
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROUTINE_ROUTINE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int specific_catalog = 0;
+        final int specific_schema  = 1;
+        final int specific_name    = 2;
+        final int routine_catalog  = 3;
+        final int routine_schema   = 4;
+        final int routine_name     = 5;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        it;
+        Object[]        row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (it.hasNext()) {
+            RoutineSchema routine = (RoutineSchema) it.next();
+
+            if (!session.getGrantee().isAccessible(routine)) {
+                continue;
+            }
+
+            Routine[] specifics = routine.getSpecificRoutines();
+
+            for (int m = 0; m < specifics.length; m++) {
+                OrderedHashSet set = specifics[m].getReferences();
+
+                for (int i = 0; i < set.size(); i++) {
+                    HsqlName refName = (HsqlName) set.get(i);
+
+                    if (refName.type != SchemaObject.SPECIFIC_ROUTINE) {
+                        continue;
+                    }
+
+                    if (!session.getGrantee().isAccessible(refName)) {
+                        continue;
+                    }
+
+                    row                   = t.getEmptyRowData();
+                    row[specific_catalog] = database.getCatalogName().name;
+                    row[specific_schema]  = specifics[m].getSchemaName().name;
+                    row[specific_name] = specifics[m].getSpecificName().name;
+                    row[routine_catalog]  = database.getCatalogName().name;
+                    row[routine_schema]   = refName.schema.name;
+                    row[routine_name]     = refName.name;
+
+                    try {
+                        t.insertSys(store, row);
+                    } catch (HsqlException e) {}
+                }
+            }
+        }
+
+        return t;
+    }
+
+    Table ROUTINE_SEQUENCE_USAGE(Session session) {
+
+        Table t = sysTables[ROUTINE_SEQUENCE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROUTINE_SEQUENCE_USAGE]);
+
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROUTINE_SEQUENCE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int specific_catalog = 0;
+        final int specific_schema  = 1;
+        final int specific_name    = 2;
+        final int sequence_catalog = 3;
+        final int sequence_schema  = 4;
+        final int sequence_name    = 5;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        it;
+        Object[]        row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (it.hasNext()) {
+            RoutineSchema routine = (RoutineSchema) it.next();
+
+            if (!session.getGrantee().isAccessible(routine)) {
+                continue;
+            }
+
+            Routine[] specifics = routine.getSpecificRoutines();
+
+            for (int m = 0; m < specifics.length; m++) {
+                OrderedHashSet set = specifics[m].getReferences();
+
+                for (int i = 0; i < set.size(); i++) {
+                    HsqlName refName = (HsqlName) set.get(i);
+
+                    if (refName.type != SchemaObject.SEQUENCE) {
+                        continue;
+                    }
+
+                    if (!session.getGrantee().isAccessible(refName)) {
+                        continue;
+                    }
+
+                    row                   = t.getEmptyRowData();
+                    row[specific_catalog] = database.getCatalogName().name;
+                    row[specific_schema]  = specifics[m].getSchemaName().name;
+                    row[specific_name] = specifics[m].getSpecificName().name;
+                    row[sequence_catalog] = database.getCatalogName().name;
+                    row[sequence_schema]  = refName.schema.name;
+                    row[sequence_name]    = refName.name;
+
+                    try {
+                        t.insertSys(store, row);
+                    } catch (HsqlException e) {}
+                }
+            }
+        }
+
+        return t;
+    }
+
+    Table ROUTINE_TABLE_USAGE(Session session) {
+
+        Table t = sysTables[ROUTINE_TABLE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROUTINE_TABLE_USAGE]);
+
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROUTINE_TABLE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                3, 4, 5, 0, 1, 2, 6, 7, 8
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int specific_catalog = 0;
+        final int specific_schema  = 1;
+        final int specific_name    = 2;
+        final int routine_catalog  = 3;
+        final int routine_schema   = 4;
+        final int routine_name     = 5;
+        final int table_catalog    = 6;
+        final int table_schema     = 7;
+        final int table_name       = 8;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        it;
+        Object[]        row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (it.hasNext()) {
+            RoutineSchema routine = (RoutineSchema) it.next();
+
+            if (!session.getGrantee().isAccessible(routine)) {
+                continue;
+            }
+
+            Routine[] specifics = routine.getSpecificRoutines();
+
+            for (int m = 0; m < specifics.length; m++) {
+                OrderedHashSet set = specifics[m].getReferences();
+
+                for (int i = 0; i < set.size(); i++) {
+                    HsqlName refName = (HsqlName) set.get(i);
+
+                    if (refName.type != SchemaObject.TABLE
+                            && refName.type != SchemaObject.VIEW) {
+                        continue;
+                    }
+
+                    if (!session.getGrantee().isAccessible(refName)) {
+                        continue;
+                    }
+
+                    row                   = t.getEmptyRowData();
+                    row[specific_catalog] = database.getCatalogName().name;
+                    row[specific_schema]  = specifics[m].getSchemaName().name;
+                    row[specific_name] = specifics[m].getSpecificName().name;
+                    row[routine_catalog]  = database.getCatalogName().name;
+                    row[routine_schema]   = routine.getSchemaName().name;
+                    row[routine_name]     = routine.getName().name;
+                    row[table_catalog]    = database.getCatalogName().name;
+                    row[table_schema]     = refName.schema.name;
+                    row[table_name]       = refName.name;
+
+                    try {
+                        t.insertSys(store, row);
+                    } catch (HsqlException e) {}
+                }
+            }
+        }
+
+        return t;
+    }
+
+    Table ROUTINES(Session session) {
+
+        Table t = sysTables[ROUTINES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[ROUTINES]);
+
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_TYPE", CHARACTER_DATA);
+            addColumn(t, "MODULE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "MODULE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "MODULE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);          //
+            addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
+            addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);        //
+            addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
+            addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "TYPE_UDT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TYPE_UDT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TYPE_UDT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);                //
+            addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);      // (only for array tyes)
+            addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
+            addColumn(t, "ROUTINE_BODY", CHARACTER_DATA);
+            addColumn(t, "ROUTINE_DEFINITION", CHARACTER_DATA);
+            addColumn(t, "EXTERNAL_NAME", CHARACTER_DATA);
+            addColumn(t, "EXTERNAL_LANGUAGE", CHARACTER_DATA);
+            addColumn(t, "PARAMETER_STYLE", CHARACTER_DATA);
+            addColumn(t, "IS_DETERMINISTIC", YES_OR_NO);
+            addColumn(t, "SQL_DATA_ACCESS", CHARACTER_DATA);
+            addColumn(t, "IS_NULL_CALL", YES_OR_NO);
+            addColumn(t, "SQL_PATH", CHARACTER_DATA);
+            addColumn(t, "SCHEMA_LEVEL_ROUTINE", YES_OR_NO);           //
+            addColumn(t, "MAX_DYNAMIC_RESULT_SETS", CARDINAL_NUMBER);
+            addColumn(t, "IS_USER_DEFINED_CAST", YES_OR_NO);
+            addColumn(t, "IS_IMPLICITLY_INVOCABLE", YES_OR_NO);
+            addColumn(t, "SECURITY_TYPE", CHARACTER_DATA);
+            addColumn(t, "TO_SQL_SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TO_SQL_SPECIFIC_SCHEMA", SQL_IDENTIFIER);    //
+            addColumn(t, "TO_SQL_SPECIFIC_NAME", SQL_IDENTIFIER);
+            addColumn(t, "AS_LOCATOR", YES_OR_NO);
+            addColumn(t, "CREATED", TIME_STAMP);
+            addColumn(t, "LAST_ALTERED", TIME_STAMP);
+            addColumn(t, "NEW_SAVEPOINT_LEVEL", YES_OR_NO);
+            addColumn(t, "IS_UDT_DEPENDENT", YES_OR_NO);
+            addColumn(t, "RESULT_CAST_FROM_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "RESULT_CAST_AS_LOCATOR", YES_OR_NO);
+            addColumn(t, "RESULT_CAST_CHAR_MAX_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_CHAR_OCTET_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_CHAR_SET_CATALOG", CHARACTER_DATA);
+            addColumn(t, "RESULT_CAST_CHAR_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_COLLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_COLLATION_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_COLLATION_NAME", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_NUMERIC_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_DATETIME_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_INTERVAL_TYPE", CHARACTER_DATA);
+            addColumn(t, "RESULT_CAST_INTERVAL_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_TYPE_UDT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_TYPE_UDT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_TYPE_UDT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_SCOPE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_SCOPE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_SCOPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "RESULT_CAST_MAX_CARDINALITY", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_DTD_IDENTIFIER", CHARACTER_DATA);
+            addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_FROM_DECLARED_DATA_TYPE",
+                      CHARACTER_DATA);
+            addColumn(t, "RESULT_CAST_DECLARED_NUMERIC_PRECISION",
+                      CARDINAL_NUMBER);
+            addColumn(t, "RESULT_CAST_DECLARED_NUMERIC_SCALE",
+                      CARDINAL_NUMBER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROUTINES].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                3, 4, 5, 0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        // column number mappings
+        final int specific_catalog                       = 0;
+        final int specific_schema                        = 1;
+        final int specific_name                          = 2;
+        final int routine_catalog                        = 3;
+        final int routine_schema                         = 4;
+        final int routine_name                           = 5;
+        final int routine_type                           = 6;
+        final int module_catalog                         = 7;
+        final int module_schema                          = 8;
+        final int module_name                            = 9;
+        final int udt_catalog                            = 10;
+        final int udt_schema                             = 11;
+        final int udt_name                               = 12;
+        final int data_type                              = 13;
+        final int character_maximum_length               = 14;
+        final int character_octet_length                 = 15;
+        final int character_set_catalog                  = 16;
+        final int character_set_schema                   = 17;
+        final int character_set_name                     = 18;
+        final int collation_catalog                      = 19;
+        final int collation_schema                       = 20;
+        final int collation_name                         = 21;
+        final int numeric_precision                      = 22;
+        final int numeric_precision_radix                = 23;
+        final int numeric_scale                          = 24;
+        final int datetime_precision                     = 25;
+        final int interval_type                          = 26;
+        final int interval_precision                     = 27;
+        final int type_udt_catalog                       = 28;
+        final int type_udt_schema                        = 29;
+        final int type_udt_name                          = 30;
+        final int scope_catalog                          = 31;
+        final int scope_schema                           = 32;
+        final int scope_name                             = 33;
+        final int maximum_cardinality                    = 34;
+        final int dtd_identifier                         = 35;
+        final int routine_body                           = 36;
+        final int routine_definition                     = 37;
+        final int external_name                          = 38;
+        final int external_language                      = 39;
+        final int parameter_style                        = 40;
+        final int is_deterministic                       = 41;
+        final int sql_data_access                        = 42;
+        final int is_null_call                           = 43;
+        final int sql_path                               = 44;
+        final int schema_level_routine                   = 45;
+        final int max_dynamic_result_sets                = 46;
+        final int is_user_defined_cast                   = 47;
+        final int is_implicitly_invocable                = 48;
+        final int security_type                          = 49;
+        final int to_sql_specific_catalog                = 50;
+        final int to_sql_specific_schema                 = 51;
+        final int to_sql_specific_name                   = 52;
+        final int as_locator                             = 53;
+        final int created                                = 54;
+        final int last_altered                           = 55;
+        final int new_savepoint_level                    = 56;
+        final int is_udt_dependent                       = 57;
+        final int result_cast_from_data_type             = 58;
+        final int result_cast_as_locator                 = 59;
+        final int result_cast_char_max_length            = 60;
+        final int result_cast_char_octet_length          = 61;
+        final int result_cast_char_set_catalog           = 62;
+        final int result_cast_char_set_schema            = 63;
+        final int result_cast_character_set_name         = 64;
+        final int result_cast_collation_catalog          = 65;
+        final int result_cast_collation_schema           = 66;
+        final int result_cast_collation_name             = 67;
+        final int result_cast_numeric_precision          = 68;
+        final int result_cast_numeric_radix              = 69;
+        final int result_cast_numeric_scale              = 70;
+        final int result_cast_datetime_precision         = 71;
+        final int result_cast_interval_type              = 72;
+        final int result_cast_interval_precision         = 73;
+        final int result_cast_type_udt_catalog           = 74;
+        final int result_cast_type_udt_schema            = 75;
+        final int result_cast_type_udt_name              = 76;
+        final int result_cast_scope_catalog              = 77;
+        final int result_cast_scope_schema               = 78;
+        final int result_cast_scope_name                 = 79;
+        final int result_cast_max_cardinality            = 80;
+        final int result_cast_dtd_identifier             = 81;
+        final int declared_data_type                     = 82;
+        final int declared_numeric_precision             = 83;
+        final int declared_numeric_scale                 = 84;
+        final int result_cast_from_declared_data_type    = 85;
+        final int result_cast_declared_numeric_precision = 86;
+        final int result_cast_declared_numeric_scale     = 87;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        it;
+        Object[]        row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (it.hasNext()) {
+            RoutineSchema routine = (RoutineSchema) it.next();
+
+            if (!session.getGrantee().isAccessible(routine)) {
+                continue;
+            }
+
+            Routine[] specifics = routine.getSpecificRoutines();
+
+            for (int m = 0; m < specifics.length; m++) {
+                row = t.getEmptyRowData();
+
+                Routine specific = specifics[m];
+                Type    type     = specific.isProcedure() ? null
+                                                          : specific
+                                                              .getReturnType();
+
+                //
+                row[specific_catalog] = database.getCatalogName().name;
+                row[specific_schema]  = specific.getSchemaName().name;
+                row[specific_name]    = specific.getSpecificName().name;
+                row[routine_catalog]  = database.getCatalogName().name;
+                row[routine_schema]   = routine.getSchemaName().name;
+                row[routine_name]     = specific.getName().name;
+                row[routine_type] = specific.isProcedure() ? Tokens.T_PROCEDURE
+                                                           : Tokens.T_FUNCTION;
+                row[module_catalog] = null;
+                row[module_schema]  = null;
+                row[module_name]    = null;
+                row[udt_catalog]    = null;
+                row[udt_schema]     = null;
+                row[udt_name]       = null;
+                row[data_type]      = type == null ? null
+                                                   : type.getNameString();
+
+                if (type != null) {
+
+                    // common type block
+                    if (type.isCharacterType()) {
+                        row[character_maximum_length] =
+                            ValuePool.getLong(type.precision);
+                        row[character_octet_length] =
+                            ValuePool.getLong(type.precision * 2);
+                        row[character_set_catalog] =
+                            database.getCatalogName().name;
+                        row[character_set_schema] =
+                            ((CharacterType) type).getCharacterSet()
+                                .getSchemaName().name;
+                        row[character_set_name] =
+                            ((CharacterType) type).getCharacterSet().getName()
+                                .name;
+                        row[collation_catalog] =
+                            database.getCatalogName().name;
+                        row[collation_schema] =
+                            ((CharacterType) type).getCollation()
+                                .getSchemaName().name;
+                        row[collation_name] =
+                            ((CharacterType) type).getCollation().getName()
+                                .name;
+                    } else if (type.isNumberType()) {
+                        row[numeric_precision] = ValuePool.getLong(
+                            ((NumberType) type).getNumericPrecisionInRadix());
+                        row[declared_numeric_precision] = ValuePool.getLong(
+                            ((NumberType) type).getNumericPrecisionInRadix());
+
+                        if (type.isExactNumberType()) {
+                            row[numeric_scale] = row[declared_numeric_scale] =
+                                ValuePool.getLong(type.scale);
+                        }
+
+                        row[numeric_precision_radix] =
+                            ValuePool.getLong(type.getPrecisionRadix());
+                    } else if (type.isBooleanType()) {
+
+                        //
+                    } else if (type.isDateTimeType()) {
+                        row[datetime_precision] =
+                            ValuePool.getLong(type.scale);
+                    } else if (type.isIntervalType()) {
+                        row[data_type] = "INTERVAL";
+                        row[interval_type] =
+                            ((IntervalType) type).getQualifier(type.typeCode);
+                        row[interval_precision] =
+                            ValuePool.getLong(type.precision);
+                        row[datetime_precision] =
+                            ValuePool.getLong(type.scale);
+                    } else if (type.isBinaryType()) {
+                        row[character_maximum_length] =
+                            ValuePool.getLong(type.precision);
+                        row[character_octet_length] =
+                            ValuePool.getLong(type.precision);
+                    } else if (type.isBitType()) {
+                        row[character_maximum_length] =
+                            ValuePool.getLong(type.precision);
+                        row[character_octet_length] =
+                            ValuePool.getLong(type.precision);
+                    } else if (type.isArrayType()) {
+                        row[maximum_cardinality] =
+                            ValuePool.getLong(type.arrayLimitCardinality());
+                    }
+
+                    // end common block
+                }
+
+                row[type_udt_catalog] = null;
+                row[type_udt_schema]  = null;
+                row[type_udt_name]    = null;
+                row[scope_catalog]    = null;
+                row[scope_schema]     = null;
+                row[scope_name]       = null;
+                row[dtd_identifier]   = null;    //**
+                row[routine_body] = specific.getLanguage()
+                                    == Routine.LANGUAGE_JAVA ? "EXTERNAL"
+                                                             : "SQL";
+                row[routine_definition] = specific.getSQL();
+                row[external_name] =
+                    specific.getLanguage() == Routine.LANGUAGE_JAVA
+                    ? specific.getMethod().getName()
+                    : null;
+                row[external_language] = specific.getLanguage()
+                                         == Routine.LANGUAGE_JAVA ? "JAVA"
+                                                                  : null;
+                row[parameter_style] = specific.getLanguage()
+                                       == Routine.LANGUAGE_JAVA ? "JAVA"
+                                                                : null;
+                row[is_deterministic] = specific.isDeterministic() ? "YES"
+                                                                   : "NO";
+                row[sql_data_access]  = specific.getDataImpactString();
+                row[is_null_call]     = type == null ? null
+                                                     : specific.isNullInputOutput()
+                                                       ? "YES"
+                                                       : "NO";
+                row[sql_path]                               = null;
+                row[schema_level_routine]                   = "YES";
+                row[max_dynamic_result_sets] = ValuePool.getLong(0);
+                row[is_user_defined_cast] = type == null ? null
+                                                         : "NO";
+                row[is_implicitly_invocable]                = null;
+                row[security_type]                          = "DEFINER";
+                row[to_sql_specific_catalog]                = null;
+                row[to_sql_specific_schema]                 = null;
+                row[to_sql_specific_name]                   = null;
+                row[as_locator] = type == null ? null
+                                               : "NO";
+                row[created]                                = null;
+                row[last_altered]                           = null;
+                row[new_savepoint_level]                    = "YES";
+                row[is_udt_dependent]                       = null;
+                row[result_cast_from_data_type]             = null;
+                row[result_cast_as_locator]                 = null;
+                row[result_cast_char_max_length]            = null;
+                row[result_cast_char_octet_length]          = null;
+                row[result_cast_char_set_catalog]           = null;
+                row[result_cast_char_set_schema]            = null;
+                row[result_cast_character_set_name]         = null;
+                row[result_cast_collation_catalog]          = null;
+                row[result_cast_collation_schema]           = null;
+                row[result_cast_collation_name]             = null;
+                row[result_cast_numeric_precision]          = null;
+                row[result_cast_numeric_radix]              = null;
+                row[result_cast_numeric_scale]              = null;
+                row[result_cast_datetime_precision]         = null;
+                row[result_cast_interval_type]              = null;
+                row[result_cast_interval_precision]         = null;
+                row[result_cast_type_udt_catalog]           = null;
+                row[result_cast_type_udt_schema]            = null;
+                row[result_cast_type_udt_name]              = null;
+                row[result_cast_scope_catalog]              = null;
+                row[result_cast_scope_schema]               = null;
+                row[result_cast_scope_name]                 = null;
+                row[result_cast_max_cardinality]            = null;
+                row[result_cast_dtd_identifier]             = null;
+                row[declared_data_type]                     = row[data_type];
+                row[declared_numeric_precision] = row[numeric_precision];
+                row[declared_numeric_scale] = row[numeric_scale];
+                row[result_cast_from_declared_data_type]    = null;
+                row[result_cast_declared_numeric_precision] = null;
+                row[result_cast_declared_numeric_scale]     = null;
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * SCHEMATA<p>
+     *
+     * <b>Function</b><p>
+     *
+     * The SCHEMATA view has one row for each accessible schema. <p>
+     *
+     * <b>Definition</b><p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE SCHEMATA (
+     *      CATALOG_NAME INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *      SCHEMA_NAME INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *      SCHEMA_OWNER INFORMATION_SCHEMA.SQL_IDENTIFIER
+     *          CONSTRAINT SCHEMA_OWNER_NOT_NULL
+     *              NOT NULL,
+     *      DEFAULT_CHARACTER_SET_CATALOG INFORMATION_SCHEMA.SQL_IDENTIFIER
+     *          CONSTRAINT DEFAULT_CHARACTER_SET_CATALOG_NOT_NULL
+     *              NOT NULL,
+     *      DEFAULT_CHARACTER_SET_SCHEMA INFORMATION_SCHEMA.SQL_IDENTIFIER
+     *          CONSTRAINT DEFAULT_CHARACTER_SET_SCHEMA_NOT_NULL
+     *              NOT NULL,
+     *      DEFAULT_CHARACTER_SET_NAME INFORMATION_SCHEMA.SQL_IDENTIFIER
+     *          CONSTRAINT DEFAULT_CHARACTER_SET_NAME_NOT_NULL
+     *              NOT NULL,
+     *      SQL_PATH INFORMATION_SCHEMA.CHARACTER_DATA,
+     *
+     *      CONSTRAINT SCHEMATA_PRIMARY_KEY
+     *          PRIMARY KEY ( CATALOG_NAME, SCHEMA_NAME ),
+     *      CONSTRAINT SCHEMATA_FOREIGN_KEY_AUTHORIZATIONS
+     *          FOREIGN KEY ( SCHEMA_OWNER )
+     *              REFERENCES AUTHORIZATIONS,
+     *      CONSTRAINT SCHEMATA_FOREIGN_KEY_CATALOG_NAMES
+     *          FOREIGN KEY ( CATALOG_NAME )
+     *              REFERENCES CATALOG_NAMES
+     *      )
+     * </pre>
+     *
+     * <b>Description</b><p>
+     *
+     * <ol>
+     *      <li>The value of CATALOG_NAME is the name of the catalog of the
+     *          schema described by this row.<p>
+     *
+     *      <li>The value of SCHEMA_NAME is the unqualified schema name of
+     *          the schema described by this row.<p>
+     *
+     *      <li>The values of SCHEMA_OWNER are the authorization identifiers
+     *          that own the schemata.<p>
+     *
+     *      <li>The values of DEFAULT_CHARACTER_SET_CATALOG,
+     *          DEFAULT_CHARACTER_SET_SCHEMA, and DEFAULT_CHARACTER_SET_NAME
+     *          are the catalog name, unqualified schema name, and qualified
+     *          identifier, respectively, of the default character set for
+     *          columns and domains in the schemata.<p>
+     *
+     *      <li>Case:<p>
+     *          <ul>
+     *              <li>If &lt;schema path specification&gt; was specified in
+     *                  the &lt;schema definition&gt; that defined the schema
+     *                  described by this row and the character representation
+     *                  of the &lt;schema path specification&gt; can be
+     *                  represented without truncation, then the value of
+     *                  SQL_PATH is that character representation.<p>
+     *
+     *              <li>Otherwise, the value of SQL_PATH is the null value.
+     *         </ul>
+     * </ol>
+     *
+     * @return Table
+     */
+    Table SCHEMATA(Session session) {
+
+        Table t = sysTables[SCHEMATA];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SCHEMATA]);
+
+            addColumn(t, "CATALOG_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SCHEMA_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SCHEMA_OWNER", SQL_IDENTIFIER);
+            addColumn(t, "DEFAULT_CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "DEFAULT_CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "DEFAULT_CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SQL_PATH", CHARACTER_DATA);
+
+            // order: CATALOG_NAME, SCHEMA_NAME
+            // false PK, as rows may have NULL CATALOG_NAME
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SCHEMATA].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        Iterator schemas;
+        String   schema;
+        String   dcsSchema = SqlInvariants.INFORMATION_SCHEMA;
+        String   dcsName   = ValuePool.getString("UTF16");
+        String   sqlPath   = null;
+        Grantee  user      = session.getGrantee();
+        Object[] row;
+
+        // column number mappings
+        final int schema_catalog                = 0;
+        final int schema_name                   = 1;
+        final int schema_owner                  = 2;
+        final int default_character_set_catalog = 3;
+        final int default_character_set_schema  = 4;
+        final int default_character_set_name    = 5;
+        final int sql_path                      = 6;
+
+        // Initialization
+        schemas = database.schemaManager.fullSchemaNamesIterator();
+
+        // Do it.
+        while (schemas.hasNext()) {
+            schema = (String) schemas.next();
+
+            if (!user.hasSchemaUpdateOrGrantRights(schema)) {
+                continue;
+            }
+
+            row                 = t.getEmptyRowData();
+            row[schema_catalog] = database.getCatalogName().name;
+            row[schema_name]    = schema;
+            row[schema_owner] =
+                database.schemaManager.toSchemaOwner(schema).getNameString();
+            row[default_character_set_catalog] =
+                database.getCatalogName().name;
+            row[default_character_set_schema] = dcsSchema;
+            row[default_character_set_name]   = dcsName;
+            row[sql_path]                     = sqlPath;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    Table SQL_FEATURES(Session session) {
+
+        Table t = sysTables[SQL_FEATURES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SQL_FEATURES]);
+
+            addColumn(t, "FEATURE_ID", CHARACTER_DATA);
+            addColumn(t, "FEATURE_NAME", CHARACTER_DATA);
+            addColumn(t, "SUB_FEATURE_ID", CHARACTER_DATA);
+            addColumn(t, "SUB_FEATURE_NAME", CHARACTER_DATA);
+            addColumn(t, "IS_SUPPORTED", YES_OR_NO);
+            addColumn(t, "IS_VERIFIED_BY", CHARACTER_DATA);
+            addColumn(t, "COMMENTS", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SQL_FEATURES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 2
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        String sql = (String) statementMap.get("/*sql_features*/");
+        Result rs =
+            sys.executeDirectStatement(sql,
+                                       ResultProperties.defaultPropsValue);
+
+        t.insertSys(store, rs);
+
+        return t;
+    }
+
+    Table SQL_IMPLEMENTATION_INFO(Session session) {
+
+        Table t = sysTables[SQL_IMPLEMENTATION_INFO];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SQL_IMPLEMENTATION_INFO]);
+
+            addColumn(t, "IMPLEMENTATION_INFO_ID", CHARACTER_DATA);
+            addColumn(t, "IMPLEMENTATION_INFO_NAME", CHARACTER_DATA);
+            addColumn(t, "INTEGER_VALUE", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_VALUE", CHARACTER_DATA);
+            addColumn(t, "COMMENTS", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SQL_IMPLEMENTATION_INFO].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+
+/*
+        Result rs = sys.executeDirectStatement(
+            "VALUES "
+            + ";");
+
+        t.insertSys(store, rs);
+*/
+        return t;
+    }
+
+    Table SQL_PACKAGES(Session session) {
+
+        Table t = sysTables[SQL_PACKAGES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SQL_PACKAGES]);
+
+            addColumn(t, "ID", CHARACTER_DATA);
+            addColumn(t, "NAME", CHARACTER_DATA);
+            addColumn(t, "IS_SUPPORTED", YES_OR_NO);
+            addColumn(t, "IS_VERIFIED_BY", CHARACTER_DATA);
+            addColumn(t, "COMMENTS", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SQL_PACKAGES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        String sql = (String) statementMap.get("/*sql_packages*/");
+        Result rs =
+            sys.executeDirectStatement(sql,
+                                       ResultProperties.defaultPropsValue);
+
+        t.insertSys(store, rs);
+
+        return t;
+    }
+
+    Table SQL_PARTS(Session session) {
+
+        Table t = sysTables[SQL_PARTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SQL_PARTS]);
+
+            addColumn(t, "PART", CHARACTER_DATA);
+            addColumn(t, "NAME", CHARACTER_DATA);
+            addColumn(t, "IS_SUPPORTED", YES_OR_NO);
+            addColumn(t, "IS_VERIFIED_BY", CHARACTER_DATA);
+            addColumn(t, "COMMENTS", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SQL_PARTS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        String sql = (String) statementMap.get("/*sql_parts*/");
+        Result rs =
+            sys.executeDirectStatement(sql,
+                                       ResultProperties.defaultPropsValue);
+
+        t.insertSys(store, rs);
+
+        return t;
+    }
+
+    Table SQL_SIZING(Session session) {
+
+        Table t = sysTables[SQL_SIZING];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SQL_SIZING]);
+
+            addColumn(t, "SIZING_ID", CARDINAL_NUMBER);
+            addColumn(t, "SIZING_NAME", CHARACTER_DATA);
+            addColumn(t, "SUPPORTED_VALUE", CARDINAL_NUMBER);
+            addColumn(t, "COMMENTS", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SQL_SIZING].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+        String sql = (String) statementMap.get("/*sql_sizing*/");
+        Result rs =
+            sys.executeDirectStatement(sql,
+                                       ResultProperties.defaultPropsValue);
+
+        t.insertSys(store, rs);
+
+        return t;
+    }
+
+    Table SQL_SIZING_PROFILES(Session session) {
+
+        Table t = sysTables[SQL_SIZING_PROFILES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SQL_SIZING_PROFILES]);
+
+            addColumn(t, "SIZING_ID", CARDINAL_NUMBER);
+            addColumn(t, "SIZING_NAME", CHARACTER_DATA);
+            addColumn(t, "PROFILE_ID", CARDINAL_NUMBER);
+            addColumn(t, "PROFILE_NAME", CHARACTER_DATA);
+            addColumn(t, "REQUIRED_VALUE", CARDINAL_NUMBER);
+            addColumn(t, "COMMENTS", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SQL_SIZING_PROFILES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Session sys = database.sessionManager.newSysSession(
+            SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
+
+        /*
+                Result rs = sys.executeDirectStatement(
+                    "VALUES "
+                    + ";");
+
+                t.insertSys(store, rs);
+        */
+        return t;
+    }
+
+    /**
+     * The TABLE_CONSTRAINTS table has one row for each table constraint
+     * associated with a table.  <p>
+     *
+     * It effectively contains a representation of the table constraint
+     * descriptors. <p>
+     *
+     * <b>Definition:</b> <p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE SYSTEM_TABLE_CONSTRAINTS (
+     *      CONSTRAINT_CATALOG      VARCHAR NULL,
+     *      CONSTRAINT_SCHEMA       VARCHAR NULL,
+     *      CONSTRAINT_NAME         VARCHAR NOT NULL,
+     *      CONSTRAINT_TYPE         VARCHAR NOT NULL,
+     *      TABLE_CATALOG           VARCHAR NULL,
+     *      TABLE_SCHEMA            VARCHAR NULL,
+     *      TABLE_NAME              VARCHAR NOT NULL,
+     *      IS_DEFERRABLE           VARCHAR NOT NULL,
+     *      INITIALLY_DEFERRED      VARCHAR NOT NULL,
+     *
+     *      CHECK ( CONSTRAINT_TYPE IN
+     *                      ( 'UNIQUE', 'PRIMARY KEY',
+     *                        'FOREIGN KEY', 'CHECK' ) ),
+     *
+     *      CHECK ( ( IS_DEFERRABLE, INITIALLY_DEFERRED ) IN
+     *              ( VALUES ( 'NO',  'NO'  ),
+     *                       ( 'YES', 'NO'  ),
+     *                       ( 'YES', 'YES' ) ) )
+     * )
+     * </pre>
+     *
+     * <b>Description:</b> <p>
+     *
+     * <ol>
+     * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, and
+     *      CONSTRAINT_NAME are the catalog name, unqualified schema
+     *      name, and qualified identifier, respectively, of the
+     *      constraint being described. If the &lt;table constraint
+     *      definition&gt; or &lt;add table constraint definition&gt;
+     *      that defined the constraint did not specify a
+     *      &lt;constraint name&gt;, then the values of CONSTRAINT_CATALOG,
+     *      CONSTRAINT_SCHEMA, and CONSTRAINT_NAME are
+     *      implementation-defined. <p>
+     *
+     * <li> The values of CONSTRAINT_TYPE have the following meanings: <p>
+     *  <table border cellpadding="3">
+     *  <tr>
+     *      <td nowrap>FOREIGN KEY</td>
+     *      <td nowrap>The constraint being described is a
+     *                 foreign key constraint.</td>
+     *  </tr>
+     *  <tr>
+     *      <td nowrap>UNIQUE</td>
+     *      <td nowrap>The constraint being described is a
+     *                 unique constraint.</td>
+     *  </tr>
+     *  <tr>
+     *      <td nowrap>PRIMARY KEY</td>
+     *      <td nowrap>The constraint being described is a
+     *                 primary key constraint.</td>
+     *  </tr>
+     *  <tr>
+     *      <td nowrap>CHECK</td>
+     *      <td nowrap>The constraint being described is a
+     *                 check constraint.</td>
+     *  </tr>
+     * </table> <p>
+     *
+     * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, and TABLE_NAME are
+     *      the catalog name, the unqualified schema name, and the
+     *      qualified identifier of the name of the table to which the
+     *      table constraint being described applies. <p>
+     *
+     * <li> The values of IS_DEFERRABLE have the following meanings: <p>
+     *
+     *  <table>
+     *      <tr>
+     *          <td nowrap>YES</td>
+     *          <td nowrap>The table constraint is deferrable.</td>
+     *      </tr>
+     *      <tr>
+     *          <td nowrap>NO</td>
+     *          <td nowrap>The table constraint is not deferrable.</td>
+     *      </tr>
+     *  </table> <p>
+     *
+     * <li> The values of INITIALLY_DEFERRED have the following meanings: <p>
+     *
+     *  <table>
+     *      <tr>
+     *          <td nowrap>YES</td>
+     *          <td nowrap>The table constraint is initially deferred.</td>
+     *      </tr>
+     *      <tr>
+     *          <td nowrap>NO</td>
+     *          <td nowrap>The table constraint is initially immediate.</td>
+     *      </tr>
+     *  </table> <p>
+     * </ol>
+     *
+     * @return Table
+     */
+    Table TABLE_CONSTRAINTS(Session session) {
+
+        Table t = sysTables[TABLE_CONSTRAINTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TABLE_CONSTRAINTS]);
+
+            addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "CONSTRAINT_TYPE", CHARACTER_DATA);    // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);         // not null
+            addColumn(t, "IS_DEFERRABLE", YES_OR_NO);           // not null
+            addColumn(t, "INITIALLY_DEFERRED", YES_OR_NO);      // not null
+
+            // false PK, as CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA,
+            // TABLE_CATALOG and/or TABLE_SCHEMA may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TABLE_CONSTRAINTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        Iterator     tables;
+        Table        table;
+        Constraint[] constraints;
+        int          constraintCount;
+        Constraint   constraint;
+        String       cat;
+        String       schem;
+        Object[]     row;
+
+        // column number mappings
+        final int constraint_catalog = 0;
+        final int constraint_schema  = 1;
+        final int constraint_name    = 2;
+        final int constraint_type    = 3;
+        final int table_catalog      = 4;
+        final int table_schema       = 5;
+        final int table_name         = 6;
+        final int is_deferable       = 7;
+        final int initially_deferred = 8;
+
+        // initialization
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+        table = null;    // else compiler complains
+
+        // do it
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            /** @todo - requires table level INSERT or UPDATE or DELETE or REFERENCES (not SELECT) right */
+            if (table.isView() || !isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            constraints     = table.getConstraints();
+            constraintCount = constraints.length;
+
+            for (int i = 0; i < constraintCount; i++) {
+                constraint = constraints[i];
+                row        = t.getEmptyRowData();
+
+                switch (constraint.getConstraintType()) {
+
+                    case SchemaObject.ConstraintTypes.CHECK : {
+                        row[constraint_type] = "CHECK";
+
+                        break;
+                    }
+                    case SchemaObject.ConstraintTypes.UNIQUE : {
+                        row[constraint_type] = "UNIQUE";
+
+                        break;
+                    }
+                    case SchemaObject.ConstraintTypes.FOREIGN_KEY : {
+                        row[constraint_type] = "FOREIGN KEY";
+                        table                = constraint.getRef();
+
+                        break;
+                    }
+                    case SchemaObject.ConstraintTypes.PRIMARY_KEY : {
+                        row[constraint_type] = "PRIMARY KEY";
+
+                        break;
+                    }
+                    case SchemaObject.ConstraintTypes.MAIN :
+                    default : {
+                        continue;
+                    }
+                }
+
+                cat                     = database.getCatalogName().name;
+                schem                   = table.getSchemaName().name;
+                row[constraint_catalog] = cat;
+                row[constraint_schema]  = schem;
+                row[constraint_name]    = constraint.getName().name;
+                row[table_catalog]      = cat;
+                row[table_schema]       = schem;
+                row[table_name]         = table.getName().name;
+                row[is_deferable]       = Tokens.T_NO;
+                row[initially_deferred] = Tokens.T_NO;
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    Table TRANSLATIONS(Session session) {
+
+        Table t = sysTables[TRANSLATIONS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TRANSLATIONS]);
+
+            addColumn(t, "TRANSLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TRANSLATION_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TRANSLATION_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SOURCE_CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SOURCE_CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SOURCE_CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TARGET_CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TARGET_CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TARGET_CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TRANSLATION_SOURCE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TRANSLATION_SOURCE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TRANSLATION_SOURCE_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TRANSLATIONS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        return t;
+    }
+
+    Table TRIGGER_COLUMN_USAGE(Session session) {
+
+        Table t = sysTables[TRIGGER_COLUMN_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TRIGGER_COLUMN_USAGE]);
+
+            addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);      // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);     // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TRIGGER_COLUMN_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int trigger_catalog = 0;
+        final int trigger_schema  = 1;
+        final int trigger_name    = 2;
+        final int table_catalog   = 3;
+        final int table_schema    = 4;
+        final int table_name      = 5;
+        final int column_name     = 6;
+        Iterator  it;
+        Object[]  row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.TRIGGER);
+
+        while (it.hasNext()) {
+            TriggerDef trigger = (TriggerDef) it.next();
+
+            if (!session.getGrantee().isAccessible(trigger)) {
+                continue;
+            }
+
+            OrderedHashSet set = trigger.getReferences();
+
+            for (int i = 0; i < set.size(); i++) {
+                HsqlName refName = (HsqlName) set.get(i);
+
+                if (refName.type != SchemaObject.COLUMN) {
+                    continue;
+                }
+
+                if (!session.getGrantee().isAccessible(refName)) {
+                    continue;
+                }
+
+                row = t.getEmptyRowData();
+
+                //
+                row[trigger_catalog] = database.getCatalogName().name;
+                row[trigger_schema]  = trigger.getSchemaName().name;
+                row[trigger_name]    = trigger.getName().name;
+                row[table_catalog]   = database.getCatalogName().name;
+                row[table_schema]    = refName.parent.schema.name;
+                row[table_name]      = refName.parent.name;
+                row[column_name]     = refName.name;
+
+                try {
+                    t.insertSys(store, row);
+                } catch (HsqlException e) {}
+            }
+        }
+
+        // Initialization
+        return t;
+    }
+
+    Table TRIGGER_ROUTINE_USAGE(Session session) {
+
+        Table t = sysTables[TRIGGER_ROUTINE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TRIGGER_ROUTINE_USAGE]);
+
+            addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);     // not null
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);    // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TRIGGER_ROUTINE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int trigger_catalog  = 0;
+        final int trigger_schema   = 1;
+        final int trigger_name     = 2;
+        final int specific_catalog = 3;
+        final int specific_schema  = 4;
+        final int specific_name    = 5;
+        Iterator  it;
+        Object[]  row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.TRIGGER);
+
+        while (it.hasNext()) {
+            TriggerDef trigger = (TriggerDef) it.next();
+
+            if (!session.getGrantee().isAccessible(trigger)) {
+                continue;
+            }
+
+            OrderedHashSet set = trigger.getReferences();
+
+            for (int i = 0; i < set.size(); i++) {
+                HsqlName refName = (HsqlName) set.get(i);
+
+                if (refName.type != SchemaObject.SPECIFIC_ROUTINE) {
+                    continue;
+                }
+
+                if (!session.getGrantee().isAccessible(refName)) {
+                    continue;
+                }
+
+                row                   = t.getEmptyRowData();
+                row[trigger_catalog]  = database.getCatalogName().name;
+                row[trigger_schema]   = trigger.getSchemaName().name;
+                row[trigger_name]     = trigger.getName().name;
+                row[specific_catalog] = database.getCatalogName().name;
+                row[specific_schema]  = refName.schema.name;
+                row[specific_name]    = refName.name;
+
+                try {
+                    t.insertSys(store, row);
+                } catch (HsqlException e) {}
+            }
+        }
+
+        return t;
+    }
+
+    Table TRIGGER_SEQUENCE_USAGE(Session session) {
+
+        Table t = sysTables[TRIGGER_SEQUENCE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TRIGGER_SEQUENCE_USAGE]);
+
+            addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);     // not null
+            addColumn(t, "SEQUENCE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_NAME", SQL_IDENTIFIER);    // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TRIGGER_SEQUENCE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int trigger_catalog  = 0;
+        final int trigger_schema   = 1;
+        final int trigger_name     = 2;
+        final int sequence_catalog = 3;
+        final int sequence_schema  = 4;
+        final int sequence_name    = 5;
+        Iterator  it;
+        Object[]  row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.TRIGGER);
+
+        while (it.hasNext()) {
+            TriggerDef trigger = (TriggerDef) it.next();
+
+            if (!session.getGrantee().isAccessible(trigger)) {
+                continue;
+            }
+
+            OrderedHashSet set = trigger.getReferences();
+
+            for (int i = 0; i < set.size(); i++) {
+                HsqlName refName = (HsqlName) set.get(i);
+
+                if (refName.type != SchemaObject.SEQUENCE) {
+                    continue;
+                }
+
+                if (!session.getGrantee().isAccessible(refName)) {
+                    continue;
+                }
+
+                row                   = t.getEmptyRowData();
+                row[trigger_catalog]  = database.getCatalogName().name;
+                row[trigger_schema]   = trigger.getSchemaName().name;
+                row[trigger_name]     = trigger.getName().name;
+                row[sequence_catalog] = database.getCatalogName().name;
+                row[sequence_schema]  = refName.schema.name;
+                row[sequence_name]    = refName.name;
+
+                try {
+                    t.insertSys(store, row);
+                } catch (HsqlException e) {}
+            }
+        }
+
+        // Initialization
+        return t;
+    }
+
+    Table TRIGGER_TABLE_USAGE(Session session) {
+
+        Table t = sysTables[TRIGGER_TABLE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TRIGGER_TABLE_USAGE]);
+
+            addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);      // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TRIGGER_TABLE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int trigger_catalog = 0;
+        final int trigger_schema  = 1;
+        final int trigger_name    = 2;
+        final int table_catalog   = 3;
+        final int table_schema    = 4;
+        final int table_name      = 5;
+        Iterator  it;
+        Object[]  row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.TRIGGER);
+
+        while (it.hasNext()) {
+            TriggerDef trigger = (TriggerDef) it.next();
+
+            if (!session.getGrantee().isAccessible(trigger)) {
+                continue;
+            }
+
+            OrderedHashSet set = trigger.getReferences();
+
+            for (int i = 0; i < set.size(); i++) {
+                HsqlName refName = (HsqlName) set.get(i);
+
+                if (refName.type != SchemaObject.TABLE
+                        && refName.type != SchemaObject.VIEW) {
+                    continue;
+                }
+
+                if (!session.getGrantee().isAccessible(refName)) {
+                    continue;
+                }
+
+                row                  = t.getEmptyRowData();
+                row[trigger_catalog] = database.getCatalogName().name;
+                row[trigger_schema]  = trigger.getSchemaName().name;
+                row[trigger_name]    = trigger.getName().name;
+                row[table_catalog]   = database.getCatalogName().name;
+                row[table_schema]    = refName.schema.name;
+                row[table_name]      = refName.name;
+
+                try {
+                    t.insertSys(store, row);
+                } catch (HsqlException e) {}
+            }
+        }
+
+        // Initialization
+        return t;
+    }
+
+    Table TRIGGERS(Session session) {
+
+        Table t = sysTables[TRIGGERS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TRIGGERS]);
+
+            addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);
+            addColumn(t, "EVENT_MANIPULATION", SQL_IDENTIFIER);
+            addColumn(t, "EVENT_OBJECT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "EVENT_OBJECT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "EVENT_OBJECT_TABLE", SQL_IDENTIFIER);
+            addColumn(t, "ACTION_ORDER", CARDINAL_NUMBER);
+            addColumn(t, "ACTION_CONDITION", CHARACTER_DATA);
+            addColumn(t, "ACTION_STATEMENT", CHARACTER_DATA);
+            addColumn(t, "ACTION_ORIENTATION", CHARACTER_DATA);
+            addColumn(t, "ACTION_TIMING", CHARACTER_DATA);
+            addColumn(t, "ACTION_REFERENCE_OLD_TABLE", SQL_IDENTIFIER);
+            addColumn(t, "ACTION_REFERENCE_NEW_TABLE", SQL_IDENTIFIER);
+            addColumn(t, "ACTION_REFERENCE_OLD_ROW", SQL_IDENTIFIER);
+            addColumn(t, "ACTION_REFERENCE_NEW_ROW", SQL_IDENTIFIER);
+            addColumn(t, "CREATED", TIME_STAMP);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TRIGGERS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int trigger_catalog            = 0;
+        final int trigger_schema             = 1;
+        final int trigger_name               = 2;
+        final int event_manipulation         = 3;
+        final int event_object_catalog       = 4;
+        final int event_object_schema        = 5;
+        final int event_object_table         = 6;
+        final int action_order               = 7;
+        final int action_condition           = 8;
+        final int action_statement           = 9;
+        final int action_orientation         = 10;
+        final int action_timing              = 11;
+        final int action_reference_old_table = 12;
+        final int action_reference_new_table = 13;
+        final int action_reference_old_row   = 14;
+        final int action_reference_new_row   = 15;
+        final int created                    = 16;
+        Iterator  it;
+        Object[]  row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.TRIGGER);
+
+        while (it.hasNext()) {
+            TriggerDef trigger = (TriggerDef) it.next();
+
+            if (!session.getGrantee().isAccessible(trigger)) {
+                continue;
+            }
+
+            row                       = t.getEmptyRowData();
+            row[trigger_catalog]      = database.getCatalogName().name;
+            row[trigger_schema]       = trigger.getSchemaName().name;
+            row[trigger_name]         = trigger.getName().name;
+            row[event_manipulation]   = trigger.getEventTypeString();
+            row[event_object_catalog] = database.getCatalogName().name;
+            row[event_object_schema] = trigger.getTable().getSchemaName().name;
+            row[event_object_table]   = trigger.getTable().getName().name;
+
+            int order =
+                trigger.getTable().getTriggerIndex(trigger.getName().name);
+
+            row[action_order]       = ValuePool.getLong(order);
+            row[action_condition]   = trigger.getConditionSQL();
+            row[action_statement]   = trigger.getProcedureSQL();
+            row[action_orientation] = trigger.getActionOrientationString();
+            row[action_timing]      = trigger.getActionTimingString();
+            row[action_reference_old_table] =
+                trigger.getOldTransitionTableName();
+            row[action_reference_new_table] =
+                trigger.getNewTransitionTableName();
+            row[action_reference_old_row] = trigger.getOldTransitionRowName();
+            row[action_reference_new_row] = trigger.getNewTransitionRowName();
+            row[created]                  = null;
+
+            t.insertSys(store, row);
+        }
+
+        // Initialization
+        return t;
+    }
+
+    Table TRIGGERED_UPDATE_COLUMNS(Session session) {
+
+        Table t = sysTables[TRIGGERED_UPDATE_COLUMNS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TRIGGERED_UPDATE_COLUMNS]);
+
+            addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);            // not null
+            addColumn(t, "EVENT_OBJECT_CATALOG", SQL_IDENTIFIER);    // not null
+            addColumn(t, "EVENT_OBJECT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "EVENT_OBJECT_TABLE", SQL_IDENTIFIER);
+            addColumn(t, "EVENT_OBJECT_COLUMN", SQL_IDENTIFIER);     // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TRIGGERED_UPDATE_COLUMNS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int trigger_catalog      = 0;
+        final int trigger_schema       = 1;
+        final int trigger_name         = 2;
+        final int event_object_catalog = 3;
+        final int event_object_schema  = 4;
+        final int event_object_table   = 5;
+        final int event_object_column  = 6;
+        Iterator  it;
+        Object[]  row;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.TRIGGER);
+
+        while (it.hasNext()) {
+            TriggerDef trigger = (TriggerDef) it.next();
+
+            if (!session.getGrantee().isAccessible(trigger)) {
+                continue;
+            }
+
+            int[] colIndexes = trigger.getUpdateColumnIndexes();
+
+            if (colIndexes == null) {
+                continue;
+            }
+
+            for (int i = 0; i < colIndexes.length; i++) {
+                ColumnSchema column =
+                    trigger.getTable().getColumn(colIndexes[i]);
+
+                row                       = t.getEmptyRowData();
+                row[trigger_catalog]      = database.getCatalogName().name;
+                row[trigger_schema]       = trigger.getSchemaName().name;
+                row[trigger_name]         = trigger.getName().name;
+                row[event_object_catalog] = database.getCatalogName().name;
+                row[event_object_schema] =
+                    trigger.getTable().getSchemaName().name;
+                row[event_object_table]  = trigger.getTable().getName().name;
+                row[event_object_column] = column.getNameString();
+
+                t.insertSys(store, row);
+            }
+        }
+
+        // Initialization
+        return t;
+    }
+
+    Table UDT_PRIVILEGES(Session session) {
+
+        Table t = sysTables[UDT_PRIVILEGES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[UDT_PRIVILEGES]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);
+            addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[UDT_PRIVILEGES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4
+            }, false);
+
+            return t;
+        }
+
+        final int       grantor        = 0;
+        final int       grantee        = 1;
+        final int       udt_catalog    = 2;
+        final int       udt_schema     = 3;
+        final int       udt_name       = 4;
+        final int       privilege_type = 5;
+        final int       is_grantable   = 6;
+        PersistentStore store          = session.sessionData.getRowStore(t);
+        Iterator objects =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TYPE);
+        OrderedHashSet grantees =
+            session.getGrantee().getGranteeAndAllRolesWithPublic();
+
+        while (objects.hasNext()) {
+            SchemaObject object = (SchemaObject) objects.next();
+
+            if (object.getType() != SchemaObject.TYPE) {
+                continue;
+            }
+
+            for (int i = 0; i < grantees.size(); i++) {
+                Grantee granteeObject = (Grantee) grantees.get(i);
+                OrderedHashSet rights =
+                    granteeObject.getAllDirectPrivileges(object);
+                OrderedHashSet grants =
+                    granteeObject.getAllGrantedPrivileges(object);
+
+                if (!grants.isEmpty()) {
+                    grants.addAll(rights);
+
+                    rights = grants;
+                }
+
+                for (int j = 0; j < rights.size(); j++) {
+                    Right    right          = (Right) rights.get(j);
+                    Right    grantableRight = right.getGrantableRights();
+                    Object[] row;
+
+                    row                 = t.getEmptyRowData();
+                    row[grantor]        = right.getGrantor().getName().name;
+                    row[grantee]        = right.getGrantee().getName().name;
+                    row[udt_catalog]    = database.getCatalogName().name;
+                    row[udt_schema]     = object.getSchemaName().name;
+                    row[udt_name]       = object.getName().name;
+                    row[privilege_type] = Tokens.T_USAGE;
+                    row[is_grantable] =
+                        right.getGrantee() == object.getOwner()
+                        || grantableRight.isFull() ? Tokens.T_YES
+                                                   : Tokens.T_NO;;
+
+                    try {
+                        t.insertSys(store, row);
+                    } catch (HsqlException e) {}
+                }
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The USAGE_PRIVILEGES view has one row for each usage privilege
+     * descriptor. <p>
+     *
+     * It effectively contains a representation of the usage privilege
+     * descriptors. <p>
+     *
+     * <b>Definition:</b> <p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE SYSTEM_USAGE_PRIVILEGES (
+     *      GRANTOR         VARCHAR NOT NULL,
+     *      GRANTEE         VARCHAR NOT NULL,
+     *      OBJECT_CATALOG  VARCHAR NULL,
+     *      OBJECT_SCHEMA   VARCHAR NULL,
+     *      OBJECT_NAME     VARCHAR NOT NULL,
+     *      OBJECT_TYPE     VARCHAR NOT NULL
+     *
+     *          CHECK ( OBJECT_TYPE IN (
+     *                      'DOMAIN',
+     *                      'CHARACTER SET',
+     *                      'COLLATION',
+     *                      'TRANSLATION',
+     *                      'SEQUENCE' ) ),
+     *
+     *      IS_GRANTABLE    VARCHAR NOT NULL
+     *
+     *          CHECK ( IS_GRANTABLE IN ( 'YES', 'NO' ) ),
+     *
+     *      UNIQUE( GRANTOR, GRANTEE, OBJECT_CATALOG,
+     *              OBJECT_SCHEMA, OBJECT_NAME, OBJECT_TYPE )
+     * )
+     * </pre>
+     *
+     * <b>Description:</b><p>
+     *
+     * <ol>
+     * <li> The value of GRANTOR is the &lt;authorization identifier&gt; of the
+     *      user or role who granted usage privileges on the object of the type
+     *      identified by OBJECT_TYPE that is identified by OBJECT_CATALOG,
+     *      OBJECT_SCHEMA, and OBJECT_NAME, to the user or role identified by the
+     *      value of GRANTEE forthe usage privilege being described. <p>
+     *
+     * <li> The value of GRANTEE is the &lt;authorization identifier&gt; of some
+     *      user or role, or PUBLIC to indicate all users, to whom the usage
+     *      privilege being described is granted. <p>
+     *
+     * <li> The values of OBJECT_CATALOG, OBJECT_SCHEMA, and OBJECT_NAME are the
+     *      catalog name, unqualified schema name, and qualified identifier,
+     *      respectively, of the object to which the privilege applies. <p>
+     *
+     * <li> The values of OBJECT_TYPE have the following meanings: <p>
+     *
+     *      <table border cellpadding="3">
+     *          <tr>
+     *              <td nowrap>DOMAIN</td>
+     *              <td nowrap>The object to which the privilege applies is
+     *                         a domain.</td>
+     *          <tr>
+     *          <tr>
+     *              <td nowrap>CHARACTER SET</td>
+     *              <td nowrap>The object to which the privilege applies is a
+     *                         character set.</td>
+     *          <tr>
+     *          <tr>
+     *              <td nowrap>COLLATION</td>
+     *              <td nowrap>The object to which the privilege applies is a
+     *                         collation.</td>
+     *          <tr>
+     *          <tr>
+     *              <td nowrap>TRANSLATION</td>
+     *              <td nowrap>The object to which the privilege applies is a
+     *                         transliteration.</td>
+     *          <tr>
+     *          <tr>
+     *              <td nowrap>SEQUENCE</td>
+     *              <td nowrap>The object to which the privilege applies is a
+     *                         sequence generator.</td>
+     *          <tr>
+     *      </table> <p>
+     *
+     * <li> The values of IS_GRANTABLE have the following meanings: <p>
+     *
+     *      <table border cellpadding="3">
+     *          <tr>
+     *              <td nowrap>YES</td>
+     *              <td nowrap>The privilege being described was granted
+     *                         WITH GRANT OPTION and is thus grantable.</td>
+     *          <tr>
+     *          <tr>
+     *              <td nowrap>NO</td>
+     *              <td nowrap>The privilege being described was not granted
+     *                  WITH GRANT OPTION and is thus not grantable.</td>
+     *          <tr>
+     *      </table> <p>
+     * <ol>
+     *
+     * @return Table
+     */
+    Table USAGE_PRIVILEGES(Session session) {
+
+        Table t = sysTables[USAGE_PRIVILEGES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[USAGE_PRIVILEGES]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);        // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);        // not null
+            addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "OBJECT_TYPE", CHARACTER_DATA);    // not null
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);        // not null
+
+            // order: COLUMN_NAME, PRIVILEGE
+            // for unique: GRANTEE, GRANTOR, TABLE_NAME, TABLE_SCHEM, TABLE_CAT
+            // false PK, as TABLE_SCHEM and/or TABLE_CAT may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[USAGE_PRIVILEGES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6, 7
+            }, false);
+
+            return t;
+        }
+
+        //
+        Object[] row;
+
+        //
+        final int       grantor        = 0;
+        final int       grantee        = 1;
+        final int       object_catalog = 2;
+        final int       object_schema  = 3;
+        final int       object_name    = 4;
+        final int       object_type    = 5;
+        final int       privilege_type = 6;
+        final int       is_grantable   = 7;
+        PersistentStore store          = session.sessionData.getRowStore(t);
+        Iterator objects =
+            new WrapperIterator(database.schemaManager
+                .databaseObjectIterator(SchemaObject.SEQUENCE), database
+                .schemaManager.databaseObjectIterator(SchemaObject.COLLATION));
+
+        objects = new WrapperIterator(
+            objects,
+            database.schemaManager.databaseObjectIterator(
+                SchemaObject.CHARSET));
+        objects = new WrapperIterator(
+            objects,
+            database.schemaManager.databaseObjectIterator(
+                SchemaObject.DOMAIN));
+
+/*
+        objects = new WrapperIterator(
+            objects,
+            database.schemaManager.databaseObjectIterator(SchemaObject.TYPE));
+*/
+        OrderedHashSet grantees =
+            session.getGrantee().getGranteeAndAllRolesWithPublic();
+
+        while (objects.hasNext()) {
+            SchemaObject object = (SchemaObject) objects.next();
+
+            for (int i = 0; i < grantees.size(); i++) {
+                Grantee granteeObject = (Grantee) grantees.get(i);
+                OrderedHashSet rights =
+                    granteeObject.getAllDirectPrivileges(object);
+                OrderedHashSet grants =
+                    granteeObject.getAllGrantedPrivileges(object);
+
+                if (!grants.isEmpty()) {
+                    grants.addAll(rights);
+
+                    rights = grants;
+                }
+
+                for (int j = 0; j < rights.size(); j++) {
+                    Right right          = (Right) rights.get(j);
+                    Right grantableRight = right.getGrantableRights();
+
+                    row                 = t.getEmptyRowData();
+                    row[grantor]        = right.getGrantor().getName().name;
+                    row[grantee]        = right.getGrantee().getName().name;
+                    row[object_catalog] = database.getCatalogName().name;
+                    row[object_schema]  = object.getSchemaName().name;
+                    row[object_name]    = object.getName().name;
+                    row[object_type] =
+                        SchemaObjectSet.getName(object.getName().type);
+                    row[privilege_type] = Tokens.T_USAGE;
+                    row[is_grantable] =
+                        right.getGrantee() == object.getOwner()
+                        || grantableRight.isFull() ? Tokens.T_YES
+                                                   : Tokens.T_NO;;
+
+                    try {
+                        t.insertSys(store, row);
+                    } catch (HsqlException e) {}
+                }
+            }
+        }
+
+        return t;
+    }
+
+    Table USER_DEFINED_TYPES(Session session) {
+
+        Table t = sysTables[USER_DEFINED_TYPES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[USER_DEFINED_TYPES]);
+
+            addColumn(t, "USER_DEFINED_TYPE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "USER_DEFINED_TYPE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "USER_DEFINED_TYPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "USER_DEFINED_TYPE_CATEGORY", SQL_IDENTIFIER);
+            addColumn(t, "IS_INSTANTIABLE", YES_OR_NO);
+            addColumn(t, "IS_FINAL", YES_OR_NO);
+            addColumn(t, "ORDERING_FORM", SQL_IDENTIFIER);
+            addColumn(t, "ORDERING_CATEGORY", SQL_IDENTIFIER);
+            addColumn(t, "ORDERING_ROUTINE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "ORDERING_ROUTINE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "ORDERING_ROUTINE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "REFERENCE_TYPE", SQL_IDENTIFIER);
+            addColumn(t, "DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
+            addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
+            addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
+            addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "SOURCE_DTD_IDENTIFIER", CHARACTER_DATA);
+            addColumn(t, "REF_DTD_IDENTIFIER", CHARACTER_DATA);
+            addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "EXTERNAL_NAME", CHARACTER_DATA);
+            addColumn(t, "EXTERNAL_LANGUAGE", CHARACTER_DATA);
+            addColumn(t, "JAVA_INTERFACE", CHARACTER_DATA);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[USER_DEFINED_TYPES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        final int       user_defined_type_catalog  = 0;
+        final int       user_defined_type_schema   = 1;
+        final int       user_defined_type_name     = 2;
+        final int       user_defined_type_category = 3;
+        final int       is_instantiable            = 4;
+        final int       is_final                   = 5;
+        final int       ordering_form              = 6;
+        final int       ordering_category          = 7;
+        final int       ordering_routine_catalog   = 8;
+        final int       ordering_routine_schema    = 9;
+        final int       ordering_routine_name      = 10;
+        final int       reference_type             = 11;
+        final int       data_type                  = 12;
+        final int       character_maximum_length   = 13;
+        final int       character_octet_length     = 14;
+        final int       character_set_catalog      = 15;
+        final int       character_set_schema       = 16;
+        final int       character_set_name         = 17;
+        final int       collation_catalog          = 18;
+        final int       collation_schema           = 19;
+        final int       collation_name             = 20;
+        final int       numeric_precision          = 21;
+        final int       numeric_precision_radix    = 22;
+        final int       numeric_scale              = 23;
+        final int       datetime_precision         = 24;
+        final int       interval_type              = 25;
+        final int       interval_precision         = 26;
+        final int       source_dtd_identifier      = 27;
+        final int       ref_dtd_identifier         = 28;
+        final int       declared_data_type         = 29;
+        final int       declared_numeric_precision = 30;
+        final int       declared_numeric_scale     = 31;
+        Iterator it =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TYPE);
+
+        while (it.hasNext()) {
+            Type type = (Type) it.next();
+
+            if (!type.isDistinctType()) {
+                continue;
+            }
+
+            Object[] row = t.getEmptyRowData();
+
+            row[user_defined_type_catalog]  = database.getCatalogName().name;
+            row[user_defined_type_schema]   = type.getSchemaName().name;
+            row[user_defined_type_name]     = type.getName().name;
+            row[data_type]                  = type.getFullNameString();
+            row[declared_data_type]         = type.getFullNameString();
+            row[user_defined_type_category] = "DISTINCT";
+            row[is_instantiable]            = "YES";
+            row[is_final]                   = "YES";
+            row[ordering_form]              = "FULL";
+
+            // common type block
+            if (type.isCharacterType()) {
+                row[character_maximum_length] =
+                    ValuePool.getLong(type.precision);
+                row[character_octet_length] = ValuePool.getLong(type.precision
+                        * 2);
+                row[character_set_catalog] = database.getCatalogName().name;
+                row[character_set_schema] =
+                    ((CharacterType) type).getCharacterSet().getSchemaName()
+                        .name;
+                row[character_set_name] =
+                    ((CharacterType) type).getCharacterSet().getName().name;
+                row[collation_catalog] = database.getCatalogName().name;
+                row[collation_schema] =
+                    ((CharacterType) type).getCollation().getSchemaName().name;
+                row[collation_name] =
+                    ((CharacterType) type).getCollation().getName().name;
+            } else if (type.isNumberType()) {
+                row[numeric_precision] = ValuePool.getLong(
+                    ((NumberType) type).getNumericPrecisionInRadix());
+                row[declared_numeric_precision] = ValuePool.getLong(
+                    ((NumberType) type).getNumericPrecisionInRadix());
+
+                if (type.isExactNumberType()) {
+                    row[numeric_scale] = row[declared_numeric_scale] =
+                        ValuePool.getLong(type.scale);
+                }
+
+                row[numeric_precision_radix] =
+                    ValuePool.getLong(type.getPrecisionRadix());
+            } else if (type.isBooleanType()) {}
+            else if (type.isDateTimeType()) {
+                row[datetime_precision] = ValuePool.getLong(type.scale);
+            } else if (type.isIntervalType()) {
+                row[data_type] = "INTERVAL";
+                row[interval_type] =
+                    ((IntervalType) type).getQualifier(type.typeCode);
+                row[interval_precision] = ValuePool.getLong(type.precision);
+                row[datetime_precision] = ValuePool.getLong(type.scale);
+            } else if (type.isBinaryType()) {
+                row[character_maximum_length] =
+                    ValuePool.getLong(type.precision);
+                row[character_octet_length] =
+                    ValuePool.getLong(type.precision);
+            } else if (type.isBitType()) {
+                row[character_maximum_length] =
+                    ValuePool.getLong(type.precision);
+                row[character_octet_length] =
+                    ValuePool.getLong(type.precision);
+            }
+
+            // end common block
+            row[source_dtd_identifier] = row[user_defined_type_name];
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * The VIEW_COLUMN_USAGE table has one row for each column of a
+     * table that is explicitly or implicitly referenced in the
+     * &lt;query expression&gt; of the view being described. <p>
+     *
+     * <b>Definition:</b> <p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE SYSTEM_VIEW_COLUMN_USAGE (
+     *      VIEW_CATALOG    VARCHAR NULL,
+     *      VIEW_SCHEMA     VARCHAR NULL,
+     *      VIEW_NAME       VARCHAR NOT NULL,
+     *      TABLE_CATALOG   VARCHAR NULL,
+     *      TABLE_SCHEMA    VARCHAR NULL,
+     *      TABLE_NAME      VARCHAR NOT NULL,
+     *      COLUMN_NAME     VARCHAR NOT NULL,
+     *      UNIQUE ( VIEW_CATALOG, VIEW_SCHEMA, VIEW_NAME,
+     *               TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME,
+     *               COLUMN_NAME )
+     * )
+     * </pre>
+     *
+     * <b>Description:</b> <p>
+     *
+     * <ol>
+     * <li> The values of VIEW_CATALOG, VIEW_SCHEMA, and VIEW_NAME are the
+     *      catalog name, unqualified schema name, and qualified identifier,
+     *      respectively, of the view being described. <p>
+     *
+     * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
+     *      COLUMN_NAME are the catalog name, unqualified schema name,
+     *      qualified identifier, and column name, respectively, of a column
+     *      of a table that is explicitly or implicitly referenced in the
+     *      &lt;query expression&gt; of the view being described.
+     * </ol>
+     *
+     * @return Table
+     */
+    Table VIEW_COLUMN_USAGE(Session session) {
+
+        Table t = sysTables[VIEW_COLUMN_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[VIEW_COLUMN_USAGE]);
+
+            addColumn(t, "VIEW_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "VIEW_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "VIEW_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[VIEW_COLUMN_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Calculated column values
+        String viewCatalog;
+        String viewSchema;
+        String viewName;
+
+        // Intermediate holders
+        Iterator tables;
+        View     view;
+        Table    table;
+        Object[] row;
+        Iterator iterator;
+
+        // Column number mappings
+        final int view_catalog  = 0;
+        final int view_schema   = 1;
+        final int view_name     = 2;
+        final int table_catalog = 3;
+        final int table_schema  = 4;
+        final int table_name    = 5;
+        final int column_name   = 6;
+
+        // Initialization
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView()
+                    && session.getGrantee().isFullyAccessibleByRole(
+                        table.getName())) {
+
+                // fall through
+            } else {
+                continue;
+            }
+
+            viewCatalog = database.getCatalogName().name;
+            viewSchema  = table.getSchemaName().name;
+            viewName    = table.getName().name;
+            view        = (View) table;
+
+            OrderedHashSet references = view.getReferences();
+
+            iterator = references.iterator();
+
+            while (iterator.hasNext()) {
+                HsqlName refName = (HsqlName) iterator.next();
+
+                if (refName.type != SchemaObject.COLUMN) {
+                    continue;
+                }
+
+                row                = t.getEmptyRowData();
+                row[view_catalog]  = viewCatalog;
+                row[view_schema]   = viewSchema;
+                row[view_name]     = viewName;
+                row[table_catalog] = viewCatalog;
+                row[table_schema]  = refName.parent.schema.name;
+                row[table_name]    = refName.parent.name;
+                row[column_name]   = refName.name;
+
+                try {
+                    t.insertSys(store, row);
+                } catch (HsqlException e) {}
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The VIEW_ROUTINE_USAGE table has one row for each SQL-invoked
+     * routine identified as the subject routine of either a &lt;routine
+     * invocation&gt;, a &lt;method reference&gt;, a &lt;method invocation&gt;,
+     * or a &lt;static method invocation&gt; contained in a &lt;view
+     * definition&gt;. <p>
+     *
+     * <b>Definition</b><p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE VIEW_ROUTINE_USAGE (
+     *      TABLE_CATALOG       VARCHAR NULL,
+     *      TABLE_SCHEMA        VARCHAR NULL,
+     *      TABLE_NAME          VARCHAR NOT NULL,
+     *      SPECIFIC_CATALOG    VARCHAR NULL,
+     *      SPECIFIC_SCHEMA     VARCHAR NULL,
+     *      SPECIFIC_NAME       VARCHAR NOT NULL,
+     *      UNIQUE( TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME,
+     *              SPECIFIC_CATALOG, SPECIFIC_SCHEMA,
+     *              SPECIFIC_NAME )
+     * )
+     * </pre>
+     *
+     * <b>Description</b><p>
+     *
+     * <ol>
+     * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, and TABLE_NAME are the
+     *      catalog name, unqualified schema name, and qualified identifier,
+     *      respectively, of the viewed table being described. <p>
+     *
+     * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA, and SPECIFIC_NAME are
+     *      the catalog name, unqualified schema name, and qualified identifier,
+     *      respectively, of the specific name of R. <p>
+     * </ol>
+     *
+     * @return Table
+     */
+    Table VIEW_ROUTINE_USAGE(Session session) {
+
+        Table t = sysTables[VIEW_ROUTINE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[VIEW_ROUTINE_USAGE]);
+
+            addColumn(t, "VIEW_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "VIEW_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "VIEW_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[VIEW_ROUTINE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        Iterator tables;
+        Table    table;
+        Object[] row;
+
+        // Column number mappings
+        final int view_catalog     = 0;
+        final int view_schema      = 1;
+        final int view_name        = 2;
+        final int specific_catalog = 3;
+        final int specific_schema  = 4;
+        final int specific_name    = 5;
+
+        // Initialization
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView()
+                    && session.getGrantee().isFullyAccessibleByRole(
+                        table.getName())) {
+
+                // fall through
+            } else {
+                continue;
+            }
+
+            OrderedHashSet set = table.getReferences();
+
+            for (int i = 0; i < set.size(); i++) {
+                HsqlName refName = (HsqlName) set.get(i);
+
+                if (!session.getGrantee().isFullyAccessibleByRole(refName)) {
+                    continue;
+                }
+
+                if (refName.type != SchemaObject.SPECIFIC_ROUTINE) {
+                    continue;
+                }
+
+                row                   = t.getEmptyRowData();
+                row[view_catalog]     = database.getCatalogName().name;
+                row[view_schema]      = table.getSchemaName().name;
+                row[view_name]        = table.getName().name;
+                row[specific_catalog] = database.getCatalogName().name;
+                row[specific_schema]  = refName.schema.name;
+                row[specific_name]    = refName.name;
+
+                try {
+                    t.insertSys(store, row);
+                } catch (HsqlException e) {}
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The VIEW_TABLE_USAGE table has one row for each table identified
+     * by a &lt;table name&gt; simply contained in a &lt;table reference&gt;
+     * that is contained in the &lt;query expression&gt; of a view. <p>
+     *
+     * <b>Definition</b><p>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE SYSTEM_VIEW_TABLE_USAGE (
+     *      VIEW_CATALOG    VARCHAR NULL,
+     *      VIEW_SCHEMA     VARCHAR NULL,
+     *      VIEW_NAME       VARCHAR NULL,
+     *      TABLE_CATALOG   VARCHAR NULL,
+     *      TABLE_SCHEMA    VARCHAR NULL,
+     *      TABLE_NAME      VARCHAR NULL,
+     *      UNIQUE( VIEW_CATALOG, VIEW_SCHEMA, VIEW_NAME,
+     *              TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME )
+     * )
+     * </pre>
+     *
+     * <b>Description:</b><p>
+     *
+     * <ol>
+     * <li> The values of VIEW_CATALOG, VIEW_SCHEMA, and VIEW_NAME are the
+     *      catalog name, unqualified schema name, and qualified identifier,
+     *      respectively, of the view being described. <p>
+     *
+     * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, and TABLE_NAME are the
+     *      catalog name, unqualified schema name, and qualified identifier,
+     *      respectively, of a table identified by a &lt;table name&gt;
+     *      simply contained in a &lt;table reference&gt; that is contained in
+     *      the &lt;query expression&gt; of the view being described.
+     * </ol>
+     *
+     * @return Table
+     */
+    Table VIEW_TABLE_USAGE(Session session) {
+
+        Table t = sysTables[VIEW_TABLE_USAGE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[VIEW_TABLE_USAGE]);
+
+            addColumn(t, "VIEW_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "VIEW_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "VIEW_NAME", SQL_IDENTIFIER);     // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);    // not null
+
+            // false PK, as VIEW_CATALOG, VIEW_SCHEMA, TABLE_CATALOG, and/or
+            // TABLE_SCHEMA may be NULL
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[VIEW_TABLE_USAGE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5
+            }, false);
+
+            return t;
+        }
+
+        // Column number mappings
+        final int view_catalog  = 0;
+        final int view_schema   = 1;
+        final int view_name     = 2;
+        final int table_catalog = 3;
+        final int table_schema  = 4;
+        final int table_name    = 5;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        tables;
+        Table           table;
+        Object[]        row;
+
+        // Initialization
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView()
+                    && session.getGrantee().isFullyAccessibleByRole(
+                        table.getName())) {
+
+                // fall through
+            } else {
+                continue;
+            }
+
+            OrderedHashSet references = table.getReferences();
+
+            for (int i = 0; i < references.size(); i++) {
+                HsqlName refName = (HsqlName) references.get(i);
+
+                if (!session.getGrantee().isFullyAccessibleByRole(refName)) {
+                    continue;
+                }
+
+                if (refName.type != SchemaObject.TABLE) {
+                    continue;
+                }
+
+                row                = t.getEmptyRowData();
+                row[view_catalog]  = database.getCatalogName().name;
+                row[view_schema]   = table.getSchemaName().name;
+                row[view_name]     = table.getName().name;
+                row[table_catalog] = database.getCatalogName().name;
+                row[table_schema]  = refName.schema.name;
+                row[table_name]    = refName.name;
+
+                try {
+                    t.insertSys(store, row);
+                } catch (HsqlException e) {}
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The VIEWS view contains one row for each VIEW definition. <p>
+     *
+     * Each row is a description of the query expression that defines its view,
+     * with the following columns:
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_CATALOG    VARCHAR     name of view's defining catalog.
+     * TABLE_SCHEMA     VARCHAR     name of view's defining schema.
+     * TABLE_NAME       VARCHAR     the simple name of the view.
+     * VIEW_DEFINITION  VARCHAR     the character representation of the
+     *                              &lt;query expression&gt; contained in the
+     *                              corresponding &lt;view descriptor&gt;.
+     * CHECK_OPTION     VARCHAR     {"CASCADED" | "LOCAL" | "NONE"}
+     * IS_UPDATABLE     VARCHAR     {"YES" | "NO"}
+     * INSERTABLE_INTO VARCHAR      {"YES" | "NO"}
+     * IS_TRIGGER_UPDATABLE        VARCHAR  {"YES" | "NO"}
+     * IS_TRIGGER_DELETEABLE       VARCHAR  {"YES" | "NO"}
+     * IS_TRIGGER_INSERTABLE_INTO  VARCHAR  {"YES" | "NO"}
+     * </pre> <p>
+     *
+     * @return a tabular description of the text source of all
+     *        <code>View</code> objects accessible to
+     *        the user.
+     */
+    Table VIEWS(Session session) {
+
+        Table t = sysTables[VIEWS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[VIEWS]);
+
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);               // not null
+            addColumn(t, "VIEW_DEFINITION", CHARACTER_DATA);          // not null
+            addColumn(t, "CHECK_OPTION", CHARACTER_DATA);             // not null
+            addColumn(t, "IS_UPDATABLE", YES_OR_NO);                  // not null
+            addColumn(t, "INSERTABLE_INTO", YES_OR_NO);               // not null
+            addColumn(t, "IS_TRIGGER_UPDATABLE", YES_OR_NO);          // not null
+            addColumn(t, "IS_TRIGGER_DELETABLE", YES_OR_NO);          // not null
+            addColumn(t, "IS_TRIGGER_INSERTABLE_INTO", YES_OR_NO);    // not null
+
+            // order TABLE_NAME
+            // added for unique: TABLE_SCHEMA, TABLE_CATALOG
+            // false PK, as TABLE_SCHEMA and/or TABLE_CATALOG may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[VIEWS].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                1, 2, 0
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        tables;
+        Table           table;
+        Object[]        row;
+        final int       table_catalog              = 0;
+        final int       table_schema               = 1;
+        final int       table_name                 = 2;
+        final int       view_definition            = 3;
+        final int       check_option               = 4;
+        final int       is_updatable               = 5;
+        final int       insertable_into            = 6;
+        final int       is_trigger_updatable       = 7;
+        final int       is_trigger_deletable       = 8;
+        final int       is_trigger_insertable_into = 9;
+
+        tables = allTables();
+
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if ((table.getSchemaName() != SqlInvariants
+                    .INFORMATION_SCHEMA_HSQLNAME && !table
+                        .isView()) || !isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            row                = t.getEmptyRowData();
+            row[table_catalog] = database.getCatalogName().name;
+            row[table_schema]  = table.getSchemaName().name;
+            row[table_name]    = table.getName().name;
+
+            String check = Tokens.T_NONE;
+
+            if (table instanceof View) {
+                if (session.getGrantee().isFullyAccessibleByRole(
+                        table.getName())) {
+                    row[view_definition] = ((View) table).getStatement();
+                }
+
+                switch (((View) table).getCheckOption()) {
+
+                    case SchemaObject.ViewCheckModes.CHECK_NONE :
+                        break;
+
+                    case SchemaObject.ViewCheckModes.CHECK_LOCAL :
+                        check = Tokens.T_LOCAL;
+                        break;
+
+                    case SchemaObject.ViewCheckModes.CHECK_CASCADE :
+                        check = Tokens.T_CASCADED;
+                        break;
+                }
+            }
+
+            row[check_option]         = check;
+            row[is_updatable]         = table.isUpdatable() ? Tokens.T_YES
+                                                            : Tokens.T_NO;
+            row[insertable_into]      = table.isInsertable() ? Tokens.T_YES
+                                                             : Tokens.T_NO;
+            row[is_trigger_updatable] = null;    // only applies to INSTEAD OF triggers
+            row[is_trigger_deletable]       = null;
+            row[is_trigger_insertable_into] = null;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+//------------------------------------------------------------------------------
+// SQL SCHEMATA BASE TABLES
+
+    /**
+     * ROLE_AUTHORIZATION_DESCRIPTORS<p>
+     *
+     * <b>Function</b><p>
+     *
+     * Contains a representation of the role authorization descriptors.<p>
+     * <b>Definition</b>
+     *
+     * <pre class="SqlCodeExample">
+     * CREATE TABLE ROLE_AUTHORIZATION_DESCRIPTORS (
+     *      ROLE_NAME INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *      GRANTEE INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *      GRANTOR INFORMATION_SCHEMA.SQL_IDENTIFIER,
+     *      IS_GRANTABLE INFORMATION_SCHEMA.CHARACTER_DATA
+     *          CONSTRAINT ROLE_AUTHORIZATION_DESCRIPTORS_IS_GRANTABLE_CHECK
+     *              CHECK ( IS_GRANTABLE IN
+     *                  ( 'YES', 'NO' ) ),
+     *          CONSTRAINT ROLE_AUTHORIZATION_DESCRIPTORS_PRIMARY_KEY
+     *              PRIMARY KEY ( ROLE_NAME, GRANTEE ),
+     *          CONSTRAINT ROLE_AUTHORIZATION_DESCRIPTORS_CHECK_ROLE_NAME
+     *              CHECK ( ROLE_NAME IN
+     *                  ( SELECT AUTHORIZATION_NAME
+     *                      FROM AUTHORIZATIONS
+     *                     WHERE AUTHORIZATION_TYPE = 'ROLE' ) ),
+     *          CONSTRAINT ROLE_AUTHORIZATION_DESCRIPTORS_FOREIGN_KEY_AUTHORIZATIONS_GRANTOR
+     *              FOREIGN KEY ( GRANTOR )
+     *                  REFERENCES AUTHORIZATIONS,
+     *          CONSTRAINT ROLE_AUTHORIZATION_DESCRIPTORS_FOREIGN_KEY_AUTHORIZATIONS_GRANTEE
+     *              FOREIGN KEY ( GRANTEE )
+     *                  REFERENCES AUTHORIZATIONS
+     *      )
+     * </pre>
+     *
+     * <b>Description</b><p>
+     *
+     * <ol>
+     *      <li>The value of ROLE_NAME is the &lt;role name&gt; of some
+     *          &lt;role granted&gt; by the &lt;grant role statement&gt; or
+     *          the &lt;role name&gt; of a &lt;role definition&gt;. <p>
+     *
+     *      <li>The value of GRANTEE is an &lt;authorization identifier&gt;,
+     *          possibly PUBLIC, or &lt;role name&gt; specified as a
+     *          &lt;grantee&gt; contained in a &lt;grant role statement&gt;,
+     *          or the &lt;authorization identifier&gt; of the current
+     *          SQLsession when the &lt;role definition&gt; is executed. <p>
+     *
+     *      <li>The value of GRANTOR is the &lt;authorization identifier&gt;
+     *          of the user or role who granted the role identified by
+     *          ROLE_NAME to the user or role identified by the value of
+     *          GRANTEE. <p>
+     *
+     *      <li>The values of IS_GRANTABLE have the following meanings:<p>
+     *
+     *      <table border cellpadding="3">
+     *          <tr>
+     *              <td nowrap>YES</td>
+     *              <td nowrap>The described role is grantable.</td>
+     *          <tr>
+     *          <tr>
+     *              <td nowrap>NO</td>
+     *              <td nowrap>The described role is not grantable.</td>
+     *          <tr>
+     *      </table> <p>
+     * </ol>
+     *
+     * @return Table
+     */
+    Table ROLE_AUTHORIZATION_DESCRIPTORS(Session session) {
+
+        Table t = sysTables[ROLE_AUTHORIZATION_DESCRIPTORS];
+
+        if (t == null) {
+            t = createBlankTable(
+                sysTableHsqlNames[ROLE_AUTHORIZATION_DESCRIPTORS]);
+
+            addColumn(t, "ROLE_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);      // not null
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);      // not null
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);      // not null
+
+            // true PK
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[ROLE_AUTHORIZATION_DESCRIPTORS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1
+            }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        String   grantorName = SqlInvariants.SYSTEM_AUTHORIZATION_NAME;
+        Iterator grantees;
+        Grantee  granteeObject;
+        String   granteeName;
+        Iterator roles;
+        String   roleName;
+        String   isGrantable;
+        Object[] row;
+
+        // Column number mappings
+        final int role_name    = 0;
+        final int grantee      = 1;
+        final int grantor      = 2;
+        final int is_grantable = 3;
+
+        // Initialization
+        grantees = session.getGrantee().visibleGrantees().iterator();
+
+        //
+        while (grantees.hasNext()) {
+            granteeObject = (Grantee) grantees.next();
+            granteeName   = granteeObject.getNameString();
+            roles         = granteeObject.getDirectRoles().iterator();
+            isGrantable   = granteeObject.isAdmin() ? Tokens.T_YES
+                                                    : Tokens.T_NO;;
+
+            while (roles.hasNext()) {
+                Grantee role = (Grantee) roles.next();
+
+                row               = t.getEmptyRowData();
+                row[role_name]    = role.getNameString();
+                row[grantee]      = granteeName;
+                row[grantor]      = grantorName;
+                row[is_grantable] = isGrantable;
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+}
diff --git a/src/org/hsqldb/dbinfo/DatabaseInformationMain.java b/src/org/hsqldb/dbinfo/DatabaseInformationMain.java
new file mode 100644
index 0000000..7c11afa
--- /dev/null
+++ b/src/org/hsqldb/dbinfo/DatabaseInformationMain.java
@@ -0,0 +1,3609 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.dbinfo;
+
+import org.hsqldb.ColumnSchema;
+import org.hsqldb.Constraint;
+import org.hsqldb.Database;
+import org.hsqldb.HsqlException;
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.NumberSequence;
+import org.hsqldb.Routine;
+import org.hsqldb.RoutineSchema;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Session;
+import org.hsqldb.SqlInvariants;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.WrapperIterator;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.rights.GrantConstants;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.rights.GranteeManager;
+import org.hsqldb.rights.Right;
+import org.hsqldb.rights.User;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/* $Id: DatabaseInformationMain.java 3570 2010-04-17 17:17:15Z fredt $ */
+
+// fredt@users - 1.7.2 - structural modifications to allow inheritance
+// boucherb@users - 1.7.2 - 20020225
+// - factored out all reusable code into DIXXX support classes
+// - completed Fred's work on allowing inheritance
+// boucherb@users - 1.7.2 - 20020304 - bug fixes, refinements, better java docs
+// fredt@users - 1.8.0 - updated to report latest enhancements and changes
+// boucherb@users 20051207 - patch 1.8.x initial JDBC 4.0 support work
+// Revision 1.9  2006/07/12 11:36:59  boucherb
+// - JDBC 4.0, Mustang b87: support for new DatabaseMetaData.getColumns() IS_AUTOINCREMENT result column
+// - minor javadoc and code comment updates
+
+/**
+ * Provides definitions for a few of the SQL Standard Schemata views that are
+ * supported by HSQLDB.<p>
+ *
+ * Provides definitions for some of HSQLDB's additional system view.
+ *
+ * The views supported in this class are exclusively those that are needed
+ * to build the ResultSet objects that are returned by JDBC DatabaseMetaData
+ * calls.<p>
+ *
+ * The definitions for the rest of SQL standard and HSQLDB specific system views
+ * are provided by DatabaseInformationFull, which extends this class. <p>
+ *
+ * Produces a collection of views that form the system data dictionary. <p>
+ *
+ * Implementations use a group of arrays of equal size to store various
+ * attributes or cached instances of system tables.<p>
+ *
+ * Two fixed static lists of reserved table names are kept in String[] and
+ * HsqlName[] forms. These are shared by all implementations of
+ * DatabaseInformtion.<p>
+ *
+ * Each implementation keeps a lookup set of names for those tables whose
+ * contents are never cached (nonCachedTablesSet). <p>
+ *
+ * An instance of this class uses three lists named sysTablexxxx for caching
+ * system tables.<p>
+ *
+ * sysTableSessionDependent indicates which tables contain data that is
+ * dependent on the user rights of the User associatiod with the Session.<p>
+ *
+ * sysTableSessions contains the Session with whose rights each cached table
+ * was built.<p>
+ *
+ * sysTables contains the cached tables.<p>
+ *
+ * At the time of instantiation, which is part of the Database.open() method
+ * invocation, an empty table is created and placed in sysTables with calls to
+ * generateTable(int) for each name in sysTableNames. Some of these
+ * table entries may be null if an implementation does not produce them.<p>
+ *
+ * Calls to getSystemTable(String, Session) return a cached table if various
+ * caching rules are met (see below), or it will delete all rows of the table
+ * and rebuild the contents via generateTable(int).<p>
+ *
+ * generateTable(int) calls the appropriate single method for each table.
+ * These methods either build and return an empty table (if sysTables
+ * contains null for the table slot) or populate the table with up-to-date
+ * rows. <p>
+ *
+ * Rules for caching are applied as follows: <p>
+ *
+ * If a table has non-cached contents, its contents are cleared and
+ * rebuilt. <p>
+ *
+ * For the rest of the tables, if the sysTableSessions slot is null or if the
+ * Session parameter is not the same as the Session object
+ * in that slot, the table contents are cleared and rebuilt. <p>
+ *
+ * (fredt@users) <p>
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.7.2
+ */
+class DatabaseInformationMain extends DatabaseInformation {
+
+    static Type CARDINAL_NUMBER = SqlInvariants.CARDINAL_NUMBER;
+    static Type YES_OR_NO       = SqlInvariants.YES_OR_NO;
+    static Type CHARACTER_DATA  = SqlInvariants.CHARACTER_DATA;
+    static Type SQL_IDENTIFIER  = SqlInvariants.SQL_IDENTIFIER;
+    static Type TIME_STAMP      = SqlInvariants.TIME_STAMP;
+
+    /** The HsqlNames of the system tables. */
+    protected static final HsqlName[] sysTableHsqlNames;
+
+    /** true if the contents of a cached system table depends on the session */
+    protected static final boolean[] sysTableSessionDependent =
+        new boolean[sysTableNames.length];
+
+    /** Set: { names of system tables that are not to be cached } */
+    protected static final HashSet nonCachedTablesSet;
+
+    /** The table types HSQLDB supports. */
+    protected static final String[] tableTypes = new String[] {
+        "GLOBAL TEMPORARY", "SYSTEM TABLE", "TABLE", "VIEW"
+    };
+
+    /** Provides naming support. */
+    static {
+        synchronized (DatabaseInformationMain.class) {
+            nonCachedTablesSet = new HashSet();
+            sysTableHsqlNames  = new HsqlName[sysTableNames.length];
+
+            for (int i = 0; i < sysTableNames.length; i++) {
+                sysTableHsqlNames[i] =
+                    HsqlNameManager.newInfoSchemaTableName(sysTableNames[i]);
+                sysTableHsqlNames[i].schema =
+                    SqlInvariants.INFORMATION_SCHEMA_HSQLNAME;
+                sysTableSessionDependent[i] = true;
+            }
+
+            // build the set of non-cached tables
+            nonCachedTablesSet.add("SYSTEM_CACHEINFO");
+            nonCachedTablesSet.add("SYSTEM_SESSIONINFO");
+            nonCachedTablesSet.add("SYSTEM_SESSIONS");
+            nonCachedTablesSet.add("SYSTEM_PROPERTIES");
+            nonCachedTablesSet.add("SYSTEM_SEQUENCES");
+        }
+    }
+
+    /** cache of system tables */
+    protected final Table[] sysTables = new Table[sysTableNames.length];
+
+    /**
+     * Constructs a table producer which provides system tables
+     * for the specified <code>Database</code> object. <p>
+     *
+     * <b>Note:</b> before 1.7.2 Alpha N, it was important to observe that
+     * by specifying an instance of this class or one of its descendents to
+     * handle system table production, the new set of builtin permissions
+     * and aliases would overwrite those of an existing database, meaning that
+     * metadata reporting might have been rendered less secure if the same
+     * database were then opened again using a lower numbered system table
+     * producer instance (i.e. one in a 1.7.1 or earlier distribution).
+     * As of 1.7.2 Alpha N, system-generated permissions and aliases are no
+     * longer recorded in the checkpoint script, obseleting this issue.
+     * Checkpointing of system-generated grants and aliases was removed
+     * because their existence is very close to a core requirment for correct
+     * operation and they are reintroduced to the system at each startup.
+     * In a future release, it may even be an exception condition to attempt
+     * to remove or alter system-generated grants and aliases,
+     * respectvely. <p>
+     *
+     * @param db the <code>Database</code> object for which this object
+     *      produces system tables
+     */
+    DatabaseInformationMain(Database db) {
+
+        super(db);
+
+        Session session = db.sessionManager.getSysSession();
+
+        init(session);
+    }
+
+    protected final void addColumn(Table t, String name, Type type) {
+
+        HsqlName     cn;
+        ColumnSchema c;
+
+        cn = database.nameManager.newInfoSchemaColumnName(name, t.getName());
+        c  = new ColumnSchema(cn, type, true, false, null);
+
+        t.addColumn(c);
+    }
+
+    /**
+     * Retrieves an enumeration over all of the tables in this database.
+     * This means all user tables, views, system tables, system views,
+     * including temporary and text tables. <p>
+     *
+     * @return an enumeration over all of the tables in this database
+     */
+    protected final Iterator allTables() {
+
+        return new WrapperIterator(
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE),
+            new WrapperIterator(sysTables, true));
+    }
+
+    /**
+     * Clears the contents of cached system tables and resets user slots
+     * to null. <p>
+     *
+     */
+    protected final void cacheClear(Session session) {
+
+        int i = sysTables.length;
+
+        while (i-- > 0) {
+            Table t = sysTables[i];
+
+            if (t != null) {
+                t.clearAllData(session);
+            }
+        }
+    }
+
+    /**
+     * Retrieves the system table corresponding to the specified
+     * tableIndex value. <p>
+     *
+     * @param tableIndex int value identifying the system table to generate
+     * @return the system table corresponding to the specified tableIndex value
+     */
+    protected Table generateTable(Session session, int tableIndex) {
+
+//        Please note that this class produces non-null tables for
+//        just those absolutely essential to the JDBC 1 spec and the
+//        HSQLDB core.  Also, all table producing methods except
+//        SYSTEM_PROCEDURES() and SYSTEM_PROCEDURECOLUMNS() are declared final;
+//        this class produces only an empty table for each, as per previous
+//        DatabaseInformation implementations, whereas
+//        DatabaseInformationFull produces comprehensive content for
+//        them).
+//
+//        This break down of inheritance allows DatabaseInformation and
+//        DatabaseInformationMain (this class) to be made as small as possible
+//        while still meeting their mandates:
+//
+//        1.) DatabaseInformation prevents use of reserved system table names
+//            for user tables and views, meaning that even under highly
+//            constrained use cases where the notion of DatabaseMetaData can
+//            be discarded (i.e. the engine operates in a distribution where
+//            DatabaseInforationMain/Full and JDBCDatabaseMetaData have been
+//            dropped from the JAR), it is still impossible to produce a
+//            database which will be incompatible in terms of system table <=>
+//            user table name clashes, if/when imported into a more
+//            capable operating environment.
+//
+//        2.) DatabaseInformationMain builds on DatabaseInformation, providing
+//            at minimum what is needed for comprehensive operation under
+//            JDK 1.1/JDBC 1 and provides, at minimum, what was provided under
+//            earlier implementations.
+//
+//        3.) descendents of DatabaseInformationMain (such as the current
+//            DatabaseInformationFull) need not (and indeed: now cannot)
+//            override most of the DatabaseInformationMain table producing
+//            methods, as for the most part they are expected to be already
+//            fully comprehensive, security aware and accessible to all users.
+        switch (tableIndex) {
+
+            case SYSTEM_BESTROWIDENTIFIER :
+                return SYSTEM_BESTROWIDENTIFIER(session);
+
+            case SYSTEM_COLUMNS :
+                return SYSTEM_COLUMNS(session);
+
+            case SYSTEM_CONNECTION_PROPERTIES :
+                return SYSTEM_CONNECTION_PROPERTIES(session);
+
+            case SYSTEM_CROSSREFERENCE :
+                return SYSTEM_CROSSREFERENCE(session);
+
+            case SYSTEM_INDEXINFO :
+                return SYSTEM_INDEXINFO(session);
+
+            case SYSTEM_PRIMARYKEYS :
+                return SYSTEM_PRIMARYKEYS(session);
+
+            case SYSTEM_PROCEDURECOLUMNS :
+                return SYSTEM_PROCEDURECOLUMNS(session);
+
+            case SYSTEM_PROCEDURES :
+                return SYSTEM_PROCEDURES(session);
+
+            case SYSTEM_SCHEMAS :
+                return SYSTEM_SCHEMAS(session);
+
+            case SYSTEM_SEQUENCES :
+                return SYSTEM_SEQUENCES(session);
+
+            case SYSTEM_TABLES :
+                return SYSTEM_TABLES(session);
+
+            case SYSTEM_TABLETYPES :
+                return SYSTEM_TABLETYPES(session);
+
+            case SYSTEM_TYPEINFO :
+                return SYSTEM_TYPEINFO(session);
+
+            case SYSTEM_USERS :
+                return SYSTEM_USERS(session);
+
+            case SYSTEM_UDTS :
+                return SYSTEM_UDTS(session);
+
+            case SYSTEM_VERSIONCOLUMNS :
+                return SYSTEM_VERSIONCOLUMNS(session);
+
+            case COLUMN_PRIVILEGES :
+                return COLUMN_PRIVILEGES(session);
+
+            case SEQUENCES :
+                return SEQUENCES(session);
+
+            case TABLE_PRIVILEGES :
+                return TABLE_PRIVILEGES(session);
+
+            case INFORMATION_SCHEMA_CATALOG_NAME :
+                return INFORMATION_SCHEMA_CATALOG_NAME(session);
+
+            default :
+                return null;
+        }
+    }
+
+    /**
+     * One time initialisation of instance attributes
+     * at construction time. <p>
+     *
+     */
+    protected final void init(Session session) {
+
+        // flag the Session-dependent cached tables
+        Table t;
+
+        for (int i = 0; i < sysTables.length; i++) {
+            t = sysTables[i] = generateTable(session, i);
+
+            if (t != null) {
+                t.setDataReadOnly(true);
+            }
+        }
+
+        GranteeManager gm    = database.getGranteeManager();
+        Right          right = new Right();
+
+        right.set(GrantConstants.SELECT, null);
+
+        for (int i = 0; i < sysTableHsqlNames.length; i++) {
+            if (sysTables[i] != null) {
+                gm.grantSystemToPublic(sysTables[i], right);
+            }
+        }
+
+        right = Right.fullRights;
+
+        gm.grantSystemToPublic(SqlInvariants.YES_OR_NO, right);
+        gm.grantSystemToPublic(SqlInvariants.TIME_STAMP, right);
+        gm.grantSystemToPublic(SqlInvariants.CARDINAL_NUMBER, right);
+        gm.grantSystemToPublic(SqlInvariants.CHARACTER_DATA, right);
+        gm.grantSystemToPublic(SqlInvariants.SQL_CHARACTER, right);
+        gm.grantSystemToPublic(SqlInvariants.SQL_IDENTIFIER_CHARSET, right);
+        gm.grantSystemToPublic(SqlInvariants.SQL_IDENTIFIER, right);
+        gm.grantSystemToPublic(SqlInvariants.SQL_TEXT, right);
+    }
+
+    /**
+     * Retrieves whether any form of SQL access is allowed against the
+     * the specified table w.r.t the database access rights
+     * assigned to current Session object's User. <p>
+     *
+     * @return true if the table is accessible, else false
+     * @param table the table for which to check accessibility
+     */
+    protected final boolean isAccessibleTable(Session session, Table table) {
+        return session.getGrantee().isAccessible(table);
+    }
+
+    /**
+     * Creates a new primoidal system table with the specified name. <p>
+     *
+     * @return a new system table
+     * @param name of the table
+     */
+    protected final Table createBlankTable(HsqlName name) {
+
+        Table table = new Table(database, name, TableBase.SYSTEM_TABLE);
+
+        return table;
+    }
+
+    /**
+     * Retrieves the system <code>Table</code> object corresponding to
+     * the given <code>name</code> and <code>session</code> arguments. <p>
+     *
+     * @param session the Session object requesting the table
+     * @param name a String identifying the desired table
+     *      database access error occurs
+     * @return a system table corresponding to the <code>name</code> and
+     *      <code>session</code> arguments
+     */
+    public synchronized final Table getSystemTable(Session session,
+            String name) {
+
+        Table t;
+        int   tableIndex;
+
+        if (!isSystemTable(name)) {
+            return null;
+        }
+
+        tableIndex = getSysTableID(name);
+        t          = sysTables[tableIndex];
+
+        // fredt - any system table that is not supported will be null here
+        if (t == null) {
+            return t;
+        }
+
+        // At the time of opening the database, no content is needed.
+        // However, table structure is required at this
+        // point to allow processing logged View defn's against system
+        // tables
+        if (!withContent) {
+            return t;
+        }
+
+        if (!session.isAdmin() ) {
+            session.getUser();
+        }
+        long dbscts = database.schemaManager.getSchemaChangeTimestamp();
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        if (store.getTimestamp() == dbscts
+                && !nonCachedTablesSet.contains(name)) {
+            return t;
+        }
+
+        // fredt - clear the contents of table and generate
+        t.clearAllData(session);
+        store.setTimestamp(dbscts);
+
+        t = generateTable(session, tableIndex);
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the optimal
+     * set of visible columns that uniquely identifies a row
+     * for each accessible table defined within this database. <p>
+     *
+     * Each row describes a single column of the best row indentifier column
+     * set for a particular table.  Each row has the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * SCOPE          SMALLINT  scope of applicability
+     * COLUMN_NAME    VARCHAR   simple name of the column
+     * DATA_TYPE      SMALLINT  SQL data type from Types
+     * TYPE_NAME      VARCHAR   canonical type name
+     * COLUMN_SIZE    INTEGER   precision
+     * BUFFER_LENGTH  INTEGER   transfer size in bytes, if definitely known
+     * DECIMAL_DIGITS SMALLINT  scale  - fixed # of decimal digits
+     * PSEUDO_COLUMN  SMALLINT  is this a pseudo column like an Oracle ROWID?
+     * TABLE_CAT      VARCHAR   table catalog
+     * TABLE_SCHEM    VARCHAR   simple name of table schema
+     * TABLE_NAME     VARCHAR   simple table name
+     * NULLABLE       SMALLINT  is column nullable?
+     * IN_KEY         BOOLEAN   column belongs to a primary or alternate key?
+     * </pre> <p>
+     *
+     * <b>Notes:</b><p>
+     *
+     * <code>JDBCDatabaseMetaData.getBestRowIdentifier</code> uses its
+     * nullable parameter to filter the rows of this table in the following
+     * manner: <p>
+     *
+     * If the nullable parameter is <code>false</code>, then rows are reported
+     * only if, in addition to satisfying the other specified filter values,
+     * the IN_KEY column value is TRUE. If the nullable parameter is
+     * <code>true</code>, then the IN_KEY column value is ignored. <p>
+     *
+     * There is not yet infrastructure in place to make some of the ranking
+     * descisions described below, and it is anticipated that mechanisms
+     * upon which cost descisions could be based will change significantly over
+     * the next few releases.  Hence, in the interest of simplicity and of not
+     * making overly complex dependency on features that will almost certainly
+     * change significantly in the near future, the current implementation,
+     * while perfectly adequate for all but the most demanding or exacting
+     * purposes, is actually sub-optimal in the strictest sense. <p>
+     *
+     * A description of the current implementation follows: <p>
+     *
+     * <b>DEFINTIONS:</b>  <p>
+     *
+     * <b>Alternate key</b> <p>
+     *
+     *  <UL>
+     *   <LI> An attribute of a table that, by virtue of its having a set of
+     *        columns that are both the full set of columns participating in a
+     *        unique constraint or index and are all not null, yeilds the same
+     *        selectability characteristic that would obtained by declaring a
+     *        primary key on those same columns.
+     *  </UL> <p>
+     *
+     * <b>Column set performance ranking</b> <p>
+     *
+     *  <UL>
+     *  <LI> The ranking of the expected average performance w.r.t a subset of
+     *       a table's columns used to select and/or compare rows, as taken in
+     *       relation to all other distinct candidate subsets under
+     *       consideration. This can be estimated by comparing each cadidate
+     *       subset in terms of total column count, relative peformance of
+     *       comparisons amongst the domains of the columns and differences
+     *       in other costs involved in the execution plans generated using
+     *       each subset under consideration for row selection/comparison.
+     *  </UL> <p>
+     *
+     *
+     * <b>Rules:</b> <p>
+     *
+     * Given the above definitions, the rules currently in effect for reporting
+     * best row identifier are as follows, in order of precedence: <p>
+     *
+     * <OL>
+     * <LI> if the table under consideration has a primary key contraint, then
+     *      the columns of the primary key are reported, with no consideration
+     *      given to the column set performance ranking over the set of
+     *      candidate keys. Each row has its IN_KEY column set to TRUE.
+     *
+     * <LI> if 1.) does not hold, then if there exits one or more alternate
+     *      keys, then the columns of the alternate key with the lowest column
+     *      count are reported, with no consideration given to the column set
+     *      performance ranking over the set of candidate keys. If there
+     *      exists a tie for lowest column count, then the columns of the
+     *      first such key encountered are reported.
+     *      Each row has its IN_KEY column set to TRUE.
+     *
+     * <LI> if both 1.) and 2.) do not hold, then, if possible, a unique
+     *      contraint/index is selected from the set of unique
+     *      contraints/indices containing at least one column having
+     *      a not null constraint, with no consideration given to the
+     *      column set performance ranking over the set of all such
+     *      candidate column sets. If there exists a tie for lowest non-zero
+     *      count of columns having a not null constraint, then the columns
+     *      of the first such encountered candidate set are reported. Each
+     *      row has its IN_KEY column set to FALSE. <p>
+     *
+     * <LI> Finally, if the set of candidate column sets in 3.) is the empty,
+     *      then no column set is reported for the table under consideration.
+     * </OL> <p>
+     *
+     * The scope reported for a best row identifier column set is determined
+     * thus: <p>
+     *
+     * <OL>
+     * <LI> if the database containing the table under consideration is in
+     *      read-only mode or the table under consideration is GLOBAL TEMPORARY
+     *      (a TEMP or TEMP TEXT table, in HSQLDB parlance), then the scope
+     *      is reported as
+     *      <code>java.sql.DatabaseMetaData.bestRowSession</code>.
+     *
+     * <LI> if 1.) does not hold, then the scope is reported as
+     *      <code>java.sql.DatabaseMetaData.bestRowTemporary</code>.
+     * </OL> <p>
+     *
+     * @return a <code>Table</code> object describing the optimal
+     * set of visible columns that uniquely identifies a row
+     * for each accessible table defined within this database
+     */
+    final Table SYSTEM_BESTROWIDENTIFIER(Session session) {
+
+        Table t = sysTables[SYSTEM_BESTROWIDENTIFIER];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_BESTROWIDENTIFIER]);
+
+            addColumn(t, "SCOPE", Type.SQL_SMALLINT);            // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);         // not null
+            addColumn(t, "DATA_TYPE", Type.SQL_SMALLINT);        // not null
+            addColumn(t, "TYPE_NAME", SQL_IDENTIFIER);           // not null
+            addColumn(t, "COLUMN_SIZE", Type.SQL_INTEGER);
+            addColumn(t, "BUFFER_LENGTH", Type.SQL_INTEGER);
+            addColumn(t, "DECIMAL_DIGITS", Type.SQL_SMALLINT);
+            addColumn(t, "PSEUDO_COLUMN", Type.SQL_SMALLINT);    // not null
+            addColumn(t, "TABLE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);          // not null
+            addColumn(t, "NULLABLE", Type.SQL_SMALLINT);         // not null
+            addColumn(t, "IN_KEY", Type.SQL_BOOLEAN);            // not null
+
+            // order: SCOPE
+            // for unique:  TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME
+            // false PK, as TABLE_CAT and/or TABLE_SCHEM may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_BESTROWIDENTIFIER].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 8, 9, 10, 1
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        Integer scope;           // { temp, transaction, session }
+        Integer pseudo;
+
+        //-------------------------------------------
+        // required for restriction of results via
+        // DatabaseMetaData filter parameters, but
+        // not actually required to be included in
+        // DatabaseMetaData.getBestRowIdentifier()
+        // result set
+        //-------------------------------------------
+        String  tableCatalog;    // table calalog
+        String  tableSchema;     // table schema
+        String  tableName;       // table name
+        Boolean inKey;           // column participates in PK or AK?
+
+        //-------------------------------------------
+
+        /**
+         * @todo -  Maybe include: - backing index (constraint) name?
+         *       - column sequence in index (constraint)?
+         */
+        //-------------------------------------------
+        // Intermediate holders
+        Iterator       tables;
+        Table          table;
+        DITableInfo    ti;
+        int[]          cols;
+        Object[]       row;
+        HsqlProperties p;
+
+        // Column number mappings
+        final int iscope          = 0;
+        final int icolumn_name    = 1;
+        final int idata_type      = 2;
+        final int itype_name      = 3;
+        final int icolumn_size    = 4;
+        final int ibuffer_length  = 5;
+        final int idecimal_digits = 6;
+        final int ipseudo_column  = 7;
+        final int itable_cat      = 8;
+        final int itable_schem    = 9;
+        final int itable_name     = 10;
+        final int inullable       = 11;
+        final int iinKey          = 12;
+
+        // Initialization
+        ti = new DITableInfo();
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        boolean translateDTI = database.getProperties().isPropertyTrue(
+            HsqlDatabaseProperties.jdbc_translate_dti_types);
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            /** @todo - requires access to the actual columns */
+            if (table.isView() || !isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            cols = table.getBestRowIdentifiers();
+
+            if (cols == null) {
+                continue;
+            }
+
+            ti.setTable(table);
+
+            inKey = ValuePool.getBoolean(table.isBestRowIdentifiersStrict());
+            tableCatalog = table.getCatalogName().name;
+            tableSchema  = table.getSchemaName().name;
+            tableName    = table.getName().name;
+
+            Type[] types = table.getColumnTypes();
+
+            scope  = ti.getBRIScope();
+            pseudo = ti.getBRIPseudo();
+
+            for (int i = 0; i < cols.length; i++) {
+                ColumnSchema column = table.getColumn(i);
+                Type         type   = types[i];
+
+                if (translateDTI) {
+                    if (type.isIntervalType()) {
+                        type = CharacterType.getCharacterType(
+                            Types.SQL_VARCHAR, type.displaySize());
+                    } else if (type.isDateTimeTypeWithZone()) {
+                        type = ((DateTimeType) type)
+                            .getDateTimeTypeWithoutZone();
+                    }
+                }
+
+                row                  = t.getEmptyRowData();
+                row[iscope]          = scope;
+                row[icolumn_name]    = column.getName().name;
+                row[idata_type] = ValuePool.getInt(type.getJDBCTypeCode());
+                row[itype_name]      = type.getNameString();
+                row[icolumn_size] = ValuePool.getInt(type.getJDBCPrecision());
+                row[ibuffer_length]  = null;
+                row[idecimal_digits] = type.getJDBCScale();
+                row[ipseudo_column]  = pseudo;
+                row[itable_cat]      = tableCatalog;
+                row[itable_schem]    = tableSchema;
+                row[itable_name]     = tableName;
+                row[inullable] = ValuePool.getInt(column.getNullability());
+                row[iinKey]          = inKey;
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the
+     * visible columns of all accessible tables defined
+     * within this database.<p>
+     *
+     * Each row is a column description with the following columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_CAT         VARCHAR   table catalog
+     * TABLE_SCHEM       VARCHAR   table schema
+     * TABLE_NAME        VARCHAR   table name
+     * COLUMN_NAME       VARCHAR   column name
+     * DATA_TYPE         SMALLINT  SQL type from DITypes
+     * TYPE_NAME         VARCHAR   canonical type name
+     * COLUMN_SIZE       INTEGER   column size (length/precision)
+     * BUFFER_LENGTH     INTEGER   transfer size in bytes, if definitely known
+     * DECIMAL_DIGITS    INTEGER   # of fractional digits (scale)
+     * NUM_PREC_RADIX    INTEGER   Radix
+     * NULLABLE          INTEGER   is NULL allowed? (from DatabaseMetaData)
+     * REMARKS           VARCHAR   comment describing column
+     * COLUMN_DEF        VARCHAR   default value (possibly expression) for the
+     *                             column, which should be interpreted as a
+     *                             string when the value is enclosed in quotes
+     *                             (may be <code>null</code>)
+     * SQL_DATA_TYPE     VARCHAR   type code as expected in the SQL CLI SQLDA
+     * SQL_DATETIME_SUB  INTEGER   the SQL CLI subtype for DATETIME types
+     * CHAR_OCTET_LENGTH INTEGER   for char types, max # of chars/bytes in column
+     * ORDINAL_POSITION  INTEGER   1-based index of column in table
+     * IS_NULLABLE       VARCHAR   is column nullable? ("YES"|"NO"|""}
+     * SCOPE_CATLOG      VARCHAR   catalog of REF attribute scope table
+     * SCOPE_SCHEMA      VARCHAR   schema of REF attribute scope table
+     * SCOPE_TABLE       VARCHAR   name of REF attribute scope table
+     * SOURCE_DATA_TYPE  VARCHAR   source type of REF attribute
+     * TYPE_SUB          INTEGER   HSQLDB data subtype code
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the
+     *        visible columns of all accessible
+     *        tables defined within this database.<p>
+     */
+    final Table SYSTEM_COLUMNS(Session session) {
+
+        Table t = sysTables[SYSTEM_COLUMNS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_COLUMNS]);
+
+            addColumn(t, "TABLE_CAT", SQL_IDENTIFIER);              // 0
+            addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);            // 1
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);             // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);            // not null
+            addColumn(t, "DATA_TYPE", Type.SQL_SMALLINT);           // not null
+            addColumn(t, "TYPE_NAME", SQL_IDENTIFIER);              // not null
+            addColumn(t, "COLUMN_SIZE", Type.SQL_INTEGER);          // 6
+            addColumn(t, "BUFFER_LENGTH", Type.SQL_INTEGER);        // 7
+            addColumn(t, "DECIMAL_DIGITS", Type.SQL_INTEGER);       // 8
+            addColumn(t, "NUM_PREC_RADIX", Type.SQL_INTEGER);       // 9
+            addColumn(t, "NULLABLE", Type.SQL_INTEGER);             // not null
+            addColumn(t, "REMARKS", CHARACTER_DATA);                // 11
+            addColumn(t, "COLUMN_DEF", CHARACTER_DATA);             // 12
+            addColumn(t, "SQL_DATA_TYPE", Type.SQL_INTEGER);        // 13
+            addColumn(t, "SQL_DATETIME_SUB", Type.SQL_INTEGER);     // 14
+            addColumn(t, "CHAR_OCTET_LENGTH", Type.SQL_INTEGER);    // 15
+            addColumn(t, "ORDINAL_POSITION", Type.SQL_INTEGER);     // not null
+            addColumn(t, "IS_NULLABLE", YES_OR_NO);                 // not null
+            addColumn(t, "SCOPE_CATLOG", SQL_IDENTIFIER);           // 18
+            addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);           // 19
+            addColumn(t, "SCOPE_TABLE", SQL_IDENTIFIER);            // 20
+            addColumn(t, "SOURCE_DATA_TYPE", SQL_IDENTIFIER);       // 21
+
+            // ----------------------------------------------------------------
+            // JDBC 4.0 - added Mustang b86
+            // ----------------------------------------------------------------
+            addColumn(t, "IS_AUTOINCREMENT", YES_OR_NO);            // 22
+
+            // order: TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION
+            // added for unique: TABLE_CAT
+            // false PK, as TABLE_SCHEM and/or TABLE_CAT may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_COLUMNS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 16
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        String tableCatalog;
+        String tableSchema;
+        String tableName;
+
+        // intermediate holders
+        int         columnCount;
+        Iterator    tables;
+        Table       table;
+        Object[]    row;
+        DITableInfo ti;
+
+        // column number mappings
+        final int itable_cat         = 0;
+        final int itable_schem       = 1;
+        final int itable_name        = 2;
+        final int icolumn_name       = 3;
+        final int idata_type         = 4;
+        final int itype_name         = 5;
+        final int icolumn_size       = 6;
+        final int ibuffer_length     = 7;
+        final int idecimal_digits    = 8;
+        final int inum_prec_radix    = 9;
+        final int inullable          = 10;
+        final int iremark            = 11;
+        final int icolumn_def        = 12;
+        final int isql_data_type     = 13;
+        final int isql_datetime_sub  = 14;
+        final int ichar_octet_length = 15;
+        final int iordinal_position  = 16;
+        final int iis_nullable       = 17;
+        final int iscope_cat         = 18;
+        final int iscope_schem       = 19;
+        final int iscope_table       = 20;
+
+        // JDBC 4.0
+        final int iis_autoinc = 22;
+
+        // HSQLDB-specific
+        final int itype_sub = 23;
+
+        // Initialization
+        tables = allTables();
+        ti     = new DITableInfo();
+
+        boolean translateDTI = database.getProperties().isPropertyTrue(
+            HsqlDatabaseProperties.jdbc_translate_dti_types);
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            /** @todo - requires access to the actual columns */
+            if (!isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            ti.setTable(table);
+
+            tableCatalog = table.getCatalogName().name;
+            tableSchema  = table.getSchemaName().name;
+            tableName    = table.getName().name;
+            columnCount  = table.getColumnCount();
+
+            for (int i = 0; i < columnCount; i++) {
+                ColumnSchema column = table.getColumn(i);
+                Type         type   = column.getDataType();
+
+                if (translateDTI) {
+                    if (type.isIntervalType()) {
+                        type = CharacterType.getCharacterType(
+                            Types.SQL_VARCHAR, type.displaySize());
+                    } else if (type.isDateTimeTypeWithZone()) {
+                        type = ((DateTimeType) type)
+                            .getDateTimeTypeWithoutZone();
+                    }
+                }
+
+                row = t.getEmptyRowData();
+
+                //
+                row[itable_cat]         = tableCatalog;
+                row[itable_schem]       = tableSchema;
+                row[itable_name]        = tableName;
+                row[icolumn_name]       = column.getName().name;
+                row[idata_type] = ValuePool.getInt(type.getJDBCTypeCode());
+                row[itype_name]         = type.getNameString();
+                row[icolumn_size]       = ValuePool.INTEGER_0;
+                row[ichar_octet_length] = ValuePool.INTEGER_0;
+
+                if (type.isCharacterType()) {
+                    row[icolumn_size] =
+                        ValuePool.getInt(type.getJDBCPrecision());
+
+                    // this is length not octet_length, for character columns
+                    row[ichar_octet_length] =
+                        ValuePool.getInt(type.getJDBCPrecision());
+                }
+
+                if (type.isBinaryType()) {
+                    row[icolumn_size] =
+                        ValuePool.getInt(type.getJDBCPrecision());
+                    row[ichar_octet_length] =
+                        ValuePool.getInt(type.getJDBCPrecision());
+                }
+
+                if (type.isNumberType()) {
+                    row[icolumn_size] = ValuePool.getInt(
+                        ((NumberType) type).getNumericPrecisionInRadix());
+                    row[inum_prec_radix] =
+                        ValuePool.getInt(type.getPrecisionRadix());
+
+                    if (type.isExactNumberType()) {
+                        row[idecimal_digits] = ValuePool.getLong(type.scale);
+                    }
+                }
+
+                if (type.isDateTimeType()) {
+                    int size = (int) column.getDataType().displaySize();
+
+                    row[icolumn_size] = ValuePool.getInt(size);
+                    row[isql_datetime_sub] = ValuePool.getInt(
+                        ((DateTimeType) type).getSqlDateTimeSub());
+                }
+
+                row[inullable] = ValuePool.getInt(column.getNullability());
+                row[iremark]           = ti.getColRemarks(i);
+                row[icolumn_def]       = column.getDefaultSQL();
+                row[isql_data_type]    = ValuePool.getInt(type.typeCode);
+                row[iordinal_position] = ValuePool.getInt(i + 1);
+                row[iis_nullable]      = column.isNullable() ? "YES"
+                                                             : "NO";
+
+                // JDBC 4.0
+                row[iis_autoinc] = column.isIdentity() ? "YES"
+                                                       : "NO";
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing, for each
+     * accessible referencing and referenced table, how the referencing
+     * tables import, for the purposes of referential integrity,
+     * the columns of the referenced tables.<p>
+     *
+     * Each row is a foreign key column description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * PKTABLE_CAT   VARCHAR   referenced table catalog
+     * PKTABLE_SCHEM VARCHAR   referenced table schema
+     * PKTABLE_NAME  VARCHAR   referenced table name
+     * PKCOLUMN_NAME VARCHAR   referenced column name
+     * FKTABLE_CAT   VARCHAR   referencing table catalog
+     * FKTABLE_SCHEM VARCHAR   referencing table schema
+     * FKTABLE_NAME  VARCHAR   referencing table name
+     * FKCOLUMN_NAME VARCHAR   referencing column
+     * KEY_SEQ       SMALLINT  sequence number within foreign key
+     * UPDATE_RULE   SMALLINT
+     *    { Cascade | Set Null | Set Default | Restrict (No Action)}?
+     * DELETE_RULE   SMALLINT
+     *    { Cascade | Set Null | Set Default | Restrict (No Action)}?
+     * FK_NAME       VARCHAR   foreign key constraint name
+     * PK_NAME       VARCHAR   primary key or unique constraint name
+     * DEFERRABILITY SMALLINT
+     *    { initially deferred | initially immediate | not deferrable }
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing how accessible tables
+     *      import other accessible tables' primary key and/or unique
+     *      constraint columns
+     */
+    final Table SYSTEM_CROSSREFERENCE(Session session) {
+
+        Table t = sysTables[SYSTEM_CROSSREFERENCE];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_CROSSREFERENCE]);
+
+            addColumn(t, "PKTABLE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "PKTABLE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "PKTABLE_NAME", SQL_IDENTIFIER);        // not null
+            addColumn(t, "PKCOLUMN_NAME", SQL_IDENTIFIER);       // not null
+            addColumn(t, "FKTABLE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "FKTABLE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "FKTABLE_NAME", SQL_IDENTIFIER);        // not null
+            addColumn(t, "FKCOLUMN_NAME", SQL_IDENTIFIER);       // not null
+            addColumn(t, "KEY_SEQ", Type.SQL_SMALLINT);          // not null
+            addColumn(t, "UPDATE_RULE", Type.SQL_SMALLINT);      // not null
+            addColumn(t, "DELETE_RULE", Type.SQL_SMALLINT);      // not null
+            addColumn(t, "FK_NAME", SQL_IDENTIFIER);
+            addColumn(t, "PK_NAME", SQL_IDENTIFIER);
+            addColumn(t, "DEFERRABILITY", Type.SQL_SMALLINT);    // not null
+
+            // order: FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and KEY_SEQ
+            // added for unique: FK_NAME
+            // false PK, as FKTABLE_CAT, FKTABLE_SCHEM and/or FK_NAME
+            // may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_CROSSREFERENCE].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                4, 5, 6, 8, 11
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        String  pkTableCatalog;
+        String  pkTableSchema;
+        String  pkTableName;
+        String  pkColumnName;
+        String  fkTableCatalog;
+        String  fkTableSchema;
+        String  fkTableName;
+        String  fkColumnName;
+        Integer keySequence;
+        Integer updateRule;
+        Integer deleteRule;
+        String  fkName;
+        String  pkName;
+        Integer deferrability;
+
+        // Intermediate holders
+        Iterator      tables;
+        Table         table;
+        Table         fkTable;
+        Table         pkTable;
+        int           columnCount;
+        int[]         mainCols;
+        int[]         refCols;
+        Constraint[]  constraints;
+        Constraint    constraint;
+        int           constraintCount;
+        HsqlArrayList fkConstraintsList;
+        Object[]      row;
+
+        // column number mappings
+        final int ipk_table_cat   = 0;
+        final int ipk_table_schem = 1;
+        final int ipk_table_name  = 2;
+        final int ipk_column_name = 3;
+        final int ifk_table_cat   = 4;
+        final int ifk_table_schem = 5;
+        final int ifk_table_name  = 6;
+        final int ifk_column_name = 7;
+        final int ikey_seq        = 8;
+        final int iupdate_rule    = 9;
+        final int idelete_rule    = 10;
+        final int ifk_name        = 11;
+        final int ipk_name        = 12;
+        final int ideferrability  = 13;
+
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        // We must consider all the constraints in all the user tables, since
+        // this is where reference relationships are recorded.  However, we
+        // are only concerned with Constraint.FOREIGN_KEY constraints here
+        // because their corresponing Constraint.MAIN entries are essentially
+        // duplicate data recorded in the referenced rather than the
+        // referencing table.  Also, we skip constraints where either
+        // the referenced, referencing or both tables are not accessible
+        // relative to the session of the calling context
+        fkConstraintsList = new HsqlArrayList();
+
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView() || !isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            constraints     = table.getConstraints();
+            constraintCount = constraints.length;
+
+            for (int i = 0; i < constraintCount; i++) {
+                constraint = (Constraint) constraints[i];
+
+                if (constraint.getConstraintType() == SchemaObject
+                        .ConstraintTypes
+                        .FOREIGN_KEY && isAccessibleTable(session, constraint
+                            .getRef())) {
+                    fkConstraintsList.add(constraint);
+                }
+            }
+        }
+
+        // Now that we have all of the desired constraints, we need to
+        // process them, generating one row in our ouput table for each
+        // imported/exported column pair of each constraint.
+        // Do it.
+        for (int i = 0; i < fkConstraintsList.size(); i++) {
+            constraint     = (Constraint) fkConstraintsList.get(i);
+            pkTable        = constraint.getMain();
+            pkTableName    = pkTable.getName().name;
+            fkTable        = constraint.getRef();
+            fkTableName    = fkTable.getName().name;
+            pkTableCatalog = pkTable.getCatalogName().name;
+            pkTableSchema  = pkTable.getSchemaName().name;
+            fkTableCatalog = fkTable.getCatalogName().name;
+            fkTableSchema  = fkTable.getSchemaName().name;
+            mainCols       = constraint.getMainColumns();
+            refCols        = constraint.getRefColumns();
+            columnCount    = refCols.length;
+            fkName         = constraint.getRefName().name;
+            pkName         = constraint.getMainName().name;
+            deferrability  = ValuePool.getInt(constraint.getDeferability());
+
+            //pkName = constraint.getMainIndex().getName().name;
+            deleteRule = ValuePool.getInt(constraint.getDeleteAction());
+            updateRule = ValuePool.getInt(constraint.getUpdateAction());
+
+            for (int j = 0; j < columnCount; j++) {
+                keySequence          = ValuePool.getInt(j + 1);
+                pkColumnName = pkTable.getColumn(mainCols[j]).getNameString();
+                fkColumnName = fkTable.getColumn(refCols[j]).getNameString();
+                row                  = t.getEmptyRowData();
+                row[ipk_table_cat]   = pkTableCatalog;
+                row[ipk_table_schem] = pkTableSchema;
+                row[ipk_table_name]  = pkTableName;
+                row[ipk_column_name] = pkColumnName;
+                row[ifk_table_cat]   = fkTableCatalog;
+                row[ifk_table_schem] = fkTableSchema;
+                row[ifk_table_name]  = fkTableName;
+                row[ifk_column_name] = fkColumnName;
+                row[ikey_seq]        = keySequence;
+                row[iupdate_rule]    = updateRule;
+                row[idelete_rule]    = deleteRule;
+                row[ifk_name]        = fkName;
+                row[ipk_name]        = pkName;
+                row[ideferrability]  = deferrability;
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the visible
+     * <code>Index</code> objects for each accessible table defined
+     * within this database.<p>
+     *
+     * Each row is an index column description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_CAT        VARCHAR   table's catalog
+     * TABLE_SCHEM      VARCHAR   simple name of table's schema
+     * TABLE_NAME       VARCHAR   simple name of the table using the index
+     * NON_UNIQUE       BOOLEAN   can index values be non-unique?
+     * INDEX_QUALIFIER  VARCHAR   catalog in which the index is defined
+     * INDEX_NAME       VARCHAR   simple name of the index
+     * TYPE             SMALLINT  index type: { Clustered | Hashed | Other }
+     * ORDINAL_POSITION SMALLINT  column sequence number within index
+     * COLUMN_NAME      VARCHAR   simple column name
+     * ASC_OR_DESC      VARCHAR   col. sort sequence: {"A" (Asc) | "D" (Desc)}
+     * CARDINALITY      INTEGER   # of unique values in index (not implemented)
+     * PAGES            INTEGER   index page use (not implemented)
+     * FILTER_CONDITION VARCHAR   filter condition, if any (not implemented)
+     * // HSQLDB-extension
+     * ROW_CARDINALITY  INTEGER   total # of rows in index (not implemented)
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the visible
+     *        <code>Index</code> objects for each accessible
+     *        table defined within this database.
+     */
+    final Table SYSTEM_INDEXINFO(Session session) {
+
+        Table t = sysTables[SYSTEM_INDEXINFO];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_INDEXINFO]);
+
+            // JDBC
+            addColumn(t, "TABLE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);             // NOT NULL
+            addColumn(t, "NON_UNIQUE", Type.SQL_BOOLEAN);           // NOT NULL
+            addColumn(t, "INDEX_QUALIFIER", SQL_IDENTIFIER);
+            addColumn(t, "INDEX_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TYPE", Type.SQL_SMALLINT);                // NOT NULL
+            addColumn(t, "ORDINAL_POSITION", Type.SQL_SMALLINT);    // NOT NULL
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ASC_OR_DESC", CHARACTER_DATA);
+            addColumn(t, "CARDINALITY", Type.SQL_INTEGER);
+            addColumn(t, "PAGES", Type.SQL_INTEGER);
+            addColumn(t, "FILTER_CONDITION", CHARACTER_DATA);
+
+            // HSQLDB extension
+            addColumn(t, "ROW_CARDINALITY", Type.SQL_INTEGER);
+
+            // order: NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
+            // added for unique: INDEX_QUALIFIER, TABLE_NAME
+            // false PK, as INDEX_QUALIFIER may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_INDEXINFO].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 7
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        String  tableCatalog;
+        String  tableSchema;
+        String  tableName;
+        Boolean nonUnique;
+        String  indexQualifier;
+        String  indexName;
+        Integer indexType;
+
+        //Integer ordinalPosition;
+        //String  columnName;
+        //String  ascOrDesc;
+        Integer cardinality;
+        Integer pages;
+        String  filterCondition;
+        Integer rowCardinality;
+
+        // Intermediate holders
+        Iterator tables;
+        Table    table;
+        int      indexCount;
+        int[]    cols;
+        int      col;
+        int      colCount;
+        Object[] row;
+
+        // column number mappings
+        final int itable_cat        = 0;
+        final int itable_schem      = 1;
+        final int itable_name       = 2;
+        final int inon_unique       = 3;
+        final int iindex_qualifier  = 4;
+        final int iindex_name       = 5;
+        final int itype             = 6;
+        final int iordinal_position = 7;
+        final int icolumn_name      = 8;
+        final int iasc_or_desc      = 9;
+        final int icardinality      = 10;
+        final int ipages            = 11;
+        final int ifilter_condition = 12;
+        final int irow_cardinality  = 13;
+
+        // Initialization
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView() || !isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            tableCatalog = table.getCatalogName().name;
+            tableSchema  = table.getSchemaName().name;
+            tableName    = table.getName().name;
+
+            // not supported yet
+            filterCondition = null;
+
+            // different cat for index not supported yet
+            indexQualifier = tableCatalog;
+            indexCount     = table.getIndexCount();
+
+            // process all of the visible indices for this table
+            for (int i = 0; i < indexCount; i++) {
+                Index index = table.getIndex(i);
+
+                colCount = table.getIndex(i).getColumnCount();
+
+                if (colCount < 1) {
+                    continue;
+                }
+
+                indexName      = index.getName().name;
+                nonUnique      = index.isUnique() ? Boolean.FALSE
+                                                  : Boolean.TRUE;
+                cardinality    = null;
+                pages          = ValuePool.INTEGER_0;
+                rowCardinality = null;
+                cols           = index.getColumns();
+                indexType      = ValuePool.getInt(3);
+
+                for (int k = 0; k < colCount; k++) {
+                    col                    = cols[k];
+                    row                    = t.getEmptyRowData();
+                    row[itable_cat]        = tableCatalog;
+                    row[itable_schem]      = tableSchema;
+                    row[itable_name]       = tableName;
+                    row[inon_unique]       = nonUnique;
+                    row[iindex_qualifier]  = indexQualifier;
+                    row[iindex_name]       = indexName;
+                    row[itype]             = indexType;
+                    row[iordinal_position] = ValuePool.getInt(k + 1);
+                    row[icolumn_name] =
+                        table.getColumn(cols[k]).getName().name;
+                    row[iasc_or_desc]      = "A";
+                    row[icardinality]      = cardinality;
+                    row[ipages]            = pages;
+                    row[irow_cardinality]  = rowCardinality;
+                    row[ifilter_condition] = filterCondition;
+
+                    t.insertSys(store, row);
+                }
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the visible
+     * primary key columns of each accessible table defined within
+     * this database. <p>
+     *
+     * Each row is a PRIMARY KEY column description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_CAT   VARCHAR   table catalog
+     * TABLE_SCHEM VARCHAR   table schema
+     * TABLE_NAME  VARCHAR   table name
+     * COLUMN_NAME VARCHAR   column name
+     * KEY_SEQ     SMALLINT  sequence number within primary key
+     * PK_NAME     VARCHAR   primary key constraint name
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the visible
+     *        primary key columns of each accessible table
+     *        defined within this database.
+     */
+    final Table SYSTEM_PRIMARYKEYS(Session session) {
+
+        Table t = sysTables[SYSTEM_PRIMARYKEYS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_PRIMARYKEYS]);
+
+            addColumn(t, "TABLE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);     // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);    // not null
+            addColumn(t, "KEY_SEQ", Type.SQL_SMALLINT);     // not null
+            addColumn(t, "PK_NAME", SQL_IDENTIFIER);
+
+            // order: COLUMN_NAME
+            // added for unique: TABLE_NAME, TABLE_SCHEM, TABLE_CAT
+            // false PK, as  TABLE_SCHEM and/or TABLE_CAT may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_PRIMARYKEYS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                3, 2, 1, 0
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        String tableCatalog;
+        String tableSchema;
+        String tableName;
+
+        //String  columnName;
+        //Integer keySequence;
+        String primaryKeyName;
+
+        // Intermediate holders
+        Iterator       tables;
+        Table          table;
+        Object[]       row;
+        Constraint     constraint;
+        int[]          cols;
+        int            colCount;
+        HsqlProperties p;
+
+        // column number mappings
+        final int itable_cat   = 0;
+        final int itable_schem = 1;
+        final int itable_name  = 2;
+        final int icolumn_name = 3;
+        final int ikey_seq     = 4;
+        final int ipk_name     = 5;
+
+        // Initialization
+        p = database.getProperties();
+        tables =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
+
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (table.isView() || !isAccessibleTable(session, table)
+                    || !table.hasPrimaryKey()) {
+                continue;
+            }
+
+            constraint     = table.getPrimaryConstraint();
+            tableCatalog   = table.getCatalogName().name;
+            tableSchema    = table.getSchemaName().name;
+            tableName      = table.getName().name;
+            primaryKeyName = constraint.getName().name;
+            cols           = constraint.getMainColumns();
+            colCount       = cols.length;
+
+            for (int j = 0; j < colCount; j++) {
+                row               = t.getEmptyRowData();
+                row[itable_cat]   = tableCatalog;
+                row[itable_schem] = tableSchema;
+                row[itable_name]  = tableName;
+                row[icolumn_name] = table.getColumn(cols[j]).getName().name;
+                row[ikey_seq]     = ValuePool.getInt(j + 1);
+                row[ipk_name]     = primaryKeyName;
+
+                t.insertSys(store, row);
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the
+     * return, parameter and result columns of the accessible
+     * routines defined within this database.<p>
+     *
+     * Each row is a procedure column description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * PROCEDURE_CAT   VARCHAR   routine catalog
+     * PROCEDURE_SCHEM VARCHAR   routine schema
+     * PROCEDURE_NAME  VARCHAR   routine name
+     * COLUMN_NAME     VARCHAR   column/parameter name
+     * COLUMN_TYPE     SMALLINT  kind of column/parameter
+     * DATA_TYPE       SMALLINT  SQL type from DITypes
+     * TYPE_NAME       VARCHAR   SQL type name
+     * PRECISION       INTEGER   precision (length) of type
+     * LENGTH          INTEGER   transfer size, in bytes, if definitely known
+     *                           (roughly equivalent to BUFFER_SIZE for table
+     *                           columns)
+     * SCALE           SMALLINT  scale
+     * RADIX           SMALLINT  radix
+     * NULLABLE        SMALLINT  can column contain NULL?
+     * REMARKS         VARCHAR   explanatory comment on column
+     * // JDBC 4.0
+     * COLUMN_DEF        VARCHAR The default column value.
+     *                           The string NULL (not enclosed in quotes)
+     *                           - If NULL was specified as the default value
+     *                           TRUNCATE (not enclosed in quotes)
+     *                           - If the specified default value cannot be
+     *                           represented without truncation
+     *                           NULL
+     *                           - If a default value was not specified
+     * SQL_DATA_TYPE     INTEGER CLI type list from SQL 2003 Table 37,
+     *                           tables 6-9 Annex A1, and/or addendums in other
+     *                           documents, such as:
+     *                           SQL 2003 Part 9: Management of External Data (SQL/MED) : DATALINK
+     *                           SQL 2003 Part 14: XML-Related Specifications (SQL/XML) : XML
+     * SQL_DATETIME_SUB  INTEGER SQL 2003 CLI datetime/interval subcode.
+     * CHAR_OCTET_LENGTH INTEGER The maximum length of binary and character
+     *                           based columns.  For any other datatype the
+     *                           returned value is a NULL
+     * ORDINAL_POSITION  INTEGER The ordinal position, starting from 1, for the
+     *                           input and output parameters for a procedure.
+     *                           A value of 0 is returned if this row describes
+     *                           the procedure's return value.
+     * IS_NULLABLE       VARCHAR ISO rules are used to determinte the nulliblity
+     *                           for a column.
+     *
+     *                           YES (enclosed in quotes)  --- if the column can include NULLs
+     *                           NO  (enclosed in quotes)  --- if the column cannot include NULLs
+     *                           empty string              --- if the nullability for the column is unknown
+     *
+     * SPECIFIC_NAME     VARCHAR The name which uniquely identifies this
+     *                           procedure within its schema.
+     *                           Typically (but not restricted to) a
+     *                           fully qualified Java Method name and
+     *                           signature
+     * // HSQLDB extension
+     * JDBC_SEQ          INTEGER The JDBC-specified order within
+     *                           runs of PROCEDURE_SCHEM, PROCEDURE_NAME,
+     *                           SPECIFIC_NAME, which is:
+     *
+     *                           return value (0), if any, first, followed
+     *                           by the parameter descriptions in call order
+     *                           (1..n1), followed by the result column
+     *                           descriptions in column number order
+     *                           (n1 + 1..n1 + n2)
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the
+     *        return, parameter and result columns
+     *        of the accessible routines defined
+     *        within this database.
+     */
+    Table SYSTEM_PROCEDURECOLUMNS(Session session) {
+
+        Table t = sysTables[SYSTEM_PROCEDURECOLUMNS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_PROCEDURECOLUMNS]);
+
+            // ----------------------------------------------------------------
+            // required
+            // ----------------------------------------------------------------
+            addColumn(t, "PROCEDURE_CAT", SQL_IDENTIFIER);          // 0
+            addColumn(t, "PROCEDURE_SCHEM", SQL_IDENTIFIER);        // 1
+            addColumn(t, "PROCEDURE_NAME", SQL_IDENTIFIER);         // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);            // not null
+            addColumn(t, "COLUMN_TYPE", Type.SQL_SMALLINT);         // not null
+            addColumn(t, "DATA_TYPE", Type.SQL_SMALLINT);           // not null
+            addColumn(t, "TYPE_NAME", SQL_IDENTIFIER);              // not null
+            addColumn(t, "PRECISION", Type.SQL_INTEGER);            // 7
+            addColumn(t, "LENGTH", Type.SQL_INTEGER);               // 8
+            addColumn(t, "SCALE", Type.SQL_SMALLINT);               // 9
+            addColumn(t, "RADIX", Type.SQL_SMALLINT);               // 10
+            addColumn(t, "NULLABLE", Type.SQL_SMALLINT);            // not null
+            addColumn(t, "REMARKS", CHARACTER_DATA);                // 12
+
+            // ----------------------------------------------------------------
+            // JDBC 4.0
+            // ----------------------------------------------------------------
+            addColumn(t, "COLUMN_DEF", CHARACTER_DATA);             // 13
+            addColumn(t, "SQL_DATA_TYPE", Type.SQL_INTEGER);        // 14
+            addColumn(t, "SQL_DATETIME_SUB", Type.SQL_INTEGER);     // 15
+            addColumn(t, "CHAR_OCTET_LENGTH", Type.SQL_INTEGER);    // 16
+            addColumn(t, "ORDINAL_POSITION", Type.SQL_INTEGER);     // 17
+            addColumn(t, "IS_NULLABLE", CHARACTER_DATA);            // 18
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);          // 19
+
+            // order: PROCEDURE_SCHEM, PROCEDURE_NAME, SPECIFIC_NAME, ORDINAL_POSITION
+            //
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_PROCEDURECOLUMNS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 19, 17
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int specific_cat            = 0;
+        final int specific_schem          = 1;
+        final int procedure_name          = 2;
+        final int parameter_name          = 3;
+        final int parameter_mode          = 4;
+        final int data_type_sql_id        = 5;
+        final int data_type               = 6;
+        final int numeric_precision       = 7;
+        final int byte_length             = 8;
+        final int numeric_scale           = 9;
+        final int numeric_precision_radix = 10;
+        final int nullable                = 11;
+        final int remark                  = 12;
+        final int default_val             = 13;
+        final int sql_data_type           = 14;
+        final int sql_datetime_sub        = 15;
+        final int character_octet_length  = 16;
+        final int ordinal_position        = 17;
+        final int is_nullable             = 18;
+        final int specific_name           = 19;
+
+        // intermediate holders
+        int           columnCount;
+        Iterator      routines;
+        RoutineSchema routineSchema;
+        Routine       routine;
+        Object[]      row;
+        Type          type;
+
+        // Initialization
+        boolean translateDTI = database.getProperties().isPropertyTrue(
+            HsqlDatabaseProperties.jdbc_translate_dti_types);
+
+        routines = database.schemaManager.databaseObjectIterator(
+            SchemaObject.ROUTINE);
+
+        while (routines.hasNext()) {
+            routineSchema = (RoutineSchema) routines.next();
+
+            if (!session.getGrantee().isAccessible(routineSchema)) {
+                continue;
+            }
+
+            Routine[] specifics = routineSchema.getSpecificRoutines();
+
+            for (int i = 0; i < specifics.length; i++) {
+                routine     = specifics[i];
+                columnCount = routine.getParameterCount();
+
+                for (int j = 0; j < columnCount; j++) {
+                    ColumnSchema column = routine.getParameter(j);
+
+                    row  = t.getEmptyRowData();
+                    type = column.getDataType();
+
+                    if (translateDTI) {
+                        if (type.isIntervalType()) {
+                            type = CharacterType.getCharacterType(
+                                Types.SQL_VARCHAR, type.displaySize());
+                        } else if (type.isDateTimeTypeWithZone()) {
+                            type = ((DateTimeType) type)
+                                .getDateTimeTypeWithoutZone();
+                        }
+                    }
+
+                    row[specific_cat]     = database.getCatalogName().name;
+                    row[specific_schem]   = routine.getSchemaName().name;
+                    row[specific_name]    = routine.getSpecificName().name;
+                    row[procedure_name]   = routine.getName().name;
+                    row[parameter_name]   = column.getName().name;
+                    row[ordinal_position] = ValuePool.getInt(j + 1);
+                    row[parameter_mode] =
+                        ValuePool.getInt(column.getParameterMode());
+                    row[data_type] = type.getFullNameString();
+                    row[data_type_sql_id] =
+                        ValuePool.getInt(type.getJDBCTypeCode());
+                    row[numeric_precision]      = ValuePool.INTEGER_0;
+                    row[character_octet_length] = ValuePool.INTEGER_0;
+
+                    if (type.isCharacterType()) {
+                        row[numeric_precision] =
+                            ValuePool.getInt(type.getJDBCPrecision());
+
+                        // this is length not octet_length, for character columns
+                        row[character_octet_length] =
+                            ValuePool.getInt(type.getJDBCPrecision());
+                    }
+
+                    if (type.isBinaryType()) {
+                        row[numeric_precision] =
+                            ValuePool.getInt(type.getJDBCPrecision());
+                        row[character_octet_length] =
+                            ValuePool.getInt(type.getJDBCPrecision());
+                    }
+
+                    if (type.isNumberType()) {
+                        row[numeric_precision] = ValuePool.getInt(
+                            ((NumberType) type).getNumericPrecisionInRadix());
+                        row[numeric_precision_radix] =
+                            ValuePool.getLong(type.getPrecisionRadix());
+
+                        if (type.isExactNumberType()) {
+                            row[numeric_scale] = ValuePool.getLong(type.scale);
+                        }
+                    }
+
+                    if (type.isDateTimeType()) {
+                        int size = (int) column.getDataType().displaySize();
+
+                        row[numeric_precision] = ValuePool.getInt(size);
+                    }
+
+                    row[sql_data_type] =
+                        ValuePool.getInt(column.getDataType().typeCode);
+                    row[nullable] = ValuePool.getInt(column.getNullability());
+                    row[is_nullable] = column.isNullable() ? "YES"
+                                                           : "NO";
+
+                    t.insertSys(store, row);
+                }
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the accessible
+     * routines defined within this database.
+     *
+     * Each row is a procedure description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * PROCEDURE_CAT     VARCHAR   catalog in which routine is defined
+     * PROCEDURE_SCHEM   VARCHAR   schema in which routine is defined
+     * PROCEDURE_NAME    VARCHAR   simple routine identifier
+     * COL_4             INTEGER   unused
+     * COL_5             INTEGER   unused
+     * COL_6             INTEGER   unused
+     * REMARKS           VARCHAR   explanatory comment on the routine
+     * PROCEDURE_TYPE    SMALLINT  { Unknown | No Result | Returns Result }
+     * // JDBC 4.0
+     * SPECIFIC_NAME     VARCHAR   The name which uniquely identifies this
+     *                             procedure within its schema.
+     *                             typically (but not restricted to) a
+     *                             fully qualified Java Method name
+     *                             and signature.
+     * // HSQLDB extension
+     * ORIGIN            VARCHAR   {ALIAS |
+     *                             [BUILTIN | USER DEFINED] ROUTINE |
+     *                             [BUILTIN | USER DEFINED] TRIGGER |
+     *                              ...}
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the accessible
+     *        routines defined within the this database
+     */
+    Table SYSTEM_PROCEDURES(Session session) {
+
+        Table t = sysTables[SYSTEM_PROCEDURES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_PROCEDURES]);
+
+            // ----------------------------------------------------------------
+            // required
+            // ----------------------------------------------------------------
+            addColumn(t, "PROCEDURE_CAT", SQL_IDENTIFIER);        // 0
+            addColumn(t, "PROCEDURE_SCHEM", SQL_IDENTIFIER);      // 1
+            addColumn(t, "PROCEDURE_NAME", SQL_IDENTIFIER);       // 2
+            addColumn(t, "COL_4", Type.SQL_INTEGER);              // 3
+            addColumn(t, "COL_5", Type.SQL_INTEGER);              // 4
+            addColumn(t, "COL_6", Type.SQL_INTEGER);              // 5
+            addColumn(t, "REMARKS", CHARACTER_DATA);              // 6
+
+            // basically: function (returns result), procedure (no return value)
+            // or unknown (say, a trigger callout routine)
+            addColumn(t, "PROCEDURE_TYPE", Type.SQL_SMALLINT);    // 7
+
+            // ----------------------------------------------------------------
+            // JDBC 4.0
+            // ----------------------------------------------------------------
+            addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);        // 8
+
+            // ----------------------------------------------------------------
+            // order: PROCEDURE_CAT, PROCEDURE_SCHEM, PROCEDURE_NAME, SPECIFIC_NAME
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_PROCEDURES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 8
+            }, false);
+
+            return t;
+        }
+
+        //
+        final int procedure_catalog = 0;
+        final int procedure_schema  = 1;
+        final int procedure_name    = 2;
+        final int col_4             = 3;
+        final int col_5             = 4;
+        final int col_6             = 5;
+        final int remarks           = 6;
+        final int procedure_type    = 7;
+        final int specific_name     = 8;
+
+        //
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        //
+        Iterator it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.SPECIFIC_ROUTINE);
+
+        while (it.hasNext()) {
+            Routine  routine = (Routine) it.next();
+            Object[] row     = t.getEmptyRowData();
+
+            row[procedure_catalog] = row[procedure_catalog] =
+                database.getCatalogName().name;
+            row[procedure_schema] = routine.getSchemaName().name;
+            row[procedure_name]   = routine.getName().name;
+            row[procedure_type] = routine.isProcedure() ? ValuePool.INTEGER_1
+                                                        : ValuePool.INTEGER_2;
+            row[specific_name]    = routine.getSpecificName().name;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * getClientInfoProperties
+     *
+     * @return Result
+     *
+     * <li><b>NAME</b> String=> The name of the client info property<br>
+     * <li><b>MAX_LEN</b> int=> The maximum length of the value for the property<br>
+     * <li><b>DEFAULT_VALUE</b> String=> The default value of the property<br>
+     * <li><b>DESCRIPTION</b> String=> A description of the property.  This will typically
+     *                                                  contain information as to where this property is
+     *                                                  stored in the database.
+     */
+    final Table SYSTEM_CONNECTION_PROPERTIES(Session session) {
+
+        Table t = sysTables[SYSTEM_CONNECTION_PROPERTIES];
+
+        if (t == null) {
+            t = createBlankTable(
+                sysTableHsqlNames[SYSTEM_CONNECTION_PROPERTIES]);
+
+            addColumn(t, "NAME", SQL_IDENTIFIER);
+            addColumn(t, "MAX_LEN", Type.SQL_INTEGER);
+            addColumn(t, "DEFAULT_VALUE", SQL_IDENTIFIER);    // not null
+            addColumn(t, "DESCRIPTION", SQL_IDENTIFIER);      // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_PRIMARYKEYS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Object[]        row;
+
+        // column number mappings
+        final int iname          = 0;
+        final int imax_len       = 1;
+        final int idefault_value = 2;
+        final int idescription   = 3;
+        Iterator  it = HsqlDatabaseProperties.getPropertiesMetaIterator();
+
+        while (it.hasNext()) {
+            Object[] meta = (Object[]) it.next();
+            int propType =
+                ((Integer) meta[HsqlProperties.indexType]).intValue();
+
+            if (propType == HsqlDatabaseProperties.FILE_PROPERTY) {
+                if (HsqlDatabaseProperties.hsqldb_readonly.equals(
+                        meta[HsqlProperties.indexName]) || HsqlDatabaseProperties
+                            .hsqldb_files_readonly.equals(
+                                meta[HsqlProperties.indexName])) {}
+                else {
+                    continue;
+                }
+            } else if (propType != HsqlDatabaseProperties.SQL_PROPERTY) {
+                continue;
+            }
+
+            row = t.getEmptyRowData();
+
+            Object def = meta[HsqlProperties.indexDefaultValue];
+
+            row[iname]          = meta[HsqlProperties.indexName];
+            row[imax_len]       = ValuePool.getInt(8);
+            row[idefault_value] = def == null ? null
+                                              : def.toString();
+            row[idescription]   = "see HyperSQL guide";
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * Inserts a set of procedure description rows into the <code>Table</code>
+     * object specified by the <code>t</code> argument. <p>
+     *
+     * @param t the table into which the specified rows will eventually
+     *      be inserted
+     * @param l the list of procedure name aliases to which the specified column
+     *      values apply
+     * @param cat the procedure catalog name
+     * @param schem the procedure schema name
+     * @param pName the base (non-alias) procedure name
+     * @param ip the procedure input parameter count
+     * @param op the procedure output parameter count
+     * @param rs the procedure result column count
+     * @param remark a human-readable remark regarding the procedure
+     * @param pType the procedure type code, indicating whether it is a
+     *      function, procedure, or uncatagorized (i.e. returns
+     *      a value, does not return a value, or it is unknown
+     *      if it returns a value)
+     * @param specificName the specific name of the procedure
+     *      (typically but not limited to a
+     *      fully qualified Java Method name and signature)
+     * @param origin origin of the procedure, e.g.
+     *      (["BUILTIN" | "USER DEFINED"] "ROUTINE" | "TRIGGER") | "ALIAS", etc.
+     *
+     */
+    protected void addProcRows(Session session, Table t, HsqlArrayList l,
+                               String cat, String schem, String pName,
+                               Integer ip, Integer op, Integer rs,
+                               String remark, Integer pType,
+                               String specificName, String origin) {
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int icat          = 0;
+        final int ischem        = 1;
+        final int ipname        = 2;
+        final int iinput_parms  = 3;
+        final int ioutput_parms = 4;
+        final int iresult_sets  = 5;
+        final int iremark       = 6;
+        final int iptype        = 7;
+        final int isn           = 8;
+        final int iporigin      = 9;
+        Object[]  row           = t.getEmptyRowData();
+
+        row[icat]          = cat;
+        row[ischem]        = schem;
+        row[ipname]        = pName;
+        row[iinput_parms]  = ip;
+        row[ioutput_parms] = op;
+        row[iresult_sets]  = rs;
+        row[iremark]       = remark;
+        row[iptype]        = pType;
+        row[iporigin]      = origin;
+        row[isn]           = specificName;
+
+        t.insertSys(store, row);
+
+        if (l != null) {
+            int size = l.size();
+
+            for (int i = 0; i < size; i++) {
+                row                = t.getEmptyRowData();
+                pName              = (String) l.get(i);
+                row[icat]          = cat;
+                row[ischem]        = schem;
+                row[ipname]        = pName;
+                row[iinput_parms]  = ip;
+                row[ioutput_parms] = op;
+                row[iresult_sets]  = rs;
+                row[iremark]       = remark;
+                row[iptype]        = pType;
+                row[iporigin]      = "ALIAS";
+                row[isn]           = specificName;
+
+                t.insertSys(store, row);
+            }
+        }
+    }
+
+    /**
+     * Inserts a set of procedure column description rows into the
+     * <code>Table</code> specified by the <code>t</code> argument.
+     *
+     * <p>
+     *
+     * @param t the table in which the rows are to be inserted
+     * @param l the list of procedure name aliases to which the specified
+     *   column values apply
+     * @param cat the procedure's catalog name
+     * @param schem the procedure's schema name
+     * @param pName the procedure's simple base (non-alias) name
+     * @param cName the procedure column name
+     * @param cType the column type (return, parameter, result)
+     * @param dType the column's data type code
+     * @param tName the column's canonical data type name
+     * @param prec the column's precision
+     * @param len the column's buffer length
+     * @param scale the column's scale (decimal digits)
+     * @param radix the column's numeric precision radix
+     * @param nullability the column's java.sql.DatbaseMetaData nullabiliy code
+     * @param remark a human-readable remark regarding the column
+     * @param colDefault String
+     * @param sqlDataType helper value to back JDBC contract sort order
+     * @param sqlDateTimeSub Integer
+     * @param charOctetLength Integer
+     * @param ordinalPosition Integer
+     * @param isNullable String
+     * @param specificName the specific name of the procedure (typically but
+     *   not limited to a fully qualified Java Method name and signature)
+     * @param jdbcSequence int
+     */
+    protected void addPColRows(Session session, Table t, HsqlArrayList l,
+                               String cat, String schem, String pName,
+                               String cName, Integer cType, Integer dType,
+                               String tName, Integer prec, Integer len,
+                               Integer scale, Integer radix,
+                               Integer nullability, String remark,
+                               String colDefault, Integer sqlDataType,
+                               Integer sqlDateTimeSub,
+                               Integer charOctetLength,
+                               Integer ordinalPosition, String isNullable,
+                               String specificName) {
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int icat       = 0;
+        final int ischem     = 1;
+        final int iname      = 2;
+        final int icol_name  = 3;
+        final int icol_type  = 4;
+        final int idata_type = 5;
+        final int itype_name = 6;
+        final int iprec      = 7;
+        final int ilength    = 8;
+        final int iscale     = 9;
+        final int iradix     = 10;
+        final int inullable  = 11;
+        final int iremark    = 12;
+
+        // JDBC 4.0
+        final int icol_default      = 13;
+        final int isql_data_type    = 14;
+        final int isql_datetime_sub = 15;
+        final int ichar_octet_len   = 16;
+        final int iordinal_position = 17;
+        final int iis_nullable      = 18;
+        final int ispecific_name    = 19;
+
+        // initialization
+        Object[] row = t.getEmptyRowData();
+
+        // Do it.
+        row[icat]       = cat;
+        row[ischem]     = schem;
+        row[iname]      = pName;
+        row[icol_name]  = cName;
+        row[icol_type]  = cType;
+        row[idata_type] = dType;
+        row[itype_name] = tName;
+        row[iprec]      = prec;
+        row[ilength]    = len;
+        row[iscale]     = scale;
+        row[iradix]     = radix;
+        row[inullable]  = nullability;
+        row[iremark]    = remark;
+
+        // JDBC 4.0
+        row[icol_default]      = colDefault;
+        row[isql_data_type]    = sqlDataType;
+        row[isql_datetime_sub] = sqlDateTimeSub;
+        row[ichar_octet_len]   = charOctetLength;
+        row[iordinal_position] = ordinalPosition;
+        row[iis_nullable]      = isNullable;
+        row[ispecific_name]    = specificName;
+
+        t.insertSys(store, row);
+
+        if (l != null) {
+            int size = l.size();
+
+            for (int i = 0; i < size; i++) {
+                row             = t.getEmptyRowData();
+                pName           = (String) l.get(i);
+                row[icat]       = cat;
+                row[ischem]     = schem;
+                row[iname]      = pName;
+                row[icol_name]  = cName;
+                row[icol_type]  = cType;
+                row[idata_type] = dType;
+                row[itype_name] = tName;
+                row[iprec]      = prec;
+                row[ilength]    = len;
+                row[iscale]     = scale;
+                row[iradix]     = radix;
+                row[inullable]  = nullability;
+                row[iremark]    = remark;
+
+                // JDBC 4.0
+                row[icol_default]      = colDefault;
+                row[isql_data_type]    = sqlDataType;
+                row[isql_datetime_sub] = sqlDateTimeSub;
+                row[ichar_octet_len]   = charOctetLength;
+                row[iordinal_position] = ordinalPosition;
+                row[iis_nullable]      = isNullable;
+                row[ispecific_name]    = specificName;
+
+                t.insertSys(store, row);
+            }
+        }
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the accessible schemas
+     * defined within this database. <p>
+     *
+     * Each row is a schema description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_SCHEM      VARCHAR   simple schema name
+     * TABLE_CATALOG    VARCHAR   catalog in which schema is defined
+     * IS_DEFAULT       BOOLEAN   is the schema the default for new sessions
+     * </pre> <p>
+     *
+     * @return table containing information about schemas defined
+     *      within this database
+     */
+    final Table SYSTEM_SCHEMAS(Session session) {
+
+        Table t = sysTables[SYSTEM_SCHEMAS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_SCHEMAS]);
+
+            addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);    // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "IS_DEFAULT", Type.SQL_BOOLEAN);
+
+            // order: TABLE_SCHEM
+            // true PK, as rows never have null TABLE_SCHEM
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_SCHEMAS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Iterator        schemas;
+        Object[]        row;
+
+        // Initialization
+        schemas = database.schemaManager.fullSchemaNamesIterator();
+
+        String defschema =
+            database.schemaManager.getDefaultSchemaHsqlName().name;
+
+        // Do it.
+        while (schemas.hasNext()) {
+            row = t.getEmptyRowData();
+
+            String schema = (String) schemas.next();
+
+            row[0] = schema;
+            row[1] = database.getCatalogName().name;
+            row[2] = schema.equals(defschema) ? Boolean.TRUE
+                                              : Boolean.FALSE;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the accessible
+     * tables defined within this database. <p>
+     *
+     * Each row is a table description with the following columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_CAT                 VARCHAR   table catalog
+     * TABLE_SCHEM               VARCHAR   table schema
+     * TABLE_NAME                VARCHAR   table name
+     * TABLE_TYPE                VARCHAR   {"TABLE" | "VIEW" |
+     *                                      "SYSTEM TABLE" | "GLOBAL TEMPORARY"}
+     * REMARKS                   VARCHAR   comment on the table.
+     * TYPE_CAT                  VARCHAR   table type catalog (not implemented).
+     * TYPE_SCHEM                VARCHAR   table type schema (not implemented).
+     * TYPE_NAME                 VARCHAR   table type name (not implemented).
+     * SELF_REFERENCING_COL_NAME VARCHAR   designated "identifier" column of
+     *                                     typed table (not implemented).
+     * REF_GENERATION            VARCHAR   {"SYSTEM" | "USER" |
+     *                                      "DERIVED" | NULL } (not implemented)
+     * HSQLDB_TYPE               VARCHAR   HSQLDB-specific type:
+     *                                     {"MEMORY" | "CACHED" | "TEXT" | ...}
+     * READ_ONLY                 BOOLEAN   TRUE if table is read-only,
+     *                                     else FALSE.
+     * COMMIT_ACTION             VARCHAR   "PRESERVE" or "DELETE" for temp tables,
+     *                                     else NULL
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the accessible
+     *      tables defined within this database
+     */
+    final Table SYSTEM_TABLES(Session session) {
+
+        Table t = sysTables[SYSTEM_TABLES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_TABLES]);
+
+            // -------------------------------------------------------------
+            // required
+            // -------------------------------------------------------------
+            addColumn(t, "TABLE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);       // not null
+            addColumn(t, "TABLE_TYPE", CHARACTER_DATA);       // not null
+            addColumn(t, "REMARKS", CHARACTER_DATA);
+
+            // -------------------------------------------------------------
+            // JDBC 3.0
+            // -------------------------------------------------------------
+            addColumn(t, "TYPE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "TYPE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "TYPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "SELF_REFERENCING_COL_NAME", SQL_IDENTIFIER);
+            addColumn(t, "REF_GENERATION", CHARACTER_DATA);
+
+            // -------------------------------------------------------------
+            // extended
+            // ------------------------------------------------------------
+            addColumn(t, "HSQLDB_TYPE", SQL_IDENTIFIER);
+            addColumn(t, "READ_ONLY", Type.SQL_BOOLEAN);      // not null
+            addColumn(t, "COMMIT_ACTION", CHARACTER_DATA);    // not null
+
+            // ------------------------------------------------------------
+            // order TABLE_TYPE, TABLE_SCHEM and TABLE_NAME
+            // added for unique: TABLE_CAT
+            // false PK, as TABLE_SCHEM and/or TABLE_CAT may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_TABLES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                3, 1, 2, 0
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // intermediate holders
+        Iterator    tables;
+        Table       table;
+        Object[]    row;
+        HsqlName    accessKey;
+        DITableInfo ti;
+
+        // column number mappings
+        // JDBC 1
+        final int itable_cat   = 0;
+        final int itable_schem = 1;
+        final int itable_name  = 2;
+        final int itable_type  = 3;
+        final int iremark      = 4;
+
+        // JDBC 3.0
+        final int itype_cat   = 5;
+        final int itype_schem = 6;
+        final int itype_name  = 7;
+        final int isref_cname = 8;
+        final int iref_gen    = 9;
+
+        // hsqldb ext
+        final int ihsqldb_type   = 10;
+        final int iread_only     = 11;
+        final int icommit_action = 12;
+
+        // Initialization
+        tables = allTables();
+        ti     = new DITableInfo();
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (!isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            ti.setTable(table);
+
+            row               = t.getEmptyRowData();
+            row[itable_cat]   = database.getCatalogName().name;
+            row[itable_schem] = table.getSchemaName().name;
+            row[itable_name]  = table.getName().name;
+            row[itable_type]  = ti.getJDBCStandardType();
+            row[iremark]      = ti.getRemark();
+            row[ihsqldb_type] = ti.getHsqlType();
+            row[iread_only]   = table.isDataReadOnly() ? Boolean.TRUE
+                                                       : Boolean.FALSE;
+            row[icommit_action] = table.isTemp()
+                                  ? (table.onCommitPreserve() ? "PRESERVE"
+                                                              : "DELETE")
+                                  : null;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the table types
+     * available in this database. <p>
+     *
+     * In general, the range of values that may be commonly encounted across
+     * most DBMS implementations is: <p>
+     *
+     * <UL>
+     *   <LI><FONT color='#FF00FF'>"TABLE"</FONT>
+     *   <LI><FONT color='#FF00FF'>"VIEW"</FONT>
+     *   <LI><FONT color='#FF00FF'>"SYSTEM TABLE"</FONT>
+     *   <LI><FONT color='#FF00FF'>"GLOBAL TEMPORARY"</FONT>
+     *   <LI><FONT color='#FF00FF'>"LOCAL TEMPORARY"</FONT>
+     *   <LI><FONT color='#FF00FF'>"ALIAS"</FONT>
+     *   <LI><FONT color='#FF00FF'>"SYNONYM"</FONT>
+     * </UL> <p>
+     *
+     * As of HSQLDB 1.7.2, the engine supports and thus this method reports
+     * only a subset of the range above: <p>
+     *
+     * <UL>
+     *   <LI><FONT color='#FF00FF'>"TABLE"</FONT>
+     *    (HSQLDB MEMORY, CACHED and TEXT tables)
+     *   <LI><FONT color='#FF00FF'>"VIEW"</FONT>  (Views)
+     *   <LI><FONT color='#FF00FF'>"SYSTEM TABLE"</FONT>
+     *    (The tables generated by this object)
+     *   <LI><FONT color='#FF00FF'>"GLOBAL TEMPORARY"</FONT>
+     *    (HSQLDB TEMP and TEMP TEXT tables)
+     * </UL> <p>
+     *
+     * @return a <code>Table</code> object describing the table types
+     *        available in this database
+     */
+    Table SYSTEM_TABLETYPES(Session session) {
+
+        Table t = sysTables[SYSTEM_TABLETYPES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_TABLETYPES]);
+
+            addColumn(t, "TABLE_TYPE", SQL_IDENTIFIER);    // not null
+
+            // order: TABLE_TYPE
+            // true PK
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_TABLETYPES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Object[]        row;
+
+        for (int i = 0; i < tableTypes.length; i++) {
+            row    = t.getEmptyRowData();
+            row[0] = tableTypes[i];
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the
+     * result expected by the JDBC DatabaseMetaData interface implementation
+     * for system-defined SQL types supported as table columns.
+     *
+     * <pre class="SqlCodeExample">
+     * TYPE_NAME          VARCHAR   the canonical name for DDL statements.
+     * DATA_TYPE          SMALLINT  data type code from DITypes.
+     * PRECISION          INTEGER   max column size.
+     *                              number => max precision.
+     *                              character => max characters.
+     *                              datetime => max chars incl. frac. component.
+     * LITERAL_PREFIX     VARCHAR   char(s) prefixing literal of this type.
+     * LITERAL_SUFFIX     VARCHAR   char(s) terminating literal of this type.
+     * CREATE_PARAMS      VARCHAR   Localized syntax-order list of domain
+     *                              create parameter keywords.
+     *                              - for human consumption only
+     * NULLABLE           SMALLINT  {No Nulls | Nullable | Unknown}
+     * CASE_SENSITIVE     BOOLEAN   case-sensitive in collations/comparisons?
+     * SEARCHABLE         SMALLINT  {None | Char (Only WHERE .. LIKE) |
+     *                               Basic (Except WHERE .. LIKE) |
+     *                               Searchable (All forms)}
+     * UNSIGNED_ATTRIBUTE BOOLEAN   {TRUE  (unsigned) | FALSE (signed) |
+     *                               NULL (non-numeric or not applicable)}
+     * FIXED_PREC_SCALE   BOOLEAN   {TRUE (fixed) | FALSE (variable) |
+     *                               NULL (non-numeric or not applicable)}
+     * AUTO_INCREMENT     BOOLEAN   automatic unique value generated for
+     *                              inserts and updates when no value or
+     *                              NULL specified?
+     * LOCAL_TYPE_NAME    VARCHAR   localized name of data type;
+     *                              - NULL if not supported.
+     *                              - for human consuption only
+     * MINIMUM_SCALE      SMALLINT  minimum scale supported.
+     * MAXIMUM_SCALE      SMALLINT  maximum scale supported.
+     * SQL_DATA_TYPE      INTEGER   value expected in SQL CLI SQL_DESC_TYPE
+     *                              field of the SQLDA.
+     * SQL_DATETIME_SUB   INTEGER   SQL CLI datetime/interval subcode.
+     * NUM_PREC_RADIX     INTEGER   numeric base w.r.t # of digits reported in
+     *                              PRECISION column (typically 10).
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object describing the
+     *      system-defined SQL types supported as table columns
+     */
+    final Table SYSTEM_TYPEINFO(Session session) {
+
+        Table t = sysTables[SYSTEM_TYPEINFO];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_TYPEINFO]);
+
+            //-------------------------------------------
+            // required by JDBC:
+            // ------------------------------------------
+            addColumn(t, "TYPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "DATA_TYPE", Type.SQL_SMALLINT);
+            addColumn(t, "PRECISION", Type.SQL_INTEGER);
+            addColumn(t, "LITERAL_PREFIX", CHARACTER_DATA);
+            addColumn(t, "LITERAL_SUFFIX", CHARACTER_DATA);
+            addColumn(t, "CREATE_PARAMS", CHARACTER_DATA);
+            addColumn(t, "NULLABLE", Type.SQL_SMALLINT);
+            addColumn(t, "CASE_SENSITIVE", Type.SQL_BOOLEAN);
+            addColumn(t, "SEARCHABLE", Type.SQL_INTEGER);
+            addColumn(t, "UNSIGNED_ATTRIBUTE", Type.SQL_BOOLEAN);
+            addColumn(t, "FIXED_PREC_SCALE", Type.SQL_BOOLEAN);
+            addColumn(t, "AUTO_INCREMENT", Type.SQL_BOOLEAN);
+            addColumn(t, "LOCAL_TYPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "MINIMUM_SCALE", Type.SQL_SMALLINT);
+            addColumn(t, "MAXIMUM_SCALE", Type.SQL_SMALLINT);
+            addColumn(t, "SQL_DATA_TYPE", Type.SQL_INTEGER);
+            addColumn(t, "SQL_DATETIME_SUB", Type.SQL_INTEGER);
+            addColumn(t, "NUM_PREC_RADIX", Type.SQL_INTEGER);
+
+            //-------------------------------------------
+            // SQL CLI / ODBC - not in JDBC spec
+            // ------------------------------------------
+            addColumn(t, "INTERVAL_PRECISION", Type.SQL_INTEGER);
+
+            // order:  DATA_TYPE, TYPE_NAME
+            // true primary key
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_TYPEINFO].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                1, 0
+            }, true);
+
+            return t;
+        }
+
+        //-----------------------------------------
+        // Same as SYSTEM_TYPEINFO
+        //-----------------------------------------
+        final int itype_name          = 0;
+        final int idata_type          = 1;
+        final int iprecision          = 2;
+        final int iliteral_prefix     = 3;
+        final int iliteral_suffix     = 4;
+        final int icreate_params      = 5;
+        final int inullable           = 6;
+        final int icase_sensitive     = 7;
+        final int isearchable         = 8;
+        final int iunsigned_attribute = 9;
+        final int ifixed_prec_scale   = 10;
+        final int iauto_increment     = 11;
+        final int ilocal_type_name    = 12;
+        final int iminimum_scale      = 13;
+        final int imaximum_scale      = 14;
+        final int isql_data_type      = 15;
+        final int isql_datetime_sub   = 16;
+        final int inum_prec_radix     = 17;
+
+        //------------------------------------------
+        // Extensions
+        //------------------------------------------
+        // not in JDBC, but in SQL CLI SQLDA / ODBC
+        //------------------------------------------
+        final int       iinterval_precision = 18;
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Object[]        row;
+        Iterator        it = Type.typeNames.keySet().iterator();
+        boolean translateDTI = database.getProperties().isPropertyTrue(
+            HsqlDatabaseProperties.jdbc_translate_dti_types);
+
+        while (it.hasNext()) {
+            String typeName = (String) it.next();
+            int    typeCode = Type.typeNames.get(typeName);
+            Type   type     = Type.getDefaultType(typeCode);
+
+            if (type == null) {
+                continue;
+            }
+
+            if (translateDTI) {
+                if (type.isIntervalType()) {
+                    type = CharacterType.getCharacterType(Types.SQL_VARCHAR,
+                                                          type.displaySize());
+                } else if (type.isDateTimeTypeWithZone()) {
+                    type = ((DateTimeType) type).getDateTimeTypeWithoutZone();
+                }
+            }
+
+            row             = t.getEmptyRowData();
+            row[itype_name] = typeName;
+            row[idata_type] = ValuePool.getInt(type.getJDBCTypeCode());
+
+            long maxPrecision = type.getMaxPrecision();
+
+            row[iprecision] = maxPrecision > Integer.MAX_VALUE
+                              ? ValuePool.INTEGER_MAX
+                              : ValuePool.getInt((int) maxPrecision);
+
+            if (type.isBinaryType() || type.isCharacterType()
+                    || type.isDateTimeType() || type.isIntervalType()) {
+                row[iliteral_prefix] = "\'";
+                row[iliteral_suffix] = "\'";
+            }
+
+            if (type.acceptsPrecision() && type.acceptsScale()) {
+                row[icreate_params] = "PRECISION,SCALE";
+            } else if (type.acceptsPrecision()) {
+                row[icreate_params] = type.isNumberType() ? "PRECISION"
+                                                          : "LENGTH";
+            } else if (type.acceptsScale()) {
+                row[icreate_params] = "SCALE";
+            }
+
+            row[inullable] = ValuePool.INTEGER_1;
+            row[icase_sensitive] =
+                type.isCharacterType()
+                && type.typeCode != Types.VARCHAR_IGNORECASE ? Boolean.TRUE
+                                                             : Boolean.FALSE;
+
+            if (type.isLobType()) {
+                row[isearchable] = ValuePool.INTEGER_0;
+            } else if (type.isCharacterType()
+                       || (type.isBinaryType() && !type.isBitType())) {
+                row[isearchable] = ValuePool.getInt(3);
+            } else {
+                row[isearchable] = ValuePool.getInt(2);
+            }
+
+            row[iunsigned_attribute] = Boolean.FALSE;
+            row[ifixed_prec_scale] =
+                type.typeCode == Types.SQL_NUMERIC
+                || type.typeCode == Types.SQL_DECIMAL ? Boolean.TRUE
+                                                      : Boolean.FALSE;
+            row[iauto_increment]   = type.isIntegralType() ? Boolean.TRUE
+                                                           : Boolean.FALSE;
+            row[ilocal_type_name]  = null;
+            row[iminimum_scale]    = ValuePool.INTEGER_0;
+            row[imaximum_scale]    = ValuePool.getInt(type.getMaxScale());
+            row[isql_data_type]    = null;
+            row[isql_datetime_sub] = null;
+            row[inum_prec_radix] = ValuePool.getInt(type.getPrecisionRadix());
+
+            //------------------------------------------
+            if (type.isIntervalType()) {
+                row[iinterval_precision] = null;
+            }
+
+            t.insertSys(store, row);
+        }
+
+        row             = t.getEmptyRowData();
+        row[itype_name] = "DISTINCT";
+        row[idata_type] = ValuePool.getInt(Types.DISTINCT);
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the accessible
+     * user-defined types defined in this database. <p>
+     *
+     * Schema-specific UDTs may have type JAVA_OBJECT, STRUCT, or DISTINCT.
+     *
+     * <P>Each row is a UDT descripion with the following columns:
+     * <OL>
+     *   <LI><B>TYPE_CAT</B> <code>VARCHAR</code> => the type's catalog
+     *   <LI><B>TYPE_SCHEM</B> <code>VARCHAR</code> => type's schema
+     *   <LI><B>TYPE_NAME</B> <code>VARCHAR</code> => type name
+     *   <LI><B>CLASS_NAME</B> <code>VARCHAR</code> => Java class name
+     *   <LI><B>DATA_TYPE</B> <code>VARCHAR</code> =>
+     *         type value defined in <code>DITypes</code>;
+     *         one of <code>JAVA_OBJECT</code>, <code>STRUCT</code>, or
+     *        <code>DISTINCT</code>
+     *   <LI><B>REMARKS</B> <code>VARCHAR</code> =>
+     *          explanatory comment on the type
+     *   <LI><B>BASE_TYPE</B><code>SMALLINT</code> =>
+     *          type code of the source type of a DISTINCT type or the
+     *          type that implements the user-generated reference type of the
+     *          SELF_REFERENCING_COLUMN of a structured type as defined in
+     *          DITypes (null if DATA_TYPE is not DISTINCT or not
+     *          STRUCT with REFERENCE_GENERATION = USER_DEFINED)
+     *
+     * </OL> <p>
+     *
+     * @return a <code>Table</code> object describing the accessible
+     *      user-defined types defined in this database
+     */
+    Table SYSTEM_UDTS(Session session) {
+
+        Table t = sysTables[SYSTEM_UDTS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_UDTS]);
+
+            addColumn(t, "TYPE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "TYPE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "TYPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "CLASS_NAME", CHARACTER_DATA);
+            addColumn(t, "DATA_TYPE", Type.SQL_INTEGER);
+            addColumn(t, "REMARKS", CHARACTER_DATA);
+            addColumn(t, "BASE_TYPE", Type.SQL_SMALLINT);
+
+            //
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_UDTS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, null, false);
+
+            return t;
+        }
+
+        boolean translateDTI = database.getProperties().isPropertyTrue(
+            HsqlDatabaseProperties.jdbc_translate_dti_types);
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // column number mappings
+        final int type_catalog = 0;
+        final int type_schema  = 1;
+        final int type_name    = 2;
+        final int class_name   = 3;
+        final int data_type    = 4;
+        final int remarks      = 5;
+        final int base_type    = 6;
+        Iterator it =
+            database.schemaManager.databaseObjectIterator(SchemaObject.TYPE);
+
+        while (it.hasNext()) {
+            Type distinct = (Type) it.next();
+
+            if (!distinct.isDistinctType()) {
+                continue;
+            }
+
+            Object[] data = t.getEmptyRowData();
+            Type     type = distinct;
+
+            if (translateDTI) {
+                if (type.isIntervalType()) {
+                    type = CharacterType.getCharacterType(Types.SQL_VARCHAR,
+                                                          type.displaySize());
+                } else if (type.isDateTimeTypeWithZone()) {
+                    type = ((DateTimeType) type).getDateTimeTypeWithoutZone();
+                }
+            }
+
+            data[type_catalog] = database.getCatalogName().name;
+            data[type_schema]  = distinct.getSchemaName().name;
+            data[type_name]    = distinct.getName().name;
+            data[class_name]   = type.getJDBCClassName();
+            data[data_type]    = ValuePool.getInt(Types.DISTINCT);
+            data[remarks]      = null;
+            data[base_type]    = ValuePool.getInt(type.getJDBCTypeCode());
+
+            t.insertSys(store, data);
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the accessible
+     * columns that are automatically updated when any value in a row
+     * is updated. <p>
+     *
+     * Each row is a version column description with the following columns: <p>
+     *
+     * <OL>
+     * <LI><B>SCOPE</B> <code>SMALLINT</code> => is not used
+     * <LI><B>COLUMN_NAME</B> <code>VARCHAR</code> => column name
+     * <LI><B>DATA_TYPE</B> <code>SMALLINT</code> =>
+     *        SQL data type from java.sql.Types
+     * <LI><B>TYPE_NAME</B> <code>SMALLINT</code> =>
+     *       Data source dependent type name
+     * <LI><B>COLUMN_SIZE</B> <code>INTEGER</code> => precision
+     * <LI><B>BUFFER_LENGTH</B> <code>INTEGER</code> =>
+     *        length of column value in bytes
+     * <LI><B>DECIMAL_DIGITS</B> <code>SMALLINT</code> => scale
+     * <LI><B>PSEUDO_COLUMN</B> <code>SMALLINT</code> =>
+     *        is this a pseudo column like an Oracle <code>ROWID</code>:<BR>
+     *        (as defined in <code>java.sql.DatabaseMetadata</code>)
+     * <UL>
+     *    <LI><code>versionColumnUnknown</code> - may or may not be
+     *        pseudo column
+     *    <LI><code>versionColumnNotPseudo</code> - is NOT a pseudo column
+     *    <LI><code>versionColumnPseudo</code> - is a pseudo column
+     * </UL>
+     * </OL> <p>
+     *
+     * <B>Note:</B> Currently, the HSQLDB engine does not support version
+     * columns, so an empty table is returned. <p>
+     *
+     * @return a <code>Table</code> object describing the columns
+     *        that are automatically updated when any value
+     *        in a row is updated
+     */
+    Table SYSTEM_VERSIONCOLUMNS(Session session) {
+
+        Table t = sysTables[SYSTEM_VERSIONCOLUMNS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_VERSIONCOLUMNS]);
+
+            // ----------------------------------------------------------------
+            // required by DatabaseMetaData.getVersionColumns result set
+            // ----------------------------------------------------------------
+            addColumn(t, "SCOPE", Type.SQL_INTEGER);
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);         // not null
+            addColumn(t, "DATA_TYPE", Type.SQL_SMALLINT);        // not null
+            addColumn(t, "TYPE_NAME", SQL_IDENTIFIER);           // not null
+            addColumn(t, "COLUMN_SIZE", Type.SQL_SMALLINT);
+            addColumn(t, "BUFFER_LENGTH", Type.SQL_INTEGER);
+            addColumn(t, "DECIMAL_DIGITS", Type.SQL_SMALLINT);
+            addColumn(t, "PSEUDO_COLUMN", Type.SQL_SMALLINT);    // not null
+
+            // -----------------------------------------------------------------
+            // required by DatabaseMetaData.getVersionColumns filter parameters
+            // -----------------------------------------------------------------
+            addColumn(t, "TABLE_CAT", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);          // not null
+
+            // -----------------------------------------------------------------
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_VERSIONCOLUMNS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, null, false);
+
+            return t;
+        }
+
+        return t;
+    }
+
+    /**
+     * Retrieves a <code>Table</code> object describing the
+     * visible <code>Users</code> defined within this database.
+     * @return table containing information about the users defined within
+     *      this database
+     */
+    Table SYSTEM_USERS(Session session) {
+
+        Table t = sysTables[SYSTEM_USERS];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_USERS]);
+
+            addColumn(t, "USER_NAME", SQL_IDENTIFIER);
+            addColumn(t, "ADMIN", Type.SQL_BOOLEAN);
+            addColumn(t, "INITIAL_SCHEMA", SQL_IDENTIFIER);
+
+            // order: USER
+            // true PK
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_USERS].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // Intermediate holders
+        HsqlArrayList users;
+        User          user;
+        Object[]      row;
+        HsqlName      initialSchema;
+
+        // Initialization
+        users = database.getUserManager().listVisibleUsers(session);
+
+        // Do it.
+        for (int i = 0; i < users.size(); i++) {
+            row           = t.getEmptyRowData();
+            user          = (User) users.get(i);
+            initialSchema = user.getInitialSchema();
+            row[0]        = user.getNameString();
+            row[1]        = ValuePool.getBoolean(user.isAdmin());
+            row[2]        = ((initialSchema == null) ? null
+                                                     : initialSchema.name);
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+// -----------------------------------------------------------------------------
+// SQL SCHEMATA VIEWS
+// limited to views used in JDBC DatabaseMetaData
+
+    /**
+     * Retrieves a <code>Table</code> object describing the visible
+     * access rights for all visible columns of all accessible
+     * tables defined within this database.<p>
+     *
+     * Each row is a column privilege description with the following
+     * columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_CAT    VARCHAR   table catalog
+     * TABLE_SCHEM  VARCHAR   table schema
+     * TABLE_NAME   VARCHAR   table name
+     * COLUMN_NAME  VARCHAR   column name
+     * GRANTOR      VARCHAR   grantor of access
+     * GRANTEE      VARCHAR   grantee of access
+     * PRIVILEGE    VARCHAR   name of access
+     * IS_GRANTABLE VARCHAR   grantable?: "YES" - grant to others, else "NO"
+     * </pre>
+     *
+     * <b>Note:</b> From 1.9.0, HSQLDB supports column level
+     * privileges. <p>
+     *
+     * @return a <code>Table</code> object describing the visible
+     *        access rights for all visible columns of
+     *        all accessible tables defined within this
+     *        database
+     */
+    final Table COLUMN_PRIVILEGES(Session session) {
+
+        Table t = sysTables[COLUMN_PRIVILEGES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[COLUMN_PRIVILEGES]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);           // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);           // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);        // not null
+            addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);       // not null
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);    // not null
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);           // not null
+
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[COLUMN_PRIVILEGES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                2, 3, 4, 5, 6, 1, 0
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+// calculated column values
+        String  tableCatalog;
+        String  tableSchema;
+        String  tableName;
+        Grantee granteeObject;
+
+// intermediate holders
+        User     user;
+        Iterator tables;
+        Table    table;
+        Object[] row;
+
+// column number mappings
+        final int grantor        = 0;
+        final int grantee        = 1;
+        final int table_catalog  = 2;
+        final int table_schema   = 3;
+        final int table_name     = 4;
+        final int column_name    = 5;
+        final int privilege_type = 6;
+        final int is_grantable   = 7;
+
+        // enumerations
+        OrderedHashSet grantees =
+            session.getGrantee().getGranteeAndAllRolesWithPublic();
+
+// Initialization
+        tables = allTables();
+
+        while (tables.hasNext()) {
+            table        = (Table) tables.next();
+            tableName    = table.getName().name;
+            tableCatalog = database.getCatalogName().name;
+            tableSchema  = table.getSchemaName().name;
+
+            for (int i = 0; i < grantees.size(); i++) {
+                granteeObject = (Grantee) grantees.get(i);
+
+                OrderedHashSet rights =
+                    granteeObject.getAllDirectPrivileges(table);
+                OrderedHashSet grants =
+                    granteeObject.getAllGrantedPrivileges(table);
+
+                if (!grants.isEmpty()) {
+                    grants.addAll(rights);
+
+                    rights = grants;
+                }
+
+                for (int j = 0; j < rights.size(); j++) {
+                    Right right          = (Right) rights.get(j);
+                    Right grantableRight = right.getGrantableRights();
+
+                    for (int k = 0; k < Right.privilegeTypes.length; k++) {
+                        OrderedHashSet columnList =
+                            right.getColumnsForPrivilege(
+                                table, Right.privilegeTypes[k]);
+                        OrderedHashSet grantableList =
+                            grantableRight.getColumnsForPrivilege(table,
+                                Right.privilegeTypes[k]);
+
+                        for (int l = 0; l < columnList.size(); l++) {
+                            HsqlName fullName = ((HsqlName) columnList.get(l));
+
+                            row                 = t.getEmptyRowData();
+                            row[grantor] = right.getGrantor().getName().name;
+                            row[grantee] = right.getGrantee().getName().name;
+                            row[table_catalog]  = tableCatalog;
+                            row[table_schema]   = tableSchema;
+                            row[table_name]     = tableName;
+                            row[column_name]    = fullName.name;
+                            row[privilege_type] = Right.privilegeNames[k];
+                            row[is_grantable] =
+                                right.getGrantee() == table.getOwner()
+                                || grantableList.contains(fullName) ? "YES"
+                                                                    : "NO";
+
+                            try {
+                                t.insertSys(store, row);
+                            } catch (HsqlException e) {}
+                        }
+                    }
+                }
+            }
+        }
+
+        return t;
+    }
+
+    /**
+     * The SEQUENCES view has one row for each external sequence
+     * generator. <p>
+     *
+     * <b>Definition:</b> <p>
+     *
+     * <pre class="SqlCodeExample">
+     *
+     *      SEQUENCE_CATALOG     VARCHAR NULL,
+     *      SEQUENCE_SCHEMA      VARCHAR NULL,
+     *      SEQUENCE_NAME        VARCHAR NOT NULL,
+     *      DATA_TYPE            CHARACTER_DATA
+     *      DATA_TYPE            CHARACTER_DATA
+     *      NUMERIC_PRECISION    CARDINAL_NUMBER
+     *      NUMERIC_PRECISION_RADIX CARDINAL_NUMBER
+     *      NUMERIC_SCALE        CARDINAL_NUMBER
+     *      MAXIMUM_VALUE        VARCHAR NOT NULL,
+     *      MINIMUM_VALUE        VARCHAR NOT NULL,
+     *      INCREMENT            VARCHAR NOT NULL,
+     *      CYCLE_OPTION         VARCHAR {'YES', 'NO'},
+     *      START_WITH           VARCHAR NOT NULL,
+     *      DECLARED_DATA_TYPE   CHARACTER_DATA
+     *      DECLARED_NUMERIC_PRECISION CARDINAL_NUMBER
+     *      DECLARED_NUMERIC_SCLAE     CARDINAL_NUMBER
+     *
+     * </pre>
+     *
+     * <b>DESCRIPTION:</b><p>
+     *
+     * <ol>
+     * <li> The values of SEQUENCE_CATALOG, SEQUENCE_SCHEMA, and
+     *      SEQUENCE_NAME are the catalog name, unqualified schema name,
+     *      and qualified identifier, respectively, of the sequence generator
+     *      being described. <p>
+     *
+     * <li> The values of SEQUENCE_CATALOG, SEQUENCE_SCHEMA, SEQUENCE_NAME, and
+     *      DTD_IDENTIFIER are the values of OBJECT_CATALOG, OBJECT_SCHEMA,
+     *      OBJECT_NAME, and DTD_IDENTIFIER, respectively, of the row in
+     *      DATA_TYPE_DESCRIPTOR (not yet implemented) that describes the data
+     *      type of the sequence generator. <p>
+     *
+     * <li> The values of MAXIMUM_VALUE, MINIMUM_VALUE, and INCREMENT are the
+     *      character representations of maximum value, minimum value,
+     *      and increment, respectively, of the sequence generator being
+     *      described. <p>
+     *
+     * <li> The values of CYCLE_OPTION have the following meanings: <p>
+     *
+     *      <table border cellpadding="3">
+     *          <tr>
+     *              <td nowrap>YES</td>
+     *              <td nowrap>The cycle option of the sequence generator
+     *                         is CYCLE.</td>
+     *          <tr>
+     *              <td nowrap>NO</td>
+     *              <td nowrap>The cycle option of the sequence generator is
+     *                         NO CYCLE.</td>
+     *          </tr>
+     *      </table> <p>
+     *
+     * <li> The value of START_WITH is HSQLDB-specific (not in the SQL 200n
+     *      spec).  <p>
+     *
+     *      It is the character representation of the START WITH value. <p>
+     *
+     * <li> The value of NEXT_VALUE is HSQLDB-specific (not in the SQL 200n)<p>
+     *      This is the character representation of the value that
+     *      would be generated by NEXT VALUE FOR when this sequence
+     *      is materialized in an SQL statement. <p>
+     * </ol>
+     *
+     * @return Table
+     */
+    final Table SEQUENCES(Session session) {
+
+        Table t = sysTables[SEQUENCES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SEQUENCES]);
+
+            addColumn(t, "SEQUENCE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "MAXIMUM_VALUE", CHARACTER_DATA);
+            addColumn(t, "MINIMUM_VALUE", CHARACTER_DATA);
+            addColumn(t, "INCREMENT", CHARACTER_DATA);
+            addColumn(t, "CYCLE_OPTION", YES_OR_NO);
+            addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_NUMERIC_SCLAE", CARDINAL_NUMBER);
+
+            // HSQLDB-specific
+            addColumn(t, "START_WITH", CHARACTER_DATA);
+            addColumn(t, "NEXT_VALUE", CHARACTER_DATA);
+
+            // order SEQUENCE_CATALOG, SEQUENCE_SCHEMA, SEQUENCE_NAME
+            // false PK, as CATALOG may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SEQUENCES].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        //
+        final int sequence_catalog           = 0;
+        final int sequence_schema            = 1;
+        final int sequence_name              = 2;
+        final int data_type                  = 3;
+        final int numeric_precision          = 4;
+        final int numeric_precision_radix    = 5;
+        final int numeric_scale              = 6;
+        final int maximum_value              = 7;
+        final int minimum_value              = 8;
+        final int increment                  = 9;
+        final int cycle_option               = 10;
+        final int declared_data_type         = 11;
+        final int declared_numeric_precision = 12;
+        final int declared_numeric_scale     = 13;
+        final int start_with                 = 14;
+        final int next_value                 = 15;
+
+        //
+        Iterator       it;
+        Object[]       row;
+        NumberSequence sequence;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.SEQUENCE);
+
+        while (it.hasNext()) {
+            sequence = (NumberSequence) it.next();
+
+            if (!session.getGrantee().isAccessible(sequence)) {
+                continue;
+            }
+
+            row = t.getEmptyRowData();
+
+            NumberType type = (NumberType) sequence.getDataType();
+            int radix =
+                (type.typeCode == Types.SQL_NUMERIC || type.typeCode == Types
+                    .SQL_DECIMAL) ? 10
+                                  : 2;
+
+            row[sequence_catalog] = database.getCatalogName().name;
+            row[sequence_schema]  = sequence.getSchemaName().name;
+            row[sequence_name]    = sequence.getName().name;
+            row[data_type]        = sequence.getDataType().getFullNameString();
+            row[numeric_precision] =
+                ValuePool.getInt((int) type.getPrecision());
+            row[numeric_precision_radix]    = ValuePool.getInt(radix);
+            row[numeric_scale]              = ValuePool.INTEGER_0;
+            row[maximum_value] = String.valueOf(sequence.getMaxValue());
+            row[minimum_value] = String.valueOf(sequence.getMinValue());
+            row[increment] = String.valueOf(sequence.getIncrement());
+            row[cycle_option]               = sequence.isCycle() ? "YES"
+                                                                 : "NO";
+            row[declared_data_type]         = row[data_type];
+            row[declared_numeric_precision] = row[numeric_precision];
+            row[declared_numeric_scale]     = row[declared_numeric_scale];
+            row[start_with] = String.valueOf(sequence.getStartValue());
+            row[next_value]                 = String.valueOf(sequence.peek());
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+    final Table SYSTEM_SEQUENCES(Session session) {
+
+        Table t = sysTables[SYSTEM_SEQUENCES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[SYSTEM_SEQUENCES]);
+
+            addColumn(t, "SEQUENCE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "SEQUENCE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
+            addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
+            addColumn(t, "MAXIMUM_VALUE", CHARACTER_DATA);
+            addColumn(t, "MINIMUM_VALUE", CHARACTER_DATA);
+            addColumn(t, "INCREMENT", CHARACTER_DATA);
+            addColumn(t, "CYCLE_OPTION", YES_OR_NO);
+            addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
+            addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
+            addColumn(t, "DECLARED_NUMERIC_SCLAE", CARDINAL_NUMBER);
+
+            // HSQLDB-specific
+            addColumn(t, "START_WITH", CHARACTER_DATA);
+            addColumn(t, "NEXT_VALUE", CHARACTER_DATA);
+
+            // order SEQUENCE_CATALOG, SEQUENCE_SCHEMA, SEQUENCE_NAME
+            // false PK, as CATALOG may be null
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SYSTEM_SEQUENCES].name, false,
+                SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        //
+        final int sequence_catalog           = 0;
+        final int sequence_schema            = 1;
+        final int sequence_name              = 2;
+        final int data_type                  = 3;
+        final int numeric_precision          = 4;
+        final int numeric_precision_radix    = 5;
+        final int numeric_scale              = 6;
+        final int maximum_value              = 7;
+        final int minimum_value              = 8;
+        final int increment                  = 9;
+        final int cycle_option               = 10;
+        final int declared_data_type         = 11;
+        final int declared_numeric_precision = 12;
+        final int declared_numeric_scale     = 13;
+        final int start_with                 = 14;
+        final int next_value                 = 15;
+
+        //
+        Iterator       it;
+        Object[]       row;
+        NumberSequence sequence;
+
+        it = database.schemaManager.databaseObjectIterator(
+            SchemaObject.SEQUENCE);
+
+        while (it.hasNext()) {
+            sequence = (NumberSequence) it.next();
+
+            if (!session.getGrantee().isAccessible(sequence)) {
+                continue;
+            }
+
+            row = t.getEmptyRowData();
+
+            NumberType type = (NumberType) sequence.getDataType();
+            int radix =
+                (type.typeCode == Types.SQL_NUMERIC || type.typeCode == Types
+                    .SQL_DECIMAL) ? 10
+                                  : 2;
+
+            row[sequence_catalog] = database.getCatalogName().name;
+            row[sequence_schema]  = sequence.getSchemaName().name;
+            row[sequence_name]    = sequence.getName().name;
+            row[data_type]        = sequence.getDataType().getFullNameString();
+            row[numeric_precision] =
+                ValuePool.getInt((int) type.getPrecision());
+            row[numeric_precision_radix]    = ValuePool.getInt(radix);
+            row[numeric_scale]              = ValuePool.INTEGER_0;
+            row[maximum_value] = String.valueOf(sequence.getMaxValue());
+            row[minimum_value] = String.valueOf(sequence.getMinValue());
+            row[increment] = String.valueOf(sequence.getIncrement());
+            row[cycle_option]               = sequence.isCycle() ? "YES"
+                                                                 : "NO";
+            row[declared_data_type]         = row[data_type];
+            row[declared_numeric_precision] = row[numeric_precision];
+            row[declared_numeric_scale]     = row[declared_numeric_scale];
+            row[start_with] = String.valueOf(sequence.getStartValue());
+            row[next_value]                 = String.valueOf(sequence.peek());
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+/*
+    WHERE ( GRANTEE IN ( 'PUBLIC', CURRENT_USER )
+    OR GRANTEE IN ( SELECT ROLE_NAME FROM ENABLED_ROLES )
+    OR GRANTOR = CURRENT_USER
+    OR GRANTOR IN ( SELECT ROLE_NAME FROM ENABLED_ROLES ) )
+
+*/
+
+/**
+     * The TABLE_PRIVILEGES view has one row for each visible access
+     * right for each accessible table definied within this database. <p>
+     *
+     * Each row is a table privilege description with the following columns: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * GRANTOR      VARCHAR   grantor of access
+     * GRANTEE      VARCHAR   grantee of access
+     * TABLE_CATALOG    VARCHAR   table catalog
+     * TABLE_SCHEMA  VARCHAR   table schema
+     * TABLE_NAME   VARCHAR   table name
+     * PRIVILEGE_TYPE    VARCHAR   { "SELECT" | "INSERT" | "UPDATE" | "DELETE" | "REFERENCES" | "TRIGGER" }
+     * IS_GRANTABLE VARCHAR   { "YES" | "NO" }
+     * WITH_HIERARCHY   { "YES" | "NO" }
+     * </pre>
+     *
+     * @return a <code>Table</code> object describing the visible
+     *        access rights for each accessible table
+     *        defined within this database
+     */
+    final Table TABLE_PRIVILEGES(Session session) {
+
+        Table t = sysTables[TABLE_PRIVILEGES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TABLE_PRIVILEGES]);
+
+            addColumn(t, "GRANTOR", SQL_IDENTIFIER);           // not null
+            addColumn(t, "GRANTEE", SQL_IDENTIFIER);           // not null
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);        // not null
+            addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);    // not null
+            addColumn(t, "IS_GRANTABLE", YES_OR_NO);           // not null
+            addColumn(t, "WITH_HIERARCHY", YES_OR_NO);
+
+            //
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[SEQUENCES].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2, 3, 4, 5, 6
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // calculated column values
+        String  tableCatalog;
+        String  tableSchema;
+        String  tableName;
+        Grantee granteeObject;
+        String  privilege;
+
+        // intermediate holders
+        Iterator tables;
+        Table    table;
+        Object[] row;
+
+        // column number mappings
+        final int grantor        = 0;
+        final int grantee        = 1;
+        final int table_catalog  = 2;
+        final int table_schema   = 3;
+        final int table_name     = 4;
+        final int privilege_type = 5;
+        final int is_grantable   = 6;
+        final int with_hierarchy = 7;
+        OrderedHashSet grantees =
+            session.getGrantee().getGranteeAndAllRolesWithPublic();
+
+        tables = allTables();
+
+        while (tables.hasNext()) {
+            table        = (Table) tables.next();
+            tableName    = table.getName().name;
+            tableCatalog = table.getCatalogName().name;
+            tableSchema  = table.getSchemaName().name;
+
+            for (int i = 0; i < grantees.size(); i++) {
+                granteeObject = (Grantee) grantees.get(i);
+
+                OrderedHashSet rights =
+                    granteeObject.getAllDirectPrivileges(table);
+                OrderedHashSet grants =
+                    granteeObject.getAllGrantedPrivileges(table);
+
+                if (!grants.isEmpty()) {
+                    grants.addAll(rights);
+
+                    rights = grants;
+                }
+
+                for (int j = 0; j < rights.size(); j++) {
+                    Right right          = (Right) rights.get(j);
+                    Right grantableRight = right.getGrantableRights();
+
+                    for (int k = 0; k < Right.privilegeTypes.length; k++) {
+                        if (!right.canAccessFully(Right.privilegeTypes[k])) {
+                            continue;
+                        }
+
+                        privilege           = Right.privilegeNames[k];
+                        row                 = t.getEmptyRowData();
+                        row[grantor] = right.getGrantor().getName().name;
+                        row[grantee] = right.getGrantee().getName().name;
+                        row[table_catalog]  = tableCatalog;
+                        row[table_schema]   = tableSchema;
+                        row[table_name]     = tableName;
+                        row[privilege_type] = privilege;
+                        row[is_grantable] =
+                            right.getGrantee() == table.getOwner()
+                            || grantableRight.canAccessFully(
+                                Right.privilegeTypes[k]) ? "YES"
+                                                         : "NO";
+                        row[with_hierarchy] = "NO";
+
+                        try {
+                            t.insertSys(store, row);
+                        } catch (HsqlException e) {}
+                    }
+                }
+            }
+        }
+
+        return t;
+    }
+
+    Table TABLES(Session session) {
+
+        Table t = sysTables[TABLES];
+
+        if (t == null) {
+            t = createBlankTable(sysTableHsqlNames[TABLES]);
+
+            addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "TABLE_TYPE", CHARACTER_DATA);
+            addColumn(t, "SELF_REFERENCING_COLUMN_NAME", SQL_IDENTIFIER);
+            addColumn(t, "REFERENCE_GENERATION", CHARACTER_DATA);
+            addColumn(t, "USER_DEFINED_TYPE_CATALOG", SQL_IDENTIFIER);
+            addColumn(t, "USER_DEFINED_TYPE_SCHEMA", SQL_IDENTIFIER);
+            addColumn(t, "USER_DEFINED_TYPE_NAME", SQL_IDENTIFIER);
+            addColumn(t, "IS_INSERTABLE_INTO", YES_OR_NO);
+            addColumn(t, "IS_TYPED", YES_OR_NO);
+            addColumn(t, "COMMIT_ACTION", CHARACTER_DATA);
+
+            //
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[TABLES].name, false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[] {
+                0, 1, 2,
+            }, false);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+
+        // intermediate holders
+        Iterator  tables;
+        Table     table;
+        Object[]  row;
+        final int table_catalog                = 0;
+        final int table_schema                 = 1;
+        final int table_name                   = 2;
+        final int table_type                   = 3;
+        final int self_referencing_column_name = 4;
+        final int reference_generation         = 5;
+        final int user_defined_type_catalog    = 6;
+        final int user_defined_type_schema     = 7;
+        final int user_defined_type_name       = 8;
+        final int is_insertable_into           = 9;
+        final int is_typed                     = 10;
+        final int commit_action                = 11;
+
+        // Initialization
+        tables = allTables();
+
+        // Do it.
+        while (tables.hasNext()) {
+            table = (Table) tables.next();
+
+            if (!isAccessibleTable(session, table)) {
+                continue;
+            }
+
+            row                = t.getEmptyRowData();
+            row[table_catalog] = database.getCatalogName().name;
+            row[table_schema]  = table.getSchemaName().name;
+            row[table_name]    = table.getName().name;
+
+            switch (table.getTableType()) {
+
+                case TableBase.SYSTEM_TABLE :
+                case TableBase.VIEW_TABLE :
+                    row[table_type]         = "VIEW";
+                    row[is_insertable_into] = "NO";
+                    break;
+
+                case TableBase.TEMP_TABLE :
+                case TableBase.TEMP_TEXT_TABLE :
+                    row[table_type]         = "GLOBAL TEMPORARY";
+                    row[is_insertable_into] = "YES";
+                    break;
+
+                default :
+                    row[table_type]         = "BASE TABLE";
+                    row[is_insertable_into] = table.isWritable() ? "YES"
+                                                                 : "NO";
+                    break;
+            }
+
+            row[self_referencing_column_name] = null;
+            row[reference_generation]         = null;
+            row[user_defined_type_catalog]    = null;
+            row[user_defined_type_schema]     = null;
+            row[user_defined_type_name]       = null;
+            row[is_typed]                     = "NO";
+            row[commit_action] = table.isTemp()
+                                 ? (table.onCommitPreserve() ? "PRESERVE"
+                                                             : "DELETE")
+                                 : null;
+
+            t.insertSys(store, row);
+        }
+
+        return t;
+    }
+
+// -----------------------------------------------------------------------------
+// SQL SCHEMATA BASE TABLE
+
+    /**
+     * Retrieves a <code>Table</code> object naming the accessible catalogs
+     * defined within this database. <p>
+     *
+     * Each row is a catalog name description with the following column: <p>
+     *
+     * <pre class="SqlCodeExample">
+     * TABLE_CAT   VARCHAR   catalog name
+     * </pre> <p>
+     *
+     * @return a <code>Table</code> object naming the accessible
+     *        catalogs defined within this database
+     */
+    final Table INFORMATION_SCHEMA_CATALOG_NAME(Session session) {
+
+        Table t = sysTables[INFORMATION_SCHEMA_CATALOG_NAME];
+
+        if (t == null) {
+            t = createBlankTable(
+                sysTableHsqlNames[INFORMATION_SCHEMA_CATALOG_NAME]);
+
+            addColumn(t, "CATALOG_NAME", SQL_IDENTIFIER);    // not null
+
+            // order:  TABLE_CAT
+            // true PK
+            HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
+                sysTableHsqlNames[INFORMATION_SCHEMA_CATALOG_NAME].name,
+                false, SchemaObject.INDEX);
+
+            t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
+
+            return t;
+        }
+
+        PersistentStore store = session.sessionData.getRowStore(t);
+        Object[]        row   = t.getEmptyRowData();
+
+        row[0] = database.getCatalogName().name;
+
+        t.insertSys(store, row);
+
+        return t;
+    }
+}
diff --git a/src/org/hsqldb/error/Error.java b/src/org/hsqldb/error/Error.java
new file mode 100644
index 0000000..73eb858
--- /dev/null
+++ b/src/org/hsqldb/error/Error.java
@@ -0,0 +1,289 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.error;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.resources.BundleHandler;
+import org.hsqldb.result.Result;
+
+/**
+ * Contains static factory methods to produce instances of HsqlException
+ *
+ * @author Loic Lefevre
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class Error {
+
+    //
+    public static boolean TRACE          = false;
+    public static boolean TRACESYSTEMOUT = false;
+
+    //
+    private static final String errPropsName = "sql-state-messages";
+    private static final int bundleHandle =
+        BundleHandler.getBundleHandle(errPropsName, null);
+    private static final String MESSAGE_TAG      = "$$";
+    private static final int    SQL_STATE_DIGITS = 5;
+    private static final int    SQL_CODE_DIGITS  = 4;
+    private static final int    ERROR_CODE_BASE  = 11;
+
+    public static RuntimeException runtimeError(int code, String add) {
+
+        HsqlException e = error(code, add);
+
+        return new RuntimeException(e.getMessage());
+    }
+
+    public static HsqlException error(int code, String add) {
+
+        String s = getMessage(code);
+
+        if (add != null) {
+            s += ": " + add.toString();
+        }
+
+        return new HsqlException(null, s.substring(SQL_STATE_DIGITS + 1),
+                                 s.substring(0, SQL_STATE_DIGITS), -code);
+    }
+
+    public static HsqlException parseError(int code, String add,
+                                           int lineNumber) {
+
+        String s = getMessage(code);
+
+        if (add != null) {
+            s = s + ": " + add;
+        }
+
+        if (lineNumber > 1) {
+            add = getMessage(ErrorCode.M_parse_line);
+            s = s + " :" + add + String.valueOf(lineNumber);
+        }
+
+        return new HsqlException(null, s.substring(SQL_STATE_DIGITS + 1),
+                                 s.substring(0, SQL_STATE_DIGITS),
+                                 -code);
+    }
+
+    public static HsqlException error(int code) {
+        return error(null, code, 0, null);
+    }
+
+    public static HsqlException error(int code, Throwable t) {
+
+        String message = getMessage(code, 0, null);
+
+        return new HsqlException(t, message.substring(0, SQL_STATE_DIGITS),
+                                 -code);
+    }
+
+    /**
+     * Compose error message by inserting the strings in the add parameters
+     * in placeholders within the error message. The message string contains
+     * $$ markers for each context variable. Context variables are supplied in
+     * the add parameters.
+     *
+     * @param code      main error code
+     * @param subCode   sub error code (if 0 => no subMessage!)
+     * @param   add     optional parameters
+     *
+     * @return an <code>HsqlException</code>
+     */
+    public static HsqlException error(Throwable t, int code, int subCode,
+                                      final Object[] add) {
+
+        String message = getMessage(code, subCode, add);
+        int    sqlCode = subCode < ERROR_CODE_BASE ? code
+                                                   : subCode;
+
+        return new HsqlException(t, message.substring(SQL_STATE_DIGITS + 1),
+                                 message.substring(0, SQL_STATE_DIGITS),
+                                 -sqlCode);
+    }
+
+    public static HsqlException parseError(int code, int subCode,
+                                           int lineNumber,
+                                           final Object[] add) {
+
+        String message = getMessage(code, subCode, add);
+
+        if (lineNumber > 1) {
+            String sub = getMessage(ErrorCode.M_parse_line);
+
+            message = message + " :" + sub + String.valueOf(lineNumber);
+        }
+
+        int sqlCode = subCode < ERROR_CODE_BASE ? code
+                                                : subCode;
+
+        return new HsqlException(null,
+                                 message.substring(SQL_STATE_DIGITS + 1),
+                                 message.substring(0, SQL_STATE_DIGITS),
+                                 -sqlCode);
+    }
+
+    public static HsqlException error(int code, int code2) {
+        return error(code, getMessage(code2));
+    }
+
+    /**
+     * Compose error
+     * in placeholders within the error message. The message string contains
+     * $$ markers for each context variable. Context variables are supplied in
+     * the add parameters.
+     *
+     * @see HsqlException#HsqlException(String, String, int)
+     * @return an <code>HsqlException</code>
+     */
+    public static HsqlException error(String message, String sqlState, int i) {
+        return new HsqlException(null, message, sqlState, i);
+    }
+
+    /**
+     * Compose error message by inserting the strings in the add variables
+     * in placeholders within the error message. The message string contains
+     * $$ markers for each context variable. Context variables are supplied in
+     * the add parameter. (by Loic Lefevre)
+     *
+     * @param message  message string
+     * @param add      optional parameters
+     *
+     * @return an <code>HsqlException</code>
+     */
+    private static String insertStrings(String message, Object[] add) {
+
+        StringBuffer sb        = new StringBuffer(message.length() + 32);
+        int          lastIndex = 0;
+        int          escIndex  = message.length();
+
+        // removed test: i < add.length
+        // because if mainErrorMessage is equal to "blabla $$"
+        // then the statement escIndex = mainErrorMessage.length();
+        // is never reached!  ???
+        for (int i = 0; i < add.length; i++) {
+            escIndex = message.indexOf(MESSAGE_TAG, lastIndex);
+
+            if (escIndex == -1) {
+                break;
+            }
+
+            sb.append(message.substring(lastIndex, escIndex));
+            sb.append(add[i] == null ? "null exception message"
+                                     : add[i].toString());
+
+            lastIndex = escIndex + MESSAGE_TAG.length();
+        }
+
+        escIndex = message.length();
+
+        sb.append(message.substring(lastIndex, escIndex));
+
+        return sb.toString();
+    }
+
+    /**
+     * Returns the error message given the error code.<br/>
+     * This method is be used when throwing exception other
+     * than <code>HsqlException</code>.
+     *
+     * @param errorCode    the error code associated to the error message
+     * @return  the error message associated with the error code
+     */
+    public static String getMessage(final int errorCode) {
+        return getResourceString(errorCode);
+
+    }
+
+    /**
+     * Returns the error SQL STATE sting given the error code.<br/>
+     * This method is be used when throwing exception based on other exceptions.
+     *
+     * @param errorCode    the error code associated to the error message
+     * @return  the error message associated with the error code
+     */
+    public static String getStateString(final int errorCode) {
+        return getMessage(errorCode, 0, null).substring(0, SQL_STATE_DIGITS);
+    }
+
+    /**
+     * Returns the error message given the error code.<br/> This method is used
+     * when throwing exception other than <code>HsqlException</code>.
+     *
+     * @param code the code for the error message
+     * @param subCode the code for the addon message
+     * @param add value(s) to use to replace the placeholer(s)
+     * @return the error message associated with the error code
+     */
+    public static String getMessage(final int code, int subCode,
+                                    final Object[] add) {
+
+        String message = getResourceString(code);
+
+        if (subCode != 0) {
+            message += getResourceString(subCode);
+        }
+
+        if (add != null) {
+            message = insertStrings(message, add);
+        }
+
+        return message;
+    }
+
+    private static String getResourceString(int code) {
+
+        String key = StringUtil.toZeroPaddedString(code, SQL_CODE_DIGITS,
+            SQL_CODE_DIGITS);
+
+        return BundleHandler.getString(bundleHandle, key);
+    }
+
+    public static HsqlException error(final Result result) {
+        return new HsqlException(result);
+    }
+
+    /**
+     * Used to print messages to System.out
+     *
+     *
+     * @param message message to print
+     */
+    public static void printSystemOut(String message) {
+
+        if (TRACESYSTEMOUT) {
+            System.out.println(message);
+        }
+    }
+}
diff --git a/src/org/hsqldb/error/ErrorCode.java b/src/org/hsqldb/error/ErrorCode.java
new file mode 100644
index 0000000..9a82903
--- /dev/null
+++ b/src/org/hsqldb/error/ErrorCode.java
@@ -0,0 +1,681 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.error;
+
+/**
+ * SQL error codes.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface ErrorCode {
+
+    // neutral placeholder strings
+    int TOKEN_REQUIRED = 1;                        // $$ required: $$
+    int CONSTRAINT     = 2;                        // $$ table: $$
+
+    //
+    int M_ERROR_IN_BINARY_SCRIPT_1 = 21;           // \u0020table $$ row count error : $$ read, needed $$
+    int M_ERROR_IN_BINARY_SCRIPT_2 = 22;           // \u0020 wrong data for insert operation
+    int M_DatabaseManager_getDatabase = 23;        // attempt to connect while db opening /closing
+    int M_parse_line                = 24;          // \u0020line:\u0020
+    int M_DatabaseScriptReader_read = 25;          // \u0020line: $$ $$
+    int M_Message_Pair              = 26;          // \u0020$$ $$
+    int M_LOAD_SAVE_PROPERTIES      = 27;          // \u0020$$.properties $$
+    int M_HsqlProperties_load       = 28;          // properties name is null or empty
+
+    //
+    int M_TEXT_SOURCE_FIELD_ERROR       = 41;      // Error in text source field
+    int M_TextCache_openning_file_error = 42;      // openning file: $$ error: $$
+    int M_TextCache_closing_file_error  = 43;      // closing file: $$ error: $$
+    int M_TextCache_purging_file_error  = 44;      // purging file: $$ error: $$
+
+    //
+    int M_DataFileCache_makeRow = 51;              // error $$ reading row - file $$
+    int M_DataFileCache_open    = 52;              // error $$ opening file - file $$
+    int M_DataFileCache_close   = 53;              // error $$ closing file - file $$
+
+    //
+    int M_SERVER_OPEN_SERVER_SOCKET_1 = 61;        // Invalid address : $$\nTry one of: $$
+    int M_SERVER_OPEN_SERVER_SOCKET_2 = 62;        // Invalid address : $$
+    int M_SERVER_SECURE_VERIFY_1      = 63;        // Server certificate has no Common Name
+    int M_SERVER_SECURE_VERIFY_2      = 64;        // Server certificate has empty Common Name
+    int M_SERVER_SECURE_VERIFY_3 = 65;             // Certificate Common Name[$$] does not match host name[$$]
+
+    //
+    int M_RS_EMPTY        = 70;                    // ResultSet is empty
+    int M_RS_BEFORE_FIRST = 71;                    // ResultSet is positioned before first row
+    int M_RS_AFTER_LAST   = 72;                    // ResultSet is positioned after last row
+
+    //
+    int M_INVALID_LIMIT = 81;                      // ; in LIMIT, OFFSET or FETCH
+
+    // SQLSTATE definitions
+    // successful completion
+    int S_00000 = 0000;                            // successful completion
+
+    //
+    int U_S0500 = 201;
+    int X_S0501 = 301;                             // no file name specified for source // TEXT_TABLE_SOURCE_FILENAME = 172
+    int X_S0502 = 302;                             // no value specified for field // TEXT_TABLE_SOURCE_VALUE_MISSING= 173
+    int X_S0503 = 303;                             // zero-length separator // TEXT_TABLE_SOURCE_SEPARATOR = 174
+    int X_S0504 = 304;
+    int X_S0521 = 320;                             // operation is not allowed on text table with data
+    int X_S0522 = 321;                             // invalid statemnet - text table required
+    int X_S0531 = 331;                             // encode / decode error:
+
+    // HSQLDB Server
+    int SERVER_TRANSFER_CORRUPTED    = 401;        // S1000 Transfer corrupted
+    int SERVER_DATABASE_DISCONNECTED = 402;        // S0504 database disconnected
+    int SERVER_VERSIONS_INCOMPATIBLE = 403;        // S0504 Client version '$$' incompatible.
+    int SERVER_UNKNOWN_CLIENT = 404;               // S0504 Network client is not a HSQLDB JDBC driver
+    int SERVER_HTTP_NOT_HSQL_PROTOCOL = 405;       // S0504 Client using HSQLDB http protocol instead of hsql
+    int SERVER_INCOMPLETE_HANDSHAKE_READ = 406;    // S0504 Incomplete read of handshaking bytes
+    int SERVER_NO_DATABASE = 407;                  // S1000 no valid database paths
+
+    //
+    // HSQLDB JDBC
+    int JDBC_COLUMN_NOT_FOUND      = 421;          // S1000 Column not found
+    int JDBC_INPUTSTREAM_ERROR     = 422;          // S1000 InputStream error
+    int JDBC_INVALID_ARGUMENT      = 423;          // S1OO0 Invalid argument in JDBC call
+    int JDBC_PARAMETER_NOT_SET     = 424;          // S1000 Parameter not set
+    int JDBC_CONNECTION_NATIVE_SQL = 425;          // S1000 Unknown JDBC escape sequence: {
+
+    // HSQLDB non-core and file errors
+    int LOCK_FILE_ACQUISITION_FAILURE = 451;       // S1000 Database lock acquisition failure
+    int FILE_IO_ERROR               = 452;         // S1000 File input/output error
+    int WRONG_DATABASE_FILE_VERSION = 453;         // S1000 unsupported database file version
+    int SHUTDOWN_REQUIRED           = 454;         // S1000 old version database must be shutdown
+    int DATABASE_IS_READONLY        = 455;         // S1000 The database is in read only mode
+    int DATA_IS_READONLY            = 456;         // S1000 The table data is read only
+    int ACCESS_IS_DENIED            = 457;         // S1000 Access is denied
+    int GENERAL_ERROR               = 458;         // S1000 General error
+    int DATABASE_IS_MEMORY_ONLY     = 459;         // S1000 Database is memory only
+    int OUT_OF_MEMORY               = 460;         // S1000 Out of Memory
+    int ERROR_IN_SCRIPT_FILE        = 461;         // S1000 error in script file
+    int UNSUPPORTED_FILENAME_SUFFIX = 462;         // S1000 Unsupported suffix in file name '$$'.  (Supported suffixes:  $$)
+    int COMPRESSION_SUFFIX_MISMATCH = 463;         // S1000 Mismatch between specified compression mode '$$' and file name '$$'
+    int DATABASE_IS_NON_FILE = 464;                // S1000 Database is non-file type
+    int DATABASE_NOT_EXISTS  = 465;                // S1000 Database does not exists
+    int DATA_FILE_ERROR      = 466;                // S1000 Data File input/output error
+    int GENERAL_IO_ERROR     = 467;                // S1000 IO error
+    int DATA_FILE_IS_FULL    = 468;                // S1000 Data file size limit is reached
+    int DATA_FILE_IN_USE     = 469;                // S1000 Data file is in use
+
+    // HSQLDB Text tables
+    int TEXT_TABLE_UNKNOWN_DATA_SOURCE = 481;      // S1000 The table's data source for has not been defined
+    int TEXT_TABLE_SOURCE = 482;                   // S1000 Invalid TEXT table source string
+    int TEXT_FILE         = 483;                   // S1000 bad TEXT table source file - line number: $$ $$
+    int TEXT_FILE_IO            = 484;             // S1000 TEXT table source file - IO error:
+    int TEXT_STRING_HAS_NEWLINE = 485;             // S1000 end-of-line characters not allowed
+    int TEXT_TABLE_HEADER            = 486;        // S1000 Header not allowed or too long
+    int TEXT_SOURCE_EXISTS           = 487;        // S1000 Text source file already exists
+    int TEXT_SOURCE_NO_END_SEPARATOR = 488;        // S1000 No end sep.
+
+    // warning
+    int W_01000 = 1000;                            // warning - generic
+    int W_01001 = 1001;                            // cursor operation conflict - 200x
+    int W_01002 = 1002;                            // disconnect error - 200x
+    int W_01003 = 1003;                            // null value eliminated in set function - 200x
+    int W_01004 = 1004;                            // string data, right truncation - 200x
+    int W_01005 = 1005;                            // insufficient item descriptor areas - 200x
+    int W_01006 = 1006;                            // privilege not revoked - 200x
+    int W_01007 = 1007;                            // privilege not granted - 200x
+    int W_01009 = 1009;                            // search condition too long for information schema - 200x
+    int W_0100A = 1010;                            // query expression too long for information schema - 200x
+    int W_0100B = 1011;                            // default value too long for information schema - 200x
+    int W_0100C = 1012;                            // result sets returned - 200x
+    int W_0100D = 1013;                            // additional result sets returned - 200x
+    int W_0100E = 1014;                            // attempt to return too many result sets - 200x
+    int W_0100F = 1015;                            // statement too long for information schema - 200x
+    int W_01011 = 1016;                            // SQL-Java path too long for information schema
+    int W_0102F = 1017;                            // array data, right truncation - 200x
+
+    // no data - 200x
+    int N_02000 = 1100;                            // no data - generic
+    int N_02001 = 1101;                            // no data: no additional result sets returned
+
+    // dynamic SQL error - 200x
+    int X_07000 = 1200;                            // dynamic SQL error
+    int X_07001 = 1201;                            // dynamic SQL error: using clause does not match dynamic parameter specifications
+    int X_07002 = 1202;                            // dynamic SQL error: using clause does not match target specifications
+    int X_07003 = 1203;                            // dynamic SQL error: cursor specification cannot be executed
+    int X_07004 = 1204;                            // dynamic SQL error: using clause required for dynamic parameters
+    int X_07005 = 1205;                            // dynamic SQL error: prepared statement not a cursor specification
+    int X_07006 = 1206;                            // dynamic SQL error: restricted data type attribute violation
+    int X_07007 = 1207;                            // dynamic SQL error: using clause required for result fields
+    int X_07008 = 1208;                            // dynamic SQL error: invalid descriptor count
+    int X_07009 = 1209;                            // dynamic SQL error: invalid descriptor index
+    int X_0700B = 1211;                            // dynamic SQL error: data type transform function violation
+    int X_0700C = 1212;                            // dynamic SQL error: undefined DATA value
+    int X_0700D = 1213;                            // dynamic SQL error: invalid DATA target
+    int X_0700E = 1214;                            // dynamic SQL error: invalid LEVEL value
+    int X_0700F = 1215;                            // dynamic SQL error: invalid DATETIME_INTERVAL_CODE
+
+    // HSQLDB
+    int X_07501 = 1251;                            // statement is closed
+    int X_07502 = 1252;                            // statement is invalid
+    int X_07503 = 1253;                            // statement generates a result set
+    int X_07504 = 1254;                            // statement does not generate a result set
+    int X_07505 = 1255;                            // statement is in batch mode
+    int X_07506 = 1256;                            // statement is not in batch mode
+
+    // connection exception - 200x
+    int X_08000 = 1300;                            // connection exception
+    int X_08001 = 1301;                            // connection exception: SQL-client unable to establish SQL-connection
+    int X_08002 = 1302;                            // connection exception: connection name in use
+    int X_08003 = 1303;                            // connection exception: connection does not exist
+    int X_08004 = 1304;                            // connection exception: SQL-server rejected establishment of SQL-connection
+    int X_08006 = 1305;                            // connection exception: connection failure
+    int X_08007 = 1306;                            // connection exception: transaction resolution unknown
+
+    // HSQLDB connection
+    int X_08501 = 1351;                            // connection exception: timed out
+    int X_08502 = 1352;                            // warning: unsupported client info
+    int X_08503 = 1353;                            // connection exception: closed
+
+    // triggered action exception - 200x
+    int X_09000 = 1400;                            // triggered action exception
+
+    // feature not supported - 200x
+    int X_0A000 = 1500;                            // feature not supported
+    int X_0A001 = 1501;                            // feature not supported: multiple server transactions
+
+    // HSQLDB feature not supported
+    int X_0A501 = 1551;                            // feature not supported:
+
+    // invalid target type specification - 200x
+    int X_0D000 = 1600;                            // invalid target type specification
+
+    // invalid schema name list specification - 200x
+    int X_0E000 = 1700;                            // invalid schema name list specification
+
+    // locator exception - 2003
+    int X_0F000 = 1800;                            // locator exception
+    int X_0F001 = 1801;                            // locator exception: invalid specification
+
+    // HSQLDB locator
+    int X_0F502 = 3474;                            // lob is no long valid
+    int X_0F503 = 3475;                            // lob stream is closed
+
+    // resignal when handler not active - xxxx
+    int X_0K000 = 1900;                            // resignal when handler not active
+
+    // invalid grantor - 2003
+    int X_0L000 = 2000;                            // invalid grantor
+
+    // HSQLDB
+    int X_0L501 = 2051;                            // invalid grantor - lacks CREATE_SCHEMA privilege
+
+    // invalid SQL-invoked procedure reference - 2003
+    int X_0M000 = 2100;                            // invalid SQL-invoked procedure reference
+
+    // invalid role specification - 2003
+    int X_0P000 = 2200;                            // invalid role specification
+
+    // HSQLDB
+    int X_0P501 = 2251;                            // invalid role specification - circular grant
+    int X_0P502 = 2252;                            // invalid role specification - already granted
+    int X_0P503 = 2253;                            // invalid role specification - does not have role
+
+    // invalid transform group name specification - 2003
+    int X_0S000 = 2300;                            // invalid transform group name specification
+
+    // target table disagrees with cursor specification - 2003
+    int X_0T000 = 2400;                            // target table disagrees with cursor specification
+
+    // attempt to assign to non-updatable column - 2003
+    int X_0U000 = 2500;                            // attempt to assign to non-updatable column
+
+    // attempt to assign to ordering column - 2003
+    int X_0V000 = 2600;                            // attempt to assign to ordering column
+
+    // prohibited statement encountered during trigger execution - 2003
+    int X_0W000 = 2700;                            // prohibited statement encountered during trigger execution
+
+    // invalid foreign server specification - xxxx
+    int X_0X000 = 2800;                            // invalid foreign server specification
+
+    // pass-through specific condition - xxxx
+    int X_0Y000 = 2900;                            // pass-through specific condition
+    int X_0Y001 = 2901;                            // pass-through specific condition: invalid cursor option
+    int X_0Y002 = 2902;                            // pass-through specific condition: invalid cursor allocation
+
+    // diagnostics exception - 2003
+    int X_0Z000 = 3000;                            // diagnostics exception
+    int X_0Z001 = 3001;                            // diagnostics exception: maximum number of stacked diagnostics areas exceeded
+
+    // 04-PSM - xxxx
+    int X_0Z002 = 3003;                            // diagnostics exception: stacked diagnostics accessed without active handler
+
+    // 04-PSM - 2003
+    int X_20000 = 3100;                            // case not found for case statement
+
+    // cardinality violation - 2003
+    int X_21000 = 3201;                            // cardinality violation
+
+    // data exception - xxxx
+    int X_22000 = 3400;                            // data exception - generic
+    int X_22001 = 3401;                            // data exception: string data, right truncation - 200x
+    int X_22002 = 3402;                            // data exception: null value, no indicator parameter - 200x
+    int X_22003 = 3403;                            // data exception: numeric value out of range - 200x
+    int X_22004 = 3404;                            // data exception: null value not allowed - 200x
+    int X_22005 = 3405;                            // data exception: error in assignment - 200x
+    int X_22006 = 3406;                            // data exception: invalid interval format - 200x
+    int X_22007 = 3407;                            // data exception: invalid datetime format - 200x
+    int X_22008 = 3408;                            // data exception: datetime field overflow - 200x
+    int X_22009 = 3409;                            // data exception: invalid time zone displacement value - 200x
+    int X_2200B = 3410;                            // data exception: escape character conflict - 200x
+    int X_2200C = 3411;                            // data exception: invalid use of escape character - 200x
+    int X_2200D = 3412;                            // data exception: invalid escape octet - 200x
+    int X_2200E = 3413;                            // data exception: null value in array target - 200x
+    int X_2200F = 3414;                            // data exception: zero-length character string - 200x
+    int X_2200G = 3415;                            // data exception: most specific type mismatch - 200x
+    int X_2200H = 3416;                            // data exception: sequence generator limit exceeded - 200x
+    int X_2200J = 3417;                            // data exception: nonidentical notations with the same name - xxxx
+    int X_2200K = 3418;                            // data exception: nonidentical unparsed entities with the same name - xxxx
+    int X_2200L = 3419;                            // data exception: not an XML document - xxxx
+    int X_2200M = 3420;                            // data exception: invalid XML document - xxxx
+    int X_2200N = 3421;                            // data exception: invalid XML content - xxxx
+    int X_2200P = 3422;                            // data exception: interval value out of range - 200x
+    int X_2200Q = 3423;                            // data exception: multiset value overflow - 200x
+    int X_2200R = 3424;                            // data exception: XML value overflow - xxxx
+    int X_2200S = 3425;                            // data exception: invalid comment - xxxx
+    int X_2200T = 3426;                            // data exception: invalid processing instruction - xxxx
+    int X_2200U = 3427;                            // data exception: not an XQuery document node - xxxx
+    int X_2200V = 3428;                            // data exception: invalid XQuery context item - xxxx
+    int X_2200W = 3429;                            // data exception: XQuery serialization error - xxxx
+    int X_22010 = 3430;                            // data exception: invalid indicator parameter value - 200x
+    int X_22011 = 3431;                            // data exception: substring error - 200x
+    int X_22012 = 3432;                            // data exception: division by zero - 200x
+    int X_22013 = 3433;                            // data exception: invalid preceding or following size in window function - 200x
+    int X_22014 = 3434;                            // data exception: invalid argument for NTILE function - 200x
+    int X_22015 = 3435;                            // data exception: interval field overflow - 200x
+    int X_22016 = 3436;                            // data exception: invalid argument for NTH_VALUE function - 200x
+    int X_22017 = 3437;                            // data exception: invalid data specified for datalink - xxxx
+    int X_22018 = 3438;                            // data exception: invalid character value for cast - 200x
+    int X_22019 = 3439;                            // data exception: invalid escape character - 200x
+    int X_2201A = 3440;                            // data exception: null argument passed to datalink constructor
+    int X_2201B = 3441;                            // data exception: invalid regular expression - 200x
+    int X_2201C = 3442;                            // data exception: null row not permitted in table - 200x
+    int X_2201D = 3443;                            // data exception: datalink value exceeds maximum length
+    int X_2201E = 3444;                            // data exception: invalid argument for natural logarithm - 200x
+    int X_2201F = 3445;                            // data exception: invalid argument for power function - 200x
+    int X_2201G = 3446;                            // data exception: invalid argument for width bucket function - 200x
+    int X_2201J = 3447;                            // data exception: XQuery sequence cannot be validated
+    int X_2201S = 3448;                            // data exception: invalid XQuery regular expression - 200x
+    int X_2201T = 3449;                            // data exception: invalid XQuery option flag - 200x
+    int X_2201U = 3450;                            // data exception: attempt to replace a zero-length string - 200x
+    int X_2201V = 3451;                            // data exception: invalid XQuery replacement string - 200x
+    int X_2201W = 3452;                            // data exception: invalid row count in fetch first clause - 200x
+    int X_2201X = 3453;                            // data exception: invalid row count in result offset clause - 200x
+    int X_22021 = 3454;                            // data exception: character not in repertoire - 200x
+    int X_22022 = 3455;                            // data exception: indicator overflow - 200x
+    int X_22023 = 3456;                            // data exception: invalid parameter value - 200x
+    int X_22024 = 3457;                            // data exception: unterminated C string - 200x
+    int X_22025 = 3458;                            // data exception: invalid escape sequence - 200x
+    int X_22026 = 3459;                            // data exception: string data, length mismatch - 200x
+    int X_22027 = 3460;                            // data exception: trim error - 200x
+    int X_22029 = 3461;                            // data exception: noncharacter in UCS string - 200x
+
+    // HSQLDB data exception
+    int X_22501 = 3471;                            // value cannot be converted to target type
+    int X_22511 = 3472;                            // invalid function argument
+    int X_22521 = 3473;                            // object serialization failure
+
+    // 04-PSM - xxxx
+    int X_2202A = 3488;                            // data exception: null value in field reference
+    int X_2202D = 3489;                            // data exception: null value substituted for mutator subject parameter - 200x
+    int X_2202E = 3490;                            // data exception: array element error
+    int X_2202F = 3491;                            // data exception: array data, right truncation - 200x
+    int X_2202G = 3492;                            // data exception: invalid repeat argument in a sample clause - 200x
+    int X_2202H = 3493;                            // data exception: invalid sample size - 200x
+
+    // integrity constraint violation - xxxx
+    int X_23000 = 3500;                            // integrity constraint violation - 200x
+    int X_23001 = 3501;                            // integrity constraint violation: restrict violation - 200x
+    int X_23502 = 10;                              // integrity constraint violation: NOT NULL check constraint
+    int X_23503 = 177;                             // integrity constraint violation: foreign key no parent
+    int X_23504 = 8;                               // integrity constraint violation: foreing key no action
+    int X_23505 = 104;                             // integrity constraint violation: unique constraint or index
+    int X_23513 = 157;                             // integrity constraint violation: check constraint
+
+    // invalid cursor state - xxxx
+    int X_24000 = 3600;                            // invalid cursor state - 2003
+    int X_24501 = 3601;                            // invalid cursor state: identified cursor is not open
+    int X_24502 = 3602;                            // invalid cursor state: identified cursor is already open
+    int X_24504 = 3603;                            // invalid cursor state: identifier cursor not positioned on row in UPDATE, DELETE, SET, or GET statement
+    int X_24513 = 3604;                            // invalid cursor state: cannot FETCH NEXT, PRIOR, CURRENT, or RELATIVE, cursor position is unknown
+    int X_24514 = 3605;                            // invalid cursor state: cursor disabled by previous error
+    int X_24515 = 3606;                            // invalid cursor state: all column must be set before insert
+    int X_24521 = 3621;                            // invalid cursor state: row has been modified outside the cursor
+
+    // invalid transaction state - 200x
+    int X_25000 = 3700;                            // invalid transaction state
+    int X_25001 = 3701;                            // invalid transaction state: active SQL-transaction
+    int X_25002 = 3702;                            // invalid transaction state: branch transaction already active
+    int X_25003 = 3703;                            // invalid transaction state: inappropriate access mode for branch transaction
+    int X_25004 = 3704;                            // invalid transaction state: inappropriate isolation level for branch transaction
+    int X_25005 = 3705;                            // invalid transaction state: no active SQL-transaction for branch transaction
+    int X_25006 = 3706;                            // invalid transaction state: read-only SQL-transaction
+    int X_25007 = 3707;                            // invalid transaction state: schema and data statement mixing not supported
+    int X_25008 = 3708;                            // invalid transaction state: held cursor requires same isolation level
+
+    // invalid SQL statement name - 2003
+    int X_26000 = 3800;                            // invalid SQL statement name
+
+    // triggered data change violation - 2003
+    int X_27000 = 3900;                            // triggered data change violation
+
+    // invalid authorization specification - 2003
+    int X_28000 = 4000;                            // invalid authorization specification
+
+    // HSQLDB invalid authorization specification
+    int X_28501 = 4001;                            // invalid authorization specification - not found
+    int X_28502 = 4002;                            // invalid authorization specification - system identifier
+    int X_28503 = 4003;                            // invalid authorization specification - already exists
+
+    // syntax error or access rule violation in direct statement
+    int X_2A000 = 4100;                            // syntax error or access rule violation in direct statement
+
+    // dependent privilege descriptors still exist
+    int X_2B000 = 4200;                            // dependent privilege descriptors still exist
+
+    // invalid character set name
+    int X_2C000 = 4300;                            // invalid character set name
+
+    // invalid transaction termination
+    int X_2D000 = 4400;                            // invalid transaction termination
+    int X_2D522 = 4401;                            // invalid transaction termination: COMMIT and ROLLBACK not allowed in ATOMIC compound statement
+
+    // invalid connection name
+    int X_2E000 = 4500;                            //invalid connection name
+
+    // SQL routine exception
+    int X_2F000 = 4600;                            // SQL routine exception
+    int X_2F002 = 4602;                            // SQL routine exception: modifying SQL-data not permitted
+    int X_2F003 = 4603;                            // SQL routine exception: prohibited SQL-statement attempted
+    int X_2F004 = 4604;                            // SQL routine exception: reading SQL-data not permitted
+    int X_2F005 = 4605;                            // SQL routine exception: function did not execute return statement
+
+    // invalid collation name
+    int X_2H000 = 4650;                            // invalid collation name
+
+    // invalid SQL statement identifier
+    int X_30000 = 4660;                            // invalid SQL statement identifier
+
+    // invalid SQL descriptor name
+    int X_33000 = 4670;                            // invalid SQL descriptor name
+
+    // invalid cursor name
+    int X_34000 = 4680;                            // invalid cursor name
+
+    // invalid condition number
+    int X_35000 = 4690;                            // invalid condition number
+
+    // cursor sensitivity exception - 200x
+    int X_36000 = 4700;                            // cursor sensitivity exception
+    int X_36001 = 4701;                            // cursor sensitivity exception: request rejected
+    int X_36002 = 4702;                            // cursor sensitivity exception: request failed
+
+    // cursor compatibility warnings
+    int W_36501 = 4711;                            // cursor sensitivity mismatch
+    int W_36502 = 4712;                            // cursor updatability mismatch
+    int W_36503 = 4713;                            // cursor holdability mismatch
+
+    // syntax error or access rule violation in dynamic statement - xxxx
+    int X_37000 = 4790;                            // syntax error or access rule violation in dynamic statement
+
+    // external routine exception - 2003
+    int X_38000 = 4800;                            // external routine exception
+    int X_38001 = 4801;                            // external routine exception: containing SQL not permitted
+    int X_38002 = 4802;                            // external routine exception: modifying SQL-data not permitted
+    int X_38003 = 4803;                            // external routine exception: prohibited SQL-statement attempted
+    int X_38004 = 4804;                            // external routine exception: reading SQL-data not permitted
+
+    // external routine invocation exception - 200x
+    int X_39000 = 4810;                            // external routine invocation exception
+    int X_39004 = 4811;                            // external routine invocation exception: null value not allowed
+
+    // savepoint exception - 200x
+    int X_3B000 = 4820;                            // savepoint exception
+    int X_3B001 = 4821;                            // savepoint exception: invalid specification
+    int X_3B002 = 4822;                            // savepoint exception: too many
+
+    // ambiguous cursor name - 200x
+    int X_3C000 = 4830;                            // ambiguous cursor name
+
+    // invalid catalog name - 200x
+    int X_3D000 = 4840;                            // invalid catalog name
+
+    // invalid schema name - 200x
+    int X_3F000 = 4850;                            // invalid schema name
+
+    // transaction rollback - 200x
+    int X_40000 = 4860;                            // transaction rollback - generic
+    int X_40001 = 4861;                            // serialization failure
+    int X_40002 = 4862;                            // integrity constraint violation
+    int X_40003 = 4863;                            // statement completion unknown
+    int X_40004 = 4864;                            // triggered action exception
+
+    // HSQLDB internal tx management
+    int X_40501 = 4871;                            // transaction
+
+    // syntax error or access rule violation - xxxx
+    int X_42000 = 5000;                            // syntax error or access rule violation - generic - 200x
+
+    // HSQLDB database object names
+    int X_42501 = 5501;                            // user lacks privilege or object not found
+    int X_42502 = 5502;                            // dependent objects exist
+    int X_42503 = 5503;                            // system object cannot be modified
+    int X_42504 = 5504;                            // object name already exists
+    int X_42505 = 5505;                            // invalid schema name - name mismatch
+    int X_42506 = 5506;                            // invalid catalog name
+    int X_42507 = 5507;                            // admin rights required
+    int X_42508 = 5508;                            // label not found
+    int X_42509 = 5509;                            // type not found or user lacks privilege
+    int X_42510 = 5510;                            // name too long
+
+    // generated columns
+    int X_42512 = 5512;                            // invalid expression in CHECK or GENERATED clause
+    int X_42513 = 5513;                            // assignment to generated column
+
+    // constraint defintition issues
+    int X_42520 = 5520;                            // SET NULL requires nullable column
+    int X_42521 = 5521;                            // SET DEFAULT requires column default expression for
+    int X_42522 = 5522;                            // a UNIQUE constraint already exists on the set of columns
+    int X_42523 = 5523;                            // table has no primary key
+    int X_42524 = 5524;                            // constraint definition not allowed
+    int X_42525 = 5525;                            // identity definition not allowed
+    int X_42526 = 5526;                            // column is in primary key
+    int X_42527 = 5527;                            // column is in constraint
+    int X_42528 = 5528;                            // a FOREIGN KEY constraint already exists on the set of columns
+    int X_42529 = 5529;                            // a UNIQUE constraint does not exist on referenced columns
+    int X_42530 = 5530;                            // primary key definition not allowed
+    int X_42531 = 5531;                            // default expression needed
+    int X_42532 = 5532;                            // primary key already exist
+    int X_42533 = 5533;                            // is referenced by FOREIGN KEY constraint
+    int X_42534 = 5534;                            // column of LOB type cannot be used in operation
+
+    // other definition issues
+    int X_42535 = 5535;                            // not an identity column
+    int X_42536 = 5536;                            // column is referenced in
+    int X_42537 = 5537;                            // cannot use WITH CHECK option for read-only view
+    int X_42538 = 5538;                            // TRIGGER definition not compatible with table
+    int X_42539 = 5539;                            // cannot drop a user that is currently connected
+
+    // DML
+    int X_42541 = 5541;                            // requires DEFAULT keyword
+    int X_42542 = 5542;                            // requires OVERRIDING clause
+    int X_42543 = 5543;                            // requires either DEFAULT keyword or OVERRIDING clause
+    int X_42544 = 5544;                            // DEFAULT keyword cannot be used as column has no DEFAULT
+    int X_42545 = 5545;                            // INSERT, UPDATE, DELETE or TRUNCATE not permitted for table or view
+    int X_42546 = 5546;                            // number of target columns does not match that of query expression
+    int X_42547 = 5547;                            // merge when matched already used
+    int X_42548 = 5548;                            // merge when not matched altready used
+    int X_42549 = 5549;                            // LIMIT, OFFSET or FETCH altready used
+
+    //
+    int X_42551 = 5551;                            // too many identifier parts
+    int X_42555 = 5555;                            // invalid property name
+    int X_42556 = 5556;                            // invalid property value
+
+    // HSQLDB type conversion
+    int X_42561 = 5561;                            // incompatible data type in conversion
+    int X_42562 = 5562;                            // incompatible data types in combination
+    int X_42563 = 5563;                            // incompatible data type in operation
+    int X_42564 = 5564;                            // row column count mismatch
+    int X_42565 = 5565;                            // row expression not allowed
+    int X_42566 = 5566;                            // interval qualifier missing
+    int X_42567 = 5567;                            // data type cast needed for parameter or null literal
+    int X_42568 = 5568;                            // data type of expression is not boolean
+    int X_42569 = 5569;                            // quoted identifier required
+    int X_42570 = 5570;                            // concatenation exceeds maximum type length
+
+    //
+    int X_42571 = 5571;                            // NULL literal not allowed
+    int X_42572 = 5572;                            // invalid GROUP BY expression
+    int X_42573 = 5573;                            // invalid HAVING expression
+    int X_42574 = 5574;                            // expression not in aggregate or GROUP BY columns
+    int X_42575 = 5575;                            // parameter marker not allowed
+    int X_42576 = 5576;                            // invalid ORDER BY expression
+    int X_42577 = 5577;                            // duplicate name in column list
+    int X_42578 = 5578;                            // duplicate column name in derived table
+    int X_42579 = 5579;                            // duplicate update of column
+    int X_42580 = 5580;                            // ambiguous column reference
+
+    // lexical elements
+    int X_42581 = 5581;                            // unexpected token
+    int X_42582 = 5582;                            // unknown token
+    int X_42583 = 5583;                            // malforemd quoted identifier
+    int X_42584 = 5584;                            // malformed string
+    int X_42585 = 5585;                            // malformed numeric constant
+    int X_42586 = 5586;                            // malformed unicode string
+    int X_42587 = 5587;                            // malformed binary string
+    int X_42588 = 5588;                            // malformed bit string
+    int X_42589 = 5589;                            // malformed comment
+    int X_42590 = 5590;                            // unexpected end of statement
+
+    // other
+    int X_42591 = 5591;                            // cannot drop sole column of table
+    int X_42592 = 5592;                            // precision or scale out of range
+    int X_42593 = 5593;                            // column count mismatch in column name list
+    int X_42594 = 5594;                            // column count mismatch in UNION, INTERSECT, EXCEPT operation
+    int X_42595 = 5595;                            // invalid privilege specified - ALL PRIVILEGES required
+    int X_42596 = 5596;                            // schema qualifier does not match enclosing create schema statement.
+    int X_42597 = 5597;                            // number out of the valid range for sequence generator
+    int X_42598 = 5598;                            // sequence expression cannot be specified in this context
+    int X_42599 = 5599;                            // length must be specified in type definition
+
+    // HSQLDB - PSM definition
+    int X_42601 = 5601;                            // repeat handler declaration
+    int X_42602 = 5602;                            // invalid statement in routine
+    int X_42603 = 5603;                            // dynamic parameter or variable required as INOUT or OUT argument
+    int X_42604 = 5604;                            // incompatible declaration attributes
+    int X_42605 = 5605;                            // routine signature already exists
+    int X_42606 = 5606;                            // routine variable name already exists
+    int X_42607 = 5607;                            // invalid SQLSTATE value
+    int X_42608 = 5608;                            // wrong or missing data impact clause in declaration
+    int X_42609 = 5609;                            // routine signature not found for
+    int X_42610 = 5610;                            // wrong arguments for AGGREGATE function
+
+    // with check option violation - 200x
+    int X_44000 = 5700;                            // with check option violation
+
+    // 04-PSM
+    // unhandled user-defined exception - 200x
+    int X_45000 = 5800;                            // unhandled user-defined exception
+
+    // SQL/JRT
+    int X_46000 = 6000;                            // Java execution / Java DDL - generic
+    int X_46001 = 6001;                            // invalid URL
+    int X_46002 = 6002;                            // invalid JAR name
+    int X_46003 = 6003;                            // invalid class deletion
+    int X_46005 = 6004;                            // invalid replacement
+    int X_4600A = 6007;                            // attempt to replace uninstalled JAR
+    int X_4600B = 6008;                            // attempt to remove uninstalled JAR
+    int X_4600C = 6009;                            // invalid JAR removal
+    int X_4600D = 6010;                            // invalid path
+    int X_4600E = 6011;                            // self-referencing path
+    int X_46102 = 6012;                            // invalid JAR name in path
+    int X_46103 = 6013;                            // unresolved class or method name
+
+    // HSQLDB - SQL/JRT
+    int X_46511 = 6021;                            // declared parameter types do not match method signature
+
+    // Unknown Error: Catch-All - xxxx
+    int X_99000 = 6500;                            // Unknown Error: Catch-All
+    int X_99099 = 6501;                            // Error converting vendor code to SQL state code
+
+    // FDW-specific condition - xxxx
+    int X_HV000 = 6600;                            // FDW-specific condition - generic
+    int X_HV001 = 6601;                            // memory allocation error
+    int X_HV002 = 6602;                            // dynamic parameter value needed
+    int X_HV004 = 6603;                            // invalid data type
+    int X_HV005 = 6604;                            // column name not found
+    int X_HV006 = 6605;                            // invalid data type descriptors
+    int X_HV007 = 6606;                            // invalid column name
+    int X_HV008 = 6607;                            // invalid column number
+    int X_HV009 = 6608;                            // invalid use of null pointer
+    int X_HV00A = 6609;                            // invalid string format
+    int X_HV00B = 6610;                            // invalid handle
+    int X_HV00C = 6611;                            // invalid option index
+    int X_HV00D = 6612;                            // invalid option name
+    int X_HV00J = 6613;                            // option name not found
+    int X_HV00K = 6614;                            // reply handle
+    int X_HV00L = 6615;                            // unable to create execution
+    int X_HV00M = 6616;                            // unable to create reply
+    int X_HV00N = 6617;                            // unable to establish connection
+    int X_HV00P = 6618;                            // no schemas
+    int X_HV00Q = 6619;                            // schema not found
+    int X_HV00R = 6620;                            // table not found
+    int X_HV010 = 6621;                            // function sequence error
+    int X_HV014 = 6622;                            // limit on number of handles exceeded
+    int X_HV021 = 6623;                            // inconsistent descriptor information
+    int X_HV024 = 6624;                            // invalid attribute value
+    int X_HV090 = 6625;                            // invalid string length or buffer length
+    int X_HV091 = 6626;                            // invalid descriptor field identifier
+
+    // datalink exception - 200x
+    int X_HW000 = 6700;                            // datalink exception - generic
+    int X_HW001 = 6701;                            // external file not linked
+    int X_HW002 = 6702;                            // external file already linked
+    int X_HW003 = 6703;                            // referenced file does not exist
+    int X_HW004 = 6704;                            // invalid write token
+    int X_HW005 = 6705;                            // invalid datalink construction
+    int X_HW006 = 6706;                            // invalid write permission for update
+    int X_HW007 = 6707;                            // referenced file not valid
+
+    // CLI-specific condition - 200x
+    int X_HY093 = 6800;                            // CLI-specific condition: invalid datalink value
+}
diff --git a/src/org/hsqldb/index/Index.java b/src/org/hsqldb/index/Index.java
new file mode 100644
index 0000000..c12754a
--- /dev/null
+++ b/src/org/hsqldb/index/Index.java
@@ -0,0 +1,230 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.index;
+
+import org.hsqldb.Row;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Session;
+import org.hsqldb.TableBase;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.types.Type;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface Index extends SchemaObject {
+
+    Index[] emptyArray = new Index[]{};
+
+    RowIterator emptyIterator();
+
+    public int getPosition();
+
+    public void setPosition(int position);
+
+    public long getPersistenceId();
+
+    /**
+     * Returns the count of visible columns used
+     */
+    public int getVisibleColumns();
+
+    public int getColumnCount();
+
+    /**
+     * Is this a UNIQUE index?
+     */
+    public boolean isUnique();
+
+    /**
+     * Does this index belong to a constraint?
+     */
+    public boolean isConstraint();
+
+    /**
+     * Returns the array containing column indexes for index
+     */
+    public int[] getColumns();
+
+    /**
+     * Returns the array containing column indexes for index
+     */
+    public Type[] getColumnTypes();
+
+    /**
+     * Returns the count of visible columns used
+     */
+    public boolean[] getColumnDesc();
+
+    /**
+     * Returns the array containing 0, 1, .. column indexes
+     */
+    public int[] getDefaultColumnMap();
+
+    /**
+     * Returns a value indicating the order of different types of index in
+     * the list of indexes for a table. The position of the groups of Indexes
+     * in the list in ascending order is as follows:
+     *
+     * primary key index
+     * unique constraint indexes
+     * autogenerated foreign key indexes for FK's that reference this table or
+     *  tables created before this table
+     * user created indexes (CREATE INDEX)
+     * autogenerated foreign key indexes for FK's that reference tables created
+     *  after this table
+     *
+     * Among a group of indexes, the order is based on the order of creation
+     * of the index.
+     *
+     * @return ordinal value
+     */
+    public int getIndexOrderValue();
+
+    public boolean isForward();
+
+    public void setTable(TableBase table);
+
+    /**
+     * Returns the node count.
+     */
+    public int size(Session session, PersistentStore store);
+
+    public int sizeUnique(PersistentStore store);
+
+    public boolean isEmpty(PersistentStore store);
+
+    public void checkIndex(PersistentStore store);
+
+    /**
+     * Insert a node into the index
+     */
+    public void insert(Session session, PersistentStore store, Row row);
+
+    public void delete(Session session, PersistentStore store, Row row);
+
+    public boolean existsParent(Session session, PersistentStore store,
+                                Object[] rowdata, int[] rowColMap);
+
+    /**
+     * Return the first node equal to the indexdata object. The rowdata has
+     * the same column mapping as this index.
+     *
+     * @param session session object
+     * @param store store object
+     * @param coldata array containing index column data
+     * @param match count of columns to match
+     * @return iterator
+     */
+    public RowIterator findFirstRow(Session session, PersistentStore store,
+                                    Object[] rowdata, int matchCount,
+                                    int compareType, boolean reversed,
+                                    boolean[] map);
+
+    /**
+     * Return the first node equal to the rowdata object.
+     * The rowdata has the same column mapping as this table.
+     *
+     * @param session session object
+     * @param store store object
+     * @param rowdata array containing table row data
+     * @return iterator
+     */
+    public RowIterator findFirstRow(Session session, PersistentStore store,
+                                    Object[] rowdata);
+
+    /**
+     * Return the first node equal to the rowdata object.
+     * The rowdata has the column mapping privided in rowColMap.
+     *
+     * @param session session object
+     * @param store store object
+     * @param rowdata array containing table row data
+     * @return iterator
+     */
+    public RowIterator findFirstRow(Session session, PersistentStore store,
+                                    Object[] rowdata, int[] rowColMap);
+
+    /**
+     * Finds the first node where the data is not null.
+     *
+     * @return iterator
+     */
+    public RowIterator findFirstRowNotNull(Session session,
+                                           PersistentStore store);
+
+    public RowIterator firstRow(PersistentStore store);
+
+    /**
+     * Returns the row for the first node of the index
+     *
+     * @return Iterator for first row
+     */
+    public RowIterator firstRow(Session session, PersistentStore store);
+
+    /**
+     * Returns the row for the last node of the index
+     *
+     * @return last row
+     */
+    public RowIterator lastRow(Session session, PersistentStore store);
+
+    /**
+     * Compares two table rows based on the columns of this index. The rowColMap
+     * parameter specifies which columns of the other table are to be compared
+     * with the colIndex columns of this index. The rowColMap can cover all
+     * or only some columns of this index.
+     *
+     * @param a row from another table
+     * @param rowColMap column indexes in the other table
+     * @param b a full row in this table
+     *
+     * @return comparison result, -1,0,+1
+     */
+    public int compareRowNonUnique(Session session, Object[] a, Object[] b,
+                                   int[] rowColMap);
+
+    public int compareRowNonUnique(Session session, Object[] a, Object[] b,
+                                   int[] rowColMap, int fieldCount);
+
+    /**
+     * As above but use the index column data
+     */
+    public int compareRowNonUnique(Session session, Object[] a, Object[] b,
+                                   int fieldcount);
+
+    public int compareRow(Session session, Object[] a, Object[] b);
+}
diff --git a/src/org/hsqldb/index/IndexAVL.java b/src/org/hsqldb/index/IndexAVL.java
new file mode 100644
index 0000000..ce3c106
--- /dev/null
+++ b/src/org/hsqldb/index/IndexAVL.java
@@ -0,0 +1,1726 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.index;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.hsqldb.Constraint;
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.OpTypes;
+import org.hsqldb.Row;
+import org.hsqldb.RowAVL;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.Tokens;
+import org.hsqldb.TransactionManager;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.types.Type;
+
+// fredt@users 20020221 - patch 513005 by sqlbob@users - corrections
+// fredt@users 20020225 - patch 1.7.0 - changes to support cascading deletes
+// tony_lai@users 20020820 - patch 595052 - better error message
+// fredt@users 20021205 - patch 1.7.2 - changes to method signature
+// fredt@users - patch 1.8.0 - reworked the interface and comparison methods
+// fredt@users - patch 1.8.0 - improved reliability for cached indexes
+// fredt@users - patch 1.9.0 - iterators and concurrency
+
+/**
+ * Implementation of an AVL tree with parent pointers in nodes. Subclasses
+ * of Node implement the tree node objects for memory or disk storage. An
+ * Index has a root Node that is linked with other nodes using Java Object
+ * references or file pointers, depending on Node implementation.<p>
+ * An Index object also holds information on table columns (in the form of int
+ * indexes) that are covered by it.<p>
+ *
+ *  New class derived from Hypersonic SQL code and enhanced in HSQLDB. <p>
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class IndexAVL implements Index {
+
+    // fields
+    private final long       persistenceId;
+    protected final HsqlName name;
+    private final boolean[]  colCheck;
+    final int[]              colIndex;
+    private final int[]      defaultColMap;
+    final Type[]             colTypes;
+    private final boolean[]  colDesc;
+    private final boolean[]  nullsLast;
+    final boolean            isSimpleOrder;
+    final boolean            isSimple;
+    protected final boolean  isPK;        // PK with or without columns
+    protected final boolean  isUnique;    // DDL uniqueness
+    protected final boolean  isConstraint;
+    private final boolean    isForward;
+    private int              depth;
+    private static final IndexRowIterator emptyIterator =
+        new IndexRowIterator(null, (PersistentStore) null, null, null, false,
+                             false);
+    protected TableBase table;
+    int                 position;
+
+    //
+    Object[] nullData;
+
+    //
+    ReadWriteLock lock      = new ReentrantReadWriteLock();
+    Lock          readLock  = lock.readLock();
+    Lock          writeLock = lock.writeLock();
+
+    /**
+     * Constructor declaration
+     *
+     * @param name HsqlName of the index
+     * @param id persistnece id
+     * @param table table of the index
+     * @param columns array of column indexes
+     * @param descending boolean[]
+     * @param nullsLast boolean[]
+     * @param colTypes array of column types
+     * @param pk if index is for a primary key
+     * @param unique is this a unique index
+     * @param constraint does this index belonging to a constraint
+     * @param forward is this an auto-index for an FK that refers to a table
+     *   defined after this table
+     */
+    public IndexAVL(HsqlName name, long id, TableBase table, int[] columns,
+                    boolean[] descending, boolean[] nullsLast,
+                    Type[] colTypes, boolean pk, boolean unique,
+                    boolean constraint, boolean forward) {
+
+        this.persistenceId = id;
+        this.name          = name;
+        this.colIndex      = columns;
+        this.colTypes      = colTypes;
+        this.colDesc       = descending == null ? new boolean[columns.length]
+                                                : descending;
+        this.nullsLast     = nullsLast == null ? new boolean[columns.length]
+                                               : nullsLast;
+        this.isPK          = pk;
+        this.isUnique      = unique;
+        this.isConstraint  = constraint;
+        this.isForward     = forward;
+        this.table         = table;
+        this.colCheck      = table.getNewColumnCheckList();
+
+        ArrayUtil.intIndexesToBooleanArray(colIndex, colCheck);
+
+        this.defaultColMap = new int[columns.length];
+
+        ArrayUtil.fillSequence(defaultColMap);
+
+        boolean simpleOrder = colIndex.length > 0;
+
+        for (int i = 0; i < colDesc.length; i++) {
+            if (this.colDesc[i] || this.nullsLast[i]) {
+                simpleOrder = false;
+            }
+        }
+
+        isSimpleOrder = simpleOrder;
+        isSimple      = isSimpleOrder && colIndex.length == 1;
+        nullData      = new Object[colIndex.length];
+    }
+
+    // SchemaObject implementation
+    public int getType() {
+        return SchemaObject.INDEX;
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public HsqlName getCatalogName() {
+        return name.schema.schema;
+    }
+
+    public HsqlName getSchemaName() {
+        return name.schema;
+    }
+
+    public Grantee getOwner() {
+        return name.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+        return new OrderedHashSet();
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb = new StringBuffer(64);
+
+        sb.append(Tokens.T_CREATE).append(' ');
+
+        if (isUnique()) {
+            sb.append(Tokens.T_UNIQUE).append(' ');
+        }
+
+        sb.append(Tokens.T_INDEX).append(' ');
+        sb.append(getName().statementName);
+        sb.append(' ').append(Tokens.T_ON).append(' ');
+        sb.append(((Table) table).getName().getSchemaQualifiedStatementName());
+
+        int[] col = getColumns();
+        int   len = getVisibleColumns();
+
+        sb.append(((Table) table).getColumnListSQL(col, len));
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    // IndexInterface
+    public RowIterator emptyIterator() {
+        return emptyIterator;
+    }
+
+    public int getPosition() {
+        return position;
+    }
+
+    public void setPosition(int position) {
+        this.position = position;
+    }
+
+    public long getPersistenceId() {
+        return persistenceId;
+    }
+
+    /**
+     * Returns the count of visible columns used
+     */
+    public int getVisibleColumns() {
+        return colIndex.length;
+    }
+
+    /**
+     * Returns the count of visible columns used
+     */
+    public int getColumnCount() {
+        return colIndex.length;
+    }
+
+    /**
+     * Is this a UNIQUE index?
+     */
+    public boolean isUnique() {
+        return isUnique;
+    }
+
+    /**
+     * Does this index belong to a constraint?
+     */
+    public boolean isConstraint() {
+        return isConstraint;
+    }
+
+    /**
+     * Returns the array containing column indexes for index
+     */
+    public int[] getColumns() {
+        return colIndex;
+    }
+
+    /**
+     * Returns the array containing column indexes for index
+     */
+    public Type[] getColumnTypes() {
+        return colTypes;
+    }
+
+    public boolean[] getColumnDesc() {
+        return colDesc;
+    }
+
+    public int[] getDefaultColumnMap() {
+        return this.defaultColMap;
+    }
+
+    /**
+     * Returns a value indicating the order of different types of index in
+     * the list of indexes for a table. The position of the groups of Indexes
+     * in the list in ascending order is as follows:
+     *
+     * primary key index
+     * unique constraint indexes
+     * autogenerated foreign key indexes for FK's that reference this table or
+     *  tables created before this table
+     * user created indexes (CREATE INDEX)
+     * autogenerated foreign key indexes for FK's that reference tables created
+     *  after this table
+     *
+     * Among a group of indexes, the order is based on the order of creation
+     * of the index.
+     *
+     * @return ordinal value
+     */
+    public int getIndexOrderValue() {
+
+        if (isPK) {
+            return 0;
+        }
+
+        if (isConstraint) {
+            return isForward ? 4
+                             : isUnique ? 0
+                                        : 1;
+        } else {
+            return 2;
+        }
+    }
+
+    public boolean isForward() {
+        return isForward;
+    }
+
+    public void setTable(TableBase table) {
+        this.table = table;
+    }
+
+    /**
+     * Returns the node count.
+     */
+    public int size(Session session, PersistentStore store) {
+
+        readLock.lock();
+
+        try {
+            return store.elementCount(session);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    public int sizeUnique(PersistentStore store) {
+
+        readLock.lock();
+
+        try {
+            return store.elementCountUnique(this);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    public int getNodeCount(Session session, PersistentStore store) {
+
+        int count = 0;
+
+        readLock.lock();
+
+        try {
+            RowIterator it = firstRow(session, store);
+
+            while (it.hasNext()) {
+                it.getNextRow();
+
+                count++;
+            }
+
+            return count;
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    public int sizeEstimate(PersistentStore store) {
+
+        firstRow(null, store);
+
+        return (int) (1L << depth);
+    }
+
+    public boolean isEmpty(PersistentStore store) {
+
+        readLock.lock();
+
+        try {
+            return getAccessor(store) == null;
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    public void checkIndex(PersistentStore store) {
+
+        readLock.lock();
+
+        try {
+            NodeAVL p = getAccessor(store);
+            NodeAVL f = null;
+
+            while (p != null) {
+                f = p;
+
+                checkNodes(store, p);
+
+                p = p.getLeft(store);
+            }
+
+            p = f;
+
+            while (f != null) {
+                checkNodes(store, f);
+
+                f = next(store, f);
+            }
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    void checkNodes(PersistentStore store, NodeAVL p) {
+
+        NodeAVL l = p.getLeft(store);
+        NodeAVL r = p.getRight(store);
+
+        if (l != null && l.getBalance(store) == -2) {
+            System.out.print("broken index - deleted");
+        }
+
+        if (r != null && r.getBalance(store) == -2) {
+            System.out.print("broken index -deleted");
+        }
+
+        if (l != null && !p.equals(l.getParent(store))) {
+            System.out.print("broken index - no parent");
+        }
+
+        if (r != null && !p.equals(r.getParent(store))) {
+            System.out.print("broken index - no parent");
+        }
+    }
+
+    /**
+     * Compares two table rows based on the columns of this index. The rowColMap
+     * parameter specifies which columns of the other table are to be compared
+     * with the colIndex columns of this index. The rowColMap can cover all or
+     * only some columns of this index.
+     *
+     * @param session Session
+     * @param a row from another table
+     * @param rowColMap column indexes in the other table
+     * @param b a full row in this table
+     * @return comparison result, -1,0,+1
+     */
+    public int compareRowNonUnique(Session session, Object[] a, Object[] b,
+                                   int[] rowColMap) {
+
+        int fieldcount = rowColMap.length;
+
+        for (int j = 0; j < fieldcount; j++) {
+            int i = colTypes[j].compare(session, a[colIndex[j]],
+                                        b[rowColMap[j]]);
+
+            if (i != 0) {
+                return i;
+            }
+        }
+
+        return 0;
+    }
+
+    public int compareRowNonUnique(Session session, Object[] a, Object[] b,
+                                   int[] rowColMap, int fieldCount) {
+
+        for (int j = 0; j < fieldCount; j++) {
+            int i = colTypes[j].compare(session, a[colIndex[j]],
+                                        b[rowColMap[j]]);
+
+            if (i != 0) {
+                return i;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * As above but use the index column data
+     */
+    public int compareRowNonUnique(Session session, Object[] a, Object[] b,
+                                   int fieldCount) {
+
+        for (int j = 0; j < fieldCount; j++) {
+            int i = colTypes[j].compare(session, a[colIndex[j]],
+                                        b[colIndex[j]]);
+
+            if (i != 0) {
+                return i;
+            }
+        }
+
+        return 0;
+    }
+
+    public int compareRow(Session session, Object[] a, Object[] b) {
+
+        for (int j = 0; j < colIndex.length; j++) {
+            int i = colTypes[j].compare(session, a[colIndex[j]],
+                                        b[colIndex[j]]);
+
+            if (i != 0) {
+                if (isSimpleOrder) {
+                    return i;
+                }
+
+                boolean nulls = a[colIndex[j]] == null
+                                || b[colIndex[j]] == null;
+
+                if (colDesc[j] && !nulls) {
+                    i = -i;
+                }
+
+                if (nullsLast[j] && nulls) {
+                    i = -i;
+                }
+
+                return i;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Compare two rows of the table for inserting rows into unique indexes
+     * Supports descending columns.
+     *
+     * @param session Session
+     * @param newRow data
+     * @param existingRow data
+     * @param useRowId boolean
+     * @param start int
+     * @return comparison result, -1,0,+1
+     */
+    int compareRowForInsertOrDelete(Session session, Row newRow,
+                                    Row existingRow, boolean useRowId,
+                                    int start) {
+
+        Object[] a = newRow.getData();
+        Object[] b = existingRow.getData();
+
+        for (int j = start; j < colIndex.length; j++) {
+            int i = colTypes[j].compare(session, a[colIndex[j]],
+                                        b[colIndex[j]]);
+
+            if (i != 0) {
+                if (isSimpleOrder) {
+                    return i;
+                }
+
+                boolean nulls = a[colIndex[j]] == null
+                                || b[colIndex[j]] == null;
+
+                if (colDesc[j] && !nulls) {
+                    i = -i;
+                }
+
+                if (nullsLast[j] && nulls) {
+                    i = -i;
+                }
+
+                return i;
+            }
+        }
+
+        if (useRowId) {
+            return newRow.getPos() - existingRow.getPos();
+        }
+
+        return 0;
+    }
+
+    int compareObject(Session session, Object[] a, Object[] b,
+                      int[] rowColMap, int position) {
+        return colTypes[position].compare(session, a[colIndex[position]],
+                                          b[rowColMap[position]]);
+    }
+
+    boolean hasNulls(Object[] rowData) {
+
+        for (int j = 0; j < colIndex.length; j++) {
+            if (rowData[colIndex[j]] == null) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Insert a node into the index
+     */
+    public void insert(Session session, PersistentStore store, Row row) {
+
+        NodeAVL n;
+        NodeAVL x;
+        boolean isleft       = true;
+        int     compare      = -1;
+        boolean compareRowId = !isUnique || hasNulls(row.getData());
+
+        writeLock.lock();
+        store.lock();
+
+        try {
+            n = getAccessor(store);
+            x = n;
+
+            if (n == null) {
+                store.setAccessor(this, ((RowAVL) row).getNode(position));
+                store.setElementCount(this, 1, 1);
+
+                return;
+            }
+
+            while (true) {
+                Row currentRow = n.getRow(store);
+
+                compare = compareRowForInsertOrDelete(session, row,
+                                                      currentRow,
+                                                      compareRowId, 0);
+
+                // after the first match and check, all compares are with row id
+                if (compare == 0 && session != null && !compareRowId
+                        && session.database.txManager.isMVRows()) {
+                    if (!isEqualReadable(session, store, n)) {
+                        compareRowId = true;
+                        compare = compareRowForInsertOrDelete(session, row,
+                                                              currentRow,
+                                                              compareRowId,
+                                                              colIndex.length);
+                    }
+                }
+
+                if (compare == 0) {
+                    Constraint c = null;
+
+                    if (isConstraint) {
+                        c = ((Table) table).getUniqueConstraintForIndex(this);
+                    }
+
+                    if (c == null) {
+                        throw Error.error(ErrorCode.X_23505,
+                                          name.statementName);
+                    } else {
+                        throw c.getException(row.getData());
+                    }
+                }
+
+                isleft = compare < 0;
+                x      = n;
+                n      = x.child(store, isleft);
+
+                if (n == null) {
+                    break;
+                }
+            }
+
+            x = x.set(store, isleft, ((RowAVL) row).getNode(position));
+
+            balance(store, x, isleft);
+            store.updateElementCount(this, 1, 1);
+        } finally {
+            store.unlock();
+            writeLock.unlock();
+        }
+    }
+
+    public void delete(Session session, PersistentStore store, Row row) {
+
+        if (!row.isInMemory()) {
+            row = (Row) store.get(row, false);
+        }
+
+        NodeAVL node = ((RowAVL) row).getNode(position);
+
+        if (node != null) {
+            delete(store, node);
+            store.updateElementCount(this, -1, -1);
+        }
+    }
+
+    void delete(PersistentStore store, NodeAVL x) {
+
+        if (x == null) {
+            return;
+        }
+
+        NodeAVL n;
+
+        writeLock.lock();
+        store.lock();
+
+        try {
+            if (x.getLeft(store) == null) {
+                n = x.getRight(store);
+            } else if (x.getRight(store) == null) {
+                n = x.getLeft(store);
+            } else {
+                NodeAVL d = x;
+
+                x = x.getLeft(store);
+
+                while (true) {
+                    NodeAVL temp = x.getRight(store);
+
+                    if (temp == null) {
+                        break;
+                    }
+
+                    x = temp;
+                }
+
+                // x will be replaced with n later
+                n = x.getLeft(store);
+
+                // swap d and x
+                int b = x.getBalance(store);
+
+                x = x.setBalance(store, d.getBalance(store));
+                d = d.setBalance(store, b);
+
+                // set x.parent
+                NodeAVL xp = x.getParent(store);
+                NodeAVL dp = d.getParent(store);
+
+                if (d.isRoot(store)) {
+                    store.setAccessor(this, x);
+                }
+
+                x = x.setParent(store, dp);
+
+                if (dp != null) {
+                    if (dp.isRight(d)) {
+                        dp = dp.setRight(store, x);
+                    } else {
+                        dp = dp.setLeft(store, x);
+                    }
+                }
+
+                // relink d.parent, x.left, x.right
+                if (d.equals(xp)) {
+                    d = d.setParent(store, x);
+
+                    if (d.isLeft(x)) {
+                        x = x.setLeft(store, d);
+
+                        NodeAVL dr = d.getRight(store);
+
+                        x = x.setRight(store, dr);
+                    } else {
+                        x = x.setRight(store, d);
+
+                        NodeAVL dl = d.getLeft(store);
+
+                        x = x.setLeft(store, dl);
+                    }
+                } else {
+                    d  = d.setParent(store, xp);
+                    xp = xp.setRight(store, d);
+
+                    NodeAVL dl = d.getLeft(store);
+                    NodeAVL dr = d.getRight(store);
+
+                    x = x.setLeft(store, dl);
+                    x = x.setRight(store, dr);
+                }
+
+                x.getRight(store).setParent(store, x);
+                x.getLeft(store).setParent(store, x);
+
+                // set d.left, d.right
+                d = d.setLeft(store, n);
+
+                if (n != null) {
+                    n = n.setParent(store, d);
+                }
+
+                d = d.setRight(store, null);
+                x = d;
+            }
+
+            boolean isleft = x.isFromLeft(store);
+
+            x.replace(store, this, n);
+
+            n = x.getParent(store);
+
+            x.delete();
+
+            while (n != null) {
+                x = n;
+
+                int sign = isleft ? 1
+                                  : -1;
+
+                switch (x.getBalance(store) * sign) {
+
+                    case -1 :
+                        x = x.setBalance(store, 0);
+                        break;
+
+                    case 0 :
+                        x = x.setBalance(store, sign);
+
+                        return;
+
+                    case 1 :
+                        NodeAVL r = x.child(store, !isleft);
+                        int     b = r.getBalance(store);
+
+                        if (b * sign >= 0) {
+                            x.replace(store, this, r);
+
+                            NodeAVL child = r.child(store, isleft);
+
+                            x = x.set(store, !isleft, child);
+                            r = r.set(store, isleft, x);
+
+                            if (b == 0) {
+                                x = x.setBalance(store, sign);
+                                r = r.setBalance(store, -sign);
+
+                                return;
+                            }
+
+                            x = x.setBalance(store, 0);
+                            r = r.setBalance(store, 0);
+                            x = r;
+                        } else {
+                            NodeAVL l = r.child(store, isleft);
+
+                            x.replace(store, this, l);
+
+                            b = l.getBalance(store);
+                            r = r.set(store, isleft, l.child(store, !isleft));
+                            l = l.set(store, !isleft, r);
+                            x = x.set(store, !isleft, l.child(store, isleft));
+                            l = l.set(store, isleft, x);
+                            x = x.setBalance(store, (b == sign) ? -sign
+                                                                : 0);
+                            r = r.setBalance(store, (b == -sign) ? sign
+                                                                 : 0);
+                            l = l.setBalance(store, 0);
+                            x = l;
+                        }
+                }
+
+                isleft = x.isFromLeft(store);
+                n      = x.getParent(store);
+            }
+        } finally {
+            store.unlock();
+            writeLock.unlock();
+        }
+    }
+
+    public boolean existsParent(Session session, PersistentStore store,
+                                Object[] rowdata, int[] rowColMap) {
+
+        NodeAVL node = findNode(session, store, rowdata, rowColMap,
+                                rowColMap.length, OpTypes.EQUAL,
+                                TransactionManager.ACTION_REF, false);
+
+        return node != null;
+    }
+
+    /**
+     * Return the first node equal to the indexdata object. The rowdata has the
+     * same column mapping as this index.
+     *
+     * @param session session object
+     * @param store store object
+     * @param rowdata array containing index column data
+     * @param fieldCount count of columns to match
+     * @param compareType int
+     * @return iterator
+     */
+    public RowIterator findFirstRow(Session session, PersistentStore store,
+                                    Object[] rowdata, int matchCount,
+                                    int compareType, boolean reversed,
+                                    boolean[] map) {
+
+        if (compareType == OpTypes.MAX) {
+            return lastRow(session, store);
+        }
+
+        NodeAVL node = findNode(session, store, rowdata, defaultColMap,
+                                matchCount, compareType,
+                                TransactionManager.ACTION_READ, reversed);
+
+        return getIterator(session, store, node, false, reversed);
+    }
+
+    /**
+     * Return the first node equal to the rowdata object.
+     * The rowdata has the same column mapping as this table.
+     *
+     * @param session session object
+     * @param store store object
+     * @param rowdata array containing table row data
+     * @return iterator
+     */
+    public RowIterator findFirstRow(Session session, PersistentStore store,
+                                    Object[] rowdata) {
+
+        NodeAVL node = findNode(session, store, rowdata, colIndex,
+                                colIndex.length, OpTypes.EQUAL,
+                                TransactionManager.ACTION_READ, false);
+
+        return getIterator(session, store, node, false, false);
+    }
+
+    /**
+     * Return the first node equal to the rowdata object. The rowdata has the
+     * column mapping privided in rowColMap.
+     *
+     * @param session session object
+     * @param store store object
+     * @param rowdata array containing table row data
+     * @param rowColMap int[]
+     * @return iterator
+     */
+    public RowIterator findFirstRow(Session session, PersistentStore store,
+                                    Object[] rowdata, int[] rowColMap) {
+
+        NodeAVL node = findNode(session, store, rowdata, rowColMap,
+                                rowColMap.length, OpTypes.EQUAL,
+                                TransactionManager.ACTION_READ, false);
+
+        return getIterator(session, store, node, false, false);
+    }
+
+    /**
+     * Finds the first node where the data is not null.
+     *
+     * @return iterator
+     */
+    public RowIterator findFirstRowNotNull(Session session,
+                                           PersistentStore store) {
+
+        NodeAVL node = findNode(session, store, nullData, this.defaultColMap,
+                                1, OpTypes.NOT,
+                                TransactionManager.ACTION_READ, false);
+
+        return getIterator(session, store, node, false, false);
+    }
+
+    /**
+     * Returns the row for the first node of the index
+     *
+     * @return Iterator for first row
+     */
+    public RowIterator firstRow(Session session, PersistentStore store) {
+
+        int tempDepth = 0;
+
+        readLock.lock();
+
+        try {
+            NodeAVL x = getAccessor(store);
+            NodeAVL l = x;
+
+            while (l != null) {
+                x = l;
+                l = x.getLeft(store);
+
+                tempDepth++;
+            }
+
+            while (session != null && x != null) {
+                Row row = x.getRow(store);
+
+                if (session.database.txManager.canRead(
+                        session, row, TransactionManager.ACTION_READ, null)) {
+                    break;
+                }
+
+                x = next(store, x);
+            }
+
+            return getIterator(session, store, x, false, false);
+        } finally {
+            depth = tempDepth;
+
+            readLock.unlock();
+        }
+    }
+
+    public RowIterator firstRow(PersistentStore store) {
+
+        int tempDepth = 0;
+
+        readLock.lock();
+
+        try {
+            NodeAVL x = getAccessor(store);
+            NodeAVL l = x;
+
+            while (l != null) {
+                x = l;
+                l = x.getLeft(store);
+
+                tempDepth++;
+            }
+
+            return getIterator(null, store, x, false, false);
+        } finally {
+            depth = tempDepth;
+
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * Returns the row for the last node of the index
+     *
+     * @return last row
+     */
+    public RowIterator lastRow(Session session, PersistentStore store) {
+
+        readLock.lock();
+
+        try {
+            NodeAVL x = getAccessor(store);
+            NodeAVL l = x;
+
+            while (l != null) {
+                x = l;
+                l = x.getRight(store);
+            }
+
+            while (session != null && x != null) {
+                Row row = x.getRow(store);
+
+                if (session.database.txManager.canRead(
+                        session, row, TransactionManager.ACTION_READ, null)) {
+                    break;
+                }
+
+                x = last(store, x);
+            }
+
+            return getIterator(null, store, x, false, true);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * Returns the node after the given one
+     */
+    NodeAVL next(Session session, PersistentStore store, NodeAVL x) {
+
+        if (x == null) {
+            return null;
+        }
+
+        readLock.lock();
+
+        try {
+            while (true) {
+                x = next(store, x);
+
+                if (x == null) {
+                    return x;
+                }
+
+                if (session == null) {
+                    return x;
+                }
+
+                Row row = x.getRow(store);
+
+                if (session.database.txManager.canRead(
+                        session, row, TransactionManager.ACTION_READ, null)) {
+                    return x;
+                }
+            }
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    NodeAVL last(Session session, PersistentStore store, NodeAVL x) {
+
+        if (x == null) {
+            return null;
+        }
+
+        readLock.lock();
+
+        try {
+            while (true) {
+                x = last(store, x);
+
+                if (x == null) {
+                    return x;
+                }
+
+                if (session == null) {
+                    return x;
+                }
+
+                Row row = x.getRow(store);
+
+                if (session.database.txManager.canRead(
+                        session, row, TransactionManager.ACTION_READ, null)) {
+                    return x;
+                }
+            }
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    NodeAVL next(PersistentStore store, NodeAVL x) {
+
+        NodeAVL r = x.getRight(store);
+
+        if (r != null) {
+            x = r;
+
+            NodeAVL l = x.getLeft(store);
+
+            while (l != null) {
+                x = l;
+                l = x.getLeft(store);
+            }
+
+            return x;
+        }
+
+        NodeAVL ch = x;
+
+        x = x.getParent(store);
+
+        while (x != null && ch.equals(x.getRight(store))) {
+            ch = x;
+            x  = x.getParent(store);
+        }
+
+        return x;
+    }
+
+    NodeAVL last(PersistentStore store, NodeAVL x) {
+
+        if (x == null) {
+            return null;
+        }
+
+        NodeAVL left = x.getLeft(store);
+
+        if (left != null) {
+            x = left;
+
+            NodeAVL right = x.getRight(store);
+
+            while (right != null) {
+                x     = right;
+                right = x.getRight(store);
+            }
+
+            return x;
+        }
+
+        NodeAVL ch = x;
+
+        x = x.getParent(store);
+
+        while (x != null && ch.equals(x.getLeft(store))) {
+            ch = x;
+            x  = x.getParent(store);
+        }
+
+        return x;
+    }
+
+    boolean isEqualReadable(Session session, PersistentStore store,
+                            NodeAVL node) {
+
+        NodeAVL  c = node;
+        Object[] data;
+        Object[] nodeData;
+
+        if (session.database.txManager.canRead(session, node.getRow(store),
+                                               TransactionManager.ACTION_DUP,
+                                               null)) {
+            return true;
+        }
+
+        data = node.getData(store);
+
+        while (true) {
+            c = last(store, c);
+
+            if (c == null) {
+                break;
+            }
+
+            nodeData = c.getData(store);
+
+            if (compareRow(session, data, nodeData) == 0) {
+                Row row = c.getRow(store);
+
+                if (session.database.txManager.canRead(
+                        session, row, TransactionManager.ACTION_DUP, null)) {
+                    return true;
+                }
+
+                continue;
+            }
+
+            break;
+        }
+
+        while (true) {
+            c = next(session, store, node);
+
+            if (c == null) {
+                break;
+            }
+
+            nodeData = c.getData(store);
+
+            if (compareRow(session, data, nodeData) == 0) {
+                Row row = c.getRow(store);
+
+                if (session.database.txManager.canRead(
+                        session, row, TransactionManager.ACTION_DUP, null)) {
+                    return true;
+                }
+
+                continue;
+            }
+
+            break;
+        }
+
+        return false;
+    }
+
+    /**
+     * Finds a match with a row from a different table
+     *
+     * @param session Session
+     * @param store PersistentStore
+     * @param rowdata array containing data for the index columns
+     * @param rowColMap map of the data to columns
+     * @param fieldCount int
+     * @param compareType int
+     * @param readMode int
+     * @return matching node or null
+     */
+    NodeAVL findNode(Session session, PersistentStore store, Object[] rowdata,
+                     int[] rowColMap, int fieldCount, int compareType,
+                     int readMode, boolean reversed) {
+
+        readLock.lock();
+
+        try {
+            NodeAVL x          = getAccessor(store);
+            NodeAVL n          = null;
+            NodeAVL result     = null;
+            Row     currentRow = null;
+
+            if (compareType != OpTypes.EQUAL
+                    && compareType != OpTypes.IS_NULL) {
+                fieldCount--;
+            }
+
+            while (x != null) {
+                currentRow = x.getRow(store);
+
+                int i = 0;
+
+                if (fieldCount > 0) {
+                    i = compareRowNonUnique(session, currentRow.getData(),
+                                            rowdata, rowColMap, fieldCount);
+                }
+
+                if (i == 0) {
+                    switch (compareType) {
+
+                        case OpTypes.IS_NULL :
+                        case OpTypes.EQUAL : {
+                            result = x;
+                            n      = x.getLeft(store);
+
+                            break;
+                        }
+                        case OpTypes.NOT :
+                        case OpTypes.GREATER : {
+                            i = compareObject(session, currentRow.getData(),
+                                              rowdata, rowColMap, fieldCount);
+
+                            if (i <= 0) {
+                                n = x.getRight(store);
+                            } else {
+                                result = x;
+                                n      = x.getLeft(store);
+                            }
+
+                            break;
+                        }
+                        case OpTypes.GREATER_EQUAL : {
+                            i = compareObject(session, currentRow.getData(),
+                                              rowdata, rowColMap, fieldCount);
+
+                            if (i < 0) {
+                                n = x.getRight(store);
+                            } else {
+                                result = x;
+                                n      = x.getLeft(store);
+                            }
+
+                            break;
+                        }
+                        case OpTypes.SMALLER : {
+                            i = compareObject(session, currentRow.getData(),
+                                              rowdata, rowColMap, fieldCount);
+
+                            if (i < 0) {
+                                result = x;
+                                n      = x.getRight(store);
+                            } else {
+                                n = x.getLeft(store);
+                            }
+
+                            break;
+                        }
+                        case OpTypes.SMALLER_EQUAL : {
+                            i = compareObject(session, currentRow.getData(),
+                                              rowdata, rowColMap, fieldCount);
+
+                            if (i <= 0) {
+                                result = x;
+                                n      = x.getRight(store);
+                            } else {
+                                n = x.getLeft(store);
+                            }
+
+                            break;
+                        }
+                        default :
+                            Error.runtimeError(ErrorCode.U_S0500, "Index");
+                    }
+                } else if (i < 0) {
+                    n = x.getRight(store);
+                } else if (i > 0) {
+                    n = x.getLeft(store);
+                }
+
+                if (n == null) {
+                    break;
+                }
+
+                x = n;
+            }
+
+            // MVCC 190
+            if (session == null) {
+                return result;
+            }
+
+            while (result != null) {
+                currentRow = result.getRow(store);
+
+                if (session.database.txManager.canRead(session, currentRow,
+                                                       readMode, colIndex)) {
+                    break;
+                }
+
+                result = reversed ? last(store, result)
+                                  : next(store, result);
+
+                if (result == null) {
+                    break;
+                }
+
+                currentRow = result.getRow(store);
+
+                if (fieldCount > 0
+                        && compareRowNonUnique(
+                            session, currentRow.getData(), rowdata, rowColMap,
+                            fieldCount) != 0) {
+                    result = null;
+
+                    break;
+                }
+            }
+
+            return result;
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * Finds a match with a value
+     *
+     * @param session Session
+     * @param store PersistentStore
+     * @param data value data for the index columns
+     * @param compareType int
+     * @param readMode int
+     * @return matching node or null
+     */
+    NodeAVL findNode(Session session, PersistentStore store, Object data,
+                     int compareType, int readMode) {
+
+        readLock.lock();
+
+        try {
+            NodeAVL x          = getAccessor(store);
+            NodeAVL n          = null;
+            NodeAVL result     = null;
+            Row     currentRow = null;
+
+            while (x != null) {
+                currentRow = x.getRow(store);
+
+                int i = colTypes[0].compare(session, data,
+                                            currentRow.getData()[colIndex[0]]);
+
+                switch (compareType) {
+
+                    case OpTypes.IS_NULL :
+                    case OpTypes.EQUAL : {
+                        if (i == 0) {
+                            result = x;
+                            n      = x.getLeft(store);
+
+                            break;
+                        } else if (i > 0) {
+                            n = x.getRight(store);
+                        } else if (i < 0) {
+                            n = x.getLeft(store);
+                        }
+
+                        break;
+                    }
+                    case OpTypes.NOT :
+                    case OpTypes.GREATER : {
+                        if (i >= 0) {
+                            n = x.getRight(store);
+                        } else {
+                            result = x;
+                            n      = x.getLeft(store);
+                        }
+
+                        break;
+                    }
+                    case OpTypes.GREATER_EQUAL : {
+                        if (i > 0) {
+                            n = x.getRight(store);
+                        } else {
+                            result = x;
+                            n      = x.getLeft(store);
+                        }
+
+                        break;
+                    }
+                    default :
+                        Error.runtimeError(ErrorCode.U_S0500, "Index");
+                }
+
+                if (n == null) {
+                    break;
+                }
+
+                x = n;
+            }
+
+            // MVCC 190
+            if (session == null) {
+                return result;
+            }
+
+            while (result != null) {
+                currentRow = result.getRow(store);
+
+                if (session.database.txManager.canRead(session, currentRow,
+                                                       readMode, colIndex)) {
+                    break;
+                }
+
+                result = next(store, result);
+
+                if (compareType == OpTypes.EQUAL) {
+                    if (colTypes[0].compare(
+                            session, data,
+                            currentRow.getData()[colIndex[0]]) != 0) {
+                        result = null;
+
+                        break;
+                    }
+                }
+            }
+
+            return result;
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * Balances part of the tree after an alteration to the index.
+     */
+    void balance(PersistentStore store, NodeAVL x, boolean isleft) {
+
+        while (true) {
+            int sign = isleft ? 1
+                              : -1;
+
+            switch (x.getBalance(store) * sign) {
+
+                case 1 :
+                    x = x.setBalance(store, 0);
+
+                    return;
+
+                case 0 :
+                    x = x.setBalance(store, -sign);
+                    break;
+
+                case -1 :
+                    NodeAVL l = x.child(store, isleft);
+
+                    if (l.getBalance(store) == -sign) {
+                        x.replace(store, this, l);
+
+                        x = x.set(store, isleft, l.child(store, !isleft));
+                        l = l.set(store, !isleft, x);
+                        x = x.setBalance(store, 0);
+                        l = l.setBalance(store, 0);
+                    } else {
+                        NodeAVL r = l.child(store, !isleft);
+
+                        x.replace(store, this, r);
+
+                        l = l.set(store, !isleft, r.child(store, isleft));
+                        r = r.set(store, isleft, l);
+                        x = x.set(store, isleft, r.child(store, !isleft));
+                        r = r.set(store, !isleft, x);
+
+                        int rb = r.getBalance(store);
+
+                        x = x.setBalance(store, (rb == -sign) ? sign
+                                                              : 0);
+                        l = l.setBalance(store, (rb == sign) ? -sign
+                                                             : 0);
+                        r = r.setBalance(store, 0);
+                    }
+
+                    return;
+            }
+
+            if (x.isRoot(store)) {
+                return;
+            }
+
+            isleft = x.isFromLeft(store);
+            x      = x.getParent(store);
+        }
+    }
+
+    NodeAVL getAccessor(PersistentStore store) {
+
+        NodeAVL node = (NodeAVL) store.getAccessor(this);
+
+        return node;
+    }
+
+    IndexRowIterator getIterator(Session session, PersistentStore store,
+                                 NodeAVL x, boolean single, boolean reversed) {
+
+        if (x == null) {
+            return emptyIterator;
+        } else {
+            IndexRowIterator it = new IndexRowIterator(session, store, this,
+                x, single, reversed);
+
+            return it;
+        }
+    }
+
+    public static final class IndexRowIterator implements RowIterator {
+
+        final Session         session;
+        final PersistentStore store;
+        final IndexAVL        index;
+        NodeAVL               nextnode;
+        Row                   lastrow;
+        boolean               single;
+        boolean               reversed;
+        IndexRowIterator      last;
+        IndexRowIterator      next;
+        IndexRowIterator      lastInSession;
+        IndexRowIterator      nextInSession;
+
+        /**
+         * When session == null, rows from all sessions are returned
+         */
+        public IndexRowIterator(Session session, PersistentStore store,
+                                IndexAVL index, NodeAVL node, boolean single,
+                                boolean reversed) {
+
+            this.session  = session;
+            this.store    = store;
+            this.index    = index;
+            this.single   = single;
+            this.reversed = reversed;
+
+            if (index == null) {
+                return;
+            }
+
+            nextnode = node;
+        }
+
+        public boolean hasNext() {
+            return nextnode != null;
+        }
+
+        public Row getNextRow() {
+
+            if (nextnode == null) {
+                release();
+
+                return null;
+            }
+
+            lastrow = nextnode.getRow(store);
+
+            if (single) {
+                nextnode = null;
+            } else if (reversed) {
+                nextnode = index.last(session, store, nextnode);
+            } else {
+                nextnode = index.next(session, store, nextnode);
+            }
+
+            return lastrow;
+        }
+
+        public Object[] getNext() {
+
+            Row row = getNextRow();
+
+            return row == null ? null
+                               : row.getData();
+        }
+
+        public void remove() {
+            store.delete(session, lastrow);
+            store.remove(lastrow.getPos());
+        }
+
+        public void release() {}
+
+        public boolean setRowColumns(boolean[] columns) {
+            return false;
+        }
+
+        public long getRowId() {
+            return nextnode.getPos();
+        }
+    }
+}
diff --git a/src/org/hsqldb/index/IndexAVLMemory.java b/src/org/hsqldb/index/IndexAVLMemory.java
new file mode 100644
index 0000000..e84c706
--- /dev/null
+++ b/src/org/hsqldb/index/IndexAVLMemory.java
@@ -0,0 +1,561 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.index;
+
+import org.hsqldb.Constraint;
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.Row;
+import org.hsqldb.RowAVL;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.types.Type;
+
+/**
+ * Implementation of an AVL for memory tables.<p>
+ *
+ *  New class derived from Hypersonic SQL code and enhanced in HSQLDB. <p>
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class IndexAVLMemory extends IndexAVL {
+
+    /**
+     * Constructor declaration
+     *
+     * @param name HsqlName of the index
+     * @param id persistnece id
+     * @param table table of the index
+     * @param columns array of column indexes
+     * @param descending boolean[]
+     * @param nullsLast boolean[]
+     * @param colTypes array of column types
+     * @param pk if index is for a primary key
+     * @param unique is this a unique index
+     * @param constraint does this index belonging to a constraint
+     * @param forward is this an auto-index for an FK that refers to a table
+     *   defined after this table
+     */
+    public IndexAVLMemory(HsqlName name, long id, TableBase table,
+                          int[] columns, boolean[] descending,
+                          boolean[] nullsLast, Type[] colTypes, boolean pk,
+                          boolean unique, boolean constraint,
+                          boolean forward) {
+        super(name, id, table, columns, descending, nullsLast, colTypes, pk,
+              unique, constraint, forward);
+    }
+
+    public void checkIndex(PersistentStore store) {
+
+        readLock.lock();
+
+        try {
+            NodeAVL p = getAccessor(store);
+            NodeAVL f = null;
+
+            while (p != null) {
+                f = p;
+
+                checkNodes(store, p);
+
+                p = p.nLeft;
+            }
+
+            p = f;
+
+            while (f != null) {
+                checkNodes(store, f);
+
+                f = next(store, f);
+            }
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    void checkNodes(PersistentStore store, NodeAVL p) {
+
+        NodeAVL l = p.nLeft;
+        NodeAVL r = p.nRight;
+
+        if (l != null && l.getBalance(store) == -2) {
+            System.out.print("broken index - deleted");
+        }
+
+        if (r != null && r.getBalance(store) == -2) {
+            System.out.print("broken index -deleted");
+        }
+
+        if (l != null && !p.equals(l.getParent(store))) {
+            System.out.print("broken index - no parent");
+        }
+
+        if (r != null && !p.equals(r.getParent(store))) {
+            System.out.print("broken index - no parent");
+        }
+    }
+
+    /**
+     * Insert a node into the index
+     */
+    public void insert(Session session, PersistentStore store, Row row) {
+
+        NodeAVL        n;
+        NodeAVL        x;
+        boolean        isleft        = true;
+        int            compare       = -1;
+        final Object[] rowData       = row.getData();
+        boolean        compareRowId  = !isUnique || hasNulls(rowData);
+        boolean        compareSimple = isSimple;
+
+        writeLock.lock();
+
+        try {
+            n = getAccessor(store);
+            x = n;
+
+            if (n == null) {
+                store.setAccessor(this, ((RowAVL) row).getNode(position));
+                store.setElementCount(this, 1, 1);
+
+                return;
+            }
+
+            while (true) {
+                Row currentRow = n.row;
+
+                compare = 0;
+
+                if (compareSimple) {
+                    compare =
+                        colTypes[0].compare(session, rowData[colIndex[0]],
+                                            currentRow.getData()[colIndex[0]]);
+
+                    if (compare == 0 && compareRowId) {
+                        compare = compareRowForInsertOrDelete(session, row,
+                                                              currentRow,
+                                                              compareRowId, 1);
+                    }
+                } else {
+                    compare = compareRowForInsertOrDelete(session, row,
+                                                          currentRow,
+                                                          compareRowId, 0);
+                }
+
+                // after the first match and check, all compares are with row id
+                if (compare == 0 && session != null && !compareRowId
+                        && session.database.txManager.isMVRows()) {
+                    if (!isEqualReadable(session, store, n)) {
+                        compareRowId = true;
+                        compare = compareRowForInsertOrDelete(session, row,
+                                                              currentRow,
+                                                              compareRowId,
+                                                              colIndex.length);
+                    }
+                }
+
+                if (compare == 0) {
+                    if (isConstraint) {
+                        Constraint c =
+                            ((Table) table).getUniqueConstraintForIndex(this);
+
+                        throw c.getException(row.getData());
+                    } else {
+                        throw Error.error(ErrorCode.X_23505,
+                                          name.statementName);
+                    }
+                }
+
+                isleft = compare < 0;
+                x      = n;
+                n      = isleft ? x.nLeft
+                                : x.nRight;
+
+                if (n == null) {
+                    break;
+                }
+            }
+
+            x = x.set(store, isleft, ((RowAVL) row).getNode(position));
+
+            balance(store, x, isleft);
+            store.updateElementCount(this, 1, 1);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    void delete(PersistentStore store, NodeAVL x) {
+
+        if (x == null) {
+            return;
+        }
+
+        NodeAVL n;
+
+        writeLock.lock();
+
+        try {
+            if (x.nLeft == null) {
+                n = x.nRight;
+            } else if (x.nRight == null) {
+                n = x.nLeft;
+            } else {
+                NodeAVL d = x;
+
+                x = x.nLeft;
+
+                while (true) {
+                    NodeAVL temp = x.nRight;
+
+                    if (temp == null) {
+                        break;
+                    }
+
+                    x = temp;
+                }
+
+                // x will be replaced with n later
+                n = x.nLeft;
+
+                // swap d and x
+                int b = x.iBalance;
+
+                x.iBalance = d.iBalance;
+                d.iBalance = b;
+
+                // set x.parent
+                NodeAVL xp = x.nParent;
+                NodeAVL dp = d.nParent;
+
+                if (d.isRoot(store)) {
+                    store.setAccessor(this, x);
+                }
+
+                x.nParent = dp;
+
+                if (dp != null) {
+                    if (dp.nRight == d) {
+                        dp.nRight = x;
+                    } else {
+                        dp.nLeft = x;
+                    }
+                }
+
+                // relink d.parent, x.left, x.right
+                if (d == xp) {
+                    d.nParent = x;
+
+                    if (d.nLeft == x) {
+                        x.nLeft = d;
+
+                        NodeAVL dr = d.nRight;
+
+                        x.nRight = dr;
+                    } else {
+                        x.nRight = d;
+
+                        NodeAVL dl = d.nLeft;
+
+                        x.nLeft = dl;
+                    }
+                } else {
+                    d.nParent = xp;
+                    xp.nRight = d;
+
+                    NodeAVL dl = d.nLeft;
+                    NodeAVL dr = d.nRight;
+
+                    x.nLeft  = dl;
+                    x.nRight = dr;
+                }
+
+                x.nRight.nParent = x;
+                x.nLeft.nParent  = x;
+
+                // set d.left, d.right
+                d.nLeft = n;
+
+                if (n != null) {
+                    n.nParent = d;
+                }
+
+                d.nRight = null;
+                x        = d;
+            }
+
+            boolean isleft = x.isFromLeft(store);
+
+            x.replace(store, this, n);
+
+            n = x.nParent;
+
+            x.delete();
+
+            while (n != null) {
+                x = n;
+
+                int sign = isleft ? 1
+                                  : -1;
+
+                switch (x.iBalance * sign) {
+
+                    case -1 :
+                        x.iBalance = 0;
+                        break;
+
+                    case 0 :
+                        x.iBalance = sign;
+
+                        return;
+
+                    case 1 :
+                        NodeAVL r = x.child(store, !isleft);
+                        int     b = r.iBalance;
+
+                        if (b * sign >= 0) {
+                            x.replace(store, this, r);
+
+                            NodeAVL child = r.child(store, isleft);
+
+                            x.set(store, !isleft, child);
+                            r.set(store, isleft, x);
+
+                            if (b == 0) {
+                                x.iBalance = sign;
+                                r.iBalance = -sign;
+
+                                return;
+                            }
+
+                            x.iBalance = 0;
+                            r.iBalance = 0;
+                            x          = r;
+                        } else {
+                            NodeAVL l = r.child(store, isleft);
+
+                            x.replace(store, this, l);
+
+                            b = l.iBalance;
+
+                            r.set(store, isleft, l.child(store, !isleft));
+                            l.set(store, !isleft, r);
+                            x.set(store, !isleft, l.child(store, isleft));
+                            l.set(store, isleft, x);
+
+                            x.iBalance = (b == sign) ? -sign
+                                                     : 0;
+                            r.iBalance = (b == -sign) ? sign
+                                                      : 0;
+                            l.iBalance = 0;
+                            x          = l;
+                        }
+                }
+
+                isleft = x.isFromLeft(store);
+                n      = x.nParent;
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    NodeAVL next(PersistentStore store, NodeAVL x) {
+
+        NodeAVL r = x.nRight;
+
+        if (r != null) {
+            x = r;
+
+            NodeAVL l = x.nLeft;
+
+            while (l != null) {
+                x = l;
+                l = x.nLeft;
+            }
+
+            return x;
+        }
+
+        NodeAVL ch = x;
+
+        x = x.nParent;
+
+        while (x != null && ch == x.nRight) {
+            ch = x;
+            x  = x.nParent;
+        }
+
+        return x;
+    }
+
+    NodeAVL last(PersistentStore store, NodeAVL x) {
+
+        if (x == null) {
+            return null;
+        }
+
+        NodeAVL left = x.nLeft;
+
+        if (left != null) {
+            x = left;
+
+            NodeAVL right = x.nRight;
+
+            while (right != null) {
+                x     = right;
+                right = x.nRight;
+            }
+
+            return x;
+        }
+
+        NodeAVL ch = x;
+
+        x = x.nParent;
+
+        while (x != null && ch.equals(x.nLeft)) {
+            ch = x;
+            x  = x.nParent;
+        }
+
+        return x;
+    }
+
+    /**
+     * Balances part of the tree after an alteration to the index.
+     */
+    void balance(PersistentStore store, NodeAVL x, boolean isleft) {
+
+        while (true) {
+            int sign = isleft ? 1
+                              : -1;
+
+            switch (x.iBalance * sign) {
+
+                case 1 :
+                    x.iBalance = 0;
+
+                    return;
+
+                case 0 :
+                    x.iBalance = -sign;
+                    break;
+
+                case -1 :
+                    NodeAVL l = isleft ? x.nLeft
+                                       : x.nRight;
+
+                    if (l.iBalance == -sign) {
+                        x.replace(store, this, l);
+                        x.set(store, isleft, l.child(store, !isleft));
+                        l.set(store, !isleft, x);
+
+                        x.iBalance = 0;
+                        l.iBalance = 0;
+                    } else {
+                        NodeAVL r = !isleft ? l.nLeft
+                                            : l.nRight;
+
+                        x.replace(store, this, r);
+                        l.set(store, !isleft, r.child(store, isleft));
+                        r.set(store, isleft, l);
+                        x.set(store, isleft, r.child(store, !isleft));
+                        r.set(store, !isleft, x);
+
+                        int rb = r.iBalance;
+
+                        x.iBalance = (rb == -sign) ? sign
+                                                   : 0;
+                        l.iBalance = (rb == sign) ? -sign
+                                                  : 0;
+                        r.iBalance = 0;
+                    }
+
+                    return;
+            }
+
+            if (x.nParent == null) {
+                return;
+            }
+
+            isleft = x.nParent == null || x == x.nParent.nLeft;
+            x      = x.nParent;
+        }
+    }
+}
diff --git a/src/org/hsqldb/index/NodeAVL.java b/src/org/hsqldb/index/NodeAVL.java
new file mode 100644
index 0000000..4c67c4e
--- /dev/null
+++ b/src/org/hsqldb/index/NodeAVL.java
@@ -0,0 +1,289 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.index;
+
+import org.hsqldb.Row;
+import org.hsqldb.RowAVLDisk;
+import org.hsqldb.lib.IntLookup;
+import org.hsqldb.persist.CachedObject;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.rowio.RowOutputInterface;
+
+// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
+// fredt@users 20020920 - path 1.7.1 - refactoring to cut mamory footprint
+// fredt@users 20021205 - path 1.7.2 - enhancements
+// fredt@users 20021215 - doc 1.7.2 - javadoc comments
+
+/**
+ *  The parent for all AVL node implementations. Subclasses of Node vary
+ *  in the way they hold
+ *  references to other Nodes in the AVL tree, or to their Row data.<br>
+ *
+ *  nNext links the Node objects belonging to different indexes for each
+ *  table row. It is used solely by Row to locate the node belonging to a
+ *  particular index.<br>
+ *
+ *  New class derived from Hypersonic SQL code and enhanced in HSQLDB. <p>
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class NodeAVL implements CachedObject {
+
+    static final int NO_POS = RowAVLDisk.NO_POS;
+    public int       iBalance;
+    public NodeAVL   nNext;    // node of next index (nNext==null || nNext.iId=iId+1)
+
+    //
+    protected NodeAVL nLeft;
+    protected NodeAVL nRight;
+    protected NodeAVL nParent;
+    protected final Row row;
+
+    NodeAVL() {
+        row = null;
+    }
+
+    public NodeAVL(Row r) {
+        row = r;
+    }
+
+    public void delete() {
+        iBalance = 0;
+        nLeft    = nRight = nParent = null;
+    }
+
+    NodeAVL getLeft(PersistentStore store) {
+        return nLeft;
+    }
+
+    NodeAVL setLeft(PersistentStore persistentStore, NodeAVL n) {
+
+        nLeft = n;
+
+        return this;
+    }
+
+    public int getBalance(PersistentStore store) {
+        return iBalance;
+    }
+
+    boolean isLeft(NodeAVL node) {
+        return nLeft == node;
+    }
+
+    boolean isRight(NodeAVL node) {
+        return nRight == node;
+    }
+
+    NodeAVL getRight(PersistentStore persistentStore) {
+        return nRight;
+    }
+
+    NodeAVL setRight(PersistentStore persistentStore, NodeAVL n) {
+
+        nRight = n;
+
+        return this;
+    }
+
+    NodeAVL getParent(PersistentStore store) {
+        return nParent;
+    }
+
+    boolean isRoot(PersistentStore store) {
+        return nParent == null;
+    }
+
+    NodeAVL setParent(PersistentStore persistentStore, NodeAVL n) {
+
+        nParent = n;
+
+        return this;
+    }
+
+    public NodeAVL setBalance(PersistentStore store, int b) {
+
+        iBalance = b;
+
+        return this;
+    }
+
+    boolean isFromLeft(PersistentStore store) {
+
+        if (nParent == null) {
+            return true;
+        }
+
+        return this == nParent.nLeft;
+    }
+
+    public NodeAVL child(PersistentStore store, boolean isleft) {
+        return isleft ? getLeft(store)
+            : getRight(store);
+    }
+
+    public NodeAVL set(PersistentStore store, boolean isLeft, NodeAVL n) {
+
+        if (isLeft) {
+            nLeft = n;
+        } else {
+            nRight = n;
+        }
+
+        if (n != null) {
+            n.nParent = this;
+        }
+
+        return this;
+    }
+
+    public void replace(PersistentStore store, Index index, NodeAVL n) {
+
+        if (nParent == null) {
+            if (n != null) {
+                n = n.setParent(store, null);
+            }
+
+            store.setAccessor(index, n);
+        } else {
+            nParent.set(store, isFromLeft(store), n);
+        }
+    }
+
+    boolean equals(NodeAVL n) {
+        return n == this;
+    }
+
+    public void setInMemory(boolean in) {}
+
+    public void write(RowOutputInterface out) {}
+
+    public void write(RowOutputInterface out, IntLookup lookup) {}
+
+    public int getPos() {
+        return 0;
+    }
+
+    protected Row getRow(PersistentStore store) {
+        return row;
+    }
+
+    protected Object[] getData(PersistentStore store) {
+        return row.getData();
+    }
+
+
+    public void updateAccessCount(int count) {}
+
+    public int getAccessCount() {
+        return 0;
+    }
+
+    public void setStorageSize(int size) {}
+
+    public int getStorageSize() {
+        return 0;
+    }
+
+    public void setPos(int pos) {}
+
+    public boolean hasChanged() {
+        return false;
+    }
+
+    public boolean isKeepInMemory() {
+        return false;
+    }
+    ;
+
+    public boolean keepInMemory(boolean keep) {
+        return true;
+    }
+
+    public boolean isInMemory() {
+        return false;
+    }
+
+    public void restore() {}
+
+    public void destroy() {}
+
+    public int getRealSize(RowOutputInterface out) {
+        return 0;
+    }
+
+    public boolean isMemory() {
+        return true;
+    }
+
+}
diff --git a/src/org/hsqldb/index/NodeAVLDisk.java b/src/org/hsqldb/index/NodeAVLDisk.java
new file mode 100644
index 0000000..c7ae4ae
--- /dev/null
+++ b/src/org/hsqldb/index/NodeAVLDisk.java
@@ -0,0 +1,589 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.index;
+
+import java.io.IOException;
+
+import org.hsqldb.Row;
+import org.hsqldb.RowAVLDisk;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.IntLookup;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
+// fredt@users 20020920 - path 1.7.1 - refactoring to cut mamory footprint
+// fredt@users 20021205 - path 1.7.2 - enhancements
+
+/**
+ *  Cached table Node implementation.<p>
+ *  Only integral references to left, right and parent nodes in the AVL tree
+ *  are held and used as pointers data.<p>
+ *
+ *  iId is a reference to the Index object that contains this node.<br>
+ *  This fields can be eliminated in the future, by changing the
+ *  method signatures to take a Index parameter from Index.java (fredt@users)
+ *
+ *  New class derived from Hypersonic SQL code and enhanced in HSQLDB. <p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge dot net)
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class NodeAVLDisk extends NodeAVL {
+
+    final RowAVLDisk row;
+
+    //
+    public int              iData;
+    private int             iLeft   = NO_POS;
+    private int             iRight  = NO_POS;
+    private int             iParent = NO_POS;
+    private int             iId;    // id of Index object for this Node
+    public static final int SIZE_IN_BYTE = 4 * 4;
+
+    public NodeAVLDisk(RowAVLDisk r, RowInputInterface in,
+                       int id) throws IOException {
+
+        row      = r;
+        iId      = id;
+        iData    = r.getPos();
+        iBalance = in.readInt();
+        iLeft    = in.readInt();
+
+        if (iLeft <= 0) {
+            iLeft = NO_POS;
+        }
+
+        iRight = in.readInt();
+
+        if (iRight <= 0) {
+            iRight = NO_POS;
+        }
+
+        iParent = in.readInt();
+
+        if (iParent <= 0) {
+            iParent = NO_POS;
+        }
+    }
+
+    public NodeAVLDisk(RowAVLDisk r, int id) {
+
+        row   = r;
+        iId   = id;
+        iData = r.getPos();
+    }
+
+    public void delete() {
+
+        iLeft    = NO_POS;
+        iRight   = NO_POS;
+        iParent  = NO_POS;
+        nLeft    = null;
+        nRight   = null;
+        nParent  = null;
+        iBalance = 0;
+
+        row.setNodesChanged();
+    }
+
+    public boolean isInMemory() {
+        return row.isInMemory();
+    }
+
+    public boolean isMemory() {
+        return false;
+    }
+
+    public int getPos() {
+        return iData;
+    }
+
+    public Row getRow(PersistentStore store) {
+
+        if (!row.isInMemory()) {
+            return (RowAVLDisk) store.get(this.row, false);
+        } else {
+            row.updateAccessCount(store.getAccessCount());
+        }
+
+        return row;
+    }
+
+    public Object[] getData(PersistentStore store) {
+        return row.getData();
+    }
+
+    private NodeAVLDisk findNode(PersistentStore store, int pos) {
+
+        NodeAVLDisk ret = null;
+        RowAVLDisk  r   = (RowAVLDisk) store.get(pos, false);
+
+        if (r != null) {
+            ret = (NodeAVLDisk) r.getNode(iId);
+        }
+
+        return ret;
+    }
+
+    boolean isLeft(NodeAVL n) {
+
+        if (n == null) {
+            return iLeft == NO_POS;
+        }
+
+        return iLeft == ((NodeAVLDisk) n).iData;
+    }
+
+    boolean isRight(NodeAVL n) {
+
+        if (n == null) {
+            return iRight == NO_POS;
+        }
+
+        return iRight == ((NodeAVLDisk) n).iData;
+    }
+
+    NodeAVL getLeft(PersistentStore store) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.isInMemory()) {
+            row  = (RowAVLDisk) store.get(this.row, false);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (node.iLeft == NO_POS) {
+            return null;
+        }
+
+        if (node.nLeft == null || !node.nLeft.isInMemory()) {
+            node.nLeft         = findNode(store, node.iLeft);
+            node.nLeft.nParent = node;
+        }
+
+        return node.nLeft;
+    }
+
+    NodeAVL getRight(PersistentStore store) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.isInMemory()) {
+            row  = (RowAVLDisk) store.get(this.row, false);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (node.iRight == NO_POS) {
+            return null;
+        }
+
+        if (node.nRight == null || !node.nRight.isInMemory()) {
+            node.nRight         = findNode(store, node.iRight);
+            node.nRight.nParent = node;
+        }
+
+        return node.nRight;
+    }
+
+    NodeAVL getParent(PersistentStore store) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.isInMemory()) {
+            row  = (RowAVLDisk) store.get(this.row, false);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (node.iParent == NO_POS) {
+            return null;
+        }
+
+        if (node.nParent == null || !node.nParent.isInMemory()) {
+            node.nParent = findNode(store, iParent);
+        }
+
+        return node.nParent;
+    }
+
+    public int getBalance(PersistentStore store) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.isInMemory()) {
+            row  = (RowAVLDisk) store.get(this.row, false);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        return node.iBalance;
+    }
+
+    boolean isRoot(PersistentStore store) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.isInMemory()) {
+            row  = (RowAVLDisk) store.get(this.row, false);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        return node.iParent == NO_POS;
+    }
+
+    boolean isFromLeft(PersistentStore store) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.isInMemory()) {
+            row  = (RowAVLDisk) store.get(this.row, false);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (node.iParent == NO_POS) {
+            return true;
+        }
+
+        if (node.nParent == null || !node.nParent.isInMemory()) {
+            node.nParent = findNode(store, iParent);
+        }
+
+        return getPos() == ((NodeAVLDisk) node.nParent).iLeft;
+    }
+
+    public NodeAVL child(PersistentStore store, boolean isleft) {
+        return isleft ? getLeft(store)
+                      : getRight(store);
+    }
+
+    NodeAVL setParent(PersistentStore store, NodeAVL n) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.keepInMemory(true)) {
+            row  = (RowAVLDisk) store.get(this.row, true);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (!row.isInMemory()) {
+            row.keepInMemory(false);
+
+            throw Error.runtimeError(ErrorCode.U_S0500, "NodeAVLDisk");
+        }
+
+        row.setNodesChanged();
+
+        node.iParent = n == null ? NO_POS
+                                 : n.getPos();
+
+        if (n != null && !n.isInMemory()) {
+            n = findNode(store, n.getPos());
+        }
+
+        node.nParent = (NodeAVLDisk) n;
+
+        row.keepInMemory(false);
+
+        return node;
+    }
+
+    public NodeAVL setBalance(PersistentStore store, int b) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.keepInMemory(true)) {
+            row  = (RowAVLDisk) store.get(this.row, true);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (!row.isInMemory()) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "NodeAVLDisk");
+        }
+
+        row.setNodesChanged();
+
+        node.iBalance = b;
+
+        row.keepInMemory(false);
+
+        return node;
+    }
+
+    NodeAVL setLeft(PersistentStore store, NodeAVL n) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.keepInMemory(true)) {
+            row  = (RowAVLDisk) store.get(this.row, true);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (!row.isInMemory()) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "NodeAVLDisk");
+        }
+
+        row.setNodesChanged();
+
+        node.iLeft = n == null ? NO_POS
+                               : n.getPos();
+
+        if (n != null && !n.isInMemory()) {
+            n = findNode(store, n.getPos());
+        }
+
+        node.nLeft = (NodeAVLDisk) n;
+
+        row.keepInMemory(false);
+
+        return node;
+    }
+
+    NodeAVL setRight(PersistentStore store, NodeAVL n) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.keepInMemory(true)) {
+            row  = (RowAVLDisk) store.get(this.row, true);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (!row.isInMemory()) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "NodeAVLDisk");
+        }
+
+        row.setNodesChanged();
+
+        node.iRight = n == null ? NO_POS
+                                : n.getPos();
+
+        if (n != null && !n.isInMemory()) {
+            n = findNode(store, n.getPos());
+        }
+
+        node.nRight = (NodeAVLDisk) n;
+
+        row.keepInMemory(false);
+
+        return node;
+    }
+
+    public NodeAVL set(PersistentStore store, boolean isLeft, NodeAVL n) {
+
+        NodeAVL x;
+
+        if (isLeft) {
+            x = setLeft(store, n);
+        } else {
+            x = setRight(store, n);
+        }
+
+        if (n != null) {
+            n.setParent(store, this);
+        }
+
+        return x;
+    }
+
+    public void replace(PersistentStore store, Index index, NodeAVL n) {
+
+        NodeAVLDisk node = this;
+        RowAVLDisk  row  = this.row;
+
+        if (!row.keepInMemory(true)) {
+            row  = (RowAVLDisk) store.get(this.row, true);
+            node = (NodeAVLDisk) row.getNode(iId);
+        }
+
+        if (node.iParent == NO_POS) {
+            if (n != null) {
+                n = n.setParent(store, null);
+            }
+
+            store.setAccessor(index, n);
+        } else {
+            boolean isFromLeft = node.isFromLeft(store);
+
+            node.getParent(store).set(store, isFromLeft, n);
+        }
+
+        row.keepInMemory(false);
+    }
+
+    boolean equals(NodeAVL n) {
+
+        if (n instanceof NodeAVLDisk) {
+            return this == n || (getPos() == ((NodeAVLDisk) n).getPos());
+        }
+
+        return false;
+    }
+
+    public int getRealSize(RowOutputInterface out) {
+        return NodeAVLDisk.SIZE_IN_BYTE;
+    }
+
+    public void setInMemory(boolean in) {
+
+        if (!in) {
+            if (nLeft != null) {
+                nLeft.nParent = null;
+            }
+
+            if (nRight != null) {
+                nRight.nParent = null;
+            }
+
+            if (nParent != null) {
+                if (iData == ((NodeAVLDisk) nParent).iLeft) {
+                    nParent.nLeft = null;
+                } else {
+                    nParent.nRight = null;
+                }
+            }
+
+            nLeft = nRight = nParent = null;
+        }
+    }
+
+    public void write(RowOutputInterface out) {
+
+        out.writeInt(iBalance);
+        out.writeInt((iLeft == NO_POS) ? 0
+                                       : iLeft);
+        out.writeInt((iRight == NO_POS) ? 0
+                                        : iRight);
+        out.writeInt((iParent == NO_POS) ? 0
+                                         : iParent);
+    }
+
+    public void write(RowOutputInterface out, IntLookup lookup) {
+
+        out.writeInt(iBalance);
+        writeTranslatePointer(iLeft, out, lookup);
+        writeTranslatePointer(iRight, out, lookup);
+        writeTranslatePointer(iParent, out, lookup);
+    }
+
+    private static void writeTranslatePointer(int pointer,
+            RowOutputInterface out, IntLookup lookup) {
+
+        int newPointer = 0;
+
+        if (pointer != NodeAVL.NO_POS) {
+            newPointer = lookup.lookupFirstEqual(pointer);
+        }
+
+        out.writeInt(newPointer);
+    }
+
+    public void restore() {}
+
+    public void destroy() {}
+
+    public void updateAccessCount(int count) {}
+
+    public int getAccessCount() {
+        return 0;
+    }
+
+    public void setStorageSize(int size) {}
+
+    public int getStorageSize() {
+        return 0;
+    }
+
+    public void setPos(int pos) {}
+
+    public boolean hasChanged() {
+        return false;
+    }
+
+    public boolean isKeepInMemory() {
+        return false;
+    }
+
+    public boolean keepInMemory(boolean keep) {
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/BlobInputStream.java b/src/org/hsqldb/jdbc/BlobInputStream.java
new file mode 100644
index 0000000..77b517f
--- /dev/null
+++ b/src/org/hsqldb/jdbc/BlobInputStream.java
@@ -0,0 +1,146 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.SQLException;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.java.JavaSystem;
+
+/**
+ * This class is used as an InputStream to retrieve data from a Blob.
+ * mark() and reset() are not supported.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class BlobInputStream extends InputStream {
+
+    final JDBCBlobClient blob;
+    final long availableLength;
+    long       bufferOffset;
+    long       currentPosition;
+    byte[]     buffer;
+    boolean    isClosed;
+    int        streamBlockSize;
+
+    public BlobInputStream(JDBCBlobClient blob, long offset, long length,
+                           int blockSize) throws SQLException {
+
+        if (!JDBCBlobClient.isInLimits(blob.length(), offset, length)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        this.blob            = blob;
+        this.availableLength = offset + length;
+        this.currentPosition = offset;
+        this.streamBlockSize = blockSize;
+    }
+
+    public int read() throws IOException {
+
+        checkClosed();
+
+        if (currentPosition >= availableLength) {
+            return -1;
+        }
+
+        if (buffer == null
+                || currentPosition >= bufferOffset + buffer.length) {
+            try {
+                readIntoBuffer();
+            } catch (SQLException e) {
+                throw JavaSystem.toIOException(e);
+            }
+        }
+
+        int val = buffer[(int) (currentPosition - bufferOffset)] & 0xff;
+
+        currentPosition++;
+
+        return val;
+    }
+
+    public long skip(long n) throws IOException {
+
+        checkClosed();
+
+        if (n <= 0) {
+            return 0;
+        }
+
+        if (currentPosition + n > availableLength) {
+            n = availableLength - currentPosition;
+        }
+
+        currentPosition += n;
+
+        return n;
+    }
+
+    public int available() throws IOException {
+
+        checkClosed();
+
+        return (int) (bufferOffset + buffer.length - currentPosition);
+    }
+
+    public void close() throws IOException {
+        isClosed = true;
+    }
+
+    private void checkClosed() throws IOException {
+
+        if (isClosed || blob.isClosed()) {
+            throw new IOException(
+                Error.getMessage(ErrorCode.X_0F503));
+        }
+    }
+
+    private void readIntoBuffer() throws SQLException {
+
+        long readLength = availableLength - currentPosition;
+
+        if (readLength <= 0) {}
+
+        if (readLength > streamBlockSize) {
+            readLength = streamBlockSize;
+        }
+
+        buffer       = blob.getBytes(currentPosition + 1, (int) readLength);
+        bufferOffset = currentPosition;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/ClobInputStream.java b/src/org/hsqldb/jdbc/ClobInputStream.java
new file mode 100644
index 0000000..071b891
--- /dev/null
+++ b/src/org/hsqldb/jdbc/ClobInputStream.java
@@ -0,0 +1,158 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.sql.SQLException;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.java.JavaSystem;
+
+/**
+ * This class is used as an InputStream to retrieve data from a Blob.
+ * mark() and reset() are not supported.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class ClobInputStream extends Reader {
+
+    final JDBCClobClient clob;
+    final long           availableLength;
+    long                 bufferOffset;
+    long                 currentPosition;
+    char[]               buffer;
+    boolean              isClosed;
+    int                  streamBlockSize;
+
+    public ClobInputStream(JDBCClobClient clob, long offset, long length,
+                           int blockSize) throws SQLException {
+
+        if (!JDBCClobClient.isInLimits(clob.length(), offset, length)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        this.clob            = clob;
+        this.availableLength = offset + length;
+        this.currentPosition = offset;
+        this.streamBlockSize = blockSize;
+    }
+
+    public int read() throws IOException {
+
+        checkClosed();
+
+        if (currentPosition >= availableLength) {
+            return -1;
+        }
+
+        if (buffer == null
+                || currentPosition >= bufferOffset + buffer.length) {
+            try {
+                readIntoBuffer();
+            } catch (SQLException e) {
+                throw JavaSystem.toIOException(e);
+            }
+        }
+
+        int val = buffer[(int) (currentPosition - bufferOffset)] & 0xff;
+
+        currentPosition++;
+
+        return val;
+    }
+
+    public int read(char[] cbuf, int off, int len) throws IOException {
+
+        checkClosed();
+
+        if (currentPosition + len >= availableLength) {
+            return -1;
+        }
+
+        for (int i = off; i < len; i++) {
+            cbuf[i] = (char) read();
+        }
+
+        return len;
+    }
+
+    public long skip(long n) throws IOException {
+
+        checkClosed();
+
+        if (n <= 0) {
+            return 0;
+        }
+
+        if (currentPosition + n > availableLength) {
+            n = availableLength - currentPosition;
+        }
+
+        currentPosition += n;
+
+        return n;
+    }
+
+    public int available() throws IOException {
+        return (int) (bufferOffset + buffer.length - currentPosition);
+    }
+
+    public void close() throws IOException {
+        isClosed = true;
+    }
+
+    private void checkClosed() throws IOException {
+
+        if (isClosed || clob.isClosed()) {
+            throw new IOException(
+                Error.getMessage(ErrorCode.X_0F503));
+        }
+    }
+
+    private void readIntoBuffer() throws SQLException {
+
+        long readLength = availableLength - currentPosition;
+
+        if (readLength <= 0) {}
+
+        if (readLength > streamBlockSize) {
+            readLength = streamBlockSize;
+        }
+
+        buffer       = clob.getChars(currentPosition, (int) readLength);
+        bufferOffset = currentPosition;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCArray.java b/src/org/hsqldb/jdbc/JDBCArray.java
new file mode 100644
index 0000000..a5f6c6d
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCArray.java
@@ -0,0 +1,559 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.Array;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hsqldb.ColumnBase;
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ * The mapping in the Java programming language for the SQL type
+ * <code>ARRAY</code>.
+ * By default, an <code>Array</code> value is a transaction-duration
+ * reference to an SQL <code>ARRAY</code> value.  By default, an <code>Array</code>
+ * object is implemented using an SQL LOCATOR(array) internally, which
+ * means that an <code>Array</code> object contains a logical pointer
+ * to the data in the SQL <code>ARRAY</code> value rather
+ * than containing the <code>ARRAY</code> value's data.
+ * <p>
+ * The <code>Array</code> interface provides methods for bringing an SQL
+ * <code>ARRAY</code> value's data to the client as either an array or a
+ * <code>ResultSet</code> object.
+ * If the elements of the SQL <code>ARRAY</code>
+ * are a UDT, they may be custom mapped.  To create a custom mapping,
+ * a programmer must do two things:
+ * <ul>
+ * <li>create a class that implements the {@link java.sql.SQLData}
+ * interface for the UDT to be custom mapped.
+ * <li>make an entry in a type map that contains
+ *   <ul>
+ *   <li>the fully-qualified SQL type name of the UDT
+ *   <li>the <code>Class</code> object for the class implementing
+ *       <code>SQLData</code>
+ *   </ul>
+ * </ul>
+ * <p>
+ * When a type map with an entry for
+ * the base type is supplied to the methods <code>getArray</code>
+ * and <code>getResultSet</code>, the mapping
+ * it contains will be used to map the elements of the <code>ARRAY</code> value.
+ * If no type map is supplied, which would typically be the case,
+ * the connection's type map is used by default.
+ * If the connection's type map or a type map supplied to a method has no entry
+ * for the base type, the elements are mapped according to the standard mapping.
+ * <p>
+ * All methods on the <code>Array</code> interface must be fully implemented if the
+ * JDBC driver supports the data type.
+ *
+ * @since 1.2
+ */
+public class JDBCArray implements Array{
+
+    /**
+     * Retrieves the SQL type name of the elements in
+     * the array designated by this <code>Array</code> object.
+     * If the elements are a built-in type, it returns
+     * the database-specific type name of the elements.
+     * If the elements are a user-defined type (UDT),
+     * this method returns the fully-qualified SQL type name.
+     *
+     * @return a <code>String</code> that is the database-specific
+     * name for a built-in base type; or the fully-qualified SQL type
+     * name for a base type that is a UDT
+     * @exception SQLException if an error occurs while attempting
+     * to access the type name
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public String getBaseTypeName() throws SQLException {
+        return elementType.getNameString();
+    }
+
+    /**
+     * Retrieves the JDBC type of the elements in the array designated
+     * by this <code>Array</code> object.
+     *
+     * @return a constant from the class {@link java.sql.Types} that is
+     * the type code for the elements in the array designated by this
+     * <code>Array</code> object
+     * @exception SQLException if an error occurs while attempting
+     * to access the base type
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public int getBaseType() throws SQLException {
+        return elementType.getJDBCTypeCode();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the contents of the SQL <code>ARRAY</code> value designated
+     * by this
+     * <code>Array</code> object in the form of an array in the Java
+     * programming language. This version of the method <code>getArray</code>
+     * uses the type map associated with the connection for customizations of
+     * the type mappings.
+     * <p>
+     * <strong>Note:</strong> When <code>getArray</code> is used to materialize
+     * a base type that maps to a primitive data type, then it is
+     * implementation-defined whether the array returned is an array of
+     * that primitive data type or an array of <code>Object</code>.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB always returns an array of <code>Object</code>.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return an array in the Java programming language that contains
+     * the ordered elements of the SQL <code>ARRAY</code> value
+     * designated by this <code>Array</code> object
+     * @exception SQLException if an error occurs while attempting to
+     * access the array
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public Object getArray() throws SQLException {
+        Object[] array = new Object[data.length];
+
+        for (int i = 0; i <data.length; i++) {
+            array[i] = elementType.convertSQLToJava(connection.sessionProxy, data[i]);
+        }
+
+        return array;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the contents of the SQL <code>ARRAY</code> value designated by this
+     * <code>Array</code> object.
+     * This method uses
+     * the specified <code>map</code> for type map customizations
+     * unless the base type of the array does not match a user-defined
+     * type in <code>map</code>, in which case it
+     * uses the standard mapping. This version of the method
+     * <code>getArray</code> uses either the given type map or the standard mapping;
+     * it never uses the type map associated with the connection.
+     * <p>
+     * <strong>Note:</strong> When <code>getArray</code> is used to materialize
+     * a base type that maps to a primitive data type, then it is
+     * implementation-defined whether the array returned is an array of
+     * that primitive data type or an array of <code>Object</code>.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB always returns an array of <code>Object</code>.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param map a <code>java.util.Map</code> object that contains mappings
+     *            of SQL type names to classes in the Java programming language
+     * @return an array in the Java programming language that contains the ordered
+     *         elements of the SQL array designated by this object
+     * @exception SQLException if an error occurs while attempting to
+     *                         access the array
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public Object getArray(java.util.Map<String, Class<?>> map) throws
+        SQLException {
+        return getArray();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves a slice of the SQL <code>ARRAY</code>
+     * value designated by this <code>Array</code> object, beginning with the
+     * specified <code>index</code> and containing up to <code>count</code>
+     * successive elements of the SQL array.  This method uses the type map
+     * associated with the connection for customizations of the type mappings.
+     * <p>
+     * <strong>Note:</strong> When <code>getArray</code> is used to materialize
+     * a base type that maps to a primitive data type, then it is
+     * implementation-defined whether the array returned is an array of
+     * that primitive data type or an array of <code>Object</code>.
+
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB always returns an array of <code>Object</code>.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param index the array index of the first element to retrieve;
+     *              the first element is at index 1
+     * @param count the number of successive SQL array elements to retrieve
+     * @return an array containing up to <code>count</code> consecutive elements
+     * of the SQL array, beginning with element <code>index</code>
+     * @exception SQLException if an error occurs while attempting to
+     * access the array
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public Object getArray(long index, int count) throws SQLException {
+
+
+        if (!JDBCClobClient.isInLimits(data.length, index - 1, count)) {
+            throw Util.outOfRangeArgument();
+        }
+        Object[] slice = new Object[count];
+
+        for (int i = 0; i < count; i++) {
+            slice[i] = elementType.convertSQLToJava(connection.sessionProxy, data[(int) index + i - 1]);
+        }
+
+        return slice;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retreives a slice of the SQL <code>ARRAY</code> value
+     * designated by this <code>Array</code> object, beginning with the specified
+     * <code>index</code> and containing up to <code>count</code>
+     * successive elements of the SQL array.
+     * <P>
+     * This method uses
+     * the specified <code>map</code> for type map customizations
+     * unless the base type of the array does not match a user-defined
+     * type in <code>map</code>, in which case it
+     * uses the standard mapping. This version of the method
+     * <code>getArray</code> uses either the given type map or the standard mapping;
+     * it never uses the type map associated with the connection.
+     * <p>
+     * <strong>Note:</strong> When <code>getArray</code> is used to materialize
+     * a base type that maps to a primitive data type, then it is
+     * implementation-defined whether the array returned is an array of
+     * that primitive data type or an array of <code>Object</code>.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB always returns an array of <code>Object</code>.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param index the array index of the first element to retrieve;
+     *              the first element is at index 1
+     * @param count the number of successive SQL array elements to
+     * retrieve
+     * @param map a <code>java.util.Map</code> object
+     * that contains SQL type names and the classes in
+     * the Java programming language to which they are mapped
+     * @return an array containing up to <code>count</code>
+     * consecutive elements of the SQL <code>ARRAY</code> value designated by this
+     * <code>Array</code> object, beginning with element
+     * <code>index</code>
+     * @exception SQLException if an error occurs while attempting to
+     * access the array
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public Object getArray(long index, int count, java.util.Map<String, Class<?>>
+        map) throws SQLException {
+        return getArray(index, count);
+    }
+
+    /**
+     * Retrieves a result set that contains the elements of the SQL
+     * <code>ARRAY</code> value
+     * designated by this <code>Array</code> object.  If appropriate,
+     * the elements of the array are mapped using the connection's type
+     * map; otherwise, the standard mapping is used.
+     * <p>
+     * The result set contains one row for each array element, with
+     * two columns in each row.  The second column stores the element
+     * value; the first column stores the index into the array for
+     * that element (with the first array element being at index 1).
+     * The rows are in ascending order corresponding to
+     * the order of the indices.
+     *
+     * @return a {@link ResultSet} object containing one row for each
+     * of the elements in the array designated by this <code>Array</code>
+     * object, with the rows in ascending order based on the indices.
+     * @exception SQLException if an error occurs while attempting to
+     * access the array
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public ResultSet getResultSet() throws SQLException {
+        Result result = this.newColumnResult(0, data.length);
+
+        return new JDBCResultSet(connection, result, result.metaData);
+    }
+
+    /**
+     * Retrieves a result set that contains the elements of the SQL
+     * <code>ARRAY</code> value designated by this <code>Array</code> object.
+     * This method uses
+     * the specified <code>map</code> for type map customizations
+     * unless the base type of the array does not match a user-defined
+     * type in <code>map</code>, in which case it
+     * uses the standard mapping. This version of the method
+     * <code>getResultSet</code> uses either the given type map or the standard mapping;
+     * it never uses the type map associated with the connection.
+     * <p>
+     * The result set contains one row for each array element, with
+     * two columns in each row.  The second column stores the element
+     * value; the first column stores the index into the array for
+     * that element (with the first array element being at index 1).
+     * The rows are in ascending order corresponding to
+     * the order of the indices.
+     *
+     * @param map contains the mapping of SQL user-defined types to
+     * classes in the Java programming language
+     * @return a <code>ResultSet</code> object containing one row for each
+     * of the elements in the array designated by this <code>Array</code>
+     * object, with the rows in ascending order based on the indices.
+     * @exception SQLException if an error occurs while attempting to
+     * access the array
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public ResultSet getResultSet(java.util.Map<String, Class<?>> map) throws
+        SQLException {
+        return getResultSet();
+    }
+
+    /**
+     * Retrieves a result set holding the elements of the subarray that
+     * starts at index <code>index</code> and contains up to
+     * <code>count</code> successive elements.  This method uses
+     * the connection's type map to map the elements of the array if
+     * the map contains an entry for the base type. Otherwise, the
+     * standard mapping is used.
+     * <P>
+     * The result set has one row for each element of the SQL array
+     * designated by this object, with the first row containing the
+     * element at index <code>index</code>.  The result set has
+     * up to <code>count</code> rows in ascending order based on the
+     * indices.  Each row has two columns:  The second column stores
+     * the element value; the first column stores the index into the
+     * array for that element.
+     *
+     * @param index the array index of the first element to retrieve;
+     *              the first element is at index 1
+     * @param count the number of successive SQL array elements to retrieve
+     * @return a <code>ResultSet</code> object containing up to
+     * <code>count</code> consecutive elements of the SQL array
+     * designated by this <code>Array</code> object, starting at
+     * index <code>index</code>.
+     * @exception SQLException if an error occurs while attempting to
+     * access the array
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public ResultSet getResultSet(long index, int count) throws SQLException {
+        Result result = this.newColumnResult(index - 1, count);
+
+        return new JDBCResultSet(connection, result, result.metaData);
+    }
+
+    /**
+     * Retrieves a result set holding the elements of the subarray that
+     * starts at index <code>index</code> and contains up to
+     * <code>count</code> successive elements.
+     * This method uses
+     * the specified <code>map</code> for type map customizations
+     * unless the base type of the array does not match a user-defined
+     * type in <code>map</code>, in which case it
+     * uses the standard mapping. This version of the method
+     * <code>getResultSet</code> uses either the given type map or the standard mapping;
+     * it never uses the type map associated with the connection.
+     * <P>
+     * The result set has one row for each element of the SQL array
+     * designated by this object, with the first row containing the
+     * element at index <code>index</code>.  The result set has
+     * up to <code>count</code> rows in ascending order based on the
+     * indices.  Each row has two columns:  The second column stores
+     * the element value; the first column stroes the index into the
+     * array for that element.
+     *
+     * @param index the array index of the first element to retrieve;
+     *              the first element is at index 1
+     * @param count the number of successive SQL array elements to retrieve
+     * @param map the <code>Map</code> object that contains the mapping
+     * of SQL type names to classes in the Java(tm) programming language
+     * @return a <code>ResultSet</code> object containing up to
+     * <code>count</code> consecutive elements of the SQL array
+     * designated by this <code>Array</code> object, starting at
+     * index <code>index</code>.
+     * @exception SQLException if an error occurs while attempting to
+     * access the array
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.2
+     */
+    public ResultSet getResultSet(long index, int count,
+                                  java.util.Map<String, Class<?>> map) throws
+        SQLException {
+        return getResultSet(index, count);
+
+    }
+
+    /**
+     * Returns a string representation in the form <code>ARRAY[..., ...]</code>
+     */
+    public String toString() {
+        if (arrayType == null) {
+            arrayType = Type.getDefaultArrayType(elementType.typeCode);
+        }
+
+        return arrayType.convertToString(data);
+    }
+    /**
+     * This method frees the <code>Array</code> object and releases the resources that
+     * it holds. The object is invalid once the <code>free</code>
+     * method is called.
+     * <p>
+     * After <code>free</code> has been called, any attempt to invoke a
+     * method other than <code>free</code> will result in a <code>SQLException</code>
+     * being thrown.  If <code>free</code> is called multiple times, the subsequent
+     * calls to <code>free</code> are treated as a no-op.
+     * <p>
+     *
+     * @throws SQLException if an error occurs releasing
+     * the Array's resources
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void free() throws SQLException {}
+
+    //-------------
+    Type           arrayType;
+    Type           elementType;
+    Object[]       data;
+    JDBCConnection connection;
+
+    /**
+     * Constructors reject unsupported types.
+     */
+    JDBCArray(Object[] data, Type type, JDBCConnection connection) throws SQLException {
+        this(data, type, null, connection);
+    }
+
+
+    JDBCArray(Object[] data, Type type, Type arrayType, JDBCConnection connection) throws SQLException {
+
+        if (type.isArrayType() || type.isLobType() || type.isRowType() ) {
+            throw Util.notSupported();
+        }
+
+        this.data        = data;
+        this.elementType = type;
+        this.arrayType   = arrayType;
+        this.connection  = connection;
+    }
+
+    Object[] getArrayInternal() {
+        return data;
+    }
+
+    private Result newColumnResult(long position, int count) throws SQLException {
+
+        if(!JDBCClobClient.isInLimits(data.length, position, count)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        Type[] types = new Type[2];
+
+        types[0] = Type.SQL_INTEGER;
+        types[1] = elementType;
+
+        ResultMetaData meta = ResultMetaData.newSimpleResultMetaData(types);
+
+        meta.columnLabels = new String[] {
+            "C1", "C2"
+        };
+        meta.colIndexes   = new int[] {
+            -1, -1
+        };
+        meta.columns      = new ColumnBase[2];
+
+        ColumnBase column = new ColumnBase("", "", "", "");
+
+        column.setType(types[0]);
+
+        meta.columns[0] = column;
+        column          = new ColumnBase("", "", "", "");
+
+        column.setType(types[1]);
+
+        meta.columns[1] = column;
+
+        RowSetNavigatorClient navigator = new RowSetNavigatorClient();
+
+        for (int i = (int) position; i < count; i++) {
+            Object[] rowData = new Object[2];
+
+            rowData[0] = ValuePool.getInt(i + 1);
+            rowData[1] = data[i];
+            navigator.add(rowData);
+        }
+
+        Result result = Result.newDataResult(meta);
+
+        result.setNavigator(navigator);
+
+        return result;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCBlob.java b/src/org/hsqldb/jdbc/JDBCBlob.java
new file mode 100644
index 0000000..8e6aedb
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCBlob.java
@@ -0,0 +1,875 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+import org.hsqldb.lib.java.JavaSystem;
+
+// boucherb@users 2004-04-xx - patch 1.7.2 - position and truncate methods
+//                             implemented; minor changes for moderate thread
+//                             safety and optimal performance
+// boucherb@users 2004-04-xx - doc 1.7.2 - javadocs updated; methods put in
+//                             correct (historical, interface declared) order
+// boucherb@users 2005-12-07 - patch 1.8.0.x - initial JDBC 4.0 support work
+// boucherb@users 2006-05-22 - doc 1.9.0     - full synch up to Mustang Build 84
+//                           - patch 1.9.0   - setBinaryStream improvement
+// patch 1.9.0
+//  - fixed invalid reference to new BinaryStream(...) in getBinaryStream
+//
+// patch 1.9.0 - full synch up to Mustang b90
+//             - better bounds checking
+//             - added support for clients to decide whether getBinaryStream
+//               uses copy of internal byte buffer
+
+/**
+ * The representation (mapping) in
+ * the Java<sup><font size=-2>TM</font></sup> programming
+ * language of an SQL
+ * <code>BLOB</code> value.  An SQL <code>BLOB</code> is a built-in type
+ * that stores a Binary Large Object as a column value in a row of
+ * a database table. By default drivers implement <code>Blob</code> using
+ * an SQL <code>locator(BLOB)</code>, which means that a
+ * <code>Blob</code> object contains a logical pointer to the
+ * SQL <code>BLOB</code> data rather than the data itself.
+ * A <code>Blob</code> object is valid for the duration of the
+ * transaction in which is was created.
+ *
+ * <P>Methods in the interfaces {@link java.sql.ResultSet},
+ * {@link java.sql.CallableStatement}, and {@link java.sql.PreparedStatement}, such as
+ * <code>getBlob</code> and <code>setBlob</code> allow a programmer to
+ * access an SQL <code>BLOB</code> value.
+ * The <code>Blob</code> interface provides methods for getting the
+ * length of an SQL <code>BLOB</code> (Binary Large Object) value,
+ * for materializing a <code>BLOB</code> value on the client, and for
+ * determining the position of a pattern of bytes within a
+ * <code>BLOB</code> value. In addition, this interface has methods for updating
+ * a <code>BLOB</code> value.
+ * <p>
+ * All methods on the <code>Blob</code> interface must be fully implemented if the
+ * JDBC driver supports the data type.
+ *
+ * <!-- start Release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * Previous to 2.0, the HSQLDB driver did not implement Blob using an SQL
+ * locator(BLOB).  That is, an HSQLDB Blob object did not contain a logical
+ * pointer to SQL BLOB data; rather it directly contained a representation of
+ * the data (a byte array). As a result, an HSQLDB Blob object was itself
+ * valid beyond the duration of the transaction in which is was created,
+ * although it did not necessarily represent a corresponding value
+ * on the database. Also, the interface methods for updating a BLOB value
+ * were unsupported, with the exception of the truncate method,
+ * in that it could be used to truncate the local value. <p>
+ *
+ * Starting with 2.0, the HSQLDB driver fully supports both local and remote
+ * SQL BLOB data implementations, meaning that an HSQLDB Blob object <em>may</em>
+ * contain a logical pointer to remote SQL BLOB data (see {@link JDBCBlobClient
+ * JDBCBlobClient}) or it may directly contain a local representation of the
+ * data (as implemented in this class).  In particular, when the product is built
+ * under JDK 1.6+ and the Blob instance is constructed as a result of calling
+ * JDBCConnection.createBlob(), then the resulting Blob instance is initially
+ * disconnected (is not bound to the tranaction scope of the vending Connection
+ * object), the data is contained directly and all interface methods for
+ * updating the BLOB value are supported for local use until the first
+ * invocation of free(); otherwise, an HSQLDB Blob's implementation is
+ * determined at runtime by the driver, it is typically not valid beyond the
+ * duration of the transaction in which is was created, and there no
+ * standard way to query whether it represents a local or remote
+ * value.<p>
+ *
+ * </div>
+ * <!-- end Release-specific documentation -->
+ *
+ * @author james house jhouse@part.net
+ * @author boucherb@users
+ * @version 2.0
+ * @since JDK 1.2, HSQLDB 1.7.2
+ * @revised JDK 1.6, HSQLDB 2.0
+ */
+public class JDBCBlob implements Blob {
+
+    /**
+     * Returns the number of bytes in the <code>BLOB</code> value
+     * designated by this <code>Blob</code> object.
+     * @return length of the <code>BLOB</code> in bytes
+     * @exception SQLException if there is an error accessing the
+     * length of the <code>BLOB</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public long length() throws SQLException {
+
+        final byte[] ldata = data;
+
+        checkValid(ldata);
+
+        return ldata.length;
+    }
+
+    /**
+     * Retrieves all or part of the <code>BLOB</code>
+     * value that this <code>Blob</code> object represents, as an array of
+     * bytes.  This <code>byte</code> array contains up to <code>length</code>
+     * consecutive bytes starting at position <code>pos</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The official specification above is ambiguous in that it does not
+     * precisely indicate the policy to be observed when
+     * pos > this.length() - length.  One policy would be to retrieve the
+     * octets from pos to this.length().  Another would be to throw an
+     * exception.  HSQLDB observes the second policy.
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param pos the ordinal position of the first byte in the
+     *        <code>BLOB</code> value to be extracted; the first byte is at
+     *        position 1
+     * @param length the number of consecutive bytes to be copied
+     * @return a byte array containing up to <code>length</code>
+     *         consecutive bytes from the <code>BLOB</code> value designated
+     *         by this <code>Blob</code> object, starting with the
+     *         byte at position <code>pos</code>
+     * @exception SQLException  if there is an error accessing the BLOB value;
+     *            if <code>pos</code> is less than 1 or <code>length</code> is
+     *            less than 0.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setBytes
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public byte[] getBytes(long pos, final int length) throws SQLException {
+
+        final byte[] ldata = data;
+
+        checkValid(ldata);
+
+        final int dlen = ldata.length;
+
+        if (pos < MIN_POS || pos > MIN_POS + dlen) {
+            throw Util.outOfRangeArgument("pos: " + pos);
+        }
+        pos--;
+
+        if (length < 0 || length > dlen - pos) {
+            throw Util.outOfRangeArgument("length: " + length);
+        }
+
+        final byte[] out = new byte[length];
+
+        System.arraycopy(ldata, (int) pos, out, 0, length);
+
+        return out;
+    }
+
+    /**
+     * Retrieves the <code>BLOB</code> value designated by this
+     * <code>Blob</code> instance as a stream.
+     *
+     * @return a stream containing the <code>BLOB</code> data
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setBinaryStream
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public InputStream getBinaryStream() throws SQLException {
+
+        final byte[] ldata = data;
+
+        checkValid(ldata);
+
+        return new ByteArrayInputStream(ldata);
+    }
+
+    /**
+     * Retrieves the byte position at which the specified byte array
+     * <code>pattern</code> begins within the <code>BLOB</code>
+     * value that this <code>Blob</code> object represents.  The
+     * search for <code>pattern</code> begins at position
+     * <code>start</code>.
+     *
+     * @param pattern the byte array for which to search
+     * @param start the position at which to begin searching; the
+     *        first position is 1
+     * @return the position at which the pattern appears, else -1
+     * @exception SQLException if there is an error accessing the
+     * <code>BLOB</code> or if start is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public long position(final byte[] pattern,
+                         long start) throws SQLException {
+
+        final byte[] ldata = data;
+
+        checkValid(ldata);
+
+        final int dlen = ldata.length;
+
+        if (start < MIN_POS) {
+            throw Util.outOfRangeArgument("start: " + start);
+        } else if (start > dlen || pattern == null) {
+            return -1L;
+        } else {
+            start--;
+        }
+
+        final int plen = pattern.length;
+
+        if (plen == 0 || start > dlen - plen) {
+            return -1L;
+        }
+
+        final int  stop = dlen - plen;
+        final byte b0   = pattern[0];
+
+        outer_loop:
+        for (int i = (int) start; i <= stop; i++) {
+            if (ldata[i] != b0) {
+                continue;
+            }
+
+            int     len     = plen;
+            int     doffset = i;
+            int     poffset = 0;
+            boolean match   = true;
+
+            while (len-- > 0) {
+                if (ldata[doffset++] != pattern[poffset++]) {
+                    continue outer_loop;
+                }
+            }
+
+            return (i + 1);
+        }
+
+        return -1L;
+    }
+
+    /**
+     * Retrieves the byte position in the <code>BLOB</code> value
+     * designated by this <code>Blob</code> object at which
+     * <code>pattern</code> begins.  The search begins at position
+     * <code>start</code>.
+     *
+     * @param pattern the <code>Blob</code> object designating
+     * the <code>BLOB</code> value for which to search
+     * @param start the position in the <code>BLOB</code> value
+     *        at which to begin searching; the first position is 1
+     * @return the position at which the pattern begins, else -1
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value or if start is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public long position(final Blob pattern, long start) throws SQLException {
+
+        final byte[] ldata = data;
+
+        checkValid(ldata);
+
+        final int dlen = ldata.length;
+
+        if (start < MIN_POS) {
+            throw Util.outOfRangeArgument("start: " + start);
+        } else if (start > dlen || pattern == null) {
+            return -1L;
+        } else {
+            start--;
+        }
+
+        final long plen = pattern.length();
+
+        if (plen == 0 || start > ((long) dlen) - plen) {
+            return -1L;
+        }
+
+        // by now, we know plen <= Integer.MAX_VALUE
+        final int iplen = (int) plen;
+        byte[]    bap;
+
+        if (pattern instanceof JDBCBlob) {
+            bap = ((JDBCBlob) pattern).data();
+        } else {
+            bap = pattern.getBytes(1L, iplen);
+        }
+
+        final int  stop = dlen - iplen;
+        final byte b0   = bap[0];
+
+        outer_loop:
+        for (int i = (int) start; i <= stop; i++) {
+            if (ldata[i] != b0) {
+                continue;
+            }
+
+            int len     = iplen;
+            int doffset = i;
+            int poffset = 0;
+
+            while (len-- > 0) {
+                if (ldata[doffset++] != bap[poffset++]) {
+                    continue outer_loop;
+                }
+            }
+
+            return i + 1;
+        }
+
+        return -1L;
+    }
+
+    // -------------------------- JDBC 3.0 -----------------------------------
+
+    /**
+     * Writes the given array of bytes to the <code>BLOB</code> value that
+     * this <code>Blob</code> object represents, starting at position
+     * <code>pos</code>, and returns the number of bytes written.
+     * The array of bytes will overwrite the existing bytes
+     * in the <code>Blob</code> object starting at the position
+     * <code>pos</code>.  If the end of the <code>Blob</code> value is reached
+     * while writing the array of bytes, then the length of the <code>Blob</code>
+     * value will be increased to accomodate the extra bytes.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>pos</code>
+     * is greater then the length+1 of the <code>BLOB</code> value then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is supported. <p>
+     *
+     * When built under JDK 1.6+ and the Blob instance is constructed as a
+     * result of calling JDBCConnection.createBlob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in a
+     * database because JDBCConnection.createBlob() constructs disconnected,
+     * initially empty Blob instances. To propogate the Blob value to a database
+     * in this case, it is required to supply the Blob instance to an updating
+     * or inserting setXXX method of a Prepared or Callable Statement, or to
+     * supply the Blob instance to an updateXXX method of an updateable
+     * ResultSet. <p>
+     *
+     * <b>Implementation Notes:</b><p>
+     *
+     * No attempt is made to ensure precise thread safety. Instead, volatile
+     * member field and local variable snapshot isolation semantics are
+     * implemented.  This is expected to eliminate most issues related
+     * to race conditions, with the possible exception of concurrent
+     * invocation of free(). <p>
+     *
+     * In general, however, if an application may perform concurrent
+     * JDBCBlob modifications and the integrity of the application depends on
+     * total order Blob modification semantics, then such operations
+     * should be synchronized on an appropriate monitor.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param pos the position in the <code>BLOB</code> object at which
+     *        to start writing; the first position is 1
+     * @param bytes the array of bytes to be written to the <code>BLOB</code>
+     *        value that this <code>Blob</code> object represents
+     * @return the number of bytes written
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value or if pos is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getBytes
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public int setBytes(long pos, byte[] bytes) throws SQLException {
+
+        if (bytes == null) {
+            throw Util.nullArgument("bytes");
+        }
+
+        return (setBytes(pos, bytes, 0, bytes.length));
+    }
+
+    /**
+     * Writes all or part of the given <code>byte</code> array to the
+     * <code>BLOB</code> value that this <code>Blob</code> object represents
+     * and returns the number of bytes written.
+     * Writing starts at position <code>pos</code> in the <code>BLOB</code>
+     * value; <code>len</code> bytes from the given byte array are written.
+     * The array of bytes will overwrite the existing bytes
+     * in the <code>Blob</code> object starting at the position
+     * <code>pos</code>.  If the end of the <code>Blob</code> value is reached
+     * while writing the array of bytes, then the length of the <code>Blob</code>
+     * value will be increased to accomodate the extra bytes.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>pos</code>
+     * is greater then the length+1 of the <code>BLOB</code> value then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is supported. <p>
+     *
+     * When built under JDK 1.6+ and the Blob instance is constructed as a
+     * result of calling JDBCConnection.createBlob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in a
+     * database because JDBCConnection.createBlob() constructs disconnected,
+     * initially empty Blob instances. To propogate the Blob value to a database
+     * in this case, it is required to supply the Blob instance to an updating
+     * or inserting setXXX method of a Prepared or Callable Statement, or to
+     * supply the Blob instance to an updateXXX method of an updateable
+     * ResultSet. <p>
+     *
+     * <b>Implementation Notes:</b><p>
+     *
+     * If the value specified for <code>pos</code>
+     * is greater than the length of the <code>BLOB</code> value, then
+     * the <code>BLOB</code> value is extended in length to accept the
+     * written octets and the undefined region up to <code>pos</code> is
+     * filled with (byte)0. <p>
+     *
+     * No attempt is made to ensure precise thread safety. Instead, volatile
+     * member field and local variable snapshot isolation semantics are
+     * implemented.  This is expected to eliminate most issues related
+     * to race conditions, with the possible exception of concurrent
+     * invocation of free(). <p>
+     *
+     * In general, however, if an application may perform concurrent
+     * JDBCBlob modifications and the integrity of the application depends on
+     * total order Blob modification semantics, then such operations
+     * should be synchronized on an appropriate monitor.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param pos the position in the <code>BLOB</code> object at which
+     *        to start writing; the first position is 1
+     * @param bytes the array of bytes to be written to this <code>BLOB</code>
+     *        object
+     * @param offset the offset into the array <code>bytes</code> at which
+     *        to start reading the bytes to be set
+     * @param len the number of bytes to be written to the <code>BLOB</code>
+     *        value from the array of bytes <code>bytes</code>
+     * @return the number of bytes written
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value or if pos is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getBytes
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public int setBytes(long pos, byte[] bytes, int offset,
+                        int len) throws SQLException {
+
+        if (!this.createdByConnection) {
+
+            /** @todo - better error message */
+            throw Util.notSupported();
+        }
+
+        if (bytes == null) {
+            throw Util.nullArgument("bytes");
+        }
+
+        if (offset < 0 || offset > bytes.length) {
+            throw Util.outOfRangeArgument("offset: " + offset);
+        }
+
+        if (len > bytes.length - offset) {
+            throw Util.outOfRangeArgument("len: " + len);
+        }
+
+        if (pos < MIN_POS || pos > 1L + (Integer.MAX_VALUE - len)) {
+            throw Util.outOfRangeArgument("pos: " + pos);
+        }
+        pos--;
+
+        byte[] ldata = this.data;
+
+        checkValid(ldata);
+
+        final int dlen = ldata.length;
+
+        if ((pos + len) > dlen) {
+            byte[] temp = new byte[(int) pos + len];
+
+            System.arraycopy(ldata, 0, temp, 0, dlen);
+
+            ldata = temp;
+            temp  = null;
+        }
+        System.arraycopy(bytes, offset, ldata, (int) pos, len);
+
+        // paranoia, in case somone free'd us during the array copies.
+        checkValid(this.data);
+
+        this.data = ldata;
+
+        return len;
+    }
+
+    /**
+     * Retrieves a stream that can be used to write to the <code>BLOB</code>
+     * value that this <code>Blob</code> object represents.  The stream begins
+     * at position <code>pos</code>.
+     * The  bytes written to the stream will overwrite the existing bytes
+     * in the <code>Blob</code> object starting at the position
+     * <code>pos</code>.  If the end of the <code>Blob</code> value is reached
+     * while writing to the stream, then the length of the <code>Blob</code>
+     * value will be increased to accomodate the extra bytes.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>pos</code>
+     * is greater then the length+1 of the <code>BLOB</code> value then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is supported. <p>
+     *
+     * When built under JDK 1.6+ and the Blob instance is constructed as a
+     * result of calling JDBCConnection.createBlob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in a
+     * database because JDBCConnection.createBlob() constructs disconnected,
+     * initially empty Blob instances. To propogate the Blob value to a database
+     * in this case, it is required to supply the Blob instance to an updating
+     * or inserting setXXX method of a Prepared or Callable Statement, or to
+     * supply the Blob instance to an updateXXX method of an updateable
+     * ResultSet. <p>
+     *
+     * <b>Implementation Notes:</b><p>
+     *
+     * The data written to the stream does not appear in this
+     * Blob until the stream is closed <p>
+     *
+     * When the stream is closed, if the value specified for <code>pos</code>
+     * is greater than the length of the <code>BLOB</code> value, then
+     * the <code>BLOB</code> value is extended in length to accept the
+     * written octets and the undefined region up to <code>pos</code> is
+     * filled with (byte)0. <p>
+     *
+     * Also, no attempt is made to ensure precise thread safety. Instead,
+     * volatile member field and local variable snapshot isolation semantics
+     * are implemented.  This is expected to eliminate most issues related
+     * to race conditions, with the possible exception of concurrent
+     * invocation of free(). <p>
+     *
+     * In general, however, if an application may perform concurrent
+     * JDBCBlob modifications and the integrity of the application depends on
+     * total order Blob modification semantics, then such operations
+     * should be synchronized on an appropriate monitor.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param pos the position in the <code>BLOB</code> value at which
+     *        to start writing; the first position is 1
+     * @return a <code>java.io.OutputStream</code> object to which data can
+     *         be written
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value or if pos is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getBinaryStream
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public OutputStream setBinaryStream(final long pos) throws SQLException {
+
+        if (!this.createdByConnection) {
+
+            /** @todo - Better error message */
+            throw Util.notSupported();
+        }
+
+        if (pos < MIN_POS || pos > MAX_POS) {
+            throw Util.outOfRangeArgument("pos: " + pos);
+        }
+        checkValid(this.data);
+
+        return new java.io.ByteArrayOutputStream() {
+
+            public synchronized void close() throws java.io.IOException {
+
+                try {
+                    JDBCBlob.this.setBytes(pos, toByteArray());
+                } catch (SQLException se) {
+                    throw JavaSystem.toIOException(se);
+                } finally {
+                    super.close();
+                }
+            }
+        };
+    }
+
+    /**
+     * Truncates the <code>BLOB</code> value that this <code>Blob</code>
+     * object represents to be <code>len</code> bytes in length.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>pos</code>
+     * is greater then the length+1 of the <code>BLOB</code> value then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is fully supported. <p>
+     *
+     * When built under JDK 1.6+ and the Blob instance is constructed as a
+     * result of calling JDBCConnection.createBlob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in a
+     * database because JDBCConnection.createBlob() constructs disconnected,
+     * initially empty Blob instances. To propogate the truncated Blob value to
+     * a database in this case, it is required to supply the Blob instance to
+     * an updating or inserting setXXX method of a Prepared or Callable
+     * Statement, or to supply the Blob instance to an updateXXX method of an
+     * updateable ResultSet. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param len the length, in bytes, to which the <code>BLOB</code> value
+     *        that this <code>Blob</code> object represents should be truncated
+     * @exception SQLException if there is an error accessing the
+     *            <code>BLOB</code> value or if len is less than 0
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public void truncate(final long len) throws SQLException {
+
+        final byte[] ldata = data;
+
+        checkValid(ldata);
+
+        if (len < 0 || len > ldata.length) {
+            throw Util.outOfRangeArgument("len: " + len);
+        }
+
+        if (len == ldata.length) {
+            return;
+        }
+
+        byte[] newData = new byte[(int) len];
+
+        System.arraycopy(ldata, 0, newData, 0, (int) len);
+        checkValid(data);    // limit possible race-condition with free()
+
+        data = newData;
+    }
+
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * This method frees the <code>Blob</code> object and releases the resources that
+     * it holds. The object is invalid once the <code>free</code>
+     * method is called.
+     * <p>
+     * After <code>free</code> has been called, any attempt to invoke a
+     * method other than <code>free</code> will result in a <code>SQLException</code>
+     * being thrown.  If <code>free</code> is called multiple times, the subsequent
+     * calls to <code>free</code> are treated as a no-op.
+     * <p>
+     *
+     * @throws SQLException if an error occurs releasing
+     * the Blob's resources
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public void free() throws SQLException {
+        this.data = null;
+    }
+
+    /**
+     * Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+     * starting  with the byte specified by pos, which is length bytes in length.
+     *
+     * @param pos the offset to the first byte of the partial value to be retrieved.
+     *  The first byte in the <code>Blob</code> is at position 1
+     * @param length the length in bytes of the partial value to be retrieved
+     * @return <code>InputStream</code> through which the partial <code>Blob</code> value can be read.
+     * @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes
+     * in the <code>Blob</code> or if pos + length is greater than the number of bytes
+     * in the <code>Blob</code>
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public InputStream getBinaryStream(long pos,
+                                       long length) throws SQLException {
+
+        final byte[] ldata = data;
+
+        checkValid(ldata);
+
+        final int dlen = ldata.length;
+
+        if (pos < MIN_POS || pos > dlen) {
+            throw Util.outOfRangeArgument("pos: " + pos);
+        }
+        pos--;
+
+        if (length < 0 || length > dlen - pos) {
+            throw Util.outOfRangeArgument("length: " + length);
+        }
+
+        if (pos == 0 && length == dlen) {
+            return new ByteArrayInputStream(ldata);
+        }
+
+        // Let client decide on policy.
+        //
+        // Zero-copy is (possibly much) faster because it does
+        // not allocate extra memory and does not involve copy
+        // processing.
+        //
+        // However, because it could lead to unexpected memory,
+        // stress, it is not polite to always pass back a stream
+        // whose buffer is the full size required to represent the
+        // underlying BLOB value.
+//        if (isGetBinaryStreamUsesCopy()) {
+        final byte[] out = new byte[(int) length];
+
+        System.arraycopy(ldata, (int) pos, out, 0, (int) length);
+
+        return new ByteArrayInputStream(out);
+
+//        } else {
+//            return new BinaryInputStream(ldata, pos, length);
+//        }
+    }
+
+    /**
+     * Assigns whether getBinaryStream() uses a copy of
+     * the underlying byte[].
+     *
+     * @param b when true, then getBinaryStream() uses a copy of
+     * the underlying byte[]
+     */
+    public void setGetBinaryStreamUsesCopy(boolean b) {
+        getBinaryStreamUsesCopy = b;
+    }
+
+    /**
+     * Retrieves whether getBinaryStream() uses a copy of
+     * the underlying buffer.
+     *
+     * @return true if getBinaryStream() uses a copy of
+     * the underlying buffer; else false
+     */
+    public boolean isGetBinaryStreamUsesCopy() {
+        return getBinaryStreamUsesCopy;
+    }
+
+    // ---------------------- internal implementation --------------------------
+    public static final long MIN_POS = 1L;
+    public static final long MAX_POS = 1L + (long) Integer.MAX_VALUE;
+    private volatile byte[]  data;
+    private final boolean    createdByConnection;
+    private boolean          getBinaryStreamUsesCopy;
+
+    /**
+     * Constructs a new JDBCBlob instance wrapping the given octet sequence. <p>
+     *
+     * This constructor is used internally to retrieve result set values as
+     * Blob objects, yet it must be public to allow access from other packages.
+     * As such (in the interest of efficiency) this object maintains a reference
+     * to the given octet sequence rather than making a copy; special care
+     * should be taken by extenal clients never to use this constructor with a
+     * byte array object that may later be modified extenally.
+     *
+     * @param data the octet sequence representing the Blob value
+     * @throws SQLException if the argument is null
+     */
+    public JDBCBlob(final byte[] data) throws SQLException {
+
+        init(data);
+
+        this.createdByConnection = false;
+    }
+
+    protected JDBCBlob() {
+        this.data                = new byte[0];
+        this.createdByConnection = true;
+    }
+
+    protected void init(byte[] data) throws SQLException {
+
+        if (data == null) {
+            throw Util.nullArgument();
+        }
+        this.data = data;    // (byte[]) data.clone();
+    }
+
+    protected void checkValid(final Object data) {
+
+        if (data == null) {
+            throw new RuntimeException("null data");
+        }
+    }
+
+    protected byte[] data() throws SQLException {
+
+        byte[] ldata = data;
+
+        checkValid(ldata);
+
+        return ldata;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCBlobClient.java b/src/org/hsqldb/jdbc/JDBCBlobClient.java
new file mode 100644
index 0000000..b9cf728
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCBlobClient.java
@@ -0,0 +1,339 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.types.BlobDataID;
+
+/**
+ * A wrapper for HSQLDB BlobData objects.
+ *
+ * Instances of this class are returnd by calls to ResultSet methods.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @since 1.9.0
+ */
+public class JDBCBlobClient implements Blob {
+
+    /**
+     * Returns the number of bytes in the <code>BLOB</code> value designated
+     * by this <code>Blob</code> object.
+     *
+     * @return length of the <code>BLOB</code> in bytes
+     * @throws SQLException if there is an error accessing the length of the
+     *   <code>BLOB</code>
+     */
+    public synchronized long length() throws SQLException {
+
+        try {
+            return blob.length(session);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Retrieves all or part of the <code>BLOB</code> value that this
+     * <code>Blob</code> object represents, as an array of bytes.
+     *
+     * @param pos the ordinal position of the first byte in the
+     *   <code>BLOB</code> value to be extracted; the first byte is at
+     *   position 1
+     * @param length the number of consecutive bytes to be copied
+     * @return a byte array containing up to <code>length</code> consecutive
+     *   bytes from the <code>BLOB</code> value designated by this
+     *   <code>Blob</code> object, starting with the byte at position
+     *   <code>pos</code>
+     * @throws SQLException if there is an error accessing the
+     *   <code>BLOB</code> value
+     */
+    public synchronized byte[] getBytes(long pos,
+                                        int length) throws SQLException {
+
+        if (!isInLimits(Long.MAX_VALUE, pos - 1, length)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        try {
+            return blob.getBytes(session, pos - 1, length);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Retrieves the <code>BLOB</code> value designated by this
+     * <code>Blob</code> instance as a stream.
+     *
+     * @return a stream containing the <code>BLOB</code> data
+     * @throws SQLException if there is an error accessing the
+     *   <code>BLOB</code> value
+     */
+    public synchronized InputStream getBinaryStream() throws SQLException {
+        return new BlobInputStream(this, 0, length(),
+                                   session.getStreamBlockSize());
+    }
+
+    /**
+     * Retrieves the byte position at which the specified byte array
+     * <code>pattern</code> begins within the <code>BLOB</code> value that
+     * this <code>Blob</code> object represents.
+     *
+     * @param pattern the byte array for which to search
+     * @param start the position at which to begin searching; the first
+     *   position is 1
+     * @return the position at which the pattern appears, else -1
+     * @throws SQLException if there is an error accessing the
+     *   <code>BLOB</code>
+     */
+    public synchronized long position(byte[] pattern,
+                                      long start) throws SQLException {
+
+        if (!isInLimits(Long.MAX_VALUE, start, 0)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        try {
+            return blob.position(session, pattern, start - 1);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Retrieves the byte position in the <code>BLOB</code> value designated
+     * by this <code>Blob</code> object at which <code>pattern</code> begins.
+     *
+     * @param pattern the <code>Blob</code> object designating the
+     *   <code>BLOB</code> value for which to search
+     * @param start the position in the <code>BLOB</code> value at which to
+     *   begin searching; the first position is 1
+     * @return the position at which the pattern begins, else -1
+     * @throws SQLException if there is an error accessing the
+     *   <code>BLOB</code> value
+     */
+    public synchronized long position(Blob pattern,
+                                      long start) throws SQLException {
+
+        if (!isInLimits(Integer.MAX_VALUE, 0, pattern.length())) {
+            throw Util.outOfRangeArgument();
+        }
+
+        byte[] bytePattern = pattern.getBytes(1, (int) pattern.length());
+
+        return position(bytePattern, start);
+    }
+
+    /**
+     * Writes the given array of bytes to the <code>BLOB</code> value that
+     * this <code>Blob</code> object represents, starting at position
+     * <code>pos</code>, and returns the number of bytes written.
+     *
+     * @param pos the position in the <code>BLOB</code> object at which to
+     *   start writing
+     * @param bytes the array of bytes to be written to the
+     *   <code>BLOB</code> value that this <code>Blob</code> object
+     *   represents
+     * @return the number of bytes written
+     * @throws SQLException if there is an error accessing the
+     *   <code>BLOB</code> value
+     */
+    public synchronized int setBytes(long pos,
+                                     byte[] bytes) throws SQLException {
+
+        throw Util.notSupported();
+/*
+        if (!isInLimits(Long.MAX_VALUE, pos - 1, bytes.length)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        try {
+            return blob.setBytes(session, pos - 1, bytes);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+*/
+    }
+
+    /**
+     * Writes all or part of the given <code>byte</code> array to the
+     * <code>BLOB</code> value that this <code>Blob</code> object represents
+     * and returns the number of bytes written.
+     *
+     * @param pos the position in the <code>BLOB</code> object at which to
+     *   start writing
+     * @param bytes the array of bytes to be written to this
+     *   <code>BLOB</code> object
+     * @param offset the offset into the array <code>bytes</code> at which
+     *   to start reading the bytes to be set
+     * @param len the number of bytes to be written to the <code>BLOB</code>
+     *   value from the array of bytes <code>bytes</code>
+     * @return the number of bytes written
+     * @throws SQLException if there is an error accessing the
+     *   <code>BLOB</code> value
+     */
+    public synchronized int setBytes(long pos, byte[] bytes, int offset,
+                                     int len) throws SQLException {
+
+        throw Util.notSupported();
+/*
+        if (!isInLimits(bytes.length, offset, len)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        if (offset != 0 || len != bytes.length) {
+            byte[] newBytes = new byte[len];
+
+            System.arraycopy(bytes, (int) offset, newBytes, 0, len);
+
+            bytes = newBytes;
+        }
+
+        return setBytes(pos, bytes);
+*/
+    }
+
+    /**
+     * Retrieves a stream that can be used to write to the <code>BLOB</code>
+     * value that this <code>Blob</code> object represents.
+     *
+     * @param pos the position in the <code>BLOB</code> value at which to
+     *   start writing
+     * @return a <code>java.io.OutputStream</code> object to which data can
+     *   be written
+     * @throws SQLException if there is an error accessing the
+     *   <code>BLOB</code> value
+     */
+    public synchronized OutputStream setBinaryStream(long pos)
+    throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * Truncates the <code>BLOB</code> value that this <code>Blob</code>
+     * object represents to be <code>len</code> bytes in length.
+     *
+     * @param len the length, in bytes, to which the <code>BLOB</code> value
+     *   that this <code>Blob</code> object represents should be truncated
+     * @throws SQLException if there is an error accessing the
+     *   <code>BLOB</code> value
+     */
+    public synchronized void truncate(long len) throws SQLException {
+
+        try {
+            blob.truncate(session, len);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * This method frees the <code>Blob</code> object and releases the resources that
+     * it holds. The object is invalid once the <code>free</code>
+     * method is called.
+     * <p>
+     * After <code>free</code> has been called, any attempt to invoke a
+     * method other than <code>free</code> will result in a <code>SQLException</code>
+     * being thrown.  If <code>free</code> is called multiple times, the subsequent
+     * calls to <code>free</code> are treated as a no-op.
+     * <p>
+     *
+     * @throws SQLException if an error occurs releasing
+     * the Blob's resources
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized void free() throws SQLException {
+        isClosed = true;
+    }
+
+    /**
+     * Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+     * starting  with the byte specified by pos, which is length bytes in length.
+     *
+     * @param pos the offset to the first byte of the partial value to be retrieved.
+     *  The first byte in the <code>Blob</code> is at position 1
+     * @param length the length in bytes of the partial value to be retrieved
+     * @return <code>InputStream</code> through which the partial <code>Blob</code> value can be read.
+     * @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes
+     * in the <code>Blob</code> or if pos + length is greater than the number of bytes
+     * in the <code>Blob</code>
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized InputStream getBinaryStream(long pos,
+            long length) throws SQLException {
+
+        if (!isInLimits(Long.MAX_VALUE, pos - 1, length)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        return new BlobInputStream(this, pos - 1, length,
+                                   session.getStreamBlockSize());
+    }
+
+    //--
+    BlobDataID       blob;
+    SessionInterface session;
+    boolean          isClosed;
+
+    JDBCBlobClient(SessionInterface session, BlobDataID blob) {
+        this.session = session;
+        this.blob    = blob;
+    }
+
+    public boolean isClosed() {
+        return isClosed;
+    }
+
+    private void checkClosed() throws SQLException {
+
+        if (isClosed) {
+            throw Util.sqlException(ErrorCode.X_07501);
+        }
+    }
+
+    static boolean isInLimits(long fullLength, long pos, long len) {
+        return pos >= 0 && len >= 0 && pos + len <= fullLength;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCCallableStatement.java b/src/org/hsqldb/jdbc/JDBCCallableStatement.java
new file mode 100644
index 0000000..7e98669
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCCallableStatement.java
@@ -0,0 +1,4841 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+//#ifdef JAVA6
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLXML;
+
+//#endif JAVA6
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.HsqlException;
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/* $Id: JDBCCallableStatement.java 3596 2010-05-30 13:06:33Z fredt $ */
+
+/** @todo fredt 1.9.0 - review wrt multiple result sets, named parameters etc. */
+
+// boucherb@users patch 1.7.2 - CallableStatement impl removed
+// from JDBCParameterMetaData and moved here; sundry changes elsewhere to
+// comply
+// TODO: 1.7.2 Alpha N :: DONE
+//       maybe implement set-by-parameter-name.  We have an informal spec,
+//       being "@p1" => 1, "@p2" => 2, etc.  Problems: return value is "@p0"
+//       and there is no support for registering the return value as an out
+//       parameter.
+// TODO: 1.9.x
+//       engine and client-side mechanisms for adding, retrieving,
+//       navigating (and perhaps controlling holdability of) multiple
+//       results generated from a single execution.
+// boucherb@users 2004-03/04-xx - patch 1.7.2 - some minor code cleanup
+//                                            - parameter map NPE correction
+//                                            - embedded SQL/SQLCLI client usability
+//                                              (parameter naming changed from @n to @pn)
+// boucherb@users 2004-04-xx - doc 1.7.2 - javadocs added/updated
+// boucherb@users 2005-12-07 - patch 1.8.0.x - initial JDBC 4.0 support work
+// boucherb@users 2006-05-22 - doc 1.9.0 - full synch up to Mustang Build 84
+// Revision 1.14  2006/07/12 11:58:49  boucherb
+//  - full synch up to Mustang b90
+
+/**
+ * <!-- start generic documentation -->
+ *
+ * The interface used to execute SQL stored procedures.  The JDBC API
+ * provides a stored procedure SQL escape syntax that allows stored procedures
+ * to be called in a standard way for all RDBMSs. This escape syntax has one
+ * form that includes a result parameter and one that does not. If used, the result
+ * parameter must be registered as an OUT parameter. The other parameters
+ * can be used for input, output or both. Parameters are referred to
+ * sequentially, by number, with the first parameter being 1.
+ * <p>(JDBC4 clarification:)
+ * <PRE>
+ *   {?= call &lt;procedure-name&gt;[(&lt;arg1&gt;,&lt;arg2&gt;, ...)]}
+ *   {call &lt;procedure-name&gt;[(&lt;arg1&gt;,&lt;arg2&gt;, ...)]}
+ * </PRE>
+ * <P>
+ * IN parameter values are set using the <code>set</code> methods inherited from
+ * {@link java.sql.PreparedStatement}.  The type of all OUT parameters must be
+ * registered prior to executing the stored procedure; their values
+ * are retrieved after execution via the <code>get</code> methods provided here.
+ * <P>
+ * A <code>CallableStatement</code> can return one {@link java.sql.ResultSet} object or
+ * multiple <code>ResultSet</code> objects.  Multiple
+ * <code>ResultSet</code> objects are handled using operations
+ * inherited from {@link java.sql.Statement}.
+ * <P>
+ * For maximum portability, a call's <code>ResultSet</code> objects and
+ * update counts should be processed prior to getting the values of output
+ * parameters.
+ * <P>
+ *
+ * <!-- end generic documentation -->
+ *
+ * <!-- start Release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * Some of the previously unsupported features of this interface
+ * are now supported, such as the parameterName-based setter methods. <p>
+ *
+ * More importantly, JDBCCallableStatement objects are now backed by a true
+ * compiled parameteric representation. Hence, there are now significant
+ * performance gains to be had by using a CallableStatement object instead of
+ * a Statement object, if a short-running CALL statement is to be executed more
+ * than a small number of times.  Moreover, the recent work lays the foundation
+ * for work in a subsequenct release to support CallableStatement OUT and
+ * IN OUT style parameters, as well as the generation and retrieval of multiple
+ * results in response to the execution of a CallableStatement object. <p>
+ *
+ * For a more in-depth discussion of performance issues regarding HSQLDB
+ * prepared and callable statement objects, please see overview section of
+ * {@link JDBCParameterMetaData JDBCPreparedStatment}.
+ *
+ * <hr>
+ *
+ * As with many DBMS, HSQLDB support for stored procedures is not provided in
+ * a completely standard fashion. <p>
+ *
+ * Beyond the XOpen/ODBC extended scalar functions, stored procedures are
+ * typically supported in ways that vary greatly from one DBMS implementation
+ * to the next.  So, it is almost guaranteed that the code for a stored
+ * procedure written under a specific DBMS product will not work without
+ * at least some modification in the context of another vendor's product
+ * or even across a single vendor's product lines.  Moving stored procedures
+ * from one DBMS product line to another almost invariably involves complex
+ * porting issues and often may not be possible at all. <em>Be warned</em>. <p>
+ *
+ * One kind of HSQLDB stored procedures is Java routines that map directly onto
+ * the static methods of compiled Java classes found on the classpath of the
+ * engine at runtime. <p>
+ *
+ * Overloaded methods are supported and resolved according to the type of
+ * para;meters.
+ *
+ * The other kind of HSQLDB stored procedures is SQL routines that are created
+ * as part of schemas.
+ *
+ * With SQL routines, <code>OUT</code> and <code>IN OUT</code> parameters
+ * are also supported. <p>
+ *
+ * In addition, HSQLDB stored procedure call mechanism allows the
+ * more general HSQLDB SQL expression evaluation mechanism.  This
+ * extension provides the ability to evaluate simple SQL expressions, possibly
+ * containing Java method invocations. <p>
+ *
+ * With HSQLDB, executing a <code>CALL</code> statement that produces an opaque
+ * (OTHER) or known scalar object reference has virtually the same effect as:
+ *
+ * <PRE class="SqlCodeExample">
+ * CREATE TABLE DUAL (dummy VARCHAR);
+ * INSERT INTO DUAL VALUES(NULL);
+ * SELECT &lt;simple-expression&gt; FROM DUAL;
+ * </PRE>
+ *
+ * As a transitional measure, HSQLDB provides the ability to materialize a
+ * general result set in response to stored procedure execution.  In this case,
+ * the stored procedure's Java method descriptor must specify a return type of
+ * java.lang.Object for external use (although at any point in the devlopment
+ * cycle, other, proprietary return types may accepted internally for engine
+ * development purposes).
+ *
+ * When HSQLDB detects that the runtime class of the resulting Object is
+ * elligible, an automatic internal unwrapping is performed to correctly
+ * expose the underlying result set to the client, whether local or remote. <p>
+ *
+ * Additionally, HSQLDB automatically detects if java.sql.Connection is
+ * the class of the first argument of any underlying Java method(s).  If so,
+ * then the engine transparently supplies the internal Connection object
+ * corresponding to the Session executing the call, adjusting the positions
+ * of other arguments to suite the SQL context. <p>
+ *
+ * The features above are not intended to be permanent.  Rather, the intention
+ * is to offer more general and powerful mechanisms in a future release;
+ * it is recommend to use them only as a temporary convenience. <p>
+ *
+ * For instance, one might be well advised to future-proof by writing
+ * HSQLDB-specific adapter methods that in turn call the real logic of an
+ * underlying generalized JDBC stored procedure library. <p>
+ *
+ * Here is a very simple example of an HSQLDB stored procedure generating a
+ * user-defined result set:
+ *
+ * <pre class="JavaCodeExample">
+ * <span class="JavaKeyWord">package</span> mypackage;
+ *
+ * <span class="JavaKeyWord">class</span> MyClass {
+ *
+ *      <span class="JavaKeyWord">public static</span> Object <b>mySp</b>(Connection conn) <span class="JavaKeyWord">throws</span> SQLException {
+ *          <span class="JavaKeyWord">return</span> conn.<b>createStatement</b>().<b>executeQuery</b>(<span class="JavaStringLiteral">"select * from my_table"</span>);
+ *      }
+ * }
+ * </pre>
+ *
+ * Here is a refinement demonstrating no more than the bare essence of the idea
+ * behind a more portable style:
+ *
+ * <pre class="JavaCodeExample">
+ * <span class="JavaKeyWord">package</span> mypackage;
+ *
+ * <span class="JavaKeyWord">import</span> java.sql.ResultSet;
+ * <span class="JavaKeyWord">import</span> java.sql.SQLException;
+ *
+ * <span class="JavaKeyWord">class</span> MyLibraryClass {
+ *
+ *      <span class="JavaKeyWord">public static</span> ResultSet <b>mySp()</b> <span class="JavaKeyWord">throws</span> SQLException {
+ *          <span class="JavaKeyWord">return</span> ctx.<b>getConnection</b>().<b>createStatement</b>().<b>executeQuery</b>(<span class="JavaStringLiteral">"select * from my_table"</span>);
+ *      }
+ * }
+ *
+ * //--
+ *
+ * <span class="JavaKeyWord">package</span> myadaptorpackage;
+ *
+ * <span class="JavaKeyWord">import</span> java.sql.Connection;
+ * <span class="JavaKeyWord">import</span> java.sql.SQLException;
+ *
+ * <span class="JavaKeyWord">class</span> MyAdaptorClass {
+ *
+ *      <span class="JavaKeyWord">public static</span> Object <b>mySp</b>(Connection conn) <span class="JavaKeyWord">throws</span> SQLException {
+ *          MyLibraryClass.<b>getCtx()</b>.<b>setConnection</b>(conn);
+ *          <span class="JavaKeyWord">return</span> MyLibraryClass.<b>mySp</b>();
+ *      }
+ * }
+ * </pre>
+ *
+ * In a future release, it is intended to provided some new features
+ * that will support writing fairly portable JDBC-based stored procedure
+ * code: <P>
+ *
+ * <ul>
+ *  <li> Support for the <span class="JavaStringLiteral">"jdbc:default:connection"</span>
+ *       standard database connection url. <p>
+ *
+ *  <li> A well-defined specification of the behaviour of the HSQLDB execution
+ *       stack under stored procedure calls. <p>
+ *
+ *  <li> A well-defined, pure JDBC specification for generating multiple
+ *       results from HSQLDB stored procedures for client retrieval.
+ * </ul>
+ *
+ * (boucherb@users)
+ * </div>
+ * <!-- end Release-specific documentation -->
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @since 1.7.2
+ * @revised JDK 1.6, HSQLDB 2.0
+ * @see JDBCConnection#prepareCall
+ * @see JDBCResultSet
+ */
+public class JDBCCallableStatement extends JDBCPreparedStatement implements CallableStatement {
+
+// ----------------------------------- JDBC 1 ----------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Registers the OUT parameter in ordinal position
+     * <code>parameterIndex</code> to the JDBC type
+     * <code>sqlType</code>.  All OUT parameters must be registered
+     * before a stored procedure is executed.
+     * <p>
+     * The JDBC type specified by <code>sqlType</code> for an OUT
+     * parameter determines the Java type that must be used
+     * in the <code>get</code> method to read the value of that parameter.
+     * <p>
+     * If the JDBC type expected to be returned to this output parameter
+     * is specific to this particular database, <code>sqlType</code>
+     * should be <code>java.sql.Types.OTHER</code>.  The method
+     * {@link #getObject} retrieves the value.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @param sqlType the JDBC type code defined by <code>java.sql.Types</code>.
+     *        If the parameter is of JDBC type <code>NUMERIC</code>
+     *        or <code>DECIMAL</code>, the version of
+     *        <code>registerOutParameter</code> that accepts a scale value
+     *        should be used.
+     *
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>sqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type
+     * @see java.sql.Types
+     */
+    public synchronized void registerOutParameter(int parameterIndex,
+            int sqlType) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        if (parameterModes[--parameterIndex]
+                == SchemaObject.ParameterModes.PARAM_IN) {
+            throw Util.invalidArgument();
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Registers the parameter in ordinal position
+     * <code>parameterIndex</code> to be of JDBC type
+     * <code>sqlType</code>.  (JDBC4 clarification:) All OUT parameters must be registered
+     * before a stored procedure is executed.
+     * <p>
+     * The JDBC type specified by <code>sqlType</code> for an OUT
+     * parameter determines the Java type that must be used
+     * in the <code>get</code> method to read the value of that parameter.
+     * <p>
+     * This version of <code>registerOutParameter</code> should be
+     * used when the parameter is of JDBC type <code>NUMERIC</code>
+     * or <code>DECIMAL</code>.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @param sqlType the SQL type code defined by <code>java.sql.Types</code>.
+     * @param scale the desired number of digits to the right of the
+     * decimal point.  It must be greater than or equal to zero.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>sqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type
+     * @see java.sql.Types
+     */
+    public synchronized void registerOutParameter(int parameterIndex,
+            int sqlType, int scale) throws SQLException {
+        registerOutParameter(parameterIndex, sqlType);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves whether the last OUT parameter read had the value of
+     * SQL <code>NULL</code>.  Note that this method should be called only after
+     * calling a getter method; otherwise, there is no value to use in
+     * determining whether it is <code>null</code> or not.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if the last parameter read was SQL
+     * <code>NULL</code>; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     */
+    public synchronized boolean wasNull() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return wasNullValue;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>CHAR</code>,
+     * <code>VARCHAR</code>, or <code>LONGVARCHAR</code> parameter as a
+     * <code>String</code> in the Java programming language.
+     * <p>
+     * For the fixed-length type JDBC <code>CHAR</code>,
+     * the <code>String</code> object
+     * returned has exactly the same value the (JDBC4 clarification:) SQL
+     * <code>CHAR</code> value had in the
+     * database, including any padding added by the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @return the parameter value. If the value is SQL <code>NULL</code>,
+     *         the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setString
+     */
+    public synchronized String getString(
+            int parameterIndex) throws SQLException {
+        return (String) getColumnInType(parameterIndex, Type.SQL_VARCHAR);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * (JDBC4 modified:)
+     * Retrieves the value of the designated JDBC <code>BIT</code>
+     * or <code>BOOLEAN</code> parameter as a
+     * <code>boolean</code> in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>,
+     *         the result is <code>false</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setBoolean
+     */
+    public synchronized boolean getBoolean(
+            int parameterIndex) throws SQLException {
+
+        Object o = getColumnInType(parameterIndex, Type.SQL_BOOLEAN);
+
+        return o == null ? false
+                         : ((Boolean) o).booleanValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>TINYINT</code> parameter
+     * as a <code>byte</code> in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setByte
+     */
+    public synchronized byte getByte(int parameterIndex) throws SQLException {
+
+        Object o = getColumnInType(parameterIndex, Type.TINYINT);
+
+        return o == null ? 0
+                         : ((Number) o).byteValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>SMALLINT</code> parameter
+     * as a <code>short</code> in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setShort
+     */
+    public synchronized short getShort(
+            int parameterIndex) throws SQLException {
+
+        Object o = getColumnInType(parameterIndex, Type.SQL_SMALLINT);
+
+        return o == null ? 0
+                         : ((Number) o).shortValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>INTEGER</code> parameter
+     * as an <code>int</code> in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setInt
+     */
+    public synchronized int getInt(int parameterIndex) throws SQLException {
+
+        Object o = getColumnInType(parameterIndex, Type.SQL_INTEGER);
+
+        return o == null ? 0
+                         : ((Number) o).intValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>BIGINT</code> parameter
+     * as a <code>long</code> in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setLong
+     */
+    public synchronized long getLong(int parameterIndex) throws SQLException {
+
+        Object o = getColumnInType(parameterIndex, Type.SQL_BIGINT);
+
+        return o == null ? 0
+                         : ((Number) o).longValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>FLOAT</code> parameter
+     * as a <code>float</code> in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setFloat
+     */
+    public synchronized float getFloat(
+            int parameterIndex) throws SQLException {
+
+        Object o = getColumnInType(parameterIndex, Type.SQL_DOUBLE);
+
+        return o == null ? (float) 0.0
+                         : ((Number) o).floatValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>DOUBLE</code> parameter as a <code>double</code>
+     * in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setDouble
+     */
+    public synchronized double getDouble(
+            int parameterIndex) throws SQLException {
+
+        Object o = getColumnInType(parameterIndex, Type.SQL_DOUBLE);
+
+        return o == null ? 0.0
+                         : ((Number) o).doubleValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a
+     * <code>java.math.BigDecimal</code> object with <i>scale</i> digits to
+     * the right of the decimal point.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @param scale the number of digits to the right of the decimal point
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @deprecated use <code>getBigDecimal(int parameterIndex)</code>
+     *             or <code>getBigDecimal(String parameterName)</code>
+     * @see #setBigDecimal
+     */
+
+//#ifdef DEPRECATEDJDBC
+    public synchronized BigDecimal getBigDecimal(int parameterIndex,
+            int scale) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (scale < 0) {
+            throw Util.outOfRangeArgument();
+        }
+
+        BigDecimal bd = getBigDecimal(parameterIndex);
+
+        if (bd != null) {
+            bd = bd.setScale(scale, BigDecimal.ROUND_DOWN);
+        }
+
+        return bd;
+    }
+
+//#endif
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>BINARY</code> or
+     * <code>VARBINARY</code> parameter as an array of <code>byte</code>
+     * values in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setBytes
+     */
+    public synchronized byte[] getBytes(
+            int parameterIndex) throws SQLException {
+
+        Object x = getColumnInType(parameterIndex, Type.SQL_VARBINARY);
+
+        if (x == null) {
+            return null;
+        }
+
+        return ((BinaryData) x).getBytes();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
+     * <code>java.sql.Date</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setDate
+     */
+    public synchronized Date getDate(int parameterIndex) throws SQLException {
+
+        TimestampData t = (TimestampData) getColumnInType(parameterIndex,
+            Type.SQL_DATE);
+
+        if (t == null) {
+            return null;
+        }
+
+        return (Date) Type.SQL_DATE.convertSQLToJava(session, t);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
+     * <code>java.sql.Time</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setTime
+     */
+    public synchronized Time getTime(int parameterIndex) throws SQLException {
+
+        TimeData t = (TimeData) getColumnInType(parameterIndex, Type.SQL_TIME);
+
+        if (t == null) {
+            return null;
+        }
+
+        return (Time) Type.SQL_TIME.convertSQLToJava(session, t);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>TIMESTAMP</code>
+     * parameter as a <code>java.sql.Timestamp</code> object. <p>
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setTimestamp
+     */
+    public synchronized Timestamp getTimestamp(
+            int parameterIndex) throws SQLException {
+
+        TimestampData t = (TimestampData) getColumnInType(parameterIndex,
+            Type.SQL_TIMESTAMP);
+
+        if (t == null) {
+            return null;
+        }
+
+        return (Timestamp) Type.SQL_TIMESTAMP.convertSQLToJava(session, t);
+    }
+
+    //----------------------------------------------------------------------
+    // Advanced features:
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated parameter as an <code>Object</code>
+     * in the Java programming language. If the value is an SQL <code>NULL</code>,
+     * the driver returns a Java <code>null</code>.
+     * <p>
+     * This method returns a Java object whose type corresponds to the JDBC
+     * type that was registered for this parameter using the method
+     * <code>registerOutParameter</code>.  By registering the target JDBC
+     * type as <code>java.sql.Types.OTHER</code>, this method can be used
+     * to read database-specific abstract data types.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     *        and so on
+     * @return A <code>java.lang.Object</code> holding the OUT parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see java.sql.Types
+     * @see #setObject
+     */
+    public synchronized Object getObject(
+            int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        Type sourceType = parameterTypes[parameterIndex - 1];
+
+        switch (sourceType.typeCode) {
+
+            case Types.SQL_DATE :
+                return getDate(parameterIndex);
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                return getTime(parameterIndex);
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return getTimestamp(parameterIndex);
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+                return getBytes(parameterIndex);
+            case Types.SQL_BIT : {
+                boolean b = getBoolean(parameterIndex);
+
+                return wasNull() ? null
+                                 : b ? Boolean.TRUE
+                                     : Boolean.FALSE;
+            }
+            case Types.OTHER :
+            case Types.JAVA_OBJECT : {
+                Object o = getColumnInType(parameterIndex, sourceType);
+
+                if (o == null) {
+                    return null;
+                }
+
+                try {
+                    return ((JavaObjectData) o).getObject();
+                } catch (HsqlException e) {
+                    throw Util.sqlException(e);
+                }
+            }
+            default :
+                return getColumnInType(parameterIndex, sourceType);
+        }
+    }
+
+// ----------------------------------- JDBC 2 ----------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a
+     * <code>java.math.BigDecimal</code> object with as many digits to the
+     * right of the decimal point as the value contains.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @return the parameter value in full precision.  If the value is
+     * SQL <code>NULL</code>, the result is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setBigDecimal
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCParameterMetaData)
+     */
+    public synchronized BigDecimal getBigDecimal(
+            int parameterIndex) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        Type targetType = resultMetaData.columnTypes[parameterIndex - 1];
+
+        switch (targetType.typeCode) {
+           case Types.SQL_NUMERIC :
+           case Types.SQL_DECIMAL :
+               break;
+
+           case Types.TINYINT :
+           case Types.SQL_SMALLINT :
+           case Types.SQL_INTEGER :
+           case Types.SQL_BIGINT :
+               targetType = Type.SQL_DECIMAL;
+               break;
+
+           case Types.SQL_DOUBLE:
+           default :
+               targetType = Type.SQL_DECIMAL_DEFAULT;
+               break;
+        }
+
+        return (BigDecimal) getColumnInType(parameterIndex, targetType);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Returns an object representing the value of OUT parameter
+     * <code>parameterIndex</code> and uses <code>map</code> for the custom
+     * mapping of the parameter value.
+     * <p>
+     * This method returns a Java object whose type corresponds to the
+     * JDBC type that was registered for this parameter using the method
+     * <code>registerOutParameter</code>.  By registering the target
+     * JDBC type as <code>java.sql.Types.OTHER</code>, this method can
+     * be used to read database-specific abstract data types.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, and so on
+     * @param map the mapping from SQL type names to Java classes
+     * @return a <code>java.lang.Object</code> holding the OUT parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setObject
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCParameterMetaData)
+     */
+
+//#ifdef JAVA6
+    public Object getObject(int parameterIndex,
+                            Map<String, Class<?>> map) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        throw Util.notSupported();
+    }
+
+//#else
+/*
+    public Object getObject(int parameterIndex, Map map) throws SQLException {
+            checkGetParameterIndex(parameterIndex);
+        throw Util.notSupported();
+    }
+*/
+
+//#endif
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>REF(&lt;structured-type&gt;)</code>
+     * parameter as a {@link java.sql.Ref} object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @return the parameter value as a <code>Ref</code> object in the
+     * Java programming language.  If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCParameterMetaData)
+     */
+    public Ref getRef(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        throw Util.notSupported();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>BLOB</code> parameter as a
+     * {@link java.sql.Blob} object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @return the parameter value as a <code>Blob</code> object in the
+     * Java programming language.  If the value was SQL <code>NULL</code>, the value
+     * <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCParameterMetaData)
+     */
+    public synchronized Blob getBlob(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        Type   sourceType = resultMetaData.columnTypes[parameterIndex - 1];
+        Object o          = getColumnInType(parameterIndex, sourceType);
+
+        if (o == null) {
+            return null;
+        }
+
+        if (o instanceof BlobDataID) {
+            return new JDBCBlobClient(session, (BlobDataID) o);
+        }
+
+        throw Util.sqlException(ErrorCode.X_42561);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>CLOB</code> parameter as a
+     * <code>java.sql.Clob</code> object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, and
+     * so on
+     * @return the parameter value as a <code>Clob</code> object in the
+     * Java programming language.  If the value was SQL <code>NULL</code>, the
+     * value <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCParameterMetaData)
+     */
+    public synchronized Clob getClob(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        Type   sourceType = resultMetaData.columnTypes[parameterIndex - 1];
+        Object o          = getColumnInType(parameterIndex, sourceType);
+
+        if (o == null) {
+            return null;
+        }
+
+        if (o instanceof ClobDataID) {
+            return new JDBCClobClient(session, (ClobDataID) o);
+        }
+
+        throw Util.sqlException(ErrorCode.X_42561);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>ARRAY</code> parameter as an
+     * {@link java.sql.Array} object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, and
+     * so on
+     * @return the parameter value as an <code>Array</code> object in
+     * the Java programming language.  If the value was SQL <code>NULL</code>, the
+     * value <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCParameterMetaData)
+     */
+    public Array getArray(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        Type type = resultMetaData.columnTypes[parameterIndex - 1];
+
+        if (!type.isArrayType()) {
+            throw Util.sqlException(ErrorCode.X_42561);
+        }
+
+        Object[] data = (Object[]) parameterValues[parameterIndex - 1];
+
+        if (data == null) {
+            return null;
+        }
+
+        return new JDBCArray(data, type.collectionBaseType(), type, connection);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>DATE</code> parameter as a
+     * <code>java.sql.Date</code> object, using
+     * the given <code>Calendar</code> object
+     * to construct the date.
+     * With a <code>Calendar</code> object, the driver
+     * can calculate the date taking into account a custom timezone and locale.
+     * If no <code>Calendar</code> object is specified, the driver uses the
+     * default timezone and locale.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the date
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setDate
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *      JDBCParameterMetaData)
+     */
+    public synchronized Date getDate(int parameterIndex,
+                                     Calendar cal) throws SQLException {
+
+        TimestampData t = (TimestampData) getColumnInType(parameterIndex,
+            Type.SQL_DATE);
+
+        if (t == null) {
+            return null;
+        }
+
+        long millis = t.getSeconds() * 1000;
+
+        if (cal != null) {
+            millis = HsqlDateTime.convertMillisToCalendar(cal, millis);
+        }
+
+        return new Date(millis);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>TIME</code> parameter as a
+     * <code>java.sql.Time</code> object, using
+     * the given <code>Calendar</code> object
+     * to construct the time.
+     * With a <code>Calendar</code> object, the driver
+     * can calculate the time taking into account a custom timezone and locale.
+     * If no <code>Calendar</code> object is specified, the driver uses the
+     * default timezone and locale.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the time
+     * @return the parameter value; if the value is SQL <code>NULL</code>, the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setTime
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCParameterMetaData)
+     */
+    public synchronized Time getTime(int parameterIndex,
+                                     Calendar cal) throws SQLException {
+
+        TimeData t = (TimeData) getColumnInType(parameterIndex, Type.SQL_TIME);
+
+        if (t == null) {
+            return null;
+        }
+
+        long millis = DateTimeType.normaliseTime(t.getSeconds()) * 1000;
+
+        if (!resultMetaData.columnTypes[--parameterIndex]
+                .isDateTimeTypeWithZone()) {
+            Calendar calendar = cal == null ? session.getCalendar()
+                    : cal;
+
+            millis = HsqlDateTime.convertMillisToCalendar(calendar, millis);
+            millis = HsqlDateTime.getNormalisedTime(millis);
+        }
+
+        return new Time(millis);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter as a
+     * <code>java.sql.Timestamp</code> object, using
+     * the given <code>Calendar</code> object to construct
+     * the <code>Timestamp</code> object.
+     * With a <code>Calendar</code> object, the driver
+     * can calculate the timestamp taking into account a custom timezone and locale.
+     * If no <code>Calendar</code> object is specified, the driver uses the
+     * default timezone and locale.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,
+     * and so on
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the timestamp
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #setTimestamp
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCParameterMetaData)
+     */
+    public synchronized Timestamp getTimestamp(int parameterIndex,
+            Calendar cal) throws SQLException {
+
+        TimestampData t = (TimestampData) getColumnInType(parameterIndex,
+            Type.SQL_TIMESTAMP);
+
+        if (t == null) {
+            return null;
+        }
+
+        long millis = t.getSeconds() * 1000;
+
+        if (!resultMetaData.columnTypes[--parameterIndex]
+                .isDateTimeTypeWithZone()) {
+            Calendar calendar = cal == null ? session.getCalendar()
+                    : cal;
+
+            if (cal != null) {
+                millis = HsqlDateTime.convertMillisToCalendar(calendar,
+                        millis);
+            }
+        }
+
+        Timestamp ts = new Timestamp(millis);
+
+        ts.setNanos(t.getNanos());
+
+        return ts;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Registers the designated output parameter.
+     * This version of
+     * the method <code>registerOutParameter</code>
+     * should be used for a user-defined or <code>REF</code> output parameter.  Examples
+     * of user-defined types include: <code>STRUCT</code>, <code>DISTINCT</code>,
+     * <code>JAVA_OBJECT</code>, and named array types.
+     * <p>
+     * All OUT parameters must be registered
+     * before a stored procedure is executed.
+     * <p>  For a user-defined parameter, the fully-qualified SQL
+     * type name of the parameter should also be given, while a <code>REF</code>
+     * parameter requires that the fully-qualified type name of the
+     * referenced type be given.  A JDBC driver that does not need the
+     * type code and type name information may ignore it.   To be portable,
+     * however, applications should always provide these values for
+     * user-defined and <code>REF</code> parameters.
+     *
+     * Although it is intended for user-defined and <code>REF</code> parameters,
+     * this method may be used to register a parameter of any JDBC type.
+     * If the parameter does not have a user-defined or <code>REF</code> type, the
+     * <i>typeName</i> parameter is ignored.
+     *
+     * <P><B>Note:</B> When reading the value of an out parameter, you
+     * must use the getter method whose Java type corresponds to the
+     * parameter's registered SQL type.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,...
+     * @param sqlType a value from {@link java.sql.Types}
+     * @param typeName the fully-qualified name of an SQL structured type
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>sqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type
+     * @see java.sql.Types
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCParameterMetaData)
+     *
+     */
+    public synchronized void registerOutParameter(int parameterIndex,
+            int sqlType, String typeName) throws SQLException {
+        registerOutParameter(parameterIndex, sqlType);
+    }
+
+// ----------------------------------- JDBC 3 ----------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Registers the OUT parameter named
+     * <code>parameterName</code> to the JDBC type
+     * <code>sqlType</code>.  All OUT parameters must be registered
+     * before a stored procedure is executed.
+     * <p>
+     * The JDBC type specified by <code>sqlType</code> for an OUT
+     * parameter determines the Java type that must be used
+     * in the <code>get</code> method to read the value of that parameter.
+     * <p>
+     * If the JDBC type expected to be returned to this output parameter
+     * is specific to this particular database, <code>sqlType</code>
+     * should be <code>java.sql.Types.OTHER</code>.  The method
+     * {@link #getObject} retrieves the value.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param sqlType the JDBC type code defined by <code>java.sql.Types</code>.
+     * If the parameter is of JDBC type <code>NUMERIC</code>
+     * or <code>DECIMAL</code>, the version of
+     * <code>registerOutParameter</code> that accepts a scale value
+     * should be used.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>sqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type or if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQL 1.7.0
+     * @see java.sql.Types
+     */
+//#ifdef JAVA4
+    public synchronized void registerOutParameter(String parameterName,
+            int sqlType) throws SQLException {
+        registerOutParameter(findParameterIndex(parameterName), sqlType);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Registers the parameter named
+     * <code>parameterName</code> to be of JDBC type
+     * <code>sqlType</code>.  (JDBC4 clarification:) All OUT parameters must be registered
+     * before a stored procedure is executed.
+     * <p>
+     * The JDBC type specified by <code>sqlType</code> for an OUT
+     * parameter determines the Java type that must be used
+     * in the <code>get</code> method to read the value of that parameter.
+     * <p>
+     * This version of <code>registerOutParameter</code> should be
+     * used when the parameter is of JDBC type <code>NUMERIC</code>
+     * or <code>DECIMAL</code>.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param sqlType SQL type code defined by <code>java.sql.Types</code>.
+     * @param scale the desired number of digits to the right of the
+     * decimal point.  It must be greater than or equal to zero.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>sqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type or if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     * @see java.sql.Types
+     */
+//#ifdef JAVA4
+    public synchronized void registerOutParameter(String parameterName,
+            int sqlType, int scale) throws SQLException {
+        registerOutParameter(findParameterIndex(parameterName), sqlType);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Registers the designated output parameter.  This version of
+     * the method <code>registerOutParameter</code>
+     * should be used for a user-named or REF output parameter.  Examples
+     * of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and
+     * named array types.
+     * <p>
+     * (JDBC4 clarification:)<p>
+     * All OUT parameters must be registered
+     * before a stored procedure is executed.
+     * <p>
+     * For a user-named parameter the fully-qualified SQL
+     * type name of the parameter should also be given, while a REF
+     * parameter requires that the fully-qualified type name of the
+     * referenced type be given.  A JDBC driver that does not need the
+     * type code and type name information may ignore it.   To be portable,
+     * however, applications should always provide these values for
+     * user-named and REF parameters.
+     *
+     * Although it is intended for user-named and REF parameters,
+     * this method may be used to register a parameter of any JDBC type.
+     * If the parameter does not have a user-named or REF type, the
+     * typeName parameter is ignored.
+     *
+     * <P><B>Note:</B> When reading the value of an out parameter, you
+     * must use the <code>getXXX</code> method whose Java type XXX corresponds to the
+     * parameter's registered SQL type.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param sqlType a value from {@link java.sql.Types}
+     * @param typeName the fully-qualified name of an SQL structured type
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>sqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type or if the JDBC driver does not support
+     * this method
+     * @see java.sql.Types
+     * @since JDK 1.4, HSQL 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void registerOutParameter(String parameterName,
+            int sqlType, String typeName) throws SQLException {
+        registerOutParameter(findParameterIndex(parameterName), sqlType);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>DATALINK</code> parameter as a
+     * <code>java.net.URL</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,...
+     * @return a <code>java.net.URL</code> object that represents the
+     *         JDBC <code>DATALINK</code> value used as the designated
+     *         parameter
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>CallableStatement</code>,
+     *            or if the URL being returned is
+     *            not a valid URL on the Java platform
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setURL
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public java.net.URL getURL(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        throw Util.notSupported();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>java.net.URL</code> object.
+     * The driver converts this to an SQL <code>DATALINK</code> value when
+     * it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param val the parameter value
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>CallableStatement</code>,
+     *            or if a URL is malformed
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getURL
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void setURL(String parameterName,
+                       java.net.URL val) throws SQLException {
+        setURL(findParameterIndex(parameterName), val);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to SQL <code>NULL</code>.
+     *
+     * <P><B>Note:</B> You must specify the parameter's SQL type.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param sqlType the SQL type code defined in <code>java.sql.Types</code>
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setNull(String parameterName,
+                                     int sqlType) throws SQLException {
+        setNull(findParameterIndex(parameterName), sqlType);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java <code>boolean</code> value.
+     *
+     * <p>(JDBC4 clarification:)<p>
+     *
+     * The driver converts this
+     * to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @see #getBoolean
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getBoolean
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setBoolean(String parameterName,
+                                        boolean x) throws SQLException {
+        setBoolean(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java <code>byte</code> value.
+     * The driver converts this
+     * to an SQL <code>TINYINT</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getByte
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setByte(String parameterName,
+                                     byte x) throws SQLException {
+        setByte(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java <code>short</code> value.
+     * The driver converts this
+     * to an SQL <code>SMALLINT</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getShort
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setShort(String parameterName,
+                                      short x) throws SQLException {
+        setShort(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java <code>int</code> value.
+     * The driver converts this
+     * to an SQL <code>INTEGER</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getInt
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setInt(String parameterName,
+                                    int x) throws SQLException {
+        setInt(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java <code>long</code> value.
+     * The driver converts this
+     * to an SQL <code>BIGINT</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getLong
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setLong(String parameterName,
+                                     long x) throws SQLException {
+        setLong(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java <code>float</code> value.
+     * The driver converts this
+     * to an SQL <code>FLOAT</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getFloat
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setFloat(String parameterName,
+                                      float x) throws SQLException {
+        setFloat(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java <code>double</code> value.
+     * The driver converts this
+     * to an SQL <code>DOUBLE</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getDouble
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setDouble(String parameterName,
+                                       double x) throws SQLException {
+        setDouble(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given
+     * <code>java.math.BigDecimal</code> value.
+     * The driver converts this to an SQL <code>NUMERIC</code> value when
+     * it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getBigDecimal
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setBigDecimal(String parameterName,
+            BigDecimal x) throws SQLException {
+        setBigDecimal(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java <code>String</code> value.
+     * The driver converts this
+     * to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
+     * (depending on the argument's
+     * size relative to the driver's limits on <code>VARCHAR</code> values)
+     * when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getString
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setString(String parameterName,
+                                       String x) throws SQLException {
+        setString(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given Java array of bytes.
+     * The driver converts this to an SQL <code>VARBINARY</code> or
+     * <code>LONGVARBINARY</code> (depending on the argument's size relative
+     * to the driver's limits on <code>VARBINARY</code> values) when it sends
+     * it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getBytes
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setBytes(String parameterName,
+                                      byte[] x) throws SQLException {
+        setBytes(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>java.sql.Date</code> value
+     * (JDBC4 clarification:)<p>
+     * using the default time zone of the virtual machine that is running
+     * the application.
+     * The driver converts this
+     * to an SQL <code>DATE</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getDate
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setDate(String parameterName,
+                                     Date x) throws SQLException {
+        setDate(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>java.sql.Time</code> value.
+     * The driver converts this
+     * to an SQL <code>TIME</code> value when it sends it to the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getTime
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setTime(String parameterName,
+                                     Time x) throws SQLException {
+        setTime(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
+     * The driver
+     * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the
+     * database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getTimestamp
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setTimestamp(String parameterName,
+            Timestamp x) throws SQLException {
+        setTimestamp(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given input stream, which will have
+     * the specified number of bytes.
+     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from ASCII to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setAsciiStream(String parameterName,
+            java.io.InputStream x, int length) throws SQLException {
+        setAsciiStream(findParameterIndex(parameterName), x, length);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given input stream, which will have
+     * the specified number of bytes.
+     * When a very large binary value is input to a <code>LONGVARBINARY</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setBinaryStream(String parameterName,
+            java.io.InputStream x, int length) throws SQLException {
+        setBinaryStream(findParameterIndex(parameterName), x, length);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the value of the designated parameter with the given object. The second
+     * argument must be an object type; for integral values, the
+     * <code>java.lang</code> equivalent objects should be used.
+     *
+     * <p>The given Java object will be converted to the given targetSqlType
+     * before being sent to the database.
+     *
+     * If the object has a custom mapping (is of a class implementing the
+     * interface <code>SQLData</code>),
+     * the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it
+     * to the SQL data stream.
+     * If, on the other hand, the object is of a class implementing
+     * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>,  <code>NClob</code>,
+     *  <code>Struct</code>, <code>java.net.URL</code>,
+     * or <code>Array</code>, the driver should pass it to the database as a
+     * value of the corresponding SQL type.
+     * <P>
+     * Note that this method may be used to pass datatabase-
+     * specific abstract data types.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the object containing the input parameter value
+     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
+     * sent to the database. The scale argument may further qualify this type.
+     * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,
+     *          this is the number of digits after the decimal point.  For all other
+     *          types, this value will be ignored.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type
+     * @see java.sql.Types
+     * @see #getObject
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setObject(String parameterName, Object x,
+                                       int targetSqlType,
+                                       int scale) throws SQLException {
+        setObject(findParameterIndex(parameterName), x, targetSqlType, scale);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the value of the designated parameter with the given object.
+     * This method is like the method <code>setObject</code>
+     * above, except that it assumes a scale of zero.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the object containing the input parameter value
+     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
+     *                      sent to the database
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type
+     * @see #getObject
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setObject(String parameterName, Object x,
+                                       int targetSqlType) throws SQLException {
+        setObject(findParameterIndex(parameterName), x, targetSqlType);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the value of the designated parameter with the given object.
+     * The second parameter must be of type <code>Object</code>; therefore, the
+     * <code>java.lang</code> equivalent objects should be used for built-in types.
+     *
+     * <p>The JDBC specification specifies a standard mapping from
+     * Java <code>Object</code> types to SQL types.  The given argument
+     * will be converted to the corresponding SQL type before being
+     * sent to the database.
+     *
+     * <p>Note that this method may be used to pass datatabase-
+     * specific abstract data types, by using a driver-specific Java
+     * type.
+     *
+     * If the object is of a class implementing the interface <code>SQLData</code>,
+     * the JDBC driver should call the method <code>SQLData.writeSQL</code>
+     * to write it to the SQL data stream.
+     * If, on the other hand, the object is of a class implementing
+     * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>,  <code>NClob</code>,
+     *  <code>Struct</code>, <code>java.net.URL</code>,
+     * or <code>Array</code>, the driver should pass it to the database as a
+     * value of the corresponding SQL type.
+     * <P>
+     * This method throws an exception if there is an ambiguity, for example, if the
+     * object is of a class implementing more than one of the interfaces named above.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the object containing the input parameter value
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>CallableStatement</code> or if the given
+     *            <code>Object</code> parameter is ambiguous
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getObject
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setObject(String parameterName,
+                                       Object x) throws SQLException {
+        setObject(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>Reader</code>
+     * object, which is the given number of characters long.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param reader the <code>java.io.Reader</code> object that
+     *        contains the UNICODE data used as the designated parameter
+     * @param length the number of characters in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setCharacterStream(String parameterName,
+            java.io.Reader reader, int length) throws SQLException {
+        setCharacterStream(findParameterIndex(parameterName), reader, length);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>java.sql.Date</code> value,
+     * using the given <code>Calendar</code> object.  The driver uses
+     * the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
+     * which the driver then sends to the database.  With a
+     * a <code>Calendar</code> object, the driver can calculate the date
+     * taking into account a custom timezone.  If no
+     * <code>Calendar</code> object is specified, the driver uses the default
+     * timezone, which is that of the virtual machine running the application.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the date
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getDate
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setDate(String parameterName, Date x,
+                                     Calendar cal) throws SQLException {
+        setDate(findParameterIndex(parameterName), x, cal);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>java.sql.Time</code> value,
+     * using the given <code>Calendar</code> object.  The driver uses
+     * the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
+     * which the driver then sends to the database.  With a
+     * a <code>Calendar</code> object, the driver can calculate the time
+     * taking into account a custom timezone.  If no
+     * <code>Calendar</code> object is specified, the driver uses the default
+     * timezone, which is that of the virtual machine running the application.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the time
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getTime
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setTime(String parameterName, Time x,
+                                     Calendar cal) throws SQLException {
+        setTime(findParameterIndex(parameterName), x, cal);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
+     * using the given <code>Calendar</code> object.  The driver uses
+     * the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,
+     * which the driver then sends to the database.  With a
+     * a <code>Calendar</code> object, the driver can calculate the timestamp
+     * taking into account a custom timezone.  If no
+     * <code>Calendar</code> object is specified, the driver uses the default
+     * timezone, which is that of the virtual machine running the application.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the timestamp
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getTimestamp
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setTimestamp(String parameterName, Timestamp x,
+            Calendar cal) throws SQLException {
+        setTimestamp(findParameterIndex(parameterName), x, cal);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to SQL <code>NULL</code>.
+     * This version of the method <code>setNull</code> should
+     * be used for user-defined types and REF type parameters.  Examples
+     * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and
+     * named array types.
+     *
+     * <P><B>Note:</B> To be portable, applications must give the
+     * SQL type code and the fully-qualified SQL type name when specifying
+     * a NULL user-defined or REF parameter.  In the case of a user-defined type
+     * the name is the type name of the parameter itself.  For a REF
+     * parameter, the name is the type name of the referenced type.  If
+     * a JDBC driver does not need the type code or type name information,
+     * it may ignore it.
+     *
+     * Although it is intended for user-defined and Ref parameters,
+     * this method may be used to set a null parameter of any JDBC type.
+     * If the parameter does not have a user-defined or REF type, the given
+     * typeName is ignored.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param sqlType a value from <code>java.sql.Types</code>
+     * @param typeName the fully-qualified name of an SQL user-defined type;
+     *        ignored if the parameter is not a user-defined type or
+     *        SQL <code>REF</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized void setNull(String parameterName, int sqlType,
+                                     String typeName) throws SQLException {
+        setNull(findParameterIndex(parameterName), sqlType, typeName);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
+     * or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
+     * the Java programming language.
+     * <p>
+     * For the fixed-length type JDBC <code>CHAR</code>,
+     * the <code>String</code> object
+     * returned has exactly the same value the (JDBC4 clarification:) SQL
+     * <code>CHAR</code> value had in the
+     * database, including any padding added by the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value. If the value is SQL <code>NULL</code>, the result
+     * is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setString
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized String getString(
+            String parameterName) throws SQLException {
+        return getString(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * (JDBC4 modified:)<p>
+     * Retrieves the value of a JDBC <code>BIT</code> or <code>BOOLEAN</code>
+     * parameter as a
+     * <code>boolean</code> in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>false</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setBoolean
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized boolean getBoolean(
+            String parameterName) throws SQLException {
+        return getBoolean(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code>
+     * in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setByte
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized byte getByte(
+            String parameterName) throws SQLException {
+        return getByte(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code>
+     * in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setShort
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized short getShort(
+            String parameterName) throws SQLException {
+        return getShort(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code>
+     * in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>,
+     *         the result is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setInt
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized int getInt(String parameterName) throws SQLException {
+        return getInt(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code>
+     * in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>,
+     *         the result is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setLong
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized long getLong(
+            String parameterName) throws SQLException {
+        return getLong(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code>
+     * in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>,
+     *         the result is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setFloat
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized float getFloat(
+            String parameterName) throws SQLException {
+        return getFloat(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code>
+     * in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>,
+     *         the result is <code>0</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setDouble
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized double getDouble(
+            String parameterName) throws SQLException {
+        return getDouble(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code>
+     * parameter as an array of <code>byte</code> values in the Java
+     * programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result is
+     *  <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setBytes
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized byte[] getBytes(
+            String parameterName) throws SQLException {
+        return getBytes(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>DATE</code> parameter as a
+     * <code>java.sql.Date</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setDate
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Date getDate(
+            String parameterName) throws SQLException {
+        return getDate(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>TIME</code> parameter as a
+     * <code>java.sql.Time</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setTime
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Time getTime(
+            String parameterName) throws SQLException {
+        return getTime(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
+     * <code>java.sql.Timestamp</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result
+     * is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setTimestamp
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Timestamp getTimestamp(
+            String parameterName) throws SQLException {
+        return getTimestamp(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a parameter as an <code>Object</code> in the Java
+     * programming language. If the value is an SQL <code>NULL</code>, the
+     * driver returns a Java <code>null</code>.
+     * <p>
+     * This method returns a Java object whose type corresponds to the JDBC
+     * type that was registered for this parameter using the method
+     * <code>registerOutParameter</code>.  By registering the target JDBC
+     * type as <code>java.sql.Types.OTHER</code>, this method can be used
+     * to read database-specific abstract data types.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return A <code>java.lang.Object</code> holding the OUT parameter value.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see java.sql.Types
+     * @see #setObject
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Object getObject(
+            String parameterName) throws SQLException {
+        return getObject(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>NUMERIC</code> parameter as a
+     * <code>java.math.BigDecimal</code> object with as many digits to the
+     * right of the decimal point as the value contains.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value in full precision.  If the value is
+     * SQL <code>NULL</code>, the result is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setBigDecimal
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized BigDecimal getBigDecimal(
+            String parameterName) throws SQLException {
+        return getBigDecimal(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Returns an object representing the value of OUT parameter
+     * <code>parameterName</code> and uses <code>map</code> for the custom
+     * mapping of the parameter value.
+     * <p>
+     * This method returns a Java object whose type corresponds to the
+     * JDBC type that was registered for this parameter using the method
+     * <code>registerOutParameter</code>.  By registering the target
+     * JDBC type as <code>java.sql.Types.OTHER</code>, this method can
+     * be used to read database-specific abstract data types.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param map the mapping from SQL type names to Java classes
+     * @return a <code>java.lang.Object</code> holding the OUT parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setObject
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+
+    /** @todo: how to use CodeSwitcher and +JAVA6 to specifiy Map<String,Class<?>> */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+
+//#endif JAVA6
+//#ifdef JAVA4
+    public synchronized Object getObject(String parameterName,
+            Map map) throws SQLException {
+        return getObject(findParameterIndex(parameterName), map);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>REF(&lt;structured-type&gt;)</code>
+     * parameter as a {@link java.sql.Ref} object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value as a <code>Ref</code> object in the
+     *         Java programming language.  If the value was SQL <code>NULL</code>,
+     *         the value <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Ref getRef(String parameterName) throws SQLException {
+        return getRef(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>BLOB</code> parameter as a
+     * {@link java.sql.Blob} object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value as a <code>Blob</code> object in the
+     *         Java programming language.  If the value was SQL <code>NULL</code>,
+     *         the value <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Blob getBlob(
+            String parameterName) throws SQLException {
+        return getBlob(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>CLOB</code> parameter as a
+     * {@link java.sql.Clob} object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value as a <code>Clob</code> object in the
+     *         Java programming language.  If the value was SQL <code>NULL</code>,
+     *         the value <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Clob getClob(
+            String parameterName) throws SQLException {
+        return getClob(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>ARRAY</code> parameter as an
+     * {@link java.sql.Array} object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value as an <code>Array</code> object in
+     *         Java programming language.  If the value was SQL <code>NULL</code>,
+     *         the value <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Array getArray(
+            String parameterName) throws SQLException {
+        return getArray(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>DATE</code> parameter as a
+     * <code>java.sql.Date</code> object, using
+     * the given <code>Calendar</code> object
+     * to construct the date.
+     * With a <code>Calendar</code> object, the driver
+     * can calculate the date taking into account a custom timezone and locale.
+     * If no <code>Calendar</code> object is specified, the driver uses the
+     * default timezone and locale.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the date
+     * @return the parameter value.  If the value is SQL <code>NULL</code>,
+     * the result is <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setDate
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Date getDate(String parameterName,
+                                     Calendar cal) throws SQLException {
+        return getDate(findParameterIndex(parameterName), cal);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>TIME</code> parameter as a
+     * <code>java.sql.Time</code> object, using
+     * the given <code>Calendar</code> object
+     * to construct the time.
+     * With a <code>Calendar</code> object, the driver
+     * can calculate the time taking into account a custom timezone and locale.
+     * If no <code>Calendar</code> object is specified, the driver uses the
+     * default timezone and locale.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the time
+     * @return the parameter value; if the value is SQL <code>NULL</code>, the result is
+     * <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setTime
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Time getTime(String parameterName,
+                                     Calendar cal) throws SQLException {
+        return getTime(findParameterIndex(parameterName), cal);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a
+     * <code>java.sql.Timestamp</code> object, using
+     * the given <code>Calendar</code> object to construct
+     * the <code>Timestamp</code> object.
+     * With a <code>Calendar</code> object, the driver
+     * can calculate the timestamp taking into account a custom timezone and locale.
+     * If no <code>Calendar</code> object is specified, the driver uses the
+     * default timezone and locale.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @param parameterName the name of the parameter
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the timestamp
+     * @return the parameter value.  If the value is SQL <code>NULL</code>, the result is
+     * <code>null</code>.
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setTimestamp
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized Timestamp getTimestamp(String parameterName,
+            Calendar cal) throws SQLException {
+        return getTimestamp(findParameterIndex(parameterName), cal);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>DATALINK</code> parameter as a
+     * <code>java.net.URL</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value as a <code>java.net.URL</code> object in the
+     * Java programming language.  If the value was SQL <code>NULL</code>, the
+     * value <code>null</code> is returned.
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>CallableStatement</code>,
+     *            or if there is a problem with the URL
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setURL
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public java.net.URL getURL(String parameterName) throws SQLException {
+        return getURL(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA4
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a
+     * <code>java.sql.RowId</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2,...
+     * @return a <code>RowId</code> object that represents the JDBC <code>ROWID</code>
+     *     value is used as the designated parameter. If the parameter contains
+     * a SQL <code>NULL</code>, then a <code>null</code> value is returned.
+     * @throws SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public RowId getRowId(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a
+     * <code>java.sql.RowId</code> object.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return a <code>RowId</code> object that represents the JDBC <code>ROWID</code>
+     *     value is used as the designated parameter. If the parameter contains
+     * a SQL <code>NULL</code>, then a <code>null</code> value is returned.
+     * @throws SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized RowId getRowId(
+            String parameterName) throws SQLException {
+        return getRowId(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The
+     * driver converts this to a SQL <code>ROWID</code> when it sends it to the
+     * database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @param x the parameter value
+     * @throws SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setRowId(String parameterName,
+                                      RowId x) throws SQLException {
+        super.setRowId(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given <code>String</code> object.
+     * The driver converts this to a SQL <code>NCHAR</code> or
+     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code>
+     * @param parameterName the name of the parameter to be set
+     * @param value the parameter value
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setNString(String parameterName,
+                                        String value) throws SQLException {
+        super.setNString(findParameterIndex(parameterName), value);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object. The
+     * <code>Reader</code> reads the data till end-of-file is reached. The
+     * driver does the necessary conversion from Java character format to
+     * the national character set in the database.
+     * @param parameterName the name of the parameter to be set
+     * @param value the parameter value
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setNCharacterStream(String parameterName,
+            Reader value, long length) throws SQLException {
+        super.setNCharacterStream(findParameterIndex(parameterName), value,
+                                  length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to a <code>java.sql.NClob</code> object. The object
+     * implements the <code>java.sql.NClob</code> interface. This <code>NClob</code>
+     * object maps to a SQL <code>NCLOB</code>.
+     * @param parameterName the name of the parameter to be set
+     * @param value the parameter value
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setNClob(String parameterName,
+                                      NClob value) throws SQLException {
+        super.setNClob(findParameterIndex(parameterName), value);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object.  The <code>reader</code> must contain  the number
+     * of characters specified by length otherwise a <code>SQLException</code> will be
+     * generated when the <code>CallableStatement</code> is executed.
+     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
+     * because it informs the driver that the parameter value should be sent to
+     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     * @param parameterName the name of the parameter to be set
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement; if the length specified is less than zero;
+     * a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setClob(String parameterName, Reader reader,
+                                     long length) throws SQLException {
+        super.setClob(findParameterIndex(parameterName), reader, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to a <code>InputStream</code> object.  The <code>inputstream</code> must contain  the number
+     * of characters specified by length, otherwise a <code>SQLException</code> will be
+     * generated when the <code>CallableStatement</code> is executed.
+     * This method differs from the <code>setBinaryStream (int, InputStream, int)</code>
+     * method because it informs the driver that the parameter value should be
+     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter
+     * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     *
+     * @param parameterName the name of the parameter to be set
+     * the second is 2, ...
+     *
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @param length the number of bytes in the parameter data.
+     * @throws SQLException  if parameterIndex does not correspond
+     * to a parameter marker in the SQL statement,  or if the length specified
+     * is less than zero; if the number of bytes in the inputstream does not match
+     * the specfied length; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setBlob(String parameterName,
+                                     InputStream inputStream,
+                                     long length) throws SQLException {
+        super.setBlob(findParameterIndex(parameterName), inputStream, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object.  The <code>reader</code> must contain  the number
+     * of characters specified by length otherwise a <code>SQLException</code> will be
+     * generated when the <code>CallableStatement</code> is executed.
+     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
+     * because it informs the driver that the parameter value should be sent to
+     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+     *
+     * @param parameterName the name of the parameter to be set
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement; if the length specified is less than zero;
+     * if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setNClob(String parameterName, Reader reader,
+                                      long length) throws SQLException {
+        super.setNClob(findParameterIndex(parameterName), reader, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated JDBC <code>NCLOB</code> parameter as a
+     * <code>java.sql.NClob</code> object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, and
+     * so on
+     * @return the parameter value as a <code>NClob</code> object in the
+     * Java programming language.  If the value was SQL <code>NULL</code>, the
+     * value <code>null</code> is returned.
+     * @exception SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public NClob getNClob(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of a JDBC <code>NCLOB</code> parameter as a
+     * <code>java.sql.NClob</code> object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return the parameter value as a <code>NClob</code> object in the
+     *         Java programming language.  If the value was SQL <code>NULL</code>,
+     *         the value <code>null</code> is returned.
+     * @exception SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized NClob getNClob(
+            String parameterName) throws SQLException {
+        return getNClob(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an
+     * <code>SQL XML</code> value when it sends it to the database.
+     *
+     * @param parameterName the name of the parameter
+     * @param xmlObject a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+     * @throws SQLException if a database access error occurs,
+     * this method is called on a closed <code>CallableStatement</code> or
+     * the <code>java.xml.transform.Result</code>,
+     *  <code>Writer</code> or <code>OutputStream</code> has not been closed for the <code>SQLXML</code> object
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setSQLXML(String parameterName,
+                                       SQLXML xmlObject) throws SQLException {
+        super.setSQLXML(findParameterIndex(parameterName), xmlObject);
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated <code>SQL XML</code> parameter as a
+     * <code>java.sql.SQLXML</code> object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+     * @throws SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public SQLXML getSQLXML(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated <code>SQL XML</code> parameter as a
+     * <code>java.sql.SQLXML</code> object in the Java programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+     * @throws SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized SQLXML getSQLXML(
+            String parameterName) throws SQLException {
+        return getSQLXML(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated <code>NCHAR</code>,
+     * <code>NVARCHAR</code>
+     * or <code>LONGNVARCHAR</code> parameter as
+     * a <code>String</code> in the Java programming language.
+     *  <p>
+     * For the fixed-length type JDBC <code>NCHAR</code>,
+     * the <code>String</code> object
+     * returned has exactly the same value the SQL
+     * <code>NCHAR</code> value had in the
+     * database, including any padding added by the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @return a <code>String</code> object that maps an
+     * <code>NCHAR</code>, <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     * @see #setNString
+     */
+//#ifdef JAVA6
+    public String getNString(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     *  Retrieves the value of the designated <code>NCHAR</code>,
+     * <code>NVARCHAR</code>
+     * or <code>LONGNVARCHAR</code> parameter as
+     * a <code>String</code> in the Java programming language.
+     * <p>
+     * For the fixed-length type JDBC <code>NCHAR</code>,
+     * the <code>String</code> object
+     * returned has exactly the same value the SQL
+     * <code>NCHAR</code> value had in the
+     * database, including any padding added by the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return a <code>String</code> object that maps an
+     * <code>NCHAR</code>, <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     * @see #setNString
+     */
+//#ifdef JAVA6
+    public synchronized String getNString(
+            String parameterName) throws SQLException {
+        return getNString(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated parameter as a
+     * <code>java.io.Reader</code> object in the Java programming language.
+     * It is intended for use when
+     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> parameters.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>java.io.Reader</code> object that contains the parameter
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public Reader getNCharacterStream(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated parameter as a
+     * <code>java.io.Reader</code> object in the Java programming language.
+     * It is intended for use when
+     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> parameters.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return a <code>java.io.Reader</code> object that contains the parameter
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized Reader getNCharacterStream(
+            String parameterName) throws SQLException {
+        return getNCharacterStream(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated parameter as a
+     * <code>java.io.Reader</code> object in the Java programming language.
+     *
+     * <!-- end generic documentstion -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. <p>
+     *
+     * Calling this method always throws an <code>SQLException</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>java.io.Reader</code> object that contains the parameter
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public Reader getCharacterStream(int parameterIndex) throws SQLException {
+
+        checkGetParameterIndex(parameterIndex);
+
+        Type   sourceType = resultMetaData.columnTypes[parameterIndex - 1];
+        Object o          = getColumnInType(parameterIndex, sourceType);
+
+        if (o == null) {
+            return null;
+        }
+
+        if (o instanceof ClobDataID) {
+            return ((ClobDataID) o).getCharacterStream(session);
+        } else if (o instanceof Clob) {
+            return ((Clob) o).getCharacterStream();
+        } else if (o instanceof String) {
+            return new StringReader((String) o);
+        }
+
+        throw Util.sqlException(ErrorCode.X_42561);
+    }
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the value of the designated parameter as a
+     * <code>java.io.Reader</code> object in the Java programming language.
+     *
+     * <!-- end generic documentstion -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterName the name of the parameter
+     * @return a <code>java.io.Reader</code> object that contains the parameter
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized Reader getCharacterStream(
+            String parameterName) throws SQLException {
+        return getCharacterStream(findParameterIndex(parameterName));
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given <code>java.sql.Blob</code> object.
+     * The driver converts this to an SQL <code>BLOB</code> value when it
+     * sends it to the database.
+     *
+     * @param parameterName the name of the parameter
+     * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     *  @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setBlob(String parameterName,
+                                     Blob x) throws SQLException {
+        super.setBlob(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given <code>java.sql.Clob</code> object.
+     * The driver converts this to an SQL <code>CLOB</code> value when it
+     * sends it to the database.
+     *
+     * @param parameterName the name of the parameter
+     * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     *  @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setClob(String parameterName,
+                                     Clob x) throws SQLException {
+        super.setClob(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given input stream, which will have
+     * the specified number of bytes.
+     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from ASCII to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
+     * @exception SQLException if parameterName does not correspond to a named
+     * parameter; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setAsciiStream(String parameterName,
+            java.io.InputStream x, long length) throws SQLException {
+
+        if (length > Integer.MAX_VALUE) {
+            String msg = "Maximum ASCII input octet length exceeded: "
+                         + length;    // NOI18N
+
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR, msg);
+        }
+        this.setAsciiStream(parameterName, x, (int) length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given input stream, which will have
+     * the specified number of bytes.
+     * When a very large binary value is input to a <code>LONGVARBINARY</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setBinaryStream(String parameterName,
+            java.io.InputStream x, long length) throws SQLException {
+
+        if (length > Integer.MAX_VALUE) {
+            String msg = "Maximum Binary input octet length exceeded: "
+                         + length;    // NOI18N
+
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR, msg);
+        }
+        setBinaryStream(parameterName, x, (int) length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given <code>Reader</code>
+     * object, which is the given number of characters long.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * @param parameterName the name of the parameter
+     * @param reader the <code>java.io.Reader</code> object that
+     *        contains the UNICODE data used as the designated parameter
+     * @param length the number of characters in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public synchronized void setCharacterStream(String parameterName,
+            java.io.Reader reader, long length) throws SQLException {
+
+        if (length > Integer.MAX_VALUE) {
+            String msg = "Maximum character input length exceeded: " + length;    // NOI18N
+
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR, msg);
+        }
+        setCharacterStream(parameterName, reader, (int) length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given input stream.
+     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from ASCII to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setAsciiStream</code> which takes a length parameter.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @exception SQLException if parameterName does not correspond to a named
+     * parameter; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *   @since 1.6
+     */
+//#ifdef JAVA6
+    public synchronized void setAsciiStream(String parameterName,
+            java.io.InputStream x) throws SQLException {
+        super.setAsciiStream(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given input stream.
+     * When a very large binary value is input to a <code>LONGVARBINARY</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code> object. The data will be read from the
+     * stream as needed until end-of-file is reached.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setBinaryStream</code> which takes a length parameter.
+     *
+     * @param parameterName the name of the parameter
+     * @param x the java input stream which contains the binary parameter value
+     * @exception SQLException if parameterName does not correspond to a named
+     * parameter; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since 1.6
+     */
+//#ifdef JAVA6
+    public synchronized void setBinaryStream(String parameterName,
+            java.io.InputStream x) throws SQLException {
+        super.setBinaryStream(findParameterIndex(parameterName), x);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to the given <code>Reader</code>
+     * object.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setCharacterStream</code> which takes a length parameter.
+     *
+     * @param parameterName the name of the parameter
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     *        Unicode data
+     * @exception SQLException if parameterName does not correspond to a named
+     * parameter; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since 1.6
+     */
+//#ifdef JAVA6
+    public synchronized void setCharacterStream(String parameterName,
+            java.io.Reader reader) throws SQLException {
+        super.setCharacterStream(findParameterIndex(parameterName), reader);
+    }
+
+//#endif JAVA6
+
+    /**
+     *   Sets the designated parameter to a <code>Reader</code> object. The
+     *   <code>Reader</code> reads the data till end-of-file is reached. The
+     *   driver does the necessary conversion from Java character format to
+     *   the national character set in the database.
+     *
+     *   <P><B>Note:</B> This stream object can either be a standard
+     *   Java stream object or your own subclass that implements the
+     *   standard interface.
+     *   <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     *   it might be more efficient to use a version of
+     *   <code>setNCharacterStream</code> which takes a length parameter.
+     *
+     *   @param parameterName the name of the parameter
+     *   @param value the parameter value
+     *   @throws SQLException if parameterName does not correspond to a named
+     *   parameter; if the driver does not support national
+     *           character sets;  if the driver can detect that a data conversion
+     *    error could occur; if a database access error occurs; or
+     *   this method is called on a closed <code>CallableStatement</code>
+     *   @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *   @since 1.6
+     */
+//#ifdef JAVA6
+    public synchronized void setNCharacterStream(String parameterName,
+            Reader value) throws SQLException {
+        super.setNCharacterStream(findParameterIndex(parameterName), value);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object.
+     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
+     * because it informs the driver that the parameter value should be sent to
+     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setClob</code> which takes a length parameter.
+     *
+     * @param parameterName the name of the parameter
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if parameterName does not correspond to a named
+     * parameter; if a database access error occurs or this method is called on
+     * a closed <code>CallableStatement</code>
+     *
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since 1.6
+     */
+//#ifdef JAVA6
+    public synchronized void setClob(String parameterName,
+                                     Reader reader) throws SQLException {
+        super.setClob(findParameterIndex(parameterName), reader);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to a <code>InputStream</code> object.
+     * This method differs from the <code>setBinaryStream (int, InputStream)</code>
+     * method because it informs the driver that the parameter value should be
+     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setBlob</code> which takes a length parameter.
+     *
+     * @param parameterName the name of the parameter
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @throws SQLException if parameterName does not correspond to a named
+     * parameter; if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *
+     * @since 1.6
+     */
+//#ifdef JAVA6
+    public synchronized void setBlob(
+            String parameterName,
+            InputStream inputStream) throws SQLException {
+        super.setBlob(findParameterIndex(parameterName), inputStream);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object.
+     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
+     * because it informs the driver that the parameter value should be sent to
+     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setNClob</code> which takes a length parameter.
+     *
+     * @param parameterName the name of the parameter
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if parameterName does not correspond to a named
+     * parameter; if the driver does not support national character sets;
+     * if the driver can detect that a data conversion
+     *  error could occur;  if a database access error occurs or
+     * this method is called on a closed <code>CallableStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *
+     * @since 1.6
+     */
+//#ifdef JAVA6
+    public synchronized void setNClob(String parameterName,
+                                      Reader reader) throws SQLException {
+        super.setNClob(findParameterIndex(parameterName), reader);
+    }
+
+//#endif JAVA6
+// --------------------------- Internal Implementation -------------------------
+
+    /** parameter name => parameter index */
+    private IntValueHashMap parameterNameMap;
+    private boolean         wasNullValue;
+
+    /** parameter index => registered OUT type */
+
+//  private IntKeyIntValueHashMap outRegistrationMap;
+
+    /**
+     * Constructs a new JDBCCallableStatement with the specified connection and
+     * result type.
+     *
+     * @param  c the connection on which this statement will execute
+     * @param sql the SQL statement this object represents
+     * @param resultSetType the type of result this statement will produce
+     * @throws HsqlException if the statement is not accepted by the database
+     * @throws SQLException if preprocessing by driver fails
+     */
+    public JDBCCallableStatement(
+            JDBCConnection c, String sql, int resultSetType,
+            int resultSetConcurrency,
+            int resultSetHoldability) throws HsqlException, SQLException {
+
+        super(c, sql, resultSetType, resultSetConcurrency,
+              resultSetHoldability, ResultConstants.RETURN_NO_GENERATED_KEYS,
+              null, null);
+
+        String[] names;
+        String   name;
+
+        // outRegistrationMap = new IntKeyIntValueHashMap();
+        parameterNameMap = new IntValueHashMap();
+
+        if (parameterMetaData != null) {
+            names = parameterMetaData.columnLabels;
+
+            for (int i = 0; i < names.length; i++) {
+                name = names[i];
+
+                // PRE:  should never happen in practice
+                if (name == null || name.length() == 0) {
+                    continue;    // throw?
+                }
+                parameterNameMap.put(name, i);
+            }
+        }
+    }
+
+    void fetchResult() throws SQLException {
+
+        super.fetchResult();
+
+        if (resultIn.getType() == ResultConstants.CALL_RESPONSE) {
+            Object[] data = resultIn.getParameterData();
+
+            for (int i = 0; i < parameterValues.length; i++) {
+                parameterValues[i] = data[i];
+            }
+        }
+    }
+
+    /**
+     * Retrieves the parameter index corresponding to the given
+     * parameter name. <p>
+     *
+     * @param parameterName to look up
+     * @throws SQLException if not found
+     * @return index for name
+     */
+    int findParameterIndex(String parameterName) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        int index = parameterNameMap.get(parameterName, -1);
+
+        if (index >= 0) {
+            return index + 1;
+        }
+
+        throw Util.sqlException(ErrorCode.JDBC_COLUMN_NOT_FOUND,
+                                parameterName);
+    }
+
+    /**
+     * Does the specialized work required to free this object's resources and
+     * that of it's parent classes. <p>
+     *
+     * @throws SQLException if a database access error occurs
+     */
+    public synchronized void close() throws SQLException {
+
+        if (isClosed()) {
+            return;
+        }
+
+        // outRegistrationMap = null;
+        parameterNameMap = null;
+
+        super.close();
+    }
+
+    /**
+     * Checks if the parameter of the given index has been successfully
+     * registered as an OUT parameter. <p>
+     *
+     * @param parameterIndex to check
+     * @throws SQLException if not registered
+     */
+/*
+    private void checkIsRegisteredParameterIndex(int parameterIndex)
+    throws SQLException {
+
+        int    type;
+        String msg;
+
+        checkClosed();
+
+        type = outRegistrationMap.get(parameterIndex, Integer.MIN_VALUE);
+
+        if (type == Integer.MIN_VALUE) {
+            msg = "Parameter not registered: " + parameterIndex; //NOI18N
+
+            throw Util.sqlException(ErrorCode.INVALID_JDBC_ARGUMENT, msg);
+        }
+    }
+*/
+
+    /**
+     * Internal value converter. Similar to its counterpart in JDBCResultSet <p>
+     *
+     * All trivially successful getXXX methods eventually go through this
+     * method, converting if neccessary from the source type to the
+     * requested type.  <p>
+     *
+     * Conversion to the JDBC representation, if different, is handled by the
+     * calling methods.
+     *
+     * @param columnIndex of the column value for which to perform the
+     *                 conversion
+     * @param targetType the org.hsqldb.types.Type object for targetType
+     * @return an Object of the requested targetType, representing the value of the
+     *       specified column
+     * @throws SQLException when there is no rowData, the column index is
+     *    invalid, or the conversion cannot be performed
+     */
+    private Object getColumnInType(int columnIndex,
+                                   Type targetType) throws SQLException {
+
+        checkGetParameterIndex(columnIndex);
+
+        Type   sourceType;
+        Object value;
+
+        sourceType = parameterTypes[--columnIndex];
+        value      = parameterValues[columnIndex];
+
+        if (trackNull(value)) {
+            return null;
+        }
+
+        if (sourceType.typeCode != targetType.typeCode) {
+            try {
+                value = targetType.convertToTypeJDBC(session, value,
+                        sourceType);
+            } catch (HsqlException e) {
+                String stringValue =
+                    (value instanceof Number || value instanceof String
+                     || value instanceof java.util.Date) ? value.toString()
+                        : "instance of " + value.getClass().getName();
+                String msg = "from SQL type " + sourceType.getNameString()
+                             + " to " + targetType.getJDBCClassName()
+                             + ", value: " + stringValue;
+                HsqlException err = Error.error(ErrorCode.X_42561, msg);
+
+                throw Util.sqlException(err, e);
+            }
+        }
+
+        return value;
+    }
+
+    private boolean trackNull(Object o) {
+        return (wasNullValue = (o == null));
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCClob.java b/src/org/hsqldb/jdbc/JDBCClob.java
new file mode 100644
index 0000000..b95ec78
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCClob.java
@@ -0,0 +1,932 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import org.hsqldb.lib.java.JavaSystem;
+
+/* $Id: JDBCClob.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+// boucherb@users 2004-03/04-xx - doc 1.7.2 - javadocs updated; methods put in
+//                                            correct (historical, interface
+//                                            declared) order
+// boucherb@users 2004-03/04-xx - patch 1.7.2 - null check for constructor (a
+//                                              null CLOB value is Java null,
+//                                              not a Clob object with null
+//                                              data);moderate thread safety;
+//                                              simplification; optimization
+//                                              of operations between jdbcClob
+//                                              instances
+// boucherb@users 2005-12-07    - patch 1.8.0.x - initial JDBC 4.0 support work
+// boucherb@users 2006-05-22    - doc   1.9.0 - full synch up to Mustang Build 84
+//                              - patch 1.9.0 - setAsciiStream &
+//                                              setCharacterStream improvement
+// patch 1.9.0
+// - full synch up to Mustang b90
+// - better bounds checking
+
+/**
+ * The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ * for the SQL <code>CLOB</code> type.
+ * An SQL <code>CLOB</code> is a built-in type
+ * that stores a Character Large Object as a column value in a row of
+ * a database table.
+ * By default drivers implement a <code>Clob</code> object using an SQL
+ * <code>locator(CLOB)</code>, which means that a <code>Clob</code> object
+ * contains a logical pointer to the SQL <code>CLOB</code> data rather than
+ * the data itself. A <code>Clob</code> object is valid for the duration
+ * of the transaction in which it was created.
+ * <P>The <code>Clob</code> interface provides methods for getting the
+ * length of an SQL <code>CLOB</code> (Character Large Object) value,
+ * for materializing a <code>CLOB</code> value on the client, and for
+ * searching for a substring or <code>CLOB</code> object within a
+ * <code>CLOB</code> value.
+ * Methods in the interfaces {@link java.sql.ResultSet},
+ * {@link java.sql.CallableStatement}, and {@link java.sql.PreparedStatement}, such as
+ * <code>getClob</code> and <code>setClob</code> allow a programmer to
+ * access an SQL <code>CLOB</code> value.  In addition, this interface
+ * has methods for updating a <code>CLOB</code> value.
+ * <p>
+ * All methods on the <code>Clob</code> interface must be fully implemented if the
+ * JDBC driver supports the data type.
+ *
+ * <!-- start Release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * Previous to 2.0, the HSQLDB driver did not implement Clob using an SQL
+ * locator(CLOB).  That is, an HSQLDB Clob object did not contain a logical
+ * pointer to SQL CLOB data; rather it directly contained a representation of
+ * the data (a String). As a result, an HSQLDB Clob object was itself
+ * valid beyond the duration of the transaction in which is was created,
+ * although it did not necessarily represent a corresponding value
+ * on the database. Also, the interface methods for updating a CLOB value
+ * were unsupported, with the exception of the truncate method,
+ * in that it could be used to truncate the local value. <p>
+ *
+ * Starting with 2.0, the HSQLDB driver fully supports both local and remote
+ * SQL CLOB data implementations, meaning that an HSQLDB Clob object <em>may</em>
+ * contain a logical pointer to remote SQL CLOB data (see {@link JDBCClobClient
+ * JDBCClobClient}) or it may directly contain a local representation of the
+ * data (as implemented in this class).  In particular, when the product is built
+ * under JDK 1.6+ and the Clob instance is constructed as a result of calling
+ * JDBCConnection.createClob(), then the resulting Clob instance is initially
+ * disconnected (is not bound to the tranaction scope of the vending Connection
+ * object), the data is contained directly and all interface methods for
+ * updating the CLOB value are supported for local use until the first
+ * invocation of free(); otherwise, an HSQLDB Clob's implementation is
+ * determined at runtime by the driver, it is typically not valid beyond
+ * the duration of the transaction in which is was created, and there no
+ * standard way to query whether it represents a local or remote value.<p>
+ *
+ * </div>
+ * <!-- end release-specific documentation -->
+ *
+ * @author  boucherb@users
+ * @version 2.0
+ * @since JDK 1.2, HSQLDB 1.7.2
+ * @revised JDK 1.6, HSQLDB 2.0
+ */
+public class JDBCClob implements Clob {
+
+    /**
+     * Retrieves the number of characters
+     * in the <code>CLOB</code> value
+     * designated by this <code>Clob</code> object.
+     *
+     * @return length of the <code>CLOB</code> in characters
+     * @exception SQLException if there is an error accessing the
+     *            length of the <code>CLOB</code> value
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public long length() throws SQLException {
+
+        final String ldata = data;
+
+        checkValid(ldata);
+
+        return ldata.length();
+    }
+
+    /**
+     * Retrieves a copy of the specified substring
+     * in the <code>CLOB</code> value
+     * designated by this <code>Clob</code> object.
+     * The substring begins at position
+     * <code>pos</code> and has up to <code>length</code> consecutive
+     * characters.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The official specification above is ambiguous in that it does not
+     * precisely indicate the policy to be observed when
+     * pos > this.length() - length.  One policy would be to retrieve the
+     * characters from pos to this.length().  Another would be to throw
+     * an exception.  HSQLDB observes the second policy. <p>
+     *
+     * <b>Note</b><p>
+     *
+     * Depending java.lang.String implementation, the returned value
+     * may be sharing the underlying (and possibly much larger) character
+     * buffer.  This facilitates much faster operation and will save memory
+     * if many transient substrings are to be retrieved during processing, but
+     * it has memory management implications should retrieved substrings be
+     * required to survive for any non-trivial duration.  It is left up to the
+     * client to decide how to handle the trade-off (whether to make an isolated
+     * copy of the returned substring or risk that more memory remains allocated
+     * than is absolutely reuired).
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param pos the first character of the substring to be extracted.
+     *            The first character is at position 1.
+     * @param length the number of consecutive characters to be copied
+     * @return a <code>String</code> that is the specified substring in
+     *         the <code>CLOB</code> value designated by this <code>Clob</code> object
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value or if pos is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public String getSubString(long pos,
+                               final int length) throws SQLException {
+
+        final String ldata = data;
+
+        checkValid(ldata);
+
+        final int dlen = ldata.length();
+
+        if (pos < MIN_POS || pos > dlen) {
+            Util.outOfRangeArgument("pos: " + pos);
+        }
+        pos--;
+
+        if (length < 0 || length > dlen - pos) {
+            throw Util.outOfRangeArgument("length: " + length);
+        }
+
+        return (pos == 0 && length == dlen) ? ldata
+                : ldata.substring((int) pos, (int) pos + length);
+    }
+
+    /**
+     * Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
+     * object as a <code>java.io.Reader</code> object (or as a stream of
+     * characters).
+     *
+     * @return a <code>java.io.Reader</code> object containing the
+     *         <code>CLOB</code> data
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setCharacterStream
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public java.io.Reader getCharacterStream() throws SQLException {
+
+        final String ldata = data;
+
+        checkValid(ldata);
+
+        return new StringReader(ldata);
+    }
+
+    /**
+     * Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
+     * object as an ascii stream.
+     *
+     * @return a <code>java.io.InputStream</code> object containing the
+     *         <code>CLOB</code> data
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #setAsciiStream
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public java.io.InputStream getAsciiStream() throws SQLException {
+
+        checkValid(data);
+
+        try {
+            return new ByteArrayInputStream(data.getBytes("US-ASCII"));
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Retrieves the character position at which the specified substring
+     * <code>searchstr</code> appears in the SQL <code>CLOB</code> value
+     * represented by this <code>Clob</code> object.  The search
+     * begins at position <code>start</code>.
+     *
+     * @param searchstr the substring for which to search
+     * @param start the position at which to begin searching; the first position
+     *              is 1
+     * @return the position at which the substring appears or -1 if it is not
+     *         present; the first position is 1
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value or if start is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public long position(final String searchstr,
+                         long start) throws SQLException {
+
+        final String ldata = data;
+
+        checkValid(ldata);
+
+        if (start < MIN_POS) {
+            throw Util.outOfRangeArgument("start: " + start);
+        }
+
+        if (searchstr == null || start > MAX_POS) {
+            return -1;
+        }
+
+        final int pos = ldata.indexOf(searchstr, (int) --start);
+
+        return (pos < 0) ? -1
+                         : pos + 1;
+    }
+
+    /**
+     * Retrieves the character position at which the specified
+     * <code>Clob</code> object <code>searchstr</code> appears in this
+     * <code>Clob</code> object.  The search begins at position
+     * <code>start</code>.
+     *
+     * @param searchstr the <code>Clob</code> object for which to search
+     * @param start the position at which to begin searching; the first
+     *              position is 1
+     * @return the position at which the <code>Clob</code> object appears
+     *              or -1 if it is not present; the first position is 1
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value or if start is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2, HSQLDB 1.7.2
+     */
+    public long position(final Clob searchstr,
+                         long start) throws SQLException {
+
+        final String ldata = data;
+
+        checkValid(ldata);
+
+        if (start < MIN_POS) {
+            throw Util.outOfRangeArgument("start: " + start);
+        }
+
+        if (searchstr == null) {
+            return -1;
+        }
+
+        final long dlen  = ldata.length();
+        final long sslen = searchstr.length();
+
+        start--;
+
+// This is potentially much less expensive than materializing a large
+// substring from some other vendor's CLOB.  Indeed, we should probably
+// do the comparison piecewise, using an in-memory buffer (or temp-files
+// when available), if it is detected that the input CLOB is very long.
+        if (start > dlen - sslen) {
+            return -1;
+        }
+
+        // by now, we know sslen and start are both < Integer.MAX_VALUE
+        String s;
+
+        if (searchstr instanceof JDBCClob) {
+            s = ((JDBCClob) searchstr).data();
+        } else {
+            s = searchstr.getSubString(1L, (int) sslen);
+        }
+
+        final int pos = ldata.indexOf(s, (int) start);
+
+        return (pos < 0) ? -1
+                         : pos + 1;
+    }
+
+    //---------------------------- jdbc 3.0 -----------------------------------
+
+    /**
+     * Writes the given Java <code>String</code> to the <code>CLOB</code>
+     * value that this <code>Clob</code> object designates at the position
+     * <code>pos</code>. The string will overwrite the existing characters
+     * in the <code>Clob</code> object starting at the position
+     * <code>pos</code>.  If the end of the <code>Clob</code> value is reached
+     * while writing the given string, then the length of the <code>Clob</code>
+     * value will be increased to accomodate the extra characters.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>pos</code>
+     * is greater then the length+1 of the <code>CLOB</code> value then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is supported. <p>
+     *
+     * When built under JDK 1.6+ and the Clob instance is constructed as a
+     * result of calling JDBCConnection.createClob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in the
+     * database because JDBCConnection.createClob() constructs disconnected,
+     * initially empty Clob instances. To propogate the Clob value to a database
+     * in this case, it is required to supply the Clob instance to an updating
+     * or inserting setXXX method of a Prepared or Callable Statement, or to
+     * supply the Clob instance to an updateXXX method of an updateable
+     * ResultSet. <p>
+     *
+     * <b>Implementation Notes:</b><p>
+     *
+     * No attempt is made to ensure precise thread safety. Instead, volatile
+     * member field and local variable snapshot isolation semantics are
+     * implemented.  This is expected to eliminate most issues related
+     * to race conditions, with the possible exception of concurrent
+     * invocation of free(). <p>
+     *
+     * In general, however, if an application may perform concurrent
+     * JDBCClob modifications and the integrity of the application depends on
+     * total order Clob modification semantics, then such operations
+     * should be synchronized on an appropriate monitor.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param pos the position at which to start writing to the <code>CLOB</code>
+     *         value that this <code>Clob</code> object represents;
+     * The first position is 1
+     * @param str the string to be written to the <code>CLOB</code>
+     *        value that this <code>Clob</code> designates
+     * @return the number of characters written
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value or if pos is less than 1
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public int setString(long pos, String str) throws SQLException {
+
+        if (str == null) {
+            throw Util.nullArgument("str");
+        }
+
+        return setString(pos, str, 0, str.length());
+    }
+
+    /**
+     * Writes <code>len</code> characters of <code>str</code>, starting
+     * at character <code>offset</code>, to the <code>CLOB</code> value
+     * that this <code>Clob</code> represents.  The string will overwrite the existing characters
+     * in the <code>Clob</code> object starting at the position
+     * <code>pos</code>.  If the end of the <code>Clob</code> value is reached
+     * while writing the given string, then the length of the <code>Clob</code>
+     * value will be increased to accomodate the extra characters.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>pos</code>
+     * is greater then the length+1 of the <code>CLOB</code> value then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is supported. <p>
+     *
+     * When built under JDK 1.6+ and the Clob instance is constructed as a
+     * result of calling JDBCConnection.createClob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in a
+     * database because JDBCConnection.createClob() constructs disconnected,
+     * initially empty Clob instances. To propogate the Clob value to a database
+     * in this case, it is required to supply the Clob instance to an updating
+     * or inserting setXXX method of a Prepared or Callable Statement, or to
+     * supply the Clob instance to an updateXXX method of an updateable
+     * ResultSet. <p>
+     *
+     * <b>Implementation Notes:</b><p>
+     *
+     * If the value specified for <code>pos</code>
+     * is greater than the length of the <code>CLOB</code> value, then
+     * the <code>CLOB</code> value is extended in length to accept the
+     * written characters and the undefined region up to <code>pos</code> is
+     * filled with (char)0. <p>
+     *
+     * No attempt is made to ensure precise thread safety. Instead, volatile
+     * member field and local variable snapshot isolation semantics are
+     * implemented.  This is expected to eliminate most issues related
+     * to race conditions, with the possible exception of concurrent
+     * invocation of free(). <p>
+     *
+     * In general, however, if an application may perform concurrent
+     * JDBCClob modifications and the integrity of the application depends on
+     * total order Clob modification semantics, then such operations
+     * should be synchronized on an appropriate monitor.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param pos the position at which to start writing to this
+     *        <code>CLOB</code> object; The first position  is 1
+     * @param str the string to be written to the <code>CLOB</code>
+     *        value that this <code>Clob</code> object represents
+     * @param offset the offset into <code>str</code> to start reading
+     *        the characters to be written
+     * @param len the number of characters to be written
+     * @return the number of characters written
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value or if pos is less than 1
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public int setString(long pos, String str, int offset,
+                         int len) throws SQLException {
+
+        if (!this.createdByConnection) {
+
+            /** @todo - better error message */
+            throw Util.notSupported();
+        }
+
+        String ldata = this.data;
+
+        checkValid(ldata);
+
+        if (str == null) {
+            throw Util.nullArgument("str");
+        }
+
+        final int strlen = str.length();
+
+        if (offset < 0 || offset > strlen) {
+            throw Util.outOfRangeArgument("offset: " + offset);
+        }
+
+        if (len > strlen - offset) {
+            throw Util.outOfRangeArgument("len: " + len);
+        }
+
+        if (pos < MIN_POS || pos > 1L + (Integer.MAX_VALUE - len)) {
+            throw Util.outOfRangeArgument("pos: " + pos);
+        }
+
+        final int    dlen = ldata.length();
+        final int    ipos = (int) (pos - 1);
+        StringBuffer sb;
+
+        if (ipos > dlen - len) {
+            sb = new StringBuffer(ipos + len);
+
+            sb.append(ldata.substring(0, ipos));
+
+            ldata = null;
+
+            sb.append(str.substring(offset, offset + len));
+
+            str = null;
+        } else {
+            sb    = new StringBuffer(ldata);
+            ldata = null;
+
+            for (int i = ipos, j = 0; j < len; i++, j++) {
+                sb.setCharAt(i, str.charAt(offset + j));
+            }
+            str = null;
+        }
+
+        // paranoia, in case somone free'd us during the copies.
+        checkValid(this.data);
+
+        this.data = sb.toString();
+
+        return len;
+    }
+
+    /**
+     * Retrieves a stream to be used to write Ascii characters to the
+     * <code>CLOB</code> value that this <code>Clob</code> object represents,
+     * starting at position <code>pos</code>.  Characters written to the stream
+     * will overwrite the existing characters
+     * in the <code>Clob</code> object starting at the position
+     * <code>pos</code>.  If the end of the <code>Clob</code> value is reached
+     * while writing characters to the stream, then the length of the <code>Clob</code>
+     * value will be increased to accomodate the extra characters.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>pos</code>
+     * is greater than the length of the <code>CLOB</code> value, then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is supported. <p>
+     *
+     * When built under JDK 1.6+ and the Clob instance is constructed as a
+     * result of calling JDBCConnection.createClob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in a
+     * database because JDBCConnection.createClob() constructs disconnected,
+     * initially empty Clob instances. To propogate the Clob value to a database
+     * in this case, it is required to supply the Clob instance to an updating
+     * or inserting setXXX method of a Prepared or Callable Statement, or to
+     * supply the Clob instance to an updateXXX method of an updateable
+     * ResultSet. <p>
+     *
+     * <b>Implementation Notes:</b><p>
+     *
+     * The data written to the stream does not appear in this
+     * Clob until the stream is closed. <p>
+     *
+     * When the stream is closed, if the value specified for <code>pos</code>
+     * is greater than the length of the <code>CLOB</code> value, then
+     * the <code>CLOB</code> value is extended in length to accept the
+     * written characters and the undefined region up to <code>pos</code> is
+     * filled with (char)0. <p>
+     *
+     * Also, no attempt is made to ensure precise thread safety. Instead,
+     * volatile member field and local variable snapshot isolation semantics
+     * are implemented.  This is expected to eliminate most issues related
+     * to race conditions, with the possible exception of concurrent
+     * invocation of free(). <p>
+     *
+     * In general, however, if an application may perform concurrent
+     * JDBCClob modifications and the integrity of the application depends on
+     * total order Clob modification semantics, then such operations
+     * should be synchronized on an appropriate monitor.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param pos the position at which to start writing to this
+     *        <code>CLOB</code> object; The first position is 1
+     * @return the stream to which ASCII encoded characters can be written
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value or if pos is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getAsciiStream
+     *
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public java.io.OutputStream setAsciiStream(
+            final long pos) throws SQLException {
+
+        if (!this.createdByConnection) {
+
+            /** @todo - Better error message */
+            throw Util.notSupported();
+        }
+        checkValid(this.data);
+
+        if (pos < MIN_POS || pos > MAX_POS) {
+            throw Util.outOfRangeArgument("pos: " + pos);
+        }
+
+        return new java.io.ByteArrayOutputStream() {
+
+            public synchronized void close() throws java.io.IOException {
+
+                try {
+                    JDBCClob.this.setString(pos,
+                            new String(toByteArray(), "US-ASCII"));
+                } catch (SQLException se) {
+                    throw JavaSystem.toIOException(se);
+                } finally {
+                    super.close();
+                }
+            }
+        };
+    }
+
+    /**
+     * Retrieves a stream to be used to write a stream of Unicode characters
+     * to the <code>CLOB</code> value that this <code>Clob</code> object
+     * represents, at position <code>pos</code>. Characters written to the stream
+     * will overwrite the existing characters
+     * in the <code>Clob</code> object starting at the position
+     * <code>pos</code>.  If the end of the <code>Clob</code> value is reached
+     * while writing characters to the stream, then the length of the <code>Clob</code>
+     * value will be increased to accomodate the extra characters.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>pos</code>
+     * is greater then the length+1 of the <code>CLOB</code> value then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is supported. <p>
+     *
+     * When built under JDK 1.6+ and the Clob instance is constructed as a
+     * result of calling JDBCConnection.createClob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in a
+     * database because JDBCConnection.createClob() constructs disconnected,
+     * initially empty Clob instances. To propogate the Clob value to a database
+     * in this case, it is required to supply the Clob instance to an updating
+     * or inserting setXXX method of a Prepared or Callable Statement, or to
+     * supply the Clob instance to an updateXXX method of an updateable
+     * ResultSet. <p>
+     *
+     * <b>Implementation Notes:</b><p>
+     *
+     * The data written to the stream does not appear in this
+     * Clob until the stream is closed. <p>
+     *
+     * When the stream is closed, if the value specified for <code>pos</code>
+     * is greater than the length of the <code>CLOB</code> value, then
+     * the <code>CLOB</code> value is extended in length to accept the
+     * written characters and the undefined region up to <code>pos</code> is
+     * filled with (char)0. <p>
+     *
+     * Also, no attempt is made to ensure precise thread safety. Instead,
+     * volatile member field and local variable snapshot isolation semantics
+     * are implemented.  This is expected to eliminate most issues related
+     * to race conditions, with the possible exception of concurrent
+     * invocation of free(). <p>
+     *
+     * In general, however, if an application may perform concurrent
+     * JDBCClob modifications and the integrity of the application depends on
+     * total order Clob modification semantics, then such operations
+     * should be synchronized on an appropriate monitor.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param  pos the position at which to start writing to the
+     *        <code>CLOB</code> value; The first position is 1
+     *
+     * @return a stream to which Unicode encoded characters can be written
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value or if pos is less than 1
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see #getCharacterStream
+     *
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public java.io.Writer setCharacterStream(
+            final long pos) throws SQLException {
+
+        if (!this.createdByConnection) {
+
+            /** @todo - better error message */
+            throw Util.notSupported();
+        }
+        checkValid(this.data);
+
+        if (pos < MIN_POS || pos > MAX_POS) {
+            throw Util.outOfRangeArgument("pos: " + pos);
+        }
+
+        return new java.io.StringWriter() {
+
+            public synchronized void close() throws java.io.IOException {
+
+                try {
+                    JDBCClob.this.setString(pos, toString());
+                } catch (SQLException se) {
+                    throw JavaSystem.toIOException(se);
+                } finally {
+                    super.close();
+                }
+            }
+        };
+    }
+
+    /**
+     * Truncates the <code>CLOB</code> value that this <code>Clob</code>
+     * designates to have a length of <code>len</code>
+     * characters.
+     * <p>
+     * <b>Note:</b> If the value specified for <code>len</code>
+     * is greater than the length of the <code>CLOB</code> value, then the
+     * behavior is undefined. Some JDBC drivers may throw a
+     * <code>SQLException</code> while other drivers may support this
+     * operation.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 2.0 this feature is fully supported. <p>
+     *
+     * When built under JDK 1.6+ and the Clob instance is constructed as a
+     * result of calling JDBCConnection.createClob(), this operation affects
+     * only the client-side value; it has no effect upon a value stored in a
+     * database because JDBCConnection.createClob() constructs disconnected,
+     * initially empty Blob instances. To propogate the truncated clob value to
+     * a database in this case, it is required to supply the Clob instance to
+     * an updating or inserting setXXX method of a Prepared or Callable
+     * Statement, or to supply the Blob instance to an updateXXX method of an
+     * updateable ResultSet. <p>
+     *
+     * <b>Implementation Notes:</b> <p>
+     *
+     * HSQLDB throws an SQLException if the specified <tt>len</tt> is greater
+     * than the value returned by {@link #length() length}. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param len the length, in characters, to which the <code>CLOB</code> value
+     *        should be truncated
+     * @exception SQLException if there is an error accessing the
+     *            <code>CLOB</code> value or if len is less than 0
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @revised JDK 1.6, HSQLDB 2.0
+     */
+    public void truncate(final long len) throws SQLException {
+
+        final String ldata = this.data;
+
+        this.checkValid(ldata);
+
+        final long dlen = ldata.length();
+
+        if (len == dlen) {
+
+            // nothing has changed, so there's nothing to be done
+        } else if (len < 0 || len > dlen) {
+            throw Util.outOfRangeArgument("len: " + len);
+        } else {
+
+            // no need to get rid of slack
+            data = ldata.substring(0, (int) len);
+        }
+    }
+
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * This method frees the <code>Clob</code> object and releases the resources the resources
+     * that it holds.  The object is invalid once the <code>free</code> method
+     * is called.
+     * <p>
+     * After <code>free</code> has been called, any attempt to invoke a
+     * method other than <code>free</code> will result in a <code>SQLException</code>
+     * being thrown.  If <code>free</code> is called multiple times, the subsequent
+     * calls to <code>free</code> are treated as a no-op.
+     * <p>
+     * @throws SQLException if an error occurs releasing
+     * the Clob's resources
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public void free() throws SQLException {
+        this.data = null;
+    }
+
+    /**
+     * Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
+     * with the character specified by pos, which is length characters in length.
+     *
+     * @param pos the offset to the first character of the partial value to
+     * be retrieved.  The first character in the Clob is at position 1.
+     * @param length the length in characters of the partial value to be retrieved.
+     * @return <code>Reader</code> through which the partial <code>Clob</code> value can be read.
+     * @throws SQLException if pos is less than 1 or if pos is greater than the number of
+     * characters in the <code>Clob</code> or if pos + length is greater than the number of
+     * characters in the <code>Clob</code>
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public Reader getCharacterStream(long pos,
+                                     long length) throws SQLException {
+
+        if (length > Integer.MAX_VALUE) {
+            throw Util.outOfRangeArgument("length: " + length);
+        }
+
+        return new StringReader(getSubString(pos, (int) length));
+    }
+
+    // ---------------------- internal implementation --------------------------
+    private static final long MIN_POS = 1L;
+    private static final long MAX_POS = 1L + (long) Integer.MAX_VALUE;
+    private volatile String   data;
+    private final boolean     createdByConnection;
+
+    /**
+     * Constructs a new JDBCClob object wrapping the given character
+     * sequence. <p>
+     *
+     * This constructor is used internally to retrieve result set values as
+     * Clob objects, yet it must be public to allow access from other packages.
+     * As such (in the interest of efficiency) this object maintains a reference
+     * to the given String object rather than making a copy and so it is
+     * gently suggested (in the interest of effective memory management) that
+     * extenal clients using this constructor either take pause to consider
+     * the implications or at least take care to provide a String object whose
+     * internal character buffer is not much larger than required to represent
+     * the value.
+     *
+     * @param data the character sequence representing the Clob value
+     * @throws SQLException if the argument is null
+     */
+    public JDBCClob(final String data) throws SQLException {
+
+        this.init(data);
+
+        this.createdByConnection = false;
+    }
+
+    protected JDBCClob() {
+        this.data                = "";
+        this.createdByConnection = true;
+    }
+
+    protected void init(String data) throws SQLException {
+
+        if (data == null) {
+            throw Util.nullArgument("data");
+        }
+        this.data = data;
+    }
+
+    protected void checkValid(final Object data) {
+
+        if (data == null) {
+            throw new RuntimeException("null data");
+        }
+    }
+
+    protected String data() throws SQLException {
+
+        final String ldata = data;
+
+        checkValid(ldata);
+
+        return ldata;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCClobClient.java b/src/org/hsqldb/jdbc/JDBCClobClient.java
new file mode 100644
index 0000000..a8da275
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCClobClient.java
@@ -0,0 +1,347 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.types.ClobDataID;
+
+/**
+ * A wrapper for HSQLDB ClobData objects.
+ *
+ * Instances of this class are returnd by calls to ResultSet methods.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @since 1.9.0
+ */
+
+public class JDBCClobClient implements Clob {
+
+    /**
+     * Retrieves the <code>CLOB</code> value designated by this
+     * <code>Clob</code> object as an ascii stream.
+     *
+     * @return a <code>java.io.InputStream</code> object containing the
+     *   <code>CLOB</code> data
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized InputStream getAsciiStream() throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * Retrieves the <code>CLOB</code> value designated by this
+     * <code>Clob</code> object as a <code>java.io.Reader</code> object (or
+     * as a stream of characters).
+     *
+     * @return a <code>java.io.Reader</code> object containing the
+     *   <code>CLOB</code> data
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized Reader getCharacterStream() throws SQLException {
+        return new ClobInputStream(this, 0, length(),
+                                   session.getStreamBlockSize());
+    }
+
+    /**
+     * Retrieves a copy of the specified substring in the <code>CLOB</code>
+     * value designated by this <code>Clob</code> object.
+     *
+     * @param pos the first character of the substring to be extracted. The
+     *   first character is at position 1.
+     * @param length the number of consecutive characters to be copied
+     * @return a <code>String</code> that is the specified substring in the
+     *   <code>CLOB</code> value designated by this <code>Clob</code> object
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized String getSubString(long pos,
+            int length) throws SQLException {
+
+        if (!isInLimits(Long.MAX_VALUE, pos - 1, length)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        try {
+            return clob.getSubString(session, pos - 1, length);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Retrieves the number of characters in the <code>CLOB</code> value
+     * designated by this <code>Clob</code> object.
+     *
+     * @return length of the <code>CLOB</code> in characters
+     * @throws SQLException if there is an error accessing the length of the
+     *   <code>CLOB</code> value
+     */
+    public synchronized long length() throws SQLException {
+
+        try {
+            return clob.length(session);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Retrieves the character position at which the specified substring
+     * <code>searchstr</code> appears in the SQL <code>CLOB</code> value
+     * represented by this <code>Clob</code> object.
+     *
+     * @param searchstr the substring for which to search
+     * @param start the position at which to begin searching; the first
+     *   position is 1
+     * @return the position at which the substring appears or -1 if it is
+     *   not present; the first position is 1
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized long position(String searchstr,
+                                      long start) throws SQLException {
+
+        if (!isInLimits(Long.MAX_VALUE, start - 1, 0)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        try {
+            return clob.position(session, searchstr, start - 1);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Retrieves the character position at which the specified
+     * <code>Clob</code> object <code>searchstr</code> appears in this
+     * <code>Clob</code> object.
+     *
+     * @param searchstr the <code>Clob</code> object for which to search
+     * @param start the position at which to begin searching; the first
+     *   position is 1
+     * @return the position at which the <code>Clob</code> object appears or
+     *   -1 if it is not present; the first position is 1
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized long position(Clob searchstr,
+                                      long start) throws SQLException {
+        return position(searchstr.getSubString(0, (int) searchstr.length()),
+                        start);
+    }
+
+    /**
+     * Retrieves a stream to be used to write Ascii characters to the
+     * <code>CLOB</code> value that this <code>Clob</code> object represents,
+     * starting at position <code>pos</code>.
+     *
+     * @param pos the position at which to start writing to this
+     *   <code>CLOB</code> object
+     * @return the stream to which ASCII encoded characters can be written
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized OutputStream setAsciiStream(long pos)
+    throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * Retrieves a stream to be used to write a stream of Unicode characters
+     * to the <code>CLOB</code> value that this <code>Clob</code> object
+     * represents, at position <code>pos</code>.
+     *
+     * @param pos the position at which to start writing to the
+     *   <code>CLOB</code> value
+     * @return a stream to which Unicode encoded characters can be written
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized Writer setCharacterStream(long pos)
+    throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * Writes the given Java <code>String</code> to the <code>CLOB</code>
+     * value that this <code>Clob</code> object designates at the position
+     * <code>pos</code>.
+     *
+     * @param pos the position at which to start writing to the
+     *   <code>CLOB</code> value that this <code>Clob</code> object
+     *   represents
+     * @param str the string to be written to the <code>CLOB</code> value
+     *   that this <code>Clob</code> designates
+     * @return the number of characters written
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized int setString(long pos,
+                                      String str) throws SQLException {
+        return setString(pos, str, 0, str.length());
+    }
+
+    /**
+     * Writes <code>len</code> characters of <code>str</code>, starting at
+     * character <code>offset</code>, to the <code>CLOB</code> value that
+     * this <code>Clob</code> represents.
+     *
+     * @param pos the position at which to start writing to this
+     *   <code>CLOB</code> object
+     * @param str the string to be written to the <code>CLOB</code> value
+     *   that this <code>Clob</code> object represents
+     * @param offset the offset into <code>str</code> to start reading the
+     *   characters to be written
+     * @param len the number of characters to be written
+     * @return the number of characters written
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized int setString(long pos, String str, int offset,
+                                      int len) throws SQLException {
+
+        throw Util.notSupported();
+/*
+        if (!isInLimits(Long.MAX_VALUE, pos - 1, len)) {
+            throw Util.outOfRangeArgument();
+        }
+
+        try {
+            return clob.setString(session, pos - 1, str, offset, len);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+*/
+    }
+
+    /**
+     * Truncates the <code>CLOB</code> value that this <code>Clob</code>
+     * designates to have a length of <code>len</code> characters.
+     *
+     * @param len the length, in bytes, to which the <code>CLOB</code> value
+     *   should be truncated
+     * @throws SQLException if there is an error accessing the
+     *   <code>CLOB</code> value
+     */
+    public synchronized void truncate(long len) throws SQLException {
+
+        try {
+            clob.truncate(session, len);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * This method frees the <code>Clob</code> object and releases the resources the resources
+     * that it holds.  The object is invalid once the <code>free</code> method
+     * is called.
+     * <p>
+     * After <code>free</code> has been called, any attempt to invoke a
+     * method other than <code>free</code> will result in a <code>SQLException</code>
+     * being thrown.  If <code>free</code> is called multiple times, the subsequent
+     * calls to <code>free</code> are treated as a no-op.
+     * <p>
+     * @throws SQLException if an error occurs releasing
+     * the Clob's resources
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized void free() throws SQLException {
+        isClosed = true;
+    }
+
+    /**
+     * Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
+     * with the character specified by pos, which is length characters in length.
+     *
+     * @param pos the offset to the first character of the partial value to
+     * be retrieved.  The first character in the Clob is at position 1.
+     * @param length the length in characters of the partial value to be retrieved.
+     * @return <code>Reader</code> through which the partial <code>Clob</code> value can be read.
+     * @throws SQLException if pos is less than 1 or if pos is greater than the number of
+     * characters in the <code>Clob</code> or if pos + length is greater than the number of
+     * characters in the <code>Clob</code>
+     *
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized Reader getCharacterStream(long pos,
+            long length) throws SQLException {
+        return new ClobInputStream(this, pos - 1, length,
+                                   session.getStreamBlockSize());
+    }
+
+    char[] getChars(long position, int length) throws SQLException {
+
+        try {
+            return clob.getChars(session, position - 1, length);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    //
+    ClobDataID       clob;
+    SessionInterface session;
+    boolean          isClosed;
+
+    JDBCClobClient(SessionInterface session, ClobDataID clob) {
+        this.session = session;
+        this.clob    = clob;
+    }
+
+    public synchronized boolean isClosed() {
+        return isClosed;
+    }
+
+    static boolean isInLimits(long fullLength, long pos, long len) {
+        return pos >= 0 && len >= 0 && pos + len <= fullLength;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCColumnMetaData.java b/src/org/hsqldb/jdbc/JDBCColumnMetaData.java
new file mode 100644
index 0000000..0eece0a
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCColumnMetaData.java
@@ -0,0 +1,161 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.lang.reflect.Field;
+
+// fredt@users - 1.9.0 rewritten as simple structure derived from JDBCResultSetMetaData
+
+/**
+ * Provides a site for holding the ResultSetMetaData for individual ResultSet
+ * columns. In 2.0 it is implemented as a simple data structure derived
+ * from calls to JDBCResultSetMetaData methods.
+ * purposes.<p>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @since HSQLDB 1.7.2
+ */
+public final class JDBCColumnMetaData {
+
+    /** The column's table's catalog name. */
+    public String catalogName;
+
+    /**
+     * The fully-qualified name of the Java class whose instances are
+     * manufactured if the method ResultSet.getObject is called to retrieve
+     * a value from the column.
+     */
+    public String columnClassName;
+
+    /** The column's normal max width in chars. */
+    public int columnDisplaySize;
+
+    /** The suggested column title for use in printouts and displays. */
+    public String columnLabel;
+
+    /** The column's name. */
+    public String columnName;
+
+    /** The column's SQL type. */
+    public int columnType;
+
+    /** The column's value's number of decimal digits. */
+    public int precision;
+
+    /** The column's value's number of digits to right of the decimal point. */
+    public int scale;
+
+    /** The column's table's schema. */
+    public String schemaName;
+
+    /** The column's table's name. */
+    public String tableName;
+
+    /** Whether the value of the column are automatically numbered. */
+    public boolean isAutoIncrement;
+
+    /** Whether the column's value's case matters. */
+    public boolean isCaseSensitive;
+
+    /** Whether the values in the column are cash values. */
+    public boolean isCurrency;
+
+    /** Whether a write on the column will definitely succeed. */
+    public boolean isDefinitelyWritable;
+
+    /** The nullability of values in the column. */
+    public int isNullable;
+
+    /** Whether the column's values are definitely not writable. */
+    public boolean isReadOnly;
+
+    /** Whether the column's values can be used in a where clause. */
+    public boolean isSearchable;
+
+    /** Whether values in the column are signed numbers. */
+    public boolean isSigned;
+
+    /** Whether it is possible for a write on the column to succeed. */
+    public boolean isWritable;
+
+    /**
+     * Retrieves a String representation of this object.
+     *
+     * @return a Sring representation of this object
+     */
+    public String toString() {
+
+        try {
+            return toStringImpl();
+        } catch (Exception e) {
+            return super.toString() + "[" + e + "]";
+        }
+    }
+
+    /**
+     * Provides the implementation of the toString() method.
+     *
+     * @return a Sring representation of this object
+     */
+    private String toStringImpl() throws Exception {
+
+        StringBuffer sb;
+        Field[]      fields;
+        Field        field;
+
+        sb = new StringBuffer();
+
+        sb.append('[');
+
+        fields = getClass().getFields();
+
+        int len = fields.length;
+
+        for (int i = 0; i < len; i++) {
+            field = fields[i];
+
+            sb.append(field.getName());
+            sb.append('=');
+            sb.append(field.get(this));
+
+            if (i + 1 < len) {
+                sb.append(',');
+                sb.append(' ');
+            }
+        }
+        sb.append(']');
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCConnection.java b/src/org/hsqldb/jdbc/JDBCConnection.java
new file mode 100644
index 0000000..35e7389
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCConnection.java
@@ -0,0 +1,3457 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.Calendar;
+import java.util.Map;
+
+//#ifdef JAVA4
+import java.sql.Savepoint;
+
+//#endif JAVA4
+//#ifdef JAVA6
+import java.sql.Array;
+import java.sql.SQLClientInfoException;
+import java.sql.NClob;
+import java.sql.SQLXML;
+import java.sql.Struct;
+import java.util.Properties;
+
+//#endif JAVA6
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.ClientConnection;
+import org.hsqldb.ClientConnectionHTTP;
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.HsqlException;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.types.Type;
+
+import java.sql.SQLData;
+import java.sql.SQLOutput;
+import java.sql.SQLInput;
+
+/* $Id: JDBCConnection.java 3596 2010-05-30 13:06:33Z fredt $ */
+
+// fredt@users    20020320 - patch 1.7.0 - JDBC 2 support and error trapping
+//
+// JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
+//
+// boucherb@users 20020509 - added "throws SQLException" to all methods where
+//                           it was missing here but specified in the
+//                           java.sql.Connection interface,
+//                           updated generic documentation to JDK 1.4, and
+//                           added JDBC3 methods and docs
+// boucherb &
+// fredt@users    20020505 - extensive review and update of docs and behaviour
+//                           to comply with java.sql specification
+// fredt@users    20020830 - patch 487323 by xclayl@users - better synchronization
+// fredt@users    20020930 - patch 1.7.1 - support for connection properties
+// kneedeepincode@users
+//                20021110 - patch 635816 - correction to properties
+// unsaved@users  20021113 - patch 1.7.2 - SSL support
+// boucherb@users 2003 ??? - patch 1.7.2 - SSL support moved to factory interface
+// fredt@users    20030620 - patch 1.7.2 - reworked to use a SessionInterface
+// boucherb@users 20030801 - JavaDoc updates to reflect new connection urls
+// boucherb@users 20030819 - patch 1.7.2 - partial fix for broken nativeSQL method
+// boucherb@users 20030819 - patch 1.7.2 - SQLWarning cases implemented
+// boucherb@users 20051207 - 1.9.0       - JDBC 4.0 support - docs and methods
+//              - 20060712               - full synch up to Mustang Build 90
+// fredt@users    20090810 - 1.9.0       - full review and updates
+//
+// Revision 1.23  2006/07/12 12:02:43 boucherb
+// patch 1.9.0
+// - full synch up to Mustang b90
+
+/**
+ * <!-- start generic documentation -->
+ *
+ * <P>A connection (session) with a specific
+ * database. SQL statements are executed and results are returned
+ * within the context of a connection.
+ * <P>
+ * A <code>Connection</code> object's database is able to provide information
+ * describing its tables, its supported SQL grammar, its stored
+ * procedures, the capabilities of this connection, and so on. This
+ * information is obtained with the <code>getMetaData</code> method.
+ *
+ * <P>(JDBC4 clarification:)
+ * <P><B>Note:</B> When configuring a <code>Connection</code>, JDBC applications
+ *  should use the appropritate <code>Connection</code> method such as
+ *  <code>setAutoCommit</code> or <code>setTransactionIsolation</code>.
+ *  Applications should not invoke SQL commands directly to change the connection's
+ *   configuration when there is a JDBC method available.  By default a <code>Connection</code> object is in
+ * auto-commit mode, which means that it automatically commits changes
+ * after executing each statement. If auto-commit mode has been
+ * disabled, the method <code>commit</code> must be called explicitly in
+ * order to commit changes; otherwise, database changes will not be saved.
+ * <P>
+ * A new <code>Connection</code> object created using the JDBC 2.1 core API
+ * has an initially empty type map associated with it. A user may enter a
+ * custom mapping for a UDT in this type map.
+ * When a UDT is retrieved from a data source with the
+ * method <code>ResultSet.getObject</code>, the <code>getObject</code> method
+ * will check the connection's type map to see if there is an entry for that
+ * UDT.  If so, the <code>getObject</code> method will map the UDT to the
+ * class indicated.  If there is no entry, the UDT will be mapped using the
+ * standard mapping.
+ * <p>
+ * A user may create a new type map, which is a <code>java.util.Map</code>
+ * object, make an entry in it, and pass it to the <code>java.sql</code>
+ * methods that can perform custom mapping.  In this case, the method
+ * will use the given type map instead of the one associated with
+ * the connection.
+ * <p>
+ * For example, the following code fragment specifies that the SQL
+ * type <code>ATHLETES</code> will be mapped to the class
+ * <code>Athletes</code> in the Java programming language.
+ * The code fragment retrieves the type map for the <code>Connection
+ * </code> object <code>con</code>, inserts the entry into it, and then sets
+ * the type map with the new entry as the connection's type map.
+ * <pre>
+ *      java.util.Map map = con.getTypeMap();
+ *      map.put("mySchemaName.ATHLETES", Class.forName("Athletes"));
+ *      con.setTypeMap(map);
+ * </pre>
+ *
+ * <!-- end generic documentation -->
+ *
+ * <!-- start release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * To get a <code>Connection</code> to an HSQLDB database, the
+ * following code may be used (updated to reflect the most recent
+ * recommendations): <p>
+ *
+ * <hr>
+ *
+ * When using HSQLDB, the database connection <b>&lt;url&gt;</b> must start with
+ * <b>'jdbc:hsqldb:'</b><p>
+ *
+ * Since 1.7.2, connection properties (&lt;key-value-pairs&gt;) may be appended
+ * to the database connection <b>&lt;url&gt;</b>, using the form: <p>
+ *
+ * <blockquote>
+ *      <b>'&lt;url&gt;[;key=value]*'</b>
+ * </blockquote> <p>
+ *
+ * Also since 1.7.2, the allowable forms of the HSQLDB database connection
+ * <b>&lt;url&gt;</b> have been extended.  However, all legacy forms continue
+ * to work, with unchanged semantics.  The extensions are as described in the
+ * following material. <p>
+ *
+ * <hr>
+ *
+ * <b>Network Server Database Connections:</b> <p>
+ *
+ * The {@link org.hsqldb.server.Server Server} database connection <b>&lt;url&gt;</b>
+ * takes one of the two following forms: <p>
+ *
+ * <div class="GeneralExample">
+ * <ol>
+ * <li> <b>'jdbc:hsqldb:hsql://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
+ *
+ * <li> <b>'jdbc:hsqldb:hsqls://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
+ *         (with TLS).
+ * </ol>
+ * </div> <p>
+ *
+ * The {@link org.hsqldb.server.WebServer WebServer} database connection <b>&lt;url&gt;</b>
+ * takes one of two following forms: <p>
+ *
+ * <div class="GeneralExample">
+ * <ol>
+ * <li> <b>'jdbc:hsqldb:http://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
+ *
+ * <li> <b>'jdbc:hsqldb:https://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
+ *      (with TLS).
+ * </ol>
+ * </div><p>
+ *
+ * In both network server database connection <b>&lt;url&gt;</b> forms, the
+ * optional <b>&lt;alias&gt;</b> component is used to identify one of possibly
+ * several database instances available at the indicated host and port.  If the
+ * <b>&lt;alias&gt;</b> component is omitted, then a connection is made to the
+ * network server's default database instance, if such an instance is
+ * available. <p>
+ *
+ * For more information on server configuration regarding mounting multiple
+ * databases and assigning them <b>&lt;alias&gt;</b> values, please read the
+ * Java API documentation for {@link org.hsqldb.server.Server Server} and related
+ * chapters in the general documentation, especially the <em>Advanced Users
+ * Guide</em>. <p>
+ *
+ * <hr>
+ *
+ * <b>Transient, In-Process Database Connections:</b> <p>
+ *
+ * The 100% in-memory (transient, in-process) database connection
+ * <b>&lt;url&gt;</b> takes one of the two following forms: <p>
+ *
+ * <div class="GeneralExample">
+ * <ol>
+ * <li> <b>'jdbc:hsqldb:.[&lt;key-value-pairs&gt;]'</b>
+ *     (the legacy form, extended)
+ *
+ * <li> <b>'jdbc:hsqldb:mem:&lt;alias&gt;[&lt;key-value-pairs&gt;]'</b>
+ *      (the new form)
+ * </ol>
+ * </div> <p>
+ *
+ * The driver converts the supplied <b>&lt;alias&gt;</b> component to
+ * Local.ENGLISH lower case and uses the resulting character sequence as the
+ * key used to look up a <b>mem:</b> protocol database instance amongst the
+ * collection of all such instances already in existence within the current
+ * class loading context in the current JVM. If no such instance exists, one
+ * <em>may</em> be automatically created and mapped to the <b>&lt;alias&gt;</b>,
+ * as governed by the <b>'ifexists=true|false'</b> connection property. <p>
+ *
+ * The rationale for converting the supplied <b>&lt;alias&gt;</b> component to
+ * lower case is to provide consistency with the behavior of <b>res:</b>
+ * protocol database connection <b>&lt;url&gt;</b>s, explained further on in
+ * this overview.
+ *
+ * <hr>
+ *
+ * <b>Persistent, In-Process Database Connections:</b> <p>
+ *
+ * The standalone (persistent, in-process) database connection
+ * <b>&lt;url&gt;</b> takes one of the three following forms: <p>
+ *
+ * <div class="GeneralExample">
+ * <ol>
+ * <li> <b>'jdbc:hsqldb:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
+ *      (the legacy form, extended)
+ *
+ * <li> <b>'jdbc:hsqldb:file:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
+ *      (same semantics as the legacy form)
+ *
+ * <li> <b>'jdbc:hsqldb:res:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
+ *      (new form with 'files_in_jar' semantics)
+ * </ol>
+ * </div> <p>
+ *
+ * For the persistent, in-process database connection <b>&lt;url&gt;</b>,
+ * the <b>&lt;path&gt;</b> component is the path prefix common to all of
+ * the files that compose the database. <p>
+ *
+ * From 1.7.2, although other files may be involved (such as transient working
+ * files and/or TEXT table CSV data source files), the essential set that may,
+ * at any particular point in time, compose an HSQLDB database is: <p>
+ *
+ * <div class="GeneralExample">
+ * <ul>
+ * <li>&lt;path&gt;.properties
+ * <li>&lt;path&gt;.script
+ * <li>&lt;path&gt;.log
+ * <li>&lt;path&gt;.data
+ * <li>&lt;path&gt;.backup
+ * <li>&lt;path&gt;.lck
+ * </ul>
+ * </div> <p>
+ *
+ * For example: <b>'jdbc:hsqldb:file:test'</b> connects to a database
+ * composed of some subset of the files listed above, where the expansion
+ * of <b>&lt;path&gt;</b> is <b>'test'</b> prefixed with the canonical path of
+ * the JVM's effective working directory at the time the designated database
+ * is first opened in-process. <p>
+ *
+ * Be careful to note that this canonical expansion of <b>&lt;path&gt;</b> is
+ * cached by the driver until JVM exit. So, although legacy JVMs tend to fix
+ * the reported effective working directory at the one noted upon JVM startup,
+ * there is no guarantee that modern JVMs will continue to uphold this
+ * behaviour.  What this means is there is effectively no guarantee into the
+ * future that a relative <b>file:</b> protocol database connection
+ * <b>&lt;url&gt;</b> will connect to the same database instance for the life
+ * of the JVM.  To avoid any future ambigutity issues, it is probably a best
+ * practice for clients to attempt to pre-canonicalize the <b>&lt;path&gt;</b>
+ * component of <b>file:</b> protocol database connection* <b>&lt;url&gt;</b>s.
+ * <p>
+ *
+ * Under <em>Windows</em> <sup><font size="-2">TM</font> </sup>, <b>
+ * 'jdbc:hsqldb:file:c:\databases\test'</b> connects to a database located
+ * on drive <b>'C:'</b> in the directory <b>'databases'</b>, composed
+ * of some subset of the files: <p>
+ *
+ * <pre class="GeneralExample">
+ * C:\
+ * +--databases\
+ *    +--test.properties
+ *    +--test.script
+ *    +--test.log
+ *    +--test.data
+ *    +--test.backup
+ *    +--test.lck
+ * </pre>
+ *
+ * Under most variations of UNIX, <b>'jdbc:hsqldb:file:/databases/test'</b>
+ * connects to a database located in the directory <b>'databases'</b> directly
+ * under root, once again composed of some subset of the files: <p>
+ *
+ * <pre class="GeneralExample">
+ *
+ * +--databases
+ *    +--test.properties
+ *    +--test.script
+ *    +--test.log
+ *    +--test.data
+ *    +--test.backup
+ *    +--test.lck
+ * </pre>
+ *
+ * <b>Some Guidelines:</b> <p>
+ *
+ * <ol>
+ * <li> Both relative and absolute database file paths are supported. <p>
+ *
+ * <li> Relative database file paths can be specified in a platform independent
+ *      manner as: <b>'[dir1/dir2/.../dirn/]&lt;file-name-prefix&gt;'</b>. <p>
+ *
+ * <li> Specification of absolute file paths is operating-system specific.<br>
+ *      Please read your OS file system documentation. <p>
+ *
+ * <li> Specification of network mounts may be operating-system specific.<br>
+ *      Please read your OS file system documentation. <p>
+ *
+ * <li> Special care may be needed w.r.t. file path specifications
+ *      containing whitespace, mixed-case, special characters and/or
+ *      reserved file names.<br>
+ *      Please read your OS file system documentation. <p>
+ * </ol> <p>
+ *
+ * <b>Note:</b> Versions of HSQLDB previous to 1.7.0 did not support creating
+ * directories along the file path specified in the persistent, in-process mode
+ * database connection <b>&lt;url&gt;</b> form, in the case that they did
+ * not already exist.  Starting with HSQLDB 1.7.0, directories <i>will</i>
+ * be created if they do not already exist., but only if HSQLDB is built under
+ * a version of the compiler greater than JDK 1.1.x. <p>
+ *
+ * <hr>
+ *
+ * <b>res: protocol Connections:</b><p>
+ *
+ * The <b>'jdbc:hsqldb:res:&lt;path&gt;'</b> database connection
+ * <b>&lt;url&gt;</b> has different semantics than the
+ * <b>'jdbc:hsqldb:file:&lt;path&gt;'</b> form. The semantics are similar to
+ * those of a <b>'files_readonly'</b> database, but with some additional
+ * points to consider. <p>
+ *
+ * Specifically, the <b>'&lt;path&gt;'</b> component of a <b>res:</b> protocol
+ * database connection <b>&lt;url&gt;</b> is first converted to lower case
+ * with <tt>Locale.ENGLISH</tt> and only then used to obtain resource URL
+ * objects, which in turn are used to read the database files as resources on
+ * the class path. <p>
+ *
+ * Due to lower case conversion by the driver, <b>res:</b> <b>'&lt;path&gt;'</b>
+ * components <em>never</em> find jar resources stored with
+ * <tt>Locale.ENGLISH</tt> mixed case paths. The rationale for converting to
+ * lower case is that not all pkzip implementations guarantee path case is
+ * preserved when archiving resources, and conversion to lower case seems to
+ * be the most common occurrence (although there is also no actual guarantee
+ * that the conversion is <tt>Locale.ENGLISH</tt>).<p>
+ *
+ * More importantly, <b>res:</b> <b>'&lt;path&gt;'</b> components <em>must</em>
+ * point only to resources contained in one or more jars on the class
+ * path. That is, only resources having the jar sub-protocol are considered
+ * valid. <p>
+ *
+ * This restriction is enforced to avoid the unfortunate situation in which,
+ * because <b>res:</b> database instances do not create a <b>&lt;path&gt;</b>.lck
+ * file (they are strictly files-read-only) and because the <b>&lt;path&gt;</b>
+ * components of <b>res:</b> and <b>file:</b> database <tt>URI</tt>s are not
+ * checked for file system equivalence, it is possible for the same database
+ * files to be accessed concurrently by both <b>file:</b> and <b>res:</b>
+ * database instances. That is, without this restriction, it is possible that
+ * <b>&lt;path&gt;</b>.data and <b>&lt;path&gt;</b>.properties file content may
+ * be written by a <b>file:</b> database instance without the knowlege or
+ * cooperation of a <b>res:</b> database instance open on the same files,
+ * potentially resulting in unexpected database errors, inconsistent operation
+ * and/or data corruption. <p>
+ *
+ * In short, a <b>res:</b> type database connection <b>&lt;url&gt;</b> is
+ * designed specifically to connect to a <b>'files_in_jar'</b> mode database
+ * instance, which in turn is designed specifically to operate under
+ * <em>Java WebStart</em><sup><font size="-2">TM</font></sup> and
+ * <em>Java Applet</em><sup><font size="-2">TM</font></sup>configurations,
+ * where co-locating the database files in the jars that make up the
+ * <em>WebStart</em> application or Applet avoids the need for special security
+ * configuration or code signing. <p>
+ *
+ * <b>Note:</b> Since it is difficult and often nearly impossible to determine
+ * or control at runtime from where all classes are being loaded or which class
+ * loader is doing the loading (and hence how relative path specifications
+ * are resolved) under <b>'files_in_jar'</b> semantics, the <b>&lt;path&gt;</b>
+ * component of the <b>res:</b> database connection <b>&lt;url&gt;</b> is always
+ * taken to be relative to the default package and resource URL resolution is
+ * always performed using the ClassLoader that loads the
+ * org.hsqldb.persist.Logger class. That is, if the <b>&lt;path&gt;</b>
+ * component does not start with '/', then'/' is prepended when obtaining the
+ * resource URLs used to read the database files, and only the effective class
+ * path of org.hsqldb.persist.Logger's ClassLoader is searched. <p>
+ *
+ * <hr>
+ *
+ * For more information about HSQLDB file structure, various database modes
+ * and other attributes such as those controlled through the HSQLDB properties
+ * files, please read the general documentation, especially the Advanced Users
+ * Guide. <p>
+ *
+ * <hr>
+ *
+ * <b>JRE 1.1.x Notes:</b> <p>
+ *
+ * In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ * Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ * versions of JDBC depends on the JDK version used for compiling and building
+ * HSQLDB.<p>
+ *
+ * Since 1.7.0, it is possible to build the product so that
+ * all JDBC 2 methods can be called while executing under the version 1.1.x
+ * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ * However, in addition to this technique requiring explicit casts to the
+ * org.hsqldb.jdbc.* classes, some of the method calls also require
+ * <code>int</code> values that are defined only in the JDBC 2 or greater
+ * version of the {@link java.sql.ResultSet ResultSet} interface.  For this
+ * reason, when the product is compiled under JDK 1.1.x, these values are
+ * defined in {@link JDBCResultSet JDBCResultSet}. <p>
+ *
+ * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ * JDBC 2+ <code>ResultSet</code> values can be achieved by referring
+ * to them in parameter specifications and return value comparisons,
+ * respectively, as follows: <p>
+ *
+ * <pre class="JavaCodeExample">
+ * JDBCResultSet.FETCH_FORWARD
+ * JDBCResultSet.TYPE_FORWARD_ONLY
+ * JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ * JDBCResultSet.CONCUR_READ_ONLY
+ * // etc.
+ * </pre>
+ *
+ * However, please note that code written to use HSQLDB JDBC 2 features under
+ * JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
+ * also note that this feature is offered solely as a convenience to developers
+ * who must work under JDK 1.1.x due to operating constraints, yet wish to
+ * use some of the more advanced features available under the JDBC 2
+ * specification. <p>
+ *
+ * <hr>
+ *
+ * <b>JDBC 4.0 Notes:</b><p>
+ *
+ * Starting with JDBC 4.0 (JDK 1.6), the <code>DriverManager</code> methods
+ * <code>getConnection</code> and <code>getDrivers</code> have been
+ * enhanced to support the Java Standard Edition Service Provider mechanism.
+ * When built under a Java runtime that supports JDBC 4.0, HSQLDB distribution
+ * jars containing the Driver implementatiton also include the file
+ * <code>META-INF/services/java.sql.Driver</code>. This file contains the fully
+ * qualified class name ('org.hsqldb.jdbc.JDBCDriver') of the HSQLDB implementation
+ * of <code>java.sql.Driver</code>. <p>
+ *
+ * Hence, under JDBC 4.0 or greater, applications no longer need to explictly
+ * load the HSQLDB JDBC driver using <code>Class.forName()</code>. Of course,
+ * existing programs which do load JDBC drivers using
+ * <code>Class.forName()</code> will continue to work without modification. <p>
+ *
+ * <hr>
+ *
+ * (fredt@users)<br>
+ * (boucherb@users)<p>
+ *
+ * </div> <!-- end release-specific documentation -->
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @revised JDK 1.6, HSQLDB 2.0
+ * @see JDBCDriver
+ * @see JDBCStatement
+ * @see JDBCParameterMetaData
+ * @see JDBCCallableStatement
+ * @see JDBCResultSet
+ * @see JDBCDatabaseMetaData
+ * @see java.sql.DriverManager#getConnection
+ * @see java.sql.Statement
+ * @see java.sql.ResultSet
+ * @see java.sql.DatabaseMetaData
+ */
+public class JDBCConnection implements Connection {
+
+// ----------------------------------- JDBC 1 -------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>Statement</code> object for sending
+     * SQL statements to the database.
+     * SQL statements without parameters are normally
+     * executed using <code>Statement</code> objects. If the same SQL statement
+     * is executed many times, it may be more efficient to use a
+     * <code>PreparedStatement</code> object.
+     * <P>
+     * Result sets created using the returned <code>Statement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 1.7.2, support for precompilation at the engine level
+     * has been implemented, so it is now much more efficient and performant
+     * to use a <code>PreparedStatement</code> object if the same short-running
+     * SQL statement is to be executed many times. <p>
+     *
+     * HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+     * <code>TYPE_SCROLL_INSENSITIVE</code> and <code>CONCUR_READ_ONLY</code>
+     * results. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @return a new default <code>Statement</code> object
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 clarification:)
+     * or this method is called on a closed connection
+     * @see #createStatement(int,int)
+     * @see #createStatement(int,int,int)
+     */
+    public synchronized Statement createStatement() throws SQLException {
+
+        checkClosed();
+
+        int props =
+            ResultProperties.getValueForJDBC(JDBCResultSet.TYPE_FORWARD_ONLY,
+                JDBCResultSet.CONCUR_READ_ONLY, rsHoldability);
+        Statement stmt = new JDBCStatement(this, props);
+
+        return stmt;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>PreparedStatement</code> object for sending
+     * parameterized SQL statements to the database.
+     * <P>
+     * A SQL statement with or without IN parameters can be
+     * pre-compiled and stored in a <code>PreparedStatement</code> object. This
+     * object can then be used to efficiently execute this statement
+     * multiple times.
+     *
+     * <P><B>Note:</B> This method is optimized for handling
+     * parametric SQL statements that benefit from precompilation. If
+     * the driver supports precompilation,
+     * the method <code>prepareStatement</code> will send
+     * the statement to the database for precompilation. Some drivers
+     * may not support precompilation. In this case, the statement may
+     * not be sent to the database until the <code>PreparedStatement</code>
+     * object is executed.  This has no direct effect on users; however, it does
+     * affect which methods throw certain <code>SQLException</code> objects.
+     * <P>
+     * Result sets created using the returned <code>PreparedStatement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 1.7.2, support for precompilation at the engine level
+     * has been implemented, so it is now much more efficient and performant
+     * to use a <code>PreparedStatement</code> object if the same short-running
+     * SQL statement is to be executed many times. <p>
+     *
+     * The support for and behaviour of PreparedStatment complies with SQL and
+     * JDBC standards.  Please read the introductory section
+     * of the documentation for ${link JDBCParameterMetaData}. <P>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL statement that may contain one or more '?' IN
+     * parameter placeholders
+     * @return a new default <code>PreparedStatement</code> object containing the
+     * pre-compiled SQL statement
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 clarification:)
+     * or this method is called on a closed connection
+     * @see #prepareStatement(String,int,int)
+     */
+    public synchronized PreparedStatement prepareStatement(
+            String sql) throws SQLException {
+
+        checkClosed();
+
+        try {
+            return new JDBCPreparedStatement(this, sql,
+                    JDBCResultSet.TYPE_FORWARD_ONLY,
+                    JDBCResultSet.CONCUR_READ_ONLY, rsHoldability,
+                    ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>CallableStatement</code> object for calling
+     * database stored procedures.
+     * The <code>CallableStatement</code> object provides
+     * methods for setting up its IN and OUT parameters, and
+     * methods for executing the call to a stored procedure.
+     *
+     * <P><B>Note:</B> This method is optimized for handling stored
+     * procedure call statements. Some drivers may send the call
+     * statement to the database when the method <code>prepareCall</code>
+     * is done; others
+     * may wait until the <code>CallableStatement</code> object
+     * is executed. This has no
+     * direct effect on users; however, it does affect which method
+     * throws certain SQLExceptions.
+     * <P>
+     * Result sets created using the returned <code>CallableStatement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.7.2, the support for and behaviour of
+     * CallableStatement has changed.  Please read the introductory section
+     * of the documentation for org.hsqldb.jdbc.JDBCCallableStatement.
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL statement that may contain one or more '?'
+     * parameter placeholders. (JDBC4 clarification:) Typically this statement is specified using JDBC
+     * call escape syntax.
+     * @return a new default <code>CallableStatement</code> object containing the
+     * pre-compiled SQL statement
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 clarification:)
+     * or this method is called on a closed connection
+     * @see #prepareCall(String,int,int)
+     */
+    public synchronized CallableStatement prepareCall(
+            String sql) throws SQLException {
+
+        CallableStatement stmt;
+
+        checkClosed();
+
+        try {
+            stmt = new JDBCCallableStatement(this, sql,
+                    JDBCResultSet.TYPE_FORWARD_ONLY,
+                    JDBCResultSet.CONCUR_READ_ONLY, rsHoldability);
+
+            return stmt;
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Converts the given SQL statement into the system's native SQL grammar.
+     * A driver may convert the JDBC SQL grammar into its system's
+     * native SQL grammar prior to sending it. This method returns the
+     * native form of the statement that the driver would have sent.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the JDBC SQL
+     * grammar into the system's native SQL grammar prior to sending
+     * it, if escape processing is set true; this method returns the
+     * native form of the statement that the driver would send in place
+     * of client-specified JDBC SQL grammar. <p>
+     *
+     * Before 1.7.2, escape processing was incomplete and
+     * also broken in terms of support for nested escapes. <p>
+     *
+     * Starting with 1.7.2, escape processing is complete and handles nesting
+     * to arbitrary depth, but enforces a very strict interpretation of the
+     * syntax and does not detect or process SQL comments. <p>
+     *
+     * In essence, the HSQLDB engine directly handles the prescribed syntax
+     * and date / time formats specified internal to the JDBC escapes.
+     * It also directly offers the XOpen / ODBC extended scalar
+     * functions specified available internal to the {fn ...} JDBC escape.
+     * As such, the driver simply removes the curly braces and JDBC escape
+     * codes in the simplest and fastest fashion possible, by replacing them
+     * with whitespace.
+     *
+     * But to avoid a great deal of complexity, certain forms of input
+     * whitespace are currently not recognised.  For instance,
+     * the driver handles "{?= call ...}" but not "{ ?= call ...} or
+     * "{? = call ...}" <p>
+     *
+     * Also, comments embedded in SQL are currently not detected or
+     * processed and thus may have unexpected effects on the output
+     * of this method, for instance causing otherwise valid SQL to become
+     * invalid. It is especially important to be aware of this because escape
+     * processing is set true by default for Statement objects and is always
+     * set true when producing a PreparedStatement from prepareStatement()
+     * or CallableStatement from prepareCall().  Currently, it is simply
+     * recommended to avoid submitting SQL having comments containing JDBC
+     * escape sequence patterns and/or single or double quotation marks,
+     * as this will avoid any potential problems.
+     *
+     * It is intended to implement a less strict handling of whitespace and
+     * proper processing of SQL comments at some point in the near future.
+     *
+     * In any event, 1.7.2 now correctly processes the following JDBC escape
+     * forms to arbitrary nesting depth, but only if the exact whitespace
+     * layout described below is used: <p>
+     *
+     * <ol>
+     * <li>{call ...}
+     * <li>{?= call ...}
+     * <li>{fn ...}
+     * <li>{oj ...}
+     * <li>{d ...}
+     * <li>{t ...}
+     * <li>{ts ...}
+     * </ol> <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL statement that may contain one or more '?'
+     * parameter placeholders
+     * @return the native form of this statement
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 clarification:)
+     * or this method is called on a closed connection
+     */
+    public synchronized String nativeSQL(
+            final String sql) throws SQLException {
+
+        checkClosed();
+
+        if (sql == null || sql.length() == 0 || sql.indexOf('{') == -1) {
+            return sql;
+        }
+
+        boolean   changed = false;
+        int          state = 0;
+        int          len   = sql.length();
+        int          nest  = 0;
+        StringBuffer sb = null;
+        String       msg;
+
+        //--
+        final int outside_all                         = 0;
+        final int outside_escape_inside_single_quotes = 1;
+        final int outside_escape_inside_double_quotes = 2;
+
+        //--
+        final int inside_escape                      = 3;
+        final int inside_escape_inside_single_quotes = 4;
+        final int inside_escape_inside_double_quotes = 5;
+
+        /** @todo */
+
+        // final int inside_single_line_comment          = 6;
+        // final int inside_multi_line_comment           = 7;
+        // Better than old way for large inputs and for avoiding GC overhead;
+        // toString() reuses internal char[], reducing memory requirment
+        // and garbage items 3:2
+
+        int tail = 0;
+        for (int i = 0; i < len; i++) {
+            char c = sql.charAt(i);
+
+            switch (state) {
+
+                case outside_all :    // Not inside an escape or quotes
+                    if (c == '\'') {
+                        state = outside_escape_inside_single_quotes;
+                    } else if (c == '"') {
+                        state = outside_escape_inside_double_quotes;
+                    } else if (c == '{') {
+                        if (sb == null) {
+                            sb = new StringBuffer(sql.length());
+                        }
+                        sb.append(sql.substring(tail, i));
+                        i = onStartEscapeSequence(sql, sb, i);
+                        tail = i;
+
+                        changed = true;
+                        nest++;
+
+                        state = inside_escape;
+                    }
+
+                    break;
+                case outside_escape_inside_single_quotes :    // inside ' ' only
+                case inside_escape_inside_single_quotes :     // inside { } and ' '
+                    if (c == '\'') {
+                        state -= 1;
+                    }
+
+                    break;
+                case outside_escape_inside_double_quotes :    // inside " " only
+                case inside_escape_inside_double_quotes :     // inside { } and " "
+                    if (c == '"') {
+                        state -= 2;
+                    }
+
+                    break;
+                case inside_escape :                          // inside { }
+                    if (c == '\'') {
+                        state = inside_escape_inside_single_quotes;
+                    } else if (c == '"') {
+                        state = inside_escape_inside_double_quotes;
+                    } else if (c == '}') {
+
+                        sb.append(sql.substring(tail, i));
+
+                        sb.append(' ');
+
+                        i++;
+                        tail = i;
+                        changed = true;
+                        nest--;
+
+                        state = (nest == 0) ? outside_all
+                                : inside_escape;
+                    } else if (c == '{') {
+                        sb.append(sql.substring(tail, i));
+                        i = onStartEscapeSequence(sql, sb, i);
+                        tail = i;
+                        changed = true;
+                        nest++;
+
+                        state = inside_escape;
+                    }
+            }
+        }
+
+        if (!changed) {
+            return sql;
+        }
+
+        sb.append(sql.substring(tail, sql.length()));
+
+        return sb.toString();
+    }
+
+    /**
+     * @todo - semantics of autocommit regarding commit when the ResultSet is closed
+     */
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets this connection's auto-commit mode to the given state.
+     * If a connection is in auto-commit mode, then all its SQL
+     * statements will be executed and committed as individual
+     * transactions.  Otherwise, its SQL statements are grouped into
+     * transactions that are terminated by a call to either
+     * the method <code>commit</code> or the method <code>rollback</code>.
+     * By default, new connections are in auto-commit
+     * mode.
+     * <P>
+     * The commit occurs when the statement completes. The time when the statement
+     * completes depends on the type of SQL Statement:
+     * <ul>
+     * <li>For DML statements, such as Insert, Update or Delete, and DDL statements,
+     * the statement is complete as soon as it has finished executing.
+     * <li>For Select statements, the statement is complete when the associated result
+     * set is closed.
+     * <li>For <code>CallableStatement</code> objects or for statements that return
+     * multiple results, the statement is complete
+     * when all of the associated result sets have been closed, and all update
+     * counts and output parameters have been retrieved.
+     * </ul>
+     * <P>
+     * <B>NOTE:</B>  If this method is called during a transaction and the
+     * auto-commit mode is changed, the transaction is committed.  If
+     * <code>setAutoCommit</code> is called and the auto-commit mode is
+     * not changed, the call is a no-op.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Up to and including HSQLDB 2.0, <p>
+     *
+     * <ol>
+     *   <li> All rows of a result set are retrieved internally <em>
+     *   before</em> the first row can actually be fetched.<br>
+     *   Therefore, a statement can be considered complete as soon as
+     *   any XXXStatement.executeXXX method returns. </li>
+     *
+     *   <li> Multiple result sets and output parameters are not yet
+     *   supported. </li>
+     * </ol>
+     * <p>
+     *
+     * Starting with 2.0, HSQLDB may not return a result set to the network
+     * client as a whole; the generic documentation will apply. The fetch
+     * size is taken into account
+     *
+     * (boucherb@users) </div> <!-- end release-specific
+     * documentation -->
+     *
+     * @param autoCommit <code>true</code> to enable auto-commit mode;
+     *         <code>false</code> to disable it
+     * @exception SQLException if a database access error occurs,
+     *  (JDBC4 Clarification:)
+     *  setAutoCommit(true) is called while participating in a distributed transaction,
+     * or this method is called on a closed connection
+     * @see #getAutoCommit
+     */
+    public synchronized void setAutoCommit(
+            boolean autoCommit) throws SQLException {
+
+        checkClosed();
+
+        try {
+            sessionProxy.setAutoCommit(autoCommit);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Retrieves the current auto-commit mode for this <code>Connection</code>
+     * object.
+     *
+     * @return the current state of this <code>Connection</code> object's
+     *         auto-commit mode
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     * @see #setAutoCommit
+     */
+    public synchronized boolean getAutoCommit() throws SQLException {
+
+        checkClosed();
+
+        try {
+            return sessionProxy.isAutoCommit();
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Makes all changes made since the previous
+     * commit/rollback permanent and releases any database locks
+     * currently held by this <code>Connection</code> object.
+     * This method should be
+     * used only when auto-commit mode has been disabled.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     * </div><!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs,
+     * (JDBC4 Clarification:)
+     * this method is called while participating in a distributed transaction,
+     * if this method is called on a closed conection or this
+     *            <code>Connection</code> object is in auto-commit mode
+     * @see #setAutoCommit
+     */
+    public synchronized void commit() throws SQLException {
+
+        checkClosed();
+
+        try {
+            sessionProxy.commit(false);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Undoes all changes made in the current transaction
+     * and releases any database locks currently held
+     * by this <code>Connection</code> object. This method should be
+     * used only when auto-commit mode has been disabled.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 1.7.2, savepoints are fully supported both
+     * in SQL and via the JDBC interface. <p>
+     *
+     * Using SQL, savepoints may be set, released and used in rollback
+     * as follows:
+     *
+     * <pre>
+     * SAVEPOINT &lt;savepoint-name&gt;
+     * RELEASE SAVEPOINT &lt;savepoint-name&gt;
+     * ROLLBACK TO SAVEPOINT &lt;savepoint-name&gt;
+     * </pre>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs,
+     * (JDBC4 Clarification:)
+     * this method is called while participating in a distributed transaction,
+     * this method is called on a closed connection or this
+     *            <code>Connection</code> object is in auto-commit mode
+     * @see #setAutoCommit
+     */
+    public synchronized void rollback() throws SQLException {
+
+        checkClosed();
+
+        try {
+            sessionProxy.rollback(false);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Releases this <code>Connection</code> object's database and JDBC resources
+     * immediately instead of waiting for them to be automatically released.
+     * <P>
+     * Calling the method <code>close</code> on a <code>Connection</code>
+     * object that is already closed is a no-op.
+     * <P>
+     * It is <b>strongly recommended</b> that an application explicitly
+     * commits or rolls back an active transaction prior to calling the
+     * <code>close</code> method.  If the <code>close</code> method is called
+     * and there is an active transaction, the results are implementation-defined.
+     * <P>
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 1.7.2, HSQLDB <code>INTERNAL</code> <code>Connection</code>
+     * objects are not closable from JDBC client code. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @exception SQLException SQLException if a database access error occurs
+     */
+    public synchronized void close() throws SQLException {
+
+        // Changed to synchronized above because
+        // we would not want a sessionProxy.close()
+        // operation to occur concurrently with a
+        // statementXXX.executeXXX operation.
+        if (isInternal || isClosed) {
+            return;
+        }
+        isClosed = true;
+
+        if (sessionProxy != null) {
+            sessionProxy.close();
+        }
+        sessionProxy   = null;
+        rootWarning    = null;
+        connProperties = null;
+    }
+
+    /**
+     * Retrieves whether this <code>Connection</code> object has been
+     * closed.  A connection is closed if the method <code>close</code>
+     * has been called on it or if certain fatal errors have occurred.
+     * This method is guaranteed to return <code>true</code> only when
+     * it is called after the method <code>Connection.close</code> has
+     * been called.
+     * <P>
+     * This method generally cannot be called to determine whether a
+     * connection to a database is valid or invalid.  A typical client
+     * can determine that a connection is invalid by catching any
+     * exceptions that might be thrown when an operation is attempted.
+     *
+     * @return <code>true</code> if this <code>Connection</code> object
+     *         is closed; <code>false</code> if it is still open
+     * @exception SQLException if a database access error occurs
+     */
+    public synchronized boolean isClosed() throws SQLException {
+        return isClosed;
+    }
+
+    //======================================================================
+    // Advanced features:
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves a <code>DatabaseMetaData</code> object that contains
+     * metadata about the database to which this
+     * <code>Connection</code> object represents a connection.
+     * The metadata includes information about the database's
+     * tables, its supported SQL grammar, its stored
+     * procedures, the capabilities of this connection, and so on.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 essentially supports full database metadata. <p>
+     *
+     * For discussion in greater detail, please follow the link to the
+     * overview for JDBCDatabaseMetaData, below.
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @return a <code>DatabaseMetaData</code> object for this
+     *         <code>Connection</code> object
+     * @exception  SQLException if a database access error occurs
+     * (JDBC4 Clarification)
+     * or this method is called on a closed connection
+     * @see JDBCDatabaseMetaData
+     */
+    public synchronized DatabaseMetaData getMetaData() throws SQLException {
+
+        checkClosed();
+
+        return new JDBCDatabaseMetaData(this);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Puts this connection in read-only mode as a hint to the driver to enable
+     * database optimizations.
+     *
+     * <P><B>Note:</B> This method cannot be called during a transaction.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports the SQL standard, which will not allow calls to
+     * this method to succeed during a transaction.<p>
+     *
+     * Additionally, HSQLDB provides a way to put a whole database in
+     * read-only mode. This is done by manually adding the line
+     * 'readonly=true' to the database's .properties file while the
+     * database is offline. Upon restart, all connections will be
+     * readonly, since the entire database will be readonly. To take
+     * a database out of readonly mode, simply take the database
+     * offline and remove the line 'readonly=true' from the
+     * database's .properties file. Upon restart, the database will
+     * be in regular (read-write) mode. <p>
+     *
+     * When a database is put in readonly mode, its files are opened
+     * in readonly mode, making it possible to create CD-based
+     * readonly databases. To create a CD-based readonly database
+     * that has CACHED tables and whose .data file is suspected of
+     * being highly fragmented, it is recommended that the database
+     * first be SHUTDOWN COMPACTed before copying the database
+     * files to CD. This will reduce the space required and may
+     * improve access times against the .data file which holds the
+     * CACHED table data. <p>
+     *
+     * Starting with 1.7.2, an alternate approach to opimizing the
+     * .data file before creating a CD-based readonly database is to issue
+     * the CHECKPOINT DEFRAG command followed by SHUTDOWN to take the
+     * database offline in preparation to burn the database files to CD. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param readOnly <code>true</code> enables read-only mode;
+     *        <code>false</code> disables it
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     *  method is called on a closed connection or this
+     *            method is called during a transaction
+     */
+    public synchronized void setReadOnly(
+            boolean readOnly) throws SQLException {
+
+        checkClosed();
+
+        try {
+            sessionProxy.setReadOnlyDefault(readOnly);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Retrieves whether this <code>Connection</code>
+     * object is in read-only mode.
+     *
+     * @return <code>true</code> if this <code>Connection</code> object
+     *         is read-only; <code>false</code> otherwise
+     * @exception SQLException SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     */
+    public synchronized boolean isReadOnly() throws SQLException {
+
+        checkClosed();
+
+        try {
+            return sessionProxy.isReadOnlyDefault();
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Sets the given catalog name in order to select
+     * a subspace of this <code>Connection</code> object's database
+     * in which to work.
+     * <P>
+     *
+     * (JDBC4 Clarification:)<p>
+     * If the driver does not support catalogs, it will
+     * silently ignore this request.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports a single catalog per database. If the given catalog name
+     * is not the same as the database catalog name, this method throws an
+     * error. <p>
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param catalog the name of a catalog (subspace in this
+     *        <code>Connection</code> object's database) in which to work
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 Clarification)
+     * or this method is called on a closed connection
+     * @see #getCatalog
+     */
+    public synchronized void setCatalog(String catalog) throws SQLException {
+
+        checkClosed();
+
+        try {
+            sessionProxy.setAttribute(SessionInterface.INFO_CATALOG, catalog);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves this <code>Connection</code> object's current catalog name.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports a single catalog per database. This method
+     * returns the catalog name for the current database
+     * error. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @return the current catalog name or <code>null</code> if there is none
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     * @see #setCatalog
+     */
+    public synchronized String getCatalog() throws SQLException {
+
+        checkClosed();
+
+        try {
+            return (String) sessionProxy.getAttribute(
+                SessionInterface.INFO_CATALOG);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * <code>Connection</code> object to the one given.
+     * The constants defined in the interface <code>Connection</code>
+     * are the possible transaction isolation levels.
+     * <P>
+     * <B>Note:</B> If this method is called during a transaction, the result
+     * is implementation-defined.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports all isolation levels. <code>Connection.TRANSACTION_READ_UNCOMMITED</code>
+     * is promoted to <code>Connection.TRANSACTION_READ_COMMITED</code>.
+     * Calling this method during a transaction always fails.<p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param level one of the following <code>Connection</code> constants:
+     *        <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>,
+     *        <code>Connection.TRANSACTION_READ_COMMITTED</code>,
+     *        <code>Connection.TRANSACTION_REPEATABLE_READ</code>, or
+     *        <code>Connection.TRANSACTION_SERIALIZABLE</code>.
+     *        (Note that <code>Connection.TRANSACTION_NONE</code> cannot be used
+     *        because it specifies that transactions are not supported.)
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     * method is called on a closed connection
+     * (:JDBC4 End Clarification)
+     *            or the given parameter is not one of the <code>Connection</code>
+     *            constants
+     * @see JDBCDatabaseMetaData#supportsTransactionIsolationLevel
+     * @see #getTransactionIsolation
+     */
+    public synchronized void setTransactionIsolation(
+            int level) throws SQLException {
+
+        checkClosed();
+
+        switch (level) {
+
+            case TRANSACTION_READ_UNCOMMITTED :
+            case TRANSACTION_READ_COMMITTED :
+            case TRANSACTION_REPEATABLE_READ :
+            case TRANSACTION_SERIALIZABLE :
+                break;
+            default :
+                throw Util.invalidArgument();
+        }
+
+        try {
+            sessionProxy.setIsolationDefault(level);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves this <code>Connection</code> object's current
+     * transaction isolation level.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports all isolation levels. <code>Connection.TRANSACTION_READ_UNCOMMITED</code>
+     * is promoted to <code>Connection.TRANSACTION_READ_COMMITED</code>.
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @return the current transaction isolation level, which will be one
+     *         of the following constants:
+     *        <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>,
+     *        <code>Connection.TRANSACTION_READ_COMMITTED</code>,
+     *        <code>Connection.TRANSACTION_REPEATABLE_READ</code>,
+     *        <code>Connection.TRANSACTION_SERIALIZABLE</code>, or
+     *        <code>Connection.TRANSACTION_NONE</code>.
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     * @see JDBCDatabaseMetaData#supportsTransactionIsolationLevel
+     * @see #setTransactionIsolation
+     */
+    public synchronized int getTransactionIsolation() throws SQLException {
+
+        checkClosed();
+
+        try {
+            return sessionProxy.getIsolation();
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the first warning reported by calls on this
+     * <code>Connection</code> object.  If there is more than one
+     * warning, subsequent warnings will be chained to the first one
+     * and can be retrieved by calling the method
+     * <code>SQLWarning.getNextWarning</code> on the warning
+     * that was retrieved previously.
+     * <P>
+     * This method may not be
+     * called on a closed connection; doing so will cause an
+     * <code>SQLException</code> to be thrown.
+     *
+     * <P><B>Note:</B> Subsequent warnings will be chained to this
+     * SQLWarning.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB produces warnings whenever a createStatement(),
+     * prepareStatement() or prepareCall() invocation requests an unsupported
+     * but defined combination of result set type, concurrency and holdability,
+     * such that another set is substituted.<p>
+     * Other warnings are typically raised during the execution of data change
+     * and query statements.<p>
+     *
+     * Only the warnings caused by the last operation on this connection are
+     * returned by this method. A single operation may return up to 10 chained
+     * warnings.
+     *
+     * </div> <!-- end release-specific documentation -->
+     * @return the first <code>SQLWarning</code> object or <code>null</code>
+     *         if there are none
+     * @exception SQLException if a database access error occurs or
+     *            this method is called on a closed connection
+     * @see java.sql.SQLWarning
+     */
+    public synchronized SQLWarning getWarnings() throws SQLException {
+
+        checkClosed();
+
+        return rootWarning;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Clears all warnings reported for this <code>Connection</code> object.
+     * After a call to this method, the method <code>getWarnings</code>
+     * returns <code>null</code> until a new warning is
+     * reported for this <code>Connection</code> object.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The standard behaviour is implemented. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @exception SQLException SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     */
+    public synchronized void clearWarnings() throws SQLException {
+
+        checkClosed();
+
+        rootWarning = null;
+    }
+
+    //--------------------------JDBC 2.0-----------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>Statement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type and concurrency.
+     * This method is the same as the <code>createStatement</code> method
+     * above, but it allows the default result set
+     * type and concurrency to be overridden.
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+     * interpretation of of resultSetType and resultSetConcurrency has
+     * changed in this version.<p>
+     *
+     * HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+     * <code>TYPE_SCROLL_INSENSITIVE</code>,
+     * <code>CONCUR_READ_ONLY</code>,
+     * <code>CONCUR_UPDATABLE</code>
+     * results. <p>
+     *
+     * If an unsupported combination is requested, a SQLWarning is issued on
+     * this Connection and the closest supported combination is used instead. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param resultSetType a result set type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency a concurrency type; one of
+     *        <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *        <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @return a new <code>Statement</code> object that will generate
+     *         <code>ResultSet</code> objects with the given type and
+     *         concurrency
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     * method is called on a closed connection
+     * (:JDBC4 Clarification)
+     *         or the given parameters are not <code>ResultSet</code>
+     *         constants indicating type and concurrency
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method or this method is not supported for the specified result
+     * set type and result set concurrency.
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *  for JDBCConnection)
+     */
+    public synchronized Statement createStatement(int resultSetType,
+            int resultSetConcurrency) throws SQLException {
+
+        checkClosed();
+
+        int props = ResultProperties.getValueForJDBC(resultSetType,
+            resultSetConcurrency, rsHoldability);
+
+        return new JDBCStatement(this, props);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>PreparedStatement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type and concurrency.
+     * This method is the same as the <code>prepareStatement</code> method
+     * above, but it allows the default result set
+     * type and concurrency to be overridden.
+     * (JDBC4 Clarification:)
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+     * interpretation of of resultSetType and resultSetConcurrency has
+     * changed in this version.<p>
+     *
+     * HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+     * <code>TYPE_SCROLL_INSENSITIVE</code>,
+     * <code>CONCUR_READ_ONLY</code>,
+     * <code>CONCUR_UPDATABLE</code>
+     * results. <p>
+     *
+     * If an unsupported combination is requested, a SQLWarning is issued on
+     * this Connection and the closest supported combination is used instead. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql a <code>String</code> object that is the SQL statement to
+     *            be sent to the database; may contain one or more '?' IN
+     *            parameters
+     * @param resultSetType a result set type; one of
+     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency a concurrency type; one of
+     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @return a new PreparedStatement object containing the
+     * pre-compiled SQL statement that will produce <code>ResultSet</code>
+     * objects with the given type and concurrency
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     * method is called on a closed connection
+     * (:JDBC4 Clarification)
+     *         or the given parameters are not <code>ResultSet</code>
+     *         constants indicating type and concurrency
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method or this method is not supported for the specified result
+     * set type and result set concurrency.
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *  for JDBCConnection)
+     */
+    public synchronized PreparedStatement prepareStatement(String sql,
+            int resultSetType, int resultSetConcurrency) throws SQLException {
+
+        checkClosed();
+
+        try {
+            return new JDBCPreparedStatement(this, sql, resultSetType,
+                    resultSetConcurrency, rsHoldability,
+                    ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>CallableStatement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type and concurrency.
+     * This method is the same as the <code>prepareCall</code> method
+     * above, but it allows the default result set
+     * type and concurrency to be overridden.
+     * (JDBC4 Clarification:)
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+     * interpretation of of resultSetType and resultSetConcurrency has
+     * changed in this version.<p>
+     *
+     * HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+     * <code>TYPE_SCROLL_INSENSITIVE</code>,
+     * <code>CONCUR_READ_ONLY</code>,
+     * <code>CONCUR_UPDATABLE</code>
+     * results. <p>
+     *
+     * If an unsupported combination is requested, a SQLWarning is issued on
+     * this Connection and the closest supported combination is used instead. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql a <code>String</code> object that is the SQL statement to
+     *            be sent to the database; may contain on or more '?' parameters
+     * @param resultSetType a result set type; one of
+     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency a concurrency type; one of
+     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @return a new <code>CallableStatement</code> object containing the
+     * pre-compiled SQL statement that will produce <code>ResultSet</code>
+     * objects with the given type and concurrency
+     * @exception SQLException if a database access error occurs, this method
+     * (JDBC4 Clarification:)
+     * is called on a closed connection
+     * (:JDBC4 Clarification)
+     *         or the given parameters are not <code>ResultSet</code>
+     *         constants indicating type and concurrency
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method or this method is not supported for the specified result
+     * set type and result set concurrency.
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     * for JDBCConnection)
+     */
+    public synchronized CallableStatement prepareCall(String sql,
+            int resultSetType, int resultSetConcurrency) throws SQLException {
+
+        checkClosed();
+
+        try {
+            return new JDBCCallableStatement(this, sql, resultSetType,
+                    resultSetConcurrency, rsHoldability);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the <code>Map</code> object associated with this
+     * <code>Connection</code> object.
+     * Unless the application has added an entry, the type map returned
+     * will be empty.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * For compatibility, HSQLDB returns an empty map. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @return the <code>java.util.Map</code> object associated
+     *         with this <code>Connection</code> object
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCConnection)
+     */
+
+//#ifdef JAVA6
+    public synchronized java.util
+            .Map<java.lang.String,
+                 java.lang.Class<?>> getTypeMap() throws SQLException {
+
+        checkClosed();
+
+        return new java.util.HashMap<java.lang.String, java.lang.Class<?>>();
+    }
+
+//#else
+/*
+    public synchronized Map getTypeMap() throws SQLException {
+
+        checkClosed();
+
+        return new java.util.HashMap();
+    }
+*/
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Installs the given <code>TypeMap</code> object as the type map for
+     * this <code>Connection</code> object.  The type map will be used for the
+     * custom mapping of SQL structured types and distinct types.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not yet support this feature. Calling this
+     * method always throws a <code>SQLException</code>, stating that
+     * the function is not supported. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param map the <code>java.util.Map</code> object to install
+     *        as the replacement for this <code>Connection</code>
+     *        object's default type map
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     * method is called on a closed connection or
+     * (:JDBC4 Clarification)
+     *        the given parameter is not a <code>java.util.Map</code>
+     *        object
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCConnection)
+     * @see #getTypeMap
+     */
+//#ifdef JAVA6
+    public synchronized void setTypeMap(Map<String,
+            Class<?>> map) throws SQLException {
+
+        checkClosed();
+
+        throw Util.notSupported();
+    }
+
+//#else
+/*
+    public synchronized void setTypeMap(Map map) throws SQLException {
+
+        checkClosed();
+
+        throw Util.notSupported();
+    }
+*/
+
+//#endif JAVA6
+    //--------------------------JDBC 3.0-----------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * (JDBC4 Clarification:)
+     * Changes the default holdability of <code>ResultSet</code> objects
+     * created using this <code>Connection</code> object to the given
+     * holdability.  The default holdability of <code>ResultSet</code> objects
+     * can be be determined by invoking
+     * {@link DatabaseMetaData#getResultSetHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param holdability a <code>ResultSet</code> holdability constant; one of
+     *        <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *        <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @throws SQLException if a database access occurs, this method is called
+     * (JDBC4 Clarification:)
+     * on a closed connection, or the given parameter
+     * (:JDBC4 Clkarification)
+     *         is not a <code>ResultSet</code> constant indicating holdability
+     * @exception SQLFeatureNotSupportedException if the given holdability is not supported
+     * @see #getHoldability
+     * @see DatabaseMetaData#getResultSetHoldability
+     * @see JDBCResultSet
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized void setHoldability(
+            int holdability) throws SQLException {
+
+        checkClosed();
+
+        switch (holdability) {
+
+            case JDBCResultSet.HOLD_CURSORS_OVER_COMMIT :
+            case JDBCResultSet.CLOSE_CURSORS_AT_COMMIT :
+                break;
+            default :
+                throw Util.invalidArgument();
+        }
+        rsHoldability = holdability;
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Retrieves the current holdability of <code>ResultSet</code> objects
+     * created using this <code>Connection</code> object.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB returns the current holdability.<p>
+     *
+     * The default is HOLD_CURSORS_OVER_COMMIT. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @return the holdability, one of
+     *        <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *        <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @throws SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     * @see #setHoldability
+     * @see DatabaseMetaData#getResultSetHoldability
+     * @see JDBCResultSet
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized int getHoldability() throws SQLException {
+
+        checkClosed();
+
+        return rsHoldability;
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates an unnamed savepoint in the current transaction and
+     * returns the new <code>Savepoint</code> object that represents it.
+     *
+     * <p>(JDBC4 clarification:)
+     * <p> if setSavepoint is invoked outside of an active transaction, a transaction will be started at this newly created
+     * savepoint.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports this feature. <p>
+     *
+     * Note: Unnamed savepoints are not part of the SQL:2003 standard.
+     * Use setSavepoint(String name) instead. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @return the new <code>Savepoint</code> object
+     * @exception SQLException if a database access error occurs,
+     * (JDBC4 Clarification:)
+     * this method is called while participating in a distributed transaction,
+     * this method is called on a closed connection
+     *            or this <code>Connection</code> object is currently in
+     *            auto-commit mode
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see JDBCSavepoint
+     * @see java.sql.Savepoint
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized Savepoint setSavepoint() throws SQLException {
+
+        checkClosed();
+
+        if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && getAutoCommit()) {
+            throw Util.sqlException(ErrorCode.X_3B001);
+        }
+
+        try {
+            sessionProxy.savepoint("SYSTEM_SAVEPOINT");
+        } catch (HsqlException e) {
+            Util.throwError(e);
+        }
+
+        return new JDBCSavepoint(this);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a savepoint with the given name in the current transaction
+     * and returns the new <code>Savepoint</code> object that represents it.
+     *
+     * <p> if setSavepoint is invoked outside of an active transaction, a
+     * transaction will be started at this newly created savepoint.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Previous to JDBC 4, if the connection is autoCommit,
+     * setting a savepoint has no effect, as it is cleared upon the execution
+     * of the next transactional statement. When built for JDBC 4, this method
+     * throws an SQLException when this <tt>Connection</tt> object is currently
+     * in auto-commit mode, as per the JDBC 4 standard.
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param name a <code>String</code> containing the name of the savepoint
+     * @return the new <code>Savepoint</code> object
+     * @exception SQLException if a database access error occurs,
+     * (JDBC4 Clarification:)
+     *      this method is called while participating in a distributed transaction,
+     * this method is called on a closed connection
+     *            or this <code>Connection</code> object is currently in
+     *            auto-commit mode
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see JDBCSavepoint
+     * @see java.sql.Savepoint
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized Savepoint setSavepoint(
+            String name) throws SQLException {
+
+        checkClosed();
+
+        if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && getAutoCommit()) {
+            throw Util.sqlException(ErrorCode.X_3B001);
+        }
+
+        if (name == null) {
+            throw Util.nullArgument();
+        }
+
+        if ("SYSTEM_SAVEPOINT".equals(name)) {
+            throw Util.invalidArgument();
+        }
+
+        try {
+            sessionProxy.savepoint(name);
+        } catch (HsqlException e) {
+            Util.throwError(e);
+        }
+
+        return new JDBCSavepoint(name, this);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Undoes all changes made after the given <code>Savepoint</code> object
+     * was set.
+     * <P>
+     * This method should be used only when auto-commit has been disabled.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Previous to JDBC 4, <tt>JDBCSavepoint</tt> objects are valid for the life of
+     * the originating <tt>Connection</tt> object and hence can be used
+     * interchangably, as long as they have equal savepoint names. <p>
+     *
+     * When built for JDBC 4, <tt>JDBCConnection</tt> objects invalidate
+     * <tt>JDBCSavepoint</tt> objects when auto-commit mode is entered as well
+     * as when they are used to successfully release or roll back to a named SQL
+     * savepoint.  As per the JDBC 4 standard, when built for JDBC 4, this
+     * method throws an <tt>SQLException</tt> when this <tt>Connection</tt>
+     * object is currently in auto-commit mode and an invalidated
+     * <tt>JDBCSavepoint</tt> is specified.
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param savepoint the <code>Savepoint</code> object to roll back to
+     * @exception SQLException if a database access error occurs,
+     * this method is called while participating in a distributed transaction,
+     * this method is called on a closed connection,
+     *            the <code>Savepoint</code> object is no longer valid,
+     *            or this <code>Connection</code> object is currently in
+     *            auto-commit mode
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see JDBCSavepoint
+     * @see java.sql.Savepoint
+     * @see #rollback
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized void rollback(
+            Savepoint savepoint) throws SQLException {
+
+        JDBCSavepoint sp;
+
+        checkClosed();
+
+        if (savepoint == null) {
+            throw Util.nullArgument();
+        }
+
+        if (!(savepoint instanceof JDBCSavepoint)) {
+            String msg = Error.getMessage(ErrorCode.X_3B001);
+
+            throw Util.invalidArgument(msg);
+        }
+        sp = (JDBCSavepoint) savepoint;
+
+        if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && sp.name == null) {
+            String msg = Error.getMessage(ErrorCode.X_3B001);
+
+            throw Util.invalidArgument(msg);
+        }
+
+        if (this != sp.connection) {
+            String msg = Error.getMessage(ErrorCode.X_3B001);
+
+            throw Util.invalidArgument(msg);
+        }
+
+        if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && getAutoCommit()) {
+            sp.name       = null;
+            sp.connection = null;
+
+            throw Util.sqlException(ErrorCode.X_3B001);
+        }
+
+        try {
+            sessionProxy.rollbackToSavepoint(sp.name);
+
+            if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4) {
+                sp.connection = null;
+                sp.name       = null;
+            }
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Removes the specified <code>Savepoint</code> (JDBC4 Clarification:) and subsequent <code>Savepoint</code> objects from the current
+     * transaction. Any reference to the savepoint after it have been removed
+     * will cause an <code>SQLException</code> to be thrown.
+     *
+     * <!-- end generic documentation -->
+     *
+     *
+     * <b>HSLQDB Note:</b><p>
+     *
+     * Previous to JDBC 4, <tt>JDBCSavepoint</tt> objects are valid for the life of
+     * the originating <tt>Connection</tt> object and hence can be used
+     * interchangably, as long as they have equal savepoint names. <p>
+     *
+     * When built for JDBC 4, <tt>JDBCConnection</tt> objects invalidate
+     * <tt>JDBCSavepoint</tt> objects when auto-commit mode is entered as well
+     * as when they are used to successfully release or roll back to a named SQL
+     * savepoint.  As per the JDBC 4 standard, when built for JDBC 4, this
+     * method throws an <tt>SQLException</tt> when this <tt>Connection</tt>
+     * object is currently in auto-commit mode and when an invalidated
+     * <tt>JDBCSavepoint</tt> is specified. <p>
+     *
+     * @param savepoint the <code>Savepoint</code> object to be removed
+     * @exception SQLException if a database access error occurs, this
+     *  (JDBC4 Clarification:)
+     *  method is called on a closed connection or
+     *            the given <code>Savepoint</code> object is not a valid
+     *            savepoint in the current transaction
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see JDBCSavepoint
+     * @see java.sql.Savepoint
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized void releaseSavepoint(
+            Savepoint savepoint) throws SQLException {
+
+        JDBCSavepoint sp;
+        Result        req;
+
+        checkClosed();
+
+        if (savepoint == null) {
+            throw Util.nullArgument();
+        }
+
+        if (!(savepoint instanceof JDBCSavepoint)) {
+            String msg = Error.getMessage(ErrorCode.X_3B001);
+
+            throw Util.invalidArgument(msg);
+        }
+        sp = (JDBCSavepoint) savepoint;
+
+        if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && sp.name == null) {
+            String msg = Error.getMessage(ErrorCode.X_3B001);
+
+            throw Util.invalidArgument(msg);
+        }
+
+        if (this != sp.connection) {
+            String msg = Error.getMessage(ErrorCode.X_3B001);
+
+            throw Util.invalidArgument(msg);
+        }
+
+        if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && getAutoCommit()) {
+            sp.name       = null;
+            sp.connection = null;
+
+            throw Util.sqlException(ErrorCode.X_3B001);
+        }
+
+        try {
+            sessionProxy.releaseSavepoint(sp.name);
+
+            if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4) {
+                sp.connection = null;
+                sp.name       = null;
+            }
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>Statement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type, concurrency,
+     * and holdability.
+     * This method is the same as the <code>createStatement</code> method
+     * above, but it allows the default result set
+     * type, concurrency, and holdability to be overridden.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+     * interpretation of of resultSetType and resultSetConcurrency has
+     * changed in this version.<p>
+     *
+     * HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+     * <code>TYPE_SCROLL_INSENSITIVE</code>,
+     * <code>CONCUR_READ_ONLY</code>,
+     * <code>CONCUR_UPDATABLE</code>
+     * results. <p>
+     *
+     * If an unsupported combination is requested, a SQLWarning is issued on
+     * this Connection and the closest supported combination is used instead. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param resultSetType one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @param resultSetHoldability one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @return a new <code>Statement</code> object that will generate
+     *         <code>ResultSet</code> objects with the given type,
+     *         concurrency, and holdability
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     * method is called on a closed connection
+     * (:JDBC4 Clarification)
+     *            or the given parameters are not <code>ResultSet</code>
+     *            constants indicating type, concurrency, and holdability
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method or this method is not supported for the specified result
+     * set type, result set holdability and result set concurrency.
+     * @see JDBCResultSet
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized Statement createStatement(int resultSetType,
+            int resultSetConcurrency,
+            int resultSetHoldability) throws SQLException {
+
+        checkClosed();
+
+        int props = ResultProperties.getValueForJDBC(resultSetType,
+            resultSetConcurrency, resultSetHoldability);
+
+        return new JDBCStatement(this, props);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>PreparedStatement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type, concurrency,
+     * and holdability.
+     * <P>
+     * This method is the same as the <code>prepareStatement</code> method
+     * above, but it allows the default result set
+     * type, concurrency, and holdability to be overridden.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+     * interpretation of of resultSetType and resultSetConcurrency has
+     * changed in this version.<p>
+     *
+     * HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+     * <code>TYPE_SCROLL_INSENSITIVE</code>,
+     * <code>CONCUR_READ_ONLY</code>,
+     * <code>CONCUR_UPDATABLE</code>
+     * results. <p>
+     *
+     * If an unsupported combination is requested, a SQLWarning is issued on
+     * this Connection and the closest supported combination is used instead. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql a <code>String</code> object that is the SQL statement to
+     *            be sent to the database; may contain one or more '?' IN
+     *            parameters
+     * @param resultSetType one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @param resultSetHoldability one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @return a new <code>PreparedStatement</code> object, containing the
+     *         pre-compiled SQL statement, that will generate
+     *         <code>ResultSet</code> objects with the given type,
+     *         concurrency, and holdability
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     * method is called on a closed connection
+     * (:JDBC4 Clarification)
+     *            or the given parameters are not <code>ResultSet</code>
+     *            constants indicating type, concurrency, and holdability
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method or this method is not supported for the specified result
+     * set type, result set holdability and result set concurrency.
+     * @see JDBCResultSet
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized PreparedStatement prepareStatement(String sql,
+            int resultSetType, int resultSetConcurrency,
+            int resultSetHoldability) throws SQLException {
+
+        checkClosed();
+
+        try {
+            return new JDBCPreparedStatement(this, sql, resultSetType,
+                    resultSetConcurrency, resultSetHoldability,
+                    ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a <code>CallableStatement</code> object that will generate
+     * <code>ResultSet</code> objects with the given type and concurrency.
+     * This method is the same as the <code>prepareCall</code> method
+     * above, but it allows the default result set
+     * type, result set concurrency type and holdability to be overridden.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
+     * interpretation of of resultSetType and resultSetConcurrency has
+     * changed in this version.<p>
+     *
+     * HSQLDB supports <code>TYPE_FORWARD_ONLY</code>,
+     * <code>TYPE_SCROLL_INSENSITIVE</code>,
+     * <code>CONCUR_READ_ONLY</code>,
+     * <code>CONCUR_UPDATABLE</code>
+     * results. <p>
+     *
+     * If an unsupported combination is requested, a SQLWarning is issued on
+     * this Connection and the closest supported combination is used instead. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql a <code>String</code> object that is the SQL statement to
+     *            be sent to the database; may contain on or more '?' parameters
+     * @param resultSetType one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @param resultSetConcurrency one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
+     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @param resultSetHoldability one of the following <code>ResultSet</code>
+     *        constants:
+     *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @return a new <code>CallableStatement</code> object, containing the
+     *         pre-compiled SQL statement, that will generate
+     *         <code>ResultSet</code> objects with the given type,
+     *         concurrency, and holdability
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     * method is called on a closed connection
+     * (:JDBC4 Clarification)
+     *            or the given parameters are not <code>ResultSet</code>
+     *            constants indicating type, concurrency, and holdability
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method or this method is not supported for the specified result
+     * set type, result set holdability and result set concurrency.
+     * @see JDBCResultSet
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized CallableStatement prepareCall(String sql,
+            int resultSetType, int resultSetConcurrency,
+            int resultSetHoldability) throws SQLException {
+
+        checkClosed();
+
+        try {
+            return new JDBCCallableStatement(this, sql, resultSetType,
+                    resultSetConcurrency, resultSetHoldability);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a default <code>PreparedStatement</code> object that has
+     * the capability to retrieve auto-generated keys. The given constant
+     * tells the driver whether it should make auto-generated keys
+     * available for retrieval.  This parameter is ignored if the SQL statement
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <P>
+     * <B>Note:</B> This method is optimized for handling
+     * parametric SQL statements that benefit from precompilation. If
+     * the driver supports precompilation,
+     * the method <code>prepareStatement</code> will send
+     * the statement to the database for precompilation. Some drivers
+     * may not support precompilation. In this case, the statement may
+     * not be sent to the database until the <code>PreparedStatement</code>
+     * object is executed.  This has no direct effect on users; however, it does
+     * affect which methods throw certain SQLExceptions.
+     * <P>
+     * Result sets created using the returned <code>PreparedStatement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     * (JDBC4 Clarification:)
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Supported in 2.0
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL statement that may contain one or more '?' IN
+     *        parameter placeholders
+     * @param autoGeneratedKeys a flag indicating whether auto-generated keys
+     *        should be returned; one of
+     *        <code>Statement.RETURN_GENERATED_KEYS</code> or
+     *        <code>Statement.NO_GENERATED_KEYS</code>
+     * @return a new <code>PreparedStatement</code> object, containing the
+     *         pre-compiled SQL statement, that will have the capability of
+     *         returning auto-generated keys
+     * @exception SQLException if a database access error occurs, this
+     * (JDBC4 Clarification:)
+     *  method is called on a closed connection
+     * (:JDBC4 Clarification)
+     *         or the given parameter is not a <code>Statement</code>
+     *         constant indicating whether auto-generated keys should be
+     *         returned
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method with a constant of Statement.RETURN_GENERATED_KEYS
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized PreparedStatement prepareStatement(String sql,
+            int autoGeneratedKeys) throws SQLException {
+
+        checkClosed();
+
+        try {
+            if (autoGeneratedKeys != ResultConstants.RETURN_GENERATED_KEYS
+                    && autoGeneratedKeys
+                       != ResultConstants.RETURN_NO_GENERATED_KEYS) {
+                throw Util.invalidArgument("autoGeneratedKeys");
+            }
+
+            return new JDBCPreparedStatement(this, sql,
+                    JDBCResultSet.TYPE_FORWARD_ONLY,
+                    JDBCResultSet.CONCUR_READ_ONLY, rsHoldability,
+                    autoGeneratedKeys, null, null);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Creates a default <code>PreparedStatement</code> object capable
+     * of returning the auto-generated keys designated by the given array.
+     * This array contains the indexes of the columns in the target
+     * table that contain the auto-generated keys that should be made
+     * available.  The driver will ignore the array if the SQL statement
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <p>
+     * An SQL statement with or without IN parameters can be
+     * pre-compiled and stored in a <code>PreparedStatement</code> object. This
+     * object can then be used to efficiently execute this statement
+     * multiple times.
+     * <P>
+     * <B>Note:</B> This method is optimized for handling
+     * parametric SQL statements that benefit from precompilation. If
+     * the driver supports precompilation,
+     * the method <code>prepareStatement</code> will send
+     * the statement to the database for precompilation. Some drivers
+     * may not support precompilation. In this case, the statement may
+     * not be sent to the database until the <code>PreparedStatement</code>
+     * object is executed.  This has no direct effect on users; however, it does
+     * affect which methods throw certain SQLExceptions.
+     * <P>
+     * Result sets created using the returned <code>PreparedStatement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     * (JDBC4 Clarification:)
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Supported in 2.0
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL statement that may contain one or more '?' IN
+     *        parameter placeholders
+     * @param columnIndexes an array of column indexes indicating the columns
+     *        that should be returned from the inserted row or rows
+     * @return a new <code>PreparedStatement</code> object, containing the
+     *         pre-compiled statement, that is capable of returning the
+     *         auto-generated keys designated by the given array of column
+     *         indexes
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized PreparedStatement prepareStatement(String sql,
+            int[] columnIndexes) throws SQLException {
+
+        checkClosed();
+
+        try {
+            return new JDBCPreparedStatement(this, sql,
+                    JDBCResultSet.TYPE_FORWARD_ONLY,
+                    JDBCResultSet.CONCUR_READ_ONLY, rsHoldability,
+                    ResultConstants.RETURN_GENERATED_KEYS_COL_INDEXES,
+                    columnIndexes, null);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     *
+     * Creates a default <code>PreparedStatement</code> object capable
+     * of returning the auto-generated keys designated by the given array.
+     * This array contains the names of the columns in the target
+     * table that contain the auto-generated keys that should be returned.
+     * The driver will ignore the array if the SQL statement
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <P>
+     * An SQL statement with or without IN parameters can be
+     * pre-compiled and stored in a <code>PreparedStatement</code> object. This
+     * object can then be used to efficiently execute this statement
+     * multiple times.
+     * <P>
+     * <B>Note:</B> This method is optimized for handling
+     * parametric SQL statements that benefit from precompilation. If
+     * the driver supports precompilation,
+     * the method <code>prepareStatement</code> will send
+     * the statement to the database for precompilation. Some drivers
+     * may not support precompilation. In this case, the statement may
+     * not be sent to the database until the <code>PreparedStatement</code>
+     * object is executed.  This has no direct effect on users; however, it does
+     * affect which methods throw certain SQLExceptions.
+     * <P>
+     * Result sets created using the returned <code>PreparedStatement</code>
+     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
+     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
+     * (JDBC4 Clarification:)
+     * The holdability of the created result sets can be determined by
+     * calling {@link #getHoldability}.
+     *
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Supported in 2.0
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL statement that may contain one or more '?' IN
+     *        parameter placeholders
+     * @param columnNames an array of column names indicating the columns
+     *        that should be returned from the inserted row or rows
+     * @return a new <code>PreparedStatement</code> object, containing the
+     *         pre-compiled statement, that is capable of returning the
+     *         auto-generated keys designated by the given array of column
+     *         names
+     * @exception SQLException if a database access error occurs
+     * (JDBC4 Clarification:)
+     * or this method is called on a closed connection
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+//#ifdef JAVA4
+    public synchronized PreparedStatement prepareStatement(String sql,
+            String[] columnNames) throws SQLException {
+
+        checkClosed();
+
+        try {
+            return new JDBCPreparedStatement(this, sql,
+                    JDBCResultSet.TYPE_FORWARD_ONLY,
+                    JDBCResultSet.CONCUR_READ_ONLY, rsHoldability,
+                    ResultConstants.RETURN_GENERATED_KEYS_COL_NAMES, null,
+                    columnNames);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+//#endif JAVA4
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * Constructs an object that implements the <code>Clob</code> interface. The object
+     * returned initially contains no data.  The <code>setAsciiStream</code>,
+     * <code>setCharacterStream</code> and <code>setString</code> methods of
+     * the <code>Clob</code> interface may be used to add data to the <code>Clob</code>.
+     * @return An object that implements the <code>Clob</code> interface
+     * @throws SQLException if an object that implements the
+     * <code>Clob</code> interface can not be constructed, this method is
+     * called on a closed connection or a database access error occurs.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this data type
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public Clob createClob() throws SQLException {
+
+        checkClosed();
+
+        return new JDBCClob();
+    }
+
+    /**
+     * Constructs an object that implements the <code>Blob</code> interface. The object
+     * returned initially contains no data.  The <code>setBinaryStream</code> and
+     * <code>setBytes</code> methods of the <code>Blob</code> interface may be used to add data to
+     * the <code>Blob</code>.
+     * @return  An object that implements the <code>Blob</code> interface
+     * @throws SQLException if an object that implements the
+     * <code>Blob</code> interface can not be constructed, this method is
+     * called on a closed connection or a database access error occurs.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this data type
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public Blob createBlob() throws SQLException {
+
+        checkClosed();
+
+        return new JDBCBlob();
+    }
+
+    /**
+     * Constructs an object that implements the <code>NClob</code> interface. The object
+     * returned initially contains no data.  The <code>setAsciiStream</code>,
+     * <code>setCharacterStream</code> and <code>setString</code> methods of the <code>NClob</code> interface may
+     * be used to add data to the <code>NClob</code>.
+     * @return An object that implements the <code>NClob</code> interface
+     * @throws SQLException if an object that implements the
+     * <code>NClob</code> interface can not be constructed, this method is
+     * called on a closed connection or a database access error occurs.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this data type
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+
+//#ifdef JAVA6
+    public NClob createNClob() throws SQLException {
+
+        checkClosed();
+
+        return new JDBCNClob();
+    }
+
+//#endif JAVA6
+
+    /**
+     * Constructs an object that implements the <code>SQLXML</code> interface. The object
+     * returned initially contains no data. The <code>createXmlStreamWriter</code> object and
+     * <code>setString</code> method of the <code>SQLXML</code> interface may be used to add data to the <code>SQLXML</code>
+     * object.
+     * @return An object that implements the <code>SQLXML</code> interface
+     * @throws SQLException if an object that implements the <code>SQLXML</code> interface can not
+     * be constructed, this method is
+     * called on a closed connection or a database access error occurs.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this data type
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public SQLXML createSQLXML() throws SQLException {
+
+        checkClosed();
+
+        return new JDBCSQLXML();
+    }
+
+//#endif JAVA6
+
+    /** @todo:  ThreadPool? HsqlTimer with callback? */
+
+    /**
+     * Returns true if the connection has not been closed and is still valid.
+     * The driver shall submit a query on the connection or use some other
+     * mechanism that positively verifies the connection is still valid when
+     * this method is called.
+     * <p>
+     * The query submitted by the driver to validate the connection shall be
+     * executed in the context of the current transaction.
+     *
+     * @param timeout -         The time in seconds to wait for the database operation
+     *                                          used to validate the connection to complete.  If
+     *                                          the timeout period expires before the operation
+     *                                          completes, this method returns false.  A value of
+     *                                          0 indicates a timeout is not applied to the
+     *                                          database operation.
+     * <p>
+     * @return true if the connection is valid, false otherwise
+     * @exception SQLException if the value supplied for <code>timeout</code>
+     * is less then 0
+     * @since JDK 1.6, HSQLDB 2.0
+     * <p>
+     * @see JDBCDatabaseMetaData#getClientInfoProperties
+     */
+//#ifdef JAVA6
+    public boolean isValid(int timeout) throws SQLException {
+
+        if (timeout < 0) {
+            throw Util.outOfRangeArgument("timeout: " + timeout);
+        }
+
+        if (this.isInternal) {
+            return true;
+        } else if (!this.isNetConn) {
+            return !this.isClosed();
+        } else if (this.isClosed()) {
+            return false;
+        } else {
+            Thread t = new Thread() {
+
+                public void run() {
+
+                    try {
+                        getMetaData().getDatabaseMajorVersion();
+                    } catch (Exception e) {
+                        throw new RuntimeException();
+                    }
+                }
+            };
+
+            // Remember:  parm is in *seconds*
+            timeout *= 1000;
+
+            try {
+                t.start();
+
+                final long start = System.currentTimeMillis();
+
+                t.join(timeout);
+
+                return (timeout > 0)
+                       ? (System.currentTimeMillis() - start) < timeout
+                       : true;
+            } catch (Exception e) {
+                return false;
+            }
+        }
+    }
+
+//#endif JAVA6
+
+    /** @todo 20051207 */
+
+    /**
+     * Sets the value of the client info property specified by name to the
+     * value specified by value.
+     * <p>
+     * Applications may use the <code>DatabaseMetaData.getClientInfoProperties</code>
+     * method to determine the client info properties supported by the driver
+     * and the maximum length that may be specified for each property.
+     * <p>
+     * The driver stores the value specified in a suitable location in the
+     * database.  For example in a special register, session parameter, or
+     * system table column.  For efficiency the driver may defer setting the
+     * value in the database until the next time a statement is executed or
+     * prepared.  Other than storing the client information in the appropriate
+     * place in the database, these methods shall not alter the behavior of
+     * the connection in anyway.  The values supplied to these methods are
+     * used for accounting, diagnostics and debugging purposes only.
+     * <p>
+     * The driver shall generate a warning if the client info name specified
+     * is not recognized by the driver.
+     * <p>
+     * If the value specified to this method is greater than the maximum
+     * length for the property the driver may either truncate the value and
+     * generate a warning or generate a <code>SQLClientInfoException</code>.  If the driver
+     * generates a <code>SQLClientInfoException</code>, the value specified was not set on the
+     * connection.
+     * <p>
+     * The following are standard client info properties.  Drivers are not
+     * required to support these properties however if the driver supports a
+     * client info property that can be described by one of the standard
+     * properties, the standard property name should be used.
+     * <p>
+     * <ul>
+     * <li>ApplicationName      -       The name of the application currently utilizing
+     *                                                  the connection</li>
+     * <li>ClientUser           -       The name of the user that the application using
+     *                                                  the connection is performing work for.  This may
+     *                                                  not be the same as the user name that was used
+     *                                                  in establishing the connection.</li>
+     * <li>ClientHostname       -       The hostname of the computer the application
+     *                                                  using the connection is running on.</li>
+     * </ul>
+     * <p>
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0, throws an SQLClientInfoException when this method is
+     * called.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param name              The name of the client info property to set
+     * @param value             The value to set the client info property to.  If the
+     *                                  value is null, the current value of the specified
+     *                                  property is cleared.
+     * <p>
+     * @throws  SQLClientInfoException if the database server returns an error while
+     *                  setting the client info value on the database server or this method
+     * is called on a closed connection
+     * <p>
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void setClientInfo(String name,
+                              String value) throws SQLClientInfoException {
+
+        SQLClientInfoException ex = new SQLClientInfoException();
+
+        ex.initCause(Util.notSupported());
+
+        throw ex;
+    }
+
+//#endif JAVA6
+
+    /** @todo 20051207 */
+
+    /**
+     * Sets the value of the connection's client info properties.  The
+     * <code>Properties</code> object contains the names and values of the client info
+     * properties to be set.  The set of client info properties contained in
+     * the properties list replaces the current set of client info properties
+     * on the connection.  If a property that is currently set on the
+     * connection is not present in the properties list, that property is
+     * cleared.  Specifying an empty properties list will clear all of the
+     * properties on the connection.  See <code>setClientInfo (String, String)</code> for
+     * more information.
+     * <p>
+     * If an error occurs in setting any of the client info properties, a
+     * <code>SQLClientInfoException</code> is thrown. The <code>SQLClientInfoException</code>
+     * contains information indicating which client info properties were not set.
+     * The state of the client information is unknown because
+     * some databases do not allow multiple client info properties to be set
+     * atomically.  For those databases, one or more properties may have been
+     * set before the error occurred.
+     * <p>
+     *
+     * @param properties                the list of client info properties to set
+     * <p>
+     * @see java.sql.Connection#setClientInfo(String, String) setClientInfo(String, String)
+     * @since JDK 1.6, HSQLDB 2.0
+     * <p>
+     * @throws SQLClientInfoException if the database server returns an error while
+     *                  setting the clientInfo values on the database server or this method
+     * is called on a closed connection
+     * <p>
+     */
+//#ifdef JAVA6
+    public void setClientInfo(
+            Properties properties) throws SQLClientInfoException {
+
+        if (!this.isClosed && (properties == null || properties.isEmpty())) {
+            return;
+        }
+
+        SQLClientInfoException ex = new SQLClientInfoException();
+
+        if (this.isClosed) {
+            ex.initCause(Util.connectionClosedException());
+        } else {
+            ex.initCause(Util.notSupported());
+        }
+
+        throw ex;
+    }
+
+//#endif JAVA6
+
+    /** @todo 1.9.0 */
+
+    /**
+     * Returns the value of the client info property specified by name.  This
+     * method may return null if the specified client info property has not
+     * been set and does not have a default value.  This method will also
+     * return null if the specified client info property name is not supported
+     * by the driver.
+     * <p>
+     * Applications may use the <code>DatabaseMetaData.getClientInfoProperties</code>
+     * method to determine the client info properties supported by the driver.
+     * <p>
+     * @param name              The name of the client info property to retrieve
+     * <p>
+     * @return                  The value of the client info property specified
+     * <p>
+     * @throws SQLException             if the database server returns an error when
+     *                                                  fetching the client info value from the database
+     * or this method is called on a closed connection
+     * <p>
+     * @since JDK 1.6, HSQLDB 2.0
+     * <p>
+     * @see java.sql.DatabaseMetaData#getClientInfoProperties
+     */
+//#ifdef JAVA6
+    public String getClientInfo(String name) throws SQLException {
+
+        checkClosed();
+
+        return null;
+    }
+
+//#endif JAVA6
+
+    /** @todo - 1.9 */
+
+    /**
+     * Returns a list containing the name and current value of each client info
+     * property supported by the driver.  The value of a client info property
+     * may be null if the property has not been set and does not have a
+     * default value.
+     * <p>
+     * @return  A <code>Properties</code> object that contains the name and current value of
+     *                  each of the client info properties supported by the driver.
+     * <p>
+     * @throws  SQLException if the database server returns an error when
+     *                  fetching the client info values from the database
+     * or this method is called on a closed connection
+     * <p>
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public Properties getClientInfo() throws SQLException {
+
+        checkClosed();
+
+        return null;
+    }
+
+//#endif JAVA6
+// --------------------------- Added: Mustang Build 80 -------------------------
+
+    /**
+     * Factory method for creating Array objects.
+     *
+     * @param typeName the SQL name of the type the elements of the array map to. The typeName is a
+     * database-specific name which may be the name of a built-in type, a user-defined type or a standard  SQL type supported by this database. This
+     *  is the value returned by <code>Array.getBaseTypeName</code>
+     * @param elements the elements that populate the returned object
+     * @return an Array object whose elements map to the specified SQL type
+     * @throws SQLException if a database error occurs, the typeName is null or this method is called on a closed connection
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this data type
+     * @since JDK 1.6_b80, HSQLDB 2.0
+     * @revised JDK 1.6_b86 method renamed from createArray to createArrayOf
+     */
+//#ifdef JAVA6
+    public Array createArrayOf(String typeName,
+                               Object[] elements) throws SQLException {
+
+        checkClosed();
+
+        if (typeName == null) {
+            throw Util.nullArgument();
+        }
+
+        typeName = typeName.toUpperCase();
+
+        int typeCode = Type.getTypeNr(typeName);
+
+        if (typeCode < 0) {
+            throw Util.invalidArgument(typeName);
+        }
+
+        Type type = Type.getDefaultType(typeCode);
+
+        Object[] newData = new Object[elements.length];
+        for (int i = 0; i < elements.length; i++) {
+            newData[i] = type.convertJavaToSQL(sessionProxy, elements[i]);
+        }
+        return new JDBCArray(newData, type, this);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Factory method for creating Struct objects.
+     * @param typeName the SQL type name of the SQL structured type that this <code>Struct</code>
+     * object maps to. The typeName is the name of  a user-defined type that
+     * has been defined for this database. It is the value returned by
+     * <code>Struct.getSQLTypeName</code>.
+     * @param attributes the attributes that populate the returned object
+     * @return a Struct object that maps to the given SQL type and is populated with the given attributes
+     * @throws SQLException if a database error occurs, the typeName is null or this method is called on a closed connection
+     * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this data type
+     * @since JDK 1.6_b80, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public Struct createStruct(String typeName,
+                               Object[] attributes) throws SQLException {
+
+        checkClosed();
+
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+// ------------------- java.sql.Wrapper implementation ---------------------
+
+    /**
+     * Returns an object that implements the given interface to allow access to
+     * non-standard methods, or standard methods not exposed by the proxy.
+     *
+     * If the receiver implements the interface then the result is the receiver
+     * or a proxy for the receiver. If the receiver is a wrapper
+     * and the wrapped object implements the interface then the result is the
+     * wrapped object or a proxy for the wrapped object. Otherwise return the
+     * the result of calling <code>unwrap</code> recursively on the wrapped object
+     * or a proxy for that result. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+    public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {
+
+        checkClosed();
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+
+        checkClosed();
+
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+//---------------------- internal implementation ---------------------------
+// -------------------------- Common Attributes ------------------------------
+
+    /** Initial holdability */
+    int rsHoldability = JDBCResultSet.HOLD_CURSORS_OVER_COMMIT;
+
+    /** Properties for the connection */
+    HsqlProperties connProperties;
+
+    /** Properties for the session */
+    HsqlProperties clientProperties;
+
+    /**
+     * This connection's interface to the corresponding Session
+     * object in the database engine.
+     */
+    SessionInterface sessionProxy;
+
+    /**
+     * Is this an internal connection?
+     */
+    boolean isInternal;
+
+    /** Is this connection to a network server instance. */
+    protected boolean isNetConn;
+
+    /**
+     * Is this connection closed?
+     */
+    boolean isClosed;
+
+    /** The first warning in the chain. Null if there are no warnings. */
+    private SQLWarning rootWarning;
+
+    /** Synchronizes concurrent modification of the warning chain */
+    private Object rootWarning_mutex = new Object();
+
+    /** ID sequence for unnamed savepoints */
+    private int savepointIDSequence;
+
+    /** reuse count in ConnectionPool */
+    int incarnation;
+
+    /**
+     * Constructs a new external <code>Connection</code> to an HSQLDB
+     * <code>Database</code>. <p>
+     *
+     * This constructor is called on behalf of the
+     * <code>java.sql.DriverManager</code> when getting a
+     * <code>Connection</code> for use in normal (external)
+     * client code. <p>
+     *
+     * Internal client code, that being code located in HSQLDB SQL
+     * functions and stored procedures, receives an INTERNAL
+     * connection constructed by the {@link
+     * #JDBCConnection(org.hsqldb.SessionInterface)
+     * JDBCConnection(SessionInterface)} constructor. <p>
+     *
+     * @param props A <code>Properties</code> object containing the connection
+     *      properties
+     * @exception SQLException when the user/password combination is
+     *     invalid, the connection url is invalid, or the
+     *     <code>Database</code> is unavailable. <p>
+     *
+     *     The <code>Database</code> may be unavailable for a number
+     *     of reasons, including network problems or the fact that it
+     *     may already be in use by another process.
+     */
+    public JDBCConnection(HsqlProperties props) throws SQLException {
+
+        String user     = props.getProperty("user");
+        String password = props.getProperty("password");
+        String connType = props.getProperty("connection_type");
+        String host     = props.getProperty("host");
+        int    port     = props.getIntegerProperty("port", 0);
+        String path     = props.getProperty("path");
+        String database = props.getProperty("database");
+        boolean isTLS = (connType == DatabaseURL.S_HSQLS
+                         || connType == DatabaseURL.S_HTTPS);
+
+        if (user == null) {
+            user = "SA";
+        }
+
+        if (password == null) {
+            password = "";
+        }
+
+        Calendar cal         = Calendar.getInstance();
+        int      zoneSeconds = HsqlDateTime.getZoneSeconds(cal);
+
+        try {
+            if (DatabaseURL.isInProcessDatabaseType(connType)) {
+
+                /**
+                 * @todo fredt - this should be the only static reference to a core class in
+                 *   the jdbc package - we may make it dynamic
+                 */
+                sessionProxy = DatabaseManager.newSession(connType, database,
+                        user, password, props, null, zoneSeconds);
+            } else if (connType == DatabaseURL.S_HSQL
+                       || connType == DatabaseURL.S_HSQLS) {
+                sessionProxy = new ClientConnection(host, port, path,
+                        database, isTLS, user, password, zoneSeconds);
+                isNetConn = true;
+            } else if (connType == DatabaseURL.S_HTTP
+                       || connType == DatabaseURL.S_HTTPS) {
+                sessionProxy = new ClientConnectionHTTP(host, port, path,
+                        database, isTLS, user, password, zoneSeconds);
+                isNetConn = true;
+            } else {    // alias: type not yet implemented
+                throw Util.invalidArgument(connType);
+            }
+            connProperties   = props;
+            clientProperties = sessionProxy.getClientProperties();
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+    }
+
+    /**
+     * Constructs an <code>INTERNAL</code> <code>Connection</code>,
+     * using the specified {@link org.hsqldb.SessionInterface
+     * SessionInterface}. <p>
+     *
+     * This constructor is called only on behalf of an existing
+     * <code>Session</code> (the internal parallel of a
+     * <code>Connection</code>), to be used as a parameter to a SQL
+     * function or stored procedure that needs to execute in the context
+     * of that <code>Session</code>. <p>
+     *
+     * When a Java SQL function or stored procedure is called and its
+     * first parameter is of type <code>Connection</code>, HSQLDB
+     * automatically notices this and constructs an <code>INTERNAL</code>
+     * <code>Connection</code> using the current <code>Session</code>.
+     * HSQLDB then passes this <code>Connection</code> in the first
+     * parameter position, moving any other parameter values
+     * specified in the SQL statement to the right by one position.
+     * <p>
+     *
+     * To read more about this, see
+     * {@link org.hsqldb.Routine Routine}. <p>
+     *
+     * <B>Notes:</B> <p>
+     *
+     * Starting with HSQLDB 1.7.2, <code>INTERNAL</code> connections are not
+     * closed by a call to close() or by a SQL DISCONNECT.
+     *
+     * For HSQLDB developers not involved with writing database
+     * internals, this change only applies to connections obtained
+     * automatically from the database as the first parameter to
+     * stored procedures and SQL functions. This is mainly an issue
+     * to developers writing custom SQL function and stored procedure
+     * libraries for HSQLDB. Presently, it is recommended that SQL function and
+     * stored procedure code avoid depending on closing or issuing a
+     * DISCONNECT on a connection obtained in this manner. <p>
+     *
+     * @param c the Session requesting the construction of this
+     *     Connection
+     * @exception HsqlException never (reserved for future use);
+     * @see org.hsqldb.Routine
+     */
+    public JDBCConnection(SessionInterface c) {
+
+        // PRE: SessionInterface is non-null
+        isInternal   = true;
+        sessionProxy = c;
+    }
+
+    /**
+     *  The default implementation simply attempts to silently {@link
+     *  #close() close()} this <code>Connection</code>
+     */
+    protected void finalize() {
+
+        try {
+            close();
+        } catch (SQLException e) {
+        }
+    }
+
+    synchronized int getSavepointID() {
+        return savepointIDSequence++;
+    }
+
+    /**
+     * Retrieves this connection's JDBC url.
+     *
+     * This method is in support of the JDBCDatabaseMetaData.getURL() method.
+     * @return the database connection url with which this object was
+     *      constructed
+     * @throws SQLException if this connection is closed
+     */
+    synchronized String getURL() throws SQLException {
+
+        checkClosed();
+
+        return isInternal ? sessionProxy.getInternalConnectionURL()
+                          : connProperties.getProperty("url");
+    }
+
+    /**
+     * An internal check for closed connections. <p>
+     *
+     * @throws SQLException when the connection is closed
+     */
+    synchronized void checkClosed() throws SQLException {
+
+        if (isClosed) {
+            throw Util.connectionClosedException();
+        }
+    }
+
+    /**
+     * Adds another SQLWarning to this Connection object's warning chain.
+     *
+     * @param w the SQLWarning to add to the chain
+     */
+    void addWarning(SQLWarning w) {
+
+        // PRE:  w is never null
+        synchronized (rootWarning_mutex) {
+            if (rootWarning == null) {
+                rootWarning = w;
+            } else {
+                rootWarning.setNextWarning(w);
+            }
+        }
+    }
+
+    /**
+     * Sets the warning chain
+     */
+    void setWarnings(SQLWarning w) {
+
+        synchronized (rootWarning_mutex) {
+            rootWarning = w;
+        }
+    }
+
+    /**
+     * Resets this connection so it can be used again. Used when connections are
+     * returned to a connection pool.
+     *
+     * @throws SQLException if a database access error occurs
+     */
+    public void reset() throws SQLException {
+        try {
+            incarnation++;
+            this.sessionProxy.resetSession();
+        } catch (HsqlException e) {
+            throw Util.sqlException(ErrorCode.X_08006, e.getMessage(), e);
+        }
+    }
+
+    /**
+     * is called from within nativeSQL when the start of an JDBC escape sequence is encountered
+     */
+    private int onStartEscapeSequence(String sql, StringBuffer sb,
+                                      int i) throws SQLException {
+
+        sb.append(' ');
+        i++;
+
+        i = StringUtil.skipSpaces(sql, i);
+
+        if (sql.regionMatches(true, i, "fn ", 0, 3)
+                || sql.regionMatches(true, i, "oj ", 0, 3)) {
+            i+= 2;
+
+        } else if (sql.regionMatches(true, i, "ts ", 0, 3)) {
+            sb.append(Tokens.T_TIMESTAMP);
+            i+= 2;
+
+        } else if (sql.regionMatches(true, i, "d ", 0, 2)) {
+            sb.append(Tokens.T_DATE);
+            i++;
+        } else if (sql.regionMatches(true, i, "t ", 0, 2)) {
+            sb.append(Tokens.T_TIME);
+            i++;
+        } else if (sql.regionMatches(true, i, "call ", 0, 5)) {
+            sb.append(Tokens.T_CALL);
+            i += 4;
+        } else if (sql.regionMatches(true, i, "?= call ", 0, 8)) {
+            sb.append(Tokens.T_CALL);
+            i += 7;
+        } else if (sql.regionMatches(true, i, "? = call ", 0, 8)) {
+            sb.append(Tokens.T_CALL);
+            i += 8;
+        } else if (sql.regionMatches(true, i, "escape ", 0, 7)) {
+            i += 6;
+        } else {
+            i--;
+
+            throw Util.sqlException(
+                Error.error(
+                    ErrorCode.JDBC_CONNECTION_NATIVE_SQL, sql.substring(i)));
+        }
+
+        return i;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCDataSource.java b/src/org/hsqldb/jdbc/JDBCDataSource.java
new file mode 100644
index 0000000..8ebf06e
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCDataSource.java
@@ -0,0 +1,451 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+import javax.naming.StringRefAddr;
+import javax.sql.DataSource;
+
+import org.hsqldb.jdbc.JDBCDriver;
+
+//#ifdef JAVA6
+import java.sql.Wrapper;
+
+import javax.sql.CommonDataSource;
+
+//#endif JAVA6
+
+/* $Id: JDBCDataSource.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+// boucherb@users 20040411 - doc 1.7.2 - javadoc updates toward 1.7.2 final
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+// boucherb@users 20060522 - patch 1.9.0 full synch up to Mustang Build 84
+// Revision 1.12  2006/07/12 12:04:06 boucherb
+// - full synch up to Mustang b90
+//- support new createQueryObject signature
+
+/**
+ * <p>A factory for connections to the physical data source that this
+ * <code>DataSource</code> object represents.  An alternative to the
+ * <code>DriverManager</code> facility, a <code>DataSource</code> object
+ * is the preferred means of getting a connection. An object that implements
+ * the <code>DataSource</code> interface will typically be
+ * registered with a naming service based on the
+ * Java<sup><font size=-2>TM</font></sup> Naming and Directory (JNDI) API.
+ * <P>
+ * The <code>DataSource</code> interface is implemented by a driver vendor.
+ * There are three types of implementations:
+ * <OL>
+ *   <LI>Basic implementation -- produces a standard <code>Connection</code>
+ *       object
+ *   <LI>Connection pooling implementation -- produces a <code>Connection</code>
+ *       object that will automatically participate in connection pooling.  This
+ *       implementation works with a middle-tier connection pooling manager.
+ *   <LI>Distributed transaction implementation -- produces a
+ *       <code>Connection</code> object that may be used for distributed
+ *       transactions and almost always participates in connection pooling.
+ *       This implementation works with a middle-tier
+ *       transaction manager and almost always with a connection
+ *       pooling manager.
+ * </OL>
+ * <P>
+ * A <code>DataSource</code> object has properties that can be modified
+ * when necessary.  For example, if the data source is moved to a different
+ * server, the property for the server can be changed.  The benefit is that
+ * because the data source's properties can be changed, any code accessing
+ * that data source does not need to be changed.
+ * <P>
+ * A driver that is accessed via a <code>DataSource</code> object does not
+ * register itself with the <code>DriverManager</code>.  Rather, a
+ * <code>DataSource</code> object is retrieved though a lookup operation
+ * and then used to create a <code>Connection</code> object.  With a basic
+ * implementation, the connection obtained through a <code>DataSource</code>
+ * object is identical to a connection obtained through the
+ * <code>DriverManager</code> facility.
+ *
+ * @since JDK 1.4
+ * @author deforest@users
+ * @author boucherb@users
+ * @version 2.0
+ * @revised JDK 1.6, HSQLDB 2.0
+ */
+//#ifdef JAVA6
+@SuppressWarnings("serial")
+
+//#endif JAVA6
+public class JDBCDataSource implements Serializable, Referenceable, DataSource
+
+//#ifdef JAVA6
+, CommonDataSource, Wrapper
+
+//#endif JAVA6
+{
+
+    /**
+     * Login timeout
+     */
+    private int loginTimeout = 0;
+
+    /**
+     * Log writer
+     */
+    private transient PrintWriter logWriter;
+
+    /**
+     * Default password to use for connections
+     */
+    private String password = "";
+
+    /**
+     * Default user to use for connections
+     */
+    private String user = "";
+
+    /**
+     * Database location
+     */
+    private String database = "";
+
+    /**
+     * Constructor
+     */
+    public JDBCDataSource() {
+    }
+
+    /**
+     * <p>Attempts to establish a connection with the data source that
+     * this <code>DataSource</code> object represents.
+     *
+     * @return  a connection to the data source
+     * @exception SQLException if a database access error occurs
+     */
+    public Connection getConnection() throws SQLException {
+        return getConnection(user, password);
+    }
+
+    /**
+     * <p>Attempts to establish a connection with the data source that
+     * this <code>DataSource</code> object represents.
+     *
+     * @param username the database user on whose behalf the connection is
+     *  being made
+     * @param password the user's password
+     * @return  a connection to the data source
+     * @exception SQLException if a database access error occurs
+     */
+    public Connection getConnection(String username,
+                                    String password) throws SQLException {
+
+        Properties props = new Properties();
+
+        if (username != null) {
+            props.put("user", username);
+        }
+
+        if (password != null) {
+            props.put("password", password);
+        }
+
+        return JDBCDriver.getConnection(database, props);
+    }
+
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * Creates a concrete implementation of a Query interface using the JDBC drivers <code>QueryObjectGenerator</code>
+     * implementation.
+     * <p>
+     * If the JDBC driver does not provide its own <code>QueryObjectGenerator</code>, the <code>QueryObjectGenerator</code>
+     * provided with Java SE will be used.
+     * <p>
+     * @param ifc The Query interface that will be created
+     * @return A concrete implementation of a Query interface
+     * @exception SQLException if a database access error occurs.
+     *  @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6BETA
+/*
+   public <T extends BaseQuery> T createQueryObject(Class<T> ifc) throws SQLException {
+        return QueryObjectFactory.createDefaultQueryObject(ifc, this);
+   }
+*/
+
+//#endif JAVA6BETA
+
+    /**
+     * Creates a concrete implementation of a Query interface using the JDBC drivers <code>QueryObjectGenerator</code>
+     * implementation.
+     * <p>
+     * If the JDBC driver does not provide its own <code>QueryObjectGenerator</code>, the <code>QueryObjectGenerator</code>
+     * provided with Java SE will be used.
+     * <p>
+     * This method is primarly for developers of Wrappers to JDBC implementations.
+     * Application developers should use <code>createQueryObject(Class&LT;T&GT; ifc).
+     * <p>
+     * @param ifc The Query interface that will be created
+     * @param ds The <code>DataSource</code> that will be used when invoking methods that access
+     * the data source. The QueryObjectGenerator implementation will use
+     * this <code>DataSource</code> without any unwrapping or modications
+     * to create connections to the data source.
+     *
+     * @return An concrete implementation of a Query interface
+     * @exception SQLException if a database access error occurs.
+     * @since 1.6
+     */
+//#ifdef JAVA6BETA
+/*
+    public <T extends BaseQuery> T createQueryObject(Class<T> ifc, DataSource ds) throws SQLException {
+        return QueryObjectFactory.createQueryObject(ifc, ds);
+    }
+*/
+
+//#endif JAVA6BETA
+
+    /**
+     * Retrieves the QueryObjectGenerator for the given JDBC driver.  If the
+     * JDBC driver does not provide its own QueryObjectGenerator, NULL is
+     * returned.
+     * @return The QueryObjectGenerator for this JDBC Driver or NULL if the driver does not provide its own
+     * implementation
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JDBC4BETA
+/*
+    public QueryObjectGenerator getQueryObjectGenerator() throws SQLException {
+        return null;
+    }
+*/
+
+//#endif JDBC4BETA
+    // ------------------- java.sql.Wrapper implementation ---------------------
+
+    /**
+     * Returns an object that implements the given interface to allow access to
+     * non-standard methods, or standard methods not exposed by the proxy.
+     *
+     * If the receiver implements the interface then the result is the receiver
+     * or a proxy for the receiver. If the receiver is a wrapper
+     * and the wrapped object implements the interface then the result is the
+     * wrapped object or a proxy for the wrapped object. Otherwise return the
+     * the result of calling <code>unwrap</code> recursively on the wrapped object
+     * or a proxy for that result. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+    public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+    // ------------------------ internal implementation ------------------------
+
+    /**
+     * Retrieves the jdbc database connection url attribute. <p>
+     *
+     * @return the jdbc database connection url attribute
+     */
+    public String getDatabase() {
+        return database;
+    }
+
+    /**
+     * Gets the maximum time in seconds that this data source can wait
+     * while attempting to connect to a database.  A value of zero
+     * means that the timeout is the default system timeout
+     * if there is one; otherwise, it means that there is no timeout.
+     * When a <code>DataSource</code> object is created, the login timeout is
+     * initially zero.
+     *
+     * @return the data source login time limit
+     * @exception SQLException if a database access error occurs.
+     * @see #setLoginTimeout
+     * @see #setLoginTimeout
+     */
+    public int getLoginTimeout() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * <p>Retrieves the log writer for this <code>DataSource</code>
+     * object.
+     *
+     * <p>The log writer is a character output stream to which all logging
+     * and tracing messages for this data source will be
+     * printed.  This includes messages printed by the methods of this
+     * object, messages printed by methods of other objects manufactured
+     * by this object, and so on.  Messages printed to a data source
+     * specific log writer are not printed to the log writer associated
+     * with the <code>java.sql.Drivermanager</code> class.  When a
+     * <code>DataSource</code> object is
+     * created, the log writer is initially null; in other words, the
+     * default is for logging to be disabled.
+     *
+     * @return the log writer for this data source or null if
+     *        logging is disabled
+     * @exception SQLException if a database access error occurs
+     * @see #setLogWriter
+     */
+    public java.io.PrintWriter getLogWriter() throws SQLException {
+        return logWriter;
+    }
+
+    // javadoc to be copied from javax.naming.Referenceable.getReference()
+    public Reference getReference() throws NamingException {
+
+        String    cname = "org.hsqldb.jdbc.JDBCDataSourceFactory";
+        Reference ref   = new Reference(getClass().getName(), cname, null);
+
+        ref.add(new StringRefAddr("database", getDatabase()));
+        ref.add(new StringRefAddr("user", getUser()));
+        ref.add(new StringRefAddr("password", password));
+
+        return ref;
+    }
+
+    /**
+     * Retrieves the user ID for the connection. <p>
+     *
+     * @return the user ID for the connection
+     */
+    public String getUser() {
+        return user;
+    }
+
+    /**
+     * Assigns the value of this object's jdbc database connection
+     * url attribute. <p>
+     *
+     * @param database the new value of this object's jdbc database connection
+     *      url attribute
+     */
+    public void setDatabase(String database) {
+        this.database = database;
+    }
+
+    /**
+     * <p>Sets the maximum time in seconds that this data source will wait
+     * while attempting to connect to a database.  A value of zero
+     * specifies that the timeout is the default system timeout
+     * if there is one; otherwise, it specifies that there is no timeout.
+     * When a <code>DataSource</code> object is created, the login timeout is
+     * initially zero.
+     *
+     * @param seconds the data source login time limit
+     * @exception SQLException if a database access error occurs.
+     * @see #getLoginTimeout
+     */
+    public void setLoginTimeout(int seconds) throws SQLException {
+        loginTimeout = 0;
+    }
+
+    /**
+     * <p>Sets the log writer for this <code>DataSource</code>
+     * object to the given <code>java.io.PrintWriter</code> object.
+     *
+     * <p>The log writer is a character output stream to which all logging
+     * and tracing messages for this data source will be
+     * printed.  This includes messages printed by the methods of this
+     * object, messages printed by methods of other objects manufactured
+     * by this object, and so on.  Messages printed to a data source-
+     * specific log writer are not printed to the log writer associated
+     * with the <code>java.sql.DriverManager</code> class. When a
+     * <code>DataSource</code> object is created the log writer is
+     * initially null; in other words, the default is for logging to be
+     * disabled.
+     *
+     * @param logWriter the new log writer; to disable logging, set to null
+     * @exception SQLException if a database access error occurs
+     * @see #getLogWriter
+     */
+    public void setLogWriter(PrintWriter logWriter) throws SQLException {
+        this.logWriter = logWriter;
+    }
+
+    /**
+     * Sets the password to use for connecting to the database
+     * @param password the password
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * Sets the userid
+     * @param user the user id
+     */
+    public void setUser(String user) {
+        this.user = user;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCDataSourceFactory.java b/src/org/hsqldb/jdbc/JDBCDataSourceFactory.java
new file mode 100644
index 0000000..9171e21
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCDataSourceFactory.java
@@ -0,0 +1,86 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.Reference;
+import javax.naming.spi.ObjectFactory;
+
+// boucherb@users 20040411 - doc 1.7.2 - javadoc updates toward 1.7.2 final
+
+/**
+ * A JNDI ObjectFactory for creating {@link JDBCDataSource JDBCDataSource}
+ * object instances.
+ *
+ * @author deforest@users
+ * @version 1.7.2
+ */
+public class JDBCDataSourceFactory implements ObjectFactory {
+
+    /**
+     * Creates a JDBCDataSource object using the location or reference
+     * information specified.<p>
+     *
+     * The Reference object should support the properties, database, user,
+     * password.
+     *
+     * @param obj The reference information used in creating a
+     *      JDBCDatasource object.
+     * @param name ignored
+     * @param nameCtx ignored
+     * @param environment ignored
+     * @return A newly created JDBCDataSource object; null if an object
+     *      cannot be created.
+     * @exception Exception never
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment) throws Exception {
+
+        String    dsClass = "org.hsqldb.jdbc.JDBCDataSource";
+        Reference ref     = (Reference) obj;
+
+        if (ref.getClassName().equals(dsClass)) {
+            JDBCDataSource ds = new JDBCDataSource();
+
+            ds.setDatabase((String) ref.get("database").getContent());
+            ds.setUser((String) ref.get("user").getContent());
+            ds.setPassword((String) ref.get("password").getContent());
+
+            return ds;
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCDatabaseMetaData.java b/src/org/hsqldb/jdbc/JDBCDatabaseMetaData.java
new file mode 100644
index 0000000..62c4b49
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCDatabaseMetaData.java
@@ -0,0 +1,6166 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+
+//#ifdef JAVA6
+import java.sql.RowIdLifetime;
+
+//#endif JAVA6
+import java.sql.SQLException;
+
+import org.hsqldb.FunctionCustom;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.types.Type;
+
+/* $Id: JDBCDatabaseMetaData.java 3617 2010-06-03 00:42:34Z fredt $ */
+
+// fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
+// JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
+//
+// boucherb &     20020409 - extensive review and update of docs and behaviour
+// fredt@users  - 20020505   to comply with previous and latest java.sql
+//                           specification
+// boucherb@users 20020509 - update to JDK 1.4 / JDBC3 methods and docs
+// boucherb@users 2002     - extensive rewrite to support new
+//              - 20030121   1.7.2 system table and metadata features.
+// boucherb@users 20040422 - doc 1.7.2 - javadoc updates toward 1.7.2 final
+// fredt@users    20050505 - patch 1.8.0 - enforced JDBC rules for non-pattern params
+// boucherb@users 20051207 - update to JDK 1.6 JDBC 4.0 methods and docs
+//              - 20060709
+// fredt@users    20080805 - full review and update to doc and method return values
+
+/**
+ * @todo 1.9.0 - fredt - revise all selects from system tables to use
+ *  SQL/SCHEMATA views with column renaming to JDBC spec
+ */
+// Revision 1.20  2006/07/12 12:06:54  boucherb
+// patch 1.9.0
+// - java.sql.Wrapper implementation section title added
+// Revision 1.19  2006/07/09 07:07:01  boucherb
+// - getting the CVS Log variable ouptut format right
+//
+// Revision 1.18  2006/07/09 07:02:38  boucherb
+// - patch 1.9.0 full synch up to Mustang Build 90
+// - getColumns() (finally!!!) officially includes IS_AUTOINCREMENT
+//
+
+/**
+ * Comprehensive information about the database as a whole.
+ * <P>
+ * This interface is implemented by driver vendors to let users know the capabilities
+ * of a Database Management System (DBMS) in combination with
+ * the driver based on JDBC<sup><font size=-2>TM</font></sup> technology
+ * ("JDBC driver") that is used with it.  Different relational DBMSs often support
+ * different features, implement features in different ways, and use different
+ * data types.  In addition, a driver may implement a feature on top of what the
+ * DBMS offers.  Information returned by methods in this interface applies
+ * to the capabilities of a particular driver and a particular DBMS working
+ * together. Note that as used in this documentation, the term "database" is
+ * used generically to refer to both the driver and DBMS.
+ * <P>
+ * A user for this interface is commonly a tool that needs to discover how to
+ * deal with the underlying DBMS.  This is especially true for applications
+ * that are intended to be used with more than one DBMS. For example, a tool might use the method
+ * <code>getTypeInfo</code> to find out what data types can be used in a
+ * <code>CREATE TABLE</code> statement.  Or a user might call the method
+ * <code>supportsCorrelatedSubqueries</code> to see if it is possible to use
+ * a correlated subquery or <code>supportsBatchUpdates</code> to see if it is
+ * possible to use batch updates.
+ * <P>
+ * Some <code>DatabaseMetaData</code> methods return lists of information
+ * in the form of <code>ResultSet</code> objects.
+ * Regular <code>ResultSet</code> methods, such as
+ * <code>getString</code> and <code>getInt</code>, can be used
+ * to retrieve the data from these <code>ResultSet</code> objects.  If
+ * a given form of metadata is not available, an empty <code>ResultSet</code>
+ * will be returned. Additional columns beyond the columns defined to be
+ * returned by the <code>ResultSet</code> object for a given method
+ * can be defined by the JDBC driver vendor and must be accessed
+ * by their <B>column label</B>.
+ * <P>
+ * Some <code>DatabaseMetaData</code> methods take arguments that are
+ * String patterns.  These arguments all have names such as fooPattern.
+ * Within a pattern String, "%" means match any substring of 0 or more
+ * characters, and "_" means match any one character. Only metadata
+ * entries matching the search pattern are returned. If a search pattern
+ * argument is set to <code>null</code>, that argument's criterion will
+ * be dropped from the search.
+ * <P>
+ * A method that gets information about a feature that the driver does not
+ * support will throw an <code>SQLException</code>.
+ * In the case of methods that return a <code>ResultSet</code>
+ * object, either a <code>ResultSet</code> object (which may be empty) is
+ * returned or an <code>SQLException</code> is thrown.
+ *
+ * <!-- start release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * Starting with HSQLDB 1.7.2, an option is provided to allow alternate
+ * system table production implementations.  In this distribution, there are
+ * three implementations whose behaviour ranges from producing no system
+ * tables at all to producing a richer and more complete body of information
+ * about an HSQLDB database than was previously available. The information
+ * provided through the default implementation is, unlike previous
+ * versions, accessible to all database users, regardless of admin status.
+ * This is now possible because the table content it produces for each
+ * user is pre-filtered, based on the user's access rights. That is, each
+ * system table now acts like a security-aware View.<p>
+ *
+ * The process of installing a system table production class is transparent and
+ * occurs dynamically at runtime during the opening sequence of a
+ * <code>Database</code> instance, in the newDatabaseInformation() factory
+ * method of the revised DatabaseInformation class, using the following
+ * steps: <p>
+ *
+ * <div class="GeneralExample">
+ * <ol>
+ * <li>If a class whose fully qualified name is org.hsqldb.dbinfo.DatabaseInformationFull
+ *     can be found and it has an accesible constructor that takes an
+ *     org.hsqldb.Database object as its single parameter, then an instance of
+ *     that class is reflectively instantiated and is used by the database
+ *     instance to produce its system tables. <p>
+ *
+ * <li>If 1.) fails, then the process is repeated, attempting to create an
+ *     instance of org.hsqldb.dbinfo.DatabaseInformationMain (which provides just the
+ *     core set of system tables required to service this class, but now does
+ *     so in a more security aware and comprehensive fashion). <p>
+ *
+ * <li>If 2.) fails, then an instance of org.hsqldb.dbinfo.DatabaseInformation is
+ *     installed (that, by default, produces no system tables, meaning that
+ *     calls to all related methods in this class will fail, throwing an
+ *     SQLException stating that a required system table is not found). <p>
+ *
+ * </ol>
+ * </div> <p>
+ *
+ * The process of searching for alternate implementations of database
+ * support classes, ending with the installation of a minimal but functional
+ * default will be refered to henceforth as <i>graceful degradation</i>.
+ * This process is advantageous in that it allows developers and administrators
+ * to easily choose packaging options, simply by adding to or deleting concerned
+ * classes from an  HSQLDB installation, without worry over providing complex
+ * initialization properties or disrupting the core operation of the engine.
+ * In this particular context, <i>graceful degradation</i> allows easy choices
+ * regarding database metadata, spanning the range of full (design-time),
+ * custom-written, minimal (production-time) or <CODE>null</CODE>
+ * (space-constrained) system table production implementations. <p>
+ *
+ * In the default full implementation, a number of new system tables are
+ * provided that, although not used directly by this class, present previously
+ * unavailable information about the database, such as about its triggers and
+ * aliases. <p>
+ *
+ * In order to better support graphical database exploration tools and as an
+ * experimental intermediate step toward more fully supporting SQL9n and
+ * SQL200n, the default installed DatabaseInformation implementation
+ * is also capable of reporting pseudo name space information, such as
+ * the catalog (database URI) of database objects. <p>
+ *
+ * The catalog reporting feature is turned off by default but
+ * can be turned on by providing the appropriate entries in the database
+ * properties file (see the advanced topics section of the product
+ * documentation). <p>
+ *
+ * When the feature is turned on, catalog is reported using
+ * the following conventions: <p>
+ *
+ * <ol>
+ * <li>All objects are reported as having a catalog equal to the URI of the
+ *     database, which is equivalent to the catenation of the
+ *     <b>&lt;type&gt;</b> and <b>&lt;path&gt;</b> portions of the HSQLDB
+ *     internal JDBC connection URL.<p>
+ *
+ *     Examples: <p>
+ *
+ *     <pre class="JavaCodeExample">
+ *     <span class="JavaStringLiteral">&quot;jdbc:hsqldb:file:test&quot;</span>      => <span class="JavaStringLiteral">&quot;file:test&quot;</span>
+ *     <span class="JavaStringLiteral">&quot;jdbc:hsqldb:mem:.&quot;</span>          => <span class="JavaStringLiteral">&quot;mem:.&quot;</span>
+ *     <span class="JavaStringLiteral">&quot;jdbc:hsqldb:hsql:/host/<alias>...&quot;</span> => URI of aliased database
+ *     <span class="JavaStringLiteral">&quot;jdbc:hsqldb:http:/host/<alias>...&quot;</span> => URI of aliased database
+ *     </pre>
+ *
+ *     <b>Note:</b> No provision is made for qualifying database objects
+ *     by catalog in DML or DDL SQL.  This feature is functional only with
+ *     respect to browsing the database through the DatabaseMetaData and system
+ *     table interfaces. <p>
+ *
+ * </ol>
+ *
+ * Again, it should be well understood that this feature provide an
+ * <i>emulation</i> of catalog support and is intended only
+ * as an experimental implementation to enhance the browsing experience
+ * when using graphical database explorers and to make a first foray
+ * into tackling the issue of implementing true catalog support
+ * in the future. <p>
+ *
+ * Due the nature of the new database system table production process, fewer
+ * assumptions can be made by this class about what information is made
+ * available in the system tables supporting <code>DatabaseMetaData</code>
+ * methods. Because of this, the SQL queries behind the <code>ResultSet</code>
+ * producing methods have been cleaned up and made to adhere more strictly to
+ * the JDBC contracts specified in relation to the method parameters. <p>
+ *
+ * One of the remaining assumptions concerns the <code>approximate</code>
+ * argument of {@link #getIndexInfo getIndexInfo()}. This parameter is still
+ * ignored since there is not yet any process in place to internally gather
+ * and persist table and index statistics.  A primitive version of a statistics
+ * gathering and reporting subsystem <em>may</em> be introduced at some time in
+ * the future. <p>
+ *
+ * Another assumption is that simple select queries against certain system
+ * tables will return rows in JDBC contract order in the absence of an
+ * &quot;ORDER BY&quot; clause.  The reason for this is that results
+ * come back much faster when no &quot;ORDER BY&quot; clause is used.
+ * Developers wishing to extend or replace an existing system table production
+ * class should be aware of this, either adding the contract
+ * &quot;ORDER BY&quot; clause to the SQL in corresponding methods in this class,
+ * or, better, by maintaing rows in the correct order in the underlying
+ * system tables, prefereably by creating appropriate primary indices. <p>
+ *
+ * <hr>
+ *
+ * <b>JRE 1.1.x Notes:</b> <p>
+ *
+ * In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ * Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ * versions of JDBC depends on the JDK version used for compiling and building
+ * HSQLDB.<p>
+ *
+ * Since 1.7.0, it is possible to build the product so that
+ * all JDBC 2 methods can be called while executing under the version 1.1.x
+ * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ * However, some of these method calls require <code>int</code> values that
+ * are defined only in the JDBC 2 or greater version of the
+ * {@link java.sql.ResultSet ResultSet} interface.  For this reason, when the
+ * product is compiled under JDK 1.1.x, these values are defined in
+ * {@link JDBCResultSet JDBCResultSet}.<p>
+ *
+ * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ * JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ * to them in parameter specifications and return value comparisons,
+ * respectively, as follows: <p>
+ *
+ * <pre class="JavaCodeExample">
+ * JDBCResultSet.FETCH_FORWARD
+ * JDBCResultSet.TYPE_FORWARD_ONLY
+ * JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ * JDBCResultSet.CONCUR_READ_ONLY
+ * // etc
+ * </pre>
+ *
+ * However, please note that code written in such a manner will not be
+ * compatible for use with other JDBC 2 drivers, since they expect and use
+ * <code>ResultSet</code>, rather than <code>JDBCResultSet</code>.  Also
+ * note, this feature is offered solely as a convenience to developers
+ * who must work under JDK 1.1.x due to operating constraints, yet wish to
+ * use some of the more advanced features available under the JDBC 2
+ * specification.<p>
+ *
+ * (fredt@users)<br>
+ * (boucherb@users)
+ * </div>
+ * <!-- end release-specific documentation -->
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @revised JDK 1.6, HSQLDB 2.0
+ * @see org.hsqldb.dbinfo.DatabaseInformation
+ * @see org.hsqldb.dbinfo.DatabaseInformationMain
+ * @see org.hsqldb.dbinfo.DatabaseInformationFull
+ */
+//#ifdef JAVA6
+public class JDBCDatabaseMetaData implements DatabaseMetaData,
+        java.sql.Wrapper {
+
+//#else
+/*
+public class JDBCDatabaseMetaData implements DatabaseMetaData {
+*/
+
+//#endif
+    //----------------------------------------------------------------------
+    // First, a variety of minor information about the target database.
+
+    /**
+     * Retrieves whether the current user can call all the procedures
+     * returned by the method <code>getProcedures</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * This method still <em>always</em> returns
+     * <code>true</code>. <p>
+     *
+     * In a future release, the plugin interface may be modified to allow
+     * implementors to report different values here, based on their
+     * implementations.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean allProceduresAreCallable() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether the current user can use all the tables returned
+     * by the method <code>getTables</code> in a <code>SELECT</code>
+     * statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB always reports <code>true</code>.<p>
+     *
+     * Please note that the default HSQLDB <code>getTables</code> behaviour is
+     * omit from the list of <em>requested</em> tables only those to which the
+     * invoking user has <em>no</em> access of any kind. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean allTablesAreSelectable() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves the URL for this DBMS.
+     *
+     * @return the URL for this DBMS or <code>null</code> if it cannot be
+     *          generated
+     * @exception SQLException if a database access error occurs
+     */
+    public String getURL() throws SQLException {
+        return connection.getURL();
+    }
+
+    /**
+     * Retrieves the user name as known to this database.
+     *
+     * @return the database user name
+     * @exception SQLException if a database access error occurs
+     */
+    public String getUserName() throws SQLException {
+
+        ResultSet rs = execute("CALL USER()");
+
+        rs.next();
+
+        String result = rs.getString(1);
+
+        rs.close();
+
+        return result;
+    }
+
+    /**
+     * Retrieves whether this database is in read-only mode.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.7.2, this makes
+     * an SQL call to the new isReadOnlyDatabase function
+     * which provides correct determination of the read-only status for
+     * both local and remote database instances.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isReadOnly() throws SQLException {
+
+        ResultSet rs = execute("CALL isReadOnlyDatabase()");
+
+        rs.next();
+
+        boolean result = rs.getBoolean(1);
+
+        rs.close();
+
+        return result;
+    }
+
+    /**
+     * Retrieves whether <code>NULL</code> values are sorted high.
+     * Sorted high means that <code>NULL</code> values
+     * sort higher than any other value in a domain.  In an ascending order,
+     * if this method returns <code>true</code>,  <code>NULL</code> values
+     * will appear at the end. By contrast, the method
+     * <code>nullsAreSortedAtEnd</code> indicates whether <code>NULL</code> values
+     * are sorted at the end regardless of sort order.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * By default HSQLDB sorts null at start; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean nullsAreSortedHigh() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether <code>NULL</code> values are sorted low.
+     * Sorted low means that <code>NULL</code> values
+     * sort lower than any other value in a domain.  In an ascending order,
+     * if this method returns <code>true</code>,  <code>NULL</code> values
+     * will appear at the beginning. By contrast, the method
+     * <code>nullsAreSortedAtStart</code> indicates whether <code>NULL</code> values
+     * are sorted at the beginning regardless of sort order.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * By default HSQLDB sorts null at the start; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean nullsAreSortedLow() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether <code>NULL</code> values are sorted at the start regardless
+     * of sort order.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * By default HSQLDB sorts null at the start; this method always returns <code>true</code>.
+     * Use NULLS LAST in the ORDER BY clause to sort null at the end.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean nullsAreSortedAtStart() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether <code>NULL</code> values are sorted at the end regardless of
+     * sort order.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * By default HSQLDB sorts null at the start; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean nullsAreSortedAtEnd() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves the name of this database product.
+     *
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Returns the name of the HSQLDB engine.
+     * </div> <p>
+     *
+     * @return database product name
+     * @exception SQLException if a database access error occurs
+     */
+    public String getDatabaseProductName() throws SQLException {
+        return HsqlDatabaseProperties.PRODUCT_NAME;
+    }
+
+    /**
+     * Retrieves the version number of this database product.
+     *
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Returns the full version string.
+     * </div> <p>
+     *
+     * @return database version number
+     * @exception SQLException if a database access error occurs
+     */
+    public String getDatabaseProductVersion() throws SQLException {
+
+        ResultSet rs = execute("call database_version()");
+
+        rs.next();
+
+        return rs.getString(1);
+    }
+
+    /**
+     * Retrieves the name of this JDBC driver.
+     *
+     * @return JDBC driver name
+     * @exception SQLException if a database access error occurs
+     */
+    public String getDriverName() throws SQLException {
+        return HsqlDatabaseProperties.PRODUCT_NAME + " Driver";
+    }
+
+    /**
+     * Retrieves the version number of this JDBC driver as a <code>String</code>.
+     *
+     * @return JDBC driver version
+     * @exception SQLException if a database access error occurs
+     */
+    public String getDriverVersion() throws SQLException {
+        return HsqlDatabaseProperties.THIS_VERSION;
+    }
+
+    /**
+     * Retrieves this JDBC driver's major version number.
+     *
+     * @return JDBC driver major version
+     */
+    public int getDriverMajorVersion() {
+        return HsqlDatabaseProperties.MAJOR;
+    }
+
+    /**
+     * Retrieves this JDBC driver's minor version number.
+     *
+     * @return JDBC driver minor version number
+     */
+    public int getDriverMinorVersion() {
+        return HsqlDatabaseProperties.MINOR;
+    }
+
+    /**
+     * Retrieves whether this database stores tables in a local file.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From HSQLDB 1.7.2 it is assumed that this refers to data being stored
+     * by the JDBC client. This method always returns false.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean usesLocalFiles() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database uses a file for each table.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not use a file for each table.
+     * This method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if this database uses a local file for each table;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean usesLocalFilePerTable() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database treats mixed case unquoted SQL identifiers as
+     * case sensitive and as a result stores them in mixed case.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB treats unquoted identifiers as case insensitive and stores
+     * them in upper case. It treats quoted identifiers as case sensitive and
+     * stores them verbatim; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsMixedCaseIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database treats mixed case unquoted SQL identifiers as
+     * case insensitive and stores them in upper case.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB treats unquoted identifiers as case insensitive and stores
+     * them in upper case. It treats quoted identifiers as case sensitive and
+     * stores them verbatim; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean storesUpperCaseIdentifiers() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database treats mixed case unquoted SQL identifiers as
+     * case insensitive and stores them in lower case.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB treats unquoted identifiers as case insensitive and stores
+     * them in upper case. It treats quoted identifiers as case sensitive and
+     * stores them verbatim; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean storesLowerCaseIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database treats mixed case unquoted SQL identifiers as
+     * case insensitive and stores them in mixed case.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB treats unquoted identifiers as case insensitive and stores
+     * them in upper case. It treats quoted identifiers as case sensitive and
+     * stores them verbatim; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean storesMixedCaseIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database treats mixed case quoted SQL identifiers as
+     * case sensitive and as a result stores them in mixed case.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB treats unquoted identifiers as case insensitive and stores
+     * them in upper case. It treats quoted identifiers as case sensitive and
+     * stores them verbatim; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database treats mixed case quoted SQL identifiers as
+     * case insensitive and stores them in upper case.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB treats unquoted identifiers as case insensitive and stores
+     * them in upper case. It treats quoted identifiers as case sensitive and
+     * stores them verbatim; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database treats mixed case quoted SQL identifiers as
+     * case insensitive and stores them in lower case.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB treats unquoted identifiers as case insensitive and stores
+     * them in upper case. It treats quoted identifiers as case sensitive and
+     * stores them verbatim; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database treats mixed case quoted SQL identifiers as
+     * case insensitive and stores them in mixed case.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB treats unquoted identifiers as case insensitive and stores
+     * them in upper case. It treats quoted identifiers as case sensitive and
+     * stores them verbatim; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves the string used to quote SQL identifiers.
+     * This method returns a space " " if identifier quoting is not supported.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB uses the standard SQL identifier quote character
+     * (the double quote character); this method always returns <b>"</b>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return the quoting string or a space if quoting is not supported
+     * @exception SQLException if a database access error occurs
+     */
+    public String getIdentifierQuoteString() throws SQLException {
+        return "\"";
+    }
+
+    /**
+     * Retrieves a comma-separated list of all of this database's SQL keywords
+     * that are NOT also SQL:2003 keywords.
+     * (JDBC4 modified => SQL:2003)
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The list is empty. However, HSQLDB also supports SQL:2008 keywords
+     * and disallows them for database object names without double quoting.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return the list of this database's keywords that are not also
+     *         SQL:2003 keywords
+     *         (JDBC4 modified => SQL:2003)
+     * @exception SQLException if a database access error occurs
+     */
+    public String getSQLKeywords() throws SQLException {
+        return "";
+    }
+
+    /**
+     * Retrieves a comma-separated list of math functions available with
+     * this database.  These are the Open /Open CLI math function names used in
+     * the JDBC function escape clause.
+     *
+     * @return the list of math functions supported by this database
+     * @exception SQLException if a database access error occurs
+     */
+    public String getNumericFunctions() throws SQLException {
+        return StringUtil.getList(FunctionCustom.openGroupNumericFunctions,
+                                  ",", "");
+    }
+
+    /**
+     * Retrieves a comma-separated list of string functions available with
+     * this database.  These are the  Open Group CLI string function names used
+     * in the JDBC function escape clause.
+     *
+     * @return the list of string functions supported by this database
+     * @exception SQLException if a database access error occurs
+     */
+    public String getStringFunctions() throws SQLException {
+        return StringUtil.getList(FunctionCustom.openGroupStringFunctions,
+                                  ",", "");
+    }
+
+    /**
+     * Retrieves a comma-separated list of system functions available with
+     * this database.  These are the  Open Group CLI system function names used
+     * in the JDBC function escape clause.
+     *
+     * @return a list of system functions supported by this database
+     * @exception SQLException if a database access error occurs
+     */
+    public String getSystemFunctions() throws SQLException {
+        return StringUtil.getList(FunctionCustom.openGroupSystemFunctions,
+                                  ",", "");
+    }
+
+    /**
+     * Retrieves a comma-separated list of the time and date functions available
+     * with this database.
+     *
+     * @return the list of time and date functions supported by this database
+     * @exception SQLException if a database access error occurs
+     */
+    public String getTimeDateFunctions() throws SQLException {
+        return StringUtil.getList(FunctionCustom.openGroupDateTimeFunctions,
+                                  ",", "");
+    }
+
+    /**
+     * Retrieves the string that can be used to escape wildcard characters.
+     * This is the string that can be used to escape '_' or '%' in
+     * the catalog search parameters that are a pattern (and therefore use one
+     * of the wildcard characters).
+     *
+     * <P>The '_' character represents any single character;
+     * the '%' character represents any sequence of zero or
+     * more characters.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB uses the "\" character to escape wildcard characters.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return the string used to escape wildcard characters
+     * @exception SQLException if a database access error occurs
+     */
+    public String getSearchStringEscape() throws SQLException {
+        return "\\";
+    }
+
+    /**
+     * Retrieves all the "extra" characters that can be used in unquoted
+     * identifier names (those beyond a-z, A-Z, 0-9 and _).
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support using any "extra" characters in unquoted
+     * identifier names; this method always returns the empty String.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return the string containing the extra characters
+     * @exception SQLException if a database access error occurs
+     */
+    public String getExtraNameCharacters() throws SQLException {
+        return "";
+    }
+
+    //--------------------------------------------------------------------
+    // Functions describing which features are supported.
+
+    /**
+     * Retrieves whether this database supports <code>ALTER TABLE</code>
+     * with add column.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 1.7.0, HSQLDB supports this type of
+     * <code>ALTER TABLE</code> statement; this method always
+     * returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsAlterTableWithAddColumn() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports <code>ALTER TABLE</code>
+     * with drop column.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 1.7.0, HSQLDB supports this type of
+     * <code>ALTER TABLE</code> statement; this method always
+     * returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsAlterTableWithDropColumn() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports column aliasing.
+     *
+     * <P>If so, the SQL AS clause can be used to provide names for
+     * computed columns or to provide alias names for columns as
+     * required.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports column aliasing; this method always
+     * returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsColumnAliasing() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports concatenations between
+     * <code>NULL</code> and non-<code>NULL</code> values being
+     * <code>NULL</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this; this method always
+     * returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean nullPlusNonNullIsNull() throws SQLException {
+        return true;
+    }
+
+    /**
+     * (JDBC4 clarification:)
+     * Retrieves whether this database supports the JDBC scalar function
+     * <code>CONVERT</code> for the conversion of one JDBC type to another.
+     * The JDBC types are the generic SQL data types defined
+     * in <code>java.sql.Types</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports conversions; this method always
+     * returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsConvert() throws SQLException {
+        return true;
+    }
+
+    /** @todo needs the full conversion matrix here. Should use org.hsqldb.types */
+
+    /**
+     * (JDBC4 clarification:)
+     * Retrieves whether this database supports the JDBC scalar function
+     * <code>CONVERT</code> for conversions between the JDBC types <i>fromType</i>
+     * and <i>toType</i>.  The JDBC types are the generic SQL data types defined
+     * in <code>java.sql.Types</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports conversion according to SQL standards. In addition,
+     * it supports conversion between values of BOOLEAN and BIT types.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @param fromType the type to convert from; one of the type codes from
+     *        the class <code>java.sql.Types</code>
+     * @param toType the type to convert to; one of the type codes from
+     *        the class <code>java.sql.Types</code>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @see java.sql.Types
+     */
+    public boolean supportsConvert(int fromType,
+                                   int toType) throws SQLException {
+
+        Type from =
+            Type.getDefaultTypeWithSize(Type.getHSQLDBTypeCode(fromType));
+        Type to = Type.getDefaultTypeWithSize(Type.getHSQLDBTypeCode(toType));
+
+        if (from == null || to == null) {
+            return false;
+        }
+
+        return to.canConvertFrom(from);
+    }
+
+    /**
+     * Retrieves whether this database supports table correlation names.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports table correlation names; this method always
+     * returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsTableCorrelationNames() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether, when table correlation names are supported, they
+     * are restricted to being different from the names of the tables.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB requires that table correlation names are different from the
+     * names of the tables; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports expressions in
+     * <code>ORDER BY</code> lists.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports expressions in <code>ORDER BY</code> lists; this
+     * method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsExpressionsInOrderBy() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports using a column that is
+     * not in the <code>SELECT</code> statement in an
+     * <code>ORDER BY</code> clause.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports using a column that is not in the <code>SELECT</code>
+     * statement in an <code>ORDER BY</code> clause; this method always
+     * returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsOrderByUnrelated() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports some form of
+     * <code>GROUP BY</code> clause.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports using the <code>GROUP BY</code> clause; this method
+     * always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsGroupBy() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports using a column that is
+     * not in the <code>SELECT</code> statement in a
+     * <code>GROUP BY</code> clause.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports using a column that is
+     * not in the <code>SELECT</code> statement in a
+     * <code>GROUP BY</code> clause; this method
+     * always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsGroupByUnrelated() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports using columns not included in
+     * the <code>SELECT</code> statement in a <code>GROUP BY</code> clause
+     * provided that all of the columns in the <code>SELECT</code> statement
+     * are included in the <code>GROUP BY</code> clause.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports using columns not included in
+     * the <code>SELECT</code> statement in a <code>GROUP BY</code> clause
+     * provided that all of the columns in the <code>SELECT</code> statement
+     * are included in the <code>GROUP BY</code> clause; this method
+     * always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsGroupByBeyondSelect() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports specifying a
+     * <code>LIKE</code> escape clause.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports specifying a
+     * <code>LIKE</code> escape clause; this method
+     * always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsLikeEscapeClause() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports getting multiple
+     * <code>ResultSet</code> objects from a single call to the
+     * method <code>execute</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Up to and including 2.0, HSQLDB does not support getting multiple
+     * <code>ResultSet</code> objects from a single call to the method
+     * <code>execute</code>; this method always returns <code>false</code>. <p>
+     *
+     * This behaviour <i>may</i> change in a future release.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsMultipleResultSets() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database allows having multiple
+     * transactions open at once (on different connections).
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB allows having multiple
+     * transactions open at once (on different connections); this method
+     * always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsMultipleTransactions() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether columns in this database may be defined as non-nullable.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the specification of non-nullable columns; this method
+     * always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsNonNullableColumns() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports the ODBC Minimum SQL grammar.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports the ODBC Minimum SQL grammar;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsMinimumSQLGrammar() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports the ODBC Core SQL grammar.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports the ODBC Core SQL grammar;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsCoreSQLGrammar() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports the ODBC Extended SQL grammar.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports the ODBC Extended SQL grammar;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsExtendedSQLGrammar() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports the ANSI92 entry level SQL
+     * grammar.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports the ANSI92 entry level SQL grammar;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports the ANSI92 intermediate SQL grammar supported.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports the ANSI92 intermediate SQL grammar;
+     * this method always returns <code>true</code>.
+     * <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsANSI92IntermediateSQL() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports the ANSI92 full SQL grammar supported.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports the ANSI92 full SQL grammar. The exceptions,
+     * such as support for ASSERTION, are not considered grammer issues.
+     * This method always returns <code>true</code>. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsANSI92FullSQL() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports the SQL Integrity
+     * Enhancement Facility.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * This method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports some form of outer join.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports outer joins; this method always returns
+     * <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsOuterJoins() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports full nested outer joins.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports full nested outer
+     * joins; this method always returns <code>true</code>. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsFullOuterJoins() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database provides limited support for outer
+     * joins.  (This will be <code>true</code> if the method
+     * <code>supportsFullOuterJoins</code> returns <code>true</code>).
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the LEFT OUTER join syntax;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsLimitedOuterJoins() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves the database vendor's preferred term for "schema".
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.8.0, HSQLDB supports schemas.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return the vendor term for "schema"
+     * @exception SQLException if a database access error occurs
+     */
+    public String getSchemaTerm() throws SQLException {
+        return "SCHEMA";
+    }
+
+    /**
+     * Retrieves the database vendor's preferred term for "procedure".
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports declaration of
+     * functions or procedures directly in SQL.<p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return the vendor term for "procedure"
+     * @exception SQLException if a database access error occurs
+     */
+    public String getProcedureTerm() throws SQLException {
+        return "PROCEDURE";
+    }
+
+    /**
+     * Retrieves the database vendor's preferred term for "catalog".
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB uses the standard name CATALOG.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the vendor term for "catalog"
+     * @exception SQLException if a database access error occurs
+     */
+    public String getCatalogTerm() throws SQLException {
+        return "CATALOG";
+    }
+
+    /**
+     * Retrieves whether a catalog appears at the start of a fully qualified
+     * table name.  If not, the catalog appears at the end.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * When allowed, a catalog appears at the start of a fully qualified
+     * table name; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if the catalog name appears at the beginning
+     *         of a fully qualified table name; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isCatalogAtStart() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves the <code>String</code> that this database uses as the
+     * separator between a catalog and table name.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * When used, a catalog name is separated with period;
+     * this method <em>always</em> returns a period
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the separator string
+     * @exception SQLException if a database access error occurs
+     */
+    public String getCatalogSeparator() throws SQLException {
+        return ".";
+    }
+
+    /**
+     * Retrieves whether a schema name can be used in a data manipulation statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports schemas where allowed by the standard;
+     * this method always returns <code>true</code>.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSchemasInDataManipulation() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise schema name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a schema name can be used in a procedure call statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports schemas where allowed by the standard;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSchemasInProcedureCalls() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise schema name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a schema name can be used in a table definition statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports schemas where allowed by the standard;
+     * this method always returns <code>true</code>.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSchemasInTableDefinitions() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise schema name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a schema name can be used in an index definition statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports schemas where allowed by the standard;
+     * this method always returns <code>true</code>.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise schema name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a schema name can be used in a privilege definition statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports schemas where allowed by the standard;
+     * this method always returns <code>true</code>.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise schema name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a catalog name can be used in a data manipulation statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports catalog names where allowed by the standard;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsCatalogsInDataManipulation() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise catalog name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a catalog name can be used in a procedure call statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports catalog names where allowed by the standard;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise catalog name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a catalog name can be used in a table definition statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports catalog names where allowed by the standard;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise catalog name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a catalog name can be used in an index definition statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports catalog names where allowed by the standard;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise catalog name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether a catalog name can be used in a privilege definition statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB supports catalog names where allowed by the standard;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+
+        // false for OOo client server compatibility
+        // otherwise catalog name is used by OOo in column references
+        return !useSchemaDefault;
+    }
+
+    /**
+     * Retrieves whether this database supports positioned <code>DELETE</code>
+     * statements.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports updateable result sets;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsPositionedDelete() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports positioned <code>UPDATE</code>
+     * statements.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports updateable result sets;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsPositionedUpdate() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports <code>SELECT FOR UPDATE</code>
+     * statements.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports updateable result sets;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSelectForUpdate() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports stored procedure calls
+     * that use the stored procedure escape syntax.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports calling public static Java methods in the context of SQL
+     * Stored Procedures; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @see JDBCParameterMetaData
+     * @see JDBCConnection#prepareCall
+     */
+    public boolean supportsStoredProcedures() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports subqueries in comparison
+     * expressions.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB has always supported subqueries in comparison expressions;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSubqueriesInComparisons() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports subqueries in
+     * <code>EXISTS</code> expressions.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB has always supported subqueries in <code>EXISTS</code>
+     * expressions; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSubqueriesInExists() throws SQLException {
+        return true;
+    }
+
+    /**
+     * (JDBC4 correction:)
+     * Retrieves whether this database supports subqueries in
+     * <code>IN</code> expressions.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB has always supported subqueries in <code>IN</code>
+     * statements; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSubqueriesInIns() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports subqueries in quantified
+     * expressions.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB has always supported subqueries in quantified
+     * expressions; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports correlated subqueries.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB has always supported correlated subqueries;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsCorrelatedSubqueries() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports SQL <code>UNION</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports SQL <code>UNION</code>;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsUnion() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports SQL <code>UNION ALL</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports SQL <code>UNION ALL</code>;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsUnionAll() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports keeping cursors open
+     * across commits.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports keeping cursors open across commits.
+     * This method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if cursors always remain open;
+     *       <code>false</code> if they might not remain open
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports keeping cursors open
+     * across rollbacks.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 closes open cursors at rollback.
+     * This method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if cursors always remain open;
+     *       <code>false</code> if they might not remain open
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database supports keeping statements open
+     * across commits.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports keeping statements open across commits;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if statements always remain open;
+     *       <code>false</code> if they might not remain open
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database supports keeping statements open
+     * across rollbacks.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports keeping statements open  across rollbacks;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if statements always remain open;
+     *       <code>false</code> if they might not remain open
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+        return true;
+    }
+
+    //----------------------------------------------------------------------
+    // The following group of methods exposes various limitations
+    // based on the target database with the current driver.
+    // Unless otherwise specified, a result of zero means there is no
+    // limit, or the limit is not known.
+
+    /**
+     * Retrieves the maximum number of hex characters this database allows in an
+     * inline binary literal.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return max the maximum length (in hex characters) for a binary literal;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxBinaryLiteralLength() throws SQLException {
+
+        // hard limit is Integer.MAX_VALUE
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of characters this database allows
+     * for a character literal.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of characters allowed for a character literal;
+     *      a result of zero means that there is no limit or the limit is
+     *      not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxCharLiteralLength() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of characters this database allows
+     * for a column name.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+     * all names.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of characters allowed for a column name;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxColumnNameLength() throws SQLException {
+        return 128;
+    }
+
+    /**
+     * Retrieves the maximum number of columns this database allows in a
+     * <code>GROUP BY</code> clause.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of columns allowed;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxColumnsInGroupBy() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of columns this database allows in an index.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of columns allowed;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxColumnsInIndex() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of columns this database allows in an
+     * <code>ORDER BY</code> clause.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of columns allowed;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxColumnsInOrderBy() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of columns this database allows in a
+     * <code>SELECT</code> list.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of columns allowed;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxColumnsInSelect() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of columns this database allows in a table.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of columns allowed;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxColumnsInTable() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of concurrent connections to this
+     * database that are possible.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of active connections possible at one time;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxConnections() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of characters that this database allows in a
+     * cursor name.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+     * all names.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of characters allowed in a cursor name;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxCursorNameLength() throws SQLException {
+        return 128;
+    }
+
+    /**
+     * Retrieves the maximum number of bytes this database allows for an
+     * index, including all of the parts of the index.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory and disk availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of bytes allowed; this limit includes the
+     *      composite of all the constituent parts of the index;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxIndexLength() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of characters that this database allows in a
+     * schema name.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+     * all names.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return the maximum number of characters allowed in a schema name;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxSchemaNameLength() throws SQLException {
+        return 128;
+    }
+
+    /**
+     * Retrieves the maximum number of characters that this database allows in a
+     * procedure name.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+     * all names.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of characters allowed in a procedure name;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxProcedureNameLength() throws SQLException {
+        return 128;
+    }
+
+    /**
+     * Retrieves the maximum number of characters that this database allows in a
+     * catalog name.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+     * all names.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of characters allowed in a catalog name;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxCatalogNameLength() throws SQLException {
+        return 128;
+    }
+
+    /**
+     * Retrieves the maximum number of bytes this database allows in
+     * a single row.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory and disk availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of bytes allowed for a row; a result of
+     *         zero means that there is no limit or the limit is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxRowSize() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves whether the return value for the method
+     * <code>getMaxRowSize</code> includes the SQL data types
+     * <code>LONGVARCHAR</code> and <code>LONGVARBINARY</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Indormation:</h3><p>
+     *
+     * Including 2.0, {@link #getMaxRowSize} <em>always</em> returns
+     * 0, indicating that the maximum row size is unknown or has no limit.
+     * This applies to the above types as well; this method <em>always</em>
+     * returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves the maximum number of characters this database allows in
+     * an SQL statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of characters allowed for an SQL statement;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxStatementLength() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of active statements to this database
+     * that can be open at the same time.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of statements that can be open at one time;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxStatements() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of characters this database allows in
+     * a table name.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Up to and including 1.8.0.x, HSQLDB did not impose a "known" limit.  Th
+     * hard limit was the maximum length of a java.lang.String
+     * (java.lang.Integer.MAX_VALUE); this method always returned
+     * <code>0</code>.
+     *
+     * Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+     * all names.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of characters allowed for a table name;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxTableNameLength() throws SQLException {
+        return 128;
+    }
+
+    /**
+     * Retrieves the maximum number of tables this database allows in a
+     * <code>SELECT</code> statement.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not impose a "known" limit.  The limit is subject to
+     * memory availabily; this method always returns <code>0</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of tables allowed in a <code>SELECT</code>
+     *         statement; a result of zero means that there is no limit or
+     *         the limit is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxTablesInSelect() throws SQLException {
+        return 0;
+    }
+
+    /**
+     * Retrieves the maximum number of characters this database allows in
+     * a user name.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for
+     * all names.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the maximum number of characters allowed for a user name;
+     *      a result of zero means that there is no limit or the limit
+     *      is not known
+     * @exception SQLException if a database access error occurs
+     */
+    public int getMaxUserNameLength() throws SQLException {
+        return 128;
+    }
+
+    //----------------------------------------------------------------------
+
+    /**
+     * Retrieves this database's default transaction isolation level.  The
+     * possible values are defined in <code>java.sql.Connection</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information</h3>
+     *
+     * Default isolation mode in version 2.0 is TRANSACTION_READ_COMMITED.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the default isolation level
+     * @exception SQLException if a database access error occurs
+     * @see JDBCConnection
+     */
+    public int getDefaultTransactionIsolation() throws SQLException {
+        return Connection.TRANSACTION_READ_COMMITTED;
+    }
+
+    /**
+     * Retrieves whether this database supports transactions. If not, invoking the
+     * method <code>commit</code> is a noop, and the isolation level is
+     * <code>TRANSACTION_NONE</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports transactions;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if transactions are supported;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsTransactions() throws SQLException {
+        return true;
+    }
+
+    /** @todo update javadoc */
+
+    /**
+     * Retrieves whether this database supports the given transaction isolation level.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information</h3>
+     * HSQLDB supports all levels.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @param level one of the transaction isolation levels defined in
+     *         <code>java.sql.Connection</code>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @see JDBCConnection
+     */
+    public boolean supportsTransactionIsolationLevel(
+            int level) throws SQLException {
+
+        return level == Connection.TRANSACTION_READ_UNCOMMITTED
+               || level == Connection.TRANSACTION_READ_COMMITTED
+               || level == Connection.TRANSACTION_REPEATABLE_READ
+               || level == Connection.TRANSACTION_SERIALIZABLE;
+    }
+
+    /**
+     * Retrieves whether this database supports both data definition and
+     * data manipulation statements within a transaction.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support a mix of both data definition and
+     * data manipulation statements within a transaction.  DDL commits the
+     * current transaction before proceding;
+     * this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database supports only data manipulation
+     * statements within a transaction.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports only data manipulation
+     * statements within a transaction.  DDL commits the
+     * current transaction before proceeding, while DML does not;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether a data definition statement within a transaction forces
+     * the transaction to commit.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, a data definition statement within a transaction forces
+     * the transaction to commit; this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves whether this database ignores a data definition statement
+     * within a transaction.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, a data definition statement is not ignored within a
+     * transaction.  Rather, a data definition statement within a
+     * transaction forces the transaction to commit; this method
+     * <em>always</em> returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves a description of the stored procedures available in the given
+     * catalog.
+     * <P>
+     * Only procedure descriptions matching the schema and
+     * procedure name criteria are returned.  They are ordered by
+     * <code>PROCEDURE_SCHEM</code>, <code>PROCEDURE_NAME</code> and (new to JDBC4) <code>SPECIFIC_ NAME</code>.
+     *
+     * <P>Each procedure description has the the following columns:
+     *  <OL>
+     *  <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be <code>null</code>)
+     *  <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be <code>null</code>)
+     *  <LI><B>PROCEDURE_NAME</B> String => procedure name
+     *  <LI> reserved for future use
+     *       (HSQLDB-specific: NUM_INPUT_PARAMS)
+     *  <LI> reserved for future use
+     *       (HSQLDB-specific: NUM_OUTPUT_PARAMS)
+     *  <LI> reserved for future use
+     *       (HSQLDB-specific: NUM_RESULT_SETS)
+     *  <LI><B>REMARKS</B> String => explanatory comment on the procedure
+     *  <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
+     *      <UL>
+     *      <LI> procedureResultUnknown - (JDBC4 clarification:) Cannot determine if  a return value
+     *       will be returned
+     *      <LI> procedureNoResult - (JDBC4 clarification:) Does not return a return value
+     *      <LI> procedureReturnsResult - (JDBC4 clarification:) Returns a return value
+     *      </UL>
+     *  <LI><B>SPECIFIC_NAME</B> String  => (JDBC4 new:) The name which uniquely identifies this procedure within its schema
+     *  </OL>
+     * <p>
+     * A user may not have permissions to execute any of the procedures that are
+     * returned by <code>getProcedures</code>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * In version 1.9, the rows returned by this method are based on rows in
+     * the INFORMATION_SCHEMA.ROUTINES table.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema name pattern; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param procedureNamePattern a procedure name pattern; must match the
+     *        procedure name as it is stored in the database
+     * @return <code>ResultSet</code> - each row is a procedure description
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     */
+    public ResultSet getProcedures(
+            String catalog, String schemaPattern,
+            String procedureNamePattern) throws SQLException {
+
+        if (wantsIsNull(procedureNamePattern)) {
+            return executeSelect("SYSTEM_PROCEDURES", "0=1");
+        }
+        catalog       = translateCatalog(catalog);
+        schemaPattern = translateSchema(schemaPattern);
+
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_PROCEDURES").append(and("PROCEDURE_CAT",
+                "=", catalog)).append(and("PROCEDURE_SCHEM", "LIKE",
+                    schemaPattern)).append(and("PROCEDURE_NAME", "LIKE",
+                        procedureNamePattern));
+
+        // By default, query already returns the result ordered by
+        // PROCEDURE_SCHEM, PROCEDURE_NAME...
+        return execute(select.toString());
+    }
+
+    /**
+     * Indicates that it is not known whether the procedure returns
+     * a result.
+     * <P>
+     * A possible value for column <code>PROCEDURE_TYPE</code> in the
+     * <code>ResultSet</code> object returned by the method
+     * <code>getProcedures</code>.
+     */
+
+//    int procedureResultUnknown        = 0;
+
+    /**
+     * Indicates that the procedure does not return a result.
+     * <P>
+     * A possible value for column <code>PROCEDURE_TYPE</code> in the
+     * <code>ResultSet</code> object returned by the method
+     * <code>getProcedures</code>.
+     */
+//    int procedureNoResult             = 1;
+
+    /**
+     * Indicates that the procedure returns a result.
+     * <P>
+     * A possible value for column <code>PROCEDURE_TYPE</code> in the
+     * <code>ResultSet</code> object returned by the method
+     * <code>getProcedures</code>.
+     */
+//    int procedureReturnsResult        = 2;
+
+    /**
+     * Retrieves a description of the given catalog's stored procedure parameter
+     * and result columns.
+     *
+     * <P>Only descriptions matching the schema, procedure and
+     * parameter name criteria are returned.  They are ordered by
+     * PROCEDURE_SCHEM, PROCEDURE_NAME and SPECIFIC_NAME. Within this, the return value,
+     * if any, is first. Next are the parameter descriptions in call
+     * order. The column descriptions follow in column number order.
+     *
+     * <P>Each row in the <code>ResultSet</code> is a parameter description or
+     * column description with the following fields:
+     *  <OL>
+     *  <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be <code>null</code>)
+     *  <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be <code>null</code>)
+     *  <LI><B>PROCEDURE_NAME</B> String => procedure name
+     *  <LI><B>COLUMN_NAME</B> String => column/parameter name
+     *  <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
+     *      <UL>
+     *      <LI> procedureColumnUnknown - nobody knows
+     *      <LI> procedureColumnIn - IN parameter
+     *      <LI> procedureColumnInOut - INOUT parameter
+     *      <LI> procedureColumnOut - OUT parameter
+     *      <LI> procedureColumnReturn - procedure return value
+     *      <LI> procedureColumnResult - result column in <code>ResultSet</code>
+     *      </UL>
+     *  <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
+     *  <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
+     *  type name is fully qualified
+     *  <LI><B>PRECISION</B> int => precision
+     *  <LI><B>LENGTH</B> int => length in bytes of data
+     *  <LI><B>SCALE</B> short => scale -  null is returned for data types where
+     * SCALE is not applicable.
+     *  <LI><B>RADIX</B> short => radix
+     *  <LI><B>NULLABLE</B> short => can it contain NULL.
+     *      <UL>
+     *      <LI> procedureNoNulls - does not allow NULL values
+     *      <LI> procedureNullable - allows NULL values
+     *      <LI> procedureNullableUnknown - nullability unknown
+     *      </UL>
+     *  <LI><B>REMARKS</B> String => comment describing parameter/column
+     *  <LI><B>COLUMN_DEF</B> String => default value for the column, which should be interpreted as a string when the value is enclosed in single quotes (may be <code>null</code>)
+     *      <UL>
+     *      <LI> The string NULL (not enclosed in quotes) - if NULL was specified as the default value
+     *      <LI> TRUNCATE (not enclosed in quotes)        - if the specified default value cannot be represented without truncation
+     *      <LI> NULL                                     - if a default value was not specified
+     *      </UL>
+     *  <LI><B>SQL_DATA_TYPE</B> int  => (JDBC4 new:) Reserved for future use
+     *
+     *        <p>HSQLDB-specific: CLI type from SQL 2003 Table 37,
+     *        tables 6-9 Annex A1, and/or addendums in other
+     *        documents, such as:<br>
+     *        SQL 2003 Part 9: Management of External Data (SQL/MED) : DATALINK<br>
+     *        SQL 2003 Part 14: XML-Related Specifications (SQL/XML) : XML<p>
+     *
+     *  <LI><B>SQL_DATETIME_SUB</B> int  => (JDBC4 new:) reserved for future use
+     *
+     *        <p>HSQLDB-specific: CLI SQL_DATETIME_SUB from SQL 2003 Table 37
+     *
+     *  <LI><B>CHAR_OCTET_LENGTH</B> int  => (JDBC4 new:) the maximum length of binary and character based columns.  For any other datatype the returned value is a
+     * NULL
+     *  <LI><B>ORDINAL_POSITION</B> int  => (JDBC4 new:) the ordinal position, starting from 1, for the input and output parameters for a procedure. A value of 0
+     * is returned if this row describes the procedure's return value.
+     *  <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine the nullability for a column.
+     *       <UL>
+     *       <LI> YES           --- if the parameter can include NULLs
+     *       <LI> NO            --- if the parameter cannot include NULLs
+     *       <LI> empty string  --- if the nullability for the
+     * parameter is unknown
+     *       </UL>
+     *  <LI><B>SPECIFIC_NAME</B> String  => (JDBC4 new:) the name which uniquely identifies this procedure within its schema.
+     * </OL>
+     *
+     * <P><B>Note:</B> Some databases may not return the column
+     * descriptions for a procedure. Additional columns beyond (JDBC4 modified:)
+     * SPECIFIC_NAME can be defined by the database and must be accessed by their <B>column name</B>.
+     *
+     * <p>(JDBC4 clarification:)
+     * <p>The PRECISION column represents the specified column size for the given column.
+     * For numeric data, this is the maximum precision.  For character data, this is the [declared or implicit maximum] length in characters.
+     * For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+     * this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+     * column size is not applicable.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationFull}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema name pattern; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param procedureNamePattern a procedure name pattern; must match the
+     *        procedure name as it is stored in the database
+     * @param columnNamePattern a column name pattern; must match the column name
+     *        as it is stored in the database
+     * @return <code>ResultSet</code> - each row describes a stored procedure parameter or
+     *      column
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     */
+    public ResultSet getProcedureColumns(String catalog, String schemaPattern,
+            String procedureNamePattern,
+            String columnNamePattern) throws SQLException {
+
+        if (wantsIsNull(procedureNamePattern)
+                || wantsIsNull(columnNamePattern)) {
+            return executeSelect("SYSTEM_PROCEDURECOLUMNS", "0=1");
+        }
+        catalog       = translateCatalog(catalog);
+        schemaPattern = translateSchema(schemaPattern);
+
+        StringBuffer select = toQueryPrefix("SYSTEM_PROCEDURECOLUMNS").append(
+            and("PROCEDURE_CAT", "=", catalog)).append(
+            and("PROCEDURE_SCHEM", "LIKE", schemaPattern)).append(
+            and("PROCEDURE_NAME", "LIKE", procedureNamePattern)).append(
+            and("COLUMN_NAME", "LIKE", columnNamePattern));
+
+        // By default, query already returns result ordered by
+        // PROCEDURE_SCHEM and PROCEDURE_NAME...
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves a description of the tables available in the given catalog.
+     * Only table descriptions matching the catalog, schema, table
+     * name and type criteria are returned.  They are ordered by
+     * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
+     * <P>
+     * Each table description has the following columns:
+     *  <OL>
+     *  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+     *  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+     *  <LI><B>TABLE_NAME</B> String => table name
+     *  <LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
+     *                  "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
+     *                  "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
+     *  <LI><B>REMARKS</B> String => explanatory comment on the table
+     *  <LI><B>TYPE_CAT</B> String => the types catalog (may be <code>null</code>)
+     *  <LI><B>TYPE_SCHEM</B> String => the types schema (may be <code>null</code>)
+     *  <LI><B>TYPE_NAME</B> String => type name (may be <code>null</code>)
+     *  <LI><B>SELF_REFERENCING_COL_NAME</B> String => name of the designated
+     *                  "identifier" column of a typed table (may be <code>null</code>)
+     *  <LI><B>REF_GENERATION</B> String => specifies how values in
+     *                  SELF_REFERENCING_COL_NAME are created. Values are
+     *                  "SYSTEM", "USER", "DERIVED". (may be <code>null</code>)
+     *  </OL>
+     *
+     * <P><B>Note:</B> Some databases may not return information for
+     * all tables.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * HSQLDB returns extra information on TEXT tables in the REMARKS column. <p>
+     *
+     * HSQLDB includes the JDBC3 columns TYPE_CAT, TYPE_SCHEM, TYPE_NAME and
+     * SELF_REFERENCING_COL_NAME in anticipation of JDBC3 compliant tools. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema name pattern; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param tableNamePattern a table name pattern; must match the
+     *        table name as it is stored in the database
+     * @param types a list of table types, which must be from the list of table types
+     *         returned from {@link #getTableTypes},to include; <code>null</code> returns
+     * all types
+     * @return <code>ResultSet</code> - each row is a table description
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     */
+    public ResultSet getTables(String catalog, String schemaPattern,
+                               String tableNamePattern,
+                               String[] types) throws SQLException {
+
+        if (wantsIsNull(tableNamePattern)
+                || (types != null && types.length == 0)) {
+            return executeSelect("SYSTEM_TABLES", "0=1");
+        }
+        catalog       = translateCatalog(catalog);
+        schemaPattern = translateSchema(schemaPattern);
+
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_TABLES").append(and("TABLE_CAT", "=",
+                catalog)).append(and("TABLE_SCHEM", "LIKE",
+                                     schemaPattern)).append(and("TABLE_NAME",
+                                         "LIKE", tableNamePattern));
+
+        if (types == null) {
+
+            // do not use to narrow search
+        } else {
+
+            // JDBC4 clarification:
+            // fredt - we shouldn't impose this test as it breaks compatibility with tools
+/*
+            String[] allowedTypes = new String[] {
+                "GLOBAL TEMPORARY", "SYSTEM TABLE", "TABLE", "VIEW"
+            };
+            int      illegalIndex = 0;
+            String   illegalType  = null;
+
+            outer_loop:
+            for (int i = 0; i < types.length; i++) {
+                for (int j = 0; j < allowedTypes.length; j++) {
+                    if (allowedTypes[j].equals(types[i])) {
+                        continue outer_loop;
+                    }
+                }
+
+                illegalIndex = i;
+                illegalType  = types[illegalIndex];
+
+                break;
+            }
+
+            if (illegalType != null) {
+                throw Util.sqlException(Trace.JDBC_INVALID_ARGUMENT,
+                                        "types[" + illegalIndex + "]=>\""
+                                        + illegalType + "\"");
+            }
+*/
+
+            // end JDBC4 clarification
+            //
+            select.append(" AND TABLE_TYPE IN (").append(
+                StringUtil.getList(types, ",", "'")).append(')');
+        }
+
+        // By default, query already returns result ordered by
+        // TABLE_TYPE, TABLE_SCHEM and TABLE_NAME...
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves the schema names available in this database.  The results
+     * are ordered by schema name.
+     *
+     * <P>The schema columns are:
+     *  <OL>
+     *  <LI><B>TABLE_SCHEM</B> String => schema name
+     *  <LI><B>TABLE_CATALOG</B> String => catalog name (may be <code>null</code>)
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.8.0, the list of schemas is returned.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>ResultSet</code> object in which each row is a
+     *         schema description
+     * @exception SQLException if a database access error occurs
+     *
+     */
+    public ResultSet getSchemas() throws SQLException {
+
+        // By default, query already returns the result in contract order
+        return executeSelect("SYSTEM_SCHEMAS", null);
+    }
+
+    /**
+     * Retrieves the catalog names available in this database.  The results
+     * are ordered by catalog name.
+     *
+     * <P>The catalog column is:
+     *  <OL>
+     *  <LI><B>TABLE_CAT</B> String => catalog name
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>ResultSet</code> object in which each row has a
+     *         single <code>String</code> column that is a catalog name
+     * @exception SQLException if a database access error occurs
+     */
+    public ResultSet getCatalogs() throws SQLException {
+
+        String select =
+            "SELECT CATALOG_NAME AS TABLE_CAT FROM INFORMATION_SCHEMA.INFORMATION_SCHEMA_CATALOG_NAME";
+
+        return execute(select);
+    }
+
+    /**
+     * Retrieves the table types available in this database.  The results
+     * are ordered by table type.
+     *
+     * <P>The table type is:
+     *  <OL>
+     *  <LI><B>TABLE_TYPE</B> String => table type.  Typical types are "TABLE",
+     *                  "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
+     *                  "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.1, HSQLDB reports: "TABLE", "VIEW" and "GLOBAL TEMPORARY"
+     * types.
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>ResultSet</code> object in which each row has a
+     *         single <code>String</code> column that is a table type
+     * @exception SQLException if a database access error occurs
+     */
+    public ResultSet getTableTypes() throws SQLException {
+
+        // system table producer returns rows in contract order
+        return executeSelect("SYSTEM_TABLETYPES", null);
+    }
+
+    /**
+     * Retrieves a description of table columns available in
+     * the specified catalog.
+     *
+     * <P>Only column descriptions matching the catalog, schema, table
+     * and column name criteria are returned.  They are ordered by
+     * <code>TABLE_SCHEM</code>, <code>TABLE_NAME</code>, and
+     * <code>ORDINAL_POSITION</code>.
+     *
+     * <P>Each column description has the following columns:
+     *  <OL>
+     *  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+     *  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+     *  <LI><B>TABLE_NAME</B> String => table name
+     *  <LI><B>COLUMN_NAME</B> String => column name
+     *  <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
+     *  <LI><B>TYPE_NAME</B> String => Data source dependent type name,
+     *  for a UDT the type name is fully qualified
+     *  <LI><B>COLUMN_SIZE</B> int => column size.
+     *  <LI><B>BUFFER_LENGTH</B> is not used.
+     *  <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits. Null is returned for data types where
+     * DECIMAL_DIGITS is not applicable.
+     *  <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
+     *  <LI><B>NULLABLE</B> int => is NULL allowed.
+     *      <UL>
+     *      <LI> columnNoNulls - might not allow <code>NULL</code> values
+     *      <LI> columnNullable - definitely allows <code>NULL</code> values
+     *      <LI> columnNullableUnknown - nullability unknown
+     *      </UL>
+     *  <LI><B>REMARKS</B> String => comment describing column (may be <code>null</code>)
+     *  <LI><B>COLUMN_DEF</B> String => (JDBC4 clarification:) default value for the column, which should be interpreted as a string when the value is enclosed in quotes (may be <code>null</code>)
+     *  <LI><B>SQL_DATA_TYPE</B> int => unused
+     *
+     *        <p>HSQLDB-specific: CLI type from SQL 2003 Table 37,
+     *        tables 6-9 Annex A1, and/or addendums in other
+     *        documents, such as:<br>
+     *        SQL 2003 Part 9: Management of External Data (SQL/MED) : DATALINK<br>
+     *        SQL 2003 Part 14: XML-Related Specifications (SQL/XML) : XML<p>
+     *
+     *  <LI><B>SQL_DATETIME_SUB</B> int => unused (HSQLDB-specific: SQL 2003 CLI datetime/interval subcode)
+     *  <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
+     *       maximum number of bytes in the column
+     *  <LI><B>ORDINAL_POSITION</B> int => index of column in table
+     *      (starting at 1)
+     *  <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine the nullability for a column.
+     *       <UL>
+     *       <LI> YES           --- if the parameter can include NULLs
+     *       <LI> NO            --- if the parameter cannot include NULLs
+     *       <LI> empty string  --- if the nullability for the
+     * parameter is unknown
+     *       </UL>
+     *  <LI><B>SCOPE_CATLOG</B> String => catalog of table that is the scope
+     *      of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+     *  <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the scope
+     *      of a reference attribute (<code>null</code> if the DATA_TYPE isn't REF)
+     *  <LI><B>SCOPE_TABLE</B> String => table name that this the scope
+     *      of a reference attribure (<code>null</code> if the DATA_TYPE isn't REF)
+     *  <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct type or user-generated
+     *      Ref type, SQL type from java.sql.Types (<code>null</code> if DATA_TYPE
+     *      isn't DISTINCT or user-generated REF)
+     *   <LI><B>IS_AUTOINCREMENT</B> String  => Indicates whether this column is auto incremented
+     *       <UL>
+     *       <LI> YES           --- if the column is auto incremented
+     *       <LI> NO            --- if the column is not auto incremented
+     *       <LI> empty string  --- if it cannot be determined whether the column is auto incremented
+     * parameter is unknown
+     *       </UL>
+     *  </OL>
+     *
+     * <p>(JDBC4 clarification:) The COLUMN_SIZE column represents the specified column size for the given column.
+     * For numeric data, this is the maximum precision.  For character data, this is the [declared or implicit maximum] length in characters.
+     * For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+     * this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+     * column size is not applicable. <p>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * This feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformation}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema name pattern; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param tableNamePattern a table name pattern; must match the
+     *        table name as it is stored in the database
+     * @param columnNamePattern a column name pattern; must match the column
+     *        name as it is stored in the database
+     * @return <code>ResultSet</code> - each row is a column description
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     */
+    public ResultSet getColumns(String catalog, String schemaPattern,
+                                String tableNamePattern,
+                                String columnNamePattern) throws SQLException {
+
+        if (wantsIsNull(tableNamePattern) || wantsIsNull(columnNamePattern)) {
+            return executeSelect("SYSTEM_COLUMNS", "0=1");
+        }
+        catalog       = translateCatalog(catalog);
+        schemaPattern = translateSchema(schemaPattern);
+
+        StringBuffer select = toQueryPrefix("SYSTEM_COLUMNS").append(
+            and("TABLE_CAT", "=", catalog)).append(
+            and("TABLE_SCHEM", "LIKE", schemaPattern)).append(
+            and("TABLE_NAME", "LIKE", tableNamePattern)).append(
+            and("COLUMN_NAME", "LIKE", columnNamePattern));
+
+        // by default, query already returns the result ordered
+        // by TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves a description of the access rights for a table's columns.
+     *
+     * <P>Only privileges matching the column name criteria are
+     * returned.  They are ordered by COLUMN_NAME and PRIVILEGE.
+     *
+     * <P>Each privilige description has the following columns:
+     *  <OL>
+     *  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+     *  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+     *  <LI><B>TABLE_NAME</B> String => table name
+     *  <LI><B>COLUMN_NAME</B> String => column name
+     *  <LI><B>GRANTOR</B> => grantor of access (may be <code>null</code>)
+     *  <LI><B>GRANTEE</B> String => grantee of access
+     *  <LI><B>PRIVILEGE</B> String => name of access (SELECT,
+     *      INSERT, UPDATE, REFRENCES, ...)
+     *  <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
+     *      to grant to others; "NO" if not; <code>null</code> if unknown
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schema a schema name; must match the schema name as it is
+     *        stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param table a table name; must match the table name as it is
+     *        stored in the database
+     * @param columnNamePattern a column name pattern; must match the column
+     *        name as it is stored in the database
+     * @return <code>ResultSet</code> - each row is a column privilege description
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     */
+    public ResultSet getColumnPrivileges(String catalog, String schema,
+            String table, String columnNamePattern) throws SQLException {
+
+        if (table == null) {
+            throw Util.nullArgument("table");
+        }
+/*
+        if (wantsIsNull(columnNamePattern)) {
+            return executeSelect("SYSTEM_COLUMNPRIVILEGES", "0=1");
+        }
+*/
+        catalog = translateCatalog(catalog);
+        schema  = translateSchema(schema);
+
+        String sql =
+            "SELECT TABLE_CATALOG TABLE_CAT, TABLE_SCHEMA TABLE_SCHEM,"
+            + "TABLE_NAME, COLUMN_NAME, GRANTOR, GRANTEE, PRIVILEGE_TYPE PRIVILEGE, IS_GRANTABLE "
+            + "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES WHERE TRUE "
+            + and("TABLE_CATALOG", "=", catalog)
+            + and("TABLE_SCHEMA", "=", schema) + and("TABLE_NAME", "=", table)
+            + and("COLUMN_NAME", "LIKE", columnNamePattern)
+        ;
+
+        // By default, the query already returns the result
+        // ordered by column name, privilege...
+        return execute(sql);
+    }
+
+    /**
+     * Retrieves a description of the access rights for each table available
+     * in a catalog. Note that a table privilege applies to one or
+     * more columns in the table. It would be wrong to assume that
+     * this privilege applies to all columns (this may be true for
+     * some systems but is not true for all.)
+     *
+     * <P>Only privileges matching the schema and table name
+     * criteria are returned.  They are ordered by TABLE_SCHEM,
+     * TABLE_NAME, and PRIVILEGE.
+     *
+     * <P>Each privilige description has the following columns:
+     *  <OL>
+     *  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+     *  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+     *  <LI><B>TABLE_NAME</B> String => table name
+     *  <LI><B>GRANTOR</B> => grantor of access (may be <code>null</code>)
+     *  <LI><B>GRANTEE</B> String => grantee of access
+     *  <LI><B>PRIVILEGE</B> String => name of access (SELECT,
+     *      INSERT, UPDATE, REFRENCES, ...)
+     *  <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
+     *      to grant to others; "NO" if not; <code>null</code> if unknown
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema name pattern; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param tableNamePattern a table name pattern; must match the
+     *        table name as it is stored in the database
+     * @return <code>ResultSet</code> - each row is a table privilege description
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     */
+    public ResultSet getTablePrivileges(
+            String catalog, String schemaPattern,
+            String tableNamePattern) throws SQLException {
+
+        catalog       = translateCatalog(catalog);
+        schemaPattern = translateSchema(schemaPattern);
+
+        String sql =
+            "SELECT TABLE_CATALOG TABLE_CAT, TABLE_SCHEMA TABLE_SCHEM,"
+            + "TABLE_NAME, GRANTOR, GRANTEE, PRIVILEGE_TYPE PRIVILEGE, IS_GRANTABLE "
+            + "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES WHERE TRUE "
+            + and("TABLE_CATALOG", "=", catalog)
+            + and("TABLE_SCHEMA", "LIKE", schemaPattern)
+            + and("TABLE_NAME", "LIKE", tableNamePattern);
+
+/*
+        if (wantsIsNull(tableNamePattern)) {
+            return executeSelect("SYSTEM_TABLEPRIVILEGES", "0=1");
+        }
+*/
+
+        // By default, the query already returns a result ordered by
+        // TABLE_SCHEM, TABLE_NAME, and PRIVILEGE...
+        return execute(sql);
+    }
+
+    /**
+     * Retrieves a description of a table's optimal set of columns that
+     * uniquely identifies a row. They are ordered by SCOPE.
+     *
+     * <P>Each column description has the following columns:
+     *  <OL>
+     *  <LI><B>SCOPE</B> short => actual scope of result
+     *      <UL>
+     *      <LI> bestRowTemporary - very temporary, while using row
+     *      <LI> bestRowTransaction - valid for remainder of current transaction
+     *      <LI> bestRowSession - valid for remainder of current session
+     *      </UL>
+     *  <LI><B>COLUMN_NAME</B> String => column name
+     *  <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
+     *  <LI><B>TYPE_NAME</B> String => Data source dependent type name,
+     *  for a UDT the type name is fully qualified
+     *  <LI><B>COLUMN_SIZE</B> int => precision
+     *  <LI><B>BUFFER_LENGTH</B> int => not used
+     *  <LI><B>DECIMAL_DIGITS</B> short  => scale - Null is returned for data types where
+     * DECIMAL_DIGITS is not applicable.
+     *  <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
+     *      like an Oracle ROWID
+     *      <UL>
+     *      <LI> bestRowUnknown - may or may not be pseudo column
+     *      <LI> bestRowNotPseudo - is NOT a pseudo column
+     *      <LI> bestRowPseudo - is a pseudo column
+     *      </UL>
+     *  </OL>
+     *
+     * <p>(JDBC4 clarification:)<p>
+     * The COLUMN_SIZE column represents the specified column size for the given column.
+     * For numeric data, this is the maximum precision.  For character data, this is the [declared or implicit maximum] length in characters.
+     * For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+     * this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+     * column size is not applicable. <p>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * If the name of a column is defined in the database without double
+     * quotes, an all-uppercase name must be specified when calling this
+     * method. Otherwise, the name must be specified in the exact case of
+     * the column definition in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schema a schema name; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param table a table name; must match the table name as it is stored
+     *        in the database
+     * @param scope the scope of interest; use same values as SCOPE
+     * @param nullable include columns that are nullable.
+     * @return <code>ResultSet</code> - each row is a column description
+     * @exception SQLException if a database access error occurs
+     */
+    public ResultSet getBestRowIdentifier(String catalog, String schema,
+            String table, int scope, boolean nullable) throws SQLException {
+
+        if (table == null) {
+            throw Util.nullArgument("table");
+        }
+
+        String scopeIn;
+
+        switch (scope) {
+
+            case bestRowTemporary :
+                scopeIn = BRI_TEMPORARY_SCOPE_IN_LIST;
+
+                break;
+            case bestRowTransaction :
+                scopeIn = BRI_TRANSACTION_SCOPE_IN_LIST;
+
+                break;
+            case bestRowSession :
+                scopeIn = BRI_SESSION_SCOPE_IN_LIST;
+
+                break;
+            default :
+                throw Util.invalidArgument("scope");
+        }
+        catalog = translateCatalog(catalog);
+        schema  = translateSchema(schema);
+
+        Integer Nullable = (nullable) ? null
+                                      : INT_COLUMNS_NO_NULLS;
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_BESTROWIDENTIFIER").append(and("TABLE_CAT",
+                "=", catalog)).append(and("TABLE_SCHEM", "=",
+                    schema)).append(and("TABLE_NAME", "=",
+                                        table)).append(and("NULLABLE", "=",
+                                            Nullable)).append(" AND SCOPE IN "
+                                                + scopeIn);
+
+        // By default, query already returns rows in contract order.
+        // However, the way things are set up, there should never be
+        // a result where there is > 1 distinct scope value:  most requests
+        // will want only one table and the system table producer (for
+        // now) guarantees that a maximum of one BRI scope column set is
+        // produced for each table
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves a description of a table's columns that are automatically
+     * updated when any value in a row is updated.  They are
+     * unordered.
+     *
+     * <P>Each column description has the following columns:
+     *  <OL>
+     *  <LI><B>SCOPE</B> short => is not used
+     *  <LI><B>COLUMN_NAME</B> String => column name
+     *  <LI><B>DATA_TYPE</B> int => SQL data type from <code>java.sql.Types</code>
+     *  <LI><B>TYPE_NAME</B> String => Data source-dependent type name
+     *  <LI><B>COLUMN_SIZE</B> int => precision
+     *  <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
+     *  <LI><B>DECIMAL_DIGITS</B> short  => scale - Null is returned for data types where
+     * DECIMAL_DIGITS is not applicable.
+     *  <LI><B>PSEUDO_COLUMN</B> short => whether this is pseudo column
+     *      like an Oracle ROWID
+     *      <UL>
+     *      <LI> versionColumnUnknown - may or may not be pseudo column
+     *      <LI> versionColumnNotPseudo - is NOT a pseudo column
+     *      <LI> versionColumnPseudo - is a pseudo column
+     *      </UL>
+     *  </OL>
+     *
+     * <p>(JDBC4 clarification:)
+     *
+     * <p>The COLUMN_SIZE column represents the specified column size for the given column.
+     * For numeric data, this is the maximum precision.  For character data, this is the [declared or implicit maximum] length in characters.
+     * For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+     * this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+     * column size is not applicable.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schema a schema name; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param table a table name; must match the table name as it is stored
+     *        in the database
+     * @return a <code>ResultSet</code> object in which each row is a
+     *         column description
+     * @exception SQLException if a database access error occurs
+     */
+    public ResultSet getVersionColumns(String catalog, String schema,
+                                       String table) throws SQLException {
+
+        if (table == null) {
+            throw Util.nullArgument("table");
+        }
+        catalog = translateCatalog(catalog);
+        schema  = translateSchema(schema);
+
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_VERSIONCOLUMNS").append(and("TABLE_CAT",
+                "=", catalog)).append(and("TABLE_SCHEM", "=",
+                    schema)).append(and("TABLE_NAME", "=", table));
+
+        // result does not need to be ordered
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves a description of the given table's primary key columns.  They
+     * are ordered by COLUMN_NAME.
+     *
+     * <P>Each primary key column description has the following columns:
+     *  <OL>
+     *  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+     *  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+     *  <LI><B>TABLE_NAME</B> String => table name
+     *  <LI><B>COLUMN_NAME</B> String => column name
+     *  <LI><B>KEY_SEQ</B> short => (JDBC4 Clarification:) sequence number within primary key( a value
+     *  of 1 represents the first column of the primary key, a value of 2 would
+     *  represent the second column within the primary key).
+     *  <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schema a schema name; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param table a table name; must match the table name as it is stored
+     *        in the database
+     * @return <code>ResultSet</code> - each row is a primary key column description
+     * @exception SQLException if a database access error occurs
+     * @see #supportsMixedCaseQuotedIdentifiers
+     * @see #storesUpperCaseIdentifiers
+     */
+    public ResultSet getPrimaryKeys(String catalog, String schema,
+                                    String table) throws SQLException {
+
+        if (table == null) {
+            throw Util.nullArgument("table");
+        }
+        catalog = translateCatalog(catalog);
+        schema  = translateSchema(schema);
+
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_PRIMARYKEYS").append(and("TABLE_CAT", "=",
+                catalog)).append(and("TABLE_SCHEM", "=",
+                                     schema)).append(and("TABLE_NAME", "=",
+                                         table));
+
+        // By default, query already returns result in contract order
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves a description of the primary key columns that are
+     * referenced by the given table's foreign key columns (the primary keys
+     * imported by a table).  They are ordered by PKTABLE_CAT,
+     * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
+     *
+     * <P>Each primary key column description has the following columns:
+     *  <OL>
+     *  <LI><B>PKTABLE_CAT</B> String => primary key table catalog
+     *      being imported (may be <code>null</code>)
+     *  <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
+     *      being imported (may be <code>null</code>)
+     *  <LI><B>PKTABLE_NAME</B> String => primary key table name
+     *      being imported
+     *  <LI><B>PKCOLUMN_NAME</B> String => primary key column name
+     *      being imported
+     *  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
+     *  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
+     *  <LI><B>FKTABLE_NAME</B> String => foreign key table name
+     *  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
+     *  <LI><B>KEY_SEQ</B> short => (JDBC4 clarification) sequence number within a foreign key (a value
+     *  of 1 represents the first column of the foreign key, a value of 2 would
+     *  represent the second column within the foreign key).
+     *  <LI><B>UPDATE_RULE</B> short => What happens to a
+     *       foreign key when the primary key is updated:
+     *      <UL>
+     *      <LI> importedNoAction - do not allow update of primary
+     *               key if it has been imported
+     *      <LI> importedKeyCascade - change imported key to agree
+     *               with primary key update
+     *      <LI> importedKeySetNull - change imported key to <code>NULL</code>
+     *               if its primary key has been updated
+     *      <LI> importedKeySetDefault - change imported key to default values
+     *               if its primary key has been updated
+     *      <LI> importedKeyRestrict - same as importedKeyNoAction
+     *                                 (for ODBC 2.x compatibility)
+     *      </UL>
+     *  <LI><B>DELETE_RULE</B> short => What happens to
+     *      the foreign key when primary is deleted.
+     *      <UL>
+     *      <LI> importedKeyNoAction - do not allow delete of primary
+     *               key if it has been imported
+     *      <LI> importedKeyCascade - delete rows that import a deleted key
+     *      <LI> importedKeySetNull - change imported key to NULL if
+     *               its primary key has been deleted
+     *      <LI> importedKeyRestrict - same as importedKeyNoAction
+     *                                 (for ODBC 2.x compatibility)
+     *      <LI> importedKeySetDefault - change imported key to default if
+     *               its primary key has been deleted
+     *      </UL>
+     *  <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
+     *  <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
+     *  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
+     *      constraints be deferred until commit
+     *      <UL>
+     *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
+     *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
+     *      <LI> importedKeyNotDeferrable - see SQL92 for definition
+     *      </UL>
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schema a schema name; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param table a table name; must match the table name as it is stored
+     *        in the database
+     * @return <code>ResultSet</code> - each row is a primary key column description
+     * @exception SQLException if a database access error occurs
+     * @see #getExportedKeys
+     * @see #supportsMixedCaseQuotedIdentifiers
+     * @see #storesUpperCaseIdentifiers
+     */
+    public ResultSet getImportedKeys(String catalog, String schema,
+                                     String table) throws SQLException {
+
+        if (table == null) {
+            throw Util.nullArgument("table");
+        }
+        catalog = translateCatalog(catalog);
+        schema  = translateSchema(schema);
+
+        StringBuffer select = toQueryPrefix("SYSTEM_CROSSREFERENCE").append(
+            and("FKTABLE_CAT", "=", catalog)).append(
+            and("FKTABLE_SCHEM", "=", schema)).append(
+            and("FKTABLE_NAME", "=", table)).append(
+            " ORDER BY PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, KEY_SEQ");
+
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves a description of the foreign key columns that reference the
+     * given table's primary key columns (the foreign keys exported by a
+     * table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
+     * FKTABLE_NAME, and KEY_SEQ.
+     *
+     * <P>Each foreign key column description has the following columns:
+     *  <OL>
+     *  <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be <code>null</code>)
+     *  <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be <code>null</code>)
+     *  <LI><B>PKTABLE_NAME</B> String => primary key table name
+     *  <LI><B>PKCOLUMN_NAME</B> String => primary key column name
+     *  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
+     *      being exported (may be <code>null</code>)
+     *  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
+     *      being exported (may be <code>null</code>)
+     *  <LI><B>FKTABLE_NAME</B> String => foreign key table name
+     *      being exported
+     *  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
+     *      being exported
+     *  <LI><B>KEY_SEQ</B> short => (JDBC4 clarification:) sequence number within foreign key( a value
+     *  of 1 represents the first column of the foreign key, a value of 2 would
+     *  represent the second column within the foreign key).
+     *  <LI><B>UPDATE_RULE</B> short => What happens to
+     *       foreign key when primary is updated:
+     *      <UL>
+     *      <LI> importedNoAction - do not allow update of primary
+     *               key if it has been imported
+     *      <LI> importedKeyCascade - change imported key to agree
+     *               with primary key update
+     *      <LI> importedKeySetNull - change imported key to <code>NULL</code> if
+     *               its primary key has been updated
+     *      <LI> importedKeySetDefault - change imported key to default values
+     *               if its primary key has been updated
+     *      <LI> importedKeyRestrict - same as importedKeyNoAction
+     *                                 (for ODBC 2.x compatibility)
+     *      </UL>
+     *  <LI><B>DELETE_RULE</B> short => What happens to
+     *      the foreign key when primary is deleted.
+     *      <UL>
+     *      <LI> importedKeyNoAction - do not allow delete of primary
+     *               key if it has been imported
+     *      <LI> importedKeyCascade - delete rows that import a deleted key
+     *      <LI> importedKeySetNull - change imported key to <code>NULL</code> if
+     *               its primary key has been deleted
+     *      <LI> importedKeyRestrict - same as importedKeyNoAction
+     *                                 (for ODBC 2.x compatibility)
+     *      <LI> importedKeySetDefault - change imported key to default if
+     *               its primary key has been deleted
+     *      </UL>
+     *  <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
+     *  <LI><B>PK_NAME</B> String => primary key name (may be <code>null</code>)
+     *  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
+     *      constraints be deferred until commit
+     *      <UL>
+     *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
+     *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
+     *      <LI> importedKeyNotDeferrable - see SQL92 for definition
+     *      </UL>
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in this database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schema a schema name; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param table a table name; must match the table name as it is stored
+     *        in this database
+     * @return a <code>ResultSet</code> object in which each row is a
+     *         foreign key column description
+     * @exception SQLException if a database access error occurs
+     * @see #getImportedKeys
+     * @see #supportsMixedCaseQuotedIdentifiers
+     * @see #storesUpperCaseIdentifiers
+     */
+    public ResultSet getExportedKeys(String catalog, String schema,
+                                     String table) throws SQLException {
+
+        if (table == null) {
+            throw Util.nullArgument("table");
+        }
+        catalog = translateCatalog(catalog);
+        schema  = translateSchema(schema);
+
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_CROSSREFERENCE").append(and("PKTABLE_CAT",
+                "=", catalog)).append(and("PKTABLE_SCHEM", "=",
+                    schema)).append(and("PKTABLE_NAME", "=", table));
+
+        // By default, query already returns the table ordered by
+        // FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and KEY_SEQ.
+        return execute(select.toString());
+    }
+
+    /**
+     * (JDBC4 clarification:)
+     * Retrieves a description of the foreign key columns in the given foreign key
+     * table that reference the primary key or the columns representing a unique constraint of the  parent table (could be the same or a different table).
+     * The number of columns returned from the parent table must match the number of
+     * columns that make up the foreign key.  They
+     * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
+     * KEY_SEQ.
+     *
+     * <P>Each foreign key column description has the following columns:
+     *  <OL>
+     *  <LI><B>PKTABLE_CAT</B> String => parent key table catalog (may be <code>null</code>)
+     *  <LI><B>PKTABLE_SCHEM</B> String => parent key table schema (may be <code>null</code>)
+     *  <LI><B>PKTABLE_NAME</B> String => parent key table name
+     *  <LI><B>PKCOLUMN_NAME</B> String => parent key column name
+     *  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be <code>null</code>)
+     *      being exported (may be <code>null</code>)
+     *  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be <code>null</code>)
+     *      being exported (may be <code>null</code>)
+     *  <LI><B>FKTABLE_NAME</B> String => foreign key table name
+     *      being exported
+     *  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
+     *      being exported
+     *  <LI><B>KEY_SEQ</B> short => sequence number within foreign key( a value
+     *  of 1 represents the first column of the foreign key, a value of 2 would
+     *  represent the second column within the foreign key).
+     *  <LI><B>UPDATE_RULE</B> short => What happens to
+     *       foreign key when parent key is updated:
+     *      <UL>
+     *      <LI> importedNoAction - do not allow update of parent
+     *               key if it has been imported
+     *      <LI> importedKeyCascade - change imported key to agree
+     *               with parent key update
+     *      <LI> importedKeySetNull - change imported key to <code>NULL</code> if
+     *               its parent key has been updated
+     *      <LI> importedKeySetDefault - change imported key to default values
+     *               if its parent key has been updated
+     *      <LI> importedKeyRestrict - same as importedKeyNoAction
+     *                                 (for ODBC 2.x compatibility)
+     *      </UL>
+     *  <LI><B>DELETE_RULE</B> short => What happens to
+     *      the foreign key when parent key is deleted.
+     *      <UL>
+     *      <LI> importedKeyNoAction - do not allow delete of parent
+     *               key if it has been imported
+     *      <LI> importedKeyCascade - delete rows that import a deleted key
+     *      <LI> importedKeySetNull - change imported key to <code>NULL</code> if
+     *               its primary key has been deleted
+     *      <LI> importedKeyRestrict - same as importedKeyNoAction
+     *                                 (for ODBC 2.x compatibility)
+     *      <LI> importedKeySetDefault - change imported key to default if
+     *               its parent key has been deleted
+     *      </UL>
+     *  <LI><B>FK_NAME</B> String => foreign key name (may be <code>null</code>)
+     *  <LI><B>PK_NAME</B> String => parent key name (may be <code>null</code>)
+     *  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
+     *      constraints be deferred until commit
+     *      <UL>
+     *      <LI> importedKeyInitiallyDeferred - see SQL92 for definition
+     *      <LI> importedKeyInitiallyImmediate - see SQL92 for definition
+     *      <LI> importedKeyNotDeferrable - see SQL92 for definition
+     *      </UL>
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parentCatalog a catalog name; must match the catalog name
+     * as it is stored in the database; "" retrieves those without a
+     * catalog; <code>null</code> means drop catalog name from the selection criteria
+     * @param parentSchema a schema name; must match the schema name as
+     * it is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means drop schema name from the selection criteria
+     * @param parentTable the name of the table that exports the key; must match
+     * the table name as it is stored in the database
+     * @param foreignCatalog a catalog name; must match the catalog name as
+     * it is stored in the database; "" retrieves those without a
+     * catalog; <code>null</code> means drop catalog name from the selection criteria
+     * @param foreignSchema a schema name; must match the schema name as it
+     * is stored in the database; "" retrieves those without a schema;
+     * <code>null</code> means drop schema name from the selection criteria
+     * @param foreignTable the name of the table that imports the key; must match
+     * the table name as it is stored in the database
+     * @return <code>ResultSet</code> - each row is a foreign key column description
+     * @exception SQLException if a database access error occurs
+     * @see #getImportedKeys
+     * @see #supportsMixedCaseQuotedIdentifiers
+     * @see #storesUpperCaseIdentifiers
+     */
+    public ResultSet getCrossReference(
+            String parentCatalog, String parentSchema, String parentTable,
+            String foreignCatalog, String foreignSchema,
+            String foreignTable) throws SQLException {
+
+        if (parentTable == null) {
+            throw Util.nullArgument("parentTable");
+        }
+
+        if (foreignTable == null) {
+            throw Util.nullArgument("foreignTable");
+        }
+        parentCatalog  = translateCatalog(parentCatalog);
+        foreignCatalog = translateCatalog(foreignCatalog);
+        parentSchema   = translateSchema(parentSchema);
+        foreignSchema  = translateSchema(foreignSchema);
+
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_CROSSREFERENCE").append(and("PKTABLE_CAT",
+                "=", parentCatalog)).append(and("PKTABLE_SCHEM", "=",
+                    parentSchema)).append(and("PKTABLE_NAME", "=",
+                        parentTable)).append(and("FKTABLE_CAT", "=",
+                            foreignCatalog)).append(and("FKTABLE_SCHEM", "=",
+                                foreignSchema)).append(and("FKTABLE_NAME",
+                                    "=", foreignTable));
+
+        // by default, query already returns the table ordered by
+        // FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and KEY_SEQ.
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves a description of all the (JDBC4 clarification:) data types supported by
+     * this database. They are ordered by DATA_TYPE and then by how
+     * closely the data type maps to the corresponding JDBC SQL type.
+     *
+     * <P>(JDBC4 clarification:) If the database supports SQL distinct types, then getTypeInfo() will return
+     * a single row with a TYPE_NAME of DISTINCT and a DATA_TYPE of Types.DISTINCT.
+     * If the database supports SQL structured types, then getTypeInfo() will return
+     * a single row with a TYPE_NAME of STRUCT and a DATA_TYPE of Types.STRUCT.
+     *
+     * <P>(JDBC4 clarification:)
+     * <P>If SQL distinct or structured types are supported, then information on the
+     * individual types may be obtained from the getUDTs() method.
+     *
+     *
+     * <P>Each type description has the following columns:
+     *  <OL>
+     *  <LI><B>TYPE_NAME</B> String => Type name
+     *  <LI><B>DATA_TYPE</B> int => SQL data type from java.sql.Types
+     *  <LI><B>PRECISION</B> int => maximum precision
+     *  <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
+     *      (may be <code>null</code>)
+     *  <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
+     * (may be <code>null</code>)
+     *  <LI><B>CREATE_PARAMS</B> String => parameters used in creating
+     *      the type (may be <code>null</code>)
+     *  <LI><B>NULLABLE</B> short => can you use NULL for this type.
+     *      <UL>
+     *      <LI> typeNoNulls - does not allow NULL values
+     *      <LI> typeNullable - allows NULL values
+     *      <LI> typeNullableUnknown - nullability unknown
+     *      </UL>
+     *  <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive.
+     *  <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
+     *      <UL>
+     *      <LI> typePredNone - No support
+     *      <LI> typePredChar - Only supported with WHERE .. LIKE
+     *      <LI> typePredBasic - Supported except for WHERE .. LIKE
+     *      <LI> typeSearchable - Supported for all WHERE ..
+     *      </UL>
+     *  <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned.
+     *  <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value.
+     *  <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
+     *      auto-increment value.
+     *  <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
+     *      (may be <code>null</code>)
+     *  <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
+     *  <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
+     *  <LI><B>SQL_DATA_TYPE</B> int => unused
+     *  <LI><B>SQL_DATETIME_SUB</B> int => unused
+     *  <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
+     *  </OL>
+     *
+     * <p>(JDBC4 clarification:) The PRECISION column represents the maximum column size that the server supports for the given datatype.
+     * For numeric data, this is the maximum precision.  For character data, this is the [maximum] length in characters.
+     * For datetime datatypes, this is the [maximum] length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+     * this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+     * column size is not applicable.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>ResultSet</code> object in which each row is an SQL
+     *         type description
+     * @exception SQLException if a database access error occurs
+     */
+    public ResultSet getTypeInfo() throws SQLException {
+
+        // system table producer returns rows in contract order
+        return executeSelect("SYSTEM_TYPEINFO", null);
+    }
+
+    /**
+     * Retrieves a description of the given table's indices and statistics. They are
+     * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
+     *
+     * <P>Each index column description has the following columns:
+     *  <OL>
+     *  <LI><B>TABLE_CAT</B> String => table catalog (may be <code>null</code>)
+     *  <LI><B>TABLE_SCHEM</B> String => table schema (may be <code>null</code>)
+     *  <LI><B>TABLE_NAME</B> String => table name
+     *  <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique.
+     *      false when TYPE is tableIndexStatistic
+     *  <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be <code>null</code>);
+     *      <code>null</code> when TYPE is tableIndexStatistic
+     *  <LI><B>INDEX_NAME</B> String => index name; <code>null</code> when TYPE is
+     *      tableIndexStatistic
+     *  <LI><B>TYPE</B> short => index type:
+     *      <UL>
+     *      <LI> tableIndexStatistic - this identifies table statistics that are
+     *           returned in conjuction with a table's index descriptions
+     *      <LI> tableIndexClustered - this is a clustered index
+     *      <LI> tableIndexHashed - this is a hashed index
+     *      <LI> tableIndexOther - this is some other style of index
+     *      </UL>
+     *  <LI><B>ORDINAL_POSITION</B> short => column sequence number
+     *      within index; zero when TYPE is tableIndexStatistic
+     *  <LI><B>COLUMN_NAME</B> String => column name; <code>null</code> when TYPE is
+     *      tableIndexStatistic
+     *  <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
+     *      "D" => descending, may be <code>null</code> if sort sequence is not supported;
+     *      <code>null</code> when TYPE is tableIndexStatistic
+     *  <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
+     *      this is the number of rows in the table; otherwise, it is the
+     *      number of unique values in the index.
+     *  <LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then
+     *      this is the number of pages used for the table, otherwise it
+     *      is the number of pages used for the current index.
+     *  <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
+     *      (may be <code>null</code>)
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Since 1.7.2, this feature is supported by default. If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in this database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schema a schema name; must match the schema name
+     *        as it is stored in this database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param table a table name; must match the table name as it is stored
+     *        in this database
+     * @param unique when true, return only indices for unique values;
+     *     when false, return indices regardless of whether unique or not
+     * @param approximate when true, result is allowed to reflect approximate
+     *     or out of data values; when false, results are requested to be
+     *     accurate
+     * @return <code>ResultSet</code> - each row is an index column description
+     * @exception SQLException if a database access error occurs
+     * @see #supportsMixedCaseQuotedIdentifiers
+     * @see #storesUpperCaseIdentifiers
+     */
+    public ResultSet getIndexInfo(String catalog, String schema, String table,
+                                  boolean unique,
+                                  boolean approximate) throws SQLException {
+
+        if (table == null) {
+            throw Util.nullArgument("table");
+        }
+        catalog = translateCatalog(catalog);
+        schema  = translateSchema(schema);
+
+        Boolean nu = (unique) ? Boolean.FALSE
+                              : null;
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_INDEXINFO").append(and("TABLE_CAT", "=",
+                catalog)).append(and("TABLE_SCHEM", "=",
+                                     schema)).append(and("TABLE_NAME", "=",
+                                         table)).append(and("NON_UNIQUE", "=",
+                                             nu));
+
+        // By default, this query already returns the table ordered by
+        // NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION...
+        return execute(select.toString());
+    }
+
+    //--------------------------JDBC 2.0-----------------------------
+
+    /**
+     * Retrieves whether this database supports the given result set type.
+     *
+     * @param type defined in <code>java.sql.ResultSet</code>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @see JDBCConnection
+     * @since  JDK 1.2 (JDK 1.1.x developers: read the overview
+     *      for JDBCDatabaseMetaData)
+     */
+    public boolean supportsResultSetType(int type) throws SQLException {
+        return (type == JDBCResultSet.TYPE_FORWARD_ONLY
+                || type == JDBCResultSet.TYPE_SCROLL_INSENSITIVE);
+    }
+
+    /**
+     * Retrieves whether this database supports the given concurrency type
+     * in combination with the given result set type.
+     *
+     * @param type defined in <code>java.sql.ResultSet</code>
+     * @param concurrency type defined in <code>java.sql.ResultSet</code>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @see JDBCConnection
+     * @since  JDK 1.2 (JDK 1.1.x developers: read the overview
+     *      for JDBCDatabaseMetaData)
+     */
+    public boolean supportsResultSetConcurrency(int type,
+            int concurrency) throws SQLException {
+
+        return supportsResultSetType(type)
+               && (concurrency == JDBCResultSet.CONCUR_READ_ONLY
+                   || concurrency == JDBCResultSet.CONCUR_UPDATABLE);
+    }
+
+    /**
+     *
+     * Retrieves whether for the given type of <code>ResultSet</code> object,
+     * the result set's own updates are visible.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     * Updates to ResultSet rows are not visible after moving from the updated
+     * row.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if updates are visible for the given result set type;
+     *        <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean ownUpdatesAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether a result set's own deletes are visible.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Rows deleted from the ResultSet are still visible after moving from the
+     * deleted row.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if deletes are visible for the given result set type;
+     *        <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean ownDeletesAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether a result set's own inserts are visible.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Rows added to a ResultSet are not visible after moving from the
+     * insert row; this method always returns <code>false</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if inserts are visible for the given result set type;
+     *        <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean ownInsertsAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether updates made by others are visible.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Updates made by other connections or the same connection while the
+     * ResultSet is open are not visible in the ResultSet.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if updates made by others
+     *        are visible for the given result set type;
+     *        <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean othersUpdatesAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether deletes made by others are visible.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Deletes made by other connections or the same connection while the
+     * ResultSet is open are not visible in the ResultSet.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if deletes made by others
+     *        are visible for the given result set type;
+     *        <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean othersDeletesAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether inserts made by others are visible.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Inserts made by other connections or the same connection while the
+     * ResultSet is open are not visible in the ResultSet.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if inserts made by others
+     *         are visible for the given result set type;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean othersInsertsAreVisible(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether or not a visible row update can be detected by
+     * calling the method <code>ResultSet.rowUpdated</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Updates made to the rows of the ResultSet are not detected by
+     * calling the <code>ResultSet.rowUpdated</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if changes are detected by the result set type;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean updatesAreDetected(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether or not a visible row delete can be detected by
+     * calling the method <code>ResultSet.rowDeleted</code>.  If the method
+     * <code>deletesAreDetected</code> returns <code>false</code>, it means that
+     * deleted rows are removed from the result set.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Deletes made to the rows of the ResultSet are not detected by
+     * calling the <code>ResultSet.rowDeleted/code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if deletes are detected by the given result set type;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean deletesAreDetected(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether or not a visible row insert can be detected
+     * by calling the method <code>ResultSet.rowInserted</code>.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Inserts made into the ResultSet are not visible and thus not detected by
+     * calling the <code>ResultSet.rowInserted</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param type the <code>ResultSet</code> type; one of
+     *        <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *        <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     *        <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @return <code>true</code> if changes are detected by the specified result
+     *         set type; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean insertsAreDetected(int type) throws SQLException {
+        return false;
+    }
+
+    /**
+     * Retrieves whether this database supports batch updates.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports batch updates;
+     * this method always returns <code>true</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if this database supports batch upcates;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public boolean supportsBatchUpdates() throws SQLException {
+        return true;
+    }
+
+    /**
+     * Retrieves a description of the user-defined types (UDTs) defined
+     * in a particular schema.  Schema-specific UDTs may have type
+     * <code>JAVA_OBJECT</code>, <code>STRUCT</code>,
+     * or <code>DISTINCT</code>.
+     *
+     * <P>Only types matching the catalog, schema, type name and type
+     * criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM
+     * and TYPE_NAME.  The type name parameter may be a fully-qualified
+     * name.  In this case, the catalog and schemaPattern parameters are
+     * ignored.
+     *
+     * <P>Each type description has the following columns:
+     *  <OL>
+     *  <LI><B>TYPE_CAT</B> String => the type's catalog (may be <code>null</code>)
+     *  <LI><B>TYPE_SCHEM</B> String => type's schema (may be <code>null</code>)
+     *  <LI><B>TYPE_NAME</B> String => type name
+     *  <LI><B>CLASS_NAME</B> String => Java class name
+     *  <LI><B>DATA_TYPE</B> int => type value defined in java.sql.Types.
+     *     One of JAVA_OBJECT, STRUCT, or DISTINCT
+     *  <LI><B>REMARKS</B> String => explanatory comment on the type
+     *  <LI><B>BASE_TYPE</B> short => type code of the source type of a
+     *     DISTINCT type or the type that implements the user-generated
+     *     reference type of the SELF_REFERENCING_COLUMN of a structured
+     *     type as defined in java.sql.Types (<code>null</code> if DATA_TYPE is not
+     *     DISTINCT or not STRUCT with REFERENCE_GENERATION = USER_DEFINED)
+     *  </OL>
+     *
+     * <P><B>Note:</B> If the driver does not support UDTs, an empty
+     * result set is returned.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * Starting with 2.0, DISTICT types are supported and are reported by this
+     * method.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema pattern name; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param typeNamePattern a type name pattern; must match the type name
+     *        as it is stored in the database; may be a fully qualified name
+     * @param types a list of user-defined types (JAVA_OBJECT,
+     *        STRUCT, or DISTINCT) to include; <code>null</code> returns all types
+     * @return <code>ResultSet</code> object in which each row describes a UDT
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape (JDBC4 clarification)
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *     for JDBCDatabaseMetaData)
+     */
+    public ResultSet getUDTs(String catalog, String schemaPattern,
+                             String typeNamePattern,
+                             int[] types) throws SQLException {
+
+        if (wantsIsNull(typeNamePattern)
+                || (types != null && types.length == 0)) {
+            executeSelect("SYSTEM_UDTS", "0=1");
+        }
+        catalog       = translateCatalog(catalog);
+        schemaPattern = translateSchema(schemaPattern);
+
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_UDTS").append(and("TYPE_CAT", "=",
+                catalog)).append(and("TYPE_SCHEM", "LIKE",
+                                     schemaPattern)).append(and("TYPE_NAME",
+                                         "LIKE", typeNamePattern));
+
+        if (types == null) {
+
+            // do not use to narrow search
+        } else {
+            select.append(" AND DATA_TYPE IN (").append(
+                StringUtil.getList(types, ",", "")).append(')');
+        }
+
+        // By default, the query already returns a result ordered by
+        // DATA_TYPE, TYPE_SCHEM, and TYPE_NAME...
+        return execute(select.toString());
+    }
+
+    /**
+     * Retrieves the connection that produced this metadata object.
+     * <P>
+     * @return the connection that produced this metadata object
+     * @exception SQLException if a database access error occurs
+     * @since  JDK 1.2 (JDK 1.1.x developers: read the overview
+     *      for JDBCDatabaseMetaData)
+     */
+    public Connection getConnection() throws SQLException {
+        return connection;
+    }
+
+    // ------------------- JDBC 3.0 -------------------------
+
+    /**
+     * Retrieves whether this database supports savepoints.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Beginning with 1.7.2, this SQL feature is supported
+     * through JDBC as well as SQL. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if savepoints are supported;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public boolean supportsSavepoints() throws SQLException {
+        return true;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves whether this database supports named parameters to callable
+     * statements.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.7.2, HSQLDB supports JDBC named parameters to
+     * callable statements; this method returns true. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if named parameters are supported;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public boolean supportsNamedParameters() throws SQLException {
+        return true;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves whether it is possible to have multiple <code>ResultSet</code> objects
+     * returned from a <code>CallableStatement</code> object
+     * simultaneously.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports multiple ResultSet
+     * objects returned from a <code>CallableStatement</code>;
+     * this method always returns <code>true</code>. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if a <code>CallableStatement</code> object
+     *         can return multiple <code>ResultSet</code> objects
+     *         simultaneously; <code>false</code> otherwise
+     * @exception SQLException if a datanase access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public boolean supportsMultipleOpenResults() throws SQLException {
+        return true;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves whether auto-generated keys can be retrieved after
+     * a statement has been executed
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports retrieval of
+     * autogenerated keys through the JDBC interface;
+     * this method always returns <code>true</code>. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if auto-generated keys can be retrieved
+     *         after a statement has executed; <code>false</code> otherwise
+     * <p>(JDBC4 Clarification:)
+     * <p>If <code>true</code> is returned, the JDBC driver must support the
+     * returning of auto-generated keys for at least SQL INSERT statements
+     * <p>
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public boolean supportsGetGeneratedKeys() throws SQLException {
+        return true;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves a description of the user-defined type (UDT) hierarchies defined in a
+     * particular schema in this database. Only the immediate super type
+     * sub type relationship is modeled.
+     * <P>
+     * Only supertype information for UDTs matching the catalog,
+     * schema, and type name is returned. The type name parameter
+     * may be a fully-qualified name. When the UDT name supplied is a
+     * fully-qualified name, the catalog and schemaPattern parameters are
+     * ignored.
+     * <P>
+     * If a UDT does not have a direct super type, it is not listed here.
+     * A row of the <code>ResultSet</code> object returned by this method
+     * describes the designated UDT and a direct supertype. A row has the following
+     * columns:
+     *  <OL>
+     *  <LI><B>TYPE_CAT</B> String => the UDT's catalog (may be <code>null</code>)
+     *  <LI><B>TYPE_SCHEM</B> String => UDT's schema (may be <code>null</code>)
+     *  <LI><B>TYPE_NAME</B> String => type name of the UDT
+     *  <LI><B>SUPERTYPE_CAT</B> String => the direct super type's catalog
+     *                           (may be <code>null</code>)
+     *  <LI><B>SUPERTYPE_SCHEM</B> String => the direct super type's schema
+     *                             (may be <code>null</code>)
+     *  <LI><B>SUPERTYPE_NAME</B> String => the direct super type's name
+     *  </OL>
+     *
+     * <P><B>Note:</B> If the driver does not support type hierarchies, an
+     * empty result set is returned.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports the SQL Standard. It treats unquoted identifiers as
+     * case insensitive in SQL and stores
+     * them in upper case; it treats quoted identifiers as case sensitive and
+     * stores them verbatim. All JDBCDatabaseMetaData methods perform
+     * case-sensitive comparison between name (pattern) arguments and the
+     * corresponding identifier values as they are stored in the database.
+     * Therefore, care must be taken to specify name arguments precisely
+     * (including case) as they are stored in the database. <p>
+     *
+     * From 2.0, this feature is supported by default and return supertypes
+     * for DOMAIN and DISTINCT types.<p>
+     *
+     * If the jar is
+     * compiled without org.hsqldb.dbinfo.DatabaseInformationMain, the feature is
+     * not supported. The default implementation is
+     * {@link org.hsqldb.dbinfo.DatabaseInformationMain}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; "" retrieves those without a catalog;
+     *        <code>null</code> means drop catalog name from the selection criteria
+     * @param schemaPattern a schema name pattern; "" retrieves those
+     *        without a schema
+     * @param typeNamePattern a UDT name pattern; may be a fully-qualified
+     *        name
+     * @return a <code>ResultSet</code> object in which a row gives information
+     *         about the designated UDT
+     * @throws SQLException if a database access error occurs
+     * @see #getSearchStringEscape (JDBC4 clarification)
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public ResultSet getSuperTypes(
+            String catalog, String schemaPattern,
+            String typeNamePattern) throws SQLException {
+
+        if (wantsIsNull(typeNamePattern)) {
+            return executeSelect("SYSTEM_SUPERTYPES", "0=1");
+        }
+        catalog       = translateCatalog(catalog);
+        schemaPattern = translateSchema(schemaPattern);
+
+        StringBuffer select = toQueryPrefixNoSelect(
+            "SELECT * FROM (SELECT USER_DEFINED_TYPE_CATALOG, USER_DEFINED_TYPE_SCHEMA, USER_DEFINED_TYPE_NAME,"
+            + "CAST (NULL AS INFORMATION_SCHEMA.SQL_IDENTIFIER), CAST (NULL AS INFORMATION_SCHEMA.SQL_IDENTIFIER), DATA_TYPE "
+            + "FROM INFORMATION_SCHEMA.USER_DEFINED_TYPES "
+            + "UNION SELECT DOMAIN_CATALOG, DOMAIN_SCHEMA, DOMAIN_NAME,NULL,NULL, DATA_TYPE "
+            + "FROM INFORMATION_SCHEMA.DOMAINS) "
+            + "AS SUPERTYPES(TYPE_CAT, TYPE_SCHEM, TYPE_NAME, SUPERTYPE_CAT, SUPERTYPE_SCHEM, SUPERTYPE_NAME) ").append(
+                and("TYPE_CAT", "=", catalog)).append(
+                and("TYPE_SCHEM", "LIKE", schemaPattern)).append(
+                and("TYPE_NAME", "LIKE", typeNamePattern));
+
+        return execute(select.toString());
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves a description of the table hierarchies defined in a particular
+     * schema in this database.
+     *
+     * <P>Only supertable information for tables matching the catalog, schema
+     * and table name are returned. The table name parameter may be a fully-
+     * qualified name, in which case, the catalog and schemaPattern parameters
+     * are ignored. If a table does not have a super table, it is not listed here.
+     * Supertables have to be defined in the same catalog and schema as the
+     * sub tables. Therefore, the type description does not need to include
+     * this information for the supertable.
+     *
+     * <P>Each type description has the following columns:
+     *  <OL>
+     *  <LI><B>TABLE_CAT</B> String => the type's catalog (may be <code>null</code>)
+     *  <LI><B>TABLE_SCHEM</B> String => type's schema (may be <code>null</code>)
+     *  <LI><B>TABLE_NAME</B> String => type name
+     *  <LI><B>SUPERTABLE_NAME</B> String => the direct super type's name
+     *  </OL>
+     *
+     * <P><B>Note:</B> If the driver does not support type hierarchies, an
+     * empty result set is returned.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * This method is intended for tables of structured types.
+     * From 2.0 this method returns an empty ResultSet.
+     * {@link org.hsqldb.dbinfo.DatabaseInformationFull}.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; "" retrieves those without a catalog;
+     *        <code>null</code> means drop catalog name from the selection criteria
+     * @param schemaPattern a schema name pattern; "" retrieves those
+     *        without a schema
+     * @param tableNamePattern a table name pattern; may be a fully-qualified
+     *        name
+     * @return a <code>ResultSet</code> object in which each row is a type description
+     * @throws SQLException if a database access error occurs
+     * @see #getSearchStringEscape (JDBC4 clarification)
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public ResultSet getSuperTables(
+            String catalog, String schemaPattern,
+            String tableNamePattern) throws SQLException {
+
+        // query with no result
+        StringBuffer select = toQueryPrefixNoSelect(
+            "SELECT TABLE_NAME AS TABLE_CAT, TABLE_NAME AS TABLE_SCHEM, TABLE_NAME, TABLE_NAME AS SUPERTABLE_NAME "
+            + "FROM INFORMATION_SCHEMA.TABLES ").append(
+                and("TABLE_NAME", "=", ""));
+
+        return execute(select.toString());
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves a description of the given attribute of the given type
+     * for a user-defined type (UDT) that is available in the given schema
+     * and catalog.
+     * <P>
+     * Descriptions are returned only for attributes of UDTs matching the
+     * catalog, schema, type, and attribute name criteria. They are ordered by
+     * TYPE_SCHEM, TYPE_NAME and ORDINAL_POSITION. This description
+     * does not contain inherited attributes.
+     * <P>
+     * The <code>ResultSet</code> object that is returned has the following
+     * columns:
+     * <OL>
+     *  <LI><B>TYPE_CAT</B> String => type catalog (may be <code>null</code>)
+     *  <LI><B>TYPE_SCHEM</B> String => type schema (may be <code>null</code>)
+     *  <LI><B>TYPE_NAME</B> String => type name
+     *  <LI><B>ATTR_NAME</B> String => attribute name
+     *  <LI><B>DATA_TYPE</B> int => attribute type SQL type from java.sql.Types
+     *  <LI><B>ATTR_TYPE_NAME</B> String => Data source dependent type name.
+     *  For a UDT, the type name is fully qualified. For a REF, the type name is
+     *  fully qualified and represents the target type of the reference type.
+     *  <LI><B>ATTR_SIZE</B> int => column size.  For char or date
+     *      types this is the maximum number of characters; for numeric or
+     *      decimal types this is precision.
+     *  <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits. Null is returned for data types where
+     * DECIMAL_DIGITS is not applicable.
+     *  <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
+     *  <LI><B>NULLABLE</B> int => whether NULL is allowed
+     *      <UL>
+     *      <LI> attributeNoNulls - might not allow NULL values
+     *      <LI> attributeNullable - definitely allows NULL values
+     *      <LI> attributeNullableUnknown - nullability unknown
+     *      </UL>
+     *  <LI><B>REMARKS</B> String => comment describing column (may be <code>null</code>)
+     *  <LI><B>ATTR_DEF</B> String => default value (may be <code>null</code>)
+     *  <LI><B>SQL_DATA_TYPE</B> int => unused
+     *  <LI><B>SQL_DATETIME_SUB</B> int => unused
+     *  <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
+     *       maximum number of bytes in the column
+     *  <LI><B>ORDINAL_POSITION</B> int => index of column in table
+     *      (starting at 1)
+     *  <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine the nullability for a column.
+     *       <UL>
+     *       <LI> YES           --- if the parameter can include NULLs
+     *       <LI> NO            --- if the parameter cannot include NULLs
+     *       <LI> empty string  --- if the nullability for the
+     * parameter is unknown
+     *       </UL>
+     *  <LI><B>SCOPE_CATALOG</B> String => catalog of table that is the
+     *      scope of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+     *  <LI><B>SCOPE_SCHEMA</B> String => schema of table that is the
+     *      scope of a reference attribute (<code>null</code> if DATA_TYPE isn't REF)
+     *  <LI><B>SCOPE_TABLE</B> String => table name that is the scope of a
+     *      reference attribute (<code>null</code> if the DATA_TYPE isn't REF)
+     * <LI><B>SOURCE_DATA_TYPE</B> short => source type of a distinct type or user-generated
+     *      Ref type,SQL type from java.sql.Types (<code>null</code> if DATA_TYPE
+     *      isn't DISTINCT or user-generated REF)
+     *  </OL>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * This method is intended for attributes of structured types.
+     * From 2.0 this method returns an empty ResultSet.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema name pattern; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param typeNamePattern a type name pattern; must match the
+     *        type name as it is stored in the database
+     * @param attributeNamePattern an attribute name pattern; must match the attribute
+     *        name as it is declared in the database
+     * @return a <code>ResultSet</code> object in which each row is an
+     *         attribute description
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public ResultSet getAttributes(
+            String catalog, String schemaPattern, String typeNamePattern,
+            String attributeNamePattern) throws SQLException {
+
+        StringBuffer select = toQueryPrefixNoSelect(
+            "SELECT TABLE_NAME AS TYPE_CAT, TABLE_NAME AS TYPE_SCHME, TABLE_NAME AS TYPE_NAME, "
+            + "TABLE_NAME AS ATTR_NAME, CAST(0 AS INTEGER) AS DATA_TYPE, TABLE_NAME AS ATTR_TYPE_NAME, "
+            + "CAST(0 AS INTEGER) AS ATTR_SIZE, CAST(0 AS INTEGER) AS DECIMAL_DIGITS, "
+            + "CAST(0 AS INTEGER) AS NUM_PREC_RADIX, CAST(0 AS INTEGER) AS NULLABLE, "
+            + "'' AS REMARK, '' AS ATTR_DEF, CAST(0 AS INTEGER) AS SQL_DATA_TYPE, "
+            + "CAST(0 AS INTEGER) AS SQL_DATETIME_SUB, CAST(0 AS INTEGER) AS CHAR_OCTECT_LENGTH, "
+            + "CAST(0 AS INTEGER) AS ORDINAL_POSITION, '' AS NULLABLE, "
+            + "'' AS SCOPE_CATALOG, '' AS SCOPE_SCHEMA, '' AS SCOPE_TABLE, "
+            + "CAST(0 AS SMALLINT) AS SCOPE_DATA_TYPE "
+            + "FROM INFORMATION_SCHEMA.TABLES ").append(
+                and("TABLE_NAME", "=", ""));
+
+        return execute(select.toString());
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves whether this database supports the given result set holdability.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB returns true for both alternatives. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param holdability one of the following constants:
+     *          <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *          <code>ResultSet.CLOSE_CURSORS_AT_COMMIT<code>
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @see JDBCConnection
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public boolean supportsResultSetHoldability(
+            int holdability) throws SQLException {
+        return holdability == JDBCResultSet.HOLD_CURSORS_OVER_COMMIT
+               || holdability == JDBCResultSet.CLOSE_CURSORS_AT_COMMIT;
+    }
+
+//#endif JAVA4
+
+    /**
+     * (JDBC4 clarification:)
+     * Retrieves this database's default holdability for <code>ResultSet</code>
+     * objects.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB defaults to HOLD_CURSORS_OVER_COMMIT for CONSUR_READ_ONLY
+     * ResultSet objects.
+     * If the ResultSet concurrency is CONCUR_UPDATABLE, then holdability is
+     * is enforced as CLOSE_CURSORS_AT_COMMIT. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the default holdability; either
+     *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public int getResultSetHoldability() throws SQLException {
+        return JDBCResultSet.HOLD_CURSORS_OVER_COMMIT;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves the major version number of the underlying database.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     * Returns the major version
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return the underlying database's major version
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public int getDatabaseMajorVersion() throws SQLException {
+
+        ResultSet rs = execute("call database_version()");
+
+        rs.next();
+
+        String v = rs.getString(1);
+
+        rs.close();
+
+        return Integer.parseInt(v.substring(0, v.indexOf(".")));
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves the minor version number of the underlying database.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * This returns the digit after the first point in version.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return underlying database's minor version
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public int getDatabaseMinorVersion() throws SQLException {
+
+        ResultSet rs = execute("call database_version()");
+
+        rs.next();
+
+        String v = rs.getString(1);
+
+        rs.close();
+
+        int start = v.indexOf(".") + 1;
+
+        return Integer.parseInt(v.substring(start, v.indexOf(".", start)));
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves the major JDBC version number for this
+     * driver.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return JDBC version major number
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public int getJDBCMajorVersion() throws SQLException {
+        return JDBC_MAJOR;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves the minor JDBC version number for this
+     * driver.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return JDBC version minor number
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public int getJDBCMinorVersion() throws SQLException {
+        return 0;
+    }
+
+//#endif JAVA4
+
+    /**
+     * (JDBC4 modified:)
+     * Indicates whether the SQLSTATE returned by <code>SQLException.getSQLState</code>
+     * is X/Open (now known as Open Group) SQL CLI or SQL:2003.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB returns  <code>sqlStateSQL</code> under JDBC4 which is equivalent
+     * to JDBC3 value of sqlStateSQL99. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return the type of SQLSTATE; one of:
+     *        sqlStateXOpen or
+     *        sqlStateSQL
+     *
+     * <p>sqlStateSQL is new in JDBC4 and its value is the same as JDBC3 sqlStateSQL99
+     * @throws SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public int getSQLStateType() throws SQLException {
+        return sqlStateSQL99;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Indicates whether updates made to a LOB are made on a copy or directly
+     * to the LOB.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Updates to a LOB are made directly.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if updates are made to a copy of the LOB;
+     *         <code>false</code> if updates are made directly to the LOB
+     * @throws SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public boolean locatorsUpdateCopy() throws SQLException {
+        return false;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Retrieves whether this database supports statement pooling.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB supports statement pooling when built under
+     * JDK 1.6+. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @throws SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public boolean supportsStatementPooling() throws SQLException {
+        return (JDBC_MAJOR >= 4);
+    }
+
+//#endif JAVA4
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * Indicates whether or not this data source supports the SQL <code>ROWID</code> type,
+     * and if so  the lifetime for which a <code>RowId</code> object remains valid.
+     * <p>
+     * The returned int values have the following relationship:
+     * <pre>
+     *     ROWID_UNSUPPORTED < ROWID_VALID_OTHER < ROWID_VALID_TRANSACTION
+     *         < ROWID_VALID_SESSION < ROWID_VALID_FOREVER
+     * </pre>
+     * so conditional logic such as
+     * <pre>
+     *     if (metadata.getRowIdLifetime() > DatabaseMetaData.ROWID_VALID_TRANSACTION)
+     * </pre>
+     * can be used. Valid Forever means valid across all Sessions, and valid for
+     * a Session means valid across all its contained Transactions.
+     *
+     * @return the status indicating the lifetime of a <code>RowId</code>
+     * @throws SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    public RowIdLifetime getRowIdLifetime() throws SQLException {
+        return RowIdLifetime.ROWID_UNSUPPORTED;
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the schema names available in this database.  The results
+     * are ordered by schema name.
+     *
+     * <P>The schema columns are:
+     *  <OL>
+     *  <LI><B>TABLE_SCHEM</B> String => schema name
+     *  <LI><B>TABLE_CATALOG</B> String => catalog name (may be <code>null</code>)
+     *  </OL>
+     *
+     *
+     * @param catalog a catalog name; must match the catalog name as it is stored
+     * in the database;"" retrieves those without a catalog; null means catalog
+     * name should not be used to narrow down the search.
+     * @param schemaPattern a schema name; must match the schema name as it is
+     * stored in the database; null means
+     * schema name should not be used to narrow down the search.
+     * @return a <code>ResultSet</code> object in which each row is a
+     *         schema description
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    public ResultSet getSchemas(String catalog,
+                                String schemaPattern) throws SQLException {
+
+        StringBuffer select =
+            toQueryPrefix("SYSTEM_SCHEMAS").append(and("TABLE_CATALOG", "=",
+                catalog)).append(and("TABLE_SCHEM", "LIKE", schemaPattern));
+
+        // By default, query already returns result in contract order
+        return execute(select.toString());
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves whether this database supports invoking user-defined or vendor functions
+     * using the stored procedure escape syntax.
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+        return true;
+    }
+
+//#endif JAVA6
+
+    /** @todo */
+
+    /**
+     * Retrieves whether a <code>SQLException</code> while autoCommit is <code>true</code> inidcates
+     * that all open ResultSets are closed, even ones that are holdable.  When a <code>SQLException</code> occurs while
+     * autocommit is <code>true</code>, it is vendor specific whether the JDBC driver responds with a commit operation, a
+     * rollback operation, or by doing neither a commit nor a rollback.  A potential result of this difference
+     * is in whether or not holdable ResultSets are closed.
+     *
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+        return false;
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves a list of the client info properties
+     * that the driver supports.  The result set contains the following columns
+     * <p>
+     * <ol>
+     * <li><b>NAME</b> String=> The name of the client info property<br>
+     * <li><b>MAX_LEN</b> int=> The maximum length of the value for the property<br>
+     * <li><b>DEFAULT_VALUE</b> String=> The default value of the property<br>
+     * <li><b>DESCRIPTION</b> String=> A description of the property.  This will typically
+     *                                                  contain information as to where this property is
+     *                                                  stored in the database.
+     * </ol>
+     * <p>
+     * The <code>ResultSet</code> is sorted by the NAME column
+     * <p>
+     * @return  A <code>ResultSet</code> object; each row is a supported client info
+     * property
+     * <p>
+     *  @exception SQLException if a database access error occurs
+     * <p>
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    public ResultSet getClientInfoProperties() throws SQLException {
+
+        String s =
+            "SELECT * FROM INFORMATION_SCHEMA.SYSTEM_CONNECTION_PROPERTIES";
+
+        return execute(s);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves a description of the user functions available in the given
+     * catalog.
+     * <P>
+     * Only system and user function descriptions matching the schema and
+     * function name criteria are returned.  They are ordered by
+     * <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>,
+     * <code>FUNCTION_NAME</code> and
+     * <code>SPECIFIC_ NAME</code>.
+     *
+     * <P>Each function description has the the following columns:
+     *  <OL>
+     *  <LI><B>FUNCTION_CAT</B> String => function catalog (may be <code>null</code>)
+     *  <LI><B>FUNCTION_SCHEM</B> String => function schema (may be <code>null</code>)
+     *  <LI><B>FUNCTION_NAME</B> String => function name.  This is the name
+     * used to invoke the function
+     *  <LI><B>REMARKS</B> String => explanatory comment on the function
+     * <LI><B>FUNCTION_TYPE</B> short => kind of function:
+     *      <UL>
+     *      <LI>functionResultUnknown - Cannot determine if a return value
+     *       or table will be returned
+     *      <LI> functionNoTable- Does not return a table
+     *      <LI> functionReturnsTable - Returns a table
+     *      </UL>
+     *  <LI><B>SPECIFIC_NAME</B> String  => the name which uniquely identifies
+     *  this function within its schema.  This is a user specified, or DBMS
+     * generated, name that may be different then the <code>FUNCTION_NAME</code>
+     * for example with overload functions
+     *  </OL>
+     * <p>
+     * A user may not have permission to execute any of the functions that are
+     * returned by <code>getFunctions</code>
+     *
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema name pattern; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param functionNamePattern a function name pattern; must match the
+     *        function name as it is stored in the database
+     * @return <code>ResultSet</code> - each row is a function description
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    public ResultSet getFunctions(
+            String catalog, String schemaPattern,
+            String functionNamePattern) throws SQLException {
+
+        StringBuffer sb = new StringBuffer(256);
+
+        sb.append("select ").append(
+            "sp.procedure_cat as FUNCTION_CAT,").append(
+            "sp.procedure_schem as FUNCTION_SCHEM,").append(
+            "sp.procedure_name as FUNCTION_NAME,").append(
+            "sp.remarks as REMARKS,").append("1 as FUNCTION_TYPE,").append(
+            "sp.specific_name as SPECIFIC_NAME ").append(
+            "from information_schema.system_procedures sp ").append(
+            "where sp.procedure_type = 2 ");
+
+        if (wantsIsNull(functionNamePattern)) {
+            return execute(sb.append("and 1=0").toString());
+        }
+        schemaPattern = translateSchema(schemaPattern);
+
+        sb.append(and("sp.procedure_cat", "=",
+                      catalog)).append(and("sp.procedure_schem", "LIKE",
+                          schemaPattern)).append(and("sp.procedure_name",
+                              "LIKE", functionNamePattern));
+
+        // By default, query already returns the result ordered by
+        // FUNCTION_SCHEM, FUNCTION_NAME...
+        return execute(sb.toString());
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves a description of the given catalog's system or user
+     * function parameters and return type.
+     *
+     * <P>Only descriptions matching the schema,  function and
+     * parameter name criteria are returned. They are ordered by
+     * <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>,
+     * <code>FUNCTION_NAME</code> and
+     * <code>SPECIFIC_ NAME</code>. Within this, the return value,
+     * if any, is first. Next are the parameter descriptions in call
+     * order. The column descriptions follow in column number order.
+     *
+     * <P>Each row in the <code>ResultSet</code>
+     * is a parameter description, column description or
+     * return type description with the following fields:
+     *  <OL>
+     *  <LI><B>FUNCTION_CAT</B> String => function catalog (may be <code>null</code>)
+     *  <LI><B>FUNCTION_SCHEM</B> String => function schema (may be <code>null</code>)
+     *  <LI><B>FUNCTION_NAME</B> String => function name.  This is the name
+     * used to invoke the function
+     *  <LI><B>COLUMN_NAME</B> String => column/parameter name
+     *  <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
+     *      <UL>
+     *      <LI> functionColumnUnknown - nobody knows
+     *      <LI> functionColumnIn - IN parameter
+     *      <LI> functionColumnInOut - INOUT parameter
+     *      <LI> functionColumnOut - OUT parameter
+     *      <LI> functionColumnReturn - function return value
+     *      <LI> functionColumnResult - Indicates that the parameter or column
+     *  is a column in the <code>ResultSet</code>
+     *      </UL>
+     *  <LI><B>DATA_TYPE</B> int => SQL type from java.sql.Types
+     *  <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
+     *  type name is fully qualified
+     *  <LI><B>PRECISION</B> int => precision
+     *  <LI><B>LENGTH</B> int => length in bytes of data
+     *  <LI><B>SCALE</B> short => scale -  null is returned for data types where
+     * SCALE is not applicable.
+     *  <LI><B>RADIX</B> short => radix
+     *  <LI><B>NULLABLE</B> short => can it contain NULL.
+     *      <UL>
+     *      <LI> functionNoNulls - does not allow NULL values
+     *      <LI> functionNullable - allows NULL values
+     *      <LI> functionNullableUnknown - nullability unknown
+     *      </UL>
+     *  <LI><B>REMARKS</B> String => comment describing column/parameter
+     *  <LI><B>CHAR_OCTET_LENGTH</B> int  => the maximum length of binary
+     * and character based parameters or columns.  For any other datatype the returned value
+     * is a NULL
+     *  <LI><B>ORDINAL_POSITION</B> int  => the ordinal position, starting
+     * from 1, for the input and output parameters. A value of 0
+     * is returned if this row describes the function's return value.
+     * For result set columns, it is the
+     * ordinal position of the column in the result set starting from 1.
+     *  <LI><B>IS_NULLABLE</B> String  => ISO rules are used to determine
+     * the nullability for a parameter or column.
+     *       <UL>
+     *       <LI> YES           --- if the parameter or column can include NULLs
+     *       <LI> NO            --- if the parameter or column  cannot include NULLs
+     *       <LI> empty string  --- if the nullability for the
+     * parameter  or column is unknown
+     *       </UL>
+     *  <LI><B>SPECIFIC_NAME</B> String  => the name which uniquely identifies
+     * this function within its schema.  This is a user specified, or DBMS
+     * generated, name that may be different then the <code>FUNCTION_NAME</code>
+     * for example with overload functions
+     *  </OL>
+     *
+     * <p>The PRECISION column represents the specified column size for the given
+     * parameter or column.
+     * For numeric data, this is the maximum precision.  For character data, this is the length in characters.
+     * For datetime datatypes, this is the length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary data, this is the length in bytes.  For the ROWID datatype,
+     * this is the length in bytes. Null is returned for data types where the
+     * column size is not applicable.
+     * @param catalog a catalog name; must match the catalog name as it
+     *        is stored in the database; "" retrieves those without a catalog;
+     *        <code>null</code> means that the catalog name should not be used to narrow
+     *        the search
+     * @param schemaPattern a schema name pattern; must match the schema name
+     *        as it is stored in the database; "" retrieves those without a schema;
+     *        <code>null</code> means that the schema name should not be used to narrow
+     *        the search
+     * @param functionNamePattern a procedure name pattern; must match the
+     *        function name as it is stored in the database
+     * @param columnNamePattern a parameter name pattern; must match the
+     * parameter or column name as it is stored in the database
+     * @return <code>ResultSet</code> - each row describes a
+     * user function parameter, column  or return type
+     *
+     * @exception SQLException if a database access error occurs
+     * @see #getSearchStringEscape
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    public ResultSet getFunctionColumns(
+            String catalog, String schemaPattern, String functionNamePattern,
+            String columnNamePattern) throws SQLException {
+
+        StringBuffer sb = new StringBuffer(256);
+
+        sb.append("select pc.procedure_cat as FUNCTION_CAT,").append(
+            "pc.procedure_schem as FUNCTION_SCHEM,").append(
+            "pc.procedure_name as FUNCTION_NAME,").append(
+            "pc.column_name as COLUMN_NAME,").append(
+            "case pc.column_type").append(" when 3 then 5").append(
+            " when 4 then 3").append(" when 5 then 4").append(
+            " else pc.column_type").append(" end as COLUMN_TYPE,").append(
+            "pc.DATA_TYPE,").append("pc.TYPE_NAME,").append(
+            "pc.PRECISION,").append("pc.LENGTH,").append("pc.SCALE,").append(
+            "pc.RADIX,").append("pc.NULLABLE,").append("pc.REMARKS,").append(
+            "pc.CHAR_OCTET_LENGTH,").append("pc.ORDINAL_POSITION,").append(
+            "pc.IS_NULLABLE,").append("pc.SPECIFIC_NAME,").append(
+            "case pc.column_type").append(" when 3 then 1").append(
+            " else 0").append(" end AS COLUMN_GROUP ").append(
+            "from information_schema.system_procedurecolumns pc ").append(
+            "join (select procedure_schem,").append("procedure_name,").append(
+            "specific_name ").append(
+            "from information_schema.system_procedures ").append(
+            "where procedure_type = 2) p ").append(
+            "on pc.procedure_schem = p.procedure_schem ").append(
+            "and pc.procedure_name = p.procedure_name ").append(
+            "and pc.specific_name = p.specific_name ").append(
+            "and ((pc.column_type = 3 and pc.column_name = '@p0') ").append(
+            "or ").append("(pc.column_type <> 3)) ");
+
+        if (wantsIsNull(functionNamePattern)
+                || wantsIsNull(columnNamePattern)) {
+            return execute(sb.append("where 1=0").toString());
+        }
+        schemaPattern = translateSchema(schemaPattern);
+
+        sb.append("where 1=1 ").append(
+            and("pc.procedure_cat", "=", catalog)).append(
+            and("pc.procedure_schem", "LIKE", schemaPattern)).append(
+            and("pc.procedure_name", "LIKE", functionNamePattern)).append(
+            and("pc.column_name", "LIKE", columnNamePattern)).append(
+            " order by 1, 2, 3, 17, 18 , 15");
+
+        // Order by FUNCTION_CAT, FUNCTION_SCHEM, FUNCTION_NAME, SPECIFIC_NAME
+        //      COLUMN_GROUP and ORDINAL_POSITION
+        return execute(sb.toString());
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns an object that implements the given interface to allow access to non-standard methods,
+     * or standard methods not exposed by the proxy.
+     * The result may be either the object found to implement the interface or a proxy for that object.
+     * If the receiver implements the interface then that is the object. If the receiver is a wrapper
+     * and the wrapped object implements the interface then that is the object. Otherwise the object is
+     *  the result of calling <code>unwrap</code> recursively on the wrapped object. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+    public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 1.9
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+    //----------------------- Internal Implementation --------------------------
+
+    /** Used by getBestRowIdentifier to avoid extra object construction */
+    static final Integer INT_COLUMNS_NO_NULLS = new Integer(columnNoNulls);
+
+    // -----------------------------------------------------------------------
+    // private attributes
+    // -----------------------------------------------------------------------
+
+    /**
+     * The connection this object uses to retrieve database instance-specific
+     * metadata.
+     */
+    private JDBCConnection connection;
+
+    /**
+     * Connection property for schema reporting.
+     */
+    final private boolean useSchemaDefault;
+
+    /**
+     * A CSV list representing the SQL IN list to use when generating
+     * queries for <code>getBestRowIdentifier</code> when the
+     * <code>scope</code> argument is <code>bestRowSession</code>.
+     * @since HSQLDB 1.7.2
+     */
+    private static final String BRI_SESSION_SCOPE_IN_LIST = "("
+        + bestRowSession + ")";
+
+    /**
+     * A CSV list representing the SQL IN list to use when generating
+     * queries for <code>getBestRowIdentifier</code> when the
+     * <code>scope</code> argument is <code>bestRowTemporary</code>.
+     * @since HSQLDB 1.7.2
+     */
+    private static final String BRI_TEMPORARY_SCOPE_IN_LIST = "("
+        + bestRowTemporary + "," + bestRowTransaction + "," + bestRowSession
+        + ")";
+
+    /**
+     * A CSV list representing the SQL IN list to use when generating
+     * queries for <code>getBestRowIdentifier</code> when the
+     * <code>scope</code> argument is <code>bestRowTransaction</code>.
+     * @since HSQLDB 1.7.2
+     */
+    private static final String BRI_TRANSACTION_SCOPE_IN_LIST = "("
+        + bestRowTransaction + "," + bestRowSession + ")";
+
+    /**
+     * "SELECT * FROM ". <p>
+     *
+     * This attribute is in support of methods that use SQL SELECT statements to
+     * generate returned <code>ResultSet</code> objects. <p>
+     *
+     * @since HSQLDB 1.7.2
+     */
+    private static final String selstar = "SELECT * FROM INFORMATION_SCHEMA.";
+
+    /**
+     * " WHERE TRUE ". <p>
+     *
+     * This attribute is in support of methods that use SQL SELECT statements to
+     * generate returned <code>ResultSet</code> objects. <p>
+     *
+     * A good optimizer will simply drop this when parsing a condition
+     * expression. And it makes our code much easier to write, since we don't
+     * have to check our "WHERE" clause productions as strictly for proper
+     * conjunction:  we just stick additional conjunctive predicates on the
+     * end of this and Presto! Everything works :-) <p>
+     * @since HSQLDB 1.7.2
+     */
+    private static final String whereTrue = " WHERE TRUE";
+
+//#ifdef JAVA6
+    public static final int JDBC_MAJOR = 4;
+
+//#else
+/*
+    public static final int JDBC_MAJOR = 3;
+*/
+
+//#endif JAVA6
+
+    /**
+     * Constructs a new <code>JDBCDatabaseMetaData</code> object using the
+     * specified connection.  This contructor is used by <code>JDBCConnection</code>
+     * when producing a <code>DatabaseMetaData</code> object from a call to
+     * {@link JDBCConnection#getMetaData() getMetaData}.
+     * @param c the connection this object will use to retrieve
+     *         instance-specific metadata
+     * @throws SQLException never - reserved for future use
+     */
+    JDBCDatabaseMetaData(JDBCConnection c) throws SQLException {
+
+        // PRE: is non-null and not closed
+        connection       = c;
+        useSchemaDefault = c.isInternal ? false
+                                        : c.connProperties
+                                        .isPropertyTrue(HsqlDatabaseProperties
+                                            .url_default_schema);
+    }
+
+    /**
+     * Retrieves an "AND" predicate based on the (column) <code>id</code>,
+     * <code>op</code>(erator) and<code>val</code>(ue) arguments to be
+     * included in an SQL "WHERE" clause, using the conventions laid out for
+     * JDBC DatabaseMetaData filter parameter values. <p>
+     *
+     * @return an "AND" predicate built from the arguments
+     * @param id the simple, non-quoted identifier of a system table
+     *      column upon which to filter. <p>
+     *
+     *      No checking is done for column name validity. <br>
+     *      It is assumed the system table column name is correct. <p>
+     *
+     * @param op the conditional operation to perform using the system table
+     *      column name value and the <code>val</code> argument. <p>
+     *
+     * @param val an object representing the value to use in some conditional
+     *      operation, op, between the column identified by the id argument
+     *      and this argument. <p>
+     *
+     *      <UL>
+     *          <LI>null causes the empty string to be returned. <p>
+     *
+     *          <LI>toString().length() == 0 causes the returned expression
+     *              to be built so that the IS NULL operation will occur
+     *              against the specified column. <p>
+     *
+     *          <LI>instanceof String causes the returned expression to be
+     *              built so that the specified operation will occur between
+     *              the specified column and the specified value, converted to
+     *              an SQL string (single quoted, with internal single quotes
+     *              escaped by doubling). If <code>op</code> is "LIKE" and
+     *              <code>val</code> does not contain any "%" or "_" wild
+     *              card characters, then <code>op</code> is silently
+     *              converted to "=". <p>
+     *
+     *          <LI>!instanceof String causes an expression to built so that
+     *              the specified operation will occur between the specified
+     *              column and <code>String.valueOf(val)</code>. <p>
+     *
+     *      </UL>
+     */
+    private static String and(String id, String op, Object val) {
+
+        // The JDBC standard for pattern arguments seems to be:
+        //
+        // - pass null to mean ignore (do not include in query),
+        // - pass "" to mean filter on <column-ident> IS NULL,
+        // - pass "%" to filter on <column-ident> IS NOT NULL.
+        // - pass sequence with "%" and "_" for wildcard matches
+        // - when searching on values reported directly from DatabaseMetaData
+        //   results, typically an exact match is desired.  In this case, it
+        //   is the client's responsibility to escape any reported "%" and "_"
+        //   characters using whatever DatabaseMetaData returns from
+        //   getSearchEscapeString(). In our case, this is the standard escape
+        //   character: '\'. Typically, '%' will rarely be encountered, but
+        //   certainly '_' is to be expected on a regular basis.
+        // - checkme:  what about the (silly) case where an identifier
+        //   has been declared such as:  'create table "xxx\_yyy"(...)'?
+        //   Must the client still escape the Java string like this:
+        //   "xxx\\\\_yyy"?
+        //   Yes: because otherwise the driver is expected to
+        //   construct something like:
+        //   select ... where ... like 'xxx\_yyy' escape '\'
+        //   which will try to match 'xxx_yyy', not 'xxx\_yyy'
+        //   Testing indicates that indeed, higher quality popular JDBC
+        //   database browsers do the escapes "properly."
+        if (val == null) {
+            return "";
+        }
+
+        StringBuffer sb    = new StringBuffer();
+        boolean      isStr = (val instanceof String);
+
+        if (isStr && ((String) val).length() == 0) {
+            return sb.append(" AND ").append(id).append(" IS NULL").toString();
+        }
+
+        String v = isStr ? Type.SQL_VARCHAR.convertToSQLString(val)
+                         : String.valueOf(val);
+
+        sb.append(" AND ").append(id).append(' ');
+
+        // add the escape to like if required
+        if (isStr && "LIKE".equalsIgnoreCase(op)) {
+            if (v.indexOf('_') < 0 && v.indexOf('%') < 0) {
+
+                // then we can optimize.
+                sb.append("=").append(' ').append(v);
+            } else {
+                sb.append("LIKE").append(' ').append(v);
+
+                if ((v.indexOf("\\_") >= 0) || (v.indexOf("\\%") >= 0)) {
+
+                    // then client has requested at least one escape.
+                    sb.append(" ESCAPE '\\'");
+                }
+            }
+        } else {
+            sb.append(op).append(' ').append(v);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * The main SQL statement executor.  All SQL destined for execution
+     * ultimately goes through this method. <p>
+     *
+     * The sqlStatement field for the result is set autoClose to comply with
+     * ResultSet.getStatement() semantics for result sets that are not from
+     * a user supplied Statement object. (fredt) <p>
+     *
+     * @param sql SQL statement to execute
+     * @return the result of issuing the statement
+     * @throws SQLException is a database error occurs
+     */
+    private ResultSet execute(String sql) throws SQLException {
+
+        // NOTE:
+        // Need to create a JDBCStatement here so JDBCResultSet can return
+        // its Statement object on call to getStatement().
+        // The native JDBCConnection.execute() method does not
+        // automatically assign a Statement object for the ResultSet, but
+        // JDBCStatement does.  That is, without this, there is no way for the
+        // JDBCResultSet to find its way back to its Connection (or Statement)
+        // Also, cannot use single, shared JDBCStatement object, as each
+        // fetchResult() closes any old JDBCResultSet before fetching the
+        // next, causing the JDBCResultSet's Result object to be nullified
+        final int scroll = JDBCResultSet.TYPE_SCROLL_INSENSITIVE;
+        final int concur = JDBCResultSet.CONCUR_READ_ONLY;
+        JDBCStatement st = (JDBCStatement) connection.createStatement(scroll,
+            concur);
+
+        st.maxRows = -1;
+
+        ResultSet r = st.executeQuery(sql);
+
+        ((JDBCResultSet) r).autoClose = true;
+
+        return r;
+    }
+
+    /**
+     * An SQL statement executor that knows how to create a "SELECT
+     * * FROM" statement, given a table name and a <em>where</em> clause.<p>
+     *
+     *  If the <em>where</em> clause is null, it is ommited.  <p>
+     *
+     *  It is assumed that the table name is non-null, since this is a private
+     *  method.  No check is performed. <p>
+     *
+     * @return the result of executing "SELECT * FROM " + table " " + where
+     * @param table the name of a table to "select * from"
+     * @param where the where condition for the select
+     * @throws SQLException if database error occurs
+     */
+    private ResultSet executeSelect(String table,
+                                    String where) throws SQLException {
+
+        String select = selstar + table;
+
+        if (where != null) {
+            select += " WHERE " + where;
+        }
+
+        return execute(select);
+    }
+
+    /**
+     * Retrieves "SELECT * FROM INFORMATION_SCHEMA.&lt;table&gt; WHERE 1=1" in string
+     * buffer form. <p>
+     *
+     * This is a convenience method provided because, for most
+     * <code>DatabaseMetaData</code> queries, this is the most suitable
+     * thing upon which to start building. <p>
+     *
+     * @return an StringBuffer whose content is:
+     *      "SELECT * FROM &lt;table&gt; WHERE 1=1"
+     * @param t the name of the table
+     */
+    private StringBuffer toQueryPrefix(String t) {
+
+        StringBuffer sb = new StringBuffer(255);
+
+        return sb.append(selstar).append(t).append(whereTrue);
+    }
+
+    /**
+     * Retrieves "&lt;expression&gt; WHERE 1=1" in string
+     */
+    private StringBuffer toQueryPrefixNoSelect(String t) {
+
+        StringBuffer sb = new StringBuffer(255);
+
+        return sb.append(t).append(whereTrue);
+    }
+
+    /**
+     * Retrieves whether the JDBC <code>DatabaseMetaData</code> contract
+     * specifies that the argument <code>s</code>code> is filter parameter
+     * value that requires a corresponding IS NULL predicate. <p>
+     *
+     * @param s the filter parameter to test
+     * @return true if the argument, s, is filter parameter value that
+     *        requires a corresponding IS NULL predicate
+     */
+    private static boolean wantsIsNull(String s) {
+        return (s != null && s.length() == 0);
+    }
+
+    /**
+     * For compatibility, when the connection property "default_schema=true"
+     * is present, any DatabaseMetaData call with an empty string as the
+     * schema parameter will use the default schema (noramlly "PUBLIC").
+     */
+    private String translateSchema(String schemaName) throws SQLException {
+
+        if (useSchemaDefault && schemaName != null
+                && schemaName.length() == 0) {
+            ResultSet rs = executeSelect("SYSTEM_SCHEMAS", "IS_DEFAULT=TRUE");
+
+            if (rs.next()) {
+                return rs.getString(1);
+            }
+
+            return schemaName;
+        }
+
+        return schemaName;
+    }
+
+    /**
+     * For compatibility, when the connection property "default_schema=true"
+     * is present, any DatabaseMetaData call with an empty string as the
+     * catalog parameter will use the default catalog "PUBLIC".
+     */
+    private String translateCatalog(String catalogName) throws SQLException {
+
+        if (useSchemaDefault && catalogName != null
+                && catalogName.length() == 0) {
+            ResultSet rs = executeSelect("SYSTEM_SCHEMAS", "IS_DEFAULT=TRUE");
+
+            if (rs.next()) {
+                return rs.getString(2);
+            }
+        }
+
+        return catalogName;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCDriver.java b/src/org/hsqldb/jdbc/JDBCDriver.java
new file mode 100644
index 0000000..caa6365
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCDriver.java
@@ -0,0 +1,491 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.persist.HsqlProperties;
+
+// fredt@users 20011220 - patch 1.7.0 by fredt
+// new version numbering scheme
+// fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
+// JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
+// fredt@users 20030528 - patch 1.7.2 suggested by Gerhard Hiller - support for properties in URL
+// boucherb@users 20051207 - patch 1.8.x initial JDBC 4.0 support work
+
+/**
+ * Provides the java.sql.Driver interface implementation required by
+ * the JDBC specification. <p>
+ *
+ *  The Java SQL framework allows for multiple database drivers. <p>
+ *
+ *  The DriverManager will try to load as many drivers as it can find and
+ *  then for any given connection request, it will ask each driver in turn
+ *  to try to connect to the target URL. <p>
+ *
+ *  The application developer will normally not need to call any function of
+ *  the Driver directly. All required calls are made by the DriverManager. <p>
+ *
+ * <!-- start release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ *  When the HSQL Database Engine Driver class is loaded, it creates an
+ *  instance of itself and register it with the DriverManager. This means
+ *  that a user can load and register the HSQL Database Engine driver by
+ *  calling:
+ *  <pre>
+ *  <code>Class.forName("org.hsqldb.jdbc.JDBCDriver")</code>
+ *  </pre>
+ *
+ *  For detailed information about how to obtain HSQLDB JDBC Connections,
+ *  please see {@link org.hsqldb.jdbc.JDBCConnection JDBCConnection}.<p>
+ *
+ * <hr>
+ *
+ * <b>JRE 1.1.x Notes:</b> <p>
+ *
+ * In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ * Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ * versions of JDBC depends on the JDK version used for compiling and building
+ * HSQLDB.<p>
+ *
+ * Since 1.7.0, it is possible to build the product so that
+ * all JDBC 2 methods can be called while executing under the version 1.1.x
+ * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ * However, in addition to this technique requiring explicit casts to the
+ * org.hsqldb.jdbc.* classes, some of the method calls also require
+ * <code>int</code> values that are defined only in the JDBC 2 or greater
+ * version of the {@link java.sql.ResultSet ResultSet} interface.  For this
+ * reason, when the product is compiled under JDK 1.1.x, these values are
+ * defined in {@link org.hsqldb.jdbc.JDBCResultSet JDBCResultSet}. <p>
+ *
+ * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ * JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ * to them in parameter specifications and return value comparisons,
+ * respectively, as follows: <p>
+ *
+ * <pre class="JavaCodeExample">
+ * JDBCResultSet.FETCH_FORWARD
+ * JDBCResultSet.TYPE_FORWARD_ONLY
+ * JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ * JDBCResultSet.CONCUR_READ_ONLY
+ * // etc.
+ * </pre>
+ *
+ * However, please note that code written to use HSQLDB JDBC 2 features under
+ * JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
+ * also note that this feature is offered solely as a convenience to developers
+ * who must work under JDK 1.1.x due to operating constraints, yet wish to
+ * use some of the more advanced features available under the JDBC 2
+ * specification. <p>
+ *
+ * <hr>
+ *
+ * <b>JDBC 4.0 notes:</b><p>
+ *
+ * Starting with JDBC 4.0 (JDK 1.6), the <code>DriverManager</code> methods
+ * <code>getConnection</code> and <code>getDrivers</code> have been
+ * enhanced to support the Java Standard Edition Service Provider mechanism.
+ * When built under a Java runtime that supports JDBC 4.0, HSQLDB distribution
+ * jars containing the Driver implementation also include the file
+ * <code>META-INF/services/java.sql.Driver</code>. This file contains the fully
+ * qualified class name ('org.hsqldb.jdbc.JDBCDriver') of the HSQLDB implementation
+ * of <code>java.sql.Driver</code>. <p>
+ *
+ * Hence, under JDBC 4.0 or greater, applications no longer need to explictly
+ * load the HSQLDB JDBC driver using <code>Class.forName()</code>. Of course,
+ * existing programs which do load JDBC drivers using
+ * <code>Class.forName()</code> will continue to work without modification. <p>
+ *
+ * <hr>
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * </div> <!-- end release-specific documentation -->
+ *
+ * @see org.hsqldb.jdbc.JDBCConnection
+ */
+public class JDBCDriver implements Driver {
+
+    /**
+     * Default constructor
+     */
+    public JDBCDriver() {
+    }
+
+    /**
+     * Attempts to make a database connection to the given URL.<p>
+     *
+     * Returns "null" if this is the wrong kind of driver to connect to the
+     * given URL.  This will be common, as when the JDBC driver manager is asked
+     * to connect to a given URL it passes the URL to each loaded driver in
+     * turn. <p>
+     *
+     * <P>The driver throws an <code>SQLException</code> if it is the right
+     * driver to connect to the given URL but has trouble connecting to
+     * the database. <p>
+     *
+     * <P>The <code>java.util.Properties</code> argument can be used to pass
+     * arbitrary string tag/value pairs as connection arguments.
+     * Normally at least "user" and "password" properties should be
+     * included in the <code>Properties</code> object. <p>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     *  For the HSQL Database Engine, at least "user" and
+     *  "password" properties should be included in the Properties.<p>
+     *
+     *  From version 1.7.1, two optional properties are supported:<p>
+     *
+     *  <ul>
+     *      <li><code>get_column_name</code> (default true) -  if set to false,
+     *          a ResultSetMetaData.getColumnName() call will return the user
+     *          defined label (getColumnLabel()) instead of the column
+     *          name.<br/>
+     *
+     *          This property is available in order to achieve
+     *          compatibility with certain non-HSQLDB JDBC driver
+     *          implementations.</li>
+     *
+     *      <li><code>strict_md</code> if set to true, some ResultSetMetaData
+     *          methods return more strict values for compatibility
+     *          reasons.</li>
+     *  </ul> <p>
+     *
+     *  From version 1.8.0.x, <code>strict_md</code> is deprecated (ignored)
+     *  because metadata reporting is always strict (JDBC-compliant), and
+     *  three new optional properties are supported: <p>
+     *
+     *  <ul>
+     *      <li><code>ifexits</code> (default false) - when true, an exception
+     *          is raised when attempting to connect to an in-process
+     *          file: or mem: scheme database instance if it has not yet been
+     *          created.  When false, an in-process file: or mem: scheme
+     *          database instance is created automatically if it has not yet
+     *          been created. This property does not apply to requests for
+     *          network or res: (i.e. files_in_jar) scheme connections. <li>
+     *
+     *      <li><code>shutdown</code> (default false) - when true, the
+     *          the target database mimics the behaviour of 1.7.1 and older
+     *          versions. When the last connection to a database is closed,
+     *          the database is automatically shut down. The property takes
+     *          effect only when the first connection is made to the database.
+     *          This means the connection that opens the database. It has no
+     *          effect if used with subsequent, simultaneous connections. <br/>
+     *
+     *          This command has two uses. One is for test suites, where
+     *          connections to the database are made from one JVM context,
+     *          immediately followed by another context. The other use is for
+     *          applications where it is not easy to configure the environment
+     *          to shutdown the database. Examples reported by users include
+     *          web application servers, where the closing of the last
+     *          connection conicides with the web app being shut down.</li>
+     *
+     *      <li><code>default_schema</code> - backwards compatibility feature.
+     *          To be used for clients written before HSQLDB schema support.
+     *          Denotes whether to use the default schema when a schema
+     *          qualifier is not included in a database object's SQL identifier
+     *          character sequence. Also affects the semantics of
+     *          DatabaseMetaData calls that supply null-valued schemaNamePattern
+     *          parameter values.</li>
+     *  </ul>
+     *
+     *
+     * </div> <!-- end release-specific documentation -->
+     * @param url the URL of the database to which to connect
+     * @param info a list of arbitrary string tag/value pairs as connection
+     *      arguments. Normally at least a "user" and "password" property
+     *      should be included.
+     * @return a <code>Connection</code> object that represents a
+     *      connection to the URL
+     * @exception SQLException if a database access error occurs
+     */
+    public Connection connect(String url,
+                              Properties info) throws SQLException {
+        return getConnection(url, info);
+    }
+
+    /**
+     * The static equivalent of the <code>connect(String,Properties)</code>
+     * method. <p>
+     *
+     * @param url the URL of the database to which to connect
+     * @param info a list of arbitrary string tag/value pairs as connection
+     *      arguments including at least at a "user" and a "password" property
+     * @throws java.sql.SQLException if a database access error occurs
+     * @return a <code>Connection</code> object that represents a
+     *      connection to the URL
+     */
+
+//#ifdef JAVA6
+    @SuppressWarnings("deprecation")
+
+//#endif JAVA6
+    public static Connection getConnection(String url,
+            Properties info) throws SQLException {
+
+        final HsqlProperties props = DatabaseURL.parseURL(url, true, false);
+
+        if (props == null) {
+
+            // supposed to be an HSQLDB driver url but has errors
+            throw Util.invalidArgument();
+        } else if (props.isEmpty()) {
+
+            // is not an HSQLDB driver url
+            return null;
+        }
+        props.addProperties(info);
+
+        long timeout = DriverManager.getLoginTimeout();
+
+        if (timeout == 0) {
+
+            // no timeout restriction
+            return new JDBCConnection(props);
+        }
+
+        String connType = props.getProperty("connection_type");
+
+        if (DatabaseURL.isInProcessDatabaseType(connType)) {
+            return new JDBCConnection(props);
+        }
+
+        /** @todo:  Better: ThreadPool? HsqlTimer with callback? */
+        final JDBCConnection[] conn = new JDBCConnection[1];
+        final SQLException[]   ex   = new SQLException[1];
+        Thread                 t    = new Thread() {
+
+            public void run() {
+
+                try {
+                    conn[0] = new JDBCConnection(props);
+                } catch (SQLException se) {
+                    ex[0] = se;
+                }
+            }
+        };
+
+        t.start();
+
+        final long start = System.currentTimeMillis();
+
+        try {
+            t.join(1000 * timeout);
+        } catch (InterruptedException ie) {
+        }
+
+        try {
+
+            // PRE:
+            // deprecated, but should be ok, since neither
+            // the HSQLClientConnection or the HTTPClientConnection
+            // constructor will ever hold monitors on objects in
+            // an inconsistent state, such that damaged objects
+            // become visible to other threads with the
+            // potential of arbitrary behavior.
+            t.stop();
+        } catch (Exception e) {
+        }
+
+        if (ex[0] != null) {
+            throw ex[0];
+        }
+
+        if (conn[0] != null) {
+            return conn[0];
+        }
+
+        throw Util.sqlException(ErrorCode.X_08501);
+    }
+
+    /**
+     *  Returns true if the driver thinks that it can open a connection to
+     *  the given URL. Typically drivers will return true if they understand
+     *  the subprotocol specified in the URL and false if they don't.
+     *
+     * @param  url the URL of the database
+     * @return  true if this driver can connect to the given URL
+     */
+
+    // fredt@users - patch 1.7.0 - allow mixedcase url's
+    public boolean acceptsURL(String url) {
+
+        if (url == null) {
+            return false;
+        }
+
+        return url.regionMatches(true, 0, DatabaseURL.S_URL_PREFIX, 0,
+                                 DatabaseURL.S_URL_PREFIX.length());
+    }
+
+    /**
+     *  Gets information about the possible properties for this driver. <p>
+     *
+     *  The getPropertyInfo method is intended to allow a generic GUI tool
+     *  to discover what properties it should prompt a human for in order to
+     *  get enough information to connect to a database. Note that depending
+     *  on the values the human has supplied so far, additional values may
+     *  become necessary, so it may be necessary to iterate though several
+     *  calls to getPropertyInfo.<p>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB uses the values submitted in info to set the value for
+     * each DriverPropertyInfo object returned. It does not use the default
+     * value that it would use for the property if the value is null. <p>
+     *
+     * </div> <!-- end release-specific documentation -->
+     *
+     * @param  url the URL of the database to which to connect
+     * @param  info a proposed list of tag/value pairs that will be sent on
+     *      connect open
+     * @return  an array of DriverPropertyInfo objects describing possible
+     *      properties. This array may be an empty array if no properties
+     *      are required.
+     */
+    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
+
+        if (!acceptsURL(url)) {
+            return new DriverPropertyInfo[0];
+        }
+
+        String[]             choices = new String[] {
+            "true", "false"
+        };
+        DriverPropertyInfo[] pinfo   = new DriverPropertyInfo[6];
+        DriverPropertyInfo   p;
+
+        if (info == null) {
+            info = new Properties();
+        }
+        p          = new DriverPropertyInfo("user", null);
+        p.value    = info.getProperty("user");
+        p.required = true;
+        pinfo[0]   = p;
+        p          = new DriverPropertyInfo("password", null);
+        p.value    = info.getProperty("password");
+        p.required = true;
+        pinfo[1]   = p;
+        p          = new DriverPropertyInfo("get_column_name", null);
+        p.value    = info.getProperty("get_column_name", "true");
+        p.required = false;
+        p.choices  = choices;
+        pinfo[2]   = p;
+        p          = new DriverPropertyInfo("ifexists", null);
+        p.value    = info.getProperty("ifexists", "false");
+        p.required = false;
+        p.choices  = choices;
+        pinfo[3]   = p;
+        p          = new DriverPropertyInfo("default_schema", null);
+        p.value    = info.getProperty("default_schema", "false");
+        p.required = false;
+        p.choices  = choices;
+        pinfo[4]   = p;
+        p          = new DriverPropertyInfo("shutdown", null);
+        p.value    = info.getProperty("shutdown", "false");
+        p.required = false;
+        p.choices  = choices;
+        pinfo[5]   = p;
+
+        return pinfo;
+    }
+
+    /**
+     *  Gets the driver's major version number.
+     *
+     * @return  this driver's major version number
+     */
+    public int getMajorVersion() {
+        return HsqlDatabaseProperties.MAJOR;
+    }
+
+    /**
+     *  Gets the driver's minor version number.
+     *
+     * @return  this driver's minor version number
+     */
+    public int getMinorVersion() {
+        return HsqlDatabaseProperties.MINOR;
+    }
+
+    /**
+     * Reports whether this driver is a genuine JDBC Compliant<sup><font
+     * size=-2>TM</font></sup> driver. A driver may only report
+     * <code>true</code> here if it passes the JDBC compliance tests; otherwise
+     * it is required to return <code>false</code>. <p>
+     *
+     * JDBC compliance requires full support for the JDBC API and full support
+     * for SQL 92 Entry Level. <p>
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     *  HSQLDB 2.0 is aimed to be compliant with JDBC 4.0 specification.
+     *  It supports SQL 92 Entry Level and beyond.
+     * </div> <!-- end release-specific documentation -->
+     *
+     * This method is not intended to encourage the development of non-JDBC
+     * compliant drivers, but is a recognition of the fact that some vendors
+     * are interested in using the JDBC API and framework for lightweight
+     * databases that do not support full database functionality, or for
+     * special databases such as document information retrieval where a SQL
+     * implementation may not be feasible.
+     *
+     * @return <code>true</code> if this driver is JDBC Compliant;
+     *         <code>false</code> otherwise
+     */
+    public boolean jdbcCompliant() {
+        return true;
+    }
+
+    static {
+        try {
+            DriverManager.registerDriver(new JDBCDriver());
+        } catch (Exception e) {
+        }
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCNClob.java b/src/org/hsqldb/jdbc/JDBCNClob.java
new file mode 100644
index 0000000..fc457e6
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCNClob.java
@@ -0,0 +1,83 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.NClob;
+
+/**
+ * The mapping in the Java<sup><font size=-2>TM</font></sup> programming language
+ * for the SQL <code>NCLOB</code> type.
+ * An SQL <code>NCLOB</code> is a built-in type
+ * that stores a Character Large Object using the National Character Set
+ *  as a column value in a row of  a database table.
+ * <P>The <code>NClob</code> interface extends the <code>Clob</code> interface
+ * which provides provides methods for getting the
+ * length of an SQL <code>NCLOB</code> value,
+ * for materializing a <code>NCLOB</code> value on the client, and for
+ * searching for a substring or <code>NCLOB</code> object within a
+ * <code>NCLOB</code> value. A <code>NClob</code> object, just like a <code>Clob</code> object, is valid for the duration
+ * of the transaction in which it was created.
+ * Methods in the interfaces {@link java.sql.ResultSet},
+ * {@link java.sql.CallableStatement}, and {@link java.sql.PreparedStatement}, such as
+ * <code>getNClob</code> and <code>setNClob</code> allow a programmer to
+ * access an SQL <code>NCLOB</code> value.  In addition, this interface
+ * has methods for updating a <code>NCLOB</code> value.
+ *
+ * <!-- start Release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * First, it should be noted that since HSQLDB represents all character data
+ * internally as Java UNICODE (UTF16) String objects, there is not currently any
+ * appreciable difference between the HSQLDB XXXCHAR types and the SQL 2003
+ * NXXXCHAR and NCLOB types. <p>
+ *
+ * See {@link org.hsqldb.jdbc.JDBCClob} for further information.
+ *
+ * </div>
+ * <!-- end Release-specific documentation -->
+ *
+ * @since JDK 1.6, HSQLDB 2.0
+ * @author boucherb@users
+ * @see JDBCClob
+ * @see JDBCClobClient
+ */
+public class JDBCNClob extends JDBCClob implements NClob {
+
+    protected JDBCNClob() {
+        super();
+    }
+
+    public JDBCNClob(String data) throws java.sql.SQLException {
+        super(data);
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCParameterMetaData.java b/src/org/hsqldb/jdbc/JDBCParameterMetaData.java
new file mode 100644
index 0000000..d532e85
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCParameterMetaData.java
@@ -0,0 +1,479 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.sql.ParameterMetaData;
+import java.sql.SQLException;
+
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/* $Id: JDBCParameterMetaData.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/** @todo 1.9.0 - implement internal support for INOUT, OUT return parameter */
+
+// fredt@users 20040412 - removed DITypeInfo dependencies
+// fredt@usres 1.9.0 - utilise the new type support
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+// boucherb@users 20060522 - doc   1.9.0 full synch up to Mustang Build 84
+// Revision 1.14  2006/07/12 12:20:49  boucherb
+// - remove unused imports
+// - full synch up to Mustang b90
+
+/**
+ * An object that can be used to get information about the types
+ * and properties for each parameter marker in a
+ * <code>PreparedStatement</code> object. (JDBC4 Clarification:) For some queries and driver
+ * implementations, the data that would be returned by a <code>ParameterMetaData</code>
+ * object may not be available until the <code>PreparedStatement</code> has
+ * been executed.
+ * <p>
+ * Some driver implementations may not be able to provide information about the
+ * types and properties for each parameter marker in a <code>CallableStatement</code>
+ * object.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @version 2.0
+ * @since JDK 1.4, HSQLDB 1.7.2
+ * @revised JDK 1.6, HSQLDB 2.0
+ */
+//#ifdef JAVA6
+public class JDBCParameterMetaData implements ParameterMetaData,
+        java.sql.Wrapper {
+
+//#else
+/*
+public class JDBCParameterMetaData
+    implements ParameterMetaData {
+*/
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the number of parameters in the <code>PreparedStatement</code>
+     * object for which this <code>ParameterMetaData</code> object contains
+     * information.
+     *
+     * @return the number of parameters
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+    public int getParameterCount() throws SQLException {
+        return parameterCount;
+    }
+
+    /**
+     * Retrieves whether null values are allowed in the designated parameter.
+     *
+     * @param param the first parameter is 1, the second is 2, ...
+     * @return the nullability status of the given parameter; one of
+     *        <code>ParameterMetaData.parameterNoNulls</code>,
+     *        <code>ParameterMetaData.parameterNullable</code>, or
+     *        <code>ParameterMetaData.parameterNullableUnknown</code>
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+    public int isNullable(int param) throws SQLException {
+
+        checkRange(param);
+
+        return ParameterMetaData.parameterNullableUnknown;
+    }
+
+    /**
+     * Retrieves whether values for the designated parameter can be signed numbers.
+     *
+     * @param param the first parameter is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+    public boolean isSigned(int param) throws SQLException {
+
+        checkRange(param);
+
+        Type type = translateType(rmd.columnTypes[--param]);
+
+        return type.isNumberType();
+    }
+
+    /**
+     * Retrieves the designated parameter's specified column size.
+     *
+     * <P>The returned value represents the maximum column size for the given parameter.
+     * For numeric data, this is the maximum precision.  For character data, this is the length in characters.
+     * For datetime datatypes, this is the length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary data, this is the length in bytes.  For the ROWID datatype,
+     * this is the length in bytes. 0 is returned for data types where the
+     * column size is not applicable.
+     *
+     * @param param the first parameter is 1, the second is 2, ...
+     * @return precision
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+    public int getPrecision(int param) throws SQLException {
+
+        checkRange(param);
+
+        Type type = translateType(rmd.columnTypes[--param]);
+
+        if (type.isDateTimeType()) {
+            return type.displaySize();
+        } else {
+            long size = type.precision;
+
+            if (size > Integer.MAX_VALUE) {
+                size = 0;
+            }
+
+            return (int) size;
+        }
+    }
+
+    /**
+     * Retrieves the designated parameter's number of digits to right of the decimal point.
+     * 0 is returned for data types where the scale is not applicable.
+     *
+     * @param param the first parameter is 1, the second is 2, ...
+     * @return scale
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+    public int getScale(int param) throws SQLException {
+
+        checkRange(param);
+
+        Type type = translateType(rmd.columnTypes[--param]);
+
+        return type.scale;
+    }
+
+    /**
+     * Retrieves the designated parameter's SQL type.
+     *
+     * @param param the first parameter is 1, the second is 2, ...
+     * @return SQL type from <code>java.sql.Types</code>
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     * @see java.sql.Types
+     */
+    public int getParameterType(int param) throws SQLException {
+
+        checkRange(param);
+
+        Type type = translateType(rmd.columnTypes[--param]);
+
+        return type.getJDBCTypeCode();
+    }
+
+    /**
+     * Retrieves the designated parameter's database-specific type name.
+     *
+     * @param param the first parameter is 1, the second is 2, ...
+     * @return type the name used by the database. If the parameter type is
+     * a user-defined type, then a fully-qualified type name is returned.
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+    public String getParameterTypeName(int param) throws SQLException {
+
+        checkRange(param);
+
+        Type type = translateType(rmd.columnTypes[--param]);
+
+        return type.getNameString();
+    }
+
+    /**
+     * Retrieves the fully-qualified name of the Java class whose instances
+     * should be passed to the method <code>PreparedStatement.setObject</code>.
+     *
+     * @param param the first parameter is 1, the second is 2, ...
+     * @return the fully-qualified name of the class in the Java programming
+     *         language that would be used by the method
+     *         <code>PreparedStatement.setObject</code> to set the value
+     *         in the specified parameter. This is the class name used
+     *         for custom mapping.
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+    public String getParameterClassName(int param) throws SQLException {
+
+        checkRange(param);
+
+        Type type = translateType(rmd.columnTypes[--param]);
+
+        return type.getJDBCClassName();
+    }
+
+    /**
+     * Retrieves the designated parameter's mode.
+     *
+     * @param param the first parameter is 1, the second is 2, ...
+     * @return mode of the parameter; one of
+     *        <code>ParameterMetaData.parameterModeIn</code>,
+     *        <code>ParameterMetaData.parameterModeOut</code>, or
+     *        <code>ParameterMetaData.parameterModeInOut</code>
+     *        <code>ParameterMetaData.parameterModeUnknown</code>.
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.4, HSQLDB 1.7.2
+     */
+    public int getParameterMode(int param) throws SQLException {
+
+        checkRange(param);
+
+        return rmd.paramModes[--param];
+    }
+
+    //----------------------------- JDBC 4.0 -----------------------------------
+    // ------------------- java.sql.Wrapper implementation ---------------------
+
+    /**
+     * Returns an object that implements the given interface to allow access to
+     * non-standard methods, or standard methods not exposed by the proxy.
+     *
+     * If the receiver implements the interface then the result is the receiver
+     * or a proxy for the receiver. If the receiver is a wrapper
+     * and the wrapped object implements the interface then the result is the
+     * wrapped object or a proxy for the wrapped object. Otherwise return the
+     * the result of calling <code>unwrap</code> recursively on the wrapped object
+     * or a proxy for that result. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+    public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+    // -------------------------- Internal Implementation ----------------------
+
+    /** The metadata object with which this object is constructed */
+    ResultMetaData rmd;
+
+    /**
+     * The fully-qualified name of the Java class whose instances should
+     * be passed to the method PreparedStatement.setObject. <p>
+     *
+     * Note that changes to Function.java and Types.java allow passing
+     * objects of any class implementing java.io.Serializable and that,
+     * as such, the parameter expression resolution mechanism has been
+     * upgraded to provide the precise FQN for SQL function and stored
+     * procedure arguments, rather than the more generic
+     * org.hsqldb.JavaObject class that is used internally to represent
+     * and transport objects whose class is not in the standard mapping.
+     */
+    String[] classNames;
+
+    /** The number of parameters in the described statement */
+    int             parameterCount;
+    private boolean translateDTIType;
+
+    /**
+     * Creates a new instance of JDBCParameterMetaData. <p>
+     *
+     * @param metaData A ResultMetaData object describing the statement parameters
+     * @throws SQLException never - reserved for future use
+     */
+    JDBCParameterMetaData(JDBCConnection conn,
+                          ResultMetaData metaData) throws SQLException {
+
+        rmd            = metaData;
+        parameterCount = rmd.getColumnCount();
+
+        if (conn.clientProperties != null) {
+            translateDTIType = conn.clientProperties.isPropertyTrue(
+                HsqlDatabaseProperties.jdbc_translate_dti_types);
+        }
+    }
+
+    /**
+     * Translates an INTERVAL type to VARCHAR.
+     * Removes time zone from datetime types.
+     *
+     */
+    private Type translateType(Type type) {
+
+        if (this.translateDTIType) {
+            if (type.isIntervalType()) {
+                type = new CharacterType(Types.SQL_VARCHAR,
+                        type.displaySize());
+            } else if (type.isDateTimeTypeWithZone()) {
+                type = ((DateTimeType) type).getDateTimeTypeWithoutZone();
+            }
+        }
+
+        return type;
+    }
+
+    /**
+     * Checks if the value of the param argument is a valid parameter
+     * position. <p>
+     *
+     * @param param position to check
+     * @throws SQLException if the value of the param argument is not a
+     *      valid parameter position
+     */
+    void checkRange(int param) throws SQLException {
+
+        if (param < 1 || param > parameterCount) {
+            String msg = param + " is out of range";
+
+            throw Util.outOfRangeArgument(msg);
+        }
+    }
+
+    /**
+     * Retrieves a String repsentation of this object. <p>
+     *
+     * @return a String repsentation of this object
+     */
+    public String toString() {
+
+        try {
+            return toStringImpl();
+        } catch (Throwable t) {
+            return super.toString() + "[toStringImpl_exception=" + t + "]";
+        }
+    }
+
+    /**
+     * Provides the implementation of the toString() method. <p>
+     *
+     * @return a String representation of this object
+     * @throws Exception if a reflection error occurs
+     */
+    private String toStringImpl() throws Exception {
+
+        StringBuffer sb;
+        Method[]     methods;
+        Method       method;
+        int          count;
+
+        sb = new StringBuffer();
+
+        sb.append(super.toString());
+
+        count = getParameterCount();
+
+        if (count == 0) {
+            sb.append("[parameterCount=0]");
+
+            return sb.toString();
+        }
+        methods = getClass().getDeclaredMethods();
+
+        sb.append('[');
+
+        int len = methods.length;
+
+        for (int i = 0; i < count; i++) {
+            sb.append('\n');
+            sb.append("    parameter_");
+            sb.append(i + 1);
+            sb.append('=');
+            sb.append('[');
+
+            for (int j = 0; j < len; j++) {
+                method = methods[j];
+
+                if (!Modifier.isPublic(method.getModifiers())) {
+                    continue;
+                }
+
+                if (method.getParameterTypes().length != 1) {
+                    continue;
+                }
+                sb.append(method.getName());
+                sb.append('=');
+                sb.append(method.invoke(this,
+                                        new Object[] { new Integer(i + 1) }));
+
+                if (j + 1 < len) {
+                    sb.append(',');
+                    sb.append(' ');
+                }
+            }
+            sb.append(']');
+
+            if (i + 1 < count) {
+                sb.append(',');
+                sb.append(' ');
+            }
+        }
+        sb.append('\n');
+        sb.append(']');
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCPreparedStatement.java b/src/org/hsqldb/jdbc/JDBCPreparedStatement.java
new file mode 100644
index 0000000..6ee904b
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCPreparedStatement.java
@@ -0,0 +1,4685 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.sql.Array;
+import java.sql.BatchUpdateException;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+//#ifdef JAVA4
+import java.sql.ParameterMetaData;
+
+//#endif JAVA4
+//#ifdef JAVA6
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLXML;
+
+//#endif JAVA6
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.HsqlException;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.StatementTypes;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.CharArrayWriter;
+import org.hsqldb.lib.CountdownInputStream;
+import org.hsqldb.lib.HsqlByteArrayOutputStream;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultLob;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/* $Id: JDBCPreparedStatement.java 3596 2010-05-30 13:06:33Z fredt $ */
+
+// changes by fredt
+// SimpleDateFormat objects moved out of methods to improve performance
+// this is safe because only one thread at a time should access a
+// PreparedStatement object until it has finished executing the statement
+//
+// fredt@users    20020215 - patch 517028 by peterhudson@users - method defined
+// minor changes by fredt
+// fredt@users    20020320 - patch 1.7.0 - JDBC 2 support and error trapping;
+//                           JDBC 2 methods can now be called from jdk 1.1.x
+//                           - see javadoc comments
+// fredt@users    20020414 - patch 517028 by peterhudson@users - setDate method defined
+//                                                             - setTime method defined
+//                                                             - setTimestamp method defined
+//                           changes by fredt                  - moved conversion to HsqlDateTime
+// fredt@users    20020429 - patch 1.7.0 - setCharacterStream method defined
+//
+// boucherb &     20020409 - extensive review and update of docs and behaviour
+// fredt@users  - 20020505   to comply with previous and latest java.sql specification
+//
+// boucherb@users 20020509 - added "throws SQLException" to all methods where it
+//                           was missing here but specified in the java.sql.PreparedStatement and
+//                           java.sqlCallableStatement interfaces, updated generic documentation to
+//                           JDK 1.4, and added JDBC3 methods and docs
+// fredt@users    20020627 - patch 574234 for setCharacterStream by ohioedge@users
+// fredt@users    20030620 - patch 1.7.2 - rewritten to support real prepared statements
+// boucherb@users 20030801 - patch 1.7.2 - support for batch execution
+// boucherb@users 20030801 - patch 1.7.2 - support for getMetaData and getParameterMetadata
+// boucherb@users 20030801 - patch 1.7.2 - updated some setXXX methods, incl. setCharacterStream
+// boucherb@users 20030801 - patch 1.7.2 - setBlob method implemented
+// boucherb@users 200403/4 - doc 1.7.2   - javadoc updates toward 1.7.2 final
+// boucherb@users 200403/4 - patch 1.7.2 - eliminate eager buffer allocation from setXXXStream/Blob/Clob
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+// fredt@users    20060215 - patch 1.8.0 - check for unset parameters
+// fredt@users    20061008 - patch 1.9.0 - partial rewrite with enhancements - separated from jdbcStatement
+// boucherb@users 20060424 - patch 1.8.x - Mustang Build 81 JDBC 4.0 support
+// boucherb@users 20060424 - doc   1.9.0 - Full synch up to Mustang Build 84
+// Revision 1.19  2006/07/12 12:24:17  boucherb
+// patch 1.9.0
+// - full synch up to Mustang b90
+
+/**
+ * <!-- start generic documentation -->
+ *
+ * An object that represents a precompiled SQL statement.
+ * <P>A SQL statement is precompiled and stored in a
+ * <code>PreparedStatement</code> object. This object can then be used to
+ * efficiently execute this statement multiple times.
+ *
+ * <P><B>Note:</B> The setter methods (<code>setShort</code>, <code>setString</code>,
+ * and so on) for setting IN parameter values
+ * must specify types that are compatible with the defined SQL type of
+ * the input parameter. For instance, if the IN parameter has SQL type
+ * <code>INTEGER</code>, then the method <code>setInt</code> should be used.
+ *
+ * <p>If arbitrary parameter type conversions are required, the method
+ * <code>setObject</code> should be used with a target SQL type.
+ * <P>
+ * In the following example of setting a parameter, <code>con</code> represents
+ * an active connection:
+ * <PRE>
+ *   PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
+ *                                     SET SALARY = ? WHERE ID = ?");
+ *   pstmt.setBigDecimal(1, 153833.00)
+ *   pstmt.setInt(2, 110592)
+ * </PRE>
+ *
+ * <!-- end generic documentation -->
+ *
+ * <!-- start Release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * From version 2.0, the implementation meets the JDBC specification
+ * requirment that any existing ResultSet is closed when execute() or
+ * executeQuery() methods are called.
+ * <p>
+ * JDBCPreparedStatement objects are backed by
+ * a true compiled parameteric representation. Hence, there are now significant
+ * performance gains to be had by using a JDBCPreparedStatement object in
+ * preference to a JDBCStatement object when a short-running SQL statement is
+ * to be executed more than once. <p>
+ *
+ * When it can be otherwise avoided, it should be considered poor practice to
+ * fully prepare (construct), parameterize, execute, fetch and close a
+ * JDBCParameterMetaData object for each execution cycle. Indeed,
+ * because the prepare and execute phases
+ * both represent a round-trip to the engine, this practice is likely to be
+ * noticably <em>less</em> performant for short-running statements (and
+ * possibly even orders of magnitude less performant over network connections
+ * for short-running statements) than the equivalent process using JDBCStatement
+ * objects, albeit far more convenient, less error prone and certainly much
+ * less resource-intensive, especially when large binary and character values
+ * are involved, due to the optimized parameterization facility. <p>
+ *
+ * Instead, when developing an application that is not totally oriented toward
+ * the execution of ad hoc SQL, it is recommended to expend some effort toward
+ * identifing the SQL statements that are good candidates for regular reuse and
+ * adapting the structure of the application accordingly. Often, this is done
+ * by recording the text of candidate SQL statements in an application resource
+ * object (which has the nice side-benefit of isolating and hiding differences
+ * in SQL dialects across different drivers) and caching for possible reuse the
+ * PreparedStatement objects derived from the recorded text. <p>
+ *
+ * Starting with 2.0, when built under a JDBC 4 environment, statement caching
+ * can be transparently enabled or disabled on a statement-by-statement basis by
+ * invoking setPoolable(true | false), respectively, upon Statement objects of
+ * interest. <p>
+ *
+ * <b>Multi thread use:</b> <p>
+ *
+ * A PreparedStatement object is stateful and should not normally be shared
+ * by multiple threads. If it has to be shared, the calls to set the
+ * parameters, calls to add batch statements, the execute call and any
+ * post-execute calls should be made within a block synchronized on the
+ * PreparedStatement Object.<p>
+ *
+ * <b>JRE 1.1.x Notes:</b> <p>
+ *
+ * In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ * Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ * versions of JDBC depends on the JDK version used for compiling and building
+ * HSQLDB.<p>
+ *
+ * Since 1.7.0, all JDBC 2 methods can be called while executing under the
+ * version 1.1.x
+ * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ * However, in addition to this technique requiring explicit casts to the
+ * org.hsqldb.jdbc.* classes, some of these method calls require
+ * <code>int</code> values that are defined only in the JDBC 2 or greater
+ * version of the {@link java.sql.ResultSet ResultSet} interface.  For this
+ * reason these values are defined in {@link JDBCResultSet JDBCResultSet}.<p>
+ *
+ * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ * JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ * to them in parameter specifications and return value comparisons,
+ * respectively, as follows: <p>
+ *
+ * <pre class="JavaCodeExample">
+ * JDBCResultSet.FETCH_FORWARD
+ * JDBCResultSet.TYPE_FORWARD_ONLY
+ * JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ * JDBCResultSet.CONCUR_READ_ONLY
+ * //etc.
+ * </pre> <p>
+ *
+ * However, please note that code written to use HSQLDB JDBC 2 features under
+ * JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
+ * also note that this feature is offered solely as a convenience to developers
+ * who must work under JDK 1.1.x due to operating constraints, yet wish to
+ * use some of the more advanced features available under the JDBC 2
+ * specification. <p>
+ *
+ * (fredt@users)<br>
+ * (boucherb@users)<p>
+ *
+ * </div>
+ * <!-- end release-specific documentation -->
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @since 1.7.2
+ * @see JDBCConnection#prepareStatement
+ * @see JDBCResultSet
+ */
+public class JDBCPreparedStatement extends JDBCStatementBase implements PreparedStatement {
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the SQL query in this <code>PreparedStatement</code> object
+     * and returns the <code>ResultSet</code> object generated by the query.
+     * <!-- end generic documentation -->
+     *
+     * @return a <code>ResultSet</code> object that contains the data produced by the
+     *         query; never <code>null</code>
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed  <code>PreparedStatement</code> or the SQL
+     *            statement does not return a <code>ResultSet</code> object
+     */
+    public synchronized ResultSet executeQuery() throws SQLException {
+
+        if (statementRetType != StatementTypes.RETURN_RESULT) {
+            checkStatementType(StatementTypes.RETURN_RESULT);
+        }
+        fetchResult();
+
+        return getResultSet();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the SQL statement in this <code>PreparedStatement</code> object,
+     * (JDBC4 clarification:)
+     * which must be an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code>; or an SQL statement that returns nothing,
+     * such as a DDL statement.
+     * <!-- end generic documentation -->
+     *
+     * @return (JDBC4 clarification:) either (1) the row count for SQL Data Manipulation Language (DML) statements
+     *         or (2) 0 for SQL statements that return nothing
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed  <code>PreparedStatement</code>
+     * or the SQL
+     *            statement returns a <code>ResultSet</code> object
+     */
+    public synchronized int executeUpdate() throws SQLException {
+
+        if (statementRetType != StatementTypes.RETURN_COUNT) {
+            checkStatementType(StatementTypes.RETURN_COUNT);
+        }
+        fetchResult();
+
+        return resultIn.getUpdateCount();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to SQL <code>NULL</code>.
+     *
+     * <P><B>Note:</B> You must specify the parameter's SQL type.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB currently ignores the sqlType argument.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param sqlType the SQL type code defined in <code>java.sql.Types</code>
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>sqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type
+     */
+    public synchronized void setNull(int parameterIndex,
+                                     int sqlType) throws SQLException {
+        setParameter(parameterIndex, null);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java <code>boolean</code> value.
+     * The driver converts this
+     * (JDBC4 Modified:)
+     * to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports BOOLEAN type for boolean values. This method can also
+     * be used to set the value of a parameter of the SQL type BIT(1), which is
+     * a bit string consisting of a 0 or 1.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setBoolean(int parameterIndex,
+                                        boolean x) throws SQLException {
+
+        Boolean b = x ? Boolean.TRUE
+                      : Boolean.FALSE;
+
+        setParameter(parameterIndex, b);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java <code>byte</code> value.
+     * The driver converts this
+     * to an SQL <code>TINYINT</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setByte(int parameterIndex,
+                                     byte x) throws SQLException {
+        setIntParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java <code>short</code> value.
+     * The driver converts this
+     * to an SQL <code>SMALLINT</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setShort(int parameterIndex,
+                                      short x) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        checkSetParameterIndex(parameterIndex, false);
+
+        if (parameterTypes[parameterIndex - 1].typeCode
+                == Types.SQL_SMALLINT) {
+            parameterValues[--parameterIndex] = ValuePool.getInt(x);
+
+            return;
+        }
+        setIntParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java <code>int</code> value.
+     * The driver converts this
+     * to an SQL <code>INTEGER</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setInt(int parameterIndex,
+                                    int x) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        checkSetParameterIndex(parameterIndex, false);
+
+        if (parameterTypes[parameterIndex - 1].typeCode == Types.SQL_INTEGER) {
+            parameterValues[--parameterIndex] = ValuePool.getInt(x);
+
+            return;
+        }
+        setIntParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java <code>long</code> value.
+     * The driver converts this
+     * to an SQL <code>BIGINT</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setLong(int parameterIndex,
+                                     long x) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        checkSetParameterIndex(parameterIndex, false);
+
+        if (parameterTypes[parameterIndex - 1].typeCode == Types.SQL_BIGINT) {
+            parameterValues[--parameterIndex] = ValuePool.getLong(x);
+
+            return;
+        }
+        setLongParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java <code>float</code> value.
+     * The driver converts this
+     * (JDBC4 correction:)
+     * to an SQL <code>REAL</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.1, HSQLDB handles Java positive/negative Infinity
+     * and NaN <code>float</code> values consistent with the Java Language
+     * Specification; these <em>special</em> values are now correctly stored
+     * to and retrieved from the database.
+     * </div>
+     * <!-- start release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setFloat(int parameterIndex,
+                                      float x) throws SQLException {
+        setDouble(parameterIndex, (double) x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java <code>double</code> value.
+     * The driver converts this
+     * to an SQL <code>DOUBLE</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.1, HSQLDB handles Java positive/negative Infinity
+     * and NaN <code>double</code> values consistent with the Java Language
+     * Specification; these <em>special</em> values are now correctly stored
+     * to and retrieved from the database.
+     * </div>
+     * <!-- start release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setDouble(int parameterIndex,
+                                       double x) throws SQLException {
+
+        Double d = new Double(x);
+
+        setParameter(parameterIndex, d);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.math.BigDecimal</code> value.
+     * The driver converts this to an SQL <code>NUMERIC</code> value when
+     * it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setBigDecimal(int parameterIndex,
+            BigDecimal x) throws SQLException {
+        setParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java <code>String</code> value.
+     * The driver converts this
+     * to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
+     * (depending on the argument's
+     * size relative to the driver's limits on <code>VARCHAR</code> values)
+     * when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, HSQLDB represents all XXXCHAR values internally as
+     * java.lang.String objects; there is no appreciable difference between
+     * CHAR, VARCHAR and LONGVARCHAR.
+     * </div>
+     * <!-- start release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setString(int parameterIndex,
+                                       String x) throws SQLException {
+        setParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given Java array of bytes.  The driver converts
+     * this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
+     * (depending on the argument's size relative to the driver's limits on
+     * <code>VARBINARY</code> values) when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, HSQLDB represents all XXXBINARY values the same way
+     * internally; there is no appreciable difference between BINARY,
+     * VARBINARY and LONGVARBINARY as far as JDBC is concerned.
+     * </div>
+     * <!-- start release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setBytes(int parameterIndex,
+                                      byte[] x) throws SQLException {
+        setParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Sets the designated parameter to the given <code>java.sql.Date</code> value
+     * using the default time zone of the virtual machine that is running
+     * the application.
+     * The driver converts this
+     * to an SQL <code>DATE</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * When a setXXX method is used to set a parameter of type
+     * TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone of the
+     * client application is used as time zone
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setDate(int parameterIndex,
+                                     Date x) throws SQLException {
+        setParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.sql.Time</code> value.
+     * The driver converts this
+     * to an SQL <code>TIME</code> value when it sends it to the database.
+     * <!-- end generic documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * When a setXXX method is used to set a parameter of type
+     * TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone of the
+     * client application is used as time zone
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setTime(int parameterIndex,
+                                     Time x) throws SQLException {
+        setParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
+     * The driver
+     * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the
+     * database.
+     * <!-- end generic documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * When a setXXX method is used to set a parameter of type
+     * TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone of the
+     * client application is used as time zone.<p>
+     *
+     * When this method is used to set a parameter of type TIME or
+     * TIME WITH TIME ZONE, then the nanosecond value of the Timestamp object
+     * will be used if the TIME parameter accpets fractional seconds.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setTimestamp(int parameterIndex,
+            Timestamp x) throws SQLException {
+        setParameter(parameterIndex, x);
+    }
+
+    /** @todo 1.9.0 - implement streaming */
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given input stream, which will have
+     * the specified number of bytes.
+     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from ASCII to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From HSQLDB 2.0 this method uses the US-ASCII character encoding to convert bytes
+     * from the stream into the characters of a String.<p>
+     * This method does not use streaming to send the data,
+     * whether the target is a CLOB or other binary object.<p>
+     *
+     * For long streams (larger than a few megabytes) with CLOB targets,
+     * it is more efficient to use a version of setCharacterStream which takes
+     * the a length parameter.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setAsciiStream(int parameterIndex,
+            java.io.InputStream x, int length) throws SQLException {
+        setAsciiStream(parameterIndex, x, (long) length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given input stream, which
+     * will have the specified number of bytes.
+     * (JDBC4 deleted:)
+     * [A Unicode character has two bytes, with the first byte being the high
+     * byte, and the second being the low byte.] <p>
+     *
+     * When a very large Unicode value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code> object. The data will be read from the
+     * stream as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from Unicode to the database char format.
+     *
+     * (JDBC4 added:)
+     * The byte format of the Unicode stream must be a Java UTF-8, as defined in the
+     * Java Virtual Machine Specification.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 1.7.0 to 1.8.0.x, this method complies with behavior as defined by
+     * the JDBC3 specification (the stream is treated as though it has UTF16
+     * encoding). <p>
+     *
+     * Starting with 2.0, this method behaves according to the JDBC4
+     * specification (the stream is treated as though it has UTF-8
+     * encoding, as defined in the Java Virtual Machine Specification) when
+     * built under JDK 1.6+; otherwise, it behaves as defined by the JDBC3
+     * specification.  Regardless, this method is deprecated: please use
+     * setCharacterStream(...) instead.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x a <code>java.io.InputStream</code> object that contains the
+     *        Unicode parameter value
+     * (JDBC4 deleted:)
+     *       [as two-byte Unicode characters]
+     * @param length the number of bytes in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @deprecated
+     *      Sun does not include a reason, but presumably
+     *      this is because setCharacterStream is now prefered
+     */
+
+//#ifdef DEPRECATEDJDBC
+    public synchronized void setUnicodeStream(int parameterIndex,
+            java.io.InputStream x, int length) throws SQLException {
+
+        checkSetParameterIndex(parameterIndex, true);
+
+        String    msg = null;
+        final int ver = JDBCDatabaseMetaData.JDBC_MAJOR;
+
+        if (x == null) {
+            throw Util.nullArgument("x");
+        }
+
+        // CHECKME:  Is JDBC4 clarification of UNICODE stream format retroactive?
+        if ((ver < 4) && (length % 2 != 0)) {
+            msg = "Odd length argument for UTF16 encoded stream: " + length;
+
+            throw Util.invalidArgument(msg);
+        }
+
+        String       encoding = (ver < 4) ? "UTF16"
+                : "UTF8";
+        StringWriter writer   = new StringWriter();
+
+        try {
+            CountdownInputStream cis    = new CountdownInputStream(x);
+            InputStreamReader    reader = new InputStreamReader(cis, encoding);
+            char[]               buff   = new char[1024];
+            int                  charsRead;
+
+            cis.setCount(length);
+
+            while (-1 != (charsRead = reader.read(buff))) {
+                writer.write(buff, 0, charsRead);
+            }
+        } catch (IOException ex) {
+            throw Util.sqlException(ErrorCode.SERVER_TRANSFER_CORRUPTED,
+                                    ex.toString());
+        }
+        setParameter(parameterIndex, writer.toString());
+    }
+
+//#endif
+
+    /** @todo 1.9.0 - implement streaming */
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given input stream, which will have
+     * the specified number of bytes.
+     * When a very large binary value is input to a <code>LONGVARBINARY</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code> object. The data will be read from the
+     * stream as needed until end-of-file is reached.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.2, this method works according to the standard.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void setBinaryStream(int parameterIndex,
+            java.io.InputStream x, int length) throws SQLException {
+        setBinaryStream(parameterIndex, x, (long) length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Clears the current parameter values immediately.
+     * <P>In general, parameter values remain in force for repeated use of a
+     * statement. Setting a parameter value automatically clears its
+     * previous value.  However, in some cases it is useful to immediately
+     * release the resources used by the current parameter values; this can
+     * be done by calling the method <code>clearParameters</code>.
+     * <!-- end generic documentation -->
+     *
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     */
+    public synchronized void clearParameters() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        ArrayUtil.fillArray(parameterValues, null);
+        ArrayUtil.clearArray(ArrayUtil.CLASS_CODE_BOOLEAN, parameterSet, 0,
+                             parameterSet.length);
+        ArrayUtil.clearArray(ArrayUtil.CLASS_CODE_BOOLEAN, parameterStream, 0,
+                             parameterStream.length);
+        ArrayUtil.clearArray(ArrayUtil.CLASS_CODE_LONG, streamLengths, 0,
+                             parameterStream.length);
+    }
+
+    //----------------------------------------------------------------------
+    // Advanced features:
+
+    /**
+     * <p>Sets the value of the designated parameter with the given object. The second
+     * argument must be an object type; for integral values, the
+     * <code>java.lang</code> equivalent objects should be used.
+     *
+     * If the second argument is an <code>InputStream</code> then the stream must contain
+     * the number of bytes specified by scaleOrLength.  If the second argument is a
+     * <code>Reader</code> then the reader must contain the number of characters specified
+     * by scaleOrLength. If these conditions are not true the driver will generate a
+     * <code>SQLException</code> when the prepared statement is executed.
+     *
+     * <p>The given Java object will be converted to the given targetSqlType
+     * before being sent to the database.
+     *
+     * If the object has a custom mapping (is of a class implementing the
+     * interface <code>SQLData</code>),
+     * the JDBC driver should call the method <code>SQLData.writeSQL</code> to
+     * write it to the SQL data stream.
+     * If, on the other hand, the object is of a class implementing
+     * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>,  <code>NClob</code>,
+     *  <code>Struct</code>, <code>java.net.URL</code>,
+     * or <code>Array</code>, the driver should pass it to the database as a
+     * value of the corresponding SQL type.
+     *
+     * <p>Note that this method may be used to pass database-specific
+     * abstract data types.
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the object containing the input parameter value
+     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
+     * sent to the database. The scale argument may further qualify this type.
+     * @param scaleOrLength for <code>java.sql.Types.DECIMAL</code>
+     *          or <code>java.sql.Types.NUMERIC types</code>,
+     *          this is the number of digits after the decimal point. For
+     *          Java Object types <code>InputStream</code> and <code>Reader</code>,
+     *          this is the length
+     *          of the data in the stream or reader.  For all other types,
+     *          this value will be ignored.
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>PreparedStatement</code> or
+     *            if the Java Object specified by x is an InputStream
+     *            or Reader object and the value of the scale parameter is less
+     *            than zero
+     * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type
+     * @see java.sql.Types
+     */
+    public synchronized void setObject(int parameterIndex, Object x,
+                                       int targetSqlType,
+                                       int scaleOrLength) throws SQLException {
+
+        if (x instanceof InputStream) {
+            setBinaryStream(parameterIndex, (InputStream) x, scaleOrLength);
+        } else if (x instanceof Reader) {
+            setCharacterStream(parameterIndex, (Reader) x, scaleOrLength);
+        } else {
+            setObject(parameterIndex, x);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the value of the designated parameter with the given object.
+     * This method is like the method <code>setObject</code>
+     * above, except that it assumes a scale of zero.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.2, this method supports conversions listed in the
+     * conversion table B-5 of the JDBC 3 specification.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the object containing the input parameter value
+     * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
+     *                      sent to the database
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type
+     * @see #setObject(int,Object)
+     */
+    public synchronized void setObject(int parameterIndex, Object x,
+                                       int targetSqlType) throws SQLException {
+        setObject(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * <p>Sets the value of the designated parameter using the given object.
+     * The second parameter must be of type <code>Object</code>; therefore, the
+     * <code>java.lang</code> equivalent objects should be used for built-in types.
+     *
+     * <p>The JDBC specification specifies a standard mapping from
+     * Java <code>Object</code> types to SQL types.  The given argument
+     * will be converted to the corresponding SQL type before being
+     * sent to the database.
+     *
+     * <p>Note that this method may be used to pass datatabase-
+     * specific abstract data types, by using a driver-specific Java
+     * type.
+     *
+     * If the object is of a class implementing the interface <code>SQLData</code>,
+     * the JDBC driver should call the method <code>SQLData.writeSQL</code>
+     * to write it to the SQL data stream.
+     * If, on the other hand, the object is of a class implementing
+     * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, (JDBC4 new:) [ <code>NClob</code> ],
+     *  <code>Struct</code>, <code>java.net.URL</code>, (JDBC4 new:) [ <code>RowId</code>, <code>SQLXML</code> ]
+     * or <code>Array</code>, the driver should pass it to the database as a
+     * value of the corresponding SQL type.
+     * <P>
+     * <b>Note:</b> Not all databases allow for a non-typed Null to be sent to
+     * the backend. For maximum portability, the <code>setNull</code> or the
+     * <code>setObject(int parameterIndex, Object x, int sqlType)</code>
+     * method should be used
+     * instead of <code>setObject(int parameterIndex, Object x)</code>.
+     * <p>
+     * <b>Note:</b> This method throws an exception if there is an ambiguity, for example, if the
+     * object is of a class implementing more than one of the interfaces named above.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3><p>
+     *
+     * Since 1.7.2, this method supports conversions listed in the conversion
+     * table B-5 of the JDBC 3 specification.
+     * </div>
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the object containing the input parameter value
+     * @exception SQLException if a database access error occurs,
+     *  this method is called on a closed <code>PreparedStatement</code>
+     * or the type of the given object is ambiguous
+     */
+    public synchronized void setObject(int parameterIndex,
+                                       Object x) throws SQLException {
+        setParameter(parameterIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the SQL statement in this <code>PreparedStatement</code> object,
+     * which may be any kind of SQL statement.
+     * Some prepared statements return multiple results; the <code>execute</code>
+     * method handles these complex statements as well as the simpler
+     * form of statements handled by the methods <code>executeQuery</code>
+     * and <code>executeUpdate</code>.
+     * <P>
+     * The <code>execute</code> method returns a <code>boolean</code> to
+     * indicate the form of the first result.  You must call either the method
+     * <code>getResultSet</code> or <code>getUpdateCount</code>
+     * to retrieve the result; you must call <code>getMoreResults</code> to
+     * move to any subsequent result(s).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Up to 1.8.0.x, prepared statements do not generate
+     * multiple fetchable results. <p>
+     *
+     * In future versions, it will be possible that statements
+     * generate multiple fetchable results under certain conditions.
+     *
+     * </div>
+     *
+     * @return <code>true</code> if the first result is a <code>ResultSet</code>
+     *         object; <code>false</code> if the first result is an update
+     *         count or there is no result
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>PreparedStatement</code>
+     * or an argument is supplied to this method
+     * @see JDBCStatement#execute
+     * @see JDBCStatement#getResultSet
+     * @see JDBCStatement#getUpdateCount
+     * @see JDBCStatement#getMoreResults
+     *
+     */
+    public synchronized boolean execute() throws SQLException {
+
+        fetchResult();
+
+        return statementRetType == StatementTypes.RETURN_RESULT;
+    }
+
+    //--------------------------JDBC 2.0-----------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Adds a set of parameters to this <code>PreparedStatement</code>
+     * object's batch of commands.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.2, this feature is supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @see JDBCStatement#addBatch
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCParameterMetaData)
+     */
+    public synchronized void addBatch() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        checkParametersSet();
+
+        if (!isBatch) {
+            resultOut.setBatchedPreparedExecuteRequest();
+
+            isBatch = true;
+        }
+
+        try {
+            performPreExecute();
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+
+        int      len              = parameterValues.length;
+        Object[] batchParamValues = new Object[len];
+
+        System.arraycopy(parameterValues, 0, batchParamValues, 0, len);
+        resultOut.addBatchedPreparedExecuteRequest(batchParamValues);
+    }
+
+    /** @todo 1.9.0 - implement streaming */
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>Reader</code>
+     * object, which is the given number of characters long.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From HSQLDB 2.0 this method uses streaming to send data
+     * when the target is a CLOB.<p>
+     * HSQLDB represents CHARACTER and related SQL types as UTF16 Unicode
+     * internally, so this method does not perform any conversion.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     *        Unicode data
+     * @param length the number of characters in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCParameterMetaData)
+     */
+    public synchronized void setCharacterStream(int parameterIndex,
+            java.io.Reader reader, int length) throws SQLException {
+        setCharacterStream(parameterIndex, reader, (long) length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given
+     *  <code>REF(&lt;structured-type&gt;)</code> value.
+     * The driver converts this to an SQL <code>REF</code> value when it
+     * sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0 HSQLDB does not support the SQL REF type. Calling this method
+     * throws an exception.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x an SQL <code>REF</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCParameterMetaData)
+     */
+    public void setRef(int parameterIndex, Ref x) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.sql.Blob</code> object.
+     * The driver converts this to an SQL <code>BLOB</code> value when it
+     * sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * For parameters of type Blob, setBlob works normally.<p>
+     *
+     * In addition since 1.7.2, setBlob is supported for BINARY and VARBINARY
+     * parameters. In this context, the Blob object is
+     * hard-limited to those of length less than or equal to Integer.MAX_VALUE.
+     * In practice, soft limits such as available heap and maximum disk usage
+     * per file (such as the transaction log) dictate a much smaller maximum
+     * length. <p>
+     *
+     * For BINARY and VARBINARY parameter types setBlob(i,x) is roughly
+     * equivalent (null and length handling not shown) to:<p>
+     *
+     * <pre class="JavaCodeExample">
+     * <b>setBinaryStream</b>(i, x.<b>getBinaryStream</b>(), (<span class="JavaKeyWord">int</span>) x.<b>length</b>());
+     * </pre></div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCParameterMetaData)
+     */
+    public synchronized void setBlob(int parameterIndex,
+                                     Blob x) throws SQLException {
+
+        checkSetParameterIndex(parameterIndex, false);
+
+        Type outType = parameterTypes[parameterIndex - 1];
+
+        switch (outType.typeCode) {
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+                setBlobForBinaryParameter(parameterIndex, x);
+
+                return;
+            case Types.SQL_BLOB :
+                setBlobParameter(parameterIndex, x);
+
+                break;
+            default :
+                throw Util.invalidArgument();
+        }
+    }
+
+    /**
+     * Converts a blob to binary data for non-blob binary parameters.
+     */
+    private void setBlobForBinaryParameter(int parameterIndex,
+            Blob x) throws SQLException {
+
+        if (x instanceof JDBCBlob) {
+            setParameter(parameterIndex, ((JDBCBlob) x).data());
+
+            return;
+        } else if (x == null) {
+            setParameter(parameterIndex, null);
+
+            return;
+        }
+        checkSetParameterIndex(parameterIndex, true);
+
+        final long length = x.length();
+
+        if (length > Integer.MAX_VALUE) {
+            String msg = "Maximum Blob input octet length exceeded: " + length;    // NOI18N
+
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR, msg);
+        }
+
+        try {
+            java.io.InputStream in = x.getBinaryStream();
+            HsqlByteArrayOutputStream out = new HsqlByteArrayOutputStream(in,
+                (int) length);
+
+            setParameter(parameterIndex, out.toByteArray());
+        } catch (IOException e) {
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR,
+                                    e.toString());
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.sql.Clob</code> object.
+     * The driver converts this to an SQL <code>CLOB</code> value when it
+     * sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * For parameters of type Clob, setClob works normally.<p>
+     *
+     * In addition since 1.7.2, setClob is supported for CHARACTER and VARCHAR
+     * parameters. In this context, the Clob object is
+     * hard-limited to those of length less than or equal to Integer.MAX_VALUE.
+     * In practice, soft limits such as available heap and maximum disk usage
+     * per file (such as the transaction log) dictate a much smaller maximum
+     * length. <p>
+     *
+     * For CHARACTER and VARCHAR parameter types setClob(i,x) is roughly
+     * equivalent (null and length handling not shown) to:<p>
+     *
+     * <pre class="JavaCodeExample">
+     * <b>setCharacterStream</b>(i, x.<b>getCharacterStream</b>(), (<span class="JavaKeyWord">int</span>) x.<b>length</b>());
+     * </pre></div>
+     * <!-- end release-specific documentation -->
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCParameterMetaData)
+     */
+    public synchronized void setClob(int parameterIndex,
+                                     Clob x) throws SQLException {
+
+        checkSetParameterIndex(parameterIndex, false);
+
+        Type outType = parameterTypes[parameterIndex - 1];
+
+        switch (outType.typeCode) {
+
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+                setClobForStringParameter(parameterIndex, x);
+
+                return;
+            case Types.SQL_CLOB :
+                setClobParameter(parameterIndex, x);
+
+                return;
+            default :
+                throw Util.invalidArgument();
+        }
+    }
+
+    private void setClobForStringParameter(int parameterIndex,
+            Clob x) throws SQLException {
+
+        if (x instanceof JDBCClob) {
+            setParameter(parameterIndex, ((JDBCClob) x).data());
+
+            return;
+        } else if (x == null) {
+            setParameter(parameterIndex, null);
+
+            return;
+        }
+        checkSetParameterIndex(parameterIndex, false);
+
+        final long length = x.length();
+
+        if (length > Integer.MAX_VALUE) {
+            String msg = "Max Clob input character length exceeded: " + length;    // NOI18N
+
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR, msg);
+        }
+
+        try {
+            java.io.Reader  reader = x.getCharacterStream();
+            CharArrayWriter writer = new CharArrayWriter(reader, (int) length);
+
+            setParameter(parameterIndex, writer.toString());
+        } catch (IOException e) {
+            throw Util.sqlException(ErrorCode.SERVER_TRANSFER_CORRUPTED,
+                                    e.toString());
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.sql.Array</code> object.
+     * The driver converts this to an SQL <code>ARRAY</code> value when it
+     * sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From version 2.0, HSQLDB supports the SQL ARRAY type.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x an <code>Array</code> object that maps an SQL <code>ARRAY</code> value
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCParameterMetaData)
+     */
+    public synchronized void setArray(int parameterIndex,
+                                      Array x) throws SQLException {
+
+        checkParameterIndex(parameterIndex);
+
+        Type type = this.parameterMetaData.columnTypes[parameterIndex -1];
+
+        if (!type.isArrayType()) {
+            throw Util.sqlException(ErrorCode.X_42561);
+        }
+
+        if (x == null) {
+            checkSetParameterIndex(parameterIndex, false);
+            setParameter(parameterIndex, null);
+            return;
+        }
+
+        Object[] data = null;
+
+        if (x instanceof JDBCArray) {
+           data = (Object[]) ((JDBCArray) x).getArrayInternal();
+        } else {
+            Object object = x.getArray();
+
+            if (object instanceof Object[]) {
+                Type baseType  = type.collectionBaseType();
+                Object[] array = (Object[]) object;
+                data           = new Object[array.length];
+
+                for (int i = 0; i < data.length; i++) {
+                    data[i] = baseType.convertJavaToSQL(session, array[i]);
+                }
+
+            } else {
+
+                // if foreign data is not Object[]
+                throw Util.notSupported();
+            }
+        }
+
+
+
+        checkSetParameterIndex(parameterIndex, false);
+        parameterValues[parameterIndex - 1] = data;
+        return;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves a <code>ResultSetMetaData</code> object that contains
+     * information about the columns of the <code>ResultSet</code> object
+     * that will be returned when this <code>PreparedStatement</code> object
+     * is executed.
+     * <P>
+     * Because a <code>PreparedStatement</code> object is precompiled, it is
+     * possible to know about the <code>ResultSet</code> object that it will
+     * return without having to execute it.  Consequently, it is possible
+     * to invoke the method <code>getMetaData</code> on a
+     * <code>PreparedStatement</code> object rather than waiting to execute
+     * it and then invoking the <code>ResultSet.getMetaData</code> method
+     * on the <code>ResultSet</code> object that is returned.
+     * <P>
+     * <B>NOTE:</B> Using this method may be expensive for some drivers due
+     * to the lack of underlying DBMS support.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.2, this feature is supported and is <em>inexpensive</em> as
+     * it is backed by underlying DBMS support.  If the statement
+     * generates an update count, then null is returned.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return the description of a <code>ResultSet</code> object's columns or
+     *         <code>null</code> if the driver cannot return a
+     *         <code>ResultSetMetaData</code> object
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCParameterMetaData)
+     */
+    public synchronized ResultSetMetaData getMetaData() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (statementRetType != StatementTypes.RETURN_RESULT) {
+            return null;
+        }
+
+        if (resultSetMetaData == null) {
+            boolean isUpdatable  = ResultProperties.isUpdatable(rsProperties);
+            boolean isInsertable = isUpdatable;
+
+            if (isInsertable) {
+                for (int i = 0; i < resultMetaData.colIndexes.length; i++) {
+                    if (resultMetaData.colIndexes[i] < 0) {
+                        isInsertable = false;
+
+                        break;
+                    }
+                }
+            }
+            resultSetMetaData = new JDBCResultSetMetaData(resultMetaData,
+                    isUpdatable, isInsertable, connection);
+        }
+
+        return resultSetMetaData;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.sql.Date</code> value,
+     * using the given <code>Calendar</code> object.  The driver uses
+     * the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
+     * which the driver then sends to the database.  With
+     * a <code>Calendar</code> object, the driver can calculate the date
+     * taking into account a custom timezone.  If no
+     * <code>Calendar</code> object is specified, the driver uses the default
+     * timezone, which is that of the virtual machine running the application.
+     * <!-- end generic documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the date
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCParameterMetaData)
+     */
+    public synchronized void setDate(int parameterIndex, Date x,
+                                     Calendar cal) throws SQLException {
+
+        checkSetParameterIndex(parameterIndex, false);
+
+        int i = parameterIndex - 1;
+
+        if (x == null) {
+            parameterValues[i] = null;
+
+            return;
+        }
+
+        Type outType    = parameterTypes[i];
+        long millis = HsqlDateTime.convertToNormalisedDate(x.getTime(), cal);
+        int  zoneOffset = HsqlDateTime.getZoneMillis(cal, millis);
+
+        switch (outType.typeCode) {
+
+            case Types.SQL_DATE :
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                break;
+            default :
+                throw Util.sqlException(ErrorCode.X_42561);
+        }
+        parameterValues[i] = new TimestampData((millis + zoneOffset) / 1000);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.sql.Time</code> value,
+     * using the given <code>Calendar</code> object.  The driver uses
+     * the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
+     * which the driver then sends to the database.  With
+     * a <code>Calendar</code> object, the driver can calculate the time
+     * taking into account a custom timezone.  If no
+     * <code>Calendar</code> object is specified, the driver uses the default
+     * timezone, which is that of the virtual machine running the application.
+     * <!-- end generic documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * When a setXXX method is used to set a parameter of type
+     * TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone (including
+     * Daylight Saving Time) of the Calendar is used as time zone for the
+     * value.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the time
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCParameterMetaData)
+     */
+    public synchronized void setTime(int parameterIndex, Time x,
+                                     Calendar cal) throws SQLException {
+
+        checkSetParameterIndex(parameterIndex, false);
+
+        int i = parameterIndex - 1;
+
+        if (x == null) {
+            parameterValues[i] = null;
+
+            return;
+        }
+
+        Type     outType    = parameterTypes[i];
+        long     millis     = x.getTime();
+        int      zoneOffset = 0;
+        Calendar calendar   = cal == null ? session.getCalendar()
+                : cal;
+
+        millis = HsqlDateTime.convertMillisFromCalendar(calendar, millis);
+        millis = HsqlDateTime.convertToNormalisedTime(millis);
+
+        switch (outType.typeCode) {
+
+            case Types.SQL_TIME :
+                break;
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                zoneOffset = HsqlDateTime.getZoneMillis(calendar, millis);
+
+                break;
+            default :
+                throw Util.sqlException(ErrorCode.X_42561);
+        }
+        parameterValues[i] = new TimeData((int) (millis / 1000), 0,
+                zoneOffset / 1000);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
+     * using the given <code>Calendar</code> object.  The driver uses
+     * the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,
+     * which the driver then sends to the database.  With a
+     *  <code>Calendar</code> object, the driver can calculate the timestamp
+     * taking into account a custom timezone.  If no
+     * <code>Calendar</code> object is specified, the driver uses the default
+     * timezone, which is that of the virtual machine running the application.
+     * <!-- end generic documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * When a setXXX method is used to set a parameter of type
+     * TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE the time zone (including
+     * Daylight Saving Time) of the Calendar is used as time zone.<p>
+     * In this case, if the Calendar argument is null, then the default Calendar
+     * for the clients JVM is used as the Calendar<p>
+     *
+     * When this method is used to set a parameter of type TIME or
+     * TIME WITH TIME ZONE, then the nanosecond value of the Timestamp object
+     * is used if the TIME parameter accepts fractional seconds.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @param cal the <code>Calendar</code> object the driver will use
+     *            to construct the timestamp
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCParameterMetaData)
+     */
+    public synchronized void setTimestamp(int parameterIndex, Timestamp x,
+            Calendar cal) throws SQLException {
+
+        checkSetParameterIndex(parameterIndex, false);
+
+        int i = parameterIndex - 1;
+
+        if (x == null) {
+            parameterValues[i] = null;
+
+            return;
+        }
+
+        Type     outType    = parameterTypes[i];
+        long     millis     = x.getTime();
+        int      zoneOffset = 0;
+        Calendar calendar   = cal == null ? session.getCalendar()
+                : cal;
+
+        millis = HsqlDateTime.convertMillisFromCalendar(calendar, millis);
+
+        switch (outType.typeCode) {
+
+            case Types.SQL_TIMESTAMP :
+                break;
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                zoneOffset = HsqlDateTime.getZoneMillis(calendar, millis);
+
+                break;
+            case Types.SQL_TIME :
+                parameterValues[i] = new TimeData((int) (millis / 1000),
+                        x.getNanos(), 0);
+
+                break;
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                zoneOffset = HsqlDateTime.getZoneMillis(calendar, millis);
+                parameterValues[i] = new TimeData((int) (millis / 1000),
+                        x.getNanos(), zoneOffset / 1000);
+
+                break;
+            default :
+                throw Util.sqlException(ErrorCode.X_42561);
+        }
+        parameterValues[i] = new TimestampData(millis / 1000, x.getNanos(),
+                zoneOffset / 1000);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to SQL <code>NULL</code>.
+     * This version of the method <code>setNull</code> should
+     * be used for user-defined types and REF type parameters.  Examples
+     * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and
+     * named array types.
+     *
+     * <P><B>Note:</B> To be portable, applications must give the
+     * SQL type code and the fully-qualified SQL type name when specifying
+     * a NULL user-defined or REF parameter.  In the case of a user-defined type
+     * the name is the type name of the parameter itself.  For a REF
+     * parameter, the name is the type name of the referenced type.  If
+     * a JDBC driver does not need the type code or type name information,
+     * it may ignore it.
+     *
+     * Although it is intended for user-defined and Ref parameters,
+     * this method may be used to set a null parameter of any JDBC type.
+     * If the parameter does not have a user-defined or REF type, the given
+     * typeName is ignored.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB simply ignores the sqlType and typeName arguments.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param sqlType a value from <code>java.sql.Types</code>
+     * @param typeName the fully-qualified name of an SQL user-defined type;
+     *  ignored if the parameter is not a user-defined type or REF
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @exception SQLFeatureNotSupportedException if <code>sqlType</code> is
+     * a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,
+     * <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,
+     * <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,
+     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
+     * or  <code>STRUCT</code> data type and the JDBC driver does not support
+     * this data type or if the JDBC driver does not support this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCParameterMetaData)
+     */
+    public synchronized void setNull(int parameterIndex, int sqlType,
+                                     String typeName) throws SQLException {
+        setParameter(parameterIndex, null);
+    }
+
+    //------------------------- JDBC 2.0 - overriden methods -------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Submits a batch of commands to the database for execution and
+     * if all commands execute successfully, returns an array of update counts.
+     * The <code>int</code> elements of the array that is returned are ordered
+     * to correspond to the commands in the batch, which are ordered
+     * according to the order in which they were added to the batch.
+     * The elements in the array returned by the method <code>executeBatch</code>
+     * may be one of the following:
+     * <OL>
+     * <LI>A number greater than or equal to zero -- indicates that the
+     * command was processed successfully and is an update count giving the
+     * number of rows in the database that were affected by the command's
+     * execution
+     * <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was
+     * processed successfully but that the number of rows affected is
+     * unknown
+     * <P>
+     * If one of the commands in a batch update fails to execute properly,
+     * this method throws a <code>BatchUpdateException</code>, and a JDBC
+     * driver may or may not continue to process the remaining commands in
+     * the batch.  However, the driver's behavior must be consistent with a
+     * particular DBMS, either always continuing to process commands or never
+     * continuing to process commands.  If the driver continues processing
+     * after a failure, the array returned by the method
+     * <code>BatchUpdateException.getUpdateCounts</code>
+     * will contain as many elements as there are commands in the batch, and
+     * at least one of the elements will be the following:
+     * <P>
+     * <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command failed
+     * to execute successfully and occurs only if a driver continues to
+     * process commands after a command fails
+     * </OL>
+     * <P>
+     * A driver is not required to implement this method.
+     * The possible implementations and return values have been modified in
+     * the Java 2 SDK, Standard Edition, version 1.3 to
+     * accommodate the option of continuing to proccess commands in a batch
+     * update after a <code>BatchUpdateException</code> obejct has been thrown. <p>
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 1.7.2, this feature is supported. <p>
+     *
+     * HSQLDB stops execution of commands in a batch when one of the commands
+     * results in an exception. The size of the returned array equals the
+     * number of commands that were executed successfully.<p>
+     *
+     * When the product is built under the JAVA1 target, an exception
+     * is never thrown and it is the responsibility of the client software to
+     * check the size of the  returned update count array to determine if any
+     * batch items failed.  To build and run under the JAVA2 target, JDK/JRE
+     * 1.3 or higher must be used.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return an array of update counts containing one element for each
+     * command in the batch.  The elements of the array are ordered according
+     * to the order in which commands were added to the batch.
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the
+     * driver does not support batch statements. Throws {@link BatchUpdateException}
+     * (a subclass of <code>SQLException</code>) if one of the commands sent to the
+     * database fails to execute properly or attempts to return a result set.
+     *
+     *
+     * @see #addBatch
+     * @see java.sql.DatabaseMetaData#supportsBatchUpdates()
+     * @since JDK 1.3 (JDK 1.1.x developers: read the overview for
+     * JDBCStatement)
+     */
+    public synchronized int[] executeBatch() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        checkStatementType(StatementTypes.RETURN_COUNT);
+
+        if (!isBatch) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_07506);
+        }
+        generatedResult = null;
+
+        int batchCount = resultOut.getNavigator().getSize();
+
+        resultIn = null;
+
+        try {
+            resultIn = session.execute(resultOut);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        } finally {
+            performPostExecute();
+            resultOut.getNavigator().clear();
+
+            isBatch = false;
+        }
+
+        if (resultIn.mode == ResultConstants.ERROR) {
+            throw Util.sqlException(resultIn);
+        }
+
+        RowSetNavigator navigator    = resultIn.getNavigator();
+        int[]           updateCounts = new int[navigator.getSize()];
+
+        for (int i = 0; i < updateCounts.length; i++) {
+            Object[] data = (Object[]) navigator.getNext();
+
+            updateCounts[i] = ((Integer) data[0]).intValue();
+        }
+
+        if (updateCounts.length != batchCount) {
+            if (errorResult == null) {
+                throw new BatchUpdateException(updateCounts);
+            } else {
+                errorResult.getMainString();
+
+                throw new BatchUpdateException(errorResult.getMainString(),
+                        errorResult.getSubString(),
+                        errorResult.getErrorCode(), updateCounts);
+            }
+        }
+
+        return updateCounts;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets escape processing on or off. <p>
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * As per JDBC spec, calling this method has no effect.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param enable <code>true</code> to enable escape processing;
+     *     <code>false</code> to disable it
+     * @exception SQLException if a database access error occurs
+     */
+    public void setEscapeProcessing(boolean enable) throws SQLException {
+        checkClosed();
+    }
+
+    /**
+     * This method should always throw if called for a PreparedStatement or
+     * CallableStatment.
+     *
+     * @param sql ignored
+     * @throws SQLException always
+     */
+    public void addBatch(String sql) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * This method should always throw if called for a PreparedStatement or
+     * CallableStatment.
+     *
+     * @param sql ignored
+     * @throws SQLException always
+     * @return nothing
+     */
+    public synchronized ResultSet executeQuery(
+            String sql) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * This method should always throw if called for a PreparedStatement or
+     * CallableStatment.
+     *
+     * @param sql ignored
+     * @throws SQLException always
+     * @return nothing
+     */
+    public boolean execute(String sql) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * This method should always throw if called for a PreparedStatement or
+     * CallableStatment.
+     *
+     * @param sql ignored
+     * @throws SQLException always
+     * @return nothing
+     */
+    public int executeUpdate(String sql) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * Does the specialized work required to free this object's resources and
+     * that of it's parent class. <p>
+     *
+     * @throws SQLException if a database access error occurs
+     */
+    public synchronized void close() throws SQLException {
+
+        if (isClosed()) {
+            return;
+        }
+        closeResultData();
+
+        HsqlException he = null;
+
+        try {
+
+            // fredt - if this is called by Connection.close() then there's no
+            // need to free the prepared statements on the server - it is done
+            // by Connection.close()
+            if (!connection.isClosed) {
+                session.execute(Result.newFreeStmtRequest(statementID));
+            }
+        } catch (HsqlException e) {
+            he = e;
+        }
+        parameterValues   = null;
+        parameterSet      = null;
+        parameterStream   = null;
+        parameterTypes    = null;
+        parameterModes    = null;
+        resultMetaData    = null;
+        parameterMetaData = null;
+        resultSetMetaData = null;
+        pmd               = null;
+        connection        = null;
+        resultIn          = null;
+        resultOut         = null;
+        isClosed          = true;
+
+        if (he != null) {
+            throw Util.sqlException(he);
+        }
+    }
+
+    /**
+     * Retrieves a String representation of this object.  <p>
+     *
+     * The representation is of the form: <p>
+     *
+     * class-name@hash[sql=[char-sequence], parameters=[p1, ...pi, ...pn]] <p>
+     *
+     * p1, ...pi, ...pn are the String representations of the currently set
+     * parameter values that will be used with the non-batch execution
+     * methods. <p>
+     *
+     * @return a String representation of this object
+     */
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer();
+        String       sql;
+        Object[]     pv;
+
+        sb.append(super.toString());
+
+        sql = this.sql;
+        pv  = parameterValues;
+
+        if (sql == null || pv == null) {
+            sb.append("[closed]");
+
+            return sb.toString();
+        }
+        sb.append("[sql=[").append(sql).append("]");
+
+        if (pv.length > 0) {
+            sb.append(", parameters=[");
+
+            for (int i = 0; i < pv.length; i++) {
+                sb.append('[');
+                sb.append(pv[i]);
+                sb.append("], ");
+            }
+            sb.setLength(sb.length() - 2);
+            sb.append(']');
+        }
+        sb.append(']');
+
+        return sb.toString();
+    }
+
+    //------------------------- JDBC 3.0 -----------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the designated parameter to the given <code>java.net.URL</code> value.
+     * The driver converts this to an SQL <code>DATALINK</code> value
+     * when it sends it to the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, HSQLDB does not support the DATALINK SQL type for which this
+     * method is intended. Calling this method throws an exception.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the <code>java.net.URL</code> object to be set
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.4, HSQL 1.7.0
+     */
+//#ifdef JAVA4
+    public void setURL(int parameterIndex,
+                       java.net.URL x) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the number, types and properties of this
+     * <code>PreparedStatement</code> object's parameters.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.7.2, this feature is supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>ParameterMetaData</code> object that contains information
+     *         about the number, types and properties for each
+     *  parameter marker of this <code>PreparedStatement</code> object
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @see java.sql.ParameterMetaData
+     * @since JDK 1.4, HSQL 1.7.0
+     */
+//#ifdef JAVA4
+    public synchronized ParameterMetaData getParameterMetaData() throws SQLException {
+
+        checkClosed();
+
+        if (pmd == null) {
+            pmd = new JDBCParameterMetaData(connection, parameterMetaData);
+        }
+
+        // NOTE:  pmd is declared as Object to avoid yet another #ifdef.
+        return (ParameterMetaData) pmd;
+    }
+
+//#endif JAVA4
+
+    /**
+     * Statement methods that must be overridden in this class and throw
+     * an exception.
+     */
+//#ifdef JAVA4
+    public int executeUpdate(String sql,
+                             int autoGeneratedKeys) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    public boolean execute(String sql,
+                           int autoGeneratedKeys) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    public int executeUpdate(String sql,
+                             int[] columnIndexes) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    public boolean execute(String sql,
+                           int[] columnIndexes) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    public int executeUpdate(String sql,
+                             String[] columnNames) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    public boolean execute(String sql,
+                           String[] columnNames) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves to this <code>Statement</code> object's next result, deals with
+     * any current <code>ResultSet</code> object(s) according  to the instructions
+     * specified by the given flag, and returns
+     * <code>true</code> if the next result is a <code>ResultSet</code> object.
+     *
+     * <P>There are no more results when the following is true:
+     * <PRE>
+     *     // stmt is a Statement object
+     *     ((stmt.getMoreResults(current) == false) && (stmt.getUpdateCount() == -1))
+     * </PRE>
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param current one of the following <code>Statement</code>
+     *        constants indicating what should happen to current
+     *        <code>ResultSet</code> objects obtained using the method
+     *        <code>getResultSet</code>:
+     *        <code>Statement.CLOSE_CURRENT_RESULT</code>,
+     *        <code>Statement.KEEP_CURRENT_RESULT</code>, or
+     *        <code>Statement.CLOSE_ALL_RESULTS</code>
+     * @return <code>true</code> if the next result is a <code>ResultSet</code>
+     *         object; <code>false</code> if it is an update count or there are no
+     *         more results
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the argument
+     *             supplied is not one of the following:
+     *        <code>Statement.CLOSE_CURRENT_RESULT</code>,
+     *        <code>Statement.KEEP_CURRENT_RESULT</code>, or
+     *        <code>Statement.CLOSE_ALL_RESULTS</code>
+     * @since JDK 1.4, HSQLDB 1.7
+     * @see #execute
+     */
+//#ifdef JAVA4
+    public synchronized boolean getMoreResults(
+            int current) throws SQLException {
+        return super.getMoreResults(current);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves any auto-generated keys created as a result of executing this
+     * <code>Statement</code> object. If this <code>Statement</code> object did
+     * not generate any keys, an empty <code>ResultSet</code>
+     * object is returned.
+     * <p>(JDBC4 clarification:)
+     * <p><B>Note:</B>If the columns which represent the auto-generated keys were not specified,
+     * the JDBC driver implementation will determine the columns which best represent the auto-generated keys.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Supported in version 2.0.<p>
+     *
+     * If column names or indexes provided by the user in the executeUpdate()
+     * method calls are not correct, an empty result is returned.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>ResultSet</code> object containing the auto-generated key(s)
+     *         generated by the execution of this <code>Statement</code> object
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized ResultSet getGeneratedKeys() throws SQLException {
+        return getGeneratedResultSet();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the result set holdability for <code>ResultSet</code> objects
+     * generated by this <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.7.2, this method returns HOLD_CURSORS_OVER_COMMIT
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized int getResultSetHoldability() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return ResultProperties.getJDBCHoldability(rsProperties);
+    }
+
+//#endif JAVA4
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * Retrieves whether this <code>Statement</code> object has been closed. A <code>Statement</code> is closed if the
+     * method close has been called on it, or if it is automatically closed.
+     * @return true if this <code>Statement</code> object is closed; false if it is still open
+     * @throws SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized boolean isClosed() {
+        return isClosed;
+    }
+
+    /**
+     * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The
+     * driver converts this to a SQL <code>ROWID</code> value when it sends it
+     * to the database
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the parameter value
+     * @throws SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+
+//#ifdef JAVA6
+    public void setRowId(int parameterIndex, RowId x) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * Sets the designated paramter to the given <code>String</code> object.
+     * The driver converts this to a SQL <code>NCHAR</code> or
+     * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+     * (depending on the argument's
+     * size relative to the driver's limits on <code>NVARCHAR</code> values)
+     * when it sends it to the database.
+     *
+     * @param parameterIndex of the first parameter is 1, the second is 2, ...
+     * @param value the parameter value
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur ; if a database access error occurs; or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized void setNString(int parameterIndex,
+                                        String value) throws SQLException {
+        setString(parameterIndex, value);
+    }
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object. The
+     * <code>Reader</code> reads the data till end-of-file is reached. The
+     * driver does the necessary conversion from Java character format to
+     * the national character set in the database.
+     * @param parameterIndex of the first parameter is 1, the second is 2, ...
+     * @param value the parameter value
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur ; if a database access error occurs; or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized void setNCharacterStream(int parameterIndex,
+            Reader value, long length) throws SQLException {
+        setCharacterStream(parameterIndex, value, length);
+    }
+
+    /**
+     * Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to a
+     * SQL <code>NCLOB</code> value when it sends it to the database.
+     * @param parameterIndex of the first parameter is 1, the second is 2, ...
+     * @param value the parameter value
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur ; if a database access error occurs; or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+
+//#ifdef JAVA6
+    public synchronized void setNClob(int parameterIndex,
+                                      NClob value) throws SQLException {
+        setClob(parameterIndex, value);
+    }
+
+//#endif JAVA6
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object.  The reader must contain  the number
+     * of characters specified by length otherwise a <code>SQLException</code> will be
+     * generated when the <code>PreparedStatement</code> is executed.
+     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
+     * because it informs the driver that the parameter value should be sent to
+     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if a database access error occurs, this method is called on
+     * a closed <code>PreparedStatement</code>, if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement, or if the length specified is less than zero.
+     *
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized void setClob(int parameterIndex, Reader reader,
+                                     long length) throws SQLException {
+        setCharacterStream(parameterIndex, reader, length);
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to a <code>InputStream</code> object.  The inputstream must contain  the number
+     * of characters specified by length otherwise a <code>SQLException</code> will be
+     * generated when the <code>PreparedStatement</code> is executed.
+     * This method differs from the <code>setBinaryStream (int, InputStream, int)</code>
+     * method because it informs the driver that the parameter value should be
+     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * In HSQLDB 2.0, this method uses streaming to send the data when the
+     * stream is assigned to a BLOB target. For other binary targets the
+     * stream is read on the client side and a byte array is sent.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex index of the first parameter is 1,
+     * the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @param length the number of bytes in the parameter data.
+     * @throws SQLException if a database access error occurs,
+     * this method is called on a closed <code>PreparedStatement</code>,
+     * if parameterIndex does not correspond
+     * to a parameter marker in the SQL statement,  if the length specified
+     * is less than zero or if the number of bytes in the inputstream does not match
+     * the specfied length.
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized void setBlob(int parameterIndex,
+                                     InputStream inputStream,
+                                     long length) throws SQLException {
+        setBinaryStream(parameterIndex, inputStream, length);
+    }
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object.  The reader must contain  the number
+     * of characters specified by length otherwise a <code>SQLException</code> will be
+     * generated when the <code>PreparedStatement</code> is executed.
+     * This method differs from the <code>setCharacterStream (int, Reader, int)</code> method
+     * because it informs the driver that the parameter value should be sent to
+     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter
+     * data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement; if the length specified is less than zero;
+     * if the driver does not support national character sets;
+     * if the driver can detect that a data conversion
+     *  error could occur;  if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized void setNClob(int parameterIndex, Reader reader,
+                                      long length) throws SQLException {
+        setClob(parameterIndex, reader, length);
+    }
+
+    /**
+     * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object.
+     * The driver converts this to an
+     * SQL <code>XML</code> value when it sends it to the database.
+     * <p>
+     *
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param xmlObject a <code>SQLXML</code> object that maps an SQL <code>XML</code> value
+     * @throws SQLException if a database access error occurs,
+     *  this method is called on a closed <code>PreparedStatement</code>
+     * or the <code>java.xml.transform.Result</code>,
+     *  <code>Writer</code> or <code>OutputStream</code> has not been closed for
+     * the <code>SQLXML</code> object
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+
+//#ifdef JAVA6
+    public void setSQLXML(int parameterIndex,
+                          SQLXML xmlObject) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+// --------------------------- Added: Mustang Build 86 -------------------------
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to the given input stream, which will have
+     * the specified number of bytes.
+     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from ASCII to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From HSQLDB 2.0 this method uses the US-ASCII character encoding to convert bytes
+     * from the stream into the characters of a String.<p>
+     * This method does not use streaming to send the data,
+     * whether the target is a CLOB or other binary object.<p>
+     *
+     * For long streams (larger than a few megabytes) with CLOB targets,
+     * it is more efficient to use a version of setCharacterStream which takes
+     * the a length parameter.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @param length the number of bytes in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @since JDK 1.6 b86, HSQLDB 2.0
+     */
+    public synchronized void setAsciiStream(int parameterIndex,
+            java.io.InputStream x, long length) throws SQLException {
+
+        if (length < 0) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "length: " + length);
+        }
+        setAscStream(parameterIndex, x, (long) length);
+    }
+
+    void setAscStream(int parameterIndex, java.io.InputStream x,
+                      long length) throws SQLException {
+
+        if (length > Integer.MAX_VALUE) {
+            Util.sqlException(ErrorCode.X_22001);
+        }
+        checkSetParameterIndex(parameterIndex, true);
+
+        if (x == null) {
+            throw Util.nullArgument("x");
+        }
+
+        try {
+            String s = StringConverter.inputStreamToString(x, "US-ASCII");
+
+            if (length >= 0 && s.length() > length) {
+                s = s.substring(0, (int) length);
+            }
+            setParameter(parameterIndex, s);
+        } catch (IOException e) {
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR);
+        }
+    }
+
+    /**
+     * Sets the designated parameter to the given input stream, which will have
+     * the specified number of bytes.
+     * When a very large binary value is input to a <code>LONGVARBINARY</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code> object. The data will be read from the
+     * stream as needed until end-of-file is reached.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * In HSQLDB 2.0, this method uses streaming to send the data when the
+     * stream is assigned to a BLOB target. For other binary targets the
+     * stream is read on the client side and a byte array is sent.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the java input stream which contains the binary parameter value
+     * @param length the number of bytes in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @since JDK 1.6 b86, HSQLDB 2.0
+     */
+    public synchronized void setBinaryStream(int parameterIndex,
+            java.io.InputStream x, long length) throws SQLException {
+
+        if (length < 0) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "length: " + length);
+        }
+        setBinStream(parameterIndex, x, length);
+    }
+
+    private void setBinStream(int parameterIndex, java.io.InputStream x,
+                              long length) throws SQLException {
+
+        if (x instanceof BlobInputStream) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "invalid InputStream");
+        }
+        checkSetParameterIndex(parameterIndex, true);
+
+        if (parameterTypes[parameterIndex - 1].typeCode == Types.SQL_BLOB) {
+            try {
+                if (length < 0) {
+                    HsqlByteArrayOutputStream output;
+
+                    output = new HsqlByteArrayOutputStream(x);
+
+                    JDBCBlob blob = new JDBCBlob(output.toByteArray());
+
+                    setBlobParameter(parameterIndex, blob);
+
+                    return;
+                }
+            } catch (IOException e) {
+                throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR,
+                                        e.toString());
+            }
+            streamLengths[parameterIndex - 1] = length;
+
+            setParameter(parameterIndex, x);
+
+            return;
+        }
+
+        try {
+            if (length > Integer.MAX_VALUE) {
+                String msg = "Maximum Blob input length exceeded: " + length;
+
+                throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR, msg);
+            }
+
+            HsqlByteArrayOutputStream output;
+
+            if (length < 0) {
+                output = new HsqlByteArrayOutputStream(x);
+            } else {
+                output = new HsqlByteArrayOutputStream(x, (int) length);
+            }
+            setParameter(parameterIndex, output.toByteArray());
+        } catch (IOException e) {
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR,
+                                    e.toString());
+        }
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to the given <code>Reader</code>
+     * object, which is the given number of characters long.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From HSQLDB 2.0 this method uses streaming to send data
+     * when the target is a CLOB.<p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     *        Unicode data
+     * @param length the number of characters in the stream
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @since JDK 1.6 b86, HSQLDB 2.0
+     */
+    public synchronized void setCharacterStream(int parameterIndex,
+            java.io.Reader reader, long length) throws SQLException {
+
+        if (length < 0) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "length: " + length);
+        }
+        setCharStream(parameterIndex, reader, length);
+    }
+
+    private void setCharStream(int parameterIndex, java.io.Reader reader,
+                               long length) throws SQLException {
+
+        if (reader instanceof ClobInputStream) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "invalid Reader");
+        }
+        checkSetParameterIndex(parameterIndex, true);
+
+        if (parameterTypes[parameterIndex - 1].typeCode == Types.SQL_CLOB) {
+            try {
+                if (length < 0) {
+                    CharArrayWriter output;
+
+                    output = new CharArrayWriter(reader);
+
+                    JDBCClob clob = new JDBCClob(output.toString());
+
+                    setClobParameter(parameterIndex, clob);
+
+                    return;
+                }
+            } catch (IOException e) {
+                throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR,
+                                        e.toString());
+            }
+            streamLengths[parameterIndex - 1] = length;
+
+            setParameter(parameterIndex, reader);
+
+            return;
+        }
+
+        try {
+            if (length > Integer.MAX_VALUE) {
+                String msg = "Maximum Clob input length exceeded: " + length;
+
+                throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR, msg);
+            }
+
+            CharArrayWriter writer;
+
+            if (length < 0) {
+                writer = new CharArrayWriter(reader);
+            } else {
+                writer = new CharArrayWriter(reader, (int) length);
+            }
+            setParameter(parameterIndex, writer.toString());
+        } catch (IOException e) {
+            throw Util.sqlException(ErrorCode.JDBC_INPUTSTREAM_ERROR,
+                                    e.toString());
+        }
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to the given input stream.
+     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from ASCII to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setAsciiStream</code> which takes a length parameter.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * In HSQLDB 2.0, this method does not use streaming to send the data,
+     * whether the target is a CLOB or other binary object.
+     *
+     * For long streams (larger than a few megabytes), it is more efficient to
+     * use a version of setCharacterStream which takes the a length parameter.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the Java input stream that contains the ASCII parameter value
+     * @exception SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement; if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *   @since 1.6
+     */
+    public void setAsciiStream(int parameterIndex,
+                               java.io.InputStream x) throws SQLException {
+        setAscStream(parameterIndex, x, -1);
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to the given input stream.
+     * When a very large binary value is input to a <code>LONGVARBINARY</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code> object. The data will be read from the
+     * stream as needed until end-of-file is reached.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setBinaryStream</code> which takes a length parameter.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From HSQLDB 2.0 this method uses the US-ASCII character encoding to convert bytes
+     * from the stream into the characters of a String.<p>
+     * This method does not use streaming to send the data,
+     * whether the target is a CLOB or other binary object.<p>
+     *
+     * For long streams (larger than a few megabytes) with CLOB targets,
+     * it is more efficient to use a version of setCharacterStream which takes
+     * the a length parameter.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param x the java input stream which contains the binary parameter value
+     * @exception SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement; if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since 1.6
+     */
+    public synchronized void setBinaryStream(int parameterIndex,
+            java.io.InputStream x) throws SQLException {
+        setBinStream(parameterIndex, x, -1);
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to the given <code>Reader</code>
+     * object.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setCharacterStream</code> which takes a length parameter.
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * In HSQLDB 2.0, this method does not use streaming to send the data,
+     * whether the target is a CLOB or other binary object.
+     *
+     * For long streams (larger than a few megabytes), it is more efficient to
+     * use a version of setCharacterStream which takes the a length parameter.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param parameterIndex the first parameter is 1, the second is 2, ...
+     * @param reader the <code>java.io.Reader</code> object that contains the
+     *        Unicode data
+     * @exception SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement; if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since 1.6
+     */
+    public void setCharacterStream(int parameterIndex,
+                                   java.io.Reader reader) throws SQLException {
+        setCharStream(parameterIndex, reader, -1);
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     *   Sets the designated parameter to a <code>Reader</code> object. The
+     *   <code>Reader</code> reads the data till end-of-file is reached. The
+     *   driver does the necessary conversion from Java character format to
+     *   the national character set in the database.
+     *
+     *   <P><B>Note:</B> This stream object can either be a standard
+     *   Java stream object or your own subclass that implements the
+     *   standard interface.
+     *   <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     *   it might be more efficient to use a version of
+     *   <code>setNCharacterStream</code> which takes a length parameter.
+     *
+     *   @param parameterIndex of the first parameter is 1, the second is 2, ...
+     *   @param value the parameter value
+     *   @throws SQLException if parameterIndex does not correspond to a parameter
+     *   marker in the SQL statement; if the driver does not support national
+     *           character sets;  if the driver can detect that a data conversion
+     *    error could occur; if a database access error occurs; or
+     *   this method is called on a closed <code>PreparedStatement</code>
+     *   @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *   @since 1.6
+     */
+    public void setNCharacterStream(int parameterIndex,
+                                    Reader value) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object.
+     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
+     * because it informs the driver that the parameter value should be sent to
+     * the server as a <code>CLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter
+     * data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setClob</code> which takes a length parameter.
+     *
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement; if a database access error occurs; this method is called on
+     * a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement
+     *
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since 1.6
+     */
+    public void setClob(int parameterIndex,
+                        Reader reader) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to a <code>InputStream</code> object.
+     * This method differs from the <code>setBinaryStream (int, InputStream)</code>
+     * method because it informs the driver that the parameter value should be
+     * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
+     * the driver may have to do extra work to determine whether the parameter
+     * data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setBlob</code> which takes a length parameter.
+     *
+     * @param parameterIndex index of the first parameter is 1,
+     * the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @throws SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement; if a database access error occurs;
+     * this method is called on a closed <code>PreparedStatement</code> or
+     * if parameterIndex does not correspond
+     * to a parameter marker in the SQL statement,
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *
+     * @since 1.6
+     */
+    public void setBlob(int parameterIndex,
+                        InputStream inputStream) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /** @todo 1.9.0 - implement streaming and remove length limits */
+
+    /**
+     * Sets the designated parameter to a <code>Reader</code> object.
+     * This method differs from the <code>setCharacterStream (int, Reader)</code> method
+     * because it informs the driver that the parameter value should be sent to
+     * the server as a <code>NCLOB</code>.  When the <code>setCharacterStream</code> method is used, the
+     * driver may have to do extra work to determine whether the parameter
+     * data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>setNClob</code> which takes a length parameter.
+     *
+     * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if parameterIndex does not correspond to a parameter
+     * marker in the SQL statement;
+     * if the driver does not support national character sets;
+     * if the driver can detect that a data conversion
+     *  error could occur;  if a database access error occurs or
+     * this method is called on a closed <code>PreparedStatement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     *
+     * @since 1.6
+     */
+    public void setNClob(int parameterIndex,
+                         Reader reader) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the maximum number of bytes that can be
+     * returned for character and binary column values in a <code>ResultSet</code>
+     * object produced by this <code>Statement</code> object.
+     * This limit applies only to  <code>BINARY</code>, <code>VARBINARY</code>,
+     * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
+     * (JDBC4 new:) <code>NCHAR</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>
+     * and <code>LONGVARCHAR</code> columns.  If the limit is exceeded, the
+     * excess data is silently discarded.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB always returns zero, meaning there is no limit.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the current column size limit for columns storing character and
+     *         binary values; zero means there is no limit
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #setMaxFieldSize
+     */
+    public synchronized int getMaxFieldSize() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return 0;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:) Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
+     * Sets the limit for the maximum number of bytes that can be returned for
+     * character and binary column values in a <code>ResultSet</code>
+     * object produced by this <code>Statement</code> object.
+     *
+     * This limit applies
+     * only to <code>BINARY</code>, <code>VARBINARY</code>,
+     * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
+     * (JDBC4 new:) <code>NCHAR</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code> and
+     * <code>LONGVARCHAR</code> fields.  If the limit is exceeded, the excess data
+     * is silently discarded. For maximum portability, use values
+     * greater than 256.
+     * <!-- emd generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * To present, calls to this method are simply ignored; HSQLDB always
+     * stores the full number of bytes when dealing with any of the field types
+     * mentioned above. These types all have an absolute maximum element upper
+     * bound determined by the Java array index limit
+     * java.lang.Integer.MAX_VALUE.  For XXXBINARY types, this translates to
+     * Integer.MAX_VALUE bytes.  For XXXCHAR types, this translates to
+     * 2 * Integer.MAX_VALUE bytes (2 bytes / character). <p>
+     *
+     * In practice, field sizes are limited to values much smaller than the
+     * absolute maximum element upper bound, in particular due to limits imposed
+     * on the maximum available Java heap memory.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param max the new column size limit in bytes; zero means there is no limit
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>
+     *            or the condition max >= 0 is not satisfied
+     * @see #getMaxFieldSize
+     */
+    public synchronized void setMaxFieldSize(int max) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (max < 0) {
+            throw Util.outOfRangeArgument();
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the maximum number of rows that a
+     * <code>ResultSet</code> object produced by this
+     * <code>Statement</code> object can contain.  If this limit is exceeded,
+     * the excess rows are silently dropped.
+     * <!-- start generic documentation -->
+     *
+     * @return the current maximum number of rows for a <code>ResultSet</code>
+     *         object produced by this <code>Statement</code> object;
+     *         zero means there is no limit
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #setMaxRows
+     */
+    public synchronized int getMaxRows() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return maxRows;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Sets the limit for the maximum number of rows that any
+     * <code>ResultSet</code> object  generated by this <code>Statement</code>
+     * object can contain to the given number.
+     * If the limit is exceeded, the excess
+     * rows are silently dropped.
+     * <!-- end generic documentation -->
+     *
+     * @param max the new max rows limit; zero means there is no limit
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>
+     *            or the condition max >= 0 is not satisfied
+     * @see #getMaxRows
+     */
+    public synchronized void setMaxRows(int max) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (max < 0) {
+            throw Util.outOfRangeArgument();
+        }
+        maxRows = max;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the number of seconds the driver will
+     * wait for a <code>Statement</code> object to execute.
+     * If the limit is exceeded, a
+     * <code>SQLException</code> is thrown.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * To present, HSQLDB always returns zero, meaning there
+     * is no limit.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the current query timeout limit in seconds; zero means there is
+     *         no limit
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #setQueryTimeout
+     */
+    public synchronized int getQueryTimeout() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return 0;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the number of seconds the driver will wait for a
+     * <code>Statement</code> object to execute to the given number of seconds.
+     * If the limit is exceeded, an <code>SQLException</code> is thrown. A JDBC
+     * (JDBC4 clarification:)
+     * driver must apply this limit to the <code>execute</code>,
+     * <code>executeQuery</code> and <code>executeUpdate</code> methods. JDBC driver
+     * implementations may also apply this limit to <code>ResultSet</code> methods
+     * (consult your driver vendor documentation for details).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The maximum value is Short.MAX_VALUE. The minimum is 0, indicating no limit.
+     * In 2.0, calls to this method are ignored; HSQLDB waits an
+     * unlimited amount of time for statement execution
+     * requests to return.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param seconds the new query timeout limit in seconds; zero means
+     *        there is no limit
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>
+     *            or the condition seconds >= 0 is not satisfied
+     * @see #getQueryTimeout
+     */
+    public synchronized void setQueryTimeout(int seconds) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (seconds < 0 || seconds > Short.MAX_VALUE) {
+            throw Util.outOfRangeArgument();
+        }
+        queryTimeout = seconds;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Cancels this <code>Statement</code> object if both the DBMS and
+     * driver support aborting an SQL statement.
+     * This method can be used by one thread to cancel a statement that
+     * is being executed by another thread.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, HSQLDB does <i>not</i> support aborting an SQL
+     * statement; calls to this method are ignored.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     */
+    public void cancel() throws SQLException {
+        checkClosed();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the first warning reported by calls on this <code>Statement</code> object.
+     * Subsequent <code>Statement</code> object warnings will be chained to this
+     * <code>SQLWarning</code> object.
+     *
+     * <p>The warning chain is automatically cleared each time
+     * a statement is (re)executed. This method may not be called on a closed
+     * <code>Statement</code> object; doing so will cause an <code>SQLException</code>
+     * to be thrown.
+     *
+     * <P><B>Note:</B> If you are processing a <code>ResultSet</code> object, any
+     * warnings associated with reads on that <code>ResultSet</code> object
+     * will be chained on it rather than on the <code>Statement</code>
+     * object that produced it.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 1.9 HSQLDB, produces Statement warnings.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the first <code>SQLWarning</code> object or <code>null</code>
+     *         if there are no warnings
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     */
+    public synchronized SQLWarning getWarnings() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return rootWarning;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Clears all the warnings reported on this <code>Statement</code>
+     * object. After a call to this method,
+     * the method <code>getWarnings</code> will return
+     * <code>null</code> until a new warning is reported for this
+     * <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Supported in HSQLDB 1.9.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     */
+    public synchronized void clearWarnings() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        rootWarning = null;
+    }
+
+    /** @todo 1.9.0 - implement */
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the SQL cursor name to the given <code>String</code>, which
+     * will be used by subsequent <code>Statement</code> object
+     * <code>execute</code> methods. This name can then be
+     * used in SQL positioned update or delete statements to identify the
+     * current row in the <code>ResultSet</code> object generated by this
+     * statement.  If the database does not support positioned update/delete,
+     * this method is a noop.  To insure that a cursor has the proper isolation
+     * level to support updates, the cursor's <code>SELECT</code> statement
+     * should have the form <code>SELECT FOR UPDATE</code>.  If
+     * <code>FOR UPDATE</code> is not present, positioned updates may fail.
+     *
+     * <P><B>Note:</B> By definition, the execution of positioned updates and
+     * deletes must be done by a different <code>Statement</code> object than
+     * the one that generated the <code>ResultSet</code> object being used for
+     * positioning. Also, cursor names must be unique within a connection.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, HSQLDB does not support named cursors;
+     * calls to this method are ignored.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param name the new cursor name, which must be unique within
+     *             a connection
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     */
+    public void setCursorName(String name) throws SQLException {
+        checkClosed();
+    }
+
+    //----------------------- Multiple Results --------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     *  Retrieves the current result as a <code>ResultSet</code> object.
+     *  This method should be called only once per result.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Without an interceding call to executeXXX, each invocation of this
+     * method will produce a new, initialized ResultSet instance referring to
+     * the current result, if any.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the current result as a <code>ResultSet</code> object or
+     * <code>null</code> if the result is an update count or there are no more results
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #execute
+     */
+    public synchronized ResultSet getResultSet() throws SQLException {
+        return super.getResultSet();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *  Retrieves the current result as an update count;
+     *  if the result is a <code>ResultSet</code> object or there are no more results, -1
+     *  is returned. This method should be called only once per result.
+     * <!-- end generic documentation -->
+     *
+     * @return the current result as an update count; -1 if the current result is a
+     * <code>ResultSet</code> object or there are no more results
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #execute
+     */
+    public synchronized int getUpdateCount() throws SQLException {
+        return super.getUpdateCount();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves to this <code>Statement</code> object's next result, returns
+     * <code>true</code> if it is a <code>ResultSet</code> object, and
+     * implicitly closes any current <code>ResultSet</code>
+     * object(s) obtained with the method <code>getResultSet</code>.
+     *
+     * <P>There are no more results when the following is true:
+     * <PRE>
+     *     // stmt is a Statement object
+     *     ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
+     * </PRE>
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the next result is a <code>ResultSet</code>
+     *         object; <code>false</code> if it is an update count or there are
+     *         no more results
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #execute
+     */
+    public synchronized boolean getMoreResults() throws SQLException {
+        return getMoreResults(JDBCStatementBase.CLOSE_CURRENT_RESULT);
+    }
+
+    //--------------------------JDBC 2.0-----------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Gives the driver a hint as to the direction in which
+     * rows will be processed in <code>ResultSet</code>
+     * objects created using this <code>Statement</code> object.  The
+     * default value is <code>ResultSet.FETCH_FORWARD</code>.
+     * <P>
+     * Note that this method sets the default fetch direction for
+     * result sets generated by this <code>Statement</code> object.
+     * Each result set has its own methods for getting and setting
+     * its own fetch direction.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Up to 1.8.0.x, HSQLDB supports only <code>FETCH_FORWARD</code>;
+     * Setting any other value would throw an <code>SQLException</code>
+     * stating that the operation is not supported. <p>
+     *
+     * Starting with 2.0, HSQLDB accepts any valid value.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param direction the initial direction for processing rows
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>
+     * or the given direction
+     * is not one of <code>ResultSet.FETCH_FORWARD</code>,
+     * <code>ResultSet.FETCH_REVERSE</code>, or <code>ResultSet.FETCH_UNKNOWN</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *    for JDBCStatement)
+     * @see #getFetchDirection
+     */
+    public synchronized void setFetchDirection(
+            int direction) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (direction != JDBCResultSet.FETCH_FORWARD
+                && direction != JDBCResultSet.FETCH_REVERSE
+                && direction != JDBCResultSet.FETCH_UNKNOWN) {
+            throw Util.notSupported();
+        }
+        fetchDirection = direction;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the direction for fetching rows from
+     * database tables that is the default for result sets
+     * generated from this <code>Statement</code> object.
+     * If this <code>Statement</code> object has not set
+     * a fetch direction by calling the method <code>setFetchDirection</code>,
+     * the return value is implementation-specific.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Up to 1.8.0.x, HSQLDB always returned FETCH_FORWARD.
+     *
+     * Starting with 2.0, HSQLDB returns FETCH_FORWARD by default, or
+     * whatever value has been explicitly assigned by invoking
+     * <code>setFetchDirection</code>.
+     * .
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the default fetch direction for result sets generated
+     *          from this <code>Statement</code> object
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *    for JDBCStatement)
+     * @see #setFetchDirection
+     */
+    public synchronized int getFetchDirection() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return fetchDirection;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Gives the JDBC driver a hint as to the number of rows that should
+     * be fetched from the database when more rows are needed for
+     * <code>ResultSet</code> objects genrated by this <code>Statement</code>.
+     * If the value specified is zero, then the hint is ignored.
+     * The default value is zero.
+     * <!-- start generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB uses the specified value as a hint, but may process more or fewer
+     * rows than specified.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param rows the number of rows to fetch
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the
+     *        (JDBC4 modified:)
+     *        condition  <code>rows >= 0</code> is not satisfied.
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *   for JDBCStatement)
+     * @see #getFetchSize
+     */
+    public synchronized void setFetchSize(int rows) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (rows < 0) {
+            throw Util.outOfRangeArgument();
+        }
+        fetchSize = rows;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the number of result set rows that is the default
+     * fetch size for <code>ResultSet</code> objects
+     * generated from this <code>Statement</code> object.
+     * If this <code>Statement</code> object has not set
+     * a fetch size by calling the method <code>setFetchSize</code>,
+     * the return value is implementation-specific.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <b>HSQLDB-Specific Information</b> <p>
+     *
+     * HSQLDB returns 0 by default, or the fetch size specified by setFetchSize
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the default fetch size for result sets generated
+     *          from this <code>Statement</code> object
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *  for JDBCStatement)
+     * @see #setFetchSize
+     */
+    public synchronized int getFetchSize() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return fetchSize;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the result set concurrency for <code>ResultSet</code> objects
+     * generated by this <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports <code>CONCUR_READ_ONLY</code> and
+     * <code>CONCUR_READ_UPDATEBLE</code> concurrency.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return either <code>ResultSet.CONCUR_READ_ONLY</code> or
+     * <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *  for JDBCStatement)
+     */
+    public synchronized int getResultSetConcurrency() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return ResultProperties.getJDBCConcurrency(rsProperties);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the result set type for <code>ResultSet</code> objects
+     * generated by this <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 1.7.0 and later versions support <code>TYPE_FORWARD_ONLY</code>
+     * and <code>TYPE_SCROLL_INSENSITIVE</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *   for JDBCStatement)
+     */
+    public synchronized int getResultSetType() throws SQLException {
+
+        // fredt - omit checkClosed() in order to be able to handle the result of a
+        // SHUTDOWN query
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return ResultProperties.getJDBCScrollability(rsProperties);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Empties this <code>Statement</code> object's current list of
+     * SQL commands.
+     * <P>
+     * (JDBC4 clarification:) <p>
+     * <B>NOTE:</B>  Support of an ability to batch updates is optional.
+     * <!-- start generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 1.7.2, this feature is supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs,
+     *  this method is called on a closed <code>Statement</code> or the
+     * driver does not support batch updates
+     * @see #addBatch
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *   for JDBCStatement)
+     */
+    public synchronized void clearBatch() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (isBatch) {
+            resultOut.getNavigator().clear();
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the <code>Connection</code> object
+     * that produced this <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * @return the connection that produced this statement
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *    for JDBCStatement)
+     */
+    public synchronized Connection getConnection() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return connection;
+    }
+
+    //----------------------------- JDBC 4.0 -----------------------------------
+// --------------------------- Added: Mustang Build 81 -------------------------
+    boolean poolable = true;
+
+    /**
+     * Requests that a <code>Statement</code> be pooled or not pooled.  The value
+     * specified is a hint to the statement pool implementation indicating
+     * whether the application wants the statement to be pooled.  It is up to
+     * the statement pool manager as to whether the hint is used.
+     * <p>
+     * The poolable value of a statement is applicable to both internal
+     * statement caches implemented by the driver and external statement caches
+     * implemented by application servers and other applications.
+     * <p>
+     * By default, a <code>Statement</code> is not poolable when created, and
+     * a <code>PreparedStatement</code> and <code>CallableStatement</code>
+     * are poolable when created.
+     * <p>
+     * @param poolable          requests that the statement be pooled if true and
+     *                                          that the statement not be pooled if false
+     * <p>
+     * @throws SQLException if this method is called on a closed
+     * <code>Statement</code>
+     * <p>
+     * @since JDK 1.6 Build 81, HSQLDB 2.0
+     */
+    public synchronized void setPoolable(
+            boolean poolable) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        this.poolable = poolable;
+    }
+
+    /**
+     * Returns a  value indicating whether the <code>Statement</code>
+     * is poolable or not.
+     * <p>
+     * @return          <code>true</code> if the <code>Statement</code>
+     * is poolable; <code>false</code> otherwise
+     * @throws SQLException if this method is called on a closed
+     * <code>Statement</code>
+     * <p>
+     * @since JDK 1.6 Build 81, HSQLDB 2.0
+     * <p>
+     * @see #setPoolable(boolean) setPoolable(boolean)
+     */
+    public synchronized boolean isPoolable() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        return this.poolable;
+    }
+
+    // ------------------- java.sql.Wrapper implementation ---------------------
+
+    /**
+     * Returns an object that implements the given interface to allow access to
+     * non-standard methods, or standard methods not exposed by the proxy.
+     *
+     * If the receiver implements the interface then the result is the receiver
+     * or a proxy for the receiver. If the receiver is a wrapper
+     * and the wrapped object implements the interface then the result is the
+     * wrapped object or a proxy for the wrapped object. Otherwise return the
+     * the result of calling <code>unwrap</code> recursively on the wrapped object
+     * or a proxy for that result. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+    public <T>T unwrap(Class<T> iface) throws java.sql.SQLException {
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+    //-------------------- Internal Implementation -----------------------------
+
+    /**
+     * Constructs a statement that produces results of the requested
+     * <code>type</code>. <p>
+     *
+     * A prepared statement must be a single SQL statement. <p>
+     *
+     * @param c the Connection used execute this statement
+     * @param sql the SQL statement this object represents
+     * @param resultSetType the type of result this statement will produce (scrollability)
+     * @param resultSetConcurrency (updatability)
+     * @param resultSetHoldability (validity beyond commit)
+     * @param generatedKeys internal mode of handling generated key reporting
+     * @param generatedIndexes column indexes for generated keys
+     * @param generatedNames column names for generated keys are given
+     * @throws HsqlException if the statement is not accepted by the database
+     * @throws SQLException if preprocessing by driver fails
+     */
+    JDBCPreparedStatement(JDBCConnection c, String sql, int resultSetType,
+                          int resultSetConcurrency, int resultSetHoldability,
+                          int generatedKeys, int[] generatedIndexes,
+                          String[] generatedNames) throws HsqlException,
+                              SQLException {
+
+        isResult   = false;
+        connection = c;
+        connectionIncarnation = connection.incarnation;
+        session    = c.sessionProxy;
+        sql        = c.nativeSQL(sql);
+
+        int[] keyIndexes = null;
+
+        if (generatedIndexes != null) {
+            keyIndexes = new int[generatedIndexes.length];
+
+            for (int i = 0; i < generatedIndexes.length; i++) {
+                keyIndexes[i] = generatedIndexes[i] - 1;
+            }
+        }
+        resultOut = Result.newPrepareStatementRequest();
+
+        int props = ResultProperties.getValueForJDBC(resultSetType,
+            resultSetConcurrency, resultSetHoldability);
+
+        resultOut.setPrepareOrExecuteProperties(sql, 0, 0, 0, queryTimeout,
+                props, generatedKeys, generatedIndexes, generatedNames);
+
+        Result in = session.execute(resultOut);
+
+        if (in.mode == ResultConstants.ERROR) {
+            throw Util.sqlException(in);
+        }
+        rootWarning = null;
+
+        Result current = in;
+
+        while (current.getChainedResult() != null) {
+            current = current.getUnlinkChainedResult();
+
+            if (current.isWarning()) {
+                SQLWarning w = Util.sqlWarning(current);
+
+                if (rootWarning == null) {
+                    rootWarning = w;
+                } else {
+                    rootWarning.setNextWarning(w);
+                }
+            }
+        }
+        connection.setWarnings(rootWarning);
+
+        statementID       = in.getStatementID();
+        statementRetType  = in.getStatementType();
+        resultMetaData    = in.metaData;
+        parameterMetaData = in.parameterMetaData;
+        parameterTypes    = parameterMetaData.getParameterTypes();
+        parameterModes    = parameterMetaData.paramModes;
+        rsProperties      = in.rsProperties;
+
+        //
+        int paramCount = parameterMetaData.getColumnCount();
+
+        parameterValues = new Object[paramCount];
+        parameterSet    = new boolean[paramCount];
+        parameterStream = new boolean[paramCount];
+        streamLengths   = new long[paramCount];
+
+        //
+        //
+        for (int i = 0; i < paramCount; i++) {
+            if (parameterTypes[i].isLobType()) {
+                hasLOBs = true;
+
+                break;
+            }
+        }
+
+        //
+        resultOut = Result.newPreparedExecuteRequest(parameterTypes,
+                statementID);
+
+        resultOut.setStatement(in.getStatement());
+
+        // for toString()
+        this.sql = sql;
+    }
+
+    /**
+     * Constructor for updatable ResultSet
+     */
+    JDBCPreparedStatement(JDBCConnection c, Result result) {
+
+        isResult   = true;
+        connection = c;
+        connectionIncarnation = connection.incarnation;
+        session    = c.sessionProxy;
+
+        int paramCount = result.metaData.getExtendedColumnCount();
+
+        parameterMetaData = result.metaData;
+        parameterTypes    = result.metaData.columnTypes;
+        parameterModes    = new byte[paramCount];
+        parameterValues   = new Object[paramCount];
+        parameterSet      = new boolean[paramCount];
+        parameterStream   = new boolean[paramCount];
+        streamLengths     = new long[paramCount];
+
+        //
+        for (int i = 0; i < paramCount; i++) {
+            parameterModes[i] = SchemaObject.ParameterModes.PARAM_IN;
+
+            if (parameterTypes[i].isLobType()) {
+                hasLOBs = true;
+            }
+        }
+
+        //
+        resultOut = Result.newUpdateResultRequest(parameterTypes,
+                result.getResultId());
+    }
+
+    /**
+     * Checks if execution does or does not generate a single row
+     * update count, throwing if the argument, yes, does not match. <p>
+     *
+     * @param type type of statement regarding what it returns
+     *      something other than a single row update count.
+     * @throws SQLException if the argument, yes, does not match
+     */
+    protected void checkStatementType(int type) throws SQLException {
+
+        if (type != statementRetType) {
+            if (statementRetType == StatementTypes.RETURN_COUNT) {
+                throw Util.sqlException(ErrorCode.X_07503);
+            } else {
+                throw Util.sqlException(ErrorCode.X_07504);
+            }
+        }
+    }
+
+    protected void checkParameterIndex(int i) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (i < 1 || i > parameterValues.length) {
+            String msg = "parameter index out of range: " + i;
+
+            throw Util.outOfRangeArgument(msg);
+        }
+    }
+
+    /**
+     * Checks if the specified parameter index value is valid in terms of
+     * setting an IN or IN OUT parameter value. <p>
+     *
+     * @param i The parameter index to check
+     * @param isStream true if parameter is a stream
+     * @throws SQLException if the specified parameter index is invalid
+     */
+    protected void checkSetParameterIndex(int i,
+            boolean isStream) throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (i < 1 || i > parameterValues.length) {
+            String msg = "parameter index out of range: " + i;
+
+            throw Util.outOfRangeArgument(msg);
+        }
+        i--;
+
+        if (parameterModes[i] == SchemaObject.ParameterModes.PARAM_OUT) {
+            i++;
+
+            String msg = "Not IN or INOUT mode for parameter: " + i;
+
+            throw Util.invalidArgument(msg);
+        }
+
+        if (isStream) {
+            parameterStream[i] = true;
+            parameterSet[i]    = false;
+        } else {
+            parameterStream[i] = false;
+            parameterSet[i]    = true;
+        }
+    }
+
+    /**
+     * Checks if the specified parameter index value is valid in terms of
+     * getting an OUT or INOUT parameter value. <p>
+     *
+     * @param i The parameter index to check
+     * @throws SQLException if the specified parameter index is invalid
+     */
+    protected void checkGetParameterIndex(int i) throws SQLException {
+
+        String msg;
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+
+        if (i < 1 || i > parameterValues.length) {
+            msg = "parameter index out of range: " + i;
+
+            throw Util.outOfRangeArgument(msg);
+        }
+
+        int mode = parameterModes[i - 1];
+
+        switch (mode) {
+
+            case SchemaObject.ParameterModes.PARAM_UNKNOWN :
+            case SchemaObject.ParameterModes.PARAM_OUT :
+            case SchemaObject.ParameterModes.PARAM_INOUT :
+                break;
+            case SchemaObject.ParameterModes.PARAM_IN :
+            default :
+                msg = "Not OUT or INOUT mode: " + mode + " for parameter: "
+                      + i;
+
+                throw Util.invalidArgument(msg);
+        }
+    }
+
+    /**
+     * Called just before execution or adding to batch, this ensures all the
+     * parameters have been set.<p>
+     *
+     * If a parameter has been set using a stream method, it should be set
+     * again for the next reuse. When set using other methods, the parameter
+     * setting is retained for the next use.
+     * @throws SQLException
+     */
+    private void checkParametersSet() throws SQLException {
+
+        if (isResult) {
+            return;
+        }
+
+        for (int i = 0; i < parameterSet.length; i++) {
+            if (parameterModes[i] != SchemaObject.ParameterModes.PARAM_OUT) {
+                if (!parameterSet[i] && !parameterStream[i]) {
+                    throw Util.sqlException(ErrorCode.JDBC_PARAMETER_NOT_SET);
+                }
+            }
+        }
+    }
+
+    /**
+     * The internal parameter value setter always converts the parameter to
+     * the Java type required for data transmission.
+     *
+     * @param i parameter index
+     * @param o object
+     * @throws SQLException if either argument is not acceptable.
+     */
+    void setParameter(int i, Object o) throws SQLException {
+
+        checkSetParameterIndex(i, false);
+
+        i--;
+
+        if (o == null) {
+            parameterValues[i] = null;
+
+            return;
+        }
+
+        Type outType = parameterTypes[i];
+
+        switch (outType.typeCode) {
+
+            case Types.OTHER :
+                try {
+                    if (o instanceof Serializable) {
+                        o = new JavaObjectData((Serializable) o);
+
+                        break;
+                    }
+                } catch (HsqlException e) {
+                    Util.throwError(e);
+                }
+                Util.throwError(Error.error(ErrorCode.X_42563));
+
+                break;
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                try {
+                    if (o instanceof Boolean) {
+                        o = outType.convertToDefaultType(session, o);
+
+                        break;
+                    }
+
+                    if (o instanceof Integer) {
+                        o = outType.convertToDefaultType(session, o);
+
+                        break;
+                    }
+
+                    if (o instanceof byte[]) {
+                        o = outType.convertToDefaultType(session, o);
+
+                        break;
+                    }
+
+                    if (o instanceof String) {
+                        o = outType.convertToDefaultType(session, o);
+
+                        break;
+                    }
+                } catch (HsqlException e) {
+                    Util.throwError(e);
+                }
+                Util.throwError(Error.error(ErrorCode.X_42563));
+
+            // fall through
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+                if (o instanceof byte[]) {
+                    o = new BinaryData((byte[]) o, !connection.isNetConn);
+
+                    break;
+                }
+
+                try {
+                    if (o instanceof String) {
+                        o = outType.convertToDefaultType(session, o);
+
+                        break;
+                    }
+                } catch (HsqlException e) {
+                    Util.throwError(e);
+                }
+                Util.throwError(Error.error(ErrorCode.X_42563));
+
+                break;
+
+            case Types.SQL_ARRAY :
+                if ( o instanceof Array) {
+                    setArray(i + 1, (Array) o);
+
+                    return;
+                }
+                Util.throwError(Error.error(ErrorCode.X_42563));
+
+            case Types.SQL_BLOB :
+                setBlobParameter(i + 1, o);
+
+                return;
+            case Types.SQL_CLOB :
+                setClobParameter(i + 1, o);
+
+                return;
+            case Types.SQL_DATE :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+            case Types.SQL_TIME :
+            case Types.SQL_TIMESTAMP : {
+                try {
+                    if (o instanceof String) {
+                        o = outType.convertToType(session, o,
+                                Type.SQL_VARCHAR);
+
+                        break;
+                    }
+                    o = outType.convertJavaToSQL(session, o);
+
+                    break;
+                } catch (HsqlException e) {
+                    Util.throwError(e);
+                }
+            }
+
+            // fall through
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                try {
+                    if (o instanceof String) {
+                        o = outType.convertToType(session, o,
+                                Type.SQL_VARCHAR);
+
+                        break;
+                    }
+                    o = outType.convertToDefaultType(session, o);
+
+                    break;
+                } catch (HsqlException e) {
+                    Util.throwError(e);
+                }
+
+            // fall through
+            default :
+                try {
+                    o = outType.convertToDefaultType(session, o);
+
+                    break;
+                } catch (HsqlException e) {
+                    Util.throwError(e);
+                }
+        }
+        parameterValues[i] = o;
+    }
+
+    /**
+     * setParameterForClob
+     *
+     * @param i int
+     * @param o Object
+     * @throws SQLException
+     */
+    void setClobParameter(int i, Object o) throws SQLException {
+
+        if (o instanceof JDBCClobClient) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "invalid Clob");
+        } else if (o instanceof Clob) {
+            parameterValues[i - 1] = o;
+            parameterSet[i - 1]    = true;
+
+            return;
+        } else if (o instanceof ClobInputStream) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "invalid Reader");
+        } else if (o instanceof Reader) {
+            parameterValues[i - 1] = o;
+            parameterStream[i - 1] = true;
+
+            return;
+        } else if (o instanceof String) {
+            JDBCClob clob = new JDBCClob((String) o);
+
+            parameterValues[i - 1] = clob;
+            parameterStream[i - 1] = true;
+
+            return;
+        }
+
+        throw Util.invalidArgument();
+    }
+
+    /**
+     * setParameterForBlob
+     *
+     * @param i int
+     * @param o Object
+     */
+    void setBlobParameter(int i, Object o) throws SQLException {
+
+        if (o instanceof JDBCBlobClient) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "invalid Clob");
+        } else if (o instanceof Blob) {
+            parameterValues[i - 1] = o;
+            parameterSet[i - 1]    = true;
+
+            return;
+        } else if (o instanceof BlobInputStream) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "invalid InputStream");
+        } else if (o instanceof InputStream) {
+            parameterValues[i - 1] = o;
+            parameterStream[i - 1] = true;
+
+            return;
+        } else if (o instanceof byte[]) {
+            JDBCBlob blob = new JDBCBlob((byte[]) o);
+
+            parameterValues[i - 1] = blob;
+            parameterSet[i - 1]    = true;
+
+            return;
+        }
+
+        throw Util.invalidArgument();
+    }
+
+    /**
+     * Used with int and narrower integral primitives
+     * @param i parameter index
+     * @param value object to set
+     * @throws SQLException if either argument is not acceptable
+     */
+    void setIntParameter(int i, int value) throws SQLException {
+
+        checkSetParameterIndex(i, false);
+
+        int outType = parameterTypes[i - 1].typeCode;
+
+        switch (outType) {
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER : {
+                Object o = ValuePool.getInt(value);
+
+                parameterValues[i - 1] = o;
+
+                break;
+            }
+            case Types.SQL_BIGINT : {
+                Object o = ValuePool.getLong(value);
+
+                parameterValues[i - 1] = o;
+
+                break;
+            }
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.OTHER :
+                throw Util.sqlException(Error.error(ErrorCode.X_42563));
+            default :
+                setParameter(i, new Integer(value));
+        }
+    }
+
+    /**
+     * Used with long and narrower integral primitives. Conversion to BINARY
+     * or OTHER types will throw here and not passed to setParameter().
+     *
+     * @param i parameter index
+     * @param value object to set
+     * @throws SQLException if either argument is not acceptable
+     */
+    void setLongParameter(int i, long value) throws SQLException {
+
+        checkSetParameterIndex(i, false);
+
+        int outType = parameterTypes[i - 1].typeCode;
+
+        switch (outType) {
+
+            case Types.SQL_BIGINT :
+                Object o = new Long(value);
+
+                parameterValues[i - 1] = o;
+
+                break;
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.OTHER :
+                throw Util.sqlException(Error.error(ErrorCode.X_42563));
+            default :
+                setParameter(i, new Long(value));
+        }
+    }
+
+    private void performPreExecute() throws SQLException, HsqlException {
+
+        if (!hasLOBs) {
+            return;
+        }
+
+        for (int i = 0; i < parameterValues.length; i++) {
+            Object value = parameterValues[i];
+
+            if (value == null) {
+                continue;
+            }
+
+            if (parameterTypes[i].typeCode == Types.SQL_BLOB) {
+                long       id;
+                BlobDataID blob = null;
+
+                if (value instanceof JDBCBlobClient) {
+
+                    // check or fix id mismatch
+                    blob = ((JDBCBlobClient) value).blob;
+                    id   = blob.getId();
+                } else if (value instanceof Blob) {
+                    long length = ((Blob) value).length();
+
+                    blob = session.createBlob(length);
+                    id   = blob.getId();
+
+                    InputStream stream = ((Blob) value).getBinaryStream();
+                    ResultLob resultLob =
+                        ResultLob.newLobCreateBlobRequest(session.getId(), id,
+                            stream, length);
+
+                    session.allocateResultLob(resultLob, null);
+                    resultOut.addLobResult(resultLob);
+                } else if (value instanceof InputStream) {
+                    long length = streamLengths[i];
+
+                    blob = session.createBlob(length);
+                    id   = blob.getId();
+
+                    InputStream stream = (InputStream) value;
+                    ResultLob resultLob =
+                        ResultLob.newLobCreateBlobRequest(session.getId(), id,
+                            stream, length);
+
+                    session.allocateResultLob(resultLob, null);
+                    resultOut.addLobResult(resultLob);
+                }
+                parameterValues[i] = blob;
+            } else if (parameterTypes[i].typeCode == Types.SQL_CLOB) {
+                long       id;
+                ClobDataID clob = null;
+
+                if (value instanceof JDBCClobClient) {
+
+                    // check or fix id mismatch
+                    clob = ((JDBCClobClient) value).clob;
+                    id   = clob.getId();
+                } else if (value instanceof Clob) {
+                    long   length = ((Clob) value).length();
+                    Reader reader = ((Clob) value).getCharacterStream();
+
+                    clob = session.createClob(length);
+                    id   = clob.getId();
+
+                    ResultLob resultLob =
+                        ResultLob.newLobCreateClobRequest(session.getId(), id,
+                            reader, length);
+
+                    session.allocateResultLob(resultLob, null);
+                    resultOut.addLobResult(resultLob);
+                } else if (value instanceof Reader) {
+                    long length = streamLengths[i];
+
+                    clob = session.createClob(length);
+                    id   = clob.getId();
+
+                    Reader reader = (Reader) value;
+                    ResultLob resultLob =
+                        ResultLob.newLobCreateClobRequest(session.getId(), id,
+                            reader, length);
+
+                    session.allocateResultLob(resultLob, null);
+                    resultOut.addLobResult(resultLob);
+                }
+                parameterValues[i] = clob;
+            }
+        }
+    }
+
+    /**
+     * Internal result producer for JDBCStatement (sqlExecDirect mode).
+     * <p>
+     *
+     * @throws SQLException when a database access error occurs
+     */
+    void fetchResult() throws SQLException {
+
+        if (isClosed || connection.isClosed) {
+            checkClosed();
+        }
+        closeResultData();
+        checkParametersSet();
+
+        if (isBatch) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_07505);
+        }
+
+        //
+        if (isResult) {
+            resultOut.setPreparedResultUpdateProperties(parameterValues);
+        } else {
+            resultOut.setPreparedExecuteProperties(parameterValues, maxRows,
+                    fetchSize, rsProperties);
+        }
+
+        try {
+            performPreExecute();
+
+            resultIn = session.execute(resultOut);
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        } finally {
+            performPostExecute();
+        }
+
+        if (resultIn.mode == ResultConstants.ERROR) {
+            throw Util.sqlException(resultIn);
+        }
+    }
+
+    boolean isAnyParameterSet() {
+
+        for (int i = 0; i < parameterValues.length; i++) {
+            if (parameterSet[i]) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * processes chained warnings and any generated columns result set
+     */
+    void performPostExecute() throws SQLException {
+
+        if (this.hasLOBs) {
+            resultOut.clearLobResults();
+        }
+        generatedResult = null;
+
+        if (resultIn == null) {
+            return;
+        }
+        rootWarning = null;
+
+        Result current = resultIn.getUnlinkChainedResult();
+
+        while (current != null) {
+            if (current.getType() == ResultConstants.WARNING) {
+                SQLWarning w = Util.sqlWarning(current);
+
+                if (rootWarning == null) {
+                    rootWarning = w;
+                } else {
+                    rootWarning.setNextWarning(w);
+                }
+            } else if (current.getType() == ResultConstants.ERROR) {
+                errorResult = current;
+            } else if (current.getType() == ResultConstants.DATA) {
+                generatedResult = current;
+            }
+            current = current.getUnlinkChainedResult();
+        }
+
+        if (rootWarning != null) {
+            connection.setWarnings(rootWarning);
+        }
+
+        if (statementRetType == StatementTypes.RETURN_RESULT
+                && resultIn.isData()) {
+            currentResultSet = new JDBCResultSet(connection,
+                    this, resultIn, resultIn.metaData);
+        }
+    }
+
+    /** The parameter values for the next non-batch execution. */
+    protected Object[] parameterValues;
+
+    /** Flags for bound variables. */
+    protected boolean[] parameterSet;
+
+    /** Flags for bound stream variables. */
+    protected boolean[] parameterStream;
+
+    /** The SQL types of the parameters. */
+    protected Type[] parameterTypes;
+
+    /** The (IN, IN OUT, or OUT) modes of parameters */
+    protected byte[] parameterModes;
+
+    /** Lengths for streams. */
+    protected long[] streamLengths;
+
+    /** Has a stream on one or more CLOB / BLOB parameter value. */
+    protected boolean hasStreams;
+
+    /** Has one or more CLOB / BLOB type parameters. */
+    protected boolean hasLOBs;
+
+    /** Is in batch mode. */
+    protected boolean isBatch;
+
+    /** Description of result set metadata. */
+    protected ResultMetaData resultMetaData;
+
+    /** Description of parameter metadata. */
+    protected ResultMetaData parameterMetaData;
+
+    /** This object's one and one ResultSetMetaData object. */
+    protected JDBCResultSetMetaData resultSetMetaData;
+
+    // NOTE:  pmd is declared as Object to avoid yet another #ifdef.
+
+    /** This object's one and only ParameterMetaData object. */
+    protected Object pmd;
+
+    /** The SQL character sequence that this object represents. */
+    protected String sql;
+
+    /** ID of the statement. */
+    protected long statementID;
+
+    /** Statement type - whether it generates a row update count or a result set. */
+    protected int statementRetType;
+
+    /** Is part of a Result. */
+    protected final boolean isResult;
+
+    /** The session attribute of the connection */
+    protected SessionInterface session;
+}
diff --git a/src/org/hsqldb/jdbc/JDBCResultSet.java b/src/org/hsqldb/jdbc/JDBCResultSet.java
new file mode 100644
index 0000000..7c81700
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCResultSet.java
@@ -0,0 +1,7389 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+//#ifdef JAVA6
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLXML;
+
+//#endif JAVA6
+import org.hsqldb.ColumnBase;
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.HsqlException;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.StringInputStream;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/* $Id: JDBCResultSet.java 3596 2010-05-30 13:06:33Z fredt $ */
+
+//boucherb@users 20051207 - patch 1.9.0 - initial JDBC 4.0 support work
+//fredt@users    20060431 - patch 1.9.0 rewrite with RowSetNavigator
+//boucherb@users 20060522 - doc   1.9.0 - full synch up to Mustang Build 84
+// Revision 1.21  2006/07/12 12:27:25  boucherb
+// patch 1.9.0
+// - full synch up to Mustang b90
+
+/**
+ * <!-- start generic documentation -->
+ * A table of data representing a database result set, which
+ * is usually generated by executing a statement that queries the database.
+ *
+ * <P>A <code>ResultSet</code> object  maintains a cursor pointing
+ * to its current row of data.  Initially the cursor is positioned
+ * before the first row. The <code>next</code> method moves the
+ * cursor to the next row, and because it returns <code>false</code>
+ * when there are no more rows in the <code>ResultSet</code> object,
+ * it can be used in a <code>while</code> loop to iterate through
+ * the result set.
+ * <P>
+ * A default <code>ResultSet</code> object is not updatable and
+ * has a cursor that moves forward only.  Thus, you can
+ * iterate through it only once and only from the first row to the
+ * last row. It is possible to
+ * produce <code>ResultSet</code> objects that are scrollable and/or
+ * updatable.  The following code fragment, in which <code>con</code>
+ * is a valid <code>Connection</code> object, illustrates how to make
+ * a result set that is scrollable and insensitive to updates by others, and
+ * that is updatable. See <code>ResultSet</code> fields for other
+ * options.
+ * <PRE>
+ *
+ *       Statement stmt = con.createStatement(
+ *                                      ResultSet.TYPE_SCROLL_INSENSITIVE,
+ *                                      ResultSet.CONCUR_UPDATABLE);
+ *       ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
+ *       // rs will be scrollable, will not show changes made by others,
+ *       // and will be updatable
+ *
+ * </PRE>
+ * The <code>ResultSet</code> interface provides
+ * <i>getter</i> methods (<code>getBoolean</code>, <code>getLong</code>, and so on)
+ * for retrieving column values from the current row.
+ * Values can be retrieved using either the index number of the
+ * column or the name of the column.  In general, using the
+ * column index will be more efficient.  Columns are numbered from 1.
+ * For maximum portability, result set columns within each row should be
+ * read in left-to-right order, and each column should be read only once.
+ *
+ * <P>For the getter methods, a JDBC driver attempts
+ * to convert the underlying data to the Java type specified in the
+ * getter method and returns a suitable Java value.  The JDBC specification
+ * has a table showing the allowable mappings from SQL types to Java types
+ * that can be used by the <code>ResultSet</code> getter methods.
+ * <P>
+ * <P>Column names used as input to getter methods are case
+ * insensitive.  When a getter method is called  with
+ * a column name and several columns have the same name,
+ * the value of the first matching column will be returned.
+ * The column name option is
+ * designed to be used when column names are used in the SQL
+ * query that generated the result set.
+ * For columns that are NOT explicitly named in the query, it
+ * is best to use column numbers. (JDBC4 clarification:) If column names are used, the
+ * programmer should take care to guarantee that they uniquely refer to
+ * the intended columns, which can be assured with the SQL <i>AS</i> clause.
+ * <P>
+ * A set of updater methods were added to this interface
+ * in the JDBC 2.0 API (Java<sup><font size=-2>TM</font></sup> 2 SDK,
+ * Standard Edition, version 1.2). The comments regarding parameters
+ * to the getter methods also apply to parameters to the
+ * updater methods.
+ * <P>
+ * The updater methods may be used in two ways:
+ * <ol>
+ * <li>to update a column value in the current row.  In a scrollable
+ *     <code>ResultSet</code> object, the cursor can be moved backwards
+ *     and forwards, to an absolute position, or to a position
+ *     relative to the current row.
+ *     The following code fragment updates the <code>NAME</code> column
+ *     in the fifth row of the <code>ResultSet</code> object
+ *     <code>rs</code> and then uses the method <code>updateRow</code>
+ *     to update the data source table from which <code>rs</code> was derived.
+ * <PRE>
+ *
+ *       rs.absolute(5); // moves the cursor to the fifth row of rs
+ *       rs.updateString("NAME", "AINSWORTH"); // updates the
+ *          // <code>NAME</code> column of row 5 to be <code>AINSWORTH</code>
+ *       rs.updateRow(); // updates the row in the data source
+ *
+ * </PRE>
+ * </li>
+ * <li>to insert column values into the insert row.  An updatable
+ *     <code>ResultSet</code> object has a special row associated with
+ *     it that serves as a staging area for building a row to be inserted.
+ *     The following code fragment moves the cursor to the insert row, builds
+ *     a three-column row, and inserts it into <code>rs</code> and into
+ *     the data source table using the method <code>insertRow</code>.
+ * <PRE>
+ *
+ *       rs.moveToInsertRow(); // moves cursor to the insert row
+ *       rs.updateString(1, "AINSWORTH"); // updates the
+ *          // first column of the insert row to be <code>AINSWORTH</code>
+ *       rs.updateInt(2,35); // updates the second column to be <code>35</code>
+ *       rs.updateBoolean(3, true); // updates the third column to <code>true</code>
+ *       rs.insertRow();
+ *       rs.moveToCurrentRow();
+ *
+ * </PRE>
+ * </li>
+ * </ol>
+ * <P>A <code>ResultSet</code> object is automatically closed when the
+ * <code>Statement</code> object that
+ * generated it is closed, re-executed, or used
+ * to retrieve the next result from a sequence of multiple results.
+ *
+ * <P>The number, types and properties of a <code>ResultSet</code>
+ * object's columns are provided by the <code>ResulSetMetaData</code>
+ * object returned by the <code>ResultSet.getMetaData</code> method.
+ * <!-- end generic documentation -->
+ *
+ * <!-- start release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * A <code>ResultSet</code> object generated by HSQLDB is by default of
+ * <code>ResultSet.TYPE_FORWARD_ONLY</code> (as is standard JDBC behavior)
+ * and does not allow the use of absolute and relative positioning
+ * methods.  If a statement is created with:<p>
+ *
+ * <pre class="JavaCodeExample">
+ * Statement stmt = conn.<b>createStatement</b>(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+ * </pre>
+ *
+ * then the <code>ResultSet</code> objects it produces support
+ * using all of  the absolute and relative positioning methods of JDBC2
+ * to set the position of the current row, for example:<p>
+ *
+ * <pre class="JavaCodeExample">
+ * rs.<b>absolute</b>(<span class="JavaNumericLiteral">5</span>);
+ * String fifthRowValue = rs.<b>getString</b>(<span class="JavaNumericLiteral">1</span>);
+ * rs.<b>relative</b>(<span class="JavaNumericLiteral">4</span>);
+ * String ninthRowValue = rs.<b>getString</b>(<span class="JavaNumericLiteral">1</span>);
+ * </pre>
+ *
+ * Note: An HSQLDB <code>ResultSet</code> object persists, even after its
+ * connection is closed.  This is regardless of the operational mode of
+ * the {@link org.hsqldb.Database Database} from which it came.  That is, they
+ * persist whether originating from a <code>Server</code>,
+ * <code>WebServer</code> or in-process mode <code>Database.</code>
+ * <p>
+ *
+ * From HSQLDB 2.0, there is full support for updatable result sets.
+ * Supported methods
+ * include all updateXXX methods for the supported types, as well as the
+ * {@link #insertRow},
+ * {@link #updateRow}, {@link #deleteRow}, {@link #moveToInsertRow}
+ * methods.<p>
+ *
+ * The Statement must be created with ResultSet.CONCUR_UPDATABLE instead of
+ * CONCUR_READ_ONLY.<p>
+ *
+ * Updatability of a result set follows the SQL standards. Some or all columns
+ * of an updatable result set can be updated. The current row in such result sets
+ * can be deleted using the {@link #deleteRow} method. Some updatable result set
+ * can also be inserted into and support {@link #moveToInsertRow}.<p>
+ *
+ * A result set is updatable if the SELECT statement
+ * is updatable. This includes SELECT from TABLE and updatable VIEW objects.
+ * An updatable SELECT statement has a single uderlying table or view.
+ * HSQLDB supports both scrollable and forward-only result sets for updatability.
+ *
+ * <pre class="JavaCodeExample">
+ * -- In the SELECT below, columns A and B are updatable, any row can be
+ * -- deleted, but it is not insertable-into as column C is not directly from
+ * -- the table.
+ * SELECT A, B, A + B AS C FROM T WHERE ...
+ *
+ * -- The SELECT below can be insertable-into so long as other columns of the
+ * -- table that do not appear in the SELECT list have a default value.
+ * SELECT A, B FROM T WHERE ...
+ * </pre>
+ *
+ * <b>JRE 1.1.x Notes:</b> <p>
+ *
+ * In general, JDBC 2 support requires Java 1.2 and above, and JDBC 3 requires
+ * Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ * versions of JDBC depends on the JDK version used for compiling and building
+ * HSQLDB.<p>
+ *
+ * Since 1.7.0, it is possible to build the product so that
+ * all JDBC 2 methods can be called while executing under the version 1.1.x
+ * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ * However, some of these method calls require <code>int</code> values that
+ * are defined only in the JDBC 2 or greater version of the
+ * {@link java.sql.ResultSet ResultSet} interface.  For this reason, when the
+ * product is compiled under JDK 1.1.x, these values are defined here, in this
+ * class. <p>
+ *
+ * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ * JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ * to them in parameter specifications and return value comparisons,
+ * respectively, as follows: <p>
+ *
+ * <pre class="JavaCodeExample">
+ * JDBCResultSet.FETCH_FORWARD
+ * JDBCResultSet.TYPE_FORWARD_ONLY
+ * JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ * JDBCResultSet.CONCUR_READ_ONLY
+ * // etc.
+ * </pre>
+ *
+ * However, please note that code written in such a manner will not be
+ * compatible for use with other JDBC 2 drivers, since they expect and use
+ * <code>ResultSet</code>, rather than <code>JDBCResultSet</code>.  Also
+ * note, this feature is offered solely as a convenience to developers
+ * who must work under JDK 1.1.x due to operating constraints, yet wish to
+ * use some of the more advanced features available under the JDBC 2
+ * specification.<p>
+ *
+ * (fredt@users) <br>
+ * (boucherb@users)<p>
+ *
+ * </div>
+ * @see JDBCStatement#executeQuery
+ * @see JDBCStatement#getResultSet
+ * @see java.sql.ResultSetMetaData
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @since 1.9.0
+ */
+public class JDBCResultSet implements ResultSet {
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor froward one row from its current position.
+     * A <code>ResultSet</code> cursor is initially positioned
+     * before the first row; the first call to the method
+     * <code>next</code> makes the first row the current row; the
+     * second call makes the second row the current row, and so on.
+     * <p>(JDBC4 clarification:)
+     * When a call to the <code>next</code> method returns <code>false</code>,
+     * the cursor is positioned after the last row. Any
+     * invocation of a <code>ResultSet</code> method which requires a
+     * current row will result in a <code>SQLException</code> being thrown.
+     *  If the result set type is <code>TYPE_FORWARD_ONLY</code>, it is vendor specified
+     * whether their JDBC driver implementation will return <code>false</code> or
+     *  throw an <code>SQLException</code> on a
+     * subsequent call to <code>next</code>.
+     *
+     * <P>If an input stream is open for the current row, a call
+     * to the method <code>next</code> will
+     * implicitly close it. A <code>ResultSet</code> object's
+     * warning chain is cleared when a new row is read.
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the new current row is valid;
+     * <code>false</code> if there are no more rows
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public boolean next() throws SQLException {
+
+        checkClosed();
+
+        rootWarning = null;
+
+        return navigator.next();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Releases this <code>ResultSet</code> object's database and
+     * JDBC resources immediately instead of waiting for
+     * this to happen when it is automatically closed.
+     *
+     * <P>(JDBC4 clarification:)
+     * The closing of a <code>ResultSet</code> object does <strong>not</strong> close the <code>Blob</code>,
+     * <code>Clob</code> or <code>NClob</code> objects created by the <code>ResultSet</code>. <code>Blob</code>,
+     * <code>Clob</code> or <code>NClob</code> objects remain valid for at least the duration of the
+     * transaction in which they are created, unless their <code>free</code> method is invoked.
+     * <p>
+     * (JDBC4 clarification:)
+     * When a <code>ResultSet</code> is closed, any <code>ResultSetMetaData</code>
+     * instances that were created by calling the  <code>getMetaData</code>
+     * method remain accessible.
+     *
+     * <P><B>Note:</B> A <code>ResultSet</code> object
+     * is automatically closed by the
+     * <code>Statement</code> object that generated it when
+     * that <code>Statement</code> object is closed,
+     * re-executed, or is used to retrieve the next result from a
+     * sequence of multiple results.
+     * (JDBC4 deleted:) [A <code>ResultSet</code> object is also automatically
+     * closed when it is garbage collected.]
+     * <p>
+     * Calling the method <code>close</code> on a <code>ResultSet</code>
+     * object that is already closed is a no-op.
+     * <P>
+     * <p>
+     * <!-- end generic documentation -->
+     *
+     * @exception SQLException if a database access error occurs
+     */
+    public void close() throws SQLException {
+
+        if (navigator == null) {
+            return;
+        }
+        navigator.close();
+
+        navigator = null;
+
+        if (autoClose && statement != null) {
+            statement.close();
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Reports whether
+     * the last column read had a value of SQL <code>NULL</code>.
+     * Note that you must first call one of the getter methods
+     * on a column to try to read its value and then call
+     * the method <code>wasNull</code> to see if the value read was
+     * SQL <code>NULL</code>.
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the last column value read was SQL
+     *         <code>NULL</code> and <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public boolean wasNull() throws SQLException {
+
+        checkClosed();
+
+        return wasNullValue;
+    }
+
+    //======================================================================
+    // Methods for accessing results by column index
+    //======================================================================
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>String</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public String getString(int columnIndex) throws SQLException {
+        return (String) getColumnInType(columnIndex, Type.SQL_VARCHAR);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>boolean</code> in the Java programming language.
+     *
+     *
+     * <P>(JDBC4 clarification:)
+     * <P>If the designated column has a datatype of CHAR or VARCHAR
+     * and contains a "0" or has a datatype of BIT, TINYINT, SMALLINT, INTEGER or BIGINT
+     * and contains  a 0, a value of <code>false</code> is returned.  If the designated column has a datatype
+     * of CHAR or VARCHAR
+     * and contains a "1" or has a datatype of BIT, TINYINT, SMALLINT, INTEGER or BIGINT
+     * and contains  a 1, a value of <code>true</code> is returned.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>false</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public boolean getBoolean(int columnIndex) throws SQLException {
+
+        Object o = getColumnInType(columnIndex, Type.SQL_BOOLEAN);
+
+        return o == null ? false
+                         : ((Boolean) o).booleanValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>byte</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the numeric value to the return type. If the value is
+     * out of the range for the return type, an error is returned. For example,
+     * this can happen if getByte() or getShort() is used to retrieve a value
+     * of type INTEGER or BIGINT and the value is beyond the range covered by
+     * the return type.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public byte getByte(int columnIndex) throws SQLException {
+
+        Object o = getColumnInType(columnIndex, Type.TINYINT);
+
+        return o == null ? 0
+                         : ((Number) o).byteValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>short</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the numeric value to the return type. If the value is
+     * out of the range for the return type, an error is returned. For example,
+     * this can happen if getByte() or getShort() is used to retrieve a value
+     * of type INTEGER or BIGINT and the value is beyond the range covered by
+     * the return type.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public short getShort(int columnIndex) throws SQLException {
+
+        Object o = getColumnInType(columnIndex, Type.SQL_SMALLINT);
+
+        return o == null ? 0
+                         : ((Number) o).shortValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * an <code>int</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the numeric value to the return type. If the value is
+     * out of the range for the return type, an error is returned. For example,
+     * this can happen if getInt() or getLong() is used to retrieve a value
+     * of type DECIMAL or NUMERIC with a large precision and the value is beyond
+     * the range covered by the return type.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public int getInt(int columnIndex) throws SQLException {
+
+        Object o = getColumnInType(columnIndex, Type.SQL_INTEGER);
+
+        return o == null ? 0
+                         : ((Number) o).intValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>long</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the numeric value to the return type. If the value is
+     * out of the range for the return type, an error is returned. For example,
+     * this can happen if getInt() or getLong() is used to retrieve a value
+     * of type DECIMAL or NUMERIC with a large precision and the value is beyond
+     * the range covered by the return type.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public long getLong(int columnIndex) throws SQLException {
+
+        Object o = getColumnInType(columnIndex, Type.SQL_BIGINT);
+
+        return o == null ? 0
+                         : ((Number) o).longValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>float</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the numeric value to the return type. If the value is
+     * out of the range for the return type, an error is returned. For example,
+     * this can happen if getFloat() or getDouble() is used to retrieve a value
+     * of type DECIMAL or NUMERIC with a large precision and the value is beyond
+     * the range covered by the return type.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public float getFloat(int columnIndex) throws SQLException {
+
+        Object o = getColumnInType(columnIndex, Type.SQL_DOUBLE);
+
+        return o == null ? (float) 0.0
+                         : ((Number) o).floatValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>double</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the numeric value to the return type. If the value is
+     * out of the range for the return type, an error is returned. For example,
+     * this can happen if getFloat() or getDouble() is used to retrieve a value
+     * of type DECIMAL or NUMERIC with a large precision and the value is beyond
+     * the range covered by the return type.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public double getDouble(int columnIndex) throws SQLException {
+
+        Object o = getColumnInType(columnIndex, Type.SQL_DOUBLE);
+
+        return o == null ? 0.0
+                         : ((Number) o).doubleValue();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>java.sql.BigDecimal</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the result and sets the scale
+     * with BigDecimal.ROUND_HALF_DOWN.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param scale the number of digits to the right of the decimal point
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @deprecated
+     *            by java.sun.com as of JDK 1.2
+     */
+
+//#ifdef DEPRECATEDJDBC
+    public BigDecimal getBigDecimal(int columnIndex,
+                                    int scale) throws SQLException {
+
+        if (scale < 0) {
+            throw Util.outOfRangeArgument();
+        }
+
+        BigDecimal bd = getBigDecimal(columnIndex);
+
+        if (bd != null) {
+            bd = bd.setScale(scale, BigDecimal.ROUND_DOWN);
+        }
+
+        return bd;
+    }
+
+//#endif
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>byte</code> array in the Java programming language.
+     * The bytes represent the raw values returned by the driver.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB returns correct values for columns of binary types
+     * <code>BINARY</code>, <code>BIT</code>,  <code>BLOB</code>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public byte[] getBytes(int columnIndex) throws SQLException {
+
+        Object x = getColumnInType(columnIndex, Type.SQL_VARBINARY);
+
+        if (x == null) {
+            return null;
+        }
+
+        return ((BinaryData) x).getBytes();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>java.sql.Date</code> object in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public Date getDate(int columnIndex) throws SQLException {
+
+        TimestampData t = (TimestampData) getColumnInType(columnIndex,
+            Type.SQL_DATE);
+
+        if (t == null) {
+            return null;
+        }
+
+        return (Date) Type.SQL_DATE.convertSQLToJava(session, t);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>java.sql.Time</code> object in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public Time getTime(int columnIndex) throws SQLException {
+
+        TimeData t = (TimeData) getColumnInType(columnIndex, Type.SQL_TIME);
+
+        if (t == null) {
+            return null;
+        }
+
+        return (Time) Type.SQL_TIME.convertSQLToJava(session, t);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>java.sql.Timestamp</code> object in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public Timestamp getTimestamp(int columnIndex) throws SQLException {
+
+        TimestampData t = (TimestampData) getColumnInType(columnIndex,
+            Type.SQL_TIMESTAMP);
+
+        if (t == null) {
+            return null;
+        }
+
+        return (Timestamp) Type.SQL_TIMESTAMP.convertSQLToJava(session, t);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a stream of ASCII characters. The value can then be read in chunks from the
+     * stream. This method is particularly
+     * suitable for retrieving large <char>LONGVARCHAR</char> values.
+     * The JDBC driver will
+     * do any necessary conversion from the database format into ASCII.
+     *
+     * <P><B>Note:</B> All the data in the returned stream must be
+     * read prior to getting the value of any other column. The next
+     * call to a getter method implicitly closes the stream.  Also, a
+     * stream may return <code>0</code> when the method
+     * <code>InputStream.available</code>
+     * is called whether there is data available or not.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The limitation noted above does not apply to HSQLDB.<p>
+     *
+     * When the column is of type CHAR and its variations, it requires no
+     * conversion since it is represented internally already as a
+     * Java String object. When the column is not of type CHAR and its
+     * variations, the returned stream is based on a conversion to the
+     * Java <code>String</code> representation of the value. In either case,
+     * the obtained stream is always equivalent to a stream of the low order
+     * bytes from the value's String representation. <p>
+     *
+     * HSQLDB SQL <code>CHAR</code> and its variations are all Unicode strings
+     * internally, so the recommended alternatives to this method are
+     * {@link #getString(int) getString},
+     * {@link #getUnicodeStream(int) getUnicodeStream} (<b>deprecated</b>)
+     * and new to 1.7.0: {@link #getCharacterStream(int) getCharacterStream}
+     * (now prefered over the deprecated getUnicodeStream alternative).
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a Java input stream that delivers the database column value
+     * as a stream of one-byte ASCII characters;
+     * if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public java.io.InputStream getAsciiStream(
+            int columnIndex) throws SQLException {
+
+        String s = getString(columnIndex);
+
+        if (s == null) {
+            return null;
+        }
+
+        try {
+            return new ByteArrayInputStream(s.getBytes("US-ASCII"));
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * as a stream of two-byte Unicode characters. The first byte is
+     * the high byte; the second byte is the low byte.
+     *
+     * The value can then be read in chunks from the
+     * stream. This method is particularly
+     * suitable for retrieving large <code>LONGVARCHAR</code>values.  The
+     * JDBC driver will do any necessary conversion from the database
+     * format into Unicode.
+     *
+     * <P><B>Note:</B> All the data in the returned stream must be
+     * read prior to getting the value of any other column. The next
+     * call to a getter method implicitly closes the stream.
+     * Also, a stream may return <code>0</code> when the method
+     * <code>InputStream.available</code>
+     * is called, whether there is data available or not.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The limitation noted above does not apply to HSQLDB.<p>
+     *
+     * When the column is of type CHAR and its variations, it requires no
+     * conversion since it is represented internally already as
+     * Java Strings. When the column is not of type CHAR and its variations,
+     * the returned stream is based on a conversion to the
+     * Java <code>String</code> representation of the value. In either case,
+     * the obtained stream is always equivalent to a stream of
+     * bytes from the value's String representation, with high-byte first.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a Java input stream that delivers the database column value
+     *         as a stream of two-byte Unicode characters;
+     *         if the value is SQL <code>NULL</code>, the value returned is
+     *         <code>null</code>
+     *
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @deprecated use <code>getCharacterStream</code> in place of
+     *              <code>getUnicodeStream</code>
+     */
+
+//#ifdef DEPRECATEDJDBC
+    public java.io.InputStream getUnicodeStream(
+            int columnIndex) throws SQLException {
+
+        String s = getString(columnIndex);
+
+        if (s == null) {
+            return null;
+        }
+
+        return new StringInputStream(s);
+    }
+
+//#endif
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a  stream of
+     * uninterpreted bytes. The value can then be read in chunks from the
+     * stream. This method is particularly
+     * suitable for retrieving large <code>LONGVARBINARY</code> values.
+     *
+     * <P><B>Note:</B> All the data in the returned stream must be
+     * read prior to getting the value of any other column. The next
+     * call to a getter method implicitly closes the stream.  Also, a
+     * stream may return <code>0</code> when the method
+     * <code>InputStream.available</code>
+     * is called whether there is data available or not.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a Java input stream that delivers the database column value
+     *         as a stream of uninterpreted bytes;
+     *         if the value is SQL <code>NULL</code>, the value returned is
+     *         <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public java.io.InputStream getBinaryStream(
+            int columnIndex) throws SQLException {
+
+        checkColumn(columnIndex);
+
+        Type   sourceType = resultMetaData.columnTypes[columnIndex - 1];
+        Object o          = getColumnInType(columnIndex, sourceType);
+
+        if (o == null) {
+            return null;
+        }
+
+        if (o instanceof BlobDataID) {
+            return ((BlobDataID) o).getBinaryStream(session);
+        } else if (o instanceof Blob) {
+            return ((Blob) o).getBinaryStream();
+        } else if (o instanceof BinaryData) {
+            byte[] b = getBytes(columnIndex);
+
+            return new ByteArrayInputStream(b);
+        }
+
+        throw Util.sqlException(ErrorCode.X_42561);
+    }
+
+    //======================================================================
+    // Methods for accessing results by column label
+    //======================================================================
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>String</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public String getString(String columnLabel) throws SQLException {
+        return getString(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>boolean</code> in the Java programming language.
+     *
+     * <P>(JDBC4 clarification:) If the designated column has a datatype of CHAR or VARCHAR
+     * and contains a "0" or has a datatype of BIT, TINYINT, SMALLINT, INTEGER or BIGINT
+     * and contains  a 0, a value of <code>false</code> is returned.  If the designated column has a datatype
+     * of CHAR or VARCHAR
+     * and contains a "1" or has a datatype of BIT, TINYINT, SMALLINT, INTEGER or BIGINT
+     * and contains  a 1, a value of <code>true</code> is returned.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>false</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public boolean getBoolean(String columnLabel) throws SQLException {
+        return getBoolean(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>byte</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public byte getByte(String columnLabel) throws SQLException {
+        return getByte(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>short</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public short getShort(String columnLabel) throws SQLException {
+        return getShort(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * an <code>int</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public int getInt(String columnLabel) throws SQLException {
+        return getInt(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>long</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public long getLong(String columnLabel) throws SQLException {
+        return getLong(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>float</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public float getFloat(String columnLabel) throws SQLException {
+        return getFloat(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>double</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>0</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public double getDouble(String columnLabel) throws SQLException {
+        return getDouble(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>java.math.BigDecimal</code> in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB converts the result and sets the scale
+     * with BigDecimal.ROUND_HALF_DOWN.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param scale the number of digits to the right of the decimal point
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @deprecated
+     *            by java.sun.com as of JDK 1.2
+     */
+
+//#ifdef DEPRECATEDJDBC
+    public BigDecimal getBigDecimal(String columnLabel,
+                                    int scale) throws SQLException {
+        return getBigDecimal(findColumn(columnLabel), scale);
+    }
+
+//#endif
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>byte</code> array in the Java programming language.
+     * The bytes represent the raw values returned by the driver.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public byte[] getBytes(String columnLabel) throws SQLException {
+        return getBytes(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>java.sql.Date</code> object in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public Date getDate(String columnLabel) throws SQLException {
+        return getDate(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>java.sql.Time</code> object in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public Time getTime(String columnLabel) throws SQLException {
+        return getTime(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>java.sql.Timestamp</code> object in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public Timestamp getTimestamp(String columnLabel) throws SQLException {
+        return getTimestamp(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a stream of
+     * ASCII characters. The value can then be read in chunks from the
+     * stream. This method is particularly
+     * suitable for retrieving large <code>LONGVARCHAR</code> values.
+     * The JDBC driver will
+     * do any necessary conversion from the database format into ASCII.
+     *
+     * <P><B>Note:</B> All the data in the returned stream must be
+     * read prior to getting the value of any other column. The next
+     * call to a getter method implicitly closes the stream. Also, a
+     * stream may return <code>0</code> when the method <code>available</code>
+     * is called whether there is data available or not.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return a Java input stream that delivers the database column value
+     * as a stream of one-byte ASCII characters.
+     * If the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code>.
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @see #getAsciiStream(int)
+     */
+    public java.io.InputStream getAsciiStream(
+            String columnLabel) throws SQLException {
+        return getAsciiStream(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a stream of two-byte
+     * Unicode characters. The first byte is the high byte; the second
+     * byte is the low byte.
+     *
+     * The value can then be read in chunks from the
+     * stream. This method is particularly
+     * suitable for retrieving large <code>LONGVARCHAR</code> values.
+     * The JDBC technology-enabled driver will
+     * do any necessary conversion from the database format into Unicode.
+     *
+     * <P><B>Note:</B> All the data in the returned stream must be
+     * read prior to getting the value of any other column. The next
+     * call to a getter method implicitly closes the stream.
+     * Also, a stream may return <code>0</code> when the method
+     * <code>InputStream.available</code> is called, whether there
+     * is data available or not.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return a Java input stream that delivers the database column value
+     *         as a stream of two-byte Unicode characters.
+     *         If the value is SQL <code>NULL</code>, the value returned
+     *         is <code>null</code>.
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @deprecated use <code>getCharacterStream</code> instead
+     * @see #getUnicodeStream(int)
+     */
+
+//#ifdef DEPRECATEDJDBC
+    public java.io.InputStream getUnicodeStream(
+            String columnLabel) throws SQLException {
+        return getUnicodeStream(findColumn(columnLabel));
+    }
+
+//#endif
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a stream of uninterpreted
+     * <code>byte</code>s.
+     * The value can then be read in chunks from the
+     * stream. This method is particularly
+     * suitable for retrieving large <code>LONGVARBINARY</code>
+     * values.
+     *
+     * <P><B>Note:</B> All the data in the returned stream must be
+     * read prior to getting the value of any other column. The next
+     * call to a getter method implicitly closes the stream. Also, a
+     * stream may return <code>0</code> when the method <code>available</code>
+     * is called whether there is data available or not.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return a Java input stream that delivers the database column value
+     * as a stream of uninterpreted bytes;
+     * if the value is SQL <code>NULL</code>, the result is <code>null</code>
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public java.io.InputStream getBinaryStream(
+            String columnLabel) throws SQLException {
+        return getBinaryStream(findColumn(columnLabel));
+    }
+
+    //=====================================================================
+    // Advanced features:
+    //=====================================================================
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the first warning reported by calls on this
+     * <code>ResultSet</code> object.
+     * Subsequent warnings on this <code>ResultSet</code> object
+     * will be chained to the <code>SQLWarning</code> object that
+     * this method returns.
+     *
+     * <P>The warning chain is automatically cleared each time a new
+     * row is read.  This method may not be called on a <code>ResultSet</code>
+     * object that has been closed; doing so will cause an
+     * <code>SQLException</code> to be thrown.
+     * <P>
+     * <B>Note:</B> This warning chain only covers warnings caused
+     * by <code>ResultSet</code> methods.  Any warning caused by
+     * <code>Statement</code> methods
+     * (such as reading OUT parameters) will be chained on the
+     * <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not produce <code>SQLWarning</code>
+     * objects on any ResultSet object warning chain; this
+     * method always returns <code>null</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the first <code>SQLWarning</code> object reported or
+     *         <code>null</code> if there are none
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public SQLWarning getWarnings() throws SQLException {
+
+        checkClosed();
+
+        return rootWarning;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Clears all warnings reported on this <code>ResultSet</code> object.
+     * After this method is called, the method <code>getWarnings</code>
+     * returns <code>null</code> until a new warning is
+     * reported for this <code>ResultSet</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not produce <code>SQLWarning</code>
+     * objects on any ResultSet object warning chain; calls to this method
+     * are ignored.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public void clearWarnings() throws SQLException {
+
+        checkClosed();
+
+        rootWarning = null;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the name of the SQL cursor used by this <code>ResultSet</code>
+     * object.
+     *
+     * <P>In SQL, a result table is retrieved through a cursor that is
+     * named. The current row of a result set can be updated or deleted
+     * using a positioned update/delete statement that references the
+     * cursor name. To insure that the cursor has the proper isolation
+     * level to support update, the cursor's <code>SELECT</code> statement
+     * should be of the form <code>SELECT FOR UPDATE</code>. If
+     * <code>FOR UPDATE</code> is omitted, the positioned updates may fail.
+     *
+     * <P>The JDBC API supports this SQL feature by providing the name of the
+     * SQL cursor used by a <code>ResultSet</code> object.
+     * The current row of a <code>ResultSet</code> object
+     * is also the current row of this SQL cursor.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature when the cursor has a name.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the SQL name for this <code>ResultSet</code> object's cursor
+     * @exception SQLException if a database access error occurs or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     */
+    public String getCursorName() throws SQLException {
+
+        checkClosed();
+
+        if (result == null) {
+            return "";
+        }
+
+        return result.getMainString();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the  number, types and properties of
+     * this <code>ResultSet</code> object's columns.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * <B>Example:</B> <p>
+     *
+     * The following code fragment creates a <code>ResultSet</code> object rs,
+     * creates a <code>ResultSetMetaData</code> object rsmd, and uses rsmd
+     * to find out how many columns rs has and whether the first column
+     * in rs can be used in a <code>WHERE</code> clause. <p>
+     *
+     * <pre class="JavaCodeExample">
+     * ResultSet rs   = stmt.<b>executeQuery</b>(<span class="JavaStringLiteral">"SELECT a, b, c FROM TABLE2"</span>);
+     * ResultSetMetaData rsmd = rs.<b>getMetaData</b>();<br>
+     * int numberOfColumns = rsmd.<b>getColumnCount</b>();<br>
+     * boolean b = rsmd.<b>isSearchable</b>(1);<br>
+     * </pre>
+     *
+     * <hr>
+     *
+     * <B>Changes:</B> <p>
+     *
+     * With version 2.0, the engine's SQL implementation has been
+     * completely rewritten. Changes to this class and the implementation of
+     * ResultSetMetaData reflect the engine's new capabilities and provide
+     * more accurate information. <p>
+     *
+     * changes to consider: <p>
+     *
+     * <ol>
+     * <li>isAutoIncrement(int) <i>always</i> returned <code>false</code></li>
+     * <li>isNullable(int) returns the nullability of a real table or view
+     *     column in the ResultSet and returns
+     *     <code>columnNoNulls</code> for non-base-column ResultSet columns
+     *     (columns of the ResultSet that are based on expressions or
+     *     aggregates).</li>
+     * <li>getColumnDisplaySize(int) returns correct results even for expression
+     *     columns.</li>
+     * <li>getPrecision(int) returns the correct precision even for expression
+     *     columns.</li>
+     * <li>getScale(int) returns the correct precision even for expression
+     *     columns.</li>
+     * <li>getCatalogName(int) returns the catalog name of the database.</li>
+     * </ol> <p>
+     *
+     * <hr>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the description of this <code>ResultSet</code> object's columns
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @see JDBCResultSetMetaData
+     */
+    public ResultSetMetaData getMetaData() throws SQLException {
+
+        checkClosed();
+
+        if (resultSetMetaData == null) {
+            resultSetMetaData = new JDBCResultSetMetaData(resultMetaData,
+                    isUpdatable, isInsertable, connection);
+        }
+
+        return resultSetMetaData;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * <p>Gets the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * an <code>Object</code> in the Java programming language.
+     *
+     * <p>This method will return the value of the given column as a
+     * Java object.  The type of the Java object will be the default
+     * Java object type corresponding to the column's SQL type,
+     * following the mapping for built-in types specified in the JDBC
+     * specification. If the value is an SQL <code>NULL</code>,
+     * the driver returns a Java <code>null</code>.
+     *
+     * <p>This method may also be used to read database-specific
+     * abstract data types.
+     *
+     * In the JDBC 2.0 API, the behavior of method
+     * <code>getObject</code> is extended to materialize
+     * data of SQL user-defined types.
+     * <p>
+     * If <code>Connection.getTypeMap</code> does not throw a
+     * <code>SQLFeatureNotSupportedException</code>,
+     * then when a column contains a structured or distinct value,
+     * the behavior of this method is as
+     * if it were a call to: <code>getObject(columnIndex,
+     * this.getStatement().getConnection().getTypeMap())</code>.
+     *
+     * If <code>Connection.getTypeMap</code> does throw a
+     * <code>SQLFeatureNotSupportedException</code>,
+     * then structured values are not supported, and distinct values
+     * are mapped to the default Java class as determined by the
+     * underlying SQL type of the DISTINCT type.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a <code>java.lang.Object</code> holding the column value
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public Object getObject(int columnIndex) throws SQLException {
+
+        checkColumn(columnIndex);
+
+        Type sourceType = resultMetaData.columnTypes[columnIndex - 1];
+
+        switch (sourceType.typeCode) {
+
+            case Types.SQL_DATE :
+                return getDate(columnIndex);
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                return getTime(columnIndex);
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return getTimestamp(columnIndex);
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+                return getBytes(columnIndex);
+            case Types.SQL_BIT : {
+                boolean b = getBoolean(columnIndex);
+
+                return wasNull() ? null
+                                 : b ? Boolean.TRUE
+                                     : Boolean.FALSE;
+            }
+            case Types.OTHER :
+            case Types.JAVA_OBJECT : {
+                Object o = getColumnInType(columnIndex, sourceType);
+
+                if (o == null) {
+                    return null;
+                }
+
+                try {
+                    return ((JavaObjectData) o).getObject();
+                } catch (HsqlException e) {
+                    throw Util.sqlException(e);
+                }
+            }
+            default :
+                return getColumnInType(columnIndex, sourceType);
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * <p>Gets the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * an <code>Object</code> in the Java programming language.
+     *
+     * <p>This method will return the value of the given column as a
+     * Java object.  The type of the Java object will be the default
+     * Java object type corresponding to the column's SQL type,
+     * following the mapping for built-in types specified in the JDBC
+     * specification. If the value is an SQL <code>NULL</code>,
+     * the driver returns a Java <code>null</code>.
+     * <P>
+     * This method may also be used to read database-specific
+     * abstract data types.
+     * <P>
+     * In the JDBC 2.0 API, the behavior of the method
+     * <code>getObject</code> is extended to materialize
+     * data of SQL user-defined types.  When a column contains
+     * a structured or distinct value, the behavior of this method is as
+     * if it were a call to: <code>getObject(columnIndex,
+     * this.getStatement().getConnection().getTypeMap())</code>.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return a <code>java.lang.Object</code> holding the column value
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     */
+    public Object getObject(String columnLabel) throws SQLException {
+        return getObject(findColumn(columnLabel));
+    }
+
+    //----------------------------------------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Maps the given <code>ResultSet</code> column label to its
+     * <code>ResultSet</code> column index.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.9.x, HSQLDB does an exhaustive search, backed by
+     * a cache lookup (to improve performance for subsequent invocations with
+     * a given input). <p>
+     *
+     * This is in response to an observation posted here: <p>
+     *
+     * http://sourceforge.net/forum/forum.php?thread_id=1388727&forum_id=73674<p>
+     *
+     * Upon careful investigation of the JDBC specification and the behaviour
+     * of existing JDBC drivers, there is actually nothing preventing the
+     * findColumn method from doing an exhaustive search, as long as it conforms
+     * to the following rules (which describe the new implementation): <p>
+     *
+     * <ol>
+     * <li> the entire search is case insensitive
+     * <li> each search iteration occurs from leftmost to rightmost column,
+     *      returning the first match encountered
+     * <li> the first pass matches only bare column labels
+     * <li> the second pass matches only simple column names
+     * <li> further passes conform to the identifier qualification
+     *      and identifier quoting rules of the engine
+     * </ol>
+     *
+     * In this implementation, the SQL tokenizer is not employed, both because
+     * it does not yet correctly handle greater than two part qualification
+     * and also because is is not immediately considered important to do a
+     * truly exhaustive search, handling the full range of possibly mixed quoted
+     * and unquoted identifier components. <p>
+     *
+     * Instead: <p>
+     * <ul>
+     * <li> a third pass matches simple table-dot-column qualified names
+     * <li> a fourth pass matches simple schema-dot-table-dot-column qualified column names
+     * </ul>
+     * </div>
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column index of the given column name
+     * @exception SQLException if the <code>ResultSet</code> object
+     * does not contain a column labeled <code>columnLabel</code>, a database access error occurs
+     *  or this method is called on a closed result set
+     */
+    public int findColumn(final String columnLabel) throws SQLException {
+
+        checkClosed();
+
+        if (columnLabel == null) {
+            throw Util.nullArgument();
+        }
+
+        int columnIndex;
+
+        // faster lookup for subsequent access
+        if (columnMap != null) {
+            columnIndex = columnMap.get(columnLabel, -1);
+
+            if (columnIndex != -1) {
+                return columnIndex;
+            }
+        }
+
+        final String[] colLabels = resultMetaData.columnLabels;
+
+        columnIndex = -1;
+
+        // column labels first, to preference column aliases
+        for (int i = 0; i < columnCount; i++) {
+            if (columnLabel.equalsIgnoreCase(colLabels[i])) {
+                columnIndex = i;
+
+                break;
+            }
+        }
+
+        final ColumnBase[] columns = resultMetaData.columns;
+
+        // then bare column names, to preference simple
+        // quoted column idents that *may* contain "."
+        if (columnIndex < 0) {
+            for (int i = 0; i < columnCount; i++) {
+                if (columnLabel.equalsIgnoreCase(columns[i].getNameString())) {
+                    columnIndex = i;
+
+                    break;
+                }
+            }
+        }
+
+        // then table-qualified column names (again, quoted
+        // table idents *may* contain "."
+        // As a last resort, "fully" qualified column names
+        // (we don't yet bother with catalog qualification)
+        if (columnIndex < 0) {
+            int position = columnLabel.indexOf('.');
+
+            if (position < 0) {
+                throw Util.sqlException(ErrorCode.JDBC_COLUMN_NOT_FOUND,
+                                        columnLabel);
+            }
+
+            for (int i = 0; i < columnCount; i++) {
+                final String tabName = columns[i].getTableNameString();
+
+                if (tabName == null || tabName.length() == 0) {
+                    continue;
+                }
+
+                final String colName = columns[i].getNameString();
+
+                if (columnLabel.equalsIgnoreCase(tabName + '.' + colName)) {
+                    columnIndex = i;
+
+                    break;
+                }
+
+                final String schemName = columns[i].getSchemaNameString();
+
+                if (schemName == null || schemName.length() == 0) {
+                    continue;
+                }
+
+                String match = new StringBuffer(schemName).append('.').append(
+                    tabName).append('.').append(colName).toString();
+
+                if (columnLabel.equalsIgnoreCase(match)) {
+                    columnIndex = i;
+
+                    break;
+                }
+            }
+        }
+
+        if (columnIndex < 0) {
+            throw Util.sqlException(ErrorCode.JDBC_COLUMN_NOT_FOUND,
+                                    columnLabel);
+        }
+        columnIndex++;
+
+        if (columnMap == null) {
+            columnMap = new IntValueHashMap();
+        }
+        columnMap.put(columnLabel, columnIndex);
+
+        return columnIndex;
+    }
+
+    //--------------------------JDBC 2.0-----------------------------------
+    //---------------------------------------------------------------------
+    // Getters and Setters
+    //---------------------------------------------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a
+     * <code>java.io.Reader</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>java.io.Reader</code> object that contains the column
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @since JDK 1.2
+     */
+    public java.io.Reader getCharacterStream(
+            int columnIndex) throws SQLException {
+
+        checkColumn(columnIndex);
+
+        Type   sourceType = resultMetaData.columnTypes[columnIndex - 1];
+        Object o          = getColumnInType(columnIndex, sourceType);
+
+        if (o == null) {
+            return null;
+        }
+
+        if (o instanceof ClobDataID) {
+            return ((ClobDataID) o).getCharacterStream(session);
+        } else if (o instanceof Clob) {
+            return ((Clob) o).getCharacterStream();
+        } else if (o instanceof String) {
+            return new StringReader((String) o);
+        }
+
+        throw Util.sqlException(ErrorCode.X_42561);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a
+     * <code>java.io.Reader</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return a <code>java.io.Reader</code> object that contains the column
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @since JDK 1.2
+     */
+    public java.io.Reader getCharacterStream(
+            String columnLabel) throws SQLException {
+        return getCharacterStream(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a
+     * <code>java.math.BigDecimal</code> with full precision.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value (full precision);
+     * if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+
+        checkColumn(columnIndex);
+
+        Type targetType = resultMetaData.columnTypes[columnIndex - 1];
+
+        switch (targetType.typeCode) {
+           case Types.SQL_NUMERIC :
+           case Types.SQL_DECIMAL :
+               break;
+
+           case Types.TINYINT :
+           case Types.SQL_SMALLINT :
+           case Types.SQL_INTEGER :
+           case Types.SQL_BIGINT :
+               targetType = Type.SQL_DECIMAL;
+               break;
+
+           case Types.SQL_DOUBLE:
+           default :
+               targetType = Type.SQL_DECIMAL_DEFAULT;
+               break;
+
+
+        }
+
+        return (BigDecimal) getColumnInType(columnIndex, targetType);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a
+     * <code>java.math.BigDecimal</code> with full precision.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return the column value (full precision);
+     * if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
+        return getBigDecimal(findColumn(columnLabel));
+    }
+
+    //---------------------------------------------------------------------
+    // Traversal/Positioning
+    //---------------------------------------------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves whether the cursor is before the first row in
+     * this <code>ResultSet</code> object.
+     * <p>
+     * (JDBC4 Clarification:) <p>
+     * <strong>Note:</strong>Support for the <code>isBeforeFirst</code> method
+     * is optional for <code>ResultSet</code>s with a result
+     * set type of <code>TYPE_FORWARD_ONLY</code>
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the cursor is before the first row;
+     * <code>false</code> if the cursor is at any other position or the
+     * result set contains no rows
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public boolean isBeforeFirst() throws SQLException {
+
+        checkClosed();
+
+        if (isOnInsertRow) {
+            return false;
+        }
+
+        return navigator.isBeforeFirst();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves whether the cursor is after the last row in
+     * this <code>ResultSet</code> object.
+     * <p>
+     * (JDBC4 Clarification:)<p>
+     * <strong>Note:</strong>Support for the <code>isAfterLast</code> method
+     * is optional for <code>ResultSet</code>s with a result
+     * set type of <code>TYPE_FORWARD_ONLY</code>
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the cursor is after the last row;
+     * <code>false</code> if the cursor is at any other position or the
+     * result set contains no rows
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public boolean isAfterLast() throws SQLException {
+
+        // At afterLast condition exists when resultset has been traversed and
+        // the current row is null.  iCurrentRow should also be set to
+        // afterlast but no need to test
+        checkClosed();
+
+        if (isOnInsertRow) {
+            return false;
+        }
+
+        return navigator.isAfterLast();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves whether the cursor is on the first row of
+     * this <code>ResultSet</code> object.
+     * <p>
+     * (JDBC4 Clarification:) <p>
+     * <strong>Note:</strong>Support for the <code>isFirst</code> method
+     * is optional for <code>ResultSet</code>s with a result
+     * set type of <code>TYPE_FORWARD_ONLY</code>
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the cursor is on the first row;
+     * <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public boolean isFirst() throws SQLException {
+
+        checkClosed();
+
+        if (isOnInsertRow) {
+            return false;
+        }
+
+        return navigator.isFirst();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves whether the cursor is on the last row of
+     * this <code>ResultSet</code> object.
+     *  <strong>Note:</strong> Calling the method <code>isLast</code> may be expensive
+     * because the JDBC driver
+     * might need to fetch ahead one row in order to determine
+     * whether the current row is the last row in the result set.
+     * <p>
+     * (JDBC4 Clarification:) <p>
+     * <strong>Note:</strong> Support for the <code>isLast</code> method
+     * is optional for <code>ResultSet</code>s with a result
+     * set type of <code>TYPE_FORWARD_ONLY</code>
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the cursor is on the last row;
+     * <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs or this method is
+     *            called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public boolean isLast() throws SQLException {
+
+        checkClosed();
+
+        if (isOnInsertRow) {
+            return false;
+        }
+
+        return navigator.isLast();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor to the front of
+     * this <code>ResultSet</code> object, just before the
+     * first row. This method has no effect if the result set contains no rows.
+     * <!-- end generic documentation -->
+     *
+     * @exception SQLException if a database access error
+     * occurs, this method is called on a closed result set or the
+     * result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public void beforeFirst() throws SQLException {
+
+        checkClosed();
+        checkNotForwardOnly();
+
+        if (isOnInsertRow || isRowUpdated) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_24513);
+        }
+        navigator.beforeFirst();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor to the end of
+     * this <code>ResultSet</code> object, just after the
+     * last row. This method has no effect if the result set contains no rows.
+     * <!-- end generic documentation -->
+     *
+     * @exception SQLException if a database access error
+     * occurs, this method is called on a closed result set
+     * or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public void afterLast() throws SQLException {
+
+        checkClosed();
+        checkNotForwardOnly();
+
+        if (isOnInsertRow || isRowUpdated) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_24513);
+        }
+        navigator.afterLast();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor to the first row in
+     * this <code>ResultSet</code> object.
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the cursor is on a valid row;
+     * <code>false</code> if there are no rows in the result set
+     * @exception SQLException if a database access error
+     * occurs, this method is called on a closed result set
+     * or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public boolean first() throws SQLException {
+
+        checkClosed();
+        checkNotForwardOnly();
+
+        if (isOnInsertRow || isRowUpdated) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_24513);
+        }
+
+        return navigator.first();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor to the last row in
+     * this <code>ResultSet</code> object.
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the cursor is on a valid row;
+     * <code>false</code> if there are no rows in the result set
+     * @exception SQLException if a database access error
+     * occurs, this method is called on a closed result set
+     * or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public boolean last() throws SQLException {
+
+        checkClosed();
+        checkNotForwardOnly();
+
+        if (isOnInsertRow || isRowUpdated) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_24513);
+        }
+
+        return navigator.last();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the current row number.  The first row is number 1, the
+     * second number 2, and so on.
+     * <p>
+     * (JDBC4 Clarification:) <p>
+     * <strong>Note:</strong>Support for the <code>getRow</code> method
+     * is optional for <code>ResultSet</code>s with a result
+     * set type of <code>TYPE_FORWARD_ONLY</code>
+     * <!-- end generic documentation -->
+     *
+     * @return the current row number; <code>0</code> if there is no current row
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public int getRow() throws SQLException {
+
+        checkClosed();
+
+        if (navigator.isAfterLast()) {
+            return 0;
+        }
+
+        return navigator.getRowNumber() + 1;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor to the given row number in
+     * this <code>ResultSet</code> object.
+     *
+     * <p>If the row number is positive, the cursor moves to
+     * the given row number with respect to the
+     * beginning of the result set.  The first row is row 1, the second
+     * is row 2, and so on.
+     *
+     * <p>If the given row number is negative, the cursor moves to
+     * an absolute row position with respect to
+     * the end of the result set.  For example, calling the method
+     * <code>absolute(-1)</code> positions the
+     * cursor on the last row; calling the method <code>absolute(-2)</code>
+     * moves the cursor to the next-to-last row, and so on.
+     *
+     * <p>An attempt to position the cursor beyond the first/last row in
+     * the result set leaves the cursor before the first row or after
+     * the last row.
+     *
+     * <p><B>Note:</B> Calling <code>absolute(1)</code> is the same
+     * as calling <code>first()</code>. Calling <code>absolute(-1)</code>
+     * is the same as calling <code>last()</code>.
+     * <!-- end generic documentation -->
+     *
+     * @param row the number of the row to which the cursor should move.
+     *        A positive number indicates the row number counting from the
+     *        beginning of the result set; a negative number indicates the
+     *        row number counting from the end of the result set
+     * @return <code>true</code> if the cursor is moved to a position in this
+     * <code>ResultSet</code> object;
+     * <code>false</code> if the cursor is before the first row or after the
+     * last row
+     * @exception SQLException if a database access error
+     * occurs, this method is called on a closed result set
+     * or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public boolean absolute(int row) throws SQLException {
+
+        checkClosed();
+        checkNotForwardOnly();
+
+        if (isOnInsertRow || isRowUpdated) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_24513);
+        }
+
+        if (row > 0) {
+            row--;
+        } else if (row == 0) {
+            return navigator.beforeFirst();
+        }
+
+        return navigator.absolute(row);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor a relative number of rows, either positive or negative.
+     * Attempting to move beyond the first/last row in the
+     * result set positions the cursor before/after the
+     * the first/last row. Calling <code>relative(0)</code> is valid, but does
+     * not change the cursor position.
+     *
+     * <p>Note: Calling the method <code>relative(1)</code>
+     * is identical to calling the method <code>next()</code> and
+     * calling the method <code>relative(-1)</code> is identical
+     * to calling the method <code>previous()</code>.
+     * <!-- end generic documentation -->
+     *
+     * @param rows an <code>int</code> specifying the number of rows to
+     *        move from the current row; a positive number moves the cursor
+     *        forward; a negative number moves the cursor backward
+     * @return <code>true</code> if the cursor is on a row;
+     *         <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs,  this method
+     * is called on a closed result set,
+     *            there is no current row, or the result set type is
+     *            <code>TYPE_FORWARD_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public boolean relative(int rows) throws SQLException {
+
+        checkClosed();
+        checkNotForwardOnly();
+
+        if (isOnInsertRow || isRowUpdated) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_24513);
+        }
+
+        return navigator.relative(rows);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor to the previous row in this
+     * <code>ResultSet</code> object.
+     * <p>
+     * (JDBC4 clarification:)
+     * When a call to the <code>previous</code> method returns <code>false</code>,
+     * the cursor is positioned before the first row.  Any invocation of a
+     * <code>ResultSet</code> method which requires a current row will result in a
+     * <code>SQLException</code> being thrown.
+     * <p>
+     * (JDBC4 clarification:)
+     * If an input stream is open for the current row, a call to the method
+     * <code>previous</code> will implicitly close it.  A <code>ResultSet</code>
+     *  object's warning change is cleared when a new row is read.
+     * <p>
+     * <!-- end generic documentation -->
+     *
+     * @return (JDBC4 clarification:) <code>true</code> if the cursor is now positioned on a valid row;
+     * <code>false</code> if the cursor is positioned before the first row
+     * @exception SQLException if a database access error
+     * occurs; this method is called on a closed result set
+     * or the result set type is <code>TYPE_FORWARD_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public boolean previous() throws SQLException {
+
+        checkClosed();
+        checkNotForwardOnly();
+
+        if (isOnInsertRow || isRowUpdated) {
+            throw Util.sqlExceptionSQL(ErrorCode.X_24513);
+        }
+        rootWarning = null;
+
+        return navigator.previous();
+    }
+
+    //---------------------------------------------------------------------
+    // Properties
+    //---------------------------------------------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Gives a hint as to the direction in which the rows in this
+     * <code>ResultSet</code> object will be processed.
+     * The initial value is determined by the
+     * <code>Statement</code> object
+     * that produced this <code>ResultSet</code> object.
+     * The fetch direction may be changed at any time.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not need this hint. However, as mandated by the JDBC standard,
+     * an SQLException is thrown if the result set type is TYPE_FORWARD_ONLY
+     * and a fetch direction other than FETCH_FORWARD is requested. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param direction an <code>int</code> specifying the suggested
+     *        fetch direction; one of <code>ResultSet.FETCH_FORWARD</code>,
+     *        <code>ResultSet.FETCH_REVERSE</code>, or
+     *        <code>ResultSet.FETCH_UNKNOWN</code>
+     * @exception SQLException if a database access error occurs; this
+     * method is called on a closed result set or
+     * the result set type is <code>TYPE_FORWARD_ONLY</code> and the fetch
+     * direction is not <code>FETCH_FORWARD</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     * @see JDBCStatement#setFetchDirection
+     * @see #getFetchDirection
+     */
+    public void setFetchDirection(int direction) throws SQLException {
+
+        checkClosed();
+
+        switch (direction) {
+
+            case FETCH_FORWARD : {
+                break;
+            }
+            case FETCH_REVERSE : {
+                checkNotForwardOnly();
+
+                break;
+            }
+            case FETCH_UNKNOWN : {
+                checkNotForwardOnly();
+
+                break;
+            }
+            default : {
+                throw Util.notSupported();
+            }
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the fetch direction for this
+     * <code>ResultSet</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not depend on fetch direction and always returns
+     * <code>FETCH_FORWARD</code>, but the value has no real meaning. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the current fetch direction for this <code>ResultSet</code> object
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     * @see #setFetchDirection
+     */
+    public int getFetchDirection() throws SQLException {
+
+        checkClosed();
+
+        return FETCH_FORWARD;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Gives the JDBC driver a hint as to the number of rows that should
+     * be fetched from the database when more rows are needed for this
+     * <code>ResultSet</code> object.
+     * If the fetch size specified is zero, the JDBC driver
+     * ignores the value and is free to make its own best guess as to what
+     * the fetch size should be.  The default value is set by the
+     * <code>Statement</code> object
+     * that created the result set.  The fetch size may be changed at any time.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB may not build and return a result set as a
+     * whole. Therefore the supplied, non-zero, fetch size value is used for
+     * some ResultSet objects.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param rows the number of rows to fetch
+     * @exception SQLException if a database access error occurs; this method
+     * (JDBC4 Clarification:)
+     * is called on a closed result set or the
+     * (JDBC4 clarification:)
+     * condition <code>rows >= 0 </code> is not satisfied
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     * @see #getFetchSize
+     * @see JDBCStatement#setFetchSize
+     * @see JDBCStatement#getFetchSize
+     */
+    public void setFetchSize(int rows) throws SQLException {
+
+        if (rows < 0) {
+            throw Util.outOfRangeArgument();
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the fetch size for this
+     * <code>ResultSet</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB may not build and return a result set as a
+     * whole. The acutal fetch size for this result set is returned.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the current fetch size for this <code>ResultSet</code> object
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     * @see #setFetchSize
+     * @see JDBCStatement#getFetchSize
+     * @see JDBCStatement#setFetchSize
+     */
+    public int getFetchSize() throws SQLException {
+
+        checkClosed();
+
+        return fetchSize;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the type of this <code>ResultSet</code> object.
+     * The type is determined by the <code>Statement</code> object
+     * that created the result set.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB accurately
+     * reports the actual runtime scrollability of this result set instance.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>,
+     *         or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public int getType() throws SQLException {
+
+        checkClosed();
+
+        return ResultProperties.getJDBCScrollability(rsProperties);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the concurrency mode of this <code>ResultSet</code> object.
+     * The concurrency used is determined by the
+     * <code>Statement</code> object that created the result set.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports updatable result sets and accurately reports the actual
+     * runtime concurrency of this result set instance.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the concurrency type, either
+     *         <code>ResultSet.CONCUR_READ_ONLY</code>
+     *         or <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public int getConcurrency() throws SQLException {
+
+        checkClosed();
+
+        return ResultProperties.getJDBCConcurrency(rsProperties);
+    }
+
+    //---------------------------------------------------------------------
+    // Updates
+    //---------------------------------------------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves whether the current row has been updated.  The value returned
+     * depends on whether or not the result set can detect updates.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports updatable result sets and accurately reports the actual
+     * value.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if the current row is detected to
+     * have been visibly updated by the owner or another; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see JDBCDatabaseMetaData#updatesAreDetected
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public boolean rowUpdated() throws SQLException {
+
+        checkClosed();
+
+        return isRowUpdated;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves whether the current row has had an insertion.
+     * The value returned depends on whether or not this
+     * <code>ResultSet</code> object can detect visible inserts.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports updatable result sets and accurately reports the actual
+     * value.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return <code>true</code> if the current row is detected to
+     * have been inserted; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see JDBCDatabaseMetaData#insertsAreDetected
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public boolean rowInserted() throws SQLException {
+
+        checkClosed();
+
+        return false;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves whether a row has been deleted.  A deleted row may leave
+     * a visible "hole" in a result set.  This method can be used to
+     * detect holes in a result set.  The value returned depends on whether
+     * or not this <code>ResultSet</code> object can detect deletions.
+     * <p>
+     * (JDBC4 Clarification:) <p>
+     * <strong>Note:</strong> Support for the <code>rowDeleted</code> method is optional with a result set
+     * concurrency of <code>CONCUR_READ_ONLY</code>
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports updatable result sets and accurately reports the actual
+     * value.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @return <code>true</code> if the current row is detected to
+     * have been deleted by the owner or another; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @see JDBCDatabaseMetaData#deletesAreDetected
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public boolean rowDeleted() throws SQLException {
+
+        checkClosed();
+
+        return false;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Updates the designated column with a <code>null</code> value.
+     *
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code>
+     * or <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateNull(int columnIndex) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, null);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>boolean</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+
+        Boolean value = x ? Boolean.TRUE
+                          : Boolean.FALSE;
+
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, value);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>byte</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateByte(int columnIndex, byte x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setIntParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>short</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateShort(int columnIndex, short x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setIntParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with an <code>int</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateInt(int columnIndex, int x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setIntParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>long</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateLong(int columnIndex, long x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setLongParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>float</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateFloat(int columnIndex, float x) throws SQLException {
+
+        Double value = new Double(x);
+
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, value);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>double</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateDouble(int columnIndex, double x) throws SQLException {
+
+        Double value = new Double(x);
+
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, value);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.math.BigDecimal</code>
+     * value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateBigDecimal(int columnIndex,
+                                 BigDecimal x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>String</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateString(int columnIndex, String x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>byte</code> array value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Date</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateDate(int columnIndex, Date x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Time</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateTime(int columnIndex, Time x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Timestamp</code>
+     * value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateTimestamp(int columnIndex,
+                                Timestamp x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Updates the designated column with an ascii stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateAsciiStream(int columnIndex, java.io.InputStream x,
+                                  int length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setAsciiStream(columnIndex, x, length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Updates the designated column with a binary stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public void updateBinaryStream(int columnIndex, java.io.InputStream x,
+                                   int length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setBinaryStream(columnIndex, x, length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Updates the designated column with a character stream value, which will have
+     * the specified number of (CHECKME: characters?) bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void updateCharacterStream(int columnIndex, java.io.Reader x,
+                                      int length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setCharacterStream(columnIndex, x, length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with an <code>Object</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <p>
+     * (JDBC clarification:)
+     * If the second argument is an <code>InputStream</code> then the stream must contain
+     * the number of bytes specified by scaleOrLength.  If the second argument is a
+     * <code>Reader</code> then the reader must contain the number of characters specified
+     * by scaleOrLength. If these conditions are not true the driver will generate a
+     * <code>SQLException</code> when the statement is executed.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @param scaleOrLength for an object of <code>java.math.BigDecimal</code> ,
+     *          this is the number of digits after the decimal point. For
+     *          Java Object types <code>InputStream</code> and <code>Reader</code>,
+     *          this is the length
+     *          of the data in the stream or reader.  For all other types,
+     *          this value will be ignored.
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void updateObject(int columnIndex, Object x,
+                             int scaleOrLength) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setObject(columnIndex, x, 0, scaleOrLength);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with an <code>Object</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void updateObject(int columnIndex, Object x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>null</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void updateNull(String columnLabel) throws SQLException {
+        updateNull(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>boolean</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void updateBoolean(String columnLabel,
+                              boolean x) throws SQLException {
+        updateBoolean(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>byte</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void updateByte(String columnLabel, byte x) throws SQLException {
+        updateByte(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>short</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void updateShort(String columnLabel, short x) throws SQLException {
+        updateShort(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with an <code>int</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void updateInt(String columnLabel, int x) throws SQLException {
+        updateInt(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>long</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateLong(String columnLabel, long x) throws SQLException {
+        updateLong(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>float </code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateFloat(String columnLabel, float x) throws SQLException {
+        updateFloat(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>double</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateDouble(String columnLabel,
+                             double x) throws SQLException {
+        updateDouble(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.BigDecimal</code>
+     * value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateBigDecimal(String columnLabel,
+                                 BigDecimal x) throws SQLException {
+        updateBigDecimal(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>String</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateString(String columnLabel,
+                             String x) throws SQLException {
+        updateString(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a byte array value.
+     *
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code>
+     * or <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+        updateBytes(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Date</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateDate(String columnLabel, Date x) throws SQLException {
+        updateDate(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Time</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateTime(String columnLabel, Time x) throws SQLException {
+        updateTime(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Timestamp</code>
+     * value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateTimestamp(String columnLabel,
+                                Timestamp x) throws SQLException {
+        updateTimestamp(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Updates the designated column with an ascii stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateAsciiStream(String columnLabel, java.io.InputStream x,
+                                  int length) throws SQLException {
+        updateAsciiStream(findColumn(columnLabel), x, length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Updates the designated column with a binary stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateBinaryStream(String columnLabel, java.io.InputStream x,
+                                   int length) throws SQLException {
+        updateBinaryStream(findColumn(columnLabel), x, length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification)
+     * Updates the designated column with a character stream value, which will have
+     * the specified number of (CHECKME: characters?) bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param reader the <code>java.io.Reader</code> object containing
+     *        the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateCharacterStream(String columnLabel,
+                                      java.io.Reader reader,
+                                      int length) throws SQLException {
+        updateCharacterStream(findColumn(columnLabel), reader, length);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with an <code>Object</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <p>
+     * (JDBC4 Clarification:)
+     * If the second argument is an <code>InputStream</code> then the stream must contain
+     * the number of bytes specified by scaleOrLength.  If the second argument is a
+     * <code>Reader</code> then the reader must contain the number of characters specified
+     * by scaleOrLength. If these conditions are not true the driver will generate a
+     * <code>SQLException</code> when the statement is executed.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @param scaleOrLength for an object of <code>java.math.BigDecimal</code> ,
+     *          this is the number of digits after the decimal point. For
+     *          Java Object types <code>InputStream</code> and <code>Reader</code>,
+     *          this is the length
+     *          of the data in the stream or reader.  For all other types,
+     *          this value will be ignored.
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateObject(String columnLabel, Object x,
+                             int scaleOrLength) throws SQLException {
+        updateObject(findColumn(columnLabel), x, scaleOrLength);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with an <code>Object</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateObject(String columnLabel,
+                             Object x) throws SQLException {
+        updateObject(findColumn(columnLabel), x);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Inserts the contents of the insert row into this
+     * <code>ResultSet</code> object and into the database.
+     * The cursor must be on the insert row when this method is called.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>,
+     * this method is called on a closed result set,
+     * if this method is called when the cursor is not on the insert row,
+     * or if not all of non-nullable columns in
+     * the insert row have been given a non-null value
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void insertRow() throws SQLException {
+        performInsert();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the underlying database with the new contents of the
+     * current row of this <code>ResultSet</code> object.
+     * This method cannot be called when the cursor is on the insert row.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * After updating any values in the current row, it is not possible to
+     * move the cursor position without calling this method, or alternatively
+     * calling cancelRowUpdates() to abandon the row update.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>;
+     *  this method is called on a closed result set or
+     * if this method is called when the cursor is on the insert row
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void updateRow() throws SQLException {
+        performUpdate();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Deletes the current row from this <code>ResultSet</code> object
+     * and from the underlying database.  This method cannot be called when
+     * the cursor is on the insert row.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     *
+     * After a successful call to this method, the row is deleted.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>;
+     * this method is called on a closed result set
+     * or if this method is called when the cursor is on the insert row
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void deleteRow() throws SQLException {
+        performDelete();
+    }
+
+    /** @todo - fredt - implement */
+
+    /**
+     * <!-- start generic documentation -->
+     * Refreshes the current row with its most recent value in
+     * the database.  This method cannot be called when
+     * the cursor is on the insert row.
+     *
+     * <P>The <code>refreshRow</code> method provides a way for an
+     * application to
+     * explicitly tell the JDBC driver to refetch a row(s) from the
+     * database.  An application may want to call <code>refreshRow</code> when
+     * caching or prefetching is being done by the JDBC driver to
+     * fetch the latest value of a row from the database.  The JDBC driver
+     * may actually refresh multiple rows at once if the fetch size is
+     * greater than one.
+     *
+     * <P> All values are refetched subject to the transaction isolation
+     * level and cursor sensitivity.  If <code>refreshRow</code> is called after
+     * calling an updater method, but before calling
+     * the method <code>updateRow</code>, then the
+     * updates made to the row are lost.  Calling the method
+     * <code>refreshRow</code> frequently will likely slow performance.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error
+     * occurs; this method is called on a closed result set;
+     * the result set type is <code>TYPE_FORWARD_ONLY</code> or if this
+     * method is called when the cursor is on the insert row
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method or this method is not supported for the specified result
+     * set type and result set concurrency.
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public void refreshRow() throws SQLException {
+        clearUpdates();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Cancels the updates made to the current row in this
+     * <code>ResultSet</code> object.
+     * This method may be called after calling an
+     * updater method(s) and before calling
+     * the method <code>updateRow</code> to roll back
+     * the updates made to a row.  If no updates have been made or
+     * <code>updateRow</code> has already been called, this method has no
+     * effect.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error
+     *            occurs; this method is called on a closed result set;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or if this method is called when the cursor is
+     *            on the insert row
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void cancelRowUpdates() throws SQLException {
+        clearUpdates();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor to the insert row.  The current cursor position is
+     * remembered while the cursor is positioned on the insert row.
+     *
+     * The insert row is a special row associated with an updatable
+     * result set.  It is essentially a buffer where a new row may
+     * be constructed by calling the updater methods prior to
+     * inserting the row into the result set.
+     *
+     * Only the updater, getter,
+     * and <code>insertRow</code> methods may be
+     * called when the cursor is on the insert row.  All of the columns in
+     * a result set must be given a value each time this method is
+     * called before calling <code>insertRow</code>.
+     * An updater method must be called before a
+     * getter method can be called on a column value.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs; this
+     * method is called on a closed result set
+     * or the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public void moveToInsertRow() throws SQLException {
+        startInsert();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves the cursor to the remembered cursor position, usually the
+     * current row.  This method has no effect if the cursor is not on
+     * the insert row.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @exception SQLException if a database access error occurs, this
+     * method is called on a closed result set
+     *  or the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public void moveToCurrentRow() throws SQLException {
+        endInsert();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the <code>Statement</code> object that produced this
+     * <code>ResultSet</code> object.
+     * If the result set was generated some other way, such as by a
+     * <code>DatabaseMetaData</code> method, this method  may return
+     * <code>null</code>.
+     * <!-- end generic documentation -->
+     *
+     * @return the <code>Statment</code> object that produced
+     * this <code>ResultSet</code> object or <code>null</code>
+     * if the result set was produced some other way
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *    JDBCResultSet)
+     */
+    public Statement getStatement() throws SQLException {
+
+        checkClosed();
+
+        return (Statement) statement;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as an <code>Object</code>
+     * in the Java programming language.
+     * If the value is an SQL <code>NULL</code>,
+     * the driver returns a Java <code>null</code>.
+     * This method uses the given <code>Map</code> object
+     * for the custom mapping of the
+     * SQL structured or distinct type that is being retrieved.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature, but ignores the map.  <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param map a <code>java.util.Map</code> object that contains the mapping
+     * from SQL type names to classes in the Java programming language
+     * @return an <code>Object</code> in the Java programming language
+     * representing the SQL value
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public Object getObject(int columnIndex, Map map) throws SQLException {
+        return getObject(columnIndex);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>Ref</code> object
+     * in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support this feature; this method always
+     * throws an <code>SQLException</code> stating that the operation is not
+     * supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a <code>Ref</code> object representing an SQL <code>REF</code>
+     *         value
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     * JDBCResultSet)
+     */
+    public Ref getRef(int columnIndex) throws SQLException {
+        throw Util.notSupported();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>Blob</code> object
+     * in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports this feature for objects of type BLOB and BINARY.
+     * The Blob returned for BINARY objects is a memory object. The Blob
+     * return for BLOB objects is not held entirely in memory. Its contents are
+     * fetched from the database when its getXXX() methods are called. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a <code>Blob</code> object representing the SQL
+     *         <code>BLOB</code> value in the specified column
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2
+     */
+    public Blob getBlob(int columnIndex) throws SQLException {
+
+        checkColumn(columnIndex);
+
+        Type   sourceType = resultMetaData.columnTypes[columnIndex - 1];
+        Object o          = getColumnInType(columnIndex, sourceType);
+
+        if (o == null) {
+            return null;
+        }
+
+        if (o instanceof BlobDataID) {
+            return new JDBCBlobClient(session, (BlobDataID) o);
+        } else if (o instanceof Blob) {
+            return (Blob) o;
+        } else if (o instanceof BinaryData) {
+            byte[] b = getBytes(columnIndex);
+
+            return new JDBCBlob(b);
+        }
+
+        throw Util.sqlException(ErrorCode.X_42561);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>Clob</code> object
+     * in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports this feature for objects of type CLOB and
+     * the variations of CHAR.
+     * The Clob returned for CHAR objects is a memory object. The Clob
+     * return for CLOB objects is not held entirely in memory. Its contents are
+     * fetched from the database when its getXXX() methods are called. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a <code>Clob</code> object representing the SQL
+     *         <code>CLOB</code> value in the specified column
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2
+     */
+    public Clob getClob(int columnIndex) throws SQLException {
+
+        checkColumn(columnIndex);
+
+        Type   sourceType = resultMetaData.columnTypes[columnIndex - 1];
+        Object o          = getColumnInType(columnIndex, sourceType);
+
+        if (o == null) {
+            return null;
+        }
+
+        if (o instanceof ClobDataID) {
+            return new JDBCClobClient(session, (ClobDataID) o);
+        } else if (o instanceof Clob) {
+            return (Clob) o;
+        } else if (o instanceof String) {
+            return new JDBCClob((String) o);
+        }
+
+        throw Util.sqlException(ErrorCode.X_42561);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as an <code>Array</code> object
+     * in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From version 2.0, HSQLDB supports array types.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return an <code>Array</code> object representing the SQL
+     *         <code>ARRAY</code> value in the specified column
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Array getArray(int columnIndex) throws SQLException {
+
+        checkColumn(columnIndex);
+
+        Type type = resultMetaData.columnTypes[columnIndex - 1];
+
+        if (!type.isArrayType()) {
+            throw Util.sqlException(ErrorCode.X_42561);
+        }
+
+        Object[] data = (Object[]) getCurrent()[columnIndex - 1];
+
+        if (data == null) {
+            return null;
+        }
+
+        return new JDBCArray(data, type.collectionBaseType(), type, connection);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as an <code>Object</code>
+     * in the Java programming language.
+     * If the value is an SQL <code>NULL</code>,
+     * the driver returns a Java <code>null</code>.
+     * This method uses the specified <code>Map</code> object for
+     * custom mapping if appropriate.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports this feature. But the Map parameter is ignored.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param map a <code>java.util.Map</code> object that contains the mapping
+     * from SQL type names to classes in the Java programming language
+     * @return an <code>Object</code> representing the SQL value in the
+     *         specified column
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Object getObject(String columnLabel, Map map) throws SQLException {
+        return getObject(findColumn(columnLabel), map);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>Ref</code> object
+     * in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, HSQLDB does not support reference types; this method
+     * always throws an <code>SQLException</code> stating that the operation
+     * is not supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return a <code>Ref</code> object representing the SQL <code>REF</code>
+     *         value in the specified column
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Ref getRef(String columnLabel) throws SQLException {
+        return getRef(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>Blob</code> object
+     * in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports this feature for objects of type BLOB and BINARY.
+     * The Blob returned for BINARY objects is a memory object. The Blob
+     * return for BLOB objects is not held entirely in memory. Its contents are
+     * fetched from the database when its getXXX() methods are called. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return a <code>Blob</code> object representing the SQL <code>BLOB</code>
+     *         value in the specified column
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2
+     */
+    public Blob getBlob(String columnLabel) throws SQLException {
+        return getBlob(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>Clob</code> object
+     * in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports this feature for objects of type CLOB and
+     * the variations of CHAR.
+     * The Clob returned for CHAR objects is a memory object. The Clob
+     * return for CLOB objects is not held entirely in memory. Its contents are
+     * fetched from the database when its getXXX() methods are called. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return a <code>Clob</code> object representing the SQL <code>CLOB</code>
+     * value in the specified column
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2
+     */
+    public Clob getClob(String columnLabel) throws SQLException {
+        return getClob(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as an <code>Array</code> object
+     * in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From version 2.0, HSQLDB supports array types.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @return an <code>Array</code> object representing the SQL <code>ARRAY</code> value in
+     *         the specified column
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Array getArray(String columnLabel) throws SQLException {
+        return getArray(findColumn(columnLabel));
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
+     * in the Java programming language.
+     * This method uses the given calendar to construct an appropriate millisecond
+     * value for the date if the underlying database does not store
+     * timezone information.
+     * <!-- end generic documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param cal the <code>java.util.Calendar</code> object
+     * to use in constructing the date
+     * @return the column value as a <code>java.sql.Date</code> object;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+
+        TimestampData t = (TimestampData) getColumnInType(columnIndex,
+            Type.SQL_DATE);
+
+        if (t == null) {
+            return null;
+        }
+
+        long millis = t.getSeconds() * 1000;
+
+        if (cal != null) {
+            millis = HsqlDateTime.convertMillisToCalendar(cal, millis);
+        }
+
+        return new Date(millis);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>java.sql.Date</code> object
+     * in the Java programming language.
+     * This method uses the given calendar to construct an appropriate millisecond
+     * value for the date if the underlying database does not store
+     * timezone information.
+     * <!-- end generic documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param cal the <code>java.util.Calendar</code> object
+     * to use in constructing the date
+     * @return the column value as a <code>java.sql.Date</code> object;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Date getDate(String columnLabel, Calendar cal) throws SQLException {
+        return getDate(findColumn(columnLabel), cal);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>java.sql.Time</code>
+     * object in the Java programming language.
+     * This method uses the given calendar to construct an appropriate millisecond
+     * value for the time if the underlying database does not store
+     * timezone information.
+     * <!-- end generic documentation -->
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The JDBC specification for this method is vague. HSQLDB interprets the
+     * specification as follows:
+     *
+     * <ol>
+     * <li>If the SQL type of the column is WITH TIME ZONE, then the UTC value
+     * of the returned java.sql.Time object is the UTC of the SQL value without
+     * modification. In other words, the Calendar object is not used.</li>
+     * <li>If the SQL type of the column is WITHOUT TIME ZONE, then the UTC
+     * value of the returned java.sql.Time is correct for the given Calendar
+     * object.</li>
+     * <li>If the cal argument is null, it it ignored and the method returns
+     * the same Object as the method without the Calendar parameter.</li>
+     * </ol>
+     * </div>
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param cal the <code>java.util.Calendar</code> object
+     * to use in constructing the time
+     * @return the column value as a <code>java.sql.Time</code> object;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *   JDBCResultSet)
+     */
+    public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+
+        TimeData t = (TimeData) getColumnInType(columnIndex, Type.SQL_TIME);
+
+        if (t == null) {
+            return null;
+        }
+
+        long millis = DateTimeType.normaliseTime(t.getSeconds()) * 1000;
+
+        if (!resultMetaData.columnTypes[--columnIndex]
+                .isDateTimeTypeWithZone()) {
+            Calendar calendar = cal == null ? session.getCalendar()
+                    : cal;
+
+            millis = HsqlDateTime.convertMillisToCalendar(calendar, millis);
+            millis = HsqlDateTime.getNormalisedTime(millis);
+        }
+
+        return new Time(millis);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>java.sql.Time</code> object
+     * in the Java programming language.
+     * This method uses the given calendar to construct an appropriate millisecond
+     * value for the time if the underlying database does not store
+     * timezone information.
+     * <!-- end generic documentation -->
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The JDBC specification for this method is vague. HSQLDB interprets the
+     * specification as follows:
+     *
+     * <ol>
+     * <li>If the SQL type of the column is WITH TIME ZONE, then the UTC value
+     * of the returned java.sql.Time object is the UTC of the SQL value without
+     * modification. In other words, the Calendar object is not used.</li>
+     * <li>If the SQL type of the column is WITHOUT TIME ZONE, then the UTC
+     * value of the returned java.sql.Time is correct for the given Calendar
+     * object.</li>
+     * <li>If the cal argument is null, it it ignored and the method returns
+     * the same Object as the method without the Calendar parameter.</li>
+     * </ol>
+     * </div>
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param cal the <code>java.util.Calendar</code> object
+     * to use in constructing the time
+     * @return the column value as a <code>java.sql.Time</code> object;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Time getTime(String columnLabel, Calendar cal) throws SQLException {
+        return getTime(findColumn(columnLabel), cal);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
+     * in the Java programming language.
+     * This method uses the given calendar to construct an appropriate millisecond
+     * value for the timestamp if the underlying database does not store
+     * timezone information.
+     * <!-- end generic documentation -->
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The JDBC specification for this method is vague. HSQLDB interprets the
+     * specification as follows:
+     *
+     * <ol>
+     * <li>If the SQL type of the column is WITH TIME ZONE, then the UTC value
+     * of the returned java.sql.Timestamp object is the UTC of the SQL value
+     * without modification. In other words, the Calendar object is not used.
+     * </li>
+     * <li>If the SQL type of the column is WITHOUT TIME ZONE, then the
+     * UTC value of the returned java.sql.Timestamp will represent the correct
+     * timestamp for the time zone (including daylight saving time) of the given
+     * Calendar object. </li>
+     * <li>In this case, if the cal argument is null, then the default Calendar
+     * of the JVM is used, which results in the same Object as one returned by the
+     * getTimestamp() methods without the Calendar parameter.</li>
+     * </ol>
+     * </div>
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param cal the <code>java.util.Calendar</code> object
+     * to use in constructing the timestamp
+     * @return the column value as a <code>java.sql.Timestamp</code> object;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Timestamp getTimestamp(int columnIndex,
+                                  Calendar cal) throws SQLException {
+
+        TimestampData t = (TimestampData) getColumnInType(columnIndex,
+            Type.SQL_TIMESTAMP);
+
+        if (t == null) {
+            return null;
+        }
+
+        long millis = t.getSeconds() * 1000;
+
+        if (!resultMetaData.columnTypes[--columnIndex]
+                .isDateTimeTypeWithZone()) {
+            Calendar calendar = cal == null ? session.getCalendar()
+                    : cal;
+
+            if (cal != null) {
+                millis = HsqlDateTime.convertMillisToCalendar(calendar,
+                        millis);
+            }
+        }
+
+        Timestamp ts = new Timestamp(millis);
+
+        ts.setNanos(t.getNanos());
+
+        return ts;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>java.sql.Timestamp</code> object
+     * in the Java programming language.
+     * This method uses the given calendar to construct an appropriate millisecond
+     * value for the timestamp if the underlying database does not store
+     * timezone information.
+     * <!-- end generic documentation -->
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The JDBC specification for this method is vague. HSQLDB interprets the
+     * specification as follows:
+     *
+     * <ol>
+     * <li>If the SQL type of the column is WITH TIME ZONE, then the UTC value
+     * of the returned java.sql.Timestamp object is the UTC of the SQL value
+     * without modification. In other words, the Calendar object is not used.
+     * </li>
+     * <li>If the SQL type of the column is WITHOUT TIME ZONE, then the UTC
+     * value of the returned java.sql.Timestamp is correct for the given
+     * Calendar object.</li>
+     * <li>If the cal argument is null, it it ignored and the method returns
+     * the same Object as the method without the Calendar parameter.</li>
+     * </ol>
+     * </div>
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param cal the <code>java.util.Calendar</code> object
+     * to use in constructing the date
+     * @return the column value as a <code>java.sql.Timestamp</code> object;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *  JDBCResultSet)
+     */
+    public Timestamp getTimestamp(String columnLabel,
+                                  Calendar cal) throws SQLException {
+        return getTimestamp(findColumn(columnLabel), cal);
+    }
+
+    //-------------------------- JDBC 3.0 ----------------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>java.net.URL</code>
+     * object in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support the datalink type; this method
+     * always throws an <code>SQLException</code> stating that the operation is
+     * not supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the index of the column 1 is the first, 2 is the second,...
+     * @return the column value as a <code>java.net.URL</code> object;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs; this method
+     * is called on a closed result set or if a URL is malformed
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public java.net.URL getURL(int columnIndex) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>java.net.URL</code>
+     * object in the Java programming language.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support the datalink type; this method
+     * always throws an <code>SQLException</code> stating that the operation is
+     * not supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @return the column value as a <code>java.net.URL</code> object;
+     * if the value is SQL <code>NULL</code>,
+     * the value returned is <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occur; this method
+     * is called on a closed result set or if a URL is malformed
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public java.net.URL getURL(String columnLabel) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Ref</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support reference types; this method
+     * always throws an <code>SQLException</code> stating that the operation is
+     * not supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void updateRef(int columnIndex,
+                          java.sql.Ref x) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Ref</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support reference types; this method
+     * always throws an <code>SQLException</code> stating that the operation is
+     * not supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void updateRef(String columnLabel,
+                          java.sql.Ref x) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Blob</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports this feature for columns of type BLOB.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void updateBlob(int columnIndex,
+                           java.sql.Blob x) throws SQLException {
+
+        if (x instanceof JDBCBlobClient) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "invalid Blob");
+        }
+        startUpdate(columnIndex);
+        preparedStatement.setBlobParameter(columnIndex, x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Blob</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports this feature for columns of type BLOB.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void updateBlob(String columnLabel,
+                           java.sql.Blob x) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        updateBlob(columnIndex, x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Clob</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports this feature for columns of type CLOB.<p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void updateClob(int columnIndex,
+                           java.sql.Clob x) throws SQLException {
+
+        if (x instanceof JDBCClobClient) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "invalid Clob");
+        }
+        startUpdate(columnIndex);
+        preparedStatement.setClobParameter(columnIndex, x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Clob</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 supports this feature for columns of type CLOB.<p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void updateClob(String columnLabel,
+                           java.sql.Clob x) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        updateClob(columnIndex, x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Array</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support array types; this method always
+     * throws an <code>SQLException</code> stating that the operation is not
+     * supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void updateArray(int columnIndex,
+                            java.sql.Array x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setParameter(columnIndex, x);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Updates the designated column with a <code>java.sql.Array</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support array types; this method always
+     * throws an <code>SQLException</code> stating that the operation is not
+     * supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param x the new column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.4, HSQLDB 1.7.0
+     */
+//#ifdef JAVA4
+    public void updateArray(String columnLabel,
+                            java.sql.Array x) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        updateArray(columnIndex, x);
+    }
+
+//#endif JAVA4
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
+     * programming language.
+     *
+     * @param columnIndex the first column is 1, the second 2, ...
+     * @return the column value; if the value is a SQL <code>NULL</code> the
+     *     value returned is <code>null</code>
+     * @throws SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public RowId getRowId(int columnIndex) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in the current row of this
+     * <code>ResultSet</code> object as a <code>java.sql.RowId</code> object in the Java
+     * programming language.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support the RowId type; this method always
+     * throws an <code>SQLException</code> stating that the operation is not
+     * supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @return the column value ; if the value is a SQL <code>NULL</code> the
+     *     value returned is <code>null</code>
+     * @throws SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public RowId getRowId(String columnLabel) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a <code>RowId</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead
+     * the <code>updateRow</code> or <code>insertRow</code> methods are called
+     * to update the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support the RowId type; this method always
+     * throws an <code>SQLException</code> stating that the operation is not
+     * supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnIndex the first column is 1, the second 2, ...
+     * @param x the column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateRowId(int columnIndex, RowId x) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a <code>RowId</code> value. The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead
+     * the <code>updateRow</code> or <code>insertRow</code> methods are called
+     * to update the database.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB does not support the RowId type; this method always
+     * throws an <code>SQLException</code> stating that the operation is not
+     * supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param x the column value
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateRowId(String columnLabel, RowId x) throws SQLException {
+        throw Util.notSupported();
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the holdability of this <code>ResultSet</code> object
+     * @return  either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @throws SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public int getHoldability() throws SQLException {
+
+        checkClosed();
+
+        return ResultProperties.getJDBCHoldability(rsProperties);
+    }
+
+    /**
+     * Retrieves whether this <code>ResultSet</code> object has been closed.
+     * A <code>ResultSet</code> is closed if the
+     * method close has been called on it, or if it is automatically closed.
+     *
+     * @return true if this <code>ResultSet</code> object is closed; false if it is still open
+     * @throws SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public boolean isClosed() throws SQLException {
+        return navigator == null;
+    }
+
+    /**
+     * Updates the designated column with a <code>String</code> value.
+     * It is intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnIndex the first column is 1, the second 2, ...
+     * @param nString the value for the column to be updated
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; this method is called on a closed result set,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or if a database access error occurs
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+
+//#ifdef JAVA6
+    public void updateNString(int columnIndex,
+                              String nString) throws SQLException {
+        updateString(columnIndex, nString);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a <code>String</code> value.
+     * It is intended for use when updating <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param nString the value for the column to be updated
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; this method is called on a closed result set;
+     * the result set concurrency is <CODE>CONCUR_READ_ONLY</code>
+     *  or if a database access error occurs
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateNString(String columnLabel,
+                              String nString) throws SQLException {
+        updateString(columnLabel, nString);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a <code>java.sql.NClob</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnIndex the first column is 1, the second 2, ...
+     * @param nClob the value for the column to be updated
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; this method is called on a closed result set,
+     * if a database access error occurs or
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
+        updateClob(columnIndex, nClob);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a <code>java.sql.NClob</code> value.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param nClob the value for the column to be updated
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; this method is called on a closed result set;
+     *  if a database access error occurs or
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateNClob(String columnLabel,
+                            NClob nClob) throws SQLException {
+        updateClob(columnLabel, nClob);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>NClob</code> object
+     * in the Java programming language.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a <code>NClob</code> object representing the SQL
+     *         <code>NCLOB</code> value in the specified column
+     * @exception SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; this method is called on a closed result set
+     * or if a database access error occurs
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public NClob getNClob(int columnIndex) throws SQLException {
+
+        String s = getString(columnIndex);
+
+        return s == null ? null
+                         : new JDBCNClob(s);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a <code>NClob</code> object
+     * in the Java programming language.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @return a <code>NClob</code> object representing the SQL <code>NCLOB</code>
+     * value in the specified column
+     * @exception SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; this method is called on a closed result set
+     * or if a database access error occurs
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public NClob getNClob(String columnLabel) throws SQLException {
+        return getNClob(findColumn(columnLabel));
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in  the current row of
+     *  this <code>ResultSet</code> as a
+     * <code>java.sql.SQLXML</code> object in the Java programming language.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+     * @throws SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public SQLXML getSQLXML(int columnIndex) throws SQLException {
+
+        checkColumn(columnIndex);
+
+        SQLXML sqlxml;
+        int    type = resultMetaData.columnTypes[columnIndex - 1].typeCode;
+
+        switch (type) {
+
+            case Types.SQL_XML : {
+                Object object = getObject(columnIndex);
+
+                if (object == null) {
+                    sqlxml = null;
+                } else if (object instanceof SQLXML) {
+                    sqlxml = (SQLXML) object;
+                } else {
+                    throw Util.notSupported();
+                }
+
+                break;
+            }
+            case Types.SQL_CLOB : {
+                Clob clob = getClob(columnIndex);
+
+                if (clob == null) {
+                    sqlxml = null;
+                } else {
+                    sqlxml = new JDBCSQLXML(clob.getCharacterStream());
+                }
+
+                break;
+            }
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE : {
+                java.io.Reader reader = getCharacterStream(columnIndex);
+
+                if (reader == null) {
+                    sqlxml = null;
+                } else {
+                    sqlxml = new JDBCSQLXML(reader);
+                }
+
+                break;
+            }
+            case Types.SQL_NCHAR :
+            case Types.SQL_NVARCHAR : {
+                java.io.Reader nreader = getNCharacterStream(columnIndex);
+
+                if (nreader == null) {
+                    sqlxml = null;
+                } else {
+                    sqlxml = new JDBCSQLXML(nreader);
+                }
+
+                break;
+            }
+            case Types.SQL_BLOB : {
+                Blob blob = getBlob(columnIndex);
+
+                if (blob == null) {
+                    sqlxml = null;
+                } else {
+                    sqlxml = new JDBCSQLXML(blob.getBinaryStream());
+                }
+
+                break;
+            }
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY : {
+                java.io.InputStream inputStream = getBinaryStream(columnIndex);
+
+                if (inputStream == null) {
+                    sqlxml = null;
+                } else {
+                    sqlxml = new JDBCSQLXML(inputStream);
+                }
+
+                break;
+            }
+            case Types.OTHER :
+            case Types.JAVA_OBJECT : {
+                Object data = getObject(columnIndex);
+
+                if (data == null) {
+                    sqlxml = null;
+                } else if (data instanceof SQLXML) {
+                    sqlxml = (SQLXML) data;
+                } else if (data instanceof String) {
+                    sqlxml = new JDBCSQLXML((String) data);
+                } else if (data instanceof byte[]) {
+                    sqlxml = new JDBCSQLXML((byte[]) data);
+                } else if (data instanceof Blob) {
+                    Blob blob = (Blob) data;
+
+                    sqlxml = new JDBCSQLXML(blob.getBinaryStream());
+                } else if (data instanceof Clob) {
+                    Clob clob = (Clob) data;
+
+                    sqlxml = new JDBCSQLXML(clob.getCharacterStream());
+                } else {
+                    throw Util.notSupported();
+                }
+
+                break;
+            }
+            default : {
+                throw Util.notSupported();
+            }
+        }
+
+        return sqlxml;
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in  the current row of
+     *  this <code>ResultSet</code> as a
+     * <code>java.sql.SQLXML</code> object in the Java programming language.
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+     * @throws SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public SQLXML getSQLXML(String columnLabel) throws SQLException {
+        return getSQLXML(findColumn(columnLabel));
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a <code>java.sql.SQLXML</code> value.
+     * The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead
+     * the <code>updateRow</code> or <code>insertRow</code> methods are called
+     * to update the database.
+     * <p>
+     *
+     * @param columnIndex the first column is 1, the second 2, ...
+     * @param xmlObject the value for the column to be updated
+     * @throws SQLException if a database access error occurs, this method
+     *  is called on a closed result set,
+     * the <code>java.xml.transform.Result</code>,
+     *  <code>Writer</code> or <code>OutputStream</code> has not been closed
+     * for the <code>SQLXML</code> object,
+     *  if there is an error processing the XML value or
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>.  The <code>getCause</code> method
+     *  of the exception may provide a more detailed exception, for example, if the
+     *  stream does not contain valid XML.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateSQLXML(int columnIndex,
+                             SQLXML xmlObject) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setSQLXML(columnIndex, xmlObject);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a <code>java.sql.SQLXML</code> value.
+     * The updater
+     * methods are used to update column values in the current row or the insert
+     * row. The updater methods do not update the underlying database; instead
+     * the <code>updateRow</code> or <code>insertRow</code> methods are called
+     * to update the database.
+     * <p>
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param xmlObject the column value
+     * @throws SQLException if a database access error occurs, this method
+     *  is called on a closed result set,
+     * the <code>java.xml.transform.Result</code>,
+     *  <code>Writer</code> or <code>OutputStream</code> has not been closed
+     * for the <code>SQLXML</code> object,
+     *  if there is an error processing the XML value or
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>.  The <code>getCause</code> method
+     *  of the exception may provide a more detailed exception, for example, if the
+     *  stream does not contain valid XML.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateSQLXML(String columnLabel,
+                             SQLXML xmlObject) throws SQLException {
+        updateSQLXML(findColumn(columnLabel), xmlObject);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>String</code> in the Java programming language.
+     * It is intended for use when
+     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public String getNString(int columnIndex) throws SQLException {
+        return getString(columnIndex);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as
+     * a <code>String</code> in the Java programming language.
+     * It is intended for use when
+     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @return the column value; if the value is SQL <code>NULL</code>, the
+     * value returned is <code>null</code>
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public String getNString(String columnLabel) throws SQLException {
+        return getString(findColumn(columnLabel));
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a
+     * <code>java.io.Reader</code> object.
+     * It is intended for use when
+     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     *
+     * @return a <code>java.io.Reader</code> object that contains the column
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language.
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public java.io.Reader getNCharacterStream(
+            int columnIndex) throws SQLException {
+        return getCharacterStream(columnIndex);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Retrieves the value of the designated column in the current row
+     * of this <code>ResultSet</code> object as a
+     * <code>java.io.Reader</code> object.
+     * It is intended for use when
+     * accessing  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @return a <code>java.io.Reader</code> object that contains the column
+     * value; if the value is SQL <code>NULL</code>, the value returned is
+     * <code>null</code> in the Java programming language
+     * @exception SQLException if a database access error occurs
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public java.io.Reader getNCharacterStream(
+            String columnLabel) throws SQLException {
+        return getCharacterStream(findColumn(columnLabel));
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a character stream value, which will have
+     * the specified number of bytes.   The
+     * driver does the necessary conversion from Java character format to
+     * the national character set in the database.
+     * It is intended for use when
+     * updating  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     *
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     * @revised JDK 1.6 b87 - length parameter changed from int to long
+     */
+//#ifdef JAVA6
+    public void updateNCharacterStream(int columnIndex, java.io.Reader x,
+                                       long length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setCharacterStream(columnIndex, x, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a character stream value, which will have
+     * the specified number of bytes.  The
+     * driver does the necessary conversion from Java character format to
+     * the national character set in the database.
+     * It is intended for use when
+     * updating  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     *
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param reader the <code>java.io.Reader</code> object containing
+     *        the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     * @revised JDK 1.6 b87 - length parameter changed from int to long
+     */
+//#ifdef JAVA6
+    public void updateNCharacterStream(String columnLabel,
+                                       java.io.Reader reader,
+                                       long length) throws SQLException {
+        updateCharacterStream(columnLabel, reader, length);
+    }
+
+//#endif JAVA6
+// --------------------------- Added: Mustang Build 86 -------------------------
+
+    /**
+     * Updates the designated column with an ascii stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateAsciiStream(int columnIndex, java.io.InputStream x,
+                                  long length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setAsciiStream(columnIndex, x, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a binary stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateBinaryStream(int columnIndex, java.io.InputStream x,
+                                   long length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setBinaryStream(columnIndex, x, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a character stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateCharacterStream(int columnIndex, java.io.Reader x,
+                                      long length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setCharacterStream(columnIndex, x, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with an ascii stream value, which will have
+     * the specified number of bytes..
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateAsciiStream(String columnLabel, java.io.InputStream x,
+                                  long length) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setAsciiStream(columnIndex, x, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a binary stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param x the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateBinaryStream(String columnLabel, java.io.InputStream x,
+                                   long length) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setBinaryStream(columnIndex, x, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a character stream value, which will have
+     * the specified number of bytes.
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param reader the <code>java.io.Reader</code> object containing
+     *        the new column value
+     * @param length the length of the stream
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateCharacterStream(String columnLabel,
+                                      java.io.Reader reader,
+                                      long length) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setCharacterStream(columnIndex, reader, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column using the given input stream, which
+     * will have the specified number of bytes.
+     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from ASCII to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @param length the number of bytes in the parameter data.
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateBlob(int columnIndex, InputStream inputStream,
+                           long length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setBlob(columnIndex, inputStream, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column using the given input stream, which
+     * will have the specified number of bytes.
+     * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.InputStream</code>. Data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from ASCII to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @param length the number of bytes in the parameter data.
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateBlob(String columnLabel, InputStream inputStream,
+                           long length) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setBlob(columnIndex, inputStream, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column using the given <code>Reader</code>
+     * object, which is the given number of characters long.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateClob(int columnIndex, Reader reader,
+                           long length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setClob(columnIndex, reader, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column using the given <code>Reader</code>
+     * object, which is the given number of characters long.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @exception SQLException if a database access error occurs,
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateClob(String columnLabel, Reader reader,
+                           long length) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setClob(columnIndex, reader, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     *  Updates the designated column using the given <code>Reader</code>
+     *  object, which is the given number of characters long.
+     *  When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     *  parameter, it may be more practical to send it via a
+     *  <code>java.io.Reader</code> object. The data will be read from the stream
+     *  as needed until end-of-file is reached.  The JDBC driver will
+     *  do any necessary conversion from UNICODE to the database char format.
+     *
+     *  <P><B>Note:</B> This stream object can either be a standard
+     *  Java stream object or your own subclass that implements the
+     *  standard interface.
+     *  <p>
+     *  The updater methods are used to update column values in the
+     *  current row or the insert row.  The updater methods do not
+     *  update the underlying database; instead the <code>updateRow</code> or
+     *  <code>insertRow</code> methods are called to update the database.
+     *
+     *  @param columnIndex the first column is 1, the second 2, ...
+     *  @param reader An object that contains the data to set the parameter value to.
+     *  @param length the number of characters in the parameter data.
+     *  @throws SQLException if the driver does not support national
+     *          character sets;  if the driver can detect that a data conversion
+     *   error could occur; this method is called on a closed result set,
+     *  if a database access error occurs or
+     *  the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     *  this method
+     *  @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateNClob(int columnIndex, Reader reader,
+                            long length) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setClob(columnIndex, reader, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column using the given <code>Reader</code>
+     * object, which is the given number of characters long.
+     * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
+     * parameter, it may be more practical to send it via a
+     * <code>java.io.Reader</code> object. The data will be read from the stream
+     * as needed until end-of-file is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <P><B>Note:</B> This stream object can either be a standard
+     * Java stream object or your own subclass that implements the
+     * standard interface.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS
+     * clause.  If the SQL AS clause was not specified, then the label is the
+     * name of the column
+     * @param reader An object that contains the data to set the parameter value to.
+     * @param length the number of characters in the parameter data.
+     * @throws SQLException if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; this method is called on a closed result set;
+     *  if a database access error occurs or
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public void updateNClob(String columnLabel, Reader reader,
+                            long length) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setClob(columnIndex, reader, length);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Updates the designated column with a character stream value.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.  The
+     * driver does the necessary conversion from Java character format to
+     * the national character set in the database.
+     * It is intended for use when
+     * updating  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateNCharacterStream</code> which takes a length parameter.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param reader the new column value
+     * @exception SQLException if the columnIndex is not valid;
+     * if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateNCharacterStream(
+            int columnIndex, java.io.Reader reader) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setCharacterStream(columnIndex, reader);
+    }
+
+    /**
+     * Updates the designated column with a character stream value.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.  The
+     * driver does the necessary conversion from Java character format to
+     * the national character set in the database.
+     * It is intended for use when
+     * updating  <code>NCHAR</code>,<code>NVARCHAR</code>
+     * and <code>LONGNVARCHAR</code> columns.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateNCharacterStream</code> which takes a length parameter.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param reader the <code>java.io.Reader</code> object containing
+     *        the new column value
+     * @exception SQLException if the columnLabel is not valid;
+     * if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateNCharacterStream(
+            String columnLabel, java.io.Reader reader) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setCharacterStream(columnIndex, reader);
+    }
+
+    /**
+     * Updates the designated column with an ascii stream value.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateAsciiStream</code> which takes a length parameter.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if the columnIndex is not valid;
+     * if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateAsciiStream(int columnIndex,
+                                  java.io.InputStream x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setAsciiStream(columnIndex, x);
+    }
+
+    /**
+     * Updates the designated column with a binary stream value.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateBinaryStream</code> which takes a length parameter.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if the columnIndex is not valid;
+     * if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateBinaryStream(int columnIndex,
+                                   java.io.InputStream x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setBinaryStream(columnIndex, x);
+    }
+
+    /**
+     * Updates the designated column with a character stream value.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateCharacterStream</code> which takes a length parameter.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param x the new column value
+     * @exception SQLException if the columnIndex is not valid;
+     * if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateCharacterStream(int columnIndex,
+                                      java.io.Reader x) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setCharacterStream(columnIndex, x);
+    }
+
+    /**
+     * Updates the designated column with an ascii stream value.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateAsciiStream</code> which takes a length parameter.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if the columnLabel is not valid;
+     * if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateAsciiStream(String columnLabel,
+                                  java.io.InputStream x) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setAsciiStream(columnIndex, x);
+    }
+
+    /**
+     * Updates the designated column with a binary stream value.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateBinaryStream</code> which takes a length parameter.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param x the new column value
+     * @exception SQLException if the columnLabel is not valid;
+     * if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateBinaryStream(String columnLabel,
+                                   java.io.InputStream x) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setBinaryStream(columnIndex, x);
+    }
+
+    /**
+     * Updates the designated column with a character stream value.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateCharacterStream</code> which takes a length parameter.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param reader the <code>java.io.Reader</code> object containing
+     *        the new column value
+     * @exception SQLException if the columnLabel is not valid; if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateCharacterStream(
+            String columnLabel, java.io.Reader reader) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setCharacterStream(columnIndex, reader);
+    }
+
+    /**
+     * Updates the designated column using the given input stream. The data will be read from the stream
+     * as needed until end-of-stream is reached.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateBlob</code> which takes a length parameter.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @exception SQLException if the columnIndex is not valid; if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateBlob(int columnIndex,
+                           InputStream inputStream) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setBlob(columnIndex, inputStream);
+    }
+
+    /**
+     * Updates the designated column using the given input stream. The data will be read from the stream
+     * as needed until end-of-stream is reached.
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     *   <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateBlob</code> which takes a length parameter.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param inputStream An object that contains the data to set the parameter
+     * value to.
+     * @exception SQLException if the columnLabel is not valid; if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateBlob(String columnLabel,
+                           InputStream inputStream) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setBlob(columnIndex, inputStream);
+    }
+
+    /**
+     * Updates the designated column using the given <code>Reader</code>
+     * object.
+     *  The data will be read from the stream
+     * as needed until end-of-stream is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     *   <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateClob</code> which takes a length parameter.
+     *
+     * @param columnIndex the first column is 1, the second is 2, ...
+     * @param reader An object that contains the data to set the parameter value to.
+     * @exception SQLException if the columnIndex is not valid;
+     * if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateClob(int columnIndex,
+                           Reader reader) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setClob(columnIndex, reader);
+    }
+
+    /**
+     * Updates the designated column using the given <code>Reader</code>
+     * object.
+     *  The data will be read from the stream
+     * as needed until end-of-stream is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateClob</code> which takes a length parameter.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param reader An object that contains the data to set the parameter value to.
+     * @exception SQLException if the columnLabel is not valid; if a database access error occurs;
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * or this method is called on a closed result set
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateClob(String columnLabel,
+                           Reader reader) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setClob(columnIndex, reader);
+    }
+
+    /**
+     *  Updates the designated column using the given <code>Reader</code>
+     *
+     *  The data will be read from the stream
+     *  as needed until end-of-stream is reached.  The JDBC driver will
+     *  do any necessary conversion from UNICODE to the database char format.
+     *
+     *  <p>
+     *  The updater methods are used to update column values in the
+     *  current row or the insert row.  The updater methods do not
+     *  update the underlying database; instead the <code>updateRow</code> or
+     *  <code>insertRow</code> methods are called to update the database.
+     *
+     *  <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     *  it might be more efficient to use a version of
+     *  <code>updateNClob</code> which takes a length parameter.
+     *
+     *  @param columnIndex the first column is 1, the second 2, ...
+     *  @param reader An object that contains the data to set the parameter value to.
+     *  @throws SQLException if the columnIndex is not valid;
+     * if the driver does not support national
+     *          character sets;  if the driver can detect that a data conversion
+     *   error could occur; this method is called on a closed result set,
+     *  if a database access error occurs or
+     *  the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     *  @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     *  this method
+     *  @since 1.6
+     */
+    public void updateNClob(int columnIndex,
+                            Reader reader) throws SQLException {
+        startUpdate(columnIndex);
+        preparedStatement.setClob(columnIndex, reader);
+    }
+
+    /**
+     * Updates the designated column using the given <code>Reader</code>
+     * object.
+     * The data will be read from the stream
+     * as needed until end-of-stream is reached.  The JDBC driver will
+     * do any necessary conversion from UNICODE to the database char format.
+     *
+     * <p>
+     * The updater methods are used to update column values in the
+     * current row or the insert row.  The updater methods do not
+     * update the underlying database; instead the <code>updateRow</code> or
+     * <code>insertRow</code> methods are called to update the database.
+     *
+     * <P><B>Note:</B> Consult your JDBC driver documentation to determine if
+     * it might be more efficient to use a version of
+     * <code>updateNClob</code> which takes a length parameter.
+     *
+     * @param columnLabel the label for the column specified with the SQL AS clause.  If the SQL AS clause was not specified, then the label is the name of the column
+     * @param reader An object that contains the data to set the parameter value to.
+     * @throws SQLException if the columnLabel is not valid; if the driver does not support national
+     *         character sets;  if the driver can detect that a data conversion
+     *  error could occur; this method is called on a closed result set;
+     *  if a database access error occurs or
+     * the result set concurrency is <code>CONCUR_READ_ONLY</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.6
+     */
+    public void updateNClob(String columnLabel,
+                            Reader reader) throws SQLException {
+
+        int columnIndex = findColumn(columnLabel);
+
+        startUpdate(columnIndex);
+        preparedStatement.setClob(columnIndex, reader);
+    }
+
+    // --------------------- java.sql.Wrapper implementation -------------------
+
+    /**
+     * Returns an object that implements the given interface to allow access to
+     * non-standard methods, or standard methods not exposed by the proxy.
+     *
+     * If the receiver implements the interface then the result is the receiver
+     * or a proxy for the receiver. If the receiver is a wrapper
+     * and the wrapped object implements the interface then the result is the
+     * wrapped object or a proxy for the wrapped object. Otherwise return the
+     * the result of calling <code>unwrap</code> recursively on the wrapped object
+     * or a proxy for that result. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+    public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+//------------------------ Internal Implementation -----------------------------
+
+    /** The internal representation. */
+    private RowSetNavigator navigator;
+
+    /** The internal representation. */
+    private ResultMetaData resultMetaData;
+
+    /** How many columns does this ResultSet have? */
+    int columnCount;
+
+    /** Did the last getXXX method encounter a null value? */
+    private boolean wasNullValue;
+
+    /** The ResultSetMetaData object for this ResultSet */
+    private ResultSetMetaData resultSetMetaData;
+
+    /** JDBCConnection for this. */
+    private JDBCConnection connection;
+
+    /** Accelerates findColumn; Map<columnName, columnIndex> */
+    private IntValueHashMap columnMap;
+
+    /** The first warning in the chain. Null if there are no warnings. */
+    protected SQLWarning rootWarning;
+
+    /** The underlying result. */
+    public Result result;
+
+    //-------------------------- Package Attributes ----------------------------
+
+    /**
+     * The Statement that generated this result. Null if the result is
+     * from DatabaseMetaData<p>
+     */
+    JDBCStatementBase statement;
+    SessionInterface  session;
+
+    /**
+     * The scrollability / scroll sensitivity type of this result.
+     */
+    boolean isScrollable;
+
+    /** The concurrency of this result. */
+    boolean isReadOnly;
+
+    /** The updatability of this result. */
+    boolean isUpdatable;
+
+    /** The insertability of this result. */
+    boolean isInsertable;
+    int     rsProperties;
+    int     fetchSize;
+
+    /** Statement is closed when its result set is closed */
+    boolean autoClose;
+
+    // ---------------------- Public Attributes --------------------------------
+    // Support for JDBC 2 from JRE 1.1.x
+
+    /** Copy of java.sql.ResultSet constant, for JDK 1.1 clients. */
+    public static final int FETCH_FORWARD = 1000;
+
+    /** Copy of java.sql.ResultSet constant, for JDK 1.1 clients. */
+    public static final int FETCH_REVERSE = 1001;
+
+    /** Copy of java.sql.ResultSet constant, for JDK 1.1 clients. */
+    public static final int FETCH_UNKNOWN = 1002;
+
+    /** Copy of java.sql.ResultSet constant, for JDK 1.1 clients. */
+    public static final int TYPE_FORWARD_ONLY = 1003;
+
+    /**
+     * Copy of java.sql.ResultSet constant, for JDK 1.1 clients. <p>
+     *
+     *  (JDBC4 clarification:) scrollable but generally not sensitive
+     *  to changes to the data that underlies the <code>ResultSet</code>.
+     */
+    public static final int TYPE_SCROLL_INSENSITIVE = 1004;
+
+    /**
+     * Copy of java.sql.ResultSet constant, for JDK 1.1 clients. <p>
+     *
+     *  (JDBC4 clarification:) scrollable and generally sensitive
+     *  to changes to the data that underlies the <code>ResultSet</code>.
+     */
+    public static final int TYPE_SCROLL_SENSITIVE = 1005;
+
+    /** Copy of java.sql.ResultSet constant, for JDK 1.1 clients. */
+    public static final int CONCUR_READ_ONLY = 1007;
+
+    /** Copy of java.sql.ResultSet constant, for JDK 1.1 clients. */
+    public static final int CONCUR_UPDATABLE = 1008;
+
+    /** Copy of java.sql.ResultSet constant, for JDK 1.1 clients. */
+    public static final int HOLD_CURSORS_OVER_COMMIT = 1;
+
+    /** Copy of java.sql.ResultSet constant, for JDK 1.1 clients. */
+    public static final int CLOSE_CURSORS_AT_COMMIT = 2;
+
+    //-------------------------- Private Methods -------------------------------
+
+    /**
+     * Fetches the current row of the result set.
+     *
+     * @throws SQLException when result set is closed; result set is empty;
+     *   result set is before first; result set is alfter last; no row data is
+     *   available.
+     * @return Object[]
+     */
+    private Object[] getCurrent() throws SQLException {
+
+        final RowSetNavigator lnavigator = this.navigator;
+
+        if (lnavigator == null) {
+            throw Util.sqlException(ErrorCode.X_24501);
+        } else if (lnavigator.isEmpty()) {
+            throw Util.sqlException(ErrorCode.X_24504, ErrorCode.M_RS_EMPTY);
+        } else if (lnavigator.isBeforeFirst()) {
+            throw Util.sqlException(ErrorCode.X_24504,
+                                    ErrorCode.M_RS_BEFORE_FIRST);
+        } else if (lnavigator.isAfterLast()) {
+            throw Util.sqlException(ErrorCode.X_24504,
+                                    ErrorCode.M_RS_AFTER_LAST);
+        }
+
+        Object[] data = lnavigator.getCurrent();
+
+        if (data == null) {
+            throw Util.sqlException(ErrorCode.X_24501);
+        }
+
+        return data;
+    }
+
+    /**
+     * Internal closed state check.
+     *
+     * @throws SQLException when this result set is closed
+     */
+    private void checkClosed() throws SQLException {
+
+        if (navigator == null) {
+            throw Util.sqlException(ErrorCode.X_24501);
+        }
+    }
+
+    /**
+     * Internal column index validity check.
+     *
+     * @param columnIndex to check
+     * @throws SQLException when this ResultSet has no such column
+     */
+    private void checkColumn(int columnIndex) throws SQLException {
+
+        if (navigator == null) {
+            throw Util.sqlException(ErrorCode.X_24501);
+        }
+
+        if (columnIndex < 1 || columnIndex > columnCount) {
+            throw Util.sqlException(ErrorCode.JDBC_COLUMN_NOT_FOUND,
+                                    String.valueOf(columnIndex));
+        }
+    }
+
+    /**
+     * Internal wasNull tracker.
+     *
+     * @param o the Object to track
+     * @return boolean
+     */
+    private boolean trackNull(Object o) {
+        return (wasNullValue = (o == null));
+    }
+
+    /**
+     * Internal value converter. <p>
+     *
+     * All trivially successful getXXX methods eventually go through this
+     * method, converting if neccessary from the source type to the
+     * requested type.  <p>
+     *
+     * Conversion to the JDBC representation, if different, is handled by the
+     * calling methods.
+     *
+     * @param columnIndex of the column value for which to perform the
+     *                 conversion
+     * @param targetType the org.hsqldb.types.Type object for targetType
+     * @return an Object of the requested targetType, representing the value of the
+     *       specified column
+     * @throws SQLException when there is no rowData, the column index is
+     *    invalid, or the conversion cannot be performed
+     */
+    private Object getColumnInType(int columnIndex,
+                                   Type targetType) throws SQLException {
+
+        Object[] rowData = getCurrent();
+        Type     sourceType;
+        Object   value;
+
+        checkColumn(columnIndex);
+
+        sourceType = resultMetaData.columnTypes[--columnIndex];
+        value      = rowData[columnIndex];
+
+        if (trackNull(value)) {
+            return null;
+        }
+
+        if (sourceType.typeCode != targetType.typeCode) {
+            try {
+                value = targetType.convertToTypeJDBC(session, value,
+                        sourceType);
+            } catch (Exception e) {
+                String stringValue = (value instanceof Number
+                                      || value
+                                         instanceof String) ? value.toString()
+                        : "instance of " + value.getClass().getName();
+                String msg = "from SQL type " + sourceType.getNameString()
+                             + " to " + targetType.getJDBCClassName()
+                             + ", value: " + stringValue;
+
+                Util.throwError(Error.error(ErrorCode.X_42561, msg));
+            }
+        }
+
+        return value;
+    }
+
+    private void checkNotForwardOnly() throws SQLException {
+
+        if (!isScrollable) {
+            throw Util.notSupported();
+        }
+    }
+
+    //-------------------------- Updates --------------------------------------
+    JDBCPreparedStatement preparedStatement;
+    boolean               isRowUpdated;
+    boolean               isOnInsertRow;
+
+    /**
+     * -2 after moveToInsertRow()
+     * -1 before any updateXXX()
+     * row number after any updateXXX()
+     * -1 after updateRow(), clearUpdate() or moveToCurrentRow();
+     */
+    int currentUpdateRowNumber;
+
+    private void checkUpdatable() throws SQLException {
+
+        checkClosed();
+
+        if (!isUpdatable) {
+            throw Util.notUpdatableColumn();
+        }
+    }
+
+    private void checkUpdatable(int columnIndex) throws SQLException {
+
+        checkClosed();
+        checkColumn(columnIndex);
+
+        if (!isUpdatable) {
+            throw Util.notUpdatableColumn();
+        }
+
+        if (resultMetaData.colIndexes[--columnIndex] == -1) {
+            throw Util.notUpdatableColumn();
+        }
+
+        if (!resultMetaData.columns[columnIndex].isWriteable()) {
+            throw Util.notUpdatableColumn();
+        }
+    }
+
+    void startUpdate(int columnIndex) throws SQLException {
+
+        checkUpdatable(columnIndex);
+
+        if (currentUpdateRowNumber != navigator.getRowNumber()) {
+            preparedStatement.clearParameters();
+        }
+        currentUpdateRowNumber = navigator.getRowNumber();
+        isRowUpdated           = true;
+    }
+
+    private void clearUpdates() throws SQLException {
+
+        checkUpdatable();
+        preparedStatement.clearParameters();
+
+        isRowUpdated = false;
+    }
+
+    private void startInsert() throws SQLException {
+
+        checkUpdatable();
+
+        // check insertable
+        isOnInsertRow = true;
+    }
+
+    private void endInsert() throws SQLException {
+
+        checkUpdatable();
+        preparedStatement.clearParameters();
+
+        isOnInsertRow = false;
+    }
+
+    private void performUpdate() throws SQLException {
+
+        preparedStatement.parameterValues[columnCount] =
+            getCurrent()[columnCount];
+
+        for (int i = 0; i < columnCount; i++) {
+            boolean set = preparedStatement.parameterSet[i]
+                          || preparedStatement.parameterStream[i];
+
+            preparedStatement.resultOut.metaData.columnTypes[i] = set
+                    ? preparedStatement.parameterTypes[i]
+                    : Type.SQL_ALL_TYPES;
+        }
+        preparedStatement.resultOut.setActionType(
+            ResultConstants.UPDATE_CURSOR);
+        preparedStatement.fetchResult();
+        preparedStatement.clearParameters();
+
+        rootWarning = preparedStatement.getWarnings();
+
+        preparedStatement.clearWarnings();
+
+        isRowUpdated = false;
+    }
+
+    private void performInsert() throws SQLException {
+
+        checkUpdatable();
+
+        for (int i = 0; i < columnCount; i++) {
+            boolean set = preparedStatement.parameterSet[i]
+                          || preparedStatement.parameterStream[i];
+
+            if (!set) {
+                throw Util.sqlException(ErrorCode.X_24515);
+            }
+            preparedStatement.resultOut.metaData.columnTypes[i] =
+                preparedStatement.parameterTypes[i];
+        }
+        preparedStatement.resultOut.setActionType(
+            ResultConstants.INSERT_CURSOR);
+        preparedStatement.fetchResult();
+        preparedStatement.clearParameters();
+
+        rootWarning = preparedStatement.getWarnings();
+
+        preparedStatement.clearWarnings();
+    }
+
+    private void performDelete() throws SQLException {
+
+        checkUpdatable();
+
+        preparedStatement.parameterValues[columnCount] =
+            getCurrent()[columnCount];
+        preparedStatement.resultOut.metaData.columnTypes[columnCount] =
+            resultMetaData.columnTypes[columnCount];
+
+        preparedStatement.resultOut.setActionType(
+            ResultConstants.DELETE_CURSOR);
+        preparedStatement.fetchResult();
+        preparedStatement.clearParameters();
+
+        rootWarning = preparedStatement.getWarnings();
+
+        preparedStatement.clearWarnings();
+    }
+
+    //-------------------------- Other Methods --------------------------------
+    // HSQLDB Specific
+    RowSetNavigator getNavigator() {
+        return navigator;
+    }
+
+    void setNavigator(RowSetNavigator navigator) {
+        this.navigator = navigator;
+    }
+
+    //------------------------------ Contructors -------------------------------
+
+    /**
+     * Constructs a new <code>JDBCResultSet</code> object using the specified
+     * navigator and <code>org.hsqldb.result.ResultMetaData</code>.
+     * <p>
+     *
+     * @param conn JDBCConnection
+     * @param s the statement
+     * @param r the internal result form that the new
+     *   <code>JDBCResultSet</code> represents
+     * @param metaData the connection properties
+     * @throws SQLException when the supplied Result is of type
+     *   org.hsqldb.Result.ERROR
+     */
+    public JDBCResultSet(JDBCConnection conn, JDBCStatementBase s, Result r,
+                  ResultMetaData metaData) throws SQLException {
+
+        this.session     = conn.sessionProxy;
+        this.statement   = s;
+        this.result      = r;
+        this.connection = conn;
+        rsProperties     = r.rsProperties;
+        navigator        = r.getNavigator();
+        resultMetaData   = metaData;
+        columnCount      = resultMetaData.getColumnCount();
+        isScrollable     = ResultProperties.isScrollable(rsProperties);
+
+        if (ResultProperties.isUpdatable(rsProperties)) {
+            isUpdatable  = true;
+            isInsertable = true;
+
+            for (int i = 0; i < metaData.colIndexes.length; i++) {
+                if (metaData.colIndexes[i] < 0) {
+                    isInsertable = false;
+
+                    break;
+                }
+            }
+            preparedStatement = new JDBCPreparedStatement(s.connection,
+                    result);
+        }
+    }
+
+    public JDBCResultSet(JDBCConnection conn, Result r,
+                  ResultMetaData metaData) throws SQLException {
+
+        this.session     = conn.sessionProxy;
+        this.result      = r;
+        this.connection = conn;
+        rsProperties     = 0;
+        navigator        = r.getNavigator();
+        resultMetaData   = metaData;
+        columnCount      = resultMetaData.getColumnCount();
+    }
+
+}
diff --git a/src/org/hsqldb/jdbc/JDBCResultSetMetaData.java b/src/org/hsqldb/jdbc/JDBCResultSetMetaData.java
new file mode 100644
index 0000000..aa738cc
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCResultSetMetaData.java
@@ -0,0 +1,1054 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/* $Id: JDBCResultSetMetaData.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+// fredt@users    - 20040412 - removed DITypeInfo dependencies
+// boucherb@users - 200404xx - removed unused imports;refinement for better
+//                             usability of getColumnDisplaySize;
+//                             javadoc updates
+// boucherb@users - 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+// boucherb@users - 20060522 - doc   1.9.0 full synch up to Mustang Build 84
+// fredt@users - 1.9.0 usage of types and new ResultMetadata and ColumnMetaData
+// Revision 1.15  2006/07/12 12:29:42  boucherb
+// patch 1.9.0
+// - full synch up to Mustang b90
+// - minor update to toString
+
+/**
+ * <!-- start generic documentation -->
+ * An object that can be used to get information about the types
+ * and properties of the columns in a <code>ResultSet</code> object.
+ * The following code fragment creates the <code>ResultSet</code> object rs,
+ * creates the <code>ResultSetMetaData</code> object rsmd, and uses rsmd
+ * to find out how many columns rs has and whether the first column in rs
+ * can be used in a <code>WHERE</code> clause.
+ * <PRE>
+ *
+ *     ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
+ *     ResultSetMetaData rsmd = rs.getMetaData();
+ *     int numberOfColumns = rsmd.getColumnCount();
+ *     boolean b = rsmd.isSearchable(1);
+ *
+ * </PRE>
+ * <!-- end generic documentation -->
+ *
+ * <!-- start Release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * HSQLDB supports a subset of the <code>ResultSetMetaData</code> interface.<p>
+ *
+ * The JDBC specification for <code>ResultSetMetaData</code> is in part very
+ * vague. This causes potential incompatibility between interpretations of the
+ * specification as realized in different JDBC driver implementations. As such,
+ * deciding to what degree reporting ResultSetMetaData is accurate has been
+ * considered very carefully. Hopefully, the design decisions made in light of
+ * these considerations have yeilded precisely the subset of full
+ * ResultSetMetaData support that is most commonly needed and that is most
+ * important, while also providing, under the most common use-cases, the
+ * fastest access with the least overhead and the best comprimise between
+ * speed, accuracy, jar-footprint and retention of JDBC resources. <p>
+ *
+ * (fredt@users) <br>
+ * (boucherb@users)<p>
+ * </div>
+ * <!-- end release-specific documentation -->
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @revised JDK 1.6, HSQLDB 2.0
+ * @see JDBCStatement#executeQuery
+ * @see JDBCStatement#getResultSet
+ * @see java.sql.ResultSetMetaData
+ */
+public class JDBCResultSetMetaData implements ResultSetMetaData {
+
+    /**
+     * <!-- start generic documentation -->
+     * Returns the number of columns in this <code>ResultSet</code> object.
+     *
+     * <!-- end generic documentation -->
+     * @return the number of columns
+     * @exception SQLException if a database access error occurs
+     */
+    public int getColumnCount() throws SQLException {
+        return resultMetaData.getColumnCount();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates whether the designated column is automatically numbered.
+     * <p>(JDBC4 deleted:)[, thus read-only.]
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 fully supports SQL Satandard features T174 and T176 that
+     * define identity column support.
+     *
+     * <hr>
+     *
+     * However, it must be stated here that contrary to the generic
+     * documentation previous to the JDBC4 specification, HSQLDB automatically
+     * numbered columns (IDENTITY columns, in HSQLDB parlance) are not
+     * read-only. <p>
+     *
+     * In fact, the generic documentation previous to the JDBC4 specification
+     * seems to contradict the general definition of what, at minimum,
+     * an auto-increment column is: <p>
+     *
+     * Simply, an auto-increment column is one that guarantees it has a
+     * autogenerated value after a successful insert or update operation,
+     * even if no value is supplied, or DEFAULT is specified.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isAutoIncrement(int column) throws SQLException {
+
+        checkColumn(column);
+
+        return resultMetaData.columns[--column].isIdentity();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates whether a column's case matters.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 1.7.1 did not report this value accurately.  <p>
+     *
+     * Starting with 1.7.2, this feature is better supported.  <p>
+     *
+     * This method returns true for any column whose data type is a character
+     * type, with the exception of VARCHAR_IGNORECASE for which it returns
+     * false. It also returns false for any column whose data type is a
+     * not a character data type. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isCaseSensitive(int column) throws SQLException {
+
+        checkColumn(column);
+
+        Type type = translateType(resultMetaData.columnTypes[--column]);
+
+        if (type.isCharacterType()) {
+            return !((CharacterType) type).isCaseInsensitive();
+        }
+
+        return false;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates whether the designated column can be used in a where clause.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 handles this differently from previous versions. <p>
+     *
+     * If the column in question is a database table or view column, and the
+     * type of the column allows searching, then returns true, otherwise false.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isSearchable(int column) throws SQLException {
+
+        checkColumn(column);
+
+        return resultMetaData.columns[--column].isSearchable();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates whether the designated column is a cash value.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 fully supports this feature and returns true for
+     * NUMERIC and DECIMAL columns. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isCurrency(int column) throws SQLException {
+
+        checkColumn(column);
+
+        Type type = translateType(resultMetaData.columnTypes[--column]);
+
+        return (type.typeCode == Types.SQL_DECIMAL
+                || type.typeCode == Types.SQL_NUMERIC) && type.scale > 0;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates the nullability of values in the designated column.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 fully supports this feature.  <p>
+     *
+     * <tt>columnNoNulls</tt> is always returned for result set columns
+     * that do not directly represent table column values (i.e. are calculated),
+     * while the corresponding value in [INFORMATION_SCHEMA.]SYSTEM_COLUMNS.NULLABLE
+     * is returned for result set columns that do directly represent table
+     * column values. <p>
+     *
+     * To determine the nullable status of a table column in isolation from
+     * ResultSetMetaData and in a DBMS-independent fashion, the
+     * DatabaseMetaData.getColumns() method can be invoked with the
+     * appropriate filter values and the result should be inspected at the
+     * position described in the DatabaseMetaData.getColumns() API
+     * documentation.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return the nullability status of the given column; one of <code>columnNoNulls</code>,
+     *          <code>columnNullable</code> or <code>columnNullableUnknown</code>
+     * @exception SQLException if a database access error occurs
+     */
+    public int isNullable(int column) throws SQLException {
+
+        checkColumn(column);
+
+        return resultMetaData.columns[--column].getNullability();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates whether values in the designated column are signed numbers.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 fully supports this feature.  <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isSigned(int column) throws SQLException {
+
+        checkColumn(column);
+
+        Type type = translateType(resultMetaData.columnTypes[--column]);
+
+        return type.isNumberType();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates the designated column's normal maximum width in characters.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 fully supports this feature.  <p>
+     *
+     * The current calculation follows these rules: <p>
+     *
+     * <ol>
+     * <li>Long character types and datetime types:<p>
+     *
+     *     The maximum length/precision, repectively.<p>
+     *
+     * <li>CHAR and VARCHAR types: <p>
+     *
+     *      <ul>
+     *      <li> If the result set column is a direct pass through of a table
+     *           column value and column size was declared, then the declared
+     *           value is returned. <p>
+     *
+     *      <li> Otherwise, the computed length according to SQL Standard is
+     *           returned. For very large values, the value of the system property
+     *           hsqldb.max_xxxchar_display_size or the magic value
+     *           32766 (0x7FFE) (tested usable/accepted by most tools and
+     *           compatible with assumptions made by java.io read/write
+     *           UTF) when the system property is not defined or is not
+     *           accessible, due to security constraints. <p>
+     *
+     *      </ul>
+     *
+     *      It must be noted that the latter value in no way affects the
+     *      ability of the HSQLDB JDBC driver to retrieve longer values
+     *      and serves only as the current best effort at providing a
+     *      value that maximizes usability across a wide range of tools,
+     *      given that the HSQLDB database engine allows very large
+     *      lengths to be declared. <p>
+     *
+     * <li>Number types: <p>
+     *
+     *     The max precision, plus the length of the negation character (1),
+     *     plus (if applicable) the maximum number of characters that may
+     *     occupy the exponent character sequence.  Note that some legacy tools
+     *     do not correctly handle BIGINT values of greater than 18 digits. <p>
+     *
+     * <li>BOOLEAN type: <p>
+     *
+     *     The length of the character sequence "false" (5), the longer of the
+     *     two boolean value String representations. <p>
+     *
+     * <li>Remaining types: <p>
+     *
+     *     The maximum length/precision, respectively, as reported by
+     *     DatabaseMetaData.getTypeInfo(), when applicable.  If the maximum
+     *     display size is unknown, unknowable or inapplicable, then zero is
+     *     returned. <p>
+     *
+     * </ol>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return the normal maximum number of characters allowed as the width
+     *          of the designated column
+     * @exception SQLException if a database access error occurs
+     */
+    public int getColumnDisplaySize(int column) throws SQLException {
+
+        checkColumn(column);
+
+        Type type = translateType(resultMetaData.columnTypes[--column]);
+
+        return type.displaySize();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Gets the designated column's suggested title for use in printouts and
+     * displays. (JDBC4 clarification:) The suggested title is usually specified by the SQL <code>AS</code>
+     * clause.  If a SQL <code>AS</code> is not specified, the value returned from
+     * <code>getColumnLabel</code> will be the same as the value returned by the
+     * <code>getColumnName</code> method.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * In HSQLDB, a <code>ResultSet</code> column label is determined using the
+     * following order of precedence:<p>
+     *
+     * <OL>
+     * <LI>The label (alias) specified in the generating query.</LI>
+     * <LI>The name of the underlying column, if no label is specified.<br>
+     * <L1>C1, C2, etc. for computed columns that have no label.</LI>
+     * </OL> <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return the suggested column title
+     * @exception SQLException if a database access error occurs
+     */
+    public String getColumnLabel(int column) throws SQLException {
+
+        checkColumn(column--);
+
+        String label = resultMetaData.columnLabels[column];
+
+        if (label != null && label.length() > 0) {
+            return label;
+        }
+
+        return resultMetaData.columns[column].getNameString();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Get the designated column's name.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * In HSQLDB, a ResultSet column name is determined using the following
+     * order of prcedence:<p>
+     *
+     * <OL>
+     * <LI>The name of the underlying columnm, if the ResultSet column
+     *   represents a column in a table.</LI>
+     * <LI>The label or alias specified in the generating query.</LI>
+     * <L1>C1, C2, etc. for computed columns that have no label.</LI>
+     * </OL> <p>
+     *
+     * If the <code>jdbc.get_column_name</code> property of the JDBC Connection
+     * has been set to false, this method returns the same value as
+     * {@link #getColumnLabel(int)}.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return column name
+     * @exception SQLException if a database access error occurs
+     */
+    public String getColumnName(int column) throws SQLException {
+
+        checkColumn(column--);
+
+        if (useColumnName) {
+            String name = resultMetaData.columns[column].getNameString();
+
+            if (name != null && name.length() > 0) {
+                return name;
+            }
+        }
+
+        String label = resultMetaData.columnLabels[column];
+
+        return label == null ? resultMetaData.columns[column].getNameString()
+                             : label;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Get the designated column's table's schema.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Since 1.8.0.x, HSQLDB implements standard SQL SCHEMA support;
+     * this method returns the actual schema of the column's table.
+     * Columns generated in queries have no schema name.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return schema name or "" if not applicable
+     * @exception SQLException if a database access error occurs
+     */
+    public String getSchemaName(int column) throws SQLException {
+
+        checkColumn(column);
+
+        String name = resultMetaData.columns[--column].getSchemaNameString();;
+
+        return name == null ? ""
+                            : name;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Get the designated column's specified column size.
+     * For numeric data, this is the maximum precision.  For character data, this is the [maximum] length in characters.
+     * For datetime datatypes, this is the [maximim] length in characters of the String representation (assuming the
+     * maximum allowed precision of the fractional seconds component). For binary data, this is the [maximum] length in bytes.  For the ROWID datatype,
+     * this is the length in bytes[, as returned by the implementation-specific java.sql.RowId.getBytes() method]. 0 is returned for data types where the
+     * column size is not applicable.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.8.0, HSQLDB reports the declared length or precision
+     * specifiers for table columns, if they are defined.<p>
+     *
+     * From 2.0, HSQLDB, reports the correct length or precision for
+     * computed columns according to the SQL Standard.<p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return precision
+     * @exception SQLException if a database access error occurs
+     */
+    public int getPrecision(int column) throws SQLException {
+
+        checkColumn(column);
+
+        // type in columnTypes overrides column type
+        Type type      = translateType(resultMetaData.columnTypes[--column]);
+        long precision = type.precision;
+
+        if (type.isDateTimeType() || type.isIntervalType()) {
+            precision = type.displaySize();
+        }
+
+        if (precision > Integer.MAX_VALUE) {
+            precision = Integer.MAX_VALUE;
+        }
+
+        return (int) precision;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Gets the designated column's number of digits to right of the decimal point.
+     * 0 is returned for data types where the scale is not applicable.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.8.0, HSQLDB reports the declared
+     * scale for table columns.<p>
+     *
+     * From 2.0, HSQLDB, reports the correct scale for
+     * computed columns according to the SQL Standard.<p>
+     *
+     * <pre>
+     * sql.enforce_strict_size
+     * </pre>
+     * For datetime and interval types such as Timestamp or Time, the
+     * fractional second precision is reported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return scale
+     * @exception SQLException if a database access error occurs
+     */
+    public int getScale(int column) throws SQLException {
+
+        Type type = translateType(resultMetaData.columnTypes[--column]);
+
+        return type.scale;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Gets the designated column's table name.
+     *
+     * <!-- end generic documentation -->
+     * @param column the first column is 1, the second is 2, ...
+     * @return table name or "" if not applicable
+     * @exception SQLException if a database access error occurs
+     */
+    public String getTableName(int column) throws SQLException {
+
+        checkColumn(column);
+
+        String name = resultMetaData.columns[--column].getTableNameString();
+
+        return name == null ? ""
+                            : name;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Gets the designated column's table's catalog name.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0, HSQLDB returns the name of the catalog. The default name is
+     * PUBLIC.
+     * This value can be changed for the database using an SQL command.<p>
+     *
+     * HSQLDB supports use of catalog qualification in DLL or DML when it is
+     * allowed by the Standard. <p>
+     *
+     * However, not all clients respect the SQL Standard and may use a
+     * catalog qualifier in a context where it is not suppoted by the Standard.
+     * <p>
+     *
+     * For greater detail, see discussion at:
+     * {@link JDBCDatabaseMetaData}. <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return the name of the catalog for the table in which the given column
+     *          appears or "" if not applicable
+     * @exception SQLException if a database access error occurs
+     */
+    public String getCatalogName(int column) throws SQLException {
+
+        checkColumn(column);
+
+        String name = resultMetaData.columns[--column].getCatalogNameString();
+
+        return name == null ? ""
+                            : name;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the designated column's SQL type.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * This reports the SQL type code of the column. For time and timestamp
+     * types that are WITH TIME ZONE, the values as the SQL Standarc CLI
+     * codes.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return SQL type from java.sql.Types
+     * @exception SQLException if a database access error occurs
+     * @see java.sql.Types
+     */
+    public int getColumnType(int column) throws SQLException {
+
+        checkColumn(column);
+
+        Type type = translateType(resultMetaData.columnTypes[--column]);
+
+        return type.getJDBCTypeCode();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the designated column's database-specific type name.
+     * <!-- end generic documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return type name used by the database. If the column type is
+     * a user-defined type, then a fully-qualified type name is returned.
+     * @exception SQLException if a database access error occurs
+     */
+    public String getColumnTypeName(int column) throws SQLException {
+
+        checkColumn(column);
+
+        Type type = translateType(resultMetaData.columnTypes[--column]);
+
+        return type.getNameString();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates whether the designated column is definitely not writable.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0 this method returns true if the ResuleSet is not updatable
+     * or the column in question is not updatable.<p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isReadOnly(int column) throws SQLException {
+
+        checkColumn(column);
+
+        return !resultMetaData.columns[--column].isWriteable();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates whether it is possible for a write on the designated column to
+     * succeed.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0 this method returns false if the ResuleSet is not updatable
+     * or the column in question is not updatable.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isWritable(int column) throws SQLException {
+
+        checkColumn(column);
+
+        return resultMetaData.colIndexes != null
+               && resultMetaData.colIndexes[--column] > -1;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Indicates whether a write on the designated column will definitely succeed.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * From 2.0 this method returns false if the ResuleSet is not updatable
+     * or the column in question is not updatable.<p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return <code>true</code> if so; <code>false</code> otherwise
+     * @exception SQLException if a database access error occurs
+     */
+    public boolean isDefinitelyWritable(int column) throws SQLException {
+
+        checkColumn(column);
+
+        return resultMetaData.colIndexes != null
+               && resultMetaData.colIndexes[--column] > -1;
+    }
+
+    //--------------------------JDBC 2.0-----------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * <p>Returns the fully-qualified name of the Java class whose instances
+     * are manufactured if the method <code>ResultSet.getObject</code>
+     * is called to retrieve a value
+     * from the column.  <code>ResultSet.getObject</code> may return a subclass of the
+     * class returned by this method.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start Release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 2.0 fully supports this feature.<p>
+     *
+     * For columns of type OTHER, there is no specific class name and
+     * java.lang.Object is returned.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param column the first column is 1, the second is 2, ...
+     * @return the fully-qualified name of the class in the Java programming
+     *         language that would be used by the method
+     * <code>ResultSet.getObject</code> to retrieve the value in the specified
+     * column. This is the class name used for custom mapping.
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview for
+     *      JDBCResultSet)
+     */
+    public String getColumnClassName(int column) throws SQLException {
+
+        checkColumn(column);
+
+        Type type = translateType(resultMetaData.columnTypes[--column]);
+
+        return type.getJDBCClassName();
+    }
+
+    //----------------------------- JDBC 4.0 -----------------------------------
+    // ------------------- java.sql.Wrapper implementation ---------------------
+
+    /**
+     * Returns an object that implements the given interface to allow access to
+     * non-standard methods, or standard methods not exposed by the proxy.
+     *
+     * If the receiver implements the interface then the result is the receiver
+     * or a proxy for the receiver. If the receiver is a wrapper
+     * and the wrapped object implements the interface then the result is the
+     * wrapped object or a proxy for the wrapped object. Otherwise return the
+     * the result of calling <code>unwrap</code> recursively on the wrapped object
+     * or a proxy for that result. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+    public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+// ------------------------- Internal Implementation ---------------------------
+    private ResultMetaData resultMetaData;
+
+    /**
+     * Whether to use the underlying column name or label when reporting
+     * getColumnName().
+     */
+    private boolean useColumnName;
+    private boolean translateDTIType;
+    private int     columnCount;
+
+    /**
+     * Constructs a new JDBCResultSetMetaData object from the specified
+     * JDBCResultSet and HsqlProprties objects.
+     *
+     * @param meta the ResultMetaData object from which to construct a new
+     *        JDBCResultSetMetaData object
+     * @param props the HsqlProperties object from which to construct a
+     *        new JDBCResultSetMetaData object
+     * @throws SQLException if a database access error occurs
+     */
+    JDBCResultSetMetaData(ResultMetaData meta, boolean isUpdatable,
+                          boolean isInsertable,
+                          JDBCConnection conn) throws SQLException {
+        init(meta, conn);
+    }
+
+    /**
+     *  Initializes this JDBCResultSetMetaData object from the specified
+     *  Result and HsqlProperties objects.
+     *
+     *  @param meta the ResultMetaData object from which to initialize this
+     *         JDBCResultSetMetaData object
+     *  @param conn the JDBCConnection
+     *  @throws SQLException if a database access error occurs
+     */
+    void init(ResultMetaData meta, JDBCConnection conn) throws SQLException {
+
+        resultMetaData = meta;
+        columnCount    = resultMetaData.getColumnCount();
+
+        // fredt -  props is null for internal connections, so always use the
+        //          default behaviour in this case
+        // JDBCDriver.getPropertyInfo says
+        // default is true
+        useColumnName = true;
+
+        if (conn.connProperties != null) {
+            useColumnName = conn.connProperties.isPropertyTrue(
+                HsqlDatabaseProperties.url_get_column_name, true);
+        }
+
+        if (conn.clientProperties != null) {
+            translateDTIType = conn.clientProperties.isPropertyTrue(
+                HsqlDatabaseProperties.jdbc_translate_dti_types);
+        }
+    }
+
+    /**
+     * Performs an internal check for column index validity. <p>
+     *
+     * @param column index of column to check
+     * @throws SQLException when this object's parent ResultSet has
+     *      no such column
+     */
+    private void checkColumn(int column) throws SQLException {
+
+        if (column < 1 || column > columnCount) {
+            throw Util.sqlException(ErrorCode.JDBC_COLUMN_NOT_FOUND,
+                                    String.valueOf(column));
+        }
+    }
+
+    /**
+     * Translates an INTERVAL type to VARCHAR.
+     * Removes time zone from datetime types.
+     *
+     */
+    private Type translateType(Type type) {
+
+        if (this.translateDTIType) {
+            if (type.isIntervalType()) {
+                type = new CharacterType(Types.SQL_VARCHAR,
+                        type.displaySize());
+            } else if (type.isDateTimeTypeWithZone()) {
+                type = ((DateTimeType) type).getDateTimeTypeWithoutZone();
+            }
+        }
+
+        return type;
+    }
+
+    /**
+     * Returns a string representation of the object. <p>
+     *
+     * The string consists of the name of the class of which the
+     * object is an instance, the at-sign character `<code>@</code>',
+     * the unsigned hexadecimal representation of the hash code of the
+     * object and a comma-delimited list of this object's indexed attributes,
+     * enclosed in square brakets.
+     *
+     * @return  a string representation of the object.
+     */
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(super.toString());
+
+        if (columnCount == 0) {
+            sb.append("[columnCount=0]");
+
+            return sb.toString();
+        }
+        sb.append('[');
+
+        for (int i = 0; i < columnCount; i++) {
+            JDBCColumnMetaData meta = getColumnMetaData(i + 1);
+
+            sb.append('\n');
+            sb.append("   column_");
+            sb.append(i + 1);
+            sb.append('=');
+            sb.append(meta);
+
+            if (i + 1 < columnCount) {
+                sb.append(',');
+                sb.append(' ');
+            }
+        }
+        sb.append('\n');
+        sb.append(']');
+
+        return sb.toString();
+    }
+
+    JDBCColumnMetaData getColumnMetaData(int i) {
+
+        JDBCColumnMetaData meta = new JDBCColumnMetaData();
+
+        try {
+            meta.catalogName          = getCatalogName(i);
+            meta.columnClassName      = getColumnClassName(i);
+            meta.columnDisplaySize    = getColumnDisplaySize(i);
+            meta.columnLabel          = getColumnLabel(i);
+            meta.columnName           = getColumnName(i);
+            meta.columnType           = getColumnType(i);
+            meta.isAutoIncrement      = isAutoIncrement(i);
+            meta.isCaseSensitive      = isCaseSensitive(i);
+            meta.isCurrency           = isCurrency(i);
+            meta.isDefinitelyWritable = isDefinitelyWritable(i);
+            meta.isNullable           = isNullable(i);
+            meta.isReadOnly           = isReadOnly(i);
+            meta.isSearchable         = isSearchable(i);
+            meta.isSigned             = isSigned(i);
+            meta.isWritable           = isWritable(i);
+            meta.precision            = getPrecision(i);
+            meta.scale                = getScale(i);
+            meta.schemaName           = getSchemaName(i);
+            meta.tableName            = getTableName(i);
+        } catch (SQLException e) {
+        }
+
+        return meta;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCRowId.java b/src/org/hsqldb/jdbc/JDBCRowId.java
new file mode 100644
index 0000000..5a54be5
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCRowId.java
@@ -0,0 +1,223 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+
+import java.io.IOException;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.util.Arrays;
+
+/* $Id: JDBCRowId.java 3598 2010-05-30 22:54:15Z fredt $ */
+
+//boucherb@users 20060522 - doc 1.8.1 full synch up to Mustang Build 84
+
+/**
+ *
+ * The representation (mapping) in the Java programming language of an SQL ROWID
+ * value. An SQL ROWID is a built-in type, a value of which can be thought of as
+ * an address  for its identified row in a database table. Whether that address
+ * is logical or, in any  respects, physical is determined by its originating data
+ * source.
+ * <p>
+ * Methods in the interfaces <code>ResultSet</code>, <code>CallableStatement</code>,
+ * and <code>PreparedStatement</code>, such as <code>getRowId</code> and <code>setRowId</code>
+ * allow a programmer to access a SQL <code>ROWID</code>  value. The <code>RowId</code>
+ * interface provides a method
+ * for representing the value of the <code>ROWID</code> as a byte array or as a
+ * <code>String</code>.
+ * <p>
+ * The method <code>getRowIdLifetime</code> in the interface <code>DatabaseMetaData</code>,
+ * can be used
+ * to determine if a <code>RowId</code> object remains valid for the duration of the transaction in
+ * which  the <code>RowId</code> was created, the duration of the session in which
+ * the <code>RowId</code> was created,
+ * or, effectively, for as long as its identified row is not deleted. In addition
+ * to specifying the duration of its valid lifetime outside its originating data
+ * source, <code>getRowIdLifetime</code> specifies the duration of a <code>ROWID</code>
+ * value's valid lifetime
+ * within its originating data source. In this, it differs from a large object,
+ * because there is no limit on the valid lifetime of a large  object within its
+ * originating data source.
+ * <p>
+ * All methods on the <code>RowId</code> interface must be fully implemented if the
+ * JDBC driver supports the data type.
+ *
+ * @see java.sql.DatabaseMetaData
+ * @since JDK 1.6, HSQLDB 2.0
+ * @author boucherb@users
+ */
+public final class JDBCRowId implements RowId {
+
+    private int hash;
+
+    // ------------------------- Internal Implementation -----------------------
+    private final byte[] id;
+
+    /**
+     * Constructs a new JDBCRowId instance wrapping the given octet sequence. <p>
+     *
+     * This constructor may be used internally to retrieve result set values as
+     * RowId objects, yet it also may need to be public to allow access from
+     * other packages. As such (in the interest of efficiency) this object
+     * maintains a reference to the given octet sequence rather than making a
+     * copy; special care should be taken by extenal clients never to use this
+     * constructor with a byte array object that may later be modified
+     * extenally.
+     *
+     * @param id the octet sequence representing the Rowid value
+     * @throws SQLException if the argument is null
+     */
+    public JDBCRowId(final byte[] id) throws SQLException {
+
+        if (id == null) {
+            throw Util.nullArgument("id");
+        }
+        this.id = id;
+    }
+
+    /**
+     * Constructs a new JDBCRowId instance whose internal octet sequence is
+     * is a copy of the octet sequence of the given RowId object. <p>
+     *
+     * @param id the octet sequence representing the Rowid value
+     * @throws SQLException if the argument is null
+     */
+    public JDBCRowId(RowId id) throws SQLException {
+        this(id.getBytes());
+    }
+
+    /**
+     * Constructs a new JDBCRowId instance whose internal octet sequence is
+     * is that represented by the given hexidecimal character sequence. <p>
+     * @param hex the hexadecimal character sequence from which to derive
+     *        the internal octet sequence
+     * @throws java.sql.SQLException if the argument is null or is not a valid
+     *         hexadecimal character sequence
+     */
+    public JDBCRowId(final String hex) throws SQLException {
+
+        if (hex == null) {
+            throw Util.nullArgument("hex");
+        }
+
+        try {
+            this.id = StringConverter.hexStringToByteArray(hex);
+        } catch (IOException e) {
+            throw Util.sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+                                    "hex: " + e);
+
+            // .illegalHexadecimalCharacterSequenceArgumentException("hex", e);
+        }
+    }
+
+    /**
+     * Compares this <code>RowId</code> to the specified object. The result is
+     * <code>true</code> if and only if the argument is not null and is a RowId
+     * object that represents the same ROWID as  this object.
+     * <p>
+     * It is important
+     * to consider both the origin and the valid lifetime of a <code>RowId</code>
+     * when comparing it to another <code>RowId</code>. If both are valid, and
+     * both are from the same table on the same data source, then if they are equal
+     * they identify
+     * the same row; if one or more is no longer guaranteed to be valid, or if
+     * they originate from different data sources, or different tables on the
+     * same data source, they  may be equal but still
+     * not identify the same row.
+     *
+     * @param obj the <code>Object</code> to compare this <code>RowId</code> object
+     *     against.
+     * @return true if the <code>RowId</code>s are equal; false otherwise
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public boolean equals(Object obj) {
+        return (obj instanceof JDBCRowId)
+               && Arrays.equals(this.id, ((JDBCRowId) obj).id);
+    }
+
+    /**
+     * Returns an array of bytes representing the value of the SQL <code>ROWID</code>
+     * designated by this <code>java.sql.RowId</code> object.
+     *
+     * @return an array of bytes, whose length is determined by the driver supplying
+     *     the connection, representing the value of the ROWID designated by this
+     *     java.sql.RowId object.
+     */
+    public byte[] getBytes() {
+        return id.clone();
+    }
+
+    /**
+     * Returns a String representing the value of the SQL ROWID designated by this
+     * <code>java.sql.RowId</code> object.
+     * <p>
+     * Like <code>java.sql.Date.toString()</code>
+     * returns the contents of its DATE as the <code>String</code> "2004-03-17"
+     * rather than as  DATE literal in SQL (which would have been the <code>String</code>
+     * DATE "2004-03-17"), toString()
+     * returns the contents of its ROWID in a form specific to the driver supplying
+     * the connection, and possibly not as a <code>ROWID</code> literal.
+     *
+     * @return a String whose format is determined by the driver supplying the
+     *     connection, representing the value of the <code>ROWID</code> designated
+     *     by this <code>java.sql.RowId</code>  object.
+     */
+    public String toString() {
+        return StringConverter.byteArrayToHexString(id);
+    }
+
+    /**
+     * Returns a hash code value of this <code>RowId</code> object.
+     *
+     * @return a hash code for the <code>RowId</code>
+     */
+    public int hashCode() {
+
+        if (hash == 0) {
+            hash = Arrays.hashCode(id);
+        }
+
+        return hash;
+    }
+
+    /**
+     * Direct access to id bytes for subclassing.
+     *
+     * @return direct reference to id bytes.
+     */
+    Object id() {
+        return id;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCSQLXML.java b/src/org/hsqldb/jdbc/JDBCSQLXML.java
new file mode 100644
index 0000000..9fc37ce
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCSQLXML.java
@@ -0,0 +1,3141 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.charset.Charset;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import javax.xml.bind.util.JAXBResult;
+import javax.xml.bind.util.JAXBSource;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stax.StAXResult;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ClosableByteArrayOutputStream;
+import org.hsqldb.lib.StringConverter;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/* $Id: JDBCSQLXML.java 3598 2010-05-30 22:54:15Z fredt $ */
+
+/**
+ * <!-- start generic documentation -->
+ * The mapping in the JavaTM programming language for the SQL XML type.
+ * XML is a built-in type that stores an XML value
+ * as a column value in a row of a database table.
+ * By default drivers implement an SQLXML object as
+ * a logical pointer to the XML data
+ * rather than the data itself.
+ * An SQLXML object is valid for the duration of the transaction in which it was created.
+ * <p>
+ * The SQLXML interface provides methods for accessing the XML value
+ * as a String, a Reader or Writer, or as a Stream.  The XML value
+ * may also be accessed through a Source or set as a Result, which
+ * are used with XML Parser APIs such as DOM, SAX, and StAX, as
+ * well as with XSLT transforms and XPath evaluations.
+ * <p>
+ * Methods in the interfaces ResultSet, CallableStatement, and PreparedStatement,
+ * such as getSQLXML allow a programmer to access an XML value.
+ * In addition, this interface has methods for updating an XML value.
+ * <p>
+ * The XML value of the SQLXML instance may be obtained as a BinaryStream using
+ * <pre>
+ *   SQLXML sqlxml = resultSet.getSQLXML(column);
+ *   InputStream binaryStream = sqlxml.getBinaryStream();
+ * </pre>
+ * For example, to parse an XML value with a DOM parser:
+ * <pre>
+ *   DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ *   Document result = parser.parse(binaryStream);
+ * </pre>
+ * or to parse an XML value with a SAX parser to your handler:
+ * <pre>
+ *   SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+ *   parser.parse(binaryStream, myHandler);
+ * </pre>
+ * or to parse an XML value with a StAX parser:
+ * <pre>
+ *   XMLInputFactory factory = XMLInputFactory.newInstance();
+ *   XMLStreamReader streamReader = factory.createXMLStreamReader(binaryStream);
+ * </pre>
+ * <p>
+ * Because databases may use an optimized representation for the XML,
+ * accessing the value through getSource() and
+ * setResult() can lead to improved processing performance
+ * without serializing to a stream representation and parsing the XML.
+ * <p>
+ * For example, to obtain a DOM Document Node:
+ * <pre>
+ *   DOMSource domSource = sqlxml.getSource(DOMSource.class);
+ *   Document document = (Document) domSource.getNode();
+ * </pre>
+ * or to set the value to a DOM Document Node to myNode:
+ * <pre>
+ *   DOMResult domResult = sqlxml.setResult(DOMResult.class);
+ *   domResult.setNode(myNode);
+ * </pre>
+ * or, to send SAX events to your handler:
+ * <pre>
+ *   SAXSource saxSource = sqlxml.getSource(SAXSource.class);
+ *   XMLReader xmlReader = saxSource.getXMLReader();
+ *   xmlReader.setContentHandler(myHandler);
+ *   xmlReader.parse(saxSource.getInputSource());
+ * </pre>
+ * or, to set the result value from SAX events:
+ * <pre>
+ *   SAXResult saxResult = sqlxml.setResult(SAXResult.class);
+ *   ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
+ *   contentHandler.startDocument();
+ *   // set the XML elements and attributes into the result
+ *   contentHandler.endDocument();
+ * </pre>
+ * or, to obtain StAX events:
+ * <pre>
+ *   StAXSource staxSource = sqlxml.getSource(StAXSource.class);
+ *   XMLStreamReader streamReader = staxSource.getXMLStreamReader();
+ * </pre>
+ * or, to set the result value from StAX events:
+ * <pre>
+ *   StAXResult staxResult = sqlxml.getResult(StAXResult.class);
+ *   XMLStreamWriter streamWriter = staxResult.getXMLStreamWriter();
+ * </pre>
+ * or, to perform XSLT transformations on the XML value using the XSLT in xsltFile
+ * output to file resultFile:
+ * <pre>
+ *   File xsltFile = new File("a.xslt");
+ *   File myFile = new File("result.xml");
+ *   Transformer xslt = TransformerFactory.newInstance().newTransformer(new StreamSource(xsltFile));
+ *   Source source = sqlxml.getSource(null);
+ *   Result result = new StreamResult(myFile);
+ *   xslt.transform(source, result);
+ * </pre>
+ * or, to evaluate an XPath expression on the XML value:
+ * <pre>
+ *   XPath xpath = XPathFactory.newInstance().newXPath();
+ *   DOMSource domSource = sqlxml.getSource(DOMSource.class);
+ *   Document document = (Document) domSource.getNode();
+ *   String expression = "/foo/@bar";
+ *   String barValue = xpath.evaluate(expression, document);
+ * </pre>
+ * To set the XML value to be the result of an XSLT transform:
+ * <pre>
+ *   File sourceFile = new File("source.xml");
+ *   Transformer xslt = TransformerFactory.newInstance().newTransformer(new StreamSource(xsltFile));
+ *   Source streamSource = new StreamSource(sourceFile);
+ *   Result result = sqlxml.setResult(null);
+ *   xslt.transform(streamSource, result);
+ * </pre>
+ * Any Source can be transformed to a Result using the identity transform
+ * specified by calling newTransformer():
+ * <pre>
+ *   Transformer identity = TransformerFactory.newInstance().newTransformer();
+ *   Source source = sqlxml.getSource(null);
+ *   File myFile = new File("result.xml");
+ *   Result result = new StreamResult(myFile);
+ *   identity.transform(source, result);
+ * </pre>
+ * To write the contents of a Source to standard output:
+ * <pre>
+ *   Transformer identity = TransformerFactory.newInstance().newTransformer();
+ *   Source source = sqlxml.getSource(null);
+ *   Result result = new StreamResult(System.out);
+ *   identity.transform(source, result);
+ * </pre>
+ * To create a DOMSource from a DOMResult:
+ * <pre>
+ *    DOMSource domSource = new DOMSource(domResult.getNode());
+ * </pre>
+ * <p>
+ * Incomplete or invalid XML values may cause an SQLException when
+ * set or the exception may occur when execute() occurs.  All streams
+ * must be closed before execute() occurs or an SQLException will be thrown.
+ * <p>
+ * Reading and writing XML values to or from an SQLXML object can happen at most once.
+ * The conceptual states of readable and not readable determine if one
+ * of the reading APIs will return a value or throw an exception.
+ * The conceptual states of writable and not writable determine if one
+ * of the writing APIs will set a value or throw an exception.
+ * <p>
+ * The state moves from readable to not readable once free() or any of the
+ * reading APIs are called: getBinaryStream(), getCharacterStream(), getSource(), and getString().
+ * Implementations may also change the state to not writable when this occurs.
+ * <p>
+ * The state moves from writable to not writeable once free() or any of the
+ * writing APIs are called: setBinaryStream(), setCharacterStream(), setResult(), and setString().
+ * Implementations may also change the state to not readable when this occurs.
+ * <p>
+ * All methods on the <code>SQLXML</code> interface must be fully implemented if the
+ * JDBC driver supports the data type.
+ * <!-- end generic documentation -->
+ *
+ * <!-- start release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * Starting with HSQLDB 2.0, a rudimentary client-side SQLXML interface
+ * implementation (this class) is supported for local use when the product is
+ * built and run under JDK 1.6+ and the SQLXML instance is constructed as the
+ * result of calling JDBCConnection.createSQLXML(). <p>
+ *
+ * SQLXML instances retrieved in such a fashion are initially write-only, with
+ * the lifecycle of read and write availability constrained in accordance with
+ * the documentation of the interface methods. <p>
+ *
+ * When build and run under JDK 1.6+, it is also possible to retrieve read-only
+ * SQLXML instances from JDBCResultSet.getSQLXML(...), given that the underlying
+ * data can be converted to an XML Document Object Model (DOM). <p>
+ *
+ * However, at the time of this writing (2007-06-12) it is not yet possible to
+ * store SQLXML objects directly into an HSQLDB database or to use them directly
+ * for HSQLDB statement parameterization purposes.  This is because the SQLXML
+ * data type is not yet natively supported by the HSQLDB engine. Instead, a
+ * JDBCSQLXML instance must first be read as a string, binary input stream,
+ * character input stream and so on, which can then be used for such purposes. <p>
+ *
+ * Here is the current read/write availability lifecycle for JDBCSQLXML:
+ *
+ * <TABLE border="1" cellspacing=1" cellpadding="3">
+ *     <THEAD valign="bottom">
+ *         <TR align="center">
+ *             <TH>
+ *                 Origin
+ *             </TH>
+ *             <TH>
+ *                 Initially
+ *             </TH>
+ *             <TH>
+ *                 After 1<SUP>st</SUP> Write
+ *             </TH>
+ *             <TH>
+ *                 After 1<SUP>st</SUP> Read
+ *             </TH>
+ *             <TH>
+ *                 After 1<SUP>st</SUP> Free
+ *             </TH>
+ *         </TR>
+ *     </THEAD>
+ *     <TBODY>
+ *         <TR >
+ *             <TH>
+ *                 <tt>org.hsqldb.jdbc.JDBCConnection.createSQLXML()</tt>
+ *             </TH>
+ *             <TD >
+ *                 Write-only
+ *             </TD>
+ *             <TD>
+ *                 Read-only
+ *             </TD>
+ *             <TD>
+ *                 Not readable or writable
+ *             </TD>
+ *             <TD>
+ *                 Not readable or writable
+ *             </TD>
+ *         </TR>
+ *         <TR>
+ *             <TH>
+ *                 <tt>org.hsqldb.jdbc.JDBCResultSet.getSQLXML(...)</tt>
+ *             </TH>
+ *             <TD >
+ *                 Read-only
+ *             </TD>
+ *             <TD>
+ *                 N/A
+ *             </TD>
+ *             <TD>
+ *                 Not readable or writable
+ *             </TD>
+ *             <TD>
+ *                 Not readable or writable
+ *             </TD>
+ *         </TR>
+ *     </TBODY>
+ * </TABLE>
+ * </div>
+ * <!-- end release-specific documentation -->
+ *
+ * @author boucherb@users
+ * @see javax.xml.parsers
+ * @see javax.xml.stream
+ * @see javax.xml.transform
+ * @see javax.xml.xpath
+ * @since JDK 1.6, HSQLDB 2.0
+ * @revised Mustang Build 79
+ */
+public class JDBCSQLXML implements SQLXML {
+
+    private static String domFeatures = "XML 3.0 Traversal +Events 2.0";
+    private static DOMImplementation         domImplementation;
+    private static DOMImplementationRegistry domImplementationRegistry;
+    private static ThreadPoolExecutor        executorService;
+    private static Transformer               identityTransformer;
+    private static TransformerFactory        transformerFactory;
+
+    /**
+     * Precomputed Charset to reduce octect to character sequence conversion
+     * charset lookup overhead.
+     */
+    private static final Charset                utf8Charset;
+    private static ArrayBlockingQueue<Runnable> workQueue;
+
+    static {
+        Charset charset = null;
+
+        try {
+            charset = Charset.forName("UTF8");
+        } catch (Exception e) {
+        }
+        utf8Charset = charset;
+    }
+
+    /**
+     * When non-null, the SAX ContentHandler currently in use to build this
+     * object's SQLXML value from a SAX event sequence.
+     */
+    private SAX2DOMBuilder builder;
+
+    /**
+     * Whether this object is closed.  When closed, no further reading
+     * or writing is possible.
+     */
+    private boolean closed;
+
+    // ------------------------- Internal Implementation -----------------------
+
+    /**
+     * This object's SQLXML value as a GZIPed byte array
+     */
+    private volatile byte[] gzdata;
+
+    /**
+     * When non-null, the stream currently in use to read this object's
+     * SQLXML value as an octet sequence.
+     */
+    private InputStream inputStream;
+
+    /**
+     * When non-null, the stream currently in use to write this object's
+     * SQLXML value from an octet sequence.
+     */
+    private ClosableByteArrayOutputStream outputStream;
+
+    /**
+     * When non-null, the DOMResult currently in use to build this object's
+     * SQLXML value.
+     */
+    private DOMResult domResult;
+
+    /**
+     * This object's public id
+     */
+    private String publicId;
+
+    /**
+     * Whether it is possible to read this object's SQLXML value.
+     */
+    private boolean readable;
+
+    /**
+     * This object's system id
+     */
+    private String systemId;
+
+    /**
+     * Whether it is possible to write this object's SQLXML value.
+     */
+    private boolean writable;
+
+    /**
+     * Constructs a new, initially write-only JDBCSQLXML object. <p>
+     */
+    protected JDBCSQLXML() {
+        setReadable(false);
+        setWritable(true);
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given octet
+     * sequence. <p>
+     *
+     * @param bytes the octet sequence representing the SQLXML value
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(byte[] bytes) throws SQLException {
+        this(bytes, null);
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given character
+     * sequence. <p>
+     *
+     * @param chars the character sequence representing the SQLXML value
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(char[] chars) throws SQLException {
+        this(chars, 0, chars.length, null);
+    }
+
+    /**
+     * Constructs a new JDBCSQLXML object from the given Document. <p>
+     *
+     * @param document the Document representing the SQLXML value
+     * @throws java.sql.SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(Document document) throws SQLException {
+        this(new DOMSource(document));
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given octet
+     * sequence. <p>
+     *
+     * Relative URI references will be resolved against the present working
+     * directory reported by the Java virtual machine. <p>
+     *
+     * @param inputStream an octet stream representing an SQLXML value
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(InputStream inputStream) throws SQLException {
+        this(inputStream, null);
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given character
+     * sequence. <p>
+     *
+     * Relative URI references will be resolved against the present working
+     * directory reported by the Java virtual machine. <p>
+     *
+     * <b>Note:</b>Normally, a byte stream should be used rather than a reader,
+     * so that the XML parser can resolve character encoding specified by the
+     * XML declaration. However, in many cases the encoding of the input stream
+     * is already resolved, as in the case of reading XML from a StringReader.
+     *
+     * @param reader a character stream representing an SQLXML value
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(Reader reader) throws SQLException {
+        this(reader, null);
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given Source
+     * object. <p>
+     *
+     * @param source a Source representing an SQLXML value
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    public JDBCSQLXML(Source source) throws SQLException {
+        init(source);
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given character
+     * sequence. <p>
+     *
+     * Relative URI references will be resolved against the present working
+     * directory reported by the Java virtual machine. <p>
+     *
+     * @param string a character sequence representing an SQLXML value
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(String string) throws SQLException {
+        this(new StreamSource(new StringReader(string)));
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given octet
+     * sequence. <p>
+     *
+     * @param bytes the octet sequence representing the SQLXML value
+     * @param systemId must be a String that conforms to the URI syntax;
+     *        allows relative URIs to be processed.
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(byte[] bytes, String systemId) throws SQLException {
+        this(new StreamSource(new ByteArrayInputStream(bytes), systemId));
+    }
+
+    protected JDBCSQLXML(char[] chars, String systemId) throws SQLException {
+        this(chars, 0, chars.length, systemId);
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given octet
+     * sequence. <p>
+     *
+     * Relative URI references will be resolved against the given systemId. <p>
+     *
+     * @param inputStream an octet stream representing an SQLXML value
+     * @param systemId a String that conforms to the URI syntax, indicating
+     *      the URI from which the XML data is being read, so that relative URI
+     *      references can be resolved
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(InputStream inputStream,
+                         String systemId) throws SQLException {
+        this(new StreamSource(inputStream, systemId));
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given character
+     * sequence. <p>
+     *
+     * Relative URI references will be resolved against the given systemId. <p>
+     *
+     * <b>Note:</b>Normally, a byte stream should be used rather than a reader,
+     * so that the XML parser can resolve character encoding specified by the
+     * XML declaration. However, in many cases the encoding of the input stream
+     * is already resolved, as in the case of reading XML from a StringReader.
+     *
+     * @param reader a character stream representing an SQLXML value;
+     * @param systemId a String that conforms to the URI syntax, indicating
+     *      the URI from which the XML data is being read, so that relative URI
+     *      references can be resolved
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(Reader reader, String systemId) throws SQLException {
+        this(new StreamSource(reader, systemId));
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given character
+     * sequence. <p>
+     *
+     * Relative URI references will be resolved against the given systemId. <p>
+     *
+     * @param string a character sequence representing an SQLXML value
+     * @param systemId a String that conforms to the URI syntax, indicating
+     *      the URI from which the XML data is being read, so that relative URI
+     *      references can be resolved
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(String string, String systemId) throws SQLException {
+        this(new StreamSource(new StringReader(string), systemId));
+    }
+
+    /**
+     * Constructs a new read-only JDBCSQLXML object from the given gzipped octet
+     * sequence. <p>
+     *
+     * @param bytes the gzipped octet sequence representing the SQLXML value
+     * @param clone whether to clone the given gzipped octet sequence
+     * @param systemId
+     * @param publicId
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected JDBCSQLXML(byte[] bytes, boolean clone, String systemId,
+                         String publicId) throws SQLException {
+
+        this.setGZipData(clone ? bytes.clone()
+                               : bytes);
+
+        this.systemId = systemId;
+        this.publicId = publicId;
+    }
+
+    protected JDBCSQLXML(char[] chars, int offset, int length,
+                         String systemId) throws SQLException {
+        this(new StreamSource(new CharArrayReader(chars, offset, length),
+                              systemId));
+    }
+
+    /**
+     * This method closes this object and releases the resources that it held.
+     * The SQL XML object becomes invalid and neither readable or writeable
+     * when this method is called.
+     *
+     * After <code>free</code> has been called, any attempt to invoke a
+     * method other than <code>free</code> will result in a <code>SQLException</code>
+     * being thrown.  If <code>free</code> is called multiple times, the subsequent
+     * calls to <code>free</code> are treated as a no-op.
+     * @throws SQLException if there is an error freeing the XML value.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6
+     */
+    public void free() throws SQLException {
+        close();
+    }
+
+    /**
+     * Retrieves the XML value designated by this SQLXML instance as a stream.
+     * The bytes of the input stream are interpreted according to appendix F of the XML 1.0 specification.
+     * The behavior of this method is the same as ResultSet.getBinaryStream()
+     * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+     * <p>
+     * The SQL XML object becomes not readable when this method is called and
+     * may also become not writable depending on implementation.
+     *
+     * @return a stream containing the XML data.
+     * @throws SQLException if there is an error processing the XML value.
+     *   An exception is thrown if the state is not readable.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6
+     */
+    public synchronized InputStream getBinaryStream() throws SQLException {
+
+        checkClosed();
+        checkReadable();
+
+        InputStream rval = getBinaryStreamImpl();
+
+        setReadable(false);
+        setWritable(false);
+
+        return rval;
+    }
+
+    /**
+     * Retrieves a stream that can be used to write the XML value that this SQLXML instance represents.
+     * The stream begins at position 0.
+     * The bytes of the stream are interpreted according to appendix F of the XML 1.0 specification
+     * The behavior of this method is the same as ResultSet.updateBinaryStream()
+     * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+     * <p>
+     * The SQL XML object becomes not writeable when this method is called and
+     * may also become not readable depending on implementation.
+     *
+     * @return a stream to which data can be written.
+     * @throws SQLException if there is an error processing the XML value.
+     *   An exception is thrown if the state is not writable.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6
+     */
+    public synchronized OutputStream setBinaryStream() throws SQLException {
+
+        checkClosed();
+        checkWritable();
+
+        OutputStream rval = setBinaryStreamImpl();
+
+        setWritable(false);
+        setReadable(true);
+
+        return rval;
+    }
+
+    /**
+     * Retrieves the XML value designated by this SQLXML instance as a java.io.Reader object.
+     * The format of this stream is defined by org.xml.sax.InputSource,
+     * where the characters in the stream represent the unicode code points for
+     * XML according to section 2 and appendix B of the XML 1.0 specification.
+     * Although an encoding declaration other than unicode may be present,
+     * the encoding of the stream is unicode.
+     * The behavior of this method is the same as ResultSet.getCharacterStream()
+     * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+     * <p>
+     * The SQL XML object becomes not readable when this method is called and
+     * may also become not writable depending on implementation.
+     *
+     * @return a stream containing the XML data.
+     * @throws SQLException if there is an error processing the XML value.
+     *   The getCause() method of the exception may provide a more detailed exception, for example,
+     *   if the stream does not contain valid characters.
+     *   An exception is thrown if the state is not readable.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6
+     */
+    public synchronized Reader getCharacterStream() throws SQLException {
+
+        checkClosed();
+        checkReadable();
+
+        Reader reader = getCharacterStreamImpl();
+
+        setReadable(false);
+        setWritable(false);
+
+        return reader;
+    }
+
+    /**
+     * Retrieves a stream to be used to write the XML value that this SQLXML instance represents.
+     * The format of this stream is defined by org.xml.sax.InputSource,
+     * where the characters in the stream represent the unicode code points for
+     * XML according to section 2 and appendix B of the XML 1.0 specification.
+     * Although an encoding declaration other than unicode may be present,
+     * the encoding of the stream is unicode.
+     * The behavior of this method is the same as ResultSet.updateCharacterStream()
+     * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+     * <p>
+     * The SQL XML object becomes not writeable when this method is called and
+     * may also become not readable depending on implementation.
+     *
+     * @return a stream to which data can be written.
+     * @throws SQLException if there is an error processing the XML value.
+     *   The getCause() method of the exception may provide a more detailed exception, for example,
+     *   if the stream does not contain valid characters.
+     *   An exception is thrown if the state is not writable.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6 Build 79
+     */
+    public synchronized Writer setCharacterStream() throws SQLException {
+
+        checkClosed();
+        checkWritable();
+
+        Writer writer = setCharacterStreamImpl();
+
+        setReadable(true);
+        setWritable(false);
+
+        return writer;
+    }
+
+    /**
+     * Returns a string representation of the XML value designated by this SQLXML instance.
+     * The format of this String is defined by org.xml.sax.InputSource,
+     * where the characters in the stream represent the unicode code points for
+     * XML according to section 2 and appendix B of the XML 1.0 specification.
+     * Although an encoding declaration other than unicode may be present,
+     * the encoding of the String is unicode.
+     * The behavior of this method is the same as ResultSet.getString()
+     * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+     * <p>
+     * The SQL XML object becomes not readable when this method is called and
+     * may also become not writable depending on implementation.
+     *
+     * @return a string representation of the XML value designated by this SQLXML instance.
+     * @throws SQLException if there is an error processing the XML value.
+     *   The getCause() method of the exception may provide a more detailed exception, for example,
+     *   if the stream does not contain valid characters.
+     *   An exception is thrown if the state is not readable.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6
+     */
+    public synchronized String getString() throws SQLException {
+
+        checkClosed();
+        checkReadable();
+
+        String value = getStringImpl();
+
+        setReadable(false);
+        setWritable(false);
+
+        return value;
+    }
+
+    /**
+     * Sets the XML value designated by this SQLXML instance to the given String representation.
+     * The format of this String is defined by org.xml.sax.InputSource,
+     * where the characters in the stream represent the unicode code points for
+     * XML according to section 2 and appendix B of the XML 1.0 specification.
+     * Although an encoding declaration other than unicode may be present,
+     * the encoding of the String is unicode.
+     * The behavior of this method is the same as ResultSet.updateString()
+     * when the designated column of the ResultSet has a type java.sql.Types of SQLXML.
+     * <p>
+     * The SQL XML object becomes not writeable when this method is called and
+     * may also become not readable depending on implementation.
+     *
+     * @param value the XML value
+     * @throws SQLException if there is an error processing the XML value.
+     *   The getCause() method of the exception may provide a more detailed exception, for example,
+     *   if the stream does not contain valid characters.
+     *   An exception is thrown if the state is not writable.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6
+     */
+    public synchronized void setString(String value) throws SQLException {
+
+        if (value == null) {
+            throw Util.nullArgument("value");
+        }
+        checkWritable();
+        setStringImpl(value);
+        setReadable(true);
+        setWritable(false);
+    }
+
+    /**
+     * Returns a Source for reading the XML value designated by this SQLXML instance.
+     * Sources are used as inputs to XML parsers and XSLT transformers.
+     * <p>
+     * Sources for XML parsers will have namespace processing on by default.
+     * The systemID of the Source is implementation dependent.
+     * <p>
+     * The SQL XML object becomes not readable when this method is called and
+     * may also become not writable depending on implementation.
+     * <p>
+     * Note that SAX is a callback architecture, so a returned
+     * SAXSource should then be set with a content handler that will
+     * receive the SAX events from parsing.  The content handler
+     * will receive callbacks based on the contents of the XML.
+     * <pre>
+     *   SAXSource saxSource = sqlxml.getSource(SAXSource.class);
+     *   XMLReader xmlReader = saxSource.getXMLReader();
+     *   xmlReader.setContentHandler(myHandler);
+     *   xmlReader.parse(saxSource.getInputSource());
+     * </pre>
+     *
+     * @param sourceClass The class of the source, or null.
+     * If the class is null, a vendor specifc Source implementation will be returned.
+     * The following classes are supported at a minimum:
+     * <pre>
+     *   javax.xml.transform.dom.DOMSource - returns a DOMSource
+     *   javax.xml.transform.sax.SAXSource - returns a SAXSource
+     *   javax.xml.transform.stax.StAXSource - returns a StAXSource
+     *   javax.xml.transform.stream.StreamSource - returns a StreamSource
+     * </pre>
+     * @return a Source for reading the XML value.
+     * @throws SQLException if there is an error processing the XML value
+     *   or if this feature is not supported.
+     *   The getCause() method of the exception may provide a more detailed exception, for example,
+     *   if an XML parser exception occurs.
+     *   An exception is thrown if the state is not readable.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6 Build 79
+     */
+    @SuppressWarnings("unchecked")
+    public synchronized <T extends Source>T getSource(
+            Class<T> sourceClass) throws SQLException {
+
+        checkClosed();
+        checkReadable();
+
+        final Source source = getSourceImpl(sourceClass);
+
+        setReadable(false);
+        setWritable(false);
+
+        return (T) source;
+    }
+
+    /**
+     * Returns a Result for setting the XML value designated by this SQLXML instance.
+     * <p>
+     * The systemID of the Result is implementation dependent.
+     * <p>
+     * The SQL XML object becomes not writeable when this method is called and
+     * may also become not readable depending on implementation.
+     * <p>
+     * Note that SAX is a callback architecture and the returned
+     * SAXResult has a content handler assigned that will receive the
+     * SAX events based on the contents of the XML.  Call the content
+     * handler with the contents of the XML document to assign the values.
+     * <pre>
+     *   SAXResult saxResult = sqlxml.getResult(SAXResult.class);
+     *   ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
+     *   contentHandler.startDocument();
+     *   // set the XML elements and attributes into the result
+     *   contentHandler.endDocument();
+     * </pre>
+     *
+     * @param resultClass The class of the result, or null.
+     * If resultClass is null, a vendor specific Result implementation will be returned.
+     * The following classes are supported at a minimum:
+     * <pre>
+     *   javax.xml.transform.dom.DOMResult - returns a DOMResult
+     *   javax.xml.transform.sax.SAXResult - returns a SAXResult
+     *   javax.xml.transform.stax.StAXResult - returns a StAXResult
+     *   javax.xml.transform.stream.StreamResult - returns a StreamResult
+     * </pre>
+     * @return Returns a Result for setting the XML value.
+     * @throws SQLException if there is an error processing the XML value
+     *   or if this feature is not supported.
+     *   The getCause() method of the exception may provide a more detailed exception, for example,
+     *   if an XML parser exception occurs.
+     *   An exception is thrown if the state is not writable.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since JDK 1.6 Build 79
+     */
+    public synchronized <T extends Result>T setResult(
+            Class<T> resultClass) throws SQLException {
+
+        checkClosed();
+        checkWritable();
+
+        final T result = createResult(resultClass);
+
+        setReadable(true);
+        setWritable(false);
+
+        return result;
+    }
+
+    /**
+     * @return that may be used to perform processesing asynchronously.
+     */
+    protected static ExecutorService getExecutorService() {
+
+        if (JDBCSQLXML.executorService == null) {
+            int      corePoolSize    = 1;
+            int      maximumPoolSize = 10;
+            long     keepAliveTime   = 1;
+            TimeUnit unit            = TimeUnit.SECONDS;
+
+            JDBCSQLXML.workQueue = new ArrayBlockingQueue<Runnable>(10);
+            JDBCSQLXML.executorService = new ThreadPoolExecutor(corePoolSize,
+                    maximumPoolSize, keepAliveTime, unit, workQueue);
+        }
+
+        return executorService;
+    }
+
+    /**
+     * @return with which to obtain xml transformer instances.
+     * @throws java.sql.SQLException when unable to obtain a factory instance.
+     */
+    protected static TransformerFactory getTransformerFactory() throws SQLException {
+
+        if (JDBCSQLXML.transformerFactory == null) {
+            try {
+                JDBCSQLXML.transformerFactory =
+                    TransformerFactory.newInstance();
+            } catch (TransformerFactoryConfigurationError ex) {
+                throw Exceptions.transformFailed(ex);
+            }
+        }
+
+        return JDBCSQLXML.transformerFactory;
+    }
+
+    /**
+     * @return used to perform identity transforms
+     * @throws java.sql.SQLException when unable to obtain the instance.
+     */
+    protected static Transformer getIdentityTransformer() throws SQLException {
+
+        if (JDBCSQLXML.identityTransformer == null) {
+            try {
+                JDBCSQLXML.identityTransformer =
+                    getTransformerFactory().newTransformer();
+            } catch (TransformerConfigurationException ex) {
+                throw Exceptions.transformFailed(ex);
+            }
+        }
+
+        return JDBCSQLXML.identityTransformer;
+    }
+
+    /**
+     * @return with which to construct DOM implementation instances.
+     * @throws java.sql.SQLException when unable to obtain a factory instance.
+     */
+    protected static DOMImplementationRegistry getDOMImplementationRegistry() throws SQLException {
+
+        if (domImplementationRegistry == null) {
+            try {
+                domImplementationRegistry =
+                    DOMImplementationRegistry.newInstance();
+            } catch (ClassCastException ex) {
+                throw Exceptions.domInstantiation(ex);
+            } catch (InstantiationException ex) {
+                throw Exceptions.domInstantiation(ex);
+            } catch (ClassNotFoundException ex) {
+                throw Exceptions.domInstantiation(ex);
+            } catch (IllegalAccessException ex) {
+                throw Exceptions.domInstantiation(ex);
+            }
+        }
+
+        return domImplementationRegistry;
+    }
+
+    /**
+     * @return with which to create document instances.
+     * @throws java.sql.SQLException when unable to obtain the DOM
+     *         implementation instance.
+     */
+    protected static DOMImplementation getDOMImplementation() throws SQLException {
+
+        if (domImplementation == null) {
+            domImplementation =
+                getDOMImplementationRegistry().getDOMImplementation(
+                    domFeatures);
+        }
+
+        if (domImplementation == null) {
+            Exception ex = new RuntimeException("Not supported: "
+                + domFeatures);
+
+            throw Exceptions.domInstantiation(ex);
+        }
+
+        return domImplementation;
+    }
+
+    /**
+     * @param namespaceURI of the document element to create or <code>null</code>.
+     * @param qualifiedName of the document element to be created or <code>null</code>.
+     * @param docType of document to be created or <code>null</code>.
+     *   When <code>doctype</code> is not <code>null</code>, its
+     *   <code>Node.ownerDocument</code> attribute is set to the document
+     *   being created.
+     * @return with its document element.
+     *   If the <code>NamespaceURI</code>, <code>qualifiedName</code>, and
+     *   <code>doctype</code> are <code>null</code>, the returned
+     *   <code>Document</code> is empty with no document element.
+     * @throws java.sql.SQLException wrapping any internal exception that occurs.
+     * @see org.w3c.dom.DOMImplementation#createDocument(String,String,DocumentType)
+     */
+    protected static Document createDocument(String namespaceURI,
+            String qualifiedName, DocumentType docType) throws SQLException {
+
+        try {
+            return getDOMImplementation().createDocument(namespaceURI,
+                    qualifiedName, docType);
+        } catch (DOMException ex) {
+            throw Exceptions.domInstantiation(ex);
+        }
+    }
+
+    /**
+     * @return that is empty with no document element.
+     * @throws java.sql.SQLException wrapping any internal exception that occurs.
+     */
+    protected static Document createDocument() throws SQLException {
+        return createDocument(null, null, null);
+    }
+
+    /**
+     * Initializes this object's SQLXML value from the given Source
+     * object. <p>
+     *
+     * @param source the Source representing the SQLXML value
+     * @throws SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected void init(Source source) throws SQLException {
+
+        if (source == null) {
+            throw Util.nullArgument("source");
+        }
+
+        Transformer           transformer =
+            JDBCSQLXML.getIdentityTransformer();
+        StreamResult          result      = new StreamResult();
+        ByteArrayOutputStream baos        = new ByteArrayOutputStream();
+        GZIPOutputStream      gzos;
+
+        try {
+            gzos = new GZIPOutputStream(baos);
+        } catch (IOException ex) {
+            throw Exceptions.transformFailed(ex);
+        }
+        result.setOutputStream(gzos);
+
+        try {
+            transformer.transform(source, result);
+        } catch (TransformerException ex) {
+            throw Exceptions.transformFailed(ex);
+        }
+
+        try {
+            gzos.close();
+        } catch (IOException ex) {
+            throw Exceptions.transformFailed(ex);
+        }
+
+        byte[] data = baos.toByteArray();
+
+        setGZipData(data);
+        setReadable(true);
+        setWritable(false);
+    }
+
+    /**
+     * Assigns this object's SQLXML value from the designated gzipped array
+     * of bytes.
+     *
+     * @param data the SQLXML value
+     * @throws java.sql.SQLException if the argument does not represent a
+     *      valid SQLXML value
+     */
+    protected void setGZipData(byte[] data) throws SQLException {
+
+        if (data == null) {
+            throw Util.nullArgument("data");
+        }
+        this.gzdata = data;
+    }
+
+    /**
+     * Directly retrieves this object's present SQLMXL value as a gzipped
+     * array of bytes. <p>
+     *
+     * May be null, empty or invalid.
+     *
+     * @return this object's SQLMXL value as a gzipped byte array
+     */
+    protected byte[] gZipData() {
+        return this.gzdata;
+    }
+
+    /**
+     * Retrieves this object's SQLXML value as a gzipped array of bytes,
+     * possibly by terminating any in-progress write operations and converting
+     * accumulated intermediate data.
+     *
+     * @throws java.sql.SQLException if an underlying I/O or transform
+     *      error occurs
+     * @return this object's SQLXML value
+     */
+    protected byte[] getGZipData() throws SQLException {
+
+        byte[] bytes = gZipData();
+
+        if (bytes != null) {
+            return bytes;
+        }
+
+        if (this.domResult != null) {
+            DOMSource source = new DOMSource(
+                    domResult.getNode(),
+                    domResult.getSystemId());
+            OutputStream os = setBinaryStreamImpl();
+            StreamResult result = new StreamResult(os);
+
+            try {
+                JDBCSQLXML.identityTransformer.transform(source, result);
+            } catch (TransformerException ex) {
+                throw Exceptions.transformFailed(ex);
+            }
+            try {
+                os.close();
+            } catch (IOException ex) {
+                throw Exceptions.transformFailed(ex);
+            }
+        }
+
+        if (this.outputStream == null) {
+            throw Exceptions.notReadable("No Data.");
+        } else if (!this.outputStream.isClosed()) {
+            throw Exceptions.notReadable(
+                "Stream used for writing must be closed but is still open.");
+        } else if (this.outputStream.isFreed()) {
+            throw Exceptions.notReadable(
+                "Stream used for writing was freed and is no longer valid.");
+        }
+
+        try {
+            setGZipData(this.outputStream.toByteArray());
+
+            return gZipData();
+        } catch (IOException ex) {
+            throw Exceptions.notReadable();
+        } finally {
+            this.freeOutputStream();
+        }
+    }
+
+    /**
+     * closes this object and releases the resources that it holds.
+     */
+    protected synchronized void close() {
+
+        this.closed = true;
+
+        setReadable(false);
+        setWritable(false);
+        freeOutputStream();
+        freeInputStream();
+        freeDomResult();
+
+        this.gzdata = null;
+    }
+
+    /**
+     * Closes the input stream, if any, currently in use to read this object's
+     * SQLXML value and nullifies the stream reference to make it elligible
+     * for subsequent garbage collection.
+     */
+    protected void freeInputStream() {
+
+        if (this.inputStream != null) {
+            try {
+                this.inputStream.close();
+            } catch (IOException ex) {
+
+                // ex.printStackTrace();
+            } finally {
+                this.inputStream = null;
+            }
+        }
+    }
+
+    /**
+     * Closes the output stream, if any, currently in use to write this object's
+     * SQLXML value and nullifies the stream reference to make it elligible for
+     * subsequent garbage collection.  The stream's data buffer reference may
+     * also be nullified, in order to make it elligible for garbage collection
+     * immediately, just in case an external client still holds a reference to
+     * the output stream.
+     */
+    protected void freeOutputStream() {
+
+        if (this.outputStream != null) {
+            try {
+                this.outputStream.free();
+            } catch (IOException ex) {
+
+                // ex.printStackTrace();
+            }
+            this.outputStream = null;
+        }
+    }
+
+    /**
+     * Checks whether this object is closed (has been freed).
+     *
+     * @throws java.sql.SQLException if this object is closed.
+     */
+    protected synchronized void checkClosed() throws SQLException {
+
+        if (this.closed) {
+            throw Exceptions.inFreedState();
+        }
+    }
+
+    /**
+     * Checks whether this object is readable.
+     *
+     * @throws java.sql.SQLException if this object is not readable.
+     */
+    protected synchronized void checkReadable() throws SQLException {
+
+        if (!this.isReadable()) {
+            throw Exceptions.notReadable();
+        }
+    }
+
+    /**
+     * Assigns this object's readability status.
+     *
+     * @param readable if <tt>true</tt>, then readable; else not readable
+     */
+    protected synchronized void setReadable(boolean readable) {
+        this.readable = readable;
+    }
+
+    /**
+     * Checks whether this object is writable.
+     *
+     * @throws java.sql.SQLException if this object is not writable.
+     */
+    protected synchronized void checkWritable() throws SQLException {
+
+        if (!this.isWritable()) {
+            throw Exceptions.notWritable();
+        }
+    }
+
+    /**
+     * Assigns this object's writability status.
+     *
+     * @param writable if <tt>true</tt>, then writable; else not writable
+     */
+    protected synchronized void setWritable(boolean writable) {
+        this.writable = writable;
+    }
+
+    /**
+     * Retrieves the object's readability status.
+     *
+     * @return if <tt>true</tt>, then readable; else not readable
+     */
+    public synchronized boolean isReadable() {
+        return this.readable;
+    }
+
+    /**
+     * Retrieves the object's readability status.
+     *
+     * @return if <tt>true</tt>, then writable; else not writable
+     */
+    public synchronized boolean isWritable() {
+        return this.writable;
+    }
+
+    /**
+     * Retrieves a stream representing the XML value designated by this
+     * SQLXML instance. <p>
+     *
+     * @return a stream containing the XML data.
+     * @throws SQLException if there is an error processing the XML value.
+     */
+    protected InputStream getBinaryStreamImpl() throws SQLException {
+
+        try {
+            byte[]               data = getGZipData();
+            ByteArrayInputStream bais = new ByteArrayInputStream(data);
+
+            return new GZIPInputStream(bais);
+        } catch (IOException ex) {
+            throw Exceptions.transformFailed(ex);
+        }
+    }
+
+    /**
+     * Retrieves a reader representing the XML value designated by this
+     * SQLXML instance. <p>
+     *
+     * @return a reader containing the XML data.
+     * @throws SQLException if there is an error processing the XML value.
+     */
+    protected Reader getCharacterStreamImpl() throws SQLException {
+        return new InputStreamReader(getBinaryStreamImpl());
+    }
+
+    /**
+     * Retrieves a string representing the XML value designated by this
+     * SQLXML instance. <p>
+     *
+     * @return a string containing the XML data.
+     * @throws SQLException if there is an error processing the XML value.
+     */
+    protected String getStringImpl() throws SQLException {
+
+        try {
+            return StringConverter.inputStreamToString(getBinaryStreamImpl(),
+                    "US-ASCII");
+        } catch (IOException ex) {
+            throw Exceptions.transformFailed(ex);
+        }
+    }
+
+    /**
+     * Retrieves a stream to completely write the XML value this SQLXML
+     * instance represents. <p>
+     *
+     * @return a stream to which the data can be written.
+     * @throws SQLException if there is an error processing the XML value.
+     */
+    protected OutputStream setBinaryStreamImpl() throws SQLException {
+
+        this.outputStream = new ClosableByteArrayOutputStream();
+
+        try {
+            return new GZIPOutputStream(this.outputStream);
+        } catch (IOException ex) {
+            this.outputStream = null;
+
+            throw Exceptions.resultInstantiation(ex);
+        }
+    }
+
+    /**
+     * Retrieves a writer to completely write the XML value this SQLXML
+     * instance represents. <p>
+     *
+     * @return a writer to which the data can be written.
+     * @throws SQLException if there is an error processing the XML value.
+     *   The getCause() method of the exception may provide a more detailed exception, for example,
+     *   if the stream does not contain valid characters.
+     *   An exception is thrown if the state is not writable.
+     * @since JDK 1.6 Build 79
+     */
+    protected Writer setCharacterStreamImpl() throws SQLException {
+        return new OutputStreamWriter(setBinaryStreamImpl());
+    }
+
+    /**
+     * Sets the XML value designated by this SQLXML instance using the given
+     * String representation. <p>
+     *
+     * @param value the XML value
+     * @throws SQLException if there is an error processing the XML value.
+     */
+    protected void setStringImpl(String value) throws SQLException {
+        init(new StreamSource(new StringReader(value)));
+    }
+
+    /**
+     * Returns a Source for reading the XML value designated by this SQLXML
+     * instance. <p>
+     *
+     * @param sourceClass The class of the source, or null.  If null, then a
+     *      DOMSource is returned.
+     * @return a Source for reading the XML value.
+     * @throws SQLException if there is an error processing the XML value
+     *   or if the given <tt>sourceClass</tt> is not supported.
+     */
+    protected <T extends Source>T getSourceImpl(
+            Class<T> sourceClass) throws SQLException {
+
+        if (JAXBSource.class.isAssignableFrom(sourceClass)) {
+
+            // Must go first presently, since JAXBSource extends SAXSource
+            // (purely as an implmentation detail) and it's not possible
+            // to instantiate a valid JAXBSource with a Zero-Args
+            // constructor(or any subclass thereof, due to the finality of
+            // its private marshaller and context object attrbutes)
+            // FALL THROUGH... will throw an exception
+        } else if (StreamSource.class.isAssignableFrom(sourceClass)) {
+            return createStreamSource(sourceClass);
+        } else if ((sourceClass == null)
+                   || DOMSource.class.isAssignableFrom(sourceClass)) {
+            return createDOMSource(sourceClass);
+        } else if (SAXSource.class.isAssignableFrom(sourceClass)) {
+            return createSAXSource(sourceClass);
+        } else if (StAXSource.class.isAssignableFrom(sourceClass)) {
+            return createStAXSource(sourceClass);
+        }
+
+        throw Util.invalidArgument("sourceClass: " + sourceClass);
+    }
+
+    /**
+     * Retrieves a new StreamSource for reading the XML value designated by this
+     * SQLXML instance. <p>
+     *
+     * @param sourceClass The class of the source
+     * @throws java.sql.SQLException if there is an error processing the XML
+     *      value or if the given <tt>sourceClass</tt> is not supported.
+     * @return a new StreamSource for reading the XML value designated by this
+     *      SQLXML instance
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends Source>T createStreamSource(
+            Class<T> sourceClass) throws SQLException {
+
+        StreamSource source = null;
+
+        try {
+            source = (sourceClass == null) ? new StreamSource()
+                    : (StreamSource) sourceClass.newInstance();
+        } catch (SecurityException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (InstantiationException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (IllegalAccessException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (ClassCastException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        }
+
+        Reader reader = getCharacterStreamImpl();
+
+        source.setReader(reader);
+
+        return (T) source;
+    }
+
+    /**
+     * Retrieves a new DOMSource for reading the XML value designated by this
+     * SQLXML instance. <p>
+     *
+     * @param sourceClass The class of the source
+     * @throws java.sql.SQLException if there is an error processing the XML
+     *      value or if the given <tt>sourceClass</tt> is not supported.
+     * @return a new DOMSource for reading the XML value designated by this
+     *      SQLXML instance
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends Source>T createDOMSource(
+            Class<T> sourceClass) throws SQLException {
+
+        DOMSource source = null;
+
+        try {
+            source = (sourceClass == null) ? new DOMSource()
+                    : (DOMSource) sourceClass.newInstance();
+        } catch (SecurityException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (IllegalAccessException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (InstantiationException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (ClassCastException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        }
+
+        Transformer  transformer  = JDBCSQLXML.getIdentityTransformer();
+        InputStream  stream       = this.getBinaryStreamImpl();
+        StreamSource streamSource = new StreamSource();
+        DOMResult    result       = new DOMResult();
+
+        streamSource.setInputStream(stream);
+
+        try {
+            transformer.transform(streamSource, result);
+        } catch (TransformerException ex) {
+            throw Exceptions.transformFailed(ex);
+        }
+        source.setNode(result.getNode());
+        source.setSystemId(result.getSystemId());
+
+        return (T) source;
+    }
+
+    /**
+     * Retrieves a new SAXSource for reading the XML value designated by this
+     * SQLXML instance. <p>
+     *
+     * @param sourceClass The class of the source
+     * @throws java.sql.SQLException if there is an error processing the XML
+     *      value or if the given <tt>sourceClass</tt> is not supported.
+     * @return a new SAXSource for reading the XML value designated by this
+     *      SQLXML instance
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends Source>T createSAXSource(
+            Class<T> sourceClass) throws SQLException {
+
+        SAXSource source = null;
+
+        try {
+            source = (sourceClass == null) ? new SAXSource()
+                    : (SAXSource) sourceClass.newInstance();
+        } catch (SecurityException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (InstantiationException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (IllegalAccessException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (ClassCastException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        }
+
+        Reader      reader      = getCharacterStreamImpl();
+        InputSource inputSource = new InputSource(reader);
+
+        source.setInputSource(inputSource);
+
+        return (T) source;
+    }
+
+    /**
+     * Retrieves a new StAXSource for reading the XML value designated by this
+     * SQLXML instance. <p>
+     *
+     * @param sourceClass The class of the source
+     * @throws java.sql.SQLException if there is an error processing the XML
+     *      value or if the given <tt>sourceClass</tt> is not supported.
+     * @return a new StAXSource for reading the XML value designated by this
+     *      SQLXML instance
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends Source>T createStAXSource(
+            Class<T> sourceClass) throws SQLException {
+
+        StAXSource      source      = null;
+        Constructor     sourceCtor  = null;
+        Reader          reader      = null;
+        XMLInputFactory factory     = null;
+        XMLEventReader  eventReader = null;
+
+        try {
+            factory = XMLInputFactory.newInstance();
+        } catch (FactoryConfigurationError ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        }
+
+        try {
+            sourceCtor =
+                (sourceClass == null)
+                ? StAXSource.class.getConstructor(XMLEventReader.class)
+                : sourceClass.getConstructor(XMLEventReader.class);
+        } catch (SecurityException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (NoSuchMethodException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        }
+        reader = getCharacterStreamImpl();
+
+        try {
+            eventReader = factory.createXMLEventReader(reader);
+        } catch (XMLStreamException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        }
+
+        try {
+            source = (StAXSource) sourceCtor.newInstance(eventReader);
+        } catch (SecurityException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (IllegalArgumentException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (IllegalAccessException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (InstantiationException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        } catch (InvocationTargetException ex) {
+            throw Exceptions.sourceInstantiation(ex.getTargetException());
+        } catch (ClassCastException ex) {
+            throw Exceptions.sourceInstantiation(ex);
+        }
+
+        return (T) source;
+    }
+
+    /**
+     * Retrieves a new Result for setting the XML value designated by this
+     * SQLXML instance.
+     *
+     * @param resultClass The class of the result, or null.
+     * @throws java.sql.SQLException if there is an error processing the XML
+     *         value or the state is not writable
+     * @return for setting the XML value designated by this SQLXML instance.
+     */
+    protected <T extends Result>T createResult(
+            Class<T> resultClass) throws SQLException {
+
+        checkWritable();
+        setWritable(false);
+        setReadable(true);
+
+        if (JAXBResult.class.isAssignableFrom(resultClass)) {
+
+            // Must go first presently, since JAXBResult extends SAXResult
+            // (purely as an implmentation detail) and it's not possible
+            // to instantiate a valid JAXBResult with a Zero-Args
+            // constructor(or any subclass thereof, due to the finality of
+            // its private UnmarshallerHandler)
+            // FALL THROUGH... will throw an exception
+        } else if ((resultClass == null)
+                   || StreamResult.class.isAssignableFrom(resultClass)) {
+            return createStreamResult(resultClass);
+        } else if (DOMResult.class.isAssignableFrom(resultClass)) {
+            return createDOMResult(resultClass);
+        } else if (SAXResult.class.isAssignableFrom(resultClass)) {
+            return createSAXResult(resultClass);
+        } else if (StAXResult.class.isAssignableFrom(resultClass)) {
+            return createStAXResult(resultClass);
+        }
+
+        throw Util.invalidArgument("resultClass: " + resultClass);
+    }
+
+    /**
+     * Retrieves a new StreamResult for setting the XML value designated by this
+     * SQLXML instance.
+     *
+     * @param resultClass The class of the result, or null.
+     * @throws java.sql.SQLException if there is an error processing the XML
+     *         value
+     * @return for setting the XML value designated by this SQLXML instance.
+     */
+
+//  @SuppressWarnings("unchecked")
+    protected <T extends Result>T createStreamResult(
+            Class<T> resultClass) throws SQLException {
+
+        StreamResult result = null;
+
+        try {
+            result = (resultClass == null) ? new StreamResult()
+                    : (StreamResult) resultClass.newInstance();
+        } catch (SecurityException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (InstantiationException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (IllegalAccessException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (ClassCastException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        }
+
+        OutputStream stream = setBinaryStreamImpl();
+
+        result.setOutputStream(stream);
+
+        return (T) result;
+    }
+
+    /**
+     * Retrieves a new DOMResult for setting the XML value designated by this
+     * SQLXML instance.
+     *
+     * @param resultClass The class of the result, or null.
+     * @throws java.sql.SQLException if there is an error processing the XML
+     *         value
+     * @return for setting the XML value designated by this SQLXML instance.
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends Result>T createDOMResult(
+            Class<T> resultClass) throws SQLException {
+
+        try {
+            T result = (resultClass == null) ? ((T) new DOMResult())
+                    : resultClass.newInstance();
+
+            this.domResult = (DOMResult) result;
+
+            return result;
+        } catch (SecurityException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (InstantiationException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (IllegalAccessException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (ClassCastException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        }
+    }
+
+    /**
+     *  Retrieves a new SAXResult for setting the XML value designated by this
+     *  SQLXML instance.
+     *
+     *  @param resultClass The class of the result, or null.
+     *  @throws java.sql.SQLException if there is an error processing the XML
+     *          value
+     *  @return for setting the XML value designated by this SQLXML instance.
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends Result>T createSAXResult(
+            Class<T> resultClass) throws SQLException {
+
+        SAXResult result = null;
+
+        try {
+            result = (resultClass == null) ? new SAXResult()
+                    : (SAXResult) resultClass.newInstance();
+        } catch (SecurityException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (InstantiationException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (IllegalAccessException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (ClassCastException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        }
+
+        SAX2DOMBuilder handler = null;
+
+        try {
+            handler = new SAX2DOMBuilder();
+        } catch (ParserConfigurationException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        }
+        this.domResult = new DOMResult();
+
+        result.setHandler(handler);
+        this.domResult.setNode(handler.getDocument());
+
+        return (T) result;
+    }
+
+    /**
+     *  Retrieves a new DOMResult for setting the XML value designated by this
+     *  SQLXML instance.
+     *
+     *  @param resultClass The class of the result, or null.
+     *  @throws java.sql.SQLException if there is an error processing the XML
+     *          value
+     *  @return for setting the XML value designated by this SQLXML instance.
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends Result>T createStAXResult(
+            Class<T> resultClass) throws SQLException {
+
+        StAXResult result = null;
+
+        try {
+            this.domResult =
+                new DOMResult((new SAX2DOMBuilder()).getDocument());
+
+            XMLOutputFactory factory = XMLOutputFactory.newInstance();
+            XMLStreamWriter xmlStreamWriter =
+                factory.createXMLStreamWriter(this.domResult);
+
+            if (resultClass == null || resultClass == StAXResult.class) {
+                result = new StAXResult(xmlStreamWriter);
+            } else {
+                Constructor ctor =
+                    resultClass.getConstructor(XMLStreamWriter.class);
+
+                result = (StAXResult) ctor.newInstance(xmlStreamWriter);
+            }
+        } catch (ParserConfigurationException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (SecurityException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (IllegalArgumentException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (IllegalAccessException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (InvocationTargetException ex) {
+            throw Exceptions.resultInstantiation(ex.getTargetException());
+        } catch (FactoryConfigurationError ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (InstantiationException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (NoSuchMethodException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        } catch (XMLStreamException ex) {
+            throw Exceptions.resultInstantiation(ex);
+        }
+
+        return (T) result;
+    }
+
+    protected void freeDomResult() {
+        this.domResult = null;
+    }
+
+    /**
+     * Basically just a namespace to isolate SQLXML exception generation
+     */
+    protected static class Exceptions {
+
+        /**
+         * Construction Disabled.
+         */
+        private Exceptions() {
+        }
+
+        /**
+         *  Retrieves a new SQLXML DOM instantiation exception.
+         *
+         * @param cause of the exception
+         */
+        static SQLException domInstantiation(Throwable cause) {
+
+            Exception ex = (cause instanceof Exception) ? (Exception) cause
+                    : new Exception(cause);
+
+            return Util.sqlException(ErrorCode.GENERAL_ERROR,
+                                     "SQLXML DOM instantiation failed: "
+                                     + cause, ex);
+        }
+
+        /**
+         * Retrieves a new SQLXML source instantiation exception.
+         *
+         * @param cause of the exception.
+         * @return a new SQLXML source instantiation exception
+         */
+        static SQLException sourceInstantiation(Throwable cause) {
+
+            Exception ex = (cause instanceof Exception) ? (Exception) cause
+                    : new Exception(cause);
+
+            return Util.sqlException(ErrorCode.GENERAL_ERROR,
+                                     "SQLXML Source instantiation failed: "
+                                     + cause, ex);
+        }
+
+        /**
+         * Retrieves a new SQLXML result instantiation exception.
+         *
+         * @param cause of the exception.
+         * @return a new SQLXML result instantiation exception
+         */
+        static SQLException resultInstantiation(Throwable cause) {
+
+            Exception ex = (cause instanceof Exception) ? (Exception) cause
+                    : new Exception(cause);
+
+            return Util.sqlException(ErrorCode.GENERAL_ERROR,
+                                     "SQLXML Result instantiation failed: "
+                                     + cause, ex);
+        }
+
+        /**
+         * Retrieves a new SQLXML parse failed exception.
+         *
+         * @param cause of the exception.
+         * @return a new SQLXML parse failed exception
+         */
+        static SQLException parseFailed(Throwable cause) {
+
+            Exception ex = (cause instanceof Exception) ? (Exception) cause
+                    : new Exception(cause);
+
+            return Util.sqlException(ErrorCode.GENERAL_ERROR,
+                                     "parse failed: " + cause, ex);
+        }
+
+        /**
+         * Retrieves a new SQLXML transform failed exception.
+         *
+         * @param cause of the exception.
+         * @return a new SQLXML parse failed exception
+         */
+        static SQLException transformFailed(Throwable cause) {
+
+            Exception ex = (cause instanceof Exception) ? (Exception) cause
+                    : new Exception(cause);
+
+            return Util.sqlException(ErrorCode.GENERAL_ERROR,
+                                     "transform failed: " + cause, ex);
+        }
+
+        /**
+         * Retrieves a new SQLXML not readable exception.
+         *
+         * @return a new SQLXML not readable exception
+         */
+        static SQLException notReadable() {
+            return Util.sqlException(ErrorCode.GENERAL_IO_ERROR,
+                                     "SQLXML in not readable state");
+        }
+
+        /**
+         * Retrieves a new SQLXML not readable exception.
+         *
+         * @return a new SQLXML not readable exception
+         */
+        static SQLException notReadable(String reason) {
+
+            return Util.sqlException(ErrorCode.GENERAL_IO_ERROR,
+                                     "SQLXML in not readable state: "
+                                     + reason);
+        }
+
+        /**
+         * Retrieves a new SQLXML not writable exception.
+         *
+         * @return a new SQLXML not writable exception
+         */
+        static SQLException notWritable() {
+            return Util.sqlException(ErrorCode.GENERAL_IO_ERROR,
+                                     "SQLXML in not writable state");
+        }
+
+        /**
+         * Currently unused.
+         *
+         * @return never
+         */
+        static SQLException directUpdateByLocatorNotSupported() {
+            return Util.sqlException(ErrorCode.X_0A000,
+                                     "SQLXML direct update by locator");
+        }
+
+        /**
+         * Retrieves a new SQLXML in freed state exception.
+         *
+         * @return a new SQLXML in freed state exception
+         */
+        static SQLException inFreedState() {
+            return Util.sqlException(ErrorCode.GENERAL_ERROR,
+                                     "SQLXML in freed state");
+        }
+    }
+
+    // -------------------------------------------------------------------------
+
+    /**
+     * Builds a DOM from SAX events.
+     */
+    protected static class SAX2DOMBuilder implements ContentHandler,
+            Closeable {
+
+        /**
+         *
+         */
+        private boolean closed;
+
+        /**
+         *
+         */
+        private Element currentElement;
+
+        // --------------------- internal implementation -----------------------
+
+        /**
+         *
+         */
+        private Node currentNode;
+
+        /**
+         *
+         */
+        private Document document;
+
+        /**
+         *
+         */
+        private Locator locator;
+
+        /**
+         * <p>Creates a new instance of SAX2DOMBuilder, which creates
+         * a new document. The document is available via
+         * {@link #getDocument()}.</p>
+         * @throws javax.xml.parsers.ParserConfigurationException
+         */
+        public SAX2DOMBuilder() throws ParserConfigurationException {
+
+            DocumentBuilderFactory documentBuilderFactory;
+            DocumentBuilder        documentBuilder;
+
+            documentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+            documentBuilderFactory.setValidating(false);
+            documentBuilderFactory.setNamespaceAware(true);
+
+            documentBuilder  = documentBuilderFactory.newDocumentBuilder();
+            this.document    = documentBuilder.newDocument();
+            this.currentNode = this.document;
+        }
+
+        /**
+         * Receive an object for locating the origin of SAX document events.
+         *
+         * <p>SAX parsers are strongly encouraged (though not absolutely
+         * required) to supply a locator: if it does so, it must supply
+         * the locator to the application by invoking this method before
+         * invoking any of the other methods in the ContentHandler
+         * interface.</p>
+         *
+         * <p>The locator allows the application to determine the end
+         * position of any document-related event, even if the parser is
+         * not reporting an error.  Typically, the application will
+         * use this information for reporting its own errors (such as
+         * character content that does not match an application's
+         * business rules).  The information returned by the locator
+         * is probably not sufficient for use with a search engine.</p>
+         *
+         * <p>Note that the locator will return correct information only
+         * during the invocation SAX event callbacks after
+         * {@link #startDocument startDocument} returns and before
+         * {@link #endDocument endDocument} is called.  The
+         * application should not attempt to use it at any other time.</p>
+         *
+         * @param locator an object that can return the location of
+         *                any SAX document event
+         * @see org.xml.sax.Locator
+         */
+        public void setDocumentLocator(Locator locator) {
+            this.locator = locator;
+        }
+
+        /**
+         * Retrieves the Locator. <p>
+         * @return the Locator
+         */
+        public Locator getDocumentLocator() {
+            return this.locator;
+        }
+
+        /**
+         * Receive notification of the beginning of a document.
+         *
+         * <p>The SAX parser will invoke this method only once, before any
+         * other event callbacks (except for {@link #setDocumentLocator
+         * setDocumentLocator}).</p>
+         *
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #endDocument
+         */
+        public void startDocument() throws SAXException {
+            checkClosed();
+        }
+
+        /**
+         * Receive notification of the end of a document.
+         *
+         * <p><strong>There is an apparent contradiction between the
+         * documentation for this method and the documentation for {@link
+         * org.xml.sax.ErrorHandler#fatalError}.  Until this ambiguity is
+         * resolved in a future major release, clients should make no
+         * assumptions about whether endDocument() will or will not be
+         * invoked when the parser has reported a fatalError() or thrown
+         * an exception.</strong></p>
+         *
+         * <p>The SAX parser will invoke this method only once, and it will
+         * be the last method invoked during the parse.  The parser shall
+         * not invoke this method until it has either abandoned parsing
+         * (because of an unrecoverable error) or reached the end of
+         * input.</p>
+         *
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #startDocument
+         */
+        public void endDocument() throws SAXException {
+            checkClosed();
+            close();
+        }
+
+        /**
+         * Begin the scope of a prefix-URI Namespace mapping.
+         *
+         * <p>The information from this event is not necessary for
+         * normal Namespace processing: the SAX XML reader will
+         * automatically replace prefixes for element and attribute
+         * names when the <code>http://xml.org/sax/features/namespaces</code>
+         * feature is <var>true</var> (the default).</p>
+         *
+         * <p>There are cases, however, when applications need to
+         * use prefixes in character data or in attribute values,
+         * where they cannot safely be expanded automatically; the
+         * start/endPrefixMapping event supplies the information
+         * to the application to expand prefixes in those contexts
+         * itself, if necessary.</p>
+         *
+         * <p>Note that start/endPrefixMapping events are not
+         * guaranteed to be properly nested relative to each other:
+         * all startPrefixMapping events will occur immediately before the
+         * corresponding {@link #startElement startElement} event,
+         * and all {@link #endPrefixMapping endPrefixMapping}
+         * events will occur immediately after the corresponding
+         * {@link #endElement endElement} event,
+         * but their order is not otherwise
+         * guaranteed.</p>
+         *
+         * <p>There should never be start/endPrefixMapping events for the
+         * "xml" prefix, since it is predeclared and immutable.</p>
+         *
+         * @param prefix the Namespace prefix being declared.
+         *      An empty string is used for the default element namespace,
+         *      which has no prefix.
+         * @param uri the Namespace URI the prefix is mapped to
+         * @throws org.xml.sax.SAXException the client may throw
+         *            an exception during processing
+         * @see #endPrefixMapping
+         * @see #startElement
+         */
+        public void startPrefixMapping(String prefix,
+                                       String uri) throws SAXException {
+            checkClosed();
+        }
+
+        /**
+         * End the scope of a prefix-URI mapping.
+         *
+         * <p>See {@link #startPrefixMapping startPrefixMapping} for
+         * details.  These events will always occur immediately after the
+         * corresponding {@link #endElement endElement} event, but the order of
+         * {@link #endPrefixMapping endPrefixMapping} events is not otherwise
+         * guaranteed.</p>
+         *
+         * @param prefix the prefix that was being mapped.
+         *      This is the empty string when a default mapping scope ends.
+         * @throws org.xml.sax.SAXException the client may throw
+         *            an exception during processing
+         * @see #startPrefixMapping
+         * @see #endElement
+         */
+        public void endPrefixMapping(String prefix) throws SAXException {
+            checkClosed();
+        }
+
+        /**
+         * Receive notification of the beginning of an element.
+         *
+         * <p>The Parser will invoke this method at the beginning of every
+         * element in the XML document; there will be a corresponding
+         * {@link #endElement endElement} event for every startElement event
+         * (even when the element is empty). All of the element's content will be
+         * reported, in order, before the corresponding endElement
+         * event.</p>
+         *
+         * <p>This event allows up to three name components for each
+         * element:</p>
+         *
+         * <ol>
+         * <li>the Namespace URI;</li>
+         * <li>the local name; and</li>
+         * <li>the qualified (prefixed) name.</li>
+         * </ol>
+         *
+         * <p>Any or all of these may be provided, depending on the
+         * values of the <var>http://xml.org/sax/features/namespaces</var>
+         * and the <var>http://xml.org/sax/features/namespace-prefixes</var>
+         * properties:</p>
+         *
+         * <ul>
+         * <li>the Namespace URI and local name are required when
+         * the namespaces property is <var>true</var> (the default), and are
+         * optional when the namespaces property is <var>false</var> (if one is
+         * specified, both must be);</li>
+         * <li>the qualified name is required when the namespace-prefixes property
+         * is <var>true</var>, and is optional when the namespace-prefixes property
+         * is <var>false</var> (the default).</li>
+         * </ul>
+         *
+         * <p>Note that the attribute list provided will contain only
+         * attributes with explicit values (specified or defaulted):
+         * #IMPLIED attributes will be omitted.  The attribute list
+         * will contain attributes used for Namespace declarations
+         * (xmlns* attributes) only if the
+         * <code>http://xml.org/sax/features/namespace-prefixes</code>
+         * property is true (it is false by default, and support for a
+         * true value is optional).</p>
+         *
+         * <p>Like {@link #characters characters()}, attribute values may have
+         * characters that need more than one <code>char</code> value.  </p>
+         *
+         * @param uri the Namespace URI, or the empty string if the
+         *        element has no Namespace URI or if Namespace
+         *        processing is not being performed
+         * @param localName the local name (without prefix), or the
+         *        empty string if Namespace processing is not being
+         *        performed
+         * @param qName the qualified name (with prefix), or the
+         *        empty string if qualified names are not available
+         * @param atts the attributes attached to the element.  If
+         *        there are no attributes, it shall be an empty
+         *        Attributes object.  The value of this object after
+         *        startElement returns is undefined
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #endElement
+         * @see org.xml.sax.Attributes
+         * @see org.xml.sax.helpers.AttributesImpl
+         */
+        public void startElement(String uri, String localName, String qName,
+                                 Attributes atts) throws SAXException {
+
+            checkClosed();
+
+            Element element;
+
+            if ((uri == null) || (uri.length() == 0)) {
+                element = getDocument().createElement(qName);
+            } else {
+                element = getDocument().createElementNS(uri, qName);
+            }
+
+            if (atts != null) {
+                for (int i = 0; i < atts.getLength(); i++) {
+                    String attrURI   = atts.getURI(i);
+                    String attrQName = atts.getQName(i);
+                    String attrValue = atts.getValue(i);
+
+                    if ((attrURI == null) || (attrURI.length() == 0)) {
+                        element.setAttribute(attrQName, attrValue);
+                    } else {
+                        element.setAttributeNS(attrURI, attrQName, attrValue);
+                    }
+                }
+            }
+            getCurrentNode().appendChild(element);
+            setCurrentNode(element);
+
+            if (getCurrentElement() == null) {
+                setCurrentElement(element);
+            }
+        }
+
+        /**
+         * Receive notification of the end of an element.
+         *
+         * <p>The SAX parser will invoke this method at the end of every
+         * element in the XML document; there will be a corresponding
+         * {@link #startElement startElement} event for every endElement
+         * event (even when the element is empty).</p>
+         *
+         * <p>For information on the names, see startElement.</p>
+         *
+         * @param uri the Namespace URI, or the empty string if the
+         *        element has no Namespace URI or if Namespace
+         *        processing is not being performed
+         * @param localName the local name (without prefix), or the
+         *        empty string if Namespace processing is not being
+         *        performed
+         * @param qName the qualified XML name (with prefix), or the
+         *        empty string if qualified names are not available
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         */
+        public void endElement(String uri, String localName,
+                               String qName) throws SAXException {
+            checkClosed();
+            setCurrentNode(getCurrentNode().getParentNode());
+        }
+
+        /**
+         * Receive notification of character data.
+         *
+         * <p>The Parser will call this method to report each chunk of
+         * character data.  SAX parsers may return all contiguous character
+         * data in a single chunk, or they may split it into several
+         * chunks; however, all of the characters in any single event
+         * must come from the same external entity so that the Locator
+         * provides useful information.</p>
+         *
+         * <p>The application must not attempt to read from the array
+         * outside of the specified range.</p>
+         *
+         * <p>Individual characters may consist of more than one Java
+         * <code>char</code> value.  There are two important cases where this
+         * happens, because characters can't be represented in just sixteen bits.
+         * In one case, characters are represented in a <em>Surrogate Pair</em>,
+         * using two special Unicode values. Such characters are in the so-called
+         * "Astral Planes", with a code point above U+FFFF.  A second case involves
+         * composite characters, such as a base character combining with one or
+         * more accent characters. </p>
+         *
+         * <p> Your code should not assume that algorithms using
+         * <code>char</code>-at-a-time idioms will be working in character
+         * units; in some cases they will split characters.  This is relevant
+         * wherever XML permits arbitrary characters, such as attribute values,
+         * processing instruction data, and comments as well as in data reported
+         * from this method.  It's also generally relevant whenever Java code
+         * manipulates internationalized text; the issue isn't unique to XML.</p>
+         *
+         * <p>Note that some parsers will report whitespace in element
+         * content using the {@link #ignorableWhitespace ignorableWhitespace}
+         * method rather than this one (validating parsers <em>must</em>
+         * do so).</p>
+         *
+         * @param ch the characters from the XML document
+         * @param start the start position in the array
+         * @param length the number of characters to read from the array
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #ignorableWhitespace
+         * @see org.xml.sax.Locator
+         */
+        public void characters(char[] ch, int start,
+                               int length) throws SAXException {
+
+            checkClosed();
+
+            Node   node = getCurrentNode().getLastChild();
+            String s    = new String(ch, start, length);
+
+            if ((node != null) && (node.getNodeType() == Node.TEXT_NODE)) {
+                ((Text) node).appendData(s);
+            } else {
+                Text text = getDocument().createTextNode(s);
+
+                getCurrentNode().appendChild(text);
+            }
+        }
+
+        /**
+         * Receive notification of ignorable whitespace in element content.
+         *
+         * <p>Validating Parsers must use this method to report each chunk
+         * of whitespace in element content (see the W3C XML 1.0
+         * recommendation, section 2.10): non-validating parsers may also
+         * use this method if they are capable of parsing and using
+         * content models.</p>
+         *
+         * <p>SAX parsers may return all contiguous whitespace in a single
+         * chunk, or they may split it into several chunks; however, all of
+         * the characters in any single event must come from the same
+         * external entity, so that the Locator provides useful
+         * information.</p>
+         *
+         * <p>The application must not attempt to read from the array
+         * outside of the specified range.</p>
+         *
+         * @param ch the characters from the XML document
+         * @param start the start position in the array
+         * @param length the number of characters to read from the array
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #characters
+         */
+        public void ignorableWhitespace(char[] ch, int start,
+                                        int length) throws SAXException {
+            characters(ch, start, length);
+        }
+
+        /**
+         * Receive notification of a processing instruction.
+         *
+         * <p>The Parser will invoke this method once for each processing
+         * instruction found: note that processing instructions may occur
+         * before or after the main document element.</p>
+         *
+         * <p>A SAX parser must never report an XML declaration (XML 1.0,
+         * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+         * using this method.</p>
+         *
+         * <p>Like {@link #characters characters()}, processing instruction
+         * data may have characters that need more than one <code>char</code>
+         * value. </p>
+         *
+         * @param target the processing instruction target
+         * @param data the processing instruction data, or null if
+         *        none was supplied.  The data does not include any
+         *        whitespace separating it from the target
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         */
+        public void processingInstruction(String target,
+                String data) throws SAXException {
+
+            checkClosed();
+
+            ProcessingInstruction processingInstruction;
+
+            processingInstruction =
+                getDocument().createProcessingInstruction(target, data);
+
+            getCurrentNode().appendChild(processingInstruction);
+        }
+
+        /**
+         * Receive notification of a skipped entity.
+         * This is not called for entity references within markup constructs
+         * such as element start tags or markup declarations.  (The XML
+         * recommendation requires reporting skipped external entities.
+         * SAX also reports internal entity expansion/non-expansion, except
+         * within markup constructs.)
+         *
+         * <p>The Parser will invoke this method each time the entity is
+         * skipped.  Non-validating processors may skip entities if they
+         * have not seen the declarations (because, for example, the
+         * entity was declared in an external DTD subset).  All processors
+         * may skip external entities, depending on the values of the
+         * <code>http://xml.org/sax/features/external-general-entities</code>
+         * and the
+         * <code>http://xml.org/sax/features/external-parameter-entities</code>
+         * properties.</p>
+         *
+         * @param name the name of the skipped entity.  If it is a
+         *        parameter entity, the name will begin with '%', and if
+         *        it is the external DTD subset, it will be the string
+         *        "[dtd]"
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         */
+        public void skippedEntity(String name) throws SAXException {
+
+            checkClosed();
+
+            EntityReference entityReference =
+                getDocument().createEntityReference(name);
+
+            getCurrentNode().appendChild(entityReference);
+        }
+
+        /**
+         * Closes this DOMBuilder.
+         */
+        public void close() {
+            this.closed = true;
+        }
+
+        /**
+         * Frees the DOMBuilder.
+         */
+        public void free() {
+
+            close();
+
+            this.document       = null;
+            this.currentElement = null;
+            this.currentNode    = null;
+            this.locator        = null;
+        }
+
+        /**
+         * Retrieves whether this DOMBuilder is closed.
+         */
+        public boolean isClosed() {
+            return this.closed;
+        }
+
+        /**
+         * Checks whether this DOMBuilder is closed.
+         *
+         * @throws SAXException if this DOMBuilder is closed.
+         */
+        protected void checkClosed() throws SAXException {
+
+            if (isClosed()) {
+                throw new SAXException("content handler is closed.");    // NOI18N
+            }
+        }
+
+        /**
+         * Retrieves the document. <p>
+         */
+        public Document getDocument() {
+            return this.document;
+        }
+
+        /**
+         * Retreives the current element. <p>
+         */
+        protected Element getCurrentElement() {
+            return this.currentElement;
+        }
+
+        /**
+         * Assigns the current element.
+         * @param element
+         */
+        protected void setCurrentElement(Element element) {
+            this.currentElement = element;
+        }
+
+        /**
+         * Retrieves the current node. <p>
+         */
+        protected Node getCurrentNode() {
+            return this.currentNode;
+        }
+
+        /**
+         * Assigns the current node. <p>
+         * @param node
+         */
+        protected void setCurrentNode(Node node) {
+            this.currentNode = node;
+        }
+    }
+
+    /**
+     * Writes to a {@link javax.xml.stream.XMLStreamWriter XMLStreamWriter}
+     * from SAX events.
+     */
+    public static class SAX2XMLStreamWriter implements ContentHandler,
+            Closeable {
+
+        /**
+         * Namespace declarations for an upcoming element.
+         */
+        private List<QualifiedName> namespaces =
+            new ArrayList<QualifiedName>();
+
+        /**
+         * Whether this object is closed.
+         */
+        private boolean closed;
+
+        /**
+         * This object's SAX locator.
+         */
+        private Locator locator;
+
+        /**
+         * XML stream writer where events are pushed.
+         */
+        private XMLStreamWriter writer;
+
+        /**
+         * Constructs a new SAX2XMLStreamWriter that writes SAX events to the
+         * designated XMLStreamWriter.
+         *
+         * @param writer the writer to which to write SAX events
+         */
+        public SAX2XMLStreamWriter(XMLStreamWriter writer) {
+
+            if (writer == null) {
+                throw new NullPointerException("writer");
+            }
+            this.writer = writer;
+        }
+
+        /**
+         * Receive notification of the beginning of a document.
+         *
+         * <p>The SAX parser will invoke this method only once, before any
+         * other event callbacks (except for {@link #setDocumentLocator
+         * setDocumentLocator}).</p>
+         *
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #endDocument
+         */
+        public void startDocument() throws SAXException {
+
+            checkClosed();
+
+            try {
+                this.writer.writeStartDocument();
+            } catch (XMLStreamException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        /**
+         * Receive notification of the end of a document.
+         *
+         * <p><strong>There is an apparent contradiction between the
+         * documentation for this method and the documentation for {@link
+         * org.xml.sax.ErrorHandler#fatalError}.  Until this ambiguity is
+         * resolved in a future major release, clients should make no
+         * assumptions about whether endDocument() will or will not be
+         * invoked when the parser has reported a fatalError() or thrown
+         * an exception.</strong></p>
+         *
+         * <p>The SAX parser will invoke this method only once, and it will
+         * be the last method invoked during the parse.  The parser shall
+         * not invoke this method until it has either abandoned parsing
+         * (because of an unrecoverable error) or reached the end of
+         * input.</p>
+         *
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #startDocument
+         */
+        public void endDocument() throws SAXException {
+
+            checkClosed();
+
+            try {
+                this.writer.writeEndDocument();
+                this.writer.flush();
+            } catch (XMLStreamException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        /**
+         * Receive notification of character data.
+         *
+         * <p>The Parser will call this method to report each chunk of
+         * character data.  SAX parsers may return all contiguous character
+         * data in a single chunk, or they may split it into several
+         * chunks; however, all of the characters in any single event
+         * must come from the same external entity so that the Locator
+         * provides useful information.</p>
+         *
+         * <p>The application must not attempt to read from the array
+         * outside of the specified range.</p>
+         *
+         * <p>Individual characters may consist of more than one Java
+         * <code>char</code> value.  There are two important cases where this
+         * happens, because characters can't be represented in just sixteen bits.
+         * In one case, characters are represented in a <em>Surrogate Pair</em>,
+         * using two special Unicode values. Such characters are in the so-called
+         * "Astral Planes", with a code point above U+FFFF.  A second case involves
+         * composite characters, such as a base character combining with one or
+         * more accent characters. </p>
+         *
+         * <p> Your code should not assume that algorithms using
+         * <code>char</code>-at-a-time idioms will be working in character
+         * units; in some cases they will split characters.  This is relevant
+         * wherever XML permits arbitrary characters, such as attribute values,
+         * processing instruction data, and comments as well as in data reported
+         * from this method.  It's also generally relevant whenever Java code
+         * manipulates internationalized text; the issue isn't unique to XML.</p>
+         *
+         * <p>Note that some parsers will report whitespace in element
+         * content using the {@link #ignorableWhitespace ignorableWhitespace}
+         * method rather than this one (validating parsers <em>must</em>
+         * do so).</p>
+         *
+         * @param ch the characters from the XML document
+         * @param start the start position in the array
+         * @param length the number of characters to read from the array
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #ignorableWhitespace
+         * @see org.xml.sax.Locator
+         */
+        public void characters(char[] ch, int start,
+                               int length) throws SAXException {
+
+            checkClosed();
+
+            try {
+                this.writer.writeCharacters(ch, start, length);
+            } catch (XMLStreamException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        /**
+         * Receive notification of the beginning of an element.
+         *
+         * <p>The Parser will invoke this method at the beginning of every
+         * element in the XML document; there will be a corresponding
+         * {@link #endElement endElement} event for every startElement event
+         * (even when the element is empty). All of the element's content will be
+         * reported, in order, before the corresponding endElement
+         * event.</p>
+         *
+         * <p>This event allows up to three name components for each
+         * element:</p>
+         *
+         * <ol>
+         * <li>the Namespace URI;</li>
+         * <li>the local name; and</li>
+         * <li>the qualified (prefixed) name.</li>
+         * </ol>
+         *
+         * <p>Any or all of these may be provided, depending on the
+         * values of the <var>http://xml.org/sax/features/namespaces</var>
+         * and the <var>http://xml.org/sax/features/namespace-prefixes</var>
+         * properties:</p>
+         *
+         * <ul>
+         * <li>the Namespace URI and local name are required when
+         * the namespaces property is <var>true</var> (the default), and are
+         * optional when the namespaces property is <var>false</var> (if one is
+         * specified, both must be);</li>
+         * <li>the qualified name is required when the namespace-prefixes property
+         * is <var>true</var>, and is optional when the namespace-prefixes property
+         * is <var>false</var> (the default).</li>
+         * </ul>
+         *
+         * <p>Note that the attribute list provided will contain only
+         * attributes with explicit values (specified or defaulted):
+         * #IMPLIED attributes will be omitted.  The attribute list
+         * will contain attributes used for Namespace declarations
+         * (xmlns* attributes) only if the
+         * <code>http://xml.org/sax/features/namespace-prefixes</code>
+         * property is true (it is false by default, and support for a
+         * true value is optional).</p>
+         *
+         * <p>Like {@link #characters characters()}, attribute values may have
+         * characters that need more than one <code>char</code> value.  </p>
+         *
+         * @param namespaceURI the Namespace URI, or the empty string if the
+         *        element has no Namespace URI or if Namespace
+         *        processing is not being performed
+         * @param localName the local name (without prefix), or the
+         *        empty string if Namespace processing is not being
+         *        performed
+         * @param qName the qualified name (with prefix), or the
+         *        empty string if qualified names are not available
+         * @param atts the attributes attached to the element.  If
+         *        there are no attributes, it shall be an empty
+         *        Attributes object.  The value of this object after
+         *        startElement returns is undefined
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #endElement
+         * @see org.xml.sax.Attributes
+         * @see org.xml.sax.helpers.AttributesImpl
+         */
+        public void startElement(String namespaceURI, String localName,
+                                 String qName,
+                                 Attributes atts) throws SAXException {
+
+            checkClosed();
+
+            try {
+                int    qi     = qName.indexOf(':');
+                String prefix = (qi > 0) ? qName.substring(0, qi)
+                        : "";
+
+                this.writer.writeStartElement(prefix, localName, namespaceURI);
+
+                int length = namespaces.size();
+
+                for (int i = 0; i < length; i++) {
+                    QualifiedName ns = namespaces.get(i);
+
+                    this.writer.writeNamespace(ns.prefix, ns.namespaceName);
+                }
+                namespaces.clear();
+
+                length = atts.getLength();
+
+                for (int i = 0; i < length; i++) {
+                    this.writer.writeAttribute(atts.getURI(i),
+                            atts.getLocalName(i), atts.getValue(i));
+                }
+            } catch (XMLStreamException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        /**
+         * Receive notification of the end of an element.
+         *
+         * <p>The SAX parser will invoke this method at the end of every
+         * element in the XML document; there will be a corresponding
+         * {@link #startElement startElement} event for every endElement
+         * event (even when the element is empty).</p>
+         *
+         * <p>For information on the names, see startElement.</p>
+         *
+         * @param namespaceURI the Namespace URI, or the empty string if the
+         *        element has no Namespace URI or if Namespace
+         *        processing is not being performed
+         * @param localName the local name (without prefix), or the
+         *        empty string if Namespace processing is not being
+         *        performed
+         * @param qName the qualified XML name (with prefix), or the
+         *        empty string if qualified names are not available
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         */
+        public void endElement(String namespaceURI, String localName,
+                               String qName) throws SAXException {
+
+            checkClosed();
+
+            try {
+                this.writer.writeEndElement();
+            } catch (XMLStreamException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        /**
+         * Begin the scope of a prefix-URI Namespace mapping.
+         *
+         * <p>The information from this event is not necessary for
+         * normal Namespace processing: the SAX XML reader will
+         * automatically replace prefixes for element and attribute
+         * names when the <code>http://xml.org/sax/features/namespaces</code>
+         * feature is <var>true</var> (the default).</p>
+         *
+         * <p>There are cases, however, when applications need to
+         * use prefixes in character data or in attribute values,
+         * where they cannot safely be expanded automatically; the
+         * start/endPrefixMapping event supplies the information
+         * to the application to expand prefixes in those contexts
+         * itself, if necessary.</p>
+         *
+         * <p>Note that start/endPrefixMapping events are not
+         * guaranteed to be properly nested relative to each other:
+         * all startPrefixMapping events will occur immediately before the
+         * corresponding {@link #startElement startElement} event,
+         * and all {@link #endPrefixMapping endPrefixMapping}
+         * events will occur immediately after the corresponding
+         * {@link #endElement endElement} event,
+         * but their order is not otherwise
+         * guaranteed.</p>
+         *
+         * <p>There should never be start/endPrefixMapping events for the
+         * "xml" prefix, since it is predeclared and immutable.</p>
+         *
+         * @param prefix the Namespace prefix being declared.
+         *      An empty string is used for the default element namespace,
+         *      which has no prefix.
+         * @param uri the Namespace URI the prefix is mapped to
+         * @throws org.xml.sax.SAXException the client may throw
+         *            an exception during processing
+         * @see #endPrefixMapping
+         * @see #startElement
+         */
+        public void startPrefixMapping(String prefix,
+                                       String uri) throws SAXException {
+
+            checkClosed();
+
+            try {
+                this.writer.setPrefix(prefix, uri);
+                namespaces.add(new QualifiedName(prefix, uri));
+            } catch (XMLStreamException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        /**
+         * End the scope of a prefix-URI mapping.
+         *
+         * <p>See {@link #startPrefixMapping startPrefixMapping} for
+         * details.  These events will always occur immediately after the
+         * corresponding {@link #endElement endElement} event, but the order of
+         * {@link #endPrefixMapping endPrefixMapping} events is not otherwise
+         * guaranteed.</p>
+         *
+         * @param prefix the prefix that was being mapped.
+         *      This is the empty string when a default mapping scope ends.
+         * @throws org.xml.sax.SAXException the client may throw
+         *            an exception during processing
+         * @see #startPrefixMapping
+         * @see #endElement
+         */
+        public void endPrefixMapping(String prefix) throws SAXException {
+
+            checkClosed();
+
+            //
+        }
+
+        /**
+         * Receive notification of ignorable whitespace in element content.
+         *
+         * <p>Validating Parsers must use this method to report each chunk
+         * of whitespace in element content (see the W3C XML 1.0
+         * recommendation, section 2.10): non-validating parsers may also
+         * use this method if they are capable of parsing and using
+         * content models.</p>
+         *
+         * <p>SAX parsers may return all contiguous whitespace in a single
+         * chunk, or they may split it into several chunks; however, all of
+         * the characters in any single event must come from the same
+         * external entity, so that the Locator provides useful
+         * information.</p>
+         *
+         * <p>The application must not attempt to read from the array
+         * outside of the specified range.</p>
+         *
+         * @param ch the characters from the XML document
+         * @param start the start position in the array
+         * @param length the number of characters to read from the array
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         * @see #characters
+         */
+        public void ignorableWhitespace(char[] ch, int start,
+                                        int length) throws SAXException {
+            characters(ch, start, length);
+        }
+
+        /**
+         * Receive notification of a processing instruction.
+         *
+         * <p>The Parser will invoke this method once for each processing
+         * instruction found: note that processing instructions may occur
+         * before or after the main document element.</p>
+         *
+         * <p>A SAX parser must never report an XML declaration (XML 1.0,
+         * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+         * using this method.</p>
+         *
+         * <p>Like {@link #characters characters()}, processing instruction
+         * data may have characters that need more than one <code>char</code>
+         * value. </p>
+         *
+         * @param target the processing instruction target
+         * @param data the processing instruction data, or null if
+         *        none was supplied.  The data does not include any
+         *        whitespace separating it from the target
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         */
+        public void processingInstruction(String target,
+                String data) throws SAXException {
+
+            checkClosed();
+
+            try {
+                this.writer.writeProcessingInstruction(target, data);
+            } catch (XMLStreamException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        /**
+         * Receive an object for locating the origin of SAX document events.
+         *
+         * <p>SAX parsers are strongly encouraged (though not absolutely
+         * required) to supply a locator: if it does so, it must supply
+         * the locator to the application by invoking this method before
+         * invoking any of the other methods in the ContentHandler
+         * interface.</p>
+         *
+         * <p>The locator allows the application to determine the end
+         * position of any document-related event, even if the parser is
+         * not reporting an error.  Typically, the application will
+         * use this information for reporting its own errors (such as
+         * character content that does not match an application's
+         * business rules).  The information returned by the locator
+         * is probably not sufficient for use with a search engine.</p>
+         *
+         * <p>Note that the locator will return correct information only
+         * during the invocation SAX event callbacks after
+         * {@link #startDocument startDocument} returns and before
+         * {@link #endDocument endDocument} is called.  The
+         * application should not attempt to use it at any other time.</p>
+         *
+         * @param locator an object that can return the location of
+         *                any SAX document event
+         * @see org.xml.sax.Locator
+         */
+        public void setDocumentLocator(Locator locator) {
+            this.locator = locator;
+        }
+
+        /**
+         * Retrieves the Locator. <p>
+         * @return the Locator
+         */
+        public Locator getDocumentLocator() {
+            return this.locator;
+        }
+
+        /**
+         * Receive notification of a skipped entity.
+         * This is not called for entity references within markup constructs
+         * such as element start tags or markup declarations.  (The XML
+         * recommendation requires reporting skipped external entities.
+         * SAX also reports internal entity expansion/non-expansion, except
+         * within markup constructs.)
+         *
+         * <p>The Parser will invoke this method each time the entity is
+         * skipped.  Non-validating processors may skip entities if they
+         * have not seen the declarations (because, for example, the
+         * entity was declared in an external DTD subset).  All processors
+         * may skip external entities, depending on the values of the
+         * <code>http://xml.org/sax/features/external-general-entities</code>
+         * and the
+         * <code>http://xml.org/sax/features/external-parameter-entities</code>
+         * properties.</p>
+         *
+         * @param name the name of the skipped entity.  If it is a
+         *        parameter entity, the name will begin with '%', and if
+         *        it is the external DTD subset, it will be the string
+         *        "[dtd]"
+         * @throws org.xml.sax.SAXException any SAX exception, possibly
+         *            wrapping another exception
+         */
+        public void skippedEntity(String name) throws SAXException {
+
+            checkClosed();
+
+            //
+        }
+
+        public void comment(char[] ch, int start,
+                            int length) throws SAXException {
+
+            checkClosed();
+
+            try {
+                this.writer.writeComment(new String(ch, start, length));
+            } catch (XMLStreamException e) {
+                throw new SAXException(e);
+            }
+        }
+
+        public XMLStreamWriter getWriter() {
+            return this.writer;
+        }
+
+        protected List<QualifiedName> getNamespaces() {
+            return this.namespaces;
+        }
+
+        /**
+         * Closes this object.
+         */
+        public void close() throws IOException {
+
+            if (!this.closed) {
+                this.closed = true;
+
+                try {
+                    this.writer.close();
+                } catch (XMLStreamException e) {
+                    throw new IOException(e);
+                } finally {
+                    this.writer     = null;
+                    this.locator    = null;
+                    this.namespaces = null;
+                }
+            }
+        }
+
+        /**
+         * Retrieves whether this object is closed.
+         */
+        public boolean isClosed() {
+            return this.closed;
+        }
+
+        /**
+         * Checks whether this object is closed.
+         *
+         * @throws SAXException if this DOMBuilder is closed.
+         */
+        protected void checkClosed() throws SAXException {
+
+            if (isClosed()) {
+                throw new SAXException("content handler is closed.");    // NOI18N
+            }
+        }
+
+        // --------------------- internal implementation -----------------------
+        protected class QualifiedName {
+
+            public final String namespaceName;
+            public final String prefix;
+
+            public QualifiedName(final String prefix,
+                                 final String namespaceName) {
+                this.prefix        = prefix;
+                this.namespaceName = namespaceName;
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCSavepoint.java b/src/org/hsqldb/jdbc/JDBCSavepoint.java
new file mode 100644
index 0000000..f00b6e5
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCSavepoint.java
@@ -0,0 +1,134 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.SQLException;
+import java.sql.Savepoint;
+
+/* $Id: JDBCSavepoint.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+// Revision 1.10  2006/07/12 12:38:22  boucherb
+// - full synch up to Mustang b90
+
+/**
+ * The representation of a savepoint, which is a point within
+ * the current transaction that can be referenced from the
+ * <code>Connection.rollback</code> method. When a transaction
+ * is rolled back to a savepoint all changes made after that
+ * savepoint are undone.
+ * <p>
+ * Savepoints can be either named or unnamed. Unnamed savepoints
+ * are identified by an ID generated by the underlying data source.
+ *
+ * <!-- start Release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3> <p>
+ *
+ * SQL 2003 standard does not support unnamed savepoints. However, this
+ * feature is supported from version 2.0.<p>
+ *
+ * If the connection is autoCommit, setting savepoints has no effect as any
+ * such savepoint is cleared upon the execution of the first transactional
+ * statement. <p>
+ *
+ * </div>
+ * <!-- end release-specific documentation -->
+ *
+ *
+ * @author boucherb@users
+ * @since JDK 1.4, HSQLDB 1.7.2
+ */
+public class JDBCSavepoint implements Savepoint {
+
+    int            id;
+    String         name;
+    JDBCConnection connection;
+
+    JDBCSavepoint(String name, JDBCConnection conn) throws SQLException {
+
+        if (name == null) {
+            throw Util.nullArgument("name");
+        }
+
+        if (conn == null) {
+            throw Util.nullArgument("conn");
+        }
+        this.name       = name;
+        this.connection = conn;
+    }
+
+    JDBCSavepoint(JDBCConnection conn) throws SQLException {
+
+        if (conn == null) {
+            throw Util.nullArgument("conn");
+        }
+        this.id         = conn.getSavepointID();
+        this.connection = conn;
+    }
+
+    /**
+     * Retrieves the generated ID for the savepoint that this
+     * <code>Savepoint</code> object represents.
+     * @return the numeric ID of this savepoint
+     * @exception SQLException if this is a named savepoint
+     * @since 1.4
+     */
+    public int getSavepointId() throws SQLException {
+
+        if (name == null) {
+            return id;
+        }
+
+        throw Util.notSupported();
+    }
+
+    /**
+     * Retrieves the name of the savepoint that this <code>Savepoint</code>
+     * object represents.
+     *
+     * @return the name of this savepoint
+     * @exception SQLException if this is an un-named savepoint
+     * @since 1.4
+     */
+    public String getSavepointName() throws SQLException {
+
+        if (name == null) {
+            throw Util.notSupported();
+        }
+
+        return name;
+    }
+
+    public String toString() {
+        return super.toString() + "[name=" + name + "]";
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCStatement.java b/src/org/hsqldb/jdbc/JDBCStatement.java
new file mode 100644
index 0000000..77cde10
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCStatement.java
@@ -0,0 +1,1808 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.BatchUpdateException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.StatementTypes;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultProperties;
+
+/* $Id: JDBCStatement.java 3529 2010-03-16 14:23:19Z fredt $ */
+
+// fredt@users   20020320 - patch 1.7.0 - JDBC 2 support and error trapping
+//
+// JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
+// SCROLL_INSENSITIVE and FORWARD_ONLY types for ResultSet are now supported
+//
+// boucherb@users 20020509 - added "throws SQLException" to all methods where
+//                           it was missing here but specified in the
+//                           java.sql.Statement interface,
+//                           updated generic documentation to JDK 1.4, and
+//                           added JDBC3 methods and docs
+// boucherb &     20020505 - extensive review and update of docs and behaviour
+// fredt@users               to comply with java.sql specification
+// fredt@users    20030620 - patch 1.7.2 - rewritten and simplified
+// boucherb@users 200404xx - javadoc updates toward 1.7.2 final
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+// boucherb@users 20060522 - doc   1.9.0 full synch up to Mustang Build 84
+// Revision 1.16  2006/07/12 12:40:59  boucherb
+// patch 1.9.0
+// - full synch up to Mustang b90
+
+/**
+ * <!-- start generic documentation -->
+ * <P>The object used for executing a static SQL statement
+ * and returning the results it produces.
+ * <P>
+ * By default, only one <code>ResultSet</code> object per <code>Statement</code>
+ * object can be open at the same time. Therefore, if the reading of one
+ * <code>ResultSet</code> object is interleaved
+ * with the reading of another, each must have been generated by
+ * different <code>Statement</code> objects. All execution methods in the
+ * <code>Statement</code> interface implicitly close a statment's current
+ * <code>ResultSet</code> object if an open one exists.
+ * <!-- end generic documentation-->
+ *
+ * <!-- start release-specific documentation -->
+ * <div class="ReleaseSpecificDocumentation">
+ * <h3>HSQLDB-Specific Information:</h3><p>
+ * From version 2.0, the implementation meets the JDBC specification
+ * requirment that any existing ResultSet is closed when execute() or
+ * executeQuery() methods are called.
+ * <p>
+ *
+ * <b>JRE 1.1.x Notes:</b> <p>
+ *
+ * In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
+ * Java 1.4 and above. In HSQLDB, support for methods introduced in different
+ * versions of JDBC depends on the JDK version used for compiling and building
+ * HSQLDB.<p>
+ *
+ * Since 1.7.0, all JDBC 2 methods can be called while executing under the
+ * version 1.1.x
+ * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
+ * However, in addition to this technique requiring explicit casts to the
+ * org.hsqldb.jdbc.* classes, some of these method calls require
+ * <code>int</code> values that are defined only in the JDBC 2 or greater
+ * version of the {@link java.sql.ResultSet ResultSet} interface.  For this
+ * reason these values are defined in {@link JDBCResultSet JDBCResultSet}.<p>
+ *
+ * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
+ * JDBC2-only <code>ResultSet</code> values can be achieved by referring
+ * to them in parameter specifications and return value comparisons,
+ * respectively, as follows: <p>
+ *
+ * <pre class="JavaCodeExample">
+ * JDBCResultSet.FETCH_FORWARD
+ * JDBCResultSet.TYPE_FORWARD_ONLY
+ * JDBCResultSet.TYPE_SCROLL_INSENSITIVE
+ * JDBCResultSet.CONCUR_READ_ONLY
+ * //etc.
+ * </pre> <p>
+ *
+ * However, please note that code written to use HSQLDB JDBC 2 features under
+ * JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
+ * also note that this feature is offered solely as a convenience to developers
+ * who must work under JDK 1.1.x due to operating constraints, yet wish to
+ * use some of the more advanced features available under the JDBC 2
+ * specification. <p>
+ *
+ * (fredt@users)<br>
+ * (boucherb@users)<p>
+ *
+ * </div>
+ * <!-- end release-specific documentation -->
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0
+ * @revised JDK 1.6, HSQLDB 2.0
+ * @see JDBCConnection#createStatement
+ * @see JDBCResultSet
+ */
+//#ifdef JAVA6
+public class JDBCStatement extends JDBCStatementBase implements Statement,
+        java.sql.Wrapper {
+
+//#else
+/*
+public class JDBCStatement extends JDBCStatementBase implements Statement {
+*/
+
+//#endif JAVA6
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement, which returns a single
+     * <code>ResultSet</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * This method should not be used for statements other than SELECT queries.<p>
+     *
+     * From 2.0, HSQLDB throws an exception when the statement
+     * is a DDL statement or an UPDATE or DELETE statement.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL statement to be sent to the database, typically a
+     *        static SQL <code>SELECT</code> statement
+     * @return a <code>ResultSet</code> object that contains the data produced
+     *         by the given query; never <code>null</code>
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the given
+     *            SQL statement produces anything other than a single
+     *            <code>ResultSet</code> object
+     */
+    public synchronized ResultSet executeQuery(
+            String sql) throws SQLException {
+
+        fetchResult(sql, StatementTypes.RETURN_RESULT,
+                    JDBCStatementBase.NO_GENERATED_KEYS, null, null);
+
+        return getResultSet();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement, which may be an <code>INSERT</code>,
+     * <code>UPDATE</code>, or <code>DELETE</code> statement or an
+     * SQL statement that returns nothing, such as an SQL DDL statement.
+     * <!-- end generic documentation -->
+     *
+     * @param sql (JDBC4 clarification:) an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code>; or an SQL statement that returns nothing,
+     * such as a DDL statement.
+     *
+     * @return (JDBC4 clarification:) either (1) the row count for SQL Data Manipulation Language (DML) statements
+     *         or (2) 0 for SQL statements that return nothing
+     *
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the given
+     *            SQL statement produces a <code>ResultSet</code> object
+     */
+    public synchronized int executeUpdate(String sql) throws SQLException {
+
+        fetchResult(sql, StatementTypes.RETURN_COUNT,
+                    JDBCStatementBase.NO_GENERATED_KEYS, null, null);
+
+        return resultIn.getUpdateCount();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Releases this <code>Statement</code> object's database
+     * and JDBC resources immediately instead of waiting for
+     * this to happen when it is automatically closed.
+     * It is generally good practice to release resources as soon as
+     * you are finished with them to avoid tying up database
+     * resources.
+     * <P>
+     * Calling the method <code>close</code> on a <code>Statement</code>
+     * object that is already closed has no effect.
+     * <P>
+     * <B>Note:</B>When a <code>Statement</code> object is
+     * closed, its current <code>ResultSet</code> object, if one exists, is
+     * also closed.
+     * (JDBC4 deleted:) [A <code>Statement</code> object is
+     * automatically closed when it is garbage collected.]
+     * <!-- end generic documentation -->
+     *
+     * @exception SQLException if a database access error occurs
+     */
+    public synchronized void close() throws SQLException {
+
+        if (isClosed) {
+            return;
+        }
+        closeResultData();
+
+        batchResultOut = null;
+        connection     = null;
+        resultIn       = null;
+        resultOut      = null;
+        isClosed       = true;
+    }
+
+    //----------------------------------------------------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the maximum number of bytes that can be
+     * returned for character and binary column values in a <code>ResultSet</code>
+     * object produced by this <code>Statement</code> object.
+     * This limit applies only to  <code>BINARY</code>, <code>VARBINARY</code>,
+     * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
+     * (JDBC4 new:) <code>NCHAR</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>
+     * and <code>LONGVARCHAR</code> columns.  If the limit is exceeded, the
+     * excess data is silently discarded.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 1.7.2, HSQLDB always returns zero, meaning there
+     * is no limit.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the current column size limit for columns storing character and
+     *         binary values; zero means there is no limit
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #setMaxFieldSize
+     */
+    public synchronized int getMaxFieldSize() throws SQLException {
+
+        checkClosed();
+
+        return 0;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:) Sets the limit for the maximum number of bytes in a <code>ResultSet</code>
+     * Sets the limit for the maximum number of bytes that can be returned for
+     * character and binary column values in a <code>ResultSet</code>
+     * object produced by this <code>Statement</code> object.
+     *
+     * This limit applies
+     * only to <code>BINARY</code>, <code>VARBINARY</code>,
+     * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
+     * (JDBC4 new:) <code>NCHAR</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code> and
+     * <code>LONGVARCHAR</code> fields.  If the limit is exceeded, the excess data
+     * is silently discarded. For maximum portability, use values
+     * greater than 256.
+     * <!-- emd generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * To present, calls to this method are simply ignored; HSQLDB always
+     * stores the full number of bytes when dealing with any of the field types
+     * mentioned above. These types all have an absolute maximum element upper
+     * bound determined by the Java array index limit
+     * java.lang.Integer.MAX_VALUE.  For XXXBINARY types, this translates to
+     * Integer.MAX_VALUE bytes.  For XXXCHAR types, this translates to
+     * 2 * Integer.MAX_VALUE bytes (2 bytes / character). <p>
+     *
+     * In practice, field sizes are limited to values much smaller than the
+     * absolute maximum element upper bound, in particular due to limits imposed
+     * on the maximum available Java heap memory.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param max the new column size limit in bytes; zero means there is no limit
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>
+     *            or the condition max >= 0 is not satisfied
+     * @see #getMaxFieldSize
+     */
+    public void setMaxFieldSize(int max) throws SQLException {
+
+        checkClosed();
+
+        if (max < 0) {
+            throw Util.outOfRangeArgument();
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the maximum number of rows that a
+     * <code>ResultSet</code> object produced by this
+     * <code>Statement</code> object can contain.  If this limit is exceeded,
+     * the excess rows are silently dropped.
+     * <!-- start generic documentation -->
+     *
+     * @return the current maximum number of rows for a <code>ResultSet</code>
+     *         object produced by this <code>Statement</code> object;
+     *         zero means there is no limit
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #setMaxRows
+     */
+    public synchronized int getMaxRows() throws SQLException {
+
+        checkClosed();
+
+        return maxRows;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Sets the limit for the maximum number of rows that any
+     * <code>ResultSet</code> object  generated by this <code>Statement</code>
+     * object can contain to the given number.
+     * If the limit is exceeded, the excess
+     * rows are silently dropped.
+     * <!-- end generic documentation -->
+     *
+     * @param max the new max rows limit; zero means there is no limit
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>
+     *            or the condition max >= 0 is not satisfied
+     * @see #getMaxRows
+     */
+    public synchronized void setMaxRows(int max) throws SQLException {
+
+        checkClosed();
+
+        if (max < 0) {
+            throw Util.outOfRangeArgument();
+        }
+        maxRows = max;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets escape processing on or off.
+     * If escape scanning is on (the default), the driver will do
+     * escape substitution before sending the SQL statement to the database.
+     *
+     * Note: Since prepared statements have usually been parsed prior
+     * to making this call, disabling escape processing for
+     * <code>PreparedStatements</code> objects will have no effect.
+     * <!-- end generic documentation -->
+     *
+     * @param enable <code>true</code> to enable escape processing;
+     *       <code>false</code> to disable it
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     */
+    public void setEscapeProcessing(boolean enable) throws SQLException {
+
+        checkClosed();
+
+        isEscapeProcessing = enable;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the number of seconds the driver will
+     * wait for a <code>Statement</code> object to execute.
+     * If the limit is exceeded, a
+     * <code>SQLException</code> is thrown.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * To present, HSQLDB always returns zero, meaning there
+     * is no limit.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the current query timeout limit in seconds; zero means there is
+     *         no limit
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #setQueryTimeout
+     */
+    public synchronized int getQueryTimeout() throws SQLException {
+
+        checkClosed();
+
+        return 0;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the number of seconds the driver will wait for a
+     * <code>Statement</code> object to execute to the given number of seconds.
+     * If the limit is exceeded, an <code>SQLException</code> is thrown. A JDBC
+     * (JDBC4 clarification:)
+     * driver must apply this limit to the <code>execute</code>,
+     * <code>executeQuery</code> and <code>executeUpdate</code> methods. JDBC driver
+     * implementations may also apply this limit to <code>ResultSet</code> methods
+     * (consult your driver vendor documentation for details).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * The maximum value is Short.MAX_VALUE. The minimum is 0, indicating no limit.
+     * In version 2.0, calls to this method are ignored; HSQLDB waits an
+     * unlimited amount of time for statement execution
+     * requests to return.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param seconds the new query timeout limit in seconds; zero means
+     *        there is no limit
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>
+     *            or the condition seconds >= 0 is not satisfied
+     * @see #getQueryTimeout
+     */
+    public void setQueryTimeout(int seconds) throws SQLException {
+
+        checkClosed();
+
+        if (seconds < 0 || seconds > Short.MAX_VALUE) {
+            throw Util.outOfRangeArgument();
+        }
+        queryTimeout = seconds;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Cancels this <code>Statement</code> object if both the DBMS and
+     * driver support aborting an SQL statement.
+     * This method can be used by one thread to cancel a statement that
+     * is being executed by another thread.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, HSQLDB does <i>not</i> support aborting an SQL
+     * statement; calls to this method are ignored.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     */
+    public synchronized void cancel() throws SQLException {
+        checkClosed();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the first warning reported by calls on this <code>Statement</code> object.
+     * Subsequent <code>Statement</code> object warnings will be chained to this
+     * <code>SQLWarning</code> object.
+     *
+     * <p>The warning chain is automatically cleared each time
+     * a statement is (re)executed. This method may not be called on a closed
+     * <code>Statement</code> object; doing so will cause an <code>SQLException</code>
+     * to be thrown.
+     *
+     * <P><B>Note:</B> If you are processing a <code>ResultSet</code> object, any
+     * warnings associated with reads on that <code>ResultSet</code> object
+     * will be chained on it rather than on the <code>Statement</code>
+     * object that produced it.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * In 2.0, HSQLDB may produces Statement warnings;
+     * this method always returns null.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the first <code>SQLWarning</code> object or <code>null</code>
+     *         if there are no warnings
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     */
+    public synchronized SQLWarning getWarnings() throws SQLException {
+
+        checkClosed();
+
+        return rootWarning;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Clears all the warnings reported on this <code>Statement</code>
+     * object. After a call to this method,
+     * the method <code>getWarnings</code> will return
+     * <code>null</code> until a new warning is reported for this
+     * <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * In HSQLDB 2.0, <code>SQLWarning</code> objects may
+     * be produced for Statement Objects; calls to this method clear the warnings.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     */
+    public synchronized void clearWarnings() throws SQLException {
+
+        checkClosed();
+
+        rootWarning = null;
+    }
+
+    /** @todo 1.9.0 - implement */
+
+    /**
+     * <!-- start generic documentation -->
+     * Sets the SQL cursor name to the given <code>String</code>, which
+     * will be used by subsequent <code>Statement</code> object
+     * <code>execute</code> methods. This name can then be
+     * used in SQL positioned update or delete statements to identify the
+     * current row in the <code>ResultSet</code> object generated by this
+     * statement.  If the database does not support positioned update/delete,
+     * this method is a noop.  To insure that a cursor has the proper isolation
+     * level to support updates, the cursor's <code>SELECT</code> statement
+     * should have the form <code>SELECT FOR UPDATE</code>.  If
+     * <code>FOR UPDATE</code> is not present, positioned updates may fail.
+     *
+     * <P><B>Note:</B> By definition, the execution of positioned updates and
+     * deletes must be done by a different <code>Statement</code> object than
+     * the one that generated the <code>ResultSet</code> object being used for
+     * positioning. Also, cursor names must be unique within a connection.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Including 2.0, HSQLDB does not support named cursors;
+     * calls to this method are ignored.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param name the new cursor name, which must be unique within
+     *             a connection
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     */
+    public void setCursorName(String name) throws SQLException {
+        checkClosed();
+    }
+
+    //----------------------- Multiple Results --------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement, which may return multiple results.
+     * In some (uncommon) situations, a single SQL statement may return
+     * multiple result sets and/or update counts.  Normally you can ignore
+     * this unless you are (1) executing a stored procedure that you know may
+     * return multiple results or (2) you are dynamically executing an
+     * unknown SQL string.
+     * <P>
+     * The <code>execute</code> method executes an SQL statement and indicates the
+     * form of the first result.  You must then use the methods
+     * <code>getResultSet</code> or <code>getUpdateCount</code>
+     * to retrieve the result, and <code>getMoreResults</code> to
+     * move to any subsequent result(s).
+     * <!-- end generic documentation -->
+     *
+     * @param sql any SQL statement
+     * @return <code>true</code> if the first result is a <code>ResultSet</code>
+     *         object; <code>false</code> if it is an update count or there are
+     *         no results
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #getResultSet
+     * @see #getUpdateCount
+     * @see #getMoreResults
+     */
+    public synchronized boolean execute(String sql) throws SQLException {
+
+        fetchResult(sql, StatementTypes.RETURN_ANY,
+                    JDBCStatementBase.NO_GENERATED_KEYS, null, null);
+
+        return resultIn.isData();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *  Retrieves the current result as a <code>ResultSet</code> object.
+     *  This method should be called only once per result.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the current result as a <code>ResultSet</code> object or
+     * <code>null</code> if the result is an update count or there are no more results
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #execute
+     */
+    public synchronized ResultSet getResultSet() throws SQLException {
+        return super.getResultSet();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     *  Retrieves the current result as an update count;
+     *  if the result is a <code>ResultSet</code> object or there are no more results, -1
+     *  is returned. This method should be called only once per result.
+     * <!-- end generic documentation -->
+     *
+     * @return the current result as an update count; -1 if the current result is a
+     * <code>ResultSet</code> object or there are no more results
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #execute
+     */
+    public synchronized int getUpdateCount() throws SQLException {
+        return super.getUpdateCount();
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves to this <code>Statement</code> object's next result, returns
+     * <code>true</code> if it is a <code>ResultSet</code> object, and
+     * implicitly closes any current <code>ResultSet</code>
+     * object(s) obtained with the method <code>getResultSet</code>.
+     *
+     * <P>There are no more results when the following is true:
+     * <PRE>
+     *     // stmt is a Statement object
+     *     ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
+     * </PRE>
+     * <!-- end generic documentation -->
+     *
+     * @return <code>true</code> if the next result is a <code>ResultSet</code>
+     *         object; <code>false</code> if it is an update count or there are
+     *         no more results
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @see #execute
+     */
+    public synchronized boolean getMoreResults() throws SQLException {
+        return getMoreResults(JDBCStatementBase.CLOSE_CURRENT_RESULT);
+    }
+
+    //--------------------------JDBC 2.0-----------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Gives the driver a hint as to the direction in which
+     * rows will be processed in <code>ResultSet</code>
+     * objects created using this <code>Statement</code> object.  The
+     * default value is <code>ResultSet.FETCH_FORWARD</code>.
+     * <P>
+     * Note that this method sets the default fetch direction for
+     * result sets generated by this <code>Statement</code> object.
+     * Each result set has its own methods for getting and setting
+     * its own fetch direction.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB accepts all valid parameters. <p>
+     * <!-- end release-specific documentation -->
+     *
+     * @param direction the initial direction for processing rows
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>
+     * or the given direction
+     * is not one of <code>ResultSet.FETCH_FORWARD</code>,
+     * <code>ResultSet.FETCH_REVERSE</code>, or <code>ResultSet.FETCH_UNKNOWN</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *    for JDBCStatement)
+     * @see #getFetchDirection
+     */
+    public synchronized void setFetchDirection(
+            int direction) throws SQLException {
+
+        checkClosed();
+        checkClosed();
+
+        switch (direction) {
+
+            case JDBCResultSet.FETCH_FORWARD :
+            case JDBCResultSet.FETCH_REVERSE :
+            case JDBCResultSet.FETCH_UNKNOWN :
+                fetchDirection = direction;
+
+                break;
+            default :
+                throw Util.invalidArgument();
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the direction for fetching rows from
+     * database tables that is the default for result sets
+     * generated from this <code>Statement</code> object.
+     * If this <code>Statement</code> object has not set
+     * a fetch direction by calling the method <code>setFetchDirection</code>,
+     * the return value is implementation-specific.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB returns the fetch direction. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the default fetch direction for result sets generated
+     *          from this <code>Statement</code> object
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *    for JDBCStatement)
+     * @see #setFetchDirection
+     */
+    public int getFetchDirection() throws SQLException {
+
+        checkClosed();
+
+        return this.fetchDirection;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * (JDBC4 clarification:)
+     * Gives the JDBC driver a hint as to the number of rows that should
+     * be fetched from the database when more rows are needed for
+     * <code>ResultSet</code> objects genrated by this <code>Statement</code>.
+     * If the value specified is zero, then the hint is ignored.
+     * The default value is zero.
+     * <!-- start generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB uses the specified value as a hint, but may process more or fewer
+     * rows than specified.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param rows the number of rows to fetch
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the
+     *        (JDBC4 modified:)
+     *        condition  <code>rows >= 0</code> is not satisfied.
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *   for JDBCStatement)
+     * @see #getFetchSize
+     */
+    public synchronized void setFetchSize(int rows) throws SQLException {
+
+        checkClosed();
+
+        if (rows < 0) {
+            throw Util.outOfRangeArgument();
+        }
+        fetchSize = rows;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the number of result set rows that is the default
+     * fetch size for <code>ResultSet</code> objects
+     * generated from this <code>Statement</code> object.
+     * If this <code>Statement</code> object has not set
+     * a fetch size by calling the method <code>setFetchSize</code>,
+     * the return value is implementation-specific.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <b>HSQLDB-Specific Information</b> <p>
+     *
+     * HSQLDB returns 0 by default, or the fetch size specified by setFetchSize
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return the default fetch size for result sets generated
+     *          from this <code>Statement</code> object
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *  for JDBCStatement)
+     * @see #setFetchSize
+     */
+    public synchronized int getFetchSize() throws SQLException {
+
+        checkClosed();
+
+        return fetchSize;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the result set concurrency for <code>ResultSet</code> objects
+     * generated by this <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB supports <code>CONCUR_READ_ONLY</code> and
+     * <code>CONCUR_UPDATABLE</code> concurrency.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return either <code>ResultSet.CONCUR_READ_ONLY</code> or
+     * <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *  for JDBCStatement)
+     */
+    public synchronized int getResultSetConcurrency() throws SQLException {
+
+        checkClosed();
+
+        return ResultProperties.getJDBCConcurrency(rsProperties);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the result set type for <code>ResultSet</code> objects
+     * generated by this <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB 1.7.0 and later versions support <code>TYPE_FORWARD_ONLY</code>
+     * and <code>TYPE_SCROLL_INSENSITIVE</code>.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
+     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *   for JDBCStatement)
+     */
+    public synchronized int getResultSetType() throws SQLException {
+
+        checkClosed();
+
+        return ResultProperties.getJDBCScrollability(rsProperties);
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Adds the given SQL command to the current list of commmands for this
+     * <code>Statement</code> object. The commands in this list can be
+     * executed as a batch by calling the method <code>executeBatch</code>.
+     * <P>
+     * (JDBC4 clarification:)<p>
+     * <B>NOTE:</B>  Support of an ability to batch updates is optional.
+     *
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.7.2, this feature is supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param sql typically this is a SQL <code>INSERT</code> or
+     * <code>UPDATE</code> statement
+     * (:JDBC4 modified)
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the
+     * driver does not support batch updates
+     * @see #executeBatch
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *   for JDBCStatement)
+     */
+    public synchronized void addBatch(String sql) throws SQLException {
+
+        checkClosed();
+
+        if (isEscapeProcessing) {
+            sql = connection.nativeSQL(sql);
+        }
+
+        if (batchResultOut == null) {
+            batchResultOut = Result.newBatchedExecuteRequest();
+        }
+        batchResultOut.getNavigator().add(new Object[] { sql });
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Empties this <code>Statement</code> object's current list of
+     * SQL commands.
+     * <P>
+     * (JDBC4 clarification:) <p>
+     * <B>NOTE:</B>  Support of an ability to batch updates is optional.
+     * <!-- start generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 1.7.2, this feature is supported.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @exception SQLException if a database access error occurs,
+     *  this method is called on a closed <code>Statement</code> or the
+     * driver does not support batch updates
+     * @see #addBatch
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *   for JDBCStatement)
+     */
+    public synchronized void clearBatch() throws SQLException {
+
+        checkClosed();
+
+        if (batchResultOut != null) {
+            batchResultOut.getNavigator().clear();
+        }
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Submits a batch of commands to the database for execution and
+     * if all commands execute successfully, returns an array of update counts.
+     * The <code>int</code> elements of the array that is returned are ordered
+     * to correspond to the commands in the batch, which are ordered
+     * according to the order in which they were added to the batch.
+     * The elements in the array returned by the method <code>executeBatch</code>
+     * may be one of the following:
+     * <OL>
+     * <LI>A number greater than or equal to zero -- indicates that the
+     * command was processed successfully and is an update count giving the
+     * number of rows in the database that were affected by the command's
+     * execution
+     * <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was
+     * processed successfully but that the number of rows affected is
+     * unknown
+     * <P>
+     * If one of the commands in a batch update fails to execute properly,
+     * this method throws a <code>BatchUpdateException</code>, and a JDBC
+     * driver may or may not continue to process the remaining commands in
+     * the batch.  However, the driver's behavior must be consistent with a
+     * particular DBMS, either always continuing to process commands or never
+     * continuing to process commands.  If the driver continues processing
+     * after a failure, the array returned by the method
+     * <code>BatchUpdateException.getUpdateCounts</code>
+     * will contain as many elements as there are commands in the batch, and
+     * at least one of the elements will be the following:
+     * <P>
+     * <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command failed
+     * to execute successfully and occurs only if a driver continues to
+     * process commands after a command fails
+     * </OL>
+     * <P>
+     * (JDBC4 clarification:) <p>
+     * <B>NOTE:</B>  Support of an ability to batch updates is optional.
+     * <p>
+     * The possible implementations and return values have been modified in
+     * the Java 2 SDK, Standard Edition, version 1.3 to
+     * accommodate the option of continuing to proccess commands in a batch
+     * update after a <code>BatchUpdateException</code> obejct has been thrown.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with HSQLDB 1.7.2, this feature is supported. <p>
+     *
+     * HSQLDB stops execution of commands in a batch when one of the commands
+     * results in an exception. The size of the returned array equals the
+     * number of commands that were executed successfully.<p>
+     *
+     * When the product is built under the JAVA1 target, an exception
+     * is never thrown and it is the responsibility of the client software to
+     * check the size of the  returned update count array to determine if any
+     * batch items failed.  To build and run under the JAVA2 target, JDK/JRE
+     * 1.3 or higher must be used.
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return an array of update counts containing one element for each
+     * command in the batch.  The elements of the array are ordered according
+     * to the order in which commands were added to the batch.
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the
+     * driver does not support batch statements. Throws {@link BatchUpdateException}
+     * (a subclass of <code>SQLException</code>) if one of the commands sent to the
+     * database fails to execute properly or attempts to return a result set.
+     *
+     *
+     * @see #addBatch
+     * @see java.sql.DatabaseMetaData#supportsBatchUpdates
+     * @since JDK 1.3 (JDK 1.1.x developers: read the overview for
+     * JDBCStatement)
+     */
+    public synchronized int[] executeBatch() throws SQLException {
+
+        checkClosed();
+
+        generatedResult = null;
+
+        if (batchResultOut == null) {
+            batchResultOut = Result.newBatchedExecuteRequest();
+        }
+
+        int batchCount = batchResultOut.getNavigator().getSize();
+
+        try {
+            resultIn = connection.sessionProxy.execute(batchResultOut);
+
+            performPostExecute();
+        } catch (HsqlException e) {
+            batchResultOut.getNavigator().clear();
+
+            throw Util.sqlException(e);
+        }
+        batchResultOut.getNavigator().clear();
+
+        if (resultIn.isError()) {
+            throw Util.sqlException(resultIn);
+        }
+
+        RowSetNavigator navigator    = resultIn.getNavigator();
+        int[]           updateCounts = new int[navigator.getSize()];
+
+        for (int i = 0; i < updateCounts.length; i++) {
+            Object[] data = (Object[]) navigator.getNext();
+
+            updateCounts[i] = ((Integer) data[0]).intValue();
+        }
+
+        if (updateCounts.length != batchCount) {
+            if (errorResult == null) {
+                throw new BatchUpdateException(updateCounts);
+            } else {
+                errorResult.getMainString();
+
+                throw new BatchUpdateException(errorResult.getMainString(),
+                        errorResult.getSubString(),
+                        errorResult.getErrorCode(), updateCounts);
+            }
+        }
+
+        return updateCounts;
+    }
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the <code>Connection</code> object
+     * that produced this <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * @return the connection that produced this statement
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.2 (JDK 1.1.x developers: read the overview
+     *    for JDBCStatement)
+     */
+    public synchronized Connection getConnection() throws SQLException {
+
+        checkClosed();
+
+        return connection;
+    }
+
+    //--------------------------JDBC 3.0-----------------------------
+
+    /**
+     * <!-- start generic documentation -->
+     * Moves to this <code>Statement</code> object's next result, deals with
+     * any current <code>ResultSet</code> object(s) according  to the instructions
+     * specified by the given flag, and returns
+     * <code>true</code> if the next result is a <code>ResultSet</code> object.
+     *
+     * <P>There are no more results when the following is true:
+     * <PRE>
+     *     // stmt is a Statement object
+     *     ((stmt.getMoreResults(current) == false) && (stmt.getUpdateCount() == -1))
+     * </PRE>
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * HSQLDB moves to the next ResultSet and returns the correct result. <p>
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param current one of the following <code>Statement</code>
+     *        constants indicating what should happen to current
+     *        <code>ResultSet</code> objects obtained using the method
+     *        <code>getResultSet</code>:
+     *        <code>Statement.CLOSE_CURRENT_RESULT</code>,
+     *        <code>Statement.KEEP_CURRENT_RESULT</code>, or
+     *        <code>Statement.CLOSE_ALL_RESULTS</code>
+     * @return <code>true</code> if the next result is a <code>ResultSet</code>
+     *         object; <code>false</code> if it is an update count or there are no
+     *         more results
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the argument
+     *             supplied is not one of the following:
+     *        <code>Statement.CLOSE_CURRENT_RESULT</code>,
+     *        <code>Statement.KEEP_CURRENT_RESULT</code>, or
+     *        <code>Statement.CLOSE_ALL_RESULTS</code>
+     * @since JDK 1.4, HSQLDB 1.7
+     * @see #execute
+     */
+//#ifdef JAVA4
+    public synchronized boolean getMoreResults(
+            int current) throws SQLException {
+        return super.getMoreResults(current);
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves any auto-generated keys created as a result of executing this
+     * <code>Statement</code> object. If this <code>Statement</code> object did
+     * not generate any keys, an empty <code>ResultSet</code>
+     * object is returned.
+     * <p>(JDBC4 clarification:)
+     * <p><B>Note:</B>If the columns which represent the auto-generated keys were not specified,
+     * the JDBC driver implementation will determine the columns which best represent the auto-generated keys.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Supported in version 2.0 <p>
+     *
+     * If column names or indexes provided by the user in the executeUpdate()
+     * method calls are not correct, an empty result is returned.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return a <code>ResultSet</code> object containing the auto-generated key(s)
+     *         generated by the execution of this <code>Statement</code> object
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized ResultSet getGeneratedKeys() throws SQLException {
+        return getGeneratedResultSet();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement and signals the driver with the
+     * given flag about whether the
+     * auto-generated keys produced by this <code>Statement</code> object
+     * should be made available for retrieval.  The driver will ignore the
+     * flag if the SQL statement
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with version 2.0, HSQLDB supports this feature.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     * @param sql an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code>; or an SQL statement that returns nothing,
+     * such as a DDL statement.
+     * (:JDBC4 clarification)
+     *
+     * @param autoGeneratedKeys a flag indicating whether auto-generated keys
+     *        should be made available for retrieval;
+     *         one of the following constants:
+     *         <code>Statement.RETURN_GENERATED_KEYS</code>
+     *         <code>Statement.NO_GENERATED_KEYS</code>
+     * @return either (1) the row count for SQL Data Manipulation Language (DML) statements
+     *         or (2) 0 for SQL statements that return nothing
+     *         (:JDBC4 clarification)
+     *
+     * @exception SQLException if a database access error occurs,
+     *  this method is called on a closed <code>Statement</code>, the given
+     *            SQL statement returns a <code>ResultSet</code> object, or
+     *            the given constant is not one of those allowed
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method with a constant of Statement.RETURN_GENERATED_KEYS
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized int executeUpdate(String sql,
+            int autoGeneratedKeys) throws SQLException {
+
+        if (autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS
+                && autoGeneratedKeys != Statement.NO_GENERATED_KEYS) {
+            throw Util.invalidArgument("autoGeneratedKeys");
+        }
+        fetchResult(sql, StatementTypes.RETURN_COUNT, autoGeneratedKeys, null,
+                    null);
+
+        if (resultIn.isError()) {
+            throw Util.sqlException(resultIn);
+        }
+
+        return resultIn.getUpdateCount();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement and signals the driver that the
+     * auto-generated keys indicated in the given array should be made available
+     * for retrieval.  The driver will ignore the array if the SQL statement
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * (JDBC 4 clarification)
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with version 2.0, HSQLDB supports this feature with single-row and
+     * multi-row inserts. <p>
+     * CHECKME: possibly change method depending to final GENERATED column support.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code>; or an SQL statement that returns nothing,
+     * such as a DDL statement.
+     * (:JDBC4 clarification)
+     *
+     * @param columnIndexes an array of column indexes indicating the columns
+     *        that should be returned from the inserted row
+     * @return either (1) the row count for SQL Data Manipulation Language (DML) statements
+     *         or (2) 0 for SQL statements that return nothing
+     *         (:JDBC 4 clarification)
+     *
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code>, the SQL
+     *            statement returns a <code>ResultSet</code> object, or the
+     *            second argument supplied to this method is not an <code>int</code> array
+     *            whose elements are valid column indexes
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized int executeUpdate(String sql,
+            int[] columnIndexes) throws SQLException {
+
+        if (columnIndexes == null || columnIndexes.length == 0) {
+            throw Util.invalidArgument("columnIndexes");
+        }
+        fetchResult(sql, StatementTypes.RETURN_COUNT,
+                    Statement.RETURN_GENERATED_KEYS, columnIndexes, null);
+
+        return resultIn.getUpdateCount();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement and signals the driver that the
+     * auto-generated keys indicated in the given array should be made available
+     * for retrieval.   The driver will ignore the array if the SQL statement
+     * (JDBC4 clarification:)
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB supports this feature.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param sql an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+     * <code>DELETE</code>; or an SQL statement that returns nothing,
+     * such as a DDL statement.
+     * (:JDBC4 clarification)
+     * @param columnNames an array of the names of the columns that should be
+     *        returned from the inserted row
+     * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>,
+     *         or <code>DELETE</code> statements, or 0 for SQL statements
+     *         that return nothing
+     * @exception SQLException if a database access error occurs,
+     *  this method is called on a closed <code>Statement</code>, the SQL
+     *            statement returns a <code>ResultSet</code> object, or the
+     *            second argument supplied to this method is not a <code>String</code> array
+     *            whose elements are valid column names
+     *
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized int executeUpdate(String sql,
+            String[] columnNames) throws SQLException {
+
+        if (columnNames == null || columnNames.length == 0) {
+            throw Util.invalidArgument("columnIndexes");
+        }
+        fetchResult(sql, StatementTypes.RETURN_COUNT,
+                    Statement.RETURN_GENERATED_KEYS, null, columnNames);
+
+        return resultIn.getUpdateCount();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement, which may return multiple results,
+     * and signals the driver that any
+     * auto-generated keys should be made available
+     * for retrieval.  The driver will ignore this signal if the SQL statement
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * (JDBC4 clarification)
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <P>
+     * In some (uncommon) situations, a single SQL statement may return
+     * multiple result sets and/or update counts.  Normally you can ignore
+     * this unless you are (1) executing a stored procedure that you know may
+     * return multiple results or (2) you are dynamically executing an
+     * unknown SQL string.
+     * <P>
+     * The <code>execute</code> method executes an SQL statement and indicates the
+     * form of the first result.  You must then use the methods
+     * <code>getResultSet</code> or <code>getUpdateCount</code>
+     * to retrieve the result, and <code>getMoreResults</code> to
+     * move to any subsequent result(s).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB supports this feature.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param sql any SQL statement
+     * @param autoGeneratedKeys a constant indicating whether auto-generated
+     *        keys should be made available for retrieval using the method
+     *        <code>getGeneratedKeys</code>; one of the following constants:
+     *        <code>Statement.RETURN_GENERATED_KEYS</code> or
+     *        <code>Statement.NO_GENERATED_KEYS</code>
+     * @return <code>true</code> if the first result is a <code>ResultSet</code>
+     *         object; <code>false</code> if it is an update count or there are
+     *         no results
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the second
+     *         parameter supplied to this method is not
+     *         <code>Statement.RETURN_GENERATED_KEYS</code> or
+     *         <code>Statement.NO_GENERATED_KEYS</code>.
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method with a constant of Statement.RETURN_GENERATED_KEYS
+     * @see #getResultSet
+     * @see #getUpdateCount
+     * @see #getMoreResults
+     * @see #getGeneratedKeys
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized boolean execute(
+            String sql, int autoGeneratedKeys) throws SQLException {
+
+        if (autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS
+                && autoGeneratedKeys != Statement.NO_GENERATED_KEYS) {
+            throw Util.invalidArgument("autoGeneratedKeys");
+        }
+        fetchResult(sql, StatementTypes.RETURN_ANY, autoGeneratedKeys, null,
+                    null);
+
+        return resultIn.isData();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement, which may return multiple results,
+     * and signals the driver that the
+     * auto-generated keys indicated in the given array should be made available
+     * for retrieval.  This array contains the indexes of the columns in the
+     * target table that contain the auto-generated keys that should be made
+     * available.  The driver will ignore the array if the SQL statement
+     * (JDBC4 clarification)
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <P>
+     * Under some (uncommon) situations, a single SQL statement may return
+     * multiple result sets and/or update counts.  Normally you can ignore
+     * this unless you are (1) executing a stored procedure that you know may
+     * return multiple results or (2) you are dynamically executing an
+     * unknown SQL string.
+     * <P>
+     * The <code>execute</code> method executes an SQL statement and indicates the
+     * form of the first result.  You must then use the methods
+     * <code>getResultSet</code> or <code>getUpdateCount</code>
+     * to retrieve the result, and <code>getMoreResults</code> to
+     * move to any subsequent result(s).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB supports this feature.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param sql any SQL statement
+     * @param columnIndexes an array of the indexes of the columns in the
+     *        inserted row that should be  made available for retrieval by a
+     *        call to the method <code>getGeneratedKeys</code>
+     * @return <code>true</code> if the first result is a <code>ResultSet</code>
+     *         object; <code>false</code> if it is an update count or there
+     *         are no results
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the
+     *            elements in the <code>int</code> array passed to this method
+     *            are not valid column indexes
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @see #getResultSet
+     * @see #getUpdateCount
+     * @see #getMoreResults
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized boolean execute(
+            String sql, int[] columnIndexes) throws SQLException {
+
+        if (columnIndexes == null || columnIndexes.length == 0) {
+            throw Util.invalidArgument("columnIndexes");
+        }
+        fetchResult(sql, StatementTypes.RETURN_ANY,
+                    Statement.RETURN_GENERATED_KEYS, columnIndexes, null);
+
+        return resultIn.isData();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Executes the given SQL statement, which may return multiple results,
+     * and signals the driver that the
+     * auto-generated keys indicated in the given array should be made available
+     * for retrieval. This array contains the names of the columns in the
+     * target table that contain the auto-generated keys that should be made
+     * available.  The driver will ignore the array if the SQL statement
+     * is not an <code>INSERT</code> statement, or an SQL statement able to return
+     * auto-generated keys (the list of such statements is vendor-specific).
+     * <P>
+     * In some (uncommon) situations, a single SQL statement may return
+     * multiple result sets and/or update counts.  Normally you can ignore
+     * this unless you are (1) executing a stored procedure that you know may
+     * return multiple results or (2) you are dynamically executing an
+     * unknown SQL string.
+     * <P>
+     * The <code>execute</code> method executes an SQL statement and indicates the
+     * form of the first result.  You must then use the methods
+     * <code>getResultSet</code> or <code>getUpdateCount</code>
+     * to retrieve the result, and <code>getMoreResults</code> to
+     * move to any subsequent result(s).
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 2.0, HSQLDB supports this feature.
+     *
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @param sql any SQL statement
+     * @param columnNames an array of the names of the columns in the inserted
+     *        row that should be made available for retrieval by a call to the
+     *        method <code>getGeneratedKeys</code>
+     * @return <code>true</code> if the next result is a <code>ResultSet</code>
+     *         object; <code>false</code> if it is an update count or there
+     *         are no more results
+     * @exception SQLException if a database access error occurs,
+     * this method is called on a closed <code>Statement</code> or the
+     *          elements of the <code>String</code> array passed to this
+     *          method are not valid column names
+     * @throws SQLFeatureNotSupportedException  if the JDBC driver does not support this method
+     * @see #getResultSet
+     * @see #getUpdateCount
+     * @see #getMoreResults
+     * @see #getGeneratedKeys
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized boolean execute(
+            String sql, String[] columnNames) throws SQLException {
+
+        if (columnNames == null || columnNames.length == 0) {
+            throw Util.invalidArgument("columnIndexes");
+        }
+        fetchResult(sql, StatementTypes.RETURN_ANY,
+                    Statement.RETURN_GENERATED_KEYS, null, columnNames);
+
+        return resultIn.isData();
+    }
+
+//#endif JAVA4
+
+    /**
+     * <!-- start generic documentation -->
+     * Retrieves the result set holdability for <code>ResultSet</code> objects
+     * generated by this <code>Statement</code> object.
+     * <!-- end generic documentation -->
+     *
+     * <!-- start release-specific documentation -->
+     * <div class="ReleaseSpecificDocumentation">
+     * <h3>HSQLDB-Specific Information:</h3> <p>
+     *
+     * Starting with 1.7.2, this method returns HOLD_CURSORS_OVER_COMMIT
+     * </div>
+     * <!-- end release-specific documentation -->
+     *
+     * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+     *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+     * @exception SQLException if a database access error occurs or
+     * this method is called on a closed <code>Statement</code>
+     * @since JDK 1.4, HSQLDB 1.7
+     */
+//#ifdef JAVA4
+    public synchronized int getResultSetHoldability() throws SQLException {
+        return ResultProperties.getJDBCHoldability(rsProperties);
+    }
+
+//#endif JAVA4
+    //----------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * Retrieves whether this <code>Statement</code> object has been closed. A <code>Statement</code> is closed if the
+     * method close has been called on it, or if it is automatically closed.
+     * @return true if this <code>Statement</code> object is closed; false if it is still open
+     * @throws SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+    public synchronized boolean isClosed() throws SQLException {
+        return isClosed;
+    }
+
+// --------------------------- Added: Mustang Build 81 -------------------------
+    boolean poolable = false;
+
+    /**
+     * Requests that a <code>Statement</code> be pooled or not pooled.  The value
+     * specified is a hint to the statement pool implementation indicating
+     * whether the applicaiton wants the statement to be pooled.  It is up to
+     * the statement pool manager as to whether the hint is used.
+     * <p>
+     * The poolable value of a statement is applicable to both internal
+     * statement caches implemented by the driver and external statement caches
+     * implemented by application servers and other applications.
+     * <p>
+     * By default, a <code>Statement</code> is not poolable when created, and
+     * a <code>PreparedStatement</code> and <code>CallableStatement</code>
+     * are poolable when created.
+     * <p>
+     * @param poolable          requests that the statement be pooled if true and
+     *                                          that the statement not be pooled if false
+     * <p>
+     * @throws SQLException if this method is called on a closed
+     * <code>Statement</code>
+     * <p>
+     * @since JDK 1.6 Build 81, HSQLDB 2.0
+     */
+
+//#ifdef JAVA6
+    public synchronized void setPoolable(
+            boolean poolable) throws SQLException {
+
+        checkClosed();
+
+        this.poolable = poolable;
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns a  value indicating whether the <code>Statement</code>
+     * is poolable or not.
+     * <p>
+     * @return          <code>true</code> if the <code>Statement</code>
+     * is poolable; <code>false</code> otherwise
+     * @throws SQLException if this method is called on a closed
+     * <code>Statement</code>
+     * <p>
+     * @since JDK 1.6 Build 81, HSQLDB 2.0
+     * <p>
+     * @see #setPoolable(boolean) setPoolable(boolean)
+     */
+//#ifdef JAVA6
+    public synchronized boolean isPoolable() throws SQLException {
+
+        checkClosed();
+
+        return this.poolable;
+    }
+
+//#endif JAVA6
+    // ------------------- java.sql.Wrapper implementation ---------------------
+
+    /**
+     * Returns an object that implements the given interface to allow access to
+     * non-standard methods, or standard methods not exposed by the proxy.
+     *
+     * If the receiver implements the interface then the result is the receiver
+     * or a proxy for the receiver. If the receiver is a wrapper
+     * and the wrapped object implements the interface then the result is the
+     * wrapped object or a proxy for the wrapped object. Otherwise return the
+     * the result of calling <code>unwrap</code> recursively on the wrapped object
+     * or a proxy for that result. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    @SuppressWarnings("unchecked")
+    public <T>T unwrap(Class<T> iface) throws java.sql.SQLException {
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 2.0
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+    // -------------------- Internal Implementation ----------------------------
+
+    /**
+     * Constructs a new JDBCStatement with the specified connection and result
+     * type.
+     *
+     * @param c the connection on which this statement will execute
+     * @param resultSetConcurrency int
+     * @param resultSetHoldability int
+     */
+    JDBCStatement(JDBCConnection c, int props) {
+
+        resultOut    = Result.newExecuteDirectRequest();
+        connection   = c;
+        connectionIncarnation = connection.incarnation;
+        rsProperties = props;
+    }
+
+    /**
+     * Internal result producer for JDBCStatement (sqlExecDirect mode).
+     *
+     * <p>
+     *
+     * @param sql a character sequence representing the SQL to be executed
+     * @param statementRetType int
+     * @param generatedKeys int
+     * @param generatedIndexes int[]
+     * @param generatedNames String[]
+     * @throws SQLException when a database access error occurs
+     */
+    private void fetchResult(String sql, int statementRetType,
+                             int generatedKeys, int[] generatedIndexes,
+                             String[] generatedNames) throws SQLException {
+
+        checkClosed();
+        closeResultData();
+
+        if (isEscapeProcessing) {
+            sql = connection.nativeSQL(sql);
+        }
+        resultOut.setPrepareOrExecuteProperties(sql, maxRows, fetchSize,
+                statementRetType, queryTimeout, rsProperties, generatedKeys,
+                generatedIndexes, generatedNames);
+
+        try {
+            resultIn = connection.sessionProxy.execute(resultOut);
+
+            performPostExecute();
+        } catch (HsqlException e) {
+            throw Util.sqlException(e);
+        }
+
+        if (resultIn.isError()) {
+            throw Util.sqlException(resultIn);
+        }
+    }
+}
diff --git a/src/org/hsqldb/jdbc/JDBCStatementBase.java b/src/org/hsqldb/jdbc/JDBCStatementBase.java
new file mode 100644
index 0000000..051af92
--- /dev/null
+++ b/src/org/hsqldb/jdbc/JDBCStatementBase.java
@@ -0,0 +1,301 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+
+/**
+ * Base class for HSQLDB's implementations of java.sql.Statement and
+ * java.sql.PreparedStatement. Contains common members and methods.
+ *
+ * @author fredt@usrs
+ * @version 2.0
+ * @since 1.9.0
+ */
+
+/**
+ * JDBC specification.
+ *
+ * Closing the Statement closes the ResultSet instance returned. But:
+ *
+ * Statement can be executed multiple times and return several results. With
+ * normal Statement objects, each execution can be for a completely different
+ * query. PreparedStatement instances are specifically for multiple use over
+ * multiple transactions.
+ *
+ * ResultSets may be held over commits and span several transactions.
+ *
+ * There is no real relation between the current state fo an Statement instance
+ * and the various ResultSets that it may have returned for different queries.
+ */
+
+/**
+ * @todo 1.9.0 - review the following issues:
+ *
+ * Does not always close ResultSet object directly when closed. Although RS
+ * objects will eventually be closed when accessed, the change is not reflected
+ * to the server, impacting ResultSets that are held.
+ */
+class JDBCStatementBase {
+
+    /**
+     * Whether this Statement has been explicitly closed.  A JDBCConnection
+     * object now explicitly closes all of its open JDBC Statement objects
+     * when it is closed.
+     */
+    volatile boolean isClosed;
+
+    /** Is escape processing enabled? */
+    protected boolean isEscapeProcessing = true;
+
+    /** The connection used to execute this statement. */
+    protected JDBCConnection connection;
+
+    /** The maximum number of rows to generate when executing this statement. */
+    protected int maxRows;
+
+    /** The number of rows returned in a chunk. */
+    protected int fetchSize = 0;
+
+    /** Direction of results fetched. */
+    protected int fetchDirection = JDBCResultSet.FETCH_FORWARD;
+
+    /** The result of executing this statement. */
+    protected Result resultIn;
+
+    /** Any error returned from a batch execute. */
+    protected Result errorResult;
+
+    /** The currently existing generated key Result */
+    protected Result generatedResult;
+
+    /** The combined result set properties obtained by executing this statement. */
+    protected int rsProperties;
+
+    /** Used by this statement to communicate non-batched requests. */
+    protected Result resultOut;
+
+    /** Used by this statement to communicate batched execution requests */
+    protected Result batchResultOut;
+
+    /** The currently existing ResultSet object */
+    protected JDBCResultSet currentResultSet;
+
+    /** The currently existing ResultSet object for generated keys */
+    protected JDBCResultSet generatedResultSet;
+
+    /** The first warning in the chain. Null if there are no warnings. */
+    protected SQLWarning rootWarning;
+
+    /** Counter for ResultSet in getMoreResults(). */
+    protected int resultSetCounter;
+
+    /** Query timeout in seconds */
+    protected int queryTimeout;
+
+    /** connection generation */
+    int connectionIncarnation;
+
+    /** Implementation in subclasses */
+    public synchronized void close() throws SQLException {}
+
+    /**
+     * An internal check for closed statements.
+     *
+     * @throws SQLException when the connection is closed
+     */
+    void checkClosed() throws SQLException {
+
+        if (isClosed) {
+            throw Util.sqlException(ErrorCode.X_07501);
+        }
+
+        if (connection.isClosed) {
+            close();
+
+            throw Util.sqlException(ErrorCode.X_08503);
+        }
+
+        if (connectionIncarnation != connection.incarnation ) {
+            throw Util.sqlException(ErrorCode.X_08503);
+        }
+    }
+
+    /**
+     * processes chained warnings and any generated columns result set
+     */
+    void performPostExecute() throws SQLException {
+
+        resultOut.clearLobResults();
+
+        generatedResult = null;
+
+        if (resultIn == null) {
+            return;
+        }
+
+        rootWarning = null;
+
+        Result current = resultIn;
+
+        while (current.getChainedResult() != null) {
+            current = current.getUnlinkChainedResult();
+
+            if (current.getType() == ResultConstants.WARNING) {
+                SQLWarning w = Util.sqlWarning(current);
+
+                if (rootWarning == null) {
+                    rootWarning = w;
+                } else {
+                    rootWarning.setNextWarning(w);
+                }
+            } else if (current.getType() == ResultConstants.ERROR) {
+                errorResult = current;
+            } else if (current.getType() == ResultConstants.DATA) {
+                generatedResult = current;
+            }
+        }
+
+        if (rootWarning != null) {
+            connection.setWarnings(rootWarning);
+        }
+
+        if (resultIn.isData()) {
+            currentResultSet = new JDBCResultSet(connection,
+                                                 this, resultIn,
+                                                 resultIn.metaData);
+        }
+    }
+
+    int getUpdateCount() throws SQLException {
+
+        checkClosed();
+
+        return (resultIn == null || resultIn.isData()) ? -1
+                                                       : resultIn
+                                                       .getUpdateCount();
+    }
+
+    ResultSet getResultSet() throws SQLException {
+
+        checkClosed();
+
+        ResultSet result = currentResultSet;
+
+        currentResultSet = null;
+
+        return result;
+    }
+
+    boolean getMoreResults() throws SQLException {
+        return getMoreResults(CLOSE_CURRENT_RESULT);
+    }
+
+    /**
+     * Not yet correct for multiple ResultSets. Should keep track of all
+     * previous ResultSet objects to be able to close them
+     */
+    boolean getMoreResults(int current) throws SQLException {
+
+        checkClosed();
+
+        if (resultIn == null) {
+            return false;
+        }
+
+        if (!resultIn.isData()) {
+            resultIn = null;
+
+            return false;
+        }
+
+        if (currentResultSet != null && current != KEEP_CURRENT_RESULT) {
+            currentResultSet.close();
+        }
+
+        resultIn = null;
+
+        return false;
+    }
+
+    ResultSet getGeneratedResultSet() throws SQLException {
+
+        if (generatedResultSet != null) {
+            generatedResultSet.close();
+        }
+
+        if (generatedResult == null) {
+            generatedResult = Result.emptyGeneratedResult;
+        }
+
+        generatedResultSet = new JDBCResultSet(connection, null,
+                                               generatedResult,
+                                               generatedResult.metaData);
+
+        return generatedResultSet;
+    }
+
+    /**
+     * See comment for getMoreResults.
+     */
+    void closeResultData() throws SQLException {
+
+        if (currentResultSet != null) {
+            currentResultSet.close();
+        }
+
+        if (generatedResultSet != null) {
+            generatedResultSet.close();
+        }
+
+        generatedResultSet = null;
+        generatedResult    = null;
+        resultIn           = null;
+    }
+
+    /**
+     * JDBC 3 constants
+     */
+    static final int CLOSE_CURRENT_RESULT  = 1;
+    static final int KEEP_CURRENT_RESULT   = 2;
+    static final int CLOSE_ALL_RESULTS     = 3;
+    static final int SUCCESS_NO_INFO       = -2;
+    static final int EXECUTE_FAILED        = -3;
+    static final int RETURN_GENERATED_KEYS = 1;
+    static final int NO_GENERATED_KEYS     = 2;
+}
diff --git a/src/org/hsqldb/jdbc/Util.java b/src/org/hsqldb/jdbc/Util.java
new file mode 100644
index 0000000..9d474fa
--- /dev/null
+++ b/src/org/hsqldb/jdbc/Util.java
@@ -0,0 +1,906 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc;
+
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+
+//#ifdef JAVA6
+import java.sql.SQLDataException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLIntegrityConstraintViolationException;
+import java.sql.SQLInvalidAuthorizationSpecException;
+import java.sql.SQLNonTransientConnectionException;
+import java.sql.SQLSyntaxErrorException;
+import java.sql.SQLTransactionRollbackException;
+import java.sql.SQLTransientConnectionException;
+
+//#endif JAVA6
+import org.hsqldb.HsqlException;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.result.Result;
+
+/* $Id: Util.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+// boucherb@users - 20060523 - patch 1.9.0 - removed some unused imports
+// Revision 1.16  2006/07/12 11:53:53  boucherb
+//  - merging back remaining material overritten by Fred's type-system upgrades
+
+/**
+ * Provides driver constants and a gateway from internal HsqlExceptions to
+ * external SQLExceptions.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class Util {
+
+    static final void throwError(HsqlException e) throws SQLException {
+
+//#ifdef JAVA6
+        throw sqlException(e.getMessage(), e.getSQLState(), e.getErrorCode(),
+                           e);
+
+//#else
+/*
+        throw new SQLException(e.getMessage(), e.getSQLState(),
+                               e.getErrorCode());
+*/
+
+//#endif JAVA6
+    }
+
+    static final void throwError(Result r) throws SQLException {
+
+//#ifdef JAVA6
+        throw sqlException(r.getMainString(), r.getSubString(),
+                           r.getErrorCode(), r.getException());
+
+//#else
+/*
+        throw new SQLException(r.getMainString(), r.getSubString(),
+                               r.getErrorCode());
+*/
+
+//#endif JAVA6
+    }
+
+    public static final SQLException sqlException(HsqlException e) {
+
+//#ifdef JAVA6
+        return sqlException(e.getMessage(), e.getSQLState(), e.getErrorCode(),
+                            e);
+
+//#else
+/*
+        return new SQLException(e.getMessage(), e.getSQLState(),
+                                e.getErrorCode());
+*/
+
+//#endif JAVA6
+    }
+
+    public static final SQLException sqlException(HsqlException e,
+            Throwable cause) {
+
+//#ifdef JAVA6
+        return sqlException(e.getMessage(), e.getSQLState(), e.getErrorCode(),
+                            cause);
+
+//#else
+/*
+        return new SQLException(e.getMessage(), e.getSQLState(),
+                                e.getErrorCode());
+*/
+
+//#endif JAVA6
+    }
+
+    public static final SQLException sqlException(int id) {
+        return sqlException(Error.error(id));
+    }
+
+    public static final SQLException sqlExceptionSQL(int id) {
+        return sqlException(Error.error(id));
+    }
+
+    public static final SQLException sqlException(int id, String message) {
+        return sqlException(Error.error(id, message));
+    }
+
+    public static final SQLException sqlException(int id, String message,
+            Exception cause) {
+        return sqlException(Error.error(id, message), cause);
+    }
+
+    public static final SQLException sqlException(int id, int add) {
+        return sqlException(Error.error(id, add));
+    }
+
+    static final SQLException sqlException(int id, int subId, Object[] add) {
+        return sqlException(Error.error(null, id, subId, add));
+    }
+
+    static final SQLException notSupported() {
+        return sqlException(Error.error(ErrorCode.X_0A000));
+    }
+
+    static SQLException notUpdatableColumn() {
+        return sqlException(ErrorCode.X_0U000);
+    }
+
+    public static SQLException nullArgument() {
+        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT);
+    }
+
+    static SQLException nullArgument(String name) {
+        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, name + ": null");
+    }
+
+    public static SQLException invalidArgument() {
+        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT);
+    }
+
+    public static SQLException invalidArgument(String name) {
+        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, name);
+    }
+
+    public static SQLException outOfRangeArgument() {
+        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT);
+    }
+
+    public static SQLException outOfRangeArgument(String name) {
+        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, name);
+    }
+
+    public static SQLException connectionClosedException() {
+        return sqlException(ErrorCode.X_08003);
+    }
+
+    public static SQLWarning sqlWarning(Result r) {
+        return new SQLWarning(r.getMainString(), r.getSubString(),
+                              r.getErrorCode());
+    }
+
+    public static SQLException sqlException(Result r) {
+
+//#ifdef JAVA6
+        return new SQLException(r.getMainString(), r.getSubString(),
+                                r.getErrorCode(), r.getException());
+
+//#else
+/*
+        return new SQLException(r.getMainString(), r.getSubString(),
+                                r.getErrorCode());
+*/
+
+//#endif JAVA6
+    }
+
+// TODO: Needs review.
+//
+//  Connection exception subclass may be an insufficient discriminator
+//  regarding the choice of throwing transient or non-transient
+//  connection exception.
+//
+// SQL 2003 Table 32  SQLSTATE class and subclass values
+//
+//  connection exception 08 (no subclass)                     000
+//
+//                     SQL-client unable to establish    001
+//                     SQL-connection
+//
+//                     connection name in use            002
+//
+//                     connection does not exist         003
+//
+//                     SQL-server rejected establishment 004
+//                     of SQL-connection
+//
+//                     connection failure                006
+//
+//                     transaction resolution unknown    007
+// org.hsqldb.Trace - sql-error-messages
+//
+// 080=08000 socket creation error                             - better 08001 ?
+// 085=08000 Unexpected exception when setting up TLS
+//
+// 001=08001 The database is already in use by another process - better 08002 ?
+//
+// 002=08003 Connection is closed
+// 003=08003 Connection is broken
+// 004=08003 The database is shutdown
+// 094=08003 Database does not exists                          - better 08001 ?
+//
+//#ifdef JAVA6
+    public static final SQLException sqlException(String msg, String sqlstate,
+            int code, Throwable cause) {
+
+        if (sqlstate.startsWith("08")) {
+            if (!sqlstate.endsWith("3")) {
+
+                // then, e.g. - the database may spuriously cease to be "in use"
+                //              upon retry
+                //            - the network configuration, server availability
+                //              may change spuriously
+                //            - keystore location/content may change spuriously
+                return new SQLTransientConnectionException(msg, sqlstate,
+                        code, cause);
+            } else {
+
+                // the database is (permanently) shut down or the connection is
+                // (permanently) closed or broken
+                return new SQLNonTransientConnectionException(msg, sqlstate,
+                        code, cause);
+            }
+        } else if (sqlstate.startsWith("22")) {
+            return new SQLDataException(msg, sqlstate, code, cause);
+        } else if (sqlstate.startsWith("23")) {
+            return new SQLIntegrityConstraintViolationException(msg, sqlstate,
+                    code, cause);
+        } else if (sqlstate.startsWith("28")) {
+            return new SQLInvalidAuthorizationSpecException(msg, sqlstate,
+                    code, cause);
+        } else if (sqlstate.startsWith("42") || sqlstate.startsWith("37")
+                   || sqlstate.startsWith("2A")) {
+
+            // TODO:
+            //
+            // First, the overview section of java.sql.SQLSyntaxErrorException
+            //
+            // "...thrown when the SQLState class value is '<i>42</i>'"
+            //
+            // appears to be inaccurate or not in sync with the
+            // SQL 2003 standard, 02 Foundation, Table 32, which states:
+            //
+            // Condition                               Class SubClass
+            // syntax error or access rule violation -  42   (no subclass) 000
+            //
+            // SQL 2003 describes an Access Rule Violation as refering to
+            // the case where, in the course of preparing or executing
+            // an SQL statement, an Access Rule section pertaining
+            // to one of the elements of the statement is violated.
+            //
+            // Further, section 13.4 Calls to an <externally-invoked-procedure>
+            // lists:
+            //
+            // SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION_NO_SUBCLASS:
+            // constant SQLSTATE_TYPE :="42000";
+            // SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION_IN_DIRECT_STATEMENT_NO_SUBCLASS:
+            // constant SQLSTATE_TYPE :="2A000";
+            // SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION_IN_DYNAMIC_STATEMENT_NO_SUBCLASS:
+            // constant SQLSTATE_TYPE :="37000";
+            //
+            // Strangely, SQLSTATEs "37000" and 2A000" are not mentioned
+            // anywhere else in any of the SQL 2003 parts and are
+            // conspicuously missing from 02 - Foundation, Table 32.
+            //
+            //  -----------------------------------
+            ///
+            // Our only Access Violation SQLSTATE so far is:
+            //
+            // Error.NOT_AUTHORIZED 255=42000 User not authorized for action '$$'
+            //
+            // Our syntax exceptions are apparently all sqlstate "37000"
+            //
+            // Clearly, we should differentiate between DIRECT and DYNAMIC
+            // SQL forms.  And clearly, our current "37000" is "wrong" in
+            // that we do not actually support dynamic SQL syntax, but
+            // rather implement similar behaviour only through JDBC
+            // Prepared and Callable statements.
+            return new SQLSyntaxErrorException(msg, sqlstate, code, cause);
+        } else if (sqlstate.startsWith("40")) {
+
+            // TODO: our 40xxx exceptions are not currently used (correctly)
+            //       for transaction rollback exceptions:
+            //
+            //       018=40001 Serialization failure
+            //
+            //       - currently used to indicate Java object serialization
+            //         failures, which is just plain wrong.
+            //
+            //       019=40001 Transfer corrupted
+            //
+            //        - currently used to indicate IOExceptions related to
+            //          PreparedStatement XXXStreamYYY operations and Result
+            //          construction using RowInputBinary (e.g. when reading
+            //          a result transmitted over the network), which is
+            //          probably also just plain wrong.
+            //
+            // SQL 2003 02 - Foundation, Table 32 states:
+            //
+            // 40000  transaction rollback  - no subclass
+            // 40001  transaction rollback  - (transaction) serialization failure
+            // 40002  transaction rollback  - integrity constraint violation
+            // 40003  transaction rollback  - statement completion unknown
+            // 40004  transaction rollback  - triggered action exception
+            //
+            return new SQLTransactionRollbackException(msg, sqlstate, code,
+                    cause);
+        } else if (sqlstate.startsWith("0A")) {    // JSR 221 2005-12-14 prd
+            return new SQLFeatureNotSupportedException(msg, sqlstate, code,
+                    cause);
+        } else {
+
+            // TODO resolved:
+            //
+            // JSR 221 2005-12-14 prd
+            //
+            //   "Any SQLState class values which are currently not mapped to
+            //    either a SQLNonTransientException or a SQLTransientException
+            //    will result in a java.sql.SQLException being thrown."
+            //
+            return new SQLException(msg, sqlstate, code, cause);
+        }
+    }
+
+//#endif JAVA6
+// -----------------------------------------------------------------------------
+// TODO:
+// This is just reminder stuff to borrow from as error reporting is refined,
+// better localized and made more standards-compliant.
+//    static SQLException blobDirectUpdateByLocatorNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException blobInFreedStateException() {
+//        return sqlException(ErrorCode.ASSERT_FAILED, "valid==true");
+//    }
+//
+//    static SQLException blobInputMaxOctetLengthExceededException(long length) {
+//        String msg = "Maximum Blob input octet length exceeded: "
+//                   + length; //NOI18N
+//
+//        return sqlException(ErrorCode.INPUTSTREAM_ERROR, msg);
+//    }
+//
+//    static SQLException blobInputStreamTransferCorruptedException(Exception e) {
+//        // According to SQL 2003, error code 19 should not
+//        // have sqlstate 40001, which is supposed to indicate a
+//        // transaction rollback due to transaction serialization
+//        // failure
+//        return sqlException(ErrorCode.TRANSFER_CORRUPTED, String.valueOf(e));
+//    }
+//
+//    static SQLException callableStatementOutAndInOutParametersNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException callableStatementParameterIndexNotFoundException(int index) {
+//        //String msg = "Parameter index out of bounds: " + index; //NOI18N
+//        return sqlException(Error.error(ErrorCode.COLUMN_NOT_FOUND, Integer.toString(index)));
+//    }
+//
+//    static SQLException callableStatementParameterNameNotFoundException(String parameterName) {
+//        return sqlException(Error.error(ErrorCode.COLUMN_NOT_FOUND, parameterName));
+//    }
+//
+//    static SQLException characterInputStreamIOException(Exception e) {
+//        return sqlException(Error.INPUTSTREAM_ERROR, String.valueOf(e));
+//    }
+//
+//    static SQLException characterInputStreamTransferCorruptedException(Exception e) {
+//        // According to SQL 2003, error code 19 should not
+//        // have sqlstate 40001, which is supposed to indicate a
+//        // transaction rollback due to transaction serialization
+//        // failure
+//        return sqlException(ErrorCode.TRANSFER_CORRUPTED, String.valueOf(e));
+//    }
+//
+//    static SQLException characterOutputStreamIOException(Exception e) {
+//        return sqlException(ErrorCode.GENERAL_IO_ERROR, String.valueOf(e));
+//    }
+//
+//    static SQLException characterSequenceIndexArgumentOutOfBoundsException(String name, long value) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, name + ": " + value);
+//    }
+//
+//    static SQLException clientInfoNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED, "ClientInfo");
+//    }
+//
+//    static SQLException clobDirectUpdateByLocatorNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException clobInFreedStateException() {
+//        return sqlException(ErrorCode.ASSERT_FAILED, "valid==true");
+//    }
+//
+//    static SQLException clobInputMaxCharacterLengthExceededException(long length) {
+//        String msg = "Max Clob input character length exceeded: "
+//                   + length; //NOI18N
+//
+//        return sqlException(ErrorCode.INPUTSTREAM_ERROR, msg);
+//    }
+//
+//    static SQLException clobInputStreamTransferCorruptedException(Exception e) {
+//        // According to SQL 2003, error code 19 should not
+//        // have sqlstate 40001, which is supposed to indicate a
+//        // transaction rollback due to transaction serialization
+//        // failure
+//        return sqlException(ErrorCode.TRANSFER_CORRUPTED, String.valueOf(e));
+//    }
+//
+////    public static SQLException connectionClosedException() {
+////        return sqlException(ErrorCode.CONNECTION_IS_CLOSED);
+////    }
+//
+//
+//    static SQLException connectionNativeSQLException(String sql, int index) {
+//        boolean substitute = true;
+//        String msg = Error.getMessage(ErrorCode.JDBC_CONNECTION_NATIVE_SQL,
+//                                      substitute, new Object[]{
+//                                      sql.substring(index)});
+//
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, msg);
+//    }
+//
+//    static SQLException connectionResetFailureException(Exception e) {
+//        return sqlException(ErrorCode.GENERAL_ERROR, "Error resetting connection: "
+//                                   + e.getMessage());
+//    }
+//
+//    static SQLException deserializeToJavaObjectException(HsqlException e) {
+//        // TODO:  This is wrong.
+//        // According to SQL 2003, error code 18,
+//        // sqlstate 40001 is supposed to indicate a
+//        // transaction rollback due to
+//        // transaction serialization failure
+//        return sqlException(e);
+//    }
+//
+//    public static SQLException driverConnectMalformedURLException(String url) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, "url: " + url);
+//    }
+//
+//    public static SQLException driverConnectTimeoutException(long timeout) {
+//        return sqlException(ErrorCode.GENERAL_ERROR,
+//                           "Connect operation timed out after " + timeout + " ms.");
+//    }
+//
+//
+//    static SQLException illegalBestRowIdentifierScopeArgumentException(int scope) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+//                            Error.JDBC_ILLEGAL_BRI_SCOPE,
+//                            new Object[]  {Integer.toString(scope)});
+//    }
+//
+//    static SQLException illegalConnectionSubProtocolException(String protocol) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, "protocol: " + protocol);
+//    }
+//
+//    static SQLException illegalHexadecimalCharacterSequenceArgumentException(String name, Exception e) {
+//        return sqlException(ErrorCode.INVALID_CONVERSION, name + ": " + e);
+//    }
+//
+//    static SQLException illegalNegativeIntegralArgumentException(String name, long value) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, name + ": " + value);
+//    }
+//
+//    static SQLException illegalNullArgumentException(String name) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, name + ": null");
+//    }
+//
+//    static SQLException illegalResultSetConcurrencyArgumentException(int concurrency) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, "concurrency: " + concurrency);
+//    }
+//
+//    static SQLException illegalResultSetFetchDirectionArgumentException(int direction) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, "direction: " + direction);
+//    }
+//
+//    static SQLException illegalResultSetHoldabilityArgumentException(int holdability) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, "holdability: " + holdability);
+//    }
+//
+//    static SQLException illegalResultSetTypeArgumentException(int type) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, "type: " + type);
+//    }
+//
+//    static SQLException illegalTableTypeArgumentException(int index, String type) {
+//        String msg = "types[" + index + "]=>\"" + type + "\"";
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, msg);
+//    }
+//
+//    static SQLException illegalTransactionIsolationLevelArgumentException(int level) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, "level: " + level);
+//    }
+//
+//    static SQLException illegalUnicodeStreamLengthArgumentException(int length) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT,
+//                "Odd length argument for pre-JDBC4 UTF16 encoded stream: "
+//                  + length); //NOI18N
+//    }
+//
+//    static SQLException invalidDateTimeEscapeException(Exception e) {
+//        return sqlException(ErrorCode.INVALID_ESCAPE, e.getMessage());
+//    }
+//
+//    static SQLException invalidNullInputStreamArgumentException() {
+//        return sqlException(ErrorCode.error(ErrorCode.JDBC_INVALID_ARGUMENT,
+//                Error.JDBC_NULL_STREAM));
+//    }
+//
+//    static SQLException octetInputStreamInvalidCharacterEncodingException(Exception e) {
+//        return sqlException(ErrorCode.INVALID_CHARACTER_ENCODING, String.valueOf(e));
+//    }
+//
+//    static SQLException octetInputStreamTransferCorruptedException(Exception e) {
+//        // According to SQL 2003, error code 19 should not
+//        // have sqlstate 40001, which is supposed to indicate a
+//        // transaction rollback due to transaction serialization
+//        // failure
+//        return sqlException(ErrorCode.TRANSFER_CORRUPTED, String.valueOf(e));
+//    }
+//
+//    static SQLException octetSequenceIndexArgumentOutOfBoundsException(String name, long value) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, name + ": " + value);
+//    }
+//
+//    static SQLException parameterMetaDataParameterIndexNotFoundException(int index) {
+//        // String msg = param + " is out of range"; //NOI18N
+//        return sqlException(ErrorCode.COLUMN_NOT_FOUND, Integer.toString(index));
+//    }
+//
+//    static SQLException preparedStatementFeatureNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException preparedStatementInitializationException(Exception e) {
+//        return sqlException(ErrorCode.GENERAL_ERROR, e.toString());
+//    }
+//
+//    static SQLException preparedStatementParameterIndexNotFoundException(int parameterIndex) {
+//        return sqlException(ErrorCode.COLUMN_NOT_FOUND,
+//                            Integer.toString(parameterIndex));
+//    }
+//
+//    static SQLException resultSetClosedException() {
+//        return sqlException(ErrorCode.JDBC_RESULTSET_IS_CLOSED);
+//    }
+//
+//    static SQLException resultSetColumnIndexNotFoundException(int columnIndex) {
+//        return sqlException(ErrorCode.COLUMN_NOT_FOUND,
+//                Integer.toString(columnIndex));
+//    }
+//
+//    static SQLException resultSetColumnNameNotFoundException(String columnName) {
+//        return sqlException(Error.error(ErrorCode.COLUMN_NOT_FOUND, columnName));
+//    }
+//
+//    static SQLWarning resultSetConcurrencyTranslationWarning(int requestedConcurrency,
+//                                                             int translatedConcurrency) {
+//        String requested  = toResultSetConcurrencyString(requestedConcurrency);
+//        String translated = toResultSetConcurrencyString(translatedConcurrency);
+//        String msg        = requested + " => " + translated;
+//
+//        return new SQLWarning(msg, "SOO10", Error.JDBC_INVALID_ARGUMENT);
+//    }
+//
+//    static SQLException resultSetCursorNameNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException resultSetDataIsNotAvailableException() {
+//        return sqlException(ErrorCode.NO_DATA_IS_AVAILABLE);
+//    }
+//
+//    static SQLException resultSetFetchDirectionValueNotSupportedException(int direction) {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED,
+//                            toResultSetFetchDirectionString(direction));
+//    }
+//
+//    static SQLWarning resultSetHoldabilityTranslationWarning(int requestedHoldability, int translatedHoldability) {
+//        String requested  = toResultSetHoldabilityString(requestedHoldability);
+//        String translated = toResultSetHoldabilityString(translatedHoldability);
+//        String msg        = requested + " => " + translated;
+//
+//        return new SQLWarning(msg, "SOO10", Error.JDBC_INVALID_ARGUMENT);
+//    }
+//
+//
+//    static SQLException resultSetHoldabilityValueNotSupportedException(int holdability) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, toResultSetHoldabilityString(holdability));
+//    }
+//
+//    static SQLException resultSetIsForwardOnlyException() {
+//        return sqlException(ErrorCode.RESULTSET_FORWARD_ONLY);
+//    }
+//
+//    static SQLException resultSetMetaDataColumnIndexNotFoundException(int columnIndex) {
+//        return Util.sqlException(ErrorCode.COLUMN_NOT_FOUND,
+//                Integer.toString(columnIndex));
+//    }
+//
+//    static SQLException resultSetMetaDataInitializationNullResultArgumentException() {
+//        return sqlException(ErrorCode.GENERAL_ERROR,
+//                Error.JDBC_NO_RESULT_SET, null);
+//    }
+//
+//    static SQLException resultSetMetaDataInitializationNullResultSetArgumentException() {
+//        return sqlException(ErrorCode.GENERAL_ERROR,
+//                Error.JDBC_NO_RESULT_SET_METADATA, null);
+//    }
+//
+//    static SQLException resultSetNotRefreshableException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException resultSetNotUpdateableException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLWarning resultSetTypeTranslationWarning(int requestedType, int translatedType) {
+//        String requested  = toResultSetTypeString(requestedType);
+//        String translated = toResultSetTypeString(translatedType);
+//        String msg        = requested + " => " + translated;
+//
+//        return new SQLWarning(msg, "SOO10", Error.JDBC_INVALID_ARGUMENT);
+//    }
+//
+//
+//    static SQLException resultSetWasNotGeneratedByStatementExecutionException() {
+//        String msg = "Expected but did not receive a result set"; // NOI18N
+//
+//        return sqlException(ErrorCode.UNEXPECTED_EXCEPTION, msg);
+//    }
+//
+//    static SQLException resultSetWillNotBeGeneratedByExecuteQueryException() {
+//        return sqlException(ErrorCode.JDBC_STATEMENT_NOT_RESULTSET);
+//    }
+//
+//    static SQLException retrieveAutoGeneratedKeysFeatureNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException savepointIssuedOnDifferentConnectionException() {
+//        return sqlException(ErrorCode.ASSERT_FAILED, "savepoint.connection==this");
+//    }
+//
+//    static SQLException savepointNumericIdentifierNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException savepointRollbackInAutocommitException() {
+//        return sqlException(ErrorCode.ASSERT_FAILED, "autocommit==false");
+//    }
+//
+//    static SQLException savepointWrongObjectClassException(Class clazz) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, "savepoint: " + clazz);
+//    }
+//
+//    static SQLException sqlxmlDirectUpdateByLocatorNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException sqlxmlInFreedStateException() {
+//        return sqlException(ErrorCode.ASSERT_FAILED, "valid==true");
+//    }
+//
+//    static SQLException sqlxmlParseException(Exception e) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, e.toString());
+//    }
+//
+//    static SQLException sqlxmlParserInitializationException(Exception e) {
+//        return sqlException(ErrorCode.GENERAL_ERROR, e.toString());
+//    }
+//
+//    static SQLException statementClosedException() {
+//        return sqlException(ErrorCode.STATEMENT_IS_CLOSED);
+//    }
+//
+//    static SQLException statementGetMoreResultsWithCurrentResultSetHandlingNotSupportedException() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static int toObjectDataType(Object o) {
+//        if (o == null) {
+//            return Types.NULL;
+//        }
+//
+//        if (o instanceof Binary) {
+//            return Types.BINARY;
+//        }  else            if (o instanceof JavaObject) {
+//                return Types.OTHER;
+//            }
+//
+//        try {
+//            return org.hsqldb.Types.getTypeNr(o.getClass().getName());
+//        }  catch (Exception e) {
+//            return o instanceof Serializable ? Types.OTHER : Types.JAVA_OBJECT;
+//        }
+//    }
+//
+//    static String toResultSetConcurrencyString(int type) {
+//        switch(type) {
+//            case JDBCResultSet.CONCUR_READ_ONLY:
+//            {
+//                return "CONCUR_READ_ONLY";
+//            }
+//            JDBCResultSet.CONCUR_UPDATABLE:
+//            {
+//                return "CONCUR_UPDATABLE";
+//            }
+//            default:
+//            {
+//                return "CONCUR_UNKNOWN: " + type;
+//            }
+//        }
+//    }
+//
+//    static String toResultSetFetchDirectionString(int direction) {
+//        switch(direction) {
+//            case JDBCResultSet.FETCH_FORWARD:
+//            {
+//                return "FETCH_FORWARD";
+//            }
+//            case JDBCResultSet.FETCH_REVERSE:
+//            {
+//                return "FETCH_REVERSE";
+//            }
+//            case JDBCResultSet.FETCH_UNKNOWN:
+//            {
+//                return "FETCH_UNKNOWN";
+//            }
+//            default:
+//            {
+//                return "direction: " + direction;
+//            }
+//        }
+//    }
+//
+//    static String toResultSetHoldabilityString(int type) {
+//        switch(type) {
+//            case JDBCResultSet.CLOSE_CURSORS_AT_COMMIT:
+//            {
+//                return "CLOSE_CURSORS_AT_COMMIT";
+//            }
+//            case JDBCResultSet.HOLD_CURSORS_OVER_COMMIT:
+//            {
+//                return "HOLD_CURSORS_OVER_COMMIT";
+//            }
+//            default:
+//            {
+//                return "HOLDABILITY_UNKNOWN: " + type;
+//            }
+//        }
+//    }
+//
+//
+//    static String toResultSetTypeString(int type) {
+//        switch(type) {
+//            case JDBCResultSet.TYPE_FORWARD_ONLY:
+//            {
+//                return "TYPE_FORWARD_ONLY";
+//            }
+//            case JDBCResultSet.TYPE_SCROLL_INSENSITIVE:
+//            {
+//                return "TYPE_SCROLL_INSENSITIVE";
+//            }
+//            case JDBCResultSet.TYPE_SCROLL_SENSITIVE:
+//            {
+//                return "TYPE_SCROLL_SENSITIVE";
+//            }
+//            default:
+//            {
+//                return "TYPE_UNKNOWN: " + type;
+//            }
+//        }
+//    }
+//
+//    static SQLException unsupportedDataType_ARRAY_Exception() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//
+//    static SQLException unsupportedDataType_DATALINK_Exception() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException unsupportedDataType_DISTINCT_Exception() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException unsupportedDataType_REF_Exception() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException unsupportedDataType_ROWID_Exception() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException unsupportedDataType_SQLXML_Exception() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException unsupportedDataType_STRUCT_Exception() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//    static SQLException unsupportedDataTypes_STRUCT_AND_DISTINCT_Exception() {
+//        return sqlException(ErrorCode.FUNCTION_NOT_SUPPORTED);
+//    }
+//
+//
+//    static SQLException unsupportedParameterValueConversionException(Object srcVal, int dstType) {
+//        return unsupportedParameterValueConversionException(toObjectDataType(srcVal),
+//                                                            srcVal,
+//                                                            dstType);
+//    }
+//
+//    static SQLException unsupportedParameterValueConversionException(int srcType, Object srcVal, int dstType) {
+//        String msg = Types.getTypeString(srcType)
+//                + " => "
+//                + Types.getTypeString(dstType)
+//                + " : "
+//                + srcVal;
+//
+//        return sqlException(ErrorCode.INVALID_CONVERSION, msg);
+//    }
+//
+//    static SQLException unsupportedResultSetValueConversionException(int srcType, Object srcVal, int dstType) {
+//        String msg = Types.getTypeString(srcType)
+//                + " => "
+//                + Types.getTypeString(dstType)
+//                + " : "
+//                + srcVal;
+//
+//        return sqlException(ErrorCode.INVALID_CONVERSION, msg);
+//    }
+//
+//    static SQLException updateCountResultInResultSetInitializationException() {
+//        return sqlException(ErrorCode.ASSERT_FAILED, "result.mode != UPDATECOUNT");
+//    }
+//
+//    static SQLException updateCountWasNotGeneratedByPreparedStatementExecutionException() {
+//        String msg = "Expected but did not receive a row update count"; //NOI18N
+//
+//        return sqlException(ErrorCode.UNEXPECTED_EXCEPTION, msg);
+//    }
+//
+//    static SQLException updateCountWasNotGeneratedByStatementExecutionException() {
+//        return sqlException(ErrorCode.ASSERT_FAILED,
+//                            Error.getMessage(ErrorCode.JDBC_STATEMENT_EXECUTE_UPDATE));
+//    }
+//
+//    static SQLException updateCountWillNotBeGeneratedByExecuteUpdateException() {
+//        return sqlException(ErrorCode.JDBC_STATEMENT_NOT_ROW_COUNT);
+//    }
+//
+//    public static SQLException wrappedObjectNotFoundException(Class clazz) {
+//        return sqlException(ErrorCode.JDBC_INVALID_ARGUMENT, String.valueOf(clazz));
+//    }
+}
diff --git a/src/org/hsqldb/jdbc/package.html b/src/org/hsqldb/jdbc/package.html
new file mode 100644
index 0000000..adeb0df
--- /dev/null
+++ b/src/org/hsqldb/jdbc/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<BODY>
+  Contains the HyperSQL JDBC Driver, and other classes providing JDBC
+  functionality and support.
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/jdbc/pool/BaseConnectionWrapper.java b/src/org/hsqldb/jdbc/pool/BaseConnectionWrapper.java
new file mode 100644
index 0000000..ac8252c
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/BaseConnectionWrapper.java
@@ -0,0 +1,472 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Map;
+import java.util.Properties;
+
+import org.hsqldb.jdbc.Util;
+
+//#ifdef JAVA6
+import java.sql.ClientInfoStatus;
+import java.sql.NClob;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLXML;
+
+//#endif JAVA6
+
+/* $Id: BaseConnectionWrapper.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+// boucherb@users 20060523 - patch 1.9.0 full synch up to Mustang Build 84
+// Revision 1.7  2006/07/12 12:45:54  boucherb
+// - full synch up to Mustang b90
+
+/**
+ * A base class for the two different types of connection wrappers:
+ * SessionConnectionWrapper and LifeTimeConnectionWrapper
+ *
+ * @author Jakob Jenkov
+ */
+public abstract class BaseConnectionWrapper implements java.sql.Connection {
+
+    protected boolean isClosed = false;
+
+    protected abstract Connection getConnection();
+
+    protected void validate() throws SQLException {
+
+        if (isClosed) {
+            throw Util.connectionClosedException();
+        }
+    }
+
+    public boolean isClosed() throws SQLException {
+        return isClosed;
+    }
+
+    public int getHoldability() throws SQLException {
+
+        validate();
+
+        return getConnection().getHoldability();
+    }
+
+    public int getTransactionIsolation() throws SQLException {
+
+        validate();
+
+        return getConnection().getTransactionIsolation();
+    }
+
+    public void clearWarnings() throws SQLException {
+        validate();
+        getConnection().clearWarnings();
+    }
+
+    public void commit() throws SQLException {
+        validate();
+        this.getConnection().commit();
+    }
+
+    public void rollback() throws SQLException {
+        validate();
+        this.getConnection().rollback();
+    }
+
+    public boolean getAutoCommit() throws SQLException {
+        return getConnection().getAutoCommit();
+    }
+
+    public boolean isReadOnly() throws SQLException {
+
+        validate();
+
+        return getConnection().isReadOnly();
+    }
+
+    public void setHoldability(int holdability) throws SQLException {
+        validate();
+        this.getConnection().setHoldability(holdability);
+    }
+
+    public void setTransactionIsolation(int level) throws SQLException {
+        validate();
+        this.getConnection().setTransactionIsolation(level);
+    }
+
+    public void setAutoCommit(boolean autoCommit) throws SQLException {
+        validate();
+        this.getConnection().setAutoCommit(autoCommit);
+    }
+
+    public void setReadOnly(boolean readOnly) throws SQLException {
+        validate();
+        this.getConnection().setReadOnly(readOnly);
+    }
+
+    public String getCatalog() throws SQLException {
+
+        validate();
+
+        return this.getConnection().getCatalog();
+    }
+
+    public void setCatalog(String catalog) throws SQLException {
+        validate();
+        this.getConnection().setCatalog(catalog);
+    }
+
+    public DatabaseMetaData getMetaData() throws SQLException {
+
+        validate();
+
+        return getConnection().getMetaData();
+    }
+
+    public SQLWarning getWarnings() throws SQLException {
+
+        validate();
+
+        return this.getConnection().getWarnings();
+    }
+
+    public Savepoint setSavepoint() throws SQLException {
+
+        validate();
+
+        return this.getConnection().setSavepoint();
+    }
+
+    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+        validate();
+        this.getConnection().releaseSavepoint(savepoint);
+    }
+
+    public void rollback(Savepoint savepoint) throws SQLException {
+        validate();
+        this.getConnection().rollback(savepoint);
+    }
+
+    public Statement createStatement() throws SQLException {
+
+        validate();
+
+        return getConnection().createStatement();
+    }
+
+    public Statement createStatement(
+            int resultSetType, int resultSetConcurrency) throws SQLException {
+
+        validate();
+
+        return this.getConnection().createStatement(resultSetType,
+                resultSetConcurrency);
+    }
+
+    public Statement createStatement(
+            int resultSetType, int resultSetConcurrency,
+            int resultSetHoldability) throws SQLException {
+
+        validate();
+
+        return this.getConnection().createStatement(resultSetType,
+                resultSetConcurrency, resultSetHoldability);
+    }
+
+    public Map getTypeMap() throws SQLException {
+
+        validate();
+
+        return this.getConnection().getTypeMap();
+    }
+
+    public void setTypeMap(Map map) throws SQLException {
+        validate();
+        this.getConnection().setTypeMap(map);
+    }
+
+    public String nativeSQL(String sql) throws SQLException {
+
+        validate();
+
+        return this.getConnection().nativeSQL(sql);
+    }
+
+    public CallableStatement prepareCall(String sql) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareCall(sql);
+    }
+
+    public CallableStatement prepareCall(String sql, int resultSetType,
+            int resultSetConcurrency) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareCall(sql, resultSetType,
+                resultSetConcurrency);
+    }
+
+    public CallableStatement prepareCall(String sql, int resultSetType,
+            int resultSetConcurrency,
+            int resultSetHoldability) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareCall(sql, resultSetType,
+                resultSetConcurrency, resultSetHoldability);
+    }
+
+    public PreparedStatement prepareStatement(String sql) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareStatement(sql);
+    }
+
+    public PreparedStatement prepareStatement(String sql,
+            int autoGeneratedKeys) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareStatement(sql, autoGeneratedKeys);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+            int resultSetConcurrency) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareStatement(sql, resultSetType,
+                                                     resultSetConcurrency);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+            int resultSetConcurrency,
+            int resultSetHoldability) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareStatement(sql, resultSetType,
+                resultSetConcurrency, resultSetHoldability);
+    }
+
+    public PreparedStatement prepareStatement(String sql,
+            int columnIndexes[]) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareStatement(sql, columnIndexes);
+    }
+
+    public Savepoint setSavepoint(String name) throws SQLException {
+
+        validate();
+
+        return this.getConnection().setSavepoint(name);
+    }
+
+    public PreparedStatement prepareStatement(String sql,
+            String columnNames[]) throws SQLException {
+
+        validate();
+
+        return this.getConnection().prepareStatement(sql, columnNames);
+    }
+
+    //------------------------- JDBC 4.0 -----------------------------------
+//#ifdef JAVA6
+    public Clob createClob() throws SQLException {
+
+        validate();
+
+        return this.getConnection().createClob();
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public Blob createBlob() throws SQLException {
+
+        validate();
+
+        return this.getConnection().createBlob();
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public NClob createNClob() throws SQLException {
+
+        validate();
+
+        return this.getConnection().createNClob();
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public SQLXML createSQLXML() throws SQLException {
+
+        validate();
+
+        return this.getConnection().createSQLXML();
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public boolean isValid(int timeout) throws SQLException {
+
+        validate();
+
+        return this.getConnection().isValid(timeout);
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public void setClientInfo(String name,
+                              String value) throws SQLClientInfoException {
+
+        try {
+            validate();
+        } catch (SQLException e) {
+            throw new SQLClientInfoException(e.getMessage(), e.getSQLState(),
+                    e.getErrorCode(), (Map<String, ClientInfoStatus>) null, e);
+        }
+        this.getConnection().setClientInfo(name, value);
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public void setClientInfo(
+            Properties properties) throws SQLClientInfoException {
+
+        try {
+            validate();
+        } catch (SQLException e) {
+            throw new SQLClientInfoException(e.getMessage(), e.getSQLState(),
+                    e.getErrorCode(), (Map<String, ClientInfoStatus>) null, e);
+        }
+        this.getConnection().setClientInfo(properties);
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public String getClientInfo(String name) throws SQLException {
+
+        validate();
+
+        return this.getConnection().getClientInfo(name);
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public Properties getClientInfo() throws SQLException {
+
+        validate();
+
+        return this.getConnection().getClientInfo();
+    }
+
+//#endif JAVA6
+//#ifdef JDBC4BETA
+/*
+    public <T extends BaseQuery> T createQueryObject(java.lang.Class<T> ifc) throws SQLException {
+        validate();
+        return this.getConnection().createQueryObject(ifc);
+    }
+*/
+
+//#endif JAVA6
+//#ifdef JDBC4BETA
+/*
+    public <T extends BaseQuery> T createQueryObject(Class<T> ifc, Connection con) throws SQLException {
+        validate();
+        return this.getConnection().createQueryObject(ifc, con);
+    }
+*/
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {
+
+        validate();
+
+        if (this.isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+// --------------------------- Added: Mustang Build 80 -------------------------
+//#ifdef JAVA6
+    // renamed from createArray - b87
+    public Array createArrayOf(String typeName,
+                               Object[] elements) throws SQLException {
+
+        validate();
+
+        return this.getConnection().createArrayOf(typeName, elements);
+    }
+
+//#endif JAVA6
+//#ifdef JAVA6
+    public Struct createStruct(String typeName,
+                               Object[] attributes) throws SQLException {
+
+        validate();
+
+        return this.getConnection().createStruct(typeName, attributes);
+    }
+
+//#endif JAVA6
+}
diff --git a/src/org/hsqldb/jdbc/pool/ConnectionDefaults.java b/src/org/hsqldb/jdbc/pool/ConnectionDefaults.java
new file mode 100644
index 0000000..8f61272
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/ConnectionDefaults.java
@@ -0,0 +1,111 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import java.sql.SQLException;
+import java.sql.Connection;
+
+/**
+ * @author Jakob Jenkov
+ */
+public class ConnectionDefaults {
+
+    private int     holdability          = -1;
+    private int     transactionIsolation = -1;
+    private boolean isAutoCommit         = true;
+    private boolean isReadOnly           = false;
+    private String  catalog              = null;
+
+    public ConnectionDefaults() {
+    }
+
+    public ConnectionDefaults(Connection connection) throws SQLException {
+
+        this.holdability          = connection.getHoldability();
+        this.transactionIsolation = connection.getTransactionIsolation();
+        this.isAutoCommit         = connection.getAutoCommit();
+        this.isReadOnly           = connection.isReadOnly();
+        this.catalog              = connection.getCatalog();
+    }
+
+    public int getHoldability() throws SQLException {
+        return this.holdability;
+    }
+
+    public void setHoldability(int holdability) throws SQLException {
+        this.holdability = holdability;
+    }
+
+    public int getTransactionIsolation() throws SQLException {
+        return this.transactionIsolation;
+    }
+
+    public void setTransactionIsolation(int level) throws SQLException {
+        this.transactionIsolation = level;
+    }
+
+    public boolean getAutoCommit() throws SQLException {
+        return this.isAutoCommit;
+    }
+
+    public void setAutoCommit(boolean autoCommit) throws SQLException {
+        this.isAutoCommit = autoCommit;
+    }
+
+    public boolean isReadOnly() throws SQLException {
+        return this.isReadOnly;
+    }
+
+    public void setReadOnly(boolean readOnly) throws SQLException {
+        this.isReadOnly = readOnly;
+    }
+
+    public String getCatalog() throws SQLException {
+        return this.catalog;
+    }
+
+    public void setCatalog(String catalog) throws SQLException {
+        this.catalog = catalog;
+    }
+
+    public void setDefaults(Connection connection) throws SQLException {
+
+        connection.setHoldability(this.holdability);
+
+        if (this.transactionIsolation != Connection.TRANSACTION_NONE) {
+            connection.setTransactionIsolation(this.transactionIsolation);
+        }
+        connection.setAutoCommit(this.isAutoCommit);
+        connection.setReadOnly(this.isReadOnly);
+        connection.setCatalog(this.catalog);
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/JDBCConnectionPoolDataSource.java b/src/org/hsqldb/jdbc/pool/JDBCConnectionPoolDataSource.java
new file mode 100644
index 0000000..0f8f9d9
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/JDBCConnectionPoolDataSource.java
@@ -0,0 +1,309 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import org.hsqldb.jdbc.JDBCConnection;
+
+import javax.sql.ConnectionPoolDataSource;
+import javax.sql.PooledConnection;
+
+import java.io.PrintWriter;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+import org.hsqldb.jdbc.JDBCConnection;
+
+/**
+ * Don't do pooling. Only be a factory. Let ManagedPoolDataSource do the pooling.
+ * @author Jakob Jenkov
+ */
+public class JDBCConnectionPoolDataSource implements ConnectionPoolDataSource {
+
+    /**
+     * @todo:  Break off code used here and in JDBCXADataSource into an
+     *        abstract class, and have these classes extend the abstract
+     *        class.
+     */
+    public static final String   driver = "org.hsqldb.jdbc.JDBCDriver";
+    protected String             url                = null;
+    protected ConnectionDefaults connectionDefaults = null;
+    private int                  loginTimeout       = 0;
+    private PrintWriter          logWriter          = null;
+    protected Properties         connProperties = new java.util.Properties();
+
+    public JDBCConnectionPoolDataSource() {}
+
+    public JDBCConnectionPoolDataSource(String url, String user,
+                                        String password,
+                                        ConnectionDefaults connectionDefaults)
+                                        throws SQLException {
+
+        this.url                = url;
+        this.connectionDefaults = connectionDefaults;
+
+        setUser(user);
+        setPassword(password);
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getUser() {
+        return connProperties.getProperty("user");
+    }
+
+    public void setUser(String user) {
+        connProperties.setProperty("user", user);
+    }
+
+    public String getPassword() {
+        return connProperties.getProperty("password");
+    }
+
+    public void setPassword(String password) {
+        connProperties.setProperty("password", password);
+    }
+
+    /**
+     * @return seconds Time, in seconds.
+     * @throws SQLException
+     * @see javax.sql.ConnectionPoolDataSource#getLoginTimeout()
+     */
+    public int getLoginTimeout() throws SQLException {
+        return this.loginTimeout;
+    }
+
+    /**
+     * @param seconds Time, in seconds.
+     * @throws SQLException
+     * @see javax.sql.ConnectionPoolDataSource#setLoginTimeout(int)
+     */
+    public void setLoginTimeout(int seconds) throws SQLException {
+        this.loginTimeout = seconds;
+    }
+
+    /**
+     * @throws SQLException
+     * @see javax.sql.ConnectionPoolDataSource#getLogWriter()
+     */
+    public PrintWriter getLogWriter() throws SQLException {
+        return logWriter;
+    }
+
+    /**
+     * @throws SQLException
+     * @see javax.sql.ConnectionPoolDataSource#setLogWriter(PrintWriter)
+     */
+    public void setLogWriter(PrintWriter out) throws SQLException {
+        logWriter = out;
+    }
+
+    public PooledConnection getPooledConnection() throws SQLException {
+
+        try {
+            Class.forName(driver).newInstance();
+        } catch (ClassNotFoundException e) {
+            throw new SQLException("Error opening connection: "
+                                   + e.getMessage());
+        } catch (IllegalAccessException e) {
+            throw new SQLException("Error opening connection: "
+                                   + e.getMessage());
+        } catch (InstantiationException e) {
+            throw new SQLException("Error opening connection: "
+                                   + e.getMessage());
+        }
+
+        JDBCConnection connection =
+            (JDBCConnection) DriverManager.getConnection(url, connProperties);
+
+        return createPooledConnection(connection);
+    }
+
+    /**
+     * Throws a SQLException if given user name or password are not same
+     * as those configured for this object.
+     *
+     * @throws SQLException if given user name or password is wrong.
+     */
+    protected void validateSpecifiedUserAndPassword(String user,
+            String password) throws SQLException {
+
+        String configUser     = connProperties.getProperty("user", "");
+        String configPassword = connProperties.getProperty("password", "");
+
+        if (user == null) {
+            user = "";
+        }
+
+        if (password == null) {
+            password = "";
+        }
+
+        if (user.equals(configUser) && password.equals(configPassword)) {
+            return;
+        }
+
+        throw new SQLException("Given user name or password does not "
+                                   + "match those configured for this object");
+
+    }
+
+    /**
+     * Performs a getPooledConnection() after validating the given username
+     * and password.
+     *
+     * @param user String which must match the 'user' configured for this
+     *             JDBCConnectionPoolDataSource.
+     * @param password  String which must match the 'password' configured
+     *                  for this JDBCConnectionPoolDataSource.
+     *
+     * @see #getPooledConnection()
+     */
+    public PooledConnection getPooledConnection(String user,
+            String password) throws SQLException {
+
+        validateSpecifiedUserAndPassword(user, password);
+
+        return getPooledConnection();
+    }
+
+    public void close() {}
+
+    protected void logInfo(String message) {
+
+        if (logWriter != null) {
+            logWriter.write("HSQLDB:Info: " + message + '\n');
+            logWriter.flush();
+        }
+    }
+
+    protected void logInfo(Throwable t) {
+
+        if (logWriter != null) {
+            t.printStackTrace(logWriter);
+            logWriter.flush();
+        }
+    }
+
+    protected void logInfo(String message, Throwable t) {
+
+        if (logWriter != null) {
+            logWriter.write("HSQLDB:Exception: " + message + '\n');
+            logWriter.flush();
+            logInfo(t);
+        }
+    }
+
+    /**
+     * Sets JDBC Connection Properties to be used when physical
+     * connections are obtained for the pool.
+     */
+    public Object setConnectionProperty(String name, String value) {
+        return connProperties.setProperty(name, value);
+    }
+
+    /**
+     * Removes JDBC Connection Properties.
+     *
+     * @see #setConnectionProperty(String, String)
+     */
+    public Object removeConnectionProperty(String name) {
+        return connProperties.remove(name);
+    }
+
+    /**
+     * @see #setConnectionProperty(String, String)
+     *
+     * Beware that this property list will normally contain the password.
+     * It is under consideration whether the list should be cloned and
+     * returned with the password obscured or removed.
+     */
+    public Properties getConnectionProperties() {
+        return connProperties;
+    }
+
+    /**
+     * Portability wrapper.
+     * Many app servers call the URL setting "database".
+     */
+    public void setDatabase(String url) {
+        setUrl(url);
+    }
+
+    /**
+     * Portability wrapper.
+     * Many app servers call the URL setting "database".
+     */
+    public String getDatabase() {
+        return getUrl();
+    }
+
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * Retrieves the QueryObjectGenerator for the given JDBC driver.  If the
+     * JDBC driver does not provide its own QueryObjectGenerator, NULL is
+     * returned.
+     * @return The QueryObjectGenerator for this JDBC Driver or NULL if the driver does not provide its own
+     * implementation
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+//#ifdef JAVA6BETA
+/*
+    public QueryObjectGenerator getQueryObjectGenerator() throws SQLException {
+        return null;
+    }
+*/
+
+//#endif JAVA6BETA
+    // ------------------------ internal implementation ------------------------
+    private PooledConnection createPooledConnection(JDBCConnection connection)
+    throws SQLException {
+
+        LifeTimeConnectionWrapper connectionWrapper =
+            new LifeTimeConnectionWrapper(connection, this.connectionDefaults);
+        JDBCPooledConnection pooledConnection =
+            new JDBCPooledConnection(connectionWrapper);
+
+        connectionWrapper.setPooledConnection(pooledConnection);
+
+        return pooledConnection;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/JDBCPooledConnection.java b/src/org/hsqldb/jdbc/pool/JDBCPooledConnection.java
new file mode 100644
index 0000000..733227a
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/JDBCPooledConnection.java
@@ -0,0 +1,86 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import javax.sql.ConnectionEventListener;
+import javax.sql.PooledConnection;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+//#ifdef JAVA6
+import javax.sql.StatementEventListener;
+
+//#endif JAVA6
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+
+/**
+ * @author Jakob Jenkov
+ */
+public class JDBCPooledConnection implements PooledConnection {
+
+    private LifeTimeConnectionWrapper connectionWrapper = null;
+
+    public JDBCPooledConnection(LifeTimeConnectionWrapper connectionWrapper) {
+        this.connectionWrapper = connectionWrapper;
+    }
+
+    public void close() throws SQLException {
+
+        connectionWrapper.closePhysically();
+
+        this.connectionWrapper = null;
+    }
+
+    public Connection getConnection() throws SQLException {
+        return this.connectionWrapper;
+    }
+
+    public void addConnectionEventListener(ConnectionEventListener listener) {
+        this.connectionWrapper.addConnectionEventListener(listener);
+    }
+
+    public void removeConnectionEventListener(
+            ConnectionEventListener listener) {
+        this.connectionWrapper.removeConnectionEventListener(listener);
+    }
+
+/** @todo - implement methods */
+
+//#ifdef JAVA6
+    public void addStatementEventListener(StatementEventListener listener) {}
+
+    public void removeStatementEventListener(
+            StatementEventListener listener) {}
+
+//#endif JAVA6
+}
diff --git a/src/org/hsqldb/jdbc/pool/JDBCXAConnection.java b/src/org/hsqldb/jdbc/pool/JDBCXAConnection.java
new file mode 100644
index 0000000..5f31fe4
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/JDBCXAConnection.java
@@ -0,0 +1,68 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import javax.sql.XAConnection;
+
+import java.sql.SQLException;
+
+import javax.transaction.xa.XAResource;
+
+// @(#)$Id: JDBCXAConnection.java 3481 2010-02-26 18:05:06Z fredt $
+
+/**
+ * HSQLDB Connection objects for use by a global transaction service manager.
+ *
+ * Other than the xaResource, this class deals with Connection Wrappers
+ * not the real thing, but these correspond 1:1 with physical
+ * JDBCConnections.
+ *
+ * @since HSQLDB v. 1.9.0
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ * @see javax.sql.XAConnection
+ */
+public class JDBCXAConnection extends JDBCPooledConnection implements XAConnection {
+
+    JDBCXAResource xaResource;
+
+    public JDBCXAConnection(JDBCXAConnectionWrapper xaConnectionWrapper,
+                            JDBCXAResource xaResource) {
+
+        super(xaConnectionWrapper);
+
+        this.xaResource = xaResource;
+    }
+
+    public XAResource getXAResource() throws SQLException {
+        return xaResource;
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/JDBCXAConnectionWrapper.java b/src/org/hsqldb/jdbc/pool/JDBCXAConnectionWrapper.java
new file mode 100644
index 0000000..c6bb937
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/JDBCXAConnectionWrapper.java
@@ -0,0 +1,182 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import org.hsqldb.jdbc.JDBCConnection;
+
+import java.sql.SQLException;
+import java.sql.Savepoint;
+
+// @(#)$Id: JDBCXAConnectionWrapper.java 3481 2010-02-26 18:05:06Z fredt $
+
+/**
+ * This is a wrapper class for JDBCConnection objects (not XAConnection
+ * object).
+ * Purpose of this class is to intercept and handle XA-related operations
+ * according to chapter 12 of the JDBC 3.0 specification, by returning this
+ * wrapped JDBCConnection to end-users.
+ * Global transaction services and XAResources will not use this wrapper.
+ * It also supports pooling, by virtue of the parent class,
+ * LifeTimeConnectionWrapper.
+ * <P>
+ * This class name would be very precise (the class being a wrapper for
+ * XA-capable JDBC Connections), except that a "XAConnection" is an entirely
+ * different thing from a JDBC java.sql.Connection.
+ * I can think of no way to eliminate the ambiguity without using an
+ * 80-character class name.
+ * Best I think I can do is to clearly state here that
+ * <b>This is a wrapper for XA-capable java.sql.Connections, not for
+ *    javax.sql.XAConnection.</b>
+ *
+ * @since HSQLDB v. 1.9.0
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ * @see org.hsqldb.jdbc.JDBCConnection
+ * @see org.hsqldb.jdbc.pool.LifeTimeConnectionWrapper
+ */
+public class JDBCXAConnectionWrapper extends LifeTimeConnectionWrapper {
+
+    /*
+     * A critical question:  One responsibility of this
+     * class is to intercept invocations of commit(), rollback(),
+     * savePoint methods, etc.  But, what about if user issues the
+     * corresponding SQL commands?  What is the point to intercepting
+     * Connection.commit() here if end-users can execute the SQL command
+     * "COMMIT" and bypass interception?
+     * Similarly, what about DDL commands that cause an explicit commit?
+     *                                                - blaine
+     */
+    private JDBCXAResource xaResource;
+
+    public JDBCXAConnectionWrapper(
+            JDBCConnection connection, JDBCXAResource xaResource,
+            ConnectionDefaults connectionDefaults) throws SQLException {
+
+        /* Could pass in the creating XAConnection, which has methods to
+         * get the connection and the xaResource, but this way cuts down
+         * on the inter-dependencies a bit. */
+        super(connection, connectionDefaults);
+
+        this.xaResource = xaResource;
+    }
+
+    /**
+     * Throws a SQLException if within a Global transaction.
+     *
+     * @throws SQLException if within a Global transaction.
+     */
+    private void validateNotWithinTransaction() throws SQLException {
+
+        if (xaResource.withinGlobalTransaction()) {
+            throw new SQLException(
+                "Method prohibited within a global transaction");
+        }
+    }
+
+    /**
+     * Interceptor method, because this method is prohibited within
+     * any global transaction.
+     * See section 1.2.4 of the JDBC 3.0 spec.
+     */
+    public void setAutoCommit(boolean autoCommit) throws SQLException {
+        validateNotWithinTransaction();
+        super.setAutoCommit(autoCommit);
+    }
+
+    /**
+     * Interceptor method, because this method is prohibited within
+     * any global transaction.
+     * See section 1.2.4 of the JDBC 3.0 spec.
+     */
+    public void commit() throws SQLException {
+        validateNotWithinTransaction();
+        super.commit();
+    }
+
+    /**
+     * Interceptor method, because this method is prohibited within
+     * any global transaction.
+     * See section 1.2.4 of the JDBC 3.0 spec.
+     */
+    public void rollback() throws SQLException {
+        validateNotWithinTransaction();
+        super.rollback();
+    }
+
+    /**
+     * Interceptor method, because this method is prohibited within
+     * any global transaction.
+     * See section 1.2.4 of the JDBC 3.0 spec.
+     */
+    public void rollback(Savepoint savepoint) throws SQLException {
+        validateNotWithinTransaction();
+        super.rollback(savepoint);
+    }
+
+    /**
+     * Interceptor method, because this method is prohibited within
+     * any global transaction.
+     * See section 1.2.4 of the JDBC 3.0 spec.
+     */
+    public Savepoint setSavepoint() throws SQLException {
+
+        validateNotWithinTransaction();
+
+        return super.setSavepoint();
+    }
+
+    /**
+     * Interceptor method, because this method is prohibited within
+     * any global transaction.
+     * See section 1.2.4 of the JDBC 3.0 spec.
+     */
+    public Savepoint setSavepoint(String name) throws SQLException {
+
+        validateNotWithinTransaction();
+
+        return super.setSavepoint(name);
+    }
+
+    /**
+     * Interceptor method, because there may be XA implications to
+     * calling the method within a global transaction.
+     * See section 1.2.4 of the JDBC 3.0 spec.
+     */
+    public void setTransactionIsolation(int level) throws SQLException {
+
+        /* Goal at this time is to get a working XA DataSource.
+         * After we have multiple transaction levels working, we can
+         * consider how we want to handle attempts to change the level
+         * within a global transaction. */
+        validateNotWithinTransaction();
+        super.setTransactionIsolation(level);
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/JDBCXADataSource.java b/src/org/hsqldb/jdbc/pool/JDBCXADataSource.java
new file mode 100644
index 0000000..1c7ca78
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/JDBCXADataSource.java
@@ -0,0 +1,194 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import javax.sql.XADataSource;
+
+import java.sql.SQLException;
+
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.Iterator;
+
+import javax.transaction.xa.Xid;
+import javax.sql.PooledConnection;
+
+import org.hsqldb.jdbc.JDBCConnection;
+
+import java.sql.DriverManager;
+
+import javax.sql.XAConnection;
+
+// @(#)$Id: JDBCXADataSource.java 3495 2010-03-06 14:20:44Z fredt $
+
+/**
+ * Connection factory for JDBCXAConnections.
+ * For use by XA data source factories, not by end users.
+ *
+ * @since HSQLDB v. 1.9.0
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ * @see javax.sql.XADataSource
+ * @see org.hsqldb.jdbc.pool.JDBCXAConnection
+ */
+public class JDBCXADataSource extends JDBCConnectionPoolDataSource implements XADataSource {
+
+    /** @todo:  Break off code used here and in JDBCConnectionPoolDataSource
+     *        into an abstract class, and have these classes extend the
+     *        abstract class.  This class should NOT extend
+     *        JDBCConnectionPoolDataSource (notice the masked
+     *        pool-specific methods below).
+     */
+    private HashMap resources = new HashMap();
+
+    public void addResource(Xid xid, JDBCXAResource xaResource) {
+        resources.put(xid, xaResource);
+    }
+
+    public JDBCXAResource removeResource(Xid xid) {
+        return (JDBCXAResource) resources.remove(xid);
+    }
+
+    /**
+     * Return the list of transactions currently <I>in prepared or
+     * heuristically completed states</I>.
+     * Need to find out what non-prepared states they are considering
+     * <I>heuristically completed</I>.
+     *
+     * @see javax.transaction.xa.XAResource#recover(int)
+     */
+    Xid[] getPreparedXids() {
+
+        Iterator it = resources.keySet().iterator();
+        Xid      curXid;
+        HashSet  preparedSet = new HashSet();
+
+        while (it.hasNext()) {
+            curXid = (Xid) it.next();
+
+            if (((JDBCXAResource) resources.get(curXid)).state
+                    == JDBCXAResource.XA_STATE_PREPARED) {
+                preparedSet.add(curXid);
+            }
+        }
+
+        return (Xid[]) preparedSet.toArray(new Xid[0]);
+    }
+
+    /**
+     * This is needed so that XAResource.commit() and
+     * XAResource.rollback() may be applied to the right Connection
+     * (which is not necessarily that associated with that XAResource
+     * object).
+     *
+     * @see javax.transaction.xa.XAResource#commit(Xid, boolean)
+     * @see javax.transaction.xa.XAResource#rollback(Xid)
+     */
+    JDBCXAResource getResource(Xid xid) {
+        return (JDBCXAResource) resources.get(xid);
+    }
+
+    /**
+     * Get new PHYSICAL connection, to be managed by a connection manager.
+     */
+    public XAConnection getXAConnection() throws SQLException {
+
+        // Comment out before public release:
+/*
+        System.err.print("Executing " + getClass().getName()
+                         + ".getXAConnection()...");
+*/
+        try {
+            Class.forName(driver).newInstance();
+        } catch (ClassNotFoundException e) {
+            throw new SQLException("Error opening connection: "
+                                   + e.getMessage());
+        } catch (IllegalAccessException e) {
+            throw new SQLException("Error opening connection: "
+                                   + e.getMessage());
+        } catch (InstantiationException e) {
+            throw new SQLException("Error opening connection: "
+                                   + e.getMessage());
+        }
+
+        JDBCConnection connection =
+            (JDBCConnection) DriverManager.getConnection(url, connProperties);
+
+        // Comment out before public release:
+/*
+        System.err.print("New phys:  " + connection);
+*/
+        JDBCXAResource xaResource = new JDBCXAResource(connection, this);
+        JDBCXAConnectionWrapper xaWrapper =
+            new JDBCXAConnectionWrapper(connection, xaResource,
+                                        connectionDefaults);
+        JDBCXAConnection xaConnection = new JDBCXAConnection(xaWrapper,
+            xaResource);
+
+        xaWrapper.setPooledConnection(xaConnection);
+
+        return xaConnection;
+    }
+
+    /**
+     * Gets a new physical connection after validating the given username
+     * and password.
+     *
+     * @param user String which must match the 'user' configured for this
+     *             JDBCXADataSource.
+     * @param password  String which must match the 'password' configured
+     *                  for this JDBCXADataSource.
+     *
+     * @see #getXAConnection()
+     */
+    public XAConnection getXAConnection(String user,
+                                        String password) throws SQLException {
+
+        validateSpecifiedUserAndPassword(user, password);
+
+        return getXAConnection();
+    }
+
+    public PooledConnection getPooledConnection() throws SQLException {
+
+        throw new SQLException(
+            "Use the getXAConnections to get XA Connections.\n"
+            + "Use the class JDBCConnectionPoolDataSource for non-XA data sources.");
+    }
+
+    public PooledConnection getPooledConnection(String user,
+            String password) throws SQLException {
+
+        throw new SQLException(
+            "Use the getXAConnections to get XA Connections.\n"
+            + "Use the class JDBCConnectionPoolDataSource for non-XA data sources.");
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/JDBCXAResource.java b/src/org/hsqldb/jdbc/pool/JDBCXAResource.java
new file mode 100644
index 0000000..2d00f43
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/JDBCXAResource.java
@@ -0,0 +1,453 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.Xid;
+
+// These require a global transaction API:
+//import javax.transaction.HeuristicMixedException;
+//import javax.transaction.HeuristicCommitException;
+//import javax.transaction.HeuristicRollbackException;
+import org.hsqldb.jdbc.JDBCConnection;
+
+import java.sql.SQLException;
+
+import org.hsqldb.SessionInterface;
+import org.hsqldb.HsqlException;
+
+// @(#)$Id: JDBCXAResource.java 3495 2010-03-06 14:20:44Z fredt $
+
+/**
+ * Used by a global transaction service to control HSQLDB transactions.
+ * Not for use by end-users.
+ * End manage global transactions using transaction APIs such as JTA.
+ * <P>
+ * According to section 12.3 of the JDBC 3.0 spec, there is a
+ * 1:1 correspondence between XAConnection and XAResource, and
+ * <I>A given XAConnection object may be associated with at most one
+ * transaction at a time</I>.
+ * Therefore, there may be at any time at most one transaction
+ * managed by a XAResource object.
+ * One implication is, the XAResource can track the current transaction
+ * state with a scaler.
+ * Another implication is, the Xids for most of the XAResource interface
+ * methods just introduce unnecessary complexity and an unnecessary point
+ * of failure-- there can be only one transaction for this object, so
+ * why track another identifier for it.
+ * My strategy is to just "validate" that the Xid does not change
+ * within a transaction.
+ * Exceptions to this are the commit and rollback methods, which the
+ * JDBC spec says can operate against any XAResource instance from
+ * the same XADataSource.
+ * N.b. The JDBC Spec does not state whether the prepare and forget
+ * methods are XAResource-specific or XADataSource-specific.
+ *
+ * @since HSQLDB v. 1.9.0
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ * @see javax.transaction.xa.XAResource
+ */
+public class JDBCXAResource implements XAResource {
+
+    /**
+     * @todo:
+     * Make thread safe.
+     * Figure out how to ensure that orphaned transactions to do not make
+     * a memory leak in JDBCXADataSource.resources.  I.e.,
+     * JDBCXADataSource.removeResource() must be called even for all
+     * transactions, even aborted ones.  Maybe tx managers are
+     * already obligated to call one of commit/forget/rollback for
+     * even transactions for which they have called start???... TEST THIS.
+     * (They may only need to commit/forget/rollback if prepare has been
+     * called?).
+     * The answer may be to implement Timeouts.
+     */
+    private JDBCConnection   connection;
+    private boolean          originalAutoCommitMode;
+    static int               XA_STATE_INITIAL  = 0;
+    static int               XA_STATE_STARTED  = 1;
+    static int               XA_STATE_ENDED    = 2;
+    static int               XA_STATE_PREPARED = 3;
+    static int               XA_STATE_DISPOSED = 4;
+    int                      state             = XA_STATE_INITIAL;
+    private JDBCXADataSource xaDataSource;
+    Xid                      xid = null;
+
+    public boolean withinGlobalTransaction() {
+        return state == XA_STATE_STARTED;
+    }
+
+    /**
+     * @throws XAException if the given Xid is the not the Xid of the
+     *                     current transaction for this XAResource object.
+     */
+    private void validateXid(Xid xid) throws XAException {
+
+        if (xid == null) {
+            throw new XAException("Null Xid");
+        }
+
+        if (this.xid == null) {
+            throw new XAException(
+                "There is no live transaction for this XAResource");
+        }
+
+        if (!xid.equals(this.xid)) {
+            throw new XAException(
+                "Given Xid is not that associated with this XAResource object");
+        }
+    }
+
+    /**
+     * @param connection A non-wrapped JDBCConnection which we need in
+     *        order to do real (non-wrapped) commits, rollbacks, etc.
+     *        This is not for the end user.  We need the real thing.
+     */
+    public JDBCXAResource(JDBCConnection connection,
+                          JDBCXADataSource xaDataSource) {
+
+        // We're getting a real Connection here and not a wrapper.
+        this.connection   = connection;
+        this.xaDataSource = xaDataSource;
+    }
+
+    JDBCXADataSource getXADataSource() {
+        return xaDataSource;
+    }
+
+    /**
+     * Per the JDBC 3.0 spec, this commits the transaction for the
+     * specified Xid, not necessarily for the transaction associated
+     * with this XAResource object.
+     */
+    public void commit(Xid xid, boolean onePhase) throws XAException {
+
+        // Comment out following debug statement before public release:
+/*
+        System.err.println("Performing a " + (onePhase ? "1-phase"
+                                                       : "2-phase") + " commit on "
+                                                       + xid);
+*/
+        JDBCXAResource resource = xaDataSource.getResource(xid);
+
+        if (resource == null) {
+            throw new XAException("The XADataSource has no such Xid:  " + xid);
+        }
+
+        resource.commitThis(onePhase);
+    }
+
+    /**
+     * This commits the connection associated with <i>this</i> XAResource.
+     *
+     * @throws javax.transaction.xa.XAException generically, since the more
+     * specific exceptions require a JTA API to compile.
+     */
+    /*
+    * @throws javax.transaction.HeuristicRollbackException
+    *         if work was rolled back.
+    *         since these specific exceptions require a JTA API.
+    * @throws javax.transaction.HeuristicMixedException
+    *         if some work was committed and some work was rolled back
+    */
+    public void commitThis(boolean onePhase) throws XAException {
+
+        if (onePhase && state == XA_STATE_PREPARED) {
+            throw new XAException(
+                "Transaction is in a 2-phase state when 1-phase is requested");
+        }
+
+        if ((!onePhase) && state != XA_STATE_PREPARED) {
+            throw new XAException("Attempt to do a 2-phase commit when "
+                                  + "transaction is not prepared");
+        }
+
+        //if (!onePhase) {
+        //  throw new XAException(
+        //   "Sorry.  HSQLDB has not implemented 2-phase commits yet");
+        //}
+        try {
+
+            /**
+             * @todo:  Determine if work was committed, rolled back, or both,
+             * and return appropriate Heuristic*Exception.
+             * connection.commit();
+             *  Commits the real, physical conn.
+             */
+            connection.commit();
+        } catch (SQLException se) {
+            throw new XAException(se.getMessage());
+        }
+
+        dispose();
+    }
+
+    private void dispose() {
+
+        state = XA_STATE_DISPOSED;
+
+        xaDataSource.removeResource(xid);
+
+        xid = null;
+    }
+
+    public void end(Xid xid, int flags) throws XAException {
+
+        validateXid(xid);
+
+        if (state != XA_STATE_STARTED) {
+            throw new XAException("Invalid XAResource state");
+        }
+
+        /** @todo - probably all flags can be ignored */
+        if (flags == XAResource.TMSUCCESS) {
+
+        }
+
+        try {
+            connection.setAutoCommit(originalAutoCommitMode);    // real/phys.
+        } catch (SQLException se) {
+            throw new XAException(se.getMessage());
+        }
+
+        state = XA_STATE_ENDED;
+    }
+
+    /**
+     * The XAResource API spec indicates implies that this is only for
+     * 2-phase transactions.
+     * I guess that one-phase transactions need to call rollback() to abort.
+     *
+     * I think we want this JDBCXAResource instance to be garbage-collectable
+     * after (a) this method is called, and (b) the tx manager releases its
+     * handle to it.
+     *
+     * @see javax.transaction.xa.XAResource#forget(Xid)
+     */
+    public void forget(Xid xid) throws XAException {
+
+        /**
+         * Should this method not attempt to clean up the aborted
+         * transaction by rolling back or something?  Maybe the
+         * tx manager will already have called rollback() if
+         * it were necessasry?
+         */
+        validateXid(xid);
+
+        if (state != XA_STATE_PREPARED) {
+            throw new XAException(
+                "Attempted to forget a XAResource that "
+                + "is not in a heuristically completed state");
+        }
+
+        dispose();
+
+        state = XA_STATE_INITIAL;
+    }
+
+    /** @todo:  Implement */
+    public int getTransactionTimeout() throws XAException {
+        throw new XAException("Transaction timeouts not implemented yet");
+    }
+
+    /**
+     * Stub.  See implementation comment in the method for why this is
+     * not implemented yet.
+     *
+     * @return false.
+     */
+    public boolean isSameRM(XAResource xares) throws XAException {
+
+        if (!(xares instanceof JDBCXAResource)) {
+            return false;
+        }
+
+        return xaDataSource == ((JDBCXAResource) xares).getXADataSource();
+    }
+
+    /**
+     * Vote on whether to commit the global transaction.
+     * We assume Xid may be different from this, as in commit() method.
+     * @throws XAException to vote negative.
+     * @return commitType of XA_RDONLY or XA_OK.  (Actually only XA_OK now).
+     */
+    public int prepare(Xid xid) throws XAException {
+
+        JDBCXAResource resource = xaDataSource.getResource(xid);
+
+        if (resource == null) {
+            throw new XAException("The XADataSource has no such Xid:  " + xid);
+        }
+
+        return resource.prepareThis();
+    }
+
+    public int prepareThis() throws XAException {
+
+        /**
+         * @todo:  This is where the real 2-phase work should be done to
+         * determine if a commit done here would succeed or not.
+         */
+
+        /**
+         * @todo:  May improve performance to return XA_RDONLY whenever
+         * possible, but I don't know.
+         * Could determine this by checking if DB instance is in RO mode,
+         * or perhaps (with much difficulty) to determine if there have
+         * been any modifications performed.
+         */
+        if (state != XA_STATE_ENDED) {
+            throw new XAException("Invalid XAResource state");
+        }
+
+        try {
+            ((SessionInterface) connection).prepareCommit();
+        } catch (HsqlException e) {
+            state = XA_STATE_PREPARED;
+
+            throw new XAException(e.getMessage());
+        }
+
+        // throw new XAException(
+        // "Sorry.  HSQLDB has not implemented 2-phase commits yet");
+        state = XA_STATE_PREPARED;
+
+        return XA_OK;    // As noted above, should check non-committed work.
+    }
+
+    /**
+     * Obtain a list of Xids of the current <i>resource manager</i>
+     * for XAResources currently in the 'prepared' * state.
+     *
+     * According to the JDBC 3.0 spec, the Xids of a specific resource
+     * manager are those of the same XADataSource.
+     */
+    public Xid[] recover(int flag) throws XAException {
+        return xaDataSource.getPreparedXids();
+    }
+
+    /**
+     * Per the JDBC 3.0 spec, this rolls back the transaction for the
+     * specified Xid, not necessarily for the transaction associated
+     * with this XAResource object.
+     */
+    public void rollback(Xid xid) throws XAException {
+
+        JDBCXAResource resource = xaDataSource.getResource(xid);
+
+        if (resource == null) {
+            throw new XAException(
+                "The XADataSource has no such Xid in prepared state:  " + xid);
+        }
+
+        resource.rollbackThis();
+    }
+
+    /**
+     * This rolls back the connection associated with <i>this</i> XAResource.
+     *
+     * @throws javax.transaction.xa.XAException generically, since the more
+     * specific exceptions require a JTA API to compile.
+     */
+    /* @throws javax.transaction.HeuristicCommitException
+     *         if work was committed.
+     * @throws javax.transaction.HeuristicMixedException
+     *         if some work was committed and some work was rolled back
+     */
+    public void rollbackThis() throws XAException {
+
+        if (state != XA_STATE_PREPARED) {
+            throw new XAException("Invalid XAResource state");
+        }
+
+        try {
+
+            /**
+             * @todo:  Determine if work was committed, rolled back, or both,
+             * and return appropriate Heuristic Exception.
+             */
+            connection.rollback();    // real/phys.
+        } catch (SQLException se) {
+            throw new XAException(se.getMessage());
+        }
+
+        dispose();
+    }
+
+    /**
+     * @todo:  Implement
+     */
+    public boolean setTransactionTimeout(int seconds) throws XAException {
+        throw new XAException("Transaction timeouts not implemented yet");
+    }
+
+    public void start(Xid xid, int flags) throws XAException {
+
+        // Comment out following debug statement before public release:
+/*
+        System.err.println("STARTING NEW Xid: " + xid);
+*/
+        if (state != XA_STATE_INITIAL && state != XA_STATE_DISPOSED) {
+            throw new XAException("Invalid XAResource state");
+        }
+
+        if (xaDataSource == null) {
+            throw new XAException(
+                "JDBCXAResource has not been associated with a XADataSource");
+        }
+
+        if (xid == null) {
+
+            // This block asserts that all JDBCXAResources with state
+            // >= XA_STATE_STARTED have a non-null xid.
+            throw new XAException("Null Xid");
+        }
+
+        try {
+            originalAutoCommitMode = connection.getAutoCommit();    // real/phys.
+
+            connection.setAutoCommit(false);                        // real/phys.
+        } catch (SQLException se) {
+            throw new XAException(se.getMessage());
+        }
+
+        this.xid = xid;
+        state    = XA_STATE_STARTED;
+
+        xaDataSource.addResource(this.xid, this);
+
+        // N.b.  The DataSource does not have this XAResource in its list
+        // until right here.  We can't tell DataSource before our start()
+        // method, because we don't know our Xid before now.
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/LifeTimeConnectionWrapper.java b/src/org/hsqldb/jdbc/pool/LifeTimeConnectionWrapper.java
new file mode 100644
index 0000000..52aac18
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/LifeTimeConnectionWrapper.java
@@ -0,0 +1,196 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import org.hsqldb.jdbc.JDBCConnection;
+
+import javax.sql.ConnectionEvent;
+import javax.sql.ConnectionEventListener;
+import javax.sql.PooledConnection;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+
+/**
+ * A simple wrapper around a regular <code>java.sql.Connection</code>.
+ * Redirects all calls to the encapsulated connection except <code>close()</code>.
+ * Calling <code>close()</code> on this wrapper marks the wrappers as closed,
+ * and puts the encapsulated connection back in the queue of idle connections.
+ *
+ * <br>
+ * This version doesn't wrap Statement, PreparedStatement, CallableStatement
+ * and ResultSet instances. In order to behave 100% correctly it probably should.
+ * That way this wrapper can close all of these instances when the wrapper is closed,
+ * before the connection is given back to the pool. Normally the wrapped connection
+ * would do this, but since it's never closed... someone has to do it.
+ * <br>
+ * The connection.reset() call is to reset the JDBC Connection,
+ * the Statement and ResultSet objects. It also resets the session settings
+ * to its initial state.
+ *
+ *
+ * @author Jakob Jenkov
+ */
+public class LifeTimeConnectionWrapper extends BaseConnectionWrapper {
+
+    protected JDBCConnection     connection          = null;
+    protected PooledConnection   pooledConnection    = null;
+    protected Set                connectionListeners = new HashSet();
+    protected ConnectionDefaults connectionDefaults  = null;
+
+    public LifeTimeConnectionWrapper(
+            JDBCConnection connection,
+            ConnectionDefaults connectionDefaults) throws SQLException {
+
+        this.connection = connection;
+
+        if (connectionDefaults != null) {
+            this.connectionDefaults = connectionDefaults;
+
+            this.connectionDefaults.setDefaults(connection);
+        } else {
+            this.connectionDefaults = new ConnectionDefaults(connection);
+        }
+    }
+
+    public LifeTimeConnectionWrapper(
+            JDBCConnection connection) throws SQLException {
+        this(connection, null);
+    }
+
+    public void setPooledConnection(JDBCPooledConnection pooledConnection) {
+        this.pooledConnection = pooledConnection;
+    }
+
+    public void addConnectionEventListener(ConnectionEventListener listener) {
+        connectionListeners.add(listener);
+    }
+
+    public void removeConnectionEventListener(
+            ConnectionEventListener listener) {
+        connectionListeners.remove(listener);
+    }
+
+    protected void finalize() throws Throwable {
+        closePhysically();
+    }
+
+    protected Connection getConnection() {
+        return this.connection;
+    }
+
+    /**
+     * Rolls the connection back, resets the connection back to defaults, clears warnings,
+     * resets the connection on the server side, and returns the connection to the pool.
+     * @throws SQLException
+     */
+    public void close() throws SQLException {
+
+        validate();
+
+        try {
+            this.connection.rollback();
+            this.connection.clearWarnings();
+            this.connection.reset();
+            this.connectionDefaults.setDefaults(this.connection);
+            fireCloseEvent();
+        } catch (SQLException e) {
+            fireSqlExceptionEvent(e);
+
+            throw e;
+        }
+    }
+
+    /**
+     * Closes the connection physically. The pool is not notified of this.
+     * @throws SQLException If something goes wrong during the closing of the wrapped JDBCConnection.
+     */
+    public void closePhysically() throws SQLException {
+
+        SQLException exception = null;
+
+        if (!isClosed && this.connection != null
+                && !this.connection.isClosed()) {
+            try {
+                this.connection.close();
+            } catch (SQLException e) {
+
+                //catch and hold so that the rest of the finalizer is run too. Throw at the end if present.
+                exception = e;
+            }
+        }
+        this.isClosed           = true;
+        this.pooledConnection   = null;
+        this.connection         = null;
+        this.connectionDefaults = null;
+
+        this.connectionListeners.clear();
+
+        this.connectionListeners = null;
+
+        if (exception != null) {
+            throw exception;
+        }
+    }
+
+    protected void fireSqlExceptionEvent(SQLException e) {
+
+        ConnectionEvent event = new ConnectionEvent(this.pooledConnection, e);
+
+        for (Iterator iterator = connectionListeners.iterator();
+                iterator.hasNext(); ) {
+            ConnectionEventListener connectionEventListener =
+                (ConnectionEventListener) iterator.next();
+
+            connectionEventListener.connectionErrorOccurred(event);
+        }
+    }
+
+    protected void fireCloseEvent() {
+
+        ConnectionEvent connectionEvent =
+            new ConnectionEvent(this.pooledConnection);
+
+        for (Iterator iterator = connectionListeners.iterator();
+                iterator.hasNext(); ) {
+            ConnectionEventListener connectionListener =
+                (ConnectionEventListener) iterator.next();
+
+            connectionListener.connectionClosed(connectionEvent);
+        }
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/ManagedPoolDataSource.java b/src/org/hsqldb/jdbc/pool/ManagedPoolDataSource.java
new file mode 100644
index 0000000..8376839
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/ManagedPoolDataSource.java
@@ -0,0 +1,1199 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.sql.ConnectionEvent;
+import javax.sql.ConnectionEventListener;
+import javax.sql.PooledConnection;
+
+import org.hsqldb.jdbc.Util;
+
+/* $Id: ManagedPoolDataSource.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+// boucherb@users 20051207 - patch 1.8.0.x initial JDBC 4.0 support work
+// boucherb@users 20060523 - patch 1.9.0 full synch up to Mustang Build 84
+// Revision 1.23  2006/07/12 12:45:54  boucherb
+// patch 1.9.0
+// - full synch up to Mustang b90
+
+/** @todo configurable: rollback() exceptions passed on to the client? */
+
+/**
+ * Connection pool manager.
+ *
+ * @author Jakob Jenkov
+ */
+public class ManagedPoolDataSource implements javax.sql.DataSource,
+        ConnectionEventListener {
+
+    /**
+     * The default connection count in the pool.
+     * Since HSQLDB has database level locking (only 1 thread in the database at a time) there is
+     * no reason to default to a large number of connections in the connection pool. All
+     * other threads will be waiting for the other connections to finish anyways. A large number
+     * of connections will only be a waste of resources in the HSQLDB server.
+     *
+     * I'm raising the default max size because
+     * (a) HSQLDB will have a multi-threaded core shortly.
+     * (b) The number of connections is not determined only by performance
+     * considerations, but also by transaction isolation requirements.
+     * Web apps often require a separate conn. app per HTTP Session or
+     * Request.  It is, indeed, the standard paradigm for J2EE web apps.
+     *                                                     - blaine
+     */
+    private static final int             DEFAULT_MAX_POOL_SIZE    = 8;
+    private boolean                      isPoolClosed             = false;
+    private int                          sessionTimeout           = 0;
+    private JDBCConnectionPoolDataSource connectionPoolDataSource = null;
+    private Set                          connectionsInUse = new HashSet();
+    private List                         connectionsInactive = new ArrayList();
+    private Map sessionConnectionWrappers = new HashMap();
+    private int                          maxPoolSize = DEFAULT_MAX_POOL_SIZE;
+    private ConnectionDefaults           connectionDefaults       = null;
+    private boolean                      initialized              = false;
+    private int                          initialSize              = 0;
+
+    // The doReset* settings say whether to automatically apply the
+    // relevant setting to physical Connections when they are (re)-established.
+    boolean doResetAutoCommit           = false;
+    boolean doResetReadOnly             = false;
+    boolean doResetTransactionIsolation = false;
+    boolean doResetCatalog              = false;
+
+    // The default values below will only be enforced if the user "checks"
+    // the values by using a getter().
+    // If user uses neither a getter nor a setter, no resetting or
+    // enforcement of these settings will be done.
+    boolean isAutoCommit         = true;
+    boolean isReadOnly           = false;
+    int     transactionIsolation = Connection.TRANSACTION_READ_COMMITTED;
+    String  catalog              = null;
+
+    /** Optional query to validate new Connections before returning them. */
+    private String validationQuery = null;
+
+    /**
+     * Base no-arg constructor.
+     * Useful for JavaBean repositories and IOC frameworks.
+     */
+    public ManagedPoolDataSource() {
+        this.connectionPoolDataSource = new JDBCConnectionPoolDataSource();
+    }
+
+    /**
+     * Base constructor that handles all parameters.
+     */
+    public ManagedPoolDataSource(
+            String url, String user, String password, int maxPoolSize,
+            ConnectionDefaults connectionDefaults) throws SQLException {
+
+        this.connectionPoolDataSource = new JDBCConnectionPoolDataSource(url,
+                user, password, connectionDefaults);
+        this.maxPoolSize = maxPoolSize;
+    }
+
+    /**
+     * Convience constructor wrapper.
+     *
+     * @see #ManagedPoolDataSource()
+     */
+    public ManagedPoolDataSource(String url, String user,
+                                 String password) throws SQLException {
+        this(url, user, password, DEFAULT_MAX_POOL_SIZE, null);
+    }
+
+    /**
+     * Convience constructor wrapper.
+     *
+     * @see #ManagedPoolDataSource()
+     */
+    public ManagedPoolDataSource(
+            String url, String user, String password,
+            ConnectionDefaults connectionDefaults) throws SQLException {
+        this(url, user, password, DEFAULT_MAX_POOL_SIZE, connectionDefaults);
+    }
+
+    /**
+     * Convience constructor wrapper.
+     *
+     * @see #ManagedPoolDataSource()
+     */
+    public ManagedPoolDataSource(String url, String user, String password,
+                                 int maxPoolSize) throws SQLException {
+        this(url, user, password, maxPoolSize, null);
+    }
+
+    public ConnectionDefaults getConnectionDefaults() {
+        return connectionDefaults;
+    }
+
+    public synchronized String getUrl() {
+        return this.connectionPoolDataSource.getUrl();
+    }
+
+    public synchronized void setUrl(String url) {
+        this.connectionPoolDataSource.setUrl(url);
+    }
+
+    public synchronized String getUser() {
+        return this.connectionPoolDataSource.getUser();
+    }
+
+    public synchronized void setUser(String user) {
+        this.connectionPoolDataSource.setUser(user);
+    }
+
+    public synchronized String getPassword() {
+        return this.connectionPoolDataSource.getPassword();
+    }
+
+    public synchronized void setPassword(String password) {
+        this.connectionPoolDataSource.setPassword(password);
+    }
+
+    public synchronized int getSessionTimeout() {
+        return sessionTimeout;
+    }
+
+    public synchronized void setSessionTimeout(int sessionTimeout) {
+        this.sessionTimeout = sessionTimeout;
+    }
+
+    public synchronized int getMaxPoolSize() {
+        return maxPoolSize;
+    }
+
+    public synchronized void setMaxPoolSize(int maxPoolSize) {
+        this.maxPoolSize = maxPoolSize;
+    }
+
+    /**
+     * @return seconds Time, in seconds.
+     * @see JDBCConnectionPoolDataSource#getLoginTimeout()
+     */
+    public synchronized int getLoginTimeout() throws SQLException {
+        return connectionPoolDataSource.getLoginTimeout();
+    }
+
+    /**
+     * @param seconds Time, in seconds.
+     * @see JDBCConnectionPoolDataSource#setLoginTimeout(int)
+     */
+    public synchronized void setLoginTimeout(int seconds) throws SQLException {
+        connectionPoolDataSource.setLoginTimeout(seconds);
+    }
+
+    /**
+     * @see JDBCConnectionPoolDataSource#getLogWriter()
+     */
+    public synchronized PrintWriter getLogWriter() throws SQLException {
+        return connectionPoolDataSource.getLogWriter();
+    }
+
+    /**
+     * @see JDBCConnectionPoolDataSource#setLogWriter(PrintWriter)
+     */
+    public synchronized void setLogWriter(
+            PrintWriter out) throws SQLException {
+        connectionPoolDataSource.setLogWriter(out);
+    }
+
+    /**
+     * Performs a getConnection() after validating the given username
+     * and password.
+     *
+     * @param user String which must match the 'user' configured for this
+     *             ManagedPoolDataSource.
+     * @param password  String which must match the 'password' configured
+     *                  for this ManagedPoolDataSource.
+     *
+     * @see #getConnection()
+     */
+    public Connection getConnection(String user,
+                                    String password) throws SQLException {
+
+        String managedPassword = getPassword();
+        String managedUser     = getUsername();
+
+        if (((user == null && managedUser != null)
+                || (user != null && managedUser == null)) || (user != null
+                   && !user.equals(managedUser)) || ((password == null
+                       && managedPassword != null) || (password != null
+                           && managedPassword == null)) || (password != null
+                               && !password.equals(managedPassword))) {
+            throw new SQLException(
+                "Connection pool manager user/password validation failed");
+        }
+
+        return getConnection();
+    }
+
+    /**
+     * This method will return a valid connection as fast as possible. Here is the sequence of events:
+     *
+     * <ol>
+     *  <li>First it will try to take a ready connection from the pool.</li>
+     *  <li>If the pool doesn't have any ready connections this method will check
+     *      if the pool has space for new connections. If yes, a new connection is created and inserted
+     *      into the pool.</li>
+     * <li>If the pool is already at maximum size this method will check for abandoned
+     *     connections among the connections given out earlier.
+     *     If any of the connections are abandoned it will be reclaimed, reset and
+     *     given out.</li>
+     * <li>If there are no abandoned connections this method waits until a connection becomes
+     *     available in the pool, or until the login time out time has passed (if login timeout set).</li>
+     * </ol>
+     *
+     * This sequence means that the pool will not grow till max size as long as there are available connections
+     * in the pool. Only when no connections are available will it spend time creating new connections.
+     * In addition it will not spend
+     * time reclaiming abandoned connections until it's absolutely necessary. Only when no new connections
+     * can be created. Ultimately it only blocks if there really are no available connections,
+     * none can be created and none can be reclaimed. Since the
+     * pool is passive this is the sequence of events that should give the highest performance possible
+     * for giving out connections from the pool.
+     *
+     * <br/><br/>
+     * Perhaps it is faster to reclaim a connection if possible than to create a new one. If so, it would be faster
+     * to reclaim existing connections before creating new ones. It may also preserve resources better.
+     * However, assuming that there will not often be abandoned connections, that programs most often
+     * remember to close them, on the average the reclaim check is only going to be "wasted overhead".
+     * It will only rarely result in a usable connection. In that perspective it should be faster
+     * to only do the reclaim check when no connections can be created.
+     *
+     * @throws SQLException
+     */
+    public Connection getConnection() throws SQLException {
+
+        PooledConnection pooledConnection = null;
+
+        synchronized (this) {
+            if (!initialized) {
+                if (initialSize > maxPoolSize) {
+                    throw new SQLException("Initial size of " + initialSize
+                            + " exceeds max. pool size of " + maxPoolSize);
+                }
+                logInfo("Pre-initializing " + initialSize
+                        + " physical connections");
+
+                for (int i = 0; i < initialSize; i++) {
+                    connectionsInactive.add(createNewConnection());
+                }
+                initialized = true;
+            }
+
+            long loginTimeoutExpiration = calculateLoginTimeoutExpiration();
+
+            //each waiting thread will spin around in this loop until either
+            //
+            // a) a connection becomes available
+            // b) the login timeout passes. Results in SQLException.
+            // c) the thread is interrupted while waiting for an available connection
+            // d) the connection pool is closed. Results in SQLException.
+            //
+            // the reason the threads spin in a loop is that they should always check all options
+            // (available + space for new  + abandoned) before waiting. In addition the threads will
+            // repeat the close check before spinning a second time. That way all threads waiting
+            // for a connection when the connection is closed will get an SQLException.
+            while (pooledConnection == null) {
+                if (this.isPoolClosed) {
+                    throw new SQLException(
+                        "The pool is closed. You cannot get anymore connections from it.");
+                }
+
+                // 1) Check if any connections available in the pool.
+                pooledConnection = dequeueFirstIfAny();
+
+                if (pooledConnection != null) {
+                    return wrapConnectionAndMarkAsInUse(pooledConnection);
+                }
+
+                // 2) Check if the pool has space for new connections and create one if it does.
+                if (poolHasSpaceForNewConnections()) {
+                    pooledConnection = createNewConnection();
+
+                    return wrapConnectionAndMarkAsInUse(pooledConnection);
+                }
+
+                // 3) Check if connection pool has session timeout. If yes,
+                // check if any connections has timed out. Return one if there are any.
+                if (this.sessionTimeout > 0) {
+                    reclaimAbandonedConnections();
+
+                    //check if any connections were closed during the time out check.
+                    pooledConnection = dequeueFirstIfAny();
+
+                    if (pooledConnection != null) {
+                        return wrapConnectionAndMarkAsInUse(pooledConnection);
+                    }
+                }
+
+                // 4) wait until a connection becomes available or the login timeout passes (if set).
+                doWait(loginTimeoutExpiration);
+            }
+
+            return wrapConnectionAndMarkAsInUse(pooledConnection);
+        }
+    }
+
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     *  Creates a concrete implementation of a Query interface using the JDBC drivers <code>QueryObjectGenerator</code>
+     *  implementation.
+     *  If the JDBC driver does not provide its own <code>QueryObjectGenerator</code>, the <code>QueryObjectGenerator</code>
+     *  provided with J2SE will be used.
+     * <p>
+     *  @param ifc The Query interface that will be created
+     *  @return A concrete implementation of a Query interface
+     *  @exception SQLException if a database access error occurs.
+     *  @since JDK 1.6, HSQLDB 1.8.x
+     */
+//#ifdef JAVA6BETA
+/*
+   public <T extends BaseQuery> T createQueryObject(Class<T> ifc) throws SQLException {
+        return QueryObjectFactory.createDefaultQueryObject(ifc, this);
+   }
+*/
+
+//#endif JAVA6BETA
+
+    /**
+     * Creates a concrete implementation of a Query interface using the JDBC drivers <code>QueryObjectGenerator</code>
+     * implementation.
+     * <p>
+     * If the JDBC driver does not provide its own <code>QueryObjectGenerator</code>, the <code>QueryObjectGenerator</code>
+     * provided with Java SE will be used.
+     * <p>
+     * This method is primarly for developers of Wrappers to JDBC implementations.
+     * Application developers should use <code>createQueryObject(Class&LT;T&GT; ifc).
+     * <p>
+     * @param ifc The Query interface that will be created
+     * @param ds The <code>DataSource</code> that will be used when invoking methods that access
+     * the data source. The QueryObjectGenerator implementation will use
+     * this <code>DataSource</code> without any unwrapping or modications
+     * to create connections to the data source.
+     *
+     * @return An concrete implementation of a Query interface
+     * @exception SQLException if a database access error occurs.
+     * @since 1.6
+     */
+//#ifdef JAVA6BETA
+/*
+    public <T extends BaseQuery> T createQueryObject(Class<T> ifc, javax.sql.DataSource ds) throws SQLException {
+        return QueryObjectFactory.createQueryObject(ifc, ds);
+    }
+*/
+
+//#endif JAVA6BETA
+
+    /**
+     * Retrieves the QueryObjectGenerator for the given JDBC driver.  If the
+     * JDBC driver does not provide its own QueryObjectGenerator, NULL is
+     * returned.
+     * @return The QueryObjectGenerator for this JDBC Driver or NULL if the driver does not provide its own
+     * implementation
+     * @exception SQLException if a database access error occurs
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+//#ifdef JAVA6BETA
+/*
+    public QueryObjectGenerator getQueryObjectGenerator() throws SQLException {
+        return null;
+    }
+*/
+
+//#endif JAVA6BETA
+
+    /**
+     * Returns an object that implements the given interface to allow access to non-standard methods,
+     * or standard methods not exposed by the proxy.
+     * The result may be either the object found to implement the interface or a proxy for that object.
+     * If the receiver implements the interface then that is the object. If the receiver is a wrapper
+     * and the wrapped object implements the interface then that is the object. Otherwise the object is
+     *  the result of calling <code>unwrap</code> recursively on the wrapped object. If the receiver is not a
+     * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
+     *
+     * @param iface A Class defining an interface that the result must implement.
+     * @return an object that implements the interface. May be a proxy for the actual implementing object.
+     * @throws java.sql.SQLException If no object found that implements the interface
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+//#ifdef JAVA6
+    public <T>T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {
+
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+
+        throw Util.invalidArgument("iface: " + iface);
+    }
+
+//#endif JAVA6
+
+    /**
+     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
+     * for an object that does. Returns false otherwise. If this implements the interface then return true,
+     * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
+     * object. If this does not implement the interface and is not a wrapper, return false.
+     * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
+     * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
+     * returns true then calling <code>unwrap</code> with the same argument should succeed.
+     *
+     * @param iface a Class defining an interface.
+     * @return true if this implements the interface or directly or indirectly wraps an object that does.
+     * @throws java.sql.SQLException  if an error occurs while determining whether this is a wrapper
+     * for an object with the given interface.
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+//#ifdef JAVA6
+    public boolean isWrapperFor(
+            java.lang.Class<?> iface) throws java.sql.SQLException {
+        return (iface != null && iface.isAssignableFrom(this.getClass()));
+    }
+
+//#endif JAVA6
+    // ------------------------ internal implementation ------------------------
+    private void doWait(long loginTimeoutExpiration) throws SQLException {
+
+        try {
+            if (loginTimeoutExpiration > 0) {
+                long timeToWait = loginTimeoutExpiration
+                                  - System.currentTimeMillis();
+
+                if (timeToWait > 0) {
+                    this.wait(timeToWait);
+                } else {
+                    throw new SQLException(
+                        "No connections available within the given login timeout: "
+                        + getLoginTimeout());
+                }
+            } else {
+                this.wait();
+            }
+        } catch (InterruptedException e) {
+            throw new SQLException(
+                "Thread was interrupted while waiting for available connection");
+        }
+    }
+
+    private PooledConnection createNewConnection() throws SQLException {
+
+        PooledConnection pooledConnection;
+
+        // I have changed "size() + 1" to "size()".  I don't know why
+        // we would want to report 1 more than the actual pool size,
+        // so I am assuming that this is a coding error.  (The size
+        // method does return the actual size of an array).  -blaine
+        logInfo("Connection created since no connections available and "
+                + "pool has space for more connections. Pool size: " + size());
+
+        pooledConnection = this.connectionPoolDataSource.getPooledConnection();
+
+        pooledConnection.addConnectionEventListener(this);
+
+        return pooledConnection;
+    }
+
+    private void reclaimAbandonedConnections() {
+
+        long     now                  = System.currentTimeMillis();
+        long     sessionTimeoutMillis = ((long) sessionTimeout) * 1000L;
+        Iterator iterator             = this.connectionsInUse.iterator();
+        List     abandonedConnections = new ArrayList();
+
+        while (iterator.hasNext()) {
+            PooledConnection connectionInUse =
+                (PooledConnection) iterator.next();
+            SessionConnectionWrapper sessionWrapper =
+                (SessionConnectionWrapper) this.sessionConnectionWrappers.get(
+                    connectionInUse);
+
+            if (isSessionTimedOut(now, sessionWrapper, sessionTimeoutMillis)) {
+                abandonedConnections.add(sessionWrapper);
+            }
+        }
+
+        //The timed out sessions are added to a list before being closed to avoid
+        //ConcurrentModificationException. When the session wrapper is closed the underlying
+        // connection will eventually call connectionClosed() on this class. connectionClosed()
+        // will in turn try to remove the pooled connection from the connectionsInUse set. So,
+        // if the sessionWrapper is closed while iterating the connectionsInUse it would result
+        // in a ConcurrentModificationException.
+        iterator = abandonedConnections.iterator();
+
+        while (iterator.hasNext()) {
+            SessionConnectionWrapper sessionWrapper =
+                (SessionConnectionWrapper) iterator.next();
+
+            closeSessionWrapper(
+                sessionWrapper,
+                "Error closing abandoned session connection wrapper.");
+        }
+
+        //if there are more than one abandoned connection then other waiting threads might
+        //now have a chance to get a connections. therefore we notify all waiting threads.
+        if (abandonedConnections.size() > 1) {
+            abandonedConnections.clear();
+            this.notifyAll();
+        }
+    }
+
+    /**
+     * Closes the session wrapper. The call to close() will in turn result in a call to this pools
+     * connectionClosed or connectionErrorOccurred method. These methods will remove the PooledConnection
+     * and SessionConnectionWrapper instances from the connectionsInUse and sessionConnectionWrappers collections,
+     * and do any necessary cleanup afterwards. That is why this method only calls sessionWrapper.close();
+     * @param sessionWrapper The session wrapper to close.
+     * @param logText The text to write to the log if the close fails.
+     */
+    private void closeSessionWrapper(SessionConnectionWrapper sessionWrapper,
+                                     String logText) {
+
+        try {
+            sessionWrapper.close();
+        } catch (SQLException e) {
+
+            //ignore exception. The connection will automatically be removed from the pool.
+            logInfo(logText, e);
+        }
+    }
+
+    private long calculateLoginTimeoutExpiration() throws SQLException {
+
+        long loginTimeoutExpiration = 0;
+
+        if (getLoginTimeout() > 0) {
+            loginTimeoutExpiration = 1000L * ((long) getLoginTimeout());
+        }
+
+        return loginTimeoutExpiration;
+    }
+
+    private void enqueue(PooledConnection connection) {
+        this.connectionsInactive.add(connection);
+        this.notifyAll();
+    }
+
+    /**
+     * Dequeues first available connection if any. If no available connections it returns null.
+     * @return The first available connection if any. Null if no connections are available.
+     */
+    private PooledConnection dequeueFirstIfAny() {
+
+        if (this.connectionsInactive.size() <= 0) {
+            return null;
+        }
+
+        return (PooledConnection) this.connectionsInactive.remove(0);
+    }
+
+    public synchronized int size() {
+        return this.connectionsInUse.size() + this.connectionsInactive.size();
+    }
+
+    private Connection wrapConnectionAndMarkAsInUse(
+            PooledConnection pooledConnection) throws SQLException {
+
+        pooledConnection = assureValidConnection(pooledConnection);
+
+        Connection conn = pooledConnection.getConnection();
+
+        if (doResetAutoCommit) {
+            conn.setAutoCommit(isAutoCommit);
+        }
+
+        if (doResetReadOnly) {
+            conn.setReadOnly(isReadOnly);
+        }
+
+        if (doResetTransactionIsolation) {
+            conn.setTransactionIsolation(transactionIsolation);
+            /* TESING ONLY!!
+            System.err.println("<<<<<<<<< ISO LVL => " + transactionIsolation
+            + " >>>>>>>>>>>>");
+            */
+        }
+
+        if (doResetCatalog) {
+            conn.setCatalog(catalog);
+            /* TESTING ONLY!
+            System.err.println("<<<<<<<<< CAT => " + catalog
+            + " >>>>>>>>>>>>");
+            */
+        }
+
+        if (validationQuery != null) {
+
+            // End-to-end test before return the Connection.
+            java.sql.ResultSet rs = null;
+
+            try {
+                rs = conn.createStatement().executeQuery(validationQuery);
+
+                if (!rs.next()) {
+                    throw new SQLException("0 rows returned");
+                }
+            } catch (SQLException se) {
+                closePhysically(pooledConnection,
+                                "Closing non-validating pooledConnection.");
+
+                throw new SQLException("Validation query failed: "
+                                       + se.getMessage());
+            } finally {
+                if (rs != null) {
+                    rs.close();
+                }
+            }
+        }
+        this.connectionsInUse.add(pooledConnection);
+
+        SessionConnectionWrapper sessionWrapper =
+            new SessionConnectionWrapper(pooledConnection.getConnection());
+
+        this.sessionConnectionWrappers.put(pooledConnection, sessionWrapper);
+
+        return sessionWrapper;
+    }
+
+    private PooledConnection assureValidConnection(
+            PooledConnection pooledConnection) throws SQLException {
+
+        if (isInvalid(pooledConnection)) {
+            closePhysically(pooledConnection,
+                            "closing invalid pooledConnection.");
+
+            return this.connectionPoolDataSource.getPooledConnection();
+        }
+
+        return pooledConnection;
+    }
+
+    private boolean isInvalid(PooledConnection pooledConnection) {
+
+        /** @todo: add  || pooledConnection.getConnection.isValid()   when JDBC 4.0 arrives. */
+        try {
+            return pooledConnection.getConnection().isClosed();
+        } catch (SQLException e) {
+            logInfo(
+                "Error calling pooledConnection.getConnection().isClosed(). Connection will be removed from pool.",
+                e);
+
+            return false;
+        }
+    }
+
+    private boolean isSessionTimedOut(long now,
+                                      SessionConnectionWrapper sessionWrapper,
+                                      long sessionTimeoutMillis) {
+        return now - sessionWrapper.getLatestActivityTime()
+               >= sessionTimeoutMillis;
+    }
+
+    /**
+     * Tells if a connection has space for new connections
+     * (fx. if a connection leaked from the pool - not properly returned),
+     * by comparing the total number of
+     * connections supposed to be in the pool with the number of connections currently
+     * in the pool + the number of connections currently being used.
+     * @return True if the number of connections supposed to be in the pool is higher
+     *         than the number of connections in the pool + the number of connections currently
+     *         in use. False if not.
+     */
+    private boolean poolHasSpaceForNewConnections() {
+        return this.maxPoolSize > size();
+    }
+
+    public synchronized void connectionClosed(ConnectionEvent event) {
+
+        PooledConnection connection = (PooledConnection) event.getSource();
+
+        this.connectionsInUse.remove(connection);
+        this.sessionConnectionWrappers.remove(connection);
+
+        if (!this.isPoolClosed) {
+            enqueue(connection);
+            logInfo("Connection returned to pool.");
+        } else {
+            closePhysically(connection, "closing returned connection.");
+            logInfo(
+                "Connection returned to pool was closed because pool is closed.");
+            this.notifyAll();    //notifies evt. threads waiting for connection or for the pool to close.
+        }
+    }
+
+    /**
+     *
+     * A fatal error has occurred and the connection cannot be used anymore.
+     * A close event from such a connection should be ignored. The connection should not be reused.
+     * A new connection will be created to replace the invalid connection, when the next client
+     * calls getConnection().
+     */
+    public synchronized void connectionErrorOccurred(ConnectionEvent event) {
+
+        PooledConnection connection = (PooledConnection) event.getSource();
+
+        connection.removeConnectionEventListener(this);
+        this.connectionsInUse.remove(connection);
+        this.sessionConnectionWrappers.remove(connection);
+        logInfo(
+            "Fatal exception occurred on pooled connection. Connection is removed from pool: ");
+        logInfo(event.getSQLException());
+        closePhysically(connection, "closing invalid, removed connection.");
+
+        //notify threads waiting for connections or for the pool to close.
+        //one waiting thread can now create a new connection since the pool has space for a new connection.
+        //if a thread waits for the pool to close this could be the last unclosed connection in the pool.
+        this.notifyAll();
+    }
+
+    /**
+     * Closes this connection pool. No further connections can be obtained from it after this.
+     * All inactive connections are physically closed before the call returns.
+     * Active connections are not closed.
+     * There may still be active connections in use after this method returns.
+     * When these connections are closed and returned to the pool they will be
+     * physically closed.
+     */
+    public synchronized void close() {
+
+        this.isPoolClosed = true;
+
+        while (this.connectionsInactive.size() > 0) {
+            PooledConnection connection = dequeueFirstIfAny();
+
+            if (connection != null) {
+                closePhysically(
+                    connection,
+                    "closing inactive connection when connection pool was closed.");
+            }
+        }
+    }
+
+    /**
+     * Closes this connection pool. All inactive connections in the pool are closed physically immediatedly.
+     * Waits until all active connections are returned to the pool and closed physically before returning.
+     * @throws InterruptedException If the thread waiting is interrupted before all connections are returned
+     *         to the pool and closed.
+     */
+    public synchronized void closeAndWait() throws InterruptedException {
+
+        close();
+
+        while (size() > 0) {
+            this.wait();
+        }
+    }
+
+    /**
+     * Closes this connection
+     */
+    public synchronized void closeImmediatedly() {
+
+        close();
+
+        Iterator iterator = this.connectionsInUse.iterator();
+
+        while (iterator.hasNext()) {
+            PooledConnection connection = (PooledConnection) iterator.next();
+            SessionConnectionWrapper sessionWrapper =
+                (SessionConnectionWrapper) this.sessionConnectionWrappers.get(
+                    connection);
+
+            closeSessionWrapper(
+                sessionWrapper,
+                "Error closing session wrapper. Connection pool was shutdown immediatedly.");
+        }
+    }
+
+    private void closePhysically(PooledConnection source, String logText) {
+
+        try {
+            source.close();
+        } catch (SQLException e) {
+            logInfo("Error " + logText, e);
+        }
+    }
+
+    /**
+     * @see JDBCConnectionPoolDataSource#logInfo(String)
+     */
+    private void logInfo(String message) {
+
+        /* For external unit tests, temporarily change visibility to public.*/
+        connectionPoolDataSource.logInfo(message);
+    }
+
+    /**
+     * @see JDBCConnectionPoolDataSource#logInfo(Throwable)
+     */
+    private void logInfo(Throwable t) {
+
+        /* For external unit tests, temporarily change visibility to public.*/
+        connectionPoolDataSource.logInfo(t);
+    }
+
+    /**
+     * @see JDBCConnectionPoolDataSource#logInfo(String, Throwable)
+     */
+    private void logInfo(String message, Throwable t) {
+
+        /* For external unit tests, temporarily change visibility to public.*/
+        connectionPoolDataSource.logInfo(message, t);
+    }
+
+    /**
+     * Sets auto-commit mode for every new connection that we provide.
+     *
+     * This is very useful to enforce desired JDBC environments when
+     * using containers (app servers being the most popular).
+     */
+    public void setDefaultAutoCommit(boolean defaultAutoCommit) {
+        isAutoCommit      = defaultAutoCommit;
+        doResetAutoCommit = true;
+    }
+
+    /**
+     * Sets read-only mode for every new connection that we provide
+     *
+     * This is an easy way to ensure a safe test environment.
+     * By making one container setting, you can be sure that the
+     * DB will not be updated.
+     */
+    public void setDefaultReadOnly(boolean defaultReadOnly) {
+        isReadOnly      = defaultReadOnly;
+        doResetReadOnly = true;
+    }
+
+    /**
+     * Sets transaction level for every new connection that we provide.
+     *
+     * For portability purposes, this has no effect on HSQLDB right now.
+     * We anticipate this working intuitively for release 1.9.0 of HSQLDB.
+     */
+    public void setDefaultTransactionIsolation(
+            int defaultTransactionIsolation) {
+        transactionIsolation        = defaultTransactionIsolation;
+        doResetTransactionIsolation = true;
+    }
+
+    /**
+     * Sets catalog for every new connection that we provide.
+     *
+     * For portability purposes, this has no effect on HSQLDB right now.
+     * Don't know yet when HSQLDB will have catalog-switching implemented.
+     */
+    public void setDefaultCatalog(String defaultCatalog) {
+        catalog        = defaultCatalog;
+        doResetCatalog = true;
+    }
+
+    /**
+     * @see #setDefaultAutoCommit(boolean)
+     */
+    public boolean getDefaultAutoCommit() {
+
+        doResetAutoCommit = true;
+
+        return isAutoCommit;
+    }
+
+    /**
+     * @see #setDefaultCatalog(String)
+     */
+    public String getDefaultCatalog() {
+
+        doResetCatalog = true;
+
+        return catalog;
+    }
+
+    /**
+     * @see #setDefaultReadOnly(boolean)
+     */
+    public boolean getDefaultReadOnly() {
+
+        doResetReadOnly = true;
+
+        return isReadOnly;
+    }
+
+    /**
+     * @see #setDefaultTransactionIsolation(int)
+     */
+    public int getDefaultTransactionIsolation() {
+
+        doResetTransactionIsolation = true;
+
+        return transactionIsolation;
+    }
+
+    /**
+     * For compatibility.
+     *
+     * @param driverClassName must be the main JDBC driver class name.
+     */
+    public void setDriverClassName(String driverClassName) {
+
+        if (driverClassName.equals(JDBCConnectionPoolDataSource.driver)) {
+            return;
+        }
+
+        /** @todo: Use a HSQLDB RuntimeException subclass */
+        throw new RuntimeException("This class only supports JDBC driver '"
+                                   + JDBCConnectionPoolDataSource.driver
+                                   + "'");
+    }
+
+    /**
+     * For compatibility.
+     *
+     * @see #setDriverClassName(String)
+     */
+    public String getDriverClassName() {
+        return JDBCConnectionPoolDataSource.driver;
+    }
+
+    /**
+     * Call this method to pre-initialize some physical connections.
+     *
+     * You must call this method before your first getConnection() call,
+     * or there will be no effect.
+     * N.b. that regardless of the initialSize, no physical connections
+     * will be established until the first call to getConnection().
+     *
+     * @param initialSize  Pre-initialize this number of physical
+     *                      connections upon first call to getConnection().
+     *                      The default is 0, which means, no pre-allocation.
+     * @see #getConnection()
+     */
+    public void setInitialSize(int initialSize) {
+        this.initialSize = initialSize;
+    }
+
+    /**
+     * This wrapper is to conform with section 11.7 of the JDBC 3.0 Spec.
+     *
+     * @see #setInitialSize(int)
+     */
+    public int getInitialPoolSize() {
+        return getInitialSize();
+    }
+
+    /**
+     * This wrapper is to conform with section 11.7 of the JDBC 3.0 Spec.
+     *
+     * @see #getInitialSize()
+     */
+    public void setInitialPoolSize(int initialSize) {
+        setInitialSize(initialSize);
+    }
+
+    /**
+     * @see #setInitialPoolSize(int)
+     */
+    public int getInitialSize() {
+        return initialSize;
+    }
+
+    /**
+     * @todo:  Implement
+     * public void setMaxIdle(int maxIdle) {
+     * }
+     * public int getMaxIdle() {
+     *   return maxIdle;
+     * }
+     */
+
+    /**
+     * @todo:  Implement
+     * public void setMaxWait(long maxWait) {
+     * }
+     */
+
+    /**
+     * @todo:  Implement
+     * public void setMinIdle(int minIdle) {
+     * }
+     */
+
+    /**
+     * The current number of active connections that have been allocated from
+     * this data source
+     */
+    public int getNumActive() {
+        return connectionsInUse.size();
+    }
+
+    /**
+     * The current number of idle connections that are waiting to be allocated
+     * from this data source
+     */
+    public int getNumIdle() {
+        return connectionsInactive.size();
+    }
+
+    /**
+     * Wrapper.
+     *
+     * @see #setUser(String)
+     */
+    public void setUsername(String username) {
+        setUser(username);
+    }
+
+    /**
+     * Wrapper.
+     *
+     * @see #getUser()
+     */
+    public String getUsername() {
+        return getUser();
+    }
+
+    /**
+     * Wrapper.
+     *
+     * @see #setMaxPoolSize(int)
+     */
+    public void setMaxActive(int maxActive) {
+        setMaxPoolSize(maxActive);
+    }
+
+    /**
+     * Wrapper.
+     *
+     * @see #getMaxPoolSize()
+     */
+    public int getMaxActive() {
+        return getMaxPoolSize();
+    }
+
+    /**
+     * Set a query that always returns at least one row.
+     *
+     * This is a standard and important connection pool manager feature.
+     * This is used to perform end-to-end validation before returning
+     * a Connection to a user.
+     */
+    public void setValidationQuery(String validationQuery) {
+        this.validationQuery = validationQuery;
+    }
+
+    /**
+     * @see #setValidationQuery(String)
+     */
+    public String getValidationQuery() {
+        return validationQuery;
+    }
+
+    /**
+     * Sets JDBC Connection Properties to be used when physical
+     * connections are obtained for the pool.
+     */
+    public void addConnectionProperty(String name, String value) {
+        this.connectionPoolDataSource.setConnectionProperty(name, value);
+    }
+
+    /**
+     * Removes JDBC Connection Properties.
+     *
+     * @see #addConnectionProperty(String, String)
+     */
+    public void removeConnectionProperty(String name) {
+        this.connectionPoolDataSource.removeConnectionProperty(name);
+    }
+
+    /**
+     * @see #addConnectionProperty(String, String)
+     */
+    public Properties getConnectionProperties() {
+        return this.connectionPoolDataSource.getConnectionProperties();
+    }
+
+    /**
+     * Dumps current state of this Manager.
+     */
+    public String toString() throws RuntimeException {
+
+        int timeout = 0;
+
+        try {
+            timeout = getLoginTimeout();
+        } catch (SQLException se) {
+            throw new RuntimeException(
+                "Failed to retrieve the Login Timeout value");
+        }
+
+        StringBuffer sb =
+            new StringBuffer(ManagedPoolDataSource.class.getName()
+                             + " instance:\n    User:  " + getUsername()
+                             + "\n    Url:  " + getUrl()
+                             + "\n    Login Timeout:  " + timeout
+                             + "\n    Num ACTIVE:  " + getNumActive()
+                             + "\n    Num IDLE:  " + getNumIdle());
+
+        if (doResetAutoCommit) {
+            sb.append("\n    Default auto-commit: " + getDefaultAutoCommit());
+        }
+
+        if (doResetReadOnly) {
+            sb.append("\n    Default read-only: " + getDefaultReadOnly());
+        }
+
+        if (doResetTransactionIsolation) {
+            sb.append("\n    Default trans. lvl.: "
+                      + getDefaultTransactionIsolation());
+        }
+
+        if (doResetCatalog) {
+            sb.append("\n    Default catalog: " + getDefaultCatalog());
+        }
+
+        /** @todo:  Add report for max and min settings which aren't implemented yet. */
+        return sb.toString() + "\n    Max Active: " + getMaxActive()
+               + "\n    Init Size: " + getInitialSize() + "\n    Conn Props: "
+               + getConnectionProperties() + "\n    Validation Query: "
+               + validationQuery + '\n';
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/SessionConnectionWrapper.java b/src/org/hsqldb/jdbc/pool/SessionConnectionWrapper.java
new file mode 100644
index 0000000..2c0fefc
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/SessionConnectionWrapper.java
@@ -0,0 +1,101 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Wraps a connection from the connection pool during a session. A session lasts from the
+ * connection is taken from the pool and until it is closed and returned to the pool. Each
+ * time a connection is taken from the pool it is wrapped in a new SessionConnectionWrapper instance.
+ * When the connection is closed the SessionConnectionWrapper is invalidated and thus that reference
+ * to the connection is invalidated. There can only be one valid SessionConnectionWrapper
+ * at any time per underlying connection.
+ *
+ * <br/><br/>
+ * The SessionConnectionWrapper makes it possible to invalidate connection references independently
+ * of each other, even if the different references point to the same underlying connection. This is useful
+ * if a thread by accident keeps a reference to the connection after it is closed. If the thread
+ * tries to call any methods on the connection the SessionConnectionWrapper will throw an SQLException.
+ * Other threads, or even the same thread, that takes the connection from the pool subsequently will
+ * get a new SessionConnectionWrapper. Therefore their reference to the connection is valid
+ * even if earlier references have been invalidated.
+ *
+ * <br/><br/>
+ * The SessionConnectionWrapper is also useful when a connection pool is to reclaim abandoned
+ * connections (connections that by accident have not been closed). After having been out of
+ * the pool and inactive for a certain time (set by the user),
+ * the pool can decide that the connection must be abandoned. The pool will then close the
+ * SessionConnectionWrapper and return the underlying connection to the pool.
+ * If the thread that abandoned the connection tries to call any
+ * methods on the SessionConnectionWrapper it will get an SQLException. The underlying connection
+ * is still valid for the next thread that takes it from the pool.
+ *
+ *
+ * @author Jakob Jenkov
+ */
+public class SessionConnectionWrapper extends BaseConnectionWrapper {
+
+    protected long       latestActivityTime = 0;
+    protected Connection connection         = null;
+
+    public SessionConnectionWrapper(Connection connection) {
+
+        this.connection = connection;
+
+        updateLatestActivityTime();
+    }
+
+    protected Connection getConnection() {
+        return this.connection;
+    }
+
+    public synchronized void updateLatestActivityTime() {
+        this.latestActivityTime = System.currentTimeMillis();
+    }
+
+    public synchronized long getLatestActivityTime() {
+        return latestActivityTime;
+    }
+
+    public void close() throws SQLException {
+
+        this.isClosed = true;
+
+        Connection temp = this.connection;
+
+        this.connection = null;
+
+        temp.close();
+    }
+}
diff --git a/src/org/hsqldb/jdbc/pool/WrapperInvocationHandler.java b/src/org/hsqldb/jdbc/pool/WrapperInvocationHandler.java
new file mode 100644
index 0000000..2ba3146
--- /dev/null
+++ b/src/org/hsqldb/jdbc/pool/WrapperInvocationHandler.java
@@ -0,0 +1,995 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.jdbc.pool;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.Array;
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.hsqldb.lib.IntValueHashMap;
+
+/**
+ * An <tt>InvocationHandler</tt> that facilitates <tt>Connection</tt> and
+ * <tt>Statement</tt> pooling.
+ *
+ * The primary function is to avoid directly exposing close() and isClosed()
+ * methods on physical <tt>Connection</tt> and <tt>Statement</tt> objects that
+ * are participating in a pooling implementation.
+ *
+ * The secondary function is to assist the pooling mechanism by providing
+ * check in notification for <tt>Connection</tt> objects and
+ * check in / check out notification for derived <tt>Statement</tt> objects.
+ *
+ * @author boucherb@users
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class WrapperInvocationHandler implements InvocationHandler {
+
+    // First, some helper definitions
+
+    /**
+     * Uniquely identifies, by the generating invocation signature, a
+     * physical <tt>Statement</tt> object or like collection thereof. <p>
+     */
+    public final class StatementKey {
+
+        // assigned in constructor
+        private final Method   method;
+        private final Object[] args;
+
+        // derived
+        private int hashCode;
+
+        /**
+         * Constructs a new <tt>StatementKey</tt> from the given invocation
+         * signature.
+         *
+         * @param method the invocation's method
+         * @param args the invocation's arguments
+         */
+        StatementKey(Method method, Object[] args) {
+
+            this.method = method;
+            this.args   = (args == null) ? null
+                                         : (Object[]) args.clone();
+        }
+
+        /**
+         * Returns the hash code value for this object. <p>
+         *
+         * This method is supported to allow semantically correct participation
+         * as a key in a keyed <tt>Collection</tt> (e.g. a <tt>Map</tt>),
+         * <tt>Hashtable</tt> or as an element in a <tt>HashSet</tt>.
+         *
+         * @return The hash code value for this object
+         * @see #equals(java.lang.Object)
+         * @see java.lang.Object#hashCode()
+         */
+        public int hashCode() {
+
+            if (hashCode == 0) {
+                int h = method.hashCode();
+
+                if (args != null) {
+                    for (int i = args.length - 1; i >= 0; i--) {
+                        if (args[i] != null) {
+                            h = 31 * h + args[i].hashCode();
+                        }
+                    }
+                }
+
+                hashCode = h;
+            }
+
+            return hashCode;
+        }
+
+        /**
+         * Indicates whether some other object is "equal to" this one. <p>
+         *
+         * An object is equal to a <tt>StatementKey</tt> if it is the same
+         * object or it is a different StatementKey having an equivalent
+         * method and argument array.
+         *
+         * @param obj the reference object with which to compare.
+         * @return  <code>true</code> if this object is the same as the obj
+         *          argument; <code>false</code> otherwise.
+         * @see     #hashCode()
+         * @see     java.lang.Object#equals(java.lang.Object)
+         */
+        public boolean equals(Object obj) {
+
+            if (this == obj) {
+                return true;
+            } else if (obj instanceof StatementKey) {
+                StatementKey other = (StatementKey) obj;
+
+                return (this.method.equals(other.method)
+                        && ((this.args == other.args)
+                            || Arrays.equals(this.args, other.args)));
+            } else {
+                return false;
+            }
+        }
+
+        /**
+         * Retrieves the <tt>Method</tt> object with which this key was
+         * constructed. <p>
+         *
+         * @return the <tt>Method</tt> object with which this key was
+         *      constructed.
+         */
+        public Method getMethod() {
+            return this.method;
+        }
+
+        /**
+         * Retrieves a copy of the argument array which this key was
+         * constructed. <p>
+         *
+         * @return a copy of the argument array which this key was
+         *      constructed
+         */
+        public Object[] getArgs() {
+            return (args == null) ? null
+                                  : (Object[]) args.clone();
+        }
+    }
+
+
+    /**
+     * Interface required to cooperate with a <tt>Statement</tt> pool
+     * implementation. <p>
+     */
+    public interface StatementPool {
+
+        /**
+         * Indicates to an underlying pool that the given physical
+         * <tt>Statement</tt> object is no longer in use by a
+         * surrogate. <p>
+         *
+         * @param key an object representing the invocation signature with
+         *      which the surrogate's invocation handler originally generated
+         *      the statement.
+         * @param stmt the physical <tt>Statement</tt> object
+         */
+        public void checkIn(StatementKey key, Statement stmt);
+
+        /**
+         * Asks an underlying pool for a physical <tt>Statement</tt> object
+         * compatible with the invocation signature represented by the given
+         * key. <p>
+         *
+         * The pool may respond with a <tt>null</tt> value, in which case it is
+         * the job of the invocation handler to delegate to the underlying
+         * physical <tt>Connection</tt>.
+         *
+         * @param key an object representing the invocation signature used
+         *      to request a statement.
+         */
+        public Statement checkOut(StatementKey key);
+
+        /**
+         * Retrieves whether the given physical <tt>Statement</tt> object is
+         * poolable. <p>
+         *
+         * If it is not, then the invocation handler is free to skip checking
+         * the <tt>Statement</tt> back in when its surrogate is closed,
+         * closing the <tt>Statement</tt> directly, instead.  On the other
+         * hand, a well-written statement pool implementation should correctly
+         * handle checkin of non-poolable statements by closing them.
+         */
+        public boolean isPoolable(Statement stmt);
+    }
+
+    /**
+     * Interface required to cooperate with a <tt>Connection</tt> pool
+     * implementation. <p>
+     *
+     * A <tt>DataSource</tt> handles checkout of physical connections from an
+     * underlying pool and exposes a <tt>WrapperInvocationHandler.ConnectionPool</tt>
+     * interface to allow each physical <tt>Connection</tt> object's
+     * corresponding <tt>WrapperInvocationHandler</tt> to check it back in to
+     * the underlying pool when the surrogate is closed.
+     */
+    public interface ConnectionPool {
+
+        /**
+         * Returns a physical <tt>Connection</tt> to an underlying pool. <p>
+         *
+         * @param connection The physical connection object being returned to
+         *      the pool.
+         * @param statementPool The implementation originally provided
+         *      by the pooling implementation to facilitate statement reuse
+         *      against the given <tt>Connection</tt> object.
+         */
+        void checkIn(Connection connection, StatementPool statementPool);
+    }
+
+    // ----- Static computation of Methods that are sensitive to pooling -------
+    public static final int                WIH_NO_SURROGATE            = 0;
+    public static final int                WIH_CLOSE_SURROGATE         = 1;
+    public static final int                WIH_IS_CLOSED_SURROGATE     = 2;
+    public static final int                WIH_GET_PARENT_SURROGATE    = 3;
+    public static final int WIH_GET_DATABASEMETADATA_SURROGATE         = 4;
+    public static final int WIH_CREATE_OR_PREPARE_STATEMENT_SURROGATE  = 5;
+    public static final int                WIH_GET_RESULTSET_SURROGATE = 6;
+    public static final int                WIH_UNWRAP_SURROGATE        = 7;
+    public static final int                WIH_GET_ARRAY_SURROGATE     = 8;
+    protected static final IntValueHashMap methodMap = new IntValueHashMap();
+
+    // ------- Interfaces having methods that are sensitive to pooling ---------
+    protected static final Class[] arrayInterface = new Class[]{ Array.class };
+    protected static final Class[] connectionInterface = new Class[]{
+        Connection.class };
+    protected static final Class[] callableStatementInterface = new Class[]{
+        CallableStatement.class };
+    protected static final Class[] databaseMetaDataInterface = new Class[]{
+        DatabaseMetaData.class };
+
+    //protected static final Class[] parameterMetaDataInterface
+    //        = new Class[]{ParameterMetaData.class};
+    protected static final Class[] preparedStatementInterface = new Class[]{
+        PreparedStatement.class };
+
+    //protected static final Class[] resultSetMetaDataInterface
+    //        = new Class[]{ResultSetMetaData.class};
+    protected static final Class[] resultSetInterface = new Class[]{
+        ResultSet.class };
+    protected static final Class[] statementInterface = new Class[]{
+        Statement.class };
+
+    // ------------------ Static Initialization Helper Methods -----------------
+
+    /**
+     * Simple test used only during static initialization.
+     *
+     * @param clazz reflecting the given public member method
+     * @param method to test
+     * @return true if close() method of poolable class
+     */
+    protected static boolean _isCloseSurrogateMethod(final Class clazz,
+            final Method method) {
+
+        return ((Connection.class.isAssignableFrom(
+            clazz) || Statement.class.isAssignableFrom(
+            clazz)) && "close".equals(method.getName()));
+    }
+
+    /**
+     * Simple test used only during static initialization.
+     *
+     * @param clazz reflecting the given public member method
+     * @param method to test
+     * @return true if isClosed() method of poolable class
+     */
+    protected static boolean _isIsClosedSurrogateMethod(final Class clazz,
+            final Method method) {
+
+        return ((Connection.class.isAssignableFrom(
+            clazz) || Statement.class.isAssignableFrom(
+            clazz)) && "isClosed".equals(method.getName()));
+    }
+
+//    /**
+//     *
+//     * Simple test used only during static initialization.
+//     *
+//     * @param clazz reflecting the given public member method
+//     * @param method to test
+//     * @return true if isWrapperFor() method of class exposes pooling-senstive
+//     *      behavior
+//     */
+//    protected static  boolean isIsWrapperForMethod(final Method method) {
+//        return "isWrapperFor".equals(method.getName());
+//    }
+
+    /**
+     * Simple test used only during static initialization.
+     *
+     * @param method to test
+     * @return true if method is an unwrap() method
+     */
+    protected static boolean _isUnwrapMethod(final Method method) {
+        return "unwrap".equals(method.getName());
+    }
+
+    // ------------------------ Static Initialization --------------------------
+    static {
+        Class[] poolingSensitiveInterfaces = new Class[] {
+            java.sql.Array.class, java.sql.CallableStatement.class,
+            java.sql.Connection.class, java.sql.DatabaseMetaData.class,
+
+            // unlikely to expose raw delegate of interest
+            //java.sql.ParameterMetaData.class,
+            java.sql.PreparedStatement.class, java.sql.ResultSet.class,
+
+            // unlikely to expose raw delegate of interest
+            //java.sql.ResultSetMetaData.class,
+            java.sql.Statement.class
+        };
+
+        for (int i = 0; i < poolingSensitiveInterfaces.length; i++) {
+            Class    clazz   = poolingSensitiveInterfaces[i];
+            Method[] methods = clazz.getMethods();
+
+            for (int j = 0; j < methods.length; j++) {
+                Method method     = methods[j];
+                Class  returnType = method.getReturnType();
+
+                if (_isCloseSurrogateMethod(clazz, method)) {
+                    methodMap.put(method, WIH_CLOSE_SURROGATE);
+                } else if (_isIsClosedSurrogateMethod(clazz, method)) {
+                    methodMap.put(method, WIH_IS_CLOSED_SURROGATE);
+                } else if (Array.class.isAssignableFrom(returnType)) {
+                    methodMap.put(method, WIH_GET_ARRAY_SURROGATE);
+                } else if (Connection.class.isAssignableFrom(returnType)) {
+                    methodMap.put(method, WIH_GET_PARENT_SURROGATE);
+                } else if (Statement.class.isAssignableFrom(returnType)) {
+                    String methodName = method.getName();
+
+                    if (methodName.startsWith("create")
+                            || methodName.startsWith("prepare")) {
+                        methodMap.put(
+                            method, WIH_CREATE_OR_PREPARE_STATEMENT_SURROGATE);
+                    } else {
+                        methodMap.put(method, WIH_GET_PARENT_SURROGATE);
+                    }
+                } else if (ResultSet.class.isAssignableFrom(returnType)) {
+                    methodMap.put(method, WIH_GET_RESULTSET_SURROGATE);
+                } else if (DatabaseMetaData.class.isAssignableFrom(
+                        returnType)) {
+                    methodMap.put(method, WIH_GET_DATABASEMETADATA_SURROGATE);
+
+                    //} else if (ParameterMetaData.class.
+                    //        isAssignableFrom(returnType)) {
+                    // *************************************************************
+                    //} else if (ResultSetMetaData.class.
+                    //        isAssignableFrom(returnType)) {
+                    // *************************************************************
+                    //} else if (isIsWrapperForMethod(method)) {
+                    // *************************************************************
+                } else if (_isUnwrapMethod(method)) {
+                    methodMap.put(method, WIH_UNWRAP_SURROGATE);
+                }
+            }
+        }
+    }
+
+    // ----------------------- Construction Utility Method ---------------------
+
+    /**
+     * Given a delegate, retrieves the interface that must be implemented by a
+     * surrogate dynamic proxy to ensure pooling sensitive methods
+     * of the delegate are not exposed directly to clients.
+     *
+     * @param delegate the target delegate of interest
+     * @return the interface that must be implemented by a surrogate dynamic
+     *         proxy to ensure pooling sensitive methods of the delegate are
+     *         not exposed directly to clients
+     */
+    protected static Class[] _computeProxiedInterface(Object delegate) {
+
+        // NOTE:  Order is important for XXXStatement.
+        if (delegate instanceof Array) {
+            return arrayInterface;
+        } else if (delegate instanceof Connection) {
+            return connectionInterface;
+        } else if (delegate instanceof CallableStatement) {
+            return callableStatementInterface;
+        } else if (delegate instanceof DatabaseMetaData) {
+            return databaseMetaDataInterface;
+        } else if (delegate instanceof PreparedStatement) {
+            return preparedStatementInterface;
+        } else if (delegate instanceof ResultSet) {
+            return resultSetInterface;
+        } else if (delegate instanceof Statement) {
+            return statementInterface;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Retrieves a numeric classification of the surrogate method type
+     * corresponding to the given delegate method.
+     *
+     * @param method the method to test
+     * @return the numeric classification
+     */
+    protected static int _computeSurrogateType(Method method) {
+        return methodMap.get(method, WIH_NO_SURROGATE);
+    }
+
+    // ---------------------------- Instance Fields ----------------------------
+    // set in constructor
+    private Object                   delegate;
+    private Object                   surrogate;
+    private WrapperInvocationHandler parentHandler;
+    private ConnectionPool           connectionPool;
+    private StatementPool            statementPool;
+
+    // derivied
+    private WrapperInvocationHandler dbmdHandler;
+    private boolean                  surrogateClosed;
+    private StatementKey             statementKey;
+    private Set                      resultSets;    //ResultSet invocation handlers
+    private Set                      statements;    //Statement invocation handlers
+
+// ------------------------------ Constructors ---------------------------------
+
+    /**
+     * Constructs a new invocation handler for the given <tt>Connection</tt>.
+     *
+     * @param connection the <tt>Connection</tt> for which to construct an
+     *      invocation handler
+     * @param connectionPool interface to an external connection pool; may be null
+     * @param statementPool interface to an external statement pool; may be null
+     * @throws java.lang.IllegalArgumentException if connection is null
+     */
+    public WrapperInvocationHandler(Connection connection,
+                                    ConnectionPool connectionPool,
+                                    StatementPool statementPool)
+                                    throws IllegalArgumentException {
+
+        this(connection, null);
+
+        this.connectionPool = connectionPool;
+        this.statementPool  = statementPool;
+    }
+
+    /**
+     * Constructs a new invocation handler for the given delegate and
+     * parent invocation handler. <p>
+     *
+     * @param delegate the delegate for which to construct the invocation handler
+     * @param parent the invocation handler of the delegate's parent; may be null.
+     * @throws IllegalArgumentException if delegate is null; or if its proxied
+     *      interface cannot be determined; or if any of the restrictions on the
+     *      parameters that may be passed to <code>Proxy.newProxyInstance</code>
+     *      are violated
+     */
+    public WrapperInvocationHandler(Object delegate,
+                                    WrapperInvocationHandler parent)
+                                    throws IllegalArgumentException {
+
+        if (delegate == null) {
+            throw new IllegalArgumentException("delegate: null");
+        }
+
+        Class[] proxiedInterface = _computeProxiedInterface(delegate);
+
+        if (proxiedInterface == null) {
+            throw new IllegalArgumentException("delegate: " + delegate);
+        }
+
+        this.delegate      = delegate;
+        this.parentHandler = parent;
+        this.surrogate =
+            Proxy.newProxyInstance(proxiedInterface[0].getClassLoader(),
+                                   proxiedInterface, this);
+    }
+
+    // ----------------------- Interface Implementation ------------------------
+
+    /**
+     * Processes a method invocation on a proxy instance and returns
+     * the result.  This method will be invoked on an invocation handler
+     * when a method is invoked on a proxy instance that it is
+     * associated with.
+     *
+     * @param   proxy the proxy instance that the method was invoked on
+     *
+     * @param   method the <code>Method</code> instance corresponding to
+     * the interface method invoked on the proxy instance.  The declaring
+     * class of the <code>Method</code> object will be the interface that
+     * the method was declared in, which may be a superinterface of the
+     * proxy interface that the proxy class inherits the method through.
+     *
+     * @param   args an array of objects containing the values of the
+     * arguments passed in the method invocation on the proxy instance,
+     * or <code>null</code> if interface method takes no arguments.
+     * Arguments of primitive types are wrapped in instances of the
+     * appropriate primitive wrapper class, such as
+     * <code>java.lang.Integer</code> or <code>java.lang.Boolean</code>.
+     *
+     * @return  the value to return from the method invocation on the
+     * proxy instance.  If the declared return type of the interface
+     * method is a primitive type, then the value returned by
+     * this method must be an instance of the corresponding primitive
+     * wrapper class; otherwise, it must be a type assignable to the
+     * declared return type.  If the value returned by this method is
+     * <code>null</code> and the interface method's return type is
+     * primitive, then a <code>NullPointerException</code> will be
+     * thrown by the method invocation on the proxy instance.  If the
+     * value returned by this method is otherwise not compatible with
+     * the interface method's declared return type as described above,
+     * a <code>ClassCastException</code> will be thrown by the method
+     * invocation on the proxy instance.
+     *
+     * @throws  Throwable the exception to throw from the method
+     * invocation on the proxy instance.  The exception's type must be
+     * assignable either to any of the exception types declared in the
+     * <code>throws</code> clause of the interface method or to the
+     * unchecked exception types <code>java.lang.RuntimeException</code>
+     * or <code>java.lang.Error</code>.  If a checked exception is
+     * thrown by this method that is not assignable to any of the
+     * exception types declared in the <code>throws</code> clause of
+     * the interface method, then undeclared {@link Throwable} containing
+     * the exception that was thrown by this method will be thrown by the
+     * method invocation on the proxy instance.
+     *
+     * @see Throwable
+     */
+
+    /**
+     * @todo: - Synchronization can be made more granular if performance suffers.
+     *      - Requires some private lock objects and synchronized blocks in
+     *        certain methods.
+     *      - This was the obvious and easy synchronization point to pick
+     *        initially for prototyping purposes
+     */
+    public synchronized Object invoke(final Object proxy, final Method method,
+                                      final Object[] args) throws Throwable {
+
+        Object result;
+
+        switch (_computeSurrogateType(method)) {
+
+            case WIH_CLOSE_SURROGATE : {
+                closeSurrogate();
+
+                result = null;
+
+                break;
+            }
+            case WIH_IS_CLOSED_SURROGATE : {
+                result = isClosedSurrogate() ? Boolean.TRUE
+                                             : Boolean.FALSE;
+
+                break;
+            }
+            case WIH_GET_PARENT_SURROGATE : {
+                checkSurrogateClosed();
+
+                result = getParentSurrogate(method, args);
+
+                break;
+            }
+            case WIH_GET_DATABASEMETADATA_SURROGATE : {
+                checkSurrogateClosed();
+
+                result = getDatabaseMetaDataSurrogate(method, args);
+
+                break;
+            }
+            case WIH_CREATE_OR_PREPARE_STATEMENT_SURROGATE : {
+                checkSurrogateClosed();
+
+                result = getCreatedOrPreparedStatementSurrogate(method, args);
+
+                break;
+            }
+            case WIH_GET_RESULTSET_SURROGATE : {
+                checkSurrogateClosed();
+
+                result = getResultSetSurrogate(method, args);
+
+                break;
+            }
+            case WIH_UNWRAP_SURROGATE : {
+                checkSurrogateClosed();
+
+                result = unwrapSurrogate(method, args);
+
+                break;
+            }
+            case WIH_GET_ARRAY_SURROGATE : {
+                checkSurrogateClosed();
+
+                result = getArraySurrogate(method, args);
+
+                break;
+            }
+            case WIH_NO_SURROGATE :
+            default : {
+                checkSurrogateClosed();
+
+                result = method.invoke(delegate, args);
+
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    // --------------------- java.lang.Object overrides ------------------------
+
+    /**
+     * Ensures the identity hash code is returned for all descendents
+     *
+     * @return the identity hashCode for this object.
+     */
+    public final int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    /**
+     * Ensures identity equality semantics are preserved for all descendents.
+     *
+     * @param o the object with which to compare
+     * @return  true if (this == o); else false
+     */
+    public final boolean equals(Object o) {
+        return (this == o);
+    }
+
+    // -------------------------- Internal Implementation ----------------------
+
+    /**
+     * Checks if the surrogate is closed.
+     *
+     * @throws java.lang.Throwable if the surrogate is closed.
+     */
+    protected void checkSurrogateClosed() throws Throwable {
+
+        if (isClosedSurrogate()) {
+            throw new SQLException("Surrogate Closed.");    // TODO: better msg
+        }
+    }
+
+    /**
+     * Effectively closes the surrogate, possibly doing work toward
+     * enabling reuse of the delegate. <p>
+     *
+     * @throws java.lang.Throwable if an access error occurs during work to
+     *      enable reuse of the delegate
+     */
+    protected void closeSurrogate() throws Throwable {
+
+        if (this.surrogateClosed) {
+            return;
+        }
+
+        if (this.resultSets != null) {
+            Iterator it = this.resultSets.iterator();
+
+            // Changed to set of ResultSet invocation handlers so
+            // that handler resources can be cleaned up too.
+            while (it.hasNext()) {
+                WrapperInvocationHandler handler =
+                    (WrapperInvocationHandler) it.next();
+
+                try {
+                    ((ResultSet) handler.delegate).close();
+                } catch (Exception ex) {}
+
+                try {
+                    handler.closeSurrogate();
+                } catch (Exception e) {}
+            }
+        }
+
+        if (this.statements != null) {
+            Iterator it = this.statements.iterator();
+
+            while (it.hasNext()) {
+                WrapperInvocationHandler handler =
+                    (WrapperInvocationHandler) it.next();
+
+                try {
+                    handler.closeSurrogate();
+                } catch (Exception e) {}
+            }
+        }
+
+        if (this.dbmdHandler != null) {
+            try {
+                this.dbmdHandler.closeSurrogate();
+            } catch (Throwable ex) {}
+        }
+
+        Object delegate = this.delegate;
+
+        try {
+            if (delegate instanceof Connection) {
+                closeConnectionSurrogate();
+            } else if (delegate instanceof Statement) {
+                closeStatementSurrogate();
+            }
+        } finally {
+            this.delegate        = null;
+            this.surrogate       = null;
+            this.dbmdHandler     = null;
+            this.parentHandler   = null;
+            this.statementKey    = null;
+            this.statementPool   = null;
+            this.connectionPool  = null;
+            this.surrogateClosed = true;
+        }
+    }
+
+    /**
+     * Does work toward enabling reuse of the delegate,
+     * when it is a Connection.
+     *
+     * @throws java.lang.Throwable the exception, if any, thrown by
+     *      returning the delegate connection to the ConnectionPool
+     *      designated at construction of the connection's
+     *      invocation handler.
+     */
+    protected void closeConnectionSurrogate() throws Throwable {
+
+        ConnectionPool connectionPool = this.connectionPool;
+
+        if (connectionPool == null) {
+
+            // CHECKME: policy?
+            // pool has "disapeared" or was never provided (why?): should
+            // "really" close the connection since it will no be reused.
+            Connection connection = (Connection) this.delegate;
+
+            try {
+                connection.close();
+            } catch (SQLException ex) {}
+        } else {
+            Connection    connection    = (Connection) this.delegate;
+            StatementPool statementPool = this.statementPool;
+
+            connectionPool.checkIn(connection, statementPool);
+        }
+    }
+
+    /**
+     * Does work toward enabling reuse of the delegate,
+     * when it is an instance of <tt>Statement</tt>.
+     *
+     * @throws java.lang.Throwable the exception, if any, thrown by
+     *      returning the delegate statement to the StatementPool
+     *      designated at construction of the statement's parent connection
+     *      invocation handler.
+     */
+    protected void closeStatementSurrogate() throws Throwable {
+
+        Statement     stmt          = (Statement) this.delegate;
+        StatementKey  key           = this.statementKey;
+        StatementPool statementPool = (this.parentHandler == null) ? null
+                                                                   : this.parentHandler
+                                                                       .statementPool;
+
+        if (key == null || statementPool == null
+                || !statementPool.isPoolable(stmt)) {
+            try {
+                stmt.close();
+            } catch (Exception ex) {}
+        } else {
+            statementPool.checkIn(key, stmt);
+        }
+    }
+
+    /**
+     * Retrieves whether the surrogate is closed. <p>
+     *
+     * @return true if surrogate is closed; else false
+     * @throws java.lang.Throwable
+     */
+    protected boolean isClosedSurrogate() throws Throwable {
+
+        if (this.surrogateClosed) {
+            return true;
+        }
+
+        // This part is overkill now, but does not introduce
+        // incorrect operation.
+        //
+
+        /**
+         * @todo:  Special handling to check the parent is still desirable
+         *       for Array surrogates (and any other proxied delegate
+         *       that has a parent whose valid lifetime is at most the
+         *       life of the parent and does not expose a public close()
+         *       method through the JDBC API
+         */
+        WrapperInvocationHandler parent = this.parentHandler;
+
+        if (parent != null && parent.isClosedSurrogate()) {
+            closeSurrogate();
+        }
+
+        return this.surrogateClosed;
+    }
+
+    /**
+     * Retrieves a surrogate for the parent <tt>Statement</tt> or
+     * <tt>Connection</tt> object of this handler's delegate.
+     *
+     * @param method that retrieves the delegate's parent object
+     * @param args required for method invocation
+     * @throws java.lang.Throwable the exception, if any, thrown by invoking
+     * the given method with the given arguments upon the delegate
+     * @return surrogate for the underlying parent object
+     */
+    protected Object getParentSurrogate(final Method method,
+                                        final Object[] args) throws Throwable {
+
+        WrapperInvocationHandler parent = this.parentHandler;
+
+        return (parent == null) ? null
+                                : parent.surrogate;
+    }
+
+    /**
+     * Surrogate for any method of the delegate that returns
+     * an instance of <tt>DatabaseMetaData</tt> object. <p>
+     *
+     * @param method returning <tt>DatabaseMetaData</tt>
+     * @param args to the method
+     * @throws java.lang.Throwable the exception, if any, thrown by invoking
+     * the given method with the given arguments upon the delegate
+     * @return surrogate for the underlying DatabaseMetaData object
+     */
+    protected Object getDatabaseMetaDataSurrogate(final Method method,
+            final Object[] args) throws Throwable {
+
+        if (this.dbmdHandler == null) {
+            Object dbmd = method.invoke(this.delegate, args);
+
+            this.dbmdHandler = new WrapperInvocationHandler(dbmd, this);
+        }
+
+        return this.dbmdHandler.surrogate;
+    }
+
+    /**
+     * Surrogate for any method of the delegate that returns an instance of
+     * <tt>Statement</tt>. <p>
+     *
+     * @param method returning instance of <tt>Statement</tt>
+     * @param args to the method
+     * @throws java.lang.Throwable the exception, if any, thrown by invoking
+     * the given method with the given arguments upon the delegate
+     * @return surrogate for the delegate Statement object
+     */
+    protected Object getCreatedOrPreparedStatementSurrogate(
+            final Method method, final Object[] args) throws Throwable {
+
+        WrapperInvocationHandler handler;
+        Object                   stmt = null;
+        StatementKey             key  = new StatementKey(method, args);
+        StatementPool            pool = this.statementPool;
+
+        if (pool != null) {
+            stmt = pool.checkOut(key);
+        }
+
+        if (stmt == null) {
+            stmt = method.invoke(this.delegate, args);
+        }
+
+        handler              = new WrapperInvocationHandler(stmt, this);
+        handler.statementKey = key;
+
+        if (this.statements == null) {
+            this.statements = new HashSet();
+        }
+
+        statements.add(handler);
+
+        return handler.surrogate;
+    }
+
+    /**
+     * Surrogate for any method of the delegate that returns an
+     * instance of <tt>ResultSet</tt>. <p>
+     *
+     * @param method returning a <tt>ResultSet</tt>
+     * @param args to the method
+     * @throws java.lang.Throwable the exception, if any, thrown by invoking
+     * the given method with the given arguments upon the delegate
+     * @return surrogate for the underlying ResultSet object
+     */
+    protected Object getResultSetSurrogate(final Method method,
+                                           final Object[] args)
+                                           throws Throwable {
+
+        Object rs = method.invoke(this.delegate, args);
+        WrapperInvocationHandler handler = new WrapperInvocationHandler(rs,
+            this);
+
+        if (resultSets == null) {
+            resultSets = new HashSet();
+        }
+
+        // Changed to set of ResultSet invocation handlers so
+        // that handler resources can be cleaned up too.
+        resultSets.add(handler);
+
+        return handler.surrogate;
+    }
+
+    /**
+     * Surrogate for the delegate's unwrap(...) method. <p>
+     *
+     * If invocation of the method returns the delegate itself, then
+     * the delegate's surrogate is returned instead.
+     *
+     * @param method the unwrap method
+     * @param args the argument(s) to the unwrap method
+     * @throws java.lang.Throwable the exception, if any, thrown by invoking
+     * the given method with the given arguments upon the delegate
+     * @return proxy if the method returns the delegate itself; else the actual
+     *      result of invoking the method upon the delegate.
+     */
+    protected Object unwrapSurrogate(final Method method,
+                                     final Object[] args) throws Throwable {
+
+        Object result = method.invoke(this.delegate, args);
+
+        return (result == this.delegate) ? this.surrogate
+                                         : result;
+    }
+
+    /**
+     * Surrogate for any method of the delegate that returns an
+     * instance of <tt>Array</tt>. <p>
+     *
+     * @param method returning an <tt>Array</tt>
+     * @param args to the method
+     * @throws java.lang.Throwable the exception, if any, thrown by invoking
+     * the given method with the given arguments upon the delegate
+     * @return surrogate for the underlying Array object
+     */
+    protected Object getArraySurrogate(final Method method,
+                                       final Object[] args)
+                                       throws java.lang.Throwable {
+
+        Object array = method.invoke(this.delegate, args);
+        WrapperInvocationHandler handler = new WrapperInvocationHandler(array,
+            this);
+
+        return handler.surrogate;
+    }
+}
diff --git a/src/org/hsqldb/jdbcDriver.java b/src/org/hsqldb/jdbcDriver.java
new file mode 100644
index 0000000..870e058
--- /dev/null
+++ b/src/org/hsqldb/jdbcDriver.java
@@ -0,0 +1,36 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb;
+
+public class jdbcDriver
+    extends org.hsqldb.jdbc.JDBCDriver {
+}
diff --git a/src/org/hsqldb/lib/AppendableException.java b/src/org/hsqldb/lib/AppendableException.java
new file mode 100644
index 0000000..20a8e21
--- /dev/null
+++ b/src/org/hsqldb/lib/AppendableException.java
@@ -0,0 +1,99 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Allows additional messages to be appended.
+ *
+ * It often makes for better (and more efficient) design to add context
+ * details to an exception at intermediate points in the thread.
+ * This class makes it easy and efficient to catch and rethrow for that purpose.
+ */
+public class AppendableException extends Exception {
+
+    static final long    serialVersionUID = -1002629580611098803L;
+    public static String LS = System.getProperty("line.separator");
+    public List<String>  appendages       = null;
+
+    public String getMessage() {
+
+        String message = super.getMessage();
+
+        if (appendages == null) {
+            return message;
+        }
+
+        StringBuffer sb = new StringBuffer();
+
+        if (message != null) {
+            sb.append(message);
+        }
+
+        for (String appendage : appendages) {
+            if (sb.length() > 0) {
+                sb.append(LS);
+            }
+
+            sb.append(appendage);
+        }
+
+        return sb.toString();
+    }
+
+    public void appendMessage(String s) {
+
+        if (appendages == null) {
+            appendages = new ArrayList<String>();
+        }
+
+        appendages.add(s);
+    }
+
+    public AppendableException() {
+        // Intentionally empty
+    }
+
+    public AppendableException(String s) {
+        super(s);
+    }
+
+    public AppendableException(Throwable cause) {
+        super(cause);
+    }
+
+    public AppendableException(String string, Throwable cause) {
+         super(string, cause);
+    }
+}
diff --git a/src/org/hsqldb/lib/ArrayCounter.java b/src/org/hsqldb/lib/ArrayCounter.java
new file mode 100644
index 0000000..a5a6f6e
--- /dev/null
+++ b/src/org/hsqldb/lib/ArrayCounter.java
@@ -0,0 +1,152 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * Collection of routines for counting the distribution of the values
+ * in an int[] array.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class ArrayCounter {
+
+    /**
+     * Returns an int[] array of length segments containing the distribution
+     * count of the elements in unsorted int[] array with values between min
+     * and max (range). Values outside the min-max range are ignored<p>
+     *
+     * A usage example is determining the count of people of each age group
+     * in a large int[] array containing the age of each person. Called with
+     * (array, 16,0,79), it will return an int[16] with the first element
+     * the count of people aged 0-4, the second element the count of those
+     * aged 5-9, and so on. People above the age of 79 are excluded. If the
+     * range is not a multiple of segments, the last segment will be cover a
+     * smaller sub-range than the rest.
+     *
+     */
+    public static int[] countSegments(int[] array, int elements,
+                                      int segments, int start, int limit) {
+
+        int[] counts   = new int[segments];
+        long  interval = calcInterval(segments, start, limit);
+        int   index    = 0;
+        int   element  = 0;
+
+        if (interval <= 0) {
+            return counts;
+        }
+
+        for (int i = 0; i < elements; i++) {
+            element = array[i];
+
+            if (element < start || element >= limit) {
+                continue;
+            }
+
+            index = (int) ((element - start) / interval);
+
+            counts[index]++;
+        }
+
+        return counts;
+    }
+
+    /**
+     * With an unsorted int[] array and with target a positive integer in the
+     * range (1,array.length), finds the value in the range (start,limit) of the
+     * largest element (rank) where the count of all smaller elements in that
+     * range is less than or equals target. Parameter margin indicates the
+     * margin of error in target<p>
+     *
+     * In statistics, this can be used to calculate a median or quadrile value.
+     * A usage example applied to an array of age values is to determine
+     * the maximum age of a given number of people. With the example array
+     * given in countSegments, rank(array, c, 6000, 18, 65, 0) will return an age
+     * value between 18-64 (inclusive) and the count of all people aged between
+     * 18 and the returned value(exclusive) will be less than or equal 6000.
+     *
+     */
+    public static int rank(int[] array, int elements, int target, int start,
+                           int limit, int margin) {
+
+        final int segments     = 256;
+        int       elementCount = 0;
+        int       currentLimit = limit;
+
+        for (;;) {
+            long interval = calcInterval(segments, start, currentLimit);
+            int[] counts = countSegments(array, elements, segments, start,
+                                         currentLimit);
+
+            for (int i = 0; i < counts.length; i++) {
+                if (elementCount + counts[i] < target) {
+                    elementCount += counts[i];
+                    start        += interval;
+                } else {
+                    break;
+                }
+            }
+
+            if (elementCount + margin >= target) {
+                return start;
+            }
+
+            if (interval <= 1) {
+                return start;
+            }
+
+            currentLimit = start + interval < limit ? (int) (start + interval)
+                                                    : limit;
+        }
+    }
+
+    /**
+     * Helper method to calculate the span of the sub-interval. Simply returns
+     * the cieling of ((limit - start) / segments) and accounts for invalid
+     * start and limit combinations.
+     */
+    static long calcInterval(int segments, int start, int limit) {
+
+        long range = limit - start;
+
+        if (range < 0) {
+            return 0;
+        }
+
+        int partSegment = (range % segments) == 0 ? 0
+                                                  : 1;
+
+        return (range / segments) + partSegment;
+    }
+}
diff --git a/src/org/hsqldb/lib/ArrayListIdentity.java b/src/org/hsqldb/lib/ArrayListIdentity.java
new file mode 100644
index 0000000..be19d88
--- /dev/null
+++ b/src/org/hsqldb/lib/ArrayListIdentity.java
@@ -0,0 +1,46 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+public class ArrayListIdentity extends HsqlArrayList implements HsqlList {
+
+    public int indexOf(Object o) {
+
+        for (int i = 0; i < elementCount; i++) {
+            if (elementData[i] == o) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+}
diff --git a/src/org/hsqldb/lib/ArraySort.java b/src/org/hsqldb/lib/ArraySort.java
new file mode 100644
index 0000000..f4cb815
--- /dev/null
+++ b/src/org/hsqldb/lib/ArraySort.java
@@ -0,0 +1,181 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.Comparator;
+
+/**
+ * FastQSorts the [l,r] partition (inclusive) of the specfied array of
+ * Rows, using the comparator.<p>
+ *
+ * Searches an ordered array.<p>
+ *
+ * @author Tony Lai
+ * @author Fred Toussi
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ArraySort {
+
+    /**
+     * Returns the index of the lowest element == the given search target,
+     * or -1
+     * @return index or (- insert pos -1) if not found
+     */
+    public static int searchFirst(Object[] array, int start, int limit,
+                                  Object value, Comparator c) {
+
+        int low     = start;
+        int high    = limit;
+        int mid     = start;
+        int compare = 0;
+        int found   = limit;
+
+        while (low < high) {
+            mid     = (low + high) / 2;
+            compare = c.compare(value, array[mid]);
+
+            if (compare < 0) {
+                high = mid;
+            } else if (compare > 0) {
+                low = mid + 1;
+            } else {
+                high  = mid;
+                found = mid;
+            }
+        }
+
+        return found == limit ? -low - 1
+                              : found;
+    }
+
+    public static void sort(Object[] array, int start, int limit,
+                            Comparator comparator) {
+
+        if (start + 1 >= limit) {
+            return;
+        }
+
+        quickSort(array, comparator, start, limit - 1);
+        insertionSort(array, comparator, start, limit - 1);
+    }
+
+    static void quickSort(Object[] array, Comparator comparator, int l,
+                          int r) {
+
+        int M = 16;
+        int i;
+        int j;
+        int v;
+
+        if ((r - l) > M) {
+            i = (r + l) / 2;
+
+            if (comparator.compare(array[i], array[l]) < 0) {
+                swap(array, l, i);    // Tri-Median Methode!
+            }
+
+            if (comparator.compare(array[r], array[l]) < 0) {
+                swap(array, l, r);
+            }
+
+            if (comparator.compare(array[r], array[i]) < 0) {
+                swap(array, i, r);
+            }
+
+            j = r - 1;
+
+            swap(array, i, j);
+
+            i = l;
+            v = j;
+
+            for (;;) {
+                while (comparator.compare(array[++i], array[v]) < 0) {}
+
+                while (comparator.compare(array[v], array[--j]) < 0) {}
+
+                if (j < i) {
+                    break;
+                }
+
+                swap(array, i, j);
+            }
+
+            swap(array, i, r - 1);
+            quickSort(array, comparator, l, j);
+            quickSort(array, comparator, i + 1, r);
+        }
+    }
+
+    public static void insertionSort(Object[] array, Comparator comparator,
+                                     int lo0, int hi0) {
+
+        int i;
+        int j;
+
+        for (i = lo0 + 1; i <= hi0; i++) {
+            j = i;
+
+            while ((j > lo0)
+                    && comparator.compare(array[i], array[j - 1]) < 0) {
+                j--;
+            }
+
+            if (i != j) {
+                moveAndInsertRow(array, i, j);
+            }
+        }
+    }
+
+    private static void swap(Object[] array, int i1, int i2) {
+
+        Object val = array[i1];
+
+        array[i1] = array[i2];
+        array[i2] = val;
+    }
+
+    private static void moveAndInsertRow(Object[] array, int i, int j) {
+
+        Object val = array[i];
+
+        moveRows(array, j, j + 1, i - j);
+
+        array[j] = val;
+    }
+
+    private static void moveRows(Object[] array, int fromIndex, int toIndex,
+                                 int rows) {
+        System.arraycopy(array, fromIndex, array, toIndex, rows);
+    }
+}
diff --git a/src/org/hsqldb/lib/ArrayUtil.java b/src/org/hsqldb/lib/ArrayUtil.java
new file mode 100644
index 0000000..900e66f
--- /dev/null
+++ b/src/org/hsqldb/lib/ArrayUtil.java
@@ -0,0 +1,1328 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.lang.reflect.Array;
+
+/**
+ * Collection of static methods for operations on arrays
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class ArrayUtil {
+
+    public static final int        CLASS_CODE_BYTE    = 'B';
+    public static final int        CLASS_CODE_CHAR    = 'C';
+    public static final int        CLASS_CODE_DOUBLE  = 'D';
+    public static final int        CLASS_CODE_FLOAT   = 'F';
+    public static final int        CLASS_CODE_INT     = 'I';
+    public static final int        CLASS_CODE_LONG    = 'J';
+    public static final int        CLASS_CODE_OBJECT  = 'L';
+    public static final int        CLASS_CODE_SHORT   = 'S';
+    public static final int        CLASS_CODE_BOOLEAN = 'Z';
+    private static IntValueHashMap classCodeMap       = new IntValueHashMap();
+
+    static {
+        classCodeMap.put(byte.class, ArrayUtil.CLASS_CODE_BYTE);
+        classCodeMap.put(char.class, ArrayUtil.CLASS_CODE_SHORT);
+        classCodeMap.put(short.class, ArrayUtil.CLASS_CODE_SHORT);
+        classCodeMap.put(int.class, ArrayUtil.CLASS_CODE_INT);
+        classCodeMap.put(long.class, ArrayUtil.CLASS_CODE_LONG);
+        classCodeMap.put(float.class, ArrayUtil.CLASS_CODE_FLOAT);
+        classCodeMap.put(double.class, ArrayUtil.CLASS_CODE_DOUBLE);
+        classCodeMap.put(boolean.class, ArrayUtil.CLASS_CODE_BOOLEAN);
+        classCodeMap.put(Object.class, ArrayUtil.CLASS_CODE_OBJECT);
+    }
+
+    /**
+     * Returns a distinct int code for each primitive type and for all Object types.
+     */
+    static int getClassCode(Class cla) {
+
+        if (!cla.isPrimitive()) {
+            return ArrayUtil.CLASS_CODE_OBJECT;
+        }
+
+        return classCodeMap.get(cla, -1);
+    }
+
+    /**
+     * Clears an area of the given array of the given type.
+     */
+    public static void clearArray(int type, Object data, int from, int to) {
+
+        switch (type) {
+
+            case ArrayUtil.CLASS_CODE_BYTE : {
+                byte[] array = (byte[]) data;
+
+                while (--to >= from) {
+                    array[to] = 0;
+                }
+
+                return;
+            }
+            case ArrayUtil.CLASS_CODE_CHAR : {
+                byte[] array = (byte[]) data;
+
+                while (--to >= from) {
+                    array[to] = 0;
+                }
+
+                return;
+            }
+            case ArrayUtil.CLASS_CODE_SHORT : {
+                short[] array = (short[]) data;
+
+                while (--to >= from) {
+                    array[to] = 0;
+                }
+
+                return;
+            }
+            case ArrayUtil.CLASS_CODE_INT : {
+                int[] array = (int[]) data;
+
+                while (--to >= from) {
+                    array[to] = 0;
+                }
+
+                return;
+            }
+            case ArrayUtil.CLASS_CODE_LONG : {
+                long[] array = (long[]) data;
+
+                while (--to >= from) {
+                    array[to] = 0;
+                }
+
+                return;
+            }
+            case ArrayUtil.CLASS_CODE_FLOAT : {
+                float[] array = (float[]) data;
+
+                while (--to >= from) {
+                    array[to] = 0;
+                }
+
+                return;
+            }
+            case ArrayUtil.CLASS_CODE_DOUBLE : {
+                double[] array = (double[]) data;
+
+                while (--to >= from) {
+                    array[to] = 0;
+                }
+
+                return;
+            }
+            case ArrayUtil.CLASS_CODE_BOOLEAN : {
+                boolean[] array = (boolean[]) data;
+
+                while (--to >= from) {
+                    array[to] = false;
+                }
+
+                return;
+            }
+            default : {
+                Object[] array = (Object[]) data;
+
+                while (--to >= from) {
+                    array[to] = null;
+                }
+
+                return;
+            }
+        }
+    }
+
+    /**
+     * Moves the contents of an array to allow both addition and removal of
+     * elements. Used arguments must be in range.
+     *
+     * @param type class type of the array
+     * @param array the array
+     * @param usedElements count of elements of array in use
+     * @param index point at which to add or remove elements
+     * @param count number of elements to add or remove
+     */
+    public static void adjustArray(int type, Object array, int usedElements,
+                                   int index, int count) {
+
+        if (index >= usedElements) {
+            return;
+        }
+
+        int newCount = usedElements + count;
+        int source;
+        int target;
+        int size;
+
+        if (count >= 0) {
+            source = index;
+            target = index + count;
+            size   = usedElements - index;
+        } else {
+            source = index - count;
+            target = index;
+            size   = usedElements - index + count;
+        }
+
+        if (size > 0) {
+            System.arraycopy(array, source, array, target, size);
+        }
+
+        if (count < 0) {
+            clearArray(type, array, newCount, usedElements);
+        }
+    }
+
+    /**
+     * Basic sort for small arrays of int.
+     */
+    public static void sortArray(int[] array) {
+
+        boolean swapped;
+
+        do {
+            swapped = false;
+
+            for (int i = 0; i < array.length - 1; i++) {
+                if (array[i] > array[i + 1]) {
+                    int temp = array[i + 1];
+
+                    array[i + 1] = array[i];
+                    array[i]     = temp;
+                    swapped      = true;
+                }
+            }
+        } while (swapped);
+    }
+
+    /**
+     *  Basic find for small arrays of Object.
+     */
+    public static int find(Object[] array, Object object) {
+
+        for (int i = 0; i < array.length; i++) {
+            if (array[i] == object) {
+
+                // hadles both nulls
+                return i;
+            }
+
+            if (object != null && object.equals(array[i])) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     *  Basic find for small arrays of int.
+     */
+    public static int find(int[] array, int value) {
+
+        for (int i = 0; i < array.length; i++) {
+            if (array[i] == value) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    public static int find(short[] array, int value) {
+
+        for (int i = 0; i < array.length; i++) {
+            if (array[i] == value) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    public static int find(short[] array, int value, int offset, int count) {
+
+        for (int i = offset; i < offset + count; i++) {
+            if (array[i] == value) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     *  Finds the first element of the array that is not equal to the given value.
+     */
+    public static int findNot(int[] array, int value) {
+
+        for (int i = 0; i < array.length; i++) {
+            if (array[i] != value) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns true if arra and arrb contain the same set of integers, not
+     * necessarily in the same order. This implies the arrays are of the same
+     * length.
+     */
+    public static boolean areEqualSets(int[] arra, int[] arrb) {
+        return arra.length == arrb.length
+               && ArrayUtil.haveEqualSets(arra, arrb, arra.length);
+    }
+
+    /**
+     * For full == true returns true if arra and arrb are identical (have the
+     * same length and contain the same integers in the same sequence).
+     *
+     * For full == false returns the result
+     * of haveEqualArrays(arra,arrb,count)
+     *
+     * For full == true, the array lengths must be the same as count
+     *
+     */
+    public static boolean areEqual(int[] arra, int[] arrb, int count,
+                                   boolean full) {
+
+        if (ArrayUtil.haveEqualArrays(arra, arrb, count)) {
+            if (full) {
+                return arra.length == arrb.length && count == arra.length;
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true if the first count elements of arra and arrb are identical
+     * sets of integers (not necessarily in the same order).
+     *
+     */
+    public static boolean haveEqualSets(int[] arra, int[] arrb, int count) {
+
+        if (ArrayUtil.haveEqualArrays(arra, arrb, count)) {
+            return true;
+        }
+
+        if (count > arra.length || count > arrb.length) {
+            return false;
+        }
+
+        if (count == 1) {
+            return arra[0] == arrb[0];
+        }
+
+        int[] tempa = (int[]) resizeArray(arra, count);
+        int[] tempb = (int[]) resizeArray(arrb, count);
+
+        sortArray(tempa);
+        sortArray(tempb);
+
+        for (int j = 0; j < count; j++) {
+            if (tempa[j] != tempb[j]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns true if the first count elements of arra and arrb are identical
+     * subarrays of integers
+     *
+     */
+    public static boolean haveEqualArrays(int[] arra, int[] arrb, int count) {
+
+        if (count > arra.length || count > arrb.length) {
+            return false;
+        }
+
+        for (int j = 0; j < count; j++) {
+            if (arra[j] != arrb[j]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns true if the first count elements of arra and arrb are identical
+     * subarrays of Objects
+     *
+     */
+    public static boolean haveEqualArrays(Object[] arra, Object[] arrb,
+                                          int count) {
+
+        if (count > arra.length || count > arrb.length) {
+            return false;
+        }
+
+        for (int j = 0; j < count; j++) {
+            if (arra[j] != arrb[j]) {
+                if (arra[j] == null || !arra[j].equals(arrb[j])) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns true if arra and arrb share any element. <p>
+     *
+     * Used for checks for any overlap between two arrays of column indexes.
+     */
+    public static boolean haveCommonElement(int[] arra, int[] arrb) {
+
+        for (int i = 0; i < arra.length; i++) {
+            int c = arra[i];
+
+            for (int j = 0; j < arrb.length; j++) {
+                if (c == arrb[j]) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns an int[] containing elements shared between the two arrays
+     * arra and arrb. The arrays contain sets (no value is repeated).
+     *
+     * Used to find the overlap between two arrays of column indexes.
+     * Ordering of the result arrays will be the same as in array
+     * a. The method assumes that each index is only listed
+     * once in the two input arrays.
+     * <p>
+     * e.g.
+     * </p>
+     * <code>
+     * <table width="90%" bgcolor="lightblue">
+     * <tr><td colspane="3">The arrays</td></tr>
+     * <tr><td>int []arra</td><td>=</td><td>{2,11,5,8}</td></tr>
+     * <tr><td>int []arrb</td><td>=</td><td>{20,8,10,11,28,12}</td></tr>
+     * <tr><td colspane="3">will result in:</td></tr>
+     * <tr><td>int []arrc</td><td>=</td><td>{11,8}</td></tr>
+     * </table>
+     *
+     * @param arra int[]; first column indexes
+     * @param arrb int[]; second column indexes
+     * @return int[] common indexes or <code>null</code> if there is no overlap.
+     */
+    public static int[] commonElements(int[] arra, int[] arrb) {
+
+        int[] c = null;
+        int   n = countCommonElements(arra, arrb);
+
+        if (n > 0) {
+            c = new int[n];
+
+            int k = 0;
+
+            for (int i = 0; i < arra.length; i++) {
+                for (int j = 0; j < arrb.length; j++) {
+                    if (arra[i] == arrb[j]) {
+                        c[k++] = arra[i];
+                    }
+                }
+            }
+        }
+
+        return c;
+    }
+
+    /**
+     * Returns the number of elements shared between the two arrays containing
+     * sets.<p>
+     *
+     * Return the number of elements shared by two column index arrays.
+     * This method assumes that each of these arrays contains a set (each
+     * element index is listed only once in each index array). Otherwise the
+     * returned number will NOT represent the number of unique column indexes
+     * shared by both index array.
+     *
+     * @param arra int[]; first array of column indexes.
+     *
+     * @param arrb int[]; second array of column indexes
+     *
+     * @return int; number of elements shared by <code>a</code> and <code>b</code>
+     */
+    public static int countCommonElements(int[] arra, int[] arrb) {
+
+        int k = 0;
+
+        for (int i = 0; i < arra.length; i++) {
+            for (int j = 0; j < arrb.length; j++) {
+                if (arra[i] == arrb[j]) {
+                    k++;
+                }
+            }
+        }
+
+        return k;
+    }
+
+    /**
+     * Returns the count of elements in arra from position start that are
+     * sequentially equal to the elements of arrb.
+     */
+    public static int countSameElements(byte[] arra, int start, byte[] arrb) {
+
+        int k     = 0;
+        int limit = arra.length - start;
+
+        if (limit > arrb.length) {
+            limit = arrb.length;
+        }
+
+        for (int i = 0; i < limit; i++) {
+            if (arra[i + start] == arrb[i]) {
+                k++;
+            } else {
+                break;
+            }
+        }
+
+        return k;
+    }
+
+    /**
+     * Returns the count of elements in arra from position start that are
+     * sequentially equal to the elements of arrb.
+     */
+    public static int countSameElements(char[] arra, int start, char[] arrb) {
+
+        int k     = 0;
+        int limit = arra.length - start;
+
+        if (limit > arrb.length) {
+            limit = arrb.length;
+        }
+
+        for (int i = 0; i < limit; i++) {
+            if (arra[i + start] == arrb[i]) {
+                k++;
+            } else {
+                break;
+            }
+        }
+
+        return k;
+    }
+
+    /**
+     * Returns an array that contains all the elements of the two arrays.
+     */
+    public static int[] union(int[] arra, int[] arrb) {
+
+        int newSize = arra.length + arrb.length
+                      - ArrayUtil.countCommonElements(arra, arrb);
+
+        if (newSize > arra.length && newSize > arrb.length) {
+            int[] arrn = (int[]) ArrayUtil.resizeArray(arrb, newSize);
+            int   pos  = arrb.length;
+
+            mainloop:
+            for (int i = 0; i < arra.length; i++) {
+                for (int j = 0; j < arrb.length; j++) {
+                    if (arra[i] == arrb[j]) {
+                        continue mainloop;
+                    }
+                }
+
+                arrn[pos++] = arra[i];
+            }
+
+            return arrn;
+        }
+
+        return arra.length > arrb.length ? arra
+                                         : arrb;
+    }
+
+    /**
+     * Returns the index of the first occurence of arrb in arra. Or -1 if not found.
+     */
+    public static int find(byte[] arra, int start, int limit, byte[] arrb) {
+
+        int k = start;
+
+        limit = limit - arrb.length + 1;
+
+        int value = arrb[0];
+
+        for (; k < limit; k++) {
+            if (arra[k] == value) {
+                if (arrb.length == 1) {
+                    return k;
+                }
+
+                if (containsAt(arra, k, arrb)) {
+                    return k;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns an index into arra (or -1) where the character is not in the
+     * charset byte array.
+     */
+    public static int findNotIn(byte[] arra, int start, int limit,
+                                byte[] charset) {
+
+        int k = 0;
+
+        for (; k < limit; k++) {
+            for (int i = 0; i < charset.length; i++) {
+                if (arra[k] == charset[i]) {
+                    continue;
+                }
+            }
+
+            return k;
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns an index into arra (or -1) where the character is in the
+     * byteSet byte array.
+     */
+    public static int findIn(byte[] arra, int start, int limit,
+                             byte[] byteSet) {
+
+        int k = 0;
+
+        for (; k < limit; k++) {
+            for (int i = 0; i < byteSet.length; i++) {
+                if (arra[k] == byteSet[i]) {
+                    return k;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns the index of b or c in arra. Or -1 if not found.
+     */
+    public static int find(byte[] arra, int start, int limit, int b, int c) {
+
+        int k = 0;
+
+        for (; k < limit; k++) {
+            if (arra[k] == b || arra[k] == c) {
+                return k;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Set elements of arrb true if their indexes appear in arrb.
+     */
+    public static int[] booleanArrayToIntIndexes(boolean[] arrb) {
+
+        int count = 0;
+
+        for (int i = 0; i < arrb.length; i++) {
+            if (arrb[i]) {
+                count++;
+            }
+        }
+
+        int[] intarr = new int[count];
+
+        count = 0;
+
+        for (int i = 0; i < arrb.length; i++) {
+            if (arrb[i]) {
+                intarr[count++] = i;
+            }
+        }
+
+        return intarr;
+    }
+
+    /**
+     * Set elements of arrb true if their indexes appear in arrb.
+     */
+    public static void intIndexesToBooleanArray(int[] arra, boolean[] arrb) {
+
+        for (int i = 0; i < arra.length; i++) {
+            if (arra[i] < arrb.length) {
+                arrb[arra[i]] = true;
+            }
+        }
+    }
+
+    /**
+     * Return array of indexes of boolean elements that are true.
+     */
+    public static int countStartIntIndexesInBooleanArray(int[] arra,
+            boolean[] arrb) {
+
+        int k = 0;
+
+        for (int i = 0; i < arra.length; i++) {
+            if (arrb[arra[i]]) {
+                k++;
+            } else {
+                break;
+            }
+        }
+
+        return k;
+    }
+
+    public static void orBooleanArray(boolean[] source, boolean[] dest) {
+
+        for (int i = 0; i < dest.length; i++) {
+            dest[i] |= source[i];
+        }
+    }
+
+    public static boolean areAllIntIndexesInBooleanArray(int[] arra,
+            boolean[] arrb) {
+
+        for (int i = 0; i < arra.length; i++) {
+            if (arrb[arra[i]]) {
+                continue;
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+
+    public static boolean isAnyIntIndexInBooleanArray(int[] arra,
+            boolean[] arrb) {
+
+        for (int i = 0; i < arra.length; i++) {
+            if (arrb[arra[i]]) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Return true if for each true element in arrb, the corresponding
+     * element in arra is true
+     */
+    public static boolean containsAllTrueElements(boolean[] arra,
+            boolean[] arrb) {
+
+        for (int i = 0; i < arra.length; i++) {
+            if (arrb[i] && !arra[i]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Return count of true elements in array
+     */
+    public static int countTrueElements(boolean[] arra) {
+
+        int count = 0;
+
+        for (int i = 0; i < arra.length; i++) {
+            if (arra[i]) {
+                count++;
+            }
+        }
+
+        return count;
+    }
+
+    /**
+     * Determines if the array has a null column for any of the positions given
+     * in the rowColMap array.
+     */
+    public static boolean hasNull(Object[] array, int[] columnMap) {
+
+        int count = columnMap.length;
+
+        for (int i = 0; i < count; i++) {
+            if (array[columnMap[i]] == null) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public static boolean hasAllNull(Object[] array, int[] columnMap) {
+
+        int count = columnMap.length;
+
+        for (int i = 0; i < count; i++) {
+            if (array[columnMap[i]] != null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns true if arra from position start contains all elements of arrb
+     * in sequential order.
+     */
+    public static boolean containsAt(byte[] arra, int start, byte[] arrb) {
+        return countSameElements(arra, start, arrb) == arrb.length;
+    }
+
+    /**
+     * Returns the count of elements in arra from position start that are
+     * among the elements of arrb. Stops at any element not in arrb.
+     */
+    public static int countStartElementsAt(byte[] arra, int start,
+                                           byte[] arrb) {
+
+        int k = 0;
+
+        mainloop:
+        for (int i = start; i < arra.length; i++) {
+            for (int j = 0; j < arrb.length; j++) {
+                if (arra[i] == arrb[j]) {
+                    k++;
+
+                    continue mainloop;
+                }
+            }
+
+            break;
+        }
+
+        return k;
+    }
+
+    /**
+     * Returns true if arra from position start contains all elements of arrb
+     * in sequential order.
+     */
+    public static boolean containsAt(char[] arra, int start, char[] arrb) {
+        return countSameElements(arra, start, arrb) == arrb.length;
+    }
+
+    /**
+     * Returns the count of elements in arra from position start that are not
+     * among the elements of arrb.
+     *
+     */
+    public static int countNonStartElementsAt(byte[] arra, int start,
+            byte[] arrb) {
+
+        int k = 0;
+
+        mainloop:
+        for (int i = start; i < arra.length; i++) {
+            for (int j = 0; j < arrb.length; j++) {
+                if (arra[i] == arrb[j]) {
+                    break mainloop;
+                }
+            }
+
+            k++;
+        }
+
+        return k;
+    }
+
+    /**
+     * Convenience wrapper for System.arraycopy().
+     */
+    public static void copyArray(Object source, Object dest, int count) {
+        System.arraycopy(source, 0, dest, 0, count);
+    }
+
+    /**
+     * Returns a range of elements of source from start to end of the array.
+     */
+    public static int[] arraySlice(int[] source, int start, int count) {
+
+        int[] slice = new int[count];
+
+        System.arraycopy(source, start, slice, 0, count);
+
+        return slice;
+    }
+
+    /**
+     * Fills part of the array with a value.
+     */
+    public static void fillArray(char[] array, int offset, char value) {
+
+        int to = array.length;
+
+        while (--to >= offset) {
+            array[to] = value;
+        }
+    }
+
+    /**
+     * Fills the array with a value.
+     */
+    public static void fillArray(Object[] array, Object value) {
+
+        int to = array.length;
+
+        while (--to >= 0) {
+            array[to] = value;
+        }
+    }
+
+    /**
+     * Fills the int array with a value
+     */
+    public static void fillArray(int[] array, int value) {
+
+        int to = array.length;
+
+        while (--to >= 0) {
+            array[to] = value;
+        }
+    }
+
+    /**
+     * Fills the int array with a value
+     */
+    public static void fillArray(boolean[] array, boolean value) {
+        int to = array.length;
+
+        while (--to >= 0) {
+            array[to] = value;
+        }
+    }
+
+    /**
+     * Returns a duplicates of an array.
+     */
+    public static Object duplicateArray(Object source) {
+
+        int size = Array.getLength(source);
+        Object newarray =
+            Array.newInstance(source.getClass().getComponentType(), size);
+
+        System.arraycopy(source, 0, newarray, 0, size);
+
+        return newarray;
+    }
+
+    /**
+     * Returns the given array if newsize is the same as existing.
+     * Returns a new array of given size, containing as many elements of
+     * the original array as it can hold.
+     */
+    public static Object resizeArrayIfDifferent(Object source, int newsize) {
+
+        int oldsize = Array.getLength(source);
+
+        if (oldsize == newsize) {
+            return source;
+        }
+
+        Object newarray =
+            Array.newInstance(source.getClass().getComponentType(), newsize);
+
+        if (oldsize < newsize) {
+            newsize = oldsize;
+        }
+
+        System.arraycopy(source, 0, newarray, 0, newsize);
+
+        return newarray;
+    }
+
+    /**
+     * Returns a new array of given size, containing as many elements of
+     * the original array as it can hold. N.B. Always returns a new array
+     * even if newsize parameter is the same as the old size.
+     */
+    public static Object resizeArray(Object source, int newsize) {
+
+        Object newarray =
+            Array.newInstance(source.getClass().getComponentType(), newsize);
+        int oldsize = Array.getLength(source);
+
+        if (oldsize < newsize) {
+            newsize = oldsize;
+        }
+
+        System.arraycopy(source, 0, newarray, 0, newsize);
+
+        return newarray;
+    }
+
+    /**
+     * Returns an array containing the elements of parameter source, with one
+     * element removed or added. Parameter adjust {-1, +1} indicates the
+     * operation. Parameter colindex indicates the position at which an element
+     * is removed or added. Parameter addition is an Object to add when
+     * adjust is +1.
+     */
+    public static Object toAdjustedArray(Object source, Object addition,
+                                         int colindex, int adjust) {
+
+        int newsize = Array.getLength(source) + adjust;
+        Object newarray =
+            Array.newInstance(source.getClass().getComponentType(), newsize);
+
+        copyAdjustArray(source, newarray, addition, colindex, adjust);
+
+        return newarray;
+    }
+
+    /**
+     *  Copies elements of source to dest. If adjust is -1 the element at
+     *  colindex is not copied. If adjust is +1 that element is filled with
+     *  the Object addition. All the rest of the elements in source are
+     *  shifted left or right accordingly when they are copied. If adjust is 0
+     *  the addition is copied over the element at colindex.
+     *
+     *  No checks are perfomed on array sizes and an exception is thrown
+     *  if they are not consistent with the other arguments.
+     */
+    public static void copyAdjustArray(Object source, Object dest,
+                                       Object addition, int colindex,
+                                       int adjust) {
+
+        int length = Array.getLength(source);
+
+        if (colindex < 0) {
+            System.arraycopy(source, 0, dest, 0, length);
+
+            return;
+        }
+
+        System.arraycopy(source, 0, dest, 0, colindex);
+
+        if (adjust == 0) {
+            int endcount = length - colindex - 1;
+
+            Array.set(dest, colindex, addition);
+
+            if (endcount > 0) {
+                System.arraycopy(source, colindex + 1, dest, colindex + 1,
+                                 endcount);
+            }
+        } else if (adjust < 0) {
+            int endcount = length - colindex - 1;
+
+            if (endcount > 0) {
+                System.arraycopy(source, colindex + 1, dest, colindex,
+                                 endcount);
+            }
+        } else {
+            int endcount = length - colindex;
+
+            Array.set(dest, colindex, addition);
+
+            if (endcount > 0) {
+                System.arraycopy(source, colindex, dest, colindex + 1,
+                                 endcount);
+            }
+        }
+    }
+
+    /**
+     * Returns a new array with the elements in collar adjusted to reflect
+     * changes at colindex. <p>
+     *
+     * Each element in collarr represents an index into another array
+     * otherarr. <p>
+     *
+     * colindex is the index at which an element is added or removed.
+     * Each element in the result array represents the new,
+     * adjusted index. <p>
+     *
+     * For each element of collarr that represents an index equal to
+     * colindex and adjust is -1, the result will not contain that element
+     * and will be shorter than collar by one element.
+     *
+     * @param  colarr the source array
+     * @param  colindex index at which to perform adjustement
+     * @param  adjust +1, 0 or -1
+     * @return new, adjusted array
+     */
+    public static int[] toAdjustedColumnArray(int[] colarr, int colindex,
+            int adjust) {
+
+        if (colarr == null) {
+            return null;
+        }
+
+        if (colindex < 0) {
+            return colarr;
+        }
+
+        int[] intarr = new int[colarr.length];
+        int   j      = 0;
+
+        for (int i = 0; i < colarr.length; i++) {
+            if (colarr[i] > colindex) {
+                intarr[j] = colarr[i] + adjust;
+
+                j++;
+            } else if (colarr[i] == colindex) {
+                if (adjust < 0) {
+
+                    // skip an element from colarr
+                } else {
+                    intarr[j] = colarr[i] + adjust;
+
+                    j++;
+                }
+            } else {
+                intarr[j] = colarr[i];
+
+                j++;
+            }
+        }
+
+        if (colarr.length != j) {
+            int[] newarr = new int[j];
+
+            copyArray(intarr, newarr, j);
+
+            return newarr;
+        }
+
+        return intarr;
+    }
+
+    /**
+     *  Copies some elements of row into newRow by using columnMap as
+     *  the list of indexes into row. <p>
+     *
+     *  columnMap and newRow are of equal length and are normally
+     *  shorter than row. <p>
+     *
+     *  @param row the source array
+     *  @param columnMap the list of indexes into row
+     *  @param newRow the destination array
+     */
+    public static void projectRow(Object[] row, int[] columnMap,
+                                  Object[] newRow) {
+
+        for (int i = 0; i < columnMap.length; i++) {
+            newRow[i] = row[columnMap[i]];
+        }
+    }
+
+    public static void projectRow(int[] row, int[] columnMap, int[] newRow) {
+
+        for (int i = 0; i < columnMap.length; i++) {
+            newRow[i] = row[columnMap[i]];
+        }
+    }
+
+    /**
+     *  As above but copies in reverse direction. <p>
+     *
+     *  @param row the target array
+     *  @param columnMap the list of indexes into row
+     *  @param newRow the source array
+     */
+    public static void projectRowReverse(Object[] row, int[] columnMap,
+                                         Object[] newRow) {
+
+        for (int i = 0; i < columnMap.length; i++) {
+            row[columnMap[i]] = newRow[i];
+        }
+    }
+
+/*
+    public static void copyColumnValues(int[] row, int[] colindex,
+                                        int[] colobject) {
+
+        for (int i = 0; i < colindex.length; i++) {
+            colobject[i] = row[colindex[i]];
+        }
+    }
+
+    public static void copyColumnValues(boolean[] row, int[] colindex,
+                                        boolean[] colobject) {
+
+        for (int i = 0; i < colindex.length; i++) {
+            colobject[i] = row[colindex[i]];
+        }
+    }
+
+    public static void copyColumnValues(byte[] row, int[] colindex,
+                                        byte[] colobject) {
+
+        for (int i = 0; i < colindex.length; i++) {
+            colobject[i] = row[colindex[i]];
+        }
+    }
+*/
+    public static void projectMap(int[] mainMap, int[] subMap,
+                                  int[] newSubMap) {
+
+        for (int i = 0; i < subMap.length; i++) {
+            for (int j = 0; j < mainMap.length; j++) {
+                if (subMap[i] == mainMap[j]) {
+                    newSubMap[i] = j;
+
+                    break;
+                }
+            }
+        }
+    }
+
+    public static void fillSequence(int[] colindex) {
+
+        for (int i = 0; i < colindex.length; i++) {
+            colindex[i] = i;
+        }
+    }
+
+    public static char[] byteArrayToChars(byte[] bytes) {
+
+        char[] chars = new char[bytes.length / 2];
+
+        for (int i = 0, j = 0; j < chars.length; i += 2, j++) {
+            chars[j] = (char) ((bytes[i] << 8) + (bytes[i + 1] & 0xff));
+        }
+
+        return chars;
+    }
+
+    public static byte[] charArrayToBytes(char[] chars) {
+
+        byte[] bytes = new byte[chars.length * 2];
+
+        for (int i = 0, j = 0; j < chars.length; i += 2, j++) {
+            int c = chars[j];
+
+            bytes[i]     = (byte) (c >> 8);
+            bytes[i + 1] = (byte) c;
+        }
+
+        return bytes;
+    }
+
+    /**
+     * returns true if arra contains all elements of arrb
+     *
+     * @param arra Object[]
+     * @param arrb Object[]
+     */
+    public static boolean containsAll(Object[] arra, Object[] arrb) {
+
+        mainLoop:
+        for (int i = 0; i < arrb.length; i++) {
+            for (int j = 0; j < arra.length; j++) {
+                if (arrb[i] == arra[j] || arrb[i].equals(arra[j])) {
+                    continue mainLoop;
+                }
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * returns true if arra contains any element of arrb
+     *
+     * @param arra Object[]
+     * @param arrb Object[]
+     */
+    public static boolean containsAny(Object[] arra, Object[] arrb) {
+
+        mainLoop:
+        for (int i = 0; i < arrb.length; i++) {
+            for (int j = 0; j < arra.length; j++) {
+                if (arrb[i] == arra[j] || arrb[i].equals(arra[j])) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * returns true if arra contains all elements of arrb
+     *
+     * @param arra int[]
+     * @param arrb int[]
+     */
+    public static boolean containsAll(int[] arra, int[] arrb) {
+
+        mainLoop:
+        for (int i = 0; i < arrb.length; i++) {
+            for (int j = 0; j < arra.length; j++) {
+                if (arrb[i] == arra[j]) {
+                    continue mainLoop;
+                }
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/lib/BaseList.java b/src/org/hsqldb/lib/BaseList.java
new file mode 100644
index 0000000..f521b0a
--- /dev/null
+++ b/src/org/hsqldb/lib/BaseList.java
@@ -0,0 +1,205 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Abstract base for Lists
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+abstract class BaseList {
+
+    protected int elementCount;
+
+    abstract Object get(int index);
+
+    abstract Object remove(int index);
+
+    abstract boolean add(Object o);
+
+    abstract int size();
+
+    public boolean contains(Object o) {
+        return indexOf(o) == -1 ? false
+                             : true;
+    }
+
+    public boolean remove(Object o) {
+
+        int i = indexOf(o);
+
+        if (i == -1) {
+            return false;
+        }
+
+        remove(i);
+
+        return true;
+    }
+
+    public int indexOf(Object o) {
+
+        for (int i = 0, size = size(); i < size; i++) {
+            Object current = get(i);
+
+            if (current == null) {
+                if (o == null) {
+                    return i;
+                }
+            } else if (current.equals(o)) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    public boolean addAll(Collection other) {
+
+        boolean  result = false;
+        Iterator it     = other.iterator();
+
+        while (it.hasNext()) {
+            result = true;
+
+            add(it.next());
+        }
+
+        return result;
+    }
+
+    public boolean addAll(Object[] array) {
+
+        boolean  result = false;
+        for (int i = 0; i < array.length; i++) {
+            result = true;
+
+            add(array[i]);
+        }
+
+        return result;
+    }
+
+    public boolean isEmpty() {
+        return elementCount == 0;
+    }
+
+    /** Returns a string representation */
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer(32 + elementCount * 3);
+
+        sb.append("List : size=");
+        sb.append(elementCount);
+        sb.append(' ');
+        sb.append('{');
+
+        Iterator it = iterator();
+
+        while (it.hasNext()) {
+            sb.append(it.next());
+
+            if (it.hasNext()) {
+                sb.append(',');
+                sb.append(' ');
+            }
+        }
+
+        sb.append('}');
+
+        return sb.toString();
+    }
+
+    public Iterator iterator() {
+        return new BaseListIterator();
+    }
+
+    private class BaseListIterator implements Iterator {
+
+        int     counter = 0;
+        boolean removed;
+
+        public boolean hasNext() {
+            return counter < elementCount;
+        }
+
+        public Object next() {
+
+            if (counter < elementCount) {
+                removed = false;
+
+                Object returnValue = get(counter);
+
+                counter++;
+
+                return returnValue;
+            }
+
+            throw new NoSuchElementException();
+        }
+
+        public int nextInt() {
+            throw new NoSuchElementException();
+        }
+
+        public long nextLong() {
+            throw new NoSuchElementException();
+        }
+
+        public void remove() {
+
+            if (removed) {
+                throw new NoSuchElementException("Iterator");
+            }
+
+            removed = true;
+
+            if (counter != 0) {
+                BaseList.this.remove(counter - 1);
+
+                counter--;    // above can throw, so decrement if successful
+
+                return;
+            }
+
+            throw new NoSuchElementException();
+        }
+
+        public void setValue(Object value) {
+            throw new NoSuchElementException();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/BasicTextJdkLogFormatter.java b/src/org/hsqldb/lib/BasicTextJdkLogFormatter.java
new file mode 100644
index 0000000..3edd429
--- /dev/null
+++ b/src/org/hsqldb/lib/BasicTextJdkLogFormatter.java
@@ -0,0 +1,84 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.StringWriter;
+import java.io.PrintWriter;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * An implementation of java.util.logging.Formatter very close to
+ * SimpleFormatter.
+ *
+ * The features here are optional timestamping, sortable numeric time stamp
+ * text, and no indication of invoking source code location (logger ID,
+ * class name, method name, etc.).
+ *
+ * @see Formatter
+ * @see SimpleFormatter
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class BasicTextJdkLogFormatter extends Formatter {
+    protected boolean withTime = true;
+    public static String LS = System.getProperty("line.separator");
+
+    protected SimpleDateFormat sdf =
+            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+
+
+    public BasicTextJdkLogFormatter(boolean withTime) {
+        this.withTime = withTime;
+    }
+
+    public BasicTextJdkLogFormatter() {
+        // Intentionally empty
+    }
+
+    public String format(LogRecord record) {
+        StringBuilder sb = new StringBuilder();
+        if (withTime) {
+            sb.append(sdf.format(new Date(record.getMillis())) + "  ");
+        }
+        sb.append(record.getLevel() + "  " + formatMessage(record));
+        if (record.getThrown() != null) {
+            StringWriter sw = new StringWriter();
+            record.getThrown().printStackTrace(new PrintWriter(sw));
+            sb.append(LS + sw);
+        }
+        return sb.toString() + LS;
+        // This uses platform-specific line-separator, the same as
+        // SimpleLogger does.
+    }
+}
diff --git a/src/org/hsqldb/lib/CharArrayWriter.java b/src/org/hsqldb/lib/CharArrayWriter.java
new file mode 100644
index 0000000..734bebb
--- /dev/null
+++ b/src/org/hsqldb/lib/CharArrayWriter.java
@@ -0,0 +1,160 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.EOFException;
+
+/**
+ * A writer for char strings.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class CharArrayWriter {
+
+    protected char[] buffer;
+    protected int    count;
+
+    public CharArrayWriter(char[] buffer) {
+        this.buffer = buffer;
+    }
+
+    public CharArrayWriter(Reader reader, int length) throws IOException {
+
+        buffer = new char[length];
+
+        for (int left = length; left > 0; ) {
+            int read = reader.read(buffer, count, left);
+
+            if (read == -1) {
+                if (left > 0) {
+                    reader.close();
+
+                    throw new EOFException();
+                }
+
+                break;
+            }
+
+            left  -= read;
+            count += read;
+        }
+    }
+
+    public CharArrayWriter(Reader reader) throws IOException {
+
+        buffer = new char[128];
+
+        for (;;) {
+            int read = reader.read(buffer, count, buffer.length - count);
+
+            if (read == -1) {
+                break;
+            }
+
+            count += read;
+
+            if (count == buffer.length) {
+                ensureRoom(128);
+            }
+        }
+    }
+
+    public void write(int c) {
+
+        if (count == buffer.length) {
+            ensureRoom(count + 1);
+        }
+
+        buffer[count++] = (char) c;
+    }
+
+    void ensureRoom(int size) {
+
+        if (size <= buffer.length) {
+            return;
+        }
+
+        int newSize = buffer.length;
+
+        while (newSize < size) {
+            newSize *= 2;
+        }
+
+        char[] newBuffer = new char[newSize];
+
+        System.arraycopy(buffer, 0, newBuffer, 0, count);
+
+        buffer = newBuffer;
+    }
+
+    public void write(String str, int off, int len) {
+
+        ensureRoom(count + len);
+        str.getChars(off, off + len, buffer, count);
+
+        count += len;
+    }
+
+    public void reset() {
+        count = 0;
+    }
+
+    public void reset(char[] buffer) {
+        count       = 0;
+        this.buffer = buffer;
+    }
+
+    public char[] toCharArray() {
+
+        char[] newBuffer = new char[count];
+
+        System.arraycopy(buffer, 0, newBuffer, 0, count);
+
+        return (char[]) newBuffer;
+    }
+
+    public int size() {
+        return count;
+    }
+
+    /**
+     * Converts input data to a string.
+     * @return the string.
+     */
+    public String toString() {
+        return new String(buffer, 0, count);
+    }
+}
diff --git a/src/org/hsqldb/lib/ClosableByteArrayOutputStream.java b/src/org/hsqldb/lib/ClosableByteArrayOutputStream.java
new file mode 100644
index 0000000..d5c1399
--- /dev/null
+++ b/src/org/hsqldb/lib/ClosableByteArrayOutputStream.java
@@ -0,0 +1,456 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+/* $Id: ClosableByteArrayOutputStream.java 2946 2009-03-22 17:44:48Z fredt $ */
+
+/**
+ * @todo - finer-grained synchronization to reduce average
+ * potential monitor contention
+ */
+
+/**
+ * Provides true Closable semantics ordinarily missing in a
+ * {@link java.io.ByteArrayOutputStream}. <p>
+ *
+ * Accumulates output in a byte array that automatically grows as needed.<p>
+ *
+ * Data is retrieved using <tt>toByteArray()</tt>,
+ * <tt>toByteArrayInputStream()</tt>, <tt>toString()</tt> and
+ * <tt>toString(encoding)</tt>. <p>
+ *
+ * {@link #close() Closing} a <tt>ClosableByteArrayOutputStream</tt> prevents
+ * further write operations, but all other operations may succeed until after
+ * the first invocation of {@link #free() free()}.<p>
+ *
+ * Freeing a <tt>ClosableByteArrayOutputStream</tt> closes the stream and
+ * releases the internal buffer, preventing successful invocation of all
+ * operations, with the exception of <tt>size()<tt>, <tt>close()</tt>,
+ * <tt>isClosed()</tt>, <tt>free()</tt> and <tt>isFreed()</tt>. <p>
+ *
+ * This class is especially useful when an accumulating output stream must be
+ * handed off to an extenal client under contract that the stream should
+ * exhibit true Closable behaviour in response both to internally tracked
+ * events and to client invocation of the <tt>OutputStream.close()</tt> method.
+ *
+ * @author boucherb@users
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ClosableByteArrayOutputStream extends OutputStream {
+
+    /**
+     * Data buffer.
+     */
+    protected byte[] buf;
+
+    /**
+     * # of valid bytes in buffer.
+     */
+    protected int count;
+
+    /**
+     * Whether this stream is closed.
+     */
+    protected boolean closed;
+
+    /**
+     * Whether this stream is freed.
+     */
+    protected boolean freed;
+
+    /**
+     * Creates a new output stream. <p>
+     *
+     * The buffer capacity is initially 32 bytes, though its size increases
+     * if necessary.
+     */
+    public ClosableByteArrayOutputStream() {
+        this(32);
+    }
+
+    /**
+     * Creates a new output stream with a buffer capacity of the specified
+     * <tt>size</tt>, in bytes.
+     *
+     * @param size the initial size.
+     * @exception IllegalArgumentException if size is negative.
+     */
+    public ClosableByteArrayOutputStream(int size)
+    throws IllegalArgumentException {
+
+        if (size < 0) {
+            throw new IllegalArgumentException("Negative initial size: "
+                                               + size);    // NOI18N
+        }
+
+        buf = new byte[size];
+    }
+
+    /**
+     * Writes the specified single byte.
+     *
+     * @param b the single byte to be written.
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #close() closed}.
+     */
+    public synchronized void write(int b) throws IOException {
+
+        checkClosed();
+
+        int newcount = count + 1;
+
+        if (newcount > buf.length) {
+            buf = copyOf(buf, Math.max(buf.length << 1, newcount));
+        }
+
+        buf[count] = (byte) b;
+        count      = newcount;
+    }
+
+    /**
+     * Writes the specified portion of the designated octet sequence. <p>
+     *
+     * @param b the data.
+     * @param off the start offset in the data.
+     * @param len the number of bytes to write.
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #close() closed}.
+     */
+    public synchronized void write(byte b[], int off,
+                                   int len) throws IOException {
+
+        checkClosed();
+
+        if ((off < 0) || (off > b.length) || (len < 0)
+                || ((off + len) > b.length) || ((off + len) < 0)) {
+            throw new IndexOutOfBoundsException();
+        } else if (len == 0) {
+            return;
+        }
+
+        int newcount = count + len;
+
+        if (newcount > buf.length) {
+            buf = copyOf(buf, Math.max(buf.length << 1, newcount));
+        }
+
+        System.arraycopy(b, off, buf, count, len);
+
+        count = newcount;
+    }
+
+    /**
+     * By default, does nothing. <p>
+     *
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #close() closed}.
+     */
+    public void flush() throws IOException {
+        checkClosed();
+    }
+
+    /**
+     * Writes the complete contents of this stream's accumulated data to the
+     * specified output stream. <p>
+     *
+     * The operation occurs as if by calling <tt>out.write(buf, 0, count)</tt>.
+     *
+     * @param out the output stream to which to write the data.
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #free() freed}.
+     */
+    public synchronized void writeTo(OutputStream out) throws IOException {
+        checkFreed();
+        out.write(buf, 0, count);
+    }
+
+    /**
+     * Returns the current capacity of this stream's data buffer.
+     *
+     * @return  the length of the internal data array
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #free() freed}.
+     */
+    public synchronized int capacity() throws IOException {
+
+        checkFreed();
+
+        return buf.length;
+    }
+
+    /**
+     * Resets the <tt>count</tt> field of this output stream to zero, so that
+     * all currently accumulated data is effectively discarded. <p>
+     *
+     * Further write operations will reuse the allocated buffer space. <p>
+     *
+     * @see #count
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #close() closed}.
+     */
+    public synchronized void reset() throws IOException {
+
+        checkClosed();
+
+        count = 0;
+    }
+
+    /**
+     * Attempts to reduce this stream's capacity to its current size. <p>
+     *
+     * If the data buffer is larger than necessary to hold its current sequence
+     * of bytes, then it may be resized to become more space efficient.
+     * Calling this method may, but is not required to, affect the value
+     * returned by a subsequent call to the {@link #capacity()} method. <p>
+     *
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #free() freed}.
+     */
+    public synchronized void trimToSize() throws IOException {
+
+        checkFreed();
+
+        if (buf.length > count) {
+            buf = copyOf(buf, count);
+        }
+    }
+
+    /**
+     * Retrieves a copy of this stream's accumated data, as a byte array.
+     *
+     * @return a copy of this stream's accumated data, as a byte array.
+     * @see #size()
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #free() freed}.
+     */
+    public synchronized byte[] toByteArray() throws IOException {
+
+        checkFreed();
+
+        return copyOf(buf, count);
+    }
+
+    /**
+     * Returns the current size of this stream's accumated data.
+     *
+     * @return the value of the <tt>count</tt> field, which is the number
+     *      of valid bytes in this output stream.
+     * @see #count
+     * @throws java.io.IOException never
+     */
+    public synchronized int size() throws IOException {
+        return count;
+    }
+
+    /**
+     * Sets the size of this stream's accumulated data. <p>
+     *
+     * @param   newSize the new size
+     * @throws  ArrayIndexOutOfBoundsException if new size is negative
+     */
+    public synchronized void setSize(int newSize) {
+
+        if (newSize < 0) {
+            throw new ArrayIndexOutOfBoundsException(newSize);
+        } else if (newSize > buf.length) {
+            buf = copyOf(buf, Math.max(buf.length << 1, newSize));
+        }
+
+        count = newSize;
+    }
+
+    /**
+     * Performs an effecient (zero-copy) conversion of the data accumulated in
+     * this output stream to an input stream. <p>
+     *
+     * To ensure the future integrity of the resulting input stream, {@link
+     * #free() free} is invoked upon this output stream as a side-effect.
+     *
+     * @return an input stream representing this output stream's accumulated
+     *      data
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #free() freed}.
+     */
+    public synchronized ByteArrayInputStream toByteArrayInputStream()
+    throws IOException {
+
+        checkFreed();
+
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(buf, 0,
+            count);
+
+        free();
+
+        return inputStream;
+    }
+
+    /**
+     * Converts this stream's accumuated data into a string, translating bytes
+     * into characters according to the platform's default character encoding.
+     *
+     * @return String translated from this stream's accumuated data.
+     * @throws RuntimeException may be thrown if this output stream has been
+     *      {@link #free() freed}.
+     */
+    public synchronized String toString() {
+
+        try {
+            checkFreed();
+        } catch (IOException ex) {
+            throw new RuntimeException(ex.toString());
+        }
+
+        return new String(buf, 0, count);
+    }
+
+    /**
+     * Converts this stream's accumuated data into a string, translating bytes
+     * into characters according to the specified character encoding.
+     *
+     * @return String translated from the buffer's contents.
+     * @param enc a character-encoding name.
+     * @throws java.io.IOException may be thrown if this output stream has been
+     *      {@link #free() freed}.
+     * @throws UnsupportedEncodingException If the named encoding is not
+     *      supported.
+     */
+    public synchronized String toString(String enc)
+    throws IOException, UnsupportedEncodingException {
+
+        checkFreed();
+
+        return new String(buf, 0, count, enc);
+    }
+
+    /**
+     * Closes this object for further writing. <p>
+     *
+     * Other operations may continue to succeed until after the first invocation
+     * of {@link #free() free()}. <p>
+     *
+     * @throws java.io.IOException if an I/O error occurs (default: never)
+     */
+    public synchronized void close() throws IOException {
+        closed = true;
+    }
+
+    /**
+     * Retrieves whether this stream is closed. <p>
+     * @return <tt>true</tt> if this stream is closed, else <tt>false</tt>
+     */
+    public synchronized boolean isClosed() {
+        return closed;
+    }
+
+    /**
+     * Closes this object and releases the underlying buffer for
+     * garbage collection. <p>
+     *
+     * @throws java.io.IOException if an I/O error occurs while closing
+     *      this stream (default: never).
+     */
+    public synchronized void free() throws IOException {
+
+        closed = true;
+        freed  = true;
+        buf    = null;
+        count  = 0;
+    }
+
+    /**
+     * Retrieves whether this stream is freed. <p>
+     *
+     * @return <tt>true</tt> if this stream is freed; else <tt>false</tt>.
+     */
+    public synchronized boolean isFreed() {
+        return freed;
+    }
+
+    /**
+     * Tests whether this stream is closed. <p>
+     *
+     * @throws java.io.IOException if this stream is closed.
+     */
+    protected synchronized void checkClosed() throws IOException {
+
+        if (closed) {
+
+            throw new IOException("stream is closed.");    // NOI18N
+        }
+    }
+
+    /**
+     * Tests whether this stream is freed. <p>
+     *
+     * @throws java.io.IOException if this stream is freed.
+     */
+    protected synchronized void checkFreed() throws IOException {
+
+        if (freed) {
+            throw new IOException("stream buffer is freed.");    // NOI18N
+        }
+    }
+
+    /**
+     * Retrieves a copy of <tt>original</tt> with the given
+     * <tt>newLength</tt>. <p>
+     *
+     * @param original the object to copy
+     * @param newLength the length of the copy
+     * @return copy of <tt>original</tt> with the given <tt>newLength</tt>
+     */
+    protected byte[] copyOf(byte[] original, int newLength) {
+
+        byte[] copy = new byte[newLength];
+
+        System.arraycopy(original, 0, copy, 0,
+                         Math.min(original.length, newLength));
+
+        return copy;
+    }
+}
diff --git a/src/org/hsqldb/lib/ClosableCharArrayWriter.java b/src/org/hsqldb/lib/ClosableCharArrayWriter.java
new file mode 100644
index 0000000..bd118b6
--- /dev/null
+++ b/src/org/hsqldb/lib/ClosableCharArrayWriter.java
@@ -0,0 +1,463 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * @todo - finer-grained synchronization to reduce average
+ * potential monitor contention
+ */
+
+/**
+ * Provides Closable semantics ordinarily missing in a
+ * {@link java.io.CharArrayWriter}. <p>
+ *
+ * Accumulates output in a character array that automatically grows as needed.<p>
+ *
+ * Data is retrieved using <tt>toCharArray()</tt>, <tt>toCharArrayReader()</tt>
+ * and <tt>toString()</tt>. <p>
+ *
+ * {@link #close() Closing} a <tt>ClosableCharArrayWriter</tt> prevents
+ * further write operations, but all other operations will succeed until after
+ * the first invocation of {@link #free() free()}.<p>
+ *
+ * Freeing a <tt>ClosableCharArrayWriter</tt> closes the writer and
+ * releases its internal buffer, preventing successful invocation of all
+ * operations, with the exception of <tt>size()<tt>, <tt>close()</tt>,
+ * <tt>isClosed()</tt>, <tt>free()</tt> and <tt>isFreed()</tt>. <p>
+ *
+ * This class is especially useful when an accumulating writer must be
+ * handed off to an extenal client under contract that the writer should
+ * exhibit true Closable behaviour, both in response to internally tracked
+ * events and to client invocation of the <tt>Writer.close()</tt> method.
+ *
+ * @author boucherb@users
+ * @version 1.8.x
+ * @since 1.8.x
+ */
+public class ClosableCharArrayWriter extends Writer {
+
+    /**
+     * Data buffer.
+     */
+    protected char[] buf;
+
+    /**
+     * # of valid characters in buffer.
+     */
+    protected int count;
+
+    /**
+     * Whether this writer is closed.
+     */
+    protected boolean closed;
+
+    /**
+     * Whether this writer is freed.
+     */
+    protected boolean freed;
+
+    /**
+     * Creates a new writer. <p>
+     *
+     * The buffer capacity is initially 32 characters, although its size
+     * automatically increases when necessary.
+     */
+    public ClosableCharArrayWriter() {
+        this(32);
+    }
+
+    /**
+     * Creates a new writer with a buffer capacity of the specified
+     * <tt>size</tt>, in characters.
+     *
+     * @param size the initial size.
+     * @exception IllegalArgumentException if <tt>size</tt> is negative.
+     */
+    public ClosableCharArrayWriter(int size) throws IllegalArgumentException {
+
+        if (size < 0) {
+            throw new IllegalArgumentException("Negative initial size: "
+                                               + size);    // NOI18N
+        }
+
+        buf = new char[size];
+    }
+
+    /**
+     * Writes the specified single character.
+     *
+     * @param c the single character to be written.
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this writer has been {@link #close() closed}.
+     */
+    public synchronized void write(int c) throws IOException {
+
+        checkClosed();
+
+        int newcount = count + 1;
+
+        if (newcount > buf.length) {
+            buf = copyOf(buf, Math.max(buf.length << 1, newcount));
+        }
+
+        buf[count] = (char) c;
+        count      = newcount;
+    }
+
+    /**
+     * Writes the designated portion of the designated character array <p>.
+     *
+     * @param c the source character sequence.
+     * @param off the start offset in the source character sequence.
+     * @param len the number of characters to write.
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this writer has been {@link #close() closed}.
+     */
+    public synchronized void write(char c[], int off,
+                                   int len) throws IOException {
+
+        checkClosed();
+
+        if ((off < 0) || (off > c.length) || (len < 0)
+                || ((off + len) > c.length) || ((off + len) < 0)) {
+            throw new IndexOutOfBoundsException();
+        } else if (len == 0) {
+            return;
+        }
+
+        int newcount = count + len;
+
+        if (newcount > buf.length) {
+            buf = copyOf(buf, Math.max(buf.length << 1, newcount));
+        }
+
+        System.arraycopy(c, off, buf, count, len);
+
+        count = newcount;
+    }
+
+    /**
+     * Efficiently writes the designated portion of the designated string. <p>
+     *
+     * The operation occurs as if by calling
+     * <tt>str.getChars(off, off + len, buf, count)</tt>. <p>
+     *
+     * @param str the string from which to write
+     * @param off the start offset in the string.
+     * @param len the number of characters to write.
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this writer has been {@link #close() closed}.
+     */
+    public synchronized void write(String str, int off,
+                                   int len) throws IOException {
+
+        checkClosed();
+
+        int strlen = str.length();
+
+        if ((off < 0) || (off > strlen) || (len < 0) || ((off + len) > strlen)
+                || ((off + len) < 0)) {
+            throw new IndexOutOfBoundsException();
+        } else if (len == 0) {
+            return;
+        }
+
+        int newcount = count + len;
+
+        if (newcount > buf.length) {
+            buf = copyOf(buf, Math.max(buf.length << 1, newcount));
+        }
+
+        str.getChars(off, off + len, buf, count);
+
+        count = newcount;
+    }
+
+    /**
+     * By default, does nothing. <p>
+     *
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this writer has been {@link #close() closed}.
+     */
+    public void flush() throws IOException {
+        checkClosed();
+    }
+
+    /**
+     * Writes the complete contents of this writer's buffered data to the
+     * specified writer. <p>
+     *
+     * The operation occurs as if by calling <tt>out.write(buf, 0, count)</tt>.
+     *
+     * @param out the writer to which to write the data.
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this writer has been {@link #free() freed}.
+     */
+    public synchronized void writeTo(Writer out) throws IOException {
+
+        checkFreed();
+
+        if (count > 0) {
+            out.write(buf, 0, count);
+        }
+    }
+
+    /**
+     * Returns the current capacity of this writer's data buffer.
+     *
+     * @return  the current capacity (the length of the internal
+     *          data array)
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this writer has been {@link #free() freed}.
+     */
+    public synchronized int capacity() throws IOException {
+
+        checkFreed();
+
+        return buf.length;
+    }
+
+    /**
+     * Resets the <tt>count</tt> field of this writer to zero, so that all
+     * currently accumulated output is effectively discarded. Further write
+     * operations will reuse the allocated buffer space.
+     *
+     * @see #count
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this output stream has been {@link #close() closed}.
+     */
+    public synchronized void reset() throws IOException {
+
+        checkClosed();
+
+        count = 0;
+    }
+
+    /**
+     * Attempts to reduce this writer's buffer capacity to its current size. <p>
+     *
+     * If the buffer is larger than necessary to hold its current sequence of
+     * characters, then it may be resized to become more space efficient.
+     * Calling this method may, but is not required to, affect the value
+     * returned by a subsequent call to the {@link #capacity()} method.
+     */
+    public synchronized void trimToSize() throws IOException {
+
+        checkFreed();
+
+        if (buf.length > count) {
+            buf = copyOf(buf, count);
+        }
+    }
+
+    /**
+     * Creates a newly allocated character array. Its size is the current
+     * size of this writer and the valid contents of the buffer
+     * have been copied into it.
+     *
+     * @return the current contents of this writer, as a character array.
+     * @see #size()
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this writer has been {@link #free() freed}.
+     */
+    public synchronized char[] toCharArray() throws IOException {
+
+        checkFreed();
+
+        return copyOf(buf, count);
+    }
+
+    /**
+     * Returns the current size of this writer's accumulated character data.
+     *
+     * @return the value of the <tt>count</tt> field, which is the number
+     *      of valid characters accumulated in this writer.
+     * @see #count
+     * @throws java.io.IOException never
+     */
+    public synchronized int size() throws IOException {
+        return count;
+    }
+
+    /**
+     * Sets the size of this writer's accumulated character data. <p>
+     *
+     * @param   newSize the new size of this writer's accumulated data
+     * @throws  ArrayIndexOutOfBoundsException if new size is negative
+     */
+    public synchronized void setSize(int newSize) {
+
+        if (newSize < 0) {
+            throw new ArrayIndexOutOfBoundsException(newSize);
+        } else if (newSize > buf.length) {
+            buf = copyOf(buf, Math.max(buf.length << 1, newSize));
+        }
+
+        count = newSize;
+    }
+
+    /**
+     * Performs an effecient (zero-copy) conversion of the character data
+     * accumulated in this writer to a reader. <p>
+     *
+     * To ensure the integrity of the resulting reader, {@link #free()
+     * free} is invoked upon this writer as a side-effect.
+     *
+     * @return a reader representing this writer's accumulated
+     *      character data
+     * @throws java.io.IOException if an I/O error occurs.
+     *      In particular, an <tt>IOException</tt> may be thrown
+     *      if this writer has been {@link #free() freed}.
+     */
+    public synchronized CharArrayReader toCharArrayReader()
+    throws IOException {
+
+        checkFreed();
+
+        CharArrayReader reader = new CharArrayReader(buf, 0, count);
+
+        //System.out.println("toCharArrayReader::buf.length: " + buf.length);
+        free();
+
+        return reader;
+    }
+
+    /**
+     * Converts this writer's accumulated data into a string.
+     *
+     * @return String constructed from this writer's accumulated data
+     * @throws RuntimeException may be thrown if this writer has been
+     *      {@link #free() freed}.
+     */
+    public synchronized String toString() {
+
+        try {
+            checkFreed();
+        } catch (IOException ex) {
+            throw new RuntimeException(ex.toString());
+        }
+
+        return new String(buf, 0, count);
+    }
+
+    /**
+     * Closes this object for further writing. <p>
+     *
+     * Other operations may continue to succeed until after the first invocation
+     * of {@link #free() free()}. <p>
+     *
+     * @throws java.io.IOException if an I/O error occurs (default: never)
+     */
+    public synchronized void close() throws IOException {
+        closed = true;
+    }
+
+    /**
+     * @return <tt>true</tt> if this writer is closed, else <tt>false</tt>
+     */
+    public synchronized boolean isClosed() {
+        return closed;
+    }
+
+    /**
+     * Closes this object and releases the underlying buffer for
+     * garbage collection. <p>
+     *
+     * @throws java.io.IOException if an I/O error occurs while closing
+     *      this writer (default: never).
+     */
+    public synchronized void free() throws IOException {
+
+        closed = true;
+        freed  = true;
+        buf    = null;
+        count  = 0;
+    }
+
+    /**
+     * @return <tt>true</tt> if this writer is freed; else <tt>false</tt>.
+     */
+    public synchronized boolean isFreed() {
+        return freed;
+    }
+
+    /**
+     * @throws java.io.IOException if this writer is closed.
+     */
+    protected synchronized void checkClosed() throws IOException {
+
+        if (closed) {
+            throw new IOException("writer is closed.");    // NOI18N
+        }
+    }
+
+    /**
+     * @throws java.io.IOException if this writer is freed.
+     */
+    protected synchronized void checkFreed() throws IOException {
+
+        if (freed) {
+            throw new IOException("write buffer is freed.");    // NOI18N
+        }
+    }
+
+    /**
+     * Retrieves a copy of <tt>original</tt> with the given
+     * <tt>newLength</tt>. <p>
+     *
+     * @param original the object to copy
+     * @param newLength the length of the copy
+     * @return copy of <tt>original</tt> with the given <tt>newLength</tt>
+     */
+    protected char[] copyOf(char[] original, int newLength) {
+
+        char[] copy = new char[newLength];
+
+        System.arraycopy(original, 0, copy, 0,
+                         Math.min(original.length, newLength));
+
+        return copy;
+    }
+}
diff --git a/src/org/hsqldb/lib/Collection.java b/src/org/hsqldb/lib/Collection.java
new file mode 100644
index 0000000..570198d
--- /dev/null
+++ b/src/org/hsqldb/lib/Collection.java
@@ -0,0 +1,71 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public interface Collection {
+
+    int size();
+
+    boolean isEmpty();
+
+    boolean contains(Object o);
+
+    Iterator iterator();
+
+/*
+    Object[] toArray();
+    Object[] toArray(Object a[]);
+*/
+    boolean add(Object o);
+
+    boolean remove(Object o);
+
+    boolean addAll(Collection c);
+
+/*
+    boolean containsAll(Collection c);
+    boolean removeAll(Collection c);
+    boolean retainAll(Collection c);
+*/
+    void clear();
+
+/*
+    boolean equals(Object o);
+*/
+    int hashCode();
+}
diff --git a/src/org/hsqldb/lib/CountUpDownLatch.java b/src/org/hsqldb/lib/CountUpDownLatch.java
new file mode 100644
index 0000000..dca0c12
--- /dev/null
+++ b/src/org/hsqldb/lib/CountUpDownLatch.java
@@ -0,0 +1,88 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.concurrent.CountDownLatch;
+
+public class CountUpDownLatch {
+
+    CountDownLatch latch;
+    int            count;
+
+    public CountUpDownLatch() {
+        latch      = new CountDownLatch(1);
+    }
+
+    public void await() throws InterruptedException {
+
+        if (count == 0) {
+            return;
+        }
+
+        latch.await();
+    }
+
+    public void countDown() {
+
+        count--;
+
+        if (count == 0) {
+            latch.countDown();
+        }
+    }
+
+    public long getCount() {
+        return count;
+    }
+
+    public void countUp() {
+
+        if (latch.getCount() == 0) {
+            latch = new CountDownLatch(1);
+        }
+
+        count++;
+    }
+
+    public void setCount(int count) {
+
+        if (count == 0) {
+            if (latch.getCount() != 0) {
+                latch.countDown();
+            }
+        } else if (latch.getCount() == 0) {
+            latch = new CountDownLatch(1);
+        }
+
+        this.count = count;
+    }
+}
diff --git a/src/org/hsqldb/lib/CountdownInputStream.java b/src/org/hsqldb/lib/CountdownInputStream.java
new file mode 100644
index 0000000..99a64e1
--- /dev/null
+++ b/src/org/hsqldb/lib/CountdownInputStream.java
@@ -0,0 +1,131 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+// fredt@users - 1.9.0 corrected read(byte[], int, int)
+
+/**
+ * Counts down from a specified value the number of bytes actually read
+ * from the wrapped InputStream. <p>
+ *
+ * Returns minus one (-1) early from readXXX methods if the count
+ * down reaches zero (0) before the end of the wrapped InputStream
+ * is encountered. <p>
+ *
+ * This class is especially useful when a fixed number of bytes is to be read
+ * from an InputStream that is in turn to be used as the source for an
+ * {@link java.io.InputStreamReader InputStreamReader}.
+ *
+ * @author boucherb@users
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class CountdownInputStream extends InputStream {
+
+    private long        count;
+    private InputStream input;
+
+    public CountdownInputStream(final InputStream is) {
+        this.input = is;
+    }
+
+    public int read() throws IOException {
+
+        if (this.count <= 0) {
+            return -1;
+        }
+
+        final int b = this.input.read();
+
+        if (b >= 0) {
+            this.count--;
+        }
+
+        return b;
+    }
+
+    public int read(final byte[] buf) throws IOException {
+
+        if (this.count <= 0) {
+            return -1;
+        }
+
+        int len = buf.length;
+
+        if (len > this.count) {
+            len = (int) this.count;
+        }
+
+        final int r = this.input.read(buf, 0, len);
+
+        if (r > 0) {
+            this.count -= r;
+        }
+
+        return r;
+    }
+
+    public int read(final byte[] buf, final int off,
+                    int len) throws IOException {
+
+        if (this.count <= 0) {
+            return -1;
+        }
+
+        if (len > this.count) {
+            len = (int) this.count;
+        }
+
+        final int r = this.input.read(buf, off, len);
+
+        if (r > 0) {
+            this.count -= r;
+        }
+
+        return r;
+    }
+
+    public void close() throws IOException {
+        this.input.close();
+    }
+
+    public long getCount() {
+        return this.count;
+    }
+
+    public void setCount(long count) {
+        this.count = count;
+    }
+}
diff --git a/src/org/hsqldb/lib/DataOutputStream.java b/src/org/hsqldb/lib/DataOutputStream.java
new file mode 100644
index 0000000..d3951df
--- /dev/null
+++ b/src/org/hsqldb/lib/DataOutputStream.java
@@ -0,0 +1,149 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+
+/**
+ * A wrapper for OutputStream
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class DataOutputStream extends java.io.BufferedOutputStream {
+
+    byte[] tempBuffer = new byte[8];
+
+    public DataOutputStream(OutputStream stream) {
+        super(stream, 8);
+    }
+
+    public final void writeByte(int v) throws IOException {
+        write(v);
+    }
+
+    public final void writeInt(int v) throws IOException {
+
+        int count = 0;
+
+        tempBuffer[count++] = (byte) (v >>> 24);
+        tempBuffer[count++] = (byte) (v >>> 16);
+        tempBuffer[count++] = (byte) (v >>> 8);
+        tempBuffer[count++] = (byte) v;
+
+        write(tempBuffer, 0, count);
+    }
+
+    public final void writeLong(long v) throws IOException {
+        writeInt((int) (v >>> 32));
+        writeInt((int) v);
+    }
+
+    public void writeChar(int v) throws IOException {
+
+        int count = 0;
+
+        tempBuffer[count++] = (byte) (v >>> 8);
+        tempBuffer[count++] = (byte) v;
+
+        write(tempBuffer, 0, count);
+    }
+
+    public void writeChars(String s) throws IOException {
+
+        int len = s.length();
+
+        for (int i = 0; i < len; i++) {
+            int v     = s.charAt(i);
+            int count = 0;
+
+            tempBuffer[count++] = (byte) (v >>> 8);
+            tempBuffer[count++] = (byte) v;
+
+            write(tempBuffer, 0, count);
+        }
+    }
+
+    public void writeChars(char[] c) throws IOException {
+        writeChars(c, c.length);
+    }
+
+    public void writeChars(char[] c, int length) throws IOException {
+
+        for (int i = 0; i < length; i++) {
+            int v     = c[i];
+            int count = 0;
+
+            tempBuffer[count++] = (byte) (v >>> 8);
+            tempBuffer[count++] = (byte) v;
+
+            write(tempBuffer, 0, count);
+        }
+    }
+
+    public void write(Reader reader, long length) throws IOException {
+
+        InputStream inputStream = new ReaderInputStream(reader);
+
+        write(inputStream, length * 2);
+    }
+
+    public void write(InputStream inputStream,
+                      long length) throws IOException {
+
+        CountdownInputStream countStream =
+            new CountdownInputStream(inputStream);
+
+        countStream.setCount(length);
+
+        byte[] data = new byte[128];
+
+        while (true) {
+            int count = countStream.read(data);
+
+            if (count < 1) {
+                if (countStream.getCount() != 0) {
+                    throw new EOFException();
+                }
+
+                break;
+            }
+
+            write(data, 0, count);
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/DoubleIntIndex.java b/src/org/hsqldb/lib/DoubleIntIndex.java
new file mode 100644
index 0000000..1448f15
--- /dev/null
+++ b/src/org/hsqldb/lib/DoubleIntIndex.java
@@ -0,0 +1,692 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Maintains an ordered  integer->integer lookup table, consisting of two
+ * columns, one for keys, the other for values.
+ *
+ * The table is sorted on either the key or value column, depending on the calls to
+ * setKeysSearchTarget() or setValuesSearchTarget(). By default, the table is
+ * sorted on values.<p>
+ *
+ * findXXX() methods return the array index into the list
+ * pair containing a matching key or value, or  or -1 if not found.<p>
+ *
+ * Sorting methods originally contributed by Tony Lai.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.8.0
+ */
+public class DoubleIntIndex implements IntLookup {
+
+    private int           count = 0;
+    private int           capacity;
+    private boolean       sorted       = true;
+    private boolean       sortOnValues = true;
+    private boolean       hasChanged;
+    private final boolean fixedSize;
+    private int[]         keys;
+    private int[]         values;
+
+//
+    private int targetSearchValue;
+
+    public DoubleIntIndex(int capacity, boolean fixedSize) {
+
+        this.capacity  = capacity;
+        keys           = new int[capacity];
+        values         = new int[capacity];
+        this.fixedSize = fixedSize;
+        hasChanged     = true;
+    }
+
+    public synchronized int getKey(int i) {
+
+        if (i < 0 || i >= count) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        return keys[i];
+    }
+
+    public synchronized int getValue(int i) {
+
+        if (i < 0 || i >= count) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        return values[i];
+    }
+
+    /**
+     * Modifies an existing pair.
+     * @param i the index
+     * @param key the key
+     */
+    public synchronized void setKey(int i, int key) {
+
+        if (i < 0 || i >= count) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        if (!sortOnValues) {
+            sorted = false;
+        }
+
+        keys[i] = key;
+    }
+
+    /**
+     * Modifies an existing pair.
+     * @param i the index
+     * @param value the value
+     */
+    public synchronized void setValue(int i, int value) {
+
+        if (i < 0 || i >= count) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        if (sortOnValues) {
+            sorted = false;
+        }
+
+        values[i] = value;
+    }
+
+    public synchronized int size() {
+        return count;
+    }
+
+    public synchronized int capacity() {
+        return capacity;
+    }
+
+    /**
+     * Adds a pair into the table.
+     *
+     * @param key the key
+     * @param value the value
+     * @return true or false depending on success
+     */
+    public synchronized boolean addUnsorted(int key, int value) {
+
+        if (count == capacity) {
+            if (fixedSize) {
+                return false;
+            } else {
+                doubleCapacity();
+            }
+        }
+
+        if (sorted && count != 0) {
+            if (sortOnValues) {
+                if (value < values[count - 1]) {
+                    sorted = false;
+                }
+            } else {
+                if (key < keys[count - 1]) {
+                    sorted = false;
+                }
+            }
+        }
+
+        hasChanged    = true;
+        keys[count]   = key;
+        values[count] = value;
+
+        count++;
+
+        return true;
+    }
+
+    /**
+     * Adds a key, value pair into the table with the guarantee that the key
+     * is equal or larger than the largest existing key. This prevents a sort
+     * from taking place on next call to find()
+     *
+     * @param key the key
+     * @param value the value
+     * @return true or false depending on success
+     */
+    public synchronized boolean addSorted(int key, int value) {
+
+        if (count == capacity) {
+            if (fixedSize) {
+                return false;
+            } else {
+                doubleCapacity();
+            }
+        }
+
+        if (count != 0) {
+            if (sortOnValues) {
+                if (value < values[count - 1]) {
+                    return false;
+                }
+            } else {
+                if (key < keys[count - 1]) {
+                    return false;
+                }
+            }
+        }
+
+        hasChanged    = true;
+        keys[count]   = key;
+        values[count] = value;
+
+        count++;
+
+        return true;
+    }
+
+    /**
+     * Adds a pair, ensuring no duplicate key xor value already exists in the
+     * current search target column.
+     * @param key the key
+     * @param value the value
+     * @return true or false depending on success
+     */
+    public synchronized boolean addUnique(int key, int value) {
+
+        if (count == capacity) {
+            if (fixedSize) {
+                return false;
+            } else {
+                doubleCapacity();
+            }
+        }
+
+        if (!sorted) {
+            fastQuickSort();
+        }
+
+        targetSearchValue = sortOnValues ? value
+                                         : key;
+
+        int i = binaryEmptySlotSearch();
+
+        if (i == -1) {
+            return false;
+        }
+
+        hasChanged = true;
+
+        if (count != i) {
+            moveRows(i, i + 1, count - i);
+        }
+
+        keys[i]   = key;
+        values[i] = value;
+
+        count++;
+
+        return true;
+    }
+
+    /**
+     * Adds a pair, maintaining sorted order
+     * current search target column.
+     * @param key the key
+     * @param value the value
+     * @return true or false depending on success
+     */
+    public synchronized int add(int key, int value) {
+
+        if (count == capacity) {
+            if (fixedSize) {
+                return -1;
+            } else {
+                doubleCapacity();
+            }
+        }
+
+        if (!sorted) {
+            fastQuickSort();
+        }
+
+        targetSearchValue = sortOnValues ? value
+                                         : key;
+
+        int i = binarySlotSearch();
+
+        if (i == -1) {
+            return i;
+        }
+
+        hasChanged = true;
+
+        if (count != i) {
+            moveRows(i, i + 1, count - i);
+        }
+
+        keys[i]   = key;
+        values[i] = value;
+
+        count++;
+
+        return i;
+    }
+
+    public int lookupFirstEqual(int key) throws NoSuchElementException {
+
+        if (sortOnValues) {
+            sorted       = false;
+            sortOnValues = false;
+        }
+
+        int i = findFirstEqualKeyIndex(key);
+
+        if (i == -1) {
+            throw new NoSuchElementException();
+        }
+
+        return getValue(i);
+    }
+
+    public int lookupFirstGreaterEqual(int key) throws NoSuchElementException {
+
+        if (sortOnValues) {
+            sorted       = false;
+            sortOnValues = false;
+        }
+
+        int i = findFirstGreaterEqualKeyIndex(key);
+
+        if (i == -1) {
+            throw new NoSuchElementException();
+        }
+
+        return getValue(i);
+    }
+
+    public synchronized void setValuesSearchTarget() {
+
+        if (!sortOnValues) {
+            sorted = false;
+        }
+
+        sortOnValues = true;
+    }
+
+    public synchronized void setKeysSearchTarget() {
+
+        if (sortOnValues) {
+            sorted = false;
+        }
+
+        sortOnValues = false;
+    }
+
+    /**
+     * @param value the value
+     * @return the index
+     */
+    public synchronized int findFirstGreaterEqualKeyIndex(int value) {
+
+        int index = findFirstGreaterEqualSlotIndex(value);
+
+        return index == count ? -1
+                              : index;
+    }
+
+    /**
+     * @param value the value
+     * @return the index
+     */
+    public synchronized int findFirstEqualKeyIndex(int value) {
+
+        if (!sorted) {
+            fastQuickSort();
+        }
+
+        targetSearchValue = value;
+
+        return binaryFirstSearch();
+    }
+
+    /**
+     * This method is similar to findFirstGreaterEqualKeyIndex(int) but
+     * returns the index of the empty row past the end of the array if
+     * the search value is larger than all the values / keys in the searched
+     * column.
+     * @param value the value
+     * @return the index
+     */
+    public synchronized int findFirstGreaterEqualSlotIndex(int value) {
+
+        if (!sorted) {
+            fastQuickSort();
+        }
+
+        targetSearchValue = value;
+
+        return binarySlotSearch();
+    }
+
+    /**
+     * Returns the index of the lowest element == the given search target,
+     * or -1
+     * @return index or -1 if not found
+     */
+    private int binaryFirstSearch() {
+
+        int low     = 0;
+        int high    = count;
+        int mid     = 0;
+        int compare = 0;
+        int found   = count;
+
+        while (low < high) {
+            mid     = (low + high) / 2;
+            compare = compare(mid);
+
+            if (compare < 0) {
+                high = mid;
+            } else if (compare > 0) {
+                low = mid + 1;
+            } else {
+                high  = mid;
+                found = mid;
+            }
+        }
+
+        return found == count ? -1
+                              : found;
+    }
+
+    /**
+     * Returns the index of the lowest element > the given search target
+     *     @return the index
+     */
+    private int binaryGreaterSearch() {
+
+        int low     = 0;
+        int high    = count;
+        int mid     = 0;
+        int compare = 0;
+
+        while (low < high) {
+            mid     = (low + high) / 2;
+            compare = compare(mid);
+
+            if (compare < 0) {
+                high = mid;
+            } else {
+                low = mid + 1;
+            }
+        }
+
+        return low == count ? -1
+                            : low;
+    }
+
+    /**
+     * Returns the index of the lowest element >= the given search target,
+     * or count
+     *     @return the index
+     */
+    private int binarySlotSearch() {
+
+        int low     = 0;
+        int high    = count;
+        int mid     = 0;
+        int compare = 0;
+
+        while (low < high) {
+            mid     = (low + high) / 2;
+            compare = compare(mid);
+
+            if (compare <= 0) {
+                high = mid;
+            } else {
+                low = mid + 1;
+            }
+        }
+
+        return low;
+    }
+
+    /**
+     * Returns the index of the lowest element > the given search target
+     * or count or -1 if target is found
+     * @return the index
+     */
+    private int binaryEmptySlotSearch() {
+
+        int low     = 0;
+        int high    = count;
+        int mid     = 0;
+        int compare = 0;
+
+        while (low < high) {
+            mid     = (low + high) / 2;
+            compare = compare(mid);
+
+            if (compare < 0) {
+                high = mid;
+            } else if (compare > 0) {
+                low = mid + 1;
+            } else {
+                return -1;
+            }
+        }
+
+        return low;
+    }
+
+    private synchronized void fastQuickSort() {
+
+        quickSort(0, count - 1);
+        insertionSort(0, count - 1);
+
+        sorted = true;
+    }
+
+    private void quickSort(int l, int r) {
+
+        int M = 16;
+        int i;
+        int j;
+        int v;
+
+        if ((r - l) > M) {
+            i = (r + l) / 2;
+
+            if (lessThan(i, l)) {
+                swap(l, i);    // Tri-Median Methode!
+            }
+
+            if (lessThan(r, l)) {
+                swap(l, r);
+            }
+
+            if (lessThan(r, i)) {
+                swap(i, r);
+            }
+
+            j = r - 1;
+
+            swap(i, j);
+
+            i = l;
+            v = j;
+
+            for (;;) {
+                while (lessThan(++i, v)) {}
+
+                while (lessThan(v, --j)) {}
+
+                if (j < i) {
+                    break;
+                }
+
+                swap(i, j);
+            }
+
+            swap(i, r - 1);
+            quickSort(l, j);
+            quickSort(i + 1, r);
+        }
+    }
+
+    private void insertionSort(int lo0, int hi0) {
+
+        int i;
+        int j;
+
+        for (i = lo0 + 1; i <= hi0; i++) {
+            j = i;
+
+            while ((j > lo0) && lessThan(i, j - 1)) {
+                j--;
+            }
+
+            if (i != j) {
+                moveAndInsertRow(i, j);
+            }
+        }
+    }
+
+    protected void moveAndInsertRow(int i, int j) {
+
+        int col1 = keys[i];
+        int col2 = values[i];
+
+        moveRows(j, j + 1, i - j);
+
+        keys[j]   = col1;
+        values[j] = col2;
+    }
+
+    protected void swap(int i1, int i2) {
+
+        int col1 = keys[i1];
+        int col2 = values[i1];
+
+        keys[i1]   = keys[i2];
+        values[i1] = values[i2];
+        keys[i2]   = col1;
+        values[i2] = col2;
+    }
+
+    /**
+     * Check if targeted column value in the row indexed i is less than the
+     * search target object.
+     * @param i the index
+     * @return -1, 0 or +1
+     */
+    protected int compare(int i) {
+
+        if (sortOnValues) {
+            if (targetSearchValue > values[i]) {
+                return 1;
+            } else if (targetSearchValue < values[i]) {
+                return -1;
+            }
+        } else {
+            if (targetSearchValue > keys[i]) {
+                return 1;
+            } else if (targetSearchValue < keys[i]) {
+                return -1;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Check if row indexed i is less than row indexed j
+     * @param i the first index
+     * @param j the second index
+     * @return true or false
+     */
+    protected boolean lessThan(int i, int j) {
+
+        if (sortOnValues) {
+            if (values[i] < values[j]) {
+                return true;
+            }
+        } else {
+            if (keys[i] < keys[j]) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    protected void moveRows(int fromIndex, int toIndex, int rows) {
+        System.arraycopy(keys, fromIndex, keys, toIndex, rows);
+        System.arraycopy(values, fromIndex, values, toIndex, rows);
+    }
+
+    protected void doubleCapacity() {
+
+        keys     = (int[]) ArrayUtil.resizeArray(keys, capacity * 2);
+        values   = (int[]) ArrayUtil.resizeArray(values, capacity * 2);
+        capacity *= 2;
+    }
+
+    public void removeRange(int start, int limit) {
+
+        moveRows(limit, start, count - limit);
+
+        count -= (limit - start);
+    }
+
+    public void removeAll() {
+
+        hasChanged = true;
+
+        ArrayUtil.clearArray(ArrayUtil.CLASS_CODE_INT, keys, 0, count);
+        ArrayUtil.clearArray(ArrayUtil.CLASS_CODE_INT, values, 0, count);
+
+        count = 0;
+    }
+
+    public final synchronized void remove(int position) {
+
+        hasChanged = true;
+
+        moveRows(position + 1, position, count - position - 1);
+
+        count--;
+
+        keys[count]   = 0;
+        values[count] = 0;
+    }
+}
diff --git a/src/org/hsqldb/lib/FileAccess.java b/src/org/hsqldb/lib/FileAccess.java
new file mode 100644
index 0000000..998a2a6
--- /dev/null
+++ b/src/org/hsqldb/lib/FileAccess.java
@@ -0,0 +1,71 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Interface for abstraction of file access.
+ *
+ * @author  Ocke Janssen oj@openoffice.org
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+public interface FileAccess {
+
+    int ELEMENT_READ         = 1;
+    int ELEMENT_SEEKABLEREAD = 3;
+    int ELEMENT_WRITE        = 4;
+    int ELEMENT_READWRITE    = 7;
+    int ELEMENT_TRUNCATE     = 8;
+
+    InputStream openInputStreamElement(java.lang.String streamName)
+    throws java.io.IOException;
+
+    OutputStream openOutputStreamElement(java.lang.String streamName)
+    throws java.io.IOException;
+
+    boolean isStreamElement(java.lang.String elementName);
+
+    void createParentDirs(java.lang.String filename);
+
+    void removeElement(java.lang.String filename);
+
+    void renameElement(java.lang.String oldName, java.lang.String newName);
+
+    public interface FileSync {
+        void sync() throws java.io.IOException;
+    }
+
+    FileSync getFileSync(OutputStream os) throws java.io.IOException;
+}
diff --git a/src/org/hsqldb/lib/FileArchiver.java b/src/org/hsqldb/lib/FileArchiver.java
new file mode 100644
index 0000000..3f63031
--- /dev/null
+++ b/src/org/hsqldb/lib/FileArchiver.java
@@ -0,0 +1,242 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+
+import org.hsqldb.lib.java.JavaSystem;
+
+/**
+ * Creates a direct, compressed or decompressed copy of a file.
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class FileArchiver {
+
+    public static final int  COMPRESSION_NONE = 0;
+    public static final int  COMPRESSION_ZIP  = 1;
+    public static final int  COMPRESSION_GZIP = 2;
+    private static final int COPY_BLOCK_SIZE  = 1 << 16;
+
+    /*
+    public static void compressFile(String infilename, String outfilename,
+                                    FileAccess storage) throws IOException {
+        FileArchiver.archive(infilename, outfilename, storage, COMPRESSION_ZIP);
+    }
+
+    public static void decompressFile(String infilename, String outfilename,
+                                      FileAccess storage) throws IOException {
+        FileArchiver.unarchive(
+                infilename, outfilename, storage, COMPRESSION_ZIP);
+    }
+
+    public static void copyFile(String infilename, String outfilename,
+                                    FileAccess storage) throws IOException {
+        FileArchiver.archive(
+                infilename, outfilename, storage, COMPRESSION_NONE);
+    }
+
+    public static void restoreFile(String infilename, String outfilename,
+                                      FileAccess storage) throws IOException {
+        FileArchiver.unarchive(
+                infilename, outfilename, storage, COMPRESSION_NONE);
+    }
+    */
+    public static void archive(String infilename, String outfilename,
+                               FileAccess storage,
+                               int compressionType) throws IOException {
+
+        InputStream          in        = null;
+        OutputStream         f         = null;
+        OutputStream         fOut      = null;
+        DeflaterOutputStream deflater  = null;
+        boolean              completed = false;
+
+        // if there is no file
+        if (!storage.isStreamElement(infilename)) {
+            return;
+        }
+
+        try {
+            byte[] b = new byte[COPY_BLOCK_SIZE];
+
+            in   = storage.openInputStreamElement(infilename);
+            f    = storage.openOutputStreamElement(outfilename);
+            fOut = f;
+
+            switch (compressionType) {
+
+                case COMPRESSION_ZIP :
+                    f = deflater = new DeflaterOutputStream(f,
+                            new Deflater(Deflater.BEST_SPEED), b.length);
+                    break;
+
+                case COMPRESSION_GZIP :
+                    f = deflater = new GZIPOutputStream(f, b.length);
+                    break;
+
+                case COMPRESSION_NONE :
+                    break;
+
+                default :
+                    throw new RuntimeException("FileArchiver"
+                                               + compressionType);
+            }
+
+            while (true) {
+                int l = in.read(b, 0, b.length);
+
+                if (l == -1) {
+                    break;
+                }
+
+                f.write(b, 0, l);
+            }
+
+            completed = true;
+        } catch (Throwable e) {
+            throw JavaSystem.toIOException(e);
+        } finally {
+            try {
+                if (in != null) {
+                    in.close();
+                }
+
+                if (f != null) {
+                    if (deflater != null) {
+                        deflater.finish();
+                    }
+
+                    if (fOut instanceof FileOutputStream) {
+                        storage.getFileSync(fOut).sync();
+                    }
+
+                    f.close();
+                }
+
+                if (!completed && storage.isStreamElement(outfilename)) {
+                    storage.removeElement(outfilename);
+                }
+            } catch (Throwable e) {
+                throw JavaSystem.toIOException(e);
+            }
+        }
+    }
+
+    public static void unarchive(String infilename, String outfilename,
+                                 FileAccess storage,
+                                 int compressionType) throws IOException {
+
+        InputStream  f         = null;
+        OutputStream outstream = null;
+        boolean      completed = false;
+
+        try {
+            if (!storage.isStreamElement(infilename)) {
+                return;
+            }
+
+            storage.removeElement(outfilename);
+
+            byte[] b = new byte[COPY_BLOCK_SIZE];
+
+            f = storage.openInputStreamElement(infilename);
+
+            switch (compressionType) {
+
+                case COMPRESSION_ZIP :
+                    f = new InflaterInputStream(f, new Inflater());
+                    break;
+
+                case COMPRESSION_GZIP :
+                    f = new GZIPInputStream(f, b.length);
+                    break;
+
+                case COMPRESSION_NONE :
+                    break;
+
+                default :
+                    throw new RuntimeException("FileArchiver: "
+                                               + compressionType);
+            }
+
+            outstream = storage.openOutputStreamElement(outfilename);
+
+            while (true) {
+                int l = f.read(b, 0, b.length);
+
+                if (l == -1) {
+                    break;
+                }
+
+                outstream.write(b, 0, l);
+            }
+
+            completed = true;
+        } catch (Throwable e) {
+            throw JavaSystem.toIOException(e);
+        } finally {
+            try {
+                if (f != null) {
+                    f.close();
+                }
+
+                if (outstream != null) {
+                    outstream.flush();
+
+                    if (outstream instanceof FileOutputStream) {
+                        storage.getFileSync(outstream).sync();
+                    }
+
+                    outstream.close();
+                }
+
+                if (!completed && storage.isStreamElement(outfilename)) {
+                    storage.removeElement(outfilename);
+                }
+            } catch (Throwable e) {
+                throw JavaSystem.toIOException(e);
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/FileUtil.java b/src/org/hsqldb/lib/FileUtil.java
new file mode 100644
index 0000000..738b0bf
--- /dev/null
+++ b/src/org/hsqldb/lib/FileUtil.java
@@ -0,0 +1,358 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Random;
+
+import org.hsqldb.lib.java.JavaSystem;
+
+/**
+ * A collection of file management methods.<p>
+ * Also provides the default FileAccess implementation
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @author Ocke Janssen oj@openoffice.org
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class FileUtil implements FileAccess {
+
+    private static FileUtil      fileUtil      = new FileUtil();
+    private static FileAccessRes fileAccessRes = new FileAccessRes();
+
+    /** Creates a new instance of FileUtil */
+    FileUtil() {}
+
+    public static FileUtil getFileUtil() {
+        return fileUtil;
+    }
+
+    public static FileAccess getFileAccess(boolean isResource) {
+        return isResource ? (FileAccess) fileAccessRes
+                          : (FileAccess) fileUtil;
+    }
+
+    public boolean isStreamElement(java.lang.String elementName) {
+        return (new File(elementName)).exists();
+    }
+
+    public InputStream openInputStreamElement(java.lang.String streamName)
+    throws java.io.IOException {
+
+        try {
+            return new FileInputStream(new File(streamName));
+        } catch (Throwable e) {
+            throw JavaSystem.toIOException(e);
+        }
+    }
+
+    public void createParentDirs(String filename) {
+        makeParentDirectories(new File(filename));
+    }
+
+    public void removeElement(String filename) {
+
+        if (isStreamElement(filename)) {
+            delete(filename);
+        }
+    }
+
+    public void renameElement(java.lang.String oldName,
+                              java.lang.String newName) {
+        renameWithOverwrite(oldName, newName);
+    }
+
+    public java.io.OutputStream openOutputStreamElement(
+            java.lang.String streamName) throws java.io.IOException {
+        return new FileOutputStream(new File(streamName));
+    }
+
+    // end of FileAccess implementation
+    // a new File("...")'s path is not canonicalized, only resolved
+    // and normalized (e.g. redundant separator chars removed),
+    // so as of JDK 1.4.2, this is a valid test for case insensitivity,
+    // at least when it is assumed that we are dealing with a configuration
+    // that only needs to consider the host platform's native file system,
+    // even if, unlike for File.getCanonicalPath(), (new File("a")).exists() or
+    // (new File("A")).exits(), regardless of the hosting system's
+    // file path case sensitivity policy.
+    public final boolean fsIsIgnoreCase =
+        (new File("A")).equals(new File("a"));
+
+    // posix separator normalized to File.separator?
+    // CHECKME: is this true for every file system under Java?
+    public final boolean fsNormalizesPosixSeparator =
+        (new File("/")).getPath().endsWith(File.separator);
+
+    // for JDK 1.1 createTempFile
+    final Random random = new Random(System.currentTimeMillis());
+
+    /**
+     * Delete the named file
+     */
+    public boolean delete(String filename) {
+        return (new File(filename)).delete();
+    }
+
+    /**
+     * Requests, in a JDK 1.1 compliant way, that the file or directory denoted
+     * by the given abstract pathname be deleted when the virtual machine
+     * terminates. <p>
+     *
+     * Deletion will be attempted only for JDK 1.2 and greater runtime
+     * environments and only upon normal termination of the virtual
+     * machine, as defined by the Java Language Specification. <p>
+     *
+     * Once deletion has been sucessfully requested, it is not possible to
+     * cancel the request. This method should therefore be used with care. <p>
+     *
+     * @param f the abstract pathname of the file be deleted when the virtual
+     *       machine terminates
+     */
+    public void deleteOnExit(File f) {
+        JavaSystem.deleteOnExit(f);
+    }
+
+    /**
+     * Return true or false based on whether the named file exists.
+     */
+    public boolean exists(String filename) {
+        return (new File(filename)).exists();
+    }
+
+    public boolean exists(String fileName, boolean resource, Class cla) {
+
+        if (fileName == null || fileName.length() == 0) {
+            return false;
+        }
+
+        return resource ? null != cla.getResource(fileName)
+                        : FileUtil.getFileUtil().exists(fileName);
+    }
+
+    /**
+     * Rename the file with oldname to newname. If a file with newname already
+     * exists, it is deleted before the renaming operation proceeds.
+     *
+     * If a file with oldname does not exist, no file will exist after the
+     * operation.
+     */
+    private boolean renameWithOverwrite(String oldname, String newname) {
+
+        File    file    = new File(oldname);
+        boolean renamed = file.renameTo(new File(newname));
+
+        if (renamed) {
+            return true;
+        }
+
+        if (delete(newname)) {
+            return file.renameTo(new File(newname));
+        }
+
+        return false;
+    }
+
+    /**
+     * Retrieves the absolute path, given some path specification.
+     *
+     * @param path the path for which to retrieve the absolute path
+     * @return the absolute path
+     */
+    public String absolutePath(String path) {
+        return (new File(path)).getAbsolutePath();
+    }
+
+    /**
+     * Retrieves the canonical file for the given file, in a
+     * JDK 1.1 complaint way.
+     *
+     * @param f the File for which to retrieve the absolute File
+     * @return the canonical File
+     */
+    public File canonicalFile(File f) throws IOException {
+        return new File(f.getCanonicalPath());
+    }
+
+    /**
+     * Retrieves the canonical file for the given path, in a
+     * JDK 1.1 complaint way.
+     *
+     * @param path the path for which to retrieve the canonical File
+     * @return the canonical File
+     */
+    public File canonicalFile(String path) throws IOException {
+        return new File(new File(path).getCanonicalPath());
+    }
+
+    /**
+     * Retrieves the canonical path for the given File, in a
+     * JDK 1.1 complaint way.
+     *
+     * @param f the File for which to retrieve the canonical path
+     * @return the canonical path
+     */
+    public String canonicalPath(File f) throws IOException {
+        return f.getCanonicalPath();
+    }
+
+    /**
+     * Retrieves the canonical path for the given path, in a
+     * JDK 1.1 complaint way.
+     *
+     * @param path the path for which to retrieve the canonical path
+     * @return the canonical path
+     */
+    public String canonicalPath(String path) throws IOException {
+        return new File(path).getCanonicalPath();
+    }
+
+    /**
+     * Retrieves the canonical path for the given path, or the absolute
+     * path if attemting to retrieve the canonical path fails.
+     *
+     * @param path the path for which to retrieve the canonical or
+     *      absolute path
+     * @return the canonical or absolute path
+     */
+    public String canonicalOrAbsolutePath(String path) {
+
+        try {
+            return canonicalPath(path);
+        } catch (Exception e) {
+            return absolutePath(path);
+        }
+    }
+
+    public void makeParentDirectories(File f) {
+
+        String parent = f.getParent();
+
+        if (parent != null) {
+            new File(parent).mkdirs();
+        } else {
+
+            // workaround for jdk 1.1 bug (returns null when there is a parent)
+            parent = f.getPath();
+
+            int index = parent.lastIndexOf('/');
+
+            if (index > 0) {
+                parent = parent.substring(0, index);
+
+                new File(parent).mkdirs();
+            }
+        }
+    }
+
+    public static String makeDirectories(String path) {
+
+        try {
+            File file = new File(path);
+
+            file.mkdirs();
+
+            return file.getCanonicalPath();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    public FileAccess.FileSync getFileSync(java.io.OutputStream os)
+    throws java.io.IOException {
+        return new FileSync((FileOutputStream) os);
+    }
+
+    public static class FileSync implements FileAccess.FileSync {
+
+        FileDescriptor outDescriptor;
+
+        FileSync(FileOutputStream os) throws IOException {
+            outDescriptor = os.getFD();
+        }
+
+        public void sync() throws IOException {
+            outDescriptor.sync();
+        }
+    }
+
+    public static class FileAccessRes implements FileAccess {
+
+        public boolean isStreamElement(String elementName) {
+            return getClass().getResource(elementName) != null;
+        }
+
+        public InputStream openInputStreamElement(String streamName)
+        throws IOException {
+
+            InputStream is;
+
+            try {
+                is = getClass().getResourceAsStream(streamName);
+
+                if (is == null) {
+                    is = Thread.currentThread().getContextClassLoader()
+                        .getResourceAsStream(streamName);
+                }
+            } catch (Throwable t) {
+                throw JavaSystem.toIOException(t);
+            }
+
+            return is;
+        }
+
+        public void createParentDirs(java.lang.String filename) {}
+
+        public void removeElement(java.lang.String filename) {}
+
+        public void renameElement(java.lang.String oldName,
+                                  java.lang.String newName) {}
+
+        public java.io.OutputStream openOutputStreamElement(String streamName)
+        throws IOException {
+            throw new IOException();
+        }
+
+        public FileAccess.FileSync getFileSync(OutputStream os)
+        throws IOException {
+            throw new IOException();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/FrameworkLogger.java b/src/org/hsqldb/lib/FrameworkLogger.java
new file mode 100644
index 0000000..8f26117
--- /dev/null
+++ b/src/org/hsqldb/lib/FrameworkLogger.java
@@ -0,0 +1,484 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.Enumeration;
+import java.util.logging.Level;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Logger;
+import java.util.logging.LogManager;
+import java.util.Map;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Properties;
+import java.io.IOException;
+import java.util.HashMap;
+import java.lang.reflect.Method;
+
+/**
+ * A logging framework wrapper that supports java.util.logging and log4j.
+ * <P/>
+ * Logger hierarchies are stored at the Class level.
+ * Log4j will be used if the Log4j system (not necessarily config files) are
+ * found in the runtime classpath.
+ * Otherwise, java.util.logging will be used.
+ * <P/>
+ * This is pretty safe because for use cases where multiple hierarchies
+ * are desired, classloader hierarchies will effectively isolate multiple
+ * class-level Logger hierarchies.
+ * <P/>
+ * Sad as it is, the java.util.logging facility lacks the most basic
+ * developer-side and configuration-side capabilities.
+ * Besides having a non-scalable discovery system, the designers didn't
+ * comprehend the need for a level between WARNING and SEVERE!
+ * Since we don't want to require log4j in Classpath, we have to live
+ * with these constraints.
+ * <P/>
+ * As with all the popular logging frameworks, if you want to capture a
+ * stack trace, you must use the two-parameters logging methods.
+ * I.e., you must also pass a String, or only toString() from your
+ * throwable will be captured.
+ * <P/>
+ * Usage example:<CODE><PRE>
+ * private static FrameworkLogger logger =
+ *        FrameworkLogger.getLog(SqlTool.class);
+ * ...
+ *   logger.finer("Doing something log-worthy");
+ * </PRE> </CODE>
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class FrameworkLogger {
+
+    static private Map     loggerInstances  = new HashMap();
+    static private Map     jdkToLog4jLevels = new HashMap();
+    static private Method  log4jGetLogger;
+    static private Method  log4jLogMethod;
+    private Object         log4jLogger;
+    private Logger         jdkLogger;
+    static private boolean haveLoadedOurDefault;
+    static private ConsoleHandler  consoleHandler = new ConsoleHandler();
+    // No need for more than one static, since we have only one console
+
+    static {
+        reconfigure();
+    }
+
+    static void reconfigure() {
+        Class log4jLoggerClass = null;
+        loggerInstances.clear();
+
+        try {
+            log4jLoggerClass = Class.forName("org.apache.log4j.Logger");
+        } catch (Exception e) {
+            log4jLoggerClass = null;
+        }
+
+        if (log4jLoggerClass == null) try {
+            log4jGetLogger = null;
+            log4jLogMethod = null;
+            LogManager lm = LogManager.getLogManager();
+            if (haveLoadedOurDefault || isDefaultJdkConfig()) {
+                haveLoadedOurDefault = true;
+                consoleHandler.setFormatter(
+                        new BasicTextJdkLogFormatter(false));
+                consoleHandler.setLevel(Level.INFO);
+                lm.readConfiguration(
+                        FrameworkLogger.class.getResourceAsStream(
+                        "/org/hsqldb/resources/jdklogging-default.properties"));
+                Logger cmdlineLogger = Logger.getLogger("org.hsqldb.cmdline");
+                cmdlineLogger.addHandler(consoleHandler);
+                cmdlineLogger.setUseParentHandlers(false);
+            } else {
+                // Do not intervene.  Use JDK logging exactly as configured by
+                // user.
+                lm.readConfiguration();
+                // The only bad thing about doing this is that if the app has
+                // programmatically changed the logging config after starting
+                // the program but before using FrameworkLogger, we will
+                // clobber those customizations.
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(
+                "<clinit> failure initializing JDK logging system", e);
+        } else try {
+            Method log4jToLevel = Class.forName(
+                "org.apache.log4j.Level").getMethod(
+                "toLevel", new Class[]{ String.class });
+
+            jdkToLog4jLevels.put(Level.ALL,
+                                 log4jToLevel.invoke(null,
+                                     new Object[]{ "ALL" }));
+            jdkToLog4jLevels.put(Level.FINER,
+                                 log4jToLevel.invoke(null,
+                                     new Object[]{ "DEBUG" }));
+            jdkToLog4jLevels.put(Level.WARNING,
+                                 log4jToLevel.invoke(null,
+                                     new Object[]{ "ERROR" }));
+            jdkToLog4jLevels.put(Level.SEVERE,
+                                 log4jToLevel.invoke(null,
+                                     new Object[]{ "FATAL" }));
+            jdkToLog4jLevels.put(Level.INFO,
+                                 log4jToLevel.invoke(null,
+                                     new Object[]{ "INFO" }));
+            jdkToLog4jLevels.put(Level.OFF,
+                                 log4jToLevel.invoke(null,
+                                     new Object[]{ "OFF" }));
+            jdkToLog4jLevels.put(Level.FINEST,
+                                 log4jToLevel.invoke(null,
+                                     new Object[]{ "TRACE" }));
+            jdkToLog4jLevels.put(Level.WARNING,
+                                 log4jToLevel.invoke(null,
+                                     new Object[]{ "WARN" }));
+
+            log4jLogMethod = log4jLoggerClass.getMethod("log",
+                    new Class[] {
+                String.class, Class.forName("org.apache.log4j.Priority"),
+                Object.class, Throwable.class
+            });
+
+            log4jGetLogger = log4jLoggerClass.getMethod("getLogger",
+                    new Class[]{ String.class });
+
+            // This last object is what we toggle on to generate either
+            // Log4j or Jdk Logger objects (to wrap).
+        } catch (Exception e) {
+            throw new RuntimeException(
+                "<clinit> failure instantiating present Log4j system", e);
+        }
+    }
+
+    /**
+     * User may not use the constructor.
+     */
+    private FrameworkLogger(String s) {
+
+        if (log4jGetLogger == null) {
+            jdkLogger = Logger.getLogger(s);
+        } else {
+            try {
+                log4jLogger = log4jGetLogger.invoke(null, new Object[]{ s });
+            } catch (Exception e) {
+                throw new RuntimeException(
+                    "Failed to instantiate Log4j Logger", e);
+            }
+        }
+
+        loggerInstances.put(s, this);
+    }
+
+    /**
+     * User's entry-point into this logging system.
+     * <P/>
+     * You normally want to work with static (class-level) pointers to
+     * logger instances, for performance efficiency.
+     * See the class-level JavaDoc for a usage example.
+     *
+     * @see FrameworkLogger
+     */
+    public static FrameworkLogger getLog(Class c) {
+        return getLog(c.getName());
+    }
+
+    /**
+     * This method just defers to the getLog(Class) method unless default
+     * (no local configuration) JDK logging is being used;
+     * In that case, this method assures that the returned logger has an
+     * associated FileHander using the supplied String identifier.
+     */
+    public static FrameworkLogger getLog(Class c, String contextId) {
+        return (contextId == null)
+                ?  getLog(c)
+                :  getLog(contextId + '.' + c.getName());
+    }
+
+    /**
+     * Alternative entry-point into this logging sytem, for cases where
+     * your want to share a single logger instance among multiple classes,
+     * or you want to use multiple logger instances from a single class.
+     *
+     * @see #getLog(Class)
+     */
+    public static FrameworkLogger getLog(String s) {
+
+        if (loggerInstances.containsKey(s)) {
+            return (FrameworkLogger) loggerInstances.get(s);
+        }
+
+        return new FrameworkLogger(s);
+    }
+
+    /**
+     * Just like FrameworkLogger.log(Level, String),
+     * but also logs a stack trace.
+     *
+     * @param level java.util.logging.Level level to filter and log at
+     * @param message Message to be logged
+     * @param t Throwable whose stack trace will be logged.
+     * @see #log(Level, String)
+     * @see Logger#log(Level, String)
+     * @see Level
+     */
+    public void log(Level level, String message, Throwable t) {
+        privlog(level, message, t, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * The "priv" prefix is historical.
+     * This is for special usage when you need to modify the reported call
+     * stack.
+     * If you don't know that you want to do this, then you should not use
+     * this method.
+     */
+    public void privlog(Level level, String message,
+    Throwable t, int revertMethods, Class skipClass) {
+
+        if (log4jLogger == null) {
+            StackTraceElement elements[] = new Throwable().getStackTrace();
+            String            c = elements[revertMethods].getClassName();
+            String            m = elements[revertMethods].getMethodName();
+
+            if (t == null) {
+                jdkLogger.logp(level, c, m, message);
+            } else {
+                jdkLogger.logp(level, c, m, message, t);
+            }
+        } else {
+            try {
+                log4jLogMethod.invoke(log4jLogger, new Object[] {
+                    skipClass.getName(), jdkToLog4jLevels.get(level), message,
+                    t
+                });
+            } catch (Exception e) {
+                throw new RuntimeException(
+                    "Logging failed when attempting to log: " + message, e);
+            }
+        }
+    }
+
+    public void enduserlog(Level level, String message) {
+        /* This method is SqlTool-specific, which is where this class began at.
+         * Need to move this back there, but it needs access to the logging
+         * structures private to this class.  Thinking...
+         */
+
+        if (log4jLogger == null) {
+            String c = FrameworkLogger.class.getName();
+            String m = "\\l";
+
+            jdkLogger.logp(level, c, m, message);
+        } else {
+            try {
+                log4jLogMethod.invoke(log4jLogger, new Object[] {
+                    FrameworkLogger.class.getName(),
+                    jdkToLog4jLevels.get(level),
+                    message, null
+                });
+
+                // Test where SqlFile correct here.
+            } catch (Exception e) {
+                throw new RuntimeException(
+                    "Logging failed when attempting to log: " + message, e);
+            }
+        }
+    }
+
+    // Wrappers
+
+    /**
+     * @param level java.util.logging.Level level to filter and log at
+     * @param message Message to be logged
+     * @see Logger#log(Level, String)
+     * @see Level
+     */
+    public void log(Level level, String message) {
+        privlog(level, message, null, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * @param message Message to be logged
+     * @see Logger#finer(String)
+     */
+    public void finer(String message) {
+        privlog(Level.FINER, message, null, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * @param message Message to be logged
+     * @see Logger#warning(String)
+     */
+    public void warning(String message) {
+        privlog(Level.WARNING, message, null, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * @param message Message to be logged
+     * @see Logger#severe(String)
+     */
+    public void severe(String message) {
+        privlog(Level.SEVERE, message, null, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * @param message Message to be logged
+     * @see Logger#info(String)
+     */
+    public void info(String message) {
+        privlog(Level.INFO, message, null, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * @param message Message to be logged
+     * @see Logger#finest(String)
+     */
+    public void finest(String message) {
+        privlog(Level.FINEST, message, null, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * This is just a wrapper for FrameworkLogger.warning(), because
+     * java.util.logging lacks a method for this critical purpose.
+     *
+     * @param message Message to be logged
+     * @see #warning(String)
+     */
+    public void error(String message) {
+        privlog(Level.WARNING, message, null, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * Just like FrameworkLogger.finer(String), but also logs a stack trace.
+     *
+     * @param t Throwable whose stack trace will be logged.
+     * @see #finer(String)
+     */
+    public void finer(String message, Throwable t) {
+        privlog(Level.FINER, message, t, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * Just like FrameworkLogger.warning(String), but also logs a stack trace.
+     *
+     * @param t Throwable whose stack trace will be logged.
+     * @see #warning(String)
+     */
+    public void warning(String message, Throwable t) {
+        privlog(Level.WARNING, message, t, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * Just like FrameworkLogger.severe(String), but also logs a stack trace.
+     *
+     * @param t Throwable whose stack trace will be logged.
+     * @see #severe(String)
+     */
+    public void severe(String message, Throwable t) {
+        privlog(Level.SEVERE, message, t, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * Just like FrameworkLogger.info(String), but also logs a stack trace.
+     *
+     * @param t Throwable whose stack trace will be logged.
+     * @see #info(String)
+     */
+    public void info(String message, Throwable t) {
+        privlog(Level.INFO, message, t, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * Just like FrameworkLogger.finest(String), but also logs a stack trace.
+     *
+     * @param t Throwable whose stack trace will be logged.
+     * @see #finest(String)
+     */
+    public void finest(String message, Throwable t) {
+        privlog(Level.FINEST, message, t, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * Just like FrameworkLogger.error(String), but also logs a stack trace.
+     *
+     * @param t Throwable whose stack trace will be logged.
+     * @see #error(String)
+     */
+    public void error(String message, Throwable t) {
+        privlog(Level.WARNING, message, t, 2, FrameworkLogger.class);
+    }
+
+    /**
+     * Whether this JVM is configured with java.util.logging defaults.
+     *
+     * If the JRE-provided config file is not in the expected place, then
+     * we return false.
+     */
+    static public boolean isDefaultJdkConfig() {
+        File globalCfgFile = new File(System.getProperty("java.home"),
+                "lib/logging.properties");
+        if (!globalCfgFile.isFile()) {
+            return false;
+        }
+        FileInputStream fis = null;
+        LogManager lm = LogManager.getLogManager();
+        try {
+            fis = new FileInputStream(globalCfgFile);
+            Properties defaultProps = new Properties();
+            defaultProps.load(fis);
+            Enumeration names = defaultProps.propertyNames();
+            int i = 0;
+            String name;
+            String liveVal;
+            while (names.hasMoreElements()) {
+                i++;
+                name = (String) names.nextElement();
+                liveVal = lm.getProperty(name);
+                if (liveVal == null) {
+                    return false;
+                }
+                if (!lm.getProperty(name).equals(liveVal)) {
+                    return false;
+                }
+            }
+            return true;
+        } catch (IOException ioe) {
+            return false;
+        } finally {
+            if (fis != null) try {
+                fis.close();
+            } catch (IOException ioe) {
+                // Intentional no-op
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/HashMap.java b/src/org/hsqldb/lib/HashMap.java
new file mode 100644
index 0000000..1a67bdf
--- /dev/null
+++ b/src/org/hsqldb/lib/HashMap.java
@@ -0,0 +1,211 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * This class does not store null keys.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class HashMap extends BaseHashMap {
+
+    Set        keySet;
+    Collection values;
+
+    public HashMap() {
+        this(8);
+    }
+
+    public HashMap(int initialCapacity) throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.objectKeyOrValue,
+              BaseHashMap.objectKeyOrValue, false);
+    }
+
+    public Object get(Object key) {
+
+        int hash   = key.hashCode();
+        int lookup = getLookup(key, hash);
+
+        if (lookup != -1) {
+            return objectValueTable[lookup];
+        }
+
+        return null;
+    }
+
+    public Object put(Object key, Object value) {
+        return super.addOrRemove(0, 0, key, value, false);
+    }
+
+    public Object remove(Object key) {
+        return super.removeObject(key, false);
+    }
+
+    public boolean containsKey(Object key) {
+        return super.containsKey(key);
+    }
+
+    public boolean containsValue(Object value) {
+        return super.containsValue(value);
+    }
+
+    public void putAll(HashMap t) {
+
+        Iterator it = t.keySet().iterator();
+
+        while (it.hasNext()) {
+            Object key = it.next();
+
+            put(key, t.get(key));
+        }
+    }
+
+    public void valuesToArray(Object[] array) {
+
+        Iterator it = values().iterator();
+        int      i  = 0;
+
+        while (it.hasNext()) {
+            array[i] = it.next();
+
+            i++;
+        }
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return HashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return HashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            return containsKey(o);
+        }
+
+        public Object get(Object key) {
+
+            int lookup = HashMap.this.getLookup(key, key.hashCode());
+
+            if (lookup < 0) {
+                return null;
+            } else {
+                return HashMap.this.objectKeyTable[lookup];
+            }
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+
+            int oldSize = size();
+
+            HashMap.this.remove(o);
+
+            return size() != oldSize;
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            HashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return HashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return HashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            HashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/HashMappedList.java b/src/org/hsqldb/lib/HashMappedList.java
new file mode 100644
index 0000000..1302d3a
--- /dev/null
+++ b/src/org/hsqldb/lib/HashMappedList.java
@@ -0,0 +1,239 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * Implementation of an Map which maintains the user-defined order of the keys.
+ * Key/value pairs can be accessed by index or by key. Iterators return the
+ * keys or values in the index order.
+ *
+ * This class does not store null keys.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class HashMappedList extends HashMap {
+
+    public HashMappedList() {
+        this(8);
+    }
+
+    public HashMappedList(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity);
+
+        isList = true;
+    }
+
+    public Object get(int index) throws IndexOutOfBoundsException {
+
+        checkRange(index);
+
+        return objectValueTable[index];
+    }
+
+    public Object remove(Object key) {
+
+        int lookup = getLookup(key, key.hashCode());
+
+        if (lookup < 0) {
+            return null;
+        }
+
+        Object returnValue = super.remove(key);
+
+        removeRow(lookup);
+
+        return returnValue;
+    }
+
+    public Object remove(int index) throws IndexOutOfBoundsException {
+
+        checkRange(index);
+
+        return remove(objectKeyTable[index]);
+    }
+
+    public boolean add(Object key, Object value) {
+
+        int lookup = getLookup(key, key.hashCode());
+
+        if (lookup >= 0) {
+            return false;
+        }
+
+        super.put(key, value);
+
+        return true;
+    }
+
+    public Object put(Object key, Object value) {
+        return super.put(key, value);
+    }
+
+    public Object set(int index,
+                      Object value) throws IndexOutOfBoundsException {
+
+        checkRange(index);
+
+        Object returnValue = objectKeyTable[index];
+
+        objectKeyTable[index] = value;
+
+        return returnValue;
+    }
+
+    public boolean insert(int index, Object key,
+                          Object value) throws IndexOutOfBoundsException {
+
+        if (index < 0 || index > size()) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        int lookup = getLookup(key, key.hashCode());
+
+        if (lookup >= 0) {
+            return false;
+        }
+
+        if (index == size()) {
+            return add(key, value);
+        }
+
+        HashMappedList hm = new HashMappedList(size());
+
+        for (int i = index; i < size(); i++) {
+            hm.add(getKey(i), get(i));
+        }
+
+        for (int i = size() - 1; i >= index; i--) {
+            remove(i);
+        }
+
+        for (int i = 0; i < hm.size(); i++) {
+            add(hm.getKey(i), hm.get(i));
+        }
+
+        return true;
+    }
+
+    public boolean set(int index, Object key,
+                       Object value) throws IndexOutOfBoundsException {
+
+        checkRange(index);
+
+        if (keySet().contains(key) && getIndex(key) != index) {
+            return false;
+        }
+
+        super.remove(objectKeyTable[index]);
+        super.put(key, value);
+
+        return true;
+    }
+
+    public boolean setKey(int index,
+                          Object key) throws IndexOutOfBoundsException {
+
+        checkRange(index);
+
+        Object value = objectValueTable[index];
+
+        return set(index, key, value);
+    }
+
+    public boolean setValue(int index,
+                            Object value) throws IndexOutOfBoundsException {
+
+        boolean result;
+        Object  existing = objectValueTable[index];
+
+        if (value == null) {
+            result = value != existing;
+        } else {
+            result = !value.equals(existing);
+        }
+
+        objectValueTable[index] = value;
+
+        return result;
+    }
+
+    public Object getKey(int index) throws IndexOutOfBoundsException {
+
+        checkRange(index);
+
+        return objectKeyTable[index];
+    }
+
+    public int getIndex(Object key) {
+        return getLookup(key, key.hashCode());
+    }
+
+    public Object[] toValuesArray(Object[] a) {
+
+        int size = size();
+
+        if (a == null || a.length < size) {
+            a = new Object[size];
+        }
+
+        for (int i = 0; i < size; i++) {
+            a[i] = super.objectValueTable[i];
+        }
+
+        return a;
+    }
+
+    public Object[] toKeysArray(Object[] a) {
+
+        int size = size();
+
+        if (a == null || a.length < size) {
+            a = new Object[size];
+        }
+
+        for (int i = 0; i < size; i++) {
+            a[i] = super.objectKeyTable[i];
+        }
+
+        return a;
+    }
+
+    private void checkRange(int i) {
+
+        if (i < 0 || i >= size()) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/HashSet.java b/src/org/hsqldb/lib/HashSet.java
new file mode 100644
index 0000000..de70e1d
--- /dev/null
+++ b/src/org/hsqldb/lib/HashSet.java
@@ -0,0 +1,204 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * This class does not store null keys.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class HashSet extends BaseHashMap implements Set {
+
+    public HashSet() {
+        this(8);
+    }
+
+    public HashSet(int initialCapacity) throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.objectKeyOrValue,
+              BaseHashMap.noKeyOrValue, false);
+    }
+
+    public boolean contains(Object key) {
+        return super.containsKey(key);
+    }
+
+    public boolean containsAll(Collection col) {
+
+        Iterator it = col.iterator();
+
+        while (it.hasNext()) {
+            if (contains(it.next())) {
+                continue;
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+
+    public Object get(Object key) {
+
+        int lookup = getLookup(key, key.hashCode());
+
+        if (lookup < 0) {
+            return null;
+        } else {
+            return objectKeyTable[lookup];
+        }
+    }
+
+    /** returns true if added */
+    public boolean add(Object key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(0, 0, key, null, false);
+
+        return oldSize != size();
+    }
+
+    /** returns true if any added */
+    public boolean addAll(Collection c) {
+
+        boolean  changed = false;
+        Iterator it      = c.iterator();
+
+        while (it.hasNext()) {
+            changed |= add(it.next());
+        }
+
+        return changed;
+    }
+
+    /** returns true if any added */
+    public boolean addAll(Object[] keys) {
+
+        boolean changed = false;
+
+        for (int i = 0; i < keys.length; i++) {
+            changed |= add(keys[i]);
+        }
+
+        return changed;
+    }
+
+    /** returns true if any added */
+    public boolean addAll(Object[] keys, int start, int limit) {
+
+        boolean changed = false;
+
+        for (int i = start; i < keys.length && i < limit; i++) {
+            changed |= add(keys[i]);
+        }
+
+        return changed;
+    }
+
+    /** returns true if removed */
+    public boolean remove(Object key) {
+
+        int oldSize = size();
+
+        return super.removeObject(key, false) != null;
+    }
+
+    /** returns true if all were removed */
+    public boolean removeAll(Collection c) {
+
+        Iterator it     = c.iterator();
+        boolean  result = true;
+
+        while (it.hasNext()) {
+            result &= remove(it.next());
+        }
+
+        return result;
+    }
+
+    /** returns true if all were removed */
+    public boolean removeAll(Object[] keys) {
+
+        boolean result = true;
+
+        for (int i = 0; i < keys.length; i++) {
+            result &= remove(keys[i]);
+        }
+
+        return result;
+    }
+
+    public Object[] toArray(Object[] a) {
+
+        if (a == null || a.length < size()) {
+            a = new Object[size()];
+        }
+
+        Iterator it = iterator();
+
+        for (int i = 0; it.hasNext(); i++) {
+            a[i] = it.next();
+        }
+
+        return a;
+    }
+
+    public Iterator iterator() {
+        return new BaseHashIterator(true);
+    }
+
+    /**
+     * Returns a String like "[Drei, zwei, Eins]", exactly like
+     * java.util.HashSet.
+     */
+    public String toString() {
+
+        Iterator     it = iterator();
+        StringBuffer sb = new StringBuffer();
+
+        while (it.hasNext()) {
+            if (sb.length() > 0) {
+                sb.append(", ");
+            } else {
+                sb.append('[');
+            }
+
+            sb.append(it.next());
+        }
+
+        return sb.toString() + ']';
+    }
+}
diff --git a/src/org/hsqldb/lib/HsqlArrayHeap.java b/src/org/hsqldb/lib/HsqlArrayHeap.java
new file mode 100644
index 0000000..56aefa0
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlArrayHeap.java
@@ -0,0 +1,331 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.Comparator;
+
+/**
+ * An HsqlHeap implementation backed by an array of objects and an
+ * {@link ObjectComparator ObjectComparator}.  This implementation
+ * is non-blocking, dynamically resizing and thread-safe.
+ *
+ * @author boucherb@users
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class HsqlArrayHeap implements HsqlHeap {
+
+// --------------------------------- members -----------------------------------
+    protected Comparator oc;
+    protected int        count;
+    protected Object[]   heap;
+
+// ------------------------------ constructors ---------------------------------
+
+    /**
+     * Creates a new HsqlArrayHeap with the given initial capacity, using
+     * the specified ObjectComparator to maintain the heap invariant.
+     *
+     * @exception IllegalArgumentException if capacity less or equal to zero
+     *      or comparator is null
+     */
+    public HsqlArrayHeap(int capacity,
+                         Comparator comparator)
+                         throws IllegalArgumentException {
+
+        if (capacity <= 0) {
+            throw new IllegalArgumentException("" + capacity);
+        }
+
+        if (comparator == null) {
+            throw new IllegalArgumentException("null comparator");
+        }
+
+        heap = new Object[capacity];
+        oc   = comparator;
+    }
+
+//    /** Copy constructor (optional) */
+//    public HsqlArrayHeap(HsqlArrayHeap other) {
+//        count = other.count;
+//        oc    = other.oc;
+//        heap  = new Object[count];
+//        System.arraycopy(other.heap,0, heap, 0, count);
+//    }
+// -------------------------- interface Implementation -------------------------
+    public synchronized void clear() {
+
+        for (int i = 0; i < count; ++i) {
+            heap[i] = null;
+        }
+
+        count = 0;
+    }
+
+    public synchronized void add(Object o)
+    throws IllegalArgumentException, RuntimeException {
+
+        int ci;    // current index
+        int pi;    // parent index
+
+        if (o == null) {
+            throw new IllegalArgumentException("null element");
+        }
+
+        if (isFull()) {
+            throw new RuntimeException("full");
+        }
+
+        if (count >= heap.length) {
+            increaseCapacity();
+        }
+
+        ci = count;
+
+        count++;
+
+        do {
+            if (ci <= 0) {
+                break;
+            }
+
+            pi = (ci - 1) >> 1;
+
+            try {
+                if (oc.compare(o, heap[pi]) >= 0) {
+                    break;
+                }
+            } catch (Exception e) {
+                throw new IllegalArgumentException(e.toString());
+            }
+
+            heap[ci] = heap[pi];
+            ci       = pi;
+        } while (true);
+
+        heap[ci] = o;
+    }
+
+    public synchronized boolean isEmpty() {
+        return count == 0;
+    }
+
+    public synchronized boolean isFull() {
+
+        // almost impossible for this to happen
+        return count == Integer.MAX_VALUE;
+    }
+
+    public synchronized Object peek() {
+        return heap[0];
+    }
+
+    public synchronized Object remove() {
+
+        int    ci;     // current index
+        int    li;     // left index
+        int    ri;     // right index
+        int    chi;    // child index
+        Object co;
+        Object ro;
+
+        if (count == 0) {
+            return null;
+        }
+
+        ci = 0;
+        ro = heap[ci];
+
+        count--;
+
+        if (count == 0) {
+            heap[0] = null;
+
+            return ro;
+        }
+
+        co          = heap[count];
+        heap[count] = null;
+
+        do {
+            li = (ci << 1) + 1;
+
+            if (li >= count) {
+                break;
+            }
+
+            ri  = (ci << 1) + 2;
+            chi = (ri >= count || oc.compare(heap[li], heap[ri]) < 0) ? li
+                                                                      : ri;
+
+            if (oc.compare(co, heap[chi]) <= 0) {
+                break;
+            }
+
+            heap[ci] = heap[chi];
+            ci       = chi;
+        } while (true);
+
+        heap[ci] = co;
+
+        return ro;
+    }
+
+    public synchronized int size() {
+        return count;
+    }
+
+// ------------- standard object and collection methods (optional) -------------
+//    public synchronized Object clone() throws CloneNotSupportedException {
+//        return new HsqlArrayHeap(this);
+//    }
+//
+//    public synchronized java.util.Enumeration elements() {
+//
+//        Object[] elements;
+//
+//        elements = new Object[count];
+//
+//        System.arraycopy(heap, 0, elements, 0, count);
+//
+//        return new HsqlEnumeration(elements);
+//    }
+//
+//    public synchronized boolean equals(Object o) {
+//
+//        HsqlArrayHeap other;
+//        HsqlArrayHeap thiscopy;
+//        HsqlArrayHeap othercopy;
+//
+//        if (this == o) {
+//            return true;
+//        }
+//
+//        if (!(o instanceof HsqlArrayHeap)) {
+//            return false;
+//        }
+//
+//        other = (HsqlArrayHeap) o;
+//
+//        if (count != other.size()) {
+//            return false;
+//        }
+//
+//        // this is a bit "iffy"... non-equal comparators _might_ still
+//        // be _equivalent_ under current element content...
+//
+//        if (!oc.equals(other.oc)) {
+//            return false;
+//        }
+//
+//        thiscopy = new HsqlArrayHeap(this);
+//        othercopy = new HsqlArrayHeap(other);
+//
+//        while(!thiscopy.isEmpty()) {
+//            if (!thiscopy.remove().equals(othercopy.remove())) {
+//                return false;
+//            }
+//        }
+//
+//        return true;
+//    }
+//
+//    public synchronized Object[] toArray(Object a[]) {
+//
+//        if (a == null) {
+//            a = new Object[count];
+//        } else if ( a.length < count) {
+//            a = (Object[]) java.lang.reflect.Array.newInstance(
+//                a.getClass().getComponentType(), count);
+//        }
+//
+//        System.arraycopy(heap, 0, a, 0, count);
+//
+//        for (int i = count; i < a.length; i++) {
+//            a[i] = null;
+//        }
+//
+//        return a;
+//    }
+//
+    public synchronized String toString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(super.toString());
+        sb.append(" : size=");
+        sb.append(count);
+        sb.append(' ');
+        sb.append('[');
+
+        for (int i = 0; i < count; i++) {
+            sb.append(heap[i]);
+
+            if (i + 1 < count) {
+                sb.append(',');
+                sb.append(' ');
+            }
+        }
+
+        sb.append(']');
+
+        return sb.toString();
+    }
+
+//
+//    public void trim() {
+//
+//        Object[] oldheap;
+//
+//        oldheap = heap;
+//
+//        heap = new Object[count == 0 ? 16 : count];
+//
+//        System.arraycopy(oldheap, 0, heap, 0, count);
+//    }
+// -------------------- internal implementation methods ------------------------
+    private void increaseCapacity() {
+
+        Object[] oldheap;
+
+        // no handling of boundary conditions.
+        // In the highly unlikely event of a rollover,
+        // in theory, an exception will be thrown (negative array index in
+        // array allocation?)
+        oldheap = heap;
+
+        // as per java collections, v.s. JDK 1.1 java util.
+        heap = new Object[3 * heap.length / 2 + 1];
+
+        System.arraycopy(oldheap, 0, heap, 0, count);
+    }
+}
diff --git a/src/org/hsqldb/lib/HsqlArrayList.java b/src/org/hsqldb/lib/HsqlArrayList.java
new file mode 100644
index 0000000..607414f
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlArrayList.java
@@ -0,0 +1,395 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.lang.reflect.Array;
+import java.util.Comparator;
+
+// fredt@users - 1.8.0, 1.9.0 - enhancements
+
+/**
+ * Intended as an asynchronous alternative to Vector.  Use HsqlLinkedList
+ * instead if its better suited.
+ *
+ * @author dnordahl@users
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class HsqlArrayList extends BaseList implements HsqlList {
+
+//fredt@users
+/*
+    private static Reporter reporter = new Reporter();
+
+    private static class Reporter {
+
+        private static int initCounter   = 0;
+        private static int updateCounter = 0;
+
+        Reporter() {
+
+            try {
+                System.runFinalizersOnExit(true);
+            } catch (SecurityException e) {}
+        }
+
+        protected void finalize() {
+
+            System.out.println("HsqlArrayList init count: " + initCounter);
+            System.out.println("HsqlArrayList update count: "
+                               + updateCounter);
+        }
+    }
+*/
+    private static final int   DEFAULT_INITIAL_CAPACITY = 10;
+    private static final float DEFAULT_RESIZE_FACTOR    = 2.0f;
+    Object[]                   elementData;
+    Object[]                   reserveElementData;
+    private boolean            minimizeOnClear;
+
+    public HsqlArrayList(Object[] data, int count) {
+        elementData  = data;
+        elementCount = count;
+    }
+
+    /** Creates a new instance of HsqlArrayList */
+    public HsqlArrayList() {
+
+//        reporter.initCounter++;
+        elementData = new Object[DEFAULT_INITIAL_CAPACITY];
+    }
+
+    /**
+     * Creates a new instance of HsqlArrayList that minimizes the size when
+     * empty
+     */
+    public HsqlArrayList(boolean minimize) {
+
+//        reporter.initCounter++;
+        elementData     = new Object[DEFAULT_INITIAL_CAPACITY];
+        minimizeOnClear = minimize;
+    }
+
+    /** Creates a new instance with the given initial capacity */
+    public HsqlArrayList(int initialCapacity) {
+
+//        reporter.initCounter++;
+        if (initialCapacity < 0) {
+            throw new NegativeArraySizeException(
+                "Invalid initial capacity given");
+        }
+
+        if (initialCapacity == 0) {
+            elementData = new Object[1];
+        } else {
+            elementData = new Object[initialCapacity];
+        }
+    }
+
+    /** Inserts an element at the given index */
+    public void add(int index, Object element) {
+
+//        reporter.updateCounter++;
+        if (index > elementCount) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + ">" + elementCount);
+        }
+
+        if (index < 0) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " < 0");
+        }
+
+        if (elementCount >= elementData.length) {
+            increaseCapacity();
+        }
+
+        for (int i = elementCount; i > index; i--) {
+            elementData[i] = elementData[i - 1];
+        }
+
+        elementData[index] = element;
+
+        elementCount++;
+    }
+
+    /** Appends an element to the end of the list */
+    public boolean add(Object element) {
+
+//        reporter.updateCounter++;
+        if (elementCount >= elementData.length) {
+            increaseCapacity();
+        }
+
+        elementData[elementCount] = element;
+
+        elementCount++;
+
+        return true;
+    }
+
+    /** Gets the element at given position */
+    public Object get(int index) {
+
+        if (index >= elementCount) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " >= "
+                                                + elementCount);
+        }
+
+        if (index < 0) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " < 0");
+        }
+
+        return elementData[index];
+    }
+
+    /** returns the index of given object or -1 if not found */
+    public int indexOf(Object o) {
+
+        if (o == null) {
+            for (int i = 0; i < elementCount; i++) {
+                if (elementData[i] == null) {
+                    return i;
+                }
+            }
+
+            return -1;
+        }
+
+        for (int i = 0; i < elementCount; i++) {
+            if (o.equals(elementData[i])) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /** Removes and returns the element at given position */
+    public Object remove(int index) {
+
+        if (index >= elementCount) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " >= "
+                                                + elementCount);
+        }
+
+        if (index < 0) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " < 0");
+        }
+
+        Object removedObj = elementData[index];
+
+        for (int i = index; i < elementCount - 1; i++) {
+            elementData[i] = elementData[i + 1];
+        }
+
+        elementCount--;
+
+        if (elementCount == 0) {
+            clear();
+        } else {
+            elementData[elementCount] = null;
+        }
+
+        return removedObj;
+    }
+
+    /** Replaces the element at given position */
+    public Object set(int index, Object element) {
+
+        if (index >= elementCount) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " >= "
+                                                + elementCount);
+        }
+
+        if (index < 0) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " < 0");
+        }
+
+        Object replacedObj = elementData[index];
+
+        elementData[index] = element;
+
+        return replacedObj;
+    }
+
+    /** Returns the number of elements in the array list */
+    public final int size() {
+        return elementCount;
+    }
+
+    private void increaseCapacity() {
+
+        int baseSize = elementData.length == 0 ? 1
+                                               : elementData.length;
+
+        baseSize = (int) (baseSize * DEFAULT_RESIZE_FACTOR);
+
+        resize(baseSize);
+    }
+
+    private void resize(int baseSize) {
+
+        if (baseSize == elementData.length) {
+            return;
+        }
+
+        Object[] newArray = (Object[]) Array.newInstance(
+            elementData.getClass().getComponentType(), baseSize);
+        int count = elementData.length > newArray.length ? newArray.length
+                                                         : elementData.length;
+
+        System.arraycopy(elementData, 0, newArray, 0, count);
+
+        if (minimizeOnClear && reserveElementData == null) {
+            ArrayUtil.clearArray(ArrayUtil.CLASS_CODE_OBJECT, elementData, 0,
+                                 elementData.length);
+
+            reserveElementData = elementData;
+        }
+
+        elementData = newArray;
+    }
+
+    /** Trims the array to be the same size as the number of elements. */
+    public void trim() {
+
+        // 0 size array is possible
+        resize(elementCount);
+    }
+
+    // fredt@users
+    public void clear() {
+
+        if (minimizeOnClear && reserveElementData != null) {
+            elementData        = reserveElementData;
+            reserveElementData = null;
+            elementCount       = 0;
+
+            return;
+        }
+
+        for (int i = 0; i < elementCount; i++) {
+            elementData[i] = null;
+        }
+
+        elementCount = 0;
+    }
+
+    /**
+     * Increase or reduce the size, setting discarded or added elements to null.
+     */
+    public void setSize(int newSize) {
+
+        if (newSize == 0) {
+            clear();
+
+            return;
+        }
+
+        if (newSize <= elementCount) {
+            for (int i = newSize; i < elementCount; i++) {
+                elementData[i] = null;
+            }
+
+            elementCount = newSize;
+
+            return;
+        }
+
+        for (; newSize > elementData.length; ) {
+            increaseCapacity();
+        }
+
+        elementCount = newSize;
+    }
+
+// fredt@users
+    public Object[] toArray() {
+
+        Object[] newArray = (Object[]) Array.newInstance(
+            elementData.getClass().getComponentType(), elementCount);
+
+        System.arraycopy(elementData, 0, newArray, 0, elementCount);
+
+        return newArray;
+    }
+
+    public Object[] toArray(int start, int limit) {
+
+        Object[] newArray = (Object[]) Array.newInstance(
+            elementData.getClass().getComponentType(), limit - start);
+
+        System.arraycopy(elementData, start, newArray, 0, limit - start);
+
+        return newArray;
+    }
+
+    /**
+     * Copies all elements of the list to a[]. It is assumed a[] is of the
+     * correct type. If a[] is too small, a new array or the same type is
+     * returned. If a[] is larger, only the list elements are copied and no
+     * other change is made to the array.
+     * Differs from the implementation in java.util.ArrayList in the second
+     * aspect.
+     */
+    public Object toArray(Object a) {
+
+        if (Array.getLength(a) < elementCount) {
+            a = Array.newInstance(a.getClass().getComponentType(),
+                                  elementCount);
+        }
+
+        System.arraycopy(elementData, 0, a, 0, elementCount);
+
+        return a;
+    }
+
+    public void sort(Comparator c) {
+
+        if (elementCount < 2) {
+            return;
+        }
+
+        ArraySort.sort(elementData, 0, elementCount, c);
+    }
+
+    public Object[] getArray() {
+        return elementData;
+    }
+}
diff --git a/src/org/hsqldb/lib/HsqlByteArrayInputStream.java b/src/org/hsqldb/lib/HsqlByteArrayInputStream.java
new file mode 100644
index 0000000..0dfd74c
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlByteArrayInputStream.java
@@ -0,0 +1,278 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.DataInput;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * This class is a replacement for both java.io.ByteArrayInputStream
+ * (without synchronization) and java.io.DataInputStream
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class HsqlByteArrayInputStream extends InputStream
+implements DataInput {
+
+    protected byte[] buffer;
+    protected int    pos;
+    protected int    mark = 0;
+    protected int    count;
+
+    public HsqlByteArrayInputStream(byte[] buf) {
+
+        this.buffer = buf;
+        this.pos    = 0;
+        this.count  = buf.length;
+    }
+
+    public HsqlByteArrayInputStream(byte[] buf, int offset, int length) {
+
+        this.buffer = buf;
+        this.pos    = offset;
+        this.count  = Math.min(offset + length, buf.length);
+        this.mark   = offset;
+    }
+
+    // methods that implement java.io.DataInput
+    public final void readFully(byte[] b) throws IOException {
+        readFully(b, 0, b.length);
+    }
+
+    public final void readFully(byte[] b, int off,
+                                int len) throws IOException {
+
+        if (len < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        int n = 0;
+
+        while (n < len) {
+            int count = read(b, off + n, len - n);
+
+            if (count < 0) {
+                throw new EOFException();
+            }
+
+            n += count;
+        }
+    }
+
+    public final boolean readBoolean() throws IOException {
+
+        int ch = read();
+
+        if (ch < 0) {
+            throw new EOFException();
+        }
+
+        return (ch != 0);
+    }
+
+    public final byte readByte() throws IOException {
+
+        int ch = read();
+
+        if (ch < 0) {
+            throw new EOFException();
+        }
+
+        return (byte) ch;
+    }
+
+    public final int readUnsignedByte() throws IOException {
+
+        int ch = read();
+
+        if (ch < 0) {
+            throw new EOFException();
+        }
+
+        return ch;
+    }
+
+    public short readShort() throws IOException {
+
+        if (count - pos < 2) {
+            pos = count;
+
+            throw new EOFException();
+        }
+
+        int ch1 = buffer[pos++] & 0xff;
+        int ch2 = buffer[pos++] & 0xff;
+
+        return (short) ((ch1 << 8) + (ch2));
+    }
+
+    public final int readUnsignedShort() throws IOException {
+
+        int ch1 = read();
+        int ch2 = read();
+
+        if ((ch1 | ch2) < 0) {
+            throw new EOFException();
+        }
+
+        return (ch1 << 8) + (ch2);
+    }
+
+    public final char readChar() throws IOException {
+
+        int ch1 = read();
+        int ch2 = read();
+
+        if ((ch1 | ch2) < 0) {
+            throw new EOFException();
+        }
+
+        return (char) ((ch1 << 8) + (ch2));
+    }
+
+    public int readInt() throws IOException {
+
+        if (count - pos < 4) {
+            pos = count;
+
+            throw new EOFException();
+        }
+
+        int ch1 = buffer[pos++] & 0xff;
+        int ch2 = buffer[pos++] & 0xff;
+        int ch3 = buffer[pos++] & 0xff;
+        int ch4 = buffer[pos++] & 0xff;
+
+        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4));
+    }
+
+    public long readLong() throws IOException {
+        return (((long) readInt()) << 32) + (((long) readInt()) & 0xffffffffL);
+    }
+
+    public final float readFloat() throws IOException {
+        return Float.intBitsToFloat(readInt());
+    }
+
+    public final double readDouble() throws IOException {
+        return Double.longBitsToDouble(readLong());
+    }
+
+    public int skipBytes(int n) throws IOException {
+        return (int) skip(n);
+    }
+
+    public String readLine() throws IOException {
+
+        /** @todo: this will probably be useful */
+        throw new java.lang.RuntimeException("not implemented.");
+    }
+
+    public String readUTF() throws IOException {
+
+        int bytecount = readUnsignedShort();
+
+        if (pos + bytecount >= count) {
+            throw new EOFException();
+        }
+
+        String result = StringConverter.readUTF(buffer, pos, bytecount);
+
+        pos += bytecount;
+
+        return result;
+    }
+
+// methods that extend java.io.InputStream
+    public int read() {
+        return (pos < count) ? (buffer[pos++] & 0xff)
+                             : -1;
+    }
+
+    public int read(byte[] b, int off, int len) {
+
+        if (pos >= count) {
+            return -1;
+        }
+
+        if (pos + len > count) {
+            len = count - pos;
+        }
+
+        if (len <= 0) {
+            return 0;
+        }
+
+        System.arraycopy(buffer, pos, b, off, len);
+
+        pos += len;
+
+        return len;
+    }
+
+    public long skip(long n) {
+
+        if (pos + n > count) {
+            n = count - pos;
+        }
+
+        if (n < 0) {
+            return 0;
+        }
+
+        pos += n;
+
+        return n;
+    }
+
+    public int available() {
+        return count - pos;
+    }
+
+    public boolean markSupported() {
+        return true;
+    }
+
+    public void mark(int readAheadLimit) {
+        mark = pos;
+    }
+
+    public void reset() {
+        pos = mark;
+    }
+
+    public void close() throws IOException {}
+}
diff --git a/src/org/hsqldb/lib/HsqlByteArrayOutputStream.java b/src/org/hsqldb/lib/HsqlByteArrayOutputStream.java
new file mode 100644
index 0000000..010fbf8
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlByteArrayOutputStream.java
@@ -0,0 +1,363 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.DataOutput;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UTFDataFormatException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * This class is a replacement for both java.io.ByteArrayOuputStream
+ * (without synchronization) and java.io.DataOutputStream
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class HsqlByteArrayOutputStream extends java.io.OutputStream
+implements DataOutput {
+
+    protected byte[] buffer;
+    protected int    count;
+
+    public HsqlByteArrayOutputStream() {
+        this(128);
+    }
+
+    public HsqlByteArrayOutputStream(int size) {
+
+        if (size < 128) {
+            size = 128;
+        }
+
+        buffer = new byte[size];
+    }
+
+    public HsqlByteArrayOutputStream(byte[] buffer) {
+        this.buffer = buffer;
+    }
+
+    /**
+     * Constructor from an InputStream limits size to the length argument.
+     * Throws if the actual length of the InputStream is smaller than
+     * length value.
+     */
+    public HsqlByteArrayOutputStream(InputStream input,
+                                     int length) throws IOException {
+
+        buffer = new byte[length];
+
+        for (int left = length; left > 0; ) {
+            int read = input.read(buffer, count, left);
+
+            if (read == -1) {
+                if (left > 0) {
+                    input.close();
+
+                    throw new EOFException();
+                }
+
+                break;
+            }
+
+            left  -= read;
+            count += read;
+        }
+    }
+
+    public HsqlByteArrayOutputStream(InputStream input) throws IOException {
+
+        buffer = new byte[128];
+
+        for (;; ) {
+
+            int read = input.read(buffer, count, buffer.length - count);
+
+            if (read == -1) {
+                break;
+            }
+
+            count += read;
+
+            if (count == buffer.length){
+                ensureRoom(128);
+            }
+        }
+    }
+
+    // methods that implement dataOutput
+    public void writeShort(int v) {
+
+        ensureRoom(2);
+
+        buffer[count++] = (byte) (v >>> 8);
+        buffer[count++] = (byte) v;
+    }
+
+    public void writeInt(int v) {
+
+        if (count + 4 > buffer.length) {
+            ensureRoom(4);
+        }
+
+        buffer[count++] = (byte) (v >>> 24);
+        buffer[count++] = (byte) (v >>> 16);
+        buffer[count++] = (byte) (v >>> 8);
+        buffer[count++] = (byte) v;
+    }
+
+    public void writeLong(long v) {
+        writeInt((int) (v >>> 32));
+        writeInt((int) v);
+    }
+
+    public final void writeBytes(String s) {
+
+        int len = s.length();
+
+        ensureRoom(len);
+
+        for (int i = 0; i < len; i++) {
+            buffer[count++] = (byte) s.charAt(i);
+        }
+    }
+
+    public final void writeFloat(float v) {
+        writeInt(Float.floatToIntBits(v));
+    }
+
+    public final void writeDouble(double v) {
+        writeLong(Double.doubleToLongBits(v));
+    }
+
+    public void writeBoolean(boolean v) {
+
+        ensureRoom(1);
+
+        buffer[count++] = (byte) (v ? 1
+                                    : 0);
+    }
+
+    public void writeByte(int v) {
+
+        ensureRoom(1);
+
+        buffer[count++] = (byte) (v);
+    }
+
+    public void writeChar(int v) {
+
+        ensureRoom(2);
+
+        buffer[count++] = (byte) (v >>> 8);
+        buffer[count++] = (byte) v;
+    }
+
+    public void writeChars(String s) {
+
+        int len = s.length();
+
+        ensureRoom(len * 2);
+
+        for (int i = 0; i < len; i++) {
+            int v = s.charAt(i);
+
+            buffer[count++] = (byte) (v >>> 8);
+            buffer[count++] = (byte) v;
+        }
+    }
+
+    public void writeUTF(String str) throws IOException {
+
+        int len = str.length();
+
+        if (len > 0xffff) {
+            throw new UTFDataFormatException();
+        }
+
+        ensureRoom(len * 3 + 2);
+
+        //
+        int initpos = count;
+
+        count += 2;
+
+        StringConverter.stringToUTFBytes(str, this);
+
+        int bytecount = count - initpos - 2;
+
+        if (bytecount > 0xffff) {
+            count = initpos;
+
+            throw new UTFDataFormatException();
+        }
+
+        buffer[initpos++] = (byte) (bytecount >>> 8);
+        buffer[initpos]   = (byte) bytecount;
+    }
+
+    /**
+     * does nothing
+     */
+    public void flush() throws java.io.IOException {}
+
+    // methods that extend java.io.OutputStream
+    public void write(int b) {
+
+        ensureRoom(1);
+
+        buffer[count++] = (byte) b;
+    }
+
+    public void writeNoCheck(int b) {
+        buffer[count++] = (byte) b;
+    }
+
+    public void write(byte[] b) {
+        write(b, 0, b.length);
+    }
+
+    public void write(byte[] b, int off, int len) {
+
+        ensureRoom(len);
+        System.arraycopy(b, off, buffer, count, len);
+
+        count += len;
+    }
+
+    public void writeTo(OutputStream out) throws IOException {
+        out.write(buffer, 0, count);
+    }
+
+    public void reset() {
+        count = 0;
+    }
+
+    public byte[] toByteArray() {
+
+        byte[] newbuf = new byte[count];
+
+        System.arraycopy(buffer, 0, newbuf, 0, count);
+
+        return newbuf;
+    }
+
+    public int size() {
+        return count;
+    }
+
+    public void setPosition(int newPos) {
+
+        if (newPos > buffer.length) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        count = newPos;
+    }
+
+    public String toString() {
+        return new String(buffer, 0, count);
+    }
+
+    public String toString(String enc) throws UnsupportedEncodingException {
+        return new String(buffer, 0, count, enc);
+    }
+
+    public void close() throws IOException {}
+
+    // additional public methods not in similar java.util classes
+    public void write(char[] c, int off, int len) {
+
+        ensureRoom(len * 2);
+
+        for (int i = off; i < len; i++) {
+            int v = c[i];
+
+            buffer[count++] = (byte) (v >>> 8);
+            buffer[count++] = (byte) v;
+        }
+    }
+
+    public void fill(int b, int len) {
+
+        ensureRoom(len);
+
+        for (int i = 0; i < len; i++) {
+            buffer[count++] = (byte) b;
+        }
+    }
+
+    public byte[] getBuffer() {
+        return this.buffer;
+    }
+
+    public void setBuffer(byte[] buffer) {
+        count       = 0;
+        this.buffer = buffer;
+    }
+
+    public void ensureRoom(int extra) {
+
+        int newcount = count + extra;
+        int newsize  = buffer.length;
+
+        if (newcount > newsize) {
+            while (newcount > newsize) {
+                newsize *= 2;
+            }
+
+            byte[] newbuf = new byte[newsize];
+
+            System.arraycopy(buffer, 0, newbuf, 0, count);
+
+            buffer = newbuf;
+        }
+    }
+
+    public void reset(int newSize) {
+
+        count = 0;
+
+        if (newSize > buffer.length) {
+            buffer = new byte[newSize];
+        }
+    }
+
+    public void reset(byte[] buffer) {
+        count       = 0;
+        this.buffer = buffer;
+    }
+}
diff --git a/src/org/hsqldb/lib/HsqlDeque.java b/src/org/hsqldb/lib/HsqlDeque.java
new file mode 100644
index 0000000..ebe0915
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlDeque.java
@@ -0,0 +1,335 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+// fredt@users 20020130 - patch 1.7.0 by fredt - new class
+
+/**
+ * jdk 1.1 compatible minimal implementation of a list object suitable for
+ * stack, queue and deque usage patterns backed by an Object[].
+ * The memory footprint of the HsqlDeque doubles when it gets full
+ * but does not shrink when it gets empty.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class HsqlDeque extends BaseList implements HsqlList {
+
+    private Object[] list;
+    private int      firstindex = 0;    // index of first list element
+    private int      endindex   = 0;    // index of last list element + 1
+
+    // can grow to fill list
+    // if elementCount == 0 then firstindex == endindex
+    private static final int DEFAULT_INITIAL_CAPACITY = 10;
+
+    public HsqlDeque() {
+        list = new Object[DEFAULT_INITIAL_CAPACITY];
+    }
+
+    public int size() {
+        return elementCount;
+    }
+
+    public boolean isEmpty() {
+        return elementCount == 0;
+    }
+
+    public Object getFirst() throws NoSuchElementException {
+
+        if (elementCount == 0) {
+            throw new NoSuchElementException();
+        }
+
+        return list[firstindex];
+    }
+
+    public Object getLast() throws NoSuchElementException {
+
+        if (elementCount == 0) {
+            throw new NoSuchElementException();
+        }
+
+        return list[endindex - 1];
+    }
+
+    public Object get(int i) throws IndexOutOfBoundsException {
+
+        int index = getInternalIndex(i);
+
+        return list[index];
+    }
+
+    public void add(int i, Object o) throws IndexOutOfBoundsException {
+        throw new java.lang.RuntimeException();
+    }
+
+    public Object set(int i, Object o) throws IndexOutOfBoundsException {
+
+        int    index  = getInternalIndex(i);
+        Object result = list[index];
+
+        list[index] = o;
+
+        return result;
+    }
+
+    public Object removeFirst() throws NoSuchElementException {
+
+        if (elementCount == 0) {
+            throw new NoSuchElementException();
+        }
+
+        Object o = list[firstindex];
+
+        list[firstindex] = null;
+
+        firstindex++;
+        elementCount--;
+
+        if (elementCount == 0) {
+            firstindex = endindex = 0;
+        } else if (firstindex == list.length) {
+            firstindex = 0;
+        }
+
+        return o;
+    }
+
+    public Object removeLast() throws NoSuchElementException {
+
+        if (elementCount == 0) {
+            throw new NoSuchElementException();
+        }
+
+        endindex--;
+
+        Object o = list[endindex];
+
+        list[endindex] = null;
+
+        elementCount--;
+
+        if (elementCount == 0) {
+            firstindex = endindex = 0;
+        } else if (endindex == 0) {
+            endindex = list.length;
+        }
+
+        return o;
+    }
+
+/*
+    public Object remove(int i){
+        return get(i);
+    }
+
+    public void add(int i, Object o) {
+
+    }
+*/
+    public boolean add(Object o) {
+
+        resetCapacity();
+
+        if (endindex == list.length) {
+            endindex = 0;
+        }
+
+        list[endindex] = o;
+
+        elementCount++;
+        endindex++;
+
+        return true;
+    }
+
+    public boolean addLast(Object o) {
+        return add(o);
+    }
+
+    public boolean addFirst(Object o) {
+
+        resetCapacity();
+
+        firstindex--;
+
+        if (firstindex < 0) {
+            firstindex = list.length - 1;
+
+            if (endindex == 0) {
+                endindex = list.length;
+            }
+        }
+
+        list[firstindex] = o;
+
+        elementCount++;
+
+        return true;
+    }
+
+    public void clear() {
+
+        if (elementCount == 0) {
+            return;
+        }
+
+        firstindex = endindex = elementCount = 0;
+
+        for (int i = 0; i < list.length; i++) {
+            list[i] = null;
+        }
+    }
+
+    public int indexOf(Object value) {
+
+        for (int i = 0; i < elementCount; i++) {
+            int index = firstindex + i;
+
+            if (index >= list.length) {
+                index -= list.length;
+            }
+
+            if (list[index] == value) {
+                return i;
+            }
+
+            if (value != null && value.equals(list[index])) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    public Object remove(int index) {
+
+        int    target = getInternalIndex(index);
+        Object value  = list[target];
+
+        if (target == firstindex) {
+            list[firstindex] = null;
+
+            firstindex++;
+
+            if (firstindex == list.length) {
+                firstindex = 0;
+            }
+        } else if (target > firstindex) {
+            System.arraycopy(list, firstindex, list, firstindex + 1,
+                             target - firstindex);
+
+            list[firstindex] = null;
+
+            firstindex++;
+
+            if (firstindex == list.length) {
+                firstindex = 0;
+            }
+        } else {
+            System.arraycopy(list, target + 1, list, target,
+                             endindex - target - 1);
+
+            endindex--;
+
+            list[endindex] = null;
+
+            if (endindex == 0) {
+                endindex = list.length;
+            }
+        }
+
+        elementCount--;
+
+        if (elementCount == 0) {
+            firstindex = endindex = 0;
+        }
+
+        return value;
+    }
+
+    private int getInternalIndex(int i) throws IndexOutOfBoundsException {
+
+        if (i < 0 || i >= elementCount) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        int index = firstindex + i;
+
+        if (index >= list.length) {
+            index -= list.length;
+        }
+
+        return index;
+    }
+
+    private void resetCapacity() {
+
+        if (elementCount < list.length) {
+            return;
+        }
+
+        Object[] newList = new Object[list.length * 2];
+
+        System.arraycopy(list, firstindex, newList, firstindex,
+                         list.length - firstindex);
+
+        if (endindex <= firstindex) {
+            System.arraycopy(list, 0, newList, list.length, endindex);
+
+            endindex = list.length + endindex;
+        }
+
+        list = newList;
+    }
+
+    public void toArray(Object[] array) {
+
+        int tempCount = list.length - firstindex;
+
+        if (tempCount > elementCount) {
+            tempCount = elementCount;
+        }
+
+        System.arraycopy(list, firstindex, array, 0, tempCount);
+
+        if (endindex <= firstindex) {
+            System.arraycopy(list, 0, array, tempCount, endindex);
+
+            endindex = list.length + endindex;
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/HsqlHeap.java b/src/org/hsqldb/lib/HsqlHeap.java
new file mode 100644
index 0000000..4b05804
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlHeap.java
@@ -0,0 +1,103 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * Provides the base HSQLDB interface for Heap ADT implementations. <p>
+ *
+ * In this context, a Heap is simply a collection-like ADT that allows addition
+ * of elements and provides a way to remove the least element, given some
+ * implementation-dependent strategy for imposing an order over its
+ * elements. <p>
+ *
+ * Typically, an HsqlHeap will be implemented as a tree-like structure that
+ * recursively guarantees a <i>Heap Invariant</i>, such that all nodes below
+ * the root are greater than the root, given some comparison stragegy. <p>
+
+ * This in turn provides the basis for an efficient implementation of ADTs such
+ * PriorityQueue, since Heap operations using the typical implementation are,
+ * in theory, guaranteed to be O(log n).
+ *
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public interface HsqlHeap {
+
+    /**
+     * Removes all of the elements from this Heap.
+     */
+    void clear();
+
+    /**
+     * Retrieves whether this Heap is empty.
+     */
+    boolean isEmpty();
+
+    /**
+     * Retrieves whether this Heap is full.
+     */
+    boolean isFull();
+
+    /**
+     * Adds the specified element to this Heap.
+     *
+     * @param o The element to add
+     * @throws IllegalArgumentException if the implementation does
+     *      not accept elements of the supplied type (optional)
+     * throws RuntimeException if the implementation
+     *      dictates that this Heap is not currently accepting additions
+     *      or that this Heap is currently full (optional)
+     */
+    void add(Object o) throws IllegalArgumentException, RuntimeException;
+
+    /**
+     * Retrieves the least element from this Heap, without removing it.
+     *
+     * @return the least element from this Heap
+     */
+    Object peek();
+
+    /**
+     * Retrieves the least element from this Heap, removing it in the process.
+     *
+     * @return the least element from this Heap
+     */
+    Object remove();
+
+    /**
+     * Retrieves the number of elements currently in this Heap.
+     *
+     * @return the number of elements currently in this Heap
+     */
+    int size();
+}
diff --git a/src/org/hsqldb/lib/HsqlLinkedList.java b/src/org/hsqldb/lib/HsqlLinkedList.java
new file mode 100644
index 0000000..06afb66
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlLinkedList.java
@@ -0,0 +1,282 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * Intended as an asynchronous alternative to HsqlArrayList.  Use HsqlArrayList if
+ * the list won't be initialized sequentially and if frequent references to
+ * specific element positions will be made.
+ *
+ * @author jcpeck@users
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class HsqlLinkedList extends BaseList implements HsqlList {
+
+    /**
+     * A reference to the head of the list.  It is a dummy head (that is, the
+     * Node for index 0 is actually first.next).
+     */
+    private Node first;
+
+    /** A reference to the tail of the list */
+    private Node last;
+
+    /**
+     * Creates a new instance of HsqlLinkedList.
+     */
+    public HsqlLinkedList() {
+
+        first        = new Node(null, null);
+        last         = first;
+        elementCount = 0;
+    }
+
+    /**
+     * Returns the first node to allow iterators to be used.
+     */
+    public Node getHeadNode() {
+        return first;
+    }
+
+    /**
+     * Removes the given node to allow removel from iterators
+     */
+    public boolean removeAfter(Node node) {
+
+        if (node == null || node.next == null) {
+            return false;
+        }
+
+        if (node.next == last) {
+            last = node;
+        }
+
+        node.next = node.next.next;
+
+        return true;
+    }
+
+    /**
+     * Inserts <code>element</code> at <code>index</code>.
+     * @throws IndexOutOfBoundsException if <code>index</code> &lt; 0 or is &gt;
+     * <code>size</code>.
+     */
+    public void add(int index, Object element) {
+
+        if (index == size()) {
+            add(element);    //Add to the end of this.
+        }
+
+        //If index > size() an exception should be thrown with a slightly
+        //different message than the exception thrown by getInternal.
+        else if (index > size()) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " > " + size());
+        } else {
+            Node current = getInternal(index);
+            Node newNext = new Node(current.data, current.next);
+
+            current.data = element;
+            current.next = newNext;
+
+            elementCount++;
+
+            //If they inserted at the last valid index, then a new last element
+            //was created, therfore update the last pointer
+            if (last == current) {
+                last = newNext;
+            }
+        }
+    }
+
+    /**
+     * Appends <code>element</code> to the end of this list.
+     * @return true
+     */
+    public boolean add(Object element) {
+
+        last.next = new Node(element, null);
+        last      = last.next;
+
+        elementCount++;
+
+        return true;
+    }
+
+    public void clear() {
+        first.next = null;
+        last = first;
+        elementCount = 0;
+    }
+
+    /**
+     * Gets the element at given position
+     * @throws IndexOutOfBoundsException if index is not valid
+     * index within the list (0 &lt;= <code>index</code> &lt;
+     * <code>size</code>).
+     */
+    public Object get(int index) {
+        return getInternal(index).data;
+    }
+
+    /**
+     * Removes and returns the element at <code>index</code>.
+     * @throws IndexOutOfBoundsException if index is not valid
+     * index within the list (0 &lt;= <code>index</code> &lt;
+     * <code>size</code>).
+     */
+    public Object remove(int index) {
+
+        //Check that the index is less than size because the getInternal
+        //method is being called with index - 1 and its checks will therefore
+        //not be useful in this case.
+        if (index >= size()) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " >= " + size());
+        }
+
+        //Get the node that is previous to the node being removed
+        Node previousToRemove;
+
+        if (index == 0) {
+            previousToRemove = first;
+        } else {
+            previousToRemove = getInternal(index - 1);
+        }
+
+        //previousToRemove.next will never be null because of the check above
+        //that index < size.
+        Node toRemove = previousToRemove.next;
+
+        previousToRemove.next = toRemove.next;
+
+        elementCount--;
+
+        //If they removed at the last valid index, then a the last element
+        //was removed, therfore update the last pointer
+        if (last == toRemove) {
+            last = previousToRemove;
+        }
+
+        return toRemove.data;
+    }
+
+    /**
+     * Replaces the current element at <code>index/code> with
+     * <code>element</code>.
+     * @return The current element at <code>index</code>.
+     */
+    public Object set(int index, Object element) {
+
+        Node   setMe   = getInternal(index);
+        Object oldData = setMe.data;
+
+        setMe.data = element;
+
+        return oldData;
+    }
+
+    /**
+     * Accessor for the size of this linked list.  The size is the total number
+     * of elements in the list and is one greater than the largest index in the
+     * list.
+     * @return The size of this.
+     */
+    public final int size() {
+        return elementCount;
+    }
+
+    /**
+     * Helper method that returns the Node at <code>index</code>.
+     * @param index The index of the Node to return.
+     * @return The Node at the given index.
+     * @throws IndexOutOfBoundsException if index is not valid
+     * index within the list (0 &lt;= <code>index</code> &lt;
+     * <code>size</code>).
+     */
+    protected final Node getInternal(int index) {
+
+        //Check preconditions for the index variable
+        if (index >= size()) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " >= " + size());
+        }
+
+        if (index < 0) {
+            throw new IndexOutOfBoundsException("Index out of bounds: "
+                                                + index + " < 0");
+        }
+
+        if (index == 0) {
+            return first.next;
+        } else if (index == (size() - 1)) {
+            return last;
+        } else {
+            Node pointer = first.next;
+
+            for (int i = 0; i < index; i++) {
+                pointer = pointer.next;
+            }
+
+            return pointer;
+        }
+    }
+
+    /**
+     * Inner class that represents nodes within the linked list.  This should
+     * be a static inner class to avoid the uneccesary overhead of the
+     * containing class "this" pointer.
+     * jcpeck@users
+     * @version 05/24/2002
+     */
+    public static class Node {
+
+        public Node   next;
+        public Object data;
+
+        public Node() {
+            next = null;
+            data = null;
+        }
+
+        public Node(Object data) {
+            this.next = null;
+            this.data = data;
+        }
+
+        public Node(Object data, Node next) {
+            this.next = next;
+            this.data = data;
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/HsqlList.java b/src/org/hsqldb/lib/HsqlList.java
new file mode 100644
index 0000000..1c80525
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlList.java
@@ -0,0 +1,60 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * This should be used as the datatype for parameters and instance variables
+ * instead of HsqlArrayList or HsqlLinkedList to allow interchangable use of the
+ * two.
+ *
+ * @author dnordahl@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public interface HsqlList extends Collection {
+
+    void add(int index, Object element);
+
+    boolean add(Object element);
+
+    Object get(int index);
+
+    Object remove(int index);
+
+    Object set(int index, Object element);
+
+    boolean isEmpty();
+
+    int size();
+
+    Iterator iterator();
+}
diff --git a/src/org/hsqldb/lib/HsqlTaskQueue.java b/src/org/hsqldb/lib/HsqlTaskQueue.java
new file mode 100644
index 0000000..70f12d7
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlTaskQueue.java
@@ -0,0 +1,164 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * Provides very simple queued execution of Runnable objects in a background
+ * thread. The underlying queue is an HsqlDeque instance, an array-based
+ * circular queue implementation with automatic capacity expansion.
+ *
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class HsqlTaskQueue {
+
+    /** The thread used to process commands */
+    protected Thread taskRunnerThread;
+
+    /** Special queue element to signal termination */
+    protected static final Runnable SHUTDOWNTASK = new Runnable() {
+        public void run() {}
+    };
+
+    /**
+     * true if thread should shut down after processing current task.
+     *
+     * Once set true, stays true forever
+     */
+    protected volatile boolean isShutdown;
+
+    public synchronized Thread getTaskRunnerThread() {
+        return taskRunnerThread;
+    }
+
+    protected synchronized void clearThread() {
+        taskRunnerThread = null;
+    }
+
+    protected final HsqlDeque queue = new HsqlDeque();
+
+    protected class TaskRunner implements Runnable {
+
+        public void run() {
+
+            Runnable task;
+
+            try {
+                while (!isShutdown) {
+                    synchronized (queue) {
+                        task = (Runnable) queue.getFirst();
+                    }
+
+                    if (task == SHUTDOWNTASK) {
+                        isShutdown = true;
+
+                        synchronized (queue) {
+                            queue.clear();
+                        }
+
+                        break;
+                    } else if (task != null) {
+                        task.run();
+
+                        task = null;
+                    } else {
+                        break;
+                    }
+                }
+            } finally {
+                clearThread();
+            }
+        }
+    }
+
+    protected final TaskRunner taskRunner = new TaskRunner();
+
+    public HsqlTaskQueue() {}
+
+    public boolean isShutdown() {
+        return isShutdown;
+    }
+
+    public synchronized void restart() {
+
+        if (taskRunnerThread == null &&!isShutdown) {
+            taskRunnerThread = new Thread(taskRunner);
+
+            taskRunnerThread.start();
+        }
+    }
+
+    public void execute(Runnable command) throws RuntimeException {
+
+        if (!isShutdown) {
+            synchronized (queue) {
+                queue.addLast(command);
+            }
+
+            restart();
+        }
+    }
+
+    public synchronized void shutdownAfterQueued() {
+
+        if (!isShutdown) {
+            synchronized (queue) {
+                queue.addLast(SHUTDOWNTASK);
+            }
+        }
+    }
+
+    public synchronized void shutdownAfterCurrent() {
+
+        isShutdown = true;
+
+        synchronized (queue) {
+            queue.clear();
+            queue.addLast(SHUTDOWNTASK);
+        }
+    }
+
+    public synchronized void shutdownImmediately() {
+
+        isShutdown = true;
+
+        if (taskRunnerThread != null) {
+            taskRunnerThread.interrupt();
+        }
+
+        synchronized (queue) {
+            queue.clear();
+            queue.addLast(SHUTDOWNTASK);
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/HsqlThreadFactory.java b/src/org/hsqldb/lib/HsqlThreadFactory.java
new file mode 100644
index 0000000..c114780
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlThreadFactory.java
@@ -0,0 +1,111 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * The default HSQLDB thread factory implementation.  This factory can be
+ * used to wrap other thread factories using the setImpl method, but, by
+ * default simply produces new, vanilla thread objects constructed with
+ * the supplied runnable object.
+ *
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+class HsqlThreadFactory implements ThreadFactory {
+
+    /**
+     * The factory implementation.  Typically, this will be the
+     * HsqlThreadFactory object itself.
+     */
+    protected ThreadFactory factory;
+
+    /**
+     * Constructs a new HsqlThreadFactory that uses itself as the factory
+     * implementation.
+     */
+    public HsqlThreadFactory() {
+        this(null);
+    }
+
+    /**
+     * Constructs a new HsqlThreadFactory whose retrieved threads come from the
+     * specified ThreadFactory object or from this factory implementation, if'
+     * the specified implementation is null.
+     *
+     * @param f the factory implementation this factory uses
+     */
+    public HsqlThreadFactory(ThreadFactory f) {
+        setImpl(f);
+    }
+
+    /**
+     * Retreives a thread instance for running the specified Runnable
+     * @param r The runnable that the retrieved thread handles
+     * @return the requested thread inatance
+     */
+    public Thread newThread(Runnable r) {
+        return factory == this ? new Thread(r)
+                               : factory.newThread(r);
+    }
+
+    /**
+     * Sets the factory implementation that this factory will use to
+     * produce threads.  If the specified argument, f, is null, then
+     * this factory uses itself as the implementation.
+     *
+     * @param f the factory implementation that this factory will use
+     *      to produce threads
+     * @return the previously installed factory implementation
+     */
+    public synchronized ThreadFactory setImpl(ThreadFactory f) {
+
+        ThreadFactory old;
+
+        old     = factory;
+        factory = (f == null) ? this
+                              : f;
+
+        return old;
+    }
+
+    /**
+     * Retrieves the factory implementation that this factory is using
+     * to produce threads.
+     *
+     * @return the factory implementation that this factory is using to produce
+     * threads.
+     */
+    public synchronized ThreadFactory getImpl() {
+        return factory;
+    }
+}
diff --git a/src/org/hsqldb/lib/HsqlTimer.java b/src/org/hsqldb/lib/HsqlTimer.java
new file mode 100644
index 0000000..2d8034c
--- /dev/null
+++ b/src/org/hsqldb/lib/HsqlTimer.java
@@ -0,0 +1,959 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.Comparator;
+import java.util.Date;
+
+/**
+ * Facility to schedule tasks for future execution in a background thread.  <p>
+ *
+ * Tasks may be scheduled for one-time execution or for repeated execution at
+ * regular intervals, using either fixed rate or fixed delay policy. <p>
+ *
+ * This class is a JDK 1.1 compatible implementation required by HSQLDB both
+ * because the java.util.Timer class is available only in JDK 1.3+ and because
+ * java.util.Timer starves least recently added tasks under high load and
+ * fixed rate scheduling, especially when the average actual task duration is
+ * greater than the average requested task periodicity. <p>
+ *
+ * An additional (minor) advantage over java.util.Timer is that this class does
+ * not retain a live background thread during periods when the task queue is
+ * empty.
+ * @author boucherb@users
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public final class HsqlTimer implements Comparator, ThreadFactory {
+
+    /** The priority queue for the scheduled tasks. */
+    protected final TaskQueue taskQueue = new TaskQueue(16,
+        (Comparator) this);
+
+    /** The inner runnable that executes tasks in the background thread. */
+    protected final TaskRunner taskRunner = new TaskRunner();
+
+    /** The background thread. */
+    protected Thread taskRunnerThread;
+
+    /** The factory that procduces the background threads. */
+    protected final ThreadFactory threadFactory;
+
+    /**
+     * Whether this timer should disallow all further processing.
+     *
+     * Once set true, stays true forever.
+     */
+    protected volatile boolean isShutdown;
+
+    /**
+     * Constructs a new HsqlTimer using the default thread factory
+     * implementation.
+     */
+    public HsqlTimer() {
+        this(null);
+    }
+
+    /**
+     * Constructs a new HsqlTimer.
+     *
+     * Uses the specified thread factory implementation.
+     *
+     * @param threadFactory the ThreadFactory used to produce this timer's
+     *      background threads.  If null, the default implementation supplied
+     *      by this class will be used.
+     */
+    public HsqlTimer(final ThreadFactory threadFactory) {
+        this.threadFactory = (threadFactory == null) ? this
+                                                     : threadFactory;
+    }
+
+    /**
+     * Required to back the priority queue for scheduled tasks.
+     *
+     * @param a the first Task
+     * @param b the second Task
+     * @return 0 if equal, < 0 if a < b, > 0 if a > b
+     */
+    public int compare(final Object a, final Object b) {
+
+        final long awhen = ((Task) (a)).getNextScheduled();
+        final long bwhen = ((Task) (b)).getNextScheduled();
+
+        return (awhen < bwhen) ? -1
+                               : (awhen == bwhen) ? 0
+                                                  : 1;
+    }
+
+    /**
+     * Default ThreadFactory implementation. <p>
+     *
+     * Contructs a new Thread from the designated runnable, sets its
+     * name to "HSQLDB Timer @" + Integer.toHexString(hashCode()),
+     * and sets it as a daemon thread. <p>
+     *
+     * @param runnable used to construct the new Thread.
+     * @return a new Thread constructed from the designated runnable.
+     */
+    public Thread newThread(final Runnable runnable) {
+
+        final Thread thread = new Thread(runnable);
+
+        thread.setName("HSQLDB Timer @" + Integer.toHexString(hashCode()));
+        thread.setDaemon(true);
+
+        return thread;
+    }
+
+    /**
+     * Retrieves the background execution thread. <p>
+     *
+     * null is returned if there is no such thread. <p>
+     *
+     * @return the current background thread (may be null)
+     */
+    public synchronized Thread getThread() {
+        return this.taskRunnerThread;
+    }
+
+    /**
+     * (Re)starts background processing of the task queue.
+     *
+     * @throws IllegalStateException if this timer is shut down.
+     * @see #shutdown()
+     * @see #shutdownImmediately()
+     */
+    public synchronized void restart() throws IllegalStateException {
+
+        if (this.isShutdown) {
+            throw new IllegalStateException("isShutdown==true");
+        } else if (this.taskRunnerThread == null) {
+            this.taskRunnerThread =
+                this.threadFactory.newThread(this.taskRunner);
+
+            this.taskRunnerThread.start();
+        } else {
+            this.taskQueue.unpark();
+        }
+    }
+
+    /**
+     * Causes the specified Runnable to be executed once in the background
+     * after the specified delay.
+     *
+     * @param delay in milliseconds
+     * @param runnable the Runnable to execute.
+     * @return opaque reference to the internal task
+     * @throws IllegalArgumentException if runnable is null
+     */
+    public Object scheduleAfter(final long delay,
+                                final Runnable runnable)
+                                throws IllegalArgumentException {
+
+        if (runnable == null) {
+            throw new IllegalArgumentException("runnable == null");
+        }
+
+        return this.addTask(now() + delay, runnable, 0, false);
+    }
+
+    /**
+     * Causes the specified Runnable to be executed once in the background
+     * at the specified time.
+     *
+     * @param date time at which to execute the specified Runnable
+     * @param runnable the Runnable to execute.
+     * @return opaque reference to the internal task
+     * @throws IllegalArgumentException if date or runnable is null
+     */
+    public Object scheduleAt(final Date date,
+                             final Runnable runnable)
+                             throws IllegalArgumentException {
+
+        if (date == null) {
+            throw new IllegalArgumentException("date == null");
+        } else if (runnable == null) {
+            throw new IllegalArgumentException("runnable == null");
+        }
+
+        return this.addTask(date.getTime(), runnable, 0, false);
+    }
+
+    /**
+     * Causes the specified Runnable to be executed periodically in the
+     * background, starting at the specified time.
+     *
+     * @return opaque reference to the internal task
+     * @param period the cycle period
+     * @param relative if true, fixed rate sheduling else fixed delay scheduling
+     * @param date time at which to execute the specified Runnable
+     * @param runnable the Runnable to execute
+     * @throws IllegalArgumentException if date or runnable is null, or
+     *      period is <= 0
+     */
+    public Object schedulePeriodicallyAt(final Date date, final long period,
+                                         final Runnable runnable,
+                                         final boolean relative)
+                                         throws IllegalArgumentException {
+
+        if (date == null) {
+            throw new IllegalArgumentException("date == null");
+        } else if (period <= 0) {
+            throw new IllegalArgumentException("period <= 0");
+        } else if (runnable == null) {
+            throw new IllegalArgumentException("runnable == null");
+        }
+
+        return addTask(date.getTime(), runnable, period, relative);
+    }
+
+    /**
+     * Causes the specified Runnable to be executed periodically in the
+     * background, starting after the specified delay.
+     *
+     * @return opaque reference to the internal task
+     * @param period the cycle period
+     * @param relative if true, fixed rate sheduling else fixed delay scheduling
+     * @param delay in milliseconds
+     * @param runnable the Runnable to execute.
+     * @throws IllegalArgumentException if runnable is null or period is <= 0
+     */
+    public Object schedulePeriodicallyAfter(final long delay,
+            final long period, final Runnable runnable,
+            final boolean relative) throws IllegalArgumentException {
+
+        if (period <= 0) {
+            throw new IllegalArgumentException("period <= 0");
+        } else if (runnable == null) {
+            throw new IllegalArgumentException("runnable == null");
+        }
+
+        return addTask(now() + delay, runnable, period, relative);
+    }
+
+    /**
+     * Shuts down this timer after the current task (if any) completes. <p>
+     *
+     * After this call, the timer has permanently entered the shutdown state;
+     * attempting to schedule any new task or directly restart this timer will
+     * result in an  IllegalStateException. <p>
+     *
+     */
+    public synchronized void shutdown() {
+
+        if (!this.isShutdown) {
+            this.isShutdown = true;
+
+            this.taskQueue.cancelAllTasks();
+        }
+    }
+
+    /** for compatiblity with previous version */
+    public synchronized void shutDown() {
+        shutdown();
+    }
+
+    /**
+     * Shuts down this timer immediately, interrupting the wait state associated
+     * with the current head of the task queue or the wait state internal to
+     * the currently executing task, if any such state is currently in effect.
+     *
+     * After this call, the timer has permanently entered the shutdown state;
+     * attempting to schedule any new task or directly restart this timer will
+     * result in an IllegalStateException. <p>
+     *
+     * <b>Note:</b> If the integrity of work performed by a scheduled task
+     * may be adversely affected by an unplanned interruption, it is the
+     * responsibility of the task's implementation to deal correctly with the
+     * possibility that this method is called while such work is in progress,
+     * for instance by catching the InterruptedException, completing the work,
+     * and then rethrowing the exception.
+     */
+    public synchronized void shutdownImmediately() {
+
+        if (!this.isShutdown) {
+            final Thread runner = this.taskRunnerThread;
+
+            this.isShutdown = true;
+
+            if (runner != null && runner.isAlive()) {
+                runner.interrupt();
+            }
+
+            this.taskQueue.cancelAllTasks();
+        }
+    }
+
+    /**
+     * Causes the task referenced by the supplied argument to be cancelled.
+     * If the referenced task is currently executing, it will continue until
+     * finished but will not be rescheduled.
+     *
+     * @param task a task reference
+     */
+    public static void cancel(final Object task) {
+
+        if (task instanceof Task) {
+            ((Task) task).cancel();
+        }
+    }
+
+    /**
+     * Retrieves whether the specified argument references a cancelled task.
+     *
+     * @param task a task reference
+     * @return true if referenced task is cancelled
+     */
+    public static boolean isCancelled(final Object task) {
+        return (task instanceof Task) ? ((Task) task).isCancelled()
+                                      : true;
+    }
+
+    /**
+     * Retrieves whether the specified argument references a task scheduled
+     * periodically using fixed rate scheduling.
+     *
+     * @param task a task reference
+     * @return true if the task is scheduled at a fixed rate
+     */
+    public static boolean isFixedRate(final Object task) {
+
+        if (task instanceof Task) {
+            final Task ltask = (Task) task;
+
+            return (ltask.relative && ltask.period > 0);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Retrieves whether the specified argument references a task scheduled
+     * periodically using fixed delay scheduling.
+     *
+     * @param task a task reference
+     * @return true if the reference is scheduled using a fixed delay
+     */
+    public static boolean isFixedDelay(final Object task) {
+
+        if (task instanceof Task) {
+            final Task ltask = (Task) task;
+
+            return (!ltask.relative && ltask.period > 0);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Retrieves whether the specified argument references a task scheduled
+     * for periodic execution.
+     *
+     * @param task a task reference
+     * @return true if the task is scheduled for periodic execution
+     */
+    public static boolean isPeriodic(final Object task) {
+        return (task instanceof Task) ? (((Task) task).period > 0)
+                                      : false;
+    }
+
+    /**
+     * Retrieves the last time the referenced task was executed, as a
+     * Date object. If the task has never been executed, null is returned.
+     *
+     * @param task a task reference
+     * @return the last time the referenced task was executed; null if never
+     */
+    public static Date getLastScheduled(Object task) {
+
+        if (task instanceof Task) {
+            final Task ltask = (Task) task;
+            final long last  = ltask.getLastScheduled();
+
+            return (last == 0) ? null
+                               : new Date(last);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Sets the periodicity of the designated task to a new value. <p>
+     *
+     * If the designated task is cancelled or the new period is identical to the
+     * task's current period, then this invocation has essentially no effect
+     * and the submitted object is returned. <p>
+     *
+     * Otherwise, if the new period is greater than the designated task's
+     * current period, then a simple assignment occurs and the submittted
+     * object is returned. <p>
+     *
+     * If neither case holds, then the designated task is cancelled and a new,
+     * equivalent task with the new period is scheduled for immediate first
+     * execution and returned to the caller. <p>
+     *
+     * @return a task reference, as per the rules stated above.
+     * @param task the task whose periodicity is to be set
+     * @param period the new period
+     */
+    public static Object setPeriod(final Object task, final long period) {
+        return (task instanceof Task) ? ((Task) task).setPeriod(period)
+                                      : task;
+    }
+
+    /**
+     * Retrieves the next time the referenced task is due to be executed, as a
+     * Date object. If the referenced task is cancelled, null is returned.
+     *
+     * @param task a task reference
+     * @return the next time the referenced task is due to be executed
+     */
+    public static Date getNextScheduled(Object task) {
+
+        if (task instanceof Task) {
+            final Task ltask = (Task) task;
+            final long next  = ltask.isCancelled() ? 0
+                                                   : ltask.getNextScheduled();
+
+            return next == 0 ? null
+                             : new Date(next);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Adds to the task queue a new Task object encapsulating the supplied
+     * Runnable and scheduling arguments.
+     *
+     * @param first the time of the task's first execution
+     * @param runnable the Runnable to execute
+     * @param period the task's periodicity
+     * @param relative if true, use fixed rate else use fixed delay scheduling
+     * @return an opaque reference to the internal task
+     */
+    protected Task addTask(final long first, final Runnable runnable,
+                           final long period, boolean relative) {
+
+        if (this.isShutdown) {
+            throw new IllegalStateException("shutdown");
+        }
+
+        final Task task = new Task(first, runnable, period, relative);
+
+        // sychronized
+        this.taskQueue.addTask(task);
+
+        // sychronized
+        this.restart();
+
+        return task;
+    }
+
+    /** Sets the background thread to null. */
+    protected synchronized void clearThread() {
+
+//#ifdef JAVA2FULL
+        try {
+            taskRunnerThread.setContextClassLoader(null);
+        } catch (Throwable t) {}
+
+//#endif JAVA2FULL
+        taskRunnerThread = null;
+    }
+
+    /**
+     * Retrieves the next task to execute, or null if this timer is shutdown,
+     * the current thread is interrupted, or there are no queued tasks.
+     *
+     * @return the next task to execute, or null
+     */
+    protected Task nextTask() {
+
+        try {
+            while (!this.isShutdown || Thread.interrupted()) {
+                long now;
+                long next;
+                long wait;
+                Task task;
+
+                // synchronized to ensure removeTask
+                // applies only to the peeked task,
+                // when the computed wait <= 0
+                synchronized (this.taskQueue) {
+                    task = this.taskQueue.peekTask();
+
+                    if (task == null) {
+
+                        // queue is empty
+                        break;
+                    }
+
+                    now  = System.currentTimeMillis();
+                    next = task.next;
+                    wait = (next - now);
+
+                    if (wait > 0) {
+
+                        // release ownership of taskQueue monitor and await
+                        // notification of task addition or cancellation,
+                        // at most until the time when the peeked task is
+                        // next supposed to execute
+                        this.taskQueue.park(wait);
+
+                        continue;           // to top of loop
+                    } else {
+                        this.taskQueue.removeTask();
+                    }
+                }
+
+                long period = task.period;
+
+                if (period > 0) {           // repeated task
+                    if (task.relative) {    // using fixed rate shceduling
+                        final long late = (now - next);
+
+                        if (late > period) {
+
+                            // ensure that really late tasks don't
+                            // completely saturate the head of the
+                            // task queue
+                            period = 0;     /** @todo : is -1, -2 ... fairer? */
+                        } else if (late > 0) {
+
+                            // compensate for scheduling overruns
+                            period -= late;
+                        }
+                    }
+
+                    task.updateSchedule(now, now + period);
+                    this.taskQueue.addTask(task);
+                }
+
+                return task;
+            }
+        } catch (InterruptedException e) {
+
+            //e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    /**
+     * stats var
+     */
+    static int nowCount = 0;
+
+    /**
+     * Convenience method replacing the longer incantation:
+     * System.currentTimeMillis()
+     *
+     * @return System.currentTimeMillis()
+     */
+    static long now() {
+
+        nowCount++;
+
+        return System.currentTimeMillis();
+    }
+
+    /**
+     * The Runnable that the background thread uses to execute
+     * scheduled tasks. <p>
+     *
+     * <b>Note:</b> Outer class could simply implement Runnable,
+     * but using an inner class protects the public run method
+     * from potential abuse.
+     */
+    protected class TaskRunner implements Runnable {
+
+        /**
+         * Runs the next available task in the background thread. <p>
+         *
+         * When there are no available tasks, the background
+         * thread dies and its instance field is cleared until
+         * tasks once again become available.
+         */
+        public void run() {
+
+            try {
+                do {
+                    final Task task = HsqlTimer.this.nextTask();
+
+                    if (task == null) {
+                        break;
+                    }
+
+                    // PROBLEM: If the runnable throws an exception other
+                    //          than InterruptedException (which likely stems
+                    //          naturally from calling shutdownImmediately()
+                    //          or getThread().interrupt()), this will still
+                    //          cause the loop to exit, which is to say that
+                    //          task scheduling will stop until a new task is
+                    //          added or the timer is restarted directly, even
+                    //          though there may still be uncancelled tasks
+                    //          left on the queue.
+                    //
+                    // TODO:    Clarify and establish a contract regarding
+                    //          the difference between InterruptedException,
+                    //          RuntimeException and other things, like
+                    //          UndeclaredThrowableException.
+                    //
+                    // SOL'N:   At present, we simply require each runnable to
+                    //          understand its part of the implicit contract,
+                    //          which is to deal with exceptions internally
+                    //          (not throw them up to the timer), with the
+                    //          possible exception of InterruptedException.
+                    //
+                    //          If the integrity of work performed by the
+                    //          runnable may be adversely affected by an
+                    //          unplanned interruption, the runnable should
+                    //          deal with this directly, for instance by
+                    //          catching the InterruptedException, ensuring
+                    //          that some integrity preserving state is
+                    //          attained, and then rethrowing the exception.
+                    task.runnable.run();
+                } while (true);
+            } finally {
+                HsqlTimer.this.clearThread();
+            }
+        }
+    }
+
+    /**
+     * Encapsulates a Runnable and its scheduling attributes.
+     *
+     * Essentially, a wrapper class used to schedule a Runnable object
+     * for execution by the enclosing HsqlTimer's TaskRunner in a
+     * background thread.
+     */
+    protected class Task {
+
+        /** What to run. */
+        Runnable runnable;
+
+        /** The periodic interval, or 0 if one-shot. */
+        long period;
+
+        /** The time this task was last executed, or 0 if never. */
+        long last;
+
+        /** The next time this task is scheduled to execute. */
+        long next;
+
+        /**
+         * Whether to silently remove this task instead of running it,
+         * the next time (if ever) it makes its way to the head of the
+         * timer queue.
+         */
+        boolean cancelled = false;
+
+        /** Serializes concurrent access to the cancelled field. */
+        private Object cancel_mutex = new Object();
+
+        /**
+         * Scheduling policy flag. <p>
+         *
+         * When true, scheduling is fixed rate (as opposed to fixed delay),
+         * and schedule updates are calculated relative to when the task was
+         * was last run rather than a fixed delay starting from the current
+         * wall-clock time provided by System.currentTimeMillis().  <p>
+         *
+         * This helps normalize scheduling for tasks that must attempt to
+         * maintain a fixed rate of execution.
+         */
+        final boolean relative;
+
+        /**
+         * Constructs a new Task object encapulating the specified Runnable
+         * and scheduling arguments.
+         *
+         * @param first the first time to execute
+         * @param runnable the Runnable to execute
+         * @param period the periodicity of execution
+         * @param relative if true, use fixed rate scheduling else fixed delay
+         */
+        Task(final long first, final Runnable runnable, final long period,
+                final boolean relative) {
+
+            this.next     = first;
+            this.runnable = runnable;
+            this.period   = period;
+            this.relative = relative;
+        }
+
+        // fixed reported race condition
+
+        /** Sets this task's cancelled flag true and signals its taskQueue. */
+        void cancel() {
+
+            boolean signalCancelled = false;
+
+            synchronized (cancel_mutex) {
+                if (!cancelled) {
+                    cancelled = signalCancelled = true;
+                }
+            }
+
+            if (signalCancelled) {
+                HsqlTimer.this.taskQueue.signalTaskCancelled(this);
+            }
+        }
+
+        /**
+         * Retrieves whether this task is cancelled.
+         *
+         * @return true if cancelled, else false
+         */
+        boolean isCancelled() {
+
+            synchronized (cancel_mutex) {
+                return cancelled;
+            }
+        }
+
+        /**
+         * Retrieves the instant in time just before this task was
+         * last executed by the background thread. A value of zero
+         * indicates that this task has never been executed.
+         *
+         * @return the last time this task was executed or zero if never
+         */
+        synchronized long getLastScheduled() {
+            return last;
+        }
+
+        /**
+         * Retrieves the time at which this task is next scheduled for
+         * execution.
+         *
+         * @return the time at which this task is next scheduled for
+         *      execution
+         */
+        synchronized long getNextScheduled() {
+            return next;
+        }
+
+        /**
+         * Updates the last and next scheduled execution times.
+         *
+         * @param last when this task was last executed
+         * @param next when this task is to be next executed
+         */
+        synchronized void updateSchedule(final long last, final long next) {
+            this.last = last;
+            this.next = next;
+        }
+
+        /**
+         * Sets the new periodicity of this task in milliseconds. <p>
+         *
+         * If this task is cancelled or the new period is identical to the
+         * current period, then this invocation has essentailly no effect
+         * and this object is returned. <p>
+         *
+         * Otherwise, if the new period is greater than the current period, then
+         * a simple field assignment occurs and this object is returned. <p>
+         *
+         * If none of the previous cases hold, then this task is cancelled and
+         * a new, equivalent task with the new period is scheduled for
+         * immediate first execution and returned to the caller. <p>
+         *
+         * @param newPeriod the new period
+         * @return a task reference, as per the rules stated above.
+         */
+        synchronized Object setPeriod(final long newPeriod) {
+
+            if (this.period == newPeriod || this.isCancelled()) {
+                return this;
+            } else if (newPeriod > this.period) {
+                this.period = newPeriod;
+
+                return this;
+            } else {
+                this.cancel();
+
+                return HsqlTimer.this.addTask(now(), this.runnable, newPeriod,
+                                              this.relative);
+            }
+        }
+    }
+
+    /**
+     * Heap-based priority queue.
+     *
+     * Provides extensions to facilitate and simplify implementing
+     * timer functionality.
+     */
+    protected static class TaskQueue extends HsqlArrayHeap {
+
+        /**
+         * Constructs a new TaskQueue with the specified initial capacity and
+         * ObjectComparator.
+         *
+         * @param capacity the initial capacity of the queue
+         * @param oc The ObjectComparator this queue uses to maintain its
+         *      Heap invariant.
+         */
+        TaskQueue(final int capacity, final Comparator oc) {
+            super(capacity, oc);
+        }
+
+        /**
+         * Type-safe add method. <p>
+         *
+         * Can be used to inject debugging or accounting behaviour. <p>
+         *
+         * @param task the task to add
+         */
+        void addTask(final Task task) {
+
+            // System.out.println("task added: " + task);
+            super.add(task);
+        }
+
+        /**
+         * Atomically removes all tasks in this queue and then and cancels
+         * them.
+         */
+        void cancelAllTasks() {
+
+            Object[] oldHeap;
+            int      oldCount;
+
+            synchronized (this) {
+                oldHeap  = this.heap;
+                oldCount = this.count;
+
+                // 1 instead of 0 to avoid unintended aoob exceptions
+                this.heap  = new Object[1];
+                this.count = 0;
+            }
+
+            for (int i = 0; i < oldCount; i++) {
+                ((Task) oldHeap[i]).cancelled = true;
+            }
+        }
+
+        /**
+         * Causes the calling thread to wait until another thread invokes
+         * {@link #unpark() unpark} or the specified amount of time has
+         * elapsed.
+         *
+         * Implements the sync & wait(n) half of this queue's availability
+         * condition. <p>
+         *
+         * @param timeout the maximum time to wait in milliseconds.
+         * @throws java.lang.InterruptedException if another thread has
+         *    interrupted the current thread.  The <i>interrupted status</i> of
+         *    the current thread is cleared when this exception is thrown.
+         */
+        synchronized void park(final long timeout)
+        throws InterruptedException {
+            this.wait(timeout);
+        }
+
+        /**
+         * Retrieves the head of this queue, without removing it. <p>
+         *
+         * This method has the side-effect of removing tasks from the
+         * head of this queue until a non-cancelled task is encountered
+         * or this queue is empty. <p>
+         *
+         * If this queue is initially empty or is emptied in the process
+         * of finding the earliest scheduled non-cancelled task,
+         * then null is returned. <p>
+         *
+         * @return the earliest scheduled non-cancelled task, or null if no such
+         *      task exists
+         */
+        synchronized Task peekTask() {
+
+            while (super.heap[0] != null
+                    && ((Task) super.heap[0]).isCancelled()) {
+                super.remove();
+            }
+
+            return (Task) super.heap[0];
+        }
+
+        /**
+         * Informs this queue that the given task is supposedly cancelled. <p>
+         *
+         * If the indicated task is identical to the current head of
+         * this queue, then it is removed and this queue is
+         * {@link #unpark() unparked}. <p>
+         *
+         * The cancelled status of the given task is not verified; it is
+         * assumed that the caller is well-behaved (always passes a
+         * non-null reference to a cancelled task).
+         *
+         * @param task a supposedly cancelled task
+         */
+        synchronized void signalTaskCancelled(Task task) {
+
+            // We only care about the case where HsqlTimer.nextTask
+            // might be parked momentarily on this task.
+            if (task == super.heap[0]) {
+                super.remove();
+                this.notify();
+            }
+        }
+
+        /**
+         * Type-safe remove method. <p>
+         *
+         * Removes the head task from this queue. <p>
+         *
+         * Can be used to inject debugging or accounting behaviour. <p>
+         *
+         * @return this queue's head task or null if no such task exists
+         */
+        Task removeTask() {
+
+            // System.out.println("removing task...");
+            return (Task) super.remove();
+        }
+
+        /**
+         * Wakes up a single thread (if any) that is waiting on this queue's
+         * {@link #park(long) park} method.
+         *
+         * Implements the sync & notify half of this queue's availability
+         * condition.
+         */
+        synchronized void unpark() {
+            this.notify();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/InOutUtil.java b/src/org/hsqldb/lib/InOutUtil.java
new file mode 100644
index 0000000..b927a4b
--- /dev/null
+++ b/src/org/hsqldb/lib/InOutUtil.java
@@ -0,0 +1,111 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+/**
+ * Input / Output utility
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.7.2
+ */
+public class InOutUtil {
+
+    /**
+     * Implementation only supports unix line-end format and is suitable for
+     * processing HTTP and other network protocol communications. Reads and writes
+     * a line of data. Returns the number of bytes read/written.
+     */
+    public static int readLine(InputStream in,
+                               OutputStream out) throws IOException {
+
+        int count = 0;
+
+        for (;;) {
+            int b = in.read();
+
+            if (b == -1) {
+                break;
+            }
+
+            count++;
+
+            out.write(b);
+
+            if (b == '\n') {
+                break;
+            }
+        }
+
+        return count;
+    }
+
+    /**
+     * Retrieves the serialized form of the specified <CODE>Object</CODE>
+     * as an array of bytes.
+     *
+     * @param s the Object to serialize
+     * @return  a static byte array representing the passed Object
+     */
+    public static byte[] serialize(Serializable s) throws IOException {
+
+        HsqlByteArrayOutputStream bo = new HsqlByteArrayOutputStream();
+        ObjectOutputStream        os = new ObjectOutputStream(bo);
+
+        os.writeObject(s);
+
+        return bo.toByteArray();
+    }
+
+    /**
+     * Deserializes the specified byte array to an
+     * <CODE>Object</CODE> instance.
+     *
+     * @return the Object resulting from deserializing the specified array of bytes
+     * @param ba the byte array to deserialize to an Object
+     */
+    public static Serializable deserialize(byte[] ba)
+    throws IOException, ClassNotFoundException {
+
+        HsqlByteArrayInputStream bi = new HsqlByteArrayInputStream(ba);
+        ObjectInputStream        is = new ObjectInputStream(bi);
+
+        return (Serializable) is.readObject();
+    }
+}
diff --git a/src/org/hsqldb/lib/IntKeyHashMap.java b/src/org/hsqldb/lib/IntKeyHashMap.java
new file mode 100644
index 0000000..17fbbe1
--- /dev/null
+++ b/src/org/hsqldb/lib/IntKeyHashMap.java
@@ -0,0 +1,186 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class IntKeyHashMap extends BaseHashMap {
+
+    Set        keySet;
+    Collection values;
+
+    public IntKeyHashMap() {
+        this(8);
+    }
+
+    public IntKeyHashMap(int initialCapacity) throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.intKeyOrValue,
+              BaseHashMap.objectKeyOrValue, false);
+    }
+
+    public Object get(int key) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return objectValueTable[lookup];
+        }
+
+        return null;
+    }
+
+    public Object put(int key, Object value) {
+        return super.addOrRemove(key, value, null, false);
+    }
+
+    public boolean containsValue(Object value) {
+        return super.containsValue(value);
+    }
+
+    public Object remove(int key) {
+        return super.addOrRemove(key, null, null, true);
+    }
+
+    public boolean containsKey(int key) {
+        return super.containsKey(key);
+    }
+
+    public void valuesToArray(Object[] array) {
+
+        Iterator it = values().iterator();
+        int      i  = 0;
+
+        while (it.hasNext()) {
+            array[i] = it.next();
+
+            i++;
+        }
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return IntKeyHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return IntKeyHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            IntKeyHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return IntKeyHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return IntKeyHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            IntKeyHashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/IntKeyHashMapConcurrent.java b/src/org/hsqldb/lib/IntKeyHashMapConcurrent.java
new file mode 100644
index 0000000..50f507e
--- /dev/null
+++ b/src/org/hsqldb/lib/IntKeyHashMapConcurrent.java
@@ -0,0 +1,239 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class IntKeyHashMapConcurrent extends BaseHashMap {
+
+    Set        keySet;
+    Collection values;
+
+    //
+    ReentrantReadWriteLock           lock      = new ReentrantReadWriteLock(true);
+    ReentrantReadWriteLock.ReadLock  readLock  = lock.readLock();
+    ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
+
+    public IntKeyHashMapConcurrent() {
+        this(8);
+    }
+
+    public IntKeyHashMapConcurrent(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.intKeyOrValue,
+              BaseHashMap.objectKeyOrValue, false);
+    }
+
+    public ReentrantReadWriteLock.WriteLock getWriteLock() {
+        return writeLock;
+    }
+
+    public Object get(int key) {
+
+        try {
+            readLock.lock();
+
+            int lookup = getLookup(key);
+
+            if (lookup != -1) {
+                return objectValueTable[lookup];
+            }
+
+            return null;
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    public Object put(int key, Object value) {
+
+        try {
+            writeLock.lock();
+
+            return super.addOrRemove(key, 0, null, value, false);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public boolean containsValue(Object value) {
+
+        try {
+            readLock.lock();
+
+            return super.containsValue(value);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    public Object remove(int key) {
+
+        try {
+            writeLock.lock();
+
+            return super.addOrRemove(key, 0, null, null, true);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public boolean containsKey(int key) {
+
+        try {
+            readLock.lock();
+
+            return super.containsKey(key);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    public int getOrderedMatchCount(int[] array) {
+
+        int i = 0;
+
+        try {
+            readLock.lock();
+
+            for (; i < array.length; i++) {
+                if (!super.containsKey(array[i])) {
+                    break;
+                }
+            }
+
+            return i;
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return IntKeyHashMapConcurrent.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return IntKeyHashMapConcurrent.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            IntKeyHashMapConcurrent.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return IntKeyHashMapConcurrent.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return IntKeyHashMapConcurrent.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            IntKeyHashMapConcurrent.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/IntKeyIntValueHashMap.java b/src/org/hsqldb/lib/IntKeyIntValueHashMap.java
new file mode 100644
index 0000000..3a9dcab
--- /dev/null
+++ b/src/org/hsqldb/lib/IntKeyIntValueHashMap.java
@@ -0,0 +1,202 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class IntKeyIntValueHashMap extends BaseHashMap {
+
+    private Set        keySet;
+    private Collection values;
+
+    public IntKeyIntValueHashMap() {
+        this(8);
+    }
+
+    public IntKeyIntValueHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.intKeyOrValue,
+              BaseHashMap.intKeyOrValue, false);
+    }
+
+    public int get(int key) throws NoSuchElementException {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return intValueTable[lookup];
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public int get(int key, int defaultValue) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return intValueTable[lookup];
+        }
+
+        return defaultValue;
+    }
+
+    public boolean get(int key, int[] value) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            value[0] = intValueTable[lookup];
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean put(int key, int value) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, value, null, null, false);
+
+        return oldSize != size();
+    }
+
+    public boolean remove(int key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, 0, null, null, true);
+
+        return oldSize != size();
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return IntKeyIntValueHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return IntKeyIntValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            IntKeyIntValueHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return IntKeyIntValueHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return IntKeyIntValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            IntKeyIntValueHashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/IntKeyLongValueHashMap.java b/src/org/hsqldb/lib/IntKeyLongValueHashMap.java
new file mode 100644
index 0000000..ca0d29c
--- /dev/null
+++ b/src/org/hsqldb/lib/IntKeyLongValueHashMap.java
@@ -0,0 +1,107 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class IntKeyLongValueHashMap extends BaseHashMap {
+
+    public IntKeyLongValueHashMap() {
+        this(8);
+    }
+
+    public IntKeyLongValueHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.intKeyOrValue,
+              BaseHashMap.longKeyOrValue, false);
+    }
+
+    public long get(int key) throws NoSuchElementException {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return longValueTable[lookup];
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public long get(int key, int defaultValue) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return longValueTable[lookup];
+        }
+
+        return defaultValue;
+    }
+
+    public boolean get(int key, long[] value) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            value[0] = longValueTable[lookup];
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean put(int key, int value) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, value, null, null, false);
+
+        return oldSize != size();
+    }
+
+    public boolean remove(int key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, 0, null, null, true);
+
+        return oldSize != size();
+    }
+}
diff --git a/src/org/hsqldb/lib/IntLookup.java b/src/org/hsqldb/lib/IntLookup.java
new file mode 100644
index 0000000..0fabbd6
--- /dev/null
+++ b/src/org/hsqldb/lib/IntLookup.java
@@ -0,0 +1,49 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.8.0
+ */
+public interface IntLookup {
+
+    int add(int key, int value);
+
+    int lookupFirstEqual(int key) throws NoSuchElementException;
+
+    int lookupFirstGreaterEqual(int key) throws NoSuchElementException;
+}
diff --git a/src/org/hsqldb/lib/IntValueHashMap.java b/src/org/hsqldb/lib/IntValueHashMap.java
new file mode 100644
index 0000000..af93152
--- /dev/null
+++ b/src/org/hsqldb/lib/IntValueHashMap.java
@@ -0,0 +1,269 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * This class does not store null keys.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class IntValueHashMap extends BaseHashMap {
+
+    Set                keySet;
+    private Collection values;
+
+    public IntValueHashMap() {
+        this(8);
+    }
+
+    public IntValueHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.objectKeyOrValue,
+              BaseHashMap.intKeyOrValue, false);
+    }
+
+    public int get(Object key) throws NoSuchElementException {
+
+        if (key == null) {
+            throw new NoSuchElementException();
+        }
+
+        int hash   = key.hashCode();
+        int lookup = getLookup(key, hash);
+
+        if (lookup != -1) {
+            return intValueTable[lookup];
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public int get(Object key, int defaultValue) {
+
+        if (key == null) {
+            throw new NoSuchElementException();
+        }
+
+        int hash   = key.hashCode();
+        int lookup = getLookup(key, hash);
+
+        if (lookup != -1) {
+            return intValueTable[lookup];
+        }
+
+        return defaultValue;
+    }
+
+    public boolean get(Object key, int[] value) {
+
+        if (key == null) {
+            throw new NoSuchElementException();
+        }
+
+        int hash   = key.hashCode();
+        int lookup = getLookup(key, hash);
+
+        if (lookup != -1) {
+            value[0] = intValueTable[lookup];
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public Object getKey(int value) {
+
+        BaseHashIterator it = new BaseHashIterator(false);
+
+        while (it.hasNext()) {
+            int i = it.nextInt();
+
+            if (i == value) {
+                return objectKeyTable[it.getLookup()];
+            }
+        }
+
+        return null;
+    }
+
+    public boolean put(Object key, int value) {
+
+        if (key == null) {
+            throw new NoSuchElementException();
+        }
+
+        int oldSize = size();
+
+        super.addOrRemove(0, value, key, null, false);
+
+        return oldSize != size();
+    }
+
+    public boolean remove(Object key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(0, 0, key, null, true);
+
+        return oldSize != size();
+    }
+
+    public boolean containsKey(Object key) {
+        return super.containsKey(key);
+    }
+
+    public boolean containsValue(int value) {
+        throw new RuntimeException();
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return IntValueHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return IntValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            return containsKey(o);
+        }
+
+        public Object get(Object key) {
+
+            int lookup = IntValueHashMap.this.getLookup(key, key.hashCode());
+
+            if (lookup < 0) {
+                return null;
+            } else {
+                return IntValueHashMap.this.objectKeyTable[lookup];
+            }
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+
+            int oldSize = size();
+
+            IntValueHashMap.this.remove(o);
+
+            return size() != oldSize;
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            IntValueHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return IntValueHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return IntValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            IntValueHashMap.this.clear();
+        }
+    }
+
+    public void putAll(IntValueHashMap t) {
+
+        Iterator it = t.keySet().iterator();
+
+        while (it.hasNext()) {
+            Object key = it.next();
+
+            put(key, t.get(key));
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/Iterator.java b/src/org/hsqldb/lib/Iterator.java
new file mode 100644
index 0000000..43888bc
--- /dev/null
+++ b/src/org/hsqldb/lib/Iterator.java
@@ -0,0 +1,55 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public interface Iterator {
+
+    boolean hasNext();
+
+    Object next() throws NoSuchElementException;
+
+    int nextInt() throws NoSuchElementException;
+
+    long nextLong() throws NoSuchElementException;
+
+    void remove() throws NoSuchElementException;
+
+    void setValue(Object value);
+}
diff --git a/src/org/hsqldb/lib/LineGroupReader.java b/src/org/hsqldb/lib/LineGroupReader.java
new file mode 100644
index 0000000..c1acc61
--- /dev/null
+++ b/src/org/hsqldb/lib/LineGroupReader.java
@@ -0,0 +1,223 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.LineNumberReader;
+
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Uses a LineNumberReader and returns multiple consecutive lines which conform
+ * to the specified group demarcation characteristics. Any IOException
+ * thrown while reading from the reader is handled internally.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class LineGroupReader {
+
+    private final static String[] defaultContinuations = new String[] {
+        " ", "*"
+    };
+    private final static String[] defaultIgnoredStarts = new String[]{ "--" };
+    static final String LS = System.getProperty("line.separator", "\n");
+
+    //
+    LineNumberReader reader;
+    String           nextStartLine       = null;
+    int              startLineNumber     = 0;
+    int              nextStartLineNumber = 0;
+
+    //
+    final String[] sectionContinuations;
+    final String[] sectionStarts;
+    final String[] ignoredStarts;
+
+    /**
+     * Default constructor for TestUtil usage.
+     * Sections start at lines beginning with any non-space character.
+     * SQL comment lines are ignored.
+     */
+    public LineGroupReader(LineNumberReader reader) {
+
+        this.sectionContinuations = defaultContinuations;
+        this.sectionStarts        = ValuePool.emptyStringArray;
+        this.ignoredStarts        = defaultIgnoredStarts;
+        this.reader               = reader;
+
+        try {
+            getSection();
+        } catch (Exception e) {}
+    }
+
+    /**
+     * Constructor for sections starting with specified strings.
+     */
+    public LineGroupReader(LineNumberReader reader, String[] sectionStarts) {
+
+        this.sectionStarts        = sectionStarts;
+        this.sectionContinuations = ValuePool.emptyStringArray;
+        this.ignoredStarts        = ValuePool.emptyStringArray;
+        this.reader               = reader;
+
+        try {
+            getSection();
+        } catch (Exception e) {}
+    }
+
+    public HsqlArrayList getSection() {
+
+        String        line;
+        HsqlArrayList list = new HsqlArrayList();
+
+        if (nextStartLine != null) {
+            list.add(nextStartLine);
+
+            startLineNumber = nextStartLineNumber;
+        }
+
+        while (true) {
+            boolean newSection = false;
+
+            line = null;
+
+            try {
+                line = reader.readLine();
+            } catch (Exception e) {}
+
+            if (line == null) {
+                nextStartLine = null;
+
+                return list;
+            }
+
+            line = line.substring(
+                0, org.hsqldb.lib.StringUtil.rightTrimSize(line));
+
+            //if the line is blank or a comment, then ignore it
+            if (line.length() == 0 || isIgnoredLine(line)) {
+                continue;
+            }
+
+            if (isNewSectionLine(line)) {
+                newSection = true;
+            }
+
+            if (newSection) {
+                nextStartLine       = line;
+                nextStartLineNumber = reader.getLineNumber();
+
+                return list;
+            }
+
+            list.add(line);
+        }
+    }
+
+    /**
+     * Returns a map/list which contains the first line of each line group
+     * as key and the rest of the lines as a String value.
+     */
+    public HashMappedList getAsMap() {
+
+        HashMappedList map = new HashMappedList();
+
+        while (true) {
+            HsqlArrayList list = getSection();
+
+            if (list.size() < 1) {
+                break;
+            }
+
+            String key   = (String) list.get(0);
+            String value = LineGroupReader.convertToString(list, 1);
+
+            map.put(key, value);
+        }
+
+        return map;
+    }
+
+    private boolean isNewSectionLine(String line) {
+
+        if (sectionStarts.length == 0) {
+            for (int i = 0; i < sectionContinuations.length; i++) {
+                if (line.startsWith(sectionContinuations[i])) {
+                    return false;
+                }
+            }
+
+            return true;
+        } else {
+            for (int i = 0; i < sectionStarts.length; i++) {
+                if (line.startsWith(sectionStarts[i])) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    }
+
+    private boolean isIgnoredLine(String line) {
+
+        for (int i = 0; i < ignoredStarts.length; i++) {
+            if (line.startsWith(ignoredStarts[i])) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public int getStartLineNumber() {
+        return startLineNumber;
+    }
+
+    public void close() {
+        try {
+            reader.close();
+        } catch (Exception e) {}
+    }
+
+    public static String convertToString(HsqlArrayList list, int offset) {
+
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = offset; i < list.size(); i++) {
+            sb.append(list.get(i)).append(LS);
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/lib/LongDeque.java b/src/org/hsqldb/lib/LongDeque.java
new file mode 100644
index 0000000..096acf8
--- /dev/null
+++ b/src/org/hsqldb/lib/LongDeque.java
@@ -0,0 +1,311 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+/**
+ * A deque of long value. Implementation based on HsqlDeque class.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class LongDeque {
+
+    private long[] list;
+    private int    firstindex = 0;    // index of first list element
+    private int    endindex   = 0;    // index of last list element + 1
+    protected int  elementCount;
+
+    // can grow to fill list
+    // if elementCount == 0 then firstindex == endindex
+    private static final int DEFAULT_INITIAL_CAPACITY = 10;
+
+    public LongDeque() {
+        list = new long[DEFAULT_INITIAL_CAPACITY];
+    }
+
+    public int size() {
+        return elementCount;
+    }
+
+    public boolean isEmpty() {
+        return elementCount == 0;
+    }
+
+    public long getFirst() throws NoSuchElementException {
+
+        if (elementCount == 0) {
+            throw new NoSuchElementException();
+        }
+
+        return list[firstindex];
+    }
+
+    public long getLast() throws NoSuchElementException {
+
+        if (elementCount == 0) {
+            throw new NoSuchElementException();
+        }
+
+        return list[endindex - 1];
+    }
+
+    public long get(int i) throws IndexOutOfBoundsException {
+
+        int index = getInternalIndex(i);
+
+        return list[index];
+    }
+
+    public long removeFirst() throws NoSuchElementException {
+
+        if (elementCount == 0) {
+            throw new NoSuchElementException();
+        }
+
+        long value = list[firstindex];
+
+        list[firstindex] = 0;
+
+        firstindex++;
+        elementCount--;
+
+        if (elementCount == 0) {
+            firstindex = endindex = 0;
+        } else if (firstindex == list.length) {
+            firstindex = 0;
+        }
+
+        return value;
+    }
+
+    public long removeLast() throws NoSuchElementException {
+
+        if (elementCount == 0) {
+            throw new NoSuchElementException();
+        }
+
+        endindex--;
+
+        long value = list[endindex];
+
+        list[endindex] = 0;
+
+        elementCount--;
+
+        if (elementCount == 0) {
+            firstindex = endindex = 0;
+        } else if (endindex == 0) {
+            endindex = list.length;
+        }
+
+        return value;
+    }
+
+    public boolean add(long value) {
+
+        resetCapacity();
+
+        if (endindex == list.length) {
+            endindex = 0;
+        }
+
+        list[endindex] = value;
+
+        elementCount++;
+        endindex++;
+
+        return true;
+    }
+
+    public boolean addLast(long value) {
+        return add(value);
+    }
+
+    public boolean addFirst(long value) {
+
+        resetCapacity();
+
+        firstindex--;
+
+        if (firstindex < 0) {
+            firstindex = list.length - 1;
+
+            if (endindex == 0) {
+                endindex = list.length;
+            }
+        }
+
+        list[firstindex] = value;
+
+        elementCount++;
+
+        return true;
+    }
+
+    public void clear() {
+
+        if (elementCount == 0) {
+            return;
+        }
+
+        firstindex = endindex = elementCount = 0;
+
+        for (int i = 0; i < list.length; i++) {
+            list[i] = 0;
+        }
+    }
+
+    public int indexOf(long value) {
+
+        for (int i = 0; i < elementCount; i++) {
+            int index = firstindex + i;
+
+            if (index >= list.length) {
+                index -= list.length;
+            }
+
+            if (list[index] == value) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    public long remove(final int index) {
+
+        int  target = getInternalIndex(index);
+        long value  = list[target];
+
+        if (target == firstindex) {
+            list[firstindex] = 0;
+
+            firstindex++;
+
+            if (firstindex == list.length) {
+                firstindex = 0;
+            }
+        } else if (target > firstindex) {
+            System.arraycopy(list, firstindex, list, firstindex + 1,
+                             target - firstindex);
+
+            list[firstindex] = 0;
+
+            firstindex++;
+
+            if (firstindex == list.length) {
+                firstindex = 0;
+            }
+        } else {
+            System.arraycopy(list, target + 1, list, target,
+                             endindex - target - 1);
+
+            endindex--;
+
+            list[endindex] = 0;
+
+            if (endindex == 0) {
+                endindex = list.length;
+            }
+        }
+
+        elementCount--;
+
+        if (elementCount == 0) {
+            firstindex = endindex = 0;
+        }
+
+        return value;
+    }
+
+    public boolean contains(long value) {
+
+        for (int i = 0; i < elementCount; i++) {
+            int index = firstindex + i;
+
+            if (index >= list.length) {
+                index -= list.length;
+            }
+
+            if (list[index] == value) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public void toArray(int[] array) {
+
+        for (int i = 0; i < elementCount; i++) {
+            array[i] = (int) get(i);
+        }
+    }
+
+    private int getInternalIndex(int i) throws IndexOutOfBoundsException {
+
+        if (i < 0 || i >= elementCount) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        int index = firstindex + i;
+
+        if (index >= list.length) {
+            index -= list.length;
+        }
+
+        return index;
+    }
+
+    private void resetCapacity() {
+
+        if (elementCount < list.length) {
+            return;
+        }
+
+        long[] newList = new long[list.length * 2];
+
+        System.arraycopy(list, firstindex, newList, firstindex,
+                         list.length - firstindex);
+
+        if (endindex <= firstindex) {
+            System.arraycopy(list, 0, newList, list.length, endindex);
+
+            endindex = list.length + endindex;
+        }
+
+        list = newList;
+    }
+}
diff --git a/src/org/hsqldb/lib/LongKeyHashMap.java b/src/org/hsqldb/lib/LongKeyHashMap.java
new file mode 100644
index 0000000..399342e
--- /dev/null
+++ b/src/org/hsqldb/lib/LongKeyHashMap.java
@@ -0,0 +1,188 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class LongKeyHashMap extends BaseHashMap {
+
+    Set        keySet;
+    Collection values;
+
+    public LongKeyHashMap() {
+        this(16);
+    }
+
+    public LongKeyHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.longKeyOrValue,
+              BaseHashMap.objectKeyOrValue, false);
+    }
+
+    public Object get(long key) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return objectValueTable[lookup];
+        }
+
+        return null;
+    }
+
+    public Object put(long key, Object value) {
+        return super.addOrRemove(key, 0, null, value, false);
+    }
+
+    public boolean containsValue(Object value) {
+        return super.containsValue(value);
+    }
+
+    public Object remove(long key) {
+        return super.addOrRemove(key, 0, null, null, true);
+    }
+
+    public boolean containsKey(long key) {
+        return super.containsKey(key);
+    }
+
+    public int getOrderedMatchCount(int[] array) {
+
+        int i = 0;
+
+        for (; i < array.length; i++) {
+            if (!super.containsKey(array[i])) {
+                break;
+            }
+        }
+
+        return i;
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return LongKeyHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return LongKeyHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            LongKeyHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return LongKeyHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return LongKeyHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            LongKeyHashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/LongKeyIntValueHashMap.java b/src/org/hsqldb/lib/LongKeyIntValueHashMap.java
new file mode 100644
index 0000000..b9fbbdf
--- /dev/null
+++ b/src/org/hsqldb/lib/LongKeyIntValueHashMap.java
@@ -0,0 +1,213 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class LongKeyIntValueHashMap extends BaseHashMap {
+
+    private Set        keySet;
+    private Collection values;
+
+    public LongKeyIntValueHashMap() {
+        this(8);
+    }
+
+    public LongKeyIntValueHashMap(boolean minimize) {
+
+        this(8);
+
+        minimizeOnEmpty = minimize;
+    }
+
+    public LongKeyIntValueHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.longKeyOrValue,
+              BaseHashMap.intKeyOrValue, false);
+    }
+
+    public int get(long key) throws NoSuchElementException {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return intValueTable[lookup];
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public int get(long key, int defaultValue) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return intValueTable[lookup];
+        }
+
+        return defaultValue;
+    }
+
+    public boolean get(long key, int[] value) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            value[0] = intValueTable[lookup];
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public int getLookup(long key) {
+        return super.getLookup(key);
+    }
+
+    public boolean put(long key, int value) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, value, null, null, false);
+
+        return oldSize != size();
+    }
+
+    public boolean remove(long key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, 0, null, null, true);
+
+        return oldSize != size();
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return LongKeyIntValueHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return LongKeyIntValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            LongKeyIntValueHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return LongKeyIntValueHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return LongKeyIntValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            LongKeyIntValueHashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/LongKeyLongValueHashMap.java b/src/org/hsqldb/lib/LongKeyLongValueHashMap.java
new file mode 100644
index 0000000..ff42a33
--- /dev/null
+++ b/src/org/hsqldb/lib/LongKeyLongValueHashMap.java
@@ -0,0 +1,209 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class LongKeyLongValueHashMap extends BaseHashMap {
+
+    private Set        keySet;
+    private Collection values;
+
+    public LongKeyLongValueHashMap() {
+        this(8);
+    }
+
+    public LongKeyLongValueHashMap(boolean minimize) {
+
+        this(8);
+
+        minimizeOnEmpty = minimize;
+    }
+
+    public LongKeyLongValueHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.longKeyOrValue,
+              BaseHashMap.longKeyOrValue, false);
+    }
+
+    public long get(long key) throws NoSuchElementException {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return longValueTable[lookup];
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public long get(long key, long defaultValue) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return longValueTable[lookup];
+        }
+
+        return defaultValue;
+    }
+
+    public boolean get(long key, long[] value) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            value[0] = longValueTable[lookup];
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean put(long key, long value) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, value, null, null, false);
+
+        return oldSize != size();
+    }
+
+    public boolean remove(long key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, 0, null, null, true);
+
+        return oldSize != size();
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return LongKeyLongValueHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return LongKeyLongValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            LongKeyLongValueHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return LongKeyLongValueHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return LongKeyLongValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            LongKeyLongValueHashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/LongValueHashMap.java b/src/org/hsqldb/lib/LongValueHashMap.java
new file mode 100644
index 0000000..4086df3
--- /dev/null
+++ b/src/org/hsqldb/lib/LongValueHashMap.java
@@ -0,0 +1,220 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * This class does not store null keys.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class LongValueHashMap extends BaseHashMap {
+
+    Set keySet;
+
+    public LongValueHashMap() {
+        this(8);
+    }
+
+    public LongValueHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.objectKeyOrValue,
+              BaseHashMap.longKeyOrValue, false);
+    }
+
+    public long get(Object key) throws NoSuchElementException {
+
+        if (key == null) {
+            throw new NoSuchElementException();
+        }
+
+        int hash   = key.hashCode();
+        int lookup = getLookup(key, hash);
+
+        if (lookup != -1) {
+            return longValueTable[lookup];
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public long get(Object key, int defaultValue) {
+
+        if (key == null) {
+            throw new NoSuchElementException();
+        }
+
+        int hash   = key.hashCode();
+        int lookup = getLookup(key, hash);
+
+        if (lookup != -1) {
+            return longValueTable[lookup];
+        }
+
+        return defaultValue;
+    }
+
+    public boolean get(Object key, long[] value) {
+
+        if (key == null) {
+            throw new NoSuchElementException();
+        }
+
+        int hash   = key.hashCode();
+        int lookup = getLookup(key, hash);
+
+        if (lookup != -1) {
+            value[0] = longValueTable[lookup];
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public Object getKey(long value) {
+
+        BaseHashIterator it = new BaseHashIterator(false);
+
+        while (it.hasNext()) {
+            long i = it.nextLong();
+
+            if (i == value) {
+                return objectKeyTable[it.getLookup()];
+            }
+        }
+
+        return null;
+    }
+
+    public boolean put(Object key, long value) {
+
+        if (key == null) {
+            throw new NoSuchElementException();
+        }
+
+        int oldSize = size();
+
+        super.addOrRemove(0, value, key, null, false);
+
+        return oldSize != size();
+    }
+
+    public boolean remove(Object key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(0, 0, key, null, true);
+
+        return oldSize != size();
+    }
+
+    public boolean containsKey(Object key) {
+        return super.containsKey(key);
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return LongValueHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return LongValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            return containsKey(o);
+        }
+
+        public Object get(Object key) {
+
+            int lookup = LongValueHashMap.this.getLookup(key, key.hashCode());
+
+            if (lookup < 0) {
+                return null;
+            } else {
+                return LongValueHashMap.this.objectKeyTable[lookup];
+            }
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+
+            int oldSize = size();
+
+            LongValueHashMap.this.remove(o);
+
+            return size() != oldSize;
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            LongValueHashMap.this.clear();
+        }
+    }
+
+    public void putAll(LongValueHashMap t) {
+
+        Iterator it = t.keySet().iterator();
+
+        while (it.hasNext()) {
+            Object key = it.next();
+
+            put(key, t.get(key));
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/MD5.java b/src/org/hsqldb/lib/MD5.java
new file mode 100644
index 0000000..743c73c
--- /dev/null
+++ b/src/org/hsqldb/lib/MD5.java
@@ -0,0 +1,166 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Provides a static utility interface to an MD5 digest algorithm
+ * obtained through the java.security.MessageDigest spi. <p>
+ *
+ * Database end-users may wish to access the services of this class
+ * to provide, for instance, application user lookup tables with
+ * one-way password encryption.  For example: <p>
+ *
+ * <pre>
+ * -- DDL
+ * CREATE TABLE USERS(UID INTEGER IDENTITY, UNAME VARCHAR, UPASS VARCHAR, UNIQUE(UNAME))
+ * CREATE FUNCTION MD5(VARCHAR(100)) RETURNS VARCHAR(16) LANGUAGE JAVA EXTERNAL NAME "org.hsqldb.lib.MD5.encode"
+ *
+ * -- DML & DQL
+ * INSERT INTO USERS(UNAME, UPASS) VALUES('joe', MD5('passwd'))
+ * UPDATE USERS SET UPASS = MD5('newpasswd') WHERE UNAME = 'joe' AND UPASS = MD5('oldpasswd')
+ * SELECT UID FROM USERS WHERE UNAME = 'joe' AND UPASS = MD5('logonpasswd')
+ * </pre>
+ *
+ * <b>NOTE:</b> <p>
+ *
+ * Although it is possible that a particular JVM / application installation may
+ * encounter NoSuchAlgorithmException when attempting to get a jce MD5 message
+ * digest generator, the likelyhood is very small for almost all JDK/JRE 1.1
+ * and later  JVM implementations, as the Sun java.security package has come,
+ * by default, with a jce MD5 message digest generator since JDK 1.1 was
+ * released.  The HSLQLDB project could have provided an MD5 implementation to
+ * guarantee presence, but this class is much more lightweight and still allows
+ * clients to install / use  custom implementations through the
+ * java.security.MessageDigest spi, for instance if there is no service
+ * provided by default under the target JVM of choice or if a client has
+ * developed / provides, say, a faster MD5 message digest implementation.
+ * In short, this class is a convenience that allows HSQLDB SQL Function and
+ * Stored Procedure style access to any underlying MD5 message digest algorithm
+ * obtained via the java.security.MessageDigest spi
+ *
+ * @author boucherb@users.sourceforge.net
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class MD5 {
+
+    /**
+     * The jce MD5 message digest generator.
+     */
+    private static MessageDigest md5;
+
+    /**
+     * Retrieves a hexidecimal character sequence representing the MD5
+     * digest of the specified character sequence, using the specified
+     * encoding to first convert the character sequence into a byte sequence.
+     * If the specified encoding is null, then ISO-8859-1 is assumed
+     *
+     * @param string the string to encode.
+     * @param encoding the encoding used to convert the string into the
+     *      byte sequence to submit for MD5 digest
+     * @return a hexidecimal character sequence representing the MD5
+     *      digest of the specified string
+     * @throws HsqlUnsupportedOperationException if an MD5 digest
+     *      algorithm is not available through the
+     *      java.security.MessageDigest spi or the requested
+     *      encoding is not available
+     */
+    public static final String encode(String string,
+            String encoding) throws RuntimeException {
+        return StringConverter.byteArrayToHexString(digest(string,
+                encoding));
+    }
+
+    /**
+     * Retrieves a byte sequence representing the MD5 digest of the
+     * specified character sequence, using the specified encoding to
+     * first convert the character sequence into a byte sequence.
+     * If the specified encoding is null, then ISO-8859-1 is
+     * assumed.
+     *
+     * @param string the string to digest.
+     * @param encoding the character encoding.
+     * @return the digest as an array of 16 bytes.
+     * @throws HsqlUnsupportedOperationException if an MD5 digest
+     *      algorithm is not available through the
+     *      java.security.MessageDigest spi or the requested
+     *      encoding is not available
+     */
+    public static byte[] digest(String string,
+                                      String encoding)
+                                      throws RuntimeException {
+
+        byte[] data;
+
+        if (encoding == null) {
+            encoding = "ISO-8859-1";
+        }
+
+        try {
+            data = string.getBytes(encoding);
+        } catch (UnsupportedEncodingException x) {
+            throw new RuntimeException(x.toString());
+        }
+
+        return digest(data);
+    }
+
+    /**
+     * Retrieves a byte sequence representing the MD5 digest of the
+     * specified byte sequence.
+     *
+     * @param data the data to digest.
+     * @return the MD5 digest as an array of 16 bytes.
+     * @throws HsqlUnsupportedOperationException if an MD5 digest
+     *       algorithm is not available through the
+     *       java.security.MessageDigest spi
+     */
+    public static final byte[] digest(byte[] data)
+    throws RuntimeException {
+
+        synchronized (MD5.class) {
+            if (md5 == null) {
+                try {
+                    md5 = MessageDigest.getInstance("MD5");
+                } catch (NoSuchAlgorithmException e) {
+                    throw new RuntimeException(e.toString());
+                }
+            }
+
+            return md5.digest(data);
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/MultiValueHashMap.java b/src/org/hsqldb/lib/MultiValueHashMap.java
new file mode 100644
index 0000000..59f7cc6
--- /dev/null
+++ b/src/org/hsqldb/lib/MultiValueHashMap.java
@@ -0,0 +1,197 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * Stores multiple values per key
+ * This class does not store null keys.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class MultiValueHashMap extends BaseHashMap {
+
+    Set        keySet;
+    Collection values;
+    Iterator   valueIterator;
+
+    public MultiValueHashMap() {
+        this(8);
+    }
+
+    public MultiValueHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+
+        super(initialCapacity, BaseHashMap.objectKeyOrValue,
+              BaseHashMap.objectKeyOrValue, false);
+
+        super.multiValueTable = new boolean[super.objectValueTable.length];
+    }
+
+    public Iterator get(Object key) {
+
+        int hash = key.hashCode();
+
+        return super.getValuesIterator(key, hash);
+    }
+
+    public Object put(Object key, Object value) {
+        return super.addOrRemoveMultiVal(0, 0, key, value, false, false);
+    }
+
+    public Object remove(Object key) {
+        return super.addOrRemoveMultiVal(0, 0, key, null, true, false);
+    }
+
+    public Object remove(Object key, Object value) {
+        return super.addOrRemoveMultiVal(0, 0, key, value, false, true);
+    }
+
+    public boolean containsKey(Object key) {
+        return super.containsKey(key);
+    }
+
+    public boolean containsValue(Object value) {
+        return super.containsValue(value);
+    }
+
+    public void putAll(HashMap t) {
+
+        Iterator it = t.keySet.iterator();
+
+        while (it.hasNext()) {
+            Object key = it.next();
+
+            put(key, t.get(key));
+        }
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return MultiValueHashMap.this.new MultiValueKeyIterator();
+        }
+
+        public int size() {
+            return MultiValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            return containsKey(o);
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+
+            int oldSize = size();
+
+            MultiValueHashMap.this.remove(o);
+
+            return size() != oldSize;
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            MultiValueHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return MultiValueHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return MultiValueHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            MultiValueHashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/OrderedHashSet.java b/src/org/hsqldb/lib/OrderedHashSet.java
new file mode 100644
index 0000000..c993f53
--- /dev/null
+++ b/src/org/hsqldb/lib/OrderedHashSet.java
@@ -0,0 +1,191 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * Implementation of an ordered Set which maintains the inserted order of
+ * elements and allows access by index. Iterators return the
+ * elements in the index order.
+ *
+ * This class does not store null elements.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class OrderedHashSet extends HashSet implements HsqlList, Set {
+
+    public OrderedHashSet() {
+
+        super(8);
+
+        isList = true;
+    }
+
+    public boolean remove(Object key) {
+
+        int oldSize = size();
+
+        super.removeObject(key, true);
+
+        return oldSize != size();
+    }
+
+    public Object remove(int index) throws IndexOutOfBoundsException {
+
+        checkRange(index);
+
+        Object result = objectKeyTable[index];
+
+        remove(result);
+
+        return result;
+    }
+
+    public boolean insert(int index,
+                          Object key) throws IndexOutOfBoundsException {
+
+        if (index < 0 || index > size()) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        if (contains(key)) {
+            return false;
+        }
+
+        if (index == size()) {
+            return add(key);
+        }
+
+        Object[] set = toArray(new Object[size()]);
+
+        super.clear();
+
+        for (int i = 0; i < index; i++) {
+            add(set[i]);
+        }
+
+        add(key);
+
+        for (int i = index; i < set.length; i++) {
+            add(set[i]);
+        }
+
+        return true;
+    }
+
+    public Object set(int index, Object key) throws IndexOutOfBoundsException {
+        throw new IndexOutOfBoundsException();
+    }
+
+    public void add(int index, Object key) throws IndexOutOfBoundsException {
+        throw new IndexOutOfBoundsException();
+    }
+
+    public Object get(int index) throws IndexOutOfBoundsException {
+
+        checkRange(index);
+
+        return objectKeyTable[index];
+    }
+
+    public int getIndex(Object key) {
+        return getLookup(key, key.hashCode());
+    }
+
+    public int getLargestIndex(OrderedHashSet other) {
+
+        int max = -1;
+
+        for (int i = 0, size = other.size(); i < size; i++) {
+            int index = getIndex(other.get(i));
+
+            if (index > max) {
+                max = index;
+            }
+        }
+
+        return max;
+    }
+
+    public int getCommonElementCount(Set other) {
+
+        int count = 0;
+
+        for (int i = 0, size = size(); i < size; i++) {
+            if (other.contains(objectKeyTable[i])) {
+                count++;
+            }
+        }
+
+        return count;
+    }
+
+    public static OrderedHashSet addAll(OrderedHashSet first,
+                                          OrderedHashSet second) {
+
+        if (second == null) {
+            return first;
+        }
+
+        if (first == null) {
+            first = new OrderedHashSet();
+        }
+
+        first.addAll(second);
+
+        return first;
+    }
+
+    public static OrderedHashSet add(OrderedHashSet first,
+                                          Object value) {
+
+        if (value == null) {
+            return first;
+        }
+
+        if (first == null) {
+            first = new OrderedHashSet();
+        }
+
+        first.add(value);
+
+        return first;
+    }
+
+    private void checkRange(int i) {
+
+        if (i < 0 || i >= size()) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/OrderedIntHashSet.java b/src/org/hsqldb/lib/OrderedIntHashSet.java
new file mode 100644
index 0000000..207f91f
--- /dev/null
+++ b/src/org/hsqldb/lib/OrderedIntHashSet.java
@@ -0,0 +1,161 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class OrderedIntHashSet extends BaseHashMap {
+
+    public OrderedIntHashSet() {
+        this(8);
+    }
+
+    public OrderedIntHashSet(int initialCapacity)
+    throws IllegalArgumentException {
+
+        super(initialCapacity, BaseHashMap.intKeyOrValue,
+              BaseHashMap.noKeyOrValue, false);
+
+        isList = true;
+    }
+
+    public boolean contains(int key) {
+        return super.containsKey(key);
+    }
+
+    public boolean add(int key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, 0, null, null, false);
+
+        return oldSize != size();
+    }
+
+    public boolean remove(int key) {
+
+        int oldSize = size();
+
+        super.addOrRemove(key, 0, null, null, true);
+
+        boolean result = oldSize != size();
+
+        if (result) {
+            int[] array = toArray();
+
+            super.clear();
+
+            for (int i = 0; i < array.length; i++) {
+                add(array[i]);
+            }
+        }
+
+        return result;
+    }
+
+    public int get(int index) {
+
+        checkRange(index);
+
+        return intKeyTable[index];
+    }
+
+    public int getIndex(int value) {
+        return getLookup(value);
+    }
+
+    public int getStartMatchCount(int[] array) {
+
+        int i = 0;
+
+        for (; i < array.length; i++) {
+            if (!super.containsKey(array[i])) {
+                break;
+            }
+        }
+
+        return i;
+    }
+
+    public int getOrderedStartMatchCount(int[] array) {
+
+        int i = 0;
+
+        for (; i < array.length; i++) {
+            if (i >= size() || get(i) != array[i]) {
+                break;
+            }
+        }
+
+        return i;
+    }
+
+    public boolean addAll(Collection col) {
+
+        int      oldSize = size();
+        Iterator it      = col.iterator();
+
+        while (it.hasNext()) {
+            add(it.nextInt());
+        }
+
+        return oldSize != size();
+    }
+
+    public int[] toArray() {
+
+        int   lookup = -1;
+        int[] array  = new int[size()];
+
+        for (int i = 0; i < array.length; i++) {
+            lookup = super.nextLookup(lookup);
+
+            int value = intKeyTable[lookup];
+
+            array[i] = value;
+        }
+
+        return array;
+    }
+
+    private void checkRange(int i) {
+
+        if (i < 0 || i >= size()) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/OrderedIntKeyHashMap.java b/src/org/hsqldb/lib/OrderedIntKeyHashMap.java
new file mode 100644
index 0000000..9c9af98
--- /dev/null
+++ b/src/org/hsqldb/lib/OrderedIntKeyHashMap.java
@@ -0,0 +1,201 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class OrderedIntKeyHashMap extends BaseHashMap {
+
+    Set        keySet;
+    Collection values;
+
+    public OrderedIntKeyHashMap() {
+        this(8);
+    }
+
+    public OrderedIntKeyHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+
+        super(initialCapacity, BaseHashMap.intKeyOrValue,
+              BaseHashMap.objectKeyOrValue, false);
+
+        isList = true;
+    }
+
+    public Object get(int key) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return objectValueTable[lookup];
+        }
+
+        return null;
+    }
+
+    public Object put(int key, Object value) {
+        return super.addOrRemove(key, value, null, false);
+    }
+
+    public boolean containsValue(Object value) {
+        return super.containsValue(value);
+    }
+
+    public Object remove(int key) {
+
+        int lookup = getLookup(key, key);
+
+        if (lookup < 0) {
+            return null;
+        }
+
+        Object returnValue = super.addOrRemove(key, null, null, true);
+
+        removeRow(lookup);
+
+        return returnValue;
+    }
+
+    public boolean containsKey(int key) {
+        return super.containsKey(key);
+    }
+
+    public void valuesToArray(Object[] array) {
+
+        Iterator it = values().iterator();
+        int      i  = 0;
+
+        while (it.hasNext()) {
+            array[i] = it.next();
+
+            i++;
+        }
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return OrderedIntKeyHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return OrderedIntKeyHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            OrderedIntKeyHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return OrderedIntKeyHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return OrderedIntKeyHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            OrderedIntKeyHashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/OrderedLongKeyHashMap.java b/src/org/hsqldb/lib/OrderedLongKeyHashMap.java
new file mode 100644
index 0000000..347e4eb
--- /dev/null
+++ b/src/org/hsqldb/lib/OrderedLongKeyHashMap.java
@@ -0,0 +1,233 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class OrderedLongKeyHashMap extends BaseHashMap {
+
+    Set        keySet;
+    Collection values;
+
+    public OrderedLongKeyHashMap() {
+        this(8);
+    }
+
+    public OrderedLongKeyHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+
+        super(initialCapacity, BaseHashMap.longKeyOrValue,
+              BaseHashMap.objectKeyOrValue, false);
+
+        isList = true;
+    }
+
+    public OrderedLongKeyHashMap(int initialCapacity,
+                                boolean hasThirdValue)
+                                throws IllegalArgumentException {
+
+        super(initialCapacity, BaseHashMap.longKeyOrValue,
+              BaseHashMap.objectKeyOrValue, false);
+
+        objectKeyTable   = new Object[objectValueTable.length];
+        isTwoObjectValue = true;
+        isList           = true;
+
+        if (hasThirdValue) {
+            objectValueTable2 = new Object[objectValueTable.length];
+        }
+    }
+
+    public Object get(long key) {
+
+        int lookup = getLookup(key);
+
+        if (lookup != -1) {
+            return objectValueTable[lookup];
+        }
+
+        return null;
+    }
+
+    public Object getValueByIndex(int index) {
+        return objectValueTable[index];
+    }
+
+    public Object getSecondValueByIndex(int index) {
+        return objectKeyTable[index];
+    }
+
+    public Object getThirdValueByIndex(int index) {
+        return objectValueTable2[index];
+    }
+
+    public Object setThirdValueByIndex(int index, Object value) {
+
+        Object oldValue = objectValueTable2[index];
+
+        objectValueTable2[index] = value;
+
+        return oldValue;
+    }
+
+    public Object put(long key, Object value) {
+        return super.addOrRemove(key, value, null, false);
+    }
+
+    public boolean containsValue(Object value) {
+        return super.containsValue(value);
+    }
+
+    public Object remove(long key) {
+        return super.addOrRemove(key, null, null, false);
+    }
+
+    public boolean containsKey(long key) {
+        return super.containsKey(key);
+    }
+
+    /* methods for two object lookups */
+    public Object put(long key, Object valueOne, Object valueTwo) {
+        return super.addOrRemove(key, valueOne, valueTwo, false);
+    }
+
+    public int getLookup(long key) {
+        return super.getLookup(key);
+    }
+
+    public Object getFirstByLookup(int lookup) {
+
+        if (lookup == -1) {
+            return null;
+        }
+
+        return objectValueTable[lookup];
+    }
+
+    public Set keySet() {
+
+        if (keySet == null) {
+            keySet = new KeySet();
+        }
+
+        return keySet;
+    }
+
+    public Collection values() {
+
+        if (values == null) {
+            values = new Values();
+        }
+
+        return values;
+    }
+
+    class KeySet implements Set {
+
+        public Iterator iterator() {
+            return OrderedLongKeyHashMap.this.new BaseHashIterator(true);
+        }
+
+        public int size() {
+            return OrderedLongKeyHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public Object get(Object key) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            OrderedLongKeyHashMap.this.clear();
+        }
+    }
+
+    class Values implements Collection {
+
+        public Iterator iterator() {
+            return OrderedLongKeyHashMap.this.new BaseHashIterator(false);
+        }
+
+        public int size() {
+            return OrderedLongKeyHashMap.this.size();
+        }
+
+        public boolean contains(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean add(Object value) {
+            throw new RuntimeException();
+        }
+
+        public boolean addAll(Collection c) {
+            throw new RuntimeException();
+        }
+
+        public boolean remove(Object o) {
+            throw new RuntimeException();
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public void clear() {
+            OrderedLongKeyHashMap.this.clear();
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/RCData.java b/src/org/hsqldb/lib/RCData.java
new file mode 100644
index 0000000..db6c434
--- /dev/null
+++ b/src/org/hsqldb/lib/RCData.java
@@ -0,0 +1,494 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+/* $Id: RCData.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/**
+ * Manages all the details we need to connect up to JDBC database(s),
+ * in a declarative way.
+ * <P>
+ * The file <CODE>src/org/hsqldb/sample/SqlFileEmbedder.java</CODE>
+ * in the HSQLDB distribution provides an example of how to use RCData for your
+ * own programs.
+ * <P/>
+ *
+ * @see <A href="../../../../util-guide/sqltool-chapt.html#sqltool_auth-sect"
+ *      target="guide">
+ *     The RC File section of the HyperSQL Utilities Guide</A>
+ * @see org.hsqldb.sample.SqlFileEmbedder
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class RCData {
+
+    public static final String DEFAULT_JDBC_DRIVER   = "org.hsqldb.jdbc.JDBCDriver";
+    private String             defaultJdbcDriverName = DEFAULT_JDBC_DRIVER;
+
+    public void setDefaultJdbcDriver(String defaultJdbcDriverName) {
+        this.defaultJdbcDriverName = defaultJdbcDriverName;
+    }
+
+    public String getDefaultJdbcDriverName() {
+        return defaultJdbcDriverName;
+    }
+
+    /**
+     * DISABLED DUE TO SECURITY CONCERNS.
+     * Just for testing and debugging.
+     *
+     * N.b. this echoes passwords!
+    public void report() {
+        System.err.println("urlid: " + id + ", url: " + url + ", username: "
+                           + username + ", password: " + password);
+    }
+     */
+
+    /**
+     * Creates a RCDataObject by looking up the given key in the
+     * given authentication file.
+     *
+     * @param dbKey Key to look up in the file.
+     *              If null, then will echo all urlids in the file to stdout.
+     *              (A rather ill-conceived design).
+     * @param file File containing the authentication information.
+     */
+    public RCData(File file, String dbKey) throws Exception {
+
+        if (file == null) {
+            throw new IllegalArgumentException("RC file name not specified");
+        }
+
+        if (!file.canRead()) {
+            throw new IOException("Please set up authentication file '" + file
+                                  + "'");
+        }
+
+        // System.err.println("Using RC file '" + file + "'");
+        StringTokenizer tokenizer = null;
+        boolean         thisone   = false;
+        String          s;
+        String          keyword, value;
+        int             linenum = 0;
+        BufferedReader  br      = new BufferedReader(new FileReader(file));
+
+        try {
+        while ((s = br.readLine()) != null) {
+            ++linenum;
+
+            s = s.trim();
+
+            if (s.length() == 0) {
+                continue;
+            }
+
+            if (s.charAt(0) == '#') {
+                continue;
+            }
+
+            tokenizer = new StringTokenizer(s);
+
+            if (tokenizer.countTokens() == 1) {
+                keyword = tokenizer.nextToken();
+                value   = "";
+            } else if (tokenizer.countTokens() > 1) {
+                keyword = tokenizer.nextToken();
+                value   = tokenizer.nextToken("").trim();
+            } else {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    // Can only report on so many errors at one time
+                }
+
+                throw new Exception("Corrupt line " + linenum + " in '" + file
+                                    + "':  " + s);
+            }
+
+            if (dbKey == null) {
+                if (keyword.equals("urlid")) {
+                    System.out.println(value);
+                }
+
+                continue;
+            }
+
+            if (keyword.equals("urlid")) {
+                if (value.equals(dbKey)) {
+                    if (id == null) {
+                        id      = dbKey;
+                        thisone = true;
+                    } else {
+                        try {
+                            br.close();
+                        } catch (IOException e) {
+                            // Can only report on so many errors at one time
+                        }
+
+                        throw new Exception("Key '" + dbKey + " redefined at"
+                                            + " line " + linenum + " in '"
+                                            + file);
+                    }
+                } else {
+                    thisone = false;
+                }
+
+                continue;
+            }
+
+            if (thisone) {
+                if (keyword.equals("url")) {
+                    url = value;
+                } else if (keyword.equals("username")) {
+                    username = value;
+                } else if (keyword.equals("driver")) {
+                    driver = value;
+                } else if (keyword.equals("charset")) {
+                    charset = value;
+                } else if (keyword.equals("truststore")) {
+                    truststore = value;
+                } else if (keyword.equals("password")) {
+                    password = value;
+                } else if (keyword.equals("transiso")) {
+                    ti = value;
+                } else if (keyword.equals("libpath")) {
+                    libpath = value;
+                } else {
+                    try {
+                        br.close();
+                    } catch (IOException e) {
+                        // Can only report on so many errors at one time
+                    }
+
+                    throw new Exception("Bad line " + linenum + " in '" + file
+                                        + "':  " + s);
+                }
+            }
+        }
+        } finally {
+            try  {
+                br.close();
+            } catch (IOException ioe) {
+                // Can only report on so many errors at one time
+            }
+            br = null;  // Encourage GC
+        }
+
+
+        if (dbKey == null) {
+            return;
+        }
+
+        if (url == null) {
+            throw new Exception("url not set " + "for '" + dbKey
+                                + "' in file '" + file + "'");
+        }
+
+        if (libpath != null) {
+            throw new IllegalArgumentException(
+                "Sorry, 'libpath' not supported yet");
+        }
+    }
+
+    /**
+     * Convenience constructor for backward compatibility.
+     *
+     * @see #RCData(String,String,String,String,String,String,String,String)
+     */
+    public RCData(String id, String url, String username, String password,
+                  String driver, String charset,
+                  String truststore) throws Exception {
+        this(id, url, username, password, driver, charset, truststore, null);
+    }
+
+    /**
+     * Wrapper for unset Transaction Isolation.
+     */
+    public RCData(String id, String url, String username, String password,
+                  String driver, String charset, String truststore,
+                  String libpath) throws Exception {
+        this(id, url, username, password, driver, charset, truststore,
+                libpath, null);
+    }
+
+    /**
+     * Creates a new <code>RCData</code> object.
+     *
+     * <P>
+     * The parameters driver, charset, truststore, and libpath are optional.
+     * Setting these parameters to <code>NULL</code> will set them to their
+     * default values.
+     * <P/>
+     *
+     * @param id The identifier for these connection settings
+     * @param url The URL of the database to connect to
+     * @param username The username to log in as
+     * @param password The password of the username
+     * @param driver The JDBC driver to use
+     * @param charset The character set to use
+     * @param truststore The trust store to use
+     * @param libpath The JDBC library to add to CLASSPATH
+     * @throws Exception if the a non-optional parameter is set to <code>NULL</code>
+     */
+    public RCData(String id, String url, String username, String password,
+                  String driver, String charset, String truststore,
+                  String libpath, String ti) throws Exception {
+
+        this.id         = id;
+        this.url        = url;
+        this.username   = username;
+        this.password   = password;
+        this.ti         = ti;
+        this.driver     = driver;
+        this.charset    = charset;
+        this.truststore = truststore;
+        this.libpath    = libpath;
+
+        if (libpath != null) {
+            throw new IllegalArgumentException(
+                "Sorry, 'libpath' not supported yet");
+        }
+
+        if (id == null || url == null) {
+            throw new Exception("id or url was not set");
+        }
+    }
+
+    /* Purposefully not using JavaBean paradigm so that these fields can
+     * be used as a traditional, public DO */
+    public String id;
+    public String url;
+    public String username;
+    public String password;
+    public String ti;
+    public String driver;
+    public String charset;
+    public String truststore;
+    public String libpath;
+
+    /**
+     * Gets a JDBC Connection using the data of this RCData object.
+     *
+     * @return New JDBC Connection
+     */
+    public Connection getConnection()
+    throws ClassNotFoundException, SQLException, MalformedURLException {
+        return getConnection(null, null);
+    }
+
+    /**
+     * Gets a JDBC Connection using the data of this RCData object with
+     * specified override elements
+     *
+     * @return New JDBC Connection
+     */
+    public Connection getConnection(String curDriverIn, String curTrustStoreIn)
+                                    throws ClassNotFoundException,
+                                           MalformedURLException,
+                                           SQLException {
+
+        // Local vars to satisfy compiler warnings
+        String curDriver = curDriverIn;
+        String curTrustStore = curTrustStoreIn;
+
+        Properties sysProps = System.getProperties();
+
+        if (curDriver == null) {
+
+            // If explicit driver not specified
+            curDriver = ((driver == null) ? DEFAULT_JDBC_DRIVER
+                                          : driver);
+        }
+
+        if (curTrustStore == null && truststore != null) {
+            curTrustStore = truststore;
+        }
+
+        if (curTrustStore == null) {
+            sysProps.remove("javax.net.ssl.trustStore");
+        } else {
+            sysProps.put("javax.net.ssl.trustStore", curTrustStore);
+        }
+
+        String urlString = null;
+
+        try {
+            urlString = expandSysPropVars(url);
+        } catch (IllegalArgumentException iae) {
+            throw new MalformedURLException(iae.getMessage() + " for URL '"
+                                            + url + "'");
+        }
+
+        String userString = null;
+
+        if (username != null) try {
+            userString = expandSysPropVars(username);
+        } catch (IllegalArgumentException iae) {
+            throw new MalformedURLException(iae.getMessage()
+                                            + " for user name '" + username
+                                            + "'");
+        }
+
+        String passwordString = null;
+
+        if (password != null) try {
+            passwordString = expandSysPropVars(password);
+        } catch (IllegalArgumentException iae) {
+            throw new MalformedURLException(iae.getMessage()
+                                            + " for password");
+        }
+
+        Class.forName(curDriver);
+        // This is not necessary for jdbc:odbc or if class loaded by a
+        // service resource file.  Consider checking for that.
+
+        Connection c = (userString == null)
+                     ? DriverManager.getConnection(urlString)
+                     : DriverManager.getConnection(urlString, userString,
+                                                   passwordString);
+        if (ti != null) RCData.setTI(c, ti);
+        // Would like to verify the setting made by checking
+        // c.getTransactionIsolation().  Unfortunately, the spec allows for
+        // databases to substitute levels according to some rules, and it's
+        // impossible to know what to expect since custom levels are permitted.
+        // Debug:
+        // System.err.println("TI set to " + ti + "\nPOST: "
+        // + SqlTool.tiToString(c.getTransactionIsolation()));
+        
+        return c;
+    }
+
+    /**
+     * Returns a copy of the given String with System property names in the
+     * format <code>${system.property}</code> replaced by the corresponding Java
+     * System Properties.
+     */
+    public static String expandSysPropVars(String inString) {
+
+        String outString = new String(inString);
+        int    varOffset, varEnd;
+        String varVal, varName;
+
+        while (true) {
+
+            // Recursive substitution for ${x} variables.
+            varOffset = outString.indexOf("${");
+
+            if (varOffset < 0) {
+                break;
+            }
+
+            varEnd = outString.indexOf('}', varOffset + 2);
+
+            if (varEnd < 0) {
+                break;
+            }
+
+            varName = outString.substring(varOffset + 2, varEnd);
+
+            if (varName.length() < 1) {
+                throw new IllegalArgumentException("Bad variable setting");
+            }
+
+            varVal = System.getProperty(varName);
+
+            if (varVal == null) {
+                throw new IllegalArgumentException(
+                    "No Java system property with name '" + varName + "'");
+            }
+
+            outString = outString.substring(0, varOffset) + varVal
+                        + outString.substring(varEnd + 1);
+        }
+
+        return outString;
+    }
+
+    /**
+     * Set Transaction Isolation level on the specified JDBC Connection
+     */
+    public static void setTI(Connection c, String tiString)
+            throws SQLException {
+        int i = -1;
+        if (tiString.equals("TRANSACTION_READ_UNCOMMITTED"))
+            i = Connection.TRANSACTION_READ_UNCOMMITTED;
+        if (tiString.equals("TRANSACTION_READ_COMMITTED"))
+            i = Connection.TRANSACTION_READ_COMMITTED;
+        if (tiString.equals("TRANSACTION_REPEATABLE_READ"))
+            i = Connection.TRANSACTION_REPEATABLE_READ;
+        if (tiString.equals("TRANSACTION_SERIALIZABLE"))
+            i = Connection.TRANSACTION_SERIALIZABLE;
+        if (tiString.equals("TRANSACTION_NONE"))
+            i = Connection.TRANSACTION_NONE;
+        if (i < 0) {
+            throw new SQLException(
+                    "Trans. isol. value not supported by "
+                    + RCData.class.getName() + ": " + tiString);
+        }
+        c.setTransactionIsolation(i);
+    }
+
+    /**
+     * Return a String representation for the given numerical
+     * java.sql.Connection Transaction level.
+     * <P>
+     * Database implementations are free to provide their own transaction
+     * isolation levels, so you can't depend upon this method to much.
+     * </P>
+     * Returns null, since DB implementations are free to provide
+     */
+    public static String tiToString(int ti) {
+        switch (ti) {
+            case Connection.TRANSACTION_READ_UNCOMMITTED:
+                return "TRANSACTION_READ_UNCOMMITTED";
+            case Connection.TRANSACTION_READ_COMMITTED:
+                return "TRANSACTION_READ_COMMITTED";
+            case Connection.TRANSACTION_REPEATABLE_READ:
+                return "TRANSACTION_REPEATABLE_READ";
+            case Connection.TRANSACTION_SERIALIZABLE:
+                return "TRANSACTION_SERIALIZABLE";
+            case Connection.TRANSACTION_NONE:
+                return "TRANSACTION_NONE";
+        }
+        return "Custom Transaction Isolation numerical value: " + ti;
+    }
+}
diff --git a/src/org/hsqldb/lib/ReaderInputStream.java b/src/org/hsqldb/lib/ReaderInputStream.java
new file mode 100644
index 0000000..8fc824a
--- /dev/null
+++ b/src/org/hsqldb/lib/ReaderInputStream.java
@@ -0,0 +1,76 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * This class is an part implementation of DataInput. It wraps a Reader object.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ReaderInputStream extends InputStream {
+
+    protected Reader reader;
+    protected long    pos;
+    int              lastChar = -1;
+
+    public ReaderInputStream(Reader reader) {
+        this.reader = reader;
+        this.pos    = 0;
+    }
+
+    public int read() throws IOException {
+
+        if (lastChar >= 0) {
+            int val = lastChar & 0xff;
+
+            lastChar = -1;
+
+            pos++;
+            return val;
+        }
+
+        lastChar = reader.read();
+
+        if (lastChar < 0) {
+            return lastChar;
+        }
+
+        pos++;
+        return lastChar >> 8;
+    }
+}
diff --git a/src/org/hsqldb/lib/RefCapablePropertyResourceBundle.java b/src/org/hsqldb/lib/RefCapablePropertyResourceBundle.java
new file mode 100644
index 0000000..98888aa
--- /dev/null
+++ b/src/org/hsqldb/lib/RefCapablePropertyResourceBundle.java
@@ -0,0 +1,464 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.PropertyResourceBundle;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.MissingResourceException;
+import java.util.Enumeration;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+
+/* $Id: RefCapablePropertyResourceBundle.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/**
+ * Just like PropertyResourceBundle, except keys mapped to nothing in the
+ * properties file will load the final String value from a text file.
+ *
+ * The use case is where one wants to use a ResourceBundle for Strings,
+ * but some of the Strings are long-- too long to maintain in a Java
+ * .properties file.
+ * By using this class, you can put each such long String in its own
+ * separate file, yet all keys mapped to (non-empty) values in the
+ * .properties file will behave just like regular PropertyResourceBundle
+ * properties.
+ * In this documentation, I call these values read in atomically from
+ * other files <i>referenced</i> values, because the values are not directly
+ * in the .properties file, but are "referenced" in the .properties file
+ * by virtue of the empty value for the key.
+ *
+ * You use this class in the same way as you would traditionally use
+ * ResourceBundle:
+ * <PRE>
+ *  import org.hsqldb.util..RefCapablePropertyResourceBundle;
+ *  ...
+ *      RefCapablePropertyResourceBundle bundle =
+ *              RefCapablePropertyResourceBundle.getBundle("subdir.xyz");
+ *      System.out.println("Value for '1' = (" + bundle.getString("1") + ')');
+ * </PRE>
+ *
+ * Just like PropertyResourceBundle, the .properties file and the
+ * <i>referenced</i> files are read in from the classpath by a class loader,
+ * according to the normal ResourceBundle rules.
+ * To eliminate the need to prohibit the use of any strings in the .properties
+ * values, and to enforce consistency, you <b>must</b> use the following rules
+ * to when putting your referenced files into place.
+ * <P/>
+ * REFERENCED FILE DIRECTORY is a directory named with the base name of the
+ * properties file, and in the same parent directory.  So, the referenced
+ * file directory <CODE>/a/b/c/greentea</CODE> is used to hold all reference
+ * files for properties files <CODE>/a/b/c/greentea_en_us.properties</CODE>,
+ * <CODE>/a/b/c/greentea_de.properties</CODE>,
+ * <CODE>/a/b/c/greentea.properties</CODE>, etc.
+ * (BTW, according to ResourceBundle rules, this resource should be looked
+ * up with name "a.b.c.greentea", not "/a/b/c..." or "a/b/c").
+ * REFERENCED FILES themselves all have the base name of the property key,
+ * with locale appendages exactly as the <i>referring</i> properties files
+ * has, plus the suffix <CODE>.text</CODE>.
+ * <P/>
+ * So, if we have the following line in
+ * <CODE>/a/b/c/greentea_de.properties</CODE>:
+ * <PRE>
+ *     1: eins
+ * </PRE>
+ * then you <b>must</b> have a reference text file
+ * <CODE>/a/b/c/greentea/1_de.properties</CODE>:
+ * <P/>
+ * In reference text files,
+ * sequences of "\r", "\n" and "\r\n" are all translated to the line
+ * delimiter for your platform (System property <CODE>line.separator</CODE>).
+ * If one of those sequences exists at the very end of the file, it will be
+ * eliminated (so, if you really want getString() to end with a line delimiter,
+ * end your file with two of them).
+ * (The file itself is never modified-- I'm talking about the value returned
+ * by <CODE>getString(String)</CODE>).
+ * <P/>
+ * To prevent throwing at runtime due to unset variables, use a wrapper class
+ * like SqltoolRB (use SqltoolRB.java as a template).
+ * To prevent throwing at runtime due to unset System Properties, or
+ * insufficient parameters passed to getString(String, String[]), set the
+ * behavior values appropriately.
+ * <P/>
+ * Just like all Properties files, referenced files must use ISO-8859-1
+ * encoding, with unicode escapes for characters outside of ISO-8859-1
+ * character set.  But, unlike Properties files, \ does not need to be
+ * escaped for normal usage.
+ * <P/>
+ * The getString() methods with more than one parameter substitute for
+ * "positional" parameters of the form "%{1}".
+ * The getExpandedString() methods substitute for System Property names
+ * of the form "${1}".
+ * In both cases, you can interpose :+ and a string between the variable
+ * name and the closing }.  This works just like the Bourne shell
+ * ${x:+y} feature.  If "x" is set, then "y" is returned, and "y" may
+ * contain references to the original variable without the curly braces.
+ * In this file, I refer to the y text as the "conditional string".
+ * One example of each type:
+ * <PRE>
+ *     Out val = (${condlSysProp:+Prop condlSysProp is set to $condlSysProp.})
+ *     Out val = (%{2:+Pos Var #2 is set to %2.})
+ * OUTPUT if neither are set:
+ *     Out val = ()
+ *     Out val = ()
+ * OUTPUT if condlSysProp=alpha and condlPLvar=beta:
+ *     Out val = (Prop condlSysProp is set to alpha.)
+ *     Out val = (Pos Var #2 is set to beta.)
+ * </PRE>
+ * This feature has the following limitations.
+ * <UL>
+ *   <LI>The conditional string may only contain the primary variable.
+ *   <LI>Inner instances of the primary variable may not use curly braces,
+ *       and therefore the variable name must end at a word boundary.
+ * </UL>
+ * The conditional string may span newlines, and it is often very useful
+ * to do so.
+ *
+ * @see java.util.PropertyResourceBundle
+ * @see java.util.ResourceBundle
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class RefCapablePropertyResourceBundle {
+    private PropertyResourceBundle wrappedBundle;
+    private String baseName;
+    private String language, country, variant;
+    static private Map<ResourceBundle, RefCapablePropertyResourceBundle>
+            allBundles =
+            new HashMap<ResourceBundle, RefCapablePropertyResourceBundle>();
+    public static String LS = System.getProperty("line.separator");
+    private Pattern sysPropVarPattern = Pattern.compile(
+            "(?s)\\Q${\\E([^}]+?)(?:\\Q:+\\E([^}]+))?\\Q}");
+    private Pattern posPattern = Pattern.compile(
+            "(?s)\\Q%{\\E(\\d)(?:\\Q:+\\E([^}]+))?\\Q}");
+    private ClassLoader loader;  // Needed to load referenced files
+
+    public static final int THROW_BEHAVIOR = 0;
+    public static final int EMPTYSTRING_BEHAVIOR = 1;
+    public static final int NOOP_BEHAVIOR = 2;
+
+    public Enumeration<String> getKeys() {
+        return wrappedBundle.getKeys();
+    }
+
+    private RefCapablePropertyResourceBundle(String baseName,
+            PropertyResourceBundle wrappedBundle, ClassLoader loader) {
+        this.baseName = baseName;
+        this.wrappedBundle = wrappedBundle;
+        Locale locale = wrappedBundle.getLocale();
+        this.loader = loader;
+        language = locale.getLanguage();
+        country = locale.getCountry();
+        variant = locale.getVariant();
+        if (language.length() < 1) language = null;
+        if (country.length() < 1) country = null;
+        if (variant.length() < 1) variant = null;
+    }
+
+    /**
+     * Same as getString(), but expands System Variables specified in
+     * property values like ${sysvarname}.
+     */
+    public String getExpandedString(String key, int behavior) {
+        String s = getString(key);
+        Matcher matcher = sysPropVarPattern.matcher(s);
+        int previousEnd = 0;
+        StringBuffer sb = new StringBuffer();
+        String varName, varValue;
+        String condlVal;  // Conditional : value
+        while (matcher.find()) {
+            varName = matcher.group(1);
+            condlVal = ((matcher.groupCount() > 1) ? matcher.group(2) : null);
+            varValue = System.getProperty(varName);
+            if (condlVal != null) {
+                // Replace varValue (the value to be substituted), with
+                // the post-:+ portion of the expression.
+                varValue = ((varValue == null)
+                        ? ""
+                        : condlVal.replaceAll("\\Q$" + varName + "\\E\\b",
+                                Matcher.quoteReplacement(varValue)));
+            }
+            if (varValue == null) switch (behavior) {
+                case THROW_BEHAVIOR:
+                    throw new RuntimeException(
+                            "No Sys Property set for variable '"
+                            + varName + "' in property value ("
+                            + s + ").");
+                case EMPTYSTRING_BEHAVIOR:
+                    varValue = "";
+                    break;
+                case NOOP_BEHAVIOR:
+                    break;
+                default:
+                    throw new RuntimeException(
+                            "Undefined value for behavior: " + behavior);
+            }
+            sb.append(s.substring(previousEnd, matcher.start())
+                        + ((varValue == null) ? matcher.group() : varValue));
+            previousEnd = matcher.end();
+        }
+        return (previousEnd < 1) ? s
+                                 : (sb.toString() + s.substring(previousEnd));
+    }
+
+    /**
+     * Replaces positional substitution patterns of the form %{\d} with
+     * corresponding element of the given subs array.
+     * Note that %{\d} numbers are 1-based, so we lok for subs[x-1].
+     */
+    public String posSubst(String s, String[] subs, int behavior) {
+        Matcher matcher = posPattern.matcher(s);
+        int previousEnd = 0;
+        StringBuffer sb = new StringBuffer();
+        String varValue;
+        int varIndex;
+        String condlVal;  // Conditional : value
+        while (matcher.find()) {
+            varIndex = Integer.parseInt(matcher.group(1)) - 1;
+            condlVal = ((matcher.groupCount() > 1) ? matcher.group(2) : null);
+            varValue = ((varIndex < subs.length) ? subs[varIndex] : null);
+            if (condlVal != null) {
+                // Replace varValue (the value to be substituted), with
+                // the post-:+ portion of the expression.
+                varValue = ((varValue == null)
+                        ? ""
+                        : condlVal.replaceAll("\\Q%" + (varIndex+1) + "\\E\\b",
+                                Matcher.quoteReplacement(varValue)));
+            }
+            // System.err.println("Behavior: " + behavior);
+            if (varValue == null) switch (behavior) {
+                case THROW_BEHAVIOR:
+                    throw new RuntimeException(
+                            Integer.toString(subs.length)
+                            + " positional values given, but property string "
+                            + "contains (" + matcher.group() + ").");
+                case EMPTYSTRING_BEHAVIOR:
+                    varValue = "";
+                    break;
+                case NOOP_BEHAVIOR:
+                    break;
+                default:
+                    throw new RuntimeException(
+                            "Undefined value for behavior: " + behavior);
+            }
+            sb.append(s.substring(previousEnd, matcher.start())
+                        + ((varValue == null) ? matcher.group() : varValue));
+            previousEnd = matcher.end();
+        }
+        return (previousEnd < 1) ? s
+                                 : (sb.toString() + s.substring(previousEnd));
+    }
+
+    public String getExpandedString(String key, String[] subs,
+            int missingPropertyBehavior, int missingPosValueBehavior) {
+        return posSubst(getExpandedString(key, missingPropertyBehavior), subs,
+                missingPosValueBehavior);
+    }
+    public String getString(String key, String[] subs, int behavior) {
+        return posSubst(getString(key), subs, behavior);
+    }
+
+    /**
+     * Just identifies this RefCapablePropertyResourceBundle instance.
+     */
+    public String toString() {
+        return baseName + " for " + language + " / " + country + " / "
+            + variant;
+    }
+
+    /**
+     * Returns value defined in this RefCapablePropertyResourceBundle's
+     * .properties file, unless that value is empty.
+     * If the value in the .properties file is empty, then this returns
+     * the entire contents of the referenced text file.
+     *
+     * @see ResourceBundle#getString(String)
+     */
+    public String getString(String key) {
+        String value = wrappedBundle.getString(key);
+        if (value.length() < 1) {
+            value = getStringFromFile(key);
+            // For conciseness and sanity, get rid of all \r's so that \n
+            // will definitively be our line breaks.
+            if (value.indexOf('\r') > -1)
+                value = value.replaceAll("\\Q\r\n", "\n")
+                        .replaceAll("\\Q\r", "\n");
+            if (value.length() > 0 && value.charAt(value.length() - 1) == '\n')
+                value = value.substring(0, value.length() - 1);
+        }
+        return RefCapablePropertyResourceBundle.toNativeLs(value);
+    }
+
+    /**
+     * @param inString  Input string with \n definitively indicating desired
+     *                  position for line separators.
+     * @return  If platform's line-separator is \n, then just returns inString.
+     *           Otherwise returns a copy of inString, with all \n's
+     *           transformed to the platform's line separators.
+     */
+    static public String toNativeLs(String inString) {
+        return LS.equals("\n") ? inString : inString.replaceAll("\\Q\n", LS);
+    }
+
+    /**
+     * Use like java.util.ResourceBundle.getBundle(String).
+     *
+     * ClassLoader is required for our getBundles()s, since it is impossible
+     * to get the "caller's" ClassLoader without using JNI (i.e., with pure
+     * Java).
+     *
+     * @see ResourceBundle#getBundle(String)
+     */
+    public static RefCapablePropertyResourceBundle getBundle(String baseName,
+            ClassLoader loader) {
+        return getRef(baseName, ResourceBundle.getBundle(baseName,
+                Locale.getDefault(), loader), loader);
+    }
+    /**
+     * Use exactly like java.util.ResourceBundle.get(String, Locale, ClassLoader).
+     *
+     * @see ResourceBundle#getBundle(String, Locale, ClassLoader)
+     */
+    public static RefCapablePropertyResourceBundle
+            getBundle(String baseName, Locale locale, ClassLoader loader) {
+        return getRef(baseName,
+                ResourceBundle.getBundle(baseName, locale, loader), loader);
+    }
+
+    /**
+     * Return a ref to a new or existing RefCapablePropertyResourceBundle,
+     * or throw a MissingResourceException.
+     */
+    static private RefCapablePropertyResourceBundle getRef(String baseName,
+            ResourceBundle rb, ClassLoader loader) {
+        if (!(rb instanceof PropertyResourceBundle))
+            throw new MissingResourceException(
+                    "Found a Resource Bundle, but it is a "
+                            + rb.getClass().getName(),
+                    PropertyResourceBundle.class.getName(), null);
+        if (allBundles.containsKey(rb)) return allBundles.get(rb);
+        RefCapablePropertyResourceBundle newPRAFP =
+                new RefCapablePropertyResourceBundle(baseName,
+                        (PropertyResourceBundle) rb, loader);
+        allBundles.put(rb, newPRAFP);
+        return newPRAFP;
+    }
+
+    /**
+     * Recursive
+     */
+    private InputStream getMostSpecificStream(
+            String key, String l, String c, String v) {
+        String filePath = baseName.replace('.', '/') + '/' + key
+                + ((l == null) ? "" : ("_" + l))
+                + ((c == null) ? "" : ("_" + c))
+                + ((v == null) ? "" : ("_" + v))
+                + ".text";
+        // System.err.println("Seeking " + filePath);
+        InputStream is = loader.getResourceAsStream(filePath);
+        // N.b.  If were using Class.getRes... instead of ClassLoader.getRes...
+        // we would need to prefix the path with "/".
+        return (is == null && l != null)
+            ? getMostSpecificStream(key, ((c == null) ? null : l),
+                    ((v == null) ? null : c), null)
+            : is;
+    }
+
+    private String getStringFromFile(String key) {
+        byte[] ba = null;
+        int bytesread = 0;
+        int retval;
+        InputStream  inputStream =
+                getMostSpecificStream(key, language, country, variant);
+        if (inputStream == null)
+            throw new MissingResourceException(
+                    "Key '" + key
+                    + "' is present in .properties file with no value, yet "
+                    + "text file resource is missing",
+                    RefCapablePropertyResourceBundle.class.getName(), key);
+        try {
+            try {
+                ba = new byte[inputStream.available()];
+            } catch (RuntimeException re) {
+                throw new MissingResourceException(
+                    "Resource is too big to read in '" + key + "' value in one "
+                    + "gulp.\nPlease run the program with more RAM "
+                    + "(try Java -Xm* switches).: " + re,
+                    RefCapablePropertyResourceBundle.class.getName(), key);
+            } catch (IOException ioe) {
+                throw new MissingResourceException(
+                    "Failed to read in value for key '" + key + "': " + ioe,
+                    RefCapablePropertyResourceBundle.class.getName(), key);
+            }
+            try {
+                while (bytesread < ba.length &&
+                        (retval = inputStream.read(
+                                ba, bytesread, ba.length - bytesread)) > 0) {
+                    bytesread += retval;
+                }
+            } catch (IOException ioe) {
+                throw new MissingResourceException(
+                    "Failed to read in value for '" + key + "': " + ioe,
+                    RefCapablePropertyResourceBundle.class.getName(), key);
+            }
+        } finally {
+            try {
+                inputStream.close();
+            } catch (IOException ioe) {
+                System.err.println("Failed to close input stream: " + ioe);
+            }
+        }
+        if (bytesread != ba.length) {
+            throw new MissingResourceException(
+                    "Didn't read all bytes.  Read in "
+                      + bytesread + " bytes out of " + ba.length
+                      + " bytes for key '" + key + "'",
+                    RefCapablePropertyResourceBundle.class.getName(), key);
+        }
+        try {
+            return new String(ba, "ISO-8859-1");
+        } catch (UnsupportedEncodingException uee) {
+            throw new RuntimeException(uee);
+        } catch (RuntimeException re) {
+            throw new MissingResourceException(
+                "Value for key '" + key + "' too big to convert to String.  "
+                + "Please run the program with more RAM "
+                + "(try Java -Xm* switches).: " + re,
+                RefCapablePropertyResourceBundle.class.getName(), key);
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/RefCapableRBInterface.java b/src/org/hsqldb/lib/RefCapableRBInterface.java
new file mode 100644
index 0000000..3a062b8
--- /dev/null
+++ b/src/org/hsqldb/lib/RefCapableRBInterface.java
@@ -0,0 +1,50 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+public interface RefCapableRBInterface {
+    public String getString();
+    public String getString(String... strings);
+    public String getExpandedString();
+    public String getExpandedString(String... strings);
+    public String getString(int i1);
+    public String getString(int i1, int i2);
+    public String getString(int i1, int i2, int i3);
+    public String getString(int i1, String s2);
+    public String getString(String s1, int i2);
+    public String getString(int i1, int i2, String s3);
+    public String getString(int i1, String s2, int i3);
+    public String getString(String s1, int i2, int i3);
+    public String getString(int i1, String s2, String s3);
+    public String getString(String s1, String s2, int i3);
+    public String getString(String s1, int i2, String s3);
+}
diff --git a/src/org/hsqldb/lib/Set.java b/src/org/hsqldb/lib/Set.java
new file mode 100644
index 0000000..78ba03d
--- /dev/null
+++ b/src/org/hsqldb/lib/Set.java
@@ -0,0 +1,75 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public interface Set extends Collection {
+
+    int size();
+
+    boolean isEmpty();
+
+    boolean contains(Object o);
+
+    Iterator iterator();
+
+/*
+    Object[] toArray();
+    Object[] toArray(Object a[]);
+*/
+    boolean add(Object o);
+
+    /**
+     * This method returns the Object that is already in the set and is
+     * equal to the argument o.
+     */
+    Object get(Object o);
+
+    boolean remove(Object o);
+
+/*
+    boolean containsAll(Collection c);
+    boolean addAll(Collection c);
+    boolean retainAll(Collection c);
+    boolean removeAll(Collection c);
+*/
+    void clear();
+
+    boolean equals(Object o);
+
+    int hashCode();
+}
diff --git a/src/org/hsqldb/lib/SimpleLog.java b/src/org/hsqldb/lib/SimpleLog.java
new file mode 100644
index 0000000..e8c1994
--- /dev/null
+++ b/src/org/hsqldb/lib/SimpleLog.java
@@ -0,0 +1,196 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+
+import org.hsqldb.HsqlDateTime;
+
+/**
+ * Simple log for recording abnormal events in persistence<p>
+ * Log levels, LOG_NONE, LOG_ERROR, and LOG_NORMAL are currently supported.<p>
+ * LOG_ERROR corresponds to property value 1 and logs main database events plus
+ * any major errors encountered in operation.
+ * LOG_NORMAL corresponds to property value 2 and logs additional normal events
+ * and minor errors.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+public class SimpleLog {
+
+    public static final int LOG_NONE   = 0;
+    public static final int LOG_ERROR  = 1;
+    public static final int LOG_NORMAL = 2;
+    private PrintWriter     writer;
+    private int             level;
+    private boolean         isSystem;
+    private String          filePath;
+
+    public SimpleLog(String path, int level) {
+
+        this.isSystem = path == null;
+        this.filePath = path;
+
+        setLevel(level);
+    }
+
+    private void setupWriter() {
+
+        if (level == LOG_NONE) {
+            close();
+
+            return;
+        }
+
+        if (writer == null) {
+            if (isSystem) {
+                writer = new PrintWriter(System.out);
+            } else {
+                File file = new File(filePath);
+
+                setupLog(file);
+            }
+        }
+    }
+
+    private void setupLog(File file) {
+
+        try {
+            FileUtil.getFileUtil().makeParentDirectories(file);
+
+            writer = new PrintWriter(new FileWriter(file.getPath(), true),
+                                     true);
+        } catch (Exception e) {
+            isSystem = true;
+            writer   = new PrintWriter(System.out);
+        }
+    }
+
+    public int getLevel() {
+        return level;
+    }
+
+    public void setLevel(int level) {
+
+        this.level = level;
+
+        setupWriter();
+    }
+
+    public PrintWriter getPrintWriter() {
+        return writer;
+    }
+
+    public synchronized void sendLine(int atLevel, String message) {
+
+        if (level >= atLevel) {
+            writer.println(HsqlDateTime.getSytemTimeString() + " " + message);
+        }
+    }
+
+    public synchronized void logContext(int atLevel, String message) {
+
+        if (level < atLevel) {
+            return;
+        }
+
+        String info = HsqlDateTime.getSytemTimeString();
+
+//#ifdef JAVA4
+        Throwable           temp     = new Throwable();
+        StackTraceElement[] elements = temp.getStackTrace();
+
+        if (elements.length > 1) {
+            info += " " + elements[1].getClassName() + "."
+                    + elements[1].getMethodName();
+        }
+
+//#endif JAVA4
+        writer.println(info + " " + message);
+    }
+
+    public synchronized void logContext(Throwable t, String inMessage) {
+
+        String message = inMessage;    // We may change this
+
+        if (level == LOG_NONE) {
+            return;
+        }
+
+        String info = HsqlDateTime.getSytemTimeString();
+
+//#ifdef JAVA4
+        Throwable           temp     = new Throwable();
+        StackTraceElement[] elements = temp.getStackTrace();
+
+        if (elements.length > 1) {
+            info += " " + elements[1].getClassName() + "."
+                    + elements[1].getMethodName();
+        }
+
+        elements = t.getStackTrace();
+
+        if (elements.length > 0) {
+            info += " " + elements[0].getClassName() + "."
+                    + elements[0].getMethodName();
+        }
+
+//#endif JAVA4
+        if (message == null) {
+            message = "";
+        }
+
+        if (writer != null) {
+            writer.println(info + " " + t.toString() + " " + message);
+        }
+    }
+
+    public void flush() {
+
+        if (writer != null) {
+            writer.flush();
+        }
+    }
+
+    public void close() {
+
+        if (writer != null && !isSystem) {
+            writer.close();
+        }
+
+        writer = null;
+    }
+}
diff --git a/src/org/hsqldb/lib/StopWatch.java b/src/org/hsqldb/lib/StopWatch.java
new file mode 100644
index 0000000..47ec8e5
--- /dev/null
+++ b/src/org/hsqldb/lib/StopWatch.java
@@ -0,0 +1,187 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ * Provides the programatic analog of a physical stop watch. <p>
+ *
+ * The watch can be started, stopped and zeroed and can be queried for
+ * elapsed running time.  The watch accumulates elapsed time over starts
+ * and stops such that only the time actually spent running is recorded.
+ * If the watch is zeroed, then the accumulated time is discarded and
+ * the watch starts again with zero acumulated time. <p>
+ *
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class StopWatch {
+
+    /**
+     * The last time this object made the transition
+     * from stopped to running state, as reported
+     * by System.currentTimeMillis().
+     */
+    private long startTime;
+    private long lastStart;
+
+    /**
+     * The accumulated running time of this object since
+     * it was last zeroed.
+     */
+    private long total;
+
+    /** Flags if this object is started or stopped. */
+    boolean running = false;
+
+    /** Creates, zeros, and starts a new StopWatch */
+    public StopWatch() {
+        this(true);
+    }
+
+    /** Creates, zeros, and starts a new StopWatch */
+    public StopWatch(boolean start) {
+
+        if (start) {
+            start();
+        }
+    }
+
+    /**
+     * Retrieves the accumulated time this object has spent running since
+     * it was last zeroed.
+     * @return the accumulated time this object has spent running since
+     * it was last zeroed.
+     */
+    public long elapsedTime() {
+
+        if (running) {
+            return total + System.currentTimeMillis() - startTime;
+        } else {
+            return total;
+        }
+    }
+
+    /**
+     * Retrieves the accumulated time this object has spent running since
+     * it was last started.
+     * @return the accumulated time this object has spent running since
+     * it was last started.
+     */
+    public long currentElapsedTime() {
+
+        if (running) {
+            return System.currentTimeMillis() - startTime;
+        } else {
+            return 0;
+        }
+    }
+
+    /** Zeros accumulated running time and restarts this object. */
+    public void zero() {
+
+        total = 0;
+
+        start();
+    }
+
+    /**
+     * Ensures that this object is in the running state.  If this object is not
+     * running, then the call has the effect of setting the <code>startTime</code>
+     * attribute to the current value of System.currentTimeMillis() and setting
+     * the <code>running</code> attribute to <code>true</code>.
+     */
+    public void start() {
+        startTime = System.currentTimeMillis();
+        running   = true;
+    }
+
+    /**
+     * Ensures that this object is in the stopped state.  If this object is
+     * in the running state, then this has the effect of adding to the
+     * <code>total</code> attribute the elapsed time since the last transition
+     * from stopped to running state and sets the <code>running</code> attribute
+     * to false. If this object is not in the running state, this call has no
+     * effect.
+     */
+    public void stop() {
+
+        if (running) {
+            total   += System.currentTimeMillis() - startTime;
+            running = false;
+        }
+    }
+
+    public void mark() {
+        stop();
+        start();
+    }
+
+    /**
+     * Retrieves prefix + " in " + elapsedTime() + " ms."
+     * @param prefix The string to use as a prefix
+     * @return prefix + " in " + elapsedTime() + " ms."
+     */
+    public String elapsedTimeToMessage(String prefix) {
+        return prefix + " in " + elapsedTime() + " ms.";
+    }
+
+    /**
+     * Retrieves prefix + " in " + elapsedTime() + " ms."
+     * @param prefix The string to use as a prefix
+     * @return prefix + " in " + elapsedTime() + " ms."
+     */
+    public String currentElapsedTimeToMessage(String prefix) {
+        return prefix + " in " + currentElapsedTime() + " ms.";
+    }
+
+    /**
+     * Retrieves the internal state of this object, as a String.
+     *
+     * The retreived value is:
+     *
+     * <pre>
+     *    super.toString() +
+     *    "[running=" +
+     *    running +
+     *    ", startTime=" +
+     *    startTime +
+     *    ", total=" +
+     *    total + "]";
+     * </pre>
+     * @return the state of this object, as a String
+     */
+    public String toString() {
+        return super.toString() + "[running=" + running + ", startTime="
+               + startTime + ", total=" + total + "]";
+    }
+}
diff --git a/src/org/hsqldb/lib/Storage.java b/src/org/hsqldb/lib/Storage.java
new file mode 100644
index 0000000..655eed5
--- /dev/null
+++ b/src/org/hsqldb/lib/Storage.java
@@ -0,0 +1,72 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.IOException;
+
+/**
+ * An interface that supports the commonly used methods of java.io.RandomAccessFile.
+ *
+ * @author Ocke Janssen oj@openoffice.org
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+public interface Storage {
+
+    long length() throws IOException;
+
+    void seek(long position) throws IOException;
+
+    long getFilePointer() throws IOException;
+
+    int read() throws IOException;
+
+    void read(byte[] b, int offset, int length) throws IOException;
+
+    void write(byte[] b, int offset, int length) throws IOException;
+
+    int readInt() throws IOException;
+
+    void writeInt(int i) throws IOException;
+
+    long readLong() throws IOException;
+
+    void writeLong(long i) throws IOException;
+
+    void close() throws IOException;
+
+    boolean isReadOnly();
+
+    boolean wasNio();
+
+    void synch();
+}
diff --git a/src/org/hsqldb/lib/StringComparator.java b/src/org/hsqldb/lib/StringComparator.java
new file mode 100644
index 0000000..3e90822
--- /dev/null
+++ b/src/org/hsqldb/lib/StringComparator.java
@@ -0,0 +1,60 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.Comparator;
+
+public class StringComparator implements Comparator {
+
+    /*
+     * @author Fred Toussi (fredt@users dot sourceforge.net)
+     * @version 1.9.0
+     * @since 1.9.0
+     */
+    public int compare(Object a, Object b) {
+
+        // handle nulls
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        return ((String) a).compareTo((String) b);
+    }
+}
diff --git a/src/org/hsqldb/lib/StringConverter.java b/src/org/hsqldb/lib/StringConverter.java
new file mode 100644
index 0000000..8812f72
--- /dev/null
+++ b/src/org/hsqldb/lib/StringConverter.java
@@ -0,0 +1,734 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.io.UTFDataFormatException;
+
+import org.hsqldb.store.BitMap;
+
+/**
+ * Collection of static methods for converting strings between different
+ * formats and to and from byte arrays.<p>
+ *
+ * Includes some methods based on Hypersonic code as indicated.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class StringConverter {
+
+    private static final byte[] HEXBYTES = {
+        (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
+        (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
+        (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
+    };
+
+    private static int getNibble(int value) {
+
+        if (value >= '0' && value <= '9') {
+            return value - '0';
+        }
+
+        if (value >= 'a' && value <= 'f') {
+            return 10 + value - 'a';
+        }
+
+        if (value >= 'A' && value <= 'F') {
+            return 10 + value - 'A';
+        }
+
+        return -1;
+    }
+
+    /**
+     * Converts a hexadecimal string into a byte array
+     *
+     *
+     * @param s hexadecimal string
+     *
+     * @return byte array for the hex string
+     * @throws IOException
+     */
+    public static byte[] hexStringToByteArray(String s) throws IOException {
+
+        int     l    = s.length();
+        byte[]  data = new byte[l / 2 + (l % 2)];
+        int     n,
+                b    = 0;
+        boolean high = true;
+        int     i    = 0;
+
+        for (int j = 0; j < l; j++) {
+            char c = s.charAt(j);
+
+            if (c == ' ') {
+                continue;
+            }
+
+            n = getNibble(c);
+
+            if (n == -1) {
+                throw new IOException(
+                    "hexadecimal string contains non hex character");    //NOI18N
+            }
+
+            if (high) {
+                b    = (n & 0xf) << 4;
+                high = false;
+            } else {
+                b         += (n & 0xf);
+                high      = true;
+                data[i++] = (byte) b;
+            }
+        }
+
+        if (!high) {
+            throw new IOException(
+                "hexadecimal string with odd number of characters");    //NOI18N
+        }
+
+        if (i < data.length) {
+            data = (byte[]) ArrayUtil.resizeArray(data, i);
+        }
+
+        return data;
+    }
+
+    /**
+     * Compacts a bit string into a BitMap
+     *
+     *
+     * @param s bit string
+     *
+     * @return byte array for the hex string
+     * @throws IOException
+     */
+    public static BitMap sqlBitStringToBitMap(String s) throws IOException {
+
+        int    l = s.length();
+        int    n;
+        int    bitIndex = 0;
+        BitMap map      = new BitMap(l);
+
+        for (int j = 0; j < l; j++) {
+            char c = s.charAt(j);
+
+            if (c == ' ') {
+                continue;
+            }
+
+            n = getNibble(c);
+
+            if (n != 0 && n != 1) {
+                throw new IOException(
+                    "hexadecimal string contains non hex character");    //NOI18N
+            }
+
+            if (n == 1) {
+                map.set(bitIndex);
+            }
+
+            bitIndex++;
+        }
+
+        map.setSize(bitIndex);
+
+        return map;
+    }
+
+    /**
+     * Converts a byte array into a hexadecimal string
+     *
+     *
+     * @param b byte array
+     *
+     * @return hex string
+     */
+    public static String byteArrayToHexString(byte[] b) {
+
+        int    len = b.length;
+        char[] s   = new char[len * 2];
+
+        for (int i = 0, j = 0; i < len; i++) {
+            int c = ((int) b[i]) & 0xff;
+
+            s[j++] = (char) HEXBYTES[c >> 4 & 0xf];
+            s[j++] = (char) HEXBYTES[c & 0xf];
+        }
+
+        return new String(s);
+    }
+
+    /**
+     * Converts a byte array into an SQL hexadecimal string
+     *
+     *
+     * @param b byte array
+     *
+     * @return hex string
+     */
+    public static String byteArrayToSQLHexString(byte[] b) {
+
+        int    len = b.length;
+        char[] s   = new char[len * 2 + 3];
+
+        s[0] = 'X';
+        s[1] = '\'';
+
+        int j = 2;
+
+        for (int i = 0; i < len; i++) {
+            int c = ((int) b[i]) & 0xff;
+
+            s[j++] = (char) HEXBYTES[c >> 4 & 0xf];
+            s[j++] = (char) HEXBYTES[c & 0xf];
+        }
+
+        s[j] = '\'';
+
+        return new String(s);
+    }
+
+    /**
+     * Converts a byte array into a bit string
+     *
+     *
+     * @param bytes byte array
+     * @param bitCount number of bits
+     * @return hex string
+     */
+    public static String byteArrayToBitString(byte[] bytes, int bitCount) {
+
+        char[] s = new char[bitCount];
+
+        for (int j = 0; j < bitCount; j++) {
+            byte b = bytes[j / 8];
+
+            s[j] = BitMap.isSet(b, j % 8) ? '1'
+                                          : '0';
+        }
+
+        return new String(s);
+    }
+
+    /**
+     * Converts a byte array into an SQL binary string
+     *
+     *
+     * @param bytes byte array
+     * @param bitCount number of bits
+     * @return hex string
+     */
+    public static String byteArrayToSQLBitString(byte[] bytes, int bitCount) {
+
+        char[] s = new char[bitCount + 3];
+
+        s[0] = 'B';
+        s[1] = '\'';
+
+        int pos = 2;
+
+        for (int j = 0; j < bitCount; j++) {
+            byte b = bytes[j / 8];
+
+            s[pos++] = BitMap.isSet(b, j % 8) ? '1'
+                                              : '0';
+        }
+
+        s[pos] = '\'';
+
+        return new String(s);
+    }
+
+    /**
+     * Converts a byte array into hexadecimal characters which are written as
+     * ASCII to the given output stream.
+     *
+     * @param o output array
+     * @param from offset into output array
+     * @param b input array
+     */
+    public static void writeHexBytes(byte[] o, int from, byte[] b) {
+
+        int len = b.length;
+
+        for (int i = 0; i < len; i++) {
+            int c = ((int) b[i]) & 0xff;
+
+            o[from++] = HEXBYTES[c >> 4 & 0xf];
+            o[from++] = HEXBYTES[c & 0xf];
+        }
+    }
+
+    public static String byteArrayToString(byte[] b, String charset) {
+
+        try {
+            return (charset == null) ? new String(b)
+                                     : new String(b, charset);
+        } catch (Exception e) {}
+
+        return null;
+    }
+
+    /**
+     * Hsqldb specific encoding used only for log files. The SQL statements that
+     * need to be written to the log file (input) are Java Unicode strings.
+     * input is converted into a 7bit escaped ASCII string (output)with the
+     * following transformations. All characters outside the 0x20-7f range are
+     * converted to a escape sequence and added to output. If a backslash
+     * character is immdediately followed by 'u', the backslash character is
+     * converted to escape sequence and added to output. All the remaining
+     * characters in input are added to output without conversion. The escape
+     * sequence is backslash, letter u, xxxx, where xxxx is the hex
+     * representation of the character code. (fredt@users)<p>
+     *
+     * Method based on Hypersonic Code
+     *
+     * @param b output stream to wite to
+     * @param s Java string
+     * @param doubleSingleQuotes boolean
+     */
+    public static void stringToUnicodeBytes(HsqlByteArrayOutputStream b,
+            String s, boolean doubleSingleQuotes) {
+
+        if (s == null) {
+            return;
+        }
+
+        final int len = s.length();
+        char[]    chars;
+        int       extras = 0;
+
+        if (len == 0) {
+            return;
+        }
+
+        chars = s.toCharArray();
+
+        b.ensureRoom(len * 2 + 5);
+
+        for (int i = 0; i < len; i++) {
+            char c = chars[i];
+
+            if (c == '\\') {
+                if ((i < len - 1) && (chars[i + 1] == 'u')) {
+                    b.writeNoCheck(c);    // encode the \ as unicode, so 'u' is ignored
+                    b.writeNoCheck('u');
+                    b.writeNoCheck('0');
+                    b.writeNoCheck('0');
+                    b.writeNoCheck('5');
+                    b.writeNoCheck('c');
+
+                    extras += 5;
+                } else {
+                    b.write(c);
+                }
+            } else if ((c >= 0x0020) && (c <= 0x007f)) {
+                b.writeNoCheck(c);        // this is 99%
+
+                if (c == '\'' && doubleSingleQuotes) {
+                    b.writeNoCheck(c);
+
+                    extras++;
+                }
+            } else {
+                b.writeNoCheck('\\');
+                b.writeNoCheck('u');
+                b.writeNoCheck(HEXBYTES[(c >> 12) & 0xf]);
+                b.writeNoCheck(HEXBYTES[(c >> 8) & 0xf]);
+                b.writeNoCheck(HEXBYTES[(c >> 4) & 0xf]);
+                b.writeNoCheck(HEXBYTES[c & 0xf]);
+
+                extras += 5;
+            }
+
+            if (extras > len) {
+                b.ensureRoom(len + extras + 5);
+
+                extras = 0;
+            }
+        }
+    }
+
+// fredt@users 20020522 - fix for 557510 - backslash bug
+// this legacy bug resulted from forward reading the input when a backslash
+// was present and manifested itself when a backslash was followed
+// immdediately by a character outside the 0x20-7f range in a database field.
+
+    /**
+     * Hsqldb specific decoding used only for log files. This method converts
+     * the 7 bit escaped ASCII strings in a log file back into Java Unicode
+     * strings. See stringToUnicodeBytes() above. <p>
+     *
+     * Method based on Hypersonic Code
+     *
+     * @param s encoded ASCII string in byte array
+     * @return Java string
+     */
+    public static String unicodeStringToString(String s) {
+
+        if ((s == null) || (s.indexOf("\\u") == -1)) {
+            return s;
+        }
+
+        int    len = s.length();
+        char[] b   = new char[len];
+        int    j   = 0;
+
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt(i);
+
+            if (c == '\\' && i < len - 5) {
+                char c1 = s.charAt(i + 1);
+
+                if (c1 == 'u') {
+                    i++;
+
+                    // 4 characters read should always return 0-15
+                    int k = getNibble(s.charAt(++i)) << 12;
+
+                    k      += getNibble(s.charAt(++i)) << 8;
+                    k      += getNibble(s.charAt(++i)) << 4;
+                    k      += getNibble(s.charAt(++i));
+                    b[j++] = (char) k;
+                } else {
+                    b[j++] = c;
+                }
+            } else {
+                b[j++] = c;
+            }
+        }
+
+        return new String(b, 0, j);
+    }
+
+    public static String readUTF(byte[] bytearr, int offset,
+                                 int length) throws IOException {
+
+        char[] buf = new char[length];
+
+        return readUTF(bytearr, offset, length, buf);
+    }
+
+    public static String readUTF(byte[] bytearr, int offset, int length,
+                                 char[] buf) throws IOException {
+
+        int bcount = 0;
+        int c, char2, char3;
+        int count = 0;
+
+        while (count < length) {
+            c = (int) bytearr[offset + count];
+
+            if (bcount == buf.length) {
+                buf = (char[]) ArrayUtil.resizeArray(buf, length);
+            }
+
+            if (c > 0) {
+
+                /* 0xxxxxxx*/
+                count++;
+
+                buf[bcount++] = (char) c;
+
+                continue;
+            }
+
+            c &= 0xff;
+
+            switch (c >> 4) {
+
+                case 12 :
+                case 13 :
+
+                    /* 110x xxxx   10xx xxxx*/
+                    count += 2;
+
+                    if (count > length) {
+                        throw new UTFDataFormatException();
+                    }
+
+                    char2 = (int) bytearr[offset + count - 1];
+
+                    if ((char2 & 0xC0) != 0x80) {
+                        throw new UTFDataFormatException();
+                    }
+
+                    buf[bcount++] = (char) (((c & 0x1F) << 6)
+                                            | (char2 & 0x3F));
+                    break;
+
+                case 14 :
+
+                    /* 1110 xxxx  10xx xxxx  10xx xxxx */
+                    count += 3;
+
+                    if (count > length) {
+                        throw new UTFDataFormatException();
+                    }
+
+                    char2 = (int) bytearr[offset + count - 2];
+                    char3 = (int) bytearr[offset + count - 1];
+
+                    if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) {
+                        throw new UTFDataFormatException();
+                    }
+
+                    buf[bcount++] = (char) (((c & 0x0F) << 12)
+                                            | ((char2 & 0x3F) << 6)
+                                            | ((char3 & 0x3F) << 0));
+                    break;
+
+                default :
+
+                    /* 10xx xxxx,  1111 xxxx */
+                    throw new UTFDataFormatException();
+            }
+        }
+
+        // The number of chars produced may be less than length
+        return new String(buf, 0, bcount);
+    }
+
+    /**
+     * Writes a string to the specified DataOutput using UTF-8 encoding in a
+     * machine-independent manner.
+     * <p>
+     * @param      str   a string to be written.
+     * @param      out   destination to write to
+     * @return     The number of bytes written out.
+     */
+    public static int stringToUTFBytes(String str,
+                                       HsqlByteArrayOutputStream out) {
+
+        int strlen = str.length();
+        int c,
+            count  = 0;
+
+        if (out.count + strlen + 8 > out.buffer.length) {
+            out.ensureRoom(strlen + 8);
+        }
+
+        char[] arr = str.toCharArray();
+
+        for (int i = 0; i < strlen; i++) {
+            c = arr[i];
+
+            if (c >= 0x0001 && c <= 0x007F) {
+                out.buffer[out.count++] = (byte) c;
+
+                count++;
+            } else if (c > 0x07FF) {
+                out.buffer[out.count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
+                out.buffer[out.count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
+                out.buffer[out.count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
+                count                   += 3;
+            } else {
+                out.buffer[out.count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
+                out.buffer[out.count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
+                count                   += 2;
+            }
+
+            if (out.count + 8 > out.buffer.length) {
+                out.ensureRoom(strlen - i + 8);
+            }
+        }
+
+        return count;
+    }
+
+    public static int getUTFSize(String s) {
+
+        int len = (s == null) ? 0
+                              : s.length();
+        int l   = 0;
+
+        for (int i = 0; i < len; i++) {
+            int c = s.charAt(i);
+
+            if ((c >= 0x0001) && (c <= 0x007F)) {
+                l++;
+            } else if (c > 0x07FF) {
+                l += 3;
+            } else {
+                l += 2;
+            }
+        }
+
+        return l;
+    }
+
+    /**
+     * Using a Reader and a Writer, returns a String from an InputStream.
+     *
+     * Method based on Hypersonic Code
+     *
+     * @param x InputStream to read from
+     * @throws IOException
+     * @return a Java string
+     */
+    public static String inputStreamToString(InputStream x,
+            String encoding) throws IOException {
+
+        InputStreamReader in        = new InputStreamReader(x, encoding);
+        StringWriter      writer    = new StringWriter();
+        int               blocksize = 8 * 1024;
+        char[]            buffer    = new char[blocksize];
+
+        for (;;) {
+            int read = in.read(buffer);
+
+            if (read == -1) {
+                break;
+            }
+
+            writer.write(buffer, 0, read);
+        }
+
+        writer.close();
+
+        return writer.toString();
+    }
+
+// fredt@users 20020130 - patch 497872 by Nitin Chauhan - use byte[] of exact size
+
+    /**
+     * Returns the quoted version of the string using the quotechar argument.
+     * doublequote argument indicates whether each instance of quotechar inside
+     * the string is doubled.<p>
+     *
+     * null string argument returns null. If the caller needs the literal
+     * "NULL" it should created it itself<p>
+     *
+     * @param s Java string
+     * @param quoteChar character used for quoting
+     * @param extraQuote true if quoteChar itself should be repeated
+     * @return String
+     */
+    public static String toQuotedString(String s, char quoteChar,
+                                        boolean extraQuote) {
+
+        if (s == null) {
+            return null;
+        }
+
+        int    count = extraQuote ? count(s, quoteChar)
+                                  : 0;
+        int    len   = s.length();
+        char[] b     = new char[2 + count + len];
+        int    i     = 0;
+        int    j     = 0;
+
+        b[j++] = quoteChar;
+
+        for (; i < len; i++) {
+            char c = s.charAt(i);
+
+            b[j++] = c;
+
+            if (extraQuote && c == quoteChar) {
+                b[j++] = c;
+            }
+        }
+
+        b[j] = quoteChar;
+
+        return new String(b);
+    }
+
+    /**
+     * Counts Character c in String s
+     *
+     * @param s Java string
+     * @param c character to count
+     * @return int count
+     */
+    static int count(final String s, final char c) {
+
+        int pos   = 0;
+        int count = 0;
+
+        if (s != null) {
+            while ((pos = s.indexOf(c, pos)) > -1) {
+                count++;
+                pos++;
+            }
+        }
+
+        return count;
+    }
+}
diff --git a/src/org/hsqldb/lib/StringInputStream.java b/src/org/hsqldb/lib/StringInputStream.java
new file mode 100644
index 0000000..c5d85c8
--- /dev/null
+++ b/src/org/hsqldb/lib/StringInputStream.java
@@ -0,0 +1,81 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * minimal InputStream subclass to fetch bytes form a String
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.0
+ */
+public class StringInputStream extends InputStream {
+
+    protected int    strOffset  = 0;
+    protected int    charOffset = 0;
+    protected int    available;
+    protected String str;
+
+    public StringInputStream(String s) {
+        str       = s;
+        available = s.length() * 2;
+    }
+
+    public int read() throws java.io.IOException {
+
+        if (available == 0) {
+            return -1;
+        }
+
+        available--;
+
+        char c = str.charAt(strOffset);
+
+        if (charOffset == 0) {
+            charOffset = 1;
+
+            return (c & 0x0000ff00) >> 8;
+        } else {
+            charOffset = 0;
+
+            strOffset++;
+
+            return c & 0x000000ff;
+        }
+    }
+
+    public int available() throws IOException {
+        return available;
+    }
+}
diff --git a/src/org/hsqldb/lib/StringUtil.java b/src/org/hsqldb/lib/StringUtil.java
new file mode 100644
index 0000000..20f22e9
--- /dev/null
+++ b/src/org/hsqldb/lib/StringUtil.java
@@ -0,0 +1,376 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.lang.reflect.Array;
+
+/** Provides a collection of convenience methods for processing and
+ * creating objects with <code>String</code> value components.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @author Nitin Chauhan
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class StringUtil {
+
+    /**
+     * If necessary, adds zeros to the beginning of a value so that the total
+     * length matches the given precision, otherwise trims the right digits.
+     * Then if maxSize is smaller than precision, trims the right digits to
+     * maxSize. Negative values are treated as positive
+     */
+    public static String toZeroPaddedString(long value, int precision,
+            int maxSize) {
+
+        StringBuffer sb = new StringBuffer();
+
+        if (value < 0) {
+            value = -value;
+        }
+
+        String s = Long.toString(value);
+
+        if (s.length() > precision) {
+            s = s.substring(precision);
+        }
+
+        for (int i = s.length(); i < precision; i++) {
+            sb.append('0');
+        }
+
+        sb.append(s);
+
+        if (maxSize < precision) {
+            sb.setLength(maxSize);
+        }
+
+        return sb.toString();
+    }
+
+    public static String toPaddedString(String source, int length, char pad,
+                                        boolean trailing) {
+
+        int len = source.length();
+
+        if (len >= length) {
+            return source;
+        }
+
+        StringBuffer sb = new StringBuffer(length);
+
+        if (trailing) {
+            sb.append(source);
+        }
+
+        for (int i = len; i < length; i++) {
+            sb.append(pad);
+        }
+
+        if (!trailing) {
+            sb.append(source);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Returns a string with non alphanumeric chars converted to the
+     * substitute character. A digit first character is also converted.
+     * By sqlbob@users
+     * @param source string to convert
+     * @param substitute character to use
+     * @return converted string
+     */
+    public static String toLowerSubset(String source, char substitute) {
+
+        int          len = source.length();
+        StringBuffer sb  = new StringBuffer(len);
+        char         ch;
+
+        for (int i = 0; i < len; i++) {
+            ch = source.charAt(i);
+
+            if (!Character.isLetterOrDigit(ch)) {
+                sb.append(substitute);
+            } else if ((i == 0) && Character.isDigit(ch)) {
+                sb.append(substitute);
+            } else {
+                sb.append(Character.toLowerCase(ch));
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Builds a bracketed CSV list from the array
+     * @param array an array of Objects
+     * @return string
+     */
+    public static String arrayToString(Object array) {
+
+        int          len  = Array.getLength(array);
+        int          last = len - 1;
+        StringBuffer sb   = new StringBuffer(2 * (len + 1));
+
+        sb.append('{');
+
+        for (int i = 0; i < len; i++) {
+            sb.append(Array.get(array, i));
+
+            if (i != last) {
+                sb.append(',');
+            }
+        }
+
+        sb.append('}');
+
+        return sb.toString();
+    }
+
+    /**
+     * Builds a CSV list from the specified String[], separator string and
+     * quote string. <p>
+     *
+     * <ul>
+     * <li>All arguments are assumed to be non-null.
+     * <li>Separates each list element with the value of the
+     * <code>separator</code> argument.
+     * <li>Prepends and appends each element with the value of the
+     *     <code>quote</code> argument.
+     * <li> No attempt is made to escape the quote character sequence if it is
+     *      found internal to a list element.
+     * <ul>
+     * @return a CSV list
+     * @param separator the <code>String</code> to use as the list element separator
+     * @param quote the <code>String</code> with which to quote the list elements
+     * @param s array of <code>String</code> objects
+     */
+    public static String getList(String[] s, String separator, String quote) {
+
+        int          len = s.length;
+        StringBuffer sb  = new StringBuffer(len * 16);
+
+        for (int i = 0; i < len; i++) {
+            sb.append(quote);
+            sb.append(s[i]);
+            sb.append(quote);
+
+            if (i + 1 < len) {
+                sb.append(separator);
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Builds a CSV list from the specified int[], <code>separator</code>
+     * <code>String</code> and <code>quote</code> <code>String</code>. <p>
+     *
+     * <ul>
+     * <li>All arguments are assumed to be non-null.
+     * <li>Separates each list element with the value of the
+     * <code>separator</code> argument.
+     * <li>Prepends and appends each element with the value of the
+     *     <code>quote</code> argument.
+     * <ul>
+     * @return a CSV list
+     * @param s the array of int values
+     * @param separator the <code>String</code> to use as the separator
+     * @param quote the <code>String</code> with which to quote the list elements
+     */
+    public static String getList(int[] s, String separator, String quote) {
+
+        int          len = s.length;
+        StringBuffer sb  = new StringBuffer(len * 8);
+
+        for (int i = 0; i < len; i++) {
+            sb.append(quote);
+            sb.append(s[i]);
+            sb.append(quote);
+
+            if (i + 1 < len) {
+                sb.append(separator);
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Builds a CSV list from the specified String[][], separator string and
+     * quote string. <p>
+     *
+     * <ul>
+     * <li>All arguments are assumed to be non-null.
+     * <li>Uses only the first element in each subarray.
+     * <li>Separates each list element with the value of the
+     * <code>separator</code> argument.
+     * <li>Prepends and appends each element with the value of the
+     *     <code>quote</code> argument.
+     * <li> No attempt is made to escape the quote character sequence if it is
+     *      found internal to a list element.
+     * <ul>
+     * @return a CSV list
+     * @param separator the <code>String</code> to use as the list element separator
+     * @param quote the <code>String</code> with which to quote the list elements
+     * @param s the array of <code>String</code> array objects
+     */
+    public static String getList(String[][] s, String separator,
+                                 String quote) {
+
+        int          len = s.length;
+        StringBuffer sb  = new StringBuffer(len * 16);
+
+        for (int i = 0; i < len; i++) {
+            sb.append(quote);
+            sb.append(s[i][0]);
+            sb.append(quote);
+
+            if (i + 1 < len) {
+                sb.append(separator);
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Appends a pair of string to the string buffer, using the separator between
+     * and terminator at the end
+     * @param b the buffer
+     * @param s1 first string
+     * @param s2 second string
+     * @param separator separator string
+     * @param terminator terminator string
+     */
+    public static void appendPair(StringBuffer b, String s1, String s2,
+                                  String separator, String terminator) {
+
+        b.append(s1);
+        b.append(separator);
+        b.append(s2);
+        b.append(terminator);
+    }
+
+    /**
+     * Checks if text is empty (characters <= space)
+     * @return boolean true if text is null or empty, false otherwise
+     * @param s java.lang.String
+     */
+    public static boolean isEmpty(String s) {
+
+        int i = s == null ? 0
+                          : s.length();
+
+        while (i > 0) {
+            if (s.charAt(--i) > ' ') {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the size of substring that does not contain any trailing spaces
+     * @param s the string
+     * @return trimmed size
+     */
+    public static int rightTrimSize(String s) {
+
+        int i = s.length();
+
+        while (i > 0) {
+            i--;
+
+            if (s.charAt(i) != ' ') {
+                return i + 1;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Skips any spaces at or after start and returns the index of first
+     * non-space character;
+     * @param s the string
+     * @param start index to start
+     * @return index of first non-space
+     */
+    public static int skipSpaces(String s, int start) {
+
+        int limit = s.length();
+        int i     = start;
+
+        for (; i < limit; i++) {
+            if (s.charAt(i) != ' ') {
+                break;
+            }
+        }
+
+        return i;
+    }
+
+    /**
+     * Splits the string into an array, using the separator. If separator is
+     * not found in the string, the whole string is returned in the array.
+     *
+     * @param s the string
+     * @param separator the separator
+     * @return array of strings
+     */
+    public static String[] split(String s, String separator) {
+
+        HsqlArrayList list      = new HsqlArrayList();
+        int           currindex = 0;
+
+        for (boolean more = true; more; ) {
+            int nextindex = s.indexOf(separator, currindex);
+
+            if (nextindex == -1) {
+                nextindex = s.length();
+                more      = false;
+            }
+
+            list.add(s.substring(currindex, nextindex));
+
+            currindex = nextindex + separator.length();
+        }
+
+        return (String[]) list.toArray(new String[list.size()]);
+    }
+}
diff --git a/src/org/hsqldb/lib/ThreadFactory.java b/src/org/hsqldb/lib/ThreadFactory.java
new file mode 100644
index 0000000..f47ae29
--- /dev/null
+++ b/src/org/hsqldb/lib/ThreadFactory.java
@@ -0,0 +1,42 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+/**
+ *
+ * @author  boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public interface ThreadFactory {
+    Thread newThread(Runnable r);
+}
diff --git a/src/org/hsqldb/lib/ValidatingResourceBundle.java b/src/org/hsqldb/lib/ValidatingResourceBundle.java
new file mode 100644
index 0000000..39146f8
--- /dev/null
+++ b/src/org/hsqldb/lib/ValidatingResourceBundle.java
@@ -0,0 +1,286 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Enumeration;
+
+/* $Id: ValidatingResourceBundle.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/**
+ * Purpose of this class is to wrap a RefCapablePropertyResourceBundle to
+ *  reliably detect any possible use of a missing property key as soon as
+ *  this class is clinitted.
+ * The reason for this is to allow us developers to detect all such errors
+ *  before end-users ever use this class.
+ *
+ * See SqltoolRB for an example implementation of this abstract class.
+ */
+public class ValidatingResourceBundle {
+    protected boolean validated = false;
+    protected Class<? extends Enum<?>> enumType;
+
+    public static final int THROW_BEHAVIOR =
+            RefCapablePropertyResourceBundle.THROW_BEHAVIOR;
+    public static final int EMPTYSTRING_BEHAVIOR =
+            RefCapablePropertyResourceBundle.EMPTYSTRING_BEHAVIOR;
+    public static final int NOOP_BEHAVIOR =
+            RefCapablePropertyResourceBundle.NOOP_BEHAVIOR;
+    /* Three constants above are only so caller doesn't need to know
+     * details of RefCapablePropertyResourceBundle (and they won't need
+     * to code that God-awfully-long class name). */
+
+    protected RefCapablePropertyResourceBundle wrappedRCPRB;
+
+    public static String resourceKeyFor(Enum<?> enumKey) {
+        return enumKey.name().replace('_', '.');
+    }
+
+    public ValidatingResourceBundle(
+            String baseName, Class<? extends Enum<?>> enumType) {
+        this.enumType = enumType;
+        try {
+            wrappedRCPRB = RefCapablePropertyResourceBundle.getBundle(baseName,
+                    enumType.getClassLoader());
+            validate();
+        } catch (RuntimeException re) {
+            System.err.println("Failed to initialize resource bundle: " + re);
+            // Make extra sure that the source of this fatal startup condition
+            // is not hidden.
+            throw re;
+        }
+    }
+
+    // The following methods are a passthru wrappers for the wrapped RCPRB.
+
+    /** @see RefCapablePropertyResourceBundle#getString(String) */
+    public String getString(Enum<?> key) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return wrappedRCPRB.getString(key.toString());
+    }
+
+    /** @see RefCapablePropertyResourceBundle#getString(String, String[], int) */
+    public String getString(Enum<?> key, String... strings) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return wrappedRCPRB.getString(
+                key.toString(), strings, missingPosValueBehavior);
+    }
+
+    /** @see RefCapablePropertyResourceBundle#getExpandedString(String, int) */
+    public String getExpandedString(Enum<?> key) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return wrappedRCPRB.getExpandedString(key.toString(), missingPropertyBehavior);
+    }
+
+    /** @see RefCapablePropertyResourceBundle#getExpandedString(String, String[], int, int) */
+    public String getExpandedString(Enum<?> key, String... strings) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return wrappedRCPRB.getExpandedString(key.toString(), strings,
+                missingPropertyBehavior, missingPosValueBehavior);
+    }
+
+    private int missingPropertyBehavior = THROW_BEHAVIOR;
+    private int missingPosValueBehavior = THROW_BEHAVIOR;
+
+    /**
+     * Set behavior for get*String*() method when a referred-to
+     * System Property is not set.  Set to one of
+     * <UL>
+     *  <LI>RefCapablePropertyResourceBundle.THROW_BEHAVIOR
+     *  <LI>RefCapablePropertyResourceBundle.EMPTYSTRING_BEHAVIOR
+     *  <LI>RefCapablePropertyResourceBundle.NOOP_BEHAVIOR
+     * </UL>
+     * The first value is the default.
+     */
+    public void setMissingPropertyBehavior(int missingPropertyBehavior) {
+        this.missingPropertyBehavior = missingPropertyBehavior;
+    }
+    /**
+     * Set behavior for get*String(String, String[]) method when a
+     * positional index (like %{4}) is used but no subs value was given for
+     * that index.  Set to one of
+     * <UL>
+     *  <LI>RefCapablePropertyResourceBundle.THROW_BEHAVIOR
+     *  <LI>RefCapablePropertyResourceBundle.EMPTYSTRING_BEHAVIOR
+     *  <LI>RefCapablePropertyResourceBundle.NOOP_BEHAVIOR
+     * </UL>
+     * The first value is the default.
+     */
+    public void setMissingPosValueBehavior(int missingPosValueBehavior) {
+        this.missingPosValueBehavior = missingPosValueBehavior;
+    }
+
+    public int getMissingPropertyBehavior() {
+        return missingPropertyBehavior;
+    }
+    public int getMissingPosValueBehavior() {
+        return missingPosValueBehavior;
+    }
+
+    public void validate() {
+        String val;
+        if (validated) return;
+        validated = true;
+        Set<String> resKeysFromEls = new HashSet<String>();
+        for (Enum<?> e : enumType.getEnumConstants())
+            resKeysFromEls.add(e.toString());
+        Enumeration<String> allKeys = wrappedRCPRB.getKeys();
+        while (allKeys.hasMoreElements()) {
+            // We can't test positional parameters, but we can verify that
+            // referenced files exist by reading the values.
+            // Pretty inefficient, but this can be optimized when I have time.
+            val = allKeys.nextElement();
+            wrappedRCPRB.getString(val);  // because it throws if missing?
+            // Keep no reference to the returned String
+            resKeysFromEls.remove(val);
+        }
+        if (resKeysFromEls.size() > 0)
+            throw new RuntimeException(
+                    "Resource Bundle pre-validation failed.  "
+                    + "Missing property with key:  " + resKeysFromEls);
+    }
+
+    /* Convenience wrappers follow for getString(int, String[]) for up to
+     * 3 int and/or String positionals or any number of just String positions
+     */
+    public String getString(Enum<?> key, int i1) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {Integer.toString(i1)});
+    }
+    public String getString(Enum<?> key, int i1, int i2) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            Integer.toString(i1), Integer.toString(i2)
+        });
+    }
+    public String getString(Enum<?> key, int i1, int i2, int i3) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            Integer.toString(i1), Integer.toString(i2), Integer.toString(i3)
+        });
+    }
+    public String getString(Enum<?> key, int i1, String s2) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            Integer.toString(i1), s2
+        });
+    }
+    public String getString(Enum<?> key, String s1, int i2) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            s1, Integer.toString(i2)
+        });
+    }
+
+    public String getString(Enum<?> key, int i1, int i2, String s3) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            Integer.toString(i1), Integer.toString(i2), s3
+        });
+    }
+    public String getString(Enum<?> key, int i1, String s2, int i3) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            Integer.toString(i1), s2, Integer.toString(i3)
+        });
+    }
+    public String getString(Enum<?> key, String s1, int i2, int i3) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            s1, Integer.toString(i2), Integer.toString(i3)
+        });
+    }
+    public String getString(Enum<?> key, int i1, String s2, String s3) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            Integer.toString(i1), s2, s3
+        });
+    }
+    public String getString(Enum<?> key, String s1, String s2, int i3) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            s1, s2, Integer.toString(i3)
+        });
+    }
+    public String getString(Enum<?> key, String s1, int i2, String s3) {
+        if (!enumType.isInstance(key))
+            throw new IllegalArgumentException(
+                    "Key is a " + key.getClass().getName() + ",not a "
+                    + enumType.getName() + ":  " + key);
+        return getString(key, new String[] {
+            s1, Integer.toString(i2), s3
+        });
+    }
+}
diff --git a/src/org/hsqldb/lib/WrapperIterator.java b/src/org/hsqldb/lib/WrapperIterator.java
new file mode 100644
index 0000000..8d2a7a2
--- /dev/null
+++ b/src/org/hsqldb/lib/WrapperIterator.java
@@ -0,0 +1,214 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib;
+
+import java.util.NoSuchElementException;
+
+/**
+ *  An Iterator that returns the elements of a specified array, or other
+ *  iterators etc. The collection of objects returned depends on the
+ *  constructor used.<p>
+ *
+ *  Based on similar Enumerator code by boucherb@users
+ *
+ * @author fred@users
+ * @version 1.9.0
+ * @since HSQLDB 1.7.2
+ */
+public class WrapperIterator implements Iterator {
+
+    private static final Object[] emptyelements = new Object[0];
+    private Object[]              elements;
+    private int                   i;
+
+    // chained iterators
+    private boolean  chained;
+    private Iterator it1;
+    private Iterator it2;
+
+    /** return only not null elements */
+    private boolean notNull;
+
+    /**
+     * Constructor for an empty iterator. <p>
+     */
+    public WrapperIterator() {
+        this.elements = emptyelements;
+    }
+
+    /**
+     * Constructor for all elements of the specified array. <p>
+     *
+     * @param elements the array of objects to enumerate
+     */
+    public WrapperIterator(Object[] elements) {
+        this.elements = elements;
+    }
+
+    /**
+     * Constructor for not-null elements of specified array. <p>
+     *
+     * @param elements the array of objects to iterate
+     */
+    public WrapperIterator(Object[] elements, boolean notNull) {
+        this.elements = elements;
+        this.notNull  = notNull;
+    }
+
+    /**
+     * Constructor for a singleton object iterator
+     *
+     * @param element the single object to iterate
+     */
+    public WrapperIterator(Object element) {
+        this.elements = new Object[]{ element };
+    }
+
+    /**
+     * Constructor for a chained iterator that returns the elements of the two
+     * specified iterators.
+     */
+    public WrapperIterator(Iterator it1, Iterator it2) {
+
+        this.it1 = it1;
+        this.it2 = it2;
+        chained  = true;
+    }
+
+    /**
+     * Tests if this iterator contains more elements. <p>
+     *
+     * @return  <code>true</code> if this iterator contains more elements;
+     *          <code>false</code> otherwise.
+     */
+    public boolean hasNext() {
+
+        // for chained iterators
+        if (chained) {
+            if (it1 == null) {
+                if (it2 == null) {
+                    return false;
+                }
+
+                if (it2.hasNext()) {
+                    return true;
+                }
+
+                it2 = null;
+
+                return false;
+            } else {
+                if (it1.hasNext()) {
+                    return true;
+                }
+
+                it1 = null;
+
+                return hasNext();
+            }
+        }
+
+        // for other interators
+        if (elements == null) {
+            return false;
+        }
+
+        for (; notNull && i < elements.length && elements[i] == null; i++) {}
+
+        if (i < elements.length) {
+            return true;
+        } else {
+
+            // release elements for garbage collection
+            elements = null;
+
+            return false;
+        }
+    }
+
+    /**
+     * Returns the next element.
+     *
+     * @return the next element
+     * @throws NoSuchElementException if there is no next element
+     */
+    public Object next() {
+
+        // for chained iterators
+        if (chained) {
+            if (it1 == null) {
+                if (it2 == null) {
+                    throw new NoSuchElementException();
+                }
+
+                if (it2.hasNext()) {
+                    return it2.next();
+                }
+
+                it2 = null;
+
+                next();
+            } else {
+                if (it1.hasNext()) {
+                    return it1.next();
+                }
+
+                it1 = null;
+
+                next();
+            }
+        }
+
+        // for other itertors
+        if (hasNext()) {
+            return elements[i++];
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public int nextInt() {
+        throw new NoSuchElementException();
+    }
+
+    public long nextLong() {
+        throw new NoSuchElementException();
+    }
+
+    public void remove() {
+        throw new NoSuchElementException();
+    }
+
+    public void setValue(Object value) {
+        throw new NoSuchElementException();
+    }
+}
diff --git a/src/org/hsqldb/lib/java/JavaSystem.java b/src/org/hsqldb/lib/java/JavaSystem.java
new file mode 100644
index 0000000..40b990d
--- /dev/null
+++ b/src/org/hsqldb/lib/java/JavaSystem.java
@@ -0,0 +1,257 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.java;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.DriverManager;
+import java.util.Properties;
+import java.text.Collator;
+import java.io.RandomAccessFile;
+
+/**
+ * Handles the differences between JDK 1.1.x and 1.2.x and above
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ */
+public class JavaSystem {
+
+    // variables to track rough count on object creation, to use in gc
+    public static int gcFrequency;
+    public static int memoryRecords;
+
+    // Garbage Collection
+    public static void gc() {
+
+        if ((gcFrequency > 0) && (memoryRecords > gcFrequency)) {
+            memoryRecords = 0;
+
+            System.gc();
+        }
+    }
+
+    public static IOException toIOException(Throwable t) {
+
+        if (t instanceof IOException) {
+            return (IOException) t;
+        }
+
+//#ifdef JAVA6
+        return new IOException(t);
+
+//#else
+/*
+        return new IOException(t.getMessage());
+*/
+
+//#endif JAVA6
+    }
+
+    final static BigDecimal BD_1  = BigDecimal.valueOf(1L);
+    final static BigDecimal MBD_1 = BigDecimal.valueOf(-1L);
+
+    public static int precision(BigDecimal o) {
+
+        if (o == null) {
+            return 0;
+        }
+
+//#ifdef JAVA6
+        int precision;
+
+        if (o.compareTo(BD_1) < 0 && o.compareTo(MBD_1) > 0) {
+            precision = o.scale();
+        } else {
+            precision = o.precision();
+        }
+
+        return precision;
+
+//#else
+/*
+        if (o.compareTo(BD_1) < 0 && o.compareTo(MBD_1) > 0) {
+            return o.scale();
+        }
+
+        BigInteger big  = o.unscaledValue();
+        int        sign = big.signum() == -1 ? 1
+                                             : 0;
+
+        return big.toString().length() - sign;
+*/
+
+//#endif JAVA6
+    }
+
+    public static String toString(BigDecimal o) {
+
+        if (o == null) {
+            return null;
+        }
+
+//#ifdef JAVA6
+        return o.toPlainString();
+
+//#else
+/*
+        return o.toString();
+*/
+
+//#endif JAVA6
+    }
+
+    public static int compareIngnoreCase(String a, String b) {
+
+//#ifdef JAVA2FULL
+        return a.compareToIgnoreCase(b);
+
+//#else
+/*
+        return a.toUpperCase().compareTo(b.toUpperCase());
+*/
+
+//#endif JAVA2
+    }
+
+    public static double parseDouble(String s) {
+
+//#ifdef JAVA2FULL
+        return Double.parseDouble(s);
+
+//#else
+/*
+        return new Double(s).doubleValue();
+*/
+
+//#endif JAVA2
+    }
+
+    public static BigInteger unscaledValue(BigDecimal o) {
+
+//#ifdef JAVA2FULL
+        return o.unscaledValue();
+
+//#else
+/*
+        int scale = o.scale();
+        return o.movePointRight(scale).toBigInteger();
+*/
+
+//#endif
+    }
+
+    public static void setLogToSystem(boolean value) {
+
+//#ifdef JAVA2FULL
+        try {
+            PrintWriter newPrintWriter = (value) ? new PrintWriter(System.out)
+                                                 : null;
+
+            DriverManager.setLogWriter(newPrintWriter);
+        } catch (Exception e) {}
+
+//#else
+/*
+        try {
+            PrintStream newOutStream = (value) ? System.out
+                                               : null;
+            DriverManager.setLogStream(newOutStream);
+        } catch (Exception e){}
+*/
+
+//#endif
+    }
+
+    public static void deleteOnExit(File f) {
+
+//#ifdef JAVA2FULL
+        f.deleteOnExit();
+
+//#endif
+    }
+
+    public static void saveProperties(Properties props, String name,
+                                      OutputStream os) throws IOException {
+
+//#ifdef JAVA2FULL
+        props.store(os, name);
+
+//#else
+/*
+        props.save(os, name);
+*/
+
+//#endif
+    }
+
+    public static void runFinalizers() {
+
+//#ifdef JAVA2FULL
+        System.runFinalizersOnExit(true);
+
+//#endif
+    }
+
+    public static boolean createNewFile(File file) {
+
+//#ifdef JAVA2FULL
+        try {
+            return file.createNewFile();
+        } catch (IOException e) {}
+
+        return false;
+
+//#else
+/*
+        return true;
+*/
+
+//#endif
+    }
+
+    public static void setRAFileLength(RandomAccessFile raFile,
+                                       long length) throws IOException {
+
+//#ifdef JAVA2FULL
+        raFile.setLength(length);
+
+//#endif
+    }
+}
diff --git a/src/org/hsqldb/lib/package.html b/src/org/hsqldb/lib/package.html
new file mode 100644
index 0000000..364934f
--- /dev/null
+++ b/src/org/hsqldb/lib/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+  Shared classes used by other HyperSQL classes.
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/lib/tar/DbBackup.java b/src/org/hsqldb/lib/tar/DbBackup.java
new file mode 100644
index 0000000..1d7b7a6
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/DbBackup.java
@@ -0,0 +1,413 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * Works with tar archives containing HSQLDB database instance backups.
+ * Viz, creating, examining, or extracting these archives.
+ * <P>
+ * This class provides OO Tar backup-creation control.
+ * The extraction and listing features are implemented only in static fashion
+ * in the Main method, which provides a consistent interface for all three
+ * features from the command-line.
+ * </P> <P>
+ * For tar creation, the default behavior is to fail if the target archive
+ * exists, and to abort if any database change is detected.
+ * Use the JavaBean setters to changes this behavior.
+ * See the main(String[]) method for details about command-line usage.
+ * </P>
+ *
+ * @see <a href="../../../../../guide/deployment-chapt.html#deployment_backup-sect"
+ *      target="guide">
+ *     The database backup section of the HyperSQL User Guide</a>
+ * @see #main(String[])
+ * @see #setOverWrite(boolean)
+ * @see #setAbortUponModify(boolean)
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class DbBackup {
+
+    /**
+     * Command line invocation to create, examine, or extract HSQLDB database
+     * backup tar archives.
+     * <P>
+     * This class stores tar entries as relative files without specifying
+     * parent directories, in what is commonly referred to as <I>tar bomb</I>
+     * format.
+     * The set of files is small, with known extensions, and the potential
+     * inconvenience of messing up the user's current directory is more than
+     * compensated by making it easier for the user to restore to a new
+     * database URL location at a peer level to the original.
+     * </P> <P>
+     * Automatically calculates buffer sizes based on the largest component
+     * file (for "save" mode) or tar file size (for other modes).
+     * </P> <P>
+     * Run<CODE><PRE>
+     *     java -cp path/to/hsqldb.jar org.hsqldb.lib.tar.DbBackup
+     * </PRE></CODE> for syntax help.
+     * </P>
+     */
+    static public void main(String[] sa)
+    throws IOException, TarMalformatException {
+
+        try {
+            if (sa.length < 1) {
+                System.out.println(
+                        RB.DbBackup_syntax.getString(DbBackup.class.getName()));
+                System.out.println();
+                System.out.println(RB.listing_format.getString());
+                System.exit(0);
+            }
+
+            if (sa[0].equals("--save")) {
+                boolean overWrite = sa.length > 1
+                                    && sa[1].equals("--overwrite");
+
+                if (sa.length != (overWrite ? 4
+                                            : 3)) {
+                    throw new IllegalArgumentException();
+                }
+
+                DbBackup backup = new DbBackup(new File(sa[sa.length - 2]),
+                                               sa[sa.length - 1]);
+
+                backup.setOverWrite(overWrite);
+                backup.write();
+            } else if (sa[0].equals("--list")) {
+                if (sa.length < 2) {
+                    throw new IllegalArgumentException();
+                }
+
+                String[] patternStrings = null;
+
+                if (sa.length > 2) {
+                    patternStrings = new String[sa.length - 2];
+
+                    for (int i = 2; i < sa.length; i++) {
+                        patternStrings[i - 2] = sa[i];
+                    }
+                }
+
+                new TarReader(new File(sa[1]), TarReader
+                    .LIST_MODE, patternStrings, new Integer(DbBackup
+                        .generateBufferBlockValue(new File(sa[1]))), null)
+                            .read();
+            } else if (sa[0].equals("--extract")) {
+                boolean overWrite = sa.length > 1
+                                    && sa[1].equals("--overwrite");
+                int firstPatInd = overWrite ? 4
+                                            : 3;
+
+                if (sa.length < firstPatInd) {
+                    throw new IllegalArgumentException();
+                }
+
+                String[] patternStrings = null;
+
+                if (sa.length > firstPatInd) {
+                    patternStrings = new String[sa.length - firstPatInd];
+
+                    for (int i = firstPatInd; i < sa.length; i++) {
+                        patternStrings[i - firstPatInd] = sa[i];
+                    }
+                }
+
+                File tarFile       = new File(sa[overWrite ? 2
+                                                           : 1]);
+                int  tarReaderMode = overWrite ? TarReader.OVERWRITE_MODE
+                                               : TarReader.EXTRACT_MODE;
+
+                new TarReader(
+                    tarFile, tarReaderMode, patternStrings,
+                    new Integer(DbBackup.generateBufferBlockValue(tarFile)),
+                    new File(sa[firstPatInd - 1])).read();
+            } else {
+                throw new IllegalArgumentException();
+            }
+        } catch (IllegalArgumentException iae) {
+            System.out.println(
+                    RB.DbBackup_syntaxerr.getString(DbBackup.class.getName()));
+            System.exit(2);
+        }
+    }
+
+    /**
+     * Instantiate a DbBackup instance for creating a Database Instance backup.
+     *
+     * Much validation is deferred until the write() method, to prevent
+     * problems with files changing between the constructor and the write call.
+     */
+    public DbBackup(File archiveFile, String dbPath) {
+
+        this.archiveFile = archiveFile;
+
+        File dbPathFile = new File(dbPath);
+
+        dbDir        = dbPathFile.getAbsoluteFile().getParentFile();
+        instanceName = dbPathFile.getName();
+    }
+
+    protected File    dbDir;
+    protected File    archiveFile;
+    protected String  instanceName;
+    protected boolean overWrite       = false;    // Defaults no NO OVERWRITE
+    protected boolean abortUponModify = true;     // Defaults to ABORT-UPON-MODIFY
+
+    /**
+     * Defaults to false.
+     *
+     * If false, then attempts to write a tar file that already exist will
+     * abort.
+     */
+    public void setOverWrite(boolean overWrite) {
+        this.overWrite = overWrite;
+    }
+
+    /**
+     * Defaults to true.
+     *
+     * If true, then the write() method will validate that the database is
+     * closed, and it will verify that no DB file changes between when we
+     * start writing the tar, and when we finish.
+     */
+    public void setAbortUponModify(boolean abortUponModify) {
+        this.abortUponModify = abortUponModify;
+    }
+
+    public boolean getOverWrite() {
+        return overWrite;
+    }
+
+    public boolean getAbortUponModify() {
+        return abortUponModify;
+    }
+
+    /**
+     * This method always backs up the .properties and .script files.
+     * It will back up all of .backup, .data, and .log which exist.
+     *
+     * If abortUponModify is set, no tar file will be created, and this
+     * method will throw.
+     *
+     * @throws IOException for any of many possible I/O problems
+     * @throws IllegalStateException only if abortUponModify is set, and
+     *                               database is open or is modified.
+     */
+    public void write() throws IOException, TarMalformatException {
+
+        File   propertiesFile = new File(dbDir, instanceName + ".properties");
+        File   scriptFile     = new File(dbDir, instanceName + ".script");
+        File[] componentFiles = new File[] {
+            propertiesFile, scriptFile,
+            new File(dbDir, instanceName + ".backup"),
+            new File(dbDir, instanceName + ".data"),
+            new File(dbDir, instanceName + ".log"),
+            new File(dbDir, instanceName + ".lobs")
+        };
+        boolean[] existList = new boolean[componentFiles.length];
+        long      startTime = new java.util.Date().getTime();
+
+        for (int i = 0; i < existList.length; i++) {
+            existList[i] = componentFiles[i].exists();
+
+            if (i < 2 && !existList[i]) {
+
+                // First 2 files are REQUIRED
+                throw new FileNotFoundException(
+                        RB.file_missing.getString(
+                        componentFiles[i].getAbsolutePath()));
+            }
+        }
+
+        if (abortUponModify) {
+            Properties      p   = new Properties();
+            FileInputStream fis = null;
+
+            try {
+                fis = new FileInputStream(propertiesFile);
+
+                p.load(fis);
+            } finally {
+                try {
+                    if (fis != null) {
+                        fis.close();
+                    }
+                } finally {
+                    fis = null; // Encourage buffer GC
+                }
+            }
+
+            String modifiedString = p.getProperty("modified");
+
+            if (modifiedString != null
+                    && (modifiedString.equalsIgnoreCase("yes")
+                        || modifiedString.equalsIgnoreCase("true"))) {
+                throw new IllegalStateException(
+                        RB.modified_property.getString(modifiedString));
+            }
+        }
+
+        TarGenerator generator = new TarGenerator(archiveFile, overWrite,
+            new Integer(DbBackup.generateBufferBlockValue(componentFiles)));
+
+        for (File componentFile : componentFiles) {
+            if (!componentFile.exists()) {
+                continue;
+
+                // We've already verified that required files exist, therefore
+                // there is no error condition here.
+            }
+
+            generator.queueEntry(componentFile.getName(), componentFile);
+        }
+
+        generator.write();
+
+        if (abortUponModify) {
+            try {
+                for (int i = 0; i < componentFiles.length; i++) {
+                    if (componentFiles[i].exists()) {
+                        if (!existList[i]) {
+                            throw new FileNotFoundException(
+                                    RB.file_disappeared.getString(
+                                    componentFiles[i].getAbsolutePath()));
+                        }
+
+                        if (componentFiles[i].lastModified() > startTime) {
+                            throw new FileNotFoundException(
+                                    RB.file_changed.getString(
+                                    componentFiles[i].getAbsolutePath()));
+                        }
+                    } else if (existList[i]) {
+                        throw new FileNotFoundException(
+                                RB.file_appeared.getString(
+                                componentFiles[i].getAbsolutePath()));
+                    }
+                }
+            } catch (IllegalStateException ise) {
+                if (!archiveFile.delete()) {
+                    System.out.println(
+                            RB.cleanup_rmfail.getString(
+                            archiveFile.getAbsolutePath()));
+
+                    // Be-it-known.  This method can write to stderr if
+                    // abortUponModify is true.
+                }
+
+                throw ise;
+            }
+        }
+    }
+
+    /**
+     * @todo - Supply a version of my MemTest program which people can run
+     * one time when the server can be starved of RAM, and save the available
+     * RAM quantity to a text file.  We can then really crank up the buffer
+     * size to make transfers really efficient.
+     */
+
+    /**
+     * Return a 512-block buffer size suggestion, based on the size of what
+     * needs to be read or written, and default and typical JVM constraints.
+     * <P>
+     * <B>Algorithm details:</B>
+     * </P> <P>
+     * Minimum system I want support is a J2SE system with 256M physical
+     * RAM.  This sytem can hold a 61 MB byte array (real 1024^2 M).
+     * (61MB with Java 1.6, 62MB with Java 1.4).
+     * This decreases to just 60 MB with (pre-production, non-optimized)
+     * HSQLDB v. 1.9 on Java 1.6.
+     * Allow the user 40 MB of for data (this only corresponds to a much
+     * smaller quantity of real data due to the huge overhead of Java and
+     * database structures).
+     * This allows 20 MB for us to use.  User can easily use more than this
+     * by raising JVM settings and/or getting more PRAM or VRAM.
+     * Therefore, ceiling = 20MB = 20 MB / .5 Kb = 40 k blocks
+     * </P> <P>
+     * We make the conservative simplification that each data file contains
+     * just one huge data entry component.  This is a good estimation, since in
+     * most cases, the contents of the single largest file will be many orders
+     * of magnitude larger than the other files and the single block entry
+     * headers.
+     * </P> <P>
+     * We aim for reading or writing these biggest file with 10 reads/writes.
+     * In the case of READING Gzip files, there will actually be many more
+     * reads than this, but that's the price you pay for smaller file size.
+     * </P>
+     *
+     * @param files  Null array elements are permitted.  They will just be
+     *               skipped by the algorithm.
+     */
+    static protected int generateBufferBlockValue(File[] files) {
+
+        long maxFileSize = 0;
+
+        for (File file : files) {
+            if (file == null) {
+                continue;
+            }
+
+            if (file.length() > maxFileSize) {
+                maxFileSize = file.length();
+            }
+        }
+
+        int idealBlocks = (int) (maxFileSize / (10L * 512L));
+
+        // I.e., 1/10 of the file, in units of 512 byte blocks.
+        // It's fine that operations will truncate down instead of round.
+        if (idealBlocks < 1) {
+            return 1;
+        }
+
+        if (idealBlocks > 40 * 1024) {
+            return 40 * 1024;
+        }
+
+        return idealBlocks;
+    }
+
+    /**
+     * Convenience wrapper for generateBufferBlockValue(File[]).
+     *
+     * @see #generateBufferBlockValue(File[])
+     */
+    static protected int generateBufferBlockValue(File file) {
+        return generateBufferBlockValue(new File[]{ file });
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/PIFData.java b/src/org/hsqldb/lib/tar/PIFData.java
new file mode 100644
index 0000000..7a5b7f4
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/PIFData.java
@@ -0,0 +1,116 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Pax Interchange Format object constituted from an Input Stream.
+ * <P>
+ * Right now, the only Pax property that we support directly is "size".
+ * </P> <P>
+ */
+public class PIFData extends HashMap<String, String> {
+    static final long serialVersionUID = 3086795680582315773L;
+
+    private static Pattern pifRecordPattern =
+        Pattern.compile("\\d+ +([^=]+)=(.*)");
+
+    /**
+     * N.b. this is nothing to do with HashMap.size() or Map.size().
+     * This returns the value of the Pax "size" property.
+     */
+    public Long getSize() {
+        return sizeObject;
+    }
+
+    private Long sizeObject = null;
+
+    public PIFData(InputStream stream)
+    throws TarMalformatException, IOException {
+
+        BufferedReader br = null;
+        try {
+            br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
+            String  s, k, v;
+            Matcher m;
+            int     lineNum = 0;
+
+            /*
+             * Pax spec does not allow for blank lines, ignored white space,
+             * nor comments of any type, in the file.
+             */
+            while ((s = br.readLine()) != null) {
+                lineNum++;
+
+                m = pifRecordPattern.matcher(s);
+
+                if (!m.matches()) {
+                    throw new TarMalformatException(
+                        RB.pif_malformat.getString(lineNum, s));
+                }
+
+                k = m.group(1);
+                v = m.group(2);
+
+                if (v == null || v.length() < 1) {
+                    remove(k);
+                } else {
+                    put(k, v);
+                }
+            }
+        } finally {
+            try {
+                stream.close();
+            } finally {
+                br = null;  // Encourage buffer GC
+            }
+        }
+
+        String sizeString = get("size");
+
+        if (sizeString != null) {
+            try {
+                sizeObject = Long.valueOf(sizeString);
+            } catch (NumberFormatException nfe) {
+                throw new TarMalformatException(
+                    RB.pif_malformat_size.getString(sizeString));
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/PIFGenerator.java b/src/org/hsqldb/lib/tar/PIFGenerator.java
new file mode 100644
index 0000000..55dd1c3
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/PIFGenerator.java
@@ -0,0 +1,181 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+
+/**
+ * Encapsulates Pax Interchange Format key/value pairs.
+ */
+public class PIFGenerator extends ByteArrayOutputStream {
+
+    OutputStreamWriter writer;
+    String             name;
+    int                fakePid;    // Only used by contructors
+    char               typeFlag;
+
+    public String getName() {
+        return name;
+    }
+
+    protected PIFGenerator() {
+
+        try {
+            writer = new OutputStreamWriter(this, "UTF-8");
+        } catch (UnsupportedEncodingException uee) {
+            throw new RuntimeException(
+                "Serious problem.  JVM can't encode UTF-8", uee);
+        }
+
+        fakePid = (int) (new Date().getTime() % 100000L);
+
+        // Java doesn't have access to PIDs, as PIF wants in the "name" field,
+        // so we emulate one in a way that is easy for us.
+    }
+
+    /**
+     * Construct a PIFGenerator object for a 'g' record.
+     *
+     * @param sequenceNum  Index starts at 1 in each Tar file
+     */
+    public PIFGenerator(int sequenceNum) {
+
+        this();
+
+        if (sequenceNum < 1) {
+
+            // No need to localize.  Would be caught at dev-time.
+            throw new IllegalArgumentException("Sequence numbers start at 1");
+        }
+
+        typeFlag = 'g';
+        name = System.getProperty("java.io.tmpdir") + "/GlobalHead." + fakePid
+               + '.' + sequenceNum;
+    }
+
+    /**
+     * Construct a PIFGenerator object for a 'x' record.
+     *
+     * @param file Target file of the x record.
+     */
+    public PIFGenerator(File file) {
+
+        this();
+
+        typeFlag = 'x';
+
+        String parentPath = (file.getParentFile() == null) ? "."
+                                                           : file.getParentFile()
+                                                               .getPath();
+
+        name = parentPath + "/PaxHeaders." + fakePid + '/' + file.getName();
+    }
+
+    /**
+     * Convenience wrapper for addRecord(String, String).
+     * N.b. this writes values exactly as either "true" or "false".
+     *
+     * @see #addRecord(String, String)
+     * @see Boolean#toString(boolean)
+     */
+    public void addRecord(String key,
+                          boolean b)
+                          throws TarMalformatException, IOException {
+        addRecord(key, Boolean.toString(b));
+    }
+
+    /**
+     * Convenience wrapper for addRecord(String, String).
+     *
+     * @see #addRecord(String, String)
+     */
+    public void addRecord(String key,
+                          int i) throws TarMalformatException, IOException {
+        addRecord(key, Integer.toString(i));
+    }
+
+    /**
+     * Convenience wrapper for addRecord(String, String).
+     *
+     * @see #addRecord(String, String)
+     */
+    public void addRecord(String key,
+                          long l) throws TarMalformatException, IOException {
+        addRecord(key, Long.toString(l));
+    }
+
+    /**
+     * I guess the "initial length" field is supposed to be in units of
+     * characters, not bytes?
+     */
+    public void addRecord(String key,
+                          String value)
+                          throws TarMalformatException, IOException {
+
+        if (key == null || value == null || key.length() < 1
+                || value.length() < 1) {
+            throw new TarMalformatException(RB.zero_write.getString());
+        }
+
+        int lenWithoutIlen = key.length() + value.length() + 3;
+
+        // "Ilen" means Initial Length field.  +3 = SPACE + = + \n
+        int lenW = 0;    // lenW = Length With initial-length-field
+
+        if (lenWithoutIlen < 8) {
+            lenW = lenWithoutIlen + 1;    // Takes just 1 char to report total
+        } else if (lenWithoutIlen < 97) {
+            lenW = lenWithoutIlen + 2;    // Takes 2 chars to report this total
+        } else if (lenWithoutIlen < 996) {
+            lenW = lenWithoutIlen + 3;    // Takes 3...
+        } else if (lenWithoutIlen < 9995) {
+            lenW = lenWithoutIlen + 4;    // ditto
+        } else if (lenWithoutIlen < 99994) {
+            lenW = lenWithoutIlen + 5;
+        } else {
+            throw new TarMalformatException(RB.pif_toobig.getString(99991));
+        }
+
+        writer.write(Integer.toString(lenW));
+        writer.write(' ');
+        writer.write(key);
+        writer.write('=');
+        writer.write(value);
+        writer.write('\n');
+        writer.flush();    // Does this do anything with a BAOS?
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/RB.java b/src/org/hsqldb/lib/tar/RB.java
new file mode 100644
index 0000000..55e2026
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/RB.java
@@ -0,0 +1,179 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+import org.hsqldb.lib.ValidatingResourceBundle;
+import org.hsqldb.lib.RefCapableRBInterface;
+
+/* $Id: RB.java 3481 2010-02-26 18:05:06Z fredt $ */
+
+/**
+ * Resource Bundle for Tar classes
+ * <P>
+ * Purpose of this class is to wrap a RefCapablePropertyResourceBundle to
+ *  reliably detect any possible use of a missing property key as soon as
+ *  this class is clinitted.
+ * The reason for this is to allow us developers to detect all such errors
+ *  before end-users ever use this class.
+ * </P> <P>
+ * IMPORTANT:  To add a new ResourceBundle element, add two new lines, one
+ * like <PRE>
+ *    static public final int NEWKEYID = keyCounter++;
+ * </PRE> and one line <PRE>
+ *      new Integer(KEY2), "key2",
+ * </PRE>
+ * Both should be inserted right after all of the other lines of the same type.
+ * NEWKEYID is obviously a new constant which you will use in calling code
+ * like RB.NEWKEYID.
+ * </P>
+ */
+public enum RB implements RefCapableRBInterface {
+    DbBackup_syntax,
+    DbBackup_syntaxerr,
+    TarGenerator_syntax,
+    pad_block_write,
+    cleanup_rmfail,
+    TarReader_syntax,
+    unsupported_entry_present,
+    bpr_write,
+    stream_buffer_report,
+    write_queue_report,
+    file_missing,
+    modified_property,
+    file_disappeared,
+    file_changed,
+    file_appeared,
+    pif_malformat,
+    pif_malformat_size,
+    zero_write,
+    pif_toobig,
+    read_denied,
+    compression_unknown,
+    insufficient_read,
+    decompression_ranout,
+    move_work_file,
+    cant_overwrite,
+    cant_write_dir,
+    no_parent_dir,
+    bad_block_write_len,
+    illegal_block_boundary,
+    workfile_delete_fail,
+    unsupported_ext,
+    dest_exists,
+    parent_not_dir,
+    cant_write_parent,
+    parent_create_fail,
+    tar_field_toobig,
+    missing_supp_path,
+    nonfile_entry,
+    read_lt_1,
+    data_changed,
+    unexpected_header_key,
+    tarreader_syntaxerr,
+    unsupported_mode,
+    dir_x_conflict,
+    pif_unknown_datasize,
+    pif_data_toobig,
+    data_size_unknown,
+    extraction_exists,
+    extraction_exists_notfile,
+    extraction_parent_not_dir,
+    extraction_parent_not_writable,
+    extraction_parent_mkfail,
+    write_count_mismatch,
+    header_field_missing,
+    checksum_mismatch,
+    create_only_normal,
+    bad_header_value,
+    bad_numeric_header_value,
+    listing_format,
+    ;
+
+    private static ValidatingResourceBundle vrb =
+            new ValidatingResourceBundle(
+                    RB.class.getPackage().getName() + ".rb", RB.class);
+    static {
+        vrb.setMissingPosValueBehavior(
+                ValidatingResourceBundle.NOOP_BEHAVIOR);
+        vrb.setMissingPropertyBehavior(
+                ValidatingResourceBundle.NOOP_BEHAVIOR);
+    }
+
+    public String getString() {
+        return vrb.getString(this);
+    }
+    public String toString() {
+        return ValidatingResourceBundle.resourceKeyFor(this);
+    }
+    public String getExpandedString() {
+        return vrb.getExpandedString(this);
+    }
+    public String getExpandedString(String... strings) {
+        return vrb.getExpandedString(this, strings);
+    }
+    public String getString(String... strings) {
+        return vrb.getString(this, strings);
+    }
+    public String getString(int i1) {
+        return vrb.getString(this, i1);
+    }
+    public String getString(int i1, int i2) {
+        return vrb.getString(this, i1, i2);
+    }
+    public String getString(int i1, int i2, int i3) {
+        return vrb.getString(this, i1, i2, i3);
+    }
+    public String getString(int i1, String s2) {
+        return vrb.getString(this, i1, s2);
+    }
+    public String getString(String s1, int i2) {
+        return vrb.getString(this, s1, i2);
+    }
+    public String getString(int i1, int i2, String s3) {
+        return vrb.getString(this, i1, i2, s3);
+    }
+    public String getString(int i1, String s2, int i3) {
+        return vrb.getString(this, i1, s2, i3);
+    }
+    public String getString(String s1, int i2, int i3) {
+        return vrb.getString(this, s1, i2, i3);
+    }
+    public String getString(int i1, String s2, String s3) {
+        return vrb.getString(this, i1, s3, s3);
+    }
+    public String getString(String s1, String s2, int i3) {
+        return vrb.getString(this, s1, s2, i3);
+    }
+    public String getString(String s1, int i2, String s3) {
+        return vrb.getString(this, s1, i2, s3);
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/TarFileInputStream.java b/src/org/hsqldb/lib/tar/TarFileInputStream.java
new file mode 100644
index 0000000..33c8a0a
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/TarFileInputStream.java
@@ -0,0 +1,307 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * Note that this class <b>is not</b> a java.io.FileInputStream,
+ * because our goal is to greatly restrict the public methods of
+ * FileInputStream, yet we must use public methods of the underlying
+ * FileInputStream internally.  Can't accomplish these goals in Java if we
+ * subclass.
+ * <P>
+ * This class is ignorant about Tar header fields, attributes and such.
+ * It is concerned with reading and writing blocks of data in conformance with
+ * Tar formatting, in a way convenient to those who want to get the header and
+ * data blocks.
+ * </P> <P>
+ * Asymmetric to the Tar file writing side, the bufferBlocks setting here is
+ * used only for to adjust read buffer size (for file data reads), so the user
+ * can compromise between available memory and performance.  Small buffer sizes
+ * will always work, but will incur more reads; on the other hand, buffer sizes
+ * larger than the largest component file is just a waste of memory.
+ * </P> <P>
+ * We assume the responsibility to manage the setting because the decision
+ * should be based on available RAM more than anything else (therefore, we can't
+ * set a good value automatically).
+ * </P> <P>
+ * As alluded to above, headers are read in separate reads, regardless of the
+ * readBufferBlocks setting.  readBufferBlocks is used for reading
+ * <I>file data</I>.
+ * </P> <P>
+ * I have purposefully not implemented skip(), because, though I haven't tested
+ * it, I believe our readBlock() and readBlocks() methods are at least as fast,
+ * since we use the larges read buffer within limits the user has set.
+ * </P>
+ */
+public class TarFileInputStream {
+
+    /* Would love to use a RandomAccessFile, but RandomAccessFiles do not play
+     * nicely with InputStreams or filters, and it just would not work with
+     * compressed input. */
+    protected long bytesRead = 0;
+
+    // Pronounced as past tense of "to read", not the other forms of "read".
+    // I.e., the homonym of "red".
+    private InputStream readStream;
+
+    /* This is not a "Reader", but the byte "Stream" that we read() from. */
+    protected byte[] readBuffer;
+    protected int    readBufferBlocks;
+    protected int    compressionType;
+
+    /**
+     * Convenience wrapper to use default readBufferBlocks and compressionType.
+     *
+     * @see #TarFileInputStream(File, int, int)
+     */
+    public TarFileInputStream(File sourceFile) throws IOException {
+        this(sourceFile, TarFileOutputStream.Compression.DEFAULT_COMPRESSION);
+    }
+
+    /**
+     * Convenience wrapper to use default readBufferBlocks.
+     *
+     * @see #TarFileInputStream(File, int, int)
+     */
+    public TarFileInputStream(File sourceFile,
+                              int compressionType) throws IOException {
+        this(sourceFile, compressionType,
+             TarFileOutputStream.Compression.DEFAULT_BLOCKS_PER_RECORD);
+    }
+
+    public int getReadBufferBlocks() {
+        return readBufferBlocks;
+    }
+
+    /**
+     * This class does no validation or enforcement of file naming conventions.
+     * If desired, the caller should enforce extensions like "tar" and
+     * "tar.gz" (and that they match the specified compression type).
+     * <P>
+     * This object will automatically release its I/O resources when you get
+     * false back from a readNextHeaderBlock() call.
+     * If you abort before then, you must call the close() method like for a
+     * normal InputStream.
+     * </P>
+     *
+     * @see #close()
+     * @see #readNextHeaderBlock()
+     */
+    public TarFileInputStream(File sourceFile, int compressionType,
+                              int readBufferBlocks) throws IOException {
+
+        if (!sourceFile.isFile()) {
+            throw new FileNotFoundException(sourceFile.getAbsolutePath());
+        }
+
+        if (!sourceFile.canRead()) {
+            throw new IOException(
+                    RB.read_denied.getString(sourceFile.getAbsolutePath()));
+        }
+
+        this.readBufferBlocks = readBufferBlocks;
+        this.compressionType  = compressionType;
+        readBuffer            = new byte[readBufferBlocks * 512];
+
+        switch (compressionType) {
+
+            case TarFileOutputStream.Compression.NO_COMPRESSION :
+                readStream = new FileInputStream(sourceFile);
+                break;
+
+            case TarFileOutputStream.Compression.GZIP_COMPRESSION :
+                readStream =
+                    new GZIPInputStream(new FileInputStream(sourceFile),
+                                        readBuffer.length);
+                break;
+
+            default :
+                throw new IllegalArgumentException(
+                    RB.compression_unknown.getString(compressionType));
+        }
+    }
+
+    /**
+     * readBlocks(int) is the method that USERS of this class should use to
+     * read file data from the tar file.
+     * This method reads from the tar file and writes to the readBuffer array.
+     * <P>
+     * This class and subclasses should read from the underlying readStream
+     * <b>ONLY WITH THIS METHOD</b>.
+     * That way we can be confident that bytesRead will always be accurate.
+     * </P> <P>
+     * This method is different from a typical Java byte array read command
+     * in that when reading tar files <OL>
+     *   <LI>we always know ahead-of-time how many bytes we should read, and
+     *   <LI>we always want to read quantities of bytes in multiples of 512.
+     * </OL>
+     * </P>
+     *
+     * @param blocks  How many 512 blocks to read.
+     * @throws IOException for an I/O error on the underlying InputStream
+     * @throws TarMalformatException if no I/O error occurred, but we failed to
+     *                               read the exact number of bytes requested.
+     */
+    public void readBlocks(int blocks)
+    throws IOException, TarMalformatException {
+
+        /* int for blocks should support sizes up to about 1T, according to
+         * my off-the-cuff calculations */
+        if (compressionType
+                != TarFileOutputStream.Compression.NO_COMPRESSION) {
+            readCompressedBlocks(blocks);
+
+            return;
+        }
+
+        int i = readStream.read(readBuffer, 0, blocks * 512);
+
+        bytesRead += i;
+
+        if (i != blocks * 512) {
+            throw new TarMalformatException(
+                RB.insufficient_read.getString(blocks * 512, i));
+        }
+    }
+
+    /**
+     * Work-around for the problem that compressed InputReaders don't fill
+     * the read buffer before returning.
+     *
+     * Has visibility 'protected' so that subclasses may override with
+     * different algorithms, or use different algorithms for different
+     * compression stream.
+     */
+    protected void readCompressedBlocks(int blocks) throws IOException {
+
+        int bytesSoFar    = 0;
+        int requiredBytes = 512 * blocks;
+
+        // This method works with individual bytes!
+        int i;
+
+        while (bytesSoFar < requiredBytes) {
+            i = readStream.read(readBuffer, bytesSoFar,
+                                requiredBytes - bytesSoFar);
+
+            if (i < 0) {
+                throw new EOFException(RB.decompression_ranout.getString(
+                        bytesSoFar, requiredBytes));
+            }
+
+            bytesRead  += i;
+            bytesSoFar += i;
+        }
+    }
+
+    /**
+     * readBlock() and readNextHeaderBlock are the methods that USERS of this
+     * class should use to read header blocks from the tar file.
+     * <P>
+     * readBlock() should be used when you know that the current block should
+     * contain what you want.
+     * E.g. you know that the very first block of a tar file should contain
+     * a Tar Entry header block.
+     * </P>
+     *
+     * @see #readNextHeaderBlock
+     */
+    public void readBlock() throws IOException, TarMalformatException {
+        readBlocks(1);
+    }
+
+    /**
+     * readBlock() and readNextHeaderBlock are the methods that USERS of this
+     * class should use to read header blocks from the tar file.
+     * <P>
+     * readNextHeaderBlock continues working through the Tar File from the
+     * current point until it finds a block with a non-0 first byte.
+     * </P>
+     *
+     * @return  True if a header block was read and place at beginning of the
+     *          readBuffer array.  False if EOF was encountered without finding
+     *          any blocks with first byte != 0.  If false is returned, we have
+     *          automatically closed the this TarFileInputStream too.
+     * @see #readBlock
+     */
+    public boolean readNextHeaderBlock()
+    throws IOException, TarMalformatException {
+
+        // We read a-byte-at-a-time because there should only be 2 empty blocks
+        // between each Tar Entry.
+        try {
+            while (readStream.available() > 0) {
+                readBlock();
+
+                if (readBuffer[0] != 0) {
+                    return true;
+                }
+            }
+        } catch (EOFException ee) {
+            /* This is a work-around.
+             * Sun Java's inputStream.available() works like crap.
+             * Reach this point when performing a read of a GZip stream when
+             * .available == 1, which according to API Spec, should not happen.
+             * We treat this condition exactly as if readStream.available is 0,
+             * which it should be.
+             */
+        }
+
+        close();
+
+        return false;
+    }
+
+    /**
+     * Implements java.io.Closeable.
+     *
+     * @see java.io.Closeable
+     */
+    public void close() throws IOException {
+        if (readStream == null) {
+            return;
+        }
+        try {
+            readStream.close();
+        } finally {
+            readStream = null;  // Encourage buffer GC
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/TarFileOutputStream.java b/src/org/hsqldb/lib/tar/TarFileOutputStream.java
new file mode 100644
index 0000000..497bfa2
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/TarFileOutputStream.java
@@ -0,0 +1,372 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * Note that this class <b>is not</b> a java.io.FileOutputStream,
+ * because our goal is to greatly restrict the public methods of
+ * FileOutputStream, yet we must use public methods of the underlying
+ * FileOutputStream internally.  Can't accomplish these goals in Java if we
+ * subclass.
+ * <P>
+ * This class is ignorant about Tar header fields, attributes and such.
+ * It is concerned with reading and writing blocks of data in conformance with
+ * Tar formatting, in a way convenient to those who want to write the header
+ * and data blocks.
+ * </P> <P>
+ * Users write file data by means of populating the provided, public byte array,
+ * then calling the single write(int) method to write a portion of that array.
+ * This design purposefully goes with efficiency, simplicity, and performance
+ * over Java convention, which would not use public fields.
+ * </P> <P>
+ * At this time, we do not support appending.  That would greatly decrease the
+ * generality and simplicity of the our design, since appending is trivial
+ * without compression and very difficult with compression.
+ * </P> <P>
+ * Users must finish tar file creation by using the finish() method.
+ * Just like a normal OutputStream, if processing is aborted for any reason,
+ * the close() method must be used to free up system resources.
+ * </P> <P>
+ * <B>SECURITY NOTE</B>
+ * Due to pitiful lack of support for file security in Java before version 1.6,
+ * this class will only explicitly set permissions if it is compiled for Java
+ * 1.6.  If it was not, and if your tar entries contain private data in files
+ * with 0400 or similar, be aware that that file can be pretty much be
+ * extracted by anybody with access to the tar file.
+ * </P>
+ *
+ * @see #finish
+ * @see #close
+ */
+public class TarFileOutputStream {
+
+    public interface Compression {
+
+        public static final int NO_COMPRESSION            = 0;
+        public static final int GZIP_COMPRESSION          = 1;
+        public static final int DEFAULT_COMPRESSION       = NO_COMPRESSION;
+        public static final int DEFAULT_BLOCKS_PER_RECORD = 20;
+    }
+
+    public static boolean debug = Boolean.getBoolean("DEBUG");
+    protected int         blocksPerRecord;
+    protected long        bytesWritten = 0;
+    private OutputStream  writeStream;
+    private File          targetFile;
+    private File          writeFile;
+
+    /* This is not a "Writer", but the byte "Stream" that we write() to. */
+    public byte[] writeBuffer;
+    /* We purposefully provide no public getter or setter for writeBuffer.
+     * No getter because the whole point of this class is that the byte
+     * array is a direct, optimally efficient byte array.  No setter because
+     * the inside implementation of this class is intimately dependent upon
+     * the nature of the write buffer. */
+    public static final byte[] ZERO_BLOCK = new byte[512];
+
+    /**
+     * Convenience wrapper to use default blocksPerRecord and compressionType.
+     *
+     * @see #TarFileOutputStream(File, int, int)
+     */
+    public TarFileOutputStream(File targetFile) throws IOException {
+        this(targetFile, Compression.DEFAULT_COMPRESSION);
+    }
+
+    /**
+     * Convenience wrapper to use default blocksPerRecord.
+     *
+     * @see #TarFileOutputStream(File, int, int)
+     */
+    public TarFileOutputStream(File targetFile,
+                               int compressionType) throws IOException {
+        this(targetFile, compressionType,
+             TarFileOutputStream.Compression.DEFAULT_BLOCKS_PER_RECORD);
+    }
+
+    /**
+     * This class does no validation or enforcement of file naming conventions.
+     * If desired, the caller should enforce extensions like "tar" and
+     * "tar.gz" (and that they match the specified compression type).
+     *
+     * It also overwrites files without warning (just like FileOutputStream).
+     */
+    public TarFileOutputStream(File targetFile, int compressionType,
+                               int blocksPerRecord) throws IOException {
+
+        this.blocksPerRecord = blocksPerRecord;
+        this.targetFile      = targetFile;
+        writeFile = new File(targetFile.getParentFile(),
+                             targetFile.getName() + "-partial");
+
+        if (this.writeFile.exists()) {
+            throw new IOException(
+                    RB.move_work_file.getString(writeFile.getAbsolutePath()));
+        }
+
+        if (targetFile.exists() && !targetFile.canWrite()) {
+            throw new IOException(
+                    RB.cant_overwrite.getString(targetFile.getAbsolutePath()));
+        }
+
+        File parentDir = targetFile.getAbsoluteFile().getParentFile();
+
+        if (parentDir.exists() && parentDir.isDirectory()) {
+            if (!parentDir.canWrite()) {
+                throw new IOException(RB.cant_write_dir.getString(
+                        parentDir.getAbsolutePath()));
+            }
+        } else {
+            throw new IOException(
+                    RB.no_parent_dir.getString(parentDir.getAbsolutePath()));
+        }
+
+        writeBuffer = new byte[blocksPerRecord * 512];
+
+        switch (compressionType) {
+
+            case TarFileOutputStream.Compression.NO_COMPRESSION :
+                writeStream = new FileOutputStream(writeFile);
+                break;
+
+            case TarFileOutputStream.Compression.GZIP_COMPRESSION :
+                writeStream =
+                    new GZIPOutputStream(new FileOutputStream(writeFile),
+                                         writeBuffer.length);
+                break;
+
+            default :
+                throw new IllegalArgumentException(
+                    RB.compression_unknown.getString(compressionType));
+        }
+
+//#ifdef JAVA6
+        writeFile.setExecutable(false, true);
+        writeFile.setExecutable(false, false);
+        writeFile.setReadable(false, false);
+        writeFile.setReadable(true, true);
+        writeFile.setWritable(false, false);
+        writeFile.setWritable(true, true);
+
+//#endif
+        // We restrict permissions to the file owner before writing
+        // anything, in case we will be writing anything private into this
+        // file.
+    }
+
+    /**
+     * This class and subclasses should write to the underlying writeStream
+     * <b>ONLY WITH THIS METHOD</b>.
+     * That way we can be confident that bytesWritten will always be accurate.
+     */
+    public void write(byte[] byteArray, int byteCount) throws IOException {
+
+        writeStream.write(byteArray, 0, byteCount);
+
+        bytesWritten += byteCount;
+    }
+
+    /**
+     * The normal way to write file data (as opposed to header data or padding)
+     * using this class.
+     */
+    public void write(int byteCount) throws IOException {
+        write(writeBuffer, byteCount);
+    }
+
+    /**
+     * Write a user-specified 512-byte block.  *
+     * For efficiency, write(int) should be used when writing file body content.
+     *
+     * @see #write(int)
+     */
+    public void writeBlock(byte[] block) throws IOException {
+
+        if (block.length != 512) {
+            throw new IllegalArgumentException(
+                    RB.bad_block_write_len.getString(block.length));
+        }
+
+        write(block, block.length);
+    }
+
+    /**
+     * Writes the specified quantity of zero'd blocks.
+     */
+    public void writePadBlocks(int blockCount) throws IOException {
+
+        for (int i = 0; i < blockCount; i++) {
+            write(ZERO_BLOCK, ZERO_BLOCK.length);
+        }
+    }
+
+    /**
+     * Writes a single zero'd block.
+     */
+    public void writePadBlock() throws IOException {
+        writePadBlocks(1);
+    }
+
+    public int bytesLeftInBlock() {
+
+        int modulus = (int) (bytesWritten % 512L);
+
+        if (modulus == 0) {
+            return 0;
+        }
+
+        return 512 - modulus;
+    }
+
+    /**
+     * @throws IllegalStateException if end of file not on a block boundary.
+     */
+    public void assertAtBlockBoundary() {
+
+        if (bytesLeftInBlock() != 0) {
+            throw new IllegalArgumentException(
+                RB.illegal_block_boundary.getString(
+                        Long.toString(bytesWritten)));
+        }
+    }
+
+    /**
+     * Rounds out the current block to the next block bondary.
+     * If we are currently at a block boundary, nothing is done.
+     */
+    public void padCurrentBlock() throws IOException {
+
+        int padBytes = bytesLeftInBlock();
+
+        if (padBytes == 0) {
+            return;
+        }
+
+        write(ZERO_BLOCK, padBytes);
+
+        // REMOVE THIS DEV-ASSERTION:
+        assertAtBlockBoundary();
+    }
+
+    /**
+     * Implements java.io.Flushable.
+     *
+     * @see java.io.Flushable
+     */
+    public void flush() throws IOException {
+        writeStream.flush();
+    }
+
+    /**
+     * Implements java.io.Closeable.
+     * <P/>
+     * <B>IMPORTANT:<B/>  This method <B>deletes</B> the work file after
+     * closing it!
+     *
+     * @see java.io.Closeable
+     */
+    public void close() throws IOException {
+
+        if (writeStream == null) {
+            return;
+        }
+
+        try {
+            writeStream.close();
+
+            if (!writeFile.delete()) {
+                throw new IOException(
+                        RB.workfile_delete_fail.getString(
+                        writeFile.getAbsolutePath()));
+            }
+        } finally {
+            writeStream = null;  // Encourage buffer GC
+        }
+    }
+
+    public long getBytesWritten() {
+        return bytesWritten;
+    }
+
+    /**
+     * (Only) when this method returns successfully, the generated file will be
+     * a valid tar file.
+     *
+     * This method always performs a close, so you never need to call the close
+     * if your code makes it to this method.
+     * (You do need to call close if processing is aborted before calling
+     * finish()).
+     *
+     * @see #close
+     */
+    public void finish() throws IOException {
+
+        try {
+            long finalBlock = bytesWritten / 512 + 2;
+
+            if (finalBlock % blocksPerRecord != 0) {
+
+                // Round up total archive size to a blocksPerRecord multiple
+                finalBlock = (finalBlock / blocksPerRecord + 1)
+                             * blocksPerRecord;
+            }
+
+            int finalPadBlocks = (int) (finalBlock - bytesWritten / 512L);
+
+            if (TarFileOutputStream.debug) {
+                System.out.println(
+                        RB.pad_block_write.getString(finalPadBlocks));
+            }
+
+            writePadBlocks(finalPadBlocks);
+        } catch (IOException ioe) {
+            try {
+                close();
+            } catch (IOException ne) {
+
+                // Too difficult to report every single error.
+                // More important that the user know about the original Exc.
+            }
+
+            throw ioe;
+        }
+
+        writeStream.close();
+        writeFile.renameTo(targetFile);
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/TarGenerator.java b/src/org/hsqldb/lib/tar/TarGenerator.java
new file mode 100644
index 0000000..bc1a752
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/TarGenerator.java
@@ -0,0 +1,691 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hsqldb.lib.StringUtil;
+
+/**
+ * Generates a tar archive from specified Files and InputStreams.
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class TarGenerator {
+
+    /**
+     * Creates specified tar file to contain specified files, or stdin,
+     * using default blocks-per-record and replacing tar file if it already
+     * exists.
+     */
+    static public void main(String[] sa)
+    throws IOException, TarMalformatException {
+
+        if (sa.length < 1) {
+            System.out.println(
+                    RB.TarGenerator_syntax.getString(DbBackup.class.getName()));
+            System.exit(0);
+        }
+
+        TarGenerator generator = new TarGenerator(new File(sa[0]), true, null);
+
+        if (sa.length == 1) {
+            generator.queueEntry("stdin", System.in, 10240);
+        } else {
+            for (int i = 1; i < sa.length; i++) {
+                generator.queueEntry(new File(sa[i]));
+            }
+        }
+
+        generator.write();
+    }
+
+    protected TarFileOutputStream archive;
+    protected List<TarEntrySupplicant> entryQueue =
+            new ArrayList<TarEntrySupplicant>();
+    protected long                paxThreshold = 0100000000000L;
+
+    // in bytes.  Value here exactly = 8GB.
+
+    /**
+     * When data file is this size or greater, in bytes, a
+     * Pix Interchange Format 'x' record will be created and used for the file
+     * entry.
+     * <P>
+     * <B>Limitation</B>
+     * At this time, PAX is only implemented for entries added a Files,
+     * not entries added as Stream.
+     * </P>
+     */
+    public void setPaxThreshold(long paxThreshold) {
+        this.paxThreshold = paxThreshold;
+    }
+
+    /**
+     * @see #setPaxThreshold(long)
+     */
+    public long getPaxThreshold() {
+        return paxThreshold;
+    }
+
+    /**
+     * Compression is determined directly by the suffix of the file name in
+     * the specified path.
+     *
+     * @param inFile  Absolute or relative (from user.dir) File for
+     *                     tar file to be created.  getName() Suffix must
+     *                     indicate tar file and may indicate a compression
+     *                     method.
+     * @param overWrite    True to replace an existing file of same path.
+     * @param blocksPerRecord  Null will use default tar value.
+     */
+    public TarGenerator(File inFile, boolean overWrite,
+                        Integer blocksPerRecord) throws IOException {
+
+        File archiveFile = inFile.getAbsoluteFile();
+
+        // Do this so we can be sure .getParent*() is non-null.  (Also allows
+        // us to use .getPath() instead of very long .getAbsolutePath() for
+        // error messages.
+        int compression = TarFileOutputStream.Compression.NO_COMPRESSION;
+
+        if (archiveFile.getName().endsWith(".tgz")
+                || archiveFile.getName().endsWith(".tar.gz")) {
+            compression = TarFileOutputStream.Compression.GZIP_COMPRESSION;
+        } else if (archiveFile.getName().endsWith(".tar")) {
+
+            // purposefully do nothing
+        } else {
+            throw new IllegalArgumentException(RB.unsupported_ext.getString(
+                    getClass().getName(), archiveFile.getPath()));
+        }
+
+        if (archiveFile.exists()) {
+            if (!overWrite) {
+                throw new IOException(
+                        RB.dest_exists.getString(archiveFile.getPath()));
+            }
+        } else {
+            File parentDir = archiveFile.getParentFile();
+
+            // parentDir will be absolute, since archiveFile is absolute.
+            if (parentDir.exists()) {
+                if (!parentDir.isDirectory()) {
+                    throw new IOException(
+                        RB.parent_not_dir.getString(parentDir.getPath()));
+                }
+
+                if (!parentDir.canWrite()) {
+                    throw new IOException(
+                        RB.cant_write_parent.getString(parentDir.getPath()));
+                }
+            } else {
+                if (!parentDir.mkdirs()) {
+                    throw new IOException(
+                        RB.parent_create_fail.getString(parentDir.getPath()));
+                }
+            }
+        }
+
+        archive = (blocksPerRecord == null)
+                  ? new TarFileOutputStream(archiveFile, compression)
+                  : new TarFileOutputStream(archiveFile, compression,
+                                            blocksPerRecord.intValue());
+
+        if (blocksPerRecord != null && TarFileOutputStream.debug) {
+            System.out.println(
+                    RB.bpr_write.getString(blocksPerRecord.intValue()));
+        }
+    }
+
+    public void queueEntry(File file)
+    throws FileNotFoundException, TarMalformatException {
+        queueEntry(null, file);
+    }
+
+    public void queueEntry(String entryPath,
+                           File file)
+                           throws FileNotFoundException,
+                                  TarMalformatException {
+        entryQueue.add(new TarEntrySupplicant(entryPath, file, archive));
+    }
+
+    /**
+     * This method does not support Pax Interchange Format, nor data sizes
+     * greater than 2G.
+     * <P>
+     * This limitation may or may not be eliminated in the future.
+     * </P>
+     */
+    public void queueEntry(String entryPath, InputStream inStream,
+                           int maxBytes)
+                           throws IOException, TarMalformatException {
+        entryQueue.add(new TarEntrySupplicant(entryPath, inStream, maxBytes,
+                                              '0', archive));
+    }
+
+    /**
+     * This method does release all of the streams, even if there is a failure.
+     */
+    public void write() throws IOException, TarMalformatException {
+
+        if (TarFileOutputStream.debug) {
+            System.out.println(
+                    RB.write_queue_report.getString(entryQueue.size()));
+        }
+
+        TarEntrySupplicant entry;
+
+        try {
+            for (int i = 0; i < entryQueue.size(); i++) {
+                System.err.print(Integer.toString(i + 1) + " / "
+                                 + entryQueue.size() + ' ');
+
+                entry = entryQueue.get(i);
+
+                System.err.print(entry.getPath() + "... ");
+
+                if (entry.getDataSize() >= paxThreshold) {
+                    entry.makeXentry().write();
+                    System.err.print("x... ");
+                }
+
+                entry.write();
+                archive.assertAtBlockBoundary();
+                System.err.println();
+            }
+
+            archive.finish();
+        } catch (IOException ioe) {
+            System.err.println();    // Exception should cause a report
+
+            try {
+
+                // Just release resources from any Entry's input, which may be
+                // left open.
+                for (TarEntrySupplicant sup : entryQueue) {
+                    sup.close();
+                }
+
+                archive.close();
+            } catch (IOException ne) {
+
+                // Too difficult to report every single error.
+                // More important that the user know about the original Exc.
+            }
+
+            throw ioe;
+        }
+    }
+
+    /**
+     * Slots for supplicant files and input streams to be added to a Tar
+     * archive.
+     *
+     * @author Blaine Simpson (blaine dot simpson at admc dot com)
+     */
+    static protected class TarEntrySupplicant {
+
+        static protected byte[] HEADER_TEMPLATE =
+            TarFileOutputStream.ZERO_BLOCK.clone();
+        static Character              swapOutDelim = null;
+        final protected static byte[] ustarBytes   = {
+            'u', 's', 't', 'a', 'r'
+        };
+
+        static {
+            char c = System.getProperty("file.separator").charAt(0);
+
+            if (c != '/') {
+                swapOutDelim = new Character(c);
+            }
+
+            try {
+                writeField(TarHeaderField.uid, 0L, HEADER_TEMPLATE);
+                writeField(TarHeaderField.gid, 0L, HEADER_TEMPLATE);
+            } catch (TarMalformatException tme) {
+
+                // This would definitely get caught in Dev env.
+                throw new RuntimeException(tme);
+            }
+
+            // Setting uid and gid to 0 = root.
+            // Misleading, yes.  Anything better we can do?  No.
+            int magicStart = TarHeaderField.magic.getStart();
+
+            for (int i = 0; i < ustarBytes.length; i++) {
+
+                // UStar magic field
+                HEADER_TEMPLATE[magicStart + i] = ustarBytes[i];
+            }
+
+            HEADER_TEMPLATE[263] = '0';
+            HEADER_TEMPLATE[264] = '0';
+
+            // UStar version field, version = 00
+            // This is the field that Gnu Tar desecrates.
+        }
+
+        static protected void writeField(TarHeaderField field, String newValue,
+                                         byte[] target)
+                                         throws TarMalformatException {
+
+            int    start = field.getStart();
+            int    stop  = field.getStop();
+            byte[] ba;
+
+            try {
+                ba = newValue.getBytes("ISO-8859-1");
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+
+            if (ba.length > stop - start) {
+                throw new TarMalformatException(
+                    RB.tar_field_toobig.getString(field.toString(), newValue));
+            }
+
+            for (int i = 0; i < ba.length; i++) {
+                target[start + i] = ba[i];
+            }
+        }
+
+        static protected void clearField(TarHeaderField field, byte[] target) {
+
+            int start = field.getStart();
+            int stop  = field.getStop();
+
+            for (int i = start; i < stop; i++) {
+                target[i] = 0;
+            }
+        }
+
+        static protected void writeField(TarHeaderField field, long newValue,
+                                         byte[] target)
+                                         throws TarMalformatException {
+
+            TarEntrySupplicant.writeField(
+                field,
+                TarEntrySupplicant.prePaddedOctalString(
+                    newValue, field.getStop() - field.getStart()), target);
+        }
+
+        static public String prePaddedOctalString(long val, int width) {
+            return StringUtil.toPaddedString(Long.toOctalString(val), width,
+                                             '0', false);
+        }
+
+        protected byte[] rawHeader = HEADER_TEMPLATE.clone();
+        protected String fileMode  = DEFAULT_FILE_MODES;
+
+        // Following fields are always initialized by constructors.
+        protected InputStream         inputStream;
+        protected String              path;
+        protected long                modTime;
+        protected TarFileOutputStream tarStream;
+        protected long                dataSize;    // In bytes
+        protected boolean             paxSized = false;
+
+        // Size will only be written to entry's header if paxSized is false.
+        public String getPath() {
+            return path;
+        }
+
+        public long getDataSize() {
+            return dataSize;
+        }
+
+        /*
+         * Internal constructor that validates the entry's path.
+         */
+        protected TarEntrySupplicant(String path, char typeFlag,
+                                     TarFileOutputStream tarStream)
+                                     throws TarMalformatException {
+
+            if (path == null) {
+                throw new IllegalArgumentException(
+                    RB.missing_supp_path.getString());
+            }
+
+            this.path = (swapOutDelim == null) ? path
+                                               : path.replace(
+                                                   swapOutDelim.charValue(),
+                                                   '/');
+            this.tarStream = tarStream;
+
+            writeField(TarHeaderField.typeflag, typeFlag);
+
+            if (typeFlag == '\0' || typeFlag == ' ') {
+                writeField(TarHeaderField.uname,
+                           System.getProperty("user.name"), HEADER_TEMPLATE);
+                writeField(TarHeaderField.gname, "root", HEADER_TEMPLATE);
+
+                // Setting UNAME and GNAME at the instance level instead of the
+                // static template, because record types 'x' and 'g' do not set
+                // these fields.
+                // POSIX UStar compliance requires that we set "gname" field.
+                // It's impossible for use to determine the correct value from
+                // Java.  We punt with "root" because (a) it's the only group
+                // name
+                // we know should exist on every UNIX system, and (b) every tar
+                // client gracefully handles it when extractor user does not
+                // have privs for the specified group.
+            }
+        }
+
+        /**
+         * This creates a 'x' entry for a 0/\0 entry.
+         */
+        public TarEntrySupplicant makeXentry()
+        throws IOException, TarMalformatException {
+
+            PIFGenerator pif = new PIFGenerator(new File(path));
+
+            pif.addRecord("size", dataSize);
+
+            paxSized = true;
+
+            // This tells the target entry to NOT set the size header field,
+            // to ensure that no tar client accidentally extracts only
+            // a portion of the file data.
+            // If the client can't read the correct size from the PIF data,
+            // we want the client to report that so the user can get a better
+            // tar client!
+            /* Really bad to make pseudo-stream just to get a byte array out
+             * of it, but it would be a very poor use of development time to
+             * re-design this class because the comparative time wasted at
+             * runtime will be negligable compared to storing the data entries.
+             */
+            return new TarEntrySupplicant(
+                pif.getName(), new ByteArrayInputStream(pif.toByteArray()),
+                pif.size(), 'x', tarStream);
+        }
+
+        /**
+         * After instantiating a TarEntrySupplicant, the user must either invoke
+         * write() or close(), to release system resources on the input
+         * File/Stream.
+         */
+        public TarEntrySupplicant(String path, File file,
+                                  TarFileOutputStream tarStream)
+                                  throws FileNotFoundException,
+                                         TarMalformatException {
+
+            // Must use an expression-embedded ternary here to satisfy compiler
+            // that this() call be first statement in constructor.
+            this(((path == null) ? file.getPath()
+                                 : path), '0', tarStream);
+
+            // Difficult call for '0'.  binary 0 and character '0' both mean
+            // regular file.  Binary 0 pre-UStar is probably more portable,
+            // but we are writing a valid UStar header, and I doubt anybody's
+            // tar implementation would choke on this since there is no
+            // outcry of UStar archives failing to work with older tars.
+            if (!file.isFile()) {
+                throw new IllegalArgumentException(
+                        RB.nonfile_entry.getString());
+            }
+
+            if (!file.canRead()) {
+                throw new IllegalArgumentException(
+                    RB.read_denied.getString(file.getAbsolutePath()));
+            }
+
+            modTime     = file.lastModified() / 1000L;
+            fileMode    = TarEntrySupplicant.getLameMode(file);
+            dataSize    = file.length();
+            inputStream = new FileInputStream(file);
+        }
+
+        /**
+         * After instantiating a TarEntrySupplicant, the user must either invoke
+         * write() or close(), to release system resources on the input
+         * File/Stream.
+         * <P>
+         * <B>WARNING:</B>
+         * Do not use this method unless the quantity of available RAM is
+         * sufficient to accommodate the specified maxBytes all at one time.
+         * This constructor loads all input from the specified InputStream into
+         * RAM before anything is written to disk.
+         * </P>
+         *
+         * @param maxBytes This method will fail if more than maxBytes bytes
+         *                 are supplied on the specified InputStream.
+         *                 As the type of this parameter enforces, the max
+         *                 size you can request is 2GB.
+         */
+        public TarEntrySupplicant(String path, InputStream origStream,
+                                  int maxBytes, char typeFlag,
+                                  TarFileOutputStream tarStream)
+                                  throws IOException, TarMalformatException {
+
+            /*
+             * If you modify this, make sure to not intermix reading/writing of
+             * the PipedInputStream and the PipedOutputStream, or you could
+             * cause dead-lock.  Everything is safe if you close the
+             * PipedOutputStream before reading the PipedInputStream.
+             */
+            this(path, typeFlag, tarStream);
+
+            if (maxBytes < 1) {
+                throw new IllegalArgumentException(RB.read_lt_1.getString());
+            }
+
+            int               i;
+            PipedOutputStream outPipe = new PipedOutputStream();
+
+            /* This constructor not available until Java 1.6:
+            inputStream = new PipedInputStream(outPipe, maxBytes);
+            */
+            try {
+                inputStream = new PipedInputStream(outPipe);
+                while ((i =
+                        origStream
+                            .read(tarStream.writeBuffer, 0, tarStream
+                                .writeBuffer.length)) > 0) {
+                    outPipe.write(tarStream.writeBuffer, 0, i);
+                }
+
+                outPipe.flush();    // Do any good on a pipe?
+
+                dataSize = inputStream.available();
+
+                if (TarFileOutputStream.debug) {
+                    System.out.println(
+                        RB.stream_buffer_report.getString(
+                                Long.toString(dataSize)));
+                }
+            } catch (IOException ioe) {
+                close();
+
+                throw ioe;
+            } finally {
+                try {
+                    outPipe.close();
+                } finally {
+                    outPipe = null;  // Encourage buffer GC
+                }
+            }
+
+            modTime = new java.util.Date().getTime() / 1000L;
+        }
+
+        public void close() throws IOException {
+            if (inputStream == null) {
+                return;
+            }
+
+            try {
+                inputStream.close();
+            } finally {
+                inputStream = null;  // Encourage buffer GC
+            }
+        }
+
+        protected long headerChecksum() {
+
+            long sum = 0;
+
+            for (int i = 0; i < rawHeader.length; i++) {
+                boolean isInRange =
+                    (i >= TarHeaderField.checksum.getStart()
+                     && i < TarHeaderField.checksum.getStop());
+
+                sum += isInRange ? 32
+                                 : (255 & rawHeader[i]);
+
+                // We ignore current contents of the checksum field so that
+                // this method will continue to work right, even if we later
+                // recycle the header or RE-calculate a header.
+            }
+
+            return sum;
+        }
+
+        protected void clearField(TarHeaderField field) {
+            TarEntrySupplicant.clearField(field, rawHeader);
+        }
+
+        protected void writeField(TarHeaderField field, String newValue)
+                throws TarMalformatException {
+            TarEntrySupplicant.writeField(field, newValue, rawHeader);
+        }
+
+        protected void writeField(TarHeaderField field, long newValue)
+                throws TarMalformatException {
+            TarEntrySupplicant.writeField(field, newValue, rawHeader);
+        }
+
+        protected void writeField(TarHeaderField field, char c)
+                throws TarMalformatException {
+            TarEntrySupplicant.writeField(field, Character.toString(c),
+                                          rawHeader);
+        }
+
+        /**
+         * Writes entire entry to this object's tarStream.
+         *
+         * This method is guaranteed to close the supplicant's input stream.
+         */
+        public void write() throws IOException, TarMalformatException {
+
+            int i;
+
+            try {
+                writeField(TarHeaderField.name, path);
+
+                // TODO:  If path.length() > 99, then write a PIF entry with
+                // the file path.
+                // Don't waste time using the PREFIX header field.
+                writeField(TarHeaderField.mode, fileMode);
+
+                if (!paxSized) {
+                    writeField(TarHeaderField.size, dataSize);
+                }
+
+                writeField(TarHeaderField.mtime, modTime);
+                writeField(
+                    TarHeaderField.checksum,
+                    TarEntrySupplicant.prePaddedOctalString(
+                        headerChecksum(), 6) + "\0 ");
+
+                // Silly, but that's what the base header spec calls for.
+                tarStream.writeBlock(rawHeader);
+
+                long dataStart = tarStream.getBytesWritten();
+
+                while ((i = inputStream.read(tarStream.writeBuffer)) > 0) {
+                    tarStream.write(i);
+                }
+
+                if (dataStart + dataSize != tarStream.getBytesWritten()) {
+                    throw new IOException(
+                            RB.data_changed.getString(Long.toString(dataSize),
+                            Long.toString(
+                            tarStream.getBytesWritten() - dataStart)));
+                }
+
+                tarStream.padCurrentBlock();
+            } finally {
+                close();
+            }
+        }
+
+        /**
+         * This method is so-named because it only sets the owner privileges,
+         * not any "group" or "other" privileges.
+         * <P>
+         * This is because of Java limitation.
+         * Incredibly, with Java 1.6, the API gives you the power to set
+         * privileges for "other" (last nibble in file Mode), but no ability
+         * to detect the same.
+         * </P>
+         */
+        static protected String getLameMode(File file) {
+
+            int umod = 0;
+
+//#ifdef JAVA6
+            if (file.canExecute()) {
+                umod = 1;
+            }
+
+//#endif
+            if (file.canWrite()) {
+                umod += 2;
+            }
+
+            if (file.canRead()) {
+                umod += 4;
+            }
+
+            return "0" + umod + "00";
+
+            // Conservative since Java gives us no way to determine group or
+            // other privileges on a file, and this file may contain passwords.
+        }
+
+        final static public String DEFAULT_FILE_MODES = "600";
+
+        // Be conservative, because these files contain passwords
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/TarHeaderField.java b/src/org/hsqldb/lib/tar/TarHeaderField.java
new file mode 100644
index 0000000..fcd9f2e
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/TarHeaderField.java
@@ -0,0 +1,119 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+/**
+ * Purely static structure defining our interface to the Tar Entry Header.
+ *
+ * The fields controlled here are fields for the individual tar file entries
+ * in an archive.  There is no such thing as a Header Field at the top archive
+ * level.
+ * <P>
+ * We use header field names as they are specified in the FreeBSD man page for
+ * tar in section 5 (Solaris and Linux have no such page in section 5).
+ * Where we use a constant, the constant name is just the FreeBSD field name
+ * capitalized.
+ * Since a single field is known as either "linkflag" or "typeflag", we are
+ * going with the UStar name typeflag for this field.
+ * </P> <P>
+ * We purposefully define no variable for this list of fields, since
+ * we DO NOT WANT TO access or change these values, due to application
+ * goals or JVM limitations:<UL>
+ *   <LI>gid
+ *   <LI>uid
+ *   <LI>linkname
+ *   <LI>magic (UStar ID),
+ *   <LI>magic version
+ *   <LI>group name
+ *   <LI>device major num
+ *   <LI>device minor num
+ * </UL>
+ * Our application has no use for these, or Java has no ability to
+ * work with them.
+ * </P> <P>
+ * This class will be very elegant when refactored as an enum with enumMap(s)
+ * and using generics with auto-boxing instead of the ugly and non-validating
+ * casts.
+ * </P>
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+@SuppressWarnings("boxing")
+public enum TarHeaderField {
+    // 1 PAST last position (in normal Java substring fashion).
+    /* Note that (with one exception), there is always 1 byte
+     * between a numeric field stop and the next start.  This is
+     * because null byte must occupy the intervening position.
+     * This is not true for non-numeric fields (which includes the
+     * link-indicator/type-flag field, which is used as a code,
+     * and is not necessarily numeric with UStar format).
+     *
+     * As a consequence, there may be NO DELIMITER after
+     * non-numerics, which may occupy the entire field segment.
+     *
+     * Arg.  man page for "pax" says that both original and ustar
+     * headers must be <= 100 chars. INCLUDING the trailing \0
+     * character.  ???  GNU tar certainly does not honor this.
+     */
+    name(0, 100),
+    mode(100, 107),
+    uid(108, 115),
+    gid(116, 123),
+    size(124, 135),
+    mtime(136, 147),  // (File.lastModified()|*.getTime())/1000
+    checksum(148, 156),// "Queer terminator" in original code.  ???
+                      // Pax UStore does not follow spec and delimits this
+                      // field like any other numeric, skipping the space byte.
+    typeflag(156, 157), // 1-byte CODE
+        // With current version, we are never doing anything with this
+        // field.  In future, we will support x and/or g type here.
+        // N.b. Gnu Tar does not honor this Stop.
+
+    // The remaining are from UStar format:
+    magic(257, 263),
+    uname(265, 296),
+    gname(297, 328),
+    prefix(345, 399),
+    ;
+
+    private TarHeaderField(int start, int stop) {
+        this.start = start;
+        this.stop = stop;
+    }
+    private int start, stop;
+
+    // The getters below throw RuntimExceptions instead of
+    // TarMalformatExceptions because these errors indicate a dev problem,
+    // not some problem with a Header, or generating or reading a Header.
+    public int getStart() { return start; }
+    public int getStop() { return stop; }
+}
diff --git a/src/org/hsqldb/lib/tar/TarMalformatException.java b/src/org/hsqldb/lib/tar/TarMalformatException.java
new file mode 100644
index 0000000..9ddcf32
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/TarMalformatException.java
@@ -0,0 +1,40 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+@SuppressWarnings("serial")
+public class TarMalformatException extends Exception {
+
+    public TarMalformatException(String s) {
+        super(s);
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/TarReader.java b/src/org/hsqldb/lib/tar/TarReader.java
new file mode 100644
index 0000000..0cb4d80
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/TarReader.java
@@ -0,0 +1,799 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.lib.tar;
+
+import org.hsqldb.lib.StringUtil;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.regex.Pattern;
+
+/**
+ * Reads a Tar file for reporting or extraction.
+ * N.b. this is not a <I>Reader</I> in the <CODE>java.io.Reader</CODE> sense,
+ * but in the sense of differentiating <CODE>tar x</CODE> and
+ * <CODE>tar t</CODE> from <CODE>tar c</CODE>.
+ * <P>
+ * <B>SECURITY NOTE</B>
+ * Due to pitiful lack of support for file security in Java before version 1.6,
+ * this class will only explicitly set permissions if it is compiled for Java
+ * 1.6.  If it was not, and if your tar entries contain private data in files
+ * with 0400 or similar, be aware that they will be extracted with privs such
+ * that they can be ready by anybody.
+ * </P>
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class TarReader {
+
+    final static public int LIST_MODE = 0;
+
+    /**
+     * EXTRACT_MODE refuses to overwrite existing files.
+     */
+    final static public int EXTRACT_MODE = 1;
+
+    /**
+     * OVERWRITE_MODE is just EXTRACT_MODE where we will silently overwrite
+     * existing files upon extraction.
+     */
+    final static public int OVERWRITE_MODE = 2;
+
+    /**
+     * Reads a specified tar file or stdin in order to either list or extract
+     * the file tar entries, depending on the first argument being "t" or "x",
+     * using default read buffer blocks.
+     */
+    static public void main(String[] sa)
+    throws IOException, TarMalformatException {
+
+        if (sa.length < 1) {
+            System.out.println(
+                    RB.TarReader_syntax.getString(TarReader.class.getName()));
+            System.out.println(RB.listing_format.getString());
+            System.exit(0);
+        }
+
+        File exDir = (sa.length > 1 && sa[1].startsWith("--directory="))
+                     ? (new File(sa[1].substring("--directory=".length())))
+                     : null;
+        int firstPatInd = (exDir == null) ? 2
+                                          : 3;
+
+        if (sa.length < firstPatInd
+                || ((!sa[0].equals("t")) && !sa[0].equals("x"))) {
+            throw new IllegalArgumentException(
+                RB.tarreader_syntaxerr.getString(TarReader.class.getName()));
+        }
+
+        String[] patternStrings = null;
+
+        if (sa.length > firstPatInd) {
+            patternStrings = new String[sa.length - firstPatInd];
+
+            for (int i = firstPatInd; i < sa.length; i++) {
+                patternStrings[i - firstPatInd] = sa[i];
+            }
+        }
+
+        if (sa[0].equals("t") && exDir != null) {
+            throw new IllegalArgumentException(RB.dir_x_conflict.getString());
+        }
+
+        int dirIndex      = (exDir == null) ? 1
+                                            : 2;
+        int tarReaderMode = sa[0].equals("t") ? LIST_MODE
+                                              : EXTRACT_MODE;
+
+        new TarReader(new File(sa[dirIndex]), tarReaderMode, patternStrings,
+                      null, exDir).read();
+    }
+
+    protected TarFileInputStream archive;
+    protected Pattern[]          patterns = null;
+    protected int                mode;
+    protected File               extractBaseDir;    // null means current directory
+
+    // Not used for Absolute path entries
+    // This path is always absolutized
+
+    /**
+     * Compression is determined directly by the suffix of the file name in
+     * the specified path.
+     *
+     * @param inFile  Absolute or relative (from user.dir) path to
+     *                tar file to be read.  Suffix may indicate
+     *                a compression method.
+     * @param mode    Whether to list, extract-without-overwrite, or
+     *                extract-with-overwrite.
+     * @param patternStrings
+     *                  List of regular expressions to match against tar entry
+     *                  names.  If null, all entries will be listed or
+     *                  extracted.  If non-null, then only entries with names
+     *                  which match will be extracted or listed.
+     * @param readBufferBlocks  Null will use default tar value.
+     * @param inDir   Directory that RELATIVE entries will be extracted
+     *                relative to.  Defaults to current directory (user.dir).
+     *                Only used for extract modes and relative file entries.
+     * @throws IllegalArgumentException if any given pattern is an invalid
+     *                  regular expression.  Don't have to worry about this if
+     *                  you call with null 'patterns' param.
+     * @see Pattern
+     */
+    public TarReader(File inFile, int mode, String[] patternStrings,
+                     Integer readBufferBlocks, File inDir) throws IOException {
+
+        this.mode = mode;
+
+        File archiveFile = inFile.getAbsoluteFile();
+
+        extractBaseDir = (inDir == null) ? null
+                                         : inDir.getAbsoluteFile();
+
+        int compression =
+            TarFileOutputStream.Compression.NO_COMPRESSION;
+
+        if (archiveFile.getName().endsWith(".tgz")
+                || archiveFile.getName().endsWith(".gz")) {
+            compression = TarFileOutputStream.Compression.GZIP_COMPRESSION;
+        }
+
+        if (patternStrings != null) {
+            patterns = new Pattern[patternStrings.length];
+
+            for (int i = 0; i < patternStrings.length; i++) {
+                patterns[i] = Pattern.compile(patternStrings[i]);
+            }
+        }
+
+        // Don't check for archive file existence here.  We can depend upon the
+        // TarFileInputStream to check that.
+        archive = (readBufferBlocks == null)
+                  ? new TarFileInputStream(archiveFile, compression)
+                  : new TarFileInputStream(archiveFile, compression,
+                                           readBufferBlocks.intValue());
+    }
+
+    public void read() throws IOException, TarMalformatException {
+
+        TarEntryHeader header;
+        boolean        anyUnsupporteds = false;
+        boolean        matched;
+        Long           paxSize   = null;
+        String         paxString = null;
+
+        try {
+            EACH_HEADER:
+            while (archive.readNextHeaderBlock()) {
+                header = new TarEntryHeader(archive.readBuffer);
+
+                char entryType = header.getEntryType();
+
+                if (entryType == 'x') {
+                    /* Since we don't know the name of the target file yet,
+                     * we must load the size from all pax headers.
+                     * If the target file is not thereafter excluded via
+                     * patterns, we will need this size for the listing or to
+                     * extract the data.
+                     */
+                    paxSize   = getPifData(header).getSize();
+                    paxString = header.toString();
+
+                    continue;
+                }
+
+                if (paxSize != null) {
+
+                    // Ignore "size" field in the entry header because PIF
+                    // setting overrides.
+                    header.setDataSize(paxSize.longValue());
+
+                    paxSize = null;
+                }
+
+                if (patterns != null) {
+                    matched = false;
+
+                    for (int i = 0; i < patterns.length; i++) {
+                        if (patterns[i].matcher(header.getPath()).matches()) {
+                            matched = true;
+
+                            break;
+                        }
+                    }
+
+                    if (!matched) {
+                        paxString = null;
+
+                        skipFileData(header);
+
+                        continue EACH_HEADER;
+                    }
+                }
+
+                if (entryType != '\0' && entryType != '0'
+                        && entryType != 'x') {
+                    anyUnsupporteds = true;
+                }
+
+                switch (mode) {
+
+                    case LIST_MODE :
+                        if (paxString != null) {
+                            System.out.println(paxString);
+                        }
+
+                        System.out.println(header.toString());
+                        skipFileData(header);
+                        break;
+
+                    case EXTRACT_MODE :
+                    case OVERWRITE_MODE :
+                        if (paxString != null) {
+                            System.out.println(paxString);
+                        }
+
+                        /* Display entry summary before successful extraction.
+                         * Both "tar" and "rsync" display the name of the
+                         * currently extracting file, and we do the same.
+                         * Thefore the currently "shown" name is still being
+                         * extracted.
+                         */
+                        System.out.println(header.toString());
+
+                        // Instance variable mode will be used to differentiate
+                        // behavior inside of extractFile().
+                        if (entryType == '\0' || entryType == '0'
+                                || entryType == 'x') {
+                            extractFile(header);
+                        } else {
+                            skipFileData(header);
+                        }
+                        break;
+
+                    default :
+                        throw new IllegalArgumentException(
+                                RB.unsupported_mode.getString(mode));
+                }
+
+                paxString = null;
+            }
+
+            if (anyUnsupporteds) {
+                System.out.println(RB.unsupported_entry_present.getString());
+            }
+        } catch (IOException ioe) {
+            archive.close();
+
+            throw ioe;
+        }
+    }
+
+    protected PIFData getPifData(TarEntryHeader header)
+    throws IOException, TarMalformatException {
+
+        /*
+         * If you modify this, make sure to not intermix reading/writing of
+         * the PipedInputStream and the PipedOutputStream, or you could
+         * cause dead-lock.  Everything is safe if you close the
+         * PipedOutputStream before reading the PipedInputStream.
+         */
+        long dataSize = header.getDataSize();
+
+        if (dataSize < 1) {
+            throw new TarMalformatException(
+                    RB.pif_unknown_datasize.getString());
+        }
+
+        if (dataSize > Integer.MAX_VALUE) {
+            throw new TarMalformatException(RB.pif_data_toobig.getString(
+                    Long.toString(dataSize), Integer.MAX_VALUE));
+        }
+
+        int readNow;
+        int readBlocks = (int) (dataSize / 512L);
+        int modulus    = (int) (dataSize % 512L);
+
+        // Couldn't care less about the entry "name" field.
+        PipedInputStream  inPipe  = null;
+        PipedOutputStream outPipe = new PipedOutputStream();
+
+        /* This constructor not available until Java 1.6:
+                new PipedInputStream(outPipe, (int) dataSize);
+        */
+        try {
+            inPipe = new PipedInputStream(outPipe);
+            while (readBlocks > 0) {
+                readNow = (readBlocks > archive.getReadBufferBlocks())
+                          ? archive.getReadBufferBlocks()
+                          : readBlocks;
+
+                archive.readBlocks(readNow);
+
+                readBlocks -= readNow;
+
+                outPipe.write(archive.readBuffer, 0, readNow * 512);
+            }
+
+            if (modulus != 0) { archive.readBlock();
+                outPipe.write(archive.readBuffer, 0, modulus);
+            }
+
+            outPipe.flush();    // Do any good on a pipe?
+        } catch (IOException ioe) {
+            if (inPipe != null) {
+                inPipe.close();
+            }
+
+            throw ioe;
+        } finally {
+            try {
+                outPipe.close();
+            } finally {
+                outPipe = null;  // Encourage buffer GC
+                inPipe = null;  // Encourage buffer GC
+            }
+        }
+
+        return new PIFData(inPipe);
+    }
+
+    protected void extractFile(TarEntryHeader header)
+    throws IOException, TarMalformatException {
+
+        if (header.getDataSize() < 1) {
+            throw new TarMalformatException(RB.data_size_unknown.getString());
+        }
+
+        int  readNow;
+        int  readBlocks = (int) (header.getDataSize() / 512L);
+        int  modulus    = (int) (header.getDataSize() % 512L);
+        File newFile    = header.generateFile();
+
+        if (!newFile.isAbsolute()) {
+            newFile = (extractBaseDir == null) ? newFile.getAbsoluteFile()
+                                               : new File(extractBaseDir,
+                                               newFile.getPath());
+        }
+
+        // newFile is definitively Absolutized at this point
+        File parentDir = newFile.getParentFile();
+
+        if (newFile.exists()) {
+            if (mode != TarReader.OVERWRITE_MODE) {
+                throw new IOException(
+                    RB.extraction_exists.getString(newFile.getAbsolutePath()));
+            }
+
+            if (!newFile.isFile()) {
+                throw new IOException(
+                        RB.extraction_exists_notfile.getString(
+                        newFile.getAbsolutePath()));
+            }
+
+            // Better to let FileOutputStream creation zero it than to
+            // to newFile.delete().
+        }
+
+        if (parentDir.exists()) {
+            if (!parentDir.isDirectory()) {
+                throw new IOException(
+                        RB.extraction_parent_not_dir.getString(
+                        parentDir.getAbsolutePath()));
+            }
+
+            if (!parentDir.canWrite()) {
+                throw new IOException(
+                        RB.extraction_parent_not_writable.getString(
+                        parentDir.getAbsolutePath()));
+            }
+        } else {
+            if (!parentDir.mkdirs()) {
+                throw new IOException(
+                        RB.extraction_parent_mkfail.getString(
+                        parentDir.getAbsolutePath()));
+            }
+        }
+
+        int              fileMode  = header.getFileMode();
+        FileOutputStream outStream = new FileOutputStream(newFile);
+
+        try {
+
+//#ifdef JAVA6
+            // Don't know exactly why I am still able to write to the file
+            // after removing read and write privs from myself, but it does
+            // work.
+            newFile.setExecutable(false, false);
+            newFile.setReadable(false, false);
+            newFile.setWritable(false, false);
+            newFile.setExecutable(((fileMode & 0100) != 0), true);
+            newFile.setReadable((fileMode & 0400) != 0, true);
+            newFile.setWritable((fileMode & 0200) != 0, true);
+
+//#endif
+            while (readBlocks > 0) {
+                readNow = (readBlocks > archive.getReadBufferBlocks())
+                          ? archive.getReadBufferBlocks()
+                          : readBlocks;
+
+                archive.readBlocks(readNow);
+
+                readBlocks -= readNow;
+
+                outStream.write(archive.readBuffer, 0, readNow * 512);
+            }
+
+            if (modulus != 0) {
+                archive.readBlock();
+                outStream.write(archive.readBuffer, 0, modulus);
+            }
+
+            outStream.flush();
+        } finally {
+            try {
+                outStream.close();
+            } finally {
+                outStream = null;  // Encourage buffer GC
+            }
+        }
+
+        newFile.setLastModified(header.getModTime() * 1000);
+
+        if (newFile.length() != header.getDataSize()) {
+            throw new IOException(RB.write_count_mismatch.getString(
+                    Long.toString(header.getDataSize()),
+                    newFile.getAbsolutePath(),
+                    Long.toString(newFile.length())));
+        }
+    }
+
+    protected void skipFileData(TarEntryHeader header)
+    throws IOException, TarMalformatException {
+
+        /*
+         * Some entry types which we don't support have 0 data size.
+         * If we just return here, the entry will just be skipped./
+        */
+        if (header.getDataSize() == 0) {
+            return;
+        }
+
+        if (header.getDataSize() < 0) {
+            throw new TarMalformatException(RB.data_size_unknown.getString());
+        }
+
+        int skipNow;
+        int oddBlocks  = (header.getDataSize() % 512L == 0L) ? 0
+                                                             : 1;
+        int skipBlocks = (int) (header.getDataSize() / 512L) + oddBlocks;
+
+        while (skipBlocks > 0) {
+            skipNow = (skipBlocks > archive.getReadBufferBlocks())
+                      ? archive.getReadBufferBlocks()
+                      : skipBlocks;
+
+            archive.readBlocks(skipNow);
+
+            skipBlocks -= skipNow;
+        }
+    }
+
+    /**
+     * A Tar entry header constituted from a header block in a tar file.
+     *
+     * @author Blaine Simpson (blaine dot simpson at admc dot com)
+     */
+    @SuppressWarnings("serial")
+    static protected class TarEntryHeader {
+
+        static protected class MissingField extends Exception {
+
+            private TarHeaderField field;
+
+            public MissingField(TarHeaderField field) {
+                this.field = field;
+            }
+
+            public String getMessage() {
+                return RB.header_field_missing.getString(field.toString());
+            }
+        }
+
+        protected SimpleDateFormat sdf =
+            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+
+        /**
+         * @param rawHeader  May be longer than 512 bytes, but the first 512
+         *                   bytes MUST COMPRISE a raw tar entry header.
+         */
+        public TarEntryHeader(byte[] rawHeader) throws TarMalformatException {
+
+            this.rawHeader = rawHeader;
+
+            Long expectedCheckSum = readInteger(TarHeaderField.checksum);
+
+            try {
+                if (expectedCheckSum == null) {
+                    throw new MissingField(TarHeaderField.checksum);
+                }
+
+                long calculatedCheckSum = headerChecksum();
+
+                if (expectedCheckSum.longValue() != calculatedCheckSum) {
+                    throw new TarMalformatException(
+                            RB.checksum_mismatch.getString(
+                            expectedCheckSum.toString(),
+                            Long.toString(calculatedCheckSum)));
+                }
+
+                path = readString(TarHeaderField.name);
+
+                if (path == null) {
+                    throw new MissingField(TarHeaderField.name);
+                }
+
+                Long longObject = readInteger(TarHeaderField.mode);
+
+                if (longObject == null) {
+                    throw new MissingField(TarHeaderField.mode);
+                }
+
+                fileMode   = (int) longObject.longValue();
+                longObject = readInteger(TarHeaderField.size);
+
+                if (longObject != null) {
+                    dataSize = longObject.longValue();
+                }
+
+                longObject = readInteger(TarHeaderField.mtime);
+
+                if (longObject == null) {
+                    throw new MissingField(TarHeaderField.mtime);
+                }
+
+                modTime = longObject.longValue();
+            } catch (MissingField mf) {
+                throw new TarMalformatException(mf.getMessage());
+            }
+
+            entryType = readChar(TarHeaderField.typeflag);
+            ownerName = readString(TarHeaderField.uname);
+
+            String pathPrefix = readString(TarHeaderField.prefix);
+
+            if (pathPrefix != null) {
+                path = pathPrefix + '/' + path;
+            }
+
+            // We're not loading the "gname" field, since there is nothing at
+            // all that Java can do with it.
+            ustar = isUstar();
+        }
+
+        protected byte[] rawHeader;
+        /* CRITICALLY IMPORTANT:  TO NOT USE rawHeader.length OR DEPEND ON
+         * THE LENGTH OF the rawHeader ARRAY!  Use only the first 512 bytes!
+         */
+        protected String  path;
+        protected int     fileMode;
+        protected long    dataSize = -1;    // In bytes
+        protected long    modTime;
+        protected char    entryType;
+        protected String  ownerName;
+        protected boolean ustar;
+
+        /**
+         * @return a new Absolutized File object generated from this
+         * TarEntryHeader.
+         */
+        public File generateFile() {
+
+            if (entryType != '\0' && entryType != '0') {
+                throw new IllegalStateException(
+                        RB.create_only_normal.getString());
+            }
+
+            // Unfortunately, it does no good to set modification times or
+            // privileges here, since those settings have no effect on our
+            // new file until after is created by the FileOutputStream
+            // constructor.
+            return new File(path);
+        }
+
+        public char getEntryType() {
+            return entryType;
+        }
+
+        public String getPath() {
+            return path;
+        }
+
+        /**
+         * Setter is needed in order to override header size setting for Pax.
+         */
+        public void setDataSize(long dataSize) {
+            this.dataSize = dataSize;
+        }
+
+        public long getDataSize() {
+            return dataSize;
+        }
+
+        public long getModTime() {
+            return modTime;
+        }
+
+        public int getFileMode() {
+            return fileMode;
+        }
+
+        /**
+         * Choosing not to report fields that we don't write (e.g. "gname"),
+         * but which would certainly be useful for a general Java tar client
+         * implementation.
+         * This design decision is subject to change.
+         */
+        public String toString() {
+
+            StringBuffer sb =
+                new StringBuffer(sdf.format(new Long(modTime * 1000L)) + ' ');
+
+            sb.append((entryType == '\0') ? ' '
+                                          : entryType);
+            sb.append(ustar ? '*'
+                            : ' ');
+            sb.append(
+                " "
+                + StringUtil.toPaddedString(
+                    Integer.toOctalString(fileMode), 4, ' ', false) + ' '
+                        + StringUtil.toPaddedString(
+                            Long.toString(dataSize), 11, ' ', false) + "  ");
+            sb.append(StringUtil.toPaddedString(((ownerName == null) ? "-"
+                                                                     : ownerName), 8,
+                                                                     ' ',
+                                                                     true));
+            sb.append("  " + path);
+
+            return sb.toString();
+        }
+
+        /**
+         * Is this any UStar variant
+         */
+        public boolean isUstar() throws TarMalformatException {
+
+            String magicString = readString(TarHeaderField.magic);
+
+            return magicString != null && magicString.startsWith("ustar");
+        }
+
+        /**
+         * @return index based at 0 == from
+         */
+        static public int indexOf(byte[] ba, byte val, int from, int to) {
+
+            for (int i = from; i < to; i++) {
+                if (ba[i] == val) {
+                    return i - from;
+                }
+            }
+
+            return -1;
+        }
+
+        protected char readChar(TarHeaderField field) throws TarMalformatException {
+
+            /* Depends on readString(int) contract that it will never return
+             * a 0-length String */
+            String s = readString(field);
+
+            return (s == null) ? '\0'
+                               : s.charAt(0);
+        }
+
+        /**
+         * @return null or String with length() > 0.
+         */
+        protected String readString(TarHeaderField field) throws TarMalformatException {
+
+            int start = field.getStart();
+            int stop  = field.getStop();
+            int termIndex = TarEntryHeader.indexOf(rawHeader, (byte) 0, start,
+                                                   stop);
+
+            switch (termIndex) {
+
+                case 0 :
+                    return null;
+
+                case -1 :
+                    termIndex = stop - start;
+                    break;
+            }
+
+            try {
+                return new String(rawHeader, start, termIndex);
+            } catch (Throwable t) {
+
+                // Java API does not specify behavior if decoding fails.
+                throw new TarMalformatException(
+                        RB.bad_header_value.getString(field.toString()));
+            }
+        }
+
+        /**
+         * Integer as in positive whole number, which does not imply Java
+         * types of <CODE>int</CODE> or <CODE>Integer</CODE>.
+         */
+        protected Long readInteger(TarHeaderField field)
+                throws TarMalformatException {
+
+            String s = readString(field);
+
+            if (s == null) {
+                return null;
+            }
+
+            try {
+                return Long.valueOf(s, 8);
+            } catch (NumberFormatException nfe) {
+                throw new TarMalformatException(
+                        RB.bad_numeric_header_value.getString(
+                        field.toString(), nfe.getMessage()));
+            }
+        }
+
+        protected long headerChecksum() {
+
+            long sum = 0;
+
+            for (int i = 0; i < 512; i++) {
+                boolean isInRange =
+                    (i >= TarHeaderField.checksum.getStart()
+                     && i < TarHeaderField.checksum.getStop());
+
+                // We ignore current contents of the checksum field so that
+                // this method will continue to work right, even if we later
+                // recycle the header or RE-calculate a header.
+                sum += isInRange ? 32
+                                 : (255 & rawHeader[i]);
+            }
+
+            return sum;
+        }
+    }
+}
diff --git a/src/org/hsqldb/lib/tar/package.html b/src/org/hsqldb/lib/tar/package.html
new file mode 100644
index 0000000..80e0e6c
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/package.html
@@ -0,0 +1,8 @@
+<HTML>
+<BODY>
+  Contains the DbBackup class, for backing up HyperSQL databases, and support
+  classes for handling files in tar and pax format.
+  See <a href="../../../../../guide/deployment-chapt.html#deployment_backup-sect" target="guide">
+  the database backup section of the HyperSQL User Guide</a>
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/lib/tar/rb.properties b/src/org/hsqldb/lib/tar/rb.properties
new file mode 100644
index 0000000..1f39910
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb.properties
@@ -0,0 +1,97 @@
+# $Id: rb.properties 3375 2009-12-18 23:27:07Z unsaved $
+
+# Default Locale String resources for TarGenerator.
+
+# IMPORTANT:  Make sure to use ISO-8859-1 encoding for any extended characters,
+# both in this file (actually any .properties file) and all referenced text
+# files.
+
+# GENERAL .properties SYNTAX:
+#   White space AT END OF LINES IS SIGNIFICANT
+#   White space at beginning of lines is not
+#   \ at very end of line makes the following line a continuation line (with
+#     no implied newline in the value.
+#     (Combined with the previous 2 rules, this means that white space before
+#     this \ is significant, and whitespace at beginning of continutation lines
+#     is not).
+#   \n does not work as an escape.  Use unicode \u000a for line breaks instead.
+
+# This file is loaded by RefCapablePropertyResourceBundle, so if any
+# property here has no value set, the value MUST be set in a file
+# located at targenerator/PROPERTYNAME.text
+# Property keys MAY NOT CONTAIN UNDERSCORE.  Underscores in Enum constants
+# will automatically be transated to dots.
+
+# These tell RefCapablePropertyResourceBundle to look for text files:
+DbBackup.syntax=
+TarGenerator.syntax=
+TarReader.syntax=
+listing.format=
+
+# Traditional inline .properties values:
+DbBackup.syntaxerr=Syntax error.  Run the following for help:\u000a    \
+    java -cp path/to/hsqldb.jar %{1}
+pad.block.write=Padding archive with %{1} zero blocks
+cleanup.rmfail=Failed to remove possibly corrupt archive: %{1}
+unsupported.entry.present=\u000aArchive contains unsupported entry type(s).\u000a\
+    We only support types ' ', '0', 'x' (entry type is shown in first column).
+bpr.write=Will write at %{1} blocks-per-record
+stream.buffer.report=Buffered %{1} bytes from given InputStream into RAM
+write.queue.report=%{1} supplicants queued for writing...
+file.missing=Required file is missing:  %{1}
+modified.property='modified' DB property is '%{1}'
+file.disappeared='%{1}' disappeared after backup started
+file.changed='%{1}' changed after backup started
+file.appeared='%{1}' appeared after backup started
+pif.malformat=Line %{1} of PIF Data is malformatted:\u000a%{2}
+pif.malformat.size=PIF Data contains malformatted 'size' value:  %{1}
+zero.write=Refusing to write record with zero-length key or value
+pif.toobig=Total key + val lengths exceeds our total supported max of %{1}
+read.denied=User does not have privileges to read file: %{1}
+compression.unknown=Unexpected compression type: %{1}
+insufficient.read=Expected to read %{1} bytes, but could only read %{2}
+decompression.ranout=Ran out of decompressed bytes after reading %{1} out of %{2}
+move.work.file=Is somebody else writing to the same file?  \
+               If not, remove aborted work file:  %{1}
+cant.overwrite=You do not have privileges to overwrite '%{1}'
+cant.write.dir=You do not have privileges to write in directory '%{1}'
+no.parent.dir=No parent directory '%{1}'
+bad.block.write.len=Specified block is %{1} bytes long instead of 512
+illegal.block.boundary=Current file length %{1} is not an even 512-byte-block multiple
+workfile.delete.fail=Failed to delete work file '%{1}'
+unsupported.ext=%{1} only generates files with extensions \
+    '.tar', '.tgz.', or '.tar.gz':  %{2}
+dest.exists=Destination file already exists: %{1}
+parent.not.dir=Parent node of specified file is not a directory: %{1}
+cant.write.parent=Parent directory of specified file is not writable: {1}
+parent.create.fail=Failed to create parent directory for tar file: %{1}
+tar.field.toobig=Input too long for field %{1}:  %{2}
+missing.supp.path=Path required if existing component file not specified
+nonfile.entry=This method intentionally creates TarEntries only for files
+read.lt.1=Does not make sense to make an entry for < 1 byte
+data.changed=Seems that the input data changed.  Input data was %{1} bytes, \
+             but we wrote %{2} bytes of data
+unexpected.header.key=Unexpected Header key: %{1}
+tarreader.syntaxerr=Run 'java -cp path/to/hsqldb.jar %{1}' for help
+unsupported.mode=Sorry, mode not supported yet: %{1}
+dir.x.conflict=The '--directory=' switch only makes sense with 'x' mode
+pif.unknown.datasize=PIF Data size unknown
+pif.data.toobig=PIF Data exceeds max supported size.  %{1} > %{2}
+data.size.unknown=Data size unknown
+extraction.exists=Extracted file already exists: %{1}
+extraction.exists.notfile=Node already exist but is not a file: %{1}
+extraction.parent.not.dir=Parent node of extracted path is not a directory: %{1}
+extraction.parent.not.writable=Parent directory of extracted path is not \
+                               writable: %{1}
+extraction.parent.mkfail=Failed to create parent directory for extracted \
+                         file: %{1}
+write.count.mismatch=Attempted to write %{1} bytes to '%{2}', but only wrote %{3}
+header.field.missing=Required field '%{1}' missing in tar entry header.
+checksum.mismatch=Corrupted tar entry header.  Expected checksum %{1}, \
+                  but calculated %{2}
+create.only.normal=At this time, we only support creation of normal files \
+                   from Tar entries
+bad.header.value=Bad value in header for field %{1}
+bad.numeric.header.value=Bad value in header for field %{1}: %{2}.\u000a\
+    Header field could use 'binary number extension', which we don't \
+    support.\u000aUse Pax Interchange Format instead for huge files.
diff --git a/src/org/hsqldb/lib/tar/rb/DbBackup.syntax.text b/src/org/hsqldb/lib/tar/rb/DbBackup.syntax.text
new file mode 100644
index 0000000..b0e7d6e
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb/DbBackup.syntax.text
@@ -0,0 +1,16 @@
+SYNTAX:
+    java -cp path/to/hsqldb.jar %{1}
+    (to display this message)
+OR
+    java -cp path/to/hsqldb.jar %{1} --save  \
+    [--overwrite] tar/path.tar db/base/path
+OR
+    java -cp path/to/hsqldb.jar %{1} --list  \
+    tar/path.tar [regex1...]
+OR
+    java -cp path/to/hsqldb.jar %{1} --extract  \
+    [--overwrite] file/path.tar[.gz] db/dir [regex1...]
+    (extracts entry files to the specified db/dir).
+
+N.b. the db/base/path includes file base name, like in JDBC URLs, whereas
+db/dir is a proper 'directory'.
diff --git a/src/org/hsqldb/lib/tar/rb/DbBackup.syntax_de.text b/src/org/hsqldb/lib/tar/rb/DbBackup.syntax_de.text
new file mode 100644
index 0000000..72cbfea
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb/DbBackup.syntax_de.text
@@ -0,0 +1,19 @@
+SYNTAX:
+    java -cp Pfad/zur/hsqldb.jar %{1}
+    (um diese Meldung anzuzeigen)
+ODER
+    java -cp Pfad/zur/hsqldb.jar %{1} --save  \
+    [--overwrite] tar/Pfad.tar DB-Wurzel-Pfad
+ODER
+    java -cp Pfad/zur/hsqldb.jar %{1} --list  \
+    tar/Pfad.tar [regex1...]
+ODER
+    java -cp path/to/hsqldb.jar %{1} --extract  \
+    [--overwrite] Datei/Pfad.tar[.gz] DB/Verz. [regex1...]
+    (entpackt die enthaltenen Dateien in die angegebene DB/das angegebene Verzeichnis).
+
+Bitte beachten: 
+#N.b. the db/base/path includes file base name, like in JDBC URLs, whereas
+#db/dir is a proper 'directory'.
+Der DB-Wurzel-Pfad beinhaltet auch das Wurzelverzeichnis der Datei,
+wie bei JDBC-URLs, wo das DB/Verz. eine normales Verzeichnis ist.
diff --git a/src/org/hsqldb/lib/tar/rb/TarGenerator.syntax.text b/src/org/hsqldb/lib/tar/rb/TarGenerator.syntax.text
new file mode 100644
index 0000000..0fa01ed
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb/TarGenerator.syntax.text
@@ -0,0 +1,3 @@
+SYNTAX: java -cp %{1} new.tar [entryFile1...]
+If no entryFiles are specified, stdin will be read to write an entry with
+name 'stdin'.  In this latter case, input is limited to 10240 bytes.
diff --git a/src/org/hsqldb/lib/tar/rb/TarGenerator.syntax_de.text b/src/org/hsqldb/lib/tar/rb/TarGenerator.syntax_de.text
new file mode 100644
index 0000000..8902e2c
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb/TarGenerator.syntax_de.text
@@ -0,0 +1,3 @@
+SYNTAX: java -cp %{1} neu.tar [Dateieintrag1...]
+Wenn keine Dateien angegeben wurden, dann wird von stdin gelesen um einen Eintrag
+mit dem Namen 'stdin' zu speichern. Bei letzteren ist die Eingabegröße auf 10240 Bytes begrenzt.
diff --git a/src/org/hsqldb/lib/tar/rb/TarReader.syntax.text b/src/org/hsqldb/lib/tar/rb/TarReader.syntax.text
new file mode 100644
index 0000000..f106482
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb/TarReader.syntax.text
@@ -0,0 +1,7 @@
+SYNTAX: java -cp path/to/hsqldb.jar %{1} {t|x}  \
+        [--directory=path] file/path/tar[.gz] [regex1...]
+where
+    t:      Table-of-content mode (like "tar -t...")
+    x:      Extract mode (like "tar -x...")
+    path:   Base extraction directory for relative entries
+    regex*: Pattern(s) which narrow entries listed or extracted
diff --git a/src/org/hsqldb/lib/tar/rb/TarReader.syntax_de.text b/src/org/hsqldb/lib/tar/rb/TarReader.syntax_de.text
new file mode 100644
index 0000000..03dd1d0
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb/TarReader.syntax_de.text
@@ -0,0 +1,7 @@
+SYNTAX: java -cp Pfad/zur/hsqldb.jar %{1} {t|x}  \
+        [--directory=Pfad] Pfad/zur/Datei/tar[.gz] [regex1...]
+wobei
+    t:      Anzeigen einer Tabelle mit den Einträgen (wie "tar -t...")
+    x:      Entpacken-Modus (wie "tar -x...")
+    Pfad:   Basisverzeichnis zum Entpacken der relativen Archiveinträge
+    regex*: Muster, welche die darauf passenden Einträge auflistet oder entpackt
diff --git a/src/org/hsqldb/lib/tar/rb/listing.format.text b/src/org/hsqldb/lib/tar/rb/listing.format.text
new file mode 100644
index 0000000..484201e
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb/listing.format.text
@@ -0,0 +1,4 @@
+LISTING FORMAT:
+modification_time__ tu mode  file_size_  owner___  filepath
+    t = Tar entry type
+    u = '*' for UStar-compliant entry
diff --git a/src/org/hsqldb/lib/tar/rb/listing.format_de.text b/src/org/hsqldb/lib/tar/rb/listing.format_de.text
new file mode 100644
index 0000000..f4f99f5
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb/listing.format_de.text
@@ -0,0 +1,4 @@
+ANZEIGE FORMAT:
+Änderungszeit__ tu Modus  Dateigröße_  Besitzer___  Dateipfad
+    t = Tar entry type
+    u = '*' für UStar-kompatible entry
diff --git a/src/org/hsqldb/lib/tar/rb_de.properties b/src/org/hsqldb/lib/tar/rb_de.properties
new file mode 100644
index 0000000..cb2e7c5
--- /dev/null
+++ b/src/org/hsqldb/lib/tar/rb_de.properties
@@ -0,0 +1,95 @@
+# $Id: rb_de.properties 3375 2009-12-18 23:27:07Z unsaved $
+
+# Default Locale String resources for TarGenerator.
+
+# IMPORTANT:  Make sure to use ISO-8859-1 encoding for any extended characters,
+# both in this file (actually any .properties file) and all referenced text
+# files.
+
+# GENERAL .properties SYNTAX:
+#   White space AT END OF LINES IS SIGNIFICANT
+#   White space at beginning of lines is not
+#   \ at very end of line makes the following line a continuation line (with
+#     no implied newline in the value.
+#     (Combined with the previous 2 rules, this means that white space before
+#     this \ is significant, and whitespace at beginning of continutation lines
+#     is not).
+#   \n does not work as an escape.  Use unicode \u000a for line breaks instead.
+
+# This file is loaded by RefCapablePropertyResourceBundle, so if any
+# property here has no value set, the value MUST be set in a file
+# located at targenerator/PROPERTYNAME.text
+# Property keys MAY NOT CONTAIN UNDERSCORE.  Underscores in Enum constants
+# will automatically be transated to dots.
+
+# These tell RefCapablePropertyResourceBundle to look for text files:
+DbBackup.syntax=
+TarGenerator.syntax=
+TarReader.syntax=
+listing.format=
+
+# Traditional inline .properties values:
+DbBackup.syntaxerr=Syntax-Fehler.  Geben Sie für Hilfe folgendes ein:\u000a    \
+    java -cp pfad/zur/hsqldb.jar %{1}
+pad.block.write=Fülle das Archive mit %{1} Null-Blöcken auf.
+cleanup.rmfail=Fehler beim Löschen eines wahrscheinlich beschädigten Archives: %{1}
+unsupported.entry.present=\u000aDas Archive beinhaltet nicht unterstützte Typen von Einträgen.\u000a\
+    Wir unterstützen nur folgende Typen ' ', '0', 'x' (Eintragstyp wird in der ersten Spalte angezeigt).
+bpr.write=Schreibe %{1} Blöcke pro Datensatz.
+stream.buffer.report=Puffere %{1} Bytes aus dem Eingabestrom im Arbeitsspeicher.
+write.queue.report=%{1} Elemente zum Schreiben in der Warteschlange...
+file.missing=Benötigte Datei wird vermisst: %{1}
+modified.property='geänderte' DB-Einstellung ist '%{1}'
+file.disappeared='%{1}' verschwunden seit dem Start des Backup.
+file.changed='%{1}' verändert seit dem Start des Backup.
+file.appeared='%{1}' neue seit dem Start des Backup.
+pif.malformat=Zeile %{1} der PIF-Daten ist fehlerhaft:\u000a%{2}
+pif.malformat.size=PIF-Daten beinhalten einen fehlerhaften 'size'-Wert: %{1}
+zero.write=Das schreiben eines Datensatzes mit leerem Schlüssel (Key) oder Wert (value) wird verweigert.
+pif.toobig=Die Gesamtlänge von Schlüssel und Wert überschreitet das unterstützte Maximum von %{1}
+read.denied=Der Benutzer hat keine ausreichenden Rechte zum Lesen der Datei: %{1}
+compression.unknown=Unerwartetes Kompressionsverfahren: %{1}
+insufficient.read=Erwartete %{1} Bytes zum Lesen, konnte aber nur %{2} einlesen
+decompression.ranout=Dekomprimierte Bytes sind ausgegangen, nach dem dem Lesen von %{1} aus %{2} Bytes.
+move.work.file=Versucht jemand anderes in dieselbe Datei zu schreiben? \
+               Wenn nicht, löschen Sie bitte die Datei, bei der die Arbeit unterbrochen wurde:  %{1}
+cant.overwrite=Sie haben keine Rechte zum Überschreiben von '%{1}'
+cant.write.dir=Sie haben keine Rechte um in das Verzeichnis '%{1}' zu schreiben.
+no.parent.dir=Kein übergeordnetes Verzeichnis '%{1}'
+bad.block.write.len=Angegebener Block ist %{1} Bytes lang, statt 512
+illegal.block.boundary=Die Länge %{1} der aktuellen Datei ist kein genaues Vielfaches eines 512-Byte-Block.
+workfile.delete.fail=Fehler beim Löschen der Arbeitsdatei '%{1}'
+unsupported.ext=Erzeuge nur %{1} Dateien mit den Erweiterungen \
+    '.tar', '.tgz.', or '.tar.gz':  %{2}
+dest.exists=Zieldatei existiert bereits: %{1}
+parent.not.dir=Der übergeordnete Knotenpunkt der angegebenen Datei ist kein Verzeichnis: %{1}
+cant.write.parent=Das übergeordnete Verzeichnis der angegebenen Datei ist nicht beschreibbar: {1}
+parent.create.fail=Fehler beim Erstellen des übergeordneten Verzeichnises für die TAR-Datei: %{1}
+tar.field.toobig=Eingabe zu lang für das Feld %{1}:  %{2}
+missing.supp.path=Pfad wird benötigt, wenn dieser bei der Datei nicht angegeben wurde. 
+nonfile.entry=Diese Methode erzeugt absichtlich TAR-Einträge nur für Dateien.
+read.lt.1=Es macht keinen Sinn einen Eintrag zu erzeugen, für weniger als einen Byte.
+data.changed=Scheint das sich die Eingabedaten geändert haben. Eingabedaten bestanden aus %{1} Bytes, \
+             geschrieben wurden aber Daten mit %{2} Bytes.
+unexpected.header.key=Unerwarteter Kopfschlüssel (Header key): %{1}
+tarreader.syntaxerr=Geben Sie 'java -cp pfad/zur/hsqldb.jar %{1}' ein für die Hilfe
+unsupported.mode=Entschuldigung, dieser Modus wird noch nicht unterstützt: %{1}
+dir.x.conflict=Der Schalter '--directory=' macht nur in Verbindung mit dem 'x'-Modus Sinn
+pif.unknown.datasize=PIF-Datengröße ist unbekannt.
+pif.data.toobig=PIF-Daten überschreiben die maximal unterstützte Größe %{1} > %{2}
+data.size.unknown=Datengröße unbekannt
+extraction.exists=Entpackte Dateien existieren bereits: %{1}
+extraction.exists.notfile=Der Knotenpunkt (Node) existert bereits, er ist aber keine Datei: %{1}
+extraction.parent.not.dir=Der übergeordnete Knotenpunkt (Parent node) des entpackten Pfades ist kein Verzeichnis: %{1}
+extraction.parent.not.writable=Das übergeordnete Verzeichnis des entpackten Pfades ist nicht beschreibbar: %{1}
+extraction.parent.mkfail=Fehler beim erzeugen des übergeordneten Verzeichnises für die entpackten Dateien: %{1}
+write.count.mismatch=Versuchte %{1} Bytes nach '%{2}' zu schreiben, konnte aber nur %{3} schreiben
+header.field.missing=Vorgeschriebenes Feld '%{1}' fehlt im TAR-Kopfzeileneintrag (tar entry header).
+checksum.mismatch=Beschädigter TAR-Kopfzeileneintrag (tar entry header).  Erwartete Prüfsumme %{1}, \
+                  berechnete ist aber %{2}
+create.only.normal=Zu diesem Zeitpunkt unterstützen wir nur die Erzeugung normaler Dateien \
+                   aus TAR-Einträgen
+bad.header.value=Falscher Wert im Kopfzeilenfeld %{1}
+bad.numeric.header.value=Falscher Wert im Kopfzeilenfeld %{1}: %{2}.\u000a\
+    Kopfzeilenfeld kann 'binary number extension' verwenden, welche wir aber nicht unterstützen \
+    \u000aVerwenden Sie das Pax-Interchange-Format anstellen von sehr großen Dateien.
diff --git a/src/org/hsqldb/navigator/RangeIterator.java b/src/org/hsqldb/navigator/RangeIterator.java
new file mode 100644
index 0000000..8b44190
--- /dev/null
+++ b/src/org/hsqldb/navigator/RangeIterator.java
@@ -0,0 +1,63 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.navigator;
+
+import org.hsqldb.RangeVariable;
+import org.hsqldb.Row;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface RangeIterator extends RowIterator {
+
+    boolean isBeforeFirst();
+
+    boolean next();
+
+    Row getCurrentRow();
+
+    Object[] getCurrent();
+
+    void setCurrent(Object[] data);
+
+    Object getRowidObject();
+
+    void remove();
+
+    void reset();
+
+    int getRangePosition();
+
+    RangeVariable getRange();
+}
diff --git a/src/org/hsqldb/navigator/RowIterator.java b/src/org/hsqldb/navigator/RowIterator.java
new file mode 100644
index 0000000..2cfafc3
--- /dev/null
+++ b/src/org/hsqldb/navigator/RowIterator.java
@@ -0,0 +1,57 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.navigator;
+
+import org.hsqldb.Row;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public interface RowIterator {
+
+    Row getNextRow();
+
+    Object[] getNext();
+
+    boolean hasNext();
+
+    void remove();
+
+    boolean setRowColumns(boolean[] columns);
+
+    void release();
+
+    long getRowId();
+}
diff --git a/src/org/hsqldb/navigator/RowSetNavigator.java b/src/org/hsqldb/navigator/RowSetNavigator.java
new file mode 100644
index 0000000..5ed5309
--- /dev/null
+++ b/src/org/hsqldb/navigator/RowSetNavigator.java
@@ -0,0 +1,332 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.navigator;
+
+import java.io.IOException;
+
+import org.hsqldb.RangeVariable;
+import org.hsqldb.Row;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/**
+ * Encapsulates navigation functionality for lists of objects. The base class
+ * provides positional navigation and checking, while the subclasses provide
+ * object retreival.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public abstract class RowSetNavigator implements RangeIterator {
+
+    public RowSetNavigator() {}
+
+    SessionInterface session;
+    long             id;
+    int              size;
+    int              mode;
+    boolean          isIterator;
+    int              currentPos = -1;
+    int              rangePosition;
+
+    /**
+     * Sets the id;
+     */
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    /**
+     * Returns the id
+     */
+    public long getId() {
+        return id;
+    }
+
+    /**
+     * Returns the current row object. Type of object is implementation defined.
+     */
+    public abstract Object[] getCurrent();
+
+    public void setCurrent(Object[] data) {}
+
+    public long getRowid() {
+        return 0;
+    }
+
+    public Object getRowidObject() {
+        return null;
+    }
+
+    public abstract Row getCurrentRow();
+
+    /**
+     * Add data to the end
+     */
+    public abstract void add(Object[] data);
+
+    /**
+     * Add row to the end
+     */
+    public abstract boolean addRow(Row row);
+
+    /**
+     * Remove current row
+     */
+    public abstract void remove();
+
+    /**
+     * Clear all rows
+     */
+    public abstract void clear();
+
+    /**
+     * Reset to initial state
+     */
+    public void reset() {
+        currentPos = -1;
+    }
+
+    /**
+     * Remove any resourses and invalidate
+     */
+    public void release() {
+        reset();
+    }
+
+    public void setSession(SessionInterface session) {
+        this.session = session;
+    }
+
+    public SessionInterface getSession() {
+        return session;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public boolean isEmpty() {
+        return size == 0;
+    }
+
+    public Object[] getNext() {
+        return next() ? getCurrent()
+                      : null;
+    }
+
+    public boolean next() {
+
+        if (hasNext()) {
+            currentPos++;
+
+            return true;
+        } else if (size != 0) {
+            currentPos = size;
+        }
+
+        return false;
+    }
+
+    public boolean hasNext() {
+        return currentPos < size - 1;
+    }
+
+    public Row getNextRow() {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigator");
+    }
+
+    public boolean setRowColumns(boolean[] columns) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigator");
+    }
+
+    public long getRowId() {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigator");
+    }
+
+    public boolean beforeFirst() {
+
+        reset();
+
+        currentPos = -1;
+
+        return true;
+    }
+
+    public boolean afterLast() {
+
+        if (size == 0) {
+            return false;
+        }
+
+        reset();
+
+        currentPos = size;
+
+        return true;
+    }
+
+    public boolean first() {
+
+        beforeFirst();
+
+        return next();
+    }
+
+    public boolean last() {
+
+        if (size == 0) {
+            return false;
+        }
+
+        if (isAfterLast()) {
+            beforeFirst();
+        }
+
+        while (hasNext()) {
+            next();
+        }
+
+        return true;
+    }
+
+    public int getRowNumber() {
+        return currentPos;
+    }
+
+    /**
+     * Uses similar semantics to java.sql.ResultSet except this is 0 based.
+     * When position is 0 or positive, it is from the start; when negative,
+     * it is from end
+     */
+    public boolean absolute(int position) {
+
+        if (position < 0) {
+            position += size;
+        }
+
+        if (position < 0) {
+            beforeFirst();
+
+            return false;
+        }
+
+        if (position >= size) {
+            afterLast();
+
+            return false;
+        }
+
+        if (size == 0) {
+            return false;
+        }
+
+        if (position < currentPos) {
+            beforeFirst();
+        }
+
+        // go to the tagget row;
+        while (position > currentPos) {
+            next();
+        }
+
+        return true;
+    }
+
+    public boolean relative(int rows) {
+
+        int position = currentPos + rows;
+
+        if (position < 0) {
+            beforeFirst();
+
+            return false;
+        }
+
+        return absolute(position);
+    }
+
+    public boolean previous() {
+        return relative(-1);
+    }
+
+    public boolean isFirst() {
+        return size > 0 && currentPos == 0;
+    }
+
+    public boolean isLast() {
+        return size > 0 && currentPos == size - 1;
+    }
+
+    public boolean isBeforeFirst() {
+        return size > 0 && currentPos == -1;
+    }
+
+    public boolean isAfterLast() {
+        return size > 0 && currentPos == size;
+    }
+
+    public void close() {}
+
+    public void writeSimple(RowOutputInterface out,
+                            ResultMetaData meta) throws IOException {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigator");
+    }
+
+    public void readSimple(RowInputInterface in,
+                           ResultMetaData meta) throws IOException {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigator");
+    }
+
+    public abstract void write(RowOutputInterface out,
+                               ResultMetaData meta) throws IOException;
+
+    public abstract void read(RowInputInterface in,
+                              ResultMetaData meta) throws IOException;
+
+    public boolean isMemory() {
+        return true;
+    }
+
+    public int getRangePosition() {
+        return rangePosition;
+    }
+
+    public RangeVariable getRange() {
+        return null;
+    }
+}
diff --git a/src/org/hsqldb/navigator/RowSetNavigatorClient.java b/src/org/hsqldb/navigator/RowSetNavigatorClient.java
new file mode 100644
index 0000000..a70ee83
--- /dev/null
+++ b/src/org/hsqldb/navigator/RowSetNavigatorClient.java
@@ -0,0 +1,279 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.navigator;
+
+import java.io.IOException;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.Row;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/*
+ * All-in-memory implementation of RowSetNavigator for client side, or for
+ * transferring a slice of the result to the client or server using a subset of
+ * a server-side row set.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowSetNavigatorClient extends RowSetNavigator {
+
+    public static final Object[][] emptyTable = new Object[0][];
+
+    //
+    int currentOffset;
+    int baseBlockSize;
+
+    //
+    Object[][] table;
+
+    //
+    public RowSetNavigatorClient() {
+        table = emptyTable;
+    }
+
+    public RowSetNavigatorClient(int blockSize) {
+        table = new Object[blockSize][];
+    }
+
+    public RowSetNavigatorClient(RowSetNavigator source, int offset,
+                                 int blockSize) {
+
+        this.size          = source.size;
+        this.baseBlockSize = blockSize;
+        this.currentOffset = offset;
+        table              = new Object[blockSize][];
+
+        source.absolute(offset);
+
+        for (int count = 0; count < blockSize; count++) {
+            table[count] = source.getCurrent();
+
+            source.next();
+        }
+
+        source.beforeFirst();
+    }
+
+    /**
+     * For communication of small resuls such as BATCHEXECRESPONSE
+     */
+    public void setData(Object[][] table) {
+        this.table = table;
+        this.size  = table.length;
+    }
+
+    public void setData(int index, Object[] data) {
+        table[index] = data;
+    }
+
+    public Object[] getData(int index) {
+        return table[index];
+    }
+
+    /**
+     * Returns the current row object. Type of object is implementation defined.
+     */
+    public Object[] getCurrent() {
+
+        if (currentPos < 0 || currentPos >= size) {
+            return null;
+        }
+
+        if (currentPos == currentOffset + table.length) {
+            getBlock(currentOffset + table.length);
+        }
+
+        return table[currentPos - currentOffset];
+    }
+
+    public Row getCurrentRow() {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigatorClient");
+    }
+
+    public void remove() {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigatorClient");
+    }
+
+    public void add(Object[] data) {
+
+        ensureCapacity();
+
+        table[size] = data;
+
+        size++;
+    }
+
+    public boolean addRow(Row row) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigatorClient");
+    }
+
+    public void clear() {
+        setData(emptyTable);
+        reset();
+    }
+
+    public boolean absolute(int position) {
+
+        if (position < 0) {
+            position += size;
+        }
+
+        if (position < 0) {
+            beforeFirst();
+
+            return false;
+        }
+
+        if (position >= size) {
+            afterLast();
+
+            return false;
+        }
+
+        if (size == 0) {
+            return false;
+        }
+
+        currentPos = position;
+
+        return true;
+    }
+
+    public void close() {
+
+        if (session != null) {
+            if (currentOffset == 0 && table.length == size) {}
+            else {
+                session.closeNavigator(id);
+            }
+        }
+    }
+
+    public void readSimple(RowInputInterface in,
+                           ResultMetaData meta) throws IOException {
+
+        size = in.readInt();
+
+        if (table.length < size) {
+            table = new Object[size][];
+        }
+
+        for (int i = 0; i < size; i++) {
+            table[i] = in.readData(meta.columnTypes);
+        }
+    }
+
+    public void writeSimple(RowOutputInterface out,
+                            ResultMetaData meta) throws IOException {
+
+        out.writeInt(size);
+
+        for (int i = 0; i < size; i++) {
+            Object[] data = table[i];
+
+            out.writeData(meta.getColumnCount(), meta.columnTypes, data, null,
+                          null);
+        }
+    }
+
+    public void read(RowInputInterface in,
+                     ResultMetaData meta) throws IOException {
+
+        id            = in.readLong();
+        size          = in.readInt();
+        currentOffset = in.readInt();
+        baseBlockSize = in.readInt();
+
+        if (table.length < baseBlockSize) {
+            table = new Object[baseBlockSize][];
+        }
+
+        for (int i = 0; i < baseBlockSize; i++) {
+            table[i] = in.readData(meta.columnTypes);
+        }
+    }
+
+    public void write(RowOutputInterface out,
+                      ResultMetaData meta) throws HsqlException, IOException {
+
+        int limit = size - currentOffset;
+
+        if (limit > table.length) {
+            limit = table.length;
+        }
+
+        out.writeLong(id);
+        out.writeInt(size);
+        out.writeInt(currentOffset);
+        out.writeInt(limit);
+
+        for (int i = 0; i < limit; i++) {
+            Object[] data = table[i];
+
+            out.writeData(meta.getColumnCount(), meta.columnTypes, data, null,
+                          null);
+        }
+    }
+
+    /**
+     * baseBlockSize remains unchanged.
+     */
+    void getBlock(int offset) {
+
+        try {
+            RowSetNavigatorClient source = session.getRows(id, offset,
+                baseBlockSize);
+
+            table         = source.table;
+            currentOffset = source.currentOffset;
+        } catch (HsqlException e) {}
+    }
+
+    private void ensureCapacity() {
+
+        if (size == table.length) {
+            int        newSize  = size == 0 ? 4
+                                            : size * 2;
+            Object[][] newTable = new Object[newSize][];
+
+            System.arraycopy(table, 0, newTable, 0, size);
+
+            table = newTable;
+        }
+    }
+}
diff --git a/src/org/hsqldb/navigator/RowSetNavigatorData.java b/src/org/hsqldb/navigator/RowSetNavigatorData.java
new file mode 100644
index 0000000..4066bc3
--- /dev/null
+++ b/src/org/hsqldb/navigator/RowSetNavigatorData.java
@@ -0,0 +1,667 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.navigator;
+
+import java.io.IOException;
+import java.util.Comparator;
+import java.util.TreeMap;
+
+import org.hsqldb.QueryExpression;
+import org.hsqldb.QuerySpecification;
+import org.hsqldb.Row;
+import org.hsqldb.Session;
+import org.hsqldb.SortAndSlice;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArraySort;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.LongKeyHashMap;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/**
+ * Implementation of RowSetNavigator for result sets.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowSetNavigatorData extends RowSetNavigator
+implements Comparator {
+
+    public static final Object[][] emptyTable = new Object[0][];
+
+    //
+    int currentOffset;
+    int baseBlockSize;
+
+    //
+    Object[][] table = emptyTable;
+
+    //
+    final Session   session;
+    QueryExpression queryExpression;
+    int             visibleColumnCount;
+    boolean         isSimpleAggregate;
+    Object[]        simpleAggregateData;
+
+    //
+    //
+    private Index mainIndex;
+
+    //
+    TreeMap        rowMap;
+    LongKeyHashMap idMap;
+
+    RowSetNavigatorData(Session session) {
+        this.session = session;
+    }
+
+    public RowSetNavigatorData(Session session, QuerySpecification select) {
+
+        this.session       = session;
+        this.queryExpression = select;
+        this.rangePosition = select.resultRangePosition;
+        visibleColumnCount = select.getColumnCount();
+        isSimpleAggregate  = select.isAggregated && !select.isGrouped;
+
+        if (select.isGrouped) {
+            mainIndex = select.groupIndex;
+            rowMap    = new TreeMap(this);
+        }
+
+        if (select.idIndex != null) {
+            idMap = new LongKeyHashMap();
+        }
+    }
+
+    public RowSetNavigatorData(Session session,
+                               QueryExpression queryExpression) {
+        this.session       = session;
+        this.queryExpression = queryExpression;
+        visibleColumnCount = queryExpression.getColumnCount();
+    }
+
+    public void sortFull() {
+
+        mainIndex = queryExpression.fullIndex;
+
+        ArraySort.sort(table, 0, size, this);
+        reset();
+    }
+
+    public void sortOrder() {
+
+        if (queryExpression.orderIndex != null) {
+            mainIndex = queryExpression.orderIndex;
+
+            ArraySort.sort(table, 0, size, this);
+        }
+
+        reset();
+    }
+
+    public void sortUnion(SortAndSlice sortAndSlice) {
+
+        if (sortAndSlice.index != null) {
+            mainIndex = sortAndSlice.index;
+
+            ArraySort.sort(table, 0, size, this);
+            reset();
+        }
+    }
+
+    public void add(Object[] data) {
+
+        ensureCapacity();
+
+        table[size] = data;
+
+        size++;
+
+        if (rowMap != null) {
+            rowMap.put(data, data);
+        }
+
+        if (idMap != null) {
+            Long id = (Long) data[visibleColumnCount];
+
+            idMap.put(id.longValue(), data);
+        }
+    }
+
+    public boolean addRow(Row row) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigatorClient");
+    }
+
+    public void update(Object[] oldData, Object[] newData) {
+        // noop
+    }
+
+    void addAdjusted(Object[] data, int[] columnMap) {
+
+        data = projectData(data, columnMap);
+
+        add(data);
+    }
+
+    void insertAdjusted(Object[] data, int[] columnMap) {
+        projectData(data, columnMap);
+        insert(data);
+    }
+
+    Object[] projectData(Object[] data, int[] columnMap) {
+
+        if (columnMap == null) {
+            data = (Object[]) ArrayUtil.resizeArrayIfDifferent(data,
+                    visibleColumnCount);
+        } else {
+            Object[] newData = new Object[visibleColumnCount];
+
+            ArrayUtil.projectRow(data, columnMap, newData);
+
+            data = newData;
+        }
+
+        return data;
+    }
+
+    /**
+     * for union only
+     */
+    void insert(Object[] data) {
+
+        ensureCapacity();
+        System.arraycopy(table, currentPos, table, currentPos + 1,
+                         size - currentPos);
+
+        table[currentPos] = data;
+
+        size++;
+    }
+
+    public void clear() {
+        this.table = emptyTable;
+        this.size  = table.length;
+        reset();
+    }
+
+    public boolean absolute(int position) {
+        return super.absolute(position);
+    }
+
+    public Object[] getCurrent() {
+
+        if (currentPos < 0 || currentPos >= size) {
+            return null;
+        }
+
+        if (currentPos == currentOffset + table.length) {
+            getBlock(currentOffset + table.length);
+        }
+
+        return table[currentPos - currentOffset];
+    }
+
+    public Row getCurrentRow() {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigatorClient");
+    }
+
+    public Object[] getNextRowData() {
+        return next() ? getCurrent()
+                      : null;
+    }
+
+    public boolean next() {
+        return super.next();
+    }
+
+    public void remove() {
+
+        System.arraycopy(table, currentPos + 1, table, currentPos,
+                         size - currentPos - 1);
+
+        table[size - 1] = null;
+
+        currentPos--;
+        size--;
+    }
+
+    public void reset() {
+        super.reset();
+    }
+
+    public void close() {
+        super.close();
+    }
+
+    public boolean isMemory() {
+        return true;
+    }
+
+    public void read(RowInputInterface in,
+                     ResultMetaData meta) throws IOException {}
+
+    public void write(RowOutputInterface out,
+                      ResultMetaData meta) throws IOException {
+
+        reset();
+        out.writeLong(id);
+        out.writeInt(size);
+        out.writeInt(0);    // offset
+        out.writeInt(size);
+
+        while (hasNext()) {
+            Object[] data = getNext();
+
+            out.writeData(meta.getExtendedColumnCount(), meta.columnTypes,
+                          data, null, null);
+        }
+
+        reset();
+    }
+
+    public Object[] getData(long rowId) {
+        return (Object[]) idMap.get(rowId);
+    }
+
+    public void copy(RowSetNavigatorData other, int[] rightColumnIndexes) {
+
+        while (other.hasNext()) {
+            Object[] currentData = other.getNext();
+
+            addAdjusted(currentData, rightColumnIndexes);
+        }
+
+        other.close();
+    }
+
+    public void union(RowSetNavigatorData other) {
+
+        Object[] currentData;
+
+        removeDuplicates();
+        other.removeDuplicates();
+
+        while (other.hasNext()) {
+            currentData = other.getNext();
+
+            int position = ArraySort.searchFirst(table, 0, size, currentData,
+                                                 this);
+
+            if (position < 0) {
+                position   = -position - 1;
+                currentPos = position;
+
+                insert(currentData);
+            }
+        }
+
+        other.close();
+        reset();
+    }
+
+    public void unionAll(RowSetNavigatorData other) {
+
+        other.reset();
+
+        while (other.hasNext()) {
+            Object[] currentData = other.getNext();
+
+            add(currentData);
+        }
+
+        other.close();
+        reset();
+    }
+
+    public void intersect(RowSetNavigatorData other) {
+
+        removeDuplicates();
+        other.sortFull();
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+            boolean  hasRow      = other.containsRow(currentData);
+
+            if (!hasRow) {
+                remove();
+            }
+        }
+
+        other.close();
+        reset();
+    }
+
+    public void intersectAll(RowSetNavigatorData other) {
+
+        Object[]    compareData = null;
+        RowIterator it;
+        Object[]    otherData = null;
+
+        sortFull();
+        other.sortFull();
+
+        it = queryExpression.fullIndex.emptyIterator();
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+            boolean newGroup =
+                compareData == null
+                || queryExpression.fullIndex.compareRowNonUnique(
+                    session, currentData, compareData,
+                    visibleColumnCount) != 0;
+
+            if (newGroup) {
+                compareData = currentData;
+                it          = other.findFirstRow(currentData);
+            }
+
+            otherData = it.getNext();
+
+            if (otherData != null
+                    && queryExpression.fullIndex.compareRowNonUnique(
+                        session, currentData, otherData,
+                        visibleColumnCount) == 0) {
+                continue;
+            }
+
+            remove();
+        }
+
+        other.close();
+        reset();
+    }
+
+    public void except(RowSetNavigatorData other) {
+
+        removeDuplicates();
+        other.sortFull();
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+            boolean  hasRow      = other.containsRow(currentData);
+
+            if (hasRow) {
+                remove();
+            }
+        }
+
+        other.close();
+        reset();
+    }
+
+    public void exceptAll(RowSetNavigatorData other) {
+
+        Object[]    compareData = null;
+        RowIterator it;
+        Object[]    otherData = null;
+
+        sortFull();
+        other.sortFull();
+
+        it = queryExpression.fullIndex.emptyIterator();
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+            boolean newGroup =
+                compareData == null
+                || queryExpression.fullIndex.compareRowNonUnique(
+                    session, currentData, compareData,
+                    queryExpression.fullIndex.getColumnCount()) != 0;
+
+            if (newGroup) {
+                compareData = currentData;
+                it          = other.findFirstRow(currentData);
+            }
+
+            otherData = it.getNext();
+
+            if (otherData != null
+                    && queryExpression.fullIndex.compareRowNonUnique(
+                        session, currentData, otherData,
+                        queryExpression.fullIndex.getColumnCount()) == 0) {
+                remove();
+            }
+        }
+
+        other.close();
+        reset();
+    }
+
+    public boolean hasUniqueNotNullRows() {
+
+        sortFull();
+        reset();
+
+        Object[] lastRowData = null;
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+
+            if (hasNull(currentData)) {
+                continue;
+            }
+
+            if (lastRowData != null
+                    && queryExpression.fullIndex.compareRow(
+                        session, lastRowData, currentData) == 0) {
+                return false;
+            } else {
+                lastRowData = currentData;
+            }
+        }
+
+        return true;
+    }
+
+    public void removeDuplicates() {
+
+        sortFull();
+        reset();
+
+        Object[] lastRowData = null;
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+
+            if (lastRowData != null
+                    && queryExpression.fullIndex.compareRow(
+                        session, lastRowData, currentData) == 0) {
+                remove();
+            } else {
+                lastRowData = currentData;
+            }
+        }
+
+        reset();
+    }
+
+    public void trim(int limitstart, int limitcount) {
+
+        if (size == 0) {
+            return;
+        }
+
+        if (limitstart >= size) {
+            clear();
+
+            return;
+        }
+
+        if (limitstart != 0) {
+            reset();
+
+            for (int i = 0; i < limitstart; i++) {
+                next();
+                remove();
+            }
+        }
+
+        if (limitcount == 0 || limitcount >= size) {
+            return;
+        }
+
+        reset();
+
+        for (int i = 0; i < limitcount; i++) {
+            next();
+        }
+
+        while (hasNext()) {
+            next();
+            remove();
+        }
+
+        reset();
+    }
+
+    boolean hasNull(Object[] data) {
+
+        for (int i = 0; i < visibleColumnCount; i++) {
+            if (data[i] == null) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Special case for isSimpleAggregate cannot use index lookup.
+     */
+    public Object[] getGroupData(Object[] data) {
+
+        if (isSimpleAggregate) {
+            if (simpleAggregateData == null) {
+                simpleAggregateData = data;
+
+                return null;
+            }
+
+            return simpleAggregateData;
+        }
+
+        return (Object[]) rowMap.get(data);
+    }
+
+    boolean containsRow(Object[] data) {
+
+        int position = ArraySort.searchFirst(table, 0, size, data, this);
+
+        return position >= 0;
+    }
+
+    RowIterator findFirstRow(Object[] data) {
+
+        int position = ArraySort.searchFirst(table, 0, size, data, this);
+
+        if (position < 0) {
+            position = size;
+        } else {
+            position--;
+        }
+
+        return new DataIterator(position);
+    }
+
+    /**
+     * baseBlockSize remains unchanged.
+     */
+    void getBlock(int offset) {
+
+        // no op for no blocks
+    }
+
+    private void ensureCapacity() {
+
+        if (size == table.length) {
+            int        newSize  = size == 0 ? 4
+                                            : size * 2;
+            Object[][] newTable = new Object[newSize][];
+
+            System.arraycopy(table, 0, newTable, 0, size);
+
+            table = newTable;
+        }
+    }
+
+    void implement() {
+        throw Error.error(ErrorCode.U_S0500, "RSND");
+    }
+
+    class DataIterator implements RowIterator {
+
+        int pos;
+
+        DataIterator(int position) {
+            pos = position;
+        }
+
+        public Row getNextRow() {
+            return null;
+        }
+
+        public Object[] getNext() {
+
+            if (hasNext()) {
+                pos++;
+
+                return table[pos];
+            }
+
+            return null;
+        }
+
+        public boolean hasNext() {
+            return pos < size - 1;
+        }
+
+        public void remove() {}
+
+        public boolean setRowColumns(boolean[] columns) {
+            return false;
+        }
+
+        public void release() {}
+
+        public long getRowId() {
+            return 0L;
+        }
+    }
+
+    public int compare(Object a, Object b) {
+        return mainIndex.compareRow(session, (Object[]) a, (Object[]) b);
+    }
+}
diff --git a/src/org/hsqldb/navigator/RowSetNavigatorDataChange.java b/src/org/hsqldb/navigator/RowSetNavigatorDataChange.java
new file mode 100644
index 0000000..ebc4c5a
--- /dev/null
+++ b/src/org/hsqldb/navigator/RowSetNavigatorDataChange.java
@@ -0,0 +1,224 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.navigator;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.hsqldb.Row;
+import org.hsqldb.Session;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.OrderedLongKeyHashMap;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+import org.hsqldb.types.Type;
+
+/*
+ * All-in-memory implementation of RowSetNavigator for delete and update
+ * operations.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+public class RowSetNavigatorDataChange extends RowSetNavigator {
+
+    OrderedLongKeyHashMap list;
+
+    public RowSetNavigatorDataChange() {
+        list = new OrderedLongKeyHashMap(8, true);
+    }
+
+    /**
+     * Returns the current row object.
+     */
+    public Object[] getCurrent() {
+        return getCurrentRow().getData();
+    }
+
+    public Row getCurrentRow() {
+        return (Row) list.getValueByIndex(super.currentPos);
+    }
+
+    public Object[] getCurrentChangedData() {
+        return (Object[]) list.getSecondValueByIndex(super.currentPos);
+    }
+
+    public int[] getCurrentChangedColumns() {
+        return (int[]) list.getThirdValueByIndex(super.currentPos);
+    }
+
+    public Row getNextRow() {
+        return next() ? getCurrentRow()
+                      : null;
+    }
+
+    public void remove() {
+        throw new NoSuchElementException();
+    }
+
+    public boolean next() {
+        return super.next();
+    }
+
+    public void reset() {
+        super.reset();
+    }
+
+    // reading and writing
+    public void write(RowOutputInterface out,
+                      ResultMetaData meta) throws IOException {
+
+        beforeFirst();
+        out.writeLong(id);
+        out.writeInt(size);
+        out.writeInt(0);    // offset
+        out.writeInt(size);
+
+        while (hasNext()) {
+            Object[] data = getNext();
+
+            out.writeData(meta.getColumnCount(), meta.columnTypes, data, null,
+                          null);
+        }
+
+        beforeFirst();
+    }
+
+    public void read(RowInputInterface in,
+                     ResultMetaData meta) throws IOException {
+
+        id = in.readLong();
+
+        int count = in.readInt();
+
+        in.readInt();    // offset
+        in.readInt();    // size again
+
+        while (count-- > 0) {
+            add(in.readData(meta.columnTypes));
+        }
+    }
+
+    public void clear() {
+
+        reset();
+        list.clear();
+
+        size = 0;
+    }
+
+    public void add(Object[] d) {
+        throw Error.runtimeError(ErrorCode.U_S0500,
+                                 "RowSetNavigatorDataChange");
+    }
+
+    public boolean addRow(Row row) {
+
+        int lookup = list.getLookup(row.getId());
+
+        if (lookup == -1) {
+            list.put(row.getId(), row, null);
+
+            size++;
+
+            return true;
+        } else {
+            if (list.getSecondValueByIndex(lookup) != null) {
+                throw Error.error(ErrorCode.X_27000);
+            }
+
+            return false;
+        }
+    }
+
+    public Object[] addRow(Session session, Row row, Object[] data,
+                           Type[] types, int[] columnMap) {
+
+        long rowId  = row.getId();
+        int  lookup = list.getLookup(rowId);
+
+        if (lookup == -1) {
+            list.put(rowId, row, data);
+            list.setThirdValueByIndex(size, columnMap);
+
+            size++;
+
+            return data;
+        } else {
+            Object[] rowData = ((Row) list.getFirstByLookup(lookup)).getData();
+            Object[] currentData =
+                (Object[]) list.getSecondValueByIndex(lookup);
+
+            if (currentData == null) {
+                throw Error.error(ErrorCode.X_27000);
+            }
+
+            for (int i = 0; i < columnMap.length; i++) {
+                int j = columnMap[i];
+
+                if (types[j].compare(session, data[j], currentData[j]) != 0) {
+                    if (types[j].compare(session, rowData[j], currentData[j])
+                            != 0) {
+                        throw Error.error(ErrorCode.X_27000);
+                    } else {
+                        currentData[j] = data[j];
+                    }
+                }
+            }
+
+            int[] currentMap = (int[]) list.getThirdValueByIndex(lookup);
+
+            currentMap = ArrayUtil.union(currentMap, columnMap);
+
+            list.setThirdValueByIndex(lookup, currentMap);
+
+            return currentData;
+        }
+    }
+
+    public boolean containsDeletedRow(Row row) {
+
+        int lookup = list.getLookup(row.getId());
+
+        if (lookup == -1) {
+            return false;
+        }
+
+        Object[] currentData = (Object[]) list.getSecondValueByIndex(lookup);
+
+        return currentData == null;
+    }
+}
diff --git a/src/org/hsqldb/navigator/RowSetNavigatorDataTable.java b/src/org/hsqldb/navigator/RowSetNavigatorDataTable.java
new file mode 100644
index 0000000..fce9bd7
--- /dev/null
+++ b/src/org/hsqldb/navigator/RowSetNavigatorDataTable.java
@@ -0,0 +1,620 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.navigator;
+
+import java.io.IOException;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.OpTypes;
+import org.hsqldb.QueryExpression;
+import org.hsqldb.QuerySpecification;
+import org.hsqldb.Row;
+import org.hsqldb.Session;
+import org.hsqldb.SortAndSlice;
+import org.hsqldb.TableBase;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.persist.PersistentStore;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/**
+ * Implementation of RowSetNavigator using a table as the data store.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowSetNavigatorDataTable extends RowSetNavigatorData {
+
+    final Session          session;
+    public TableBase       table;
+    public PersistentStore store;
+    RowIterator            iterator;
+    Row                    currentRow;
+    int                    maxMemoryRowCount;
+    boolean                isClosed;
+    int                    visibleColumnCount;
+    boolean                isAggregate;
+    boolean                isSimpleAggregate;
+    Object[]               simpleAggregateData;
+    Object[]               tempRowData;
+
+    //
+    boolean reindexTable;
+
+    //
+    private Index mainIndex;
+    private Index fullIndex;
+    private Index orderIndex;
+    private Index groupIndex;
+    private Index idIndex;
+
+    public RowSetNavigatorDataTable(Session session,
+                                    QuerySpecification select) {
+
+        super(session);
+
+        this.session       = session;
+        this.rangePosition = select.resultRangePosition;
+        maxMemoryRowCount  = session.getResultMemoryRowCount();
+        visibleColumnCount = select.indexLimitVisible;
+        table              = select.resultTable.duplicate();
+        table.store = store = session.sessionData.getNewResultRowStore(table,
+                !select.isAggregated);
+        isAggregate       = select.isAggregated;
+        isSimpleAggregate = select.isAggregated && !select.isGrouped;
+        reindexTable      = select.isGrouped;
+        mainIndex         = select.mainIndex;
+        fullIndex         = select.fullIndex;
+        orderIndex        = select.orderIndex;
+        groupIndex        = select.groupIndex;
+        idIndex           = select.idIndex;
+        tempRowData       = new Object[1];
+    }
+
+    public RowSetNavigatorDataTable(Session session,
+                                    QuerySpecification select,
+                                    RowSetNavigatorData navigator) {
+
+        this(session, (QuerySpecification) select);
+
+        navigator.reset();
+
+        while (navigator.hasNext()) {
+            add(navigator.getNext());
+        }
+    }
+
+    public RowSetNavigatorDataTable(Session session,
+                                    QueryExpression queryExpression) {
+
+        super(session);
+
+        this.session       = session;
+        maxMemoryRowCount  = session.getResultMemoryRowCount();
+        table              = queryExpression.resultTable.duplicate();
+        visibleColumnCount = table.getColumnCount();
+        table.store = store = session.sessionData.getNewResultRowStore(table,
+                true);
+        mainIndex = queryExpression.mainIndex;
+        fullIndex = queryExpression.fullIndex;
+    }
+
+    public RowSetNavigatorDataTable(Session session, TableBase table) {
+
+        super(session);
+
+        this.session       = session;
+        maxMemoryRowCount  = session.getResultMemoryRowCount();
+        this.table         = table;
+        visibleColumnCount = table.getColumnCount();
+        store              = session.sessionData.getRowStore(table);
+        mainIndex          = table.getPrimaryIndex();
+        fullIndex          = table.getFullIndex();
+        this.size          = mainIndex.size(null, store);
+
+        reset();
+    }
+
+    public void sortFull() {
+
+        if (reindexTable) {
+            store.indexRows();
+        }
+
+        mainIndex = fullIndex;
+
+        reset();
+    }
+
+    public void sortOrder() {
+
+        if (orderIndex != null) {
+            if (reindexTable) {
+                store.indexRows();
+            }
+
+            mainIndex = orderIndex;
+
+            reset();
+        }
+    }
+
+    public void sortUnion(SortAndSlice sortAndSlice) {
+
+        if (sortAndSlice.index != null) {
+            mainIndex = sortAndSlice.index;
+
+            reset();
+        }
+    }
+
+    public void add(Object[] data) {
+
+        try {
+            Row row = (Row) store.getNewCachedObject(session, data);
+
+            store.indexRow(null, row);
+
+            size++;
+        } catch (HsqlException e) {}
+    }
+
+    void addAdjusted(Object[] data, int[] columnMap) {
+
+        try {
+            if (columnMap == null) {
+                data = (Object[]) ArrayUtil.resizeArrayIfDifferent(data,
+                        visibleColumnCount);
+            } else {
+                Object[] newData = new Object[visibleColumnCount];
+
+                ArrayUtil.projectRow(data, columnMap, newData);
+
+                data = newData;
+            }
+
+            add(data);
+        } catch (HsqlException e) {}
+    }
+
+    public void update(Object[] oldData, Object[] newData) {
+
+        if (isSimpleAggregate) {
+            return;
+        }
+
+        RowIterator it = groupIndex.findFirstRow(session, store, oldData);
+
+        if (it.hasNext()) {
+            Row row = it.getNextRow();
+
+            it.remove();
+            it.release();
+
+            size--;
+
+            add(newData);
+        }
+    }
+
+    public void clear() {
+
+        table.clearAllData(store);
+
+        size = 0;
+
+        reset();
+    }
+
+    public boolean absolute(int position) {
+        return super.absolute(position);
+    }
+
+    public Object[] getCurrent() {
+        return currentRow.getData();
+    }
+
+    public Row getCurrentRow() {
+        return currentRow;
+    }
+
+    public boolean next() {
+
+        boolean result = super.next();
+
+        currentRow = iterator.getNextRow();
+
+        return result;
+    }
+
+    public void remove() {
+
+        if (currentRow != null) {
+            iterator.remove();
+
+            currentRow = null;
+
+            currentPos--;
+            size--;
+        }
+    }
+
+    public void reset() {
+
+        super.reset();
+
+        iterator = mainIndex.firstRow(store);
+    }
+
+    public void close() {
+
+        if (isClosed) {
+            return;
+        }
+
+        iterator.release();
+
+        isClosed = true;
+    }
+
+    public boolean isMemory() {
+        return store.isMemory();
+    }
+
+    public void read(RowInputInterface in,
+                     ResultMetaData meta) throws IOException {}
+
+    public void write(RowOutputInterface out,
+                      ResultMetaData meta) throws IOException {
+
+        reset();
+        out.writeLong(id);
+        out.writeInt(size);
+        out.writeInt(0);    // offset
+        out.writeInt(size);
+
+        while (hasNext()) {
+            Object[] data = getNext();
+
+            out.writeData(meta.getExtendedColumnCount(), meta.columnTypes,
+                          data, null, null);
+        }
+
+        reset();
+    }
+
+    public Object[] getData(Long rowId) {
+
+        tempRowData[0] = rowId;
+
+        RowIterator it = idIndex.findFirstRow(session, store, tempRowData,
+                                              idIndex.getDefaultColumnMap());
+
+        return it.getNext();
+    }
+
+    public void copy(RowSetNavigatorData other, int[] rightColumnIndexes) {
+
+        while (other.hasNext()) {
+            Object[] currentData = other.getNext();
+
+            addAdjusted(currentData, rightColumnIndexes);
+        }
+
+        other.close();
+    }
+
+    public void union(RowSetNavigatorData other) {
+
+        Object[] currentData;
+
+        removeDuplicates();
+        reset();
+
+        while (other.hasNext()) {
+            currentData = other.getNext();
+
+            RowIterator it = findFirstRow(currentData);
+
+            if (!it.hasNext()) {
+                currentData =
+                    (Object[]) ArrayUtil.resizeArrayIfDifferent(currentData,
+                        table.getColumnCount());
+
+                add(currentData);
+            }
+        }
+
+        other.close();
+    }
+
+    public void intersect(RowSetNavigatorData other) {
+
+        removeDuplicates();
+        reset();
+        other.sortFull();
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+            boolean  hasRow      = other.containsRow(currentData);
+
+            if (!hasRow) {
+                remove();
+            }
+        }
+
+        other.close();
+    }
+
+    public void intersectAll(RowSetNavigatorData other) {
+
+        Object[]    compareData = null;
+        RowIterator it;
+        Row         otherRow  = null;
+        Object[]    otherData = null;
+
+        sortFull();
+        reset();
+        other.sortFull();
+
+        it = fullIndex.emptyIterator();
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+            boolean newGroup =
+                compareData == null
+                || fullIndex.compareRowNonUnique(
+                    session, currentData, compareData,
+                    fullIndex.getColumnCount()) != 0;
+
+            if (newGroup) {
+                compareData = currentData;
+                it          = other.findFirstRow(currentData);
+            }
+
+            otherRow  = it.getNextRow();
+            otherData = otherRow == null ? null
+                                         : otherRow.getData();
+
+            if (otherData != null
+                    && fullIndex.compareRowNonUnique(
+                        session, currentData, otherData,
+                        fullIndex.getColumnCount()) == 0) {
+                continue;
+            }
+
+            remove();
+        }
+
+        other.close();
+    }
+
+    public void except(RowSetNavigatorData other) {
+
+        removeDuplicates();
+        reset();
+        other.sortFull();
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+            boolean  hasRow      = other.containsRow(currentData);
+
+            if (hasRow) {
+                remove();
+            }
+        }
+
+        other.close();
+    }
+
+    public void exceptAll(RowSetNavigatorData other) {
+
+        Object[]    compareData = null;
+        RowIterator it;
+        Row         otherRow  = null;
+        Object[]    otherData = null;
+
+        sortFull();
+        reset();
+        other.sortFull();
+
+        it = fullIndex.emptyIterator();
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+            boolean newGroup =
+                compareData == null
+                || fullIndex.compareRowNonUnique(
+                    session, currentData, compareData,
+                    fullIndex.getColumnCount()) != 0;
+
+            if (newGroup) {
+                compareData = currentData;
+                it          = other.findFirstRow(currentData);
+            }
+
+            otherRow  = it.getNextRow();
+            otherData = otherRow == null ? null
+                                         : otherRow.getData();
+
+            if (otherData != null
+                    && fullIndex.compareRowNonUnique(
+                        session, currentData, otherData,
+                        fullIndex.getColumnCount()) == 0) {
+                remove();
+            }
+        }
+
+        other.close();
+    }
+
+    public boolean hasUniqueNotNullRows() {
+
+        sortFull();
+        reset();
+
+        Object[] lastRowData = null;
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+
+            if (hasNull(currentData)) {
+                continue;
+            }
+
+            if (lastRowData != null
+                    && fullIndex.compareRow(session, lastRowData, currentData)
+                       == 0) {
+                return false;
+            } else {
+                lastRowData = currentData;
+            }
+        }
+
+        return true;
+    }
+
+    public void removeDuplicates() {
+
+        sortFull();
+        reset();
+
+        Object[] lastRowData = null;
+
+        while (hasNext()) {
+            Object[] currentData = getNext();
+
+            if (lastRowData != null
+                    && fullIndex.compareRow(session, lastRowData, currentData)
+                       == 0) {
+                remove();
+            } else {
+                lastRowData = currentData;
+            }
+        }
+    }
+
+    public void trim(int limitstart, int limitcount) {
+
+        if (size == 0) {
+            return;
+        }
+
+        if (limitstart >= size) {
+            clear();
+
+            return;
+        }
+
+        if (limitstart != 0) {
+            reset();
+
+            for (int i = 0; i < limitstart; i++) {
+                next();
+                remove();
+            }
+        }
+
+        if (limitcount == 0 || limitcount >= size) {
+            return;
+        }
+
+        reset();
+
+        for (int i = 0; i < limitcount; i++) {
+            next();
+        }
+
+        while (hasNext()) {
+            next();
+            remove();
+        }
+    }
+
+    boolean hasNull(Object[] data) {
+
+        for (int i = 0; i < visibleColumnCount; i++) {
+            if (data[i] == null) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Special case for isSimpleAggregate cannot use index lookup.
+     */
+    public Object[] getGroupData(Object[] data) {
+
+        if (isSimpleAggregate) {
+            if (simpleAggregateData == null) {
+                simpleAggregateData = data;
+
+                return null;
+            }
+
+            return simpleAggregateData;
+        }
+
+        RowIterator it = groupIndex.findFirstRow(session, store, data);
+
+        if (it.hasNext()) {
+            Row row = it.getNextRow();
+
+            if (isAggregate) {
+                row.setChanged();
+            }
+
+            return row.getData();
+        }
+
+        return null;
+    }
+
+    boolean containsRow(Object[] data) {
+
+        RowIterator it     = mainIndex.findFirstRow(session, store, data);
+        boolean     result = it.hasNext();
+
+        it.release();
+
+        return result;
+    }
+
+    RowIterator findFirstRow(Object[] data) {
+        return mainIndex.findFirstRow(session, store, data);
+    }
+}
diff --git a/src/org/hsqldb/navigator/RowSetNavigatorLinkedList.java b/src/org/hsqldb/navigator/RowSetNavigatorLinkedList.java
new file mode 100644
index 0000000..b910e43
--- /dev/null
+++ b/src/org/hsqldb/navigator/RowSetNavigatorLinkedList.java
@@ -0,0 +1,186 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.navigator;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.hsqldb.Row;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlLinkedList;
+import org.hsqldb.lib.HsqlLinkedList.Node;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/*
+ * All-in-memory implementation of RowSetNavigator for simple client or server
+ * side result sets. These are the result sets used for batch or other internal
+ * operations.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowSetNavigatorLinkedList extends RowSetNavigator {
+
+    HsqlLinkedList list;
+    final Node     root;
+    Node           previous;
+    Node           current;
+
+    public RowSetNavigatorLinkedList() {
+
+        list    = new HsqlLinkedList();
+        root    = list.getHeadNode();
+        current = root;
+    }
+
+    /**
+     * Returns the current row object.
+     */
+    public Object[] getCurrent() {
+        return ((Row) current.data).getData();
+    }
+
+    public Row getCurrentRow() {
+        return (Row) current.data;
+    }
+
+    public Row getNextRow() {
+        return next() ? (Row) current.data
+                      : null;
+    }
+
+    public void remove() {
+
+        // avoid consecutive removes without next()
+        if (previous == null) {
+            throw new NoSuchElementException();
+        }
+
+        if (currentPos < size && currentPos != -1) {
+            list.removeAfter(previous);
+
+            current = previous;
+
+            size--;
+            currentPos--;
+
+            return;
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public boolean next() {
+
+        boolean result = super.next();
+
+        if (result) {
+            previous = current;
+            current  = current.next;
+        }
+
+        return result;
+    }
+
+    public void reset() {
+
+        super.reset();
+
+        current  = root;
+        previous = null;
+    }
+
+    // reading and writing
+    public void write(RowOutputInterface out,
+                      ResultMetaData meta) throws IOException {
+
+        beforeFirst();
+        out.writeLong(id);
+        out.writeInt(size);
+        out.writeInt(0);    // offset
+        out.writeInt(size);
+
+        while (hasNext()) {
+            Object[] data = getNext();
+
+            out.writeData(meta.getColumnCount(), meta.columnTypes, data, null,
+                          null);
+        }
+
+        beforeFirst();
+    }
+
+    public void read(RowInputInterface in,
+                     ResultMetaData meta) throws IOException {
+
+        id = in.readLong();
+
+        int count = in.readInt();
+
+        in.readInt();    // offset
+        in.readInt();    // size again
+
+        while (count-- > 0) {
+            add(in.readData(meta.columnTypes));
+        }
+    }
+
+    public void clear() {
+
+        reset();
+        list.clear();
+
+        size = 0;
+    }
+
+    /**
+     *  Method declaration
+     *
+     * @param  d
+     */
+    public void add(Object[] d) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowSetNavigatorClient");
+    }
+
+    public boolean addRow(Row row) {
+
+        list.add(row);
+
+        size++;
+
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/package.html b/src/org/hsqldb/package.html
new file mode 100644
index 0000000..54ed175
--- /dev/null
+++ b/src/org/hsqldb/package.html
@@ -0,0 +1,7 @@
+<HTML>
+<BODY>
+  Contains basic HyperSQL engine classes.
+  See <a href="../../../guide/index.html" target="guide">
+  the HyperSQL User Guide for details about HyperSQL database </a>
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/persist/Cache.java b/src/org/hsqldb/persist/Cache.java
new file mode 100644
index 0000000..567d5f7
--- /dev/null
+++ b/src/org/hsqldb/persist/Cache.java
@@ -0,0 +1,373 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.util.Comparator;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.lib.ArraySort;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.StopWatch;
+import org.hsqldb.store.BaseHashMap;
+
+/**
+ * New implementation of row caching for CACHED tables.<p>
+ *
+ * Manages memory for the cache map and its contents based on least recently
+ * used clearup.<p>
+ * Also provides services for selecting rows to be saved and passing them
+ * to DataFileCache.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+public class Cache extends BaseHashMap {
+
+    final DataFileCache                  dataFileCache;
+    private int                          capacity;         // number of Rows
+    private long                         bytesCapacity;    // number of bytes
+    private final CachedObjectComparator rowComparator;
+
+//
+    private CachedObject[] rowTable;
+    long                   cacheBytesLength;
+
+    // for testing
+    StopWatch saveAllTimer = new StopWatch(false);
+    StopWatch sortTimer    = new StopWatch(false);
+    int       saveRowCount = 0;
+
+    Cache(DataFileCache dfc) {
+
+        super(dfc.capacity(), BaseHashMap.intKeyOrValue,
+              BaseHashMap.objectKeyOrValue, true);
+
+        maxCapacity      = dfc.capacity();
+        dataFileCache    = dfc;
+        capacity         = dfc.capacity();
+        bytesCapacity    = dfc.bytesCapacity();
+        rowComparator    = new CachedObjectComparator();
+        rowTable         = new CachedObject[capacity];
+        cacheBytesLength = 0;
+    }
+
+    /**
+     *  Structural initialisations take place here. This allows the Cache to
+     *  be resized while the database is in operation.
+     */
+    void init(int capacity, long bytesCapacity) {}
+
+    long getTotalCachedBlockSize() {
+        return cacheBytesLength;
+    }
+
+    /**
+     * Returns a row if in memory cache.
+     */
+    public synchronized CachedObject get(int pos) {
+
+        if (accessCount > ACCESS_MAX) {
+            updateAccessCounts();
+            resetAccessCount();
+            updateObjectAccessCounts();
+        }
+
+        int lookup = getLookup(pos);
+
+        if (lookup == -1) {
+            return null;
+        }
+
+        accessTable[lookup] = ++accessCount;
+
+        CachedObject object = (CachedObject) objectValueTable[lookup];
+
+        return object;
+    }
+
+    /**
+     * Adds a row to the cache.
+     */
+    synchronized void put(int key, CachedObject row) {
+
+        int storageSize = row.getStorageSize();
+
+        if (size() >= capacity
+                || storageSize + cacheBytesLength > bytesCapacity) {
+            cleanUp();
+        }
+
+        if (accessCount > ACCESS_MAX) {
+            updateAccessCounts();
+            resetAccessCount();
+            updateObjectAccessCounts();
+        }
+
+        super.addOrRemove(key, row, null, false);
+        row.setInMemory(true);
+
+        cacheBytesLength += storageSize;
+    }
+
+    /**
+     * Removes an object from memory cache. Does not release the file storage.
+     */
+    synchronized CachedObject release(int i) {
+
+        CachedObject r = (CachedObject) super.addOrRemove(i, null, null, true);
+
+        if (r == null) {
+            return null;
+        }
+
+        cacheBytesLength -= r.getStorageSize();
+
+        r.setInMemory(false);
+
+        return r;
+    }
+
+    /**
+     * Replace a row in the cache.
+     */
+    synchronized void replace(int key, CachedObject row) {
+
+        int lookup = super.getLookup(key);
+
+        super.objectValueTable[lookup] = row;
+    }
+
+    private void updateAccessCounts() {
+
+        CachedObject r;
+        int          count;
+
+        for (int i = 0; i < objectValueTable.length; i++) {
+            r = (CachedObject) objectValueTable[i];
+
+            if (r != null) {
+                count = r.getAccessCount();
+
+                if (count > accessTable[i]) {
+                    accessTable[i] = count;
+                }
+            }
+        }
+    }
+
+    private void updateObjectAccessCounts() {
+
+        CachedObject r;
+        int          count;
+
+        for (int i = 0; i < objectValueTable.length; i++) {
+            r = (CachedObject) objectValueTable[i];
+
+            if (r != null) {
+                count = accessTable[i];
+
+                r.updateAccessCount(count);
+            }
+        }
+    }
+
+    /**
+     * Reduces the number of rows held in this Cache object. <p>
+     *
+     * Cleanup is done by checking the accessCount of the Rows and removing
+     * the rows with the lowest access count.
+     *
+     * Index operations require that up to 5 recently accessed rows remain
+     * in the cache.
+     *
+     */
+    private synchronized void cleanUp() {
+
+        updateAccessCounts();
+
+        int                          removeCount = size() / 2;
+        int accessTarget = getAccessCountCeiling(removeCount, removeCount / 8);
+        BaseHashMap.BaseHashIterator it          = new BaseHashIterator();
+        int                          savecount   = 0;
+
+        for (; it.hasNext(); ) {
+            CachedObject row                = (CachedObject) it.next();
+            int          currentAccessCount = it.getAccessCount();
+
+            if (currentAccessCount <= accessTarget) {
+                synchronized (row) {
+                    if (row.isKeepInMemory()) {
+                        it.setAccessCount(accessTarget + 1);
+                    } else {
+                        row.setInMemory(false);
+
+                        if (row.hasChanged()) {
+                            rowTable[savecount++] = row;
+                        }
+
+                        it.remove();
+
+                        cacheBytesLength -= row.getStorageSize();
+
+                        removeCount--;
+                    }
+                }
+            }
+
+            if (savecount == rowTable.length) {
+                saveRows(savecount);
+
+                savecount = 0;
+            }
+        }
+
+        super.setAccessCountFloor(accessTarget);
+        saveRows(savecount);
+    }
+
+    synchronized void forceCleanUp() {
+
+        BaseHashMap.BaseHashIterator it = new BaseHashIterator();
+
+        for (; it.hasNext(); ) {
+            CachedObject row = (CachedObject) it.next();
+
+            synchronized (row) {
+                if (!row.isKeepInMemory()) {
+                    row.setInMemory(false);
+                    it.remove();
+
+                    cacheBytesLength -= row.getStorageSize();
+                }
+            }
+        }
+    }
+
+    private synchronized void saveRows(int count) {
+
+        if (count == 0) {
+            return;
+        }
+
+        rowComparator.setType(CachedObjectComparator.COMPARE_POSITION);
+        sortTimer.start();
+        ArraySort.sort(rowTable, 0, count, rowComparator);
+        sortTimer.stop();
+        saveAllTimer.start();
+        dataFileCache.saveRows(rowTable, 0, count);
+
+        saveRowCount += count;
+
+        /*
+                // not necessary if the full storage size of each object is written out
+                try {
+                    dataFile.file.seek(fileFreePosition);
+                } catch (IOException e){}
+        */
+        saveAllTimer.stop();
+    }
+
+    /**
+     * Writes out all modified cached Rows.
+     */
+    synchronized void saveAll() {
+
+        Iterator it        = new BaseHashIterator();
+        int      savecount = 0;
+
+        for (; it.hasNext(); ) {
+            if (savecount == rowTable.length) {
+                saveRows(savecount);
+
+                savecount = 0;
+            }
+
+            CachedObject r = (CachedObject) it.next();
+
+            if (r.hasChanged()) {
+                rowTable[savecount++] = r;
+            }
+        }
+
+        saveRows(savecount);
+
+        Error.printSystemOut(
+            saveAllTimer.elapsedTimeToMessage(
+                "Cache.saveRows() total row save time"));
+        Error.printSystemOut("Cache.saveRow() total row save count = "
+                             + saveRowCount);
+        Error.printSystemOut(
+            sortTimer.elapsedTimeToMessage("Cache.sort() total time"));
+    }
+
+    /**
+     * clears out the memory cache
+     */
+    synchronized public void clear() {
+
+        super.clear();
+
+        cacheBytesLength = 0;
+    }
+
+    static final class CachedObjectComparator implements Comparator {
+
+        static final int COMPARE_LAST_ACCESS = 0;
+        static final int COMPARE_POSITION    = 1;
+        static final int COMPARE_SIZE        = 2;
+        private int      compareType;
+
+        CachedObjectComparator() {}
+
+        void setType(int type) {
+            compareType = type;
+        }
+
+        public int compare(Object a, Object b) {
+
+            switch (compareType) {
+
+                case COMPARE_POSITION :
+                    return ((CachedObject) a).getPos()
+                           - ((CachedObject) b).getPos();
+
+                case COMPARE_SIZE :
+                    return ((CachedObject) a).getStorageSize()
+                           - ((CachedObject) b).getStorageSize();
+
+                default :
+                    return 0;
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/persist/CachedObject.java b/src/org/hsqldb/persist/CachedObject.java
new file mode 100644
index 0000000..9680aa6
--- /dev/null
+++ b/src/org/hsqldb/persist/CachedObject.java
@@ -0,0 +1,81 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.lib.IntLookup;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/**
+ * Interface for an object stored in the memory cache.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+public interface CachedObject {
+
+    CachedObject[] emptyArray = new CachedObject[]{};
+
+    boolean isMemory();
+
+    void updateAccessCount(int count);
+
+    int getAccessCount();
+
+    void setStorageSize(int size);
+
+    int getStorageSize();
+
+    int getPos();
+
+    void setPos(int pos);
+
+    boolean hasChanged();
+
+    boolean isKeepInMemory();
+
+    boolean keepInMemory(boolean keep);
+
+    boolean isInMemory();
+
+    void setInMemory(boolean in);
+
+    void restore();
+
+    void destroy();
+
+    int getRealSize(RowOutputInterface out);
+
+    void write(RowOutputInterface out);
+
+    void write(RowOutputInterface out, IntLookup lookup);
+}
diff --git a/src/org/hsqldb/persist/Crypto.java b/src/org/hsqldb/persist/Crypto.java
new file mode 100644
index 0000000..e05207e
--- /dev/null
+++ b/src/org/hsqldb/persist/Crypto.java
@@ -0,0 +1,202 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+
+public class Crypto {
+
+    SecretKeySpec key;
+    Cipher        outCipher;
+    Cipher        inCipher;
+
+    public Crypto(String keyString, String cipherName, String provider) {
+
+        try {
+            byte[] encodedKey =
+                StringConverter.hexStringToByteArray(keyString);
+
+            key       = new SecretKeySpec(encodedKey, cipherName);
+            outCipher = provider == null ? Cipher.getInstance(cipherName)
+                                         : Cipher.getInstance(cipherName,
+                                         provider);
+
+            outCipher.init(Cipher.ENCRYPT_MODE, key);
+
+            inCipher = provider == null ? Cipher.getInstance(cipherName)
+                                        : Cipher.getInstance(cipherName,
+                                        provider);
+
+            inCipher.init(Cipher.DECRYPT_MODE, key);
+
+            return;
+        } catch (NoSuchPaddingException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (NoSuchAlgorithmException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (InvalidKeyException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (NoSuchProviderException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        }
+    }
+
+    public synchronized InputStream getInputStream(InputStream in) {
+
+        if (inCipher == null) {
+            return in;
+        }
+
+        try {
+            inCipher.init(Cipher.DECRYPT_MODE, key);
+
+            return new CipherInputStream(in, inCipher);
+        } catch (java.security.InvalidKeyException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        }
+    }
+
+    public synchronized OutputStream getOutputStream(OutputStream out) {
+
+        if (outCipher == null) {
+            return out;
+        }
+
+        try {
+            outCipher.init(Cipher.ENCRYPT_MODE, key);
+
+            return new CipherOutputStream(out, outCipher);
+        } catch (java.security.InvalidKeyException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        }
+    }
+
+    public synchronized int decode(byte[] source, int sourceOffset,
+                                   int length, byte[] dest, int destOffset) {
+
+        if (inCipher == null) {
+            return length;
+        }
+
+        try {
+            inCipher.init(Cipher.DECRYPT_MODE, key);
+
+            return inCipher.doFinal(source, sourceOffset, length, dest,
+                                    destOffset);
+        } catch (java.security.InvalidKeyException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (BadPaddingException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (IllegalBlockSizeException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (ShortBufferException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        }
+    }
+
+    public synchronized int encode(byte[] source, int sourceOffset,
+                                   int length, byte[] dest, int destOffset) {
+
+        if (outCipher == null) {
+            return length;
+        }
+
+        try {
+            outCipher.init(Cipher.ENCRYPT_MODE, key);
+
+            return outCipher.doFinal(source, sourceOffset, length, dest,
+                                     destOffset);
+        } catch (java.security.InvalidKeyException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (BadPaddingException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (IllegalBlockSizeException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (ShortBufferException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        }
+    }
+
+    public static byte[] getNewKey(String cipherName, String provider) {
+
+        try {
+            KeyGenerator generator = provider == null
+                                     ? KeyGenerator.getInstance(cipherName)
+                                     : KeyGenerator.getInstance(cipherName,
+                                         provider);
+            SecretKey key = generator.generateKey();
+            byte[]    raw = key.getEncoded();
+
+            return raw;
+        } catch (java.security.NoSuchAlgorithmException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        } catch (NoSuchProviderException e) {
+            throw Error.error(ErrorCode.X_S0531, e);
+        }
+    }
+
+    public synchronized int getEncodedSize(int size) {
+
+        try {
+            return outCipher.getOutputSize(size);
+        } catch (IllegalStateException ex) {
+            try {
+                outCipher.init(Cipher.ENCRYPT_MODE, key);
+
+                return outCipher.getOutputSize(size);
+            } catch (java.security.InvalidKeyException e) {
+                throw Error.error(ErrorCode.X_S0531, e);
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/persist/DataFileBlockManager.java b/src/org/hsqldb/persist/DataFileBlockManager.java
new file mode 100644
index 0000000..bdfcb94
--- /dev/null
+++ b/src/org/hsqldb/persist/DataFileBlockManager.java
@@ -0,0 +1,172 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.lib.DoubleIntIndex;
+
+/**
+ * Maintains a list of free file blocks with fixed capacity.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.8.0
+ */
+public class DataFileBlockManager {
+
+    private DoubleIntIndex lookup;
+    private final int      capacity;
+    private int            midSize;
+    private final int      scale;
+    private long           releaseCount;
+    private long           requestCount;
+    private long           requestSize;
+
+    // reporting vars
+    long    lostFreeBlockSize;
+    boolean isModified;
+
+    /**
+     *
+     */
+    public DataFileBlockManager(int capacity, int scale, long lostSize) {
+
+        lookup = new DoubleIntIndex(capacity, true);
+
+        lookup.setValuesSearchTarget();
+
+        this.capacity          = capacity;
+        this.scale             = scale;
+        this.lostFreeBlockSize = lostSize;
+        this.midSize           = 128;    // arbitrary initial value
+    }
+
+    /**
+     */
+    void add(int pos, int rowSize) {
+
+        isModified = true;
+
+        if (capacity == 0) {
+            lostFreeBlockSize += rowSize;
+
+            return;
+        }
+
+        releaseCount++;
+
+        //
+        if (lookup.size() == capacity) {
+            resetList();
+        }
+
+        lookup.add(pos, rowSize);
+    }
+
+    /**
+     * Returns the position of a free block or 0.
+     */
+    int get(int rowSize) {
+
+        if (lookup.size() == 0) {
+            return -1;
+        }
+
+        int index = lookup.findFirstGreaterEqualKeyIndex(rowSize);
+
+        if (index == -1) {
+            return -1;
+        }
+
+        // statistics for successful requests only - to be used later for midSize
+        requestCount++;
+
+        requestSize += rowSize;
+
+        int length     = lookup.getValue(index);
+        int difference = length - rowSize;
+        int key        = lookup.getKey(index);
+
+        lookup.remove(index);
+
+        if (difference >= midSize) {
+            int pos = key + (rowSize / scale);
+
+            lookup.add(pos, difference);
+        } else {
+            lostFreeBlockSize += difference;
+        }
+
+        return key;
+    }
+
+    int size() {
+        return lookup.size();
+    }
+
+    long getLostBlocksSize() {
+        return lostFreeBlockSize;
+    }
+
+    boolean isModified() {
+        return isModified;
+    }
+
+    void clear() {
+        removeBlocks(lookup.size());
+    }
+
+    private void resetList() {
+
+        if (requestCount != 0) {
+            midSize = (int) (requestSize / requestCount);
+        }
+
+        int first = lookup.findFirstGreaterEqualSlotIndex(midSize);
+
+        if (first < lookup.size() / 4) {
+            first = lookup.size() / 4;
+        }
+
+        removeBlocks(first);
+    }
+
+    private void removeBlocks(int blocks) {
+
+        for (int i = 0; i < blocks; i++) {
+            lostFreeBlockSize += lookup.getValue(i);
+        }
+
+        lookup.removeRange(0, blocks);
+    }
+
+    private void checkIntegrity() throws NullPointerException {}
+}
diff --git a/src/org/hsqldb/persist/DataFileCache.java b/src/org/hsqldb/persist/DataFileCache.java
new file mode 100644
index 0000000..2fc0256
--- /dev/null
+++ b/src/org/hsqldb/persist/DataFileCache.java
@@ -0,0 +1,1161 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.hsqldb.Database;
+import org.hsqldb.HsqlException;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.FileAccess;
+import org.hsqldb.lib.FileArchiver;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.StopWatch;
+import org.hsqldb.lib.Storage;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.rowio.RowInputBinary180;
+import org.hsqldb.rowio.RowInputBinaryDecode;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputBinary180;
+import org.hsqldb.rowio.RowOutputBinaryEncode;
+import org.hsqldb.rowio.RowOutputInterface;
+import org.hsqldb.store.BitMap;
+
+/**
+ * Acts as a manager for CACHED table persistence.<p>
+ *
+ * This contains the top level functionality. Provides file management services
+ * and access.<p>
+ *
+ * Rewritten for 1.8.0 together with Cache.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class DataFileCache {
+
+    protected FileAccess fa;
+
+    // We are using persist.Logger-instance-specific FrameworkLogger
+    // because it is Database-instance specific.
+    // If add any static level logging, should instantiate a standard,
+    // context-agnostic FrameworkLogger for that purpose.
+    // flags
+    public static final int FLAG_ISSHADOWED = 1;
+    public static final int FLAG_ISSAVED    = 2;
+    public static final int FLAG_ROWINFO    = 3;
+    public static final int FLAG_190        = 4;
+
+    // file format fields
+    static final int LONG_EMPTY_SIZE      = 4;     // empty space size
+    static final int LONG_FREE_POS_POS    = 12;    // where iFreePos is saved
+    static final int LONG_EMPTY_INDEX_POS = 20;    // empty space index
+    static final int FLAGS_POS            = 28;
+    static final int MIN_INITIAL_FREE_POS = 32;
+
+    //
+    DataFileBlockManager     freeBlocks;
+    private static final int initIOBufferSize = 256;
+
+    //
+    protected String   dataFileName;
+    protected String   backupFileName;
+    protected Database database;
+
+    // this flag is used externally to determine if a backup is required
+    protected boolean fileModified;
+    protected int     cacheFileScale;
+
+    // post openning constant fields
+    protected boolean cacheReadonly;
+
+    //
+    protected int     cachedRowPadding = 8;
+    protected int     initialFreePos   = MIN_INITIAL_FREE_POS;
+    protected boolean hasRowInfo       = false;
+
+    // reusable input / output streams
+    protected RowInputInterface rowIn;
+    public RowOutputInterface   rowOut;
+
+    //
+    public long maxDataFileSize;
+
+    //
+    boolean is180;
+
+    //
+    protected Storage       dataFile;
+    protected volatile long fileFreePosition;
+    protected int           maxCacheRows;          // number of Rows
+    protected long          maxCacheBytes;         // number of bytes
+    protected int           maxFreeBlocks;
+    protected Cache         cache;
+
+    //
+    private RAShadowFile shadowFile;
+
+    //
+    ReadWriteLock lock      = new ReentrantReadWriteLock();
+    Lock          readLock  = lock.readLock();
+    Lock          writeLock = lock.writeLock();
+
+    public DataFileCache(Database db, String baseFileName) {
+
+        initParams(db, baseFileName);
+
+        cache = new Cache(this);
+    }
+
+    /**
+     * initial external parameters are set here.
+     */
+    protected void initParams(Database database, String baseFileName) {
+
+        this.dataFileName   = baseFileName + ".data";
+        this.backupFileName = baseFileName + ".backup";
+        this.database       = database;
+        fa                  = database.logger.getFileAccess();
+        cacheFileScale      = database.logger.getCacheFileScale();
+        cachedRowPadding    = 8;
+
+        if (cacheFileScale > 8) {
+            cachedRowPadding = cacheFileScale;
+        }
+
+        if (initialFreePos < cacheFileScale) {
+            initialFreePos = cacheFileScale;
+        }
+
+        cacheReadonly   = database.logger.propFilesReadOnly;
+        maxCacheRows    = database.logger.propCacheMaxRows;
+        maxCacheBytes   = database.logger.propCacheMaxSize;
+        maxDataFileSize = (long) Integer.MAX_VALUE * cacheFileScale;
+        maxFreeBlocks   = database.logger.propMaxFreeBlocks;
+        dataFile        = null;
+        shadowFile      = null;
+    }
+
+    /**
+     * Opens the *.data file for this cache, setting the variables that
+     * allow access to the particular database version of the *.data file.
+     */
+    public void open(boolean readonly) {
+
+        fileFreePosition = 0;
+
+        database.logger.logInfoEvent("open start");
+
+        try {
+            boolean isNio = database.logger.propNioDataFile;
+            int     fileType;
+
+            if (database.logger.isStoredFileAccess()) {
+                fileType = ScaledRAFile.DATA_FILE_STORED;
+            } else if (database.isFilesInJar()) {
+                fileType = ScaledRAFile.DATA_FILE_JAR;
+            } else if (isNio) {
+                fileType = ScaledRAFile.DATA_FILE_NIO;
+            } else {
+                fileType = ScaledRAFile.DATA_FILE_RAF;
+            }
+
+            if (readonly || database.isFilesInJar()) {
+                dataFile = ScaledRAFile.newScaledRAFile(database,
+                        dataFileName, readonly, fileType);
+
+                initBuffers();
+
+                return;
+            }
+
+            boolean preexists = false;
+            long    freesize  = 0;
+
+            if (fa.isStreamElement(dataFileName)) {
+                preexists = true;
+            }
+
+            dataFile = ScaledRAFile.newScaledRAFile(database, dataFileName,
+                    readonly, fileType);
+
+            if (preexists) {
+                dataFile.seek(FLAGS_POS);
+
+                int     flags   = dataFile.readInt();
+                boolean isSaved = BitMap.isSet(flags, FLAG_ISSAVED);
+
+                database.logger.propIncrementBackup = BitMap.isSet(flags,
+                        FLAG_ISSHADOWED);
+                is180 = !BitMap.isSet(flags, FLAG_190);
+
+                if (!isSaved) {
+                    boolean restored = true;
+
+                    dataFile.close();
+
+                    if (database.logger.propIncrementBackup) {
+                        restored = restoreBackupIncremental();
+                    } else {
+                        restoreBackup();
+                    }
+
+                    dataFile = ScaledRAFile.newScaledRAFile(database,
+                            dataFileName, readonly, fileType);
+
+                    if (!restored) {
+                        initNewFile();
+
+                        is180 = false;
+                    }
+                }
+
+                dataFile.seek(LONG_EMPTY_SIZE);
+
+                freesize = dataFile.readLong();
+
+                dataFile.seek(LONG_FREE_POS_POS);
+
+                fileFreePosition = dataFile.readLong();
+
+                if (fileFreePosition < initialFreePos) {
+                    fileFreePosition = initialFreePos;
+                }
+
+                if (database.logger.propIncrementBackup
+                        && fileFreePosition != initialFreePos) {
+                    shadowFile = new RAShadowFile(database, dataFile,
+                                                  backupFileName,
+                                                  fileFreePosition, 1 << 14);
+                }
+            } else {
+                initNewFile();
+            }
+
+            initBuffers();
+
+            fileModified = false;
+            freeBlocks = new DataFileBlockManager(maxFreeBlocks,
+                                                  cacheFileScale, freesize);
+
+            database.logger.logInfoEvent("open end");
+        } catch (Throwable t) {
+            database.logger.logSevereEvent("open failed", t);
+            close(false);
+
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_DataFileCache_open, new Object[] {
+                t.getMessage(), dataFileName
+            });
+        }
+    }
+
+    void initNewFile() throws IOException {
+
+        fileFreePosition = initialFreePos;
+
+        dataFile.seek(LONG_FREE_POS_POS);
+        dataFile.writeLong(initialFreePos);
+
+        // set shadowed flag;
+        int flags = 0;
+
+        if (database.logger.propIncrementBackup) {
+            flags = BitMap.set(flags, FLAG_ISSHADOWED);
+        }
+
+        flags = BitMap.set(flags, FLAG_190);
+
+        dataFile.seek(FLAGS_POS);
+        dataFile.writeInt(flags);
+        dataFile.synch();
+    }
+
+    void setIncrementBackup(boolean value) {
+
+        writeLock.lock();
+
+        try {
+            dataFile.seek(FLAGS_POS);
+
+            int flags = dataFile.readInt();
+
+            if (value) {
+                flags = BitMap.set(flags, FLAG_ISSHADOWED);
+            } else {
+                flags = BitMap.unset(flags, FLAG_ISSHADOWED);
+            }
+
+            dataFile.seek(FLAGS_POS);
+            dataFile.writeInt(flags);
+            dataFile.synch();
+        } catch (Throwable t) {
+            database.logger.logSevereEvent("backupFile failed", t);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Restores a compressed backup or the .data file.
+     */
+    private boolean restoreBackup() {
+
+        // in case data file cannot be deleted, reset it
+        deleteOrResetFreePos();
+
+        try {
+            FileAccess fa = database.logger.getFileAccess();
+
+            if (fa.isStreamElement(backupFileName)) {
+                FileArchiver.unarchive(backupFileName, dataFileName, fa,
+                                       FileArchiver.COMPRESSION_ZIP);
+
+                return true;
+            }
+
+            return false;
+        } catch (Throwable t) {
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_Message_Pair, new Object[] {
+                t.getMessage(), backupFileName
+            });
+        }
+    }
+
+    /**
+     * Restores in from an incremental backup
+     */
+    private boolean restoreBackupIncremental() {
+
+        try {
+            if (fa.isStreamElement(backupFileName)) {
+                RAShadowFile.restoreFile(database, backupFileName,
+                                         dataFileName);
+                deleteBackup();
+
+                return true;
+            }
+
+            return false;
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, e);
+        }
+    }
+
+    /**
+     *  Parameter write indicates either an orderly close, or a fast close
+     *  without backup.
+     *
+     *  When false, just closes the file.
+     *
+     *  When true, writes out all cached rows that have been modified and the
+     *  free position pointer for the *.data file and then closes the file.
+     */
+    public void close(boolean write) {
+
+        writeLock.lock();
+
+        try {
+            if (cacheReadonly) {
+                if (dataFile != null) {
+                    dataFile.close();
+
+                    dataFile = null;
+                }
+
+                return;
+            }
+
+            database.logger.logInfoEvent("DataFileCache.close(" + write
+                                         + ") : start");
+
+            if (write) {
+                cache.saveAll();
+                database.logger.logInfoEvent(
+                    "DataFileCache.close() : save data");
+
+                if (fileModified || freeBlocks.isModified()) {
+
+                    // set empty
+                    dataFile.seek(LONG_EMPTY_SIZE);
+                    dataFile.writeLong(freeBlocks.getLostBlocksSize());
+
+                    // set end
+                    dataFile.seek(LONG_FREE_POS_POS);
+                    dataFile.writeLong(fileFreePosition);
+
+                    // set saved flag;
+                    dataFile.seek(FLAGS_POS);
+
+                    int flags = dataFile.readInt();
+
+                    flags = BitMap.set(flags, FLAG_ISSAVED);
+
+                    dataFile.seek(FLAGS_POS);
+                    dataFile.writeInt(flags);
+                    database.logger.logInfoEvent(
+                        "DataFileCache.close() : flags");
+
+                    //
+                    dataFile.seek(fileFreePosition);
+                    database.logger.logInfoEvent(
+                        "DataFileCache.close() : seek end");
+                }
+            }
+
+            if (dataFile != null) {
+                dataFile.synch();
+                dataFile.close();
+                database.logger.logInfoEvent("DataFileCache.close() : close");
+
+                dataFile = null;
+            }
+
+            if (shadowFile != null) {
+                shadowFile.close();
+
+                shadowFile = null;
+            }
+
+            boolean empty = fileFreePosition == initialFreePos;
+
+            if (empty) {
+                deleteFile();
+                deleteBackup();
+            }
+        } catch (Throwable t) {
+            database.logger.logSevereEvent("Close failed", t);
+
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_DataFileCache_close, new Object[] {
+                t.getMessage(), dataFileName
+            });
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    protected void initBuffers() {
+
+        if (rowOut == null
+                || rowOut.getOutputStream().getBuffer().length
+                   > initIOBufferSize) {
+            if (is180) {
+                rowOut = new RowOutputBinary180(256, cachedRowPadding);
+            } else {
+                rowOut = new RowOutputBinaryEncode(database.logger.getCrypto(),
+                                                   256, cachedRowPadding);
+            }
+        }
+
+        if (rowIn == null || rowIn.getBuffer().length > initIOBufferSize) {
+            if (is180) {
+                rowIn = new RowInputBinary180(new byte[256]);
+            } else {
+                rowIn = new RowInputBinaryDecode(database.logger.getCrypto(),
+                                                 new byte[256]);
+            }
+        }
+    }
+
+    DataFileDefrag defrag() {
+
+        writeLock.lock();
+
+        try {
+            cache.saveAll();
+
+            DataFileDefrag dfd = new DataFileDefrag(database, this,
+                dataFileName);
+
+            dfd.process();
+            close(true);
+            cache.clear();
+
+            if (!database.logger.propIncrementBackup) {
+                backupFile();
+            }
+
+            database.schemaManager.setTempIndexRoots(dfd.getIndexRoots());
+            database.logger.log.writeScript(false);
+            database.getProperties().setDBModified(
+                HsqlDatabaseProperties.FILES_NEW);
+            database.logger.log.closeLog();
+            database.logger.log.deleteLog();
+            database.logger.log.renameNewScript();
+            renameDataFile();
+            renameBackupFile();
+            database.getProperties().setDBModified(
+                HsqlDatabaseProperties.FILES_NOT_MODIFIED);
+            open(false);
+            dfd.updateTransactionRowIDs();
+            database.schemaManager.setIndexRoots(dfd.getIndexRoots());
+
+            if (database.logger.log.dbLogWriter != null) {
+                database.logger.log.openLog();
+            }
+
+            database.getProperties().setDBModified(
+                HsqlDatabaseProperties.FILES_MODIFIED);
+
+            return dfd;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Used when a row is deleted as a result of some DML or DDL statement.
+     * Removes the row from the cache data structures.
+     * Adds the file space for the row to the list of free positions.
+     */
+    public void remove(int i, PersistentStore store) {
+
+        writeLock.lock();
+
+        try {
+            CachedObject r = release(i);
+
+            if (r != null) {
+                int size = r.getStorageSize();
+
+                freeBlocks.add(i, size);
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public void removePersistence(int i, PersistentStore store) {}
+
+    /**
+     * Allocates file space for the row. <p>
+     *
+     * Free space is requested from the block manager if it exists.
+     * Otherwise the file is grown to accommodate it.
+     */
+    int setFilePos(CachedObject r) {
+
+        int rowSize = r.getStorageSize();
+        int i       = freeBlocks == null ? -1
+                                         : freeBlocks.get(rowSize);
+
+        if (i == -1) {
+            i = (int) (fileFreePosition / cacheFileScale);
+
+            long newFreePosition = fileFreePosition + rowSize;
+
+            if (newFreePosition > maxDataFileSize) {
+                throw Error.error(ErrorCode.DATA_FILE_IS_FULL);
+            }
+
+            fileFreePosition = newFreePosition;
+        }
+
+        r.setPos(i);
+
+        return i;
+    }
+
+    public void add(CachedObject object) {
+
+        writeLock.lock();
+
+        try {
+            int i = setFilePos(object);
+
+            cache.put(i, object);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public int getStorageSize(int i) {
+
+        readLock.lock();
+
+        try {
+            CachedObject value = cache.get(i);
+
+            if (value != null) {
+                return value.getStorageSize();
+            }
+        } finally {
+            readLock.unlock();
+        }
+
+        return readSize(i);
+    }
+
+    public void replace(CachedObject object) {
+
+        writeLock.lock();
+
+        try {
+            int pos = object.getPos();
+
+            cache.replace(pos, object);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    public CachedObject get(CachedObject object, PersistentStore store,
+                            boolean keep) {
+
+        readLock.lock();
+
+        int pos;
+
+        try {
+            if (object.isInMemory()) {
+                if (keep) {
+                    object.keepInMemory(true);
+                }
+
+                return object;
+            }
+
+            pos = object.getPos();
+
+            if (pos < 0) {
+                return null;
+            }
+
+            object = cache.get(pos);
+
+            if (object != null) {
+                if (keep) {
+                    object.keepInMemory(true);
+                }
+
+                return object;
+            }
+        } finally {
+            readLock.unlock();
+        }
+
+        return getFromFile(pos, store, keep);
+    }
+
+    public CachedObject get(int pos, PersistentStore store, boolean keep) {
+
+        CachedObject object;
+
+        if (pos < 0) {
+            return null;
+        }
+
+        readLock.lock();
+
+        try {
+            object = cache.get(pos);
+
+            if (object != null) {
+                if (keep) {
+                    object.keepInMemory(true);
+                }
+
+                return object;
+            }
+        } finally {
+            readLock.unlock();
+        }
+
+        return getFromFile(pos, store, keep);
+    }
+
+    private CachedObject getFromFile(int pos, PersistentStore store,
+                                     boolean keep) {
+
+        CachedObject object = null;
+
+        writeLock.lock();
+
+        try {
+            object = cache.get(pos);
+
+            if (object != null) {
+                if (keep) {
+                    object.keepInMemory(true);
+                }
+
+                return object;
+            }
+
+            for (int j = 0; j < 2; j++) {
+                try {
+                    RowInputInterface rowInput = readObject(pos);
+
+                    if (rowInput == null) {
+                        return null;
+                    }
+
+                    object = store.get(rowInput);
+
+                    break;
+                } catch (OutOfMemoryError err) {
+                    cache.forceCleanUp();
+                    System.gc();
+
+                    if (j > 0) {
+                        throw err;
+                    }
+                }
+            }
+
+            // for text tables with empty rows at the beginning,
+            // pos may move forward in readObject
+            pos = object.getPos();
+
+            cache.put(pos, object);
+
+            if (keep) {
+                object.keepInMemory(true);
+            }
+
+            store.set(object);
+
+            return object;
+        } catch (HsqlException e) {
+            database.logger.logSevereEvent(dataFileName + " getFromFile "
+                                           + pos, e);
+
+            throw e;
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    RowInputInterface getRaw(int i) {
+
+        writeLock.lock();
+
+        try {
+            return readObject(i);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    protected int readSize(int pos) {
+
+        writeLock.lock();
+
+        try {
+            dataFile.seek((long) pos * cacheFileScale);
+
+            return dataFile.readInt();
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, e);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    protected RowInputInterface readObject(int pos) {
+
+        try {
+            dataFile.seek((long) pos * cacheFileScale);
+
+            int size = dataFile.readInt();
+
+            rowIn.resetRow(pos, size);
+            dataFile.read(rowIn.getBuffer(), 4, size - 4);
+
+            return rowIn;
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, e);
+        }
+    }
+
+    public CachedObject release(int pos) {
+
+        writeLock.lock();
+
+        try {
+            return cache.release(pos);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    protected void saveRows(CachedObject[] rows, int offset, int count) {
+
+        try {
+            copyShadow(rows, offset, count);
+            setFileModified();
+
+            for (int i = offset; i < offset + count; i++) {
+                CachedObject r = rows[i];
+
+                saveRowNoLock(r);
+
+                rows[i] = null;
+            }
+        } catch (HsqlException e) {
+            database.logger.logSevereEvent("saveRows failed", e);
+
+            throw e;
+        } catch (Throwable e) {
+            database.logger.logSevereEvent("saveRows failed", e);
+
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, e);
+        } finally {
+            initBuffers();
+        }
+    }
+
+    /**
+     * Writes out the specified Row. Will write only the Nodes or both Nodes
+     * and table row data depending on what is not already persisted to disk.
+     */
+    public void saveRow(CachedObject row) {
+
+        writeLock.lock();
+
+        try {
+            copyShadow(row);
+            setFileModified();
+            saveRowNoLock(row);
+        } catch (Throwable e) {
+            database.logger.logSevereEvent("saveRow failed", e);
+
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, e);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    private void saveRowNoLock(CachedObject row) {
+
+        try {
+            rowOut.reset();
+            row.write(rowOut);
+            dataFile.seek((long) row.getPos() * cacheFileScale);
+            dataFile.write(rowOut.getOutputStream().getBuffer(), 0,
+                           rowOut.getOutputStream().size());
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, e);
+        }
+    }
+
+    protected void copyShadow(CachedObject[] rows, int offset,
+                              int count) throws IOException {
+
+        if (shadowFile != null) {
+            for (int i = offset; i < offset + count; i++) {
+                CachedObject row     = rows[i];
+                long         seekpos = (long) row.getPos() * cacheFileScale;
+
+                shadowFile.copy(seekpos, row.getStorageSize());
+            }
+
+            shadowFile.close();
+        }
+    }
+
+    protected void copyShadow(CachedObject row) throws IOException {
+
+        if (shadowFile != null) {
+            long seekpos = (long) row.getPos() * cacheFileScale;
+
+            shadowFile.copy(seekpos, row.getStorageSize());
+            shadowFile.close();
+        }
+    }
+
+    /**
+     *  Saves the *.data file as compressed *.backup.
+     *
+     * @throws  HsqlException
+     */
+    void backupFile() {
+
+        writeLock.lock();
+
+        try {
+            if (database.logger.propIncrementBackup) {
+                if (fa.isStreamElement(backupFileName)) {
+                    deleteBackup();
+                }
+
+                return;
+            }
+
+            if (fa.isStreamElement(dataFileName)) {
+                FileArchiver.archive(dataFileName, backupFileName + ".new",
+                                     database.logger.getFileAccess(),
+                                     FileArchiver.COMPRESSION_ZIP);
+            }
+        } catch (IOException e) {
+            database.logger.logSevereEvent("backupFile failed", e);
+
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, e);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    void renameBackupFile() {
+
+        writeLock.lock();
+
+        try {
+            if (database.logger.propIncrementBackup) {
+                deleteBackup();
+
+                return;
+            }
+
+            if (fa.isStreamElement(backupFileName + ".new")) {
+                deleteBackup();
+                fa.renameElement(backupFileName + ".new", backupFileName);
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     *  Renames the *.data.new file.
+     *
+     * @throws  HsqlException
+     */
+    void renameDataFile() {
+
+        writeLock.lock();
+
+        try {
+            if (fa.isStreamElement(dataFileName + ".new")) {
+                deleteFile();
+                fa.renameElement(dataFileName + ".new", dataFileName);
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    void deleteFile() {
+
+        writeLock.lock();
+
+        try {
+
+            // first attemp to delete
+            fa.removeElement(dataFileName);
+
+            // OOo related code
+            if (database.logger.isStoredFileAccess()) {
+                return;
+            }
+
+            // OOo end
+            if (fa.isStreamElement(dataFileName)) {
+
+//#ifdef JAVA2FULL
+                try {
+                    File   file = new File(database.getCanonicalPath());
+                    File[] list = file.getParentFile().listFiles();
+
+                    for (int i = 0; i < list.length; i++) {
+                        if (list[i].getName().endsWith(".old")
+                                && list[i].getName().startsWith(
+                                    file.getName())) {
+                            list[i].delete();
+                        }
+                    }
+                } catch (Throwable t) {}
+
+//#endif JAVA2FULL
+                fa.removeElement(dataFileName);
+
+                if (fa.isStreamElement(dataFileName)) {
+                    String discardName = newDiscardFileName();
+
+                    fa.renameElement(dataFileName, discardName);
+                }
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    String newDiscardFileName() {
+
+        String timestamp = StringUtil.toPaddedString(
+            Integer.toHexString((int) System.currentTimeMillis()), 8, '0',
+            true);
+        String discardName = dataFileName + "." + timestamp + ".old";
+
+        return discardName;
+    }
+
+    void deleteBackup() {
+
+        writeLock.lock();
+
+        try {
+            if (fa.isStreamElement(backupFileName)) {
+                fa.removeElement(backupFileName);
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * This method deletes a data file or resets its free position.
+     * this is used only for nio files - not OOo files
+     */
+    void deleteOrResetFreePos() {
+
+        deleteFile();
+
+        // OOo related code
+        if (database.logger.isStoredFileAccess()) {
+            return;
+        }
+
+        // OOo end
+        if (!database.logger.getFileAccess().isStreamElement(dataFileName)) {
+            return;
+        }
+
+        try {
+            dataFile = new ScaledRAFileSimple(dataFileName, "rw");
+
+            initNewFile();
+        } catch (IOException e) {
+            database.logger.logSevereEvent("deleteOrResetFreePos failed", e);
+        } finally {
+            if (dataFile != null) {
+                try {
+                    dataFile.close();
+
+                    dataFile = null;
+                } catch (IOException e) {
+                    database.logger.logWarningEvent("Failed to close RA file",
+                                                    e);
+                }
+            }
+        }
+    }
+
+    public int capacity() {
+        return maxCacheRows;
+    }
+
+    public long bytesCapacity() {
+        return maxCacheBytes;
+    }
+
+    public long getTotalCachedBlockSize() {
+        return cache.getTotalCachedBlockSize();
+    }
+
+    public int getFreeBlockCount() {
+        return freeBlocks.size();
+    }
+
+    public int getTotalFreeBlockSize() {
+        return 0;
+    }
+
+    public long getFileFreePos() {
+        return fileFreePosition;
+    }
+
+    public int getCachedObjectCount() {
+        return cache.size();
+    }
+
+    public int getAccessCount() {
+        return cache.incrementAccessCount();
+    }
+
+    public String getFileName() {
+        return dataFileName;
+    }
+
+    public boolean hasRowInfo() {
+        return hasRowInfo;
+    }
+
+    public boolean isFileModified() {
+        return fileModified;
+    }
+
+    public boolean isFileOpen() {
+        return dataFile != null;
+    }
+
+    protected void setFileModified() {
+
+        writeLock.lock();
+
+        try {
+            if (!fileModified) {
+
+                // unset saved flag;
+                dataFile.seek(FLAGS_POS);
+
+                int flags = dataFile.readInt();
+
+                flags = BitMap.unset(flags, FLAG_ISSAVED);
+
+                dataFile.seek(FLAGS_POS);
+                dataFile.writeInt(flags);
+                dataFile.synch();
+                Error.printSystemOut(
+                    cache.saveAllTimer.currentElapsedTimeToMessage(
+                        "flags set time: "));
+
+                fileModified = true;
+            }
+        } catch (Throwable t) {}
+        finally {
+            writeLock.unlock();
+        }
+    }
+
+    public boolean isDataReadOnly() {
+        return this.cacheReadonly;
+    }
+}
diff --git a/src/org/hsqldb/persist/DataFileCacheSession.java b/src/org/hsqldb/persist/DataFileCacheSession.java
new file mode 100644
index 0000000..1f022bd
--- /dev/null
+++ b/src/org/hsqldb/persist/DataFileCacheSession.java
@@ -0,0 +1,148 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.Database;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.FileUtil;
+
+/**
+ * A file-based row store for temporary CACHED table persistence.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class DataFileCacheSession extends DataFileCache {
+
+    // We are using persist.Logger-instance-specific FrameworkLogger
+    // because it is Database-instance specific.
+    // If add any static level logging, should instantiate a standard,
+    // context-agnostic FrameworkLogger for that purpose.
+    public int storeCount;
+
+    public DataFileCacheSession(Database db, String baseFileName) {
+        super(db, baseFileName);
+    }
+
+    /**
+     * Initial external parameters are set here. The size if fixed.
+     */
+    protected void initParams(Database database, String baseFileName) {
+
+        this.dataFileName = baseFileName + ".data.tmp";
+        this.database     = database;
+        fa                = FileUtil.getFileUtil();
+
+        int cacheSizeScale = 10;
+
+        cacheFileScale = 8;
+        maxCacheRows   = 2048;
+
+        int avgRowBytes = 1 << cacheSizeScale;
+
+        maxCacheBytes   = maxCacheRows * avgRowBytes;
+        maxDataFileSize = (long) Integer.MAX_VALUE * 4;
+        dataFile        = null;
+    }
+
+    /**
+     * Opens the *.data file for this cache.
+     */
+    public void open(boolean readonly) {
+
+        try {
+            dataFile = ScaledRAFile.newScaledRAFile(database, dataFileName,
+                    false, ScaledRAFile.DATA_FILE_RAF);
+            fileFreePosition = MIN_INITIAL_FREE_POS;
+
+            initBuffers();
+
+            freeBlocks = new DataFileBlockManager(0, cacheFileScale, 0);
+        } catch (Throwable t) {
+            database.logger.logWarningEvent("Failed to open RA file", t);
+            close(false);
+
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_DataFileCache_open, new Object[] {
+                t.getMessage(), dataFileName
+            });
+        }
+    }
+
+    public synchronized void add(CachedObject object) {
+        super.add(object);
+    }
+
+    /**
+     *  Parameter write is always false. The backing file is simply closed and
+     *  deleted.
+     */
+    public synchronized void close(boolean write) {
+
+        try {
+            if (dataFile != null) {
+                dataFile.close();
+
+                dataFile = null;
+
+                fa.removeElement(dataFileName);
+            }
+        } catch (Throwable t) {
+            database.logger.logWarningEvent("Failed to close RA file", t);
+
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_DataFileCache_close, new Object[] {
+                t.getMessage(), dataFileName
+            });
+        }
+    }
+
+    void postClose(boolean keep) {}
+
+    public void clear() {
+
+        cache.clear();
+
+        fileFreePosition = MIN_INITIAL_FREE_POS;
+    }
+
+    public void deleteAll() {
+
+        cache.clear();
+
+        fileFreePosition = MIN_INITIAL_FREE_POS;
+
+        initBuffers();
+    }
+}
diff --git a/src/org/hsqldb/persist/DataFileDefrag.java b/src/org/hsqldb/persist/DataFileDefrag.java
new file mode 100644
index 0000000..e70f212
--- /dev/null
+++ b/src/org/hsqldb/persist/DataFileDefrag.java
@@ -0,0 +1,321 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.hsqldb.Database;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.IndexAVL;
+import org.hsqldb.lib.DoubleIntIndex;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.StopWatch;
+import org.hsqldb.lib.Storage;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.rowio.RowOutputInterface;
+import org.hsqldb.store.BitMap;
+
+// oj@openoffice.org - changed to file access api
+
+/**
+ *  Routine to defrag the *.data file.
+ *
+ *  This method iterates over the primary index of a table to find the
+ *  disk position for each row and stores it, together with the new position
+ *  in an array.
+ *
+ *  A second pass over the primary index writes each row to the new disk
+ *  image after translating the old pointers to the new.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version    1.9.0
+ * @since      1.7.2
+ */
+final class DataFileDefrag {
+
+    BufferedOutputStream fileStreamOut;
+    long                 fileOffset;
+    StopWatch            stopw = new StopWatch();
+    String               dataFileName;
+    int[][]              rootsList;
+    Database             database;
+    DataFileCache        cache;
+    int                  scale;
+    DoubleIntIndex       transactionRowLookup;
+
+    DataFileDefrag(Database db, DataFileCache cache, String dataFileName) {
+
+        this.database     = db;
+        this.cache        = cache;
+        this.scale        = cache.cacheFileScale;
+        this.dataFileName = dataFileName;
+    }
+
+    void process() {
+
+        boolean complete = false;
+
+        Error.printSystemOut("Defrag process begins");
+
+        transactionRowLookup = database.txManager.getTransactionIDList();
+
+        Error.printSystemOut("transaction count: "
+                             + transactionRowLookup.size());
+
+        HsqlArrayList allTables = database.schemaManager.getAllTables();
+
+        rootsList = new int[allTables.size()][];
+
+        Storage dest = null;
+
+        try {
+            OutputStream fos =
+                database.logger.getFileAccess().openOutputStreamElement(
+                    dataFileName + ".new");
+
+            fileStreamOut = new BufferedOutputStream(fos, 1 << 12);
+
+            for (int i = 0; i < cache.initialFreePos; i++) {
+                fileStreamOut.write(0);
+            }
+
+            fileOffset = cache.initialFreePos;
+
+            for (int i = 0, tSize = allTables.size(); i < tSize; i++) {
+                Table t = (Table) allTables.get(i);
+
+                if (t.getTableType() == TableBase.CACHED_TABLE) {
+                    int[] rootsArray = writeTableToDataFile(t);
+
+                    rootsList[i] = rootsArray;
+                } else {
+                    rootsList[i] = null;
+                }
+
+                Error.printSystemOut("table: " + t.getName().name
+                                     + " complete");
+            }
+
+            fileStreamOut.flush();
+            fileStreamOut.close();
+
+            fileStreamOut = null;
+
+            // write out the end of file position
+            int type = database.logger.isStoredFileAccess()
+                       ? ScaledRAFile.DATA_FILE_STORED
+                       : ScaledRAFile.DATA_FILE_RAF;
+
+            dest = ScaledRAFile.newScaledRAFile(database,
+                                                dataFileName + ".new", false,
+                                                type);
+
+            dest.seek(DataFileCache.LONG_FREE_POS_POS);
+            dest.writeLong(fileOffset);
+
+            // set shadowed flag;
+            int flags = 0;
+
+            if (database.logger.propIncrementBackup) {
+                flags = BitMap.set(flags, DataFileCache.FLAG_ISSHADOWED);
+            }
+
+            flags = BitMap.set(flags, DataFileCache.FLAG_190);
+            flags = BitMap.set(flags, DataFileCache.FLAG_ISSAVED);
+
+            dest.seek(DataFileCache.FLAGS_POS);
+            dest.writeInt(flags);
+            dest.close();
+
+            dest = null;
+
+            for (int i = 0, size = rootsList.length; i < size; i++) {
+                int[] roots = rootsList[i];
+
+                if (roots != null) {
+                    Error.printSystemOut(
+                        "roots: "
+                        + org.hsqldb.lib.StringUtil.getList(roots, ",", ""));
+                }
+            }
+
+            complete = true;
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, e);
+        } catch (OutOfMemoryError e) {
+            throw Error.error(ErrorCode.OUT_OF_MEMORY, e);
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.GENERAL_ERROR, t);
+        } finally {
+            try {
+                if (fileStreamOut != null) {
+                    fileStreamOut.close();
+                }
+
+                if (dest != null) {
+                    dest.close();
+                }
+            } catch (Throwable t) {
+                database.logger.logSevereEvent("backupFile failed", t);
+            }
+
+            if (!complete) {
+                database.logger.getFileAccess().removeElement(dataFileName
+                        + ".new");
+            }
+        }
+
+        Error.printSystemOut("Defrag transfer complete: "
+                             + stopw.elapsedTime());
+    }
+
+    /**
+     * called from outside after the complete end of defrag
+     */
+    void updateTableIndexRoots() {
+
+        HsqlArrayList allTables = database.schemaManager.getAllTables();
+
+        for (int i = 0, size = allTables.size(); i < size; i++) {
+            Table t = (Table) allTables.get(i);
+
+            if (t.getTableType() == TableBase.CACHED_TABLE) {
+                int[] rootsArray = rootsList[i];
+
+                t.setIndexRoots(rootsArray);
+            }
+        }
+    }
+
+    /**
+     * called from outside after the complete end of defrag
+     */
+    void updateTransactionRowIDs() {
+        database.txManager.convertTransactionIDs(transactionRowLookup);
+    }
+
+    int[] writeTableToDataFile(Table table) throws IOException {
+
+        Session session = database.getSessionManager().getSysSession();
+        PersistentStore    store  = session.sessionData.getRowStore(table);
+        RowOutputInterface rowOut = cache.rowOut.duplicate();
+        DoubleIntIndex pointerLookup = new DoubleIntIndex(
+            ((IndexAVL) table.getPrimaryIndex()).sizeEstimate(store), false);
+        int[] rootsArray = table.getIndexRootsArray();
+        long  pos        = fileOffset;
+        int   count      = 0;
+
+        pointerLookup.setKeysSearchTarget();
+        Error.printSystemOut("lookup begins: " + stopw.elapsedTime());
+
+        // all rows
+        RowIterator it = table.rowIterator(store);
+
+        for (; it.hasNext(); count++) {
+            CachedObject row = it.getNextRow();
+
+            pointerLookup.addUnsorted(row.getPos(), (int) (pos / scale));
+
+            if (count % 50000 == 0) {
+                Error.printSystemOut("pointer pair for row " + count + " "
+                                     + row.getPos() + " " + pos);
+            }
+
+            pos += row.getStorageSize();
+        }
+
+        Error.printSystemOut("table: " + table.getName().name + " list done: "
+                             + stopw.elapsedTime());
+
+        count = 0;
+        it    = table.rowIterator(store);
+
+        for (; it.hasNext(); count++) {
+            CachedObject row = it.getNextRow();
+
+            rowOut.reset();
+            row.write(rowOut, pointerLookup);
+            fileStreamOut.write(rowOut.getOutputStream().getBuffer(), 0,
+                                rowOut.size());
+
+            fileOffset += row.getStorageSize();
+
+            if ((count) % 50000 == 0) {
+                Error.printSystemOut(count + " rows " + stopw.elapsedTime());
+            }
+        }
+
+        for (int i = 0; i < table.getIndexCount(); i++) {
+            if (rootsArray[i] == -1) {
+                continue;
+            }
+
+            int lookupIndex =
+                pointerLookup.findFirstEqualKeyIndex(rootsArray[i]);
+
+            if (lookupIndex == -1) {
+                throw Error.error(ErrorCode.DATA_FILE_ERROR);
+            }
+
+            rootsArray[i] = pointerLookup.getValue(lookupIndex);
+        }
+
+        setTransactionRowLookups(pointerLookup);
+        Error.printSystemOut("table: " + table.getName().name
+                             + " : table converted");
+
+        return rootsArray;
+    }
+
+    public int[][] getIndexRoots() {
+        return rootsList;
+    }
+
+    void setTransactionRowLookups(DoubleIntIndex pointerLookup) {
+
+        for (int i = 0, size = transactionRowLookup.size(); i < size; i++) {
+            int key         = transactionRowLookup.getKey(i);
+            int lookupIndex = pointerLookup.findFirstEqualKeyIndex(key);
+
+            if (lookupIndex != -1) {
+                transactionRowLookup.setValue(
+                    i, pointerLookup.getValue(lookupIndex));
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/persist/HsqlDatabaseProperties.java b/src/org/hsqldb/persist/HsqlDatabaseProperties.java
new file mode 100644
index 0000000..8ce3a4d
--- /dev/null
+++ b/src/org/hsqldb/persist/HsqlDatabaseProperties.java
@@ -0,0 +1,799 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.util.Enumeration;
+
+import org.hsqldb.Database;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.Set;
+import org.hsqldb.lib.StringUtil;
+
+/**
+ * Manages a .properties file for a database.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class HsqlDatabaseProperties extends HsqlProperties {
+
+    // We are using persist.Logger-instance-specific FrameworkLogger
+    // because it is Database-instance specific.
+    // If add any static level logging, should instantiate a standard,
+    // context-agnostic FrameworkLogger for that purpose.
+    private static final String hsqldb_method_class_names =
+        "hsqldb.method_class_names";
+    private static HashSet accessibleJavaMethodNames;
+
+    static {
+        try {
+            String prop = System.getProperty(hsqldb_method_class_names);
+
+            if (prop != null) {
+                accessibleJavaMethodNames = new HashSet();
+
+                String[] names = StringUtil.split(prop, ";");
+
+                for (int i = 0; i < names.length; i++) {
+                    accessibleJavaMethodNames.add(names[i]);
+                }
+            }
+        } catch (Exception e) {}
+    }
+
+    /**
+     * If the system property "hsqldb.method_class_names" is not set, then
+     * static methods of all available Java classes can be accessed as functions
+     * in HSQLDB. If the property is set, then only the list of semicolon
+     * seperated method names becomes accessible. An empty property value means
+     * no class is accessible.<p>
+     *
+     * A property value that ends with .* is treated as a wild card and allows
+     * access to all classe or method names formed by substitution of the
+     * asterisk.<p>
+     *
+     * All methods of java.lang.Math are always accessible.
+     *
+     *
+     */
+    public static boolean supportsJavaMethod(String name) {
+
+        if (accessibleJavaMethodNames == null) {
+            return true;
+        }
+
+        if (name.startsWith("java.lang.Math.")) {
+            return true;
+        }
+
+        if (accessibleJavaMethodNames.contains(name)) {
+            return true;
+        }
+
+        Iterator it = accessibleJavaMethodNames.iterator();
+
+        while (it.hasNext()) {
+            String className = (String) it.next();
+            int    limit     = className.lastIndexOf(".*");
+
+            if (limit < 1) {
+                continue;
+            }
+
+            if (name.startsWith(className.substring(0, limit + 1))) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    // accessibility
+    public static final int SYSTEM_PROPERTY = 0;
+    public static final int FILE_PROPERTY   = 1;
+    public static final int SQL_PROPERTY    = 2;
+
+    // db files modified
+    public static final int     FILES_NOT_MODIFIED = 0;
+    public static final int     FILES_MODIFIED     = 1;
+    public static final int     FILES_NEW          = 2;
+    private static final String MODIFIED_NO        = "no";
+    private static final String MODIFIED_YES       = "yes";
+    private static final String MODIFIED_NEW       = "no-new-files";
+
+    // allowed property metadata
+    private static final HashMap dbMeta   = new HashMap(67);
+    private static final HashMap textMeta = new HashMap(17);
+
+    // versions
+    public static final String VERSION_STRING_1_8_0 = "1.8.0";
+    public static final String THIS_VERSION         = "2.0.0";
+    public static final String THIS_FULL_VERSION    = "2.0.0";
+    public static final String THIS_CACHE_VERSION   = "2.0.0";
+    public static final String PRODUCT_NAME         = "HSQL Database Engine";
+    public static final int    MAJOR                = 2,
+                               MINOR                = 0,
+                               REVISION             = 0;
+
+    /**
+     * system properties supported by HSQLDB
+     */
+    public static final String system_lockfile_poll_retries_property =
+        "hsqldb.lockfile_poll_retries";
+    public static final String system_max_char_or_varchar_display_size =
+        "hsqldb.max_char_or_varchar_display_size";
+
+    //
+    public static final String hsqldb_inc_backup = "hsqldb.incremental_backup";
+
+    //
+    public static final String  hsqldb_version  = "version";
+    public static final String  hsqldb_readonly = "readonly";
+    private static final String hsqldb_modified = "modified";
+
+    //
+    public static final String runtime_gc_interval = "runtime.gc_interval";
+
+    //
+    public static final String url_ifexists        = "ifexists";
+    public static final String url_default_schema  = "default_schema";
+    public static final String url_check_props     = "check_props";
+    public static final String url_get_column_name = "get_column_name";
+
+    //
+    public static final String url_storage_class_name = "storage_class_name";
+    public static final String url_fileaccess_class_name =
+        "fileaccess_class_name";
+    public static final String url_storage_key = "storage_key";
+    public static final String url_shutdown    = "shutdown";
+
+    //
+    public static final String url_crypt_key      = "crypt_key";
+    public static final String url_crypt_type     = "crypt_type";
+    public static final String url_crypt_provider = "crypt_provider";
+
+    //
+    public static final String hsqldb_tx             = "hsqldb.tx";
+    public static final String hsqldb_tx_level       = "hsqldb.tx_level";
+    public static final String hsqldb_applog         = "hsqldb.applog";
+    public static final String hsqldb_lob_file_scale = "hsqldb.lob_file_scale";
+    public static final String hsqldb_cache_file_scale =
+        "hsqldb.cache_file_scale";
+    public static final String hsqldb_cache_free_count_scale =
+        "hsqldb.cache_free_count_scale";
+    public static final String hsqldb_cache_rows = "hsqldb.cache_rows";
+    public static final String hsqldb_cache_size = "hsqldb.cache_size";
+    public static final String hsqldb_default_table_type =
+        "hsqldb.default_table_type";
+    public static final String hsqldb_defrag_limit   = "hsqldb.defrag_limit";
+    public static final String hsqldb_files_readonly = "files_readonly";
+    public static final String hsqldb_lock_file      = "hsqldb.lock_file";
+    public static final String hsqldb_log_data       = "hsqldb.log_data";
+    public static final String hsqldb_log_size       = "hsqldb.log_size";
+    public static final String hsqldb_nio_data_file  = "hsqldb.nio_data_file";
+    public static final String hsqldb_max_nio_scale  = "hsqldb.max_nio_scale";
+    public static final String hsqldb_script_format  = "hsqldb.script_format";
+    public static final String hsqldb_temp_directory = "hsqldb.temp_directory";
+    public static final String hsqldb_result_max_memory_rows =
+        "hsqldb.result_max_memory_rows";
+    public static final String hsqldb_write_delay = "hsqldb.write_delay";
+    public static final String hsqldb_write_delay_millis =
+        "hsqldb.write_delay_millis";
+
+    //
+    public static final String sql_ref_integrity     = "sql.ref_integrity";
+    public static final String sql_compare_in_locale = "sql.compare_in_locale";
+    public static final String sql_enforce_size      = "sql.enforce_size";
+    public static final String sql_enforce_strict_size =
+        "sql.enforce_strict_size";
+    public static final String sql_enforce_refs = "sql.enforce_refs";
+    public static final String sql_enforce_names = "sql.enforce_names";
+    public static final String jdbc_translate_dti_types =
+        "jdbc.translate_dti_types";
+    public static final String sql_identity_is_pk = "sql.identity_is_pk";
+
+    //
+    public static final String textdb_cache_scale = "textdb.cache_scale";
+    public static final String textdb_cache_size_scale =
+        "textdb.cache_size_scale";
+    public static final String textdb_all_quoted = "textdb.all_quoted";
+    public static final String textdb_allow_full_path =
+        "textdb.allow_full_path";
+    public static final String textdb_encoding     = "textdb.encoding";
+    public static final String textdb_ignore_first = "textdb.ignore_first";
+    public static final String textdb_quoted       = "textdb.quoted";
+    public static final String textdb_fs           = "textdb.fs";
+    public static final String textdb_vs           = "textdb.vs";
+    public static final String textdb_lvs          = "textdb.lvs";
+
+    static {
+
+        // text table defaults
+        textMeta.put(textdb_allow_full_path,
+                     HsqlProperties.getMeta(textdb_allow_full_path,
+                                            SYSTEM_PROPERTY, false));
+        textMeta.put(textdb_quoted,
+                     HsqlProperties.getMeta(textdb_quoted, SQL_PROPERTY,
+                                            false));
+        textMeta.put(textdb_all_quoted,
+                     HsqlProperties.getMeta(textdb_all_quoted, SQL_PROPERTY,
+                                            false));
+        textMeta.put(textdb_ignore_first,
+                     HsqlProperties.getMeta(textdb_ignore_first, SQL_PROPERTY,
+                                            false));
+        textMeta.put(textdb_fs,
+                     HsqlProperties.getMeta(textdb_fs, SQL_PROPERTY, ","));
+        textMeta.put(textdb_vs,
+                     HsqlProperties.getMeta(textdb_vs, SQL_PROPERTY, null));
+        textMeta.put(textdb_lvs,
+                     HsqlProperties.getMeta(textdb_lvs, SQL_PROPERTY, null));
+        textMeta.put(textdb_encoding,
+                     HsqlProperties.getMeta(textdb_encoding, SQL_PROPERTY,
+                                            "ISO-8859-1"));
+        textMeta.put(textdb_cache_scale,
+                     HsqlProperties.getMeta(textdb_cache_scale, SQL_PROPERTY,
+                                            10, 8, 16));
+        textMeta.put(textdb_cache_size_scale,
+                     HsqlProperties.getMeta(textdb_cache_size_scale,
+                                            SQL_PROPERTY, 10, 6, 20));
+        dbMeta.putAll(textMeta);
+
+        // string defaults for protected props
+        dbMeta.put(hsqldb_version,
+                   HsqlProperties.getMeta(hsqldb_version, FILE_PROPERTY,
+                                          null));
+        dbMeta.put(hsqldb_modified,
+                   HsqlProperties.getMeta(hsqldb_modified, FILE_PROPERTY,
+                                          null));
+
+        // boolean defaults for protected props
+        dbMeta.put(hsqldb_readonly,
+                   HsqlProperties.getMeta(hsqldb_readonly, FILE_PROPERTY,
+                                          false));
+        dbMeta.put(hsqldb_files_readonly,
+                   HsqlProperties.getMeta(hsqldb_files_readonly,
+                                          FILE_PROPERTY, false));
+
+        // integral defaults for protected props
+        dbMeta.put(hsqldb_lob_file_scale,
+                   HsqlProperties.getMeta(hsqldb_lob_file_scale,
+                                          FILE_PROPERTY, 32, new int[] {
+            1, 2, 4, 8, 16, 32
+        }));
+
+        // this property is normally either 1 or 8 - 8 for new databases
+        dbMeta.put(hsqldb_cache_file_scale,
+                   HsqlProperties.getMeta(hsqldb_cache_file_scale,
+                                          FILE_PROPERTY, 8, new int[] {
+            1, 8, 16, 32, 64, 128
+        }));
+
+        // string defaults for user defined props
+        dbMeta.put(hsqldb_tx,
+                   HsqlProperties.getMeta(hsqldb_tx, SQL_PROPERTY, "LOCKS"));
+        dbMeta.put(hsqldb_tx_level,
+                   HsqlProperties.getMeta(hsqldb_tx_level, SQL_PROPERTY,
+                                          "READ_COMMITTED"));
+        dbMeta.put(hsqldb_temp_directory,
+                   HsqlProperties.getMeta(hsqldb_temp_directory, SQL_PROPERTY,
+                                          null));
+        dbMeta.put(hsqldb_default_table_type,
+                   HsqlProperties.getMeta(hsqldb_default_table_type,
+                                          SQL_PROPERTY, "MEMORY"));
+
+        // boolean defaults for user defined props
+        dbMeta.put(jdbc_translate_dti_types,
+                   HsqlProperties.getMeta(jdbc_translate_dti_types,
+                                          SQL_PROPERTY, true));
+        dbMeta.put(hsqldb_inc_backup,
+                   HsqlProperties.getMeta(hsqldb_inc_backup, SQL_PROPERTY,
+                                          true));
+        dbMeta.put(hsqldb_lock_file,
+                   HsqlProperties.getMeta(hsqldb_lock_file, SQL_PROPERTY,
+                                          true));
+        dbMeta.put(hsqldb_log_data,
+                   HsqlProperties.getMeta(hsqldb_log_data, SQL_PROPERTY,
+                                          true));
+        dbMeta.put(hsqldb_nio_data_file,
+                   HsqlProperties.getMeta(hsqldb_nio_data_file, SQL_PROPERTY,
+                                          true));
+
+        // char padding to size and exception if data is too long
+        dbMeta.put(sql_identity_is_pk,
+                   HsqlProperties.getMeta(sql_identity_is_pk, SQL_PROPERTY,
+                                          false));
+        dbMeta.put(sql_ref_integrity,
+                   HsqlProperties.getMeta(sql_ref_integrity, SQL_PROPERTY,
+                                          true));
+        dbMeta.put(sql_enforce_refs,
+                   HsqlProperties.getMeta(sql_enforce_refs, SQL_PROPERTY,
+                                          false));
+        dbMeta.put(sql_enforce_size,
+                   HsqlProperties.getMeta(sql_enforce_size, SQL_PROPERTY,
+                                          true));
+        dbMeta.put(sql_enforce_strict_size,
+                   HsqlProperties.getMeta(sql_enforce_strict_size,
+                                          SQL_PROPERTY, true));
+
+        // SQL reserved words not allowed as some identifiers
+        dbMeta.put(sql_enforce_names,
+                   HsqlProperties.getMeta(sql_enforce_names, SQL_PROPERTY,
+                                          false));
+        dbMeta.put(sql_compare_in_locale,
+                   HsqlProperties.getMeta(sql_compare_in_locale, SQL_PROPERTY,
+                                          false));
+        dbMeta.put(hsqldb_write_delay,
+                   HsqlProperties.getMeta(hsqldb_write_delay, SQL_PROPERTY,
+                                          true));
+        dbMeta.put(hsqldb_write_delay_millis,
+                   HsqlProperties.getMeta(hsqldb_write_delay_millis,
+                                          SQL_PROPERTY, 500, 20, 10000));
+
+        // integral defaults for user-defined set props
+        dbMeta.put(hsqldb_applog,
+                   HsqlProperties.getMeta(hsqldb_applog, SQL_PROPERTY, 0, 0,
+                                          2));
+        dbMeta.put(hsqldb_script_format,
+                   HsqlProperties.getMeta(hsqldb_script_format, SQL_PROPERTY,
+                                          0, new int[] {
+            0, 1, 3
+        }));
+
+        // integral defaults for user defined range props
+        dbMeta.put(hsqldb_log_size,
+                   HsqlProperties.getMeta(hsqldb_log_size, SQL_PROPERTY, 50,
+                                          0, 1000));
+        dbMeta.put(hsqldb_defrag_limit,
+                   HsqlProperties.getMeta(hsqldb_defrag_limit, SQL_PROPERTY,
+                                          20, 0, 100));
+        dbMeta.put(runtime_gc_interval,
+                   HsqlProperties.getMeta(runtime_gc_interval, SQL_PROPERTY,
+                                          0, 0, 1000000));
+        dbMeta.put(hsqldb_cache_size,
+                   HsqlProperties.getMeta(hsqldb_cache_size, SQL_PROPERTY,
+                                          10000, 100, 1000000));
+        dbMeta.put(hsqldb_cache_rows,
+                   HsqlProperties.getMeta(hsqldb_cache_rows, SQL_PROPERTY,
+                                          50000, 100, 1000000));
+        dbMeta.put(hsqldb_cache_free_count_scale,
+                   HsqlProperties.getMeta(hsqldb_cache_free_count_scale,
+                                          SQL_PROPERTY, 9, 6, 12));
+        dbMeta.put(hsqldb_result_max_memory_rows,
+                   HsqlProperties.getMeta(hsqldb_result_max_memory_rows,
+                                          SQL_PROPERTY, 0, 0, 1000000));
+        dbMeta.put(hsqldb_max_nio_scale,
+                   HsqlProperties.getMeta(hsqldb_max_nio_scale, SQL_PROPERTY,
+                                          28, 24, 31));
+    }
+
+    private Database database;
+
+    public HsqlDatabaseProperties(Database db) {
+
+        super(dbMeta, db.getPath(), db.logger.getFileAccess(),
+              db.isFilesInJar());
+
+        database = db;
+
+        setNewDatabaseProperties();
+    }
+
+    void setNewDatabaseProperties() {
+
+        // version of a new database
+        setProperty(hsqldb_version, THIS_VERSION);
+        setProperty(hsqldb_modified, "no-new-files");
+
+        // OOo related code
+        if (database.logger.isStoredFileAccess()) {
+            setProperty(hsqldb_cache_rows, 25000);
+            setProperty(hsqldb_cache_size, 6000);
+            setProperty(hsqldb_log_size, 10);
+            setProperty(sql_enforce_size, true);
+            setProperty(hsqldb_nio_data_file, false);
+            setProperty(hsqldb_lock_file, true);
+            setProperty(hsqldb_default_table_type, "cached");
+            setProperty(jdbc_translate_dti_types, true);
+        }
+
+        // OOo end
+    }
+
+    /**
+     * Creates file with defaults if it didn't exist.
+     * Returns false if file already existed.
+     */
+    public boolean load() {
+
+        boolean exists;
+
+        if (!DatabaseURL.isFileBasedDatabaseType(database.getType())) {
+            return true;
+        }
+
+        try {
+            exists = super.load();
+        } catch (Throwable t) {
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_LOAD_SAVE_PROPERTIES, new Object[] {
+                t.getMessage(), fileName
+            });
+        }
+
+        if (!exists) {
+            return false;
+        }
+
+        filterLoadedProperties();
+
+        String version = getStringProperty(hsqldb_version);
+        int    check = version.substring(0, 5).compareTo(VERSION_STRING_1_8_0);
+
+        // do not open early version databases
+        if (check < 0) {
+            throw Error.error(ErrorCode.WRONG_DATABASE_FILE_VERSION);
+        }
+
+        check = version.substring(0, 5).compareTo(THIS_VERSION);
+
+        // do not open if the database belongs to a later (future) version
+        if (check > 0) {
+            throw Error.error(ErrorCode.WRONG_DATABASE_FILE_VERSION);
+        }
+
+        // do not open modified databases of compatible earlier versions
+        if (check < 0) {
+            if (!MODIFIED_NO.equals(getStringProperty(hsqldb_modified))) {
+                throw Error.error(ErrorCode.SHUTDOWN_REQUIRED);
+            }
+        }
+
+        if (getIntegerProperty(hsqldb_script_format) != 0) {
+            throw Error.error(ErrorCode.WRONG_DATABASE_FILE_VERSION);
+        }
+
+        return true;
+    }
+
+    public void save() {
+
+        if (!DatabaseURL.isFileBasedDatabaseType(database.getType())
+                || database.isFilesReadOnly() || database.isFilesInJar()) {
+            return;
+        }
+
+        try {
+            HsqlProperties props = new HsqlProperties(dbMeta,
+                database.getPath(), database.logger.getFileAccess(), false);
+
+            props.setProperty(hsqldb_version, THIS_VERSION);
+            props.setProperty(hsqldb_modified, getProperty(hsqldb_modified));
+            props.save(fileName + ".properties" + ".new");
+            fa.renameElement(fileName + ".properties" + ".new",
+                             fileName + ".properties");
+        } catch (Throwable t) {
+            database.logger.logSevereEvent("save failed", t);
+
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_LOAD_SAVE_PROPERTIES, new Object[] {
+                t.getMessage(), fileName
+            });
+        }
+    }
+
+    void filterLoadedProperties() {
+
+        Enumeration en = stringProps.propertyNames();
+
+        while (en.hasMoreElements()) {
+            String  key    = (String) en.nextElement();
+            boolean accept = dbMeta.containsKey(key);
+
+            if (!accept) {
+                stringProps.remove(key);
+            }
+        }
+    }
+
+    /**
+     *  overload file database properties with any passed on URL line
+     *  do not store password etc
+     */
+    public void setURLProperties(HsqlProperties p) {
+
+        boolean strict = false;
+
+        if (p == null) {
+            return;
+        }
+
+        strict = p.isPropertyTrue(url_check_props, false);
+
+        for (Enumeration e = p.propertyNames(); e.hasMoreElements(); ) {
+            String   propertyName = (String) e.nextElement();
+            Object[] row          = (Object[]) dbMeta.get(propertyName);
+            boolean  valid        = false;
+            boolean  validVal     = false;
+
+            if (row != null
+                    && ((Integer) row[HsqlProperties.indexType]).intValue()
+                       == SQL_PROPERTY) {
+                valid = true;
+                validVal = setDatabaseProperty(propertyName,
+                                               p.getProperty(propertyName));
+            }
+
+            if (propertyName.startsWith("sql.")
+                    || propertyName.startsWith("hsqldb.")
+                    || propertyName.startsWith("textdb.")) {
+                if (strict && !valid) {
+                    throw Error.error(ErrorCode.X_42555, propertyName);
+                }
+
+                if (strict && !validVal) {
+                    throw Error.error(ErrorCode.X_42556, propertyName);
+                }
+            }
+        }
+    }
+
+    public Set getUserDefinedPropertyData() {
+
+        Set      set = new HashSet();
+        Iterator it  = dbMeta.values().iterator();
+
+        while (it.hasNext()) {
+            Object[] row = (Object[]) it.next();
+
+            if (((Integer) row[HsqlProperties.indexType]).intValue()
+                    == SQL_PROPERTY) {
+                set.add(row);
+            }
+        }
+
+        return set;
+    }
+
+    public boolean isUserDefinedProperty(String key) {
+
+        Object[] row = (Object[]) dbMeta.get(key);
+
+        return row != null
+               && ((Integer) row[HsqlProperties.indexType]).intValue()
+                  == SQL_PROPERTY;
+    }
+
+    public boolean isBoolean(String key) {
+
+        Object[] row = (Object[]) dbMeta.get(key);
+
+        return row != null && row[HsqlProperties.indexClass].equals("Boolean")
+               && ((Integer) row[HsqlProperties.indexType]).intValue()
+                  == SQL_PROPERTY;
+    }
+
+    public boolean isIntegral(String key) {
+
+        Object[] row = (Object[]) dbMeta.get(key);
+
+        return row != null && row[HsqlProperties.indexClass].equals("Integer")
+               && ((Integer) row[HsqlProperties.indexType]).intValue()
+                  == SQL_PROPERTY;
+    }
+
+    public boolean isString(String key) {
+
+        Object[] row = (Object[]) dbMeta.get(key);
+
+        return row != null && row[HsqlProperties.indexClass].equals("String")
+               && ((Integer) row[HsqlProperties.indexType]).intValue()
+                  == SQL_PROPERTY;
+    }
+
+    public boolean setDatabaseProperty(String key, String value) {
+
+        Object[] meta  = (Object[]) dbMeta.get(key);
+        String   error = HsqlProperties.validateProperty(key, value, meta);
+
+        if (error != null) {
+            return false;
+        }
+
+        stringProps.put(key, value);
+
+        return true;
+    }
+
+    public int getDefaultWriteDelay() {
+
+        // OOo related code
+        if (database.logger.isStoredFileAccess()) {
+            return 2000;
+        }
+
+        // OOo end
+        return 10000;
+    }
+
+//---------------------
+// new properties to review / persist
+    public final static int NO_MESSAGE = 1;
+
+    public int getErrorLevel() {
+
+        //      return 0;
+        return NO_MESSAGE;
+    }
+
+    public boolean divisionByZero() {
+        return false;
+    }
+
+//------------------------
+    public void setDBModified(int mode) {
+
+        String value = MODIFIED_NO;
+
+        if (mode == FILES_MODIFIED) {
+            value = MODIFIED_YES;
+        } else if (mode == FILES_NEW) {
+            value = MODIFIED_NEW;
+        }
+
+        stringProps.put(hsqldb_modified, value);
+        save();
+    }
+
+    public int getDBModified() {
+
+        String value = getStringProperty("modified");
+
+        if (MODIFIED_YES.equals(value)) {
+            return FILES_MODIFIED;
+        } else if (MODIFIED_NEW.equals(value)) {
+            return FILES_NEW;
+        }
+
+        return FILES_NOT_MODIFIED;
+    }
+
+//-----------------------
+    public String getProperty(String key) {
+
+        Object[] metaData = (Object[]) dbMeta.get(key);
+
+        if (metaData == null) {
+            throw Error.error(ErrorCode.X_42555, key);
+        }
+
+        return stringProps.getProperty(key);
+    }
+
+    public boolean isPropertyTrue(String key) {
+
+        Boolean  value;
+        Object[] metaData = (Object[]) dbMeta.get(key);
+
+        if (metaData == null) {
+            throw Error.error(ErrorCode.X_42555, key);
+        }
+
+        value = (Boolean) metaData[HsqlProperties.indexDefaultValue];
+
+        String prop = stringProps.getProperty(key);
+        boolean isSystem =
+            ((Integer) metaData[HsqlProperties.indexType]).intValue()
+            == SYSTEM_PROPERTY;
+
+        if (prop == null && isSystem) {
+            prop = System.getProperty(key);
+        }
+
+        if (prop != null) {
+            value = Boolean.valueOf(prop);
+        }
+
+        return value.booleanValue();
+    }
+
+    public String getStringProperty(String key) {
+
+        String   value;
+        Object[] metaData = (Object[]) dbMeta.get(key);
+
+        if (metaData == null) {
+            throw Error.error(ErrorCode.X_42555, key);
+        }
+
+        value = (String) metaData[HsqlProperties.indexDefaultValue];
+
+        String prop = stringProps.getProperty(key);
+
+        if (prop != null) {
+            value = prop;
+        }
+
+        return value;
+    }
+
+    public int getIntegerProperty(String key) {
+
+        int      value;
+        Object[] metaData = (Object[]) dbMeta.get(key);
+
+        if (metaData == null) {
+            throw Error.error(ErrorCode.X_42555, key);
+        }
+
+        value =
+            ((Integer) metaData[HsqlProperties.indexDefaultValue]).intValue();
+
+        String prop = stringProps.getProperty(key);
+
+        if (prop != null) {
+            try {
+                value = Integer.parseInt(prop);
+            } catch (NumberFormatException e) {}
+        }
+
+        return value;
+    }
+
+    public static Iterator getPropertiesMetaIterator() {
+        return dbMeta.values().iterator();
+    }
+
+    public String getClientPropertiesAsString() {
+
+        if (isPropertyTrue(jdbc_translate_dti_types)) {
+            StringBuffer sb = new StringBuffer(jdbc_translate_dti_types);
+
+            sb.append('=').append(true);
+        }
+
+        return "";
+    }
+
+    public boolean isVersion18() {
+
+        String version =
+            getStringProperty(HsqlDatabaseProperties.hsqldb_version);
+
+        return version.substring(0, 4).equals("1.8.");
+    }
+}
diff --git a/src/org/hsqldb/persist/HsqlProperties.java b/src/org/hsqldb/persist/HsqlProperties.java
new file mode 100644
index 0000000..1546f0b
--- /dev/null
+++ b/src/org/hsqldb/persist/HsqlProperties.java
@@ -0,0 +1,526 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.FileAccess;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Wrapper for java.util.Properties to limit values to Specific types and
+ * allow saving and loading.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class HsqlProperties {
+
+    //
+    public static final int NO_VALUE_FOR_KEY = 1;
+    protected String        fileName;
+    protected Properties    stringProps;
+    protected int[]         errorCodes = ValuePool.emptyIntArray;
+    protected String[]      errorKeys  = ValuePool.emptyStringArray;
+    protected boolean       resource   = false;
+    protected FileAccess    fa;
+    protected HashMap       metaData;
+
+    public HsqlProperties() {
+        stringProps = new Properties();
+        fileName    = null;
+    }
+
+    public HsqlProperties(String fileName) {
+
+        stringProps   = new Properties();
+        this.fileName = fileName;
+        fa            = FileUtil.getFileUtil();
+    }
+
+    public HsqlProperties(HashMap meta, String fileName, FileAccess accessor,
+                          boolean b) {
+
+        stringProps   = new Properties();
+        this.fileName = fileName;
+        fa            = accessor;
+        metaData      = meta;
+    }
+
+    public HsqlProperties(Properties props) {
+        stringProps = props;
+    }
+
+    public void setFileName(String name) {
+        fileName = name;
+    }
+
+    public String setProperty(String key, int value) {
+        return setProperty(key, Integer.toString(value));
+    }
+
+    public String setProperty(String key, boolean value) {
+        return setProperty(key, String.valueOf(value));
+    }
+
+    public String setProperty(String key, String value) {
+        return (String) stringProps.put(key, value);
+    }
+
+    public String setPropertyIfNotExists(String key, String value) {
+
+        value = getProperty(key, value);
+
+        return setProperty(key, value);
+    }
+
+    public Properties getProperties() {
+        return stringProps;
+    }
+
+    public String getProperty(String key) {
+        return stringProps.getProperty(key);
+    }
+
+    public String getProperty(String key, String defaultValue) {
+        return stringProps.getProperty(key, defaultValue);
+    }
+
+    public int getIntegerProperty(String key, int defaultValue) {
+
+        String prop = getProperty(key);
+
+        try {
+            if (prop != null) {
+                defaultValue = Integer.parseInt(prop);
+            }
+        } catch (NumberFormatException e) {}
+
+        return defaultValue;
+    }
+
+    public boolean isPropertyTrue(String key) {
+        return isPropertyTrue(key, false);
+    }
+
+    public boolean isPropertyTrue(String key, boolean defaultValue) {
+
+        String value = stringProps.getProperty(key);
+
+        if (value == null) {
+            return defaultValue;
+        }
+
+        return value.toLowerCase().equals("true");
+    }
+
+    public void removeProperty(String key) {
+        stringProps.remove(key);
+    }
+
+    public void addProperties(Properties props) {
+
+        if (props == null) {
+            return;
+        }
+
+        Enumeration keys = props.propertyNames();
+
+        while (keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+            String value = props.getProperty(key);
+            this.stringProps.put(key, value);
+        }
+    }
+
+    public void addProperties(HsqlProperties props) {
+
+        if (props == null) {
+            return;
+        }
+
+        addProperties(props.stringProps);
+    }
+
+// oj@openoffice.org
+    public boolean propertiesFileExists() {
+
+        String propFilename = fileName + ".properties";
+
+        return fa.isStreamElement(propFilename);
+    }
+
+    public boolean load() throws Exception {
+
+        if (!propertiesFileExists()) {
+            return false;
+        }
+
+        if (fileName == null || fileName.length() == 0) {
+            throw new FileNotFoundException(
+                Error.getMessage(ErrorCode.M_HsqlProperties_load));
+        }
+
+        InputStream fis           = null;
+        String      propsFilename = fileName + ".properties";
+
+// oj@openoffice.org
+        try {
+            fis = fa.openInputStreamElement(propsFilename);
+
+            stringProps.load(fis);
+        } finally {
+            if (fis != null) {
+                fis.close();
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     *  Saves the properties.
+     */
+    public void save() throws Exception {
+
+        if (fileName == null || fileName.length() == 0) {
+            throw new java.io.FileNotFoundException(
+                Error.getMessage(ErrorCode.M_HsqlProperties_load));
+        }
+
+        String filestring = fileName + ".properties";
+
+        save(filestring);
+    }
+
+    /**
+     *  Saves the properties using JDK2 method if present, otherwise JDK1.
+     */
+    public void save(String fileString) throws Exception {
+
+// oj@openoffice.org
+        fa.createParentDirs(fileString);
+
+        OutputStream        fos = fa.openOutputStreamElement(fileString);
+        FileAccess.FileSync outDescriptor = fa.getFileSync(fos);
+
+        JavaSystem.saveProperties(
+            stringProps,
+            HsqlDatabaseProperties.PRODUCT_NAME + " "
+            + HsqlDatabaseProperties.THIS_FULL_VERSION, fos);
+        fos.flush();
+        outDescriptor.sync();
+        fos.close();
+
+        return;
+    }
+
+    /**
+     * Adds the error code and the key to the list of errors. This list
+     * is populated during construction or addition of elements and is used
+     * outside this class to act upon the errors.
+     */
+    private void addError(int code, String key) {
+
+        errorCodes = (int[]) ArrayUtil.resizeArray(errorCodes,
+                errorCodes.length + 1);
+        errorKeys = (String[]) ArrayUtil.resizeArray(errorKeys,
+                errorKeys.length + 1);
+        errorCodes[errorCodes.length - 1] = code;
+        errorKeys[errorKeys.length - 1]   = key;
+    }
+
+    /**
+     * Creates and populates an HsqlProperties Object from the arguments
+     * array of a Main method. Properties are in the form of "-key value"
+     * pairs. Each key is prefixed with the type argument and a dot before
+     * being inserted into the properties Object. <p>
+     *
+     * "--help" is treated as a key with no value and not inserted.
+     */
+    public static HsqlProperties argArrayToProps(String[] arg, String type) {
+
+        HsqlProperties props = new HsqlProperties();
+
+        for (int i = 0; i < arg.length; i++) {
+            String p = arg[i];
+
+            if (p.equals("--help") || p.equals("-help")) {
+                props.addError(NO_VALUE_FOR_KEY, p.substring(1));
+            } else if (p.startsWith("--")) {
+                String value = i + 1 < arg.length ? arg[i + 1]
+                                                  : "";
+
+                props.setProperty(type + "." + p.substring(2), value);
+
+                i++;
+            } else if (p.charAt(0) == '-') {
+                String value = i + 1 < arg.length ? arg[i + 1]
+                                                  : "";
+
+                props.setProperty(type + "." + p.substring(1), value);
+
+                i++;
+            }
+        }
+
+        return props;
+    }
+
+    /**
+     * Creates and populates a new HsqlProperties Object using a string
+     * such as "key1=value1;key2=value2". <p>
+     *
+     * The string that represents the = sign above is specified as pairsep
+     * and the one that represents the semicolon is specified as delimiter,
+     * allowing any string to be used for either.<p>
+     *
+     * Leading / trailing spaces around the keys and values are discarded.<p>
+     *
+     * The string is parsed by (1) subdividing into segments by delimiter
+     * (2) subdividing each segment in two by finding the first instance of
+     * the pairsep (3) trimming each pair of segments from step 2 and
+     * inserting into the properties object.<p>
+     *
+     * Each key is prefixed with the type argument and a dot before being
+     * inserted.<p>
+     *
+     * Any key without a value is added to the list of errors.
+     */
+    public static HsqlProperties delimitedArgPairsToProps(String s,
+            String pairsep, String dlimiter, String type) {
+
+        HsqlProperties props       = new HsqlProperties();
+        int            currentpair = 0;
+
+        while (true) {
+            int nextpair = s.indexOf(dlimiter, currentpair);
+
+            if (nextpair == -1) {
+                nextpair = s.length();
+            }
+
+            // find value within the segment
+            int valindex = s.substring(0, nextpair).indexOf(pairsep,
+                                       currentpair);
+
+            if (valindex == -1) {
+                props.addError(NO_VALUE_FOR_KEY,
+                               s.substring(currentpair, nextpair).trim());
+            } else {
+                String key = s.substring(currentpair, valindex).trim();
+                String value = s.substring(valindex + pairsep.length(),
+                                           nextpair).trim();
+
+                if (type != null) {
+                    key = type + "." + key;
+                }
+
+                props.setProperty(key, value);
+            }
+
+            if (nextpair == s.length()) {
+                break;
+            }
+
+            currentpair = nextpair + dlimiter.length();
+        }
+
+        return props;
+    }
+
+    public Enumeration propertyNames() {
+        return stringProps.propertyNames();
+    }
+
+    public boolean isEmpty() {
+        return stringProps.isEmpty();
+    }
+
+    public String[] getErrorKeys() {
+        return errorKeys;
+    }
+
+    // column number mappings
+    public static final int indexName         = 0;
+    public static final int indexType         = 1;
+    public static final int indexClass        = 2;
+    public static final int indexIsRange      = 3;
+    public static final int indexDefaultValue = 4;
+    public static final int indexRangeLow     = 5;
+    public static final int indexRangeHigh    = 6;
+    public static final int indexValues       = 7;
+    public static final int indexLimit        = 9;
+
+    public static Object[] getMeta(String name, int type,
+                                   String defaultValue) {
+
+        Object[] row = new Object[indexLimit];
+
+        row[indexName]         = name;
+        row[indexType]         = ValuePool.getInt(type);
+        row[indexClass]        = "String";
+        row[indexDefaultValue] = defaultValue;
+
+        return row;
+    }
+
+    public static Object[] getMeta(String name, int type,
+                                   boolean defaultValue) {
+
+        Object[] row = new Object[indexLimit];
+
+        row[indexName]         = name;
+        row[indexType]         = ValuePool.getInt(type);
+        row[indexClass]        = "Boolean";
+        row[indexDefaultValue] = defaultValue ? Boolean.TRUE
+                                              : Boolean.FALSE;
+
+        return row;
+    }
+
+    public static Object[] getMeta(String name, int type, int defaultValue,
+                                   int[] values) {
+
+        Object[] row = new Object[indexLimit];
+
+        row[indexName]         = name;
+        row[indexType]         = ValuePool.getInt(type);
+        row[indexClass]        = "Integer";
+        row[indexDefaultValue] = ValuePool.getInt(defaultValue);
+        row[indexValues]       = values;
+
+        return row;
+    }
+
+    public static Object[] getMeta(String name, int type, int defaultValue,
+                                   int rangeLow, int rangeHigh) {
+
+        Object[] row = new Object[indexLimit];
+
+        row[indexName]         = name;
+        row[indexType]         = ValuePool.getInt(type);
+        row[indexClass]        = "Integer";
+        row[indexDefaultValue] = ValuePool.getInt(defaultValue);
+        row[indexIsRange]      = Boolean.TRUE;
+        row[indexRangeLow]     = ValuePool.getInt(rangeLow);
+        row[indexRangeHigh]    = ValuePool.getInt(rangeHigh);
+
+        return row;
+    }
+
+    /**
+     * Perfoms any range checking for property and return an error message
+     */
+    public static String validateProperty(String key, String value,
+                                          Object[] meta) {
+
+        if (meta[indexClass].equals("Boolean")) {
+            value = value.toLowerCase();
+
+            if (value.equals("true") || value.equals("false")) {
+                return null;
+            }
+
+            return "invalid boolean value for property: " + key;
+        }
+
+        if (meta[indexClass].equals("String")) {
+            return null;
+        }
+
+        if (meta[indexClass].equals("Integer")) {
+            int number = Integer.parseInt(value);
+
+            if (Boolean.TRUE.equals(meta[indexIsRange])) {
+                int low  = ((Integer) meta[indexRangeLow]).intValue();
+                int high = ((Integer) meta[indexRangeHigh]).intValue();
+
+                if (number < low || high < number) {
+                    return "value outside range for property: " + key;
+                }
+            }
+
+            if (meta[indexValues] != null) {
+                int[] values = (int[]) meta[indexValues];
+
+                if (ArrayUtil.find(values, number) == -1) {
+                    return "value not supported for property: " + key;
+                }
+            }
+
+            return null;
+        }
+
+        return null;
+    }
+
+    public String toString() {
+
+        StringBuffer sb;
+
+        sb = new StringBuffer();
+
+        sb.append('[');
+
+        int         len = stringProps.size();
+        Enumeration en  = stringProps.propertyNames();
+
+        for (int i = 0; i < len; i++) {
+            String key = (String) en.nextElement();
+
+            sb.append(key);
+            sb.append('=');
+            sb.append(stringProps.get(key));
+
+            if (i + 1 < len) {
+                sb.append(',');
+                sb.append(' ');
+            }
+
+            sb.append(']');
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/persist/LobManager.java b/src/org/hsqldb/persist/LobManager.java
new file mode 100644
index 0000000..637c668
--- /dev/null
+++ b/src/org/hsqldb/persist/LobManager.java
@@ -0,0 +1,1326 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+
+import org.hsqldb.Database;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.HsqlException;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.Session;
+import org.hsqldb.Statement;
+import org.hsqldb.Table;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.LineGroupReader;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultLob;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.Types;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class LobManager {
+
+    static final String resourceFileName =
+        "/org/hsqldb/resources/lob-schema.sql";
+    static final String[] starters = new String[]{ "/*" };
+
+    //
+    Database database;
+    LobStore lobStore;
+    Session  sysLobSession;
+
+    //
+    //
+    int lobBlockSize;
+    int totalBlockLimitCount = Integer.MAX_VALUE;
+
+    //
+    int deletedLobCount;
+
+    //
+    Statement getLob;
+    Statement getLobPart;
+    Statement deleteLobCall;
+    Statement deleteLobPartCall;
+    Statement divideLobPartCall;
+    Statement createLob;
+    Statement createLobPartCall;
+    Statement updateLobLength;
+    Statement updateLobUsage;
+    Statement getNextLobId;
+    Statement deleteUnusedLobs;
+    Statement getLobCount;
+
+    // LOBS columns
+    private interface LOBS {
+
+        int BLOCK_ADDR   = 0;
+        int BLOCK_COUNT  = 1;
+        int BLOCK_OFFSET = 2;
+        int LOB_ID       = 3;
+    }
+
+    private interface LOB_IDS {
+
+        int LOB_ID          = 0;
+        int LOB_LENGTH      = 1;
+        int LOB_USAGE_COUNT = 2;
+        int LOB_TYPE        = 3;
+    }
+
+    private interface GET_LOB_PART {
+
+        int LOB_ID       = 0;
+        int BLOCK_OFFSET = 1;
+        int BLOCK_LIMIT  = 2;
+    }
+
+    private interface DIVIDE_BLOCK {
+        int BLOCK_OFFSET = 0;
+        int LOB_ID       = 1;
+    }
+
+    private interface DELETE_BLOCKS {
+
+        int LOB_ID       = 0;
+        int BLOCK_OFFSET = 1;
+        int BLOCK_LIMIT  = 2;
+        int TX_ID        = 3;
+    }
+
+    private interface ALLOC_BLOCKS {
+
+        int BLOCK_COUNT  = 0;
+        int BLOCK_OFFSET = 1;
+        int LOB_ID       = 2;
+    }
+
+    private interface UPDATE_USAGE {
+        int BLOCK_COUNT = 0;
+        int LOB_ID      = 1;
+    }
+
+    private interface UPDATE_LENGTH {
+        int LOB_LENGTH = 0;
+        int LOB_ID     = 1;
+    }
+
+    //BLOCK_ADDR INT, BLOCK_COUNT INT, TX_ID BIGINT
+    private static String initialiseBlocksSQL =
+        "INSERT INTO SYSTEM_LOBS.BLOCKS VALUES(?,?,?)";
+    private static String getLobSQL =
+        "SELECT * FROM SYSTEM_LOBS.LOB_IDS WHERE LOB_ID = ?";
+    private static String getLobPartSQL =
+        "SELECT * FROM SYSTEM_LOBS.LOBS WHERE LOB_ID = ? AND BLOCK_OFFSET + BLOCK_COUNT > ? AND BLOCK_OFFSET < ? ORDER BY BLOCK_OFFSET";
+    private static String deleteLobPartCallSQL =
+        "CALL SYSTEM_LOBS.DELETE_BLOCKS(?,?,?,?)";
+    private static String createLobSQL =
+        "INSERT INTO SYSTEM_LOBS.LOB_IDS VALUES(?, ?, ?, ?)";
+    private static String updateLobLengthSQL =
+        "UPDATE SYSTEM_LOBS.LOB_IDS SET LOB_LENGTH = ? WHERE LOB_ID = ?";
+    private static String createLobPartCallSQL =
+        "CALL SYSTEM_LOBS.ALLOC_BLOCKS(?, ?, ?)";
+    private static String divideLobPartCallSQL =
+        "CALL SYSTEM_LOBS.DIVIDE_BLOCK(?, ?)";
+    private static String getSpanningBlockSQL =
+        "SELECT * FROM SYSTEM_LOBS.LOBS WHERE LOB_ID = ? AND ? > BLOCK_OFFSET AND ? < BLOCK_OFFSET + BLOCK_COUNT";
+    private static String updateLobUsageSQL =
+        "UPDATE SYSTEM_LOBS.LOB_IDS SET LOB_USAGE_COUNT = ? WHERE LOB_ID = ?";
+    private static String getNextLobIdSQL =
+        "VALUES NEXT VALUE FOR SYSTEM_LOBS.LOB_ID";
+    private static String deleteLobCallSQL =
+        "CALL SYSTEM_LOBS.DELETE_LOB(?, ?)";
+    private static String deleteUnusedCallSQL =
+        "CALL SYSTEM_LOBS.DELETE_UNUSED()";
+    private static String getLobCountSQL =
+        "SELECT COUNT(*) FROM SYSTEM_LOBS.LOB_IDS";
+
+    public LobManager(Database database) {
+        this.database = database;
+    }
+
+    synchronized public void createSchema() {
+
+        sysLobSession = database.sessionManager.getSysLobSession();
+
+        InputStream fis = getClass().getResourceAsStream(resourceFileName);
+        InputStreamReader reader = null;
+
+        try {
+            reader = new InputStreamReader(fis, "ISO-8859-1");
+        } catch (Exception e) {}
+
+        LineNumberReader lineReader = new LineNumberReader(reader);
+        LineGroupReader  lg = new LineGroupReader(lineReader, starters);
+        HashMappedList   map        = lg.getAsMap();
+
+        lg.close();
+
+        String sql = (String) map.get("/*lob_schema_definition*/");
+        Statement statement = sysLobSession.compileStatement(sql,
+            ResultProperties.defaultPropsValue);
+        Result result = statement.execute(sysLobSession);
+
+        if (result.isError()) {
+            throw result.getException();
+        }
+
+        HsqlName name =
+            database.schemaManager.getSchemaHsqlName("SYSTEM_LOBS");
+        Table table = database.schemaManager.getTable(sysLobSession, "BLOCKS",
+            "SYSTEM_LOBS");
+
+        getLob = sysLobSession.compileStatement(getLobSQL,
+                ResultProperties.defaultPropsValue);
+        getLobPart = sysLobSession.compileStatement(getLobPartSQL,
+                ResultProperties.defaultPropsValue);
+        createLob = sysLobSession.compileStatement(createLobSQL,
+                ResultProperties.defaultPropsValue);
+        createLobPartCall =
+            sysLobSession.compileStatement(createLobPartCallSQL,
+                                           ResultProperties.defaultPropsValue);
+        divideLobPartCall =
+            sysLobSession.compileStatement(divideLobPartCallSQL,
+                                           ResultProperties.defaultPropsValue);
+        deleteLobCall = sysLobSession.compileStatement(deleteLobCallSQL,
+                ResultProperties.defaultPropsValue);
+        deleteLobPartCall =
+            sysLobSession.compileStatement(deleteLobPartCallSQL,
+                                           ResultProperties.defaultPropsValue);
+        updateLobLength = sysLobSession.compileStatement(updateLobLengthSQL,
+                ResultProperties.defaultPropsValue);
+        updateLobUsage = sysLobSession.compileStatement(updateLobUsageSQL,
+                ResultProperties.defaultPropsValue);
+        getNextLobId = sysLobSession.compileStatement(getNextLobIdSQL,
+                ResultProperties.defaultPropsValue);
+        deleteUnusedLobs = sysLobSession.compileStatement(deleteUnusedCallSQL,
+                ResultProperties.defaultPropsValue);
+        getLobCount = sysLobSession.compileStatement(getLobCountSQL,
+                ResultProperties.defaultPropsValue);
+    }
+
+    synchronized public void initialiseLobSpace() {
+
+        Statement statement =
+            sysLobSession.compileStatement(initialiseBlocksSQL,
+                                           ResultProperties.defaultPropsValue);
+        Object[] params = new Object[3];
+
+        params[0] = ValuePool.INTEGER_0;
+        params[1] = ValuePool.getInt(totalBlockLimitCount);
+        params[2] = ValuePool.getLong(0);
+
+        sysLobSession.executeCompiledStatement(statement, params);
+    }
+
+    synchronized public void open() {
+
+        if (lobStore != null) {
+            return;
+        }
+
+        lobBlockSize = database.logger.getLobBlockSize();
+
+        if (database.getType() == DatabaseURL.S_RES) {
+            lobStore = new LobStoreInJar(database, lobBlockSize);
+        } else if (database.getType() == DatabaseURL.S_FILE) {
+            lobStore = new LobStoreRAFile(database, lobBlockSize);
+        } else {
+            lobStore = new LobStoreMem(lobBlockSize);
+        }
+    }
+
+    synchronized public void close() {
+        lobStore.close();
+    }
+
+    LobStore getLobStore() {
+
+        if (lobStore == null) {
+            open();
+        }
+
+        return lobStore;
+    }
+
+    //
+    private long getNewLobID() {
+
+        Result result = getNextLobId.execute(sysLobSession);
+
+        if (result.isError()) {
+            return 0;
+        }
+
+        RowSetNavigator navigator = result.getNavigator();
+        boolean         next      = navigator.next();
+
+        if (!next) {
+            navigator.close();
+
+            return 0;
+        }
+
+        Object[] data = navigator.getCurrent();
+
+        return ((Long) data[0]).longValue();
+    }
+
+    private Object[] getLobHeader(long lobID) {
+
+        ResultMetaData meta     = getLob.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[0] = ValuePool.getLong(lobID);
+
+        sysLobSession.sessionContext.pushDynamicArguments(params);
+
+        Result result = getLob.execute(sysLobSession);
+
+        sysLobSession.sessionContext.pop();
+
+        if (result.isError()) {
+            return null;
+        }
+
+        RowSetNavigator navigator = result.getNavigator();
+        boolean         next      = navigator.next();
+
+        if (!next) {
+            navigator.close();
+
+            return null;
+        }
+
+        Object[] data = navigator.getCurrent();
+
+        return data;
+    }
+
+    synchronized public BlobData getBlob(long lobID) {
+
+        Object[] data = getLobHeader(lobID);
+
+        if (data == null) {
+            return null;
+        }
+
+        BlobData blob = new BlobDataID(lobID);
+
+        return blob;
+    }
+
+    synchronized public ClobData getClob(long lobID) {
+
+        Object[] data = getLobHeader(lobID);
+
+        if (data == null) {
+            return null;
+        }
+
+        ClobData clob = new ClobDataID(lobID);
+
+        return clob;
+    }
+
+    synchronized public long createBlob(long length) {
+
+        long           lobID    = getNewLobID();
+        ResultMetaData meta     = createLob.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[LOB_IDS.LOB_ID]          = ValuePool.getLong(lobID);
+        params[LOB_IDS.LOB_LENGTH]      = ValuePool.getLong(length);
+        params[LOB_IDS.LOB_USAGE_COUNT] = ValuePool.INTEGER_0;
+        params[LOB_IDS.LOB_TYPE]        = ValuePool.getInt(Types.SQL_BLOB);
+
+        Result result = sysLobSession.executeCompiledStatement(createLob,
+            params);
+
+        return lobID;
+    }
+
+    synchronized public long createClob(long length) {
+
+        long           lobID    = getNewLobID();
+        ResultMetaData meta     = createLob.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[LOB_IDS.LOB_ID]          = ValuePool.getLong(lobID);
+        params[LOB_IDS.LOB_LENGTH]      = ValuePool.getLong(length);
+        params[LOB_IDS.LOB_USAGE_COUNT] = ValuePool.INTEGER_0;
+        params[LOB_IDS.LOB_TYPE]        = ValuePool.getInt(Types.SQL_CLOB);
+
+        Result result = sysLobSession.executeCompiledStatement(createLob,
+            params);
+
+        return lobID;
+    }
+
+    synchronized public Result deleteLob(long lobID) {
+
+        ResultMetaData meta     = deleteLobCall.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[0] = ValuePool.getLong(lobID);
+        params[1] = ValuePool.getLong(0);
+
+        Result result = sysLobSession.executeCompiledStatement(deleteLobCall,
+            params);
+
+        return result;
+    }
+
+    synchronized public Result deleteUnusedLobs() {
+
+        Result result =
+            sysLobSession.executeCompiledStatement(deleteUnusedLobs,
+                ValuePool.emptyObjectArray);
+
+        deletedLobCount = 0;
+
+        return result;
+    }
+
+    synchronized public Result getLength(long lobID) {
+
+        try {
+            Object[] data = getLobHeader(lobID);
+
+            if (data == null) {
+                throw Error.error(ErrorCode.X_0F502);
+            }
+
+            long length = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+            int  type   = ((Integer) data[LOB_IDS.LOB_TYPE]).intValue();
+
+            return ResultLob.newLobSetResponse(lobID, length);
+        } catch (HsqlException e) {
+            return Result.newErrorResult(e);
+        }
+    }
+
+    synchronized public int compare(BlobData a, byte[] b) {
+
+        Object[] data    = getLobHeader(a.getId());
+        long     aLength = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+        int[][] aAddresses = getBlockAddresses(a.getId(), 0,
+                                               Integer.MAX_VALUE);
+        int aIndex  = 0;
+        int bOffset = 0;
+        int aOffset = 0;
+
+        while (true) {
+            int aBlockOffset = aAddresses[aIndex][LOBS.BLOCK_ADDR] + aOffset;
+            byte[] aBytes    = getLobStore().getBlockBytes(aBlockOffset, 1);
+
+            for (int i = 0; i < aBytes.length; i++) {
+                if (bOffset + i >= b.length) {
+                    if (aLength == b.length) {
+                        return 0;
+                    }
+
+                    return 1;
+                }
+
+                if (aBytes[i] == b[bOffset + i]) {
+                    continue;
+                }
+
+                return (((int) aBytes[i]) & 0xff)
+                       > (((int) b[bOffset + i]) & 0xff) ? 1
+                                                         : -1;
+            }
+
+            aOffset++;
+
+            bOffset += lobBlockSize;
+
+            if (aOffset == aAddresses[aIndex][LOBS.BLOCK_COUNT]) {
+                aOffset = 0;
+
+                aIndex++;
+            }
+
+            if (aIndex == aAddresses.length) {
+                break;
+            }
+        }
+
+        return -1;
+    }
+
+    synchronized public int compare(BlobData a, BlobData b) {
+
+        if (a.getId() == b.getId()) {
+            return 0;
+        }
+
+        Object[] data = getLobHeader(a.getId());
+
+        // abnormal case
+        if (data == null) {
+            return 1;
+        }
+
+        long lengthA = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+
+        data = getLobHeader(b.getId());
+
+        // abnormal case
+        if (data == null) {
+            return -1;
+        }
+
+        long lengthB = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+
+        if (lengthA > lengthB) {
+            return 1;
+        }
+
+        if (lengthA < lengthB) {
+            return -1;
+        }
+
+        return compareBytes(a.getId(), b.getId());
+    }
+
+    // todo - implement as compareText()
+    synchronized public int compare(ClobData a, String b) {
+
+        Object[] data    = getLobHeader(a.getId());
+        long     aLength = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+        int[][] aAddresses = getBlockAddresses(a.getId(), 0,
+                                               Integer.MAX_VALUE);
+        int aIndex  = 0;
+        int bOffset = 0;
+        int aOffset = 0;
+
+        while (true) {
+            int aBlockOffset = aAddresses[aIndex][LOBS.BLOCK_ADDR] + aOffset;
+            byte[] aBytes    = getLobStore().getBlockBytes(aBlockOffset, 1);
+            long aLimit = aLength
+                          - (aAddresses[aIndex][LOBS.BLOCK_OFFSET] + aOffset)
+                            * lobBlockSize / 2;
+
+            if (aLimit > lobBlockSize / 2) {
+                aLimit = lobBlockSize / 2;
+            }
+
+            String aString = new String(ArrayUtil.byteArrayToChars(aBytes), 0,
+                                        (int) aLimit);
+            int bLimit = b.length() - bOffset;
+
+            if (bLimit > lobBlockSize / 2) {
+                bLimit = lobBlockSize / 2;
+            }
+
+            String bString = b.substring(bOffset, bOffset + bLimit);
+            int    diff    = database.collation.compare(aString, bString);
+
+            if (diff != 0) {
+                return diff;
+            }
+
+            aOffset++;
+
+            bOffset += lobBlockSize / 2;
+
+            if (aOffset == aAddresses[aIndex][LOBS.BLOCK_COUNT]) {
+                aOffset = 0;
+
+                aIndex++;
+            }
+
+            if (aIndex == aAddresses.length) {
+                break;
+            }
+        }
+
+        return 0;
+    }
+
+    synchronized public int compare(ClobData a, ClobData b) {
+
+        if (a.getId() == b.getId()) {
+            return 0;
+        }
+
+        return compareText(a.getId(), b.getId());
+    }
+
+    synchronized int compareBytes(long aID, long bID) {
+
+        int[][] aAddresses = getBlockAddresses(aID, 0, Integer.MAX_VALUE);
+        int[][] bAddresses = getBlockAddresses(bID, 0, Integer.MAX_VALUE);
+        int     aIndex     = 0;
+        int     bIndex     = 0;
+        int     aOffset    = 0;
+        int     bOffset    = 0;
+
+        while (true) {
+            int aBlockOffset = aAddresses[aIndex][LOBS.BLOCK_ADDR] + aOffset;
+            int bBlockOffset = bAddresses[bIndex][LOBS.BLOCK_ADDR] + bOffset;
+            byte[] aBytes    = getLobStore().getBlockBytes(aBlockOffset, 1);
+            byte[] bBytes    = getLobStore().getBlockBytes(bBlockOffset, 1);
+
+            for (int i = 0; i < aBytes.length; i++) {
+                if (aBytes[i] == bBytes[i]) {
+                    continue;
+                }
+
+                return (((int) aBytes[i]) & 0xff) > (((int) bBytes[i]) & 0xff)
+                       ? 1
+                       : -1;
+            }
+
+            aOffset++;
+            bOffset++;
+
+            if (aOffset == aAddresses[aIndex][LOBS.BLOCK_COUNT]) {
+                aOffset = 0;
+
+                aIndex++;
+            }
+
+            if (bOffset == bAddresses[bIndex][LOBS.BLOCK_COUNT]) {
+                bOffset = 0;
+
+                bIndex++;
+            }
+
+            if (aIndex == aAddresses.length) {
+                break;
+            }
+        }
+
+        return 0;
+    }
+
+    /** @todo - word-separator and end block zero issues */
+    synchronized int compareText(long aID, long bID) {
+
+        Object[] data    = getLobHeader(aID);
+        long     aLength = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+
+        data = getLobHeader(bID);
+
+        long    bLength    = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+        int[][] aAddresses = getBlockAddresses(aID, 0, Integer.MAX_VALUE);
+        int[][] bAddresses = getBlockAddresses(bID, 0, Integer.MAX_VALUE);
+        int     aIndex     = 0;
+        int     bIndex     = 0;
+        int     aOffset    = 0;
+        int     bOffset    = 0;
+
+        while (true) {
+            int aBlockOffset = aAddresses[aIndex][LOBS.BLOCK_ADDR] + aOffset;
+            int bBlockOffset = bAddresses[bIndex][LOBS.BLOCK_ADDR] + bOffset;
+            byte[] aBytes    = getLobStore().getBlockBytes(aBlockOffset, 1);
+            byte[] bBytes    = getLobStore().getBlockBytes(bBlockOffset, 1);
+            long aLimit = aLength
+                          - (aAddresses[aIndex][LOBS.BLOCK_OFFSET] + aOffset)
+                            * lobBlockSize / 2;
+
+            if (aLimit > lobBlockSize / 2) {
+                aLimit = lobBlockSize / 2;
+            }
+
+            long bLimit = bLength
+                          - (bAddresses[bIndex][LOBS.BLOCK_OFFSET] + bOffset)
+                            * lobBlockSize / 2;
+
+            if (bLimit > lobBlockSize / 2) {
+                bLimit = lobBlockSize / 2;
+            }
+
+            String aString = new String(ArrayUtil.byteArrayToChars(aBytes), 0,
+                                        (int) aLimit);
+            String bString = new String(ArrayUtil.byteArrayToChars(bBytes), 0,
+                                        (int) bLimit);
+            int diff = database.collation.compare(aString, bString);
+
+            if (diff != 0) {
+                return diff;
+            }
+
+            aOffset++;
+            bOffset++;
+
+            if (aOffset == aAddresses[aIndex][LOBS.BLOCK_COUNT]) {
+                aOffset = 0;
+
+                aIndex++;
+            }
+
+            if (bOffset == bAddresses[bIndex][LOBS.BLOCK_COUNT]) {
+                bOffset = 0;
+
+                bIndex++;
+            }
+
+            if (aIndex == aAddresses.length) {
+                break;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Used for SUBSTRING
+     */
+    synchronized public Result getLob(long lobID, long offset, long length) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "LobManager");
+    }
+
+    synchronized public Result createDuplicateLob(long lobID) {
+
+        Object[] data = getLobHeader(lobID);
+
+        if (data == null) {
+            return Result.newErrorResult(Error.error(ErrorCode.X_0F502));
+        }
+
+        long   newLobID = getNewLobID();
+        Object params[] = new Object[data.length];
+
+        params[LOB_IDS.LOB_ID] = ValuePool.getLong(newLobID);
+        params[1]              = data[1];
+        params[2]              = data[2];
+        params[3]              = data[3];
+
+        Result result = sysLobSession.executeCompiledStatement(createLob,
+            params);
+
+        if (result.isError()) {
+            return result;
+        }
+
+        long length     = ((Long) data[1]).longValue();
+        long byteLength = length;
+        int  lobType    = ((Integer) data[1]).intValue();
+
+        if (lobType == Types.SQL_CLOB) {
+            byteLength *= 2;
+        }
+
+        int newBlockCount = (int) byteLength / lobBlockSize;
+
+        if (byteLength % lobBlockSize != 0) {
+            newBlockCount++;
+        }
+
+        createBlockAddresses(newLobID, 0, newBlockCount);
+
+        // copy the contents
+        int[][] sourceBlocks = getBlockAddresses(lobID, 0, Integer.MAX_VALUE);
+        int[][] targetBlocks = getBlockAddresses(newLobID, 0,
+            Integer.MAX_VALUE);
+
+        try {
+            copyBlockSet(sourceBlocks, targetBlocks);
+        } catch (HsqlException e) {
+            return Result.newErrorResult(e);
+        }
+
+        return ResultLob.newLobSetResponse(newLobID, length);
+    }
+
+    private void copyBlockSet(int[][] source, int[][] target) {
+
+        int sourceIndex = 0;
+        int targetIndex = 0;
+
+        while (true) {
+            int sourceOffset = source[sourceIndex][LOBS.BLOCK_OFFSET]
+                               + sourceIndex;
+            int targetOffset = target[targetIndex][LOBS.BLOCK_OFFSET]
+                               + targetIndex;
+            byte[] bytes = getLobStore().getBlockBytes(sourceOffset, 1);
+
+            getLobStore().setBlockBytes(bytes, targetOffset, 1);
+
+            sourceOffset++;
+            targetOffset++;
+
+            if (sourceOffset == source[sourceIndex][LOBS.BLOCK_COUNT]) {
+                sourceOffset = 0;
+
+                sourceIndex++;
+            }
+
+            if (targetOffset == target[sourceIndex][LOBS.BLOCK_COUNT]) {
+                targetOffset = 0;
+
+                targetIndex++;
+            }
+
+            if (sourceIndex == source.length) {
+                break;
+            }
+        }
+    }
+
+    synchronized public Result getChars(long lobID, long offset, int length) {
+
+        Result result = getBytes(lobID, offset * 2, length * 2);
+
+        if (result.isError()) {
+            return result;
+        }
+
+        byte[] bytes = ((ResultLob) result).getByteArray();
+        char[] chars = ArrayUtil.byteArrayToChars(bytes);
+
+/*
+        HsqlByteArrayInputStream be    = new HsqlByteArrayInputStream(bytes);
+        char[]                   chars = new char[bytes.length / 2];
+
+        try {
+            for (int i = 0; i < chars.length; i++) {
+                chars[i] = be.readChar();
+            }
+        } catch (Exception e) {
+            return Result.newErrorResult(e);
+        }
+*/
+        return ResultLob.newLobGetCharsResponse(lobID, offset, chars);
+    }
+
+    synchronized public Result getBytes(long lobID, long offset, int length) {
+
+        int blockOffset     = (int) (offset / lobBlockSize);
+        int byteBlockOffset = (int) (offset % lobBlockSize);
+        int blockLimit      = (int) ((offset + length) / lobBlockSize);
+        int byteLimitOffset = (int) ((offset + length) % lobBlockSize);
+
+        if (byteLimitOffset == 0) {
+            byteLimitOffset = lobBlockSize;
+        } else {
+            blockLimit++;
+        }
+
+        int    dataBytesPosition = 0;
+        byte[] dataBytes         = new byte[length];
+        int[][] blockAddresses = getBlockAddresses(lobID, blockOffset,
+            blockLimit);
+
+        if (blockAddresses.length == 0) {
+            return Result.newErrorResult(Error.error(ErrorCode.X_0F502));
+        }
+
+        //
+        int i = 0;
+        int blockCount = blockAddresses[i][LOBS.BLOCK_COUNT]
+                         + blockAddresses[i][LOBS.BLOCK_OFFSET] - blockOffset;
+
+        if (blockAddresses[i][LOBS.BLOCK_COUNT]
+                + blockAddresses[i][LOBS.BLOCK_OFFSET] > blockLimit) {
+            blockCount -= (blockAddresses[i][LOBS.BLOCK_COUNT]
+                           + blockAddresses[i][LOBS.BLOCK_OFFSET]
+                           - blockLimit);
+        }
+
+        byte[] bytes;
+
+        try {
+            bytes =
+                getLobStore().getBlockBytes(blockAddresses[i][LOBS.BLOCK_ADDR]
+                                            + blockOffset, blockCount);
+        } catch (HsqlException e) {
+            return Result.newErrorResult(e);
+        }
+
+        int subLength = lobBlockSize * blockCount - byteBlockOffset;
+
+        if (subLength > length) {
+            subLength = length;
+        }
+
+        System.arraycopy(bytes, byteBlockOffset, dataBytes, dataBytesPosition,
+                         subLength);
+
+        dataBytesPosition += subLength;
+
+        i++;
+
+        for (; i < blockAddresses.length && dataBytesPosition < length; i++) {
+            blockCount = blockAddresses[i][LOBS.BLOCK_COUNT];
+
+            if (blockAddresses[i][LOBS.BLOCK_COUNT]
+                    + blockAddresses[i][LOBS.BLOCK_OFFSET] > blockLimit) {
+                blockCount -= (blockAddresses[i][LOBS.BLOCK_COUNT]
+                               + blockAddresses[i][LOBS.BLOCK_OFFSET]
+                               - blockLimit);
+            }
+
+            try {
+                bytes = getLobStore().getBlockBytes(
+                    blockAddresses[i][LOBS.BLOCK_ADDR], blockCount);
+            } catch (HsqlException e) {
+                return Result.newErrorResult(e);
+            }
+
+            subLength = lobBlockSize * blockCount;
+
+            if (subLength > length - dataBytesPosition) {
+                subLength = length - dataBytesPosition;
+            }
+
+            System.arraycopy(bytes, 0, dataBytes, dataBytesPosition,
+                             subLength);
+
+            dataBytesPosition += subLength;
+        }
+
+        return ResultLob.newLobGetBytesResponse(lobID, offset, dataBytes);
+    }
+
+    synchronized public Result setBytesBA(long lobID, byte[] dataBytes,
+                                          long offset, int length) {
+
+        int blockOffset     = (int) (offset / lobBlockSize);
+        int byteBlockOffset = (int) (offset % lobBlockSize);
+        int blockLimit      = (int) ((offset + length) / lobBlockSize);
+        int byteLimitOffset = (int) ((offset + length) % lobBlockSize);
+
+        if (byteLimitOffset == 0) {
+            byteLimitOffset = lobBlockSize;
+        } else {
+            blockLimit++;
+        }
+
+        int[][] blockAddresses = getBlockAddresses(lobID, blockOffset,
+            blockLimit);
+        byte[] newBytes = new byte[(blockLimit - blockOffset) * lobBlockSize];
+
+        if (blockAddresses.length > 0) {
+            int blockAddress = blockAddresses[0][LOBS.BLOCK_ADDR]
+                               + (blockOffset
+                                  - blockAddresses[0][LOBS.BLOCK_OFFSET]);
+
+            try {
+                byte[] block = getLobStore().getBlockBytes(blockAddress, 1);
+
+                System.arraycopy(block, 0, newBytes, 0, lobBlockSize);
+
+                if (blockAddresses.length > 1) {
+                    blockAddress =
+                        blockAddresses[blockAddresses.length - 1][LOBS.BLOCK_ADDR]
+                        + (blockLimit
+                           - blockAddresses[blockAddresses.length - 1][LOBS.BLOCK_OFFSET]
+                           - 1);
+                    block = getLobStore().getBlockBytes(blockAddress, 1);
+
+                    System.arraycopy(block, 0, newBytes,
+                                     blockLimit - blockOffset - 1,
+                                     lobBlockSize);
+                } else if (blockLimit - blockOffset > 1) {
+                    blockAddress = blockAddresses[0][LOBS.BLOCK_ADDR]
+                                   + (blockLimit
+                                      - blockAddresses[0][LOBS.BLOCK_OFFSET]
+                                      - 1);
+                    block = getLobStore().getBlockBytes(blockAddress, 1);
+
+                    System.arraycopy(block, 0, newBytes,
+                                     (blockLimit - blockOffset - 1)
+                                     * lobBlockSize, lobBlockSize);
+                }
+            } catch (HsqlException e) {
+                return Result.newErrorResult(e);
+            }
+
+            // should turn into SP
+            divideBlockAddresses(lobID, blockOffset);
+            divideBlockAddresses(lobID, blockLimit);
+            deleteBlockAddresses(lobID, blockOffset, blockLimit);
+        }
+
+        createBlockAddresses(lobID, blockOffset, blockLimit - blockOffset);
+        System.arraycopy(dataBytes, 0, newBytes, byteBlockOffset, length);
+
+        blockAddresses = getBlockAddresses(lobID, blockOffset, blockLimit);
+
+        //
+        try {
+            for (int i = 0; i < blockAddresses.length; i++) {
+                getLobStore().setBlockBytes(newBytes, blockAddresses[i][0],
+                                            blockAddresses[i][1]);
+            }
+        } catch (HsqlException e) {
+            return Result.newErrorResult(e);
+        }
+
+        return ResultLob.newLobSetResponse(lobID, 0);
+    }
+
+    private Result setBytesIS(long lobID, InputStream inputStream,
+                              long length) {
+
+        int blockLimit      = (int) (length / lobBlockSize);
+        int byteLimitOffset = (int) (length % lobBlockSize);
+
+        if (byteLimitOffset == 0) {
+            byteLimitOffset = lobBlockSize;
+        } else {
+            blockLimit++;
+        }
+
+        createBlockAddresses(lobID, 0, blockLimit);
+
+        int[][] blockAddresses = getBlockAddresses(lobID, 0, blockLimit);
+        byte[]  dataBytes      = new byte[lobBlockSize];
+
+        for (int i = 0; i < blockAddresses.length; i++) {
+            for (int j = 0; j < blockAddresses[i][LOBS.BLOCK_COUNT]; j++) {
+                int localLength = lobBlockSize;
+
+                if (i == blockAddresses.length - 1
+                        && j == blockAddresses[i][LOBS.BLOCK_COUNT] - 1) {
+                    localLength = byteLimitOffset;
+
+// todo -- use block op
+                    for (int k = localLength; k < lobBlockSize; k++) {
+                        dataBytes[k] = 0;
+                    }
+                }
+
+                try {
+                    int count = 0;
+
+                    while (localLength > 0) {
+                        int read = inputStream.read(dataBytes, count,
+                                                    localLength);
+
+                        if (read == -1) {
+                            return Result.newErrorResult(new EOFException());
+                        }
+
+                        localLength -= read;
+                        count       += read;
+                    }
+
+                    // read more
+                } catch (IOException e) {
+
+                    // deallocate
+                    return Result.newErrorResult(e);
+                }
+
+                try {
+                    getLobStore().setBlockBytes(
+                        dataBytes, blockAddresses[i][LOBS.BLOCK_ADDR] + j, 1);
+                } catch (HsqlException e) {
+                    return Result.newErrorResult(e);
+                }
+            }
+        }
+
+        return ResultLob.newLobSetResponse(lobID, 0);
+    }
+
+    synchronized public Result setBytes(long lobID, byte[] dataBytes,
+                                        long offset) {
+
+        if (dataBytes.length == 0) {
+            return ResultLob.newLobSetResponse(lobID, 0);
+        }
+
+        Object[] data = getLobHeader(lobID);
+
+        if (data == null) {
+            return Result.newErrorResult(Error.error(ErrorCode.X_0F502));
+        }
+
+        long   length = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+        Result result = setBytesBA(lobID, dataBytes, offset, dataBytes.length);
+
+        if (offset + dataBytes.length > length) {
+            setLength(lobID, offset + dataBytes.length);
+        }
+
+        return result;
+    }
+
+    synchronized public Result setBytesForNewBlob(long lobID,
+            InputStream inputStream, long length) {
+
+        if (length == 0) {
+            return ResultLob.newLobSetResponse(lobID, 0);
+        }
+
+        Result result = setBytesIS(lobID, inputStream, length);
+
+        return result;
+    }
+
+    synchronized public Result setChars(long lobID, long offset,
+                                        char[] chars) {
+
+        if (chars.length == 0) {
+            return ResultLob.newLobSetResponse(lobID, 0);
+        }
+
+        Object[] data = getLobHeader(lobID);
+
+        if (data == null) {
+            return Result.newErrorResult(Error.error(ErrorCode.X_0F502));
+        }
+
+        long   length = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+        byte[] bytes  = ArrayUtil.charArrayToBytes(chars);
+/*
+        HsqlByteArrayOutputStream os =
+            new HsqlByteArrayOutputStream(chars.length * 2);
+
+        os.write(chars, 0, chars.length);
+
+        byte[] bytes = os.getBuffer();
+*/
+        Result result = setBytesBA(lobID, bytes, offset * 2, chars.length * 2);
+
+        if (result.isError()) {
+            return result;
+        }
+
+        if (offset + chars.length > length) {
+            result = setLength(lobID, offset + chars.length);
+
+            if (result.isError()) {
+                return result;
+            }
+        }
+
+        return ResultLob.newLobSetResponse(lobID, 0);
+    }
+
+    synchronized public Result setCharsForNewClob(long lobID,
+            InputStream inputStream, long length) {
+
+        if (length == 0) {
+            return ResultLob.newLobSetResponse(lobID, 0);
+        }
+
+        Result result = setBytesIS(lobID, inputStream, length * 2);
+
+        if (result.isError()) {
+            return result;
+        }
+
+        return ResultLob.newLobSetResponse(lobID, 0);
+    }
+
+    synchronized public Result truncate(long lobID, long offset) {
+
+        Object[] data = getLobHeader(lobID);
+
+        if (data == null) {
+            return Result.newErrorResult(Error.error(ErrorCode.X_0F502));
+        }
+
+        /** @todo 1.9.0 - double offset for clob */
+        long           length = ((Long) data[LOB_IDS.LOB_LENGTH]).longValue();
+        int            blockOffset = (int) (offset / lobBlockSize);
+        ResultMetaData meta        = deleteLobPartCall.getParametersMetaData();
+        Object         params[]    = new Object[meta.getColumnCount()];
+
+        params[DELETE_BLOCKS.LOB_ID]       = ValuePool.getLong(lobID);
+        params[DELETE_BLOCKS.BLOCK_OFFSET] = new Integer(blockOffset);
+        params[DELETE_BLOCKS.BLOCK_LIMIT]  = new Integer(Integer.MAX_VALUE);
+        params[DELETE_BLOCKS.TX_ID] =
+            ValuePool.getLong(sysLobSession.getTransactionTimestamp());
+
+        Result result =
+            sysLobSession.executeCompiledStatement(deleteLobPartCall, params);
+
+        setLength(lobID, offset);
+
+        return ResultLob.newLobTruncateResponse(lobID);
+    }
+
+    synchronized Result setLength(long lobID, long length) {
+
+        ResultMetaData meta     = updateLobLength.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[UPDATE_LENGTH.LOB_LENGTH] = ValuePool.getLong(length);
+        params[UPDATE_LENGTH.LOB_ID]     = ValuePool.getLong(lobID);
+
+        Result result = sysLobSession.executeCompiledStatement(updateLobLength,
+            params);
+
+        return result;
+    }
+
+    synchronized public Result adjustUsageCount(long lobID, int delta) {
+
+        Object[] data  = getLobHeader(lobID);
+        int      count = ((Number) data[LOB_IDS.LOB_USAGE_COUNT]).intValue();
+
+        if (count + delta == 0) {
+            deletedLobCount++;
+        }
+
+        ResultMetaData meta     = updateLobUsage.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[UPDATE_USAGE.BLOCK_COUNT] = ValuePool.getInt(count + delta);
+        params[UPDATE_USAGE.LOB_ID]      = ValuePool.getLong(lobID);
+
+        sysLobSession.sessionContext.pushDynamicArguments(params);
+
+        Result result = updateLobUsage.execute(sysLobSession);
+
+        sysLobSession.sessionContext.pop();
+
+        return result;
+    }
+
+    private int[][] getBlockAddresses(long lobID, int offset, int limit) {
+
+        ResultMetaData meta     = getLobPart.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[GET_LOB_PART.LOB_ID]       = ValuePool.getLong(lobID);
+        params[GET_LOB_PART.BLOCK_OFFSET] = ValuePool.getInt(offset);
+        params[GET_LOB_PART.BLOCK_LIMIT]  = ValuePool.getInt(limit);
+
+        sysLobSession.sessionContext.pushDynamicArguments(params);
+
+        Result result = getLobPart.execute(sysLobSession);
+
+        sysLobSession.sessionContext.pop();
+
+        RowSetNavigator navigator = result.getNavigator();
+        int             size      = navigator.getSize();
+        int[][]         blocks    = new int[size][3];
+
+        for (int i = 0; i < size; i++) {
+            navigator.absolute(i);
+
+            Object[] data = navigator.getCurrent();
+
+            blocks[i][LOBS.BLOCK_ADDR] =
+                ((Integer) data[LOBS.BLOCK_ADDR]).intValue();
+            blocks[i][LOBS.BLOCK_COUNT] =
+                ((Integer) data[LOBS.BLOCK_COUNT]).intValue();
+            blocks[i][LOBS.BLOCK_OFFSET] =
+                ((Integer) data[LOBS.BLOCK_OFFSET]).intValue();
+        }
+
+        navigator.close();
+
+        return blocks;
+    }
+
+    private void deleteBlockAddresses(long lobID, int offset, int limit) {
+
+        ResultMetaData meta     = deleteLobPartCall.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[DELETE_BLOCKS.LOB_ID]       = ValuePool.getLong(lobID);
+        params[DELETE_BLOCKS.BLOCK_OFFSET] = ValuePool.getInt(offset);
+        params[DELETE_BLOCKS.BLOCK_LIMIT]  = ValuePool.getInt(limit);
+        params[DELETE_BLOCKS.TX_ID] =
+            ValuePool.getLong(sysLobSession.getTransactionTimestamp());
+
+        Result result =
+            sysLobSession.executeCompiledStatement(deleteLobPartCall, params);
+    }
+
+    private void divideBlockAddresses(long lobID, int offset) {
+
+        ResultMetaData meta     = divideLobPartCall.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[DIVIDE_BLOCK.BLOCK_OFFSET] = ValuePool.getInt(offset);
+        params[DIVIDE_BLOCK.LOB_ID]       = ValuePool.getLong(lobID);
+
+        Result result =
+            sysLobSession.executeCompiledStatement(divideLobPartCall, params);
+    }
+
+    private void createBlockAddresses(long lobID, int offset, int count) {
+
+        ResultMetaData meta     = createLobPartCall.getParametersMetaData();
+        Object         params[] = new Object[meta.getColumnCount()];
+
+        params[ALLOC_BLOCKS.BLOCK_COUNT]  = ValuePool.getInt(count);
+        params[ALLOC_BLOCKS.BLOCK_OFFSET] = ValuePool.getInt(offset);
+        params[ALLOC_BLOCKS.LOB_ID]       = ValuePool.getLong(lobID);
+
+        Result result =
+            sysLobSession.executeCompiledStatement(createLobPartCall, params);
+    }
+
+    synchronized public int getLobCount() {
+
+        sysLobSession.sessionContext.pushDynamicArguments(new Object[]{});
+
+        Result result = getLobCount.execute(sysLobSession);
+
+        sysLobSession.sessionContext.pop();
+
+        RowSetNavigator navigator = result.getNavigator();
+        boolean         next      = navigator.next();
+
+        if (!next) {
+            navigator.close();
+
+            return 0;
+        }
+
+        Object[] data = navigator.getCurrent();
+
+        return ((Number) data[0]).intValue();
+    }
+}
diff --git a/src/org/hsqldb/persist/LobStore.java b/src/org/hsqldb/persist/LobStore.java
new file mode 100644
index 0000000..f57f99f
--- /dev/null
+++ b/src/org/hsqldb/persist/LobStore.java
@@ -0,0 +1,48 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface LobStore {
+
+    byte[] getBlockBytes(int blockAddress, int blockCount);
+
+    void setBlockBytes(byte[] dataBytes, int blockAddress, int blockCount);
+
+    int getBlockSize();
+
+    void close();
+}
diff --git a/src/org/hsqldb/persist/LobStoreInJar.java b/src/org/hsqldb/persist/LobStoreInJar.java
new file mode 100644
index 0000000..6e43cec
--- /dev/null
+++ b/src/org/hsqldb/persist/LobStoreInJar.java
@@ -0,0 +1,152 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.hsqldb.Database;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class LobStoreInJar implements LobStore {
+
+    final int       lobBlockSize;
+    Database        database;
+    DataInputStream file;
+    final String    fileName;
+
+    //
+    long realPosition;
+
+    public LobStoreInJar(Database database, int lobBlockSize) {
+
+        this.lobBlockSize = lobBlockSize;
+        this.database     = database;
+
+        try {
+            fileName = database.getPath() + ".lobs";
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, t);
+        }
+    }
+
+    public byte[] getBlockBytes(int blockAddress, int blockCount) {
+
+        if (file == null) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR);
+        }
+
+        try {
+            long   address   = (long) blockAddress * lobBlockSize;
+            int    count     = blockCount * lobBlockSize;
+            byte[] dataBytes = new byte[count];
+
+            fileSeek(address);
+            file.readFully(dataBytes, 0, count);
+
+            realPosition = address + count;
+
+            return dataBytes;
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, t);
+        }
+    }
+
+    public void setBlockBytes(byte[] dataBytes, int blockAddress,
+                              int blockCount) {}
+
+    public int getBlockSize() {
+        return lobBlockSize;
+    }
+
+    public void close() {
+
+        try {
+            if (file != null) {
+                file.close();
+            }
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, t);
+        }
+    }
+
+    private void resetStream() throws IOException {
+
+        if (file != null) {
+            file.close();
+        }
+
+        InputStream fis;
+
+        try {
+            fis = getClass().getResourceAsStream(fileName);
+
+            if (fis == null) {
+                fis = Thread.currentThread().getContextClassLoader()
+                    .getResourceAsStream(fileName);
+            }
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATABASE_NOT_EXISTS, t);
+        }
+
+        file         = new DataInputStream(fis);
+        realPosition = 0;
+    }
+
+    private void fileSeek(long position) throws IOException {
+
+        if (file == null) {
+            resetStream();
+        }
+
+        long skipPosition = realPosition;
+
+        if (position < skipPosition) {
+            resetStream();
+
+            skipPosition = 0;
+        }
+
+        while (position > skipPosition) {
+            skipPosition += file.skip(position - skipPosition);
+        }
+
+        realPosition = position;
+    }
+}
diff --git a/src/org/hsqldb/persist/LobStoreMem.java b/src/org/hsqldb/persist/LobStoreMem.java
new file mode 100644
index 0000000..9564412
--- /dev/null
+++ b/src/org/hsqldb/persist/LobStoreMem.java
@@ -0,0 +1,125 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.lib.HsqlArrayList;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class LobStoreMem implements LobStore {
+
+    final int     lobBlockSize;
+    int           blocksInLargeBlock = 128;
+    int           largeBlockSize;
+    HsqlArrayList byteStoreList;
+
+    public LobStoreMem(int lobBlockSize) {
+
+        this.lobBlockSize = lobBlockSize;
+        largeBlockSize    = lobBlockSize * blocksInLargeBlock;
+        byteStoreList     = new HsqlArrayList();
+    }
+
+    public byte[] getBlockBytes(int blockAddress, int blockCount) {
+
+        byte[] dataBytes       = new byte[blockCount * lobBlockSize];
+        int    dataBlockOffset = 0;
+
+        while (blockCount > 0) {
+            int    largeBlockIndex   = blockAddress / blocksInLargeBlock;
+            byte[] largeBlock = (byte[]) byteStoreList.get(largeBlockIndex);
+            int    blockOffset       = blockAddress % blocksInLargeBlock;
+            int    currentBlockCount = blockCount;
+
+            if ((blockOffset + currentBlockCount) > blocksInLargeBlock) {
+                currentBlockCount = blocksInLargeBlock - blockOffset;
+            }
+
+            System.arraycopy(largeBlock, blockOffset * lobBlockSize,
+                             dataBytes, dataBlockOffset * lobBlockSize,
+                             currentBlockCount * lobBlockSize);
+
+            blockAddress    += currentBlockCount;
+            dataBlockOffset += currentBlockCount;
+            blockCount      -= currentBlockCount;
+        }
+
+        return dataBytes;
+    }
+
+    public void setBlockBytes(byte[] dataBytes, int blockAddress,
+                              int blockCount) {
+
+        int dataBlockOffset = 0;
+
+        while (blockCount > 0) {
+            int largeBlockIndex = blockAddress / blocksInLargeBlock;
+            int largeBlockLimit = (blockAddress + blockCount)
+                                  / blocksInLargeBlock;
+
+            if ((blockAddress + blockCount) % blocksInLargeBlock != 0) {
+                largeBlockLimit++;
+            }
+
+            if (largeBlockIndex >= byteStoreList.size()) {
+                byteStoreList.add(new byte[largeBlockSize]);
+            }
+
+            byte[] largeBlock = (byte[]) byteStoreList.get(largeBlockIndex);
+            int    blockOffset       = blockAddress % blocksInLargeBlock;
+            int    currentBlockCount = blockCount;
+
+            if ((blockOffset + currentBlockCount) > blocksInLargeBlock) {
+                currentBlockCount = blocksInLargeBlock - blockOffset;
+            }
+
+            System.arraycopy(dataBytes, dataBlockOffset * lobBlockSize,
+                             largeBlock, blockOffset * lobBlockSize,
+                             currentBlockCount * lobBlockSize);
+
+            blockAddress    += currentBlockCount;
+            dataBlockOffset += currentBlockCount;
+            blockCount      -= currentBlockCount;
+        }
+    }
+
+    public int getBlockSize() {
+        return lobBlockSize;
+    }
+
+    public void close() {
+        byteStoreList.clear();
+    }
+}
diff --git a/src/org/hsqldb/persist/LobStoreRAFile.java b/src/org/hsqldb/persist/LobStoreRAFile.java
new file mode 100644
index 0000000..4145c89
--- /dev/null
+++ b/src/org/hsqldb/persist/LobStoreRAFile.java
@@ -0,0 +1,138 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.Database;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.Storage;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class LobStoreRAFile implements LobStore {
+
+    final int lobBlockSize;
+    Storage   file;
+    Database  database;
+
+    public LobStoreRAFile(Database database, int lobBlockSize) {
+
+        this.lobBlockSize = lobBlockSize;
+        this.database     = database;
+
+        try {
+            String name = database.getPath() + ".lobs";
+            boolean exists =
+                database.logger.getFileAccess().isStreamElement(name);
+
+            if (exists) {
+                openFile();
+            }
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, t);
+        }
+    }
+
+    private void openFile() {
+
+        try {
+            String  name     = database.getPath() + ".lobs";
+            boolean readonly = database.isReadOnly();
+
+            if (database.logger.isStoredFileAccess()) {
+                file = ScaledRAFile.newScaledRAFile(
+                    database, name, readonly, ScaledRAFile.DATA_FILE_STORED);
+            } else {
+                file = new ScaledRAFileSimple(name, readonly ? "r"
+                                                             : "rwd");
+            }
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, t);
+        }
+    }
+
+    public byte[] getBlockBytes(int blockAddress, int blockCount) {
+
+        if (file == null) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR);
+        }
+
+        try {
+            long   address   = (long) blockAddress * lobBlockSize;
+            int    count     = blockCount * lobBlockSize;
+            byte[] dataBytes = new byte[count];
+
+            file.seek(address);
+            file.read(dataBytes, 0, count);
+
+            return dataBytes;
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, t);
+        }
+    }
+
+    public void setBlockBytes(byte[] dataBytes, int blockAddress,
+                              int blockCount) {
+
+        if (file == null) {
+            openFile();
+        }
+
+        try {
+            long address = (long) blockAddress * lobBlockSize;
+            int  count   = blockCount * lobBlockSize;
+
+            file.seek(address);
+            file.write(dataBytes, 0, count);
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, t);
+        }
+    }
+
+    public int getBlockSize() {
+        return lobBlockSize;
+    }
+
+    public void close() {
+
+        try {
+            if (file != null) {
+                file.close();
+            }
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, t);
+        }
+    }
+}
diff --git a/src/org/hsqldb/persist/LockFile.java b/src/org/hsqldb/persist/LockFile.java
new file mode 100644
index 0000000..3d07c66
--- /dev/null
+++ b/src/org/hsqldb/persist/LockFile.java
@@ -0,0 +1,2408 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.HsqlException;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.HsqlTimer;
+import org.hsqldb.lib.StringConverter;
+
+/**
+ * Base cooperative file locking implementation and <tt>LockFile</tt>
+ * factory. <p>
+ *
+ * <hr>
+ *
+ * Provides a facility for cooperative file locking across process boundaries
+ * and isolated in-process class loader contexts. <p>
+ *
+ * The need is obvious for inter-process cases, but it is no less essential for
+ * in-process Java clients whose classes have been loaded by isolated class
+ * loaders.  This is because static fields--the conventional<a href="#note1">
+ * <sup>*</sup></a> means for supporting in-process global discovery--become
+ * distinct and inaccessible across Java class loader context boundaries when
+ * the contexts do not share a common parent class loader or do not implement
+ * normal parent class loader delegation semantics. <p>
+ *
+ * <a name="note1"><sup>*</sup></a>
+ * The only purely in-process global discovery alternative known to the author
+ * is to reflect upon objects found while traversing up the Java runtime thread
+ * hierarchy.  However, this method is often subject to Java security
+ * restrictions whose collective purpose is essentially dissimilar to that of
+ * restrictions in effect relative to cooperative file locking requirements,
+ * making it a generally unacceptable option in this context. <p>
+ *
+ * <hr>
+ *
+ * Here is the way this class presently operates: <p>
+ *
+ * <ol style="list-style-type: upper-latin">
+ *    <li>A file with a commonly agreed-upon path is used to implement
+ *        cooperative locking semantics regarding another set of files with
+ *        commonly agreed-upon paths.<p>
+ *
+ *    <li>In particular, a background thread periodically writes a timestamp
+ *        value, which acts as a heartbeat that indicates to others whether a
+ *        cooperative lock condition is currently held.<p>
+ *
+ *    <li>In addition, a magic value is written so that it is possible to
+ *        distinguish with a reasonably high degree of accuracy between the
+ *        existence of a lock file and some other type of file.<p>
+ *
+ *    <li>The generic rules used to aquire a cooperative lock condition are
+ *        as follows:<p>
+ *
+ *    <ol>
+ *        <li>If a lock condition is already held by this object, do nothing and
+ *            signify that the lock attempt was successful, else...<p>
+ *
+ *        <li>Poll the underlying file, using a configured maximum number of
+ *            retries and a configured interval between the end of a failed
+ *            poll and the beginning of the next.<p>
+ *
+ *        <li>For each poll:<p>
+ *
+ *        <ol style="list-style-type: lower-roman">
+ *
+ *            <li>Attempt to atomically create the underlying file if and only
+ *                if it does not yet exist, exit the polling loop immediately
+ *                indicating success if the attempt succeeds, else fast fail
+ *                the current poll if a security exeption is thrown in response
+ *                to the attempt, else...<p>
+ *
+ *            <li>Test if the underlying file exists, fast failing the current
+ *                poll if it is impossible to determine (i.e. if a security
+ *                exeption is thrown).<p>
+ *
+ *            <li>If the file does not exist, exit the polling loop immediately
+ *                indicating success.<p>
+ *
+ *                This can occur only under pre-JDK 1.2 runtimes; or when the
+ *                underlying platform does not correctly support {@link
+ *                java.io.File#createNewFile()}; or when the underlying file is
+ *                deleted within a very short time after i.), above (typically
+ *                on the order of microseconds). <p>
+ *
+ *                If the underlying platform employs a kernel-enforced mandatory
+ *                file locking blanket policy for open files (e.g. <em>Windows
+ *                </em><sup>tm</sup>), then this is likely a non-issue. And if
+ *                this case makes possible a race condition with another
+ *                <tt>LockFile</tt> object (because the test for existence and
+ *                subsequent file creation is not atomic relative to all other
+ *                file system actions), it is still <em>very</em> unlikely that
+ *                so unfortunate a timing will occur as to allow simultaneous
+ *                lock conditions to be established. Finally, if some
+ *                non-<tt>LockFile</tt> entity deleted the file, then there are
+ *                much worse things to worry about, in particular that the files
+ *                this object is supposed to protect are in reality subject to
+ *                arbitrary external modification and deletion.<p>
+ *
+ *            <li>Test the file's length, fast failing the current poll if the
+ *                length cannot be determined or it is not the expected
+ *                value.<p>
+ *
+ *            <li>Open a stream to read the file's <tt>MAGIC</tt> and heartbeat
+ *                timestamp values, fast failing the current poll if the stream
+ *                cannot be opened.<p>
+ *
+ *            <li>Test the file's <tt>MAGIC</tt> value, failing the current poll
+ *                if the value cannot be read or it is not the expected
+ *                value.<p>
+ *
+ *            <li>Test the file's heartbeat timestamp value, fast failing the
+ *                current poll if it cannot be read or it is less than a
+ *                commonly agreed-upon value into the past (or future, to
+ *                overcome a caveat observed by a patch contributor).<p>
+ *        </ol>
+ *        <li>If the polling phase exits with a failure indication, then one or
+ *            more of the following cases must have been true at every poll
+ *            iteration: <p>
+ *
+ *            <ul>
+ *               <li>The file had the wrong length or <tt>MAGIC</tt> value (was
+ *                   not an HSQLDB lock file).
+ *
+ *               <li>The file was deleted externally after a poll's initial
+ *                   test for existence and recreated at some point before
+ *                   the next poll's initial test for existence.
+ *
+ *               <li>An incompatible OS-enforced security restriction was in
+ *                   effect.
+ *
+ *               <li>An incompatible Java-enforced security restriction was
+ *                   in effect.
+ *
+ *               <li>The target file system media was effectively inaccessible.
+
+ *               <li>A cooperative lock condition was held by some other
+ *                   <tt>LockFile</tt>.
+ *
+ *               <li>A kernel-enforced manditory or advisory file lock was held.
+ *            </ul> <p>
+ *
+ *            In this case, signify failure indicating the last encountered
+ *            reason, else...<p>
+ *
+ *        <li>Open the file for reading and writing, write the magic value and
+ *            an initial heartbeat timestamp, schedule a periodic heartbeat
+ *            timestamp writer task and signify success.<p>
+ *    </ol>
+ *    <li>The generic rules used to release a cooperative lock condition are:<p>
+ *    <ol>
+ *        <li>If a lock condition is not currently held, do nothing and signify
+ *            success, else...<p>
+ *
+ *        <li>A lock condition is currently held by this object, so try to
+ *            release it. <p>
+ *
+ *            By default, releasing the lock condition consists of closing and
+ *            nullifying any objects that have a file descriptor open on the
+ *            lock file, cancelling the periodic heartbeat timestamp writer
+ *            task and deleting the lock file. If the release occurs without
+ *            raising an exception, signify success, else signify that the
+ *            release attempt <em>might</em> have failed. <p>
+ *    </ol>
+ * </ol> <p>
+ *
+ * <hr>
+ *
+ * Additionally, {@link #doOptionalLockActions() doOptionalLockActions()} and
+ * {@link #doOptionalReleaseActions() doOptionalReleaseActions()} are invoked
+ * during lock and release attempts, respectively.  This enables integration of
+ * extended lock and release strategies based on subclassing. Subclass
+ * availability is automatically detected and exposed by the factory method
+ * {@link #newLockFile newLockFile()}.<p>
+ *
+ * In particular, if {@link #USE_NIO_FILELOCK_PROPERTY} is true and the required
+ * classes are available at static initialization, then <tt>newLockFile()</tt>
+ * produces {@link org.hsqldb.persist.NIOLockFile NIOLockFile} instances.<p>
+ *
+ * When <tt>NIOLockFile</tt> instances are produced, then it is possible that
+ * true kernel-enforced advisory or manditory file locking is used to protect
+ * the underlying lock file from inadvertent modification (and possibly even
+ * from deletion, including deletion by the system superuser).
+ *
+ * Otherwise, <tt>newLockFile()</tt> produces vanilla <tt>LockFile</tt>
+ * instances, which exhibit just the elementary cooperative locking behavior on
+ * platforms that do not, by default, implement kernel-enforced manditory
+ * locking for open files. <p>
+ *
+ * At this point, it must be noted that not every target platform upon which
+ * Java can run actually provides true kernel-enforced manditory (or even
+ * advisory) file locking. Indeed, even when a target platform <em>does</em>
+ * provide such locking guarantees for local file systems, it may not be able
+ * to do so for network file systems, or it may only be able to do so safely
+ * (or at all) with certain restrictions. Further, external system configuration
+ * may be a prerequisite to enable manditory locking on systems that support it
+ * but employ advisory locking by default. <p>
+ *
+ * In recognition of these facts, the official Java NIO package specification
+ * explicitly states basically the same information. What is unfortunate,
+ * however, is that no capabilities API is yet provided as part of the package.
+ * What is even more unfortunate is that without something like a capabilities
+ * API, it is impossible for an implementation to indicate or clients to
+ * distiguish between simple lack of platform support and cases involving
+ * immature Java runtimes that do not fully or correctly implement all NIO
+ * features (and hence may throw exceptions at unexpected times or in places
+ * where the API specification indicates none can be thrown).<p>
+ *
+ * It is for the preceding reasons that, as of HSQLDB 1.8.0.3,
+ * <tt>FileLock</tt>'s use of Java NIO has been made a purely optional feature.
+ * Previous to HSQLDB 1.8.0.3, if NIO was detected available, used to create a
+ * <tt>FileLock</tt> and failed, then the enclosing cooperative lock attempt
+ * failed also, despite the fact that a vanilla locking approach could
+ * succeed. <p>
+ *
+ * <b>Polling Configuration</b>:<p>
+ *
+ * Although the {@link #HEARTBEAT_INTERVAL} and default polling values may
+ * seem quite conservative, they are the result of ongoing research into
+ * generally reasonable concerns regarding normal timing and resource
+ * availability fluctuations experienced frequently under most, if not all
+ * operating systems. <p>
+ *
+ * Regardless, flexibility is almost always a good thing, so this class is
+ * designed to allow polling interval and retry count values to be configured
+ * at run-time. <p>
+ *
+ * At present, this can be done at any time by setting the system properties
+ * whose names are  {@link #POLL_RETRIES_PROPERTY} and {@link
+ * #POLL_INTERVAL_PROPERTY}. <p>
+ *
+ * Some consideration has also been given to modifying the polling scheme so
+ * that run-time configuration of the HEARTBEAT_INTERVAL is possible.  For now,
+ * however, this option has been rejected due to the relative complexity of
+ * guaranteeing acceptably safe, deterministic behaviour.  On the other hand,
+ * if it can be guaranteed that certain site invariants hold (in particular,
+ * that only one version of the hsqldb jar will ever be used to open database
+ * instances at the site) and it is desirable or required to experiment with
+ * a lower interval, then it is recommended for now simply to recompile the
+ * jar using a different value in the static field assignment.  Note that great
+ * care should be taken to avoid assigning too low a value, or else it may
+ * become possible that even very short-lived timing and resource availability
+ * fluctuations will cause incorrect operation of this class. <p>
+ *
+ * <b>NIO Configuration</b>:<p>
+ *
+ * Starting with 1.8.0.3, NIO-enhanced file lock attempts are turned off by
+ * default. The general reasons for this are discussed above.  Anyone interested
+ * in the reading the detailed research notes should refer to the overview of
+ * {@link NIOLockFile}. If, after reviewing the notes and the capabilities of
+ * the intended target platform, one should still wish to enable NIO-enhanced
+ * file lock attempts, it can be done by setting the system property {@link
+ * #USE_NIO_FILELOCK_PROPERTY} true at JVM startup (for example, by using a
+ * command-line <tt>-D&lt;property-name&gt;=true</tt> directive). Be aware that
+ * the system property value is read only once, in the static initializer block
+ * for this class. <p>
+ *
+ * <b>Design Notes</b>:<p>
+ *
+ * First, it should be noted that no thread synchronization occurs in
+ * this class.  Primarily, this is because the standard entry point,
+ * {@link #newLockFileLock(String)}, is always called from within a block
+ * synchronized upon an HSQLDB Database instance.  If this class is to be used
+ * elsewhere and it could be accessed concurrently, then access should be
+ * synchronized on an appropriate monitor.  That said, certain members of this
+ * class have been declared volatile to minimize possibility of inconsistent
+ * views under concurrent read-only access. <p>
+ *
+ * Second, to the limit of the author's present understanding, the
+ * implementation details of this class represent a good comprimse under varying
+ * and generally uncontrollable JVM, OS and hardware platform
+ * limitations/capabilites, as well as under usability considerations and
+ * external security or operating constraints that may need to be imposed.<p>
+ *
+ * Alternate approaches that have been considered and rejected for now
+ * include: <p>
+ *
+ * <ul>
+ *    <li>Socket-based locks (with/without broadcast protocol)
+ *    <li>Pure NIO locking
+ *    <li>Simple lock file (no heartbeat or polling)
+ *    <li>JNI and native configuration alternatives
+ * </ul>
+ *
+ * Of course, discussions involving and patches implementing improvements
+ * or better alternatives are always welcome. <p>
+ *
+ * As a final note and sign post for developers starting to work with
+ * Java NIO: <p>
+ *
+ * A separate <tt>NIOLockFile</tt> descendent exists specifically
+ * because it was determined though experimenatation that
+ * <tt>java.nio.channels.FileLock</tt> does not always exhibit the correct
+ * or desired behaviour under reflective method invocation. That is, it was
+ * discovered that under some operating system/JVM combinations, after calling
+ * <tt>FileLock.release()</tt> via a reflective method invocation, the lock is
+ * not released properly, deletion of the lock file is not possible even from
+ * the owning object (this) and it is impossible for other <tt>LockFile</tt>
+ * instances, other in-process objects or other processes to successfully obtain
+ * a lock condition on the lock file, despite the fact that the
+ * <tt>FileLock</tt> object reports that its lock is invalid (was released
+ * successfully). Frustratingly, this condition appears to persist until full
+ * exit of the process hosting the JVM in which the <tt>FileLock.tryLock()</tt>
+ * method was reflectively invoked. <p>
+ *
+ * To solve this, the original <tt>LockFile</tt> class was split in two and
+ * instead of reflective method invocation, subclass instantiation is now
+ * performed at the level of the <tt>newLockFile()</tt> factory method.
+ * Similarly, the HSQLDB ANT build script now detects the presence or abscence
+ * of JDK 1.4+ features such as java.nio and only attempts to build and deploy
+ * <tt>NIOLockFile</tt> to the hsqldb.jar if such features are reported
+ * present. <p>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @version 1.8.1.2
+ * @since 1.7.2
+ */
+public class LockFile {
+
+    /**
+     * Arbitary period, in milliseconds, at which heartbeat timestamps are
+     * written to this object's lock file. <p>
+     *
+     * This value was selected to be very conservative, just in case timing
+     * jitters are experienced on the order introduced by brief network
+     * partitions, accidentally removed media and transient high load
+     * CPU bursts.
+     */
+    public static final long HEARTBEAT_INTERVAL = 10000;
+
+    /**
+     * {@link #HEARTBEAT_INTERVAL} + 100. <p>
+     *
+     * Interval used by {@link #checkHeartbeat(boolean) checkHeartbeat} to
+     * test whether the timestamp in the underlying lock file is live or stale.
+     * Padding added in the hope of reducing potential timing jitter issues
+     * under the polling scheme introduced in 1.8.0.3
+     */
+    public static final long HEARTBEAT_INTERVAL_PADDED = 10100;
+
+    /**
+     * Value written at the beginning of an HSQLDB lock file to distinguish it
+     * from other file types. <p>
+     *
+     * The value is the octet sequence: {0x48, 0x53, 0x51, 0x4c, 0x4c, 0x4f,
+     * 0x43, 0x4b}, which is the ASCII sequence {'H', 'S', 'Q', 'L', 'L', 'O',
+     * 'C', 'K'}. <p>
+     *
+     * <b>Design Note</b>: <p>
+     *
+     * "HSQLLOCK".getBytes() is no longer used because it is dependent on the
+     * underlying platform's default character set.
+     */
+    protected static final byte[] MAGIC = {
+        0x48, 0x53, 0x51, 0x4c, 0x4c, 0x4f, 0x43, 0x4b
+    };
+
+    /**
+     * Size, in bytes, of the region at the beginning of a lock file that is
+     * actually used to record lock information. <p>
+     *
+     * Value is currently MAGIC.length + sizeof(long) = (8 + 8) = 16
+     */
+    public static final int USED_REGION = 16;
+
+    /**
+     * Number of retries used by default in {@link #pollHeartbeat()
+     * pollHeartbeat}.
+     */
+    public static final int POLL_RETRIES_DEFAULT = 10;
+
+    /**
+     * System property that can be used to override the default number of
+     * heartbeat poll retries.
+     */
+    public static final String POLL_RETRIES_PROPERTY =
+        "hsqldb.lockfile.poll.retries";
+
+    /**
+     * System property that can be used to override the default number of
+     * milliseconds between each heartbeat poll retry.
+     */
+    public static final String POLL_INTERVAL_PROPERTY =
+        "hsqldb.lockfile.poll.interval";
+
+    /** Whether <tt>java.nio</tt> file locking is attempted by default. */
+    public static final boolean USE_NIO_FILELOCK_DEFAULT = false;
+
+    /**
+     * System property that can be used to control whether nio file locking is
+     * attempted.
+     */
+    public static final String USE_NIO_FILELOCK_PROPERTY =
+        "hsqldb.lockfile.nio.filelock";
+
+    /**
+     * Statically computed indication of <tt>java.nio.channels.FileLock</tt>
+     * runtime availability. <p>
+     *
+     * <b>Design Note</b>:<p>
+     *
+     * Computed in a static initializer block.  Will be <tt>false</tt> if
+     * <tt>USE_NIO_FILELOCK_PROPERTY</tt> is <tt>false</tt> at static
+     * initialization, regardless of actual availability.
+     */
+    public static final boolean NIO_FILELOCK_AVAILABLE;
+
+    /**
+     * Statically computed reference to the <tt>NIOLockFile</tt> class. <p>
+     *
+     * <b>Design Note</b>:<p>
+     *
+     * Computed in a static initializer block.  Will be <tt>null</tt> if
+     * <tt>USE_NIO_FILELOCK_PROPERTY</tt> is <tt>false</tt> at static
+     * initialization, regardless of actual availability.
+     */
+    public static final Class NIO_LOCKFILE_CLASS;
+
+    /**
+     * The timed scheduler with which to register this object's
+     * heartbeat task.
+     */
+    protected static final HsqlTimer timer = DatabaseManager.getTimer();
+
+    // This static initializer comes last, since it references a subclass
+    //
+    // That is, it is best practice to ensure the static fields of this class
+    // are all initialized before referecing a subclass whose static
+    // field initializtion may in turn reference static fields in this class.
+    static {
+        synchronized (LockFile.class) {
+            boolean use = USE_NIO_FILELOCK_DEFAULT;
+
+            try {
+                use = "true".equalsIgnoreCase(
+                    System.getProperty(USE_NIO_FILELOCK_PROPERTY, use ? "true"
+                                                                      : "false"));
+            } catch (Exception e) {}
+
+            boolean avail = false;
+            Class   clazz = null;
+
+            if (use) {
+                try {
+                    Class.forName("java.nio.channels.FileLock");
+
+                    clazz = Class.forName("org.hsqldb.persist.NIOLockFile");
+                    avail = true;
+                } catch (Exception e) {}
+            }
+
+            NIO_FILELOCK_AVAILABLE = avail;
+            NIO_LOCKFILE_CLASS     = clazz;
+        }
+    }
+
+    /**
+     * Canonical reference to this object's lock file. <p>
+     *
+     * <b>Design Note</b>:<p>
+     *
+     * Should really be final, but finality makes reflective construction
+     * and adherence to desirable <tt>LockFile</tt> factory method event
+     * sequence more complicated.
+     */
+    protected File file;
+
+    /**
+     * Cached value of the lock file's canonical path
+     *
+     * <b>Design Note</b>:<p>
+     *
+     * Should really be final, but finality makes reflective construction
+     * and adherence to desirable <tt>LockFile</tt> factory method event
+     * sequence much more complicated.
+     */
+    private String cpath;
+
+    /**
+     * A <tt>RandomAccessFile</tt> constructed from this object's canonical file
+     * reference. <p>
+     *
+     * This <tt>RandomAccessFile</tt> is used to periodically write out the
+     * heartbeat timestamp to this object's lock file.
+     */
+    protected volatile RandomAccessFile raf;
+
+    /** Indicates presence or absence of the cooperative lock condition. */
+    protected volatile boolean locked;
+
+    /** Opaque reference to this object's heatbeat task. */
+    private volatile Object timerTask;
+
+    /**
+     * Retrieves a new <tt>NIOLockFile</tt>, or <tt>null</tt> if not available
+     * under the current runtime environment.
+     *
+     * @return a new <tt>NIOLockFile</tt>, or <tt>null</tt> if not available
+     *      under the current runtime environment
+     */
+    private static final LockFile newNIOLockFile() {
+
+        if (NIO_FILELOCK_AVAILABLE && NIO_LOCKFILE_CLASS != null) {
+            try {
+                return (LockFile) NIO_LOCKFILE_CLASS.newInstance();
+            } catch (Exception e) {
+
+                // e.printStackTrace()
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * To allow subclassing without exposing a public constructor.
+     */
+    protected LockFile() {}
+
+    /**
+     * Retrieves a <tt>LockFile</tt> instance, initialized with a <tt>File</tt>
+     * object whose path is the canonical form of the one specified by the
+     * given <tt>path</tt> argument. <p>
+     *
+     * The resulting <tt>LockFile</tt> instance does not yet hold a lock
+     * condition on the file with the given path, nor does it guarantee that the
+     * file pre-exists or is created.
+     *
+     * However, upon successful execution, it is guaranteed that all required
+     * parent directories have been created and that the underlying platform has
+     * verified the specified path is legal on the file system of the underlying
+     * storage partition.
+     *
+     * @return a <tt>LockFile</tt> instance initialized with a <tt>File</tt>
+     *         object whose path is the one specified by the given <tt>path</tt>
+     *         argument.
+     * @param path the path of the <tt>File</tt> object with which the retrieved
+     *        <tt>LockFile</tt> object is to be initialized
+     * @throws FileCanonicalizationException if an I/O error occurs upon
+     *         canonicalization of the given path, which is possible because
+     *         it may be illegal on the runtime file system or because
+     *         construction of the canonical path name may require native file
+     *         system queries
+     * @throws FileSecurityException if a required system property value cannot
+     *         be accessed, or if a security manager exists and its <tt>{@link
+     *         java.lang.SecurityManager#checkRead}</tt> method denies read
+     *         access to the file; or if its <tt>{@link
+     *         java.lang.SecurityManager#checkRead(java.lang.String)}</tt>
+     *         method does not permit verification of the existence of all
+     *         necessary parent directories; or if the <tt>{@link
+     *         java.lang.SecurityManager#checkWrite(java.lang.String)}</tt>
+     *         method does not permit all necessary parent directories to be
+     *         created
+     */
+    public static final LockFile newLockFile(final String path)
+    throws FileCanonicalizationException, FileSecurityException {
+
+        LockFile lockFile = newNIOLockFile();
+
+        if (lockFile == null) {
+            lockFile = new LockFile();
+        }
+
+        lockFile.setPath(path);
+
+        return lockFile;
+    }
+
+    /**
+     * {@link org.hsqldb.persist.Logger#acquireLock(java.lang.String)}
+     * delegate.<p>
+     *
+     * Retrieves a new <tt>LockFile</tt> object holding a cooperative lock
+     * condition upon the file with the given path, appended with the
+     * extension '.lck'. <p>
+     *
+     * @param path of the lock file, to which will be appended '.lck'
+     * @throws org.hsqldb.HsqlException if the lock condition cannot
+     *      be obtained for any reason.
+     * @return a new <tt>LockFile</tt> object holding a cooperative lock
+     *      condition upon the file with the given path, appended with the
+     *      extension '.lck'
+     */
+    public static final LockFile newLockFileLock(final String path)
+    throws HsqlException {
+
+        LockFile lockFile = null;
+
+        try {
+            lockFile = LockFile.newLockFile(path + ".lck");
+        } catch (LockFile.BaseException e) {
+            throw Error.error(ErrorCode.LOCK_FILE_ACQUISITION_FAILURE,
+                              e.getMessage());
+        }
+
+        boolean locked = false;
+
+        try {
+            locked = lockFile.tryLock();
+        } catch (LockFile.BaseException e) {
+            throw Error.error(ErrorCode.LOCK_FILE_ACQUISITION_FAILURE,
+                              e.getMessage());
+        }
+
+        // Paranoia mode: In theory, this case can't happen, given the way
+        // tryLock now works; by all current understanding of the involved API
+        // contracts, an exception will always be thrown instead by the code
+        // above.
+        if (!locked) {
+            throw Error.error(ErrorCode.LOCK_FILE_ACQUISITION_FAILURE,
+                              lockFile.toString());
+        }
+
+        return lockFile;
+    }
+
+    /**
+     * Checks whether the underlying file is an HSQLDB lock file and, if so,
+     * whether its heartbeat timestamp is live (is, as far as can be known,
+     * presumably in use by another <tt>LockFile</tt> instance) or stale. <p>
+     *
+     * The check conforms to the following rules: <p>
+     *
+     * <ol>
+     * <li>If the parameter <tt>withCreateNewFile</tt> is true, {@link
+     *     java.io.File#createNewFile()} is available and its invocation
+     *     upon this object's <tt>file</tt> object indicates the underlying
+     *     file was atomically created if and only if it did not yet exist,
+     *     then return immediately (we have won the <em>race</em> to establish
+     *     a lock file). <p>
+     *
+     * <li>Test again if the file exists, returning immediately if it does not
+     *     (there's no file and hence no heartbeat to check). <p>
+     *
+     *     An immediate return can occur here only under pre-JDK 1.2 runtimes;
+     *     or when the underlying platform does not correctly support
+     *     <tt>File.createNewFile()</tt>; or when the underlying file is deleted
+     *     within a very short time after i.), above (typically on the order of
+     *     microseconds). <p>
+     *
+     *     If the underlying platform employs a kernel-enforced mandatory file
+     *     locking blanket policy for open files (e.g. <em>Windows</em><sup>tm
+     *     </sup>), then this is likely a non-issue. And if this case makes
+     *     possible a race condition with another <tt>LockFile</tt> object
+     *     (because the test for existence yeilds false and subsequent file
+     *     creation is not atomic relative to all other file system actions), it
+     *     is still <em>very</em> unlikely that so unfortunate a timing will
+     *     occur as to allow simultaneous lock conditions to be established.
+     *     Finally, if some non-<tt>LockFile</tt> entity deleted the file, then
+     *     there are much worse things to worry about, in particular that the
+     *     files this object is supposed to protect are in reality subject to
+     *     arbitrary external modification and deletion by some uncooperative
+     *     process.<p>
+     *
+     * <li>If a Java security exception is thrown while testing for existence,
+     *     it is rethrown as a <tt>FileSecurityException</tt>.
+     *
+     * <li>Read the file's length.
+     *
+     * <li>If a Java security exception is thrown reading length, it is rethrown
+     *     as a <tt>FileSecurityException</tt> (it <em>is</em> possible somebody
+     *     concurrently refreshed the system Policy in the interim).
+     *
+     * <li>If the file does not have the expected length, a
+     *     <tt>WrongLengthException</tt> is thrown (we're trying to check
+     *     something that is not an HSQLDB lock file).
+     *
+     * <li>Open an input steam to read the file's <tt>MAGIC</tt> and heartbeat
+     *     timestamp values.
+     *
+     * <li>If a file not found exception is thrown above, it is rethrown as an
+     *     <tt>UnexpectedFileNotFoundException</tt> (we've already tested for
+     *     existence).
+     *
+     * <li>If a Java security exception is thrown above, it is rethrown as a
+     *     <tt>FileSecurityException</tt> (it <em>is</em> possible somebody
+     *     concurrently refreshed the system Policy in the interim).
+     *
+     * <li>Read the <tt>MAGIC</tt> value.
+     *
+     * <li>If an end of file exepction is thrown above, it is rethrown as an
+     *     <tt>UnexpectedEndOfFileException</tt> (we've already tested the
+     *     length... did someone truncate the file in the interim?).
+     *
+     * <li>If an I/O exception is thrown, it is rethrown as an
+     *     <tt>UnexpectedFileIOException</tt> (we've already tested for
+     *     existence, length and successfully opened a stream...did someone,
+     *     for example, force unmount or physically remove the underlying device
+     *     in the interim?)
+     *
+     * <li>If the value read in does not match the expected <tt>MAGIC</tt> value,
+     *     a <tt>WrongMagicException</tt> is thrown (we're trying to check
+     *     something that is not an HSQLDB lock file).
+     *
+     * <li>Read the heartbeat timestamp.
+     *
+     * <li>If a Java security exception is thrown above, it is rethrown as a
+     *     <tt>FileSecurityException</tt> (it <em>is</em> possible somebody
+     *     concurrently refreshed the system Policy in the interim).
+     *
+     * <li>If an end of file exection is thrown above, it is rethrown as an
+     *     <tt>UnexpectedEndOfFileException</tt> (we've already tested the
+     *     length... did someone truncate the file in the interim?).
+     *
+     * <li>If an I/O exception is thrown, it is rethrown as an
+     *     <tt>UnexpectedFileIOException</tt> (we've already tested for
+     *     existence, length and successfully opened a stream...did someone,
+     *     for example, force unmount or physically remove the underlying device
+     *     in the interim?)
+     *
+     * <li>If the timestamp read in is less than or equal to
+     *     {@link #HEARTBEAT_INTERVAL_PADDED} milliseconds into the past or
+     *     future, then a <tt>LockHeldExternallyException</tt> is thrown.
+     *
+     * <li>Otherwise, this method simply returns.
+     * </ol>
+     *
+     * @param withCreateNewFile if <tt>true</tt>, attempt to employ
+     *      <tt>File.createNewFile()</tt> as part of the check so as to
+     *      eliminate potential race conditions when establising a new
+     *      lock file
+     * @throws FileSecurityException if the check fails due to a Java
+     *      security permission check failure
+     * @throws LockHeldExternallyException if it is determined that the
+     *      file's heartbeat timestamp is less than
+     *      <tt>HEARTBEAT_INTERVAL_PADDED</tt> into the past (or future)
+     * @throws UnexpectedEndOfFileException if an <tt>EOFExceoption</tt> is
+     *      thrown while reading either the magic or heartbeat timestamp values
+     * @throws UnexpectedFileIOException if an <tt>IOException</tt> other than
+     *      <tt>EOFException</tt> is thrown while reading either the magic or
+     *      heartbeat timestamp values
+     * @throws UnexpectedFileNotFoundException if a
+     *      <tt>FileNotFoundException</tt> is thrown while attempting to open a
+     *      stream to read the underlying file's magic and heartbeat timestamp
+     *      values
+     * @throws WrongLengthException if it is determined that the length
+     *      of the file does not equal {@link #USED_REGION}
+     * @throws WrongMagicException if it is determined that the file's
+     *      content does not start with {@link #MAGIC}.
+     */
+    private final void checkHeartbeat(boolean withCreateNewFile)
+    throws LockFile.FileSecurityException,
+           LockFile.LockHeldExternallyException,
+           LockFile.UnexpectedEndOfFileException,
+           LockFile.UnexpectedFileIOException,
+           LockFile.UnexpectedFileNotFoundException,
+           LockFile.WrongLengthException, LockFile.WrongMagicException {
+
+        long now;
+        long lastHeartbeat;
+        long length = 0;
+
+//#ifdef JAVA2FULL
+        try {
+            if (withCreateNewFile) {
+                try {
+                    if (file.createNewFile()) {
+                        return;
+                    }
+                } catch (IOException ioe) {}
+            }
+
+            if (!file.exists()) {
+                return;
+            }
+
+            length = file.length();
+        } catch (SecurityException se) {
+            throw new FileSecurityException(this, "checkHeartbeat", se);
+        }
+
+//#else
+/*
+
+        if (!file.exists()) {
+            if (withCreateNewFile) {
+                openRAF();
+                closeRAF();
+            }
+            return;
+        }
+
+        length = file.length();
+*/
+
+//#endif JAVA2
+        if (length != USED_REGION) {
+            if (length == 0) {
+                file.delete();
+
+                return;
+            }
+
+            throw new WrongLengthException(this, "checkHeartbeat", length);
+        }
+
+        // Compute the current wall clock time *first* to reduce possibility
+        // of unwanted time dilation effects introduced, for example,
+        // by intervening thread or process context switches under CPU
+        // bursts.
+        //
+        // Example:
+        //
+        // Say currentTimeMillis is actually somewhere in (-0.5 and 0.5]
+        // and another LockFile concurrently writes a 0-valued heartbeat
+        // timestamp.
+        //
+        // Then, if readHeartbeat comes first here, happens to 'win the race
+        // condition' (reads the previous heartbeat: -10,000) and an intervening
+        // switch causes greater than ~0.5 millisecond elapsed time to
+        // be experienced between readHeartbeat and currentTimeMillis, then
+        // currentTimeMillis will be computed as n (n > 0), and (now -
+        // lastHearbeat) will be HEARTBEAT_INTERVAL + n, instead of
+        // HEARTBEAT_INTERVAL.
+        //
+        // Now, let n be greater than (HEARTBEAT_INTERVAL_PADDED -
+        // HEARTBEAT_INTERVAL).
+        //
+        // Then the check will succeed, although it should fail.
+        //
+        // On the other hand, if currentTimeMillis is computed first, the
+        // worst than can happen is a false positive indication that
+        // the read heartbeat timestamp value was written by a live LockFile
+        // instance.
+        //
+        now           = System.currentTimeMillis();
+        lastHeartbeat = readHeartbeat();
+
+        // Using padded interval to further reduce corner case effects,
+        // now that heartbeat polling is in effect.
+        //
+        // Basically, it is absolutely essential to fail when a lock really is
+        // still held elsewhere, so it is OK to fail on corner cases where
+        // the last written heartbeat is very close to HEARTBEAT_INTERVAL
+        // in the past and it is possible that timing jitters make it uncertain
+        // whether the lock really is still held.
+        if (Math.abs(now - lastHeartbeat) <= (HEARTBEAT_INTERVAL_PADDED)) {
+            throw new LockHeldExternallyException(this, "checkHeartbeat", now,
+                                                  lastHeartbeat);
+        }
+    }
+
+    /**
+     * Closes this object's {@link #raf RandomAccessFile}. <p>
+     *
+     * As a side-effect, the associated <tt>FileChannel</tt> object, if any,
+     * is closed as well.
+     *
+     * @throws UnexpectedFileIOException if an <tt>IOException</tt> is thrown
+     */
+    private final void closeRAF() throws LockFile.UnexpectedFileIOException {
+
+        if (raf != null) {
+            try {
+                raf.close();
+            } catch (IOException ex) {
+                throw new UnexpectedFileIOException(this, "closeRAF", ex);
+            } finally {
+                raf = null;
+            }
+        }
+    }
+
+    /**
+     * Provides any optional locking actions for the {@link #tryLock()
+     * tryLock()} template method. <p>
+     *
+     * Descendents are free to provide additional functionality here,
+     * using the following rules: <p>
+     *
+     * <b>PRE:</b><p>
+     *
+     * This method is called only from <tt>tryLock()</tt> and it is called if
+     * and only if <tt>tryLock()</tt> successfully invokes
+     * <tt>pollHeartbeat()</tt> and <tt>openRAF()</tt> first. <p>
+     *
+     * From this, it can be inferred that upon entry: <p>
+     *
+     * <ol>
+     * <li><tt>locked == false</tt>.
+     * <li><tt>raf</tt> is a non-null instance that can be used to get a
+     *     <tt>FileChannel</tt> instance, if desired.
+     * <li>the underlying file either did not exist before invoking
+     *     <tt>openRAF()</tt> or it was a valid but stale HSQLDB lock file
+     *     because it:
+     *
+     *     <ol style="list-style-type: lower-roman">
+     *     <li>did exist,
+     *     <li>was readable on <tt>USED_REGION</tt>,
+     *     <li>had the expected length and <tt>MAGIC</tt> value and
+     *     <li>had a stale heartbeat timestamp value.
+     *     </ol>
+     * </ol> <p>
+     *
+     * Further, it can be assumed that this object's heatbeat task is definitely
+     * cancelled and/or has never been scheduled at this point, so whatever
+     * timestamp is recorded in the lock file, if it did pre-exist, was written
+     * by a different <tt>LockFile</tt> instance or as the result of a previous,
+     * successful <tt>tryLock()</tt> invocation upon this <tt>LockFile</tt>
+     * instance. <p>
+     *
+     * Finally, it is important that this method does not rethrow any exceptions
+     * it encounters as unchecked exceptions to the calling context. <p>
+     *
+     * <b>POST:</b><p>
+     *
+     * This method should return <tt>false</tt> if optional locking work is not
+     * performed or if it fails, else <tt>true</tt>. <p>
+     *
+     * In general, if optional locking work fails, then any resources
+     * acquired in the process should be freed before this method returns.
+     * In this way, the surrounding implementation can take advantage of a
+     * <tt>false</tt> return value to avoid calling {@link
+     * #doOptionalReleaseActions() doOptionalReleaseActions()} as part of the
+     * {@link #tryRelease() tryRelease()} method. <p>
+     *
+     * <b>Note:</b><p>
+     *
+     * The default implementation does nothing and always returns
+     * <tt>false</tt>. <p>
+     *
+     * @return <tt>true</tt> if optional lock actions are performed and they
+     *      succeed, else <tt>false</tt>
+     */
+    protected boolean doOptionalLockActions() {
+        return false;
+    }
+
+    /**
+     * Provides any optional release actions for the {@link #tryRelease()
+     * tryRelease()} template method. <p>
+     *
+     * <b>PRE:</b> <p>
+     *
+     * It is important that this method does not rethrow any exceptions
+     * it encounters as unchecked exceptions to the calling context. <p>
+     *
+     * <b>POST:</b> <p>
+     *
+     * In general, <tt>false</tt> should be returned if optional locking work
+     * is not performed or if it fails, else <tt>true</tt>.  However, the return
+     * value is currenly treated  as purely informative. <p>
+     *
+     * <b>Note:</b> <p>
+     *
+     * The default implementation does nothing and always returns false. <p>
+     *
+     * @return <tt>true</tt> if optional release actions are performed and they
+     *      succeed, else <tt>false</tt>
+     */
+    protected boolean doOptionalReleaseActions() {
+        return false;
+    }
+
+    /**
+     * Initializes this object with a <tt>File</tt> object whose path has the
+     * canonical form of the given <tt>path</tt> argument. <p>
+     *
+     *  <b>PRE</b>:<p>
+     *
+     * <ol>
+     *    <li>This method is called once and <em>only</em> once per
+     *        <tt>Lockfile</tt> instance.
+     *
+     *    <li>It is <em>always</em> the first method called after
+     *        <tt>LockFile</tt> construction
+     *
+     *    <li>The supplied <tt>path</tt> argument is <em>never</em>
+     *        <tt>null</tt>.
+     * </ol>
+     *
+     * @param path the abstract path representing the file this object is to
+     *        use as its lock file
+     * @throws FileCanonicalizationException if an I/O error occurs upon
+     *         canonicalization of the given path, which is possible because
+     *         the given path may be illegal on the runtime file system or
+     *         because construction of the canonical pathname may require
+     *         native file system queries
+     * @throws FileSecurityException if a required system property value cannot
+     *         be accessed, or if a Java security manager exists and its
+     *        <tt>{@link java.lang.SecurityManager#checkRead}</tt> method denies
+     *         read access to the file; or if its <tt>{@link
+     *         java.lang.SecurityManager#checkRead(java.lang.String)}</tt>
+     *         method does not permit verification of the existence of
+     *         all necessary parent directories; or if
+     *         its <tt>{@link
+     *         java.lang.SecurityManager#checkWrite(java.lang.String)}</tt>
+     *         method does not permit all necessary parent directories to be
+     *         created
+     */
+    private final void setPath(String path)
+    throws LockFile.FileCanonicalizationException,
+           LockFile.FileSecurityException {
+
+        // Should at least be absolutized for reporting purposes, just in case
+        // a security or canonicalization exception gets thrown.
+        path      = FileUtil.getFileUtil().canonicalOrAbsolutePath(path);
+        this.file = new File(path);
+
+        try {
+            FileUtil.getFileUtil().makeParentDirectories(this.file);
+        } catch (SecurityException ex) {
+            throw new FileSecurityException(this, "setPath", ex);
+        }
+
+        try {
+            this.file = FileUtil.getFileUtil().canonicalFile(path);
+        } catch (SecurityException ex) {
+            throw new FileSecurityException(this, "setPath", ex);
+        } catch (IOException ex) {
+            throw new FileCanonicalizationException(this, "setPath", ex);
+        }
+
+        this.cpath = this.file.getPath();
+    }
+
+    /**
+     * Opens (constructs) this object's {@link #raf RandomAccessFile}. <p>
+     *
+     * @throws UnexpectedFileNotFoundException if a
+     *         <tt>FileNotFoundException</tt> is thrown in reponse to
+     *         constructing the <tt>RandomAccessFile</tt> object.
+     * @throws FileSecurityException if a required system property value cannot
+     *         be accessed, or if a Java security manager exists and its
+     *         <tt>{@link java.lang.SecurityManager#checkRead}</tt> method
+     *         denies read access to the file; or if its <tt>{@link
+     *         java.lang.SecurityManager#checkWrite(java.lang.String)}</tt>
+     *         method denies write access to the file
+     */
+    private final void openRAF()
+    throws LockFile.UnexpectedFileNotFoundException,
+           LockFile.FileSecurityException, LockFile.UnexpectedFileIOException {
+
+        try {
+            raf = new RandomAccessFile(file, "rw");
+        } catch (SecurityException ex) {
+            throw new FileSecurityException(this, "openRAF", ex);
+        } catch (FileNotFoundException ex) {
+            throw new UnexpectedFileNotFoundException(this, "openRAF", ex);
+        } catch (IOException ex) {
+            throw new UnexpectedFileIOException(this, "openRAF", ex);
+        }
+    }
+
+    /**
+     * Checks whether the given <tt>DataInputStream</tt> contains the
+     * {@link #MAGIC} value.
+     *
+     * @param  dis the stream to check
+     * @throws FileSecurityException if a required system property value cannot
+     *         be accessed, or if a Java security manager exists and its
+     *         <tt>{@link java.lang.SecurityManager#checkRead}</tt> method
+     *         denies read access to the file
+     * @throws UnexpectedEndOfFileException if an <tt>EOFException</tt> is
+     *         thrown while reading the <tt>DataInputStream</tt>
+     * @throws UnexpectedFileIOException if an <tt>IOException</tt> other than
+     *         <tt>EOFException</tt> is thrown while reading the
+     *         <tt>DataInputStream</tt>
+     * @throws WrongMagicException if a value other than <tt>MAGIC</tt> is read
+     *         from the <tt>DataInputStream</tt>
+     */
+    private final void checkMagic(final DataInputStream dis)
+    throws LockFile.FileSecurityException,
+           LockFile.UnexpectedEndOfFileException,
+           LockFile.UnexpectedFileIOException, LockFile.WrongMagicException {
+
+        boolean      success = true;
+        final byte[] magic   = new byte[MAGIC.length];
+
+        try {
+            for (int i = 0; i < MAGIC.length; i++) {
+                magic[i] = dis.readByte();
+
+                if (MAGIC[i] != magic[i]) {
+                    success = false;
+                }
+            }
+        } catch (SecurityException ex) {
+            throw new FileSecurityException(this, "checkMagic", ex);
+        } catch (EOFException ex) {
+            throw new UnexpectedEndOfFileException(this, "checkMagic", ex);
+        } catch (IOException ex) {
+            throw new UnexpectedFileIOException(this, "checkMagic", ex);
+        }
+
+        if (!success) {
+            throw new WrongMagicException(this, "checkMagic", magic);
+        }
+    }
+
+    /**
+     * Retrieves the last written hearbeat timestamp from this object's lock
+     * file.  If this object's lock file does not exist, then <tt>Long.MIN_VALUE
+     * </tt> (the earliest time representable as a <tt>long</tt> in Java) is
+     * returned immediately. <p>
+     *
+     * @return the hearbeat timestamp read from this object's lock file,
+     *         as a <tt>long</tt> value or, if this object's lock
+     *         file does not exist, <tt>Long.MIN_VALUE</tt>, the earliest time
+     *         representable as a <tt>long</tt> in Java.
+     * @throws FileSecurityException if a required system property value cannot
+     *         be accessed, or if a Java security manager exists and its
+     *         <tt>{@link java.lang.SecurityManager#checkRead}</tt> method
+     *         denies read access to the file
+     * @throws UnexpectedEndOfFileException if an <tt>EOFException</tt> is
+     *         thrown while attempting to read the target file's <tt>MAGIC</tt>
+     *         or heartbeat timestamp value
+     * @throws UnexpectedFileNotFoundException if, after successfully testing
+     *         for existence, the target file is not found a moment later while
+     *         attempting to read its <tt>MAGIC</tt> and heartbeat timestamp
+     *         values
+     * @throws UnexpectedFileIOException if any other input stream error occurs
+     * @throws WrongMagicException if the lock file does not start with the
+     *         the {@link #MAGIC} value
+     */
+    private final long readHeartbeat()
+    throws LockFile.FileSecurityException,
+           LockFile.UnexpectedFileNotFoundException,
+           LockFile.UnexpectedEndOfFileException,
+           LockFile.UnexpectedFileIOException, LockFile.WrongMagicException {
+
+        FileInputStream fis = null;
+        DataInputStream dis = null;
+
+        try {
+            if (!file.exists()) {
+                return Long.MIN_VALUE;
+            }
+
+            fis = new FileInputStream(file);
+            dis = new DataInputStream(fis);
+
+            checkMagic(dis);
+
+            return dis.readLong();
+        } catch (SecurityException ex) {
+            throw new FileSecurityException(this, "readHeartbeat", ex);
+        } catch (FileNotFoundException ex) {
+            throw new UnexpectedFileNotFoundException(this, "readHeartbeat",
+                    ex);
+        } catch (EOFException ex) {
+            throw new UnexpectedEndOfFileException(this, "readHeartbeat", ex);
+        } catch (IOException ex) {
+            throw new UnexpectedFileIOException(this, "readHeartbeat", ex);
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException ioe) {
+
+                    // ioe.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * Schedules the lock heartbeat task.
+     */
+    private final void startHeartbeat() {
+
+        if (timerTask == null || HsqlTimer.isCancelled(timerTask)) {
+            Runnable runner = new HeartbeatRunner();
+
+            timerTask = timer.schedulePeriodicallyAfter(0, HEARTBEAT_INTERVAL,
+                    runner, true);
+        }
+    }
+
+    /**
+     * Cancels the lock heartbeat task.
+     */
+    private final void stopHeartbeat() {
+
+        if (timerTask != null && !HsqlTimer.isCancelled(timerTask)) {
+            HsqlTimer.cancel(timerTask);
+
+            timerTask = null;
+        }
+    }
+
+    /**
+     * Writes the {@link #MAGIC} value to this object's lock file that
+     * distiguishes it as an HSQLDB lock file. <p>
+     *
+     * @throws FileSecurityException possibly never (seek and write are native
+     *      methods whose JavaDoc entries do not actually specify throwing
+     *      <tt>SecurityException</tt>).  However, it is conceivable that these
+     *      native methods may, in turn, access Java methods that do
+     *      throw <tt>SecurityException</tt>. In this case, a
+     *      <tt>SecurityException</tt> might be thrown if a required system
+     *      property value cannot be accessed, or if a security manager exists
+     *      and its <tt>{@link
+     *      java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)}</tt>
+     *      method denies write access to the file
+     * @throws UnexpectedEndOfFileException if an end of file exception is
+     *      thrown while attempting to write the <tt>MAGIC</tt> value to the
+     *      target file (typically, this cannot happen, but the case is
+     *      included to distiguish it from the general <tt>IOException</tt>
+     *      case).
+     * @throws UnexpectedFileIOException if any other I/O error occurs while
+     *      attepting to write the <tt>MAGIC</tt> value to the target file.
+     */
+    private final void writeMagic()
+    throws LockFile.FileSecurityException,
+           LockFile.UnexpectedEndOfFileException,
+           LockFile.UnexpectedFileIOException {
+
+        try {
+            raf.seek(0);
+            raf.write(MAGIC);
+        } catch (SecurityException ex) {
+            throw new FileSecurityException(this, "writeMagic", ex);
+        } catch (EOFException ex) {
+            throw new UnexpectedEndOfFileException(this, "writeMagic", ex);
+        } catch (IOException ex) {
+            throw new UnexpectedFileIOException(this, "writeMagic", ex);
+        }
+    }
+
+    /**
+     * Writes the current hearbeat timestamp value to this object's lock
+     * file. <p>
+     *
+     * @throws FileSecurityException possibly never (seek and write are native
+     *      methods whose JavaDoc entries do not actually specifiy throwing
+     *      <tt>SecurityException</tt>).  However, it is conceivable that these
+     *      native methods may, in turn, access Java methods that do throw
+     *      <tt>SecurityException</tt>. In this case, a
+     *      <tt>SecurityException</tt> might be thrown if a required system
+     *      property value cannot be accessed, or if a security manager exists
+     *      and its <tt>{@link
+     *      java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)}</tt>
+     *      method denies write access to the file
+     * @throws UnexpectedEndOfFileException if an end of file exception is
+     *      thrown while attepting to write the heartbeat timestamp value to
+     *      the target file (typically, this cannot happen, but the case is
+     *      included to distiguish it from the general IOException case).
+     * @throws UnexpectedFileIOException if the current heartbeat timestamp
+     *      value cannot be written due to an underlying I/O error
+     */
+    private final void writeHeartbeat()
+    throws LockFile.FileSecurityException,
+           LockFile.UnexpectedEndOfFileException,
+           LockFile.UnexpectedFileIOException {
+
+        try {
+            raf.seek(MAGIC.length);
+            raf.writeLong(System.currentTimeMillis());
+        } catch (SecurityException ex) {
+            throw new FileSecurityException(this, "writeHeartbeat", ex);
+        } catch (EOFException ex) {
+            throw new UnexpectedEndOfFileException(this, "writeHeartbeat", ex);
+        } catch (IOException ex) {
+            throw new UnexpectedFileIOException(this, "writeHeartbeat", ex);
+        }
+    }
+
+    /**
+     * Tests whether some other object is "equal to" this one. <p>
+     *
+     * An object is considered equal to a <tt>LockFile</tt> object if and
+     * only if it is not null, it is an instance of <tt>LockFile</tt> and
+     * either it is the identical instance or it has the same lock file.  More
+     * formally, is is considered equal if and only if it is not null, it is an
+     * instance of <tt>LockFile</tt>, and the expression: <p>
+     *
+     * <pre>
+     * this == other ||
+     * this.file == null ? other.file == null : this.file.equals(other.file);
+     * </pre>
+     *
+     * yeilds true. <p>
+     *
+     * Note that <tt>file</tt> must be a canonical reference to correctly
+     * satisfy this contract. <p>
+     *
+     * @param obj the reference object with which to compare.
+     * @return <tt>true</tt> if this object is equal to the <tt>obj</tt>
+     *         argument; <tt>false</tt> otherwise.
+     * @see #hashCode
+     */
+    public final boolean equals(final Object obj) {
+
+        if (this == obj) {
+            return true;
+        } else if (obj instanceof LockFile) {
+            LockFile other = (LockFile) obj;
+
+            return (this.file == null) ? other.file == null
+                                       : this.file.equals(other.file);
+        }
+
+        return false;
+    }
+
+    /**
+     * Retrieves the canonical path of this object's lock file, as a
+     * <tt>String</tt> object. <p>
+     *
+     * @return the canonical path of this object's lock file.
+     */
+    public final String getCanonicalPath() {
+        return cpath;
+    }
+
+    /**
+     * Retrieves the hash code value for this object. <p>
+     *
+     * The value is zero if <tt>file</tt> is <tt>null</tt>, else the
+     * <tt>hashCode</tt> of <tt>file</tt>. That is, two <tt>LockFile</tt>
+     * objects have the same <tt>hashCode</tt> value if they refer to the
+     * same lock file. <p>
+     *
+     * Note that <tt>file</tt> must be a canonical reference to correctly
+     * satisfy this contract. <p>
+     *
+     * @return a hash code value for this object.
+     * @see #equals(java.lang.Object)
+     */
+    public final int hashCode() {
+        return file == null ? 0
+                            : file.hashCode();
+    }
+
+    /**
+     * Retrieves whether this object has successfully obtained and is still
+     * holding (has not yet released) a cooperative lock condition on its
+     * lock file. <p>
+     *
+     * <b>Note:</b> <p>
+     *
+     * Due to platform-independence retrictions placed on a JVM, it is quite
+     * possible to successfully acquire a lock condition and yet for the
+     * condition to become invalid while still held. <p>
+     *
+     * For instance, under JVMs with no <tt>java.nio</tt> package or under
+     * operating systems that do not apply mandatory file locking (espcially
+     * mandatory locking that precludes deletion), it is quite possible for
+     * another process or even an uncooperative bit of code running in the same
+     * JVM to overwrite or delete the target lock file while this object holds
+     * a lock condition. <p>
+     *
+     * Because of this, the <tt>isValid()</tt> method is provided in the public
+     * interface in order to allow clients to detect at least a subset of such
+     * situations. <p>
+     *
+     * @return <tt>true</tt> if this object has successfully obtained and is
+     *        still holding (has not yet released) a lock condition, else
+     *        <tt>false</tt>
+     * @see #isValid
+     */
+    public final boolean isLocked() {
+        return locked;
+    }
+
+    /**
+     * Retrieves whether there is potentially already a cooperative lock,
+     * operating system lock or some other situation preventing a cooperative
+     * lock condition from being aquired using the specified path.
+     *
+     * @param path the path to test
+     * @return <tt>true</tt> if there is currently something preventing the
+     *      acquisition of a cooperative lock condition using the specified
+     *      <tt>path</tt>, else <tt>false</tt>
+     */
+    public final static boolean isLocked(final String path) {
+
+        boolean locked = true;
+
+        try {
+            LockFile lockFile = LockFile.newLockFile(path);
+
+            lockFile.checkHeartbeat(false);
+
+            locked = false;
+        } catch (Exception e) {}
+
+        return locked;
+    }
+
+    /**
+     * Retrieves whether this object holds a valid lock condition on its
+     * lock file. <p>
+     *
+     * More formally, this method retrieves true if and only if: <p>
+     *
+     * <pre>
+     * isLocked() && file != null && file.exists() && raf != null
+     * </pre>
+     *
+     * @return <tt>true</tt> if this object holds a valid lock condition on its
+     *        lock file; else <tt>false</tt>
+     * @throws SecurityException if a required system property value cannot
+     *         be accessed, or if a Java security manager exists and its
+     *         <tt>checkRead</tt> method denies read access to the lock file;
+     */
+    public boolean isValid() {
+        return isLocked() && file != null && file.exists() && raf != null;
+    }
+
+    /**
+     * Retrieves a String representation of this object. <p>
+     *
+     * The String is of the form: <p>
+     *
+     * <pre>
+     * super.toString() +
+     * "[file=" + getCanonicalPath() +
+     * ", exists=" + file.exists() +
+     * ", locked=" + isLocked() +
+     * ", valid=" + isValid() +
+     * ", " + toStringImpl() +
+     * "]";
+     * </pre>
+     *
+     *
+     * @return a String representation of this object.
+     * @see #toStringImpl
+     * @throws SecurityException if a required system property value cannot
+     *         be accessed, or if a security manager exists and its <tt>{@link
+     *         java.lang.SecurityManager#checkRead}</tt> method denies
+     *         read access to the lock file;
+     */
+    public String toString() {
+
+        return new StringBuffer(super.toString()).append("[file =").append(
+            cpath).append(", exists=").append(file.exists()).append(
+            ", locked=").append(isLocked()).append(", valid=").append(
+            isValid()).append(", ").append(toStringImpl()).append(
+            "]").toString();
+    }
+
+    /**
+     * Retrieves an implementation-specific tail value for the
+     * <tt>toString()</tt> method. <p>
+     *
+     * The default implementation returns the empty string.
+     *
+     * @return an implementation-specific tail value for the <tt>toString()</tt>
+     *      method
+     * @see #toString
+     */
+    protected String toStringImpl() {
+        return "";
+    }
+
+    /**
+     * Retrieves the number of times <tt>checkHeartbeat</tt> may fail before
+     * <tt>pollHeartbeat</tt> fails as a consequence. <p>
+     *
+     * The value is obtained in the following manner: <p>
+     *
+     * <ol>
+     * <li>retries is assigned <tt>POLL_RETRIES_DEFAULT</tt>.
+     *
+     * <li>retries is assigned <tt>Integer.getInteger(POLL_RETRIES_PROPERTY,
+     * retries)</tt> inside a try-catch block to silently ignore any security
+     * exception.
+     *
+     * <li>If retries is less than one (1), retries is assigned one (1).
+     * </ol>
+     *
+     * @return the number of times <tt>checkHeartbeat</tt> may fail before
+     *      <tt>pollHeartbeat</tt> fails as a consequence.
+     */
+    public int getPollHeartbeatRetries() {
+
+        int retries = POLL_RETRIES_DEFAULT;
+
+        try {
+            retries = Integer.getInteger(
+                HsqlDatabaseProperties.system_lockfile_poll_retries_property,
+                retries).intValue();
+        } catch (Exception e) {}
+
+        if (retries < 1) {
+            retries = 1;
+        }
+
+        return retries;
+    }
+
+    /**
+     * Retrieves the interval, in milliseconds, that <tt>pollHeartbeat</tt>
+     * waits between failed invocations of <tt>checkHeartbeat</tt>.
+     *
+     * The value is obtained in the following manner: <p>
+     *
+     * <ol>
+     * <li>interval is assigned <tt>10 + (HEARTBEAT_INTERVAL_PADDED
+     * getPollHeartbeatRetries())</tt>
+     *
+     * <li>interval is assigned <tt>Long.getLong(POLL_INTERVAL_PROPERTY,
+     * interval)</tt>, inside a try-catch block, to silently ignore any security
+     * exception.
+     *
+     * <li>If interval is less than or equal to zero (0), interval is reassigned
+     * <tt>10 + (HEARTBEAT_INTERVAL_PADDED / getPollHeartbeatRetries())</tt>
+     * </ol>
+     *
+     * @return the interval, in milliseconds, that <tt>pollHeartbeat</tt>
+     *      waits between failed invocations of <tt>checkHeartbeat</tt>
+     */
+    public long getPollHeartbeatInterval() {
+
+        int  retries  = getPollHeartbeatRetries();
+        long interval = 10 + (HEARTBEAT_INTERVAL_PADDED / retries);
+
+        try {
+            interval = Long.getLong(POLL_INTERVAL_PROPERTY,
+                                    interval).longValue();
+        } catch (Exception e) {}
+
+        if (interval <= 0) {
+            interval = 10 + (HEARTBEAT_INTERVAL_PADDED / retries);
+        }
+
+        return interval;
+    }
+
+    /**
+     * Polls the underlying lock file to determine if a lock condition
+     * exists. <p>
+     *
+     * Specifically, polls {@link #checkHeartbeat(boolean) checkHeartbeat} at
+     * the configured interval until the check passes, the current poll interval
+     * wait state is interrupted or the configured number of poll retries is
+     * reached. <p>
+     *
+     * The last exception thrown by <tt>checkHeartbeat</tt> is re-thrown if no
+     * check passes. <p>
+     *
+     * @throws FileSecurityException if the Java security system denied read
+     *      to the target file
+     * @throws LockHeldExternallyException if the target file's heartbeat
+     *      timestamp indicated that a lock condition was held by another
+     *      <tt>LockFile</tt>.
+     * @throws UnexpectedFileNotFoundException if the target file became
+     *      unavailable between a test for existence and an attempt to read
+     *      the <tt>MAGIC</tt> or heartbeat timestamp value.
+     * @throws UnexpectedEndOfFileException if an <tt>EOFException</tt> was
+     *      raised while trying to read the <tt>MAGIC</tt> or heartbeat
+     *      timestamp value of the target file
+     * @throws UnexpectedFileIOException if an <tt>EOFException</tt> other than
+     *      <tt>EOFException</tt> was raised while trying to read the
+     *      <tt>MAGIC</tt> or heartbeat timestamp value of the target file
+     * @throws WrongLengthException if the target file did not have the
+     *      expected length
+     * @throws WrongMagicException if the target file did not begin with the
+     *      expected <tt>MAGIC</tt> value
+     */
+    private final void pollHeartbeat()
+    throws LockFile.FileSecurityException,
+           LockFile.LockHeldExternallyException,
+           LockFile.UnexpectedFileNotFoundException,
+           LockFile.UnexpectedEndOfFileException,
+           LockFile.UnexpectedFileIOException, LockFile.WrongLengthException,
+           LockFile.WrongMagicException {
+
+        boolean                success  = false;
+        int                    retries  = getPollHeartbeatRetries();
+        long                   interval = getPollHeartbeatInterval();
+        LockFile.BaseException reason   = null;
+
+        for (int i = retries; i > 0; i--) {
+            try {
+                checkHeartbeat(true);    // withCreateNewFile == true
+
+                success = true;
+
+                break;
+            } catch (LockFile.BaseException ex) {
+                reason = ex;
+            }
+
+            // We get here if and only if success == false and reason != null,
+            // so its OK to 'break'
+            try {
+                Thread.sleep(interval);
+            } catch (InterruptedException ex) {
+                break;
+            }
+        }
+
+        /**
+         * @todo:
+         * Do not want to specify just BaseException in the throws clause.
+         * Is this really the cleanest way?
+         */
+        if (!success) {
+            if (reason instanceof FileSecurityException) {
+                throw (FileSecurityException) reason;
+            } else if (reason instanceof LockHeldExternallyException) {
+                throw (LockHeldExternallyException) reason;
+            } else if (reason instanceof UnexpectedFileNotFoundException) {
+                throw (UnexpectedFileNotFoundException) reason;
+            } else if (reason instanceof UnexpectedEndOfFileException) {
+                throw (UnexpectedEndOfFileException) reason;
+            } else if (reason instanceof UnexpectedFileIOException) {
+                throw (UnexpectedFileIOException) reason;
+            } else if (reason instanceof WrongLengthException) {
+                throw (WrongLengthException) reason;
+            } else if (reason instanceof WrongMagicException) {
+                throw (WrongMagicException) reason;
+            }
+        }
+    }
+
+    /**
+     * Attempts to obtain a cooperative lock condition upon this object's lock
+     * file. <p>
+     *
+     * @return <tt>true</tt> if this object already holds a lock or the lock was
+     *      obtained successfully, else <tt>false</tt>
+     * @throws FileSecurityException if the lock condition could not be
+     *      obtained due to a Java security permission violation
+     * @throws LockHeldExternallyException if the lock condition could not
+     *      be obtained because the target file's heartbeat timestamp indicated
+     *      that a lock condition was held by another <tt>LockFile</tt>.
+     * @throws UnexpectedFileNotFoundException if the lock condition could not
+     *      be obtained because the target file became unavailable between a
+     *      successful test for existence and an attempt to read its
+     *      <tt>MAGIC</tt> or heartbeat timestamp value.
+     * @throws UnexpectedEndOfFileException if the lock condition could not be
+     *      obtained because <tt>EOFException</tt> was raised while trying to
+     *      read the <tt>MAGIC</tt> or heartbeat timestamp value of the target
+     *      file
+     * @throws UnexpectedFileIOException if the lock condition could not be
+     *      obtained due to an <tt>IOException</tt> other than
+     *      <tt>EOFException</tt>
+     * @throws WrongLengthException if the lock condition could not be obtained
+     *      because the target file was the wrong length
+     * @throws WrongMagicException if the lock condition could not be obtained
+     *      because the target file had the wrong <tt>MAGIC</tt> value
+     * @return <tt>true</tt> if and only if a lock condition is obtained;
+     *      <tt>false</tt> otherwise.  In general, an exception will
+     *      <em>always</em> be thrown if a lock condition cannot be obtained for
+     *      any reason
+     */
+    public final boolean tryLock()
+    throws LockFile.FileSecurityException,
+           LockFile.LockHeldExternallyException,
+           LockFile.UnexpectedFileNotFoundException,
+           LockFile.UnexpectedEndOfFileException,
+           LockFile.UnexpectedFileIOException, LockFile.WrongLengthException,
+           LockFile.WrongMagicException {
+
+        if (this.locked) {
+            return true;
+        }
+
+        try {
+            pollHeartbeat();
+            openRAF();
+
+            // Must come *after* openRAF to comply with the
+            // doOptionalLockActions() PRE: assertion contract.
+            //
+            // <sigh> In an ideal world, it would be possible from Java to open
+            // a file handle and obtain at least one associated NIO FileLock in
+            // one kernel-enforced atomic operation.  However, we can't even
+            // guarantee that NIO is available.
+            //
+            // Note:
+            // The NIOLockFile version of this operation is 'self cleaning'...
+            // if it fails for some reason, then it does a 'best effort' to
+            // eagerly release and nullify its FileLock object before
+            // returning.
+            doOptionalLockActions();
+
+            // Inlined the following to reduce potential for timing issues
+            // such as initial timer thread startup induced delay of first
+            // pulse.
+            //
+            // In general, what we'll get is two initial pulses in rapid
+            // sucession: one here and one an instant later as a result of
+            // startHeartbeat (which is OK... no harm, and it's one-shot
+            // behaviour, not repeated on every writeHeartbeat)
+            //
+            // Unfortunately, we may occasionally encounter astronomic (at least
+            // in computer time) delays between invocation of startHeartbeat
+            // and the time at which effort is actually expended toward writing
+            // the initial MAGIC and heartbeat timestamp values.
+            //
+            // Another good reason to inline the first writeHeartbeat is to
+            // provide a last line of defence against inter-process as well
+            // as inter-thread race conditions.  That is, exceptions thrown in
+            // HeartbeatRunner.run() do yet get propagated anywhere useful.
+            //
+            // Of course, if we are operating under a fully-featured and correct
+            // NIO implementation, the concerns described above are really
+            // non-issues... at this point, we will have (at least in theory) a
+            // valid OS-enforced file lock.
+            //
+            // But in an ideal world (with or without NIO), any pulse failure in
+            // HeartbeatRunner.run() would flag the database Logger that a
+            // database lock condition violation has occured, preventing further
+            // ad-hoc operation of the database.
+            //
+            // The problem is, if a lock condition has been violated that is
+            // being used by a database instance, what mechanism can be used to
+            // safely checkpoint, backup and/or shut down that instance?  For
+            // all we know, the violation indicates that another instance is now
+            // happily writing to the other database files...
+            //
+            // A prudent course of action to take under detection of a
+            // cooperative lock condition violation in the heartbeatRunner task
+            // would be to perform a 'SCRIPT <file>' to some pre-ordained 'safe'
+            // backup location using a globally unique file name and then do a
+            // 'SHUTDOWN IMMEDIATELY' in one database-scope atomic context (e.g.
+            // a single JDBC statement execution).
+            //
+            // However, by the time a lock condition violation has been detected,
+            // the data cache file (and log/script) may already be quite
+            // corrupted, meaning the resulting script may be totally inaccurate
+            // or worse.
+            //
+            // Bottom line:
+            //
+            // Regardless of this inlining measure, if a lock violation occurs
+            // after startHeartbeat, it's almost certain there's much worse in
+            // store...
+            writeMagic();
+            writeHeartbeat();
+            FileUtil.getFileUtil().deleteOnExit(file);
+
+            this.locked = true;
+
+            startHeartbeat();
+        } finally {
+            if (!locked) {
+
+                // No harm in this...
+                //
+                // If this LockFile is an NIOLockFile instance and
+                // doOptionalLockActions() failed above, then a 'best
+                // effort' optional release was already perfomed and
+                // this will be a no-op.
+                //
+                // On the other hand, if doOptionalLockActions() succeeded, best
+                // to undo them here right away, since the core locking work
+                // failed.
+                //
+                // In practice, however, it is very unlikely for the core
+                // locking work to fail if this LockFile is an NIOLockFile
+                // instance and doOptionalLockActions() succeeded, except
+                // under JVM implementations whose NIO package is broken in
+                // a very specific way.
+                //
+                // Other possibilities include unfortunate timing of events
+                // under certain network file system or removable media
+                // configurations, device umounts, physical removal of storage
+                // media, Java security or file system security policy
+                // updates, etc.
+                doOptionalReleaseActions();
+
+                try {
+                    closeRAF();
+                } catch (Exception ex) {
+
+                    // It's too late to do anything useful with this exception.
+                    //
+                    // we've already/ failed and will let the caller know the
+                    // reason via the exception thrown in the try block.
+                    //
+                    // ex.printStackTrace();
+                }
+            }
+        }
+
+        return this.locked;
+    }
+
+    /**
+     * Attempts to release any cooperative lock condition this object
+     * may hold upon its lock file. <p>
+     *
+     *
+     * @return <tt>true</tt> if this object does not currently hold a
+     *      lock condition or the lock is released completely (including
+     *      successful file deletion), else <tt>false</tt>.
+     * @throws FileSecurityException if a <tt>SecurityException</tt> is raised
+     *      in the process of releasing the lock condition
+     * @throws UnexpectedFileIOException if an IoException is raised in the
+     *      process of releasing the lock condition
+     */
+    public final boolean tryRelease()
+    throws LockFile.FileSecurityException, LockFile.UnexpectedFileIOException {
+
+        boolean released = !locked;
+
+        if (released) {
+            return true;
+        }
+
+        stopHeartbeat();
+        doOptionalReleaseActions();
+
+        UnexpectedFileIOException closeRAFReason = null;
+        FileSecurityException     securityReason = null;
+
+        try {
+            try {
+                closeRAF();
+            } catch (UnexpectedFileIOException ex) {
+                closeRAFReason = ex;
+            }
+
+            try {
+
+                // Hack Alert:
+                //
+                // Even without the presence of concurrent locking attempts,
+                // the delete or exists invocations below occasionally return
+                // false otherwise, perhaps due to a race condition with the
+                // heartbeat timestamp writer task or some nio file lock release
+                // timing issue?
+                //
+                // TODO:
+                //
+                // determine if this is an external constraint or if we can
+                // solve it instead by waiting for any in-progress
+                // writeHeartbeat operation to conclude.
+                Thread.sleep(100);
+            } catch (Exception ex) {
+
+                // ex.printStackTrace();
+            }
+
+            try {
+                released = file.delete();
+
+                // Perhaps excessive...
+                //
+                // Another Lockfile may recreate the file an instant after it is
+                // deleted above (if it it deleted successfully, that is)
+                // released = !file.exists();
+            } catch (SecurityException ex) {
+                securityReason = new FileSecurityException(this, "tryRelease",
+                        ex);
+            }
+        } finally {
+
+            // Regardless of whether all release work succeeds, it is important
+            // to indicate that, from the perspective of this instance, a lock
+            // condition is no longer held.
+            //
+            // However, in a world of concurrent execution, we do not want to
+            // to expose this fact extenally until *after* all release work has
+            // been at least attempted.
+            this.locked = false;
+        }
+
+        if (closeRAFReason != null) {
+            throw closeRAFReason;
+        } else if (securityReason != null) {
+            throw securityReason;
+        }
+
+        return released;
+    }
+
+    /**
+     * Attempts to release this object's cooperative lock condition. <p>
+     *
+     * @throws Throwable if this object encounters an unhandled exception
+     *        while trying to release the cooperative lock condition
+     */
+    protected final void finalize() throws Throwable {
+        this.tryRelease();
+    }
+
+    /**
+     * For internal use only. <p>
+     *
+     * This Runnable class provides the implementation for the timed task
+     * that periodically writes out a heartbeat timestamp to the lock file.<p>
+     */
+    private final class HeartbeatRunner implements Runnable {
+
+        public void run() {
+
+            try {
+                LockFile.this.writeHeartbeat();
+            } catch (Throwable t) {
+                Error.printSystemOut(t.toString());
+            }
+        }
+    }
+
+    /**
+     * Base exception class for lock condition specific exceptions. <p>
+     *
+     */
+    public abstract static class BaseException extends Exception {
+
+        private final LockFile lockFile;
+        private final String   inMethod;
+
+        /**
+         * Constructs a new <tt>LockFile.BaseException</tt>. <p>
+         *
+         * @param lockFile the underlying <tt>LockFile</tt> object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         */
+        public BaseException(final LockFile lockFile, final String inMethod) {
+
+            super();
+
+            if (lockFile == null) {
+                throw new NullPointerException("lockFile");
+            }
+
+            if (inMethod == null) {
+                throw new NullPointerException("inMethod");
+            }
+
+            this.lockFile = lockFile;
+            this.inMethod = inMethod;
+        }
+
+        /**
+         * Subclass-specific override. <p>
+         *
+         * @return representation of <tt>lockFile</tt> and
+         *      <tt>inMethod</tt>, as <tt>String</tt> object
+         */
+        public String getMessage() {    // override
+            return "lockFile: " + lockFile + " method: " + inMethod;
+        }
+
+        /**
+         * Getter for <tt>inMethod</tt> property. <p>
+         *
+         * @return name of method in which exception originally occured
+         */
+        public String getInMethod() {
+            return this.inMethod;
+        }
+
+        /**
+         * Getter for <tt>lockFile</tt> property. <p>
+         *
+         * @return the underlying <tt>LockFile</tt> object
+         */
+        public LockFile getLockFile() {
+            return this.lockFile;
+        }
+    }
+
+    /**
+     * Thrown when canonicalization of a <tt>LockFile</tt> object's target
+     * file path fails. <p>
+     *
+     * This is possible because the given path may be illegal on the runtime
+     * file system or because construction of the canonical pathname may require
+     * filesystem queries.
+     */
+    public static final class FileCanonicalizationException
+    extends BaseException {
+
+        private final IOException reason;
+
+        /**
+         * Constructs a new <tt>FileCanonicalizationException</tt>.<p>
+         *
+         * @param lockFile the underlying <tt>LockFile</tt> object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         * @param reason the exception thrown during canonicalization
+         */
+        public FileCanonicalizationException(final LockFile lockFile,
+                                             final String inMethod,
+                                             final IOException reason) {
+
+            super(lockFile, inMethod);
+
+            this.reason = reason;
+        }
+
+        /**
+         * Retrieves the underlying <tt>IOException</tt>. <p>
+         *
+         * @return Value of property reason.
+         */
+        public IOException getReason() {
+            return this.reason;
+        }
+
+        /**
+         * Subclass-specific override. <p>
+         *
+         * @return representation of <tt>lockFile</tt>, <tt>inMethod</tt> and
+         *      <tt>reason</tt>, as a <tt>String</tt> object
+         */
+        public String getMessage() {    // override
+            return super.getMessage() + " reason: " + reason;
+        }
+    }
+
+    /**
+     * Thrown when access to a <tt>LockFile</tt> object's target file raises a
+     * Java <tt>SecurityEception</tt>. <p>
+     *
+     * This can occur if a required system property value cannot be accessed, or
+     * if a security manager exists and its <tt>{@link
+     * java.lang.SecurityManager#checkRead}</tt> method denies read access to a
+     * file; or if its <tt>{@link
+     * java.lang.SecurityManager#checkRead(java.lang.String)}</tt>
+     * method does not permit verification of the existence of all necessary
+     * parent directories; or if its <tt>{@link
+     * java.lang.SecurityManager#checkWrite(java.lang.String)}</tt>
+     * method does not permit all necessary parent directories to be
+     * created. <p>
+     *
+     */
+    public static final class FileSecurityException extends BaseException {
+
+        private final SecurityException reason;
+
+        /**
+         * Constructs a new <tt>FileSecurityException</tt>. <p>
+         *
+         * @param lockFile the underlying LockFile object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         * @param reason the underlying Java security exception
+         */
+        public FileSecurityException(final LockFile lockFile,
+                                     final String inMethod,
+                                     final SecurityException reason) {
+
+            super(lockFile, inMethod);
+
+            this.reason = reason;
+        }
+
+        /**
+         * Retrieves the underlying <tt>SecurityException</tt>. <p>
+         *
+         * @return Value of property reason.
+         */
+        public SecurityException getReason() {
+            return this.reason;
+        }
+
+        /**
+         * Subclass-specific override.
+         *
+         * @return representation of lockFile, inMethod and reason, as
+         *      a String object
+         */
+        public String getMessage() {    // override
+            return super.getMessage() + " reason: " + reason;
+        }
+    }
+
+    /**
+     * Thrown when an externally held lock condition prevents lock
+     * aquisition. <p>
+     *
+     * Specifically, this exception is thrown when polling fails because the
+     * lock file's heartbeat timestamp value indicates that another LockFile
+     * object still holds the lock condition. <p>
+     *
+     */
+    public static final class LockHeldExternallyException
+    extends BaseException {
+
+        private final long read;
+        private final long heartbeat;
+
+        /**
+         * Constructs a new <tt>LockHeldExternallyException</tt>. <p>
+         *
+         * @param lockFile the underlying <tt>LockFile</tt> object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         * @param read the time, in milliseconds since 1970-01-01, at which
+         *      the heartbeat timestamp value was read from the lock file
+         * @param heartbeat the heartbeat timestamp value, in milliseconds
+         *      since 1970-01-01, that was read from the lock file.
+         */
+        public LockHeldExternallyException(final LockFile lockFile,
+                                           final String inMethod,
+                                           final long read,
+                                           final long heartbeat) {
+
+            super(lockFile, inMethod);
+
+            this.read      = read;
+            this.heartbeat = heartbeat;
+        }
+
+        /**
+         * Getter for the <tt>heartbeat</tt> attribute. <p>
+         *
+         * @return the heartbeat timestamp value, in milliseconds since
+         *      1970-01-01, that was read from the lock file.
+         */
+        public long getHeartbeat() {
+            return this.heartbeat;
+        }
+
+        /**
+         * Getter for the <tt>read</tt> attribute. <p>
+         *
+         * @return the time, in milliseconds since 1970-01-01, that
+         *      the heartbeat timestamp value was read from the lock file.
+         */
+        public long getRead() {
+            return this.read;
+        }
+
+        /**
+         * Subclass-specific override. <p>
+         *
+         * @return representation of <tt>lockFile</tt>, <tt>inMethod</tt>,
+         *      <tt>read</tt> and <tt>heartbeat</tt>, as a <tt>String</tt>
+         *      object
+         */
+        public String getMessage() {    // override
+
+            return super.getMessage() + " read: "
+                   + HsqlDateTime.getTimestampString(this.read)
+                   + " heartbeat - read: " + (this.heartbeat - this.read)
+                   + " ms.";
+        }
+    }
+
+    /**
+     * Thrown when access to a <tt>LockFile</tt> object's target file raises an
+     * unexpected <tt>EOFException</tt>.
+     */
+    public static final class UnexpectedEndOfFileException
+    extends BaseException {
+
+        private final EOFException reason;
+
+        /**
+         * Constructs a new <tt>UnexpectedEndOfFileException</tt>. <p>
+         *
+         * @param lockFile the underlying <tt>LockFile</tt> object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         * @param reason the underlying exception
+         */
+        public UnexpectedEndOfFileException(final LockFile lockFile,
+                                            final String inMethod,
+                                            final EOFException reason) {
+
+            super(lockFile, inMethod);
+
+            this.reason = reason;
+        }
+
+        /**
+         * Retrieves the underlying <tt>EOFException<tt>. <p>
+         *
+         * @return Value of property reason.
+         */
+        public EOFException getReason() {
+            return this.reason;
+        }
+
+        /**
+         * Subclass-specific override. <p>
+         *
+         * @return representation of <tt>lockFile<tt>, <tt>inMethod</tt> and
+         *      <tt>reason</tt>, as a <tt>String</tt> object
+         */
+        public String getMessage() {    // override
+            return super.getMessage() + " reason: " + reason;
+        }
+    }
+
+    /**
+     * Thrown when access to a <tt>LockFile</tt> object's target file raises an
+     * unexpected <tt>IOException</tt> other than <tt>EOFException</tt>.
+     */
+    public static final class UnexpectedFileIOException extends BaseException {
+
+        private final IOException reason;
+
+        /**
+         * Constructs a new <tt>UnexpectedFileIOException<tt>.
+         *
+         * @param lockFile the underlying <tt>LockFile</tt> object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         * @param reason the underlying exception
+         */
+        public UnexpectedFileIOException(final LockFile lockFile,
+                                         final String inMethod,
+                                         final IOException reason) {
+
+            super(lockFile, inMethod);
+
+            this.reason = reason;
+        }
+
+        /**
+         * Retrieves the underlying <tt>IOException</tt>.
+         *
+         * @return Value of property reason.
+         */
+        public IOException getReason() {
+            return this.reason;
+        }
+
+        /**
+         * Subclass-specific override.
+         *
+         * @return representation of <tt>lockFile</tt>, <tt>inMethod</tt> and
+         *      <tt>reason</tt>, as a <tt>String</tt> object
+         */
+        public String getMessage() {    // override
+            return super.getMessage() + " reason: " + reason;
+        }
+    }
+
+    /**
+     * Thrown when access to a <tt>LockFile</tt> object's target file raises an
+     * unexpected <tt>FileNotFoundException</tt>.
+     */
+    public static final class UnexpectedFileNotFoundException
+    extends BaseException {
+
+        private final FileNotFoundException reason;
+
+        /**
+         * Constructs a new <tt>UnexpectedFileNotFoundException<tt>. <p>
+         *
+         * @param lockFile the underlying <tt>LockFile</tt> object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         * @param reason the underlying exception
+         */
+        public UnexpectedFileNotFoundException(
+                final LockFile lockFile, final String inMethod,
+                final FileNotFoundException reason) {
+
+            super(lockFile, inMethod);
+
+            this.reason = reason;
+        }
+
+        /**
+         * Retrieves the underlying FileNotFoundException.
+         *
+         * @return Value of property reason.
+         */
+        public FileNotFoundException getReason() {
+            return this.reason;
+        }
+
+        /**
+         * Subclass-specific override.
+         *
+         * @return representation of lockFile, inMethod and reason, as
+         *      a String object
+         */
+        public String getMessage() {    // override
+            return super.getMessage() + " reason: " + reason;
+        }
+    }
+
+    /**
+     * Thrown when it is detected that a LockFile object's target file does not
+     * have the expected length.
+     */
+    public static final class WrongLengthException extends BaseException {
+
+        private final long length;
+
+        /**
+         * Constructs a new WrongLengthException.
+         *
+         * @param lockFile the underlying LockFile object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         * @param length the actual length reported by the file system
+         */
+        public WrongLengthException(final LockFile lockFile,
+                                    final String inMethod, final long length) {
+
+            super(lockFile, inMethod);
+
+            this.length = length;
+        }
+
+        /**
+         * Retreives the actual length reported by the file system.
+         *
+         * @return the actual length reported by the file system
+         */
+        public long getLength() {
+            return this.length;
+        }
+
+        /**
+         * Subclass-specific override.
+         *
+         * @return representation of lockFile, inMethod and length, as
+         *      a String object
+         */
+        public String getMessage() {    // override
+            return super.getMessage() + " length: " + length;
+        }
+    }
+
+    /**
+     * Thrown when it is detected that a LockFile object's target file does not
+     * start with the expected MAGIC value.
+     */
+    public static final class WrongMagicException extends BaseException {
+
+        private final byte[] magic;
+
+        /**
+         * Constructs a new WrongMagicException.
+         *
+         * @param lockFile the underlying LockFile object
+         * @param inMethod the name of the method in which the exception
+         *        was originally thrown (may be passed up serveral levels)
+         * @param magic the actual magic value read from the file
+         */
+        public WrongMagicException(final LockFile lockFile,
+                                   final String inMethod, final byte[] magic) {
+
+            super(lockFile, inMethod);
+
+            this.magic = magic;
+        }
+
+        /**
+         * Subclass-specific override.
+         *
+         * @return representation of inMethod, file and magic,
+         *      as a String object
+         */
+        public String getMessage() {    // override
+
+            String message = super.getMessage() + " magic: ";
+
+            message = message + ((magic == null) ? "null"
+                                                 : "'"
+                                                   + StringConverter.byteArrayToHexString(magic)
+                                                   + "'");
+
+            return message;
+        }
+
+        /**
+         * Retrieves a copy of the actual <tt>MAGIC</tt> value read from the
+         * file. <p>
+         *
+         * @return a copy of the actual <tt>MAGIC</tt> value read from the file
+         */
+        public byte[] getMagic() {
+            return (magic == null) ? null
+                                   : (byte[]) this.magic.clone();
+        }
+    }
+}
diff --git a/src/org/hsqldb/persist/Log.java b/src/org/hsqldb/persist/Log.java
new file mode 100644
index 0000000..ce3220e
--- /dev/null
+++ b/src/org/hsqldb/persist/Log.java
@@ -0,0 +1,914 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.hsqldb.Database;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.HsqlException;
+import org.hsqldb.NumberSequence;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.FileAccess;
+import org.hsqldb.lib.FileArchiver;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.scriptio.ScriptReaderBase;
+import org.hsqldb.scriptio.ScriptReaderDecode;
+import org.hsqldb.scriptio.ScriptReaderText;
+import org.hsqldb.scriptio.ScriptWriterBase;
+import org.hsqldb.scriptio.ScriptWriterEncode;
+import org.hsqldb.scriptio.ScriptWriterText;
+
+// fredt@users 20020215 - patch 1.7.0 by fredt
+// to move operations on the database.properties files to new
+// class HsqlDatabaseProperties
+// fredt@users 20020220 - patch 488200 by xclayl@users - throw exception
+// throw addded to all methods relying on file io
+// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
+// fredt@users 20020405 - patch 1.7.0 by fredt - no change in db location
+// because important information about the database is now stored in the
+// *.properties file, all database files should be in the same folder as the
+// *.properties file
+// tony_lai@users 20020820 - export hsqldb.log_size to .properties file
+// tony_lai@users 20020820 - changes to shutdown compact to save memory
+// fredt@users 20020910 - patch 1.7.1 by Nitin Chauhan - code improvements
+// fredt@users 20021208 - ongoing revamp
+// fredt@users 20021212 - do not rewrite the *.backup file if the *.data
+// file has not been updated in the current session.
+// boucherb@users 20030510 - patch 1.7.2 consolidated all periodic database
+// tasks in one timed task queue
+// fredt@users - 20050102 patch 1.8.0 - refactoring and clearer separation of concerns
+/*
+    - if props.modified, use .backup file - .data file is ready
+    - read .script file and set index roots
+
+
+    - if .data file is modified, use .backup with .data file flag for increment backup - .data file is ready
+*/
+
+/**
+ *  This class is responsible for managing the database files. An HSQLDB database
+ *  consists of a .properties file, a .script file (contains an SQL script),
+ *  a .data file (contains data of cached tables) a .backup file
+ *  and a .log file.<p>
+ *  When using TEXT tables, a data source for each table is also present.<p>
+ *
+ *  Notes on OpenOffice.org integration.
+ *
+ *  A Storage API is used when HSQLDB is integrated into OpenOffice.org. All
+ *  file operations on the 4 main files are performed by OOo, which integrates
+ *  the contents of these files into its database file. The script format is
+ *  always TEXT in this case.
+ *
+ * Extensively rewritten and extended in successive versions of HSQLDB.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class Log {
+
+    private HsqlDatabaseProperties properties;
+    private String                 fileName;
+    private Database               database;
+    private FileAccess             fa;
+    ScriptWriterBase               dbLogWriter;
+    private String                 scriptFileName;
+    private String                 logFileName;
+    private boolean                filesReadOnly;
+    private long                   maxLogSize;
+    private int                    writeDelay;
+    private int                    scriptFormat;
+    private DataFileCache          cache;
+
+    // We are using persist.Logger-instance-specific FrameworkLogger
+    // because it is Database-instance specific.
+    // If add any static level logging, should instantiate a standard,
+    // context-agnostic FrameworkLogger for that purpose.
+    Log(Database db) {
+
+        database   = db;
+        fa         = db.logger.getFileAccess();
+        fileName   = db.getPath();
+        properties = db.getProperties();
+    }
+
+    void initParams() {
+
+        // Allows the user to set log size in the properties file.
+        maxLogSize     = database.logger.propLogSize * 1024L * 1024;
+        scriptFormat   = 0;
+        writeDelay     = database.logger.propWriteDelay;
+        filesReadOnly  = database.isFilesReadOnly();
+        scriptFileName = fileName + ".script";
+        logFileName    = fileName + ".log";
+    }
+
+    /**
+     * When opening a database, the hsqldb.compatible_version property is
+     * used to determine if this version of the engine is equal to or greater
+     * than the earliest version of the engine capable of opening that
+     * database.<p>
+     *
+     * @throws  HsqlException
+     */
+    void open() {
+
+        initParams();
+
+        int state = properties.getDBModified();
+
+        switch (state) {
+
+            case HsqlDatabaseProperties.FILES_MODIFIED :
+                deleteNewAndOldFiles();
+                processScript();
+                processLog();
+                close(false);
+
+                if (cache != null) {
+                    cache.open(filesReadOnly);
+                }
+
+                reopenAllTextCaches();
+                break;
+
+            case HsqlDatabaseProperties.FILES_NEW :
+                renameNewDataFile();
+                renameNewBackup();
+                renameNewScript();
+                deleteLog();
+                properties.setDBModified(
+                    HsqlDatabaseProperties.FILES_NOT_MODIFIED);
+
+            // continue as non-modified files
+            // fall through
+            case HsqlDatabaseProperties.FILES_NOT_MODIFIED :
+
+                /**
+                 * if startup is after a SHUTDOWN SCRIPT and there are CACHED
+                 * or TEXT tables, perform a checkpoint so that the .script
+                 * file no longer contains CACHED or TEXT table rows.
+                 */
+                processScript();
+
+                if (isAnyCacheModified()) {
+                    properties.setDBModified(
+                        HsqlDatabaseProperties.FILES_MODIFIED);
+                    close(false);
+
+                    if (cache != null) {
+                        cache.open(filesReadOnly);
+                    }
+
+                    reopenAllTextCaches();
+                }
+                break;
+        }
+
+        openLog();
+
+        if (!filesReadOnly) {
+            properties.setDBModified(HsqlDatabaseProperties.FILES_MODIFIED);
+        }
+    }
+
+    /**
+     * Close all the database files. If script argument is true, no .data
+     * or .backup file will remain and the .script file will contain all the
+     * data of the cached tables as well as memory tables.
+     *
+     * This is not used for filesReadOnly databases which use shutdown.
+     */
+    void close(boolean script) {
+
+        closeLog();
+        deleteNewAndOldFiles();
+        writeScript(script);
+        closeAllTextCaches(script);
+
+        if (cache != null) {
+            cache.close(true);
+        }
+
+        // set this one last to save the props
+        properties.setDBModified(HsqlDatabaseProperties.FILES_NEW);
+        deleteLog();
+
+        if (cache != null) {
+            if (script) {
+                cache.deleteFile();
+                cache.deleteBackup();
+            } else {
+                cache.backupFile();
+                cache.renameBackupFile();
+            }
+        }
+
+        renameNewScript();
+        properties.setDBModified(HsqlDatabaseProperties.FILES_NOT_MODIFIED);
+    }
+
+    /**
+     * Fast counterpart to close(). Does not perform a checkpoint or a backup
+     * of the .data file.
+     */
+    void shutdown() {
+
+        synchLog();
+
+        if (cache != null) {
+            cache.close(false);
+        }
+
+        closeAllTextCaches(false);
+        closeLog();
+    }
+
+    /**
+     * Deletes the leftovers from any previous unfinished operations.
+     */
+    void deleteNewAndOldFiles() {
+
+        fa.removeElement(fileName + ".data" + ".old");
+        fa.removeElement(fileName + ".data" + ".new");
+        fa.removeElement(fileName + ".backup" + ".new");
+        fa.removeElement(scriptFileName + ".new");
+    }
+
+    void deleteBackup() {
+        fa.removeElement(fileName + ".backup");
+    }
+
+    void deleteData() {
+        fa.removeElement(fileName + ".data");
+    }
+
+    void backupData() throws IOException {
+
+        if (database.logger.propIncrementBackup) {
+            fa.removeElement(fileName + ".backup");
+
+            return;
+        }
+
+        if (fa.isStreamElement(fileName + ".data")) {
+            FileArchiver.archive(fileName + ".data", fileName + ".backup.new",
+                                 database.logger.getFileAccess(),
+                                 FileArchiver.COMPRESSION_ZIP);
+        }
+    }
+
+    void renameNewDataFile() {
+
+        if (fa.isStreamElement(fileName + ".data.new")) {
+            fa.renameElement(fileName + ".data.new", fileName + ".data");
+        }
+    }
+
+    void renameNewBackup() {
+
+        // required for inc backup
+        fa.removeElement(fileName + ".backup");
+
+        if (fa.isStreamElement(fileName + ".backup.new")) {
+            fa.renameElement(fileName + ".backup.new", fileName + ".backup");
+        }
+    }
+
+    void renameNewScript() {
+
+        if (fa.isStreamElement(scriptFileName + ".new")) {
+            fa.renameElement(scriptFileName + ".new", scriptFileName);
+        }
+    }
+
+    void deleteNewScript() {
+        fa.removeElement(scriptFileName + ".new");
+    }
+
+    void deleteNewBackup() {
+        fa.removeElement(fileName + ".backup.new");
+    }
+
+    void deleteLog() {
+        fa.removeElement(logFileName);
+    }
+
+    /**
+     * Checks all the caches and returns true if the modified flag is set for any
+     */
+    boolean isAnyCacheModified() {
+
+        if (cache != null && cache.isFileModified()) {
+            return true;
+        }
+
+        return isAnyTextCacheModified();
+    }
+
+    /**
+     * Performs checkpoint including pre and post operations. Returns to the
+     * same state as before the checkpoint.
+     */
+    void checkpoint(boolean defrag) {
+
+        if (filesReadOnly) {
+            return;
+        }
+
+        if (cache == null) {
+            defrag = false;
+        } else if (forceDefrag()) {
+            defrag = true;
+        }
+
+        if (defrag) {
+            try {
+                defrag();
+
+                return;
+            } catch (Exception e) {
+                database.logger.checkpointDisabled = true;
+
+                return;
+            }
+        }
+
+        boolean result = checkpointClose();
+
+        if (result) {
+            checkpointReopen();
+        }
+    }
+
+    /**
+     * Performs checkpoint including pre and post operations. Returns to the
+     * same state as before the checkpoint.
+     */
+    boolean checkpointClose() {
+
+        if (filesReadOnly) {
+            return true;
+        }
+
+        deleteNewAndOldFiles();
+
+        try {
+            writeScript(false);
+        } catch (HsqlException e) {
+            deleteNewScript();
+
+            return false;
+        }
+
+        try {
+            if (cache != null) {
+                cache.close(true);
+                cache.backupFile();
+            }
+        } catch (Exception ee) {
+
+            // backup failed perhaps due to lack of disk space
+            deleteNewScript();
+            deleteNewBackup();
+
+            try {
+                if (!cache.isFileOpen()) {
+                    cache.open(false);
+                }
+            } catch (Exception e1) {}
+
+            return false;
+        }
+
+        properties.setDBModified(HsqlDatabaseProperties.FILES_NEW);
+        closeLog();
+        deleteLog();
+        renameNewScript();
+        renameNewBackup();
+
+        try {
+            properties.setDBModified(
+                HsqlDatabaseProperties.FILES_NOT_MODIFIED);
+        } catch (Exception e) {}
+
+        return true;
+    }
+
+    boolean checkpointReopen() {
+
+        if (filesReadOnly) {
+            return true;
+        }
+
+        try {
+            if (cache != null) {
+                cache.open(false);
+            }
+
+            if (dbLogWriter != null) {
+                openLog();
+            }
+
+            properties.setDBModified(HsqlDatabaseProperties.FILES_MODIFIED);
+        } catch (Exception e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     *  Writes out all the rows to a new file without fragmentation.
+     */
+    public void defrag() {
+
+        if (cache.fileFreePosition == cache.initialFreePos) {
+            return;
+        }
+
+        database.logger.logInfoEvent("defrag start");
+
+        try {
+
+// test
+/*            {
+                Session session = database.getSessionManager().getSysSession();
+                HsqlArrayList allTables =
+                    database.schemaManager.getAllTables();
+
+                for (int i = 0, tSize = allTables.size(); i < tSize; i++) {
+                    Table t     = (Table) allTables.get(i);
+                    int   count = 0;
+
+                    if (t.getTableType() == TableBase.CACHED_TABLE) {
+                        RowIterator it = t.rowIterator(session);
+
+                        for (; it.hasNext(); count++) {
+                            CachedObject row = it.getNextRow();
+                        }
+
+                        System.out.println("table " + t.getName().name + " "
+                                           + count);
+                    }
+                }
+            }
+*/
+
+//
+            DataFileDefrag dfd = cache.defrag();
+        } catch (HsqlException e) {
+            database.logger.logSevereEvent("defrag failure", e);
+
+            throw (HsqlException) e;
+        } catch (Throwable e) {
+            database.logger.logSevereEvent("defrag failure", e);
+
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, e);
+        }
+
+// test
+/*
+        {
+            Session session = database.getSessionManager().getSysSession();
+            HsqlArrayList allTables = database.schemaManager.getAllTables();
+
+            for (int i = 0, tSize = allTables.size(); i < tSize; i++) {
+                Table t     = (Table) allTables.get(i);
+                int   count = 0;
+
+                if (t.getTableType() == Table.CACHED_TABLE) {
+                    RowIterator it = t.rowIterator(session);
+
+                    for (; it.hasNext(); count++) {
+                        CachedObject row = it.getNextRow();
+                    }
+
+                    System.out.println("table " + t.getName().name + " "
+                                       + count);
+                }
+            }
+        }
+*/
+
+//
+        database.logger.logInfoEvent("defrag end");
+    }
+
+    /**
+     * Returns true if lost space is above the threshold percentage
+     */
+    boolean forceDefrag() {
+
+        long limit = database.logger.propCacheDefragLimit
+                     * cache.getFileFreePos() / 100;
+        long lostSize = cache.freeBlocks.getLostBlocksSize();
+
+        return limit > 0 && lostSize > limit;
+    }
+
+    /**
+     *
+     */
+    boolean hasCache() {
+        return cache != null;
+    }
+
+    /**
+     * Responsible for creating the cache instance.
+     */
+    DataFileCache getCache() {
+
+        if (cache == null) {
+            cache = new DataFileCache(database, fileName);
+
+            cache.open(filesReadOnly);
+        }
+
+        return cache;
+    }
+
+    void setLogSize(int megas) {
+        maxLogSize = megas * 1024L * 1024;
+    }
+
+    int getScriptType() {
+        return scriptFormat;
+    }
+
+    /**
+     * Write delay specifies the frequency of FileDescriptor.sync() calls.
+     */
+    int getWriteDelay() {
+        return writeDelay;
+    }
+
+    void setWriteDelay(int delay) {
+
+        writeDelay = delay;
+
+        if (dbLogWriter != null) {
+            dbLogWriter.forceSync();
+            dbLogWriter.stop();
+            dbLogWriter.setWriteDelay(delay);
+            dbLogWriter.start();
+        }
+    }
+
+    public void setIncrementBackup(boolean val) {
+
+        if (cache != null) {
+            cache.setIncrementBackup(val);
+
+            cache.fileModified = true;
+        }
+    }
+
+    /**
+     * Various writeXXX() methods are used for logging statements.
+     */
+    void writeStatement(Session session, String s) {
+
+        try {
+            dbLogWriter.writeLogStatement(session, s);
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, logFileName);
+        }
+
+        if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
+            database.logger.checkpointRequired = true;
+        }
+    }
+
+    void writeInsertStatement(Session session, Table t, Object[] row) {
+
+        try {
+            dbLogWriter.writeInsertStatement(session, t, row);
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, logFileName);
+        }
+
+        if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
+            database.logger.checkpointRequired = true;
+        }
+    }
+
+    void writeDeleteStatement(Session session, Table t, Object[] row) {
+
+        try {
+            dbLogWriter.writeDeleteStatement(session, t, row);
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, logFileName);
+        }
+
+        if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
+            database.logger.checkpointRequired = true;
+        }
+    }
+
+    void writeSequenceStatement(Session session, NumberSequence s) {
+
+        try {
+            dbLogWriter.writeSequenceStatement(session, s);
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, logFileName);
+        }
+
+        if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
+            database.logger.checkpointRequired = true;
+        }
+    }
+
+    void writeCommitStatement(Session session) {
+
+        try {
+            dbLogWriter.writeCommitStatement(session);
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, logFileName);
+        }
+
+        if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
+            database.logger.checkpointRequired = true;
+        }
+    }
+
+    void synchLog() {
+
+        if (dbLogWriter != null) {
+            dbLogWriter.sync();
+        }
+    }
+
+    /**
+     * Wrappers for openning-starting / stoping-closing the log file and
+     * writer.
+     */
+    void openLog() {
+
+        if (filesReadOnly) {
+            return;
+        }
+
+        Crypto crypto = database.logger.getCrypto();
+
+        try {
+            if (crypto == null) {
+                dbLogWriter = new ScriptWriterText(database, logFileName,
+                                                   false, false, false);
+            } else {
+                dbLogWriter = new ScriptWriterEncode(database, logFileName,
+                                                     crypto);
+            }
+
+            dbLogWriter.setWriteDelay(writeDelay);
+            dbLogWriter.start();
+        } catch (Exception e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, logFileName);
+        }
+    }
+
+    synchronized void closeLog() {
+
+        if (dbLogWriter != null) {
+            dbLogWriter.close();
+        }
+    }
+
+    /**
+     * Write the .script file as .script.new.
+     */
+    void writeScript(boolean full) {
+
+        deleteNewScript();
+
+        ScriptWriterBase scw;
+        Crypto           crypto = database.logger.getCrypto();
+
+        if (crypto == null) {
+            scw = new ScriptWriterText(database, scriptFileName + ".new",
+                                       full, true, false);
+        } else {
+            scw = new ScriptWriterEncode(database, scriptFileName + ".new",
+                                         full, crypto);
+        }
+
+        scw.writeAll();
+        scw.close();
+    }
+
+    /**
+     * Performs all the commands in the .script file.
+     */
+    private void processScript() {
+
+        ScriptReaderBase scr = null;
+
+        try {
+            if (fa.isStreamElement(scriptFileName)) {
+                Crypto crypto = database.logger.getCrypto();
+
+                if (crypto == null) {
+                    scr = new ScriptReaderText(database, scriptFileName);
+                } else {
+                    scr = new ScriptReaderDecode(database, scriptFileName,
+                                                 crypto);
+                }
+
+                Session session =
+                    database.sessionManager.getSysSessionForScript(database);
+
+                scr.readAll(session);
+                scr.close();
+            }
+        } catch (Throwable e) {
+            if (scr != null) {
+                scr.close();
+
+                if (cache != null) {
+                    cache.close(false);
+                }
+
+                closeAllTextCaches(false);
+            }
+
+            database.logger.logWarningEvent("Script processing failure", e);
+
+            if (e instanceof HsqlException) {
+                throw (HsqlException) e;
+            } else if (e instanceof IOException) {
+                throw Error.error(ErrorCode.FILE_IO_ERROR, e);
+            } else if (e instanceof OutOfMemoryError) {
+                throw Error.error(ErrorCode.OUT_OF_MEMORY);
+            } else {
+                throw Error.error(ErrorCode.GENERAL_ERROR, e);
+            }
+        }
+    }
+
+    /**
+     * Performs all the commands in the .log file.
+     */
+    private void processLog() {
+
+        if (fa.isStreamElement(logFileName)) {
+            ScriptRunner.runScript(database, logFileName);
+        }
+    }
+
+// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) - text tables
+    private HashMap textCacheList = new HashMap();
+
+    DataFileCache openTextCache(Table table, String source,
+                                boolean readOnlyData, boolean reversed) {
+
+        closeTextCache(table);
+
+        if (database.getType() != DatabaseURL.S_RES
+                && !properties.isPropertyTrue(
+                    HsqlDatabaseProperties.textdb_allow_full_path)) {
+            if (source.indexOf("..") != -1) {
+                throw (Error.error(ErrorCode.ACCESS_IS_DENIED, source));
+            }
+
+            String path = new File(
+                new File(
+                    database.getPath()
+                    + ".properties").getAbsolutePath()).getParent();
+
+            if (path != null) {
+                source = path + File.separator + source;
+            }
+        }
+
+        TextCache c = new TextCache(table, source);
+
+        c.open(readOnlyData || filesReadOnly);
+        textCacheList.put(table.getName(), c);
+
+        return c;
+    }
+
+    void closeTextCache(Table table) {
+
+        TextCache c = (TextCache) textCacheList.remove(table.getName());
+
+        if (c != null) {
+            try {
+                c.close(true);
+            } catch (HsqlException e) {}
+        }
+    }
+
+    private void closeAllTextCaches(boolean script) {
+
+        Iterator it = textCacheList.values().iterator();
+
+        while (it.hasNext()) {
+            TextCache textCache = ((TextCache) it.next());
+
+            // use textCache.table to cover both cach and table readonly
+            if (script && !textCache.table.isDataReadOnly()) {
+                textCache.purge();
+            } else {
+                textCache.close(true);
+            }
+        }
+    }
+
+    private void reopenAllTextCaches() {
+
+        Iterator it = textCacheList.values().iterator();
+
+        while (it.hasNext()) {
+            ((TextCache) it.next()).reopen();
+        }
+    }
+
+    private boolean isAnyTextCacheModified() {
+
+        Iterator it = textCacheList.values().iterator();
+
+        while (it.hasNext()) {
+            if (((TextCache) it.next()).isFileModified()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/persist/Logger.java b/src/org/hsqldb/persist/Logger.java
new file mode 100644
index 0000000..be2cd69
--- /dev/null
+++ b/src/org/hsqldb/persist/Logger.java
@@ -0,0 +1,1359 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import org.hsqldb.Database;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.NumberSequence;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.SqlInvariants;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.Tokens;
+import org.hsqldb.TransactionManager;
+import org.hsqldb.TransactionManagerMV2PL;
+import org.hsqldb.TransactionManagerMVCC;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.index.IndexAVL;
+import org.hsqldb.index.IndexAVLMemory;
+import org.hsqldb.lib.FileAccess;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.FrameworkLogger;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.SimpleLog;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.lib.tar.DbBackup;
+import org.hsqldb.lib.tar.TarMalformatException;
+import org.hsqldb.types.Type;
+
+// boucherb@users 20030510 - patch 1.7.2 - added cooperative file locking
+
+/**
+ *  The public interface of persistence and logging classes.<p>
+ *
+ *  Implements a storage manager wrapper that provides a consistent,
+ *  always available interface to storage management for the Database
+ *  class, despite the fact not all Database objects actually use file
+ *  storage.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class Logger {
+
+    public SimpleLog appLog;
+    Log              log;
+    private Database database;
+    private LockFile lockFile;
+    public boolean   checkpointRequired;
+    public boolean   checkpointDue;
+    public boolean   checkpointDisabled;
+    private boolean  logsStatements;    // false indicates Log is being opened
+    private boolean  loggingEnabled;
+    private boolean  syncFile = false;
+
+    //
+    boolean        propFilesReadOnly;
+    boolean        propDatabaseReadOnly;
+    boolean        propIncrementBackup;
+    boolean        propNioDataFile;
+    int            propMaxFreeBlocks;
+    int            propCacheMaxRows;
+    int            propCacheMaxSize;
+    int            propCacheFileScale;
+    int            propCacheDefragLimit;
+    String         propTextSourceDefault = "";
+    HsqlProperties propTextSourceProps;
+    boolean        propTextAllowFullPath;
+    int            propWriteDelay;
+    int            propLogSize;
+    boolean        propLogData = true;
+    int            propEventLogLevel;
+    int            propGC;
+    int            propTxMode       = TransactionManager.LOCKS;
+    boolean        propRefIntegrity = true;
+    int            propLobBlockSize = 32 * 1024;
+
+    //
+    private Crypto    crypto;
+    public FileAccess fileAccess;
+    public boolean    isStoredFileAccess;
+    String            tempDirectoryPath;
+
+    //
+    public boolean isNewDatabase;
+
+    public Logger(Database database) {
+        this.database = database;
+    }
+
+    /**
+     *  Opens the specified Database object's database files and starts up
+     *  the logging process. <p>
+     *
+     *  If the specified Database object is a new database, its database
+     *  files are first created.
+     *
+     * @param  db the Database
+     * @throws  HsqlException if there is a problem, such as the case when
+     *      the specified files are in use by another process
+     */
+    public void openPersistence() {
+
+        // oj@openoffice.org - changed to file access api
+        String fileaccess_class_name =
+            (String) database.getURLProperties().getProperty(
+                HsqlDatabaseProperties.url_fileaccess_class_name);
+
+        if (fileaccess_class_name != null) {
+            String storagekey = database.getURLProperties().getProperty(
+                HsqlDatabaseProperties.url_storage_key);
+
+            try {
+                Class zclass = Class.forName(fileaccess_class_name);
+                Constructor constructor = zclass.getConstructor(new Class[]{
+                    Object.class });
+
+                fileAccess =
+                    (FileAccess) constructor.newInstance(new Object[]{
+                        storagekey });
+                isStoredFileAccess = true;
+            } catch (java.lang.ClassNotFoundException e) {
+                System.out.println("ClassNotFoundException");
+            } catch (java.lang.InstantiationException e) {
+                System.out.println("InstantiationException");
+            } catch (java.lang.IllegalAccessException e) {
+                System.out.println("IllegalAccessException");
+            } catch (Exception e) {
+                System.out.println("Exception");
+            }
+        } else {
+            fileAccess = FileUtil.getFileAccess(database.isFilesInJar());
+        }
+
+        boolean isFile =
+            DatabaseURL.isFileBasedDatabaseType(database.getType());
+
+        database.databaseProperties = new HsqlDatabaseProperties(database);
+        isNewDatabase = !isFile
+                        || !fileAccess.isStreamElement(database.getPath()
+                            + ".script");
+
+        if (isNewDatabase) {
+            String name = newUniqueName();
+
+            database.setUniqueName(name);
+
+            boolean checkExists = database.isFilesInJar()
+                                  || database.urlProperties.isPropertyTrue(
+                                      HsqlDatabaseProperties.url_ifexists);
+
+            if (checkExists) {
+                throw Error.error(ErrorCode.DATABASE_NOT_EXISTS,
+                                  database.getPath());
+            }
+
+            database.databaseProperties.setURLProperties(
+                database.urlProperties);
+        } else {
+            database.databaseProperties.load();
+
+            if (database.urlProperties.isPropertyTrue(
+                    HsqlDatabaseProperties.hsqldb_files_readonly)) {
+                database.databaseProperties.setProperty(
+                    HsqlDatabaseProperties.hsqldb_files_readonly, true);
+            }
+
+            if (database.urlProperties.isPropertyTrue(
+                    HsqlDatabaseProperties.hsqldb_readonly)) {
+                database.databaseProperties.setProperty(
+                    HsqlDatabaseProperties.hsqldb_readonly, true);
+            }
+        }
+
+        setVariables();
+
+        String logPath = null;
+
+        if (DatabaseURL.isFileBasedDatabaseType(database.getType())
+                && !database.isFilesReadOnly()) {
+            logPath = database.getPath() + ".app.log";
+        }
+
+        this.appLog = new SimpleLog(logPath, propEventLogLevel);
+
+        database.setReferentialIntegrity(propRefIntegrity);
+
+        if (!isFile) {
+            return;
+        }
+
+        checkpointRequired = false;
+        logsStatements     = false;
+
+        boolean useLock = database.getProperties().isPropertyTrue(
+            HsqlDatabaseProperties.hsqldb_lock_file);
+
+        if (useLock && !database.isFilesReadOnly()) {
+            acquireLock(database.getPath());
+        }
+
+        log = new Log(database);
+
+        log.open();
+
+        logsStatements = true;
+        loggingEnabled = propLogData && !database.isFilesReadOnly();
+
+        boolean version18 = database.databaseProperties.isVersion18();
+
+        if (version18) {
+            HsqlName name = database.schemaManager.findSchemaHsqlName(
+                SqlInvariants.PUBLIC_SCHEMA);
+
+            if (name != null) {
+                database.schemaManager.setDefaultSchemaHsqlName(name);
+            }
+
+            database.setUniqueName(newUniqueName());
+            checkpoint(false);
+        }
+
+        if (database.getUniqueName() == null) {
+            database.setUniqueName(newUniqueName());
+        }
+    }
+
+    private void setVariables() {
+
+        String cryptKey = database.urlProperties.getProperty(
+            HsqlDatabaseProperties.url_crypt_key);
+
+        if (cryptKey != null) {
+            String cryptType = database.urlProperties.getProperty(
+                HsqlDatabaseProperties.url_crypt_type);
+            String cryptProvider = database.urlProperties.getProperty(
+                HsqlDatabaseProperties.url_crypt_provider);
+
+            crypto = new Crypto(cryptKey, cryptType, cryptProvider);
+        }
+
+        if (database.databaseProperties.isPropertyTrue(
+                HsqlDatabaseProperties.hsqldb_readonly)) {
+            database.setReadOnly();
+        }
+
+        if (database.databaseProperties.isPropertyTrue(
+                HsqlDatabaseProperties.hsqldb_files_readonly)) {
+            database.setFilesReadOnly();
+        }
+
+        // handle invalid paths as well as access issues
+        if (!database.isFilesReadOnly()) {
+            if (database.getType() == DatabaseURL.S_MEM
+                    || isStoredFileAccess) {
+                tempDirectoryPath = database.getProperties().getStringProperty(
+                    HsqlDatabaseProperties.hsqldb_temp_directory);
+            } else {
+                tempDirectoryPath = database.getPath() + ".tmp";
+            }
+
+            if (tempDirectoryPath != null) {
+                tempDirectoryPath =
+                    FileUtil.makeDirectories(tempDirectoryPath);
+            }
+        }
+
+        boolean version18 = database.databaseProperties.isVersion18();
+
+        if (!isNewDatabase && !version18) {
+            return;
+        }
+
+        if (tempDirectoryPath != null) {
+            int rows = database.databaseProperties.getIntegerProperty(
+                HsqlDatabaseProperties.hsqldb_result_max_memory_rows);
+
+            database.setResultMaxMemoryRows(rows);
+        }
+
+        String tableType = database.databaseProperties.getStringProperty(
+            HsqlDatabaseProperties.hsqldb_default_table_type);
+
+        if ("CACHED".equalsIgnoreCase(tableType)) {
+            database.schemaManager.setDefaultTableType(TableBase.CACHED_TABLE);
+        }
+
+        String txMode = database.databaseProperties.getStringProperty(
+            HsqlDatabaseProperties.hsqldb_tx);
+
+        if (Tokens.T_MVCC.equalsIgnoreCase(txMode)) {
+            propTxMode = TransactionManager.MVCC;
+        } else if (Tokens.T_MVLOCKS.equalsIgnoreCase(txMode)) {
+            propTxMode = TransactionManager.MVLOCKS;
+        } else if (Tokens.T_LOCKS.equalsIgnoreCase(txMode)) {
+            propTxMode = TransactionManager.LOCKS;
+        }
+
+        switch (propTxMode) {
+
+            case TransactionManager.LOCKS :
+                break;
+
+            case TransactionManager.MVLOCKS :
+                database.txManager = new TransactionManagerMV2PL(database);
+                break;
+
+            case TransactionManager.MVCC :
+                database.txManager = new TransactionManagerMVCC(database);
+                break;
+        }
+
+        String txLevel = database.databaseProperties.getStringProperty(
+            HsqlDatabaseProperties.hsqldb_tx_level);
+
+        if (Tokens.T_SERIALIZABLE.equalsIgnoreCase(txLevel)) {
+            database.defaultIsolationLevel = SessionInterface.TX_SERIALIZABLE;
+        } else {
+            database.defaultIsolationLevel =
+                SessionInterface.TX_READ_COMMITTED;
+        }
+
+        database.sqlEnforceRefs = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.sql_enforce_refs);
+        database.sqlEnforceSize = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.sql_enforce_strict_size);
+        database.sqlEnforceSize = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.sql_enforce_size);
+        database.sqlEnforceNames = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.sql_enforce_names);
+
+        if (database.databaseProperties.isPropertyTrue(
+                HsqlDatabaseProperties.sql_compare_in_locale)) {
+            database.collation.setCollationAsLocale();
+        }
+
+        propEventLogLevel = database.databaseProperties.getIntegerProperty(
+            HsqlDatabaseProperties.hsqldb_applog);
+        propFilesReadOnly = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.hsqldb_files_readonly);
+        propDatabaseReadOnly = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.hsqldb_readonly);
+        propIncrementBackup = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.hsqldb_inc_backup);
+        propNioDataFile = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.hsqldb_nio_data_file);
+        propCacheMaxRows = database.databaseProperties.getIntegerProperty(
+            HsqlDatabaseProperties.hsqldb_cache_rows);
+        propCacheMaxSize =
+            database.databaseProperties.getIntegerProperty(
+                HsqlDatabaseProperties.hsqldb_cache_size) * 1024;
+
+        setLobFileScaleNoCheck(
+            database.databaseProperties.getIntegerProperty(
+                HsqlDatabaseProperties.hsqldb_lob_file_scale));
+        setCacheFileScaleNoCheck(
+            database.databaseProperties.getIntegerProperty(
+                HsqlDatabaseProperties.hsqldb_cache_file_scale));
+
+        propCacheDefragLimit = database.databaseProperties.getIntegerProperty(
+            HsqlDatabaseProperties.hsqldb_defrag_limit);
+        propMaxFreeBlocks = database.databaseProperties.getIntegerProperty(
+            HsqlDatabaseProperties.hsqldb_cache_free_count_scale);
+        propMaxFreeBlocks = 1 << propMaxFreeBlocks;
+        propTextAllowFullPath = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.textdb_allow_full_path);
+        propWriteDelay = database.databaseProperties.getIntegerProperty(
+            HsqlDatabaseProperties.hsqldb_write_delay_millis);
+
+        if (!database.databaseProperties.isPropertyTrue(
+                HsqlDatabaseProperties.hsqldb_write_delay)) {
+            propWriteDelay = 0;
+        }
+
+        propLogSize = database.databaseProperties.getIntegerProperty(
+            HsqlDatabaseProperties.hsqldb_log_size);
+        propLogData = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.hsqldb_log_data);
+        propGC = database.databaseProperties.getIntegerProperty(
+            HsqlDatabaseProperties.runtime_gc_interval);
+        propRefIntegrity = database.databaseProperties.isPropertyTrue(
+            HsqlDatabaseProperties.sql_ref_integrity);
+    }
+
+// fredt@users 20020130 - patch 495484 by boucherb@users
+
+    /**
+     *  Shuts down the logging process using the specified mode. <p>
+     *
+     * @param  closemode The mode in which to shut down the logging
+     *      process
+     *      <OL>
+     *        <LI> closemode -1 performs SHUTDOWN IMMEDIATELY, equivalent
+     *        to  a poweroff or crash.
+     *        <LI> closemode 0 performs a normal SHUTDOWN that
+     *        checkpoints the database normally.
+     *        <LI> closemode 1 performs a shutdown compact that scripts
+     *        out the contents of any CACHED tables to the log then
+     *        deletes the existing *.data file that contains the data
+     *        for all CACHED table before the normal checkpoint process
+     *        which in turn creates a new, compact *.data file.
+     *        <LI> closemode 2 performs a SHUTDOWN SCRIPT.
+     *      </OL>
+     *
+     * @return  true if closed with no problems or false if a problem was
+     *        encountered.
+     */
+    public boolean closePersistence(int closemode) {
+
+        if (log == null) {
+            return true;
+        }
+
+        database.lobManager.deleteUnusedLobs();
+
+        try {
+            switch (closemode) {
+
+                case Database.CLOSEMODE_IMMEDIATELY :
+                    log.shutdown();
+                    break;
+
+                case Database.CLOSEMODE_NORMAL :
+                    log.close(false);
+                    break;
+
+                case Database.CLOSEMODE_COMPACT :
+                case Database.CLOSEMODE_SCRIPT :
+                    log.close(true);
+                    break;
+            }
+        } catch (Throwable e) {
+            logSevereEvent("error closing log", e);
+
+            log = null;
+
+            return false;
+        }
+
+        logInfoEvent("Database closed");
+
+        log = null;
+
+        appLog.close();
+
+        logsStatements = false;
+        loggingEnabled = false;
+
+        return true;
+    }
+
+    String newUniqueName() {
+
+        String name = StringUtil.toPaddedString(
+            Long.toHexString(System.currentTimeMillis()), 16, '0', false);
+
+        name = "HSQLDB" + name.substring(6).toUpperCase(Locale.ENGLISH);
+
+        return name;
+    }
+
+    /**
+     *  Determines if the logging process actually does anything. <p>
+     *
+     *  In-memory Database objects do not need to log anything. This
+     *  method is essentially equivalent to testing whether this logger's
+     *  database is an in-memory mode database.
+     *
+     * @return  true if this object encapsulates a non-null Log instance,
+     *      else false
+     */
+    public boolean hasPersistence() {
+        return log != null;
+    }
+
+    /*
+     * Must return correct mode prior to initialisation
+     * @return  true if this object encapsulates a non-null Log instance,
+     *      else false
+     */
+    public boolean isLogged() {
+        return DatabaseURL.isFileBasedDatabaseType(database.getType())
+               && !database.isFilesReadOnly();
+    }
+
+    FrameworkLogger fwLogger;
+
+    /**
+     * All usage of FrameworkLogger should call this method before using an
+     * instance.
+     *
+     * It ensures and requires that no logging should take place before a new
+     * database unique name has been created for a new database or read from the
+     * .script file for an old database.<p>
+     *
+     * An instance is returned when:
+     * - database unique name has been created
+     * - FrameworkLogger would use log4j
+     *
+     * Otherwise null is returned.
+     *
+     * This tactic avoids usage of file-based jdk logging for the time being.
+     *
+     */
+    private FrameworkLogger getEventLogger() {
+
+        if (fwLogger != null) {
+            return fwLogger;
+        }
+
+        String name = database.getUniqueName();
+
+        if (name == null) {
+
+            // The database unique name is set up at different times
+            // depending on upgraded / exiting / new databases.
+            // Therefore FrameworkLogger is not used until the unique
+            // name is known.
+            return null;
+        }
+
+        fwLogger = FrameworkLogger.getLog(Logger.class,
+                                          database.getUniqueName());
+
+        return fwLogger;
+    }
+
+    public void setEventLogLevel(int level) {
+
+        propEventLogLevel = level;
+
+        appLog.setLevel(level);
+    }
+
+    public void logSevereEvent(String message, Throwable t) {
+
+        getEventLogger();
+
+        if (fwLogger != null) {
+            fwLogger.severe(message, t);
+        }
+
+        if (appLog != null) {
+            appLog.logContext(t, message);
+        }
+    }
+
+    public void logWarningEvent(String message, Throwable t) {
+
+        getEventLogger();
+
+        if (fwLogger != null) {
+            fwLogger.warning(message, t);
+        }
+
+        appLog.logContext(t, message);
+    }
+
+    public void logInfoEvent(String message) {
+
+        getEventLogger();
+
+        if (fwLogger != null) {
+            fwLogger.info(message);
+        }
+
+        appLog.logContext(SimpleLog.LOG_NORMAL, message);
+    }
+
+    /**
+     *  Returns the Cache object or null if one doesn't exist.
+     */
+    public DataFileCache getCache() {
+
+        if (log == null) {
+            return null;
+        } else {
+            return log.getCache();
+        }
+    }
+
+    /**
+     *  Returns true if Cache object exists.
+     */
+    public boolean hasCache() {
+
+        if (log == null) {
+            return false;
+        } else {
+            return log.hasCache();
+        }
+    }
+
+    /**
+     *  Records a Log entry representing a new connection action on the
+     *  specified Session object.
+     *
+     * @param  session the Session object for which to record the log
+     *      entry
+     * @throws  HsqlException if there is a problem recording the Log
+     *      entry
+     */
+    public synchronized void logStartSession(Session session) {
+
+        if (loggingEnabled) {
+            writeToLog(session, session.getUser().getConnectUserSQL());
+        }
+    }
+
+    /**
+     *  Records a Log entry for the specified SQL statement, on behalf of
+     *  the specified Session object.
+     *
+     * @param  session the Session object for which to record the Log
+     *      entry
+     * @param  statement the SQL statement to Log
+     * @throws  HsqlException if there is a problem recording the entry
+     */
+    public synchronized void writeToLog(Session session, String statement) {
+
+        if (loggingEnabled) {
+            log.writeStatement(session, statement);
+        }
+    }
+
+    public synchronized void writeInsertStatement(Session session,
+            Table table, Object[] row) {
+
+        if (loggingEnabled) {
+            log.writeInsertStatement(session, table, row);
+        }
+    }
+
+    public synchronized void writeDeleteStatement(Session session, Table t,
+            Object[] row) {
+
+        if (loggingEnabled) {
+            log.writeDeleteStatement(session, t, row);
+        }
+    }
+
+    public synchronized void writeSequenceStatement(Session session,
+            NumberSequence s) {
+
+        if (loggingEnabled) {
+            log.writeSequenceStatement(session, s);
+        }
+    }
+
+    public synchronized void writeCommitStatement(Session session) {
+
+        if (loggingEnabled) {
+            log.writeCommitStatement(session);
+            synchLog();
+        }
+    }
+
+    /**
+     * Called after commits or after each statement when autocommit is on
+     */
+    public synchronized void synchLog() {
+
+        if (loggingEnabled && syncFile) {
+            log.synchLog();
+        }
+    }
+
+    public synchronized void synchLogForce() {
+
+        if (loggingEnabled) {
+            log.synchLog();
+        }
+    }
+
+    /**
+     *  Checkpoints the database. <p>
+     *
+     *  The most important effect of calling this method is to cause the
+     *  log file to be rewritten in the most efficient form to
+     *  reflect the current state of the database, i.e. only the DDL and
+     *  insert DML required to recreate the database in its present state.
+     *  Other house-keeping duties are performed w.r.t. other database
+     *  files, in order to ensure as much as possible the ACID properites
+     *  of the database.
+     *
+     * @throws  HsqlException if there is a problem checkpointing the
+     *      database
+     */
+    public synchronized void checkpoint(boolean mode) {
+
+        database.lobManager.deleteUnusedLobs();
+
+        if (logsStatements) {
+            logInfoEvent("Checkpoint start");
+            log.checkpoint(mode);
+            database.sessionManager.resetLoggedSchemas();
+            logInfoEvent("Checkpoint end");
+        }
+
+        checkpointDue = false;
+    }
+
+    /**
+     *  Sets the maximum size to which the log file can grow
+     *  before being automatically checkpointed.
+     *
+     * @param  megas size in MB
+     */
+    public synchronized void setLogSize(int megas) {
+
+        propLogSize = megas;
+
+        if (log != null) {
+            log.setLogSize(propLogSize);
+        }
+    }
+
+    /**
+     *  Sets logging on or off.
+     *
+     * @param  megas size in MB
+     */
+    public synchronized void setLogData(boolean mode) {
+
+        propLogData    = mode;
+        loggingEnabled = propLogData && !database.isFilesReadOnly();
+        loggingEnabled &= logsStatements;
+    }
+
+    /**
+     *  Sets the type of script file, currently 0 for text (default)
+     *  1 for binary and 3 for compressed
+     *
+     * @param  i The type
+     */
+    public synchronized void setScriptType(int i) {
+
+        if (log != null) {
+
+            //
+        }
+    }
+
+    /**
+     *  Sets the log write delay mode to number of seconds. By default
+     *  executed commands written to the log are committed fully at most
+     *  60 second after they are executed. This improves performance for
+     *  applications that execute a large number
+     *  of short running statements in a short period of time, but risks
+     *  failing to log some possibly large number of statements in the
+     *  event of a crash. A small value improves recovery.
+     *  A value of 0 will severly slow down logging when autocommit is on,
+     *  or many short transactions are committed.
+     *
+     * @param  delay in seconds
+     */
+    public synchronized void setWriteDelay(int delay) {
+
+        propWriteDelay = delay;
+
+        if (log != null) {
+            syncFile = (delay == 0);
+
+            log.setWriteDelay(delay);
+        }
+    }
+
+    public Crypto getCrypto() {
+        return crypto;
+    }
+
+    public int getWriteDelay() {
+        return propWriteDelay;
+    }
+
+    public int getLogSize() {
+        return propLogSize;
+    }
+
+    public int getLobBlockSize() {
+        return propLobBlockSize;
+    }
+
+    public int getScriptType() {
+        return log != null ? log.getScriptType()
+                           : 0;
+    }
+
+    public synchronized void setIncrementBackup(boolean val) {
+
+        if (val == propIncrementBackup) {
+            return;
+        }
+
+        if (log != null) {
+            log.setIncrementBackup(val);
+
+            if (log.hasCache()) {
+                database.logger.checkpointRequired = true;
+            }
+        }
+
+        propIncrementBackup = val;
+    }
+
+    public void setCacheMaxRows(int value) {
+        propCacheMaxRows = value;
+    }
+
+    public int getCacheRowsDefault() {
+        return propCacheMaxRows;
+    }
+
+    public void setCacheSize(int value) {
+        propCacheMaxSize = value * 1024;
+    }
+
+    public int getCacheSize() {
+        return propCacheMaxSize;
+    }
+
+    public void setCacheFileScale(int value) {
+
+        if (propCacheFileScale == value) {
+            return;
+        }
+
+        checkPower(value, 8);
+
+        if (1 < value && value < 8) {
+            throw Error.error(ErrorCode.X_42556);
+        }
+
+        if (getCache() != null) {
+            throw Error.error(ErrorCode.DATA_FILE_IN_USE);
+        }
+
+        propCacheFileScale = value;
+    }
+
+    public void setCacheFileScaleNoCheck(int value) {
+
+        checkPower(value, 8);
+
+        if (1 < value && value < 8) {
+            throw Error.error(ErrorCode.X_42556);
+        }
+
+        propCacheFileScale = value;
+    }
+
+    public int getCacheFileScale() {
+        return propCacheFileScale;
+    }
+
+    public void setLobFileScale(int value) {
+
+        if (propLobBlockSize == value * 1024) {
+            return;
+        }
+
+        checkPower(value, 6);
+
+        if (database.lobManager.getLobCount() > 0) {
+            throw Error.error(ErrorCode.DATA_FILE_IN_USE);
+        }
+
+        propLobBlockSize = value * 1024;
+
+        database.lobManager.close();
+        database.lobManager.open();
+    }
+
+    public void setLobFileScaleNoCheck(int value) {
+
+        checkPower(value, 6);
+
+        propLobBlockSize = value * 1024;
+    }
+
+    public int getLobFileScale() {
+        return propLobBlockSize / 1024;
+    }
+
+    public void setDefagLimit(int value) {
+        propCacheDefragLimit = value;
+    }
+
+    public int getDefragLimit() {
+        return propCacheDefragLimit;
+    }
+
+    public void setDefaultTextTableProperties(String source,
+            HsqlProperties props) {
+        this.propTextSourceDefault = source;
+        this.propTextSourceProps   = props;
+    }
+
+    static void checkPower(int n, int limit) {
+
+        for (int i = 0; i < limit; i++) {
+            if ((n & 1) != 0) {
+                if ((n | 1) != 1) {
+                    throw Error.error(ErrorCode.X_42556);
+                }
+
+                return;
+            }
+
+            n >>= 1;
+        }
+
+        throw Error.error(ErrorCode.X_42556);
+    }
+
+    /**
+     *  Opens the TextCache object.
+     */
+    public DataFileCache openTextFilePersistence(Table table, String source,
+            boolean readOnlyData, boolean reversed) {
+        return log.openTextCache(table, source, readOnlyData, reversed);
+    }
+
+    /**
+     *  Closes the TextCache object.
+     */
+    public void closeTextCache(Table table) {
+        log.closeTextCache(table);
+    }
+
+    public synchronized boolean needsCheckpointReset() {
+
+        if (checkpointRequired && !checkpointDue && !checkpointDisabled) {
+            checkpointDue      = true;
+            checkpointRequired = false;
+
+            return true;
+        }
+
+        checkpointRequired = false;
+
+        return false;
+    }
+
+    public boolean hasLockFile() {
+        return lockFile != null;
+    }
+
+    public void acquireLock(String path) {
+
+        if (lockFile != null) {
+            return;
+        }
+
+        lockFile = LockFile.newLockFileLock(path);
+    }
+
+    public void releaseLock() {
+
+        try {
+            if (lockFile != null) {
+                lockFile.tryRelease();
+            }
+        } catch (Exception e) {}
+
+        lockFile = null;
+    }
+
+    // properties
+    public void setNioDataFile(boolean value) {
+        propNioDataFile = value;
+    }
+
+    public FileAccess getFileAccess() {
+        return fileAccess;
+    }
+
+    public boolean isStoredFileAccess() {
+        return isStoredFileAccess;
+    }
+
+    public String getTempDirectoryPath() {
+        return tempDirectoryPath;
+    }
+
+    public PersistentStore newStore(Session session,
+                                    PersistentStoreCollection collection,
+                                    TableBase table, boolean diskBased) {
+
+        switch (table.getTableType()) {
+
+            case TableBase.CACHED_TABLE :
+                DataFileCache cache = getCache();
+
+                if (cache == null) {
+                    break;
+                }
+
+                return new RowStoreAVLDisk(collection, cache, (Table) table);
+
+            case TableBase.MEMORY_TABLE :
+            case TableBase.SYSTEM_TABLE :
+                return new RowStoreAVLMemory(collection, (Table) table);
+
+            case TableBase.TEXT_TABLE :
+                return new RowStoreAVLDiskData(collection, (Table) table);
+
+            case TableBase.RESULT_TABLE :
+                if (session == null) {
+                    return null;
+                }
+
+                return new RowStoreAVLHybrid(session, collection, table);
+
+            case TableBase.TEMP_TABLE :
+                diskBased = false;
+
+            // fall through
+            case TableBase.SYSTEM_SUBQUERY :
+            case TableBase.VIEW_TABLE :
+            case TableBase.TRANSITION_TABLE :
+                if (session == null) {
+                    return null;
+                }
+
+                return new RowStoreAVLHybrid(session, collection, table,
+                                             diskBased);
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "Logger");
+    }
+
+    public Index newIndex(HsqlName name, long id, TableBase table,
+                          int[] columns, boolean[] descending,
+                          boolean[] nullsLast, Type[] colTypes, boolean pk,
+                          boolean unique, boolean constraint,
+                          boolean forward) {
+
+        switch (table.getTableType()) {
+
+            case TableBase.SYSTEM_TABLE :
+            case TableBase.MEMORY_TABLE :
+                return new IndexAVLMemory(name, id, table, columns,
+                                          descending, nullsLast, colTypes, pk,
+                                          unique, constraint, forward);
+
+            case TableBase.FUNCTION_TABLE :
+            case TableBase.CACHED_TABLE :
+            case TableBase.TEXT_TABLE :
+            case TableBase.TEMP_TABLE :
+            case TableBase.RESULT_TABLE :
+            case TableBase.SYSTEM_SUBQUERY :
+            case TableBase.VIEW_TABLE :
+            case TableBase.TRANSITION_TABLE :
+                return new IndexAVL(name, id, table, columns, descending,
+                                    nullsLast, colTypes, pk, unique,
+                                    constraint, forward);
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "Logger");
+    }
+
+    public String[] getPropertiesSQL() {
+
+        HsqlArrayList list = new HsqlArrayList();
+        StringBuffer  sb   = new StringBuffer();
+
+        sb.append("SET DATABASE ").append(Tokens.T_UNIQUE).append(' ');
+        sb.append(Tokens.T_NAME).append(' ').append(database.getUniqueName());
+        list.add(sb.toString());
+        sb.setLength(0);
+        sb.append("SET DATABASE ").append(Tokens.T_GC).append(' ');
+        sb.append(propGC);
+        list.add(sb.toString());
+        sb.setLength(0);
+        sb.append("SET DATABASE ").append(Tokens.T_DEFAULT).append(' ');
+        sb.append(Tokens.T_RESULT).append(' ').append(Tokens.T_MEMORY);
+        sb.append(' ').append(Tokens.T_ROWS).append(' ');
+        sb.append(database.getResultMaxMemoryRows());
+        list.add(sb.toString());
+        sb.setLength(0);
+        sb.append("SET DATABASE ").append(Tokens.T_EVENT).append(' ');
+        sb.append(Tokens.T_LOG).append(' ').append(Tokens.T_LEVEL);
+        sb.append(' ').append(propEventLogLevel);
+        list.add(sb.toString());
+        sb.setLength(0);
+        sb.append("SET DATABASE ").append(Tokens.T_SQL).append(' ');
+        sb.append(Tokens.T_REFERENCES).append(' ');
+        sb.append(database.sqlEnforceRefs ? Tokens.T_TRUE
+                                          : Tokens.T_FALSE);
+        list.add(sb.toString());
+        sb.setLength(0);
+        sb.append("SET DATABASE ").append(Tokens.T_SQL).append(' ');
+        sb.append(Tokens.T_SIZE).append(' ');
+        sb.append(database.sqlEnforceSize ? Tokens.T_TRUE
+                                          : Tokens.T_FALSE);
+        list.add(sb.toString());
+        sb.setLength(0);
+        sb.append("SET DATABASE ").append(Tokens.T_SQL).append(' ');
+        sb.append(Tokens.T_NAMES).append(' ');
+        sb.append(database.sqlEnforceNames ? Tokens.T_TRUE
+                                           : Tokens.T_FALSE);
+        list.add(sb.toString());
+        sb.setLength(0);
+        sb.append("SET DATABASE ").append(Tokens.T_TRANSACTION);
+        sb.append(' ').append(Tokens.T_CONTROL).append(' ');
+
+        switch (database.txManager.getTransactionControl()) {
+
+            case TransactionManager.MVCC :
+                sb.append(Tokens.T_MVCC);
+                break;
+
+            case TransactionManager.MVLOCKS :
+                sb.append(Tokens.T_MVLOCKS);
+                break;
+
+            case TransactionManager.LOCKS :
+                sb.append(Tokens.T_LOCKS);
+                break;
+        }
+
+        list.add(sb.toString());
+        sb.setLength(0);
+        sb.append("SET DATABASE ").append(Tokens.T_DEFAULT).append(' ');
+        sb.append(Tokens.T_ISOLATION).append(' ').append(Tokens.T_LEVEL);
+        sb.append(' ');
+
+        switch (database.getDefaultIsolationLevel()) {
+
+            case SessionInterface.TX_READ_COMMITTED :
+                sb.append(Tokens.T_READ).append(' ').append(
+                    Tokens.T_COMMITTED);
+                break;
+
+            case SessionInterface.TX_SERIALIZABLE :
+                sb.append(Tokens.T_SERIALIZABLE);
+                break;
+        }
+
+        list.add(sb.toString());
+        sb.setLength(0);
+
+        if (hasPersistence()) {
+            if (database.schemaManager.getDefaultTableType()
+                    == TableBase.CACHED_TABLE) {
+                list.add("SET DATABASE DEFAULT TABLE TYPE CACHED");
+            }
+
+            int     delay  = propWriteDelay;
+            boolean millis = delay > 0 && delay < 1000;
+
+            if (millis) {
+                if (delay < 20) {
+                    delay = 20;
+                }
+            } else {
+                delay /= 1000;
+            }
+
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_WRITE).append(' ');
+            sb.append(Tokens.T_DELAY).append(' ').append(delay);
+
+            if (millis) {
+                sb.append(' ').append(Tokens.T_MILLIS);
+            }
+
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_BACKUP);
+            sb.append(' ').append(Tokens.T_INCREMENT).append(' ');
+            sb.append(propIncrementBackup ? Tokens.T_TRUE
+                                          : Tokens.T_FALSE);
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_CACHE);
+            sb.append(' ').append(Tokens.T_SIZE).append(' ');
+            sb.append(propCacheMaxSize / 1024);
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_CACHE);
+            sb.append(' ').append(Tokens.T_ROWS).append(' ');
+            sb.append(propCacheMaxRows);
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_SCALE);
+            sb.append(' ').append(propCacheFileScale);
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_LOB).append(' ').append(
+                Tokens.T_SCALE);
+            sb.append(' ').append(getLobFileScale());
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_DEFRAG);
+            sb.append(' ').append(propCacheDefragLimit);
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_NIO);
+            sb.append(' ').append(propNioDataFile ? Tokens.T_TRUE
+                                                  : Tokens.T_FALSE);
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_LOG).append(' ');
+            sb.append(propLogData ? Tokens.T_TRUE
+                                  : Tokens.T_FALSE);
+            list.add(sb.toString());
+            sb.setLength(0);
+            sb.append("SET FILES ").append(Tokens.T_LOG).append(' ');
+            sb.append(Tokens.T_SIZE).append(' ').append(propLogSize);
+            list.add(sb.toString());
+            sb.setLength(0);
+            /*
+            if (propTempDirectoryPath != null) {
+                sb.append("SET FILES ").append(Tokens.T_TEMP).append(' ');
+                sb.append(Tokens.T_PATH).append(' ');
+                sb.append(propTempDirectoryPath);
+                list.add(sb.toString());
+                sb.setLength(0);
+            }
+            */
+            sb.append("SET DATABASE ").append(Tokens.T_TEXT).append(' ');
+            sb.append(Tokens.T_TABLE).append(' ').append(Tokens.T_DEFAULTS);
+            sb.append(' ').append('\'');
+            sb.append(propTextSourceDefault).append('\'');
+            list.add(sb.toString());
+            sb.setLength(0);
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    //
+    static private SimpleDateFormat backupFileFormat =
+        new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+    static private Character runtimeFileDelim = null;
+
+    public synchronized void backup(String destPath, String dbPath,
+                                    boolean script, boolean blocking,
+                                    boolean compressed) {
+
+        /* If want to add db Id also, will need to pass either Database
+         * instead of dbPath, or pass dbPath + Id from CommandStatement.
+         */
+        if (runtimeFileDelim == null) {
+            runtimeFileDelim =
+                new Character(System.getProperty("file.separator").charAt(0));
+        }
+
+        String instanceName = new File(dbPath).getName();
+
+        if (destPath == null || destPath.length() < 1) {
+            throw Error.error(ErrorCode.X_2200F, "0-length destination path");
+        }
+
+        char lastChar = destPath.charAt(destPath.length() - 1);
+        boolean generateName = (lastChar == '/'
+                                || lastChar == runtimeFileDelim.charValue());
+        String defaultCompressionSuffix = compressed ? ".tar.gz"
+                                                     : ".tar";
+        File archiveFile =
+            generateName
+            ? (new File(destPath.substring(0, destPath.length() - 1),
+                        instanceName + '-'
+                        + backupFileFormat.format(new java.util.Date())
+                        + defaultCompressionSuffix))
+            : (new File(destPath));
+        boolean nameImpliesCompress =
+            archiveFile.getName().endsWith(".tar.gz")
+            || archiveFile.getName().endsWith(".tgz");
+
+        if ((!nameImpliesCompress)
+                && !archiveFile.getName().endsWith(".tar")) {
+            throw Error.error(null, ErrorCode.UNSUPPORTED_FILENAME_SUFFIX, 0,
+                              new String[] {
+                archiveFile.getName(), ".tar, .tar.gz, .tgz"
+            });
+        }
+
+        if (compressed != nameImpliesCompress) {
+            throw Error.error(null, ErrorCode.COMPRESSION_SUFFIX_MISMATCH, 0,
+                              new Object[] {
+                new Boolean(compressed), archiveFile.getName()
+            });
+        }
+
+        log.checkpointClose();
+
+        try {
+            logInfoEvent("Initiating backup of instance '" + instanceName
+                         + "'");
+
+            // By default, DbBackup will throw if archiveFile (or
+            // corresponding work file) already exist.  That's just what we
+            // want here.
+            DbBackup backup = new DbBackup(archiveFile, dbPath);
+
+            backup.setAbortUponModify(false);
+            backup.write();
+            logInfoEvent("Successfully backed up instance '" + instanceName
+                         + "' to '" + destPath + "'");
+
+            // RENAME tempPath to destPath
+        } catch (IllegalArgumentException iae) {
+            throw Error.error(ErrorCode.X_HV00A, iae.getMessage());
+        } catch (IOException ioe) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, ioe.getMessage());
+        } catch (TarMalformatException tme) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, tme.getMessage());
+        } finally {
+            log.checkpointReopen();
+        }
+    }
+}
diff --git a/src/org/hsqldb/persist/PersistentStore.java b/src/org/hsqldb/persist/PersistentStore.java
new file mode 100644
index 0000000..3f49a2e
--- /dev/null
+++ b/src/org/hsqldb/persist/PersistentStore.java
@@ -0,0 +1,146 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.Row;
+import org.hsqldb.Session;
+import org.hsqldb.TableBase;
+import org.hsqldb.index.Index;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.rowio.RowInputInterface;
+
+/**
+ * Interface for a store for CachedObject objects.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.9.0
+ */
+public interface PersistentStore {
+
+    int               INT_STORE_SIZE  = 4;
+    int               LONG_STORE_SIZE = 8;
+    PersistentStore[] emptyArray      = new PersistentStore[]{};
+
+    TableBase getTable();
+
+    long getTimestamp();
+
+    void setTimestamp(long timestamp);
+
+    boolean isMemory();
+
+    int getAccessCount();
+
+    void set(CachedObject object);
+
+    /** get object */
+    CachedObject get(int key);
+
+    /** get object, ensuring future gets will return the same instance of the object */
+    CachedObject getKeep(int key);
+
+    /** get object with keep, ensuring future gets will return the same instance of the object */
+    CachedObject get(int key, boolean keep);
+
+    CachedObject get(CachedObject object, boolean keep);
+
+    int getStorageSize(int key);
+
+    /** add new object */
+    void add(CachedObject object);
+
+    CachedObject get(RowInputInterface in);
+
+    CachedObject getNewInstance(int size);
+
+    CachedObject getNewCachedObject(Session session, Object object);
+
+    /** remove the persisted image but not the cached copy */
+    void removePersistence(int i);
+
+    void removeAll();
+
+    /** remove both persisted and cached copies */
+    void remove(int i);
+
+    /** remove the cached copies */
+    void release(int i);
+
+    /** commit persisted image */
+    void commitPersistence(CachedObject object);
+
+    //
+    void delete(Session session, Row row);
+
+    void indexRow(Session session, Row row);
+
+    void commitRow(Session session, Row row, int changeAction, int txModel);
+
+    void rollbackRow(Session session, Row row, int changeAction, int txModel);
+    //
+    void indexRows();
+
+    RowIterator rowIterator();
+
+    //
+    DataFileCache getCache();
+
+    void setCache(DataFileCache cache);
+
+    void release();
+
+    PersistentStore getAccessorStore(Index index);
+
+    CachedObject getAccessor(Index key);
+
+    void setAccessor(Index key, CachedObject accessor);
+
+    void setAccessor(Index key, int accessor);
+
+    int elementCount(Session session);
+
+    int elementCountUnique(Index index);
+
+    void setElementCount(Index key, int size, int uniqueSize);
+
+    void updateElementCount(Index key, int size, int uniqueSize);
+
+    void resetAccessorKeys(Index[] keys);
+
+    void moveData(Session session, PersistentStore other, int colindex,
+                  int adjust);
+
+    void lock();
+
+    void unlock();
+}
diff --git a/src/org/hsqldb/persist/PersistentStoreCollection.java b/src/org/hsqldb/persist/PersistentStoreCollection.java
new file mode 100644
index 0000000..64e6021
--- /dev/null
+++ b/src/org/hsqldb/persist/PersistentStoreCollection.java
@@ -0,0 +1,39 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+public interface PersistentStoreCollection {
+
+    PersistentStore getStore(Object key);
+
+    void setStore(Object key, PersistentStore store);
+}
diff --git a/src/org/hsqldb/persist/PersistentStoreCollectionDatabase.java b/src/org/hsqldb/persist/PersistentStoreCollectionDatabase.java
new file mode 100644
index 0000000..3dca5af
--- /dev/null
+++ b/src/org/hsqldb/persist/PersistentStoreCollectionDatabase.java
@@ -0,0 +1,77 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.TableBase;
+import org.hsqldb.lib.LongKeyHashMap;
+
+public class PersistentStoreCollectionDatabase
+implements PersistentStoreCollection {
+
+    private long                 persistentStoreIdSequence;
+    private final LongKeyHashMap rowStoreMap = new LongKeyHashMap();
+
+    public void setStore(Object key, PersistentStore store) {
+
+        long persistenceId = ((TableBase) key).getPersistenceId();
+
+        if (store == null) {
+            rowStoreMap.remove(persistenceId);
+        } else {
+            rowStoreMap.put(persistenceId, store);
+        }
+    }
+
+    public PersistentStore getStore(Object key) {
+
+        long persistenceId = ((TableBase) key).getPersistenceId();
+        PersistentStore store =
+            (PersistentStore) rowStoreMap.get(persistenceId);
+
+        return store;
+    }
+
+    public void releaseStore(TableBase table) {
+
+        PersistentStore store =
+            (PersistentStore) rowStoreMap.get(table.getPersistenceId());
+
+        if (store != null) {
+            store.release();
+            rowStoreMap.remove(table.getPersistenceId());
+        }
+    }
+
+    public long getNextId() {
+        return persistentStoreIdSequence++;
+    }
+}
diff --git a/src/org/hsqldb/persist/PersistentStoreCollectionSession.java b/src/org/hsqldb/persist/PersistentStoreCollectionSession.java
new file mode 100644
index 0000000..20cd11f
--- /dev/null
+++ b/src/org/hsqldb/persist/PersistentStoreCollectionSession.java
@@ -0,0 +1,279 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.LongKeyHashMap;
+
+/**
+ * Collection of PersistenceStore itmes currently used by a session.
+ * An item is retrieved based on key returned by
+ * TableBase.getPersistenceId().
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class PersistentStoreCollectionSession
+implements PersistentStoreCollection {
+
+    private final Session        session;
+    private final LongKeyHashMap rowStoreMapSession     = new LongKeyHashMap();
+    private LongKeyHashMap       rowStoreMapTransaction = new LongKeyHashMap();
+    private LongKeyHashMap       rowStoreMapStatement   = new LongKeyHashMap();
+
+    public PersistentStoreCollectionSession(Session session) {
+        this.session = session;
+    }
+
+    public void setStore(Object key, PersistentStore store) {
+
+        TableBase table = (TableBase) key;
+
+        switch (table.persistenceScope) {
+
+            case TableBase.SCOPE_STATEMENT :
+                if (store == null) {
+                    rowStoreMapStatement.remove(table.getPersistenceId());
+                } else {
+                    rowStoreMapStatement.put(table.getPersistenceId(), store);
+                }
+                break;
+
+            // SYSTEM_TABLE
+            case TableBase.SCOPE_FULL :
+            case TableBase.SCOPE_TRANSACTION :
+                if (store == null) {
+                    rowStoreMapTransaction.remove(table.getPersistenceId());
+                } else {
+                    rowStoreMapTransaction.put(table.getPersistenceId(),
+                                               store);
+                }
+                break;
+
+            case TableBase.SCOPE_SESSION :
+                if (store == null) {
+                    rowStoreMapSession.remove(table.getPersistenceId());
+                } else {
+                    rowStoreMapSession.put(table.getPersistenceId(), store);
+                }
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "PersistentStoreCollectionSession");
+        }
+    }
+
+    public PersistentStore getStore(Object key) {
+
+        try {
+            TableBase       table = (TableBase) key;
+            PersistentStore store;
+
+            switch (table.persistenceScope) {
+
+                case TableBase.SCOPE_STATEMENT :
+                    store = (PersistentStore) rowStoreMapStatement.get(
+                        table.getPersistenceId());
+
+                    if (store == null) {
+                        store = session.database.logger.newStore(session,
+                                this, table, true);
+                    }
+
+                    return store;
+
+                // SYSTEM_TABLE
+                case TableBase.SCOPE_FULL :
+                case TableBase.SCOPE_TRANSACTION :
+                    store = (PersistentStore) rowStoreMapTransaction.get(
+                        table.getPersistenceId());
+
+                    if (store == null) {
+                        store = session.database.logger.newStore(session,
+                                this, table, true);
+                    }
+
+                    return store;
+
+                case TableBase.SCOPE_SESSION :
+                    store = (PersistentStore) rowStoreMapSession.get(
+                        table.getPersistenceId());
+
+                    if (store == null) {
+                        store = session.database.logger.newStore(session,
+                                this, table, true);
+                    }
+
+                    return store;
+            }
+        } catch (HsqlException e) {}
+
+        throw Error.runtimeError(ErrorCode.U_S0500,
+                                 "PersistentStoreCollectionSession");
+    }
+
+    public void clearAllTables() {
+
+        clearSessionTables();
+        clearTransactionTables();
+        clearStatementTables();
+    }
+
+    public void clearResultTables(long actionTimestamp) {
+
+        if (rowStoreMapSession.isEmpty()) {
+            return;
+        }
+
+        Iterator it = rowStoreMapSession.values().iterator();
+
+        while (it.hasNext()) {
+            PersistentStore store = (PersistentStore) it.next();
+
+            if (store.getTimestamp() == actionTimestamp) {
+                store.release();
+            }
+        }
+    }
+
+    public void clearSessionTables() {
+
+        if (rowStoreMapSession.isEmpty()) {
+            return;
+        }
+
+        Iterator it = rowStoreMapSession.values().iterator();
+
+        while (it.hasNext()) {
+            PersistentStore store = (PersistentStore) it.next();
+
+            store.release();
+        }
+
+        rowStoreMapSession.clear();
+    }
+
+    public void clearTransactionTables() {
+
+        if (rowStoreMapTransaction.isEmpty()) {
+            return;
+        }
+
+        Iterator it = rowStoreMapTransaction.values().iterator();
+
+        while (it.hasNext()) {
+            PersistentStore store = (PersistentStore) it.next();
+
+            store.release();
+        }
+
+        rowStoreMapTransaction.clear();
+    }
+
+    public void clearStatementTables() {
+
+        if (rowStoreMapStatement.isEmpty()) {
+            return;
+        }
+
+        Iterator it = rowStoreMapStatement.values().iterator();
+
+        while (it.hasNext()) {
+            PersistentStore store = (PersistentStore) it.next();
+
+            store.release();
+        }
+
+        rowStoreMapStatement.clear();
+    }
+
+    public void registerIndex(Table table) {
+
+        PersistentStore store = findStore(table);
+
+        if (store == null) {
+            return;
+        }
+
+        store.resetAccessorKeys(table.getIndexList());
+    }
+
+    public PersistentStore findStore(Table table) {
+
+        PersistentStore store = null;
+
+        switch (table.persistenceScope) {
+
+            case TableBase.SCOPE_STATEMENT :
+                store = (PersistentStore) rowStoreMapStatement.get(
+                    table.getPersistenceId());
+                break;
+
+            // SYSTEM_TABLE
+            case TableBase.SCOPE_FULL :
+            case TableBase.SCOPE_TRANSACTION :
+                store = (PersistentStore) rowStoreMapTransaction.get(
+                    table.getPersistenceId());
+                break;
+
+            case TableBase.SCOPE_SESSION :
+                store = (PersistentStore) rowStoreMapSession.get(
+                    table.getPersistenceId());
+                break;
+        }
+
+        return store;
+    }
+
+    public void moveData(Table oldTable, Table newTable, int colIndex,
+                         int adjust) {
+
+        PersistentStore oldStore = findStore(oldTable);
+
+        if (oldStore == null) {
+            return;
+        }
+
+        PersistentStore newStore = getStore(newTable);
+
+        newStore.moveData(session, oldStore, colIndex, adjust);
+        setStore(oldTable, null);
+    }
+}
diff --git a/src/org/hsqldb/persist/RAShadowFile.java b/src/org/hsqldb/persist/RAShadowFile.java
new file mode 100644
index 0000000..374019d
--- /dev/null
+++ b/src/org/hsqldb/persist/RAShadowFile.java
@@ -0,0 +1,204 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.hsqldb.Database;
+import org.hsqldb.lib.HsqlByteArrayOutputStream;
+import org.hsqldb.lib.Storage;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.store.BitMap;
+
+/*
+ * Wrapper for random access file for incremental backup of the .data file.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RAShadowFile {
+
+    final Database database;
+    final String   pathName;
+    final Storage  source;
+    Storage        dest;
+    final int      pageSize;
+    final long     maxSize;
+    final BitMap   bitMap;
+    boolean        zeroPageSet;
+    HsqlByteArrayOutputStream byteArrayOutputStream =
+        new HsqlByteArrayOutputStream(new byte[]{});
+
+    RAShadowFile(Database database, Storage source, String pathName,
+                 long maxSize, int pageSize) {
+
+        this.database = database;
+        this.pathName = pathName;
+        this.source   = source;
+        this.pageSize = pageSize;
+        this.maxSize  = maxSize;
+
+        int bitSize = (int) (maxSize / pageSize);
+
+        if (maxSize % pageSize != 0) {
+            bitSize++;
+        }
+
+        bitMap = new BitMap(bitSize);
+    }
+
+    void copy(long fileOffset, int size) throws IOException {
+
+        // always copy the first page
+        if (!zeroPageSet) {
+            copy(0);
+            bitMap.set(0);
+
+            zeroPageSet = true;
+        }
+
+        if (fileOffset >= maxSize) {
+            return;
+        }
+
+        long endOffset       = fileOffset + size;
+        int  startPageOffset = (int) (fileOffset / pageSize);
+        int  endPageOffset   = (int) (endOffset / pageSize);
+
+        if (endOffset % pageSize == 0) {
+            endPageOffset--;
+        }
+
+        for (; startPageOffset <= endPageOffset; startPageOffset++) {
+            copy(startPageOffset);
+        }
+    }
+
+    private void copy(int pageOffset) throws IOException {
+
+        if (bitMap.set(pageOffset) == 1) {
+            return;
+        }
+
+        long position = (long) pageOffset * pageSize;
+        int  readSize = pageSize;
+
+        if (maxSize - position < pageSize) {
+            readSize = (int) (maxSize - position);
+        }
+
+        try {
+            if (dest == null) {
+                open();
+            }
+
+            long   writePos = dest.length();
+            byte[] buffer   = new byte[pageSize + 12];
+
+            byteArrayOutputStream.setBuffer(buffer);
+            byteArrayOutputStream.writeInt(pageSize);
+            byteArrayOutputStream.writeLong(position);
+            source.seek(position);
+            source.read(buffer, 12, readSize);
+            dest.seek(writePos);
+            dest.write(buffer, 0, buffer.length);
+        } catch (Throwable t) {
+            bitMap.unset(pageOffset);
+            close();
+            database.logger.logWarningEvent("pos" + position + " " + readSize,
+                                            t);
+
+            throw JavaSystem.toIOException(t);
+        } finally {}
+    }
+
+    private void open() throws IOException {
+
+        if (database.logger.isStoredFileAccess()) {
+            dest = ScaledRAFile.newScaledRAFile(database, pathName, false,
+                                                ScaledRAFile.DATA_FILE_STORED);
+        } else {
+            dest = new ScaledRAFileSimple(pathName, "rwd");
+        }
+    }
+
+    /**
+     * Called externally after a series of copy() calls.
+     * Called internally after a restore or when error in writing
+     */
+    void close() throws IOException {
+
+        if (dest != null) {
+            dest.synch();
+            dest.close();
+
+            dest = null;
+        }
+    }
+
+    private static Storage getStorage(Database database, String pathName,
+                                      String openMode) throws IOException {
+
+        if (database.logger.isStoredFileAccess()) {
+            return ScaledRAFile.newScaledRAFile(database, pathName,
+                                                openMode.equals("r"),
+                                                ScaledRAFile.DATA_FILE_STORED);
+        } else {
+            return new ScaledRAFileSimple(pathName, openMode);
+        }
+    }
+
+    /** todo - take account of incomplete addition of block due to lack of disk */
+
+    // buggy database files had size == position == 0 at the end
+    public static void restoreFile(Database database, String sourceName,
+                                   String destName) throws IOException {
+
+        Storage source = getStorage(database, sourceName, "r");
+        Storage dest   = getStorage(database, destName, "rw");
+
+        while (source.getFilePointer() != source.length()) {
+            int    size     = source.readInt();
+            long   position = source.readLong();
+            byte[] buffer   = new byte[size];
+
+            source.read(buffer, 0, buffer.length);
+            dest.seek(position);
+            dest.write(buffer, 0, buffer.length);
+        }
+
+        source.close();
+        dest.close();
+    }
+}
diff --git a/src/org/hsqldb/persist/RowStoreAVL.java b/src/org/hsqldb/persist/RowStoreAVL.java
new file mode 100644
index 0000000..6c55255
--- /dev/null
+++ b/src/org/hsqldb/persist/RowStoreAVL.java
@@ -0,0 +1,419 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.ColumnSchema;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Row;
+import org.hsqldb.RowAVL;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.index.IndexAVL;
+import org.hsqldb.index.NodeAVL;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.types.Type;
+
+public abstract class RowStoreAVL implements PersistentStore {
+
+    PersistentStoreCollection manager;
+    Index[]                   indexList    = Index.emptyArray;
+    CachedObject[]            accessorList = CachedObject.emptyArray;
+    TableBase                 table;
+    int                       elementCount;
+
+    // for result tables
+    // for INFORMATION SCHEMA tables
+    long timestamp;
+
+    public TableBase getTable() {
+        return table;
+    }
+
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public boolean isMemory() {
+        return false;
+    }
+
+    public abstract int getAccessCount();
+
+    public abstract void set(CachedObject object);
+
+    public abstract CachedObject get(int key, boolean keep);
+
+    public abstract CachedObject get(CachedObject object, boolean keep);
+
+    public abstract int getStorageSize(int key);
+
+    public abstract void add(CachedObject object);
+
+    public abstract CachedObject get(RowInputInterface in);
+
+    public abstract CachedObject getNewInstance(int size);
+
+    public abstract CachedObject getNewCachedObject(Session session,
+            Object object);
+
+    public abstract void removePersistence(int i);
+
+    public abstract void removeAll();
+
+    public abstract void remove(int i);
+
+    public abstract void release(int i);
+
+    public abstract void commitPersistence(CachedObject object);
+
+    public abstract DataFileCache getCache();
+
+    public abstract void setCache(DataFileCache cache);
+
+    public abstract void release();
+
+    public PersistentStore getAccessorStore(Index index) {
+        return null;
+    }
+
+    public CachedObject getAccessor(Index key) {
+
+        int position = key.getPosition();
+
+        if (position >= accessorList.length) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVL");
+        }
+
+        return accessorList[position];
+    }
+
+    /**
+     * Basic delete with no logging or referential checks.
+     */
+    public void delete(Session session, Row row) {
+
+        row = (Row) get(row, false);
+
+        for (int i = indexList.length - 1; i >= 0; i--) {
+            indexList[i].delete(session, this, row);
+        }
+
+        row.delete(this);
+    }
+
+    public void indexRow(Session session, Row row) {
+
+        int i = 0;
+
+        try {
+            for (; i < indexList.length; i++) {
+                indexList[i].insert(session, this, row);
+            }
+        } catch (HsqlException e) {
+
+            // unique index violation - rollback insert
+            for (--i; i >= 0; i--) {
+                indexList[i].delete(session, this, row);
+            }
+
+            remove(row.getPos());
+
+            throw e;
+        }
+    }
+
+    //
+    public final void indexRows() {
+
+        RowIterator it = rowIterator();
+
+        for (int i = 1; i < indexList.length; i++) {
+            setAccessor(indexList[i], null);
+        }
+
+        while (it.hasNext()) {
+            Row row = it.getNextRow();
+
+            ((RowAVL) row).clearNonPrimaryNodes();
+
+            for (int i = 1; i < indexList.length; i++) {
+                indexList[i].insert(null, this, row);
+            }
+        }
+    }
+
+    public final RowIterator rowIterator() {
+
+        if (indexList.length == 0 || indexList[0] == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVL");
+        }
+
+        return indexList[0].firstRow(this);
+    }
+
+    public abstract void setAccessor(Index key, CachedObject accessor);
+
+    public abstract void setAccessor(Index key, int accessor);
+
+    public void resetAccessorKeys(Index[] keys) {
+
+        if (indexList.length == 0 || indexList[0] == null
+                || accessorList[0] == null) {
+            indexList    = keys;
+            accessorList = new CachedObject[indexList.length];
+
+            return;
+        }
+
+        CachedObject[] oldAccessors = accessorList;
+        Index[]        oldIndexList = indexList;
+        int            limit        = indexList.length;
+        int            diff         = 1;
+        int            position     = 0;
+
+        if (keys.length < indexList.length) {
+            diff  = -1;
+            limit = keys.length;
+        }
+
+        for (; position < limit; position++) {
+            if (indexList[position] != keys[position]) {
+                break;
+            }
+        }
+
+        accessorList = (CachedObject[]) ArrayUtil.toAdjustedArray(accessorList,
+                null, position, diff);
+        indexList = keys;
+
+        try {
+            if (diff > 0) {
+                insertIndexNodes(indexList[0], indexList[position]);
+            } else {
+                dropIndexFromRows(indexList[0], oldIndexList[position]);
+            }
+        } catch (HsqlException e) {
+            accessorList = oldAccessors;
+            indexList    = oldIndexList;
+
+            throw e;
+        }
+    }
+
+    public int elementCount(Session session) {
+
+        if (elementCount < 0) {
+            Index index = this.indexList[0];
+
+            if (index == null) {
+                elementCount = 0;
+            } else {
+                elementCount = ((IndexAVL) index).getNodeCount(session, this);
+            }
+        }
+
+        return elementCount;
+    }
+
+    public int elementCountUnique(Index index) {
+        return 0;
+    }
+
+    public void setElementCount(Index key, int size, int uniqueSize) {
+        elementCount = size;
+    }
+
+    public void updateElementCount(Index key, int size, int uniqueSize) {
+
+        if (key.getPosition() == 0 && elementCount > -1) {
+            elementCount += size;
+        }
+    }
+
+    /**
+     * Moves the data from an old store to new after changes to table
+     * The colindex argument is the index of the column that was
+     * added or removed. The adjust argument is {-1 | 0 | +1}
+     */
+    public final void moveData(Session session, PersistentStore other,
+                               int colindex, int adjust) {
+
+        Type   oldtype  = null;
+        Type   newtype  = null;
+        Object colvalue = null;
+
+        if (adjust >= 0 && colindex != -1) {
+            ColumnSchema column = ((Table) table).getColumn(colindex);
+
+            colvalue = column.getDefaultValue(session);
+            newtype  = ((Table) table).getColumnTypes()[colindex];
+        }
+
+        if (adjust <= 0 && colindex != -1) {
+            oldtype = ((Table) other.getTable()).getColumnTypes()[colindex];
+        }
+
+        RowIterator it    = other.rowIterator();
+        Table       table = (Table) this.table;
+
+        try {
+            while (it.hasNext()) {
+                Row      row      = it.getNextRow();
+                Object[] olddata  = row.getData();
+                Object[] data     = table.getEmptyRowData();
+                Object   oldvalue = null;
+
+                if (adjust == 0 && colindex != -1) {
+                    oldvalue = olddata[colindex];
+                    colvalue = newtype.convertToType(session, oldvalue,
+                                                     oldtype);
+                }
+
+                if (colvalue != null && newtype.isLobType()) {
+                    session.sessionData.adjustLobUsageCount(colvalue, +1);
+                }
+
+                if (oldvalue != null && oldtype != null
+                        && oldtype.isLobType()) {
+                    session.sessionData.adjustLobUsageCount(oldvalue, -1);
+                }
+
+                ArrayUtil.copyAdjustArray(olddata, data, colvalue, colindex,
+                                          adjust);
+                table.systemSetIdentityColumn(session, data);
+                table.enforceTypeLimits(session, data);
+                table.enforceRowConstraints(session, data);
+
+                // get object without RowAction
+                Row newrow = (Row) getNewCachedObject(null, data);
+
+                indexRow(null, newrow);
+            }
+        } catch (java.lang.OutOfMemoryError e) {
+            throw Error.error(ErrorCode.OUT_OF_MEMORY);
+        }
+    }
+
+    public void lock() {}
+
+    public void unlock() {}
+
+    void dropIndexFromRows(Index primaryIndex, Index oldIndex) {
+
+        RowIterator it       = primaryIndex.firstRow(this);
+        int         position = oldIndex.getPosition() - 1;
+
+        while (it.hasNext()) {
+            Row     row      = it.getNextRow();
+            int     i        = position - 1;
+            NodeAVL backnode = ((RowAVL) row).getNode(0);
+
+            while (i-- > 0) {
+                backnode = backnode.nNext;
+            }
+
+            backnode.nNext = backnode.nNext.nNext;
+        }
+    }
+
+    boolean insertIndexNodes(Index primaryIndex, Index newIndex) {
+
+        int           position = newIndex.getPosition();
+        RowIterator   it       = primaryIndex.firstRow(this);
+        int           rowCount = 0;
+        HsqlException error    = null;
+
+        try {
+            while (it.hasNext()) {
+                Row row = it.getNextRow();
+
+                ((RowAVL) row).insertNode(position);
+
+                // count before inserting
+                rowCount++;
+
+                newIndex.insert(null, this, row);
+            }
+
+            return true;
+        } catch (java.lang.OutOfMemoryError e) {
+            error = Error.error(ErrorCode.OUT_OF_MEMORY);
+        } catch (HsqlException e) {
+            error = e;
+        }
+
+        // backtrack on error
+        // rowCount rows have been modified
+        it = primaryIndex.firstRow(this);
+
+        for (int i = 0; i < rowCount; i++) {
+            Row     row      = it.getNextRow();
+            NodeAVL backnode = ((RowAVL) row).getNode(0);
+            int     j        = position;
+
+            while (--j > 0) {
+                backnode = backnode.nNext;
+            }
+
+            backnode.nNext = backnode.nNext.nNext;
+        }
+
+        throw error;
+    }
+
+    /**
+     * for result tables
+     */
+    void reindex(Session session, Index index) {
+
+        setAccessor(index, null);
+
+        RowIterator it = table.rowIterator(this);
+
+        while (it.hasNext()) {
+            Row row = it.getNextRow();
+
+            // may need to clear the node before insert
+            index.insert(session, this, row);
+        }
+    }
+}
diff --git a/src/org/hsqldb/persist/RowStoreAVLDisk.java b/src/org/hsqldb/persist/RowStoreAVLDisk.java
new file mode 100644
index 0000000..06d1df8
--- /dev/null
+++ b/src/org/hsqldb/persist/RowStoreAVLDisk.java
@@ -0,0 +1,376 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.IOException;
+
+import org.hsqldb.Database;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Row;
+import org.hsqldb.RowAVL;
+import org.hsqldb.RowAVLDisk;
+import org.hsqldb.RowAction;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TransactionManager;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.index.IndexAVL;
+import org.hsqldb.index.NodeAVL;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/*
+ * Implementation of PersistentStore for CACHED tables.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowStoreAVLDisk extends RowStoreAVL {
+
+    DataFileCache      cache;
+    RowOutputInterface rowOut;
+    Database           database;
+
+    public RowStoreAVLDisk(PersistentStoreCollection manager,
+                           DataFileCache cache, Table table) {
+
+        this.database     = table.database;
+        this.manager      = manager;
+        this.table        = table;
+        this.indexList    = table.getIndexList();
+        this.accessorList = new CachedObject[indexList.length];
+        this.cache        = cache;
+
+        if (cache != null) {
+            rowOut = cache.rowOut.duplicate();
+        }
+
+        manager.setStore(table, this);
+    }
+
+    public boolean isMemory() {
+        return false;
+    }
+
+    public int getAccessCount() {
+        return cache.getAccessCount();
+    }
+
+    public void set(CachedObject object) {
+
+        Row row = ((Row) object);
+
+        database.txManager.setTransactionInfo(row);
+    }
+
+    public CachedObject get(int key) {
+
+        CachedObject object = cache.get(key, this, false);
+
+        return object;
+    }
+
+    public CachedObject getKeep(int key) {
+
+        CachedObject object = cache.get(key, this, true);
+
+        return object;
+    }
+
+    public CachedObject get(int key, boolean keep) {
+
+        CachedObject object = cache.get(key, this, keep);
+
+        return object;
+    }
+
+    public CachedObject get(CachedObject object, boolean keep) {
+
+        object = cache.get(object, this, keep);
+
+        return object;
+    }
+
+    public int getStorageSize(int i) {
+        return cache.get(i, this, false).getStorageSize();
+    }
+
+    public void add(CachedObject object) {
+
+        int size = object.getRealSize(rowOut);
+
+        size = rowOut.getStorageSize(size);
+
+        object.setStorageSize(size);
+        cache.add(object);
+    }
+
+    public CachedObject get(RowInputInterface in) {
+
+        try {
+            return new RowAVLDisk(table, in);
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.DATA_FILE_ERROR, e);
+        }
+    }
+
+    public CachedObject getNewInstance(int size) {
+        return null;
+    }
+
+    public CachedObject getNewCachedObject(Session session, Object object) {
+
+        Row row = new RowAVLDisk(table, (Object[]) object);
+
+        add(row);
+
+        if (session != null) {
+            RowAction action = new RowAction(session, table,
+                                             RowAction.ACTION_INSERT, row,
+                                             null);
+
+            row.rowAction = action;
+        }
+
+        return row;
+    }
+
+    public void indexRow(Session session, Row row) {
+
+        int i = 0;
+
+        try {
+            for (; i < indexList.length; i++) {
+                indexList[i].insert(session, this, row);
+            }
+        } catch (HsqlException e) {
+
+            // unique index violation - rollback insert
+            for (--i; i >= 0; i--) {
+                indexList[i].delete(session, this, row);
+            }
+
+            remove(row.getPos());
+            database.txManager.removeTransactionInfo(row);
+
+            throw e;
+        }
+    }
+
+    public void removeAll() {
+        elementCount = 0;
+        ArrayUtil.fillArray(accessorList, null);
+    }
+
+    public void remove(int i) {
+        cache.remove(i, this);
+    }
+
+    public void removePersistence(int i) {}
+
+    public void release(int i) {
+        cache.release(i);
+    }
+
+    public void commitPersistence(CachedObject row) {}
+
+    public void commitRow(Session session, Row row, int changeAction,
+                          int txModel) {
+
+        Object[] data = row.getData();
+
+        switch (changeAction) {
+
+            case RowAction.ACTION_DELETE :
+                database.logger.writeDeleteStatement(session, (Table) table,
+                                                     data);
+
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                }
+                break;
+
+            case RowAction.ACTION_INSERT :
+                database.logger.writeInsertStatement(session, (Table) table,
+                                                     data);
+                break;
+
+            case RowAction.ACTION_INSERT_DELETE :
+
+                // INSERT + DELETE
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                }
+                break;
+
+            case RowAction.ACTION_DELETE_FINAL :
+                delete(session, row);
+
+                // remove after delete
+                database.txManager.removeTransactionInfo(row);
+                remove(row.getPos());
+                break;
+        }
+    }
+
+    public void rollbackRow(Session session, Row row, int changeAction,
+                            int txModel) {
+
+        switch (changeAction) {
+
+            case RowAction.ACTION_DELETE :
+                if (txModel == TransactionManager.LOCKS) {
+                    row = (Row) get(row, true);
+
+                    ((RowAVL) row).setNewNodes();
+                    row.keepInMemory(false);
+                    indexRow(session, row);
+                }
+                break;
+
+            case RowAction.ACTION_INSERT :
+                if (txModel == TransactionManager.LOCKS) {
+                    delete(session, row);
+                    remove(row.getPos());
+                }
+                break;
+
+            case RowAction.ACTION_INSERT_DELETE :
+
+                // INSERT + DELETE
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                }
+                break;
+        }
+    }
+
+    //
+    public DataFileCache getCache() {
+        return cache;
+    }
+
+    public void setCache(DataFileCache cache) {
+        this.cache = cache;
+    }
+
+    public void release() {
+
+        ArrayUtil.fillArray(accessorList, null);
+
+        cache = null;
+    }
+
+    public CachedObject getAccessor(Index key) {
+
+        NodeAVL node = (NodeAVL) accessorList[key.getPosition()];
+
+        if (node == null) {
+            return null;
+        }
+
+        if (!node.isInMemory()) {
+            RowAVL row = (RowAVL) get(node.getPos(), false);
+
+            node                            = row.getNode(key.getPosition());
+            accessorList[key.getPosition()] = node;
+        }
+
+        return node;
+    }
+
+    public void setAccessor(Index key, CachedObject accessor) {
+
+        Index index = (Index) key;
+
+        accessorList[index.getPosition()] = accessor;
+    }
+
+    public void setAccessor(Index key, int accessor) {
+
+        CachedObject object = get(accessor, false);
+
+        if (object != null) {
+            NodeAVL node = ((RowAVL) object).getNode(key.getPosition());
+
+            object = node;
+        }
+
+        setAccessor(key, object);
+    }
+
+    public void resetAccessorKeys(Index[] keys) {
+
+        if (indexList.length == 0 || indexList[0] == null
+                || accessorList[0] == null) {
+            indexList    = keys;
+            accessorList = new CachedObject[indexList.length];
+
+            return;
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVLDisk");
+    }
+
+    public int elementCount(Session session) {
+
+        Index index = this.indexList[0];
+
+        if (elementCount < 0) {
+            if (index == null) {
+                elementCount = 0;
+            } else {
+                elementCount = ((IndexAVL) index).getNodeCount(session, this);
+            }
+        }
+
+        if (session != null && index != null
+                && database.txManager.getTransactionControl()
+                   != TransactionManager.LOCKS) {
+            return ((IndexAVL) index).getNodeCount(session, this);
+        }
+
+        return elementCount;
+    }
+
+    public void lock() {
+        cache.writeLock.lock();
+    }
+
+    public void unlock() {
+        cache.writeLock.unlock();
+    }
+}
diff --git a/src/org/hsqldb/persist/RowStoreAVLDiskData.java b/src/org/hsqldb/persist/RowStoreAVLDiskData.java
new file mode 100644
index 0000000..b356eb1
--- /dev/null
+++ b/src/org/hsqldb/persist/RowStoreAVLDiskData.java
@@ -0,0 +1,267 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.IOException;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.Row;
+import org.hsqldb.RowAVL;
+import org.hsqldb.RowAVLDiskData;
+import org.hsqldb.RowAction;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TransactionManager;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.rowio.RowInputInterface;
+
+/*
+ * Implementation of PersistentStore for TEXT tables.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowStoreAVLDiskData extends RowStoreAVLDisk {
+
+    ReentrantReadWriteLock           lock = new ReentrantReadWriteLock(true);
+    ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
+    RowAVLDiskData                   currentRow;
+
+    public RowStoreAVLDiskData(PersistentStoreCollection manager,
+                               Table table) {
+        super(manager, null, table);
+    }
+
+    public CachedObject get(CachedObject object, boolean keep) {
+
+        writeLock.lock();
+
+        try {
+            currentRow = (RowAVLDiskData) object;
+            object     = cache.get(object, this, keep);
+
+            return object;
+        } finally {
+            currentRow = null;
+
+            writeLock.unlock();
+        }
+    }
+
+    public void add(CachedObject object) {
+
+        int size = object.getRealSize(cache.rowOut);
+
+        object.setStorageSize(size);
+
+        cache.add(object);
+    }
+
+    public CachedObject get(RowInputInterface in) {
+
+        try {
+            RowAVLDiskData newRow = new RowAVLDiskData(this, table, in);
+
+            if (currentRow == null) {
+                return newRow;
+            }
+
+            currentRow.setData(newRow.getData());
+
+            return currentRow;
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.TEXT_FILE_IO, e);
+        }
+    }
+
+    public CachedObject getNewCachedObject(Session session, Object object) {
+
+        Row row = new RowAVLDiskData(this, table, (Object[]) object);
+
+        add(row);
+
+        if (session != null) {
+            RowAction.addInsertAction(session, table, row);
+        }
+
+        return row;
+    }
+
+    public void indexRow(Session session, Row row) {
+
+        int i = 0;
+
+        try {
+            for (; i < indexList.length; i++) {
+                indexList[i].insert(session, this, row);
+            }
+        } catch (HsqlException e) {
+
+            // unique index violation - rollback insert
+            for (--i; i >= 0; i--) {
+                indexList[i].delete(session, this, row);
+            }
+
+            remove(row.getPos());
+
+            throw e;
+        }
+    }
+
+    public void set(CachedObject object) {}
+
+    public void removeAll() {
+        elementCount = 0;
+        ArrayUtil.fillArray(accessorList, null);
+    }
+
+    public void remove(int i) {
+
+        cache.remove(i, this);
+    }
+
+    public void removePersistence(int i) {
+        cache.removePersistence(i, this);
+    }
+
+    public void release(int i) {
+
+        cache.release(i);
+    }
+
+    public CachedObject getAccessor(Index key) {
+
+        int position = key.getPosition();
+
+        if (position >= accessorList.length) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVL");
+        }
+
+        return accessorList[position];
+    }
+
+    public void commitPersistence(CachedObject row) {
+
+        try {
+            cache.saveRow(row);
+        } catch (HsqlException e1) {}
+    }
+
+    public void delete(Session session, Row row) {
+
+        for (int j = indexList.length - 1; j >= 0; j--) {
+            indexList[j].delete(session, this, row);
+        }
+
+        row.delete(this);
+    }
+
+    public void commitRow(Session session, Row row, int changeAction,
+                          int txModel) {
+
+        switch (changeAction) {
+
+            case RowAction.ACTION_DELETE :
+                removePersistence(row.getPos());
+                break;
+
+            case RowAction.ACTION_INSERT :
+                commitPersistence(row);
+                break;
+
+            case RowAction.ACTION_INSERT_DELETE :
+
+                // INSERT + DELETE
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                } else {
+                    delete(session, row);
+                    remove(row.getPos());
+                }
+                break;
+
+            case RowAction.ACTION_DELETE_FINAL :
+                if (txModel != TransactionManager.LOCKS) {
+                    delete(session, row);
+                    remove(row.getPos());
+                }
+                break;
+        }
+    }
+
+    public void rollbackRow(Session session, Row row, int changeAction,
+                            int txModel) {
+
+        switch (changeAction) {
+
+            case RowAction.ACTION_DELETE :
+                if (txModel == TransactionManager.LOCKS) {
+
+                    ((RowAVL) row).setNewNodes();
+                    indexRow(session, row);
+                }
+                break;
+
+            case RowAction.ACTION_INSERT :
+                if (txModel == TransactionManager.LOCKS) {
+                    delete(session, row);
+                    remove(row.getPos());
+                } else {}
+                break;
+
+            case RowAction.ACTION_INSERT_DELETE :
+
+                // INSERT + DELETE
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                } else {
+                    delete(session, row);
+                    remove(row.getPos());
+                }
+                break;
+        }
+    }
+
+    //
+    public void release() {
+
+        ArrayUtil.fillArray(accessorList, null);
+        table.database.logger.closeTextCache((Table) table);
+
+        cache = null;
+    }
+}
diff --git a/src/org/hsqldb/persist/RowStoreAVLHybrid.java b/src/org/hsqldb/persist/RowStoreAVLHybrid.java
new file mode 100644
index 0000000..c3d165d
--- /dev/null
+++ b/src/org/hsqldb/persist/RowStoreAVLHybrid.java
@@ -0,0 +1,427 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.IOException;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.Row;
+import org.hsqldb.RowAVL;
+import org.hsqldb.RowAVLDisk;
+import org.hsqldb.RowAction;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.TransactionManager;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.rowio.RowInputInterface;
+
+/*
+ * Implementation of PersistentStore for result set and temporary tables.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowStoreAVLHybrid extends RowStoreAVL implements PersistentStore {
+
+    final Session         session;
+    DataFileCacheSession  cache;
+    private int           maxMemoryRowCount;
+    private int           memoryRowCount;
+    private boolean       useCache;
+    private boolean       isCached;
+    private final boolean isTempTable;
+    int                   rowIdSequence = 0;
+
+    public RowStoreAVLHybrid(Session session,
+                             PersistentStoreCollection manager,
+                             TableBase table) {
+
+        this(session, manager, table, true);
+
+        cache = session.sessionData.getResultCache();
+
+        if (cache != null) {
+            isCached = true;
+        }
+    }
+
+    public RowStoreAVLHybrid(Session session,
+                             PersistentStoreCollection manager,
+                             TableBase table, boolean useCache) {
+
+        this.session           = session;
+        this.manager           = manager;
+        this.table             = table;
+        this.maxMemoryRowCount = session.getResultMemoryRowCount();
+        this.isTempTable       = table.getTableType() == TableBase.TEMP_TABLE;
+        this.useCache          = useCache;
+
+        if (maxMemoryRowCount == 0) {
+            this.useCache = false;
+        }
+
+        if (table.getTableType() == TableBase.RESULT_TABLE) {
+            timestamp = session.getActionTimestamp();
+        }
+
+// test code to force use of cache
+/*
+        if (useCache) {
+            cache = session.sessionData.getResultCache();
+
+            if (cache != null) {
+                isCached = useCache;
+
+                cache.storeCount++;
+            }
+        }
+*/
+
+//
+        resetAccessorKeys(table.getIndexList());
+        manager.setStore(table, this);
+    }
+
+    public boolean isMemory() {
+        return !isCached;
+    }
+
+    public synchronized int getAccessCount() {
+        return isCached ? cache.getAccessCount()
+                        : 0;
+    }
+
+    public void set(CachedObject object) {}
+
+    public CachedObject get(int i) {
+
+        try {
+            if (isCached) {
+                return cache.get(i, this, false);
+            } else {
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "RowStoreAVLHybrid");
+            }
+        } catch (HsqlException e) {
+            return null;
+        }
+    }
+
+    public CachedObject getKeep(int i) {
+
+        try {
+            if (isCached) {
+                return cache.get(i, this, true);
+            } else {
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "RowStoreAVLHybrid");
+            }
+        } catch (HsqlException e) {
+            return null;
+        }
+    }
+
+    public CachedObject get(int i, boolean keep) {
+
+        try {
+            if (isCached) {
+                return cache.get(i, this, keep);
+            } else {
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "RowStoreAVLHybrid");
+            }
+        } catch (HsqlException e) {
+            return null;
+        }
+    }
+
+    public CachedObject get(CachedObject object, boolean keep) {
+
+        try {
+            if (isCached) {
+                return cache.get(object, this, keep);
+            } else {
+                return object;
+            }
+        } catch (HsqlException e) {
+            return null;
+        }
+    }
+
+    public int getStorageSize(int i) {
+
+        try {
+            if (isCached) {
+                return cache.get(i, this, false).getStorageSize();
+            } else {
+                return 0;
+            }
+        } catch (HsqlException e) {
+            return 0;
+        }
+    }
+
+    public void add(CachedObject object) {
+
+        if (isCached) {
+            int size = object.getRealSize(cache.rowOut);
+
+            size = cache.rowOut.getStorageSize(size);
+
+            object.setStorageSize(size);
+            cache.add(object);
+        }
+    }
+
+    public CachedObject get(RowInputInterface in) {
+
+        try {
+            if (isCached) {
+                return new RowAVLDisk(table, in);
+            }
+        } catch (HsqlException e) {
+            return null;
+        } catch (IOException e1) {
+            return null;
+        }
+
+        return null;
+    }
+
+    public CachedObject getNewInstance(int size) {
+        return null;
+    }
+
+    public CachedObject getNewCachedObject(Session session, Object object) {
+
+        int id = rowIdSequence++;
+
+        if (isCached) {
+            Row row = new RowAVLDisk(table, (Object[]) object);
+
+            add(row);
+
+            if (isTempTable) {
+                RowAction.addInsertAction(session, (Table) table, row);
+            }
+
+            return row;
+        } else {
+            memoryRowCount++;
+
+            if (useCache && memoryRowCount > maxMemoryRowCount) {
+                changeToDiskTable();
+
+                return getNewCachedObject(session, object);
+            }
+
+            Row row = new RowAVL(table, (Object[]) object, id);
+
+            if (isTempTable) {
+                RowAction action = new RowAction(session, table,
+                                                 RowAction.ACTION_INSERT, row,
+                                                 null);
+
+                row.rowAction = action;
+            }
+
+            return row;
+        }
+    }
+
+    public void removeAll() {
+        elementCount = 0;
+        ArrayUtil.fillArray(accessorList, null);
+    }
+
+    public void remove(int i) {
+
+        if (isCached) {
+            cache.remove(i, this);
+        }
+    }
+
+    public void removePersistence(int i) {}
+
+    public void release(int i) {
+
+        if (isCached) {
+            cache.release(i);
+        }
+    }
+
+    public void commitPersistence(CachedObject row) {}
+
+    public void commitRow(Session session, Row row, int changeAction,
+                          int txModel) {
+
+        switch (changeAction) {
+
+            case RowAction.ACTION_DELETE :
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                }
+                break;
+
+            case RowAction.ACTION_INSERT :
+                break;
+
+            case RowAction.ACTION_INSERT_DELETE :
+
+                // INSERT + DELEETE
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                }
+                break;
+
+            case RowAction.ACTION_DELETE_FINAL :
+                delete(session, row);
+                break;
+        }
+    }
+
+    public void rollbackRow(Session session, Row row, int changeAction,
+                            int txModel) {
+
+        switch (changeAction) {
+
+            case RowAction.ACTION_DELETE :
+                if (txModel == TransactionManager.LOCKS) {
+                    row = (Row) get(row, true);
+
+                    ((RowAVL) row).setNewNodes();
+                    row.keepInMemory(false);
+                    indexRow(session, row);
+                }
+                break;
+
+            case RowAction.ACTION_INSERT :
+                if (txModel == TransactionManager.LOCKS) {
+                    delete(session, row);
+                    remove(row.getPos());
+                }
+                break;
+
+            case RowAction.ACTION_INSERT_DELETE :
+
+                // INSERT + DELEETE
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                }
+                break;
+        }
+    }
+
+    //
+    public DataFileCache getCache() {
+        return cache;
+    }
+
+    public void setCache(DataFileCache cache) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVLHybrid");
+    }
+
+    public void release() {
+
+        ArrayUtil.fillArray(accessorList, null);
+
+        if (isCached) {
+            cache.storeCount--;
+
+            if (cache.storeCount == 0) {
+                cache.clear();
+            }
+
+            cache    = null;
+            isCached = false;
+        }
+
+        manager.setStore(table, null);
+    }
+
+    public void setAccessor(Index key, CachedObject accessor) {
+
+        Index index = (Index) key;
+
+        accessorList[index.getPosition()] = accessor;
+    }
+
+    public void setAccessor(Index key, int accessor) {}
+
+    public synchronized void resetAccessorKeys(Index[] keys) {
+
+        if (indexList.length == 0 || indexList[0] == null
+                || accessorList[0] == null) {
+            indexList    = keys;
+            accessorList = new CachedObject[indexList.length];
+
+            return;
+        }
+
+        if (isCached) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVLHybrid");
+        }
+
+        super.resetAccessorKeys(keys);
+    }
+
+    public void changeToDiskTable() {
+
+        cache = session.sessionData.getResultCache();
+
+        if (cache != null) {
+            RowIterator iterator = table.rowIterator(this);
+
+            ArrayUtil.fillArray(accessorList, null);
+
+            isCached = true;
+
+            cache.storeCount++;
+
+            while (iterator.hasNext()) {
+                Row row    = iterator.getNextRow();
+                Row newRow = (Row) getNewCachedObject(session, row.getData());
+
+                indexRow(null, newRow);
+                row.destroy();
+            }
+        }
+
+        maxMemoryRowCount = Integer.MAX_VALUE;
+    }
+}
diff --git a/src/org/hsqldb/persist/RowStoreAVLMemory.java b/src/org/hsqldb/persist/RowStoreAVLMemory.java
new file mode 100644
index 0000000..121a089
--- /dev/null
+++ b/src/org/hsqldb/persist/RowStoreAVLMemory.java
@@ -0,0 +1,245 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.Database;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Row;
+import org.hsqldb.RowAVL;
+import org.hsqldb.RowAction;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.TransactionManager;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.index.Index;
+import org.hsqldb.index.IndexAVL;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.rowio.RowInputInterface;
+
+/*
+ * Implementation of PersistentStore for MEMORY tables.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowStoreAVLMemory extends RowStoreAVL implements PersistentStore {
+
+    Database database;
+    int      rowIdSequence = 0;
+
+    public RowStoreAVLMemory(PersistentStoreCollection manager, Table table) {
+
+        this.database     = table.database;
+        this.manager      = manager;
+        this.table        = table;
+        this.indexList    = table.getIndexList();
+        this.accessorList = new CachedObject[indexList.length];
+
+        manager.setStore(table, this);
+    }
+
+    public boolean isMemory() {
+        return true;
+    }
+
+    public int getAccessCount() {
+        return 0;
+    }
+
+    public void set(CachedObject object) {}
+
+    public CachedObject get(int i) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVMemory");
+    }
+
+    public CachedObject getKeep(int i) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVLMemory");
+    }
+
+    public CachedObject get(int i, boolean keep) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVLMemory");
+    }
+
+    public CachedObject get(CachedObject object, boolean keep) {
+        return object;
+    }
+
+    public int getStorageSize(int i) {
+        return 0;
+    }
+
+    public void add(CachedObject object) {}
+
+    public CachedObject get(RowInputInterface in) {
+        return null;
+    }
+
+    public CachedObject getNewInstance(int size) {
+        return null;
+    }
+
+    public CachedObject getNewCachedObject(Session session, Object object) {
+
+        int id;
+
+        synchronized (this) {
+            id = rowIdSequence++;
+        }
+
+        Row row = new RowAVL(table, (Object[]) object, id);
+
+        if (session != null) {
+            RowAction action = new RowAction(session, table,
+                                             RowAction.ACTION_INSERT, row,
+                                             null);
+
+            row.rowAction = action;
+        }
+
+        return row;
+    }
+
+    public void removeAll() {
+        elementCount = 0;
+        ArrayUtil.fillArray(accessorList, null);
+    }
+
+    public void remove(int i) {}
+
+    public void removePersistence(int i) {}
+
+    public void release(int i) {}
+
+    public void commitPersistence(CachedObject row) {}
+
+    public void commitRow(Session session, Row row, int changeAction,
+                          int txModel) {
+
+        Object[] data = row.getData();
+
+        switch (changeAction) {
+
+            case RowAction.ACTION_DELETE :
+                database.logger.writeDeleteStatement(session, (Table) table,
+                                                     data);
+                break;
+
+            case RowAction.ACTION_INSERT :
+                database.logger.writeInsertStatement(session, (Table) table,
+                                                     data);
+                break;
+
+            case RowAction.ACTION_INSERT_DELETE :
+
+                // INSERT + DELETE
+                break;
+
+            case RowAction.ACTION_DELETE_FINAL :
+                delete(session, row);
+                break;
+        }
+    }
+
+    public void rollbackRow(Session session, Row row, int changeAction,
+                            int txModel) {
+
+        switch (changeAction) {
+
+            case RowAction.ACTION_DELETE :
+                if (txModel == TransactionManager.LOCKS) {
+                    ((RowAVL) row).setNewNodes();
+                    indexRow(session, row);
+                }
+                break;
+
+            case RowAction.ACTION_INSERT :
+                if (txModel == TransactionManager.LOCKS) {
+                    delete(session, row);
+                    remove(row.getPos());
+                }
+                break;
+
+            case RowAction.ACTION_INSERT_DELETE :
+
+                // INSERT + DELETE
+                if (txModel == TransactionManager.LOCKS) {
+                    remove(row.getPos());
+                }
+                break;
+        }
+    }
+
+    //
+    public DataFileCache getCache() {
+        return null;
+    }
+
+    public void setCache(DataFileCache cache) {}
+
+    public void release() {
+        ArrayUtil.fillArray(accessorList, null);
+    }
+
+    public void setAccessor(Index key, CachedObject accessor) {
+
+        Index index = (Index) key;
+
+        accessorList[index.getPosition()] = accessor;
+    }
+
+    public void setAccessor(Index key, int accessor) {}
+
+    public int elementCount(Session session) {
+
+        Index index = this.indexList[0];
+
+        if (elementCount < 0) {
+            if (index == null) {
+                elementCount = 0;
+            } else {
+                elementCount = ((IndexAVL) index).getNodeCount(session, this);
+            }
+        }
+
+        if (session != null && index != null
+                && (table.getTableType() == TableBase.SYSTEM_TABLE
+                    || database.txManager.getTransactionControl()
+                       != TransactionManager.LOCKS)) {
+            return ((IndexAVL) index).getNodeCount(session, this);
+        }
+
+        return elementCount;
+    }
+}
diff --git a/src/org/hsqldb/persist/ScaledRAFile.java b/src/org/hsqldb/persist/ScaledRAFile.java
new file mode 100644
index 0000000..ee19d5a
--- /dev/null
+++ b/src/org/hsqldb/persist/ScaledRAFile.java
@@ -0,0 +1,519 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.EOFException;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Constructor;
+
+import org.hsqldb.Database;
+import org.hsqldb.lib.HsqlByteArrayInputStream;
+import org.hsqldb.lib.Storage;
+
+// fredt@users 20030111 - patch 1.7.2 by bohgammer@users - pad file before seek() beyond end
+// some incompatible JVM implementations do not allow seek beyond the existing end of file
+
+/**
+ * This class is a wapper for a random access file such as that used for
+ * CACHED table storage.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version  1.9.0
+ * @since  1.7.2
+ */
+final class ScaledRAFile implements ScaledRAInterface {
+
+    static final int  DATA_FILE_RAF    = 0;
+    static final int  DATA_FILE_NIO    = 1;
+    static final int  DATA_FILE_JAR    = 2;
+    static final int  DATA_FILE_STORED = 3;
+    static final long MAX_NIO_LENGTH   = (1L << 28);
+
+    // We are using persist.Logger-instance-specific FrameworkLogger
+    // because it is Database-instance specific.
+    // If add any static level logging, should instantiate a standard,
+    // context-agnostic FrameworkLogger for that purpose.
+    final Database                 database;
+    final RandomAccessFile         file;
+    final FileDescriptor           fileDescriptor;
+    private final boolean          readOnly;
+    final String                   fileName;
+    boolean                        isNio;
+    boolean                        bufferDirty = true;
+    final byte[]                   buffer;
+    final HsqlByteArrayInputStream ba;
+    long                           bufferOffset;
+    long                           fileLength;
+
+    //
+    long seekPosition;
+    long realPosition;
+    int  cacheHit;
+
+    /**
+     * seekPosition is the position in seek() calls or after reading or writing
+     * realPosition is the file position
+     */
+    static Storage newScaledRAFile(Database database, String name,
+                                   boolean readonly,
+                                   int type)
+                                   throws FileNotFoundException, IOException {
+
+        if (type == DATA_FILE_STORED) {
+            try {
+                String cname = database.getURLProperties().getProperty(
+                    HsqlDatabaseProperties.url_storage_class_name);
+                String skey = database.getURLProperties().getProperty(
+                    HsqlDatabaseProperties.url_storage_key);
+                Class       zclass      = Class.forName(cname);
+                Constructor constructor = zclass.getConstructor(new Class[] {
+                    String.class, Boolean.class, Object.class
+                });
+
+                return (Storage) constructor.newInstance(new Object[] {
+                    name, new Boolean(readonly), skey
+                });
+            } catch (ClassNotFoundException e) {
+                throw new IOException();
+            } catch (NoSuchMethodException e) {
+                throw new IOException();
+            } catch (InstantiationException e) {
+                throw new IOException();
+            } catch (IllegalAccessException e) {
+                throw new IOException();
+            } catch (java.lang.reflect.InvocationTargetException e) {
+                throw new IOException();
+            }
+        }
+
+        if (type == DATA_FILE_JAR) {
+            return new ScaledRAFileInJar(name);
+        } else if (type == DATA_FILE_RAF) {
+            return new ScaledRAFile(database, name, readonly);
+        } else {
+            java.io.File fi     = new java.io.File(name);
+            long         length = fi.length();
+
+            if (length > MAX_NIO_LENGTH) {
+                return new ScaledRAFile(database, name, readonly);
+            }
+
+            try {
+                Class.forName("java.nio.MappedByteBuffer");
+
+                return new ScaledRAFileHybrid(database, name, readonly);
+            } catch (Exception e) {
+                return new ScaledRAFile(database, name, readonly);
+            }
+        }
+    }
+
+    ScaledRAFile(Database database, String name,
+                 boolean readonly) throws FileNotFoundException, IOException {
+
+        this.database = database;
+        this.readOnly = readonly;
+        this.fileName = name;
+        this.file     = new RandomAccessFile(name, readonly ? "r"
+                                                            : "rw");
+
+        int bufferSize = 1 << 12;
+
+        buffer         = new byte[bufferSize];
+        ba             = new HsqlByteArrayInputStream(buffer);
+        fileDescriptor = file.getFD();
+        fileLength = length();
+    }
+
+    public long length() throws IOException {
+        return file.length();
+    }
+
+    /**
+     * Some JVM's do not allow seek beyond end of file, so zeros are written
+     * first in that case. Reported by bohgammer@users in Open Disucssion
+     * Forum.
+     */
+    public void seek(long position) throws IOException {
+
+        if (!readOnly && fileLength < position) {
+            long tempSize = position - fileLength;
+
+            if (tempSize > 1 << 16) {
+                tempSize = 1 << 16;
+            }
+
+            byte[] temp = new byte[(int) tempSize];
+
+            try {
+                long pos = fileLength;
+
+                for (; pos < position - tempSize; pos += tempSize) {
+                    file.seek(pos);
+                    file.write(temp, 0, (int) tempSize);
+                }
+
+                file.seek(pos);
+                file.write(temp, 0, (int) (position - pos));
+
+                realPosition = position;
+                fileLength   = position;
+            } catch (IOException e) {
+                database.logger.logWarningEvent("seek failed", e);
+
+                throw e;
+            }
+        }
+
+        seekPosition = position;
+    }
+
+    public long getFilePointer() throws IOException {
+        return seekPosition;
+    }
+
+    private void readIntoBuffer() throws IOException {
+
+        long filePos    = seekPosition;
+        long subOffset  = filePos % buffer.length;
+        long readLength = fileLength - (filePos - subOffset);
+
+        try {
+            if (readLength <= 0) {
+                throw new IOException("read beyond end of file");
+            }
+
+            if (readLength > buffer.length) {
+                readLength = buffer.length;
+            }
+
+            if (realPosition != filePos - subOffset) {
+                file.seek(filePos - subOffset);
+            }
+
+            file.readFully(buffer, 0, (int) readLength);
+
+            bufferOffset = filePos - subOffset;
+            realPosition = bufferOffset + readLength;
+            bufferDirty  = false;
+        } catch (IOException e) {
+            resetPointer();
+            database.logger.logWarningEvent(" " + realPosition + " "
+                                            + readLength, e);
+
+            throw e;
+        }
+    }
+
+    public int read() throws IOException {
+
+        try {
+            if (seekPosition >= fileLength) {
+                return -1;
+            }
+
+            if (bufferDirty || seekPosition < bufferOffset
+                    || seekPosition >= bufferOffset + buffer.length) {
+                readIntoBuffer();
+            } else {
+                cacheHit++;
+            }
+
+            ba.reset();
+            ba.skip(seekPosition - bufferOffset);
+
+            int val = ba.read();
+
+            seekPosition++;
+
+            return val;
+        } catch (IOException e) {
+            resetPointer();
+            database.logger.logWarningEvent("read failed", e);
+
+            throw e;
+        }
+    }
+
+    public long readLong() throws IOException {
+
+        try {
+            if (bufferDirty || seekPosition < bufferOffset
+                    || seekPosition >= bufferOffset + buffer.length) {
+                readIntoBuffer();
+            } else {
+                cacheHit++;
+            }
+
+            ba.reset();
+
+            if (seekPosition - bufferOffset
+                    != ba.skip(seekPosition - bufferOffset)) {
+                throw new EOFException();
+            }
+
+            long val;
+
+            try {
+                val = ba.readLong();
+            } catch (EOFException e) {
+                file.seek(seekPosition);
+
+                val          = file.readLong();
+                realPosition = file.getFilePointer();
+            }
+
+            seekPosition += 8;
+
+            return val;
+        } catch (IOException e) {
+            resetPointer();
+            database.logger.logWarningEvent("failed ot read a Long", e);
+
+            throw e;
+        }
+    }
+
+    public int readInt() throws IOException {
+
+        try {
+            if (bufferDirty || seekPosition < bufferOffset
+                    || seekPosition >= bufferOffset + buffer.length) {
+                readIntoBuffer();
+            } else {
+                cacheHit++;
+            }
+
+            ba.reset();
+
+            if (seekPosition - bufferOffset
+                    != ba.skip(seekPosition - bufferOffset)) {
+                throw new EOFException();
+            }
+
+            int val;
+
+            try {
+                val = ba.readInt();
+            } catch (EOFException e) {
+                file.seek(seekPosition);
+
+                val          = file.readInt();
+                realPosition = file.getFilePointer();
+            }
+
+            seekPosition += 4;
+
+            return val;
+        } catch (IOException e) {
+            resetPointer();
+            database.logger.logWarningEvent("failed to read an Int", e);
+
+            throw e;
+        }
+    }
+
+    public void read(byte[] b, int offset, int length) throws IOException {
+
+        try {
+            if (bufferDirty || seekPosition < bufferOffset
+                    || seekPosition >= bufferOffset + buffer.length) {
+                readIntoBuffer();
+            } else {
+                cacheHit++;
+            }
+
+            ba.reset();
+
+            if (seekPosition - bufferOffset
+                    != ba.skip(seekPosition - bufferOffset)) {
+                throw new EOFException();
+            }
+
+            int bytesRead = ba.read(b, offset, length);
+
+            seekPosition += bytesRead;
+
+            if (bytesRead < length) {
+                if (seekPosition != realPosition) {
+                    file.seek(seekPosition);
+                }
+
+                file.readFully(b, offset + bytesRead, length - bytesRead);
+
+                seekPosition += (length - bytesRead);
+                realPosition = seekPosition;
+            }
+        } catch (IOException e) {
+            resetPointer();
+            database.logger.logWarningEvent("faeild to read a byte array", e);
+
+            throw e;
+        }
+    }
+
+    public void write(byte[] b, int off, int len) throws IOException {
+
+        try {
+            if (realPosition != seekPosition) {
+                file.seek(seekPosition);
+
+                realPosition = seekPosition;
+            }
+
+            if (seekPosition < bufferOffset + buffer.length
+                    && seekPosition + len > bufferOffset) {
+                bufferDirty = true;
+            }
+
+            file.write(b, off, len);
+
+            seekPosition += len;
+            realPosition = seekPosition;
+
+            if (realPosition > fileLength) {
+                fileLength = realPosition;
+            }
+        } catch (IOException e) {
+            resetPointer();
+            database.logger.logWarningEvent("failed to write a byte array", e);
+
+            throw e;
+        }
+    }
+
+    public void writeInt(int i) throws IOException {
+
+        try {
+            if (realPosition != seekPosition) {
+                file.seek(seekPosition);
+
+                realPosition = seekPosition;
+            }
+
+            if (seekPosition < bufferOffset + buffer.length
+                    && seekPosition + 4 > bufferOffset) {
+                bufferDirty = true;
+            }
+
+            file.writeInt(i);
+
+            seekPosition += 4;
+            realPosition = seekPosition;
+
+            if (realPosition > fileLength) {
+                fileLength = realPosition;
+            }
+        } catch (IOException e) {
+            resetPointer();
+            database.logger.logWarningEvent("failed to write an int", e);
+
+            throw e;
+        }
+    }
+
+    public void writeLong(long i) throws IOException {
+
+        try {
+            if (realPosition != seekPosition) {
+                file.seek(seekPosition);
+
+                realPosition = seekPosition;
+            }
+
+            if (seekPosition < bufferOffset + buffer.length
+                    && seekPosition + 8 > bufferOffset) {
+                bufferDirty = true;
+            }
+
+            file.writeLong(i);
+
+            seekPosition += 8;
+            realPosition = seekPosition;
+
+            if (realPosition > fileLength) {
+                fileLength = realPosition;
+            }
+        } catch (IOException e) {
+            resetPointer();
+            database.logger.logWarningEvent("failed to write a Long", e);
+
+            throw e;
+        }
+    }
+
+    public void close() throws IOException {
+        file.close();
+    }
+
+    public boolean isReadOnly() {
+        return readOnly;
+    }
+
+    public boolean wasNio() {
+        return false;
+    }
+
+    public boolean canAccess(int length) {
+        return true;
+    }
+
+    public boolean canSeek(long position) {
+        return true;
+    }
+
+    public Database getDatabase() {
+        return null;
+    }
+
+    public void synch() {
+
+        try {
+            fileDescriptor.sync();
+        } catch (IOException e) {}
+    }
+
+    private void resetPointer() {
+
+        try {
+            bufferDirty = true;
+
+            file.seek(seekPosition);
+
+            realPosition = seekPosition;
+            fileLength   = length();
+        } catch (Throwable e) {}
+    }
+}
diff --git a/src/org/hsqldb/persist/ScaledRAFileHybrid.java b/src/org/hsqldb/persist/ScaledRAFileHybrid.java
new file mode 100644
index 0000000..f00b46a
--- /dev/null
+++ b/src/org/hsqldb/persist/ScaledRAFileHybrid.java
@@ -0,0 +1,197 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.IOException;
+
+import org.hsqldb.Database;
+
+/**
+ * Mixe NIO / non-NIO version of ScaledRAFile.
+ * This class is used only for storing a CACHED
+ * TABLE .data file and cannot be used for TEXT TABLE source files.
+ *
+ * Due to various issues with java.nio classes, this class will use a mapped
+ * channel of fixed size. After reaching this size, the file and channel are
+ * closed and a new one opened, up to the maximum size.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version  1.8.0.5
+ * @since 1.7.2
+ */
+public final class ScaledRAFileHybrid implements ScaledRAInterface {
+
+    final Database    database;
+    final String      fileName;
+    final boolean     isReadOnly;
+    final boolean     wasNio;
+    long              maxLength;
+    ScaledRAInterface store;
+
+    public ScaledRAFileHybrid(Database database, String name,
+                              boolean readOnly) throws IOException {
+
+        this.database   = database;
+        this.fileName   = name;
+        this.isReadOnly = readOnly;
+
+        newStore(0);
+
+        this.wasNio = store.wasNio();
+    }
+
+    public long length() throws IOException {
+        return store.length();
+    }
+
+    public void seek(long position) throws IOException {
+        checkSeek(position);
+        store.seek(position);
+    }
+
+    public long getFilePointer() throws IOException {
+        return store.getFilePointer();
+    }
+
+    public int read() throws IOException {
+
+        checkLength(1);
+
+        return store.read();
+    }
+
+    public void read(byte[] b, int offset, int length) throws IOException {
+        checkLength(length);
+        store.read(b, offset, length);
+    }
+
+    public void write(byte[] b, int offset, int length) throws IOException {
+        checkLength(length);
+        store.write(b, offset, length);
+    }
+
+    public int readInt() throws IOException {
+
+        checkLength(4);
+
+        return store.readInt();
+    }
+
+    public void writeInt(int i) throws IOException {
+        checkLength(4);
+        store.writeInt(i);
+    }
+
+    public long readLong() throws IOException {
+
+        checkLength(8);
+
+        return store.readLong();
+    }
+
+    public void writeLong(long i) throws IOException {
+        checkLength(8);
+        store.writeLong(i);
+    }
+
+    public void close() throws IOException {
+        store.close();
+    }
+
+    public boolean isReadOnly() {
+        return store.isReadOnly();
+    }
+
+    public boolean wasNio() {
+        return wasNio;
+    }
+
+    public boolean canAccess(int length) {
+        return true;
+    }
+
+    public boolean canSeek(long position) {
+        return true;
+    }
+
+    public Database getDatabase() {
+        return null;
+    }
+
+    public void synch() {
+        store.synch();
+    }
+
+    private void checkLength(int length) throws IOException {
+
+        if (store.canAccess(length)) {
+            return;
+        }
+
+        newStore(store.getFilePointer() + length);
+    }
+
+    private void checkSeek(long position) throws IOException {
+
+        if (store.canSeek(position)) {
+            return;
+        }
+
+        newStore(position);
+    }
+
+    void newStore(long requiredPosition) throws IOException {
+
+        long currentPosition = 0;
+
+        if (store != null) {
+            currentPosition = store.getFilePointer();
+
+            store.close();
+        }
+
+        if (requiredPosition <= ScaledRAFile.MAX_NIO_LENGTH) {
+            try {
+                store = new ScaledRAFileNIO(database, fileName, isReadOnly,
+                                            (int) requiredPosition);
+
+                store.seek(currentPosition);
+
+                return;
+            } catch (Throwable e) {}
+        }
+
+        store = new ScaledRAFile(database, fileName, isReadOnly);
+
+        store.seek(currentPosition);
+    }
+}
diff --git a/src/org/hsqldb/persist/ScaledRAFileInJar.java b/src/org/hsqldb/persist/ScaledRAFileInJar.java
new file mode 100644
index 0000000..4a3215a
--- /dev/null
+++ b/src/org/hsqldb/persist/ScaledRAFileInJar.java
@@ -0,0 +1,274 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.DataInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.hsqldb.Database;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlByteArrayInputStream;
+
+/**
+ * This class is a random access wrapper around a DataInputStream object and
+ * enables access to cached tables when a database is included in a jar.
+ *
+ * A proof-of-concept prototype was first contributed by winfriedthom@users.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version  1.9.0
+ * @since  1.8.0
+ */
+final class ScaledRAFileInJar implements ScaledRAInterface {
+
+    DataInputStream          file;
+    final String             fileName;
+    long                     fileLength;
+    boolean                  bufferDirty = true;
+    byte[]                   buffer      = new byte[4096];
+    HsqlByteArrayInputStream ba = new HsqlByteArrayInputStream(buffer);
+    long                     bufferOffset;
+
+    //
+    long seekPosition;
+    long realPosition;
+
+    ScaledRAFileInJar(String name) throws FileNotFoundException, IOException {
+
+        fileName   = name;
+        fileLength = getLength();
+
+        resetStream();
+    }
+
+    public long length() throws IOException {
+        return fileLength;
+    }
+
+    /**
+     * Some JVM's do not allow seek beyond end of file, so zeros are written
+     * first in that case. Reported by bohgammer@users in Open Disucssion
+     * Forum.
+     */
+    public void seek(long position) throws IOException {
+        seekPosition = position;
+    }
+
+    public long getFilePointer() throws IOException {
+        return seekPosition;
+    }
+
+    private void readIntoBuffer() throws IOException {
+
+        long filePos = seekPosition;
+
+        bufferDirty = false;
+
+        long subOffset  = filePos % buffer.length;
+        long readLength = fileLength - (filePos - subOffset);
+
+        if (readLength <= 0) {
+            throw new IOException("read beyond end of file");
+        }
+
+        if (readLength > buffer.length) {
+            readLength = buffer.length;
+        }
+
+        fileSeek(filePos - subOffset);
+        file.readFully(buffer, 0, (int) readLength);
+
+        bufferOffset = filePos - subOffset;
+        realPosition = bufferOffset + readLength;
+    }
+
+    public int read() throws IOException {
+
+        if (seekPosition >= fileLength) {
+            return -1;
+        }
+
+        if (bufferDirty || seekPosition < bufferOffset
+                || seekPosition >= bufferOffset + buffer.length) {
+            readIntoBuffer();
+        }
+
+        ba.reset();
+        ba.skip(seekPosition - bufferOffset);
+
+        int val = ba.read();
+
+        seekPosition++;
+
+        return val;
+    }
+
+    public long readLong() throws IOException {
+
+        long hi = readInt();
+        long lo = readInt();
+
+        return (hi << 32) + (lo & 0xffffffffL);
+    }
+
+    public int readInt() throws IOException {
+
+        if (bufferDirty || seekPosition < bufferOffset
+                || seekPosition >= bufferOffset + buffer.length) {
+            readIntoBuffer();
+        }
+
+        ba.reset();
+        ba.skip(seekPosition - bufferOffset);
+
+        int val = ba.readInt();
+
+        seekPosition += 4;
+
+        return val;
+    }
+
+    public void read(byte[] b, int offset, int length) throws IOException {
+
+        if (bufferDirty || seekPosition < bufferOffset
+                || seekPosition >= bufferOffset + buffer.length) {
+            readIntoBuffer();
+        }
+
+        ba.reset();
+        ba.skip(seekPosition - bufferOffset);
+
+        int bytesRead = ba.read(b, offset, length);
+
+        seekPosition += bytesRead;
+
+        if (bytesRead < length) {
+            if (seekPosition != realPosition) {
+                fileSeek(seekPosition);
+            }
+
+            file.readFully(b, offset + bytesRead, length - bytesRead);
+
+            seekPosition += (length - bytesRead);
+            realPosition = seekPosition;
+        }
+    }
+
+    public void write(byte[] b, int off, int len) throws IOException {}
+
+    public void writeInt(int i) throws IOException {}
+
+    public void writeLong(long i) throws IOException {}
+
+    public void close() throws IOException {
+        file.close();
+    }
+
+    public boolean isReadOnly() {
+        return true;
+    }
+
+    public boolean wasNio() {
+        return false;
+    }
+
+    private long getLength() throws IOException {
+
+        int count = 0;
+
+        resetStream();
+
+        while (true) {
+            if (file.read() < 1) {
+                break;
+            }
+
+            count++;
+        }
+
+        return count;
+    }
+
+    private void resetStream() throws IOException {
+
+        if (file != null) {
+            file.close();
+        }
+
+        InputStream fis;
+
+        try {
+            fis = getClass().getResourceAsStream(fileName);
+
+            if (fis == null) {
+                fis = Thread.currentThread().getContextClassLoader()
+                    .getResourceAsStream(fileName);
+            }
+        } catch (Throwable t) {
+            throw Error.error(ErrorCode.DATABASE_NOT_EXISTS, t);
+        }
+
+        file = new DataInputStream(fis);
+    }
+
+    private void fileSeek(long position) throws IOException {
+
+        long skipPosition = realPosition;
+
+        if (position < skipPosition) {
+            resetStream();
+
+            skipPosition = 0;
+        }
+
+        while (position > skipPosition) {
+            skipPosition += file.skip(position - skipPosition);
+        }
+    }
+
+    public boolean canAccess(int length) {
+        return false;
+    }
+
+    public boolean canSeek(long position) {
+        return false;
+    }
+
+    public Database getDatabase() {
+        return null;
+    }
+
+    public void synch() {}
+}
diff --git a/src/org/hsqldb/persist/ScaledRAFileNIO.java b/src/org/hsqldb/persist/ScaledRAFileNIO.java
new file mode 100644
index 0000000..ca53d7e
--- /dev/null
+++ b/src/org/hsqldb/persist/ScaledRAFileNIO.java
@@ -0,0 +1,451 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+
+import org.hsqldb.Database;
+import org.hsqldb.error.Error;
+
+/**
+ * New NIO version of ScaledRAFile. This class is used only for storing a CACHED
+ * TABLE .data file and cannot be used for TEXT TABLE source files.
+ *
+ * Due to various issues with java.nio classes, this class will use a mapped
+ * channel of fixed size. After reaching this size, the file and channel are
+ * closed.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version  1.9.0
+ * @since 1.8.0.5
+ */
+final class ScaledRAFileNIO implements ScaledRAInterface {
+
+    private final Database   database;
+    private final boolean    readOnly;
+    private final long       bufferLength;
+    private RandomAccessFile file;
+    private MappedByteBuffer buffer;
+    private FileChannel      channel;
+    private boolean          bufferModified;
+
+    // We are using persist.Logger-instance-specific FrameworkLogger
+    // because it is Database-instance specific.
+    // If add any static level logging, should instantiate a standard,
+    // context-agnostic FrameworkLogger for that purpose.
+    private final static String JVM_ERROR = "JVM threw unsupported Exception";
+
+    ScaledRAFileNIO(Database database, String name, boolean readOnly,
+                    int bufferLength) throws Throwable {
+
+        this.database = database;
+
+        long fileLength;
+
+        if (bufferLength < 1 << 18) {
+            bufferLength = 1 << 18;
+        }
+
+        try {
+            file = new RandomAccessFile(name, readOnly ? "r"
+                                                       : "rw");
+        } catch (Throwable e) {
+            throw e;
+        }
+
+        try {
+            fileLength = file.length();
+        } catch (Throwable e) {
+            file.close();
+
+            throw e;
+        }
+
+        if (fileLength > ScaledRAFile.MAX_NIO_LENGTH) {
+            file.close();
+
+            throw new IOException("length exceeds nio limit");
+        }
+
+        if (bufferLength < fileLength) {
+            bufferLength = (int) fileLength;
+        }
+
+        bufferLength = newNIOBufferSize(bufferLength);
+
+        if (readOnly) {
+            bufferLength = (int) fileLength;
+        }
+
+        if (fileLength < bufferLength) {
+            try {
+                file.seek(bufferLength - 1);
+                file.writeByte(0);
+                file.getFD().sync();
+                file.close();
+
+                file = new RandomAccessFile(name, readOnly ? "r"
+                                                           : "rw");
+            } catch (Throwable e) {
+                file.close();
+
+                throw e;
+            }
+        }
+
+        this.readOnly     = readOnly;
+        this.bufferLength = bufferLength;
+        this.channel      = file.getChannel();
+
+        try {
+            buffer = channel.map(readOnly ? FileChannel.MapMode.READ_ONLY
+                                          : FileChannel.MapMode.READ_WRITE, 0,
+                                          bufferLength);
+
+            Error.printSystemOut("NIO file instance created. mode: "
+                                 + readOnly);
+
+            if (!readOnly) {
+                long tempSize = bufferLength - fileLength;
+
+                if (tempSize > 1 << 18) {
+                    tempSize = 1 << 18;
+                }
+
+                byte[] temp = new byte[(int) tempSize];
+
+                try {
+                    long pos = fileLength;
+
+                    for (; pos < bufferLength - tempSize; pos += tempSize) {
+                        buffer.position((int) pos);
+                        buffer.put(temp, 0, temp.length);
+                    }
+
+                    buffer.position((int) pos);
+                    buffer.put(temp, 0, (int) (bufferLength - pos));
+                    buffer.force();
+                } catch (Throwable t) {
+                    database.logger.logWarningEvent(JVM_ERROR + " "
+                                                    + "length: "
+                                                    + bufferLength, t);
+                }
+
+                buffer.position(0);
+            }
+        } catch (Throwable e) {
+            Error.printSystemOut("NIO constructor failed:  " + bufferLength);
+
+            buffer  = null;
+            channel = null;
+
+            file.close();
+
+            // System.gc();
+            throw e;
+        }
+    }
+
+    public long length() throws IOException {
+
+        try {
+            return file.length();
+        } catch (IOException e) {
+            database.logger.logWarningEvent("nio", e);
+
+            throw e;
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public void seek(long newPos) throws IOException {
+
+        try {
+            buffer.position((int) newPos);
+        } catch (IllegalArgumentException e) {
+            database.logger.logWarningEvent("nio", e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public long getFilePointer() throws IOException {
+
+        try {
+            return buffer.position();
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public int read() throws IOException {
+
+        try {
+            return buffer.get();
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public void read(byte[] b, int offset, int length) throws IOException {
+
+        try {
+            buffer.get(b, offset, length);
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public int readInt() throws IOException {
+
+        try {
+            return buffer.getInt();
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public long readLong() throws IOException {
+
+        try {
+            return buffer.getLong();
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public void write(byte[] b, int offset, int len) throws IOException {
+
+        try {
+            bufferModified = true;
+
+            buffer.put(b, offset, len);
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public void writeInt(int i) throws IOException {
+
+        try {
+            bufferModified = true;
+
+            buffer.putInt(i);
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public void writeLong(long i) throws IOException {
+
+        try {
+            bufferModified = true;
+
+            buffer.putLong(i);
+        } catch (Throwable e) {
+            database.logger.logWarningEvent(JVM_ERROR, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public void close() throws IOException {
+
+        try {
+            Error.printSystemOut("NIO close() start - fileLength = "
+                                 + bufferLength);
+
+            if (buffer != null && bufferModified) {
+                try {
+                    buffer.force();
+                } catch (Throwable t) {
+                    try {
+                        buffer.force();
+                    } catch (Throwable t1) {
+                        database.logger.logWarningEvent(JVM_ERROR + " "
+                                                        + "length: "
+                                                        + bufferLength, t);
+                    }
+                }
+            }
+
+            buffer  = null;
+            channel = null;
+
+            file.close();
+
+            // System.gc();
+        } catch (Throwable e) {
+            database.logger.logWarningEvent("length: " + bufferLength, e);
+
+            IOException io = new IOException(e.getMessage());
+
+            try {
+                io.initCause(e);
+            } catch (Throwable e1) {}
+
+            throw io;
+        }
+    }
+
+    public boolean isReadOnly() {
+        return readOnly;
+    }
+
+    public boolean wasNio() {
+        return true;
+    }
+
+    public boolean canAccess(int length) {
+        return buffer.position() + length <= bufferLength;
+    }
+
+    public boolean canSeek(long position) {
+        return position <= bufferLength;
+    }
+
+    public Database getDatabase() {
+        return null;
+    }
+
+    public void synch() {
+
+        try {
+            buffer.force();
+        } catch (Throwable t) {}
+    }
+
+    static int newNIOBufferSize(int newSize) {
+
+        int bufSize = 0;
+
+        for (int scale = 20; scale < 30; scale++) {
+            bufSize = 1 << scale;
+
+            if (bufSize >= newSize) {
+                break;
+            }
+        }
+
+        return bufSize;
+    }
+}
diff --git a/src/org/hsqldb/persist/ScaledRAFileSimple.java b/src/org/hsqldb/persist/ScaledRAFileSimple.java
new file mode 100644
index 0000000..4cc0179
--- /dev/null
+++ b/src/org/hsqldb/persist/ScaledRAFileSimple.java
@@ -0,0 +1,136 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.hsqldb.Database;
+
+/**
+ * This class is a simple wapper for a random access file such as used
+ * for backup and lobs.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version  1.9.0
+ * @since  1.9.0
+ */
+final class ScaledRAFileSimple implements ScaledRAInterface {
+
+    final RandomAccessFile file;
+    final boolean          readOnly;
+
+    ScaledRAFileSimple(String name,
+                       String openMode)
+                       throws FileNotFoundException, IOException {
+        this.file = new RandomAccessFile(name, openMode);
+        readOnly  = openMode.equals("r");
+    }
+
+    public long length() throws IOException {
+        return file.length();
+    }
+
+    /**
+     * Some JVM's do not allow seek beyond end of file, so zeros are written
+     * first in that case. Reported by bohgammer@users in Open Disucssion
+     * Forum.
+     */
+    public void seek(long position) throws IOException {
+        file.seek(position);
+    }
+
+    public long getFilePointer() throws IOException {
+        return file.getFilePointer();
+    }
+
+    public int read() throws IOException {
+        return file.read();
+    }
+
+    public long readLong() throws IOException {
+        return file.readLong();
+    }
+
+    public int readInt() throws IOException {
+        return file.readInt();
+    }
+
+    public void read(byte[] b, int offset, int length) throws IOException {
+        file.readFully(b, offset, length);
+    }
+
+    public void write(byte[] b, int off, int len) throws IOException {
+        file.write(b, off, len);
+    }
+
+    public void writeInt(int i) throws IOException {
+        file.writeInt(i);
+    }
+
+    public void writeLong(long i) throws IOException {
+        file.writeLong(i);
+    }
+
+    public void close() throws IOException {
+        file.close();
+    }
+
+    public boolean isReadOnly() {
+        return readOnly;
+    }
+
+    public boolean wasNio() {
+        return false;
+    }
+
+    public boolean canAccess(int length) {
+        return true;
+    }
+
+    public boolean canSeek(long position) {
+        return true;
+    }
+
+    public Database getDatabase() {
+        return null;
+    }
+
+    public void synch() {
+
+        try {
+            file.getFD().sync();
+        } catch (IOException e) {}
+    }
+}
diff --git a/src/org/hsqldb/persist/ScaledRAInterface.java b/src/org/hsqldb/persist/ScaledRAInterface.java
new file mode 100644
index 0000000..d00a870
--- /dev/null
+++ b/src/org/hsqldb/persist/ScaledRAInterface.java
@@ -0,0 +1,44 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import org.hsqldb.Database;
+import org.hsqldb.lib.Storage;
+
+public interface ScaledRAInterface extends Storage {
+
+    boolean canAccess(int length);
+
+    boolean canSeek(long position);
+
+    Database getDatabase();
+}
diff --git a/src/org/hsqldb/persist/ScriptRunner.java b/src/org/hsqldb/persist/ScriptRunner.java
new file mode 100644
index 0000000..12d18cd
--- /dev/null
+++ b/src/org/hsqldb/persist/ScriptRunner.java
@@ -0,0 +1,212 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.EOFException;
+
+import org.hsqldb.Database;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.Session;
+import org.hsqldb.Statement;
+import org.hsqldb.StatementDML;
+import org.hsqldb.StatementTypes;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.StopWatch;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.scriptio.ScriptReaderBase;
+import org.hsqldb.scriptio.ScriptReaderDecode;
+import org.hsqldb.scriptio.ScriptReaderText;
+
+/**
+ * Restores the state of a Database instance from an SQL log file. <p>
+ *
+ * If there is an error, processing stops at that line and the message is
+ * logged to the application log. If memory runs out, an exception is thrown.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class ScriptRunner {
+
+    /**
+     *  This is used to read the *.log file and manage any necessary
+     *  transaction rollback.
+     */
+    public static void runScript(Database database, String logFilename) {
+
+        IntKeyHashMap sessionMap = new IntKeyHashMap();
+        Session       current    = null;
+        int           currentId  = 0;
+
+        database.setReferentialIntegrity(false);
+
+        ScriptReaderBase scr = null;
+        String           statement;
+        int              statementType;
+        Statement dummy = new StatementDML(StatementTypes.UPDATE_CURSOR,
+                                           StatementTypes.X_SQL_DATA_CHANGE,
+                                           null);
+
+        try {
+            StopWatch sw     = new StopWatch();
+            Crypto    crypto = database.logger.getCrypto();
+
+            if (crypto == null) {
+                scr = new ScriptReaderText(database, logFilename);
+            } else {
+                scr = new ScriptReaderDecode(database, logFilename, crypto,
+                                             true);
+            }
+
+            while (scr.readLoggedStatement(current)) {
+                int sessionId = scr.getSessionNumber();
+
+                if (current == null || currentId != sessionId) {
+                    currentId = sessionId;
+                    current   = (Session) sessionMap.get(currentId);
+
+                    if (current == null) {
+                        current =
+                            database.getSessionManager().newSession(database,
+                                database.getUserManager().getSysUser(), false,
+                                true, null, 0);
+
+                        sessionMap.put(currentId, current);
+                    }
+                }
+
+                if (current.isClosed()) {
+                    sessionMap.remove(currentId);
+
+                    continue;
+                }
+
+                Result result = null;
+
+                statementType = scr.getStatementType();
+
+                switch (statementType) {
+
+                    case ScriptReaderBase.ANY_STATEMENT :
+                        statement = scr.getLoggedStatement();
+                        result = current.executeDirectStatement(statement,
+                                ResultProperties.defaultPropsValue);
+
+                        if (result != null && result.isError()) {
+                            if (result.getException() != null) {
+                                throw result.getException();
+                            }
+
+                            throw Error.error(result);
+                        }
+                        break;
+
+                    case ScriptReaderBase.COMMIT_STATEMENT :
+                        current.commit(false);
+                        break;
+
+                    case ScriptReaderBase.INSERT_STATEMENT : {
+                        current.sessionContext.currentStatement = dummy;
+
+                        current.beginAction(dummy);
+
+                        Object[] data = scr.getData();
+
+                        scr.getCurrentTable().insertNoCheckFromLog(current,
+                                data);
+                        current.endAction(Result.updateOneResult);
+
+                        break;
+                    }
+                    case ScriptReaderBase.DELETE_STATEMENT : {
+                        current.sessionContext.currentStatement = dummy;
+
+                        current.beginAction(dummy);
+
+                        Object[] data = scr.getData();
+
+                        scr.getCurrentTable().deleteNoCheckFromLog(current,
+                                data);
+                        current.endAction(Result.updateOneResult);
+
+                        break;
+                    }
+                    case ScriptReaderBase.SET_SCHEMA_STATEMENT : {
+                        HsqlName name =
+                            database.schemaManager.findSchemaHsqlName(
+                                scr.getCurrentSchema());
+
+                        current.setCurrentSchemaHsqlName(name);
+
+                        break;
+                    }
+                    case ScriptReaderBase.SESSION_ID : {
+                        break;
+                    }
+                }
+
+                if (current.isClosed()) {
+                    sessionMap.remove(currentId);
+                }
+            }
+        } catch (Throwable e) {
+
+            // catch out-of-memory errors and terminate
+            if (e instanceof EOFException) {
+
+                // end of file - normal end
+            } else if (e instanceof OutOfMemoryError) {
+                database.logger.logSevereEvent("out of memory processing "
+                                               + logFilename + " line: "
+                                               + scr.getLineNumber(), e);
+
+                throw Error.error(ErrorCode.OUT_OF_MEMORY);
+            } else {
+
+                // stop processing on bad script line
+                database.logger.logSevereEvent(logFilename + " line: "
+                                               + scr.getLineNumber(), e);
+            }
+        } finally {
+            if (scr != null) {
+                scr.close();
+            }
+
+            database.getSessionManager().closeAllSessions();
+            database.setReferentialIntegrity(true);
+        }
+    }
+}
diff --git a/src/org/hsqldb/persist/TextCache.java b/src/org/hsqldb/persist/TextCache.java
new file mode 100644
index 0000000..23568b6
--- /dev/null
+++ b/src/org/hsqldb/persist/TextCache.java
@@ -0,0 +1,833 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.persist;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import org.hsqldb.Database;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Table;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.HsqlByteArrayOutputStream;
+import org.hsqldb.rowio.RowInputInterface;
+import org.hsqldb.rowio.RowInputText;
+import org.hsqldb.rowio.RowInputTextQuoted;
+import org.hsqldb.rowio.RowOutputText;
+import org.hsqldb.rowio.RowOutputTextQuoted;
+import org.hsqldb.scriptio.ScriptWriterText;
+import org.hsqldb.store.ObjectCacheHashMap;
+
+// Ito Kazumitsu 20030328 - patch 1.7.2 - character encoding support
+// Dimitri Maziuk - patch for NL in string support
+// sqlbob@users - updated for 1.8.0 to allow new-lines in fields
+// fredt@users - updated for 1.8.0 to allow correct behaviour with transactions
+
+/**
+ * Acts as a buffer manager for a single TEXT table with respect its Row data.<p>
+ *
+ * Handles read/write operations on the table's text format data file using a
+ * compatible pair of org.hsqldb.rowio input/output class instances.
+ *
+ *
+ *  fredt - this used to write rows as soon as they are inserted
+ *  but now this is subject to transaction management.
+ *  A memory buffer contains the rows not yet committed.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class TextCache extends DataFileCache {
+
+    //state of Cache
+    public static final String NL = System.getProperty("line.separator");
+    public String              fs;
+    public String              vs;
+    public String              lvs;
+    public String              stringEncoding;
+    public boolean             isQuoted;
+    public boolean             isAllQuoted;
+    public boolean             ignoreFirst;
+    protected String           header;
+    protected Table            table;
+    private ObjectCacheHashMap uncommittedCache;
+
+    //
+    final static char DOUBLE_QUOTE_CHAR = '\"';
+    final static char BACKSLASH_CHAR    = '\\';
+    final static char LF_CHAR           = '\n';
+    final static char CR_CHAR           = '\r';
+
+    /**
+     *  The source string for a cached table is evaluated and the parameters
+     *  are used to open the source file.<p>
+     *
+     *  Settings are used in this order: (1) settings specified in the
+     *  source string for the table (2) global database settings in
+     *  *.properties file (3) program defaults
+     */
+    TextCache(Table table, String name) {
+
+        super(table.database, name);
+
+        this.table       = table;
+        uncommittedCache = new ObjectCacheHashMap(5);
+    }
+
+    protected void initParams(Database database, String baseFileName) {
+
+        this.dataFileName = dataFileName;
+        this.database     = database;
+        fa                = FileUtil.getFileUtil();
+
+        HsqlProperties tableprops =
+            HsqlProperties.delimitedArgPairsToProps(baseFileName, "=", ";",
+                "textdb");
+        HsqlDatabaseProperties dbProps = database.getProperties();
+
+        //-- Get file name
+        switch (tableprops.errorCodes.length) {
+
+            case 0 :
+                throw Error.error(ErrorCode.X_S0501);
+            case 1 :
+
+                // source file name is the only key without a value
+                this.dataFileName = tableprops.errorKeys[0].trim();
+                break;
+
+            default :
+                throw Error.error(ErrorCode.X_S0502);
+        }
+
+        //-- Get separators: from database properties, then from table properties
+        fs  = dbProps.getStringProperty(HsqlDatabaseProperties.textdb_fs);
+        fs  = tableprops.getProperty(HsqlDatabaseProperties.textdb_fs, fs);
+        vs  = dbProps.getStringProperty(HsqlDatabaseProperties.textdb_vs);
+        vs  = tableprops.getProperty(HsqlDatabaseProperties.textdb_vs, vs);
+        lvs = dbProps.getStringProperty(HsqlDatabaseProperties.textdb_lvs);
+        lvs = tableprops.getProperty(HsqlDatabaseProperties.textdb_lvs, lvs);
+
+        if (vs == null) {
+            vs = fs;
+        }
+
+        if (lvs == null) {
+            lvs = fs;
+        }
+
+        fs  = translateSep(fs);
+        vs  = translateSep(vs);
+        lvs = translateSep(lvs);
+
+        if (fs.length() == 0 || vs.length() == 0 || lvs.length() == 0) {
+            throw Error.error(ErrorCode.X_S0503);
+        }
+
+        //-- Get booleans
+        ignoreFirst =
+            dbProps.isPropertyTrue(HsqlDatabaseProperties.textdb_ignore_first);
+        ignoreFirst = tableprops.isPropertyTrue(
+            HsqlDatabaseProperties.textdb_ignore_first, ignoreFirst);
+        isQuoted =
+            dbProps.isPropertyTrue(HsqlDatabaseProperties.textdb_quoted);
+        isQuoted =
+            tableprops.isPropertyTrue(HsqlDatabaseProperties.textdb_quoted,
+                                      isQuoted);
+        isAllQuoted =
+            dbProps.isPropertyTrue(HsqlDatabaseProperties.textdb_all_quoted);
+        isAllQuoted =
+            tableprops.isPropertyTrue(HsqlDatabaseProperties.textdb_all_quoted,
+                                      isAllQuoted);
+        stringEncoding =
+            dbProps.getStringProperty(HsqlDatabaseProperties.textdb_encoding);
+        stringEncoding =
+            tableprops.getProperty(HsqlDatabaseProperties.textdb_encoding,
+                                   stringEncoding);
+
+        //-- Get size and scale
+        int cacheScale = tableprops.getIntegerProperty(
+            HsqlDatabaseProperties.textdb_cache_scale,
+            dbProps.getIntegerProperty(
+                HsqlDatabaseProperties.textdb_cache_scale));
+        int cacheSizeScale = tableprops.getIntegerProperty(
+            HsqlDatabaseProperties.textdb_cache_size_scale,
+            dbProps.getIntegerProperty(
+                HsqlDatabaseProperties.textdb_cache_size_scale));
+        int lookupTableLength = 1 << cacheScale;
+        int avgRowBytes       = 1 << cacheSizeScale;
+
+        maxCacheRows     = lookupTableLength * 3;
+        maxCacheBytes    = maxCacheRows * avgRowBytes;
+        maxDataFileSize  = Integer.MAX_VALUE;
+        cachedRowPadding = 1;
+        cacheFileScale   = 1;
+    }
+
+    protected void initBuffers() {
+
+        if (isQuoted || isAllQuoted) {
+            rowIn = new RowInputTextQuoted(fs, vs, lvs, isAllQuoted);
+            rowOut = new RowOutputTextQuoted(fs, vs, lvs, isAllQuoted,
+                                             stringEncoding);
+        } else {
+            rowIn  = new RowInputText(fs, vs, lvs, false);
+            rowOut = new RowOutputText(fs, vs, lvs, false, stringEncoding);
+        }
+    }
+
+    private static String translateSep(String sep) {
+        return translateSep(sep, false);
+    }
+
+    /**
+     * Translates the escaped characters in a separator string and returns
+     * the non-escaped string.
+     */
+    private static String translateSep(String sep, boolean isProperty) {
+
+        if (sep == null) {
+            return null;
+        }
+
+        int next = sep.indexOf(BACKSLASH_CHAR);
+
+        if (next != -1) {
+            int          start    = 0;
+            char[]       sepArray = sep.toCharArray();
+            char         ch       = 0;
+            int          len      = sep.length();
+            StringBuffer sb       = new StringBuffer(len);
+
+            do {
+                sb.append(sepArray, start, next - start);
+
+                start = ++next;
+
+                if (next >= len) {
+                    sb.append(BACKSLASH_CHAR);
+
+                    break;
+                }
+
+                if (!isProperty) {
+                    ch = sepArray[next];
+                }
+
+                if (ch == 'n') {
+                    sb.append(LF_CHAR);
+
+                    start++;
+                } else if (ch == 'r') {
+                    sb.append(CR_CHAR);
+
+                    start++;
+                } else if (ch == 't') {
+                    sb.append('\t');
+
+                    start++;
+                } else if (ch == BACKSLASH_CHAR) {
+                    sb.append(BACKSLASH_CHAR);
+
+                    start++;
+                } else if (ch == 'u') {
+                    start++;
+
+                    sb.append(
+                        (char) Integer.parseInt(
+                            sep.substring(start, start + 4), 16));
+
+                    start += 4;
+                } else if (sep.startsWith("semi", next)) {
+                    sb.append(';');
+
+                    start += 4;
+                } else if (sep.startsWith("space", next)) {
+                    sb.append(' ');
+
+                    start += 5;
+                } else if (sep.startsWith("quote", next)) {
+                    sb.append(DOUBLE_QUOTE_CHAR);
+
+                    start += 5;
+                } else if (sep.startsWith("apos", next)) {
+                    sb.append('\'');
+
+                    start += 4;
+                } else {
+                    sb.append(BACKSLASH_CHAR);
+                    sb.append(sepArray[next]);
+
+                    start++;
+                }
+            } while ((next = sep.indexOf(BACKSLASH_CHAR, start)) != -1);
+
+            sb.append(sepArray, start, len - start);
+
+            sep = sb.toString();
+        }
+
+        return sep;
+    }
+
+    /**
+     *  Opens a data source file.
+     */
+    public void open(boolean readonly) {
+
+        fileFreePosition = 0;
+
+        try {
+            int type = database.getType() == DatabaseURL.S_RES
+                       ? ScaledRAFile.DATA_FILE_JAR
+                       : ScaledRAFile.DATA_FILE_RAF;
+
+            dataFile = ScaledRAFile.newScaledRAFile(database, dataFileName,
+                    readonly, type);
+            fileFreePosition = dataFile.length();
+
+            if (fileFreePosition > Integer.MAX_VALUE) {
+                throw Error.error(ErrorCode.DATA_FILE_IS_FULL);
+            }
+
+            initBuffers();
+        } catch (Throwable t) {
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_TextCache_openning_file_error,
+                              new Object[] {
+                t.getMessage(), dataFileName
+            });
+        }
+
+        cacheReadonly = readonly;
+    }
+
+    void reopen() {
+        open(cacheReadonly);
+    }
+
+    /**
+     *  Writes newly created rows to disk. In the current implentation,
+     *  such rows have already been saved, so this method just removes a
+     *  source file that has no rows.
+     */
+    public synchronized void close(boolean write) {
+
+        if (dataFile == null) {
+            return;
+        }
+
+        try {
+            cache.saveAll();
+
+            boolean empty = (dataFile.length() <= NL.length());
+
+            dataFile.close();
+
+            dataFile = null;
+
+            if (empty && !cacheReadonly) {
+                FileUtil.getFileUtil().delete(dataFileName);
+            }
+
+            uncommittedCache.clear();
+        } catch (Throwable t) {
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_TextCache_closing_file_error,
+                              new Object[] {
+                t.getMessage(), dataFileName
+            });
+        }
+    }
+
+    /**
+     * Closes the source file and deletes it if it is not read-only.
+     */
+    void purge() {
+
+        uncommittedCache.clear();
+
+        try {
+            if (cacheReadonly) {
+                close(false);
+            } else {
+                if (dataFile != null) {
+                    dataFile.close();
+
+                    dataFile = null;
+                }
+
+                FileUtil.getFileUtil().delete(dataFileName);
+            }
+        } catch (Throwable t) {
+            throw Error.error(t, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_TextCache_purging_file_error,
+                              new Object[] {
+                t.getMessage(), dataFileName
+            });
+        }
+    }
+
+    /**
+     *
+     */
+    public synchronized void remove(int pos, PersistentStore store) {
+
+        CachedObject row = (CachedObject) uncommittedCache.remove(pos);
+
+        if (row != null) {
+            return;
+        }
+
+        row = cache.release(pos);
+    }
+
+    public synchronized void removePersistence(int pos,
+            PersistentStore store) {
+
+        CachedObject row = (CachedObject) uncommittedCache.remove(pos);
+
+        if (row == null) {
+            row = get(pos, store, false);
+        }
+
+        clearRowImage(row);
+    }
+
+    private void clearRowImage(CachedObject row) {
+
+        try {
+            int length = row.getStorageSize()
+                         - ScriptWriterText.BYTES_LINE_SEP.length;
+
+            rowOut.reset();
+
+            HsqlByteArrayOutputStream out = rowOut.getOutputStream();
+
+            out.fill(' ', length);
+            out.write(ScriptWriterText.BYTES_LINE_SEP);
+            dataFile.seek(row.getPos());
+            dataFile.write(out.getBuffer(), 0, out.size());
+        } catch (IOException e) {
+            throw Error.runtimeError(ErrorCode.U_S0500, e.getMessage());
+        }
+    }
+
+    protected synchronized RowInputInterface readObject(int pos) {
+
+        try {
+            ByteArray buffer   = new ByteArray(80);
+            boolean   complete = false;
+            boolean   wasCR    = false;
+            int       c;
+            boolean   hasQuote  = false;
+            boolean   wasNormal = false;
+
+            pos = findNextUsedLinePos(pos);
+
+            if (pos == -1) {
+                return null;
+            }
+
+            dataFile.seek(pos);
+
+            while (!complete) {
+                wasNormal = false;
+                c         = dataFile.read();
+
+                if (c == -1) {
+                    if (buffer.length() == 0) {
+                        return null;
+                    }
+
+                    complete = true;
+
+                    if (wasCR) {
+                        break;
+                    }
+
+                    if (!cacheReadonly) {
+                        dataFile.write(ScriptWriterText.BYTES_LINE_SEP, 0,
+                                       ScriptWriterText.BYTES_LINE_SEP.length);
+                    }
+
+                    break;
+                }
+
+                switch (c) {
+
+                    case DOUBLE_QUOTE_CHAR :
+                        wasNormal = true;
+                        complete  = wasCR;
+                        wasCR     = false;
+
+                        if (isQuoted) {
+                            hasQuote = !hasQuote;
+                        }
+                        break;
+
+                    case CR_CHAR :
+                        wasCR = !hasQuote;
+                        break;
+
+                    case LF_CHAR :
+                        complete = !hasQuote;
+                        break;
+
+                    default :
+                        wasNormal = true;
+                        complete  = wasCR;
+                        wasCR     = false;
+                }
+
+                buffer.append(c);
+            }
+
+            if (complete) {
+                int length = (int) dataFile.getFilePointer() - pos;
+
+                if (wasNormal) {
+                    length--;
+                }
+
+                ((RowInputText) rowIn).setSource(buffer.toString(), pos,
+                                                 length);
+
+                return rowIn;
+            }
+
+            return null;
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.TEXT_FILE_IO, e);
+        }
+    }
+
+    public int readHeaderLine() {
+
+        boolean   complete  = false;
+        boolean   wasCR     = false;
+        boolean   wasNormal = false;
+        ByteArray buffer    = new ByteArray(80);
+
+        while (!complete) {
+            wasNormal = false;
+
+            int c;
+
+            try {
+                c = dataFile.read();
+
+                if (c == -1) {
+                    if (buffer.length() == 0) {
+                        return 0;
+                    }
+
+                    complete = true;
+
+                    if (!cacheReadonly) {
+                        dataFile.write(ScriptWriterText.BYTES_LINE_SEP, 0,
+                                       ScriptWriterText.BYTES_LINE_SEP.length);
+                    }
+
+                    break;
+                }
+            } catch (IOException e) {
+                throw Error.error(ErrorCode.TEXT_FILE);
+            }
+
+            switch (c) {
+
+                case CR_CHAR :
+                    wasCR = true;
+                    break;
+
+                case LF_CHAR :
+                    complete = true;
+                    break;
+
+                default :
+                    wasNormal = true;
+                    complete  = wasCR;
+                    wasCR     = false;
+            }
+
+            if (wasCR || complete) {
+                continue;
+            }
+
+            buffer.append(c);
+        }
+
+        header = buffer.toString();
+
+        try {
+            int length = (int) dataFile.getFilePointer();
+
+            if (wasNormal) {
+                length--;
+            }
+
+            return length;
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.TEXT_FILE);
+        }
+    }
+
+    // fredt - new method
+
+    /**
+     * Searches from file pointer, pos, and finds the beginning of the first
+     * line that contains any non-space character. Increments the row counter
+     * when a blank line is skipped.
+     *
+     * If none found return -1
+     */
+    int findNextUsedLinePos(int pos) {
+
+        try {
+            int     firstPos   = pos;
+            int     currentPos = pos;
+            boolean wasCR      = false;
+
+            dataFile.seek(pos);
+
+            while (true) {
+                int c = dataFile.read();
+
+                currentPos++;
+
+                switch (c) {
+
+                    case CR_CHAR :
+                        wasCR = true;
+                        break;
+
+                    case LF_CHAR :
+                        wasCR = false;
+
+                        ((RowInputText) rowIn).skippedLine();
+
+                        firstPos = currentPos;
+                        break;
+
+                    case ' ' :
+                        if (wasCR) {
+                            wasCR = false;
+
+                            ((RowInputText) rowIn).skippedLine();
+                        }
+                        break;
+
+                    case -1 :
+                        return -1;
+
+                    default :
+                        return firstPos;
+                }
+            }
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.TEXT_FILE_IO, e);
+        }
+    }
+
+    public synchronized void add(CachedObject object) {
+
+        setFilePos(object);
+        uncommittedCache.put(object.getPos(), object);
+        clearRowImage(object);
+    }
+
+    public CachedObject get(CachedObject object, PersistentStore store,
+                            boolean keep) {
+
+        if (object == null) {
+            return null;
+        }
+
+        CachedObject o = (CachedObject) uncommittedCache.get(object.getPos());
+
+        if (o == null) {
+            o = super.get(object.getPos(), store, keep);
+        }
+
+        return o;
+    }
+
+    public synchronized CachedObject get(int i, PersistentStore store,
+                                         boolean keep) {
+
+        if (i < 0) {
+            return null;
+        }
+
+        CachedObject o = (CachedObject) uncommittedCache.get(i);
+
+        if (o == null) {
+            o = super.get(i, store, keep);
+        }
+
+/*
+        if (o == null) {
+            o = super.get(i, store, keep);
+        }
+*/
+        return o;
+    }
+
+    /**
+     * this is no longer called- fredt
+     */
+    protected synchronized void saveRows(CachedObject[] rows, int offset,
+                                         int count) {
+
+        if (count == 0) {
+            return;
+        }
+
+        for (int i = offset; i < offset + count; i++) {
+            CachedObject r = rows[i];
+
+            uncommittedCache.put(r.getPos(), r);
+
+            rows[i] = null;
+        }
+    }
+
+    /**
+     * The row is always in uncommittedCache.
+     * Saves the row as normal and removes it
+     */
+    public synchronized void saveRow(CachedObject row) {
+
+        super.saveRow(row);
+        uncommittedCache.remove(row.getPos());
+        cache.put(row.getPos(), row);
+    }
+
+    public String getHeader() {
+        return header;
+    }
+
+    public void setHeader(String header) {
+
+        if (ignoreFirst && fileFreePosition == 0) {
+            try {
+                writeHeader(header);
+
+                this.header = header;
+            } catch (HsqlException e) {
+                throw new HsqlException(
+                    e, Error.getMessage(ErrorCode.GENERAL_IO_ERROR),
+                    ErrorCode.GENERAL_IO_ERROR);
+            }
+
+            return;
+        }
+
+        throw Error.error(ErrorCode.TEXT_TABLE_HEADER);
+    }
+
+    private void writeHeader(String header) {
+
+        try {
+            byte[] buf       = null;
+            String firstLine = header + NL;
+
+            try {
+                buf = firstLine.getBytes(stringEncoding);
+            } catch (UnsupportedEncodingException e) {
+                buf = firstLine.getBytes();
+            }
+
+            dataFile.write(buf, 0, buf.length);
+
+            fileFreePosition = buf.length;
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.TEXT_FILE_IO, e);
+        }
+    }
+
+    private class ByteArray {
+
+        private byte[] buffer;
+        private int    buflen;
+
+        public ByteArray(int n) {
+            buffer = new byte[n];
+            buflen = 0;
+        }
+
+        public void append(int c) {
+
+            if (buflen >= buffer.length) {
+                byte[] newbuf = new byte[buflen + 80];
+
+                System.arraycopy(buffer, 0, newbuf, 0, buflen);
+
+                buffer = newbuf;
+            }
+
+            buffer[buflen] = (byte) c;
+
+            buflen++;
+        }
+
+        public int length() {
+            return buflen;
+        }
+
+        public void setLength(int l) {
+            buflen = l;
+        }
+
+        public String toString() {
+
+            try {
+                return new String(buffer, 0, buflen, stringEncoding);
+            } catch (UnsupportedEncodingException e) {
+                return new String(buffer, 0, buflen);
+            }
+        }
+    }
+
+    public int getLineNumber() {
+        return ((RowInputText) rowIn).getLineNumber();
+    }
+
+    protected void setFileModified() {
+        fileModified = true;
+    }
+}
diff --git a/src/org/hsqldb/resources/BundleHandler.java b/src/org/hsqldb/resources/BundleHandler.java
new file mode 100644
index 0000000..73b7090
--- /dev/null
+++ b/src/org/hsqldb/resources/BundleHandler.java
@@ -0,0 +1,246 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.resources;
+
+import java.lang.reflect.Method;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HsqlArrayList;
+
+/**
+ * A ResourceBundle helper class. <p>
+ *
+ * Allows clients to get/set locale and get at localized resource bundle
+ * content in a resource path independent manner, without having to worry
+ * about handling exception states or deal directly with ResourceBundle
+ * object instances. Instead, clients recieve numeric handles to the
+ * underlying objects.  Rather than causing exception states, missing or
+ * inaccessible resources and underlying MissingResource and NullPointer
+ * exceptions result in null return values when attempting to retrieve a
+ * resource. <p>
+ *
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public final class BundleHandler {
+
+    /** Used to synchronize access */
+    private static final Object mutex = new Object();
+
+    /** The Locale used internally to fetch resource bundles. */
+    private static Locale locale = Locale.getDefault();
+
+    /** Map:  Integer object handle => <code>ResourceBundle</code> object. */
+    private static HashMap bundleHandleMap = new HashMap();
+
+    /** List whose elements are <code>ResourceBundle</code> objects */
+    private static HsqlArrayList bundleList = new HsqlArrayList();
+
+    /**
+     * The resource path prefix of the <code>ResourceBundle</code> objects
+     * handled by this class.
+     */
+    private static final String prefix = "org/hsqldb/resources/";
+
+    /** JDK 1.1 compliance */
+    private static final Method newGetBundleMethod = getNewGetBundleMethod();
+
+    /** Pure utility class: external construction disabled. */
+    private BundleHandler() {}
+
+    /**
+     * Getter for property locale. <p>
+     *
+     * @return Value of property locale.
+     */
+    public static Locale getLocale() {
+
+        synchronized (mutex) {
+            return locale;
+        }
+    }
+
+    /**
+     * Setter for property locale. <p>
+     *
+     * @param l the new locale
+     * @throws IllegalArgumentException when the new locale is null
+     */
+    public static void setLocale(Locale l) throws IllegalArgumentException {
+
+        synchronized (mutex) {
+            if (l == null) {
+                throw new IllegalArgumentException("null locale");
+            }
+
+            locale = l;
+        }
+    }
+
+    /**
+     * Retrieves an <code>int</code> handle to the <code>ResourceBundle</code>
+     * object corresponding to the specified name and current
+     * <code>Locale</code>, using the specified <code>ClassLoader</code>. <p>
+     *
+     * @return <code>int</code> handle to the <code>ResourceBundle</code>
+     *        object corresponding to the specified name and
+     *        current <code>Locale</code>, or -1 if no such bundle
+     *        can be found
+     * @param cl The ClassLoader to use in the search
+     * @param name of the desired bundle
+     */
+    public static int getBundleHandle(String name, ClassLoader cl) {
+
+        Integer        bundleHandle;
+        ResourceBundle bundle;
+        String         bundleName;
+        String         bundleKey;
+
+        bundleName = prefix + name;
+
+        synchronized (mutex) {
+            bundleKey    = locale.toString() + bundleName;
+            bundleHandle = (Integer) bundleHandleMap.get(bundleKey);
+
+            if (bundleHandle == null) {
+                bundle = getBundle(bundleName, locale, cl);
+
+                bundleList.add(bundle);
+
+                bundleHandle = new Integer(bundleList.size() - 1);
+
+                bundleHandleMap.put(bundleKey, bundleHandle);
+            }
+        }
+
+        return bundleHandle == null ? -1
+                                    : bundleHandle.intValue();
+    }
+
+    /**
+     * Retrieves, from the <code>ResourceBundle</code> object corresponding
+     * to the specified handle, the <code>String</code> value corresponding
+     * to the specified key.  <code>null</code> is retrieved if either there
+     *  is no <code>ResourceBundle</code> object for the handle or there is no
+     * <code>String</code> value for the specified key. <p>
+     *
+     * @param handle an <code>int</code> handle to a
+     *      <code>ResourceBundle</code> object
+     * @param key A <code>String</code> key to a <code>String</code> value
+     * @return The String value correspoding to the specified handle and key.
+     */
+    public static String getString(int handle, String key) {
+
+        ResourceBundle bundle;
+        String         s;
+
+        synchronized (mutex) {
+            if (handle < 0 || handle >= bundleList.size() || key == null) {
+                bundle = null;
+            } else {
+                bundle = (ResourceBundle) bundleList.get(handle);
+            }
+        }
+
+        if (bundle == null) {
+            s = null;
+        } else {
+            try {
+                s = bundle.getString(key);
+            } catch (Exception e) {
+                s = null;
+            }
+        }
+
+        return s;
+    }
+
+    /**
+     * One-shot initialization of JDK 1.2+ ResourceBundle.getBundle() method
+     * having ClassLoader in the signature.
+     */
+    private static Method getNewGetBundleMethod() {
+
+        Class   clazz;
+        Class[] args;
+
+        clazz = ResourceBundle.class;
+        args  = new Class[] {
+            String.class, Locale.class, ClassLoader.class
+        };
+
+        try {
+            return clazz.getMethod("getBundle", args);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /**
+     * Retrieves a resource bundle using the specified base name, locale, and
+     * class loader. This is a JDK 1.1 compliant substitution for the
+     * ResourceBundle method with the same name and signature. If there
+     * is a problem using the JDK 1.2 functionality (the class loader is
+     * specified non-null and the underlying method is not available or there
+     * is a security exception, etc.), then the behaviour reverts to that
+     * of JDK 1.1.
+     *
+     * @param name the base name of the resource bundle, a fully
+     *      qualified class name
+     * @param locale the locale for which a resource bundle is desired
+     * @param cl the class loader from which to load the resource bundle
+     */
+    public static ResourceBundle getBundle(String name, Locale locale,
+                                           ClassLoader cl)
+                                           throws NullPointerException,
+                                               MissingResourceException {
+
+        if (cl == null) {
+            return ResourceBundle.getBundle(name, locale);
+        } else if (newGetBundleMethod == null) {
+            return ResourceBundle.getBundle(name, locale);
+        } else {
+            try {
+                return (ResourceBundle) newGetBundleMethod.invoke(null,
+                        new Object[] {
+                    name, locale, cl
+                });
+            } catch (Exception e) {
+                return ResourceBundle.getBundle(name, locale);
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/resources/column-remarks.properties b/src/org/hsqldb/resources/column-remarks.properties
new file mode 100644
index 0000000..4340db2
--- /dev/null
+++ b/src/org/hsqldb/resources/column-remarks.properties
@@ -0,0 +1,394 @@
+# default column-remarks
+# SYSTEM_ALLTYPEINFO
+SYSTEM_ALLTYPEINFO_TYPE_NAME=the HSQLDB-specific data type name; this is the canonical name used in CREATE TABLE and ALTER TABLE statements.
+SYSTEM_ALLTYPEINFO_DATA_TYPE=SQL data type.  This may be a java.sql.Types data type, a SQL 200n data type or an HSQLDB-specific data type.  For datetime or interval data types, this column returns the concise data type (such as SQL_­TYPE_­TIME or SQL_­INTERVAL_­YEAR_­TO_­MONTH).
+SYSTEM_ALLTYPEINFO_PRECISION=The maximum column size for this data type.  For numeric data, this is the maximum precision.  For string data, this is the length in characters.  For datetime data types, this is the length in characters of the string representation (assuming the maximum allowed precision of the fractional seconds component).  NULL for data types where column size is not applicable.  For interval data types, this is the number of characters in the character representation of the interval literal (as defined by the interval leading precision).
+SYSTEM_ALLTYPEINFO_LITERAL_PREFIX=the character or characters used to prefix a literal of this type; for example, a single quotation mark (') for character data types; NULL for data types where a literal prefix is not applicable
+SYSTEM_ALLTYPEINFO_LITERAL_SUFFIX=the character or characters used to terminate a literal of this type; for example, a single quotation mark (') for character data types; NULL for data types where a literal suffix is not applicable
+SYSTEM_ALLTYPEINFO_CREATE_PARAMS=A list of keywords, separated by commas, corresponding to each parameter that may be specified in parentheses when issuing DDL relative to the data type.  The keywords in the list, in the language of the current Locale, may be any of the following:  length, precision, scale.  They appear in the order that the syntax requires that they be used.  For example, CREATE_PARAMS for DECIMAL with an English locale would be "precision,scale"; CREATE_PARAMS for VARCHAR would be "length".  The value is NULL if there are no parameters for the data type definition; for example, INTEGER.
+SYSTEM_ALLTYPEINFO_NULLABLE=NULL values allowed for this type?: { No Nulls | Nullable | Unknown }
+SYSTEM_ALLTYPEINFO_CASE_SENSITIVE=TRUE if the type is case-sensitive in collations and comparisons; FALSE otherwise
+SYSTEM_ALLTYPEINFO_SEARCHABLE=use of WHERE?: { None | Char (Only WHERE .. LIKE) | Basic (Except WHERE .. LIKE) | Searchable (All forms of WHERE...) }
+SYSTEM_ALLTYPEINFO_UNSIGNED_ATTRIBUTE=TRUE if the data type is unsigned; NULL the attribute is not applicable to the data type or the data type is not numeric.
+SYSTEM_ALLTYPEINFO_FIXED_PREC_SCALE=TRUE if the data type has predefined fixed precision and scale , like a money data type.  NULL for non-numeric types.
+SYSTEM_ALLTYPEINFO_AUTO_INCREMENT=NULL if the attribute is not applicable to the data type or the data type is not numeric.  If TRUE, this indicates that when an insert is made, a unique value is inserted into the column at insert time. The increment is not defined. An application should not assume that auto-increment values start at any particular point or increment by any particular value.
+SYSTEM_ALLTYPEINFO_LOCAL_TYPE_NAME=Localized version of the name of the data type; NULL if a localized name is not supported.  This name is intended for display only, such as in dialog boxes
+SYSTEM_ALLTYPEINFO_MINIMUM_SCALE=minimum scale supported
+SYSTEM_ALLTYPEINFO_MAXIMUM_SCALE=maximum scale supported
+SYSTEM_ALLTYPEINFO_SQL_DATA_TYPE=The value of the SQL data type as it would appear in the SQL CLI SQL_DESC_TYPE field of the SQLDA.
+SYSTEM_ALLTYPEINFO_SQL_DATETIME_SUB=When the value of SQL_DATA_TYPE is SQL_DATETIME or SQL_INTERVAL, this column contains the datetime/interval subcode.  For data types other than datetime and interval, this column is NULL.
+SYSTEM_ALLTYPEINFO_NUM_PREC_RADIX=For numeric types, this column contains the value 10 to indicate that COLUMN_SIZE specifies a number of decimal digits.  Otherwise, this column is NULL.
+SYSTEM_ALLTYPEINFO_INTERVAL_PRECISION=If the data type is an interval data type, then this column contains the value of the interval leading precision.  Otherwise, this column is NULL.
+SYSTEM_ALLTYPEINFO_AS_TAB_COL=TRUE if the engine supports this data type as a table column, else FALSE
+SYSTEM_ALLTYPEINFO_AS_PROC_COL=TRUE if the engine supports this data type as a procedure parameter or return type, else FALSE
+SYSTEM_ALLTYPEINFO_MAX_PREC_ACT=same as PRECISION except for data types whose precision cannot be represented by an INTEGER column value
+SYSTEM_ALLTYPEINFO_MIN_SCALE_ACT=same as MINIMUM_SCALE except for data types whose minimum scale cannot be represented by a SMALLINT column value
+SYSTEM_ALLTYPEINFO_MAX_SCALE_ACT=same as MAXIMUM_SCALE except for data types whose maximum scale cannot be represented by a SMALLINT column value
+SYSTEM_ALLTYPEINFO_COL_ST_CLS_NAME=the fully qualified name of the Java class that HSQLDB uses to represent values of this type in memory
+SYSTEM_ALLTYPEINFO_COL_ST_IS_SUP=TRUE if the Java class that HSQLDB uses to represent values of this type in memory is supported under the hosting JVM and engine build options
+SYSTEM_ALLTYPEINFO_STD_MAP_CLS_NAME=the fully qualified name of the Java class that the JDBC standard mapping uses to represent values of this type
+SYSTEM_ALLTYPEINFO_STD_MAP_IS_SUP=TRUE if the Java class that the JDBC standard mapping uses to represent values of this type is supported under the current JVM
+SYSTEM_ALLTYPEINFO_CST_MAP_CLS_NAME=the fully qualified name of the Java class that HSQLDB provides to represent values of this type via the JDBC interface
+SYSTEM_ALLTYPEINFO_CST_MAP_IS_SUP=TRUE if the Java class that HSQLDB provides to represent values of this type via the JDBC interface is supported under the hosting JVM and engine build options
+SYSTEM_ALLTYPEINFO_MCOL_JDBC=the maximum character octet length of this type if it is representable via the JDBC interface (i.e. as an INTEGER column value)
+SYSTEM_ALLTYPEINFO_MCOL_ACT=same as MCOL_JDBC except for data types whose maximum character octet length cannot be represented by an INTEGER column value
+SYSTEM_ALLTYPEINFO_DEF_OR_FIXED_SCALE=the default or fixed scale of numeric types; NULL if not applicable of the type is not numeric
+SYSTEM_ALLTYPEINFO_REMARKS=a localized explanatory comment on the data type
+SYSTEM_ALLTYPEINFO_TYPE_SUB=the variant tag for this variation of the data type.  1 = standard, 2 = identity, 4 = ignore case
+# SYSTEM_BESTROWIDENTIFIER
+SYSTEM_BESTROWIDENTIFIER_SCOPE=actual scope of result, as defined in java.sql.DatabaseMetadata
+SYSTEM_BESTROWIDENTIFIER_COLUMN_NAME=simple column name
+SYSTEM_BESTROWIDENTIFIER_DATA_TYPE=SQL data type.  This may be a java.sql.Types data type, a SQL 200n data type or an HSQLDB-specific data type.  For datetime or interval data types, this column returns the concise data type (such as SQL_­TYPE_­TIME or SQL_­INTERVAL_­YEAR_­TO_­MONTH).
+SYSTEM_BESTROWIDENTIFIER_TYPE_NAME=the HSQLDB-specific data type name; this is the canonical name used in CREATE TABLE and ALTER TABLE statements.
+SYSTEM_BESTROWIDENTIFIER_COLUMN_SIZE=precision for number types; length for variable sized types; NULL for others
+SYSTEM_BESTROWIDENTIFIER_BUFFER_LENGTH=The maximum length in bytes of data, if definitely known, that would be transferred to a buffer on a fetch operation.  For numeric data, this size may be different than the size of the data stored on the data source.  This value is the same as the COLUMN_SIZE column for binary data. This value is the twice the COLUMN_SIZE column for character data.  If the actual value is larger than can be represented in an INTEGER column value, this is NULL.
+SYSTEM_BESTROWIDENTIFIER_DECIMAL_DIGITS=scale of column for number types
+SYSTEM_BESTROWIDENTIFIER_PSEUDO_COLUMN=is this a pseudo column like an Oracle ROWID?
+SYSTEM_BESTROWIDENTIFIER_TABLE_CAT=catalog in which the table containing the column is defined
+SYSTEM_BESTROWIDENTIFIER_TABLE_SCHEM=schema in which the table containing the column is defined
+SYSTEM_BESTROWIDENTIFIER_TABLE_NAME=simple name of the table containing the column
+SYSTEM_BESTROWIDENTIFIER_NULLABLE=is the column nullable?
+SYSTEM_BESTROWIDENTIFIER_IN_KEY=does column participate in primary or alternate key?
+# SYSTEM_CACHEINFO
+#SYSTEM_CACHEINFO_CACHE_CLASS=FQN of the Java Class implementing the cache
+#SYSTEM_CACHEINFO_CACHE_HASH=the in-memory hashCode() of the Cache object
+SYSTEM_CACHEINFO_CACHE_FILE=absolute path of the file underlying the cache object
+#SYSTEM_CACHEINFO_CACHE_LENGTH=length of the cache object's row data array
+SYSTEM_CACHEINFO_MAX_CACHE_COUNT=maximum number of rows that will be buffered in memory by this cache
+SYSTEM_CACHEINFO_MAX_CACHE_BYTES=approximate maximum size, in bytes, of row data that will be buffered in memory by this cache
+SYSTEM_CACHEINFO_CACHE_SIZE=number of rows currently cached
+SYSTEM_CACHEINFO_CACHE_BYTES=approximate number of row data bytes currently cached
+SYSTEM_CACHEINFO_FILE_FREE_BYTES=aggregate size, in octets, of all allocation units considered available for reuse
+#SYSTEM_CACHEINFO_SMALLEST_FREE_ITEM=size, in octets, of smallest allocation unit available for reuse
+#SYSTEM_CACHEINFO_LARGEST_FREE_ITEM=size, in octets, of largest allocation unit available for reuse
+SYSTEM_CACHEINFO_FILE_FREE_COUNT=number of allocation units available for reuse
+SYSTEM_CACHEINFO_FILE_FREE_POS=one greater than largest file position known to be allocated
+#SYSTEM_CACHEINFO_MAX_CACHE_SIZE=maximum allowable number of cached Row objects
+#SYSTEM_CACHEINFO_MAX_CACHE_BYTE_SIZE=limit on memory consumption of cached Row objects
+#SYSTEM_CACHEINFO_MULTIPLIER_MASK=binary mask used to calculate indices into row data array
+#SYSTEM_CACHEINFO_WRITER_LENGTH=length of row write buffer array
+# INFORMATION_SCHEMA_CATALOG_NAME
+INFORMATION_SCHEMA_CATALOG_NAME_CATALOG_NAME=catalog name
+# SYSTEM_COLUMNPRIVILEGES
+SYSTEM_COLUMNPRIVILEGES_TABLE_CAT=catalog in which the table containing the column is defined
+SYSTEM_COLUMNPRIVILEGES_TABLE_SCHEM=schema in which the table containing the column is defined
+SYSTEM_COLUMNPRIVILEGES_TABLE_NAME=simple name of the table containing the column is defined
+SYSTEM_COLUMNPRIVILEGES_COLUMN_NAME=simple name of the column
+SYSTEM_COLUMNPRIVILEGES_GRANTOR=grantor of access
+SYSTEM_COLUMNPRIVILEGES_GRANTEE=grantee of access
+SYSTEM_COLUMNPRIVILEGES_PRIVILEGE=name of access, e.g. one of { ALL, SELECT, INSERT, UPDATE, DELETE, ...}
+SYSTEM_COLUMNPRIVILEGES_IS_GRANTABLE=grantable?: YES - may grant to others, NO - not permitted to grant to others, NULL - unknown
+# SYSTEM_COLUMNS
+SYSTEM_COLUMNS_TABLE_CAT=catalog in which the table containing the column is defined
+SYSTEM_COLUMNS_TABLE_SCHEM=schema in which the table containing the column is defined
+SYSTEM_COLUMNS_TABLE_NAME=simple name of the table containing the column
+SYSTEM_COLUMNS_COLUMN_NAME=simple name of the column
+SYSTEM_COLUMNS_DATA_TYPE=SQL data type.  This may be a java.sql.Types data type, a SQL 200n data type or an HSQLDB-specific data type.  For datetime or interval data types, this column returns the concise data type (such as SQL_­TYPE_­TIME or SQL_­INTERVAL_­YEAR_­TO_­MONTH).
+SYSTEM_COLUMNS_TYPE_NAME=the HSQLDB-specific data type name; this is the canonical name used in CREATE TABLE and ALTER TABLE statements.
+SYSTEM_COLUMNS_COLUMN_SIZE=precision for number types; length for sized types; NULL if not applicable
+SYSTEM_COLUMNS_BUFFER_LENGTH=The maximum length in bytes of data, if definitely known, that would be transferred to a buffer on a fetch operation.  For numeric data, this size may be different than the size of the data stored on the data source.  This value is the same as the COLUMN_SIZE column for binary data. This value is the twice the COLUMN_SIZE column for character data.  If the actual value is larger than can be represented in an INTEGER column value, this is NULL.
+SYSTEM_COLUMNS_DECIMAL_DIGITS=# of fractional digits (scale) for number types
+SYSTEM_COLUMNS_NUM_PREC_RADIX=Radix of reported numeric precision (i.e. base of number types)
+SYSTEM_COLUMNS_NULLABLE=is NULL allowed?: { columnNoNulls (maybe not), columnNullable (definitely), columnNullableUnknown }
+SYSTEM_COLUMNS_REMARKS=explanitory comment describing the column (may be NULL)
+SYSTEM_COLUMNS_COLUMN_DEF=default value (may be NULL)
+SYSTEM_COLUMNS_SQL_DATA_TYPE=The value of the SQL data type as it would appear in the SQL CLI SQL_DESC_TYPE field of the SQLDA.
+SYSTEM_COLUMNS_SQL_DATETIME_SUB=When the value of SQL_DATA_TYPE is SQL_DATETIME or SQL_INTERVAL, this column contains the datetime/interval subcode.  For data types other than datetime and interval, this column is NULL.
+SYSTEM_COLUMNS_CHAR_OCTET_LENGTH=for char types, the maximum number of bytes in the column, if the value can be represented as an INTEGER column value, else NULL
+SYSTEM_COLUMNS_ORDINAL_POSITION=index of column in table (starting at 1)
+SYSTEM_COLUMNS_IS_NULLABLE=is column nullable?: { YES (might allow) | NO (definitely not)  | '' (unknown) }
+SYSTEM_COLUMNS_SCOPE_CATLOG=catalog of table that is the scope of a reference attribute (NULL if DATA_TYPE isn't REF)
+SYSTEM_COLUMNS_SCOPE_SCHEMA=schema of table that is the scope of a reference attribute (NULL if the DATA_TYPE isn't REF)
+SYSTEM_COLUMNS_SCOPE_TABLE=table name that this the scope of a reference attribute (NULL if the DATA_TYPE isn't REF)
+SYSTEM_COLUMNS_SOURCE_DATA_TYPE=source type of a distinct type or user-generated Ref type, SQL type from DITypes (NULL if DATA_TYPE isn't DISTINCT or user-generated REF)
+SYSTEM_COLUMNS_TYPE_SUB=the HSQLDB-specific type subidentifier (1:default, 2:identity, 4:ignorecase)
+# SYSTEM_CROSSREFERENCE
+SYSTEM_CROSSREFERENCE_PKTABLE_CAT=the catalog in which the referenced table is defined
+SYSTEM_CROSSREFERENCE_PKTABLE_SCHEM=the schema in which the referenced table is defined
+SYSTEM_CROSSREFERENCE_PKTABLE_NAME=simple name of the referenced table
+SYSTEM_CROSSREFERENCE_PKCOLUMN_NAME=simple name of the referenced column
+SYSTEM_CROSSREFERENCE_FKTABLE_CAT=the catalog in which the referencing table is defined
+SYSTEM_CROSSREFERENCE_FKTABLE_SCHEM=the schema in which the referencing table is defined
+SYSTEM_CROSSREFERENCE_FKTABLE_NAME=the simple name of the referencing table
+SYSTEM_CROSSREFERENCE_FKCOLUMN_NAME=the simple name of the referencing column
+SYSTEM_CROSSREFERENCE_KEY_SEQ=sequence number within foreign key definition
+SYSTEM_CROSSREFERENCE_UPDATE_RULE=how does an update of referenced row columns affect referencing rows?: e.g. { Cascade | Set Null | Set Default | Restrict (No Action) }
+SYSTEM_CROSSREFERENCE_DELETE_RULE=how does deletion of a referenced row affect referencing rows?: e.g. { Cascade | Set Null | Set Default | Restrict (No Action) }
+SYSTEM_CROSSREFERENCE_FK_NAME=the name of the foreign key
+SYSTEM_CROSSREFERENCE_PK_NAME=the name of the referenced column set (usually the name of a primary key constraint, but may be a unique constraint or even the name of a non-unique index previous to 1.7.0)
+SYSTEM_CROSSREFERENCE_DEFERRABILITY=foreign key constraints deferred until commit?: e.g. { initially deferred | initially immediate | not deferrable }
+# SYSTEM_INDEXINFO
+SYSTEM_INDEXINFO_TABLE_CAT=catalog in which the table using the index is defined
+SYSTEM_INDEXINFO_TABLE_SCHEM=schema in which the table using the index is defined
+SYSTEM_INDEXINFO_TABLE_NAME=simple name of the table using the index
+SYSTEM_INDEXINFO_NON_UNIQUE=can index values be non-unique?
+SYSTEM_INDEXINFO_INDEX_QUALIFIER=catalog in which the index is defined
+SYSTEM_INDEXINFO_INDEX_NAME=simple name of the index
+SYSTEM_INDEXINFO_TYPE=index type: e.g. { Clustered | Hashed | Other }
+SYSTEM_INDEXINFO_ORDINAL_POSITION=column sequence number within index
+SYSTEM_INDEXINFO_COLUMN_NAME=simple column name
+SYSTEM_INDEXINFO_ASC_OR_DESC=column sort sequence: e.g. { "A" (Ascending) | "D" (Descending) }
+SYSTEM_INDEXINFO_CARDINALITY=index cardinality: # of unique values in the index (currently unused)
+SYSTEM_INDEXINFO_PAGES=index page use (currently unused)
+SYSTEM_INDEXINFO_FILTER_CONDITION=filter condition, if any (currently unused)
+# SYSTEM_LOBS
+SYSTEM_LOBS_NAME=Java classfile encoded absolute name of a resource ( /dir1/.../dirn/resourcename.ext)
+SYSTEM_LOBS_CONTENT=binary content of Java class file or resource
+SYSTEM_LOBS_CONTENT_TYPE=content type (possibly a mime-type value)
+SYSTEM_LOBS_MD5=MD5 hash of content (efficiently detects and avoids attempts to reload identical content)
+SYSTEM_LOBS_CREATED=time at which content was initially loaded
+SYSTEM_LOBS_MODIFIED=time at which content was last modified
+# SYSTEM_PRIMARYKEYS
+SYSTEM_PRIMARYKEYS_TABLE_CAT=catalog in which table containing primary key is defined
+SYSTEM_PRIMARYKEYS_TABLE_SCHEM=schema in which table containing primary key is defined
+SYSTEM_PRIMARYKEYS_TABLE_NAME=simple name of table containing primary key
+SYSTEM_PRIMARYKEYS_COLUMN_NAME=simple name of column participating in primary key
+SYSTEM_PRIMARYKEYS_KEY_SEQ=sequence number of column within primary key
+SYSTEM_PRIMARYKEYS_PK_NAME=primary key name
+# SYSTEM_PROCEDURECOLUMNS
+SYSTEM_PROCEDURECOLUMNS_PROCEDURE_CAT=catalog in which procedure is defined
+SYSTEM_PROCEDURECOLUMNS_PROCEDURE_SCHEM=schema in which procedure is defined
+SYSTEM_PROCEDURECOLUMNS_PROCEDURE_NAME=procedure identifier
+SYSTEM_PROCEDURECOLUMNS_COLUMN_NAME=( result column | call parameter | return value ) name
+SYSTEM_PROCEDURECOLUMNS_COLUMN_TYPE=kind of column/parameter: { Unknown | IN | INOUT | OUT | RETURN | RESULT }
+SYSTEM_PROCEDURECOLUMNS_DATA_TYPE=SQL data type.  This may be a java.sql.Types data type, a SQL 200n data type or an HSQLDB-specific data type.  For datetime or interval data types, this column returns the concise data type (such as SQL_­TYPE_­TIME or SQL_­INTERVAL_­YEAR_­TO_­MONTH).
+SYSTEM_PROCEDURECOLUMNS_TYPE_NAME=the HSQLDB-specific data type name; for data types supported as table column types, this is the canonical name used in CREATE TABLE and ALTER TABLE statements.
+SYSTEM_PROCEDURECOLUMNS_PRECISION=precision for number types; max length for sized types; fixed or max length for others if known, or NULL if not applicable
+SYSTEM_PROCEDURECOLUMNS_LENGTH=The maximum length in bytes of data, if definitely known, that would be transferred to a buffer on a fetch operation.  For numeric data, this size may be different than the size of the data stored on the data source.  This value is the same as the COLUMN_SIZE column for binary data. This value is the twice the COLUMN_SIZE column for character data.  If the actual value is unknown or is larger than can be represented in an INTEGER column value, this is NULL.
+SYSTEM_PROCEDURECOLUMNS_SCALE=scale (# of fractional digits) for number types
+SYSTEM_PROCEDURECOLUMNS_RADIX=Radix of reported numeric precision (i.e. base of number types)
+SYSTEM_PROCEDURECOLUMNS_NULLABLE=can column contain NULL: { No Nulls | Nullable | Unknown }?
+SYSTEM_PROCEDURECOLUMNS_REMARKS=comment describing parameter or result column
+SYSTEM_PROCEDURECOLUMNS_SPECIFIC_NAME=typically, (but not limited to) the fully qualified name and signature of the Java method providing the SQL-invoked routine's entry point
+SYSTEM_PROCEDURECOLUMNS_SEQ=provides the ability to deliver rows in JDBC DataseMetaData sort contrct order
+# SYSTEM_PROCEDURES
+SYSTEM_PROCEDURES_PROCEDURE_CAT=catalog in which procedure is defined
+SYSTEM_PROCEDURES_PROCEDURE_SCHEM=schema in which procedure is defined
+SYSTEM_PROCEDURES_PROCEDURE_NAME=procedure identifier
+SYSTEM_PROCEDURES_REMARKS=explanatory comment on the procedure
+SYSTEM_PROCEDURES_PROCEDURE_TYPE=kind of procedure: { Unknown | No Result | Returns Result }
+SYSTEM_PROCEDURES_NUM_INPUT_PARAMS=number of procedure input parameters
+SYSTEM_PROCEDURES_NUM_OUTPUT_PARAMS=number of procedure output parameters
+SYSTEM_PROCEDURES_NUM_RESULT_SETS=number of result sets returned by procedure (if any)
+SYSTEM_PROCEDURES_ORIGIN=how was named procedure introduced to system?: e.g. { BUILTIN | USER CLASS GRANT | ALIAS | TRIGGER | MODULE | ...}
+SYSTEM_PROCEDURES_SPECIFIC_NAME=typically, (but not limited to) the fully qualified name and signature of the Java method providing the SQL-invoked routine's entry point
+# SYSTEM_PROPERTIES
+SYSTEM_PROPERTIES_PROPERTY_SCOPE=the scope of the property, e.g. ( TEMPORARY | TRANSACTION | SESSION | ...}
+SYSTEM_PROPERTIES_PROPERTY_NAMESPACE=the namespace in which the property is applicable, e.g. ( database.properties | org.hsqldb.Database | java.sql.DatabaseMetaData | ...)
+SYSTEM_PROPERTIES_PROPERTY_NAME=the name of the property
+SYSTEM_PROPERTIES_PROPERTY_VALUE=the current value of the property
+SYSTEM_PROPERTIES_PROPERTY_CLASS=the type of the value, e.g. ( int | boolean | java.lang.String | ...)
+# SYSTEM_SCHEMAS
+SYSTEM_SCHEMAS_TABLE_SCHEM=schema name
+SYSTEM_SCHEMAS_TABLE_CATALOG=catalog in which schema is defined
+SYSTEM_SCHEMAS_IS_DEFAULT=whether the described schema is the default schema
+# SYSTEM_SESSIONS
+SYSTEM_SESSIONS_SESSION_ID=session identifier
+SYSTEM_SESSIONS_CONNECTED=time at which session connected to database
+SYSTEM_SESSIONS_USER_NAME=name of session user, as known to the database
+SYSTEM_SESSIONS_IS_ADMIN=is session user an admin user?
+SYSTEM_SESSIONS_AUTOCOMMIT=is session in autocommit mode?
+SYSTEM_SESSIONS_READONLY=is session in read-only mode?
+SYSTEM_SESSIONS_MAXROWS=what is the session's MAXROWS setting?
+SYSTEM_SESSIONS_LAST_IDENTITY=what is the last identity value used by this session?
+SYSTEM_SESSIONS_TRANSACTION_SIZE=how many undo items are there in this session's transaction buffer?
+#since 1.8.0
+SYSTEM_SESSIONS_SCHEMA=this session's current default schema
+# SYSTEM_SESSIONINFO
+SYSTEM_SESSIONINFO_KEY=KEY: { SESSION_ID | AUTOCOMMIT | USER | CONNECTION_READONLY | DATABASE_READONLY | MAXROWS | DATABASE | IDENTITY ... }
+SYSTEM_SESSIONINFO_VALUE=VALUE: the value corresponding to the indicated key (see JavaDocs)
+# SYSTEM_TABLEPRIVILEGES
+SYSTEM_TABLEPRIVILEGES_TABLE_CAT=table catalog
+SYSTEM_TABLEPRIVILEGES_TABLE_SCHEM=table schema
+SYSTEM_TABLEPRIVILEGES_TABLE_NAME=table name
+SYSTEM_TABLEPRIVILEGES_GRANTOR=grantor of access
+SYSTEM_TABLEPRIVILEGES_GRANTEE=grantee of access
+SYSTEM_TABLEPRIVILEGES_PRIVILEGE=name of access: e.g. one of { ALL | SELECT | INSERT | UPDATE | DELETE }
+SYSTEM_TABLEPRIVILEGES_IS_GRANTABLE=for grantee: YES - may grant to others, NO - may not grant to others, NULL - unknown
+# SYSTEM_TABLES
+SYSTEM_TABLES_TABLE_CAT=table catalog
+SYSTEM_TABLES_TABLE_SCHEM=table schema
+SYSTEM_TABLES_TABLE_NAME=table name
+SYSTEM_TABLES_TABLE_TYPE=table type: e.g. one of { TABLE | VIEW | SYSTEM TABLE | GLOBAL TEMPORARY ... }
+SYSTEM_TABLES_REMARKS=explanatory comment on the table
+SYSTEM_TABLES_TYPE_CAT=table type catalog
+SYSTEM_TABLES_TYPE_SCHEM=table type schema
+SYSTEM_TABLES_TYPE_NAME=table type name
+SYSTEM_TABLES_SELF_REFERENCING_COL_NAME=name of the designated "identifier" column of typed table (null if not typed)
+SYSTEM_TABLES_REF_GENERATION=how are values in SELF_REFERENCING_COL_NAME created?: e.g. one of { "SYSTEM" | "USER" | "DERIVED" | NULL }
+SYSTEM_TABLES_HSQLDB_TYPE=the HSQLDB-specific type of the table, e.g. ( MEMORY | CACHED | TEXT | ...)
+SYSTEM_TABLES_READ_ONLY=TRUE if the table is read-only, else FALSE
+# SYSTEM_TABLETYPES
+SYSTEM_TABLETYPES_TABLE_TYPE=table type name
+# SYSTEM_TEXTTABLES
+SYSTEM_TEXTTABLES_TABLE_CAT=table catalog
+SYSTEM_TEXTTABLES_TABLE_SCHEM=table schema
+SYSTEM_TEXTTABLES_TABLE_NAME=table name
+SYSTEM_TEXTTABLES_DATA_SOURCE_DEFINTION=the "spec" proption of the table's SET TABLE ... SOURCE DDL declaration
+SYSTEM_TEXTTABLES_FILE_PATH=path to table's text file data source
+SYSTEM_TEXTTABLES_FILE_ENCODING=encoding of table's text file data source
+SYSTEM_TEXTTABLES_FIELD_SEPARATOR=the default field separator
+SYSTEM_TEXTTABLES_VARCHAR_SEPARATOR=varchar field separator
+SYSTEM_TEXTTABLES_LONGVARCHAR_SEPARATOR=longvarchar field separator
+SYSTEM_TEXTTABLES_IS_IGNORE_FIRST=ignores first line of file?
+# added to reflect 1.7.2 RC1
+SYSTEM_TEXTTABLES_IS_QUOTED=fields are quoted if necessary?
+#--
+SYSTEM_TEXTTABLES_IS_ALL_QUOTED=every field is quoted?
+SYSTEM_TEXTTABLES_IS_DESC=read rows starting at end of file?
+# SYSTEM_TYPEINFO
+SYSTEM_TYPEINFO_TYPE_NAME=the HSQLDB-specific data type name; this is the canonical name used in CREATE TABLE and ALTER TABLE statements.
+SYSTEM_TYPEINFO_DATA_TYPE=SQL data type.  This may be a java.sql.Types data type, a SQL 200n data type or an HSQLDB-specific data type.  For datetime or interval data types, this column returns the concise data type (such as SQL_­TYPE_­TIME or SQL_­INTERVAL_­YEAR_­TO_­MONTH).
+SYSTEM_TYPEINFO_PRECISION=The maximum column size for this data type.  For numeric data, this is the maximum precision.  For string data, this is the length in characters.  For datetime data types, this is the length in characters of the string representation (assuming the maximum allowed precision of the fractional seconds component).  NULL for data types where column size is not applicable.  For interval data types, this is the number of characters in the character representation of the interval literal (as defined by the interval leading precision).
+SYSTEM_TYPEINFO_LITERAL_PREFIX=the character or characters used to prefix a literal of this type; for example, a single quotation mark (') for character data types; NULL for data types where a literal prefix is not applicable
+SYSTEM_TYPEINFO_LITERAL_SUFFIX=the character or characters used to terminate a literal of this type; for example, a single quotation mark (') for character data types; NULL for data types where a literal suffix is not applicable
+SYSTEM_TYPEINFO_CREATE_PARAMS=A list of keywords, separated by commas, corresponding to each parameter that may be specified in parentheses when issuing DDL relative to the data type.  The keywords in the list, in the language of the current Locale, may be any of the following:  length, precision, scale.  They appear in the order that the syntax requires that they be used.  For example, CREATE_PARAMS for DECIMAL with an English locale would be "precision,scale"; CREATE_PARAMS for VARCHAR would be "length".  The value is NULL if there are no parameters for the data type definition; for example, INTEGER.
+SYSTEM_TYPEINFO_NULLABLE=NULL values allowed for this type?: { No Nulls | Nullable | Unknown }
+SYSTEM_TYPEINFO_CASE_SENSITIVE=TRUE if the type is case-sensitive in collations and comparisons; FALSE otherwise
+SYSTEM_TYPEINFO_SEARCHABLE=use of WHERE?: { None | Char (Only WHERE .. LIKE) | Basic (Except WHERE .. LIKE) | Searchable (All forms of WHERE...) }
+SYSTEM_TYPEINFO_UNSIGNED_ATTRIBUTE=TRUE if the data type is unsigned; NULL the attribute is not applicable to the data type or the data type is not numeric.
+SYSTEM_TYPEINFO_FIXED_PREC_SCALE=TRUE if the data type has predefined fixed precision and scale , like a money data type.  NULL for non-numeric types.
+SYSTEM_TYPEINFO_AUTO_INCREMENT=NULL if the attribute is not applicable to the data type or the data type is not numeric.  If TRUE, this indicates that when an insert is made, a unique value is inserted into the column at insert time. The increment is not defined. An application should not assume that auto-increment values start at any particular point or increment by any particular value.
+SYSTEM_TYPEINFO_LOCAL_TYPE_NAME=Localized version of the name of the data type; NULL if a localized name is not supported.  This name is intended for display only, such as in dialog boxes
+SYSTEM_TYPEINFO_MINIMUM_SCALE=minimum scale supported
+SYSTEM_TYPEINFO_MAXIMUM_SCALE=maximum scale supported
+SYSTEM_TYPEINFO_SQL_DATA_TYPE=The value of the SQL data type as it would appear in the SQL CLI SQL_DESC_TYPE field of the SQLDA.
+SYSTEM_TYPEINFO_SQL_DATETIME_SUB=When the value of SQL_DATA_TYPE is SQL_DATETIME or SQL_INTERVAL, this column contains the datetime/interval subcode.  For data types other than datetime and interval, this column is NULL.
+SYSTEM_TYPEINFO_NUM_PREC_RADIX=For numeric types, this column contains the value 10 to indicate that COLUMN_SIZE specifies a number of decimal digits.  Otherwise, this column is NULL.
+SYSTEM_TYPEINFO_TYPE_SUB=the variant tag for this variation of the data type.  1 = standard, 2 = identity, 4 = ignore case
+# SYSTEM_UDTS
+SYSTEM_UDTS_TYPE_CAT=type's catalog
+SYSTEM_UDTS_TYPE_SCHEM=type's schema
+SYSTEM_UDTS_TYPE_NAME=type's DBMS name
+SYSTEM_UDTS_CLASS_NAME=type's Java class name
+SYSTEM_UDTS_DATA_TYPE=type value defined in DITypes, from one of { "JAVA_OBJECT" | "STRUCT" | "DISTINCT" }
+SYSTEM_UDTS_BASE_TYPE=type code of the source type of a DISTINCT type or the type that implements the user-generated reference type of the SELF_REFERENCING_COLUMN of a structured type as defined in DITypes (null if DATA_TYPE is not DISTINCT or not STRUCT with REFERENCE_GENERATION = USER_DEFINED)
+SYSTEM_UDTS_REMARKS=explanatory comment on the user defined type
+# SYSTEM_USERS
+SYSTEM_USERS_USER=user name
+SYSTEM_USERS_ADMIN=has the administrative privilege?
+SYSTEM_USERS_INITIAL_SCHEMA=initial schema for user
+# SYSTEM_VERSIONCOLUMNS
+SYSTEM_VERSIONCOLUMNS_TABLE_CAT=table catalog
+SYSTEM_VERSIONCOLUMNS_TABLE_SCHEM=table schema
+SYSTEM_VERSIONCOLUMNS_TABLE_NAME=simple table name
+SYSTEM_VERSIONCOLUMNS_SCOPE=not used
+SYSTEM_VERSIONCOLUMNS_COLUMN_NAME=column name
+SYSTEM_VERSIONCOLUMNS_DATA_TYPE=SQL data type from DITypes
+SYSTEM_VERSIONCOLUMNS_TYPE_NAME=Data source dependent type name
+SYSTEM_VERSIONCOLUMNS_COLUMN_SIZE=precision
+SYSTEM_VERSIONCOLUMNS_BUFFER_LENGTH=length of column value in bytes
+SYSTEM_VERSIONCOLUMNS_DECIMAL_DIGITS=scale
+SYSTEM_VERSIONCOLUMNS_PSEUDO_COLUMN=is this a pseudo column like an Oracle ROWID: { Unknown | Not Pseudo | Pseudo }?
+# SYSTEM_VIEWS
+SYSTEM_VIEWS_TABLE_CATALOG=name of catalog in which view is defined
+SYSTEM_VIEWS_TABLE_SCHEMA=unqualified name of schema in which view is defined
+SYSTEM_VIEWS_TABLE_NAME=simple name of view
+SYSTEM_VIEWS_VIEW_DEFINITION=the character representation of the query expression contained in the corresponding view descriptor.
+SYSTEM_VIEWS_CHECK_OPTION={"CASCADED" | "LOCAL" | "NONE"}
+SYSTEM_VIEWS_IS_UPDATABLE={"YES" | "NO"}
+SYSTEM_VIEWS_VALID={TRUE | FALSE}
+# Since 1.7.2 RC1
+# SYSTEM_CHECK_COLUMN_USAGE
+SYSTEM_CHECK_COLUMN_USAGE_CONSTRAINT_CATALOG=constraint catalog name
+SYSTEM_CHECK_COLUMN_USAGE_CONSTRAINT_SCHEMA=constraint schema name
+SYSTEM_CHECK_COLUMN_USAGE_CONSTRAINT_NAME=constraint identifier
+SYSTEM_CHECK_COLUMN_USAGE_TABLE_CATALOG=table catalog name
+SYSTEM_CHECK_COLUMN_USAGE_TABLE_SCHEMA= table schema name
+SYSTEM_CHECK_COLUMN_USAGE_TABLE_NAME=table name
+SYSTEM_CHECK_COLUMN_USAGE_COLUMN_NAME=name of column referenced explicitly or implicitly as contained in the <search condition> of the constraint being described.
+# SYSTEM_CHECK_CONSTRAINTS
+SYSTEM_CHECK_CONSTRAINTS_CONSTRAINT_CATALOG=constraint catalog name
+SYSTEM_CHECK_CONSTRAINTS_CONSTRAINT_SCHEMA=constraint schema name
+SYSTEM_CHECK_CONSTRAINTS_CONSTRAINT_NAME=constraint identifier
+SYSTEM_CHECK_CONSTRAINTS_CHECK_CLAUSE=the character representation of the <search condition> contained in the <check constraint definition>, <domain constraint definition>, or <assertion definition> that defined the check constraint being described, or NULL if it cannot be described without truncation
+# SYSTEM_CHECK_ROUTINE_USAGE
+SYSTEM_CHECK_ROUTINE_USAGE_CONSTRAINT_CATALOG=constraint catalog name
+SYSTEM_CHECK_ROUTINE_USAGE_CONSTRAINT_SCHEMA=constraint schema name
+SYSTEM_CHECK_ROUTINE_USAGE_CONSTRAINT_NAME=constraint identifier
+SYSTEM_CHECK_ROUTINE_USAGE_SPECIFIC_CATALOG=catalog name of specific name of routine
+SYSTEM_CHECK_ROUTINE_USAGE_SPECIFIC_SCHEMA=schema name of specific name of routine
+SYSTEM_CHECK_ROUTINE_USAGE_SPECIFIC_NAME=specific name of SQL-invoked routine identified as the subject routine of either a <routine invocation>, a <method reference>, a <method invocation>, or a <static method invocation> contained in the <assertion definition> or in the <check constraint definition> contained in either a <domain constraint> or a <table constraint definition>
+# CONSTRAINT_TABLE_USAGE
+CONSTRAINT_TABLE_USAGE_TABLE_CATALOG=table catalog name
+CONSTRAINT_TABLE_USAGE_TABLE_SCHEMA=table schema name
+CONSTRAINT_TABLE_USAGE_TABLE_NAME=name of a table identified by a <table name> simply contained in a <table reference> contained in the lt;search condition> of the constraint being described.
+CONSTRAINT_TABLE_USAGE_CONSTRAINT_CATALOG=constraint catalog name
+CONSTRAINT_TABLE_USAGE_CONSTRAINT_SCHEMA=constraint schema name
+CONSTRAINT_TABLE_USAGE_CONSTRAINT_NAME=constraint identifier
+# SYSTEM_SEQUENCES
+SYSTEM_SEQUENCES_SEQUENCE_CATALOG=sequence catalog name
+SYSTEM_SEQUENCES_SEQUENCE_SCHEMA=sequence schema name
+SYSTEM_SEQUENCES_SEQUENCE_NAME=sequence identifier
+SYSTEM_SEQUENCES_DTD_IDENTIFIER=implementation dependent data type descriptor identifier
+SYSTEM_SEQUENCES_MAXIMUM_VALUE=sequence maximum value
+SYSTEM_SEQUENCES_MINIMUM_VALUE=sequence minimum value
+SYSTEM_SEQUENCES_INCREMENT=sequence increment
+SYSTEM_SEQUENCES_CYCLE_OPTION=sequence cycle option ('YES' | 'NO')
+SYSTEM_SEQUENCES_START_WITH=sequence start with value
+# SYSTEM_TABLE_CONSTRAINTS
+SYSTEM_TABLE_CONSTRAINTS_CONSTRAINT_CATALOG=constraint catalog name
+SYSTEM_TABLE_CONSTRAINTS_CONSTRAINT_SCHEMA=constraint schema name
+SYSTEM_TABLE_CONSTRAINTS_CONSTRAINT_NAME=constraint identifier
+SYSTEM_TABLE_CONSTRAINTS_CONSTRAINT_TYPE=('UNIQUE' | 'PRIMARY KEY' | 'FOREIGN KEY' | 'CHECK')
+SYSTEM_TABLE_CONSTRAINTS_TABLE_CATALOG=table catalog name
+SYSTEM_TABLE_CONSTRAINTS_TABLE_SCHEMA=table schema name
+SYSTEM_TABLE_CONSTRAINTS_TABLE_NAME=table identifier
+SYSTEM_TABLE_CONSTRAINTS_IS_DEFERRABLE=('YES' | 'NO')
+SYSTEM_TABLE_CONSTRAINTS_INITIALLY_DEFERRED=('YES' | 'NO')
+# SYSTEM_USAGE_PRIVILEGES
+SYSTEM_USAGE_PRIVILEGES_GRANTOR=<authorization identifier> of the user or role who granted usage privileges on the object
+SYSTEM_USAGE_PRIVILEGES_GRANTEE=<authorization identifier> of some user or role, or ?PUBLIC? to indicate all users, to whom the usage privilege being described is granted
+SYSTEM_USAGE_PRIVILEGES_OBJECT_CATALOG=object catalog name
+SYSTEM_USAGE_PRIVILEGES_OBJECT_SCHEMA=object catalog schema
+SYSTEM_USAGE_PRIVILEGES_OBJECT_NAME=identifier of the object to which the privilege applies
+SYSTEM_USAGE_PRIVILEGES_OBJECT_TYPE=(DOMAIN' | 'CHARACTER SET' | 'COLLATION' | 'TRANSLATION' | 'SEQUENCE')
+SYSTEM_USAGE_PRIVILEGES_IS_GRANTABLE=('YES' | 'NO')
+# SYSTEM_VIEW_COLUMN_USAGE
+SYSTEM_VIEW_COLUMN_USAGE_VIEW_CATALOG=view catalog name
+SYSTEM_VIEW_COLUMN_USAGE_VIEW_SCHEMA=view schema name
+SYSTEM_VIEW_COLUMN_USAGE_VIEW_NAME=view identifier
+SYSTEM_VIEW_COLUMN_USAGE_TABLE_CATALOG=table catalog name
+SYSTEM_VIEW_COLUMN_USAGE_TABLE_SCHEMA=table schema name
+SYSTEM_VIEW_COLUMN_USAGE_TABLE_NAME=table identifier
+SYSTEM_VIEW_COLUMN_USAGE_COLUMN_NAME=column of table that is explicitly or implicitly referenced in the <query expression> of the view being described.
+# SYSTEM_VIEW_ROUTINE_USAGE
+SYSTEM_VIEW_ROUTINE_USAGE_TABLE_CATALOG=view catalog name
+SYSTEM_VIEW_ROUTINE_USAGE_TABLE_SCHEMA=view schema name
+SYSTEM_VIEW_ROUTINE_USAGE_TABLE_NAME=view identifier
+SYSTEM_VIEW_ROUTINE_USAGE_SPECIFIC_CATALOG=catalog name of specific name of routine
+SYSTEM_VIEW_ROUTINE_USAGE_SPECIFIC_SCHEMA=schema name of specific name of routine
+SYSTEM_VIEW_ROUTINE_USAGE_SPECIFIC_NAME=specific name of SQL-invoked subject routine of either a <routine invocation>, a <method reference>, a <method invocation>, or a <static method invocation> contained in the <view definition>
+
+SYSTEM_VIEW_TABLE_USAGE_VIEW_CATALOG=view catalog name
+SYSTEM_VIEW_TABLE_USAGE_VIEW_SCHEMA=view schema name
+SYSTEM_VIEW_TABLE_USAGE_VIEW_NAME=view identifier
+SYSTEM_VIEW_TABLE_USAGE_TABLE_CATALOG=table catalog name
+SYSTEM_VIEW_TABLE_USAGE_TABLE_SCHEMA=table schema name
+SYSTEM_VIEW_TABLE_USAGE_TABLE_NAME=table identified by a <table name> simply contained in a <table reference> that is contained in the <query expression> of the view being described.
+# Since 1.8.0
+# SYSTEM_AUTHORIZATIONS
+SYSTEM_AUTHORIZATIONS_AUTHORIZATION_NAME=a <role name> or <user identifier>
+SYSTEM_AUTHORIZATIONS_AUTHORIZATION_TYPE=('USER' | 'ROLE') whether the AUTHORIZATION_NAME is a known <user identifier> or is a <role name> defined by a <role definition>.
+# SYSTEM_COLLATIONS
+SYSTEM_COLLATIONS_COLLATION_CATALOG=catalog name of the collation being described
+SYSTEM_COLLATIONS_COLLATION_SCHEMA=unqualified schema name of the collation being described
+SYSTEM_COLLATIONS_COLLATION_NAME=qualified identifier of the collation being described
+SYSTEM_COLLATIONS_PAD_ATTRIBUTE=('NO PAD' | 'PAD SPACE') whether the collation being described has the NO PAD or PAD SPACE characteristic
+SYSTEM_COLLATIONS_COLLATION_TYPE=NULL (deprecated)
+SYSTEM_COLLATIONS_COLLATION_DEFINITION=NULL (deprecated)
+SYSTEM_COLLATIONS_COLLATION_DICTIONARY=NULL (deprecated)
+SYSTEM_COLLATIONS_CHARACTER_REPERTOIRE_NAME=the name of the charater repertoire to which the collation being described is applicable.
+# SYSTEM_ROLE_AUTHORIZATION_DESCRIPTORS
+SYSTEM_ROLE_AUTHORIZATION_DESCRIPTORS_ROLE_NAME=the <role name> of some <role granted> by the <grant role statement> or the <role name> of a <role definition>.
+SYSTEM_ROLE_AUTHORIZATION_DESCRIPTORS_GRANTEE=an <authorization identifier>, possibly PUBLIC, or <role name> specified as a <grantee> contained in a <grant role statement>, or the <authorization identifier> of the current SQLsession when the <role definition> is executed.
+SYSTEM_ROLE_AUTHORIZATION_DESCRIPTORS_GRANTOR=the <authorization identifier> of the user or role who granted the role identified by ROLE_NAME to the user or role identified by the value of GRANTEE.
+# SYSTEM_SCHEMATA
+SYSTEM_SCHEMATA_CATALOG_NAME=the name of the catalog of the described schema
+SYSTEM_SCHEMATA_SCHEMA_NAME=the unqualified schema name of the described schema
+SYSTEM_SCHEMATA_SCHEMA_OWNER=the authorization identifier that owns the schema.
+SYSTEM_SCHEMATA_DEFAULT_CHARACTER_SET_CATALOG=the catalog name of the default character set for columns and domains in the schema.
+SYSTEM_SCHEMATA_DEFAULT_CHARACTER_SET_SCHEMA=the unqualified schema name of the default character set for columns and domains in the schema.
+SYSTEM_SCHEMATA_DEFAULT_CHARACTER_SET_NAME=the qualified identifier of the default character set for columns and domains in the schemata.
+SYSTEM_SCHEMATA_SQL_PATH=the character representation of the schema's <schema path specification>, or null if it cannot be represented without truncation
+
diff --git a/src/org/hsqldb/resources/content-types.properties b/src/org/hsqldb/resources/content-types.properties
new file mode 100644
index 0000000..e3e5ca6
--- /dev/null
+++ b/src/org/hsqldb/resources/content-types.properties
@@ -0,0 +1,584 @@
+# default content-types with alternates commented
+3dm=x-world/x-3dmf
+3dmf=x-world/x-3dmf
+a=application/octet-stream
+aab=application/x-authorware-bin
+aam=application/x-authorware-map
+aas=application/x-authorware-seg
+abc=text/vndabc
+acgi=text/html
+afl=video/animaflex
+ai=application/postscript
+aif=audio/aiff
+#aif=audio/x-aiff
+aifc=audio/aiff
+#aifc=audio/x-aiff
+aiff=audio/aiff
+#aiff=audio/x-aiff
+aim=application/x-aim
+aip=text/x-audiosoft-intra
+ani=application/x-navi-animation
+aos=application/x-nokia-9000-communicator-add-on-software
+aps=application/mime
+arc=application/octet-stream
+arj=application/arj
+#arj=application/octet-stream
+art=image/x-jg
+asf=video/x-ms-asf
+asm=text/x-asm
+asp=text/asp
+asx=application/x-mplayer2
+#asx=video/x-ms-asf,video/x-ms-asf-plugin
+au=audio/basic
+#ua=audio/x-au
+avi=application/x-troff-msvideo
+#avi=video/avi,video/msvideo,video/x-msvideo
+avs=video/avs-video
+bcpio=application/x-bcpio
+bin=application/mac-binary
+#bin=application/macbinary,application/octet-stream,application/x-binary,application/x-macbinary
+bm=image/bmp
+bmp=image/bmp
+#bmp=image/x-windows-bmp
+boo=application/book
+book=application/book
+boz=application/x-bzip2
+bsh=application/x-bsh
+bz=application/x-bzip
+bz2=application/x-bzip2
+c=text/plain
+#c=text/x-c
+c++=text/plain
+cat=application/vndms-pkiseccat
+cc=text/plain
+#cc=text/x-c
+ccad=application/clariscad
+cco=application/x-cocoa
+cdf=application/cdf
+#cdf=application/x-cdf,application/x-netcdf
+cer=application/pkix-cert
+#cer=application/x-x509-ca-cert
+cha=application/x-chat
+chat=application/x-chat
+class=application/octet-stream
+#class=application/java-vm,application/java,application/java-byte-code,application/x-java-class
+com=application/octet-stream
+#com=text/plain
+conf=text/plain
+cpio=application/x-cpio
+cpp=text/x-c
+cpt=application/mac-compactpro
+#cpt=application/x-compactpro,application/x-cpt
+crl=application/pkcs-crl
+crl=application/pkix-crl
+crt=application/pkix-cert
+#crt=application/x-x509-ca-cert,application/x-x509-user-cert
+csh=application/x-csh
+#csh=text/x-scriptcsh
+css=text/css
+#css=application/x-pointplus
+cxx=text/plain
+dcr=application/x-director
+deepv=application/x-deepv
+def=text/plain
+der=application/x-x509-ca-cert
+dif=video/x-dv
+#dif=application/x-director
+dl=video/dl
+#dl=video/x-dl
+doc=application/msword
+dot=application/msword
+dp=application/commonground
+drw=application/drafting
+dump=application/octet-stream
+dv=video/x-dv
+dvi=application/x-dvi
+dwf=drawing/x-dwf
+#dwf=model/vnddwf
+dwg=application/acad
+#dwg=image/vnddwg,image/x-dwg
+dxf=application/dxf
+#dxf=image/vnddwg,image/x-dwg
+dxr=application/x-director
+el=text/x-scriptelisp
+elc=application/x-bytecodeelisp
+#elc=application/x-elc
+env=application/x-envoy
+eps=application/postscript
+es=application/x-esrehber
+etx=text/x-setext
+evy=application/envoy
+#env=application/x-envoy
+exe=application/octet-stream
+f=text/plain
+#f=text/x-fortran
+f77=text/x-fortran
+f90=text/x-fortran
+fdf=application/vndfdf
+fif=application/fractals
+#fif=image/fif
+fli=video/fli
+#fli=video/x-fli
+flo=image/florian
+flx=text/vndfmiflexstor
+fmf=video/x-atomic3d-feature
+for=text/plain
+#for=text/x-fortran
+fpx=image/vndfpx
+#fpx=image/vndnet-fpx
+frl=application/freeloader
+funk=audio/make
+g=text/plain
+g3=image/g3fax
+gif=image/gif
+gl=video/gl
+#gl=video/x-gl
+gsd=audio/x-gsm
+gsm=audio/x-gsm
+gsp=application/x-gsp
+gss=application/x-gss
+gtar=application/x-gtar
+gz=application/x-compressed
+#gz=application/x-gzip
+gzip=application/x-gzip
+#gzip=multipart/x-gzip
+h=text/plain
+#h=text/x-h
+hdf=application/x-hdf
+help=application/x-helpfile
+hgl=application/vndhp-HPGL
+hh=text/plain
+#hh=text/x-h
+hlb=text/x-script
+hlp=application/hlp
+#hlp=application/x-helpfile,application/x-winhelp
+hpg=application/vndhp-HPGL
+hpgl=application/vndhp-HPGL
+hqx=application/binhex
+#hqx=application/binhex4,application/mac-binhex,application/mac-binhex40,application/x-binhex40,application/x-mac-binhex40
+hta=application/hta
+htc=text/x-component
+htm=text/html
+html=text/html
+htmls=text/html
+htt=text/webviewhtml
+htx=text/html
+ice=x-conference/x-cooltalk
+ico=image/x-icon
+idc=text/plain
+ief=image/ief
+iefs=image/ief
+iges=application/iges
+#iges=model/iges
+igs=application/iges
+#igs=model/iges
+ima=application/x-ima
+imap=application/x-httpd-imap
+inf=application/inf
+ins=application/x-internet-signup
+ip=application/x-ip2
+isu=video/x-isvideo
+it=audio/it
+iv=application/x-inventor
+ivr=i-world/i-vrml
+ivy=application/x-livescreen
+jam=audio/x-jam
+jav=text/plain
+#jav=text/x-java-source
+java=text/plain
+#java=text/x-java-source
+jcm=application/x-java-commerce
+jfif=image/jpeg
+#jfif=image/pjpeg
+jfif-tbnl=image/jpeg
+jpe=image/jpeg
+#jpe=image/pjpeg
+jpeg=image/jpeg
+#jpeg=image/pjpeg
+jpg=image/jpeg
+#jpg=image/pjpeg
+jps=image/x-jps
+js=application/x-javascript
+jut=image/jutvision
+kar=audio/midi
+#kar=music/x-karaoke
+ksh=application/x-ksh
+#ksh=text/x-scriptksh
+la=audio/nspaudio
+#la=audio/x-nspaudio
+lam=audio/x-liveaudio
+latex=application/x-latex
+lha=application/lha
+#lha=application/octet-stream,application/x-lha
+lhx=application/octet-stream
+list=text/plain
+lma=audio/nspaudio
+#lma=audio/x-nspaudio
+log=text/plain
+lsp=application/x-lisp
+#lsp=text/x-scriptlisp
+lst=text/plain
+lsx=text/x-la-asf
+ltx=application/x-latex
+lzh=application/octet-stream
+#lzh=application/x-lzh
+lzx=application/lzx
+#lsx=application/octet-stream,application/x-lzx
+m=text/plain
+#m=text/x-m
+m1v=video/mpeg
+m2a=audio/mpeg
+m2v=video/mpeg
+m3u=audio/x-mpequrl
+man=application/x-troff-man
+map=application/x-navimap
+mar=text/plain
+mbd=application/mbedlet
+mc$=application/x-magic-cap-package-10
+mcd=application/mcad
+#mcd=application/x-mathcad
+mcf=image/vasa
+#mcf=text/mcf
+mcp=application/netmc
+me=application/x-troff-me
+mht=message/rfc822
+mhtml=message/rfc822
+mid=application/x-midi
+#mid=audio/midi,audio/x-mid,audio/x-midi,music/crescendo,x-music/x-midi
+midi=application/x-midi
+#midi=audio/midi,audio/x-mid,audio/x-midi,music/crescendo,x-music/x-midi
+mif=application/x-frame
+#mif=application/x-mif
+mime=message/rfc822
+mime=www/mime
+mjf=audio/x-vndAudioExplosionMjuiceMediaFile
+mjpg=video/x-motion-jpeg
+mm=application/base64
+#mm=application/x-meme
+mme=application/base64
+mod=audio/mod
+#mod=audio/x-mod
+moov=video/quicktime
+mov=video/quicktime
+movie=video/x-sgi-movie
+mp2=audio/mpeg
+#mp2=audio/x-mpeg,video/mpeg,video/x-mpeg,video/x-mpeq2a
+mp3=audio/mpeg3
+#mp3=audio/x-mpeg-3,video/mpeg,video/x-mpeg
+mpa=audio/mpeg
+#mpa=video/mpeg
+mpc=application/x-project
+mpe=video/mpeg
+mpeg=video/mpeg
+mpg=video/mpeg
+#mpg=audio/mpeg
+mpga=audio/mpeg
+mpp=application/vndms-project
+mpt=application/x-project
+mpv=application/x-project
+mpx=application/x-project
+mrc=application/marc
+ms=application/x-troff-ms
+mv=video/x-sgi-movie
+my=audio/make
+mzz=application/x-vndAudioExplosionmzz
+nap=image/naplps
+naplps=image/naplps
+nc=application/x-netcdf
+ncm=application/vndnokiaconfiguration-message
+nif=image/x-niff
+niff=image/x-niff
+nix=application/x-mix-transfer
+nsc=application/x-conference
+nvd=application/x-navidoc
+o=application/octet-stream
+oda=application/oda
+omc=application/x-omc
+omcd=application/x-omcdatamaker
+omcr=application/x-omcregerator
+p=text/x-pascal
+p10=application/pkcs10
+#p10=application/x-pkcs10
+p12=application/pkcs-12
+#p12=application/x-pkcs12
+p7a=application/x-pkcs7-signature
+p7c=application/pkcs7-mime
+#p7c=application/x-pkcs7-mime
+p7m=application/pkcs7-mime
+#p7m=application/x-pkcs7-mime
+p7r=application/x-pkcs7-certreqresp
+p7s=application/pkcs7-signature
+part=application/pro_eng
+pas=text/pascal
+pbm=image/x-portable-bitmap
+pcl=application/vndhp-PCL
+#pcl=application/x-pcl
+pct=image/x-pict
+pcx=image/x-pcx
+pdb=chemical/x-pdb
+pdf=application/pdf
+pfunk=audio/make
+#pfunk=audio/makemyfunk
+pgm=image/x-portable-graymap
+#pgm=image/x-portable-greymap
+pic=image/pict
+pict=image/pict
+pkg=application/x-newton-compatible-pkg
+pko=application/vndms-pkipko
+pl=text/plain
+#pl=text/x-scriptperl
+plx=application/x-PiXCLscript
+pm=image/x-xpixmap
+pm=text/x-scriptperl-module
+pm4=application/x-pagemaker
+pm5=application/x-pagemaker
+png=image/png
+pnm=application/x-portable-anymap
+#pnm=image/x-portable-anymap
+pot=application/mspowerpoint
+#pot=application/vndms-powerpoint
+pov=model/x-pov
+ppa=application/vndms-powerpoint
+ppm=image/x-portable-pixmap
+pps=application/mspowerpoint
+#pps=application/vndms-powerpoint
+ppt=application/mspowerpoint
+#ppt=application/powerpoint,application/vndms-powerpoint,application/x-mspowerpoint
+ppz=application/mspowerpoint
+pre=application/x-freelance
+prt=application/pro_eng
+ps=application/postscript
+psd=application/octet-stream
+pvu=paleovu/x-pv
+pwz=application/vndms-powerpoint
+py=text/x-scriptphyton
+pyc=applicaiton/x-bytecodepython
+qcp=audio/vndqcelp
+qd3=x-world/x-3dmf
+qd3d=x-world/x-3dmf
+qif=image/x-quicktime
+qt=video/quicktime
+qtc=video/x-qtc
+qti=image/x-quicktime
+qtif=image/x-quicktime
+ra=audio/x-pn-realaudio
+#ra=audio/x-pn-realaudio-plugin,audio/x-realaudio
+ram=audio/x-pn-realaudio
+ras=application/x-cmu-raster
+ras=image/cmu-raster
+#ras=image/x-cmu-raster
+rast=image/cmu-raster
+rexx=text/x-scriptrexx
+rf=image/vndrn-realflash
+rgb=image/x-rgb
+rm=application/vndrn-realmedia
+#rm=audio/x-pn-realaudio
+rmi=audio/mid
+rmm=audio/x-pn-realaudio
+rmp=audio/x-pn-realaudio
+rmp=audio/x-pn-realaudio-plugin
+rng=application/ringing-tones
+rng=application/vndnokiaringing-tone
+rnx=application/vndrn-realplayer
+roff=application/x-troff
+rp=image/vndrn-realpix
+rpm=audio/x-pn-realaudio-plugin
+rt=text/richtext
+rt=text/vndrn-realtext
+rtf=application/rtf
+#rtf=application/x-rtf,text/richtext
+rtx=application/rtf
+#rtx=text/richtext
+rv=video/vndrn-realvideo
+s=text/x-asm
+s3m=audio/s3m
+saveme=application/octet-stream
+sbk=application/x-tbook
+scm=application/x-lotusscreencam
+#scm=text/x-scriptguile,text/x-scriptscheme,video/x-scm
+sdml=text/plain
+sdp=application/sdp
+#sdp=application/x-sdp
+sdr=application/sounder
+sea=application/sea
+#sea=application/x-sea
+set=application/set
+sgm=text/sgml
+#sgm=text/x-sgml
+sgml=text/sgml
+#sgml=text/x-sgml
+sh=application/x-bsh
+#sh=application/x-sh,text/x-scriptsh,application/x-shar
+shar=application/x-bsh
+#shar=application/x-shar
+shtml=text/html
+#shtml=text/x-server-parsed-html
+sid=audio/x-psid
+sit=application/x-sit
+#sit=application/x-stuffit
+skd=application/x-koan
+skm=application/x-koan
+skp=application/x-koan
+skt=application/x-koan
+sl=application/x-seelogo
+smi=application/smil
+smil=application/smil
+snd=audio/basic
+#snd=audio/x-adpcm
+sol=application/solids
+spc=application/x-pkcs7-certificates
+#spc=text/x-speech
+spl=application/futuresplash
+spr=application/x-sprite
+sprite=application/x-sprite
+src=application/x-wais-source
+ssi=text/x-server-parsed-html
+ssm=application/streamingmedia
+sst=application/vndms-pkicertstore
+step=application/step
+stl=application/sla
+#stl=application/vndms-pkistl,application/x-navistyle
+stp=application/step
+sv4cpio=application/x-sv4cpio
+sv4crc=application/x-sv4crc
+svf=image/vnddwg
+#svf=image/x-dwg,application/x-world
+svr=x-world/x-svr
+swf=application/x-shockwave-flash
+t=application/x-troff
+talk=text/x-speech
+tar=application/x-tar
+tbk=application/toolbook
+#tbk=application/x-tbook
+tcl=application/x-tcl
+#tcl=text/x-scripttcl
+tcsh=text/x-scripttcsh
+tex=application/x-tex
+texi=application/x-texinfo
+texinfo=application/x-texinfo
+text=text/plain
+tgz=application/gnutar
+#tgz=application/x-compressed
+tif=image/tiff
+#tif=image/x-tiff,image/tiff,image/x-tiff
+tr=application/x-troff
+tsi=audio/tsp-audio
+tsp=application/dsptype
+tsp=audio/tsplayer
+tsv=text/tab-separated-values
+turbot=image/florian
+txt=text/plain
+uil=text/x-uil
+uni=text/uri-list
+unis=text/uri-list
+unv=application/i-deas
+uri=text/uri-list
+uris=text/uri-list
+ustar=application/x-ustar
+#ustar=multipart/x-ustar
+uu=application/octet-stream
+#uu=text/x-uuencode
+uue=text/x-uuencode
+vcd=application/x-cdlink
+vcs=text/x-vCalendar
+vda=application/vda
+vdo=video/vdo
+vew=application/groupwise
+viv=video/vivo
+#viv=video/vndvivo,video/vivo,video/vndvivo
+vmd=application/vocaltec-media-desc
+vmf=application/vocaltec-media-file
+voc=audio/voc
+#voc=audio/x-voc
+vos=video/vosaic
+vox=audio/voxware
+vqe=audio/x-twinvq-plugin
+vqf=audio/x-twinvq
+vql=audio/x-twinvq-plugin
+vrml=application/x-vrml
+#vrml=model/vrml,x-world/x-vrml
+vrt=x-world/x-vrt
+vsd=application/x-visio
+vst=application/x-visio
+vsw=application/x-visio
+w60=application/wordperfect60
+w61=application/wordperfect61
+w6w=application/msword
+wav=audio/wav
+#wav=audio/x-wav
+wb1=application/x-qpro
+wbmp=image/vndwapwbmp
+web=application/vndxara
+wiz=application/msword
+wk1=application/x-123
+wmf=windows/metafile
+wml=text/vndwapwml
+wmlc=application/vndwapwmlc
+wmls=text/vndwapwmlscript
+wmlsc=application/vndwapwmlscriptc
+word=application/msword
+wp=application/wordperfect
+wp5=application/wordperfect
+wp5=application/wordperfect60
+wp6=application/wordperfect
+wpd=application/wordperfect
+#wpd=application/x-wpwin
+wq1=application/x-lotus
+wri=application/mswrite
+#wri=application/x-wri
+wrl=application/x-world
+#wrl=model/vrml,x-world/x-vrml
+wrz=model/vrml
+#wrz=x-world/x-vrml
+wsc=text/scriplet
+wsrc=application/x-wais-source
+wtk=application/x-wintalk
+xbm=image/x-xbitmap
+#xbm=image/x-xbm,image/xbm
+xdr=video/x-amt-demorun
+xgz=xgl/drawing
+xif=image/vndxiff
+xl=application/excel
+xla=application/excel
+#xla=application/x-excel,application/x-msexcel
+xlb=application/excel
+#xlb=application/vndms-excel,application/x-excel
+xlc=application/excel
+#xlc=application/vndms-excel,application/x-excel
+xld=application/excel
+#xld=application/x-excel
+xlk=application/excel
+#xlk=application/x-excel
+xll=application/excel
+#xll=application/vndms-excel,application/x-excel
+xlm=application/excel
+#xlm=application/vndms-excel,application/x-excel
+xls=application/excel
+#xls=application/vndms-excel,application/x-excel,application/x-msexcel
+xlt=application/excel
+#xlt=application/x-excel
+xlv=application/excel
+#xlv=application/x-excel
+xlw=application/excel
+#xlw=application/vndms-excel,application/x-excel,application/x-msexcel
+xm=audio/xm
+xml=application/xml
+#xml=text/xml
+xmz=xgl/movie
+xpix=application/x-vndls-xpix
+xpm=image/x-xpixmap
+#xpm=image/xpm
+x-png=image/png
+xsr=video/x-amt-showrun
+xwd=image/x-xwd
+#xwd=image/x-xwindowdump
+xyz=chemical/x-pdb
+z=application/x-compress
+#z=application/x-compressed
+zip=application/x-zip-compressed
+#zip=zip=application/x-compressed,application/zip,multipart/x-zip
+zoo=application/octet-stream
+zsh=text/x-scriptzsh
+
+
+
diff --git a/src/org/hsqldb/resources/data-type-create-parameters.properties b/src/org/hsqldb/resources/data-type-create-parameters.properties
new file mode 100644
index 0000000..a3e3e17
--- /dev/null
+++ b/src/org/hsqldb/resources/data-type-create-parameters.properties
@@ -0,0 +1,3 @@
+# default data-type-create-parameters
+SIZED=length
+DECIMAL=precision,scale
diff --git a/src/org/hsqldb/resources/data-type-names.properties b/src/org/hsqldb/resources/data-type-names.properties
new file mode 100644
index 0000000..9fba4b8
--- /dev/null
+++ b/src/org/hsqldb/resources/data-type-names.properties
@@ -0,0 +1,34 @@
+# default data-type-names
+ARRAY=ARRAY
+BIGINT=BIGINT
+BIGINT_IDENTITY=BIGINT IDENTITY
+BINARY=BINARY
+BOOLEAN=BOOLEAN
+BLOB=BLOB
+CHAR=CHAR
+CLOB=CLOB
+DATALINK=DATALINK
+DATE=DATE
+DECIMAL=DECIMAL
+DISTINCT=DISTINCT
+DOUBLE=DOUBLE
+FLOAT=FLOAT
+INTEGER=INTEGER
+INTEGER_IDENTITY=INTEGER IDENTITY
+JAVA_OBJECT=JAVA_OBJECT
+LONGVARBINARY=LONGVARBINARY
+LONGVARCHAR=LONGVARCHAR
+NULL=NULL
+NUMERIC=NUMERIC
+OTHER=OTHER
+REAL=REAL
+REF=REF
+SMALLINT=SMALLINT
+STRUCT=STRUCT
+TIME=TIME
+TIMESTAMP=TIMESTAMP
+TINYINT=TINYINT
+VARBINARY=VARBINARY
+VARCHAR_IGNORECASE=VARCHAR_IGNORECASE
+VARCHAR=VARCHAR
+XML=XML
diff --git a/src/org/hsqldb/resources/data-type-remarks.properties b/src/org/hsqldb/resources/data-type-remarks.properties
new file mode 100644
index 0000000..838840a
--- /dev/null
+++ b/src/org/hsqldb/resources/data-type-remarks.properties
@@ -0,0 +1,8 @@
+# default data-type-remarks
+BINARY=legal literal character range: { '0'..'9' | 'a'..'f' | 'A'..'F' }; must be a case-insensitive hex value string consisting of a whole number of octets, e.g. '00af0b12'
+DATALINK=legal literal formats: '[scheme:]scheme-specific-part[#fragment]' (see http://www.ietf.org/rfc/rfc2396.txt and http://www.ietf.org/rfc/rfc2732.txt)
+DATE=legal literal formats: [ {d ] 'yyyy-mm-dd' [ } ]
+OTHER=legal literal character range: { '0'..'9' | 'a'..'f' | 'A'..'F' }; must be a case-insentivie hex value string consisting of a whole number of octets representing a valid serialization of a Java object
+TIME=legal literal formats: [ {t ] 'hh:mm:ss' [ } ]
+TIMESTAMP=legal literal formats: [ {ts ] 'yyyy-mm-dd[ hh:mm:ss[.fffffffff]]' [ } ]
+XML=legal literal formats: '...'; must be a valid XML document with SQL<=>XML encodings as descibed in WG3:DRS-020 = H2-2002-365, WD 9075-14 (SQL/XML), August, 2002
diff --git a/src/org/hsqldb/resources/information-schema.sql b/src/org/hsqldb/resources/information-schema.sql
new file mode 100644
index 0000000..b8b03ff
--- /dev/null
+++ b/src/org/hsqldb/resources/information-schema.sql
@@ -0,0 +1,544 @@
+-- author Fred Toussi (fredt@users dot sourceforge.net) version 1.9.0
+/*system_procedures*/
+SELECT ROUTINE_CATALOG AS PROCEDURE_CAT, ROUTINE_SCHEMA AS PROCEDURE_SCHEM,
+ROUTINE_NAME AS PROCEDURE_NAME, 0, 0, 0,
+CAST( NULL AS VARCHAR(256)) AS REMARKS,
+CASE WHEN ROUTINE_TYPE = 'PROCEDURE' THEN 1 ELSE 2 END CASE AS PROCEDURE_TYPE,
+SPECIFIC_NAME FROM INFORMATION_SCHEMA.ROUTINES
+
+/*data_type_privileges*/
+SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME,
+'TABLE', DTD_IDENTIFIER
+FROM COLUMNS
+UNION
+SELECT DOMAIN_CATALOG, DOMAIN_SCHEMA, DOMAIN_NAME,
+'DOMAIN', DTD_IDENTIFIER
+FROM DOMAINS
+UNION
+SELECT SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME,
+'ROUTINE', DTD_IDENTIFIER
+FROM PARAMETERS
+UNION
+SELECT SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME,
+'ROUTINE', DTD_IDENTIFIER
+FROM ROUTINES
+WHERE DTD_IDENTIFIER IS NOT NULL
+UNION
+SELECT USER_DEFINED_TYPE_CATALOG, USER_DEFINED_TYPE_SCHEMA,
+USER_DEFINED_TYPE_NAME, 'USER-DEFINED TYPE', SOURCE_DTD_IDENTIFIER
+FROM USER_DEFINED_TYPES
+WHERE SOURCE_DTD_IDENTIFIER IS NOT NULL
+UNION
+SELECT USER_DEFINED_TYPE_CATALOG, USER_DEFINED_TYPE_SCHEMA,
+USER_DEFINED_TYPE_NAME, 'USER-DEFINED TYPE', REF_DTD_IDENTIFIER
+FROM USER_DEFINED_TYPES
+WHERE REF_DTD_IDENTIFIER IS NOT NULL;
+/*sql_features*/
+VALUES
+('B011', 'Embedded Ada', '', '', 'NO', CAST(NULL AS CHARACTER), ''),
+('B012', 'Embedded C', '', '', 'NO', NULL, ''),
+('B013', 'Embedded COBOL', '', '', 'NO', NULL, ''),
+('B014', 'Embedded Fortran', '', '', 'NO', NULL, ''),
+('B015', 'Embedded MUMPS', '', '', 'NO', NULL, ''),
+('B016', 'Embedded Pascal', '', '', 'NO', NULL, ''),
+('B017', 'Embedded PL/I', '', '', 'NO', NULL, ''),
+('B021', 'Direct SQL', '', '', 'YES', NULL, ''),
+('B031', 'Basic dynamic SQL', '', '', 'NO', NULL, ''),
+('B032', 'Extended dynamic SQL', '', '', 'NO', NULL, ''),
+('B032', 'Extended dynamic SQL', '01', 'describe input statement', 'NO', NULL, ''),
+('B033', 'Untyped SQL-invoked function arguments', '', '', 'NO', NULL, ''),
+('B034', 'Dynamic specification of cursor attributes', '', '', 'NO', NULL, ''),
+('B041', 'Extensions to embedded SQL exception declarations', '', '', 'NO', NULL, ''),
+('B051', 'Enhanced execution rights', '', '', 'NO', NULL, ''),
+('B111', 'Module language Ada', '', '', 'NO', NULL, ''),
+('B112', 'Module language C', '', '', 'NO', NULL, ''),
+('B113', 'Module language COBOL', '', '', 'NO', NULL, ''),
+('B114', 'Module language Fortran', '', '', 'NO', NULL, ''),
+('B115', 'Module language MUMPS', '', '', 'NO', NULL, ''),
+('B116', 'Module language Pascal', '', '', 'NO', NULL, ''),
+('B117', 'Module language PL/I', '', '', 'NO', NULL, ''),
+('B121', 'Routine language Ada', '', '', 'NO', NULL, ''),
+('B122', 'Routine language C', '', '', 'NO', NULL, ''),
+('B123', 'Routine language COBOL', '', '', 'NO', NULL, ''),
+('B124', 'Routine language Fortran', '', '', 'NO', NULL, ''),
+('B125', 'Routine language MUMPS', '', '', 'NO', NULL, ''),
+('B126', 'Routine language Pascal', '', '', 'NO', NULL, ''),
+('B127', 'Routine language PL/I', '', '', 'NO', NULL, ''),
+('B128', 'Routine language SQL', '', '', 'YES', NULL, 'only schema-contained routines'),
+('C011', 'Call-Level Interface', '', '', 'YES', NULL, 'via JDBC'),
+('E011', 'Numeric data types', '', '', 'YES', NULL, ''),
+('E011', 'Numeric data types', '01', 'INTEGER and SMALLINT data types', 'YES', NULL, ''),
+('E011', 'Numeric data types', '02', 'REAL, DOUBLE PRECISION, and FLOAT data types', 'YES', NULL, ''),
+('E011', 'Numeric data types', '03', 'DECIMAL and NUMERIC data types', 'YES', NULL, ''),
+('E011', 'Numeric data types', '04', 'Arithmetic operators', 'YES', NULL, ''),
+('E011', 'Numeric data types', '05', 'Numeric comparison', 'YES', NULL, ''),
+('E011', 'Numeric data types', '06', 'Implicit casting among the numeric data types', 'YES', NULL, ''),
+('E021', 'Character data types', '', '', 'YES', NULL, ''),
+('E021', 'Character string types', '01', 'CHARACTER data type', 'YES', NULL, ''),
+('E021', 'Character string types', '02', 'CHARACTER VARYING data type', 'YES', NULL, ''),
+('E021', 'Character string types', '03', 'Character literals', 'YES', NULL, ''),
+('E021', 'Character string types', '04', 'CHARACTER_LENGTH function', 'YES', NULL, ''),
+('E021', 'Character string types', '05', 'OCTET_LENGTH function', 'YES', NULL, ''),
+('E021', 'Character string types', '06', 'SUBSTRING function', 'YES', NULL, ''),
+('E021', 'Character string types', '07', 'Character concatenation', 'YES', NULL, ''),
+('E021', 'Character string types', '08', 'UPPER and LOWER functions', 'YES', NULL, ''),
+('E021', 'Character string types', '09', 'TRIM function', 'YES', NULL, ''),
+('E021', 'Character string types', '10', 'Implicit casting among the character string types', 'YES', NULL, ''),
+('E021', 'Character string types', '11', 'POSITION function', 'YES', NULL, ''),
+('E021', 'Character string types', '12', 'Character comparison', 'YES', NULL, ''),
+('E031', 'Identifiers', '', '', 'YES', NULL, ''),
+('E031', 'Identifiers', '01', 'Delimited identifiers', 'YES', NULL, ''),
+('E031', 'Identifiers', '02', 'Lower case identifiers', 'YES', NULL, ''),
+('E031', 'Identifiers', '03', 'Trailing underscore', 'YES', NULL, ''),
+('E051', 'Basic query specification', '', '', 'YES', NULL, ''),
+('E051', 'Basic query specification', '01', 'SELECT DISTINCT', 'YES', NULL, ''),
+('E051', 'Basic query specification', '02', 'GROUP BY clause', 'YES', NULL, ''),
+('E051', 'Basic query specification', '04', 'GROUP BY can contain columns not in <select list>', 'YES', NULL, ''),
+('E051', 'Basic query specification', '05', 'Select list items can be renamed', 'YES', NULL, ''),
+('E051', 'Basic query specification', '06', 'HAVING clause', 'YES', NULL, ''),
+('E051', 'Basic query specification', '07', 'Qualified * in select list', 'YES', NULL, ''),
+('E051', 'Basic query specification', '08', 'Correlation names in the FROM clause', 'YES', NULL, ''),
+('E051', 'Basic query specification', '09', 'Rename columns in the FROM clause', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '', '', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '01', 'Comparison predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '02', 'BETWEEN predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '03', 'IN predicate with list of values', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '04', 'LIKE predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '05', 'LIKE predicate ESCAPE clause', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '06', 'NULL predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '07', 'Quantified comparison predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '08', 'EXISTS predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '09', 'Subqueries in comparison predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '11', 'Subqueries in IN predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '12', 'Subqueries in quantified comparison predicate', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '13', 'Correlated subqueries', 'YES', NULL, ''),
+('E061', 'Basic predicates and search conditions', '14', 'Search condition', 'YES', NULL, ''),
+('E071', 'Basic query expressions', '', '', 'YES', NULL, ''),
+('E071', 'Basic query expressions', '01', 'UNION DISTINCT table operator', 'YES', NULL, ''),
+('E071', 'Basic query expressions', '02', 'UNION ALL table operator', 'YES', NULL, ''),
+('E071', 'Basic query expressions', '03', 'EXCEPT DISTINCT table operator', 'YES', NULL, ''),
+('E071', 'Basic query expressions', '05', 'Columns combined via table operators need not have exactly the same data type', 'YES', NULL, ''),
+('E071', 'Basic query expressions', '06', 'Table operators in subqueries', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '', '', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '01', 'SELECT privilege', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '02', 'DELETE privilege', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '03', 'INSERT privilege at the table level', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '04', 'UPDATE privilege at the table level', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '05', 'UPDATE privilege at the column level', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '06', 'REFERENCES privilege at the table level', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '07', 'REFERENCES privilege at the column level', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '08', 'WITH GRANT OPTION', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '09', 'USAGE privilege', 'YES', NULL, ''),
+('E081', 'Basic Privileges', '10', 'EXECUTE privilege', 'YES', NULL, ''),
+('E091', 'Set functions', '', '', 'YES', NULL, ''),
+('E091', 'Set functions', '01', 'AVG', 'YES', NULL, ''),
+('E091', 'Set functions', '02', 'COUNT', 'YES', NULL, ''),
+('E091', 'Set functions', '03', 'MAX', 'YES', NULL, ''),
+('E091', 'Set functions', '04', 'MIN', 'YES', NULL, ''),
+('E091', 'Set functions', '05', 'SUM', 'YES', NULL, ''),
+('E091', 'Set functions', '06', 'ALL quantifier', 'YES', NULL, ''),
+('E091', 'Set functions', '07', 'DISTINCT quantifier', 'YES', NULL, ''),
+('E101', 'Basic data manipulation', '', '', 'YES', NULL, ''),
+('E101', 'Basic data manipulation', '01', 'INSERT statement', 'YES', NULL, ''),
+('E101', 'Basic data manipulation', '03', 'Searched UPDATE statement', 'YES', NULL, ''),
+('E101', 'Basic data manipulation', '04', 'Searched DELETE statement', 'YES', NULL, ''),
+('E111', 'Single row SELECT statement', '', '', 'YES', NULL, ''),
+('E121', 'Basic cursor support', '', '', 'NO', NULL, 'yes via JDBC'),
+('E121', 'Basic cursor support', '01', 'DECLARE CURSOR', 'NO', NULL, 'yes via JDBC'),
+('E121', 'Basic cursor support', '02', 'ORDER BY columns need not be in select list', 'YES', NULL, ''),
+('E121', 'Basic cursor support', '03', 'Value expressions in ORDER BY clause', 'YES', NULL, ''),
+('E121', 'Basic cursor support', '04', 'OPEN statement', 'NO', NULL, 'yes via JDBC'),
+('E121', 'Basic cursor support', '06', 'Positioned UPDATE statement', 'NO', NULL, 'yes via JDBC'),
+('E121', 'Basic cursor support', '07', 'Positioned DELETE statement', 'NO', NULL, 'yes via JDBC'),
+('E121', 'Basic cursor support', '08', 'CLOSE statement', 'NO', NULL, 'yes via JDBC'),
+('E121', 'Basic cursor support', '10', 'FETCH statement implicit NEXT', 'NO', NULL, 'yes via JDBC'),
+('E121', 'Basic cursor support', '17', 'WITH HOLD cursors', 'NO', NULL, 'yes via JDBC'),
+('E131', 'Null value support (nulls in lieu of values)', '', '', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '', '', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '01', 'NOT NULL constraints', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '02', 'UNIQUE constraints of NOT NULL columns', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '03', 'PRIMARY KEY constraints', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '04', 'Basic FOREIGN KEY constraint with the NO ACTION default for both referential delete action and referential update action', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '06', 'CHECK constraints', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '07', 'Column defaults', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '08', 'NOT NULL inferred on PRIMARY KEY', 'YES', NULL, ''),
+('E141', 'Basic integrity constraints', '10', 'Names in a foreign key can be specified in any order', 'YES', NULL, ''),
+('E151', 'Transaction support', '', '', 'YES', NULL, ''),
+('E151', 'Transaction support', '01', 'COMMIT statement', 'YES', NULL, ''),
+('E151', 'Transaction support', '02', 'ROLLBACK statement', 'YES', NULL, ''),
+('E152', 'Basic SET TRANSACTION statement', '', '', 'YES', NULL, ''),
+('E152', 'Basic SET TRANSACTION statement', '01', 'SET TRANSACTION statement: ISOLATION LEVEL SERIALIZABLE clause', 'YES', NULL, ''),
+('E152', 'Basic SET TRANSACTION statement', '02', 'SET TRANSACTION statement: READ ONLY and READ WRITE clauses', 'YES', NULL, ''),
+('E153', 'Updatable queries with subqueries', '', '', 'YES', NULL, ''),
+('E161', 'SQL comments using leading double minus', '', '', 'YES', NULL, ''),
+('E171', 'SQLSTATE support', '', '', 'YES', NULL, ''),
+('E182', 'Module language', '', '', 'YES', NULL, 'only schema contained routines'),
+('F021', 'Basic information schema', '', '', 'YES', NULL, ''),
+('F021', 'Basic information schema', '01', 'COLUMNS view', 'YES', NULL, ''),
+('F021', 'Basic information schema', '02', 'TABLES view', 'YES', NULL, ''),
+('T655', 'Cyclically dependent routines', '', '', 'NO', NULL, ''),
+('F021', 'Basic information schema', '03', 'VIEWS view', 'YES', NULL, ''),
+('F021', 'Basic information schema', '04', 'TABLE_CONSTRAINTS view', 'YES', NULL, ''),
+('F021', 'Basic information schema', '05', 'REFERENTIAL_CONSTRAINTS view', 'YES', NULL, ''),
+('F021', 'Basic information schema', '06', 'CHECK_CONSTRAINTS view', 'YES', NULL, ''),
+('F031', 'Basic schema manipulation', '', '', 'YES', NULL, ''),
+('F031', 'Basic schema manipulation', '01', 'CREATE TABLE statement to create persistent base tables', 'YES', NULL, ''),
+('F031', 'Basic schema manipulation', '02', 'CREATE VIEW statement', 'YES', NULL, ''),
+('F031', 'Basic schema manipulation', '03', 'GRANT statement', 'YES', NULL, ''),
+('F031', 'Basic schema manipulation', '04', 'ALTER TABLE statement: ADD COLUMN clause', 'YES', NULL, ''),
+('F031', 'Basic schema manipulation', '13', 'DROP TABLE statement: RESTRICT clause', 'YES', NULL, ''),
+('F031', 'Basic schema manipulation', '16', 'DROP VIEW statement: RESTRICT clause', 'YES', NULL, ''),
+('F031', 'Basic schema manipulation', '19', 'REVOKE statement: RESTRICT clause', 'YES', NULL, ''),
+('F032', 'CASCADE drop behavior', '', '', 'YES', NULL, ''),
+('F033', 'ALTER TABLE statement: DROP COLUMN clause', '', '', 'YES', NULL, ''),
+('F034', 'Extended REVOKE statement', '', '', 'YES', NULL, ''),
+('F034', 'Extended REVOKE statement', '01', 'REVOKE statement performed by other than the owner of a schema object', 'YES', NULL, ''),
+('F034', 'Extended REVOKE statement', '02', 'REVOKE statement: GRANT OPTION FOR clause', 'YES', NULL, ''),
+('F034', 'Extended REVOKE statement', '03', 'REVOKE statement to revoke a privilege that the grantee has WITH GRANT OPTION', 'YES', NULL, ''),
+('F041', 'Basic joined table', '', '', 'YES', NULL, ''),
+('F041', 'Basic joined table', '01', 'Inner join (but not necessarily the INNER keyword)', 'YES', NULL, ''),
+('F041', 'Basic joined table', '02', 'INNER keyword', 'YES', NULL, ''),
+('F041', 'Basic joined table', '03', 'LEFT OUTER JOIN', 'YES', NULL, ''),
+('F041', 'Basic joined table', '04', 'RIGHT OUTER JOIN', 'YES', NULL, ''),
+('F041', 'Basic joined table', '05', 'Outer joins can be nested', 'YES', NULL, ''),
+('F041', 'Basic joined table', '07', 'The inner table in a left or right outer join can also be used in an inner join', 'YES', NULL, ''),
+('F041', 'Basic joined table', '08', 'All comparison operators are supported (rather than just =)', 'YES', NULL, ''),
+('F051', 'Basic date and time', '', '', 'YES', NULL, ''),
+('F051', 'Basic date and time', '01', 'DATE data type (including support of DATE literal)', 'YES', NULL, ''),
+('F051', 'Basic date and time', '02', 'TIME data type (including support of TIME literal) with fractional seconds precision of at least 0', 'YES', NULL, ''),
+('F051', 'Basic date and time', '03', 'TIMESTAMP data type (including support of TIMESTAMP literal) with fractional seconds precision of at least 0 and 6', 'YES', NULL, ''),
+('F051', 'Basic date and time', '04', 'Comparison predicate on DATE, TIME, and TIMESTAMP data types', 'YES', NULL, ''),
+('F051', 'Basic date and time', '05', 'Explicit CAST between datetime types and character string types', 'YES', NULL, ''),
+('F051', 'Basic date and time', '06', 'CURRENT_DATE', 'YES', NULL, ''),
+('F051', 'Basic date and time', '07', 'LOCALTIME', 'YES', NULL, ''),
+('F051', 'Basic date and time', '08', 'LOCALTIMESTAMP', 'YES', NULL, ''),
+('F052', 'Intervals and datetime arithmetic', '', '', 'YES', NULL, ''),
+('F053', 'OVERLAPS predicate', '', '', 'YES', NULL, ''),
+('F081', 'UNION and EXCEPT in views', '', '', 'YES', NULL, ''),
+('F111', 'Isolation levels other than SERIALIZABLE', '', '', 'YES', NULL, ''),
+('F111', 'Isolation levels other than SERIALIZABLE', '01', 'READ UNCOMMITTED isolation level', 'YES', NULL, ''),
+('F111', 'Isolation levels other than SERIALIZABLE', '02', 'READ COMMITTED isolation level', 'YES', NULL, ''),
+('F111', 'Isolation levels other than SERIALIZABLE', '03', 'REPEATABLE READ isolation level', 'YES', NULL, ''),
+('F121', 'Basic diagnostics management', '', '', 'NO', NULL, ''),
+('F121', 'Basic diagnostics management', '01', 'GET DIAGNOSTICS statement', 'NO', NULL, ''),
+('F121', 'Basic diagnostics management', '02', 'SET TRANSACTION statement: DIAGNOSTICS SIZE clause', 'NO', NULL, ''),
+('F131', 'Grouped operations', '', '', 'YES', NULL, ''),
+('F131', 'Grouped operations', '01', 'WHERE, GROUP BY, and HAVING clauses supported in queries with grouped views', 'YES', NULL, ''),
+('F131', 'Grouped operations', '02', 'Multiple tables supported in queries with grouped views', 'YES', NULL, ''),
+('F131', 'Grouped operations', '03', 'Set functions supported in queries with grouped views', 'YES', NULL, ''),
+('F131', 'Grouped operations', '04', 'Subqueries with GROUP BY and HAVING clauses and grouped views', 'YES', NULL, ''),
+('F131', 'Grouped operations', '05', 'Single row SELECT with GROUP BY and HAVING clauses and grouped views', 'YES', NULL, ''),
+('F171', 'Multiple schemas per user', '', '', 'YES', NULL, ''),
+('F181', 'Multiple module support', '', '', 'NO', NULL, ''),
+('F191', 'Referential delete actions', '', '', 'YES', NULL, ''),
+('F201', 'CAST function', '', '', 'YES', NULL, ''),
+('F221', 'Explicit defaults', '', '', 'YES', NULL, ''),
+('F222', 'INSERT statement: DEFAULT VALUES clause', '', '', 'YES', NULL, ''),
+('F231', 'Privilege tables', '', '', 'YES', NULL, ''),
+('F231', 'Privilege tables', '01', 'TABLE_PRIVILEGES view', 'YES', NULL, ''),
+('F231', 'Privilege tables', '02', 'COLUMN_PRIVILEGES view', 'YES', NULL, ''),
+('F231', 'Privilege tables', '03', 'USAGE_PRIVILEGES view', 'YES', NULL, ''),
+('F251', 'Domain support', '', '', 'YES', NULL, ''),
+('F261', 'CASE expression', '', '', 'YES', NULL, ''),
+('F261', 'CASE expression', '01', 'Simple CASE', 'YES', NULL, ''),
+('F261', 'CASE expression', '02', 'Searched CASE', 'YES', NULL, ''),
+('F261', 'CASE expression', '03', 'NULLIF', 'YES', NULL, ''),
+('F261', 'CASE expression', '04', 'COALESCE', 'YES', NULL, ''),
+('F262', 'Extended CASE expression', '', '', 'YES', NULL, ''),
+('F263', 'Comma-separated predicates in simple CASE expression', '', '', 'YES', NULL, ''),
+('F271', 'Compound character literals', '', '', 'YES', NULL, ''),
+('F281', 'LIKE enhancements', '', '', 'YES', NULL, ''),
+('F291', 'UNIQUE predicate', '', '', 'YES', NULL, ''),
+('F301', 'CORRESPONDING in query expressions', '', '', 'YES', NULL, ''),
+('F302', 'INTERSECT table operator', '', '', 'YES', NULL, ''),
+('F302', 'INTERSECT table operator', '01', 'INTERSECT DISTINCT table operator', 'YES', NULL, ''),
+('F302', 'INTERSECT table operator', '02', 'INTERSECT ALL table operator', 'YES', NULL, ''),
+('F304', 'EXCEPT ALL table operator', '', '', 'YES', NULL, ''),
+('F311', 'Schema definition statement', '', '', 'YES', NULL, ''),
+('F311', 'Schema definition statement', '01', 'CREATE SCHEMA', 'YES', NULL, ''),
+('F311', 'Schema definition statement', '02', 'CREATE TABLE for persistent base tables', 'YES', NULL, ''),
+('F311', 'Schema definition statement', '03', 'CREATE VIEW', 'YES', NULL, ''),
+('F311', 'Schema definition statement', '04', 'CREATE VIEW: WITH CHECK OPTION', 'YES', NULL, ''),
+('F311', 'Schema definition statement', '05', 'GRANT statement', 'YES', NULL, ''),
+('F312', 'MERGE statement', '', '', 'YES', NULL, ''),
+('F321', 'User authorization', '', '', 'YES', NULL, ''),
+('F341', 'Usage tables', '', '', 'YES', NULL, ''),
+('F361', 'Subprogram support', '', '', 'YES', NULL, ''),
+('F381', 'Extended schema manipulation', '', '', 'YES', NULL, ''),
+('F381', 'Extended schema manipulation', '01', 'ALTER TABLE statement: ALTER COLUMN clause', 'YES', NULL, ''),
+('F381', 'Extended schema manipulation', '02', 'ALTER TABLE statement: ADD CONSTRAINT clause', 'YES', NULL, ''),
+('F381', 'Extended schema manipulation', '03', 'ALTER TABLE statement: DROP CONSTRAINT clause', 'YES', NULL, ''),
+('F391', 'Long identifiers', '', '', 'YES', NULL, ''),
+('F392', 'Unicode escapes in identifiers', '', '', 'YES', NULL, ''),
+('F393', 'Unicode escapes in literals', '', '', 'YES', NULL, ''),
+('F401', 'Extended joined table', '', '', 'YES', NULL, ''),
+('F401', 'Extended joined table', '01', 'NATURAL JOIN', 'YES', NULL, ''),
+('F401', 'Extended joined table', '02', 'FULL OUTER JOIN', 'YES', NULL, ''),
+('F401', 'Extended joined table', '04', 'CROSS JOIN', 'YES', NULL, ''),
+('F402', 'Named column joins for LOBs, arrays, and multisets', '', '', 'YES', NULL, ''),
+('F411', 'Time zone specification', '', '', 'YES', NULL, ''),
+('F421', 'National character', '', '', 'YES', NULL, ''),
+('F431', 'Read-only scrollable cursors', '', '', 'NO', NULL, 'yes via JDBC'),
+('F431', 'Read-only scrollable cursors', '01', 'FETCH with explicit NEXT', 'NO', NULL, 'yes via JDBC'),
+('F431', 'Read-only scrollable cursors', '02', 'FETCH FIRST', 'NO', NULL, 'yes via JDBC'),
+('F431', 'Read-only scrollable cursors', '03', 'FETCH LAST', 'NO', NULL, 'yes via JDBC'),
+('F431', 'Read-only scrollable cursors', '04', 'FETCH PRIOR', 'NO', NULL, 'yes via JDBC'),
+('F431', 'Read-only scrollable cursors', '05', 'FETCH ABSOLUTE', 'NO', NULL, 'yes via JDBC'),
+('F431', 'Read-only scrollable cursors', '06', 'FETCH RELATIVE', 'NO', NULL, 'yes via JDBC'),
+('F441', 'Extended set function support', '', '', 'YES', NULL, ''),
+('F442', 'Mixed column references in set functions', '', '', 'YES', NULL, ''),
+('F451', 'Character set definition', '', '', 'YES', NULL, ''),
+('F461', 'Named character sets', '', '', 'YES', NULL, ''),
+('F471', 'Scalar subquery values', '', '', 'YES', NULL, ''),
+('F481', 'Expanded NULL predicate', '', '', 'YES', NULL, ''),
+('F491', 'Constraint management', '', '', 'YES', NULL, ''),
+('F501', 'Features and conformance views', '', '', 'YES', NULL, ''),
+('F501', 'Features and conformance views', '01', 'SQL_FEATURES view', 'YES', NULL, ''),
+('F501', 'Features and conformance views', '02', 'SQL_SIZING view', 'YES', NULL, ''),
+('F501', 'Features and conformance views', '03', 'SQL_LANGUAGES view', 'YES', NULL, ''),
+('F502', 'Enhanced documentation tables', '', '', 'YES', NULL, ''),
+('F502', 'Enhanced documentation tables', '01', 'SQL_SIZING_PROFILES view', 'YES', NULL, ''),
+('F502', 'Enhanced documentation tables', '02', 'SQL_IMPLEMENTATION_INFO view', 'YES', NULL, ''),
+('F502', 'Enhanced documentation tables', '03', 'SQL_PACKAGES view', 'YES', NULL, ''),
+('F521', 'Assertions', '', '', 'NO', NULL, ''),
+('F531', 'Temporary tables', '', '', 'YES', NULL, ''),
+('F555', 'Enhanced seconds precision', '', '', 'YES', NULL, ''),
+('F561', 'Full value expressions', '', '', 'YES', NULL, ''),
+('F571', 'Truth value tests', '', '', 'YES', NULL, ''),
+('F591', 'Derived tables', '', '', 'YES', NULL, ''),
+('F611', 'Indicator data types', '', '', 'NO', NULL, ''),
+('F641', 'Row and table constructors', '', '', 'YES', NULL, ''),
+('F651', 'Catalog name qualifiers', '', '', 'YES', NULL, ''),
+('F661', 'Simple tables', '', '', 'YES', NULL, ''),
+('F671', 'Subqueries in CHECK', '', '', 'NO', NULL, ''),
+('F672', 'Retrospective check constraints', '', '', 'YES', NULL, ''),
+('F691', 'Collation and translation', '', '', 'NO', NULL, 'only one collation per database can be selected'),
+('F692', 'Enhanced collation support', '', '', 'NO', NULL, ''),
+('F693', 'SQL-session and client module collations', '', '', 'NO', NULL, ''),
+('F695', 'Translation support', '', '', 'NO', NULL, ''),
+('F696', 'Additional translation documentation', '', '', 'NO', NULL, ''),
+('F701', 'Referential update actions', '', '', 'YES', NULL, ''),
+('F711', 'ALTER domain', '', '', 'YES', NULL, ''),
+('F721', 'Deferrable constraints', '', '', 'NO', NULL, ''),
+('F731', 'INSERT column privileges', '', '', 'YES', NULL, ''),
+('F741', 'Referential MATCH types', '', '', 'YES', NULL, 'MATCH FULL and MATCH SIMPLE supported but not MATCH PARTIAL'),
+('F751', 'View CHECK enhancements', '', '', 'YES', NULL, ''),
+('F761', 'Session management', '', '', 'NO', NULL, ''),
+('F771', 'Connection management', '', '', 'NO', NULL, ''),
+('F762', 'CURRENT_CATALOG', '','',  'YES', NULL, ''),
+('F763', 'CURRENT_SCHEMA', '','',  'YES', NULL, ''),
+('F781', 'Self-referencing operations', '', '', 'NO', NULL, ''),
+('F791', 'Insensitive cursors', '', '', 'NO', NULL, 'yes via JDBC'),
+('F801', 'Full set function', '', '', 'YES', NULL, ''),
+('F811', 'Extended flagging', '', '', 'NO', NULL, ''),
+('F812', 'Basic flagging', '', '', 'NO', NULL, ''),
+('F813', 'Extended flagging', '', '', 'NO', NULL, ''),
+('F821', 'Local table references', '', '', 'NO', NULL, ''),
+('F831', 'Full cursor update', '', '', 'NO', NULL, 'yes via JDBC'),
+('F831', 'Full cursor update', '01', 'Updatable scrollable cursors', 'NO', NULL, 'yes via JDBC'),
+('F831', 'Full cursor update', '02', 'Updatable ordered cursors', 'NO', NULL, 'yes via JDBC'),
+('F850', 'Top-level <order by clause> in <query expression>', '', '', 'YES', NULL, ''),
+('F851', '<order by clause> in subqueries', '', '', 'YES', NULL, ''),
+('F852', 'Top-level <order by clause> in views', '', '', 'YES', NULL, ''),
+('F855', 'Nested <order by clause> in <query expression>', '', '', 'YES', NULL, ''),
+('F856', 'Nested <fetch first clause> in <query expression>', '', '', 'YES', NULL, ''),
+('F857', 'Top-level <fetch first clause> in <query expression>', '', '', 'YES', NULL, ''),
+('F858', '<fetch first clause> in subqueries', '', '', 'YES', NULL, ''),
+('F859', 'Top-level <fetch first clause> in views', '', '', 'YES', NULL, ''),
+('J621', 'external Java routines', '', '', 'YES', NULL, ''),
+('P001', 'Stored modules', '', '', 'NO', NULL, ''),
+('P002', 'Computational completeness', '', '', 'YES', NULL, ''),
+('P003', 'Information Schema views', '', '', 'YES', NULL, ''),
+('P004', 'extended CASE statement', '', '', 'YES', NULL, ''),
+('P006', 'Multiple assignment', '', '', 'YES', NULL, ''),
+('P007', 'Enhanced diagnostics management', '', '', 'NO', NULL, ''),
+('P008', 'Comma-separated predicates in simple CASE statement', '', '', 'YES', NULL, ''),
+('S011', 'Distinct data types', '', '', 'YES', NULL, ''),
+('S011', 'Distinct data types', '01', 'USER_DEFINED_TYPES view', 'YES', NULL, ''),
+('S023', 'Basic structured types', '', '', 'NO', NULL, ''),
+('S024', 'Enhanced structured types', '', '', 'NO', NULL, ''),
+('S025', 'Final structured types', '', '', 'NO', NULL, ''),
+('S026', 'Self-referencing structured types', '', '', 'NO', NULL, ''),
+('S027', 'Create method by specific method name', '', '', 'NO', NULL, ''),
+('S028', 'Permutable UDT options list', '', '', 'NO', NULL, ''),
+('S041', 'Basic reference types', '', '', 'NO', NULL, ''),
+('S043', 'Enhanced reference types', '', '', 'NO', NULL, ''),
+('S051', 'Create table of type', '', '', 'NO', NULL, ''),
+('S071', 'SQL paths in function and type name resolution', '', '', 'YES', NULL, ''),
+('S081', 'Subtables', '', '', 'NO', NULL, ''),
+('S091', 'Basic array support', '', '', 'YES', NULL, ''),
+('S091', 'Basic array support', '01', 'Arrays of built-in data types', 'YES', NULL, ''),
+('S091', 'Basic array support', '02', 'Arrays of distinct types', 'YES', NULL, ''),
+('S091', 'Basic array support', '03', 'Array expressions', 'YES', NULL, ''),
+('S092', 'Arrays of user-defined types', '', '', 'NO', NULL, ''),
+('S094', 'Arrays of reference types', '', '', 'NO', NULL, ''),
+('S095', 'Array constructors by query', '', '', 'YES', NULL, ''),
+('S096', 'Optional array bounds', '', '', 'YES', NULL, ''),
+('S097', 'Array element assignment', '', '', 'YES', NULL, ''),
+('S111', 'ONLY in query expressions', '', '', 'NO', NULL, ''),
+('S151', 'Type predicate', '', '', 'NO', NULL, ''),
+('S161', 'Subtype treatment', '', '', 'NO', NULL, ''),
+('S162', 'Subtype treatment for references', '', '', 'NO', NULL, ''),
+('S201', 'SQL-invoked routines on arrays', '', '', 'YES', NULL, ''),
+('S201', 'SQL-invoked routines on arrays', '01', 'Array parameters', 'YES', NULL, ''),
+('S201', 'SQL-invoked routines on arrays', '02', 'Array as result type of functions', 'YES', NULL, ''),
+('S202', 'SQL-invoked routines on multisets', '', '', 'NO', NULL, ''),
+('S211', 'User-defined cast functions', '', '', 'NO', NULL, ''),
+('S231', 'Structured type locators', '', '', 'NO', NULL, ''),
+('S232', 'Array locators', '', '', 'NO', NULL, ''),
+('S233', 'Multiset locators', '', '', 'NO', NULL, ''),
+('S241', 'Transform functions', '', '', 'NO', NULL, ''),
+('S242', 'Alter transform statement', '', '', 'NO', NULL, ''),
+('S251', 'User-defined orderings', '', '', 'NO', NULL, ''),
+('S261', 'Specific type method', '', '', 'NO', NULL, ''),
+('S271', 'Basic multiset support', '', '', 'NO', NULL, ''),
+('S272', 'Multisets of user-defined types', '', '', 'NO', NULL, ''),
+('S274', 'Multisets of reference types', '', '', 'NO', NULL, ''),
+('S275', 'Advanced multiset support', '', '', 'NO', NULL, ''),
+('S281', 'Nested collection types', '', '', 'NO', NULL, ''),
+('S291', 'Unique constraint on entire row', '', '', 'NO', NULL, ''),
+('T011', 'Timestamp in Information Schema', '', '', 'YES', NULL, ''),
+('T021', 'BINARY and VARBINARY data types', '', '', 'YES', NULL, ''),
+('T022', 'Advanced BINARY and VARBINARY data type support', '', '', 'YES', NULL, ''),
+('T023', 'Compound binary literals', '', '', 'YES', NULL, ''),
+('T024', 'Spaces in binary literals', '', '', 'YES', NULL, ''),
+('T031', 'BOOLEAN data type', '', '', 'YES', NULL, ''),
+('T041', 'Basic LOB data type support', '', '', 'YES', NULL, ''),
+('T041', 'Basic LOB data type support', '01', 'BLOB data type', 'YES', NULL, ''),
+('T041', 'Basic LOB data type support', '02', 'CLOB data type', 'YES', NULL, ''),
+('T041', 'Basic LOB data type support', '03', 'POSITION, LENGTH, LOWER, TRIM, UPPER, and SUBSTRING functions for LOB data types', 'YES', NULL, ''),
+('T041', 'Basic LOB data type support', '04', 'Concatenation of LOB data types', 'YES', NULL, ''),
+('T041', 'Basic LOB data type support', '05', 'LOB locator: non-holdable', 'YES', NULL, 'yes via JDBC'),
+('T042', 'Extended LOB data type support', '', '', 'YES', NULL, ''),
+('T051', 'Row types', '', '', 'NO', NULL, ''),
+('T052', 'MAX and MIN for row types', '', '', 'NO', NULL, ''),
+('T053', 'Explicit aliases for all-fields reference', '', '', 'NO', NULL, ''),
+('T061', 'UCS support', '', '', 'YES', NULL, ''),
+('T071', 'BIGINT data type', '', '', 'YES', NULL, ''),
+('T111', 'Updatable joins, unions, and columns', '', '', 'NO', NULL, 'only updatable columns'),
+('T121', 'WITH (excluding RECURSIVE) in query expression', '', '', 'YES', NULL, ''),
+('T122', 'WITH (excluding RECURSIVE) in subquery', '', '', 'YES', NULL, ''),
+('T131', 'Recursive query', '', '', 'NO', NULL, ''),
+('T132', 'Recursive query in subquery', '', '', 'NO', NULL, ''),
+('T141', 'SIMILAR predicate', '', '', 'NO', NULL, ''),
+('T151', 'DISTINCT predicate', '', '', 'YES', NULL, ''),
+('T152', 'DISTINCT predicate with negation', '', '', 'YES', NULL, ''),
+('T171', 'LIKE clause in table definition', '', '', 'YES', NULL, ''),
+('T172', 'AS subquery clause in table definition', '', '', 'YES', NULL, ''),
+('T173', 'Extended LIKE clause in table definition', '', '', 'YES', NULL, ''),
+('T174', 'Identity columns', '', '', 'YES', NULL, ''),
+('T175', 'Generated columns', '', '', 'YES', NULL, ''),
+('T176', 'Sequence generator support', '', '', 'YES', NULL, ''),
+('T191', 'Referential action RESTRICT', '', '', 'YES', NULL, ''),
+('T201', 'Comparable data types for referential constraints', '', '', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '', '', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '01', 'Triggers activated on UPDATE, INSERT, or DELETE of one base table', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '02', 'BEFORE triggers', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '03', 'AFTER triggers', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '04', 'FOR EACH ROW triggers', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '05', 'Ability to specify a search condition that must be true before the trigger is invoked', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '06', 'Support for run-time rules for the interaction of triggers and constraints', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '07', 'TRIGGER privilege', 'YES', NULL, ''),
+('T211', 'Basic trigger capability', '08', 'Multiple triggers for the same event are executed in the order in which they were created in the catalog', 'YES', NULL, ''),
+('T212', 'Enhanced trigger capability', '', '', 'YES', NULL, ''),
+('T231', 'Sensitive cursors', '', '', 'YES', NULL, ''),
+('T241', 'START TRANSACTION statement', '', '', 'YES', NULL, ''),
+('T251', 'SET TRANSACTION statement: LOCAL option', '', '', 'NO', NULL, ''),
+('T261', 'Chained transactions', '', '', 'YES', NULL, ''),
+('T271', 'Savepoints', '', '', 'YES', NULL, ''),
+('T272', 'Enhanced savepoint management', '', '', 'YES', NULL, ''),
+('T281', 'SELECT privilege with column granularity', '', '', 'YES', NULL, ''),
+('T301', 'Functional dependencies', '', '', 'YES', NULL, ''),
+('T312', 'OVERLAY function', '', '', 'YES', NULL, ''),
+('T321', 'Basic SQL-invoked routines', '', '', 'YES', NULL, ''),
+('T321', 'Basic SQL-invoked routines', '01', 'User-defined functions with no overloading', 'YES', NULL, ''),
+('T321', 'Basic SQL-invoked routines', '02', 'User-defined stored procedures with no overloading', 'YES', NULL, ''),
+('T321', 'Basic SQL-invoked routines', '03', 'Function invocation', 'YES', NULL, ''),
+('T321', 'Basic SQL-invoked routines', '04', 'CALL statement', 'YES', NULL, ''),
+('T321', 'Basic SQL-invoked routines', '05', 'RETURN statement', 'YES', NULL, ''),
+('T321', 'Basic SQL-invoked routines', '06', 'ROUTINES view', 'YES', NULL, ''),
+('T321', 'Basic SQL-invoked routines', '07', 'PARAMETERS view', 'YES', NULL, ''),
+('T322', 'Overloading of SQL-invoked functions and procedures', '', '', 'YES', NULL, ''),
+('T323', 'Explicit security for external routines', '', '', 'NO', NULL, ''),
+('T324', 'Explicit security for SQL routines', '', '', 'YES', NULL, 'only DEFINER'),
+('T325', 'Qualified SQL parameter references', '', '', 'NO', NULL, ''),
+('T326', 'Table functions', '', '', 'YES', NULL, ''),
+('T331', 'Basic roles', '', '', 'YES', NULL, ''),
+('T332', 'Extended roles', '', '', 'NO', NULL, ''),
+('T351', 'Bracketed SQL comments (/*...*/ comments)', '', '', 'YES', NULL, ''),
+('T401', 'INSERT into a cursor', '', '', 'NO', NULL, 'yes via JDBC'),
+('T411', 'UPDATE statement: SET ROW option', '', '', 'NO', NULL, ''),
+('T431', 'Extended grouping capabilities', '', '', 'NO', NULL, ''),
+('T432', 'Nested and concatenated GROUPING SETS', '', '', 'NO', NULL, ''),
+('T433', 'Multiargument GROUPING function', '', '', 'NO', NULL, ''),
+('T434', 'GROUP BY DISINCT', '', '', 'NO', NULL, ''),
+('T441', 'ABS and MOD functions', '', '', 'YES', NULL, ''),
+('T461', 'Symmetric BETWEEN predicate', '', '', 'YES', NULL, ''),
+('T471', 'Result sets return value', '', '', 'NO', NULL, ''),
+('T491', 'LATERAL derived table', '', '', 'YES', NULL, ''),
+('T501', 'Enhanced EXISTS predicate', '', '', 'YES', NULL, ''),
+('T511', 'Transaction counts', '', '', 'NO', NULL, ''),
+('T541', 'Updatable table references', '', '', 'NO', NULL, ''),
+('T551', 'Optional key words for default syntax', '', '', 'YES', NULL, ''),
+('T561', 'Holdable locators', '', '', 'NO', NULL, ''),
+('T571', 'Array-returning external SQL-invoked functions', '', '', 'YES', NULL, ''),
+('T572', 'Multiset-returning external SQL-invoked functions', '', '', 'NO', NULL, ''),
+('T581', 'Regular expression substring function', '', '', 'YES', NULL, ''),
+('T591', 'UNIQUE constraints of possibly null columns', '', '', 'YES', NULL, ''),
+('T601', 'Local cursor references', '', '', 'NO', NULL, ''),
+('T611', 'Elementary OLAP operations', '', '', 'NO', NULL, ''),
+('T612', 'Advanced OLAP operations', '', '', 'NO', NULL, ''),
+('T613', 'Sampling', '', '', 'NO', NULL, ''),
+('T621', 'Enhanced numeric functions', '', '', 'NO', NULL, ''),
+('T631', 'IN predicate with one list element', '', '', 'YES', NULL, ''),
+('T641', 'Multiple column assignment', '', '', 'YES', NULL, ''),
+('T651', 'SQL-schema statements in SQL routines', '', '', 'NO', NULL, ''),
+('T652', 'SQL-dynamic statements in SQL routines', '', '', 'NO', NULL, ''),
+('T653', 'SQL-schema statements in external routines', '', '', 'NO', NULL, ''),
+('T654', 'SQL-dynamic statements in external routines', '', '', 'YES', NULL, '');
+/*sql_packages*/
+VALUES
+( 'PKG001', 'Enhanced datetime facilities','YES', CAST(NULL AS CHARACTER), '' ),
+( 'PKG002', 'Enhanced integrity management','YES', NULL, '' ),
+( 'PKG004', 'PSM', 'YES', NULL, 'only schema contained routines' ),
+( 'PKG006', 'Basic object support', 'NO', NULL, '' ),
+( 'PKG007', 'Enhanced object support','NO', NULL, '' ),
+( 'PKG008', 'Active database', 'YES', NULL, '' ),
+( 'PKG010', 'OLAP', 'NO', NULL, '');
+/*sql_parts*/
+VALUES
+( 'ISO9075-1', 'Framework','YES', CAST(NULL AS CHARACTER), '' ),
+( 'ISO9075-2', 'Foundation','YES', NULL, '' ),
+( 'ISO9075-3', 'Call-level interface','YES', NULL, '' ),
+( 'ISO9075-4', 'Persistent Stored Modules', 'YES', NULL, '' ),
+( 'ISO9075-9', 'Management of External Data', 'NO', NULL, '' ),
+( 'ISO9075-10', 'Object Language Bindings,','NO', NULL, '' ),
+( 'ISO9075-11', 'Information and Definition Schemas', 'YES', NULL, '' ),
+( 'ISO9075-13', 'Routines & Types Using the Java Programming', 'YES', NULL, ''),
+( 'ISO9075-14', 'XML-Related Specifications', 'NO', NULL, '');
+/*sql_sizing*/
+VALUES
+( 34, 'MAXIMUM CATALOG NAME LENGTH', 128,'length in characters' ),
+( 30, 'MAXIMUM COLUMN NAME LENGTH',128, NULL ),
+( 97, 'MAXIMUM COLUMNS IN GROUP BY', 0, 'limited by memory only' ),
+( 99, 'MAXIMUM COLUMNS IN ORDER BY', 0, 'limited by memory only' ),
+( 100, 'MAXIMUM COLUMNS IN SELECT', 0,'limited by memory only' ),
+( 101, 'MAXIMUM COLUMNS IN TABLE', 0, 'limited by memory only' ),
+( 1, 'MAXIMUM CONCURRENT ACTIVITIES', 0, 'limited by memory only'),
+( 31, 'MAXIMUM CURSOR NAME LENGTH', 128, NULL),
+( 0, 'MAXIMUM DRIVER CONNECTIONS', 0, 'limited by memory only' ),
+( 10005, 'MAXIMUM IDENTIFIER LENGTH', 128, NULL),
+( 32, 'MAXIMUM SCHEMA NAME LENGTH', 128, NULL),
+( 20000, 'MAXIMUM STATEMENT OCTETS', 0, 'limited by memory only'),
+( 20001, 'MAXIMUM STATEMENT OCTETS DATA', 0, 'limited by memory only'),
+( 20002, 'MAXIMUM STATEMENT OCTETS SCHEMA',0, 'limited by memory only'),
+( 35, 'MAXIMUM TABLE NAME LENGTH', 128, NULL),
+( 106, 'MAXIMUM TABLES IN SELECT', 0, 'limited by memory only'),
+( 107, 'MAXIMUM USER NAME LENGTH', 128, NULL ),
+( 25000, 'MAXIMUM CURRENT DEFAULT TRANSFORM GROUP LENGTH', NULL, NULL),
+( 25001, 'MAXIMUM CURRENT TRANSFORM GROUP LENGTH',NULL, NULL),
+( 25002, 'MAXIMUM CURRENT PATH LENGTH', NULL, NULL),
+( 25003, 'MAXIMUM CURRENT ROLE LENGTH', 128, NULL),
+( 25004, 'MAXIMUM SESSION USER LENGTH', 128, NULL),
+( 25005, 'MAXIMUM SYSTEM USER LENGTH', 128, NULL);
+
diff --git a/src/org/hsqldb/resources/jdklogging-default.properties b/src/org/hsqldb/resources/jdklogging-default.properties
new file mode 100644
index 0000000..99c3362
--- /dev/null
+++ b/src/org/hsqldb/resources/jdklogging-default.properties
@@ -0,0 +1,30 @@
+# $Id: jdklogging-default.properties 3108 2009-08-13 14:04:00Z unsaved $
+
+# As this is a Java .properties file, use ISO-8859-1 encoding for any
+# extended characters.
+
+# See http://java.sun.com/javase/6/docs/technotes/guides/logging/overview.html
+# for an overview of the JDK logging system, aka the Java Logging API or
+# java.util.logging.
+# If you want more, and easier, control, particularly over the format of
+# output records, use Log4J instead.
+
+# When HSQLDB's FrameworkLogger loads this configuration, it also
+# programmatically adds a ConsoleHandler just for packages under
+# org.hsqldb.cmdline, because JDK logging doesn't support declarative
+# package-specific Handler configuration like this.
+# It then programmatically adds additional catalog-specific FileHandlers as
+# catalogs come online.
+
+handlers=java.util.logging.ConsoleHandler
+.level=ALL
+
+java.util.logging.ConsoleHandler.level=WARNING
+java.util.logging.ConsoleHandler.formatter=org.hsqldb.lib.BasicTextJdkLogFormatter
+
+#java.util.logging.FileHandler.pattern=hsqldb.applog
+#java.util.logging.FileHandler.limit=50000
+#java.util.logging.FileHandler.count=1
+#java.util.logging.FileHandler.append=true
+#java.util.logging.FileHandler.formatter=org.hsqldb.lib.BasicTextJdkLogFormatter
+#java.util.logging.FileHandler.level=WARNING
diff --git a/src/org/hsqldb/resources/lob-schema.sql b/src/org/hsqldb/resources/lob-schema.sql
new file mode 100644
index 0000000..de91e5b
--- /dev/null
+++ b/src/org/hsqldb/resources/lob-schema.sql
@@ -0,0 +1,143 @@
+-- author Fred Toussi (fredt@users dot sourceforge.net) version 1.9.0
+
+/*lob_schema_definition*/
+CREATE SCHEMA SYSTEM_LOBS AUTHORIZATION DBA
+ CREATE TABLE BLOCKS(BLOCK_ADDR INT, BLOCK_COUNT INT NOT NULL, TX_ID BIGINT NOT NULL,
+   CONSTRAINT BLOCKS_PK PRIMARY KEY(BLOCK_ADDR))
+ CREATE INDEX BLOCKS_IDX1 ON BLOCKS(BLOCK_COUNT)
+ CREATE INDEX BLOCKS_IDX2 ON BLOCKS(TX_ID)
+ CREATE TABLE LOBS(BLOCK_ADDR INT NOT NULL, BLOCK_COUNT INT NOT NULL, BLOCK_OFFSET INT, LOB_ID BIGINT,
+   CONSTRAINT LOBS_PK PRIMARY KEY(LOB_ID, BLOCK_OFFSET),
+   CONSTRAINT LOBS_UQ1 UNIQUE(LOB_ID, BLOCK_ADDR),  CONSTRAINT LOBS_UQ2 UNIQUE(BLOCK_ADDR) )
+ CREATE INDEX LOBS_IDX1 ON LOBS(LOB_ID, BLOCK_COUNT)
+ CREATE TABLE LOB_IDS(LOB_ID BIGINT, LOB_LENGTH BIGINT NOT NULL, LOB_USAGE_COUNT INT DEFAULT 0, LOB_TYPE SMALLINT NOT NULL,
+   CONSTRAINT LOB_IDS_PK PRIMARY KEY(LOB_ID))
+ CREATE INDEX LOBS_IDX2 ON LOB_IDS(LOB_USAGE_COUNT)
+ CREATE SEQUENCE LOB_ID AS BIGINT START WITH 1
+
+ CREATE PROCEDURE CONVERT_BLOCK(B_ADDR INT, B_COUNT INT, B_OFFSET INT, L_ID BIGINT)
+  MODIFIES SQL DATA BEGIN ATOMIC
+  DELETE FROM BLOCKS WHERE BLOCK_ADDR = B_ADDR;
+  INSERT INTO LOBS VALUES(B_ADDR, B_COUNT, B_OFFSET, L_ID);
+ END
+
+ CREATE PROCEDURE DELETE_LOB(L_ID BIGINT, TX_ID BIGINT)
+  MODIFIES SQL DATA BEGIN ATOMIC
+  INSERT INTO BLOCKS (SELECT BLOCK_ADDR,BLOCK_COUNT,TX_ID FROM LOBS WHERE LOB_ID = L_ID);
+  DELETE FROM LOBS WHERE LOB_ID = L_ID;
+  DELETE FROM LOB_IDS WHERE LOB_ID = L_ID;
+ END
+
+ CREATE PROCEDURE DELETE_UNUSED()
+  MODIFIES SQL DATA BEGIN ATOMIC
+  INSERT INTO BLOCKS (SELECT BLOCK_ADDR,BLOCK_COUNT,0 FROM LOBS WHERE LOB_ID
+   IN (SELECT LOB_ID FROM LOB_IDS WHERE LOB_USAGE_COUNT < 1));
+  DELETE FROM LOBS WHERE LOB_ID
+   IN (SELECT LOB_ID FROM LOB_IDS WHERE LOB_USAGE_COUNT < 1);
+  DELETE FROM LOB_IDS WHERE LOB_USAGE_COUNT < 1;
+ END
+
+ CREATE PROCEDURE DELETE_BLOCKS(L_ID BIGINT, B_OFFSET INT, B_LIMIT INT, TX_ID BIGINT)
+  MODIFIES SQL DATA BEGIN ATOMIC
+
+  INSERT INTO BLOCKS (SELECT BLOCK_ADDR,BLOCK_COUNT,TX_ID FROM LOBS
+   WHERE LOB_ID = L_ID AND BLOCK_OFFSET >= B_OFFSET AND BLOCK_OFFSET < B_LIMIT);
+  DELETE FROM LOBS
+   WHERE LOB_ID = L_ID AND BLOCK_OFFSET >= B_OFFSET AND BLOCK_OFFSET < B_LIMIT;
+ END
+
+ CREATE PROCEDURE CREATE_EMPTY_BLOCK(INOUT B_ADDR INT, IN B_COUNT INT)
+  MODIFIES SQL DATA BEGIN ATOMIC
+  DECLARE TEMP_COUNT INT DEFAULT NULL;
+  DECLARE TEMP_ADDR INT DEFAULT NULL;
+  SET (TEMP_ADDR, TEMP_COUNT) = (SELECT BLOCK_ADDR, BLOCK_COUNT FROM BLOCKS WHERE BLOCK_COUNT > B_COUNT AND TX_ID = 0 FETCH 1 ROW ONLY);
+
+  IF TEMP_ADDR IS NULL THEN
+   SIGNAL SQLSTATE '45000';
+  END IF;
+
+  UPDATE BLOCKS SET BLOCK_COUNT = B_COUNT WHERE BLOCK_ADDR = TEMP_ADDR;
+  INSERT INTO BLOCKS VALUES (TEMP_ADDR + B_COUNT, TEMP_COUNT - B_COUNT, 0);
+  SET B_ADDR = TEMP_ADDR;
+ END
+
+ CREATE PROCEDURE DIVIDE_BLOCK(B_OFFSET INT, L_ID BIGINT)
+  MODIFIES SQL DATA BEGIN ATOMIC
+  DECLARE BL_ADDR INT DEFAULT NULL;
+  DECLARE BL_COUNT INT DEFAULT NULL;
+  DECLARE BL_OFFSET INT DEFAULT NULL;
+
+  SET (BL_ADDR, BL_COUNT, BL_OFFSET) = (SELECT BLOCK_ADDR, BLOCK_COUNT, BLOCK_OFFSET FROM LOBS WHERE LOB_ID = L_ID AND B_OFFSET > BLOCK_OFFSET AND B_OFFSET < BLOCK_OFFSET + BLOCK_COUNT);
+
+   IF BL_ADDR IS NULL THEN
+    SIGNAL SQLSTATE '45000';
+   END IF;
+  DELETE FROM LOBS WHERE BLOCK_ADDR = BL_ADDR;
+  INSERT INTO LOBS VALUES (BL_ADDR, B_OFFSET - BL_OFFSET, BL_OFFSET, L_ID);
+  INSERT INTO LOBS VALUES (BL_ADDR + B_OFFSET - BL_OFFSET, BL_OFFSET + BL_COUNT - B_OFFSET, B_OFFSET, L_ID);
+
+ END
+
+ CREATE PROCEDURE ALLOC_BLOCKS (IN B_COUNT INT, IN B_OFFSET INT, IN L_ID BIGINT)
+  MODIFIES SQL DATA BEGIN ATOMIC
+
+  DECLARE LOB_ADDR INT DEFAULT NULL;
+  DECLARE REMAINING_COUNT INT DEFAULT 0;
+  DECLARE BL_ADDR INT DEFAULT NULL;
+  DECLARE TEMP_COUNT INT DEFAULT 0;
+  DECLARE BL_OFFSET INT DEFAULT 0;
+
+  SET REMAINING_COUNT = B_COUNT;
+  SET BL_OFFSET = B_OFFSET;
+
+  MAIN_LOOP: LOOP
+
+   SET BL_ADDR = (SELECT BLOCK_ADDR FROM BLOCKS WHERE BLOCK_COUNT = REMAINING_COUNT AND TX_ID = 0 FETCH 1 ROW ONLY);
+
+   IF BL_ADDR IS NOT NULL THEN
+
+    CALL CONVERT_BLOCK (BL_ADDR, REMAINING_COUNT, BL_OFFSET, L_ID);
+
+    IF LOB_ADDR IS NULL THEN
+     SET LOB_ADDR = BL_ADDR;
+    END IF;
+
+    LEAVE MAIN_LOOP;
+
+   END IF;
+
+   SET (BL_ADDR, TEMP_COUNT) = (SELECT BLOCK_ADDR, BLOCK_COUNT FROM BLOCKS WHERE BLOCK_COUNT < REMAINING_COUNT AND TX_ID = 0 FETCH 1 ROW ONLY);
+
+   IF BL_ADDR IS NOT NULL THEN
+
+    CALL CONVERT_BLOCK (BL_ADDR, TEMP_COUNT, BL_OFFSET, L_ID);
+
+    IF LOB_ADDR IS NULL THEN
+      SET LOB_ADDR = BL_ADDR;
+    END IF;
+
+    SET REMAINING_COUNT = REMAINING_COUNT - TEMP_COUNT;
+    SET BL_OFFSET = BL_OFFSET + TEMP_COUNT;
+    SET BL_ADDR = NULL;
+    SET TEMP_COUNT = 0;
+
+   ELSE
+
+    CALL CREATE_EMPTY_BLOCK (BL_ADDR, REMAINING_COUNT);
+    CALL CONVERT_BLOCK (BL_ADDR, REMAINING_COUNT, BL_OFFSET, L_ID);
+
+    IF LOB_ADDR IS NULL THEN
+     SET LOB_ADDR = BL_ADDR;
+
+    END IF;
+    LEAVE MAIN_LOOP;
+   END IF;
+
+  END LOOP MAIN_LOOP;
+ END
+;
+
+/*get_lob_query*/
+SELECT * FROM LOBS WHERE LOB_ID = ?;
+/*get_lob_part_statement*/
+SELECT * FROM LOBS WHERE LOB_ID = ? ORDER BY BLOCK_OFFSET OFFSET ? FETCH ? ROWS ONLY;
diff --git a/src/org/hsqldb/resources/org_hsqldb_DatabaseClassLoader.properties b/src/org/hsqldb/resources/org_hsqldb_DatabaseClassLoader.properties
new file mode 100644
index 0000000..66b8ccc
--- /dev/null
+++ b/src/org/hsqldb/resources/org_hsqldb_DatabaseClassLoader.properties
@@ -0,0 +1,12 @@
+jarLoad(java.sql.Connection,java.lang.String)=Loads the resources stored in the specified archive into the database specified by the <CODE>conn</CODE> argument. <p> Only entries that pass an acceptance test are actually stored. For instance, entries whose content is Java bytecode are accepted only if the classes they define are not in a java.* package. Similarly, all entries of the jar archive special form "META-INF/*" are rejected. Also, for each loading entry that has a resource with the same name already loaded, the MD5 hash values of the contents are compared; if the hash values are equal, then loading entry is ignored.
+jarLoad(java.sql.Connection,java.lang.String)@0=A <CODE>Result</CODE> object describing the result of loading the archive
+jarLoad(java.sql.Connection,java.lang.String)@1=conn - A <CODE>Connection</CODE> object identifying the target database
+jarLoad(java.sql.Connection,java.lang.String)@2=name - the name of the archive; this may be either a jar protocol URL string or a bare file path
+jarUnload(java.sql.Connection,java.lang.String)=Removes the resources in the archive identified by the from <CODE>name</CODE> argument from the database specified by the <CODE>conn</CODE> argument.
+jarUnload(java.sql.Connection,java.lang.String)@0=A <CODE>Result</CODE> object describing the result of unloading the archive
+jarUnload(java.sql.Connection,java.lang.String)@1=conn - A <CODE>Connection</CODE> object identifying the target database
+jarUnload(java.sql.Connection,java.lang.String)@2=name - the name of the archive; this may be either a jar protocol URL string or a bare file path
+callMain(java.sql.Connection,java.lang.String,java.lang.String)=Invokes the special <CODE>public static void main(String[] args)</CODE> method of the Java <CODE>Class</CODE> indentified by the <CODE>className</CODE> argument.
+callMain(java.sql.Connection,java.lang.String,java.lang.String)@1=conn - A <CODE>Connection</CODE> object identifying the execution context in which to invoke the method
+callMain(java.sql.Connection,java.lang.String,java.lang.String)@2=className - the fully qualified name of a Java <CODE>Class</CODE>
+callMain(java.sql.Connection,java.lang.String,java.lang.String)@3=args - a comma-separated list of argument strings
diff --git a/src/org/hsqldb/resources/org_hsqldb_Server_messages.properties b/src/org/hsqldb/resources/org_hsqldb_Server_messages.properties
new file mode 100644
index 0000000..a925a66
--- /dev/null
+++ b/src/org/hsqldb/resources/org_hsqldb_Server_messages.properties
@@ -0,0 +1,54 @@
+# Sample ResourceBundle properties file
+server.help=Usage: java org.hsqldb.server.Server [options]\n\
+\n\
++-----------------+-------------+----------+------------------------------+\n\
+|     OPTION      |    TYPE     | DEFAULT  |         DESCRIPTION          |\n\
++-----------------+-------------+----------+------------------------------|\n\
+| --help          | -           | -        | displays this message        |\n\
+| --address       | name|number | any      | server inet address          |\n\
+| --port          | number      | 9001/544 | port at which server listens |\n\
+| --database.i    | [type]spec  | 0=test   | name of database i           |\n\
+| --dbname.i      | alias       | -        | url alias for database i     |\n\
+| --silent        | true|false  | true     | false => display all queries |\n\
+| --trace         | true|false  | false    | display JDBC trace messages  |\n\
+| --tls           | true|false  | false    | TLS/SSL (secure) sockets     |\n\
+| --no_system_exit| true|false  | false    | do not issue System.exit()   |\n\
++-----------------+-------------+----------+------------------------------+\n\
+\n\
+The server looks for a 'server.properties' file in the current directory and\n\
+loads properties from it if it exists.\n\
+Command line options override those loaded from the 'server.properties' file.\n\
+\n\
+See the HSQLDB User Guide for further details.
+
+webserver.help=Usage: java org.hsqldb.server.WebServer [options]\n\
+\n\
++-----------------+------------ +------------+------------------------------+\n\
+|     OPTION      |    TYPE     |  DEFAULT   |         DESCRIPTION          |\n\
++-----------------+-------------+------------+------------------------------|\n\
+| --help          | -           | -          | displays this message        |\n\
+| --address       | name|number | any        | server inet address          |\n\
+| --port          | number      | 80/443     | port at which server listens |\n\
+| --database.i    | [type]spec  | 0=test     | name of database i           |\n\
+| --dbname.i      | alias       | -          | url alias for database i     |\n\
+| --root          | path        | ./         | path to web root             |\n\
+| --default_page  | file        | index.html | default web page             |\n\
+| --silent        | true|false  | true       | false => display all queries |\n\
+| --trace         | true|false  | false      | display JDBC trace messages  |\n\
+| --tls           | true|false  |            | HTTPS (secure) sockets       |\n\
+| --no_system_exit| true|false  | false      | do not issue System.exit()   |\n\
++-----------------+-------------+------------+------------------------------+\n\
+\n\
+The web server looks for a 'webserver.properties' file in the current directory\n\
+and loads properties from it if it exists.\n\
+Command line options override those loaded from the 'webserver.properties' file.\n\n\
+See the HSQLDB User Guide for further details.
+online.help=To close normally, connect and execute SHUTDOWN SQL\n\
+From command line, use [Ctrl]+[C] to abort abruptly
+
+# Broken into 2 parts to avoid messy substr substit. w/out Java 1.4.
+# Purposeful trailing space at end of 2nd line:
+textbanner.part1: HSQLDB JDBC Network Listener.\n\
+        Use JDBC driver with Network Compatibility Version
+textbanner.part2: \ and a JDBC URL like \
+        jdbc:hsqldb:hsql://hostname...
diff --git a/src/org/hsqldb/resources/sql-state-messages.properties b/src/org/hsqldb/resources/sql-state-messages.properties
new file mode 100644
index 0000000..d66cdb6
--- /dev/null
+++ b/src/org/hsqldb/resources/sql-state-messages.properties
@@ -0,0 +1,650 @@
+# SQL CODE definitions
+
+#
+#
+#
+#
+# @author Campbell Boucher Burnett (boucherb@users dot sourceforge.net)
+# @author Fred Toussi (fredt@users dot sourceforge.net)
+# @version 1.9.0
+# @since 1.9.0
+#
+
+0001=: $$ required: $$
+0002=; $$ table: $$
+
+# message parts
+0021=\u0020table $$ row count error : $$ read, needed $$
+0022=\u0020 wrong data for insert operation
+0023=attempt to connect while db opening /closing
+0024=\u0020line:\u0020
+0025=\u0020line: $$ $$
+0026=\u0020$$ $$
+0027=\u0020$$.properties $$
+0028=properties name is null or empty
+
+# message parts
+0041=Error in text source field
+0042=openning file: $$ error: $$
+0043=closing file: $$ error: $$
+0044=purging file: $$ error: $$
+
+# message parts
+0051=error $$ reading row - file $$
+0052=error $$ opening file - file $$
+0053=error $$ closing file - file $$
+
+# message parts
+0061=Invalid address : $$\nTry one of: $$
+0062=Invalid address : $$
+0063=Server certificate has no Common Name
+0064=Server certificate has empty Common Name
+0065=Certificate Common Name[$$] does not match host name[$$]
+
+# message parts
+0070=; ResultSet is empty
+0071=; ResultSet is positioned before first row
+0072=; ResultSet is positioned after last row
+
+# message parts
+0081=; in LIMIT, OFFSET or FETCH
+
+# SQLSTATE definitions
+# successful completion
+0000=00000 successful completion
+
+# HSQLDB operations
+0201=S0500 unsupported internal operation
+0301=S0501 no file name specified for source
+0302=S0502 no value specified for field
+0303=S0503 zero-length separator
+0304=S0504
+0320=S0521 operation is not allowed on text table with data
+0321=S0522 invalid statemnet - text table required
+0331=S0531 encode / decode error
+
+# Server
+0401=S1000 Transfer corrupted
+0402=S0504 database disconnected
+0403=S0504 Client version '$$' incompatible.  \
+        HSQLDB Network-Compatibility-Version '$$' required.
+0404=S0504 Network client is not a HSQLDB JDBC driver
+0405=S0504 Client using HSQLDB http protocol instead of hsql
+0406=S0504 Incomplete read of handshaking bytes
+0407=S1000 no valid database paths
+
+# JDBC
+0421=S1000 Column not found
+0422=S1000 InputStream error
+0423=S1000 Invalid argument in JDBC call
+0424=S1000 Parameter not set
+0425=S1000 Unknown JDBC escape sequence: {
+
+# HSQLDB non-core and file
+0451=S1000 Database lock acquisition failure
+0452=S1000 file input/output error
+0453=S1000 wrong database file version
+0454=S1000 old version database must be shutdown
+0455=S1000 The database is in read only mode
+0456=S1000 The table data is read only
+0457=S1000 Access is denied
+0458=S1000 General error
+0459=S1000 Database is memory only
+0460=S1000 Out of Memory
+0461=S1000 error in script file
+0462=S1000 Unsupported suffix in file name '$$'.  (Supported suffixes:  $$)
+0463=S1000 Mismatch between specified compression mode '$$' and file name '$$'
+0464=S1000 Database is non-file type
+0465=S1000 Database does not exists
+0466=S1000 Data File input/output error
+0467=S1000 IO error
+0468=S1000 Data File size limit is reached
+0469=S1000 Data File is in use
+
+# text tables
+0481=S1000 The table's data source for has not been defined
+0482=S1000 Invalid TEXT table source string
+0483=S1000 bad TEXT table source file - line number: $$ $$
+0484=S1000 TEXT table source file - IO error
+0485=S1000 end-of-line characters not allowed
+0486=S1000 Header not allowed or too long
+0487=S1000 Text source file already exists
+0488=S1000 No end sep.
+
+# warning
+1000=01000 warning
+1001=01001 warning: cursor operation conflict
+1002=01002 warning: disconnect error
+1003=01003 warning: null value eliminated in set function
+1004=01004 warning: string data, right truncation
+1005=01005 warning: insufficient item descriptor areas
+1006=01006 warning: privilege not revoked
+1007=01007 warning: privilege not granted
+1009=01009 warning: search condition too long for information schema
+1010=0100A warning: query expression too long for information schema
+1011=0100B warning: default value too long for information schema
+1012=0100C warning: result sets returned
+1013=0100D warning: additional result sets returned
+1014=0100E warning: attempt to return too many result sets
+1015=0100F warning: statement too long for information schema
+1016=01011 warning: SQL-Java path too long for information schema
+1017=0102F warning: array data, right truncation
+
+# no data
+1100=02000 no data
+1101=02001 no data: no additional result sets returned
+
+# dynamic SQL error
+1200=07000 dynamic SQL error
+1201=07001 dynamic SQL error: using clause does not match dynamic parameter specifications
+1202=07002 dynamic SQL error: using clause does not match target specifications
+1203=07003 dynamic SQL error: cursor specification cannot be executed
+1204=07004 dynamic SQL error: using clause required for dynamic parameters
+1205=07005 dynamic SQL error: prepared statement not a cursor specification
+1206=07006 dynamic SQL error: restricted data type attribute violation
+1207=07007 dynamic SQL error: using clause required for result fields
+1208=07008 dynamic SQL error: invalid descriptor count
+1209=07009 dynamic SQL error: invalid descriptor index
+1211=0700B dynamic SQL error: data type transform function violation
+1212=0700C dynamic SQL error: undefined DATA value
+1213=0700D dynamic SQL error: invalid DATA target
+1214=0700E dynamic SQL error: invalid LEVEL value
+1215=0700F dynamic SQL error: invalid DATETIME_INTERVAL_CODE
+
+# HSQLDB
+1251=07501 statement is closed
+1252=07502 statement is invalid
+1253=07503 statement does not generate a row count
+1254=07504 statement does not generate a result set
+1255=07505 statement is in batch mode
+1256=07506 statement is not in batch mode
+
+# connection exception
+1300=08000 connection exception
+1301=08001 connection exception: SQL-client unable to establish SQL-connection
+1302=08002 connection exception: connection name in use
+1303=08003 connection exception: connection does not exist
+1304=08004 connection exception: SQL-server rejected establishment of SQL-connection
+1305=08006 connection exception: connection failure
+1306=08007 connection exception: transaction resolution unknown
+
+# HSQLDB connection exception
+1351=08501 connection exception: timed out
+1352=08502 warning: unsupported client info
+1353=08503 connection exception: closed
+
+# triggered action exception
+1400=09000 triggered action exception
+
+# feature not supported
+1500=0A000 feature not supported
+1501=0A001 feature not supported: multiple server transactions
+
+# HSQLDB feature not supported
+1551=0A501 feature not supported:
+
+# invalid target type specification
+1600=0D000 invalid target type specification
+
+# invalid schema name list specification
+1700=0E000 invalid schema name list specification
+
+# locator exception
+1800=0F000 locator exception
+1801=0F001 locator exception: invalid specification
+
+# HSQLDB locator
+3474=0F502 lob is no longer valid
+3475=0F503 lob stream is closed
+
+# resignal when handler not active
+1900=0K000 resignal when handler not active
+
+# invalid grantor
+2000=0L000 invalid grantor
+
+# HSQLDB
+2051=0L501 invalid grantor - lacks CREATE_SCHEMA privilege
+
+# invalid SQL-invoked procedure reference
+2100=0M000 invalid SQL-invoked procedure reference
+
+# invalid role specification
+2200=0P000 invalid role specification
+
+# HSQLDB
+2251=0P501 invalid role specification - circular grant
+2252=0P502 invalid role specification - already granted
+2253=0P503 invalid role specification - does not have role
+
+# invalid transform group name specification
+2300=0S000 invalid transform group name specification
+
+# target table disagrees with cursor specification
+2400=0T000 target table disagrees with cursor specification
+
+# attempt to assign to non-updatable column
+2500=0U000 attempt to assign to non-updatable column
+
+# attempt to assign to ordering column
+2600=0V000 attempt to assign to ordering column
+
+# prohibited statement encountered during trigger execution
+2700=0W000 prohibited statement encountered during trigger execution
+
+# invalid foreign server specification
+2800=0X000 invalid foreign server specification
+
+# pass-through specific condition
+2900=0Y000 pass-through specific condition
+2901=0Y001 pass-through specific condition: invalid cursor option
+2902=0Y002 pass-through specific condition: invalid cursor allocation
+
+# diagnostics exception
+3000=0Z000 diagnostics exception
+3001=0Z001 diagnostics exception: maximum number of stacked diagnostics areas exceeded
+
+# 04-PSM
+3003=0Z002 diagnostics exception: stacked diagnostics accessed without active handler
+
+# 04-PSM
+3100=20000 case not found for case statement
+
+# cardinality violation
+3201=21000 cardinality violation
+
+# data exception
+3400=22000 data exception
+3401=22001 data exception: string data, right truncation
+3402=22002 data exception: null value, no indicator parameter
+3403=22003 data exception: numeric value out of range
+3404=22004 data exception: null value not allowed
+3405=22005 data exception: error in assignment
+3406=22006 data exception: invalid interval format
+3407=22007 data exception: invalid datetime format
+3408=22008 data exception: datetime field overflow
+3409=22009 data exception: invalid time zone displacement value
+3410=2200B data exception: escape character conflict
+3411=2200C data exception: invalid use of escape character
+3412=2200D data exception: invalid escape octet
+3413=2200E data exception: null value in array target
+3414=2200F data exception: zero-length character string
+3415=2200G data exception: most specific type mismatch
+3416=2200H data exception: sequence generator limit exceeded
+3417=2200J data exception: nonidentical notations with the same name
+3418=2200K data exception: nonidentical unparsed entities with the same name
+3419=2200L data exception: not an XML document
+3420=2200M data exception: invalid XML document
+3421=2200N data exception: invalid XML content
+3422=2200P data exception: interval value out of range
+3423=2200Q data exception: multiset value overflow
+3424=2200R data exception: XML value overflow
+3425=2200S data exception: invalid comment
+3426=2200T data exception: invalid processing instruction
+3427=2200U data exception: not an XQuery document node
+3428=2200V data exception: invalid XQuery context item
+3429=2200W data exception: XQuery serialization error
+3430=22010 data exception: invalid indicator parameter value
+3431=22011 data exception: substring error
+3432=22012 data exception: division by zero
+3433=22013 data exception: invalid preceding or following size in window function
+3434=22014 data exception: invalid argument for NTILE function
+3435=22015 data exception: interval field overflow
+3436=22016 data exception: invalid argument for NTH_VALUE function
+3437=22017 data exception: invalid data specified for datalink
+3438=22018 data exception: invalid character value for cast
+3439=22019 data exception: invalid escape character
+3440=2201A data exception: null argument passed to datalink constructor
+3441=2201B data exception: invalid regular expression
+3442=2201C data exception: null row not permitted in table
+3443=2201D data exception: datalink value exceeds maximum length
+3444=2201E data exception: invalid argument for natural logarithm
+3445=2201F data exception: invalid argument for power function
+3446=2201G data exception: invalid argument for width bucket function
+3447=2201J data exception: XQuery sequence cannot be validated
+3448=2201S data exception: invalid XQuery regular expression
+3449=2201T data exception: invalid XQuery option flag
+3450=2201U data exception: attempt to replace a zero-length string
+3451=2201V data exception: invalid XQuery replacement string
+3452=2201W data exception: invalid row count in fetch first clause
+3453=2201X data exception: invalid row count in result offset clause
+3454=22021 data exception: character not in repertoire
+3455=22022 data exception: indicator overflow
+3456=22023 data exception: invalid parameter value
+3457=22024 data exception: unterminated C string
+3458=22025 data exception: invalid escape sequence
+3459=22026 data exception: string data, length mismatch
+3460=22027 data exception: trim error
+3461=22029 data exception: noncharacter in UCS string
+
+# HSQLDB data exception
+3471=22501 value cannot be converted to target type
+3472=22511 invalid function argument
+3473=22521 object serialization failure
+
+# 04-PSM
+3488=2202A data exception: null value in field reference
+3489=2202D data exception: null value substituted for mutator subject parameter
+3490=2202E data exception: array element error
+3491=2202F data exception: array data, right truncation
+3492=2202G data exception: invalid repeat argument in a sample clause
+3493=2202H data exception: invalid sample size
+
+# integrity constraint violation
+3500=23000 integrity constraint violation
+3501=23001 integrity constraint violation: restrict violation
+0010=23502 integrity constraint violation: NOT NULL check constraint
+0177=23503 integrity constraint violation: foreign key no parent
+0008=23504 integrity constraint violation: foreign key no action
+0104=23505 integrity constraint violation: unique constraint or index violation
+0157=23513 integrity constraint violation: check constraint
+
+# invalid cursor state
+3600=24000 invalid cursor state
+3601=24501 invalid cursor state: identified cursor is not open
+3602=24502 invalid cursor state: identified cursor is already open
+3603=24504 invalid cursor state: identifier cursor not positioned on row in UPDATE, DELETE, SET, or GET statement
+3604=24513 invalid cursor state: cannot FETCH NEXT, PRIOR, CURRENT, or RELATIVE, cursor position is unknown
+3605=24514 invalid cursor state: cursor disabled by previous error
+3606=24515 invalid cursor state: all column must be set before insert
+3621=24521 invalid cursor state: row has been modified outside the cursor
+
+# invalid transaction state
+3700=25000 invalid transaction state
+3701=25001 invalid transaction state: active SQL-transaction
+3702=25002 invalid transaction state: branch transaction already active
+3703=25003 invalid transaction state: inappropriate access mode for branch transaction
+3704=25004 invalid transaction state: inappropriate isolation level for branch transaction
+3705=25005 invalid transaction state: no active SQL-transaction for branch transaction
+3706=25006 invalid transaction state: read-only SQL-transaction
+3707=25007 invalid transaction state: schema and data statement mixing not supported
+3708=25008 invalid transaction state: held cursor requires same isolation level
+
+# invalid SQL statement name
+3800=26000 invalid SQL statement name
+
+# triggered data change violation
+3900=27000 triggered data change violation
+
+# invalid authorization specification
+4000=28000 invalid authorization specification
+
+# HSQLDB invalid authorization specification
+4001=28501 invalid authorization specification - not found
+4002=28502 invalid authorization specification - system identifier
+4003=28503 invalid authorization specification - already exists
+
+# syntax error or access rule violation in direct statement
+4100=2A000 syntax error or access rule violation in direct statement
+
+# dependent privilege descriptors still exist
+4200=2B000 dependent privilege descriptors still exist
+
+# invalid character set name
+4300=2C000 invalid character set name
+
+# invalid transaction termination
+4400=2D000 invalid transaction termination
+4401=2D522 invalid transaction termination: COMMIT and ROLLBACK not allowed in ATOMIC compound statement
+
+# invalid connection name
+4500=2E000 invalid connection name
+
+# SQL routine exception
+4600=2F000 SQL routine exception
+4602=2F002 SQL routine exception: modifying SQL-data not permitted
+4603=2F003 SQL routine exception: prohibited SQL-statement attempted
+4604=2F004 SQL routine exception: reading SQL-data not permitted
+4605=2F005 SQL routine exception: function did not execute return statement
+
+# invalid collation name
+4650=2H000 invalid collation name
+
+# invalid SQL statement identifier
+4660=30000 invalid SQL statement identifier
+
+# invalid SQL descriptor name
+4670=33000 invalid SQL descriptor name
+
+# invalid cursor name
+4680=34000 invalid cursor name
+
+# invalid condition number
+4690=35000 invalid condition number
+
+# cursor sensitivity exception
+4700=36000 cursor sensitivity exception
+4701=36001 cursor sensitivity exception: request rejected
+4702=36002 cursor sensitivity exception: request failed
+
+# cursor compatibility warnings
+4711=36501 cursor sensitivity mismatch
+4712=36502 cursor updatability mismatch
+4713=36503 cursor holdability mismatch
+
+# syntax error or access rule violation in dynamic statement
+4790=37000 syntax error or access rule violation in dynamic statement
+
+# external routine exception
+4800=38000 external routine exception
+4801=38001 external routine exception: containing SQL not permitted
+4802=38002 external routine exception: modifying SQL-data not permitted
+4803=38003 external routine exception: prohibited SQL-statement attempted
+4804=38004 external routine exception: reading SQL-data not permitted
+
+# external routine invocation exception
+4810=39000 external routine invocation exception
+4811=39004 external routine invocation exception: null value not allowed
+
+# savepoint exception
+4820=3B000 savepoint exception
+4821=3B001 savepoint exception: invalid specification
+4822=3B002 savepoint exception: too many
+
+# ambiguous cursor name
+4830=3C000 ambiguous cursor name
+
+# invalid catalog name
+4840=3D000 invalid catalog name
+
+# invalid schema name
+4850=3F000 invalid schema name
+
+# transaction rollback
+4860=40000 transaction rollback
+4861=40001 transaction rollback: serialization failure
+4862=40002 transaction rollback: integrity constraint violation
+4863=40003 transaction rollback: statement completion unknown
+4864=40004 transaction rollback: triggered action exception
+
+# HSQLDB internal transactions
+4871=40501 transaction rollback: row change by multiple transactions
+
+# syntax error or access rule violation
+5000=42000 syntax error or access rule violation
+
+# HSQLDB database object names
+5501=42501 user lacks privilege or object not found
+5502=42502 dependent objects exist
+5503=42503 system object cannot be modified
+5504=42504 object name already exists
+5505=42505 invalid schema name - name mismatch
+5506=42506 invalid catalog name
+5507=42507 admin rights required
+5508=42508 label not found
+5509=42509 type not found or user lacks privilege
+5510=42510 name too long
+
+# genrated columns
+5512=42512 invalid expression in CHECK or GENERATED clause
+5513=42513 assignment to generated column
+
+# constraint defintition issues
+5520=42520 SET NULL requires nullable column
+5521=42521 SET DEFAULT requires column default expression for
+5522=42522 a UNIQUE constraint already exists on the set of columns
+5523=42523 table has no primary key
+5524=42524 constraint definition not allowed
+5525=42525 identity definition not allowed
+5526=42526 column is in primary key
+5527=42527 column is in constraint
+5528=42528 a FOREIGN KEY constraint already exists on the set of columns
+5529=42529 a UNIQUE constraint does not exist on referenced columns
+5530=42530 primary key definition not allowed
+5531=42531 default expression needed
+5532=42532 primary key already exist
+5533=42533 is referenced by FOREIGN KEY constraint
+5534=42534 column of LOB type cannot be used in operation
+
+# other definition issues
+5535=42535 not an identity column
+5536=42536 column is referenced in
+5537=42537 cannot use WITH CHECK OPTION for read-only view
+5538=42538 TRIGGER definition not compatible with table
+5539=42539 cannot drop a user that is currently connected
+
+# DML
+5541=42541 requires DEFAULT keyword
+5542=42542 requires OVERRIDING clause
+5543=42543 requires either DEFAULT keyword or OVERRIDING clause
+5544=42544 DEFAULT keyword cannot be used as column has no DEFAULT
+5545=42545 INSERT, UPDATE, DELETE or TRUNCATE not permitted for table or view
+5546=42546 number of target columns does not match that of query expression
+5547=42547 WHEN MATCHED already used in MERGE
+5548=42548 WHEN NOT MATCHED altready used in MERGE
+5549=42549 LIMIT, OFFSET or FETCH altready used
+
+#
+5551=42551 too many identifier parts
+5555=42555 invalid property name
+5556=42556 invalid property value
+
+# HSQLDB type conversion
+5561=42561 incompatible data type in conversion
+5562=42562 incompatible data types in combination
+5563=42563 incompatible data type in operation
+5564=42564 row column count mismatch
+5565=42565 row expression not allowed
+5566=42566 interval qualifier missing
+5567=42567 data type cast needed for parameter or null literal
+5568=42568 data type of expression is not boolean
+5569=42569 quoted identifier required
+5570=42570 concatenation exceeds maximum type length
+
+#
+5571=42571 NULL literal not allowed
+5572=42572 invalid GROUP BY expression
+5573=42573 invalid HAVING expression
+5574=42574 expression not in aggregate or GROUP BY columns
+5575=42575 parameter marker not allowed
+5576=42576 invalid ORDER BY expression
+5577=42577 duplicate column name in column list
+5578=42578 duplicate column name in derived table
+5579=42579 duplicate update of column
+5580=42580 ambiguous column reference
+
+# lexical elements
+5581=42581 unexpected token
+5582=42582 unknown token
+5583=42583 malformed quoted identifier
+5584=42584 malformed string
+5585=42585 malformed numeric constant
+5586=42586 malformed unicode string
+5587=42587 malformed binary string
+5588=42588 malformed bit string
+5589=42589 malformed comment
+5590=42590 unexpected end of statement
+
+# other
+5591=42591 cannot drop sole column of table
+5592=42592 precision or scale out of range
+5593=42593 column count mismatch in column name list
+5594=42594 column number mismatch detected in rows of UNION, INTERSECT, EXCEPT, or VALUES operation
+5595=42595 invalid privilege specified - ALL PRIVILEGES required
+5596=42596 schema qualifier does not match enclosing create schema statement.
+5597=42597 number out of the valid range for sequence generator
+5598=42598 sequence expression cannot be used in this context
+5599=42599 length must be specified in type definition
+
+# HSQLDB - PSM definition and calls
+5601=42601 repeat handler declaration
+5602=42602 invalid statement
+5603=42603 dynamic parameter or variable required as INOUT or OUT argument
+5604=42604 SQL routine exception: incompatible declaration attributes
+5605=42605 SQL routine exception: routine signature already exists
+5606=42606 SQL routine exception: variable name already exists
+5607=42607 invalid SQLSTATE value
+5608=42608 wrong or missing data impact clause in declaration
+5609=42609 routine signature not found for
+5610=42610 wrong signature for aggregate function declaration
+
+# with check option violation
+5700=44000 with check option violation
+
+# 04-PSM
+# unhandled user-defined exception
+5800=45000 unhandled user-defined exception
+
+# Java execution
+6000=46000 Java execution
+6001=46001 Java execution: invalid URL
+6002=46002 Java execution: invalid JAR name
+6003=46003 Java execution: invalid class deletion
+6004=46005 Java execution: invalid replacement
+6007=4600A Java execution: attempt to replace uninstalled JAR
+6008=4600B Java execution: attempt to remove uninstalled JAR
+6009=4600C Java execution: invalid JAR removal
+6010=4600D Java execution: invalid path
+6011=4600E Java execution: self-referencing path
+6012=46102 Java execution: invalid JAR name in path
+6013=46103 Java execution: unresolved class name
+
+# HSQLDB - SQL/JRT
+6021=46511 declared parameter types do not match method signature
+
+# Unknown Error: Catch-All
+6500=99000 Unknown Error: Catch-All
+6501=99099 Unknown Error: Error converting vendor code to SQL state code
+
+# FDW-specific condition
+6600=HV000 FDW-specific condition
+6601=HV001 FDW-specific condition: memory allocation error
+6602=HV002 FDW-specific condition: dynamic parameter value needed
+6603=HV004 FDW-specific condition: invalid data type
+6604=HV005 FDW-specific condition: column name not found
+6605=HV006 FDW-specific condition: invalid data type descriptors
+6606=HV007 FDW-specific condition: invalid column name
+6607=HV008 FDW-specific condition: invalid column number
+6608=HV009 FDW-specific condition: invalid use of null pointer
+6609=HV00A FDW-specific condition: invalid string format
+6610=HV00B FDW-specific condition: invalid handle
+6611=HV00C FDW-specific condition: invalid option index
+6612=HV00D FDW-specific condition: invalid option name
+6613=HV00J FDW-specific condition: option name not found
+6614=HV00K FDW-specific condition: reply handle
+6615=HV00L FDW-specific condition: unable to create execution
+6616=HV00M FDW-specific condition: unable to create reply
+6617=HV00N FDW-specific condition: unable to establish connection
+6618=HV00P FDW-specific condition: no schemas
+6619=HV00Q FDW-specific condition: schema not found
+6620=HV00R FDW-specific condition: table not found
+6621=HV010 FDW-specific condition: function sequence error
+6622=HV014 FDW-specific condition: limit on number of handles exceeded
+6623=HV021 FDW-specific condition: inconsistent descriptor information
+6624=HV024 FDW-specific condition: invalid attribute value
+6625=HV090 FDW-specific condition: invalid string length or buffer length
+6626=HV091 FDW-specific condition: invalid descriptor field identifier
+
+# datalink exception
+6700=HW000 datalink exception
+6701=HW001 datalink exception: external file not linked
+6702=HW002 datalink exception: external file already linked
+6703=HW003 datalink exception: referenced file does not exist
+6704=HW004 datalink exception: invalid write token
+6705=HW005 datalink exception: invalid datalink construction
+6706=HW006 datalink exception: invalid write permission for update
+6707=HW007 datalink exception: referenced file not valid
+
+# CLI-specific condition
+6800=HY093 CLI-specific condition: invalid datalink value
+
diff --git a/src/org/hsqldb/resources/sql-state-messages_es.properties b/src/org/hsqldb/resources/sql-state-messages_es.properties
new file mode 100644
index 0000000..71e6ffd
--- /dev/null
+++ b/src/org/hsqldb/resources/sql-state-messages_es.properties
@@ -0,0 +1,650 @@
+# SQL CODE definitions
+
+# Translated by Miquel Jordana (miquel71@users dot sourceforge.net)
+#
+# todo -- rewrite 5610 transation
+#
+# @author Campbell Boucher Burnett (boucherb@users dot sourceforge.net)
+# @author Fred Toussi (fredt@users dot sourceforge.net)
+# @version 1.9.0
+# @since 1.9.0
+#
+
+0001=: $$ requerido: $$
+0002=; $$ tabla: $$
+
+# message parts
+0021=\u0020tabla $$ error contando filas : $$ leídas, pero $$ requeridas
+0022=\u0020dato erróneo en operación de inserción
+0023=intentado conectar mientras la base de datos se esta abriendo o cerrando
+0024=\u0020línea:\u0020
+0025=\u0020línea: $$ $$
+0026=\u0020$$ $$
+0027=\u0020$$.properties $$
+0028=el nombre del las 'properties' es nulo o vacío
+
+# message parts
+0041=Error en el texto del campo origen
+0042=abriendo fichero: $$ error: $$
+0043=cerrando fichero: $$ error: $$
+0044=limpiando fichero: $$ error: $$
+
+# message parts
+0051=error $$ abriendo fila - fichero $$
+0052=error $$ cerrando fichero - fichero $$
+0053=error $$ cerrando fichero - fichero $$
+
+# message parts
+0061=Dirección incorrecta : $$\nIntente una entre: $$
+0062=Dirección incorrecta : $$
+0063=El certificado del servidor no tiene Nombre Común
+0064=El certificado del servidor tiene un texto vacío en el Nombre Común
+0065=El Nombre Común del certificado[$$] no corresponde con el nombre del equipo[$$]
+
+# message parts
+0070=; El resultado de la consulta es vacío
+0071=; Posición actual del resultado de la consulta es antes del primer registro
+0072=; Posición actual del resultado de la consulta es después del último registro
+
+# message parts
+0081=; en LIMIT, OFFSET o FETCH
+
+# SQLSTATE definitions
+# successful completion
+0000=00000 operación completada correctamente
+
+# HSQLDB operations
+0201=S0500 operación interna no soportada
+0301=S0501 no se ha indicado nombre para el origen
+0302=S0502 no se ha indicado valor para el campo
+0303=S0503 separador con texto de longitud cero
+0304=S0504
+0320=S0521 la operación no está permitida en una tabla de texto con datos
+0321=S0522 sentencia inválida - es necesario indicar tabla de texto
+0331=S0531 error de codificación / decodificación
+
+# Server
+0401=S1000 Datos transferidos corruptos
+0402=S0504 base de datos desconectada
+0403=S0504 La versión del cliente '$$' es incompatible.  \
+        Se requiere una versión de protocolo de red HSQLDB '$$'.
+0404=S0504 El cliente de red no es un controlador JDBC HSQLDB
+0405=S0504 El cliente está usando el protocolo HSQLDB http en lugar de hsql
+0406=S0504 Lectura incompleta de datos personalizados
+0407=S1000 Rutas de ficheros para la base de datos no son correctas
+
+# JDBC
+0421=S1000 Columna no encontrada
+0422=S1000 Error en lectura de datos ('InputStream')
+0423=S1000 Argumento incorrecto en una llamada JDBC
+0424=S1000 Parámetro no indicado
+0425=S1000 Secuencia de escape JDBC desconocida: {
+
+# HSQLDB non-core and file
+0451=S1000 Fallo al obtener un bloqueo en la base de datos
+0452=S1000 Error de lectura/escritura de fichero
+0453=S1000 Versión de fichero de base de datos errónea
+0454=S1000 La versión antigua de la base de datos debe ser cerrada
+0455=S1000 La base de datos está en modo solo lectura
+0456=S1000 La tabla de datos es de solo lectura
+0457=S1000 Acceso denegado
+0458=S1000 Error general
+0459=S1000 La base de datos es de tipo solo memoria
+0460=S1000 Sin memoria
+0461=S1000 Error en el fichero script
+0462=S1000 Sufijo inválido en el nombre del fichero '$$'.  (sufijos válidos:  $$)
+0463=S1000 Discordancia entre el modo de compresión indicado '$$' y el nombre de fichero '$$'
+0464=S1000 La base de datos es de tipo 'sin fichero'
+0465=S1000 La base de datos no existe
+0466=S1000 Error de lectura/escritura del fichero de datos
+0467=S1000 Error de lectura/escritura (IO)
+0468=S1000 Superado el tamaño máximo para el fichero de datos
+0469=S1000 Archivo de datos en uso
+
+# text tables
+0481=S1000 El origen de datos para la tabla no se ha especificado
+0482=S1000 Texto incorrecto para TEXT de la tabla origen
+0483=S1000 TEXT incorrecto en el fichero de la tabla origen - número de línea: $$ $$
+0484=S1000 TEXT en el fichero de la tabla origen - error de lectura/escritura ('IO')
+0485=S1000 Caracteres de final de línea no permitidos
+0486=S1000 Cabecera no permitida o demasiado larga
+0487=S1000 El fichero de texto origen ya existe
+0488=S1000 No hay separador de fin
+
+# warning
+1000=01000 advertencia
+1001=01001 advertencia: conflicto en la operación del cursor
+1002=01002 advertencia: error de desconexión
+1003=01003 advertencia: valor nulo eliminado en la operación de asignación
+1004=01004 advertencia: dato de tipo texto, truncado por la derecha
+1005=01005 advertencia: áreas de descripción del elemento insuficientes
+1006=01006 advertencia: privilegio no revocado
+1007=01007 advertencia: privilegio no otorgado
+1009=01009 advertencia: condición de búsqueda demasiado larga para el esquema de información ('information schema')
+1010=0100A advertencia: expresión demasiado larga para el esquema de información ('information schema')
+1011=0100B advertencia: valor por defecto demasiado largo para el esquema de información ('information schema')
+1012=0100C advertencia: conjunto de datos ('resultset') devueltos en la operación
+1013=0100D advertencia: conjunto de datos ('resultset') adicionales devueltos
+1014=0100E advertencia: se ha intentado devolver demasiados conjuntos de datos
+1015=0100F advertencia: sentencia demasiado larga para el esquema de información ('information schema')
+1016=01011 advertencia: ruta SQL-Java demasiado larga para el esquema de información ('information schema')
+1017=0102F advertencia: dato de tipo lista ('array'), truncado por la derecha
+
+# no data
+1100=02000 no hay datos
+1101=02001 no hay datos: no se devuelven conjuntos de datos ('resultsets') adicionales
+
+# dynamic SQL error
+1200=07000 error de sentencia SQL dinámica
+1201=07001 error de sentencia SQL dinámica: la parte USING de la sentencia SQL no cumple las especificaciones de sentencia dinámica
+1202=07002 error de sentencia SQL dinámica: la parte USING de la sentencia SQL no cumple las especificaciones para la tabla destino
+1203=07003 error de sentencia SQL dinámica: el cursor indicado no puede ejecutarse
+1204=07004 error de sentencia SQL dinámica: la sentencia dinámica requiere la parte USING
+1205=07005 error de sentencia SQL dinámica: la sentencia preparada no es un cursor válido
+1206=07006 error de sentencia SQL dinámica: atributo no permitido para el tipo de dato restringido
+1207=07007 error de sentencia SQL dinámica: los campos resultantes de la sentencia requieren la parte USING
+1208=07008 error de sentencia SQL dinámica: contador de descripción incorrecto
+1209=07009 error de sentencia SQL dinámica: índice de descripción incorrecto
+1211=0700B error de sentencia SQL dinámica: función de transformación no permitida para el tipo de dato
+1212=0700C error de sentencia SQL dinámica: valor DATA no definido
+1213=0700D error de sentencia SQL dinámica: destino DATA incorrecto
+1214=0700E error de sentencia SQL dinámica: valor LEVEL incorrecto
+1215=0700F error de sentencia SQL dinámica: DATETIME_INTERVAL_CODE incorrecto
+
+# HSQLDB
+1251=07501 sentencia SQL está cerrada
+1252=07502 sentencia SQL es incorrecta
+1253=07503 sentencia SQL no devuelve el número de filas
+1254=07504 sentencia SQL no devuelve un conjunto de datos ('result set')
+1255=07505 sentencia SQL se ejecuta en modo 'batch'
+1256=07506 sentencia SQL no se ejecuta en modo 'batch'
+
+# connection exception
+1300=08000 excepción de conexión
+1301=08001 excepción de conexión: cliente SQL no puede establecer una conexión
+1302=08002 excepción de conexión: nombre de conexión en uso
+1303=08003 excepción de conexión: conexión no existe
+1304=08004 excepción de conexión: servidor SQL rechaza la conexión SQL
+1305=08006 excepción de conexión: fallo de conexión
+1306=08007 excepción de conexión: resolución de transacción desconocida
+
+# HSQLDB connection exception
+1351=08501 excepción de conexión: demasiado tiempo (timed out)
+1352=08502 advertencia: información de cliente no soportada
+1353=08503 excepción de conexión: cerrada
+
+# triggered action exception
+1400=09000 excepción en la acción del disparador ('trigger')
+
+# feature not supported
+1500=0A000 característica no soportada
+1501=0A001 característica no soportada: múltiple transacciones de servidor
+
+# HSQLDB feature not supported
+1551=0A501 característica no soportada:
+
+# invalid target type specification
+1600=0D000 tipo de destino indicado incorrecto
+
+# invalid schema name list specification
+1700=0E000 nombre de lista indicada para el esquema incorrecto
+
+# locator exception
+1800=0F000 excepción del localizador
+1801=0F001 excepción del localizador: valor indicado incorrecto
+
+# HSQLDB locator
+3474=0F502 lob antiguo y ya no es válido
+3475=0F503 lob - canal de datos ('stream') está cerrado
+
+# resignal when handler not active
+1900=0K000 señal reenviada cuando el canal no estaba activo
+
+# invalid grantor
+2000=0L000 otorgador de privilegios ('grantor') incorrecto
+
+# HSQLDB
+2051=0L501 otorgador de privilegios ('grantor') incorrecto - falta el privilegio CREATE_SCHEMA
+
+# invalid SQL-invoked procedure reference
+2100=0M000 referencia al procedimiento SQL invocado incorrecto
+
+# invalid role specification
+2200=0P000 role indicado incorrecto
+
+# HSQLDB
+2251=0P501 role indicado incorrecto - permiso circular
+2252=0P502 role indicado incorrecto - permiso ya otorgado
+2253=0P503 role indicado incorrecto - role no indicado
+
+# invalid transform group name specification
+2300=0S000 nombre de la transformación del grupo indicado incorrecto
+
+# target table disagrees with cursor specification
+2400=0T000 tabla destino no corresponde con el cursor indicado
+
+# attempt to assign to non-updatable column
+2500=0U000 intento de asignar valores a una columna no actualizable
+
+# attempt to assign to ordering column
+2600=0V000 intento de asignar valores a una columna de ordenación
+
+# prohibited statement encountered during trigger execution
+2700=0W000 sentencia prohibida durante la ejecución de un disparador ('trigger')
+
+# invalid foreign server specification
+2800=0X000 servidor externo indicado incorrecto
+
+# pass-through specific condition
+2900=0Y000 condición del no-verificador ('pass-through')
+2901=0Y001 condición del no-verificador ('pass-through'): opción del cursor incorrecto
+2902=0Y002 condición del no-verificador ('pass-through'): creación del cursor incorrecto
+
+# diagnostics exception
+3000=0Z000 excepción de diagnósticos
+3001=0Z001 excepción de diagnósticos: máximo número de áreas de diagnosis excedido
+
+# 04-PSM
+3003=0Z002 excepción de diagnósticos: diagnosis accedido sin un canal activo
+
+# 04-PSM
+3100=20000 sentencia CASE no contiene casos
+
+# cardinality violation
+3201=21000 violación de cardinalidad
+
+# data exception
+3400=22000 excepción de datos
+3401=22001 excepción de datos: dato de tipo texto, truncado por la derecha
+3402=22002 excepción de datos: valor nulo, parámetro no indicador
+3403=22003 excepción de datos: valor numérico fuera de rango
+3404=22004 excepción de datos: valor nulo no permitido
+3405=22005 excepción de datos: error en asignación
+3406=22006 excepción de datos: formato de intervalo incorrecto
+3407=22007 excepción de datos: formato fecha/hora incorrecto
+3408=22008 excepción de datos: desbordamiento ('overflow') para campo fecha/hora
+3409=22009 excepción de datos: valor de desplazamiento de zona horaria incorrecto
+3410=2200B excepción de datos: conflicto con el carácter de escape
+3411=2200C excepción de datos: uso incorrecto del carácter de escape
+3412=2200D excepción de datos: octeto de escape incorrecto
+3413=2200E excepción de datos: valor nulo en lista ('array') destino
+3414=2200F excepción de datos: texto de longitud cero
+3415=2200G excepción de datos: error más específico de conversión de tipo
+3416=2200H excepción de datos: excedido el límite del generador de secuencia
+3417=2200J excepción de datos: notaciones no idénticas con el mismo nombre
+3418=2200K excepción de datos: entidades sin parsear no idénticas con el mismo nombre
+3419=2200L excepción de datos: no es un documento XML
+3420=2200M excepción de datos: documento XML incorrecto
+3421=2200N excepción de datos: contenido XML incorrecto
+3422=2200P excepción de datos: valor del intervalo fuera de rango
+3423=2200Q excepción de datos: desbordamiento ('overflow') en valor multiregistro ('multiset')
+3424=2200R excepción de datos: desbordamiento ('overflow') en valor XML
+3425=2200S excepción de datos: comentario incorrecto
+3426=2200T excepción de datos: instrucción de procesado incorrecta
+3427=2200U excepción de datos: nodo del documento no es un XQuery
+3428=2200V excepción de datos: contexto del elemento XQuery incorrecto
+3429=2200W excepción de datos: error al serializar un XQuery
+3430=22010 excepción de datos: valor del parámetro del indicador incorrecto
+3431=22011 excepción de datos: error en parte del texto ('substring')
+3432=22012 excepción de datos: división por cero
+3433=22013 excepción de datos: tamaño anterior o posterior del contexto de la función incorrecto
+3434=22014 excepción de datos: argumento incorrecto para la función NTILE
+3435=22015 excepción de datos: desbordamiento del campo intervalo
+3436=22016 excepción de datos: argumento incorrecto para la función NTH_VALUE
+3437=22017 excepción de datos: dato indicado incorrecto para el canal de datos ('datalink')
+3438=22018 excepción de datos: valor incorrecto para CAST
+3439=22019 excepción de datos: carácter de escape incorrecto
+3440=2201A excepción de datos: argumento nulo pasado al constructor del canal de datos ('datalink')
+3441=2201B excepción de datos: expresión regular incorrecta
+3442=2201C excepción de datos: fila nula no permitido en la tabla
+3443=2201D excepción de datos: el valor del canal de datos ('datalink') excede la longitud máxima
+3444=2201E excepción de datos: argumento incorrecto para el logaritmo natural
+3445=2201F excepción de datos: argumento incorrecto para la función potencia
+3446=2201G excepción de datos: argumento incorrecto para la funcion cubo
+3447=2201J excepción de datos: secuencia XQuery no puede ser validada
+3448=2201S excepción de datos: expresión regular en XQuery incorrecta
+3449=2201T excepción de datos: opción en XQuery incorrecta
+3450=2201U excepción de datos: intento de remplazar un texto de longitud cero
+3451=2201V excepción de datos: texto sustituto para XQuery incorrecto
+3452=2201W excepción de datos: filas contadas incorrectas al procesar mover al primer registro
+3453=2201X excepción de datos: filas contadas incorrecata al procesar posición del resultado
+3454=22021 excepción de datos: carácter no encontrado en el dicccionario
+3455=22022 excepción de datos: desbordamiento del indicador
+3456=22023 excepción de datos: valor del parámetro incorrecto
+3457=22024 excepción de datos: texto C no terminado
+3458=22025 excepción de datos: secuencia de escape incorrecta
+3459=22026 excepción de datos: dato tipo texto, discondancia en la longitud
+3460=22027 excepción de datos: error de trim
+3461=22029 excepción de datos: no hay caracteres in texto UCS
+
+# HSQLDB data exception
+3471=22501 el valor no se puede convertir al tipo destino
+3472=22511 argumento de la función incorrecto
+3473=22521 fallo de serializar el objeto
+
+# 04-PSM
+3488=2202A excepción de datos: valor nulo en el campo referencia
+3489=2202D excepción de datos: valor nulo sustituido por el parámetro del sujeto variable
+3490=2202E excepción de datos: error en el elemento lista ('array')
+3491=2202F excepción de datos: dato lista ('array'), truncado por la derecha
+3492=2202G excepción de datos: argumento repetido en un paso del muestreo
+3493=2202H excepción de datos: tamaño del muestreo incorrecto
+
+# integrity constraint violation
+3500=23000 violación del restricción de integridad
+3501=23001 violación del restricción de integridad: violación de la restriciión
+0010=23502 violación del restricción de integridad: restricción ('check') NOT NULL
+0177=23503 violación del restricción de integridad: no ha registro padre en clave foránea
+0008=23504 violación del restricción de integridad: sin acción para la clave foránea
+0104=23505 violación del restricción de integridad: violación de índice o clave única
+0157=23513 violación del restricción de integridad: restricción ('check') no se cumple
+
+# invalid cursor state
+3600=24000 estado del cursor incorrecto
+3601=24501 estado del cursor incorrecto: cursor indicado no está abierto
+3602=24502 estado del cursor incorrecto: cursor indicado ya estaba abierto
+3603=24504 estado del cursor incorrecto: cursor indicado no está posicionado en una fila para sentencia UPDATE, DELETE, SET, o GET
+3604=24513 estado del cursor incorrecto: no se puede hacer FETCH NEXT, PRIOR, CURRENT, o RELATIVE, ya que la posicón del cursor es desconocida
+3605=24514 estado del cursor incorrecto: cursor desactivado por un error previo
+3606=24515 estado del cursor incorrecto: todas las columnas se deben informar antes de llamar a INSERT
+3621=24521 estado del cursor incorrecto: la fila se ha modificado fuera del cursor
+
+# invalid transaction state
+3700=25000 estado de transacción incorrecto
+3701=25001 estado de transacción incorrecto: transacción SQL activa
+3702=25002 estado de transacción incorrecto: transacción parcial ya estaba activa
+3703=25003 estado de transacción incorrecto: modo de acceso inadecuado para una transacción parcial
+3704=25004 estado de transacción incorrecto: nivel de aislamiento inadecuado para una transacción parcial
+3705=25005 estado de transacción incorrecto: no hay activo ninguna transacción SQL para la transacción parcial
+3706=25006 estado de transacción incorrecto: transacción SQL de sólo lectura
+3707=25007 estado de transacción incorrecto: no se soporta mezclar sentencias de datos y de sistema ('infomartion schema')
+3708=25008 estado de transacción incorrecto: el cursor detenido necesita el mismo nivel de aislamiento
+
+# invalid SQL statement name
+3800=26000 nombre de sentencia SQL incorrecto
+
+# triggered data change violation
+3900=27000 violación al cambiar datos a través de un disparador
+
+# invalid authorization specification
+4000=28000 autorización incorrecta
+
+# HSQLDB invalid authorization specification
+4001=28501 autorización incorrecta - no se encuentra
+4002=28502 autorización incorrecta - identificador interno
+4003=28503 autorización incorrecta - ya existe
+
+# syntax error or access rule violation in direct statement
+4100=2A000 error de sintáxis o violación de acceso en una sentencia directa
+
+# dependent privilege descriptors still exist
+4200=2B000 descritores de privilegios dependientes todavía existen
+
+# invalid character set name
+4300=2C000 name informado con carácter incorrecto
+
+# invalid transaction termination
+4400=2D000 finalización de la transacción incorrecta
+4401=2D522 finalización de la transacción incorrecta: COMMIT y ROLLBACK no están permitidos en una sentencia atómica compuesta
+
+# invalid connection name
+4500=2E000 nombre de conexión incorrecto
+
+# SQL routine exception
+4600=2F000 excepción en rutina SQL
+4602=2F002 excepción en rutina SQL: modificar datos SQL no está permitido
+4603=2F003 excepción en rutina SQL: sentencia SQL ejecutada prohibida
+4604=2F004 excepción en rutina SQL: leer datos SQL no está permitido
+4605=2F005 excepción en rutina SQL: la función no ejecutó una sentencia RETURN
+
+# invalid collation name
+4650=2H000 nombre de juego de caracteres ('collation') incorrecto
+
+# invalid SQL statement identifier
+4660=30000 identificador de sentencia SQL incorrecto
+
+# invalid SQL descriptor name
+4670=33000 nombre de descriptor SQL incorrecto
+
+# invalid cursor name
+4680=34000 nombre de cursor incorrecto
+
+# invalid condition number
+4690=35000 número de condición incorrecto
+
+# cursor sensitivity exception
+4700=36000 excepción en sensibilidad del cursor
+4701=36001 excepción en sensibilidad del cursor: petición rechazada
+4702=36002 excepción en sensibilidad del cursor: petición fallida
+
+# cursor compatibility warnings
+4711=36501 discrepancia en sensibilidad del cursor
+4712=36502 discrepancia en updatibiidad del cursor
+4713=36503 discrepancia en nivel de retención del cursor
+
+# syntax error or access rule violation in dynamic statement
+4790=37000 error de sintáxis o violación de acceso en una sentencia dinámica
+
+# external routine exception
+4800=38000 excepcón en rutina externa
+4801=38001 excepcón en rutina externa: SQL contenido no permitido
+4802=38002 excepcón en rutina externa: cambios en datos SQL no está permitido
+4803=38003 excepcón en rutina externa: sentencia SQL ejecutada prohibida
+4804=38004 excepcón en rutina externa: leer datos SQL no está permitido
+
+# external routine invocation exception
+4810=39000 excepcón al ejecutar rutina externa
+4811=39004 excepcón al ejecutar rutina externa: valor nulo no permitido
+
+# savepoint exception
+4820=3B000 excepción en punto de retorno ('savepoint')
+4821=3B001 excepción en punto de retorno ('savepoint'): formato incorrecto
+4822=3B002 excepción en punto de retorno ('savepoint'): demasiados
+
+# ambiguous cursor name
+4830=3C000 nombre de cursor ambiguo
+
+# invalid catalog name
+4840=3D000 nombre de catálogo incorrecto
+
+# invalid schema name
+4850=3F000 nombre de esquema incorrecto
+
+# transaction rollback
+4860=40000 deshacer transacción ('rollback')
+4861=40001 deshacer transacción ('rollback'): fallo de serialización
+4862=40002 deshacer transacción ('rollback'): violación del restricción de integridad
+4863=40003 deshacer transacción ('rollback'): sentencia de finalización desconocida
+4864=40004 deshacer transacción ('rollback'): excepción al ejecutar un disparador
+
+# HSQLDB internal transactions
+4871=40501 deshacer transacción ('rollback'): fila modificada por múltiples transacciones
+
+# syntax error or access rule violation
+5000=42000 error de sintáxis o violación de acceso
+
+# HSQLDB database object names
+5501=42501 usuario no tiene privilegios suficientes o objeto no encontrado
+5502=42502 exiset objeto dependiente
+5503=42503 objeto de sistema no puede ser modificado
+5504=42504 nombre del objeto ya existe
+5505=42505 nombre de esquema incorrecto - discrepancia en el nombre
+5506=42506 nombre de catálogo incorrecto
+5507=42507 se requiere derechos de administrador
+5508=42508 etiqueta no encontrada
+5509=42509 tipo no encontrado o el usuario no tiene privilegios suficientes
+5510=42510 nombre demasiado largo
+
+# genrated columns
+5512=42512 expresión incorrecta en paret CHECK o GENERATED
+5513=42513 asignación a columna generada
+
+# constraint defintition issues
+5520=42520 SET NULL requiere una columna nulable
+5521=42521 SET DEFAULT requiere una expresión para el valor por defecto de la columna
+5522=42522 ya existe una restricción única, UNIQUE, para este conjunto de columnas
+5523=42523 la tabla no tiene clave primária
+5524=42524 la definición de esta restricción no está permitida
+5525=42525 la definición de identidad ('identity') no está permitida
+5526=42526 la columna forma parte de la clave primaria
+5527=42527 la columna forma parte de una restricción
+5528=42528 ya existe una clave foránea ('FOREIGN KEY') para este conjunto de columnas
+5529=42529 no existe una restricción única, ('UNIQUE') en las columnas indicadas
+5530=42530 la definición de esta clave primária no está permitida
+5531=42531 se necesita una expresión para el valor por defecto
+5532=42532 ya existe una clave primária
+5533=42533 es referenciada por una clave foránea ('FOREIGN KEY')
+5534=42534 la columna de tipo LOB no se puede usar en esta operación
+
+# other definition issues
+5535=42535 no es una columna identidad ('identity')
+5536=42536 la columna está referenciada en
+5537=42537 no se puede usar WITH CHECK OPTION para una vista de sólo lectura
+5538=42538 la definición del disparador ('TRIGGER') no es compatible con la tabla
+5539=42539 no se puede borrar un usuario mientras esté conectado
+
+# DML
+5541=42541 se requiere la palabra DEFAULT
+5542=42542 se requiere la parte OVERRIDING
+5543=42543 se requiere o la palabra DEFAULT o la parte OVERRIDING
+5544=42544 la palabra DEFAULT no se puede usar en columnas sin valor por defecto
+5545=42545 INSERT, UPDATE, DELETE o TRUNCATE no permitido para la tabla o la vista
+5546=42546 el número de columnas destino no concuerda con la expressión de la consulta
+5547=42547 WHEN MATCHED repetido en sentencia MERGE
+5548=42548 WHEN NOT MATCHED repetido en sentencia MERGE
+5549=42549 LIMIT, OFFSET o FETCH ya utilizado
+
+#
+5551=42551 demasiados elementos para los identificadores
+5555=42555 nombre de propiedad incorrecto
+5556=42556 valor para la propiedad incorrecto
+
+# HSQLDB type conversion
+5561=42561 tipo de datos incompatibles en la conversión
+5562=42562 tipo de datos incompatibles en la combinación
+5563=42563 tipo de datos incompatibles en la comparación
+5564=42564 discrepancia en el número de filas contadas
+5565=42565 tipo de datos incompatibles en la operación
+5566=42566 falta el calificador del intervalo
+5567=42567 se necesita conversión de tipo de dato para el parámetro o para el literal nulo
+5568=42568 el tipo de dato de la expresión no es boleano
+5569=42569 se requiere un identificador entrecomillado
+5570=42570 la concatenación excede el máximo de longitud que permite el tipo de dato
+
+#
+5571=42571 el literal NULL no está permitido
+5572=42572 expresión GROUP BY incorrecta
+5573=42573 expresión HAVING incorrecta
+5574=42574 la expresión no está en una agregación o columnas del GROUP BY
+5575=42575 el marcador del parámetro no está permitido
+5576=42576 expresión ORDER BY incorrecta
+5577=42577 nombre de columna duplicada en la lista de columnas
+5578=42578 nombre de columna duplicada en la tabla derivada
+5579=42579 actualización de la columna duplicada
+
+# lexical elements
+5580=42580 identificador incorrecto
+5581=42581 palabra no esperado
+5582=42582 palabra desconocida
+5583=42583 identificador entrecomillado mal escrito
+5584=42584 texto mal escrito
+5585=42585 constante numérica mal escrita
+5586=42586 texto unicode mal escrito
+5587=42587 texto binario mal escrito
+5588=42588 texto de tipo bit mal escrito
+5589=42589 comentario mal escrito
+5590=42590 fin de sentencia no esperado
+
+# other
+5591=42591 no se puede borrar última columna de la tabla
+5592=42592 precisión o escala fuera de rango
+5593=42593 se han detectado columnas incompatibles en filas resultantes de operaciones UNION, INTERSECT, EXCEPT, o VALUES
+5594=42594 numéro de filas incorrecto en filas resultantes de operaciones UNION, INTERSECT, EXCEPT, o VALUES
+5595=42595 privilegio indicado incorrecto - se requiere ALL PRIVILEGES
+5596=42596 el esquema indicado no corresponde con el esquema de la sentencia "create schema" incluida
+5597=42597 número fuera de rango válido para el generador de secuencia
+5598=42598 la expresión secuencia no se puede usar en este contexto
+5599=42599 la longitud se debe indicar en la definición del tipo de dato
+
+# HSQLDB - PSM definition and calls
+5601=42601 declaración de identificador repetida
+5602=42602 sentencia incorrecta
+5603=42603 parámetro dinámico o variable requerida en un argumento INOUT o OUT
+5604=42604 excepción en rutina SQL: declaración de atributos incompatible
+5605=42605 excepción en rutina SQL: ya existe otra rutina con la misma firma
+5606=42606 excepción en rutina SQL: nombre de variable ya existe
+5607=42607 valor SQLSTATE incorrecto
+5608=42608 declaración incorrecta ya que no respeta la restricción sobre datos, parámetro SQL DATA
+5609=42609 la firma de la rutina no se ha encontrado para
+5610=42610 declaración incorrecta 'aggregate function'
+
+# with check option violation
+5700=44000 violación de opción 'with check option'
+
+# 04-PSM
+# unhandled user-defined exception
+5800=45000 excepción definida por el usuario no esperada
+
+# Java execution
+6000=46000 Java execution
+6001=46001 Java execution: URL incorrecto
+6002=46002 Java execution: nombre de JAR incorrecto
+6003=46003 Java execution: borrado de clase incorrecto
+6004=46005 Java execution: substitución incorrecta
+6007=4600A Java execution: intento de reemplazar un JAR desinstalado
+6008=4600B Java execution: intento de borrar un JAR ya desinstalado
+6009=4600C Java execution: borrado de JAR incorrecto
+6010=4600D Java execution: ruta incorrecta
+6011=4600E Java execution: la ruta apunta a si mismo
+6012=46102 Java execution: nombre de JAR incorrecto en la ruta
+6013=46103 Java execution: no se puede resolver el nombre de clase
+
+# HSQLDB - SQL/JRT
+6021=46511 los tipos de parámetros declarados no corresponden con la firma del método
+
+# Unknown Error: Catch-All
+6500=99000 Error desconocido: no contemplado ('Catch-All')
+6501=99099 Error desconocido: Error convirtiendo el código del vendedor a un código de estado SQL
+
+# FDW-specific condition
+6600=HV000 condición específica FDW
+6601=HV001 condición específica FDW: error al reservar memoria
+6602=HV002 condición específica FDW: se necesita un valor de parámetro dinámico
+6603=HV004 condición específica FDW: tipo de dato incorrecto
+6604=HV005 condición específica FDW: nombre de columna no encontrado
+6605=HV006 condición específica FDW: los descriptores de los tipos de dato son incorrectos
+6606=HV007 condición específica FDW: nombre de columna incorrecto
+6607=HV008 condición específica FDW: número de columna incorrecto
+6608=HV009 condición específica FDW: uso incorrecto del puntero nulo
+6609=HV00A condición específica FDW: formato de texto incorrecto
+6610=HV00B condición específica FDW: identificador ('handle') incorrecto
+6611=HV00C condición específica FDW: índice de opción incorrecto
+6612=HV00D condición específica FDW: nombre de opción incorrecto
+6613=HV00J condición específica FDW: nombre de opción no encontrado
+6614=HV00K condición específica FDW: identficador ('handle') repetido
+6615=HV00L condición específica FDW: no se podido crer la ejecución
+6616=HV00M condición específica FDW: no se podido crear la repetción
+6617=HV00N condición específica FDW: no se podido establecer la conexión
+6618=HV00P condición específica FDW: no hay esquemas
+6619=HV00Q condición específica FDW: esquema no encontrado
+6620=HV00R condición específica FDW: tabla no encontrada
+6621=HV010 condición específica FDW: error en la función secuencia
+6622=HV014 condición específica FDW: excedido el máximo de identificadores ('handle') permitido
+6623=HV021 condición específica FDW: información del descriptor inconsistente
+6624=HV024 condición específica FDW: valor del atributo incorrecto
+6625=HV090 condición específica FDW: longitud de bufer o del texto incorrecto
+6626=HV091 condición específica FDW: identificador del campo descriptor incorrecto
+
+# datalink exception
+6700=HW000 excepción en conexión de datos
+6701=HW001 excepción en conexión de datos: fichero externo no conectado
+6702=HW002 excepción en conexión de datos: fichero externo ya está conectado
+6703=HW003 excepción en conexión de datos: el fichero de referencia no existe
+6704=HW004 excepción en conexión de datos: palabra ('token') de escritura incorrecto
+6705=HW005 excepción en conexión de datos: construcción de la conexión de datos incorrecto
+6706=HW006 excepción en conexión de datos: no tiene permiso de escritura para actualizar
+6707=HW007 excepción en conexión de datos: fichero de referencia incorrecto
+
+# CLI-specific condition
+6800=HY093 condición específica CLI: valor de conexión de datos incorrecto
+
diff --git a/src/org/hsqldb/resources/table-remarks.properties b/src/org/hsqldb/resources/table-remarks.properties
new file mode 100644
index 0000000..cd969c3
--- /dev/null
+++ b/src/org/hsqldb/resources/table-remarks.properties
@@ -0,0 +1,40 @@
+#table remarks
+SYSTEM_ALLTYPEINFO=a description of all non user-defined data types known to this database and the level of support for them in various capacities
+SYSTEM_BESTROWIDENTIFIER=for each accessible table defined within this database, the optimal set of visible columns that uniquely identifies a row
+SYSTEM_CACHEINFO=the current state of the system row caching mechanism
+SYSTEM_COLUMNS=the visible columns of each accessible table defined within this database
+SYSTEM_CROSSREFERENCE=a description of how the accessible tables defined within this database import visible columns to enforce referential integrity
+SYSTEM_LOBS=LOB storage for Java resources defined within this database
+SYSTEM_INDEXINFO=information about the indicies of each accessible table defined within this database
+SYSTEM_PRIMARYKEYS=the visible columns of the primary key of each accessible table defined within this database
+SYSTEM_PROCEDURECOLUMNS=a description of the return type, parameters and result columns of each accessible callable procedure, SQL function, trigger body and UDT method defined within this database
+SYSTEM_PROCEDURES=the procedures, SQL functions, trigger body routines and UDT methods defined within the database
+SYSTEM_PROPERTIES=the static and dynamic system properties and operating parameters of this database
+SYSTEM_SCHEMAS=the accessible schemas defined within this database
+SYSTEM_SESSIONINFO=information about the current database session
+SYSTEM_SESSIONS=the visible sessions open in this database
+SYSTEM_TABLES=the accessible tables defined within this database
+SYSTEM_TABLETYPES=the types of tables that can be created/found within this database
+SYSTEM_TEXTTABLES=the data source descriptors of the accessible TEXT TABLE objects defined within this database
+SYSTEM_TYPEINFO=a description of predefined table column data types known to this database
+SYSTEM_UDTS=the user-defined types that are available within this database
+SYSTEM_USERS=users defined within this database
+SYSTEM_VERSIONCOLUMNS=the visible columns of the accessible tables that are automatically updated when any value in a row is updated
+AUTHORIZATIONS=one row for each user and one row for each role
+COLLATIONS=one row for each character collation descriptor.
+COLUMN_PRIVILEGES=the visible user level access permissions of each visible column of each accessible table defined within this database
+CONSTRAINT_COLUMN_USAGE=one row for each column identified by a <column reference> contained in the <search condition> of a check constraint, domain constraint, or assertion.
+CHECK_CONSTRAINT_ROUTINE_USAGE=one row for each SQL-invoked routine identified as the subject routine of either a <routine invocation>, a <method reference>, a  <method invocation>, or a <static method invocation>  contained in an <assertion definition>, a <domain constraint>, or a <table constraint definition>.
+CHECK_CONSTRAINTS=one row for each domain constraint, table check constraint, and assertion.
+CONSTRAINT_TABLE_USAGE=one row for each table identified by a <table name> simply contained in a <table reference> contained in the <search condition> of a check constraint, domain constraint, or assertion.
+INFORMATION_SCHEMA_CATALOG_NAME=the catalog defined within this database
+ROLE_AUTHORIZATION_DESCRIPTORS=one row for each role granted directly to a grantee
+SCHEMATA=one row for each schema.
+SEQUENCES=one row for each external sequence generator
+TABLE_CONSTRAINTS=one row for each table constraint associated with a table
+TABLE_PRIVILEGES=the visible user level access permissions for each accessible table defined within this database
+USAGE_PRIVILEGES=one row for each usage privilege descriptor.
+VIEW_COLUMN_USAGE=one row for each column of a table that is explicitly or implicitly referenced in the <query expression> of the view being described.
+VIEW_ROUTINE_USAGE=one row for each SQL-invoked routine identified as the subject routine of either a <routine invocation>, a <method reference>, a <method invocation>, or a <static method invocation> contained in a <view definition>
+VIEW_TABLE_USAGE=one row for each table identified by a <table name> simply contained in a <table reference> that is contained in the <query expression> of a view
+VIEWS=the view descriptors of the accessible views defined within this database
diff --git a/src/org/hsqldb/resources/webserver.properties b/src/org/hsqldb/resources/webserver.properties
new file mode 100644
index 0000000..6781384
--- /dev/null
+++ b/src/org/hsqldb/resources/webserver.properties
@@ -0,0 +1,4 @@
+# English WebServer responses
+BAD_REQUEST=<HTML><BODY><H1>Bad Request</H1>The server could not understand this request.<P></BODY></HTML>
+NOT_FOUND=<HTML><BODY><H1>Not Found</H1>The server could not find this file.<P></BODY></HTML>
+FORBIDDEN=<HTML><BODY><H1>Forbidden</H1>Access is not allowed.<P></BODY></HTML>
diff --git a/src/org/hsqldb/result/Result.java b/src/org/hsqldb/result/Result.java
new file mode 100644
index 0000000..d886d8a
--- /dev/null
+++ b/src/org/hsqldb/result/Result.java
@@ -0,0 +1,1585 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.result;
+
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.StringReader;
+
+import org.hsqldb.ColumnBase;
+import org.hsqldb.Database;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Statement;
+import org.hsqldb.StatementTypes;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.rowio.RowInputBinary;
+import org.hsqldb.rowio.RowOutputInterface;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ *  The primary unit of communication between Connection, Server and Session
+ *  objects.
+ *
+ *  An HSQLDB Result object encapsulates all requests (such as to alter or
+ *  query session settings, to allocate and execute statements, etc.) and all
+ *  responses (such as exception indications, update counts, result sets and
+ *  result set metadata). It also implements the HSQL wire protocol for
+ *  comunicating all such requests and responses across the network.
+ *  Uses a navigator for data.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class Result {
+
+    public static final ResultMetaData sessionAttributesMetaData =
+        ResultMetaData.newResultMetaData(SessionInterface.INFO_LIMIT);
+
+    static {
+        for (int i = 0; i < Session.INFO_LIMIT; i++) {
+            sessionAttributesMetaData.columns[i] = new ColumnBase(null, null,
+                    null, null);
+        }
+
+        sessionAttributesMetaData.columns[Session.INFO_ID].setType(
+            Type.SQL_INTEGER);
+        sessionAttributesMetaData.columns[Session.INFO_INTEGER].setType(
+            Type.SQL_INTEGER);
+        sessionAttributesMetaData.columns[Session.INFO_BOOLEAN].setType(
+            Type.SQL_BOOLEAN);
+        sessionAttributesMetaData.columns[Session.INFO_VARCHAR].setType(
+            Type.SQL_VARCHAR);
+        sessionAttributesMetaData.prepareData();
+    }
+
+    private static final ResultMetaData emptyMeta =
+        ResultMetaData.newResultMetaData(0);
+    public static final Result emptyGeneratedResult =
+        Result.newDataResult(emptyMeta);
+    public static final Result updateZeroResult = newUpdateCountResult(0);
+    public static final Result updateOneResult  = newUpdateCountResult(1);
+
+    // type of result
+    public byte mode;
+
+    // database ID
+    int databaseID;
+
+    // session ID
+    long sessionID;
+
+    // result id
+    private long id;
+
+    // database name for new connection
+    private String databaseName;
+
+    // user / password for new connection
+    // error strings in error results
+    private String mainString;
+    private String subString;
+    private String zoneString;
+
+    // vendor error code
+    int errorCode;
+
+    // the exception if this is an error
+    private HsqlException exception;
+
+    // prepared statement id
+    long statementID;
+
+    // statement type based on whether it returns an update count or a result set
+    // type of session info requested
+    int statementReturnType;
+
+    // max rows (out)
+    // update count (in)
+    // fetch part result count (in)
+    // time zone seconds (connect)
+    public int updateCount;
+
+    // fetch size (in)
+    private int fetchSize;
+
+    // secondary result
+    private Result chainedResult;
+
+    //
+    private int lobCount;
+    ResultLob   lobResults;
+
+    /** A Result object's metadata */
+    public ResultMetaData metaData;
+
+    /** Additional meta data for parameters used in PREPARE_ACK results */
+    public ResultMetaData parameterMetaData;
+
+    /** Additional meta data for required generated columns */
+    public ResultMetaData generatedMetaData;
+
+    //
+    public int rsProperties;
+
+    //
+    public int queryTimeout;
+
+    //
+    int generateKeys;
+
+    // simple value for PSM, or parameter array
+    public Object valueData;
+
+    //
+    public Statement statement;
+
+    Result(int mode) {
+        this.mode = (byte) mode;
+    }
+
+    public Result(int mode, int count) {
+        this.mode   = (byte) mode;
+        updateCount = count;
+    }
+
+    public static Result newResult(RowSetNavigator nav) {
+
+        Result result = new Result(ResultConstants.DATA);
+
+        result.navigator = nav;
+
+        return result;
+    }
+
+    public static Result newResult(int type) {
+
+        RowSetNavigator navigator = null;
+        Result          result    = null;
+
+        switch (type) {
+
+            case ResultConstants.CALL_RESPONSE :
+            case ResultConstants.EXECUTE :
+            case ResultConstants.UPDATE_RESULT :
+                break;
+
+            case ResultConstants.BATCHEXECUTE :
+            case ResultConstants.BATCHEXECDIRECT :
+                navigator = new RowSetNavigatorClient(4);
+                break;
+
+            case ResultConstants.SETSESSIONATTR :
+            case ResultConstants.PARAM_METADATA :
+                navigator = new RowSetNavigatorClient(1);
+                break;
+
+            case ResultConstants.BATCHEXECRESPONSE :
+                navigator = new RowSetNavigatorClient(4);
+                break;
+
+            case ResultConstants.DATA :
+            case ResultConstants.DATAHEAD :
+            case ResultConstants.DATAROWS :
+                break;
+
+            case ResultConstants.LARGE_OBJECT_OP :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Result");
+            default :
+        }
+
+        result           = new Result(type);
+        result.navigator = navigator;
+
+        return result;
+    }
+
+    public static Result newResult(DataInput dataInput,
+                                   RowInputBinary in)
+                                   throws IOException, HsqlException {
+        return newResult(null, dataInput.readByte(), dataInput, in);
+    }
+
+    public static Result newResult(Session session, int mode,
+                                   DataInput dataInput,
+                                   RowInputBinary in)
+                                   throws IOException, HsqlException {
+
+        try {
+            if (mode == ResultConstants.LARGE_OBJECT_OP) {
+                return ResultLob.newLob(dataInput, false);
+            }
+
+            Result result = newResult(session, dataInput, in, mode);
+
+            return result;
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.X_08000);
+        }
+    }
+
+    public void readAdditionalResults(SessionInterface session,
+                                      DataInputStream inputStream,
+                                      RowInputBinary in)
+                                      throws IOException, HsqlException {
+
+        setSession(session);
+
+        Result  currentResult = this;
+        boolean hasLob        = false;
+
+        while (true) {
+            int addedResultMode = inputStream.readByte();
+
+            if (addedResultMode == ResultConstants.LARGE_OBJECT_OP) {
+                ResultLob resultLob = ResultLob.newLob(inputStream, false);
+
+                if (session instanceof Session) {
+                    ((Session) session).allocateResultLob(resultLob,
+                                                          inputStream);
+                }
+
+                currentResult.addLobResult(resultLob);
+
+                hasLob = true;
+
+                continue;
+            }
+
+            if (hasLob) {
+                hasLob = false;
+
+                if (session instanceof Session) {
+                    ((Session) session).registerResultLobs(currentResult);
+                }
+            }
+
+            if (addedResultMode == ResultConstants.NONE) {
+                return;
+            }
+
+            currentResult = newResult(null, inputStream, in, addedResultMode);
+
+            addChainedResult(currentResult);
+        }
+    }
+
+    private static Result newResult(Session session, DataInput dataInput,
+                                    RowInputBinary in,
+                                    int mode)
+                                    throws IOException, HsqlException {
+
+        Result result = newResult(mode);
+        int    length = dataInput.readInt();
+
+        in.resetRow(0, length);
+
+        byte[]    byteArray = in.getBuffer();
+        final int offset    = 4;
+
+        dataInput.readFully(byteArray, offset, length - offset);
+
+        switch (mode) {
+
+            case ResultConstants.GETSESSIONATTR :
+                result.statementReturnType = in.readByte();
+                break;
+
+            case ResultConstants.DISCONNECT :
+            case ResultConstants.RESETSESSION :
+            case ResultConstants.STARTTRAN :
+                break;
+
+            case ResultConstants.PREPARE :
+                result.setStatementType(in.readByte());
+
+                result.mainString   = in.readString();
+                result.rsProperties = in.readByte();
+                result.generateKeys = in.readByte();
+
+                if (result.generateKeys == ResultConstants
+                        .RETURN_GENERATED_KEYS_COL_NAMES || result
+                        .generateKeys == ResultConstants
+                        .RETURN_GENERATED_KEYS_COL_INDEXES) {
+                    result.generatedMetaData = new ResultMetaData(in);
+                }
+                break;
+
+            case ResultConstants.CLOSE_RESULT :
+                result.id = in.readLong();
+                break;
+
+            case ResultConstants.FREESTMT :
+                result.statementID = in.readLong();
+                break;
+
+            case ResultConstants.EXECDIRECT :
+                result.updateCount         = in.readInt();
+                result.fetchSize           = in.readInt();
+                result.statementReturnType = in.readByte();
+                result.mainString          = in.readString();
+                result.rsProperties        = in.readByte();
+                result.queryTimeout        = in.readShort();
+                result.generateKeys        = in.readByte();
+
+                if (result.generateKeys == ResultConstants
+                        .RETURN_GENERATED_KEYS_COL_NAMES || result
+                        .generateKeys == ResultConstants
+                        .RETURN_GENERATED_KEYS_COL_INDEXES) {
+                    result.generatedMetaData = new ResultMetaData(in);
+                }
+                break;
+
+            case ResultConstants.CONNECT :
+                result.databaseName = in.readString();
+                result.mainString   = in.readString();
+                result.subString    = in.readString();
+                result.zoneString   = in.readString();
+                result.updateCount  = in.readInt();
+                break;
+
+            case ResultConstants.ERROR :
+            case ResultConstants.WARNING :
+                result.mainString = in.readString();
+                result.subString  = in.readString();
+                result.errorCode  = in.readInt();
+                break;
+
+            case ResultConstants.CONNECTACKNOWLEDGE :
+                result.databaseID = in.readInt();
+                result.sessionID  = in.readLong();
+                result.mainString = in.readString();
+                break;
+
+            case ResultConstants.UPDATECOUNT :
+                result.updateCount = in.readInt();
+                break;
+
+            case ResultConstants.ENDTRAN : {
+                int type = in.readInt();
+
+                result.setActionType(type);                     // endtran type
+
+                switch (type) {
+
+                    case ResultConstants.TX_SAVEPOINT_NAME_RELEASE :
+                    case ResultConstants.TX_SAVEPOINT_NAME_ROLLBACK :
+                        result.mainString = in.readString();    // savepoint name
+                        break;
+
+                    case ResultConstants.TX_COMMIT :
+                    case ResultConstants.TX_ROLLBACK :
+                    case ResultConstants.TX_COMMIT_AND_CHAIN :
+                    case ResultConstants.TX_ROLLBACK_AND_CHAIN :
+                        break;
+
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500, "Result");
+                }
+
+                break;
+            }
+            case ResultConstants.SETCONNECTATTR : {
+                int type = in.readInt();                        // attr type
+
+                result.setConnectionAttrType(type);
+
+                switch (type) {
+
+                    case ResultConstants.SQL_ATTR_SAVEPOINT_NAME :
+                        result.mainString = in.readString();    // savepoint name
+                        break;
+
+                    //  case ResultConstants.SQL_ATTR_AUTO_IPD :
+                    //      - always true
+                    //  default: throw - case never happens
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500, "Result");
+                }
+
+                break;
+            }
+            case ResultConstants.PREPARE_ACK :
+                result.statementReturnType = in.readByte();
+                result.statementID         = in.readLong();
+                result.rsProperties        = in.readByte();
+                result.metaData            = new ResultMetaData(in);
+                result.parameterMetaData   = new ResultMetaData(in);
+                break;
+
+            case ResultConstants.CALL_RESPONSE :
+                result.updateCount  = in.readInt();
+                result.fetchSize    = in.readInt();
+                result.statementID  = in.readLong();
+                result.rsProperties = in.readByte();
+                result.metaData     = new ResultMetaData(in);
+                result.valueData    = readSimple(in, result.metaData);
+                break;
+
+            case ResultConstants.EXECUTE :
+                result.updateCount  = in.readInt();
+                result.fetchSize    = in.readInt();
+                result.statementID  = in.readLong();
+                result.rsProperties = in.readByte();
+                result.queryTimeout = in.readShort();
+
+                Statement statement =
+                    session.statementManager.getStatement(session,
+                        result.statementID);
+
+                result.statement = statement;
+
+                if (statement != null) {
+                    result.metaData = result.statement.getParametersMetaData();
+                }
+
+                result.valueData = readSimple(in, result.metaData);
+                break;
+
+            case ResultConstants.UPDATE_RESULT : {
+                result.id = in.readLong();
+
+                int type = in.readInt();
+
+                result.setActionType(type);
+
+                result.metaData  = new ResultMetaData(in);
+                result.valueData = readSimple(in, result.metaData);
+
+                break;
+            }
+            case ResultConstants.BATCHEXECRESPONSE :
+            case ResultConstants.BATCHEXECUTE :
+            case ResultConstants.BATCHEXECDIRECT :
+            case ResultConstants.SETSESSIONATTR : {
+                result.updateCount  = in.readInt();
+                result.fetchSize    = in.readInt();
+                result.statementID  = in.readLong();
+                result.queryTimeout = in.readShort();
+                result.metaData     = new ResultMetaData(in);
+
+                result.navigator.readSimple(in, result.metaData);
+
+                break;
+            }
+            case ResultConstants.PARAM_METADATA : {
+                result.metaData = new ResultMetaData(in);
+
+                result.navigator.read(in, result.metaData);
+
+                break;
+            }
+            case ResultConstants.REQUESTDATA : {
+                result.id          = in.readLong();
+                result.updateCount = in.readInt();
+                result.fetchSize   = in.readInt();
+
+                break;
+            }
+            case ResultConstants.DATAHEAD :
+            case ResultConstants.DATA : {
+                result.id           = in.readLong();
+                result.updateCount  = in.readInt();
+                result.fetchSize    = in.readInt();
+                result.rsProperties = in.readByte();
+                result.metaData     = new ResultMetaData(in);
+                result.navigator    = new RowSetNavigatorClient();
+
+                result.navigator.read(in, result.metaData);
+
+                break;
+            }
+            case ResultConstants.DATAROWS : {
+                result.metaData  = new ResultMetaData(in);
+                result.navigator = new RowSetNavigatorClient();
+
+                result.navigator.read(in, result.metaData);
+
+                break;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Result");
+        }
+
+        return result;
+    }
+
+    /**
+     * For interval PSM return values
+     */
+    public static Result newPSMResult(int type, String label, Object value) {
+
+        Result result = newResult(ResultConstants.VALUE);
+
+        result.errorCode  = type;
+        result.mainString = label;
+        result.valueData  = value;
+
+        return result;
+    }
+
+    /**
+     * For interval PSM return values
+     */
+    public static Result newPSMResult(Object value) {
+
+        Result result = newResult(ResultConstants.VALUE);
+
+        result.valueData = value;
+
+        return result;
+    }
+
+    /**
+     * For SQLPREPARE
+     * For parparation of SQL parepared statements.
+     */
+    public static Result newPrepareStatementRequest() {
+        return newResult(ResultConstants.PREPARE);
+    }
+
+    /**
+     * For SQLEXECUTE
+     * For execution of SQL prepared statements.
+     * The parameters are set afterwards as the Result is reused
+     */
+    public static Result newPreparedExecuteRequest(Type[] types,
+            long statementId) {
+
+        Result result = newResult(ResultConstants.EXECUTE);
+
+        result.metaData    = ResultMetaData.newSimpleResultMetaData(types);
+        result.statementID = statementId;
+        result.valueData   = ValuePool.emptyObjectArray;
+
+        return result;
+    }
+
+    /**
+     * For CALL_RESPONSE
+     * For execution of SQL callable statements.
+     */
+    public static Result newCallResponse(Type[] types, long statementId,
+                                         Object[] values) {
+
+        Result result = newResult(ResultConstants.CALL_RESPONSE);
+
+        result.metaData    = ResultMetaData.newSimpleResultMetaData(types);
+        result.statementID = statementId;
+        result.valueData   = values;
+
+        return result;
+    }
+
+    /**
+     * For UPDATE_RESULT
+     * The parameters are set afterwards as the Result is reused
+     */
+    public static Result newUpdateResultRequest(Type[] types, long id) {
+
+        Result result = newResult(ResultConstants.UPDATE_RESULT);
+
+        result.metaData  = ResultMetaData.newUpdateResultMetaData(types);
+        result.id        = id;
+        result.valueData = new Object[]{};
+
+        return result;
+    }
+
+    /**
+     * For UPDATE_RESULT results
+     * The parameters are set by this method as the Result is reused
+     */
+    public void setPreparedResultUpdateProperties(Object[] parameterValues) {
+        valueData = parameterValues;
+    }
+
+    /**
+     * For SQLEXECUTE results
+     * The parameters are set by this method as the Result is reused
+     */
+    public void setPreparedExecuteProperties(Object[] parameterValues,
+            int maxRows, int fetchSize, int resultProps) {
+
+        mode              = ResultConstants.EXECUTE;
+        valueData         = parameterValues;
+        updateCount       = maxRows;
+        this.fetchSize    = fetchSize;
+        this.rsProperties = resultProps;
+    }
+
+    /**
+     * For BATCHEXECUTE
+     */
+    public void setBatchedPreparedExecuteRequest() {
+
+        mode = ResultConstants.BATCHEXECUTE;
+
+        if (navigator == null) {
+            navigator = new RowSetNavigatorClient(4);
+        } else {
+            ((RowSetNavigatorClient) navigator).clear();
+        }
+
+        updateCount    = 0;
+        this.fetchSize = 0;
+    }
+
+    public void addBatchedPreparedExecuteRequest(Object[] parameterValues) {
+        ((RowSetNavigatorClient) navigator).add(parameterValues);
+    }
+
+    /**
+     * For BATCHEXECDIRECT
+     */
+    public static Result newBatchedExecuteRequest() {
+
+        Type[] types  = new Type[]{ Type.SQL_VARCHAR };
+        Result result = newResult(ResultConstants.BATCHEXECDIRECT);
+
+        result.metaData = ResultMetaData.newSimpleResultMetaData(types);
+
+        return result;
+    }
+
+    /**
+     * For BATCHEXERESPONSE for a BATCHEXECUTE or BATCHEXECDIRECT
+     */
+    public static Result newBatchedExecuteResponse(int[] updateCounts,
+            Result generatedResult, Result e) {
+
+        Result result = newResult(ResultConstants.BATCHEXECRESPONSE);
+
+        result.addChainedResult(generatedResult);
+        result.addChainedResult(e);
+
+        Type[] types = new Type[]{ Type.SQL_INTEGER };
+
+        result.metaData = ResultMetaData.newSimpleResultMetaData(types);
+
+        Object[][] table = new Object[updateCounts.length][];
+
+        for (int i = 0; i < updateCounts.length; i++) {
+            table[i] = new Object[]{ ValuePool.getInt(updateCounts[i]) };
+        }
+
+        ((RowSetNavigatorClient) result.navigator).setData(table);
+
+        return result;
+    }
+
+    public static Result newResetSessionRequest() {
+
+        Result result = newResult(ResultConstants.RESETSESSION);
+
+        return result;
+    }
+
+    public static Result newConnectionAttemptRequest(String user,
+            String password, String database, String zoneString,
+            int timeZoneSeconds) {
+
+        Result result = newResult(ResultConstants.CONNECT);
+
+        result.mainString   = user;
+        result.subString    = password;
+        result.zoneString   = zoneString;
+        result.databaseName = database;
+        result.updateCount  = timeZoneSeconds;
+
+        return result;
+    }
+
+    public static Result newConnectionAcknowledgeResponse(Database database,
+            long sessionID, int databaseID) {
+
+        Result result = newResult(ResultConstants.CONNECTACKNOWLEDGE);
+
+        result.sessionID  = sessionID;
+        result.databaseID = databaseID;
+        result.mainString =
+            database.getProperties().getClientPropertiesAsString();
+
+        return result;
+    }
+
+    public static Result newUpdateZeroResult() {
+        return new Result(ResultConstants.UPDATECOUNT, 0);
+    }
+
+    public static Result newUpdateCountResult(int count) {
+        return new Result(ResultConstants.UPDATECOUNT, count);
+    }
+
+    public static Result newUpdateCountResult(ResultMetaData meta, int count) {
+
+        Result result     = newResult(ResultConstants.UPDATECOUNT);
+        Result dataResult = newDataResult(meta);
+
+        result.updateCount = count;
+
+        result.addChainedResult(dataResult);
+
+        return result;
+    }
+
+    public static Result newSingleColumnResult(ResultMetaData meta) {
+
+        Result result = newResult(ResultConstants.DATA);
+
+        result.metaData  = meta;
+        result.navigator = new RowSetNavigatorClient();
+
+        return result;
+    }
+
+    public static Result newSingleColumnResult(String colName, Type type) {
+
+        Result result = newResult(ResultConstants.DATA);
+
+        result.metaData            = ResultMetaData.newResultMetaData(1);
+        result.metaData.columns[0] = new ColumnBase(null, null, null, colName);
+
+        result.metaData.columns[0].setType(type);
+        result.metaData.prepareData();
+
+        //
+        result.navigator = new RowSetNavigatorClient(8);
+
+        return result;
+    }
+
+    public static Result newSingleColumnStringResult(String colName,
+            String contents) {
+
+        Result result = Result.newSingleColumnResult("OPERATION",
+            Type.SQL_VARCHAR);
+        LineNumberReader lnr =
+            new LineNumberReader(new StringReader(contents));
+
+        while (true) {
+            String line = null;
+
+            try {
+                line = lnr.readLine();
+            } catch (Exception e) {}
+
+            if (line == null) {
+                break;
+            }
+
+            result.getNavigator().add(new Object[]{ line });
+        }
+
+        return result;
+    }
+
+    public static Result newPrepareResponse(Statement statement) {
+
+        Result r = newResult(ResultConstants.PREPARE_ACK);
+
+        r.statement   = statement;
+        r.statementID = statement.getID();
+
+        int csType = statement.getType();
+
+        r.statementReturnType =
+            (csType == StatementTypes.SELECT_CURSOR || csType == StatementTypes
+                .CALL) ? StatementTypes.RETURN_RESULT
+                       : StatementTypes.RETURN_COUNT;
+        r.metaData          = statement.getResultMetaData();
+        r.parameterMetaData = statement.getParametersMetaData();
+
+        return r;
+    }
+
+    public static Result newFreeStmtRequest(long statementID) {
+
+        Result r = newResult(ResultConstants.FREESTMT);
+
+        r.statementID = statementID;
+
+        return r;
+    }
+
+    /**
+     * For direct execution of SQL statements. The statement and other
+     *  parameters are set afterwards as the Result is reused
+     */
+    public static Result newExecuteDirectRequest() {
+        return newResult(ResultConstants.EXECDIRECT);
+    }
+
+    /**
+     * For both EXECDIRECT and PREPARE
+     */
+    public void setPrepareOrExecuteProperties(String sql, int maxRows,
+            int fetchSize, int statementReturnType, int timeout,
+            int resultSetProperties, int keyMode, int[] generatedIndexes,
+            String[] generatedNames) {
+
+        mainString               = sql;
+        updateCount              = maxRows;
+        this.fetchSize           = fetchSize;
+        this.statementReturnType = statementReturnType;
+        this.queryTimeout        = timeout;
+        rsProperties             = resultSetProperties;
+        generateKeys             = keyMode;
+        generatedMetaData =
+            ResultMetaData.newGeneratedColumnsMetaData(generatedIndexes,
+                generatedNames);
+    }
+
+    public static Result newSetSavepointRequest(String name) {
+
+        Result result;
+
+        result = newResult(ResultConstants.SETCONNECTATTR);
+
+        result.setConnectionAttrType(ResultConstants.SQL_ATTR_SAVEPOINT_NAME);
+        result.setMainString(name);
+
+        return result;
+    }
+
+    public static Result newRequestDataResult(long id, int offset, int count) {
+
+        Result result = newResult(ResultConstants.REQUESTDATA);
+
+        result.id          = id;
+        result.updateCount = offset;
+        result.fetchSize   = count;
+
+        return result;
+    }
+
+    public static Result newDataResult(ResultMetaData md) {
+
+        Result result = newResult(ResultConstants.DATA);
+
+        result.navigator = new RowSetNavigatorClient();
+        result.metaData  = md;
+
+        return result;
+    }
+
+    /**
+     * initially, only used for updatability
+     */
+    public int getExecuteProperties() {
+        return rsProperties;
+    }
+
+    /**
+     * For DATA
+     */
+    public void setDataResultProperties(int maxRows, int fetchSize,
+                                        int resultSetScrollability,
+                                        int resultSetConcurrency,
+                                        int resultSetHoldability) {
+
+        updateCount    = maxRows;
+        this.fetchSize = fetchSize;
+        rsProperties = ResultProperties.getValueForJDBC(resultSetScrollability,
+                resultSetConcurrency, resultSetHoldability);
+    }
+
+    public static Result newDataHeadResult(SessionInterface session,
+                                           Result source, int offset,
+                                           int count) {
+
+        if (offset + count > source.navigator.getSize()) {
+            count = source.navigator.getSize() - offset;
+        }
+
+        Result result = newResult(ResultConstants.DATAHEAD);
+
+        result.metaData = source.metaData;
+        result.navigator = new RowSetNavigatorClient(source.navigator, offset,
+                count);
+
+        result.navigator.setId(source.navigator.getId());
+        result.setSession(session);
+
+        result.rsProperties = source.rsProperties;
+        result.fetchSize    = source.fetchSize;
+
+        return result;
+    }
+
+    public static Result newDataRowsResult(Result source, int offset,
+                                           int count) {
+
+        if (offset + count > source.navigator.getSize()) {
+            count = source.navigator.getSize() - offset;
+        }
+
+        Result result = newResult(ResultConstants.DATAROWS);
+
+        result.id       = source.id;
+        result.metaData = source.metaData;
+        result.navigator = new RowSetNavigatorClient(source.navigator, offset,
+                count);
+
+        return result;
+    }
+
+    public static Result newDataRowsResult(RowSetNavigator navigator) {
+
+        Result result = newResult(ResultConstants.DATAROWS);
+
+        result.navigator = navigator;
+
+        return result;
+    }
+
+    /**
+     * Result structure used for set/get session attributes
+     */
+    public static Result newSessionAttributesResult() {
+
+        Result result = newResult(ResultConstants.DATA);
+
+        result.navigator = new RowSetNavigatorClient(1);
+        result.metaData  = sessionAttributesMetaData;
+
+        result.navigator.add(new Object[SessionInterface.INFO_LIMIT]);
+
+        return result;
+    }
+
+    public static Result newWarningResult(HsqlException w) {
+
+        Result result = newResult(ResultConstants.WARNING);
+
+        result.mainString = w.getMessage();
+        result.subString  = w.getSQLState();
+        result.errorCode  = w.getErrorCode();
+
+        return result;
+    }
+
+    public static Result newErrorResult(Throwable t) {
+        return newErrorResult(t, null);
+    }
+
+    /** @todo 1.9.0 fredt - move the messages to Error.java */
+    public static Result newErrorResult(Throwable t, String statement) {
+
+        Result result = newResult(ResultConstants.ERROR);
+
+        if (t instanceof HsqlException) {
+            result.exception  = (HsqlException) t;
+            result.mainString = result.exception.getMessage();
+            result.subString  = result.exception.getSQLState();
+
+            if (statement != null) {
+                result.mainString += " in statement [" + statement + "]";
+            }
+
+            result.errorCode = result.exception.getErrorCode();
+        } else if (t instanceof OutOfMemoryError) {
+
+            // gc() at this point may clear the memory allocated so far
+
+            /** @todo 1.9.0 - review if it's better to gc higher up the stack */
+            System.gc();
+
+            result.exception  = Error.error(ErrorCode.OUT_OF_MEMORY, t);
+            result.mainString = result.exception.getMessage();
+            result.subString  = result.exception.getSQLState();
+            result.errorCode  = result.exception.getErrorCode();
+        } else {
+            result.exception = Error.error(ErrorCode.GENERAL_ERROR, t);
+            result.mainString = result.exception.getMessage() + " "
+                                + t.getMessage();
+            result.subString = result.exception.getSQLState();
+            result.errorCode = result.exception.getErrorCode();
+
+            if (statement != null) {
+                result.mainString += " in statement [" + statement + "]";
+            }
+        }
+
+        return result;
+    }
+
+    public void write(DataOutputStream dataOut,
+                      RowOutputInterface rowOut)
+                      throws IOException, HsqlException {
+
+        rowOut.reset();
+        rowOut.writeByte(mode);
+
+        int startPos = rowOut.size();
+
+        rowOut.writeSize(0);
+
+        switch (mode) {
+
+            case ResultConstants.GETSESSIONATTR :
+                rowOut.writeByte(statementReturnType);
+                break;
+
+            case ResultConstants.DISCONNECT :
+            case ResultConstants.RESETSESSION :
+            case ResultConstants.STARTTRAN :
+                break;
+
+            case ResultConstants.PREPARE :
+                rowOut.writeByte(statementReturnType);
+                rowOut.writeString(mainString);
+                rowOut.writeByte(rsProperties);
+                rowOut.writeByte(generateKeys);
+
+                if (generateKeys == ResultConstants
+                        .RETURN_GENERATED_KEYS_COL_NAMES || generateKeys == ResultConstants
+                        .RETURN_GENERATED_KEYS_COL_INDEXES) {
+                    generatedMetaData.write(rowOut);
+                }
+                break;
+
+            case ResultConstants.FREESTMT :
+                rowOut.writeLong(statementID);
+                break;
+
+            case ResultConstants.CLOSE_RESULT :
+                rowOut.writeLong(id);
+                break;
+
+            case ResultConstants.EXECDIRECT :
+                rowOut.writeInt(updateCount);
+                rowOut.writeInt(fetchSize);
+                rowOut.writeByte(statementReturnType);
+                rowOut.writeString(mainString);
+                rowOut.writeByte(rsProperties);
+                rowOut.writeShort(queryTimeout);
+                rowOut.writeByte(generateKeys);
+
+                if (generateKeys == ResultConstants
+                        .RETURN_GENERATED_KEYS_COL_NAMES || generateKeys == ResultConstants
+                        .RETURN_GENERATED_KEYS_COL_INDEXES) {
+                    generatedMetaData.write(rowOut);
+                }
+                break;
+
+            case ResultConstants.CONNECT :
+                rowOut.writeString(databaseName);
+                rowOut.writeString(mainString);
+                rowOut.writeString(subString);
+                rowOut.writeString(zoneString);
+                rowOut.writeInt(updateCount);
+                break;
+
+            case ResultConstants.ERROR :
+            case ResultConstants.WARNING :
+                rowOut.writeString(mainString);
+                rowOut.writeString(subString);
+                rowOut.writeInt(errorCode);
+                break;
+
+            case ResultConstants.CONNECTACKNOWLEDGE :
+                rowOut.writeInt(databaseID);
+                rowOut.writeLong(sessionID);
+                rowOut.writeString(mainString);
+                break;
+
+            case ResultConstants.UPDATECOUNT :
+                rowOut.writeInt(updateCount);
+                break;
+
+            case ResultConstants.ENDTRAN : {
+                int type = getActionType();
+
+                rowOut.writeInt(type);                     // endtran type
+
+                switch (type) {
+
+                    case ResultConstants.TX_SAVEPOINT_NAME_RELEASE :
+                    case ResultConstants.TX_SAVEPOINT_NAME_ROLLBACK :
+                        rowOut.writeString(mainString);    // savepoint name
+                        break;
+
+                    case ResultConstants.TX_COMMIT :
+                    case ResultConstants.TX_ROLLBACK :
+                    case ResultConstants.TX_COMMIT_AND_CHAIN :
+                    case ResultConstants.TX_ROLLBACK_AND_CHAIN :
+                        break;
+
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500, "Result");
+                }
+
+                break;
+            }
+            case ResultConstants.PREPARE_ACK :
+                rowOut.writeByte(statementReturnType);
+                rowOut.writeLong(statementID);
+                rowOut.writeByte(rsProperties);
+                metaData.write(rowOut);
+                parameterMetaData.write(rowOut);
+                break;
+
+            case ResultConstants.CALL_RESPONSE :
+                rowOut.writeInt(updateCount);
+                rowOut.writeInt(fetchSize);
+                rowOut.writeLong(statementID);
+                rowOut.writeByte(rsProperties);
+                metaData.write(rowOut);
+                writeSimple(rowOut, metaData, (Object[]) valueData);
+                break;
+
+            case ResultConstants.EXECUTE :
+                rowOut.writeInt(updateCount);
+                rowOut.writeInt(fetchSize);
+                rowOut.writeLong(statementID);
+                rowOut.writeByte(rsProperties);
+                rowOut.writeShort(queryTimeout);
+                writeSimple(rowOut, metaData, (Object[]) valueData);
+                break;
+
+            case ResultConstants.UPDATE_RESULT :
+                rowOut.writeLong(id);
+                rowOut.writeInt(getActionType());
+                metaData.write(rowOut);
+                writeSimple(rowOut, metaData, (Object[]) valueData);
+                break;
+
+            case ResultConstants.BATCHEXECRESPONSE :
+            case ResultConstants.BATCHEXECUTE :
+            case ResultConstants.BATCHEXECDIRECT :
+            case ResultConstants.SETSESSIONATTR : {
+                rowOut.writeInt(updateCount);
+                rowOut.writeInt(fetchSize);
+                rowOut.writeLong(statementID);
+                rowOut.writeShort(queryTimeout);
+                metaData.write(rowOut);
+                navigator.writeSimple(rowOut, metaData);
+
+                break;
+            }
+            case ResultConstants.PARAM_METADATA : {
+                metaData.write(rowOut);
+                navigator.write(rowOut, metaData);
+
+                break;
+            }
+            case ResultConstants.SETCONNECTATTR : {
+                int type = getConnectionAttrType();
+
+                rowOut.writeInt(type);                     // attr type / updateCount
+
+                switch (type) {
+
+                    case ResultConstants.SQL_ATTR_SAVEPOINT_NAME :
+                        rowOut.writeString(mainString);    // savepoint name
+                        break;
+
+                    // case ResultConstants.SQL_ATTR_AUTO_IPD // always true
+                    // default: // throw, but case never happens
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500, "Result");
+                }
+
+                break;
+            }
+            case ResultConstants.REQUESTDATA : {
+                rowOut.writeLong(id);
+                rowOut.writeInt(updateCount);
+                rowOut.writeInt(fetchSize);
+
+                break;
+            }
+            case ResultConstants.DATAROWS :
+                metaData.write(rowOut);
+                navigator.write(rowOut, metaData);
+                break;
+
+            case ResultConstants.DATAHEAD :
+            case ResultConstants.DATA :
+                rowOut.writeLong(id);
+                rowOut.writeInt(updateCount);
+                rowOut.writeInt(fetchSize);
+                rowOut.writeByte(rsProperties);
+                metaData.write(rowOut);
+                navigator.write(rowOut, metaData);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Result");
+        }
+
+        rowOut.writeIntData(rowOut.size() - startPos, startPos);
+        dataOut.write(rowOut.getOutputStream().getBuffer(), 0, rowOut.size());
+
+        int    count   = getLobCount();
+        Result current = this;
+
+        for (int i = 0; i < count; i++) {
+            ResultLob lob = current.lobResults;
+
+            lob.writeBody(dataOut);
+
+            current = current.lobResults;
+        }
+
+        if (chainedResult == null) {
+            dataOut.writeByte(ResultConstants.NONE);
+        } else {
+            chainedResult.write(dataOut, rowOut);
+        }
+
+        dataOut.flush();
+    }
+
+    public int getType() {
+        return mode;
+    }
+
+    public boolean isData() {
+        return mode == ResultConstants.DATA
+               || mode == ResultConstants.DATAHEAD;
+    }
+
+    public boolean isError() {
+        return mode == ResultConstants.ERROR;
+    }
+
+    public boolean isWarning() {
+        return mode == ResultConstants.WARNING;
+    }
+
+    public boolean isUpdateCount() {
+        return mode == ResultConstants.UPDATECOUNT;
+    }
+
+    public boolean isSimpleValue() {
+        return mode == ResultConstants.VALUE;
+    }
+
+    public boolean hasGeneratedKeys() {
+        return mode == ResultConstants.UPDATECOUNT && chainedResult != null;
+    }
+
+    public HsqlException getException() {
+        return exception;
+    }
+
+    public long getStatementID() {
+        return statementID;
+    }
+
+    public void setStatementID(long statementId) {
+        this.statementID = statementId;
+    }
+
+    public String getMainString() {
+        return mainString;
+    }
+
+    public void setMainString(String sql) {
+        this.mainString = sql;
+    }
+
+    public String getSubString() {
+        return subString;
+    }
+
+    public String getZoneString() {
+        return zoneString;
+    }
+
+    public int getErrorCode() {
+        return errorCode;
+    }
+
+    public Object getValueObject() {
+        return valueData;
+    }
+
+    public void setValueObject(Object value) {
+        valueData = value;
+    }
+
+    public Statement getStatement() {
+        return statement;
+    }
+
+    public void setStatement(Statement statement) {
+        this.statement = statement;
+    }
+
+    public String getDatabaseName() {
+        return databaseName;
+    }
+
+    public void setMaxRows(int count) {
+        updateCount = count;
+    }
+
+    public int getFetchSize() {
+        return this.fetchSize;
+    }
+
+    public void setFetchSize(int count) {
+        fetchSize = count;
+    }
+
+    public int getUpdateCount() {
+        return updateCount;
+    }
+
+    public int getConnectionAttrType() {
+        return updateCount;
+    }
+
+    public void setConnectionAttrType(int type) {
+        updateCount = type;
+    }
+
+    public int getActionType() {
+        return updateCount;
+    }
+
+    public void setActionType(int type) {
+        updateCount = type;
+    }
+
+    public long getSessionId() {
+        return sessionID;
+    }
+
+    public void setSessionId(long id) {
+        sessionID = id;
+    }
+
+    public void setSession(SessionInterface session) {
+
+        if (navigator != null) {
+            navigator.setSession(session);
+        }
+    }
+
+    public int getDatabaseId() {
+        return databaseID;
+    }
+
+    public void setDatabaseId(int id) {
+        databaseID = id;
+    }
+
+    public long getResultId() {
+        return id;
+    }
+
+    public void setResultId(long id) {
+
+        this.id = id;
+
+        if (navigator != null) {
+            navigator.setId(id);
+        }
+    }
+
+    public void setUpdateCount(int count) {
+        updateCount = count;
+    }
+
+    public void setAsTransactionEndRequest(int subType, String savepoint) {
+
+        mode        = ResultConstants.ENDTRAN;
+        updateCount = subType;
+        mainString  = savepoint == null ? ""
+                                        : savepoint;
+    }
+
+    public Object[] getSingleRowData() {
+
+        Object[] data = (Object[]) initialiseNavigator().getNext();
+
+        data = (Object[]) ArrayUtil.resizeArrayIfDifferent(data,
+                metaData.getColumnCount());
+
+        return data;
+    }
+
+    public Object[] getParameterData() {
+        return (Object[]) valueData;
+    }
+
+    public Object[] getSessionAttributes() {
+        return (Object[]) initialiseNavigator().getNext();
+    }
+
+    public void setResultType(int type) {
+        mode = (byte) type;
+    }
+
+    public void setStatementType(int type) {
+        statementReturnType = type;
+    }
+
+    public int getStatementType() {
+        return statementReturnType;
+    }
+
+    public int getGeneratedResultType() {
+        return generateKeys;
+    }
+
+    public ResultMetaData getGeneratedResultMetaData() {
+        return generatedMetaData;
+    }
+
+    public Result getChainedResult() {
+        return chainedResult;
+    }
+
+    public Result getUnlinkChainedResult() {
+
+        Result result = chainedResult;
+
+        chainedResult = null;
+
+        return result;
+    }
+
+    public void addChainedResult(Result result) {
+
+        Result current = this;
+
+        while (current.chainedResult != null) {
+            current = current.chainedResult;
+        }
+
+        current.chainedResult = result;
+    }
+
+    public void addWarnings(HsqlException[] warnings) {
+
+        for (int i = 0; i < warnings.length; i++) {
+            Result warning = newWarningResult(warnings[i]);
+
+            addChainedResult(warning);
+        }
+    }
+
+    public int getLobCount() {
+        return lobCount;
+    }
+
+    public ResultLob getLOBResult() {
+        return lobResults;
+    }
+
+    public void addLobResult(ResultLob result) {
+
+        Result current = this;
+
+        while (current.lobResults != null) {
+            current = current.lobResults;
+        }
+
+        current.lobResults = result;
+
+        lobCount++;
+    }
+
+    public void clearLobResults() {
+        lobResults = null;
+        lobCount   = 0;
+    }
+
+    private static Object[] readSimple(RowInputBinary in,
+                                       ResultMetaData meta)
+                                       throws IOException {
+
+        int size = in.readInt();
+
+        return in.readData(meta.columnTypes);
+    }
+
+    private static void writeSimple(RowOutputInterface out,
+                                    ResultMetaData meta,
+                                    Object[] data) throws IOException {
+
+        out.writeInt(1);
+        out.writeData(meta.getColumnCount(), meta.columnTypes, data, null,
+                      null);
+    }
+
+//----------- Navigation
+    public RowSetNavigator navigator;
+
+    public RowSetNavigator getNavigator() {
+        return navigator;
+    }
+
+    public void setNavigator(RowSetNavigator navigator) {
+        this.navigator = navigator;
+    }
+
+    public RowSetNavigator initialiseNavigator() {
+
+        switch (mode) {
+
+            case ResultConstants.BATCHEXECUTE :
+            case ResultConstants.BATCHEXECDIRECT :
+            case ResultConstants.BATCHEXECRESPONSE :
+            case ResultConstants.SETSESSIONATTR :
+            case ResultConstants.PARAM_METADATA :
+                navigator.beforeFirst();
+
+                return navigator;
+
+            case ResultConstants.DATA :
+            case ResultConstants.DATAHEAD :
+                navigator.reset();
+
+                return navigator;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Result");
+        }
+    }
+}
diff --git a/src/org/hsqldb/result/ResultConstants.java b/src/org/hsqldb/result/ResultConstants.java
new file mode 100644
index 0000000..128d4ea
--- /dev/null
+++ b/src/org/hsqldb/result/ResultConstants.java
@@ -0,0 +1,710 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.result;
+
+import org.hsqldb.StatementTypes;
+
+/**
+ * An enumeration of the request and response mode values used to communicate
+ * between the client and the engine when sending Result objects back
+ * and forth.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @since 1.9.0
+ * @version 1.7.2
+ */
+
+// fredt@users - the constants from the SQL standards are used freely where a
+// similar function is performed. The Result objects do not necessarily contain
+// the same information as stated in SQL standard for CLI.
+public interface ResultConstants {
+
+    /** The offset at which HSQLDB API Result mode values start. */
+    int HSQL_API_BASE = 0;
+
+    /**
+     * Not a result
+     */
+    int NONE = HSQL_API_BASE + 0;
+
+    /**
+     * Indicates that the Result object encapsulates an update
+     * count response.
+     */
+    int UPDATECOUNT = HSQL_API_BASE + 1;
+
+    /**
+     * Indicates that the Result object encapsualtes an
+     * error response.
+     */
+    int ERROR = HSQL_API_BASE + 2;
+
+    /**
+     * Indicates that the Result object encapsulates a result
+     * set response containing data.
+     */
+    int DATA = HSQL_API_BASE + 3;
+
+    /**
+     * Indicates that the Result object encapsulates a response
+     * that communicates the acknowlegement of newly allocated
+     * Statement object in the form of its statementID
+     * and metadata
+     */
+    int PREPARE_ACK = HSQL_API_BASE + 4;
+
+    /**
+     * Indicates that the Result object encapsulates a result
+     * set for setting session attributes.
+     */
+    int SETSESSIONATTR = HSQL_API_BASE + 6;
+
+    /**
+     * Indicates that the Result object encapsulates a request
+     * to get session attributes.
+     */
+    int GETSESSIONATTR = HSQL_API_BASE + 7;
+
+    /**
+     * Indicates that the Result object encapsulates a batch of statements
+     */
+    int BATCHEXECDIRECT = HSQL_API_BASE + 8;
+
+    /**
+     * Indicates that the Result object encapsulates a batch of prepared
+     * statement parameter values
+     */
+    int BATCHEXECUTE = HSQL_API_BASE + 9;
+
+    /**
+     * Indicates that the Result object encapsulates a request to start a new
+     * internal session for the connection
+     */
+    int RESETSESSION = HSQL_API_BASE + 10;
+
+    /**
+     * Indicates that the Result object encapsulates a response to a connection
+     * attempt that was successful
+     */
+    int CONNECTACKNOWLEDGE = HSQL_API_BASE + 11;
+
+    /**
+     * Indicates that the Result object encapsulates a request to prepare
+     * to commit as the first phase of a two-phase commit
+     */
+    int PREPARECOMMIT = HSQL_API_BASE + 12;
+
+    /**
+     * Indicates that the Result object encapsulates a request to return
+     * some rows of data
+     */
+    int REQUESTDATA = HSQL_API_BASE + 13;
+
+    /**
+     * Indicates that the Result object encapsulates a set of data rows
+     * without metadata
+     */
+    int DATAROWS = HSQL_API_BASE + 14;
+
+    /**
+     * Indicates that the Result object encapsulates a set of data rows
+     * with metadata
+     */
+    int DATAHEAD = HSQL_API_BASE + 15;
+
+    /**
+     * Indicates that the Result object encapsulates a set of update counts
+     * for a batch execution
+     */
+    int BATCHEXECRESPONSE = HSQL_API_BASE + 16;
+
+    /**
+     * Only for metadata, indicates that the metadata is for the parameters.
+     */
+    int PARAM_METADATA = HSQL_API_BASE + 17;
+
+    /**
+     * Common result type for all large object operations
+     */
+    int LARGE_OBJECT_OP = HSQL_API_BASE + 18;
+
+    /**
+     * Warning
+     */
+    int WARNING = HSQL_API_BASE + 19;
+
+    /**
+     * Indicates that Result encapsulates a request to establish a connection.
+     */
+    int CONNECT = HSQL_API_BASE + 31;
+
+    /**
+     * Indicates that Result encapsulates a request to terminate an
+     * established connection.
+     */
+    int DISCONNECT = HSQL_API_BASE + 32;
+
+    /**
+     * Indicates that Result encapsulates a request to terminate an
+     * SQL-transaction.
+     */
+    int ENDTRAN = HSQL_API_BASE + 33;
+
+    /**
+     * Indicates that Result encapsulates a request to execute a statement
+     * directly.
+     */
+    int EXECDIRECT = HSQL_API_BASE + 34;
+
+    /**
+     * Indicates that Result encapsulates a request to execute a prepared
+     * statement.
+     */
+    int EXECUTE = HSQL_API_BASE + 35;
+
+    /**
+     * Indicates that Result encapsulates a request to deallocate an
+     * SQL-statement.
+     */
+    int FREESTMT = HSQL_API_BASE + 36;
+
+    /**
+     * Indicates that Result encapsulates a request to prepare a statement.
+     */
+    int PREPARE = HSQL_API_BASE + 37;
+
+    /**
+     * Indicates that Result encapsulates a request to set the value of an
+     * SQL-connection attribute.
+     */
+    int SETCONNECTATTR = HSQL_API_BASE + 38;
+
+    /**
+     * Indicates that Result encapsulates a request to explicitly start an
+     * SQL-transaction and set its characteristics.
+     */
+    int STARTTRAN = HSQL_API_BASE + 39;
+
+    /**
+     * Indicates that the Result encapsulates a request to close a result set
+     */
+    int CLOSE_RESULT = HSQL_API_BASE + 40;
+
+    /**
+     * Indicates that the Result encapsulates a request to update or insert into a result set
+     */
+    int UPDATE_RESULT = HSQL_API_BASE + 41;
+
+    /**
+     * Indicates that the Result encapsulates a simple value for internal use
+     */
+    int VALUE = HSQL_API_BASE + 42;
+
+    /**
+     * Indicates that the Result encapsulates a response to a procedure call via CallableStatement
+     */
+    int CALL_RESPONSE    = HSQL_API_BASE + 43;
+    int MODE_UPPER_LIMIT = HSQL_API_BASE + 44;
+
+//    /** The offset at which the standard SQL API Result mode values start. */
+//    int SQL_API_BASE = 0x00010000;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to allocate an
+//     * SQL-connection and assign a handle to it.
+//     */
+//    int SQLALLOCCONNECT     = SQL_API_BASE + 1;
+//    /**
+//     * Indicates that Result encapsulates a request to allocate an
+//     * SQL-environment and assign a handle to it.
+//     */
+//    int SQLALLOCENV         = SQL_API_BASE + 2;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to allocate a resource
+//     * and assign a handle to it.
+//     */
+//    int SQLALLOCHANDLE      = SQL_API_BASE + 1001;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to allocate an
+//     * SQL-statement and assign a handle to it.
+//     */
+//    int SQLALLOCSTMT        = SQL_API_BASE + 3;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to describe a target
+//     * specification or array of target specifications.
+//     */
+//    int SQLBINDCOL          = SQL_API_BASE + 4;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to describe a
+//     * dynamic parameter specification and its value.
+//     */
+//    int SQLBINDPARAMETER    = SQL_API_BASE + 72;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to cancel execution of
+//     * a CLI routine.
+//     */
+//    int SQLCANCEL           = SQL_API_BASE + 5;
+//
+//    /** Indicates that Result encapsulates a request to close a cursor. */
+//    int SQLCLOSECURSOR      = SQL_API_BASE + 1003;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get a
+//     * column attribute.
+//     */
+//    int SQLCOLATTRIBUTE     = SQL_API_BASE + 6;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to return a result set that
+//     * contains a list of the privileges held on the columns whose names adhere
+//     * to the requested pattern or patterns within a single specified table
+//     * stored in the Information Schema of the connected data source.
+//     */
+//    int SQLCOLUMNPRIVILEGES = SQL_API_BASE + 56;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to, based on the specified
+//     * selection criteria, return a result set that contains information about
+//     * columns of tables stored in the information schemas of the connected
+//     * data source.
+//     */
+//    int SQLCOLUMNS          = SQL_API_BASE + 40;
+//
+//
+//    /**
+//     * Indicates that Result encapsulates a request to establish a connection.
+//     */
+//    int SQLCONNECT = SQL_API_BASE + 7;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to copy a CLI descriptor.
+//     */
+//    int SQLCOPYDESC         = SQL_API_BASE + 1004;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get server name(s) that
+//     * the application can connect to, along with description information,
+//     * if available.
+//     */
+//    int SQLDATASOURCES      = SQL_API_BASE + 57;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get column attributes.
+//     */
+//    int SQLDESCRIBECOL      = SQL_API_BASE + 8;
+//
+//
+//    /**
+//     * Indicates that Result encapsulates a request to terminate an
+//     * established connection.
+//     */
+//    int SQLDISCONNECT = SQL_API_BASE + 9;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to terminate an
+//     * SQL-transaction.
+//     */
+//    int SQLENDTRAN = SQL_API_BASE + 1005;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to return diagnostic
+//     * information.
+//     */
+//    int SQLERROR            = SQL_API_BASE + 10;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to execute a statement
+//     * directly.
+//     */
+//    int SQLEXECDIRECT = SQL_API_BASE + 11;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to execute a prepared
+//     * statement.
+//     */
+//    int SQLEXECUTE = SQL_API_BASE + 12;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to fetch the next row of
+//     * a cursor.
+//     */
+//
+//  int SQLFETCH = SQL_API_BASE + 13;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to position a cursor on
+//     * the specified row and retrieve values from that row.
+//     */
+//  int SQLFETCHSCROLL = SQL_API_BASE + 1021;
+//    /**
+//     * Indicates that Result encapsulates a request to return a result set
+//     * that contains information about foreign keys either in or referencing
+//     * a single specified table stored in the Information Schema of the
+//     * connected data source.
+//     */
+//    int SQLFOREIGNKEYS      = SQL_API_BASE + 60;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to deallocate an
+//     * SQL-connection.
+//     */
+//    int SQLFREECONNECT      = SQL_API_BASE + 14;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to deallocate an
+//     * SQL-environment.
+//     */
+//    int SQLFREEENV          = SQL_API_BASE + 15;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to free a resource.
+//     */
+//    int SQLFREEHANDLE       = SQL_API_BASE + 1006;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to deallocate an
+//     * SQL-statement.
+//     */
+//    int SQLFREESTMT = SQL_API_BASE + 16;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get the value of an
+//     * SQL-connection attribute.
+//     */
+//    int SQLGETCONNECTATTR   = SQL_API_BASE + 1007;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get a cursor name.
+//     */
+//    int SQLGETCURSORNAME    = SQL_API_BASE + 17;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to retrieve a column value.
+//     */
+//    int SQLGETDATA          = SQL_API_BASE + 43;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get a field from a CLI
+//     * descriptor area.
+//     */
+//    int SQLGETDESCFIELD     = SQL_API_BASE + 1008;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get commonly-used
+//     * fields from a CLI descriptor area.
+//     */
+//    int SQLGETDESCREC       = SQL_API_BASE + 1009;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get information from a
+//     * CLI diagnostics area.
+//     */
+//    int SQLGETDIAGFIELD     = SQL_API_BASE + 1010;
+//
+//    /** Indicates that Result encapsulates a request to get commonly-used
+//     * information from a CLI diagnostics area.
+//     */
+//    int SQLGETDIAGREC       = SQL_API_BASE + 1011;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get the value of an
+//     * SQL-environment attribute.
+//     */
+//    int SQLGETENVATTR       = SQL_API_BASE + 1012;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get information
+//     * about features supported by the CLI implementation.
+//     */
+//    int SQLGETFEATUREINFO   = SQL_API_BASE + 1027;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to determine whether a CLI
+//     * routine is supported.
+//     */
+//    int SQLGETFUNCTIONS     = SQL_API_BASE + 44;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get information about
+//     * the implementation.
+//     */
+//    int SQLGETINFO          = SQL_API_BASE + 45;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to retrieve the length of
+//     * the character or octet string value represented by a Large Object
+//     * locator.
+//     */
+//    int SQLGETLENGTH        = SQL_API_BASE + 1022;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to retrieve the value of a
+//     * dynamic output parameter.
+//     */
+//    int SQLGETPARAMDATA     = SQL_API_BASE + 1025;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to retrieve the starting
+//     * position of a string value within another string value, where the second
+//     * string value is represented by a Large Object locator.
+//     */
+//    int SQLGETPOSITION      = SQL_API_BASE + 1023;
+//
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get information about
+//     * general value specifications supported by the implementation.
+//     */
+//    int SQLGETSESSIONINFO = SQL_API_BASE + 1028;
+//    /**
+//     * Indicates that Result encapsulates a request to get the value of an
+//     * SQL-statement attribute.
+//     */
+//    int SQLGETSTMTATTR      = SQL_API_BASE + 1014;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to either retrieve a
+//     * portion of a character or octet string value that is represented by
+//     * a Large Object locator or create a Large Object value at the server
+//     * and retrieve a Large Object locator for that value.
+//     */
+//    int SQLGETSUBSTRING     = SQL_API_BASE + 1024;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get information about
+//     * one or all of the predefined data types supported by the implementation.
+//     */
+//    int SQLGETTYPEINFO      = SQL_API_BASE + 47;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to determine whether there
+//     * are more result sets available on a statement handle and, if there are,
+//     * initialize processing for those result sets.
+//     */
+//  int SQLMORERESULTS = SQL_API_BASE + 61;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to determine whether there
+//     * are more result sets available on a statement handle and, if there are,
+//     * initialize processing for the next result set on a separate statement
+//     * handle.
+//     */
+//  int SQLNEXTRESULT = SQL_API_BASE + 73;
+//    /**
+//     * Indicates that Result encapsulates a request to get the number of
+//     * result columns of a prepared or executed statement.
+//     */
+//    int SQLNUMRESULTCOLS = SQL_API_BASE + 18;
+//    /**
+//     * Indicates that Result encapsulates a request to process a deferred
+//     * parameter value. For example, a streamed or locator identified
+//     * parameter.
+//     */
+//    int SQLPARAMDATA        = SQL_API_BASE + 48;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to prepare a statement.
+//     */
+//    int SQLPREPARE = SQL_API_BASE + 19;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to return a result set that
+//     * contains a list of the column names that comprise the primary key for a
+//     * single specified table stored in the information schemas of the
+//     * connected data source.
+//     */
+//    int SQLPRIMARYKEYS      = SQL_API_BASE + 65;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to provide a deferred
+//     * parameter value. For example, a streamed or locator-identified
+//     * parameter.
+//     */
+//    int SQLPUTDATA          = SQL_API_BASE + 49;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to get the row count of an
+//     * executed statement.
+//     */
+//    int SQLROWCOUNT = SQL_API_BASE + 20;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to set the value of an
+//     * SQL-connection attribute.
+//     */
+//    int SQLSETCONNECTATTR = SQL_API_BASE + 1016;
+//
+//
+//    /** Indicates that Result encapsulates a request to set a cursor name. */
+//    int SQLSETCURSORNAME    = SQL_API_BASE + 21;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to set a field in a CLI
+//     * descriptor area.
+//     */
+//    int SQLSETDESCFIELD     = SQL_API_BASE + 1017;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to set commonly-used
+//     * fields in a CLI descriptor area.
+//     */
+//    int SQLSETDESCREC       = SQL_API_BASE + 1018;
+//
+//
+//    /**
+//     * Indicates that Result encapsulates a request to set the value of an
+//     * SQL-environment attribute.
+//     */
+//  int SQLSETENVATTR = SQL_API_BASE + 1019;
+//    /** Indicates that Result encapsulates a request to set the value of an
+//     * SQL-statement attribute.
+//     */
+//    int SQLSETSTMTATTR      = SQL_API_BASE + 1020;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to return a result set that
+//     * contains a list of columns the combined values of which can uniquely
+//     * identify any row within a single specified table described by the
+//     * Information Schemas of the connected data source.
+//     */
+//    int SQLSPECIALCOLUMNS   = SQL_API_BASE + 52;
+//
+//
+//    /**
+//     * Indicates that Result encapsulates a request to explicitly start an
+//     * SQL-transaction and set its characteristics.
+//     */
+//    int SQLSTARTTRAN = SQL_API_BASE + 74;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to return a result set that
+//     * contains a list of the privileges held on the tables whose names adhere
+//     * to the requested pattern(s) within tables described by the Information
+//     * Schemas of the connected data source.
+//     */
+//    int SQLTABLES           = SQL_API_BASE + 54;
+//
+//    /**
+//     * Indicates that Result encapsulates a request to, based on the specified
+//     * selection criteria, return a result set that contains information about
+//     * tables described by the Information Schema of the connected data source.
+//     */
+//    int SQLTABLEPRIVILEGES  = SQL_API_BASE + 70;
+/*
+ Codes for transaction termination:
+
+ COMMIT 0
+ ROLLBACK 1
+ SAVEPOINT NAME ROLLBACK 2
+ SAVEPOINT NAME RELEASE 4
+ COMMIT AND CHAIN 6
+ ROLLBACK AND CHAIN 7
+ Implementation-defined termination type <0
+ */
+    int TX_COMMIT                  = 0;
+    int TX_ROLLBACK                = 1;
+    int TX_SAVEPOINT_NAME_ROLLBACK = 2;
+    int TX_SAVEPOINT_NAME_RELEASE  = 4;
+    int TX_COMMIT_AND_CHAIN        = 6;
+    int TX_ROLLBACK_AND_CHAIN      = 7;
+
+/* StatementType codes duplicated for cursor operations */
+    int UPDATE_CURSOR = StatementTypes.UPDATE_CURSOR;
+    int DELETE_CURSOR = StatementTypes.DELETE_CURSOR;
+    int INSERT_CURSOR = StatementTypes.INSERT;
+
+/* Environment attributes */
+
+//#define SQL_ATTR_OUTPUT_NTS 10001
+
+/* Connection attributes */
+
+//#define SQL_ATTR_AUTO_IPD 10001
+//#define SQL_ATTR_SAVEPOINT_NAME 10027
+    int SQL_ATTR_SAVEPOINT_NAME = 10027;
+
+// Batched execution constants:
+
+    /** batch item failed */
+    int EXECUTE_FAILED = -3;
+
+    /**
+     * Batch item succeeded but does not generate an update count,
+     * for example a call having no return value
+     */
+    int SUCCESS_NO_INFO = -2;
+/*
+   SQL standard properties
+   The operational sensitivity property (either SENSITIVE, INSENSITIVE, or ASENSITIVE).
+   The operational scrollability property (either SCROLL or NO SCROLL).
+   The operational holdability property (either WITH HOLD or WITHOUT HOLD).
+   The operational returnability property (either WITH RETURN or WITHOUT RETURN).
+*/
+    int SQL_ASENSITIVE    = 0;
+    int SQL_INSENSITIVE   = 1;
+    int SQL_SENSITIVE     = 2;
+    int SQL_NONSCROLLABLE = 0;
+    int SQL_SCROLLABLE    = 1;
+    int SQL_NONHOLDABLE   = 0;
+    int SQL_HOLDABLE      = 1;
+
+//
+    int SQL_WITHOUT_RETURN = 0;
+    int SQL_WITH_RETURN    = 1;
+    int SQL_NOT_UPDATABLE  = 0;
+    int SQL_UPDATABLE      = 1;
+
+// data result properties - matching java.sql.ResultSet constants
+    int TYPE_FORWARD_ONLY       = 1003;
+    int TYPE_SCROLL_INSENSITIVE = 1004;
+    int TYPE_SCROLL_SENSITIVE   = 1005;
+
+    //
+    int CONCUR_READ_ONLY = 1007;
+    int CONCUR_UPDATABLE = 1008;
+
+    //
+    int HOLD_CURSORS_OVER_COMMIT = 1;
+    int CLOSE_CURSORS_AT_COMMIT  = 2;
+
+    /** Constants indicating generated key return behaviour */
+    int RETURN_GENERATED_KEYS             = 1;     // matching java.sql.Statement constant
+    int RETURN_NO_GENERATED_KEYS          = 2;     // matching java.sql.Statement constant
+    int RETURN_GENERATED_KEYS_COL_NAMES   = 11;    // constant in HSQLDB only
+    int RETURN_GENERATED_KEYS_COL_INDEXES = 21;    // constant in HSQLDB only
+}
diff --git a/src/org/hsqldb/result/ResultLob.java b/src/org/hsqldb/result/ResultLob.java
new file mode 100644
index 0000000..a262408
--- /dev/null
+++ b/src/org/hsqldb/result/ResultLob.java
@@ -0,0 +1,516 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.result;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.rowio.RowOutputInterface;
+
+/**
+ * Sub-class of Result for communicating Blob and Clob operations.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class ResultLob extends Result {
+
+    public static interface LobResultTypes {
+
+        int REQUEST_GET_BYTES                 = 1;
+        int REQUEST_SET_BYTES                 = 2;
+        int REQUEST_GET_CHARS                 = 3;
+        int REQUEST_SET_CHARS                 = 4;
+        int REQUEST_GET_BYTE_PATTERN_POSITION = 5;
+        int REQUEST_GET_CHAR_PATTERN_POSITION = 6;
+        int REQUEST_CREATE_BYTES              = 7;
+        int REQUEST_CREATE_CHARS              = 8;
+        int REQUEST_TRUNCATE                  = 9;
+        int REQUEST_GET_LENGTH                = 10;
+        int REQUEST_GET_LOB                   = 11;
+
+        //
+        int RESPONSE_GET_BYTES                 = 21;
+        int RESPONSE_SET                       = 22;
+        int RESPONSE_GET_CHARS                 = 23;
+        int RESPONSE_GET_BYTE_PATTERN_POSITION = 25;
+        int RESPONSE_GET_CHAR_PATTERN_POSITION = 26;
+        int RESPONSE_CREATE_BYTES              = 27;
+        int RESPONSE_CREATE_CHARS              = 28;
+        int RESPONSE_TRUNCATE                  = 29;
+    }
+
+    long        lobID;
+    int         subType;
+    long        blockOffset;
+    long        blockLength;
+    byte[]      byteBlock;
+    char[]      charBlock;
+    Reader      reader;
+    InputStream stream;
+
+    private ResultLob() {
+        super(ResultConstants.LARGE_OBJECT_OP);
+    }
+
+    public static ResultLob newLobGetLengthRequest(long id) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType = LobResultTypes.REQUEST_GET_LENGTH;
+        result.lobID   = id;
+
+        return result;
+    }
+
+    public static ResultLob newLobGetBytesRequest(long id, long offset,
+            int length) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.REQUEST_GET_BYTES;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.blockLength = length;
+
+        return result;
+    }
+
+    public static ResultLob newLobGetCharsRequest(long id, long offset,
+            int length) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.REQUEST_GET_CHARS;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.blockLength = length;
+
+        return result;
+    }
+
+    public static ResultLob newLobSetBytesRequest(long id, long offset,
+            byte block[]) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.REQUEST_SET_BYTES;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.byteBlock   = block;
+        result.blockLength = block.length;
+
+        return result;
+    }
+
+    public static ResultLob newLobSetCharsRequest(long id, long offset,
+            char[] chars) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.REQUEST_SET_CHARS;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.charBlock   = chars;
+        result.blockLength = chars.length;
+
+        return result;
+    }
+
+    public static ResultLob newLobTruncateRequest(long id, long offset) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.REQUEST_TRUNCATE;
+        result.lobID       = id;
+        result.blockOffset = offset;
+
+        return result;
+    }
+
+    public static ResultLob newLobGetBytesResponse(long id, long offset,
+            byte block[]) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.RESPONSE_GET_BYTES;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.byteBlock   = block;
+        result.blockLength = block.length;
+
+        return result;
+    }
+
+    public static ResultLob newLobGetCharsResponse(long id, long offset,
+            char[] chars) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.RESPONSE_GET_CHARS;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.charBlock   = chars;
+        result.blockLength = chars.length;
+
+        return result;
+    }
+
+    public static ResultLob newLobSetResponse(long id, long length) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.RESPONSE_SET;
+        result.lobID       = id;
+        result.blockLength = length;
+
+        return result;
+    }
+
+    public static ResultLob newLobGetBytePatternPositionRequest(long id,
+            byte[] pattern, long offset) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.REQUEST_GET_BYTE_PATTERN_POSITION;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.byteBlock   = pattern;
+        result.blockLength = pattern.length;
+
+        return result;
+    }
+
+    public static ResultLob newLobGetCharPatternPositionRequest(long id,
+            char[] pattern, long offset) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.REQUEST_GET_CHAR_PATTERN_POSITION;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.charBlock   = pattern;
+        result.blockLength = pattern.length;
+
+        return result;
+    }
+
+    public static ResultLob newLobCreateBlobRequest(long sessionID,
+            long lobID, InputStream stream, long length) {
+
+        ResultLob result = new ResultLob();
+
+        result.lobID       = lobID;
+        result.subType     = LobResultTypes.REQUEST_CREATE_BYTES;
+        result.blockLength = length;
+        result.stream      = stream;
+
+        return result;
+    }
+
+    public static ResultLob newLobCreateClobRequest(long sessionID,
+            long lobID, Reader reader, long length) {
+
+        ResultLob result = new ResultLob();
+
+        result.lobID       = lobID;
+        result.subType     = LobResultTypes.REQUEST_CREATE_CHARS;
+        result.blockLength = length;
+        result.reader      = reader;
+
+        return result;
+    }
+
+    public static ResultLob newLobCreateBlobResponse(long id) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType = LobResultTypes.RESPONSE_CREATE_BYTES;
+        result.lobID   = id;
+
+        return result;
+    }
+
+    public static ResultLob newLobCreateClobResponse(long id) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType = LobResultTypes.RESPONSE_CREATE_CHARS;
+        result.lobID   = id;
+
+        return result;
+    }
+
+    public static ResultLob newLobTruncateResponse(long id) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType = LobResultTypes.RESPONSE_TRUNCATE;
+        result.lobID   = id;
+
+        return result;
+    }
+
+    public static ResultLob newLobGetRequest(long id, long offset,
+            long length) {
+
+        ResultLob result = new ResultLob();
+
+        result.subType     = LobResultTypes.REQUEST_GET_LOB;
+        result.lobID       = id;
+        result.blockOffset = offset;
+        result.blockLength = length;
+
+        return result;
+    }
+
+    public static ResultLob newLob(DataInput dataInput,
+                                   boolean readTerminate)
+                                   throws IOException {
+
+        ResultLob result = new ResultLob();
+
+        result.databaseID = dataInput.readInt();
+        result.sessionID  = dataInput.readLong();
+        result.lobID      = dataInput.readLong();
+        result.subType    = dataInput.readInt();
+
+        switch (result.subType) {
+
+            case LobResultTypes.REQUEST_CREATE_BYTES :
+            case LobResultTypes.REQUEST_CREATE_CHARS :
+                result.blockOffset = dataInput.readLong();
+                result.blockLength = dataInput.readLong();
+                break;
+
+            case LobResultTypes.REQUEST_GET_LOB :
+
+            //
+            case LobResultTypes.REQUEST_GET_BYTES :
+            case LobResultTypes.REQUEST_GET_CHARS :
+                result.blockOffset = dataInput.readLong();
+                result.blockLength = dataInput.readLong();
+                break;
+
+            case LobResultTypes.REQUEST_SET_BYTES :
+            case LobResultTypes.REQUEST_GET_BYTE_PATTERN_POSITION :
+                result.blockOffset = dataInput.readLong();
+                result.blockLength = dataInput.readLong();
+                result.byteBlock   = new byte[(int) result.blockLength];
+
+                dataInput.readFully(result.byteBlock);
+                break;
+
+            case LobResultTypes.REQUEST_SET_CHARS :
+            case LobResultTypes.REQUEST_GET_CHAR_PATTERN_POSITION :
+                result.blockOffset = dataInput.readLong();
+                result.blockLength = dataInput.readLong();
+                result.charBlock   = new char[(int) result.blockLength];
+
+                for (int i = 0; i < result.charBlock.length; i++) {
+                    result.charBlock[i] = dataInput.readChar();
+                }
+                break;
+
+            case LobResultTypes.REQUEST_GET_LENGTH :
+            case LobResultTypes.REQUEST_TRUNCATE :
+                result.blockOffset = dataInput.readLong();
+                break;
+
+            case LobResultTypes.RESPONSE_GET_BYTES :
+                result.blockOffset = dataInput.readLong();
+                result.blockLength = dataInput.readLong();
+                result.byteBlock   = new byte[(int) result.blockLength];
+
+                dataInput.readFully(result.byteBlock);
+                break;
+
+            case LobResultTypes.RESPONSE_GET_CHARS :
+                result.blockOffset = dataInput.readLong();
+                result.blockLength = dataInput.readLong();
+                result.charBlock   = new char[(int) result.blockLength];
+
+                for (int i = 0; i < result.charBlock.length; i++) {
+                    result.charBlock[i] = dataInput.readChar();
+                }
+                break;
+
+            case LobResultTypes.RESPONSE_SET :
+            case LobResultTypes.RESPONSE_CREATE_BYTES :
+            case LobResultTypes.RESPONSE_CREATE_CHARS :
+            case LobResultTypes.RESPONSE_TRUNCATE :
+                result.blockLength = dataInput.readLong();
+                break;
+
+            case LobResultTypes.RESPONSE_GET_BYTE_PATTERN_POSITION :
+            case LobResultTypes.RESPONSE_GET_CHAR_PATTERN_POSITION :
+                result.blockOffset = dataInput.readLong();
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ResultLob");
+        }
+
+        if (readTerminate) {
+            dataInput.readByte();
+        }
+
+        return result;
+    }
+
+    public void write(DataOutputStream dataOut,
+                      RowOutputInterface rowOut)
+                      throws IOException {
+
+        writeBody(dataOut);
+        dataOut.writeByte(ResultConstants.NONE);
+        dataOut.flush();
+    }
+
+    public void writeBody(DataOutputStream dataOut)
+    throws IOException {
+
+        dataOut.writeByte(mode);
+        dataOut.writeInt(databaseID);
+        dataOut.writeLong(sessionID);
+        dataOut.writeLong(lobID);
+        dataOut.writeInt(subType);
+
+        switch (subType) {
+
+            case LobResultTypes.REQUEST_CREATE_BYTES :
+                dataOut.writeLong(blockOffset);
+                dataOut.writeLong(blockLength);
+                dataOut.write(stream, blockLength);
+                break;
+
+            case LobResultTypes.REQUEST_CREATE_CHARS :
+                dataOut.writeLong(blockOffset);
+                dataOut.writeLong(blockLength);
+                dataOut.write(reader, blockLength);
+                break;
+
+            case LobResultTypes.REQUEST_SET_BYTES :
+            case LobResultTypes.REQUEST_GET_BYTE_PATTERN_POSITION :
+                dataOut.writeLong(blockOffset);
+                dataOut.writeLong(blockLength);
+                dataOut.write(byteBlock);
+                break;
+
+            case LobResultTypes.REQUEST_SET_CHARS :
+            case LobResultTypes.REQUEST_GET_CHAR_PATTERN_POSITION :
+                dataOut.writeLong(blockOffset);
+                dataOut.writeLong(blockLength);
+                dataOut.writeChars(charBlock);
+                break;
+
+            case LobResultTypes.REQUEST_GET_LOB :
+
+            //
+            case LobResultTypes.REQUEST_GET_BYTES :
+            case LobResultTypes.REQUEST_GET_CHARS :
+                dataOut.writeLong(blockOffset);
+                dataOut.writeLong(blockLength);
+                break;
+
+            case LobResultTypes.REQUEST_GET_LENGTH :
+            case LobResultTypes.REQUEST_TRUNCATE :
+                dataOut.writeLong(blockOffset);
+                break;
+
+            case LobResultTypes.RESPONSE_GET_BYTES :
+                dataOut.writeLong(blockOffset);
+                dataOut.writeLong(blockLength);
+                dataOut.write(byteBlock);
+                break;
+
+            case LobResultTypes.RESPONSE_GET_CHARS :
+                dataOut.writeLong(blockOffset);
+                dataOut.writeLong(blockLength);
+                dataOut.writeChars(charBlock);
+                break;
+
+            case LobResultTypes.RESPONSE_SET :
+            case LobResultTypes.RESPONSE_CREATE_BYTES :
+            case LobResultTypes.RESPONSE_CREATE_CHARS :
+            case LobResultTypes.RESPONSE_TRUNCATE :
+                dataOut.writeLong(blockLength);
+                break;
+
+            case LobResultTypes.RESPONSE_GET_BYTE_PATTERN_POSITION :
+            case LobResultTypes.RESPONSE_GET_CHAR_PATTERN_POSITION :
+                dataOut.writeLong(blockOffset);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "ResultLob");
+        }
+    }
+
+    public long getLobID() {
+        return lobID;
+    }
+
+    public int getSubType() {
+        return subType;
+    }
+
+    public long getOffset() {
+        return blockOffset;
+    }
+
+    public long getBlockLength() {
+        return blockLength;
+    }
+
+    public byte[] getByteArray() {
+        return byteBlock;
+    }
+
+    public char[] getCharArray() {
+        return charBlock;
+    }
+
+    public InputStream getInputStream() {
+        return stream;
+    }
+
+    public Reader getReader() {
+        return reader;
+    }
+}
diff --git a/src/org/hsqldb/result/ResultMetaData.java b/src/org/hsqldb/result/ResultMetaData.java
new file mode 100644
index 0000000..bd64d86
--- /dev/null
+++ b/src/org/hsqldb/result/ResultMetaData.java
@@ -0,0 +1,496 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.result;
+
+import java.io.IOException;
+
+import org.hsqldb.ColumnBase;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.rowio.RowInputBinary;
+import org.hsqldb.rowio.RowOutputInterface;
+import org.hsqldb.types.ArrayType;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Metadata for a result set.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.8.0
+ */
+public final class ResultMetaData {
+
+    public static final int RESULT_METADATA          = 1;
+    public static final int SIMPLE_RESULT_METADATA   = 2;
+    public static final int UPDATE_RESULT_METADATA   = 3;
+    public static final int PARAM_METADATA           = 4;
+    public static final int GENERATED_INDEX_METADATA = 5;
+    public static final int GENERATED_NAME_METADATA  = 6;
+
+    //
+    private int type;
+
+    // values overriding table column
+    public String[] columnLabels;
+    public Type[]   columnTypes;
+    private int     columnCount;
+    private int     extendedColumnCount;
+    public static final ResultMetaData emptyResultMetaData =
+        newResultMetaData(0);
+    public static final ResultMetaData emptyParamMetaData =
+        newParameterMetaData(0);
+
+    // column indexes for mapping or for generated columns
+    public int[] colIndexes;
+
+    // columns for data columns
+    public ColumnBase[] columns;
+
+    // param mode and nullability for parameter metadata
+    public byte[] paramModes;
+    public byte[] paramNullable;
+
+    //
+    private ResultMetaData(int type) {
+        this.type = type;
+    }
+
+    public static ResultMetaData newUpdateResultMetaData(Type[] types) {
+
+        ResultMetaData md = new ResultMetaData(UPDATE_RESULT_METADATA);
+
+        md.columnTypes         = new Type[types.length];
+        md.columnCount         = types.length;
+        md.extendedColumnCount = types.length;
+
+        ArrayUtil.copyArray(types, md.columnTypes, types.length);
+
+        return md;
+    }
+
+    public static ResultMetaData newSimpleResultMetaData(Type[] types) {
+
+        ResultMetaData md = new ResultMetaData(SIMPLE_RESULT_METADATA);
+
+        md.columnTypes         = types;
+        md.columnCount         = types.length;
+        md.extendedColumnCount = types.length;
+
+        return md;
+    }
+
+    public static ResultMetaData newResultMetaData(int colCount) {
+
+        Type[] types = new Type[colCount];
+
+        return newResultMetaData(types, null, colCount, colCount);
+    }
+
+    public static ResultMetaData newResultMetaData(Type[] types,
+            int[] baseColumnIndexes, int colCount, int extColCount) {
+
+        ResultMetaData md = new ResultMetaData(RESULT_METADATA);
+
+        md.columnLabels        = new String[colCount];
+        md.columns             = new ColumnBase[colCount];
+        md.columnTypes         = types;
+        md.colIndexes          = baseColumnIndexes;
+        md.columnCount         = colCount;
+        md.extendedColumnCount = extColCount;
+
+        return md;
+    }
+
+    public static ResultMetaData newParameterMetaData(int colCount) {
+
+        ResultMetaData md = new ResultMetaData(PARAM_METADATA);
+
+        md.columnTypes         = new Type[colCount];
+        md.columnLabels        = new String[colCount];
+        md.paramModes          = new byte[colCount];
+        md.paramNullable       = new byte[colCount];
+        md.columnCount         = colCount;
+        md.extendedColumnCount = colCount;
+
+        return md;
+    }
+
+    public static ResultMetaData newGeneratedColumnsMetaData(
+            int[] columnIndexes, String[] columnNames) {
+
+        if (columnIndexes != null) {
+            ResultMetaData md = new ResultMetaData(GENERATED_INDEX_METADATA);
+
+            md.columnCount         = columnIndexes.length;
+            md.extendedColumnCount = columnIndexes.length;
+            md.colIndexes          = new int[columnIndexes.length];
+
+            for (int i = 0; i < columnIndexes.length; i++) {
+                md.colIndexes[i] = columnIndexes[i] - 1;
+            }
+
+            return md;
+        } else if (columnNames != null) {
+            ResultMetaData md = new ResultMetaData(GENERATED_NAME_METADATA);
+
+            md.columnLabels        = new String[columnNames.length];
+            md.columnCount         = columnNames.length;
+            md.extendedColumnCount = columnNames.length;
+            md.columnLabels        = columnNames;
+
+            return md;
+        } else {
+            return null;
+        }
+    }
+
+    public void prepareData() {
+
+        if (columns != null) {
+            for (int i = 0; i < columnCount; i++) {
+                if (columnTypes[i] == null) {
+                    columnTypes[i] = columns[i].getDataType();
+                }
+            }
+        }
+    }
+
+    public int getColumnCount() {
+        return columnCount;
+    }
+
+    public int getExtendedColumnCount() {
+        return extendedColumnCount;
+    }
+
+    public void resetExtendedColumnCount() {
+        extendedColumnCount = columnCount;
+    }
+
+    public Type[] getParameterTypes() {
+        return columnTypes;
+    }
+
+    public String[] getGeneratedColumnNames() {
+        return columnLabels;
+    }
+
+    public int[] getGeneratedColumnIndexes() {
+        return colIndexes;
+    }
+
+    public boolean isTableColumn(int i) {
+
+        String colName   = columns[i].getNameString();
+        String tableName = columns[i].getTableNameString();
+
+        return tableName != null && tableName.length() > 0 && colName != null
+               && colName.length() > 0;
+    }
+
+    private static void decodeTableColumnAttrs(int in, ColumnBase column) {
+
+        column.setNullability((byte) (in & 0x00000003));
+        column.setIdentity((in & 0x00000004) != 0);
+        column.setWriteable((in & 0x00000008) != 0);
+    }
+
+    private static int encodeTableColumnAttrs(ColumnBase column) {
+
+        int out = column.getNullability();    // always between 0x00 and 0x02
+
+        if (column.isIdentity()) {
+            out |= 0x00000004;
+        }
+
+        if (column.isWriteable()) {
+            out |= 0x00000008;
+        }
+
+        return out;
+    }
+
+    private void decodeParamColumnAttrs(int in, int columnIndex) {
+        paramNullable[columnIndex] = (byte) (in & 0x00000003);
+        paramModes[columnIndex]    = (byte) ((in >> 4) & 0x0000000f);
+    }
+
+    private int encodeParamColumnAttrs(int columnIndex) {
+
+        int out = paramModes[columnIndex] << 4;
+
+        out |= paramNullable[columnIndex];
+
+        return out;
+    }
+
+    ResultMetaData(RowInputBinary in) throws IOException {
+
+        type        = in.readInt();
+        columnCount = in.readInt();
+
+        switch (type) {
+
+            case UPDATE_RESULT_METADATA :
+            case SIMPLE_RESULT_METADATA : {
+                columnTypes = new Type[columnCount];
+
+                for (int i = 0; i < columnCount; i++) {
+                    columnTypes[i] = readDataTypeSimple(in);
+                }
+
+                return;
+            }
+            case GENERATED_INDEX_METADATA : {
+                colIndexes = new int[columnCount];
+
+                for (int i = 0; i < columnCount; i++) {
+                    colIndexes[i] = in.readInt();
+                }
+
+                return;
+            }
+            case GENERATED_NAME_METADATA : {
+                columnLabels = new String[columnCount];
+
+                for (int i = 0; i < columnCount; i++) {
+                    columnLabels[i] = in.readString();
+                }
+
+                return;
+            }
+            case PARAM_METADATA : {
+                columnTypes   = new Type[columnCount];
+                columnLabels  = new String[columnCount];
+                paramModes    = new byte[columnCount];
+                paramNullable = new byte[columnCount];
+
+                for (int i = 0; i < columnCount; i++) {
+                    columnTypes[i]  = readDataType(in);
+                    columnLabels[i] = in.readString();
+
+                    decodeParamColumnAttrs(in.readByte(), i);
+                }
+
+                return;
+            }
+            case RESULT_METADATA : {
+                extendedColumnCount = in.readInt();
+                columnTypes         = new Type[extendedColumnCount];
+                columnLabels        = new String[columnCount];
+                columns             = new ColumnBase[columnCount];
+
+                if (columnCount != extendedColumnCount) {
+                    colIndexes = new int[columnCount];
+                }
+
+                for (int i = 0; i < extendedColumnCount; i++) {
+                    Type type = readDataType(in);
+
+                    columnTypes[i] = type;
+                }
+
+                for (int i = 0; i < columnCount; i++) {
+                    columnLabels[i] = in.readString();
+
+                    String catalog = in.readString();
+                    String schema  = in.readString();
+                    String table   = in.readString();
+                    String name    = in.readString();
+                    ColumnBase column = new ColumnBase(catalog, schema, table,
+                                                       name);
+
+                    column.setType(columnTypes[i]);
+                    decodeTableColumnAttrs(in.readByte(), column);
+
+                    columns[i] = column;
+                }
+
+                if (columnCount != extendedColumnCount) {
+                    for (int i = 0; i < columnCount; i++) {
+                        colIndexes[i] = in.readInt();
+                    }
+                }
+
+                return;
+            }
+            default : {
+                throw Error.runtimeError(ErrorCode.U_S0500, "ResultMetaData");
+            }
+        }
+    }
+
+    Type readDataTypeSimple(RowInputBinary in) throws IOException {
+
+        int     typeCode = in.readType();
+        boolean isArray  = typeCode == Types.SQL_ARRAY;
+
+        if (isArray) {
+            typeCode = in.readType();
+            return Type.getDefaultArrayType(typeCode);
+        }
+
+        return Type.getDefaultType(typeCode);
+    }
+
+
+    Type readDataType(RowInputBinary in) throws IOException {
+
+        int     typeCode = in.readType();
+        boolean isArray  = typeCode == Types.SQL_ARRAY;
+
+        if (isArray) {
+            typeCode = in.readType();
+        }
+
+        long size  = in.readLong();
+        int  scale = in.readInt();
+        Type type  = Type.getType(typeCode, 0, size, scale);
+
+        if (isArray) {
+            type = new ArrayType(type, Type.defaultArrayCardinality);
+        }
+
+        return type;
+    }
+
+    void writeDataType(RowOutputInterface out, Type type) {
+
+        out.writeType(type.typeCode);
+
+        if (type.isArrayType()) {
+            out.writeType(type.collectionBaseType().typeCode);
+        }
+
+        out.writeLong(type.precision);
+        out.writeInt(type.scale);
+    }
+
+    void writeDataTypeCodes(RowOutputInterface out, Type type) {
+
+        out.writeType(type.typeCode);
+
+        if (type.isArrayType()) {
+            out.writeType(type.collectionBaseType().typeCode);
+        }
+    }
+
+    void write(RowOutputInterface out) throws IOException {
+
+        out.writeInt(type);
+        out.writeInt(columnCount);
+
+        switch (type) {
+
+            case UPDATE_RESULT_METADATA :
+            case SIMPLE_RESULT_METADATA : {
+                for (int i = 0; i < columnCount; i++) {
+                    writeDataTypeCodes(out, columnTypes[i]);
+                }
+
+                return;
+            }
+            case GENERATED_INDEX_METADATA : {
+                for (int i = 0; i < columnCount; i++) {
+                    out.writeInt(colIndexes[i]);
+                }
+
+                return;
+            }
+            case GENERATED_NAME_METADATA : {
+                for (int i = 0; i < columnCount; i++) {
+                    out.writeString(columnLabels[i]);
+                }
+
+                return;
+            }
+            case PARAM_METADATA :
+                for (int i = 0; i < columnCount; i++) {
+                    writeDataType(out, columnTypes[i]);
+                    out.writeString(columnLabels[i]);
+                    out.writeByte(encodeParamColumnAttrs(i));
+                }
+
+                return;
+
+            case RESULT_METADATA : {
+                out.writeInt(extendedColumnCount);
+
+                for (int i = 0; i < extendedColumnCount; i++) {
+                    if (columnTypes[i] == null) {
+                        ColumnBase column = columns[i];
+
+                        columnTypes[i] = column.getDataType();
+                    }
+
+                    writeDataType(out, columnTypes[i]);
+                }
+
+                for (int i = 0; i < columnCount; i++) {
+                    ColumnBase column = columns[i];
+
+                    out.writeString(columnLabels[i]);
+                    out.writeString(column.getCatalogNameString());
+                    out.writeString(column.getSchemaNameString());
+                    out.writeString(column.getTableNameString());
+                    out.writeString(column.getNameString());
+                    out.writeByte(encodeTableColumnAttrs(column));
+                }
+
+                if (columnCount != extendedColumnCount) {
+                    for (int i = 0; i < colIndexes.length; i++) {
+                        out.writeInt(colIndexes[i]);
+                    }
+                }
+
+                return;
+            }
+            default : {
+                throw Error.runtimeError(ErrorCode.U_S0500, "ResultMetaData");
+            }
+        }
+    }
+
+    public ResultMetaData getNewMetaData(int[] columnMap) {
+
+        ResultMetaData newMeta = newResultMetaData(columnMap.length);
+
+        ArrayUtil.projectRow(columnLabels, columnMap, newMeta.columnLabels);
+        ArrayUtil.projectRow(columnTypes, columnMap, newMeta.columnTypes);
+        ArrayUtil.projectRow(columns, columnMap, newMeta.columns);
+
+        return newMeta;
+    }
+}
diff --git a/src/org/hsqldb/result/ResultProperties.java b/src/org/hsqldb/result/ResultProperties.java
new file mode 100644
index 0000000..5feaa2a
--- /dev/null
+++ b/src/org/hsqldb/result/ResultProperties.java
@@ -0,0 +1,139 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.result;
+
+/*
+ * Execute properties for SELECT statements.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ResultProperties {
+
+    //
+    final static int idx_returnable = 0;
+    final static int idx_holdable   = 1;
+    final static int idx_scrollable = 2;
+    final static int idx_updatable  = 3;
+    final static int idx_sensitive  = 4;
+
+    //
+    public static final int defaultPropsValue   = 0;
+    public static final int updatablePropsValue = 1 << idx_updatable;
+
+    // uses SQL constants - no JDBC
+    public static int getProperties(int sensitive, int updatable,
+                                    int scrollable, int holdable,
+                                    int returnable) {
+
+        int combined = (sensitive << idx_sensitive)
+                       | (updatable << idx_updatable)
+                       | (scrollable << idx_scrollable)
+                       | (holdable << idx_holdable)
+                       | (returnable << idx_returnable);
+
+        return combined;
+    }
+
+    public static int getJDBCHoldability(int props) {
+        return isHoldable(props) ? ResultConstants.HOLD_CURSORS_OVER_COMMIT
+                                 : ResultConstants.CLOSE_CURSORS_AT_COMMIT;
+    }
+
+    public static int getJDBCConcurrency(int props) {
+        return isReadOnly(props) ? ResultConstants.CONCUR_READ_ONLY
+                                 : ResultConstants.CONCUR_UPDATABLE;
+    }
+
+    public static int getJDBCScrollability(int props) {
+        return isScrollable(props) ? ResultConstants.TYPE_SCROLL_INSENSITIVE
+                                   : ResultConstants.TYPE_FORWARD_ONLY;
+    }
+
+    public static int getValueForJDBC(int type, int concurrency,
+                                      int holdability) {
+
+        int scrollable = type == ResultConstants.TYPE_FORWARD_ONLY ? 0
+                                                                   : 1;
+        int updatable  = concurrency == ResultConstants.CONCUR_UPDATABLE ? 1
+                                                                         : 0;
+        int holdable = holdability == ResultConstants.HOLD_CURSORS_OVER_COMMIT
+                       ? 1
+                       : 0;
+        int prop = (updatable << idx_updatable)
+                   | (scrollable << idx_scrollable)
+                   | (holdable << idx_holdable);
+
+        return prop;
+    }
+
+    public static boolean isUpdatable(int props) {
+        return (props & (1 << idx_updatable)) == 0 ? false
+                                                   : true;
+    }
+
+    public static boolean isScrollable(int props) {
+        return (props & (1 << idx_scrollable)) == 0 ? false
+                                                    : true;
+    }
+
+    public static boolean isHoldable(int props) {
+        return (props & (1 << idx_holdable)) == 0 ? false
+                                                  : true;
+    }
+
+    public static boolean isSensitive(int props) {
+        return (props & (1 << idx_sensitive)) == 0 ? false
+                                                   : true;
+    }
+
+    public static boolean isReadOnly(int props) {
+        return (props & (1 << idx_updatable)) == 0 ? true
+                                                   : false;
+    }
+
+    public static int addUpdatable(int props, boolean flag) {
+        return flag ? props | ((1) << idx_updatable)
+                    : props & (~(1 << idx_updatable));
+    }
+
+    public static int addHoldable(int props, boolean flag) {
+        return flag ? props | ((1) << idx_holdable)
+                    : props & (~(1 << idx_holdable));
+    }
+
+    public static int addScrollable(int props, boolean flag) {
+        return flag ? props | ((1) << idx_scrollable)
+                    : props & (~(1 << idx_scrollable));
+    }
+}
diff --git a/src/org/hsqldb/rights/GrantConstants.java b/src/org/hsqldb/rights/GrantConstants.java
new file mode 100644
index 0000000..00bc318
--- /dev/null
+++ b/src/org/hsqldb/rights/GrantConstants.java
@@ -0,0 +1,69 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rights;
+
+/**
+ * The constants for grants.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public interface GrantConstants {
+
+    /** Flag required to SELECT from a table. */
+    int SELECT = 1 << 0;
+
+    /** Flag required to DELETE from a table. */
+    int DELETE = 1 << 1;
+
+    /** Flag required to INSERT into a table. */
+    int INSERT = 1 << 2;
+
+    /** Flag required to UPDATE a table. */
+    int UPDATE = 1 << 3;
+
+    /** Flag required to use a sequence. */
+    int USAGE = 1 << 4;
+
+    /** Flag required to execute a routine. */
+    int EXECUTE = 1 << 5;
+
+    /** Flag required for check or assertion constraint referencing a column. */
+    int REFERENCES = 1 << 6;
+
+    /** Flag required to use of a trigger. */
+    int TRIGGER = 1 << 7;
+
+    /** Combined flag permitting any action. */
+    int ALL = SELECT | DELETE | INSERT | UPDATE | USAGE | EXECUTE;
+}
diff --git a/src/org/hsqldb/rights/Grantee.java b/src/org/hsqldb/rights/Grantee.java
new file mode 100644
index 0000000..29edace
--- /dev/null
+++ b/src/org/hsqldb/rights/Grantee.java
@@ -0,0 +1,1244 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rights;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.NumberSequence;
+import org.hsqldb.Routine;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.MultiValueHashMap;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.Set;
+import org.hsqldb.lib.WrapperIterator;
+import org.hsqldb.types.Type;
+
+/**
+ * A Grantee Object holds the name, access and administrative rights for a
+ * particular grantee.<p>
+ * It supplies the methods used to grant, revoke, test
+ * and check a grantee's access rights to other database objects.
+ * It also holds a reference to the common PUBLIC User Object,
+ * which represent the special user refered to in
+ * GRANT ... TO PUBLIC statements.<p>
+ * The check(), isAccessible() and getGrantedClassNames() methods check the
+ * rights granted to the PUBLIC User Object, in addition to individually
+ * granted rights, in order to decide which rights exist for the user.
+ *
+ * Method names ending in Direct indicate methods which do not recurse
+ * to look through Roles which "this" object is a member of.
+ *
+ * We use the word "Admin" (e.g., in private variable "admin" and method
+ * "isAdmin()) to mean this Grantee has admin priv by any means.
+ * We use the word "adminDirect" (e.g., in private variable "adminDirect"
+ * and method "isAdminDirect()) to mean this Grantee has admin priv
+ * directly.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ *
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+public class Grantee implements SchemaObject {
+
+    boolean isRole;
+
+    /**
+     * true if this grantee has database administrator priv directly
+     *  (ie., not by membership in any role)
+     */
+    private boolean isAdminDirect = false;
+
+    /** true if this grantee has database administrator priv by any means. */
+    private boolean isAdmin = false;
+
+    /** true if this user can create schemas with its own authorisation */
+    boolean isSchemaCreator = false;
+
+    /** true if this grantee is PUBLIC. */
+    boolean isPublic = false;
+
+    /** true if this grantee is _SYSTEM. */
+    boolean isSystem = false;
+
+    /** Grantee name. */
+    protected HsqlName granteeName;
+
+    /** map with database object identifier keys and access privileges values */
+    private MultiValueHashMap directRightsMap;
+
+    /** contains righs granted direct, or via roles, expept those of PUBLIC */
+    private HashMap fullRightsMap;
+
+    /** These are the DIRECT roles.  Each of these may contain nested roles */
+    OrderedHashSet roles;
+
+    /** map with database object identifier keys and access privileges values */
+    private MultiValueHashMap grantedRightsMap;
+
+    /** Needed only to give access to the roles for this database */
+    protected GranteeManager granteeManager;
+
+    /**  */
+    protected Right ownerRights;
+
+    /**
+     * Constructor.
+     */
+    Grantee(HsqlName name, GranteeManager man) {
+
+        fullRightsMap       = new HashMap();
+        directRightsMap     = new MultiValueHashMap();
+        grantedRightsMap    = new MultiValueHashMap();
+        granteeName         = name;
+        granteeManager      = man;
+        roles               = new OrderedHashSet();
+        ownerRights         = new Right();
+        ownerRights.isFull  = true;
+        ownerRights.grantor = GranteeManager.systemAuthorisation;
+        ownerRights.grantee = this;
+    }
+
+    public int getType() {
+        return SchemaObject.GRANTEE;
+    }
+
+    public HsqlName getName() {
+        return granteeName;
+    }
+
+    public HsqlName getSchemaName() {
+        return null;
+    }
+
+    public HsqlName getCatalogName() {
+        return null;
+    }
+
+    public Grantee getOwner() {
+        return null;
+    }
+
+    public OrderedHashSet getReferences() {
+        return new OrderedHashSet();
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_CREATE).append(' ').append(Tokens.T_ROLE);
+        sb.append(' ').append(granteeName.statementName);
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    public String getNameString() {
+        return granteeName.name;
+    }
+
+    public String getStatementName() {
+        return granteeName.statementName;
+    }
+
+    public boolean isRole() {
+        return isRole;
+    }
+
+    public boolean isSystem() {
+        return isSystem;
+    }
+
+    /**
+     * Retrieves the map object that represents the rights that have been
+     * granted on database objects.  <p>
+     *
+     * The map has keys and values with the following interpretation: <P>
+     *
+     * <UL>
+     * <LI> The keys are generally (but not limited to) objects having
+     *      an attribute or value equal to the name of an actual database
+     *      object.
+     *
+     * <LI> Specifically, the keys act as database object identifiers.
+     *
+     * <LI> The values are Right objects.
+     * </UL>
+     */
+    public MultiValueHashMap getRights() {
+
+        // necessary to create the script
+        return directRightsMap;
+    }
+
+    /**
+     * Grant a role
+     */
+    public void grant(Grantee role) {
+        roles.add(role);
+    }
+
+    /**
+     * Revoke a direct role only
+     */
+    public void revoke(Grantee role) {
+
+        if (!hasRoleDirect(role)) {
+            throw Error.error(ErrorCode.X_0P503, role.getNameString());
+        }
+
+        roles.remove(role);
+    }
+
+    /**
+     * Gets direct roles, not roles nested within them.
+     */
+    public OrderedHashSet getDirectRoles() {
+        return roles;
+    }
+
+    String getAllRolesAsString() {
+        return roleMapToString(getAllRoles());
+    }
+
+    public String getDirectRolesAsString() {
+        return roleMapToString(roles);
+    }
+
+    public String roleMapToString(OrderedHashSet roles) {
+
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < roles.size(); i++) {
+            if (sb.length() > 0) {
+                sb.append(',');
+            }
+
+            Grantee role = (Grantee) roles.get(i);
+
+            sb.append(role.getStatementName());
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Gets direct and indirect roles.
+     */
+    public OrderedHashSet getAllRoles() {
+
+        OrderedHashSet set = getGranteeAndAllRoles();
+
+        // Since we added "Grantee" in addition to Roles, need to remove self.
+        set.remove(this);
+
+        return set;
+    }
+
+    public OrderedHashSet getGranteeAndAllRoles() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        addGranteeAndRoles(set);
+
+        return set;
+    }
+
+    public OrderedHashSet getGranteeAndAllRolesWithPublic() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        addGranteeAndRoles(set);
+        set.add(granteeManager.publicRole);
+
+        return set;
+    }
+
+    /**
+     * Adds to given Set this.sName plus all roles and nested roles.
+     *
+     * @return Given role with new elements added.
+     */
+    private OrderedHashSet addGranteeAndRoles(OrderedHashSet set) {
+
+        Grantee candidateRole;
+
+        set.add(this);
+
+        for (int i = 0; i < roles.size(); i++) {
+            candidateRole = (Grantee) roles.get(i);
+
+            if (!set.contains(candidateRole)) {
+                candidateRole.addGranteeAndRoles(set);
+            }
+        }
+
+        return set;
+    }
+
+    /**
+     * returns a map with grantee name keys and sets of granted roles as value
+     */
+    public void addAllRoles(HashMap map) {
+
+        for (int i = 0; i < roles.size(); i++) {
+            Grantee role = (Grantee) roles.get(i);
+
+            map.put(role.granteeName.name, role.roles);
+        }
+    }
+
+    public boolean hasRoleDirect(Grantee role) {
+        return roles.contains(role);
+    }
+
+    public boolean hasRole(Grantee role) {
+        return getAllRoles().contains(role);
+    }
+
+    /**
+     * Grants the specified rights on the specified database object. <p>
+     *
+     * Keys stored in rightsMap for database tables are their HsqlName
+     * attribute. This allows rights to persist when a table is renamed. <p>
+     */
+    void grant(HsqlName name, Right right, Grantee grantor,
+               boolean withGrant) {
+
+        final Right grantableRights = grantor.getAllGrantableRights(name);
+        Right       existingRight   = null;
+
+        if (right == Right.fullRights) {
+            if (grantableRights.isEmpty()) {
+                return;    // has no rights
+            }
+
+            right = grantableRights;
+        } else {
+            if (!grantableRights.contains(right)) {
+                throw Error.error(ErrorCode.X_0L000);
+            }
+        }
+
+        Iterator it = directRightsMap.get(name);
+
+        while (it.hasNext()) {
+            Right existing = (Right) it.next();
+
+            if (existing.grantor == grantor) {
+                existingRight = existing;
+
+                existingRight.add(right);
+
+                break;
+            }
+        }
+
+        if (existingRight == null) {
+            existingRight         = right.duplicate();
+            existingRight.grantor = grantor;
+            existingRight.grantee = this;
+
+            directRightsMap.put(name, existingRight);
+        }
+
+        if (withGrant) {
+            if (existingRight.grantableRights == null) {
+                existingRight.grantableRights = right.duplicate();
+            } else {
+                existingRight.grantableRights.add(right);
+            }
+        }
+
+        if (!grantor.isSystem) {
+
+            // based on assumption that there is no need to access
+            grantor.grantedRightsMap.put(name, existingRight);
+        }
+
+        updateAllRights();
+    }
+
+    /**
+     * Revokes the specified rights on the specified database object. <p>
+     *
+     * If, after removing the specified rights, no rights remain on the
+     * database object, then the key/value pair for that object is removed
+     * from the rights map
+     */
+    void revoke(SchemaObject object, Right right, Grantee grantor,
+                boolean grantOption) {
+
+        HsqlName name = object.getName();
+
+        if (object instanceof Routine) {
+            name = ((Routine) object).getSpecificName();
+        }
+
+        Iterator it       = directRightsMap.get(name);
+        Right    existing = null;
+
+        while (it.hasNext()) {
+            existing = (Right) it.next();
+
+            if (existing.grantor == grantor) {
+                break;
+            }
+        }
+
+        if (existing == null) {
+            return;
+        }
+
+        if (existing.grantableRights != null) {
+            existing.grantableRights.remove(object, right);
+        }
+
+        if (grantOption) {
+            return;
+        }
+
+        if (right.isFull) {
+            directRightsMap.remove(name, existing);
+            grantor.grantedRightsMap.remove(name, existing);
+            updateAllRights();
+
+            return;
+        }
+
+        existing.remove(object, right);
+
+        if (existing.isEmpty()) {
+            directRightsMap.remove(name, existing);
+            grantor.grantedRightsMap.remove(name, existing);
+        }
+
+        updateAllRights();
+
+        return;
+    }
+
+    /**
+     * Revokes all rights on the specified database object.<p>
+     *
+     * This method removes any existing mapping from the rights map
+     */
+    void revokeDbObject(HsqlName name) {
+
+        directRightsMap.remove(name);
+        grantedRightsMap.remove(name);
+        fullRightsMap.remove(name);
+    }
+
+    /**
+     * Revokes all rights from this Grantee object.  The map is cleared and
+     * the database administrator role attribute is set false.
+     */
+    void clearPrivileges() {
+
+        roles.clear();
+        directRightsMap.clear();
+        grantedRightsMap.clear();
+        fullRightsMap.clear();
+
+        isAdmin = false;
+    }
+
+    public OrderedHashSet getColumnsForAllPrivileges(Table table) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return table.getColumnNameSet();
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        return right == null ? Right.emptySet
+                             : right.getColumnsForAllRights(table);
+    }
+
+    public OrderedHashSet getAllDirectPrivileges(SchemaObject object) {
+
+        if (object.getOwner() == this) {
+            OrderedHashSet set = new OrderedHashSet();
+
+            set.add(ownerRights);
+
+            return set;
+        }
+
+        Iterator rights = directRightsMap.get(object.getName());
+
+        if (rights.hasNext()) {
+            OrderedHashSet set = new OrderedHashSet();
+
+            while (rights.hasNext()) {
+                set.add(rights.next());
+            }
+
+            return set;
+        }
+
+        return Right.emptySet;
+    }
+
+    public OrderedHashSet getAllGrantedPrivileges(SchemaObject object) {
+
+        Iterator rights = grantedRightsMap.get(object.getName());
+
+        if (rights.hasNext()) {
+            OrderedHashSet set = new OrderedHashSet();
+
+            while (rights.hasNext()) {
+                set.add(rights.next());
+            }
+
+            return set;
+        }
+
+        return Right.emptySet;
+    }
+
+    /**
+     * Checks if a right represented by the methods
+     * have been granted on the specified database object. <p>
+     *
+     * This is done by checking that a mapping exists in the rights map
+     * from the dbobject argument. Otherwise, it throws.
+     */
+    public void checkSelect(Table table, boolean[] checkList) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return;
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        if (right != null && right.canSelect(table, checkList)) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42501, table.getName().name);
+    }
+
+    public void checkInsert(Table table, boolean[] checkList) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return;
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        if (right != null && right.canInsert(table, checkList)) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42501, table.getName().name);
+    }
+
+    public void checkUpdate(Table table, boolean[] checkList) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return;
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        if (right != null && right.canUpdate(table, checkList)) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42501, table.getName().name);
+    }
+
+    public void checkReferences(Table table, boolean[] checkList) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return;
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        if (right != null && right.canReference(table, checkList)) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42501, table.getName().name);
+    }
+
+    public void checkTrigger(Table table, boolean[] checkList) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return;
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        if (right != null && right.canReference(table, checkList)) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42501, table.getName().name);
+    }
+
+    public void checkDelete(Table table) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return;
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        if (right != null && right.canDelete()) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42501, table.getName().name);
+    }
+
+    public void checkAccess(SchemaObject object) {
+
+        if (isFullyAccessibleByRole(object.getName())) {
+            return;
+        }
+
+        HsqlName name = object.getName();
+
+        if (object instanceof Routine) {
+            name = ((Routine) object).getSpecificName();
+        }
+
+        Right right = (Right) fullRightsMap.get(name);
+
+        if (right != null && !right.isEmpty()) {
+            return;
+        }
+
+        throw Error.error(ErrorCode.X_42501, object.getName().name);
+    }
+
+    /**
+     * Checks if this object can modify schema objects or grant access rights
+     * to them.
+     */
+    public void checkSchemaUpdateOrGrantRights(String schemaName) {
+
+        if (!hasSchemaUpdateOrGrantRights(schemaName)) {
+            throw Error.error(ErrorCode.X_42501, schemaName);
+        }
+    }
+
+    /**
+     * Checks if this object can modify schema objects or grant access rights
+     * to them.
+     */
+    public boolean hasSchemaUpdateOrGrantRights(String schemaName) {
+
+        // If a DBA
+        if (isAdmin()) {
+            return true;
+        }
+
+        Grantee schemaOwner =
+            granteeManager.database.schemaManager.toSchemaOwner(schemaName);
+
+        // If owner of Schema
+        if (schemaOwner == this) {
+            return true;
+        }
+
+        // If a member of Schema authorization role
+        if (hasRole(schemaOwner)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean isGrantable(SchemaObject object, Right right) {
+
+        if (isFullyAccessibleByRole(object.getName())) {
+            return true;
+        }
+
+        Right grantableRights = getAllGrantableRights(object.getName());
+
+        return grantableRights.contains(right);
+    }
+
+    public boolean isGrantable(Grantee role) {
+        return isAdmin;
+    }
+
+    public boolean isFullyAccessibleByRole(HsqlName name) {
+
+        if (isAdmin) {
+            return true;
+        }
+
+        if (name.schema == null) {
+            return false;
+        }
+
+        Grantee owner = name.schema.owner;
+
+        if (owner == this) {
+            return true;
+        }
+
+        if (hasRole(owner)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks whether this Grantee has administrative privs either directly
+     * or indirectly. Otherwise it throws.
+     */
+    public void checkAdmin() {
+
+        if (!isAdmin()) {
+            throw Error.error(ErrorCode.X_42507);
+        }
+    }
+
+    /**
+     * Returns true if this Grantee has administrative privs either directly
+     * or indirectly.
+     */
+    public boolean isAdmin() {
+        return isAdmin;
+    }
+
+    /**
+     * Returns true if this Grantee can create schemas with own authorization.
+     */
+    public boolean isSchemaCreator() {
+        return isAdmin || hasRole(granteeManager.schemaRole);
+    }
+
+    /**
+     * Returns true if this Grantee can change to a different user.
+     */
+    public boolean canChangeAuthorisation() {
+        return isAdmin || hasRole(granteeManager.changeAuthRole);
+    }
+
+    /**
+     * Returns true if this grantee object is for the PUBLIC role.
+     */
+    public boolean isPublic() {
+        return isPublic;
+    }
+
+    /**
+     * Violates naming convention (for backward compatibility).
+     * Should be "setAdminDirect(boolean").
+     */
+    void setAdminDirect() {
+        isAdmin = isAdminDirect = true;
+    }
+
+    /**
+     * Recursive method used with ROLE Grantee objects to set the fullRightsMap
+     * and admin flag for all the roles.
+     *
+     * If a new ROLE is granted to a ROLE Grantee object, the ROLE should first
+     * be added to the Set of ROLE Grantee objects (roles) for the grantee.
+     * The grantee will be the parameter.
+     *
+     * If the direct permissions granted to an existing ROLE Grentee is
+     * modified no extra initial action is necessary.
+     * The existing Grantee will be the parameter.
+     *
+     * If an existing ROLE is REVOKEed from a ROLE, it should first be removed
+     * from the set of ROLE Grantee objects in the containing ROLE.
+     * The containing ROLE will be the parameter.
+     *
+     * If an existing ROLE is DROPped, all its privileges should be cleared
+     * first. The ROLE will be the parameter. After calling this method on
+     * all other roles, the DROPped role should be removed from all grantees.
+     *
+     * After the initial modification, this method should be called iteratively
+     * on all the ROLE Grantee objects contained in RoleManager.
+     *
+     * The updateAllRights() method is then called iteratively on all the
+     * USER Grantee objects contained in UserManager.
+     * @param role a modified, revoked or dropped role.
+     * @return true if this Grantee has possibly changed as a result
+     */
+    boolean updateNestedRoles(Grantee role) {
+
+        boolean hasNested = false;
+
+        if (role != this) {
+            for (int i = 0; i < roles.size(); i++) {
+                Grantee currentRole = (Grantee) roles.get(i);
+
+                hasNested |= currentRole.updateNestedRoles(role);
+            }
+        }
+
+        if (hasNested) {
+            updateAllRights();
+        }
+
+        return hasNested || role == this;
+    }
+
+    /**
+     * Method used with all Grantee objects to set the full set of rights
+     * according to those inherited form ROLE Grantee objects and those
+     * granted to the object itself.
+     */
+
+    /**
+     * @todo -- see if this is correct and the currentRole.fullRightsMap
+     * is always updated prior to being added to this.fullRightsMap
+     */
+    void updateAllRights() {
+
+        fullRightsMap.clear();
+
+        isAdmin = isAdminDirect;
+
+        for (int i = 0; i < roles.size(); i++) {
+            Grantee currentRole = (Grantee) roles.get(i);
+
+            addToFullRights(currentRole.fullRightsMap);
+
+            isAdmin |= currentRole.isAdmin();
+        }
+
+        addToFullRights(directRightsMap);
+
+        if (!isRole && !isPublic && !isSystem) {
+            addToFullRights(granteeManager.publicRole.fullRightsMap);
+        }
+    }
+
+    /**
+     * Full or partial rights are added to existing
+     */
+    void addToFullRights(HashMap map) {
+
+        Iterator it = map.keySet().iterator();
+
+        while (it.hasNext()) {
+            Object key      = it.next();
+            Right  add      = (Right) map.get(key);
+            Right  existing = (Right) fullRightsMap.get(key);
+
+            if (existing == null) {
+                existing = add.duplicate();
+
+                fullRightsMap.put(key, existing);
+            } else {
+                existing.add(add);
+            }
+
+            if (add.grantableRights == null) {
+                continue;
+            }
+
+            if (existing.grantableRights == null) {
+                existing.grantableRights = add.grantableRights.duplicate();
+            } else {
+                existing.grantableRights.add(add.grantableRights);
+            }
+        }
+    }
+
+    /**
+     * Full or partial rights are added to existing
+     */
+    void addToFullRights(MultiValueHashMap map) {
+
+        Iterator it = map.keySet().iterator();
+
+        while (it.hasNext()) {
+            Object   key      = it.next();
+            Iterator values   = map.get(key);
+            Right    existing = (Right) fullRightsMap.get(key);
+
+            while (values.hasNext()) {
+                Right add = (Right) values.next();
+
+                if (existing == null) {
+                    existing = add.duplicate();
+
+                    fullRightsMap.put(key, existing);
+                } else {
+                    existing.add(add);
+                }
+
+                if (add.grantableRights == null) {
+                    continue;
+                }
+
+                if (existing.grantableRights == null) {
+                    existing.grantableRights = add.grantableRights.duplicate();
+                } else {
+                    existing.grantableRights.add(add.grantableRights);
+                }
+            }
+        }
+    }
+
+    /**
+     * Iteration of all visible grantees, including self. <p>
+     *
+     * For grantees with admin, this is all grantees.
+     * For regular grantees, this is self plus all roles granted directly
+     * or indirectly
+     */
+    public Set visibleGrantees() {
+
+        HashSet        grantees = new HashSet();
+        GranteeManager gm       = granteeManager;
+
+        if (isAdmin()) {
+            grantees.addAll(gm.getGrantees());
+        } else {
+            grantees.add(this);
+
+            Iterator it = getAllRoles().iterator();
+
+            while (it.hasNext()) {
+                grantees.add(it.next());
+            }
+        }
+
+        return grantees;
+    }
+
+    /**
+     * Set of all non-reserved visible grantees, including self. <p>
+     *
+     * For grantees with admin, this is all grantees.
+     * For regular grantees, this is self plus all roles granted directly
+     * or indirectly. <P>
+     *
+     * @param andPublic when <tt>true</tt> retains the reserved PUBLIC grantee
+     */
+    public Set nonReservedVisibleGrantees(boolean andPublic) {
+
+        Set            grantees = visibleGrantees();
+        GranteeManager gm       = granteeManager;
+
+        grantees.remove(gm.dbaRole);
+        grantees.remove(GranteeManager.systemAuthorisation);
+
+        if (!andPublic) {
+            grantees.remove(gm.publicRole);
+        }
+
+        return grantees;
+    }
+
+    public boolean hasNonSelectTableRight(Table table) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return true;
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        if (right == null) {
+            return false;
+        }
+
+        return right.isFull || right.isFullDelete || right.isFullInsert
+               || right.isFullUpdate || right.isFullReferences
+               || right.isFullTrigger;
+    }
+
+    public boolean hasTableRight(Table table) {
+
+        if (isFullyAccessibleByRole(table.getName())) {
+            return true;
+        }
+
+        Right right = (Right) fullRightsMap.get(table.getName());
+
+        if (right == null) {
+            return false;
+        }
+
+        return right.isFull || right.isFullDelete || right.isFullInsert
+               || right.isFullUpdate || right.isFullReferences
+               || right.isFullTrigger || right.isFullSelect;
+    }
+
+    public Iterator getAllDirectFullRights(SchemaObject object) {
+
+        Grantee owner = object.getOwner();
+
+        if (owner == this) {
+            return new WrapperIterator(ownerRights);
+        }
+
+        return directRightsMap.get(object.getName());
+    }
+
+    public Right getAllGrantableRights(HsqlName name) {
+
+        if (isAdmin) {
+            return name.schema.owner.ownerRights;
+        }
+
+        if (name.schema.owner == this) {
+            return ownerRights;
+        }
+
+        if (roles.contains(name.schema.owner)) {
+            return name.schema.owner.ownerRights;
+        }
+
+        OrderedHashSet set = getAllRoles();
+
+        for (int i = 0; i < set.size(); i++) {
+            Grantee role = (Grantee) set.get(i);
+
+            if (name.schema.owner == role) {
+                return role.ownerRights;
+            }
+        }
+
+        Right right = (Right) fullRightsMap.get(name);
+
+        return right == null || right.grantableRights == null ? Right.noRights
+                                                              : right
+                                                              .grantableRights;
+    }
+
+    public boolean isAccessible(HsqlName name, int privilegeType) {
+
+        if (isFullyAccessibleByRole(name)) {
+            return true;
+        }
+
+        Right right = (Right) fullRightsMap.get(name);
+
+        if (right == null) {
+            return false;
+        }
+
+        return right.canAccess(privilegeType);
+    }
+
+    /**
+     * returns true if grantee has any privilege (to any column) of the object
+     */
+    public boolean isAccessible(SchemaObject object) {
+        return isAccessible(object.getName());
+    }
+
+    public boolean isAccessible(HsqlName name) {
+
+        if (isFullyAccessibleByRole(name)) {
+            return true;
+        }
+
+        Right right = (Right) fullRightsMap.get(name);
+
+        if (right != null && !right.isEmpty()) {
+            return true;
+        }
+
+        if (!isPublic) {
+            return granteeManager.publicRole.isAccessible(name);
+        }
+
+        return false;
+    }
+
+    public HsqlArrayList getRightsSQL() {
+
+        HsqlArrayList list       = new HsqlArrayList();
+        String        roleString = getDirectRolesAsString();
+
+        if (roleString.length() != 0) {
+            StringBuffer sb = new StringBuffer(128);
+
+            sb.append(Tokens.T_GRANT).append(' ').append(roleString);
+            sb.append(' ').append(Tokens.T_TO).append(' ');
+            sb.append(getStatementName());
+            list.add(sb.toString());
+        }
+
+        MultiValueHashMap rightsMap = getRights();
+        Iterator          dbObjects = rightsMap.keySet().iterator();
+
+        while (dbObjects.hasNext()) {
+            Object   nameObject = dbObjects.next();
+            Iterator rights     = rightsMap.get(nameObject);
+
+            while (rights.hasNext()) {
+                Right        right    = (Right) rights.next();
+                StringBuffer sb       = new StringBuffer(128);
+                HsqlName     hsqlname = (HsqlName) nameObject;
+
+                switch (hsqlname.type) {
+
+                    case SchemaObject.TABLE :
+                    case SchemaObject.VIEW :
+                        Table table =
+                            granteeManager.database.schemaManager
+                                .findUserTable(null, hsqlname.name,
+                                               hsqlname.schema.name);
+
+                        if (table != null) {
+                            sb.append(Tokens.T_GRANT).append(' ');
+                            sb.append(right.getTableRightsSQL(table));
+                            sb.append(' ').append(Tokens.T_ON).append(' ');
+                            sb.append(Tokens.T_TABLE).append(' ');
+                            sb.append(
+                                hsqlname.getSchemaQualifiedStatementName());
+                        }
+                        break;
+
+                    case SchemaObject.SEQUENCE :
+                        NumberSequence sequence =
+                            (NumberSequence) granteeManager.database
+                                .schemaManager
+                                .findSchemaObject(hsqlname.name,
+                                                  hsqlname.schema.name,
+                                                  SchemaObject.SEQUENCE);
+
+                        if (sequence != null) {
+                            sb.append(Tokens.T_GRANT).append(' ');
+                            sb.append(Tokens.T_USAGE);
+                            sb.append(' ').append(Tokens.T_ON).append(' ');
+                            sb.append(Tokens.T_SEQUENCE).append(' ');
+                            sb.append(
+                                hsqlname.getSchemaQualifiedStatementName());
+                        }
+                        break;
+
+                    case SchemaObject.DOMAIN :
+                        Type domain =
+                            (Type) granteeManager.database.schemaManager
+                                .findSchemaObject(hsqlname.name,
+                                                  hsqlname.schema.name,
+                                                  SchemaObject.DOMAIN);
+
+                        if (domain != null) {
+                            sb.append(Tokens.T_GRANT).append(' ');
+                            sb.append(Tokens.T_USAGE);
+                            sb.append(' ').append(Tokens.T_ON).append(' ');
+                            sb.append(Tokens.T_DOMAIN).append(' ');
+                            sb.append(
+                                hsqlname.getSchemaQualifiedStatementName());
+                        }
+                        break;
+
+                    case SchemaObject.TYPE :
+                        Type type =
+                            (Type) granteeManager.database.schemaManager
+                                .findSchemaObject(hsqlname.name,
+                                                  hsqlname.schema.name,
+                                                  SchemaObject.DOMAIN);
+
+                        if (type != null) {
+                            sb.append(Tokens.T_GRANT).append(' ');
+                            sb.append(Tokens.T_USAGE);
+                            sb.append(' ').append(Tokens.T_ON).append(' ');
+                            sb.append(Tokens.T_TYPE).append(' ');
+                            sb.append(
+                                hsqlname.getSchemaQualifiedStatementName());
+                        }
+                        break;
+
+                    case SchemaObject.PROCEDURE :
+                    case SchemaObject.FUNCTION :
+                    case SchemaObject.SPECIFIC_ROUTINE :
+                        SchemaObject routine =
+                            (SchemaObject) granteeManager.database
+                                .schemaManager
+                                .findSchemaObject(hsqlname.name,
+                                                  hsqlname.schema.name,
+                                                  hsqlname.type);
+
+                        if (routine != null) {
+                            sb.append(Tokens.T_GRANT).append(' ');
+                            sb.append(Tokens.T_EXECUTE).append(' ');
+                            sb.append(Tokens.T_ON).append(' ');
+                            sb.append(Tokens.T_SPECIFIC).append(' ');
+
+                            if (routine.getType() == SchemaObject.PROCEDURE) {
+                                sb.append(Tokens.T_PROCEDURE);
+                            } else {
+                                sb.append(Tokens.T_FUNCTION);
+                            }
+
+                            sb.append(' ');
+                            sb.append(
+                                hsqlname.getSchemaQualifiedStatementName());
+                        }
+                        break;
+                }
+
+                if (sb.length() == 0) {
+                    continue;
+                }
+
+                sb.append(' ').append(Tokens.T_TO).append(' ');
+                sb.append(getStatementName());
+                list.add(sb.toString());
+            }
+        }
+
+        return list;
+    }
+}
diff --git a/src/org/hsqldb/rights/GranteeManager.java b/src/org/hsqldb/rights/GranteeManager.java
new file mode 100644
index 0000000..3e289a6
--- /dev/null
+++ b/src/org/hsqldb/rights/GranteeManager.java
@@ -0,0 +1,770 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rights;
+
+import org.hsqldb.Database;
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.Routine;
+import org.hsqldb.RoutineSchema;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.SqlInvariants;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.Collection;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.lib.Set;
+
+/**
+ * Contains a set of Grantee objects, and supports operations for creating,
+ * finding, modifying and deleting Grantee objects for a Database; plus
+ * Administrative privileges.
+ *
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ *
+ * @version 1.9.0
+ * @since 1.8.0
+ * @see Grantee
+ */
+public class GranteeManager {
+
+    /**
+     * The grantee object for the _SYSTEM role.
+     */
+    static User systemAuthorisation;
+
+    static {
+        HsqlName name = HsqlNameManager.newSystemObjectName(
+            SqlInvariants.SYSTEM_AUTHORIZATION_NAME, SchemaObject.GRANTEE);
+
+        systemAuthorisation          = new User(name, null);
+        systemAuthorisation.isSystem = true;
+
+        systemAuthorisation.setAdminDirect();
+        systemAuthorisation.setInitialSchema(
+            SqlInvariants.SYSTEM_SCHEMA_HSQLNAME);
+
+        SqlInvariants.INFORMATION_SCHEMA_HSQLNAME.owner = systemAuthorisation;
+        SqlInvariants.SYSTEM_SCHEMA_HSQLNAME.owner      = systemAuthorisation;
+        SqlInvariants.LOBS_SCHEMA_HSQLNAME.owner        = systemAuthorisation;
+        SqlInvariants.SQLJ_SCHEMA_HSQLNAME.owner        = systemAuthorisation;
+    }
+
+    /**
+     * Map of grantee-String-to-Grantee-objects.<p>
+     * Keys include all USER and ROLE names
+     */
+    private HashMappedList map = new HashMappedList();
+
+    /**
+     * Map of role-Strings-to-Grantee-object.<p>
+     * Keys include all ROLES names
+     */
+    private HashMappedList roleMap = new HashMappedList();
+
+    /**
+     * Used only to pass the SchemaManager to Grantees for checking
+     * schema authorizations.
+     */
+    Database database;
+
+    /**
+     * The PUBLIC role.
+     */
+    Grantee publicRole;
+
+    /**
+     * The DBA role.
+     */
+    Grantee dbaRole;
+
+    /**
+     * The role for schema creation rights.
+     */
+    Grantee schemaRole;
+
+    /**
+     * The role for changing authorization rights.
+     */
+    Grantee changeAuthRole;
+
+    /**
+     * Construct the GranteeManager for a Database. Construct special Grantee
+     * objects for _SYSTEM, PUBLIC and DBA, and add them to the Grantee map.
+     *
+     * @param database Only needed to link to the RoleManager later on.
+     */
+    public GranteeManager(Database database) {
+
+        this.database = database;
+
+//        map.add(systemAuthorisation.getNameString(), systemAuthorisation);
+//        roleMap.add(systemAuthorisation.getNameString(), systemAuthorisation);
+        addRole(
+            this.database.nameManager.newHsqlName(
+                SqlInvariants.PUBLIC_ROLE_NAME, false, SchemaObject.GRANTEE));
+
+        publicRole          = getRole(SqlInvariants.PUBLIC_ROLE_NAME);
+        publicRole.isPublic = true;
+
+        addRole(
+            this.database.nameManager.newHsqlName(
+                SqlInvariants.DBA_ADMIN_ROLE_NAME, false,
+                SchemaObject.GRANTEE));
+
+        dbaRole = getRole(SqlInvariants.DBA_ADMIN_ROLE_NAME);
+
+        dbaRole.setAdminDirect();
+        addRole(
+            this.database.nameManager.newHsqlName(
+                SqlInvariants.SCHEMA_CREATE_ROLE_NAME, false,
+                SchemaObject.GRANTEE));
+
+        schemaRole = getRole(SqlInvariants.SCHEMA_CREATE_ROLE_NAME);
+
+        addRole(
+            this.database.nameManager.newHsqlName(
+                SqlInvariants.CHANGE_AUTH_ROLE_NAME, false,
+                SchemaObject.GRANTEE));
+
+        changeAuthRole = getRole(SqlInvariants.CHANGE_AUTH_ROLE_NAME);
+    }
+
+    static final IntValueHashMap rightsStringLookup = new IntValueHashMap(7);
+
+    static {
+        rightsStringLookup.put(Tokens.T_ALL, GrantConstants.ALL);
+        rightsStringLookup.put(Tokens.T_SELECT, GrantConstants.SELECT);
+        rightsStringLookup.put(Tokens.T_UPDATE, GrantConstants.UPDATE);
+        rightsStringLookup.put(Tokens.T_DELETE, GrantConstants.DELETE);
+        rightsStringLookup.put(Tokens.T_INSERT, GrantConstants.INSERT);
+        rightsStringLookup.put(Tokens.T_EXECUTE, GrantConstants.EXECUTE);
+        rightsStringLookup.put(Tokens.T_USAGE, GrantConstants.USAGE);
+        rightsStringLookup.put(Tokens.T_REFERENCES, GrantConstants.REFERENCES);
+        rightsStringLookup.put(Tokens.T_TRIGGER, GrantConstants.TRIGGER);
+    }
+
+    public Grantee getDBARole() {
+        return dbaRole;
+    }
+
+    public static Grantee getSystemRole() {
+        return systemAuthorisation;
+    }
+
+    /**
+     * Grants the rights represented by the rights argument on
+     * the database object identified by the dbobject argument
+     * to the Grantee object identified by name argument.<p>
+     *
+     *  Note: For the dbobject argument, Java Class objects are identified
+     *  using a String object whose value is the fully qualified name
+     *  of the Class, while Table and other objects are
+     *  identified by an HsqlName object.  A Table
+     *  object identifier must be precisely the one obtained by calling
+     *  table.getName(); if a different HsqlName
+     *  object with an identical name attribute is specified, then
+     *  rights checks and tests will fail, since the HsqlName
+     *  class implements its {@link HsqlName#hashCode hashCode} and
+     *  {@link HsqlName#equals equals} methods based on pure object
+     *  identity, rather than on attribute values. <p>
+     */
+    public void grant(OrderedHashSet granteeList, SchemaObject dbObject,
+                      Right right, Grantee grantor, boolean withGrantOption) {
+
+        if (dbObject instanceof RoutineSchema) {
+            SchemaObject[] routines =
+                ((RoutineSchema) dbObject).getSpecificRoutines();
+
+            grant(granteeList, routines, right, grantor, withGrantOption);
+
+            return;
+        }
+
+        HsqlName name = dbObject.getName();
+        if (dbObject instanceof Routine) {
+            name = ((Routine) dbObject).getSpecificName();
+        }
+
+        if (!grantor.isGrantable(dbObject, right)) {
+            throw Error.error(ErrorCode.X_0L000, grantor.getNameString());
+        }
+
+        if (grantor.isAdmin()) {
+            grantor = dbObject.getOwner();
+        }
+
+        checkGranteeList(granteeList);
+
+        for (int i = 0; i < granteeList.size(); i++) {
+            Grantee grantee = get((String) granteeList.get(i));
+
+            grantee.grant(name, right, grantor, withGrantOption);
+
+            if (grantee.isRole) {
+                updateAllRights(grantee);
+            }
+        }
+    }
+
+    public void grant(OrderedHashSet granteeList, SchemaObject[] routines,
+                      Right right, Grantee grantor, boolean withGrantOption) {
+
+        boolean granted = false;
+
+        for (int i = 0; i < routines.length; i++) {
+            if (!grantor.isGrantable(routines[i], right)) {
+                continue;
+            }
+
+            grant(granteeList, routines[i], right, grantor, withGrantOption);
+
+            granted = true;
+        }
+
+        if (!granted) {
+            throw Error.error(ErrorCode.X_0L000, grantor.getNameString());
+        }
+    }
+
+    public void checkGranteeList(OrderedHashSet granteeList) {
+
+        for (int i = 0; i < granteeList.size(); i++) {
+            String  name    = (String) granteeList.get(i);
+            Grantee grantee = get(name);
+
+            if (grantee == null) {
+                throw Error.error(ErrorCode.X_28501, name);
+            }
+
+            if (isImmutable(name)) {
+                throw Error.error(ErrorCode.X_28502, name);
+            }
+        }
+    }
+
+    /**
+     * Grant a role to this Grantee.
+     */
+    public void grant(String granteeName, String roleName, Grantee grantor) {
+
+        Grantee grantee = get(granteeName);
+
+        if (grantee == null) {
+            throw Error.error(ErrorCode.X_28501, granteeName);
+        }
+
+        if (isImmutable(granteeName)) {
+            throw Error.error(ErrorCode.X_28502, granteeName);
+        }
+
+        Grantee role = getRole(roleName);
+
+        if (role == null) {
+            throw Error.error(ErrorCode.X_0P000, roleName);
+        }
+
+        if (role == grantee) {
+            throw Error.error(ErrorCode.X_0P501, granteeName);
+        }
+
+        // boucherb@users 20050515
+        // SQL 2003 Foundation, 4.34.3
+        // No cycles of role grants are allowed.
+        if (role.hasRole(grantee)) {
+
+            // boucherb@users
+
+            /** @todo: Correct reporting of actual grant path */
+            throw Error.error(ErrorCode.X_0P501, roleName);
+        }
+
+        if (!grantor.isGrantable(role)) {
+            throw Error.error(ErrorCode.X_0L000, grantor.getNameString());
+        }
+
+        grantee.grant(role);
+        grantee.updateAllRights();
+
+        if (grantee.isRole) {
+            updateAllRights(grantee);
+        }
+    }
+
+    public void checkRoleList(String granteeName, OrderedHashSet roleList,
+                              Grantee grantor, boolean grant) {
+
+        Grantee grantee = get(granteeName);
+
+        for (int i = 0; i < roleList.size(); i++) {
+            String  roleName = (String) roleList.get(i);
+            Grantee role     = getRole(roleName);
+
+            if (role == null) {
+                throw Error.error(ErrorCode.X_0P000, roleName);
+            }
+
+            if (roleName.equals(SqlInvariants.SYSTEM_AUTHORIZATION_NAME)
+                    || roleName.equals(SqlInvariants.PUBLIC_ROLE_NAME)) {
+                throw Error.error(ErrorCode.X_28502, roleName);
+            }
+
+            if (grant) {
+                if (grantee.getDirectRoles().contains(role)) {
+
+                    /** @todo  shouldnt throw */
+                    throw Error.error(ErrorCode.X_0P000, granteeName);
+                }
+            } else {
+                if (!grantee.getDirectRoles().contains(role)) {
+
+                    /** @todo  shouldnt throw */
+                    throw Error.error(ErrorCode.X_0P000, roleName);
+                }
+            }
+
+            if (!grantor.isAdmin()) {
+                throw Error.error(ErrorCode.X_0L000, grantor.getNameString());
+            }
+        }
+    }
+
+    public void grantSystemToPublic(SchemaObject object, Right right) {
+        publicRole.grant(object.getName(), right, systemAuthorisation, true);
+    }
+
+    /**
+     * Revoke a role from a Grantee
+     */
+    public void revoke(String granteeName, String roleName, Grantee grantor) {
+
+        if (!grantor.isAdmin()) {
+            throw Error.error(ErrorCode.X_42507);
+        }
+
+        Grantee grantee = get(granteeName);
+
+        if (grantee == null) {
+            throw Error.error(ErrorCode.X_28000, granteeName);
+        }
+
+        Grantee role = (Grantee) roleMap.get(roleName);
+
+        grantee.revoke(role);
+        grantee.updateAllRights();
+
+        if (grantee.isRole) {
+            updateAllRights(grantee);
+        }
+    }
+
+    /**
+     * Revokes the rights represented by the rights argument on
+     * the database object identified by the dbobject argument
+     * from the User object identified by the name
+     * argument.<p>
+     * @see #grant
+     */
+    public void revoke(OrderedHashSet granteeList, SchemaObject dbObject,
+                       Right rights, Grantee grantor, boolean grantOption,
+                       boolean cascade) {
+
+        if (dbObject instanceof RoutineSchema) {
+            SchemaObject[] routines =
+                ((RoutineSchema) dbObject).getSpecificRoutines();
+
+            revoke(granteeList, routines, rights, grantor, grantOption,
+                   cascade);
+
+            return;
+        }
+
+        HsqlName name = dbObject.getName();
+        if (dbObject instanceof Routine) {
+            name = ((Routine) dbObject).getSpecificName();
+        }
+
+        if (!grantor.isFullyAccessibleByRole(name)) {
+            throw Error.error(ErrorCode.X_42501, dbObject.getName().name);
+        }
+
+        if (grantor.isAdmin()) {
+            grantor = dbObject.getOwner();
+        }
+
+        for (int i = 0; i < granteeList.size(); i++) {
+            String  granteeName = (String) granteeList.get(i);
+            Grantee g    = get(granteeName);
+
+            if (g == null) {
+                throw Error.error(ErrorCode.X_28501, granteeName);
+            }
+
+            if (isImmutable(granteeName)) {
+                throw Error.error(ErrorCode.X_28502, granteeName);
+            }
+        }
+
+        for (int i = 0; i < granteeList.size(); i++) {
+            String  granteeName = (String) granteeList.get(i);
+            Grantee g    = get(granteeName);
+
+            g.revoke(dbObject, rights, grantor, grantOption);
+            g.updateAllRights();
+
+            if (g.isRole) {
+                updateAllRights(g);
+            }
+        }
+    }
+
+    public void revoke(OrderedHashSet granteeList, SchemaObject[] routines,
+                       Right rights, Grantee grantor, boolean grantOption,
+                       boolean cascade) {
+
+        for (int i = 0; i < routines.length; i++) {
+            revoke(granteeList, routines[i], rights, grantor, grantOption,
+                   cascade);
+        }
+    }
+
+    /**
+     * Removes a role without any privileges from all grantees
+     */
+    void removeEmptyRole(Grantee role) {
+
+        for (int i = 0; i < map.size(); i++) {
+            Grantee grantee = (Grantee) map.get(i);
+
+            grantee.roles.remove(role);
+        }
+    }
+
+    /**
+     * Removes all rights mappings for the database object identified by
+     * the dbobject argument from all Grantee objects in the set.
+     */
+    public void removeDbObject(HsqlName name) {
+
+        for (int i = 0; i < map.size(); i++) {
+            Grantee g = (Grantee) map.get(i);
+
+            g.revokeDbObject(name);
+        }
+    }
+
+    public void removeDbObjects(OrderedHashSet nameSet) {
+
+        Iterator it = nameSet.iterator();
+
+        while (it.hasNext()) {
+            HsqlName name = (HsqlName) it.next();
+
+            for (int i = 0; i < map.size(); i++) {
+                Grantee g = (Grantee) map.get(i);
+
+                g.revokeDbObject(name);
+            }
+        }
+    }
+
+    /**
+     * First updates all ROLE Grantee objects. Then updates all USER Grantee
+     * Objects.
+     */
+    void updateAllRights(Grantee role) {
+
+        for (int i = 0; i < map.size(); i++) {
+            Grantee grantee = (Grantee) map.get(i);
+
+            if (grantee.isRole) {
+                grantee.updateNestedRoles(role);
+            }
+        }
+
+        for (int i = 0; i < map.size(); i++) {
+            Grantee grantee = (Grantee) map.get(i);
+
+            if (!grantee.isRole) {
+                grantee.updateAllRights();
+            }
+        }
+    }
+
+    /**
+     */
+    public boolean removeGrantee(String name) {
+
+        /*
+         * Explicitly can't remove PUBLIC_USER_NAME and system grantees.
+         */
+        if (isReserved(name)) {
+            return false;
+        }
+
+        Grantee g = (Grantee) map.remove(name);
+
+        if (g == null) {
+            return false;
+        }
+
+        g.clearPrivileges();
+        updateAllRights(g);
+
+        if (g.isRole) {
+            roleMap.remove(name);
+            removeEmptyRole(g);
+        }
+
+        return true;
+    }
+
+    /**
+     * Creates a new Role object under management of this object. <p>
+     *
+     *  A set of constraints regarding user creation is imposed: <p>
+     *
+     *  <OL>
+     *    <LI>Can't create a role with name same as any right.
+     *
+     *    <LI>If this object's collection already contains an element whose
+     *        name attribute equals the name argument, then
+     *        a GRANTEE_ALREADY_EXISTS or ROLE_ALREADY_EXISTS Trace
+     *        is thrown.
+     *        (This will catch attempts to create Reserved grantee names).
+     *  </OL>
+     */
+    public Grantee addRole(HsqlName name) {
+
+        if (map.containsKey(name.name)) {
+            throw Error.error(ErrorCode.X_28503, name.name);
+        }
+
+        Grantee g = new Grantee(name, this);
+
+        g.isRole = true;
+
+        map.put(name.name, g);
+        roleMap.add(name.name, g);
+
+        return g;
+    }
+
+    public User addUser(HsqlName name) {
+
+        if (map.containsKey(name.name)) {
+            throw Error.error(ErrorCode.X_28503, name.name);
+        }
+
+        User g = new User(name, this);
+
+        map.put(name.name, g);
+
+        return g;
+    }
+
+    /**
+     * Returns true if named Grantee object exists.
+     * This will return true for reserved Grantees
+     * SYSTEM_AUTHORIZATION_NAME, ADMIN_ROLE_NAME, PUBLIC_USER_NAME.
+     */
+    boolean isGrantee(String name) {
+        return map.containsKey(name);
+    }
+
+    public static int getCheckSingleRight(String right) {
+
+        int r = getRight(right);
+
+        if (r != 0) {
+            return r;
+        }
+
+        throw Error.error(ErrorCode.X_42581, right);
+    }
+
+    /**
+     * Translate a string representation or right(s) into its numeric form.
+     */
+    public static int getRight(String right) {
+        return rightsStringLookup.get(right, 0);
+    }
+
+    public Grantee get(String name) {
+        return (Grantee) map.get(name);
+    }
+
+    public Collection getGrantees() {
+        return map.values();
+    }
+
+    public static boolean validRightString(String rightString) {
+        return getRight(rightString) != 0;
+    }
+
+    public static boolean isImmutable(String name) {
+
+        return name.equals(SqlInvariants.SYSTEM_AUTHORIZATION_NAME)
+               || name.equals(SqlInvariants.DBA_ADMIN_ROLE_NAME)
+               || name.equals(SqlInvariants.SCHEMA_CREATE_ROLE_NAME)
+               || name.equals(SqlInvariants.CHANGE_AUTH_ROLE_NAME);
+    }
+
+    public static boolean isReserved(String name) {
+
+        return name.equals(SqlInvariants.SYSTEM_AUTHORIZATION_NAME)
+               || name.equals(SqlInvariants.DBA_ADMIN_ROLE_NAME)
+               || name.equals(SqlInvariants.SCHEMA_CREATE_ROLE_NAME)
+               || name.equals(SqlInvariants.CHANGE_AUTH_ROLE_NAME)
+               || name.equals(SqlInvariants.PUBLIC_ROLE_NAME);
+    }
+
+    /**
+     * Attempts to drop a Role with the specified name
+     *  from this object's set. <p>
+     *
+     *  A successful drop action consists of: <p>
+     *
+     *  <UL>
+     *
+     *    <LI>removing the Grantee object with the specified name
+     *        from the set.
+     *  </UL> <p>
+     *
+     */
+    public void dropRole(String name) {
+
+        if (!isRole(name)) {
+            throw Error.error(ErrorCode.X_0P000, name);
+        }
+
+        if (GranteeManager.isReserved(name)) {
+            throw Error.error(ErrorCode.X_42507);
+        }
+
+        removeGrantee(name);
+    }
+
+    public Set getRoleNames() {
+        return roleMap.keySet();
+    }
+
+    public Collection getRoles() {
+        return roleMap.values();
+    }
+
+    /**
+     * Returns Grantee for the named Role
+     */
+    public Grantee getRole(String name) {
+
+        Grantee g = (Grantee) roleMap.get(name);
+
+        if (g == null) {
+            throw Error.error(ErrorCode.X_0P000, name);
+        }
+
+        return g;
+    }
+
+    public boolean isRole(String name) {
+        return roleMap.containsKey(name);
+    }
+
+    public String[] getSQL() {
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        // roles
+        Iterator it = getRoles().iterator();
+
+        while (it.hasNext()) {
+            Grantee grantee = (Grantee) it.next();
+
+            // ADMIN_ROLE_NAME is not persisted
+            if (!GranteeManager.isReserved(grantee.getNameString())) {
+                list.add(grantee.getSQL());
+            }
+        }
+
+        // users
+        it = getGrantees().iterator();
+
+        for (; it.hasNext(); ) {
+            Grantee grantee = (Grantee) it.next();
+
+            if (grantee instanceof User) {
+                list.add(grantee.getSQL());
+            }
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+
+    public String[] getRightstSQL() {
+
+        HsqlArrayList list     = new HsqlArrayList();
+        Iterator      grantees = getGrantees().iterator();
+
+        while (grantees.hasNext()) {
+            Grantee grantee = (Grantee) grantees.next();
+            String  name    = grantee.getNameString();
+
+            // _SYSTEM user, DBA Role grants not persisted
+            if (GranteeManager.isImmutable(name)) {
+                continue;
+            }
+
+            HsqlArrayList subList = grantee.getRightsSQL();
+
+            list.addAll(subList);
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+}
diff --git a/src/org/hsqldb/rights/Right.java b/src/org/hsqldb/rights/Right.java
new file mode 100644
index 0000000..c7a9fbb
--- /dev/null
+++ b/src/org/hsqldb/rights/Right.java
@@ -0,0 +1,931 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rights;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Table;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.OrderedHashSet;
+
+/**
+ * Represents the set of rights on a database object
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ *
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class Right {
+
+    boolean        isFull;
+    boolean        isFullSelect;
+    boolean        isFullInsert;
+    boolean        isFullUpdate;
+    boolean        isFullReferences;
+    boolean        isFullTrigger;
+    boolean        isFullDelete;
+    OrderedHashSet selectColumnSet;
+    OrderedHashSet insertColumnSet;
+    OrderedHashSet updateColumnSet;
+    OrderedHashSet referencesColumnSet;
+    OrderedHashSet triggerColumnSet;
+
+    //
+    Right   grantableRights;
+    Grantee grantor;
+    Grantee grantee;
+
+    //
+    public static final OrderedHashSet emptySet      = new OrderedHashSet();
+    public static final Right          fullRights    = new Right();
+    public static final Right          noRights      = new Right();
+    static final OrderedHashSet        fullRightsSet = new OrderedHashSet();
+
+    static {
+        fullRights.grantor = GranteeManager.systemAuthorisation;
+        fullRights.isFull  = true;
+
+        fullRightsSet.add(fullRights);
+    }
+
+    public static final String[] privilegeNames = {
+        Tokens.T_SELECT, Tokens.T_INSERT, Tokens.T_UPDATE, Tokens.T_DELETE,
+        Tokens.T_REFERENCES, Tokens.T_TRIGGER
+    };
+    public static final int[] privilegeTypes = {
+        GrantConstants.SELECT, GrantConstants.INSERT, GrantConstants.UPDATE,
+        GrantConstants.DELETE, GrantConstants.REFERENCES,
+        GrantConstants.TRIGGER
+    };
+
+    public Right() {
+        this.isFull = false;
+    }
+
+    Right(Table table) {
+
+        isFull              = false;
+        isFullDelete        = true;
+        selectColumnSet     = table.getColumnNameSet();
+        insertColumnSet     = table.getColumnNameSet();
+        updateColumnSet     = table.getColumnNameSet();
+        referencesColumnSet = table.getColumnNameSet();
+        triggerColumnSet    = table.getColumnNameSet();
+    }
+
+    public boolean isFull() {
+        return isFull;
+    }
+
+    public Grantee getGrantor() {
+        return grantor;
+    }
+
+    public Grantee getGrantee() {
+        return grantee;
+    }
+
+    public Right getGrantableRights() {
+        return grantableRights == null ? noRights
+                                       : grantableRights;
+    }
+
+    public Right duplicate() {
+
+        Right right = new Right();
+
+        right.add(this);
+
+        return right;
+    }
+
+    /**
+     * Supports column level GRANT
+     */
+    public void add(Right right) {
+
+        if (isFull) {
+            return;
+        }
+
+        if (right.isFull) {
+            clear();
+
+            isFull = true;
+
+            return;
+        }
+
+        isFullSelect     |= right.isFullSelect;
+        isFullInsert     |= right.isFullInsert;
+        isFullUpdate     |= right.isFullUpdate;
+        isFullReferences |= right.isFullReferences;
+        isFullDelete     |= right.isFullDelete;
+
+        if (isFullSelect) {
+            selectColumnSet = null;
+        } else if (right.selectColumnSet != null) {
+            if (selectColumnSet == null) {
+                selectColumnSet = new OrderedHashSet();
+            }
+
+            selectColumnSet.addAll(right.selectColumnSet);
+        }
+
+        if (isFullInsert) {
+            insertColumnSet = null;
+        } else if (right.insertColumnSet != null) {
+            if (insertColumnSet == null) {
+                insertColumnSet = new OrderedHashSet();
+            }
+
+            insertColumnSet.addAll(right.insertColumnSet);
+        }
+
+        if (isFullUpdate) {
+            updateColumnSet = null;
+        } else if (right.updateColumnSet != null) {
+            if (updateColumnSet == null) {
+                updateColumnSet = new OrderedHashSet();
+            }
+
+            updateColumnSet.addAll(right.updateColumnSet);
+        }
+
+        if (isFullReferences) {
+            referencesColumnSet = null;
+        } else if (right.referencesColumnSet != null) {
+            if (referencesColumnSet == null) {
+                referencesColumnSet = new OrderedHashSet();
+            }
+
+            referencesColumnSet.addAll(right.referencesColumnSet);
+        }
+
+        if (isFullTrigger) {
+            triggerColumnSet = null;
+        } else if (right.triggerColumnSet != null) {
+            if (triggerColumnSet == null) {
+                triggerColumnSet = new OrderedHashSet();
+            }
+
+            triggerColumnSet.addAll(right.triggerColumnSet);
+        }
+    }
+
+    /**
+     * supports column level REVOKE
+     */
+    public void remove(SchemaObject object, Right right) {
+
+        if (right.isFull) {
+            clear();
+
+            return;
+        }
+
+        if (isFull) {
+            isFull = false;
+            isFullSelect = isFullInsert = isFullUpdate = isFullReferences =
+                isFullDelete = true;
+        }
+
+        if (right.isFullDelete) {
+            isFullDelete = false;
+        }
+
+        if (!isFullSelect && selectColumnSet == null) {}
+        else if (right.isFullSelect) {
+            isFullSelect    = false;
+            selectColumnSet = null;
+        } else if (right.selectColumnSet != null) {
+            if (isFullSelect) {
+                isFullSelect    = false;
+                selectColumnSet = ((Table) object).getColumnNameSet();
+            }
+
+            selectColumnSet.removeAll(right.selectColumnSet);
+
+            if (selectColumnSet.isEmpty()) {
+                selectColumnSet = null;
+            }
+        }
+
+        if (!isFullInsert && insertColumnSet == null) {}
+        else if (right.isFullInsert) {
+            isFullInsert    = false;
+            insertColumnSet = null;
+        } else if (right.insertColumnSet != null) {
+            if (isFullInsert) {
+                isFullInsert    = false;
+                insertColumnSet = ((Table) object).getColumnNameSet();
+            }
+
+            insertColumnSet.removeAll(right.insertColumnSet);
+
+            if (insertColumnSet.isEmpty()) {
+                insertColumnSet = null;
+            }
+        }
+
+        if (!isFullUpdate && updateColumnSet == null) {}
+        else if (right.isFullUpdate) {
+            isFullUpdate    = false;
+            updateColumnSet = null;
+        } else if (right.updateColumnSet != null) {
+            if (isFullUpdate) {
+                isFullUpdate    = false;
+                updateColumnSet = ((Table) object).getColumnNameSet();
+            }
+
+            updateColumnSet.removeAll(right.updateColumnSet);
+
+            if (updateColumnSet.isEmpty()) {
+                updateColumnSet = null;
+            }
+        }
+
+        if (!isFullReferences && referencesColumnSet == null) {}
+        else if (right.isFullReferences) {
+            isFullReferences    = false;
+            referencesColumnSet = null;
+        } else if (right.referencesColumnSet != null) {
+            if (isFullReferences) {
+                isFullReferences    = false;
+                referencesColumnSet = ((Table) object).getColumnNameSet();
+            }
+
+            referencesColumnSet.removeAll(right.referencesColumnSet);
+
+            if (referencesColumnSet.isEmpty()) {
+                referencesColumnSet = null;
+            }
+        }
+
+        if (!isFullTrigger && triggerColumnSet == null) {}
+        else if (right.isFullTrigger) {
+            isFullTrigger    = false;
+            triggerColumnSet = null;
+        } else if (right.triggerColumnSet != null) {
+            if (isFullTrigger) {
+                isFullTrigger    = false;
+                triggerColumnSet = ((Table) object).getColumnNameSet();
+            }
+
+            triggerColumnSet.removeAll(right.triggerColumnSet);
+
+            if (triggerColumnSet.isEmpty()) {
+                triggerColumnSet = null;
+            }
+        }
+    }
+
+    void clear() {
+
+        isFull = isFullSelect = isFullInsert = isFullUpdate =
+            isFullReferences = isFullDelete = false;
+        selectColumnSet = insertColumnSet = updateColumnSet =
+            referencesColumnSet = triggerColumnSet = null;
+    }
+
+    /**
+     * supports column level GRANT / REVOKE
+     */
+    public boolean isEmpty() {
+
+        if (isFull || isFullSelect || isFullInsert || isFullUpdate
+                || isFullReferences || isFullDelete) {
+            return false;
+        }
+
+        if (selectColumnSet != null && !selectColumnSet.isEmpty()) {
+            return false;
+        }
+
+        if (insertColumnSet != null && !insertColumnSet.isEmpty()) {
+            return false;
+        }
+
+        if (updateColumnSet != null && !updateColumnSet.isEmpty()) {
+            return false;
+        }
+
+        if (referencesColumnSet != null && !referencesColumnSet.isEmpty()) {
+            return false;
+        }
+
+        if (triggerColumnSet != null && !triggerColumnSet.isEmpty()) {
+            return false;
+        }
+
+        return true;
+    }
+
+    OrderedHashSet getColumnsForAllRights(Table table) {
+
+        if (isFull) {
+            return table.getColumnNameSet();
+        }
+
+        if (isFullSelect || isFullInsert || isFullUpdate || isFullReferences) {
+            return table.getColumnNameSet();
+        }
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        if (selectColumnSet != null) {
+            set.addAll(selectColumnSet);
+        }
+
+        if (insertColumnSet != null) {
+            set.addAll(insertColumnSet);
+        }
+
+        if (updateColumnSet != null) {
+            set.addAll(updateColumnSet);
+        }
+
+        if (referencesColumnSet != null) {
+            set.addAll(referencesColumnSet);
+        }
+
+        return set;
+    }
+
+    // construction
+    public boolean contains(Right right) {
+
+        if (isFull) {
+            return true;
+        }
+
+        if (right.isFull) {
+            return false;
+        }
+
+        if (!containsRights(isFullSelect, selectColumnSet,
+                            right.selectColumnSet, right.isFullSelect)) {
+            return false;
+        }
+
+        if (!containsRights(isFullInsert, insertColumnSet,
+                            right.insertColumnSet, right.isFullInsert)) {
+            return false;
+        }
+
+        if (!containsRights(isFullUpdate, updateColumnSet,
+                            right.updateColumnSet, right.isFullUpdate)) {
+            return false;
+        }
+
+        if (!containsRights(isFullReferences, referencesColumnSet,
+                            right.referencesColumnSet,
+                            right.isFullReferences)) {
+            return false;
+        }
+
+        if (!containsRights(isFullTrigger, triggerColumnSet,
+                            right.triggerColumnSet, right.isFullTrigger)) {
+            return false;
+        }
+
+        if (!isFullDelete && right.isFullDelete) {
+            return false;
+        }
+
+        return true;
+    }
+
+    void removeDroppedColumns(OrderedHashSet columnSet, Table table) {
+
+        for (int i = 0; i < columnSet.size(); i++) {
+            HsqlName name = (HsqlName) columnSet.get(i);
+
+            if (table.findColumn(name.name) >= 0) {
+                columnSet.remove(i);
+
+                i--;
+            }
+        }
+    }
+
+    public OrderedHashSet getColumnsForPrivilege(Table table, int type) {
+
+        if (isFull) {
+            return table.getColumnNameSet();
+        }
+
+        switch (type) {
+
+            case GrantConstants.SELECT :
+                return isFullSelect ? table.getColumnNameSet()
+                                    : selectColumnSet == null ? emptySet
+                                                              : selectColumnSet;
+
+            case GrantConstants.INSERT :
+                return isFullInsert ? table.getColumnNameSet()
+                                    : insertColumnSet == null ? emptySet
+                                                              : insertColumnSet;
+
+            case GrantConstants.UPDATE :
+                return isFullUpdate ? table.getColumnNameSet()
+                                    : updateColumnSet == null ? emptySet
+                                                              : updateColumnSet;
+
+            case GrantConstants.REFERENCES :
+                return isFullReferences ? table.getColumnNameSet()
+                                        : referencesColumnSet == null
+                                          ? emptySet
+                                          : referencesColumnSet;
+
+            case GrantConstants.TRIGGER :
+                return isFullTrigger ? table.getColumnNameSet()
+                                     : triggerColumnSet == null ? emptySet
+                                                                : triggerColumnSet;
+        }
+
+        return emptySet;
+    }
+
+    /**
+     * Supports column level checks
+     */
+    static boolean containsAllColumns(OrderedHashSet columnSet, Table table,
+                                      boolean[] columnCheckList) {
+
+        for (int i = 0; i < columnCheckList.length; i++) {
+            if (columnCheckList[i]) {
+                if (columnSet == null) {
+                    return false;
+                }
+
+                if (columnSet.contains(table.getColumn(i).getName())) {
+                    continue;
+                }
+
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    static boolean containsRights(boolean isFull, OrderedHashSet columnSet,
+                                  OrderedHashSet otherColumnSet,
+                                  boolean otherIsFull) {
+
+        if (isFull) {
+            return true;
+        }
+
+        if (otherIsFull) {
+            return false;
+        }
+
+        if (otherColumnSet != null
+                && (columnSet == null
+                    || !columnSet.containsAll(otherColumnSet))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Supports column level rights
+     */
+    boolean canSelect(Table table, boolean[] columnCheckList) {
+
+        if (isFull || isFullSelect) {
+            return true;
+        }
+
+        return containsAllColumns(selectColumnSet, table, columnCheckList);
+    }
+
+    /**
+     * Supports column level rights
+     */
+    boolean canInsert(Table table, boolean[] columnCheckList) {
+
+        if (isFull || isFullInsert) {
+            return true;
+        }
+
+        return containsAllColumns(insertColumnSet, table, columnCheckList);
+    }
+
+    /**
+     * Supports column level rights
+     */
+    boolean canUpdate(Table table, boolean[] columnCheckList) {
+
+        if (isFull || isFullUpdate) {
+            return true;
+        }
+
+        return containsAllColumns(updateColumnSet, table, columnCheckList);
+    }
+
+    /**
+     * Supports column level rights
+     */
+    boolean canReference(Table table, boolean[] columnCheckList) {
+
+        if (isFull || isFullReferences) {
+            return true;
+        }
+
+        return containsAllColumns(referencesColumnSet, table, columnCheckList);
+    }
+
+    /**
+     * Supports column level rights
+     */
+    boolean canTrigger(Table table, boolean[] columnCheckList) {
+
+        if (isFull || isFullTrigger) {
+            return true;
+        }
+
+        return containsAllColumns(triggerColumnSet, table, columnCheckList);
+    }
+
+    boolean canDelete() {
+        return isFull || isFullDelete;
+    }
+
+    public boolean canAccessFully(int privilegeType) {
+
+        if (isFull) {
+            return true;
+        }
+
+        switch (privilegeType) {
+
+            case GrantConstants.DELETE :
+                return isFullDelete;
+
+            case GrantConstants.SELECT :
+                return isFullSelect;
+
+            case GrantConstants.INSERT :
+                return isFullInsert;
+
+            case GrantConstants.UPDATE :
+                return isFullUpdate;
+
+            case GrantConstants.REFERENCES :
+                return isFullReferences;
+
+            case GrantConstants.TRIGGER :
+                return isFullTrigger;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Right");
+        }
+    }
+
+    /**
+     * Supports column level rights
+     */
+    public boolean canAccess(int privilegeType) {
+
+        if (isFull) {
+            return true;
+        }
+
+        switch (privilegeType) {
+
+            case GrantConstants.DELETE :
+                return isFullDelete;
+
+            case GrantConstants.SELECT :
+                if (isFullSelect) {
+                    return true;
+                }
+
+                return selectColumnSet != null && !selectColumnSet.isEmpty();
+
+            case GrantConstants.INSERT :
+                if (isFullInsert) {
+                    return true;
+                }
+
+                return insertColumnSet != null && !insertColumnSet.isEmpty();
+
+            case GrantConstants.UPDATE :
+                if (isFullUpdate) {
+                    return true;
+                }
+
+                return updateColumnSet != null && !updateColumnSet.isEmpty();
+
+            case GrantConstants.REFERENCES :
+                if (isFullReferences) {
+                    return true;
+                }
+
+                return referencesColumnSet != null
+                       && !referencesColumnSet.isEmpty();
+
+            case GrantConstants.TRIGGER :
+                if (isFullTrigger) {
+                    return true;
+                }
+
+                return triggerColumnSet != null && !triggerColumnSet.isEmpty();
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Right");
+        }
+    }
+
+    /**
+     * supports column level GRANT
+     */
+    String getTableRightsSQL(Table table) {
+
+        StringBuffer sb = new StringBuffer();
+
+        if (isFull) {
+            return Tokens.T_ALL;
+        }
+
+        if (isFullSelect) {
+            sb.append(Tokens.T_SELECT);
+            sb.append(',');
+        } else if (selectColumnSet != null) {
+            sb.append(Tokens.T_SELECT);
+            getColumnList(table, selectColumnSet, sb);
+            sb.append(',');
+        }
+
+        if (isFullInsert) {
+            sb.append(Tokens.T_INSERT);
+            sb.append(',');
+        } else if (insertColumnSet != null) {
+            sb.append(Tokens.T_INSERT);
+            getColumnList(table, insertColumnSet, sb);
+            sb.append(',');
+        }
+
+        if (isFullUpdate) {
+            sb.append(Tokens.T_UPDATE);
+            sb.append(',');
+        } else if (updateColumnSet != null) {
+            sb.append(Tokens.T_UPDATE);
+            getColumnList(table, updateColumnSet, sb);
+            sb.append(',');
+        }
+
+        if (isFullDelete) {
+            sb.append(Tokens.T_DELETE);
+            sb.append(',');
+        }
+
+        if (isFullReferences) {
+            sb.append(Tokens.T_REFERENCES);
+            sb.append(',');
+        } else if (referencesColumnSet != null) {
+            sb.append(Tokens.T_REFERENCES);
+            sb.append(',');
+        }
+
+        if (isFullTrigger) {
+            sb.append(Tokens.T_TRIGGER);
+            sb.append(',');
+        } else if (triggerColumnSet != null) {
+            sb.append(Tokens.T_TRIGGER);
+            sb.append(',');
+        }
+
+        return sb.toString().substring(0, sb.length() - 1);
+    }
+
+    private static void getColumnList(Table t, OrderedHashSet set,
+                                      StringBuffer buf) {
+
+        int       count        = 0;
+        boolean[] colCheckList = t.getNewColumnCheckList();
+
+        for (int i = 0; i < set.size(); i++) {
+            HsqlName name     = (HsqlName) set.get(i);
+            int      colIndex = t.findColumn(name.name);
+
+            if (colIndex == -1) {
+                continue;
+            }
+
+            colCheckList[colIndex] = true;
+
+            count++;
+        }
+
+        if (count == 0) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Right");
+        }
+
+        buf.append('(');
+
+        for (int i = 0, colCount = 0; i < colCheckList.length; i++) {
+            if (colCheckList[i]) {
+                colCount++;
+
+                buf.append(t.getColumn(i).getName().statementName);
+
+                if (colCount < count) {
+                    buf.append(',');
+                }
+            }
+        }
+
+        buf.append(')');
+    }
+
+    public void setColumns(Table table) {
+
+        if (selectColumnSet != null) {
+            setColumns(table, selectColumnSet);
+        }
+
+        if (insertColumnSet != null) {
+            setColumns(table, insertColumnSet);
+        }
+
+        if (updateColumnSet != null) {
+            setColumns(table, updateColumnSet);
+        }
+
+        if (referencesColumnSet != null) {
+            setColumns(table, referencesColumnSet);
+        }
+
+        if (triggerColumnSet != null) {
+            setColumns(table, triggerColumnSet);
+        }
+    }
+
+    private static void setColumns(Table t, OrderedHashSet set) {
+
+        int       count        = 0;
+        boolean[] colCheckList = t.getNewColumnCheckList();
+
+        for (int i = 0; i < set.size(); i++) {
+            String name     = (String) set.get(i);
+            int    colIndex = t.findColumn(name);
+
+            if (colIndex == -1) {
+                throw Error.error(ErrorCode.X_42501, name);
+            }
+
+            colCheckList[colIndex] = true;
+
+            count++;
+        }
+
+        if (count == 0) {
+            throw Error.error(ErrorCode.X_42501);
+        }
+
+        set.clear();
+
+        for (int i = 0; i < colCheckList.length; i++) {
+            if (colCheckList[i]) {
+                set.add(t.getColumn(i).getName());
+            }
+        }
+    }
+
+    public void set(int type, OrderedHashSet set) {
+
+        switch (type) {
+
+            case GrantConstants.SELECT :
+                if (set == null) {
+                    isFullSelect = true;
+                }
+
+                selectColumnSet = set;
+                break;
+
+            case GrantConstants.DELETE :
+                if (set == null) {
+                    isFullDelete = true;
+                }
+                break;
+
+            case GrantConstants.INSERT :
+                if (set == null) {
+                    isFullInsert = true;
+                }
+
+                insertColumnSet = set;
+                break;
+
+            case GrantConstants.UPDATE :
+                if (set == null) {
+                    isFullUpdate = true;
+                }
+
+                updateColumnSet = set;
+                break;
+
+            case GrantConstants.REFERENCES :
+                if (set == null) {
+                    isFullReferences = true;
+                }
+
+                referencesColumnSet = set;
+                break;
+
+            case GrantConstants.TRIGGER :
+                if (set == null) {
+                    isFullTrigger = true;
+                }
+
+                triggerColumnSet = set;
+                break;
+        }
+    }
+
+    /**
+     * Used solely by org.hsqldb.dbinfo in existing system tables lacking column
+     * level reporting.<p>
+     *
+     * Returns names of individual rights instead of ALL
+     */
+    String[] getTableRightsArray() {
+
+        if (isFull) {
+            return new String[] {
+                Tokens.T_SELECT, Tokens.T_INSERT, Tokens.T_UPDATE,
+                Tokens.T_DELETE, Tokens.T_REFERENCES
+            };
+        }
+
+        HsqlArrayList list  = new HsqlArrayList();
+        String[]      array = new String[list.size()];
+
+        if (isFullSelect) {
+            list.add(Tokens.T_SELECT);
+        }
+
+        if (isFullInsert) {
+            list.add(Tokens.T_INSERT);
+        }
+
+        if (isFullUpdate) {
+            list.add(Tokens.T_UPDATE);
+        }
+
+        if (isFullDelete) {
+            list.add(Tokens.T_DELETE);
+        }
+
+        if (isFullReferences) {
+            list.add(Tokens.T_REFERENCES);
+        }
+
+        if (isFullTrigger) {
+            list.add(Tokens.T_TRIGGER);
+        }
+
+        list.toArray(array);
+
+        return array;
+    }
+}
diff --git a/src/org/hsqldb/rights/User.java b/src/org/hsqldb/rights/User.java
new file mode 100644
index 0000000..22d7c59
--- /dev/null
+++ b/src/org/hsqldb/rights/User.java
@@ -0,0 +1,214 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rights;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+
+/**
+ * A User Object extends Grantee with password for a
+ * particular database user.<p>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ *
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+public class User extends Grantee {
+
+    /** password. */
+    private String password;
+
+    /** default schema when new Sessions started (defaults to PUBLIC schema) */
+    private HsqlName initialSchema = null;
+
+    /**
+     * Constructor
+     */
+    User(HsqlName name, GranteeManager manager) {
+
+        super(name, manager);
+
+        if (manager != null) {
+            updateAllRights();
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_CREATE).append(' ').append(Tokens.T_USER);
+        sb.append(' ').append(granteeName.statementName).append(' ');
+        sb.append(Tokens.T_PASSWORD).append(' ');
+        sb.append('\'').append(password).append('\'');
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    public void setPassword(String password) {
+
+        /** @todo - introduce complexity interface */
+
+        // checkComplexity(password);
+        // requires: UserManager.createSAUser(), UserManager.createPublicUser()
+        this.password = password;
+    }
+
+    /**
+     * Checks if this object's password attibute equals
+     * specified argument, else throws.
+     */
+    public void checkPassword(String value) {
+
+        if (!value.equals(password)) {
+            throw Error.error(ErrorCode.X_28000);
+        }
+    }
+
+    /**
+     * Returns the initial schema for the user
+     */
+    public HsqlName getInitialSchema() {
+        return initialSchema;
+    }
+
+    public HsqlName getInitialOrDefaultSchema() {
+
+        if (initialSchema != null) {
+            return initialSchema;
+        }
+
+        HsqlName schema =
+            granteeManager.database.schemaManager.findSchemaHsqlName(
+                getNameString());
+
+        if (schema == null) {
+            return granteeManager.database.schemaManager
+                .getDefaultSchemaHsqlName();
+        } else {
+            return schema;
+        }
+    }
+
+    /**
+     * This class does not have access to the SchemaManager, therefore
+     * caller should verify that the given schemaName exists.
+     *
+     * @param schema An existing schema.  Null value allowed,
+     *                   which means use the DB default session schema.
+     */
+    public void setInitialSchema(HsqlName schema) {
+        initialSchema = schema;
+    }
+
+    /**
+     * Returns the ALTER USER DDL character sequence that preserves the
+     * this user's current password value and mode. <p>
+     *
+     * @return  the DDL
+     */
+    public String getAlterUserSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_ALTER).append(' ');
+        sb.append(Tokens.T_USER).append(' ');
+        sb.append(getStatementName()).append(' ');
+        sb.append(Tokens.T_SET).append(' ');
+        sb.append(Tokens.T_PASSWORD).append(' ');
+        sb.append('"').append(password).append('"');
+
+        return sb.toString();
+    }
+
+    public String getInitialSchemaSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_ALTER).append(' ');
+        sb.append(Tokens.T_USER).append(' ');
+        sb.append(getStatementName()).append(' ');
+        sb.append(Tokens.T_SET).append(' ');
+        sb.append(Tokens.T_INITIAL).append(' ');
+        sb.append(Tokens.T_SCHEMA).append(' ');
+        sb.append(initialSchema.statementName);
+
+        return sb.toString();
+    }
+
+    /**
+     * Returns the DDL string
+     * sequence that creates this user.
+     *
+     */
+    public String getCreateUserSQL() {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        sb.append(Tokens.T_CREATE).append(' ');
+        sb.append(Tokens.T_USER).append(' ');
+        sb.append(getStatementName()).append(' ');
+        sb.append(Tokens.T_PASSWORD).append(' ');
+        sb.append(StringConverter.toQuotedString(password, '"', true));
+
+        return sb.toString();
+    }
+
+    /**
+     * Retrieves the redo log character sequence for connecting
+     * this user
+     *
+     * @return the redo log character sequence for connecting
+     *      this user
+     */
+    public String getConnectUserSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_SET).append(' ');
+        sb.append(Tokens.T_SESSION).append(' ');
+        sb.append(Tokens.T_AUTHORIZATION).append(' ');
+        sb.append(StringConverter.toQuotedString(getNameString(), '\'', true));
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/rights/UserManager.java b/src/org/hsqldb/rights/UserManager.java
new file mode 100644
index 0000000..5021076
--- /dev/null
+++ b/src/org/hsqldb/rights/UserManager.java
@@ -0,0 +1,332 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rights;
+
+import org.hsqldb.Database;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.Session;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.SqlInvariants;
+
+/**
+ * Manages the User objects for a Database instance.
+ * The special users PUBLIC_USER_NAME and SYSTEM_AUTHORIZATION_NAME
+ * are created and managed here.  SYSTEM_AUTHORIZATION_NAME is also
+ * special in that the name is not kept in the user "list"
+ * (PUBLIC_USER_NAME is kept in the list because it's needed by MetaData
+ * routines via "listVisibleUsers(x, true)").
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ *
+ * @version 1.8.0
+ * @since 1.7.2
+ * @see  User
+ */
+public final class UserManager {
+
+    /**
+     * This object's set of User objects. <p>
+     *
+     * Note: The special _SYSTEM  role
+     * is not included in this list but the special PUBLIC
+     * User object is kept in the list because it's needed by MetaData
+     * routines via "listVisibleUsers(x, true)".
+     */
+    private HashMappedList userList;
+    private GranteeManager granteeManager;
+
+    /**
+     * Construction happens once for each Database instance.
+     *
+     * Creates special users PUBLIC_USER_NAME and SYSTEM_AUTHORIZATION_NAME.
+     * Sets up association with the GranteeManager for this database.
+     */
+    public UserManager(Database database) {
+        granteeManager = database.getGranteeManager();
+        userList       = new HashMappedList();
+    }
+
+    /**
+     * Creates a new User object under management of this object. <p>
+     *
+     *  A set of constraints regarding user creation is imposed: <p>
+     *
+     *  <OL>
+     *    <LI>If the specified name is null, then an
+     *        ASSERTION_FAILED exception is thrown stating that
+     *        the name is null.
+     *
+     *    <LI>If this object's collection already contains an element whose
+     *        name attribute equals the name argument, then
+     *        a GRANTEE_ALREADY_EXISTS exception is thrown.
+     *        (This will catch attempts to create Reserved grantee names).
+     *  </OL>
+     */
+    public User createUser(HsqlName name, String password) {
+
+        // This will throw an appropriate exception if grantee already exists,
+        // regardless of whether the name is in any User, Role, etc. list.
+        User user = granteeManager.addUser(name);
+
+        user.setPassword(password);
+
+        boolean success = userList.add(name.name, user);
+
+        if (!success) {
+            throw Error.error(ErrorCode.X_28503, name.statementName);
+        }
+
+        return user;
+    }
+
+    /**
+     * Attempts to drop a User object with the specified name
+     *  from this object's set. <p>
+     *
+     *  A successful drop action consists of: <p>
+     *
+     *  <UL>
+     *
+     *    <LI>removing the User object with the specified name
+     *        from the set.
+     *
+     *    <LI>revoking all rights from the removed User<br>
+     *        (this ensures that in case there are still references to the
+     *        just dropped User object, those references
+     *        cannot be used to erronously access database objects).
+     *
+     *  </UL> <p>
+     *
+     */
+    public void dropUser(String name) {
+
+        boolean reservedUser = GranteeManager.isReserved(name);
+
+        if (reservedUser) {
+            throw Error.error(ErrorCode.X_28502, name);
+        }
+
+        boolean result = granteeManager.removeGrantee(name);
+
+        if (!result) {
+            throw Error.error(ErrorCode.X_28501, name);
+        }
+
+        User user = (User) userList.remove(name);
+
+        if (user == null) {
+            throw Error.error(ErrorCode.X_28501, name);
+        }
+    }
+
+    public void createFirstUser(String username, String password) {
+
+        boolean isQuoted = true;
+        if (username.equalsIgnoreCase("SA")) {
+            username = "SA";
+            isQuoted = false;
+        }
+
+        HsqlName name =
+            granteeManager.database.nameManager.newHsqlName(username, isQuoted,
+                SchemaObject.GRANTEE);
+
+        createUser(name, password);
+        granteeManager.grant(name.name, SqlInvariants.DBA_ADMIN_ROLE_NAME,
+                             granteeManager.getDBARole());
+    }
+
+    /**
+     * Returns the User object with the specified name and
+     * password from this object's set.
+     */
+    public User getUser(String name, String password) {
+
+        if (name == null) {
+            name = "";
+        }
+
+        if (password == null) {
+            password = "";
+        }
+
+        User user = get(name);
+
+        user.checkPassword(password);
+
+        return user;
+    }
+
+    /**
+     * Retrieves this object's set of User objects as
+     *  an associative list.
+     */
+    public HashMappedList getUsers() {
+        return userList;
+    }
+
+    public boolean exists(String name) {
+        return userList.get(name) == null ? false
+                                          : true;
+    }
+
+    /**
+     * Returns the User object identified by the
+     * name argument.
+     */
+    public User get(String name) {
+
+        User user = (User) userList.get(name);
+
+        if (user == null) {
+            throw Error.error(ErrorCode.X_28501, name);
+        }
+
+        return user;
+    }
+
+    /**
+     * Retrieves the <code>User</code> objects representing the database
+     * users that are visible to the <code>User</code> object
+     * represented by the <code>session</code> argument. <p>
+     *
+     * If the <code>session</code> argument's <code>User</code> object
+     * attribute has isAdmin() true (directly or by virtue of a Role),
+     * then all of the
+     * <code>User</code> objects in this collection are considered visible.
+     * Otherwise, only this object's special <code>PUBLIC</code>
+     * <code>User</code> object attribute and the session <code>User</code>
+     * object, if it exists in this collection, are considered visible. <p>
+     *
+     * @param session The <code>Session</code> object used to determine
+     *          visibility
+     * @return a list of <code>User</code> objects visible to
+     *          the <code>User</code> object contained by the
+     *         <code>session</code> argument.
+     *
+     */
+    public HsqlArrayList listVisibleUsers(Session session) {
+
+        HsqlArrayList list;
+        User          user;
+        boolean       isAdmin;
+        String        sessionName;
+        String        userName;
+
+        list        = new HsqlArrayList();
+        isAdmin     = session.isAdmin();
+        sessionName = session.getUsername();
+
+        if (userList == null || userList.size() == 0) {
+            return list;
+        }
+
+        for (int i = 0; i < userList.size(); i++) {
+            user = (User) userList.get(i);
+
+            if (user == null) {
+                continue;
+            }
+
+            userName = user.getNameString();
+
+            if (isAdmin) {
+                list.add(user);
+            } else if (sessionName.equals(userName)) {
+                list.add(user);
+            }
+        }
+
+        return list;
+    }
+
+    /**
+     * Returns the specially constructed
+     * <code>SYSTEM_AUTHORIZATION_NAME</code>
+     * <code>User</code> object for the current <code>Database</code> object.
+     *
+     * @return the <code>SYS_AUTHORIZATION_NAME</code>
+     *          <code>User</code> object
+     *
+     */
+    public User getSysUser() {
+        return GranteeManager.systemAuthorisation;
+    }
+
+    public synchronized void removeSchemaReference(String schemaName) {
+
+        for (int i = 0; i < userList.size(); i++) {
+            User     user   = (User) userList.get(i);
+            HsqlName schema = user.getInitialSchema();
+
+            if (schema == null) {
+                continue;
+            }
+
+            if (schemaName.equals(schema.name)) {
+                user.setInitialSchema(null);
+            }
+        }
+    }
+
+    public String[] getInitialSchemaSQL() {
+
+        HsqlArrayList list = new HsqlArrayList(userList.size());
+
+        for (int i = 0; i < userList.size(); i++) {
+            User user = (User) userList.get(i);
+
+            if (user.isSystem) {
+                continue;
+            }
+
+            HsqlName name = user.getInitialSchema();
+
+            if (name == null) {
+                continue;
+            }
+
+            list.add(user.getInitialSchemaSQL());
+        }
+
+        String[] array = new String[list.size()];
+
+        list.toArray(array);
+
+        return array;
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowInputBase.java b/src/org/hsqldb/rowio/RowInputBase.java
new file mode 100644
index 0000000..b4126bc
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowInputBase.java
@@ -0,0 +1,317 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlByteArrayInputStream;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Base class for reading the data for a database row in different formats.
+ * Defines the methods that are independent of storage format and declares
+ * the format-dependent methods that subclasses should define.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.7.0
+ */
+abstract class RowInputBase extends HsqlByteArrayInputStream {
+
+    static final int NO_POS = -1;
+
+    // fredt - initialisation may be unnecessary as it's done in resetRow()
+    protected int filePos = NO_POS;
+    protected int size;
+
+    RowInputBase() {
+        this(new byte[4]);
+    }
+
+    /**
+     * Constructor takes a complete row
+     */
+    RowInputBase(byte[] buf) {
+
+        super(buf);
+
+        size = buf.length;
+    }
+
+    public int getPos() {
+
+        if (filePos == NO_POS) {
+
+//                Trace.printSystemOut(Trace.DatabaseRowInput_getPos);
+        }
+
+        return filePos;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+// fredt@users - comment - methods used for node and type data
+    public abstract int readType() throws IOException;
+
+    public abstract String readString() throws IOException;
+
+// fredt@users - comment - methods used for SQL types
+    protected abstract boolean readNull() throws IOException;
+
+    protected abstract String readChar(Type type) throws IOException;
+
+    protected abstract Integer readSmallint() throws IOException;
+
+    protected abstract Integer readInteger() throws IOException;
+
+    protected abstract Long readBigint() throws IOException;
+
+    protected abstract Double readReal() throws IOException;
+
+    protected abstract BigDecimal readDecimal(Type type) throws IOException;
+
+    protected abstract Boolean readBoole() throws IOException;
+
+    protected abstract TimeData readTime(Type type) throws IOException;
+
+    protected abstract TimestampData readDate(Type type) throws IOException;
+
+    protected abstract TimestampData readTimestamp(Type type)
+    throws IOException;
+
+    protected abstract IntervalMonthData readYearMonthInterval(Type type)
+    throws IOException;
+
+    protected abstract IntervalSecondData readDaySecondInterval(Type type)
+    throws IOException;
+
+    protected abstract Object readOther() throws IOException;
+
+    protected abstract BinaryData readBinary()
+    throws IOException, HsqlException;
+
+    protected abstract BinaryData readBit() throws IOException;
+
+    protected abstract ClobData readClob() throws IOException;
+
+    protected abstract BlobData readBlob() throws IOException;
+
+    protected abstract Object[] readArray(Type type) throws IOException;
+
+    /**
+     *  reads row data from a stream using the JDBC types in colTypes
+     *
+     * @param  colTypes
+     * @throws  IOException
+     */
+    public Object[] readData(Type[] colTypes) throws IOException {
+
+        int      l    = colTypes.length;
+        Object[] data = new Object[l];
+
+        for (int i = 0; i < l; i++) {
+            Type type = colTypes[i];
+
+            data[i] = readData(type);
+        }
+
+        return data;
+    }
+
+    public Object readData(Type type) throws IOException {
+
+        Object o = null;
+
+        if (readNull()) {
+            return null;
+        }
+
+        switch (type.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                break;
+
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                o = readChar(type);
+                break;
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+                o = readSmallint();
+                break;
+
+            case Types.SQL_INTEGER :
+                o = readInteger();
+                break;
+
+            case Types.SQL_BIGINT :
+                o = readBigint();
+                break;
+
+            //fredt although REAL is now Double, it is read / written in
+            //the old format for compatibility
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                o = readReal();
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                o = readDecimal(type);
+                break;
+
+            case Types.SQL_DATE :
+                o = readDate(type);
+                break;
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                o = readTime(type);
+                break;
+
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                o = readTimestamp(type);
+                break;
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                o = readYearMonthInterval(type);
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                o = readDaySecondInterval(type);
+                break;
+
+            case Types.SQL_BOOLEAN :
+                o = readBoole();
+                break;
+
+            case Types.OTHER :
+                o = readOther();
+                break;
+
+            case Types.SQL_CLOB :
+                o = readClob();
+                break;
+
+            case Types.SQL_BLOB :
+                o = readBlob();
+                break;
+
+            case Types.SQL_ARRAY :
+                o = readArray(type);
+                break;
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+                o = readBinary();
+                break;
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                o = readBit();
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "RowInputBase - "
+                                         + type.getNameString());
+        }
+
+        return o;
+    }
+
+    /**
+     *  Used to reset the row, ready for a new row to be written into the
+     *  byte[] buffer by an external routine.
+     *
+     */
+    public void resetRow(int filepos, int rowsize) throws IOException {
+
+        mark = 0;
+
+        reset();
+
+        if (buffer.length < rowsize) {
+            buffer = new byte[rowsize];
+        }
+
+        filePos   = filepos;
+        size      = count = rowsize;
+        pos       = 4;
+        buffer[0] = (byte) ((rowsize >>> 24) & 0xFF);
+        buffer[1] = (byte) ((rowsize >>> 16) & 0xFF);
+        buffer[2] = (byte) ((rowsize >>> 8) & 0xFF);
+        buffer[3] = (byte) ((rowsize >>> 0) & 0xFF);
+    }
+
+    public byte[] getBuffer() {
+        return buffer;
+    }
+
+    public int skipBytes(int n) throws IOException {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowInputBase");
+    }
+
+    public String readLine() throws IOException {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowInputBase");
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowInputBinary.java b/src/org/hsqldb/rowio/RowInputBinary.java
new file mode 100644
index 0000000..bbf7a8d
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowInputBinary.java
@@ -0,0 +1,294 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ *  Provides methods for reading the data for a row from a
+ *  byte array. The format of data is that used for storage of cached
+ *  tables by v.1.6.x databases, apart from strings.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class RowInputBinary extends RowInputBase
+implements org.hsqldb.rowio.RowInputInterface {
+
+    private RowOutputBinary out;
+
+    public RowInputBinary(byte[] buf) {
+        super(buf);
+    }
+
+    /**
+     * uses the byte[] buffer from out. At each reset, the buffer is set
+     * to the current one for out.
+     */
+    public RowInputBinary(RowOutputBinary out) {
+
+        super(out.getBuffer());
+
+        this.out = out;
+    }
+
+    public int readType() throws IOException {
+        return readShort();
+    }
+
+    public String readString() throws IOException {
+
+        int    length = readInt();
+        String s      = StringConverter.readUTF(buffer, pos, length);
+
+        s   = ValuePool.getString(s);
+        pos += length;
+
+        return s;
+    }
+
+    protected boolean readNull() throws IOException {
+
+        int b = readByte();
+
+        return b == 0 ? true
+                      : false;
+    }
+
+    protected String readChar(Type type) throws IOException {
+        return readString();
+    }
+
+    protected Integer readSmallint() throws IOException {
+        return ValuePool.getInt(readShort());
+    }
+
+    protected Integer readInteger() throws IOException {
+        return ValuePool.getInt(readInt());
+    }
+
+    protected Long readBigint() throws IOException {
+        return ValuePool.getLong(readLong());
+    }
+
+    protected Double readReal() throws IOException {
+        return ValuePool.getDouble(readLong());
+    }
+
+    protected BigDecimal readDecimal(Type type) throws IOException {
+
+        byte[]     bytes  = readByteArray();
+        int        scale  = readInt();
+        BigInteger bigint = new BigInteger(bytes);
+
+        return ValuePool.getBigDecimal(new BigDecimal(bigint, scale));
+    }
+
+    protected Boolean readBoole() throws IOException {
+        return readBoolean() ? Boolean.TRUE
+                             : Boolean.FALSE;
+    }
+
+    protected TimeData readTime(Type type) throws IOException {
+
+        if (type.typeCode == Types.SQL_TIME) {
+            return new TimeData(readInt(), readInt(), 0);
+        } else {
+            return new TimeData(readInt(), readInt(), readInt());
+        }
+    }
+
+    protected TimestampData readDate(Type type) throws IOException {
+
+        long date = readLong();
+
+        return new TimestampData(date);
+    }
+
+    protected TimestampData readTimestamp(Type type) throws IOException {
+
+        if (type.typeCode == Types.SQL_TIMESTAMP) {
+            return new TimestampData(readLong(), readInt());
+        } else {
+            return new TimestampData(readLong(), readInt(), readInt());
+        }
+    }
+
+    protected IntervalMonthData readYearMonthInterval(Type type)
+    throws IOException {
+
+        long months = readLong();
+
+        return new IntervalMonthData(months, (IntervalType) type);
+    }
+
+    protected IntervalSecondData readDaySecondInterval(Type type)
+    throws IOException {
+
+        long seconds = readLong();
+        int  nanos   = readInt();
+
+        return new IntervalSecondData(seconds, nanos, (IntervalType) type);
+    }
+
+    protected Object readOther() throws IOException {
+        return new JavaObjectData(readByteArray());
+    }
+
+    protected BinaryData readBit() throws IOException {
+
+        int    length = readInt();
+        byte[] b      = new byte[(length + 7) / 8];
+
+        readFully(b);
+
+        return BinaryData.getBitData(b, length);
+    }
+
+    protected BinaryData readBinary() throws IOException {
+        return new BinaryData(readByteArray(), false);
+    }
+
+    protected ClobData readClob() throws IOException {
+
+        long id = super.readLong();
+
+        return new ClobDataID(id);
+    }
+
+    protected BlobData readBlob() throws IOException {
+
+        long id = super.readLong();
+
+        return new BlobDataID(id);
+    }
+
+    protected Object[] readArray(Type type) throws IOException {
+        type = type.collectionBaseType();
+        int size = readInt();
+
+        Object[] data = new Object[size];
+
+        for (int i = 0; i < size; i++) {
+            data[i] = readData(type);
+        }
+
+        return data;
+    }
+
+    public Object[] readData(Type[] colTypes) throws IOException {
+        return super.readData(colTypes);
+    }
+
+    // helper methods
+    public byte[] readByteArray() throws IOException {
+
+        byte[] b = new byte[readInt()];
+
+        readFully(b);
+
+        return b;
+    }
+
+    public char[] readCharArray() throws IOException {
+
+        char[] c = new char[readInt()];
+
+        if (count - pos < c.length) {
+            pos = count;
+
+            throw new EOFException();
+        }
+
+        for (int i = 0; i < c.length; i++) {
+            int ch1 = buffer[pos++] & 0xff;
+            int ch2 = buffer[pos++] & 0xff;
+
+            c[i] = (char) ((ch1 << 8) + (ch2));
+        }
+
+        return c;
+    }
+
+    /**
+     *  Used to reset the row, ready for Result data to be written into the
+     *  byte[] buffer by an external routine.
+     *
+     */
+    public void resetRow(int rowsize) {
+
+        if (out != null) {
+            out.reset(rowsize);
+
+            buffer = out.getBuffer();
+        }
+
+        super.reset();
+    }
+
+    /**
+     *  Used to reset the row, ready for a new db row to be written into the
+     *  byte[] buffer by an external routine.
+     *
+     */
+    public void resetRow(int filepos, int rowsize) throws IOException {
+
+        if (out != null) {
+            out.reset(rowsize);
+
+            buffer = out.getBuffer();
+        }
+
+        super.resetRow(filepos, rowsize);
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowInputBinary180.java b/src/org/hsqldb/rowio/RowInputBinary180.java
new file mode 100644
index 0000000..d531296
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowInputBinary180.java
@@ -0,0 +1,94 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.IOException;
+
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowInputBinary180 extends RowInputBinary {
+
+    public RowInputBinary180(byte[] buf) {
+        super(buf);
+    }
+
+    protected TimeData readTime(Type type) throws IOException {
+
+        if (type.typeCode == Types.SQL_TIME) {
+            long millis = readLong();
+
+            millis = HsqlDateTime.convertMillisFromCalendar(
+                HsqlDateTime.tempCalDefault, millis);
+            millis = HsqlDateTime.getNormalisedTime(millis);
+
+            return new TimeData((int) (millis / 1000), 0, 0);
+        } else {
+            return new TimeData(readInt(), readInt(), readInt());
+        }
+    }
+
+    protected TimestampData readDate(Type type) throws IOException {
+
+        long millis = readLong();
+
+        millis = HsqlDateTime.convertMillisFromCalendar(HsqlDateTime.tempCalDefault,
+                                               millis);
+
+        millis = HsqlDateTime.getNormalisedDate(millis);
+
+        return new TimestampData(millis / 1000);
+    }
+
+    protected TimestampData readTimestamp(Type type) throws IOException {
+
+        if (type.typeCode == Types.SQL_TIMESTAMP) {
+            long millis = readLong();
+            int  nanos  = readInt();
+
+            millis = HsqlDateTime.convertMillisFromCalendar(HsqlDateTime.tempCalDefault,
+                                                   millis);
+
+            return new TimestampData(millis / 1000, nanos);
+        } else {
+            return new TimestampData(readLong(), readInt(), readInt());
+        }
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowInputBinaryDecode.java b/src/org/hsqldb/rowio/RowInputBinaryDecode.java
new file mode 100644
index 0000000..9a05484
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowInputBinaryDecode.java
@@ -0,0 +1,68 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.IOException;
+
+import org.hsqldb.persist.Crypto;
+import org.hsqldb.types.Type;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowInputBinaryDecode extends RowInputBinary {
+
+    final Crypto crypto;
+
+    public RowInputBinaryDecode(Crypto crypto, byte[] buf) {
+
+        super(buf);
+
+        this.crypto = crypto;
+    }
+
+    public Object[] readData(Type[] colTypes) throws IOException {
+
+        if (crypto != null) {
+            int start = pos;
+            int size  = readInt();
+
+            crypto.decode(buffer, pos, size, buffer, start);
+
+            pos = start;
+        }
+
+        return super.readData(colTypes);
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowInputInterface.java b/src/org/hsqldb/rowio/RowInputInterface.java
new file mode 100644
index 0000000..b93d589
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowInputInterface.java
@@ -0,0 +1,67 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.IOException;
+
+import org.hsqldb.types.Type;
+
+/**
+ * Public interface for reading the data for a database row.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public interface RowInputInterface {
+
+    int getPos();
+
+    int getSize();
+
+    int readType() throws IOException;
+
+    String readString() throws IOException;
+
+    short readShort() throws IOException;
+
+    int readInt() throws IOException;
+
+    long readLong() throws IOException;
+
+    Object[] readData(Type[] colTypes) throws IOException;
+
+    void resetRow(int filePos, int size) throws IOException;
+
+    byte[] getBuffer();
+}
diff --git a/src/org/hsqldb/rowio/RowInputText.java b/src/org/hsqldb/rowio/RowInputText.java
new file mode 100644
index 0000000..c143c09
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowInputText.java
@@ -0,0 +1,550 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+import org.hsqldb.Scanner;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Class for reading the data for a database row in text table format.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class RowInputText extends RowInputBase implements RowInputInterface {
+
+    // text table specific
+    private String    fieldSep;
+    private String    varSep;
+    private String    longvarSep;
+    private int       fieldSepLen;
+    private int       varSepLen;
+    private int       longvarSepLen;
+    private boolean   fieldSepEnd;
+    private boolean   varSepEnd;
+    private boolean   longvarSepEnd;
+    private int       textLen;
+    protected String  text;
+    protected int     line;
+    protected int     field;
+    protected int     next = 0;
+    protected boolean allQuoted;
+    protected Scanner scanner;
+
+    /**
+     * fredt@users - comment - in future may use a custom subclasse of
+     * InputStream to read the data.
+     */
+    public RowInputText(String fieldSep, String varSep, String longvarSep,
+                        boolean allQuoted) {
+
+        super(new byte[0]);
+
+        scanner = new Scanner();
+
+        //-- Newline indicates that field should match to end of line.
+        if (fieldSep.endsWith("\n")) {
+            fieldSepEnd = true;
+            fieldSep    = fieldSep.substring(0, fieldSep.length() - 1);
+        }
+
+        if (varSep.endsWith("\n")) {
+            varSepEnd = true;
+            varSep    = varSep.substring(0, varSep.length() - 1);
+        }
+
+        if (longvarSep.endsWith("\n")) {
+            longvarSepEnd = true;
+            longvarSep    = longvarSep.substring(0, longvarSep.length() - 1);
+        }
+
+        this.allQuoted  = allQuoted;
+        this.fieldSep   = fieldSep;
+        this.varSep     = varSep;
+        this.longvarSep = longvarSep;
+        fieldSepLen     = fieldSep.length();
+        varSepLen       = varSep.length();
+        longvarSepLen   = longvarSep.length();
+    }
+
+    public void setSource(String text, int pos, int byteSize) {
+
+        size      = byteSize;
+        this.text = text;
+        textLen   = text.length();
+        filePos   = pos;
+        next      = 0;
+
+        line++;
+
+        field = 0;
+    }
+
+    protected String getField(String sep, int sepLen,
+                              boolean isEnd) throws IOException {
+
+        String s = null;
+
+        try {
+            int start = next;
+
+            field++;
+
+            if (isEnd) {
+                if ((next >= textLen) && (sepLen > 0)) {
+                    throw Error.error(ErrorCode.TEXT_SOURCE_NO_END_SEPARATOR);
+                } else if (text.endsWith(sep)) {
+                    next = textLen - sepLen;
+                } else {
+                    throw Error.error(ErrorCode.TEXT_SOURCE_NO_END_SEPARATOR);
+                }
+            } else {
+                next = text.indexOf(sep, start);
+
+                if (next == -1) {
+                    next = textLen;
+                }
+            }
+
+            if (start > next) {
+                start = next;
+            }
+
+            s    = text.substring(start, next);
+            next += sepLen;
+            s    = s.trim();
+
+            if (s.length() == 0) {
+                s = null;
+            }
+        } catch (Exception e) {
+            throw new IOException(
+                Error.getMessage(
+                    ErrorCode.M_TEXT_SOURCE_FIELD_ERROR, 0, new Object[] {
+                new Integer(field), e.toString()
+            }));
+        }
+
+        return s;
+    }
+
+    public String readString() throws IOException {
+        return getField(fieldSep, fieldSepLen, fieldSepEnd);
+    }
+
+    private String readVarString() throws IOException {
+        return getField(varSep, varSepLen, varSepEnd);
+    }
+
+    /**
+     * Obsoleted in 1.9.0
+     */
+    private String readLongVarString() throws IOException {
+        return getField(longvarSep, longvarSepLen, longvarSepEnd);
+    }
+
+    public short readShort() throws IOException {
+        return (short) readInt();
+    }
+
+    public int readInt() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return 0;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return 0;
+        }
+
+        return Integer.parseInt(s);
+    }
+
+    public long readLong() throws IOException {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowInputText");
+    }
+
+    public int readType() throws IOException {
+        return 0;
+    }
+
+    protected boolean readNull() {
+
+        // Return null on each column read instead.
+        return false;
+    }
+
+    protected String readChar(Type type) throws IOException {
+
+        String s = null;;
+
+        switch (type.typeCode) {
+
+            case Types.SQL_CHAR :
+                s = readString();
+                break;
+
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                s = readVarString();
+                break;
+
+            default :
+                s = readLongVarString();
+                break;
+        }
+
+        if (s == null) {
+            return null;
+        }
+
+        // cut down size
+        return new String(s);
+    }
+
+    protected Integer readSmallint() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return Integer.valueOf(s);
+    }
+
+    protected Integer readInteger() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return Integer.valueOf(s);
+    }
+
+    protected Long readBigint() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return Long.valueOf(s);
+    }
+
+    protected Double readReal() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return Double.valueOf(s);
+    }
+
+    protected BigDecimal readDecimal(Type type) throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return new BigDecimal(s);
+    }
+
+    protected TimeData readTime(Type type) throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return scanner.newTime(s);
+    }
+
+    protected TimestampData readDate(Type type) throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return scanner.newDate(s);
+    }
+
+    protected TimestampData readTimestamp(Type type) throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return scanner.newTimestamp(s);
+    }
+
+    protected IntervalMonthData readYearMonthInterval(Type type)
+    throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return (IntervalMonthData) scanner.newInterval(s, (IntervalType) type);
+    }
+
+    protected IntervalSecondData readDaySecondInterval(Type type)
+    throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return (IntervalSecondData) scanner.newInterval(s,
+                (IntervalType) type);
+    }
+
+    protected Boolean readBoole() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        return s.equalsIgnoreCase(Tokens.T_TRUE) ? Boolean.TRUE
+                                                 : Boolean.FALSE;
+    }
+
+    protected Object readOther() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        BinaryData data = scanner.convertToBinary(s);
+
+        if (data.length(null) == 0) {
+            return null;
+        }
+
+        return new JavaObjectData(data.getBytes());
+    }
+
+    protected BinaryData readBit() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        BinaryData data = scanner.convertToBit(s);
+
+        return data;
+    }
+
+    protected BinaryData readBinary() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        BinaryData data = scanner.convertToBinary(s);
+
+        return data;
+    }
+
+    protected ClobData readClob() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        long id = Long.parseLong(s);
+
+        return new ClobDataID(id);
+    }
+
+    protected BlobData readBlob() throws IOException {
+
+        String s = readString();
+
+        if (s == null) {
+            return null;
+        }
+
+        s = s.trim();
+
+        if (s.length() == 0) {
+            return null;
+        }
+
+        long id = Long.parseLong(s);
+
+        return new BlobDataID(id);
+    }
+
+    protected Object[] readArray(Type type) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowInputText");
+    }
+
+    public int getLineNumber() {
+        return line;
+    }
+
+    public void skippedLine() {
+        line++;
+    }
+
+    public void reset() {
+
+        text    = "";
+        textLen = 0;
+        filePos = 0;
+        next    = 0;
+        field   = 0;
+        line    = 0;
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowInputTextLog.java b/src/org/hsqldb/rowio/RowInputTextLog.java
new file mode 100644
index 0000000..e495cab
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowInputTextLog.java
@@ -0,0 +1,547 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Scanner;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.scriptio.ScriptReaderBase;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.BlobDataID;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.ClobDataID;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.IntervalType;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+
+/**
+ * Class for reading the data for a database row from the script file.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.7.3
+ */
+public class RowInputTextLog extends RowInputBase
+implements RowInputInterface {
+
+    Scanner scanner;
+    String  tableName  = null;
+    String  schemaName = null;
+    int     statementType;
+    Object  value;
+    boolean version18;
+    boolean noSeparators;
+
+    public RowInputTextLog() {
+
+        super(new byte[0]);
+
+        scanner = new Scanner();
+    }
+
+    public RowInputTextLog(boolean version18) {
+
+        super(new byte[0]);
+
+        scanner        = new Scanner();
+        this.version18 = version18;
+    }
+
+    public void setSource(String text) {
+
+        scanner.reset(text);
+
+        statementType = ScriptReaderBase.ANY_STATEMENT;
+
+        scanner.scanNext();
+
+        String s = scanner.getString();
+
+        if (s.equals(Tokens.T_INSERT)) {
+            statementType = ScriptReaderBase.INSERT_STATEMENT;
+
+            scanner.scanNext();
+            scanner.scanNext();
+
+            tableName = scanner.getString();
+
+            scanner.scanNext();
+        } else if (s.equals(Tokens.T_DELETE)) {
+            statementType = ScriptReaderBase.DELETE_STATEMENT;
+
+            scanner.scanNext();
+            scanner.scanNext();
+
+            tableName = scanner.getString();
+        } else if (s.equals(Tokens.T_COMMIT)) {
+            statementType = ScriptReaderBase.COMMIT_STATEMENT;
+        } else if (s.equals(Tokens.T_SET)) {
+            scanner.scanNext();
+
+            if (Tokens.T_SCHEMA.equals(scanner.getString())) {
+                scanner.scanNext();
+
+                schemaName    = scanner.getString();
+                statementType = ScriptReaderBase.SET_SCHEMA_STATEMENT;
+            }
+        }
+    }
+
+    public int getStatementType() {
+        return statementType;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+
+    protected void readField() {
+
+        readFieldPrefix();
+        scanner.scanNext();
+
+        value = scanner.getValue();
+    }
+
+    protected void readNumberField(Type type) {
+
+        readFieldPrefix();
+        scanner.scanNext();
+
+        boolean minus = scanner.getTokenType() == Tokens.MINUS;
+
+        if (minus) {
+            scanner.scanNext();
+        }
+
+        value = scanner.getValue();
+
+        if (minus) {
+            try {
+                value = ((NumberType) scanner.getDataType()).negate(value);
+            } catch (HsqlException e) {}
+        }
+    }
+
+    protected void readFieldPrefix() {
+
+        if (!noSeparators) {
+            scanner.scanNext();
+
+            if (statementType == ScriptReaderBase.DELETE_STATEMENT) {
+                scanner.scanNext();
+                scanner.scanNext();
+            }
+        }
+    }
+
+    public String readString() throws IOException {
+
+        readField();
+
+        return (String) value;
+    }
+
+    public short readShort() throws IOException {
+        throw Error.runtimeError(ErrorCode.U_S0500, "");
+    }
+
+    public int readInt() throws IOException {
+        throw Error.runtimeError(ErrorCode.U_S0500, "");
+    }
+
+    public long readLong() throws IOException {
+        throw Error.runtimeError(ErrorCode.U_S0500, "");
+    }
+
+    public int readType() throws IOException {
+        return 0;
+    }
+
+    protected boolean readNull() {
+
+        // Return null on each column read instead.
+        return false;
+    }
+
+    protected String readChar(Type type) throws IOException {
+
+        readField();
+
+        return (String) value;
+    }
+
+    protected Integer readSmallint() throws IOException {
+
+        readNumberField(Type.SQL_SMALLINT);
+
+        return (Integer) value;
+    }
+
+    protected Integer readInteger() throws IOException {
+
+        readNumberField(Type.SQL_INTEGER);
+
+        if (value instanceof Long) {
+            value = Type.SQL_INTEGER.convertToDefaultType(null, value);
+        }
+
+        return (Integer) value;
+    }
+
+    protected Long readBigint() throws IOException {
+
+        readNumberField(Type.SQL_BIGINT);
+
+        if (value == null) {
+            return null;
+        }
+
+        if (value instanceof BigDecimal) {
+            return (Long) Type.SQL_BIGINT.convertToDefaultType(null, value);
+        }
+
+        return ValuePool.getLong(((Number) value).longValue());
+    }
+
+    protected Double readReal() throws IOException {
+
+        readNumberField(Type.SQL_DOUBLE);
+
+        if (value == null) {
+            return null;
+        }
+
+        if (scanner.scanSpecialIdentifier(Tokens.T_DIVIDE)) {
+            scanner.scanNext();
+
+            Object divisor = scanner.getValue();
+            double i       = ((Number) divisor).doubleValue();
+
+            if (i == 0) {
+                if (((Number) value).doubleValue() == 1E0) {
+                    i = Double.NEGATIVE_INFINITY;
+                } else if (((Number) value).doubleValue() == -1E0) {
+                    i = Double.POSITIVE_INFINITY;
+                } else if (((Number) value).doubleValue() == 0E0) {
+                    i = Double.NaN;
+                } else {
+                    throw Error.error(ErrorCode.X_42584);
+                }
+            } else {
+                throw Error.error(ErrorCode.X_42584);
+            }
+
+            value = Double.valueOf(i);
+        }
+
+        return (Double) value;
+    }
+
+    protected BigDecimal readDecimal(Type type) throws IOException {
+
+        readNumberField(type);
+
+        if (value == null) {
+            return null;
+        }
+
+        BigDecimal bd = (BigDecimal) type.convertToDefaultType(null, value);
+
+        return (BigDecimal) type.convertToTypeLimits(null, bd);
+    }
+
+    protected TimeData readTime(Type type) throws IOException {
+
+        readField();
+
+        if (value == null) {
+            return null;
+        }
+
+        if (version18) {
+            java.sql.Time dateTime = java.sql.Time.valueOf((String) value);
+            long millis = HsqlDateTime.convertMillisFromCalendar(
+                HsqlDateTime.tempCalDefault, dateTime.getTime());
+
+            millis = HsqlDateTime.getNormalisedTime(millis);
+
+            return new TimeData((int) millis / 1000, 0, 0);
+        }
+
+        return scanner.newTime((String) value);
+    }
+
+    protected TimestampData readDate(Type type) throws IOException {
+
+        readField();
+
+        if (value == null) {
+            return null;
+        }
+
+        if (version18) {
+            java.sql.Date dateTime = java.sql.Date.valueOf((String) value);
+            long millis = HsqlDateTime.convertMillisFromCalendar(
+                HsqlDateTime.tempCalDefault, dateTime.getTime());
+
+            millis = HsqlDateTime.getNormalisedDate(millis);
+
+            return new TimestampData(millis / 1000);
+        }
+
+        return scanner.newDate((String) value);
+    }
+
+    protected TimestampData readTimestamp(Type type) throws IOException {
+
+        readField();
+
+        if (value == null) {
+            return null;
+        }
+
+        if (version18) {
+            java.sql.Timestamp dateTime =
+                java.sql.Timestamp.valueOf((String) value);
+            long millis = HsqlDateTime.convertMillisFromCalendar(
+                HsqlDateTime.tempCalDefault, dateTime.getTime());
+            int nanos = dateTime.getNanos();
+
+            nanos = ((DateTimeType) type).normaliseFraction(nanos, type.scale);
+
+            return new TimestampData(millis / 1000, nanos, 0);
+        }
+
+        return scanner.newTimestamp((String) value);
+    }
+
+    protected IntervalMonthData readYearMonthInterval(Type type)
+    throws IOException {
+
+        readField();
+
+        if (value == null) {
+            return null;
+        }
+
+        return (IntervalMonthData) scanner.newInterval((String) value,
+                (IntervalType) type);
+    }
+
+    protected IntervalSecondData readDaySecondInterval(Type type)
+    throws IOException {
+
+        readField();
+
+        if (value == null) {
+            return null;
+        }
+
+        return (IntervalSecondData) scanner.newInterval((String) value,
+                (IntervalType) type);
+    }
+
+    protected Boolean readBoole() throws IOException {
+
+        readFieldPrefix();
+        scanner.scanNext();
+
+        String token = scanner.getString();
+
+        value = null;
+
+        if (token.equalsIgnoreCase(Tokens.T_TRUE)) {
+            value = Boolean.TRUE;
+        } else if (token.equalsIgnoreCase(Tokens.T_FALSE)) {
+            value = Boolean.FALSE;
+        }
+
+        return (Boolean) value;
+    }
+
+    protected Object readOther() throws IOException {
+
+        readFieldPrefix();
+
+        if (scanner.scanNull()) {
+            return null;
+        }
+
+        scanner.scanBinaryStringWithQuote();
+
+        if (scanner.getTokenType() == Tokens.X_MALFORMED_BINARY_STRING) {
+            throw Error.error(ErrorCode.X_42587);
+        }
+
+        value = scanner.getValue();
+
+        return new JavaObjectData(((BinaryData) value).getBytes());
+    }
+
+    protected BinaryData readBit() throws IOException {
+
+        readFieldPrefix();
+
+        if (scanner.scanNull()) {
+            return null;
+        }
+
+        scanner.scanBitStringWithQuote();
+
+        if (scanner.getTokenType() == Tokens.X_MALFORMED_BIT_STRING) {
+            throw Error.error(ErrorCode.X_42587);
+        }
+
+        value = scanner.getValue();
+
+        return (BinaryData) value;
+    }
+
+    protected BinaryData readBinary() throws IOException {
+
+        readFieldPrefix();
+
+        if (scanner.scanNull()) {
+            return null;
+        }
+
+        scanner.scanBinaryStringWithQuote();
+
+        if (scanner.getTokenType() == Tokens.X_MALFORMED_BINARY_STRING) {
+            throw Error.error(ErrorCode.X_42587);
+        }
+
+        value = scanner.getValue();
+
+        return (BinaryData) value;
+    }
+
+    protected ClobData readClob() throws IOException {
+
+        readNumberField(Type.SQL_BIGINT);
+
+        if (value == null) {
+            return null;
+        }
+
+        long id = ((Number) value).longValue();
+
+        return new ClobDataID(id);
+    }
+
+    protected BlobData readBlob() throws IOException {
+
+        readNumberField(Type.SQL_BIGINT);
+
+        if (value == null) {
+            return null;
+        }
+
+        long id = ((Number) value).longValue();
+
+        return new BlobDataID(id);
+    }
+
+    protected Object[] readArray(Type type) throws IOException {
+
+        type = type.collectionBaseType();
+
+        readFieldPrefix();
+        scanner.scanNext();
+
+        String token = scanner.getString();
+
+        value = null;
+
+        if (token.equalsIgnoreCase(Tokens.T_NULL)) {
+            return null;
+        } else if (!token.equalsIgnoreCase(Tokens.T_ARRAY)) {
+            throw Error.error(ErrorCode.X_42584);
+        }
+
+        scanner.scanNext();
+
+        token = scanner.getString();
+
+        if (!token.equalsIgnoreCase(Tokens.T_LEFTBRACKET)) {
+            throw Error.error(ErrorCode.X_42584);
+        }
+
+        HsqlArrayList list = new HsqlArrayList();
+
+        noSeparators = true;
+
+        for (int i = 0; ; i++) {
+            if (scanner.scanSpecialIdentifier(Tokens.T_RIGHTBRACKET)) {
+                break;
+            }
+
+            if (i > 0) {
+                if (!scanner.scanSpecialIdentifier(Tokens.T_COMMA)) {
+                    throw Error.error(ErrorCode.X_42584);
+                }
+            }
+
+            Object value = readData(type);
+
+            list.add(value);
+        }
+
+        noSeparators = false;
+
+        Object[] data = new Object[list.size()];
+
+        list.toArray(data);
+
+        return data;
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowInputTextQuoted.java b/src/org/hsqldb/rowio/RowInputTextQuoted.java
new file mode 100644
index 0000000..1363cc4
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowInputTextQuoted.java
@@ -0,0 +1,150 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.IOException;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * Fields in the source file need not be quoted. Methods in this class unquote
+ * the fields if they are quoted and handle quote character doubling in this
+ * case.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class RowInputTextQuoted extends RowInputText {
+
+    private static final int NORMAL_FIELD   = 0;
+    private static final int NEED_END_QUOTE = 1;
+    private static final int FOUND_QUOTE    = 2;
+    private char[]           qtext;
+
+    public RowInputTextQuoted(String fieldSep, String varSep,
+                              String longvarSep, boolean allQuoted) {
+        super(fieldSep, varSep, longvarSep, allQuoted);
+    }
+
+    public void setSource(String text, int pos, int byteSize) {
+
+        super.setSource(text, pos, byteSize);
+
+        qtext = text.toCharArray();
+    }
+
+    protected String getField(String sep, int sepLen,
+                              boolean isEnd) throws IOException {
+
+        //fredt - now the only supported behaviour is emptyIsNull
+        String s = null;
+
+        if (next >= qtext.length || qtext[next] != '\"') {
+            return super.getField(sep, sepLen, isEnd);
+        }
+
+        try {
+            field++;
+
+            StringBuffer sb    = new StringBuffer();
+            boolean      done  = false;
+            int          state = NORMAL_FIELD;
+            int          end   = -1;
+
+            if (!isEnd) {
+                end = text.indexOf(sep, next);
+            }
+
+            for (; next < qtext.length; next++) {
+                switch (state) {
+
+                    case NORMAL_FIELD :
+                    default :
+                        if (next == end) {
+                            next += sepLen;
+                            done = true;
+                        } else if (qtext[next] == '\"') {
+
+                            //-- Beginning of field
+                            state = NEED_END_QUOTE;
+                        } else {
+                            sb.append(qtext[next]);
+                        }
+                        break;
+
+                    case NEED_END_QUOTE :
+                        if (qtext[next] == '\"') {
+                            state = FOUND_QUOTE;
+                        } else {
+                            sb.append(qtext[next]);
+                        }
+                        break;
+
+                    case FOUND_QUOTE :
+                        if (qtext[next] == '\"') {
+
+                            //-- Escaped quote
+                            sb.append(qtext[next]);
+
+                            state = NEED_END_QUOTE;
+                        } else {
+                            next  += sepLen - 1;
+                            state = NORMAL_FIELD;
+
+                            if (!isEnd) {
+                                next++;
+
+                                done = true;
+                            }
+                        }
+                        break;
+                }
+
+                if (done) {
+                    break;
+                }
+            }
+
+            s = sb.toString();
+        } catch (Exception e) {
+            throw new IOException(
+                Error.getMessage(
+                    ErrorCode.M_TEXT_SOURCE_FIELD_ERROR, 0, new Object[] {
+                new Integer(field), e.toString()
+            }));
+        }
+
+        return s;
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowOutputBase.java b/src/org/hsqldb/rowio/RowOutputBase.java
new file mode 100644
index 0000000..db01cb9
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowOutputBase.java
@@ -0,0 +1,310 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.math.BigDecimal;
+
+import org.hsqldb.ColumnSchema;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlByteArrayOutputStream;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Base class for writing the data for a database row in different formats.
+ * Defines the methods that are independent of storage format and declares
+ * the format-dependent methods that subclasses should define.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+abstract class RowOutputBase extends HsqlByteArrayOutputStream
+implements RowOutputInterface {
+
+    public static final int CACHED_ROW_160 = 0;
+    public static final int CACHED_ROW_170 = 1;
+
+    // the last column in a table is an ID that should not be written to file
+    protected boolean skipSystemId = false;
+
+    /**
+     *  Constructor used for persistent storage of a Table row
+     *
+     * @exception  IOException when an IO error is encountered
+     */
+    public RowOutputBase() {
+        super();
+    }
+
+    /**
+     *  Constructor used for result sets
+     *
+     * @exception  IOException when an IO error is encountered
+     */
+    public RowOutputBase(int initialSize) {
+        super(initialSize);
+    }
+
+    /**
+     *  Constructor used for network transmission of result sets
+     *
+     * @exception  IOException when an IO error is encountered
+     */
+    public RowOutputBase(byte[] buffer) {
+        super(buffer);
+    }
+
+// fredt@users - comment - methods for writing Result column type, name and data size
+    public abstract void writeEnd();
+
+    public abstract void writeSize(int size);
+
+    public abstract void writeType(int type);
+
+    public abstract void writeIntData(int i, int position);
+
+    public abstract void writeString(String s);
+
+// fredt@users - comment - methods used for writing each SQL type
+    protected void writeFieldPrefix() {}
+
+    protected abstract void writeFieldType(Type type);
+
+    protected abstract void writeNull(Type type);
+
+    protected abstract void writeChar(String s, Type t);
+
+    protected abstract void writeSmallint(Number o);
+
+    protected abstract void writeInteger(Number o);
+
+    protected abstract void writeBigint(Number o);
+
+    protected abstract void writeReal(Double o);
+
+    protected abstract void writeDecimal(BigDecimal o, Type type);
+
+    protected abstract void writeBoolean(Boolean o);
+
+    protected abstract void writeDate(TimestampData o, Type type);
+
+    protected abstract void writeTime(TimeData o, Type type);
+
+    protected abstract void writeTimestamp(TimestampData o, Type type);
+
+    protected abstract void writeYearMonthInterval(IntervalMonthData o,
+            Type type);
+
+    protected abstract void writeDaySecondInterval(IntervalSecondData o,
+            Type type);
+
+    protected abstract void writeOther(JavaObjectData o);
+
+    protected abstract void writeBit(BinaryData o);
+
+    protected abstract void writeBinary(BinaryData o);
+
+    protected abstract void writeClob(ClobData o, Type type);
+
+    protected abstract void writeBlob(BlobData o, Type type);
+
+    protected abstract void writeArray(Object[] o, Type type);
+
+    /**
+     *  This method is called to write data for a table row.
+     */
+    public void writeData(Object[] data, Type[] types) {
+        writeData(types.length, types, data, null, null);
+    }
+
+    /**
+     *  This method is called directly to write data for a delete statement.
+     */
+    public void writeData(int l, Type[] types, Object[] data,
+                          HashMappedList cols, int[] primaryKeys) {
+
+        boolean hasPK = primaryKeys != null && primaryKeys.length != 0;
+        int     limit = hasPK ? primaryKeys.length
+                              : l;
+
+        for (int i = 0; i < limit; i++) {
+            int    j = hasPK ? primaryKeys[i]
+                             : i;
+            Object o = data[j];
+            Type   t = types[j];
+
+            if (cols != null) {
+                ColumnSchema col = (ColumnSchema) cols.get(j);
+
+                writeFieldPrefix();
+                writeString(col.getName().statementName);
+            }
+
+            writeData(t, o);
+        }
+    }
+
+    public void writeData(Type t, Object o) {
+
+        if (o == null) {
+            writeNull(t);
+
+            return;
+        }
+
+        writeFieldType(t);
+
+        switch (t.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                break;
+
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                writeChar((String) o, t);
+                break;
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+                writeSmallint((Number) o);
+                break;
+
+            case Types.SQL_INTEGER :
+                writeInteger((Number) o);
+                break;
+
+            case Types.SQL_BIGINT :
+                writeBigint((Number) o);
+                break;
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                writeReal((Double) o);
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                writeDecimal((BigDecimal) o, t);
+                break;
+
+            case Types.SQL_BOOLEAN :
+                writeBoolean((Boolean) o);
+                break;
+
+            case Types.SQL_DATE :
+                writeDate((TimestampData) o, t);
+                break;
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                writeTime((TimeData) o, t);
+                break;
+
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                writeTimestamp((TimestampData) o, t);
+                break;
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                writeYearMonthInterval((IntervalMonthData) o, t);
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                writeDaySecondInterval((IntervalSecondData) o, t);
+                break;
+
+            case Types.OTHER :
+                writeOther((JavaObjectData) o);
+                break;
+
+            case Types.SQL_BLOB :
+                writeBlob((BlobData) o, t);
+                break;
+
+            case Types.SQL_CLOB :
+                writeClob((ClobData) o, t);
+                break;
+
+            case Types.SQL_ARRAY :
+                writeArray((Object[]) o, t);
+                break;
+
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+                writeBinary((BinaryData) o);
+                break;
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                writeBit((BinaryData) o);
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "RowOutputBase - "
+                                         + t.getNameString());
+        }
+    }
+
+    // returns the underlying HsqlByteArrayOutputStream
+    public HsqlByteArrayOutputStream getOutputStream() {
+        return this;
+    }
+
+    public abstract RowOutputInterface duplicate();
+}
diff --git a/src/org/hsqldb/rowio/RowOutputBinary.java b/src/org/hsqldb/rowio/RowOutputBinary.java
new file mode 100644
index 0000000..7ae877e
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowOutputBinary.java
@@ -0,0 +1,468 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.hsqldb.Row;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * Provides methods for writing the data for a row to a
+ * byte array. The new format of data consists of mainly binary values
+ * and is not compatible with v.1.6.x databases.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.7.0
+ */
+public class RowOutputBinary extends RowOutputBase {
+
+    protected static final int INT_STORE_SIZE = 4;
+    int                        storageSize;
+    final int                  scale;    // 2 to power n where n >= 0
+    final int                  mask;
+
+    public RowOutputBinary(int initialSize, int scale) {
+
+        super(initialSize);
+
+        this.scale = scale;
+        this.mask  = ~(scale - 1);
+    }
+
+    /**
+     * Constructor used for network transmission of result sets
+     *
+     * @param buffer byte[]
+     */
+    public RowOutputBinary(byte[] buffer) {
+
+        super(buffer);
+
+        scale     = 1;
+        this.mask = ~(scale - 1);
+    }
+
+// fredt@users - comment - methods for writing column type, name and data size
+    public void writeIntData(int i, int position) {
+
+        int temp = count;
+
+        count = position;
+
+        writeInt(i);
+
+        if (count < temp) {
+            count = temp;
+        }
+    }
+
+    public void writeData(Object[] data, Type[] types) {
+        super.writeData(data, types);
+    }
+
+    public void writeEnd() {
+
+        if (count > storageSize) {
+            Error.runtimeError(ErrorCode.U_S0500, "RowOutputBinary");
+        }
+
+        for (; count < storageSize; ) {
+            this.write(0);
+        }
+    }
+
+    public void writeSize(int size) {
+
+        storageSize = size;
+
+        writeInt(size);
+    }
+
+    public void writeType(int type) {
+        writeShort(type);
+    }
+
+    public void writeString(String s) {
+
+        int temp = count;
+
+        writeInt(0);
+
+        if (s != null && s.length() != 0) {
+            StringConverter.stringToUTFBytes(s, this);
+            writeIntData(count - temp - INT_STORE_SIZE, temp);
+        }
+    }
+
+    /**
+     *  Calculate the size of byte array required to store a row.
+     *
+     * @param  row - a database row
+     * @return  size of byte array
+     * @exception  HsqlException When data is inconsistent
+     */
+    public int getSize(Row row) {
+
+        Object[] data  = row.getData();
+        Type[]   types = row.getTable().getColumnTypes();
+        int      cols  = row.getTable().getDataColumnCount();
+
+        return INT_STORE_SIZE + getSize(data, cols, types);
+    }
+
+    public int getStorageSize(int size) {
+        return (size + scale - 1) & mask;
+    }
+
+    protected void writeFieldType(Type type) {
+        write(1);
+    }
+
+    protected void writeNull(Type type) {
+        write(0);
+    }
+
+    protected void writeChar(String s, Type t) {
+        writeString(s);
+    }
+
+    protected void writeSmallint(Number o) {
+        writeShort(o.intValue());
+    }
+
+    protected void writeInteger(Number o) {
+        writeInt(o.intValue());
+    }
+
+    protected void writeBigint(Number o) {
+        writeLong(o.longValue());
+    }
+
+    protected void writeReal(Double o) {
+        writeLong(Double.doubleToLongBits((o.doubleValue())));
+    }
+
+    protected void writeDecimal(BigDecimal o, Type type) {
+
+        int        scale   = o.scale();
+        BigInteger bigint  = JavaSystem.unscaledValue(o);
+        byte[]     bytearr = bigint.toByteArray();
+
+        writeByteArray(bytearr);
+        writeInt(scale);
+    }
+
+    protected void writeBoolean(Boolean o) {
+        write(o.booleanValue() ? 1
+                               : 0);
+    }
+
+    protected void writeDate(TimestampData o, Type type) {
+        writeLong(o.getSeconds());
+    }
+
+    protected void writeTime(TimeData o, Type type) {
+
+        writeInt(o.getSeconds());
+        writeInt(o.getNanos());
+
+        if (type.typeCode == Types.SQL_TIME_WITH_TIME_ZONE) {
+            writeInt(o.getZone());
+        }
+    }
+
+    protected void writeTimestamp(TimestampData o, Type type) {
+
+        writeLong(o.getSeconds());
+        writeInt(o.getNanos());
+
+        if (type.typeCode == Types.SQL_TIMESTAMP_WITH_TIME_ZONE) {
+            writeInt(o.getZone());
+        }
+    }
+
+    protected void writeYearMonthInterval(IntervalMonthData o, Type type) {
+        writeLong(o.units);
+    }
+
+    protected void writeDaySecondInterval(IntervalSecondData o, Type type) {
+        writeLong(o.units);
+        writeInt(o.nanos);
+    }
+
+    protected void writeOther(JavaObjectData o) {
+        writeByteArray(o.getBytes());
+    }
+
+    protected void writeBit(BinaryData o) {
+        writeInt((int) o.bitLength(null));
+        write(o.getBytes(), 0, o.getBytes().length);
+    }
+
+    protected void writeBinary(BinaryData o) {
+        writeByteArray(o.getBytes());
+    }
+
+    protected void writeClob(ClobData o, Type type) {
+        writeLong(o.getId());
+    }
+
+    protected void writeBlob(BlobData o, Type type) {
+        writeLong(o.getId());
+    }
+
+    protected void writeArray(Object[] o, Type type) {
+
+        type = type.collectionBaseType();
+
+        writeInt(o.length);
+
+        for (int i = 0; i < o.length; i++) {
+            writeData(type, o[i]);
+        }
+    }
+
+// fredt@users - comment - helper and conversion methods
+    public void writeByteArray(byte[] b) {
+        writeInt(b.length);
+        write(b, 0, b.length);
+    }
+
+    // fredt@users - comment - helper and conversion methods
+    public void writeCharArray(char[] c) {
+        writeInt(c.length);
+        write(c, 0, c.length);
+    }
+
+    /**
+     * Calculate the size of byte array required to store a row.
+     *
+     * @param data - the row data
+     * @param l - number of data[] elements to include in calculation
+     * @param types - array of java.sql.Types values
+     * @return size of byte array
+     */
+    private int getSize(Object[] data, int l, Type[] types) {
+
+        int s = 0;
+
+        for (int i = 0; i < l; i++) {
+            Object o = data[i];
+
+            s += getSize(o, types[i]);
+        }
+
+        return s;
+    }
+
+    private int getSize(Object o, Type type) {
+
+        int s = 1;    // type or null
+
+        if (o == null) {
+            return s;
+        }
+
+        switch (type.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                break;
+
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                s += INT_STORE_SIZE;
+                s += StringConverter.getUTFSize((String) o);
+                break;
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+                s += 2;
+                break;
+
+            case Types.SQL_INTEGER :
+                s += 4;
+                break;
+
+            case Types.SQL_BIGINT :
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                s += 8;
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                s += 8;
+
+                BigDecimal bigdecimal = (BigDecimal) o;
+                BigInteger bigint     = JavaSystem.unscaledValue(bigdecimal);
+
+                s += bigint.toByteArray().length;
+                break;
+
+            case Types.SQL_BOOLEAN :
+                s += 1;
+                break;
+
+            case Types.SQL_DATE :
+                s += 8;
+                break;
+
+            case Types.SQL_TIME :
+                s += 8;
+                break;
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                s += 12;
+                break;
+
+            case Types.SQL_TIMESTAMP :
+                s += 12;
+                break;
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                s += 16;
+                break;
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                s += 8;
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                s += 12;
+                break;
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+                s += INT_STORE_SIZE;
+                s += ((BinaryData) o).length(null);
+                break;
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                s += INT_STORE_SIZE;
+                s += ((BinaryData) o).length(null);
+                break;
+
+            case Types.SQL_CLOB :
+            case Types.SQL_BLOB :
+                s += 8;
+                break;
+
+            case Types.SQL_ARRAY : {
+                s += 4;
+
+                Object[] array = (Object[]) o;
+
+                type = type.collectionBaseType();
+
+                for (int i = 0; i < array.length; i++) {
+                    s += getSize(array[i], type);
+                }
+
+                break;
+            }
+            case Types.OTHER :
+                JavaObjectData jo = (JavaObjectData) o;
+
+                s += INT_STORE_SIZE;
+                s += jo.getBytesLength();
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "RowOutputBinary");
+        }
+
+        return s;
+    }
+
+    /**
+     * @param  extra amount of extra space
+     */
+    public void ensureRoom(int extra) {
+        super.ensureRoom(extra);
+    }
+
+    public void reset() {
+
+        super.reset();
+
+        storageSize = 0;
+    }
+
+    public void reset(int newSize) {
+
+        super.reset(newSize);
+
+        storageSize = 0;
+    }
+
+    public void setBuffer(byte[] buffer) {
+
+        this.buffer = buffer;
+
+        reset();
+    }
+
+    public RowOutputInterface duplicate() {
+        return new RowOutputBinary(128, this.scale);
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowOutputBinary180.java b/src/org/hsqldb/rowio/RowOutputBinary180.java
new file mode 100644
index 0000000..98159ce
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowOutputBinary180.java
@@ -0,0 +1,95 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowOutputBinary180 extends RowOutputBinary {
+
+    public RowOutputBinary180(int initialSize, int scale) {
+        super(initialSize, scale);
+    }
+
+    protected void writeDate(TimestampData o, Type type) {
+
+        long millis = o.getSeconds() * 1000L;
+
+        millis =
+            HsqlDateTime.convertMillisToCalendar(HsqlDateTime.tempCalDefault,
+                millis);
+
+        writeLong(millis);
+        writeLong(o.getSeconds() * 1000L);
+    }
+
+    protected void writeTime(TimeData o, Type type) {
+
+        if (type.typeCode == Types.SQL_TIME) {
+            long millis = o.getSeconds() * 1000L;
+
+            millis = HsqlDateTime.convertMillisToCalendar(
+                HsqlDateTime.tempCalDefault, millis);
+
+            writeLong(millis);
+        } else {
+            writeInt(o.getSeconds());
+            writeInt(o.getNanos());
+            writeInt(o.getZone());
+        }
+    }
+
+    protected void writeTimestamp(TimestampData o, Type type) {
+
+        if (type.typeCode == Types.SQL_TIMESTAMP) {
+            long millis = o.getSeconds() * 1000L;
+
+            millis = HsqlDateTime.convertMillisToCalendar(
+                HsqlDateTime.tempCalDefault, millis);
+
+            writeLong(millis);
+            writeInt(o.getNanos());
+        } else {
+            writeLong(o.getSeconds());
+            writeInt(o.getNanos());
+            writeInt(o.getZone());
+        }
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowOutputBinaryEncode.java b/src/org/hsqldb/rowio/RowOutputBinaryEncode.java
new file mode 100644
index 0000000..d824a9c
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowOutputBinaryEncode.java
@@ -0,0 +1,97 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import org.hsqldb.Row;
+import org.hsqldb.persist.Crypto;
+import org.hsqldb.types.Type;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class RowOutputBinaryEncode extends RowOutputBinary {
+
+    final Crypto crypto;
+
+    public RowOutputBinaryEncode(Crypto crypto, int initialSize, int scale) {
+
+        super(initialSize, scale);
+
+        this.crypto = crypto;
+    }
+
+    public void writeData(Object[] data, Type[] types) {
+
+        if (crypto == null) {
+            super.writeData(data, types);
+        } else {
+            int start = count;
+
+            writeInt(0);
+            super.writeData(data, types);
+
+            int origLength = count - start - INT_STORE_SIZE;
+            int newLength = crypto.encode(buffer, start + INT_STORE_SIZE,
+                                          origLength, buffer,
+                                          start + INT_STORE_SIZE);
+
+            writeIntData(newLength, start);
+
+            count = start + INT_STORE_SIZE + newLength;
+        }
+    }
+
+    /**
+     *  Calculate the size of byte array required to store a row.
+     *
+     * @param  row - a database row
+     * @return  size of byte array
+     * @exception  HsqlException When data is inconsistent
+     */
+    public int getSize(Row row) {
+
+        int size = super.getSize(row);
+
+        if (crypto != null) {
+            size = crypto.getEncodedSize(size - INT_STORE_SIZE)
+                   + INT_STORE_SIZE * 2;
+        }
+
+        return size;
+    }
+
+    public RowOutputInterface duplicate() {
+        return new RowOutputBinaryEncode(crypto, 128, this.scale);
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowOutputInterface.java b/src/org/hsqldb/rowio/RowOutputInterface.java
new file mode 100644
index 0000000..3a634a2
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowOutputInterface.java
@@ -0,0 +1,90 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import org.hsqldb.Row;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlByteArrayOutputStream;
+import org.hsqldb.types.Type;
+
+/**
+ * Public interface for writing the data for a database row.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public interface RowOutputInterface extends Cloneable {
+
+    void writeEnd();
+
+    void writeSize(int size);
+
+    void writeType(int type);
+
+    void writeString(String value);
+
+    void writeByte(int i);
+
+    void writeShort(int i);
+
+    void writeInt(int i);
+
+    void writeIntData(int i, int position);
+
+    void writeLong(long i);
+
+    void writeData(Object[] data, Type[] types);
+
+    void writeData(int l, Type[] types, Object[] data, HashMappedList cols,
+                   int[] primarykeys);
+
+    // independent of the this object, calls only a static method
+    int getSize(Row row);
+
+    int getStorageSize(int size);
+
+    // returns the underlying HsqlByteArrayOutputStream
+    HsqlByteArrayOutputStream getOutputStream();
+
+    // sets the byte[] buffer
+    public void setBuffer(byte[] mainBuffer);
+
+    // resets the byte[] buffer, ready for processing new row
+    void reset();
+
+    // returns the current size
+    int size();
+
+    public RowOutputInterface duplicate();
+}
diff --git a/src/org/hsqldb/rowio/RowOutputText.java b/src/org/hsqldb/rowio/RowOutputText.java
new file mode 100644
index 0000000..e8fa794
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowOutputText.java
@@ -0,0 +1,386 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+
+import org.hsqldb.Row;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.persist.TextCache;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+
+/**
+ *  Class for writing the data for a database row in text table format.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 1.7.0
+ */
+public class RowOutputText extends RowOutputBase {
+
+    protected String  fieldSep;
+    protected String  varSep;
+    protected String  longvarSep;
+    private boolean   fieldSepEnd;
+    private boolean   varSepEnd;
+    private boolean   longvarSepEnd;
+    private String    nextSep = "";
+    private boolean   nextSepEnd;
+    protected boolean allQuoted;
+    private String    encoding;
+
+    public RowOutputText(String fieldSep, String varSep, String longvarSep,
+                         boolean allQuoted, String encoding) {
+
+        super();
+
+        initTextDatabaseRowOutput(fieldSep, varSep, longvarSep, allQuoted,
+                                  encoding);
+    }
+
+    private void initTextDatabaseRowOutput(String fieldSep, String varSep,
+                                           String longvarSep,
+                                           boolean allQuoted,
+                                           String encoding) {
+
+        //-- Newline indicates that field should match to end of line.
+        if (fieldSep.endsWith("\n")) {
+            fieldSepEnd = true;
+            fieldSep    = fieldSep.substring(0, fieldSep.length() - 1);
+        }
+
+        if (varSep.endsWith("\n")) {
+            varSepEnd = true;
+            varSep    = varSep.substring(0, varSep.length() - 1);
+        }
+
+        if (longvarSep.endsWith("\n")) {
+            longvarSepEnd = true;
+            longvarSep    = longvarSep.substring(0, longvarSep.length() - 1);
+        }
+
+        this.fieldSep   = fieldSep;
+        this.varSep     = varSep;
+        this.longvarSep = longvarSep;
+        this.allQuoted  = allQuoted;
+        this.encoding   = encoding;
+    }
+
+    public void writeEnd() {
+
+        // terminate at the end of row
+        if (nextSepEnd) {
+            writeBytes(nextSep);
+        }
+
+        writeBytes(TextCache.NL);
+    }
+
+    public void writeSize(int size) {
+
+        // initialise at the start of row
+        nextSep    = "";
+        nextSepEnd = false;
+    }
+
+    public void writeType(int type) {
+
+        //--do Nothing
+    }
+
+    public void writeString(String s) {
+
+        s = checkConvertString(s, fieldSep);
+
+        // error
+        if (s == null) {
+            return;
+        }
+
+        // writeBytes(s);
+        byte[] bytes = getBytes(s);
+
+        write(bytes, 0, bytes.length);
+
+        nextSep    = fieldSep;
+        nextSepEnd = fieldSepEnd;
+    }
+
+    protected void writeVarString(String s) {
+
+        s = checkConvertString(s, varSep);
+
+        if (s == null) {
+            return;
+        }
+
+        // writeBytes(s);
+        byte[] bytes = getBytes(s);
+
+        write(bytes, 0, bytes.length);
+
+        nextSep    = varSep;
+        nextSepEnd = varSepEnd;
+    }
+
+    protected void writeLongVarString(String s) {
+
+        s = checkConvertString(s, longvarSep);
+
+        if (s == null) {
+            return;
+        }
+
+        // writeBytes(s);
+        byte[] bytes = getBytes(s);
+
+        write(bytes, 0, bytes.length);
+
+        nextSep    = longvarSep;
+        nextSepEnd = longvarSepEnd;
+    }
+
+    protected String checkConvertString(String s, String sep) {
+
+        if (s.indexOf('\n') != -1 || s.indexOf('\r') != -1) {
+            throw new IllegalArgumentException(
+                Error.getMessage(ErrorCode.TEXT_STRING_HAS_NEWLINE));
+        } else if (s.indexOf(sep) != -1) {
+            return null;
+        }
+
+        return s;
+    }
+
+    private byte[] getBytes(String s) {
+
+        byte[] bytes = null;
+
+        try {
+            bytes = s.getBytes(encoding);
+        } catch (UnsupportedEncodingException e) {
+            bytes = s.getBytes();
+        }
+
+        return bytes;
+    }
+
+    protected void writeByteArray(byte[] b) {
+
+        ensureRoom(b.length * 2);
+        StringConverter.writeHexBytes(this.getBuffer(), count, b);
+
+        count += b.length * 2;
+    }
+
+    public void writeShort(int i) {
+        writeInt(i);
+    }
+
+    public void writeInt(int i) {
+
+        writeBytes(Integer.toString(i));
+
+        nextSep    = fieldSep;
+        nextSepEnd = fieldSepEnd;
+    }
+
+    public void writeIntData(int i, int position) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowOutputText");
+    }
+
+    public void writeLong(long i) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowOutputText");
+    }
+
+// fredt@users - comment - methods used for writing each SQL type
+    protected void writeFieldType(Type type) {
+
+        writeBytes(nextSep);
+
+        switch (type.typeCode) {
+
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                nextSep    = varSep;
+                nextSepEnd = varSepEnd;
+                break;
+
+            default :
+                nextSep    = fieldSep;
+                nextSepEnd = fieldSepEnd;
+                break;
+        }
+    }
+
+    protected void writeNull(Type type) {
+        writeFieldType(type);
+    }
+
+    protected void writeChar(String s, Type t) {
+
+        switch (t.typeCode) {
+
+            case Types.SQL_CHAR :
+                writeString(s);
+
+                return;
+
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                writeVarString(s);
+
+                return;
+
+            default :
+                writeLongVarString(s);
+
+                return;
+        }
+    }
+
+    protected void writeSmallint(Number o) {
+        writeString(o.toString());
+    }
+
+    protected void writeInteger(Number o) {
+        writeString(o.toString());
+    }
+
+    protected void writeBigint(Number o) {
+        writeString(o.toString());
+    }
+
+    protected void writeReal(Double o) {
+        writeString(o.toString());
+    }
+
+    protected void writeDecimal(BigDecimal o, Type type) {
+        writeString(type.convertToString(o));
+    }
+
+    protected void writeBoolean(Boolean o) {
+        writeString(o.toString());
+    }
+
+    protected void writeDate(TimestampData o, Type type) {
+        writeString(type.convertToString(o));
+    }
+
+    protected void writeTime(TimeData o, Type type) {
+        writeString(type.convertToString(o));
+    }
+
+    protected void writeTimestamp(TimestampData o, Type type) {
+        writeString(type.convertToString(o));
+    }
+
+    protected void writeYearMonthInterval(IntervalMonthData o, Type type) {
+        this.writeBytes(type.convertToString(o));
+    }
+
+    protected void writeDaySecondInterval(IntervalSecondData o, Type type) {
+        this.writeBytes(type.convertToString(o));
+    }
+
+    protected void writeOther(JavaObjectData o) {
+
+        byte[] ba = o.getBytes();
+
+        writeByteArray(ba);
+    }
+
+    protected void writeBit(BinaryData o) {
+
+        String s = StringConverter.byteArrayToBitString(o.getBytes(),
+            (int) o.bitLength(null));
+
+        writeString(s);
+    }
+
+    protected void writeBinary(BinaryData o) {
+        writeByteArray(o.getBytes());
+    }
+
+    protected void writeClob(ClobData o, Type type) {
+        writeString(Long.toString(o.getId()));
+    }
+
+    protected void writeBlob(BlobData o, Type type) {
+        writeString(Long.toString(o.getId()));
+    }
+
+    protected void writeArray(Object[] o, Type type) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowOutputText");
+    }
+
+    public int getSize(Row r) {
+
+        reset();
+
+        try {
+            writeSize(0);
+            writeData(r.getData(), r.getTable().getColumnTypes());
+            writeEnd();
+        } catch (Exception e) {
+            reset();
+
+//            throw Error.error(ErrorCode.FILE_IO_ERROR, e.toString());
+        }
+
+        int rowsize = size();
+
+        reset();
+
+        return rowsize;
+    }
+
+    public int getStorageSize(int size) {
+        return size;
+    }
+
+    public RowOutputInterface duplicate() {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowOutputText");
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowOutputTextLog.java b/src/org/hsqldb/rowio/RowOutputTextLog.java
new file mode 100644
index 0000000..e339a88
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowOutputTextLog.java
@@ -0,0 +1,297 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+
+import org.hsqldb.Row;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.BlobData;
+import org.hsqldb.types.ClobData;
+import org.hsqldb.types.IntervalMonthData;
+import org.hsqldb.types.IntervalSecondData;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.types.TimeData;
+import org.hsqldb.types.TimestampData;
+import org.hsqldb.types.Type;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @since 2.0.0
+ * @version 1.7.2
+ */
+public class RowOutputTextLog extends RowOutputBase {
+
+    static byte[] BYTES_NULL;
+    static byte[] BYTES_TRUE;
+    static byte[] BYTES_FALSE;
+    static byte[] BYTES_AND;
+    static byte[] BYTES_IS;
+    static byte[] BYTES_ARRAY;
+
+    static {
+        try {
+            BYTES_NULL  = Tokens.T_NULL.getBytes("ISO-8859-1");
+            BYTES_TRUE  = Tokens.T_TRUE.getBytes("ISO-8859-1");
+            BYTES_FALSE = Tokens.T_FALSE.getBytes("ISO-8859-1");
+            BYTES_AND   = " AND ".getBytes("ISO-8859-1");
+            BYTES_IS    = " IS ".getBytes("ISO-8859-1");
+            BYTES_ARRAY = " ARRAY[".getBytes("ISO-8859-1");
+        } catch (UnsupportedEncodingException e) {
+            Error.runtimeError(ErrorCode.U_S0500, "RowOutputTextLog");
+        }
+    }
+
+    public static final int MODE_DELETE = 1;
+    public static final int MODE_INSERT = 0;
+    private boolean         isWritten;
+    private int             logMode;
+    private boolean         noSeparators;
+
+    public void setMode(int mode) {
+        logMode = mode;
+    }
+
+    protected void writeFieldPrefix() {
+
+        if (!noSeparators) {
+            if (logMode == MODE_DELETE && isWritten) {
+                write(BYTES_AND);
+            }
+        }
+    }
+
+    protected void writeChar(String s, Type t) {
+
+        write('\'');
+        StringConverter.stringToUnicodeBytes(this, s, true);
+        write('\'');
+    }
+
+    protected void writeReal(Double o) {
+        writeBytes(Type.SQL_DOUBLE.convertToSQLString(o));
+    }
+
+    protected void writeSmallint(Number o) {
+        this.writeBytes(o.toString());
+    }
+
+    public void writeEnd() {}
+
+    protected void writeBit(BinaryData o) {
+
+        ensureRoom((int) (o.length(null) * 8 + 2));
+        write('\'');
+
+        String s = StringConverter.byteArrayToBitString(o.getBytes(),
+            (int) o.bitLength(null));
+
+        writeBytes(s);
+        write('\'');
+    }
+
+    protected void writeBinary(BinaryData o) {
+
+        ensureRoom((int) (o.length(null) * 2 + 2));
+        write('\'');
+        StringConverter.writeHexBytes(getBuffer(), count, o.getBytes());
+
+        count += (o.length(null) * 2);
+
+        write('\'');
+    }
+
+    protected void writeClob(ClobData o, Type type) {
+        writeString(Long.toString(o.getId()));
+    }
+
+    protected void writeBlob(BlobData o, Type type) {
+        writeString(Long.toString(o.getId()));
+    }
+
+    protected void writeArray(Object[] o, Type type) {
+
+        type = type.collectionBaseType();
+
+        noSeparators = true;
+        write(BYTES_ARRAY);
+
+        for (int i = 0; i < o.length; i++) {
+            if (i > 0) {
+                write(',');
+            }
+
+            writeData(type, o[i]);
+        }
+
+        write(']');
+        noSeparators = false;
+    }
+
+    public void writeType(int type) {}
+
+    public void writeSize(int size) {}
+
+    public int getSize(Row row) {
+        return 0;
+    }
+
+    public int getStorageSize(int size) {
+        return size;
+    }
+
+    protected void writeInteger(Number o) {
+        this.writeBytes(o.toString());
+    }
+
+    protected void writeBigint(Number o) {
+        this.writeBytes(o.toString());
+    }
+
+//fredt@users - patch 1108647 by nkowalcz@users (NataliaK) fix for IS NULL
+    protected void writeNull(Type type) {
+
+        if (!noSeparators) {
+            if (logMode == MODE_DELETE) {
+                write(BYTES_IS);
+            } else if (isWritten) {
+                write(',');
+            }
+
+            isWritten = true;
+        }
+
+        write(BYTES_NULL);
+    }
+
+    protected void writeOther(JavaObjectData o) {
+
+        ensureRoom(o.getBytesLength() * 2 + 2);
+        write('\'');
+        StringConverter.writeHexBytes(getBuffer(), count, o.getBytes());
+
+        count += o.getBytesLength() * 2;
+
+        write('\'');
+    }
+
+    public void writeString(String value) {
+        StringConverter.stringToUnicodeBytes(this, value, false);
+    }
+
+    protected void writeBoolean(Boolean o) {
+        write(o.booleanValue() ? BYTES_TRUE
+                               : BYTES_FALSE);
+    }
+
+    protected void writeDecimal(BigDecimal o, Type type) {
+        writeBytes(type.convertToSQLString(o));
+    }
+
+    protected void writeFieldType(Type type) {
+
+        if (!noSeparators) {
+            if (logMode == MODE_DELETE) {
+                write('=');
+            } else if (isWritten) {
+                write(',');
+            }
+
+            isWritten = true;
+        }
+    }
+
+    public void writeLong(long value) {
+        this.writeBytes(Long.toString(value));
+    }
+
+    public void writeIntData(int i, int position) {}
+
+    protected void writeTime(TimeData o, Type type) {
+
+        write('\'');
+        writeBytes(type.convertToString(o));
+        write('\'');
+    }
+
+    protected void writeDate(TimestampData o, Type type) {
+
+        write('\'');
+        writeBytes(type.convertToString(o));
+        write('\'');
+    }
+
+    protected void writeTimestamp(TimestampData o, Type type) {
+
+        write('\'');
+        writeBytes(type.convertToString(o));
+        write('\'');
+    }
+
+    protected void writeYearMonthInterval(IntervalMonthData o, Type type) {
+
+        write('\'');
+        writeBytes(type.convertToString(o));
+        write('\'');
+    }
+
+    protected void writeDaySecondInterval(IntervalSecondData o, Type type) {
+
+        write('\'');
+        writeBytes(type.convertToString(o));
+        write('\'');
+    }
+
+    public void writeShort(int i) {
+        writeBytes(Integer.toString(i));
+    }
+
+    public void writeInt(int i) {
+        writeBytes(Integer.toString(i));
+    }
+
+    public void reset() {
+
+        super.reset();
+
+        isWritten = false;
+    }
+
+    public RowOutputInterface duplicate() {
+        throw Error.runtimeError(ErrorCode.U_S0500, "RowOutputText");
+    }
+}
diff --git a/src/org/hsqldb/rowio/RowOutputTextQuoted.java b/src/org/hsqldb/rowio/RowOutputTextQuoted.java
new file mode 100644
index 0000000..58fb9ec
--- /dev/null
+++ b/src/org/hsqldb/rowio/RowOutputTextQuoted.java
@@ -0,0 +1,73 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.rowio;
+
+import org.hsqldb.lib.StringConverter;
+
+/**
+ * This class quotes strings only if they contain the quote character or
+ * the separator for the field. The quote character is doubled.
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.0
+ */
+public class RowOutputTextQuoted extends RowOutputText {
+
+    public RowOutputTextQuoted(String fieldSep, String varSep,
+                               String longvarSep, boolean allQuoted,
+                               String encoding) {
+        super(fieldSep, varSep, longvarSep, allQuoted, encoding);
+    }
+
+    protected String checkConvertString(String s, String sep) {
+
+        if (allQuoted || s.length() == 0 || s.indexOf('\"') != -1
+                || (sep.length() > 0 && s.indexOf(sep) != -1)
+                || hasUnprintable(s)) {
+            s = StringConverter.toQuotedString(s, '\"', true);
+        }
+
+        return s;
+    }
+
+    private static boolean hasUnprintable(String s) {
+
+        for (int i = 0, len = s.length(); i < len; i++) {
+            if (Character.isISOControl(s.charAt(i))) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/sample/ConnectionTypesSample.java b/src/org/hsqldb/sample/ConnectionTypesSample.java
new file mode 100644
index 0000000..d6ae763
--- /dev/null
+++ b/src/org/hsqldb/sample/ConnectionTypesSample.java
@@ -0,0 +1,54 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+/*
+ * How to customize DatabaseManager with pluggable connection types.
+ *
+ * @version 1.7.0
+ */
+public class ConnectionTypesSample extends java.util.Vector {
+
+    public ConnectionTypesSample() {
+
+        // An example
+        addElement("Example");
+        addElement("org.example:ExampleDriver");
+        addElement("jdbc:example");
+
+        // Something useful
+        addElement("Sybase");
+        addElement("com.sybase.jdbc.SybDriver");
+        addElement("jdbc:sybase:Tds:"
+                   + "\u00ABhost?\u00BB:2638/\u00ABdatabase?\u00BB");
+    }
+}
diff --git a/src/org/hsqldb/sample/DatabaseManagerSample.java b/src/org/hsqldb/sample/DatabaseManagerSample.java
new file mode 100644
index 0000000..fd67144
--- /dev/null
+++ b/src/org/hsqldb/sample/DatabaseManagerSample.java
@@ -0,0 +1,50 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.util.Properties;
+
+/*
+ * How to customize DatabaseManager with pluggable connection types.
+ *
+ * @version 1.7.0
+ */
+public class DatabaseManagerSample extends org.hsqldb.util.DatabaseManager {
+
+    static {
+        Properties p = new Properties();
+
+        p.put("org.hsqldb.util.ConnectionTypeClass",
+              "org.hsqldb.sample.ConnectionTypesSample");
+        System.setProperties(p);
+    }
+}
diff --git a/src/org/hsqldb/sample/FindFile.java b/src/org/hsqldb/sample/FindFile.java
new file mode 100644
index 0000000..f0bcc8b
--- /dev/null
+++ b/src/org/hsqldb/sample/FindFile.java
@@ -0,0 +1,258 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * Extract a directory tree and store in an HSQLDB database.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.7.0
+ * @since Hypersonic SQL
+ */
+class FindFile {
+
+    /**
+     * Extracts a directory tree and stores it ina HSQLDB database.<br>
+     * Usage:<p>
+     * <pre>
+     * java org.hsqldb.sample.FindFile -init .
+     * Re-create database from directory '.'
+     * java org.hsqldb.sample.FindFile name
+     * Find files like 'name'
+     * </pre>
+     *
+     * @param arg
+     */
+    public static void main(String[] arg) {
+
+        // Exceptions may occur
+        try {
+
+            // Load the HSQL Database Engine JDBC driver
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            // Connect to the database
+            // It will be create automatically if it does not yet exist
+            // 'testfiles' in the URL is the name of the database
+            // "SA" is the user name and "" is the (empty) password
+            Connection conn =
+                DriverManager.getConnection("jdbc:hsqldb:testfiles", "SA",
+                                            "");
+
+            // Check the command line parameters
+            if (arg.length == 1) {
+
+                // One parameter:
+                // Find and print the list of files that are like this
+                listFiles(conn, arg[0]);
+            } else if ((arg.length == 2) && arg[0].equals("-init")) {
+
+                // Command line parameters: -init pathname
+                // Init the database and fill all file names in
+                fillFileNames(conn, arg[1]);
+            } else {
+
+                // Display the usage info
+                System.out.println("Usage:");
+                System.out.println("java FindFile -init .");
+                System.out.println("  Re-create database from directory '.'");
+                System.out.println("java FindFile name");
+                System.out.println("  Find files like 'name'");
+            }
+
+            // Finally, close the connection
+            conn.close();
+        } catch (Exception e) {
+
+            // Print out the error message
+            System.out.println(e);
+            e.printStackTrace();
+        }
+    }
+
+    // Search in the database and list out files like this
+
+    /**
+     * @throws SQLException
+     */
+    static void listFiles(Connection conn, String name) throws SQLException {
+
+        System.out.println("Files like '" + name + "'");
+
+        // Convert to upper case, so the search is case-insensitive
+        name = name.toUpperCase();
+
+        // Create a statement object
+        Statement stat = conn.createStatement();
+
+        // Now execute the search query
+        // UCASE: This is a case insensitive search
+        // ESCAPE ':' is used so it can be easily searched for '\'
+        ResultSet result = stat.executeQuery("SELECT Path FROM Files WHERE "
+                                             + "UCASE(Path) LIKE '%" + name
+                                             + "%' ESCAPE ':'");
+
+        // Moves to the next record until no more records
+        while (result.next()) {
+
+            // Print the first column of the result
+            // could use also getString("Path")
+            System.out.println(result.getString(1));
+        }
+
+        // Close the ResultSet - not really necessary, but recommended
+        result.close();
+    }
+
+    // Re-create the database and fill the file names in
+
+    /**
+     * @throws SQLException
+     */
+    static void fillFileNames(Connection conn,
+                              String root) throws SQLException {
+
+        System.out.println("Re-creating the database...");
+
+        // Create a statement object
+        Statement stat = conn.createStatement();
+
+        // Try to drop the table
+        try {
+            stat.executeUpdate("DROP TABLE Files");
+        } catch (SQLException e) {    // Ignore Exception, because the table may not yet exist
+        }
+
+        // For compatibility to other database, use varchar(255)
+        // In HSQL Database Engine, length is unlimited, like Java Strings
+        stat.execute("CREATE TABLE Files"
+                     + "(Path varchar(255),Name varchar(255))");
+
+        // Close the Statement object, it is no longer used
+        stat.close();
+
+        // Use a PreparedStatement because Path and Name could contain '
+        PreparedStatement prep =
+            conn.prepareCall("INSERT INTO Files (Path,Name) VALUES (?,?)");
+
+        // Start with the 'root' directory and recurse all subdirectories
+        fillPath(root, "", prep);
+
+        // Close the PreparedStatement
+        prep.close();
+        System.out.println("Finished");
+    }
+
+    // Fill the file names, using the PreparedStatement
+
+    /**
+     * @throws SQLException
+     */
+    static void fillPath(String path, String name,
+                         PreparedStatement prep) throws SQLException {
+
+        File f = new File(path);
+
+        if (f.isFile()) {
+
+            // Clear all Parameters of the PreparedStatement
+            prep.clearParameters();
+
+            // Fill the first parameter: Path
+            prep.setString(1, path);
+
+            // Fill the second parameter: Name
+            prep.setString(2, name);
+
+            // Its a file: add it to the table
+            prep.execute();
+        } else if (f.isDirectory()) {
+            if (!path.endsWith(File.separator)) {
+                path += File.separator;
+            }
+
+            String[] list = f.list();
+
+            // Process all files recursivly
+            for (int i = 0; (list != null) && (i < list.length); i++) {
+                fillPath(path + list[i], list[i], prep);
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/sample/SqlFileEmbedder.java b/src/org/hsqldb/sample/SqlFileEmbedder.java
new file mode 100644
index 0000000..1fefc45
--- /dev/null
+++ b/src/org/hsqldb/sample/SqlFileEmbedder.java
@@ -0,0 +1,150 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import org.hsqldb.lib.RCData;
+import org.hsqldb.cmdline.SqlFile;
+import org.hsqldb.cmdline.SqlToolError;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Sample class which executes SQL files, by embedding SqlFile.
+ * <P/>
+ * Suitable for using as a template.
+ * <P/>
+ * This class also serves as an example of using RCData to allow your
+ * application users to store JDBC access information in a convenient
+ * text file.
+ *
+ * @see #main(String[])
+ * @see SqlFile
+ * @see RCData
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class SqlFileEmbedder {
+    private Connection conn;
+
+    /**
+     * For applications that use a persistent JDBC connection, this class can
+     * be used to encapsulate that connection.  (Just strip out the SqlFile
+     * stuff if you don't need that).
+     *
+     * @return The encapsulated JDBC Connection.
+     */
+    public Connection getConn() {
+        return conn;
+    }
+
+    /**
+     * Run<PRE>
+     *     java SqlFileEmbedder</PRE>
+     * to see Syntax message.
+     */
+    public static void main(String[] sa) throws Exception {
+        if (sa.length < 3) {
+            System.err.println("SYNTAX:  " + SqlFileEmbedder.class.getName()
+                    + " path/ro/file.rc URLID file1.sql...");
+            System.exit(2);
+        }
+        SqlFileEmbedder embedder =
+                new SqlFileEmbedder(new File(sa[0]), sa[1]);
+        String[] files = new String[sa.length - 2];
+        for (int i = 0; i < sa.length - 2; i++) {
+            files[i] = sa[i + 2];
+        }
+        try {
+            embedder.executeFiles(files);
+        } finally {
+            try {
+                embedder.getConn().close();
+            } catch (SQLException se) {
+                // Purposefully ignoring.
+                // We have done what we want and are now going to exit, so
+                // who cares.
+            }
+        }
+    }
+
+    /**
+     * Instantiates SqlFileEmbedder object and connects to specified database.
+     * <P/>
+     * N.b., you do not need to use RCData to use SqlFile.
+     * All SqlFile needs is a live Connection.
+     * I'm using RCData because it is a convenient way for a non-contained
+     * app (i.e. one that doesn't run in a 3rd party container) to get a
+     * Connection.
+     */
+    public SqlFileEmbedder(File rcFile, String urlid) throws Exception {
+        conn = (new RCData(rcFile, urlid)).getConnection();
+        conn.setAutoCommit(false);
+    }
+
+    /**
+     * Your own classes can use this method to execute SQL files.
+     * <P/>
+     * See source code for the main(String[]) method for an example of calling
+     * this method.
+     *
+     * @see #main(String[])
+     */
+    public void executeFiles(String[] fileStrings)
+            throws IOException, SqlToolError, SQLException {
+        Map<String, String> sqlVarMap = new HashMap<String, String>();
+        sqlVarMap.put("invoker", getClass().getName());
+        // This variable is pretty useless, but this should show you how to
+        // set variables which you can access inside of scripts like *{this}.
+
+        File file;
+        SqlFile sqlFile;
+        for (String fileString : fileStrings) {
+            file = new File(fileString);
+            if (!file.isFile())
+                throw new IOException("SQL file not present: "
+                        + file.getAbsolutePath());
+            sqlFile = new SqlFile(file);
+            sqlFile.setConnection(conn);
+            sqlFile.addUserVars(sqlVarMap);
+            sqlFile.execute();
+
+            // The only reason for the following two statements is so that
+            // changes made by one .sql file will effect the future SQL files.
+            // Has no effect if you only execute one SQL file.
+            conn = sqlFile.getConnection();
+            sqlVarMap = sqlFile.getUserVars();
+        }
+    }
+}
diff --git a/src/org/hsqldb/sample/Testdb.java b/src/org/hsqldb/sample/Testdb.java
new file mode 100644
index 0000000..f211469
--- /dev/null
+++ b/src/org/hsqldb/sample/Testdb.java
@@ -0,0 +1,203 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * Title:        Testdb
+ * Description:  simple hello world db example of a
+ *               standalone persistent db application
+ *
+ *               every time it runs it adds four more rows to sample_table
+ *               it does a query and prints the results to standard out
+ *
+ * Author: Karl Meissner karl@meissnersd.com
+ */
+public class Testdb {
+
+    Connection conn;                                                //our connnection to the db - presist for life of program
+
+    // we dont want this garbage collected until we are done
+    public Testdb(String db_file_name_prefix) throws Exception {    // note more general exception
+
+        // Load the HSQL Database Engine JDBC driver
+        // hsqldb.jar should be in the class path or made part of the current jar
+        Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+        // connect to the database.   This will load the db files and start the
+        // database if it is not alread running.
+        // db_file_name_prefix is used to open or create files that hold the state
+        // of the db.
+        // It can contain directory names relative to the
+        // current working directory
+        conn = DriverManager.getConnection("jdbc:hsqldb:"
+                                           + db_file_name_prefix,    // filenames
+                                           "SA",                     // username
+                                           "");                      // password
+    }
+
+    public void shutdown() throws SQLException {
+
+        Statement st = conn.createStatement();
+
+        // db writes out to files and performs clean shuts down
+        // otherwise there will be an unclean shutdown
+        // when program ends
+        st.execute("SHUTDOWN");
+        conn.close();    // if there are no other open connection
+    }
+
+//use for SQL command SELECT
+    public synchronized void query(String expression) throws SQLException {
+
+        Statement st = null;
+        ResultSet rs = null;
+
+        st = conn.createStatement();         // statement objects can be reused with
+
+        // repeated calls to execute but we
+        // choose to make a new one each time
+        rs = st.executeQuery(expression);    // run the query
+
+        // do something with the result set.
+        dump(rs);
+        st.close();    // NOTE!! if you close a statement the associated ResultSet is
+
+        // closed too
+        // so you should copy the contents to some other object.
+        // the result set is invalidated also  if you recycle an Statement
+        // and try to execute some other query before the result set has been
+        // completely examined.
+    }
+
+//use for SQL commands CREATE, DROP, INSERT and UPDATE
+    public synchronized void update(String expression) throws SQLException {
+
+        Statement st = null;
+
+        st = conn.createStatement();    // statements
+
+        int i = st.executeUpdate(expression);    // run the query
+
+        if (i == -1) {
+            System.out.println("db error : " + expression);
+        }
+
+        st.close();
+    }    // void update()
+
+    public static void dump(ResultSet rs) throws SQLException {
+
+        // the order of the rows in a cursor
+        // are implementation dependent unless you use the SQL ORDER statement
+        ResultSetMetaData meta   = rs.getMetaData();
+        int               colmax = meta.getColumnCount();
+        int               i;
+        Object            o = null;
+
+        // the result set is a cursor into the data.  You can only
+        // point to one row at a time
+        // assume we are pointing to BEFORE the first row
+        // rs.next() points to next row and returns true
+        // or false if there is no next row, which breaks the loop
+        for (; rs.next(); ) {
+            for (i = 0; i < colmax; ++i) {
+                o = rs.getObject(i + 1);    // Is SQL the first column is indexed
+
+                // with 1 not 0
+                System.out.print(o.toString() + " ");
+            }
+
+            System.out.println(" ");
+        }
+    }                                       //void dump( ResultSet rs )
+
+    public static void main(String[] args) {
+
+        Testdb db = null;
+
+        try {
+            db = new Testdb("db_file");
+        } catch (Exception ex1) {
+            ex1.printStackTrace();    // could not start db
+
+            return;                   // bye bye
+        }
+
+        try {
+
+            //make an empty table
+            //
+            // by declaring the id column IDENTITY, the db will automatically
+            // generate unique values for new rows- useful for row keys
+            db.update(
+                "CREATE TABLE sample_table ( id INTEGER IDENTITY, str_col VARCHAR(256), num_col INTEGER)");
+        } catch (SQLException ex2) {
+
+            //ignore
+            //ex2.printStackTrace();  // second time we run program
+            //  should throw execption since table
+            // already there
+            //
+            // this will have no effect on the db
+        }
+
+        try {
+
+            // add some rows - will create duplicates if run more then once
+            // the id column is automatically generated
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Ford', 100)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Toyota', 200)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('Honda', 300)");
+            db.update(
+                "INSERT INTO sample_table(str_col,num_col) VALUES('GM', 400)");
+
+            // do a query
+            db.query("SELECT * FROM sample_table WHERE num_col < 250");
+
+            // at end of program
+            db.shutdown();
+        } catch (SQLException ex3) {
+            ex3.printStackTrace();
+        }
+    }    // main()
+}    // class Testdb
+
diff --git a/src/org/hsqldb/sample/TriggerSample.java b/src/org/hsqldb/sample/TriggerSample.java
new file mode 100644
index 0000000..42831c6
--- /dev/null
+++ b/src/org/hsqldb/sample/TriggerSample.java
@@ -0,0 +1,506 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.sample;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.Trigger;
+import org.hsqldb.lib.StringUtil;
+
+// peterhudson@users 20020130 - patch 478657 by peterhudson - new class
+// fredt@users 20030727 - signature altered
+// boucherb@users 20040315 - sample updated
+
+/**
+ * <P>Sample code for use of triggers in hsqldb.
+ *
+ * This class org.hsqldb.sample package, but a typical implementation is in
+ * users's class hierarchy.
+ *
+ * SQL to invoke is:<p>
+ * CREATE TRIGGER triggerSample BEFORE|AFTER INSERT|UPDATE|DELETE
+ * ON myTable [FOR EACH ROW] [QUEUE n] [NOWAIT] CALL "myPackage.trigClass"<br>
+ *
+ * This will create a thread that will wait for its firing event to occur;
+ * when this happens, the trigger's thread runs the 'trigClass.fire'
+ * Note that this is still in the same Java Virtual Machine as the
+ * database, so make sure the fired method does not hang.<p>
+ *
+ * There is a queue of events waiting to be run by each trigger thread.
+ * This is particularly useful for 'FOR EACH ROW' triggers, when a large
+ * number of trigger events occur in rapid succession, without the trigger
+ * thread getting a chance to run. If the queue becomes full, subsequent
+ * additions to it cause the database engine to suspend awaiting space
+ * in the queue. Take great care to avoid this situation if the trigger
+ * action involves accessing the database, as deadlock will occur.
+ * This can be avoided either by ensuring the QUEUE parameter makes a large
+ * enough queue, or by using the NOWAIT parameter, which causes a new
+ * trigger event to overwrite the most recent event in the queue.
+ * The default queue size is 1024.<p>
+ *
+ * Ensure that "myPackage.trigClass" is present in the classpath which
+ * you use to start hsql.<p>
+ *
+ * If the method wants to access the database, it must establish
+ * a JDBC connection.<p>
+ *
+ * When the 'fire' method is called, it is passed the following arguments: <p>
+ *
+ * fire (int type, String trigName, String tabName, Object oldRow[],
+ *       Object[] newRow) <p>
+ *
+ * where 'type' is one of the values enumerated in the Trigger interface and
+ * the 'oldRow'/'newRow' pair represents the rows acted on. The first
+ * length - 1 array slots contain column values and the final slot contains
+ * either null or the value of the internally assigned row identity, if
+ * the concerned table has no primary key. The final slot must _never_ be
+ * modified. <p>
+ *
+ * The mapping of row classes to database types is specified in
+ * /doc/hsqlSyntax.html#Datatypes. <p>
+ *
+ * To be done:<p>
+ *
+ * <ol>
+ * <li> Implement the "jdbc:default:connection: URL to provide transparent
+ *      and portable access to internal connections for use in triggers and
+ *      stored procedures. <p>
+ *
+ * <li> Implement declaritive column to trigger method argument
+ *      mapping, conditional execution (WHEN clause), etc. <p>
+ *
+ * <li> Investigate and refine synchronous and asynchronous trigger models. <p>
+ *
+ *      Because certain combinations of trigger create parameters cause the
+ *      individual triggered actions of a multirow update to run in different
+ *      threads, it is possible for an 'after' trigger to run before its
+ *      corresponding 'before' trigger; the acceptability and implications
+ *      of this needs to be investigated, documented and the behaviour of
+ *      the engine fully specified.
+ *
+ * <li> Investigate and implement the SQL 200n specified execution stack under
+ *      arbitrary triggered action and SQL-invoked routine call graphs.
+ * </ol>
+ *
+ * @author Peter Hudson
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+public class TriggerSample implements Trigger {
+
+    static final PrintWriter out  = new PrintWriter(System.out);
+    static final String      drv  = "org.hsqldb.jdbc.JDBCDriver";
+    static final String      url  = "jdbc:hsqldb:mem:trigger-sample";
+    static final String      usr  = "SA";
+    static final String      pwd  = "";
+    static final String      impl = TriggerSample.class.getName();
+    static final String      tn   = "trig_test";
+    static final String drop_test_table_stmt = "DROP TABLE " + tn
+        + " IF EXISTS";
+    static final String create_test_table_stmt = "CREATE TABLE " + tn
+        + "(id INTEGER PRIMARY KEY, value VARCHAR(20))";
+    static final String drop_audit_table_stmt = "DROP TABLE audit IF EXISTS";
+    static final String create_audit_table_stmt = "CREATE TABLE audit("
+        + "id  INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1), "
+        + "op  VARCHAR(6), " + "tn  VARCHAR(20), " + "ors LONGVARCHAR, "
+        + "nrs LONGVARCHAR, " + "ts  TIMESTAMP DEFAULT CURRENT_TIMESTAMP)";
+    static final String audit_insert_stmt =
+        "INSERT INTO audit(op, tn, ors, nrs) VALUES(?, ?, ?, ?)";
+
+    /**
+     * A sample HSQLDB Trigger interface implementation. <p>
+     *
+     * This sample prints information about the firing trigger and records
+     * actions in an audit table. <p>
+     *
+     * The techniques used here are simplified dramatically for demonstration
+     * purposes and are in no way recommended as a model upon which to build
+     * actual installations involving triggered actions.
+     *
+     * @param typ trigger type
+     * @param trn trigger name
+     * @param tn  table name
+     * @param or  old row
+     * @param nr  new row
+     */
+    public void fire(int typ, String trn, String tn, Object[] or,
+                     Object[] nr) {
+
+        synchronized (TriggerSample.class) {
+            String ors = or == null ? "null"
+                                    : StringUtil.arrayToString(or);
+            String nrs = nr == null ? "null"
+                                    : StringUtil.arrayToString(nr);
+
+            out.println("----------------------------------------");
+            out.println(getTriggerDescriptor(trn, typ, tn));
+            out.println("old row : " + ors);
+            out.println("new row : " + nrs);
+            out.flush();
+
+            if ("TRIG_TEST".equals(tn)) {
+                switch (typ) {
+
+                    case INSERT_BEFORE_ROW : {
+
+                        // Business rule: ID shall be less than 11.
+                        // (Marti DiBergi, we love you ;-)
+                        // You can cast row[i] given your knowledge of what
+                        // the table format is:
+                        final int ID = ((Number) nr[0]).intValue();
+
+                        doAssert(ID < 11, "ID < 11");
+
+                        break;
+                    }
+                    case UPDATE_BEFORE_ROW : {
+
+                        // Business rule:  ignore update of VALUE 'unchangable'.
+                        if ("unchangable".equals(or[1])) {
+                            nr[1] = or[1];    // short-circuit the update
+                        }
+
+                        // !!!Warning!!!
+                        // The engine does not check the class of substituted
+                        // values; it's up to you to use the correct class.
+                        // For example, this will cause database curruption:
+                        //  nr[1] = new Integer(5);
+                        break;
+                    }
+                }
+            }
+
+            doAuditStep(typ, tn, ors, nrs);
+        }
+    }
+
+    private static void doAssert(boolean b, String msg) {
+
+        if (b) {
+
+            // do nothing
+        } else {
+            throw org.hsqldb.error.Error.error(ErrorCode.GENERAL_ERROR,
+                                               msg);
+        }
+    }
+
+    private static void doAuditStep(int typ, String tn, String ors,
+                                    String nrs) {
+
+        Connection        conn;
+        PreparedStatement stmt;
+
+        switch (typ) {
+
+            case INSERT_AFTER_ROW :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER_ROW : {
+                try {
+                    conn = getConnection();
+                    stmt = conn.prepareStatement(audit_insert_stmt);
+
+                    stmt.setString(1, getOperationSpec(typ));
+                    stmt.setString(2, tn);
+                    stmt.setString(3, ors);
+                    stmt.setString(4, nrs);
+                    stmt.executeUpdate();
+                    conn.close();
+                } catch (SQLException se) {
+                    se.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public static String getWhenSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_BEFORE_ROW :
+            case UPDATE_BEFORE_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "BEFORE";
+            }
+            case INSERT_AFTER :
+            case INSERT_AFTER_ROW :
+            case UPDATE_AFTER :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER :
+            case DELETE_AFTER_ROW : {
+                return "AFTER";
+            }
+            default : {
+                return "";
+            }
+        }
+    }
+
+    public static String getOperationSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_AFTER :
+            case INSERT_AFTER_ROW :
+            case INSERT_BEFORE_ROW : {
+                return "INSERT";
+            }
+            case UPDATE_AFTER :
+            case UPDATE_AFTER_ROW :
+            case UPDATE_BEFORE_ROW : {
+                return "UPDATE";
+            }
+            case DELETE_AFTER :
+            case DELETE_AFTER_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "DELETE";
+            }
+            default : {
+                return "";
+            }
+        }
+    }
+
+    public static String getQueueSpec(int qs) {
+        return (qs < 0) ? ""
+                        : ("QUEUE " + qs);
+    }
+
+    public static String getForEachSpec(int type) {
+
+        switch (type) {
+
+            case INSERT_BEFORE_ROW :
+            case INSERT_AFTER_ROW :
+            case UPDATE_BEFORE_ROW :
+            case UPDATE_AFTER_ROW :
+            case DELETE_AFTER_ROW :
+            case DELETE_BEFORE_ROW : {
+                return "FOR EACH ROW";
+            }
+            default : {
+                return "FOR EACH STATEMENT";
+            }
+        }
+    }
+
+    public static String getTriggerDDL(String trn, int typ, String tab,
+                                       int qs,
+                                       String impl) throws SQLException {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("CREATE TRIGGER ");
+        sb.append(trn);
+        sb.append(' ');
+        sb.append(getWhenSpec(typ));
+        sb.append(' ');
+        sb.append(getOperationSpec(typ));
+        sb.append(" ON ");
+        sb.append(tab);
+        sb.append(' ');
+        sb.append(getForEachSpec(typ));
+        sb.append(' ');
+        sb.append(getQueueSpec(qs));
+        sb.append(" CALL \"");
+        sb.append(impl);
+        sb.append("\"");
+
+        return sb.toString();
+    }
+
+    public static String getTriggerDescriptor(String trn, int typ,
+            String tab) {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("TRIGGER : ");
+        sb.append(trn);
+        sb.append(' ');
+        sb.append(getWhenSpec(typ));
+        sb.append(' ');
+        sb.append(getOperationSpec(typ));
+        sb.append(" ON ");
+        sb.append(tab);
+        sb.append(' ');
+        sb.append(getForEachSpec(typ));
+
+        return sb.toString();
+    }
+
+    private static Connection getConnection() throws SQLException {
+
+        try {
+            Class.forName(drv).newInstance();
+
+            return DriverManager.getConnection(url, usr, pwd);
+        } catch (SQLException se) {
+            throw se;
+        } catch (Exception e) {
+            throw new SQLException(e.toString());
+        }
+    }
+
+    private static void createTrigger(Statement stmt, String trn,
+                                      int typ) throws SQLException {
+        stmt.execute(getTriggerDDL(trn, typ, tn, 0, impl));
+    }
+
+    private static void setup() throws SQLException {
+
+        Connection conn = getConnection();
+        Statement  stmt = conn.createStatement();
+
+        stmt.execute(drop_test_table_stmt);
+        stmt.execute(create_test_table_stmt);
+        stmt.execute(drop_audit_table_stmt);
+        stmt.execute(create_audit_table_stmt);
+        createTrigger(stmt, "tibr_" + tn, INSERT_BEFORE_ROW);
+        createTrigger(stmt, "tia_" + tn, INSERT_AFTER);
+        createTrigger(stmt, "tiar_" + tn, INSERT_AFTER_ROW);
+        createTrigger(stmt, "tubr_" + tn, UPDATE_BEFORE_ROW);
+        createTrigger(stmt, "tua_" + tn, UPDATE_AFTER);
+        createTrigger(stmt, "tuar_" + tn, UPDATE_AFTER_ROW);
+        createTrigger(stmt, "tdbr_" + tn, DELETE_BEFORE_ROW);
+        createTrigger(stmt, "tda_" + tn, DELETE_AFTER);
+        createTrigger(stmt, "tdar_" + tn, DELETE_AFTER_ROW);
+        stmt.close();
+        conn.close();
+    }
+
+    private static void doSomeWork() throws SQLException {
+
+        Connection conn = getConnection();
+        Statement  stmt = conn.createStatement();
+
+        conn.setAutoCommit(false);
+        stmt.execute("INSERT INTO trig_test VALUES (1, 'hello')");
+        stmt.execute("INSERT INTO trig_test VALUES (2, 'now what?')");
+        stmt.execute("INSERT INTO trig_test VALUES (3, 'unchangable')");
+        stmt.execute("INSERT INTO trig_test VALUES (4, 'goodbye')");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.execute("UPDATE trig_test SET value = 'all done'");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.execute("DELETE FROM trig_test");
+        conn.rollback();
+        dumpTable("trig_test");
+
+        try {
+            stmt.execute("INSERT INTO trig_test VALUES(11, 'whatever')");
+        } catch (SQLException se) {
+            se.printStackTrace();
+        }
+
+        stmt.execute("INSERT INTO trig_test VALUES(10, 'whatever')");
+        conn.commit();
+        dumpTable("trig_test");
+        stmt.close();
+        conn.close();
+    }
+
+    private static void dumpTable(String tn) throws SQLException {
+
+        Connection        conn  = getConnection();
+        Statement         stmt  = conn.createStatement();
+        ResultSet         rs    = stmt.executeQuery("select * from " + tn);
+        ResultSetMetaData rsmd  = rs.getMetaData();
+        int               count = rsmd.getColumnCount();
+
+        out.println();
+        out.println("****************************************");
+        out.println("DUMP FOR TABLE: " + tn);
+        out.println("****************************************");
+        out.flush();
+
+        while (rs.next()) {
+            out.print("[");
+
+            for (int i = 1; i <= count; i++) {
+                out.print(rs.getString(i));
+
+                if (i < count) {
+                    out.print(" : ");
+                }
+            }
+
+            out.println("]");
+        }
+
+        out.println();
+        out.flush();
+        rs.close();
+        stmt.close();
+        conn.close();
+    }
+
+    private static void runSample() throws SQLException {
+
+        setup();
+        doSomeWork();
+        dumpTable("audit");
+    }
+
+    public static void main(String[] args) throws SQLException {
+        runSample();
+    }
+}
+/*
+    test SQL
+    CREATE CACHED TABLE trig_test (int_field     integer)
+    CREATE TRIGGER ins_before BEFORE INSERT ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER ins_after  AFTER  INSERT ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_before BEFORE UPDATE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_after  AFTER  UPDATE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_before_row BEFORE UPDATE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER upd_after_row  AFTER  UPDATE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_before BEFORE DELETE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_after  AFTER  DELETE ON trig_test CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_before_row BEFORE DELETE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    CREATE TRIGGER del_after_row  AFTER  DELETE ON trig_test FOR EACH ROW CALL "org.hsqldb.sample.TriggerSample"
+    INSERT INTO trig_test VALUES (1)
+    INSERT INTO trig_test VALUES (2)
+    INSERT INTO trig_test VALUES (3)
+    UPDATE trig_test SET int_field = int_field + 3
+    DELETE FROM trig_test
+ */
diff --git a/src/org/hsqldb/sample/package.html b/src/org/hsqldb/sample/package.html
new file mode 100644
index 0000000..3b7b7b4
--- /dev/null
+++ b/src/org/hsqldb/sample/package.html
@@ -0,0 +1,8 @@
+<HTML>
+<BODY>
+  Contains examples for hooking into HyperSQL from your own Java code.
+  <P/>
+  Other examples may be found in the <CODE>sample/</CODE> subdirectory of
+  your HyperSQL distribution
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/scriptio/ScriptReaderBase.java b/src/org/hsqldb/scriptio/ScriptReaderBase.java
new file mode 100644
index 0000000..0890148
--- /dev/null
+++ b/src/org/hsqldb/scriptio/ScriptReaderBase.java
@@ -0,0 +1,125 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.scriptio;
+
+import java.io.IOException;
+
+import org.hsqldb.Database;
+import org.hsqldb.NumberSequence;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.persist.PersistentStore;
+
+/**
+ * Base class for all script readers.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public abstract class ScriptReaderBase {
+
+    public static final int ANY_STATEMENT        = 1;
+    public static final int DELETE_STATEMENT     = 2;
+    public static final int INSERT_STATEMENT     = 3;
+    public static final int COMMIT_STATEMENT     = 4;
+    public static final int SESSION_ID           = 5;
+    public static final int SET_SCHEMA_STATEMENT = 6;
+    Database                database;
+    int                     lineCount;
+
+    ScriptReaderBase(Database db) {
+        this.database = db;
+    }
+
+    public void readAll(Session session) throws IOException {
+        readDDL(session);
+        readExistingData(session);
+    }
+
+    protected abstract void readDDL(Session session) throws IOException;
+
+    protected abstract void readExistingData(Session session)
+    throws IOException;
+
+    public abstract boolean readLoggedStatement(Session session)
+    throws IOException;
+
+    int             statementType;
+    int             sessionNumber;
+    boolean         sessionChanged;
+    Object[]        rowData;
+    long            sequenceValue;
+    String          statement;
+    Table           currentTable;
+    PersistentStore currentStore;
+    NumberSequence  currentSequence;
+    String          currentSchema;
+
+    public int getStatementType() {
+        return statementType;
+    }
+
+    public int getSessionNumber() {
+        return sessionNumber;
+    }
+
+    public Object[] getData() {
+        return rowData;
+    }
+
+    public String getLoggedStatement() {
+        return statement;
+    }
+
+    public NumberSequence getCurrentSequence() {
+        return currentSequence;
+    }
+
+    public long getSequenceValue() {
+        return sequenceValue;
+    }
+
+    public Table getCurrentTable() {
+        return currentTable;
+    }
+
+    public String getCurrentSchema() {
+        return currentSchema;
+    }
+
+    public int getLineNumber() {
+        return lineCount;
+    }
+
+    public abstract void close();
+}
diff --git a/src/org/hsqldb/scriptio/ScriptReaderDecode.java b/src/org/hsqldb/scriptio/ScriptReaderDecode.java
new file mode 100644
index 0000000..c6d4297
--- /dev/null
+++ b/src/org/hsqldb/scriptio/ScriptReaderDecode.java
@@ -0,0 +1,138 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.scriptio;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.zip.GZIPInputStream;
+
+import org.hsqldb.Database;
+import org.hsqldb.Session;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.persist.Crypto;
+import org.hsqldb.rowio.RowInputTextLog;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ScriptReaderDecode extends ScriptReaderText {
+
+    DataInputStream dataInput;
+    Crypto          crypto;
+    byte[]          buffer = new byte[256];
+
+    public ScriptReaderDecode(Database db, String fileName,
+                              Crypto crypto) throws IOException {
+
+        super(db);
+
+        InputStream d =
+            database.logger.getFileAccess().openInputStreamElement(fileName);
+        InputStream stream = crypto.getInputStream(d);
+
+        stream       = new GZIPInputStream(stream);
+        dataStreamIn = new BufferedReader(new InputStreamReader(stream));
+        rowIn        = new RowInputTextLog();
+    }
+
+    public ScriptReaderDecode(Database db, String fileName, Crypto crypto,
+                              boolean forLog) throws IOException {
+
+        super(db);
+
+        this.crypto = crypto;
+
+        InputStream d =
+            database.logger.getFileAccess().openInputStreamElement(fileName);
+
+        dataInput = new DataInputStream(new BufferedInputStream(d));
+        rowIn     = new RowInputTextLog();
+    }
+
+    public boolean readLoggedStatement(Session session) throws IOException {
+
+        if (dataInput == null) {
+            return super.readLoggedStatement(session);
+        }
+
+        int count;
+
+        try {
+            count = dataInput.readInt();
+
+            if (count * 2 > buffer.length) {
+                buffer = new byte[count * 2];
+            }
+
+            dataInput.readFully(buffer, 0, count);
+        } catch (Throwable t) {
+            return false;
+        }
+
+        count = crypto.decode(buffer, 0, count, buffer, 0);
+
+        String s = new String(buffer, 0, count, "ISO-8859-1");
+
+        lineCount++;
+
+//        System.out.println(lineCount);
+        statement = StringConverter.unicodeStringToString(s);
+
+        if (statement == null) {
+            return false;
+        }
+
+        processStatement(session);
+
+        return true;
+    }
+
+    public void close() {
+
+        try {
+            if (dataStreamIn != null) {
+                dataStreamIn.close();
+            }
+
+            if (dataInput != null) {
+                dataInput.close();
+            }
+        } catch (Exception e) {}
+    }
+}
diff --git a/src/org/hsqldb/scriptio/ScriptReaderText.java b/src/org/hsqldb/scriptio/ScriptReaderText.java
new file mode 100644
index 0000000..5fee920
--- /dev/null
+++ b/src/org/hsqldb/scriptio/ScriptReaderText.java
@@ -0,0 +1,287 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.scriptio;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.hsqldb.Database;
+import org.hsqldb.HsqlException;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.Session;
+import org.hsqldb.Statement;
+import org.hsqldb.StatementTypes;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.rowio.RowInputTextLog;
+import org.hsqldb.store.ValuePool;
+import org.hsqldb.types.Type;
+
+/**
+ * Handles operations involving reading back a script or log file written
+ * out by ScriptWriterText. This implementation
+ * corresponds to ScriptWriterText.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ *  @version 1.9.0
+ *  @since 1.7.2
+ */
+public class ScriptReaderText extends ScriptReaderBase {
+
+    // this is used only to enable reading one logged line at a time
+    BufferedReader  dataStreamIn;
+    RowInputTextLog rowIn;
+    boolean         isInsert;
+
+    public ScriptReaderText(Database db) {
+        super(db);
+    }
+
+    public ScriptReaderText(Database db, String fileName) throws IOException {
+
+        super(db);
+
+        InputStream d =
+            database.logger.getFileAccess().openInputStreamElement(fileName);
+
+        dataStreamIn = new BufferedReader(
+            new InputStreamReader(new BufferedInputStream(d)));
+        rowIn = new RowInputTextLog(db.databaseProperties.isVersion18());
+    }
+
+    protected void readDDL(Session session) throws IOException {
+
+        for (; readLoggedStatement(session); ) {
+            Statement cs     = null;
+            Result    result = null;
+
+            if (rowIn.getStatementType() == INSERT_STATEMENT) {
+                isInsert = true;
+
+                break;
+            }
+
+            try {
+                cs = session.compileStatement(
+                    statement, ResultProperties.defaultPropsValue);
+                result = session.executeCompiledStatement(cs,
+                        ValuePool.emptyObjectArray);
+            } catch (HsqlException e) {
+                result = Result.newErrorResult(e);
+            }
+
+            if (result.isError()) {
+
+                // handle grants on math and library routines in old versions
+                if (cs == null) {}
+                else if (cs.getType() == StatementTypes.GRANT) {
+                    continue;
+                } else if (cs.getType() == StatementTypes.CREATE_ROUTINE) {
+
+                    // ignore legacy references
+                    if (result.getMainString().contains(
+                            "org.hsqldb.Library")) {
+                        continue;
+                    }
+                }
+            }
+
+            if (result.isError()) {
+                database.logger.logWarningEvent(result.getMainString(),
+                                                result.getException());
+
+                if (cs != null
+                        && cs.getType() == StatementTypes.CREATE_ROUTINE) {
+                    continue;
+                }
+
+                throw Error.error(result.getException(),
+                                  ErrorCode.ERROR_IN_SCRIPT_FILE,
+                                  ErrorCode.M_DatabaseScriptReader_read,
+                                  new Object[] {
+                    new Integer(lineCount), result.getMainString()
+                });
+            }
+        }
+    }
+
+    protected void readExistingData(Session session) throws IOException {
+
+        try {
+            String tablename = null;
+
+            // fredt - needed for forward referencing FK constraints
+            database.setReferentialIntegrity(false);
+
+            for (; isInsert || readLoggedStatement(session);
+                    isInsert = false) {
+                if (statementType == SET_SCHEMA_STATEMENT) {
+                    session.setSchema(currentSchema);
+
+                    continue;
+                } else if (statementType == INSERT_STATEMENT) {
+                    if (!rowIn.getTableName().equals(tablename)) {
+                        tablename = rowIn.getTableName();
+
+                        String schema = session.getSchemaName(currentSchema);
+
+                        currentTable =
+                            database.schemaManager.getUserTable(session,
+                                tablename, schema);
+                        currentStore =
+                            database.persistentStoreCollection.getStore(
+                                currentTable);
+                    }
+
+                    currentTable.insertFromScript(session, currentStore,
+                                                  rowData);
+                } else {
+                    throw Error.error(ErrorCode.ERROR_IN_SCRIPT_FILE);
+                }
+            }
+
+            database.setReferentialIntegrity(true);
+        } catch (Throwable t) {
+            database.logger.logSevereEvent("readExistingData failed", t);
+
+            throw Error.error(
+                t, ErrorCode.ERROR_IN_SCRIPT_FILE,
+                ErrorCode.M_DatabaseScriptReader_read,
+                new Object[] {
+                t.getMessage(), new Integer(lineCount)
+            });
+        }
+    }
+
+    public boolean readLoggedStatement(Session session) throws IOException {
+
+        if (!sessionChanged) {
+
+            //fredt temporary solution - should read bytes directly from buffer
+            String s = dataStreamIn.readLine();
+
+            lineCount++;
+
+            //        System.out.println(lineCount);
+            statement = StringConverter.unicodeStringToString(s);
+
+            if (statement == null) {
+                return false;
+            }
+        }
+
+        processStatement(session);
+
+        return true;
+    }
+
+    void processStatement(Session session) throws IOException {
+
+        try {
+            if (statement.startsWith("/*C")) {
+                int endid = statement.indexOf('*', 4);
+
+                sessionNumber = Integer.parseInt(statement.substring(3,
+                        endid));
+                statement      = statement.substring(endid + 2);
+                sessionChanged = true;
+                statementType  = SESSION_ID;
+
+                return;
+            }
+
+            sessionChanged = false;
+
+            rowIn.setSource(statement);
+
+            statementType = rowIn.getStatementType();
+
+            if (statementType == ANY_STATEMENT) {
+                rowData      = null;
+                currentTable = null;
+
+                return;
+            } else if (statementType == COMMIT_STATEMENT) {
+                rowData      = null;
+                currentTable = null;
+
+                return;
+            } else if (statementType == SET_SCHEMA_STATEMENT) {
+                rowData       = null;
+                currentTable  = null;
+                currentSchema = rowIn.getSchemaName();
+
+                return;
+            }
+
+            String name   = rowIn.getTableName();
+            String schema = session.getCurrentSchemaHsqlName().name;
+
+            currentTable = database.schemaManager.getUserTable(session, name,
+                    schema);
+            currentStore =
+                database.persistentStoreCollection.getStore(currentTable);
+
+            Type[] colTypes;
+
+            if (statementType == INSERT_STATEMENT) {
+                colTypes = currentTable.getColumnTypes();
+            } else if (currentTable.hasPrimaryKey()) {
+                colTypes = currentTable.getPrimaryKeyTypes();
+            } else {
+                colTypes = currentTable.getColumnTypes();
+            }
+
+            try {
+                rowData = rowIn.readData(colTypes);
+            } catch (Exception e) {
+                throw e;
+            }
+        } catch (Exception e) {
+            throw JavaSystem.toIOException(e);
+        }
+    }
+
+    public void close() {
+
+        try {
+            dataStreamIn.close();
+        } catch (Exception e) {}
+    }
+}
diff --git a/src/org/hsqldb/scriptio/ScriptWriterBase.java b/src/org/hsqldb/scriptio/ScriptWriterBase.java
new file mode 100644
index 0000000..8761a78
--- /dev/null
+++ b/src/org/hsqldb/scriptio/ScriptWriterBase.java
@@ -0,0 +1,429 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.scriptio;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.hsqldb.Database;
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.NumberSequence;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.TableBase;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.FileAccess;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.HsqlTimer;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.navigator.RowIterator;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.result.Result;
+
+//import org.hsqldb.lib.StopWatch;
+
+/**
+ * @todo - can lock the database engine as readonly in a wrapper for this when
+ * used at checkpoint
+ */
+
+/**
+ * Handles all logging to file operations. A log consists of three kinds of
+ * blocks:<p>
+ *
+ * DDL BLOCK: definition of DB objects, users and rights at startup time<br>
+ * DATA BLOCK: all data for MEMORY tables at startup time<br>
+ * LOG BLOCK: SQL statements logged since startup or the last CHECKPOINT<br>
+ *
+ * The implementation of this class and its subclasses support the formats
+ * used for writing the data. Since 1.7.2 the data can also be
+ * written as binray in order to speed up shutdown and startup.<p>
+ *
+ * From 1.7.2, two separate files are used, one for the DDL + DATA BLOCK and
+ * the other for the LOG BLOCK.<p>
+ *
+ * A related use for this class is for saving a current snapshot of the
+ * database data to a user-defined file. This happens in the SHUTDOWN COMPACT
+ * process or done as a result of the SCRIPT command. In this case, the
+ * DATA block contains the CACHED table data as well.<p>
+ *
+ * DatabaseScriptReader and its subclasses read back the data at startup time.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public abstract class ScriptWriterBase implements Runnable {
+
+    Database            database;
+    String              outFile;
+    OutputStream        fileStreamOut;
+    FileAccess.FileSync outDescriptor;
+    int                 tableRowCount;
+    HsqlName            schemaToLog;
+    boolean             isClosed;
+
+    /**
+     * this determines if the script is the normal script (false) used
+     * internally by the engine or a user-initiated snapshot of the DB (true)
+     */
+    boolean          isDump;
+    boolean          includeCachedData;
+    long             byteCount;
+    volatile boolean needsSync;
+    volatile boolean forceSync;
+    volatile boolean busyWriting;
+    private int      syncCount;
+    static final int INSERT             = 0;
+    static final int INSERT_WITH_SCHEMA = 1;
+
+    /** the last schema for last sessionId */
+    Session                      currentSession;
+    public static final String[] LIST_SCRIPT_FORMATS = new String[] {
+        Tokens.T_TEXT, Tokens.T_BINARY, null, Tokens.T_COMPRESSED
+    };
+
+    ScriptWriterBase(Database db, String file, boolean includeCachedData,
+                     boolean isNewFile, boolean isDump) {
+
+        this.isDump = isDump;
+
+        initBuffers();
+
+        boolean exists = false;
+
+        if (isDump) {
+            exists = FileUtil.getFileUtil().exists(file);
+        } else {
+            exists = db.logger.getFileAccess().isStreamElement(file);
+        }
+
+        if (exists && isNewFile) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR, file);
+        }
+
+        this.database          = db;
+        this.includeCachedData = includeCachedData;
+        outFile                = file;
+        currentSession         = database.sessionManager.getSysSession();
+
+        // start with neutral schema - no SET SCHEMA to log
+        schemaToLog = currentSession.loggedSchema =
+            currentSession.currentSchema;
+
+        openFile();
+    }
+
+    public void reopen() {
+        openFile();
+    }
+
+    protected abstract void initBuffers();
+
+    /**
+     *  Called internally or externally in write delay intervals.
+     */
+    public void sync() {
+
+        if (isClosed) {
+            return;
+        }
+
+        synchronized (fileStreamOut) {
+            if (needsSync) {
+                if (busyWriting) {
+                    forceSync = true;
+
+                    return;
+                }
+
+                try {
+                    fileStreamOut.flush();
+                    outDescriptor.sync();
+
+                    syncCount++;
+                } catch (IOException e) {
+                    Error.printSystemOut("flush() or sync() error: "
+                                         + e.toString());
+                }
+
+                needsSync = false;
+                forceSync = false;
+            }
+        }
+    }
+
+    public synchronized void forceSync() {
+
+        if (isClosed) {
+            return;
+        }
+
+        synchronized (fileStreamOut) {
+            try {
+                fileStreamOut.flush();
+                outDescriptor.sync();
+
+                syncCount++;
+            }
+            catch (IOException e) {
+                Error.printSystemOut("flush() or sync() error: " + e.toString());
+            }
+
+            needsSync = false;
+            forceSync = false;
+        }
+    }
+
+    public void close() {
+
+        stop();
+
+        if (isClosed) {
+            return;
+        }
+
+        try {
+            synchronized (fileStreamOut) {
+                needsSync = false;
+                isClosed  = true;
+
+                fileStreamOut.flush();
+                outDescriptor.sync();
+                fileStreamOut.close();
+            }
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR);
+        }
+
+        byteCount = 0;
+    }
+
+    public long size() {
+        return byteCount;
+    }
+
+    public void writeAll() {
+
+        try {
+            writeDDL();
+            writeExistingData();
+            finishStream();
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.FILE_IO_ERROR);
+        }
+    }
+
+    /**
+     *  File is opened in append mode although in current usage the file
+     *  never pre-exists
+     */
+    protected void openFile() {
+
+        try {
+            FileAccess   fa  = isDump ? FileUtil.getFileUtil()
+                                      : database.logger.getFileAccess();
+            OutputStream fos = fa.openOutputStreamElement(outFile);
+
+            outDescriptor = fa.getFileSync(fos);
+            fileStreamOut = new BufferedOutputStream(fos, 2 << 12);
+        } catch (IOException e) {
+            throw Error.error(e, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_Message_Pair, new Object[] {
+                e.getMessage(), outFile
+            });
+        }
+    }
+
+    /**
+     * This is not really useful in the current usage but may be if this
+     * class is used in a different way.
+     */
+    protected void finishStream() throws IOException {}
+
+    protected void writeDDL() throws IOException {
+
+        Result ddlPart = database.getScript(!includeCachedData);
+
+        writeSingleColumnResult(ddlPart);
+    }
+
+    protected void writeExistingData() throws IOException {
+
+        // start with blank schema - SET SCHEMA to log
+        currentSession.loggedSchema = null;
+
+        Iterator schemas = database.schemaManager.allSchemaNameIterator();
+
+        while (schemas.hasNext()) {
+            String schema = (String) schemas.next();
+            Iterator tables =
+                database.schemaManager.databaseObjectIterator(schema,
+                    SchemaObject.TABLE);
+
+            while (tables.hasNext()) {
+                Table t = (Table) tables.next();
+
+                // write all memory table data
+                // write cached table data unless index roots have been written
+                // write all text table data apart from readonly text tables
+                // unless index roots have been written
+                boolean script = false;
+
+                switch (t.getTableType()) {
+
+                    case TableBase.MEMORY_TABLE :
+                        script = true;
+                        break;
+
+                    case TableBase.CACHED_TABLE :
+                        script = includeCachedData;
+                        break;
+
+                    case TableBase.TEXT_TABLE :
+                        script = includeCachedData && !t.isReadOnly();
+                        break;
+                }
+
+                try {
+                    if (script) {
+                        schemaToLog = t.getName().schema;
+
+                        writeTableInit(t);
+
+                        RowIterator it = t.rowIterator(currentSession);
+
+                        while (it.hasNext()) {
+                            writeRow(currentSession, t,
+                                     it.getNextRow().getData());
+                        }
+
+                        writeTableTerm(t);
+                    }
+                } catch (Exception e) {
+                    throw Error.error(ErrorCode.FILE_IO_ERROR, e.toString());
+                }
+            }
+        }
+
+        writeDataTerm();
+    }
+
+    protected void writeTableInit(Table t) throws IOException {}
+
+    protected void writeTableTerm(Table t) throws IOException {}
+
+    protected void writeSingleColumnResult(Result r) throws IOException {
+
+        RowSetNavigator nav = r.initialiseNavigator();
+
+        while (nav.hasNext()) {
+            Object[] data = (Object[]) nav.getNext();
+
+            writeLogStatement(currentSession, (String) data[0]);
+        }
+    }
+
+    abstract void writeRow(Session session, Table table,
+                           Object[] data) throws IOException;
+
+    protected abstract void writeDataTerm() throws IOException;
+
+    protected abstract void writeSessionIdAndSchema(Session session)
+    throws IOException;
+
+    public abstract void writeLogStatement(Session session,
+                                           String s) throws IOException;
+
+    public abstract void writeInsertStatement(Session session, Table table,
+            Object[] data) throws IOException;
+
+    public abstract void writeDeleteStatement(Session session, Table table,
+            Object[] data) throws IOException;
+
+    public abstract void writeSequenceStatement(Session session,
+            NumberSequence seq) throws IOException;
+
+    public abstract void writeCommitStatement(Session session)
+    throws IOException;
+
+    //
+    private Object timerTask;
+
+    // long write delay for scripts : 60s
+    protected volatile int writeDelay = 60000;
+
+    public void run() {
+
+        try {
+            if (writeDelay != 0) {
+                sync();
+            }
+
+            /** @todo: try to do Cache.cleanUp() here, too */
+        } catch (Exception e) {
+
+            // ignore exceptions
+            // may be InterruptedException or IOException
+        }
+    }
+
+    public void setWriteDelay(int delay) {
+        writeDelay = delay;
+    }
+
+    public void start() {
+
+        if (writeDelay > 0) {
+            timerTask = DatabaseManager.getTimer().schedulePeriodicallyAfter(0,
+                    writeDelay, this, false);
+        }
+    }
+
+    public void stop() {
+
+        if (timerTask != null) {
+            HsqlTimer.cancel(timerTask);
+
+            timerTask = null;
+        }
+    }
+
+    public int getWriteDelay() {
+        return writeDelay;
+    }
+}
diff --git a/src/org/hsqldb/scriptio/ScriptWriterEncode.java b/src/org/hsqldb/scriptio/ScriptWriterEncode.java
new file mode 100644
index 0000000..4f347a4
--- /dev/null
+++ b/src/org/hsqldb/scriptio/ScriptWriterEncode.java
@@ -0,0 +1,106 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.scriptio;
+
+import java.io.IOException;
+import java.util.zip.GZIPOutputStream;
+
+import org.hsqldb.Database;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HsqlByteArrayOutputStream;
+import org.hsqldb.persist.Crypto;
+
+/**
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @since 1.9.0
+ * @version 1.9.0
+ */
+public class ScriptWriterEncode extends ScriptWriterText {
+
+    Crypto                    crypto;
+    HsqlByteArrayOutputStream byteOut;
+
+    public ScriptWriterEncode(Database db, String file, boolean includeCached,
+                              Crypto crypto) {
+
+        super(db, file, includeCached, true, false);
+
+        try {
+            fileStreamOut = crypto.getOutputStream(fileStreamOut);
+            fileStreamOut = new GZIPOutputStream(fileStreamOut);
+        } catch (IOException e) {
+            throw Error.error(e, ErrorCode.FILE_IO_ERROR,
+                              ErrorCode.M_Message_Pair, new Object[] {
+                e.getMessage(), outFile
+            });
+        }
+    }
+
+    public ScriptWriterEncode(Database db, String file, Crypto crypto) {
+
+        super(db, file, false, false, false);
+
+        this.crypto = crypto;
+        byteOut     = new HsqlByteArrayOutputStream();
+    }
+
+    protected void finishStream() throws IOException {
+
+        if (fileStreamOut instanceof GZIPOutputStream) {
+            ((GZIPOutputStream) fileStreamOut).finish();
+        }
+
+        fileStreamOut.flush();
+    }
+
+    void writeRowOutToFile() throws IOException {
+
+        synchronized (fileStreamOut) {
+            if (byteOut == null) {
+                super.writeRowOutToFile();
+
+                return;
+            }
+
+            int count = crypto.getEncodedSize(rowOut.size());
+            byteOut.ensureRoom(count + 4);
+
+            count = crypto.encode(rowOut.getBuffer(), 0, rowOut.size(),
+                                      byteOut.getBuffer(), 4);
+            byteOut.setPosition(0);
+            byteOut.writeInt(count);
+            fileStreamOut.write(byteOut.getBuffer(), 0, count + 4);
+        }
+    }
+}
diff --git a/src/org/hsqldb/scriptio/ScriptWriterText.java b/src/org/hsqldb/scriptio/ScriptWriterText.java
new file mode 100644
index 0000000..7e25964
--- /dev/null
+++ b/src/org/hsqldb/scriptio/ScriptWriterText.java
@@ -0,0 +1,306 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.scriptio;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import org.hsqldb.Database;
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.NumberSequence;
+import org.hsqldb.Session;
+import org.hsqldb.Table;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.rowio.RowOutputTextLog;
+
+/**
+ * Handles all scripting and logging operations. A script consists of two blocks:<p>
+ *
+ * DDL: SQL statements for table and user definitions
+ * DATA: INSERT statements for memory tables
+ *
+ * This happens as part of the CHECKPOINT and SHUTDOWN COMPACT
+ * process. In this case, the
+ * DATA block contains the CACHED table data as well.<p>
+ *
+ * A related use for this class is for saving a current snapshot of the
+ * database data to a user-defined file with the SCRIPT command
+ *
+ * A log consists of SQL statements of different types. Each statement is
+ * encoded as ASCII and saved.
+ *
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class ScriptWriterText extends ScriptWriterBase {
+
+    RowOutputTextLog rowOut;
+
+    /** @todo - perhaps move this global into a lib utility class */
+    public static byte[] BYTES_LINE_SEP;
+    static byte[]        BYTES_COMMIT;
+    static byte[]        BYTES_INSERT_INTO;
+    static byte[]        BYTES_VALUES;
+    static byte[]        BYTES_TERM;
+    static byte[]        BYTES_DELETE_FROM;
+    static byte[]        BYTES_WHERE;
+    static byte[]        BYTES_SEQUENCE;
+    static byte[]        BYTES_SEQUENCE_MID;
+    static byte[]        BYTES_C_ID_INIT;
+    static byte[]        BYTES_C_ID_TERM;
+    static byte[]        BYTES_SCHEMA;
+
+    static {
+        String sLineSep = System.getProperty("line.separator", "\n");
+
+        try {
+            BYTES_LINE_SEP     = sLineSep.getBytes();
+            BYTES_COMMIT       = "COMMIT".getBytes("ISO-8859-1");
+            BYTES_INSERT_INTO  = "INSERT INTO ".getBytes("ISO-8859-1");
+            BYTES_VALUES       = " VALUES(".getBytes("ISO-8859-1");
+            BYTES_TERM         = ")".getBytes("ISO-8859-1");
+            BYTES_DELETE_FROM  = "DELETE FROM ".getBytes("ISO-8859-1");
+            BYTES_WHERE        = " WHERE ".getBytes("ISO-8859-1");
+            BYTES_SEQUENCE     = "ALTER SEQUENCE ".getBytes("ISO-8859-1");
+            BYTES_SEQUENCE_MID = " RESTART WITH ".getBytes("ISO-8859-1");
+            BYTES_C_ID_INIT    = "/*C".getBytes("ISO-8859-1");
+            BYTES_C_ID_TERM    = "*/".getBytes("ISO-8859-1");
+            BYTES_SCHEMA       = "SET SCHEMA ".getBytes("ISO-8859-1");
+        } catch (UnsupportedEncodingException e) {
+            Error.runtimeError(ErrorCode.U_S0500, "ScriptWriterText");
+        }
+    }
+
+    public ScriptWriterText(Database db, String file,
+                            boolean includeCachedData, boolean newFile,
+                            boolean isDump) {
+        super(db, file, includeCachedData, newFile, isDump);
+    }
+
+    protected void initBuffers() {
+        rowOut = new RowOutputTextLog();
+    }
+
+    protected void writeDataTerm() throws IOException {}
+
+    protected void writeSessionIdAndSchema(Session session) throws IOException {
+
+        if (session == null) {
+            return;
+        }
+
+        if (session != currentSession) {
+            rowOut.reset();
+            rowOut.write(BYTES_C_ID_INIT);
+            rowOut.writeLong(session.getId());
+            rowOut.write(BYTES_C_ID_TERM);
+
+            currentSession = session;
+            writeRowOutToFile();
+
+            byteCount   += rowOut.size();
+        }
+
+        if (schemaToLog != session.loggedSchema) {
+            rowOut.reset();
+            writeSchemaStatement(schemaToLog);
+
+            session.loggedSchema = schemaToLog;
+            writeRowOutToFile();
+
+            byteCount   += rowOut.size();
+        }
+    }
+
+    private void writeSchemaStatement(HsqlName schema) {
+
+        rowOut.write(BYTES_SCHEMA);
+        rowOut.writeString(schema.statementName);
+        rowOut.write(BYTES_LINE_SEP);
+    }
+
+    public void writeLogStatement(Session session,
+                                  String s) throws IOException {
+
+        schemaToLog = session.currentSchema;
+        busyWriting = true;
+
+        writeSessionIdAndSchema(session);
+        rowOut.reset();
+        rowOut.writeString(s);
+        rowOut.write(BYTES_LINE_SEP);
+        writeRowOutToFile();
+
+        byteCount   += rowOut.size();
+        needsSync   = true;
+        busyWriting = false;
+
+        if (forceSync) {
+            sync();
+        }
+    }
+
+    protected void writeRow(Session session, Table table,
+                            Object[] data) throws IOException {
+
+        schemaToLog = table.getName().schema;
+        busyWriting = true;
+
+        writeSessionIdAndSchema(session);
+        rowOut.reset();
+        ((RowOutputTextLog) rowOut).setMode(RowOutputTextLog.MODE_INSERT);
+        rowOut.write(BYTES_INSERT_INTO);
+        rowOut.writeString(table.getName().statementName);
+        rowOut.write(BYTES_VALUES);
+        rowOut.writeData(data, table.getColumnTypes());
+        rowOut.write(BYTES_TERM);
+        rowOut.write(BYTES_LINE_SEP);
+        writeRowOutToFile();
+
+        byteCount   += rowOut.size();
+        busyWriting = false;
+
+        if (forceSync) {
+            sync();
+        }
+    }
+
+    protected void writeTableInit(Table t) throws IOException {
+
+        if (t.isEmpty(currentSession)) {
+            return;
+        }
+
+        if (schemaToLog == currentSession.loggedSchema) {
+            return;
+        }
+
+        rowOut.reset();
+        writeSchemaStatement(t.getName().schema);
+        writeRowOutToFile();
+
+        currentSession.loggedSchema = schemaToLog;
+    }
+
+    public void writeInsertStatement(Session session, Table table,
+                                     Object[] data) throws IOException {
+
+        schemaToLog = table.getName().schema;
+
+        writeRow(session, table, data);
+    }
+
+    public void writeDeleteStatement(Session session, Table table,
+                                     Object[] data) throws IOException {
+
+        schemaToLog = table.getName().schema;
+        busyWriting = true;
+
+        writeSessionIdAndSchema(session);
+        rowOut.reset();
+        ((RowOutputTextLog) rowOut).setMode(RowOutputTextLog.MODE_DELETE);
+        rowOut.write(BYTES_DELETE_FROM);
+        rowOut.writeString(table.getName().statementName);
+        rowOut.write(BYTES_WHERE);
+        rowOut.writeData(table.getColumnCount(), table.getColumnTypes(), data,
+                         table.columnList, table.getPrimaryKey());
+        rowOut.write(BYTES_LINE_SEP);
+        writeRowOutToFile();
+
+        byteCount   += rowOut.size();
+        busyWriting = false;
+
+        if (forceSync) {
+            sync();
+        }
+    }
+
+    public void writeSequenceStatement(Session session,
+                                       NumberSequence seq) throws IOException {
+
+        schemaToLog = seq.getName().schema;
+        busyWriting = true;
+
+        writeSessionIdAndSchema(session);
+        rowOut.reset();
+        rowOut.write(BYTES_SEQUENCE);
+        rowOut.writeString(seq.getSchemaName().statementName);
+        rowOut.write('.');
+        rowOut.writeString(seq.getName().statementName);
+        rowOut.write(BYTES_SEQUENCE_MID);
+        rowOut.writeLong(seq.peek());
+        rowOut.write(BYTES_LINE_SEP);
+        writeRowOutToFile();
+
+        byteCount   += rowOut.size();
+        needsSync   = true;
+        busyWriting = false;
+
+        if (forceSync) {
+            sync();
+        }
+    }
+
+    public void writeCommitStatement(Session session) throws IOException {
+
+        busyWriting = true;
+
+        writeSessionIdAndSchema(session);
+        rowOut.reset();
+        rowOut.write(BYTES_COMMIT);
+        rowOut.write(BYTES_LINE_SEP);
+        writeRowOutToFile();
+
+        byteCount   += rowOut.size();
+        needsSync   = true;
+        busyWriting = false;
+
+        if (forceSync || writeDelay == 0) {
+            sync();
+        }
+    }
+
+    protected void finalize() {
+        sync();
+    }
+
+    void writeRowOutToFile() throws IOException {
+
+        synchronized (fileStreamOut) {
+            fileStreamOut.write(rowOut.getBuffer(), 0, rowOut.size());
+        }
+    }
+}
diff --git a/src/org/hsqldb/server/HsqlServerFactory.java b/src/org/hsqldb/server/HsqlServerFactory.java
new file mode 100644
index 0000000..c1816fb
--- /dev/null
+++ b/src/org/hsqldb/server/HsqlServerFactory.java
@@ -0,0 +1,91 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.sql.SQLException;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.HsqlException;
+import org.hsqldb.jdbc.Util;
+import org.hsqldb.persist.HsqlProperties;
+
+// fredt@users 20020215 - patch 461556 by paul-h@users - modified
+// minor changes to support the new HsqlServerProperties class
+// boucherb@users 20030501 - Server now implements HsqlSocketRequestHandler
+
+/**
+ * HsqlServerFactory
+ *
+ * @author paul-h@users
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+public class HsqlServerFactory {
+
+    private HsqlServerFactory() {}
+
+    public static HsqlSocketRequestHandler createHsqlServer(String dbFilePath,
+            boolean debugMessages, boolean silentMode) throws SQLException {
+
+        HsqlProperties props = new HsqlProperties();
+
+        props.setProperty("server.database.0", dbFilePath);
+        props.setProperty("server.trace", debugMessages);
+        props.setProperty("server.silent", silentMode);
+
+        Server server = new Server();
+
+        try {
+            server.setProperties(props);
+        } catch (Exception e) {
+            throw new SQLException("Failed to set server properties: " + e);
+        }
+
+        if (!server.openDatabases()) {
+            Throwable t = server.getServerError();
+
+            if (t instanceof HsqlException) {
+                throw Util.sqlException((HsqlException) t);
+            } else {
+
+                throw Util.sqlException(Error.error(ErrorCode.GENERAL_ERROR));
+            }
+        }
+
+        server.setState(ServerConstants.SERVER_STATE_ONLINE);
+
+        // Server now implements HsqlSocketRequestHandler,
+        // so there's really no need for HsqlSocketRequestHandlerImpl
+        return server;
+    }
+}
diff --git a/src/org/hsqldb/server/HsqlSocketFactory.java b/src/org/hsqldb/server/HsqlSocketFactory.java
new file mode 100644
index 0000000..6fcc220
--- /dev/null
+++ b/src/org/hsqldb/server/HsqlSocketFactory.java
@@ -0,0 +1,203 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/**
+ * Base class for producing the Socket objects used by HSQLDB.
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ * @author boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class HsqlSocketFactory {
+
+// ----------------------------- static members ---------------------------------
+    private static HsqlSocketFactory plainImpl;
+    private static HsqlSocketFactory sslImpl;
+
+// ------------------------------ constructors ---------------------------------
+
+    /**
+     * External construction disabled.  New factory instances are retreived
+     * through the newHsqlSocketFactory method instead.
+     */
+    protected HsqlSocketFactory() throws Exception {}
+
+// ------------------------- factory builder method ----------------------------
+
+    /**
+     * Retrieves an HsqlSocketFactory whose subclass and attributes are
+     * determined by the specified argument, tls.
+     *
+     * @param tls whether to retrieve a factory producing SSL sockets
+     * @throws Exception if the new factory cannot be constructed or is
+     *      of the wrong type
+     * @return a new factory
+     */
+    public static HsqlSocketFactory getInstance(boolean tls)
+    throws Exception {
+        return tls ? getSSLImpl()
+                   : getPlainImpl();
+    }
+
+// -------------------------- public instance methods --------------------------
+    public void configureSocket(Socket socket) {
+
+        // default: do nothing
+    }
+
+    /**
+     * Returns a server socket bound to the specified port.
+     * The socket is configured with the socket options
+     * given to this factory.
+     *
+     * @return the ServerSocket
+     * @param port the port to which to bind the ServerSocket
+     * @throws Exception if a network error occurs
+     */
+    public ServerSocket createServerSocket(int port) throws Exception {
+        return new ServerSocket(port);
+    }
+
+    /**
+     * Returns a server socket bound to the specified port.
+     * The socket is configured with the socket options
+     * given to this factory.
+     *
+     * @return the ServerSocket
+     * @param port the port to which to bind the ServerSocket
+     * @throws Exception if a network error occurs
+     */
+    public ServerSocket createServerSocket(int port,
+                                           String address) throws Exception {
+        return new ServerSocket(port, 128, InetAddress.getByName(address));
+    }
+
+    /**
+     * Creates a socket and connects it to the specified remote host at the
+     * specified remote port. This socket is configured using the socket options
+     * established for this factory.
+     *
+     * @return the socket
+     * @param host the server host
+     * @param port the server port
+     * @throws Exception if a network error occurs
+     */
+    public Socket createSocket(String host, int port) throws Exception {
+        return new Socket(host, port);
+    }
+
+    /**
+     * Retrieves whether this factory produces secure sockets.
+     *
+     * @return true if this factory produces secure sockets
+     */
+    public boolean isSecure() {
+        return false;
+    }
+
+// ------------------------ static utility methods -----------------------------
+    private static HsqlSocketFactory getPlainImpl() throws Exception {
+
+        synchronized (HsqlSocketFactory.class) {
+            if (plainImpl == null) {
+                plainImpl = new HsqlSocketFactory();
+            }
+        }
+
+        return plainImpl;
+    }
+
+    private static HsqlSocketFactory getSSLImpl() throws Exception {
+
+        synchronized (HsqlSocketFactory.class) {
+            if (sslImpl == null) {
+                sslImpl = newFactory("org.hsqldb.server.HsqlSocketFactorySecure");
+            }
+        }
+
+        return sslImpl;
+    }
+
+    /**
+     * Retrieves a new HsqlSocketFactory whose class
+     * is determined by the implClass argument. The basic contract here
+     * is that implementations constructed by this method should return
+     * true upon calling isSecure() iff they actually create secure sockets.
+     * There is no way to guarantee this directly here, so it is simply
+     * trusted that an  implementation is secure if it returns true
+     * for calls to isSecure();
+     *
+     * @return a new secure socket factory
+     * @param implClass the fully qaulified name of the desired
+     *      class to construct
+     * @throws Exception if a new secure socket factory cannot
+     *      be constructed
+     */
+    private static HsqlSocketFactory newFactory(String implClass)
+    throws Exception {
+
+        Class       clazz;
+        Constructor ctor;
+        Class[]     ctorParm;
+        Object[]    ctorArg;
+        Object      factory;
+
+        clazz    = Class.forName(implClass);
+        ctorParm = new Class[0];
+
+        // protected constructor
+        ctor    = clazz.getDeclaredConstructor(ctorParm);
+        ctorArg = new Object[0];
+
+        try {
+            factory = ctor.newInstance(ctorArg);
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getTargetException();
+
+            throw (t instanceof Exception) ? ((Exception) t)
+                                           : new RuntimeException(
+                                               t.toString());
+        }
+
+        return (HsqlSocketFactory) factory;
+    }
+
+// --
+}
diff --git a/src/org/hsqldb/server/HsqlSocketFactorySecure.java b/src/org/hsqldb/server/HsqlSocketFactorySecure.java
new file mode 100644
index 0000000..e38014e
--- /dev/null
+++ b/src/org/hsqldb/server/HsqlSocketFactorySecure.java
@@ -0,0 +1,387 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.security.cert.X509Certificate;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+
+/**
+ * The default secure socket factory implementation.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ *
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public final class HsqlSocketFactorySecure extends HsqlSocketFactory
+implements HandshakeCompletedListener {
+
+// --------------------------------- members -----------------------------------
+
+    /** The underlying socket factory implementation. */
+    protected Object socketFactory;
+
+    /** The underlying server socket factory implementation. */
+    protected Object serverSocketFactory;
+
+    /**
+     * Monitor object to guard against conncurrent modification
+     * of the underlying socket factory implementation member.
+     */
+    protected final Object socket_factory_mutex = new Object();
+
+    /**
+     * Monitor object to guard against concurrent modification of
+     * the underlying server socket factory implementation member.
+     */
+    protected final Object server_socket_factory_mutex = new Object();
+
+// ------------------------------ constructors ---------------------------------
+
+    /**
+     * External construction disabled.  New factory instances are retreived
+     * through the newHsqlSocketFactory method instead.
+     */
+    protected HsqlSocketFactorySecure() throws Exception {
+
+        super();
+
+        Provider p;
+        String   cls;
+
+        if (Security.getProvider("SunJSSE") == null) {
+            try {
+                p = (Provider) Class.forName(
+                    "com.sun.net.ssl.internal.ssl.Provider").newInstance();
+
+                Security.addProvider(p);
+            } catch (Exception e) {}
+        }
+    }
+
+// ----------------------------- subclass overrides ----------------------------
+    public void configureSocket(Socket socket) {
+
+        SSLSocket s;
+
+        super.configureSocket(socket);
+
+        s = (SSLSocket) socket;
+
+        s.addHandshakeCompletedListener(this);
+    }
+
+    /**
+     * Creates a secure server socket bound to the specified port.
+     * The socket is configured with the socket options
+     * given to this factory.
+     *
+     * @return the secure ServerSocket
+     * @param port the port to which to bind the secure ServerSocket
+     * @throws Exception if a network or security provider error occurs
+     */
+    public ServerSocket createServerSocket(int port) throws Exception {
+
+        SSLServerSocket ss;
+
+        ss = (SSLServerSocket) getServerSocketFactoryImpl()
+            .createServerSocket(port);
+
+        if (Error.TRACESYSTEMOUT) {
+            Error.printSystemOut("[" + this + "]: createServerSocket()");
+            Error.printSystemOut("capabilities for " + ss + ":");
+            Error.printSystemOut("----------------------------");
+            dump("supported cipher suites", ss.getSupportedCipherSuites());
+            dump("enabled cipher suites", ss.getEnabledCipherSuites());
+        }
+
+        return ss;
+    }
+
+    /**
+     * Creates a secure server socket bound to the specified port.
+     * The socket is configured with the socket options
+     * given to this factory.
+     *
+     * @return the secure ServerSocket
+     * @param port the port to which to bind the secure ServerSocket
+     * @throws Exception if a network or security provider error occurs
+     */
+    public ServerSocket createServerSocket(int port,
+                                           String address) throws Exception {
+
+        SSLServerSocket ss;
+        InetAddress     addr;
+
+        addr = InetAddress.getByName(address);
+        ss = (SSLServerSocket) getServerSocketFactoryImpl()
+            .createServerSocket(port, 128, addr);
+
+        if (Error.TRACE) {
+            Error.printSystemOut("[" + this + "]: createServerSocket()");
+            Error.printSystemOut("capabilities for " + ss + ":");
+            Error.printSystemOut("----------------------------");
+            dump("supported cipher suites", ss.getSupportedCipherSuites());
+            dump("enabled cipher suites", ss.getEnabledCipherSuites());
+        }
+
+        return ss;
+    }
+
+    private static void dump(String title, String[] as) {
+
+        Error.printSystemOut(title);
+        Error.printSystemOut("----------------------------");
+
+        for (int i = 0; i < as.length; i++) {
+            Error.printSystemOut(String.valueOf(as[i]));
+        }
+
+        Error.printSystemOut("----------------------------");
+    }
+
+    /**
+     * Creates a secure Socket and connects it to the specified remote host
+     * at the specified remote port. This socket is configured using the
+     * socket options established for this factory.
+     *
+     * @return the socket
+     * @param host the server host
+     * @param port the server port
+     * @throws Exception if a network or security provider error occurs
+     */
+    public Socket createSocket(String host, int port) throws Exception {
+
+        SSLSocket socket;
+
+        socket = (SSLSocket) getSocketFactoryImpl().createSocket(host, port);
+
+        socket.addHandshakeCompletedListener(this);
+        socket.startHandshake();
+
+// unsaved@users
+// For https protocol, the protocol handler should do this verification
+// (Sun's implementation does), but if we do not use the Protocol
+// handler (which is only available in Java >= 1.4), then we need to do
+// the verification: hostname == cert CN
+//
+// boucherb@users 20030503:
+// CHEKME/TODO:
+//
+// Stricter verify?  Either require SunJSSE (assume its trust manager properly
+// verifies whole chain), or implement our own TrustManager layer?
+//
+// What about v1/v3 and signing checks (re: man-in-the-middle attack),
+// CRL check, basic constraints? notBefore? notAfter?
+//
+// Reference:  http://www.securitytracker.com/alerts/2002/Aug/1005030.html
+//
+// That is, we can't guarantee that installed/prefered provider trust manager
+// implementations verify the whole chain properly and there are still
+// v1 certs out there (i.e. have no basic constraints, etc.), meaning that
+// we should check for and reject any intermediate certs that are not v3+
+// (cannot be checked for basic constraints).  Only root and intermediate
+// certs found in the trust store should be allowed to be v1 (since we must
+// be trusing them for them to be there).  All other intermediate signers,
+// however, should be required to be v3+, otherwise anybody with any kind
+// of cert issued somehow via a trust chain from the root can pose as an
+// intermediate signing CA and hence leave things open to man-in-the-middle
+// style attack.  Also, we should really check CRLs, just in case
+// it turns out that trust chain has been breached and thus issuer has revoked
+// on some cert(s).  Of course, this really begs the question, as it is not
+// guaranteed that all CAs in trust store have valid, working CRL URL
+//
+// So what to do?
+//
+// Maybe best to leave this all up to DBA?
+        verify(host, socket.getSession());
+
+        return socket;
+    }
+
+    /**
+     * Retrieves whether this factory produces secure sockets.
+     *
+     * @return true iff this factory creates secure sockets
+     */
+    public boolean isSecure() {
+        return true;
+    }
+
+// ----------------------- internal implementation -----------------------------
+
+    /**
+     * Retrieves the underlying javax.net.ssl.SSLServerSocketFactory.
+     *
+     * @throws Exception if there is a problem retrieving the
+     *      underlying factory
+     * @return the underlying javax.net.ssl.SSLServerSocketFactory
+     */
+    protected SSLServerSocketFactory getServerSocketFactoryImpl()
+    throws Exception {
+
+        Object factory;
+
+        synchronized (server_socket_factory_mutex) {
+            factory = serverSocketFactory;
+
+            if (factory == null) {
+                factory             = SSLServerSocketFactory.getDefault();
+                serverSocketFactory = factory;
+            }
+        }
+
+        return (SSLServerSocketFactory) factory;
+    }
+
+    /**
+     * Retrieves the underlying javax.net.ssl.SSLSocketFactory.
+     *
+     * @throws Exception if there is a problem retrieving the
+     *      underlying factory
+     * @return the underlying javax.net.ssl.SSLSocketFactory
+     */
+    protected SSLSocketFactory getSocketFactoryImpl() throws Exception {
+
+        Object factory;
+
+        synchronized (socket_factory_mutex) {
+            factory = socketFactory;
+
+            if (factory == null) {
+                factory       = SSLSocketFactory.getDefault();
+                socketFactory = factory;
+            }
+        }
+
+        return (SSLSocketFactory) factory;
+    }
+
+    /**
+     * Verifyies the certificate chain presented by the server to which
+     * a secure Socket has just connected.  Specifically, the provided host
+     * name is checked against the Common Name of the server certificate;
+     * additional checks may or may not be performed.
+     *
+     * @param host the requested host name
+     * @param session SSLSession used on the connection to host
+     * @throws Exception if the certificate chain cannot be verified
+     */
+    protected void verify(String host, SSLSession session) throws Exception {
+
+        X509Certificate[] chain;
+        X509Certificate   certificate;
+        Principal         principal;
+        PublicKey         publicKey;
+        String            DN;
+        String            CN;
+        int               start;
+        int               end;
+        String            emsg;
+
+        chain       = session.getPeerCertificateChain();
+        certificate = chain[0];
+        principal   = certificate.getSubjectDN();
+        DN          = String.valueOf(principal);
+        start       = DN.indexOf("CN=");
+
+        if (start < 0) {
+            throw new UnknownHostException(
+                Error.getMessage(ErrorCode.M_SERVER_SECURE_VERIFY_1));
+        }
+
+        start += 3;
+        end   = DN.indexOf(',', start);
+        CN    = DN.substring(start, (end > -1) ? end
+                                               : DN.length());
+
+        if (CN.length() < 1) {
+            throw new UnknownHostException(
+                Error.getMessage(ErrorCode.M_SERVER_SECURE_VERIFY_2));
+        }
+
+        if (!CN.equalsIgnoreCase(host)) {
+
+            // TLS_HOSTNAME_MISMATCH
+            throw new UnknownHostException(
+                Error.getMessage(
+                    ErrorCode.M_SERVER_SECURE_VERIFY_3, 0,
+                    new Object[] {
+                CN, host
+            }));
+        }
+    }
+
+    public void handshakeCompleted(HandshakeCompletedEvent evt) {
+
+        SSLSession session;
+        String     sessionId;
+        SSLSocket  socket;
+
+        if (Error.TRACE) {
+            socket  = evt.getSocket();
+            session = evt.getSession();
+
+            Error.printSystemOut("SSL handshake completed:");
+            Error.printSystemOut(
+                "------------------------------------------------");
+            Error.printSystemOut("socket:      : " + socket);
+            Error.printSystemOut("cipher suite : "
+                                 + session.getCipherSuite());
+
+            sessionId = StringConverter.byteArrayToHexString(session.getId());
+
+            Error.printSystemOut("session id   : " + sessionId);
+            Error.printSystemOut(
+                "------------------------------------------------");
+        }
+    }
+}
diff --git a/src/org/hsqldb/server/HsqlSocketRequestHandler.java b/src/org/hsqldb/server/HsqlSocketRequestHandler.java
new file mode 100644
index 0000000..18ff5a0
--- /dev/null
+++ b/src/org/hsqldb/server/HsqlSocketRequestHandler.java
@@ -0,0 +1,51 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.net.Socket;
+
+/**
+ * Interface HsqlSocketRequestHandler
+ *
+ * @author paul-h@users
+ * @version 1.70
+ * @since 1.7.0
+ * @see Server
+ */
+
+// fredt@users - patch 461556 by paul-h@users
+public interface HsqlSocketRequestHandler {
+
+    void handleConnection(Socket socket);
+
+    void signalCloseAllServerConnections();
+}
diff --git a/src/org/hsqldb/server/OdbcPacketInputStream.java b/src/org/hsqldb/server/OdbcPacketInputStream.java
new file mode 100644
index 0000000..688cd89
--- /dev/null
+++ b/src/org/hsqldb/server/OdbcPacketInputStream.java
@@ -0,0 +1,226 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.types.BinaryData;
+
+/**
+ * An atomic transfer packet received from a HyperSQL client.
+ *
+ * Since we read and cache all data for the packet upon instantiation, the
+ * available method is reliable and may be relied upon.
+ *
+ * @see #available()
+ */
+class OdbcPacketInputStream extends DataInputStream {
+    char packetType;
+    private InputStream bufferStream;
+
+    /**
+     * Instantiate a packet of the specified type and size.
+     */
+    static OdbcPacketInputStream newOdbcPacketInputStream(
+    char cType, InputStream streamSource, int sizeInt) throws IOException {
+        return newOdbcPacketInputStream(
+            cType, streamSource, new Integer(sizeInt));
+    }
+
+    /**
+     * Instantiate a packet of the specified type, with size determined by
+     * the first int read from the given stream.
+     */
+    static OdbcPacketInputStream newOdbcPacketInputStream(
+    char cType, InputStream streamSource) throws IOException {
+        return newOdbcPacketInputStream(cType, streamSource, null);
+    }
+
+    static private OdbcPacketInputStream newOdbcPacketInputStream(
+    char cType, InputStream streamSource, Integer packetSizeObj)
+    throws IOException {
+        int bytesRead, i;
+        int packetSize = 0;
+
+        if (packetSizeObj == null) {
+            byte[] fourBytes = new byte[4];
+            bytesRead = 0;
+            while ((i = streamSource.read(fourBytes, bytesRead,
+                fourBytes.length - bytesRead)) > 0) {
+                bytesRead += i;
+            }
+            if (bytesRead != fourBytes.length) {
+                throw new EOFException("Failed to read size header int");
+            }
+            packetSize =
+                ((fourBytes[0] & 0xff) << 24) + ((fourBytes[1] & 0xff) <<16)
+                + ((fourBytes[2] & 0xff) << 8) + (fourBytes[3] & 0xff) - 4;
+            // Minus 4 because this counts the size int itself.
+        } else {
+            packetSize = packetSizeObj.intValue();
+        }
+        byte[] xferBuffer = new byte[packetSize];
+        bytesRead = 0;
+        while ((i = streamSource.read(xferBuffer, bytesRead,
+            xferBuffer.length - bytesRead)) > 0) {
+            bytesRead += i;
+        }
+        if (bytesRead != xferBuffer.length) {
+            throw new EOFException (
+                    "Failed to read packet contents from given stream");
+        }
+        return new OdbcPacketInputStream(
+            cType, new ByteArrayInputStream(xferBuffer));
+    }
+
+    private OdbcPacketInputStream(char packetType, InputStream bufferStream) {
+        super(bufferStream);
+        this.packetType = packetType;
+    }
+
+    /**
+     * Generate a String/String Map from null-terminated String pairs, until
+     * a '\0' character is read in place of the first key character.
+     *
+     * @return the generated Map
+     * @throws EOFException if the rest of packet does not contained the
+     *                   required, well-formed null-terminated string pairs.
+     */
+    Map readStringPairs() throws IOException {
+        String key;
+        Map map = new HashMap();
+        while (true) {
+            key = readString();
+            if (key.length() < 1) {
+                break;
+            }
+            map.put(key, readString());
+        }
+        return map;
+    }
+
+    /**
+     * Reads a NULL-TERMINATED String.
+     *
+     * @throws IOException if attempt to read past end of packet.
+     */
+    String readString() throws IOException {
+        /* Would be MUCH easier to do this with Java6's String
+         * encoding/decoding operations */
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        baos.write((byte) 'X');
+        baos.write((byte) 'X');
+        // Place-holders to be replaced with short length
+
+        int i;
+        while ((i = readByte()) > 0) {
+            baos.write((byte) i);
+        }
+        byte[] ba = baos.toByteArray();
+        baos.close();
+
+        int len = ba.length - 2;
+        ba[0] = (byte) (len >>> 8);
+        ba[1] = (byte) len;
+
+        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(ba));
+        String s = dis.readUTF();
+        //String s = DataInputStream.readUTF(dis);
+        // TODO:  Test the previous two to see if one works better for
+        // high-order characters.
+        dis.close();
+        return s;
+    }
+
+    BinaryData readSizedBinaryData() throws IOException {
+        int len = readInt();
+        try {
+            return (len < 0) ? null : new BinaryData((long) len, this);
+        } catch (HsqlException he) {
+            throw new IOException(he.getMessage());
+        }
+    }
+
+    String readSizedString() throws IOException {
+        int len = readInt();
+        return (len < 0) ? null : readString(len);
+    }
+
+    /**
+     * These Strings are not null-terminated.
+     *
+     * @param len Bytes to read (not necessarily characters to be returned!
+     * @throws IOException if attempt to read past end of packet.
+     */
+    String readString(int len) throws IOException {
+        /* Would be MUCH easier to do this with Java6's String
+         * encoding/decoding operations */
+        int bytesRead = 0;
+        int i;
+        byte[] ba = new byte[len + 2];
+        ba[0] = (byte) (len >>> 8);
+        ba[1] = (byte) len;
+        while ((i = read(ba, 2 + bytesRead, len - bytesRead)) > -1
+            && bytesRead < len) {
+            bytesRead += i;
+        }
+        if (bytesRead != len) {
+            throw new EOFException("Packet ran dry");
+        }
+        for (i = 2; i < ba.length - 1; i++) {
+            if (ba[i] == 0) {
+                throw new RuntimeException(
+                        "Null internal to String at offset " + (i - 2));
+            }
+        }
+
+        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(ba));
+        String s = dis.readUTF();
+        //String s = DataInputStream.readUTF(dis);
+        // TODO:  Test the previous two to see if one works better for
+        // high-order characters.
+        dis.close();
+        return s;
+    }
+
+    public char readByteChar() throws IOException {
+        return (char) readByte();
+    }
+}
diff --git a/src/org/hsqldb/server/OdbcPacketOutputStream.java b/src/org/hsqldb/server/OdbcPacketOutputStream.java
new file mode 100644
index 0000000..27e588a
--- /dev/null
+++ b/src/org/hsqldb/server/OdbcPacketOutputStream.java
@@ -0,0 +1,140 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * Atomic transmission packet from HyperSQL server to ODBC client.
+ *
+ * Sample usage
+ * <CODE>
+ *     outPacket = OdbcPacketOutputStream.newOdbcPacketOutputStream();
+ *     ...
+ *     // For each packet you need to transmit:
+ *     outPacket.reset();
+ *     outPacket.write(this);
+ *     outPacket.write(that);
+ *     outPacket.xmit('X', hsqlDataOutputStream);
+ * </CODE>
+ */
+class OdbcPacketOutputStream extends DataOutputStream {
+    private ByteArrayOutputStream byteArrayOutputStream;
+    private ByteArrayOutputStream stringWriterOS = new ByteArrayOutputStream();
+    private DataOutputStream stringWriterDos =
+        new DataOutputStream(stringWriterOS);
+    private int packetStart = 0; // Stream's "written" at start of packet.
+
+    public int getSize() {
+        return written - packetStart;
+    }
+
+    /**
+     * Wrapper method to write a null-terminated String.
+     */
+    synchronized void write(String s) throws IOException {
+        write(s, true);
+    }
+
+    synchronized void write(String s, boolean nullTerm)
+    throws IOException {
+        stringWriterDos.writeUTF(s);
+        write(stringWriterOS.toByteArray(), 2, stringWriterOS.size() - 2);
+        stringWriterOS.reset();
+        if (nullTerm) {
+            writeByte(0);
+        }
+    }
+
+    synchronized void writeSized(String s) throws IOException {
+        stringWriterDos.writeUTF(s);
+        byte[] ba = stringWriterOS.toByteArray();
+        stringWriterOS.reset();
+
+        writeInt(ba.length - 2);
+        write(ba, 2, ba.length - 2);
+    }
+
+    synchronized void reset() throws IOException {
+        byteArrayOutputStream.reset();
+        packetStart = written;
+        writeInt(-1); // length placeholder
+    }
+
+    static OdbcPacketOutputStream newOdbcPacketOutputStream()
+    throws IOException {
+        return new OdbcPacketOutputStream(new ByteArrayOutputStream());
+    }
+
+    protected OdbcPacketOutputStream(
+    ByteArrayOutputStream byteArrayOutputStream) throws IOException {
+        super(byteArrayOutputStream);
+        this.byteArrayOutputStream = byteArrayOutputStream;
+        reset();
+    }
+
+    /**
+     * @return packet size (which does not count the type byte).
+     */
+    synchronized int xmit(
+    char packetType, org.hsqldb.lib.DataOutputStream destinationStream)
+    throws IOException {
+        byte[] ba = byteArrayOutputStream.toByteArray();
+        ba[0] = (byte) (ba.length >> 24);
+        ba[1] = (byte) (ba.length >> 16);
+        ba[2] = (byte) (ba.length >> 8);
+        ba[3] = (byte) ba.length;
+        reset();
+        destinationStream.writeByte(packetType);
+        destinationStream.write(ba);
+        destinationStream.flush();
+        return ba.length;
+    }
+
+    synchronized public void close() throws IOException {
+        super.close();
+        stringWriterDos.close();
+    }
+
+    /**
+     * The behavior here is purposefully different from
+     * java.io.DataOutputStream.writeChar(int), which writes 2 bytes.
+     *
+     * We are supporting only 1-byte characters, or don't care about the
+     * high bits.
+     */
+    synchronized public void writeByteChar(char c) throws IOException {
+        writeByte(c);
+    }
+}
diff --git a/src/org/hsqldb/server/OdbcPreparedStatement.java b/src/org/hsqldb/server/OdbcPreparedStatement.java
new file mode 100644
index 0000000..e5102e0
--- /dev/null
+++ b/src/org/hsqldb/server/OdbcPreparedStatement.java
@@ -0,0 +1,115 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.hsqldb.Session;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultProperties;
+
+class OdbcPreparedStatement {
+
+    public String  handle, query;
+    public Result  ackResult;
+    public Session session;
+    private Map    containingMap;
+    private List   portals = new ArrayList();
+
+    protected OdbcPreparedStatement(OdbcPreparedStatement other) {
+        this.handle    = other.handle;
+        this.ackResult = other.ackResult;
+    }
+
+    /**
+     * Instantiates an proxy OdbcPreparedStatement object for the
+     * Connection Session, and adds the new instance to the specified map.
+     */
+    public OdbcPreparedStatement(String handle, String query,
+                                 Map containingMap,
+                                 Session session)
+                                 throws RecoverableOdbcFailure {
+
+        this.handle        = handle;
+        this.query         = query;
+        this.containingMap = containingMap;
+        this.session       = session;
+
+        Result psResult = Result.newPrepareStatementRequest();
+
+        psResult.setPrepareOrExecuteProperties(
+            query, 0, 0, 0, 0,ResultProperties.defaultPropsValue,
+            Statement.NO_GENERATED_KEYS, null, null);
+
+        ackResult = session.execute(psResult);
+
+        switch (ackResult.getType()) {
+
+            case ResultConstants.PREPARE_ACK :
+                break;
+
+            case ResultConstants.ERROR :
+                throw new RecoverableOdbcFailure(ackResult);
+            default :
+                throw new RecoverableOdbcFailure(
+                    "Output Result from Statement prep is of "
+                    + "unexpected type: " + ackResult.getType());
+        }
+
+        containingMap.put(handle, this);
+    }
+
+    /**
+     * Releases resources for this instance and all associated StatementPortals,
+     * and removes this instance from the containing map.
+     */
+    public void close() {
+
+        // TODO:  Free up resources!
+        containingMap.remove(handle);
+
+        while (portals.size() > 0) {
+            ((StatementPortal) portals.remove(1)).close();
+        }
+    }
+
+    /**
+     * Associates an StatementPortal withwith OdbcPreparedStatement.
+     */
+    public void addPortal(StatementPortal portal) {
+        portals.add(portal);
+    }
+}
diff --git a/src/org/hsqldb/server/OdbcUtil.java b/src/org/hsqldb/server/OdbcUtil.java
new file mode 100644
index 0000000..b48b69d
--- /dev/null
+++ b/src/org/hsqldb/server/OdbcUtil.java
@@ -0,0 +1,291 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import org.hsqldb.ColumnBase;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.result.ResultMetaData;
+
+/**
+ * Static values and methods to facilitate servicing ODBC clients.
+ */
+public class OdbcUtil {
+
+    static void validateInputPacketSize(OdbcPacketInputStream p)
+    throws RecoverableOdbcFailure {
+        int remaining = -1;
+        try {
+            remaining = p.available();
+        } catch (IOException ioe) {
+            // Just ignore here and we will send notifiction below.
+            // If there really is an I/O problem, it will be handled better
+            // on the next read.
+        }
+        if (remaining < 1) {
+            return;
+        }
+        throw new RecoverableOdbcFailure(
+            "Client supplied bad length for " + p.packetType
+            + " packet.  " + remaining + " bytes available after processing",
+            "Bad length for " + p.packetType
+            + " packet.  " + remaining + " extra bytes", "08P01");
+        // Code here means Protocol Violation
+    }
+
+    static String echoBackReplyString(String inCommand, int retval) {
+        String uc = inCommand.trim().toUpperCase(Locale.ENGLISH);
+        int firstWhiteSpace;
+        for (firstWhiteSpace = 0; firstWhiteSpace < uc.length();
+            firstWhiteSpace++) {
+            if (Character.isWhitespace(uc.charAt(firstWhiteSpace))) {
+                break;
+            }
+        }
+        StringBuffer replyString = new StringBuffer(
+            uc.substring(0, firstWhiteSpace));
+        String keyword = replyString.toString();
+        if (keyword.equals("UPDATE") || keyword.equals("DELETE")) {
+            replyString.append(" " + retval);
+        } else if (keyword.equals("CREATE") || keyword.equals("DROP")) {
+            // This case is significantly missing from the spec., yet
+            // PostgreSQL Server echo's these commands as implemented here.
+            // TODO: Add error-checking
+            int wordStart;
+            for (wordStart = firstWhiteSpace; wordStart < uc.length();
+                wordStart++) {
+                if (!Character.isWhitespace(uc.charAt(wordStart))) {
+                    break;
+                }
+            }
+            int wordEnd;
+            for (wordEnd = wordStart; wordEnd < uc.length();
+                wordEnd++) {
+                if (!Character.isWhitespace(uc.charAt(wordEnd))) {
+                    break;
+                }
+            }
+            replyString.append(" " + uc.substring(wordStart, wordEnd));
+        } else if (keyword.equals("INSERT")) {
+            replyString.append(" " + 0 + ' ' + retval);
+            // The number is the supposed to be the oid for single-row
+            // inserts into a table that has row oids.
+            // Since the requirement is conditional, it's very likely that the
+            // client will make any use of the value we pass.
+        }
+        // If we ever implement following SQL commands, add echo's for these
+        // strings too:  MOVE, FETCH, COPY.
+        return replyString.toString();
+    }
+
+    static void writeParam(
+    String key, String val, DataOutputStream hOutStream) throws IOException {
+        OdbcPacketOutputStream alertPacket =
+            OdbcPacketOutputStream.newOdbcPacketOutputStream();
+        alertPacket.write(key);
+        alertPacket.write(val);
+        alertPacket.xmit('S', hOutStream);
+        alertPacket.close();
+    }
+
+    // Constants taken from connection.h
+    static final int ODBC_SM_DATABASE = 64;
+    static final int ODBC_SM_USER = 32;
+    static final int ODBC_SM_OPTIONS = 64;
+    static final int ODBC_SM_UNUSED = 64;
+    static final int ODBC_SM_TTY = 64;
+    static final int ODBC_AUTH_REQ_PASSWORD = 3;
+    static final int ODBC_AUTH_REQ_OK = 0;
+
+    static void alertClient(int severity, String message,
+    DataOutputStream hOutStream) throws IOException {
+        alertClient(severity, message, null, hOutStream);
+    }
+
+    static void alertClient(int severity, String message,
+    String sqlStateCode, DataOutputStream hOutStream) throws IOException {
+        if (sqlStateCode == null) {
+            sqlStateCode = "XX000";
+            // This default code means INTERNAL ERROR
+        }
+        if (!odbcSeverityMap.containsKey(severity)) {
+            throw new IllegalArgumentException(
+                "Unknown severity value (" + severity + ')');
+        }
+        OdbcPacketOutputStream alertPacket =
+            OdbcPacketOutputStream.newOdbcPacketOutputStream();
+        alertPacket.write("S" + odbcSeverityMap.get(severity));
+        if (severity < ODBC_SEVERITY_NOTICE) {
+            alertPacket.write("C" + sqlStateCode);
+        }
+        alertPacket.write("M" + message);
+        alertPacket.writeByte(0);
+        alertPacket.xmit((severity < ODBC_SEVERITY_NOTICE) ? 'E' : 'N',
+                hOutStream);
+        alertPacket.close();
+    }
+
+    static String[][] hardcodedParams = new String[][] {
+        new String[] { "client_encoding", "SQL_ASCII" },
+        new String[] { "DateStyle", "ISO, MDY" },
+        new String[] { "integer_datetimes", "on" },
+        new String[] { "is_superuser", "on" },
+        new String[] { "server_encoding", "SQL_ASCII" },
+        new String[] { "server_version", "8.3.1" },
+        new String[] { "session_authorization", "blaine" },
+        new String[] { "standard_conforming_strings", "off" },
+        new String[] { "TimeZone", "US/Eastern" },
+    };
+
+    static final int ODBC_SIMPLE_MODE = 0;
+    static final int ODBC_EXTENDED_MODE = 1;
+    static final int ODBC_EXT_RECOVER_MODE = 2;
+
+    static final int ODBC_SEVERITY_FATAL = 1;
+    static final int ODBC_SEVERITY_ERROR = 2;
+    static final int ODBC_SEVERITY_PANIC = 3;
+    static final int ODBC_SEVERITY_WARNING = 4;
+    static final int ODBC_SEVERITY_NOTICE = 5;
+    static final int ODBC_SEVERITY_DEBUG = 6;
+    static final int ODBC_SEVERITY_INFO = 7;
+    static final int ODBC_SEVERITY_LOG = 8;
+
+    static org.hsqldb.lib.IntKeyHashMap odbcSeverityMap =
+        new org.hsqldb.lib.IntKeyHashMap();
+
+    static {
+        odbcSeverityMap.put(ODBC_SEVERITY_FATAL, "FATAL");
+        odbcSeverityMap.put(ODBC_SEVERITY_ERROR, "ERROR");
+        odbcSeverityMap.put(ODBC_SEVERITY_PANIC, "PANIC");
+        odbcSeverityMap.put(ODBC_SEVERITY_WARNING, "WARNING");
+        odbcSeverityMap.put(ODBC_SEVERITY_NOTICE, "NOTICE");
+        odbcSeverityMap.put(ODBC_SEVERITY_DEBUG, "DEBUG");
+        odbcSeverityMap.put(ODBC_SEVERITY_INFO, "INFO");
+        odbcSeverityMap.put(ODBC_SEVERITY_LOG, "LOG");
+    }
+
+
+    /**
+     * TODO:  Eliminate the mungling on the client-side instead of
+     * attempting very problematic correction here!
+     */
+    static String revertMungledPreparedQuery(String inQuery) {
+        // THIS PURPOSEFULLY USING Java 1.4!
+        return inQuery.replaceAll("\\$\\d+", "?");
+    }
+
+    static public int getTableOidForColumn(int colIndex, ResultMetaData md) {
+        if (!md.isTableColumn(colIndex)) {
+            return 0;
+        }
+        ColumnBase col = md.columns[colIndex];
+        int hashCode = (col.getSchemaNameString() + '.'
+            + col.getTableNameString()).hashCode();
+        if (hashCode < 0) {
+            hashCode *= -1;
+        }
+        return hashCode;
+    }
+
+    /**
+     * Temporary hack.
+     *
+     * This ID should stick with the table
+     * column.  Here, it will change based on user-specified column label.
+     * The int has is also being truncated into a short.
+     */
+    static public short getIdForColumn(int colIndex, ResultMetaData md) {
+        if (!md.isTableColumn(colIndex)) {
+            return 0;
+        }
+        short hashCode =
+            (short) md.getGeneratedColumnNames()[colIndex].hashCode();
+        if (hashCode < 0) {
+            hashCode *= -1;
+        }
+        return hashCode;
+        //return (short) (colIndex + 1);
+    }
+
+    /**
+     * @param hexChars A String containing an EVEN number of hex
+     *                      characters.
+     */
+    static public String hexCharsToOctalOctets(String hexChars) {
+        int chars = hexChars.length();
+        if (chars != (chars / 2) * 2) {
+            throw new IllegalArgumentException("Hex character lists contains "
+                + "an odd number of characters: " + chars);
+        }
+        StringBuffer sb = new StringBuffer();
+        char c;
+        int octet;
+        for (int i = 0; i < chars; i++) {
+            octet = 0;
+            c = hexChars.charAt(i);
+            if (c >= 'a' && c <= 'f') {
+                octet += 10 + c - 'a';
+            } else if (c >= 'A' && c <= 'F') {
+                octet += 10 + c - 'A';
+            } else if (c >= '0' && c <= '9') {
+                octet += c - '0';
+            } else {
+                throw new IllegalArgumentException(
+                    "Non-hex character in input at offset " + i + ": " + c);
+            }
+            octet = octet << 4;
+            c = hexChars.charAt(++i);
+            if (c >= 'a' && c <= 'f') {
+                octet += 10 + c - 'a';
+            } else if (c >= 'A' && c <= 'F') {
+                octet += 10 + c - 'A';
+            } else if (c >= '0' && c <= '9') {
+                octet += c - '0';
+            } else {
+                throw new IllegalArgumentException(
+                    "Non-hex character in input at offset " + i + ": " + c);
+            }
+
+            sb.append('\\');
+            sb.append((char) ('0' + (octet >> 6)));
+            sb.append((char) ('0' + ((octet >> 3) & 7)));
+            sb.append((char) ('0' + (octet & 7)));
+        }
+        return sb.toString();
+    }
+
+    static public void main(String[] sa) {
+        System.out.println("(" + OdbcUtil.hexCharsToOctalOctets(sa[0]) + ')');
+    }
+}
diff --git a/src/org/hsqldb/server/PgType.java b/src/org/hsqldb/server/PgType.java
new file mode 100644
index 0000000..443e316
--- /dev/null
+++ b/src/org/hsqldb/server/PgType.java
@@ -0,0 +1,544 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * $Id: PgType.java 3481 2010-02-26 18:05:06Z fredt $
+ */
+
+package org.hsqldb.server;
+
+import org.hsqldb.types.Type;
+import org.hsqldb.types.Types;
+import org.hsqldb.types.NumberType;
+import org.hsqldb.types.BooleanType;
+import org.hsqldb.types.CharacterType;
+import org.hsqldb.types.DateTimeType;
+import org.hsqldb.Session;
+import org.hsqldb.types.Types;
+import java.sql.SQLException;
+import java.io.Serializable;
+import org.hsqldb.types.JavaObjectData;
+import org.hsqldb.HsqlException;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.jdbc.Util;
+
+public class PgType {
+    private int oid;
+    private int typeWidth = -1;
+    private int lpConstraint = -1; // Length or Precision
+    private Type hType;
+
+    public int getOid() {
+        return oid;
+    }
+    public int getTypeWidth() {
+        return typeWidth;
+    }
+    public int getLPConstraint() {
+        return lpConstraint;
+    }
+
+    /**
+     * Convenience wrapper for PgType constructor, when there is no
+     * type width, length, or precision setting for the type.
+     *
+     * @see #PgType(Type, int, Integer, Integer)
+     */
+    protected PgType(Type hType, int oid) {
+        this(hType, oid, null, null);
+    }
+
+    /**
+     * Convenience wrapper for PgType constructor, when there is no
+     * length or precision setting for the type.
+     *
+     * @see #PgType(Type, int, Integer, Integer)
+     */
+    protected PgType(Type hType, int oid, int typeWidth) {
+        this(hType, oid, new Integer(typeWidth), null);
+    }
+
+    /**
+     * Convenience wrapper for PgType constructor, when there is no fixed
+     * width for the type.
+     *
+     * @param dummy Normally pass null.  This is a dummy parameter just to make
+     *              a unique method signature.  If non-null, will be treated
+     *              exactly the same as the typeWidthObject from the 3-param
+     *              constructor.
+     * @see #PgType(Type, int, Integer, Integer)
+     */
+    protected PgType(Type hType, int oid, Integer dummy, long lpConstraint)
+    throws RecoverableOdbcFailure {
+        this(hType, oid, dummy, new Integer((int) lpConstraint));
+        if (lpConstraint < 0) {
+            throw new RecoverableOdbcFailure(
+                "Length/Precision value is below minimum value of 0");
+        }
+        if (lpConstraint > Integer.MAX_VALUE) {
+            throw new RecoverableOdbcFailure(
+                "Length/Precision value is above maximum value of "
+                + Integer.MAX_VALUE);
+        }
+    }
+
+    /**
+     * @param hType HyperSQL data type
+     * @param oid Numeric Object ID for the driver-side type.
+     * @param typeWidthObject Fixed width for the type
+     * @param lpConstraintObject Either length or Precision setting for this
+     *                     instance of the type.
+     *                     <b>IMPORTANT!</b> for all types with positive
+     *                     lpConstraint other than Timestamps and Times,
+     *                     add an extra 4 to satisy crazy driver protocol.
+     */
+    protected PgType(Type hType,
+        int oid, Integer typeWidthObject, Integer lpConstraintObject) {
+        this.hType = hType;
+        this.oid = oid;
+        this.typeWidth = (typeWidthObject == null)
+                       ? -1 : typeWidthObject.intValue();
+        this.lpConstraint = (lpConstraintObject == null)
+                       ? -1 : lpConstraintObject.intValue();
+    }
+
+    static public PgType getPgType(Type hType, boolean directColumn)
+    throws RecoverableOdbcFailure {
+        switch (hType.typeCode) {
+            case Types.TINYINT:
+                return tinyIntSingleton;
+            case Types.SQL_SMALLINT:
+                return int2singleton;
+            case Types.SQL_INTEGER:
+                return int4singleton;
+            case Types.SQL_BIGINT:
+                return int8singleton;
+
+            case Types.SQL_NUMERIC:
+            case Types.SQL_DECIMAL:
+                return new PgType(hType, TYPE_NUMERIC, null,
+                        (hType.precision << 16) + hType.scale + 4);
+
+            case Types.SQL_FLOAT:
+                // TODO:
+                // Improve the driver to make use of the Float precision
+                // return new PgType(hType, TYPE_FLOAT8, null, hType.precision);
+            case Types.SQL_DOUBLE:
+            case Types.SQL_REAL:
+                return doubleSingleton;
+
+            case Types.BOOLEAN:
+                return boolSingleton;
+
+            case Types.SQL_CHAR: // = CHARACTER
+                if (directColumn) {
+                    return new PgType(hType,
+                        TYPE_BPCHAR, null, hType.precision + 4);
+                }
+                return unknownSingleton;  // constant value
+
+            case Types.SQL_VARCHAR: // = CHARACTER VARYING = LONGVARCHAR
+            case Types.VARCHAR_IGNORECASE: // Don't know if possible here
+                if (hType.precision < 0) {
+                    throw new RecoverableOdbcFailure (
+                        "Length/Precision value is below minimum value of 0");
+                }
+                if (hType.precision > Integer.MAX_VALUE) {
+                    throw new RecoverableOdbcFailure (
+                        "Length/Precision value is above maximum value of "
+                        + Integer.MAX_VALUE);
+                }
+                return (hType.precision != 0 && directColumn)
+                    ? new PgType(hType, TYPE_VARCHAR, null, hType.precision + 4)
+                    : textSingleton;
+                // Return TEXT type for both unlimited VARCHARs, and for
+                // Non-direct-table-col results.
+            case Types.SQL_CLOB: // = CHARACTER LARGE OBJECT
+                throw new RecoverableOdbcFailure (
+                    "Driver doesn't support type 'CLOB' yet");
+
+            case Types.SQL_BLOB: // = BINARY LARGE OBJECT
+                return new PgType(hType, TYPE_BLOB, null, hType.precision);
+            case Types.SQL_BINARY:
+            case Types.SQL_VARBINARY: // = BINARY VARYING
+                return new PgType(hType, TYPE_BYTEA, null, hType.precision);
+                // Note that we are returning SQL_BINARY data as if they were
+                // variable.  I don't think the unnecessary variability will
+                // have any side-effects.
+                // No reason to differentiate here, since the client's
+                // atttypm parameter is where we would communicate the length
+                // in both cases.
+
+            case Types.OTHER:
+                throw new RecoverableOdbcFailure (
+                    "Driver doesn't support type 'OTHER' yet");
+
+            case Types.SQL_BIT:
+                return bitSingleton;
+            case Types.SQL_BIT_VARYING:
+                return bitVaryingSingleton;
+                // I have no idea why length contstaint spec is not needed for
+                // BIT_VARYING.
+
+            case Types.SQL_DATE:
+                return dateSingleton;
+
+            // 4 bytes
+            case Types.SQL_TIME :
+                return new PgType(hType, TYPE_TIME, new Integer(8),
+                                  hType.precision);
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                return new PgType(hType, TYPE_TIME_WITH_TMZONE,
+                                  new Integer(12), hType.precision);
+
+            case Types.SQL_TIMESTAMP :
+                return new PgType(hType, TYPE_TIMESTAMP_NO_TMZONE,
+                                  new Integer(8), hType.precision);
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return new PgType(hType, TYPE_TIMESTAMP, new Integer(8),
+                                  hType.precision);
+
+            // Postgresql is returning type DATETIME for this case.
+            // It should return TYPE_TIMESTAMP, no?
+            /* *********************************************************
+             * For INTERVALs, we get the more specific type here, not just
+             * SQL_INTERVAL.
+            case Types.SQL_INTERVAL:
+             *
+             * The reason no precisions are passed to the ODBC client is that I
+             * have so far been unsuccessful at figuring out exactly how the
+             * driver wants the atttypmod formatted.  See doc/odbc.txt for
+             * notes about this.
+             */
+            case Types.SQL_INTERVAL_YEAR:
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH:
+            case Types.SQL_INTERVAL_MONTH:
+                // Need to test these, since the driver Interval type is
+                // intended for second-resolution only, not month resolution.
+                throw new RecoverableOdbcFailure (
+                    "Driver doesn't support month-resolution 'INTERVAL's yet");
+            case Types.SQL_INTERVAL_DAY:
+            case Types.SQL_INTERVAL_DAY_TO_HOUR:
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE:
+            case Types.SQL_INTERVAL_HOUR:
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE:
+            case Types.SQL_INTERVAL_MINUTE:
+                // Our server uses the type to distinguish the resolution here.
+                // The driver expects these types to be distinguished in the
+                // value itself, like "99 days".
+                // Therefore, these types are incompatible until driver is
+                // enhanced.
+                throw new RecoverableOdbcFailure (
+                    "Driver doesn't support non-second-resolution 'INTERVAL's "
+                    + "yet");
+            case Types.SQL_INTERVAL_DAY_TO_SECOND:
+                PgType.ignoredConstraintWarning(hType);
+                return daySecIntervalSingleton;
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND:
+                PgType.ignoredConstraintWarning(hType);
+                return hourSecIntervalSingleton;
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND:
+                PgType.ignoredConstraintWarning(hType);
+                return minSecIntervalSingleton;
+            case Types.SQL_INTERVAL_SECOND:
+                PgType.ignoredConstraintWarning(hType);
+                return secIntervalSingleton;
+
+            default:
+                throw new RecoverableOdbcFailure (
+                    "Unsupported type: " + hType.getNameString());
+        }
+    }
+
+    /**
+     * This method copied from JDBCPreparedStatement.java.
+     *
+     * The internal parameter value setter always converts the parameter to
+     * the Java type required for data transmission.
+     * <P>
+     * This method will not be called for binary types.  Binary values are
+     * just loaded directly into the Object parameter array.
+     * </P>
+     *
+     * @throws SQLException if either argument is not acceptable.
+     */
+    public Object getParameter(String inString, Session session)
+    throws SQLException, RecoverableOdbcFailure {
+        if (inString == null) {
+            return null;
+        }
+        Object o = inString;
+
+        switch (hType.typeCode) {
+            case Types.SQL_BOOLEAN :
+                if (inString.length() == 1) switch (inString.charAt(0)) {
+                    case 'T':
+                    case 't':
+                    case 'Y':
+                    case 'y':
+                    case '1':
+                        return Boolean.TRUE;
+                    default:
+                        return Boolean.FALSE;
+                }
+                return Boolean.valueOf(inString);
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.SQL_BLOB :
+                throw new RecoverableOdbcFailure(
+                    "This data type should be transmitted to server in binary "
+                    + "format: " + hType.getNameString());
+
+            case Types.OTHER :
+            case Types.SQL_CLOB :
+                throw new RecoverableOdbcFailure(
+                        "Type not supported yet: " + hType.getNameString());
+                /*
+            case Types.OTHER :
+                try {
+                    if (o instanceof Serializable) {
+                        o = new JavaObjectData((Serializable) o);
+
+                        break;
+                    }
+                } catch (HsqlException e) {
+                    PgType.throwError(e);
+                }
+                PgType.throwError(Error.error(ErrorCode.X_42565));
+
+                break;
+            case Types.SQL_BLOB :
+                //setBlobParameter(i, o);
+
+                //break;
+            case Types.SQL_CLOB :
+                //setClobParameter(i, o);
+
+                //break;
+            */
+            case Types.SQL_DATE :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+            case Types.SQL_TIME :
+            case Types.SQL_TIMESTAMP : {
+                try {
+                    o = hType.convertToType(session, o, Type.SQL_VARCHAR);
+                } catch (HsqlException e) {
+                    PgType.throwError(e);
+                }
+                break;
+            }
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                try {
+                    o = hType.convertToType(session, o, Type.SQL_VARCHAR);
+                } catch (HsqlException e) {
+                    PgType.throwError(e);
+                }
+                break;
+            default :
+                /*
+                throw new RecoverableOdbcFailure(
+                    "Parameter value is of unexpected type: "
+                    + hType.getNameString());
+                */
+                try {
+                    o = hType.convertToDefaultType(session, o);
+                    // Supposed to handle String -> SQL_BIT.  Not working.
+                } catch (HsqlException e) {
+                    PgType.throwError(e);
+                }
+                break;
+        }
+        return o;
+    }
+
+    public String valueString(Object datum) {
+        String dataString = hType.convertToString(datum);
+        switch (hType.typeCode) {
+            case Types.SQL_BOOLEAN :
+                return String.valueOf(((Boolean) datum).booleanValue()
+                    ? 't' : 'f');
+                // Default would probably work fine, since the Driver looks at
+                // only the first byte, but this why send an extra 3 or 4 bytes
+                // with every data, plus there could be some dependency upon
+                // single-character in the driver code somewhere.
+            case Types.SQL_VARBINARY :
+            case Types.SQL_BINARY :
+                dataString = OdbcUtil.hexCharsToOctalOctets(dataString);
+                break;
+        }
+        return dataString;
+    }
+
+    /*
+     * The followign settings are a Java port of pgtypes.h
+     */
+    public static final int TYPE_BOOL         =  16;
+    public static final int TYPE_BYTEA        =  17;
+    public static final int TYPE_CHAR         =  18;
+    public static final int TYPE_NAME         =  19;
+    public static final int TYPE_INT8         =  20;
+    public static final int TYPE_INT2         =  21;
+    public static final int TYPE_INT2VECTOR   =  22;
+    public static final int TYPE_INT4         =  23;
+    public static final int TYPE_REGPROC      =  24;
+    public static final int TYPE_TEXT         =  25;
+    public static final int TYPE_OID          =  26;
+    public static final int TYPE_TID          =  27;
+    public static final int TYPE_XID          =  28;
+    public static final int TYPE_CID          =  29;
+    public static final int TYPE_OIDVECTOR    =  30;
+    public static final int TYPE_SET          =  32;
+    public static final int TYPE_XML          = 142;
+    public static final int TYPE_XMLARRAY     = 143;
+    public static final int TYPE_CHAR2        = 409;
+    public static final int TYPE_CHAR4        = 410;
+    public static final int TYPE_CHAR8        = 411;
+    public static final int TYPE_POINT        = 600;
+    public static final int TYPE_LSEG         = 601;
+    public static final int TYPE_PATH         = 602;
+    public static final int TYPE_BOX          = 603;
+    public static final int TYPE_POLYGON      = 604;
+    public static final int TYPE_FILENAME     = 605;
+    public static final int TYPE_CIDR         = 650;
+    public static final int TYPE_FLOAT4       = 700;
+    public static final int TYPE_FLOAT8       = 701;
+    public static final int TYPE_ABSTIME      = 702;
+    public static final int TYPE_RELTIME      = 703;
+    public static final int TYPE_TINTERVAL    = 704;
+    public static final int TYPE_UNKNOWN      = 705;
+    public static final int TYPE_MONEY        = 790;
+    public static final int TYPE_OIDINT2      = 810;
+    public static final int TYPE_MACADDR      = 829;
+    public static final int TYPE_INET         = 869;
+    public static final int TYPE_OIDINT4      = 910;
+    public static final int TYPE_OIDNAME      = 911;
+    public static final int TYPE_TEXTARRAY    = 1009;
+    public static final int TYPE_BPCHARARRAY  = 1014;
+    public static final int TYPE_VARCHARARRAY = 1015;
+    public static final int TYPE_BPCHAR       = 1042;
+    public static final int TYPE_VARCHAR      = 1043;
+    public static final int TYPE_DATE         = 1082;
+    public static final int TYPE_TIME         = 1083;
+    public static final int TYPE_TIMESTAMP_NO_TMZONE = 1114; /* since 7.2 */
+    public static final int TYPE_DATETIME     = 1184;
+    public static final int TYPE_TIME_WITH_TMZONE   = 1266;   /* since 7.1 */
+    public static final int TYPE_TIMESTAMP    = 1296; /* deprecated since 7.0 */
+    public static final int TYPE_NUMERIC      = 1700;
+    public static final int TYPE_RECORD       = 2249;
+    public static final int TYPE_VOID         = 2278;
+    public static final int TYPE_UUID         = 2950;
+
+    // Numbering new HyperSQL-only client-side types beginning with 9999 and
+    // getting lower, to reduce chance of conflict with future PostreSQL types.
+    public static final int TYPE_BLOB         = 9998;
+    public static final int TYPE_TINYINT      = 9999;
+
+    // Apparenly new additions, from Postgresql server file pg_type.h:
+    public static final int TYPE_BIT          = 1560;
+    // Also defined is _bit.  No idea what that is about
+    public static final int TYPE_VARBIT       = 1562;
+    // Also defined is _varbit.  No idea what that is about
+
+    /* Following stuff is to support code copied from
+     * JDBCPreparedStatement.java. */
+    static final void throwError(HsqlException e) throws SQLException {
+
+//#ifdef JAVA6
+        throw Util.sqlException(e.getMessage(), e.getSQLState(),
+            e.getErrorCode(), e);
+
+//#else
+/*
+        throw new SQLException(e.getMessage(), e.getSQLState(),
+                               e.getErrorCode());
+*/
+
+//#endif JAVA6
+    }
+
+    static protected final PgType tinyIntSingleton =
+        new PgType(Type.TINYINT, TYPE_TINYINT, 1);
+    static protected final PgType int2singleton =
+        new PgType(Type.SQL_SMALLINT, TYPE_INT2, 2);
+    static protected final PgType int4singleton =
+        new PgType(Type.SQL_INTEGER, TYPE_INT4, 4);
+    static protected final PgType int8singleton =
+        new PgType(Type.SQL_BIGINT, TYPE_INT8, 8);
+    static protected final PgType doubleSingleton =
+        new PgType(Type.SQL_DOUBLE, TYPE_FLOAT8, 8);
+    static protected final PgType boolSingleton =
+        new PgType(Type.SQL_BOOLEAN, TYPE_BOOL, 1);
+    static protected final PgType textSingleton =
+        new PgType(Type.SQL_VARCHAR, TYPE_TEXT);
+    static protected final PgType dateSingleton =
+        new PgType(Type.SQL_DATE, TYPE_DATE, 4);
+    static protected final PgType unknownSingleton =
+        new PgType(Type.SQL_CHAR_DEFAULT, TYPE_UNKNOWN, -2);
+    static protected final PgType bitSingleton =
+        new PgType(Type.SQL_BIT, TYPE_BIT);
+    static protected final PgType bitVaryingSingleton =
+        new PgType(Type.SQL_BIT_VARYING, TYPE_VARBIT);
+    static protected final PgType daySecIntervalSingleton =
+        new PgType(Type.SQL_INTERVAL_DAY_TO_SECOND, TYPE_TINTERVAL, 16);
+    static protected final PgType hourSecIntervalSingleton =
+        new PgType(Type.SQL_INTERVAL_HOUR_TO_SECOND, TYPE_TINTERVAL, 16);
+    static protected final PgType minSecIntervalSingleton =
+        new PgType(Type.SQL_INTERVAL_MINUTE_TO_SECOND, TYPE_TINTERVAL, 16);
+    static protected final PgType secIntervalSingleton =
+        new PgType(Type.SQL_INTERVAL_SECOND, TYPE_TINTERVAL, 16);
+
+    static private void ignoredConstraintWarning(Type hsqldbType) {
+        if (hsqldbType.precision == 0 && hsqldbType.scale == 0) {
+            return;
+        }
+        // TODO:  Use logging system!
+        /*
+        System.err.println(
+                "WARNING:  Not passing INTERVAL precision setting "
+                + "or second precision setting to ODBC client");
+        */
+    }
+}
diff --git a/src/org/hsqldb/server/RecoverableOdbcFailure.java b/src/org/hsqldb/server/RecoverableOdbcFailure.java
new file mode 100644
index 0000000..caa1a68
--- /dev/null
+++ b/src/org/hsqldb/server/RecoverableOdbcFailure.java
@@ -0,0 +1,83 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import org.hsqldb.result.Result;
+
+class RecoverableOdbcFailure extends Exception {
+    private String clientMessage = null;
+    private String sqlStateCode = null;
+    private Result errorResult = null;
+    public String getSqlStateCode() {
+        return sqlStateCode;
+    }
+    public Result getErrorResult() {
+        return errorResult;
+    }
+    public RecoverableOdbcFailure(Result errorResult) {
+        this.errorResult = errorResult;
+    }
+    /**
+     * This constructor purposefully means that both server-side and
+     * client-side message will be set to the specified message.
+     */
+    public RecoverableOdbcFailure(String m) {
+        super(m);
+        clientMessage = m;
+    }
+    /**
+     * This constructor purposefully means that both server-side and
+     * client-side message will be set to the specified message.
+     * <P><B>
+     * Note:  The parameters DO NOT SPECIFY server-side and client-side
+     * messages.  Use the 3-parameter constructor for that.
+     * </B></P>
+     *
+     * @see #RecoverableOdbcFailure(String, String, String)
+     */
+    public RecoverableOdbcFailure(String m, String sqlStateCode) {
+        this(m);
+        this.sqlStateCode = sqlStateCode;
+    }
+    /**
+     * Set any parameter to null to skip the specified reporting.
+     */
+    public RecoverableOdbcFailure(
+    String ourMessage, String clientMessage, String sqlStateCode) {
+        super(ourMessage);
+        this.clientMessage = clientMessage;
+        this.sqlStateCode = sqlStateCode;
+    }
+    public String getClientMessage() {
+        return clientMessage;
+    }
+}
diff --git a/src/org/hsqldb/server/Server.java b/src/org/hsqldb/server/Server.java
new file mode 100644
index 0000000..8cc527e
--- /dev/null
+++ b/src/org/hsqldb/server/Server.java
@@ -0,0 +1,2410 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.HsqlException;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.StopWatch;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.lib.WrapperIterator;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.resources.BundleHandler;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+
+// fredt@users 20020215 - patch 1.7.0
+// methods reorganised to use new HsqlProperties class
+// fredt@users 20020424 - patch 1.7.0 - shutdown without exit
+// see the comments in ServerConnection.java
+// unsaved@users 20021113 - patch 1.7.2 - SSL support
+// boucherb@users 20030510-14 - 1.7.2 - SSL support moved to factory interface
+// boucherb@users 20030510-14 - 1.7.2 - service control, JavaBean API
+// fredt@users 20030916 - 1.7.2 - review, simplification and multiple DB's
+// fredt@users 20040320 - 1.7.2 - review and correction
+// fredt@users 20050225 - 1.8.0 - minor corrections
+// fredt@users 20051231 - 1.8.1 - support for remote opening of databases
+// fredt@users 20080531 - 1.8.1 - removed synchronized from print methods
+// unnecessary and could cause deadlock
+
+/**
+ * The HSQLDB HSQL protocol network database server. <p>
+ *
+ * A Server object acts as a network database server and is one way of using
+ * the client-server mode of HSQLDB Database Engine. Instances of this
+ * class handle native HSQL protocol connections exclusively, allowing database
+ * queries to be performed efficienly across the network.  Server's direct
+ * descendent, WebServer, handles HTTP protocol connections exclusively,
+ * allowing HSQL protocol to be tunneled over HTTP to avoid sandbox and
+ * firewall issues, albeit less efficiently. <p>
+ *
+ * There are a number of ways to configure and start a Server instance. <p>
+ *
+ * When started from the command line or programatically via the main(String[])
+ * method, configuration occurs in three phases, with later phases overriding
+ * properties set by previous phases:
+ *
+ * <ol>
+ *   <li>Upon construction, a Server object is assigned a set of default
+ *       properties. <p>
+ *
+ *   <li>If it exists, properties are loaded from a file named
+ *       'server.properties' in the present working directory. <p>
+ *
+ *   <li>The command line arguments (alternatively, the String[] passed to
+ *       main()) are parsed and used to further configure the Server's
+ *       properties. <p>
+ *
+ * </ol> <p>
+ *
+ * From the command line, the options are as follows: <p>
+ * <pre>
+ * +-----------------+-------------+----------+------------------------------+
+ * |    OPTION       |    TYPE     | DEFAULT  |         DESCRIPTION          |
+ * +-----------------+-------------+----------+------------------------------|
+ * | --help          |             |          | prints this message          |
+ * | --address       | name|number | any      | server inet address          |
+ * | --port          | number      | 9001/544 | port at which server listens |
+ * | --database.i    | [type]spec  | 0=test   | path of database i           |
+ * | --dbname.i      | alias       |          | url alias for database i     |
+ * | --silent        | true|false  | true     | false => display all queries |
+ * | --trace         | true|false  | false    | display JDBC trace messages  |
+ * | --tls           | true|false  | false    | TLS/SSL (secure) sockets     |
+ * | --no_system_exit| true|false  | false    | do not issue System.exit()  |
+ * | --remote_open   | true|false  | false    | can open databases remotely  |
+ * +-----------------+-------------+----------+------------------------------+
+ * </pre>
+ *
+ * The <em>database.i</em> and <em>dbname.i</em> options need further
+ * explanation:
+ *
+ * <ul>
+ *   <li>Multiple databases can be served by each instance of the Server.
+ *       The value of <em>i</em> is currently limited to the range 0..9,
+ *       allowing up to 10 different databases. Any number is this range
+ *       can be used.<p>
+ *
+ *   <li>The value assigned to <em>database.i</em> is interpreted using the
+ *       format <b>'[type]spec'</b>, where the optional <em>type</em> component
+ *       is one of <b>'file:'</b>, <b>'res:'</b> or <b>'mem:'</b> and the
+ *       <em>spec</em> component is interpreted in the context of the
+ *       <em>type</em> component.  <p>
+ *
+ *       If omitted, the <em>type</em> component is taken to be
+ *       <b>'file:'</b>.  <p>
+ *
+ *        A full description of how
+ *       <b>'[type]spec'</b> values are interpreted appears in the overview for
+ *       {@link org.hsqldb.jdbc.JDBCConnection JDBCConnection}. <p>
+ *
+ *   <li>The value assigned to <em>dbname.i</em> is taken to be the key used to
+ *       look up the desired database instance and thus corresponds to the
+ *       <b>&lt;alias&gt;</b> component of the HSQLDB HSQL protocol database
+ *       connection url:
+ *       'jdbc:hsqldb:hsql[s]://host[port][/<b>&lt;alias&gt;</b>]'. <p>
+ *
+ *   <li>The value of <em>database.0</em> is special. If  <em>dbname.0</em>
+ *       is not specified, then this defaults to an empty string and
+ *       a connection is made to <em>database.0</em> path when
+ *       the <b>&lt;alias&gt;</b> component of an HSQLDB HSQL protocol database
+ *       connection url is omitted. If a <em>database</em> key/value pair is
+ *       found in the properties when the main method is called, this
+ *       pair is supersedes the <em>database.0</em> setting<p>
+ *
+ *       This behaviour allows the previous
+ *       database connection url format to work with essentially unchanged
+ *       semantics.<p>
+ *
+ *   <li>When the  <em>remote_open</em> property is true, a connection attempt
+ *       to an unopened database results in the database being opened. The URL
+ *       for connection should include the property filepath to specify the path.
+ *       'jdbc:hsqldb:hsql[s]://host[port]/<b>&lt;alias&gt;;filepath=hsqldb:file:&lt;database path&gt;</b>'.
+ *       the given alias and filepath value will be associated together. The
+ *       database user and password to start this connection must be valid.
+ *       If this form of connection is used again, after the database has been
+ *       opened, the filepath property is ignored.<p>
+ *
+ *   <li>Once an alias such as "mydb" has been associated with a path, it cannot
+ *       be  reassigned to a different path.<p>
+ *
+ *   <li>If a database is closed with the SHUTDOWN command, its
+ *       alias is removed. It is then possible to connect to this database again
+ *       with a different (or the same) alias.<p>
+ *
+ *   <li>If the same database is connected to via two different
+ *       aliases, and then one of the is closed with the SHUTDOWN command, the
+ *       other is also closed.<p>
+ * </ul>
+ *
+ * From the 'server.properties' file, options can be set similarly, using a
+ * slightly different format. <p>
+ *
+ * Here is an example 'server.properties' file:
+ *
+ * <pre>
+ * server.port=9001
+ * server.database.0=test
+ * server.dbname.0=...
+ * ...
+ * server.database.n=...
+ * server.dbname.n=...
+ * server.silent=true
+ * </pre>
+ *
+ * Starting with 1.7.2, Server has been refactored to become a simple JavaBean
+ * with non-blocking start() and stop() service methods.  It is possible to
+ * configure a Server instance through the JavaBean API as well, but this
+ * part of the public interface is still under review and will not be finalized
+ * or documented fully until the final 1.7.2 release. <p>
+ *
+ * <b>Note:</b> <p>
+ *
+ * The 'no_system_exit' property is of particular interest. <p>
+ *
+ * If a Server instance is to run embedded in, say, an application server,
+ * such as when the JDBCDataSource or HsqlServerFactory classes are used, it
+ * is typically necessary to avoid calling System.exit() when the Server
+ * instance shuts down. <p>
+ *
+ * By default, 'no_system_exit' is set: <p>
+ *
+ * <ol>
+ *    <li><b>true</b> when a Server is started directly from the start()
+ *        method. <p>
+ *
+ *    <li><b>false</b> when a Server is started from the main(String[])
+ *         method.
+ * </ol> <p>
+ *
+ * These values are natural to their context because the first case allows
+ * the JVM to exit by default on Server shutdown when a Server instance is
+ * started from a command line environment, whereas the second case prevents
+ * a typically unwanted JVM exit on Server shutdown when a Server intance
+ * is started as part of a larger framework. <p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ *
+ * @jmx.mbean
+ *    description="HSQLDB Server"
+ *    extends="org.hsqldb.mx.mbean.RegistrationSupportBaseMBean"
+ *
+ * @jboss.xmbean
+ */
+public class Server implements HsqlSocketRequestHandler {
+
+//
+    protected static final int serverBundleHandle =
+        BundleHandler.getBundleHandle("org_hsqldb_Server_messages", null);
+
+//
+    ServerProperties serverProperties;
+
+//
+    HashSet serverConnSet;
+
+//  As of HSQLDB 1.9.0, the following arrays are used starting from 0.
+//  The indexes do not correspond to the user-specified indexes.
+    protected String[]         dbAlias;
+    protected String[]         dbType;
+    protected String[]         dbPath;
+    protected HsqlProperties[] dbProps;
+    protected int[]            dbID;
+    protected long[]           dbActionSequence;
+
+// set of aliases
+    HashSet aliasSet = new HashSet();
+
+//  Currently unused
+    protected int maxConnections;
+    volatile long actionSequence;
+
+//
+    protected String            serverId;
+    protected int               serverProtocol;
+    protected ThreadGroup       serverConnectionThreadGroup;
+    protected HsqlSocketFactory socketFactory;
+    protected ServerSocket      socket;
+
+//
+    private Thread             serverThread;
+    private Throwable          serverError;
+    private volatile int       serverState;
+    private volatile boolean   isSilent;
+    protected volatile boolean isRemoteOpen;
+    protected boolean          isDaemon;
+    private PrintWriter        logWriter;
+    private PrintWriter        errWriter;
+    private ServerAcl          acl = null;    // null means no access tests
+
+//
+
+    /**
+     * A specialized Thread inner class in which the run() method of this
+     * server executes.
+     */
+    private class ServerThread extends Thread {
+
+        /**
+         * Constructs a new thread in which to execute the run method
+         * of this server.
+         *
+         * @param name The thread name
+         */
+        ServerThread(String name) {
+
+            super(name);
+
+            setName(name + '@' + Integer.toString(Server.this.hashCode(), 16));
+        }
+
+        /**
+         * Executes the run() method of this server
+         */
+        public void run() {
+            Server.this.run();
+            printWithThread("ServerThread.run() exited");
+        }
+    }
+
+    /**
+     * Creates a new Server instance handling HSQL protocol connections.
+     */
+    public Server() {
+        this(ServerConstants.SC_PROTOCOL_HSQL);
+    }
+
+    /**
+     * Creates a new Server instance handling the specified connection
+     * protocol. <p>
+     *
+     * For example, the no-args WebServer constructor invokes this constructor
+     * with ServerConstants.SC_PROTOCOL_HTTP, while the Server() no args
+     * contructor invokes this constructor with
+     * ServerConstants.SC_PROTOCOL_HSQL. <p>
+     *
+     * @param protocol the ServerConstants code indicating which
+     *      connection protocol to handle
+     */
+    protected Server(int protocol) {
+        init(protocol);
+    }
+
+    /**
+     * Checks if this Server object is or is not running and throws if the
+     * current state does not match the specified value.
+     *
+     * @param running if true, ensure the server is running, else ensure the
+     *      server is not running
+     * @throws RuntimeException if the supplied value does not match the
+     *      current running status
+     */
+    public void checkRunning(boolean running) throws RuntimeException {
+
+        int     state;
+        boolean error;
+
+        printWithThread("checkRunning(" + running + ") entered");
+
+        state = getState();
+        error = (running && state != ServerConstants.SERVER_STATE_ONLINE)
+                || (!running
+                    && state != ServerConstants.SERVER_STATE_SHUTDOWN);
+
+        if (error) {
+            String msg = "server is " + (running ? "not "
+                                                 : "") + "running";
+
+            throw new RuntimeException(msg);
+        }
+
+        printWithThread("checkRunning(" + running + ") exited");
+    }
+
+    /**
+     * Closes all connections to this Server.
+     *
+     * @jmx.managed-operation
+     *  impact="ACTION"
+     *  description="Closes all open connections"
+     */
+    public synchronized void signalCloseAllServerConnections() {
+
+        Iterator it;
+
+        printWithThread("signalCloseAllServerConnections() entered");
+
+        synchronized (serverConnSet) {
+
+            // snapshot
+            it = new WrapperIterator(serverConnSet.toArray(null));
+        }
+
+        for (; it.hasNext(); ) {
+            ServerConnection sc = (ServerConnection) it.next();
+
+            printWithThread("Closing " + sc);
+
+            // also removes all but one connection from serverConnSet
+            sc.signalClose();
+        }
+
+        printWithThread("signalCloseAllServerConnections() exited");
+    }
+
+    protected void finalize() throws Throwable {
+
+        if (serverThread != null) {
+            releaseServerSocket();
+        }
+    }
+
+    /**
+     * Retrieves, in string form, this server's host address.
+     *
+     * @return this server's host address
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Host InetAddress"
+     */
+    public String getAddress() {
+
+        return socket == null
+               ? serverProperties.getProperty(ServerConstants.SC_KEY_ADDRESS)
+               : socket.getInetAddress().getHostAddress();
+    }
+
+    /**
+     * Retrieves the url alias (network name) of the i'th database
+     * that this Server hosts.
+     *
+     * @param index the index of the url alias upon which to report
+     * @param asconfigured if true, report the configured value, else
+     *      the live value
+     * @return the url alias component of the i'th database
+     *      that this Server hosts, or null if no such name exists.
+     *
+     * @jmx.managed-operation
+     *  impact="INFO"
+     *  description="url alias component of the i'th hosted Database"
+     *
+     * @jmx.managed-operation-parameter
+     *      name="index"
+     *      type="int"
+     *      position="0"
+     *      description="This Server's index for the hosted Database"
+     *
+     * @jmx.managed-operation-parameter
+     *      name="asconfigured"
+     *      type="boolean"
+     *      position="1"
+     *      description="if true, the configured value, else the live value"
+     */
+    public String getDatabaseName(int index, boolean asconfigured) {
+
+        if (asconfigured) {
+            return serverProperties.getProperty(ServerConstants.SC_KEY_DBNAME
+                                                + "." + index);
+        } else if (getState() == ServerConstants.SERVER_STATE_ONLINE) {
+            return (dbAlias == null || index < 0 || index >= dbAlias.length)
+                   ? null
+                   : dbAlias[index];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Retrieves the HSQLDB path descriptor (uri) of the i'th
+     * Database that this Server hosts.
+     *
+     * @param index the index of the uri upon which to report
+     * @param asconfigured if true, report the configured value, else
+     *      the live value
+     * @return the HSQLDB database path descriptor of the i'th database
+     *      that this Server hosts, or null if no such path descriptor
+     *      exists
+     *
+     * @jmx.managed-operation
+     *  impact="INFO"
+     *  description="For i'th hosted database"
+     *
+     * @jmx.managed-operation-parameter
+     *      name="index"
+     *      type="int"
+     *      position="0"
+     *      description="This Server's index for the hosted Database"
+     *
+     * @jmx.managed-operation-parameter
+     *      name="asconfigured"
+     *      type="boolean"
+     *      position="1"
+     *      description="if true, the configured value, else the live value"
+     */
+    public String getDatabasePath(int index, boolean asconfigured) {
+
+        if (asconfigured) {
+            return serverProperties.getProperty(ServerConstants.SC_KEY_DATABASE
+                                                + "." + index);
+        } else if (getState() == ServerConstants.SERVER_STATE_ONLINE) {
+            return (dbPath == null || index < 0 || index >= dbPath.length)
+                   ? null
+                   : dbPath[index];
+        } else {
+            return null;
+        }
+    }
+
+    public String getDatabaseType(int index) {
+        return (dbType == null || index < 0 || index >= dbType.length) ? null
+                                                                       : dbType[index];
+    }
+
+    /**
+     * Retrieves the name of the web page served when no page is specified.
+     * This attribute is relevant only when server protocol is HTTP(S).
+     *
+     * @return the name of the web page served when no page is specified
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Used when server protocol is HTTP(S)"
+     */
+    public String getDefaultWebPage() {
+        return "[IGNORED]";
+    }
+
+    /**
+     * Retrieves a String object describing the command line and
+     * properties options for this Server.
+     *
+     * @return the command line and properties options help for this Server
+     */
+    public String getHelpString() {
+        return BundleHandler.getString(serverBundleHandle, "server.help");
+    }
+
+    /**
+     * Retrieves the PrintWriter to which server errors are printed.
+     *
+     * @return the PrintWriter to which server errors are printed.
+     */
+    public PrintWriter getErrWriter() {
+        return errWriter;
+    }
+
+    /**
+     * Retrieves the PrintWriter to which server messages are printed.
+     *
+     * @return the PrintWriter to which server messages are printed.
+     */
+    public PrintWriter getLogWriter() {
+        return logWriter;
+    }
+
+    /**
+     * Retrieves this server's host port.
+     *
+     * @return this server's host port
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="At which ServerSocket listens for connections"
+     */
+    public int getPort() {
+        return serverProperties.getIntegerProperty(ServerConstants.SC_KEY_PORT,
+                ServerConfiguration.getDefaultPort(serverProtocol, isTls()));
+    }
+
+    /**
+     * Retrieves this server's product name.  <p>
+     *
+     * Typically, this will be something like: "HSQLDB xxx server".
+     *
+     * @return the product name of this server
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Of Server"
+     */
+    public String getProductName() {
+        return "HSQLDB server";
+    }
+
+    /**
+     * Retrieves the server's product version, as a String.  <p>
+     *
+     * Typically, this will be something like: "1.x.x" or "2.x.x" and so on.
+     *
+     * @return the product version of the server
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Of Server"
+     */
+    public String getProductVersion() {
+        return HsqlDatabaseProperties.THIS_VERSION;
+    }
+
+    /**
+     * Retrieves a string respresentaion of the network protocol
+     * this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.
+     *
+     * @return string respresentation of this server's protocol
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Used to handle connections"
+     */
+    public String getProtocol() {
+        return isTls() ? "HSQLS"
+                       : "HSQL";
+    }
+
+    /**
+     * Retrieves a Throwable indicating the last server error, if any. <p>
+     *
+     * @return a Throwable indicating the last server error
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Indicating last exception state"
+     */
+    public Throwable getServerError() {
+        return serverError;
+    }
+
+    /**
+     * Retrieves a String identifying this Server object.
+     *
+     * @return a String identifying this Server object
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Identifying Server"
+     */
+    public String getServerId() {
+        return serverId;
+    }
+
+    /**
+     * Retrieves current state of this server in numerically coded form. <p>
+     *
+     * Typically, this will be one of: <p>
+     *
+     * <ol>
+     * <li>ServerProperties.SERVER_STATE_ONLINE (1)
+     * <li>ServerProperties.SERVER_STATE_OPENING (4)
+     * <li>ServerProperties.SERVER_STATE_CLOSING (8)
+     * <li>ServerProperties.SERVER_STATE_SHUTDOWN (16)
+     * </ol>
+     *
+     * @return this server's state code.
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="1:ONLINE 4:OPENING 8:CLOSING, 16:SHUTDOWN"
+     */
+    public int getState() {
+        return serverState;
+    }
+
+    /**
+     * Retrieves a character sequence describing this server's current state,
+     * including the message of the last exception, if there is one and it
+     * is still in context.
+     *
+     * @return this server's state represented as a character sequence.
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="State as string"
+     */
+    public String getStateDescriptor() {
+
+        String    state;
+        Throwable t = getServerError();
+
+        switch (serverState) {
+
+            case ServerConstants.SERVER_STATE_SHUTDOWN :
+                state = "SHUTDOWN";
+                break;
+
+            case ServerConstants.SERVER_STATE_OPENING :
+                state = "OPENING";
+                break;
+
+            case ServerConstants.SERVER_STATE_CLOSING :
+                state = "CLOSING";
+                break;
+
+            case ServerConstants.SERVER_STATE_ONLINE :
+                state = "ONLINE";
+                break;
+
+            default :
+                state = "UNKNOWN";
+                break;
+        }
+
+        return state;
+    }
+
+    /**
+     * Retrieves the root context (directory) from which web content
+     * is served.  This property is relevant only when the server
+     * protocol is HTTP(S).  Although unlikely, it may be that in the future
+     * other contexts, such as jar urls may be supported, so that pages can
+     * be served from the contents of a jar or from the JVM class path.
+     *
+     * @return the root context (directory) from which web content is served
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Context (directory)"
+     */
+    public String getWebRoot() {
+        return "[IGNORED]";
+    }
+
+    /**
+     * Assigns the specified socket to a new conection handler and
+     * starts the handler in a new Thread.
+     *
+     * @param s the socket to connect
+     */
+    public void handleConnection(Socket s) {
+
+        Thread   t;
+        Runnable r;
+        String   ctn;
+
+        printWithThread("handleConnection(" + s + ") entered");
+
+        if (!allowConnection(s)) {
+            try {
+                s.close();
+            } catch (Exception e) {}
+
+            printWithThread("allowConnection(): connection refused");
+            printWithThread("handleConnection() exited");
+
+            return;
+        }
+
+        // Maybe set up socket options, SSL
+        // Session tracing/callbacks, etc.
+        if (socketFactory != null) {
+            socketFactory.configureSocket(s);
+        }
+
+        if (serverProtocol == ServerConstants.SC_PROTOCOL_HSQL) {
+            r   = new ServerConnection(s, this);
+            ctn = ((ServerConnection) r).getConnectionThreadName();
+
+            synchronized (serverConnSet) {
+                serverConnSet.add(r);
+            }
+        } else {
+            r   = new WebServerConnection(s, (WebServer) this);
+            ctn = ((WebServerConnection) r).getConnectionThreadName();
+        }
+
+        t = new Thread(serverConnectionThreadGroup, r, ctn);
+
+        t.start();
+        printWithThread("handleConnection() exited");
+    }
+
+    /**
+     * Retrieves whether this server calls System.exit() when shutdown.
+     *
+     * @return true if this server does not call System.exit()
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="When Shutdown"
+     */
+    public boolean isNoSystemExit() {
+        return serverProperties.isPropertyTrue(
+            ServerConstants.SC_KEY_NO_SYSTEM_EXIT);
+    }
+
+    /**
+     * Retrieves whether this server restarts on shutdown.
+     *
+     * @return true this server restarts on shutdown
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Automatically?"
+     */
+    public boolean isRestartOnShutdown() {
+        return serverProperties.isPropertyTrue(
+            ServerConstants.SC_KEY_AUTORESTART_SERVER);
+    }
+
+    /**
+     * Retrieves whether silent mode operation was requested in
+     * the server properties.
+     *
+     * @return if true, silent mode was requested, else trace messages
+     *      are to be printed
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="No trace messages?"
+     */
+    public boolean isSilent() {
+        return isSilent;
+    }
+
+    /**
+     * Retrieves whether the use of secure sockets was requested in the
+     * server properties.
+     *
+     * @return if true, secure sockets are requested, else not
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Use TLS/SSL sockets?"
+     */
+    public boolean isTls() {
+        return serverProperties.isPropertyTrue(ServerConstants.SC_KEY_TLS);
+    }
+
+    /**
+     * Retrieves whether JDBC trace messages are to go to System.out or the
+     * DriverManger PrintStream/PrintWriter, if any.
+     *
+     * @return true if tracing is on (JDBC trace messages to system out)
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="JDBC trace messages to System.out?"
+     */
+    public boolean isTrace() {
+        return serverProperties.isPropertyTrue(ServerConstants.SC_KEY_TRACE);
+    }
+
+    /**
+     * Attempts to put properties from the file
+     * with the specified path. The file
+     * extension '.properties' is implicit and should not
+     * be included in the path specification.
+     *
+     * @param path the path of the desired properties file, without the
+     *      '.properties' file extension
+     * @throws RuntimeException if this server is running
+     * @return true if the indicated file was read sucessfully, else false
+     *
+     * @jmx.managed-operation
+     *  impact="ACTION"
+     *  description="Reads in properties"
+     *
+     * @jmx.managed-operation-parameter
+     *   name="path"
+     *   type="java.lang.String"
+     *   position="0"
+     *   description="(optional) returns false if path is empty"
+     */
+    public boolean putPropertiesFromFile(String path) {
+
+        if (getState() != ServerConstants.SERVER_STATE_SHUTDOWN) {
+            throw new RuntimeException();
+        }
+
+        path = FileUtil.getFileUtil().canonicalOrAbsolutePath(path);
+
+        HsqlProperties p = ServerConfiguration.getPropertiesFromFile(
+            ServerConstants.SC_PROTOCOL_HSQL, path);
+
+        if (p == null || p.isEmpty()) {
+            return false;
+        }
+
+        printWithThread("putPropertiesFromFile(): [" + path + ".properties]");
+
+        try {
+            setProperties(p);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to set properties: " + e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Puts properties from the supplied string argument.  The relevant
+     * key value pairs are the same as those for the (web)server.properties
+     * file format, except that the 'server.' prefix should not be specified.
+     *
+     * @param s semicolon-delimited key=value pair string,
+     *      e.g. silent=false;port=8080;...
+     * @throws RuntimeException if this server is running
+     *
+     * @jmx.managed-operation
+     *   impact="ACTION"
+     *   description="'server.' key prefix automatically supplied"
+     *
+     * @jmx.managed-operation-parameter
+     *   name="s"
+     *   type="java.lang.String"
+     *   position="0"
+     *   description="semicolon-delimited key=value pairs"
+     */
+    public void putPropertiesFromString(String s) {
+
+        if (getState() != ServerConstants.SERVER_STATE_SHUTDOWN) {
+            throw new RuntimeException();
+        }
+
+        if (StringUtil.isEmpty(s)) {
+            return;
+        }
+
+        printWithThread("putPropertiesFromString(): [" + s + "]");
+
+        HsqlProperties p = HsqlProperties.delimitedArgPairsToProps(s, "=",
+            ";", ServerConstants.SC_KEY_PREFIX);
+
+        try {
+            setProperties(p);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to set properties: " + e);
+        }
+    }
+
+    /**
+     * Sets the InetAddress with which this server's ServerSocket will be
+     * constructed.  A null or empty string or the special value "0.0.0.0"
+     * can be used to bypass explicit selection, causing the ServerSocket
+     * to be constructed without specifying an InetAddress.
+     *
+     * @param address A string representing the desired InetAddress as would
+     *    be retrieved by InetAddres.getByName(), or a null or empty string
+     *    or "0.0.0.0" to signify that the server socket should be constructed
+     *    using the signature that does not specify the InetAddress.
+     * @throws RuntimeException if this server is running
+     *
+     * @jmx.managed-attribute
+     */
+    public void setAddress(String address) throws RuntimeException {
+
+        checkRunning(false);
+
+        if (org.hsqldb.lib.StringUtil.isEmpty(address)) {
+            address = ServerConstants.SC_DEFAULT_ADDRESS;
+        }
+
+        printWithThread("setAddress(" + address + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_ADDRESS, address);
+    }
+
+    /**
+     * Sets the external name (url alias) of the i'th hosted database.
+     *
+     * @param name external name (url alias) of the i'th HSQLDB database
+     *      instance this server is to host.
+     * @throws RuntimeException if this server is running
+     *
+     * @jmx.managed-operation
+     *      impact="ACTION"
+     *      description="Sets the url alias by which is known the i'th hosted Database"
+     *
+     * @jmx.managed-operation-parameter
+     *      name="index"
+     *      type="int"
+     *      position="0"
+     *      description="This Server's index for the hosted Database"
+     *
+     * @jmx.managed-operation-parameter
+     *      name="name"
+     *      type="java.lang.String"
+     *      position="1"
+     *      description="url alias component for the hosted Database"
+     */
+    public void setDatabaseName(int index,
+                                String name) throws RuntimeException {
+
+        checkRunning(false);
+        printWithThread("setDatabaseName(" + index + "," + name + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_DBNAME + "."
+                                     + index, name);
+    }
+
+    /**
+     * Sets the path of the hosted database. The path always starts with the
+     * catalog type. Examples of the path include: "file:mydir/mydb",
+     * "mem:mymemdb", "res:org/mydomain/mydbs/settingsdb".
+     *
+     * @param path The path of the i'th HSQLDB database instance this server
+     *      is to host.
+     *
+     * @jmx.managed-operation
+     *      impact="ACTION"
+     *      description="Sets the database uri path for the i'th hosted Database"
+     *
+     * @jmx.managed-operation-parameter
+     *      name="index"
+     *      type="int"
+     *      position="0"
+     *      description="This Server's index for the hosted Database"
+     *
+     * @jmx.managed-operation-parameter
+     *      name="path"
+     *      type="java.lang.String"
+     *      position="1"
+     *      description="database uri path of the hosted Database"
+     */
+    public void setDatabasePath(int index,
+                                String path) throws RuntimeException {
+
+        checkRunning(false);
+        printWithThread("setDatabasePath(" + index + "," + path + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_DATABASE + "."
+                                     + index, path);
+    }
+
+    /**
+     * Sets the name of the web page served when no page is specified.
+     *
+     * @param file the name of the web page served when no page is specified
+     *
+     * @jmx.managed-attribute
+     */
+    public void setDefaultWebPage(String file) {
+
+        checkRunning(false);
+        printWithThread("setDefaultWebPage(" + file + ")");
+
+        if (serverProtocol != ServerConstants.SC_PROTOCOL_HTTP) {
+            return;
+        }
+
+        serverProperties.setProperty(ServerConstants.SC_KEY_WEB_DEFAULT_PAGE,
+                                     file);
+    }
+
+    /**
+     * Sets the server listen port.
+     *
+     * @param port the port at which this server listens
+     *
+     * @jmx.managed-attribute
+     */
+    public void setPort(int port) throws RuntimeException {
+
+        checkRunning(false);
+        printWithThread("setPort(" + port + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_PORT, port);
+    }
+
+    /**
+     * Sets the PrintWriter to which server errors are logged. <p>
+     *
+     * Setting this attribute to null disables server error logging
+     *
+     * @param pw the PrintWriter to which server messages are logged
+     */
+    public void setErrWriter(PrintWriter pw) {
+        errWriter = pw;
+    }
+
+    /**
+     * Sets the PrintWriter to which server messages are logged. <p>
+     *
+     * Setting this attribute to null disables server message logging
+     *
+     * @param pw the PrintWriter to which server messages are logged
+     */
+    public void setLogWriter(PrintWriter pw) {
+        logWriter = pw;
+    }
+
+    /**
+     * Sets whether this server calls System.exit() when shutdown.
+     *
+     * @param noExit if true, System.exit() will not be called.
+     *
+     * @jmx.managed-attribute
+     */
+    public void setNoSystemExit(boolean noExit) {
+
+        printWithThread("setNoSystemExit(" + noExit + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_NO_SYSTEM_EXIT,
+                                     noExit);
+    }
+
+    /**
+     * Sets whether this server restarts on shutdown.
+     *
+     * @param restart if true, this server restarts on shutdown
+     *
+     * @jmx.managed-attribute
+     */
+    public void setRestartOnShutdown(boolean restart) {
+
+        printWithThread("setRestartOnShutdown(" + restart + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_AUTORESTART_SERVER,
+                                     restart);
+    }
+
+    /**
+     * Sets silent mode operation
+     *
+     * @param silent if true, then silent mode, else trace messages
+     *  are to be printed
+     *
+     * @jmx.managed-attribute
+     */
+    public void setSilent(boolean silent) {
+
+        printWithThread("setSilent(" + silent + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_SILENT, silent);
+
+        isSilent = silent;
+    }
+
+    /**
+     * Sets whether to use secure sockets
+     *
+     * @param tls true for secure sockets, else false
+     * @throws RuntimeException if this server is running
+     *
+     * @jmx.managed-attribute
+     */
+    public void setTls(boolean tls) {
+
+        checkRunning(false);
+        printWithThread("setTls(" + tls + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_TLS, tls);
+    }
+
+    /**
+     * Sets whether trace messages go to System.out or the
+     * DriverManger PrintStream/PrintWriter, if any.
+     *
+     * @param trace if true, route JDBC trace messages to System.out
+     *
+     * @jmx.managed-attribute
+     */
+    public void setTrace(boolean trace) {
+
+        printWithThread("setTrace(" + trace + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_TRACE, trace);
+        JavaSystem.setLogToSystem(trace);
+    }
+
+    /**
+     * Sets whether server thread is a daemon. Used before starting
+     *
+     * @jmx.managed-attribute
+     */
+    public void setDaemon(boolean daemon) {
+
+        checkRunning(false);
+        printWithThread("setDaemon(" + daemon + ")");
+        serverProperties.setProperty(ServerConstants.SC_KEY_DAEMON, daemon);
+    }
+
+    /**
+     * Sets the path of the root directory from which web content is served.
+     *
+     * @param root the root (context) directory from which web content
+     *      is served
+     *
+     * @jmx.managed-attribute
+     */
+    public void setWebRoot(String root) {
+
+        checkRunning(false);
+
+        root = (new File(root)).getAbsolutePath();
+
+        printWithThread("setWebRoot(" + root + ")");
+
+        if (serverProtocol != ServerConstants.SC_PROTOCOL_HTTP) {
+            return;
+        }
+
+        serverProperties.setProperty(ServerConstants.SC_KEY_WEB_ROOT, root);
+    }
+
+    /**
+     * Sets server properties using the specified properties object
+     *
+     * @param p The object containing properties to set
+     * @throws ServerAcl.AclFormatException
+     *          ACL list was requested but problem loading ACL.
+     * @throws IOException
+     *          ACL list was requested but I/O problem loading ACL.
+     */
+    public void setProperties(HsqlProperties p)
+    throws IOException, ServerAcl.AclFormatException {
+
+        checkRunning(false);
+
+        if (p != null) {
+            serverProperties.addProperties(p);
+            ServerConfiguration.translateAddressProperty(serverProperties);
+        }
+
+        maxConnections = serverProperties.getIntegerProperty(
+            ServerConstants.SC_KEY_MAX_CONNECTIONS, 16);
+
+        JavaSystem.setLogToSystem(isTrace());
+
+        isSilent =
+            serverProperties.isPropertyTrue(ServerConstants.SC_KEY_SILENT);
+        isRemoteOpen = serverProperties.isPropertyTrue(
+            ServerConstants.SC_KEY_REMOTE_OPEN_DB);
+        isDaemon =
+            serverProperties.isPropertyTrue(ServerConstants.SC_KEY_DAEMON);
+
+        String aclFilepath =
+            serverProperties.getProperty(ServerConstants.SC_KEY_ACL_FILEPATH);
+
+        if (aclFilepath != null) {
+            acl = new ServerAcl(new File(aclFilepath));;
+
+            if (logWriter != null && !isSilent) {
+                acl.setPrintWriter(logWriter);
+            }
+        }
+    }
+
+    /**
+     * Starts this server synchronously. <p>
+     *
+     * This method waits for current state to change from
+     * SERVER_STATE_OPENNING. In order to discover the success or failure
+     * of this operation, server state must be polled or a subclass of Server
+     * must be used that overrides the setState method to provide state
+     * change notification.
+     *
+     * @return the server state noted at entry to this method
+     *
+     * @jmx.managed-operation
+     *  impact="ACTION_INFO"
+     *  description="Invokes asynchronous startup sequence; returns previous state"
+     */
+    public int start() {
+
+        printWithThread("start() entered");
+
+        int previousState = getState();
+
+        if (serverThread != null) {
+            printWithThread("start(): serverThread != null; no action taken");
+
+            return previousState;
+        }
+
+        setState(ServerConstants.SERVER_STATE_OPENING);
+
+        serverThread = new ServerThread("HSQLDB Server ");
+
+        if (isDaemon) {
+            serverThread.setDaemon(true);
+        }
+
+        serverThread.start();
+
+        // call synchronized getState() to become owner of the Server Object's monitor
+        while (getState() == ServerConstants.SERVER_STATE_OPENING) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {}
+        }
+
+        printWithThread("start() exiting");
+
+        return previousState;
+    }
+
+    /**
+     * Stops this server asynchronously. <p>
+     *
+     * This method returns immediately, regardless of current state.  In order
+     * to discover the success or failure of this operation, server state must
+     * be polled or a subclass of Server must be used that overrides the
+     * setState method to provide state change notification.
+     *
+     * @return the server state noted at entry to this method
+     *
+     * @jmx.managed-operation
+     *  impact="ACTION_INFO"
+     *  description="Invokes asynchronous shutdown sequence; returns previous state"
+     */
+    public int stop() {
+
+        printWithThread("stop() entered");
+
+        int previousState = getState();
+
+        if (serverThread == null) {
+            printWithThread("stop() serverThread is null; no action taken");
+
+            return previousState;
+        }
+
+        releaseServerSocket();
+        printWithThread("stop() exiting");
+
+        return previousState;
+    }
+
+    /**
+     * Retrieves whether the specified socket should be allowed
+     * to make a connection.  By default, this method always returns
+     * true, but it can be overidden to implement hosts allow-deny
+     * functionality.
+     *
+     * @param socket the socket to test.
+     */
+    protected boolean allowConnection(Socket socket) {
+
+        return (acl == null) ? true
+                             : acl.permitAccess(
+                                 socket.getInetAddress().getAddress());
+    }
+
+    /**
+     * Initializes this server, setting the accepted connection protocol.
+     *
+     * @param protocol typically either SC_PROTOCOL_HTTP or SC_PROTOCOL_HSQL
+     */
+    protected void init(int protocol) {
+
+        // PRE:  This method is only called from the constructor
+        serverState      = ServerConstants.SERVER_STATE_SHUTDOWN;
+        serverConnSet    = new HashSet();
+        serverId         = toString();
+        serverId         = serverId.substring(serverId.lastIndexOf('.') + 1);
+        serverProtocol   = protocol;
+        serverProperties = ServerConfiguration.newDefaultProperties(protocol);
+        logWriter        = new PrintWriter(System.out);
+        errWriter        = new PrintWriter(System.err);
+
+        JavaSystem.setLogToSystem(isTrace());
+    }
+
+    /**
+     * Sets the server state value.
+     *
+     * @param state the new value
+     */
+    protected synchronized void setState(int state) {
+        serverState = state;
+    }
+
+    /**
+     * This is called from org.hsqldb.DatabaseManager when a database is
+     * shutdown. This shuts the server down if it is the last database
+     *
+     * @param action a code indicating what has happend
+     */
+    public final void notify(int action, int id) {
+
+        printWithThread("notifiy(" + action + "," + id + ") entered");
+
+        if (action != ServerConstants.SC_DATABASE_SHUTDOWN) {
+            return;
+        }
+
+        releaseDatabase(id);
+
+        boolean shutdown = true;
+
+        for (int i = 0; i < dbID.length; i++) {
+            if (dbAlias[i] != null) {
+                shutdown = false;
+            }
+        }
+
+        if (!isRemoteOpen && shutdown) {
+            stop();
+        }
+    }
+
+    /**
+     * This releases the resources used for a database.
+     * Is called with id 0 multiple times for non-existent databases
+     */
+    final synchronized void releaseDatabase(int id) {
+
+        Iterator it;
+        boolean  found = false;
+
+        printWithThread("releaseDatabase(" + id + ") entered");
+
+        // check all slots as a database may be opened by multiple aliases
+        for (int i = 0; i < dbID.length; i++) {
+            if (dbID[i] == id && dbAlias[i] != null) {
+                dbID[i]             = 0;
+                dbActionSequence[i] = 0;
+                dbAlias[i]          = null;
+                dbPath[i]           = null;
+                dbType[i]           = null;
+                dbProps[i]          = null;
+            }
+        }
+
+        synchronized (serverConnSet) {
+            it = new WrapperIterator(serverConnSet.toArray(null));
+        }
+
+        while (it.hasNext()) {
+            ServerConnection sc = (ServerConnection) it.next();
+
+            if (sc.dbID == id) {
+                sc.signalClose();
+                serverConnSet.remove(sc);
+            }
+        }
+
+        printWithThread("releaseDatabase(" + id + ") exiting");
+    }
+
+    /**
+     * Prints the specified message, s, formatted to identify that the print
+     * operation is against this server instance.
+     *
+     * @param msg The message to print
+     */
+    protected void print(String msg) {
+
+        PrintWriter writer = logWriter;
+
+        if (writer != null) {
+            writer.println("[" + serverId + "]: " + msg);
+            writer.flush();
+        }
+    }
+
+    /**
+     * Prints value from server's resource bundle, formatted to
+     * identify that the print operation is against this server instance.
+     * Value may be localized according to the default JVM locale
+     *
+     * @param key the resource key
+     */
+    final void printResource(String key) {
+
+        String          resource;
+        StringTokenizer st;
+
+        if (serverBundleHandle < 0) {
+            return;
+        }
+
+        resource = BundleHandler.getString(serverBundleHandle, key);
+
+        if (resource == null) {
+            return;
+        }
+
+        st = new StringTokenizer(resource, "\n\r");
+
+        while (st.hasMoreTokens()) {
+            print(st.nextToken());
+        }
+    }
+
+    /**
+     * Prints the stack trace of the Throwable, t, to this Server object's
+     * errWriter. <p>
+     *
+     * @param t the Throwable whose stack trace is to be printed
+     */
+    protected void printStackTrace(Throwable t) {
+
+        if (errWriter != null) {
+            t.printStackTrace(errWriter);
+            errWriter.flush();
+        }
+    }
+
+    /**
+     * Prints the specified message, s, prepended with a timestamp representing
+     * the current date and time, formatted to identify that the print
+     * operation is against this server instance.
+     *
+     * @param msg the message to print
+     */
+    final void printWithTimestamp(String msg) {
+        print(HsqlDateTime.getSytemTimeString() + " " + msg);
+    }
+
+    /**
+     * Prints a message formatted similarly to print(String), additionally
+     * identifying the current (calling) thread. Replaces old method
+     * trace(String msg).
+     *
+     * @param msg the message to print
+     */
+    protected void printWithThread(String msg) {
+
+        if (!isSilent()) {
+            print("[" + Thread.currentThread() + "]: " + msg);
+        }
+    }
+
+    /**
+     * Prints an error message to this Server object's errWriter.
+     * The message is formatted similarly to print(String),
+     * additionally identifying the current (calling) thread.
+     *
+     * @param msg the message to print
+     */
+    protected void printError(String msg) {
+
+        PrintWriter writer = errWriter;
+
+        if (writer != null) {
+            writer.print("[" + serverId + "]: ");
+            writer.print("[" + Thread.currentThread() + "]: ");
+            writer.println(msg);
+            writer.flush();
+        }
+    }
+
+    /**
+     * Prints a description of the request encapsulated by the
+     * Result argument, r.
+     *
+     * Printing occurs iff isSilent() is false. <p>
+     *
+     * The message is formatted similarly to print(String), additionally
+     * indicating the connection identifier.  <p>
+     *
+     * For Server instances, cid is typically the value assigned to each
+     * ServerConnection object that is unique amongst all such identifiers
+     * in each distinct JVM session / class loader
+     * context. <p>
+     *
+     * For WebServer instances, a single logical connection actually spawns
+     * a new physical WebServerConnection object for each request, so the
+     * cid is typically the underlying session id, since that does not
+     * change for the duration of the logical connection.
+     *
+     * @param cid the connection identifier
+     * @param r the request whose description is to be printed
+     */
+    final void printRequest(int cid, Result r) {
+
+        if (isSilent()) {
+            return;
+        }
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(cid);
+        sb.append(':');
+
+        switch (r.getType()) {
+
+            case ResultConstants.PREPARE : {
+                sb.append("SQLCLI:SQLPREPARE ");
+                sb.append(r.getMainString());
+
+                break;
+            }
+            case ResultConstants.EXECDIRECT : {
+                sb.append(r.getMainString());
+
+                break;
+            }
+            case ResultConstants.EXECUTE : {
+                sb.append("SQLCLI:SQLEXECUTE:");
+                sb.append(r.getStatementID());
+
+/**
+ * @todo 1.9.0 - fredt - fix this without appendStringValueOf - use type to convert to string
+ */
+/*
+                if (r.getSize() == 1) {
+                    sb.append('\n');
+                    StringUtil.appendStringValueOf(r.getParameterData(), sb, true);
+                }
+*/
+                break;
+            }
+            case ResultConstants.BATCHEXECUTE :
+                sb.append("SQLCLI:SQLEXECUTE:");
+                sb.append("BATCHMODE:");
+                sb.append(r.getStatementID());
+                break;
+
+            case ResultConstants.UPDATE_RESULT : {
+                sb.append("SQLCLI:RESULTUPDATE:");
+                sb.append(r.getStatementID());
+
+                break;
+            }
+            case ResultConstants.FREESTMT : {
+                sb.append("SQLCLI:SQLFREESTMT:");
+                sb.append(r.getStatementID());
+
+                break;
+            }
+            case ResultConstants.GETSESSIONATTR : {
+                sb.append("HSQLCLI:GETSESSIONATTR");
+
+                break;
+            }
+            case ResultConstants.SETSESSIONATTR : {
+                sb.append("HSQLCLI:SETSESSIONATTR:");
+
+                break;
+            }
+            case ResultConstants.ENDTRAN : {
+                sb.append("SQLCLI:SQLENDTRAN:");
+
+                switch (r.getActionType()) {
+
+                    case ResultConstants.TX_COMMIT :
+                        sb.append("COMMIT");
+                        break;
+
+                    case ResultConstants.TX_ROLLBACK :
+                        sb.append("ROLLBACK");
+                        break;
+
+                    case ResultConstants.TX_SAVEPOINT_NAME_RELEASE :
+                        sb.append("SAVEPOINT_NAME_RELEASE ");
+                        sb.append(r.getMainString());
+                        break;
+
+                    case ResultConstants.TX_SAVEPOINT_NAME_ROLLBACK :
+                        sb.append("SAVEPOINT_NAME_ROLLBACK ");
+                        sb.append(r.getMainString());
+                        break;
+
+                    default :
+                        sb.append(r.getActionType());
+                }
+
+                break;
+            }
+            case ResultConstants.STARTTRAN : {
+                sb.append("SQLCLI:SQLSTARTTRAN");
+
+                break;
+            }
+            case ResultConstants.DISCONNECT : {
+                sb.append("SQLCLI:SQLDISCONNECT");
+
+                break;
+            }
+            case ResultConstants.SETCONNECTATTR : {
+                sb.append("SQLCLI:SQLSETCONNECTATTR:");
+
+                switch (r.getConnectionAttrType()) {
+
+                    case ResultConstants.SQL_ATTR_SAVEPOINT_NAME : {
+                        sb.append("SQL_ATTR_SAVEPOINT_NAME ");
+                        sb.append(r.getMainString());
+
+                        break;
+                    }
+                    default : {
+                        sb.append(r.getConnectionAttrType());
+                    }
+                }
+
+                break;
+            }
+            default : {
+                sb.append("SQLCLI:MODE:");
+                sb.append(r.getType());
+
+                break;
+            }
+        }
+
+        print(sb.toString());
+    }
+
+    /**
+     * return database ID
+     */
+    synchronized final int getDBIndex(String aliasPath) {
+
+        int    semipos  = aliasPath.indexOf(';');
+        String alias    = aliasPath;
+        String filepath = null;
+
+        if (semipos != -1) {
+            alias    = aliasPath.substring(0, semipos);
+            filepath = aliasPath.substring(semipos + 1);
+        }
+
+        int dbIndex = ArrayUtil.find(dbAlias, alias);
+
+        if (dbIndex == -1) {
+            if (filepath == null) {
+                RuntimeException e =
+                    new RuntimeException("database alias does not exist");
+
+                printError("database alias=" + alias + " does not exist");
+                setServerError(e);
+
+                throw e;
+            } else {
+                return openDatabase(alias, filepath);
+            }
+        } else {
+            return dbIndex;
+        }
+    }
+
+    /**
+     * Open and return database index
+     */
+    final int openDatabase(String alias, String datapath) {
+
+        if (!isRemoteOpen) {
+            RuntimeException e =
+                new RuntimeException("remote open not allowed");
+
+            printError("Remote database open not allowed");
+            setServerError(e);
+
+            throw e;
+        }
+
+        int i = getFirstEmptyDatabaseIndex();
+
+        if (i < -1) {
+            i = closeOldestDatabase();
+
+            if (i < -1) {
+                RuntimeException e =
+                    new RuntimeException("limit of open databases reached");
+
+                printError("limit of open databases reached");
+                setServerError(e);
+
+                throw e;
+            }
+        }
+
+        HsqlProperties newprops = DatabaseURL.parseURL(datapath, false, false);
+
+        if (newprops == null) {
+            RuntimeException e = new RuntimeException("invalid database path");
+
+            printError("invalid database path");
+            setServerError(e);
+
+            throw e;
+        }
+
+        String path = newprops.getProperty(DatabaseURL.url_database);
+        String type = newprops.getProperty(DatabaseURL.url_connection_type);
+
+        try {
+            int dbid = DatabaseManager.getDatabase(type, path, this, newprops);
+
+            dbID[i]             = dbid;
+            dbActionSequence[i] = actionSequence;
+            dbAlias[i]          = alias;
+            dbPath[i]           = path;
+            dbType[i]           = type;
+            dbProps[i]          = newprops;
+
+            return i;
+        } catch (HsqlException e) {
+            printError("Database [index=" + i + ", db=" + dbType[i]
+                       + dbPath[i] + ", alias=" + dbAlias[i]
+                       + "] did not open: " + e.toString());
+            setServerError(e);
+
+            throw e;
+        }
+    }
+
+    final int getFirstEmptyDatabaseIndex() {
+
+        for (int i = 0; i < dbAlias.length; i++) {
+            if (dbAlias[i] == null) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Opens this server's database instances. This method returns true If
+     * at least one database goes online, otherwise it returns false.
+     *
+     * If openning any of the databases is attempted and an exception is
+     * thrown, the server error is set to this exception.
+     */
+    final boolean openDatabases() {
+
+        printWithThread("openDatabases() entered");
+
+        boolean success = false;
+
+        setDBInfoArrays();
+
+        for (int i = 0; i < dbAlias.length; i++) {
+            if (dbAlias[i] == null) {
+                continue;
+            }
+
+            printWithThread("Opening database: [" + dbType[i] + dbPath[i]
+                            + "]");
+
+            StopWatch sw = new StopWatch();
+            int       id;
+
+            try {
+                id = DatabaseManager.getDatabase(dbType[i], dbPath[i], this,
+                                                 dbProps[i]);
+                dbID[i] = id;
+                success = true;
+            } catch (HsqlException e) {
+                printError("Database [index=" + i + ", db=" + dbType[i]
+                           + dbPath[i] + ", alias=" + dbAlias[i]
+                           + "] did not open: " + e.toString());
+                setServerError(e);
+
+                dbAlias[i] = null;
+                dbPath[i]  = null;
+                dbType[i]  = null;
+                dbProps[i] = null;
+
+                continue;
+            }
+
+            sw.stop();
+
+            String msg = "Database [index=" + i + ", id=" + id + ", db="
+                         + dbType[i] + dbPath[i] + ", alias=" + dbAlias[i]
+                         + "] opened sucessfully";
+
+            print(sw.elapsedTimeToMessage(msg));
+        }
+
+        printWithThread("openDatabases() exiting");
+
+        if (isRemoteOpen) {
+            success = true;
+        }
+
+        if (!success && getServerError() == null) {
+
+            // database alias / path list is empty or without full info for any DB
+            setServerError(Error.error(ErrorCode.SERVER_NO_DATABASE));
+        }
+
+        return success;
+    }
+
+    /**
+     * Initialises the database attributes lists from the server properties object.
+     */
+    private void setDBInfoArrays() {
+
+        IntKeyHashMap dbNumberMap  = getDBNameArray();
+        int           maxDatabases = dbNumberMap.size();
+
+        if (serverProperties.isPropertyTrue(
+                ServerConstants.SC_KEY_REMOTE_OPEN_DB)) {
+            int max = serverProperties.getIntegerProperty(
+                ServerConstants.SC_KEY_MAX_DATABASES,
+                ServerConstants.SC_DEFAULT_MAX_DATABASES);
+
+            if (maxDatabases < max) {
+                maxDatabases = max;
+            }
+        }
+
+        dbAlias          = new String[maxDatabases];
+        dbPath           = new String[dbAlias.length];
+        dbType           = new String[dbAlias.length];
+        dbID             = new int[dbAlias.length];
+        dbActionSequence = new long[dbAlias.length];
+        dbProps          = new HsqlProperties[dbAlias.length];
+
+        Iterator it = dbNumberMap.keySet().iterator();
+
+        for (int i = 0; it.hasNext(); ) {
+            int    dbNumber = it.nextInt();
+            String path     = getDatabasePath(dbNumber, true);
+
+            if (path == null) {
+                printWithThread("missing database path: "
+                                + dbNumberMap.get(dbNumber));
+
+                continue;
+            }
+
+            HsqlProperties dbURL = DatabaseURL.parseURL(path, false, false);
+
+            if (dbURL == null) {
+                printWithThread("malformed database path: " + path);
+
+                continue;
+            }
+
+            dbAlias[i] = (String) dbNumberMap.get(dbNumber);
+            dbPath[i]  = dbURL.getProperty("database");
+            dbType[i]  = dbURL.getProperty("connection_type");
+            dbProps[i] = dbURL;
+
+            i++;
+        }
+    }
+
+    /**
+     * Returns a map of n values from server.dbname.n values to database names
+     * from the properties object.
+     */
+    private IntKeyHashMap getDBNameArray() {
+
+        final String  prefix       = ServerConstants.SC_KEY_DBNAME + ".";
+        final int     prefixLen    = prefix.length();
+        IntKeyHashMap idToAliasMap = new IntKeyHashMap();
+        Enumeration   en           = serverProperties.propertyNames();
+
+        for (; en.hasMoreElements(); ) {
+            String key = (String) en.nextElement();
+
+            if (!key.startsWith(prefix)) {
+                continue;
+            }
+
+            int dbNumber;
+
+            try {
+                dbNumber = Integer.parseInt(key.substring(prefixLen));
+            } catch (NumberFormatException e1) {
+                printWithThread("maformed database enumerator: " + key);
+
+                continue;
+            }
+
+            String alias = serverProperties.getProperty(key).toLowerCase();
+
+            if (!aliasSet.add(alias)) {
+                printWithThread("duplicate alias: " + alias);
+            }
+
+            Object existing = idToAliasMap.put(dbNumber, alias);
+
+            if (existing != null) {
+                printWithThread("duplicate database enumerator: " + key);
+            }
+        }
+
+        return idToAliasMap;
+    }
+
+    /**
+     * Constructs and installs a new ServerSocket instance for this server.
+     *
+     * @throws Exception if it is not possible to construct and install
+     *      a new ServerSocket
+     */
+    private void openServerSocket() throws Exception {
+
+        String    address;
+        int       port;
+        String[]  candidateAddrs;
+        String    emsg;
+        StopWatch sw;
+
+        printWithThread("openServerSocket() entered");
+
+        if (isTls()) {
+            printWithThread("Requesting TLS/SSL-encrypted JDBC");
+        }
+
+        sw            = new StopWatch();
+        socketFactory = HsqlSocketFactory.getInstance(isTls());
+        address       = getAddress();
+        port          = getPort();
+
+        if (org.hsqldb.lib.StringUtil.isEmpty(address)
+                || ServerConstants.SC_DEFAULT_ADDRESS.equalsIgnoreCase(
+                    address.trim())) {
+            socket = socketFactory.createServerSocket(port);
+        } else {
+            try {
+                socket = socketFactory.createServerSocket(port, address);
+            } catch (UnknownHostException e) {
+                candidateAddrs =
+                    ServerConfiguration.listLocalInetAddressNames();
+
+                int      messageID;
+                Object[] messageParameters;
+
+                if (candidateAddrs.length > 0) {
+                    messageID = ErrorCode.M_SERVER_OPEN_SERVER_SOCKET_1;
+
+                    StringBuffer sb = new StringBuffer();
+
+                    for (int i = 0; i < candidateAddrs.length; i++) {
+                        if (sb.length() > 0) {
+                            sb.append(", ");
+                        }
+
+                        sb.append(candidateAddrs[i]);
+                    }
+
+                    messageParameters = new Object[] {
+                        address, sb.toString()
+                    };
+                } else {
+                    messageID = ErrorCode.M_SERVER_OPEN_SERVER_SOCKET_2;
+                    messageParameters = new Object[]{ address };
+                }
+
+                throw new UnknownHostException(Error.getMessage(messageID, 0,
+                        messageParameters));
+            }
+        }
+
+        /*
+         * Following line necessary for Java 1.3 on UNIX.  See accept()
+         * comment elsewhere in this file.
+         */
+        socket.setSoTimeout(1000);
+        printWithThread("Got server socket: " + socket);
+        print(sw.elapsedTimeToMessage("Server socket opened successfully"));
+
+        if (socketFactory.isSecure()) {
+            print("Using TLS/SSL-encrypted JDBC");
+        }
+
+        printWithThread("openServerSocket() exiting");
+    }
+
+    /** Prints a timestamped message indicating that this server is online */
+    private void printServerOnlineMessage() {
+
+        String s = getProductName() + " " + getProductVersion()
+                   + " is online on port " + this.getPort();
+        ;
+
+        printWithTimestamp(s);
+        printResource("online.help");
+    }
+
+    /**
+     * Prints a description of the server properties iff !isSilent().
+     */
+    protected void printProperties() {
+
+        Enumeration e;
+        String      key;
+        String      value;
+
+        // Avoid the waste of generating each description,
+        // only for trace() to silently discard it
+        if (isSilent()) {
+            return;
+        }
+
+        e = serverProperties.propertyNames();
+
+        while (e.hasMoreElements()) {
+            key   = (String) e.nextElement();
+            value = serverProperties.getProperty(key);
+
+            printWithThread(key + "=" + value);
+        }
+    }
+
+    /**
+     * Puts this server into the SERVER_CLOSING state, closes the ServerSocket
+     * and nullifies the reference to it. If the ServerSocket is already null,
+     * this method exists immediately, otherwise, the result is to fully
+     * shut down the server.
+     */
+    private void releaseServerSocket() {
+
+        printWithThread("releaseServerSocket() entered");
+
+        if (socket != null) {
+            printWithThread("Releasing server socket: [" + socket + "]");
+            setState(ServerConstants.SERVER_STATE_CLOSING);
+
+            try {
+                socket.close();
+            } catch (IOException e) {
+                printError("Exception closing server socket");
+                printError("releaseServerSocket(): " + e);
+            }
+
+            socket = null;
+        }
+
+        printWithThread("releaseServerSocket() exited");
+    }
+
+    /**
+     * Attempts to bring this server fully online by opening
+     * a new ServerSocket, obtaining the hosted databases,
+     * notifying the status waiter thread (if any) and
+     * finally entering the listen loop if all else succeeds.
+     * If any part of the process fails, then this server enters
+     * its shutdown sequence.
+     */
+    private void run() {
+
+        StopWatch   sw;
+        ThreadGroup tg;
+        String      tgName;
+
+        printWithThread("run() entered");
+        print("Initiating startup sequence...");
+        printProperties();
+
+        sw = new StopWatch();
+
+        setServerError(null);
+
+        try {
+
+            // Faster init first:
+            // It is huge waste to fully open the databases, only
+            // to find that the socket address is already in use
+            openServerSocket();
+        } catch (Exception e) {
+            setServerError(e);
+            printError("run()/openServerSocket(): ");
+            printStackTrace(e);
+            shutdown(true);
+
+            return;
+        }
+
+        tgName = "HSQLDB Connections @"
+                 + Integer.toString(this.hashCode(), 16);
+        tg = new ThreadGroup(tgName);
+
+        tg.setDaemon(false);
+
+        serverConnectionThreadGroup = tg;
+
+        // Mount the databases this server is supposed to host.
+        // This may take some time if the databases are not all
+        // already open.
+        if (!openDatabases()) {
+            setServerError(null);
+            printError("Shutting down because there are no open databases");
+            shutdown(true);
+
+            return;
+        }
+
+        // At this point, we have a valid server socket and
+        // a valid hosted database set, so its OK to start
+        // listening for connections.
+        setState(ServerConstants.SERVER_STATE_ONLINE);
+        print(sw.elapsedTimeToMessage("Startup sequence completed"));
+        printServerOnlineMessage();
+
+        try {
+            /*
+             * This loop is necessary for UNIX w/ Sun Java 1.3 because
+             * in that case the socket.close() elsewhere will not
+             * interrupt this accept().
+             */
+            while (true) {
+                try {
+                    handleConnection(socket.accept());
+                } catch (java.io.InterruptedIOException iioe) {}
+            }
+        } catch (IOException ioe) {
+            if (getState() == ServerConstants.SERVER_STATE_ONLINE) {
+                setServerError(ioe);
+                printError(this + ".run()/handleConnection(): ");
+                printStackTrace(ioe);
+            }
+        } catch (Throwable t) {
+            printWithThread(t.toString());
+        } finally {
+            shutdown(false);    // or maybe getServerError() != null?
+        }
+    }
+
+    /**
+     * Sets this Server's last encountered error state.
+     *
+     * @param t The new value for the server error
+     */
+    protected void setServerError(Throwable t) {
+        serverError = t;
+    }
+
+    /**
+     * External method to shut down this server.
+     */
+    public void shutdown() {
+        shutdown(false);
+    }
+
+    /**
+     * Shuts down this server.
+     *
+     * @param error true if shutdown is in response to an error
+     *      state, else false
+     */
+    protected synchronized void shutdown(boolean error) {
+
+        if (serverState == ServerConstants.SERVER_STATE_SHUTDOWN) {
+            return;
+        }
+
+        StopWatch sw;
+
+        printWithThread("shutdown() entered");
+
+        sw = new StopWatch();
+
+        print("Initiating shutdown sequence...");
+        releaseServerSocket();
+        DatabaseManager.deRegisterServer(this);
+
+        if (dbPath != null) {
+            for (int i = 0; i < dbPath.length; i++) {
+                releaseDatabase(dbID[i]);
+            }
+        }
+
+        // Be nice and let applications exit if there are no
+        // running connection threads
+        if (serverConnectionThreadGroup != null) {
+            if (!serverConnectionThreadGroup.isDestroyed()) {
+                for (int i = 0; serverConnectionThreadGroup.activeCount() > 0;
+                        i++) {
+                    int count;
+
+                    try {
+                        Thread.sleep(100);
+                    } catch (Exception e) {
+
+                        // e.getMessage();
+                    }
+                }
+
+                try {
+                    serverConnectionThreadGroup.destroy();
+                    printWithThread(serverConnectionThreadGroup.getName()
+                                    + " destroyed");
+                } catch (Throwable t) {
+                    printWithThread(serverConnectionThreadGroup.getName()
+                                    + " not destroyed");
+                    printWithThread(t.toString());
+                }
+            }
+
+            serverConnectionThreadGroup = null;
+        }
+
+        serverThread = null;
+
+        setState(ServerConstants.SERVER_STATE_SHUTDOWN);
+        print(sw.elapsedTimeToMessage("Shutdown sequence completed"));
+
+        if (isNoSystemExit()) {
+            printWithTimestamp("SHUTDOWN : System.exit() was not called");
+            printWithThread("shutdown() exited");
+        } else {
+            printWithTimestamp("SHUTDOWN : System.exit() is called next");
+            printWithThread("shutdown() exiting...");
+
+            try {
+                System.exit(0);
+            } catch (Throwable t) {
+                printWithThread(t.toString());
+            }
+        }
+    }
+
+    /**
+     * Used by Connection object
+     */
+    synchronized void setActionSequence(int dbIndex) {
+        dbActionSequence[dbIndex] = actionSequence++;
+    }
+
+    /**
+     * Feature is turned off by, pending a property to allow it.
+     */
+    protected int closeOldestDatabase() {
+
+        return -1;
+/*
+        int      index = -1;
+        Database db;
+
+        synchronized (this) {
+            long min = Long.MAX_VALUE;
+
+            for (int i = 0; i < dbActionSequence.length; i++) {
+                if (min > dbActionSequence[i]) {
+                    min   = dbActionSequence[i];
+                    index = i;
+                }
+            }
+
+            if (index == -1) {
+                return -1;
+            }
+
+            db = DatabaseManager.lookupDatabaseObject(dbType[index],
+                    dbPath[index]);
+
+            if (db == null) {
+                return -1;
+            }
+        }
+
+        db.close(Database.CLOSEMODE_IMMEDIATELY);
+
+        return index;
+ */
+    }
+
+    /**
+     * Prints message for the specified key, without any special
+     * formatting. The message content comes from the server
+     * resource bundle and thus may localized according to the default
+     * JVM locale.<p>
+     *
+     * Uses System.out directly instead of Trace.printSystemOut() so it
+     * always prints, regardless of Trace settings.
+     *
+     * @param key for message
+     */
+    protected static void printHelp(String key) {
+        System.out.println(BundleHandler.getString(serverBundleHandle, key));
+    }
+
+    /**
+     * Creates and starts a new Server.  <p>
+     *
+     * Allows starting a Server via the command line interface. <p>
+     *
+     * @param args the command line arguments for the Server instance
+     */
+    public static void main(String[] args) {
+
+        String propsPath =
+            FileUtil.getFileUtil().canonicalOrAbsolutePath("server");
+        ServerProperties fileProps = ServerConfiguration.getPropertiesFromFile(
+            ServerConstants.SC_PROTOCOL_HSQL, propsPath);
+        ServerProperties props =
+            fileProps == null
+            ? new ServerProperties(ServerConstants.SC_PROTOCOL_HSQL)
+            : fileProps;
+        HsqlProperties stringProps = null;
+
+        stringProps = HsqlProperties.argArrayToProps(args,
+                ServerConstants.SC_KEY_PREFIX);
+
+        if (stringProps.getErrorKeys().length != 0) {
+            printHelp("server.help");
+
+            return;
+        }
+
+        props.addProperties(stringProps);
+        ServerConfiguration.translateDefaultDatabaseProperty(props);
+
+        // Standard behaviour when started from the command line
+        // is to halt the VM when the server shuts down.  This may, of
+        // course, be overridden by whatever, if any, security policy
+        // is in place.
+        ServerConfiguration.translateDefaultNoSystemExitProperty(props);
+
+        // finished setting up properties;
+        Server server = new Server();
+
+        try {
+            server.setProperties(props);
+            props.validate();
+
+            // This must be called after setProperties, because stringProps
+            // isn't populated until then.
+        } catch (Exception e) {
+            server.printError("Failed to set properties");
+            server.printStackTrace(e);
+
+            return;
+        }
+
+        // now messages go to the channel specified in properties
+        server.print("Startup sequence initiated from main() method");
+
+        if (fileProps != null) {
+            server.print("Loaded properties from [" + propsPath
+                         + ".properties]");
+        } else {
+            server.print("Could not load properties from file");
+            server.print("Using cli/default properties only");
+        }
+
+        server.start();
+    }
+}
diff --git a/src/org/hsqldb/server/ServerAcl.java b/src/org/hsqldb/server/ServerAcl.java
new file mode 100644
index 0000000..115d973
--- /dev/null
+++ b/src/org/hsqldb/server/ServerAcl.java
@@ -0,0 +1,525 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.hsqldb.store.BitMap;
+
+/**
+ * A list of ACL permit and deny entries with a permitAccess method
+ * which tells whether candidate addresses are permitted or denied
+ * by this ACL list.
+ * <P>
+ * The ACL file is reloaded whenever a modification to it is detected.
+ * If you copy in a file with an older file date, you will need to touch it.
+ * </P>
+ *
+ * <P>
+ * The public runtime method is permitAccess().
+ * The public setup method is the constructor.
+ * </P> <P>
+ * Each non-comment line in the ACL file must be a rule of the format:
+ * <PRE><CODE>
+ *     {allow|deny} <ip_address>[/significant-bits]
+ * </CODE></PRE>
+ * For example
+ * <PRE><CODE>
+ *     allow ahostname
+ *     deny ahost.domain.com
+ *     allow 127.0.0.1
+ *     allow 2001:db8::/32
+ * </CODE></PRE>
+ * </P> <P>
+ * In order to detect bit specification mistakes, we require that
+ * non-significant bits be zero in the values.
+ * An undesirable consequence of this is, you can't use a specification like
+ * the following to mean "all of the hosts on the same network as x.admc.com":
+ * <PRE><CODE>
+ *     allow x.admc.com/24
+ * </CODE></PRE>
+ * </P>
+ *
+ * @see #ServerAcl(File)
+ * @see #permitAccess
+ **/
+public final class ServerAcl {
+
+    public static final class AclFormatException extends Exception {
+
+        public AclFormatException(String s) {
+            super(s);
+        }
+    }
+
+    protected final static byte[] ALL_SET_4BYTES  = new byte[] {
+        -1, -1, -1, -1
+    };
+    protected final static byte[] ALL_SET_16BYTES = new byte[] {
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+    };
+
+    // -1 is all-bits-on in 2's-complement for signed values.
+    // Must do it this way since Java has no support for unsigned integral
+    // constants.
+    private static final class AclEntry {
+
+        private byte[] value;
+        private byte[] mask;    // These are the bits in candidate which must match
+        private int    bitBlockSize;
+        public boolean allow;
+
+        public AclEntry(byte[] value, int bitBlockSize,
+                        boolean allow) throws AclFormatException {
+
+            byte[] allOn = null;
+
+            switch (value.length) {
+
+                case 4 :
+                    allOn = ALL_SET_4BYTES;
+                    break;
+
+                case 16 :
+                    allOn = ALL_SET_16BYTES;
+                    break;
+
+                default :
+                    throw new IllegalArgumentException(
+                        "Only 4 and 16 bytes supported, not " + value.length);
+            }
+
+            if (bitBlockSize > value.length * 8) {
+                throw new IllegalArgumentException(
+                    "Specified " + bitBlockSize
+                    + " significant bits, but value only has "
+                    + (value.length * 8) + " bits");
+            }
+
+            this.bitBlockSize = bitBlockSize;
+            this.value        = value;
+            mask = BitMap.leftShift(allOn, value.length * 8 - bitBlockSize);
+
+            if (mask.length != value.length) {
+                throw new RuntimeException(
+                    "Basic program assertion failed.  "
+                    + "Generated mask length " + mask.length
+                    + " (bytes) does not match given value length "
+                    + value.length + " (bytes).");
+            }
+
+            this.allow = allow;
+
+            validateMask();
+        }
+
+        public String toString() {
+
+            StringBuffer sb = new StringBuffer("Addrs ");
+
+            sb.append((value.length == 16)
+                      ? ("[" + ServerAcl.colonNotation(value) + ']')
+                      : ServerAcl.dottedNotation(value));
+            sb.append("/" + bitBlockSize + ' ' + (allow ? "ALLOW"
+                                                        : "DENY"));
+
+            return sb.toString();
+        }
+
+        public boolean matches(byte[] candidate) {
+
+            if (value.length != candidate.length) {
+                return false;
+            }
+
+            return !BitMap.hasAnyBitSet(BitMap.xor(value,
+                                                   BitMap.and(candidate,
+                                                       mask)));
+        }
+
+        public void validateMask() throws AclFormatException {
+
+            if (BitMap.hasAnyBitSet(BitMap.and(value, BitMap.not(mask)))) {
+                throw new AclFormatException(
+                    "The base address '" + ServerAcl.dottedNotation(value)
+                    + "' is too specific for block-size-spec /"
+                    + bitBlockSize);
+            }
+        }
+    }
+
+    /**
+     * @param uba  Unsigned byte array
+     */
+    static public String dottedNotation(byte[] uba) {
+
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < uba.length; i++) {
+            if (i > 0) {
+                sb.append('.');
+            }
+
+            sb.append((int) uba[i] & 0xff);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * @param uba  Unsigned byte array
+     */
+    static public String colonNotation(byte[] uba) {
+
+        // TODO:  handle odd byte lengths.
+        if ((uba.length / 2) * 2 != uba.length) {
+            throw new RuntimeException(
+                "At this time .colonNotation only handles even byte quantities");
+        }
+
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < uba.length; i += 2) {
+            if (i > 0) {
+                sb.append(':');
+            }
+
+            sb.append(Integer.toHexString((uba[i] & 0xff) * 256
+                                          + (uba[i + 1] & 0xff)));
+        }
+
+        return sb.toString();
+    }
+
+    private PrintWriter pw = null;
+
+    public void setPrintWriter(PrintWriter pw) {
+        this.pw = pw;
+    }
+
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < aclEntries.size(); i++) {
+            if (i > 0) {
+                sb.append('\n');
+            }
+
+            sb.append("Entry " + (i + 1) + ": " + aclEntries.get(i));
+        }
+
+        return sb.toString();
+    }
+
+    private List            aclEntries;
+    static private AclEntry PROHIBIT_ALL_IPV4;
+    static private AclEntry PROHIBIT_ALL_IPV6;
+
+    static {
+        try {
+            PROHIBIT_ALL_IPV4 =
+                new AclEntry(InetAddress.getByName("0.0.0.0").getAddress(), 0,
+                             false);
+            PROHIBIT_ALL_IPV6 =
+                new AclEntry(InetAddress.getByName("::").getAddress(), 0,
+                             false);
+        } catch (UnknownHostException uke) {
+
+            // Should never reach here, since no name service is needed to
+            // look up either address.
+            throw new RuntimeException(
+                "Unexpected problem in static initializer", uke);
+        } catch (AclFormatException afe) {
+            throw new RuntimeException(
+                "Unexpected problem in static initializer", afe);
+        }
+    }
+
+    /**
+     * Uses system network libraries to resolve the given String to an IP addr,
+     * then determine whether this address is permitted or denied.
+     *
+     * Specified name may be a numerical-based String like "1.2.3.4", a
+     * constant known to the networking libraries, or a host name to be
+     * resolved by the systems name resolution system.
+     *
+     * If the given String can't be resolved to an IP addr, false is returned.
+     *
+     * @see #permitAccess(byte[])
+     */
+    public boolean permitAccess(String s) {
+
+        try {
+            return permitAccess(InetAddress.getByName(s).getAddress());
+        } catch (UnknownHostException uke) {
+            println("'" + s + "' denied because failed to resolve to an addr");
+
+            return false;    // Resolution of candidate failed
+        }
+    }
+
+    /**
+     * @return true if access for the candidate address should be permitted,
+     *          false if access should be denied.
+     * @throws RuntimeException if no rule covers the candidate address.
+     *          This would be the case if this class is applied to some
+     *          network protocol other than ipv4 or ipv6, without adding a
+     *          default rule for it.
+     */
+    public boolean permitAccess(byte[] addr) {
+
+        ensureAclsUptodate();
+
+        for (int i = 0; i < aclEntries.size(); i++) {
+            if (((AclEntry) aclEntries.get(i)).matches(addr)) {
+                AclEntry hit = (AclEntry) aclEntries.get(i);
+
+                println("Addr '" + ServerAcl.dottedNotation(addr)
+                        + "' matched rule #" + (i + 1) + ":  " + hit);
+
+                return hit.allow;
+            }
+        }
+
+        throw new RuntimeException("No rule matches address '"
+                                   + ServerAcl.dottedNotation(addr) + "'");
+    }
+
+    private void println(String s) {
+
+        if (pw == null) {
+            return;
+        }
+
+        pw.println(s);
+        pw.flush();
+    }
+
+    private File aclFile;
+    private long lastLoadTime = 0;
+
+    private static final class InternalException extends Exception {}
+
+    public ServerAcl(File aclFile) throws IOException, AclFormatException {
+        this.aclFile = aclFile;
+        aclEntries   = load();
+    }
+
+    synchronized protected void ensureAclsUptodate() {
+
+        if (lastLoadTime > aclFile.lastModified()) {
+            return;
+        }
+
+        try {
+            aclEntries = load();
+
+            println("ACLs reloaded from file");
+
+            return;
+        } catch (Exception e) {
+            println("Failed to reload ACL file.  Retaining old ACLs.  " + e);
+        }
+    }
+
+    protected List load() throws IOException, AclFormatException {
+
+        if (!aclFile.exists()) {
+            throw new IOException("File '" + aclFile.getAbsolutePath()
+                                  + "' is not present");
+        }
+
+        if (!aclFile.isFile()) {
+            throw new IOException("'" + aclFile.getAbsolutePath()
+                                  + "' is not a regular file");
+        }
+
+        if (!aclFile.canRead()) {
+            throw new IOException("'" + aclFile.getAbsolutePath()
+                                  + "' is not accessible");
+        }
+
+        String          line;
+        String          ruleTypeString;
+        StringTokenizer toker;
+        String          addrString,
+                        bitString = null;
+        int             slashIndex;
+        int             linenum = 0;
+        byte[]          addr;
+        boolean         allow;
+        int             bits;
+        BufferedReader  br      = new BufferedReader(new FileReader(aclFile));
+        List            newAcls = new ArrayList();
+
+        try {
+            while ((line = br.readLine()) != null) {
+                linenum++;
+
+                line = line.trim();
+
+                if (line.length() < 1) {
+                    continue;
+                }
+
+                if (line.charAt(0) == '#') {
+                    continue;
+                }
+
+                toker = new StringTokenizer(line);
+
+                try {
+                    if (toker.countTokens() != 2) {
+                        throw new InternalException();
+                    }
+
+                    ruleTypeString = toker.nextToken();
+                    addrString     = toker.nextToken();
+                    slashIndex     = addrString.indexOf('/');
+
+                    if (slashIndex > -1) {
+                        bitString  = addrString.substring(slashIndex + 1);
+                        addrString = addrString.substring(0, slashIndex);
+                    }
+
+                    addr = InetAddress.getByName(addrString).getAddress();
+                    bits = (bitString == null) ? (addr.length * 8)
+                                               : Integer.parseInt(bitString);
+
+                    if (ruleTypeString.equalsIgnoreCase("allow")) {
+                        allow = true;
+                    } else if (ruleTypeString.equalsIgnoreCase("permit")) {
+                        allow = true;
+                    } else if (ruleTypeString.equalsIgnoreCase("accept")) {
+                        allow = true;
+                    } else if (ruleTypeString.equalsIgnoreCase("prohibit")) {
+                        allow = false;
+                    } else if (ruleTypeString.equalsIgnoreCase("deny")) {
+                        allow = false;
+                    } else if (ruleTypeString.equalsIgnoreCase("reject")) {
+                        allow = false;
+                    } else {
+                        throw new InternalException();
+                    }
+                } catch (NumberFormatException nfe) {
+                    throw new AclFormatException("Syntax error at ACL file '"
+                                                 + aclFile.getAbsolutePath()
+                                                 + "', line " + linenum);
+                } catch (InternalException ie) {
+                    throw new AclFormatException("Syntax error at ACL file '"
+                                                 + aclFile.getAbsolutePath()
+                                                 + "', line " + linenum);
+                }
+
+                try {
+                    newAcls.add(new AclEntry(addr, bits, allow));
+                } catch (AclFormatException afe) {
+                    throw new AclFormatException("Syntax error at ACL file '"
+                                                 + aclFile.getAbsolutePath()
+                                                 + "', line " + linenum + ": "
+                                                 + afe.getMessage());
+                }
+            }
+        } finally {
+            br.close();
+        }
+
+        newAcls.add(PROHIBIT_ALL_IPV4);
+        newAcls.add(PROHIBIT_ALL_IPV6);
+
+        lastLoadTime = new java.util.Date().getTime();
+
+        return newAcls;
+    }
+
+    /**
+     * Utility method that allows interactive testing of individal
+     * ACL records, as well as the net effect of the ACL record list.
+     *
+     * Run  "java -cp path/to/hsqldb.jar org.hsqldb.server.ServerAcl --help"
+     * for Syntax help.
+     */
+    public static void main(String[] sa)
+    throws AclFormatException, IOException {
+
+        if (sa.length > 1) {
+            throw new RuntimeException("Try: java -cp path/to/hsqldb.jar "
+                                       + ServerAcl.class.getName()
+                                       + " --help");
+        }
+
+        if (sa.length > 0 && sa[0].equals("--help")) {
+            System.err.println("SYNTAX: java -cp path/to/hsqldb.jar "
+                               + ServerAcl.class.getName()
+                               + " [filepath.txt]");
+            System.err.println("ACL file path defaults to 'acl.txt' in the "
+                               + "current directory.");
+            System.exit(0);
+        }
+
+        ServerAcl serverAcl = new ServerAcl(new File((sa.length == 0)
+            ? "acl.txt"
+            : sa[0]));
+
+        serverAcl.setPrintWriter(new PrintWriter(System.out));
+        System.out.println(serverAcl.toString());
+
+        BufferedReader br =
+            new BufferedReader(new InputStreamReader(System.in));
+
+        System.out.println("Enter hostnames or IP addresses to be tested "
+                           + "(one per line).");
+
+        String s;
+
+        while ((s = br.readLine()) != null) {
+            s = s.trim();
+
+            if (s.length() < 1) {
+                continue;
+            }
+
+            System.out.println(Boolean.toString(serverAcl.permitAccess(s)));
+        }
+    }
+}
diff --git a/src/org/hsqldb/server/ServerConfiguration.java b/src/org/hsqldb/server/ServerConfiguration.java
new file mode 100644
index 0000000..aea330b
--- /dev/null
+++ b/src/org/hsqldb/server/ServerConfiguration.java
@@ -0,0 +1,273 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.net.InetAddress;
+
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.persist.HsqlProperties;
+
+/**
+ * @todo:  move to here from Server and WebServer the remaining extraneous code
+ *          dealing primarily with reading/setting properties from files, etc.
+ */
+
+/**
+ * Assists with Server and WebServer configuration tasks.
+ *
+ * @author  boucherb@users
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public final class ServerConfiguration implements ServerConstants {
+
+    private ServerConfiguration() {}
+
+    /**
+     * Retrieves the default port that a Server will try to use in the
+     * abscence of an explicitly specified one, given the specified
+     * value for whether or not to use secure sockets.
+     *
+     * @param protocol the protcol specifier code of the Server
+     * @param isTls if true, retrieve the default port when using secure
+     *      sockets, else the default port when using plain sockets
+     * @return the default port used in the abscence of an explicit
+     *      specification.
+     *
+     */
+    public static int getDefaultPort(int protocol, boolean isTls) {
+
+        switch (protocol) {
+
+            case SC_PROTOCOL_HSQL : {
+                return isTls ? SC_DEFAULT_HSQLS_SERVER_PORT
+                             : SC_DEFAULT_HSQL_SERVER_PORT;
+            }
+            case SC_PROTOCOL_HTTP : {
+                return isTls ? SC_DEFAULT_HTTPS_SERVER_PORT
+                             : SC_DEFAULT_HTTP_SERVER_PORT;
+            }
+            case SC_PROTOCOL_BER : {
+                return isTls ? -1
+                             : SC_DEFAULT_BER_SERVER_PORT;
+            }
+            default : {
+                return -1;
+            }
+        }
+    }
+
+    /**
+     * Retrieves a new HsqlProperties object, if possible, loaded from the
+     * specified file.
+     *
+     * @param path the file's path, without the .properties extention
+     *      (which is added automatically)
+     * @return a new properties object loaded from the specified file
+     */
+    public static ServerProperties getPropertiesFromFile(int protocol,
+            String path) {
+
+        if (StringUtil.isEmpty(path)) {
+            return null;
+        }
+
+        ServerProperties p = new ServerProperties(protocol, path);
+
+        try {
+            p.load();
+        } catch (Exception e) {}
+
+        return p;
+    }
+
+    /**
+     * Retrieves an array of Strings naming the distinct, known to be valid local
+     * InetAddress names for this machine.  The process is to collect and
+     * return the union of the following sets:
+     *
+     * <ol>
+     * <li> InetAddress.getAllByName(InetAddress.getLocalHost().getHostAddress())
+     * <li> InetAddress.getAllByName(InetAddress.getLocalHost().getHostName())
+     * <li> InetAddress.getAllByName(InetAddress.getByName(null).getHostAddress())
+     * <li> InetAddress.getAllByName(InetAddress.getByName(null).getHostName())
+     * <li> InetAddress.getByName("loopback").getHostAddress()
+     * <li> InetAddress.getByName("loopback").getHostname()
+     * </ol>
+     *
+     * @return the distinct, known to be valid local
+     *        InetAddress names for this machine
+     */
+    public static String[] listLocalInetAddressNames() {
+
+        InetAddress   addr;
+        InetAddress[] addrs;
+        HashSet       set;
+
+        set = new HashSet();
+
+        try {
+            addr  = InetAddress.getLocalHost();
+            addrs = InetAddress.getAllByName(addr.getHostAddress());
+
+            for (int i = 0; i < addrs.length; i++) {
+                set.add(addrs[i].getHostAddress());
+                set.add(addrs[i].getHostName());
+            }
+
+            addrs = InetAddress.getAllByName(addr.getHostName());
+
+            for (int i = 0; i < addrs.length; i++) {
+                set.add(addrs[i].getHostAddress());
+                set.add(addrs[i].getHostName());
+            }
+        } catch (Exception e) {}
+
+        try {
+            addr  = InetAddress.getByName(null);
+            addrs = InetAddress.getAllByName(addr.getHostAddress());
+
+            for (int i = 0; i < addrs.length; i++) {
+                set.add(addrs[i].getHostAddress());
+                set.add(addrs[i].getHostName());
+            }
+
+            addrs = InetAddress.getAllByName(addr.getHostName());
+
+            for (int i = 0; i < addrs.length; i++) {
+                set.add(addrs[i].getHostAddress());
+                set.add(addrs[i].getHostName());
+            }
+        } catch (Exception e) {}
+
+        try {
+            set.add(InetAddress.getByName("loopback").getHostAddress());
+            set.add(InetAddress.getByName("loopback").getHostName());
+        } catch (Exception e) {}
+
+        return (String[]) set.toArray(new String[set.size()]);
+    }
+
+    /**
+     * Retrieves a new default properties object for a server of the
+     * specified protocol
+     *
+     * @return a new default properties object
+     */
+    public static ServerProperties newDefaultProperties(int protocol) {
+
+        ServerProperties p = new ServerProperties(protocol);
+
+        p.setProperty(SC_KEY_AUTORESTART_SERVER,
+                      SC_DEFAULT_SERVER_AUTORESTART);
+        p.setProperty(SC_KEY_ADDRESS, SC_DEFAULT_ADDRESS);
+        p.setProperty(SC_KEY_NO_SYSTEM_EXIT, SC_DEFAULT_NO_SYSTEM_EXIT);
+        p.setProperty(SC_KEY_MAX_DATABASES, SC_DEFAULT_MAX_DATABASES);
+        p.setProperty(SC_KEY_SILENT, SC_DEFAULT_SILENT);
+        p.setProperty(SC_KEY_TLS, SC_DEFAULT_TLS);
+        p.setProperty(SC_KEY_TRACE, SC_DEFAULT_TRACE);
+        p.setProperty(SC_KEY_WEB_DEFAULT_PAGE, SC_DEFAULT_WEB_PAGE);
+        p.setProperty(SC_KEY_WEB_ROOT, SC_DEFAULT_WEB_ROOT);
+
+        // Purposefully do not set a default Port because the default is
+        // derived from TLS, which is runtime-configurable.
+        // Things work very well if we leave it unset here and use the
+        // getDefaultPort() method above to get the correct value.
+        return p;
+    }
+
+    /**
+     * Translates null or zero length value for address key to the
+     * special value ServerConstants.SC_DEFAULT_ADDRESS which causes
+     * ServerSockets to be constructed without specifying an InetAddress.
+     *
+     * @param p The properties object upon which to perform the translation
+     */
+    public static void translateAddressProperty(HsqlProperties p) {
+
+        if (p == null) {
+            return;
+        }
+
+        String address = p.getProperty(SC_KEY_ADDRESS);
+
+        if (StringUtil.isEmpty(address)) {
+            p.setProperty(SC_KEY_ADDRESS, SC_DEFAULT_ADDRESS);
+        }
+    }
+
+    /**
+     * Translates the legacy default database form: database=...
+     * to the 1.7.2 form: database.0=...
+     *
+     * @param p The properties object upon which to perform the translation
+     */
+    public static void translateDefaultDatabaseProperty(HsqlProperties p) {
+
+        if (p == null) {
+            return;
+        }
+
+        if (!p.isPropertyTrue(SC_KEY_REMOTE_OPEN_DB)) {
+            if (p.getProperty(SC_KEY_DATABASE + "." + 0) == null) {
+                String defaultdb = p.getProperty(SC_KEY_DATABASE);
+
+                if (defaultdb == null) {
+                    defaultdb = SC_DEFAULT_DATABASE;
+                }
+
+                p.setProperty(SC_KEY_DATABASE + ".0", defaultdb);
+                p.setProperty(SC_KEY_DBNAME + ".0", "");
+            }
+
+            if (p.getProperty(SC_KEY_DBNAME + "." + 0) == null) {
+                p.setProperty(SC_KEY_DBNAME + ".0", "");
+            }
+        }
+    }
+
+    /**
+     * Tranlates unspecified no_system_exit property to false, the default
+     * typically required when a Server is started from the command line.
+     *
+     * @param p The properties object upon which to perform the translation
+     */
+    public static void translateDefaultNoSystemExitProperty(HsqlProperties p) {
+
+        if (p == null) {
+            return;
+        }
+
+        p.setPropertyIfNotExists(SC_KEY_NO_SYSTEM_EXIT, "false");
+    }
+}
diff --git a/src/org/hsqldb/server/ServerConnection.java b/src/org/hsqldb/server/ServerConnection.java
new file mode 100644
index 0000000..ee5a7b8
--- /dev/null
+++ b/src/org/hsqldb/server/ServerConnection.java
@@ -0,0 +1,1943 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketException;
+
+import org.hsqldb.ClientConnection;
+import org.hsqldb.ColumnBase;
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Session;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.resources.BundleHandler;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.result.ResultProperties;
+import org.hsqldb.rowio.RowInputBinary;
+import org.hsqldb.rowio.RowOutputBinary;
+import org.hsqldb.rowio.RowOutputInterface;
+import org.hsqldb.types.Type;
+import org.hsqldb.StatementTypes;
+
+// fredt@users 20020215 - patch 461556 by paul-h@users - server factory
+// fredt@users 20020424 - patch 1.7.0 by fredt - shutdown without exit
+// fredt@users 20021002 - patch 1.7.1 by fredt - changed notification method
+// fredt@users 20030618 - patch 1.7.2 by fredt - changed read/write methods
+// fredt@users 20091013 - move set session to null suggested by Otto Joyner
+
+/**
+ *  All ServerConnection objects are listed in a Set in server
+ *  and removed by this class when closed.<p>
+ *
+ *  When the database or server is shutdown, the signalClose() method is called
+ *  for all current ServerConnection instances. This will call the private
+ *  close() method unless the ServerConnection thread itself has caused the
+ *  shutdown. In this case, the keepAlive flag is set to false, allowing the
+ *  thread to terminate once it has returned the result of the operation to
+ *  the client.
+ *  (fredt@users)<p>
+ *
+ * Rewritten in  HSQLDB version 1.7.2, based on original Hypersonic code.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+class ServerConnection implements Runnable {
+
+    boolean                  keepAlive;
+    private String           user;
+    int                      dbID;
+    int                      dbIndex;
+    private volatile Session session;
+    private Socket           socket;
+    private Server           server;
+    private DataInputStream  dataInput;
+    private DataOutputStream dataOutput;
+    private static int       mCurrentThread = 0;
+    private int              mThread;
+    static final int         BUFFER_SIZE = 0x1000;
+    final byte[]             mainBuffer  = new byte[BUFFER_SIZE];
+    RowOutputInterface       rowOut;
+    RowInputBinary           rowIn;
+    Thread                   runnerThread;
+    protected static String  TEXTBANNER_PART1 = null;
+    protected static String  TEXTBANNER_PART2 = null;
+
+    static {
+        int serverBundleHandle =
+            BundleHandler.getBundleHandle("org_hsqldb_Server_messages", null);
+
+        if (serverBundleHandle < 0) {
+            throw new RuntimeException(
+                "MISSING Resource Bundle.  See source code");
+
+            // This will be caught before prod release.
+            // Not necessary to localize message.
+        }
+
+        TEXTBANNER_PART1 = BundleHandler.getString(serverBundleHandle,
+                "textbanner.part1");
+        TEXTBANNER_PART2 = BundleHandler.getString(serverBundleHandle,
+                "textbanner.part2");
+
+        if (TEXTBANNER_PART1 == null || TEXTBANNER_PART2 == null) {
+            throw new RuntimeException(
+                "MISSING Resource Bundle msg definition.  See source code");
+
+            // This will be caught before prod release.
+            // Not necessary to localize message.
+        }
+    }
+
+    /**
+     * Creates a new ServerConnection to the specified Server on the
+     * specified socket.
+     *
+     * @param socket the network socket on which Server communication
+     *      takes place
+     * @param server the Server instance to which the object
+     *      represents a connection
+     */
+    ServerConnection(Socket socket, Server server) {
+
+        RowOutputBinary rowOutTemp = new RowOutputBinary(mainBuffer);
+
+        rowIn  = new RowInputBinary(rowOutTemp);
+        rowOut = rowOutTemp;
+
+        //
+        Thread runnerThread;
+
+        this.socket = socket;
+        this.server = server;
+
+        synchronized (ServerConnection.class) {
+            mThread = mCurrentThread++;
+        }
+
+        synchronized (server.serverConnSet) {
+            server.serverConnSet.add(this);
+        }
+    }
+
+    /**
+     * Signals this object to close, including exiting the thread running
+     * the request handling loop
+     */
+    void signalClose() {
+
+        keepAlive = false;
+
+        if (!Thread.currentThread().equals(runnerThread)) {
+            close();
+        }
+    }
+
+    /**
+     * Closes this connection.
+     */
+    private void close() {
+
+        if (session != null) {
+            session.close();
+
+            session = null;
+        }
+
+        // fredt@user - closing the socket is to stop this thread
+        try {
+            synchronized (this) {
+                if (socket != null) {
+                    socket.close();
+                }
+            }
+        } catch (IOException e) {}
+
+        socket = null;
+
+        synchronized (server.serverConnSet) {
+            server.serverConnSet.remove(this);
+        }
+    }
+
+    /**
+     * Initializes this connection.
+     * <p>
+     * Will return (not throw) if fail to initialize the connection.
+     * </p>
+     */
+    private void init() {
+
+        runnerThread = Thread.currentThread();
+        keepAlive    = true;
+
+        try {
+            socket.setTcpNoDelay(true);
+
+            dataInput = new DataInputStream(
+                new BufferedInputStream(socket.getInputStream()));
+            dataOutput = new DataOutputStream(socket.getOutputStream());
+
+            int firstInt = handshake();
+
+            switch (streamProtocol) {
+
+                case HSQL_STREAM_PROTOCOL :
+                    if (firstInt
+                            != ClientConnection
+                                .NETWORK_COMPATIBILITY_VERSION_INT) {
+                        String verString =
+                            ClientConnection.toNetCompVersionString(firstInt);
+
+                        throw Error.error(
+                            null, ErrorCode.SERVER_VERSIONS_INCOMPATIBLE, 0,
+                            new String[] {
+                            verString,
+                            ClientConnection.NETWORK_COMPATIBILITY_VERSION
+                        });
+                    }
+
+                    Result resultIn = Result.newResult(dataInput, rowIn);
+
+                    resultIn.readAdditionalResults(session, dataInput, rowIn);
+
+                    Result resultOut;
+
+                    resultOut = setDatabase(resultIn);
+
+                    resultOut.write(dataOutput, rowOut);
+                    break;
+
+                case ODBC_STREAM_PROTOCOL :
+                    odbcConnect(firstInt);
+                    break;
+
+                default :
+
+                    // Protocol detection failures should already have been
+                    // handled.
+                    keepAlive = false;
+            }
+        } catch (Exception e) {
+
+            // Only "unexpected" failures are caught here.
+            // Expected failures will have been handled (by sending feedback
+            // to user-- with an output Result for normal protocols), then
+            // continuing.
+            StringBuffer sb = new StringBuffer(mThread
+                                               + ":Failed to connect client.");
+
+            if (user != null) {
+                sb.append("  User '" + user + "'.");
+            }
+
+            server.printWithThread(sb.toString() + "  Stack trace follows.");
+            server.printStackTrace(e);
+        }
+    }
+
+    private static class CleanExit extends Exception {}
+
+    private static class ClientFailure extends Exception {
+
+        private String clientMessage = null;
+
+        public ClientFailure(String ourMessage, String clientMessage) {
+
+            super(ourMessage);
+
+            this.clientMessage = clientMessage;
+        }
+
+        public String getClientMessage() {
+            return clientMessage;
+        }
+    }
+
+    private CleanExit cleanExit = new CleanExit();
+
+    private void receiveResult(int resultMode)
+    throws CleanExit, IOException, HsqlException {
+
+        Result resultIn = Result.newResult(session, resultMode, dataInput,
+                                           rowIn);
+
+        resultIn.readAdditionalResults(session, dataInput, rowIn);
+        server.printRequest(mThread, resultIn);
+
+        Result resultOut = null;
+
+        switch (resultMode) {
+
+            case ResultConstants.CONNECT : {
+                resultOut = setDatabase(resultIn);
+
+                break;
+            }
+            case ResultConstants.DISCONNECT : {
+                throw cleanExit;
+            }
+            case ResultConstants.RESETSESSION : {
+                session.resetSession();
+
+                return;
+            }
+            default :
+                resultOut = session.execute(resultIn);
+        }
+
+        resultOut.write(dataOutput, rowOut);
+        rowOut.setBuffer(mainBuffer);
+        rowIn.resetRow(mainBuffer.length);
+    }
+
+    private OdbcPacketOutputStream outPacket = null;
+
+    private void receiveOdbcPacket(char inC) throws IOException, CleanExit {
+
+        /*
+         * The driver's notion of the transaction state, I (no) or T (yes),
+         * corresponds precisely inversely to our server-side Session
+         * autoCommit setting.
+         * If the user/app runs in non-autocommit mode and says to run a
+         * COMMIT followed by an INSERT, the driver will handle the user/app's
+         * facade of autocommittedness, and will send the server <OL>
+         *   <LI>COMMIT (which will cause us to set session.setAutoCommit(true)
+         *   <LI>BEGIN (which will cause us to set session.setAutoCommit(false)
+         *   <LI>INSERT...
+         * </OL>
+         */
+        char    c;
+        boolean sendReadyForQuery = false;
+        String  psHandle, portalHandle, handle, dataString, tmpStr;
+
+        // Statement which must be executed after the primary statement, but
+        // before sending the ReadyForQuery Z packet.
+        String                interposedStatement = null;
+        Result                r, rOut;
+        int                   paramCount, lastSemi;
+        OdbcPreparedStatement odbcPs;
+        StatementPortal       portal;
+        ResultMetaData        pmd;
+        OdbcPacketInputStream inPacket = null;
+        Type[]                colTypes;
+        PgType[]              pgTypes;
+
+        try {
+            inPacket = OdbcPacketInputStream.newOdbcPacketInputStream(inC,
+                    dataInput);
+
+            server.printWithThread("Got op (" + inPacket.packetType + ')');
+            server.printWithThread("Got packet length of "
+                                   + inPacket.available()
+                                   + " + type byte + 4 size header");
+
+            if (inPacket.available() >= 1000000000) {
+                throw new IOException("Insane packet length: "
+                                      + inPacket.available()
+                                      + " + type byte + 4 size header");
+            }
+        } catch (SocketException se) {
+            server.printWithThread("Ungraceful client exit: " + se);
+
+            throw cleanExit;    // not "clean", but handled
+        } catch (IOException ioe) {
+            server.printWithThread("Fatal ODBC protocol failure: " + ioe);
+
+            try {
+                OdbcUtil.alertClient(OdbcUtil.ODBC_SEVERITY_FATAL,
+                                     ioe.getMessage(), "08P01", dataOutput);
+
+                // Code here means Protocol Violation
+            } catch (Exception e) {
+
+                // We just make an honest effort to notify the client
+            }
+
+            throw cleanExit;    // not "clean", but handled
+        }
+
+        /**
+         * ODBC Service State Machine  (the remainder of this method)
+         */
+        switch (odbcCommMode) {
+
+            case OdbcUtil.ODBC_EXT_RECOVER_MODE :
+                if (inPacket.packetType != 'S') {
+                    if (server.isTrace()) {
+                        server.printWithThread("Ignoring a '"
+                                               + inPacket.packetType + "'");
+                    }
+
+                    return;
+                }
+
+                odbcCommMode = OdbcUtil.ODBC_EXTENDED_MODE;
+
+                server.printWithThread(
+                    "EXTENDED comm session being recovered");
+
+                // Now the main switch will handle the Sync packet carefully
+                // the same as if there were no recovery.
+                break;
+
+            case OdbcUtil.ODBC_SIMPLE_MODE :
+                switch (inPacket.packetType) {
+
+                    case 'P' :
+
+                    // This is the only way to make this switch, according
+                    // to docs, but that does not allow for intermixing of
+                    // static and prepared statement (selects or other).
+                    // Therefore we allow all of the following, which works
+                    // great.
+                    case 'H' :
+                    case 'S' :
+                    case 'D' :
+                    case 'B' :
+                    case 'E' :
+                    case 'C' :
+                        odbcCommMode = OdbcUtil.ODBC_EXTENDED_MODE;
+
+                        server.printWithThread(
+                            "Switching mode from SIMPLE to EXTENDED");
+
+                    // Do not detect unexpected ops here.
+                    // In that case, leave the mode as it is, and the main
+                    // switch below will handle appropriately.
+                }
+                break;
+
+            case OdbcUtil.ODBC_EXTENDED_MODE :
+                switch (inPacket.packetType) {
+
+                    case 'Q' :
+                        odbcCommMode = OdbcUtil.ODBC_SIMPLE_MODE;
+
+                        server.printWithThread(
+                            "Switching mode from EXTENDED to SIMPLE");
+
+                    // Do not detect unexpected ops here.
+                    // In that case, leave the mode as it is, and the main
+                    // switch below will handle appropriately.
+                }
+                break;
+
+            default :
+                throw new RuntimeException("Unexpected ODBC comm mode value: "
+                                           + odbcCommMode);
+        }
+
+        outPacket.reset();
+
+        try {
+
+            // Every switch case must either throw or break.
+            // For cases which break
+            //   The packet will always be checked to make sure all bytes have
+            //   been consumed.
+            //   Set boolean sendReadyForQuery to send a Z/ReadyForQuery packet
+            //   to client.
+            // DO NOT return early.  If you need to abort, that is exceptional
+            // behavior and you should throw an Exception.
+            MAIN_ODBC_COMM_SWITCH:
+            switch (inPacket.packetType) {
+
+                case 'Q' :                                    // Query packet
+                    String sql = inPacket.readString();
+
+                    // We don't ask for the null terminator
+                    /* **********************************************
+                     * These first few cases handle the driver's implicit handling
+                     * of transactions. */
+                    if (sql.startsWith("BEGIN;") || sql.equals("BEGIN")) {
+                        /*
+                         * We may get here because of Driver client trying to
+                         * manage transactions implicitly; or because user/app.
+                         * has really issued a "BEGIN" command.
+                         * In the first case, we don't need to run the
+                         * corresponding START TRANSACTION command, since the
+                         * HyperSQL engine does this automatically, and can tell
+                         * when it is needed far better than the client; however
+                         * we do use this fact to update our Session autocommit
+                         * state to match the client's notion.
+                         * We ignore the latter case, because real HyperSQL
+                         * user/apps will use "START TRANSACTION", not "BEGIN".
+                         * Therefore, we just update autocommit state and run no
+                         * other command against the engine.
+                         */
+                        sql = sql.equals("BEGIN") ? null
+                                                  : sql.substring(
+                                                      "BEGIN;".length());
+
+                        server.printWithThread(
+                            "ODBC Trans started.  Session AutoCommit -> F");
+
+                        try {
+                            session.setAutoCommit(false);
+                        } catch (HsqlException he) {
+                            throw new RecoverableOdbcFailure(
+                                "Failed to change transaction state: "
+                                + he.getMessage(), he.getSQLState());
+                        }
+
+                        // Now just placate the driver
+                        outPacket.write("BEGIN");
+                        outPacket.xmit('C', dataOutput);
+
+                        if (sql == null) {
+                            sendReadyForQuery = true;
+
+                            break;
+                        }
+                    }
+
+                    if (sql.startsWith("SAVEPOINT ") && sql.indexOf(';') > 0) {
+                        int firstSemi = sql.indexOf(';');
+
+                        server.printWithThread(
+                            "Interposing BEFORE primary statement: "
+                            + sql.substring(0, firstSemi));
+                        odbcExecDirect(sql.substring(0, firstSemi));
+
+                        sql = sql.substring(firstSemi + 1);
+                    }
+
+                    lastSemi = sql.lastIndexOf(';');
+
+                    if (lastSemi > 0) {
+                        String suffix = sql.substring(lastSemi + 1);
+
+                        if (suffix.startsWith("RELEASE ")) {
+                            interposedStatement = suffix;
+                            sql                 = sql.substring(0, lastSemi);
+                        }
+                    }
+
+                    /** ******************************************* */
+                    String normalized = sql.trim().toLowerCase();
+
+                    if (server.isTrace()) {
+                        server.printWithThread("Received query (" + sql + ')');
+                    }
+
+                    /*
+                     * BEWARE:  We aren't supporting multiple result-sets from a
+                     * compound statement.  Plus, a general requirement is, the
+                     * entire compound statement may return just one result set.
+                     * I don't have time to check how it works elsewhere, but here,
+                     * and for now, the Rowset-generating statement (SELECT, etc.)
+                     * must be first in order for us to detect that we need to
+                     * return a result set.
+                     * If we do parse out the component statement here, the states
+                     * set above apply to all executions, and only one Z packet
+                     * should be sent at the very end.
+                     *
+                     * I find that the Driver can't handle compound statements
+                     * which mix resultset + non-resultset statements (even in
+                     * SIMPLE mode), so we are more capable than our client is.
+                     */
+                    if (normalized.startsWith("select current_schema()")) {
+                        server.printWithThread(
+                            "Implement 'select current_schema() emulation!");
+
+                        throw new RecoverableOdbcFailure(
+                            "current_schema() not supported yet", "0A000");
+                    }
+
+                    if (normalized.startsWith("select n.nspname,")) {
+
+                        // Executed by psqlodbc after every user-specified query.
+                        server.printWithThread(
+                            "Swallowing 'select n.nspname,...'");
+                        outPacket.writeShort(1);              // Num cols.
+                        outPacket.write("oid");
+                        outPacket.writeInt(201);
+                        outPacket.writeShort(1);
+                        outPacket.writeInt(23);
+                        outPacket.writeShort(4);
+                        outPacket.writeInt(-1);
+                        outPacket.writeShort(0);
+                        outPacket.xmit('T', dataOutput);      // Xmit Row Definition
+
+                        // This query returns no rows.  typenam "lo"??
+                        outPacket.write("SELECT");
+                        outPacket.xmit('C', dataOutput);
+
+                        sendReadyForQuery = true;
+
+                        break;
+                    }
+
+                    if (normalized.startsWith(
+                            "select oid, typbasetype from")) {
+
+                        // Executed by psqlodbc immediately after connecting.
+                        server.printWithThread(
+                            "Simulating 'select oid, typbasetype...'");
+                        /*
+                         * This query is run as "a hack to get the oid of our
+                         * large object oid type.
+                         */
+                        outPacket.writeShort(2);              // Num cols.
+                        outPacket.write("oid");               // Col. name
+                        outPacket.writeInt(101);              // table ID
+                        outPacket.writeShort(102);            // column id
+                        outPacket.writeInt(26);               // Datatype ID  [adtid]
+                        outPacket.writeShort(4);              // Datatype size  [adtsize]
+                        outPacket.writeInt(-1);               // Var size [atttypmod]
+                        outPacket.writeShort(0);              // text "format code"
+                        outPacket.write("typbasetype");       // Col. name
+                        outPacket.writeInt(101);              // table ID
+                        outPacket.writeShort(103);            // column id
+                        outPacket.writeInt(26);               // Datatype ID  [adtid]
+                        outPacket.writeShort(4);              // Datatype size  [adtsize]
+                        outPacket.writeInt(-1);               // Var size [atttypmod]
+                        outPacket.writeShort(0);              // text "format code"
+                        outPacket.xmit('T', dataOutput);      // sending a Tuple (row)
+
+                        // This query returns no rows.  typenam "lo"??
+                        outPacket.write("SELECT");
+                        outPacket.xmit('C', dataOutput);
+
+                        sendReadyForQuery = true;
+
+                        break;
+                    }
+
+                    if (normalized.startsWith("select ")) {
+                        server.printWithThread(
+                            "Performing a real non-prepared SELECT...");
+
+                        r = Result.newExecuteDirectRequest();
+
+                        r.setPrepareOrExecuteProperties(
+                            sql, 0, 0, StatementTypes.RETURN_RESULT, 0,
+                            ResultProperties.defaultPropsValue,
+                            java.sql.Statement.NO_GENERATED_KEYS, null, null);
+
+                        rOut = session.execute(r);
+
+                        switch (rOut.getType()) {
+
+                            case ResultConstants.DATA :
+                                break;
+
+                            case ResultConstants.ERROR :
+                                throw new RecoverableOdbcFailure(rOut);
+                            default :
+                                throw new RecoverableOdbcFailure(
+                                    "Output Result from Query execution is of "
+                                    + "unexpected type: " + rOut.getType());
+                        }
+
+                        // See Result.newDataHeadResult() for what we have here
+                        // .metaData, .navigator
+                        RowSetNavigator navigator = rOut.getNavigator();
+                        ResultMetaData  md        = rOut.metaData;
+
+                        if (md == null) {
+                            throw new RecoverableOdbcFailure(
+                                "Failed to get metadata for query results");
+                        }
+
+                        int      columnCount = md.getColumnCount();
+                        String[] colLabels   = md.getGeneratedColumnNames();
+
+                        colTypes = md.columnTypes;
+                        pgTypes  = new PgType[columnCount];
+
+                        for (int i = 0; i < pgTypes.length; i++) {
+                            pgTypes[i] = PgType.getPgType(colTypes[i],
+                                                          md.isTableColumn(i));
+                        }
+
+                        // fredt : colLabels may not contain some column names
+                        // colDefs is used when no label is present:
+                        // SELECT TABLECOL AS COLLABLE has both name and label
+                        // SELECT TABLECOL has name 'TABLECOL'
+                        // SELECT 2 AS CONST has label 'CONST'
+                        ColumnBase[] colDefs = md.columns;
+
+                        // Num cols.
+                        outPacket.writeShort(columnCount);
+
+                        for (int i = 0; i < columnCount; i++) {
+
+                            // col name
+                            if (colLabels[i] != null) {
+                                outPacket.write(colLabels[i]);
+                            } else {
+                                outPacket.write(colDefs[i].getNameString());
+                            }
+
+                            // table ID  [relid]:
+                            outPacket.writeInt(OdbcUtil.getTableOidForColumn(i,
+                                    md));
+
+                            // column id  [attid]
+                            outPacket.writeShort(OdbcUtil.getIdForColumn(i,
+                                    md));
+                            outPacket.writeInt(pgTypes[i].getOid());
+
+                            // Datatype size  [adtsize]
+                            outPacket.writeShort(pgTypes[i].getTypeWidth());
+                            outPacket.writeInt(pgTypes[i].getLPConstraint());
+
+                            // Var size [atttypmod]
+                            // This is the size constraint integer
+                            // like VARCHAR(12) or DECIMAL(4).
+                            // -1 if none specified for this column.
+                            outPacket.writeShort(0);
+
+                            // format code, 0 = text column, 1 = binary column,
+                            // but entirely ignored by our driver.
+                            // Would only be non-0 if a 'B' command requested it.
+                        }
+
+                        outPacket.xmit('T', dataOutput);      // Xmit Row Definition
+
+                        int rowNum = 0;
+
+                        while (navigator.next()) {
+                            rowNum++;
+
+                            Object[] rowData = navigator.getCurrent();
+
+                            // Row.getData().  Don't know why *Data.getCurrent()
+                            //                 method returns Object instead of O[].
+                            //  TODO:  Remove the assertion here:
+                            if (rowData == null) {
+                                throw new RecoverableOdbcFailure("Null row?");
+                            }
+
+                            if (rowData.length < columnCount) {
+                                throw new RecoverableOdbcFailure(
+                                    "Data element mismatch. " + columnCount
+                                    + " metadata cols, yet " + rowData.length
+                                    + " data elements for row " + rowNum);
+                            }
+
+                            //server.printWithThread("Row " + rowNum + " has "
+                            //+ rowData.length + " elements");
+                            outPacket.writeShort(columnCount);
+
+                            // This field is just swallowed by PG ODBC
+                            // client, but OdbcUtil.validated by psql.
+                            for (int i = 0; i < columnCount; i++) {
+                                if (rowData[i] == null) {
+                                    /*
+                                    server.printWithThread("R" + rowNum + "C"
+                                        + (i+1) + " => [null]");
+                                    */
+                                    outPacket.writeInt(-1);
+                                } else {
+                                    dataString =
+                                        pgTypes[i].valueString(rowData[i]);
+
+                                    outPacket.writeSized(dataString);
+
+                                    if (server.isTrace()) {
+                                        server.printWithThread(
+                                            "R" + rowNum + "C" + (i + 1)
+                                            + " => ("
+                                            + rowData[i].getClass().getName()
+                                            + ") [" + dataString + ']');
+                                    }
+                                }
+                            }
+
+                            outPacket.xmit('D', dataOutput);
+                        }
+
+                        outPacket.write("SELECT");
+                        outPacket.xmit('C', dataOutput);
+
+                        sendReadyForQuery = true;
+
+                        break;
+                    }
+
+                    if (normalized.startsWith("deallocate \"")
+                            && normalized.charAt(normalized.length() - 1)
+                               == '"') {
+                        tmpStr = sql.trim().substring(
+                            "deallocate \"".length()).trim();
+
+                        // Must use "sql" directly since name is case-sensitive
+                        handle = tmpStr.substring(0, tmpStr.length() - 1);
+                        odbcPs = (OdbcPreparedStatement) sessionOdbcPsMap.get(
+                            handle);
+
+                        if (odbcPs != null) {
+                            odbcPs.close();
+                        }
+
+                        portal =
+                            (StatementPortal) sessionOdbcPortalMap.get(handle);
+
+                        if (portal != null) {
+                            portal.close();
+                        }
+
+                        if (odbcPs == null && portal == null) {
+                            /*
+                            throw new RecoverableOdbcFailure(null,
+                                "No object present for handle: " + handle, "08P01");
+                            Driver does not handle state change correctly, so
+                            for now we just issue a warning:
+                            OdbcUtil.alertClient(OdbcUtil.ODBC_SEVERITY_ERROR,
+                                "No object present for handle: " + handle,
+                                dataOutput);
+                            TODO:  Retest this.  May have been side-effect of
+                                   other problems.
+                            */
+                            server.printWithThread(
+                                "Ignoring bad 'DEALLOCATE' cmd");
+                        }
+
+                        if (server.isTrace()) {
+                            server.printWithThread("Deallocated PS/Portal '"
+                                                   + handle + "'");
+                        }
+
+                        outPacket.write("DEALLOCATE");
+                        outPacket.xmit('C', dataOutput);
+
+                        sendReadyForQuery = true;
+
+                        break;
+                    }
+
+                    if (normalized.startsWith("set client_encoding to ")) {
+                        server.printWithThread("Stubbing EXECDIR for: " + sql);
+                        outPacket.write("SET");
+                        outPacket.xmit('C', dataOutput);
+
+                        sendReadyForQuery = true;
+
+                        break;
+                    }
+
+                    // Case below is non-String-matched Qs:
+                    server.printWithThread("Performing a real EXECDIRECT...");
+                    odbcExecDirect(sql);
+
+                    sendReadyForQuery = true;
+                    break;
+
+                case 'X' :                                    // Terminate packet
+                    if (sessionOdbcPsMap.size()
+                            > (sessionOdbcPsMap.containsKey("") ? 1
+                                                                : 0)) {
+                        server.printWithThread("Client left "
+                                               + sessionOdbcPsMap.size()
+                                               + " PS objects open");
+                    }
+
+                    if (sessionOdbcPortalMap.size()
+                            > (sessionOdbcPortalMap.containsKey("") ? 1
+                                                                    : 0)) {
+                        server.printWithThread("Client left "
+                                               + sessionOdbcPortalMap.size()
+                                               + " Portal objects open");
+                    }
+
+                    OdbcUtil.validateInputPacketSize(inPacket);
+
+                    throw cleanExit;
+                case 'H' :                                    // Flush packet
+
+                    // No-op.  It is impossible to cache while supporting multiple
+                    // ps and portal objects, so there is nothing for a Flush to
+                    // do.  There isn't even a reply to a Flush packet.
+                    break;
+
+                case 'S' :                                    // Sync packet
+
+                    // Special case for Sync packets.
+                    // To facilitate recovery, we do not abort in case of problems.
+                    if (session.isAutoCommit()) {
+                        try {
+
+                            // I don't see how this can be useful.  If we ran DML, it
+                            // will have autocommitted.  If we have just switched to
+                            // autoCommit mode, then according to spec we must have
+                            // executed an implicit commit then.
+                            server.printWithThread(
+                                "Silly implicit commit by Sync");
+                            session.commit(true);
+
+                            // TODO:  Find out if chain param should be T or F.
+                        } catch (HsqlException he) {
+                            server.printWithThread("Implicit commit failed: "
+                                                   + he);
+                            OdbcUtil.alertClient(OdbcUtil.ODBC_SEVERITY_ERROR,
+                                                 "Implicit commit failed",
+                                                 he.getSQLState(), dataOutput);
+                        }
+                    }
+
+                    sendReadyForQuery = true;
+                    break;
+
+                case 'P' :                                    // Parse packet
+                    psHandle = inPacket.readString();
+
+                    String query = OdbcUtil.revertMungledPreparedQuery(
+                        inPacket.readString());
+
+                    paramCount = inPacket.readUnsignedShort();
+
+                    for (int i = 0; i < paramCount; i++) {
+                        if (inPacket.readInt() != 0) {
+                            throw new RecoverableOdbcFailure(
+                                null,
+                                "Parameter-type OID specifiers not supported yet",
+                                "0A000");
+                        }
+                    }
+
+                    if (server.isTrace()) {
+                        server.printWithThread(
+                            "Received Prepare request for query (" + query
+                            + ") with handle '" + psHandle + "'");
+                    }
+
+                    if (psHandle.length() > 0
+                            && sessionOdbcPsMap.containsKey(psHandle)) {
+                        throw new RecoverableOdbcFailure(
+                            null,
+                            "PS handle '" + psHandle + "' already in use.  "
+                            + "You must close it before recreating", "08P01");
+                    }
+
+                    new OdbcPreparedStatement(psHandle, query,
+                                              sessionOdbcPsMap, session);
+                    outPacket.xmit('1', dataOutput);
+                    break;
+
+                case 'D' :                                    // Describe packet
+                    c      = inPacket.readByteChar();
+                    handle = inPacket.readString();
+                    odbcPs = null;
+                    portal = null;
+
+                    if (c == 'S') {
+                        odbcPs = (OdbcPreparedStatement) sessionOdbcPsMap.get(
+                            handle);
+                    } else if (c == 'P') {
+                        portal =
+                            (StatementPortal) sessionOdbcPortalMap.get(handle);
+                    } else {
+                        throw new RecoverableOdbcFailure(
+                            null,
+                            "Description packet request type invalid: " + c,
+                            "08P01");
+                    }
+
+                    if (server.isTrace()) {
+                        server.printWithThread("Received Describe request for "
+                                               + c + " of  handle '" + handle
+                                               + "'");
+                    }
+
+                    if (odbcPs == null && portal == null) {
+                        throw new RecoverableOdbcFailure(
+                            null,
+                            "No object present for " + c + " handle: "
+                            + handle, "08P01");
+                    }
+
+                    Result ackResult = (odbcPs == null) ? portal.ackResult
+                                                        : odbcPs.ackResult;
+
+                    pmd        = ackResult.parameterMetaData;
+                    paramCount = pmd.getColumnCount();
+
+                    Type[] paramTypes = pmd.getParameterTypes();
+
+                    if (paramCount != paramTypes.length) {
+                        throw new RecoverableOdbcFailure(
+                            "Parameter count mismatch.  Count of "
+                            + paramCount + " reported, but there are "
+                            + paramTypes.length + " param md objects");
+                    }
+
+                    if (c == 'S') {
+                        outPacket.writeShort(paramCount);
+
+                        for (int i = 0; i < paramTypes.length; i++) {
+                            outPacket.writeInt(
+                                PgType.getPgType(
+                                    paramTypes[i], true).getOid());
+
+                            // TODO:  Determine whether parameter typing works
+                            // better for Strings when try to match table column
+                            // or not.  2nd param to getPgType().
+                        }
+
+                        outPacket.xmit('t', dataOutput);
+
+                        // ParameterDescription packet
+                    }
+
+                    ResultMetaData md = ackResult.metaData;
+
+                    if (md.getColumnCount() < 1) {
+                        if (server.isTrace()) {
+                            server.printWithThread(
+                                "Non-rowset query so returning NoData packet");
+                        }
+
+                        // Send NoData packet because no columnar output from
+                        // this statement.
+                        outPacket.xmit('n', dataOutput);
+
+                        break;
+                    }
+
+                    // TODO:
+                    // May need to pass the extra BIGINT pseudo-column for
+                    // updatable-row or other purposes.  In that case, it may
+                    // make sense to use getExtendedColumnCount(), etc.
+                    String[] colNames = md.getGeneratedColumnNames();
+
+                    if (md.getColumnCount() != colNames.length) {
+                        throw new RecoverableOdbcFailure(
+                            "Couldn't get all column names: "
+                            + md.getColumnCount() + " cols. but only got "
+                            + colNames.length + " col. names");
+                    }
+
+                    colTypes = md.columnTypes;
+                    pgTypes  = new PgType[colNames.length];
+
+                    ColumnBase[] colDefs = md.columns;
+
+                    for (int i = 0; i < pgTypes.length; i++) {
+                        pgTypes[i] = PgType.getPgType(colTypes[i],
+                                                      md.isTableColumn(i));
+                    }
+
+                    if (colNames.length != colDefs.length) {
+                        throw new RecoverableOdbcFailure(
+                            "Col data mismatch.  " + colDefs.length
+                            + " col instances but " + colNames.length
+                            + " col names");
+                    }
+
+                    outPacket.writeShort(colNames.length);    // Num cols.
+
+                    for (int i = 0; i < colNames.length; i++) {
+                        outPacket.write(colNames[i]);         // Col. name
+
+                        // table ID  [relid]:
+                        outPacket.writeInt(OdbcUtil.getTableOidForColumn(i,
+                                md));
+
+                        // column id  [attid]
+                        outPacket.writeShort(OdbcUtil.getIdForColumn(i, md));
+                        outPacket.writeInt(pgTypes[i].getOid());
+
+                        // Datatype size  [adtsize]
+                        outPacket.writeShort(pgTypes[i].getTypeWidth());
+                        outPacket.writeInt(pgTypes[i].getLPConstraint());
+
+                        // Var size [atttypmod]
+                        // This is the size constraint integer
+                        // like VARCHAR(12) or DECIMAL(4).
+                        // -1 if none specified for this column.
+                        outPacket.writeShort(0);
+
+                        // format code, 0 = text column, 1 = binary column,
+                        // but entirely ignored by our driver.
+                        // Would only be non-0 if a 'B' command requested it.
+                    }
+
+                    outPacket.xmit('T', dataOutput);          // Xmit Row Definition
+                    break;
+
+                case 'B' :                                    // Bind packet
+                    portalHandle = inPacket.readString();
+                    psHandle     = inPacket.readString();
+
+                    int       paramFormatCount = inPacket.readUnsignedShort();
+                    boolean[] paramBinary      = new boolean[paramFormatCount];
+
+                    for (int i = 0; i < paramFormatCount; i++) {
+                        paramBinary[i] = inPacket.readUnsignedShort() != 0;
+
+                        if (server.isTrace() && paramBinary[i]) {
+                            server.printWithThread("Binary param #" + i);
+                        }
+                    }
+
+                    paramCount = inPacket.readUnsignedShort();
+
+                    Object[] paramVals = new Object[paramCount];
+
+                    for (int i = 0; i < paramVals.length; i++) {
+                        if (i < paramBinary.length && paramBinary[i]) {
+                            paramVals[i] = inPacket.readSizedBinaryData();
+                        } else {
+                            paramVals[i] = inPacket.readSizedString();
+                        }
+                    }
+
+                    int outFormatCount = inPacket.readUnsignedShort();
+
+                    for (int i = 0; i < outFormatCount; i++) {
+                        if (inPacket.readUnsignedShort() != 0) {
+                            throw new RecoverableOdbcFailure(
+                                null, "Binary output values not supported",
+                                "0A000");
+                        }
+                    }
+
+                    if (server.isTrace()) {
+                        server.printWithThread(
+                            "Received Bind request to make Portal from ("
+                            + psHandle + ")' with handle '" + portalHandle
+                            + "'");
+                    }
+
+                    odbcPs =
+                        (OdbcPreparedStatement) sessionOdbcPsMap.get(psHandle);
+
+                    if (odbcPs == null) {
+                        throw new RecoverableOdbcFailure(
+                            null,
+                            "No object present for PS handle: " + psHandle,
+                            "08P01");
+                    }
+
+                    if (portalHandle.length() > 0
+                            && sessionOdbcPortalMap.containsKey(
+                                portalHandle)) {
+                        throw new RecoverableOdbcFailure(
+                            null,
+                            "Portal handle '" + portalHandle
+                            + "' already in use.  "
+                            + "You must close it before recreating", "08P01");
+                    }
+
+                    pmd = odbcPs.ackResult.parameterMetaData;
+
+                    if (paramCount != pmd.getColumnCount()) {
+                        throw new RecoverableOdbcFailure(
+                            null,
+                            "Client didn't specify all "
+                            + pmd.getColumnCount() + " parameters ("
+                            + paramCount + ')', "08P01");
+                    }
+
+                    new StatementPortal(portalHandle, odbcPs, paramVals,
+                                        sessionOdbcPortalMap);
+                    outPacket.xmit('2', dataOutput);
+                    break;
+
+                case 'E' :                                    // Execute packet
+                    portalHandle = inPacket.readString();
+
+                    int fetchRows = inPacket.readInt();
+
+                    if (server.isTrace()) {
+                        server.printWithThread("Received Exec request for "
+                                               + fetchRows
+                                               + " rows from portal handle '"
+                                               + portalHandle + "'");
+                    }
+
+                    portal = (StatementPortal) sessionOdbcPortalMap.get(
+                        portalHandle);
+
+                    if (portal == null) {
+                        throw new RecoverableOdbcFailure(
+                            null,
+                            "No object present for Portal handle: "
+                            + portalHandle, "08P01");
+                    }
+
+                    // result properties means readonly, not holdable
+                    portal.bindResult.setPreparedExecuteProperties(
+                        portal.parameters, fetchRows, 0, 0);
+
+                    // 0 for maxRows means unlimited.  Same for fetchRows.
+                    rOut = session.execute(portal.bindResult);
+
+                    switch (rOut.getType()) {
+
+                        case ResultConstants.UPDATECOUNT :
+                            outPacket.write(
+                                OdbcUtil.echoBackReplyString(
+                                    portal.lcQuery, rOut.getUpdateCount()));
+                            outPacket.xmit('C', dataOutput);
+
+                            // end of rows (B or D packets)
+                            // This keeps session.autoUpdate in sync with client's
+                            // notion of transaction state.
+                            if (portal.lcQuery.equals("commit")
+                                    || portal.lcQuery.startsWith("commit ")
+                                    || portal.lcQuery.equals("rollback")
+                                    || portal.lcQuery.startsWith(
+                                        "rollback ")) {
+                                try {
+                                    session.setAutoCommit(true);
+                                } catch (HsqlException he) {
+                                    throw new RecoverableOdbcFailure(
+                                        "Failed to change transaction state: "
+                                        + he.getMessage(), he.getSQLState());
+                                }
+                            }
+                            break MAIN_ODBC_COMM_SWITCH;
+
+                        case ResultConstants.DATA :
+                            break;
+
+                        case ResultConstants.ERROR :
+                            throw new RecoverableOdbcFailure(rOut);
+                        default :
+                            throw new RecoverableOdbcFailure(
+                                "Output Result from Portal execution is of "
+                                + "unexpected type: " + rOut.getType());
+                    }
+
+                    // See Result.newDataHeadResult() for what we have here
+                    // .metaData, .navigator
+                    RowSetNavigator navigator = rOut.getNavigator();
+                    int             rowNum    = 0;
+                    int colCount = portal.ackResult.metaData.getColumnCount();
+
+                    while (navigator.next()) {
+                        rowNum++;
+
+                        Object[] rowData = navigator.getCurrent();
+
+                        if (rowData == null) {
+                            throw new RecoverableOdbcFailure("Null row?");
+                        }
+
+                        if (rowData.length < colCount) {
+                            throw new RecoverableOdbcFailure(
+                                "Data element mismatch. " + colCount
+                                + " metadata cols, yet " + rowData.length
+                                + " data elements for row " + rowNum);
+                        }
+
+                        //server.printWithThread("Row " + rowNum + " has "
+                        //+ rowData.length + " elements");
+                        outPacket.writeShort(colCount);
+
+                        // This field is just swallowed by PG ODBC
+                        // client, but validated by psql.
+                        colTypes = portal.ackResult.metaData.columnTypes;
+                        pgTypes  = new PgType[colCount];
+
+                        for (int i = 0; i < pgTypes.length; i++) {
+                            pgTypes[i] = PgType.getPgType(
+                                colTypes[i],
+                                portal.ackResult.metaData.isTableColumn(i));
+                        }
+
+                        for (int i = 0; i < colCount; i++) {
+                            if (rowData[i] == null) {
+                                /*
+                                server.printWithThread("R" + rowNum + "C"
+                                    + (i+1) + " => [null]");
+                                */
+                                outPacket.writeInt(-1);
+                            } else {
+                                dataString =
+                                    pgTypes[i].valueString(rowData[i]);
+
+                                outPacket.writeSized(dataString);
+
+                                if (server.isTrace()) {
+                                    server.printWithThread(
+                                        "R" + rowNum + "C" + (i + 1) + " => ("
+                                        + rowData[i].getClass().getName()
+                                        + ") [" + dataString + ']');
+                                }
+                            }
+                        }
+
+                        outPacket.xmit('D', dataOutput);
+                    }
+
+                    if (navigator.afterLast()) {
+                        outPacket.write("SELECT");
+                        outPacket.xmit('C', dataOutput);
+
+                        // end of rows (B or D packets)
+                    } else {
+                        outPacket.xmit('s', dataOutput);
+                    }
+
+                    // N.b., we return.
+                    // You might think that this completion of an EXTENDED sequence
+                    // would end in ReadyForQuery/Z, but no.
+                    break;
+
+                case 'C' :                                    // Close packet
+                    c      = inPacket.readByteChar();
+                    handle = inPacket.readString();
+                    odbcPs = null;
+                    portal = null;
+
+                    if (c == 'S') {
+                        odbcPs = (OdbcPreparedStatement) sessionOdbcPsMap.get(
+                            handle);
+
+                        if (odbcPs != null) {
+                            odbcPs.close();
+                        }
+                    } else if (c == 'P') {
+                        portal =
+                            (StatementPortal) sessionOdbcPortalMap.get(handle);
+
+                        if (portal != null) {
+                            portal.close();
+                        }
+                    } else {
+                        throw new RecoverableOdbcFailure(
+                            null,
+                            "Description packet request type invalid: " + c,
+                            "08P01");
+                    }
+
+                    // TODO:  Try sending a warning to client for both == null.
+                    // Broke things earlier, but that may have been due to
+                    // other problems.
+                    if (server.isTrace()) {
+                        server.printWithThread("Closed " + c + " '" + handle
+                                               + "'? "
+                                               + (odbcPs != null
+                                                  || portal != null));
+                    }
+
+                    outPacket.xmit('3', dataOutput);
+                    break;
+
+                default :
+                    throw new RecoverableOdbcFailure(
+                        null,
+                        "Unsupported operation type (" + inPacket.packetType
+                        + ')', "0A000");
+            }
+
+            OdbcUtil.validateInputPacketSize(inPacket);
+
+            if (interposedStatement != null) {
+                server.printWithThread("Interposing AFTER primary statement: "
+                                       + interposedStatement);
+                odbcExecDirect(interposedStatement);
+            }
+
+            if (sendReadyForQuery) {
+                outPacket.reset();
+
+                // The reset is unnecessary now.  For safety in case somebody
+                // codes something above which may abort processing of a
+                // packet before xmit.
+                outPacket.writeByte(session.isAutoCommit() ? 'I'
+                                                           : 'T');
+                outPacket.xmit('Z', dataOutput);
+            }
+        } catch (RecoverableOdbcFailure rf) {
+            Result errorResult = rf.getErrorResult();
+
+            if (errorResult == null) {
+                String stateCode = rf.getSqlStateCode();
+                String svrMsg    = rf.getMessage();
+                String cliMsg    = rf.getClientMessage();
+
+                if (svrMsg != null) {
+                    server.printWithThread(svrMsg);
+                } else if (server.isTrace()) {
+                    server.printWithThread("Client error: " + cliMsg);
+                }
+
+                if (cliMsg != null) {
+                    OdbcUtil.alertClient(OdbcUtil.ODBC_SEVERITY_ERROR, cliMsg,
+                                         stateCode, dataOutput);
+                }
+            } else {
+                if (server.isTrace()) {
+                    server.printWithThread("Result object error: "
+                                           + errorResult.getMainString());
+                }
+
+                // This class of error is not considered a Server problem, so
+                // we don't log on the server side.
+                OdbcUtil.alertClient(OdbcUtil.ODBC_SEVERITY_ERROR,
+                                     errorResult.getMainString(),
+                                     errorResult.getSubString(), dataOutput);
+            }
+
+            switch (odbcCommMode) {
+
+                case OdbcUtil.ODBC_SIMPLE_MODE :
+                    outPacket.reset();                        /// transaction status = Error
+                    outPacket.writeByte('E');                 /// transaction status = Error
+
+                    // TODO:  Consider keeping this state until the session
+                    // is either committed or rolled back.
+                    // (Right now we just return 'E' here, then revert to
+                    // I or T).
+                    outPacket.xmit('Z', dataOutput);
+                    break;
+
+                case OdbcUtil.ODBC_EXTENDED_MODE :
+                    odbcCommMode = OdbcUtil.ODBC_EXT_RECOVER_MODE;
+
+                    server.printWithThread("Reverting to EXT_RECOVER mode");
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Initializes this connection and runs the request handling
+     * loop until closed.
+     */
+    public void run() {
+
+        int msgType;
+
+        init();
+
+        if (session != null) {
+            try {
+                while (keepAlive) {
+                    msgType = dataInput.readByte();
+
+                    if (msgType < ResultConstants.MODE_UPPER_LIMIT) {
+                        receiveResult(msgType);
+                    } else {
+                        receiveOdbcPacket((char) msgType);
+                    }
+                }
+            } catch (CleanExit ce) {
+                keepAlive = false;
+            } catch (IOException e) {
+
+                // fredt - is thrown when connection drops
+                server.printWithThread(mThread + ":disconnected " + user);
+            } catch (HsqlException e) {
+
+                // fredt - is thrown while constructing the result or server shutdown
+                // blaine - Should we check shutdown state and slip the stack
+                //          trace if this exception is expected?
+                if (keepAlive) {
+                    server.printStackTrace(e);
+                }
+            }
+        }
+
+        close();
+    }
+
+    private Result setDatabase(Result resultIn) {
+
+        try {
+            String databaseName = resultIn.getDatabaseName();
+
+            dbIndex = server.getDBIndex(databaseName);
+            dbID    = server.dbID[dbIndex];
+            user    = resultIn.getMainString();
+
+            if (!server.isSilent()) {
+                server.printWithThread(mThread + ":Trying to connect user '"
+                                       + user + "' to DB (" + databaseName
+                                       + ')');
+            }
+
+            session = DatabaseManager.newSession(dbID, user,
+                                                 resultIn.getSubString(),
+                                                 resultIn.getZoneString(),
+                                                 resultIn.getUpdateCount());
+
+            if (!server.isSilent()) {
+                server.printWithThread(mThread + ":Connected user '" + user
+                                       + "'");
+            }
+
+            return Result.newConnectionAcknowledgeResponse(
+                session.getDatabase(), session.getId(),
+                session.getDatabase().getDatabaseID());
+        } catch (HsqlException e) {
+            session = null;
+
+            return Result.newErrorResult(e);
+        } catch (RuntimeException e) {
+            session = null;
+
+            return Result.newErrorResult(e);
+        }
+    }
+
+    /**
+     * Retrieves the thread name to be used  when
+     * this object is the Runnable object of a Thread.
+     *
+     * @return the thread name to be used  when this object is the Runnable
+     * object of a Thread.
+     */
+    String getConnectionThreadName() {
+        return "HSQLDB Connection @" + Integer.toString(hashCode(), 16);
+    }
+
+    /**
+     * Don't want this too high, or users may give up before seeing the
+     * banner.  Can't be too low or we could close a valid but slow
+     * client connection.
+     */
+    public static long MAX_WAIT_FOR_CLIENT_DATA   = 1000;    // ms.
+    public static long CLIENT_DATA_POLLING_PERIOD = 100;     // ms.
+
+    /**
+     * The only known case where a connection attempt will get stuck is
+     * if client connects with hsqls to a https server; or
+     * hsql to a http server.
+     * All other client X server combinations are handled gracefully.
+     * <P/>
+     * If returns (a.o.t. throws), then state variable streamProtocol will
+     * be set.
+     *
+     * @return int read as first thing off of stream
+     */
+    public int handshake() throws IOException, HsqlException {
+
+        long clientDataDeadline = new java.util.Date().getTime()
+                                  + MAX_WAIT_FOR_CLIENT_DATA;
+
+        if (!(socket instanceof javax.net.ssl.SSLSocket)) {
+
+            // available() does not work for SSL socket input stream
+            do {
+                try {
+                    Thread.sleep(CLIENT_DATA_POLLING_PERIOD);
+                } catch (InterruptedException ie) {}
+            } while (dataInput.available() < 5
+                     && new java.util.Date().getTime() < clientDataDeadline);
+
+            // Old HSQLDB clients will send resultType byte + 4 length bytes
+            // New HSQLDB clients will send NCV int + above = 9 bytes
+            // ODBC clients will send a much larger StartupPacket
+            if (dataInput.available() < 1) {
+                dataOutput.write(
+                    (TEXTBANNER_PART1
+                     + ClientConnection.NETWORK_COMPATIBILITY_VERSION
+                     + TEXTBANNER_PART2 + '\n').getBytes());
+                dataOutput.flush();
+
+                throw Error.error(ErrorCode.SERVER_UNKNOWN_CLIENT);
+            }
+        }
+
+        int firstInt = dataInput.readInt();
+
+        switch (firstInt >> 24) {
+
+            case 80 :    // Empirically
+                server.print(
+                    "Rejected attempt from client using hsql HTTP protocol");
+
+                return 0;
+
+            case 0 :
+
+                // For ODBC protocol, this is the first byte of a 4-byte int
+                // size.  The size can never be large enough that the first
+                // byte will be non-zero.
+                streamProtocol = ODBC_STREAM_PROTOCOL;
+                break;
+
+            default :
+                streamProtocol = HSQL_STREAM_PROTOCOL;
+
+            // HSQL protocol client
+        }
+
+        return firstInt;
+    }
+
+    private void odbcConnect(int firstInt) throws IOException, HsqlException {
+
+        /* Until client receives teh ReadyForQuery packet at the end of this
+         * method, we (the server) initiate all packet exchanges. */
+        int major = dataInput.readUnsignedShort();
+        int minor = dataInput.readUnsignedShort();
+
+        // Can just return to fail, until the value of "session" is set below.
+        if (major == 1 && minor == 7) {
+
+            // This is what old HyperSQL versions always send
+            // TODO:  Consider sending client a 1.8-compatible SQLException
+            server.print("A pre-9.0 client attempted to connect.  "
+                         + "We rejected them.");
+
+            return;
+        }
+
+        if (major == 1234 && minor == 5679) {
+
+            // No reason to pay any attention to the size header in this case.
+            dataOutput.writeByte('N');    // SSL not supported yet
+
+            // TODO:  Implement SSL here (and reply with 'S')
+            odbcConnect(dataInput.readInt());
+
+            return;
+        }
+
+        if (major == 1234 && minor == 5678) {
+
+            // No reason to pay any attention to the size header in this case.
+            if (firstInt != 16) {
+                server.print(
+                    "ODBC cancellation request sent wrong packet length: "
+                    + firstInt);
+            }
+
+            server.print(
+                "Got an ODBC cancelation request for thread ID "
+                + dataInput.readInt() + ", but we don't support "
+                + "OOB cancellation yet.  "
+                + "Ignoring this request and closing the connection.");
+
+            // N.b.,  Spec says to NOT reply to client in this case.
+            return;
+        }
+
+        server.printWithThread("ODBC client connected.  "
+                               + "ODBC Protocol Compatibility Version "
+                               + major + '.' + minor);
+
+        OdbcPacketInputStream inPacket =
+            OdbcPacketInputStream.newOdbcPacketInputStream('\0', dataInput,
+                firstInt - 8);
+
+        // - 4 for size of firstInt - 2 for major - 2 for minor
+        java.util.Map stringPairs = inPacket.readStringPairs();
+
+        if (server.isTrace()) {
+            server.print("String Pairs from ODBC client: " + stringPairs);
+        }
+
+        try {
+            try {
+                OdbcUtil.validateInputPacketSize(inPacket);
+            } catch (RecoverableOdbcFailure rf) {
+
+                // In this case, we do not treat it as recoverable
+                throw new ClientFailure(rf.getMessage(),
+                                        rf.getClientMessage());
+            }
+
+            inPacket.close();
+
+            if (!stringPairs.containsKey("database")) {
+                throw new ClientFailure("Client did not identify database",
+                                        "Target database not identified");
+            }
+
+            if (!stringPairs.containsKey("user")) {
+                throw new ClientFailure("Client did not identify user",
+                                        "Target account not identified");
+            }
+
+            String databaseName = (String) stringPairs.get("database");
+
+            user = (String) stringPairs.get("user");
+
+            if (databaseName.equals("/")) {
+
+                // Work-around because ODBC doesn't allow "" for Database name
+                databaseName = "";
+            }
+
+            /* Unencoded/unsalted authentication */
+            dataOutput.writeByte('R');
+            dataOutput.writeInt(8);    //size
+            dataOutput.writeInt(OdbcUtil.ODBC_AUTH_REQ_PASSWORD);
+            dataOutput.flush();
+
+            // areq of auth. mode.
+            char c = '\0';
+
+            try {
+                c = (char) dataInput.readByte();
+            } catch (EOFException eofe) {
+                server.printWithThread(
+                    "Looks like we got a goofy psql no-auth attempt.  "
+                    + "Will probably retry properly very shortly");
+
+                return;
+            }
+
+            if (c != 'p') {
+                throw new ClientFailure(
+                    "Expected password prefix 'p', " + "but got '" + c + "'",
+                    "Password value not prefixed with 'p'");
+            }
+
+            int len = dataInput.readInt() - 5;
+
+            // Is password len after -4 for count int -1 for null term
+            if (len < 0) {
+                throw new ClientFailure(
+                    "Client submitted invalid password length " + len,
+                    "Invalid password length " + len);
+            }
+
+            String password = ServerConnection.readNullTermdUTF(len,
+                dataInput);
+
+            dbIndex = server.getDBIndex(databaseName);
+            dbID    = server.dbID[dbIndex];
+
+            if (!server.isSilent()) {
+                server.printWithThread(mThread + ":Trying to connect user '"
+                                       + user + "' to DB (" + databaseName
+                                       + ')');
+            }
+
+            try {
+                session = DatabaseManager.newSession(dbID, user, password,
+                                                     null, 0);
+
+                // TODO:  Find out what updateCount, the last para, is for:
+                //                                   resultIn.getUpdateCount());
+            } catch (Exception e) {
+                throw new ClientFailure("User name or password denied: " + e,
+                                        "Login attempt rejected");
+            }
+        } catch (ClientFailure cf) {
+            server.print(cf.getMessage());
+
+            // Code below means CONNECTION FAILURE
+            OdbcUtil.alertClient(OdbcUtil.ODBC_SEVERITY_FATAL,
+                                 cf.getClientMessage(), "08006", dataOutput);
+
+            return;
+        }
+
+        outPacket = OdbcPacketOutputStream.newOdbcPacketOutputStream();
+
+        outPacket.writeInt(OdbcUtil.ODBC_AUTH_REQ_OK);    //success
+        outPacket.xmit('R', dataOutput);                  // Notify client of success
+
+        for (int i = 0; i < OdbcUtil.hardcodedParams.length; i++) {
+            OdbcUtil.writeParam(OdbcUtil.hardcodedParams[i][0],
+                                OdbcUtil.hardcodedParams[i][1], dataOutput);
+        }
+
+        // If/when we implement OOB cancellation, we would send the
+        // Session identifier and key here, with a 'K' packet.
+        outPacket.writeByte('I');           // Trans. status = Not in transaction
+        outPacket.xmit('Z', dataOutput);    // Notify client of success
+
+        // This ReadyForQuery turns over responsibility to initiate packet
+        // exchanges to the client.
+        OdbcUtil.alertClient(
+            OdbcUtil.ODBC_SEVERITY_INFO,
+            "MHello\nYou have connected to HyperSQL ODBC Server", dataOutput);
+        dataOutput.flush();
+    }
+
+    private java.util.Map sessionOdbcPsMap     = new java.util.HashMap();
+    private java.util.Map sessionOdbcPortalMap = new java.util.HashMap();
+
+    /**
+     * Read String directy from dataInput.
+     *
+     * @param reqLength Required length
+     */
+    private static String readNullTermdUTF(int reqLength,
+                                           java.io.InputStream istream)
+                                           throws IOException {
+
+        /* Would be MUCH easier to do this with Java6's String
+         * encoding/decoding operations */
+        int    bytesRead = 0;
+        byte[] ba        = new byte[reqLength + 3];
+
+        ba[0] = (byte) (reqLength >>> 8);
+        ba[1] = (byte) reqLength;
+
+        while (bytesRead < reqLength + 1) {
+            bytesRead += istream.read(ba, 2 + bytesRead,
+                                      reqLength + 1 - bytesRead);
+        }
+
+        if (ba[ba.length - 1] != 0) {
+            throw new IOException("String not null-terminated");
+        }
+
+        for (int i = 2; i < ba.length - 1; i++) {
+            if (ba[i] == 0) {
+                throw new RuntimeException("Null internal to String at offset "
+                                           + (i - 2));
+            }
+        }
+
+        java.io.DataInputStream dis =
+            new java.io.DataInputStream(new ByteArrayInputStream(ba));
+        String s = dis.readUTF();
+
+        //String s = java.io.DataInputStream.readUTF(dis);
+        // TODO:  Test the previous two to see if one works better for
+        // high-order characters.
+        dis.close();
+
+        return s;
+    }
+
+    // Tentative state variable
+    private int      streamProtocol            = UNDEFINED_STREAM_PROTOCOL;
+    static final int UNDEFINED_STREAM_PROTOCOL = 0;
+    static final int HSQL_STREAM_PROTOCOL      = 1;
+    static final int ODBC_STREAM_PROTOCOL      = 2;
+    int              odbcCommMode              = OdbcUtil.ODBC_SIMPLE_MODE;
+
+    private void odbcExecDirect(String inStatement)
+    throws RecoverableOdbcFailure, IOException {
+
+        String statement = inStatement;
+        String norm      = statement.trim().toLowerCase();
+
+        if (norm.startsWith("release ")
+                && !norm.startsWith("release savepoint")) {
+            server.printWithThread(
+                "Transmogrifying 'RELEASE ...' to 'RELEASE SAVEPOINT...");
+
+            statement = statement.trim().substring(0, "release ".length())
+                        + "SAVEPOINT "
+                        + statement.trim().substring("release ".length());
+        }
+
+        Result r = Result.newExecuteDirectRequest();
+
+        r.setPrepareOrExecuteProperties(
+            statement, 0, 0, StatementTypes.RETURN_COUNT, 0,
+            ResultProperties.defaultPropsValue,
+            ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);
+
+        Result rOut = session.execute(r);
+
+        switch (rOut.getType()) {
+
+            case ResultConstants.UPDATECOUNT :
+                break;
+
+            case ResultConstants.ERROR :
+                throw new RecoverableOdbcFailure(rOut);
+            default :
+                throw new RecoverableOdbcFailure(
+                    "Output Result from execution is of "
+                    + "unexpected type: " + rOut.getType());
+        }
+
+        outPacket.reset();
+        outPacket.write(OdbcUtil.echoBackReplyString(norm,
+                rOut.getUpdateCount()));
+
+        // This keeps session.autoUpdate in sync with client's notion
+        // of transaction state.
+        outPacket.xmit('C', dataOutput);
+
+        if (norm.equals("commit") || norm.startsWith("commit ")
+                || norm.equals("rollback") || norm.startsWith("rollback ")) {
+            try {
+                session.setAutoCommit(true);
+            } catch (HsqlException he) {
+                throw new RecoverableOdbcFailure(
+                    "Failed to change transaction state: " + he.getMessage(),
+                    he.getSQLState());
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/server/ServerConstants.java b/src/org/hsqldb/server/ServerConstants.java
new file mode 100644
index 0000000..c2e01e4
--- /dev/null
+++ b/src/org/hsqldb/server/ServerConstants.java
@@ -0,0 +1,101 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+/**
+ * An enumeration of the property keys and default property values used by
+ * HSQLDB servers
+ *
+ * @author  boucherb@users
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public interface ServerConstants {
+
+    // server states
+    int SERVER_STATE_ONLINE   = 1;
+    int SERVER_STATE_OPENING  = 4;
+    int SERVER_STATE_CLOSING  = 8;
+    int SERVER_STATE_SHUTDOWN = 16;
+    int SC_DATABASE_SHUTDOWN  = 0;
+
+    // use default address for server socket
+    String SC_DEFAULT_ADDRESS = "0.0.0.0";
+
+    // default database name if non specified
+    String SC_DEFAULT_DATABASE = "test";
+
+    // default port for each protocol
+    int SC_DEFAULT_HSQL_SERVER_PORT  = 9001;
+    int SC_DEFAULT_HSQLS_SERVER_PORT = 554;
+    int SC_DEFAULT_HTTP_SERVER_PORT  = 80;
+    int SC_DEFAULT_HTTPS_SERVER_PORT = 443;
+    int SC_DEFAULT_BER_SERVER_PORT   = 9101;
+
+    // operation modes
+    boolean SC_DEFAULT_SERVER_AUTORESTART = false;
+    boolean SC_DEFAULT_NO_SYSTEM_EXIT     = true;
+    boolean SC_DEFAULT_SILENT             = true;
+    boolean SC_DEFAULT_TLS                = false;
+    boolean SC_DEFAULT_TRACE              = false;
+    boolean SC_DEFAULT_REMOTE_OPEN_DB     = false;
+    int     SC_DEFAULT_MAX_DATABASES      = 10;
+
+    // type of server
+    int SC_PROTOCOL_HTTP = 0;
+    int SC_PROTOCOL_HSQL = 1;
+    int SC_PROTOCOL_BER  = 2;
+
+    // keys to properties
+    String SC_KEY_PREFIX             = "server";
+    String SC_KEY_ADDRESS            = SC_KEY_PREFIX + ".address";
+    String SC_KEY_AUTORESTART_SERVER = SC_KEY_PREFIX + ".restart_on_shutdown";
+    String SC_KEY_DATABASE           = SC_KEY_PREFIX + ".database";
+    String SC_KEY_DBNAME             = SC_KEY_PREFIX + ".dbname";
+    String SC_KEY_NO_SYSTEM_EXIT     = SC_KEY_PREFIX + ".no_system_exit";
+    String SC_KEY_PORT               = SC_KEY_PREFIX + ".port";
+    String SC_KEY_SILENT             = SC_KEY_PREFIX + ".silent";
+    String SC_KEY_TLS                = SC_KEY_PREFIX + ".tls";
+    String SC_KEY_TRACE              = SC_KEY_PREFIX + ".trace";
+    String SC_KEY_DAEMON             = SC_KEY_PREFIX + ".daemon";
+    String SC_KEY_WEB_DEFAULT_PAGE   = SC_KEY_PREFIX + ".default_page";
+    String SC_KEY_WEB_ROOT           = SC_KEY_PREFIX + ".root";
+    String SC_KEY_MAX_CONNECTIONS    = SC_KEY_PREFIX + ".maxconnections";
+    String SC_KEY_REMOTE_OPEN_DB     = SC_KEY_PREFIX + ".remote_open";
+    String SC_KEY_MAX_DATABASES      = SC_KEY_PREFIX + ".maxdatabases";
+    String SC_KEY_ACL_FILEPATH       = SC_KEY_PREFIX + ".acl_filepath";
+
+    // web server page defaults
+    String SC_DEFAULT_WEB_MIME = "text/html";
+    String SC_DEFAULT_WEB_PAGE = "index.html";
+    String SC_DEFAULT_WEB_ROOT = ".";
+}
diff --git a/src/org/hsqldb/server/ServerProperties.java b/src/org/hsqldb/server/ServerProperties.java
new file mode 100644
index 0000000..a07ab44
--- /dev/null
+++ b/src/org/hsqldb/server/ServerProperties.java
@@ -0,0 +1,316 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.util.Enumeration;
+
+import org.hsqldb.lib.HashMap;
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.persist.HsqlProperties;
+
+/**
+ * A subclass HsqlProperties with functionality needed for the HSQLDB Server
+ * implementations.<p>
+ *
+ * A property object is checked once and all the errors are stored in
+ * collections to be used
+ *
+ * Meta records specify accepted keys and policies for the expected values.<p>
+ *
+ * Policy for defaults: <ul>
+ *  <li>If (non-null) default is specified for the Meta record, then
+ *  behavior is obvious.
+ *  <li>If pattern-type Meta record, then there is no default.
+ *  A value is required for the property.
+ *  <li>Otherwise null is specified for the Meta record and user must set
+ *  a value.
+ * </ul>
+ *
+ * If a range is specified in the Meta record, then the value is checked
+ * against the range.<p>
+ *
+ * If a set of values specified in the Meta record, then the value is checked
+ * against the set.<p>
+ *
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ServerProperties extends HsqlProperties {
+
+    // types of properties
+    final static int SERVER_PROPERTY       = 0;
+    final static int SERVER_MULTI_PROPERTY = 1;
+    final static int SYSTEM_PROPERTY       = 2;
+
+    // keys to properties
+    final static String sc_key_address = "server.address";
+    final static String sc_key_autorestart_server =
+        "server.restart_on_shutdown";
+    final static String sc_key_database         = "server.database.";
+    final static String sc_key_dbname           = "server.dbname.";
+    final static String sc_key_no_system_exit   = "server.no_system_exit";
+    final static String sc_key_port             = "server.port";
+    final static String sc_key_http_port        = "server.port";
+    final static String sc_key_silent           = "server.silent";
+    final static String sc_key_tls              = "server.tls";
+    final static String sc_key_trace            = "server.trace";
+    final static String sc_key_web_default_page = "server.default_page";
+    final static String sc_key_web_root         = "server.root";
+    final static String sc_key_max_connections  = "server.maxconnections";
+    final static String sc_key_remote_open_db   = "server.remote_open";
+    final static String sc_key_max_databases    = "server.maxdatabases";
+    final static String sc_key_acl              = "server.acl";
+    final static String sc_key_daemon           = "server.daemon";
+    final static String sc_key_system           = "system.";
+
+    // web server page defaults
+    final static String sc_default_web_mime = "text/html";
+    final static String sc_default_web_page = "index.html";
+    final static String sc_default_web_root = ".";
+
+    //
+    final static HashMap        meta     = new HashMap();
+    final static OrderedHashSet prefixes = new OrderedHashSet();
+
+    //
+    final int         protocol;
+    protected boolean initialised = false;
+
+    //
+    IntKeyHashMap  idToAliasMap = new IntKeyHashMap();
+    IntKeyHashMap  idToPathMap  = new IntKeyHashMap();
+    HashMappedList databases    = new HashMappedList();
+
+    //
+    HsqlArrayList errorList = new HsqlArrayList();
+
+    ServerProperties(int protocol) {
+        this.protocol = protocol;
+    }
+
+    ServerProperties(int protocol, String path) {
+
+        super(path);
+
+        this.protocol = protocol;
+    }
+
+    /**
+     * Validates according to Meta map, and sets System Properties for those
+     * properties with names matching the requisite pattern.
+     */
+    void validate() {
+
+        Enumeration en = stringProps.propertyNames();
+
+        while (en.hasMoreElements()) {
+            String   key      = (String) en.nextElement();
+            Object[] metadata = (Object[]) meta.get(key);
+
+            if (metadata == null) {
+                metadata = getPrefixedMetadata(key);
+            }
+
+            if (metadata == null) {
+                String error = "unsupported property: " + key;
+
+                errorList.add(error);
+
+                continue;
+            }
+
+            String error = null;
+
+            if (((Integer) metadata[indexType]).intValue()
+                    == SYSTEM_PROPERTY) {
+                error = validateSystemProperty(key, metadata);
+            } else if (((Integer) metadata[indexType]).intValue()
+                       == SERVER_MULTI_PROPERTY) {
+                error = validateMultiProperty(key, metadata);
+            } else {
+                String value = getProperty(key);
+
+                if (value == null) {
+                    if (metadata[indexDefaultValue] == null) {
+                        error = "missing value for property: " + key;
+                    } else {
+                        setProperty(key,
+                                    metadata[indexDefaultValue].toString());
+                    }
+                } else {
+                    error = HsqlProperties.validateProperty(key, value,
+                            metadata);
+                }
+            }
+
+            if (error != null) {
+                errorList.add(error);
+            }
+        }
+
+        Iterator it = idToAliasMap.keySet().iterator();
+
+        while (it.hasNext()) {
+            int number = it.nextInt();
+
+            if (!idToPathMap.containsKey(number)) {
+                errorList.add("no path for database id: " + number);
+            }
+        }
+
+        it = idToPathMap.keySet().iterator();
+
+        while (it.hasNext()) {
+            int number = it.nextInt();
+
+            if (!idToAliasMap.containsKey(number)) {
+                errorList.add("no alias for database id: " + number);
+            }
+        }
+
+        initialised = true;
+    }
+
+    Object[] getPrefixedMetadata(String key) {
+
+        for (int i = 0; i < prefixes.size(); i++) {
+            String prefix = (String) prefixes.get(i);
+
+            if (key.startsWith(prefix)) {
+                return (Object[]) meta.get(prefix);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Checks an alias or database path. Duplicates are checked as duplicate
+     * numbering may result from differnt strings (e.g. 02 and 2).
+     */
+    String validateMultiProperty(String key, Object[] meta) {
+
+        int    dbNumber;
+        String prefix = (String) meta[indexName];
+
+        try {
+            dbNumber = Integer.parseInt(key.substring(prefix.length()));
+        } catch (NumberFormatException e1) {
+            return ("maformed database enumerator: " + key);
+        }
+
+        if (meta[indexName].equals(sc_key_dbname)) {
+            String alias = stringProps.getProperty(key).toLowerCase();
+
+            if (databases.containsKey(alias)) {
+                return "duplicate alias: " + alias;
+            }
+
+            Object existing = idToAliasMap.put(dbNumber, alias);
+
+            if (existing != null) {
+                return "duplicate database enumerator: " + key;
+            }
+        } else if (meta[indexName].equals(sc_key_database)) {
+            String path     = stringProps.getProperty(key);
+            Object existing = idToPathMap.put(dbNumber, path);
+
+            if (existing != null) {
+                return "duplicate database enumerator: " + key;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * System properties are currently not checked, as different libraries in
+     * the environment may need different names?
+     */
+    String validateSystemProperty(String key, Object[] meta) {
+
+        String prefix      = (String) meta[indexName];
+        String specificKey = key.substring(prefix.length());
+        String value       = stringProps.getProperty(key);
+
+        if (value == null) {
+            return "value required for property: " + key;
+        }
+
+        System.setProperty(specificKey, value);
+
+        return null;
+    }
+
+    static {
+
+        // properties with variable suffixes
+        meta.put(sc_key_database,
+                 getMeta(sc_key_database, SERVER_MULTI_PROPERTY, null));
+        meta.put(sc_key_dbname,
+                 getMeta(sc_key_dbname, SERVER_MULTI_PROPERTY, null));
+        meta.put(sc_key_system, getMeta(sc_key_system, SYSTEM_PROPERTY, null));
+
+        // properties with fixed names
+        meta.put(sc_key_silent,
+                 getMeta(sc_key_silent, SERVER_PROPERTY, false));
+        meta.put(sc_key_trace, getMeta(sc_key_trace, SERVER_PROPERTY, false));
+        meta.put(sc_key_tls, getMeta(sc_key_tls, SERVER_PROPERTY, false));
+        meta.put(sc_key_acl, getMeta(sc_key_acl, SERVER_PROPERTY, false));
+        meta.put(sc_key_autorestart_server,
+                 getMeta(sc_key_autorestart_server, SERVER_PROPERTY, false));
+        meta.put(sc_key_remote_open_db,
+                 getMeta(sc_key_remote_open_db, SERVER_PROPERTY, false));
+        meta.put(sc_key_no_system_exit,
+                 getMeta(sc_key_no_system_exit, SERVER_PROPERTY, false));
+        meta.put(sc_key_daemon, getMeta(sc_key_daemon, SERVER_PROPERTY, false));
+
+        //
+        prefixes.add(sc_key_database);
+        prefixes.add(sc_key_dbname);
+        prefixes.add(sc_key_system);
+
+        //
+        meta.put(sc_key_address,
+                 getMeta(sc_key_address, SERVER_PROPERTY, null));
+        meta.put(sc_key_port, getMeta(sc_key_port, 0, 9001, 0, 65535));
+        meta.put(sc_key_http_port, getMeta(sc_key_http_port, 0, 80, 0, 65535));
+        meta.put(sc_key_max_connections,
+                 getMeta(sc_key_max_connections, 0, 100, 1, 10000));
+        meta.put(sc_key_max_databases,
+                 getMeta(sc_key_max_databases, 0, 10, 1, 1000));
+    }
+}
diff --git a/src/org/hsqldb/server/Servlet.java b/src/org/hsqldb/server/Servlet.java
new file mode 100644
index 0000000..e26635a
--- /dev/null
+++ b/src/org/hsqldb/server/Servlet.java
@@ -0,0 +1,320 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.DatabaseURL;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Session;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.rowio.RowInputBinary;
+import org.hsqldb.rowio.RowOutputBinary;
+
+// fredt@users 20020130 - patch 475586 by wreissen@users
+// fredt@users 20020328 - patch 1.7.0 by fredt - error trapping
+// fredt@users 20030630 - patch 1.7.2 - new protocol, persistent sessions
+// fredt@users 20041112 - patch by Willian Crick - use web_inf directory
+
+/**
+ * Servlet can act as an interface between the client and the database for the
+ * the client / server mode of HSQL Database Engine. It uses the HTTP protocol
+ * for communication. This class is not required if the included HSQLDB
+ * Weberver is used on the server host. But if the host is running a J2EE
+ * application server or a servlet container such as Tomcat, the Servlet class
+ * can be hosted on this server / container to serve external requests from
+ * external hosts.<p>
+ * The remote applet / application should
+ * use the normal JDBC interfaces to connect to the URL of this servlet. An
+ * example URL is:
+ * <pre>
+ * jdbc:hsqldb:http://myhost.com:8080/servlet/org.hsqldb.server.Servlet
+ * </pre>
+ * The database path/name is taken from the servlet engine property:
+ * <pre>
+ * hsqldb.server.database
+ * </pre>
+ * <p>
+ * If the database is deployed in the WEB-INF directory of the servlet container,
+ * the property:
+ * <pre>
+ *  hsqldb.server.use_web-inf_path
+ * </pre>
+ * should be set "true" in the web.xml file of the servlet container.
+ * In this case, the database path should begin with a "/".
+ *
+ * JDBC connections via the HTTP protocol are persistent
+ * in the JDBC sense. The JDBC Connection that is established can support
+ * transactions spanning several Statement calls and real PreparedStatement
+ * calls are supported. This class has been rewritten to support the new
+ * features.<p>
+ * (fredt@users)<p>
+ *
+ * Extensively rewritten for HSQLDB.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class Servlet extends javax.servlet.http.HttpServlet {
+
+    private static final int BUFFER_SIZE = 256;
+    private String           dbType;
+    private String           dbPath;
+    private String           errorStr;
+    private RowOutputBinary  rowOut;
+    private RowInputBinary   rowIn;
+    private int              iQueries;
+
+    public void init(ServletConfig config) {
+
+        try {
+            super.init(config);
+
+            rowOut = new RowOutputBinary(BUFFER_SIZE, 1);
+            rowIn  = new RowInputBinary(rowOut);
+        } catch (ServletException e) {
+            log(e.toString());
+        }
+
+        String dbStr = getInitParameter("hsqldb.server.database");
+
+        if (dbStr == null) {
+            dbStr = ".";
+        }
+
+// begin WEB-INF patch */
+        String useWebInfStr =
+            getInitParameter("hsqldb.server.use_web-inf_path");
+
+        if (!dbStr.equals(".") && "true".equalsIgnoreCase(useWebInfStr)) {
+            dbStr = getServletContext().getRealPath("/") + "WEB-INF/" + dbStr;
+        }
+
+// end WEB-INF patch
+        HsqlProperties dbURL = DatabaseURL.parseURL(dbStr, false, false);
+
+        log("Database filename = " + dbStr);
+
+        if (dbURL == null) {
+            errorStr = "Bad Database name";
+        } else {
+            dbPath = dbURL.getProperty("database");
+            dbType = dbURL.getProperty("connection_type");
+
+            try {
+
+// loosecannon1@users 1.7.2 patch properties on the JDBC URL
+                DatabaseManager.getDatabase(dbType, dbPath, dbURL);
+            } catch (HsqlException e) {
+                errorStr = e.getMessage();
+            }
+        }
+
+        log(errorStr);
+        log("Initialization completed.");
+    }
+
+    private static long lModified = 0;
+
+    protected long getLastModified(HttpServletRequest req) {
+
+        // this is made so that the cache of the http server is not used
+        // maybe there is some other way
+        return lModified++;
+    }
+
+    public void doGet(HttpServletRequest request,
+                      HttpServletResponse response)
+                      throws IOException, ServletException {
+
+        String query = request.getQueryString();
+
+        if ((query == null) || (query.length() == 0)) {
+            response.setContentType("text/html");
+
+// fredt@users 20020130 - patch 1.7.0 by fredt
+// to avoid caching on the browser
+            response.setHeader("Pragma", "no-cache");
+
+            PrintWriter out = response.getWriter();
+
+            out.println(
+                "<html><head><title>HSQL Database Engine Servlet</title>");
+            out.println("</head><body><h1>HSQL Database Engine Servlet</h1>");
+            out.println("The servlet is running.<p>");
+
+            if (errorStr == null) {
+                out.println("The database is also running.<p>");
+                out.println("Database name: " + dbType + dbPath + "<p>");
+                out.println("Queries processed: " + iQueries + "<p>");
+            } else {
+                out.println("<h2>The database is not running!</h2>");
+                out.println("The error message is:<p>");
+                out.println(errorStr);
+            }
+
+            out.println("</body></html>");
+        }
+    }
+
+    public void doPost(HttpServletRequest request,
+                       HttpServletResponse response)
+                       throws IOException, ServletException {
+
+        synchronized (this) {
+            DataInputStream  inStream = null;
+            DataOutputStream dataOut  = null;
+
+            try {
+
+                // fredt@users - the servlet container, Resin does not return all
+                // the bytes with one call to input.read(b,0,len) when len > 8192
+                // bytes, the loop in the Result.read() method handles this
+                inStream = new DataInputStream(request.getInputStream());
+
+                int  databaseID = inStream.readInt();
+                long sessionID  = inStream.readLong();
+                int  mode       = inStream.readByte();
+                Session session = DatabaseManager.getSession(databaseID,
+                    sessionID);
+                Result resultIn = Result.newResult(session, mode, inStream,
+                                                   rowIn);
+
+                resultIn.setDatabaseId(databaseID);
+                resultIn.setSessionId(sessionID);
+
+                Result resultOut;
+
+                if (resultIn.getType() == ResultConstants.CONNECT) {
+                    try {
+                        session = DatabaseManager.newSession(
+                            dbType, dbPath, resultIn.getMainString(),
+                            resultIn.getSubString(), new HsqlProperties(),
+                            resultIn.getZoneString(),
+                            resultIn.getUpdateCount());
+
+                        resultIn.readAdditionalResults(null, inStream, rowIn);
+
+                        resultOut = Result.newConnectionAcknowledgeResponse(
+                            session.getDatabase(), session.getId(),
+                            session.getDatabase().getDatabaseID());
+                    } catch (HsqlException e) {
+                        resultOut = Result.newErrorResult(e);
+                    }
+                } else {
+                    int  dbId      = resultIn.getDatabaseId();
+                    long sessionId = resultIn.getSessionId();
+
+                    session = DatabaseManager.getSession(dbId, sessionId);
+
+                    resultIn.readAdditionalResults(session, inStream, rowIn);
+
+                    resultOut = session.execute(resultIn);
+                }
+
+                //
+                response.setContentType("application/octet-stream");
+                response.setContentLength(rowOut.size());
+
+                //
+                dataOut = new DataOutputStream(response.getOutputStream());
+
+                resultOut.write(dataOut, rowOut);
+
+                iQueries++;
+            } catch (HsqlException e) {}
+            finally {
+                if (dataOut != null) {
+                    dataOut.close();
+                }
+
+                if (inStream != null) {
+                    inStream.close();
+                }
+            }
+        }
+
+        // Trace.printSystemOut("Queries processed: "+iQueries+"  \n");
+    }
+}
diff --git a/src/org/hsqldb/server/StatementPortal.java b/src/org/hsqldb/server/StatementPortal.java
new file mode 100644
index 0000000..3a48c16
--- /dev/null
+++ b/src/org/hsqldb/server/StatementPortal.java
@@ -0,0 +1,122 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.util.Map;
+
+import org.hsqldb.Session;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+
+class StatementPortal {
+    public Object[] parameters;
+    public Result bindResult, ackResult;
+    public String lcQuery;
+    public String handle;
+    private Map containingMap;
+    private Session session;
+
+    /**
+     * Convenience wrapper for the 3-param constructor.
+     *
+     * @see #StatementPortal(String, OdbcPreparedStatement, Object[], Map)
+     */
+    public StatementPortal(String handle,
+    OdbcPreparedStatement odbcPs, Map containingMap)
+    throws RecoverableOdbcFailure {
+        this(handle, odbcPs, new Object[0], containingMap);
+    }
+
+    /**
+     * Instantiates a proxy ODBC StatementPortal object for the
+     * Connection Session, and adds the new instance to the specified map.
+     *
+     * @param paramObjs Param values are either String or BinaryData instances
+     */
+    public StatementPortal(String handle, OdbcPreparedStatement odbcPs,
+    Object[] paramObjs, Map containingMap) throws RecoverableOdbcFailure {
+        this.handle = handle;
+        lcQuery = odbcPs.query.toLowerCase();
+        ackResult = odbcPs.ackResult;
+        session = odbcPs.session;
+        this.containingMap = containingMap;
+        bindResult = Result.newPreparedExecuteRequest(
+            odbcPs.ackResult.parameterMetaData.getParameterTypes(),
+            odbcPs.ackResult.getStatementID());
+        switch (bindResult.getType()) {
+            case ResultConstants.EXECUTE:
+                break;
+            case ResultConstants.ERROR:
+                throw new RecoverableOdbcFailure(bindResult);
+            default:
+                throw new RecoverableOdbcFailure(
+                    "Output Result from seconary Statement prep is of "
+                    + "unexpected type: " + bindResult.getType());
+        }
+        if (paramObjs.length < 1) {
+            parameters = new Object[0];
+        } else {
+            org.hsqldb.result.ResultMetaData pmd =
+                odbcPs.ackResult.parameterMetaData;
+            if (pmd == null) {
+                throw new RecoverableOdbcFailure("No metadata for Result ack");
+            }
+            org.hsqldb.types.Type[] paramTypes = pmd.getParameterTypes();
+            if (paramTypes.length != paramObjs.length) {
+                throw new RecoverableOdbcFailure(null,
+                    "Client didn't specify all " + paramTypes.length
+                    + " parameters (" + paramObjs.length + ')', "08P01");
+            }
+            parameters = new Object[paramObjs.length];
+            try {
+                for (int i = 0; i < parameters.length; i++) {
+                    parameters[i] = (paramObjs[i] instanceof String)
+                        ? PgType.getPgType(paramTypes[i], true)
+                            .getParameter((String) paramObjs[i], session)
+                        : paramObjs[i];
+                }
+            } catch (java.sql.SQLException se) {
+                throw new RecoverableOdbcFailure("Typing failure: " + se);
+            }
+        }
+        containingMap.put(handle, this);
+    }
+
+    /**
+     * Releases resources for this instance
+     * and removes this instance from the containing map.
+     */
+    public void close() {
+        // TODO:  Free up resources!
+        containingMap.remove(handle);
+    }
+}
diff --git a/src/org/hsqldb/server/WebServer.java b/src/org/hsqldb/server/WebServer.java
new file mode 100644
index 0000000..b3ce0d7
--- /dev/null
+++ b/src/org/hsqldb/server/WebServer.java
@@ -0,0 +1,270 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.resources.BundleHandler;
+
+// fredt@users 20020215 - patch 1.7.0 by fredt
+// method rorganised to use new HsqlServerProperties class
+// unsaved@users 20021113 - patch 1.7.2 - SSL support
+// boucherb@users 20030510 - patch 1.7.2 - SSL support moved to factory interface
+// boucherb@users 20030510 - patch 1.7.2 - moved all common code to Server
+// boucherb@users 20030510 - patch 1.7.2 - general lint removal
+
+/**
+ *  The HSQLDB HTTP protocol network database server. <p>
+ *
+ *  WebServer has two distinct functions:<p>
+ *
+ *  The primary function is to allow client/server access to HSQLDB databases
+ *  via the HTTP protocol. This protocol is less efficient than the HSQL
+ *  protocol used by the Server class and should be used only in situations
+ *  where sandboxes or firewalls between the client and the server do not
+ *  allow the use of the HSQL protocol. One example is client/server access by
+ *  an applet running in browsers on remote hosts and accessing the database
+ *  engine on the HTTP server from which the applet originated. From version
+ *  1.7.2, HTTP database connections are persistent and support transactions.
+ *  Similar to HSQL connections, they should be explicitly closed to free the
+ *  server resources. <p>
+ *
+ *  The secondary function of WebServer is to act as a simple general purpose
+ *  HTTP server. It is aimed to support the minimum requirements set out by
+ *  the HTTP/1.0 standard. The HEAD and GET methods can be used to query and
+ *  retreive static files from the HTTP server.<p>
+ *
+ *  Both the database server and HTTP server functions of WebServer can be
+ *  configured with the webserver.properties file. It contains entries for the
+ *  database server similar to those for the HSQL protocol Server class. In
+ *  addition, a list mapping different file endings to their mime types may be
+ *  included in this file. (fredt@users) <p>
+ *
+ * From the command line, the options are as follows: <p>
+ * <pre>
+ * +-----------------+-------------+----------+------------------------------+
+ * |    OPTION       |    TYPE     | DEFAULT  |         DESCRIPTION          |
+ * +-----------------+-------------+----------+------------------------------|
+ * | --help          |             |          | prints this message          |
+ * | --address       | name|number | any      | server inet address          |
+ * | --port          | number      | 80       | port at which server listens |
+ * | --database.i    | [type]spec  | 0=test   | path of database i           |
+ * | --dbname.i      | alias       |          | url alias for database i     |
+ * | --silent        | true|false  | true     | false => display all queries |
+ * | --trace         | true|false  | false    | display JDBC trace messages  |
+ * | --no_system_exit| true|false  | false    | do not issue System.exit()   |
+ * +-----------------+-------------+----------+------------------------------+
+ * </pre>
+ *
+ *  Example of the webserver.properties file:
+ *
+ * <pre>
+ * server.port=80
+ * server.database.0=test
+ * server.dbname.0=...
+ * ...
+ * server.database.n=...
+ * server.dbname.n=...
+ * server.silent=true
+ *
+ * .htm=text/html
+ * .html=text/html
+ * .txt=text/plain
+ * .gif=image/gif
+ * .class=application/octet-stream
+ * .jpg=image/jpeg
+ * .jgep=image/jpeg
+ * .zip=application/x-zip-compressed
+ * </pre>
+ *
+ * <ul>
+ *   <li>For server.root, use '/'  as the separator, even for DOS/Windows.
+ *   <li>File extensions for mime types must be lowercase and start with '.'
+ * </ul>
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class WebServer extends Server {
+
+    /**
+     * Handle to resource bundle providing i18n for things like
+     * HTTP error pages.
+     */
+    static int webBundleHandle = BundleHandler.getBundleHandle("webserver",
+        null);
+
+    public WebServer() {
+        super(ServerConstants.SC_PROTOCOL_HTTP);
+    }
+
+    /**
+     *  Starts a new WebServer.
+     *
+     * @param  args the "command line" parameters with which to start
+     *      the WebServer.  "-?" will cause the command line arguments
+     *      help to be printed to the standard output
+     */
+    public static void main(String[] args) {
+
+        String propsPath =
+            FileUtil.getFileUtil().canonicalOrAbsolutePath("webserver");
+        ServerProperties fileProps = ServerConfiguration.getPropertiesFromFile(
+            ServerConstants.SC_PROTOCOL_HTTP, propsPath);
+        ServerProperties props =
+            fileProps == null
+            ? new ServerProperties(ServerConstants.SC_PROTOCOL_HTTP)
+            : fileProps;
+        HsqlProperties stringProps = null;
+
+        stringProps = HsqlProperties.argArrayToProps(args,
+                ServerConstants.SC_KEY_PREFIX);
+
+        if (stringProps.getErrorKeys().length != 0) {
+            printHelp("webserver.help");
+
+            return;
+        }
+
+        props.addProperties(stringProps);
+        ServerConfiguration.translateDefaultDatabaseProperty(props);
+
+        // Standard behaviour when started from the command line
+        // is to halt the VM when the server shuts down.  This may, of
+        // course, be overridden by whatever, if any, security policy
+        // is in place.
+        ServerConfiguration.translateDefaultNoSystemExitProperty(props);
+
+        // finished setting up properties;
+        Server server = new WebServer();
+
+        try {
+            server.setProperties(props);
+            props.validate();
+
+            // This must be called after setProperties, because stringProps
+            // isn't populated until then.
+        } catch (Exception e) {
+            server.printError("Failed to set properties");
+            server.printStackTrace(e);
+
+            return;
+        }
+
+        // now messages go to the channel specified in properties
+        server.print("Startup sequence initiated from main() method");
+
+        if (fileProps != null) {
+            server.print("Loaded properties from [" + propsPath
+                         + ".properties]");
+        } else {
+            server.print("Could not load properties from file");
+            server.print("Using cli/default properties only");
+        }
+
+        server.start();
+    }
+
+    /**
+     * Retrieves the name of the web page served when no page is specified.
+     * This attribute is relevant only when server protocol is HTTP(S).
+     *
+     * @return the name of the web page served when no page is specified
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Used when server protocol is HTTP(S)"
+     */
+    public String getDefaultWebPage() {
+        return serverProperties.getProperty(
+            ServerConstants.SC_KEY_WEB_DEFAULT_PAGE);
+    }
+
+    /**
+     * Retrieves a String object describing the command line and
+     * properties options for this Server.
+     *
+     * @return the command line and properties options help for this Server
+     */
+    public String getHelpString() {
+        return BundleHandler.getString(serverBundleHandle, "webserver.help");
+    }
+
+    /**
+     * Retrieves this server's product name.  <p>
+     *
+     * Typically, this will be something like: "HSQLDB xxx server".
+     *
+     * @return the product name of this server
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Of Server"
+     */
+    public String getProductName() {
+        return "HSQLDB web server";
+    }
+
+    /**
+     * Retrieves a string respresentaion of the network protocol
+     * this server offers, typically one of 'HTTP', HTTPS', 'HSQL' or 'HSQLS'.
+     *
+     * @return string respresentation of this server's protocol
+     *
+     * @jmx.managed-attribute
+     *  access="read-only"
+     *  description="Used to handle connections"
+     */
+    public String getProtocol() {
+        return isTls() ? "HTTPS"
+                       : "HTTP";
+    }
+
+    /**
+     * Retrieves the root context (directory) from which web content
+     * is served.  This property is relevant only when the server
+     * protocol is HTTP(S).  Although unlikely, it may be that in the future
+     * other contexts, such as jar urls may be supported, so that pages can
+     * be served from the contents of a jar or from the JVM class path.
+     *
+     * @return the root context (directory) from which web content is served
+     *
+     * @jmx.managed-attribute
+     *  access="read-write"
+     *  description="Context (directory)"
+     */
+    public String getWebRoot() {
+        return serverProperties.getProperty(ServerConstants.SC_KEY_WEB_ROOT);
+    }
+}
diff --git a/src/org/hsqldb/server/WebServerConnection.java b/src/org/hsqldb/server/WebServerConnection.java
new file mode 100644
index 0000000..2cd37a3
--- /dev/null
+++ b/src/org/hsqldb/server/WebServerConnection.java
@@ -0,0 +1,553 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.server;
+
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.Socket;
+
+import org.hsqldb.DatabaseManager;
+import org.hsqldb.HsqlException;
+import org.hsqldb.Session;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.DataOutputStream;
+import org.hsqldb.lib.InOutUtil;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+import org.hsqldb.resources.BundleHandler;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultConstants;
+import org.hsqldb.rowio.RowInputBinary;
+import org.hsqldb.rowio.RowOutputBinary;
+
+// fredt@users 20021002 - patch 1.7.1 - changed notification method
+// unsaved@users 20021113 - patch 1.7.2 - SSL support
+// boucherb@users 20030510 - patch 1.7.2 - SSL support moved to factory interface
+// boucherb@users 20030510 - patch 1.7.2 - general lint removal
+// boucherb@users 20030514 - patch 1.7.2 - localized error responses
+// fredt@users 20030628 - patch 1.7.2 - new protocol, persistent sessions
+
+/**
+ *  A web server connection is a transient object that lasts for the duration
+ *  of the SQL call and its result. This class uses the notification
+ *  mechanism in WebServer to allow cleanup after a SHUTDOWN.<p>
+ *
+ *  The POST method is used for login  and subsequent remote calls. In 1.7.2
+ *  The initial login establishes a persistent Session and returns its handle
+ *  to the client. Subsequent calls are executed in the context of this
+ *  session.<p>
+ *  (fredt@users)
+ *
+ * Rewritten in version HSQLDB 1.7.2, based on original Hypersonic code.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+class WebServerConnection implements Runnable {
+
+    static final String         ENCODING = "ISO-8859-1";
+    private Socket              socket;
+    private WebServer           server;
+    private static final int    REQUEST_TYPE_BAD  = 0;
+    private static final int    REQUEST_TYPE_GET  = 1;
+    private static final int    REQUEST_TYPE_HEAD = 2;
+    private static final int    REQUEST_TYPE_POST = 3;
+    private static final String HEADER_OK         = "HTTP/1.0 200 OK";
+    private static final String HEADER_BAD_REQUEST =
+        "HTTP/1.0 400 Bad Request";
+    private static final String HEADER_NOT_FOUND = "HTTP/1.0 404 Not Found";
+    private static final String HEADER_FORBIDDEN = "HTTP/1.0 403 Forbidden";
+    static final int            BUFFER_SIZE      = 256;
+    final byte[]                mainBuffer       = new byte[BUFFER_SIZE];
+    private RowOutputBinary     rowOut = new RowOutputBinary(mainBuffer);
+    private RowInputBinary      rowIn            = new RowInputBinary(rowOut);
+
+    //
+    static byte[] BYTES_GET;
+    static byte[] BYTES_HEAD;
+    static byte[] BYTES_POST;
+    static byte[] BYTES_CONTENT;
+
+    static {
+        try {
+            BYTES_GET     = "GET".getBytes("ISO-8859-1");
+            BYTES_HEAD    = "HEAD".getBytes("ISO-8859-1");
+            BYTES_POST    = "POST".getBytes("ISO-8859-1");
+            BYTES_CONTENT = "Content-Length: ".getBytes("ISO-8859-1");
+        } catch (UnsupportedEncodingException e) {
+            Error.runtimeError(ErrorCode.U_S0500, "RowOutputTextLog");
+        }
+    }
+
+    static final byte[] BYTES_WHITESPACE = new byte[] {
+        (byte) ' ', (byte) '\t'
+    };
+
+    // default mime type mappings
+    private static final int hnd_content_types =
+        BundleHandler.getBundleHandle("content-types", null);
+
+    /**
+     * Creates a new WebServerConnection to the specified WebServer on the
+     * specified socket.
+     *
+     * @param socket the network socket on which WebServer communication
+     *      takes place
+     * @param server the WebServer instance to which the object
+     *      represents a connection
+     */
+    WebServerConnection(Socket socket, WebServer server) {
+        this.server = server;
+        this.socket = socket;
+    }
+
+    /**
+     * Retrieves a best-guess mime-type string using the file extension
+     * of the name argument.
+     *
+     * @return a best-guess mime-type string using the file extension
+     *      of the name argument.
+     */
+    private String getMimeTypeString(String name) {
+
+        int    pos;
+        String key;
+        String mimeType;
+
+        if (name == null) {
+            return ServerConstants.SC_DEFAULT_WEB_MIME;
+        }
+
+        pos      = name.lastIndexOf('.');
+        key      = null;
+        mimeType = null;
+
+        // first search user-specified mapping
+        if (pos >= 0) {
+            key      = name.substring(pos).toLowerCase();
+            mimeType = server.serverProperties.getProperty(key);
+        }
+
+        // if not found, search default mapping
+        if (mimeType == null && key.length() > 1) {
+            mimeType = BundleHandler.getString(hnd_content_types,
+                                               key.substring(1));
+        }
+
+        return mimeType == null ? ServerConstants.SC_DEFAULT_WEB_MIME
+                                : mimeType;
+    }
+
+    /**
+     * Causes this WebServerConnection to process its HTTP request
+     * in a blocking fashion until the request is fully processed
+     * or an exception occurs internally.
+     *
+     * This method reads the Request line then delegates action to subroutines.
+     */
+    public void run() {
+
+        DataInputStream inStream = null;
+
+        try {
+            inStream = new DataInputStream(socket.getInputStream());
+
+            int    count;
+            String request;
+            String name   = null;
+            int    method = REQUEST_TYPE_BAD;
+            int    len    = -1;
+
+            // read line, ignoring any leading blank lines
+            do {
+                count = InOutUtil.readLine(inStream, rowOut);
+
+                if (count == 0) {
+                    throw new Exception();
+                }
+            } while (count < 2);
+
+            byte[] byteArray = rowOut.getBuffer();
+            int    offset    = rowOut.size() - count;
+
+            if (ArrayUtil.containsAt(byteArray, offset, BYTES_POST)) {
+                method = REQUEST_TYPE_POST;
+                offset += BYTES_POST.length;
+            } else if (ArrayUtil.containsAt(byteArray, offset, BYTES_GET)) {
+                method = REQUEST_TYPE_GET;
+                offset += BYTES_GET.length;
+            } else if (ArrayUtil.containsAt(byteArray, offset, BYTES_HEAD)) {
+                method = REQUEST_TYPE_HEAD;
+                offset += BYTES_HEAD.length;
+            } else {
+                method = REQUEST_TYPE_BAD;
+            }
+
+            count = ArrayUtil.countStartElementsAt(byteArray, offset,
+                                                   BYTES_WHITESPACE);
+
+            if (count == 0) {
+                method = REQUEST_TYPE_BAD;
+            }
+
+            offset += count;
+            count = ArrayUtil.countNonStartElementsAt(byteArray, offset,
+                    BYTES_WHITESPACE);
+            name = new String(byteArray, offset, count, ENCODING);
+
+            switch (method) {
+
+                case REQUEST_TYPE_BAD :
+                    processError(REQUEST_TYPE_BAD);
+                    break;
+
+                case REQUEST_TYPE_GET :
+                    processGet(name, true);
+                    break;
+
+                case REQUEST_TYPE_HEAD :
+                    processGet(name, false);
+                    break;
+
+                case REQUEST_TYPE_POST :
+                    processPost(inStream, name);
+                    break;
+            }
+        } catch (Exception e) {
+            server.printStackTrace(e);
+        } finally {
+            try {
+                if (inStream != null) {
+                    inStream.close();
+                }
+
+                socket.close();
+            } catch (IOException ioe) {
+                server.printStackTrace(ioe);
+            }
+        }
+    }
+
+    /**
+     * POST is used only for database access. So we can assume the strings
+     * are those generated by HTTPClientConnection
+     */
+    private void processPost(InputStream inStream,
+                             String name) throws IOException {
+
+        // fredt - parsing in this block is not actually necessary
+        try {
+
+            // read the Content-Type line
+            InOutUtil.readLine(inStream, rowOut);
+
+            // read and parse the Content-Length line
+            int count  = InOutUtil.readLine(inStream, rowOut);
+            int offset = rowOut.size() - count;
+
+            // get buffer always after reading into rowOut, else old buffer may
+            // be returned
+            byte[] byteArray = rowOut.getBuffer();
+
+            if (!ArrayUtil.containsAt(byteArray, offset, BYTES_CONTENT)) {
+                throw new Exception();
+            }
+
+            count  -= BYTES_CONTENT.length;
+            offset += BYTES_CONTENT.length;
+
+            // omit the last two characters
+            String lenStr = new String(byteArray, offset, count - 2);
+            int    length = Integer.parseInt(lenStr);
+
+            InOutUtil.readLine(inStream, rowOut);
+        } catch (Exception e) {
+            processError(HttpURLConnection.HTTP_BAD_REQUEST);
+
+            return;
+        }
+
+        processQuery(inStream);
+    }
+
+    /**
+     * Processes a database query in HSQL protocol that has been
+     * tunneled over HTTP protocol.
+     *
+     * @param inStream the incoming byte stream representing the HSQL protocol
+     *      database query
+     */
+    void processQuery(InputStream inStream) {
+
+        try {
+            DataInputStream dataIn     = new DataInputStream(inStream);
+            int             databaseID = dataIn.readInt();
+            long            sessionID  = dataIn.readLong();
+            int             mode       = dataIn.readByte();
+            Session session = DatabaseManager.getSession(databaseID,
+                sessionID);
+            Result resultIn = Result.newResult(session, mode, dataIn, rowIn);
+
+            resultIn.setDatabaseId(databaseID);
+            resultIn.setSessionId(sessionID);
+
+            //
+            Result resultOut;
+
+            if (resultIn.getType() == ResultConstants.CONNECT) {
+                try {
+                    String databaseName = resultIn.getDatabaseName();
+                    int    dbIndex      = server.getDBIndex(databaseName);
+                    int    dbID         = server.dbID[dbIndex];
+
+                    session =
+                        DatabaseManager.newSession(dbID,
+                                                   resultIn.getMainString(),
+                                                   resultIn.getSubString(),
+                                                   resultIn.getZoneString(),
+                                                   resultIn.getUpdateCount());
+
+                    resultIn.readAdditionalResults(session, dataIn, rowIn);
+
+                    resultOut = Result.newConnectionAcknowledgeResponse(
+                        session.getDatabase(), session.getId(), dbID);
+                } catch (HsqlException e) {
+                    resultOut = Result.newErrorResult(e);
+                } catch (RuntimeException e) {
+                    resultOut = Result.newErrorResult(e);
+                }
+            } else {
+                int dbID = resultIn.getDatabaseId();
+
+                if (session == null) {
+                    resultOut = Result.newErrorResult(
+                        Error.error(ErrorCode.SERVER_DATABASE_DISCONNECTED));
+                } else {
+                    resultIn.setSession(session);
+                    resultIn.readAdditionalResults(session, dataIn, rowIn);
+
+                    resultOut = session.execute(resultIn);
+                }
+            }
+
+            int type = resultIn.getType();
+
+            if (type == ResultConstants.DISCONNECT
+                    || type == ResultConstants.RESETSESSION) {
+                return;
+            }
+
+//
+            DataOutputStream dataOut =
+                new DataOutputStream(socket.getOutputStream());
+            String header = getHead(HEADER_OK, false,
+                                    "application/octet-stream", rowOut.size());
+
+            dataOut.write(header.getBytes(ENCODING));
+            dataOut.flush();
+            resultOut.write(dataOut, rowOut);
+            dataOut.close();
+        } catch (Exception e) {
+            server.printStackTrace(e);
+        }
+    }
+
+    /**
+     *  Processes an HTTP GET request
+     *
+     * @param  name the name of the content to get
+     * @param  send whether to send the content as well, or just the header
+     */
+    private void processGet(String name, boolean send) {
+
+        try {
+            String       hdr;
+            OutputStream os;
+            InputStream  is;
+            int          b;
+
+            if (name.endsWith("/")) {
+                name += server.getDefaultWebPage();
+            }
+
+            // traversing up the directory structure is forbidden.
+            if (name.indexOf("..") != -1) {
+                processError(HttpURLConnection.HTTP_FORBIDDEN);
+
+                return;
+            }
+
+            name = server.getWebRoot() + name;
+
+            if (File.separatorChar != '/') {
+                name = name.replace('/', File.separatorChar);
+            }
+
+            is = null;
+
+            server.printWithThread("GET " + name);
+
+            try {
+                File file = new File(name);
+
+                is = new DataInputStream(new FileInputStream(file));
+                hdr = getHead(HEADER_OK, true, getMimeTypeString(name),
+                              (int) file.length());
+            } catch (IOException e) {
+                processError(HttpURLConnection.HTTP_NOT_FOUND);
+
+                if (is != null) {
+                    is.close();
+                }
+
+                return;
+            }
+
+            os = new BufferedOutputStream(socket.getOutputStream());
+
+            os.write(hdr.getBytes(ENCODING));
+
+            if (send) {
+                while ((b = is.read()) != -1) {
+                    os.write(b);
+                }
+            }
+
+            os.flush();
+            os.close();
+            is.close();
+        } catch (Exception e) {
+            server.printError("processGet: " + e.toString());
+            server.printStackTrace(e);
+        }
+    }
+
+    /**
+     * Retrieves an HTTP protocol header given the supplied arguments.
+     *
+     * @param responseCodeString the HTTP response code
+     * @param addInfo true if additional header info is to be added
+     * @param mimeType the Content-Type field value
+     * @param length the Content-Length field value
+     * @return an HTTP protocol header
+     */
+    String getHead(String responseCodeString, boolean addInfo,
+                   String mimeType, int length) {
+
+        StringBuffer sb = new StringBuffer(128);
+
+        sb.append(responseCodeString).append("\r\n");
+
+        if (addInfo) {
+            sb.append("Allow: GET, HEAD, POST\nMIME-Version: 1.0\r\n");
+            sb.append("Server: ").append(
+                HsqlDatabaseProperties.PRODUCT_NAME).append("\r\n");
+        }
+
+        if (mimeType != null) {
+            sb.append("Content-Type: ").append(mimeType).append("\r\n");
+            sb.append("Content-Length: ").append(length).append("\r\n");
+        }
+
+        sb.append("\r\n");
+
+        return sb.toString();
+    }
+
+    /**
+     *  Processess an HTTP error condition, sending an error response to
+     *  the client.
+     *
+     * @param code the error condition code
+     */
+    private void processError(int code) {
+
+        String msg;
+
+        server.printWithThread("processError " + code);
+
+        switch (code) {
+
+            case HttpURLConnection.HTTP_BAD_REQUEST :
+                msg = getHead(HEADER_BAD_REQUEST, false, null, 0);
+                msg += BundleHandler.getString(WebServer.webBundleHandle,
+                                               "BAD_REQUEST");
+                break;
+
+            case HttpURLConnection.HTTP_FORBIDDEN :
+                msg = getHead(HEADER_FORBIDDEN, false, null, 0);
+                msg += BundleHandler.getString(WebServer.webBundleHandle,
+                                               "FORBIDDEN");
+                break;
+
+            case HttpURLConnection.HTTP_NOT_FOUND :
+            default :
+                msg = getHead(HEADER_NOT_FOUND, false, null, 0);
+                msg += BundleHandler.getString(WebServer.webBundleHandle,
+                                               "NOT_FOUND");
+                break;
+        }
+
+        try {
+            OutputStream os =
+                new BufferedOutputStream(socket.getOutputStream());
+
+            os.write(msg.getBytes(ENCODING));
+            os.flush();
+            os.close();
+        } catch (Exception e) {
+            server.printError("processError: " + e.toString());
+            server.printStackTrace(e);
+        }
+    }
+
+    /**
+     * Retrieves the thread name to be used  when
+     * this object is the Runnable object of a Thread.
+     *
+     * @return the thread name to be used  when
+     *      this object is the Runnable object of a Thread.
+     */
+    String getConnectionThreadName() {
+        return "HSQLDB HTTP Connection @" + Integer.toString(hashCode(), 16);
+    }
+}
diff --git a/src/org/hsqldb/server/package.html b/src/org/hsqldb/server/package.html
new file mode 100644
index 0000000..dfb4c56
--- /dev/null
+++ b/src/org/hsqldb/server/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+  The HyperSQL network listener classes.
+</BODY>
+</HTML>
diff --git a/src/org/hsqldb/store/BaseHashMap.java b/src/org/hsqldb/store/BaseHashMap.java
new file mode 100644
index 0000000..7a4f2ed
--- /dev/null
+++ b/src/org/hsqldb/store/BaseHashMap.java
@@ -0,0 +1,1555 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.store;
+
+import java.util.NoSuchElementException;
+
+import org.hsqldb.lib.ArrayCounter;
+import org.hsqldb.lib.Iterator;
+
+/**
+ * Base class for hash tables or sets. The exact type of the structure is
+ * defined by the constructor. Each instance has at least a keyTable array
+ * and a HashIndex instance for looking up the keys into this table. Instances
+ * that are maps also have a valueTable the same size as the keyTable.
+ *
+ * Special getOrAddXXX() methods are used for object maps in some subclasses.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class BaseHashMap {
+
+/*
+
+    data store:
+    keys: {array of primitive | array of object}
+    values: {none | array of primitive | array of object} same size as keys
+    objects support : hashCode(), equals()
+
+    implemented types of keyTable:
+    {objectKeyTable: variable size Object[] array for keys |
+    intKeyTable: variable size int[] for keys |
+    longKeyTable: variable size long[] for keys }
+
+    implemented types of valueTable:
+    {objectValueTable: variable size Object[] array for values |
+    intValueTable: variable size int[] for values |
+    longValueTable: variable size long[] for values}
+
+    valueTable does not exist for sets or for object pools
+
+    hash index:
+    hashTable: fixed size int[] array for hash lookup into keyTable
+    linkTable: pointer to the next key ; size equal or larger than hashTable
+    but equal to the valueTable
+
+    access count table:
+    {none |
+    variable size int[] array for access count} same size as xxxKeyTable
+*/
+
+    //
+    boolean           isIntKey;
+    boolean           isLongKey;
+    boolean           isObjectKey;
+    boolean           isNoValue;
+    boolean           isIntValue;
+    boolean           isLongValue;
+    boolean           isObjectValue;
+    protected boolean isTwoObjectValue;
+    protected boolean isList;
+
+    //
+    private ValuesIterator valuesIterator;
+
+    //
+    protected HashIndex hashIndex;
+
+    //
+    protected int[]    intKeyTable;
+    protected Object[] objectKeyTable;
+    protected long[]   longKeyTable;
+
+    //
+    protected int[]    intValueTable;
+    protected Object[] objectValueTable;
+    protected long[]   longValueTable;
+
+    //
+    protected int       accessMin;
+    protected int       accessCount;
+    protected int[]     accessTable;
+    protected boolean[] multiValueTable;
+    protected Object[]  objectValueTable2;
+
+    //
+    final float       loadFactor;
+    final int         initialCapacity;
+    int               threshold;
+    protected int     maxCapacity;
+    protected int     purgePolicy = NO_PURGE;
+    protected boolean minimizeOnEmpty;
+
+    //
+    boolean hasZeroKey;
+    int     zeroKeyIndex = -1;
+
+    // keyOrValueTypes
+    protected static final int noKeyOrValue     = 0;
+    protected static final int intKeyOrValue    = 1;
+    protected static final int longKeyOrValue   = 2;
+    protected static final int objectKeyOrValue = 3;
+
+    // purgePolicy
+    protected static final int NO_PURGE      = 0;
+    protected static final int PURGE_ALL     = 1;
+    protected static final int PURGE_HALF    = 2;
+    protected static final int PURGE_QUARTER = 3;
+
+    //
+    public final static int ACCESS_MAX = Integer.MAX_VALUE - (1 << 20);
+
+    protected BaseHashMap(int initialCapacity, int keyType, int valueType,
+                          boolean hasAccessCount)
+                          throws IllegalArgumentException {
+
+        if (initialCapacity <= 0) {
+            throw new IllegalArgumentException();
+        }
+
+        if (initialCapacity < 3) {
+            initialCapacity = 3;
+        }
+
+        this.loadFactor      = 1;    // can use any value if necessary
+        this.initialCapacity = initialCapacity;
+        threshold            = initialCapacity;
+
+        int hashtablesize = (int) (initialCapacity * loadFactor);
+
+        if (hashtablesize < 3) {
+            hashtablesize = 3;
+        }
+
+        hashIndex = new HashIndex(hashtablesize, initialCapacity, true);
+
+        int arraySize = threshold;
+
+        if (keyType == BaseHashMap.intKeyOrValue) {
+            isIntKey    = true;
+            intKeyTable = new int[arraySize];
+        } else if (keyType == BaseHashMap.objectKeyOrValue) {
+            isObjectKey    = true;
+            objectKeyTable = new Object[arraySize];
+        } else {
+            isLongKey    = true;
+            longKeyTable = new long[arraySize];
+        }
+
+        if (valueType == BaseHashMap.intKeyOrValue) {
+            isIntValue    = true;
+            intValueTable = new int[arraySize];
+        } else if (valueType == BaseHashMap.objectKeyOrValue) {
+            isObjectValue    = true;
+            objectValueTable = new Object[arraySize];
+        } else if (valueType == BaseHashMap.longKeyOrValue) {
+            isLongValue    = true;
+            longValueTable = new long[arraySize];
+        } else {
+            isNoValue = true;
+        }
+
+        if (hasAccessCount) {
+            accessTable = new int[arraySize];
+        }
+    }
+
+    protected int getLookup(Object key, int hash) {
+
+        int    lookup = hashIndex.getLookup(hash);
+        Object tempKey;
+
+        for (; lookup >= 0; lookup = hashIndex.getNextLookup(lookup)) {
+            tempKey = objectKeyTable[lookup];
+
+            if (key.equals(tempKey)) {
+                return lookup;
+            }
+        }
+
+        return lookup;
+    }
+
+    protected int getLookup(int key) {
+
+        int lookup = hashIndex.getLookup(key);
+        int tempKey;
+
+        for (; lookup >= 0; lookup = hashIndex.linkTable[lookup]) {
+            tempKey = intKeyTable[lookup];
+
+            if (key == tempKey) {
+                return lookup;
+            }
+        }
+
+        return lookup;
+    }
+
+    protected int getLookup(long key) {
+
+        int  lookup = hashIndex.getLookup((int) key);
+        long tempKey;
+
+        for (; lookup >= 0; lookup = hashIndex.getNextLookup(lookup)) {
+            tempKey = longKeyTable[lookup];
+
+            if (key == tempKey) {
+                return lookup;
+            }
+        }
+
+        return lookup;
+    }
+
+    protected Iterator getValuesIterator(Object key, int hash) {
+
+        int lookup = getLookup(key, hash);
+
+        if (valuesIterator == null) {
+            valuesIterator = new ValuesIterator();
+        }
+
+        valuesIterator.reset(key, lookup);
+
+        return valuesIterator;
+    }
+
+    /**
+     * generic method for adding or removing keys
+     */
+    protected Object addOrRemove(long longKey, long longValue,
+                                 Object objectKey, Object objectValue,
+                                 boolean remove) {
+
+        int hash = (int) longKey;
+
+        if (isObjectKey) {
+            if (objectKey == null) {
+                return null;
+            }
+
+            hash = objectKey.hashCode();
+        }
+
+        int    index       = hashIndex.getHashIndex(hash);
+        int    lookup      = hashIndex.hashTable[index];
+        int    lastLookup  = -1;
+        Object returnValue = null;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            if (isObjectKey) {
+                if (objectKeyTable[lookup].equals(objectKey)) {
+                    break;
+                }
+            } else if (isIntKey) {
+                if (longKey == intKeyTable[lookup]) {
+                    break;
+                }
+            } else if (isLongKey) {
+                if (longKey == longKeyTable[lookup]) {
+                    break;
+                }
+            }
+        }
+
+        if (lookup >= 0) {
+            if (remove) {
+                if (isObjectKey) {
+                    objectKeyTable[lookup] = null;
+                } else {
+                    if (longKey == 0) {
+                        hasZeroKey   = false;
+                        zeroKeyIndex = -1;
+                    }
+
+                    if (isIntKey) {
+                        intKeyTable[lookup] = 0;
+                    } else {
+                        longKeyTable[lookup] = 0;
+                    }
+                }
+
+                if (isObjectValue) {
+                    returnValue              = objectValueTable[lookup];
+                    objectValueTable[lookup] = null;
+                } else if (isIntValue) {
+                    intValueTable[lookup] = 0;
+                } else if (isLongValue) {
+                    longValueTable[lookup] = 0;
+                }
+
+                hashIndex.unlinkNode(index, lastLookup, lookup);
+
+                if (accessTable != null) {
+                    accessTable[lookup] = 0;
+                }
+
+                if (minimizeOnEmpty && hashIndex.elementCount == 0) {
+                    rehash(initialCapacity);
+                }
+
+                return returnValue;
+            }
+
+            if (isObjectValue) {
+                returnValue              = objectValueTable[lookup];
+                objectValueTable[lookup] = objectValue;
+            } else if (isIntValue) {
+                intValueTable[lookup] = (int) longValue;
+            } else if (isLongValue) {
+                longValueTable[lookup] = longValue;
+            }
+
+            if (accessTable != null) {
+                accessTable[lookup] = ++accessCount;
+            }
+
+            return returnValue;
+        }
+
+        // not found
+        if (remove) {
+            return null;
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+
+            // should throw maybe, if reset returns false?
+            if (reset()) {
+                return addOrRemove(longKey, longValue, objectKey, objectValue,
+                                   remove);
+            } else {
+                return null;
+            }
+        }
+
+        lookup = hashIndex.linkNode(index, lastLookup);
+
+        // type dependent block
+        if (isObjectKey) {
+            objectKeyTable[lookup] = objectKey;
+        } else if (isIntKey) {
+            intKeyTable[lookup] = (int) longKey;
+
+            if (longKey == 0) {
+                hasZeroKey   = true;
+                zeroKeyIndex = lookup;
+            }
+        } else if (isLongKey) {
+            longKeyTable[lookup] = longKey;
+
+            if (longKey == 0) {
+                hasZeroKey   = true;
+                zeroKeyIndex = lookup;
+            }
+        }
+
+        if (isObjectValue) {
+            objectValueTable[lookup] = objectValue;
+        } else if (isIntValue) {
+            intValueTable[lookup] = (int) longValue;
+        } else if (isLongValue) {
+            longValueTable[lookup] = longValue;
+        }
+
+        //
+        if (accessTable != null) {
+            accessTable[lookup] = ++accessCount;
+        }
+
+        return returnValue;
+    }
+
+    /**
+     * generic method for adding or removing key / values in multi-value
+     * maps
+     */
+    protected Object addOrRemoveMultiVal(long longKey, long longValue,
+                                         Object objectKey, Object objectValue,
+                                         boolean removeKey,
+                                         boolean removeValue) {
+
+        int hash = (int) longKey;
+
+        if (isObjectKey) {
+            if (objectKey == null) {
+                return null;
+            }
+
+            hash = objectKey.hashCode();
+        }
+
+        int     index       = hashIndex.getHashIndex(hash);
+        int     lookup      = hashIndex.hashTable[index];
+        int     lastLookup  = -1;
+        Object  returnValue = null;
+        boolean multiValue  = false;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            if (isObjectKey) {
+                if (objectKeyTable[lookup].equals(objectKey)) {
+                    if (removeKey) {
+                        while (true) {
+                            objectKeyTable[lookup]   = null;
+                            returnValue = objectValueTable[lookup];
+                            objectValueTable[lookup] = null;
+
+                            hashIndex.unlinkNode(index, lastLookup, lookup);
+
+                            multiValueTable[lookup] = false;
+                            lookup = hashIndex.hashTable[index];
+
+                            if (lookup < 0
+                                    || !objectKeyTable[lookup].equals(
+                                        objectKey)) {
+                                return returnValue;
+                            }
+                        }
+                    } else {
+                        if (objectValueTable[lookup].equals(objectValue)) {
+                            if (removeValue) {
+                                objectKeyTable[lookup]   = null;
+                                returnValue = objectValueTable[lookup];
+                                objectValueTable[lookup] = null;
+
+                                hashIndex.unlinkNode(index, lastLookup,
+                                                     lookup);
+
+                                multiValueTable[lookup] = false;
+                                lookup                  = lastLookup;
+
+                                return returnValue;
+                            } else {
+                                return objectValueTable[lookup];
+                            }
+                        }
+                    }
+
+                    multiValue = true;
+                }
+            } else if (isIntKey) {
+                if (longKey == intKeyTable[lookup]) {
+                    if (removeKey) {
+                        while (true) {
+                            if (longKey == 0) {
+                                hasZeroKey   = false;
+                                zeroKeyIndex = -1;
+                            }
+
+                            intKeyTable[lookup]   = 0;
+                            intValueTable[lookup] = 0;
+
+                            hashIndex.unlinkNode(index, lastLookup, lookup);
+
+                            multiValueTable[lookup] = false;
+                            lookup = hashIndex.hashTable[index];
+
+                            if (lookup < 0 || longKey != intKeyTable[lookup]) {
+                                return null;
+                            }
+                        }
+                    } else {
+                        if (intValueTable[lookup] == longValue) {
+                            return null;
+                        }
+                    }
+
+                    multiValue = true;
+                }
+            } else if (isLongKey) {
+                if (longKey == longKeyTable[lookup]) {
+                    if (removeKey) {
+                        while (true) {
+                            if (longKey == 0) {
+                                hasZeroKey   = false;
+                                zeroKeyIndex = -1;
+                            }
+
+                            longKeyTable[lookup]   = 0;
+                            longValueTable[lookup] = 0;
+
+                            hashIndex.unlinkNode(index, lastLookup, lookup);
+
+                            multiValueTable[lookup] = false;
+                            lookup = hashIndex.hashTable[index];
+
+                            if (lookup < 0
+                                    || longKey != longKeyTable[lookup]) {
+                                return null;
+                            }
+                        }
+                    } else {
+                        if (intValueTable[lookup] == longValue) {
+                            return null;
+                        }
+                    }
+
+                    multiValue = true;
+                }
+            }
+        }
+
+        if (removeKey || removeValue) {
+            return returnValue;
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+
+            // should throw maybe, if reset returns false?
+            if (reset()) {
+                return addOrRemoveMultiVal(longKey, longValue, objectKey,
+                                           objectValue, removeKey,
+                                           removeValue);
+            } else {
+                return null;
+            }
+        }
+
+        lookup = hashIndex.linkNode(index, lastLookup);
+
+        // type dependent block
+        if (isObjectKey) {
+            objectKeyTable[lookup] = objectKey;
+        } else if (isIntKey) {
+            intKeyTable[lookup] = (int) longKey;
+
+            if (longKey == 0) {
+                hasZeroKey   = true;
+                zeroKeyIndex = lookup;
+            }
+        } else if (isLongKey) {
+            longKeyTable[lookup] = longKey;
+
+            if (longKey == 0) {
+                hasZeroKey   = true;
+                zeroKeyIndex = lookup;
+            }
+        }
+
+        if (isObjectValue) {
+            objectValueTable[lookup] = objectValue;
+        } else if (isIntValue) {
+            intValueTable[lookup] = (int) longValue;
+        } else if (isLongValue) {
+            longValueTable[lookup] = longValue;
+        }
+
+        if (multiValue) {
+            multiValueTable[lookup] = true;
+        }
+
+        //
+        if (accessTable != null) {
+            accessTable[lookup] = ++accessCount;
+        }
+
+        return returnValue;
+    }
+
+    /**
+     * type-specific method for adding or removing keys in long or int->Object maps
+     */
+    protected Object addOrRemove(long longKey, Object objectValue,
+                                 Object objectValueTwo, boolean remove) {
+
+        int    hash        = (int) longKey;
+        int    index       = hashIndex.getHashIndex(hash);
+        int    lookup      = hashIndex.hashTable[index];
+        int    lastLookup  = -1;
+        Object returnValue = null;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            if (isIntKey) {
+                if (longKey == intKeyTable[lookup]) {
+                    break;
+                }
+            } else {
+                if (longKey == longKeyTable[lookup]) {
+                    break;
+                }
+            }
+        }
+
+        if (lookup >= 0) {
+            if (remove) {
+                if (longKey == 0) {
+                    hasZeroKey   = false;
+                    zeroKeyIndex = -1;
+                }
+
+                if (isIntKey) {
+                    intKeyTable[lookup] = 0;
+                } else {
+                    longKeyTable[lookup] = 0;
+                }
+
+                returnValue              = objectValueTable[lookup];
+                objectValueTable[lookup] = null;
+
+                hashIndex.unlinkNode(index, lastLookup, lookup);
+
+                if (isTwoObjectValue) {
+                    objectKeyTable[lookup] = null;
+                }
+
+                if (accessTable != null) {
+                    accessTable[lookup] = 0;
+                }
+
+                return returnValue;
+            }
+
+            if (isObjectValue) {
+                returnValue              = objectValueTable[lookup];
+                objectValueTable[lookup] = objectValue;
+            }
+
+            if (isTwoObjectValue) {
+                objectKeyTable[lookup] = objectValueTwo;
+            }
+
+            if (accessTable != null) {
+                accessTable[lookup] = ++accessCount;
+            }
+
+            return returnValue;
+        }
+
+        // not found
+        if (remove) {
+            return returnValue;
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+            if (reset()) {
+                return addOrRemove(longKey, objectValue, objectValueTwo,
+                                   remove);
+            } else {
+                return null;
+            }
+        }
+
+        lookup = hashIndex.linkNode(index, lastLookup);
+
+        if (isIntKey) {
+            intKeyTable[lookup] = (int) longKey;
+        } else {
+            longKeyTable[lookup] = longKey;
+        }
+
+        if (longKey == 0) {
+            hasZeroKey   = true;
+            zeroKeyIndex = lookup;
+        }
+
+        objectValueTable[lookup] = objectValue;
+
+        if (isTwoObjectValue) {
+            objectKeyTable[lookup] = objectValueTwo;
+        }
+
+        if (accessTable != null) {
+            accessTable[lookup] = ++accessCount;
+        }
+
+        return returnValue;
+    }
+
+    /**
+     * type specific method for Object sets or Object->Object maps
+     */
+    protected Object removeObject(Object objectKey, boolean removeRow) {
+
+        if (objectKey == null) {
+            return null;
+        }
+
+        int    hash        = objectKey.hashCode();
+        int    index       = hashIndex.getHashIndex(hash);
+        int    lookup      = hashIndex.hashTable[index];
+        int    lastLookup  = -1;
+        Object returnValue = null;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            if (objectKeyTable[lookup].equals(objectKey)) {
+                objectKeyTable[lookup] = null;
+
+                hashIndex.unlinkNode(index, lastLookup, lookup);
+
+                if (isObjectValue) {
+                    returnValue              = objectValueTable[lookup];
+                    objectValueTable[lookup] = null;
+                }
+
+                if (removeRow) {
+                    removeRow(lookup);
+                }
+
+                return returnValue;
+            }
+        }
+
+        // not found
+        return returnValue;
+    }
+
+    protected boolean reset() {
+
+        if (maxCapacity == 0 || maxCapacity > threshold) {
+            rehash(hashIndex.linkTable.length * 2);
+
+            return true;
+        } else if (purgePolicy == PURGE_ALL) {
+            clear();
+
+            return true;
+        } else if (purgePolicy == PURGE_QUARTER) {
+            clear(threshold / 4, threshold >> 8);
+
+            return true;
+        } else if (purgePolicy == PURGE_HALF) {
+            clear(threshold / 2, threshold >> 8);
+
+            return true;
+        } else if (purgePolicy == NO_PURGE) {
+            return false;
+        }
+
+        return false;
+    }
+
+    /**
+     * rehash uses existing key and element arrays. key / value pairs are
+     * put back into the arrays from the top, removing any gaps. any redundant
+     * key / value pairs duplicated at the end of the array are then cleared.
+     *
+     * newCapacity must be larger or equal to existing number of elements.
+     */
+    protected void rehash(int newCapacity) {
+
+        int     limitLookup     = hashIndex.newNodePointer;
+        boolean oldZeroKey      = hasZeroKey;
+        int     oldZeroKeyIndex = zeroKeyIndex;
+
+        if (newCapacity < hashIndex.elementCount) {
+            return;
+        }
+
+        hashIndex.reset((int) (newCapacity * loadFactor), newCapacity);
+
+        if (multiValueTable != null) {
+            int counter = multiValueTable.length;
+
+            while (--counter >= 0) {
+                multiValueTable[counter] = false;
+            }
+        }
+
+        hasZeroKey   = false;
+        zeroKeyIndex = -1;
+        threshold    = newCapacity;
+
+        for (int lookup = -1;
+                (lookup = nextLookup(lookup, limitLookup, oldZeroKey, oldZeroKeyIndex))
+                < limitLookup; ) {
+            long   longKey     = 0;
+            long   longValue   = 0;
+            Object objectKey   = null;
+            Object objectValue = null;
+
+            if (isObjectKey) {
+                objectKey = objectKeyTable[lookup];
+            } else if (isIntKey) {
+                longKey = intKeyTable[lookup];
+            } else {
+                longKey = longKeyTable[lookup];
+            }
+
+            if (isObjectValue) {
+                objectValue = objectValueTable[lookup];
+            } else if (isIntValue) {
+                longValue = intValueTable[lookup];
+            } else if (isLongValue) {
+                longValue = longValueTable[lookup];
+            }
+
+            if (multiValueTable == null) {
+                addOrRemove(longKey, longValue, objectKey, objectValue, false);
+            } else {
+                addOrRemoveMultiVal(longKey, longValue, objectKey,
+                                    objectValue, false, false);
+            }
+
+            if (accessTable != null) {
+                accessTable[hashIndex.elementCount - 1] = accessTable[lookup];
+            }
+        }
+
+        resizeElementArrays(hashIndex.newNodePointer, newCapacity);
+    }
+
+    /**
+     * resize the arrays contianing the key / value data
+     */
+    private void resizeElementArrays(int dataLength, int newLength) {
+
+        Object temp;
+        int    usedLength = newLength > dataLength ? dataLength
+                                                   : newLength;
+
+        if (isIntKey) {
+            temp        = intKeyTable;
+            intKeyTable = new int[newLength];
+
+            System.arraycopy(temp, 0, intKeyTable, 0, usedLength);
+        }
+
+        if (isIntValue) {
+            temp          = intValueTable;
+            intValueTable = new int[newLength];
+
+            System.arraycopy(temp, 0, intValueTable, 0, usedLength);
+        }
+
+        if (isLongKey) {
+            temp         = longKeyTable;
+            longKeyTable = new long[newLength];
+
+            System.arraycopy(temp, 0, longKeyTable, 0, usedLength);
+        }
+
+        if (isLongValue) {
+            temp           = longValueTable;
+            longValueTable = new long[newLength];
+
+            System.arraycopy(temp, 0, longValueTable, 0, usedLength);
+        }
+
+        if (objectKeyTable != null) {
+            temp           = objectKeyTable;
+            objectKeyTable = new Object[newLength];
+
+            System.arraycopy(temp, 0, objectKeyTable, 0, usedLength);
+        }
+
+        if (isObjectValue) {
+            temp             = objectValueTable;
+            objectValueTable = new Object[newLength];
+
+            System.arraycopy(temp, 0, objectValueTable, 0, usedLength);
+        }
+
+        if (objectValueTable2 != null) {
+            temp              = objectValueTable2;
+            objectValueTable2 = new Object[newLength];
+
+            System.arraycopy(temp, 0, objectValueTable2, 0, usedLength);
+        }
+
+        if (accessTable != null) {
+            temp        = accessTable;
+            accessTable = new int[newLength];
+
+            System.arraycopy(temp, 0, accessTable, 0, usedLength);
+        }
+
+        if (multiValueTable != null) {
+            temp            = multiValueTable;
+            multiValueTable = new boolean[newLength];
+
+            System.arraycopy(temp, 0, multiValueTable, 0, usedLength);
+        }
+    }
+
+    /**
+     * clear all the key / value data in a range.
+     */
+    private void clearElementArrays(final int from, final int to) {
+
+        if (isIntKey) {
+            int counter = to;
+
+            while (--counter >= from) {
+                intKeyTable[counter] = 0;
+            }
+        } else if (isLongKey) {
+            int counter = to;
+
+            while (--counter >= from) {
+                longKeyTable[counter] = 0;
+            }
+        } else if (isObjectKey || objectKeyTable != null) {
+            int counter = to;
+
+            while (--counter >= from) {
+                objectKeyTable[counter] = null;
+            }
+        }
+
+        if (isIntValue) {
+            int counter = to;
+
+            while (--counter >= from) {
+                intValueTable[counter] = 0;
+            }
+        } else if (isLongValue) {
+            int counter = to;
+
+            while (--counter >= from) {
+                longValueTable[counter] = 0;
+            }
+        } else if (isObjectValue) {
+            int counter = to;
+
+            while (--counter >= from) {
+                objectValueTable[counter] = null;
+            }
+        }
+
+        if (accessTable != null) {
+            int counter = to;
+
+            while (--counter >= from) {
+                accessTable[counter] = 0;
+            }
+        }
+
+        if (multiValueTable != null) {
+            int counter = to;
+
+            while (--counter >= from) {
+                multiValueTable[counter] = false;
+            }
+        }
+    }
+
+    /**
+     * move the elements after a removed key / value pair to fill the gap
+     */
+    void removeFromElementArrays(int lookup) {
+
+        int arrayLength = hashIndex.linkTable.length;
+
+        if (isIntKey) {
+            Object array = intKeyTable;
+
+            System.arraycopy(array, lookup + 1, array, lookup,
+                             arrayLength - lookup - 1);
+
+            intKeyTable[arrayLength - 1] = 0;
+        }
+
+        if (isLongKey) {
+            Object array = longKeyTable;
+
+            System.arraycopy(array, lookup + 1, array, lookup,
+                             arrayLength - lookup - 1);
+
+            longKeyTable[arrayLength - 1] = 0;
+        }
+
+        if (isObjectKey || objectKeyTable != null) {
+            Object array = objectKeyTable;
+
+            System.arraycopy(array, lookup + 1, array, lookup,
+                             arrayLength - lookup - 1);
+
+            objectKeyTable[arrayLength - 1] = null;
+        }
+
+        if (isIntValue) {
+            Object array = intValueTable;
+
+            System.arraycopy(array, lookup + 1, array, lookup,
+                             arrayLength - lookup - 1);
+
+            intValueTable[arrayLength - 1] = 0;
+        }
+
+        if (isLongValue) {
+            Object array = longValueTable;
+
+            System.arraycopy(array, lookup + 1, array, lookup,
+                             arrayLength - lookup - 1);
+
+            longValueTable[arrayLength - 1] = 0;
+        }
+
+        if (isObjectValue) {
+            Object array = objectValueTable;
+
+            System.arraycopy(array, lookup + 1, array, lookup,
+                             arrayLength - lookup - 1);
+
+            objectValueTable[arrayLength - 1] = null;
+        }
+    }
+
+    /**
+     * find the next lookup in the key/value tables with an entry
+     * allows the use of old limit and zero int key attributes
+     */
+    int nextLookup(int lookup, int limitLookup, boolean hasZeroKey,
+                   int zeroKeyIndex) {
+
+        for (++lookup; lookup < limitLookup; lookup++) {
+            if (isObjectKey) {
+                if (objectKeyTable[lookup] != null) {
+                    return lookup;
+                }
+            } else if (isIntKey) {
+                if (intKeyTable[lookup] != 0) {
+                    return lookup;
+                } else if (hasZeroKey && lookup == zeroKeyIndex) {
+                    return lookup;
+                }
+            } else {
+                if (longKeyTable[lookup] != 0) {
+                    return lookup;
+                } else if (hasZeroKey && lookup == zeroKeyIndex) {
+                    return lookup;
+                }
+            }
+        }
+
+        return lookup;
+    }
+
+    /**
+     * find the next lookup in the key/value tables with an entry
+     * uses current limits and zero integer key state
+     */
+    protected int nextLookup(int lookup) {
+
+        for (++lookup; lookup < hashIndex.newNodePointer; lookup++) {
+            if (isObjectKey) {
+                if (objectKeyTable[lookup] != null) {
+                    return lookup;
+                }
+            } else if (isIntKey) {
+                if (intKeyTable[lookup] != 0) {
+                    return lookup;
+                } else if (hasZeroKey && lookup == zeroKeyIndex) {
+                    return lookup;
+                }
+            } else {
+                if (longKeyTable[lookup] != 0) {
+                    return lookup;
+                } else if (hasZeroKey && lookup == zeroKeyIndex) {
+                    return lookup;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * row must already been freed of key / element
+     */
+    protected void removeRow(int lookup) {
+        hashIndex.removeEmptyNode(lookup);
+        removeFromElementArrays(lookup);
+    }
+
+    /**
+     * Clear the map completely.
+     */
+    public void clear() {
+
+        if (hashIndex.modified) {
+            accessCount  = 0;
+            accessMin    = accessCount;
+            hasZeroKey   = false;
+            zeroKeyIndex = -1;
+
+            clearElementArrays(0, hashIndex.linkTable.length);
+            hashIndex.clear();
+
+            if (minimizeOnEmpty) {
+                rehash(initialCapacity);
+            }
+        }
+    }
+
+    /**
+     * Return the max accessCount value for count elements with the lowest
+     * access count. Always return at least accessMin + 1
+     */
+    public int getAccessCountCeiling(int count, int margin) {
+        return ArrayCounter.rank(accessTable, hashIndex.newNodePointer, count,
+                                 accessMin + 1, accessCount, margin);
+    }
+
+    /**
+     * This is called after all elements below count accessCount have been
+     * removed
+     */
+    public void setAccessCountFloor(int count) {
+        accessMin = count;
+    }
+
+    public int incrementAccessCount() {
+        return ++accessCount;
+    }
+
+    /**
+     * Clear approximately count elements from the map, starting with
+     * those with low accessTable ranking.
+     *
+     * Only for maps with Object key table
+     */
+    protected void clear(int count, int margin) {
+
+        if (margin < 64) {
+            margin = 64;
+        }
+
+        int maxlookup  = hashIndex.newNodePointer;
+        int accessBase = getAccessCountCeiling(count, margin);
+
+        for (int lookup = 0; lookup < maxlookup; lookup++) {
+            Object o = objectKeyTable[lookup];
+
+            if (o != null && accessTable[lookup] < accessBase) {
+                removeObject(o, false);
+            }
+        }
+
+        accessMin = accessBase;
+    }
+
+    protected void resetAccessCount() {
+
+        if (accessCount < ACCESS_MAX) {
+            return;
+        }
+
+        if (accessMin < Integer.MAX_VALUE - (1 << 24)) {
+            accessMin = Integer.MAX_VALUE - (1 << 24);
+        }
+
+        int i = accessTable.length;
+
+        while (--i >= 0) {
+            if (accessTable[i] <= accessMin) {
+                accessTable[i] = 0;
+            } else {
+                accessTable[i] -= accessMin;
+            }
+        }
+
+        accessCount -= accessMin;
+        accessMin   = 0;
+    }
+
+    public int capacity() {
+        return hashIndex.linkTable.length;
+    }
+
+    public int size() {
+        return hashIndex.elementCount;
+    }
+
+    public boolean isEmpty() {
+        return hashIndex.elementCount == 0;
+    }
+
+    protected boolean containsKey(Object key) {
+
+        if (key == null) {
+            return false;
+        }
+
+        if (hashIndex.elementCount == 0) {
+            return false;
+        }
+
+        int lookup = getLookup(key, key.hashCode());
+
+        return lookup == -1 ? false
+                            : true;
+    }
+
+    protected boolean containsKey(int key) {
+
+        if (hashIndex.elementCount == 0) {
+            return false;
+        }
+
+        int lookup = getLookup(key);
+
+        return lookup == -1 ? false
+                            : true;
+    }
+
+    protected boolean containsKey(long key) {
+
+        if (hashIndex.elementCount == 0) {
+            return false;
+        }
+
+        int lookup = getLookup(key);
+
+        return lookup == -1 ? false
+                            : true;
+    }
+
+    protected boolean containsValue(Object value) {
+
+        int lookup = 0;
+
+        if (hashIndex.elementCount == 0) {
+            return false;
+        }
+
+        if (value == null) {
+            for (; lookup < hashIndex.newNodePointer; lookup++) {
+                if (objectValueTable[lookup] == null) {
+                    if (isObjectKey) {
+                        if (objectKeyTable[lookup] != null) {
+                            return true;
+                        }
+                    } else if (isIntKey) {
+                        if (intKeyTable[lookup] != 0) {
+                            return true;
+                        } else if (hasZeroKey && lookup == zeroKeyIndex) {
+                            return true;
+                        }
+                    } else {
+                        if (longKeyTable[lookup] != 0) {
+                            return true;
+                        } else if (hasZeroKey && lookup == zeroKeyIndex) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        } else {
+            for (; lookup < hashIndex.newNodePointer; lookup++) {
+                if (value.equals(objectValueTable[lookup])) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Currently only for object maps
+     */
+    protected class ValuesIterator implements org.hsqldb.lib.Iterator {
+
+        int    lookup = -1;
+        Object key;
+
+        private void reset(Object key, int lookup) {
+            this.key    = key;
+            this.lookup = lookup;
+        }
+
+        public boolean hasNext() {
+            return lookup != -1;
+        }
+
+        public Object next() throws NoSuchElementException {
+
+            if (lookup == -1) {
+                return null;
+            }
+
+            Object value = BaseHashMap.this.objectValueTable[lookup];
+
+            while (true) {
+                lookup = BaseHashMap.this.hashIndex.getNextLookup(lookup);
+
+                if (lookup == -1
+                        || BaseHashMap.this.objectKeyTable[lookup].equals(
+                            key)) {
+                    break;
+                }
+            }
+
+            return value;
+        }
+
+        public int nextInt() throws NoSuchElementException {
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public long nextLong() throws NoSuchElementException {
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public void remove() throws NoSuchElementException {
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public void setValue(Object value) {
+            throw new NoSuchElementException("Hash Iterator");
+        }
+    }
+
+    protected class MultiValueKeyIterator implements Iterator {
+
+        boolean keys;
+        int     lookup = -1;
+        int     counter;
+        boolean removed;
+
+        public MultiValueKeyIterator() {
+            toNextLookup();
+        }
+
+        private void toNextLookup() {
+
+            while (true) {
+                lookup = nextLookup(lookup);
+
+                if (lookup == -1 || !multiValueTable[lookup]) {
+                    break;
+                }
+            }
+        }
+
+        public boolean hasNext() {
+            return lookup != -1;
+        }
+
+        public Object next() throws NoSuchElementException {
+
+            Object value = objectKeyTable[lookup];
+
+            toNextLookup();
+
+            return value;
+        }
+
+        public int nextInt() throws NoSuchElementException {
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public long nextLong() throws NoSuchElementException {
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public void remove() throws NoSuchElementException {
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public void setValue(Object value) {
+            throw new NoSuchElementException("Hash Iterator");
+        }
+    }
+
+    /**
+     * Iterator returns Object, int or long and is used both for keys and
+     * values
+     */
+    protected class BaseHashIterator implements Iterator {
+
+        boolean keys;
+        int     lookup = -1;
+        int     counter;
+        boolean removed;
+
+        /**
+         * default is iterator for values
+         */
+        public BaseHashIterator() {}
+
+        public BaseHashIterator(boolean keys) {
+            this.keys = keys;
+        }
+
+        public boolean hasNext() {
+            return counter < hashIndex.elementCount;
+        }
+
+        public Object next() throws NoSuchElementException {
+
+            if ((keys && !isObjectKey) || (!keys && !isObjectValue)) {
+                throw new NoSuchElementException("Hash Iterator");
+            }
+
+            removed = false;
+
+            if (hasNext()) {
+                counter++;
+
+                lookup = nextLookup(lookup);
+
+                if (keys) {
+                    return objectKeyTable[lookup];
+                } else {
+                    return objectValueTable[lookup];
+                }
+            }
+
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public int nextInt() throws NoSuchElementException {
+
+            if ((keys && !isIntKey) || (!keys && !isIntValue)) {
+                throw new NoSuchElementException("Hash Iterator");
+            }
+
+            removed = false;
+
+            if (hasNext()) {
+                counter++;
+
+                lookup = nextLookup(lookup);
+
+                if (keys) {
+                    return intKeyTable[lookup];
+                } else {
+                    return intValueTable[lookup];
+                }
+            }
+
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public long nextLong() throws NoSuchElementException {
+
+            if ((!isLongKey || !keys)) {
+                throw new NoSuchElementException("Hash Iterator");
+            }
+
+            removed = false;
+
+            if (hasNext()) {
+                counter++;
+
+                lookup = nextLookup(lookup);
+
+                if (keys) {
+                    return longKeyTable[lookup];
+                } else {
+                    return longValueTable[lookup];
+                }
+            }
+
+            throw new NoSuchElementException("Hash Iterator");
+        }
+
+        public void remove() throws NoSuchElementException {
+
+            if (removed) {
+                throw new NoSuchElementException("Hash Iterator");
+            }
+
+            counter--;
+
+            removed = true;
+
+            if (BaseHashMap.this.isObjectKey) {
+                if (multiValueTable == null) {
+                    addOrRemove(0, 0, objectKeyTable[lookup], null, true);
+                } else {
+                    if (keys) {
+                        addOrRemoveMultiVal(0, 0, objectKeyTable[lookup],
+                                            null, true, false);
+                    } else {
+                        addOrRemoveMultiVal(0, 0, objectKeyTable[lookup],
+                                            objectValueTable[lookup], false,
+                                            true);
+                    }
+                }
+            } else if (isIntKey) {
+                addOrRemove(intKeyTable[lookup], 0, null, null, true);
+            } else {
+                addOrRemove(longKeyTable[lookup], 0, null, null, true);
+            }
+
+            if (isList) {
+                removeRow(lookup);
+                lookup--;
+            }
+        }
+
+        public void setValue(Object value) {
+
+            if (keys) {
+                throw new NoSuchElementException();
+            }
+
+            objectValueTable[lookup] = value;
+        }
+
+        public int getAccessCount() {
+
+            if (removed || accessTable == null) {
+                throw new NoSuchElementException();
+            }
+
+            return accessTable[lookup];
+        }
+
+        public void setAccessCount(int count) {
+
+            if (removed || accessTable == null) {
+                throw new NoSuchElementException();
+            }
+
+            accessTable[lookup] = count;
+        }
+
+        public int getLookup() {
+            return lookup;
+        }
+    }
+}
diff --git a/src/org/hsqldb/store/BitMap.java b/src/org/hsqldb/store/BitMap.java
new file mode 100644
index 0000000..1d634ef
--- /dev/null
+++ b/src/org/hsqldb/store/BitMap.java
@@ -0,0 +1,556 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.store;
+
+/**
+ * Implementation of a bit map of any size, together with static methods to
+ * manipulate int, byte and byte[] values as bit maps.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.8.0
+*/
+public class BitMap {
+
+    int   defaultCapacity;
+    int   capacity;
+    int[] map;
+    int   limitPos;
+
+    public BitMap(int initialCapacity) {
+
+        int words = initialCapacity / 32;
+
+        if (initialCapacity % 32 != 0) {
+            words++;
+        }
+
+        defaultCapacity = capacity = words * 32;
+        map             = new int[words];
+        limitPos        = 0;
+    }
+
+    public int size() {
+        return limitPos;
+    }
+
+    public void setSize(int size) {
+        limitPos = size;
+    }
+
+    /**
+     * Resets to blank with original capacity
+     */
+    public void reset() {
+
+        map      = new int[defaultCapacity / 32];
+        capacity = defaultCapacity;
+        limitPos = 0;
+    }
+
+    /**
+     * Sets pos and returns old value
+     */
+    public int set(int pos) {
+
+        while (pos >= capacity) {
+            doubleCapacity();
+        }
+
+        if (pos >= limitPos) {
+            limitPos = pos + 1;
+        }
+
+        int windex = pos >> 5;
+        int mask   = 0x80000000 >>> (pos & 0x1F);
+        int word   = map[windex];
+        int result = (word & mask) == 0 ? 0
+                                        : 1;
+
+        map[windex] = (word | mask);
+
+        return result;
+    }
+
+    /**
+     * Unsets pos and returns old value
+     */
+    public int unset(int pos) {
+
+        while (pos >= capacity) {
+            doubleCapacity();
+        }
+
+        if (pos >= limitPos) {
+            limitPos = pos + 1;
+
+            return 0;
+        }
+
+        int windex = pos >> 5;
+        int mask   = 0x80000000 >>> (pos & 0x1F);
+        int word   = map[windex];
+        int result = (word & mask) == 0 ? 0
+                                        : 1;
+
+        mask        = ~mask;
+        map[windex] = (word & mask);
+
+        return result;
+    }
+
+    public int get(int pos) {
+
+        while (pos >= capacity) {
+            doubleCapacity();
+        }
+
+        if (pos >= limitPos) {
+            limitPos = pos + 1;
+
+            return 0;
+        }
+
+        int windex = pos >> 5;
+        int mask   = 0x80000000 >>> (pos & 0x1F);
+        int word   = map[windex];
+
+        return (word & mask) == 0 ? 0
+                                  : 1;
+    }
+
+    public boolean isSet(int pos) {
+        return get(pos) == 1;
+    }
+
+    public byte[] getBytes() {
+
+        byte[] buf = new byte[(limitPos + 7) / 8];
+
+        if (buf.length == 0) {
+            return buf;
+        }
+
+        for (int i = 0; ; ) {
+            int v = map[i / 4];
+
+            buf[i++] = (byte) (v >>> 24);
+
+            if (i == buf.length) {
+                break;
+            }
+
+            buf[i++] = (byte) (v >>> 16);
+
+            if (i == buf.length) {
+                break;
+            }
+
+            buf[i++] = (byte) (v >>> 8);
+
+            if (i == buf.length) {
+                break;
+            }
+
+            buf[i++] = (byte) v;
+
+            if (i == buf.length) {
+                break;
+            }
+        }
+
+        return buf;
+    }
+
+    private void doubleCapacity() {
+
+        int[] newmap = new int[map.length * 2];
+
+        capacity *= 2;
+
+        System.arraycopy(map, 0, newmap, 0, map.length);
+
+        map = newmap;
+    }
+
+    /**
+     * copy the byte value into the map at given position (0, 24)
+     */
+    public static int setByte(int map, byte value, int pos) {
+
+        int intValue = (value & 0xff) << (24 - pos);
+        int mask     = 0xff000000 >>> pos;
+
+        mask = ~mask;
+        map  &= mask;
+
+        return (map | intValue);
+    }
+
+    public static int set(int map, int pos) {
+
+        int mask = 0x80000000 >>> pos;
+
+        return (map | mask);
+    }
+
+    public static byte set(byte map, int pos) {
+
+        int mask = 0x00000080 >>> pos;
+
+        return (byte) (map | mask);
+    }
+
+    public static int unset(int map, int pos) {
+
+        int mask = 0x80000000 >>> pos;
+
+        mask = ~mask;
+
+        return (map & mask);
+    }
+
+    public static boolean isSet(int map, int pos) {
+
+        int mask = 0x80000000 >>> pos;
+
+        return (map & mask) == 0 ? false
+                                 : true;
+    }
+
+    public static boolean isSet(byte map, int pos) {
+
+        int mask = 0x00000080 >>> pos;
+
+        return (map & mask) == 0 ? false
+                                 : true;
+    }
+
+    public static boolean isSet(byte[] map, int pos) {
+
+        int mask  = 0x00000080 >>> (pos & 0x07);;
+        int index = pos / 8;
+
+        if (index >= map.length) {
+            return false;
+        }
+
+        byte b = map[index];
+
+        return (b & mask) == 0 ? false
+                               : true;
+    }
+
+    public static void unset(byte[] map, int pos) {
+
+        int mask = 0x00000080 >>> (pos & 0x07);
+
+        mask = ~mask;
+
+        int index = pos / 8;
+
+        if (index >= map.length) {
+            return;
+        }
+
+        byte b = map[index];
+
+        map[index] = (byte) (b & mask);
+    }
+
+    public static void set(byte[] map, int pos) {
+
+        int mask  = 0x00000080 >>> (pos & 0x07);
+        int index = pos / 8;
+
+        if (index >= map.length) {
+            return;
+        }
+
+        byte b = map[index];
+
+        map[index] = (byte) (b | mask);
+    }
+
+    /**
+     * AND count bits from source with map contents starting at pos
+     */
+    public static void and(byte[] map, int pos, byte source, int count) {
+
+        int shift     = pos & 0x07;
+        int mask      = (source & 0xff) >>> shift;
+        int innermask = 0xff >> shift;
+        int index     = pos / 8;
+
+        if (count < 8) {
+            innermask = innermask >>> (8 - count);
+            innermask = innermask << (8 - count);
+        }
+
+        mask      &= innermask;
+        innermask = ~innermask;
+
+        if (index >= map.length) {
+            return;
+        }
+
+        byte b = map[index];
+
+        map[index] = (byte) (b & innermask);
+        b          = (byte) (b & mask);
+        map[index] = (byte) (map[index] | b);
+
+        if (shift == 0) {
+            return;
+        }
+
+        shift = 8 - shift;
+
+        if (count > shift) {
+            mask           = ((source & 0xff) << 8) >>> shift;
+            innermask      = 0xff00 >>> shift;
+            innermask      = ~innermask;
+            b              = map[index + 1];
+            map[index + 1] = (byte) (b & innermask);
+            b              = (byte) (b & mask);
+            map[index + 1] = (byte) (map[index + 1] | b);
+        }
+    }
+
+    /**
+     * OR count bits from source with map contents starting at pos
+     */
+    public static void or(byte[] map, int pos, byte source, int count) {
+
+        int shift = pos & 0x07;
+        int mask  = (source & 0xff) >>> shift;
+        int index = pos / 8;
+
+        if (index >= map.length) {
+            return;
+        }
+
+        byte b = (byte) (map[index] | mask);
+
+        map[index] = b;
+
+        if (shift == 0) {
+            return;
+        }
+
+        shift = 8 - shift;
+
+        if (count > shift) {
+            mask           = ((source & 0xff) << 8) >>> shift;
+            b              = (byte) (map[index + 1] | mask);
+            map[index + 1] = b;
+        }
+    }
+
+    /**
+     * overlay count bits from source on map contents starting at pos
+     */
+    public static void overlay(byte[] map, int pos, byte source, int count) {
+
+        int shift     = pos & 0x07;
+        int mask      = (source & 0xff) >>> shift;
+        int innermask = 0xff >> shift;
+        int index     = pos / 8;
+
+        if (count < 8) {
+            innermask = innermask >>> (8 - count);
+            innermask = innermask << (8 - count);
+        }
+
+        mask      &= innermask;
+        innermask = ~innermask;
+
+        if (index >= map.length) {
+            return;
+        }
+
+        byte b = map[index];
+
+        b          = (byte) (b & innermask);
+        map[index] = (byte) (b | mask);
+
+        if (shift == 0) {
+            return;
+        }
+
+        shift = 8 - shift;
+
+        if (count > shift) {
+            mask           = ((source & 0xff) << 8) >>> shift;
+            innermask      = 0xff00 >>> shift;
+            innermask      = ~innermask;
+            b              = map[index + 1];
+            b              = (byte) (b & innermask);
+            map[index + 1] = (byte) (b | mask);
+        }
+    }
+
+    public static int compare(byte[] a, byte[] b) {
+
+        int shortLength = a.length > b.length ? b.length
+                                              : a.length;
+
+        for (int i = 0; i < shortLength; i++) {
+            if (a[i] == b[i]) {
+                continue;
+            }
+
+            return (((int) a[i]) & 0xff) > (((int) b[i]) & 0xff) ? 1
+                                                                 : -1;
+        }
+
+        if (a.length == b.length) {
+            return 0;
+        }
+
+        return a.length > b.length ? 1
+                                   : -1;
+    }
+
+    public static byte[] and(byte[] a, byte[] b) {
+
+        int    length      = a.length > b.length ? a.length
+                                                 : b.length;
+        int    shortLength = a.length > b.length ? b.length
+                                                 : a.length;
+        byte[] map         = new byte[length];
+
+        for (int i = 0; i < shortLength; i++) {
+            map[i] = (byte) (a[i] & b[i]);
+        }
+
+        return map;
+    }
+
+    public static byte[] or(byte[] a, byte[] b) {
+
+        int    length      = a.length > b.length ? a.length
+                                                 : b.length;
+        int    shortLength = a.length > b.length ? b.length
+                                                 : a.length;
+        byte[] map         = new byte[length];
+
+        if (length != shortLength) {
+            byte[] source = a.length > b.length ? a
+                                                : b;
+
+            System.arraycopy(source, shortLength, map, shortLength,
+                             length - shortLength);
+        }
+
+        for (int i = 0; i < shortLength; i++) {
+            map[i] = (byte) (a[i] | b[i]);
+        }
+
+        return map;
+    }
+
+    public static byte[] xor(byte[] a, byte[] b) {
+
+        int    length      = a.length > b.length ? a.length
+                                                 : b.length;
+        int    shortLength = a.length > b.length ? b.length
+                                                 : a.length;
+        byte[] map         = new byte[length];
+
+        if (length != shortLength) {
+            byte[] source = a.length > b.length ? a
+                                                : b;
+
+            System.arraycopy(source, shortLength, map, shortLength,
+                             length - shortLength);
+        }
+
+        for (int i = 0; i < shortLength; i++) {
+            map[i] = (byte) (a[i] ^ b[i]);
+        }
+
+        return map;
+    }
+
+    public static byte[] not(byte[] a) {
+
+        byte[] map = new byte[a.length];
+
+        for (int i = 0; i < a.length; i++) {
+            map[i] = (byte) ~a[i];
+        }
+
+        return map;
+    }
+
+    public static boolean hasAnyBitSet(byte[] map) {
+
+        for (int i = 0; i < map.length; i++) {
+            if (map[i] != 0) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public static byte[] leftShift(byte[] map, int shiftBits) {
+
+        byte[] newMap     = new byte[map.length];
+        int    shiftBytes = shiftBits / 8;
+
+        if (shiftBytes >= map.length) {
+            return newMap;
+        }
+
+        shiftBits = shiftBits % 8;
+
+        if (shiftBits == 0) {
+            for (int i = 0, j = shiftBytes; j < map.length; i++, j++) {
+                newMap[i] = map[j];
+            }
+        } else {
+            for (int i = 0, j = shiftBytes; j < map.length; i++, j++) {
+                int shifted = (map[j] & 0xff) << shiftBits;
+
+                newMap[i] = (byte) shifted;
+
+                if (i > 0) {
+                    newMap[i - 1] |= (byte) (shifted >>> 8);
+                }
+            }
+        }
+
+        return newMap;
+    }
+}
diff --git a/src/org/hsqldb/store/HashIndex.java b/src/org/hsqldb/store/HashIndex.java
new file mode 100644
index 0000000..3976120
--- /dev/null
+++ b/src/org/hsqldb/store/HashIndex.java
@@ -0,0 +1,272 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.store;
+
+/**
+ * A chained bucket hash index implementation.
+ *
+ * hashTable and linkTable are arrays of signed integral types. This
+ * implementation uses int as the type but short or byte can be used for
+ * smaller index sizes (cardinality).
+ *
+ * hashTable[index] contains the pointer to the first node with
+ * (index == hash modulo hashTable.length) or -1 if there is no corresponding
+ * node. linkTable[{0,newNodePointer}] (the range between 0 and newNodePointer)
+ * contains either the pointer to the next node or -1 if there is no
+ * such node. reclaimedNodeIndex contains a pointer to an element
+ * of linkTable which is the first element in the list of reclaimed nodes
+ * (nodes no longer in index) or -1 if there is no such node.
+ *
+ * elemenet at and above linkTable[newNodePointer] have never been used
+ * as a node and their contents is not significant.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+class HashIndex {
+
+    int[]   hashTable;
+    int[]   linkTable;
+    int     newNodePointer;
+    int     elementCount;
+    int     reclaimedNodePointer = -1;
+    boolean fixedSize;
+    boolean modified;
+
+    HashIndex(int hashTableSize, int capacity, boolean fixedSize) {
+
+        if (capacity < hashTableSize) {
+            capacity = hashTableSize;
+        }
+
+        reset(hashTableSize, capacity);
+
+        this.fixedSize = fixedSize;
+    }
+
+    /**
+     * Reset the structure with a new size as empty.
+     *
+     * @param hashTableSize
+     * @param capacity
+     */
+    void reset(int hashTableSize, int capacity) {
+
+        int[] newHT = new int[hashTableSize];
+        int[] newLT = new int[capacity];
+
+        // allocate memory before assigning
+        hashTable = newHT;
+        linkTable = newLT;
+
+        resetTables();
+    }
+
+    void resetTables() {
+
+        int   to       = hashTable.length;
+        int[] intArray = hashTable;
+
+        while (--to >= 0) {
+            intArray[to] = -1;
+        }
+
+        newNodePointer       = 0;
+        elementCount         = 0;
+        reclaimedNodePointer = -1;
+        modified             = false;
+    }
+
+    /**
+     * Reset the index as empty.
+     */
+    void clear() {
+
+        int   to       = linkTable.length;
+        int[] intArray = linkTable;
+
+        while (--to >= 0) {
+            intArray[to] = 0;
+        }
+
+        resetTables();
+    }
+
+    /**
+     * @param hash
+     */
+    int getHashIndex(int hash) {
+        return (hash & 0x7fffffff) % hashTable.length;
+    }
+
+    /**
+     * Return the array index for a hash.
+     *
+     * @param hash the hash value used for indexing
+     * @return either -1 or the first node for this hash value
+     */
+    int getLookup(int hash) {
+
+        if (elementCount == 0) {
+            return -1;
+        }
+
+        int index = (hash & 0x7fffffff) % hashTable.length;
+
+        return hashTable[index];
+    }
+
+    /**
+     * This looks from a given node, so the parameter is always > -1.
+     *
+     * @param lookup A valid node to look from
+     * @return either -1 or the next node from this node
+     */
+    int getNextLookup(int lookup) {
+        return linkTable[lookup];
+    }
+
+    /**
+     * Link a new node to the end of the linked for a hash index.
+     *
+     * @param index an index into hashTable
+     * @param lastLookup either -1 or the node to which the new node will be linked
+     * @return the new node
+     */
+    int linkNode(int index, int lastLookup) {
+
+        // get the first reclaimed slot
+        int lookup = reclaimedNodePointer;
+
+        if (lookup == -1) {
+            lookup = newNodePointer++;
+        } else {
+
+            // reset the first reclaimed slot
+            reclaimedNodePointer = linkTable[lookup];
+        }
+
+        // link the node
+        if (lastLookup == -1) {
+            hashTable[index] = lookup;
+        } else {
+            linkTable[lastLookup] = lookup;
+        }
+
+        linkTable[lookup] = -1;
+
+        elementCount++;
+
+        modified = true;
+
+        return lookup;
+    }
+
+    /**
+     * Unlink a node from a linked list and link into the reclaimed list.
+     *
+     * @param index an index into hashTable
+     * @param lastLookup either -1 or the node to which the target node is linked
+     * @param lookup the node to remove
+     */
+    void unlinkNode(int index, int lastLookup, int lookup) {
+
+        // unlink the node
+        if (lastLookup == -1) {
+            hashTable[index] = linkTable[lookup];
+        } else {
+            linkTable[lastLookup] = linkTable[lookup];
+        }
+
+        // add to reclaimed list
+        linkTable[lookup]    = reclaimedNodePointer;
+        reclaimedNodePointer = lookup;
+
+        elementCount--;
+    }
+
+    /**
+     * Remove a node that has already been unlinked. This is not required
+     * for index operations. It is used only when the row needs to be removed
+     * from the data structures that store the actual indexed data and the
+     * nodes need to be contiguous.
+     *
+     * @param lookup the node to remove
+     * @return true if node found in unlinked state
+     */
+    boolean removeEmptyNode(int lookup) {
+
+        boolean found      = false;
+        int     lastLookup = -1;
+
+        for (int i = reclaimedNodePointer; i >= 0;
+                lastLookup = i, i = linkTable[i]) {
+            if (i == lookup) {
+                if (lastLookup == -1) {
+                    reclaimedNodePointer = linkTable[lookup];
+                } else {
+                    linkTable[lastLookup] = linkTable[lookup];
+                }
+
+                found = true;
+
+                break;
+            }
+        }
+
+        if (!found) {
+            return false;
+        }
+
+        for (int i = 0; i < newNodePointer; i++) {
+            if (linkTable[i] > lookup) {
+                linkTable[i]--;
+            }
+        }
+
+        System.arraycopy(linkTable, lookup + 1, linkTable, lookup,
+                         newNodePointer - lookup - 1);
+
+        linkTable[newNodePointer - 1] = 0;
+
+        newNodePointer--;
+
+        for (int i = 0; i < hashTable.length; i++) {
+            if (hashTable[i] > lookup) {
+                hashTable[i]--;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/store/ObjectCacheHashMap.java b/src/org/hsqldb/store/ObjectCacheHashMap.java
new file mode 100644
index 0000000..9e27f85
--- /dev/null
+++ b/src/org/hsqldb/store/ObjectCacheHashMap.java
@@ -0,0 +1,108 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.store;
+
+import org.hsqldb.lib.Collection;
+import org.hsqldb.lib.Iterator;
+import org.hsqldb.lib.Set;
+
+/**
+ * Maps integer keys to Objects. Hashes the keys.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.8.0
+ */
+public final class ObjectCacheHashMap extends BaseHashMap {
+
+    Set        keySet;
+    Collection values;
+
+    public ObjectCacheHashMap(int initialCapacity)
+    throws IllegalArgumentException {
+        super(initialCapacity, BaseHashMap.intKeyOrValue,
+              BaseHashMap.objectKeyOrValue, true);
+    }
+
+    public Object get(int key) {
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        int lookup = getLookup(key);
+
+        if (lookup == -1) {
+            return null;
+        }
+
+        accessTable[lookup] = accessCount++;
+
+        return objectValueTable[lookup];
+    }
+
+    public Object put(int key, Object value) {
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        return super.addOrRemove(key, value, null, false);
+    }
+
+    public Object remove(int key) {
+        return super.addOrRemove(key, null, null, true);
+    }
+
+    /**
+     * for count number of elements with the given margin, return the access
+     * count.
+     */
+    public int getAccessCountCeiling(int count, int margin) {
+        return super.getAccessCountCeiling(count, margin);
+    }
+
+    /**
+     * This is called after all elements below count accessCount have been
+     * removed
+     */
+    public void setAccessCountFloor(int count) {
+        super.accessMin = count;
+    }
+
+    public ObjectCacheIterator iterator() {
+        return new ObjectCacheIterator();
+    }
+
+    public final class ObjectCacheIterator extends BaseHashIterator
+    implements Iterator {}
+}
diff --git a/src/org/hsqldb/store/ReusableObjectCache.java b/src/org/hsqldb/store/ReusableObjectCache.java
new file mode 100644
index 0000000..a8bd45b
--- /dev/null
+++ b/src/org/hsqldb/store/ReusableObjectCache.java
@@ -0,0 +1,61 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.store;
+
+import org.hsqldb.lib.HashMappedList;
+import org.hsqldb.lib.HashSet;
+
+public class ReusableObjectCache {
+
+    public ReusableObjectCache() {
+
+        try {
+            jbInit();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    public static HashMappedList getHashMappedList() {
+        return new HashMappedList();
+    }
+
+    public static void putHashMappedList(HashMappedList object) {}
+
+    public static HashSet getHashSet() {
+        return new HashSet();
+    }
+
+    public static void putHashSet(HashSet object) {}
+
+    private void jbInit() throws Exception {}
+}
diff --git a/src/org/hsqldb/store/ValuePool.java b/src/org/hsqldb/store/ValuePool.java
new file mode 100644
index 0000000..0e3e95d
--- /dev/null
+++ b/src/org/hsqldb/store/ValuePool.java
@@ -0,0 +1,223 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.store;
+
+import java.math.BigDecimal;
+
+import org.hsqldb.types.TimestampData;
+
+/**
+  * Supports pooling of Integer, Long, Double, BigDecimal, String and Date
+  * Java Objects. Leads to reduction in memory use when an Object is used more
+  * then twice in the database.
+  *
+  * getXXX methods are used for retrival of values. If a value is not in
+  * the pool, it is added to the pool and returned. When the pool gets
+  * full, half the contents that have been accessed less recently are purged.
+  *
+  * @author Fred Toussi (fredt@users dot sourceforge.net)
+  * @version 1.9.0
+  * @since 1.7.2
+  */
+public class ValuePool {
+
+    //
+    static ValuePoolHashMap intPool;
+    static ValuePoolHashMap longPool;
+    static ValuePoolHashMap doublePool;
+    static ValuePoolHashMap bigdecimalPool;
+    static ValuePoolHashMap stringPool;
+    static ValuePoolHashMap datePool;
+    static final int        SPACE_STRING_SIZE       = 50;
+    static final int        DEFAULT_VALUE_POOL_SIZE = 8192;
+    static final int[]      defaultPoolLookupSize   = new int[] {
+        DEFAULT_VALUE_POOL_SIZE, DEFAULT_VALUE_POOL_SIZE,
+        DEFAULT_VALUE_POOL_SIZE, DEFAULT_VALUE_POOL_SIZE,
+        DEFAULT_VALUE_POOL_SIZE, DEFAULT_VALUE_POOL_SIZE
+    };
+    static final int POOLS_COUNT            = defaultPoolLookupSize.length;
+    static final int defaultSizeFactor      = 2;
+    static final int defaultMaxStringLength = 16;
+
+    //
+    static ValuePoolHashMap[] poolList;
+
+    //
+    static int maxStringLength;
+
+    //
+    static {
+        initPool();
+    }
+
+    public static final Integer INTEGER_0 = ValuePool.getInt(0);
+    public static final Integer INTEGER_1 = ValuePool.getInt(1);
+    public static final Integer INTEGER_2 = ValuePool.getInt(2);
+    public static final Integer INTEGER_MAX =
+        ValuePool.getInt(Integer.MAX_VALUE);
+    public static final BigDecimal BIG_DECIMAL_0 =
+        ValuePool.getBigDecimal(new BigDecimal(0.0));
+    public static final BigDecimal BIG_DECIMAL_1 =
+        ValuePool.getBigDecimal(new BigDecimal(1.0));
+
+    //
+    public final static String[] emptyStringArray = new String[]{};
+    public final static Object[] emptyObjectArray = new Object[]{};
+    public final static int[]    emptyIntArray    = new int[]{};
+    public static String         spaceString;
+
+    //
+    private static void initPool() {
+
+        int[] sizeArray  = defaultPoolLookupSize;
+        int   sizeFactor = defaultSizeFactor;
+
+        synchronized (ValuePool.class) {
+            maxStringLength = defaultMaxStringLength;
+            poolList        = new ValuePoolHashMap[POOLS_COUNT];
+
+            for (int i = 0; i < POOLS_COUNT; i++) {
+                int size = sizeArray[i];
+
+                poolList[i] = new ValuePoolHashMap(size, size * sizeFactor,
+                                                   BaseHashMap.PURGE_HALF);
+            }
+
+            intPool        = poolList[0];
+            longPool       = poolList[1];
+            doublePool     = poolList[2];
+            bigdecimalPool = poolList[3];
+            stringPool     = poolList[4];
+            datePool       = poolList[5];
+
+            char[] c = new char[SPACE_STRING_SIZE];
+
+            for (int i = 0; i < SPACE_STRING_SIZE; i++) {
+                c[i] = ' ';
+            }
+
+            spaceString = new String(c);
+        }
+    }
+
+    public static int getMaxStringLength() {
+        return maxStringLength;
+    }
+
+    public static void resetPool(int[] sizeArray, int sizeFactor) {
+
+        synchronized (ValuePool.class) {
+            for (int i = 0; i < POOLS_COUNT; i++) {
+                poolList[i].resetCapacity(sizeArray[i] * sizeFactor,
+                                          BaseHashMap.PURGE_HALF);
+            }
+        }
+    }
+
+    public static void resetPool() {
+
+        synchronized (ValuePool.class) {
+            resetPool(defaultPoolLookupSize, defaultSizeFactor);
+        }
+    }
+
+    public static void clearPool() {
+
+        synchronized (ValuePool.class) {
+            for (int i = 0; i < POOLS_COUNT; i++) {
+                poolList[i].clear();
+            }
+        }
+    }
+
+    public static Integer getInt(int val) {
+
+        synchronized (intPool) {
+            return intPool.getOrAddInteger(val);
+        }
+    }
+
+    public static Long getLong(long val) {
+
+        synchronized (longPool) {
+            return longPool.getOrAddLong(val);
+        }
+    }
+
+    public static Double getDouble(long val) {
+
+        synchronized (doublePool) {
+            return doublePool.getOrAddDouble(val);
+        }
+    }
+
+    public static String getString(String val) {
+
+        if (val == null || val.length() > maxStringLength) {
+            return val;
+        }
+
+        synchronized (stringPool) {
+            return stringPool.getOrAddString(val);
+        }
+    }
+
+    public static String getSubString(String val, int start, int limit) {
+
+        synchronized (stringPool) {
+            return stringPool.getOrAddString(val.substring(start, limit));
+        }
+    }
+
+    public static TimestampData getDate(long val) {
+
+        synchronized (datePool) {
+            return datePool.getOrAddDate(val);
+        }
+    }
+
+    public static BigDecimal getBigDecimal(BigDecimal val) {
+
+        if (val == null) {
+            return val;
+        }
+
+        synchronized (bigdecimalPool) {
+            return (BigDecimal) bigdecimalPool.getOrAddObject(val);
+        }
+    }
+
+    public static Boolean getBoolean(boolean b) {
+        return b ? Boolean.TRUE
+                 : Boolean.FALSE;
+    }
+}
diff --git a/src/org/hsqldb/store/ValuePoolHashMap.java b/src/org/hsqldb/store/ValuePoolHashMap.java
new file mode 100644
index 0000000..c2c493e
--- /dev/null
+++ b/src/org/hsqldb/store/ValuePoolHashMap.java
@@ -0,0 +1,414 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.store;
+
+import org.hsqldb.types.TimestampData;
+
+/*
+ * implementation notes:
+ *
+ * NB: As of this version this class cannot be used for mixed object types
+ * It is relativly easy to support this by adding an 'instanceof' test inside
+ * each getOrAddXxxx method before casting the Set values to the target type
+ * for comparison purposes.
+ *
+ * superclass is used as an Object Set
+ * getOrAddXxxx methods are implemented directly for speed
+ * the superclass infrastructure is otherwise used
+ */
+
+/**
+ * Subclass of BaseHashMap for maintaining a pool of objects. Supports a
+ * range of java.lang.* objects.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ *
+ */
+public class ValuePoolHashMap extends BaseHashMap {
+
+    public ValuePoolHashMap(int initialCapacity, int maxCapacity,
+                            int purgePolicy) throws IllegalArgumentException {
+
+        super(initialCapacity, BaseHashMap.objectKeyOrValue, BaseHashMap.noKeyOrValue,
+              true);
+
+        this.maxCapacity = maxCapacity;
+        this.purgePolicy = purgePolicy;
+    }
+
+    /**
+     * In rare circumstances resetCapacity may not succeed, in which case
+     * capacity remains unchanged but purge policy is set to newPolicy
+     */
+    public void resetCapacity(int newCapacity,
+                              int newPolicy) throws IllegalArgumentException {
+
+        if (newCapacity != 0 && hashIndex.elementCount > newCapacity) {
+            int surplus = hashIndex.elementCount - newCapacity;
+
+            surplus += (surplus >> 5);
+
+            if (surplus > hashIndex.elementCount) {
+                surplus = hashIndex.elementCount;
+            }
+
+            clear(surplus, (surplus >> 6));
+        }
+
+        if (newCapacity != 0 && newCapacity < threshold) {
+            rehash(newCapacity);
+
+            if (newCapacity < hashIndex.elementCount) {
+                newCapacity = maxCapacity;
+            }
+        }
+
+        this.maxCapacity = newCapacity;
+        this.purgePolicy = newPolicy;
+    }
+
+    protected Integer getOrAddInteger(int intKey) {
+
+        Integer testValue;
+        int     index      = hashIndex.getHashIndex(intKey);
+        int     lookup     = hashIndex.hashTable[index];
+        int     lastLookup = -1;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            testValue = (Integer) objectKeyTable[lookup];
+
+            if (testValue.intValue() == intKey) {
+                if (accessCount > ACCESS_MAX) {
+                    resetAccessCount();
+                }
+
+                accessTable[lookup] = accessCount++;
+
+                return testValue;
+            }
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+            reset();
+
+            return getOrAddInteger(intKey);
+        }
+
+        lookup                 = hashIndex.linkNode(index, lastLookup);
+        testValue              = new Integer(intKey);
+        objectKeyTable[lookup] = testValue;
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        accessTable[lookup] = accessCount++;
+
+        return testValue;
+    }
+
+    protected Long getOrAddLong(long longKey) {
+
+        Long testValue;
+        int index = hashIndex.getHashIndex((int) (longKey ^ (longKey >>> 32)));
+        int  lookup     = hashIndex.hashTable[index];
+        int  lastLookup = -1;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            testValue = (Long) objectKeyTable[lookup];
+
+            if (testValue.longValue() == longKey) {
+                if (accessCount > ACCESS_MAX) {
+                    resetAccessCount();
+                }
+
+                accessTable[lookup] = accessCount++;
+
+                return testValue;
+            }
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+            reset();
+
+            return getOrAddLong(longKey);
+        }
+
+        lookup                 = hashIndex.linkNode(index, lastLookup);
+        testValue              = new Long(longKey);
+        objectKeyTable[lookup] = testValue;
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        accessTable[lookup] = accessCount++;
+
+        return testValue;
+    }
+
+    /**
+     * This is dissimilar to normal hash map get() methods. The key Object
+     * should have an equals(String) method which should return true if the
+     * key.toString().equals(String) is true. Also the key.hashCode() method
+     * must return the same value as key.toString.hashCode().<p>
+     *
+     * The above is always true when the key is a String. But it means it is
+     * possible to submit special keys that fulfill the contract. For example
+     * a wrapper around a byte[] can be submitted as key to retrieve either
+     * a new String, which is the result of the toString() method of the
+     * wrapper, or return an existing String which would be equal to the result
+     * of toString().
+     *
+     * @param key String or other Object with compatible equals(String)
+     * and hashCode().
+     * @return String from map or a new String
+     */
+    protected String getOrAddString(Object key) {
+
+        String testValue;
+        int    index      = hashIndex.getHashIndex(key.hashCode());
+        int    lookup     = hashIndex.hashTable[index];
+        int    lastLookup = -1;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            testValue = (String) objectKeyTable[lookup];
+
+            if (key.equals(testValue)) {
+                if (accessCount > ACCESS_MAX) {
+                    resetAccessCount();
+                }
+
+                accessTable[lookup] = accessCount++;
+
+                return testValue;
+            }
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+            reset();
+
+            return getOrAddString(key);
+        }
+
+        testValue              = key.toString();
+        lookup                 = hashIndex.linkNode(index, lastLookup);
+        objectKeyTable[lookup] = testValue;
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        accessTable[lookup] = accessCount++;
+
+        return testValue;
+    }
+
+    protected String getOrAddSubString(String key, int from, int limit) {
+
+        // to improve
+        key = key.substring(from, limit);
+
+        String testValue;
+        int    index      = hashIndex.getHashIndex(key.hashCode());
+        int    lookup     = hashIndex.hashTable[index];
+        int    lastLookup = -1;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            testValue = (String) objectKeyTable[lookup];
+
+            if (key.equals(testValue)) {
+                if (accessCount > ACCESS_MAX) {
+                    resetAccessCount();
+                }
+
+                accessTable[lookup] = accessCount++;
+
+                return testValue;
+            }
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+            reset();
+
+            return getOrAddString(key);
+        }
+
+        testValue              = new String(key.toCharArray());
+        lookup                 = hashIndex.linkNode(index, lastLookup);
+        objectKeyTable[lookup] = testValue;
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        accessTable[lookup] = accessCount++;
+
+        return testValue;
+    }
+
+    protected TimestampData getOrAddDate(long longKey) {
+
+        TimestampData testValue;
+        int  hash       = (int) longKey ^ (int) (longKey >>> 32);
+        int  index      = hashIndex.getHashIndex(hash);
+        int  lookup     = hashIndex.hashTable[index];
+        int  lastLookup = -1;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            testValue = (TimestampData) objectKeyTable[lookup];
+
+            if (testValue.getSeconds() == longKey) {
+                if (accessCount > ACCESS_MAX) {
+                    resetAccessCount();
+                }
+
+                accessTable[lookup] = accessCount++;
+
+                return testValue;
+            }
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+            reset();
+
+            return getOrAddDate(longKey);
+        }
+
+        lookup                 = hashIndex.linkNode(index, lastLookup);
+        testValue              = new TimestampData(longKey);
+        objectKeyTable[lookup] = testValue;
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        accessTable[lookup] = accessCount++;
+
+        return testValue;
+    }
+
+    protected Double getOrAddDouble(long longKey) {
+
+        Double testValue;
+        int index = hashIndex.getHashIndex((int) (longKey ^ (longKey >>> 32)));
+        int    lookup     = hashIndex.hashTable[index];
+        int    lastLookup = -1;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            testValue = (Double) objectKeyTable[lookup];
+
+            if (Double.doubleToLongBits(testValue.doubleValue()) == longKey) {
+                if (accessCount > ACCESS_MAX) {
+                    resetAccessCount();
+                }
+
+                accessTable[lookup] = accessCount++;
+
+                return testValue;
+            }
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+            reset();
+
+            return getOrAddDouble(longKey);
+        }
+
+        lookup                 = hashIndex.linkNode(index, lastLookup);
+        testValue              = new Double(Double.longBitsToDouble(longKey));
+        objectKeyTable[lookup] = testValue;
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        accessTable[lookup] = accessCount++;
+
+        return testValue;
+    }
+
+    protected Object getOrAddObject(Object key) {
+
+        Object testValue;
+        int    index      = hashIndex.getHashIndex(key.hashCode());
+        int    lookup     = hashIndex.hashTable[index];
+        int    lastLookup = -1;
+
+        for (; lookup >= 0;
+                lastLookup = lookup,
+                lookup = hashIndex.getNextLookup(lookup)) {
+            testValue = objectKeyTable[lookup];
+
+            if (testValue.equals(key)) {
+                if (accessCount > ACCESS_MAX) {
+                    resetAccessCount();
+                }
+
+                accessTable[lookup] = accessCount++;
+
+                return testValue;
+            }
+        }
+
+        if (hashIndex.elementCount >= threshold) {
+            reset();
+
+            return getOrAddObject(key);
+        }
+
+        lookup                 = hashIndex.linkNode(index, lastLookup);
+        objectKeyTable[lookup] = key;
+
+        if (accessCount > ACCESS_MAX) {
+            resetAccessCount();
+        }
+
+        accessTable[lookup] = accessCount++;
+
+        return key;
+    }
+}
diff --git a/src/org/hsqldb/test/AbstractTestOdbc.java b/src/org/hsqldb/test/AbstractTestOdbc.java
new file mode 100644
index 0000000..3faf6d3
--- /dev/null
+++ b/src/org/hsqldb/test/AbstractTestOdbc.java
@@ -0,0 +1,223 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.hsqldb.persist.HsqlProperties;
+import org.hsqldb.server.Server;
+import org.hsqldb.server.ServerConstants;
+
+/**
+ * Base test class for ODBC testing with JUnit 3.x.
+ *
+ * Provides utility testrunner method, plus sets up and runs a HyperSQL
+ * listener.
+ * <P>
+ * You MUST have a native (non-Java) ODBC DSN configured with the HyperSQL
+ * ODBC driver, DSN name "HSQLDB_UTEST", DSN database "/", port "9797".
+ * The user name and password don't matter.
+ * We use the word <I>query</i> how it is used in the JDBC API, to mean a
+ * SELECT statement, not in the more general way as used in the ODBC API.
+ * </P> <P>
+ * The DSN name and port may be changed from these defaults by setting Java
+ * system properties "test.hsqlodbc.dsnname" and/or "test.hsqlodbc.port".
+ * </P> <P>
+ *   <B>This class badly needs JUnit 4.x.
+ *   Test runs take about 50x as long as they should because JUnit 3.x does
+ *   not have a way to do one-time-per-class setUp and tearDown.</B>
+ *   We should instantiate and start up the Server one time, and repopulate
+ *   the catalog contents in the traditional setUp().
+ * </P>
+ */
+public abstract class AbstractTestOdbc extends junit.framework.TestCase {
+    protected Connection netConn = null;
+    protected Server server = null;
+    static protected String portString = null;
+    static protected String dsnName = null;
+
+    public AbstractTestOdbc() {}
+
+    /**
+     * Accommodate JUnit's test-runner conventions.
+     */
+    public AbstractTestOdbc(String s) {
+        super(s);
+    }
+
+    static {
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+        } catch (ClassNotFoundException cnfe) {
+            throw new RuntimeException(
+                "<clinit> failed.  JDBC Driver class not in CLASSPATH");
+        }
+        portString = System.getProperty("test.hsqlodbc.port");
+        dsnName = System.getProperty("test.hsqlodbc.dsnname");
+        if (portString == null) {
+            portString = "9797";
+        }
+        if (dsnName == null) {
+            dsnName = "HSQLDB_UTEST";
+        }
+    }
+
+    /**
+     * JUnit convention for cleanup.
+     *
+     * Called after each test*() method.
+     */
+    protected void tearDown() throws SQLException {
+        if (netConn != null) {
+            netConn.rollback();
+            // Necessary to prevent the SHUTDOWN command from causing implied
+            // transaction control commands, which will not be able to
+            // complete.
+            netConn.createStatement().executeUpdate("SHUTDOWN");
+            netConn.close();
+            netConn = null;
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {
+            }
+        }
+        if (server != null
+            && server.getState() != ServerConstants.SERVER_STATE_SHUTDOWN) {
+            throw new RuntimeException("Server failed to shut down");
+        }
+    }
+
+    /**
+     * Specifically, this opens a mem-only DB, populates it, starts a
+     * HyperSQL Server to server it, and opens network JDBC Connection
+     * "netConn" to it,
+     *
+     * Invoked before each test*() invocation by JUnit.
+     */
+    protected void setUp() {
+        try {
+            Connection setupConn = DriverManager.getConnection(
+                "jdbc:hsqldb:mem:test", "SA", "");
+            setupConn.setAutoCommit(false);
+            Statement st = setupConn.createStatement();
+            st.executeUpdate("SET PASSWORD 'sapwd'");
+            populate(st);
+            st.close();
+            setupConn.commit();
+            setupConn.close();
+        } catch (SQLException se) {
+            throw new RuntimeException(
+                "Failed to set up in-memory database", se);
+        }
+        try {
+            server = new Server();
+            HsqlProperties properties = new HsqlProperties();
+            if (System.getProperty("VERBOSE") == null) {
+                server.setLogWriter(null);
+                server.setErrWriter(null);
+            } else {
+                properties.setProperty("server.silent", "false");
+                properties.setProperty("server.trace", "true");
+            }
+            properties.setProperty("server.database.0", "mem:test");
+            properties.setProperty("server.dbname.0", "");
+            properties.setProperty("server.port", AbstractTestOdbc.portString);
+            server.setProperties(properties);
+            server.start();
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(
+                "Failed to set up in-memory database", e);
+        }
+        if (server.getState() != ServerConstants.SERVER_STATE_ONLINE) {
+            throw new RuntimeException("Server failed to start up");
+        }
+        try {
+            netConn = DriverManager.getConnection(
+                "jdbc:odbc:" + dsnName, "SA", "sapwd");
+            //netConn.setAutoCommit(false);
+        } catch (SQLException se) {
+            if (se.getMessage().indexOf("No suitable driver") > -1) {
+                throw new RuntimeException(
+                    "You must install the native library for Sun's jdbc:odbc "
+                    + "JDBC driver");
+            }
+            if (se.getMessage().indexOf("Data source name not found") > -1) {
+                throw new RuntimeException(
+                    "You must configure ODBC DSN '" + dsnName
+                    + "' (you may change the name and/or port by setting Java "
+                    + "system properties 'test.hsqlodbc.port' or "
+                    + "'test.hsqlodbc.dsnname'");
+            }
+            throw new RuntimeException(
+                "Failed to set up JDBC/ODBC network connection", se);
+        }
+    }
+
+    protected void enableAutoCommit() {
+        try {
+            netConn.setAutoCommit(false);
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        }
+    }
+
+    /**
+     * This method allows to easily run this unit test independent of the other
+     * unit tests, and without dealing with Ant or unrelated test suites.
+     *
+     * Invoke like this:<PRE><CODE>
+     *  static public void main(String[] sa) {
+     *      staticRunner(TestOdbcService.class, sa);
+     *  }
+     *</CODE></PRE>, but give your subclass name in place of
+     * <CODE>TestOdbcService</CODE>
+     */
+    static public void staticRunner(Class c, String[] sa) {
+            junit.textui.TestRunner runner = new junit.textui.TestRunner();
+            junit.framework.TestResult result =
+                runner.run(runner.getTest(c.getName()));
+
+            System.exit(result.wasSuccessful() ? 0 : 1);
+    }
+
+    abstract protected void populate(Statement st) throws SQLException;
+}
diff --git a/src/org/hsqldb/test/AllSimpleTests.java b/src/org/hsqldb/test/AllSimpleTests.java
new file mode 100644
index 0000000..63b33d1
--- /dev/null
+++ b/src/org/hsqldb/test/AllSimpleTests.java
@@ -0,0 +1,74 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+public class AllSimpleTests {
+
+    public AllSimpleTests() {
+
+        try {
+            jbInit();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    String[] args = new String[0];
+
+    void doTests() throws Exception {
+
+        System.out.println("*********** " + HSQLBug.class.getName());
+        HSQLBug.main(args);
+        System.out.println("*********** "
+                           + TestBatchBug.class.getClass().getName());
+        TestBatchBug.main(args);
+        System.out.println("*********** " + TestDima.class.getName());
+        TestDima.main(args);
+        System.out.println("*********** " + TestHSQLDB.class.getName());
+        TestHSQLDB.main(args);
+        System.out.println("*********** " + TestObjectSize.class.getName());
+        TestObjectSize.main(args);
+        System.out.println(
+            "*********** "
+            + TestSubQueriesInPreparedStatements.class.getName());
+        TestSubQueriesInPreparedStatements.main(args);
+    }
+
+    public static void main(String[] Args) throws Exception {
+
+        AllSimpleTests ast = new AllSimpleTests();
+
+        ast.doTests();
+    }
+
+    private void jbInit() throws Exception {}
+}
diff --git a/src/org/hsqldb/test/AllTests.java b/src/org/hsqldb/test/AllTests.java
new file mode 100644
index 0000000..a04a7a7
--- /dev/null
+++ b/src/org/hsqldb/test/AllTests.java
@@ -0,0 +1,80 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AllTests extends TestCase {
+
+    public AllTests(String s) {
+        super(s);
+    }
+
+    public static Test suite() {
+
+        TestSuite suite = new TestSuite();
+
+        suite.addTestSuite(org.hsqldb.test.TestBatchExecution.class);
+        suite.addTestSuite(org.hsqldb.test.TestBug1191815.class);
+        suite.addTestSuite(org.hsqldb.test.TestBug778213.class);
+        suite.addTestSuite(org.hsqldb.test.TestBug785429.class);
+        suite.addTestSuite(org.hsqldb.test.TestBug808460.class);
+        suite.addTestSuite(org.hsqldb.test.TestCollation.class);
+        suite.addTestSuite(org.hsqldb.test.TestDatabaseMetaData.class);
+        suite.addTestSuite(org.hsqldb.test.TestDateTime.class);
+        suite.addTestSuite(org.hsqldb.test.TestINPredicateParameterizationAndCorrelation.class);
+        suite.addTestSuite(org.hsqldb.test.TestJDBCGeneratedColumns.class);
+        suite.addTestSuite(org.hsqldb.test.TestJDBCSavepoints.class);
+        suite.addTestSuite(org.hsqldb.test.TestLikePredicateOptimizations.class);
+        suite.addTestSuite(org.hsqldb.test.TestLobs.class);
+        suite.addTestSuite(org.hsqldb.test.TestMerge.class);
+        suite.addTestSuite(org.hsqldb.test.TestMultiInsert.class);
+        suite.addTestSuite(org.hsqldb.test.TestPreparedSubQueries.class);
+        suite.addTestSuite(org.hsqldb.test.TestSql.class);
+        suite.addTestSuite(org.hsqldb.test.TestStoredProcedure.class);
+        suite.addTestSuite(org.hsqldb.test.TestSubselect.class);
+        suite.addTestSuite(org.hsqldb.test.TestTextTable.class);
+        suite.addTestSuite(org.hsqldb.test.TestTextTables.class);
+        suite.addTestSuite(org.hsqldb.test.TestViewAsterisks.class);
+
+        //
+        suite.addTestSuite(org.hsqldb.test.TestCascade.class);
+//        suite.addTestSuite(org.hsqldb.test.TestDataStructures.class);
+        suite.addTestSuite(org.hsqldb.test.TestGroupByHaving.class);
+        suite.addTestSuite(org.hsqldb.test.TestSqlPersistent.class);
+        suite.addTestSuite(org.hsqldb.test.TestUpdatableResults.class);
+        suite.addTestSuite(org.hsqldb.test.TestUpdatableResultSets.class);
+        return suite;
+    }
+}
diff --git a/src/org/hsqldb/test/BlaineTrig.java b/src/org/hsqldb/test/BlaineTrig.java
new file mode 100644
index 0000000..bcbbcf7
--- /dev/null
+++ b/src/org/hsqldb/test/BlaineTrig.java
@@ -0,0 +1,44 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+public class BlaineTrig implements org.hsqldb.Trigger {
+
+    public void fire(int i, String name, String table, Object[] row1,
+                     Object[] row2) {
+        System.err.println("Hello World.  There is a fire");
+    }
+
+    public static String capitalize(String s) {
+        return s.toUpperCase();
+    }
+}
diff --git a/src/org/hsqldb/test/ClearTests.java b/src/org/hsqldb/test/ClearTests.java
new file mode 100644
index 0000000..159e3a6
--- /dev/null
+++ b/src/org/hsqldb/test/ClearTests.java
@@ -0,0 +1,50 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+class ClearTests {
+
+    public static void main(String[] argv) {
+
+        TestUtil.deleteDatabase("test");
+        TestUtil.deleteDatabase("test1");
+        TestUtil.deleteDatabase("test2");
+        TestUtil.deleteDatabase("test3");
+        TestUtil.deleteDatabase("/hsql/testbench/test");
+        TestUtil.deleteDatabase("/hsql/jdbcbench/test");
+        TestUtil.deleteDatabase("/hsql/test/subselect");
+        TestUtil.deleteDatabase("/hsql/test/testpersistent");
+        TestUtil.deleteDatabase("/hsql/testdima/test");
+        TestUtil.deleteDatabase("/hsql/testpa/test");
+        TestUtil.deleteDatabase("/hsql/testtime/test");
+    }
+}
diff --git a/src/org/hsqldb/test/HSQLBug.java b/src/org/hsqldb/test/HSQLBug.java
new file mode 100644
index 0000000..91b81a5
--- /dev/null
+++ b/src/org/hsqldb/test/HSQLBug.java
@@ -0,0 +1,114 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Properties;
+
+public class HSQLBug {
+
+    public static void main(String[] args) throws Exception {
+
+        Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+        String     url        = "jdbc:hsqldb:mem:.";
+        Properties properties = new Properties();
+
+        properties.setProperty("user", "sa");
+        properties.setProperty("password", "");
+
+        Connection con = DriverManager.getConnection(url, properties);
+        Statement  s   = con.createStatement();
+
+        s.executeUpdate(
+            "CREATE TABLE Table1 (Id INTEGER IDENTITY, Timec DATETIME NOT NULL)");
+        s.executeUpdate(
+            "CREATE TABLE Table2 (Id INTEGER NOT NULL, Value VARCHAR(100) NOT NULL)");
+        s.executeUpdate("CREATE INDEX idx1 ON Table1(timec)");
+
+        // Add test data to the tables
+        GregorianCalendar gc = new GregorianCalendar();
+
+        for (int i = 0; i < 1000; i++) {
+            gc.add(Calendar.MINUTE, -1);
+
+            String query = "INSERT INTO Table1 (Timec) VALUES ('"
+                           + formatter.format(gc.getTime()) + "')";
+
+            s.executeUpdate(query);
+
+            ResultSet r = s.executeQuery("CALL IDENTITY();");
+
+            r.next();
+
+            int id = r.getInt(1);
+
+            s.executeUpdate("INSERT INTO Table2 VALUES (" + id + ", 'ABC')");
+            s.executeUpdate("INSERT INTO Table2 VALUES (" + id + ", 'DEF')");
+        }
+
+        // Build the query
+        StringBuffer query = new StringBuffer();
+
+        query.append("SELECT Timec, Value FROM Table1, Table2 ");
+        query.append("WHERE Table1.Id = Table2.Id  ");
+        query.append("AND Table1.Timec = ");    // The equals sign causes the CPU to go to 100% for a while
+
+//                      query.append( "AND Table1.Time IN " );  // The work-around is to replace it with IN
+        query.append("(");
+        query.append(
+            "SELECT MAX(Timec) FROM Table1 WHERE Timec <= '2020-01-01 00:00:00'");
+        query.append(")");
+        System.out.println("Query = " + query);
+        System.out.println(
+            "Starting Query at: "
+            + formatter.format((new GregorianCalendar()).getTime()));
+
+        ResultSet r = s.executeQuery(query.toString());
+
+        r.next();
+        System.out.println("Result    : " + r.getTimestamp(1) + "  "
+                           + r.getString(2));
+        System.out.println(
+            "DONE Query at    : "
+            + formatter.format((new GregorianCalendar()).getTime()));
+    }
+
+    private static SimpleDateFormat formatter =
+        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+}
diff --git a/src/org/hsqldb/test/HsqldbTestCase.java b/src/org/hsqldb/test/HsqldbTestCase.java
new file mode 100644
index 0000000..b946877
--- /dev/null
+++ b/src/org/hsqldb/test/HsqldbTestCase.java
@@ -0,0 +1,170 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Properties;
+
+/**
+ * <b>Description</b> : HsqldbTestCase
+ *
+ * <p><b>Society</b> : dataXpresso
+ * @since 8 august 2006
+ * @author Julien Blaize
+ */
+public class HsqldbTestCase {
+
+    /**
+     * Deletes all files and subdirectories under dir.
+     * Returns true if all deletions were successful.
+     * If a deletion fails, the method stops attempting to delete and returns false.
+     */
+    public static boolean deleteDir(File dir) {
+
+        if (dir.isDirectory()) {
+            String[] children = dir.list();
+
+            for (int i = 0; i < children.length; i++) {
+                boolean success = deleteDir(new File(dir, children[i]));
+
+                if (!success) {
+                    return false;
+                }
+            }
+        }
+
+        // The directory is now empty so delete it
+        return dir.delete();
+    }
+
+    public static void main(String[] args) {
+
+        Properties props = new Properties();
+
+        props.put("user", "sa");
+        props.put("password", "");
+        props.put("hsqldb.default_table_type", "cached");
+
+        //props.put("hsqldb.cache_size_scale", "12");
+        props.put("hsqldb.cache_scale", "8");
+
+        //props.put("hsqldb.cache_file_scale", "8");
+        props.put("hsqldb.applog", "0");
+        props.put("hsqldb.log_size", "200");
+        props.put("hsqldb.result_memory_rows", "10");
+        props.put("shutdown", "true");
+
+        String url = "jdbc:hsqldb:";
+
+        url += "/hsql/statBase/test";
+
+        //delete earlier files
+        HsqldbTestCase.deleteDir(new File("/hsql/statBase/"));
+
+        try {
+            Class  clsDriver = Class.forName("org.hsqldb.jdbc.JDBCDriver");
+            Driver driver    = (Driver) clsDriver.newInstance();
+
+            DriverManager.registerDriver(driver);
+
+            Connection con = DriverManager.getConnection(url, props);
+            String createQuery =
+                "drop table test1 if exists;create table test1 (rowNum identity, col1 varchar(50), col2 int, col3 varchar(50))";
+            Statement st = con.createStatement();
+
+            st.execute(createQuery);
+            st.close();
+
+            //we try to insert values in batch
+            String insertQuery =
+                "insert into test1 (col1,col2,col3) values (?,?,?)";
+            PreparedStatement pst = con.prepareStatement(insertQuery);
+
+            //we insert 1001
+            for (int i = 0; i < 1001; i++) {
+                pst.setString(1, "string_" + i);
+                pst.setInt(2, i);
+                pst.setString(3, "string2_" + i);
+                pst.addBatch();
+
+                if ((i > 0) && (i % 100 == 0)) {
+                    pst.executeBatch();
+                }
+            }
+
+            pst.close();
+
+            //we try to do a select on this statement and to scroll it with the absolute method
+            String selectQuery = "select * from test1";
+
+            st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
+                                     ResultSet.CONCUR_READ_ONLY);
+
+            ResultSet scrollableSet = st.executeQuery(selectQuery);
+
+            scrollableSet.setFetchSize(100);
+            scrollableSet.next();
+
+            int tmpIndex = scrollableSet.getInt(3);
+
+            if (tmpIndex != 0) {
+                System.out.println("index at 0 is !=0");
+            }
+
+            //we go from 0 to 1000 with absolute and a gap of 100
+            for (int i = 0; i <= 1000; i += 100) {
+                scrollableSet.absolute(i + 1);
+
+                tmpIndex = scrollableSet.getInt(3);
+
+                System.out.println(tmpIndex);
+            }
+
+            //we go from 1000 to 0 with absolute and a gap of 100
+            for (int i = 1000; i > 0; i -= 100) {
+                scrollableSet.relative(-100);
+
+                tmpIndex = scrollableSet.getInt(3);
+
+                System.out.println(tmpIndex);
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace(System.out);
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/JDBCBench.java b/src/org/hsqldb/test/JDBCBench.java
new file mode 100644
index 0000000..ee91dd0
--- /dev/null
+++ b/src/org/hsqldb/test/JDBCBench.java
@@ -0,0 +1,1113 @@
+package org.hsqldb.test;
+
+// nbazin@users - enhancements to the original code
+// fredt@users - 20050202 - corrected getRandomID(int) to return a randomly distributed value
+/*
+ *  This is a sample implementation of the Transaction Processing Performance
+ *  Council Benchmark B coded in Java and ANSI SQL2.
+ *
+ *  This version is using one connection per thread to parallellize
+ *  server operations.
+ * @author Mark Matthews (mark@mysql.com)
+ */
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Enumeration;
+import java.util.Vector;
+
+class JDBCBench {
+
+    /* tpc bm b scaling rules */
+    public static int tps       = 1;         /* the tps scaling factor: here it is 1 */
+    public static int nbranches = 1;         /* number of branches in 1 tps db       */
+    public static int ntellers  = 10;        /* number of tellers in  1 tps db       */
+    public static int naccounts = 100000;    /* number of accounts in 1 tps db       */
+    public static int nhistory = 864000;     /* number of history recs in 1 tps db   */
+    public static final int TELLER              = 0;
+    public static final int BRANCH              = 1;
+    public static final int ACCOUNT             = 2;
+    int                     failed_transactions = 0;
+    int                     transaction_count   = 0;
+    static int              n_clients           = 10;
+    static int              n_txn_per_client    = 10;
+    long                    start_time          = 0;
+    static boolean          transactions        = true;
+    static boolean          prepared_stmt       = false;
+    static String           tableExtension      = "";
+    static String           createExtension     = "";
+    static String           ShutdownCommand     = "";
+    static PrintStream      TabFile             = null;
+    static boolean          verbose             = false;
+    MemoryWatcherThread     MemoryWatcher;
+
+    /* main program,    creates a 1-tps database:  i.e. 1 branch, 10 tellers,...
+     *                    runs one TPC BM B transaction
+     * example command line:
+     * -driver  org.hsqldb.jdbc.JDBCDriver -url jdbc:hsqldb:/hsql/jdbcbench/test -user SA -clients 20 -tpc 10000
+     */
+    public static void main(String[] Args) {
+
+        String  DriverName         = "";
+        String  DBUrl              = "";
+        String  DBUser             = "";
+        String  DBPassword         = "";
+        boolean initialize_dataset = false;
+
+        for (int i = 0; i < Args.length; i++) {
+            if (Args[i].equals("-clients")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    n_clients = Integer.parseInt(Args[i]);
+                }
+            } else if (Args[i].equals("-driver")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    DriverName = Args[i];
+
+                    if (DriverName.equals(
+                            "org.enhydra.instantdb.jdbc.idbDriver")) {
+                        ShutdownCommand = "SHUTDOWN";
+                    }
+
+                    if (DriverName.equals(
+                            "com.borland.datastore.jdbc.DataStoreDriver")) {}
+
+                    if (DriverName.equals("com.mckoi.JDBCDriver")) {
+                        ShutdownCommand = "SHUTDOWN";
+                    }
+
+                    if (DriverName.equals("org.hsqldb.jdbc.JDBCDriver")
+                            || DriverName.equals("org.hsqldb.jdbcDriver")) {
+
+                        tableExtension  = "CREATE CACHED TABLE ";
+//                        ShutdownCommand = "SHUTDOWN";
+                    }
+                }
+            } else if (Args[i].equals("-url")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    DBUrl = Args[i];
+                }
+            } else if (Args[i].equals("-user")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    DBUser = Args[i];
+                }
+            } else if (Args[i].equals("-tabfile")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    try {
+                        FileOutputStream File = new FileOutputStream(Args[i]);
+
+                        TabFile = new PrintStream(File);
+                    } catch (Exception e) {
+                        TabFile = null;
+                    }
+                }
+            } else if (Args[i].equals("-password")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    DBPassword = Args[i];
+                }
+            } else if (Args[i].equals("-tpc")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    n_txn_per_client = Integer.parseInt(Args[i]);
+                }
+            } else if (Args[i].equals("-init")) {
+                initialize_dataset = true;
+            } else if (Args[i].equals("-tps")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    tps = Integer.parseInt(Args[i]);
+                }
+            } else if (Args[i].equals("-v")) {
+                verbose = true;
+            }
+        }
+
+        if (DriverName.length() == 0 || DBUrl.length() == 0) {
+            System.out.println(
+                "usage: java JDBCBench -driver [driver_class_name] -url [url_to_db] -user [username] -password [password] [-v] [-init] [-tpc n] [-clients n]");
+            System.out.println();
+            System.out.println("-v          verbose error messages");
+            System.out.println("-init       initialize the tables");
+            System.out.println("-tpc        transactions per client");
+            System.out.println("-clients    number of simultaneous clients");
+            System.exit(-1);
+        }
+
+        System.out.println(
+            "*********************************************************");
+        System.out.println(
+            "* JDBCBench v1.1                                        *");
+        System.out.println(
+            "*********************************************************");
+        System.out.println();
+        System.out.println("Driver: " + DriverName);
+        System.out.println("URL:" + DBUrl);
+        System.out.println();
+        System.out.println("Scale factor value: " + tps);
+        System.out.println("Number of clients: " + n_clients);
+        System.out.println("Number of transactions per client: "
+                           + n_txn_per_client);
+        System.out.println();
+
+        try {
+            Class.forName(DriverName);
+
+            JDBCBench Me = new JDBCBench(DBUrl, DBUser, DBPassword,
+                                         initialize_dataset);
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        }
+    }
+
+    public JDBCBench(String url, String user, String password, boolean init) {
+
+        Vector      vClient  = new Vector();
+        Thread      Client   = null;
+        Enumeration e        = null;
+        Connection  guardian = null;
+
+        try {
+            java.util.Date start = new java.util.Date();
+
+            if (init) {
+                System.out.println("Start: " + start.toString());
+                System.out.print("Initializing dataset...");
+                createDatabase(url, user, password);
+
+                double seconds = (System.currentTimeMillis() - start.getTime())
+                                 / 1000D;
+
+                System.out.println("done. in " + seconds + " seconds\n");
+                System.out.println("Complete: "
+                                   + (new java.util.Date()).toString());
+            }
+
+            System.out.println("* Starting Benchmark Run *");
+
+            MemoryWatcher = new MemoryWatcherThread();
+
+            MemoryWatcher.start();
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+/*
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+            oneRound(url, user, password, transactions, true);
+*/
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        } finally {
+            MemoryWatcher.end();
+
+            try {
+                MemoryWatcher.join();
+
+                if (ShutdownCommand.length() > 0) {
+                    guardian = connect(url, user, password);
+
+                    Statement Stmt = guardian.createStatement();
+
+                    Stmt.execute("SHUTDOWN IMMEDIATELY");
+                    Stmt.close();
+                    connectClose(guardian);
+                }
+
+                if (TabFile != null) {
+                    TabFile.close();
+                }
+            } catch (Exception E1) {}
+
+//            System.exit(0);
+        }
+    }
+
+    void oneRound(String url, String user, String password,
+                  boolean transactions,
+                  boolean prepared) throws InterruptedException, SQLException {
+
+        Vector      vClient  = new Vector();
+        Thread      Client   = null;
+        Enumeration e        = null;
+        Connection  guardian = null;
+
+        //
+        this.transactions  = transactions;
+        this.prepared_stmt = prepared;
+        start_time         = System.currentTimeMillis();
+
+        for (int i = 0; i < n_clients; i++) {
+            Client = new ClientThread(n_txn_per_client, url, user, password,
+                                      Connection.TRANSACTION_READ_COMMITTED);
+
+            Client.start();
+            vClient.addElement(Client);
+        }
+
+        /*
+         ** Barrier to complete this test session
+         */
+        e = vClient.elements();
+
+        while (e.hasMoreElements()) {
+            Client = (Thread) e.nextElement();
+
+            Client.join();
+        }
+
+        vClient.removeAllElements();
+        reportDone();
+
+        guardian = connect(url, user, password);
+
+        checkSums(guardian);
+        connectClose(guardian);
+    }
+
+    public void reportDone() {
+
+        long end_time = System.currentTimeMillis();
+        double completion_time = ((double) end_time - (double) start_time)
+                                 / 1000;
+
+        if (TabFile != null) {
+            TabFile.print(tps + ";" + n_clients + ";" + n_txn_per_client
+                          + ";");
+        }
+
+        System.out.println("\n* Benchmark Report *");
+        System.out.print("* Featuring ");
+
+        if (prepared_stmt) {
+            System.out.print("<prepared statements> ");
+
+            if (TabFile != null) {
+                TabFile.print("<prepared statements>;");
+            }
+        } else {
+            System.out.print("<direct queries> ");
+
+            if (TabFile != null) {
+                TabFile.print("<direct queries>;");
+            }
+        }
+
+        if (transactions) {
+            System.out.print("<transactions> ");
+
+            if (TabFile != null) {
+                TabFile.print("<transactions>;");
+            }
+        } else {
+            System.out.print("<auto-commit> ");
+
+            if (TabFile != null) {
+                TabFile.print("<auto-commit>;");
+            }
+        }
+
+        System.out.println("\n--------------------");
+        System.out.println("Time to execute " + transaction_count
+                           + " transactions: " + completion_time
+                           + " seconds.");
+        System.out.println("Max/Min memory usage: " + MemoryWatcher.max
+                           + " / " + MemoryWatcher.min + " kb");
+        System.out.println(failed_transactions + " / " + transaction_count
+                           + " failed to complete.");
+
+        double rate = (transaction_count - failed_transactions)
+                      / completion_time;
+
+        System.out.println("Transaction rate: " + rate + " txn/sec.");
+
+        if (TabFile != null) {
+            TabFile.print(MemoryWatcher.max + ";" + MemoryWatcher.min + ";"
+                          + failed_transactions + ";" + rate + "\n");
+        }
+
+        transaction_count   = 0;
+        failed_transactions = 0;
+
+        MemoryWatcher.reset();
+    }
+
+    public synchronized void incrementTransactionCount() {
+        transaction_count++;
+    }
+
+    public synchronized void incrementFailedTransactionCount() {
+        failed_transactions++;
+    }
+
+    void createDatabase(String url, String user,
+                        String password) throws Exception {
+
+        Connection Conn = connect(url, user, password);
+        String     s    = Conn.getMetaData().getDatabaseProductName();
+
+        System.out.println("DBMS: " + s);
+
+        transactions = true;
+
+        if (transactions) {
+            try {
+                Conn.setAutoCommit(false);
+                System.out.println("In transaction mode");
+            } catch (SQLException Etrxn) {
+                transactions = false;
+            }
+        }
+
+        try {
+            int       accountsnb = 0;
+            Statement Stmt       = Conn.createStatement();
+            String    Query;
+
+//
+            Stmt.execute("SET WRITE_DELAY 10000 MILLIS;");
+            Stmt.execute("SET PROPERTY \"hsqldb.cache_scale\" 16;");
+
+//
+            Query = "SELECT count(*) ";
+            Query += "FROM   accounts";
+
+            ResultSet RS = Stmt.executeQuery(Query);
+
+            Stmt.clearWarnings();
+
+            while (RS.next()) {
+                accountsnb = RS.getInt(1);
+            }
+
+            if (transactions) {
+                Conn.commit();
+            }
+
+            Stmt.close();
+
+            if (accountsnb == (naccounts * tps)) {
+                System.out.println("Already initialized");
+                connectClose(Conn);
+
+                return;
+            }
+        } catch (Exception E) {}
+
+        System.out.println("Drop old tables if they exist");
+
+        try {
+            Statement Stmt = Conn.createStatement();
+            String    Query;
+
+            Query = "DROP TABLE history";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DROP TABLE accounts";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DROP TABLE tellers";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DROP TABLE branches";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            if (transactions) {
+                Conn.commit();
+            }
+
+            Stmt.close();
+        } catch (Exception E) {}
+
+        System.out.println("Creates tables");
+
+        try {
+            Statement Stmt = Conn.createStatement();
+            String    Query;
+
+            if (tableExtension.length() > 0) {
+                Query = tableExtension + " branches (";
+            } else {
+                Query = "CREATE TABLE branches (";
+            }
+
+            Query += "Bid         INTEGER NOT NULL PRIMARY KEY, ";
+            Query += "Bbalance    INTEGER,";
+            Query += "filler      CHAR(88))";    /* pad to 100 bytes */
+
+            if (createExtension.length() > 0) {
+                Query += createExtension;
+            }
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            if (tableExtension.length() > 0) {
+                Query = tableExtension + " tellers (";
+            } else {
+                Query = "CREATE TABLE tellers (";
+            }
+
+            Query += "Tid         INTEGER NOT NULL PRIMARY KEY,";
+            Query += "Bid         INTEGER,";
+            Query += "Tbalance    INTEGER,";
+            Query += "filler      CHAR(84))";    /* pad to 100 bytes */
+
+            if (createExtension.length() > 0) {
+                Query += createExtension;
+            }
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            if (tableExtension.length() > 0) {
+                Query = tableExtension + " accounts (";
+            } else {
+                Query = "CREATE TABLE accounts (";
+            }
+
+            Query += "Aid         INTEGER NOT NULL PRIMARY KEY, ";
+            Query += "Bid         INTEGER, ";
+            Query += "Abalance    INTEGER, ";
+            Query += "filler      CHAR(84))";    /* pad to 100 bytes */
+
+            if (createExtension.length() > 0) {
+                Query += createExtension;
+            }
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            if (tableExtension.length() > 0) {
+                Query = tableExtension + " history (";
+            } else {
+                Query = "CREATE TABLE history (";
+            }
+
+            Query += "Tid         INTEGER, ";
+            Query += "Bid         INTEGER, ";
+            Query += "Aid         INTEGER, ";
+            Query += "delta       INTEGER, ";
+            Query += "tstime        TIMESTAMP, ";
+            Query += "filler      CHAR(22))";    /* pad to 50 bytes  */
+
+            if (createExtension.length() > 0) {
+                Query += createExtension;
+            }
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+/*
+            Stmt.execute("SET TABLE ACCOUNTS SOURCE \"ACCOUNTS.TXT\"");
+            Stmt.execute("SET TABLE BRANCHES SOURCE \"BBRANCHES.TXT\"");
+            Stmt.execute("SET TABLE TELLERS SOURCE \"TELLERS.TXT\"");
+            Stmt.execute("SET TABLE HISTORY SOURCE \"HISTORY.TXT\"");
+*/
+            if (transactions) {
+                Conn.commit();
+            }
+
+            Stmt.close();
+        } catch (Exception E) {
+            System.out.println(
+                "Delete elements in table in case Drop didn't work");
+        }
+
+        System.out.println(
+            "Delete elements in table in case Drop didn't work");
+
+        try {
+            Statement Stmt = Conn.createStatement();
+            String    Query;
+
+            Query = "DELETE FROM history";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DELETE FROM accounts";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DELETE FROM tellers";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DELETE FROM branches";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            if (transactions) {
+                Conn.commit();
+            }
+
+            /* prime database using TPC BM B scaling rules.
+             **  Note that for each branch and teller:
+             **      branch_id = teller_id  / ntellers
+             **      branch_id = account_id / naccounts
+             */
+            PreparedStatement pstmt = null;
+
+            prepared_stmt = true;
+
+            if (prepared_stmt) {
+                try {
+                    Query = "INSERT INTO branches(Bid,Bbalance) VALUES (?,0)";
+                    pstmt = Conn.prepareStatement(Query);
+
+                    System.out.println("Using prepared statements");
+                } catch (SQLException Epstmt) {
+                    pstmt         = null;
+                    prepared_stmt = false;
+                }
+            }
+
+            System.out.println("Insert data in branches table");
+
+            for (int i = 0; i < nbranches * tps; i++) {
+                if (prepared_stmt) {
+                    pstmt.setInt(1, i);
+                    pstmt.executeUpdate();
+                    pstmt.clearWarnings();
+                } else {
+                    Query = "INSERT INTO branches(Bid,Bbalance) VALUES (" + i
+                            + ",0)";
+
+                    Stmt.executeUpdate(Query);
+                }
+
+                if ((i % 100 == 0) && (transactions)) {
+                    Conn.commit();
+                }
+            }
+
+            if (prepared_stmt) {
+                pstmt.close();
+            }
+
+            if (transactions) {
+                Conn.commit();
+            }
+
+            if (prepared_stmt) {
+                Query = "INSERT INTO tellers(Tid,Bid,Tbalance) VALUES (?,?,0)";
+                pstmt = Conn.prepareStatement(Query);
+            }
+
+            System.out.println("Insert data in tellers table");
+
+            for (int i = 0; i < ntellers * tps; i++) {
+                if (prepared_stmt) {
+                    pstmt.setInt(1, i);
+                    pstmt.setInt(2, i / ntellers);
+                    pstmt.executeUpdate();
+                    pstmt.clearWarnings();
+                } else {
+                    Query = "INSERT INTO tellers(Tid,Bid,Tbalance) VALUES ("
+                            + i + "," + i / ntellers + ",0)";
+
+                    Stmt.executeUpdate(Query);
+                }
+
+                if ((i % 100 == 0) && (transactions)) {
+                    Conn.commit();
+                }
+            }
+
+            if (prepared_stmt) {
+                pstmt.close();
+            }
+
+            if (transactions) {
+                Conn.commit();
+            }
+
+            if (prepared_stmt) {
+                Query =
+                    "INSERT INTO accounts(Aid,Bid,Abalance) VALUES (?,?,0)";
+                pstmt = Conn.prepareStatement(Query);
+            }
+
+            System.out.println("Insert data in accounts table");
+
+            for (int i = 0; i < naccounts * tps; i++) {
+                if (prepared_stmt) {
+                    pstmt.setInt(1, i);
+                    pstmt.setInt(2, i / naccounts);
+                    pstmt.executeUpdate();
+                    pstmt.clearWarnings();
+                } else {
+                    Query = "INSERT INTO accounts(Aid,Bid,Abalance) VALUES ("
+                            + i + "," + i / naccounts + ",0)";
+
+                    Stmt.executeUpdate(Query);
+                }
+
+                if ((i % 10000 == 0) && (transactions)) {
+                    Conn.commit();
+                }
+
+                if ((i > 0) && ((i % 10000) == 0)) {
+                    System.out.println("\t" + i + "\t records inserted");
+                }
+            }
+
+            if (prepared_stmt) {
+                pstmt.close();
+            }
+
+            if (transactions) {
+                Conn.commit();
+            }
+
+            System.out.println("\t" + (naccounts * tps)
+                               + "\t records inserted");
+
+            // for tests
+            if (ShutdownCommand.length() > 0) {
+                Stmt.execute(ShutdownCommand);
+            }
+
+            Stmt.close();
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        }
+
+        connectClose(Conn);
+    }    /* end of CreateDatabase    */
+
+    public static int getRandomInt(int lo, int hi) {
+
+        int ret = 0;
+
+        ret = (int) (Math.random() * (hi - lo + 1));
+        ret += lo;
+
+        return ret;
+    }
+
+    public static int getRandomID(int type) {
+
+        int min = 0,
+            max = 0;
+
+        switch (type) {
+
+            case TELLER :
+                max = ntellers * tps - 1;
+                break;
+
+            case BRANCH :
+                max = nbranches * tps - 1;
+                break;
+
+            case ACCOUNT :
+                max = naccounts * tps - 1;
+                break;
+        }
+
+        return (getRandomInt(min, max));
+    }
+
+    public static Connection connect(String DBUrl, String DBUser,
+                                     String DBPassword) {
+
+        try {
+            Connection conn = DriverManager.getConnection(DBUrl, DBUser,
+                DBPassword);
+
+            return conn;
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public static void connectClose(Connection c) {
+
+        if (c == null) {
+            return;
+        }
+
+        try {
+            c.close();
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        }
+    }
+
+    void checkSums(Connection conn) throws SQLException {
+
+        Statement st1 = null;
+        ResultSet rs  = null;
+        int       bbalancesum;
+        int       tbalancesum;
+        int       abalancesum;
+        int       deltasum;
+
+        try {
+            st1 = conn.createStatement();
+            rs  = st1.executeQuery("select sum(bbalance) from branches");
+
+            rs.next();
+
+            bbalancesum = rs.getInt(1);
+
+            rs.close();
+
+            rs = st1.executeQuery("select sum(tbalance) from tellers");
+
+            rs.next();
+
+            tbalancesum = rs.getInt(1);
+
+            rs.close();
+
+            rs = st1.executeQuery("select sum(abalance) from accounts");
+
+            rs.next();
+
+            abalancesum = rs.getInt(1);
+
+            rs.close();
+
+            rs = st1.executeQuery("select sum(delta) from history");
+
+            rs.next();
+
+            deltasum = rs.getInt(1);
+
+            rs.close();
+
+            rs = null;
+
+            st1.close();
+
+            st1 = null;
+
+            if (abalancesum != bbalancesum || bbalancesum != tbalancesum
+                    || tbalancesum != deltasum) {
+                System.out.println("sums don't match!");
+            } else {
+                System.out.println("sums match!");
+            }
+
+            System.out.println("A " + abalancesum + " B " + bbalancesum
+                               + " T " + tbalancesum + " H " + deltasum);
+        } finally {
+            if (st1 != null) {
+                st1.close();
+            }
+        }
+    }
+
+    class ClientThread extends Thread {
+
+        int               ntrans = 0;
+        Connection        Conn;
+        PreparedStatement pstmt1 = null;
+        PreparedStatement pstmt2 = null;
+        PreparedStatement pstmt3 = null;
+        PreparedStatement pstmt4 = null;
+        PreparedStatement pstmt5 = null;
+
+        public ClientThread(int number_of_txns, String url, String user,
+                            String password, int transactionMode) {
+
+            System.out.println(number_of_txns);
+
+            ntrans = number_of_txns;
+            Conn   = connect(url, user, password);
+
+            if (Conn == null) {
+                return;
+            }
+
+            try {
+                if (transactions) {
+                    Conn.setAutoCommit(false);
+                }
+
+                Conn.setTransactionIsolation(transactionMode);
+
+                if (prepared_stmt) {
+                    String Query;
+
+                    Query  = "UPDATE accounts ";
+                    Query  += "SET     Abalance = Abalance + ? ";
+                    Query  += "WHERE   Aid = ?";
+                    pstmt1 = Conn.prepareStatement(Query);
+                    Query  = "SELECT Abalance ";
+                    Query  += "FROM   accounts ";
+                    Query  += "WHERE  Aid = ?";
+                    pstmt2 = Conn.prepareStatement(Query);
+                    Query  = "UPDATE tellers ";
+                    Query  += "SET    Tbalance = Tbalance + ? ";
+                    Query  += "WHERE  Tid = ?";
+                    pstmt3 = Conn.prepareStatement(Query);
+                    Query  = "UPDATE branches ";
+                    Query  += "SET    Bbalance = Bbalance + ? ";
+                    Query  += "WHERE  Bid = ?";
+                    pstmt4 = Conn.prepareStatement(Query);
+                    Query  = "INSERT INTO history(Tid, Bid, Aid, delta) ";
+                    Query  += "VALUES (?,?,?,?)";
+                    pstmt5 = Conn.prepareStatement(Query);
+                }
+            } catch (Exception E) {
+                System.out.println(E.getMessage());
+                E.printStackTrace();
+            }
+        }
+
+        public void run() {
+
+            while (ntrans-- > 0) {
+                int account = JDBCBench.getRandomID(ACCOUNT);
+                int branch  = JDBCBench.getRandomID(BRANCH);
+                int teller  = JDBCBench.getRandomID(TELLER);
+                int delta   = JDBCBench.getRandomInt(0, 1000);
+
+                doOne(branch, teller, account, delta);
+                incrementTransactionCount();
+            }
+
+            if (prepared_stmt) {
+                try {
+                    if (pstmt1 != null) {
+                        pstmt1.close();
+                    }
+
+                    if (pstmt2 != null) {
+                        pstmt2.close();
+                    }
+
+                    if (pstmt3 != null) {
+                        pstmt3.close();
+                    }
+
+                    if (pstmt4 != null) {
+                        pstmt4.close();
+                    }
+
+                    if (pstmt5 != null) {
+                        pstmt5.close();
+                    }
+                } catch (Exception E) {
+                    System.out.println(E.getMessage());
+                    E.printStackTrace();
+                }
+            }
+
+            connectClose(Conn);
+
+            Conn = null;
+        }
+
+        /*
+         **  doOne() - Executes a single TPC BM B transaction.
+         */
+        int doOne(int bid, int tid, int aid, int delta) {
+
+            int aBalance = 0;
+
+            if (Conn == null) {
+                incrementFailedTransactionCount();
+
+                return 0;
+            }
+
+            try {
+                if (prepared_stmt) {
+                    pstmt1.setInt(1, delta);
+                    pstmt1.setInt(2, aid);
+                    pstmt1.executeUpdate();
+                    pstmt1.clearWarnings();
+                    pstmt2.setInt(1, aid);
+
+                    ResultSet RS = pstmt2.executeQuery();
+
+                    pstmt2.clearWarnings();
+
+                    while (RS.next()) {
+                        aBalance = RS.getInt(1);
+                    }
+
+                    pstmt3.setInt(1, delta);
+                    pstmt3.setInt(2, tid);
+                    pstmt3.executeUpdate();
+                    pstmt3.clearWarnings();
+                    pstmt4.setInt(1, delta);
+                    pstmt4.setInt(2, bid);
+                    pstmt4.executeUpdate();
+                    pstmt4.clearWarnings();
+                    pstmt5.setInt(1, tid);
+                    pstmt5.setInt(2, bid);
+                    pstmt5.setInt(3, aid);
+                    pstmt5.setInt(4, delta);
+                    pstmt5.executeUpdate();
+                    pstmt5.clearWarnings();
+                } else {
+                    Statement Stmt  = Conn.createStatement();
+                    String    Query = "UPDATE accounts ";
+
+                    Query += "SET     Abalance = Abalance + " + delta + " ";
+                    Query += "WHERE   Aid = " + aid;
+
+                    int res = Stmt.executeUpdate(Query);
+
+                    Stmt.clearWarnings();
+
+                    Query = "SELECT Abalance ";
+                    Query += "FROM   accounts ";
+                    Query += "WHERE  Aid = " + aid;
+
+                    ResultSet RS = Stmt.executeQuery(Query);
+
+                    Stmt.clearWarnings();
+
+                    while (RS.next()) {
+                        aBalance = RS.getInt(1);
+                    }
+
+                    Query = "UPDATE tellers ";
+                    Query += "SET    Tbalance = Tbalance + " + delta + " ";
+                    Query += "WHERE  Tid = " + tid;
+
+                    Stmt.executeUpdate(Query);
+                    Stmt.clearWarnings();
+
+                    Query = "UPDATE branches ";
+                    Query += "SET    Bbalance = Bbalance + " + delta + " ";
+                    Query += "WHERE  Bid = " + bid;
+
+                    Stmt.executeUpdate(Query);
+                    Stmt.clearWarnings();
+
+                    Query = "INSERT INTO history(Tid, Bid, Aid, delta) ";
+                    Query += "VALUES (";
+                    Query += tid + ",";
+                    Query += bid + ",";
+                    Query += aid + ",";
+                    Query += delta + ")";
+
+                    Stmt.executeUpdate(Query);
+                    Stmt.clearWarnings();
+                    Stmt.close();
+                }
+
+                if (transactions) {
+                    Conn.commit();
+                }
+
+                return aBalance;
+            } catch (Exception E) {
+                if (verbose) {
+                    System.out.println("Transaction failed: "
+                                       + E.getMessage());
+                    E.printStackTrace();
+                }
+
+                incrementFailedTransactionCount();
+
+                if (transactions) {
+                    try {
+                        Conn.rollback();
+                    } catch (SQLException E1) {}
+                }
+            }
+
+            return 0;
+        }    /* end of DoOne         */
+    }    /* end of class ClientThread */
+
+    class MemoryWatcherThread extends Thread {
+
+        long    min          = 0;
+        long    max          = 0;
+        boolean keep_running = true;
+
+        public MemoryWatcherThread() {
+
+            this.reset();
+
+            keep_running = true;
+        }
+
+        public void reset() {
+
+            System.gc();
+
+            long currentFree  = Runtime.getRuntime().freeMemory();
+            long currentAlloc = Runtime.getRuntime().totalMemory();
+
+            min = max = (currentAlloc - currentFree);
+        }
+
+        public void end() {
+            keep_running = false;
+        }
+
+        public void run() {
+
+            while (keep_running) {
+                long currentFree  = Runtime.getRuntime().freeMemory();
+                long currentAlloc = Runtime.getRuntime().totalMemory();
+                long used         = currentAlloc - currentFree;
+
+                if (used < min) {
+                    min = used;
+                }
+
+                if (used > max) {
+                    max = used;
+                }
+
+                try {
+                    sleep(100);
+                } catch (InterruptedException E) {}
+            }
+        }
+    }    /* end of class MemoryWatcherThread */
+}
diff --git a/src/org/hsqldb/test/TestAcl.java b/src/org/hsqldb/test/TestAcl.java
new file mode 100644
index 0000000..3252534
--- /dev/null
+++ b/src/org/hsqldb/test/TestAcl.java
@@ -0,0 +1,426 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.hsqldb.server.ServerAcl;
+
+import junit.framework.Test;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.FileWriter;
+import java.net.InetAddress;
+import java.util.List;
+import java.util.ArrayList;
+
+public class TestAcl extends junit.framework.TestCase {
+
+    private ServerAcl   aclDefault          = null;
+    private ServerAcl[] aclPermitLocalhosts = null;
+    private ServerAcl[] aclPermitLocalNets  = null;
+    private ServerAcl[] aclDenyLocalNets    = null;
+    private ServerAcl[] aclDenyLocalhosts   = null;
+    private ServerAcl[] aclPermitAlls       = null;
+    private ServerAcl[] aclDenyAlls         = null;
+    private InetAddress localhostByName = InetAddress.getByName("localhost");
+    private InetAddress localhostByAddr = InetAddress.getByAddress(new byte[] {
+        127, 0, 0, 1
+    });
+
+    // Can't depend on any other host name being resolvable :(
+    private InetAddress otherHostByAddr = InetAddress.getByAddress(new byte[] {
+        1, 2, 3, 4
+    });
+
+    public TestAcl() throws IOException, ServerAcl.AclFormatException {
+        commonSetup();
+    }
+
+    public TestAcl(String s) throws IOException, ServerAcl.AclFormatException {
+
+        super(s);
+
+        commonSetup();
+    }
+
+    private void commonSetup()
+    throws IOException, ServerAcl.AclFormatException {
+
+        boolean     verbose = System.getProperty("VERBOSE") != null;
+        File        file;
+        PrintWriter pw;
+        List        acls = new ArrayList();
+
+        file = File.createTempFile("zero", ".txt");
+
+        file.deleteOnExit();
+        (new FileWriter(file)).close();
+
+        aclDefault = new ServerAcl(file);
+
+        if (verbose) {
+            aclDefault.setPrintWriter(new PrintWriter(System.out));
+        }
+
+        acls.clear();
+
+        file = File.createTempFile("aclDenyAll1", ".txt");
+
+        file.deleteOnExit();
+
+        pw = new PrintWriter(new FileWriter(file));
+
+        pw.println("# Deny all test ACL\n");
+        pw.println("deny 0.0.0.0/0");
+        pw.close();
+        acls.add(new ServerAcl(file));
+
+        aclDenyAlls = (ServerAcl[]) acls.toArray(new ServerAcl[0]);
+
+        if (verbose) {
+            for (int i = 0; i < aclDenyAlls.length; i++) {
+                aclDenyAlls[i].setPrintWriter(new PrintWriter(System.out));
+            }
+        }
+
+        acls.clear();
+
+        file = File.createTempFile("aclPermitLocalhost1", ".txt");
+
+        file.deleteOnExit();
+
+        pw = new PrintWriter(new FileWriter(file));
+
+        pw.println("# Permit Localhost test ACL\n");
+        pw.println("permit 127.0.0.1");
+        pw.close();
+        acls.add(new ServerAcl(file));
+
+        file = File.createTempFile("aclPermitLocalhost2", ".txt");
+
+        file.deleteOnExit();
+
+        pw = new PrintWriter(new FileWriter(file));
+
+        pw.println("# Permit Localhost test ACL\n");
+        pw.println("permit 127.0.0.1/32");
+        pw.close();
+        acls.add(new ServerAcl(file));
+
+        aclPermitLocalhosts = (ServerAcl[]) acls.toArray(new ServerAcl[0]);
+
+        if (verbose) {
+            for (int i = 0; i < aclPermitLocalhosts.length; i++) {
+                aclPermitLocalhosts[i].setPrintWriter(
+                    new PrintWriter(System.out));
+            }
+        }
+
+        acls.clear();
+
+        file = File.createTempFile("aclPermitLocalNet1", ".txt");
+
+        file.deleteOnExit();
+
+        pw = new PrintWriter(new FileWriter(file));
+
+        pw.println("# Permit Local Net test ACL\n");
+        pw.println("permit 127.0.0.0/24");
+        pw.close();
+        acls.add(new ServerAcl(file));
+
+        aclPermitLocalNets = (ServerAcl[]) acls.toArray(new ServerAcl[0]);
+
+        if (verbose) {
+            for (int i = 0; i < aclPermitLocalNets.length; i++) {
+                aclPermitLocalNets[i].setPrintWriter(
+                    new PrintWriter(System.out));
+            }
+        }
+
+        acls.clear();
+
+        file = File.createTempFile("aclDenyLocalNet1", ".txt");
+
+        file.deleteOnExit();
+
+        pw = new PrintWriter(new FileWriter(file));
+
+        pw.println("# Deny Local Net test ACL\n");
+        pw.println("deny 127.0.0.0/24");
+        pw.println("allow 0.0.0.0/0");
+        pw.close();
+        acls.add(new ServerAcl(file));
+
+        aclDenyLocalNets = (ServerAcl[]) acls.toArray(new ServerAcl[0]);
+
+        if (verbose) {
+            for (int i = 0; i < aclDenyLocalNets.length; i++) {
+                aclDenyLocalNets[i].setPrintWriter(
+                    new PrintWriter(System.out));
+            }
+        }
+
+        acls.clear();
+
+        file = File.createTempFile("aclDenyLocalhost1", ".txt");
+
+        file.deleteOnExit();
+
+        pw = new PrintWriter(new FileWriter(file));
+
+        pw.println("# Deny Localhost test ACL\n");
+        pw.println("deny 127.0.0.1/32");
+        pw.println("allow 0.0.0.0/0");
+        pw.close();
+        acls.add(new ServerAcl(file));
+
+        aclDenyLocalhosts = (ServerAcl[]) acls.toArray(new ServerAcl[0]);
+
+        if (verbose) {
+            for (int i = 0; i < aclDenyLocalhosts.length; i++) {
+                aclDenyLocalhosts[i].setPrintWriter(
+                    new PrintWriter(System.out));
+            }
+        }
+
+        acls.clear();
+
+        file = File.createTempFile("aclPermitAll1", ".txt");
+
+        file.deleteOnExit();
+
+        pw = new PrintWriter(new FileWriter(file));
+
+        pw.println("# Permit all test ACL\n");
+        pw.println("permit 0.0.0.0/0");
+        pw.close();
+        acls.add(new ServerAcl(file));
+
+        aclPermitAlls = (ServerAcl[]) acls.toArray(new ServerAcl[0]);
+
+        if (verbose) {
+            for (int i = 0; i < aclPermitAlls.length; i++) {
+                aclPermitAlls[i].setPrintWriter(new PrintWriter(System.out));
+            }
+        }
+    }
+
+    /**
+     * This method allows to easily run this unit test independent of the other
+     * unit tests, and without dealing with Ant or unrelated test suites.
+     */
+    static public void main(String[] sa) {
+            junit.textui.TestRunner runner = new junit.textui.TestRunner();
+            junit.framework.TestResult result =
+                runner.run(runner.getTest(TestAcl.class.getName()));
+
+            System.exit(result.wasSuccessful() ? 0 : 1);
+    }
+
+    public void testDefaultWithNames() {
+        assertFalse("Permitting access from localhost with default ACL",
+                    aclDefault.permitAccess(localhostByName.getAddress()));
+    }
+
+    public void testDefaultWithIPs() {
+
+        assertFalse("Permitting access from localhost with default ACL",
+                    aclDefault.permitAccess(localhostByAddr.getAddress()));
+        assertFalse("Permitting access from other host with default ACL",
+                    aclDefault.permitAccess(otherHostByAddr.getAddress()));
+    }
+
+    public void testDenyAllWithNames() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclDenyAlls.length; i++) {
+            acl = (ServerAcl) aclDenyAlls[i];
+
+            assertFalse("Permitting access from localhost with deny-all ACL",
+                        acl.permitAccess(localhostByName.getAddress()));
+        }
+    }
+
+    public void testDenyAllWithIPs() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclDenyAlls.length; i++) {
+            acl = (ServerAcl) aclDenyAlls[i];
+
+            assertFalse("Permitting access from localhost with deny-all ACL",
+                        acl.permitAccess(localhostByAddr.getAddress()));
+            assertFalse("Permitting access from other host with deny-all ACL",
+                        acl.permitAccess(otherHostByAddr.getAddress()));
+        }
+    }
+
+    public void testLocalhostOnlyWithNames() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclPermitLocalhosts.length; i++) {
+            acl = (ServerAcl) aclPermitLocalhosts[i];
+
+            assertTrue(
+                "Denying access from localhost with localhost-permit ACL",
+                acl.permitAccess(localhostByName.getAddress()));
+        }
+    }
+
+    public void testLocalhostOnlyWithIPs() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclPermitLocalhosts.length; i++) {
+            acl = (ServerAcl) aclPermitLocalhosts[i];
+
+            assertTrue(
+                "Denying access from localhost with localhost-permit ACL",
+                acl.permitAccess(localhostByAddr.getAddress()));
+            assertFalse(
+                "Permitting access from other host with localhost-permit ACL",
+                acl.permitAccess(otherHostByAddr.getAddress()));
+        }
+    }
+
+    public void testNoLocalhostOnlyWithNames() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclDenyLocalhosts.length; i++) {
+            acl = (ServerAcl) aclDenyLocalhosts[i];
+
+            assertFalse(
+                "Permitting access from localhost with localhost-deny ACL",
+                acl.permitAccess(localhostByName.getAddress()));
+        }
+    }
+
+    public void testNoLocalhostOnlyWithIPs() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclDenyLocalhosts.length; i++) {
+            acl = (ServerAcl) aclDenyLocalhosts[i];
+
+            assertFalse(
+                "Permitting access from localhost with localhost-deny ACL",
+                acl.permitAccess(localhostByAddr.getAddress()));
+            assertTrue(
+                "Denying access from other host with localhost-deny ACL",
+                acl.permitAccess(otherHostByAddr.getAddress()));
+        }
+    }
+
+    public void testLocalNetOnlyWithNames() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclPermitLocalNets.length; i++) {
+            acl = (ServerAcl) aclPermitLocalNets[i];
+
+            assertTrue("Denying access from localNet with localNet-permit ACL",
+                       acl.permitAccess(localhostByName.getAddress()));
+        }
+    }
+
+    public void testLocalNetOnlyWithIPs() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclPermitLocalNets.length; i++) {
+            acl = (ServerAcl) aclPermitLocalNets[i];
+
+            assertTrue("Denying access from localNet with localNet-permit ACL",
+                       acl.permitAccess(localhostByAddr.getAddress()));
+            assertFalse(
+                "Permitting access from other Net with localNet-permit ACL",
+                acl.permitAccess(otherHostByAddr.getAddress()));
+        }
+    }
+
+    public void testNoLocalNetOnlyWithNames() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclDenyLocalNets.length; i++) {
+            acl = (ServerAcl) aclDenyLocalNets[i];
+
+            assertFalse(
+                "Permitting access from localNet with localNet-deny ACL",
+                acl.permitAccess(localhostByName.getAddress()));
+        }
+    }
+
+    public void testNoLocalNetOnlyWithIPs() {
+
+        ServerAcl acl;
+
+        for (int i = 0; i < aclDenyLocalNets.length; i++) {
+            acl = (ServerAcl) aclDenyLocalNets[i];
+
+            assertFalse(
+                "Permitting access from localNet with localNet-deny ACL",
+                acl.permitAccess(localhostByAddr.getAddress()));
+            assertTrue("Denying access from other Net with localNet-deny ACL",
+                       acl.permitAccess(otherHostByAddr.getAddress()));
+        }
+    }
+
+    static public Test suite()
+    throws IOException, ServerAcl.AclFormatException {
+
+        TestSuite newSuite = new TestSuite();
+
+        newSuite.addTest(new TestAcl("testDefaultWithNames"));
+        newSuite.addTest(new TestAcl("testDefaultWithIPs"));
+        newSuite.addTest(new TestAcl("testDenyAllWithNames"));
+        newSuite.addTest(new TestAcl("testDenyAllWithIPs"));
+        newSuite.addTest(new TestAcl("testLocalhostOnlyWithNames"));
+        newSuite.addTest(new TestAcl("testLocalhostOnlyWithIPs"));
+        newSuite.addTest(new TestAcl("testNoLocalhostOnlyWithNames"));
+        newSuite.addTest(new TestAcl("testNoLocalhostOnlyWithIPs"));
+        newSuite.addTest(new TestAcl("testLocalNetOnlyWithNames"));
+        newSuite.addTest(new TestAcl("testLocalNetOnlyWithIPs"));
+        newSuite.addTest(new TestAcl("testNoLocalNetOnlyWithNames"));
+        newSuite.addTest(new TestAcl("testNoLocalNetOnlyWithIPs"));
+
+        return newSuite;
+    }
+}
diff --git a/src/org/hsqldb/test/TestAllTypes.java b/src/org/hsqldb/test/TestAllTypes.java
new file mode 100644
index 0000000..4cf373d
--- /dev/null
+++ b/src/org/hsqldb/test/TestAllTypes.java
@@ -0,0 +1,453 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Random;
+
+import org.hsqldb.lib.StopWatch;
+
+/**
+ * Test large tables containing columns of different types.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ */
+public class TestAllTypes {
+
+    protected String url = "jdbc:hsqldb:";
+
+//    protected String filepath = ".";
+    protected String filepath = "/hsql/testalltypes/test";
+
+//    protected String filepath = "hsql://localhost/yourtest";
+    boolean    network = true;
+    String     user;
+    String     password;
+    Statement  sStatement;
+    Connection cConnection;
+
+    // prameters
+    boolean reportProgress  = false;
+    boolean cachedTable     = true;
+    int     cacheScale      = 12;
+    int     logType         = 3;
+    int     writeDelay      = 60;
+    boolean indexZip        = true;
+    boolean indexLastName   = false;
+    boolean addForeignKey   = false;
+    boolean refIntegrity    = true;
+    boolean createTempTable = false;
+
+    // introduces fragmentation to the .data file
+    boolean deleteWhileInsert         = false;
+    int     deleteWhileInsertInterval = 10000;
+
+    //
+    int bigrows = 1000;
+
+    protected void setUp() {
+
+        user     = "sa";
+        password = "";
+
+        try {
+            sStatement  = null;
+            cConnection = null;
+
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            boolean createDatabase = false;
+
+            if (!network) {
+                File file = new File(filepath);
+
+                createDatabase = !file.exists();
+            }
+
+            if (createDatabase) {
+                cConnection = DriverManager.getConnection(url + filepath,
+                        user, password);
+                sStatement = cConnection.createStatement();
+
+                sStatement.execute("SET SCRIPTFORMAT " + logType);
+                sStatement.execute("SET LOGSIZE " + 400);
+                sStatement.execute("SET WRITE_DELAY " + writeDelay);
+                sStatement.execute("SET PROPERTY \"hsqldb.cache_scale\" 16;");
+                sStatement.execute("SHUTDOWN");
+                cConnection.close();
+
+                cConnection = DriverManager.getConnection(url + filepath,
+                        user, password);
+                sStatement = cConnection.createStatement();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("TestSql.setUp() error: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Fill up the cache
+     *
+     *
+     */
+    public void testFillUp() {
+
+        StopWatch sw        = new StopWatch();
+        int       smallrows = 0xfff;
+        double    value     = 0;
+        String ddl1 = "DROP TABLE test IF EXISTS;"
+                      + "DROP TABLE zip IF EXISTS;";
+        String ddl2 = "CREATE TABLE zip( zip INT IDENTITY );";
+        String ddl3 = "CREATE " + (cachedTable ? "CACHED "
+                                               : "") + "TABLE test( id INT IDENTITY,"
+                                                   + " firstname VARCHAR, "
+                                                   + " lastname VARCHAR, "
+                                                   + " zip INTEGER, "
+                                                   + " longfield BIGINT, "
+                                                   + " doublefield DOUBLE, "
+                                                   + " bigdecimalfield DECIMAL, "
+                                                   + " datefield DATE, "
+                                                   + " filler VARCHAR); ";
+
+        // adding extra index will slow down inserts a bit
+        String ddl4 = "CREATE INDEX idx1 ON TEST (lastname);";
+
+        // adding this index will slow down  inserts a lot
+        String ddl5 = "CREATE INDEX idx2 ON TEST (zip);";
+
+        // referential integrity checks will slow down inserts a bit
+        String ddl6 =
+            "ALTER TABLE test add constraint c1 FOREIGN KEY (zip) REFERENCES zip(zip);";
+        String filler = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+        try {
+            System.out.println("Connecting");
+            sw.zero();
+
+            cConnection = null;
+            sStatement  = null;
+            cConnection = DriverManager.getConnection(url + filepath, user,
+                    password);
+
+            System.out.println("connected: " + sw.elapsedTime());
+            sw.zero();
+
+            sStatement = cConnection.createStatement();
+
+            java.util.Random randomgen = new java.util.Random();
+
+            sStatement.execute(ddl1);
+            sStatement.execute(ddl2);
+            sStatement.execute(ddl3);
+            System.out.println("test table with no index");
+
+            if (indexLastName) {
+                sStatement.execute(ddl4);
+                System.out.println("create index on lastname");
+            }
+
+            if (indexZip) {
+                sStatement.execute(ddl5);
+                System.out.println("create index on zip");
+            }
+
+            if (addForeignKey) {
+                sStatement.execute(ddl6);
+                System.out.println("add foreign key");
+            }
+
+            int i;
+
+            for (i = 0; i <= smallrows; i++) {
+                sStatement.execute("INSERT INTO zip VALUES(null);");
+            }
+
+            PreparedStatement ps = cConnection.prepareStatement(
+                "INSERT INTO test (firstname,lastname,zip,longfield,doublefield,bigdecimalfield,datefield,filler) VALUES (?,?,?,?,?,?,?,?)");
+
+            ps.setString(1, "Julia");
+            ps.setString(2, "Clancy");
+
+            for (i = 0; i < bigrows; i++) {
+                ps.setInt(3, nextIntRandom(randomgen, smallrows));
+
+                int nextrandom   = nextIntRandom(randomgen, filler.length());
+                int randomlength = nextIntRandom(randomgen, filler.length());
+
+                ps.setLong(4, randomgen.nextLong());
+                ps.setDouble(5, randomgen.nextDouble());
+                ps.setBigDecimal(6, null);
+
+//                ps.setDouble(6, randomgen.nextDouble());
+                ps.setDate(7, new java.sql.Date(nextIntRandom(randomgen, 1000)
+                                                * 24L * 3600 * 1000));
+
+                String varfiller = filler.substring(0, randomlength);
+
+                ps.setString(8, nextrandom + varfiller);
+                ps.execute();
+
+                if (reportProgress && (i + 1) % 10000 == 0) {
+                    System.out.println("Insert " + (i + 1) + " : "
+                                       + sw.elapsedTime());
+                }
+
+                // delete and add 4000 rows to introduce fragmentation
+                if (deleteWhileInsert && i != 0
+                        && i % deleteWhileInsertInterval == 0) {
+                    sStatement.execute("CALL IDENTITY();");
+
+                    ResultSet rs = sStatement.getResultSet();
+
+                    rs.next();
+
+                    int lastId = rs.getInt(1);
+
+                    sStatement.execute(
+                        "SELECT * INTO TEMP tempt FROM test WHERE id > "
+                        + (lastId - 4000) + " ;");
+                    sStatement.execute("DELETE FROM test WHERE id > "
+                                       + (lastId - 4000) + " ;");
+                    sStatement.execute(
+                        "INSERT INTO test SELECT * FROM tempt;");
+                    sStatement.execute("DROP TABLE tempt;");
+                }
+            }
+
+//            sStatement.execute("INSERT INTO test SELECT * FROM temptest;");
+//            sStatement.execute("DROP TABLE temptest;");
+//            sStatement.execute(ddl7);
+            System.out.println("Total insert: " + i);
+            System.out.println("Insert time: " + sw.elapsedTime() + " rps: "
+                               + (i * 1000 / sw.elapsedTime()));
+            sw.zero();
+
+            if (!network) {
+                sStatement.execute("SHUTDOWN");
+            }
+
+            cConnection.close();
+            System.out.println("Shutdown Time: " + sw.elapsedTime());
+        } catch (SQLException e) {
+            System.out.println(e.getMessage());
+        }
+    }
+
+    protected void tearDown() {}
+
+    protected void checkResults() {
+
+        try {
+            StopWatch sw = new StopWatch();
+            ResultSet rs;
+
+            cConnection = DriverManager.getConnection(url + filepath, user,
+                    password);
+
+            System.out.println("Reopened database: " + sw.elapsedTime());
+            sw.zero();
+
+            sStatement = cConnection.createStatement();
+
+            sStatement.execute("SET WRITE_DELAY " + writeDelay);
+
+            // the tests use different indexes
+            // use primary index
+            sStatement.execute("SELECT count(*) from TEST");
+
+            rs = sStatement.getResultSet();
+
+            rs.next();
+            System.out.println("Row Count: " + rs.getInt(1));
+            System.out.println("Time to count: " + sw.elapsedTime());
+
+            // use index on zip
+            sw.zero();
+            sStatement.execute("SELECT count(*) from TEST where zip > -1");
+
+            rs = sStatement.getResultSet();
+
+            rs.next();
+            System.out.println("Row Count: " + rs.getInt(1));
+            System.out.println("Time to count: " + sw.elapsedTime());
+            checkSelects();
+            checkUpdates();
+            sw.zero();
+            cConnection.close();
+            System.out.println("Closed connection: " + sw.elapsedTime());
+        } catch (SQLException e) {
+            System.out.println(e.getMessage());
+        }
+    }
+
+    private void checkSelects() {
+
+        StopWatch        sw        = new StopWatch();
+        int              smallrows = 0xfff;
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+
+        try {
+            for (; i < bigrows; i++) {
+                PreparedStatement ps = cConnection.prepareStatement(
+                    "SELECT TOP 1 firstname,lastname,zip,filler FROM test WHERE zip = ?");
+
+                ps.setInt(1, nextIntRandom(randomgen, smallrows));
+                ps.execute();
+
+                if ((i + 1) == 100 && sw.elapsedTime() > 5000) {
+                    slow = true;
+                }
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Select " + (i + 1) + " : "
+                                       + sw.elapsedTime() + " rps: "
+                                       + (i * 1000 / sw.elapsedTime()));
+                }
+            }
+        } catch (SQLException e) {}
+
+        System.out.println("Select random zip " + i + " rows : "
+                           + sw.elapsedTime() + " rps: "
+                           + (i * 1000 / sw.elapsedTime()));
+        sw.zero();
+
+        try {
+            for (i = 0; i < bigrows; i++) {
+                PreparedStatement ps = cConnection.prepareStatement(
+                    "SELECT firstname,lastname,zip,filler FROM test WHERE id = ?");
+
+                ps.setInt(1, nextIntRandom(randomgen, bigrows - 1));
+                ps.execute();
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Select " + (i + 1) + " : "
+                                       + sw.elapsedTime());
+                }
+            }
+        } catch (SQLException e) {}
+
+        System.out.println("Select random id " + i + " rows : "
+                           + sw.elapsedTime() + " rps: "
+                           + (i * 1000 / sw.elapsedTime()));
+    }
+
+    private void checkUpdates() {
+
+        StopWatch        sw        = new StopWatch();
+        int              smallrows = 0xfff;
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+        int              count     = 0;
+
+        try {
+            for (; i < smallrows; i++) {
+                PreparedStatement ps = cConnection.prepareStatement(
+                    "UPDATE test SET filler = filler || zip WHERE zip = ?");
+                int random = nextIntRandom(randomgen, smallrows - 1);
+
+                ps.setInt(1, random);
+
+                count += ps.executeUpdate();
+
+                if (reportProgress && count % 10000 < 20) {
+                    System.out.println("Update " + count + " : "
+                                       + sw.elapsedTime());
+                }
+            }
+        } catch (SQLException e) {}
+
+        System.out.println("Update with random zip " + i
+                           + " UPDATE commands, " + count + " rows : "
+                           + sw.elapsedTime() + " rps: "
+                           + (count * 1000 / sw.elapsedTime()));
+        sw.zero();
+
+        try {
+            for (i = 0; i < bigrows; i++) {
+                PreparedStatement ps = cConnection.prepareStatement(
+                    "UPDATE test SET zip = zip + 1 WHERE id = ?");
+                int random = nextIntRandom(randomgen, bigrows - 1);
+
+                ps.setInt(1, random);
+                ps.execute();
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Update " + (i + 1) + " : "
+                                       + sw.elapsedTime() + " rps: "
+                                       + (i * 1000 / sw.elapsedTime()));
+                }
+            }
+        } catch (SQLException e) {}
+
+        System.out.println("Update with random id " + i + " rows : "
+                           + sw.elapsedTime() + " rps: "
+                           + (i * 1000 / sw.elapsedTime()));
+    }
+
+    int nextIntRandom(Random r, int range) {
+
+        int b = r.nextInt();
+
+        if (b == Integer.MIN_VALUE) {
+            b = Integer.MAX_VALUE;
+        }
+
+        b = Math.abs(b);
+
+        return b % range;
+    }
+
+    public static void main(String[] argv) {
+
+        StopWatch    sw   = new StopWatch();
+        TestAllTypes test = new TestAllTypes();
+
+        test.setUp();
+        test.testFillUp();
+        test.tearDown();
+        test.checkResults();
+        System.out.println("Total Test Time: " + sw.elapsedTime());
+    }
+}
diff --git a/src/org/hsqldb/test/TestAnother.java b/src/org/hsqldb/test/TestAnother.java
new file mode 100644
index 0000000..b2a8fc2
--- /dev/null
+++ b/src/org/hsqldb/test/TestAnother.java
@@ -0,0 +1,106 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import org.hsqldb.lib.StopWatch;
+
+public class TestAnother {
+
+    // fixed
+    protected String url = "jdbc:hsqldb:";
+
+//    protected String  filepath = "hsql://localhost/mytest";
+//    protected String filepath = "mem:test";
+    protected String filepath = "/hsql/testtime/test";
+
+    public TestAnother() {}
+
+    public void setUp() {
+
+        String user     = "sa";
+        String password = "";
+
+        try {
+            Connection conn = null;
+
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            conn = DriverManager.getConnection(url + filepath, user,
+                                               password);
+
+            Statement stmnt = conn.createStatement();
+            Statement st    = conn.createStatement();
+
+            st.executeUpdate("CREATE TABLE TT(D DATE)");
+            st.executeUpdate("INSERT INTO TT VALUES ('2004-01-02')");
+            st.executeUpdate("INSERT INTO TT VALUES ('2004-02-02')");
+
+            ResultSet rs = st.executeQuery("SELECT * FROM TT");
+
+            while (rs.next()) {
+                System.out.println(rs.getDate(1));
+            }
+
+            st.executeUpdate("DROP TABLE TT");
+            rs.close();
+
+            Statement stm = conn.createStatement();
+
+            stm.executeUpdate(
+                "create table test (id int,atime timestamp default current_timestamp)");
+
+            stm = conn.createStatement();
+
+            int count = stm.executeUpdate("insert into test (id) values (1)");
+
+            System.out.println(count);
+            conn.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("TestSql.setUp() error: " + e.getMessage());
+        }
+    }
+
+    public static void main(String[] argv) {
+
+        StopWatch   sw   = new StopWatch();
+        TestAnother test = new TestAnother();
+
+        test.setUp();
+        System.out.println("Total Test Time: " + sw.elapsedTime());
+    }
+}
diff --git a/src/org/hsqldb/test/TestBase.java b/src/org/hsqldb/test/TestBase.java
new file mode 100644
index 0000000..1ecb4c9
--- /dev/null
+++ b/src/org/hsqldb/test/TestBase.java
@@ -0,0 +1,155 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.lang.reflect.Constructor;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import org.hsqldb.server.Server;
+import org.hsqldb.server.WebServer;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * HSQLDB TestBugBase Junit test case. <p>
+ *
+ * @author  boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public abstract class TestBase extends TestCase {
+
+    //  change the url to reflect your preferred db location and name
+    String  serverProps;
+    String  url;
+    String  user     = "sa";
+    String  password = "";
+    Server  server;
+    boolean isNetwork = true;
+    boolean isHTTP    = false;
+
+    public TestBase(String name) {
+        super(name);
+    }
+
+    public TestBase(String name, String url, boolean isNetwork,
+                    boolean isHTTP) {
+
+        super(name);
+
+        this.isNetwork = isNetwork;
+        this.url       = url;
+        this.isHTTP    = isHTTP;
+    }
+
+    protected void setUp() {
+
+        if (isNetwork) {
+            if (url == null) {
+                url = isHTTP ? "jdbc:hsqldb:http://localhost/test"
+                             : "jdbc:hsqldb:hsql://localhost/test";
+            }
+
+            server = isHTTP ? new WebServer()
+                            : new Server();
+
+            server.setDatabaseName(0, "test");
+            server.setDatabasePath(0, "mem:test;sql.enforce_strict_size=true");
+            server.setLogWriter(null);
+            server.setErrWriter(null);
+            server.start();
+        } else {
+            if (url == null) {
+                url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
+            }
+        }
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println(this + ".setUp() error: " + e.getMessage());
+        }
+    }
+
+    protected void tearDown() {
+
+        if (isNetwork) {
+            server.stop();
+
+            server = null;
+        }
+    }
+
+    Connection newConnection() throws SQLException {
+        return DriverManager.getConnection(url, user, password);
+    }
+
+    public static void runWithResult(Class testCaseClass, String testName) {
+
+        try {
+            Constructor ctor = testCaseClass.getConstructor(new Class[]{
+                String.class });
+            TestBase theTest = (TestBase) ctor.newInstance(new Object[]{
+                testName });
+
+            theTest.runWithResult();
+        } catch (Exception ex) {
+            System.err.println("couldn't execute test:");
+            ex.printStackTrace(System.err);
+        }
+    }
+
+    public void runWithResult() {
+
+        TestResult result   = run();
+        String     testName = this.getClass().getName();
+
+        if (testName.startsWith("org.hsqldb.test.")) {
+            testName = testName.substring(16);
+        }
+
+        testName += "." + getName();
+
+        int failureCount = result.failureCount();
+
+        System.out.println(testName + " failure count: " + failureCount);
+
+        java.util.Enumeration failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.err.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestBatchBug.java b/src/org/hsqldb/test/TestBatchBug.java
new file mode 100644
index 0000000..3904490
--- /dev/null
+++ b/src/org/hsqldb/test/TestBatchBug.java
@@ -0,0 +1,232 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+
+public class TestBatchBug {
+
+    static final int    DATASET_COUNT              = 2;
+    static final int    DECIMAL_FIELDS_PER_DATASET = 2;
+    static final String TABLE_ATTR_CACHED          = "CACHED";
+    static final String IN_PROCESS_FILE_URL =
+        "jdbc:hsqldb:/hsql/testbatch/perftest";
+    static final String HSQLDB_LOCALHOST_URL =
+        "jdbc:hsqldb:hsql://localhost/yourtest";
+    ;
+    static final String TEST_TABLE_NAME       = "CSBug";
+    static String       FIELD_LIST_WITHOUT_ID = "Kennung, Last_Update ";
+
+// wird in static {} erweitert:
+    static String FIELD_LIST_WITH_ID    = "ID, ";
+    static String SQL_SELECT_ALL_FIELDS = "SELECT ";
+
+// wird in static {} erweitert:
+    static {
+        for (int i = 1; i <= DECIMAL_FIELDS_PER_DATASET; i++) {
+            FIELD_LIST_WITHOUT_ID += ", Field_" + i;
+        }
+
+        FIELD_LIST_WITH_ID += FIELD_LIST_WITHOUT_ID;
+        SQL_SELECT_ALL_FIELDS += FIELD_LIST_WITH_ID + " FROM "
+                                 + TEST_TABLE_NAME;
+    }
+
+    static int ldfNrFuerKennung;
+
+    public static void main(String[] arg) {
+
+        try {
+
+// Load the HSQL Database Engine JDBC driver
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            String[] urls = {
+                IN_PROCESS_FILE_URL
+            };
+
+            for (int i = 0; i < urls.length; i++) {
+                String   url        = urls[i];
+                String[] tableAttrs = { TABLE_ATTR_CACHED };
+
+                for (int iAttr = 0; iAttr < tableAttrs.length; iAttr++) {
+                    testURL(url, "CACHED");
+                }
+            }
+
+            System.out.println("bye");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    static void testURL(String url, String tableAttr) throws SQLException {
+
+        System.out.println(url);
+
+        Connection con = DriverManager.getConnection(url, "sa", "");
+
+        reCreateTable(con, "CACHED");
+        populateTable(con);
+        con.close();
+    }
+
+    static void reCreateTable(Connection con,
+                              String tableAttr) throws SQLException {
+
+        String cvsFileName = TEST_TABLE_NAME + ".csv";
+
+// Create a statement object
+        Statement stmt = con.createStatement();
+
+// Try to drop the table
+        try {
+
+            stmt.executeUpdate("DROP TABLE " + TEST_TABLE_NAME + " IF EXISTS");
+        } catch (SQLException e) {    // Ignore Exception, because the table may not yet exist
+            System.out.println(e.getMessage());
+        }
+
+        StringBuffer sql = new StringBuffer();
+
+        sql.append("CREATE ");
+        sql.append(tableAttr);    // z.B. "CACHED"
+        sql.append(" TABLE ");
+        sql.append(TEST_TABLE_NAME);
+        sql.append(" (");
+        sql.append("Id integer IDENTITY");
+        sql.append(", ");
+        sql.append("Kennung varchar(20) NOT NULL");
+
+// etwas andere Schreibweise von CURRENT TIMESTAMP
+        sql.append(", last_update TIMESTAMP ");
+        sql.append("DEFAULT CURRENT_TIMESTAMP NOT NULL");
+
+        for (int i = 1; i <= DECIMAL_FIELDS_PER_DATASET; i++) {
+            sql.append(", Field_" + i + " decimal");
+        }
+
+        sql.append(", UNIQUE(Kennung)");
+        sql.append(")");
+        System.out.println(sql.toString());
+        stmt.executeUpdate(sql.toString());
+
+// CLEAR TABLE
+        sql = new StringBuffer();
+
+        sql.append("DELETE FROM ");
+        sql.append(TEST_TABLE_NAME);
+        System.out.println(sql.toString());
+        stmt.executeUpdate(sql.toString());
+        stmt.close();    // is no longer used
+    }
+
+// tries to enter 2 records
+    static void populateTable(Connection con) throws SQLException {
+
+        long      startTime = System.currentTimeMillis();
+        Timestamp now       = new Timestamp(startTime);
+
+        con.setAutoCommit(false);
+
+        String            sql  = createInsertSQL(true, false);
+        PreparedStatement prep = con.prepareStatement(sql);
+
+        prep.clearParameters();
+        prep.setString(1, "xxx");
+        prep.setTimestamp(2, now);    // last_update
+
+        for (int ii = 0; ii < DECIMAL_FIELDS_PER_DATASET; ii++) {
+            prep.setDouble(ii + 3, 0.123456789);    // Wert
+        }
+
+        prep.addBatch();
+        prep.setString(1, "yyy");
+        prep.setTimestamp(2, now);    // last_update
+
+        for (int ii = 0; ii < DECIMAL_FIELDS_PER_DATASET; ii++) {
+            prep.setDouble(ii + 3, 0.123456789);    // Wert
+        }
+
+        prep.addBatch();
+
+        int[] updateCounts = prep.executeBatch();
+
+        con.setAutoCommit(true);
+        prep.close();
+    }
+
+    static String createInsertSQL(boolean prepStmt,
+                                  boolean getIdAfterInsert) {
+
+        StringBuffer sql = new StringBuffer();
+
+        sql.append("INSERT INTO ");
+        sql.append(TEST_TABLE_NAME);
+        sql.append(" (");
+        sql.append(FIELD_LIST_WITHOUT_ID);
+        sql.append(") VALUES (");
+
+        Timestamp now = new Timestamp(System.currentTimeMillis());
+        Object    val = "?";
+
+        if (prepStmt) {
+            sql.append(val + ", " + val);
+        } else {
+            long millis = System.currentTimeMillis();
+
+            sql.append("'Ken");
+            sql.append((++ldfNrFuerKennung) + "'");
+
+            val = new Double(0.123456789) + "";
+
+            sql.append(", '" + now.toString() + "'");
+        }
+
+        for (int i = 1; i <= DECIMAL_FIELDS_PER_DATASET; i++) {
+            sql.append(", " + val);
+        }
+
+        sql.append(")");
+
+        String ret = sql.toString();
+
+        System.out.println(ret);
+
+        return ret;
+    }
+}
diff --git a/src/org/hsqldb/test/TestBatchExecution.java b/src/org/hsqldb/test/TestBatchExecution.java
new file mode 100644
index 0000000..7c43688
--- /dev/null
+++ b/src/org/hsqldb/test/TestBatchExecution.java
@@ -0,0 +1,368 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.hsqldb.lib.StopWatch;
+
+/**
+ * A quick test of the new CompiledStatement and batch execution facilities.
+ *
+ * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+
+// fredt@users - modified to do some network connection and generated result tests
+public class TestBatchExecution extends TestBase {
+
+    static final String drop_table_sql = "drop table test if exists";
+    static final String create_cached  = "create cached ";
+    static final String create_memory  = "create memory ";
+    static final String create_temp    = "create temp ";
+    static final String table_sql = "table test(id int identity primary key,"
+                                    + "fname varchar(20), lname "
+                                    + "varchar(20), zip int)";
+    static final String insert_sql = "insert into test values(?,?,?,?)";
+    static final String update_sql =
+        "update test set fname = 'Hans' where id = ?";
+    static final String select_sql   = "select * from test where id = ?";
+    static final String delete_sql   = "delete from test where id = ?";
+    static final String call_sql     = "call identity()";
+    static final String shutdown_sql = "shutdown compact";
+    static final String def_db_path  = "batchtest";
+    static final int    def_runs     = 5;
+    static final int    rows         = 10000;
+    static Connection   conn;
+    static Statement    stmnt;
+    static String       url;
+
+    public TestBatchExecution(String name) {
+        super(name);
+    }
+
+    public void test() throws Exception {
+
+        conn  = newConnection();
+        stmnt = conn.createStatement();
+        url   = super.url;
+
+        nonPreparedTest();
+        preparedTestOne(5);
+    }
+
+    static void print(String s) {
+        System.out.print(s);
+    }
+
+    static void println(String s) {
+        System.out.println(s);
+    }
+
+    static void printCommandStats(StopWatch sw, String cmd) {
+
+        long et = sw.elapsedTime();
+
+        print(sw.elapsedTimeToMessage(rows + " " + cmd));
+        println(" " + ((1000 * rows) / et) + " ops/s.");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        int    runs;
+        String db_path;
+        Driver driver;
+
+        runs    = def_runs;
+        db_path = def_db_path;
+
+        try {
+            runs = Integer.parseInt(args[0]);
+        } catch (Exception e) {}
+
+        db_path = "batchtest";
+        try {
+            db_path = args[1];
+        } catch (Exception e) {}
+
+        // get the connection and statement
+        driver =
+            (Driver) Class.forName("org.hsqldb.jdbc.JDBCDriver").newInstance();
+
+        DriverManager.registerDriver(driver);
+
+        url = "jdbc:hsqldb:file:" + db_path
+              + ";crypt_key=604a6105889da65326bf35790a923932;crypt_type=blowfish;hsqldb.default_table_type=cached;hsqldb.cache_rows=100"
+        ;
+        conn  = DriverManager.getConnection(url, "SA", "");
+        stmnt = conn.createStatement();
+
+        runTests(runs);
+    }
+
+    static void runTests(int runs) throws Exception {
+
+        println("");
+        println("***************************************");
+        println("featuring cached (persistent) table");
+        println("***************************************");
+
+        // drop and recreate the test table
+        println(drop_table_sql);
+        stmnt.execute(drop_table_sql);
+        println(create_cached + table_sql);
+        stmnt.execute(create_cached + table_sql);
+        preparedTestOne(runs);
+
+        // drop the test table and shut down database
+        println(drop_table_sql);
+        stmnt.execute(drop_table_sql);
+        println("---------------------------------------");
+        println("shutting down database");
+        stmnt.execute(shutdown_sql);
+        println("---------------------------------------");
+
+        // get the connection and statement
+        conn  = DriverManager.getConnection(url, "SA", "");
+        stmnt = conn.createStatement();
+
+        println("");
+        println("***************************************");
+        println("featuring memory (persistent) table");
+        println("***************************************");
+
+        // drop and recreate the test table
+        println(drop_table_sql);
+        stmnt.execute(drop_table_sql);
+        println(create_memory + table_sql);
+        stmnt.execute(create_memory + table_sql);
+        preparedTestOne(runs);
+
+        // drop the test table and shut down database
+        println(drop_table_sql);
+        stmnt.execute(drop_table_sql);
+        println("---------------------------------------");
+        println("shutting down database");
+        stmnt.execute(shutdown_sql);
+        println("---------------------------------------");
+
+        // get the connection and statement
+        conn  = DriverManager.getConnection(url, "SA", "");
+        stmnt = conn.createStatement();
+
+        println("");
+        println("***************************************");
+        println("featuring temp (transient) table");
+        println("***************************************");
+
+        // drop and recreate the test table
+        println(drop_table_sql);
+        stmnt.execute(drop_table_sql);
+        println(create_temp + table_sql);
+        stmnt.execute(create_temp + table_sql);
+        preparedTestOne(runs);
+
+        // drop the test table
+        println(drop_table_sql);
+        stmnt.execute(drop_table_sql);
+        println("---------------------------------------");
+        println("shutting down database");
+        stmnt.execute(shutdown_sql);
+        println("---------------------------------------");
+        preparedTestTwo();
+    }
+
+    public static void nonPreparedTest() throws Exception {
+
+        stmnt.addBatch(drop_table_sql);
+        stmnt.addBatch(create_memory + table_sql);
+        stmnt.executeBatch();
+    }
+
+    public static void preparedTestOne(int runs) throws Exception {
+
+        PreparedStatement insertStmnt;
+        PreparedStatement updateStmnt;
+        PreparedStatement selectStmnt;
+        PreparedStatement deleteStmnt;
+        PreparedStatement callStmnt;
+        StopWatch         sw;
+
+        println("---------------------------------------");
+        println("Preparing Statements:");
+        println("---------------------------------------");
+        println(insert_sql);
+        println(update_sql);
+        println(select_sql);
+        println(delete_sql);
+        println(call_sql);
+
+        sw = new StopWatch();
+
+        // prepare the statements
+        insertStmnt = conn.prepareStatement(insert_sql,
+                                            Statement.RETURN_GENERATED_KEYS);
+        updateStmnt = conn.prepareStatement(update_sql);
+        selectStmnt = conn.prepareStatement(select_sql);
+        deleteStmnt = conn.prepareStatement(delete_sql);
+        callStmnt   = conn.prepareCall(call_sql);
+
+        println("---------------------------------------");
+        println(sw.elapsedTimeToMessage("statements prepared"));
+        println("---------------------------------------");
+        sw.zero();
+
+        // set up the batch data
+        for (int i = 0; i < rows; i++) {
+            insertStmnt.setInt(1, i);
+            insertStmnt.setString(2, "Julia");
+            insertStmnt.setString(3, "Peterson-Clancy");
+            insertStmnt.setInt(4, i);
+            updateStmnt.setInt(1, i);
+            selectStmnt.setInt(1, i);
+            deleteStmnt.setInt(1, i);
+            insertStmnt.addBatch();
+            updateStmnt.addBatch();
+            selectStmnt.addBatch();
+            deleteStmnt.addBatch();
+            callStmnt.addBatch();
+        }
+
+        println("---------------------------------------");
+        println(sw.elapsedTimeToMessage("" + 5 * rows
+                                        + " batch entries created"));
+        sw.zero();
+
+        // do the test loop forever
+        for (int i = 0; i < 1; i++) {
+            println("---------------------------------------");
+
+            // inserts
+            sw.zero();
+            insertStmnt.executeBatch();
+            printCommandStats(sw, "inserts");
+
+            ResultSet    generated = insertStmnt.getGeneratedKeys();
+            StringBuffer sb        = new StringBuffer();
+
+            while (generated.next()) {
+                int gen = generated.getInt(1);
+
+                if (gen % 1000 == 0) {
+                    sb.append(gen).append(" - ");
+                }
+            }
+
+            System.out.println(sb.toString());
+            printCommandStats(sw, "generated reads");
+
+            // updates
+            sw.zero();
+            updateStmnt.executeBatch();
+            printCommandStats(sw, "updates");
+
+            // selects
+            sw.zero();
+
+//            selectStmnt.executeBatch();
+//            printCommandStats(sw, "selects");
+            // deletes
+            sw.zero();
+            deleteStmnt.executeBatch();
+            printCommandStats(sw, "deletes");
+
+            // calls
+            sw.zero();
+
+//            callStmnt.executeBatch();
+//            printCommandStats(sw, "calls  ");
+        }
+    }
+
+    public static void preparedTestTwo() {
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            Connection con = DriverManager.getConnection("jdbc:hsqldb:mem:.",
+                "sa", "");
+
+            System.out.println("con=" + con);
+
+            Statement stmt = con.createStatement();
+
+            try {
+                stmt.executeUpdate("drop table ttt");
+            } catch (Exception e) {}
+
+            stmt.executeUpdate("create table ttt (id integer)");
+
+            PreparedStatement prep =
+                con.prepareStatement("INSERT INTO ttt (id) VALUES (?)");
+
+            con.setAutoCommit(false);
+
+            for (int i = 1; i <= 4; i++) {    // [2, 3, 4]
+                prep.setInt(1, i);
+                prep.addBatch();
+                System.out.println("executeBatch() for " + i);
+                prep.executeBatch();
+                con.commit();
+
+                // prep.clearBatch(); // -> java.lang.NullPointerException
+                // at org.hsqldb.Result.getUpdateCounts(Unknown Source)
+            }
+
+            prep.close();
+
+            // see what we got
+            ResultSet rs = stmt.executeQuery("select * from ttt");
+
+            while (rs.next()) {
+                System.out.println("id = " + rs.getInt(1));
+            }
+
+            System.out.println("bye.");
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestBench.java b/src/org/hsqldb/test/TestBench.java
new file mode 100644
index 0000000..4fe1e15
--- /dev/null
+++ b/src/org/hsqldb/test/TestBench.java
@@ -0,0 +1,948 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+// nbazin@users - enhancements to the original code
+// fredt@users - 20050202 - corrected getRandomID(int) to return a randomly distributed value
+/*
+ *  This is a sample implementation of the Transaction Processing Performance
+ *  Council Benchmark B coded in Java and ANSI SQL2.
+ *
+ *  This version is using one connection per thread to parallellize
+ *  server operations.
+ * @author Mark Matthews (mark@mysql.com)
+ */
+import java.io.PrintStream;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Enumeration;
+import java.util.Vector;
+
+class TestBench {
+
+    /* tpc bm b scaling rules */
+    public static int tps       = 1;         /* the tps scaling factor: here it is 1 */
+    public static int nbranches = 1;         /* number of branches in 1 tps db       */
+    public static int ntellers  = 10;        /* number of tellers in  1 tps db       */
+    public static int naccounts = 100000;    /* number of accounts in 1 tps db       */
+    public static int nhistory = 864000;     /* number of history recs in 1 tps db   */
+    public static final int TELLER              = 0;
+    public static final int BRANCH              = 1;
+    public static final int ACCOUNT             = 2;
+    int                     failed_transactions = 0;
+    int                     transaction_count   = 0;
+    static int              n_clients           = 10;
+    static int              n_txn_per_client    = 10;
+    static boolean          count_results       = false;
+    long                    start_time          = 0;
+    static String           tableExtension      = "";
+    static String           createExtension     = "";
+    static String           ShutdownCommand     = "";
+    static boolean          verbose             = false;
+    MemoryWatcherThread     MemoryWatcher;
+
+    /* main program,    creates a 1-tps database:  i.e. 1 branch, 10 tellers,...
+     *                    runs one TPC BM B transaction
+     * example command line:
+     * -driver  org.hsqldb.jdbc.JDBCDriver -url jdbc:hsqldb:/hsql/jdbcbench/test -user SA -clients 20 -tpc 10000
+     */
+    public static void main(String[] Args) {
+
+        String  DriverName         = "";
+        String  DBUrl              = "";
+        String  DBUser             = "";
+        String  DBPassword         = "";
+        boolean initialize_dataset = true;
+
+        for (int i = 0; i < Args.length; i++) {
+            if (Args[i].equals("-clients")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    n_clients = Integer.parseInt(Args[i]);
+                }
+            } else if (Args[i].equals("-driver")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    DriverName = Args[i];
+
+                    if (DriverName.equals(
+                            "com.borland.datastore.jdbc.DataStoreDriver")) {}
+
+                    if (DriverName.equals("com.mckoi.JDBCDriver")) {
+                        ShutdownCommand = "SHUTDOWN";
+                    }
+
+                    if (DriverName.equals("org.hsqldb.jdbc.JDBCDriver")
+                            || DriverName.equals("org.hsqldb.jdbcDriver")) {}
+                }
+            } else if (Args[i].equals("-url")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    DBUrl = Args[i];
+                }
+            } else if (Args[i].equals("-user")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    DBUser = Args[i];
+                }
+            } else if (Args[i].equals("-password")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    DBPassword = Args[i];
+                }
+            } else if (Args[i].equals("-tpc")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    n_txn_per_client = Integer.parseInt(Args[i]);
+                }
+            } else if (Args[i].equals("-init")) {
+                initialize_dataset = true;
+            } else if (Args[i].equals("-tps")) {
+                if (i + 1 < Args.length) {
+                    i++;
+
+                    tps = Integer.parseInt(Args[i]);
+                }
+            } else if (Args[i].equals("-v")) {
+                verbose = true;
+            }
+        }
+
+        if (DriverName.length() == 0 || DBUrl.length() == 0) {
+            System.out.println(
+                "usage: java TestBench -driver [driver_class_name] -url [url_to_db] -user [username] -password [password] [-v] [-init] [-tpc n] [-clients n]");
+            System.out.println();
+            System.out.println("-v          verbose error messages");
+            System.out.println("-init       initialize the tables");
+            System.out.println("-tpc        transactions per client");
+            System.out.println("-clients    number of simultaneous clients");
+            System.exit(-1);
+        }
+
+        System.out.println(
+            "*********************************************************");
+        System.out.println(
+            "* TestBench v1.1                                        *");
+        System.out.println(
+            "*********************************************************");
+        System.out.println();
+        System.out.println("Driver: " + DriverName);
+        System.out.println("URL:" + DBUrl);
+        System.out.println();
+        System.out.println("Scale factor value: " + tps);
+        System.out.println("Number of clients: " + n_clients);
+        System.out.println("Number of transactions per client: "
+                           + n_txn_per_client);
+        System.out.println();
+
+        try {
+            Class.forName(DriverName);
+
+            TestBench Me = new TestBench(DBUrl, DBUser, DBPassword,
+                                         initialize_dataset);
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        }
+    }
+
+    public TestBench(String url, String user, String password, boolean init) {
+
+        Vector      vClient  = new Vector();
+        Thread      Client   = null;
+        Enumeration e        = null;
+        Connection  guardian = null;
+
+        try {
+            java.util.Date start = new java.util.Date();
+
+            if (init) {
+                System.out.println("Start: " + start.toString());
+                System.out.print("Initializing dataset...");
+                createDatabase(url, user, password);
+
+                double seconds = (System.currentTimeMillis() - start.getTime())
+                                 / 1000D;
+
+                System.out.println("done. in " + seconds + " seconds\n");
+                System.out.println("Complete: "
+                                   + (new java.util.Date()).toString());
+            }
+
+            System.out.println("* Starting Benchmark Run *");
+
+            MemoryWatcher = new MemoryWatcherThread();
+
+            MemoryWatcher.start();
+
+            long tempTime = System.currentTimeMillis();
+
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+
+            guardian = connect(url, user, password);
+
+            checkSums(guardian);
+            connectClose(guardian);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+            oneRound(url, user, password);
+
+            guardian = connect(url, user, password);
+
+            checkSums(guardian);
+            connectClose(guardian);
+
+            tempTime = System.currentTimeMillis() - tempTime;
+
+            System.out.println("Total time: " + tempTime / 1000D + " seconds");
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        } finally {
+            MemoryWatcher.end();
+
+            try {
+                MemoryWatcher.join();
+
+                if (ShutdownCommand.length() > 0) {
+                    guardian = connect(url, user, password);
+
+                    Statement Stmt = guardian.createStatement();
+
+                    Stmt.execute(ShutdownCommand);
+                    Stmt.close();
+                    connectClose(guardian);
+                }
+            } catch (Exception E1) {}
+
+//            System.exit(0);
+        }
+    }
+
+    void oneRound(String url, String user,
+                  String password) throws InterruptedException, SQLException {
+
+        Vector      vClient  = new Vector();
+        Thread      Client   = null;
+        Enumeration e        = null;
+        Connection  guardian = null;
+
+        //
+        start_time = System.currentTimeMillis();
+
+        for (int i = 0; i < n_clients; i++) {
+            Client = new ClientThread(n_txn_per_client, url, user, password,
+                                      Connection.TRANSACTION_READ_COMMITTED);
+
+            Client.start();
+            vClient.addElement(Client);
+        }
+
+        /*
+         ** Barrier to complete this test session
+         */
+        e = vClient.elements();
+
+        while (e.hasMoreElements()) {
+            Client = (Thread) e.nextElement();
+
+            Client.join();
+        }
+
+        vClient.removeAllElements();
+        reportDone();
+
+        guardian = connect(url, user, password);
+
+        if (count_results) {
+            checkSums(guardian);
+        }
+
+        connectClose(guardian);
+    }
+
+    public void reportDone() {
+
+        long end_time = System.currentTimeMillis();
+        double completion_time = ((double) end_time - (double) start_time)
+                                 / 1000;
+
+        System.out.println("\n* Benchmark Report *");
+        System.out.println("\n--------------------");
+        System.out.println("Time to execute " + transaction_count
+                           + " transactions: " + completion_time
+                           + " seconds.");
+        System.out.println("Max/Min memory usage: " + MemoryWatcher.max
+                           + " / " + MemoryWatcher.min + " kb");
+        System.out.println(failed_transactions + " / " + transaction_count
+                           + " failed to complete.");
+
+        double rate = (transaction_count - failed_transactions)
+                      / completion_time;
+
+        System.out.println("Transaction rate: " + rate + " txn/sec.");
+        System.out.print(MemoryWatcher.max + ";" + MemoryWatcher.min + ";"
+                         + failed_transactions + ";" + rate + "\n");
+
+        transaction_count   = 0;
+        failed_transactions = 0;
+
+        MemoryWatcher.reset();
+    }
+
+    public synchronized void incrementTransactionCount() {
+        transaction_count++;
+    }
+
+    public synchronized void incrementFailedTransactionCount() {
+        failed_transactions++;
+    }
+
+    void createDatabase(String url, String user,
+                        String password) throws Exception {
+
+        Connection Conn = connect(url, user, password);
+        String     s    = Conn.getMetaData().getDatabaseProductName();
+
+        System.out.println("DBMS: " + s);
+
+        try {
+            Conn.setAutoCommit(false);
+            System.out.println("In transaction mode");
+        } catch (SQLException Etrxn) {}
+
+        try {
+            int       accountsnb = 0;
+            Statement Stmt       = Conn.createStatement();
+            String    Query;
+
+//
+//            Stmt.execute("SET WRITE_DELAY 1000 MILLIS;");
+
+//            Stmt.execute("SET DATABASE DEFAULT TABLE TYPE CACHED");
+
+//
+            Query = "SELECT count(*) ";
+            Query += "FROM   accounts";
+
+            ResultSet RS = Stmt.executeQuery(Query);
+
+            Stmt.clearWarnings();
+
+            while (RS.next()) {
+                accountsnb = RS.getInt(1);
+            }
+
+            Conn.commit();
+            Stmt.close();
+
+            if (accountsnb == (naccounts * tps)) {
+                System.out.println("Already initialized");
+                connectClose(Conn);
+
+                return;
+            }
+        } catch (Exception E) {}
+
+        System.out.println("Drop old tables if they exist");
+
+        try {
+            Statement Stmt = Conn.createStatement();
+            String    Query;
+
+            Query = "DROP TABLE history";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DROP TABLE accounts";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DROP TABLE tellers";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DROP TABLE branches";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+            Conn.commit();
+            Stmt.close();
+        } catch (Exception E) {}
+
+        System.out.println("Creates tables");
+
+        try {
+            Statement Stmt = Conn.createStatement();
+            String    Query;
+
+            Query = "CREATE TABLE branches ( "
+                    + "Bid         INTEGER NOT NULL PRIMARY KEY, "
+                    + "Bbalance    INTEGER," + "filler      CHAR(88))";    /* pad to 100 bytes */
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "CREATE TABLE tellers ("
+                    + "Tid         INTEGER NOT NULL PRIMARY KEY,"
+                    + "Bid         INTEGER," + "Tbalance    INTEGER,"
+                    + "filler      CHAR(84))";                             /* pad to 100 bytes */
+
+            if (createExtension.length() > 0) {
+                Query += createExtension;
+            }
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "CREATE TABLE accounts ("
+                    + "Aid         INTEGER NOT NULL PRIMARY KEY, "
+                    + "Bid         INTEGER, " + "Abalance    INTEGER, "
+                    + "filler      CHAR(84))";                             /* pad to 100 bytes */
+
+            if (createExtension.length() > 0) {
+                Query += createExtension;
+            }
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "CREATE TABLE history (" + "Tid         INTEGER, "
+                    + "Bid         INTEGER, " + "Aid         INTEGER, "
+                    + "delta       INTEGER, " + "tstime        TIMESTAMP, "
+                    + "filler      CHAR(22))";                             /* pad to 50 bytes  */
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+/*
+            Stmt.execute("SET TABLE ACCOUNTS SOURCE \"ACCOUNTS.TXT\"");
+            Stmt.execute("SET TABLE BRANCHES SOURCE \"BBRANCHES.TXT\"");
+            Stmt.execute("SET TABLE TELLERS SOURCE \"TELLERS.TXT\"");
+            Stmt.execute("SET TABLE HISTORY SOURCE \"HISTORY.TXT\"");
+*/
+            Conn.commit();
+            Stmt.close();
+        } catch (Exception E) {
+            System.out.println(
+                "Delete elements in table in case Drop didn't work");
+        }
+
+        try {
+            Statement Stmt = Conn.createStatement();
+            String    Query;
+
+            Query = "DELETE FROM history";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DELETE FROM accounts";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DELETE FROM tellers";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+
+            Query = "DELETE FROM branches";
+
+            Stmt.execute(Query);
+            Stmt.clearWarnings();
+            Conn.commit();
+
+            /* prime database using TPC BM B scaling rules.
+             **  Note that for each branch and teller:
+             **      branch_id = teller_id  / ntellers
+             **      branch_id = account_id / naccounts
+             */
+            PreparedStatement pstmt = null;
+
+            try {
+                Query = "INSERT INTO branches(Bid,Bbalance) VALUES (?,0)";
+                pstmt = Conn.prepareStatement(Query);
+            } catch (SQLException Epstmt) {
+                pstmt = null;
+            }
+
+            System.out.println("Insert data in branches table");
+
+            for (int i = 0; i < nbranches * tps; i++) {
+                pstmt.setInt(1, i);
+                pstmt.executeUpdate();
+                pstmt.clearWarnings();
+
+                if (i % 100 == 0) {
+                    Conn.commit();
+                }
+            }
+
+            pstmt.close();
+            Conn.commit();
+
+            Query = "INSERT INTO tellers(Tid,Bid,Tbalance) VALUES (?,?,0)";
+            pstmt = Conn.prepareStatement(Query);
+
+            System.out.println("Insert data in tellers table");
+
+            for (int i = 0; i < ntellers * tps; i++) {
+                pstmt.setInt(1, i);
+                pstmt.setInt(2, i / ntellers);
+                pstmt.executeUpdate();
+                pstmt.clearWarnings();
+
+                if (i % 100 == 0) {
+                    Conn.commit();
+                }
+            }
+
+            pstmt.close();
+            Conn.commit();
+
+            Query = "INSERT INTO accounts(Aid,Bid,Abalance) VALUES (?,?,0)";
+            pstmt = Conn.prepareStatement(Query);
+
+            System.out.println("Insert data in accounts table");
+
+            for (int i = 0; i < naccounts * tps; i++) {
+                pstmt.setInt(1, i);
+                pstmt.setInt(2, i / naccounts);
+                pstmt.executeUpdate();
+                pstmt.clearWarnings();
+
+                if (i % 10000 == 0) {
+                    Conn.commit();
+                }
+
+                if ((i > 0) && ((i % 10000) == 0)) {
+                    System.out.println("\t" + i + "\t records inserted");
+                }
+            }
+
+            pstmt.close();
+            Conn.commit();
+            System.out.println("\t" + (naccounts * tps)
+                               + "\t records inserted");
+
+            // for tests
+            if (ShutdownCommand.length() > 0) {
+                Stmt.execute(ShutdownCommand);
+            }
+
+            Stmt.close();
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        }
+
+        connectClose(Conn);
+    }    /* end of CreateDatabase    */
+
+    public static int getRandomInt(int lo, int hi) {
+
+        int ret = 0;
+
+        ret = (int) (Math.random() * (hi - lo + 1));
+        ret += lo;
+
+        return ret;
+    }
+
+    public static int getRandomID(int type) {
+
+        int min = 0,
+            max = 0;
+
+        switch (type) {
+
+            case TELLER :
+                max = ntellers * tps - 1;
+                break;
+
+            case BRANCH :
+                max = nbranches * tps - 1;
+                break;
+
+            case ACCOUNT :
+                max = naccounts * tps - 1;
+                break;
+        }
+
+        return (getRandomInt(min, max));
+    }
+
+    public static Connection connect(String DBUrl, String DBUser,
+                                     String DBPassword) {
+
+        try {
+            Connection conn = DriverManager.getConnection(DBUrl, DBUser,
+                DBPassword);
+
+            return conn;
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public static void connectClose(Connection c) {
+
+        if (c == null) {
+            return;
+        }
+
+        try {
+            c.close();
+        } catch (Exception E) {
+            System.out.println(E.getMessage());
+            E.printStackTrace();
+        }
+    }
+
+    void checkSums(Connection conn) throws SQLException {
+
+        Statement st1 = null;
+        ResultSet rs  = null;
+        int       bbalancesum;
+        int       tbalancesum;
+        int       abalancesum;
+        int       abalancecount;
+        int       deltasum;
+
+        try {
+            st1 = conn.createStatement();
+            rs  = st1.executeQuery("select sum(bbalance) from branches");
+
+            rs.next();
+
+            bbalancesum = rs.getInt(1);
+
+            rs.close();
+
+            rs = st1.executeQuery("select sum(tbalance) from tellers");
+
+            rs.next();
+
+            tbalancesum = rs.getInt(1);
+
+            rs.close();
+
+            rs = st1.executeQuery(
+                "select sum(abalance), count(abalance) from accounts");
+
+            rs.next();
+
+            abalancesum   = rs.getInt(1);
+            abalancecount = rs.getInt(2);
+
+            rs.close();
+
+            rs = st1.executeQuery("select sum(delta) from history");
+
+            rs.next();
+
+            deltasum = rs.getInt(1);
+
+            rs.close();
+
+            rs = null;
+
+            st1.close();
+
+            st1 = null;
+
+            conn.commit();
+
+            if (abalancesum != bbalancesum || bbalancesum != tbalancesum
+                    || tbalancesum != deltasum) {
+                System.out.println("sums don't match!");
+            } else {
+                System.out.println("sums match!");
+            }
+
+            System.out.println("AC " + abalancecount + " A " + abalancesum
+                               + " B " + bbalancesum + " T " + tbalancesum
+                               + " H " + deltasum);
+        } finally {
+            if (st1 != null) {
+                st1.close();
+            }
+        }
+    }
+
+    class ClientThread extends Thread {
+
+        int               ntrans = 0;
+        Connection        Conn;
+        PreparedStatement pstmt1 = null;
+        PreparedStatement pstmt2 = null;
+        PreparedStatement pstmt3 = null;
+        PreparedStatement pstmt4 = null;
+        PreparedStatement pstmt5 = null;
+
+        public ClientThread(int number_of_txns, String url, String user,
+                            String password, int transactionMode) {
+
+            System.out.println(number_of_txns);
+
+            ntrans = number_of_txns;
+            Conn   = connect(url, user, password);
+
+            if (Conn == null) {
+                return;
+            }
+
+            try {
+                Conn.setAutoCommit(false);
+                Conn.setTransactionIsolation(transactionMode);
+                prepareStatements();
+            } catch (Exception E) {
+                System.out.println(E.getMessage());
+                E.printStackTrace();
+            }
+        }
+
+        void prepareStatements() throws SQLException {
+
+            String Query;
+
+            Query =
+                "UPDATE accounts SET Abalance = Abalance + ? WHERE  Aid = ?";
+            pstmt1 = Conn.prepareStatement(Query);
+            Query  = "SELECT Abalance FROM   accounts WHERE  Aid = ?";
+            pstmt2 = Conn.prepareStatement(Query);
+            Query =
+                "UPDATE tellers SET Tbalance = Tbalance + ? WHERE  Tid = ?";
+            pstmt3 = Conn.prepareStatement(Query);
+            Query =
+                "UPDATE branches SET Bbalance = Bbalance + ? WHERE  Bid = ?";
+            pstmt4 = Conn.prepareStatement(Query);
+            Query =
+                "INSERT INTO history(Tid, Bid, Aid, delta) VALUES (?,?,?,?)";
+            pstmt5 = Conn.prepareStatement(Query);
+        }
+
+        public void run() {
+
+            int count = ntrans;
+
+            while (count-- > 0) {
+                int account = TestBench.getRandomID(ACCOUNT);
+                int branch  = TestBench.getRandomID(BRANCH);
+                int teller  = TestBench.getRandomID(TELLER);
+                int delta   = TestBench.getRandomInt(-1000, 1000);
+
+                doOne(branch, teller, account, delta);
+                incrementTransactionCount();
+            }
+
+/*
+            count = ntrans * 20;
+
+            try {
+                Conn.setReadOnly(true);
+                while (count-- > 0) {
+                    int account = TestBench.getRandomID(ACCOUNT);
+
+                    pstmt2.setInt(1, account);
+                    pstmt2.executeQuery();
+                    Conn.commit();
+                    incrementTransactionCount();
+                }
+            } catch (SQLException e) {}
+*/
+            try {
+                if (pstmt1 != null) {
+                    pstmt1.close();
+                }
+
+                if (pstmt2 != null) {
+                    pstmt2.close();
+                }
+
+                if (pstmt3 != null) {
+                    pstmt3.close();
+                }
+
+                if (pstmt4 != null) {
+                    pstmt4.close();
+                }
+
+                if (pstmt5 != null) {
+                    pstmt5.close();
+                }
+            } catch (Exception E) {
+                System.out.println(E.getMessage());
+                E.printStackTrace();
+            }
+
+            connectClose(Conn);
+
+            Conn = null;
+        }
+
+        /*
+         **  doOne() - Executes a single TPC BM B transaction.
+         */
+        int doOne(int bid, int tid, int aid, int delta) {
+
+            int aBalance = 0;
+
+            if (Conn == null) {
+                incrementFailedTransactionCount();
+
+                return 0;
+            }
+
+            try {
+                pstmt1.setInt(1, delta);
+                pstmt1.setInt(2, aid);
+                pstmt1.executeUpdate();
+                pstmt1.clearWarnings();
+                pstmt2.setInt(1, aid);
+
+                ResultSet RS = pstmt2.executeQuery();
+
+                pstmt2.clearWarnings();
+
+                while (RS.next()) {
+                    aBalance = RS.getInt(1);
+                }
+
+                pstmt3.setInt(1, delta);
+                pstmt3.setInt(2, tid);
+                pstmt3.executeUpdate();
+                pstmt3.clearWarnings();
+                pstmt4.setInt(1, delta);
+                pstmt4.setInt(2, bid);
+                pstmt4.executeUpdate();
+                pstmt4.clearWarnings();
+                pstmt5.setInt(1, tid);
+                pstmt5.setInt(2, bid);
+                pstmt5.setInt(3, aid);
+                pstmt5.setInt(4, delta);
+                pstmt5.executeUpdate();
+                pstmt5.clearWarnings();
+                Conn.commit();
+
+                return aBalance;
+            } catch (Exception E) {
+                if (verbose) {
+                    System.out.println("Transaction failed: "
+                                       + E.getMessage());
+                    E.printStackTrace();
+                }
+
+                incrementFailedTransactionCount();
+
+                try {
+                    Conn.rollback();
+                } catch (SQLException E1) {}
+            }
+
+            return 0;
+        }    /* end of DoOne         */
+    }    /* end of class ClientThread */
+
+    class MemoryWatcherThread extends Thread {
+
+        long    min          = 0;
+        long    max          = 0;
+        boolean keep_running = true;
+
+        public MemoryWatcherThread() {
+
+            this.reset();
+
+            keep_running = true;
+        }
+
+        public void reset() {
+
+            System.gc();
+
+            long currentFree  = Runtime.getRuntime().freeMemory();
+            long currentAlloc = Runtime.getRuntime().totalMemory();
+
+            min = max = (currentAlloc - currentFree);
+        }
+
+        public void end() {
+            keep_running = false;
+        }
+
+        public void run() {
+
+            while (keep_running) {
+                long currentFree  = Runtime.getRuntime().freeMemory();
+                long currentAlloc = Runtime.getRuntime().totalMemory();
+                long used         = currentAlloc - currentFree;
+
+                if (used < min) {
+                    min = used;
+                }
+
+                if (used > max) {
+                    max = used;
+                }
+
+                try {
+                    sleep(100);
+                } catch (InterruptedException E) {}
+            }
+        }
+    }    /* end of class MemoryWatcherThread */
+}
diff --git a/src/org/hsqldb/test/TestBug1191815.java b/src/org/hsqldb/test/TestBug1191815.java
new file mode 100644
index 0000000..486f567
--- /dev/null
+++ b/src/org/hsqldb/test/TestBug1191815.java
@@ -0,0 +1,128 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * Created on Apr 28, 2005
+ * @author Antranig Basman (antranig@caret.cam.ac.uk)
+ */
+public class TestBug1191815 extends TestBase {
+
+    public TestBug1191815(String name) {
+        super(name);
+    }
+
+    public void test() throws Exception {
+
+        try {
+            Connection conn = newConnection();
+            Statement  stmt = conn.createStatement();
+
+            stmt.executeUpdate("drop table testA if exists;");
+            stmt.executeUpdate("create table testA(data timestamp);");
+
+            TimeZone pst = TimeZone.getTimeZone("PST");
+            Calendar cal = new GregorianCalendar(pst);
+
+            cal.clear();
+            cal.set(2005, 0, 1, 0, 0, 0);
+
+
+            // yyyy-mm-dd hh:mm:ss.fffffffff
+            Timestamp ts = new Timestamp(cal.getTimeInMillis());
+            ts.setNanos(1000);
+            PreparedStatement ps =
+                conn.prepareStatement("insert into testA values(?)");
+
+            ps.setTimestamp(1, ts, cal);
+            ps.execute();
+            ps.setTimestamp(1, ts, null);
+            ps.execute();
+
+            String sql = "select * from testA";
+
+            stmt = conn.createStatement();
+
+            ResultSet rs = stmt.executeQuery(sql);
+
+            rs.next();
+
+            Timestamp returned = rs.getTimestamp(1, cal);
+
+            rs.next();
+
+            Timestamp def = rs.getTimestamp(1, null);
+
+            assertEquals(ts, returned);
+            assertEquals(ts, def);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration exceptions;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestBug1191815("test");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println("TestBug1192000 failure count: " + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestBug778213.java b/src/org/hsqldb/test/TestBug778213.java
new file mode 100644
index 0000000..403fa53
--- /dev/null
+++ b/src/org/hsqldb/test/TestBug778213.java
@@ -0,0 +1,194 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * HSQLDB TestBug778213 Junit test case. <p>
+ *
+ * Test to ensure that DDL can be executed through the
+ * HSQLDB PreparedStatement interface implementation and
+ * that the behaviour of the prepared statement object is
+ * nominally correct under "prepared" DDL.
+ *
+ * @author  boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class TestBug778213 extends TestBase {
+
+    public TestBug778213(String name) {
+        super(name);
+    }
+
+    /* Implements the TestBug778213_Part3 test */
+    public void test() throws Exception {
+
+        Connection        conn = newConnection();
+        PreparedStatement pstmt;
+        int               updateCount;
+
+        try {
+            pstmt = conn.prepareStatement("drop table test if exists");
+
+            pstmt.executeUpdate();
+
+            pstmt       = conn.prepareStatement("create table test(id int)");
+            updateCount = pstmt.executeUpdate();
+
+            assertTrue("expected update count of zero", updateCount == 0);
+
+            pstmt       = conn.prepareStatement("drop table test");
+            updateCount = pstmt.executeUpdate();
+
+            assertTrue("expected update count of zero", updateCount == 0);
+        } catch (Exception e) {
+            assertTrue("unable to prepare or execute DDL", false);
+        } finally {
+            conn.close();
+        }
+
+        conn = newConnection();
+
+        try {
+            pstmt = conn.prepareStatement("create table test(id int)");
+
+            assertTrue("got data expecting update count", !pstmt.execute());
+        } catch (Exception e) {
+            assertTrue("unable to prepare or execute DDL", false);
+        } finally {
+            conn.close();
+        }
+
+        conn = newConnection();
+
+        boolean exception = true;
+
+        try {
+            pstmt = conn.prepareStatement("drop table test");
+
+            pstmt.executeQuery();
+        } catch (SQLException e) {
+            exception = false;
+        } finally {
+            conn.close();
+        }
+
+        if (exception) {
+            assertTrue("no exception thrown for executeQuery(DDL)", false);
+        }
+
+        conn = newConnection();
+
+        try {
+            pstmt = conn.prepareStatement("call identity()");
+
+            pstmt.execute();
+        } catch (Exception e) {
+            assertTrue("unable to prepare or execute call", false);
+        } finally {
+            conn.close();
+        }
+
+        exception = false;
+        conn      = newConnection();
+
+        try {
+            pstmt = conn.prepareStatement("create table test(id int)");
+
+            pstmt.addBatch();
+        } catch (SQLException e) {
+            exception = true;
+        } finally {
+            conn.close();
+        }
+
+        if (exception) {
+            assertTrue("not expected exception batching prepared DDL", false);
+        }
+
+        conn = newConnection();
+
+        try {
+            pstmt = conn.prepareStatement("create table test(id int)");
+
+            assertTrue("expected null ResultSetMetadata for prepared DDL",
+                       null == pstmt.getMetaData());
+        } finally {
+            conn.close();
+        }
+
+        conn = newConnection();
+
+//#ifdef JAVA4
+        try {
+            pstmt = conn.prepareStatement("create table test(id int)");
+
+            assertTrue("expected zero parameter for prepared DDL",
+                       0 == pstmt.getParameterMetaData().getParameterCount());
+        } finally {
+            conn.close();
+        }
+
+//#endif JAVA4
+    }
+
+    /* Runs TestBug778213_Part3 test from the command line*/
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestBug778213("test");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println("TestBug778213 failure count: " + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestBug785429.java b/src/org/hsqldb/test/TestBug785429.java
new file mode 100644
index 0000000..62fb971
--- /dev/null
+++ b/src/org/hsqldb/test/TestBug785429.java
@@ -0,0 +1,163 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * Tests Bug 785429 concerning BINARY values as PreparedStatement parameters
+ *
+ * @author  boucherb@users
+ */
+public class TestBug785429 extends TestBase {
+
+    Statement  stmt;
+    Connection conn;
+
+    public TestBug785429(String name) {
+        super(name);
+    }
+
+    public void test() throws Exception {
+
+        Connection conn = newConnection();
+
+        conn.setAutoCommit(false);
+
+        Statement         stmt = conn.createStatement();
+        String            sql;
+        String            msg;
+        PreparedStatement ps;
+        ResultSet         rs;
+        int               rowcount = 0;
+
+        stmt.executeUpdate("drop table testA if exists;");
+        stmt.executeUpdate("drop table testB if exists;");
+        stmt.executeUpdate(
+            "create table testA(oid binary(2), data integer);");
+        stmt.executeUpdate(
+            "create table testB(oid binary(2), data integer);");
+        stmt.executeUpdate("insert into testA values(X'0001',1);");
+        stmt.executeUpdate("insert into testB values(X'0001',1);");
+
+        sql = "select * from testA as ttt,(select oid,data from testB) as tst "
+              + "where (tst.oid=ttt.oid) and (tst.oid=X'0001');";
+        rs       = stmt.executeQuery(sql);
+        rowcount = 0;
+
+        while (rs.next()) {
+            rowcount++;
+        }
+
+        msg = sql + ": row count:";
+
+        assertEquals(msg, 1, rowcount);
+        stmt.execute("drop table testA if exists");
+        stmt.execute("drop table testB if exists");
+        stmt.execute("create table testA(oid binary(2), data integer)");
+        stmt.execute("create table testB(oid binary(2), data integer)");
+
+        byte[] oid = new byte[] {
+            0, 1
+        };
+
+        ps = conn.prepareStatement("insert into testA values(?,1)");
+
+        ps.setBytes(1, oid);
+        ps.execute();
+
+        ps = conn.prepareStatement("insert into testB values (?,1)");
+
+        ps.setBytes(1, oid);
+        ps.execute();
+
+        sql = "select * from testA as ttt,(select oid,data from testB) as tst "
+              + "where (tst.oid=ttt.oid) and (tst.oid=?);";
+
+        try {
+            ps = conn.prepareStatement(sql);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        ps.setBytes(1, oid);
+
+        rs       = ps.executeQuery();
+        rowcount = 0;
+
+        int colCount = rs.getMetaData().getColumnCount();
+
+        while (rs.next()) {
+
+//            for (int i= 1; i <= colCount; i++) {
+//                System.out.print(rs.getString(i) + ", ");
+//            }
+//
+//            System.out.println();
+            rowcount++;
+        }
+
+        msg = sql + ": row count:";
+
+        assertEquals(msg, 1, rowcount);
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration exceptions;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestBug785429("test");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println("TestBug785429 failure count: " + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestBug808460.java b/src/org/hsqldb/test/TestBug808460.java
new file mode 100644
index 0000000..827b6ef
--- /dev/null
+++ b/src/org/hsqldb/test/TestBug808460.java
@@ -0,0 +1,92 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * HSQLDB TestBug808460 Junit test case. <p>
+ *
+ * @author  boucherb@users
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class TestBug808460 extends TestBase {
+
+    public TestBug808460(String name) {
+        super(name);
+    }
+
+    /* Implements the TestBug808460 test */
+    public void test() throws Exception {
+
+        Connection conn = newConnection();
+        Statement  stmt = conn.createStatement();
+
+        stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.SYSTEM_SESSIONS");
+        conn.close();
+
+        conn = newConnection();
+        stmt = conn.createStatement();
+
+        stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.SYSTEM_SESSIONS");
+        conn.close();
+    }
+
+    /* Runs TestBug808460 test from the command line*/
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestBug808460("test");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println("TestBug808460 failure count: " + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestCacheSize.java b/src/org/hsqldb/test/TestCacheSize.java
new file mode 100644
index 0000000..734f9dd
--- /dev/null
+++ b/src/org/hsqldb/test/TestCacheSize.java
@@ -0,0 +1,1019 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.FileWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Random;
+
+import org.hsqldb.lib.FileUtil;
+import org.hsqldb.lib.StopWatch;
+import org.hsqldb.persist.HsqlProperties;
+
+/**
+ * Test large cached tables by setting up a cached table of 100000 records
+ * or more and a much smaller memory table with about 1/100th rows used.
+ * Populate both tables so that an indexed column of the cached table has a
+ * foreign key reference to the main table.
+ *
+ * This database can be used to demonstrate efficient queries to retrieve
+ * the data from the cached table.
+ *
+ * 1.7.1 insert timings for 100000 rows, cache scale 12:
+ * simple table, no extra index: 52 s
+ * with index on lastname only: 56 s
+ * with index on zip only: 211 s
+ * foreign key, referential_integrity true: 216 s
+ *
+ * The above have improved a lot in 1.7.2
+ *
+ * This test now incorporates the defunct TestTextTables
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.7.0
+ */
+public class TestCacheSize {
+
+    // program can edit the *.properties file to set cache_size, old files are deleted
+    protected boolean filedb = true;
+
+    // shutdown performed mid operation - not for mem: or hsql: URL's
+    protected boolean shutdown = true;
+
+    // fixed
+    protected String url = "jdbc:hsqldb:";
+
+//    protected String  filepath = "hsql://localhost/mytest";
+//    protected String filepath = "mem:test";
+    protected String filepath = "/hsql/testcache/test";
+
+    // frequent reporting of progress
+    boolean reportProgress = false;
+
+    // type of the big table {MEMORY | CACHED | TEXT | ""}
+    String  tableType      = "CACHED";
+    int     cacheScale     = 14;
+    int     cacheSizeScale = 10;
+    boolean nioMode        = true;
+    int     writeDelay     = 60;
+    boolean indexZip       = false;
+    boolean indexLastName  = false;
+    boolean addForeignKey  = false;
+    boolean refIntegrity   = true;
+
+    // may speed up inserts when tableType=="CACHED"
+    boolean createTempTable = false;
+
+    // introduces fragmentation to the .data file during insert
+    boolean deleteWhileInsert         = false;
+    int     deleteWhileInsertInterval = 10000;
+
+    // size of the tables used in test
+    int bigrows = 1024000;
+
+    // number of ops
+    int bigops    = 1024000;
+    int smallops  = 256000;
+    int smallrows = 0xfff;
+
+    // if the extra table needs to be created and filled up
+    boolean multikeytable = false;
+
+    //
+    String     user;
+    String     password;
+    Statement  sStatement;
+    Connection cConnection;
+    FileWriter writer;
+
+    //
+    String filler = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                    + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    private void checkSelects() {
+
+        countTestID();
+        selectID();
+
+//        selectZipTable();
+    }
+
+    private void checkUpdates() {
+
+//        updateIDLinear();
+//        updateID();
+        updateTestString();
+        countTestID();
+        deleteTest();
+        countTestID();
+        countZip();
+    }
+
+    protected void setUp() {
+
+        try {
+            writer = new FileWriter("speedtests.html", true);
+
+            writer.write("<table>\n");
+            storeResult(new java.util.Date().toString(), 0, 0, 0);
+            storeResult(filepath + " " + tableType + " " + nioMode,
+                        cacheScale, 0, 0);
+        } catch (Exception e) {}
+
+        user     = "sa";
+        password = "";
+
+        try {
+            sStatement  = null;
+            cConnection = null;
+
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            if (filedb) {
+                deleteDatabase(filepath);
+
+                cConnection = DriverManager.getConnection(url + filepath,
+                        user, password);
+                sStatement = cConnection.createStatement();
+
+                sStatement.execute("SET FILES WRITE DELAY " + 2);
+                sStatement.execute("SET FILES DEFRAG " + 0);
+                sStatement.execute("SET FILES LOG SIZE " + 0);
+                sStatement.execute("SET DATABASE EVENT LOG LEVEL 1");
+
+                int cacheRows = (1 << cacheScale) * 3;
+                int cacheSize = ((1 << cacheSizeScale) / 1024) * cacheRows;
+
+                sStatement.execute("SET FILES CACHE ROWS " + cacheRows);
+                sStatement.execute("SET FILES CACHE SIZE " + cacheSize);
+                sStatement.execute("SET FILES NIO " + nioMode);
+                sStatement.execute("SET FILES BACKUP INCREMENT " + true);
+                sStatement.execute("SHUTDOWN");
+                cConnection.close();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("TestSql.setUp() error: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Fill up the cache
+     *
+     *
+     */
+    public void testFillUp() {
+
+        StopWatch sw    = new StopWatch();
+        String    ddl1  = "DROP TABLE test IF EXISTS";
+        String    ddl11 = "DROP TABLE zip IF EXISTS";
+        String    ddl2  = "CREATE TABLE zip( zip INT IDENTITY )";
+        String ddl3 = "CREATE " + tableType + " TABLE test( id INT IDENTITY,"
+                      + " firstname VARCHAR(20), " + " lastname VARCHAR(20), "
+                      + " zip INTEGER, " + " filler VARCHAR(300))";
+        String ddl31 = "SET TABLE test SOURCE \"test.csv;cache_scale="
+                       + cacheScale + "\"";
+
+        // adding extra index will slow down inserts a bit
+        String ddl4 = "CREATE INDEX idx1 ON TEST (lastname)";
+
+        // adding this index will slow down  inserts a lot
+        String ddl5 = "CREATE INDEX idx2 ON TEST (zip)";
+
+        // referential integrity checks will slow down inserts a bit
+        String ddl6 =
+            "ALTER TABLE test add constraint c1 FOREIGN KEY (zip) REFERENCES zip(zip) ON DELETE CASCADE;";
+        String ddl7 = "CREATE TEMP TABLE temptest( id INT,"
+                      + " firstname VARCHAR, " + " lastname VARCHAR, "
+                      + " zip INTEGER, " + " filler VARCHAR)";
+        String mddl1 = "DROP TABLE test2 IF EXISTS";
+        String mddl2 = "CREATE " + tableType
+                       + " TABLE test2( id1 INT, id2 INT,"
+                       + " firstname VARCHAR, " + " lastname VARCHAR, "
+                       + " zip INTEGER, " + " filler VARCHAR, "
+                       + " PRIMARY KEY (id1,id2) )";
+        String mdd13 = "SET TABLE test2 SOURCE \"test2.csv;cache_scale="
+                       + cacheScale + "\"";
+
+        try {
+
+//            System.out.println("Connecting");
+            sw.zero();
+
+            cConnection = null;
+            sStatement  = null;
+            cConnection = DriverManager.getConnection(url + filepath, user,
+                    password);
+
+            System.out.println("connection time -- " + sw.elapsedTime());
+            sw.zero();
+
+            sStatement = cConnection.createStatement();
+
+            java.util.Random randomgen = new java.util.Random();
+
+//            sStatement.execute("SET WRITE_DELAY " + writeDelay);
+            sStatement.execute(ddl1);
+            sStatement.execute(ddl2);
+            sStatement.execute(ddl3);
+
+            if (tableType.equals("TEXT")) {
+                sStatement.execute(ddl31);
+            }
+
+//            System.out.println("test table with no index");
+            if (indexLastName) {
+                sStatement.execute(ddl4);
+                System.out.println("created index on lastname");
+            }
+
+            if (indexZip) {
+                sStatement.execute(ddl5);
+                System.out.println("created index on zip");
+            }
+
+            if (addForeignKey) {
+                sStatement.execute(ddl6);
+                System.out.println("added foreign key");
+            }
+
+            if (createTempTable) {
+                sStatement.execute(ddl7);
+                System.out.println("created temp table");
+            }
+
+            if (multikeytable) {
+                sStatement.execute(mddl1);
+                sStatement.execute(mddl2);
+
+                if (tableType.equals("TEXT")) {
+                    sStatement.execute(mdd13);
+                }
+
+                System.out.println("created multi key table");
+            }
+
+//            sStatement.execute("CREATE INDEX idx3 ON tempTEST (zip);");
+            System.out.println("complete setup time -- " + sw.elapsedTime()
+                               + " ms");
+            fillUpBigTable(filler, randomgen);
+
+            if (multikeytable) {
+                fillUpMultiTable(filler, randomgen);
+            }
+
+            sw.zero();
+
+            if (shutdown) {
+                sStatement.execute("SHUTDOWN");
+
+                long time = sw.elapsedTime();
+
+                storeResult("shutdown", 0, time, 0);
+                System.out.println("shutdown time  -- " + time + " ms");
+            }
+
+            cConnection.close();
+        } catch (SQLException e) {
+            System.out.println(e.getMessage());
+        }
+    }
+
+    private void fillUpBigTable(String filler,
+                                Random randomgen) throws SQLException {
+
+        StopWatch sw = new StopWatch();
+        int       i;
+        PreparedStatement ps =
+            cConnection.prepareStatement("INSERT INTO zip VALUES(?)");
+
+        for (i = 0; i <= smallrows; i++) {
+            ps.setInt(1, i);
+            ps.execute();
+        }
+
+        ps.close();
+        sStatement.execute("SET DATABASE REFERENTIAL INTEGRITY "
+                           + this.refIntegrity);
+
+        ps = cConnection.prepareStatement(
+            "INSERT INTO test (firstname,lastname,zip,filler) VALUES (?,?,?,?)");
+
+        ps.setString(1, "Julia");
+        ps.setString(2, "Clancy");
+
+        for (i = 0; i < bigrows; i++) {
+            ps.setInt(3, nextIntRandom(randomgen, smallrows));
+
+            {
+
+                // small rows
+                long nextrandom   = randomgen.nextLong();
+                int  randomlength = (int) nextrandom & 0x7f;
+
+                if (randomlength > filler.length()) {
+                    randomlength = filler.length();
+                }
+
+                String varfiller = filler.substring(0, randomlength);
+
+                ps.setString(4, nextrandom + varfiller);
+            }
+
+/*
+            {
+                // big rows
+                long nextrandom   = randomgen.nextLong();
+                int  randomlength = (int) nextrandom & 0x7ff;
+
+                if (randomlength > filler.length() * 20) {
+                    randomlength = filler.length() * 20;
+                }
+
+                StringBuffer sb = new StringBuffer(0xff);
+
+                for (int j = 0; j < 20; j++) {
+                    sb.append(filler);
+                }
+
+                String varfiller = sb.substring(0, randomlength);
+
+                ps.setString(4, nextrandom + varfiller);
+            }
+*/
+            ps.execute();
+
+            if (reportProgress && (i + 1) % 10000 == 0) {
+                System.out.println("insert " + (i + 1) + " : "
+                                   + sw.elapsedTime());
+            }
+
+            // delete and add 4000 rows to introduce fragmentation
+            if (deleteWhileInsert && i != 0
+                    && i % deleteWhileInsertInterval == 0) {
+                sStatement.execute("CALL IDENTITY();");
+
+                ResultSet rs = sStatement.getResultSet();
+
+                rs.next();
+
+                int lastId = rs.getInt(1);
+
+                sStatement.execute(
+                    "SELECT * INTO TEMP tempt FROM test WHERE id > "
+                    + (lastId - 4000));
+                sStatement.execute("DELETE FROM test WHERE id > "
+                                   + (lastId - 4000));
+                sStatement.execute("INSERT INTO test SELECT * FROM tempt");
+                sStatement.execute("DROP TABLE tempt");
+            }
+        }
+
+        ps.close();
+
+//            sStatement.execute("INSERT INTO test SELECT * FROM temptest;");
+//            sStatement.execute("DROP TABLE temptest;");
+//            sStatement.execute(ddl7);
+        long time = sw.elapsedTime();
+        long rate = ((long) i * 1000) / (time + 1);
+
+        storeResult("insert", i, time, rate);
+        System.out.println("insert time for " + i + " rows -- " + time
+                           + " ms -- " + rate + " tps");
+    }
+
+    private void fillUpMultiTable(String filler,
+                                  Random randomgen) throws SQLException {
+
+        StopWatch sw = new StopWatch();
+        int       i;
+        PreparedStatement ps = cConnection.prepareStatement(
+            "INSERT INTO test2 (id1, id2, firstname,lastname,zip,filler) VALUES (?,?,?,?,?,?)");
+
+        ps.setString(3, "Julia");
+        ps.setString(4, "Clancy");
+
+        int id1 = 0;
+
+        for (i = 0; i < bigrows; i++) {
+            int id2 = nextIntRandom(randomgen, Integer.MAX_VALUE);
+
+            if (i % 1000 == 0) {
+                id1 = nextIntRandom(randomgen, Integer.MAX_VALUE);
+            }
+
+            ps.setInt(1, id1);
+            ps.setInt(2, id2);
+            ps.setInt(5, nextIntRandom(randomgen, smallrows));
+
+            long nextrandom   = randomgen.nextLong();
+            int  randomlength = (int) nextrandom & 0x7f;
+
+            if (randomlength > filler.length()) {
+                randomlength = filler.length();
+            }
+
+            String varfiller = filler.substring(0, randomlength);
+
+            ps.setString(6, nextrandom + varfiller);
+
+            try {
+                ps.execute();
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+
+            if (reportProgress && (i + 1) % 10000 == 0) {
+                System.out.println("insert " + (i + 1) + " : "
+                                   + sw.elapsedTime());
+            }
+        }
+
+        ps.close();
+        System.out.println("total multi key rows inserted: " + i);
+        System.out.println("insert time: " + sw.elapsedTime() + " rps: "
+                           + (i * 1000 / (sw.elapsedTime() + 1)));
+    }
+
+    protected void tearDown() {
+
+        try {
+            writer.write("\n</table>\n");
+            writer.close();
+        } catch (Exception e) {}
+    }
+
+    protected void checkResults() {
+
+        try {
+            StopWatch sw = new StopWatch();
+            ResultSet rs;
+
+            cConnection = DriverManager.getConnection(url + filepath, user,
+                    password);
+
+            long time = sw.elapsedTime();
+
+            storeResult("reopen", 0, time, 0);
+            System.out.println("database reopen time -- " + time + " ms");
+            sw.zero();
+
+            sStatement = cConnection.createStatement();
+
+//            sStatement.execute("SET WRITE_DELAY " + writeDelay);
+            checkSelects();
+            checkUpdates();
+            sw.zero();
+
+            if (shutdown) {
+                sStatement.execute("SHUTDOWN");
+
+                time = sw.elapsedTime();
+
+                storeResult("shutdown", 0, time, 0);
+                System.out.println("shutdown time  -- " + time + " ms");
+            }
+
+            cConnection.close();
+
+//            System.out.println("database close time  -- " + sw.elapsedTime() + " ms");
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    void selectZip() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+
+        try {
+            PreparedStatement ps = cConnection.prepareStatement(
+                "SELECT TOP 1 firstname,lastname,zip,filler FROM test WHERE zip = ?");
+
+            for (; i < bigops; i++) {
+                ps.setInt(1, nextIntRandom(randomgen, smallrows));
+                ps.execute();
+
+                if ((i + 1) == 100 && sw.elapsedTime() > 50000) {
+                    slow = true;
+                }
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Select " + (i + 1) + " : "
+                                       + sw.elapsedTime() + " rps: "
+                                       + (i * 1000 / (sw.elapsedTime() + 1)));
+                }
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = ((long) i * 1000) / (time + 1);
+
+        storeResult("select random zip", i, time, rate);
+        System.out.println("select time for random zip " + i + " rows  -- "
+                           + time + " ms -- " + rate + " tps");
+    }
+
+    void selectID() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+
+        try {
+            PreparedStatement ps = cConnection.prepareStatement(
+                "SELECT firstname,lastname,zip,filler FROM test WHERE id = ?");
+
+            for (i = 0; i < smallops; i++) {
+                ps.setInt(1, nextIntRandom(randomgen, bigrows - 1));
+                ps.execute();
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Select " + (i + 1) + " : "
+                                       + (sw.elapsedTime() + 1));
+                }
+            }
+
+            ps.close();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = ((long) i * 1000) / (time + 1);
+
+        storeResult("select random id", i, time, rate);
+        System.out.println("select time for random id " + i + " rows  -- "
+                           + time + " ms -- " + rate + " tps");
+    }
+
+    void selectZipTable() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+
+        try {
+            PreparedStatement ps = cConnection.prepareStatement(
+                "SELECT zip FROM zip WHERE zip = ?");
+
+            for (i = 0; i < bigops; i++) {
+                ps.setInt(1, nextIntRandom(randomgen, smallrows - 1));
+                ps.execute();
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Select " + (i + 1) + " : "
+                                       + (sw.elapsedTime() + 1));
+                }
+            }
+
+            ps.close();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = ((long) i * 1000) / (time + 1);
+
+        storeResult("select random zip (zip table)", i, time, rate);
+        System.out.println("select time for random zip from zip table " + i
+                           + " rows  -- " + time + " ms -- " + rate + " tps");
+    }
+
+    private void countTestID() {
+
+        try {
+            StopWatch sw = new StopWatch();
+
+            // the tests use different indexes
+            // use primary index
+            sStatement.execute("SELECT count(*) from TEST where id > -1");
+
+            ResultSet rs = sStatement.getResultSet();
+
+            rs.next();
+
+            long time = sw.elapsedTime();
+            long rate = ((long) bigrows * 1000) / (time + 1);
+
+            storeResult("count (index on id)", rs.getInt(1), time, rate);
+            System.out.println("count time (index on id) " + rs.getInt(1)
+                               + " rows  -- " + time + " ms -- " + rate
+                               + " tps");
+        } catch (SQLException e) {}
+    }
+
+    private void countTestZip() {
+
+        try {
+            StopWatch sw = new StopWatch();
+
+            sStatement.execute("SELECT count(*) from TEST where zip > -1");
+
+            ResultSet rs = sStatement.getResultSet();
+
+            rs.next();
+
+            long time = (long) sw.elapsedTime();
+            long rate = ((long) bigrows * 1000) / (time + 1);
+
+            storeResult("count (index on zip)", rs.getInt(1), time, rate);
+            System.out.println("count time (index on zip) " + rs.getInt(1)
+                               + " rows  -- " + time + " ms -- " + rate
+                               + " tps");
+        } catch (SQLException e) {}
+    }
+
+    private void countZip() {
+
+        try {
+            StopWatch sw = new StopWatch();
+
+            sStatement.execute("SELECT count(*) from zip where zip > -1");
+
+            ResultSet rs = sStatement.getResultSet();
+
+            rs.next();
+            System.out.println("count time (zip table) " + rs.getInt(1)
+                               + " rows  -- " + sw.elapsedTime() + " ms");
+        } catch (SQLException e) {}
+    }
+
+    private void updateZip() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+        int              count     = 0;
+        int              random    = 0;
+
+        try {
+            PreparedStatement ps = cConnection.prepareStatement(
+                "UPDATE test SET filler = filler || zip WHERE zip = ?");
+
+            for (; i < smallrows; i++) {
+                random = nextIntRandom(randomgen, smallrows - 1);
+
+                ps.setInt(1, random);
+
+                count += ps.executeUpdate();
+
+                if (reportProgress && count % 10000 < 20) {
+                    System.out.println("Update " + count + " : "
+                                       + (sw.elapsedTime() + 1));
+                }
+            }
+
+            ps.close();
+        } catch (SQLException e) {
+            System.out.println("error : " + random);
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = (i * 1000) / (time + 1);
+
+        storeResult("update with random zip", i, time, rate);
+        System.out.println("update time with random zip " + i + " rows  -- "
+                           + time + " ms -- " + rate + " tps");
+    }
+
+    void updateID() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+        int              count     = 0;
+        int              random    = 0;
+
+        try {
+            PreparedStatement ps = cConnection.prepareStatement(
+                "UPDATE test SET zip = zip + 1 WHERE id = ? and zip <> "
+                + smallrows);
+
+            for (i = 0; i < smallops; i++) {
+                random = nextIntRandom(randomgen, bigrows - 1);
+
+                ps.setInt(1, random);
+                ps.execute();
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Update " + (i + 1) + " : "
+                                       + sw.elapsedTime() + " rps: "
+                                       + (i * 1000 / (sw.elapsedTime() + 1)));
+                }
+            }
+
+            ps.close();
+        } catch (SQLException e) {
+            System.out.println("error : " + random);
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = (i * 1000) / (time + 1);
+
+        storeResult("update with random id", i, time, rate);
+        System.out.println("update time with random id " + i + " rows  -- "
+                           + time + " ms -- " + rate + " tps");
+    }
+
+    void updateTestString() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+        int              count     = 0;
+        int              random    = 0;
+
+        try {
+            PreparedStatement ps = cConnection.prepareStatement(
+                "UPDATE test SET filler = ? WHERE id = ? and zip <> "
+                + smallrows);
+
+            for (i = 0; i < smallops * 2; i++) {
+                random = nextIntRandom(randomgen, bigrows - 1);
+
+                int randomLength = nextIntRandom(randomgen, filler.length());
+                String newFiller = filler.substring(randomLength);
+
+                ps.setString(1, newFiller);
+                ps.setInt(2, random);
+                ps.execute();
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Update " + (i + 1) + " : "
+                                       + sw.elapsedTime() + " rps: "
+                                       + (i * 1000 / (sw.elapsedTime() + 1)));
+                }
+            }
+
+            ps.close();
+        } catch (SQLException e) {
+            System.out.println("error : " + random);
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = (i * 1000) / (time + 1);
+
+        storeResult("update with random id", i, time, rate);
+        System.out.println("update time with random id " + i + " rows  -- "
+                           + time + " ms -- " + rate + " tps");
+    }
+
+    void updateIDLinear() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+        int              count     = 0;
+        int              random    = 0;
+
+        try {
+            PreparedStatement ps = cConnection.prepareStatement(
+                "UPDATE test SET zip = zip + 1 WHERE id = ? and zip <> "
+                + smallrows);
+
+            for (i = 0; i < bigops; i++) {
+                random = i;
+
+                ps.setInt(1, random);
+                ps.execute();
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("Update " + (i + 1) + " : "
+                                       + sw.elapsedTime() + " rps: "
+                                       + (i * 1000 / (sw.elapsedTime() + 1)));
+                }
+            }
+
+            ps.close();
+        } catch (SQLException e) {
+            System.out.println("error : " + random);
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = (i * 1000) / (time + 1);
+
+        storeResult("update with sequential id", i, time, rate);
+        System.out.println("update time with sequential id " + i
+                           + " rows  -- " + time + " ms -- " + rate + " tps");
+    }
+
+    void deleteTest() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+        int              count     = 0;
+        int              random    = 0;
+
+        try {
+            PreparedStatement ps =
+                cConnection.prepareStatement("DELETE FROM test WHERE id = ?");
+
+            for (i = 0; count < smallops; i++) {
+                random = nextIntRandom(randomgen, bigrows);
+
+//                random = i;
+                ps.setInt(1, random);
+
+                count += ps.executeUpdate();
+
+/*
+                if ((i + 1) % 10000 == 0) {
+                    Statement st = cConnection.createStatement();
+
+                    st.execute("CHECKPOINT DEFRAG");
+                    st.close();
+                }
+*/
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("delete " + (i + 1) + " : "
+                                       + sw.elapsedTime() + " rps: "
+                                       + (i * 1000 / (sw.elapsedTime() + 1)));
+                }
+            }
+
+            ps.close();
+        } catch (SQLException e) {
+            System.out.println("error : " + random);
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = (count * 1000) / (time + 1);
+
+        storeResult("delete with random id", count, time, rate);
+        System.out.println("delete time for random id " + count + " rows  -- "
+                           + time + " ms -- " + rate + " tps");
+    }
+
+    void deleteZipTable() {
+
+        StopWatch        sw        = new StopWatch();
+        java.util.Random randomgen = new java.util.Random();
+        int              i         = 0;
+        boolean          slow      = false;
+        int              count     = 0;
+        int              random    = 0;
+
+        try {
+            PreparedStatement ps =
+                cConnection.prepareStatement("DELETE FROM zip WHERE zip = ?");
+
+            for (i = 0; i <= smallrows; i++) {
+
+//                random = randomgen.nextInt(smallrows - 1);
+                random = i;
+
+                ps.setInt(1, random);
+
+                count += ps.executeUpdate();
+
+                if (reportProgress && (i + 1) % 10000 == 0
+                        || (slow && (i + 1) % 100 == 0)) {
+                    System.out.println("delete " + (i + 1) + " : "
+                                       + sw.elapsedTime() + " rps: "
+                                       + (i * 1000 / (sw.elapsedTime() + 1)));
+                }
+            }
+
+            ps.close();
+        } catch (SQLException e) {
+            System.out.println("error : " + random);
+            e.printStackTrace();
+        }
+
+        long time = sw.elapsedTime();
+        long rate = ((long) count * 1000) / (time + 1);
+
+        storeResult("delete with random zip", count, time, rate);
+        System.out.println("delete time for random zip " + count
+                           + " rows  -- " + time + " ms -- " + rate + " tps");
+    }
+
+    void storeResult(String description, int count, long time, long rate) {
+
+        try {
+            writer.write("<tr><td>" + description + "</td><td>" + count
+                         + "</td><td>" + time + "</td><td>" + rate
+                         + "</td></tr>\n");
+        } catch (Exception e) {}
+    }
+
+    static void deleteDatabase(String path) {
+
+        FileUtil fileUtil = FileUtil.getFileUtil();
+
+        fileUtil.delete(path + ".backup");
+        fileUtil.delete(path + ".properties");
+        fileUtil.delete(path + ".script");
+        fileUtil.delete(path + ".data");
+        fileUtil.delete(path + ".log");
+        fileUtil.delete(path + ".lck");
+        fileUtil.delete(path + ".csv");
+    }
+
+    int nextIntRandom(Random r, int range) {
+
+        int b = r.nextInt();
+
+        if (b == Integer.MIN_VALUE) {
+            b = Integer.MAX_VALUE;
+        }
+
+        b = Math.abs(b);
+
+        return b % range;
+    }
+
+    public static void main(String[] argv) {
+
+        TestCacheSize  test  = new TestCacheSize();
+        HsqlProperties props = HsqlProperties.argArrayToProps(argv, "test");
+
+        test.bigops   = props.getIntegerProperty("test.bigops", test.bigops);
+        test.bigrows  = test.bigops;
+        test.smallops = test.bigops / 8;
+        test.cacheScale = props.getIntegerProperty("test.scale",
+                test.cacheScale);
+        test.tableType = props.getProperty("test.tabletype", test.tableType);
+        test.nioMode   = props.isPropertyTrue("test.nio", test.nioMode);
+
+        if (props.getProperty("test.dbtype", "").equals("mem")) {
+            test.filepath = "mem:test";
+            test.filedb   = false;
+            test.shutdown = false;
+        }
+
+        test.setUp();
+
+        StopWatch sw = new StopWatch();
+
+        test.testFillUp();
+        test.checkResults();
+
+        long time = sw.elapsedTime();
+
+        test.storeResult("total test time", 0, (int) time, 0);
+        System.out.println("total test time -- " + sw.elapsedTime() + " ms");
+        test.tearDown();
+    }
+}
diff --git a/src/org/hsqldb/test/TestCascade.java b/src/org/hsqldb/test/TestCascade.java
new file mode 100644
index 0000000..8533857
--- /dev/null
+++ b/src/org/hsqldb/test/TestCascade.java
@@ -0,0 +1,180 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+/*
+ * CascadeDeleteBug.java
+ *
+ * Created on June 24, 2002, 8:48 AM
+ */
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case to demonstrate catastrophic bug in cascade delete code.
+ *
+ * @version 1.0
+ * @author  David Kopp
+ */
+public class TestCascade extends TestCase {
+
+    Connection con;
+
+    public TestCascade(String name) {
+        super(name);
+    }
+
+    protected void setUp() {
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+            createDatabase();
+
+            con = DriverManager.getConnection("jdbc:hsqldb:testdb", "sa", "");
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println(this + ".setUp() error: " + e.getMessage());
+        }
+    }
+
+    protected void tearDown() {
+
+        try {
+            con.createStatement().execute("SHUTDOWN");
+            con.close();
+        } catch (SQLException e) {}
+    }
+
+    public void testDelete() {
+
+        try {
+            insertData(con);
+
+            Statement stmt = con.createStatement();
+            ResultSet rs =
+                stmt.executeQuery("SELECT COUNT(EIACODXA) FROM CA");
+
+            rs.next();
+
+            int origCount = rs.getInt(1);
+
+            rs.close();
+            deleteXBRecord(con);
+
+            rs = stmt.executeQuery("SELECT COUNT(EIACODXA) FROM CA");
+
+            rs.next();
+
+            int newCount = rs.getInt(1);
+
+            rs.close();
+            stmt.close();
+            assertEquals(9, newCount);
+        } catch (SQLException e) {
+            this.assertTrue("SQLException thrown", false);
+        }
+    }
+
+    private static void createDatabase() throws SQLException {
+
+        new File("testdb.backup").delete();
+        new File("testdb.data").delete();
+        new File("testdb.properties").delete();
+        new File("testdb.script").delete();
+
+        Connection con = DriverManager.getConnection("jdbc:hsqldb:testdb",
+            "sa", "");
+        String[] saDDL = {
+            "CREATE CACHED TABLE XB (EIACODXA VARCHAR(10) NOT NULL, LSACONXB VARCHAR(18) NOT NULL, ALTLCNXB VARCHAR(2) NOT NULL, LCNTYPXB VARCHAR(1) NOT NULL, LCNINDXB VARCHAR(1), LCNAMEXB VARCHAR(19), UPDT_BY VARCHAR(32), LST_UPDT TIMESTAMP, CONSTRAINT XPKXB PRIMARY KEY (EIACODXA, LSACONXB, ALTLCNXB, LCNTYPXB));",
+
+//            "CREATE INDEX XIF2XB ON XB (EIACODXA);",
+            "CREATE CACHED TABLE CA ( EIACODXA VARCHAR(10) NOT NULL, LSACONXB VARCHAR(18) NOT NULL, ALTLCNXB VARCHAR(2) NOT NULL, LCNTYPXB VARCHAR(1) NOT NULL, TASKCDCA VARCHAR(7) NOT NULL, TSKFRQCA NUMERIC(7,4), UPDT_BY VARCHAR(32), LST_UPDT TIMESTAMP, CONSTRAINT XPKCA PRIMARY KEY (EIACODXA, LSACONXB, ALTLCNXB, LCNTYPXB, TASKCDCA),        CONSTRAINT R_XB_CA FOREIGN KEY (EIACODXA, LSACONXB, ALTLCNXB, LCNTYPXB) REFERENCES XB ON DELETE CASCADE);",
+
+//            "CREATE INDEX XIF26CA ON CA ( EIACODXA, LSACONXB, ALTLCNXB, LCNTYPXB);"
+        };
+        Statement stmt = con.createStatement();
+
+        for (int index = 0; index < saDDL.length; index++) {
+            stmt.executeUpdate(saDDL[index]);
+        }
+
+        stmt.execute("SHUTDOWN");
+        con.close();
+    }    // createDatabase
+
+    /**
+     * This method demonstrates the bug in cascading deletes. Before this method,
+     * the CA table has 12 records. After, it should have 9, but instead it has
+     * 0.
+     */
+    private static void deleteXBRecord(Connection con) throws SQLException {
+
+        Statement stmt = con.createStatement();
+
+        stmt.executeUpdate(
+            "DELETE FROM XB WHERE LSACONXB = 'LEAA' AND EIACODXA = 'T850' AND LCNTYPXB = 'P' AND ALTLCNXB = '00'");
+        stmt.close();
+    }    // deleteXBRecord
+
+    private static void insertData(Connection con) throws SQLException {
+
+        String[] saData = {
+            "INSERT INTO XB VALUES('T850','LEAA','00','P',NULL,'LCN NAME','sa',NOW)",
+            "INSERT INTO XB VALUES('T850','LEAA01','00','P',NULL,'LCN NAME','sa',NOW)",
+            "INSERT INTO XB VALUES('T850','LEAA02','00','P',NULL,'LCN NAME','sa',NOW)",
+            "INSERT INTO XB VALUES('T850','LEAA03','00','P',NULL,'LCN NAME','sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA','00','P','ABCDEFG',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA','00','P','QRSTUJV',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA','00','P','ZZZZZZZ',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA01','00','P','ABCDEFG',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA01','00','P','QRSTUJV',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA01','00','P','ZZZZZZZ',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA02','00','P','ABCDEFG',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA02','00','P','QRSTUJV',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA02','00','P','ZZZZZZZ',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA03','00','P','ABCDEFG',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA03','00','P','QRSTUJV',3.14,'sa',NOW)",
+            "INSERT INTO CA VALUES('T850','LEAA03','00','P','ZZZZZZZ',3.14,'sa',NOW)"
+        };
+        Statement stmt = con.createStatement();
+
+        for (int index = 0; index < saData.length; index++) {
+            stmt.executeUpdate(saData[index]);
+        }
+    }    // insertData
+}
diff --git a/src/org/hsqldb/test/TestCollation.java b/src/org/hsqldb/test/TestCollation.java
new file mode 100644
index 0000000..543b9bd
--- /dev/null
+++ b/src/org/hsqldb/test/TestCollation.java
@@ -0,0 +1,250 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import org.hsqldb.Collation;
+
+/**
+ * Test HSQLDBs collation capabilities
+ * @author frank.schoenheit@sun.com
+ */
+public class TestCollation extends TestBase {
+
+    java.sql.Statement      statement;
+    java.sql.Connection     connection;
+    org.hsqldb.lib.Iterator collIterator;
+    org.hsqldb.lib.Iterator localeIterator;
+
+    /** Creates a new instance of TestCollation */
+    public TestCollation(String name) {
+
+        super(name);
+
+        super.isNetwork = false;
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            connection = super.newConnection();
+            statement  = connection.createStatement();
+        } catch (Exception e) {}
+
+        collIterator   = Collation.getCollationsIterator();
+        localeIterator = Collation.getLocalesIterator();
+    }
+
+    protected void tearDown() {
+
+        try {
+            statement = connection.createStatement();
+
+            statement.execute("SHUTDOWN");
+        } catch (Exception e) {}
+
+        super.tearDown();
+    }
+
+    /**
+     * checks whether expected locales are present and selectable
+     */
+    public void testVerifyAvailability() {
+
+        // let's check whether unknown collation identifiers are rejected
+        try {
+            statement.execute(
+                getSetCollationStmt(
+                    "ThisIsDefinitlyNoValidCollationIdentifier"));
+            fail("database did not reject invalid collation name");
+        } catch (java.sql.SQLException e) {}
+
+        // let's check whether the DB accepts all known collations
+        int count = 0;
+
+        while (collIterator.hasNext()) {
+            String collationName = (String) collIterator.next();
+
+            try {
+                statement.execute(getSetCollationStmt(collationName));
+            } catch (java.sql.SQLException e) {
+                fail("could not set collation '" + collationName
+                     + "'\n  exception message: " + e.getMessage());
+            }
+
+            ++count;
+        }
+
+        System.out.println("checked " + count
+                           + " collations for availability.");
+
+        // even if the above worked, we cannot be sure that all locales are really supported.
+        // The fact that SET DATABASE COLLATION succeeeded only means that a Collator could
+        // be instantiated with a Locale matching the given collation name. But what if
+        // Locale.Instance(...) lied, and returned a fallback Locale instance?
+        //
+        // Hmm, looking at the documentation of Locale.getAvailableLocales, I'm not sure
+        // whether it is really feasible. The doc states "returns a list of all installed Locales".
+        // The "installed" puzzles me - maybe this is really different per installation, and not only
+        // per JDK version?
+        java.util.Locale[] availableLocales =
+            java.util.Locale.getAvailableLocales();
+        org.hsqldb.lib.Set existenceCheck = new org.hsqldb.lib.HashSet();
+
+        for (int i = 0; i < availableLocales.length; ++i) {
+            String availaleName = availableLocales[i].getLanguage();
+
+            if (availableLocales[i].getCountry().length() > 0) {
+                availaleName += "-" + availableLocales[i].getCountry();
+            }
+
+            existenceCheck.add(availaleName);
+        }
+
+        String notInstalled = "";
+        int    expected     = 0,
+               failed       = 0;
+
+        while (localeIterator.hasNext()) {
+            String localeName = (String) localeIterator.next();
+
+            ++expected;
+
+            if (!existenceCheck.contains(localeName)) {
+                if (notInstalled.length() > 0) {
+                    notInstalled += "; ";
+                }
+
+                notInstalled += localeName;
+
+                ++failed;
+            }
+        }
+
+        if (notInstalled.length() > 0) {
+            fail("the following locales are not installed:\n  " + notInstalled
+                 + "\n  (" + failed + " out of " + expected + ")");
+        }
+    }
+
+    /**
+     * checks whether sorting via a given collation works as expected
+     */
+    public void testVerifyCollation() {
+
+        String failedCollations = "";
+        String failMessage      = "";
+
+        while (collIterator.hasNext()) {
+            String collationName = (String) collIterator.next();
+            String message       = checkSorting(collationName);
+
+            if (message.length() > 0) {
+                if (failedCollations.length() > 0) {
+                    failedCollations += ", ";
+                }
+
+                failedCollations += collationName;
+                failMessage      += message;
+            }
+        }
+
+        if (failedCollations.length() > 0) {
+            fail("test failed for following collations:\n" + failedCollations
+                 + "\n" + failMessage);
+        }
+    }
+
+    /**
+     * returns an SQL statement to set the database collation
+     */
+    protected final String getSetCollationStmt(String collationName) {
+
+        final String setCollationStmtPre  = "SET DATABASE COLLATION \"";
+        final String setCollationStmtPost = "\"";
+
+        return setCollationStmtPre + collationName + setCollationStmtPost;
+    }
+
+    /**
+     * checks sorting a table with according to a given collation
+     */
+    protected String checkSorting(String collationName) {
+
+        String stmt1 =
+            "DROP TABLE WORDLIST IF EXISTS;";
+        String stmt2 =
+            "CREATE TEXT TABLE WORDLIST ( ID INTEGER, WORD VARCHAR(50) );";
+        String stmt3 =
+            "SET TABLE WORDLIST SOURCE \"" + collationName
+            + ".csv;encoding=UTF-8\"";
+        String selectStmt    = "SELECT ID, WORD FROM WORDLIST ORDER BY WORD";
+        String returnMessage = "";
+
+        try {
+
+            // set database collation
+            statement.execute(getSetCollationStmt(collationName));
+            statement.execute(stmt1);
+            statement.execute(stmt2);
+            statement.execute(stmt3);
+
+            java.sql.ResultSet results = statement.executeQuery(selectStmt);
+
+            while (results.next()) {
+                int expectedPosition = results.getInt(1);
+                int foundPosition    = results.getRow();
+
+                if (expectedPosition != foundPosition) {
+                    String word = results.getString(2);
+
+                    return "testing collation '" + collationName
+                           + "' failed\n" + "  word              : " + word
+                           + "\n" + "  expected position : "
+                           + expectedPosition + "\n"
+                           + "  found position    : " + foundPosition + "\n";
+                }
+            }
+        } catch (java.sql.SQLException e) {
+            return "testing collation '" + collationName
+                   + "' failed\n  exception message: " + e.getMessage() + "\n";
+        }
+
+        return "";
+    }
+
+    public static void main(String[] argv) {
+        runWithResult(TestCollation.class, "testVerifyAvailability");
+        runWithResult(TestCollation.class, "testVerifyCollation");
+    }
+}
diff --git a/src/org/hsqldb/test/TestDataStructures.java b/src/org/hsqldb/test/TestDataStructures.java
new file mode 100644
index 0000000..7628c2b
--- /dev/null
+++ b/src/org/hsqldb/test/TestDataStructures.java
@@ -0,0 +1,498 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Random;
+import java.util.Vector;
+
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.HsqlLinkedList;
+import org.hsqldb.lib.HsqlList;
+import org.hsqldb.lib.StopWatch;
+
+import junit.framework.TestCase;
+
+/**
+ * Randomly excutes methods on the HsqlList data structures and compares the
+ * results with equivalent calls on the java vector class.
+ *
+ * @author dnordahl@users
+ */
+public class TestDataStructures extends TestCase {
+
+    private static final int NUMBER_OF_TEST_RUNS          = 100000;
+    private static final int NUMBER_OF_ITERATIONS_PER_RUN = 80;
+    private Random           randomGenerator;
+
+    //Commands
+    private static final int ADD        = 1;
+    private static final int ADD_AT     = 2;
+    private static final int GET        = 3;
+    private static final int REMOVE     = 4;
+    private static final int SET        = 5;
+    private static final int OPTIMIZE   = 6;
+    private static final int REMOVE_ALL = 7;
+    private Vector           listCommandsCalled;
+
+    /** Creates a new instance of TestDataStructures */
+    public TestDataStructures(String s) {
+
+        super(s);
+
+        randomGenerator    = new Random(System.currentTimeMillis());
+        listCommandsCalled = new Vector(NUMBER_OF_ITERATIONS_PER_RUN);
+    }
+
+    /** Runs a test on the hsqldb lists */
+    public void testLists() {
+
+        HsqlArrayList  arrayList  = new HsqlArrayList();
+        HsqlLinkedList linkedList = new HsqlLinkedList();
+        Vector         vector     = new Vector();
+        Vector listCommandsCalled = new Vector(NUMBER_OF_ITERATIONS_PER_RUN);
+        Integer        tempInt    = null;
+        int            tempCommandCode;
+        int            tempPosition;
+        boolean        arrayListException  = false;
+        boolean        linkedListException = false;
+        boolean        vectorException     = false;
+        Object         arrayListObject     = null;
+        Object         linkedListObject    = null;
+        Object         vectorObject        = null;
+
+        for (int i = 0; i < getRandomInt(3, 12); i++) {    // prime the contents with a couple items
+            tempInt = getRandomInteger();
+
+            arrayList.add(tempInt);
+            linkedList.add(tempInt);
+            vector.addElement(tempInt);
+            listCommandsCalled.addElement("Add");
+        }
+
+        compareLists(arrayList, linkedList, vector);
+
+        for (int j = 0; j < NUMBER_OF_ITERATIONS_PER_RUN; j++) {
+            tempCommandCode = getRandomInt(0, 15);    // 0 and 8 are ignored or used for a special op
+
+            switch (tempCommandCode) {
+
+                case ADD :
+                    tempInt = getRandomInteger();
+
+                    listCommandsCalled.addElement("Add");
+                    arrayList.add(tempInt);
+                    linkedList.add(tempInt);
+                    vector.addElement(tempInt);
+                    break;
+
+                case ADD_AT :
+                    tempInt      = getRandomInteger();
+                    tempPosition = getRandomInt(0, vector.size());
+
+                    listCommandsCalled.addElement("Add at " + tempPosition);
+
+                    try {
+                        arrayList.add(tempPosition, tempInt);
+                    } catch (Exception ex) {
+                        arrayListException = true;
+                    }
+
+                    try {
+                        linkedList.add(tempPosition, tempInt);
+                    } catch (Exception ex) {
+                        linkedListException = true;
+                    }
+
+                    try {
+                        vector.insertElementAt(tempInt, tempPosition);
+                    } catch (Exception ex) {
+                        vectorException = true;
+                    }
+                    break;
+
+                case GET :
+                    tempPosition = getRandomInt(0, vector.size() -1);
+
+                    listCommandsCalled.addElement("Get " + tempPosition);
+
+                    try {
+                        arrayListObject = arrayList.get(tempPosition);
+                    } catch (Exception ex) {
+                        arrayListException = true;
+                    }
+
+                    try {
+                        linkedListObject = linkedList.get(tempPosition);
+                    } catch (Exception ex) {
+                        linkedListException = true;
+                    }
+
+                    try {
+                        vectorObject = vector.elementAt(tempPosition);
+                    } catch (Exception ex) {
+                        vectorException = true;
+                    }
+                    break;
+
+                case REMOVE :
+                    tempPosition = getRandomInt(0, vector.size() - 1);
+
+                    listCommandsCalled.addElement("Remove " + tempPosition);
+
+                    try {
+                        arrayListObject = arrayList.remove(tempPosition);
+                    } catch (Exception ex) {
+                        arrayListException = true;
+                    }
+
+                    try {
+                        linkedListObject = linkedList.remove(tempPosition);
+                    } catch (Exception ex) {
+                        linkedListException = true;
+                    }
+
+                    try {
+                        vectorObject = vector.elementAt(tempPosition);
+
+                        vector.removeElementAt(tempPosition);
+                    } catch (Exception ex) {
+                        vectorException = true;
+                    }
+                    break;
+
+                case SET :
+                    tempInt      = getRandomInteger();
+                    tempPosition = getRandomInt(0, vector.size() -1);
+
+                    listCommandsCalled.addElement("Set " + tempPosition);
+
+                    try {
+                        arrayList.set(tempPosition, tempInt);
+                    } catch (Exception ex) {
+                        arrayListException = true;
+                    }
+
+                    try {
+                        linkedList.set(tempPosition, tempInt);
+                    } catch (Exception ex) {
+                        linkedListException = true;
+                    }
+
+                    try {
+                        vector.setElementAt(tempInt, tempPosition);
+                    } catch (Exception ex) {
+                        vectorException = true;
+                    }
+                    break;
+
+                case OPTIMIZE :
+                    listCommandsCalled.addElement("Optimize");
+                    arrayList.trim();
+                    vector.trimToSize();
+                    break;
+
+                case REMOVE_ALL :
+                    if (getRandomInt(0, 5) == 4) {    // to limit the frequency of this call
+                        listCommandsCalled.addElement("Remove all");
+
+                        if (vector.size() == 0) {
+                            break;
+                        }
+
+                        for (int k = arrayList.size() - 1; k >= 0; k--) {
+                            arrayList.remove(k);
+                            linkedList.remove(k);
+                        }
+
+                        vector.removeAllElements();
+                    }
+                    break;
+
+                default :
+            }
+
+            if (arrayListException || linkedListException || vectorException) {
+
+                // if an exception is thrown in vector but not one of the lists or vice versa
+                if (!(arrayListException && linkedListException
+                        && vectorException)) {
+                    if (!(arrayListException && vectorException)) {
+                        System.out.println(
+                            "Exception descrepancy with vector and arraylist");
+                    } else if (!(linkedListException && vectorException)) {
+                        System.out.println(
+                            "Exception descrepancy with vector and linkedlist");
+                    } else {
+                        System.out.println("Error in TestDataStructures");
+                    }
+
+                    this.printListCommandsCalled(listCommandsCalled);
+                    fail("test failed");
+
+                    //System.exit(0);
+                }
+
+                return;
+            }
+
+            if (!objectEquals(linkedListObject, arrayListObject,
+                              vectorObject)) {
+                System.out.println("Objects returned inconsistent");
+                this.printListCommandsCalled(listCommandsCalled);
+                fail("test failed");
+
+                //System.exit(0);
+            }
+
+            compareLists(arrayList, linkedList, vector);
+        }
+    }
+
+    /**
+     * Compare contents of lists to the vector.  Print out stuff if they are
+     * inconsistent and exit.
+     */
+    public void compareLists(HsqlArrayList arrayList,
+                             HsqlLinkedList linkedList, Vector vector) {
+
+        boolean arrayListError  = false;
+        boolean linkedListError = false;
+
+        if (!equalsVector(arrayList, vector)) {
+            System.out.println("Error in array list implementation");
+
+            arrayListError = true;
+        }
+
+        if (!equalsVector(linkedList, vector)) {
+            System.out.println("Error in linked list implementation");
+
+            linkedListError = true;
+        }
+
+        if (arrayListError || linkedListError) {
+            this.printListCommandsCalled(listCommandsCalled);
+            System.out.flush();
+            fail("test failed");
+        }
+    }
+
+    /** Prints the list of commands called so far */
+    public void printListCommandsCalled(Vector commands) {
+
+        int commandCode = 0;
+
+        for (int i = 0; i < commands.size(); i++) {
+            System.out.println((String) commands.elementAt(i));
+        }
+
+        System.out.flush();
+    }
+
+    /** Returns whether three objects are equal */
+    private boolean objectEquals(Object lObject, Object aObject,
+                                 Object vObject) {
+
+        if (lObject == null && aObject == null && vObject == null) {
+            return true;
+        }
+
+        try {
+            if (!lObject.equals(vObject)) {
+                System.out.println("LinkList object returned inconsistent");
+
+                return false;
+            } else if (!aObject.equals(vObject)) {
+                System.out.println("ArrayList object returned inconsistent");
+
+                return false;
+            } else {
+                return true;
+            }
+        } catch (NullPointerException ex) {
+            return false;
+        }
+    }
+
+    /** Returns a random integer in the range of the lowBound and highBound */
+    private int getRandomInt(int lowBound, int highBound) {
+
+        double random = randomGenerator.nextDouble();
+
+        return ((int) (((highBound - lowBound) * random) + .5)) + lowBound;
+    }
+
+    /**
+     * Returns an Integer object with a value between Integer.MIN_VALUE and
+     * Integer.MAX_VALUE
+     */
+    private Integer getRandomInteger() {
+        return new Integer(getRandomInt(0, (int) (Integer.MAX_VALUE / 100.0)));
+    }
+
+    /** Tells whether the given list contains the same data as the vector */
+    private boolean equalsVector(HsqlList list, Vector vector) {
+
+        if (list.size() != vector.size()) {
+            return false;
+        }
+
+        org.hsqldb.lib.Iterator listElements   = list.iterator();
+        Enumeration             vectorElements = vector.elements();
+        Object                  listObj        = null;
+        Object                  vectorObj      = null;
+
+        while (listElements.hasNext()) {
+            listObj   = listElements.next();
+            vectorObj = vectorElements.nextElement();
+
+            if (!listObj.equals(vectorObj)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public void testGrowth() {
+
+        HsqlArrayList d = new HsqlArrayList();
+
+        for (int i = 0; i < 12; i++) {
+            d.add(new Integer(i));
+        }
+
+        for (int i = 0; i < d.size(); i++) {
+            System.out.println(d.get(i));
+        }
+
+        d = new HsqlArrayList();
+
+        for (int i = 0; i < 12; i++) {
+            d.add(new Integer(i));
+        }
+
+        d.set(11, new Integer(11));
+
+        for (int i = 0; i < d.size(); i++) {
+            System.out.println(d.get(i));
+        }
+
+        org.hsqldb.lib.Iterator it = d.iterator();
+
+        for (int i = 0; it.hasNext(); i++) {
+            Integer value = (Integer) it.next();
+
+            System.out.println(value);
+            assertEquals(i, value.intValue());
+        }
+
+        //-
+        assertEquals(12, d.size());
+    }
+
+    public void testSpeed() {
+
+        randomGenerator = new Random(System.currentTimeMillis());
+
+        int           TEST_RUNS     = 100000;
+        int           LOOP_COUNT    = 1000;
+        HsqlArrayList arrayList     = new HsqlArrayList(TEST_RUNS);
+        ArrayList     utilArrayList = new ArrayList(TEST_RUNS);
+        Vector        vector        = new Vector(TEST_RUNS);
+        Integer       value         = new Integer(randomGenerator.nextInt());
+        Integer       INT_0         = new Integer(0);
+        StopWatch     sw            = new StopWatch();
+
+        System.out.println(sw.currentElapsedTimeToMessage("time"));
+
+        for (int i = 0; i < TEST_RUNS; i++) {
+            arrayList.add(INT_0);
+        }
+
+        for (int i = 0; i < TEST_RUNS; i++) {
+            for (int j = 0; j < LOOP_COUNT; j++) {
+                arrayList.set(i, INT_0);
+            }
+        }
+
+        System.out.println(sw.currentElapsedTimeToMessage("time HsqlArrayLsit"));
+        sw.zero();
+
+        for (int i = 0; i < TEST_RUNS; i++) {
+            utilArrayList.add(INT_0);
+        }
+
+        for (int i = 0; i < TEST_RUNS; i++) {
+            for (int j = 0; j < LOOP_COUNT; j++) {
+                utilArrayList.set(i, INT_0);
+            }
+        }
+
+        System.out.println(sw.currentElapsedTimeToMessage("time ArrayList"));
+        sw.zero();
+
+        for (int i = 0; i < TEST_RUNS; i++) {
+            vector.addElement(INT_0);
+        }
+
+        for (int i = 0; i < TEST_RUNS; i++) {
+            for (int j = 0; j < LOOP_COUNT; j++) {
+                vector.setElementAt(INT_0, i);
+            }
+        }
+
+        System.out.println(sw.currentElapsedTimeToMessage("time Vector"));
+    }
+
+    public static void main(String[] args) {
+
+        TestDataStructures test = new TestDataStructures("testLists");
+
+        for (int i = 0; i < NUMBER_OF_TEST_RUNS; i++) {
+            test.testLists();
+
+            if (i % 1000 == 0) {
+                System.out.println("Finished " + i + " tests");
+                System.out.flush();
+            }
+        }
+
+        System.out.println(
+            "After " + NUMBER_OF_TEST_RUNS + " tests of a maximum of "
+            + NUMBER_OF_ITERATIONS_PER_RUN
+            + " list commands each test, the list tests passed");
+        test.testGrowth();
+    }
+}
diff --git a/src/org/hsqldb/test/TestDatabaseMetaData.java b/src/org/hsqldb/test/TestDatabaseMetaData.java
new file mode 100644
index 0000000..3a0c620
--- /dev/null
+++ b/src/org/hsqldb/test/TestDatabaseMetaData.java
@@ -0,0 +1,274 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+public class TestDatabaseMetaData extends TestBase {
+
+    public TestDatabaseMetaData(String name) {
+        super(name);
+    }
+
+    public void testOne() throws Exception {
+
+        Connection        conn = newConnection();
+        PreparedStatement pstmt;
+        int               updateCount;
+
+        try {
+            pstmt = conn.prepareStatement("DROP TABLE t1 IF EXISTS");
+
+            pstmt.executeUpdate();
+            pstmt.close();
+
+            pstmt = conn.prepareStatement(
+                "CREATE TABLE t1 (cha CHARACTER, dec DECIMAL, doub DOUBLE, lon BIGINT, \"IN\" INTEGER, sma SMALLINT, tin TINYINT, "
+                + "dat DATE DEFAULT CURRENT_DATE, tim TIME DEFAULT CURRENT_TIME, timest TIMESTAMP DEFAULT CURRENT_TIMESTAMP );");
+            updateCount = pstmt.executeUpdate();
+
+            assertTrue("expected update count of zero", updateCount == 0);
+
+            pstmt = conn.prepareStatement("CREATE INDEX t1 ON t1 (cha );");
+            updateCount = pstmt.executeUpdate();
+            pstmt       = conn.prepareStatement("DROP TABLE t2 IF EXISTS");
+            updateCount = pstmt.executeUpdate();
+            pstmt = conn.prepareStatement(
+                "CREATE TABLE t2 (cha CHARACTER, dec DECIMAL, doub DOUBLE, lon BIGINT, \"IN\" INTEGER, sma SMALLINT, tin TINYINT, "
+                + "dat DATE DEFAULT CURRENT_DATE, tim TIME DEFAULT CURRENT_TIME, timest TIMESTAMP DEFAULT CURRENT_TIMESTAMP );");
+            updateCount = pstmt.executeUpdate();
+            pstmt = conn.prepareStatement("CREATE INDEX t2 ON t2 (cha );");
+            updateCount = pstmt.executeUpdate();
+
+            DatabaseMetaData dbmd = conn.getMetaData();
+            ResultSet        rsp  = dbmd.getTablePrivileges(null, null, "T1");
+
+            while (rsp.next()) {
+                System.out.println("Table: " + rsp.getString(3) + " priv: "
+                                   + rsp.getString(6));
+            }
+
+            rsp = dbmd.getIndexInfo(null, null, "T1", false, false);
+
+            while (rsp.next()) {
+                System.out.println("Table: " + rsp.getString(3)
+                                   + " IndexName: " + rsp.getString(6));
+            }
+
+            rsp = dbmd.getIndexInfo(null, null, "T2", false, false);
+
+            while (rsp.next()) {
+                System.out.println("Table: " + rsp.getString(3)
+                                   + " IndexName: " + rsp.getString(6));
+            }
+
+            pstmt       = conn.prepareStatement("DROP INDEX t2;");
+            updateCount = pstmt.executeUpdate();
+            rsp         = dbmd.getIndexInfo(null, null, "T2", false, false);
+
+            assertTrue("expected getIndexInfo returns empty resultset",
+                       rsp.next() == false);
+
+            ResultSet rs = dbmd.getTables(null, null, "T1",
+                                          new String[]{ "TABLE" });
+            ArrayList tablesarr = new ArrayList();
+            int       i;
+
+            for (i = 0; rs.next(); i++) {
+                String tempstr =
+                    rs.getString("TABLE_NAME").trim().toLowerCase();
+
+                tablesarr.add(tempstr);
+            }
+
+            rs.close();
+            assertTrue("expected table t1 count of 1", i == 1);
+
+            Iterator it = tablesarr.iterator();
+
+            for (; it.hasNext(); ) {
+
+                // create new ArrayList and HashMap for the table
+                String tablename = ((String) it.next()).trim();
+                List   collist   = new ArrayList(30);
+
+                rs = dbmd.getColumns(null, null, tablename.toUpperCase(),
+                                     null);
+
+                for (i = 0; rs.next(); i++) {
+                    collist.add(
+                        rs.getString("COLUMN_NAME").trim().toLowerCase());
+                }
+
+                rs.close();
+            }
+
+            pstmt = conn.prepareStatement("DROP TABLE t_1 IF EXISTS");
+
+            pstmt.executeUpdate();
+            pstmt.close();
+
+            pstmt = conn.prepareStatement(
+                "CREATE TABLE t_1 (cha CHARACTER(10), deci DECIMAL(10,2), doub DOUBLE, lon BIGINT, \"IN\" INTEGER, sma SMALLINT, tin TINYINT, "
+                + "dat DATE DEFAULT CURRENT_DATE, tim TIME DEFAULT CURRENT_TIME, timest TIMESTAMP DEFAULT CURRENT_TIMESTAMP, bool BOOLEAN );");
+            updateCount = pstmt.executeUpdate();
+
+            assertTrue("expected update count of zero", updateCount == 0);
+
+            rs = dbmd.getTables(null, null, "T\\_1", new String[]{ "TABLE" });
+
+            for (i = 0; rs.next(); i++) {
+                String tempstr =
+                    rs.getString("TABLE_NAME").trim().toLowerCase();
+
+                tablesarr.add(tempstr);
+            }
+
+            rs.close();
+            assertTrue("expected table t_1 count of 1", i == 1);
+
+            // test various methods
+            dbmd.getPrimaryKeys(null, null, "T_1");
+            dbmd.getImportedKeys(null, null, "T_1");
+            dbmd.getCrossReference(null, null, "T_1", null, null, "T_1");
+
+            // test ResultSetMetaData
+            pstmt = conn.prepareStatement(
+                "INSERT INTO T_1 (cha, deci, doub) VALUES ('name', 10.23, 0)");
+
+            pstmt.executeUpdate();
+            pstmt.close();
+
+            pstmt = conn.prepareStatement("SELECT * FROM T_1");
+            rs    = pstmt.executeQuery();
+
+            ResultSetMetaData md = rs.getMetaData();
+            int               x  = md.getColumnDisplaySize(1);
+            int               y  = md.getColumnDisplaySize(2);
+            int               b  = md.getPrecision(2);
+            int               c  = md.getScale(1);
+            int               d  = md.getScale(2);
+            String            e  = md.getColumnClassName(10);
+            boolean testresult = (x == 10) && (y == 12) && (b == 10)
+                                 && (c == 0) && (d == 2)
+                                 && e.equals("java.sql.Timestamp");
+
+            assertTrue("wrong result metadata", testresult);
+
+            e          = md.getColumnClassName(11);
+            testresult = e.equals("java.lang.Boolean");
+
+            assertTrue("wrong result metadata", testresult);
+            pstmt.close();
+
+            //
+        } catch (Exception e) {
+            assertTrue("unable to prepare or execute DDL", false);
+        } finally {
+            conn.close();
+        }
+    }
+
+    /**
+     * Basic test of DatabaseMetaData functions that access system tables
+     */
+    public void testTwo() throws Exception {
+
+        Connection conn = newConnection();
+        int updateCount;
+
+        try {
+            TestUtil.testScript(conn, "testrun/hsqldb/TestSelf.txt");
+
+            DatabaseMetaData dbmeta = conn.getMetaData();
+
+            dbmeta.allProceduresAreCallable();
+            dbmeta.getBestRowIdentifier(null, null, "T_1",
+                                        DatabaseMetaData.bestRowTransaction, true);
+            dbmeta.getCatalogs();
+            dbmeta.getColumnPrivileges(null, "PUBLIC", "T_1", "%");
+            dbmeta.getColumns("PUBLIC", "PUBLIC", "T_1", "%");
+            dbmeta.getCrossReference(null, null, "T_1", null, null, "T_1");
+            dbmeta.getExportedKeys(null, null, "T_1");
+            dbmeta.getFunctionColumns(null, "%", "%", "%");
+            dbmeta.getFunctions(null, "%", "%");
+            dbmeta.getImportedKeys("PUBLIC", "PUBLIC", "T_1");
+            dbmeta.getIndexInfo("PUBLIC", "PUBLIC", "T1", true, true);
+            dbmeta.getPrimaryKeys("PUBLIC", "PUBLIC", "T_1");
+            dbmeta.getProcedureColumns(null, null, "%", "%");
+            dbmeta.getProcedures("PUBLIC", "%", "%");
+            dbmeta.getSchemas(null, "#");
+            dbmeta.getTablePrivileges(null, "%", "%");
+            dbmeta.getUDTs(null, "%", "%", new int[] {Types.DISTINCT});
+
+        }
+        catch (Exception e) {
+            assertTrue("unable to prepare or execute DDL", false);
+        }
+        finally {
+            conn.close();
+        }
+    }
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestDatabaseMetaData("test");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println("TestDatabaseMetaData failure count: " + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestDateTime.java b/src/org/hsqldb/test/TestDateTime.java
new file mode 100644
index 0000000..7a81218
--- /dev/null
+++ b/src/org/hsqldb/test/TestDateTime.java
@@ -0,0 +1,335 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.text.DateFormat;
+import java.util.Calendar;
+
+import junit.framework.Assert;
+
+/**
+ * Tests for normalisation of Time and Date values.
+ * Base on the original test submission.
+ * @author Miro Halas
+ */
+public class TestDateTime extends TestBase {
+
+    public TestDateTime(String s) {
+        super(s);
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            Connection connection = super.newConnection();
+            Statement  statement  = connection.createStatement();
+
+            statement.execute("drop table time_test if exists");
+            statement.execute("drop table date_test if exists");
+            statement.execute("create table time_test(time_test time)");
+            statement.execute("create table date_test(date_test date)");
+            connection.close();
+        } catch (Exception e) {}
+    }
+
+    /**
+     * Test the database support for Date objects. Date object ignores the time
+     * portion of the Java Date.
+     *
+     * This class inserts date into database, then retrieve it back using
+     * different java time
+     *
+     * @throws Throwable - an error has occured during test
+     */
+    public void testBasicDateSupport() throws Throwable {
+
+        final String INSERT_DATE =
+            "insert into date_test(date_test) values (?)";
+
+        // See OracleTests class why we need to select tablename.*
+        final String SELECT_DATE =
+            "select date_test.* from date_test where date_test = ?";
+        final String DELETE_DATE =
+            "delete from date_test where date_test = ?";
+        Calendar          calGenerate = Calendar.getInstance();
+        java.sql.Date     insertDate;
+        Connection        connection = super.newConnection();
+        PreparedStatement insertStatement;
+        int               iUpdateCount = 0;
+
+        // Set date of my birthday ;-)
+        calGenerate.set(1995, 9, 15, 1, 2, 3);
+
+        insertDate      = new java.sql.Date(calGenerate.getTimeInMillis());
+        insertStatement = connection.prepareStatement(INSERT_DATE);
+
+        insertStatement.setDate(1, insertDate);
+
+        iUpdateCount = insertStatement.executeUpdate();
+
+        insertStatement.close();
+        Assert.assertEquals(
+            "Exactly one record with date data shoud have been inserted.",
+            iUpdateCount, 1);
+
+        // Now select it back to be sure it is there
+        PreparedStatement selectStatement = null;
+        PreparedStatement deleteStatement = null;
+        ResultSet         results         = null;
+        java.sql.Date     retrievedDate   = null;
+        boolean           bHasMoreThanOne;
+        int               iDeletedCount = 0;
+
+        // Set different time, since when we are dealing with just dates it
+        // shouldn't matter
+        calGenerate.set(1995, 9, 15, 2, 3, 4);
+
+        java.sql.Date selectDate =
+            new java.sql.Date(calGenerate.getTimeInMillis());
+
+        selectStatement = connection.prepareStatement(SELECT_DATE);
+
+        selectStatement.setDate(1, selectDate);
+
+        results = selectStatement.executeQuery();
+
+        // Get the date from the database
+        Assert.assertTrue("The inserted date is not in the database.",
+                          results.next());
+
+        retrievedDate   = results.getDate(1);
+        deleteStatement = connection.prepareStatement(DELETE_DATE);
+
+        deleteStatement.setDate(1, insertDate);
+
+        iDeletedCount = deleteStatement.executeUpdate();
+
+        deleteStatement.close();
+        Assert.assertEquals(
+            "Exactly one record with date data shoud have been deleted.",
+            iDeletedCount, 1);
+
+        boolean result = retrievedDate.toString().startsWith(
+            insertDate.toString().substring(0, 10));
+
+        Assert.assertTrue(
+            "The date retrieved from database "
+            + DateFormat.getDateTimeInstance().format(retrievedDate)
+            + " is not the same as the inserted one "
+            + DateFormat.getDateTimeInstance().format(insertDate), result);
+    }
+
+    public void testBasicDefaultTimeSupport() throws Throwable {
+
+        final String INSERT_TIME =
+            "insert into time_test(time_test) values (?)";
+
+        // See OracleTests class why we need to select tablename.*
+        final String SELECT_TIME =
+            "select time_test.* from time_test where time_test = ?";
+        final String DELETE_TIME =
+            "delete from time_test where time_test = ?";
+        java.sql.Time     insertTime;
+        Connection        connection = super.newConnection();
+        PreparedStatement insertStatement;
+        int               iUpdateCount = 0;
+
+        insertTime      = new java.sql.Time(3600000);
+        insertStatement = connection.prepareStatement(INSERT_TIME);
+
+        insertStatement.setTime(1, insertTime);
+
+        iUpdateCount = insertStatement.executeUpdate();
+
+        insertStatement.close();
+        Assert.assertEquals(
+            "Exactly one record with time data shoud have been inserted.",
+            iUpdateCount, 1);
+
+        // Now select it back to be sure it is there
+        PreparedStatement selectStatement = null;
+        PreparedStatement deleteStatement = null;
+        ResultSet         results         = null;
+        java.sql.Time     retrievedTime;
+        int               iDeletedCount = 0;
+        java.sql.Time     selectTime;
+
+        selectStatement = connection.prepareStatement(SELECT_TIME);
+
+        selectTime = new java.sql.Time(3600000);
+
+        selectStatement.setTime(1, selectTime);
+
+        results = selectStatement.executeQuery();
+
+        // Get the date from the database
+        Assert.assertTrue("The inserted time is not in the database.",
+                          results.next());
+
+        retrievedTime = results.getTime(1);
+
+        //
+        deleteStatement = connection.prepareStatement(DELETE_TIME);
+
+        deleteStatement.setTime(1, insertTime);
+
+        iDeletedCount = deleteStatement.executeUpdate();
+
+        Assert.assertEquals(
+            "Exactly one record with time data shoud have been deleted.",
+            iDeletedCount, 1);
+
+        // And now test the date
+        Assert.assertNotNull(
+            "The inserted time shouldn't be retrieved as null from the database",
+            retrievedTime);
+
+        // Ignore milliseconds when comparing dates
+        String selectString = selectTime.toString();
+        String retrievedString = retrievedTime.toString();
+
+        boolean result =
+            retrievedString.equals(selectString);
+
+        Assert.assertTrue(
+            "The time retrieved from database "
+            + DateFormat.getDateTimeInstance().format(retrievedTime)
+            + " is not the same as the inserted one "
+            + DateFormat.getDateTimeInstance().format(insertTime), result);
+    }
+
+    /**
+     * Test the database support for Time objects. Time object ignores the date
+     * portion of the Java Date.
+     *
+     * This class inserts time into database, then retrieve it back using
+     * different java date and deletes it using cursor.
+     *
+     * Uses the already setup connection and transaction.
+     * No need to close the connection since base class is doing it for us.
+     *
+     * @throws Throwable - an error has occured during test
+     */
+    public void testBasicTimeSupport() throws Throwable {
+
+        final String INSERT_TIME =
+            "insert into time_test(time_test) values (?)";
+
+        // See OracleTests class why we need to select tablename.*
+        final String SELECT_TIME =
+            "select time_test.* from time_test where time_test = ?";
+        final String DELETE_TIME =
+            "delete from time_test where time_test = ?";
+        Calendar          calGenerate = Calendar.getInstance();
+        java.sql.Time     insertTime;
+        Connection        connection = super.newConnection();
+        PreparedStatement insertStatement;
+        int               iUpdateCount = 0;
+
+        // Set date of my birthday ;-)
+        calGenerate.set(1995, 9, 15, 1, 2, 3);
+
+        insertTime      = new java.sql.Time(calGenerate.getTime().getTime());
+        insertStatement = connection.prepareStatement(INSERT_TIME);
+
+        insertStatement.setTime(1, insertTime, calGenerate);
+
+        iUpdateCount = insertStatement.executeUpdate();
+
+        insertStatement.close();
+        Assert.assertEquals(
+            "Exactly one record with time data shoud have been inserted.",
+            iUpdateCount, 1);
+
+        // Now select it back to be sure it is there
+        PreparedStatement selectStatement = null;
+        PreparedStatement deleteStatement = null;
+        ResultSet         results         = null;
+        java.sql.Time     retrievedTime;
+        int               iDeletedCount = 0;
+        java.sql.Time     selectTime;
+
+        selectStatement = connection.prepareStatement(SELECT_TIME);
+
+        // Set different date, since when we are dealing with just time it
+        // shouldn't matter
+        // fredt - but make sure the date is in the same daylight saving range as today !
+        calGenerate.set(1975, 9, 16, 1, 2, 3);
+
+        selectTime = new java.sql.Time(calGenerate.getTime().getTime());
+
+        selectStatement.setTime(1, selectTime, calGenerate);
+
+        results = selectStatement.executeQuery();
+
+        // Get the date from the database
+        Assert.assertTrue("The inserted time is not in the database.",
+                          results.next());
+
+        retrievedTime = results.getTime(1, calGenerate);
+
+        //
+        deleteStatement = connection.prepareStatement(DELETE_TIME);
+
+        deleteStatement.setTime(1, insertTime, calGenerate);
+
+        iDeletedCount = deleteStatement.executeUpdate();
+
+        Assert.assertEquals(
+            "Exactly one record with time data shoud have been deleted.",
+            iDeletedCount, 1);
+
+        // And now test the date
+        Assert.assertNotNull(
+            "The inserted time shouldn't be retrieved as null from the database",
+            retrievedTime);
+
+        // Ignore milliseconds when comparing dates
+        String selectString = selectTime.toString();
+        String retrievedString = retrievedTime.toString();
+
+        boolean result =
+            retrievedString.equals(selectString);
+
+        Assert.assertTrue(
+            "The time retrieved from database "
+            + DateFormat.getDateTimeInstance().format(retrievedTime)
+            + " is not the same as the inserted one "
+            + DateFormat.getDateTimeInstance().format(insertTime), result);
+    }
+}
diff --git a/src/org/hsqldb/test/TestDatetimeSimple.java b/src/org/hsqldb/test/TestDatetimeSimple.java
new file mode 100644
index 0000000..294d955
--- /dev/null
+++ b/src/org/hsqldb/test/TestDatetimeSimple.java
@@ -0,0 +1,250 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.TimeZone;
+import java.sql.SQLException;
+
+/**
+ * Date Test Case.
+ */
+public class TestDatetimeSimple extends junit.framework.TestCase {
+
+    static {
+        try {
+            Class.forName("org.hsqldb.jdbcDriver");
+        } catch (ClassNotFoundException cnfe) {
+            throw new RuntimeException(
+                "<clinit> failed.  JDBC Driver class not in CLASSPATH");
+        }
+    }
+
+    public void testSimple() throws SQLException {
+
+        Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:m",
+            "SA", "");
+        ResultSet         rs;
+        PreparedStatement ps;
+        Statement         st = conn.createStatement();
+
+        st.executeUpdate("CREATE TABLE t(i int, d date)");
+        st.executeUpdate("INSERT INTO t VALUES(1, '2008-11-27')");
+
+        rs = st.executeQuery("SELECT d FROM t");
+
+        rs.next();
+        System.out.println("Object: " + rs.getObject("d")               //
+                           + " ; Timestamp: " + rs.getTimestamp("d")    //
+                           + " ; Date: " + rs.getDate("d")              //
+                           + " ; String: " + rs.getString("d"));
+        rs.close();
+
+        rs = st.executeQuery("SELECT count(*) c FROM t WHERE d = "
+                             + "'2008-11-27'");
+
+        rs.next();
+        System.out.println("Match? " + (rs.getInt("c") > 0));
+        st.executeUpdate("DELETE FROM t");
+
+        /* This is prohibited:
+
+        st.executeUpdate("INSERT INTO t VALUES(2, '2008-11-27 0:00:00')");
+
+        Q: Do we want to prohibit this, even though we permit the same
+        usage with PreparedStatement using a Timestamp, as follows?
+
+        A: In the disallowed case, a String that is not a data string is used,
+           while in the other case, a timestamp object is used. It follows the
+           cast specification, which requires the String to be a valid date
+           string, and allows casting from a TIMESTAMP object to DATE
+
+        */
+        ps = conn.prepareStatement("INSERT INTO t VALUES(3, ?)");
+
+        ps.setTimestamp(1, java.sql.Timestamp.valueOf("2008-10-27 0:00:00"));
+        ps.execute();
+        ps.close();
+
+        rs = st.executeQuery("SELECT d FROM t");
+
+        rs.next();
+        System.out.println("Object: " + rs.getObject("d")                 //
+                           + " ; Date: " + rs.getDate("d")                //
+                           + " ; Timestamp: " + rs.getTimestamp("d") +    //
+                               "; String: " + rs.getString("d"));
+        rs.close();
+
+        rs = st.executeQuery("SELECT count(*) c FROM t WHERE d = "
+                             + "'2008-10-27'");
+
+        /* FRED:  When the DATE value is inserted with a TIMESTAMP,
+         * all matches using a date fail.  The query here fails regardless
+         * of what date I use. */
+        rs.next();
+        System.out.println("Match? " + (rs.getInt("c") > 0));
+
+        /** ********  TIMESTAMP COL BELOW ********* */
+        st.executeUpdate("CREATE TABLE t2(i int, ts timestamp)");
+        /* These all fail:
+        st.executeUpdate("INSERT INTO t2 VALUES(1, '2008-11-27')");
+        st.executeUpdate("INSERT INTO t2 VALUES(1, timestamp '2008-11-27')");
+        in both cases, the string is not a valid timestamp string
+        */
+        st.executeUpdate(
+            "INSERT INTO t2 VALUES(1, timestamp '2008-11-27 12:30:00')");
+        st.executeUpdate("INSERT INTO t2 VALUES(1, '2008-11-27 12:30:00')");
+
+        /** FOLLOWING ALL WORK AS EXPECTED: */
+        ps = conn.prepareStatement("INSERT INTO t2 VALUES(2, ?)");
+
+        ps.setTimestamp(1, java.sql.Timestamp.valueOf("2008-10-27 0:00:00"));
+        ps.execute();
+        ps.close();
+
+        rs = st.executeQuery("SELECT ts FROM t2");
+
+        rs.next();
+        System.out.println("Object: " + rs.getObject("ts")                //
+                           + " ; Timestamp: " + rs.getTimestamp("ts")    //
+                           + " ; Date: " + rs.getObject("ts")            //
+                           + "; String: " + rs.getString("ts"));
+        rs.close();
+        st.executeUpdate("SHUTDOWN");
+        conn.close();
+    }
+
+    public void testValues() throws SQLException {
+
+        Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:m",
+            "SA", "");
+        ResultSet          rs;
+        PreparedStatement  ps;
+        String             s;
+        Object             o;
+        java.sql.Date      d;
+        java.sql.Timestamp ts;
+        Statement          st = conn.createStatement();
+
+        st.executeUpdate("CREATE TABLE t(d date)");
+        st.executeUpdate("INSERT INTO t VALUES('2008-11-27')");
+
+        rs = st.executeQuery("SELECT d FROM t");
+
+        rs.next();
+
+        s  = rs.getString("d");
+        o  = rs.getObject("d");
+        d  = rs.getDate("d");
+        ts = rs.getTimestamp("d");
+
+        System.out.println("2008-11-27 INSERTED" + "\n    String: " + s
+                           + "\n    Object: " + o + "\n    Date: " + dump(d)
+                           + "\n    Timestamp: " + dump(ts) + '\n');
+        rs.close();
+
+        rs = st.executeQuery("CALL CURRENT_DATE");
+
+        rs.next();
+
+        o  = rs.getObject(1);
+        d  = rs.getDate(1);
+        s  = rs.getString(1);
+        ts = rs.getTimestamp(1);
+
+        System.out.println("CURRENT_DATE @" + new java.util.Date()
+                           + "\n    String: " + s + "\n    Object: " + o
+                           + "\n    Date: " + dump(d) + "\n    Timestamp: "
+                           + dump(ts) + '\n');
+        rs.close();
+
+        rs = st.executeQuery("CALL LOCALTIMESTAMP");
+
+        rs.next();
+
+        o  = rs.getObject(1);
+        s  = rs.getString(1);
+        ts = rs.getTimestamp(1);
+
+        System.out.println("LOCALTIMESTAMP @" + new java.util.Date()
+                           + "\n    String: " + s + "\n    Object: " + o
+                           + "\n    Timestamp: " + dump(ts) + '\n');
+        rs.close();
+
+        rs = st.executeQuery("CALL CURRENT_TIMESTAMP");
+
+        rs.next();
+
+        s  = rs.getString(1);
+        o  = rs.getObject(1);
+        ts = rs.getTimestamp(1);
+
+        System.out.println("CURRENT_TIMESTAMP @" + new java.util.Date()
+                           + "\n    String: " + s + "\n    Object: " + o
+                           + "\n    Timestamp: " + dump(ts) + '\n');
+        rs.close();
+        st.executeUpdate("SHUTDOWN");
+        conn.close();
+    }
+
+    static public String dump(java.sql.Timestamp t) {
+        return "String (" + t.toString() + "), GMTString (" + t.toGMTString()
+               + "), LocalString (" + t.toLocaleString() + ')';
+    }
+
+    static public String dump(java.sql.Date d) {
+        return "String (" + d.toString() + "), GMTString (" + d.toGMTString()
+               + "), LocalString (" + d.toLocaleString() + ')';
+    }
+
+    public static void main(String[] argv) {
+
+        TestDatetimeSimple testA = new TestDatetimeSimple();
+        String[]           zones = { "GMT-05:00" };
+
+        try {
+            for (int i = 0; i < zones.length; i++) {
+                TimeZone timeZone = TimeZone.getTimeZone(zones[i]);
+
+                TimeZone.setDefault(timeZone);
+                testA.testSimple();
+                testA.testValues();
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestDbBackup.java b/src/org/hsqldb/test/TestDbBackup.java
new file mode 100644
index 0000000..a11288f
--- /dev/null
+++ b/src/org/hsqldb/test/TestDbBackup.java
@@ -0,0 +1,625 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+
+import org.hsqldb.lib.tar.DbBackup;
+import org.hsqldb.lib.tar.TarMalformatException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class TestDbBackup extends junit.framework.TestCase {
+
+    public TestDbBackup() throws IOException, SQLException {}
+
+    static protected File baseDir =
+        new File(System.getProperty("java.io.tmpdir"),
+                 "TestDbBackup-" + System.getProperty("user.name"));
+
+    static {
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+        } catch (ClassNotFoundException cnfe) {
+            throw new RuntimeException(
+                "<clinit> failed.  JDBC Driver class not in CLASSPATH");
+        }
+    }
+
+    /**
+     * Individual test methods may or may not need a Connection.
+     * If they do, they run setupConn() then use 'conn', and it will be
+     * automatically closed by the tearDown() method.
+     *
+     * @see #tearDown()
+     */
+    protected void setupConn(String id) throws SQLException {
+        conn = getConnection(id);
+        alreadyShut = false;
+    }
+
+    protected void shutdownAndCloseConn() throws SQLException {
+
+        if (conn == null) {
+            return;
+        }
+        if (!alreadyShut) {
+            conn.createStatement().executeUpdate("SHUTDOWN");
+            alreadyShut = true;
+        }
+        if (verbose) {
+            System.err.println("Shut down 'db1'");
+        }
+        conn.close();
+
+        conn = null;
+    }
+
+    /**
+     * Use setupConn() to set up this Connection for just this individual test.
+     *
+     * @see #setupConn(String)
+     */
+    protected Connection conn = null;
+    protected boolean alreadyShut = false;
+
+    /**
+     * Remove the specified directory and all of it's descendants.
+     *
+     * @throws IOException if unable to completely remove the specified dir
+     */
+    protected void rmR(File dir) throws IOException {
+
+        if (!dir.exists()) {
+            throw new IOException("Specified dir does not exist: "
+                                  + dir.getAbsolutePath());
+        }
+
+        File[] children = dir.listFiles();
+
+        for (int i = 0; i < children.length; i++) {
+            if (children[i].isDirectory()) {
+                rmR(children[i]);
+            } else if (!children[i].delete()) {
+                throw new IOException("Failed to remove '"
+                                      + children[i].getAbsolutePath() + "'");
+            }
+        }
+
+        if (!dir.delete()) {
+            throw new IOException("Failed to remove '" + dir.getAbsolutePath()
+                                  + "'");
+        }
+    }
+
+    /**
+     * Accommodate JUnit's test-runner conventions.
+     */
+    public TestDbBackup(String s) throws IOException, SQLException {
+        super(s);
+    }
+
+    /**
+     * JUnit convention for cleanup.
+     *
+     * Called after each test*() method.
+     */
+    protected void tearDown() throws IOException, SQLException {
+
+        if (baseDir.exists()) {
+            rmR(baseDir);
+            if (verbose) {
+                System.err.println("Tore down");
+            }
+        }
+    }
+
+    static boolean verbose = Boolean.getBoolean("VERBOSE");
+
+    /**
+     * Specifically, this method creates and populates "db1", then closes it.
+     *
+     * Invoked before each test*() invocation by JUnit.
+     */
+    protected void setUp() throws IOException, SQLException {
+        if (verbose) {
+            System.err.println("Set-upping");
+        }
+
+        if (baseDir.exists()) {
+            throw new IOException(
+                    "Please wipe out work directory '"
+                    + baseDir + ", which is probably left over from an "
+                    + "aborted test run");
+        }
+
+        try {
+            setupConn("db1");
+
+            Statement st = conn.createStatement();
+
+            st.executeUpdate("CREATE TABLE t(i int);");
+            st.executeUpdate("INSERT INTO t values(34);");
+            conn.commit();
+        } catch (SQLException se) {}
+        finally {
+            shutdownAndCloseConn();
+        }
+    }
+
+    /**
+     * Make sure to close after using the returned connection
+     * (like in a finally block).
+     */
+    protected Connection getConnection(String id) throws SQLException {
+
+        Connection c = DriverManager.getConnection("jdbc:hsqldb:file:"
+            + baseDir.getAbsolutePath() + '/' + id + "/dbfile", "SA", "");
+
+        if (verbose) {
+            System.err.println("Opening JDBC URL '"
+                    + "jdbc:hsqldb:file:" + baseDir.getAbsolutePath()
+                    + '/' + id + "/dbfile");
+        }
+
+        c.setAutoCommit(false);
+
+        return c;
+    }
+
+    /**
+     * This method allows to easily run this unit test independent of the other
+     * unit tests, and without dealing with Ant or unrelated test suites.
+     */
+    static public void main(String[] sa) {
+        if (sa.length > 0 && !sa[sa.length - 1].equals("-g")) {
+            TestDbBackup.baseDir = new File(sa[0]);
+
+            if (baseDir.exists()) {
+                throw new IllegalArgumentException(
+                    "If you specify a work directory, it must not exist "
+                    + "yet.  (This makes it much easier for us to clean up "
+                    + "after ourselves).");
+            }
+
+            System.err.println("Using user-specified base dir: "
+                               + baseDir.getAbsolutePath());
+        }
+            junit.textui.TestRunner runner = new junit.textui.TestRunner();
+            junit.framework.TestResult result =
+                runner.run(runner.getTest(TestDbBackup.class.getName()));
+
+            System.exit(result.wasSuccessful() ? 0 : 1);
+    }
+
+    public void testSanity() throws SQLException {
+
+        try {
+            setupConn("db1");
+
+            ResultSet rs =
+                conn.createStatement().executeQuery("SELECT * FROM t;");
+
+            rs.next();
+            assertEquals("Wrong table 't' contents", 34, rs.getInt("i"));
+        } finally {
+            shutdownAndCloseConn();
+        }
+    }
+
+    public void testBasicBackup()
+    throws SQLException, IOException, TarMalformatException {
+        mainBackupAndRestore("basic.tar");
+    }
+
+    public void testGzip()
+    throws SQLException, IOException, TarMalformatException {
+        mainBackupAndRestore("compressed.tar.gz");
+    }
+
+    /**
+     * Test all forms of online backups with explicit filenames.
+     */
+    public void testOnlineBackup()
+    throws SQLException, IOException, TarMalformatException {
+        onlineBackupAndRestore("online.tar", true, false, "db11");
+        onlineBackupAndRestore("online.tar.gz", false, true, "db12");
+        onlineBackupAndRestore("online.tgz", false, true, "db13");
+    }
+
+    public void onlineBackupAndRestore(String baseTarName,
+            boolean populate, boolean compress, String restoreDest)
+    throws SQLException, IOException, TarMalformatException {
+
+        try {
+            setupConn("db1");
+            conn.createStatement().executeUpdate("DELETE FROM t");
+            // For this case, we wipe the data that we so carefully set up,
+            // so that we can call this method repeatedly without worrying
+            // about left-over data from a previous run.
+            conn.commit();
+            conn.createStatement().executeUpdate("INSERT INTO t VALUES(1)");
+            conn.createStatement().executeUpdate("INSERT INTO t VALUES(2)");
+            conn.createStatement().executeUpdate("INSERT INTO t VALUES(3)");
+            conn.commit();
+            conn.createStatement().executeUpdate("INSERT INTO t VALUES(4)");
+            conn.createStatement().executeUpdate("INSERT INTO t VALUES(5)");
+            conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                                                 + baseDir.getAbsolutePath()
+                                                 + '/' + baseTarName
+                                                 + "' BLOCKING"
+                    + (compress ? "" : " NOT COMPRESSED"));
+            conn.createStatement().executeUpdate(
+                    "INSERT INTO t VALUES(6)");
+            conn.commit();
+            conn.createStatement().executeUpdate("SHUTDOWN");
+            alreadyShut = true;
+            if (verbose) {
+                System.err.println("Shut down 'db1'");
+            }
+        } finally {
+            shutdownAndCloseConn();
+        }
+
+        File destDir = new File(baseDir, restoreDest);
+
+        if (!destDir.mkdir()) {
+            throw new IOException("Failed to make new dir. to restore to: "
+                                  + destDir.getAbsolutePath());
+        }
+
+        DbBackup.main(new String[] {
+            "--extract", baseDir.getAbsolutePath() + '/' + baseTarName,
+            destDir.getAbsolutePath()
+        });
+
+        try {
+            setupConn(restoreDest);
+            conn.createStatement().executeUpdate("ROLLBACK");
+
+            ResultSet rs =
+                conn.createStatement().executeQuery("SELECT count(*) c FROM t;");
+
+            rs.next();
+            // 3 committed, 5 uncommited before saving:
+            assertEquals("Wrong table 't' contents", 5, rs.getInt("c"));
+        } finally {
+            shutdownAndCloseConn();
+        }
+    }
+
+    public void mainBackupAndRestore(String baseTarName)
+    throws SQLException, IOException, TarMalformatException {
+
+        DbBackup.main(new String[] {
+            "--save", baseDir.getAbsolutePath() + '/' + baseTarName,
+            baseDir.getAbsolutePath() + "/db1/dbfile"
+        });
+
+        File destDir = new File(baseDir, "mainrestored");
+
+        if (!destDir.mkdir()) {
+            throw new IOException("Failed to make new dir. to restore to: "
+                                  + destDir.getAbsolutePath());
+        }
+
+        DbBackup.main(new String[] {
+            "--extract", baseDir.getAbsolutePath() + '/' + baseTarName,
+            destDir.getAbsolutePath()
+        });
+
+        try {
+            setupConn("mainrestored");
+
+            ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t;");
+
+            rs.next();
+            assertEquals("Wrong table 't' contents", 34, rs.getInt("i"));
+        } finally {
+            shutdownAndCloseConn();
+        }
+    }
+
+    public void testMainAlreadyOpen()
+    throws SQLException, IOException, TarMalformatException {
+
+        try {
+            setupConn("db1");
+
+            try {
+                DbBackup.main(new String[] {
+                    "--save", baseDir.getAbsolutePath() + "/mainOpen.tar",
+                    baseDir.getAbsolutePath() + "/db1/dbfile"
+                });
+            } catch (IllegalStateException ioe) {
+                return;
+            }
+        } finally {
+            shutdownAndCloseConn();
+        }
+
+        fail("Backup from main() did not throw even though DB is open");
+    }
+
+    /**
+     * Test that bad explicit filenames are rejected for onilne backups.
+     */
+    public void testTarFileNames()
+    throws SQLException, IOException, TarMalformatException {
+
+        boolean caught;
+        try {
+            setupConn("db1");
+            conn.createStatement().executeUpdate("INSERT INTO t VALUES(2)");
+            conn.commit();
+
+            // #1:  COMPRESSED -> no-extension
+            caught = false;
+            try {
+                conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                        + baseDir.getAbsolutePath()
+                        + "/x/bad' BLOCKING COMPRESSED");
+            } catch (SQLException se) {
+                caught = true;
+            }
+            if (!caught) {
+                fail("BACKUP did not throw even though requested compression "
+                        + "to file '/x/bad'");
+            }
+            // #2:  NOT COMPRESSED -> no-extension
+            caught = false;
+            try {
+                conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                        + baseDir.getAbsolutePath()
+                        + "/x/bad' BLOCKING NOT COMPRESSED");
+            } catch (SQLException se) {
+                caught = true;
+            }
+            if (!caught) {
+                fail("BACKUP did not throw even though requested "
+                        + "no-compression to file '/x/bad'");
+            }
+            // #3:  COMPRESSED -> *.txt
+            caught = false;
+            try {
+                conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                        + baseDir.getAbsolutePath()
+                        + "/x/bad.txt' BLOCKING COMPRESSED");
+            } catch (SQLException se) {
+                caught = true;
+            }
+            if (!caught) {
+                fail("BACKUP did not throw even though requested compression "
+                        + "to file '/x/bad.txt'");
+            }
+            // #4:  NOT COMPRESSED -> *.txt
+            caught = false;
+            try {
+                conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                        + baseDir.getAbsolutePath()
+                        + "/x/bad.txt' BLOCKING NOT COMPRESSED");
+            } catch (SQLException se) {
+                caught = true;
+            }
+            if (!caught) {
+                fail("BACKUP did not throw even though requested "
+                        + "no-compression to file '/x/bad.txt'");
+            }
+            // #5:  DEFAULT -> *.tar
+            caught = false;
+            try {
+                conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                        + baseDir.getAbsolutePath()
+                        + "/x/bad.tar' BLOCKING");
+            } catch (SQLException se) {
+                caught = true;
+            }
+            if (!caught) {
+                fail("BACKUP did not throw even though requested default "
+                        + "to file '/x/bad.tar'");
+            }
+            // #6:  COMPRESSION -> *.tar
+            caught = false;
+            try {
+                conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                        + baseDir.getAbsolutePath()
+                        + "/x/bad.tar' BLOCKING COMPRESSED");
+            } catch (SQLException se) {
+                caught = true;
+            }
+            if (!caught) {
+                fail("BACKUP did not throw even though requested compression "
+                        + "to file '/x/bad.tar'");
+            }
+            // #7:  NOT COMPRESSED -> *.tar.gz
+            caught = false;
+            try {
+                conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                        + baseDir.getAbsolutePath()
+                        + "/x/bad.tar.gz' BLOCKING NOT COMPRESSED");
+            } catch (SQLException se) {
+                caught = true;
+            }
+            if (!caught) {
+                fail("BACKUP did not throw even though requested "
+                        + "non-compression to file '/x/bad.tar.gz'");
+            }
+            // #8:  NOT COMPRESSED -> *.tgz
+            caught = false;
+            try {
+                conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                        + baseDir.getAbsolutePath()
+                        + "/x/bad.tgz' BLOCKING NOT COMPRESSED");
+            } catch (SQLException se) {
+                caught = true;
+            }
+            if (!caught) {
+                fail("BACKUP did not throw even though requested "
+                        + "non-compression to file '/x/bad.tgz'");
+            }
+
+            // Finally run a test to ensure that the attempts above didn't
+            // fail for some unexpected reason.
+            conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                    + baseDir.getAbsolutePath()
+                    + "/positivetest.tar' BLOCKING NOT COMPRESSED");
+        } finally {
+            shutdownAndCloseConn();
+        }
+
+    }
+
+    /**
+     * Test that correct DB names are generated when user supplies just a
+     * directory.
+     *
+     * N.b.  This test may not work right if tests are run at midnight.
+     * This limitation will be removed once we can update the FilenameFilters
+     * with Java 4's java.util.regex.
+     */
+    public void testAutoNaming()
+    throws SQLException, IOException, TarMalformatException {
+
+        boolean caught;
+        int fileCount;
+        try {
+            setupConn("db1");
+            conn.createStatement().executeUpdate("INSERT INTO t VALUES(2)");
+            conn.commit();
+
+            fileCount = baseDir.listFiles(autoTarFilenameFilter).length;
+            if (fileCount != 0)
+                throw new IllegalStateException(Integer.toString(fileCount)
+                        + " auto-tar files exist in baseDir '"
+                        + baseDir.getAbsolutePath()
+                        + "' before starting testAutoNaming");
+            fileCount = baseDir.listFiles(autoTarGzFilenameFilter).length;
+            if (fileCount != 0)
+                throw new IllegalStateException(Integer.toString(fileCount)
+                        + " auto-tar.gz files exist in baseDir '"
+                        + baseDir.getAbsolutePath()
+                        + "' before starting testAutoNaming");
+            conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                    + baseDir.getAbsolutePath()
+                    + "/' BLOCKING NOT COMPRESSED");
+            fileCount = baseDir.listFiles(autoTarFilenameFilter).length;
+            if (fileCount != 1)
+                fail(Integer.toString(fileCount)
+                        + " auto-tar files exist in baseDir '"
+                        + baseDir.getAbsolutePath()
+                        + "' after writing a non-compressed backup");
+            fileCount = baseDir.listFiles(autoTarGzFilenameFilter).length;
+            if (fileCount != 0)
+                fail(Integer.toString(fileCount)
+                        + " auto-tar.gz files exist in baseDir '"
+                        + baseDir.getAbsolutePath()
+                        + "' after writing a non-compressed backup");
+            conn.createStatement().executeUpdate("BACKUP DATABASE TO '"
+                    + baseDir.getAbsolutePath()
+                    + "/' BLOCKING COMPRESSED");
+            fileCount = baseDir.listFiles(autoTarFilenameFilter).length;
+            if (fileCount != 1)
+                fail(Integer.toString(fileCount)
+                        + " auto-tar files exist in baseDir '"
+                        + baseDir.getAbsolutePath()
+                        + "' after writing both backups");
+            fileCount = baseDir.listFiles(autoTarGzFilenameFilter).length;
+            if (fileCount != 1)
+                fail(Integer.toString(fileCount)
+                        + " auto-tar.gz files exist in baseDir '"
+                        + baseDir.getAbsolutePath()
+                        + "' after writing a compressed backup");
+        } finally {
+            shutdownAndCloseConn();
+        }
+
+    }
+    static public Test suite() throws IOException, SQLException {
+
+        TestSuite newSuite = new TestSuite();
+
+        newSuite.addTest(new TestDbBackup("testSanity"));
+        newSuite.addTest(new TestDbBackup("testBasicBackup"));
+        newSuite.addTest(new TestDbBackup("testMainAlreadyOpen"));
+        newSuite.addTest(new TestDbBackup("testGzip"));
+        newSuite.addTest(new TestDbBackup("testOnlineBackup"));
+        newSuite.addTest(new TestDbBackup("testTarFileNames"));
+        newSuite.addTest(new TestDbBackup("testAutoNaming"));
+
+        return newSuite;
+    }
+
+    private String autoMiddlingString = "-"
+            + new SimpleDateFormat("yyyyMMdd").format(new java.util.Date())
+            + 'T';
+
+    FilenameFilter autoTarFilenameFilter = new FilenameFilter() {
+        private String suffixFormat = "-yyyyMMddTHHmmss.tar";
+        public boolean accept(File dir, String name) {
+            if (name.length() < suffixFormat.length() + 1) {
+                // Require variable name length >= 1 char
+                return false;
+            }
+            int suffixPos = name.length() - suffixFormat.length();
+            // Would like to use Java 1.4's java.util.regex here.
+            return name.endsWith(".tar")
+                    && name.substring(suffixPos,
+                    suffixPos + autoMiddlingString.length())
+                    .equals(autoMiddlingString);
+        }
+    };
+
+    FilenameFilter autoTarGzFilenameFilter = new FilenameFilter() {
+        private String suffixFormat = "-yyyyMMddTHHmmss.tar.gz";
+        public boolean accept(File dir, String name) {
+            if (name.length() < suffixFormat.length() + 1) {
+                // Require variable name length >= 1 char
+                return false;
+            }
+            int suffixPos = name.length() - suffixFormat.length();
+            // Would like to use Java 1.4's java.util.regex here.
+            return name.endsWith(".tar.gz")
+                    && name.substring(suffixPos,
+                    suffixPos + autoMiddlingString.length())
+                    .equals(autoMiddlingString);
+        }
+    };
+}
diff --git a/src/org/hsqldb/test/TestDima.java b/src/org/hsqldb/test/TestDima.java
new file mode 100644
index 0000000..55b8c47
--- /dev/null
+++ b/src/org/hsqldb/test/TestDima.java
@@ -0,0 +1,219 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Properties;
+
+public class TestDima {
+
+    public void testOne() {
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            Connection conn = java.sql.DriverManager.getConnection(
+                "jdbc:hsqldb:file:/hsql/testdima/test", "sa", "");
+
+            conn.setAutoCommit(false);
+
+            Statement stat = conn.createStatement();
+
+            stat.executeUpdate("DROP TABLE BAZ IF EXISTS");
+            stat.executeUpdate("DROP TABLE BAR IF EXISTS");
+            stat.executeUpdate("DROP TABLE FOO IF EXISTS");
+            conn.commit();
+            stat.executeUpdate("CHECKPOINT");
+            stat.executeUpdate(
+                "CREATE CACHED TABLE FOO (ID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, VAL VARCHAR(80))");
+            stat.executeUpdate(
+                "CREATE TABLE BAR (ID INTEGER IDENTITY PRIMARY KEY, FOOID INTEGER NOT NULL, "
+                + "VAL VARCHAR(80), FOREIGN KEY(FOOID) REFERENCES FOO(ID) ON DELETE CASCADE)");
+            stat.executeUpdate(
+                "CREATE TABLE BAZ (ID INTEGER IDENTITY PRIMARY KEY, BARID INTEGER NOT NULL, "
+                + "VAL VARCHAR(80), FOREIGN KEY(BARID) REFERENCES BAR(ID) ON DELETE CASCADE)");
+            conn.commit();
+            stat.executeUpdate("CHECKPOINT");
+            stat.executeUpdate("INSERT INTO FOO (VAL) VALUES ('foo 1')");
+            stat.executeUpdate(
+                "INSERT INTO BAR (FOOID,VAL) VALUES (IDENTITY(),'bar 1')");
+            stat.executeUpdate(
+                "INSERT INTO BAZ (BARID,VAL) VALUES (IDENTITY(),'baz 1')");
+            stat.executeUpdate("INSERT INTO FOO (VAL) VALUES ('foo 2')");
+            stat.executeUpdate(
+                "INSERT INTO BAR (FOOID,VAL) VALUES (IDENTITY(),'bar 2')");
+            stat.executeUpdate(
+                "INSERT INTO BAZ (BARID,VAL) VALUES (IDENTITY(),'baz 2')");
+            stat.executeUpdate("INSERT INTO FOO (VAL) VALUES ('foo 3')");
+            stat.executeUpdate(
+                "INSERT INTO BAR (FOOID,VAL) VALUES (IDENTITY(),'bar 3')");
+            stat.executeUpdate(
+                "INSERT INTO BAZ (BARID,VAL) VALUES (IDENTITY(),'baz 3')");
+
+            ResultSet rs;
+            Statement query = conn.createStatement(
+                java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,
+                java.sql.ResultSet.CONCUR_READ_ONLY);
+
+            rs = query.executeQuery("SELECT ID,VAL FROM FOO");
+
+            System.out.println("Table FOO:");
+
+            while (rs.next()) {
+                System.out.println(rs.getInt(1));
+                System.out.println(rs.getString(2));
+            }
+
+            rs = query.executeQuery("SELECT ID,FOOID,VAL FROM BAR");
+
+            System.out.println("Table BAR:");
+
+            while (rs.next()) {
+                System.out.println(rs.getInt(1));
+                System.out.println(rs.getInt(2));
+                System.out.println(rs.getString(3));
+            }
+
+            rs = query.executeQuery("SELECT ID,BARID,VAL FROM BAZ");
+
+            System.out.println("Table BAZ:");
+
+            while (rs.next()) {
+                System.out.println(rs.getInt(1));
+                System.out.println(rs.getInt(2));
+                System.out.println(rs.getString(3));
+            }
+
+            rs.close();
+            query.close();
+            stat.close();
+            conn.close();
+        } catch (Exception e) {
+            System.err.println(e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    public static void testTwo() {
+
+        TestUtil.deleteDatabase("test");
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            Properties pp = new Properties();
+
+            pp.put("user", "sa");
+            pp.put("password", "");
+
+            Connection c =
+                DriverManager.getConnection("jdbc:hsqldb:file:test", pp);
+
+            c.createStatement().executeUpdate(
+                "create cached table SNS_OIDS(NAME varchar(20) not null primary key, ID int)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='_snsLog'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('_snsLog', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='visitorTags'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('visitorTags', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='departments'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('departments', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='operators'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('operators', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='zones'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('zones', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='pages'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('pages', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=21 WHERE \"NAME\"='visitorTags'");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='actionDefinitions'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('actionDefinitions', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='actionVariants'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('actionVariants', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='actionPoints'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('actionPoints', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='actionTags'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('actionTags', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='captureFields'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('captureFields', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='reactions'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('reactions', 1)");
+            c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=1 WHERE \"NAME\"='reactionOperations'");
+            c.createStatement().executeUpdate(
+                "INSERT INTO SNS_OIDS (\"NAME\", \"ID\") VALUES ('reactionOperations', 1)");
+
+            int count = c.createStatement().executeUpdate(
+                "UPDATE SNS_OIDS SET \"ID\"=21 WHERE \"NAME\"='actionTags'");
+
+            System.out.println("count == " + count);    // should be 1, 0 instead!
+        } catch (Exception e) {
+            System.err.println(e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        TestDima test = new TestDima();
+
+        test.testOne();
+        test.testTwo();
+
+    }
+}
diff --git a/src/org/hsqldb/test/TestGroupByHaving.java b/src/org/hsqldb/test/TestGroupByHaving.java
new file mode 100644
index 0000000..2c7d87d
--- /dev/null
+++ b/src/org/hsqldb/test/TestGroupByHaving.java
@@ -0,0 +1,355 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+
+/**
+ * Test cases for HSQL aggregates and HAVING clause.
+ *
+ * @author Tony Lai
+ */
+
+// fredt@users - modified to remove dependecy on DBUnit
+public class TestGroupByHaving extends TestCase {
+
+    //------------------------------------------------------------
+    // Class variables
+    //------------------------------------------------------------
+    private static final String databaseDriver   = "org.hsqldb.jdbc.JDBCDriver";
+    private static final String databaseURL      = "jdbc:hsqldb:mem:.";
+    private static final String databaseUser     = "sa";
+    private static final String databasePassword = "";
+
+    //------------------------------------------------------------
+    // Instance variables
+    //------------------------------------------------------------
+    private Connection conn;
+    private Statement  stmt;
+
+    //------------------------------------------------------------
+    // Constructors
+    //------------------------------------------------------------
+
+    /**
+     * Constructs a new SubselectTest.
+     */
+    public TestGroupByHaving(String s) {
+        super(s);
+    }
+
+    //------------------------------------------------------------
+    // Class methods
+    //------------------------------------------------------------
+    protected static Connection getJDBCConnection() throws SQLException {
+        return DriverManager.getConnection(databaseURL, databaseUser,
+                                           databasePassword);
+    }
+
+    protected void setUp() throws Exception {
+
+        super.setUp();
+
+        if (conn != null) {
+            return;
+        }
+
+        Class.forName(databaseDriver);
+
+        conn = getJDBCConnection();
+        stmt = conn.createStatement();
+
+        // I decided not the use the "IF EXISTS" clause since it is not a
+        // SQL standard.
+        try {
+
+//            stmt.execute("drop table employee");
+            stmt.execute("drop table employee if exists");
+        } catch (Exception x) {}
+
+        stmt.execute("create table employee(id int, "
+                     + "firstname VARCHAR(50), " + "lastname VARCHAR(50), "
+                     + "salary decimal(10, 2), " + "superior_id int, "
+                     + "CONSTRAINT PK_employee PRIMARY KEY (id), "
+                     + "CONSTRAINT FK_superior FOREIGN KEY (superior_id) "
+                     + "REFERENCES employee(ID))");
+        addEmployee(1, "Mike", "Smith", 160000, -1);
+        addEmployee(2, "Mary", "Smith", 140000, -1);
+
+        // Employee under Mike
+        addEmployee(10, "Joe", "Divis", 50000, 1);
+        addEmployee(11, "Peter", "Mason", 45000, 1);
+        addEmployee(12, "Steve", "Johnson", 40000, 1);
+        addEmployee(13, "Jim", "Hood", 35000, 1);
+
+        // Employee under Mike
+        addEmployee(20, "Jennifer", "Divis", 60000, 2);
+        addEmployee(21, "Helen", "Mason", 50000, 2);
+        addEmployee(22, "Daisy", "Johnson", 40000, 2);
+        addEmployee(23, "Barbara", "Hood", 30000, 2);
+    }
+
+    protected void tearDown() throws Exception {
+
+        // I decided not the use the "IF EXISTS" clause since it is not a
+        // SQL standard.
+        try {
+
+//            stmt.execute("drop table employee");
+            stmt.execute("drop table employee if exists");
+        } catch (Exception x) {}
+
+        if (stmt != null) {
+            stmt.close();
+
+            stmt = null;
+        }
+
+        if (conn != null) {
+            conn.close();
+
+            conn = null;
+        }
+
+        super.tearDown();
+
+    }
+
+    private void addEmployee(int id, String firstName, String lastName,
+                             double salary, int superiorId) throws Exception {
+
+        stmt.execute("insert into employee values(" + id + ", '" + firstName
+                     + "', '" + lastName + "', " + salary + ", "
+                     + (superiorId <= 0 ? "null"
+                                        : ("" + superiorId)) + ")");
+    }
+
+    /**
+     * Tests aggregated selection with a <b>GROUP_BY</b> clause.  This is
+     * a normal use of the <b>GROUP_BY</b> clause.  The first two employees
+     * do not have a superior, and must be grouped within the same group,
+     * according to <b>GROUP_BY</b> standard.
+     */
+    public void testAggregatedGroupBy() throws SQLException {
+
+        String sql = "select avg(salary), max(id) from employee "
+                     + "group by superior_id " + "order by superior_id " + "";
+        Object[][] expected = new Object[][] {
+            {
+                new Double(150000), new Integer(2)
+            }, {
+                new Double(42500), new Integer(13)
+            }, {
+                new Double(45000), new Integer(23)
+            },
+        };
+
+        compareResults(sql, expected, "00000");
+    }
+
+    /**
+     * Tests aggregated selection with a <b>GROUP_BY</b> clause and a
+     * <b>HAVING</b> clause.
+     * <p>
+     * This is a typical use of the <b>GROUP_BY</b> + <b>HAVING</b> clause.
+     * The first two employees are eliminated due to the <b>HAVING</b>
+     * condition.
+     * <p>
+     * This test uses aggregated function to eliminate first group.
+     */
+    public void testAggregatedGroupByHaving1() throws SQLException {
+
+        String sql = "select avg(salary), max(id) from employee "
+                     + "group by superior_id " + "having max(id) > 5 "
+                     + "order by superior_id " + "";
+        Object[][] expected = new Object[][] {
+            {
+                new Double(42500), new Integer(13)
+            }, {
+                new Double(45000), new Integer(23)
+            },
+        };
+
+        compareResults(sql, expected, "00000");
+    }
+
+    /**
+     * Tests aggregated selection with a <b>GROUP_BY</b> clause and a
+     * <b>HAVING</b> clause.
+     * <p>
+     * This is a typical use of the <b>GROUP_BY</b> + <b>HAVING</b> clause.
+     * The first two employees are eliminated due to the <b>HAVING</b>
+     * condition.
+     * <p>
+     * This test uses <b>GROUP_BY</b> column to eliminate first group.
+     */
+    public void testAggregatedGroupByHaving2() throws SQLException {
+
+        String sql = "select avg(salary), max(id) from employee "
+                     + "group by superior_id "
+                     + "having superior_id is not null "
+                     + "order by superior_id " + "";
+        Object[][] expected = new Object[][] {
+            {
+                new Double(42500), new Integer(13)
+            }, {
+                new Double(45000), new Integer(23)
+            },
+        };
+
+        compareResults(sql, expected, "00000");
+    }
+
+    /**
+     * Tests an unusual usage of the <b>HAVING</b> clause, without a
+     * <b>GROUP BY</b> clause.
+     * <p>
+     * Only one row is returned by the aggregate selection without a
+     * <b>GROUP BY</b> clause.  The <b>HAVING</b> clause is applied to the
+     * only returned row.  In this case, the <b>HAVING</b> condition is
+     * satisfied.
+     */
+    public void testHavingWithoutGroupBy1() throws SQLException {
+
+        String sql = "select avg(salary), max(id) from employee "
+                     + "having avg(salary) > 1000 " + "";
+        Object[][] expected = new Object[][] {
+            {
+                new Double(65000), new Integer(23)
+            },
+        };
+
+        compareResults(sql, expected, "00000");
+    }
+
+    /**
+     * Tests an unusual usage of the <b>HAVING</b> clause, without a
+     * <b>GROUP BY</b> clause.
+     * <p>
+     * Only one row is returned by the aggregate selection without a
+     * <b>GROUP BY</b> clause.  The <b>HAVING</b> clause is applied to the
+     * only returned row.  In this case, the <b>HAVING</b> condition is
+     * NOT satisfied.
+     */
+    public void testHavingWithoutGroupBy2() throws SQLException {
+
+        String sql = "select avg(salary), max(id) from employee "
+                     + "having avg(salary) > 1000000 " + "";
+        Object[][] expected = new Object[][]{};
+
+        compareResults(sql, expected, "00000");
+    }
+
+    /**
+     * Tests an invalid <b>HAVING</b> clause that contains columns not in
+     * the <b>GROUP BY</b> clause.  A SQLException should be thrown.
+     */
+    public void testInvalidHaving() throws SQLException {
+
+        String sql = "select avg(salary), max(id) from employee "
+                     + "group by lastname "
+                     + "having (max(id) > 1) and (superior_id > 1) " + "";
+        Object[][] expected = new Object[][]{};
+
+        compareResults(sql, expected, "42573");
+    }
+
+    //------------------------------------------------------------
+    // Helper methods
+    //------------------------------------------------------------
+    private void compareResults(String sql, Object[][] rows,
+                                String sqlState) throws SQLException {
+
+        ResultSet rs = null;
+
+        try {
+            rs = stmt.executeQuery(sql);
+
+            assertTrue("Statement <" + sql + "> \nexpecting error code: "
+                       + sqlState, ("00000".equals(sqlState)));
+        } catch (SQLException sqlx) {
+            if (!sqlx.getSQLState().equals(sqlState)) {
+                sqlx.printStackTrace();
+            }
+
+            assertTrue("Statement <" + sql + "> \nthrows wrong error code: "
+                       + sqlx.getErrorCode() + " expecting error code: "
+                       + sqlState, (sqlx.getSQLState().equals(sqlState)));
+
+            return;
+        }
+
+        int rowCount = 0;
+        int colCount = rows.length > 0 ? rows[0].length
+                                       : 0;
+
+        while (rs.next()) {
+            assertTrue("Statement <" + sql + "> \nreturned too many rows.",
+                       (rowCount < rows.length));
+
+            Object[] columns = rows[rowCount];
+
+            for (int col = 1, i = 0; i < colCount; i++, col++) {
+                Object result   = null;
+                Object expected = columns[i];
+
+                if (expected == null) {
+                    result = rs.getString(col);
+                    result = rs.wasNull() ? null
+                                          : result;
+                } else if (expected instanceof String) {
+                    result = rs.getString(col);
+                } else if (expected instanceof Double) {
+                    result = new Double(rs.getString(col));
+                } else if (expected instanceof Integer) {
+                    result = new Integer(rs.getInt(col));
+                }
+
+                assertEquals("Statement <" + sql
+                             + "> \nreturned wrong value.", columns[i],
+                                 result);
+            }
+
+            rowCount++;
+        }
+
+        assertEquals("Statement <" + sql
+                     + "> \nreturned wrong number of rows.", rows.length,
+                         rowCount);
+    }
+}
diff --git a/src/org/hsqldb/test/TestHSQLDB.java b/src/org/hsqldb/test/TestHSQLDB.java
new file mode 100644
index 0000000..126b83c
--- /dev/null
+++ b/src/org/hsqldb/test/TestHSQLDB.java
@@ -0,0 +1,97 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/*
+ * TestHSQLDB.java
+ *
+ * Created on June 10, 2004, 10:28 PM
+ */
+
+/**
+ *
+ * @author  Diego Ballve
+ */
+public class TestHSQLDB {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+
+        java.sql.DatabaseMetaData metaData = null;
+        String databaseURL                 = "jdbc:hsqldb:mem:test";
+        String                    driver   = "org.hsqldb.jdbc.JDBCDriver";
+        String                    user     = "sa";
+        String                    password = "";
+
+        //Table creation sql:
+        String ddlStr =
+            "CREATE TABLE USER_(ID VARCHAR(64) NOT NULL PRIMARY KEY,HOME VARCHAR(128),OBJECTTYPE VARCHAR(64),STATUS VARCHAR(64) NOT NULL,PERSONNAME_FIRSTNAME VARCHAR(64),PERSONNAME_MIDDLENAME VARCHAR(64),PERSONNAME_LASTNAME VARCHAR(64),URL VARCHAR(256))";
+        String sqlStr =
+            "UPDATE User_ SET  id=\'urn:uuid:921284f0-bbed-4a4c-9342-ecaf0625f9d7\',  home=null, objectType=\'urn:uuid:6d07b299-10e7-408f-843d-bb2bc913bfbb\', status=\'urn:uuid:37d17f1b-3245-425b-988d-e0d98200a146\' , personName_firstName=\'Registry\', personName_middleName=null, personName_lastName=\'Operator\', url=\'http://sourceforge.net/projects/ebxmlrr\' WHERE id = \'urn:uuid:921284f0-bbed-4a4c-9342-ecaf0625f9d7\' ";
+        Statement stmt = null;
+
+        try {
+            Class.forName(driver);
+
+            Connection connection = DriverManager.getConnection(databaseURL,
+                user, password);
+
+            stmt = connection.createStatement();
+
+            stmt.addBatch(ddlStr);
+            stmt.addBatch(sqlStr);
+
+            int[] updateCounts = stmt.executeBatch();
+        } catch (ClassNotFoundException e) {
+            System.err.println(e.getClass().getName() + ": "
+                               + e.getMessage());
+            e.printStackTrace(System.err);
+        } catch (SQLException e) {
+            System.err.println(e.getClass().getName() + ": "
+                               + e.getMessage());
+            e.printStackTrace(System.err);
+        } finally {
+            try {
+                if (stmt != null) {
+                    stmt.close();
+                }
+            } catch (SQLException e) {}
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestHarness.java b/src/org/hsqldb/test/TestHarness.java
new file mode 100644
index 0000000..9951965
--- /dev/null
+++ b/src/org/hsqldb/test/TestHarness.java
@@ -0,0 +1,278 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* Filename: TestHarness.java
+ * Created on May 18, 2005
+ * Author: Carl Gould
+ * Copyright Calmetrics 2005
+ * Project: HSQLDB_Test
+ */
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+/**
+ * Describe this class
+ *
+ * @author Carl
+ */
+public class TestHarness extends JFrame {
+
+    protected String    dbURL;
+    protected JTextArea textArea;
+
+    public static void main(String[] args) {
+
+        if (args.length == 0) {
+            args = new String[]{ "testrecovery" };
+        }
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver").newInstance();
+        } catch (Exception e) {
+            System.out.println("ERROR: failed to load HSQLDB JDBC driver.");
+            e.printStackTrace();
+
+            return;
+        }
+
+        new TestHarness("jdbc:hsqldb:file:" + args[0]);
+    }
+
+    public TestHarness(String url) {
+
+        super("HSQLDB Test Harness");
+
+        this.dbURL = url;
+
+        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+        addWindowListener(new WindowAdapter() {
+
+            public void windowClosing(WindowEvent e) {
+                doClose();
+            }
+        });
+        initComponents();
+        setSize(400, 400);
+        setLocation(200, 200);
+        setVisible(true);
+
+        try {
+            Connection c = getConnection("sa", "password", true);
+
+            textArea.setText("Database already exists.");
+            c.close();
+        } catch (SQLException e1) {
+            doCreate();
+        }
+    }
+
+    protected void initComponents() {
+
+        Container main = getContentPane();
+
+        textArea = new JTextArea();
+
+        JPanel  buttons = new JPanel(new FlowLayout());
+        JButton close   = new JButton("Close Gracefully");
+
+        close.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                doClose();
+            }
+        });
+
+        JButton create = new JButton("Add Row");
+
+        create.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                doInsert();
+            }
+        });
+
+        JButton list = new JButton("List Data");
+
+        list.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                doListing();
+            }
+        });
+
+        JButton kill = new JButton("Kill");
+
+        kill.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                System.exit(0);
+            }
+        });
+        buttons.add(create);
+        buttons.add(list);
+        buttons.add(kill);
+        buttons.add(close);
+        main.add(new JScrollPane(textArea), BorderLayout.CENTER);
+        main.add(buttons, BorderLayout.SOUTH);
+    }
+
+    protected void doInsert() {
+
+        try {
+            Connection con = getConnection("ABCD", "dcba", false);
+
+            if (con != null) {
+                Statement stmt = con.createStatement();
+                ResultSet rs = stmt.executeQuery(
+                    "SELECT NEXT VALUE FOR MySeq FROM Dummy");
+
+                rs.next();
+
+                int id = rs.getInt(1);
+
+                stmt.executeUpdate("INSERT INTO MyTable (Id, Name) VALUES ("
+                                   + id + ", 'This is row #" + id + "')");
+                append("Row #" + id + " added");
+                stmt.close();
+                con.close();
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    protected void doListing() {
+
+        try {
+            Connection con = getConnection("ABCD", "dcba", false);
+
+            if (con != null) {
+                Statement stmt = con.createStatement();
+                ResultSet rs = stmt.executeQuery(
+                    "SELECT * FROM MyTable ORDER BY Id ASC");
+
+                append("Listing 'MyTable'....");
+
+                while (rs.next()) {
+                    append("  " + rs.getString(1) + ", " + rs.getString(2));
+                }
+
+                append("...done.");
+                stmt.close();
+                con.close();
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void append(String s) {
+        textArea.setText(textArea.getText() + "\n" + s);
+    }
+
+    protected void doClose() {
+
+        try {
+            Connection con = getConnection("sa", "password", false);
+
+            if (con != null) {
+                Statement stmt = con.createStatement();
+
+                stmt.execute("SHUTDOWN");
+                stmt.close();
+                con.close();
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+
+        System.exit(0);
+    }
+
+    protected void doCreate() {
+
+        try {
+            Connection con = getConnection("sa", "", false);
+
+            if (con != null) {
+                Statement stmt = con.createStatement();
+
+                stmt.execute("SET PASSWORD 'password'");
+                stmt.execute("CREATE USER abcd PASSWORD 'dcba'");
+                stmt.execute("CREATE SEQUENCE MySeq");
+                stmt.execute(
+                    "CREATE TABLE MyTable (Id INT PRIMARY KEY, Name VARCHAR(100) NOT NULL)");
+                stmt.execute("CREATE TABLE Dummy (Blah VARCHAR(100) NOT NULL)");
+                stmt.execute(
+                    "INSERT INTO Dummy (Blah) VALUES ('dummy value')");
+                stmt.execute("GRANT ALL ON MyTable TO abcd");
+                stmt.execute("GRANT ALL ON Dummy TO abcd");
+                stmt.execute("GRANT ALL ON SEQUENCE MySeq TO abcd");
+                stmt.close();
+                con.close();
+                textArea.setText("Database created.");
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    protected Connection getConnection(String username, String password,
+                                       boolean ifExists) throws SQLException {
+
+        Properties props = new Properties();
+
+        props.put("user", username);
+        props.put("password", password);
+        props.put("ifexists", String.valueOf(ifExists));
+
+        return DriverManager.getConnection(dbURL, props);
+    }
+}
diff --git a/src/org/hsqldb/test/TestHashStructures.java b/src/org/hsqldb/test/TestHashStructures.java
new file mode 100644
index 0000000..262eb21
--- /dev/null
+++ b/src/org/hsqldb/test/TestHashStructures.java
@@ -0,0 +1,567 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.util.Random;
+
+import org.hsqldb.lib.DoubleIntIndex;
+import org.hsqldb.lib.StopWatch;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ */
+public class TestHashStructures extends TestCase {
+
+    public TestHashStructures(String s) {
+        super(s);
+    }
+
+    Random randomgen = new java.util.Random();
+
+    public void testHashMap() throws Exception {
+
+        boolean                failed   = false;
+        int                    testSize = 33;
+        org.hsqldb.lib.HashMap hMap     = new org.hsqldb.lib.HashMap();
+        org.hsqldb.lib.IntKeyHashMap hIntMap =
+            new org.hsqldb.lib.IntKeyHashMap();
+        java.util.HashMap uMap = new java.util.HashMap();
+
+        try {
+            populateBySerialIntKeys(uMap, hMap, testSize);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+
+            // -
+            populateByRandomIntKeys(uMap, hMap, testSize);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+
+            //
+            depopulateRandomly(uMap, hMap, 20);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+
+            // -
+            populateBySerialIntKeys(uMap, hMap, testSize);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+
+            //
+            depopulateByIterator(uMap, hMap, 20);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+        } catch (Exception e) {
+            failed = true;
+        }
+
+        assertTrue(!failed);
+    }
+
+    public void testIntKeyHashMap() throws Exception {
+
+        boolean failed   = false;
+        int     testSize = 33;
+        org.hsqldb.lib.IntKeyHashMap hIntMap =
+            new org.hsqldb.lib.IntKeyHashMap();
+        java.util.HashMap uMap = new java.util.HashMap();
+
+        try {
+            populateBySerialIntKeysInt(uMap, hIntMap, testSize);
+            compareByUIteratorInt(uMap, hIntMap);
+            populateByRandomIntKeysInt(uMap, hIntMap, testSize);
+            compareByUIteratorInt(uMap, hIntMap);
+            compareByHIteratorInt(uMap, hIntMap);
+
+            //
+            depopulateByIntIterator(uMap, hIntMap, 20);
+            compareByUIteratorInt(uMap, hIntMap);
+            compareByHIteratorInt(uMap, hIntMap);
+
+            //
+            clearByIntIterator(uMap, hIntMap);
+            compareByUIteratorInt(uMap, hIntMap);
+            compareByHIteratorInt(uMap, hIntMap);
+
+            // -
+            populateBySerialIntKeysInt(uMap, hIntMap, testSize);
+            compareByUIteratorInt(uMap, hIntMap);
+            compareByHIteratorInt(uMap, hIntMap);
+
+            //
+            clearByIntIterator(uMap, hIntMap);
+            compareByUIteratorInt(uMap, hIntMap);
+            compareByHIteratorInt(uMap, hIntMap);
+        } catch (Exception e) {
+            failed = true;
+        }
+
+        assertTrue(!failed);
+    }
+
+    public void testHashMappedList() throws Exception {
+
+        boolean failed   = false;
+        int     testSize = 33;
+        org.hsqldb.lib.HashMappedList hMap =
+            new org.hsqldb.lib.HashMappedList();
+        java.util.HashMap uMap = new java.util.HashMap();
+
+        try {
+            populateBySerialIntKeys(uMap, hMap, testSize);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+            populateByRandomIntKeys(uMap, hMap, testSize);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+            depopulateRandomly(uMap, hMap, 20);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+            populateByRandomIntKeys(uMap, hMap, testSize);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+            depopulateRandomly(uMap, hMap, 20);
+            populateBySerialIntKeys(uMap, hMap, testSize);
+            compareByUIterator(uMap, hMap);
+            compareByHIterator(uMap, hMap);
+        } catch (Exception e) {
+            failed = true;
+        }
+
+        assertTrue(!failed);
+    }
+
+    public void testDoubleIntLookup() throws Exception {
+
+        boolean failed   = false;
+        int     testSize = 512;
+        org.hsqldb.lib.IntKeyHashMap hIntMap =
+            new org.hsqldb.lib.IntKeyHashMap();
+        DoubleIntIndex intLookup = new DoubleIntIndex(12, false);
+
+        try {
+            intLookup.setKeysSearchTarget();
+            populateBySerialIntKeysInt(intLookup, hIntMap, testSize);
+            compareByHIteratorInt(intLookup, hIntMap);
+            populateByRandomIntKeysInt(intLookup, hIntMap, testSize);
+            compareByHIteratorInt(intLookup, hIntMap);
+        } catch (Exception e) {
+            failed = true;
+        }
+
+        assertTrue(!failed);
+    }
+
+    public void testDoubleIntSpeed() throws Exception {
+
+        boolean failed   = false;
+        int     testSize = 500;
+        org.hsqldb.lib.IntKeyHashMap hIntMap =
+            new org.hsqldb.lib.IntKeyHashMap();
+        DoubleIntIndex intLookup = new DoubleIntIndex(testSize, false);
+
+        intLookup.setKeysSearchTarget();
+        populateByRandomIntKeysInt(intLookup, hIntMap, testSize);
+        compareByHIteratorInt(intLookup, hIntMap);
+
+        int[]     sample     = getSampleIntArray(intLookup, 100);
+        int[]     sampleVals = new int[sample.length];
+        int       i          = 0;
+        int       j          = 0;
+        StopWatch sw         = new StopWatch();
+
+        try {
+            for (j = 0; j < 10000; j++) {
+                for (i = 0; i < sample.length; i++) {
+                    int pos = intLookup.findFirstEqualKeyIndex(sample[i]);
+
+                    sampleVals[i] = intLookup.getValue(pos);
+
+                    intLookup.remove(pos);
+                }
+
+                for (i = 0; i < sample.length; i++) {
+                    intLookup.addUnique(sample[i], sampleVals[i]);
+                }
+            }
+
+            System.out.println(
+                sw.elapsedTimeToMessage("Double int table times"));
+            intLookup.findFirstEqualKeyIndex(0);    // sort
+            compareByHIteratorInt(intLookup, hIntMap);
+        } catch (Exception e) {
+            System.out.println(
+                sw.elapsedTimeToMessage("Double int table error: i =" + i));
+
+            failed = true;
+        }
+
+        assertTrue(!failed);
+    }
+
+    int[] getSampleIntArray(org.hsqldb.lib.DoubleIntIndex index, int size) {
+
+        int[]                        array = new int[size];
+        org.hsqldb.lib.IntKeyHashMap map = new org.hsqldb.lib.IntKeyHashMap();
+
+        for (; map.size() < size; ) {
+            int pos = nextIntRandom(randomgen, index.size());
+
+            map.put(pos, null);
+        }
+
+        org.hsqldb.lib.Iterator it = map.keySet().iterator();
+
+        for (int i = 0; i < size; i++) {
+            int pos = it.nextInt();
+
+            array[i] = index.getKey(pos);
+        }
+
+        return array;
+    }
+
+    void populateBySerialIntKeys(java.util.HashMap uMap,
+                                 org.hsqldb.lib.HashMap hMap,
+                                 int testSize) throws Exception {
+
+        for (int i = 0; i < testSize; i++) {
+            int intValue = randomgen.nextInt();
+
+            uMap.put(new Integer(i), new Integer(intValue));
+            hMap.put(new Integer(i), new Integer(intValue));
+
+            if (uMap.size() != hMap.size()) {
+                throw new Exception("HashMap size mismatch");
+            }
+        }
+    }
+
+    void populateBySerialIntKeysInt(java.util.HashMap uMap,
+                                    org.hsqldb.lib.IntKeyHashMap hMap,
+                                    int testSize) throws Exception {
+
+        for (int i = 0; i < testSize; i++) {
+            int intValue = randomgen.nextInt();
+
+            uMap.put(new Integer(i), new Integer(intValue));
+            hMap.put(i, new Integer(intValue));
+
+            if (uMap.size() != hMap.size()) {
+                throw new Exception("HashMap size mismatch");
+            }
+        }
+    }
+
+    void populateBySerialIntKeysInt(DoubleIntIndex intLookup,
+                                    org.hsqldb.lib.IntKeyHashMap hMap,
+                                    int testSize) throws Exception {
+
+        for (int i = 0; i < testSize; i++) {
+            int intValue = randomgen.nextInt();
+
+            intLookup.addUnique(i, intValue);
+            hMap.put(i, new Integer(intValue));
+
+            if (intLookup.size() != hMap.size()) {
+                throw new Exception("HashMap size mismatch");
+            }
+        }
+    }
+
+    void populateByRandomIntKeysInt(DoubleIntIndex intLookup,
+                                    org.hsqldb.lib.IntKeyHashMap hMap,
+                                    int testSize) throws Exception {
+
+        for (int i = 0; i < testSize; i++) {
+            int intValue = randomgen.nextInt();
+
+            intLookup.addUnique(intValue, i);
+            hMap.put(intValue, new Integer(i));
+
+            // actually this can happen as duplicates are allowed in DoubleIntTable
+            if (intLookup.size() != hMap.size()) {
+                throw new Exception("Duplicate random in int lookup");
+            }
+        }
+    }
+
+    void populateByRandomIntKeys(java.util.HashMap uMap,
+                                 org.hsqldb.lib.HashMap hMap,
+                                 int testSize) throws Exception {
+
+        for (int i = 0; i < testSize; i++) {
+            int intValue = randomgen.nextInt();
+
+            uMap.put(new Integer(intValue), new Integer(i));
+            hMap.put(new Integer(intValue), new Integer(i));
+
+            if (uMap.size() != hMap.size()) {
+                throw new Exception("HashMap size mismatch");
+            }
+        }
+    }
+
+    void populateByRandomIntKeysInt(java.util.HashMap uMap,
+                                    org.hsqldb.lib.IntKeyHashMap hMap,
+                                    int testSize) throws Exception {
+
+        for (int i = 0; i < testSize; i++) {
+            int intValue = randomgen.nextInt();
+
+            uMap.put(new Integer(intValue), new Integer(i));
+            hMap.put(intValue, new Integer(i));
+
+            if (uMap.size() != hMap.size()) {
+                throw new Exception("HashMap size mismatch");
+            }
+        }
+    }
+
+    void depopulateRandomly(java.util.HashMap uMap,
+                            org.hsqldb.lib.HashMap hMap,
+                            int testCount) throws Exception {
+
+        int removeCount = 0;
+        int size        = uMap.size();
+
+        if (testCount > size / 2) {
+            testCount = size / 2;
+        }
+
+        while (removeCount < testCount) {
+            java.util.Iterator uIt = uMap.keySet().iterator();
+
+            for (int i = 0; uIt.hasNext(); i++) {
+                Object uKey     = uIt.next();
+                int    intValue = randomgen.nextInt(size);
+
+                if (intValue == i) {
+                    uIt.remove();
+                    hMap.remove(uKey);
+
+                    removeCount++;
+                }
+
+                if (uMap.size() != hMap.size()) {
+                    throw new Exception("HashMap size mismatch");
+                }
+            }
+        }
+    }
+
+    void depopulateByIterator(java.util.HashMap uMap,
+                              org.hsqldb.lib.HashMap hMap,
+                              int testCount) throws Exception {
+
+        org.hsqldb.lib.Iterator hIt = hMap.keySet().iterator();
+
+        System.out.println(uMap.size());
+
+        for (int i = 0; hIt.hasNext(); i++) {
+            Object key   = hIt.next();
+            int    check = randomgen.nextInt(2);
+
+            if (check == i % 2) {
+                hIt.remove();
+                uMap.remove(key);
+            }
+
+            if (uMap.size() != hMap.size()) {
+                throw new Exception("HashMap size mismatch");
+            }
+        }
+
+        System.out.println(uMap.size());
+    }
+
+    void depopulateByIntIterator(java.util.HashMap uMap,
+                                 org.hsqldb.lib.IntKeyHashMap hIntMap,
+                                 int testCount) throws Exception {
+
+        org.hsqldb.lib.Iterator hIt = hIntMap.keySet().iterator();
+
+        System.out.println(uMap.size());
+
+        for (int i = 0; hIt.hasNext(); i++) {
+            Object key   = new Integer(hIt.nextInt());
+            int    check = randomgen.nextInt(2);
+
+            if (check == i % 2) {
+                hIt.remove();
+                uMap.remove(key);
+            }
+
+            if (uMap.size() != hIntMap.size()) {
+                throw new Exception("HashMap size mismatch");
+            }
+        }
+
+        System.out.println(uMap.size());
+    }
+
+    void clearByIntIterator(java.util.HashMap uMap,
+                            org.hsqldb.lib.IntKeyHashMap hIntMap)
+                            throws Exception {
+
+        org.hsqldb.lib.Iterator hIt = hIntMap.keySet().iterator();
+
+        System.out.println(uMap.size());
+
+        for (int i = 0; hIt.hasNext(); i++) {
+            Object key = new Integer(hIt.nextInt());
+
+            hIt.remove();
+            uMap.remove(key);
+
+            if (uMap.size() != hIntMap.size()) {
+                throw new Exception("HashMap size mismatch");
+            }
+        }
+
+        System.out.println(uMap.size());
+    }
+
+    void compareByUIterator(java.util.HashMap uMap,
+                            org.hsqldb.lib.HashMap hMap) throws Exception {
+
+        java.util.Iterator uIt = uMap.keySet().iterator();
+
+        for (int i = 0; uIt.hasNext(); i++) {
+            Object uKey = uIt.next();
+            Object oU   = uMap.get(uKey);
+            Object hU   = hMap.get(uKey);
+
+            if (!oU.equals(hU)) {
+                throw new Exception("HashMap value mismatch");
+            }
+        }
+    }
+
+    void compareByHIterator(java.util.HashMap uMap,
+                            org.hsqldb.lib.HashMap hMap) throws Exception {
+
+        org.hsqldb.lib.Iterator hIt = hMap.keySet().iterator();
+
+        for (int i = 0; hIt.hasNext(); i++) {
+            Object hKey = hIt.next();
+            Object oU   = uMap.get(hKey);
+            Object hU   = hMap.get(hKey);
+
+            if (!oU.equals(hU)) {
+                throw new Exception("HashMap value mismatch");
+            }
+        }
+    }
+
+    void compareByUIteratorInt(java.util.HashMap uMap,
+                               org.hsqldb.lib.IntKeyHashMap hMap)
+                               throws Exception {
+
+        java.util.Iterator uIt = uMap.keySet().iterator();
+
+        for (int i = 0; uIt.hasNext(); i++) {
+            Object uKey = uIt.next();
+            Object oU   = uMap.get(uKey);
+            Object hU   = hMap.get(((Integer) uKey).intValue());
+
+            if (!oU.equals(hU)) {
+                throw new Exception("HashMap value mismatch");
+            }
+        }
+    }
+
+    void compareByHIteratorInt(java.util.HashMap uMap,
+                               org.hsqldb.lib.IntKeyHashMap hMap)
+                               throws Exception {
+
+        org.hsqldb.lib.Iterator hIt = hMap.keySet().iterator();
+
+        for (int i = 0; hIt.hasNext(); i++) {
+            Object hKey = new Integer(hIt.nextInt());
+            Object oU   = uMap.get(hKey);
+            Object hU   = hMap.get(((Integer) hKey).intValue());
+
+            if (!oU.equals(hU)) {
+                throw new Exception("HashMap value mismatch");
+            }
+        }
+    }
+
+    void compareByHIteratorInt(DoubleIntIndex intLookup,
+                               org.hsqldb.lib.IntKeyHashMap hMap)
+                               throws Exception {
+
+        org.hsqldb.lib.Iterator hIt = hMap.keySet().iterator();
+
+        for (int i = 0; hIt.hasNext(); i++) {
+            int     hK     = hIt.nextInt();
+            int     lookup = intLookup.findFirstEqualKeyIndex(hK);
+            int     lV     = intLookup.getValue(lookup);
+            Integer hV     = (Integer) hMap.get(hK);
+
+            if (hV.intValue() != lV) {
+                throw new Exception("HashMap value mismatch");
+            }
+        }
+    }
+
+    int nextIntRandom(Random r, int range) {
+
+        int b = r.nextInt();
+
+        if (b == Integer.MIN_VALUE) {
+            b = Integer.MAX_VALUE;
+        }
+
+        b = Math.abs(b);
+
+        return b % range;
+    }
+
+    public static void main(String[] argv) {
+
+        try {
+            TestHashStructures test = new TestHashStructures("testHashMap");
+
+            test.testHashMap();
+            test.testIntKeyHashMap();
+            test.testHashMappedList();
+            test.testDoubleIntLookup();
+            test.testDoubleIntSpeed();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestINPredicateParameterizationAndCorrelation.java b/src/org/hsqldb/test/TestINPredicateParameterizationAndCorrelation.java
new file mode 100644
index 0000000..6308934
--- /dev/null
+++ b/src/org/hsqldb/test/TestINPredicateParameterizationAndCorrelation.java
@@ -0,0 +1,222 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ *  HSQLDB TestINPredicate Junit test case. <p>
+ *
+ * @author  boucherb@users
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class TestINPredicateParameterizationAndCorrelation extends TestBase {
+
+    public TestINPredicateParameterizationAndCorrelation(String name) {
+        super(name);
+    }
+
+    /* Implements the TestINPredicate test */
+    public void test() throws Exception {
+
+        Connection        conn = newConnection();
+        Statement         stmt = conn.createStatement();
+        PreparedStatement pstmt;
+        ResultSet         rs;
+        int               actualCount;
+        int               expectedCount;
+        String            sql;
+
+        stmt.execute("drop table test if exists");
+
+        sql = "create table test(id int)";
+
+        stmt.execute(sql);
+
+        sql   = "insert into test values(?)";
+        pstmt = conn.prepareStatement(sql);
+
+        for (int i = 0; i < 10; i++) {
+            pstmt.setInt(1, i);
+            pstmt.addBatch();
+        }
+
+        pstmt.executeBatch();
+
+        //
+        sql   = "select count(*) from test where id in(?,?)";
+        pstmt = conn.prepareStatement(sql);
+
+        pstmt.setInt(1, 0);
+        pstmt.setInt(2, 9);
+
+        rs = pstmt.executeQuery();
+
+        rs.next();
+
+        expectedCount = 2;
+        actualCount   = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+        //
+        sql = "select count(*) from test a, test b where 0 in(a.id, b.id)";
+        rs  = stmt.executeQuery(sql);
+
+        rs.next();
+
+        expectedCount = rs.getInt(1);
+        sql = "select count(*) from test a, test b where ? in (a.id, b.id)";
+        pstmt         = conn.prepareStatement(sql);
+
+        pstmt.setInt(1, 0);
+
+        rs = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+        //
+        expectedCount = 20;
+        sql = "select count(*) from test a, test b where a.id in(?, ?)";
+        pstmt         = conn.prepareStatement(sql);
+
+        pstmt.setInt(1, 0);
+        pstmt.setInt(2, 9);
+
+        rs = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+        //
+        expectedCount = 10;
+        sql = "select count(*) from test a, test b where ? in(?, b.id)";
+        pstmt         = conn.prepareStatement(sql);
+
+        pstmt.setInt(1, 0);
+        pstmt.setInt(2, 9);
+
+        rs = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+        //
+        expectedCount = 1;
+        sql = "select count(*) from test a where ? in(select b.id from test b where a.id = b.id)";
+        pstmt = conn.prepareStatement(sql);
+
+        pstmt.setInt(1, 0);
+
+        rs = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+        //
+        sql = "select count(*) from "
+              + "(select * from test where id in (1,2)) a,"
+              + "(select * from test where id in (3,4)) b "
+              + "where a.id < 2 and b.id < 4";
+        rs = stmt.executeQuery(sql);
+
+        rs.next();
+
+        expectedCount = rs.getInt(1);
+        sql = "select count(*) from "
+              + "(select * from test where id in (?,?)) a,"
+              + "(select * from test where id in (?,?)) b "
+              + "where a.id < ? and b.id < ?";
+        pstmt = conn.prepareStatement(sql);
+
+        pstmt.setInt(1, 1);
+        pstmt.setInt(2, 2);
+        pstmt.setInt(3, 3);
+        pstmt.setInt(4, 4);
+        pstmt.setInt(5, 2);
+        pstmt.setInt(6, 4);
+
+        rs = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("row count: ", expectedCount, actualCount);
+    }
+
+    /* Runs TestINPredicate test from the command line*/
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestINPredicateParameterizationAndCorrelation("test");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println(
+            "TestINPredicateParameterizationAndCorrelation failure count: "
+            + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestInstantiation.java b/src/org/hsqldb/test/TestInstantiation.java
new file mode 100644
index 0000000..603c31e
--- /dev/null
+++ b/src/org/hsqldb/test/TestInstantiation.java
@@ -0,0 +1,79 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.sql.SQLException;
+
+import org.hsqldb.server.HsqlServerFactory;
+import org.hsqldb.server.HsqlSocketRequestHandler;
+
+/**
+ * Test the HsqlServerFactory interface. After running, connect to the
+ * server at port 9999 using the database manager.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.0
+ */
+public class TestInstantiation {
+
+    public TestInstantiation() {
+
+        try {
+            ServerSocket             serversocket;
+            Socket                   socket;
+            String                   m_DatabaseName;
+            HsqlSocketRequestHandler m_hsrh;
+
+            m_DatabaseName = "mem:.";
+            serversocket   = new ServerSocket(9999);
+
+            while (true) {
+                socket = serversocket.accept();
+                m_hsrh = HsqlServerFactory.createHsqlServer(m_DatabaseName,
+                        true, false);
+
+                m_hsrh.handleConnection(socket);
+            }
+        } catch (IOException e1) {
+            System.out.println(e1.getMessage());
+        } catch (SQLException e2) {
+            System.out.println(e2.getMessage());
+        }
+    }
+
+    public static void main(String[] argv) {
+        new TestInstantiation();
+    }
+}
diff --git a/src/org/hsqldb/test/TestJDBCGeneratedColumns.java b/src/org/hsqldb/test/TestJDBCGeneratedColumns.java
new file mode 100644
index 0000000..794d462
--- /dev/null
+++ b/src/org/hsqldb/test/TestJDBCGeneratedColumns.java
@@ -0,0 +1,123 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+public class TestJDBCGeneratedColumns extends TestBase {
+
+    public TestJDBCGeneratedColumns(String name) {
+        super(name);
+    }
+
+    public void testQuery() {
+
+        boolean successPrepared = false;
+        boolean successDirect   = false;
+
+        try {
+            Connection c  = newConnection();
+            Statement  st = c.createStatement();
+            String     s  = "DROP TABLE T IF EXISTS";
+
+            st.execute(s);
+
+            s = "CREATE TABLE T (I INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 33), C CHARACTER(10))";
+
+            st.execute(s);
+
+            s = "INSERT INTO T (C) VALUES('TEST')";
+
+            st.execute(s, Statement.RETURN_GENERATED_KEYS);
+
+            ResultSet rs = st.getGeneratedKeys();
+
+            while (rs.next()) {
+                System.out.println("generated: " + rs.getInt(1));
+
+                successDirect = rs.getInt(1) == 33;
+            }
+
+            PreparedStatement ps = c.prepareStatement(s,
+                Statement.RETURN_GENERATED_KEYS);
+
+            ps.execute();
+
+            rs = ps.getGeneratedKeys();
+
+            while (rs.next()) {
+                System.out.println("" + rs.getInt(1));
+
+                successPrepared = rs.getInt(1) == 34;
+            }
+
+            ps.close();
+
+            ps = c.prepareStatement(s, new int[]{ 1 });
+
+            ps.execute();
+
+            rs = ps.getGeneratedKeys();
+
+            while (rs.next()) {
+                System.out.println("" + rs.getInt(1));
+
+                successPrepared &= rs.getInt(1) == 35;
+            }
+
+            ps.close();
+
+            ps = c.prepareStatement(s, new String[]{ "I" });
+
+            ps.execute();
+
+            rs = ps.getGeneratedKeys();
+
+            while (rs.next()) {
+                System.out.println("" + rs.getInt(1));
+
+                successPrepared &= rs.getInt(1) == 36;
+                successPrepared &= rs.getBigDecimal(1).intValue() == 36;
+            }
+
+            ps.close();
+        } catch (Exception e) {
+            System.out.print(e);
+        }
+
+        assertTrue(successPrepared);
+        assertTrue(successDirect);
+    }
+}
diff --git a/src/org/hsqldb/test/TestJDBCSavepoints.java b/src/org/hsqldb/test/TestJDBCSavepoints.java
new file mode 100644
index 0000000..d0c8e32
--- /dev/null
+++ b/src/org/hsqldb/test/TestJDBCSavepoints.java
@@ -0,0 +1,510 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Savepoint;
+import java.sql.Statement;
+
+import org.hsqldb.server.WebServer;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import org.hsqldb.server.Server;
+
+/**
+ * Tests JDBC java.sql.Savepoint support in context of new engine SQL-savepoint
+ * support and new HSQL protocol extensions for savepoint support. <p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class TestJDBCSavepoints extends TestCase {
+
+//  You change the url and serverProps to reflect your preferred settings
+    // String serverProps = "database.0=mem:test;dbname.0=;silent=false;trace=true" // debugging
+    String serverProps = "database.0=mem:test;dbname.0=;silent=true;trace=false";
+
+    String     url         = "jdbc:hsqldb:hsql://localhost";
+    // String     url = "jdbc:hsqldb:http://localhost";
+    String     user;
+    String     password;
+    Statement  stmt;
+    Connection conn1;
+    Connection conn2;
+
+    // Server server;
+    // this exercises everything:
+    // the engine and JDBC savepoint support,
+    // the new HSQL protocol and tunneling HSQL protocol over HTTP
+    Server server;
+
+    public TestJDBCSavepoints(String name) {
+        super(name);
+    }
+
+    protected void setUp() {
+
+        user     = "sa";
+        password = "";
+        stmt     = null;
+        conn1    = null;
+        conn2    = null;
+
+        server   = new Server();
+//        server = new WebServer();
+
+        server.putPropertiesFromString(serverProps);
+        server.start();
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            conn1 = DriverManager.getConnection(url, user, password);
+            conn2 = DriverManager.getConnection(url, user, password);
+            stmt  = conn1.createStatement();
+        } catch (Exception e) {
+
+            //e.printStackTrace();
+            System.out.println(this + ".setUp() error: " + e.getMessage());
+        }
+    }
+
+    protected void tearDown() {
+
+        try {
+            conn1.close();
+        } catch (Exception e) {
+
+            //e.printStackTrace();
+            System.out.println(this + ".tearDown() error: " + e.getMessage());
+        }
+
+        try {
+            conn2.close();
+        } catch (Exception e) {
+
+            //e.printStackTrace();
+            System.out.println(this + ".tearDown() error: " + e.getMessage());
+        }
+
+        server.stop();
+    }
+
+    public void testJDBCSavepoints() throws Exception {
+
+        String            sql;
+        String            msg;
+        int               i;
+        PreparedStatement ps;
+        ResultSet         rs;
+        Savepoint         sp1;
+        Savepoint         sp2;
+        Savepoint         sp3;
+        Savepoint         sp4;
+        Savepoint         sp5;
+        Savepoint         sp6;
+        Savepoint         sp7;
+        int               rowcount = 0;
+
+        sql = "drop table t if exists";
+
+        stmt.executeUpdate(sql);
+
+        sql = "create table t(id int, fn varchar(40), ln varchar(40), zip int)";
+
+        stmt.executeUpdate(sql);
+        conn1.setAutoCommit(true);
+
+        //-- Test 1 : The execution of an SQL savepoint statement shall
+        //            raise an exception in the absence of an active
+        //            enclosing transaction
+        // fredt@users - there is always an active transaction when autocommit
+        // is true. The transaction is committed automatically if the next
+        // Statement.execute() or similar call is performed successfully.
+/*
+        msg = "savepoint set successfully in the abscence of an active transaction";
+        try {
+            conn.setSavepoint("savepoint1");
+            assertTrue(msg,false);
+        } catch (Exception e) {}
+
+*/
+
+        //-- setup for following tests
+        conn1.setAutoCommit(false);
+
+        sql = "insert into t values(?,?,?,?)";
+        ps  = conn1.prepareStatement(sql);
+
+        ps.setString(2, "Mary");
+        ps.setString(3, "Peterson-Clancy");
+
+        i = 0;
+
+        for (; i < 10; i++) {
+            ps.setInt(1, i);
+            ps.setInt(4, i);
+            ps.executeUpdate();
+        }
+
+        sp1 = conn1.setSavepoint("savepoint1");
+
+        for (; i < 20; i++) {
+            ps.setInt(1, i);
+            ps.setInt(4, i);
+            ps.executeUpdate();
+        }
+
+        sp2 = conn1.setSavepoint("savepoint2");
+
+        for (; i < 30; i++) {
+            ps.setInt(1, i);
+            ps.setInt(4, i);
+            ps.executeUpdate();
+        }
+
+        sp3 = conn1.setSavepoint("savepoint3");
+
+        for (; i < 40; i++) {
+            ps.setInt(1, i);
+            ps.setInt(4, i);
+            ps.executeUpdate();
+        }
+
+        sp4 = conn1.setSavepoint("savepoint4");
+
+        for (; i < 50; i++) {
+            ps.setInt(1, i);
+            ps.setInt(4, i);
+            ps.executeUpdate();
+        }
+
+        sp5 = conn1.setSavepoint("savepoint5");
+        sp6 = conn1.setSavepoint("savepoint6");
+        sp7 = conn1.setSavepoint("savepoint7");
+        rs  = stmt.executeQuery("select count(*) from t");
+
+        rs.next();
+
+        rowcount = rs.getInt(1);
+
+        rs.close();
+
+        //-- Test 2 : count of rows matches # rows inserted (assertion req'd by
+        //            following tests, but not directly related to the feature
+        //            being tested)
+        msg = "select count(*) from t value";
+
+        try {
+            assertEquals(msg, 50, rowcount);
+        } catch (Exception e) {}
+
+        conn2.setAutoCommit(false);
+        conn2.setSavepoint("savepoint1");
+        conn2.setSavepoint("savepoint2");
+
+        //-- test 3 : A JDBC Savepoint shall be considered invalid if used to
+        //            release an SQL-savepoint in an SQL-session other than that
+        //            of the originating Connection object
+        msg = "savepoint released succesfully on non-originating connection";
+
+        try {
+            conn2.releaseSavepoint(sp2);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+
+        //-- test 4 : A JDBC Savepoint shall be invalid if used to roll back to
+        //            an SQL-savepoint in an SQL-session other than that of the
+        //            originating Connection object
+        try {
+            conn2.rollback(sp1);
+
+            msg = "succesful rollback to savepoint on "
+                  + "non-originating connection";
+
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+
+        //-- test 5 : Direct execution of a <release savepoint> statement shall
+        //            not fail to release an existing indicated savepoint,
+        //            regardless of how the indicated savepoint was created
+        msg = "direct execution of <release savepoint> statement failed to "
+              + "release JDBC-created SQL-savepoint with identical savepoint name";
+
+        try {
+            conn2.createStatement().executeUpdate(
+                "release savepoint \"savepoint2\"");
+        } catch (Exception e) {
+            try {
+                assertTrue(msg, false);
+            } catch (Exception e2) {}
+        }
+
+        //-- test 6 : Direct execution of a <rollback to savepoint> statement
+        //            shall not fail to roll back to an existing indicated
+        //            savepoint due and only due to how the indicated savepoint
+        //            was created
+        msg = "direct execution of <rollback to savepoint> statement failed to "
+              + "roll back to existing JDBC-created SQL-savepoint with identical "
+              + "savepoint name";
+
+        try {
+            conn2.createStatement().executeUpdate(
+                "rollback to savepoint \"savepoint1\"");
+        } catch (Exception e) {
+            e.printStackTrace();
+
+            try {
+                assertTrue(msg, false);
+            } catch (Exception e2) {}
+        }
+
+        conn1.releaseSavepoint(sp6);
+
+        //-- test 7 : Releasing an SQL-savepoint shall destroy that savepoint
+        msg = "savepoint released succesfully > 1 times";
+
+        try {
+            conn1.releaseSavepoint(sp6);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+
+        //-- test 8 : Releasing an SQL-savepoint shall destroy all subsequent SQL-
+        //            savepoints in the same savepoint level
+        msg = "savepoint released successfully after preceding savepoint released";
+
+        try {
+            conn1.releaseSavepoint(sp7);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+
+        //-- test 9 : Releasing an SQL-savepoint shall not affect preceding
+        //            savepoints
+        msg = "preceding same-point savepoint destroyed by following savepoint release";
+
+        try {
+            conn1.releaseSavepoint(sp5);
+        } catch (Exception e) {
+            try {
+                assertTrue(msg, false);
+            } catch (Exception e2) {}
+        }
+
+        conn1.rollback(sp4);
+
+        rs = stmt.executeQuery("select count(*) from t");
+
+        rs.next();
+
+        rowcount = rs.getInt(1);
+
+        rs.close();
+
+        //-- Test 10 : count of rows matches # rows inserted less the number
+        //             of insertions rolled back
+        msg = "select * rowcount after 50 inserts - 10 rolled back:";
+
+        try {
+            assertEquals(msg, 40, rowcount);
+        } catch (Exception e) {}
+
+        //-- test 11 : An SQL-savepoint shall be destroyed in the
+        //            process of rolling back to that savepoint
+        msg = "savepoint rolled back succesfully > 1 times";
+
+        try {
+            conn1.rollback(sp4);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+
+        conn1.rollback(sp3);
+
+        rs = stmt.executeQuery("select count(*) from t");
+
+        rs.next();
+
+        rowcount = rs.getInt(1);
+
+        rs.close();
+
+        //-- Test 12 : count of rows matches # rows inserted less the number
+        //             of insertions rolled back
+        msg = "select count(*) after 50 inserts - 20 rolled back:";
+
+        try {
+            assertEquals(msg, 30, rowcount);
+        } catch (Exception e) {}
+
+        //-- test 13 : An SQL-savepoint shall be destroyed in the
+        //            process of rolling back to that savepoint
+        msg = "savepoint released succesfully after use in rollback";
+
+        try {
+            conn1.releaseSavepoint(sp3);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+
+        conn1.rollback(sp1);
+
+        //-- test 14 : All subsequent savepoints (in a savepoint level)
+        //            shall be destroyed by the process of rolling back to
+        //            a preceeding savepoint (in the same savepoint level)
+        msg = "savepoint rolled back without raising an exception after "
+              + "rollback to a preceeding savepoint";
+
+        try {
+            conn1.rollback(sp2);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+
+        conn1.rollback();
+
+        //-- test 15 : All subsequent savepoints (in a savepoint level)
+        //            shall be destroyed by the process of
+        //            rolling back the active transaction
+        msg = "savepoint released succesfully when it should have been "
+              + "destroyed by a full rollback";
+
+        try {
+            conn1.releaseSavepoint(sp1);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+
+        conn1.setAutoCommit(false);
+
+        sp1 = conn1.setSavepoint("savepoint1");
+
+        conn1.rollback();
+        conn1.setAutoCommit(false);
+        conn1.createStatement().executeUpdate("savepoint \"savepoint1\"");
+
+        //-- test 16 : A JDBC Savepoint shall be considered invalid if used to
+        //             release an SQL-savepoint other than precisely the
+        //             one created in correspondence to the creation of that
+        //             JDBC Savepoint object
+        // fredt@users - we allow this if the name is valid
+/*
+        msg = "JDBC Savepoint used to successfully release an identically named "
+              + "savepoint in a transaction distinct from the originating "
+              + "transaction";
+        try {
+            conn1.releaseSavepoint(sp1);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+*/
+        conn1.setAutoCommit(false);
+
+        sp1 = conn1.setSavepoint("savepoint1");
+
+        conn1.createStatement().executeUpdate("savepoint \"savepoint1\"");
+
+        //-- test 17 : A JDBC Savepoint shall be considered invalid if used to
+        //             release an SQL-savepoint other than precisely the
+        //             one created in correspondence to the creation of that
+        //             JDBC Savepoint object
+        // fredt@users - we allow this if the name is valid
+/*
+        msg = "JDBC Savepoint used to successfully release an identically named "
+              + "savepoint in a transaction other than the originating "
+              + "transaction";
+        try {
+            conn1.releaseSavepoint(sp1);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+*/
+
+        //-- test 18 : A JDBC Savepoint shall be considered invalid if used to
+        //             roll back to an SQL-savepoint other than precisely the
+        //             one created in correspondence to the creation of that
+        //             JDBC Savepoint object
+        // fredt@users - we allow this if the name is valid
+/*
+        msg = "JDBC Savepoint used to successfully to roll back to an "
+              + "identically named savepoint in a transaction distinct "
+              + "from the originating transaction";
+        try {
+            conn1.rollback(sp1);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+*/
+        conn1.setAutoCommit(false);
+
+        sp1 = conn1.setSavepoint("savepoint1");
+
+        conn1.createStatement().executeUpdate("savepoint \"savepoint1\"");
+
+        //-- test 19 : A JDBC Savepoint shall be considered invalid if used to
+        //             roll back to an SQL-savepoint other than precisely the
+        //             one created in correspondence to the creation of that
+        //             JDBC Savepoint object
+        // fredt@users - we allow this if the name is valid
+/*
+        msg = "JDBC Savepoint used to successfully release an identically named "
+              + "savepoint in a transaction other than the originating "
+              + "transaction";
+        try {
+            conn1.releaseSavepoint(sp1);
+            assertTrue(msg, false);
+        } catch (Exception e) {}
+*/
+    }
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestJDBCSavepoints("testJDBCSavepoints");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println("TestJDBCSavepoints failure count: " + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestJavaFunctions.java b/src/org/hsqldb/test/TestJavaFunctions.java
new file mode 100644
index 0000000..d6eb435
--- /dev/null
+++ b/src/org/hsqldb/test/TestJavaFunctions.java
@@ -0,0 +1,207 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.math.BigInteger;
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.hsqldb.jdbc.JDBCConnection;
+import org.hsqldb.jdbc.JDBCResultSet;
+import org.hsqldb.navigator.RowSetNavigator;
+import org.hsqldb.navigator.RowSetNavigatorClient;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultMetaData;
+import org.hsqldb.types.BinaryData;
+import org.hsqldb.types.Type;
+
+public class TestJavaFunctions extends TestBase {
+
+    public TestJavaFunctions() {
+        super("TestJavaFunction", "jdbc:hsqldb:file:test3", false, false);
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            prepareDatabase();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    void prepareDatabase() throws SQLException {
+
+        Connection c = newConnection();
+        Statement  s = c.createStatement();
+
+        s.executeUpdate("DROP FUNCTION TEST_QUERY IF EXISTS");
+        s.executeUpdate("DROP FUNCTION TEST_CUSTOM_RESULT IF EXISTS");
+        s.executeUpdate("DROP TABLE T IF EXISTS");
+        s.executeUpdate("CREATE TABLE T(C VARCHAR(20), I INT)");
+        s.executeUpdate("INSERT INTO T VALUES 'Thames', 10");
+        s.executeUpdate("INSERT INTO T VALUES 'Fleet', 12");
+        s.executeUpdate("INSERT INTO T VALUES 'Brent', 14");
+        s.executeUpdate("INSERT INTO T VALUES 'Westbourne', 16");
+        s.executeUpdate(
+            "CREATE FUNCTION TEST_QUERY(INT) RETURNS TABLE(N VARCHAR(20), I INT) "
+            + " READS SQL DATA LANGUAGE JAVA EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.TestJavaFunctions.getQueryResult'");
+        s.executeUpdate(
+            "CREATE FUNCTION TEST_CUSTOM_RESULT(BIGINT, BIGINT) RETURNS TABLE(I BIGINT, N VARBINARY(1000)) "
+            + " READS SQL DATA LANGUAGE JAVA EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.TestJavaFunctions.getCustomResult'");
+        s.executeUpdate("CHECKPOINT");
+        c.close();
+    }
+
+    public void testOne() throws SQLException {
+
+        Connection        c = newConnection();
+        CallableStatement s = c.prepareCall("CALL TEST_QUERY(16)");
+
+        s.execute();
+
+        ResultSet r = s.getResultSet();
+
+        while (r.next()) {
+            String temp = "" + r.getInt(2) + " " + r.getString(1);
+
+            System.out.println(temp);
+        }
+
+        s = c.prepareCall("CALL TEST_CUSTOM_RESULT(6, 19)");
+
+        s.execute();
+
+        r = s.getResultSet();
+
+        while (r.next()) {
+            String temp =
+                "" + r.getLong(1) + " "
+                + org.hsqldb.lib.StringConverter.byteArrayToSQLHexString(
+                    r.getBytes(2));
+
+            System.out.println(temp);
+        }
+
+        s = c.prepareCall("CALL TEST_CUSTOM_RESULT(6, 1900)");
+
+        try {
+            s.execute();
+
+            r = s.getResultSet();
+
+            fail("exception not thrown");
+        } catch (SQLException e) {
+            System.out.println(e.getMessage());
+        }
+
+        c.close();
+    }
+
+    public static void main(String[] args) throws SQLException {}
+
+    public static ResultSet getQueryResult(Connection connection,
+                                           int i) throws SQLException {
+
+        Statement st = connection.createStatement();
+
+        return st.executeQuery("SELECT * FROM T WHERE I < " + i);
+    }
+
+    public static ResultSet getQueryResult(Connection connection,
+                                           String p1) throws SQLException {
+        return getQueryResult(connection, 13);
+    }
+
+    public static ResultSet getQueryResult(Connection connection, String p1,
+                                           String p2) throws SQLException {
+        return getQueryResult(connection, 20);
+    }
+
+    private static Result newTwoColumnResult() {
+
+        Type[] types = new Type[2];
+
+        types[0] = Type.SQL_BIGINT;
+        types[1] = Type.SQL_VARBINARY_DEFAULT;
+
+        ResultMetaData  meta = ResultMetaData.newSimpleResultMetaData(types);
+        RowSetNavigator navigator = new RowSetNavigatorClient();
+        Result          result    = Result.newDataResult(meta);
+
+        result.setNavigator(navigator);
+
+        return result;
+    }
+
+    public static ResultSet getCustomResult(Connection connection, long start,
+            long end) throws SQLException {
+
+        Result result = newTwoColumnResult();
+
+        if (end < start) {
+            long temp = start;
+
+            start = end;
+            end   = temp;
+        }
+
+        if (end > 1000) {
+            throw org.hsqldb.jdbc.Util.invalidArgument(
+                "value larger than 100");
+        }
+
+        if (end > start + 100) {
+            end = start + 100;
+        }
+
+        for (long i = start; i < end; i++) {
+            Object[] row = new Object[2];
+
+            row[0] = Long.valueOf(i);
+            row[1] = new BinaryData(BigInteger.valueOf(i).toByteArray(),
+                                    false);
+
+            result.navigator.add(row);
+        }
+
+        result.navigator.reset();
+
+        return new JDBCResultSet((JDBCConnection) connection, null, result,
+                                 result.metaData);
+    }
+}
diff --git a/src/org/hsqldb/test/TestKarl.java b/src/org/hsqldb/test/TestKarl.java
new file mode 100644
index 0000000..e332f58
--- /dev/null
+++ b/src/org/hsqldb/test/TestKarl.java
@@ -0,0 +1,307 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+/**
+ * @author karl
+ *
+ */
+public class TestKarl {
+
+    final static String SHUTDOWN             = "SHUTDOWN";
+    final static String SHUTDOWN_IMMEDIATELY = "SHUTDOWN IMMEDIATELY";
+    final static String SHUTDOWN_COMPACT     = "SHUTDOWN COMPACT";
+
+    /**
+     *
+     * @param args
+     */
+    public static void main(String[] args) {
+
+        Connection c = null;
+
+        try {
+
+            //copy db
+            File f = new File("db");
+
+            if (!f.exists()) {
+                f.mkdir();
+            } else {
+                File[] list = f.listFiles();
+
+                for (int i = 0; i < list.length; i++) {
+                    list[i].delete();
+                }
+            }
+
+            copy("save/brwahl.properties", "db/brwahl.properties");
+            copy("save/brwahl.script", "db/brwahl.script");
+            copy("save/waehler.csv", "db/waehler.csv");
+
+            // config test
+            String  shutdown   = SHUTDOWN;
+            boolean autocommit = false;
+
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            c = DriverManager.getConnection("jdbc:hsqldb:file:db/brwahl",
+                                            "sa", "");
+
+            c.setAutoCommit(autocommit);
+
+            // open ok
+            printMeta(c);
+            printTable(c, "WAEHLER");
+
+            // test existing
+            doUpdateInsertDeleteWaehler(c);
+            printTable(c, "WAEHLER");
+
+            // test new
+            doCreateTableTest(c);
+            printTable(c, "TEST");
+
+            // colse
+            Statement st = c.createStatement();
+
+            st.execute(shutdown);
+            st.close();
+            c.close();
+
+            c = null;
+
+            // reopen test
+            System.out.println("\nDB OK? ...");
+
+            c = DriverManager.getConnection("jdbc:hsqldb:file:db/brwahl",
+                                            "sa", "");
+
+            c.setAutoCommit(false);
+            printTable(c, "WAEHLER");
+            printTable(c, "TEST");
+            doUpdateInsertDeleteWaehler(c);
+            c.rollback();
+
+            if (!autocommit) {
+                doCreateTableTest(c);
+                c.rollback();
+            }
+
+            c.close();
+
+            c = null;
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (c != null) {
+                try {
+                    c.close();
+                } catch (SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * @param p_connection
+     * @throws SQLException
+     */
+    private static void doCreateTableTest(Connection p_connection)
+    throws SQLException {
+
+        System.out.println("CREATE TESTTABLE START ...");
+
+        Statement st = p_connection.createStatement();
+
+        st.executeUpdate("DROP TABLE TEST IF EXISTS");
+        st.executeUpdate("CREATE TABLE TEST (TEST INTEGER)");
+        st.close();
+        System.out.println("END CREATE TESTTABLE");
+        System.out.println("INSERT INTO TESTTABLE START ...");
+
+        PreparedStatement p = p_connection.prepareStatement(
+            "INSERT INTO TEST (TEST) values (?)");
+
+        p.setInt(1, 123);
+        p.execute();
+        p.close();
+        System.out.println("END INSERT INTO TESTTABLE");
+    }
+
+    /**
+     * @param p_connection
+     * @throws SQLException
+     */
+    private static void doUpdateInsertDeleteWaehler(Connection p_connection)
+    throws SQLException {
+
+        System.out.println("UPDATE WAEHLER START ...");
+
+        PreparedStatement p = p_connection.prepareStatement(
+            "UPDATE WAEHLER SET AUSTRITTSDATUM=? WHERE NAME=?");
+
+        p.setDate(1, null);
+        p.setString(2, "Muster1");
+        p.execute();
+        p.close();
+        System.out.println("END UPDATE WAEHLER");
+        System.out.println("INSERT INTO WAEHLER START ...");
+
+        p = p_connection.prepareStatement(
+            "INSERT INTO WAEHLER (NAME, AUSTRITTSDATUM) VALUES (?,?)");
+
+        Calendar cal = GregorianCalendar.getInstance();
+
+        p.setString(1, "Muster3");
+        p.setDate(2, new Date(cal.getTimeInMillis()), cal);
+        p.execute();
+        p.close();
+        System.out.println("END INSERT INTO WAEHLER");
+        System.out.println("DELETE FROM WAEHLER START ...");
+
+        p = p_connection.prepareStatement(
+            "DELETE FROM WAEHLER WHERE NAME = ?");
+
+        p.setString(1, "Muster2");
+        p.execute();
+        p.close();
+        System.out.println("END DELETE FROM WAEHLER");
+    }
+
+    /**
+     * @param p_connection
+     * @param p_table
+     * @throws SQLException
+     */
+    private static void printTable(Connection p_connection,
+                                   String p_table) throws SQLException {
+
+        System.out.println("GET TABLE " + p_table + " START ...");
+
+        Statement st        = p_connection.createStatement();
+        ResultSet rs        = st.executeQuery("SELECT * FROM " + p_table);
+        int       col_count = rs.getMetaData().getColumnCount();
+
+        for (int i = 1; i <= col_count; i++) {
+            System.out.print(rs.getMetaData().getColumnLabel(i) + "\t");
+        }
+
+        System.out.println("");
+
+        while (rs.next()) {
+            for (int i = 1; i <= col_count; i++) {
+                System.out.print(rs.getObject(i));
+                System.out.print("\t");
+            }
+
+            System.out.println("");
+        }
+
+        st.close();
+        System.out.println("... END GET TABLE " + p_table);
+    }
+
+    /**
+     * @param p_connection
+     * @throws SQLException
+     */
+    private static void printMeta(Connection p_connection)
+    throws SQLException {
+
+        System.out.println("GET METADATA START ...");
+
+        ResultSet rs = p_connection.getMetaData().getTables(null, null, null,
+            null);
+
+        System.out.println(rs.toString());
+
+        int col_count = rs.getMetaData().getColumnCount();
+
+        for (int i = 1; i <= col_count; i++) {
+            System.out.print(rs.getMetaData().getColumnLabel(i) + "\t");
+        }
+
+        System.out.println("");
+
+        while (rs.next()) {
+            for (int i = 1; i <= col_count; i++) {
+                System.out.print(rs.getObject(i));
+                System.out.print("\t");
+            }
+
+            System.out.println("");
+        }
+
+        System.out.println("END GET METADATA");
+    }
+
+    private static void copy(String src, String dest) throws IOException {
+
+        File inputFile  = new File(src);
+        File outputFile = new File(dest);
+
+        if (!inputFile.exists()) {
+            return;
+        }
+
+        FileInputStream  in  = new FileInputStream(inputFile);
+        FileOutputStream out = new FileOutputStream(outputFile);
+        int              c;
+
+        while ((c = in.read()) != -1) {
+            out.write(c);
+        }
+
+        in.close();
+        out.close();
+    }
+}
diff --git a/src/org/hsqldb/test/TestLibSpeed.java b/src/org/hsqldb/test/TestLibSpeed.java
new file mode 100644
index 0000000..6ba4046
--- /dev/null
+++ b/src/org/hsqldb/test/TestLibSpeed.java
@@ -0,0 +1,239 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import org.hsqldb.lib.DoubleIntIndex;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.IntKeyHashMap;
+import org.hsqldb.lib.IntKeyIntValueHashMap;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.StopWatch;
+
+/**
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ */
+public class TestLibSpeed {
+
+    static final String[][] sNumeric = {
+        {
+            "ABS", "org.hsqldb.Library.abs"
+        }, {
+            "ACOS", "java.lang.Math.acos"
+        }, {
+            "ASIN", "java.lang.Math.asin"
+        }, {
+            "ATAN", "java.lang.Math.atan"
+        }, {
+            "ATAN2", "java.lang.Math.atan2"
+        }, {
+            "CEILING", "java.lang.Math.ceil"
+        }, {
+            "COS", "java.lang.Math.cos"
+        }, {
+            "COT", "org.hsqldb.Library.cot"
+        }, {
+            "DEGREES", "java.lang.Math.toDegrees"
+        }, {
+            "EXP", "java.lang.Math.exp"
+        }, {
+            "FLOOR", "java.lang.Math.floor"
+        }, {
+            "LOG", "java.lang.Math.log"
+        }, {
+            "LOG10", "org.hsqldb.Library.log10"
+        }, {
+            "MOD", "org.hsqldb.Library.mod"
+        }, {
+            "PI", "org.hsqldb.Library.pi"
+        }, {
+            "POWER", "java.lang.Math.pow"
+        }, {
+            "RADIANS", "java.lang.Math.toRadians"
+        }, {
+            "RAND", "java.lang.Math.random"
+        }, {
+            "ROUND", "org.hsqldb.Library.round"
+        }, {
+            "SIGN", "org.hsqldb.Library.sign"
+        }, {
+            "SIN", "java.lang.Math.sin"
+        }, {
+            "SQRT", "java.lang.Math.sqrt"
+        }, {
+            "TAN", "java.lang.Math.tan"
+        }, {
+            "TRUNCATE", "org.hsqldb.Library.truncate"
+        }, {
+            "BITAND", "org.hsqldb.Library.bitand"
+        }, {
+            "BITOR", "org.hsqldb.Library.bitor"
+        }, {
+            "ROUNDMAGIC", "org.hsqldb.Library.roundMagic"
+        }
+    };
+    static HashSet          hashSet  = new HashSet();
+    static DoubleIntIndex doubleIntLookup =
+        new DoubleIntIndex(sNumeric.length, false);
+    static IntKeyIntValueHashMap intKeyIntValueHashLookup =
+        new IntKeyIntValueHashMap();
+    static IntValueHashMap intValueHashLookup =
+        new IntValueHashMap(sNumeric.length);
+    static IntKeyHashMap intKeyHashLookup = new IntKeyHashMap();
+
+    static {
+        doubleIntLookup.setKeysSearchTarget();
+
+        java.util.Random randomgen = new java.util.Random();
+        int[]            row       = new int[2];
+
+        for (int i = 0; i < sNumeric.length; i++) {
+            hashSet.add(sNumeric[i][0]);
+            intKeyIntValueHashLookup.put(randomgen.nextInt(sNumeric.length),
+                                         i);
+            intKeyHashLookup.put(i, new Integer(i));
+            doubleIntLookup.add(randomgen.nextInt(sNumeric.length), i);
+            intValueHashLookup.put(sNumeric[i][0],
+                                   randomgen.nextInt(sNumeric.length));
+        }
+    }
+
+    static int count = 100000;
+
+    public TestLibSpeed() {
+
+        java.util.Random randomgen = new java.util.Random();
+        StopWatch        sw        = new StopWatch();
+        int              dummy     = 0;
+
+        System.out.println("set lookup ");
+
+        for (int k = 0; k < 3; k++) {
+            sw.zero();
+
+            for (int j = 0; j < count; j++) {
+                for (int i = 0; i < sNumeric.length; i++) {
+                    int r = randomgen.nextInt(sNumeric.length);
+
+                    hashSet.contains(sNumeric[r][0]);
+
+                    dummy += r;
+                }
+            }
+
+            System.out.println("HashSet contains " + sw.elapsedTime());
+            sw.zero();
+
+            for (int j = 0; j < count; j++) {
+                for (int i = 0; i < sNumeric.length; i++) {
+                    int r = randomgen.nextInt(sNumeric.length);
+
+                    intKeyIntValueHashLookup.get(r, -1);
+
+                    dummy += r;
+                }
+            }
+
+            System.out.println("IntKeyIntValueHashMap Lookup with array "
+                               + sw.elapsedTime());
+            sw.zero();
+
+            for (int j = 0; j < count; j++) {
+                for (int i = 0; i < sNumeric.length; i++) {
+                    int r = randomgen.nextInt(sNumeric.length);
+
+                    intKeyHashLookup.get(r);
+
+                    dummy += r;
+                }
+            }
+
+            System.out.println("IntKeyHashMap Lookup " + sw.elapsedTime());
+            sw.zero();
+
+            for (int j = 0; j < count; j++) {
+                for (int i = 0; i < sNumeric.length; i++) {
+                    int r = randomgen.nextInt(sNumeric.length);
+
+                    doubleIntLookup.findFirstEqualKeyIndex(r);
+
+                    dummy += r;
+                }
+            }
+
+            System.out.println("DoubleIntTable Lookup " + sw.elapsedTime());
+            sw.zero();
+
+            for (int j = 0; j < count; j++) {
+                for (int i = 0; i < sNumeric.length; i++) {
+                    int r = randomgen.nextInt(sNumeric.length);
+
+                    intValueHashLookup.get(sNumeric[r][0], 0);
+
+                    dummy += r;
+                }
+            }
+
+            System.out.println("IntKeyIntValueHashMap Lookup "
+                               + sw.elapsedTime());
+            sw.zero();
+
+            for (int j = 0; j < count; j++) {
+                for (int i = 0; i < sNumeric.length; i++) {
+                    int r = randomgen.nextInt(sNumeric.length);
+
+                    dummy += r;
+                }
+            }
+
+            System.out.println("emptyOp " + sw.elapsedTime());
+            sw.zero();
+
+            for (int j = 0; j < count; j++) {
+                for (int i = 0; i < sNumeric.length; i++) {
+                    int r = randomgen.nextInt(sNumeric.length);
+
+                    doubleIntLookup.findFirstEqualKeyIndex(r);
+
+                    dummy += r;
+                }
+            }
+
+            System.out.println("DoubleIntTable Lookup " + sw.elapsedTime());
+            sw.zero();
+            System.out.println("Object Cache Test " + sw.elapsedTime());
+        }
+    }
+
+    public static void main(String[] argv) {
+        TestLibSpeed ls = new TestLibSpeed();
+    }
+}
diff --git a/src/org/hsqldb/test/TestLikePredicateOptimizations.java b/src/org/hsqldb/test/TestLikePredicateOptimizations.java
new file mode 100644
index 0000000..d41f7cb
--- /dev/null
+++ b/src/org/hsqldb/test/TestLikePredicateOptimizations.java
@@ -0,0 +1,268 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * HSQLDB TestLikePredicate Junit test case. <p>
+ *
+ * @author  boucherb@users
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class TestLikePredicateOptimizations extends TestBase {
+
+    public TestLikePredicateOptimizations(String name) {
+        super(name);
+    }
+
+    /* Implements the TestLikePredicate test */
+    public void test() throws Exception {
+
+        Connection        conn = newConnection();
+        Statement         stmt = conn.createStatement();
+        PreparedStatement pstmt;
+        ResultSet         rs;
+        String            sql;
+        int               expectedCount;
+        int               actualCount;
+
+        stmt.execute("drop table test if exists");
+        stmt.execute("drop table empty if exists");
+
+        sql = "create table test(name varchar(255))";
+
+        stmt.execute(sql);
+
+        sql = "create table empty(name varchar(255))";
+
+        stmt.execute(sql);
+
+        sql = "insert into empty values 'name10'";
+
+        stmt.execute(sql);
+
+        sql = "insert into empty values 'name11'";
+
+        stmt.execute(sql);
+
+        sql   = "insert into test values(?)";
+        pstmt = conn.prepareStatement(sql);
+
+        for (int i = 0; i < 10000; i++) {
+            pstmt.setString(1, "name" + i);
+            pstmt.addBatch();
+        }
+
+        pstmt.executeBatch();
+
+//
+        sql = "select count(*) from test where name = (select max(name) from empty)";
+        rs = stmt.executeQuery(sql);
+
+        rs.next();
+
+        expectedCount = rs.getInt(1);
+        sql = "select count(*) from test where name like (select min(name) from empty)";
+        pstmt = conn.prepareStatement(sql);
+        rs    = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+        sql = "select count(*) from test where (select max(name) from empty where empty.name = test.name and empty.name > ?) like '%ame11%'";
+        pstmt = conn.prepareStatement(sql);
+
+        pstmt.setString(1, "n");
+
+        rs = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+// --
+        sql = "select count(*) from test where name = ''";
+        rs  = stmt.executeQuery(sql);
+
+        rs.next();
+
+        expectedCount = rs.getInt(1);
+        sql           = "select count(*) from test where name like ''";
+        pstmt         = conn.prepareStatement(sql);
+        rs            = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+        // --
+        sql = "SELECT t.name FROM test t WHERE ((SELECT t2.name from test t2 where t2.name=?) like '%name5000%')";
+        pstmt = conn.prepareStatement(sql);
+
+        pstmt.setString(1, "name5000");
+
+        rs = pstmt.executeQuery();
+
+        assertEquals(rs.next(), true);
+        String actual = rs.getString(1);
+        assertEquals(actual, "name0");
+
+// --
+// --
+        sql = "select count(*) from test where name is not null";
+        rs  = stmt.executeQuery(sql);
+
+        rs.next();
+
+        expectedCount = rs.getInt(1);
+        sql           = "select count(*) from test where name like '%'";
+        pstmt         = conn.prepareStatement(sql);
+        rs            = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+// --
+        sql = "select count(*) from test where substring(name from 1 for 6) = 'name44'";
+        rs = stmt.executeQuery(sql);
+
+        rs.next();
+
+        expectedCount = rs.getInt(1);
+        sql           = "select count(*) from test where name like 'name44%'";
+        pstmt         = conn.prepareStatement(sql);
+        rs            = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+// --
+        sql = "select count(*) from test where left(name,5) = 'name4' and right(name,1) = '5'";
+        rs = stmt.executeQuery(sql);
+
+        rs.next();
+
+        expectedCount = rs.getInt(1);
+        sql           = "select count(*) from test where name like 'name4%5'";
+        pstmt         = conn.prepareStatement(sql);
+        rs            = pstmt.executeQuery();
+
+        rs.next();
+
+        actualCount = rs.getInt(1);
+
+        assertEquals("\"" + sql + "\"", expectedCount, actualCount);
+
+// --
+        String result  = "true";
+        String presult = "false";
+
+        stmt.execute("drop table test1 if exists");
+
+        sql   = "CREATE TABLE test1 (col CHAR(30))";
+        pstmt = conn.prepareStatement(sql);
+
+        pstmt.execute();
+
+        sql   = "INSERT INTO test1 (col) VALUES ('one')";
+        pstmt = conn.prepareStatement(sql);
+
+        pstmt.execute();
+
+        sql   = "SELECT * FROM test1 WHERE ( col LIKE ? )";
+        pstmt = conn.prepareStatement(sql);
+
+        pstmt.setString(1, "on%");
+
+        rs = pstmt.executeQuery();
+
+        if (rs.next()) {
+            presult = rs.getString("COL");
+        }
+
+        sql   = "SELECT * FROM test1 WHERE ( col LIKE 'one' )";
+        pstmt = conn.prepareStatement(sql);
+        rs    = pstmt.executeQuery();
+
+        if (rs.next()) {
+            result = rs.getString("COL");
+        }
+
+        assertEquals("\"" + sql + "\"", result, presult);
+    }
+
+    /* Runs TestLikePredicate test from the command line*/
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestLikePredicateOptimizations("test");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println("TestLikePredicateOptimizations failure count: "
+                           + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestLobs.java b/src/org/hsqldb/test/TestLobs.java
new file mode 100644
index 0000000..692d539
--- /dev/null
+++ b/src/org/hsqldb/test/TestLobs.java
@@ -0,0 +1,664 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.rowset.serial.SerialBlob;
+
+import org.hsqldb.jdbc.JDBCBlob;
+import org.hsqldb.jdbc.JDBCClob;
+import org.hsqldb.lib.StopWatch;
+import org.hsqldb.lib.HsqlByteArrayInputStream;
+
+public class TestLobs extends TestBase {
+
+    Connection connection;
+    Statement  statement;
+
+    public TestLobs(String name) {
+
+        super(name);
+//        super(name, "jdbc:hsqldb:file:test3", false, false);
+
+//        super(name, "jdbc:hsqldb:mem:test3", false, false);
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            connection = super.newConnection();
+            statement  = connection.createStatement();
+        } catch (Exception e) {
+            System.out.println(e);
+        }
+    }
+
+    public void testBlobA() {
+
+        try {
+            String ddl0 = "DROP TABLE BLOBTEST IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE BLOBTEST(ID IDENTITY, BLOBFIELD BLOB(1000))";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+
+        try {
+            String dml0 = "insert into blobtest(blobfield) values(?)";
+            String            dql0 = "select * from blobtest;";
+            PreparedStatement ps   = connection.prepareStatement(dml0);
+            byte[]            data = new byte[] {
+                1, 2, 3, 4, 5, 6, 7, 8, 9, 10
+            };
+            Blob              blob = new JDBCBlob(data);
+
+            ps.setBlob(1, blob);
+            ps.executeUpdate();
+
+            data[4] = 50;
+            blob    = new JDBCBlob(data);
+
+            ps.setBlob(1, blob);
+            ps.executeUpdate();
+            ps.close();
+
+            ps = connection.prepareStatement(dql0);
+
+            ResultSet rs = ps.executeQuery();
+
+            rs.next();
+
+            Blob blob1 = rs.getBlob(2);
+
+            rs.next();
+
+            Blob   blob2 = rs.getBlob(2);
+            byte[] data1 = blob1.getBytes(1, 10);
+            byte[] data2 = blob2.getBytes(1, 10);
+
+            assertTrue(data1[4] == 5 && data2[4] == 50);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+    }
+
+    public void testBlobB() {
+
+        ResultSet rs;
+        byte[]    ba;
+        byte[]    baR1 = new byte[] {
+            (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5,
+            (byte) 0xF6, (byte) 0xF7, (byte) 0xF8, (byte) 0xF9, (byte) 0xFA,
+            (byte) 0xFB
+        };
+        byte[] baR2 = new byte[] {
+            (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5,
+            (byte) 0xE6, (byte) 0xE7, (byte) 0xE8, (byte) 0xE9, (byte) 0xEA,
+            (byte) 0xEB
+        };
+
+        try {
+            connection.setAutoCommit(false);
+
+            Statement st = connection.createStatement();
+
+            st.executeUpdate("CREATE TABLE blo (id INTEGER, b blob( 100))");
+
+            PreparedStatement ps = connection.prepareStatement(
+                "INSERT INTO blo(id, b) values(2, ?)");
+
+            //st.executeUpdate("INSERT INTO blo (id, b) VALUES (1, x'A003')");
+            ps.setBlob(1, new SerialBlob(baR1));
+            ps.executeUpdate();
+
+            rs = st.executeQuery("SELECT b FROM blo WHERE id = 2");
+
+            if (!rs.next()) {
+                assertTrue("No row with id 2", false);
+            }
+
+            java.sql.Blob blob1 = rs.getBlob("b");
+
+            System.out.println("Size of retrieved blob: " + blob1.length());
+
+            //System.out.println("Value = (" + rs.getString("b") + ')');
+            byte[] baOut = blob1.getBytes(1, (int) blob1.length());
+
+            if (baOut.length != baR1.length) {
+                assertTrue("Expected array len " + baR1.length + ", got len "
+                           + baOut.length, false);
+            }
+
+            for (int i = 0; i < baOut.length; i++) {
+                if (baOut[i] != baR1[i]) {
+                    assertTrue("Expected array len " + baR1.length
+                               + ", got len " + baOut.length, false);
+                }
+            }
+
+            rs.close();
+
+            rs = st.executeQuery("SELECT b FROM blo WHERE id = 2");
+
+            if (!rs.next()) {
+                assertTrue("No row with id 2", false);
+            }
+
+//            ba = rs.getBytes("b"); doesn't convert but throws ClassCast
+            blob1 = rs.getBlob("b");
+            ba    = blob1.getBytes(1, baR2.length);
+
+            if (ba.length != baR2.length) {
+                assertTrue("row2 byte length differs", false);
+            }
+
+            for (int i = 0; i < ba.length; i++) {
+                if (ba[i] != baR1[i]) {
+                    assertTrue("row2 byte " + i + " differs", false);
+                }
+            }
+
+            rs.close();
+            connection.rollback();
+
+            // again with stream
+            ps.setBinaryStream(1, new HsqlByteArrayInputStream(baR1),
+                               baR1.length);
+            ps.executeUpdate();
+
+            rs = st.executeQuery("SELECT b FROM blo WHERE id = 2");
+
+            if (!rs.next()) {
+                assertTrue("No row with id 2", false);
+            }
+
+            blob1 = rs.getBlob("b");
+
+            System.out.println("Size of retrieved blob: " + blob1.length());
+
+            //System.out.println("Value = (" + rs.getString("b") + ')');
+            baOut = blob1.getBytes(1, (int) blob1.length());
+
+            if (baOut.length != baR1.length) {
+                assertTrue("Expected array len " + baR1.length + ", got len "
+                           + baOut.length, false);
+            }
+
+            for (int i = 0; i < baOut.length; i++) {
+                if (baOut[i] != baR1[i]) {
+                    assertTrue("Expected array len " + baR1.length
+                               + ", got len " + baOut.length, false);
+                }
+            }
+
+            rs.close();
+            connection.close();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+    }
+
+    public void testClobA() {
+
+        try {
+            String ddl0 = "DROP TABLE CLOBTEST IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE CLOBTEST(ID IDENTITY, CLOBFIELD CLOB(1000))";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {}
+
+        try {
+            String dml0 = "insert into clobtest(clobfield) values(?)";
+            String            dql0 = "select * from clobtest;";
+            PreparedStatement ps   = connection.prepareStatement(dml0);
+            String            data = "Testing clob insert and select ops";
+            Clob              clob = new JDBCClob(data);
+
+            ps.setClob(1, clob);
+            ps.executeUpdate();
+
+            data = data.replaceFirst("insert", "INSERT");
+            clob = new JDBCClob(data);
+
+            ps.setClob(1, clob);
+            ps.executeUpdate();
+            ps.close();
+
+            ps = connection.prepareStatement(dql0);
+
+            ResultSet rs = ps.executeQuery();
+
+            rs.next();
+
+            Clob clob1 = rs.getClob(2);
+
+            rs.next();
+
+            Clob clob2 = rs.getClob(2);
+            int data1 = clob1.getSubString(1, data.length()).indexOf("insert");
+            int data2 = clob2.getSubString(1, data.length()).indexOf("INSERT");
+
+            assertTrue(data1 == data2 && data1 > 0);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+    }
+
+    public void testClobB() {
+
+        try {
+            String ddl0 = "DROP TABLE CLOBTEST IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE CLOBTEST(ID IDENTITY, V VARCHAR(10), I INT, CLOBFIELD CLOB(1000))";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {}
+
+        try {
+            String dml0 = "insert into clobtest values(default, ?, ?, ?)";
+            String            dql0 = "select * from clobtest;";
+            PreparedStatement ps   = connection.prepareStatement(dml0);
+            String            data = "Testing clob insert and select ops";
+            Clob              clob = new JDBCClob(data);
+
+            ps.setString(1, "test");
+            ps.setInt(2, 5);
+            ps.setClob(3, clob);
+            ps.executeUpdate();
+
+            data = data.replaceFirst("insert", "INSERT");
+            clob = new JDBCClob(data);
+
+            ps.setClob(3, clob);
+            ps.executeUpdate();
+
+            PreparedStatement ps2 = connection.prepareStatement(dql0);
+            ResultSet         rs  = ps2.executeQuery();
+
+            rs.next();
+
+            Clob clob1 = rs.getClob(4);
+
+            rs.next();
+
+            Clob clob2 = rs.getClob(4);
+            int data1 = clob1.getSubString(1, data.length()).indexOf("insert");
+            int data2 = clob2.getSubString(1, data.length()).indexOf("INSERT");
+
+            assertTrue(data1 == data2 && data1 > 0);
+
+            //
+            Clob   clob3  = new JDBCClob(data);
+            Reader reader = clob3.getCharacterStream();
+
+            ps.setCharacterStream(3, reader, (int) clob3.length());
+            ps.executeUpdate();
+
+            //
+            reader = clob2.getCharacterStream();
+
+            try {
+                ps.setCharacterStream(3, reader, (int) clob3.length());
+                assertTrue(false);
+                ps.executeUpdate();
+            } catch (SQLException e) {}
+
+            connection.commit();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+    }
+
+    public void testClobC() {
+
+        try {
+            String ddl0 = "DROP TABLE VARIABLE IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE VARIABLE (stateid varchar(128), varid numeric(16,0), "
+                + "scalabilitypassivated char(1) DEFAULT 'N', value clob (2G), scopeguid varchar(128),"
+                + "primary key (stateid, varid, scalabilitypassivated, scopeguid))";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {}
+
+        try {
+            String dml0 = "INSERT INTO VARIABLE VALUES (?, ?, 'N', ?, ?)";
+            String dml1 =
+                "UPDATE VARIABLE SET value = ? WHERE stateid = ? AND "
+                + "varid = ? AND scalabilitypassivated = 'N' AND scopeguid = ?";
+            PreparedStatement ps = connection.prepareStatement(dml0);
+
+            //
+            String resourceFileName  = "/org/hsqldb/resources/lob-schema.sql";
+            InputStreamReader reader = null;
+
+            try {
+                InputStream fis =
+                    getClass().getResourceAsStream(resourceFileName);
+
+                reader = new InputStreamReader(fis, "ISO-8859-1");
+            } catch (Exception e) {}
+
+            ps.setString(1, "test-id-1");
+            ps.setLong(2, 23456789123456L);
+            ps.setCharacterStream(3, reader, 1000);
+            ps.setString(4, "test-scope-1");
+            ps.executeUpdate();
+
+            try {
+                InputStream fis =
+                    getClass().getResourceAsStream(resourceFileName);
+
+                fis    = getClass().getResourceAsStream(resourceFileName);
+                reader = new InputStreamReader(fis, "ISO-8859-1");
+
+                for (int i = 0; i < 100; i++) {
+                    reader.read();
+                }
+            } catch (Exception e) {}
+
+            //
+            ps.setString(1, "test-id-2");
+            ps.setLong(2, 23456789123457L);
+            ps.setCharacterStream(3, reader, 100);
+            ps.setString(4, "test-scope-2");
+            ps.addBatch();
+            ps.setString(1, "test-id-3");
+            ps.setLong(2, 23456789123458L);
+            ps.setCharacterStream(3, reader, 100);
+            ps.setString(4, "test-scope-3");
+            ps.addBatch();
+
+            int[] results = ps.executeBatch();
+
+            //
+            try {
+                InputStream fis =
+                    getClass().getResourceAsStream(resourceFileName);
+
+                fis    = getClass().getResourceAsStream(resourceFileName);
+                reader = new InputStreamReader(fis, "ISO-8859-1");
+
+                for (int i = 0; i < 100; i++) {
+                    reader.read();
+                }
+            } catch (Exception e) {}
+
+            ps = connection.prepareStatement(dml1);
+
+            ps.setCharacterStream(1, reader, 500);
+            ps.setString(2, "test-id-1");
+            ps.setLong(3, 23456789123456L);
+            ps.setString(4, "test-scope-1");
+            ps.executeUpdate();
+            ps.close();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+    }
+
+    public void testClobD() {
+
+        try {
+            String ddl0 = "DROP TABLE VARIABLE IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE VARIABLE (stateid varchar(128), varid numeric(16,0), "
+                + "scalabilitypassivated char(1) DEFAULT 'N', value clob(2000), scopeguid varchar(128),"
+                + "primary key (stateid, varid, scalabilitypassivated, scopeguid))";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {}
+
+        try {
+            String dml0 = "INSERT INTO VARIABLE VALUES (?, ?, 'N', ?, ?)";
+            String dml1 =
+                "UPDATE VARIABLE SET value = ? WHERE stateid = ? AND "
+                + "varid = ? AND scalabilitypassivated = 'N' AND scopeguid = ?";
+            PreparedStatement ps = connection.prepareStatement(dml0);
+
+            connection.setAutoCommit(false);
+
+            //
+            JDBCClob dataClob =
+                new JDBCClob("the quick brown fox jumps on the lazy dog");
+            Reader    reader = null;
+            StopWatch sw     = new StopWatch();
+
+            sw.start();
+
+            for (int i = 0; i < 1000; i++) {
+                reader = dataClob.getCharacterStream();
+
+                ps.setString(1, "test-id-1" + i);
+                ps.setLong(2, 23456789123456L + i);
+                ps.setCharacterStream(3, reader, dataClob.length());
+                ps.setString(4, "test-scope-1" + i);
+                ps.executeUpdate();
+                connection.commit();
+            }
+
+            sw.stop();
+            System.out.println(sw.elapsedTimeToMessage("Time for inserts"));
+
+            ps = connection.prepareStatement(dml1);
+
+            sw.zero();
+            sw.start();
+
+            for (int i = 100; i < 200; i++) {
+                reader = dataClob.getCharacterStream();
+
+                ps.setCharacterStream(1, reader, dataClob.length());
+                ps.setString(2, "test-id-1" + i);
+                ps.setLong(3, 23456789123456L + i);
+                ps.setString(4, "test-scope-1" + i);
+                ps.executeUpdate();
+                connection.commit();
+            }
+
+            connection.commit();
+            sw.stop();
+            System.out.println(sw.elapsedTimeToMessage("Time for updates"));
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+    }
+
+    public void testClobE() {
+
+        try {
+            String ddl0 = "DROP TABLE VARIABLE IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE VARIABLE (stateid varchar(128), varid numeric(16,0), "
+                + "scalabilitypassivated char(1) DEFAULT 'N', value clob(2000), scopeguid varchar(128),"
+                + "primary key (stateid, varid, scalabilitypassivated, scopeguid))";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {}
+
+        try {
+            String dml0 = "INSERT INTO VARIABLE VALUES (?, ?, 'N', ?, ?)";
+            String dml1 =
+                "UPDATE VARIABLE SET varid = varid + 1 WHERE stateid = ? AND "
+                + "varid = ? AND scalabilitypassivated = 'N' AND scopeguid = ?";
+            PreparedStatement ps = connection.prepareStatement(dml0);
+
+            connection.setAutoCommit(false);
+
+            //
+            JDBCClob dataClob =
+                new JDBCClob("the quick brown fox jumps on the lazy dog");
+            Reader    reader = null;
+            StopWatch sw     = new StopWatch();
+
+            sw.start();
+
+            for (int i = 0; i < 100; i++) {
+                reader = dataClob.getCharacterStream();
+
+                ps.setString(1, "test-id-1" + i);
+                ps.setLong(2, 23456789123456L + i);
+                ps.setCharacterStream(3, reader, dataClob.length());
+                ps.setString(4, "test-scope-1" + i);
+                ps.executeUpdate();
+                connection.commit();
+            }
+
+            sw.stop();
+            System.out.println(sw.elapsedTimeToMessage("Time for inserts"));
+
+            ps = connection.prepareStatement(dml1);
+
+            sw.zero();
+            sw.start();
+
+            for (int i = 10; i < 20; i++) {
+                ps.setString(1, "test-id-1" + i);
+                ps.setLong(2, 23456789123456L + i);
+                ps.setString(3, "test-scope-1" + i);
+                ps.executeUpdate();
+                connection.commit();
+            }
+
+            connection.commit();
+
+            ResultSet rs = statement.executeQuery("SELECT * FROM VARIABLE");
+
+            while (rs.next()) {
+                Clob clob       = rs.getClob(4);
+                long dataLength = dataClob.length();
+                long clobLength = clob.length();
+
+                assertTrue(dataLength == clobLength);
+                assertTrue(
+                    dataClob.getSubString(1, 30).equals(
+                        clob.getSubString(1, 30)));
+            }
+
+            rs = statement.executeQuery(
+                "SELECT CAST(SUBSTRING(VALUE FROM 19) AS VARCHAR(100)),STATEID,"
+                + "CHARACTER_LENGTH(VALUE),CAST(VALUE AS VARCHAR(100)) FROM "
+                + "VARIABLE WHERE VALUE='THE QUICK BROWN FOX JUMPS ON THE LAZY DOG'"
+                + "AND STATEID>'TEST-ID-197'");
+
+            while (rs.next()) {
+                assertTrue(rs.getString(1).equals("x jumps on the lazy dog"));
+            }
+
+            sw.stop();
+            System.out.println(sw.elapsedTimeToMessage("Time for updates"));
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+    }
+
+    public void testClobF() {
+
+        try {
+            String ddl0 = "DROP TABLE CLOBTEST IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE CLOBTEST(ID IDENTITY, CLOBFIELD CLOB(1000))";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {}
+
+        try {
+            String dml0  = "insert into clobtest(clobfield) values('";
+            String value = "0123456789";
+
+            dml0 = dml0 + value + "')";
+
+            String dql0 = "select CHARACTER_LENGTH(clobfield) from clobtest;";
+            PreparedStatement ps = connection.prepareStatement(dml0);
+
+            //ps.setClob(1, clob);
+            ps.executeUpdate();
+            ps.close();
+
+            ps = connection.prepareStatement(dql0);
+
+            final ResultSet rs = ps.executeQuery();
+
+            rs.next();
+
+            final int length = rs.getInt(1);
+
+            assertTrue(value.length() == length);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("test failure");
+        }
+    }
+
+    protected void tearDown() {
+
+        try {
+            statement = connection.createStatement();
+
+            statement.execute("SHUTDOWN");
+            statement.close();
+            connection.close();
+        } catch (Exception e) {}
+
+        super.tearDown();
+    }
+}
diff --git a/src/org/hsqldb/test/TestMerge.java b/src/org/hsqldb/test/TestMerge.java
new file mode 100644
index 0000000..7eaef18
--- /dev/null
+++ b/src/org/hsqldb/test/TestMerge.java
@@ -0,0 +1,436 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Enumeration;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * Test merge statements via jdbc against in-memory database
+ * @author Justin Spadea
+ */
+public class TestMerge extends TestBase {
+
+    Statement         stmnt;
+    PreparedStatement pstmnt;
+    Connection        connection;
+
+    public TestMerge(String name) {
+        super(name);
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            connection = super.newConnection();
+            stmnt      = connection.createStatement();
+        } catch (Exception e) {}
+    }
+
+    /**
+     * Prints a table displaying specified columns, and checks the expected
+     * number of rows.
+     */
+    private void printTable(String table, String cols,
+                            int expected) throws SQLException {
+
+        int               rows = 0;
+        ResultSet rs = stmnt.executeQuery("SELECT " + cols + " FROM " + table);
+        ResultSetMetaData rsmd = rs.getMetaData();
+        String result = "Table " + table + ", expecting " + expected
+                        + " rows total:\n";
+
+        while (rs.next()) {
+            for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                result += rsmd.getColumnLabel(i + 1) + ":"
+                          + rs.getString(i + 1) + ":";
+            }
+
+            result += "\n";
+
+            rows++;
+        }
+
+        rs.close();
+        System.out.println(result);
+        assertEquals(expected, rows);
+    }
+
+    /**
+     * Sets up tables T and S and executes MERGE query on them
+     * @param sql
+     * @throws SQLException
+     */
+    private void executeMerge(String merge) throws SQLException {
+
+        // create table T and insert some preliminary data
+        stmnt.execute("DROP SCHEMA SA IF EXISTS CASCADE;");
+        stmnt.execute("CREATE SCHEMA SA AUTHORIZATION SA");
+        stmnt.execute("DROP TABLE SA.T IF EXISTS;");
+        stmnt.execute(
+            "CREATE TABLE SA.T (I IDENTITY, A CHAR(10), B CHAR(10));");
+        stmnt.execute("INSERT INTO SA.T VALUES ((0, 'A', 'a'),"
+                      + "(1, 'B', 'b'), (4, 'C', 'c'));");
+
+        // create table S and insert some preliminary data
+        stmnt.execute("DROP TABLE SA.S IF EXISTS;");
+        stmnt.execute(
+            "CREATE TABLE SA.S (I IDENTITY, A CHAR(10), B CHAR(10), C CHAR(10));");
+        stmnt.execute(
+            "INSERT INTO SA.S VALUES ((0, 'D', 'd', 'Dd'),"
+            + "(2, 'E', 'e', 'Ee'), (3, 'F', 'f', 'Ff'), (4, 'G', 'g', 'Gg'));");
+        printTable("SA.T", "*", 3);
+        printTable("SA.S", "*", 4);
+        stmnt.execute(merge);
+    }
+
+    public void testMerge1() {
+
+        try {
+
+            // merge statement with table aliases, using both match statements
+            executeMerge(
+                "MERGE INTO SA.T X " +
+                "USING SA.S AS Y " +
+                "ON X.I = Y.I " +
+                "WHEN MATCHED THEN " +
+                    "UPDATE SET X.A = Y.A, X.B = 'UPDATED' " +
+                "WHEN NOT MATCHED THEN " +
+                    "INSERT (I, A, B) VALUES (Y.I, Y.A, 'INSERTED');"
+            );
+
+            // table t should now have 5 rows, first and fifth with A/B updated
+            // to values A/C from S, second should be the same, and third and
+            // fourth should be the inserted rows that didn't exist before.
+            printTable("SA.T", "*", 5);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge1 complete\n");
+    }
+
+    public void testMerge2() {
+
+        try {
+
+            // merge statement with only update statement
+            executeMerge(
+                "MERGE INTO SA.T " +
+                "USING SA.S " +
+                "ON T.I = S.I " +
+                "WHEN MATCHED THEN " +
+                    "UPDATE SET T.A = S.A, T.B = 'UPDATED';"
+            );
+
+            // two rows should be updated, nothing inserted
+            printTable("SA.T", "*", 3);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge2 complete\n");
+    }
+
+    public void testMerge3() {
+
+        try {
+
+            // merge statement with only insert statement, without
+            // specifying insert columns
+            executeMerge(
+                "MERGE INTO SA.T " +
+                "USING SA.S " +
+                "ON T.I = S.I " +
+                "WHEN NOT MATCHED THEN " +
+                    "INSERT VALUES (S.I, S.A, 'INSERTED');"
+            );
+
+            // two rows should be updated, nothing inserted
+            printTable("SA.T", "*", 5);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge3 complete\n");
+    }
+
+    public void testMerge4() {
+
+        try {
+
+            // merge statement with both update and insert, without
+            // specifying insert columns
+            executeMerge(
+                "MERGE INTO SA.T " +
+                "USING SA.S " +
+                "ON T.I = S.I " +
+                "WHEN MATCHED THEN " +
+                    "UPDATE SET T.A = S.A, T.B = 'UPDATED' " +
+                "WHEN NOT MATCHED THEN " +
+                    "INSERT VALUES (S.I, S.A, 'INSERTED');"
+            );
+
+            // two rows should be updated, two rows inserted
+            printTable("SA.T", "*", 5);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge4 complete\n");
+    }
+
+    public void testMerge5() {
+
+        try {
+
+            // merge statement with select statement as source table, using all
+            // columns from S
+            executeMerge(
+                "MERGE INTO SA.T " +
+                "USING (SELECT * FROM SA.S) AS X " +
+                "ON T.I = X.I " +
+                "WHEN MATCHED THEN " +
+                    "UPDATE SET T.A = X.A, T.B = 'UPDATED' " +
+                "WHEN NOT MATCHED THEN " +
+                    "INSERT VALUES (X.I, X.A, 'INSERTED');"
+            );
+
+            // two rows should be updated, two rows inserted
+            printTable("SA.T", "*", 5);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge5 complete\n");
+    }
+
+    public void testMerge6() {
+
+        try {
+
+            // merge statement with select statement as source table, specifying
+            // select columns from S
+            executeMerge(
+                "MERGE INTO SA.T " +
+                "USING (SELECT I, A, C FROM SA.S) AS X " +
+                "ON T.I = X.I " +
+                "WHEN MATCHED THEN " +
+                    "UPDATE SET T.A = X.A, T.B = 'UPDATED' " +
+                "WHEN NOT MATCHED THEN " +
+                    "INSERT VALUES (X.I, X.A, 'INSERTED');"
+            );
+
+            // two rows should be updated, two rows inserted
+            printTable("SA.T", "*", 5);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge6 complete\n");
+    }
+
+    public void testMerge7() {
+
+        try {
+
+            // merge statement with select statement as source table, with WHERE
+            // condition that matches a row in T
+            executeMerge(
+                "MERGE INTO SA.T " +
+                "USING (SELECT * FROM SA.S WHERE I = 4) AS X " +
+                "ON T.I = X.I " +
+                "WHEN MATCHED THEN " +
+                    "UPDATE SET T.A = X.A, T.B = 'UPDATED' " +
+                "WHEN NOT MATCHED THEN " +
+                    "INSERT VALUES (X.I, X.A, 'INSERTED');"
+            );
+
+            // 1 row should be updated
+            printTable("SA.T", "*", 3);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge7 complete\n");
+    }
+
+    public void testMerge8() {
+
+        try {
+
+            // merge statement with select statement as source table, with WHERE
+            // condition that does not match a row in T
+            executeMerge(
+                "MERGE INTO SA.T " +
+                "USING (SELECT * FROM SA.S WHERE I = 3) AS X " +
+                "ON T.I = X.I " +
+                "WHEN MATCHED THEN " +
+                    "UPDATE SET T.A = X.A, T.B = 'UPDATED' " +
+                "WHEN NOT MATCHED THEN " +
+                    "INSERT VALUES (X.I, X.A, 'INSERTED');"
+            );
+
+            // 1 row should be inserted
+            printTable("SA.T", "*", 4);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge8 complete\n");
+    }
+
+    public void testMerge9() {
+
+        try {
+
+            // merge statement with select statement as source table, with WHERE
+            // condition that does and does not not match a row in T
+            executeMerge(
+                "MERGE INTO SA.T " +
+                "USING (SELECT * FROM SA.S WHERE I > 2) AS X " +
+                "ON T.I = X.I " +
+                "WHEN MATCHED THEN " +
+                    "UPDATE SET T.A = X.A, T.B = 'UPDATED' " +
+                "WHEN NOT MATCHED THEN " +
+                    "INSERT VALUES (X.I, X.A, 'INSERTED');"
+            );
+
+            // 1 row should be inserted, 1 row updated
+            printTable("SA.T", "*", 4);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge9 complete\n");
+    }
+
+    public void testMerge10() {
+
+        try {
+
+            // merge statement with values as source table, with WHERE
+            // condition that does not not match a row in T
+            executeMerge("MERGE INTO SA.T "
+                         + "USING (VALUES(10, 'testA', 'testB')) AS X (I, A, B) "
+                         + "ON T.I = X.I " + "WHEN MATCHED THEN "
+                         + "UPDATE SET T.A = X.A, T.B = 'UPDATED' "
+                         + "WHEN NOT MATCHED THEN "
+                         + "INSERT VALUES (X.I, X.A, 'INSERTED');");
+
+            // 1 row should be inserted
+            printTable("SA.T", "*", 4);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge10 complete\n");
+    }
+
+    public void testMerge11() {
+
+        try {
+            executeMerge("SET SCHEMA PUBLIC");
+
+            PreparedStatement ps = connection.prepareStatement(
+        "MERGE INTO SA.T "
+                         + "USING (VALUES(CAST(? AS INT), 'testA', 'testB')) AS X (I, A, B) "
+                         + "ON T.I = X.I " + "WHEN MATCHED THEN "
+                         + "UPDATE SET T.A = X.A, T.B = 'UPDATED' "
+                         + "WHEN NOT MATCHED THEN "
+                         + "INSERT VALUES (X.I, X.A, 'INSERTED');");
+
+            ps.setInt(1, 10);
+            ps.executeUpdate();
+
+            // 1 row should be inserted
+            printTable("SA.T", "*", 4);
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMerge10 complete\n");
+    }
+    protected void tearDown() {
+
+        try {
+            stmnt.execute("DROP SCHEMA SA IF EXISTS CASCADE;");
+            connection.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("TestSql.tearDown() error: " + e.getMessage());
+        }
+
+        super.tearDown();
+    }
+
+    public static void main(String[] argv) {
+
+        TestResult result = new TestResult();
+        TestCase   testA  = new TestMerge("testMerge1");
+        TestCase   testB  = new TestMerge("testMerge2");
+        TestCase   testC  = new TestMerge("testMerge3");
+        TestCase   testD  = new TestMerge("testMerge4");
+        TestCase   testE  = new TestMerge("testMerge5");
+        TestCase   testF  = new TestMerge("testMerge6");
+        TestCase   testG  = new TestMerge("testMerge7");
+        TestCase   testH  = new TestMerge("testMerge8");
+        TestCase   testI  = new TestMerge("testMerge9");
+
+        testA.run(result);
+        testB.run(result);
+        testC.run(result);
+        testD.run(result);
+        testE.run(result);
+        testF.run(result);
+        testG.run(result);
+        testH.run(result);
+        testI.run(result);
+        System.out.println("TestMerge error count: " + result.failureCount());
+
+        Enumeration e = result.failures();
+
+        while (e.hasMoreElements()) {
+            System.out.println(e.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestMultiInsert.java b/src/org/hsqldb/test/TestMultiInsert.java
new file mode 100644
index 0000000..b517cbe
--- /dev/null
+++ b/src/org/hsqldb/test/TestMultiInsert.java
@@ -0,0 +1,160 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Enumeration;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * Test multiple row insert statements via jdbc against in-memory database
+ * @author Justin Spadea
+ */
+public class TestMultiInsert extends TestBase {
+
+    Statement         stmnt;
+    PreparedStatement pstmnt;
+    Connection        connection;
+
+    public TestMultiInsert(String name) {
+        super(name);
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            connection = super.newConnection();
+            stmnt      = connection.createStatement();
+        } catch (Exception e) {}
+    }
+
+    private void printTable(String table, String cols, int expected) throws SQLException {
+        int rows = 0;
+        ResultSet rs = stmnt.executeQuery("SELECT " + cols + " FROM " + table);
+
+        ResultSetMetaData rsmd = rs.getMetaData();
+        String result = "Table " + table + ", expecting "
+            + expected + " rows total:\n";
+
+        while (rs.next()) {
+            for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                result += rsmd.getColumnLabel(i + 1) + ":"
+                           + rs.getString(i + 1) + ":";
+            }
+            result += "\n";
+            rows++;
+        }
+        rs.close();
+        System.out.println(result);
+        assertEquals(expected, rows);
+    }
+
+    public void testMultiInsert() {
+
+        try {
+
+            // create table T and insert two rows simultaneously
+            stmnt.execute("DROP TABLE T IF EXISTS;");
+            stmnt.execute(
+                "CREATE TABLE T (I IDENTITY, A CHAR(10), B CHAR(10));");
+            stmnt.execute(
+                "INSERT INTO T VALUES (NULL, 'A', 'a'),(NULL, 'B', 'b');");
+
+            // print table out - should have two rows
+            printTable("T", "*", 2);
+
+            // 3 inserts - a normal standard syntax, multi-row syntax for
+            //             single row, and multi-row syntax for two rows
+            stmnt.execute("INSERT INTO T VALUES(NULL,'single1','s1');");
+            stmnt.execute("INSERT INTO T VALUES((NULL,'single2','s2'));");
+            stmnt.execute(
+                "INSERT INTO T VALUES((NULL,'double1','d1'),(NULL,'double2','d2'));");
+
+            // print table out - should have 6 rows
+            printTable("T", "*", 6);
+
+            // insert via a prepared statement - both single and multi rows
+            pstmnt = connection.prepareStatement("INSERT INTO T VALUES (?,?,?)");
+            pstmnt.setString(1, null);
+            pstmnt.setString(2, "prepared1");
+            pstmnt.setString(3, "test1");
+            pstmnt.executeUpdate();
+            pstmnt = connection.prepareStatement("INSERT INTO T VALUES (?,?,?),(null,?,?)");
+            pstmnt.setString(1, null);
+            pstmnt.setString(2, "prepared2");
+            pstmnt.setString(3, "test2");
+            pstmnt.setString(4, "prepared3");
+            pstmnt.setString(5, "test3");
+            pstmnt.executeUpdate();
+
+            // print table out - should have 9 rows
+            printTable("T", "*", 9);
+
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMultiInsert complete");
+
+    }
+
+    protected void tearDown() {
+
+        try {
+            connection.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("TestSql.tearDown() error: " + e.getMessage());
+        }
+        super.tearDown();
+    }
+
+    public static void main(String[] argv) {
+
+        TestResult result = new TestResult();
+        TestCase   testA  = new TestMultiInsert("testMultiInsert");
+
+        testA.run(result);
+        System.out.println("TestMultiInsert error count: " + result.failureCount());
+        Enumeration e = result.failures();
+        while(e.hasMoreElements()) System.out.println(e.nextElement());
+    }
+}
diff --git a/src/org/hsqldb/test/TestMultipleConnections.java b/src/org/hsqldb/test/TestMultipleConnections.java
new file mode 100644
index 0000000..a901950
--- /dev/null
+++ b/src/org/hsqldb/test/TestMultipleConnections.java
@@ -0,0 +1,101 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+public class TestMultipleConnections {
+
+    public TestMultipleConnections() {}
+
+    public static void main(String[] args) throws Exception {
+
+        // test for bug itme 500105 commit does not work with multiple con. FIXED
+        TestMultipleConnections hs   = new TestMultipleConnections();
+        Connection              con1 = hs.createObject();
+        Connection              con2 = hs.createObject();
+        Connection              con3 = hs.createObject();
+
+        con1.setAutoCommit(false);
+
+        //connection1.commit();
+        con2.setAutoCommit(false);
+
+        //connection1.commit();
+        con3.setAutoCommit(false);
+
+        //connection1.commit();
+        Statement st = con3.createStatement();
+
+        st.execute("DROP TABLE T IF EXISTS");
+        st.execute("CREATE TABLE T (I INT)");
+        st.execute("INSERT INTO T VALUES (2)");
+
+        ResultSet rs = st.executeQuery("SELECT * FROM T");
+
+        rs.next();
+
+        int value = rs.getInt(1);
+
+        con2.commit();
+        con3.commit();
+        con1.commit();
+
+        rs = st.executeQuery("SELECT * FROM T");
+
+        rs.next();
+
+        if (value != rs.getInt(1)) {
+            throw new Exception("value doesn't exist");
+        }
+    }
+
+    /**
+     * create a connection and wait
+     */
+    protected Connection createObject() {
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            return DriverManager.getConnection("jdbc:hsqldb:/hsql/test/test",
+                                               "sa", "");
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+
+        return null;
+    }
+}
diff --git a/src/org/hsqldb/test/TestNitin.java b/src/org/hsqldb/test/TestNitin.java
new file mode 100644
index 0000000..60ea2fb
--- /dev/null
+++ b/src/org/hsqldb/test/TestNitin.java
@@ -0,0 +1,92 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+/**
+ * DB Out of memory test
+ * cached tables in non-nio mode
+ * @author Nitin Chauhan
+ */
+public class TestNitin {
+
+    public static void main(String[] args) {
+
+        java.sql.Connection    c  = null;
+        java.sql.Statement     s  = null;
+        java.io.BufferedReader br = null;
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            c = java.sql.DriverManager.getConnection(
+                "jdbc:hsqldb:c:/ft/hsqldb_w_1_8_0/oom/my.db", "SA", "");
+            s = c.createStatement();
+            br = new java.io.BufferedReader(
+                new java.io.FileReader("c:/ft/hsqldb_w_1_8_0//oom//my.sql"));
+
+            String line;
+            int    lineNo = 0;
+
+            while ((line = br.readLine()) != null) {
+                if (line.length() > 0 && line.charAt(0) != '#') {
+                    s.execute(line);
+
+                    if (lineNo++ % 100 == 0) {
+                        System.out.println(lineNo);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (br != null) {
+                    br.close();
+                }
+            } catch (java.io.IOException ioe) {}
+
+            try {
+                if (s != null) {
+                    s.close();
+                }
+            } catch (java.sql.SQLException se) {}
+
+            try {
+                if (c != null) {
+                    c.close();
+                }
+            } catch (java.sql.SQLException se) {}
+        }
+
+        System.exit(0);
+    }
+}
diff --git a/src/org/hsqldb/test/TestNullInUnion.java b/src/org/hsqldb/test/TestNullInUnion.java
new file mode 100644
index 0000000..bbae7c7
--- /dev/null
+++ b/src/org/hsqldb/test/TestNullInUnion.java
@@ -0,0 +1,84 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+
+public class TestNullInUnion extends TestCase {
+
+    public void testUnionSubquery() throws Exception {
+
+        Class.forName("org.hsqldb.jdbcDriver").newInstance();
+
+        Connection con = DriverManager.getConnection("jdbc:hsqldb:mem:test",
+            "sa", "");
+        Statement st = con.createStatement();
+
+        st.execute(
+            "CREATE TABLE t1 (id int not null, v1 int, v2 int, primary key(id))");
+        st.execute(
+            "CREATE TABLE t2 (id int not null, v1 int, v3 int, primary key(id))");
+        st.execute("INSERT INTO t1 values(1,1,1)");
+        st.execute("INSERT INTO t1 values(2,2,2)");
+        st.execute("INSERT INTO t2 values(1,3,3)");
+
+        ResultSet rs = st.executeQuery(
+            "select t as atable, a as idvalue, b as value1, c as value2, d as value3 from("
+            + "(select 't1' as t, t1.id as a, t1.v1 as b, t1.v2 as c, null as d from t1) union"
+            + "(select 't2' as t, t2.id as a, t2.v1 as b, null as c, t2.v3 as d from t2)) order by atable, idvalue");
+
+        assertTrue(rs.next());
+        assertEquals("t1", rs.getObject("atable"));
+        assertEquals(1, rs.getInt("idvalue"));
+        assertEquals(1, rs.getInt("value1"));
+        assertEquals(1, rs.getInt("value2"));
+        assertEquals(null, rs.getObject("value3"));
+        assertTrue(rs.next());
+        assertEquals("t1", rs.getObject("atable"));
+        assertEquals(2, rs.getInt("idvalue"));
+        assertEquals(2, rs.getInt("value1"));
+        assertEquals(2, rs.getInt("value2"));
+        assertEquals(null, rs.getObject("value3"));
+        assertTrue(rs.next());
+        assertEquals("t2", rs.getObject("atable"));
+        assertEquals(1, rs.getInt("idvalue"));
+        assertEquals(3, rs.getInt("value1"));
+        assertEquals(null, rs.getObject("value2"));
+        assertEquals(3, rs.getInt("value3"));    //this fails!
+        assertFalse(rs.next());
+    }
+}
diff --git a/src/org/hsqldb/test/TestObjectSize.java b/src/org/hsqldb/test/TestObjectSize.java
new file mode 100644
index 0000000..fcc4e56
--- /dev/null
+++ b/src/org/hsqldb/test/TestObjectSize.java
@@ -0,0 +1,76 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Timestamp;
+
+import org.hsqldb.lib.StopWatch;
+
+public class TestObjectSize {
+
+    public TestObjectSize() {
+
+        StopWatch sw        = new StopWatch();
+        int       testCount = 2350000;
+
+        System.out.println("Fill Memory with Objects ");
+
+        Object[] objectArray = new Object[testCount];
+
+        for (int j = 0; j < objectArray.length; j++) {
+            objectArray[j] = new Timestamp(0);
+        }
+
+        System.out.println("Array Filled " + sw.elapsedTime());
+
+        for (int j = 0; j < objectArray.length; j++) {
+            objectArray[j] = null;
+        }
+
+        Object[] objectArray2 = new Object[testCount];
+        Object[] objectArray3 = new Object[testCount];
+        Object[] objectArray4 = new Object[testCount];
+        Object[] objectArray5 = new Object[testCount];
+        Object[] objectArray6 = new Object[testCount];
+
+//        Object[] objectArray7 = new Object[testCount];
+        short[] shortArray = new short[testCount];
+        byte[]  byteArray  = new byte[testCount];
+
+        System.out.println("Fill with Empty Arrays " + sw.elapsedTime());
+        sw.zero();
+    }
+
+    public static void main(String[] argv) {
+        TestObjectSize ls = new TestObjectSize();
+    }
+}
diff --git a/src/org/hsqldb/test/TestOdbcService.java b/src/org/hsqldb/test/TestOdbcService.java
new file mode 100644
index 0000000..5238eff
--- /dev/null
+++ b/src/org/hsqldb/test/TestOdbcService.java
@@ -0,0 +1,396 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Statement;
+
+/**
+ * See AbstractTestOdbc for more general ODBC test information.
+ *
+ * Standard test methods perform the named test, then perform a simple
+ * (non-prepared) query to verify the state of the server is healthy enough
+ * to successfully serve a query.
+ * (We may or many not add test(s) to verify behavior when no static query
+ * follows).
+ *
+ * @see AbstractTestOdbc
+ */
+public class TestOdbcService extends AbstractTestOdbc {
+
+    public TestOdbcService() {}
+
+    /**
+     * Accommodate JUnit's test-runner conventions.
+     */
+    public TestOdbcService(String s) {
+        super(s);
+    }
+
+    public void testSanity() {
+        try {
+            ResultSet rs = netConn.createStatement().executeQuery(
+                "SELECT count(*) FROM nullmix");
+            if (!rs.next()) {
+                throw new RuntimeException("The most basic query failed.  "
+                    + "No row count from 'nullmix'.");
+            }
+            assertEquals("Sanity check failed.  Rowcount of 'nullmix'", 6,
+                rs.getInt(1));
+            rs.close();
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(
+                "The most basic query failed");
+            ase.initCause(se);
+            throw ase;
+        }
+    }
+
+    /**
+     * Tests with input and output parameters, and rerunning query with
+     * modified input parameters.
+     */
+    public void testFullyPreparedQuery() {
+        try {
+            ResultSet rs;
+            PreparedStatement ps = netConn.prepareStatement(
+                "SELECT i, 3, vc, 'str' FROM nullmix WHERE i < ? OR i > ? "
+                + "ORDER BY i");
+            ps.setInt(1, 10);
+            ps.setInt(2, 30);
+            rs = ps.executeQuery();
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(5, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("five", rs.getString(3));
+
+            assertTrue("Not enough rows fetched", rs.next());
+            assertEquals(3, rs.getInt(2));
+            assertEquals(40, rs.getInt(1));
+            assertEquals("forty", rs.getString(3));
+            assertEquals("str", rs.getString(4));
+
+            assertFalse("Too many rows fetched", rs.next());
+            rs.close();
+
+            ps.setInt(1, 16);
+            ps.setInt(2, 100);
+            rs = ps.executeQuery();
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(5, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("five", rs.getString(3));
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(10, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("ten", rs.getString(3));
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(15, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("fifteen", rs.getString(3));
+
+            assertFalse("Too many rows fetched", rs.next());
+            rs.close();
+
+            verifySimpleQueryOutput(); // Verify server state still good
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        }
+    }
+
+    public void testDetailedSimpleQueryOutput() {
+        try {
+            verifySimpleQueryOutput();
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        }
+    }
+
+    /**
+     * Assumes none of the records above i=20 have been modified.
+     */
+    public void verifySimpleQueryOutput() throws SQLException {
+        ResultSet rs = netConn.createStatement().executeQuery(
+            "SELECT i, 3, vc, 'str' FROM nullmix WHERE i > 20 ORDER BY i");
+        assertTrue("No rows fetched", rs.next());
+        assertEquals("str", rs.getString(4));
+        assertEquals(21, rs.getInt(1));
+        assertEquals(3, rs.getInt(2));
+        assertEquals("twenty one", rs.getString(3));
+
+        assertTrue("Not enough rows fetched", rs.next());
+        assertEquals(3, rs.getInt(2));
+        assertEquals(25, rs.getInt(1));
+        assertNull(rs.getString(3));
+        assertEquals("str", rs.getString(4));
+
+        assertTrue("Not enough rows fetched", rs.next());
+        assertEquals("str", rs.getString(4));
+        assertEquals(3, rs.getInt(2));
+        assertEquals(40, rs.getInt(1));
+        assertEquals("forty", rs.getString(3));
+
+        assertFalse("Too many rows fetched", rs.next());
+        rs.close();
+    }
+
+    public void testPreparedNonRowStatement() {
+        try {
+            PreparedStatement ps = netConn.prepareStatement(
+                    "UPDATE nullmix set xtra = ? WHERE i < ?");
+            ps.setString(1, "first");
+            ps.setInt(2, 25);
+            assertEquals("First update failed", 4, ps.executeUpdate());
+
+            ps.setString(1, "second");
+            ps.setInt(2, 15);
+            assertEquals("Second update failed", 2, ps.executeUpdate());
+            ps.close();
+
+
+            ResultSet rs = netConn.createStatement().executeQuery(
+                "SELECT i, 3, vc, xtra FROM nullmix ORDER BY i");
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("second", rs.getString(4));
+            assertEquals(5, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("five", rs.getString(3));
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("second", rs.getString(4));
+            assertEquals(10, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("ten", rs.getString(3));
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("first", rs.getString(4));
+            assertEquals(15, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("fifteen", rs.getString(3));
+
+            assertTrue("Not enough rows fetched", rs.next());
+            assertEquals(3, rs.getInt(2));
+            assertEquals(21, rs.getInt(1));
+            assertEquals("twenty one", rs.getString(3));
+            assertEquals("first", rs.getString(4));
+
+            assertTrue("Not enough rows fetched", rs.next());
+            assertEquals(3, rs.getInt(2));
+            assertEquals(25, rs.getInt(1));
+            assertNull(rs.getString(3));
+            assertNull(rs.getString(4));
+
+            assertTrue("Not enough rows fetched", rs.next());
+            assertEquals(3, rs.getInt(2));
+            assertEquals(40, rs.getInt(1));
+            assertEquals("forty", rs.getString(3));
+            assertNull(rs.getString(4));
+
+            assertFalse("Too many rows fetched", rs.next());
+            rs.close();
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        }
+    }
+
+    public void testParamlessPreparedQuery() {
+        try {
+            ResultSet rs;
+            PreparedStatement ps = netConn.prepareStatement(
+                "SELECT i, 3, vc, 'str' FROM nullmix WHERE i != 21 "
+                + "ORDER BY i");
+            rs = ps.executeQuery();
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(5, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("five", rs.getString(3));
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(10, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("ten", rs.getString(3));
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(15, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("fifteen", rs.getString(3));
+
+            assertTrue("Not enough rows fetched", rs.next());
+            assertEquals(3, rs.getInt(2));
+            assertEquals(25, rs.getInt(1));
+            assertNull(rs.getString(3));
+            assertEquals("str", rs.getString(4));
+
+            assertTrue("Not enough rows fetched", rs.next());
+            assertEquals(3, rs.getInt(2));
+            assertEquals(40, rs.getInt(1));
+            assertEquals("forty", rs.getString(3));
+            assertEquals("str", rs.getString(4));
+
+            assertFalse("Too many rows fetched", rs.next());
+            rs.close();
+
+            rs = ps.executeQuery();
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(5, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("five", rs.getString(3));
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(10, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("ten", rs.getString(3));
+
+            assertTrue("No rows fetched", rs.next());
+            assertEquals("str", rs.getString(4));
+            assertEquals(15, rs.getInt(1));
+            assertEquals(3, rs.getInt(2));
+            assertEquals("fifteen", rs.getString(3));
+
+            assertTrue("Not enough rows fetched", rs.next());
+            assertEquals(3, rs.getInt(2));
+            assertEquals(25, rs.getInt(1));
+            assertNull(rs.getString(3));
+            assertEquals("str", rs.getString(4));
+
+            assertTrue("Not enough rows fetched", rs.next());
+            assertEquals(3, rs.getInt(2));
+            assertEquals(40, rs.getInt(1));
+            assertEquals("forty", rs.getString(3));
+            assertEquals("str", rs.getString(4));
+
+            assertFalse("Too many rows fetched", rs.next());
+            rs.close();
+
+            verifySimpleQueryOutput(); // Verify server state still good
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        }
+    }
+
+    public void testSimpleUpdate() {
+        try {
+            Statement st = netConn.createStatement();
+            assertEquals(2, st.executeUpdate(
+                    "UPDATE nullmix SET xtra = 'updated' WHERE i < 12"));
+            ResultSet rs = netConn.createStatement().executeQuery(
+                "SELECT * FROM nullmix WHERE xtra = 'updated'");
+            assertTrue("No rows updated", rs.next());
+            assertTrue("Only one row updated", rs.next());
+            assertFalse("Too many rows updated", rs.next());
+            rs.close();
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        }
+    }
+
+    public void testTranSanity() {
+        enableAutoCommit();
+        testSanity();
+    }
+    public void testTranFullyPreparedQuery() {
+        enableAutoCommit();
+        testFullyPreparedQuery();
+    }
+    public void testTranDetailedSimpleQueryOutput() {
+        enableAutoCommit();
+        testDetailedSimpleQueryOutput();
+    }
+    public void testTranPreparedNonRowStatement() {
+        enableAutoCommit();
+        testPreparedNonRowStatement();
+    }
+    public void testTranParamlessPreparedQuery() {
+        enableAutoCommit();
+        testParamlessPreparedQuery();
+    }
+    public void testTranSimpleUpdate() {
+        enableAutoCommit();
+        testSimpleUpdate();
+    }
+
+    protected void populate(Statement st) throws SQLException {
+        st.executeUpdate("DROP TABLE nullmix IF EXISTS");
+        st.executeUpdate("CREATE TABLE nullmix "
+                + "(i INT NOT NULL, vc VARCHAR(20), xtra VARCHAR(20))");
+
+        // Would be more elegant and efficient to use a prepared statement
+        // here, but our we want this setup to be as simple as possible, and
+        // leave feature testing for the actual unit tests.
+        st.executeUpdate("INSERT INTO nullmix (i, vc) values(10, 'ten')");
+        st.executeUpdate("INSERT INTO nullmix (i, vc) values(5, 'five')");
+        st.executeUpdate("INSERT INTO nullmix (i, vc) values(15, 'fifteen')");
+        st.executeUpdate(
+                "INSERT INTO nullmix (i, vc) values(21, 'twenty one')");
+        st.executeUpdate("INSERT INTO nullmix (i, vc) values(40, 'forty')");
+        st.executeUpdate("INSERT INTO nullmix (i) values(25)");
+    }
+
+    static public void main(String[] sa) {
+        staticRunner(TestOdbcService.class, sa);
+    }
+}
diff --git a/src/org/hsqldb/test/TestOdbcTypes.java b/src/org/hsqldb/test/TestOdbcTypes.java
new file mode 100644
index 0000000..70bfca1
--- /dev/null
+++ b/src/org/hsqldb/test/TestOdbcTypes.java
@@ -0,0 +1,1721 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.math.BigDecimal;
+
+/**
+ * See AbstractTestOdbc for more general ODBC test information.
+ *
+ * @see AbstractTestOdbc
+ */
+public class TestOdbcTypes extends AbstractTestOdbc {
+    /* HyperSQL types to be tested:
+     *
+     * Exact Numeric
+     *     TINYINT
+     *     SMALLINT
+     *     INTEGER
+     *     BIGINT
+     *     NUMERIC(p?,s?) = DECIMAL()   (default for decimal literals)
+     * Approximate Numeric
+     *     FLOAT(p?)
+     *     DOUBLE = REAL (default for literals with exponent)
+     * BOOLEAN
+     * Character Strings
+     *     CHARACTER(1l)* = CHAR()
+     *     CHARACTER VARYING(1l) = VARCHAR() = LONGVARCHAR()
+     *     CLOB(1l) = CHARACTER LARGE OBJECT(1)
+     * Binary Strings
+     *     BINARY(1l)*
+     *     BINARY VARYING(1l) = VARBINARY()
+     *     BLOB(1l) = BINARY LARGE OBJECT()
+     * Bits
+     *     BIT(1l)
+     *     BIT VARYING(1l)
+     * OTHER  (for holding serialized Java objects)
+     * Date/Times
+     *     DATE
+     *     TIME(p?,p?)
+     *     TIMESTAMP(p?,p?)
+     *     INTERVAL...(p2,p0)
+     */
+
+    public TestOdbcTypes() {}
+
+    /**
+     * Accommodate JUnit's test-runner conventions.
+     */
+    public TestOdbcTypes(String s) {
+        super(s);
+    }
+
+    protected void populate(Statement st) throws SQLException {
+        st.executeUpdate("DROP TABLE alltypes IF EXISTS");
+        st.executeUpdate("CREATE TABLE alltypes (\n"
+            + "    id INTEGER,\n"
+            + "    ti TINYINT,\n"
+            + "    si SMALLINT,\n"
+            + "    i INTEGER,\n"
+            + "    bi BIGINT,\n"
+            + "    n NUMERIC(5,2),\n"
+            + "    f FLOAT(5),\n"
+            + "    r DOUBLE,\n"
+            + "    b BOOLEAN,\n"
+            + "    c CHARACTER(3),\n"
+            + "    cv CHARACTER VARYING(3),\n"
+            + "    bt BIT(9),\n"
+            + "    btv BIT VARYING(3),\n"
+            + "    d DATE,\n"
+            + "    t TIME(2),\n"
+            + "    tw TIME(2) WITH TIME ZONE,\n"
+            + "    ts TIMESTAMP(2),\n"
+            + "    tsw TIMESTAMP(2) WITH TIME ZONE,\n"
+            + "    bin BINARY(4),\n"
+            + "    vb VARBINARY(4),\n"
+            + "    dsival INTERVAL DAY(5) TO SECOND(6),\n"
+            + "    sival INTERVAL SECOND(6,4)\n"
+           + ')');
+        /** TODO:  This test class can't handle testing unlmited VARCHAR, since
+         * we set up with strict size setting, which prohibits unlimited
+         * VARCHARs.  Need to write a standalone test class to test that.
+         */
+
+        // Would be more elegant and efficient to use a prepared statement
+        // here, but our we want this setup to be as simple as possible, and
+        // leave feature testing for the actual unit tests.
+        st.executeUpdate("INSERT INTO alltypes VALUES (\n"
+            + "    1, 3, 4, 5, 6, 7.8, 8.9, 9.7, true, 'ab', 'cd',\n"
+            + "    b'10', b'10', current_date, '13:14:00',\n"
+            + "    '15:16:00', '2009-02-09 16:17:18', '2009-02-09 17:18:19',\n"
+            + "    x'A103', x'A103', "
+            + "INTERVAL '145 23:12:19.345' DAY TO SECOND,\n"
+            + "    INTERVAL '1000.345' SECOND\n"
+            + ')'
+        );
+        st.executeUpdate("INSERT INTO alltypes VALUES (\n"
+            + "    2, 3, 4, 5, 6, 7.8, 8.9, 9.7, true, 'ab', 'cd',\n"
+            + "    b'10', b'10', current_date, '13:14:00',\n"
+            + "    '15:16:00', '2009-02-09 16:17:18', '2009-02-09 17:18:19',\n"
+            + "    x'A103', x'A103', "
+            + "    INTERVAL '145 23:12:19.345' DAY TO SECOND,\n"
+            + "    INTERVAL '1000.345' SECOND\n"
+            + ')'
+        );
+    }
+
+    public void testIntegerSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Integer.class, rs.getObject("i").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(5, rs.getInt("i"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testTinyIntSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Integer.class, rs.getObject("ti").getClass());
+            // Nb. HyperSQL purposefully returns an Integer for this type
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals((byte) 3, rs.getByte("ti"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testSmallIntSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Integer.class, rs.getObject("si").getClass());
+            // Nb. HyperSQL purposefully returns an Integer for this type
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals((short) 4, rs.getShort("si"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testBigIntSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Long.class, rs.getObject("bi").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(6, rs.getLong("bi"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    /*
+    public void testNumericSimpleRead() {
+        // This is failing.
+        // Looks like we inherited a real bug with numerics from psqlodbc,
+        // because the problem exists with Postresql-supplied psqlodbc
+        // connecting to a Postgresql server.
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(BigDecimal.class, rs.getObject("n").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(new BigDecimal(7.8), rs.getBigDecimal("n"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+    */
+
+    public void testFloatSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Double.class, rs.getObject("f").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(8.9D, rs.getDouble("f"), 0D);
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testDoubleSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Double.class, rs.getObject("r").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(9.7D, rs.getDouble("r"), 0D);
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testBooleanSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Boolean.class, rs.getObject("b").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertTrue(rs.getBoolean("b"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testCharSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(String.class, rs.getObject("c").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals("ab ", rs.getString("c"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testVarCharSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(String.class, rs.getObject("cv").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals("cd", rs.getString("cv"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testFixedStringSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT i, 'fixed str' fs, cv\n"
+                    + "FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(String.class, rs.getObject("fs").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals("fixed str", rs.getString("fs"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testDerivedStringSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT i, cv || 'appendage' app, 4\n"
+                    + "FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(String.class, rs.getObject("app").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals("cdappendage", rs.getString("app"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testDateSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(java.sql.Date.class, rs.getObject("d").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(
+                new java.sql.Date(new java.util.Date().getTime()).toString(),
+                rs.getDate("d").toString());
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testTimeSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(java.sql.Time.class, rs.getObject("t").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(Time.valueOf("13:14:00"), rs.getTime("t"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    /*
+    public void testTimeWSimpleRead() {
+        // This test is failing because the JDBC Driver is returning a
+        // String instead of a Time oject for rs.getTime().
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(java.sql.Time.class, rs.getObject("tw").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(Time.valueOf("15:16:00"), rs.getTime("tw"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+    */
+
+    public void testTimestampSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try { st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Timestamp.class, rs.getObject("ts").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(Timestamp.valueOf("2009-02-09 16:17:18"),
+                    rs.getTimestamp("ts"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testTimestampWSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals(Timestamp.class, rs.getObject("tsw").getClass());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals(Timestamp.valueOf("2009-02-09 17:18:19"),
+                    rs.getTimestamp("tsw"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testBitSimpleRead() {
+        // This test is failing because of a BIT padding bug in the engine.
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals("100000000", rs.getString("bt"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testBitVaryingSimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            assertEquals("10", rs.getString("btv"));
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testBinarySimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        byte[] expectedBytes = new byte[] {
+            (byte) 0xa1, (byte) 0x03, (byte) 0, (byte) 0
+        };
+        byte[] ba;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals("A1030000", rs.getString("bin"));
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            ba = rs.getBytes("bin");
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) { junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+        assertEquals("Retrieved bye array length wrong",
+            expectedBytes.length, ba.length);
+        for (int i = 0; i < ba.length; i++) {
+            assertEquals("Byte " + i + " wrong", expectedBytes[i], ba[i]);
+        }
+    }
+
+    public void testVarBinarySimpleRead() {
+        ResultSet rs = null;
+        Statement st = null;
+        byte[] expectedBytes = new byte[] { (byte) 0xa1, (byte) 0x03 };
+        byte[] ba;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals("A103", rs.getString("vb"));
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            ba = rs.getBytes("vb");
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+        assertEquals("Retrieved bye array length wrong",
+            expectedBytes.length, ba.length);
+        for (int i = 0; i < ba.length; i++) {
+            assertEquals("Byte " + i + " wrong", expectedBytes[i], ba[i]);
+        }
+    }
+
+    public void testDaySecIntervalSimpleRead() {
+        /* Since our client does not support the INTERVAL precision
+         * constraints, the returned value will always be toString()'d to
+         * precision of microseconds. */
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals("145 23:12:19.345000", rs.getString("dsival"));
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            // Can't test the class, because jdbc:odbc or the driver returns
+            // a String for getObject() for interval values.
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testSecIntervalSimpleRead() {
+        /* Since our client does not support the INTERVAL precision
+         * constraints, the returned value will always be toString()'d to
+         * precision of microseconds. */
+        ResultSet rs = null;
+        Statement st = null;
+        try {
+            st = netConn.createStatement();
+            rs = st.executeQuery("SELECT * FROM alltypes WHERE id in (1, 2)");
+            assertTrue("Got no rows with id in (1, 2)", rs.next());
+            assertEquals("1000.345000", rs.getString("sival"));
+            assertTrue("Got only one row with id in (1, 2)", rs.next());
+            // Can't test the class, because jdbc:odbc or the driver returns
+            // a String for getObject() for interval values.
+            assertFalse("Got too many rows with id in (1, 2)", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (st != null) {
+                    st.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testIntegerComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, i) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setInt(2, 495);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE i = ?");
+            ps.setInt(1, 495);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with i = 495", rs.next());
+            assertEquals(Integer.class, rs.getObject("i").getClass());
+            assertTrue("Got only one row with i = 495", rs.next());
+            assertEquals(495, rs.getInt("i"));
+            assertFalse("Got too many rows with i = 495", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testTinyIntComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, ti) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setByte(2, (byte) 200);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE ti = ?");
+            ps.setByte(1, (byte) 200);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with ti = 200", rs.next());
+            assertEquals(Integer.class, rs.getObject("ti").getClass());
+            assertTrue("Got only one row with ti = 200", rs.next());
+            assertEquals((byte) 200, rs.getByte("ti"));
+            assertFalse("Got too many rows with ti = 200", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testSmallIntComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, si) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setShort(2, (short) 395);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE si = ?");
+            ps.setShort(1, (short) 395);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with si = 395", rs.next());
+            assertEquals(Integer.class, rs.getObject("si").getClass());
+            // Nb. HyperSQL purposefully returns an Integer for this type
+            assertTrue("Got only one row with si = 395", rs.next());
+            assertEquals((short) 395, rs.getShort("si"));
+            assertFalse("Got too many rows with si = 395", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testBigIntComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, bi) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setLong(2, 295L);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE bi = ?");
+            ps.setLong(1, 295L);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with bi = 295L", rs.next());
+            assertEquals(Long.class, rs.getObject("bi").getClass());
+            assertTrue("Got only one row with bi = 295L", rs.next());
+            assertEquals(295L, rs.getLong("bi"));
+            assertFalse("Got too many rows with bi = 295L", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    /* TODO:  Implement this test after get testNumericSimpleRead() working.
+     *        See that method above.
+    public void testNumericComplex() {
+    */
+
+    public void testFloatComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, f) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setFloat(2, 98.765F);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE f = ?");
+            ps.setFloat(1, 98.765F);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with f = 98.765F", rs.next());
+            assertEquals(Double.class, rs.getObject("f").getClass());
+            assertTrue("Got only one row with f = 98.765F", rs.next());
+            assertEquals(98.765D, rs.getDouble("f"), .01D);
+            assertFalse("Got too many rows with f = 98.765F", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testDoubleComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, r) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setDouble(2, 876.54D);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE r = ?");
+            ps.setDouble(1, 876.54D);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with r = 876.54D", rs.next());
+            assertEquals(Double.class, rs.getObject("r").getClass());
+            assertTrue("Got only one row with r = 876.54D", rs.next());
+            assertEquals(876.54D, rs.getDouble("r"), 0D);
+            assertFalse("Got too many rows with r = 876.54D", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testBooleanComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, b) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setBoolean(2, false);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE b = ?");
+            ps.setBoolean(1, false);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with b = false", rs.next());
+            assertEquals(Boolean.class, rs.getObject("b").getClass());
+            assertTrue("Got only one row with b = false", rs.next());
+            assertEquals(false, rs.getBoolean("b"));
+            assertFalse("Got too many rows with b = false", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testCharComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, c) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setString(2, "xy");
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE c = ?");
+            ps.setString(1, "xy ");
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with c = 'xy '", rs.next());
+            assertEquals(String.class, rs.getObject("c").getClass());
+            assertTrue("Got only one row with c = 'xy '", rs.next());
+            assertEquals("xy ", rs.getString("c"));
+            assertFalse("Got too many rows with c = 'xy '", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testVarCharComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, cv) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setString(2, "xy");
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE cv = ?");
+            ps.setString(1, "xy");
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with cv = 'xy'", rs.next());
+            assertEquals(String.class, rs.getObject("cv").getClass());
+            assertTrue("Got only one row with cv = 'xy'", rs.next());
+            assertEquals("xy", rs.getString("cv"));
+            assertFalse("Got too many rows with cv = 'xy'", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    /**
+     * TODO:  Find out if there is a way to select based on an expression
+     * using a named derived pseudo-column.
+    public void testDerivedComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "SELECT id, cv || 'app' appendage FROM alltypes\n"
+                + "WHERE appendage = ?");
+            ps.setString(1, "cvapp");
+            rs = ps.executeQuery();
+            assertTrue("Got no rows appendage = 'cvapp'", rs.next());
+            assertEquals(String.class, rs.getObject("r").getClass());
+            assertTrue("Got only one row with appendage = 'cvapp'", rs.next());
+            assertEquals("cvapp", rs.getString("r"));
+            assertFalse("Got too many rows with appendage = 'cvapp'", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+    */
+
+    public void testDateComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        java.sql.Date tomorrow =
+                new java.sql.Date(new java.util.Date().getTime()
+                        + 1000 * 60 * 60 * 24);
+
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, d) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setDate(2, tomorrow);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE d = ?");
+            ps.setDate(1, tomorrow);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with d = tomorrow", rs.next());
+            assertEquals(java.sql.Date.class, rs.getObject("d").getClass());
+            assertTrue("Got only one row with d = tomorrow", rs.next());
+            assertEquals(tomorrow.toString(), rs.getDate("d").toString());
+            // Compare the Strings since "tomorrow" has resolution to
+            // millisecond, but getDate() is probably to the day.
+            assertFalse("Got too many rows with d = tomorrow", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testTimeComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Time aTime = Time.valueOf("21:19:27");
+
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, t) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setTime(2, aTime);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE t = ?");
+            ps.setTime(1, aTime);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with t = aTime", rs.next());
+            assertEquals(Time.class, rs.getObject("t").getClass());
+            assertTrue("Got only one row with t = aTime", rs.next());
+            assertEquals(aTime, rs.getTime("t"));
+            assertFalse("Got too many rows with t = aTime", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    /* TODO:  Implement this test after get testTimeWSimpleRead() working.
+     *        See that method above.
+    public void testTimeWComplex() {
+    */
+
+    public void testTimestampComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Timestamp aTimestamp = Timestamp.valueOf("2009-03-27 17:18:19");
+
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, ts) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setTimestamp(2, aTimestamp);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE ts = ?");
+            ps.setTimestamp(1, aTimestamp);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with ts = aTimestamp", rs.next());
+            assertEquals(Timestamp.class, rs.getObject("ts").getClass());
+            assertTrue("Got only one row with ts = aTimestamp", rs.next());
+            assertEquals(aTimestamp, rs.getTimestamp("ts"));
+            assertFalse("Got too many rows with ts = aTimestamp", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testTimestampWComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Timestamp aTimestamp = Timestamp.valueOf("2009-03-27 17:18:19");
+
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, tsw) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setTimestamp(2, aTimestamp);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE tsw = ?");
+            ps.setTimestamp(1, aTimestamp);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with tsw = aTimestamp", rs.next());
+            assertEquals(Timestamp.class, rs.getObject("tsw").getClass());
+            assertTrue("Got only one row with tsw = aTimestamp", rs.next());
+            assertEquals(aTimestamp, rs.getTimestamp("tsw"));
+            assertFalse("Got too many rows with tsw = aTimestamp", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    /*
+     * Driver needs to be modified to transfer bits in byte (binary) fashion,
+     * the same as is done for VARBINARY/bytea type.
+    public void testBitComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, bt) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setString(2, "101");
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE bt = ?");
+            ps.setString(1, "101");
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with bt = 101", rs.next());
+            assertEquals(String.class, rs.getObject("bt").getClass());
+            assertTrue("Got only one row with bt = 101", rs.next());
+            assertEquals("101000000", rs.getString("bt"));
+            assertFalse("Got too many rows with bt = 101", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            } }
+    }
+
+    public void testBitVaryingComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, btv) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setString(2, "10101");
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE btv = ?");
+            ps.setString(1, "10101");
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with btv = 10101", rs.next());
+            assertEquals(String.class, rs.getObject("btv").getClass());
+            assertTrue("Got only one row with btv = 10101", rs.next());
+            assertEquals("10101", rs.getString("btv"));
+            assertFalse("Got too many rows with btv = 10101", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+    */
+
+    public void testBinaryComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        byte[] expectedBytes = new byte[] {
+            (byte) 0xaa, (byte) 0x99, (byte) 0, (byte) 0
+        };
+        byte[] ba1, ba2;
+
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, bin) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setBytes(2, expectedBytes);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE bin = ?");
+            ps.setBytes(1, expectedBytes);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with bin = b'AA99'", rs.next());
+            ba1 = rs.getBytes("bin");
+            assertTrue("Got only one row with bin = b'AA99'", rs.next());
+            ba2 = rs.getBytes("bin");
+            assertFalse("Got too many rows with bin = b'AA99'", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                } } catch(Exception e) {
+            }
+        }
+        assertEquals("Retrieved bye array length wrong (1)",
+            expectedBytes.length, ba1.length);
+        for (int i = 0; i < ba1.length; i++) {
+            assertEquals("Byte " + i + " wrong (1)", expectedBytes[i], ba1[i]);
+        }
+        assertEquals("Retrieved bye array length wrong (2)",
+            expectedBytes.length, ba2.length);
+        for (int i = 0; i < ba2.length; i++) {
+            assertEquals("Byte " + i + " wrong (2)", expectedBytes[i], ba2[i]);
+        }
+    }
+
+    public void testVarBinaryComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        byte[] expectedBytes = new byte[] { (byte) 0xaa, (byte) 0x99 };
+        byte[] ba1, ba2;
+
+        try {
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, vb) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setBytes(2, expectedBytes);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE vb = ?");
+            ps.setBytes(1, expectedBytes);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with vb = b'AA99'", rs.next());
+            ba1 = rs.getBytes("vb");
+            assertTrue("Got only one row with vb = b'AA99'", rs.next());
+            ba2 = rs.getBytes("vb");
+            assertFalse("Got too many rows with vb = b'AA99'", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                } } catch(Exception e) {
+            }
+        }
+        assertEquals("Retrieved bye array length wrong (1)",
+            expectedBytes.length, ba1.length);
+        for (int i = 0; i < ba1.length; i++) {
+            assertEquals("Byte " + i + " wrong (1)", expectedBytes[i], ba1[i]);
+        }
+        assertEquals("Retrieved bye array length wrong (2)",
+            expectedBytes.length, ba2.length);
+        for (int i = 0; i < ba2.length; i++) {
+            assertEquals("Byte " + i + " wrong (2)", expectedBytes[i], ba2[i]);
+        }
+    }
+
+    /*
+     * TODO:  Learn how to set input params for INTERVAL types.
+     *        I don't see how I could set the variant
+     *        (HOUR, ...TO SECOND, etc.) with setString() or anything else.
+    public void testDaySecIntervalComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            assertEquals("145 23:12:19.345000", rs.getString("dsival"));
+
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, dsival) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setString(2, 876.54D);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE dsival = ?");
+            ps.setString(1, 876.54D);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with dsival = 876.54D", rs.next());
+            assertEquals(String.class, rs.getObject("dsival").getClass());
+            assertTrue("Got only one row with dsival = 876.54D", rs.next());
+            assertEquals(876.54D, rs.getString("dsival"));
+            assertFalse("Got too many rows with dsival = 876.54D", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+
+    public void testSecIntervalComplex() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        try {
+            assertEquals("1000.345000", rs.getString("sival"));
+
+            ps = netConn.prepareStatement(
+                "INSERT INTO alltypes(id, sival) VALUES(?, ?)");
+            ps.setInt(1, 3);
+            ps.setString(2, 876.54D);
+            assertEquals(1, ps.executeUpdate());
+            ps.setInt(1, 4);
+            assertEquals(1, ps.executeUpdate());
+            ps.close();
+            netConn.commit();
+            ps = netConn.prepareStatement(
+                "SELECT * FROM alltypes WHERE sival = ?");
+            ps.setString(1, 876.54D);
+            rs = ps.executeQuery();
+            assertTrue("Got no rows with sival = 876.54D", rs.next());
+            assertEquals(String.class, rs.getObject("sival").getClass());
+            assertTrue("Got only one row with sival = 876.54D", rs.next());
+            assertEquals(876.54D, rs.getString("sival"));
+            assertFalse("Got too many rows with sival = 876.54D", rs.next());
+        } catch (SQLException se) {
+            junit.framework.AssertionFailedError ase
+                = new junit.framework.AssertionFailedError(se.getMessage());
+            ase.initCause(se);
+            throw ase;
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            } catch(Exception e) {
+            }
+        }
+    }
+    */
+
+    static public void main(String[] sa) {
+        staticRunner(TestOdbcTypes.class, sa);
+    }
+
+    /*
+    static protected boolean closeEnough(Time t1, Time t2, int fudgeMin) {
+        long delta = t1.getTime() - t2.getTime();
+        if (delta < 0) {
+            delta *= -1;
+        }
+        //System.err.println("Delta  " + delta);
+        //System.err.println("exp  " + (fudgeMin * 1000 * 60));
+        return delta < fudgeMin * 1000 * 60;
+    }
+    */
+}
diff --git a/src/org/hsqldb/test/TestPreparedSubQueries.java b/src/org/hsqldb/test/TestPreparedSubQueries.java
new file mode 100644
index 0000000..71d5477
--- /dev/null
+++ b/src/org/hsqldb/test/TestPreparedSubQueries.java
@@ -0,0 +1,223 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+
+/**
+ * @author kloska@users
+ */
+public class TestPreparedSubQueries extends TestCase {
+
+    private Connection con = null;
+
+    private class sqlStmt {
+
+        boolean prepare;
+        boolean update;
+        String  command;
+
+        sqlStmt(String c, boolean p, boolean u) {
+
+            prepare = p;
+            command = c;
+            update  = u;
+        }
+    }
+    ;
+
+    private sqlStmt[] stmtArray = {
+        new sqlStmt("drop table a if exists cascade", false, false),
+        new sqlStmt("create cached table a (a int identity,b int)", false,
+                    false),
+        new sqlStmt("create index bIdx on a(b)", false, false),
+        new sqlStmt("insert into a(b) values(1)", true, true),
+        new sqlStmt("insert into a(b) values(2)", true, true),
+        new sqlStmt("insert into a(b) values(3)", true, true),
+        new sqlStmt("insert into a(b) values(4)", true, true),
+        new sqlStmt("insert into a(b) values(5)", true, true),
+        new sqlStmt("insert into a(b) values(6)", true, true),
+        new sqlStmt(
+            "update a set b=100 where b>(select b from a X where X.a=2)",
+            true, true),
+        new sqlStmt("update a set b=200 where b>(select b from a where a=?)",
+                    true, true),
+        new sqlStmt(
+            "update a set b=300 where b>(select b from a X where X.a=?)",
+            true, true)
+    };
+    private Object[][] stmtArgs = {
+        {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, { new Integer(2) },
+        { new Integer(2) }
+    };
+
+    public TestPreparedSubQueries(String name) {
+        super(name);
+    }
+
+    protected void setUp() {
+
+        String url = "jdbc:hsqldb:test";
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            con = java.sql.DriverManager.getConnection(url, "sa", "");
+        } catch (Exception e) {}
+    }
+
+    public void testA() {
+
+        try {
+            int i = 0;
+
+            for (i = 0; i < stmtArray.length; i++) {
+                int j;
+
+                System.out.println(" -- #" + i + " ----------------------- ");
+
+                if (stmtArray[i].prepare) {
+                    PreparedStatement ps = null;
+
+                    System.out.println(" -- preparing\n<<<\n"
+                                       + stmtArray[i].command + "\n>>>\n");
+
+                    ps = con.prepareStatement(stmtArray[i].command);
+
+                    System.out.print(" -- setting " + stmtArgs[i].length
+                                     + " Args [");
+
+                    for (j = 0; j < stmtArgs[i].length; j++) {
+                        System.out.print((j > 0 ? "; "
+                                                : "") + stmtArgs[i][j]);
+                        ps.setObject(j + 1, stmtArgs[i][j]);
+                    }
+
+                    System.out.println("]");
+                    System.out.println(" -- executing ");
+
+                    if (stmtArray[i].update) {
+                        int r = ps.executeUpdate();
+
+                        System.out.println(" ***** ps.executeUpdate gave me "
+                                           + r);
+                    } else {
+                        boolean b = ps.execute();
+
+                        System.out.print(" ***** ps.execute gave me " + b);
+                    }
+                } else {
+                    System.out.println(" -- executing directly\n<<<\n"
+                                       + stmtArray[i].command + "\n>>>\n");
+
+                    Statement s = con.createStatement();
+                    boolean   b = s.execute(stmtArray[i].command);
+
+                    System.out.println(" ***** st.execute gave me " + b);
+                }
+            }
+        } catch (Exception e) {
+            System.out.println(" ?? Caught Exception " + e);
+            assertTrue(false);
+        }
+
+        assertTrue(true);
+    }
+
+    public void testGenerated() {
+        boolean valid = false;
+        try {
+            Statement s = con.createStatement();
+            s.execute("drop table a if exists");
+            s.execute("create cached table a (a int identity,b int)");
+            s.execute("insert into a(b) values(1)", Statement.RETURN_GENERATED_KEYS);
+            ResultSet r = s.getGeneratedKeys();
+            while(r.next()) {
+                r.getInt(1);
+                valid = true;
+            }
+            r.close();
+            assertTrue(valid);
+
+            s.execute("insert into a(b) values(2)",new int[]{1});
+            r = s.getGeneratedKeys();
+            while(r.next()) {
+                r.getInt(1);
+                valid = true;
+            }
+            assertTrue(valid);
+        } catch (Exception e) {
+            assertTrue(false);
+        }
+    }
+
+    public void testIdentity() {
+        boolean valid = false;
+        try {
+            Statement s = con.createStatement();
+            s.execute("drop table a if exists");
+            s.execute("create cached table a (a int identity, b int)");
+            PreparedStatement p1 = con.prepareStatement("insert into a(b) values ?");
+            p1.setInt(1, 10);
+            p1.executeUpdate();
+            PreparedStatement p2 = con.prepareStatement("call identity()");
+            ResultSet r = p2.executeQuery();
+            while(r.next()) {
+                r.getInt(1);
+                valid = true;
+            }
+            p1.setInt(1, 11);
+            p1.executeUpdate();
+
+            PreparedStatement ps3 = con.prepareStatement("select count(*) from a where a in ((select a from a where b = ?) union (select ? from a))");
+            ps3.setInt(1, 10);
+            ps3.setInt(2, 1);
+
+            r = ps3.executeQuery();
+
+            while(r.next()) {
+                int value = r.getInt(1);
+                valid = value == 2;
+            }
+
+            assertTrue(valid);
+        } catch (Exception e) {
+        assertTrue(false);
+    }
+    }
+
+}
diff --git a/src/org/hsqldb/test/TestQuotes.java b/src/org/hsqldb/test/TestQuotes.java
new file mode 100644
index 0000000..f536d85
--- /dev/null
+++ b/src/org/hsqldb/test/TestQuotes.java
@@ -0,0 +1,158 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ *  Test handling of quote characters in strings
+ *
+ * @author <a href="mailto:david@walend.net">David Walend</a>
+ * @author <a href="mailto:jvanzyl@zenplex.com">Jason van Zyl</a>
+ */
+public class TestQuotes extends TestCase {
+
+    private static final String CREATETABLE =
+        "create table quotetest (test varchar)";
+    private static final String DELETE = "delete from quotetest";
+    private static final String TESTSTRING =
+        "insert into quotetest (test) values (?)";
+    private static final String NOQUOTES = "the house of the dog of kevin";
+    private static final String QUOTES   = "kevin's dog's house";
+    private static final String RESULT   = "select * from quotetest";
+
+    public TestQuotes(String testName) {
+        super(testName);
+    }
+
+    /**
+     * Run all related test methods
+     */
+    public static Test suite() {
+        return new TestSuite(org.hsqldb.test.TestQuotes.class);
+    }
+
+    public void testSetString() {
+
+        Connection        connection = null;
+        Statement         statement  = null;
+        PreparedStatement pStatement = null;
+        ResultSet         rs1        = null;
+        ResultSet         rs2        = null;
+
+        try {
+            DriverManager.registerDriver(new org.hsqldb.jdbc.JDBCDriver());
+
+            connection = DriverManager.getConnection("jdbc:hsqldb:mem:.", "sa",
+                    "");
+            statement = connection.createStatement();
+
+            statement.executeUpdate(CREATETABLE);
+
+            pStatement = connection.prepareStatement(TESTSTRING);
+
+            pStatement.setString(1, NOQUOTES);
+            pStatement.executeUpdate();
+
+            rs1 = statement.executeQuery(RESULT);
+
+            rs1.next();
+
+            String result1 = rs1.getString(1);
+
+            assertTrue("result1 is -" + result1 + "- not -" + NOQUOTES + "-",
+                       NOQUOTES.equals(result1));
+            statement.executeUpdate(DELETE);
+            pStatement.setString(1, QUOTES);
+            pStatement.executeUpdate();
+
+            rs2 = statement.executeQuery(RESULT);
+
+            rs2.next();
+
+            String result2 = rs2.getString(1);
+
+            assertTrue("result2 is " + result2, QUOTES.equals(result2));
+        } catch (SQLException sqle) {
+            fail(sqle.getMessage());
+        } finally {
+            if (rs2 != null) {
+                try {
+                    rs2.close();
+                } catch (SQLException sqle) {
+                    sqle.printStackTrace();
+                }
+            }
+
+            if (rs1 != null) {
+                try {
+                    rs1.close();
+                } catch (SQLException sqle) {
+                    sqle.printStackTrace();
+                }
+            }
+
+            if (statement != null) {
+                try {
+                    statement.close();
+                } catch (SQLException sqle) {
+                    sqle.printStackTrace();
+                }
+            }
+
+            if (pStatement != null) {
+                try {
+                    pStatement.close();
+                } catch (SQLException sqle) {
+                    sqle.printStackTrace();
+                }
+            }
+
+            if (connection != null) {
+                try {
+                    connection.close();
+                } catch (SQLException sqle) {
+                    sqle.printStackTrace();
+                }
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestSchemaParse.java b/src/org/hsqldb/test/TestSchemaParse.java
new file mode 100644
index 0000000..544b2be
--- /dev/null
+++ b/src/org/hsqldb/test/TestSchemaParse.java
@@ -0,0 +1,1060 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class TestSchemaParse extends junit.framework.TestCase {
+
+    Connection                  con = null;
+    Statement                   statement;
+    private static final String ipref = "INFORMATION_SCHEMA.";
+
+    protected void setUp() throws Exception {
+
+        Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+        con = DriverManager.getConnection("jdbc:hsqldb:mem:parsetest", "sa",
+                                          "");
+        statement = con.createStatement();
+
+        execSQL("SET AUTOCOMMIT false", 0);
+        execSQL("CREATE TABLE tsttbl (i INT, vc VARCHAR(100))", 0);
+        execSQL("CREATE TABLE bigtbl (i INT, vc VARCHAR(100), i101 INT, i102 INT, "
+                + "i103 INT, i104 INT, i105 INT, i106 INT, i107 INT, "
+                + "i108 INT, i109 INT, i110 INT, i111 INT, i112 INT, "
+                + "i113 INT, i114 INT, i115 INT, i116 INT, i117 INT, "
+                + "i118 INT, i119 INT)", 0);
+        execSQL("INSERT INTO tsttbl VALUES (1, 'one')", 1);
+        execSQL("INSERT INTO tsttbl VALUES (2, 'two')", 1);
+        execSQL("CREATE TABLE joinedtbl (i2 INT, vc2 VARCHAR(100))", 0);
+        execSQL("INSERT INTO joinedtbl VALUES (2, 'zwei')", 1);
+        execSQL("CREATE TABLE indexedtbl (i3 INT, vc3 VARCHAR(100))", 0);
+        execSQL("INSERT INTO indexedtbl VALUES (3, 'tres')", 1);
+        execSQL("CREATE TABLE triggedtbl (i4 INT, vc4 VARCHAR(100))", 0);
+
+        // Can't test text tables in memory-only DB.
+        //execSQL("CREATE TEXT TABLE texttbl (i5 INT, vc5 VARCHAR(100))", 0);
+        execSQL("INSERT INTO triggedtbl VALUES (4, 'quatro')", 1);
+        execSQL("CREATE FUNCTION tstali(VARCHAR(100)) RETURNS VARCHAR(100) "
+                + "LANGUAGE JAVA EXTERNAL NAME "
+                + "'CLASSPATH:org.hsqldb.test.BlaineTrig.capitalize'", 0);
+        execSQL("CREATE UNIQUE INDEX tstind ON indexedtbl (i3)", 0);
+        execSQL("CREATE SEQUENCE tstseq", 0);
+        execSQL("CREATE TRIGGER tsttrig AFTER INSERT ON triggedtbl CALL \""
+                + "org.hsqldb.test.BlaineTrig\"", 0);
+        execSQL("CREATE USER tstuser PASSWORD fake", 0);
+        execSQL("CREATE TABLE constrainedtbl (i6 INT, vc6 VARCHAR(100), "
+                + "CONSTRAINT ucons UNIQUE(i6))", 0);
+        execSQL("CREATE TABLE primarytbl (i8 INT, i18 INT, vc8 VARCHAR(100), "
+                + "UNIQUE(i8), UNIQUE(i18))", 0);
+        execSQL(
+            "CREATE TABLE foreigntbl (i7 INT, vc7 VARCHAR(100), "
+            + "CONSTRAINT tstfk FOREIGN KEY (i7) REFERENCES primarytbl (i8))", 0);
+        execSQL("CREATE TABLE playtbl (i9 INT, vc9 VARCHAR(100))", 0);
+        execSQL("CREATE TABLE toindextbl (i10 INT, vc10 VARCHAR(100))", 0);
+        execSQL("INSERT INTO toindextbl VALUES (10, 'zehn')", 1);
+
+        // Do the view last since it can cause dependendies with indexes, etc.
+        execSQL("CREATE VIEW tstview AS SELECT * FROM tsttbl WHERE i < 10", 0);
+        execSQL("COMMIT", 0);
+    }
+
+    // Want to permit the SHUTDOWN SQL command in tearDown() to fail iff
+    // the test method run has tested SHUTDOWN.
+    private boolean shutdownTested = false;
+
+    protected void tearDown() throws Exception {
+
+        // Shut down to destroy all of the DB objects (only works because
+        // it's an in-memory instance.
+        execSQL("SHUTDOWN", shutdownTested);
+
+        if (con != null) {
+            con.close();
+        }
+
+        super.tearDown();
+    }
+
+    public void test2pTables() throws Exception {
+
+        String prefix = "public.";
+
+        execSQL("DROP VIEW tstview", 0);    // Just so deps don't cause problems
+
+        // Select commands
+        assertEquals(2, queryRowCount("SELECT i FROM " + prefix
+                                      + "tsttbl WHERE i IN (1, 2, 3)"));
+        execSQL("CREATE TABLE " + prefix + "newtbl AS (SELECT * FROM tsttbl) WITH DATA", 0);
+        assertEquals(2, queryRowCount("SELECT admin FROM " + ipref
+                                      + "system_users"));
+        assertEquals("Sub-query", 1,
+                     queryRowCount("SELECT vc FROM " + prefix
+                                   + "tsttbl WHERE i = (\n"
+                                   + "    SELECT i2 FROM " + prefix
+                                   + "joinedtbl\n" + ")"));
+        assertEquals("Join", 1,
+                     queryRowCount("SELECT vc FROM " + prefix + "tsttbl, "
+                                   + prefix + "joinedtbl\n"
+                                   + "WHERE tsttbl.i = joinedtbl.i2\n"
+                                   + "AND joinedtbl.vc2 = 'zwei'"));
+
+        // Selects using Labels/Aliases
+        assertEquals(
+            2, queryRowCount(
+                "SELECT ali.i FROM " + prefix
+                + "tsttbl ali WHERE ali.i IN (1, 2, 3)"));
+        execSQL("CREATE TABLE " + prefix + "newtbl2 AS (SELECT * FROM tsttbl) WITH DATA", 0);
+        execSQL("CREATE TABLE newtbl3 AS (SELECT * FROM " + prefix + "tsttbl ali) WITH DATA", 0);
+        execSQL("CREATE TABLE "+ prefix + "newtbl4 AS (SELECT * FROM " + prefix
+                + "tsttbl ali) WITH DATA", 0);
+        assertEquals(2, queryRowCount("SELECT ali.admin FROM " + ipref
+                                      + "system_users ali"));
+        assertEquals("Sub-query", 1,
+                     queryRowCount("SELECT ali.vc FROM " + prefix
+                                   + "tsttbl ali WHERE i = (\n"
+                                   + "    SELECT bali.i2 FROM " + prefix
+                                   + "joinedtbl bali\n" + ")"));
+        assertEquals("Join", 1,
+                     queryRowCount("SELECT ali.vc FROM " + prefix
+                                   + "tsttbl ali, " + prefix
+                                   + "joinedtbl bali\n"
+                                   + "WHERE ali.i = bali.i2\n"
+                                   + "AND bali.vc2 = 'zwei'"));
+        /* Mixed aliases not working yet
+        assertEquals("Join", 1, queryRowCount(
+          "SELECT ali.vc FROM " + prefix + "tsttbl ali, " + prefix
+          + "joinedtbl bali\nWHERE tsttbl.i = joinedtbl.i2\n"
+            + "AND bali.vc2 = 'zwei'"));
+        */
+
+        // Alter Table commands
+        execSQL("ALTER TABLE " + prefix + "playtbl RENAME TO " + prefix
+                + "renamedtbl", 0);
+        execSQL("ALTER TABLE " + prefix + "renamedtbl RENAME TO " + prefix
+                + "playtbl", 0);
+        execSQL("ALTER TABLE " + prefix
+                + "constrainedtbl ADD CONSTRAINT con1 CHECK (i6 > 4)", 0);
+        execSQL("ALTER TABLE " + prefix + "tsttbl ADD COLUMN vco1 VARCHAR(100)", 0);
+        execSQL("ALTER TABLE " + prefix + "tsttbl DROP COLUMN vco1", 0);
+        execSQL("ALTER TABLE " + prefix + "tsttbl ADD COLUMN vco1 VARCHAR(100)", 0);
+        execSQL("ALTER TABLE " + prefix
+                + "tsttbl ALTER COLUMN vco1 RENAME TO j1", 0);
+        execSQL("ALTER TABLE " + prefix
+                + "constrainedtbl DROP CONSTRAINT con1", 0);
+        execSQL("ALTER TABLE " + prefix + "foreigntbl DROP CONSTRAINT tstfk",
+                0);
+        execSQL("ALTER TABLE " + prefix
+                + "foreigntbl ADD CONSTRAINT tstfk FOREIGN KEY "
+                + "(i7) REFERENCES primarytbl (i8)", 0);
+        execSQL("ALTER TABLE " + prefix
+                + "playtbl ADD CONSTRAINT ucons9 UNIQUE (i9)", 0);
+
+        // Drop table command
+        execSQL("DROP TABLE " + prefix + "playtbl", 0);
+
+        // Set table readonly command
+        execSQL("SET TABLE " + prefix + "tsttbl READONLY true", 0);
+        execSQL("SET TABLE " + prefix + "tsttbl READONLY false", 0);
+
+        // Create table commands
+        execSQL("CREATE TABLE " + prefix + "tsttbly (i INT, vc VARCHAR(100))", 0);
+        execSQL("CREATE CACHED TABLE " + prefix
+                + "tsttblx (i INT, vc VARCHAR(100))", 0);
+        execSQL("CREATE TABLE constrz (i6 INT, vc6 VARCHAR(100), "
+                + "CONSTRAINT uconsz UNIQUE(i6))", 0);
+        execSQL(
+            "CREATE TABLE forztbl (i7 INT, vc7 VARCHAR(100), "
+            + "CONSTRAINT tstfkz FOREIGN KEY (i7) REFERENCES primarytbl (i8))", 0);
+
+        // Update command
+        execSQL("UPDATE " + prefix + "tsttbl SET vc = 'eleven' WHERE i = 1",
+                1);
+
+        // delete
+        execSQL("DELETE FROM  " + prefix + "tsttbl WHERE i = 1", 1);
+
+        // grant, revoke
+        execSQL("GRANT ALL ON " + prefix + "tsttbl TO tstuser", 0);
+        execSQL("REVOKE ALL ON " + prefix + "tsttbl FROM tstuser RESTRICT", 0);
+    }
+
+    public void test2pViews() throws Exception {
+
+        String prefix = "public.";
+
+        assertEquals(2, queryRowCount("SELECT i FROM " + prefix
+                                      + "tstview WHERE i IN (1, 2, 3)"));
+        assertEquals(2, queryRowCount("SELECT i FROM tstview"));
+        assertEquals(2, queryRowCount("SELECT ali.i FROM tstview ali"));
+        assertEquals("Sub-query", 1,
+                     queryRowCount("SELECT vc FROM " + prefix
+                                   + "tstview WHERE i = (\n"
+                                   + "    SELECT i2 FROM " + prefix
+                                   + "joinedtbl\n" + ")"));
+        assertEquals("Join", 1,
+                     queryRowCount("SELECT vc FROM " + prefix + "tstview, "
+                                   + prefix + "joinedtbl\n"
+                                   + "WHERE tstview.i = joinedtbl.i2\n"
+                                   + "AND joinedtbl.vc2 = 'zwei'"));
+        assertEquals(
+            2, queryRowCount(
+                "SELECT i FROM " + prefix
+                + "tstview ali WHERE ali.i IN (1, 2, 3)"));
+
+        // view
+        execSQL("CREATE VIEW " + prefix
+                + "tstview2 AS SELECT * FROM tsttbl WHERE i < 10", 0);
+
+        // grant, revoke
+        execSQL("GRANT ALL ON " + prefix + "tstview TO tstuser", 0);
+        execSQL("REVOKE ALL ON " + prefix + "tstview FROM tstuser RESTRICT", 0);
+
+        // drop
+        execSQL("DROP VIEW tstview", 0);
+    }
+
+    public void test2pSequences() throws Exception {
+
+        String prefix = "public.";
+
+        execSQL("CREATE SEQUENCE " + prefix + "tstseq2", 0);
+        execSQL("ALTER SEQUENCE " + prefix + "tstseq RESTART WITH 23", 0);
+        assertEquals(1, queryRowCount("SELECT next value FOR " + prefix
+                                      + "tstseq FROM tsttbl WHERE i = 1"));
+        execSQL("DROP SEQUENCE " + prefix + "tstseq", 0);
+    }
+
+    public void test2pConstraints() throws Exception {
+
+        String prefix = "public.";
+
+        // Some named constraints
+        execSQL("CREATE TABLE constbl1 (i11 INT, vc12 VARCHAR(100), "
+                + "CONSTRAINT " + prefix + "uconsw UNIQUE(vc12))", 0);
+        execSQL("CREATE TABLE constbl2 (i11 INT, vc12 VARCHAR(100), "
+                + "CONSTRAINT " + prefix + "chk CHECK (i11 > 4))", 0);
+        execSQL("CREATE TABLE for2tbl (i7 INT, vc7 VARCHAR(100), " + "CONSTRAINT "
+                + prefix
+                + "tstfk2 FOREIGN KEY (i7) REFERENCES primarytbl (i8))", 0);
+        execSQL("CREATE TABLE for3tbl (i7 INT, vc7 VARCHAR(100), " + "CONSTRAINT "
+                + prefix + "tstpk2 PRIMARY KEY (i7))", 0);
+        execSQL("ALTER TABLE constrainedtbl ADD CONSTRAINT " + prefix
+                + "con1 CHECK (i6 > 4)", 0);
+        execSQL("ALTER TABLE foreigntbl ADD CONSTRAINT " + prefix
+                + "tstfkm FOREIGN KEY "
+                + "(i7) REFERENCES primarytbl (i18)", 0);
+        execSQL("ALTER TABLE for3tbl DROP CONSTRAINT " + prefix + "tstpk2", 0);
+    }
+
+    public void test2pIndexes() throws Exception {
+
+        String prefix = "public.";
+
+        execSQL("CREATE UNIQUE INDEX playind ON playtbl (i9)", 0);
+        execSQL("CREATE UNIQUE INDEX bigind ON bigtbl (i)", 0);
+        execSQL("CREATE UNIQUE INDEX " + prefix + "tstind2 ON tsttbl (i)", 0);
+        execSQL("ALTER INDEX " + prefix + "playind RENAME TO renamedind", 0);
+        execSQL("ALTER INDEX " + prefix + "renamedind RENAME TO " + prefix
+                + "tstind22", 0);
+        execSQL("ALTER INDEX tstind RENAME TO " + prefix + "renamedind", 0);
+        execSQL("DROP INDEX " + prefix + "bigind", 0);
+    }
+
+    public void test2pAliases() throws Exception {
+
+        String prefix = "public.";
+
+        // All occurrences of "expect" in this method indicate bugs.
+        // When fixed, don't change the value of "expect" in the method body.
+        int expect = 0;
+
+        expect = SQL_ABORT;
+
+        execSQL("CREATE ALIAS " + prefix + "tstalias "
+                + "FOR \"org.hsqldb.test.BlaineTrig.capitalize\"", expect);
+
+        // Following should not throw an exception:
+        /*
+        assertEquals(
+            expect, queryRowCount(
+                "SELECT " + prefix + "tstalias('helo') FROM tsttbl WHERE i = 1"));
+        */
+    }
+
+    public void test2pTriggers() throws Exception {
+
+        String prefix = "public.";
+
+        execSQL("CREATE TRIGGER " + prefix
+                + "tsttrig2 AFTER INSERT ON triggedtbl "
+                + "CALL \"org.hsqldb.test.BlaineTrig\"", 0);
+        execSQL("DROP TRIGGER " + prefix + "tsttrig", 0);
+    }
+
+    public void testSanityCheck() throws Exception {
+
+        // All occurrences of "expect" in this method indicate bugs.
+        // When fixed, change the value of "expect" to 0:
+        int expect = SQL_ABORT;
+
+        // The most basic CREATEs and INSERTs would have already failed
+        // in the setup method.
+        // Get rid of view early so it doesn't cause dependency problems.
+        assertEquals(2, queryRowCount("SELECT i FROM tstview"));
+        execSQL("DROP VIEW tstview", 0);
+        execSQL("CREATE CACHED TABLE cachtbl (i INT, vc VARCHAR(100))", 0);
+        execSQL("SET TABLE tsttbl READONLY true", 0);
+        execSQL("SET TABLE tsttbl READONLY false", 0);
+        execSQL("INSERT INTO tsttbl VALUES (11, 'eleven')", 1);
+        assertEquals(1, queryRowCount("SELECT i FROM tsttbl WHERE i = 1"));
+        assertEquals(
+            2, queryRowCount("SELECT i FROM tsttbl WHERE i IN (1, 2, 3)"));
+        execSQL("ALTER SEQUENCE tstseq RESTART WITH 13", 0);
+        execSQL("ALTER TABLE playtbl RENAME TO renamedtbl", 0);
+        execSQL("ALTER TABLE renamedtbl RENAME TO playtbl", 0);
+        execSQL("DROP INDEX tstind", 0);
+        execSQL("DROP TABLE bigtbl", 0);
+        execSQL("DROP SEQUENCE tstseq", 0);
+        execSQL("SET FILES LOG SIZE 5", 0);
+
+        // Following syntax is now obsolete.
+        execSQL("SET PROPERTY \"hsqldb.first_identity\" 4", SQL_ABORT);
+        execSQL("UPDATE tsttbl SET vc = 'eleven' WHERE i = 1", 1);
+        execSQL(
+            "ALTER TABLE constrainedtbl ADD CONSTRAINT con1 CHECK (i6 > 4)",
+            0);
+
+        // Can't test text tables in in-memory DB.
+        execSQL("COMMIT", 0);
+        execSQL("DELETE FROM tsttbl WHERE i < 10", 2);
+        assertEquals(1, queryRowCount("SELECT i FROM tsttbl"));
+        execSQL("ROLLBACK", 0);
+        assertEquals(3, queryRowCount("SELECT i FROM tsttbl"));
+
+        // Remember that inserts must change after adding a column.
+        execSQL("ALTER TABLE tsttbl ADD COLUMN vco1 VARCHAR(100)", 0);
+        execSQL("ALTER TABLE tsttbl DROP COLUMN vco1", 0);
+        execSQL("CREATE UNIQUE INDEX tstind ON tsttbl (i)", 0);
+        execSQL("SET AUTOCOMMIT true", 0);
+        execSQL("SET AUTOCOMMIT false", 0);
+        execSQL("SET IGNORECASE true", 0);
+        execSQL("SET IGNORECASE false", 0);
+        execSQL("SET PASSWORD blah", 0);
+        execSQL("SET PASSWORD 'blah'", 0);
+        execSQL("SET DATABASE REFERENTIAL INTEGRITY true", 0);
+        execSQL("GRANT ALL ON playtbl TO tstuser", 0);
+        execSQL("REVOKE ALL ON playtbl FROM tstuser RESTRICT", 0);
+
+// TODO:  These should not throw a Null Pointer exception.
+        execSQL("ALTER INDEX tstind RENAME TO renamedind", 0);
+        execSQL("ALTER INDEX renamedind RENAME TO tstind", 0);
+        execSQL("ALTER USER tstuser SET PASSWORD frank", 0);
+        execSQL("ALTER USER tstuser SET PASSWORD 'frank'", 0);
+        execSQL("ALTER TABLE tsttbl ADD COLUMN vco1 VARCHAR(100)", 0);
+        execSQL("ALTER TABLE tsttbl ALTER COLUMN vco1 RENAME TO j1", 0);
+        execSQL("ALTER TABLE constrainedtbl DROP CONSTRAINT con1", 0);
+        execSQL("ALTER TABLE foreigntbl DROP CONSTRAINT tstfk", 0);
+        execSQL("ALTER TABLE foreigntbl ADD CONSTRAINT tstfk FOREIGN KEY "
+                + "(i7) REFERENCES primarytbl (i8)", 0);
+        assertEquals("Sub-query", 1,
+                     queryRowCount("SELECT vc FROM tsttbl WHERE i = (\n"
+                                   + "    SELECT i2 FROM joinedtbl\n" + ")"));
+        assertEquals(
+            "Join", 1,
+            queryRowCount(
+                "SELECT vc FROM tsttbl, joinedtbl WHERE tsttbl.i = joinedtbl.i2\n"
+                + "AND joinedtbl.vc2 = 'zwei'"));
+
+        // Over-specified table names
+        assertEquals(
+            "Over-specified Query 1", 1,
+            queryRowCount("SELECT tsttbl.i FROM tsttbl WHERE tsttbl.i = 1"));
+        assertEquals("Over-specified Query 2", 1,
+                     queryRowCount("SELECT tsttbl.i FROM tsttbl WHERE i = 1"));
+        assertEquals("Over-specified Query 3", 1,
+                     queryRowCount("SELECT i FROM tsttbl WHERE tsttbl.i = 1"));
+
+        // HSQLDB labels, Oracle aliases
+        assertEquals("Trivial Label/alias 1", 1,
+                     queryRowCount("SELECT i FROM tsttbl ali WHERE i = 1"));
+        assertEquals("Trivial Label/alias 2", 1,
+                     queryRowCount("SELECT i FROM tsttbl AS ali WHERE i = 1"));
+        assertEquals(
+            "Trivial Label/alias 3", 1,
+            queryRowCount("SELECT ali.i FROM tsttbl ali WHERE i = 1"));
+        assertEquals(
+            "Trivial Label/alias 4", 1,
+            queryRowCount("SELECT i FROM tsttbl ali WHERE ali.i = 1"));
+        assertEquals(
+            "Trivial Label/alias 5", 1,
+            queryRowCount("SELECT ali.i FROM tsttbl ali WHERE ali.i = 1"));
+
+        /**
+         * Uncomment when this mixing of aliases and real names is fixed.
+         *
+         * assertEquals("Mixed Label/aliases 1", 1, queryRowCount(
+         *       "SELECT tsttbl.i FROM tsttbl ali WHERE i = 1"));
+         * assertEquals("Mixed Label/aliases 2", 1, queryRowCount(
+         *       "SELECT i FROM tsttbl ali WHERE tsttbl.i = 1"));
+         * assertEquals("Mixed Label/aliases 3", 1, queryRowCount(
+         *       "SELECT tsttbl.i FROM tsttbl ali WHERE tsttbl.i = 1"));
+         * assertEquals("Mixed Label/aliases 4", 1, queryRowCount(
+         *       "SELECT tsttbl.i FROM tsttbl ali WHERE ali.i = 1"));
+         * assertEquals("Mixed Label/aliases 5", 1, queryRowCount(
+         *       "SELECT ali.i FROM tsttbl ali WHERE tsttbl.i = 1"));
+         */
+        assertEquals(
+            "Join w/Labels/aliases 1", 1,
+            queryRowCount(
+                "SELECT vc FROM tsttbl ali1, joinedtbl ali2\n"
+                + "WHERE i = i2 AND vc2 = 'zwei'"));
+        assertEquals(
+            "Join w/Labels/aliases 2", 1,
+            queryRowCount(
+                "SELECT vc FROM tsttbl ali1, joinedtbl ali2\n"
+                + "WHERE ali1.i = i2 AND ali2.vc2 = 'zwei'"));
+        assertEquals(
+            "Join w/Labels/aliases 3", 1,
+            queryRowCount(
+                "SELECT ali1.vc FROM tsttbl ali1, joinedtbl ali2\n"
+                + "WHERE ali1.i = i2 AND ali2.vc2 = 'zwei'"));
+        assertEquals(
+            "Join w/Labels/aliases 4", 1,
+            queryRowCount(
+                "SELECT ali1.vc FROM tsttbl ali1, joinedtbl ali2\n"
+                + "WHERE i = i2 AND vc2 = 'zwei'"));
+
+        /**
+         * Uncomment when this mixing of aliases and real names is fixed.
+         * assertEquals("Join w/Mixed Labels/aliases 1", 1, queryRowCount(
+         * "SELECT vc FROM tsttbl ali1, joinedtbl ali2\n"
+         * + "WHERE tsttbl.i = i2 AND vc2 = 'zwei'"));
+         * assertEquals("Join w/Mixed Labels/aliases 2", 1, queryRowCount(
+         * "SELECT vc FROM tsttbl ali1, joinedtbl ali2\n"
+         * + "WHERE tsttbl.i = i2 AND joinedtbl.vc2 = 'zwei'"));
+         * assertEquals("Join w/Mixed Labels/aliases 3", 1, queryRowCount(
+         * "SELECT ali1.vc FROM tsttbl ali1, joinedtbl ali2\n"
+         * + "WHERE ali1.i = i2 AND joinedtbl.vc2 = 'zwei'"));
+         * assertEquals("Join w/Mixed Labels/aliases 4", 1, queryRowCount(
+         * "SELECT tsttbl.vc FROM tsttbl ali1, joinedtbl ali2\n"
+         * + "WHERE ali1.i = i2 AND ali2.vc2 = 'zwei'"));
+         * assertEquals("Join w/Mixed Labels/aliases 5", 1, queryRowCount(
+         * "SELECT tsttbl.vc FROM tsttbl ali1, joinedtbl ali2\n"
+         * + "WHERE i = i2 AND vc2 = 'zwei'"));
+         * assertEquals("Join w/Mixed Labels/aliases 6", 1, queryRowCount(
+         * "SELECT tsttbl.vc FROM tsttbl ali1, joinedtbl ali2\n"
+         * + "WHERE i = i2 AND joinedtbl.vc2 = 'zwei'"));
+         */
+        execSQL("CHECKPOINT bad", expect);
+        execSQL("INSERT INTO tsttbl(i, vc) VALUES (12, 'twelve')", 1);
+        execSQL("CREATE TABLE newtbl AS (SELECT * FROM tsttbl) WITH DATA", 0);
+    }
+
+    public void testTwoPartKeywords() throws Exception {
+        multiPartKeywords("public.");
+    }
+
+    public void testThreePartKeywords() throws Exception {
+        multiPartKeywords("alpha.public.");
+    }
+
+    public void multiPartKeywords(String pref) throws Exception {
+
+        /*
+         *  Search for "expect =".  This indicates a bug that needs fixing.
+         */
+        /*
+         * IMPORTANT!!!!  When fixed, the method should NOT change the
+         * expect value from SQL_ABORT.
+         * Where "expect" is used there is always a real error.
+         */
+        int expect = SQL_ABORT;
+
+        // If > 2 name parts.  E.g. "x.y.z".
+        boolean manyParter = (pref.lastIndexOf('.') != pref.indexOf('.'));
+
+        // Prep for we will attempt to drop later
+        execSQL("DROP VIEW tstview", 0);                              // Don't want dep. problems
+        execSQL("CREATE TABLE adroptbl (i INT, vc VARCHAR(100))", 0);
+        execSQL("CREATE TABLE bdroptbl (i INT, vc VARCHAR(100))", 0);
+        execSQL("CREATE UNIQUE INDEX adropind ON adroptbl (i)", 0);
+        execSQL("CREATE UNIQUE INDEX bdropind ON bdroptbl (i)", 0);
+        execSQL("CREATE SEQUENCE bdropseq", 0);
+        execSQL("CREATE SEQUENCE adropseq", 0);
+        execSQL("CREATE TRIGGER adroptrig AFTER INSERT ON adroptbl CALL \""
+                + "org.hsqldb.test.BlaineTrig\"", 0);
+        execSQL("CREATE TRIGGER bdroptrig AFTER INSERT ON bdroptbl CALL \""
+                + "org.hsqldb.test.BlaineTrig\"", 0);
+        execSQL("CREATE VIEW adropviewx AS SELECT * FROM adroptbl", 0);
+        execSQL("CREATE VIEW bdropviewx AS SELECT * FROM bdroptbl", 0);
+        execSQL("ALTER TABLE playtbl ADD COLUMN newc VARCHAR(100)", 0);    // prep
+        execSQL("SET TABLE tsttbl READONLY false", 0);                // reset
+        execSQL("SET TABLE tsttbl READONLY " + pref + "true", expect);
+        execSQL(pref + "CREATE SEQUENCE tstseqa", expect);
+        execSQL(pref + "SET PROPERTY \"hsqldb.first_identity\" 4", expect);
+        execSQL("SET " + pref + "PROPERTY \"hsqldb.first_identity\" 4",
+                expect);
+
+        /* This block not keywords, but other non-Strings */
+        execSQL("SELECT i FROM tsttbl WHERE i = " + pref + "1", expect);
+        execSQL("SELECT i FROM tsttbl WHERE vc = " + pref + "'1.3'", expect);
+        execSQL("SELECT i FROM tsttbl WHERE vc = " + pref + "1", expect);
+        execSQL("SELECT i FROM tsttbl WHERE i = " + pref + "'1.3'", expect);
+        execSQL("SELECT i FROM tsttbl WHERE " + pref + "1 = " + pref + "1",
+                expect);
+        execSQL("SELECT i FROM tsttbl WHERE " + pref + "'1.3' = " + pref
+                + "'1.3'", expect);
+        execSQL("SELECT i FROM tsttbl WHERE " + pref + "true = " + pref
+                + "true", expect);
+        execSQL("SELECT i FROM tsttbl WHERE i " + pref + "IN (2, 4)", expect);
+        execSQL("SELECT i FROM tsttbl WHERE i < 3 y.AND i > 0", expect);
+        execSQL("SELECT i FROM tsttbl WHERE i < y.3 AND i > 0", expect);
+        execSQL("INSERT INTO tsttbl VALUES (" + pref + "1, 'one')", expect);
+        execSQL("CREATE VIEW tstviewx AS SELECT " + pref
+                + "* FROM tsttbl WHERE i < 10", expect);
+        execSQL("DROP VIEW tstviewx IF EXISTS", 0);                   // reset
+        execSQL("INSERT INTO tsttbl VALUES (1, " + pref + "'one')", expect);
+        execSQL("CREATE UNIQUE INDEX tstinda ON toindextbl (" + pref + "i10)",
+                expect);
+        execSQL("DROP INDEX tstinda IF EXISTS", 0);                   // reset
+        execSQL("CREATE VIEW tstviewx AS SELECT * FROM tsttbl WHERE i < "
+                + pref + "10", expect);
+        execSQL("DROP VIEW tstviewx IF EXISTS", 0);                   // reset
+        execSQL("xDROP VIEW adropview", expect);
+        execSQL("DROP xVIEW bdropview", expect);
+        execSQL("xDROP TRIGGER adroptrig", expect);
+        execSQL("DROP xTRIGGER bdroptrig", expect);
+        execSQL("xDROP INDEX adropind", expect);
+        execSQL("DROP xINDEX bdropind", expect);
+        execSQL("xDROP TABLE adroptbl", expect);
+        execSQL("DROP xTABLE bdroptbl", expect);
+        execSQL("xDROP SEQUENCE adropseq", expect);
+        execSQL("DROP xSEQUENCE bdropseq", expect);
+        execSQL("SET LOGSIZE " + pref + "5", expect);
+
+        // Can't test text tables in in-memory DB.
+        execSQL(pref + "SET TABLE texttbl SOURCE \"test.csv;fs=|\"", expect);
+        execSQL("SET " + pref + "TABLE texttbl SOURCE \"test.csv;fs=|\"",
+                expect);
+        execSQL("SET TABLE texttbl " + pref + "SOURCE \"test.csv;fs=|\"",
+                expect);
+        execSQL("SET TABLE texttbl SOURCE " + pref + "\"test.csv;fs=|\"",
+                expect);
+        execSQL("UPDATE tsttbl SET vc = " + pref + "'eleven' WHERE i = 1",
+                expect);
+        execSQL("UPDATE tsttbl SET vc = 'eleven' WHERE i = " + pref + "1",
+                expect);
+        execSQL("ALTER SEQUENCE tstseq RESTART WITH " + pref + "13", expect);
+        execSQL("ALTER TABLE constrainedtbl ADD CONSTRAINT con1 CHECK (i6 > "
+                + pref + "4)", expect);
+        execSQL(pref + "INSERT INTO tsttbl VALUES (1, 'one')", expect);
+        execSQL("INSERT " + pref + "INTO tsttbl VALUES (1, 'one')", expect);
+
+        if (!manyParter) {
+            expect = 1;
+        }
+
+        execSQL("INSERT INTO " + pref + "tsttbl VALUES (1, 'one')", expect);
+
+        expect = SQL_ABORT;
+
+        execSQL(pref + "DELETE FROM tsttbl WHERE i < 10", expect);
+        execSQL("SELECT vc FROM " + pref + "tsttbl, " + pref
+                + "joinedtbl WHERE tsttbl.i = joinedtbl.i2\n"
+                + "AND joinedtbl.vc2 = 'zwei'", (manyParter ? SQL_ABORT
+                                                            : SQL_FAIL));
+        execSQL(pref + "SELECT i FROM tsttbl", expect);
+        execSQL("SELECT i " + pref + "FROM tsttbl", expect);
+        execSQL("SELECT i FROM tsttbl " + pref + "WHERE i > 0", expect);
+        execSQL(pref + "CREATE ALIAS alpha.tstalia "
+                + "FOR \"org.hsqldb.test.BlaineTrig.capitalize\"", expect);
+        execSQL("CREATE " + pref + "ALIAS tstalib "
+                + "FOR \"org.hsqldb.test.BlaineTrig.capitalize\"", expect);
+        execSQL("CREATE ALIAS tstalic " + pref
+                + "FOR \"org.hsqldb.test.BlaineTrig.capitalize\"", expect);
+        execSQL("CREATE ALIAS tstalid " + "FOR " + pref
+                + "\"org.hsqldb.test.BlaineTrig.capitalize\"", expect);
+        execSQL("ALTER " + pref + "TABLE playtbl DROP COLUMN newc", expect);
+        execSQL("CREATE " + pref + "SEQUENCE tstseqb", expect);
+        execSQL("CREATE " + pref
+                + "TRIGGER tsttrigx AFTER INSERT ON triggedtbl CALL '"
+                + "org.hsqldb.test.BlaineTrig'", expect);
+        execSQL("CREATE " + pref + "USER tstusera PASSWORD fake", expect);
+        execSQL("CREATE VIEW tstviewx " + pref
+                + "AS SELECT * FROM tsttbl WHERE i < 10", expect);
+        execSQL("DROP VIEW tstviewx IF EXISTS", 0);    // reset
+        execSQL("CREATE UNIQUE " + pref + "INDEX tstinda ON toindextbl (i10)",
+                expect);
+        execSQL("DROP INDEX tstinda IF EXISTS", 0);    // reset
+        execSQL("CREATE " + pref + "INDEX tstinda ON toindextbl (i10)",
+                expect);
+        execSQL("DROP INDEX tstinda IF EXISTS", 0);    // reset
+        execSQL("CREATE TRIGGER tsttrigy " + pref
+                + "AFTER INSERT ON triggedtbl CALL \""
+                + "org.hsqldb.test.BlaineTrig\"", expect);
+        execSQL("CREATE USER tstuserb " + pref + "PASSWORD fake", expect);
+        execSQL("CREATE VIEW tstviewx AS " + pref
+                + "SELECT * FROM tsttbl WHERE i < 10", expect);
+        execSQL("DROP VIEW tstviewx IF EXISTS", 0);    // reset
+        execSQL("CREATE UNIQUE INDEX tstinda " + pref + "ON toindextbl (i10)",
+                expect);
+        execSQL("DROP INDEX tstinda IF EXISTS", 0);    // reset
+        execSQL("CREATE TRIGGER tsttrigz AFTER " + pref
+                + "INSERT ON triggedtbl CALL \""
+                + "org.hsqldb.test.BlaineTrig\"", expect);
+        execSQL("CREATE VIEW tstviewx AS SELECT * " + pref
+                + "FROM tsttbl WHERE i < 10", expect);
+
+        if (!manyParter) {
+            expect = 0;
+        }
+
+        execSQL("CREATE USER tstuserc PASSWORD " + pref + "fake", expect);
+
+        expect = SQL_ABORT;
+
+        execSQL("DROP VIEW tstviewx IF EXISTS", 0);    // reset
+        execSQL("CREATE TRIGGER tsttriga AFTER INSERT " + pref
+                + "ON triggedtbl CALL \""
+                + "org.hsqldb.test.BlaineTrig\"", expect);
+        execSQL("CREATE TRIGGER tsttrigb AFTER INSERT ON triggedtbl " + pref
+                + "CALL \"" + "org.hsqldb.test.BlaineTrig\"", expect);
+        execSQL("CREATE VIEW tstviewx AS SELECT * FROM tsttbl " + pref
+                + "WHERE i < 10", expect);
+        execSQL("DROP VIEW tstviewx IF EXISTS", 0);    // reset
+        execSQL("CREATE TRIGGER tsttrigc AFTER INSERT ON triggedtbl CALL "
+                + pref + "\"org.hsqldb.test.BlaineTrig'", expect);
+        execSQL("CREATE " + pref + "UNIQUE INDEX tstindx ON toindextbl (i10)",
+                expect);
+        execSQL("DROP INDEX tstinda IF EXISTS", 0);    // reset
+        execSQL(
+            "CREATE " + pref
+            + "VIEW tstviewx AS SELECT * FROM tsttbl WHERE i < 10", expect);
+        execSQL("DROP VIEW tstviewx IF EXISTS", 0);    // reset
+        execSQL(pref + "CREATE USER tstuserd PASSWORD fake", expect);
+        execSQL(pref
+                + "CREATE TRIGGER tsttrigd AFTER INSERT ON triggedtbl CALL \""
+                + "org.hsqldb.test.BlaineTrig\"", expect);
+        execSQL(
+            pref
+            + "CREATE VIEW tstviewx AS SELECT * FROM tsttbl WHERE i < 10", expect);
+        execSQL("DROP VIEW tstviewx IF EXISTS", 0);    // reset
+        execSQL(pref + "CREATE UNIQUE INDEX tstinda ON toindextbl (i10)",
+                expect);
+        execSQL("DROP INDEX tstinda IF EXISTS", 0);    // reset
+        execSQL("CREATE TABLE t1 (i " + pref + "INT, vc VARCHAR)", expect);
+        execSQL("DROP TABLE t1 IF EXISTS", 0);         // reset
+        execSQL("CREATE TABLE t1 (i INT, vc " + pref + "VARCHAR)", expect);
+        execSQL("DROP TABLE t1 IF EXISTS", 0);         // reset
+        execSQL(pref + "CREATE TABLE t1 (i INT, vc VARCHAR)", expect);
+        execSQL("DROP TABLE t1 IF EXISTS", 0);         // reset
+        execSQL("CREATE " + pref + "TABLE t1 (i INT, vc VARCHAR)", expect);
+        execSQL("DROP TABLE t1 IF EXISTS", 0);         // reset
+        execSQL("CREATE TABLE t1 (i " + pref + "INT, vc VARCHAR)", expect);
+        execSQL("DROP TABLE t1 IF EXISTS", 0);         // reset
+        execSQL("CREATE TABLE t1 (i INT, vc " + pref + "VARCHAR)", expect);
+        execSQL("DROP TABLE t1 IF EXISTS", 0);         // reset
+        execSQL("DELETE " + pref + "FROM tsttbl WHERE i < 10", expect);
+
+        if (!manyParter) {
+            expect = 3;
+        }
+
+        execSQL("DELETE FROM tsttbl " + pref + "WHERE i < 10", expect);
+
+        expect = SQL_ABORT;
+
+        execSQL(pref + "SET AUTOCOMMIT true", expect);
+        execSQL("SET " + pref + "AUTOCOMMIT true", expect);
+        execSQL("SET AUTOCOMMIT false", 0);               // reset
+        execSQL(pref + "SET IGNORECASE true", expect);
+        execSQL("SET " + pref + "IGNORECASE true", expect);
+        execSQL(pref + "SET LOGSIZE 5", expect);
+        execSQL("SET " + pref + "LOGSIZE 5", expect);
+        execSQL(pref + "SET PASSWORD blah", expect);
+        execSQL("SET " + pref + "PASSWORD blah", expect);
+        execSQL(pref + "SET REFERENTIAL_INTEGRITY true", expect);
+        execSQL("SET " + pref + "REFERENTIAL_INTEGRITY true", expect);
+
+        // Can't test text tables in in-memory DB.
+        execSQL(pref + "SET SCRIPTFORMAT text", expect);
+        execSQL("SET " + pref + "SCRIPTFORMAT text", expect);
+        execSQL(pref + "SET TABLE tsttbl READONLY true", expect);
+        execSQL("SET " + pref + "TABLE tsttbl READONLY true", expect);
+        execSQL("SET TABLE tsttbl READONLY false", 0);    // reset
+        execSQL(pref + "GRANT ALL ON playtbl TO tstuser", expect);
+        execSQL("GRANT " + pref + "ALL ON playtbl TO tstuser", expect);
+        execSQL("GRANT ALL " + pref + "ON playtbl TO tstuser", expect);
+        execSQL("GRANT ALL ON playtbl " + pref + "TO tstuser", expect);
+
+        if (!manyParter) {
+            expect = 0;
+        }
+
+        execSQL("GRANT ALL ON playtbl TO " + pref + "tstuser", expect);
+
+        expect = SQL_ABORT;
+
+        execSQL(pref + "REVOKE ALL ON playtbl FROM tstuser RESTRICT", expect);
+        execSQL("REVOKE " + pref + "ALL ON playtbl FROM tstuser RESTRICT", expect);
+        execSQL("REVOKE ALL " + pref + "ON playtbl FROM tstuser RESTRICT", expect);
+        execSQL("REVOKE ALL ON playtbl " + pref + "FROM tstuser RESTRICT", expect);
+
+        if (!manyParter) {
+            expect = 0;
+        }
+
+        execSQL("REVOKE ALL ON playtbl FROM " + pref + "tstuser RESTRICT", expect);
+
+        expect = SQL_ABORT;
+
+        execSQL("GRANT ALL ON playtbl TO tstuser", 0);    // reset
+        execSQL(pref + "COMMIT", expect);
+        execSQL(pref + "ROLLBACK", expect);
+        execSQL(pref + "UPDATE tsttbl SET vc = 'eleven' WHERE i = 1", expect);
+        execSQL("UPDATE tsttbl " + pref + "SET vc = 'eleven' WHERE i = 1",
+                expect);
+        execSQL("UPDATE tsttbl SET vc = 'eleven' " + pref + "WHERE i = 1",
+                expect);
+        execSQL(pref + "ALTER INDEX tstind RENAME TO renamedind", expect);
+        execSQL("ALTER INDEX tstind " + pref + "RENAME TO renamedind", expect);
+        execSQL("ALTER " + pref + "INDEX tstind RENAME TO renamedind", expect);
+        execSQL("ALTER INDEX tstind RENAME " + pref + "TO renamedind", expect);
+        execSQL(pref + "ALTER SEQUENCE tstseq RESTART WITH 13", expect);
+        execSQL("ALTER " + pref + "SEQUENCE tstseq RESTART WITH 13", expect);
+        execSQL("ALTER SEQUENCE tstseq " + pref + "RESTART WITH 13", expect);
+        execSQL("ALTER SEQUENCE tstseq RESTART " + pref + "WITH 13", expect);
+
+        if (!manyParter) {
+            expect = 0;
+        }
+
+        execSQL("ALTER USER tstuser SET PASSWORD " + pref + "frank", expect);
+
+        expect = SQL_ABORT;
+
+        execSQL(pref + "ALTER USER tstuser SET PASSWORD frank", expect);
+        execSQL("ALTER " + pref + "USER tstuser SET PASSWORD frank", expect);
+        execSQL("ALTER USER tstuser " + pref + "SET PASSWORD frank", expect);
+        execSQL("ALTER USER tstuser SET " + pref + "PASSWORD frank", expect);
+        execSQL(pref + "ALTER TABLE tsttbl ADD COLUMN vco1 VARCHAR", expect);
+        execSQL("ALTER " + pref + "TABLE tsttbl ADD COLUMN vco2 VARCHAR",
+                expect);
+        execSQL("ALTER TABLE tsttbl " + pref + "ADD COLUMN vco3 VARCHAR",
+                expect);
+        execSQL("ALTER TABLE tsttbl ADD " + pref + "COLUMN vco4 VARCHAR",
+                expect);
+        execSQL("ALTER TABLE tsttbl ADD " + pref + "COLUMN vco5 " + pref
+                + "VARCHAR", expect);
+        execSQL("ALTER TABLE bigtbl DROP " + pref + "COLUMN i103", expect);
+        execSQL("ALTER TABLE bigtbl " + pref + "DROP COLUMN i102", expect);
+        execSQL(pref + "ALTER TABLE bigtbl DROP COLUMN i101", expect);
+        execSQL(pref + "ALTER TABLE bigtbl ALTER COLUMN i104 RENAME TO j1",
+                expect);
+        execSQL("ALTER " + pref
+                + "TABLE bigtbl ALTER COLUMN i105 RENAME TO j2", expect);
+        execSQL("ALTER TABLE bigtbl " + pref
+                + "ALTER COLUMN i106 RENAME TO j3", expect);
+        execSQL("ALTER TABLE bigtbl ALTER " + pref
+                + "COLUMN i107 RENAME TO j4", expect);
+        execSQL("ALTER TABLE bigtbl ALTER COLUMN i108 " + pref
+                + "RENAME TO j5", expect);
+        execSQL("ALTER TABLE bigtbl ALTER COLUMN i109 RENAME " + pref
+                + "TO j6", expect);
+        execSQL(
+            pref
+            + "ALTER TABLE constrainedtbl ADD CONSTRAINT con2 CHECK (i6 > 4)", expect);
+        execSQL(
+            "ALTER " + pref
+            + "TABLE constrainedtbl ADD CONSTRAINT con3 CHECK (i6 > 4)", expect);
+        execSQL("ALTER TABLE constrainedtbl " + pref
+                + "ADD CONSTRAINT con4 CHECK (i6 > 4)", expect);
+        execSQL(
+            "ALTER TABLE constrainedtbl ADD CONSTRAINT con1 CHECK (i6 > 4)",
+            true);                                                            // setup
+        execSQL(
+            "ALTER TABLE constrainedtbl ADD CONSTRAINT con2 CHECK (i6 > 4)",
+            true);                                                            // setup
+        execSQL(
+            "ALTER TABLE constrainedtbl ADD CONSTRAINT con3 CHECK (i6 > 4)",
+            true);                                                            // setup
+        execSQL(
+            "ALTER TABLE constrainedtbl ADD CONSTRAINT con4 CHECK (i6 > 4)",
+            true);                                                            // setup
+        execSQL("ALTER TABLE constrainedtbl ADD " + pref
+                + "CONSTRAINT con5 CHECK (i6 > 4)", expect);
+        execSQL("ALTER TABLE constrainedtbl ADD CONSTRAINT con6 " + pref
+                + "CHECK (i6 > 4)", expect);
+        execSQL("ALTER TABLE constrainedtbl DROP CONSTRAINT ucons", true);    // reset
+        execSQL(
+            pref
+            + "ALTER TABLE constrainedtbl ADD CONSTRAINT ucons UNIQUE (i6)", expect);
+        execSQL("ALTER TABLE constrainedtbl DROP CONSTRAINT ucons", true);    // reset
+        execSQL(
+            "ALTER " + pref
+            + "TABLE constrainedtbl ADD CONSTRAINT ucons UNIQUE (i6)", expect);
+        execSQL("ALTER TABLE constrainedtbl DROP CONSTRAINT ucons", true);    // reset
+        execSQL("ALTER TABLE constrainedtbl " + pref
+                + "ADD CONSTRAINT ucons UNIQUE (i6)", expect);
+        execSQL("ALTER TABLE constrainedtbl DROP CONSTRAINT ucons", true);    // reset
+        execSQL("ALTER TABLE constrainedtbl ADD " + pref
+                + "CONSTRAINT ucons UNIQUE (i6)", expect);
+        execSQL("ALTER TABLE constrainedtbl DROP CONSTRAINT ucons", true);    // reset
+        execSQL("ALTER TABLE constrainedtbl ADD CONSTRAINT ucons " + pref
+                + "UNIQUE (i6)", expect);
+        execSQL("ALTER TABLE constrainedtbl ADD CONSTRAINT ucons UNIQUE (i6)",
+                true);                                                        // reset
+        execSQL(pref + "ALTER TABLE playtbl RENAME TO renamedtbl", expect);
+        execSQL("ALTER TABLE renamedtbl RENAME TO playtbl", true);            // reset
+        execSQL("ALTER " + pref + "TABLE playtbl RENAME TO renamedtbl",
+                expect);
+        execSQL("ALTER TABLE renamedtbl RENAME TO playtbl", true);            // reset
+        execSQL("ALTER TABLE playtbl " + pref + "RENAME TO renamedtbl",
+                expect);
+        execSQL("ALTER TABLE renamedtbl RENAME TO playtbl", true);            // reset
+        execSQL("ALTER TABLE playtbl RENAME " + pref + "TO renamedtbl",
+                expect);
+        execSQL(pref + "ALTER TABLE constrainedtbl DROP CONSTRAINT con1",
+                expect);
+        execSQL("ALTER " + pref + "TABLE constrainedtbl DROP CONSTRAINT con2",
+                expect);
+        execSQL("ALTER TABLE constrainedtbl " + pref + "DROP CONSTRAINT con3",
+                expect);
+        execSQL("ALTER TABLE constrainedtbl DROP " + pref + "CONSTRAINT con4",
+                expect);
+        execSQL("ALTER TABLE foreigntbl DROP CONSTRAINT tstfk", true);        // reset
+        execSQL(pref
+                + "ALTER TABLE foreigntbl ADD CONSTRAINT tstfk FOREIGN KEY "
+                + "(i7) REFERENCES primarytbl (i8)", expect);
+        execSQL("ALTER TABLE foreigntbl DROP CONSTRAINT tstfk", true);        // reset
+        execSQL("ALTER " + pref
+                + "TABLE foreigntbl ADD CONSTRAINT tstfk FOREIGN KEY "
+                + "(i7) REFERENCES primarytbl (i8)", expect);
+        execSQL("ALTER TABLE foreigntbl DROP CONSTRAINT tstfk", true);        // reset
+        execSQL("ALTER TABLE foreigntbl " + pref
+                + "ADD CONSTRAINT tstfk FOREIGN KEY "
+                + "(i7) REFERENCES primarytbl (i8)", expect);
+        execSQL("ALTER TABLE foreigntbl DROP CONSTRAINT tstfk", true);        // reset
+        execSQL("ALTER TABLE foreigntbl ADD " + pref
+                + "CONSTRAINT tstfk FOREIGN KEY "
+                + "(i7) REFERENCES primarytbl (i8)", expect);
+        execSQL("ALTER TABLE foreigntbl DROP CONSTRAINT tstfk", true);        // reset
+        execSQL("ALTER TABLE foreigntbl ADD CONSTRAINT tstfk " + pref
+                + "FOREIGN KEY " + "(i7) REFERENCES primarytbl (i8)", expect);
+        execSQL("ALTER TABLE foreigntbl DROP CONSTRAINT tstfk", true);        // reset
+        execSQL("ALTER TABLE foreigntbl ADD CONSTRAINT tstfk FOREIGN " + pref
+                + "KEY " + "(i7) REFERENCES primarytbl (i8)", expect);
+        execSQL("ALTER TABLE foreigntbl DROP CONSTRAINT tstfk", true);        // reset
+        execSQL("ALTER TABLE foreigntbl ADD CONSTRAINT tstfk FOREIGN KEY "
+                + "(i7) " + pref + "REFERENCES primarytbl (i8)", expect);
+
+        /*
+        // KEEP THESE TEST CASES AT THE BOTTOM!!!!  Can wreck all following
+        // tests in current method, even when this test succeeds.
+        // Can only run one successful SHUTDOWN command in one test case.
+        execSQL(pref + "SHUTDOWN", SQL_ABORT);
+        execSQL(pref + "SHUTDOWN IMMEDIATELY", SQL_ABORT);
+        */
+        shutdownTested = true;
+
+        /* Failing
+        execSQL(pref + "SHUTDOWN BADARG", SQL_ABORT);
+        execSQL("Bad SHUTDOWN command did shut down database",
+                "SET LOGSIZE " + pref + "5", 0);
+        */
+        execSQL("SHUTDOWN IMMEDIATELY", 0);
+    }
+
+    public void testThreePartNames() throws Exception {
+        execSQL("SELECT public.tsttbl.i FROM public.beta.tsttbl\n"
+                + "WHERE public.tsttbl.i = 1", SQL_ABORT);
+    }
+
+    /**
+     * This method seems to be obsolete.
+     */
+    public void testBasicQueries() throws Exception {
+
+        String prefix = "public.";
+
+        assertEquals(2, queryRowCount("SELECT i FROM " + prefix + "tsttbl"));
+        assertEquals(1, queryRowCount("SELECT vc FROM " + prefix
+                                      + "tsttbl WHERE i = 1"));
+        assertEquals(1, queryRowCount("SELECT vc FROM " + prefix
+                                      + "tsttbl WHERE i = (\n"
+                                      + "    SELECT i2 FROM " + prefix
+                                      + "joinedtbl\n" + ")"));
+    }
+
+    /** @todo fredt - need to define additional identifiers to use for all cases of expect */
+    private static final int SQL_ABORT   = -1234;
+    private static final int SQL_INITIAL = -1233;
+    private static final int SQL_FAIL    = -1;
+
+    private void execSQL(String s, boolean ignoreError) throws SQLException {
+
+        try {
+            statement.execute(s);
+            statement.getUpdateCount();
+        } catch (SQLException se) {
+            if (!ignoreError) {
+                throw se;
+            }
+
+//else System.err.println("FAILURE of (" + s + ')');
+        }
+    }
+
+    private void execSQL(String m, String s, int expect) {
+
+        int retval = SQL_INITIAL;
+
+        try {
+            statement.execute(s);
+
+            retval = statement.getUpdateCount();
+        } catch (SQLException se) {
+            retval = SQL_ABORT;
+        }
+
+        assertEquals(m, expect, retval);
+    }
+
+/** @todo fredt - this method body seems to be incorrect */
+    private void execSQL(String s, int expect) {
+        execSQL(s, s, expect);
+    }
+
+    private int queryRowCount(String query) throws SQLException {
+
+        int count = 0;
+
+        if (!statement.execute(query)) {
+            return count;
+        }
+
+        ResultSet rs = statement.getResultSet();
+
+        try {
+            while (rs.next()) {
+                count++;
+            }
+        } finally {
+            rs.close();
+        }
+
+        return count;
+    }
+
+    private int tableRowCount(String tableName) throws SQLException {
+
+        String query = "SELECT count(*) FROM " + tableName;
+
+        if (!statement.execute(query)) {
+            return 0;
+        }
+
+        ResultSet rs = statement.getResultSet();
+
+        try {
+            if (!rs.next()) {
+                throw new SQLException("0 rows returned by (" + query + ')');
+            }
+
+            int count = rs.getInt(1);
+
+            if (rs.next()) {
+                throw new SQLException("> 1 row returned by (" + query + ')');
+            }
+
+            return count;
+        } finally {
+            rs.close();
+        }
+
+        //throw new Exception("Failed to get rowcount for " + tableName);
+    }
+
+    public TestSchemaParse() {
+        super();
+    }
+
+    public TestSchemaParse(String s) {
+        super(s);
+    }
+
+    /**
+     * This method allows to easily run this unit test independent of the other
+     * unit tests, and without dealing with Ant or unrelated test suites.
+     */
+    static public void main(String[] sa) {
+            junit.textui.TestRunner runner = new junit.textui.TestRunner();
+            junit.framework.TestResult result =
+                runner.run(runner.getTest(TestSchemaParse.class.getName()));
+
+            System.exit(result.wasSuccessful() ? 0 : 1);
+    }
+
+    public static junit.framework.Test suite() {
+
+        junit.framework.TestSuite newSuite = new junit.framework.TestSuite();
+
+        newSuite.addTest(new TestSchemaParse("testSanityCheck"));
+        newSuite.addTest(new TestSchemaParse("testTwoPartKeywords"));
+        newSuite.addTest(new TestSchemaParse("testThreePartKeywords"));
+        newSuite.addTest(new TestSchemaParse("testThreePartNames"));
+        newSuite.addTest(new TestSchemaParse("testBasicQueries"));
+        newSuite.addTest(new TestSchemaParse("test2pTables"));
+        newSuite.addTest(new TestSchemaParse("test2pViews"));
+        newSuite.addTest(new TestSchemaParse("test2pSequences"));
+        newSuite.addTest(new TestSchemaParse("test2pIndexes"));
+        newSuite.addTest(new TestSchemaParse("test2pAliases"));
+        newSuite.addTest(new TestSchemaParse("test2pConstraints"));
+        newSuite.addTest(new TestSchemaParse("test2pTriggers"));
+
+        return newSuite;
+    }
+    ;
+
+    public void fire(int i, String name, String table, Object[] row1,
+                     Object[] row2) {}
+
+    public static String capitalize(String inString) {
+        return inString.toUpperCase();
+    }
+}
diff --git a/src/org/hsqldb/test/TestScript.java b/src/org/hsqldb/test/TestScript.java
new file mode 100644
index 0000000..1cfa372
--- /dev/null
+++ b/src/org/hsqldb/test/TestScript.java
@@ -0,0 +1,105 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+
+public class TestScript extends TestBase {
+
+      String path = "TestSelf01TempTables.txt";
+//       String path = "TestSelfTriggers2.txt";
+//    String path = "TestAny.txt";
+//    String path = "TestSelf.txt";
+//    String path = "TestSelf3PartNames.txt";
+//    String path = "TestSelfArithmetic.txt";
+//    String path = "TestSelfAlterColumn.txt";
+//    String path = "TestSelfCaseWhen.txt";
+//    String path = "TestSelfCheckConstraints.txt";
+//    String path = "TestSelfColGrant.txt";
+//    String path = "TestSelfCreate.txt";
+//    String path = "TestSelfConstraints.txt";
+//    String path = "TestSelfGrantees.txt";
+//    String path = "TestSelfGroupBy.txt";
+//    String path = "TestSelfInsertDeleteQueries.txt";
+//    String path = "TestSelfInterval.txt";
+//    String path = "TestSelfInternalFunctions.txt";
+//    String path = "TestSelfFieldLimits.txt";
+//    String path = "TestSelfFKModes.txt";
+//    String path = "TestSelfInPredicateReferencing.txt";
+//    String path = "TestSelfIssues.txt";
+//    String path = "TestSelfJoins.txt";
+//    String path = "TestSelfLeftJoin.txt";
+//    String path = "TestSelfNameResolution.txt";
+//    String path = "TestSelfImmediateShutdown.txt";
+//    String path = "TestSelfInsertDeleteQueries.txt";
+//    String path = "TestSelfInPredicateReferencing.txt";
+//    String path = "TestSelfMultiGrants.txt";
+//    String path = "TestSelfNot.txt";
+//    String path = "TestSelfOrderLimits.txt";
+//    String path = "TestSelfRoleNesting.txt";
+//    String path = "TestSelfQueries.txt";
+//    String path = "TestSelfSchemaPersistB1.txt";
+//    String path = "TestSelfSeqRightsA.txt";
+//      String path = "TestSelfStoredProcedure.txt";
+//      String path = "TestSelfStoredProcedureTypes.txt";
+//    String path = "TestSelfSysTables.txt";
+//    String path = "TestSelfTempTable1.txt";
+//    String path = "TestSelfTransaction.txt";
+//    String path = "TestSelfTriggers.txt";
+//    String path = "TestSelfUnions.txt";
+//    String path = "TestSelfUserFunction.txt";
+//    String path = "TestSelfViews.txt";
+//    String path = "TestSelfViewGrants.txt";
+//    String path = "TestSelfSeqRightsA.txt";
+//      String path = "TestSelfSysTables.txt";
+//    String path = "TestTemp.txt";
+    public TestScript(String name) {
+        super(name, null, false, false);
+    }
+
+    public void test() throws java.lang.Exception {
+
+        TestUtil.deleteDatabase("test");
+
+        Connection conn = newConnection();
+        String fullPath = "testrun/hsqldb/" + path;
+        TestUtil.testScript(conn, fullPath);
+        conn.createStatement().execute("SHUTDOWN IMMEDIATELY");
+    }
+
+    public static void main(String[] Args) throws Exception {
+
+        TestScript ts = new TestScript("test");
+
+        ts.test();
+    }
+}
diff --git a/src/org/hsqldb/test/TestScriptRunner.java b/src/org/hsqldb/test/TestScriptRunner.java
new file mode 100644
index 0000000..31b8651
--- /dev/null
+++ b/src/org/hsqldb/test/TestScriptRunner.java
@@ -0,0 +1,374 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.FileReader;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.lang.reflect.Method;
+import org.hsqldb.test.TestUtil;
+import org.hsqldb.lib.RCData;
+
+/**
+ * @see #main
+ */
+class TestScriptRunner {
+    protected static final String DEFAULT_RCFILE = "testscriptrunner.rc";
+    static public String LS = System.getProperty("line.separator");
+    static public String SYNTAX_MSG =
+        "java " + TestScriptRunner.class.getName()
+        + " [--optionalSwitches...] --urlid=URLID1 [script1.tsql [[--urlid=URLIDX] scriptY.tsql...]...]"
+        + LS
+        + "    Specify one input file name as '-' to read from stdin." + LS
+        + "    No scripts specified will read from only stdin." + LS
+        + "    Simple single-threaded example with RC file '" + DEFAULT_RCFILE
+        + "':" + LS
+        + "java " + TestScriptRunner.class.getName()
+        + "--urlid=URLID script1.tsql script2.tsql" + LS + LS
+        + "OPTIONAL SWITCHES:" + LS
+        + "    --verbose        Obviously..." + LS
+        + "    --threads        Each script runs in a parallel thread (dflt. sequential)."
+        + LS
+        + "    --rcfile=/path/to/file.rc   (Defaults to '" + DEFAULT_RCFILE
+        + "')" + LS
+        + "    --populate       Use TestCacheSize class to populate one database" + LS
+        + "    --sqltool=URLID  Invoke an interactive SqlTool session on given URLID" + LS
+        + "(This last is useful for troubleshooting and interactive script dev).";
+
+    public boolean verbose = false;
+    public boolean threaded = false;
+
+    /**
+     * Executes specified SQL test scripts.
+     *
+     * Run <CODE>java org.hsqldb.util.TestScriptRunner</CODE> with no
+     * args to display syntax help.
+     *
+     * The TestCacheSize database population uses the database details
+     * as generated in TestCacheSize.  It would be nice to get these
+     * from the RC file, but alas, TestCacheSize does much magical work
+     * based on components of the URL, for example.  Therefore our user
+     * must make a URLID definition to match that generated by
+     * TestCacheSize for the DB type requested below.  We must use that
+     * as the URLID for scripts (and/or SqlTool session) which we want
+     * to connect to the same database.
+     */
+    static public void main(String[] sa) throws IOException, SQLException {
+        // Make a copy if argv so we can change it safely
+        int argIndex = 0;
+        boolean threaded = false;
+        boolean verbose = false;
+        boolean populate = false;
+        String rcFile = DEFAULT_RCFILE;
+        Map scriptFileMap = new HashMap(); // scriptname -> URLID
+        String currentUrlid = null;
+        String sqlToolUrlid = null;
+        Method sqlToolMainMethod = null;
+
+        try {
+            for (int i = 0; i < sa.length; i++) {
+                if (sa[i].equals("--verbose")) {
+                    verbose = true;
+                    continue;
+                }
+                if (sa[i].equals("--threads")) {
+                    threaded = true;
+                    continue;
+                }
+                if (sa[i].equals("--populate")) {
+                    populate = true;
+                    continue;
+                }
+                if (sa[i].startsWith("--rcfile=")) {
+                    rcFile = sa[i].substring("--rcfile=".length());
+                    continue;
+                }
+                if (sa[i].startsWith("--urlid=")) {
+                    currentUrlid = sa[i].substring("--urlid=".length()); continue;
+                }
+                if (sa[i].startsWith("--sqltool=")) {
+                    sqlToolUrlid = sa[i].substring("--sqltool=".length());
+                    continue;
+                }
+                if (currentUrlid == null) {
+                    throw new IllegalArgumentException(
+                            "You must specify 'urlid' before script files.");
+                }
+                if (scriptFileMap.containsKey(sa[i]))
+                    throw new IllegalArgumentException(
+                            TestScriptRunner.class.getName()
+                            + " can't handle the same script name twice.  "
+                            + "(Just copy or sym-link the script).");
+                scriptFileMap.put(sa[i], currentUrlid);
+            }
+            if (currentUrlid == null) throw new IllegalArgumentException();
+            if (scriptFileMap.size() < 1) {
+                scriptFileMap.put("-", currentUrlid);
+            }
+        } catch (IllegalArgumentException e) {
+            if (e.getMessage() != null) System.err.println(e.getMessage());
+            System.err.println(SYNTAX_MSG);
+            System.exit(2);
+        }
+
+        if (sqlToolUrlid != null) {
+            Class sqlToolClass = null;
+            try {
+                sqlToolClass = Class.forName("org.hsqldb.util.SqlTool");
+            } catch (Exception e) {
+                System.err.println("SqlTool class not accessible.  "
+                        + "Re-run without '--sqltool' switch.");
+                System.exit(3);
+            }
+            try {
+                sqlToolMainMethod = sqlToolClass.
+                        getMethod("objectMain", new Class[] {sa.getClass()} );
+            } catch (Exception e) {
+                System.err.println("SqlTool integration failure: " + e);
+                System.exit(3);
+            }
+        } 
+        TestScriptRunner runner = new TestScriptRunner(rcFile, scriptFileMap);
+        runner.setVerbose(verbose);
+        runner.setThreaded(threaded);
+        TestCacheSize tcs = populate ? populate() : null;
+        runner.establishConnections();
+        boolean success = runner.runScripts();
+        if (sqlToolMainMethod != null) try {
+            sqlToolMainMethod.invoke(null, new Object[] { new String[] {
+                "--rcfile=" + rcFile, sqlToolUrlid }});
+        } catch (Exception e) {
+            System.err.println("SqlTool failed: " + e);
+            e.printStackTrace();
+        }
+        if (tcs != null) tcs.tearDown();
+        System.exit(success ? 0 : 1);
+    }
+
+    List scriptRuns = new ArrayList();
+
+    private class ScriptRun extends Thread {
+        private Reader reader;
+        private Connection conn = null;
+        private RCData rcdata;
+        private boolean success = false;
+
+        public ScriptRun(String name, Reader reader, RCData rcdata) {
+            super(name);
+            this.reader = reader;
+            this.rcdata = rcdata;
+        }
+
+        public boolean getSuccess() {
+            return success;
+        }
+
+        public void connect() throws SQLException {
+            if (conn != null) {
+                throw new IllegalStateException("Thread '" + getName()
+                        + "' has already been connected");
+            }
+            try {
+                conn = rcdata.getConnection();
+            } catch (Exception e) {
+                throw new RuntimeException(
+                        "Failed to connect to get JDBC connection for '"
+                        + getName() + "'", e);
+            }
+            conn.setAutoCommit(false);
+            System.out.println("ScriptRun '" + getName() + "' connected with "
+                    + RCData.tiToString(conn.getTransactionIsolation()) + '.');
+        }
+
+        public void run() {
+            try {
+                TestUtil.testScript(conn, getName(), reader);
+                success = true;
+            } catch (TestUtil.TestRuntimeException tre) {
+                System.err.println("Script '" + getName() + "' failed");
+            } catch (IOException ioe) {
+                System.err.println("Aborting thread for script '" + getName()
+                        + "' due to: " + ioe);
+                throw new RuntimeException(ioe);
+            } catch (SQLException se) {
+                System.err.println("Aborting thread for script '" + getName()
+                        + "' due to: " + se);
+                throw new RuntimeException(se);
+            } finally { try {
+                conn.close();
+            } catch (SQLException se) {
+                System.err.println("Failed to close JDBC connection for '"
+                        + getName() + "': " + se);
+            } }
+        }
+    }
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+    public void setThreaded(boolean threaded) {
+        this.threaded = threaded;
+    }
+
+    public TestScriptRunner(String rcFileString, Map scriptFileMap)
+            throws IOException {
+        TestUtil.setAbortOnErr(true);
+        Map rcdataMap = new HashMap();
+        File rcFile = new File(rcFileString);
+        if (!rcFile.isFile())
+            throw new IllegalArgumentException(
+                    "RC file '" + rcFileString + "' not a file");
+
+        String scriptPath, urlid;
+        Iterator it;
+        File file;
+        Reader reader = null;
+
+        it = scriptFileMap.values().iterator();
+        while (it.hasNext()) {
+            urlid = (String) it.next();
+            if (rcdataMap.containsKey(urlid)) continue;
+            try {
+                rcdataMap.put(urlid, new RCData(rcFile, urlid));
+            } catch (Exception e) {
+                throw new RuntimeException(
+                        "Failed to instantiate RCData with file '"
+                        + rcFile + "' for urlid '" + urlid + "'", e);
+            }
+        }
+
+        it = scriptFileMap.keySet().iterator();
+        while (it.hasNext()) {
+            scriptPath = (String) it.next();
+            urlid = (String) scriptFileMap.get(scriptPath);
+
+            if (scriptPath.equals("-")) {
+                reader = new InputStreamReader(System.in);
+            } else {
+                file = new File(scriptPath);
+                if (!file.isFile()) throw new IOException("'" + file
+                        + "' is not a file");
+                if (!file.canRead()) throw new IOException("'" + file
+                        + "' is not readable");
+                reader = new FileReader(file);
+            }
+            scriptRuns.add(new ScriptRun(scriptPath,
+                    reader, (RCData) rcdataMap.get(urlid)));
+        }
+    }
+
+    public void establishConnections() throws SQLException {
+        for (int i = 0; i < scriptRuns.size(); i++)
+            ((ScriptRun) scriptRuns.get(i)).connect();
+        if (verbose) System.out.println(Integer.toString(scriptRuns.size())
+                    + " connection threads connected");
+    }
+
+    public boolean runScripts() {
+        ScriptRun scriptRun;
+        for (int i = 0; i < scriptRuns.size(); i++) {
+            scriptRun = (ScriptRun) scriptRuns.get(i);
+            if (verbose) System.out.print("Starting " + (++i) + " / "
+                + scriptRuns.size() + "...");
+            scriptRun.start();
+            if (verbose) System.out.println("  +");
+            if (!threaded) try {
+                scriptRun.join();
+            } catch (InterruptedException ie) {
+                throw new RuntimeException(
+                        "Interrupted while waiting for script '"
+                        + scriptRun.getName() + "' to execute", ie);
+            }
+        }
+        if (threaded) {
+            if (verbose)
+                System.out.println(
+                        "All scripts started.  Will now wait for them.");
+            for (int i = 0; i < scriptRuns.size(); i++) try {
+                ((ScriptRun) scriptRuns.get(i)).join();
+            } catch (InterruptedException ie) {
+                throw new RuntimeException(
+                        "Interrupted while waiting for script to execute", ie);
+            }
+        }
+        for (int i = 0; i < scriptRuns.size(); i++) {
+            if (!((ScriptRun) scriptRuns.get(i)).getSuccess()) return false;
+        }
+        return true;
+    }
+
+    /**
+     * Copied directly from TestCacheSize.main().
+     *
+     * My goal is to configure population of this database by a properties
+     * file, not by command line (which would just be too many settings
+     * along with the main settings), nor by System Properties (ditto).
+     * I see nothing in the TestCacheSize source code to allow loading by
+     * a properties file, however.
+     */
+    static protected TestCacheSize populate() {
+        TestCacheSize  test  = new TestCacheSize();
+        
+        /* Use all defaults
+        HsqlProperties props = HsqlProperties.argArrayToProps(argv, "test");
+
+        test.bigops   = props.getIntegerProperty("test.bigops", test.bigops);
+        test.bigrows  = test.bigops;
+        test.smallops = test.bigops / 8;
+        test.cacheScale = props.getIntegerProperty("test.scale",
+                test.cacheScale);
+        test.logType   = props.getProperty("test.logtype", test.logType);
+        test.tableType = props.getProperty("test.tabletype", test.tableType);
+        test.nioMode   = props.isPropertyTrue("test.nio", test.nioMode);
+        */
+
+        test.filepath = "mem:test";
+        test.filedb   = false;
+        test.shutdown = false;
+
+        test.setUp();
+        test.testFillUp();
+        //test.checkResults();
+        //System.out.println("total test time -- " + sw.elapsedTime() + " ms");
+        return test;
+    }
+}
diff --git a/src/org/hsqldb/test/TestScripts.java b/src/org/hsqldb/test/TestScripts.java
new file mode 100644
index 0000000..bb91788
--- /dev/null
+++ b/src/org/hsqldb/test/TestScripts.java
@@ -0,0 +1,222 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Runs test scripts against a single database, using persistent connection(s)
+ * across multiple test script(s).
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+class TestScripts extends TestUtil {
+
+    /**
+     * Run java org.hsqldb.util.TestScripts --help.
+     * For each script run, the connection will be closed or persisted
+     * depending on whether "--ephConnId=x" or "--persistConnId=x" preceded
+     * the file name (defaulting to closing).
+     * So, by default, for each script file, a new connection will be made
+     * and closed immediately after the script runs.
+     */
+    public static void main(String[] argv) {
+
+        if (argv.length > 0 && argv[0].equals("--help")) {
+            System.err.println(SYNTAX_MSG);
+            System.exit(2);
+        }
+
+        ArrayList scripts   = new ArrayList();
+        ArrayList connIds   = new ArrayList();
+        ArrayList retains   = new ArrayList();
+        int       i         = -1;
+        int       curscript = 0;
+
+        // java.util.ArrayLists may contain null elements.
+        connIds.add(null);
+        retains.add(null);
+
+        String newName = null;
+
+        while (++i < argv.length) {
+            if (argv[i].startsWith("--ephConnId=")) {
+                newName = getIdName(argv[i]);
+
+                if (newName == null
+                        || connIds.set(connIds.size() - 1, getIdName(argv[i]))
+                           != null) {
+                    System.err.println(SYNTAX_MSG);
+                    System.exit(2);
+                }
+
+                if (retains.set(retains.size() - 1, Boolean.FALSE) != null) {
+                    System.err.println(SYNTAX_MSG);
+                    System.exit(2);
+                }
+            } else if (argv[i].startsWith("--persistConnId=")) {
+                newName = getIdName(argv[i]);
+
+                if (newName == null
+                        || connIds.set(connIds.size() - 1, newName) != null) {
+                    System.err.println(SYNTAX_MSG);
+                    System.exit(2);
+                }
+
+                if (retains.set(retains.size() - 1, Boolean.TRUE) != null) {
+                    System.err.println(SYNTAX_MSG);
+                    System.exit(2);
+                }
+            } else if (argv[i].startsWith("-")) {
+                System.err.println(SYNTAX_MSG);
+                System.exit(2);
+            } else {
+                scripts.add(argv[i]);
+                connIds.add(null);
+                retains.add(null);
+            }
+        }
+
+        test(DEF_URL, DEF_USER, DEF_PASSWORD, DEF_DB,
+             (String[]) scripts.toArray(new String[0]),
+             (String[]) connIds.toArray(new String[0]),
+             (Boolean[]) retains.toArray(new Boolean[0]));
+    }
+
+    private static String getIdName(String s) {
+
+        int nameStart = s.indexOf('=') + 1;
+
+        if (nameStart < 1) {
+            return null;
+        }
+
+        if (nameStart == s.length()) {
+            throw new RuntimeException(
+                "Leave off '=' if you do not want to name a connection");
+        }
+
+        return s.substring(nameStart);
+    }
+
+    private static final String SYNTAX_MSG = "SYNTAX  java "
+        + TestScripts.class.getName()
+        + " [--ephConnId=x | --persistConnId=x] file1.txt...";
+
+    static void delete(String file) {
+
+        try {
+            new File(file).delete();
+        } catch (Exception e) {}
+    }
+
+    static void deleteDatabase(String path) {
+
+        delete(path + ".backup");
+        delete(path + ".properties");
+        delete(path + ".script");
+        delete(path + ".data");
+        delete(path + ".log");
+    }
+
+    static String DEF_DB = "test3";
+    static String DEF_URL = "jdbc:hsqldb:" + DEF_DB
+                            + ";sql.enforce_strict_size=true";
+    static String DEF_USER     = "SA";
+    static String DEF_PASSWORD = "";
+
+    static void test(String url, String user, String password, String db,
+                     String[] scriptList, String[] idList,
+                     Boolean[] persistList) {
+
+        if (scriptList.length < 1) {
+            System.err.println("Nothing to do.  No scripts specified.");
+
+            return;
+        }
+
+        HashMap connMap = new HashMap();
+
+        if (db != null) {
+            deleteDatabase(db);
+        }
+
+        try {
+            DriverManager.registerDriver(new org.hsqldb.jdbc.JDBCDriver());
+
+            Connection cConnection = null;
+            String     id;
+
+            for (int i = 0; i < scriptList.length; i++) {
+                id = idList[i];
+
+                System.out.println("ID: " + id);
+
+                cConnection = ((id == null) ? null
+                                            : (Connection) connMap.get(id));
+
+                if (cConnection == null) {
+                    System.out.println("Getting NEW conn");
+
+                    cConnection = DriverManager.getConnection(url, user,
+                            password);
+
+                    if (id != null) {
+
+                        // If new named conn., then store it.
+                        connMap.put(id, cConnection);
+                        System.out.println("Storing NEW conn");
+                    }
+                }
+
+                testScript(cConnection, scriptList[i]);
+
+                if (persistList[i] == null ||!persistList[i].booleanValue()) {
+                    if (id != null) {
+                        connMap.remove(id);
+                        System.out.println("Removed conn");
+                    }
+
+                    cConnection.close();
+                    System.out.println("Closed conn");
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            print("TestSelf init error: " + e.getMessage());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestSql.java b/src/org/hsqldb/test/TestSql.java
new file mode 100644
index 0000000..cc37f6f
--- /dev/null
+++ b/src/org/hsqldb/test/TestSql.java
@@ -0,0 +1,942 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import java.sql.Date;
+
+/**
+ * Test sql statements via jdbc against in-memory database
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ */
+public class TestSql extends TestBase {
+
+    Statement         stmnt;
+    PreparedStatement pstmnt;
+    Connection        connection;
+    String            getColumnName = "false";
+
+    public TestSql(String name) {
+        super(name);
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            connection = super.newConnection();
+            stmnt      = connection.createStatement();
+        } catch (Exception e) {}
+    }
+
+    public void testMetaData() {
+
+        String ddl0 =
+            "DROP TABLE ADDRESSBOOK IF EXISTS; DROP TABLE ADDRESSBOOK_CATEGORY IF EXISTS; DROP TABLE USER IF EXISTS;";
+        String ddl1 =
+            "CREATE TABLE USER(USER_ID INTEGER NOT NULL PRIMARY KEY,LOGIN_ID VARCHAR(128) NOT NULL,USER_NAME VARCHAR(254) DEFAULT ' ' NOT NULL,CREATE_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,UPDATE_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,LAST_ACCESS_DATE TIMESTAMP,CONSTRAINT IXUQ_LOGIN_ID0 UNIQUE(LOGIN_ID))";
+        String ddl2 =
+            "CREATE TABLE ADDRESSBOOK_CATEGORY(USER_ID INTEGER NOT NULL,CATEGORY_ID INTEGER DEFAULT 0 NOT NULL,CATEGORY_NAME VARCHAR(60) DEFAULT '' NOT NULL,CONSTRAINT SYS_PK_ADDRESSBOOK_CATEGORY PRIMARY KEY(USER_ID,CATEGORY_ID),CONSTRAINT FK_ADRBKCAT1 FOREIGN KEY(USER_ID) REFERENCES USER(USER_ID) ON DELETE CASCADE)";
+        String ddl3 =
+            "CREATE TABLE ADDRESSBOOK(USER_ID INTEGER NOT NULL,ADDRESSBOOK_ID INTEGER NOT NULL,CATEGORY_ID INTEGER DEFAULT 0 NOT NULL,FIRST VARCHAR(64) DEFAULT '' NOT NULL,LAST VARCHAR(64) DEFAULT '' NOT NULL,NOTE VARCHAR(128) DEFAULT '' NOT NULL,CONSTRAINT SYS_PK_ADDRESSBOOK PRIMARY KEY(USER_ID,ADDRESSBOOK_ID),CONSTRAINT FK_ADRBOOK1 FOREIGN KEY(USER_ID,CATEGORY_ID) REFERENCES ADDRESSBOOK_CATEGORY(USER_ID,CATEGORY_ID) ON DELETE CASCADE)";
+        String result1 = "1";
+        String result2 = "2";
+        String result3 = "3";
+        String result4 = "4";
+        String result5 = "5";
+
+        try {
+            stmnt.execute(ddl0);
+            stmnt.execute(ddl1);
+            stmnt.execute(ddl2);
+            stmnt.execute(ddl3);
+
+            DatabaseMetaData md = connection.getMetaData();
+
+            {
+                System.out.println("Testing DatabaseMetaData methods");
+
+                System.out.println(md.getDatabaseMajorVersion());
+                System.out.println(md.getDatabaseMinorVersion());
+                System.out.println(md.getDatabaseProductName());
+                System.out.println(md.getDatabaseProductVersion());
+                System.out.println(md.getDefaultTransactionIsolation());
+                System.out.println(md.getDriverMajorVersion());
+                System.out.println(md.getDriverMinorVersion());
+                System.out.println(md.getDriverName());
+                System.out.println(md.getDriverVersion());
+                System.out.println(md.getExtraNameCharacters());
+                System.out.println(md.getIdentifierQuoteString());
+
+                System.out.println(md.getJDBCMajorVersion());
+                System.out.println(md.getJDBCMinorVersion());
+                System.out.println(md.getMaxBinaryLiteralLength());
+                System.out.println(md.getMaxCatalogNameLength());
+                System.out.println(md.getMaxColumnsInGroupBy());
+                System.out.println(md.getMaxColumnsInIndex());
+                System.out.println(md.getMaxColumnsInOrderBy());
+                System.out.println(md.getMaxColumnsInSelect());
+                System.out.println(md.getMaxColumnsInTable());
+                System.out.println(md.getMaxConnections());
+                System.out.println(md.getMaxCursorNameLength());
+                System.out.println(md.getMaxIndexLength());
+                System.out.println(md.getMaxProcedureNameLength());
+                System.out.println(md.getMaxRowSize());
+                System.out.println(md.getMaxSchemaNameLength());
+                System.out.println(md.getMaxStatementLength());
+                System.out.println(md.getMaxStatements());
+                System.out.println(md.getMaxTableNameLength());
+                System.out.println(md.getMaxUserNameLength());
+                System.out.println(md.getNumericFunctions());
+                System.out.println(md.getProcedureTerm());
+
+                System.out.println(md.getResultSetHoldability());
+                System.out.println(md.getSchemaTerm());
+                System.out.println(md.getSearchStringEscape());
+                System.out.println(
+                    "Testing DatabaseMetaData.getSQLKeywords()");
+                System.out.println(md.getSQLKeywords());
+
+                System.out.println(md.getSQLStateType());
+                System.out.println(
+                    "Testing DatabaseMetaData.getStringFunctions()");
+                System.out.println(md.getStringFunctions());
+                System.out.println(
+                    "Testing DatabaseMetaData.getSystemFunctions()");
+                System.out.println(md.getSystemFunctions());
+                System.out.println(
+                    "Testing DatabaseMetaData.getTimeDateFunctions()");
+                System.out.println(md.getTimeDateFunctions());
+                System.out.println(md.getURL());
+                System.out.println(md.getUserName());
+                System.out.println(DatabaseMetaData.importedKeyCascade);
+                System.out.println(md.isCatalogAtStart());
+                System.out.println(md.isReadOnly());
+
+                ResultSet rs;
+
+                rs = md.getPrimaryKeys(null, null, "USER");
+
+                ResultSetMetaData rsmd    = rs.getMetaData();
+                String            result0 = "";
+
+                for (; rs.next(); ) {
+                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                        result0 += rs.getString(i + 1) + ":";
+                    }
+
+                    result0 += "\n";
+                }
+
+                rs.close();
+                System.out.println(result0);
+            }
+
+            {
+                ResultSet rs;
+
+                rs = md.getBestRowIdentifier(null, null, "USER", 0, true);
+
+                ResultSetMetaData rsmd    = rs.getMetaData();
+                String            result0 = "";
+
+                for (; rs.next(); ) {
+                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                        result0 += rs.getString(i + 1) + ":";
+                    }
+
+                    result0 += "\n";
+                }
+
+                rs.close();
+                System.out.println(result0);
+            }
+
+            {
+                ResultSet rs = md.getImportedKeys(null, null, "ADDRESSBOOK");
+                ResultSetMetaData rsmd = rs.getMetaData();
+
+                result1 = "";
+
+                for (; rs.next(); ) {
+                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                        result1 += rs.getString(i + 1) + ":";
+                    }
+
+                    result1 += "\n";
+                }
+
+                rs.close();
+                System.out.println(result1);
+            }
+
+            {
+                ResultSet rs = md.getCrossReference(null, null,
+                                                    "ADDRESSBOOK_CATEGORY",
+                                                    null, null, "ADDRESSBOOK");
+                ResultSetMetaData rsmd = rs.getMetaData();
+
+                result2 = "";
+
+                for (; rs.next(); ) {
+                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                        result2 += rs.getString(i + 1) + ":";
+                    }
+
+                    result2 += "\n";
+                }
+
+                rs.close();
+                System.out.println(result2);
+            }
+
+            {
+                ResultSet         rs = md.getExportedKeys(null, null, "USER");
+                ResultSetMetaData rsmd = rs.getMetaData();
+
+                result3 = "";
+
+                for (; rs.next(); ) {
+                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                        result3 += rs.getString(i + 1) + ":";
+                    }
+
+                    result3 += "\n";
+                }
+
+                rs.close();
+                System.out.println(result3);
+            }
+
+            {
+                ResultSet rs = md.getCrossReference(null, null, "USER", null,
+                                                    null,
+                                                    "ADDRESSBOOK_CATEGORY");
+                ResultSetMetaData rsmd = rs.getMetaData();
+
+                result4 = "";
+
+                for (; rs.next(); ) {
+                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                        result4 += rs.getString(i + 1) + ":";
+                    }
+
+                    result4 += "\n";
+                }
+
+                rs.close();
+                System.out.println(result4);
+            }
+
+            {
+                stmnt.execute("DROP TABLE T IF EXISTS;");
+                stmnt.execute(
+                    "CREATE TABLE T (I IDENTITY, A CHAR(20), B CHAR(20));");
+                stmnt.execute(
+                    "INSERT INTO T VALUES (NULL, 'get_column_name', '"
+                    + getColumnName + "');");
+
+                ResultSet rs = stmnt.executeQuery(
+                    "SELECT I, A, B, A \"aliasA\", B \"aliasB\", 1 FROM T;");
+                ResultSetMetaData rsmd = rs.getMetaData();
+
+                result5 = "";
+
+                for (; rs.next(); ) {
+                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                        result5 += rsmd.getColumnName(i + 1) + ":"
+                                   + rs.getString(i + 1) + ":";
+                    }
+
+                    result5 += "\n";
+                }
+
+                rs.close();
+
+                rs = stmnt.executeQuery(
+                    "SELECT I, A, B, A \"aliasA\", B \"aliasB\", 1 FROM T;");;
+                rsmd = rs.getMetaData();
+
+                for (; rs.next(); ) {
+                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
+                        result5 += rsmd.getColumnLabel(i + 1) + ":"
+                                   + rs.getString(i + 1) + ":";
+                    }
+
+                    result5 += "\n";
+                }
+
+                System.out.println(result5);
+                System.out.println("first column identity: "
+                                   + rsmd.isAutoIncrement(1));
+                rsmd.isCaseSensitive(1);
+                rsmd.isCurrency(1);
+                rsmd.isDefinitelyWritable(1);
+                rsmd.isNullable(1);
+                rsmd.isReadOnly(1);
+                rsmd.isSearchable(1);
+                rsmd.isSigned(1);
+                rsmd.isWritable(1);
+                rs.close();
+
+                // test identity with PreparedStatement
+                pstmnt = connection.prepareStatement(
+                    "INSERT INTO T VALUES (?,?,?)");
+
+                pstmnt.setString(1, null);
+                pstmnt.setString(2, "test");
+                pstmnt.setString(3, "test2");
+                pstmnt.executeUpdate();
+
+                pstmnt = connection.prepareStatement("call identity()");
+
+                ResultSet rsi = pstmnt.executeQuery();
+
+                rsi.next();
+
+                int identity = rsi.getInt(1);
+
+                System.out.println("call identity(): " + identity);
+                rsi.close();
+            }
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testMetaData complete");
+
+        // assert equality of exported and imported with xref
+        assertEquals(result1, result2);
+        assertEquals(result3, result4);
+    }
+
+    /**
+     * Demonstration of a reported bug.<p>
+     * Because all values were turned into strings with toString before
+     * PreparedStatement.executeQuery() was called, special values such as
+     * NaN were not accepted.
+     *
+     * This test can be extended to cover various conversions through JDBC
+     *
+     */
+    public void testDoubleNaN() {
+
+        double  value    = 0;
+        boolean wasEqual = false;
+        String  message  = "DB operation completed";
+        String ddl1 =
+            "DROP TABLE t1 IF EXISTS;"
+            + "CREATE TABLE t1 ( d DECIMAL, f DOUBLE, l BIGINT, i INTEGER, s SMALLINT, t TINYINT, "
+            + "dt DATE DEFAULT CURRENT_DATE, ti TIME DEFAULT CURRENT_TIME, ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP );";
+
+        try {
+            stmnt.execute(ddl1);
+
+            PreparedStatement ps = connection.prepareStatement(
+                "INSERT INTO t1 (d,f,l,i,s,t,dt,ti,ts) VALUES (?,?,?,?,?,?,?,?,?)");
+
+            ps.setString(1, "0.2");
+            ps.setDouble(2, 0.2);
+            ps.setLong(3, java.lang.Long.MAX_VALUE);
+            ps.setInt(4, Integer.MAX_VALUE);
+            ps.setInt(5, Short.MAX_VALUE);
+            ps.setInt(6, 0);
+            ps.setDate(7, new java.sql.Date(System.currentTimeMillis()));
+            ps.setTime(8, new java.sql.Time(System.currentTimeMillis()));
+            ps.setTimestamp(
+                9, new java.sql.Timestamp(System.currentTimeMillis()));
+            ps.execute();
+            ps.setInt(1, 0);
+            ps.setDouble(2, java.lang.Double.NaN);
+            ps.setLong(3, java.lang.Long.MIN_VALUE);
+            ps.setInt(4, Integer.MIN_VALUE);
+            ps.setInt(5, Short.MIN_VALUE);
+            ps.setInt(6, 0);
+
+            // allowed conversions
+            ps.setTimestamp(
+                7, new java.sql.Timestamp(System.currentTimeMillis() + 1));
+            ps.setTime(8, new java.sql.Time(System.currentTimeMillis() + 1));
+            ps.setDate(9, new java.sql.Date(System.currentTimeMillis() + 1));
+            ps.execute();
+
+            //
+            ps.setInt(1, 0);
+            ps.setDouble(2, java.lang.Double.POSITIVE_INFINITY);
+            ps.setInt(4, Integer.MIN_VALUE);
+
+            // test conversion
+            // ps.setObject(5, Boolean.TRUE); // no longer converts boolean to int
+            // ps.setBoolean(5, true);
+            ps.setObject(5, new Short((short) 2), Types.SMALLINT);
+            ps.setObject(6, new Integer(2), Types.TINYINT);
+
+            // allowed conversions
+            ps.setObject(7, new java.sql.Date(System.currentTimeMillis() + 2));
+            ps.setObject(8, new java.sql.Time(System.currentTimeMillis() + 2));
+            ps.setObject(9, new java.sql.Timestamp(System.currentTimeMillis()
+                                                   + 2));
+            ps.execute();
+            ps.setObject(1, new Float(0), Types.INTEGER);
+            ps.setObject(4, new Float(1), Types.INTEGER);
+            ps.setDouble(2, java.lang.Double.NEGATIVE_INFINITY);
+            ps.execute();
+
+            ResultSet rs =
+                stmnt.executeQuery("SELECT d, f, l, i, s*2, t FROM t1");
+            boolean result = rs.next();
+
+            value = rs.getDouble(2);
+
+//            int smallintValue = rs.getShort(3);
+            int integerValue = rs.getInt(4);
+
+            if (rs.next()) {
+                value        = rs.getDouble(2);
+                wasEqual     = Double.isNaN(value);
+                integerValue = rs.getInt(4);
+
+                // tests for conversion
+                // getInt on DECIMAL
+                integerValue = rs.getInt(1);
+            }
+
+            if (rs.next()) {
+                value    = rs.getDouble(2);
+                wasEqual = wasEqual && value == Double.POSITIVE_INFINITY;
+            }
+
+            if (rs.next()) {
+                value    = rs.getDouble(2);
+                wasEqual = wasEqual && value == Double.NEGATIVE_INFINITY;
+            }
+
+            rs = stmnt.executeQuery("SELECT MAX(i) FROM t1");
+
+            if (rs.next()) {
+                int max = rs.getInt(1);
+
+                System.out.println("Max value for i: " + max);
+            }
+
+            try {
+
+                // cause errors
+                ps.setString(5, "three");
+                assertTrue(false);
+            } catch (SQLException e) {
+                System.out.println("rubbish");
+            }
+
+            {
+                stmnt.execute("drop table CDTYPE if exists");
+
+                // test for the value MAX(column) in an empty table
+                stmnt.execute(
+                    "CREATE TABLE cdType (ID INTEGER NOT NULL, name VARCHAR(50), PRIMARY KEY(ID))");
+
+                rs = stmnt.executeQuery("SELECT MAX(ID) FROM cdType");
+
+                if (rs.next()) {
+                    int max = rs.getInt(1);
+
+                    System.out.println("Max value for ID: " + max);
+                } else {
+                    System.out.println("Max value for ID not returned");
+                }
+
+                stmnt.executeUpdate(
+                    "INSERT INTO cdType VALUES (10,'Test String');");
+                stmnt.execute("CALL IDENTITY();");
+
+                try {
+                    stmnt.executeUpdate(
+                        "INSERT INTO cdType VALUES (10,'Test String');");
+                } catch (SQLException e1) {
+                    stmnt.execute("ROLLBACK");
+                    connection.rollback();
+                }
+            }
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testDoubleNaN complete");
+
+        // assert new behaviour
+        assertEquals(true, wasEqual);
+    }
+
+    public void testAny() {
+
+        try {
+            String ddl =
+                "drop table PRICE_RELATE_USER_ORDER_V2 if exists;"
+                + "create table PRICE_RELATE_USER_ORDER_V2 "
+                + "(ID_ORDER_V2 BIGINT, ID_USER NUMERIC, DATE_CREATE TIMESTAMP)";
+            String sql = "insert into PRICE_RELATE_USER_ORDER_V2 "
+                         + "(ID_ORDER_V2, ID_USER, DATE_CREATE) " + "values "
+                         + "(?, ?, ?)";
+            Statement st = connection.createStatement();
+
+            st.execute(ddl);
+
+            PreparedStatement ps = connection.prepareStatement(sql);
+
+            ps.setLong(1, 1);
+            ps.setNull(2, Types.NUMERIC);
+            ps.setTimestamp(
+                3, new java.sql.Timestamp(System.currentTimeMillis()));
+            ps.execute();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            System.out.println("TestSql.testAny() error: " + e.getMessage());
+        }
+
+        System.out.println("testAny complete");
+    }
+
+    /**
+     * Fix for bug #1201135
+     */
+    public void testBinds() {
+
+        try {
+            PreparedStatement pstmt =
+                connection.prepareStatement("drop table test if exists");
+
+            pstmt.execute();
+
+            pstmt =
+                connection.prepareStatement("create table test (id integer)");
+
+            pstmt.execute();
+
+            pstmt =
+                connection.prepareStatement("insert into test values (10)");
+
+            pstmt.execute();
+
+            pstmt =
+                connection.prepareStatement("insert into test values (20)");
+
+            pstmt.execute();
+
+            pstmt = connection.prepareStatement(
+                "select count(*) from test where id is null");
+
+            ResultSet rs = pstmt.executeQuery();
+
+            rs.next();
+
+            int count = rs.getInt(1);
+
+            assertEquals(0, count);
+
+            pstmt =
+                connection.prepareStatement("select limit ? 2  id from test");
+
+            pstmt.setInt(1, 0);
+
+            rs = pstmt.executeQuery();
+
+            rs.next();
+
+            count = rs.getInt(1);
+
+            assertEquals(10, count);
+            pstmt.setInt(1, 1);
+
+            rs = pstmt.executeQuery();
+
+            rs.next();
+
+            count = rs.getInt(1);
+
+            assertEquals(20, count);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            System.out.println("TestSql.testBinds() error: " + e.getMessage());
+        }
+    }
+
+    // miscellaneous tests
+    public void testX1() {
+
+        String tableDDL =
+            "create table lo_attribute ( "
+            + "learningid varchar(15) not null, "
+            + "ordering integer not null,"
+            + "attribute_value_data varchar(85),"
+            + "constraint PK_LO_ATTR primary key (learningid, ordering))";
+
+        try {
+            Statement stmt = connection.createStatement();
+
+            stmt.execute("drop table lo_attribute if exists");
+            stmt.execute(tableDDL);
+            stmt.execute(
+                "insert into lo_attribute values('abcd', 10, 'cdef')");
+            stmt.execute(
+                "insert into lo_attribute values('bcde', 20, 'cdef')");
+        } catch (SQLException e) {
+            assertEquals(0, 1);
+        }
+
+        try {
+            String prepared =
+                "update lo_attribute set "
+                + " ordering = (ordering - 1) where ordering > ?";
+            PreparedStatement ps = connection.prepareStatement(prepared);
+
+            ps.setInt(1, 10);
+            ps.execute();
+        } catch (SQLException e) {
+            assertEquals(0, 1);
+        }
+
+        try {
+            connection.setAutoCommit(false);
+
+            java.sql.Savepoint savepoint =
+                connection.setSavepoint("savepoint");
+
+            connection.createStatement().executeQuery("CALL true;");
+            connection.rollback(savepoint);
+        } catch (SQLException e) {
+            assertEquals(0, 1);
+        }
+    }
+
+    /**
+     * In 1.8.0.2, this fails in client / server due to column type of the
+     * second select for b1 being boolean, while the first select is interpreted
+     * as varchar. The rowOutputBase class attempts to cast the Java Boolean
+     * into String.
+     */
+    public void testUnionColumnTypes() {
+
+        try {
+            Connection conn = newConnection();
+            Statement  stmt = conn.createStatement();
+
+            stmt.execute("DROP TABLE test1 IF EXISTS");
+            stmt.execute("DROP TABLE test2 IF EXISTS");
+            stmt.execute("CREATE TABLE test1 (id int, b1 boolean)");
+            stmt.execute("CREATE TABLE test2 (id int)");
+            stmt.execute("INSERT INTO test1 VALUES(1,true)");
+            stmt.execute("INSERT INTO test2 VALUES(2)");
+
+            ResultSet rs = stmt.executeQuery(
+                "select id,null as b1 from test2 union select id, b1 from test1");
+            Boolean[] array = new Boolean[2];
+
+            for (int i = 0; rs.next(); i++) {
+                boolean boole = rs.getBoolean(2);
+
+                array[i] = Boolean.valueOf(boole);
+
+                if (rs.wasNull()) {
+                    array[i] = null;
+                }
+            }
+
+            boolean result = (array[0] == null && array[1] == Boolean.TRUE)
+                             || (array[0] == Boolean.TRUE && array[1] == null);
+
+            assertTrue(result);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            System.out.println("TestSql.testUnionColumnType() error: "
+                               + e.getMessage());
+        }
+    }
+
+    public void testUnionSubquery() throws Exception {
+
+        Statement st = connection.createStatement();
+
+        st.execute("DROP TABLE t1 if exists;");
+        st.execute("DROP TABLE t2 if exists;");
+        st.execute(
+            "CREATE TABLE t1 (id int not null, v1 int, v2 int, primary key(id))");
+        st.execute(
+            "CREATE TABLE t2 (id int not null, v1 int, v3 int, primary key(id))");
+        st.execute("INSERT INTO t1 values(1,1,1)");
+        st.execute("INSERT INTO t1 values(2,2,2)");
+        st.execute("INSERT INTO t2 values(1,3,3)");
+
+        ResultSet rs = st.executeQuery(
+            "select t as atable, a as idvalue, b as value1, c as value2, d as value3 from("
+            + "(select 't1' as t, t1.id as a, t1.v1 as b, t1.v2 as c, null as d from t1) union"
+            + "(select 't2' as t, t2.id as a, t2.v1 as b, null as c, t2.v3 as d from t2)) order by atable, idvalue");
+
+        assertTrue(rs.next());
+        assertEquals("t1", rs.getObject("atable"));
+        assertEquals(1, rs.getInt("idvalue"));
+        assertEquals(1, rs.getInt("value1"));
+        assertEquals(1, rs.getInt("value2"));
+        assertEquals(null, rs.getObject("value3"));
+        assertTrue(rs.next());
+        assertEquals("t1", rs.getObject("atable"));
+        assertEquals(2, rs.getInt("idvalue"));
+        assertEquals(2, rs.getInt("value1"));
+        assertEquals(2, rs.getInt("value2"));
+        assertEquals(null, rs.getObject("value3"));
+        assertTrue(rs.next());
+        assertEquals("t2", rs.getObject("atable"));
+        assertEquals(1, rs.getInt("idvalue"));
+        assertEquals(3, rs.getInt("value1"));
+        assertEquals(null, rs.getObject("value2"));
+        assertEquals(3, rs.getInt("value3"));    //this fails!
+        assertFalse(rs.next());
+    }
+
+    public void testPreparedWithManyParams() throws Exception {
+
+        int    count    = 40;
+        String tabledef = "CREATE TABLE T1 (";
+
+        for (int i = 0; i < count; i++) {
+            if (i != 0) {
+                tabledef = tabledef + ',';
+            }
+
+            tabledef = tabledef + "COL_" + i + " INT NOT NULL";
+        }
+
+        tabledef += ");";
+
+        String querydef = "INSERT INTO T1(";
+
+        for (int i = 0; i < count; i++) {
+            if (i != 0) {
+                querydef = querydef + ',';
+            }
+
+            querydef = querydef + "COL_" + i;
+        }
+
+        querydef += ") VALUES (";
+
+        for (int i = 0; i < count; i++) {
+            if (i != 0) {
+                querydef = querydef + ',';
+            }
+
+            querydef = querydef + "?";
+        }
+
+        querydef += ");";
+
+        Statement st = connection.createStatement();
+
+        st.execute("DROP TABLE T1 IF EXISTS;");
+        st.execute(tabledef);
+
+        PreparedStatement ps = connection.prepareStatement(querydef);
+
+        for (int i = 0; i < count; i++) {
+            ps.setInt(i + 1, i + 311);
+        }
+
+        ps.executeUpdate();
+    }
+
+
+    static byte[] b1 = {
+        0, 1, -128, 44, 12
+    };
+    static byte[] b2 = {
+        10, 127
+    };
+
+    public void testBinaryFunction() throws Exception {
+
+        Statement sStatement = null;
+        ResultSet r;
+        boolean mismatch;
+       sStatement = connection.createStatement();
+
+        try {
+
+            // prepared statements
+            String s = "create table bintest(id int primary key, bin varbinary(100))";
+
+            sStatement.execute(s);
+
+            s = "insert into bintest values ( ?, ?)";
+
+            PreparedStatement p = connection.prepareStatement(s);
+
+            p.clearParameters();
+            p.setInt(1, 10);
+
+            p.setBytes(2, b1);
+            p.executeUpdate();
+
+            p.clearParameters();
+            p.setInt(1, 20);
+
+            p.setBytes(2, b2);
+            p.executeUpdate();
+
+            byte[]  b1n;
+            byte[]  b2n;
+
+            s = "select \"org.hsqldb.lib.ArrayUtil.countStartElementsAt\"(bin,0, ?) "
+                + "from bintest";
+            p = connection.prepareStatement(s);
+
+            p.setBytes(1, b2);
+
+            r = p.executeQuery();
+
+            r.next();
+
+            int integer1 = r.getInt(1);
+
+            r.next();
+
+            int integer2 = r.getInt(1);
+
+            s = "select \"org.hsqldb.lib.StringConverter.hexStringToByteArray\""
+                + "(\"org.hsqldb.lib.StringConverter.byteArrayToHexString\"(x'abcd')) "
+                + "from bintest";
+            r = sStatement.executeQuery(s);
+
+            r.next();
+
+            b1n = r.getBytes(1);
+
+            r.next();
+
+            b1n = r.getBytes(1);
+
+            //--
+            s = "select \"org.hsqldb.lib.StringConverter.byteArrayToHexString\"(bin) "
+                + "from bintest";
+            r = sStatement.executeQuery(s);
+
+            r.next();
+
+            b1n = r.getBytes(1);
+
+            r.next();
+
+            b1n = r.getBytes(1);
+
+            s = "create table obj(id int,o object)";
+
+            sStatement.execute(s);
+
+            s = "insert into obj values(?,?)";
+            p = connection.prepareStatement(s);
+
+            p.setInt(1, 1);
+
+            int[] ia1 = {
+                1, 2, 3
+            };
+
+            p.setObject(2, ia1);
+            p.executeUpdate();
+            p.clearParameters();
+            p.setInt(1, 2);
+
+            java.awt.Rectangle r1 = new java.awt.Rectangle(10, 11, 12, 13);
+
+            p.setObject(2, r1);
+            p.executeUpdate();
+
+            r = sStatement.executeQuery("SELECT o FROM obj ORDER BY id DESC");
+
+            r.next();
+
+            java.awt.Rectangle r2 = (java.awt.Rectangle) r.getObject(1);
+
+            if (r2.x != 10 || r2.y != 11 || r2.width != 12
+                    || r2.height != 13) {
+                throw new Exception("Object data error: Rectangle");
+            }
+
+            r.next();
+
+            int[] ia2 = (int[]) (r.getObject(1));
+
+            if (ia2[0] != 1 || ia2[1] != 2 || ia2[2] != 3 || ia2.length != 3) {
+                throw new Exception("Object data error: int[]");
+            }
+
+            sStatement.close();
+        } catch (Exception e) {
+            assertEquals(0, 1);
+        }
+    }
+
+    protected void tearDown() {
+
+        try {
+            stmnt.execute("SHUTDOWN");
+            connection.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("TestSql.tearDown() error: " + e.getMessage());
+        }
+
+        super.tearDown();
+    }
+
+    public static void main(String[] argv) {
+
+        TestResult result = new TestResult();
+        TestCase   testA  = new TestSql("testMetaData");
+        TestCase   testB  = new TestSql("testDoubleNaN");
+        TestCase   testC  = new TestSql("testAny");
+
+        testA.run(result);
+        testB.run(result);
+        testC.run(result);
+        System.out.println("TestSql error count: " + result.failureCount());
+    }
+}
diff --git a/src/org/hsqldb/test/TestSqlPersistent.java b/src/org/hsqldb/test/TestSqlPersistent.java
new file mode 100644
index 0000000..c03a37d
--- /dev/null
+++ b/src/org/hsqldb/test/TestSqlPersistent.java
@@ -0,0 +1,603 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * Test sql statements via jdbc against a database with cached tables
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ */
+public class TestSqlPersistent extends TestCase {
+
+    // change the url to reflect your preferred db location and name
+//    String url = "jdbc:hsqldb:hsql://localhost/mytest";
+    String     url = "jdbc:hsqldb:/hsql/test/testpersistent";
+    String     user;
+    String     password;
+    Statement  stmnt;
+    Connection connection;
+
+    public TestSqlPersistent(String name) {
+        super(name);
+    }
+
+    protected void setUp() throws Exception {
+
+        super.setUp();
+
+        user       = "sa";
+        password   = "";
+        stmnt      = null;
+        connection = null;
+
+        TestUtil.deleteDatabase("/hsql/test/testpersistent");
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            connection = DriverManager.getConnection(url, user, password);
+            stmnt      = connection.createStatement();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("TestSqlPersistence.setUp() error: "
+                               + e.getMessage());
+        }
+    }
+
+    /**
+     *  demonstration of bug fix #482109 - inserting Integers
+     *  and Strings with PreparedStatement.setObject() did not work;
+     *  String, Integer and Array types are inserted and retrieved<b>
+     *
+     *  demonstration of retrieving values using different getXXX methods
+     */
+    public void testInsertObject() {
+
+        Object  stringValue        = null;
+        Object  integerValue       = null;
+        Object  arrayValue         = null;
+        Object  bytearrayValue     = null;
+        Object  stringValueResult  = null;
+        Object  integerValueResult = null;
+        Object  arrayValueResult   = null;
+        boolean wasNull            = false;
+        String  message            = "DB operation completed";
+
+        try {
+            String sqlString = "DROP TABLE PREFERENCE IF EXISTS;"
+                               + "CREATE CACHED TABLE PREFERENCE ("
+                               + "User_Id INTEGER NOT NULL, "
+                               + "Pref_Name VARCHAR(30) NOT NULL, "
+                               + "Pref_Value OBJECT NOT NULL, "
+                               + "DateCreated DATETIME DEFAULT NOW NOT NULL, "
+                               + "PRIMARY KEY(User_Id, Pref_Name) )";
+
+            stmnt.execute(sqlString);
+
+            sqlString = "INSERT INTO PREFERENCE "
+                        + "(User_Id,Pref_Name,Pref_Value,DateCreated) "
+                        + "VALUES (?,?,?,current_timestamp)";
+
+            PreparedStatement ps = connection.prepareStatement(sqlString);
+
+            // initialise
+            stringValue  = "String Value for Preference 1";
+            integerValue = new Integer(1000);
+            arrayValue   = new Double[] {
+                new Double(1), new Double(Double.NaN),
+                new Double(Double.NEGATIVE_INFINITY),
+                new Double(Double.POSITIVE_INFINITY)
+            };
+            bytearrayValue = new byte[] {
+                1, 2, 3, 4, 5, 6,
+            };
+
+            // String as Object
+            ps.setInt(1, 1);
+            ps.setString(2, "String Type Object 1");
+
+// fredt - in order to store Strings in OBJECT columns setObject should
+// explicitly be called with a Types.OTHER type
+//            ps.setObject(3, stringValue); will throw an exception
+            ps.setObject(3, stringValue, Types.OTHER);
+            ps.execute();
+
+            // Integer as Object
+            ps.setInt(1, 2);
+            ps.setString(2, "Integer Type Object 2");
+
+//            ps.setObject(3, integerValue, Types.OTHER); should work too
+            ps.setObject(3, integerValue);
+            ps.execute();
+
+            // Array as object
+            ps.setInt(1, 3);
+            ps.setString(2, "Array Type Object 3");
+            /*
+            ps.setCharacterStream(
+                2, new java.io.StringReader("Array Type Object 3"), 19);
+            */
+
+            // ps.setObject(3, arrayValue, Types.OTHER); should work too
+            ps.setObject(3, arrayValue);
+            ps.execute();
+
+            // byte arrray as object
+            ps.setInt(1, 3);
+            ps.setString(2, "byte Array Type Object 3");
+            /*
+            ps.setCharacterStream(
+                2, new java.io.StringReader("byte Array Type Object 3"), 19);
+            */
+
+            // ps.setObject(3, bytearrayValue); will fail
+            // must use this to indicate we are inserting into an OTHER column
+            ps.setObject(3, bytearrayValue, Types.OTHER);
+            ps.execute();
+
+            ResultSet rs     = stmnt.executeQuery("SELECT * FROM PREFERENCE");
+            boolean   result = rs.next();
+
+            // a string can be retrieved as a String or a stream
+            // as Unicode string
+            String str = rs.getString(2);
+
+            System.out.println(str);
+
+            // as Unicode stream
+            InputStream is = rs.getUnicodeStream(2);
+            int         c;
+
+            while ((c = is.read()) > -1) {
+                c = is.read();
+
+                System.out.print((char) c);
+            }
+
+            System.out.println();
+
+            // as ASCII stream, ignoring the high order bytes
+            is = rs.getAsciiStream(2);
+
+            while ((c = is.read()) > -1) {
+                System.out.print((char) c);
+            }
+
+            System.out.println();
+
+            // JAVA 2 specific
+            // as character stream via a Reader
+            /*
+            Reader re = rs.getCharacterStream(2);
+
+            while ((c = re.read()) > -1) {
+                System.out.print((char) c);
+            }
+            */
+
+            // retrieving objects inserted into the third column
+            stringValueResult = rs.getObject(3);
+
+            rs.next();
+
+            integerValueResult = rs.getObject(3);
+
+            rs.next();
+
+            arrayValueResult = rs.getObject(3);
+
+            // how to check if the last retrieved value was null
+            wasNull = rs.wasNull();
+
+            // cast objects to original types - will throw if type is wrong
+            String   castStringValue      = (String) stringValueResult;
+            Integer  castIntegerValue     = (Integer) integerValueResult;
+            Double[] castDoubleArrayValue = (Double[]) arrayValueResult;
+
+            {
+                sqlString = "DELETE FROM PREFERENCE WHERE user_id = ?";
+
+                PreparedStatement st = connection.prepareStatement(sqlString);
+
+                st.setString(1, "2");
+
+                int ret = st.executeUpdate();
+
+                // here, ret is equal to 1, that is expected
+                //conn.commit(); // not needed, as far as AUTO_COMMIT is set to TRUE
+                st.close();
+
+                st = connection.prepareStatement(
+                    "SELECT user_id FROM PREFERENCE WHERE user_id=?");
+
+                st.setString(1, "2");
+
+                rs = st.executeQuery();
+
+                while (rs.next()) {
+                    System.out.println(rs.getString(1));
+                }
+            }
+        } catch (SQLException e) {
+            System.out.println(e.getMessage());
+        } catch (IOException e1) {}
+
+        /*
+        boolean success = stringValue.equals(stringValueResult)
+                          && integerValue.equals(integerValueResult)
+                          && java.util.Arrays.equals((Double[]) arrayValue,
+                              (Double[]) arrayValueResult);
+        */
+        boolean success = true;
+
+        assertEquals(true, success);
+    }
+
+    public void testSelectObject() throws IOException {
+
+        String   stringValue        = null;
+        Integer  integerValue       = null;
+        Double[] arrayValue         = null;
+        byte[]   byteArrayValue     = null;
+        String   stringValueResult  = null;
+        Integer  integerValueResult = null;
+        Double[] arrayValueResult   = null;
+        boolean  wasNull            = false;
+        String   message            = "DB operation completed";
+
+        try {
+            String sqlString = "DROP TABLE TESTOBJECT IF EXISTS;"
+                               + "CREATE CACHED TABLE TESTOBJECT ("
+                               + "ID INTEGER NOT NULL IDENTITY, "
+                               + "STOREDOBJECT OTHER, STOREDBIN BINARY(100) )";
+
+            stmnt.execute(sqlString);
+
+            sqlString = "INSERT INTO TESTOBJECT "
+                        + "(STOREDOBJECT, STOREDBIN) " + "VALUES (?,?)";
+
+            PreparedStatement ps = connection.prepareStatement(sqlString);
+
+            // initialise
+            stringValue  = "Test String Value";
+            integerValue = new Integer(1000);
+            arrayValue   = new Double[] {
+                new Double(1), new Double(Double.NaN),
+                new Double(Double.NEGATIVE_INFINITY),
+                new Double(Double.POSITIVE_INFINITY)
+            };
+            byteArrayValue = new byte[] {
+                1, 2, 3
+            };
+
+            // String as Object
+// fredt - in order to store Strings in OBJECT columns setObject should
+// explicitly be called with a Types.OTHER type
+            ps.setObject(1, stringValue, Types.OTHER);
+            ps.setBytes(2, byteArrayValue);
+            ps.execute();
+
+            // Integer as Object
+            ps.setObject(1, integerValue, Types.OTHER);
+            ps.setBinaryStream(2, new ByteArrayInputStream(byteArrayValue),
+                               byteArrayValue.length);
+            ps.execute();
+
+            // Array as object
+            ps.setObject(1, arrayValue, Types.OTHER);
+
+            // file as binary - works fine but file path and name has to be modified for test environment
+            /*
+            int length = (int) new File("c://ft/db.jar").length();
+            FileInputStream fis = new FileInputStream("c://ft/db.jar");
+            ps.setBinaryStream(2,fis,length);
+            */
+            ps.execute();
+
+            ResultSet rs     = stmnt.executeQuery("SELECT * FROM TESTOBJECT");
+            boolean   result = rs.next();
+
+            // retrieving objects inserted into the third column
+            stringValueResult = (String) rs.getObject(2);
+
+            rs.next();
+
+            integerValueResult = (Integer) rs.getObject(2);
+
+            rs.next();
+
+            arrayValueResult = (Double[]) rs.getObject(2);
+
+            // cast objects to original types - will throw if type is wrong
+            String   castStringValue      = (String) stringValueResult;
+            Integer  castIntegerValue     = (Integer) integerValueResult;
+            Double[] castDoubleArrayValue = (Double[]) arrayValueResult;
+
+            for (int i = 0; i < arrayValue.length; i++) {
+                if (!arrayValue[i].equals(arrayValueResult[i])) {
+                    System.out.println("array mismatch: " + arrayValue[i]
+                                       + " : " + arrayValueResult[i]);
+                }
+            }
+
+            rs.close();
+            ps.close();
+
+            sqlString = "SELECT * FROM TESTOBJECT WHERE STOREDOBJECT = ?";
+            ps        = connection.prepareStatement(sqlString);
+
+            ps.setObject(1, new Integer(1000));
+
+            rs = ps.executeQuery();
+
+            rs.next();
+
+            Object returnVal = rs.getObject(2);
+
+            rs.next();
+        } catch (SQLException e) {
+            System.out.println(e.getMessage());
+        }
+
+        boolean success = stringValue.equals(stringValueResult)
+                          && integerValue.equals(integerValueResult)
+                          && java.util.Arrays.equals((Double[]) arrayValue,
+                              (Double[]) arrayValueResult);
+
+        assertEquals(true, success);
+
+        try {
+            String            sqlString = "drop table objects if exists";
+            PreparedStatement ps = connection.prepareStatement(sqlString);
+
+            ps.execute();
+
+            sqlString =
+                "create cached table objects (object_id INTEGER IDENTITY,"
+                + "object_name VARCHAR(128) NOT NULL,role_name VARCHAR(128) NOT NULL,"
+                + "value LONGVARBINARY(1000) NOT NULL,description LONGVARCHAR(1000))";
+            ps = connection.prepareStatement(sqlString);
+
+            ps.execute();
+
+            sqlString =
+                "INSERT INTO objects VALUES(1, 'name','role',?,'description')";
+            ps = connection.prepareStatement(sqlString);
+
+            ps.setBytes(1, new byte[] {
+                1, 2, 3, 4, 5
+            });
+            ps.executeUpdate();
+
+            sqlString = "UPDATE objects SET value = ?, description = ? WHERE "
+                        + "object_name = ? AND role_name = ?";
+            ps = connection.prepareStatement(sqlString);
+
+            ps.setBytes(1, new byte[] {
+                1, 2, 3, 4, 5
+            });
+            ps.setString(2, "desc");
+            ps.setString(3, "new");
+            ps.setString(4, "role");
+            ps.executeUpdate();
+        } catch (SQLException e) {
+            System.out.println(e.getMessage());
+        }
+    }
+
+    public void testDoubleNaN() {
+        doTestDoubleNan(false);
+    }
+
+    private void doTestDoubleNan(boolean shutdown) {
+
+        double  value    = 0;
+        boolean wasEqual = false;
+        String  message  = "DB operation completed";
+        String ddl1 =
+            "DROP TABLE t1 IF EXISTS;"
+            + "CREATE TABLE t1 ( d DECIMAL, f DOUBLE, l BIGINT, i INTEGER, s SMALLINT, t TINYINT, "
+            + "dt DATE DEFAULT CURRENT_DATE, ti TIME DEFAULT CURRENT_TIME, ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP );";
+
+        try {
+            stmnt.execute(ddl1);
+
+            PreparedStatement ps = connection.prepareStatement(
+                "INSERT INTO t1 (d,f,l,i,s,t,dt,ti,ts) VALUES (?,?,?,?,?,?,?,?,?)");
+
+            ps.setString(1, "0.2");
+            ps.setDouble(2, 0.2);
+            ps.setLong(3, java.lang.Long.MAX_VALUE);
+            ps.setInt(4, Integer.MAX_VALUE);
+            ps.setInt(5, Short.MAX_VALUE);
+            ps.setInt(6, 0);
+            ps.setDate(7, new java.sql.Date(System.currentTimeMillis()));
+            ps.setTime(8, new java.sql.Time(System.currentTimeMillis()));
+            ps.setTimestamp(
+                9, new java.sql.Timestamp(System.currentTimeMillis()));
+            ps.execute();
+            ps.setInt(1, 0);
+            ps.setDouble(2, java.lang.Double.NaN);
+            ps.setLong(3, java.lang.Long.MIN_VALUE);
+            ps.setInt(4, Integer.MIN_VALUE);
+            ps.setInt(5, Short.MIN_VALUE);
+            ps.setInt(6, 0);
+
+            // allowed conversions
+            ps.setTimestamp(
+                7, new java.sql.Timestamp(System.currentTimeMillis() + 1));
+            ps.setTime(8, new java.sql.Time(System.currentTimeMillis() + 1));
+            ps.setDate(9, new java.sql.Date(System.currentTimeMillis() + 1));
+            ps.execute();
+
+            //
+            ps.setInt(1, 0);
+            ps.setDouble(2, java.lang.Double.POSITIVE_INFINITY);
+            ps.setInt(4, Integer.MIN_VALUE);
+
+            // test conversion
+            // ps.setObject(5, Boolean.TRUE); // no longer converts boolean to int
+            // ps.setBoolean(5, true);
+            ps.setObject(5, new Short((short) 2), Types.SMALLINT);
+            ps.setObject(6, new Integer(2), Types.TINYINT);
+
+            // allowed conversions
+            ps.setObject(7, new java.sql.Date(System.currentTimeMillis() + 2));
+            ps.setObject(8, new java.sql.Time(System.currentTimeMillis() + 2));
+            ps.setObject(9, new java.sql.Timestamp(System.currentTimeMillis()
+                                                   + 2));
+            ps.execute();
+            ps.setObject(1, new Float(0), Types.INTEGER);
+            ps.setObject(4, new Float(1), Types.INTEGER);
+            ps.setDouble(2, java.lang.Double.NEGATIVE_INFINITY);
+            ps.execute();
+
+            ResultSet rs =
+                stmnt.executeQuery("SELECT d, f, l, i, s*2, t FROM t1");
+            boolean result = rs.next();
+
+            value = rs.getDouble(2);
+
+//            int smallintValue = rs.getShort(3);
+            int integerValue = rs.getInt(4);
+
+            if (rs.next()) {
+                value        = rs.getDouble(2);
+                wasEqual     = Double.isNaN(value);
+                integerValue = rs.getInt(4);
+
+                // tests for conversion
+                // getInt on DECIMAL
+                integerValue = rs.getInt(1);
+            }
+
+            if (rs.next()) {
+                value    = rs.getDouble(2);
+                wasEqual = wasEqual && value == Double.POSITIVE_INFINITY;
+            }
+
+            if (rs.next()) {
+                value    = rs.getDouble(2);
+                wasEqual = wasEqual && value == Double.NEGATIVE_INFINITY;
+            }
+
+            rs = stmnt.executeQuery("SELECT MAX(i) FROM t1");
+
+            if (rs.next()) {
+                int max = rs.getInt(1);
+
+                System.out.println("Max value for i: " + max);
+            }
+
+            try {
+
+                // cause errors
+                ps.setString(5, "three");
+                assertTrue(false);
+            } catch (SQLException e) {
+                System.out.println("rubbish");
+            }
+
+            {
+                stmnt.execute("drop table CDTYPE if exists");
+
+                // test for the value MAX(column) in an empty table
+                stmnt.execute(
+                    "CREATE TABLE cdType (ID INTEGER NOT NULL, name VARCHAR(50), PRIMARY KEY(ID))");
+
+                rs = stmnt.executeQuery("SELECT MAX(ID) FROM cdType");
+
+                if (rs.next()) {
+                    int max = rs.getInt(1);
+
+                    System.out.println("Max value for ID: " + max);
+                } else {
+                    System.out.println("Max value for ID not returned");
+                }
+
+                stmnt.executeUpdate(
+                    "INSERT INTO cdType VALUES (10,'Test String');");
+                stmnt.execute("CALL IDENTITY();");
+
+                try {
+                    stmnt.executeUpdate(
+                        "INSERT INTO cdType VALUES (10,'Test String');");
+                } catch (SQLException e1) {
+                    connection.rollback();
+                }
+            }
+        } catch (SQLException e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("testDoubleNaN complete");
+
+        // assert new behaviour
+        assertEquals(true, wasEqual);
+    }
+
+    protected void tearDown() {
+
+        try {
+            stmnt.execute("SHUTDOWN");
+            connection.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("TestSql.tearDown() error: " + e.getMessage());
+        }
+    }
+
+    public static void main(String[] argv) {
+
+        TestResult result = new TestResult();
+        TestCase   testC  = new TestSqlPersistent("testInsertObject");
+        TestCase   testD  = new TestSqlPersistent("testSelectObject");
+
+        testC.run(result);
+        testD.run(result);
+        System.out.println("TestSqlPersistent error count: "
+                           + result.failureCount());
+    }
+}
diff --git a/src/org/hsqldb/test/TestStoredProcedure.java b/src/org/hsqldb/test/TestStoredProcedure.java
new file mode 100644
index 0000000..099c414
--- /dev/null
+++ b/src/org/hsqldb/test/TestStoredProcedure.java
@@ -0,0 +1,192 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * Tests for stored procedures.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.2
+ */
+public class TestStoredProcedure extends TestBase {
+
+    public TestStoredProcedure(String name) {
+        super(name);
+    }
+
+    public void testOne() throws Exception {
+
+        Connection conn = newConnection();
+        Statement  statement;
+
+        try {
+            statement = conn.createStatement();
+
+            ResultSet rs = statement.executeQuery(
+                "call \"org.hsqldb.test.TestStoredProcedure.procTest1\"()");
+
+            rs.next();
+
+            int cols = rs.getInt(1);
+
+            assertFalse("test result not correct", false);
+        } catch (Exception e) {
+        }
+
+        try {
+            statement = conn.createStatement();
+
+            statement.execute(
+            "create procedure proc1()"
+            + "SPECIFIC P2 LANGUAGE JAVA DETERMINISTIC MODIFIES SQL EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.TestStoredProcedure.procTest1'");
+
+        } catch (Exception e) {
+            assertTrue("unexpected error", true);
+        } finally {
+            conn.close();
+        }
+    }
+
+    public void testTwo() throws Exception {
+
+        Connection conn = newConnection();
+        Statement  statement;
+        int        updateCount;
+
+        try {
+            statement = conn.createStatement();
+            statement.execute("create user testuser password 'test'");
+            statement.execute("create table testtable(v varchar(20))");
+            statement.execute("insert into testtable values ('tennis'), ('tent'), ('television'), ('radio')");
+            ResultSet rs = statement.executeQuery(
+                "call \"org.hsqldb.test.TestStoredProcedure.funcTest2\"('test')");
+
+            rs.next();
+
+            boolean b = rs.getBoolean(1);
+
+            rs.close();
+            assertTrue("test result not correct", b);
+            statement.execute(
+                "create function func2(varchar(20)) returns boolean "
+                + "SPECIFIC F2 LANGUAGE JAVA DETERMINISTIC NO SQL CALLED ON NULL INPUT EXTERNAL NAME 'CLASSPATH:org.hsqldb.test.TestStoredProcedure.funcTest2'");
+
+            rs = statement.executeQuery("call func2('test')");
+
+            rs.next();
+
+            b = rs.getBoolean(1);
+
+            rs.close();
+            assertTrue("test result not correct", b);
+
+            rs = statement.executeQuery("select count(*) from testtable where func2(v)");
+
+            rs.next();
+
+            int count = rs.getInt(1);
+
+            assertTrue("test result not correct", count == 3);
+
+            statement.execute("grant execute on specific function public.f2 to testuser");
+
+
+        } catch (Exception e) {
+            assertTrue("unable to execute call to procedure", false);
+        } finally {
+            conn.close();
+        }
+    }
+
+    public static int procTest1(Connection conn) throws java.sql.SQLException {
+
+        int                cols;
+        java.sql.Statement stmt = conn.createStatement();
+
+        stmt.execute(
+            "CREATE temp TABLE MYTABLE(COL1 INTEGER,COL2 VARCHAR(10));");
+        stmt.execute("INSERT INTO MYTABLE VALUES    (1,'test1');");
+        stmt.execute("INSERT INTO MYTABLE VALUES(2,'test2');");
+
+        java.sql.ResultSet rs = stmt.executeQuery("select * from MYTABLE");
+        java.sql.ResultSetMetaData meta = rs.getMetaData();
+
+        cols = meta.getColumnCount();
+
+        rs.close();
+        stmt.close();
+
+        return cols;
+    }
+
+    public static boolean funcTest2(Connection conn,
+                                    String value)
+                                    throws java.sql.SQLException {
+
+        if (value != null && value.startsWith("te")) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        TestResult            result;
+        TestCase              test;
+        java.util.Enumeration failures;
+        int                   count;
+
+        result = new TestResult();
+        test   = new TestStoredProcedure("test");
+
+        test.run(result);
+
+        count = result.failureCount();
+
+        System.out.println("TestStoredProcedure failure count: " + count);
+
+        failures = result.failures();
+
+        while (failures.hasMoreElements()) {
+            System.out.println(failures.nextElement());
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestStressInsert.java b/src/org/hsqldb/test/TestStressInsert.java
new file mode 100644
index 0000000..f99d2e6
--- /dev/null
+++ b/src/org/hsqldb/test/TestStressInsert.java
@@ -0,0 +1,210 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Random;
+
+import org.hsqldb.jdbc.JDBCBlob;
+
+/**
+ * Test with small cache and very large row inserts
+ */
+public class TestStressInsert {
+
+    private Connection        con;
+    private PreparedStatement insertStmtA;
+    private PreparedStatement insertStmtB;
+    private static final int  LOB_SIZE = 1024 * 1024;
+    private static final int  MAX_SIZE = 4000;
+    private final Random      random   = new Random(0);
+    byte[]                    data     = getRandomBytes(LOB_SIZE);
+
+    public void init() throws Exception {
+
+        String driver = "org.hsqldb.jdbc.JDBCDriver";
+        String url    = "jdbc:hsqldb:file:/hsql/stress/test";
+//        String url    = "jdbc:hsqldb:hsql://localhost/test";
+
+        Class.forName(driver);
+
+        con = DriverManager.getConnection(url, "sa", "");
+
+        con.setAutoCommit(true);
+
+        // set cache sizes
+        Statement stmt = con.createStatement();
+
+        try {
+            stmt.execute("set files write delay 10000 millis");
+            stmt.execute("set files log size " + 200);
+
+            stmt.execute("set files backup increment true");
+
+            DatabaseMetaData metaData = con.getMetaData();
+            ResultSet        rs = metaData.getTables(null, null, "B", null);
+            boolean          schemaExists;
+
+            try {
+                schemaExists = rs.next();
+            } finally {
+                rs.close();
+            }
+
+            if (!schemaExists) {
+                stmt.execute(
+                    "create cached table A (ID binary(16) PRIMARY KEY, DATA longvarbinary not null)");
+                stmt.execute(
+                    "create cached table B (ID binary(16) PRIMARY KEY, DATA BLOB(10M) not null)");
+            }
+
+            stmt.execute("checkpoint");
+        } finally {
+            stmt.close();
+        }
+
+        // prepare statements
+        insertStmtA =
+            con.prepareStatement("insert into A (DATA, ID) values (?, ?)");
+        insertStmtB =
+            con.prepareStatement("insert into B (DATA, ID) values (?, ?)");
+    }
+
+    public void shutdown() throws Exception {
+
+        insertStmtA.close();
+        insertStmtB.close();
+
+        Statement stmt = con.createStatement();
+
+        stmt.executeUpdate("SHUTDOWN");
+        con.close();
+    }
+
+    public void insertA(byte[] id) throws Exception {
+
+        try {
+            insertStmtA.setBytes(1, data);
+            insertStmtA.setBytes(2, id);
+            insertStmtA.execute();
+        } finally {
+            insertStmtA.clearParameters();
+            insertStmtA.clearWarnings();
+        }
+    }
+
+    public void insertB(byte[] id) throws Exception {
+
+        try {
+            insertStmtB.setBlob(1, new JDBCBlob(data));
+            insertStmtB.setBytes(2, id);
+            insertStmtB.execute();
+        } finally {
+            insertStmtB.clearParameters();
+            insertStmtB.clearWarnings();
+        }
+    }
+
+    private void stressInsertA() throws Exception {
+
+        long t1 = System.currentTimeMillis();
+        long t2 = System.currentTimeMillis();
+
+        System.out.println("done " + (t2 - t1));
+
+        for (int i = 0; i < MAX_SIZE; i++) {
+            insertA(getRandomBytes(16));
+
+            if (i % 100 == 0) {
+                long t3 = System.currentTimeMillis();
+
+                System.out.println("inserted " + i + ", 100 in " + (t3 - t2));
+
+                t2 = t3;
+            }
+        }
+
+        System.out.println("total inserted " + MAX_SIZE + " in " + (t2 - t1));
+        shutdown();
+    }
+
+    private void stressInsertB() throws Exception {
+
+        long t1 = System.currentTimeMillis();
+        long t2 = System.currentTimeMillis();
+
+        System.out.println("done " + (t2 - t1));
+
+        for (int i = 0; i < MAX_SIZE; i++) {
+            insertB(getRandomBytes(16));
+
+            if (i % 100 == 0) {
+                long t3 = System.currentTimeMillis();
+
+                System.out.println("inserted " + i + ", 100 in " + (t3 - t2));
+
+                t2 = t3;
+            }
+        }
+
+        System.out.println("total inserted " + MAX_SIZE + " in " + (t2 - t1));
+        shutdown();
+    }
+
+    public static void main(String[] args) {
+
+        try {
+            System.out.print("Initializing...");
+
+            TestStressInsert test = new TestStressInsert();
+
+            test.init();
+            test.stressInsertB();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private byte[] getRandomBytes(int length) {
+
+        byte[] ret = new byte[length];
+
+        random.nextBytes(ret);
+
+        return ret;
+    }
+}
diff --git a/src/org/hsqldb/test/TestSubQueriesInPreparedStatements.java b/src/org/hsqldb/test/TestSubQueriesInPreparedStatements.java
new file mode 100644
index 0000000..1457955
--- /dev/null
+++ b/src/org/hsqldb/test/TestSubQueriesInPreparedStatements.java
@@ -0,0 +1,161 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * TestSubQueriesInPreparedStatements.java
+ *
+ * Created on July 9, 2003, 4:03 PM
+ */
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+/**
+ *
+ * @author boucherb@users
+ */
+public class TestSubQueriesInPreparedStatements {
+
+    public static void main(String[] args) throws Exception {
+        test();
+    }
+
+    public static void test() throws Exception {
+
+        Connection        conn;
+        Statement         stmnt;
+        PreparedStatement pstmnt;
+        Driver            driver;
+
+        driver =
+            (Driver) Class.forName("org.hsqldb.jdbc.JDBCDriver").newInstance();
+
+        DriverManager.registerDriver(driver);
+
+        conn = DriverManager.getConnection("jdbc:hsqldb:mem:test", "sa", "");
+        stmnt  = conn.createStatement();
+        pstmnt = conn.prepareStatement("drop table t if exists");
+
+        boolean result = pstmnt.execute();
+
+        pstmnt = conn.prepareStatement("create table t(i decimal)");
+
+        int updatecount = pstmnt.executeUpdate();
+
+        pstmnt = conn.prepareStatement("insert into t values(?)");
+
+        for (int i = 0; i < 100; i++) {
+            pstmnt.setInt(1, i);
+            pstmnt.executeUpdate();
+        }
+
+        pstmnt = conn.prepareStatement(
+            "select * from (select * from t where i < ?)");
+
+        System.out.println("Expecting: 0..3");
+        pstmnt.setInt(1, 4);
+
+        ResultSet rs = pstmnt.executeQuery();
+
+        while (rs.next()) {
+            System.out.println(rs.getInt(1));
+        }
+
+        System.out.println("Expecting: 0..4");
+        pstmnt.setInt(1, 5);
+
+        rs = pstmnt.executeQuery();
+
+        while (rs.next()) {
+            System.out.println(rs.getInt(1));
+        }
+
+        pstmnt = conn.prepareStatement(
+            "select sum(i) from (select i from t where i between ? and ?)");
+
+        System.out.println("Expecting: 9");
+        pstmnt.setInt(1, 4);
+        pstmnt.setInt(2, 5);
+
+        rs = pstmnt.executeQuery();
+
+        while (rs.next()) {
+            System.out.println(rs.getInt(1));
+        }
+
+        System.out.println("Expecting: 15");
+        pstmnt.setInt(2, 6);
+
+        rs = pstmnt.executeQuery();
+
+        while (rs.next()) {
+            System.out.println(rs.getInt(1));
+        }
+
+        pstmnt = conn.prepareStatement(
+            "select * from (select i as c1 from t where i < ?) a, (select i as c2 from t where i < ?) b");
+
+        System.out.println("Expecting: (0,0)");
+        pstmnt.setInt(1, 1);
+        pstmnt.setInt(2, 1);
+
+        rs = pstmnt.executeQuery();
+
+        while (rs.next()) {
+            System.out.println("(" + rs.getInt(1) + "," + rs.getInt(2) + ")");
+        }
+
+        System.out.println("Expecting: ((0,0), (0,1), (1,0), (1,1)");
+        pstmnt.setInt(1, 2);
+        pstmnt.setInt(2, 2);
+
+        rs = pstmnt.executeQuery();
+
+        while (rs.next()) {
+            System.out.println("(" + rs.getInt(1) + "," + rs.getInt(2) + ")");
+        }
+
+        System.out.println("Expecting: ((0,0) .. (3,3)");
+        pstmnt.setInt(1, 4);
+        pstmnt.setInt(2, 4);
+
+        rs = pstmnt.executeQuery();
+
+        while (rs.next()) {
+            System.out.println("(" + rs.getInt(1) + "," + rs.getInt(2) + ")");
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestSubselect.java b/src/org/hsqldb/test/TestSubselect.java
new file mode 100644
index 0000000..ad00f6f
--- /dev/null
+++ b/src/org/hsqldb/test/TestSubselect.java
@@ -0,0 +1,447 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+
+/**
+ * Test cases for HSQL subselects.
+ *
+ * @author David Moles Apr 30, 2002
+ */
+
+// fredt@users - modified to remove dependecy on DBUnit
+public class TestSubselect extends TestCase {
+
+    //------------------------------------------------------------
+    // Class variables
+    //------------------------------------------------------------
+    private static final String databaseDriver = "org.hsqldb.jdbc.JDBCDriver";
+    private static final String databaseURL =
+        "jdbc:hsqldb:/hsql/test/subselect";
+    private static final String databaseUser     = "sa";
+    private static final String databasePassword = "";
+
+    //------------------------------------------------------------
+    // Instance variables
+    //------------------------------------------------------------
+    private Connection jdbcConnection;
+
+    //------------------------------------------------------------
+    // Constructors
+    //------------------------------------------------------------
+
+    /**
+     * Constructs a new SubselectTest.
+     */
+    public TestSubselect(String s) {
+        super(s);
+    }
+
+    //------------------------------------------------------------
+    // Class methods
+    //------------------------------------------------------------
+    protected static Connection getJDBCConnection() throws SQLException {
+        return DriverManager.getConnection(databaseURL, databaseUser,
+                                           databasePassword);
+    }
+
+    protected void setUp() throws Exception {
+
+        TestUtil.deleteDatabase("/hsql/test/subselect");
+        Class.forName(databaseDriver);
+
+        jdbcConnection = getJDBCConnection();
+
+        createDataset();
+    }
+
+    protected void tearDown() throws Exception {
+
+        jdbcConnection.close();
+
+        jdbcConnection = null;
+
+        super.tearDown();
+    }
+
+    void createDataset() throws SQLException {
+
+        Statement statement = jdbcConnection.createStatement();
+
+        statement.execute("drop table colors if exists; "
+                          + "drop table sizes if exists; "
+                          + "drop table fruits if exists; "
+                          + "drop table trees if exists; ");
+        statement.execute("create table colors(id int, val varchar(10)); ");
+        statement.execute("insert into colors values(1,'red'); "
+                          + "insert into colors values(2,'green'); "
+                          + "insert into colors values(3,'orange'); "
+                          + "insert into colors values(4,'indigo'); ");
+        statement.execute("create table sizes(id int, val varchar(10)); ");
+        statement.execute("insert into sizes values(1,'small'); "
+                          + "insert into sizes values(2,'medium'); "
+                          + "insert into sizes values(3,'large'); "
+                          + "insert into sizes values(4,'odd'); ");
+        statement.execute(
+            "create table fruits(id int, name varchar(20), color_id int); ");
+        statement.execute(
+            "insert into fruits values(1, 'golden delicious',2); "
+            + "insert into fruits values(2, 'macintosh',1); "
+            + "insert into fruits values(3, 'red delicious',1); "
+            + "insert into fruits values(4, 'granny smith',2); "
+            + "insert into fruits values(5, 'tangerine',4);");
+        statement.execute(
+            "create table trees(id int, name varchar(30), fruit_id int, size_id int); ");
+        statement.execute(
+            "insert into trees values(1, 'small golden delicious tree',1,1); "
+            + "insert into trees values(2, 'large macintosh tree',2,3); "
+            + "insert into trees values(3, 'large red delicious tree',3,3); "
+            + "insert into trees values(4, 'small red delicious tree',3,1); "
+            + "insert into trees values(5, 'medium granny smith tree',4,2); ");
+        statement.close();
+    }
+
+    //------------------------------------------------------------
+    // Helper methods
+    //------------------------------------------------------------
+    private static void compareResults(String sql, String[] expected,
+                                       Connection jdbcConnection)
+                                       throws SQLException {
+
+        Statement statement = jdbcConnection.createStatement();
+        ResultSet results   = statement.executeQuery(sql);
+        int       rowCount  = 0;
+
+        while (results.next()) {
+            assertTrue("Statement <" + sql + "> returned too many rows.",
+                       (rowCount < expected.length));
+            assertEquals("Statement <" + sql + "> returned wrong value.",
+                         expected[rowCount], results.getString(1));
+
+            rowCount++;
+        }
+
+        assertEquals("Statement <" + sql + "> returned wrong number of rows.",
+                     expected.length, rowCount);
+    }
+
+    //------------------------------------------------------------
+    // Test methods
+    //------------------------------------------------------------
+
+    /**
+     * This test is basically a sanity check of the data set.
+     */
+    public void testSimpleJoin() throws SQLException {
+
+        String sql =
+            "select trees.id, trees.name, sizes.val, fruits.name, colors.val"
+            + " from trees, sizes, fruits, colors"
+            + " where trees.size_id = sizes.id"
+            + " and trees.fruit_id = fruits.id"
+            + " and fruits.color_id = colors.id" + " order by 1";
+        int      expectedRows  = 5;
+        String[] expectedTrees = new String[] {
+            "small golden delicious tree", "large macintosh tree",
+            "large red delicious tree", "small red delicious tree",
+            "medium granny smith tree"
+        };
+        String[] expectedSizes  = new String[] {
+            "small", "large", "large", "small", "medium"
+        };
+        String[] expectedFruits = new String[] {
+            "golden delicious", "macintosh", "red delicious", "red delicious",
+            "granny smith"
+        };
+        String[]  expectedColors = new String[] {
+            "green", "red", "red", "red", "green"
+        };
+        Statement statement      = jdbcConnection.createStatement();
+        ResultSet results        = statement.executeQuery(sql);
+        String[]  trees          = new String[expectedRows];
+        String[]  fruits         = new String[expectedRows];
+        String[]  sizes          = new String[expectedRows];
+        String[]  colors         = new String[expectedRows];
+        int       rowCount       = 0;
+
+        while (results.next()) {
+            assertTrue("Statement <" + sql + "> returned too many rows.",
+                       (rowCount <= expectedRows));
+            assertEquals("Statement <" + sql
+                         + "> returned rows in wrong order.", (1 + rowCount),
+                             results.getInt(1));
+            assertEquals("Statement <" + sql + "> returned wrong value.",
+                         expectedTrees[rowCount], results.getString(2));
+            assertEquals("Statement <" + sql + "> returned wrong value.",
+                         expectedSizes[rowCount], results.getString(3));
+            assertEquals("Statement <" + sql + "> returned wrong value.",
+                         expectedFruits[rowCount], results.getString(4));
+            assertEquals("Statement <" + sql + "> returned wrong value.",
+                         expectedColors[rowCount], results.getString(5));
+
+            rowCount++;
+        }
+
+        assertEquals("Statement <" + sql + "> returned wrong number of rows.",
+                     expectedRows, rowCount);
+    }
+
+    /**
+     * Inner select with where clause in outer select having column with same name as where clause in inner select
+     */
+    public void testWhereClausesColliding() throws SQLException {
+
+        String sql =
+            "select name from fruits where id in (select fruit_id from trees where id < 3) order by name";
+        String[] expected = new String[] {
+            "golden delicious", "macintosh"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * As above, with table aliases.
+     */
+    public void testWhereClausesCollidingWithAliases() throws SQLException {
+
+        String sql =
+            "select a.name from fruits a where a.id in (select b.fruit_id from trees b where b.id < 3) order by name";
+        String[] expected = new String[] {
+            "golden delicious", "macintosh"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * Inner select with two tables having columns with the same name, one of which is referred to in the
+     * subselect, the other of which is not used in the query (both FRUITS and TREES have NAME column,
+     * but we're only selecting FRUITS.NAME and we're not referring to TREES.NAME at all).
+     */
+    public void testHiddenCollision() throws SQLException {
+
+        String sql =
+            "select name from fruits where id in (select fruit_id from trees) order by name";
+        String[] expected = new String[] {
+            "golden delicious", "granny smith", "macintosh", "red delicious"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * As above, with table aliases.
+     */
+    public void testHiddenCollisionWithAliases() throws SQLException {
+
+        String sql =
+            "select a.name from fruits a where a.id in (select b.fruit_id from trees b) order by a.name";
+        String[] expected = new String[] {
+            "golden delicious", "granny smith", "macintosh", "red delicious"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * Inner select with where clause in outer select having column with same name as select clause in inner select
+     */
+    public void testWhereSelectColliding() throws SQLException {
+
+        // Yes, this is a nonsensical query
+        String sql =
+            "select val from colors where id in (select id from trees where fruit_id = 3) order by val";
+        String[] expected = new String[] {
+            "indigo", "orange"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * As above, with aliases.
+     */
+    public void testWhereSelectCollidingWithAliases() throws SQLException {
+
+        // Yes, this is a nonsensical query
+        String sql =
+            "select a.val from colors a where a.id in (select b.id from trees b where b.fruit_id = 3) order by a.val";
+        String[] expected = new String[] {
+            "indigo", "orange"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * Inner select involving same table
+     */
+    public void testSameTable() throws SQLException {
+
+        String sql =
+            "select name from trees where id in (select id from trees where fruit_id = 3) order by name";
+        String[] expected = new String[] {
+            "large red delicious tree", "small red delicious tree"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * As above with aliases.
+     */
+    public void testSameTableWithAliases() throws SQLException {
+
+        String sql =
+            "select a.name from trees a where a.id in (select b.id from trees b where b.fruit_id = 3) order by a.name";
+        String[] expected = new String[] {
+            "large red delicious tree", "small red delicious tree"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     *     Inner select involving same table as one of two joined tables in outer select
+     */
+    public void testSameTableWithJoin() throws SQLException {
+
+        String sql =
+            "select sizes.val from trees, sizes where sizes.id = trees.size_id and trees.id in (select id from trees where fruit_id = 3) order by sizes.val";
+        String[] expected = new String[] {
+            "large", "small"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * Tests two subselects, anded.
+     */
+    public void testAndedSubselects() throws SQLException {
+
+        String sql =
+            "select name from trees where size_id in (select id from sizes where val = 'large') and fruit_id in (select id from fruits where color_id = 1) order by name";
+        String[] expected = new String[] {
+            "large macintosh tree", "large red delicious tree"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * Test nested subselects.
+     */
+    public void testNestedSubselects() throws SQLException {
+
+        String sql =
+            "select name from trees where fruit_id in (select id from fruits where color_id in (select id from colors where val = 'red')) order by name";
+        String[] expected = new String[] {
+            "large macintosh tree", "large red delicious tree",
+            "small red delicious tree"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * Inner select with "not in" in outer select where clause.
+     */
+    public void testNotIn() throws SQLException {
+
+        String sql =
+            "select name from fruits where id not in (select fruit_id from trees) order by name";
+        String[] expected = new String[]{ "tangerine" };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * Inner select with "not in" in outer select where clause and same table in inner select where clause.
+     */
+    public void testNotInSameTableAndColumn() throws SQLException {
+
+        String sql =
+            "select name from fruits where id not in (select id from fruits where color_id > 1 ) order by name";
+        String[] expected = new String[] {
+            "macintosh", "red delicious"
+        };
+
+        compareResults(sql, expected, jdbcConnection);
+    }
+
+    /**
+     * Inner select reusing alias names from outer select, but using them for different tables
+     */
+    public void testAliasScope() throws SQLException {
+
+        String sql =
+            "select a.val, b.name from sizes a, trees b where a.id = b.size_id and b.id in (select a.id from trees a, fruits b where a.fruit_id = b.id and b.name='red delicious') order by a.val";
+        String[] expectedSizes = new String[] {
+            "large", "small"
+        };
+        String[] expectedTrees = new String[] {
+            "large red delicious tree", "small red delicious tree"
+        };
+
+        assertEquals(
+            "Programmer error: expected arrays should be of equal length.",
+            expectedSizes.length, expectedTrees.length);
+
+        Statement statement = jdbcConnection.createStatement();
+        ResultSet results   = statement.executeQuery(sql);
+        int       rowCount  = 0;
+
+        while (results.next()) {
+            assertTrue("Statement <" + sql + "> returned too many rows.",
+                       (rowCount < expectedSizes.length));
+            assertEquals("Statement <" + sql + "> returned wrong value.",
+                         expectedSizes[rowCount], results.getString(1));
+            assertEquals("Statement <" + sql + "> returned wrong value.",
+                         expectedTrees[rowCount], results.getString(2));
+
+            rowCount++;
+        }
+
+        assertEquals("Statement <" + sql + "> returned wrong number of rows.",
+                     expectedSizes.length, rowCount);
+    }
+}
diff --git a/src/org/hsqldb/test/TestTextTable.java b/src/org/hsqldb/test/TestTextTable.java
new file mode 100644
index 0000000..194326e
--- /dev/null
+++ b/src/org/hsqldb/test/TestTextTable.java
@@ -0,0 +1,569 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.sql.SQLException;
+
+import org.hsqldb.lib.FileUtil;
+
+/** test various text table features
+ *
+ * @author frank.schoenheit@sun.com
+ */
+public class TestTextTable extends TestBase {
+
+    java.sql.Statement  m_statement;
+    java.sql.Connection m_connection;
+
+    private class TextTableDescriptor {
+
+        private String     m_name;
+        private String     m_columnSpec;
+        private String     m_separator;
+        private String     m_separatorSpec;
+        private Object[][] m_data;
+
+        public TextTableDescriptor(String name, String columnSpec,
+                                   String separator, String separatorSpec,
+                                   Object[][] data) {
+
+            m_name          = name;
+            m_columnSpec    = columnSpec;
+            m_separator     = separator;
+            m_separatorSpec = separatorSpec;
+            m_data          = data;
+        }
+
+        public final String getName() {
+            return m_name;
+        }
+
+        public final String getColumnSpec() {
+            return m_columnSpec;
+        }
+
+        public final String getSeparator() {
+            return m_separator;
+        }
+
+        public final String getSeparatorSpec() {
+            return m_separatorSpec;
+        }
+
+        public final Object[][] getData() {
+            return m_data;
+        }
+
+        public final Object[][] appendRowData(Object[] rowData) {
+
+            Object[][] newData = new Object[m_data.length + 1][rowData.length];
+
+            for (int row = 0; row < m_data.length; ++row) {
+                newData[row] = m_data[row];
+            }
+
+            newData[m_data.length] = rowData;
+            m_data                 = newData;
+
+            return m_data;
+        }
+
+        /**
+         * creates a text file as described by this instance
+         */
+        private void createTextFile() {
+
+            PrintStream textFile = null;
+
+            try {
+                String completeFileName = m_name + ".csv";
+
+                textFile = new PrintStream(
+                    FileUtil.getFileUtil().openOutputStreamElement(
+                        completeFileName));
+
+                new java.io.File(completeFileName).deleteOnExit();
+            } catch (IOException ex) {
+                fail(ex.toString());
+            }
+
+            for (int row = 0; row < m_data.length; ++row) {
+                StringBuffer buf      = new StringBuffer();
+                int          colCount = m_data[row].length;
+
+                for (int col = 0; col < colCount; ++col) {
+                    buf.append(m_data[row][col].toString());
+
+                    if (col + 1 != colCount) {
+                        buf.append(m_separator);
+                    }
+                }
+
+                textFile.println(buf.toString());
+            }
+
+            textFile.close();
+        }
+
+        private String getDataSourceSpec() {
+            return m_name + ".csv;encoding=UTF-8;fs=" + m_separatorSpec;
+        }
+
+        private void createTable(java.sql.Connection connection)
+        throws SQLException {
+
+            String createTable = "DROP TABLE \"" + m_name + "\" IF EXISTS;";
+
+            createTable += "CREATE TEXT TABLE \"" + m_name + "\" ( "
+                           + m_columnSpec + " );";
+
+            connection.createStatement().execute(createTable);
+
+            boolean test = isReadOnly(m_name);
+            String setTableSource = "SET TABLE \"" + m_name + "\" SOURCE \""
+                                    + getDataSourceSpec() + "\"";
+
+            connection.createStatement().execute(setTableSource);
+        }
+    }
+    ;
+
+    TextTableDescriptor m_products = new TextTableDescriptor("products",
+        "ID INTEGER PRIMARY KEY, \"name\" VARCHAR(20)", "\t", "\\t",
+        new Object[][] {
+        new Object[] {
+            new Integer(1), "Apples"
+        }, new Object[] {
+            new Integer(2), "Oranges"
+        }
+    });
+    TextTableDescriptor m_customers = new TextTableDescriptor("customers",
+        "ID INTEGER PRIMARY KEY," + "\"name\" VARCHAR(50),"
+        + "\"address\" VARCHAR(50)," + "\"city\" VARCHAR(50),"
+        + "\"postal\" VARCHAR(50)", ";", "\\semi", new Object[][] {
+        new Object[] {
+            new Integer(1), "Food, Inc.", "Down Under", "Melbourne", "509"
+        }, new Object[] {
+            new Integer(2), "Simply Delicious", "Down Under", "Melbourne",
+            "518"
+        }, new Object[] {
+            new Integer(3), "Pure Health", "10 Fish St.", "San Francisco",
+            "94107"
+        }
+    });
+
+    /** Creates a new instance of TestTextTable */
+    public TestTextTable(String testName) {
+        super(testName, null, false, false);
+    }
+
+    /**
+     * sets up all text files for the test database
+     */
+    private void setupTextFiles() {
+        m_products.createTextFile();
+        m_customers.createTextFile();
+    }
+
+    /**
+     * creates the database tables needed for the test
+     */
+    private void setupDatabase() {
+
+        try {
+            m_connection = newConnection();
+            m_statement  = m_connection.createStatement();
+
+            m_products.createTable(m_connection);
+            m_customers.createTable(m_connection);
+        } catch (SQLException ex) {
+            fail(ex.toString());
+        }
+    }
+
+    public void setUp() {
+
+        super.setUp();
+        setupTextFiles();
+        setupDatabase();
+    }
+
+    protected void tearDown() {
+        executeStatement("SHUTDOWN");
+        super.tearDown();
+    }
+
+    /**
+     * returns the data source definition for a given text table
+     */
+    private String getDataSourceSpec(String tableName) {
+
+        String spec = null;
+
+        try {
+            java.sql.ResultSet results = m_statement.executeQuery(
+                "SELECT DATA_SOURCE_DEFINTION FROM INFORMATION_SCHEMA.SYSTEM_TEXTTABLES "
+                + "WHERE TABLE_NAME='" + tableName + "'");
+
+            results.next();
+
+            spec = results.getString(1);
+        } catch (SQLException ex) {
+            fail("getDataSourceSpec(" + tableName + ") failed: "
+                 + ex.toString());
+        }
+
+        return spec;
+    }
+
+    /**
+     * determines whether a given table is currently read-only
+     */
+    private boolean isReadOnly(String tableName) {
+
+        boolean isReadOnly = true;
+
+        try {
+            java.sql.ResultSet systemTables = m_statement.executeQuery(
+                "SELECT READ_ONLY FROM INFORMATION_SCHEMA.SYSTEM_TABLES "
+                + "WHERE TABLE_NAME='" + m_products.getName() + "'");
+
+            systemTables.next();
+
+            isReadOnly = systemTables.getBoolean(1);
+        } catch (SQLException ex) {
+            fail("isReadOnly(" + tableName + ") failed: " + ex.toString());
+        }
+
+        return isReadOnly;
+    }
+
+    /**
+     * checks different field separators
+     */
+    private void checkSeparators() {
+
+        String[][] separators = new String[][] {
+
+            // special separators
+            new String[] {
+                ";", "\\semi"
+            }, new String[] {
+                "\"", "\\quote"
+            }, new String[] {
+                " ", "\\space"
+            }, new String[] {
+                "'", "\\apos"
+            },
+
+            //new String[] { "\n", "\\n" },
+            // doesn't work as expected - seems I don't understand how this is intended to work?
+            new String[] {
+                "\t", "\\t"
+            }, new String[] {
+                "\\", "\\"
+            },
+
+            // some arbitrary separators which need not to be escaped
+            new String[] {
+                ".", "."
+            }, new String[] {
+                "-", "-"
+            }, new String[] {
+                "#", "#"
+            }, new String[] {
+                ",", ","
+            }
+
+            // unicode character
+            //new String[] { "\u1234", "\\u1234" }
+            // doesn't work. How do I specify in a FileOutputStream which encoding to use when writing
+            // strings?
+        };
+
+        for (int i = 0; i < separators.length; ++i) {
+            String separator     = separators[i][0];
+            String separatorSpec = separators[i][1];
+
+            // create the file
+            String tableName = "customers_" + i;
+            TextTableDescriptor tempCustomersDesc =
+                new TextTableDescriptor(tableName,
+                                        m_customers.getColumnSpec(),
+                                        separator, separatorSpec,
+                                        m_customers.getData());
+
+            tempCustomersDesc.createTextFile();
+
+            try {
+                tempCustomersDesc.createTable(m_connection);
+            } catch (Throwable t) {
+                fail("checkSeparators: separator '" + separatorSpec
+                     + "' doesn't work: " + t.toString());
+            }
+
+            executeStatement("SET TABLE \"" + tableName + "\" SOURCE OFF");
+            executeStatement("DROP TABLE \"" + tableName + "\"");
+        }
+    }
+
+    /**
+     * verifies the content of a given table is as expected
+     *  @param tableName
+     *      the name of the table whose content is to check
+     *  @param expectedValues
+     *      the values expected in the table
+     */
+    private void verifyTableContent(String tableName,
+                                    Object[][] expectedValues) {
+
+        String selectStmt = "SELECT * FROM \"" + tableName + "\" ORDER BY ID";
+
+        try {
+            java.sql.ResultSet results = m_statement.executeQuery(selectStmt);
+            int                row     = 0;
+
+            while (results.next()) {
+                row = results.getRow();
+
+                Object[] expectedRowContent = expectedValues[row - 1];
+
+                for (int col = 0; col < expectedRowContent.length; ++col) {
+                    Object expectedValue = expectedRowContent[col];
+                    Object foundValue    = results.getObject(col + 1);
+
+                    assertEquals("table " + tableName + ", row " + row
+                                 + ", column " + col + ":", expectedValue,
+                                     foundValue);
+                }
+            }
+
+            // finally ensure that there are not more rows in the table than expected
+            assertEquals("table " + tableName + "'s row count: ",
+                         expectedValues.length, row);
+        } catch (junit.framework.AssertionFailedError e) {
+            throw e;
+        } catch (Throwable t) {
+            fail("verifyTableContent(" + tableName + ") failed with "
+                 + t.toString());
+        }
+    }
+
+    /**
+     * executes a given m_statement
+     *
+     *  <p>Basically, this method calls <code>m_statement.execute(sql)</code>,
+     *  but wraps any <code>SQLException</code>s into a JUnit error.
+     */
+    private void executeStatement(String sql) {
+
+        try {
+            m_statement.execute(sql);
+        } catch (SQLException ex) {
+            fail(ex.toString());
+        }
+    }
+
+    /**
+     * verifies the initial content of the "products" text table, plus a simple insertion
+     */
+    private void verifyInitialContent() {
+        verifyTableContent(m_products.getName(), m_products.getData());
+        verifyTableContent(m_customers.getName(), m_customers.getData());
+    }
+
+    /**
+     * does some very basic insertion tests
+     */
+    private void checkInsertions() {
+
+        // check whether inserting a value succeeds
+        executeStatement("INSERT INTO \"" + m_products.getName()
+                         + "\" VALUES ( 3, 'Pears' )");
+        verifyTableContent(m_products.getName(),
+                           m_products.appendRowData(new Object[] {
+            new Integer(3), "Pears"
+        }));
+
+        // check whether the PK constraint works
+        try {
+            m_statement.execute("INSERT INTO \"" + m_products.getName()
+                                + "\" VALUES ( 1, 'Green Apples' )");
+            fail("PKs do not work as expected.");
+        } catch (SQLException e) {}
+    }
+
+    /**
+     * verifies whether implicit and explicit dis/connections from/to the text table source work
+     *  as expected
+     */
+    private void checkSourceConnection() {
+
+        String sqlSetTable = "SET TABLE \"" + m_products.getName() + "\"";
+
+        // preconditions for the following tests
+        assertEquals(
+            "internal error: retrieving the data source does not work properly at all.",
+            m_products.getDataSourceSpec(),
+            getDataSourceSpec(m_products.getName()));
+        assertFalse("internal error: table should not be read-only, initially",
+                    isReadOnly(m_products.getName()));
+
+        // disconnect, see if the table behaves well afterwards
+        executeStatement(sqlSetTable + " SOURCE OFF");
+        assertEquals(
+            "Disconnecting a text table should not reset the table source.",
+            m_products.getDataSourceSpec(),
+            getDataSourceSpec(m_products.getName()));
+        assertTrue(
+            "Disconnecting from the table source should put the table into read-only mode.",
+            isReadOnly(m_products.getName()));
+
+        try {
+            java.sql.ResultSet tableContent =
+                m_statement.executeQuery("SELECT * FROM \""
+                                         + m_products.getName() + "\"");
+
+            assertFalse("A disconnected table should be empty.",
+                        tableContent.next());
+        } catch (SQLException ex) {
+            fail("Selecting from a disconnected table should return an empty result set.");
+        }
+
+        // reconnect, see if the table works as expected then
+        executeStatement(sqlSetTable + " SOURCE ON");
+        verifyTableContent(m_products.getName(), m_products.getData());
+
+        // check whether dis-/reconnecting a readonly table preserves the readonly-ness
+        executeStatement(sqlSetTable + " READONLY TRUE");
+        assertTrue("Setting the table to read-only failed.",
+                   isReadOnly(m_products.getName()));
+        executeStatement(sqlSetTable + " SOURCE OFF");
+        assertTrue("Still, a disconnected table should be read-only.",
+                   isReadOnly(m_products.getName()));
+        executeStatement(sqlSetTable + " SOURCE ON");
+        assertTrue(
+            "A reconnected readonly table should preserve its readonly-ness.",
+            isReadOnly(m_products.getName()));
+        executeStatement(sqlSetTable + " READONLY FALSE");
+        assertFalse("Unable to reset the readonly-ness.",
+                    isReadOnly(m_products.getName()));
+
+        // check whether setting an invalid data source sets the table to readonly, by
+        // preserving the data source
+        try {
+
+            // create a malformed file
+            String fileName = "malformed.csv";
+            PrintStream textFile = new PrintStream(
+                FileUtil.getFileUtil().openOutputStreamElement(fileName));
+
+            textFile.println("not a number;some text");
+            textFile.close();
+            new java.io.File(fileName).deleteOnExit();
+
+            // try setting it as source
+            String newDataSourceSpec = fileName + ";encoding=UTF-8;fs=\\semi";
+
+            try {
+                m_statement.execute(sqlSetTable + " SOURCE \""
+                                    + newDataSourceSpec + "\"");
+                fail("a malformed data source was accepted silently.");
+            } catch (java.sql.SQLException es) {    /* that's expected here */
+            }
+
+/*
+            // new - a malformed data source assignment by user should not survive
+            // and should revert to the existing one
+            assertTrue(
+                "A table with an invalid data source should fall back to read-only.",
+                isReadOnly(m_products.getName()));
+
+            assertEquals(
+                "A data source which cannot be set should nonetheless be remembered.",
+                newDataSourceSpec, getDataSourceSpec(m_products.getName()));
+*/
+
+            // the data source spec should even survive a shutdown
+            executeStatement("SHUTDOWN");
+
+            m_connection = newConnection();
+            m_statement  = m_connection.createStatement();
+/*
+            assertEquals(
+                "A data source pointing to a mailformed file should survive a database shutdown.",
+                newDataSourceSpec, getDataSourceSpec(m_products.getName()));
+            assertTrue(
+                "After shutdown and DB-reconnect, the table with a malformed source should be read-only, again.",
+                isReadOnly(m_products.getName()));
+*/
+
+            // reconnect after fixing the file
+            textFile = new PrintStream(
+                FileUtil.getFileUtil().openOutputStreamElement(fileName));
+
+            textFile.println("1;some text");
+            textFile.close();
+            executeStatement(sqlSetTable + " SOURCE ON");
+            assertFalse(
+                "The file was fixed, reconnect was successful, so the table shouldn't be read-only.",
+                isReadOnly(m_products.getName()));
+
+            // finally re-create the proper version of the table for any further tests
+            m_products.createTextFile();
+            m_products.createTable(m_connection);
+            verifyTableContent(m_products.getName(), m_products.getData());
+        } catch (junit.framework.AssertionFailedError e) {
+            throw e;
+        } catch (Throwable t) {
+            fail("checkSourceConnection: unable to check invalid data sources, error: "
+                 + t.toString());
+        }
+    }
+
+    /**
+     * basic tests for text files
+     */
+    public void testTextFiles() {
+
+        verifyInitialContent();
+        checkInsertions();
+        checkSeparators();
+        checkSourceConnection();
+    }
+
+    public static void main(String[] argv) {
+        runWithResult(TestTextTable.class, "testTextFiles");
+    }
+}
diff --git a/src/org/hsqldb/test/TestTextTables.java b/src/org/hsqldb/test/TestTextTables.java
new file mode 100644
index 0000000..c975654
--- /dev/null
+++ b/src/org/hsqldb/test/TestTextTables.java
@@ -0,0 +1,284 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+public class TestTextTables extends TestBase {
+
+    static String url =
+        "jdbc:hsqldb:file:/hsql/testtext/test;sql.enforce_strict_size=true";
+
+    public TestTextTables(String name) {
+        super(name, url, false, false);
+    }
+
+    protected void setUp() {
+        super.setUp();
+    }
+
+    public void testSectionOne() throws Exception {
+
+        TestUtil.deleteDatabase("/hsql/testtext/test");
+        TestUtil.delete("/hsql/testtext/t.txt");
+        TestUtil.delete("/hsql/testtext/tt.txt");
+        TestUtil.delete("/hsql/testtext/ttt.txt");
+        TestUtil.delete("/hsql/testtext/tttt.txt");
+        initDatabase();
+        partA();
+        partD();
+    }
+
+    public void testSectionTwo() throws Exception {
+
+        TestUtil.deleteDatabase("/hsql/testtext/test");
+        TestUtil.delete("/hsql/testtext/t.txt");
+        TestUtil.delete("/hsql/testtext/tt.txt");
+        TestUtil.delete("/hsql/testtext/ttt.txt");
+        TestUtil.delete("/hsql/testtext/tttt.txt");
+        initDatabase();
+        partB();
+        partD();
+    }
+
+    public void testSectionThree() throws Exception {
+
+        Connection conn = newConnection();
+        Statement  st   = conn.createStatement();
+
+        st.execute("SHUTDOWN SCRIPT");
+    }
+
+    public void testSectionFour() throws Exception {
+
+        partD();
+
+        Connection conn = newConnection();
+        Statement  st   = conn.createStatement();
+
+        st.execute("SHUTDOWN");
+    }
+
+    public void testSectionFive() throws Exception {
+
+        Connection conn = newConnection();
+        PreparedStatement ps =
+            conn.prepareStatement("insert into tident (c2) values ?");
+
+        for (int i = 0; i < 20; i++) {
+            ps.setString(1, String.valueOf(i));
+            ps.executeUpdate();
+        }
+
+        ps.close();
+
+        ps = conn.prepareStatement("insert into tsingle (c1) values ?");
+
+        for (int i = 0; i < 20; i++) {
+            ps.setInt(1, i + 7);
+            ps.executeUpdate();
+        }
+
+        ps.close();
+
+        Statement st = conn.createStatement();
+
+        st.execute("SHUTDOWN IMMEDIATELY");
+        partD();
+
+        conn = newConnection();
+        st   = conn.createStatement();
+
+        st.execute("insert into tident values default, 'dont know'");
+
+        int count = st.executeUpdate("update tident set c2 = c2 || ' '");
+
+        assertEquals("identity table count mismatch", 21, count);
+
+        ResultSet rs = st.executeQuery("select count(*) from tsingle");
+
+        assertTrue(rs.next());
+        assertEquals(20, rs.getInt(1));
+        st.execute("set table tsingle read only");
+        st.execute("SHUTDOWN SCRIPT");
+
+        conn = newConnection();
+        st   = conn.createStatement();
+
+        st.execute("SHUTDOWN SCRIPT");
+    }
+
+    public void testSectionSix() throws Exception {
+
+        Connection conn = newConnection();
+
+        Statement st = conn.createStatement();
+
+        st.execute("set table tsingle read write");
+
+        st.execute("SHUTDOWN SCRIPT");
+
+        conn = newConnection();
+
+        st = conn.createStatement();
+
+        st.execute("create memory table tmsingle (c1 int primary key)");
+
+        st.execute("truncate table tident restart identity");
+
+        st.execute("truncate table tsingle restart identity");
+
+        ResultSet rs = st.executeQuery("select count(*) from tident");
+
+        assertTrue(rs.next());
+        assertEquals(0, rs.getInt(1));
+
+        st.execute("set table tident source off");
+        st.execute("set table tsingle source off");
+
+        st.execute("alter table tsingle add unique(c1)");
+
+        st.execute("alter table tident add foreign key (c1) references tmsingle(c1)");
+
+        st.execute("set table tident source on");
+        st.execute("set table tsingle source on");
+
+        rs = st.executeQuery("select count(*) from tmsingle");
+
+        assertTrue(rs.next());
+        assertEquals(0, rs.getInt(1));
+
+        rs = st.executeQuery("select count(*) from tident");
+
+        assertTrue(rs.next());
+        assertEquals(0, rs.getInt(1));
+
+
+        PreparedStatement ps =
+            conn.prepareStatement("insert into tmsingle(c1) values ?");
+
+        for (int i = 0; i < 20; i++) {
+            ps.setInt(1, i);
+            ps.executeUpdate();
+        }
+
+        ps.close();
+
+        ps = conn.prepareStatement("insert into tident (c1, c2) values ?, ?");
+
+        for (int i = 0; i < 20; i++) {
+            ps.setInt(1, i);
+            ps.setString(2, String.valueOf(i));
+            ps.executeUpdate();
+        }
+
+        ps.close();
+
+        st   = conn.createStatement();
+
+        rs = st.executeQuery("select count(*) from tmsingle");
+
+        assertTrue(rs.next());
+        assertEquals(20, rs.getInt(1));
+
+        rs = st.executeQuery("select count(*) from tident");
+
+        assertTrue(rs.next());
+        assertEquals(20, rs.getInt(1));
+
+
+        st.execute("SHUTDOWN SCRIPT");
+
+        conn = newConnection();
+        st   = conn.createStatement();
+
+        rs = st.executeQuery("select count(*) from tmsingle");
+
+        assertTrue(rs.next());
+        assertEquals(20, rs.getInt(1));
+
+        rs = st.executeQuery("select count(*) from tident");
+
+        assertTrue(rs.next());
+        assertEquals(20, rs.getInt(1));
+
+        conn = newConnection();
+        st   = conn.createStatement();
+
+        st.execute("SHUTDOWN");
+    }
+
+    void initDatabase() throws Exception {
+
+        Connection conn = newConnection();
+        Statement  st   = conn.createStatement();
+
+        st.execute("set files write delay 0");
+        st.execute("set database transaction control locks");
+    }
+
+    void partA() throws Exception {
+
+        Connection conn = newConnection();
+
+        TestUtil.testScript(conn, "TestText01.txt");
+
+        Statement st = conn.createStatement();
+
+        st.execute("SHUTDOWN");
+    }
+
+    void partB() throws Exception {
+
+        Connection conn = newConnection();
+
+        TestUtil.testScript(conn, "TestText01.txt");
+
+        Statement st = conn.createStatement();
+
+        st.execute("SHUTDOWN IMMEDIATELY");
+    }
+
+    void partD() throws Exception {
+
+        Connection conn = newConnection();
+
+        TestUtil.testScript(conn, "TestText02.txt");
+
+        Statement st = conn.createStatement();
+
+        st.execute("SHUTDOWN");
+    }
+}
diff --git a/src/org/hsqldb/test/TestTriggers.java b/src/org/hsqldb/test/TestTriggers.java
new file mode 100644
index 0000000..0994284
--- /dev/null
+++ b/src/org/hsqldb/test/TestTriggers.java
@@ -0,0 +1,174 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.hsqldb.Trigger;
+import org.hsqldb.lib.ArrayUtil;
+
+/**
+ *
+ * @author fredt
+ */
+public class TestTriggers extends TestBase {
+
+    Connection conn;
+
+    public TestTriggers(String testName) {
+        super(testName, "jdbc:hsqldb:file:trigs", false, false);
+    }
+
+    public void setUp() {
+
+        super.setUp();
+
+        try {
+            openConnection();
+        } catch (SQLException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public void tearDown() {
+
+        try {
+            conn.close();
+        } catch (SQLException ex) {
+            throw new RuntimeException(ex);
+        }
+
+        super.tearDown();
+    }
+
+    public void testTriggerAction() {
+
+        runScript();
+
+        try {
+            runStatements();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+
+        try {
+            shutdownDatabase();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+
+        try {
+            openConnection();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+
+        try {
+            runStatements();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            assertTrue(false);
+        }
+    }
+
+    private void openConnection() throws SQLException {
+        conn = newConnection();
+    }
+
+    private void runScript() {
+        TestUtil.testScript(conn, "TestTriggers.txt");
+    }
+
+    private void shutdownDatabase() throws SQLException {
+
+        Statement st = conn.createStatement();
+
+        st.execute("shutdown");
+        st.close();
+    }
+
+    private void runStatements() throws SQLException {
+
+        Statement st = conn.createStatement();
+
+        st.execute("delete from testtrig");
+        st.execute("alter table testtrig alter column c1 restart with 0");
+        clearCalls();
+        st.execute(
+            "insert into testtrig values (default, 'inserted val 1', 100)");
+        checkCallCount(3);
+        checkCalls(Trigger.INSERT_AFTER, 1);
+        checkCalls(Trigger.INSERT_BEFORE_ROW, 1);
+        checkCalls(Trigger.INSERT_AFTER_ROW, 1);
+        clearCalls();
+        st.execute(
+            "insert into testtrig (c2, c3) select c2, c3 from testtrig where c1 < 0");
+        checkCallCount(1);
+        checkCalls(Trigger.INSERT_AFTER, 1);
+        checkCalls(Trigger.INSERT_BEFORE_ROW, 0);
+        checkCalls(Trigger.INSERT_AFTER_ROW, 0);
+        clearCalls();
+        st.execute("update testtrig set c2 = c2 || ' updated' where c1 = 0");
+        checkCallCount(3);
+        checkCalls(Trigger.UPDATE_AFTER, 1);
+        checkCalls(Trigger.UPDATE_BEFORE_ROW, 1);
+        checkCalls(Trigger.UPDATE_AFTER_ROW, 1);
+        clearCalls();
+        st.execute("update testtrig set c2 = c2 || ' updated' where c1 < 0");
+        checkCallCount(1);
+        checkCalls(Trigger.UPDATE_AFTER, 1);
+        checkCalls(Trigger.UPDATE_BEFORE_ROW, 0);
+        checkCalls(Trigger.UPDATE_AFTER_ROW, 0);
+        st.close();
+    }
+
+    void checkCalls(int trigType, int callCount) {
+        assertEquals("call count mismatch", TriggerClass.callCounts[trigType],
+                     callCount);
+    }
+
+    void clearCalls() {
+
+        TriggerClass.callCount = 0;
+
+        ArrayUtil.fillArray(TriggerClass.callCounts, 0);
+    }
+
+    void checkCallCount(int count) {
+        assertEquals("trigger call mismatch", count, TriggerClass.callCount);
+    }
+}
diff --git a/src/org/hsqldb/test/TestTypeConversion.java b/src/org/hsqldb/test/TestTypeConversion.java
new file mode 100644
index 0000000..d927ab7
--- /dev/null
+++ b/src/org/hsqldb/test/TestTypeConversion.java
@@ -0,0 +1,178 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.io.*;
+
+public class TestTypeConversion extends TestBase {
+
+    Connection connection;
+    Statement  statement;
+
+    public TestTypeConversion(String name) {
+
+        super(name);
+
+//        super(name, "jdbc:hsqldb:file:test3", false, false);
+//       super(name, "jdbc:hsqldb:mem:test3", false, false);
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            connection = super.newConnection();
+            statement  = connection.createStatement();
+        } catch (Exception e) {
+            System.out.println(e);
+        }
+    }
+
+    public void testStreams() {
+
+        try {
+            String ddl0 = "DROP TABLE BSTREAM IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE BSTREAM(A INT IDENTITY PRIMARY KEY, B VARBINARY(20))";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("ddl failure");
+        }
+
+        try {
+            String            dml0 = "insert into bstream values(default, ?)";
+            String            dql0 = "select * from bstream where a = ?";
+            PreparedStatement ps1   = connection.prepareStatement(dml0);
+            PreparedStatement ps2   = connection.prepareStatement(dql0);
+            byte[]            data = new byte[] {
+                0x10, 0x11, 0x12, 0x13, 0x14, 0x15
+            };
+            InputStream is = new ByteArrayInputStream(data);
+            ps1.setBinaryStream(1,  is);
+            ps1.execute();
+
+            ps1.setObject(1, data);
+            ps1.execute();
+
+            ps2.setInt(1, 1);
+            ResultSet rs = ps2.executeQuery();
+
+            rs.next();
+
+            InputStream isr = rs.getBinaryStream(2);
+
+            for(int i =0; i < data.length ; i++) {
+                int val = isr.read();
+
+                assertTrue(val == data[i]);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail("dml failure");
+        }
+    }
+
+    public void testBitA() {
+
+        try {
+            String ddl0 = "DROP TABLE BITTEST IF EXISTS";
+            String ddl1 =
+                "CREATE TABLE BITTEST(BITA BIT(1), BITB BIT(2), "
+                + "BITVA BIT VARYING(1), BITVB BIT VARYING(2), ID IDENTITY)";
+
+            statement.execute(ddl0);
+            statement.execute(ddl1);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("ddl failure");
+        }
+
+        try {
+            String dml0 = "insert into bittest values(?, ?, ?, ?, default)";
+            String            dql0 = "select * from bittest;";
+            PreparedStatement ps   = connection.prepareStatement(dml0);
+            byte[]            data = new byte[]{ -0x80 };
+
+            ps.setBoolean(1, true);
+            ps.setBytes(2, data);
+            ps.setBytes(3, data);
+            ps.setBytes(4, data);
+            ps.executeUpdate();
+
+            //
+            data = new byte[]{ 0 };
+
+            ps.setBoolean(1, false);
+            ps.setBytes(2, data);
+            ps.setBytes(3, data);
+            ps.setBytes(4, data);
+            ps.executeUpdate();
+            ps.close();
+
+            ps = connection.prepareStatement(dql0);
+
+            ResultSet rs = ps.executeQuery();
+
+            rs.next();
+
+            boolean boole = rs.getBoolean(1);
+
+            assertTrue(boole);
+
+            boole = rs.getBoolean(1);
+
+            assertTrue(boole);
+            rs.next();
+
+            boole = rs.getBoolean(1);
+
+            assertFalse(boole);
+
+            boole = rs.getBoolean(1);
+
+            assertFalse(boole);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            fail("dml failure");
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestUpdatableResultSets.java b/src/org/hsqldb/test/TestUpdatableResultSets.java
new file mode 100644
index 0000000..c884742
--- /dev/null
+++ b/src/org/hsqldb/test/TestUpdatableResultSets.java
@@ -0,0 +1,192 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class TestUpdatableResultSets extends TestBase {
+
+    //
+    Connection connection;
+    Statement  statement;
+
+    public TestUpdatableResultSets(String name) {
+        super(name);
+    }
+
+    protected void setUp() {
+
+        super.setUp();
+
+        try {
+            connection = super.newConnection();
+            statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
+                                                   ResultSet.CONCUR_UPDATABLE);
+        } catch (Exception e) {
+            System.out.println(e);
+        }
+    }
+
+    public void testUpdatable() {
+
+        try {
+            statement.execute("drop table t1 if exists");
+            statement.execute(
+                "create table t1 (i int primary key, c varchar(10), t varbinary(3))");
+
+            String            insert = "insert into t1 values(?,?,?)";
+            String            select = "select i, c, t from t1";
+            PreparedStatement ps     = connection.prepareStatement(insert);
+
+            for (int i = 0; i < 10; i++) {
+                ps.setInt(1, i);
+                ps.setString(2, String.valueOf(i) + " s");
+                ps.setBytes(3, new byte[] {
+                    (byte) i, ' ', (byte) i
+                });
+                ps.execute();
+            }
+
+            connection.setAutoCommit(false);
+
+            ResultSet rs = statement.executeQuery(select);
+
+            while (rs.next()) {
+                String s = rs.getString(2);
+
+                rs.updateString(2, s + s);
+                rs.updateRow();
+            }
+
+            rs.close();
+
+            rs = statement.executeQuery(select);
+
+            while (rs.next()) {
+                String s = rs.getString(2);
+
+                System.out.println(s);
+            }
+
+            connection.rollback();
+
+            rs = statement.executeQuery(select);
+
+            while (rs.next()) {
+                String s = rs.getString(2);
+
+                System.out.println(s);
+            }
+
+            connection.commit();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void testScrollable() {
+
+        try {
+            statement.execute("drop table t1 if exists");
+            statement.execute(
+                "create table t1 (i int primary key, c varchar(10), t varbinary(3))");
+            statement.close();
+
+            String            insert = "insert into t1 values(?,?,?)";
+            String            select = "select i, c, t from t1";
+            PreparedStatement ps     = connection.prepareStatement(insert);
+
+            for (int i = 0; i < 10; i++) {
+                ps.setInt(1, i);
+                ps.setString(2, String.valueOf(i) + " s");
+                ps.setBytes(3, new byte[] {
+                    (byte) i, ' ', (byte) i
+                });
+                ps.execute();
+            }
+
+            connection.setAutoCommit(false);
+
+            statement =
+                connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
+                                           ResultSet.CONCUR_READ_ONLY);
+
+            ResultSet srs = statement.executeQuery("select * from t1 limit 2");
+
+            srs.afterLast();
+
+            while (srs.previous()) {
+                String name = srs.getString(2);
+                float  id   = srs.getFloat(1);
+
+                System.out.println(name + "   " + id);
+            }
+
+            srs.close();
+
+            srs = statement.executeQuery("select * from t1 limit 2");
+
+            srs.absolute(3);
+
+            while (srs.previous()) {
+                String name = srs.getString(2);
+                float  id   = srs.getFloat(1);
+
+                System.out.println(name + "   " + id);
+            }
+
+            srs.absolute(2);
+
+            while (srs.previous()) {
+                String name = srs.getString(2);
+                float  id   = srs.getFloat(1);
+
+                System.out.println(name + "   " + id);
+            }
+
+            srs.absolute(-1);
+
+            while (srs.previous()) {
+                String name = srs.getString(2);
+                float  id   = srs.getFloat(1);
+
+                System.out.println(name + "   " + id);
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestUpdatableResults.java b/src/org/hsqldb/test/TestUpdatableResults.java
new file mode 100644
index 0000000..7eb32cf
--- /dev/null
+++ b/src/org/hsqldb/test/TestUpdatableResults.java
@@ -0,0 +1,101 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+public class TestUpdatableResults extends TestBase {
+
+    public TestUpdatableResults(String name) {
+        super(name);
+    }
+
+    public void testQuery() {
+
+        try {
+            Connection c = newConnection();
+            Statement st = c.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
+                                             ResultSet.CONCUR_UPDATABLE);
+            String s = "CREATE TABLE T (I INTEGER, C CHARACTER(10), B BIT(4) DEFAULT B'')";
+
+            st.execute(s);
+
+            s = "INSERT INTO T VALUES(?,?, DEFAULT)";
+
+            PreparedStatement ps = c.prepareStatement(s);
+
+            for (int i = 1; i <= 20; i++) {
+                ps.setInt(1, i);
+                ps.setString(2, "TEST " + i);
+                ps.execute();
+            }
+
+            c.setAutoCommit(false);
+
+            s = "SELECT * FROM T";
+
+            ResultSet rs = st.executeQuery(s);
+
+
+            rs.absolute(10);
+            rs.updateString(2, "UPDATE10");
+            rs.updateRow();
+
+            rs.absolute(11);
+            rs.deleteRow();
+
+            rs.moveToInsertRow();
+
+            rs.updateInt(1, 1011);
+            rs.updateString(2, "INSERT1011");
+            rs.updateString(3, "0101");
+
+            rs.insertRow();
+
+            rs.close();
+
+            rs = st.executeQuery(s);
+
+            while (rs.next()) {
+                System.out.println("" + rs.getInt(1) + "      "
+                                   + rs.getString(2) + "      "
+                                   + rs.getString(3));
+            }
+
+        } catch (Exception e) {
+            System.out.print(e);
+        }
+    }
+}
diff --git a/src/org/hsqldb/test/TestUtil.java b/src/org/hsqldb/test/TestUtil.java
new file mode 100644
index 0000000..19576ec
--- /dev/null
+++ b/src/org/hsqldb/test/TestUtil.java
@@ -0,0 +1,1314 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+
+import org.hsqldb.lib.ArraySort;
+import org.hsqldb.lib.HsqlArrayList;
+import org.hsqldb.lib.LineGroupReader;
+import org.hsqldb.lib.StopWatch;
+import org.hsqldb.lib.StringComparator;
+import org.hsqldb.lib.StringUtil;
+
+/**
+ * Utility class providing methodes for submitting test statements or
+ * scripts to the database, comparing the results returned with
+ * the expected results. The test script format is compatible with existing
+ * scripts.
+ *
+ * Script writers be aware that you can't use stderr to distinguish error
+ * messages.  This class writes error messages to stdout.
+ *
+ * @author Ewan Slater (ewanslater@users dot sourceforge.net)
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ */
+public class TestUtil {
+
+    /*
+     * The executing scripts do have state.  This class should be
+     * redesigned with OOD.
+     */
+    static private final SimpleDateFormat sdfYMDHMS =
+        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    static private boolean      abortOnErr        = false;
+    static final private String TIMESTAMP_VAR_STR = "${timestamp}";
+    static final String LS = System.getProperty("line.separator", "\n");
+
+    public static void main(String[] argv) {
+
+        StopWatch sw = new StopWatch(true);
+
+        TestUtil.testScripts("testrun/hsqldb");
+        System.out.println(sw.currentElapsedTimeToMessage("Total time :"));
+    }
+
+    static void deleteDatabase(String path) {
+
+        delete(path + ".backup");
+        delete(path + ".properties");
+        delete(path + ".script");
+        delete(path + ".data");
+        delete(path + ".log");
+        delete(path + ".lck");
+        delete(path + ".lobs");
+    }
+
+    static void delete(String file) {
+
+        try {
+            new File(file).delete();
+        } catch (Exception e) {}
+    }
+
+    /**
+     * Expand occurrences of "${timestamp}" in input to time stamps.
+     */
+    static protected void expandStamps(StringBuffer sb) {
+
+        int i = sb.indexOf(TIMESTAMP_VAR_STR);
+
+        if (i < 1) {
+            return;
+        }
+
+        String timestamp;
+
+        synchronized (sdfYMDHMS) {
+            timestamp = sdfYMDHMS.format(new java.util.Date());
+        }
+
+        while (i > -1) {
+            sb.replace(i, i + TIMESTAMP_VAR_STR.length(), timestamp);
+
+            i = sb.indexOf(TIMESTAMP_VAR_STR);
+        }
+    }
+
+    static void testScripts(String directory) {
+
+        TestUtil.deleteDatabase("test1");
+
+        try {
+            Class.forName("org.hsqldb.jdbc.JDBCDriver");
+
+            String     url = "jdbc:hsqldb:test1;sql.enforce_strict_size=true";
+            String     user        = "sa";
+            String     password    = "";
+            Connection cConnection = null;
+            String[]   filelist;
+            String     absolute = new File(directory).getAbsolutePath();
+
+            filelist = new File(absolute).list();
+
+            ArraySort.sort((Object[]) filelist, 0, filelist.length,
+                           new StringComparator());
+
+            for (int i = 0; i < filelist.length; i++) {
+                String fname = filelist[i];
+
+                if (fname.startsWith("TestSelf") && fname.endsWith(".txt")) {
+                    print("Openning DB");
+
+                    cConnection = DriverManager.getConnection(url, user,
+                            password);
+
+                    testScript(cConnection, absolute + File.separator + fname);
+                    cConnection.close();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            print("TestUtil init error: " + e.getMessage());
+        }
+    }
+
+    static void testScript(Connection aConnection, String aPath) {
+
+        /*
+         * This is a legacy wrapper method which purposefully inherits the sins
+         * of the original.
+         * No indication is given to the invoker of even RuntimeExceptions.
+         */
+        File file = new File(aPath);
+
+        try {
+            TestUtil.testScript(aConnection, file.getAbsolutePath(),
+                                new FileReader(file));
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("test script file error: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Runs a preformatted script.<p>
+     *
+     * Where a result set is required, each line in the script will
+     * be interpreted as a seperate expected row in the ResultSet
+     * returned by the query.  Within each row, fields should be delimited
+     * using either comma (the default), or a user defined delimiter
+     * which should be specified in the System property TestUtilFieldDelimiter
+     * @param aConnection Connection object for the database
+     * @param sourceName Identifies the script which failed
+     * @param inReader Source of commands to be tested
+     */
+    public static void testScript(Connection aConnection, String sourceName,
+                                  Reader inReader)
+                                  throws SQLException, IOException {
+
+        Statement        statement = aConnection.createStatement();
+        LineNumberReader reader    = new LineNumberReader(inReader);
+        LineGroupReader  sqlReader = new LineGroupReader(reader);
+        int              startLine = 0;
+
+        System.out.println("Opened test script file: " + sourceName);
+
+        /**
+         * we read the lines from the start of one section of the script "/*"
+         *  until the start of the next section, collecting the lines in the
+         *  list.
+         *  When a new section starts, we pass the list of lines
+         *  to the test method to be processed.
+         */
+        try {
+            while (true) {
+                HsqlArrayList section = sqlReader.getSection();
+
+                startLine = sqlReader.getStartLineNumber();
+
+                if (section.size() == 0) {
+                    break;
+                }
+
+                testSection(statement, section, sourceName, startLine);
+            }
+
+            statement.close();
+
+            // The following catch blocks are just to report the source location
+            // of the failure.
+        } catch (SQLException se) {
+            System.out.println("Error encountered at command beginning at "
+                               + sourceName + ':' + startLine);
+
+            throw se;
+        } catch (RuntimeException re) {
+            System.out.println("Error encountered at command beginning at "
+                               + sourceName + ':' + startLine);
+
+            throw re;
+        }
+
+        System.out.println("Processed " + reader.getLineNumber()
+                           + " lines from " + sourceName);
+    }
+
+    /** Legacy wrapper */
+    static void test(Statement stat, String s, int line) {
+        TestUtil.test(stat, s, null, line);
+    }
+
+    /**
+     * Performs a preformatted statement or group of statements and throws
+     *  if the result does not match the expected one.
+     * @param line start line in the script file for this test
+     * @param stat Statement object used to access the database
+     * @param sourceName Identifies the script which failed
+     * @param s Contains the type, expected result and SQL for the test
+     */
+    static void test(Statement stat, String s, String sourceName, int line) {
+
+        //maintain the interface for this method
+        HsqlArrayList section = new HsqlArrayList();
+
+        section.add(s);
+        testSection(stat, section, sourceName, line);
+    }
+
+    /**
+     * Method to save typing ;-)
+     * This method does not distinguish between normal and error output.
+     *
+     * @param s String to be printed
+     */
+    static void print(String s) {
+        System.out.println(s);
+    }
+
+    /**
+     * Takes a discrete section of the test script, contained in the
+     * section vector, splits this into the expected result(s) and
+     * submits the statement to the database, comparing the results
+     * returned with the expected results.
+     * If the actual result differs from that expected, or an
+     * exception is thrown, then the appropriate message is printed.
+     * @param stat Statement object used to access the database
+     * @param section Vector of script lines containing a discrete
+     * section of script (i.e. test type, expected results,
+     * SQL for the statement).
+     * @param line line of the script file where this section started
+     */
+    private static void testSection(Statement stat, HsqlArrayList section,
+                                    String scriptName, int line) {
+
+        //create an appropriate instance of ParsedSection
+        ParsedSection pSection = parsedSectionFactory(section);
+
+        if (pSection == null) {    //it was not possible to sucessfully parse the section
+            System.out.println(
+                "The section starting at " + scriptName + ':' + line
+                + " could not be parsed, and so was not processed." + LS);
+
+            return;
+        }
+
+        if (pSection instanceof IgnoreParsedSection) {
+            System.out.println("At " + scriptName + ':' + line + ": "
+                               + pSection.getResultString());
+
+            return;
+        }
+
+        if (pSection instanceof DisplaySection
+                || pSection instanceof WaitSection
+                || pSection instanceof ProceedSection) {
+            String s = pSection.getResultString();
+
+            if (s != null) {
+
+                // May or may not want to report line number for these sections?
+                System.out.println(pSection.getResultString());
+            }
+        }
+
+        if (pSection instanceof DisplaySection) {
+            return;    // Do not run test method for DisplaySections.
+        }
+
+        if (!pSection.test(stat)) {
+            System.out.println("Section starting at " + scriptName + ':'
+                               + line + " returned an unexpected result: "
+                               + pSection);
+
+            if (TestUtil.abortOnErr) {
+                throw new TestRuntimeException(scriptName + ": " + line
+                                               + "pSection");
+            }
+        }
+    }
+
+    /**
+     * Factory method to create appropriate parsed section class for the section
+     * @param aSection Vector containing the section of script
+     * @return a ParesedSection object
+     */
+    private static ParsedSection parsedSectionFactory(HsqlArrayList aSection) {
+
+        //type of the section
+        char type = ' ';
+
+        //section represented as an array of Strings, one for each significant
+        //line in the section
+        String[] rows = null;
+
+        //read the first line of the Vector...
+        String topLine = (String) aSection.get(0);
+
+        //...and check it for the type...
+        if (topLine.startsWith("/*")) {
+            type = topLine.charAt(2);
+
+            //if the type code is UPPERCASE and system property IgnoreCodeCase
+            //has been set to true, make the type code lowercase
+            if ((Character.isUpperCase(type))
+                    && (Boolean.getBoolean("IgnoreCodeCase"))) {
+                type = Character.toLowerCase(type);
+            }
+
+            //if the type code is invalid return null
+            if (!ParsedSection.isValidCode(type)) {
+                return null;
+            }
+
+            //...strip out the type declaration...
+            topLine = topLine.substring(3);
+        }
+
+        //if, after stripping out the declaration from topLine, the length of topLine
+        //is greater than 0, then keep the rest of the line, as the first row.
+        //Otherwise it will be discarded, and the offset (between the array and the vector)
+        //set to 1.
+        int offset = 0;
+
+        if (topLine.trim().length() > 0) {
+            rows    = new String[aSection.size()];
+            rows[0] = topLine;
+        } else {
+            rows   = new String[aSection.size() - 1];
+            offset = 1;
+        }
+
+        //pull the rest of aSection into the rows array.
+        for (int i = (1 - offset); i < rows.length; i++) {
+            rows[i] = (String) aSection.get(i + offset);
+        }
+
+        //then pass this to the constructor for the ParsedSection class that
+        //corresponds to the value of type
+        switch (type) {
+
+            case 'u' :
+                return new UpdateParsedSection(rows);
+
+            case 's' :
+                return new SilentParsedSection(rows);
+
+            case 'w' :
+                return new WaitSection(rows);
+
+            case 'p' :
+                return new ProceedSection(rows);
+
+            case 'r' :
+                return new ResultSetParsedSection(rows);
+
+            case 'o' :
+                return new ResultSetOutputParsedSection(rows);
+
+            case 'c' :
+                return new CountParsedSection(rows);
+
+            case 'd' :
+                return new DisplaySection(rows);
+
+            case 'e' :
+                return new ExceptionParsedSection(rows);
+
+            case ' ' :
+                return new BlankParsedSection(rows);
+
+            default :
+
+                //if we arrive here, then we should have a valid code,
+                //since we validated it earlier, so return an
+                //IgnoreParsedSection object
+                return new IgnoreParsedSection(rows, type);
+        }
+    }
+
+    /**
+     * This method should certainly be an instance method.
+     *
+     * Can't do that until make this entire class OO.
+     */
+    static public void setAbortOnErr(boolean aoe) {
+        abortOnErr = aoe;
+    }
+
+    static class TestRuntimeException extends RuntimeException {
+
+        public TestRuntimeException(String s) {
+            super(s);
+        }
+
+        public TestRuntimeException(Throwable t) {
+            super(t);
+        }
+
+        public TestRuntimeException(String s, Throwable t) {
+            super(s, t);
+        }
+    }
+}
+
+/**
+ * Abstract inner class representing a parsed section of script.
+ * The specific ParsedSections for each type of test should inherit from this.
+ */
+abstract class ParsedSection {
+
+    static final String LS = System.getProperty("line.separator", "\n");
+
+    /**
+     * Type of this test.
+     * @see #isValidCode(char) for allowed values
+     */
+    protected char type = ' ';
+
+    /** error message for this section */
+    String message = null;
+
+    /** contents of the section as an array of Strings, one for each line in the section. */
+    protected String[] lines = null;
+
+    /** number of the last row containing results in sectionLines */
+    protected int resEndRow = 0;
+
+    /** SQL query to be submitted to the database. */
+    protected String sqlString = null;
+
+    /**
+     * Constructor when the section's input lines do not need to be parsed
+     * into SQL.
+     */
+    protected ParsedSection() {}
+
+    /**
+     * Common constructor functions for this family.
+     * @param aLines Array of the script lines containing the section of script.
+     * database
+     */
+    protected ParsedSection(String[] aLines) {
+
+        lines = aLines;
+
+        //read the lines array backwards to get out the SQL String
+        //using a StringBuffer for efficency until we've got the whole String
+        StringBuffer sqlBuff  = new StringBuffer();
+        int          endIndex = 0;
+        int          k        = lines.length - 1;
+
+        do {
+
+            //check to see if the row contains the end of the result set
+            if ((endIndex = lines[k].indexOf("*/")) != -1) {
+
+                //then this is the end of the result set
+                sqlBuff.insert(0, lines[k].substring(endIndex + 2));
+
+                lines[k] = lines[k].substring(0, endIndex);
+
+                if (lines[k].length() == 0) {
+                    resEndRow = k - 1;
+                } else {
+                    resEndRow = k;
+                }
+
+                break;
+            } else {
+                sqlBuff.insert(0, lines[k]);
+            }
+
+            k--;
+        } while (k >= 0);
+
+        //set sqlString value
+        sqlString = sqlBuff.toString();
+    }
+
+    /**
+     * String representation of this ParsedSection
+     * @return String representation of this ParsedSection
+     */
+    public String toString() {
+
+        StringBuffer b = new StringBuffer();
+
+        b.append(LS + "******" + LS);
+        b.append("contents of lines array:" + LS);
+
+        for (int i = 0; i < lines.length; i++) {
+            if (lines[i].trim().length() > 0) {
+                b.append("line ").append(i).append(": ").append(
+                    lines[i]).append(LS);
+            }
+        }
+
+        b.append("Type: ");
+        b.append(getType()).append(LS);
+        b.append("SQL: ").append(getSql()).append(LS);
+        b.append("results:").append(LS);
+        b.append(getResultString());
+
+        //check to see if the message field has been populated
+        if (getMessage() != null) {
+            b.append("\nmessage:").append(LS);
+            b.append(getMessage());
+        }
+
+        b.append(LS + "******" + LS);
+
+        return b.toString();
+    }
+
+    /**
+     * returns a String representation of the expected result for the test
+     * @return The expected result(s) for the test
+     */
+    protected abstract String getResultString();
+
+    /**
+     *  returns the error message for the section
+     *
+     * @return message
+     */
+    protected String getMessage() {
+        return message;
+    }
+
+    /**
+     * returns the type of this section
+     * @return type of this section
+     */
+    protected char getType() {
+        return type;
+    }
+
+    /**
+     * returns the SQL statement for this section
+     * @return SQL statement for this section
+     */
+    protected String getSql() {
+        return sqlString;
+    }
+
+    /**
+     * performs the test contained in the section against the database.
+     * @param aStatement Statement object
+     * @return true if the result(s) are as expected, otherwise false
+     */
+    protected boolean test(Statement aStatement) {
+
+        try {
+            aStatement.execute(getSql());
+        } catch (Exception x) {
+            message = x.getMessage();
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks that the type code letter is valid
+     * @param aCode Lower-cased type code to validate.
+     * @return true if the type code is valid, otherwise false.
+     */
+    protected static boolean isValidCode(char aCode) {
+
+        /* Allowed values for test codes are:
+         * (note that UPPERCASE codes, while valid are only processed if the
+         * system property IgnoreCodeCase has been set to true)
+         *
+         * 'u' - update
+         * 'c' - count
+         * 'e' - exception
+         * 'r' - results
+         * 'w' - wait
+         * 'p' - proceed
+         * 's' - silent
+         * 'd' - display   (No reason to use upper-case).
+         * ' ' - not a test
+         */
+        switch (aCode) {
+
+            case ' ' :
+            case 'r' :
+            case 'o' :
+            case 'e' :
+            case 'c' :
+            case 'u' :
+            case 's' :
+            case 'd' :
+            case 'w' :
+            case 'p' :
+                return true;
+        }
+
+        return false;
+    }
+}
+
+/** Represents a ParsedSection for a ResultSet test */
+class ResultSetParsedSection extends ParsedSection {
+
+    private String   delim = System.getProperty("TestUtilFieldDelimiter", ",");
+    private String[] expectedRows = null;
+
+    /**
+     * constructs a new instance of ResultSetParsedSection, interpreting
+     * the supplied results as one or more lines of delimited field values
+     * @param lines String[]
+     */
+    protected ResultSetParsedSection(String[] lines) {
+
+        super(lines);
+
+        type = 'r';
+
+        //now we'll populate the expectedResults array
+        expectedRows = new String[(resEndRow + 1)];
+
+        for (int i = 0; i <= resEndRow; i++) {
+            int skip = StringUtil.skipSpaces(lines[i], 0);
+
+            expectedRows[i] = lines[i].substring(skip);
+        }
+    }
+
+    protected String getResultString() {
+
+        StringBuffer printVal = new StringBuffer();
+
+        for (int i = 0; i < getExpectedRows().length; i++) {
+            printVal.append(getExpectedRows()[i]).append(LS);
+        }
+
+        return printVal.toString();
+    }
+
+    protected boolean test(Statement aStatement) {
+
+        try {
+            try {
+
+                //execute the SQL
+                aStatement.execute(getSql());
+            } catch (SQLException s) {
+                throw new Exception("Expected a ResultSet, but got the error: "
+                                    + s.getMessage());
+            }
+
+            //check that update count != -1
+            if (aStatement.getUpdateCount() != -1) {
+                throw new Exception(
+                    "Expected a ResultSet, but got an update count of "
+                    + aStatement.getUpdateCount());
+            }
+
+            //iterate over the ResultSet
+            ResultSet results = aStatement.getResultSet();
+            int       count   = 0;
+
+            while (results.next()) {
+                if (count < getExpectedRows().length) {
+
+//                    String[] expectedFields = getExpectedRows()[count].split(delim);
+                    String[] expectedFields =
+                        StringUtil.split(getExpectedRows()[count], delim);
+
+                    //check that we have the number of columns expected...
+                    if (results.getMetaData().getColumnCount()
+                            == expectedFields.length) {
+
+                        //...and if so, check that the column values are as expected...
+                        int j = 0;
+
+                        for (int i = 0; i < expectedFields.length; i++) {
+                            j = i + 1;
+
+                            String actual = results.getString(j);
+
+                            //...including null values...
+                            if (actual == null) {    //..then we have a null
+
+                                //...check to see if we were expecting it...
+                                if (!expectedFields[i].equalsIgnoreCase(
+                                        "NULL")) {
+                                    throw new Exception(
+                                        "Expected row " + count
+                                        + " of the ResultSet to contain:" + LS
+                                        + getExpectedRows()[count] + LS
+                                        + "but field " + j
+                                        + " contained NULL");
+                                }
+                            } else if (!actual.equals(expectedFields[i])) {
+
+                                //then the results are different
+                                throw new Exception(
+                                    "Expected row " + (count + 1)
+                                    + " of the ResultSet to contain:" + LS
+                                    + getExpectedRows()[count] + LS
+                                    + "but field " + j + " contained "
+                                    + results.getString(j));
+                            }
+                        }
+                    } else {
+
+                        //we have the wrong number of columns
+                        throw new Exception(
+                            "Expected the ResultSet to contain "
+                            + expectedFields.length
+                            + " fields, but it contained "
+                            + results.getMetaData().getColumnCount()
+                            + " fields.");
+                    }
+                }
+
+                count++;
+            }
+
+            //check that we got as many rows as expected
+            if (count != getExpectedRows().length) {
+
+                //we don't have the expected number of rows
+                throw new Exception("Expected the ResultSet to contain "
+                                    + getExpectedRows().length
+                                    + " rows, but it contained " + count
+                                    + " rows.");
+            }
+        } catch (Exception x) {
+            message = x.getMessage();
+
+            return false;
+        }
+
+        return true;
+    }
+
+    private String[] getExpectedRows() {
+        return expectedRows;
+    }
+}
+
+/** Represents a ParsedSection for a ResultSet dump */
+class ResultSetOutputParsedSection extends ParsedSection {
+
+    private String   delim = System.getProperty("TestUtilFieldDelimiter", ",");
+    private String[] expectedRows = null;
+
+    /**
+     * constructs a new instance of ResultSetParsedSection, interpreting
+     * the supplied results as one or more lines of delimited field values
+     * @param lines String[]
+     */
+    protected ResultSetOutputParsedSection(String[] lines) {
+
+        super(lines);
+
+        type = 'o';
+    }
+
+    protected String getResultString() {
+        return "";
+    }
+
+    protected boolean test(Statement aStatement) {
+
+        try {
+            try {
+
+                //execute the SQL
+                aStatement.execute(getSql());
+            } catch (SQLException s) {
+                throw new Exception("Expected a ResultSet, but got the error: "
+                                    + s.getMessage());
+            }
+
+            //check that update count != -1
+            if (aStatement.getUpdateCount() != -1) {
+                throw new Exception(
+                    "Expected a ResultSet, but got an update count of "
+                    + aStatement.getUpdateCount());
+            }
+
+            //iterate over the ResultSet
+            ResultSet    results  = aStatement.getResultSet();
+            StringBuffer printVal = new StringBuffer();
+
+            while (results.next()) {
+                for (int j = 0; j < results.getMetaData().getColumnCount();
+                        j++) {
+                    if (j != 0) {
+                        printVal.append(',');
+                    }
+
+                    printVal.append(results.getString(j + 1));
+                }
+
+                printVal.append(LS);
+            }
+
+            throw new Exception(printVal.toString());
+        } catch (Exception x) {
+            message = x.getMessage();
+
+            return false;
+        }
+    }
+
+    private String[] getExpectedRows() {
+        return expectedRows;
+    }
+}
+
+/** Represents a ParsedSection for an update test */
+class UpdateParsedSection extends ParsedSection {
+
+    //expected update count
+    int countWeWant;
+
+    protected UpdateParsedSection(String[] lines) {
+
+        super(lines);
+
+        type        = 'u';
+        countWeWant = Integer.parseInt(lines[0]);
+    }
+
+    protected String getResultString() {
+        return Integer.toString(getCountWeWant());
+    }
+
+    private int getCountWeWant() {
+        return countWeWant;
+    }
+
+    protected boolean test(Statement aStatement) {
+
+        try {
+            try {
+
+                //execute the SQL
+                aStatement.execute(getSql());
+            } catch (SQLException s) {
+                throw new Exception("Expected an update count of "
+                                    + getCountWeWant()
+                                    + ", but got the error: "
+                                    + s.getMessage());
+            }
+
+            if (aStatement.getUpdateCount() != getCountWeWant()) {
+                throw new Exception("Expected an update count of "
+                                    + getCountWeWant()
+                                    + ", but got an update count of "
+                                    + aStatement.getUpdateCount() + ".");
+            }
+        } catch (Exception x) {
+            message = x.getMessage();
+
+            return false;
+        }
+
+        return true;
+    }
+}
+
+class WaitSection extends ParsedSection {
+
+    /* Would love to have a setting to say whether multi-thread mode,
+     * but the static design of TestUtil prevents that.
+     * a W command will cause a non-threaded execution to wait forever.
+     */
+    static private String W_SYNTAX_MSG =
+        "Syntax of Wait commands:" + LS
+        + "    /*w 123*/     To Wait 123 milliseconds" + LS
+        + "    /*w false x*/ Wait until /*p*/ command in another script has executed"
+        + LS
+        + "    /*w true x*/  Same, but the /*p*/ must not have executed yet";
+
+/** Represents a ParsedSection for wait execution */
+    long    sleepTime       = -1;
+    Waiter  waiter          = null;
+    boolean enforceSequence = false;
+
+    protected WaitSection(String[] inLines) {
+
+        /* Can't user the super constructor, since it does funny things when
+         * constructing the SQL Buffer, which we don't need. */
+        lines = inLines;
+
+        int    closeCmd = lines[0].indexOf("*/");
+        String cmd      = lines[0].substring(0, closeCmd);
+
+        lines[0] = lines[0].substring(closeCmd + 2).trim();
+
+        String trimmed = cmd.trim();
+
+        if (trimmed.indexOf('e') < 0 && trimmed.indexOf('E') < 0) {
+
+            // Does not contain "true" or "false"
+            sleepTime = Long.parseLong(trimmed);
+        } else {
+            try {
+
+                // Would like to use String.split(), but don't know if Java 4
+                // is allowed here.
+                // Until we can use Java 4, prohibit tabs as white space.
+                int index = trimmed.indexOf(' ');
+
+                if (index < 0) {
+                    throw new IllegalArgumentException();
+                }
+
+                enforceSequence = Boolean.valueOf(trimmed.substring(0,
+                        index)).booleanValue();
+                waiter = Waiter.getWaiter(trimmed.substring(index).trim());
+            } catch (IllegalArgumentException ie) {
+                throw new IllegalArgumentException(W_SYNTAX_MSG);
+            }
+        }
+
+        type = 'w';
+    }
+
+    protected String getResultString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        if (lines.length == 1 && lines[0].trim().length() < 1) {
+            return null;
+        }
+
+        for (int i = 0; i < lines.length; i++) {
+            if (i > 0) {
+                sb.append(LS);
+            }
+
+            sb.append("+ " + lines[i]);
+        }
+
+        TestUtil.expandStamps(sb);
+
+        return sb.toString().trim();
+    }
+
+    protected boolean test(Statement aStatement) {
+
+        if (waiter == null) {
+            try {
+
+                //System.err.println("Sleeping for " + sleepTime + " ms.");
+                Thread.sleep(sleepTime);
+            } catch (InterruptedException ie) {
+                throw new RuntimeException("Test sleep interrupted", ie);
+            }
+        } else {
+            waiter.waitFor(enforceSequence);
+        }
+
+        return true;
+    }
+}
+
+class ProceedSection extends ParsedSection {
+
+    /* See comment above for WaitSection */
+    static private String P_SYNTAX_MSG =
+        "Syntax of Proceed commands:" + LS
+        + "    /*p false x*/ /*p*/ command in another script may Proceed" + LS
+        + "    /*p true x*/  Same, but the /*w*/ must be waiting when we execute /*p*/"
+    ;
+
+/** Represents a ParsedSection for wait execution */
+    Waiter  waiter          = null;
+    boolean enforceSequence = false;
+
+    protected ProceedSection(String[] inLines) {
+
+        /* Can't use the super constructor, since it does funny things when
+         * constructing the SQL Buffer, which we don't need. */
+        lines = inLines;
+
+        int    closeCmd = lines[0].indexOf("*/");
+        String cmd      = lines[0].substring(0, closeCmd);
+
+        lines[0] = lines[0].substring(closeCmd + 2).trim();
+
+        String trimmed = cmd.trim();
+
+        try {
+
+            // Would like to use String.split(), but don't know if Java 4
+            // is allowed here.
+            // Until we can use Java 4, prohibit tabs as white space.
+            int index = trimmed.indexOf(' ');
+
+            if (index < 0) {
+                throw new IllegalArgumentException();
+            }
+
+            enforceSequence = Boolean.valueOf(trimmed.substring(0,
+                    index)).booleanValue();
+            waiter = Waiter.getWaiter(trimmed.substring(index).trim());
+        } catch (IllegalArgumentException ie) {
+            throw new IllegalArgumentException(P_SYNTAX_MSG);
+        }
+
+        type = 'p';
+    }
+
+    protected String getResultString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        if (lines.length == 1 && lines[0].trim().length() < 1) {
+            return null;
+        }
+
+        for (int i = 0; i < lines.length; i++) {
+            if (i > 0) {
+                sb.append(LS);
+            }
+
+            sb.append("+ " + lines[i]);
+        }
+
+        TestUtil.expandStamps(sb);
+
+        return sb.toString().trim();
+    }
+
+    protected boolean test(Statement aStatement) {
+
+        waiter.resume(enforceSequence);
+
+        return true;
+    }
+}
+
+/** Represents a ParsedSection for silent execution */
+class SilentParsedSection extends ParsedSection {
+
+    protected SilentParsedSection(String[] lines) {
+
+        super(lines);
+
+        type = 's';
+    }
+
+    protected String getResultString() {
+        return null;
+    }
+
+    protected boolean test(Statement aStatement) {
+
+        try {
+            aStatement.execute(getSql());
+        } catch (Exception x) {}
+
+        return true;
+    }
+}
+
+/** Represents a ParsedSection for a count test */
+class CountParsedSection extends ParsedSection {
+
+    //expected row count
+    private int countWeWant;
+
+    protected CountParsedSection(String[] lines) {
+
+        super(lines);
+
+        type        = 'c';
+        countWeWant = Integer.parseInt(lines[0]);
+    }
+
+    protected String getResultString() {
+        return Integer.toString(getCountWeWant());
+    }
+
+    private int getCountWeWant() {
+        return countWeWant;
+    }
+
+    protected boolean test(Statement aStatement) {
+
+        try {
+
+            //execute the SQL
+            try {
+                aStatement.execute(getSql());
+            } catch (SQLException s) {
+                throw new Exception("Expected a ResultSet containing "
+                                    + getCountWeWant()
+                                    + " rows, but got the error: "
+                                    + s.getMessage());
+            }
+
+            //check that update count != -1
+            if (aStatement.getUpdateCount() != -1) {
+                throw new Exception(
+                    "Expected a ResultSet, but got an update count of "
+                    + aStatement.getUpdateCount());
+            }
+
+            //iterate over the ResultSet
+            ResultSet results = aStatement.getResultSet();
+            int       count   = 0;
+
+            while (results.next()) {
+                count++;
+            }
+
+            //check that we got as many rows as expected
+            if (count != getCountWeWant()) {
+
+                //we don't have the expected number of rows
+                throw new Exception("Expected the ResultSet to contain "
+                                    + getCountWeWant()
+                                    + " rows, but it contained " + count
+                                    + " rows.");
+            }
+        } catch (Exception x) {
+            message = x.getMessage();
+
+            return false;
+        }
+
+        return true;
+    }
+}
+
+/** Represents a ParsedSection for an Exception test */
+class ExceptionParsedSection extends ParsedSection {
+
+    private String    expectedState = null;
+    private Throwable caught        = null;
+
+    protected ExceptionParsedSection(String[] lines) {
+
+        super(lines);
+
+        expectedState = lines[0].trim();
+
+        if (expectedState.length() < 1) {
+            expectedState = null;
+        }
+
+        type = 'e';
+    }
+
+    protected String getResultString() {
+        return (caught == null) ? "Nothing thrown"
+                                : caught.toString();
+    }
+
+    protected boolean test(Statement aStatement) {
+
+        try {
+            aStatement.execute(getSql());
+        } catch (SQLException sqlX) {
+            caught = sqlX;
+
+            if (expectedState == null
+                    || expectedState.equalsIgnoreCase(sqlX.getSQLState())) {
+                return true;
+            }
+
+            message = "SQLState '" + sqlX.getSQLState() + "' : "
+                      + sqlX.getMessage() + " instead of '" + expectedState
+                      + "'";
+        } catch (Exception x) {
+            caught  = x;
+            message = x.getMessage();
+        }
+
+        return false;
+    }
+}
+
+/** Represents a ParsedSection for a section with blank type */
+class BlankParsedSection extends ParsedSection {
+
+    protected BlankParsedSection(String[] lines) {
+
+        super(lines);
+
+        type = ' ';
+    }
+
+    protected String getResultString() {
+        return message;
+    }
+}
+
+/** Represents a ParsedSection that is to be ignored */
+class IgnoreParsedSection extends ParsedSection {
+
+    protected IgnoreParsedSection(String[] inLines, char aType) {
+
+        /* Extremely ambiguous to use input parameter of same exact
+         * variable name as the superclass member "lines".
+         * Therefore, renaming to inLines. */
+
+        // Inefficient to parse this into SQL when we aren't going to use
+        // it as SQL.  Should probably just be removed to use the
+        // super() constructor.
+        super(inLines);
+
+        type = aType;
+    }
+
+    protected String getResultString() {
+        return "This section, of type '" + getType() + "' was ignored";
+    }
+}
+
+/** Represents a Section to be Displayed, not executed */
+class DisplaySection extends ParsedSection {
+
+    protected DisplaySection(String[] inLines) {
+
+        /* Can't user the super constructor, since it does funny things when
+         * constructing the SQL Buffer, which we don't need. */
+        lines = inLines;
+
+        int firstSlash = lines[0].indexOf('/');
+
+        lines[0] = lines[0].substring(firstSlash + 1).trim();
+    }
+
+    protected String getResultString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        if (lines.length == 1 && lines[0].trim().length() < 1) {
+            return null;
+        }
+
+        for (int i = 0; i < lines.length; i++) {
+            if (i > 0) {
+                sb.append(LS);
+            }
+
+            sb.append("+ " + lines[i]);
+        }
+
+        TestUtil.expandStamps(sb);
+
+        return sb.toString().trim();
+    }
+}
diff --git a/src/org/hsqldb/test/TestViewAsterisks.java b/src/org/hsqldb/test/TestViewAsterisks.java
new file mode 100644
index 0000000..b6be6ea
--- /dev/null
+++ b/src/org/hsqldb/test/TestViewAsterisks.java
@@ -0,0 +1,591 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+import org.hsqldb.error.ErrorCode;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ *  is a test which verifies the functionality of replacing asterisks in VIEW statements with column
+ *  lists.
+ *
+ *  During investigating http://www.openoffice.org/issues/show_bug.cgi?id=78296 (an issue raised
+ *  in OpenOffice.org, which integrates HSQLDB), it rose that views did not behave to the standard
+ *  in that they don't always reflect the table column list at the time of creation of the view.
+ *
+ *  This was changed so that when you CREATE a VIEW, then any asterisks in the constituting
+ *  statement are replaced with their column lists.
+ *
+ *  This test verifies this functionality in a number of different flavours.
+ *
+ * @author frank.schoenheit@sun.com
+ */
+public class TestViewAsterisks extends TestBase {
+
+    java.sql.Statement  m_statement;
+    java.sql.Connection m_connection;
+
+    /** Creates a new instance of TestViewAsterisks */
+    public TestViewAsterisks(String testName) {
+        super(testName, null, false, false);
+    }
+
+    /**
+     * creates the database tables needed for the test
+     */
+    private void setupDatabase() {
+
+        try {
+            m_connection = newConnection();
+            m_statement  = m_connection.createStatement();
+
+            executeStatement("DROP TABLE ABC IF EXISTS CASCADE");
+            executeStatement("DROP TABLE TABLE_A IF EXISTS CASCADE");
+            executeStatement("DROP TABLE TABLE_B IF EXISTS CASCADE");
+            executeStatement("DROP VIEW V1 IF EXISTS CASCADE"); // V1 is created by a previous test case
+            executeStatement(
+                "CREATE TABLE ABC (ID INTEGER NOT NULL PRIMARY KEY, A VARCHAR(50), B VARCHAR(50), C VARCHAR(50))");
+            executeStatement("INSERT INTO ABC VALUES (1, 'a', 'b', 'c')");
+            executeStatement("INSERT INTO ABC VALUES (2, 'd', 'e', 'f')");
+            executeStatement(
+                "CREATE TABLE TABLE_A (ID_A INTEGER NOT NULL PRIMARY KEY, NAME_A VARCHAR(50))");
+            executeStatement("INSERT INTO TABLE_A VALUES (1, 'first A')");
+            executeStatement("INSERT INTO TABLE_A VALUES (2, 'second A')");
+            executeStatement(
+                "CREATE TABLE TABLE_B (ID_B INTEGER NOT NULL PRIMARY KEY, NAME_B VARCHAR(50))");
+            executeStatement("INSERT INTO TABLE_B VALUES (1, 'first B')");
+            executeStatement("INSERT INTO TABLE_B VALUES (2, 'second B')");
+        } catch (SQLException ex) {
+            fail(ex.toString());
+        }
+    }
+
+    public void setUp() {
+        super.setUp();
+        setupDatabase();
+    }
+
+    protected void tearDown() {
+        executeStatement("SHUTDOWN");
+        super.tearDown();
+    }
+
+    /**
+     * executes a given m_statement
+     *
+     *  <p>Basically, this method calls <code>m_statement.execute(sql)</code>,
+     *  but wraps any <code>SQLException</code>s into a JUnit error.
+     */
+    private void executeStatement(String sql) {
+        executeStatement(sql, 0);
+    }
+
+    private void executeStatement(String sql, int expectedVendorCode) {
+
+        try {
+            m_statement.execute(sql);
+            assertTrue(
+                "executing\n  " + sql
+                + "\nwas expected to fail, but it didn't", expectedVendorCode
+                    == 0);
+        } catch (SQLException ex) {
+            if (expectedVendorCode == 0) {
+                fail(ex.toString());
+            }
+
+            assertEquals(
+                "executing\n  " + sql
+                + "\ndid not result in the expected error", expectedVendorCode, -ex
+                    .getErrorCode());
+        }
+    }
+
+    /**
+     *  creates a view with the given name, the given constituting statement, and an optional column list
+     *
+     *  @param viewName
+     *      specifies the name of the view to create
+     *  @param columnList
+     *      list of names of the columns of the view, will be specified in the CREATE VIEW statement. Might be <code>null</code>.
+     *  @param viewStatement
+     *      the statement of the view
+     */
+    private void createView(String viewName, String[] columnList,
+                            String viewStatement) throws SQLException {
+
+        StringBuffer colList = new StringBuffer();
+
+        if (columnList != null) {
+            colList.append(" (");
+
+            for (int i = 0; i < columnList.length; ++i) {
+                colList.append('"').append(columnList[i]).append('"');
+
+                if (i < columnList.length - 1) {
+                    colList.append(',');
+                }
+            }
+
+            colList.append(")");
+        }
+
+        executeStatement("CREATE VIEW " + viewName + colList.toString()
+                         + " AS " + viewStatement);
+
+        if (columnList != null) {
+            ensureTableColumns(viewName, columnList);
+        }
+    }
+
+    /**
+     *  retrieves the statement which defines a given view
+     */
+    private String getViewStatement(String viewName) throws SQLException {
+
+        ResultSet res = m_statement.executeQuery(
+            "SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = '"
+            + viewName + "'");
+
+        res.next();
+
+        String statement = res.getString(1);
+
+        return statement;
+    }
+
+    /**
+     *  ensures two tables (or views, that is) have the same content
+     */
+    private void ensureEqualContent(String tableNameLHS,
+                                    String tableNameRHS) throws SQLException {
+
+        ResultSet lhs = m_statement.executeQuery("SELECT * FROM \""
+            + tableNameLHS + "\"");
+        ResultSet rhs = m_statement.executeQuery("SELECT * FROM \""
+            + tableNameRHS + "\"");
+        ResultSetMetaData meta = lhs.getMetaData();
+
+        while (lhs.next() && rhs.next()) {
+            for (int col = 1; col <= meta.getColumnCount(); ++col) {
+                assertEquals("table content does not match: cp. "
+                             + tableNameLHS + "-" + tableNameRHS + ", row "
+                             + lhs.getRow() + ", col "
+                             + col, lhs.getObject(col), rhs.getObject(col));
+            }
+        }
+
+        // lhs should be after last, rhs still on last
+        assertTrue("row count does not match: " + tableNameLHS + "-"
+                   + tableNameRHS, lhs.isAfterLast() && rhs.isLast());
+    }
+
+    /**
+     *  ensures the content of a given table matches a given object array's content
+     */
+    private void ensureTableContent(String tableName,
+                                    Object[][] tableData) throws SQLException {
+
+        ResultSet lhs = m_statement.executeQuery("SELECT * FROM \""
+            + tableName + "\"");
+        ResultSetMetaData meta     = lhs.getMetaData();
+        int               colCount = meta.getColumnCount();
+
+        while (lhs.next()) {
+            int row = lhs.getRow();
+
+            assertEquals(colCount, tableData[row - 1].length);
+
+            for (int col = 1; col <= colCount; ++col) {
+                assertEquals(
+                    "unexpected table content in " + tableName + " (row "
+                    + row + ", col " + col + ")", tableData[row - 1][col - 1],
+                                                  lhs.getObject(col));
+            }
+        }
+    }
+
+    /**
+     *  creates a view with a given name and statement, ensures that it's statement is translated as expected, and ensures
+     *  that the content of the view is as expected
+     *
+     *  @param viewName
+     *      the name of the to-be-created view
+     *  @param columnNames
+     *      the names of the columns of the view, as to be specified in the CREATE VIEW statement. Might be null,
+     *      in this case the view will be created without an explicit column list
+     *  @param viewStatement
+     *      the statement of the to-be-created view
+     *  @param expectedTranslatedStatement
+     *      the expected statement of the view, after it has been implicitly translated by HSQL. If the actual
+     *      statement after creation does not match this expected statement, this is a failure condition which
+     *      results in a AssertionFailedError being thrown.
+     *  @param expectedContent
+     *      the expected content of the view. If this is <code>null</code>, it is ignored. Else, if it is a
+     *      string, it is interpreted as name of the table which must have the same content as a view. If
+     *      it's no string either, it must be a two-dimensional Object array specifying the expected content.
+     */
+    private void checkViewTranslationAndContent(String viewName,
+            String[] columnList, String viewStatement,
+            String expectedTranslatedStatement,
+            Object expectedContent) throws SQLException {
+
+        createView(viewName, columnList, viewStatement);
+
+        String actualTranslatedStatement = getViewStatement(viewName);
+
+        if (!actualTranslatedStatement.equals(expectedTranslatedStatement)) {
+            StringBuffer message = new StringBuffer();
+
+            message.append(viewName).append(
+                "'s statement not translated as expected\n");
+            message.append("original statement:\n  ").append(
+                viewStatement).append('\n');
+            message.append("expected translated statement:\n  ").append(
+                expectedTranslatedStatement).append('\n');
+            message.append("actual translated statement:\n  ").append(
+                actualTranslatedStatement).append('\n');
+
+            throw new AssertionFailedError(message.toString());
+        }
+
+        if (expectedContent instanceof Object[][]) {
+            ensureTableContent(viewName, (Object[][]) expectedContent);
+        }
+    }
+
+    /**
+     *  ensures that a given table has columns with a given name
+     */
+    private void ensureTableColumns(String tableName,
+                                    String[] columnNames) throws SQLException {
+
+        ResultSet res = m_connection.getMetaData().getColumns(null, null,
+            tableName, "%");
+
+        while (res.next()) {
+            assertEquals(
+                "unexpected column name in table \"" + tableName
+                + "\" at position "
+                + (res.getRow() - 1), res.getString(
+                    "COLUMN_NAME"), columnNames[res.getRow() - 1]);
+        }
+
+        res.previous();
+        assertEquals("not enough columns in table \"" + tableName + "\"",
+                     columnNames.length, res.getRow());
+    }
+
+    /**
+     *  checks views selecting an asterisk from a table, in different flavours
+     */
+    private void checkSimpleViews() throws SQLException {
+
+        // ................................................................
+        // SELECT *
+        checkViewTranslationAndContent(
+            "S1", null, "SELECT * FROM ABC",
+            "SELECT PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C FROM PUBLIC.ABC",
+            "ABC");
+
+        // adding a column to "ABC" should succeed, and still leave the view with the columns
+        // before the addition
+        executeStatement("ALTER TABLE ABC ADD COLUMN D VARCHAR(50)");
+        ensureTableColumns("ABC", new String[] {
+            "ID", "A", "B", "C", "D"
+        });
+        ensureTableColumns("S1", new String[] {
+            "ID", "A", "B", "C"
+        });
+
+        // dropping the column which is not part of the view should be possible
+        executeStatement("ALTER TABLE ABC DROP COLUMN D");
+
+        // dropping another column which *is* part of the view shouldn't
+        executeStatement("ALTER TABLE ABC DROP COLUMN C", ErrorCode.X_42536);
+
+        // finally, dropping the column with CASCADE should work, and also drop the view
+        //executeStatement("ALTER TABLE ABC DROP COLUMN C CASCADE");
+        // DROP COLUMN c CASCADE not implemented, yet
+        // ................................................................
+        // same as S1, but this time add a LIMIT clause to the statement
+        checkViewTranslationAndContent(
+            "S2", null, "SELECT LIMIT 0 2 * FROM ABC ORDER BY ID",
+            "SELECT LIMIT 0 2 PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C FROM PUBLIC.ABC ORDER BY ID",
+            "ABC");
+
+        // ................................................................
+        // same as S1, but this time add a TOP clause to the statement
+        checkViewTranslationAndContent(
+            "S3", null, "SELECT TOP 2 * FROM ABC ORDER BY ID",
+            "SELECT TOP 2 PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C FROM PUBLIC.ABC ORDER BY ID",
+            "ABC");
+
+        // ................................................................
+        // same as S1, but this time add a DISTINCT clause to the statement
+        checkViewTranslationAndContent(
+            "S4", null, "SELECT DISTINCT * FROM ABC",
+            "SELECT DISTINCT PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C FROM PUBLIC.ABC",
+            "ABC");
+
+        // ................................................................
+        // same as S1, but this time qualifying the asterisk
+        checkViewTranslationAndContent(
+            "S5", null, "SELECT ABC.* FROM ABC",
+            "SELECT  PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C  FROM PUBLIC.ABC",
+            "ABC");
+
+        // ................................................................
+        // same as S5, but this time also giving the table an alias
+        checkViewTranslationAndContent(
+            "S6", null, "SELECT \"A\".* FROM ABC AS A",
+            "SELECT A.ID,A.A,A.B,A.C FROM PUBLIC.ABC AS A",
+            "ABC");
+
+        // ................................................................
+        // same as S1, but bracket the SELECT definition
+        checkViewTranslationAndContent(
+            "S7", null, "( SELECT * FROM ABC )",
+            "(SELECT PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C FROM PUBLIC.ABC)",
+            "ABC");
+    }
+
+    /**
+     *  checks views selecting an asterisk plus existing columns
+     */
+    private void checkAsterisksCombined() throws SQLException {
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "C1", null, "SELECT * AS \"a2\" FROM ABC",
+            "SELECT PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C AS\"a2\" FROM PUBLIC.ABC",
+            new Object[][] {
+            new Object[] {
+                new Integer(1), "a", "b", "c"
+            }, new Object[] {
+                new Integer(2), "d", "e", "f"
+            }
+        });
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "C2", null, "SELECT B AS \"b2\", ABC.* FROM ABC",
+            "SELECT B AS\"b2\" , PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C  FROM PUBLIC.ABC",
+            new Object[][] {
+            new Object[] {
+                "b", new Integer(1), "a", "b", "c"
+            }, new Object[] {
+                "e", new Integer(2), "d", "e", "f"
+            }
+        });
+    }
+
+    /**
+     *  checks views selecting asterisks from multiple tables
+     */
+    private void checkMultipleTables() throws SQLException {
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "M1", null, "SELECT * FROM TABLE_A, TABLE_B",
+            "SELECT PUBLIC.TABLE_A.ID_A,PUBLIC.TABLE_A.NAME_A,PUBLIC.TABLE_B.ID_B,PUBLIC.TABLE_B.NAME_B FROM PUBLIC.TABLE_A,PUBLIC.TABLE_B",
+            new Object[][] {
+            new Object[] {
+                new Integer(1), "first A", new Integer(1), "first B"
+            }, new Object[] {
+                new Integer(1), "first A", new Integer(2), "second B"
+            }, new Object[] {
+                new Integer(2), "second A", new Integer(1), "first B"
+            }, new Object[] {
+                new Integer(2), "second A", new Integer(2), "second B"
+            }
+        });
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "M2", null, "SELECT TABLE_B.*, TABLE_A.* FROM TABLE_A, TABLE_B",
+            "SELECT  PUBLIC.TABLE_B.ID_B,PUBLIC.TABLE_B.NAME_B , PUBLIC.TABLE_A.ID_A,PUBLIC.TABLE_A.NAME_A  FROM PUBLIC.TABLE_A,PUBLIC.TABLE_B",
+            new Object[][] {
+            new Object[] {
+                new Integer(1), "first B", new Integer(1), "first A"
+            }, new Object[] {
+                new Integer(2), "second B", new Integer(1), "first A"
+            }, new Object[] {
+                new Integer(1), "first B", new Integer(2), "second A"
+            }, new Object[] {
+                new Integer(2), "second B", new Integer(2), "second A"
+            }
+        });
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "M3", null, "SELECT \"TABLE_A\".* FROM TABLE_A, TABLE_B",
+            "SELECT PUBLIC.TABLE_A.ID_A,PUBLIC.TABLE_A.NAME_A FROM PUBLIC.TABLE_A,PUBLIC.TABLE_B",
+            new Object[][] {
+            new Object[] {
+                new Integer(1), "first A"
+            }, new Object[] {
+                new Integer(1), "first A"
+            }, new Object[] {
+                new Integer(2), "second A"
+            }, new Object[] {
+                new Integer(2), "second A"
+            }
+        });
+    }
+
+    /**
+     *  checks views selecting from sub selects
+     */
+    private void checkSubSelects() throws SQLException {
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "Q1", null, "SELECT * FROM ( SELECT * FROM ABC )",
+            "SELECT ID,A,B,C FROM(SELECT PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C FROM PUBLIC.ABC)",
+            null);
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "Q2", null,
+            "SELECT * FROM ( SELECT * FROM TABLE_A ), ( SELECT * FROM TABLE_B )",
+            "SELECT ID_A,NAME_A,ID_B,NAME_B FROM(SELECT PUBLIC.TABLE_A.ID_A,PUBLIC.TABLE_A.NAME_A FROM PUBLIC.TABLE_A),(SELECT PUBLIC.TABLE_B.ID_B,PUBLIC.TABLE_B.NAME_B FROM PUBLIC.TABLE_B)",
+            null);
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "Q3", null, "SELECT A.* FROM ( SELECT * FROM TABLE_A ) AS A",
+            "SELECT  A.ID_A,A.NAME_A  FROM(SELECT PUBLIC.TABLE_A.ID_A,PUBLIC.TABLE_A.NAME_A FROM PUBLIC.TABLE_A)AS A",
+            null);
+
+        // ................................................................
+        checkViewTranslationAndContent(
+            "Q4", null,
+            "SELECT A.*, B.* FROM ( SELECT * FROM TABLE_A ) AS A, ( SELECT * FROM TABLE_B ) AS B",
+            "SELECT  A.ID_A,A.NAME_A , B.ID_B,B.NAME_B  FROM(SELECT PUBLIC.TABLE_A.ID_A,PUBLIC.TABLE_A.NAME_A FROM PUBLIC.TABLE_A)AS A,(SELECT PUBLIC.TABLE_B.ID_B,PUBLIC.TABLE_B.NAME_B FROM PUBLIC.TABLE_B)AS B",
+            null);
+    }
+
+    /**
+     *  checks views which are defined using a column list
+     */
+    private void checkColumnLists() throws SQLException {
+
+        // just to ensure the column count handling is as expected, else below tests might be useless
+        executeStatement("CREATE VIEW IMPOSSIBLE (\"A\") AS SELECT * FROM ABC",
+                         ErrorCode.X_42593);
+
+        // ................................................................
+        // not that it should make any difference to S1, but who knows
+        checkViewTranslationAndContent("L1", new String[] {
+            "C1", "C2", "C3", "C4"
+        }, "SELECT * FROM ABC", "SELECT PUBLIC.ABC.ID,PUBLIC.ABC.A,PUBLIC.ABC.B,PUBLIC.ABC.C FROM PUBLIC.ABC",
+           "ABC");
+    }
+
+    /**
+     *  checks views based on other views
+     */
+    private void checkViewsOnViews() throws SQLException {
+
+        // ................................................................
+        // not that it should make any difference whether we SELECT FROM a table or view, but who knows
+        checkViewTranslationAndContent(
+            "V1", null, "SELECT * FROM S1",
+            "SELECT PUBLIC.S1.ID,PUBLIC.S1.A,PUBLIC.S1.B,PUBLIC.S1.C FROM PUBLIC.S1", "L1");
+    }
+
+    /**
+     *  checks views based on a UNION statement
+     */
+    private void checkUnionViews() throws SQLException {
+
+        checkViewTranslationAndContent(
+            "U1", null, "SELECT * FROM TABLE_A UNION SELECT * FROM TABLE_B",
+            "SELECT PUBLIC.TABLE_A.ID_A,PUBLIC.TABLE_A.NAME_A FROM PUBLIC.TABLE_A UNION SELECT PUBLIC.TABLE_B.ID_B,PUBLIC.TABLE_B.NAME_B FROM PUBLIC.TABLE_B",
+            new Object[][] {
+            new Object[] {
+                new Integer(1), "first A"
+            }, new Object[] {
+                new Integer(1), "first B"
+            }, new Object[] {
+                new Integer(2), "second A"
+            }, new Object[] {
+                new Integer(2), "second B"
+            }
+        });
+        checkViewTranslationAndContent(
+            "U2", null,
+            "SELECT * FROM ( SELECT * FROM TABLE_A UNION SELECT * FROM TABLE_B )",
+            "SELECT ID_A,NAME_A FROM(SELECT PUBLIC.TABLE_A.ID_A,PUBLIC.TABLE_A.NAME_A FROM PUBLIC.TABLE_A UNION SELECT PUBLIC.TABLE_B.ID_B,PUBLIC.TABLE_B.NAME_B FROM PUBLIC.TABLE_B)",
+            new Object[][] {
+            new Object[] {
+                new Integer(1), "first A"
+            }, new Object[] {
+                new Integer(1), "first B"
+            }, new Object[] {
+                new Integer(2), "second A"
+            }, new Object[] {
+                new Integer(2), "second B"
+            }
+        });
+    }
+
+    /**
+     *  main test method of this class
+     */
+    public void test() {
+
+        try {
+            checkSimpleViews();
+            checkAsterisksCombined();
+            checkMultipleTables();
+            checkSubSelects();
+            checkColumnLists();
+            checkViewsOnViews();
+            checkUnionViews();
+        } catch (SQLException ex) {
+            fail(ex.toString());
+        }
+    }
+
+    /**
+     *  entry point to run the test directly
+     */
+    public static void main(String[] argv) {
+        runWithResult(TestViewAsterisks.class, "test");
+    }
+}
diff --git a/src/org/hsqldb/test/TriggerClass.java b/src/org/hsqldb/test/TriggerClass.java
new file mode 100644
index 0000000..68cd76f
--- /dev/null
+++ b/src/org/hsqldb/test/TriggerClass.java
@@ -0,0 +1,46 @@
+/* Copyright (c) 2001-2009, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import org.hsqldb.Trigger;
+
+public class TriggerClass implements Trigger {
+
+    static int   callCount;
+    static int[] callCounts = new int[12];
+
+    public void fire(int type, String trigName, String tabName,
+                     Object[] oldRow, Object[] newRow) {
+        callCounts[type]++;
+        callCount++;
+    }
+}
diff --git a/src/org/hsqldb/test/Waiter.java b/src/org/hsqldb/test/Waiter.java
new file mode 100644
index 0000000..8e78c42
--- /dev/null
+++ b/src/org/hsqldb/test/Waiter.java
@@ -0,0 +1,122 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.test;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Single-use synchronization object.
+ *
+ * Design would be more scalable if there were a separate collection class,
+ * instead of the static Waiter.map.  The limitation is acceptable since
+ * there's no use case for running multiple Test Runners simultaneously
+ * from a single JVM (one Test runner can handle multiple test scripts
+ * simultaneously or synchronously).
+ *
+ * (It would be much work to make the collection non-static, because that
+ * would require a refactor of TestUtil with proper OOD).
+ */
+public class Waiter {
+    /*
+    static private HashMap<String, Waiter> map =
+            new HashMap<String, Waiter>();
+    Java 5 */
+    static private Map map = new HashMap();
+    private String key;
+    private boolean notified = false; // resume() method has been called
+    private boolean waiting = false;  // a client is waiting (in waitFor()).
+    private boolean abort = false;  // Make fail if partner failed
+
+    public boolean isNotified() { return notified; }
+    public boolean isWaiting() { return waiting; }
+
+    private Waiter(String key) {
+        this.key = key;
+        map.put(key, this);
+    }
+
+    /**
+     * @param enforceSequence  Fail if waitFor() called before resume()
+     */
+    public synchronized void waitFor(boolean enforceSequence) {
+        if (abort)
+            throw new RuntimeException("Notifier side failed previously");
+        if (notified) {
+            if (enforceSequence)
+                throw new RuntimeException(
+                        "Request to wait on '" + key
+                        + "', but this object has already been notified");
+            return;
+        }
+        waiting = true;
+        try {
+            wait();
+        } catch (InterruptedException ie) {
+            throw new RuntimeException(
+                    "Unexpected interrupted while waiting for '"
+                    + key + "'", ie);
+        } finally {
+            waiting = false;
+        }
+        map.remove(this);
+        if (!notified)
+            throw new RuntimeException(
+                    "Exiting waitFor() on '" + key
+                    + "' even though not 'notified'");
+    }
+
+    /**
+     * @param enforceSequence  Fail if waitFor() called before resume()
+     */
+    public synchronized void resume(boolean enforceSequence) {
+        if (enforceSequence && !waiting) {
+            abort = true;
+            throw new RuntimeException("Requested to resume on '"
+                    + key + " ', but nothing is waiting for it");
+        }
+        notified = true;
+        notify();
+    }
+
+    /**
+     * It doesn't matter if the waiter or the waitee runs getWaiter()
+     * first.  Whoever requests it first will instantiate it.
+     *
+     * @return A Waiter instance.  Never returns nul.
+     */
+    synchronized static public Waiter getWaiter(String key) {
+        Waiter waiter = (Waiter) map.get(key);
+        if (waiter == null) waiter = new Waiter(key);
+        return waiter;
+    }
+}
diff --git a/src/org/hsqldb/types/ArrayType.java b/src/org/hsqldb/types/ArrayType.java
new file mode 100644
index 0000000..00f644a
--- /dev/null
+++ b/src/org/hsqldb/types/ArrayType.java
@@ -0,0 +1,359 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Class for ARRAY type objects.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class ArrayType extends Type {
+
+    final Type dataType;
+    final int  maxCardinality;
+
+    public ArrayType(Type dataType, int cardinality) {
+
+        super(Types.SQL_ARRAY, Types.SQL_ARRAY, 0, 0);
+
+        this.dataType       = dataType;
+        this.maxCardinality = cardinality;
+    }
+
+    public int displaySize() {
+        return 7 + (dataType.displaySize() + 1) * maxCardinality ;
+    }
+
+    public int getJDBCTypeCode() {
+        return Types.ARRAY;
+    }
+
+    public Class getJDBCClass() {
+        return java.sql.Array.class;
+    }
+
+    public String getJDBCClassName() {
+        return "java.sql.Array";
+    }
+
+    public Integer getJDBCScale() {
+        return ValuePool.INTEGER_0;
+    }
+
+    public int getJDBCPrecision() {
+        return ValuePool.INTEGER_0;
+    }
+
+    public int getSQLGenericTypeCode() {
+        return 0;
+    }
+
+    public String getNameString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(dataType.getNameString()).append(' ');
+        sb.append(Tokens.T_ARRAY);
+
+        if (maxCardinality != defaultArrayCardinality) {
+            sb.append('[').append(maxCardinality).append(']');
+        }
+
+        return sb.toString();
+    }
+
+    String getDefinition() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(dataType.getDefinition()).append(' ');
+        sb.append(Tokens.T_ARRAY);
+
+        if (maxCardinality != defaultArrayCardinality) {
+            sb.append('[').append(maxCardinality).append(']');
+        }
+
+        return sb.toString();
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        Object[] arra   = (Object[]) a;
+        Object[] arrb   = (Object[]) b;
+        int      length = arra.length;
+
+        if (arrb.length < length) {
+            length = arrb.length;
+        }
+
+        for (int i = 0; i < length; i++) {
+            int result = dataType.compare(session, arra[i], arrb[i]);
+
+            if (result != 0) {
+                return result;
+            }
+        }
+
+        if (arra.length > arrb.length) {
+            return 1;
+        } else if (arra.length < arrb.length) {
+            return -1;
+        }
+
+        return 0;
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        Object[] arra = (Object[]) a;
+
+        if (arra.length > maxCardinality) {
+            throw Error.error(ErrorCode.X_2202F);
+        }
+
+        Object[] arrb = new Object[arra.length];
+
+        for (int i = 0; i < arra.length; i++) {
+            arrb[i] = dataType.convertToTypeLimits(session, arra[i]);
+        }
+
+        return arrb;
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (otherType == null) {
+            return a;
+        }
+
+        if (!otherType.isArrayType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        Object[] arra = (Object[]) a;
+
+        if (arra.length > maxCardinality) {
+            throw Error.error(ErrorCode.X_2202F);
+        }
+
+        Type otherComponent = otherType.collectionBaseType();
+
+        if (dataType.equals(otherComponent)) {
+            return a;
+        }
+
+        Object[] arrb = new Object[arra.length];
+
+        for (int i = 0; i < arra.length; i++) {
+            arrb[i] = dataType.convertToType(session, arra[i], otherComponent);
+        }
+
+        return arrb;
+    }
+
+    public Object convertToDefaultType(SessionInterface sessionInterface,
+                                       Object o) {
+        return o;
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return convertToSQLString(a);
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        Object[]     arra = (Object[]) a;
+        StringBuffer sb   = new StringBuffer();
+
+        sb.append(Tokens.T_ARRAY);
+        sb.append('[');
+
+        for (int i = 0; i < arra.length; i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+
+            sb.append(dataType.convertToSQLString(arra[i]));
+        }
+
+        sb.append(']');
+
+        return sb.toString();
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+
+        if (otherType == null) {
+            return true;
+        }
+
+        if (!otherType.isArrayType()) {
+            return false;
+        }
+
+        Type otherComponent = otherType.collectionBaseType();
+
+        return dataType.canConvertFrom(otherComponent);
+    }
+
+    public boolean canBeAssignedFrom(Type otherType) {
+
+        if (otherType == null) {
+            return true;
+        }
+
+        Type otherComponent = otherType.collectionBaseType();
+
+        return otherComponent != null
+               && dataType.canBeAssignedFrom(otherComponent);
+    }
+
+    public Type collectionBaseType() {
+        return dataType;
+    }
+
+    public int arrayLimitCardinality() {
+        return maxCardinality;
+    }
+
+    public boolean isArrayType() {
+        return true;
+    }
+
+    public Type getAggregateType(Type otherType) {
+
+        if (otherType == null) {
+            return this;
+        }
+
+        if (!otherType.isArrayType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        Type otherComponent = otherType.collectionBaseType();
+
+        if (dataType.equals(otherComponent)) {
+            return this;
+        }
+
+        Type newType = dataType.getAggregateType(otherComponent);
+
+        return new ArrayType(newType, maxCardinality);
+    }
+
+    public Type getCombinedType(Type otherType, int operation) {
+
+        if (operation != OpTypes.CONCAT) {
+            return getAggregateType(otherType);
+        }
+
+        if (otherType == null) {
+            return this;
+        }
+
+        if (!otherType.isArrayType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        Type otherComponent = otherType.collectionBaseType();
+        Type combinedType   = dataType.getAggregateType(otherComponent);
+
+        return new ArrayType(combinedType,
+                             maxCardinality
+                             + otherType.arrayLimitCardinality());
+    }
+
+    public int cardinality(Session session, Object a) {
+
+        if (a == null) {
+            return 0;
+        }
+
+        return ((Object[]) a).length;
+    }
+
+    public Object concat(Session session, Object a, Object b) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        int      size  = ((Object[]) a).length + ((Object[]) b).length;
+        Object[] array = new Object[size];
+
+        System.arraycopy(a, 0, array, 0, ((Object[]) a).length);
+        System.arraycopy(b, 0, array, ((Object[]) a).length,
+                         ((Object[]) b).length);
+
+        return array;
+    }
+}
diff --git a/src/org/hsqldb/types/BinaryData.java b/src/org/hsqldb/types/BinaryData.java
new file mode 100644
index 0000000..96a74da
--- /dev/null
+++ b/src/org/hsqldb/types/BinaryData.java
@@ -0,0 +1,282 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+
+/**
+ * Implementation of BlobData for memory binary data.<p>
+ * A Binary object instance always wraps a non-null byte[] object.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class BinaryData implements BlobData {
+
+    public final static BinaryData singleBitZero =
+        new BinaryData(new byte[]{ 0 }, 1);
+    public final static BinaryData singleBitOne =
+        new BinaryData(new byte[]{ -0x80 }, 1);
+    public final static BinaryData zeroLengthBinary =
+        new BinaryData(new byte[0], false);
+    long             id;
+    protected byte[] data;
+    private boolean  isBits;
+    private long     bitLength;
+
+    public static BinaryData getBitData(byte[] data, long bitLength) {
+
+        if (bitLength == 1) {
+            return data[0] == 0 ? singleBitZero
+                                : singleBitOne;
+        }
+
+        return new BinaryData(data, bitLength);
+    }
+
+    /**
+     * This constructor is used inside the engine when an already serialized
+     * byte[] is read from a file (.log, .script, .data or text table source).
+     * In this case clone is false.
+     *
+     * When a byte[] is submitted as a parameter of PreparedStatement then
+     * clone is true.
+     */
+    public BinaryData(byte[] data, boolean clone) {
+
+        if (clone) {
+            data = (byte[]) ArrayUtil.duplicateArray(data);
+        }
+
+        this.data      = data;
+        this.bitLength = data.length * 8;
+    }
+
+    public BinaryData(SessionInterface session, BlobData b1, BlobData b2) {
+
+        long length = (b1.length(session) + b2.length(session));
+
+        if (length > Integer.MAX_VALUE) {
+            throw Error.error(ErrorCode.X_22001);
+        }
+
+        data = new byte[(int) length];
+
+        System.arraycopy(b1.getBytes(), 0, data, 0, (int) b1.length(session));
+        System.arraycopy(b2.getBytes(), 0, data, (int) b1.length(session),
+                         (int) b2.length(session));
+
+        this.bitLength = (b1.length(session) + b2.length(session)) * 8;
+    }
+
+    public BinaryData(byte[] data, long bitLength) {
+
+        this.data      = data;
+        this.bitLength = bitLength;
+        this.isBits    = true;
+    }
+
+    public BinaryData(long length, DataInput stream) {
+
+        data      = new byte[(int) length];
+        bitLength = data.length * 8;
+
+        try {
+            stream.readFully(data);
+        } catch (IOException e) {
+            throw Error.error(ErrorCode.GENERAL_IO_ERROR, e);
+        }
+    }
+
+    public byte[] getBytes() {
+        return data;
+    }
+
+    public long length(SessionInterface session) {
+        return data.length;
+    }
+
+    public long bitLength(SessionInterface session) {
+        return bitLength;
+    }
+
+    public boolean isBits() {
+        return isBits;
+    }
+
+    public byte[] getBytes(SessionInterface session, long pos, int length) {
+
+        if (!isInLimits(data.length, pos, length)) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        byte[] bytes = new byte[length];
+
+        System.arraycopy(data, (int) pos, bytes, 0, length);
+
+        return bytes;
+    }
+
+    public BlobData getBlob(SessionInterface session, long pos, long length) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "BinaryData");
+    }
+
+    public InputStream getBinaryStream(SessionInterface session) {
+        return new BlobInputStream(session, this, 0L, length(session));
+    }
+
+    public InputStream getBinaryStream(SessionInterface session, long pos,
+                                       long length) {
+
+        if (!isInLimits(data.length, pos, length)) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        return new BlobInputStream(session, this, pos, length(session));
+    }
+
+    public int setBytes(SessionInterface session, long pos, byte[] bytes,
+                        int offset, int length) {
+
+        if (!isInLimits(data.length, pos, 0)) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        if (!isInLimits(data.length, pos, length)) {
+            data = (byte[]) ArrayUtil.resizeArray(data, (int) pos + length);
+        }
+
+        System.arraycopy(bytes, offset, data, (int) pos, length);
+
+        bitLength = data.length * 8;
+
+        return length;
+    }
+
+    public int setBytes(SessionInterface session, long pos, byte[] bytes) {
+
+        setBytes(session, pos, bytes, 0, bytes.length);
+
+        return bytes.length;
+    }
+
+    public long setBinaryStream(SessionInterface session, long pos,
+                                InputStream in) {
+        return 0;
+    }
+
+    public OutputStream setBinaryStream(SessionInterface session, long pos) {
+        return null;
+    }
+
+    public void truncate(SessionInterface session, long len) {
+
+        if (data.length > len) {
+            data      = (byte[]) ArrayUtil.resizeArray(data, (int) len);
+            bitLength = data.length * 8;
+        }
+    }
+
+    public BlobData duplicate(SessionInterface session) {
+        return new BinaryData(data, true);
+    }
+
+    public long position(SessionInterface session, byte[] pattern,
+                         long start) {
+
+        if (pattern.length > data.length) {
+            return -1;
+        }
+
+        if (start >= data.length) {
+            return -1;
+        }
+
+        return ArrayUtil.find(data, (int) start, data.length, pattern);
+    }
+
+    public long position(SessionInterface session, BlobData pattern,
+                         long start) {
+
+        if (pattern.length(session) > data.length) {
+            return -1;
+        }
+
+        byte[] bytes = pattern.getBytes();
+
+        return position(session, bytes, start);
+    }
+
+    public long nonZeroLength(SessionInterface session) {
+
+        // temp
+        return data.length;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public int getStreamBlockSize() {
+        return 512 * 1024;
+    }
+
+    public boolean isClosed() {
+        return false;
+    }
+
+    public void free() {}
+
+    public void setSession(SessionInterface session) {}
+
+    //---
+    static boolean isInLimits(long fullLength, long pos, long len) {
+        return pos >= 0 && len >= 0 && pos + len <= fullLength;
+    }
+
+    public boolean isBinary() {
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/types/BinaryType.java b/src/org/hsqldb/types/BinaryType.java
new file mode 100644
index 0000000..5fa47d1
--- /dev/null
+++ b/src/org/hsqldb/types/BinaryType.java
@@ -0,0 +1,706 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.StringConverter;
+
+/**
+ * Type implementation for BINARY, VARBINARY and (part) BLOB.<p>
+
+ * SQL:2008 Standard  specifies silent truncation of zero bytes at the end of the
+ * binary strings used for assignment and contatenation.<p>
+ *
+ * * A binary string of type BINARY VALYING and BLOB when assigned to a column
+ * of similar type but shorter maximum length.<p?
+ *
+ * * The Second operand of a concatenation when the length of the result exceeds
+ * the maximum implementation-dependent length of BINARY VARYING and BLOB
+ * binary strings.<p>
+ *
+ * The behaviour is similar to trimming of space characters from strings of
+ * CHARACTER VARYING and CLOB types.<p>
+ *
+ * <p>
+ * In most real-world use-cases, all the bytes of variable-length binary values
+ * stored in a database are significant and should not be discarded.<p>
+ *
+ * HSQLDB follows the Standard completely, despite this inadequecy.<p>
+ *
+ * Comparison of binary values follows the Standard. When two values are not
+ * the same length and all the bytes of the shorter value equal the initial
+ * sequence of bytes of the longer value, then the shorter value is the smaller.
+ * The Standard treats this determination as implementation dependent.<p>
+ *
+ * BIT types, which were part of the SQL:1999, can be converted to and from
+ * BINARY. The BIT strings may be padded with zero bits for byte alignment.<p>
+ *
+ * As an extension to the Standard, HSQLDB supports cast from CHARACTER types
+ * to BINARY. The length of the string must be even and all character
+ * must be hexadecimal characters.<p>
+ *
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class BinaryType extends Type {
+
+    static final long maxBinaryPrecision = Integer.MAX_VALUE;
+
+    protected BinaryType(int type, long precision) {
+        super(Types.SQL_VARBINARY, type, precision, 0);
+    }
+
+    public int displaySize() {
+        return precision > Integer.MAX_VALUE ? Integer.MAX_VALUE
+                                             : (int) precision;
+    }
+
+    public int getJDBCTypeCode() {
+        return typeCode == Types.SQL_BINARY ? Types.BINARY
+                                            : Types.VARBINARY;
+    }
+
+    public Class getJDBCClass() {
+        return byte[].class;
+    }
+
+    public String getJDBCClassName() {
+        return "[B";
+    }
+
+    public String getNameString() {
+        return typeCode == Types.SQL_BINARY ? Tokens.T_BINARY
+                                            : Tokens.T_VARBINARY;
+    }
+
+    public String getNameFullString() {
+        return typeCode == Types.SQL_BINARY ? Tokens.T_BINARY
+                                            : "BINARY VARYING";
+    }
+
+    public String getDefinition() {
+
+        if (precision == 0) {
+            return getNameString();
+        }
+
+        StringBuffer sb = new StringBuffer(16);
+
+        sb.append(getNameString());
+        sb.append('(');
+        sb.append(precision);
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public boolean isBinaryType() {
+        return true;
+    }
+
+    public boolean acceptsPrecision() {
+        return true;
+    }
+
+    public long getMaxPrecision() {
+        return maxBinaryPrecision;
+    }
+
+    public boolean requiresPrecision() {
+        return typeCode == Types.SQL_VARBINARY;
+    }
+
+    /**
+     * relaxes the SQL standard list to avoid problems with covnersion of
+     * literals and java method parameter type issues
+     */
+    public int precedenceDegree(Type other) {
+
+        if (other.typeCode == typeCode) {
+            return 0;
+        }
+
+        if (!other.isBinaryType()) {
+            return Integer.MIN_VALUE;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                return Integer.MIN_VALUE;
+
+            case Types.SQL_BINARY :
+                return other.typeCode == Types.SQL_BLOB ? 4
+                                                        : 2;
+
+            case Types.SQL_VARBINARY :
+                return other.typeCode == Types.SQL_BLOB ? 4
+                                                        : 2;
+
+            case Types.SQL_BLOB :
+                return other.typeCode == Types.SQL_BINARY ? -4
+                                                          : -2;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "BinaryType");
+        }
+    }
+
+    public Type getAggregateType(Type other) {
+
+        if (typeCode == other.typeCode) {
+            return precision >= other.precision ? this
+                                                : other;
+        }
+
+        if (other.isCharacterType()) {
+            return other.getAggregateType(this);
+        }
+
+        switch (other.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                return this;
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING : {
+                long bytePrecision = (other.precision + 7) / 8;
+
+                return precision >= bytePrecision ? this
+                                                  : getBinaryType(
+                                                      this.typeCode,
+                                                      bytePrecision);
+            }
+            case Types.SQL_BINARY :
+                return precision >= other.precision ? this
+                                                    : getBinaryType(typeCode,
+                                                    other.precision);
+
+            case Types.SQL_VARBINARY :
+                if (typeCode == Types.SQL_BLOB) {
+                    return precision >= other.precision ? this
+                                                        : getBinaryType(
+                                                        typeCode,
+                                                        other.precision);
+                } else {
+                    return other.precision >= precision ? other
+                                                        : getBinaryType(
+                                                        other.typeCode,
+                                                        precision);
+                }
+            case Types.SQL_BLOB :
+                return other.precision >= precision ? other
+                                                    : getBinaryType(
+                                                    other.typeCode, precision);
+
+            default :
+                throw Error.error(ErrorCode.X_42562);
+        }
+    }
+
+    /**
+     * Returns type for concat
+     */
+    public Type getCombinedType(Type other, int operation) {
+
+        if (operation != OpTypes.CONCAT) {
+            return getAggregateType(other);
+        }
+
+        Type newType;
+        long newPrecision = this.precision + other.precision;
+
+        switch (other.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                return this;
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                newPrecision = this.precision + (other.precision + 7) / 8;
+                newType      = this;
+                break;
+
+            case Types.SQL_BINARY :
+                newType = this;
+                break;
+
+            case Types.SQL_VARBINARY :
+                newType = (typeCode == Types.SQL_BLOB) ? this
+                                                       : other;
+                break;
+
+            case Types.SQL_BLOB :
+                newType = other;
+                break;
+
+            default :
+                throw Error.error(ErrorCode.X_42561);
+        }
+
+        if (newPrecision > maxBinaryPrecision) {
+            if (typeCode == Types.SQL_BINARY) {
+
+                // Standard disallows type length reduction
+                throw Error.error(ErrorCode.X_42570);
+            } else if (typeCode == Types.SQL_VARBINARY) {
+                newPrecision = maxBinaryPrecision;
+            }
+        }
+
+        return getBinaryType(newType.typeCode, newPrecision);
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        if (a instanceof BinaryData && b instanceof BinaryData) {
+            byte[] data1  = ((BinaryData) a).getBytes();
+            byte[] data2  = ((BinaryData) b).getBytes();
+            int    length = data1.length > data2.length ? data2.length
+                                                        : data1.length;
+
+            for (int i = 0; i < length; i++) {
+                if (data1[i] == data2[i]) {
+                    continue;
+                }
+
+                return (((int) data1[i]) & 0xff) > (((int) data2[i]) & 0xff)
+                       ? 1
+                       : -1;
+            }
+
+            if (data1.length == data2.length) {
+                return 0;
+            }
+
+            return data1.length > data2.length ? 1
+                                               : -1;
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "BinaryType");
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+        return castOrConvertToType(session, a, this, false);
+    }
+
+    public Object castToType(SessionInterface session, Object a,
+                             Type otherType) {
+        return castOrConvertToType(session, a, otherType, true);
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+        return castOrConvertToType(session, a, otherType, false);
+    }
+
+    public Object convertJavaToSQL(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (a instanceof byte[]) {
+            return new BinaryData((byte[]) a, true);
+        }
+
+        throw Error.error(ErrorCode.X_42561);
+    }
+
+    public Object convertSQLToJava(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return ((BlobData) a).getBytes();
+    }
+
+    Object castOrConvertToType(SessionInterface session, Object a,
+                               Type otherType, boolean cast) {
+
+        BlobData b;
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (otherType.typeCode) {
+
+            // non-SQL feature, for compatibility with previous versions
+            case Types.SQL_VARCHAR :
+            case Types.SQL_CHAR : {
+                b = session.getScanner().convertToBinary((String) a);
+                otherType = getBinaryType(Types.SQL_VARBINARY,
+                                          b.length(session));
+
+                break;
+            }
+            case Types.SQL_BIT : {
+                b = (BlobData) a;
+                otherType = getBinaryType(Types.SQL_VARBINARY,
+                                          b.length(session));
+
+                break;
+            }
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.SQL_BLOB :
+                b = (BlobData) a;
+                break;
+
+            default :
+                throw Error.error(ErrorCode.X_22501);
+        }
+
+        if (precision == 0) {
+            return b;    // never a blob
+        }
+
+        if (b.length(session) > precision
+                && b.nonZeroLength(session) > precision) {
+            if (!cast) {
+                throw Error.error(ErrorCode.X_22001);
+            }
+
+            session.addWarning(Error.error(ErrorCode.W_01004));
+        }
+
+        if (otherType.typeCode == Types.SQL_BLOB) {
+            long blobLength = b.length(session);
+
+            if (blobLength > precision) {
+                throw Error.error(ErrorCode.X_22501);
+            }
+
+            byte[] bytes = b.getBytes(session, 0, (int) blobLength);
+
+            b = new BinaryData(bytes, false);
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_BINARY : {
+                if (b.length(session) > precision) {
+                    byte[] data = b.getBytes(session, 0, (int) precision);
+
+                    b = new BinaryData(data, false);
+                } else if (b.length(session) < precision) {
+                    byte[] data = (byte[]) ArrayUtil.resizeArray(b.getBytes(),
+                        (int) precision);
+
+                    b = new BinaryData(data, false);
+                }
+
+                return b;
+            }
+            case Types.SQL_VARBINARY : {
+                if (b.length(session) > precision) {
+                    byte[] data = b.getBytes(session, 0, (int) precision);
+
+                    b = new BinaryData(data, false);
+                }
+
+                return b;
+            }
+            default :
+        }
+
+        throw Error.error(ErrorCode.X_22501);
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return a;
+        }
+
+        if (a instanceof byte[]) {
+            return new BinaryData((byte[]) a, false);
+        } else if (a instanceof BinaryData) {
+            return a;
+        } else if (a instanceof String) {
+            return castOrConvertToType(session, a, Type.SQL_VARCHAR, false);
+        }
+
+        throw Error.error(ErrorCode.X_22501);
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return StringConverter.byteArrayToHexString(((BlobData) a).getBytes());
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        return StringConverter.byteArrayToSQLHexString(
+            ((BinaryData) a).getBytes());
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+        return otherType.typeCode == Types.SQL_ALL_TYPES
+               || otherType.isBinaryType() || otherType.isCharacterType();
+    }
+
+    public long position(SessionInterface session, BlobData data,
+                         BlobData otherData, Type otherType, long offset) {
+
+        if (data == null || otherData == null) {
+            return -1L;
+        }
+
+        long otherLength = ((BlobData) data).length(session);
+
+        if (offset + otherLength > data.length(session)) {
+            return -1;
+        }
+
+        return data.position(session, otherData, offset);
+    }
+
+    public BlobData substring(SessionInterface session, BlobData data,
+                              long offset, long length, boolean hasLength) {
+
+        long end;
+        long dataLength = data.length(session);
+
+        if (hasLength) {
+            end = offset + length;
+        } else {
+            end = dataLength > offset ? dataLength
+                                      : offset;
+        }
+
+        if (offset > end) {
+            throw Error.error(ErrorCode.X_22011);
+        }
+
+        if (offset > end || end < 0) {
+
+            // return zero length data
+            offset = 0;
+            end    = 0;
+        }
+
+        if (offset < 0) {
+            offset = 0;
+        }
+
+        if (end > dataLength) {
+            end = dataLength;
+        }
+
+        length = end - offset;
+
+        // change method signature to take long
+        byte[] bytes = ((BlobData) data).getBytes(session, offset,
+            (int) length);
+
+        return new BinaryData(bytes, false);
+    }
+
+    int getRightTrimSize(BlobData data) {
+
+        byte[] bytes    = data.getBytes();
+        int    endindex = bytes.length;
+
+        for (--endindex; endindex >= 0 && bytes[endindex] == 0; endindex--) {}
+
+        return ++endindex;
+    }
+
+    public BlobData trim(Session session, BlobData data, int trim,
+                         boolean leading, boolean trailing) {
+
+        if (data == null) {
+            return null;
+        }
+
+        byte[] bytes    = ((BlobData) data).getBytes();
+        int    endindex = bytes.length;
+
+        if (trailing) {
+            for (--endindex; endindex >= 0 && bytes[endindex] == trim;
+                    endindex--) {}
+
+            endindex++;
+        }
+
+        int startindex = 0;
+
+        if (leading) {
+            while (startindex < endindex && bytes[startindex] == trim) {
+                startindex++;
+            }
+        }
+
+        byte[] newBytes = bytes;
+
+        if (startindex != 0 || endindex != bytes.length) {
+            newBytes = new byte[endindex - startindex];
+
+            System.arraycopy(bytes, startindex, newBytes, 0,
+                             endindex - startindex);
+        }
+
+        if (typeCode == Types.SQL_BLOB) {
+            BlobData blob = session.createBlob(newBytes.length);
+
+            blob.setBytes(session, 0, newBytes);
+
+            return blob;
+        } else {
+            return new BinaryData(newBytes, newBytes == bytes);
+        }
+    }
+
+    public BlobData overlay(Session session, BlobData data, BlobData overlay,
+                            long offset, long length, boolean hasLength) {
+
+        if (data == null || overlay == null) {
+            return null;
+        }
+
+        if (!hasLength) {
+            length = ((BlobData) overlay).length(session);
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY : {
+                BinaryData binary =
+                    new BinaryData(session,
+                                   substring(session, data, 0, offset, true),
+                                   overlay);
+
+                binary = new BinaryData(session, binary,
+                                        substring(session, data,
+                                                  offset + length, 0, false));
+
+                return binary;
+            }
+            case Types.SQL_BLOB : {
+                byte[] bytes = substring(session, data, 0, offset,
+                                         false).getBytes();
+                long blobLength = data.length(session)
+                                  + overlay.length(session) - length;
+                BlobData blob = session.createBlob(blobLength);
+
+                blob.setBytes(session, 0, bytes);
+                blob.setBytes(session, blob.length(session),
+                              overlay.getBytes());
+
+                bytes = substring(session, data, offset + length, 0,
+                                  false).getBytes();
+
+                blob.setBytes(session, blob.length(session), bytes);
+
+                return blob;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "BinaryType");
+        }
+    }
+
+    public Object concat(Session session, Object a, Object b) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        long length = ((BlobData) a).length(session)
+                      + ((BlobData) b).length(session);
+
+        if (length > precision) {
+            throw Error.error(ErrorCode.X_22001);
+        }
+
+        if (typeCode == Types.SQL_BLOB) {
+            BlobData blob = session.createBlob(length);
+
+            blob.setBytes(session, 0, ((BlobData) b).getBytes());
+            blob.setBytes(session, ((BlobData) a).length(session),
+                          ((BlobData) b).getBytes());
+
+            return blob;
+        } else {
+            return new BinaryData(session, (BlobData) a, (BlobData) b);
+        }
+    }
+
+    /** @todo check and adjust max precision */
+    public static BinaryType getBinaryType(int type, long precision) {
+
+        switch (type) {
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+                return new BinaryType(type, precision);
+
+            case Types.SQL_BLOB :
+                return new BlobType(precision);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "BinaryType");
+        }
+    }
+}
diff --git a/src/org/hsqldb/types/BitType.java b/src/org/hsqldb/types/BitType.java
new file mode 100644
index 0000000..68beaca
--- /dev/null
+++ b/src/org/hsqldb/types/BitType.java
@@ -0,0 +1,571 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.store.BitMap;
+
+/**
+ *
+ * Operations allowed on BIT strings are CONCAT, SUBSTRING, POSITION,
+ * BIT_LENGTH and OCTECT_LENGTH.<p>
+ *
+ * BIT values can be cast to BINARY and vice-versa. In casts, BIT values are
+ * converted to their counterpart BINARY values by treating each set of 8 bits
+ * or less as a signle byte. The first bit of a BIT string is treated as the most
+ * significan bit of the resutling byte value. Binary values are converted by
+ * treating the bits in the sequence of bytes as sequence of bits in the BIT
+ * string<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class BitType extends BinaryType {
+
+    static final long maxBitPrecision = 1024;
+
+    public BitType(int type, long precision) {
+        super(type, precision);
+    }
+
+    public int displaySize() {
+        return (int) precision;
+    }
+
+    public int getJDBCTypeCode() {
+        return Types.BIT;
+    }
+
+    public Class getJDBCClass() {
+        return byte[].class;
+    }
+
+    public String getJDBCClassName() {
+        return "[B";
+    }
+
+    public int getSQLGenericTypeCode() {
+        return typeCode;
+    }
+
+    public String getNameString() {
+        return typeCode == Types.SQL_BIT ? Tokens.T_BIT
+                                         : "BIT VARYING";
+    }
+
+    public String getDefinition() {
+
+        if (precision == 0) {
+            return getNameString();
+        }
+
+        StringBuffer sb = new StringBuffer(16);
+
+        sb.append(getNameString());
+        sb.append('(');
+        sb.append(precision);
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public boolean isBitType() {
+        return true;
+    }
+
+    public long getMaxPrecision() {
+        return maxBitPrecision;
+    }
+
+    public boolean requiresPrecision() {
+        return typeCode == Types.SQL_BIT_VARYING;
+    }
+
+    public Type getAggregateType(Type other) {
+
+        if (typeCode == other.typeCode) {
+            return precision >= other.precision ? this
+                                                : other;
+        }
+
+        switch (other.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                return this;
+
+            case Types.SQL_BIT :
+                return precision >= other.precision ? this
+                                                    : getBitType(typeCode,
+                                                    other.precision);
+
+            case Types.SQL_BIT_VARYING :
+                return other.precision >= precision ? other
+                                                    : getBitType(
+                                                    other.typeCode, precision);
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.SQL_BLOB :
+                return other;
+
+            default :
+                throw Error.error(ErrorCode.X_42562);
+        }
+    }
+
+    /**
+     * Returns type for concat
+     */
+    public Type getCombinedType(Type other, int operation) {
+
+        if (operation != OpTypes.CONCAT) {
+            return getAggregateType(other);
+        }
+
+        Type newType;
+        long newPrecision = precision + other.precision;
+
+        switch (other.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                return this;
+
+            case Types.SQL_BIT :
+                newType = this;
+                break;
+
+            case Types.SQL_BIT_VARYING :
+                newType = other;
+                break;
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.SQL_BLOB :
+                return other.getCombinedType(this, operation);
+
+            default :
+                throw Error.error(ErrorCode.X_42562);
+        }
+
+        if (newPrecision > maxBitPrecision) {
+            if (typeCode == Types.SQL_BIT) {
+
+                // Standard disallows type length reduction
+                throw Error.error(ErrorCode.X_42570);
+            }
+
+            newPrecision = maxBitPrecision;
+        }
+
+        return getBitType(newType.typeCode, newPrecision);
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        int i = super.compare(session, a, b);
+
+        if (i == 0 && a != null) {
+            if (((BinaryData) a).bitLength(null)
+                    == ((BinaryData) b).bitLength(null)) {
+                return 0;
+            }
+
+            return ((BinaryData) a).bitLength(null)
+                   > ((BinaryData) b).bitLength(null) ? 1
+                                                      : -1;
+        }
+
+        return i;
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+        return castOrConvertToType(null, a, this, false);
+    }
+
+    public Object castToType(SessionInterface session, Object a,
+                             Type otherType) {
+        return castOrConvertToType(session, a, otherType, true);
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+        return castOrConvertToType(session, a, otherType, false);
+    }
+
+    Object castOrConvertToType(SessionInterface session, Object a,
+                               Type otherType, boolean cast) {
+
+        BlobData b;
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (otherType.typeCode) {
+
+            case Types.SQL_VARCHAR :
+            case Types.SQL_CHAR : {
+                b = session.getScanner().convertToBit((String) a);
+                otherType = getBitType(Types.SQL_BIT_VARYING,
+                                       b.length(session));
+
+                break;
+            }
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.SQL_BLOB :
+                b = (BlobData) a;
+                break;
+
+            case Types.SQL_BOOLEAN : {
+                if (precision != 1) {
+                    throw Error.error(ErrorCode.X_22501);
+                }
+
+                if (((Boolean) a).booleanValue()) {
+                    return BinaryData.singleBitOne;
+                } else {
+                    return BinaryData.singleBitZero;
+                }
+            }
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                if (precision != 1) {
+                    throw Error.error(ErrorCode.X_22501);
+                }
+
+                if (((NumberType) otherType).compareToZero(a) == 0) {
+                    return BinaryData.singleBitZero;
+                } else {
+                    return BinaryData.singleBitOne;
+                }
+            }
+            default :
+                throw Error.error(ErrorCode.X_22501);
+        }
+
+        // no special 0 bit consideration
+        if (b.bitLength(session) > precision) {
+            if (!cast) {
+                throw Error.error(ErrorCode.X_22001);
+            }
+
+            session.addWarning(Error.error(ErrorCode.W_01004));
+        }
+
+        int bytePrecision = (int) ((precision + 7) / 8);
+
+        if (otherType.typeCode == Types.SQL_BLOB) {
+            byte[] bytes = b.getBytes(session, 0, bytePrecision);
+
+            b = new BinaryData(bytes, precision);
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_BIT : {
+                if (b.bitLength(session) == precision) {
+                    return b;
+                }
+
+                if (b.length(session) > bytePrecision) {
+                    byte[] data = b.getBytes(session, 0, bytePrecision);
+
+                    b = new BinaryData(data, precision);
+                } else if (b.length(session) <= bytePrecision) {
+                    byte[] data = (byte[]) ArrayUtil.resizeArray(b.getBytes(),
+                        bytePrecision);
+
+                    b = new BinaryData(data, precision);
+                }
+
+                break;
+            }
+            case Types.SQL_BIT_VARYING : {
+                if (b.bitLength(session) <= precision) {
+                    return b;
+                }
+
+                if (b.length(session) > bytePrecision) {
+                    byte[] data = b.getBytes(session, 0, bytePrecision);
+
+                    b = new BinaryData(data, precision);
+                }
+
+                break;
+            }
+            default :
+                throw Error.error(ErrorCode.X_22501);
+        }
+
+        byte[] data = b.getBytes();
+
+        for (int i = (int) precision; i < b.length(session) * 8; i++) {
+            BitMap.unset(data, i);
+        }
+
+        return b;
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return a;
+        }
+
+        if (a instanceof byte[]) {
+            BinaryData data = new BinaryData((byte[]) a, ((byte[]) a).length);
+
+            return convertToTypeLimits(session, data);
+        } else if (a instanceof BinaryData) {
+            return convertToTypeLimits(session, a);
+        } else if (a instanceof String) {
+            return convertToType(session, a, Type.SQL_VARCHAR);
+        } else if (a instanceof Boolean) {
+            return convertToType(session, a, Type.SQL_BOOLEAN);
+        } else if (a instanceof Integer) {
+            return convertToType(session, a, Type.SQL_INTEGER);
+        } else if (a instanceof Long) {
+            return convertToType(session, a, Type.SQL_BIGINT);
+        }
+
+        throw Error.error(ErrorCode.X_22501);
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return StringConverter.byteArrayToBitString(
+            ((BinaryData) a).getBytes(),
+            (int) ((BinaryData) a).bitLength(null));
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        return StringConverter.byteArrayToSQLBitString(
+            ((BinaryData) a).getBytes(),
+            (int) ((BinaryData) a).bitLength(null));
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+
+        return otherType.typeCode == Types.SQL_ALL_TYPES
+               || otherType.isBinaryType()
+               || (precision == 1
+                   && (otherType.isIntegralType() || otherType
+                       .isBooleanType()) || otherType.isCharacterType());
+    }
+
+    /** @todo - implement */
+    public long position(SessionInterface session, BlobData data,
+                         BlobData otherData, Type otherType, long offset) {
+
+        if (data == null || otherData == null) {
+            return -1L;
+        }
+
+        long otherLength = ((BlobData) data).bitLength(session);
+
+        if (offset + otherLength > data.bitLength(session)) {
+            return -1;
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "BitType");
+    }
+
+    public BlobData substring(SessionInterface session, BlobData data,
+                              long offset, long length, boolean hasLength) {
+
+        long end;
+        long dataLength = data.bitLength(session);
+
+        if (hasLength) {
+            end = offset + length;
+        } else {
+            end = dataLength > offset ? dataLength
+                                      : offset;
+        }
+
+        if (end < offset) {
+            throw Error.error(ErrorCode.X_22011);
+        }
+
+        if (offset > end || end < 0) {
+
+            // return zero length data
+            offset = 0;
+            end    = 0;
+        }
+
+        if (offset < 0) {
+            offset = 0;
+        }
+
+        if (end > dataLength) {
+            end = dataLength;
+        }
+
+        length = end - offset;
+
+        byte[] dataBytes = data.getBytes();
+        byte[] bytes     = new byte[(int) (length + 7) / 8];
+
+        for (int i = (int) offset; i < end; i++) {
+            if (BitMap.isSet(dataBytes, i)) {
+                BitMap.set(bytes, i - (int) offset);
+            }
+        }
+
+        return new BinaryData(bytes, length);
+    }
+
+    int getRightTrimSize(BinaryData data) {
+
+        int    i     = (int) data.bitLength(null) - 1;
+        byte[] bytes = data.getBytes();
+
+        for (; i >= 0; i--) {
+            if (BitMap.isSet(bytes, i)) {
+                break;
+            }
+        }
+
+        return i + 1;
+    }
+
+    public BlobData overlay(Session session, BlobData value, BlobData overlay,
+                            long offset, long length, boolean hasLength) {
+
+        if (value == null || overlay == null) {
+            return null;
+        }
+
+        if (!hasLength) {
+            length = ((BlobData) overlay).bitLength(session);
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING : {
+                byte[] data =
+                    (byte[]) ArrayUtil.duplicateArray(value.getBytes());
+                byte[] overlaydata = overlay.getBytes();
+
+                for (int i = 0, pos = (int) offset; i < length;
+                        pos += 8, i++) {
+                    int count = 8;
+
+                    if (length - pos < 8) {
+                        count = (int) length - pos;
+                    }
+
+                    BitMap.overlay(data, pos, overlaydata[i], count);
+                }
+
+                BinaryData binary = new BinaryData(data,
+                                                   value.bitLength(session));
+
+                return binary;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "BitType");
+        }
+    }
+
+    public Object concat(Session session, Object a, Object b) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        long length = ((BlobData) a).bitLength(session)
+                      + ((BlobData) b).bitLength(session);
+
+        if (length > Integer.MAX_VALUE) {
+            throw Error.error(ErrorCode.W_01000);
+        }
+
+        byte[] aData   = ((BlobData) a).getBytes();
+        byte[] bData   = ((BlobData) b).getBytes();
+        int    aLength = (int) ((BlobData) a).bitLength(session);
+        int    bLength = (int) ((BlobData) b).bitLength(session);
+        byte[] bytes   = new byte[(int) (length + 7) / 8];
+
+        System.arraycopy(aData, 0, bytes, 0, aData.length);
+
+        for (int i = 0; i < bLength; i++) {
+            if (BitMap.isSet(bData, i)) {
+                BitMap.set(bytes, aLength + i);
+            }
+        }
+
+        return new BinaryData(bytes, length);
+    }
+
+    public static BinaryType getBitType(int type, long precision) {
+
+        switch (type) {
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                return new BitType(type, precision);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "BitType");
+        }
+    }
+}
diff --git a/src/org/hsqldb/types/BlobData.java b/src/org/hsqldb/types/BlobData.java
new file mode 100644
index 0000000..d2bd473
--- /dev/null
+++ b/src/org/hsqldb/types/BlobData.java
@@ -0,0 +1,98 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.hsqldb.SessionInterface;
+
+/**
+ * Interface for Binary Large Object implementations.<p>
+ *
+ * All positions are 0 based
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface BlobData extends LobData {
+
+    byte[] getBytes();
+
+    byte[] getBytes(SessionInterface session, long pos, int length);
+
+    BlobData getBlob(SessionInterface session, long pos, long length);
+
+    InputStream getBinaryStream(SessionInterface session);
+
+    InputStream getBinaryStream(SessionInterface session, long pos,
+                                long length);
+
+    long length(SessionInterface session);
+
+    long bitLength(SessionInterface session);
+
+    boolean isBits();
+
+    int setBytes(SessionInterface session, long pos, byte[] bytes, int offset,
+                 int len);
+
+    int setBytes(SessionInterface session, long pos, byte[] bytes);
+
+    public long setBinaryStream(SessionInterface session, long pos,
+                                InputStream in);
+
+    OutputStream setBinaryStream(SessionInterface session, long pos);
+
+    void truncate(SessionInterface session, long len);
+
+    BlobData duplicate(SessionInterface session);
+
+    long position(SessionInterface session, byte[] pattern, long start);
+
+    long position(SessionInterface session, BlobData pattern, long start);
+
+    long nonZeroLength(SessionInterface session);
+
+    long getId();
+
+    void setId(long id);
+
+    void free();
+
+    boolean isClosed();
+
+    void setSession(SessionInterface session);
+
+    int getStreamBlockSize();
+}
diff --git a/src/org/hsqldb/types/BlobDataID.java b/src/org/hsqldb/types/BlobDataID.java
new file mode 100644
index 0000000..dd61403
--- /dev/null
+++ b/src/org/hsqldb/types/BlobDataID.java
@@ -0,0 +1,206 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultLob;
+
+public class BlobDataID implements BlobData {
+
+    long id;
+
+    public BlobDataID(long id) {
+        this.id = id;
+    }
+
+    public BlobData duplicate(SessionInterface session) {
+        return null;
+    }
+
+    public void free() {}
+
+    public InputStream getBinaryStream(SessionInterface session) {
+
+        long length = length(session);
+
+        return new BlobInputStream(session, this, 0, length);
+    }
+
+    public InputStream getBinaryStream(SessionInterface session, long pos,
+                                       long length) {
+        return new BlobInputStream(session, this, pos, length);
+    }
+
+    public byte[] getBytes() {
+        return null;
+    }
+
+    public byte[] getBytes(SessionInterface session, long pos, int length) {
+
+        ResultLob resultOut = ResultLob.newLobGetBytesRequest(id, pos, length);
+        Result    resultIn  = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw Error.error(resultIn);
+        }
+
+        return ((ResultLob) resultIn).getByteArray();
+    }
+
+    public BlobData getBlob(SessionInterface session, long pos, long length) {
+
+        ResultLob resultOut = ResultLob.newLobGetRequest(id, pos, length);
+        Result    resultIn  = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw Error.error(resultIn);
+        }
+
+        long lobID = ((ResultLob) resultIn).getLobID();
+
+        return new BlobDataID(lobID);
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public int getStreamBlockSize() {
+        return 0;
+    }
+
+    public boolean isClosed() {
+        return false;
+    }
+
+    public long length(SessionInterface session) {
+
+        ResultLob resultOut = ResultLob.newLobGetLengthRequest(id);
+        Result    resultIn  = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return ((ResultLob) resultIn).getBlockLength();
+    }
+
+    public long bitLength(SessionInterface session) {
+        return 0;
+    }
+
+    public boolean isBits() {
+        return false;
+    }
+
+    public long position(SessionInterface session, BlobData pattern,
+                         long start) {
+        return 0L;
+    }
+
+    public long position(SessionInterface session, byte[] pattern,
+                         long start) {
+
+        ResultLob resultOut = ResultLob.newLobGetBytePatternPositionRequest(id,
+            pattern, start);
+        ResultLob resultIn = (ResultLob) session.execute(resultOut);
+
+        return resultIn.getOffset();
+    }
+
+    public long nonZeroLength(SessionInterface session) {
+        return 0;
+    }
+
+    public OutputStream setBinaryStream(SessionInterface session, long pos) {
+        return null;
+    }
+
+    public int setBytes(SessionInterface session, long pos, byte[] bytes,
+                        int offset, int len) {
+
+        if (offset != 0 || len != bytes.length) {
+            if (!BinaryData.isInLimits(bytes.length, offset, len)) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            byte[] newbytes = new byte[len];
+
+            System.arraycopy(bytes, offset, newbytes, 0, len);
+
+            bytes = newbytes;
+        }
+
+        ResultLob resultOut = ResultLob.newLobSetBytesRequest(id, pos, bytes);
+        Result    resultIn  = (ResultLob) session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return bytes.length;
+    }
+
+    public int setBytes(SessionInterface session, long pos, byte[] bytes) {
+        return setBytes(session, pos, bytes, 0, bytes.length);
+    }
+
+    public long setBinaryStream(SessionInterface session, long pos,
+                                InputStream in) {
+        return 0;
+    }
+
+    public void setSession(SessionInterface session) {}
+
+    public void truncate(SessionInterface session, long len) {
+
+        ResultLob resultOut = ResultLob.newLobTruncateRequest(id, len);
+        Result    resultIn  = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+    }
+
+    public boolean isBinary() {
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/types/BlobInputStream.java b/src/org/hsqldb/types/BlobInputStream.java
new file mode 100644
index 0000000..da8d1ae
--- /dev/null
+++ b/src/org/hsqldb/types/BlobInputStream.java
@@ -0,0 +1,144 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.java.JavaSystem;
+
+/**
+ * This class is used as an InputStream to retrieve data from a Blob.
+ * mark() and reset() are not supported.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class BlobInputStream extends InputStream {
+
+    final BlobData   blob;
+    final long       availableLength;
+    long             bufferOffset;
+    long             currentPosition;
+    byte[]           buffer;
+    boolean          isClosed;
+    SessionInterface session;
+
+    public BlobInputStream(SessionInterface session, BlobData blob,
+                           long offset, long length) {
+
+        if (!isInLimits(blob.length(session), offset, length)) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        this.session         = session;
+        this.blob            = blob;
+        this.availableLength = offset + length;
+        this.currentPosition = offset;
+    }
+
+    public int read() throws IOException {
+
+        if (currentPosition >= availableLength) {
+            return -1;
+        }
+
+        if (buffer == null
+                || currentPosition >= bufferOffset + buffer.length) {
+            try {
+                checkClosed();
+                readIntoBuffer();
+            } catch (HsqlException e) {
+                throw JavaSystem.toIOException(e);
+            }
+        }
+
+        int val = buffer[(int) (currentPosition - bufferOffset)] & 0xff;
+
+        currentPosition++;
+
+        return val;
+    }
+
+    public long skip(long n) throws IOException {
+
+        if (n <= 0) {
+            return 0;
+        }
+
+        if (currentPosition + n > availableLength) {
+            n = availableLength - currentPosition;
+        }
+
+        currentPosition += n;
+
+        return n;
+    }
+
+    public int available() {
+        return (int) (bufferOffset + buffer.length - currentPosition);
+    }
+
+    public void close() throws IOException {
+        isClosed = true;
+    }
+
+    private void checkClosed() {
+
+        if (isClosed || blob.isClosed()) {
+            throw Error.error(ErrorCode.X_0F503);
+        }
+    }
+
+    private void readIntoBuffer() {
+
+        long readLength = availableLength - currentPosition;
+
+        if (readLength <= 0) {}
+
+        if (readLength > session.getStreamBlockSize()) {
+            readLength = session.getStreamBlockSize();
+        }
+
+        buffer = blob.getBytes(session, currentPosition, (int) readLength);
+        bufferOffset = currentPosition;
+    }
+
+    static boolean isInLimits(long fullLength, long pos, long len) {
+        return pos >= 0 && len >= 0 && pos + len <= fullLength;
+    }
+}
diff --git a/src/org/hsqldb/types/BlobType.java b/src/org/hsqldb/types/BlobType.java
new file mode 100644
index 0000000..afd4b07
--- /dev/null
+++ b/src/org/hsqldb/types/BlobType.java
@@ -0,0 +1,212 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+
+public final class BlobType extends BinaryType {
+
+    public static final long maxBlobPrecision = 1024L * 1024 * 1024 * 1024;
+    public static final int  defaultBlobSize  = 1024 * 1024 * 16;
+
+    public BlobType(long precision) {
+        super(Types.SQL_BLOB, precision);
+    }
+
+    public int displaySize() {
+        return precision > Integer.MAX_VALUE ? Integer.MAX_VALUE
+                                             : (int) precision;
+    }
+
+    public int getJDBCTypeCode() {
+        return Types.BLOB;
+    }
+
+    public Class getJDBCClass() {
+        return java.sql.Blob.class;
+    }
+
+    public String getJDBCClassName() {
+        return "java.sql.Blob";
+    }
+
+    public String getNameString() {
+        return Tokens.T_BLOB;
+    }
+
+    public String getFullNameString() {
+        return "BINARY LARGE OBJECT";
+    }
+
+    public String getDefinition() {
+
+        long   factor     = precision;
+        String multiplier = null;
+
+        if (precision % (1024 * 1024 * 1024) == 0) {
+            factor     = precision / (1024 * 1024 * 1024);
+            multiplier = Tokens.T_G_FACTOR;
+        } else if (precision % (1024 * 1024) == 0) {
+            factor     = precision / (1024 * 1024);
+            multiplier = Tokens.T_M_FACTOR;
+        } else if (precision % (1024) == 0) {
+            factor     = precision / (1024);
+            multiplier = Tokens.T_K_FACTOR;
+        }
+
+        StringBuffer sb = new StringBuffer(16);
+
+        sb.append(getNameString());
+        sb.append('(');
+        sb.append(factor);
+
+        if (multiplier != null) {
+            sb.append(multiplier);
+        }
+
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public boolean acceptsPrecision() {
+        return true;
+    }
+
+    public boolean requiresPrecision() {
+        return false;
+    }
+
+    public long getMaxPrecision() {
+        return maxBlobPrecision;
+    }
+
+    public boolean isBinaryType() {
+        return true;
+    }
+
+    public boolean isLobType() {
+        return true;
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        if (b instanceof BinaryData) {
+            return session.database.lobManager.compare((BlobData) a,
+                    ((BlobData) b).getBytes());
+        }
+
+        return session.database.lobManager.compare((BlobData) a, (BlobData) b);
+    }
+
+    /** @todo - implement */
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+        return a;
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (otherType.typeCode == Types.SQL_BLOB) {
+            return a;
+        }
+
+        if (otherType.typeCode == Types.SQL_BINARY
+                || otherType.typeCode == Types.SQL_VARBINARY) {
+            BlobData b    = (BlobData) a;
+            BlobData blob = session.createBlob(b.length(session));
+
+            blob.setBytes(session, 0, b.getBytes());
+
+            return blob;
+        }
+
+        throw Error.error(ErrorCode.X_42561);
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return a;
+        }
+
+        // conversion to Blob via PreparedStatement.setObject();
+        if (a instanceof byte[]) {
+            return new BinaryData((byte[]) a, false);
+        }
+
+        throw Error.error(ErrorCode.X_42561);
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        byte[] bytes = ((BlobData) a).getBytes();
+
+        return StringConverter.byteArrayToHexString(bytes);
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        byte[] bytes = ((BlobData) a).getBytes();
+
+        return StringConverter.byteArrayToSQLHexString(bytes);
+    }
+}
diff --git a/src/org/hsqldb/types/BooleanType.java b/src/org/hsqldb/types/BooleanType.java
new file mode 100644
index 0000000..171a48a
--- /dev/null
+++ b/src/org/hsqldb/types/BooleanType.java
@@ -0,0 +1,279 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.store.BitMap;
+
+/**
+ * Type implementation for BOOLEAN.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class BooleanType extends Type {
+
+    static final BooleanType booleanType = new BooleanType();
+
+    private BooleanType() {
+        super(Types.SQL_BOOLEAN, Types.SQL_BOOLEAN, 0, 0);
+    }
+
+    public int displaySize() {
+        return 5;
+    }
+
+    public int getJDBCTypeCode() {
+        return Types.BOOLEAN;
+    }
+
+    public Class getJDBCClass() {
+        return Boolean.class;
+    }
+
+    public String getJDBCClassName() {
+        return "java.lang.Boolean";
+    }
+
+    public String getNameString() {
+        return Tokens.T_BOOLEAN;
+    }
+
+    public String getDefinition() {
+        return Tokens.T_BOOLEAN;
+    }
+
+    public boolean isBooleanType() {
+        return true;
+    }
+
+    public Type getAggregateType(Type other) {
+
+        if (typeCode == other.typeCode) {
+            return this;
+        }
+
+        if (other.isCharacterType()) {
+            return other.getAggregateType(this);
+        }
+
+        throw Error.error(ErrorCode.X_42562);
+    }
+
+    public Type getCombinedType(Type other, int operation) {
+
+        switch (operation) {
+
+            case OpTypes.EQUAL :
+                if (other.isBooleanType()) {
+                    return this;
+                }
+        }
+
+        throw Error.error(ErrorCode.X_42562);
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        boolean boola = ((Boolean) a).booleanValue();
+        boolean boolb = ((Boolean) b).booleanValue();
+
+        return (boola == boolb) ? 0
+                                : (boolb ? -1
+                                         : 1);
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+        return a;
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+
+        if (a == null) {
+            return a;
+        }
+
+        switch (otherType.typeCode) {
+
+            case Types.SQL_BOOLEAN :
+                return a;
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING : {
+                BinaryData b = (BinaryData) a;
+
+                if (b.bitLength(session) == 1) {
+                    return BitMap.isSet(b.getBytes(), 0) ? Boolean.TRUE
+                                                         : Boolean.FALSE;
+                }
+
+                break;
+            }
+            case Types.SQL_CLOB :
+                a = Type.SQL_VARCHAR.convertToType(session, a, otherType);
+
+            // fall through
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE : {
+                a = ((CharacterType) otherType).trim(session, a, (int) ' ',
+                                                     true, true);
+
+                if (((String) a).equalsIgnoreCase(Tokens.T_TRUE)) {
+                    return Boolean.TRUE;
+                } else if (((String) a).equalsIgnoreCase(Tokens.T_FALSE)) {
+                    return Boolean.FALSE;
+                } else if (((String) a).equalsIgnoreCase(Tokens.T_UNKNOWN)) {
+                    return null;
+                }
+
+                break;
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return NumberType.isZero(a) ? Boolean.FALSE
+                                            : Boolean.TRUE;
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT : {
+                if (((Number) a).longValue() == 0) {
+                    return Boolean.FALSE;
+                } else {
+                    return Boolean.TRUE;
+                }
+            }
+        }
+
+        throw Error.error(ErrorCode.X_22018);
+    }
+
+    /**
+     * ResultSet getBoolean support
+     */
+    public Object convertToTypeJDBC(SessionInterface session, Object a,
+                                    Type otherType) {
+
+        if (a == null) {
+            return a;
+        }
+
+        switch (otherType.typeCode) {
+
+            case Types.SQL_BOOLEAN :
+                return a;
+
+            default :
+                if (otherType.isLobType() ) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+
+                if (otherType.isCharacterType()) {
+                    if ("0".equals(a)) {
+                        return Boolean.TRUE;
+                    } else if ("1".equals(a)) {
+                        return Boolean.TRUE;
+                    }
+                }
+
+                return convertToType(session, a, otherType);
+        }
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (a instanceof Boolean) {
+            return a;
+        } else if (a instanceof String) {
+            return convertToType(session, a, Type.SQL_VARCHAR);
+        }
+
+        throw Error.error(ErrorCode.X_42561);
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return ((Boolean) a).booleanValue() ? Tokens.T_TRUE
+                                            : Tokens.T_FALSE;
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_UNKNOWN;
+        }
+
+        return ((Boolean) a).booleanValue() ? Tokens.T_TRUE
+                                            : Tokens.T_FALSE;
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+
+        return otherType.typeCode == Types.SQL_ALL_TYPES
+               || otherType.isBooleanType() || otherType.isCharacterType()
+               || otherType.isIntegralType()
+               || (otherType.isBitType() && otherType.precision == 1);
+    }
+
+    public static BooleanType getBooleanType() {
+        return booleanType;
+    }
+}
diff --git a/src/org/hsqldb/types/CharacterType.java b/src/org/hsqldb/types/CharacterType.java
new file mode 100644
index 0000000..a37fd97
--- /dev/null
+++ b/src/org/hsqldb/types/CharacterType.java
@@ -0,0 +1,999 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.math.BigDecimal;
+
+import org.hsqldb.Collation;
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.StringConverter;
+import org.hsqldb.lib.StringUtil;
+import org.hsqldb.lib.java.JavaSystem;
+
+/**
+ * Type subclass for CHARACTER, VARCHAR, etc.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class CharacterType extends Type {
+
+    Collation         collation;
+    Charset           charset;
+    boolean           isEqualIdentical;
+    final static int  defaultCharPrecision = 32 * 1024;
+    static final long maxCharPrecision     = Integer.MAX_VALUE;
+
+    public CharacterType(Collation collation, int type, long precision) {
+
+        super(Types.SQL_VARCHAR, type, precision, 0);
+
+        this.collation = collation;
+        this.charset   = Charset.getDefaultInstance();
+        isEqualIdentical = this.collation.isEqualAlwaysIdentical()
+                           && type != Types.VARCHAR_IGNORECASE;
+    }
+
+    /**
+     * Always English collation
+     */
+    public CharacterType(int type, long precision) {
+
+        super(Types.SQL_VARCHAR, type, precision, 0);
+
+        this.collation   = Collation.getDefaultInstance();
+        this.charset     = Charset.getDefaultInstance();
+        isEqualIdentical = type != Types.VARCHAR_IGNORECASE;
+    }
+
+    public int displaySize() {
+        return precision > Integer.MAX_VALUE ? Integer.MAX_VALUE
+                                             : (int) precision;
+    }
+
+    public int getJDBCTypeCode() {
+
+        switch (typeCode) {
+
+            case Types.SQL_CHAR :
+                return Types.CHAR;
+
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                return Types.VARCHAR;
+
+            case Types.SQL_CLOB :
+                return Types.CLOB;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+
+    public Class getJDBCClass() {
+        return String.class;
+    }
+
+    public String getJDBCClassName() {
+        return "java.lang.String";
+    }
+
+    public int getSQLGenericTypeCode() {
+        return typeCode == Types.SQL_CHAR ? typeCode
+                                          : Types.SQL_VARCHAR;
+    }
+
+    public String getNameString() {
+
+        switch (typeCode) {
+
+            case Types.SQL_CHAR :
+                return Tokens.T_CHARACTER;
+
+            case Types.SQL_VARCHAR :
+                return Tokens.T_VARCHAR;
+
+            case Types.VARCHAR_IGNORECASE :
+                return Tokens.T_VARCHAR_IGNORECASE;
+
+            case Types.SQL_CLOB :
+                return Tokens.T_CLOB;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+
+    public String getFullNameString() {
+
+        switch (typeCode) {
+
+            case Types.SQL_CHAR :
+                return Tokens.T_CHARACTER;
+
+            case Types.SQL_VARCHAR :
+                return "CHARACTER VARYING";
+
+            case Types.VARCHAR_IGNORECASE :
+                return Tokens.T_VARCHAR_IGNORECASE;
+
+            case Types.SQL_CLOB :
+                return "CHARACTER LARGE OBJECT";
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+
+    public String getDefinition() {
+
+        if (precision == 0) {
+            return getNameString();
+        }
+
+        StringBuffer sb = new StringBuffer(16);
+
+        sb.append(getNameString());
+        sb.append('(');
+        sb.append(precision);
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public boolean isCharacterType() {
+        return true;
+    }
+
+    public long getMaxPrecision() {
+        return maxCharPrecision;
+    }
+
+    public boolean acceptsPrecision() {
+        return true;
+    }
+
+    public boolean requiresPrecision() {
+        return typeCode == Types.SQL_VARCHAR
+               || typeCode == Types.VARCHAR_IGNORECASE;
+    }
+
+    public int precedenceDegree(Type other) {
+
+        if (other.typeCode == typeCode) {
+            return 0;
+        }
+
+        if (!other.isCharacterType()) {
+            return Integer.MIN_VALUE;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_CHAR :
+                return other.typeCode == Types.SQL_CLOB ? 4
+                                                        : 2;
+
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                if (other.typeCode == Types.SQL_VARCHAR
+                        || other.typeCode == Types.VARCHAR_IGNORECASE) {
+                    return 0;
+                }
+
+                return other.typeCode == Types.SQL_CLOB ? 4
+                                                        : 2;
+
+            case Types.SQL_CLOB :
+                return other.typeCode == Types.SQL_CHAR ? -4
+                                                        : -2;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+
+    public Type getAggregateType(Type other) {
+
+        if (typeCode == other.typeCode) {
+            return precision >= other.precision ? this
+                                                : other;
+        }
+
+        switch (other.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                return this;
+
+            case Types.SQL_CHAR :
+                return precision >= other.precision ? this
+                                                    : getCharacterType(
+                                                    typeCode, other.precision);
+
+            case Types.SQL_VARCHAR :
+                if (typeCode == Types.SQL_CLOB
+                        || typeCode == Types.VARCHAR_IGNORECASE) {
+                    return precision >= other.precision ? this
+                                                        : getCharacterType(
+                                                        typeCode,
+                                                        other.precision);
+                } else {
+                    return other.precision >= precision ? other
+                                                        : getCharacterType(
+                                                        other.typeCode,
+                                                        precision);
+                }
+            case Types.VARCHAR_IGNORECASE :
+                if (typeCode == Types.SQL_CLOB) {
+                    return precision >= other.precision ? this
+                                                        : getCharacterType(
+                                                        typeCode,
+                                                        other.precision);
+                } else {
+                    return other.precision >= precision ? other
+                                                        : getCharacterType(
+                                                        other.typeCode,
+                                                        precision);
+                }
+            case Types.SQL_CLOB :
+                return other.precision >= precision ? other
+                                                    : getCharacterType(
+                                                    other.typeCode, precision);
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+            case Types.SQL_BLOB :
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.OTHER :
+                throw Error.error(ErrorCode.X_42562);
+            default :
+
+                /**
+                 * @todo - this seems to be allowed in SQL-92 (is in NIST)
+                 * but is disallowed in SQL:2003
+                 * need to make dependent on a database property
+                 */
+/*
+                int length = other.displaySize();
+
+                return getCharacterType(Types.SQL_VARCHAR,
+                                        length).getAggregateType(this);
+*/
+                throw Error.error(ErrorCode.X_42562);
+        }
+    }
+
+    /**
+     * For concatenation
+     */
+    public Type getCombinedType(Type other, int operation) {
+
+        if (operation != OpTypes.CONCAT) {
+            return getAggregateType(other);
+        }
+
+        Type newType;
+        long newPrecision = this.precision + other.precision;
+
+        switch (other.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                return this;
+
+            case Types.SQL_CHAR :
+                newType = this;
+                break;
+
+            case Types.SQL_VARCHAR :
+                newType =
+                    (typeCode == Types.SQL_CLOB || typeCode == Types
+                        .VARCHAR_IGNORECASE) ? this
+                                             : other;
+                break;
+
+            case Types.VARCHAR_IGNORECASE :
+                newType = typeCode == Types.SQL_CLOB ? this
+                                                     : other;
+                break;
+
+            case Types.SQL_CLOB :
+                newType = other;
+                break;
+
+            default :
+                throw Error.error(ErrorCode.X_42562);
+        }
+
+        if (newPrecision > maxCharPrecision) {
+            if (typeCode == Types.SQL_BINARY) {
+
+                // Standard disallows type length reduction
+                throw Error.error(ErrorCode.X_42570);
+            } else if (typeCode == Types.SQL_CHAR) {
+                newPrecision = maxCharPrecision;
+            }
+        }
+
+        return getCharacterType(newType.typeCode, precision + other.precision);
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        String as = (String) a;
+        String bs = (String) b;
+        int    la = as.length();
+        int    lb = bs.length();
+
+        if (la == lb) {}
+        else if (la > lb) {
+            char[] buffer = new char[la];
+
+            bs.getChars(0, lb, buffer, 0);
+            ArrayUtil.fillArray(buffer, lb, ' ');
+
+            bs = String.valueOf(buffer);
+        } else {
+            char[] buffer = new char[lb];
+
+            as.getChars(0, la, buffer, 0);
+            ArrayUtil.fillArray(buffer, la, ' ');
+
+            as = String.valueOf(buffer);
+        }
+
+        if (typeCode == Types.VARCHAR_IGNORECASE) {
+            return collation.compareIgnoreCase(as, bs);
+        } else {
+            return collation.compare(as, bs);
+        }
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return a;
+        }
+
+        if (precision == 0) {
+            return a;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_CHAR : {
+                int slen = ((String) a).length();
+
+                if (slen == precision) {
+                    return a;
+                }
+
+                if (slen > precision) {
+                    if (getRightTrimSise((String) a, ' ') <= precision) {
+                        return ((String) a).substring(0, (int) precision);
+                    } else {
+                        throw Error.error(ErrorCode.X_22001);
+                    }
+                }
+
+                char[] b = new char[(int) precision];
+
+                ((String) a).getChars(0, slen, b, 0);
+
+                for (int i = slen; i < precision; i++) {
+                    b[i] = ' ';
+                }
+
+                return new String(b);
+            }
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE : {
+                int slen = ((String) a).length();
+
+                if (slen > precision) {
+                    if (getRightTrimSise((String) a, ' ') <= precision) {
+                        return ((String) a).substring(0, (int) precision);
+                    } else {
+                        throw Error.error(ErrorCode.X_22001);
+                    }
+                }
+
+                return a;
+            }
+            case Types.SQL_CLOB :
+
+                /** @todo implement */
+                return a;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+
+    public Object castToType(SessionInterface session, Object a,
+                             Type otherType) {
+
+        if (a == null) {
+            return a;
+        }
+
+        return castOrConvertToType(session, a, otherType, true);
+    }
+
+    public Object castOrConvertToType(SessionInterface session, Object a,
+                                      Type otherType, boolean cast) {
+
+        switch (otherType.typeCode) {
+
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE : {
+                int length = ((String) a).length();
+
+                if (precision != 0 && length > precision) {
+                    if (StringUtil.rightTrimSize((String) a) > precision) {
+                        if (!cast) {
+                            throw Error.error(ErrorCode.X_22001);
+                        }
+
+                        session.addWarning(Error.error(ErrorCode.W_01004));
+                    }
+
+                    a = ((String) a).substring(0, (int) precision);
+                }
+
+                switch (typeCode) {
+
+                    case Types.SQL_CHAR :
+                        return convertToTypeLimits(session, a);
+
+                    case Types.SQL_VARCHAR :
+                    case Types.VARCHAR_IGNORECASE :
+                        return a;
+
+                    case Types.SQL_CLOB : {
+                        ClobData clob =
+                            session.createClob(((String) a).length());
+
+                        clob.setString(session, 0, (String) a);
+
+                        return clob;
+                    }
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "CharacterType");
+                }
+            }
+            case Types.SQL_CLOB : {
+                long length = ((ClobData) a).length(session);
+
+                if (precision != 0 && length > precision) {
+                    if (((ClobData) a).nonSpaceLength(session) > precision) {
+                        if (!cast) {
+                            throw Error.error(ErrorCode.X_22001);
+                        }
+
+                        session.addWarning(Error.error(ErrorCode.W_01004));
+                    }
+                }
+
+                switch (typeCode) {
+
+                    case Types.SQL_CHAR :
+                    case Types.SQL_VARCHAR :
+                    case Types.VARCHAR_IGNORECASE : {
+                        if (length > maxCharPrecision) {
+                            if (!cast) {
+                                throw Error.error(ErrorCode.X_22001);
+                            }
+
+                            length = maxCharPrecision;
+                        }
+
+                        a = ((ClobData) a).getSubString(session, 0,
+                                                        (int) length);
+
+                        return convertToTypeLimits(session, a);
+                    }
+                    case Types.SQL_CLOB : {
+                        if (precision != 0 && length > precision) {
+                            return ((ClobData) a).getClob(session, 0,
+                                                          precision);
+                        }
+
+                        return a;
+                    }
+                    default :
+                        throw Error.runtimeError(ErrorCode.U_S0500,
+                                                 "CharacterType");
+                }
+            }
+            case Types.OTHER :
+                throw Error.error(ErrorCode.X_42561);
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+            case Types.SQL_BLOB :
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            default :
+                String s = otherType.convertToString(a);
+
+                if (precision != 0 && s.length() > precision) {
+                    throw Error.error(ErrorCode.X_22001);
+                }
+
+                a = s;
+
+                return convertToTypeLimits(session, a);
+        }
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+
+        if (a == null) {
+            return a;
+        }
+
+        return castOrConvertToType(session, a, otherType, false);
+    }
+
+    public Object convertToTypeJDBC(SessionInterface session, Object a,
+                                    Type otherType) {
+
+        if (a == null) {
+            return a;
+        }
+
+        if (otherType.typeCode == Types.SQL_BLOB) {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        return convertToType(session, a, otherType);
+    }
+
+    /**
+     * Relaxes SQL parameter type enforcement, allowing long strings.
+     */
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return a;
+        }
+
+        String s;
+
+        if (a instanceof Boolean) {
+            s = a.toString();
+        } else if (a instanceof BigDecimal) {
+            s = JavaSystem.toString((BigDecimal) a);
+        } else if (a instanceof Number) {
+            s = a.toString();    // use shortcut
+        } else if (a instanceof String) {
+            s = (String) a;
+        } else if (a instanceof java.sql.Date) {
+            s = ((java.sql.Date) a).toString();
+        } else if (a instanceof java.sql.Time) {
+            s = ((java.sql.Time) a).toString();
+        } else if (a instanceof java.sql.Timestamp) {
+            s = ((java.sql.Timestamp) a).toString();
+        } else {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        return s;
+
+        // return convertToType(session, a, Type.SQL_VARCHAR);
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_CHAR : {
+                int slen = ((String) a).length();
+
+                if (precision == 0 || slen == precision) {
+                    return (String) a;
+                }
+
+                char[] b = new char[(int) precision];
+
+                ((String) a).getChars(0, slen, b, 0);
+
+                for (int i = slen; i < precision; i++) {
+                    b[i] = ' ';
+                }
+
+                return new String(b);
+            }
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE : {
+                return (String) a;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        String s = convertToString(a);
+
+        return StringConverter.toQuotedString(s, '\'', true);
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+        return !otherType.isObjectType();
+    }
+
+    public Collation getCollation() {
+        return collation;
+    }
+
+    public Charset getCharacterSet() {
+        return charset;
+    }
+
+    public boolean isEqualIdentical() {
+        return isEqualIdentical;
+    }
+
+    public boolean isCaseInsensitive() {
+        return typeCode == Types.VARCHAR_IGNORECASE;
+    }
+
+    public long position(SessionInterface session, Object data,
+                         Object otherData, Type otherType, long offset) {
+
+        if (data == null || otherData == null) {
+            return -1L;
+        }
+
+        if (otherType.typeCode == Types.SQL_CLOB) {
+            long otherLength = ((ClobData) data).length(session);
+
+            if (offset + otherLength > ((String) data).length()) {
+                return -1;
+            }
+
+            String otherString = ((ClobData) otherData).getSubString(session,
+                0, (int) otherLength);
+
+            return ((String) data).indexOf(otherString, (int) offset);
+        } else if (otherType.isCharacterType()) {
+            long otherLength = ((String) data).length();
+
+            if (offset + otherLength > ((String) data).length()) {
+                return -1;
+            }
+
+            return ((String) data).indexOf((String) otherData, (int) offset);
+        } else {
+            throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+
+    public Object substring(SessionInterface session, Object data,
+                            long offset, long length, boolean hasLength,
+                            boolean trailing) {
+
+        long end;
+        long dataLength = typeCode == Types.SQL_CLOB
+                          ? ((ClobData) data).length(session)
+                          : ((String) data).length();
+
+        if (trailing) {
+            end = dataLength;
+
+            if (length > dataLength) {
+                offset = 0;
+                length = dataLength;
+            } else {
+                offset = dataLength - length;
+            }
+        } else if (hasLength) {
+            end = offset + length;
+        } else {
+            end = dataLength > offset ? dataLength
+                                      : offset;
+        }
+
+        if (end < offset) {
+            throw Error.error(ErrorCode.X_22011);
+        }
+
+        if (offset > end || end < 0) {
+
+            // return zero length data
+            offset = 0;
+            end    = 0;
+        }
+
+        if (offset < 0) {
+            offset = 0;
+        }
+
+        if (end > dataLength) {
+            end = dataLength;
+        }
+
+        length = end - offset;
+
+        if (data instanceof String) {
+            return ((String) data).substring((int) offset,
+                                             (int) (offset + length));
+        } else if (data instanceof ClobData) {
+            ClobData clob = session.createClob(length);
+
+            /** @todo - change to support long strings */
+            String result = ((ClobData) data).getSubString(session, offset,
+                (int) length);
+
+            clob.setString(session, 0, result);
+
+            return clob;
+        } else {
+            throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+
+    /**
+     * Memory limits apply to Upper and Lower implementations with Clob data
+     */
+    public Object upper(Session session, Object data) {
+
+        if (data == null) {
+            return null;
+        }
+
+        if (typeCode == Types.SQL_CLOB) {
+            String result = ((ClobData) data).getSubString(session, 0,
+                (int) ((ClobData) data).length(session));
+
+            result = collation.toUpperCase(result);
+
+            ClobData clob = session.createClob(result.length());
+
+            clob.setString(session, 0, result);
+
+            return clob;
+        }
+
+        return collation.toUpperCase((String) data);
+    }
+
+    public Object lower(Session session, Object data) {
+
+        if (data == null) {
+            return null;
+        }
+
+        if (typeCode == Types.SQL_CLOB) {
+            String result = ((ClobData) data).getSubString(session, 0,
+                (int) ((ClobData) data).length(session));
+
+            result = collation.toLowerCase(result);
+
+            ClobData clob = session.createClob(result.length());
+
+            clob.setString(session, 0, result);
+
+            return clob;
+        }
+
+        return collation.toLowerCase((String) data);
+    }
+
+    public Object trim(SessionInterface session, Object data, int trim,
+                       boolean leading, boolean trailing) {
+
+        if (data == null) {
+            return null;
+        }
+
+        String s;
+
+        if (typeCode == Types.SQL_CLOB) {
+            s = ((ClobData) data).getSubString(
+                session, 0, (int) ((ClobData) data).length(session));
+        } else {
+            s = (String) data;
+        }
+
+        int endindex = s.length();
+
+        if (trailing) {
+            for (--endindex; endindex >= 0 && s.charAt(endindex) == trim;
+                    endindex--) {}
+
+            endindex++;
+        }
+
+        int startindex = 0;
+
+        if (leading) {
+            while (startindex < endindex && s.charAt(startindex) == trim) {
+                startindex++;
+            }
+        }
+
+        /** @todo - change to support long strings */
+        if (startindex == 0 && endindex == s.length()) {}
+        else {
+            s = s.substring(startindex, endindex);
+        }
+
+        if (typeCode == Types.SQL_CLOB) {
+            ClobData clob = session.createClob(s.length());
+
+            clob.setString(session, 0, s);
+
+            return clob;
+        } else {
+            return s;
+        }
+    }
+
+    public Object overlay(SessionInterface session, Object data,
+                          Object overlay, long offset, long length,
+                          boolean hasLength) {
+
+        if (data == null || overlay == null) {
+            return null;
+        }
+
+        if (!hasLength) {
+            length = typeCode == Types.SQL_CLOB
+                     ? ((ClobData) overlay).length(session)
+                     : ((String) overlay).length();
+        }
+
+        Object temp = concat(null,
+                             substring(session, data, 0, offset, true, false),
+                             overlay);
+
+        return concat(null, temp,
+                      substring(session, data, offset + length, 0, false,
+                                false));
+    }
+
+    public Object concat(Session session, Object a, Object b) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        String left;
+        String right;
+
+        if (a instanceof ClobData) {
+            left = ((ClobData) a).getSubString(
+                session, 0, (int) ((ClobData) a).length(session));
+        } else {
+            left = (String) a;
+        }
+
+        if (b instanceof ClobData) {
+            right = ((ClobData) b).getSubString(
+                session, 0, (int) ((ClobData) b).length(session));
+        } else {
+            right = (String) b;
+        }
+
+        if (typeCode == Types.SQL_CLOB) {
+            ClobData clob = session.createClob(left.length() + right.length());
+
+            clob.setString(session, 0, left);
+            clob.setString(session, left.length(), right);
+
+            return clob;
+        } else {
+            return left + right;
+        }
+    }
+
+    public long size(SessionInterface session, Object data) {
+
+        if (typeCode == Types.SQL_CLOB) {
+            return ((ClobData) data).length(session);
+        }
+
+        return ((String) data).length();
+    }
+
+/*
+    public static Object concat(Object a, Object b) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        return a.toString() + b.toString();
+    }
+*/
+    public static int getRightTrimSise(String s, char trim) {
+
+        int endindex = s.length();
+
+        for (--endindex; endindex >= 0 && s.charAt(endindex) == trim;
+                endindex--) {}
+
+        endindex++;
+
+        return endindex;
+    }
+
+    public static Type getCharacterType(int type, long precision) {
+
+        switch (type) {
+
+            case Types.SQL_VARCHAR :
+            case Types.SQL_CHAR :
+            case Types.VARCHAR_IGNORECASE :
+                return new CharacterType(type, (int) precision);
+
+            case Types.SQL_CLOB :
+                return new ClobType(precision);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "CharacterType");
+        }
+    }
+}
diff --git a/src/org/hsqldb/types/Charset.java b/src/org/hsqldb/types/Charset.java
new file mode 100644
index 0000000..6a6ed20
--- /dev/null
+++ b/src/org/hsqldb/types/Charset.java
@@ -0,0 +1,186 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Session;
+import org.hsqldb.SqlInvariants;
+import org.hsqldb.Tokens;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.rights.Grantee;
+
+/**
+ * Implementation of CHARACTER SET objects.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class Charset implements SchemaObject {
+
+    public static final int[][] uppercaseLetters   = new int[][] {
+        {
+            'A', 'Z'
+        }
+    };
+    public static final int[][] unquotedIdentifier = new int[][] {
+        {
+            '0', '9'
+        }, {
+            'A', 'Z'
+        }, {
+            '_', '_'
+        }
+    };
+    public static final int[][] basicIdentifier    = new int[][] {
+        {
+            '0', '9'
+        }, {
+            'A', 'Z'
+        }, {
+            '_', '_'
+        }, {
+            'a', 'z'
+        }
+    };
+    HsqlName                    name;
+    public HsqlName             base;
+
+    //
+    int[][] ranges;
+
+    public Charset(HsqlName name) {
+        this.name = name;
+    }
+
+    public int getType() {
+        return SchemaObject.CHARSET;
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public HsqlName getCatalogName() {
+        return name.schema.schema;
+    }
+
+    public HsqlName getSchemaName() {
+        return name.schema;
+    }
+
+    public Grantee getOwner() {
+        return name.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        set.add(base);
+
+        return set;
+    }
+
+    public OrderedHashSet getComponents() {
+        return null;
+    }
+
+    public void compile(Session session, SchemaObject parentObject) {}
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_CREATE).append(' ').append(
+            Tokens.T_CHARACTER).append(' ').append(Tokens.T_SET).append(' ');
+        sb.append(name.getSchemaQualifiedStatementName());
+        sb.append(' ').append(Tokens.T_AS).append(' ').append(Tokens.T_GET);
+        sb.append(' ').append(base.getSchemaQualifiedStatementName());
+
+        return sb.toString();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    public static boolean isInSet(String value, int[][] ranges) {
+
+        int length = value.length();
+
+        mainLoop:
+        for (int index = 0; index < length; index++) {
+            int ch = value.charAt(index);
+
+            for (int i = 0; i < ranges.length; i++) {
+                if (ch > ranges[i][1]) {
+                    continue;
+                }
+
+                if (ch < ranges[i][0]) {
+                    return false;
+                }
+
+                continue mainLoop;
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+
+    public static boolean startsWith(String value, int[][] ranges) {
+
+        int ch = value.charAt(0);
+
+        for (int i = 0; i < ranges.length; i++) {
+            if (ch > ranges[i][1]) {
+                continue;
+            }
+
+            if (ch < ranges[i][0]) {
+                return false;
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    public static Charset getDefaultInstance() {
+        return SqlInvariants.UTF16;
+    }
+}
diff --git a/src/org/hsqldb/types/ClobData.java b/src/org/hsqldb/types/ClobData.java
new file mode 100644
index 0000000..4a5e9bb
--- /dev/null
+++ b/src/org/hsqldb/types/ClobData.java
@@ -0,0 +1,86 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.Reader;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.SessionInterface;
+
+/**
+ * Interface for Character Large Object implementations.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface ClobData extends LobData {
+
+    char[] getChars(SessionInterface session, final long position, int length);
+
+    long length(SessionInterface session);
+
+    String getSubString(SessionInterface session, final long pos,
+                        final int length);
+
+    ClobData getClob(SessionInterface session, final long pos,
+                     final long length);
+
+    void truncate(SessionInterface session, long len);
+
+    Reader getCharacterStream(SessionInterface session);
+
+    int setString(SessionInterface session, long pos, String str);
+
+    int setString(SessionInterface session, long pos, String str, int offset,
+                  int len);
+
+    int setChars(SessionInterface session, long pos, char[] chars, int offset,
+                 int len);
+
+    public long setCharacterStream(SessionInterface session, long pos,
+                                   Reader in);
+
+    long position(SessionInterface session, String searchstr, long start);
+
+    long position(SessionInterface session, ClobData searchstr, long start);
+
+    long nonSpaceLength(SessionInterface session);
+
+    Reader getCharacterStream(SessionInterface session, long pos, long length);
+
+    long getId();
+
+    void setId(long id);
+
+    long getRightTrimSize(SessionInterface session);
+}
diff --git a/src/org/hsqldb/types/ClobDataID.java b/src/org/hsqldb/types/ClobDataID.java
new file mode 100644
index 0000000..0ac0cd3
--- /dev/null
+++ b/src/org/hsqldb/types/ClobDataID.java
@@ -0,0 +1,224 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.Reader;
+
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.result.Result;
+import org.hsqldb.result.ResultLob;
+
+/**
+ * Implementation of CLOB for client and server.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class ClobDataID implements ClobData {
+
+    long id;
+
+    public ClobDataID(long id) {
+        this.id = id;
+    }
+
+    public char[] getChars(SessionInterface session, long position,
+                           int length) {
+
+        ResultLob resultOut = ResultLob.newLobGetCharsRequest(id, position,
+            length);
+        Result resultIn = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return ((ResultLob) resultIn).getCharArray();
+    }
+
+    public long length(SessionInterface session) {
+
+        ResultLob resultOut = ResultLob.newLobGetLengthRequest(id);
+        Result    resultIn  = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return ((ResultLob) resultIn).getBlockLength();
+    }
+
+    public String getSubString(SessionInterface session, long pos,
+                               int length) {
+
+        char[] chars = getChars(session, pos, length);
+
+        return new String(chars);
+    }
+
+    public ClobData getClob(SessionInterface session, long position,
+                            long length) {
+
+        ResultLob resultOut = ResultLob.newLobGetRequest(id, position, length);
+        Result    resultIn  = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return new ClobDataID(((ResultLob) resultIn).getLobID());
+    }
+
+    public void truncate(SessionInterface session, long len) {
+        ResultLob resultOut = ResultLob.newLobTruncateRequest(id, len);
+        Result    resultIn  = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+    }
+
+    public Reader getCharacterStream(SessionInterface session) {
+        long length = length(session);
+        return new ClobInputStream(session, this, 0, length);
+    }
+
+    public long setCharacterStream(SessionInterface session, long pos,
+                                   Reader in) {
+        return 0;
+    }
+
+    public int setString(SessionInterface session, long pos, String str) {
+
+        ResultLob resultOut = ResultLob.newLobSetCharsRequest(id, pos,
+            str.toCharArray());
+        Result resultIn = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return str.length();
+    }
+
+    public int setString(SessionInterface session, long pos, String str,
+                         int offset, int len) {
+
+        if (!isInLimits(str.length(), offset, len)) {
+            throw Error.error(ErrorCode.X_22001);
+        }
+
+        ResultLob resultOut = ResultLob.newLobSetCharsRequest(id, pos,
+            str.substring(offset, len).toCharArray());
+        Result resultIn = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return str.length();
+    }
+
+    public int setChars(SessionInterface session, long pos, char[] chars,
+                        int offset, int len) {
+
+        if (!isInLimits(chars.length, offset, len)) {
+            throw Error.error(ErrorCode.X_22001);
+        }
+
+        char[] newChars = new char[len];
+
+        System.arraycopy(chars, offset, newChars, 0, len);
+
+        ResultLob resultOut = ResultLob.newLobSetCharsRequest(id, pos, chars);
+        Result    resultIn  = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return len;
+    }
+
+    public long position(SessionInterface session, String searchstr,
+                         long start) {
+
+        ResultLob resultOut = ResultLob.newLobGetCharPatternPositionRequest(id,
+            searchstr.toCharArray(), start);
+        Result resultIn = session.execute(resultOut);
+
+        if (resultIn.isError()) {
+            throw resultIn.getException();
+        }
+
+        return ((ResultLob) resultIn).getOffset();
+    }
+
+    public long position(SessionInterface session, ClobData searchstr,
+                         long start) {
+        return 0L;
+    }
+
+    public long nonSpaceLength(SessionInterface session) {
+        return 0;
+    }
+
+    public Reader getCharacterStream(SessionInterface session, long pos,
+                                     long length) {
+        return new ClobInputStream(session, this, pos, length);
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public long getRightTrimSize(SessionInterface session) {
+        return 0;
+    }
+
+    static boolean isInLimits(long fullLength, long pos, long len) {
+        return pos >= 0 && len >= 0 && pos + len <= fullLength;
+    }
+
+    public void setSession(SessionInterface session) {}
+
+    public boolean isBinary() {
+        return false;
+    }
+}
diff --git a/src/org/hsqldb/types/ClobInputStream.java b/src/org/hsqldb/types/ClobInputStream.java
new file mode 100644
index 0000000..e6de276
--- /dev/null
+++ b/src/org/hsqldb/types/ClobInputStream.java
@@ -0,0 +1,161 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.hsqldb.HsqlException;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.java.JavaSystem;
+
+/**
+ * This class is used as an InputStream to retrieve data from a Blob.
+ * mark() and reset() are not supported.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class ClobInputStream extends Reader {
+
+    final ClobData   clob;
+    final long       availableLength;
+    long             bufferOffset;
+    long             currentPosition;
+    char[]           buffer;
+    boolean          isClosed;
+    SessionInterface session;
+
+    public ClobInputStream(SessionInterface session, ClobData clob,
+                           long offset, long length) {
+
+        long clobLength = clob.length(session);
+
+        if (!isInLimits(clobLength, offset, length)) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        this.clob            = clob;
+        this.availableLength = offset + length;
+        this.currentPosition = offset;
+        this.session         = session;
+    }
+
+    public int read() throws IOException {
+
+        if (currentPosition >= availableLength) {
+            return -1;
+        }
+
+        if (buffer == null
+                || currentPosition >= bufferOffset + buffer.length) {
+            try {
+                checkClosed();
+                readIntoBuffer();
+            } catch (HsqlException e) {
+                throw JavaSystem.toIOException(e);
+            }
+        }
+
+        int val = buffer[(int) (currentPosition - bufferOffset)] & 0xff;
+
+        currentPosition++;
+
+        return val;
+    }
+
+    public int read(char[] cbuf, int off, int len) throws IOException {
+
+        checkClosed();
+
+        if (currentPosition + len >= availableLength) {
+            return -1;
+        }
+
+        for (int i = off; i < len; i++) {
+            cbuf[i] = (char) read();
+        }
+
+        return len;
+    }
+
+    public long skip(long n) throws IOException {
+
+        if (n <= 0) {
+            return 0;
+        }
+
+        if (currentPosition + n > availableLength) {
+            n = availableLength - currentPosition;
+        }
+
+        currentPosition += n;
+
+        return n;
+    }
+
+    public int available() {
+        return (int) (bufferOffset + buffer.length - currentPosition);
+    }
+
+    public void close() throws IOException {
+        isClosed = true;
+    }
+
+    private void checkClosed() throws IOException {
+
+        if (isClosed) {
+            throw new IOException(Error.getMessage(ErrorCode.X_0F503));
+        }
+    }
+
+    private void readIntoBuffer() {
+
+        long readLength = availableLength - currentPosition;
+
+        if (readLength <= 0) {}
+
+        if (readLength > session.getStreamBlockSize()) {
+            readLength = session.getStreamBlockSize();
+        }
+
+        buffer = clob.getChars(session, currentPosition, (int) readLength);
+        bufferOffset = currentPosition;
+    }
+
+    static boolean isInLimits(long fullLength, long pos, long len) {
+        return pos >= 0 && len >= 0 && pos + len <= fullLength;
+    }
+}
diff --git a/src/org/hsqldb/types/ClobType.java b/src/org/hsqldb/types/ClobType.java
new file mode 100644
index 0000000..65a02e5
--- /dev/null
+++ b/src/org/hsqldb/types/ClobType.java
@@ -0,0 +1,196 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+
+/**
+ * Type subclass CLOB data.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class ClobType extends CharacterType {
+
+    static final long maxClobPrecision = 1024L * 1024 * 1024 * 1024;
+    static final int  defaultClobSize  = 1024 * 1024 * 16;
+
+    public ClobType(long precision) {
+        super(Types.SQL_CLOB, precision);
+    }
+
+    public int displaySize() {
+        return precision > Integer.MAX_VALUE ? Integer.MAX_VALUE
+                                             : (int) precision;
+    }
+
+    public int getJDBCTypeCode() {
+        return Types.CLOB;
+    }
+
+    public Class getJDBCClass() {
+        return java.sql.Clob.class;
+    }
+
+    public String getJDBCClassName() {
+        return "java.sql.Clob";
+    }
+
+    public int getSQLGenericTypeCode() {
+        return typeCode;
+    }
+
+    public String getDefinition() {
+
+        long   factor     = precision;
+        String multiplier = null;
+
+        if (precision % (1024) == 0) {
+            if (precision % (1024 * 1024 * 1024) == 0) {
+                factor     = precision / (1024 * 1024 * 1024);
+                multiplier = Tokens.T_G_FACTOR;
+            } else if (precision % (1024 * 1024) == 0) {
+                factor     = precision / (1024 * 1024);
+                multiplier = Tokens.T_M_FACTOR;
+            } else {
+                factor     = precision / (1024);
+                multiplier = Tokens.T_K_FACTOR;
+            }
+        }
+
+        StringBuffer sb = new StringBuffer(16);
+
+        sb.append(getNameString());
+        sb.append('(');
+        sb.append(factor);
+
+        if (multiplier != null) {
+            sb.append(multiplier);
+        }
+
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public long getMaxPrecision() {
+        return maxClobPrecision;
+    }
+
+    public boolean isLobType() {
+        return true;
+    }
+
+    /** @todo - collation comparison */
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        if (b instanceof String) {
+            return session.database.lobManager.compare((ClobData) a,
+                    (String) b);
+        }
+
+        return session.database.lobManager.compare((ClobData) a, (ClobData) b);
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (a instanceof ClobData) {
+            return a;
+        }
+
+        if (a instanceof String) {
+            ClobData clob = session.createClob(((String) a).length());
+
+            clob.setString(session, 0, (String) a);
+
+            return clob;
+        }
+
+        throw Error.error(ErrorCode.X_42561);
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return ((ClobData) a).toString();
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        String s = convertToString(a);
+
+        return StringConverter.toQuotedString(s, '\'', true);
+    }
+
+    public long position(SessionInterface session, Object data,
+                         Object otherData, Type otherType, long start) {
+
+        if (otherType.typeCode == Types.SQL_CLOB) {
+            return ((ClobData) data).position(session, (ClobData) otherData,
+                                              start);
+        } else if (otherType.isCharacterType()) {
+            return ((ClobData) data).position(session, (String) otherData,
+                                              start);
+        } else {
+            throw Error.runtimeError(ErrorCode.U_S0500, "ClobType");
+        }
+    }
+}
diff --git a/src/org/hsqldb/types/DTIType.java b/src/org/hsqldb/types/DTIType.java
new file mode 100644
index 0000000..1fcb9ee
--- /dev/null
+++ b/src/org/hsqldb/types/DTIType.java
@@ -0,0 +1,486 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.math.BigDecimal;
+
+import org.hsqldb.Session;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.IntKeyIntValueHashMap;
+
+/**
+ * Common elements for Type instances for DATETIME and INTERVAL.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public abstract class DTIType extends Type {
+
+    public static final byte[] yearToSecondSeparators = {
+        '-', '-', ' ', ':', ':', '.'
+    };
+    public static final int[]  yearToSecondFactors    = {
+        12, 1, 24 * 60 * 60, 60 * 60, 60, 1, 0
+    };
+
+//    static final int[]  hourToSecondFactors   = {
+//        60 * 60, 60, 1, 0
+//    };
+    public static final int[]  yearToSecondLimits           = {
+        0, 12, 0, 24, 60, 60, 1000000000
+    };
+    public static final int    INTERVAL_MONTH_INDEX         = 1;
+    public static final int    INTERVAL_FRACTION_PART_INDEX = 6;
+    public static final long[] precisionLimits              = {
+        1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
+        1000000000, 10000000000L, 100000000000L, 1000000000000L
+    };
+    public static final int[] precisionFactors = {
+        100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1
+    };
+    public static final int[] nanoScaleFactors = {
+        1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10,
+        1
+    };
+    public static final int timezoneSecondsLimit = 14 * 60 * 60;
+    static final int[]      intervalParts        = {
+        Types.SQL_INTERVAL_YEAR, Types.SQL_INTERVAL_MONTH,
+        Types.SQL_INTERVAL_DAY, Types.SQL_INTERVAL_HOUR,
+        Types.SQL_INTERVAL_MINUTE, Types.SQL_INTERVAL_SECOND
+    };
+    static final int[][] intervalTypes = {
+        {
+            Types.SQL_INTERVAL_YEAR, Types.SQL_INTERVAL_YEAR_TO_MONTH, 0, 0, 0,
+            0
+        }, {
+            0, Types.SQL_INTERVAL_MONTH, 0, 0, 0, 0
+        }, {
+            0, 0, Types.SQL_INTERVAL_DAY, Types.SQL_INTERVAL_DAY_TO_HOUR,
+            Types.SQL_INTERVAL_DAY_TO_MINUTE, Types.SQL_INTERVAL_DAY_TO_SECOND
+        }, {
+            0, 0, 0, Types.SQL_INTERVAL_HOUR,
+            Types.SQL_INTERVAL_HOUR_TO_MINUTE,
+            Types.SQL_INTERVAL_HOUR_TO_SECOND
+        }, {
+            0, 0, 0, 0, Types.SQL_INTERVAL_MINUTE,
+            Types.SQL_INTERVAL_MINUTE_TO_SECOND
+        }, {
+            0, 0, 0, 0, 0, Types.SQL_INTERVAL_SECOND
+        },
+    };
+    static final IntKeyIntValueHashMap intervalIndexMap =
+        new IntKeyIntValueHashMap();
+
+    static {
+        intervalIndexMap.put(Types.SQL_INTERVAL_YEAR, 0);
+        intervalIndexMap.put(Types.SQL_INTERVAL_MONTH, 1);
+        intervalIndexMap.put(Types.SQL_INTERVAL_DAY, 2);
+        intervalIndexMap.put(Types.SQL_INTERVAL_HOUR, 3);
+        intervalIndexMap.put(Types.SQL_INTERVAL_MINUTE, 4);
+        intervalIndexMap.put(Types.SQL_INTERVAL_SECOND, 5);
+    }
+
+    public static final int TIMEZONE_HOUR   = Types.SQL_TYPE_NUMBER_LIMIT + 1;
+    public static final int TIMEZONE_MINUTE = Types.SQL_TYPE_NUMBER_LIMIT + 2;
+    public static final int DAY_OF_WEEK     = Types.SQL_TYPE_NUMBER_LIMIT + 3;
+    public static final int DAY_OF_MONTH    = Types.SQL_TYPE_NUMBER_LIMIT + 4;
+    public static final int DAY_OF_YEAR     = Types.SQL_TYPE_NUMBER_LIMIT + 5;
+    public static final int WEEK_OF_YEAR    = Types.SQL_TYPE_NUMBER_LIMIT + 6;
+    public static final int QUARTER         = Types.SQL_TYPE_NUMBER_LIMIT + 7;
+    public static final int DAY_NAME        = Types.SQL_TYPE_NUMBER_LIMIT + 8;
+    public static final int MONTH_NAME      = Types.SQL_TYPE_NUMBER_LIMIT + 9;
+    public static final int SECONDS_MIDNIGHT = Types.SQL_TYPE_NUMBER_LIMIT
+        + 10;
+
+    //
+    public final int startIntervalType;
+    public final int endIntervalType;
+
+    //
+    public final int startPartIndex;
+    public final int endPartIndex;
+
+    protected DTIType(int typeGroup, int type, long precision, int scale,
+                      int startIntervalType, int endIntervalType) {
+
+        super(typeGroup, type, precision, scale);
+
+        this.startIntervalType = startIntervalType;
+        this.endIntervalType   = endIntervalType;
+        startPartIndex         = intervalIndexMap.get(startIntervalType);
+        endPartIndex           = intervalIndexMap.get(endIntervalType);
+    }
+
+    protected DTIType(int typeGroup, int type, long precision, int scale) {
+
+        super(typeGroup, type, precision, scale);
+
+        switch (type) {
+
+            case Types.SQL_DATE :
+                startIntervalType = Types.SQL_INTERVAL_YEAR;
+                endIntervalType   = Types.SQL_INTERVAL_DAY;
+                break;
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                startIntervalType = Types.SQL_INTERVAL_HOUR;
+                endIntervalType   = Types.SQL_INTERVAL_SECOND;
+                break;
+
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                startIntervalType = Types.SQL_INTERVAL_YEAR;
+                endIntervalType   = Types.SQL_INTERVAL_SECOND;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DTIType");
+        }
+
+        startPartIndex = intervalIndexMap.get(startIntervalType);
+        endPartIndex   = intervalIndexMap.get(endIntervalType);
+    }
+
+    String intervalSecondToString(long seconds, int nanos, boolean signed) {
+
+        StringBuffer sb = new StringBuffer(64);
+
+        if (seconds < 0) {
+            seconds = -seconds;
+
+            sb.append('-');
+        } else if (signed) {
+            sb.append('+');
+        }
+
+        for (int i = startPartIndex; i <= endPartIndex; i++) {
+            int  factor = DTIType.yearToSecondFactors[i];
+            long part   = seconds / factor;
+
+            if (i == startPartIndex) {
+                int startDigits = precision == 0 ? 2
+                                                 : (int) precision;
+                int zeros = (int) startDigits - getPrecisionExponent(part);
+/*
+                for (int j = 0; j < zeros; j++) {
+                    buffer.append('0');
+                }
+*/
+            } else if (part < 10) {
+                sb.append('0');
+            }
+
+            sb.append(part);
+
+            seconds %= factor;
+
+            if (i < endPartIndex) {
+                sb.append((char) DTIType.yearToSecondSeparators[i]);
+            }
+        }
+
+        if (scale != 0) {
+            sb.append((char) DTIType
+                .yearToSecondSeparators[DTIType.INTERVAL_FRACTION_PART_INDEX - 1]);
+        }
+
+        if (nanos < 0) {
+            nanos = -nanos;
+        }
+
+        for (int i = 0; i < scale; i++) {
+            int digit = nanos / DTIType.precisionFactors[i];
+
+            nanos -= digit * DTIType.precisionFactors[i];
+
+            sb.append(digit);
+        }
+
+        return sb.toString();
+    }
+
+    public int getStartIntervalType() {
+        return startIntervalType;
+    }
+
+    public int getEndIntervalType() {
+        return endIntervalType;
+    }
+
+    public Type getExtractType(int part) {
+
+        switch (part) {
+
+            case DAY_NAME :
+            case MONTH_NAME :
+            case QUARTER :
+            case DAY_OF_MONTH :
+            case DAY_OF_YEAR :
+            case DAY_OF_WEEK :
+            case WEEK_OF_YEAR :
+                if (!isDateTimeType()
+                        || startIntervalType != Types.SQL_INTERVAL_YEAR) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                if (part == DAY_NAME || part == MONTH_NAME) {
+                    return Type.SQL_VARCHAR;
+                } else {
+                    return Type.SQL_INTEGER;
+                }
+            case Types.SQL_INTERVAL_SECOND :
+                if (part == startIntervalType) {
+                    if (scale != 0) {
+                        return new NumberType(Types.SQL_DECIMAL,
+                                              precision + scale, scale);
+                    }
+                } else if (part == endIntervalType) {
+                    if (scale != 0) {
+                        return new NumberType(Types.SQL_DECIMAL,
+                                              maxIntervalPrecision + scale,
+                                              scale);
+                    }
+                }
+
+            // fall through
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_MONTH :
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_MINUTE :
+                if (part < startIntervalType || part > endIntervalType) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                return Type.SQL_INTEGER;
+
+            case SECONDS_MIDNIGHT :
+                if (!isDateTimeType()
+                        || endIntervalType < Types.SQL_INTERVAL_SECOND) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                return Type.SQL_INTEGER;
+
+            case TIMEZONE_HOUR :
+            case TIMEZONE_MINUTE :
+                if (typeCode != Types.SQL_TIMESTAMP_WITH_TIME_ZONE
+                        && typeCode != Types.SQL_TIME_WITH_TIME_ZONE) {
+                    throw Error.error(ErrorCode.X_42561);
+                }
+
+                return Type.SQL_INTEGER;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DTIType");
+        }
+    }
+
+    public static int normaliseFraction(int fraction, int precision) {
+        return (fraction / nanoScaleFactors[precision])
+               * nanoScaleFactors[precision];
+    }
+
+    static int getPrecisionExponent(long value) {
+
+        int i = 1;
+
+        for (; i < precisionLimits.length; i++) {
+            if (value < precisionLimits[i]) {
+                break;
+            }
+        }
+
+        return i;
+    }
+
+    public static int getFieldNameTypeForToken(int token) {
+
+        switch (token) {
+
+            case Tokens.YEAR :
+                return Types.SQL_INTERVAL_YEAR;
+
+            case Tokens.MONTH :
+                return Types.SQL_INTERVAL_MONTH;
+
+            case Tokens.DAY :
+                return Types.SQL_INTERVAL_DAY;
+
+            case Tokens.HOUR :
+                return Types.SQL_INTERVAL_HOUR;
+
+            case Tokens.MINUTE :
+                return Types.SQL_INTERVAL_MINUTE;
+
+            case Tokens.SECOND :
+                return Types.SQL_INTERVAL_SECOND;
+
+            case Tokens.TIMEZONE_HOUR :
+                return TIMEZONE_HOUR;
+
+            case Tokens.TIMEZONE_MINUTE :
+                return TIMEZONE_MINUTE;
+
+            case Tokens.DAY_NAME :
+                return DAY_NAME;
+
+            case Tokens.MONTH_NAME :
+                return MONTH_NAME;
+
+            case Tokens.QUARTER :
+                return QUARTER;
+
+            case Tokens.DAY_OF_MONTH :
+                return DAY_OF_MONTH;
+
+            case Tokens.DAY_OF_WEEK :
+                return DAY_OF_WEEK;
+
+            case Tokens.DAY_OF_YEAR :
+                return DAY_OF_YEAR;
+
+            case Tokens.WEEK_OF_YEAR :
+                return WEEK_OF_YEAR;
+
+            case Tokens.SECONDS_MIDNIGHT :
+                return SECONDS_MIDNIGHT;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DTIType");
+        }
+    }
+
+    public static String getFieldNameTokenForType(int type) {
+
+        switch (type) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                return Tokens.T_YEAR;
+
+            case Types.SQL_INTERVAL_MONTH :
+                return Tokens.T_MONTH;
+
+            case Types.SQL_INTERVAL_DAY :
+                return Tokens.T_DAY;
+
+            case Types.SQL_INTERVAL_HOUR :
+                return Tokens.T_HOUR;
+
+            case Types.SQL_INTERVAL_MINUTE :
+                return Tokens.T_MINUTE;
+
+            case Types.SQL_INTERVAL_SECOND :
+                return Tokens.T_SECOND;
+
+            case TIMEZONE_HOUR :
+                return Tokens.T_TIMEZONE_HOUR;
+
+            case TIMEZONE_MINUTE :
+                return Tokens.T_TIMEZONE_MINUTE;
+
+            case DAY_NAME :
+                return Tokens.T_DAY_NAME;
+
+            case MONTH_NAME :
+                return Tokens.T_MONTH_NAME;
+
+            case QUARTER :
+                return Tokens.T_QUARTER;
+
+            case DAY_OF_MONTH :
+                return Tokens.T_DAY_OF_MONTH;
+
+            case DAY_OF_WEEK :
+                return Tokens.T_DAY_OF_WEEK;
+
+            case DAY_OF_YEAR :
+                return Tokens.T_DAY_OF_YEAR;
+
+            case WEEK_OF_YEAR :
+                return Tokens.T_WEEK_OF_YEAR;
+
+            case SECONDS_MIDNIGHT :
+                return Tokens.T_SECONDS_MIDNIGHT;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DTIType");
+        }
+    }
+
+    public static boolean isValidDatetimeRange(Type a, Type b) {
+
+        if (!a.isDateTimeType()) {
+            return false;
+        }
+
+        if (b.isDateTimeType()) {
+            if ((a.typeCode == Types.SQL_TIME && b.typeCode == Types.SQL_DATE)
+                    || (a.typeCode == Types.SQL_DATE
+                        && b.typeCode == Types.SQL_TIME)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        if (b.isIntervalType()) {
+            return ((DateTimeType) a).canAdd((IntervalType) b);
+        }
+
+        return false;
+    }
+
+    public static final int defaultTimeFractionPrecision      = 0;
+    public static final int defaultTimestampFractionPrecision = 6;
+    public static final int defaultIntervalPrecision          = 2;
+    public static final int defaultIntervalFractionPrecision  = 6;
+    public static final int maxIntervalPrecision              = 9;
+    public static final int maxFractionPrecision              = 9;
+    public static final int limitNanoseconds                  = 1000000000;
+
+    abstract public int getPart(Session session, Object dateTime, int part);
+
+    abstract public BigDecimal getSecondPart(Object dateTime);
+
+    BigDecimal getSecondPart(long seconds, long nanos) {
+
+        seconds *= DTIType.precisionLimits[scale];
+        seconds += nanos / DTIType.nanoScaleFactors[scale];
+
+        return BigDecimal.valueOf(seconds, scale);
+    }
+}
diff --git a/src/org/hsqldb/types/DateTimeType.java b/src/org/hsqldb/types/DateTimeType.java
new file mode 100644
index 0000000..88326ed
--- /dev/null
+++ b/src/org/hsqldb/types/DateTimeType.java
@@ -0,0 +1,1582 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.hsqldb.HsqlDateTime;
+import org.hsqldb.HsqlException;
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+
+/**
+ * Type subclass for DATE, TIME and TIMESTAMP.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class DateTimeType extends DTIType {
+
+    public final boolean withTimeZone;
+
+    public DateTimeType(int typeGroup, int type, int scale) {
+
+        super(typeGroup, type, 0, scale);
+
+        withTimeZone = type == Types.SQL_TIME_WITH_TIME_ZONE
+                       || type == Types.SQL_TIMESTAMP_WITH_TIME_ZONE;
+    }
+
+    public int displaySize() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                return 10;
+
+            case Types.SQL_TIME :
+                return 8 + (scale == 0 ? 0
+                                       : scale + 1);
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                return 8 + (scale == 0 ? 0
+                                       : scale + 1) + 6;
+
+            case Types.SQL_TIMESTAMP :
+                return 19 + (scale == 0 ? 0
+                                        : scale + 1);
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return 19 + (scale == 0 ? 0
+                                        : scale + 1) + 6;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public int getJDBCTypeCode() {
+
+        // JDBC numbers happen to be the same as SQL
+        return typeCode;
+    }
+
+    public Class getJDBCClass() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                return java.sql.Date.class;
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                return java.sql.Time.class;
+
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return java.sql.Timestamp.class;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public String getJDBCClassName() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                return "java.sql.Date";
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                return "java.sql.Time";
+
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return "java.sql.Timestamp";
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public int getJDBCPrecision() {
+        return this.displaySize();
+    }
+
+    public int getSQLGenericTypeCode() {
+        return Types.SQL_DATETIME;
+    }
+
+    public String getNameString() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                return Tokens.T_DATE;
+
+            case Types.SQL_TIME :
+                return Tokens.T_TIME;
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                return Tokens.T_TIME + ' ' + Tokens.T_WITH + ' '
+                       + Tokens.T_TIME + ' ' + Tokens.T_ZONE;
+
+            case Types.SQL_TIMESTAMP :
+                return Tokens.T_TIMESTAMP;
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return Tokens.T_TIMESTAMP + ' ' + Tokens.T_WITH + ' '
+                       + Tokens.T_TIME + ' ' + Tokens.T_ZONE;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public String getDefinition() {
+
+        if (scale == DTIType.defaultTimeFractionPrecision) {
+            return getNameString();
+        }
+
+        String token;
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                return Tokens.T_DATE;
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIME :
+                if (scale == DTIType.defaultTimeFractionPrecision) {
+                    return getNameString();
+                }
+
+                token = Tokens.T_TIME;
+                break;
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP :
+                if (scale == DTIType.defaultTimestampFractionPrecision) {
+                    return getNameString();
+                }
+
+                token = Tokens.T_TIMESTAMP;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+
+        StringBuffer sb = new StringBuffer(16);
+
+        sb.append(token);
+        sb.append('(');
+        sb.append(scale);
+        sb.append(')');
+
+        if (withTimeZone) {
+            sb.append(' ' + Tokens.T_WITH + ' ' + Tokens.T_TIME + ' '
+                      + Tokens.T_ZONE);
+        }
+
+        return sb.toString();
+    }
+
+    public boolean isDateTimeType() {
+        return true;
+    }
+
+    public boolean isDateTimeTypeWithZone() {
+        return withTimeZone;
+    }
+
+    public boolean acceptsFractionalPrecision() {
+        return typeCode != Types.SQL_DATE;
+    }
+
+    public Type getAggregateType(Type other) {
+
+        // DATE with DATE returned here
+        if (typeCode == other.typeCode) {
+            return scale >= other.scale ? this
+                                        : other;
+        }
+
+        if (other.typeCode == Types.SQL_ALL_TYPES) {
+            return this;
+        }
+
+        if (other.isCharacterType()) {
+            return other.getAggregateType(this);
+        }
+
+        if (!other.isDateTimeType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        DateTimeType otherType = (DateTimeType) other;
+
+        // DATE with TIME caught here
+        if (otherType.startIntervalType > endIntervalType
+                || startIntervalType > otherType.endIntervalType) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        int     newType = typeCode;
+        int     scale   = this.scale > otherType.scale ? this.scale
+                                                       : otherType.scale;
+        boolean zone    = withTimeZone || otherType.withTimeZone;
+        int startType = otherType.startIntervalType > startIntervalType
+                        ? startIntervalType
+                        : otherType.startIntervalType;
+
+        if (startType == Types.SQL_INTERVAL_HOUR) {
+            newType = zone ? Types.SQL_TIME_WITH_TIME_ZONE
+                           : Types.SQL_TIME;
+        } else {
+            newType = zone ? Types.SQL_TIMESTAMP_WITH_TIME_ZONE
+                           : Types.SQL_TIMESTAMP;
+        }
+
+        return getDateTimeType(newType, scale);
+    }
+
+    public Type getCombinedType(Type other, int operation) {
+
+        switch (operation) {
+
+            case OpTypes.EQUAL :
+            case OpTypes.GREATER :
+            case OpTypes.GREATER_EQUAL :
+            case OpTypes.SMALLER_EQUAL :
+            case OpTypes.SMALLER :
+            case OpTypes.NOT_EQUAL : {
+                if (typeCode == other.typeCode) {
+                    return this;
+                }
+
+                if (other.typeCode == Types.SQL_ALL_TYPES) {
+                    return this;
+                }
+
+                if (!other.isDateTimeType()) {
+                    throw Error.error(ErrorCode.X_42562);
+                }
+
+                DateTimeType otherType = (DateTimeType) other;
+
+                // DATE with TIME caught here
+                if (otherType.startIntervalType > endIntervalType
+                        || startIntervalType > otherType.endIntervalType) {
+                    throw Error.error(ErrorCode.X_42562);
+                }
+
+                int     newType = typeCode;
+                int     scale   = this.scale > otherType.scale ? this.scale
+                                                               : otherType
+                                                                   .scale;
+                boolean zone    = withTimeZone || otherType.withTimeZone;
+                int startType = otherType.startIntervalType
+                                > startIntervalType ? startIntervalType
+                                                    : otherType
+                                                        .startIntervalType;
+
+                if (startType == Types.SQL_INTERVAL_HOUR) {
+                    newType = zone ? Types.SQL_TIME_WITH_TIME_ZONE
+                                   : Types.SQL_TIME;
+                } else {
+                    newType = zone ? Types.SQL_TIMESTAMP_WITH_TIME_ZONE
+                                   : Types.SQL_TIMESTAMP;
+                }
+
+                return getDateTimeType(newType, scale);
+            }
+            case OpTypes.ADD :
+            case OpTypes.SUBTRACT :
+                if (other.isIntervalType()) {
+                    if (typeCode != Types.SQL_DATE && other.scale > scale) {
+                        return getDateTimeType(typeCode, other.scale);
+                    }
+
+                    return this;
+                }
+                break;
+
+            default :
+        }
+
+        throw Error.error(ErrorCode.X_42562);
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        long diff;
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE : {
+                diff = ((TimeData) a).getSeconds()
+                       - ((TimeData) b).getSeconds();
+
+                if (diff == 0) {
+                    diff = ((TimeData) a).getNanos()
+                           - ((TimeData) b).getNanos();
+                }
+
+                return diff == 0 ? 0
+                                 : diff > 0 ? 1
+                                            : -1;
+            }
+            case Types.SQL_DATE :
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                diff = ((TimestampData) a).getSeconds()
+                       - ((TimestampData) b).getSeconds();
+
+                if (diff == 0) {
+                    diff = ((TimestampData) a).getNanos()
+                           - ((TimestampData) b).getNanos();
+                }
+
+                return diff == 0 ? 0
+                                 : diff > 0 ? 1
+                                            : -1;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (scale == maxFractionPrecision) {
+            return a;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                return a;
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIME : {
+                TimeData ti       = (TimeData) a;
+                int      nanos    = ti.getNanos();
+                int      newNanos = scaleNanos(nanos);
+
+                if (newNanos == nanos) {
+                    return ti;
+                }
+
+                return new TimeData(ti.getSeconds(), newNanos, ti.getZone());
+            }
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP : {
+                TimestampData ts       = (TimestampData) a;
+                int           nanos    = ts.getNanos();
+                int           newNanos = scaleNanos(nanos);
+
+                if (newNanos == nanos) {
+                    return ts;
+                }
+
+                return new TimestampData(ts.getSeconds(), newNanos,
+                                         ts.getZone());
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    int scaleNanos(int nanos) {
+
+        int divisor = nanoScaleFactors[scale];
+
+        return (nanos / divisor) * divisor;
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+
+        if (a == null) {
+            return a;
+        }
+
+        switch (otherType.typeCode) {
+
+            case Types.SQL_CLOB :
+                a = a.toString();
+
+            //fall through
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                switch (this.typeCode) {
+
+                    case Types.SQL_DATE :
+                    case Types.SQL_TIME_WITH_TIME_ZONE :
+                    case Types.SQL_TIME :
+                    case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                    case Types.SQL_TIMESTAMP : {
+                        return session.getScanner().convertToDatetimeInterval(
+                            session, (String) a, this);
+                    }
+                }
+                break;
+
+            case Types.SQL_DATE :
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                break;
+
+            default :
+                throw Error.error(ErrorCode.X_42561);
+        }
+
+        switch (this.typeCode) {
+
+            case Types.SQL_DATE :
+                switch (otherType.typeCode) {
+
+                    case Types.SQL_DATE :
+                        return a;
+
+                    case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                        long seconds = ((TimestampData) a).getSeconds()
+                                       + ((TimestampData) a).getZone();
+                        long l = HsqlDateTime.getNormalisedDate(seconds
+                            * 1000);
+
+                        return new TimestampData(l / 1000);
+                    }
+                    case Types.SQL_TIMESTAMP : {
+                        long l = HsqlDateTime.getNormalisedDate(
+                            ((TimestampData) a).getSeconds() * 1000);
+
+                        return new TimestampData(l / 1000);
+                    }
+                    default :
+                        throw Error.error(ErrorCode.X_42561);
+                }
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                switch (otherType.typeCode) {
+
+                    case Types.SQL_TIME_WITH_TIME_ZONE :
+                        return convertToTypeLimits(session, a);
+
+                    case Types.SQL_TIME : {
+                        TimeData ti = (TimeData) a;
+
+                        return new TimeData(
+                            ti.getSeconds() - session.getZoneSeconds(),
+                            scaleNanos(ti.getNanos()),
+                            session.getZoneSeconds());
+                    }
+                    case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                        TimestampData ts = (TimestampData) a;
+                        long seconds =
+                            HsqlDateTime.convertToNormalisedTime(
+                                ts.getSeconds() * 1000) / 1000;
+
+                        return new TimeData((int) (seconds),
+                                            scaleNanos(ts.getNanos()),
+                                            ts.getZone());
+                    }
+                    case Types.SQL_TIMESTAMP : {
+                        TimestampData ts = (TimestampData) a;
+                        long seconds = ts.getSeconds()
+                                       - session.getZoneSeconds();
+
+                        seconds =
+                            HsqlDateTime.convertToNormalisedTime(
+                                seconds * 1000) / 1000;
+
+                        return new TimeData((int) (seconds),
+                                            scaleNanos(ts.getNanos()),
+                                            session.getZoneSeconds());
+                    }
+                    default :
+                        throw Error.error(ErrorCode.X_42561);
+                }
+            case Types.SQL_TIME :
+                switch (otherType.typeCode) {
+
+                    case Types.SQL_TIME_WITH_TIME_ZONE : {
+                        TimeData ti = (TimeData) a;
+
+                        return new TimeData(ti.getSeconds() + ti.getZone(),
+                                            scaleNanos(ti.getNanos()), 0);
+                    }
+                    case Types.SQL_TIME :
+                        return convertToTypeLimits(session, a);
+
+                    case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                        TimestampData ts      = (TimestampData) a;
+                        long          seconds = ts.getSeconds() + ts.getZone();
+
+                        seconds =
+                            HsqlDateTime.convertToNormalisedTime(
+                                seconds * 1000) / 1000;
+
+                        return new TimeData((int) (seconds),
+                                            scaleNanos(ts.getNanos()), 0);
+                    }
+                    case Types.SQL_TIMESTAMP :
+                        TimestampData ts = (TimestampData) a;
+                        long seconds =
+                            HsqlDateTime.convertToNormalisedTime(
+                                ts.getSeconds() * 1000) / 1000;
+
+                        return new TimeData((int) (seconds),
+                                            scaleNanos(ts.getNanos()));
+
+                    default :
+                        throw Error.error(ErrorCode.X_42561);
+                }
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                switch (otherType.typeCode) {
+
+                    case Types.SQL_TIME_WITH_TIME_ZONE : {
+                        TimeData ti = (TimeData) a;
+                        long seconds = session.getCurrentDate().getSeconds()
+                                       + ti.getSeconds();
+
+                        return new TimestampData(seconds,
+                                                 scaleNanos(ti.getNanos()),
+                                                 ti.getZone());
+                    }
+                    case Types.SQL_TIME : {
+                        TimeData ti = (TimeData) a;
+                        long seconds = session.getCurrentDate().getSeconds()
+                                       + ti.getSeconds()
+                                       - session.getZoneSeconds();
+
+                        return new TimestampData(seconds,
+                                                 scaleNanos(ti.getNanos()),
+                                                 session.getZoneSeconds());
+                    }
+                    case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                        return convertToTypeLimits(session, a);
+
+                    case Types.SQL_TIMESTAMP : {
+                        TimestampData ts = (TimestampData) a;
+                        long seconds = ts.getSeconds()
+                                       - session.getZoneSeconds();
+
+                        return new TimestampData(seconds,
+                                                 scaleNanos(ts.getNanos()),
+                                                 session.getZoneSeconds());
+                    }
+                    case Types.SQL_DATE : {
+                        TimestampData ts = (TimestampData) a;
+
+                        return new TimestampData(ts.getSeconds(), 0,
+                                                 session.getZoneSeconds());
+                    }
+                    default :
+                        throw Error.error(ErrorCode.X_42561);
+                }
+            case Types.SQL_TIMESTAMP :
+                switch (otherType.typeCode) {
+
+                    case Types.SQL_TIME_WITH_TIME_ZONE : {
+                        TimeData ti = (TimeData) a;
+                        long seconds = session.getCurrentDate().getSeconds()
+                                       + ti.getSeconds()
+                                       - session.getZoneSeconds();
+
+                        return new TimestampData(seconds,
+                                                 scaleNanos(ti.getNanos()),
+                                                 session.getZoneSeconds());
+                    }
+                    case Types.SQL_TIME : {
+                        TimeData ti = (TimeData) a;
+                        long seconds = session.getCurrentDate().getSeconds()
+                                       + ti.getSeconds();
+
+                        return new TimestampData(seconds,
+                                                 scaleNanos(ti.getNanos()));
+                    }
+                    case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                        TimestampData ts      = (TimestampData) a;
+                        long          seconds = ts.getSeconds() + ts.getZone();
+
+                        return new TimestampData(seconds,
+                                                 scaleNanos(ts.getNanos()));
+                    }
+                    case Types.SQL_TIMESTAMP :
+                        return convertToTypeLimits(session, a);
+
+                    case Types.SQL_DATE :
+                        return a;
+
+                    default :
+                        throw Error.error(ErrorCode.X_42561);
+                }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+        throw Error.error(ErrorCode.X_42561);
+    }
+
+    /** @todo - check the time zone conversion */
+    public Object convertJavaToSQL(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                if (a instanceof java.sql.Date) {
+                    break;
+                }
+
+                if (a instanceof java.util.Date) {
+                    long millis;
+                    int  nanos       = 0;
+                    int  zoneSeconds = 0;
+
+                    if (typeCode == Types.SQL_TIME) {
+                        millis = HsqlDateTime.convertMillisFromCalendar(
+                            session.getCalendar(),
+                            ((java.util.Date) a).getTime());
+                    } else {
+                        millis      = ((java.util.Date) a).getTime();
+                        zoneSeconds = session.getZoneSeconds();
+                    }
+
+                    millis = HsqlDateTime.getNormalisedTime(millis);
+
+                    if (a instanceof java.sql.Timestamp) {
+                        nanos = ((java.sql.Timestamp) a).getNanos();
+                        nanos = normaliseFraction(nanos, scale);
+                    }
+
+                    return new TimeData((int) millis / 1000, nanos,
+                                        zoneSeconds);
+                }
+                break;
+
+            case Types.SQL_DATE : {
+                if (a instanceof java.sql.Time) {
+                    break;
+                }
+
+                if (a instanceof java.util.Date) {
+                    long millis;
+
+                    millis = HsqlDateTime.convertMillisFromCalendar(
+                        session.getCalendar(), ((java.util.Date) a).getTime());
+                    millis = HsqlDateTime.getNormalisedDate(millis);
+
+                    return new TimestampData(millis / 1000);
+                }
+
+                break;
+            }
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                if (a instanceof java.sql.Time) {
+                    break;
+                }
+
+                if (a instanceof java.util.Date) {
+                    long millis;
+                    int  nanos       = 0;
+                    int  zoneSeconds = 0;
+
+                    if (typeCode == Types.SQL_TIMESTAMP) {
+                        millis = HsqlDateTime.convertMillisFromCalendar(
+                            session.getCalendar(),
+                            ((java.util.Date) a).getTime());
+                    } else {
+                        millis      = ((java.util.Date) a).getTime();
+                        zoneSeconds = session.getZoneSeconds();
+                    }
+
+                    if (a instanceof java.sql.Timestamp) {
+                        nanos = ((java.sql.Timestamp) a).getNanos();
+                        nanos = this.normaliseFraction(nanos, scale);
+                    }
+
+                    return new TimestampData(millis / 1000, nanos,
+                                             zoneSeconds);
+                }
+
+                break;
+            }
+        }
+
+        throw Error.error(ErrorCode.X_42561);
+    }
+
+    /*
+                return (Time) Type.SQL_TIME.getJavaDateObject(session, t, 0);
+        java.sql.Timestamp value = new java.sql.Timestamp(
+            (((TimestampData) o).getSeconds() - ((TimestampData) o)
+                .getZone()) * 1000);
+    */
+    public Object convertSQLToJavaGMT(SessionInterface session, Object a) {
+
+        long millis;
+
+        switch (typeCode) {
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                millis = ((TimeData) a).getSeconds() * 1000;
+
+                return new java.sql.Time(millis);
+
+            case Types.SQL_DATE :
+                millis = ((TimestampData) a).getSeconds() * 1000;
+
+                return new java.sql.Date(millis);
+
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                millis = ((TimestampData) a).getSeconds() * 1000;
+
+                java.sql.Timestamp value = new java.sql.Timestamp(millis);
+
+                value.setNanos(((TimestampData) a).getNanos());
+
+                return value;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public Object convertSQLToJava(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_TIME : {
+                Calendar cal = session.getCalendar();
+                long millis = HsqlDateTime.convertMillisToCalendar(cal,
+                    ((TimeData) a).getSeconds() * 1000);
+
+                millis = HsqlDateTime.getNormalisedTime(cal, millis);
+
+                java.sql.Time value = new java.sql.Time(millis);
+
+                return value;
+            }
+            case Types.SQL_TIME_WITH_TIME_ZONE : {
+                int seconds = ((TimeData) a).getSeconds();
+
+                return new java.sql.Time(seconds * 1000);
+            }
+            case Types.SQL_DATE : {
+                Calendar cal = session.getCalendar();
+                long millis = HsqlDateTime.convertMillisToCalendar(cal,
+                    ((TimestampData) a).getSeconds() * 1000);
+
+                // millis = HsqlDateTime.getNormalisedDate(cal, millis);
+                java.sql.Date value = new java.sql.Date(millis);
+
+                return value;
+            }
+            case Types.SQL_TIMESTAMP : {
+                Calendar cal = session.getCalendar();
+                long millis = HsqlDateTime.convertMillisToCalendar(cal,
+                    ((TimestampData) a).getSeconds() * 1000);
+                java.sql.Timestamp value = new java.sql.Timestamp(millis);
+
+                value.setNanos(((TimestampData) a).getNanos());
+
+                return value;
+            }
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                long seconds = ((TimestampData) a).getSeconds();
+                java.sql.Timestamp value = new java.sql.Timestamp(seconds
+                    * 1000);
+
+                value.setNanos(((TimestampData) a).getNanos());
+
+                return value;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public static int normaliseTime(int seconds) {
+
+        while (seconds < 0) {
+            seconds += 24 * 60 * 60;
+        }
+
+        if (seconds > 24 * 60 * 60) {
+            seconds %= 24 * 60 * 60;
+        }
+
+        return seconds;
+    }
+
+    public String convertToString(Object a) {
+
+        boolean      zone = false;
+        String       s;
+        StringBuffer sb;
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                return HsqlDateTime.getDateString(
+                    ((TimestampData) a).getSeconds());
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIME : {
+                TimeData t       = (TimeData) a;
+                int      seconds = normaliseTime(t.getSeconds() + t.getZone());
+
+                s = intervalSecondToString(seconds, t.getNanos(), false);
+
+                if (!withTimeZone) {
+                    return s;
+                }
+
+                sb = new StringBuffer(s);
+                s = Type.SQL_INTERVAL_HOUR_TO_MINUTE.intervalSecondToString(
+                    ((TimeData) a).getZone(), 0, true);
+
+                sb.append(s);
+
+                return sb.toString();
+            }
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP : {
+                TimestampData ts = (TimestampData) a;
+
+                sb = new StringBuffer();
+
+                HsqlDateTime.getTimestampString(sb,
+                                                ts.getSeconds()
+                                                + ts.getZone(), ts.getNanos(),
+                                                    scale);
+
+                if (!withTimeZone) {
+                    return sb.toString();
+                }
+
+                s = Type.SQL_INTERVAL_HOUR_TO_MINUTE.intervalSecondToString(
+                    ((TimestampData) a).getZone(), 0, true);
+
+                sb.append(s);
+
+                return sb.toString();
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        StringBuffer sb = new StringBuffer(32);
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                sb.append(Tokens.T_DATE);
+                break;
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIME :
+                sb.append(Tokens.T_TIME);
+                break;
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP :
+                sb.append(Tokens.T_TIMESTAMP);
+                break;
+        }
+
+        sb.append(StringConverter.toQuotedString(convertToString(a), '\'',
+                false));
+
+        return sb.toString();
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+
+        if (otherType.typeCode == Types.SQL_ALL_TYPES) {
+            return true;
+        }
+
+        if (otherType.isCharacterType()) {
+            return true;
+        }
+
+        if (!otherType.isDateTimeType()) {
+            return false;
+        }
+
+        if (otherType.typeCode == Types.SQL_DATE) {
+            return typeCode != Types.SQL_TIME;
+        } else if (otherType.typeCode == Types.SQL_TIME) {
+            return typeCode != Types.SQL_DATE;
+        }
+
+        return true;
+    }
+
+    public Object add(Object a, Object b, Type otherType) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            /** @todo -  range checks for units added */
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIME :
+                if (b instanceof IntervalMonthData) {
+                    throw Error.runtimeError(ErrorCode.U_S0500,
+                                             "DateTimeType");
+                } else if (b instanceof IntervalSecondData) {
+                    return addSeconds((TimeData) a,
+                                      (int) ((IntervalSecondData) b).units,
+                                      ((IntervalSecondData) b).nanos);
+                }
+                break;
+
+            case Types.SQL_DATE :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP :
+                if (b instanceof IntervalMonthData) {
+                    return addMonths((TimestampData) a,
+                                     (int) ((IntervalMonthData) b).units);
+                } else if (b instanceof IntervalSecondData) {
+                    return addSeconds((TimestampData) a,
+                                      (int) ((IntervalSecondData) b).units,
+                                      ((IntervalSecondData) b).nanos);
+                }
+                break;
+
+            default :
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+    }
+
+    public Object subtract(Object a, Object b, Type otherType) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIME :
+                if (b instanceof IntervalMonthData) {
+                    throw Error.runtimeError(ErrorCode.U_S0500,
+                                             "DateTimeType");
+                } else if (b instanceof IntervalSecondData) {
+                    return addSeconds((TimeData) a,
+                                      -(int) ((IntervalSecondData) b).units,
+                                      -((IntervalSecondData) b).nanos);
+                }
+                break;
+
+            case Types.SQL_DATE :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP :
+                if (b instanceof IntervalMonthData) {
+                    return addMonths((TimestampData) a,
+                                     -(int) ((IntervalMonthData) b).units);
+                } else if (b instanceof IntervalSecondData) {
+                    return addSeconds((TimestampData) a,
+                                      -(int) ((IntervalSecondData) b).units,
+                                      -((IntervalSecondData) b).nanos);
+                }
+                break;
+
+            default :
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+    }
+
+    public boolean equals(Object other) {
+
+        if (other instanceof Type) {
+            return super.equals(other)
+                   && ((DateTimeType) other).withTimeZone == withTimeZone;
+        }
+
+        return false;
+    }
+
+    public int getPart(Session session, Object dateTime, int part) {
+
+        int calendarPart;
+        int increment = 0;
+        int divisor   = 1;
+
+        switch (part) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                calendarPart = Calendar.YEAR;
+                break;
+
+            case Types.SQL_INTERVAL_MONTH :
+                increment    = 1;
+                calendarPart = Calendar.MONTH;
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+            case DAY_OF_MONTH :
+                calendarPart = Calendar.DAY_OF_MONTH;
+                break;
+
+            case Types.SQL_INTERVAL_HOUR :
+                calendarPart = Calendar.HOUR_OF_DAY;
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE :
+                calendarPart = Calendar.MINUTE;
+                break;
+
+            case Types.SQL_INTERVAL_SECOND :
+                calendarPart = Calendar.SECOND;
+                break;
+
+            case DAY_OF_WEEK :
+                calendarPart = Calendar.DAY_OF_WEEK;
+                break;
+
+            case WEEK_OF_YEAR :
+                calendarPart = Calendar.WEEK_OF_YEAR;
+                break;
+
+            case SECONDS_MIDNIGHT : {
+                if (typeCode == Types.SQL_TIME
+                        || typeCode == Types.SQL_TIME_WITH_TIME_ZONE) {}
+                else {
+                    try {
+                        Type target = withTimeZone
+                                      ? Type.SQL_TIME_WITH_TIME_ZONE
+                                      : Type.SQL_TIME;
+
+                        dateTime = target.castToType(session, dateTime, this);
+                    } catch (HsqlException e) {}
+                }
+
+                return ((TimeData) dateTime).getSeconds();
+            }
+            case TIMEZONE_HOUR :
+                if (typeCode == Types.SQL_TIMESTAMP_WITH_TIME_ZONE) {
+                    return ((TimestampData) dateTime).getZone() / 3600;
+                } else {
+                    return ((TimeData) dateTime).getZone() / 3600;
+                }
+            case TIMEZONE_MINUTE :
+                if (typeCode == Types.SQL_TIMESTAMP_WITH_TIME_ZONE) {
+                    return ((TimestampData) dateTime).getZone() / 60 % 60;
+                } else {
+                    return ((TimeData) dateTime).getZone() / 60 % 60;
+                }
+            case QUARTER :
+                increment    = 1;
+                divisor      = 3;
+                calendarPart = Calendar.MONTH;
+                break;
+
+            case DAY_OF_YEAR :
+                calendarPart = Calendar.DAY_OF_YEAR;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500,
+                                         "DateTimeType - " + part);
+        }
+
+        long millis;
+
+        if (typeCode == Types.SQL_TIME
+                || typeCode == Types.SQL_TIME_WITH_TIME_ZONE) {
+            millis =
+                (((TimeData) dateTime).getSeconds() + ((TimeData) dateTime)
+                    .getZone()) * 1000;
+        } else {
+            millis =
+                (((TimestampData) dateTime)
+                    .getSeconds() + ((TimestampData) dateTime).getZone()) * 1000;
+        }
+
+        return HsqlDateTime.getDateTimePart(millis, calendarPart) / divisor
+               + increment;
+    }
+
+    public BigDecimal getSecondPart(Object dateTime) {
+
+        long seconds = getPart(null, dateTime, Types.SQL_INTERVAL_SECOND);
+        int  nanos   = 0;
+
+        if (typeCode == Types.SQL_TIMESTAMP) {
+            nanos = ((TimestampData) dateTime).getNanos();
+        } else if (typeCode == Types.SQL_TIME) {
+            nanos = ((TimeData) dateTime).getNanos();
+        }
+
+        return getSecondPart(seconds, nanos);
+    }
+
+    public String getPartString(Session session, Object dateTime, int part) {
+
+        String javaPattern = "";
+
+        switch (part) {
+
+            case DAY_NAME :
+                javaPattern = "EEEE";
+                break;
+
+            case MONTH_NAME :
+                javaPattern = "MMMM";
+                break;
+        }
+
+        SimpleDateFormat format = session.getSimpleDateFormatGMT();
+
+        try {
+            format.applyPattern(javaPattern);
+        } catch (Exception e) {}
+
+        Date date = (Date) convertSQLToJavaGMT(session, dateTime);
+
+        return format.format(date);
+    }
+
+    public Object getValue(long seconds, int nanos, int zoneSeconds) {
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                seconds =
+                    HsqlDateTime.getNormalisedDate(
+                        (seconds + zoneSeconds) * 1000) / 1000;
+
+                return new TimestampData(seconds);
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                seconds = HsqlDateTime.getNormalisedDate(seconds * 1000)
+                          / 1000;
+
+                return new TimeData((int) seconds, nanos, zoneSeconds);
+
+            case Types.SQL_TIME :
+                seconds =
+                    HsqlDateTime.getNormalisedTime(
+                        (seconds + zoneSeconds) * 1000) / 1000;
+
+                return new TimeData((int) seconds, nanos);
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return new TimestampData(seconds, nanos, zoneSeconds);
+
+            case Types.SQL_TIMESTAMP :
+                return new TimestampData(seconds + zoneSeconds, nanos);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public DateTimeType getDateTimeTypeWithoutZone() {
+
+        if (this.withTimeZone) {
+            switch (typeCode) {
+
+                case Types.SQL_TIME_WITH_TIME_ZONE :
+                    if (scale != DTIType.defaultTimeFractionPrecision) {
+                        return new DateTimeType(Types.SQL_TIME,
+                                                Types.SQL_TIME, scale);
+                    }
+
+                    return SQL_TIME;
+
+                case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                    if (scale != DTIType.defaultTimestampFractionPrecision) {
+                        return new DateTimeType(Types.SQL_TIMESTAMP,
+                                                Types.SQL_TIMESTAMP, scale);
+                    }
+
+                    return SQL_TIMESTAMP;
+
+                default :
+                    throw Error.runtimeError(ErrorCode.U_S0500,
+                                             "DateTimeType");
+            }
+        }
+
+        return this;
+    }
+
+    public static DateTimeType getDateTimeType(int type, int scale) {
+
+        if (scale > DTIType.maxFractionPrecision) {
+            throw Error.error(ErrorCode.X_42592);
+        }
+
+        switch (type) {
+
+            case Types.SQL_DATE :
+                return SQL_DATE;
+
+            case Types.SQL_TIME :
+                if (scale != DTIType.defaultTimeFractionPrecision) {
+                    return new DateTimeType(Types.SQL_TIME, type, scale);
+                }
+
+                return SQL_TIME;
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                if (scale != DTIType.defaultTimeFractionPrecision) {
+                    return new DateTimeType(Types.SQL_TIME, type, scale);
+                }
+
+                return SQL_TIME_WITH_TIME_ZONE;
+
+            case Types.SQL_TIMESTAMP :
+                if (scale != DTIType.defaultTimestampFractionPrecision) {
+                    return new DateTimeType(Types.SQL_TIMESTAMP, type, scale);
+                }
+
+                return SQL_TIMESTAMP;
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                if (scale != DTIType.defaultTimestampFractionPrecision) {
+                    return new DateTimeType(Types.SQL_TIMESTAMP, type, scale);
+                }
+
+                return SQL_TIMESTAMP_WITH_TIME_ZONE;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "DateTimeType");
+        }
+    }
+
+    public Object changeZone(Object a, Type otherType, int targetZone,
+                             int localZone) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (otherType.typeCode == Types.SQL_TIMESTAMP_WITH_TIME_ZONE
+                || otherType.typeCode == Types.SQL_TIME_WITH_TIME_ZONE) {
+            localZone = 0;
+        }
+
+        if (targetZone > DTIType.timezoneSecondsLimit
+                || -targetZone > DTIType.timezoneSecondsLimit) {
+            throw Error.error(ErrorCode.X_22009);
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_TIME_WITH_TIME_ZONE : {
+                TimeData value = (TimeData) a;
+
+                if (localZone != 0 || value.zone != targetZone) {
+                    return new TimeData(value.getSeconds() - localZone,
+                                        value.getNanos(), targetZone);
+                }
+
+                break;
+            }
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : {
+                TimestampData value = (TimestampData) a;
+
+                if (localZone != 0 || value.zone != targetZone) {
+                    return new TimestampData(value.getSeconds() - localZone,
+                                             value.getNanos(), targetZone);
+                }
+
+                break;
+            }
+        }
+
+        return a;
+    }
+
+    public boolean canAdd(IntervalType other) {
+        return other.startPartIndex >= startPartIndex
+               && other.endPartIndex <= endPartIndex;
+    }
+
+    public int getSqlDateTimeSub() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DATE :
+                return 1;
+
+            case Types.SQL_TIME :
+                return 2;
+
+            case Types.SQL_TIMESTAMP :
+                return 3;
+
+            default :
+                return 0;
+        }
+    }
+
+    public static Boolean overlaps(Session session, Object[] a, Type[] ta,
+                                   Object[] b, Type[] tb) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        if (a[0] == null || b[0] == null) {
+            return null;
+        }
+
+        if (a[1] == null) {
+            a[1] = a[0];
+        }
+
+        if (b[1] == null) {
+            b[1] = b[0];
+        }
+
+        Type commonType = ta[0].getCombinedType(tb[0], OpTypes.EQUAL);
+
+        a[0] = commonType.castToType(session, a[0], ta[0]);
+        b[0] = commonType.castToType(session, b[0], tb[0]);
+
+        if (ta[1].isIntervalType()) {
+            a[1] = commonType.add(a[0], a[1], ta[1]);
+        } else {
+            a[1] = commonType.castToType(session, a[1], ta[1]);
+        }
+
+        if (tb[1].isIntervalType()) {
+            b[1] = commonType.add(b[0], b[1], tb[1]);
+        } else {
+            b[1] = commonType.castToType(session, b[1], tb[1]);
+        }
+
+        if (commonType.compare(session, a[0], a[1]) > 0) {
+            Object temp = a[0];
+
+            a[0] = a[1];
+            a[1] = temp;
+        }
+
+        if (commonType.compare(session, b[0], b[1]) > 0) {
+            Object temp = b[0];
+
+            b[0] = b[1];
+            b[1] = temp;
+        }
+
+        if (commonType.compare(session, a[0], b[0]) > 0) {
+            Object[] temp = a;
+
+            a = b;
+            b = temp;
+        }
+
+        if (commonType.compare(session, a[1], b[0]) > 0) {
+            return Boolean.TRUE;
+        }
+
+        return Boolean.FALSE;
+    }
+
+    //
+    public static int subtractMonths(TimestampData a, TimestampData b,
+                                     boolean isYear) {
+
+        synchronized (HsqlDateTime.tempCalGMT) {
+            boolean negate = false;
+
+            if (b.getSeconds() > a.getSeconds()) {
+                negate = true;
+
+                TimestampData temp = a;
+
+                a = b;
+                b = temp;
+            }
+
+            HsqlDateTime.setTimeInMillis(HsqlDateTime.tempCalGMT,
+                                         a.getSeconds() * 1000);
+
+            int months = HsqlDateTime.tempCalGMT.get(Calendar.MONTH);
+            int years  = HsqlDateTime.tempCalGMT.get(Calendar.YEAR);
+
+            HsqlDateTime.setTimeInMillis(HsqlDateTime.tempCalGMT,
+                                         b.getSeconds() * 1000);
+
+            months -= HsqlDateTime.tempCalGMT.get(Calendar.MONTH);
+            years  -= HsqlDateTime.tempCalGMT.get(Calendar.YEAR);
+
+            if (isYear) {
+                months = years * 12;
+            } else {
+                if (months < 0) {
+                    months += 12;
+
+                    years--;
+                }
+
+                months += years * 12;
+
+                if (negate) {
+                    months = -months;
+                }
+            }
+
+            return months;
+        }
+    }
+
+    /** @todo - overflow */
+    public static TimeData addSeconds(TimeData source, int seconds,
+                                      int nanos) {
+
+        nanos   += source.getNanos();
+        seconds += nanos / limitNanoseconds;
+        nanos   %= limitNanoseconds;
+
+        if (nanos < 0) {
+            nanos += DTIType.limitNanoseconds;
+
+            seconds--;
+        }
+
+        seconds += source.getSeconds();
+        seconds %= (24 * 60 * 60);
+
+        TimeData ti = new TimeData(seconds, nanos, source.getZone());
+
+        return ti;
+    }
+
+    /** @todo - overflow */
+    public static TimestampData addMonths(TimestampData source, int months) {
+
+        int n = source.getNanos();
+
+        synchronized (HsqlDateTime.tempCalGMT) {
+            HsqlDateTime.setTimeInMillis(HsqlDateTime.tempCalGMT,
+                                         source.getSeconds() * 1000);
+            HsqlDateTime.tempCalGMT.add(Calendar.MONTH, months);
+
+            TimestampData ts =
+                new TimestampData(HsqlDateTime.tempCalGMT.getTimeInMillis()
+                                  / 1000, n, source.getZone());
+
+            return ts;
+        }
+    }
+
+    /** @todo - overflow */
+    public static TimestampData addSeconds(TimestampData source, int seconds,
+                                           int nanos) {
+
+        nanos   += source.getNanos();
+        seconds += nanos / limitNanoseconds;
+        nanos   %= limitNanoseconds;
+
+        if (nanos < 0) {
+            nanos += limitNanoseconds;
+
+            seconds--;
+        }
+
+        long newSeconds = source.getSeconds() + seconds;
+        TimestampData ts = new TimestampData(newSeconds, nanos,
+                                             source.getZone());
+
+        return ts;
+    }
+}
diff --git a/src/org/hsqldb/types/IntervalMonthData.java b/src/org/hsqldb/types/IntervalMonthData.java
new file mode 100644
index 0000000..1ef5b1d
--- /dev/null
+++ b/src/org/hsqldb/types/IntervalMonthData.java
@@ -0,0 +1,103 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * Implementation of data item for INTERVAL MONTH.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class IntervalMonthData {
+
+    public final long units;
+
+    public static IntervalMonthData newIntervalYear(long years,
+            IntervalType type) {
+        return new IntervalMonthData(years * 12, type);
+    }
+
+    public static IntervalMonthData newIntervalMonth(long months,
+            IntervalType type) {
+        return new IntervalMonthData(months, type);
+    }
+
+    public IntervalMonthData(long months, IntervalType type) {
+
+        if (months >= type.getIntervalValueLimit()) {
+            throw Error.error(ErrorCode.X_22006);
+        }
+
+        if (type.typeCode == Types.SQL_INTERVAL_YEAR) {
+            months -= (months % 12);
+        }
+
+        this.units = months;
+    }
+
+    public IntervalMonthData(long months) {
+        this.units = months;
+    }
+
+    public boolean equals(Object other) {
+
+        if (other instanceof IntervalMonthData) {
+            return units == ((IntervalMonthData) other).units;
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+        return (int) units;
+    }
+
+    public int compareTo(IntervalMonthData b) {
+
+        long diff = units - b.units;
+
+        if (diff == 0) {
+            return 0;
+        } else {
+            return diff > 0 ? 1
+                            : -1;
+        }
+    }
+
+    public String toString() {
+        return Type.SQL_INTERVAL_MONTH_MAX_PRECISION.convertToString(this);
+    }
+}
diff --git a/src/org/hsqldb/types/IntervalSecondData.java b/src/org/hsqldb/types/IntervalSecondData.java
new file mode 100644
index 0000000..d7e5b17
--- /dev/null
+++ b/src/org/hsqldb/types/IntervalSecondData.java
@@ -0,0 +1,171 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * Implementation of data item for INTERVAL SECOND.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class IntervalSecondData {
+
+    public final long units;
+    public final int  nanos;
+
+    public static IntervalSecondData newIntervalDay(long days,
+            IntervalType type) {
+        return new IntervalSecondData(days * 24 * 60 * 60, 0, type);
+    }
+
+    public static IntervalSecondData newIntervalHour(long hours,
+            IntervalType type) {
+        return new IntervalSecondData(hours * 60 * 60, 0, type);
+    }
+
+    public static IntervalSecondData newIntervalMinute(long minutes,
+            IntervalType type) {
+        return new IntervalSecondData(minutes * 60, 0, type);
+    }
+
+    public static IntervalSecondData newIntervalSeconds(long seconds,
+            IntervalType type) {
+        return new IntervalSecondData(seconds, 0, type);
+    }
+
+    public IntervalSecondData(long seconds, int nanos, IntervalType type) {
+
+        if (seconds >= type.getIntervalValueLimit()) {
+            throw Error.error(ErrorCode.X_22015);
+        }
+
+        this.units = seconds;
+        this.nanos = nanos;
+    }
+
+    public IntervalSecondData(long seconds, int nanos) {
+        this.units = seconds;
+        this.nanos = nanos;
+    }
+
+    /**
+     * normalise is a marker, values are always normalised
+     */
+    public IntervalSecondData(long seconds, long nanos, IntervalType type,
+                              boolean normalise) {
+
+        if (nanos >= DTIType.limitNanoseconds) {
+            long carry = nanos / DTIType.limitNanoseconds;
+
+            nanos   = nanos % DTIType.limitNanoseconds;
+            seconds += carry;
+        } else if (nanos <= -DTIType.limitNanoseconds) {
+            long carry = -nanos / DTIType.limitNanoseconds;
+
+            nanos   = -(-nanos % DTIType.limitNanoseconds);
+            seconds -= carry;
+        }
+
+        int scaleFactor = DTIType.nanoScaleFactors[type.scale];
+
+        nanos /= scaleFactor;
+        nanos *= scaleFactor;
+
+        if (seconds > 0 && nanos < 0) {
+            nanos += DTIType.limitNanoseconds;
+
+            seconds--;
+        } else if (seconds < 0 && nanos > 0) {
+            nanos -= DTIType.limitNanoseconds;
+
+            seconds++;
+        }
+
+        scaleFactor = DTIType.yearToSecondFactors[type.endPartIndex];
+        seconds     /= scaleFactor;
+        seconds     *= scaleFactor;
+
+        if (seconds >= type.getIntervalValueLimit()) {
+            throw Error.error(ErrorCode.X_22015);
+        }
+
+        this.units = seconds;
+        this.nanos = (int) nanos;
+    }
+
+    public boolean equals(Object other) {
+
+        if (other instanceof IntervalSecondData) {
+            return units == ((IntervalSecondData) other).units
+                   && nanos == ((IntervalSecondData) other).nanos;
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+        return (int) units ^ nanos;
+    }
+
+    public int compareTo(IntervalSecondData b) {
+
+        long diff = units - b.units;
+
+        if (diff == 0) {
+            diff = nanos - b.nanos;
+
+            if (diff == 0) {
+                return 0;
+            }
+        }
+
+        return diff > 0 ? 1
+                        : -1;
+    }
+
+    public long getSeconds() {
+        return units;
+    }
+
+    public int getNanos() {
+        return nanos;
+    }
+
+    public String toString() {
+        return Type.SQL_INTERVAL_SECOND_MAX_FRACTION_MAX_PRECISION
+            .convertToString(this);
+    }
+}
diff --git a/src/org/hsqldb/types/IntervalType.java b/src/org/hsqldb/types/IntervalType.java
new file mode 100644
index 0000000..6ff7a9c
--- /dev/null
+++ b/src/org/hsqldb/types/IntervalType.java
@@ -0,0 +1,1500 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.math.BigDecimal;
+
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * Type subclass for various typs of INTERVAL.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class IntervalType extends DTIType {
+
+    public final boolean defaultPrecision;
+    public final boolean isYearMonth;
+
+    private IntervalType(int typeGroup, int type, long precision, int scale,
+                         int startIntervalType, int endIntervalType,
+                         boolean defaultPrecision) {
+
+        super(typeGroup, type, precision, scale, startIntervalType,
+              endIntervalType);
+
+        switch (startIntervalType) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_MONTH :
+                isYearMonth = true;
+                break;
+
+            default :
+                isYearMonth = false;
+                break;
+        }
+
+        this.defaultPrecision = defaultPrecision;
+    }
+
+    public int displaySize() {
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                return (int) precision + 1;
+
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+                return (int) precision + 4;
+
+            case Types.SQL_INTERVAL_MONTH :
+                return (int) precision + 1;
+
+            case Types.SQL_INTERVAL_DAY :
+                return (int) precision + 1;
+
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+                return (int) precision + 4;
+
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+                return (int) precision + 7;
+
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+                return (int) precision + 10 + (scale == 0 ? 0
+                                                          : scale + 1);
+
+            case Types.SQL_INTERVAL_HOUR :
+                return (int) precision + 1;
+
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+                return (int) precision + 4;
+
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+                return (int) precision + 7 + (scale == 0 ? 0
+                                                         : scale + 1);
+
+            case Types.SQL_INTERVAL_MINUTE :
+                return (int) precision + 1;
+
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+                return (int) precision + 4 + (scale == 0 ? 0
+                                                         : scale + 1);
+
+            case Types.SQL_INTERVAL_SECOND :
+                return (int) precision + 1 + (scale == 0 ? 0
+                                                         : scale + 1);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public int getJDBCTypeCode() {
+
+        // no JDBC number is available
+        return typeCode;
+    }
+
+    public Class getJDBCClass() {
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                return IntervalMonthData.class;
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                return org.hsqldb.types.IntervalSecondData.class;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public String getJDBCClassName() {
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                return IntervalMonthData.class.getName();
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                return org.hsqldb.types.IntervalSecondData.class.getName();
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public int getJDBCPrecision() {
+        return this.displaySize();
+    }
+
+    public int getSQLGenericTypeCode() {
+        return Types.SQL_INTERVAL;
+    }
+
+    public String getNameString() {
+        return "INTERVAL " + getQualifier(typeCode);
+    }
+
+    public static String getQualifier(int type) {
+
+        switch (type) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                return "YEAR";
+
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+                return "YEAR TO MONTH";
+
+            case Types.SQL_INTERVAL_MONTH :
+                return "MONTH";
+
+            case Types.SQL_INTERVAL_DAY :
+                return "DAY";
+
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+                return "DAY TO HOUR";
+
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+                return "DAY TO MINUTE";
+
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+                return "DAY TO SECOND";
+
+            case Types.SQL_INTERVAL_HOUR :
+                return "HOUR";
+
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+                return "HOUR TO MINUTE";
+
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+                return "HOUR TO SECOND";
+
+            case Types.SQL_INTERVAL_MINUTE :
+                return "MINUTE";
+
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+                return "MINUTE TO SECOND";
+
+            case Types.SQL_INTERVAL_SECOND :
+                return "SECOND";
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public String getDefinition() {
+
+        if (precision == defaultIntervalPrecision
+                && (endIntervalType != Types.SQL_INTERVAL_SECOND
+                    || scale == defaultIntervalFractionPrecision)) {
+            return getNameString();
+        }
+
+        StringBuffer sb = new StringBuffer(32);
+
+        sb.append(Tokens.T_INTERVAL).append(' ');
+        sb.append(getQualifier(startIntervalType));
+
+        if (typeCode == Types.SQL_INTERVAL_SECOND) {
+            sb.append('(');
+            sb.append(precision);
+
+            if (scale != defaultIntervalFractionPrecision) {
+                sb.append(',');
+                sb.append(scale);
+            }
+
+            sb.append(')');
+
+            return sb.toString();
+        }
+
+        if (precision != defaultIntervalPrecision) {
+            sb.append('(');
+            sb.append(precision);
+            sb.append(')');
+        }
+
+        if (startIntervalType != endIntervalType) {
+            sb.append(' ');
+            sb.append(Tokens.T_TO);
+            sb.append(' ');
+            sb.append(Tokens.SQL_INTERVAL_FIELD_NAMES[endPartIndex]);
+
+            if (endIntervalType == Types.SQL_INTERVAL_SECOND
+                    && scale != defaultIntervalFractionPrecision) {
+                sb.append('(');
+                sb.append(scale);
+                sb.append(')');
+            }
+        }
+
+        return sb.toString();
+    }
+
+    public boolean isIntervalType() {
+        return true;
+    }
+
+    public boolean isYearMonthIntervalType() {
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    public boolean isDaySecondIntervalType() {
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    public boolean acceptsPrecision() {
+        return true;
+    }
+
+    public boolean acceptsFractionalPrecision() {
+        return endIntervalType == Types.SQL_INTERVAL_SECOND;
+    }
+
+    public Type getAggregateType(Type other) {
+
+        if (typeCode == other.typeCode) {
+            if (precision >= other.precision && scale >= other.scale) {
+                return this;
+            } else if (precision <= other.precision && scale <= other.scale) {
+                return other;
+            }
+        }
+
+        if (other == SQL_ALL_TYPES) {
+            return this;
+        }
+
+        if (other.isCharacterType()) {
+            return other.getAggregateType(this);
+        }
+
+        if (!other.isIntervalType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        int startType = ((IntervalType) other).startIntervalType
+                        > startIntervalType ? startIntervalType
+                                            : ((IntervalType) other)
+                                                .startIntervalType;
+        int endType = ((IntervalType) other).endIntervalType > endIntervalType
+                      ? ((IntervalType) other).endIntervalType
+                      : endIntervalType;
+        int  newType      = getCombinedIntervalType(startType, endType);
+        long newPrecision = precision > other.precision ? precision
+                                                        : other.precision;
+        int  newScale     = scale > other.scale ? scale
+                                                : other.scale;
+
+        try {
+            return getIntervalType(newType, startType, endType, newPrecision,
+                                   newScale, false);
+        } catch (RuntimeException e) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+    }
+
+    public Type getCombinedType(Type other, int operation) {
+
+        switch (operation) {
+
+            case OpTypes.MULTIPLY :
+                if (other.isNumberType()) {
+                    return getIntervalType(this, maxIntervalPrecision, scale);
+                }
+                break;
+
+            case OpTypes.DIVIDE :
+                if (other.isNumberType()) {
+                    return this;
+                }
+                break;
+
+            case OpTypes.ADD :
+                if (other.isDateTimeType()) {
+                    return other.getCombinedType(this, operation);
+                } else if (other.isIntervalType()) {
+                    IntervalType newType =
+                        (IntervalType) getAggregateType(other);
+
+                    return getIntervalType(newType, maxIntervalPrecision, 0);
+                }
+                break;
+
+            case OpTypes.SUBTRACT :
+            default :
+                return getAggregateType(other);
+        }
+
+        throw Error.error(ErrorCode.X_42562);
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                return ((IntervalMonthData) a).compareTo(
+                    (IntervalMonthData) b);
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                return ((IntervalSecondData) a).compareTo(
+                    (IntervalSecondData) b);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (a instanceof IntervalMonthData) {
+            IntervalMonthData im = (IntervalMonthData) a;
+
+            if (im.units > getIntervalValueLimit()) {
+                throw Error.error(ErrorCode.X_22015);
+            }
+        } else if (a instanceof IntervalSecondData) {
+            IntervalSecondData is = (IntervalSecondData) a;
+
+            if (is.units > getIntervalValueLimit()) {
+                throw Error.error(ErrorCode.X_22015);
+            }
+
+//            int divisor = nanoScaleFactors[scale];
+//            is.nanos = (is.nanos / divisor) * divisor;
+        }
+
+        return a;
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (otherType.typeCode) {
+
+            case Types.SQL_CLOB :
+                a = a.toString();
+
+            // fall through
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE : {
+                return session.getScanner().convertToDatetimeInterval(session,
+                        (String) a, this);
+            }
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                if (a instanceof BigDecimal) {
+                    if (!NumberType.isInLongLimits((BigDecimal) a)) {
+                        throw Error.error(ErrorCode.X_22015);
+                    }
+                }
+
+                long value = ((Number) a).longValue();
+
+                switch (this.endIntervalType) {
+
+                    case Types.SQL_INTERVAL_YEAR :
+                        return IntervalMonthData.newIntervalYear(value, this);
+
+                    case Types.SQL_INTERVAL_MONTH :
+                        return IntervalMonthData.newIntervalMonth(value, this);
+
+                    case Types.SQL_INTERVAL_DAY :
+                        return IntervalSecondData.newIntervalDay(value, this);
+
+                    case Types.SQL_INTERVAL_HOUR :
+                        return IntervalSecondData.newIntervalHour(value, this);
+
+                    case Types.SQL_INTERVAL_MINUTE :
+                        return IntervalSecondData.newIntervalMinute(value,
+                                this);
+
+                    case Types.SQL_INTERVAL_SECOND : {
+                        int nanos = 0;
+
+                        if (scale > 0 && a instanceof BigDecimal) {
+                            nanos = (int) NumberType.scaledDecimal(
+                                a, DTIType.maxFractionPrecision);
+                        }
+
+                        return new IntervalSecondData(value, nanos, this);
+                    }
+                    default :
+                        throw Error.error(ErrorCode.X_42561);
+                }
+            }
+            case Types.SQL_INTERVAL_YEAR : {
+                long months = (((IntervalMonthData) a).units / 12) * 12;
+
+                return new IntervalMonthData(months, this);
+            }
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH : {
+                long months = ((IntervalMonthData) a).units;
+
+                return new IntervalMonthData(months, this);
+            }
+            case Types.SQL_INTERVAL_DAY : {
+                long seconds = ((IntervalSecondData) a).units;
+
+                seconds = (seconds / DTIType.yearToSecondFactors[2])
+                          * DTIType.yearToSecondFactors[2];
+
+                return new IntervalSecondData(seconds, 0, this);
+            }
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE : {
+                long seconds = ((IntervalSecondData) a).units;
+
+                seconds = (seconds / DTIType.yearToSecondFactors[endPartIndex])
+                          * DTIType.yearToSecondFactors[endPartIndex];
+
+                return new IntervalSecondData(seconds, 0, this);
+            }
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND : {
+                long seconds = ((IntervalSecondData) a).units;
+                int  nanos   = ((IntervalSecondData) a).nanos;
+
+                if (scale == 0) {
+                    nanos = 0;
+                } else {
+                    nanos = (nanos / (DTIType.nanoScaleFactors[scale]))
+                            * (DTIType.nanoScaleFactors[scale]);
+                }
+
+                return new IntervalSecondData(seconds, nanos, this);
+            }
+            default :
+                throw Error.error(ErrorCode.X_42561);
+        }
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (a instanceof String) {
+            return convertToType(null, a, Type.SQL_VARCHAR);
+        } else {
+            throw Error.error(ErrorCode.X_42561);
+        }
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                return intervalMonthToString(a);
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                return intervalSecondToString(a);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        StringBuffer sb = new StringBuffer(32);
+
+        sb.append(Tokens.T_INTERVAL).append(' ');
+        sb.append('\'').append(convertToString(a)).append('\'').append(' ');
+        sb.append(Tokens.SQL_INTERVAL_FIELD_NAMES[startPartIndex]);
+        sb.append(' ');
+        sb.append(Tokens.T_TO);
+        sb.append(' ');
+        sb.append(Tokens.SQL_INTERVAL_FIELD_NAMES[endPartIndex]);
+
+        return sb.toString();
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+
+        if (otherType.typeCode == Types.SQL_ALL_TYPES) {
+            return true;
+        }
+
+        if (otherType.isCharacterType()) {
+            return true;
+        }
+
+        if (otherType.isNumberType()) {
+            return true;
+        }
+
+        if (!otherType.isIntervalType()) {
+            return false;
+        }
+
+        return !(isYearMonthIntervalType()
+                 ^ ((IntervalType) otherType).isYearMonthIntervalType());
+    }
+
+    public int compareToTypeRange(Object o) {
+
+        long max = precisionLimits[(int) precision];
+        long units;
+
+        if (o instanceof IntervalMonthData) {
+            units = ((IntervalMonthData) o).units;
+        } else if (o instanceof IntervalSecondData) {
+            units = ((IntervalSecondData) o).units;
+        } else {
+            return 0;
+        }
+
+        if (units >= max) {
+            return 1;
+        }
+
+        if (units < 0) {
+            if (-units >= max) {
+                return -1;
+            }
+        }
+
+        return 0;
+    }
+
+    public Object absolute(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (a instanceof IntervalMonthData) {
+            if (((IntervalMonthData) a).units < 0) {
+                return negate(a);
+            }
+        } else {
+            if (((IntervalSecondData) a).units < 0
+                    || ((IntervalSecondData) a).nanos < 0) {
+                return negate(a);
+            }
+        }
+
+        return a;
+    }
+
+    public Object negate(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (a instanceof IntervalMonthData) {
+            long units = ((IntervalMonthData) a).units;
+
+            return new IntervalMonthData(-units, this);
+        } else {
+            long units = ((IntervalSecondData) a).units;
+            int  nanos = ((IntervalSecondData) a).nanos;
+
+            return new IntervalSecondData(-units, -nanos, this, true);
+        }
+    }
+
+    public Object add(Object a, Object b, Type otherType) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                long months = ((IntervalMonthData) a).units
+                              + ((IntervalMonthData) b).units;
+
+                return new IntervalMonthData(months, this);
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                long seconds = ((IntervalSecondData) a).units
+                               + ((IntervalSecondData) b).units;
+                long nanos = ((IntervalSecondData) a).nanos
+                             + ((IntervalSecondData) b).nanos;
+
+                return new IntervalSecondData(seconds, nanos, this, true);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public Object subtract(Object a, Object b, Type otherType) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+                if (a instanceof IntervalMonthData
+                        && b instanceof IntervalMonthData) {
+                    long months = ((IntervalMonthData) a).units
+                                  - ((IntervalMonthData) b).units;
+
+                    return new IntervalMonthData(months, this);
+                } else if (a instanceof TimestampData
+                           && b instanceof TimestampData) {
+                    boolean isYear = typeCode == Types.SQL_INTERVAL_YEAR;
+                    long months =
+                        DateTimeType.subtractMonths((TimestampData) a,
+                                                    (TimestampData) b, isYear);
+
+                    return new IntervalMonthData(months, this);
+                }
+
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                if (a instanceof IntervalSecondData
+                        && b instanceof IntervalSecondData) {
+                    long seconds = ((IntervalSecondData) a).units
+                                   - ((IntervalSecondData) b).units;
+                    long nanos = ((IntervalSecondData) a).nanos
+                                 - ((IntervalSecondData) b).nanos;
+
+                    return new IntervalSecondData(seconds, nanos, this, true);
+                } else if (a instanceof TimeData && b instanceof TimeData) {
+                    long seconds = ((TimeData) a).getSeconds()
+                                   - ((TimeData) b).getSeconds();
+                    long nanos = ((TimeData) a).getNanos()
+                                 - ((TimeData) b).getNanos();
+
+                    return new IntervalSecondData(seconds, nanos, this, true);
+                } else if (a instanceof TimestampData
+                           && b instanceof TimestampData) {
+                    long seconds = (((TimestampData) a).getSeconds()
+                                    - ((TimestampData) b).getSeconds());
+                    long nanos = ((TimestampData) a).getNanos()
+                                 - ((TimestampData) b).getNanos();
+
+                    return new IntervalSecondData(seconds, nanos, this, true);
+                }
+
+            // fall through
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public Object multiply(Object a, Object b) {
+        return multiplyOrDivide(a, b, false);
+    }
+
+    public Object divide(Object a, Object b) {
+        return multiplyOrDivide(a, b, true);
+    }
+
+    private Object multiplyOrDivide(Object a, Object b, boolean divide) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        if (a instanceof Number) {
+            Object temp = a;
+
+            a = b;
+            b = temp;
+        }
+
+        if (divide && NumberType.isZero(b)) {
+            throw Error.error(ErrorCode.X_22012);
+        }
+
+        NumberType factorType = NumberType.getNumberType(Types.SQL_DECIMAL,
+            40, maxFractionPrecision);
+        BigDecimal factor = (BigDecimal) factorType.convertToDefaultType(null,
+            b);
+        BigDecimal units;
+
+        if (isYearMonth) {
+            units = BigDecimal.valueOf(((IntervalMonthData) a).units);
+        } else {
+            long value =
+                ((IntervalSecondData) a).units * DTIType.nanoScaleFactors[0]
+                + ((IntervalSecondData) a).nanos;
+
+            units = BigDecimal.valueOf(value, 9);
+        }
+
+        BigDecimal result = divide
+                            ? (BigDecimal) factorType.divide(units, factor)
+                            : (BigDecimal) factorType.multiply(units, factor);
+
+        if (!NumberType.isInLongLimits(result)) {
+            throw Error.error(ErrorCode.X_22015);
+        }
+
+        if (isYearMonth) {
+            return new IntervalMonthData(result.longValue(), this);
+        }
+
+        int nanos = (int) NumberType.scaledDecimal(result,
+            DTIType.maxFractionPrecision);
+
+        return new IntervalSecondData(result.longValue(), nanos, this, true);
+    }
+
+    String intervalMonthToString(Object a) {
+
+        StringBuffer sb     = new StringBuffer(8);
+        long         months = ((IntervalMonthData) a).units;
+
+        if (months < 0) {
+            months = -months;
+
+            sb.append('-');
+        }
+
+        for (int i = startPartIndex; i <= endPartIndex; i++) {
+            int  factor = DTIType.yearToSecondFactors[i];
+            long part   = months / factor;
+
+            if (i == startPartIndex) {
+                int zeros = (int) precision - getPrecisionExponent(part);
+/*
+                for (int j = 0; j < zeros; j++) {
+                    buffer.append('0');
+                }
+*/
+            } else if (part < 10) {
+                sb.append('0');
+            }
+
+            sb.append(part);
+
+            months %= factor;
+
+            if (i < endPartIndex) {
+                sb.append((char) DTIType.yearToSecondSeparators[i]);
+            }
+        }
+
+        return sb.toString();
+    }
+
+    String intervalSecondToString(Object a) {
+
+        long seconds = ((IntervalSecondData) a).units;
+        int  nanos   = ((IntervalSecondData) a).nanos;
+
+        return intervalSecondToString(seconds, nanos, false);
+    }
+
+    public int precedenceDegree(Type other) {
+
+        if (other.isIntervalType()) {
+            int otherIndex = ((IntervalType) other).endPartIndex;
+
+            return otherIndex - endPartIndex;
+        }
+
+        return Integer.MIN_VALUE;
+    }
+
+    public int getStartIntervalType() {
+        return startIntervalType;
+    }
+
+    public int getEndIntervalType() {
+        return endIntervalType;
+    }
+
+    public static IntervalType newIntervalType(int type, long precision,
+            int fractionPrecision) {
+
+        int startType = getStartIntervalType(type);
+        int endType   = getEndIntervalType(type);
+        int group = startType > Types.SQL_INTERVAL_MONTH
+                    ? Types.SQL_INTERVAL_SECOND
+                    : Types.SQL_INTERVAL_MONTH;
+
+        return new IntervalType(group, type, precision, fractionPrecision,
+                                startType, endType, false);
+    }
+
+    public static IntervalType getIntervalType(IntervalType type,
+            long precision, int fractionalPrecision) {
+
+        if (type.precision >= precision && type.scale >= fractionalPrecision) {
+            return type;
+        }
+
+        return getIntervalType(type.typeCode, precision, fractionalPrecision);
+    }
+
+    public static IntervalType getIntervalType(int type, long precision,
+            int fractionPrecision) {
+
+        int startType = getStartIntervalType(type);
+        int endType   = getEndIntervalType(type);
+
+        return getIntervalType(type, startType, endType, precision,
+                               fractionPrecision, false);
+    }
+
+    public static IntervalType getIntervalType(int startIndex, int endIndex,
+            long precision, int fractionPrecision) {
+
+        boolean defaultPrecision = precision == -1;
+
+        if (startIndex == -1 || endIndex == -1) {
+            throw Error.error(ErrorCode.X_22006);
+        }
+
+        if (startIndex > endIndex) {
+            throw Error.error(ErrorCode.X_22006);
+        }
+
+        if (startIndex <= DTIType.INTERVAL_MONTH_INDEX
+                && endIndex > DTIType.INTERVAL_MONTH_INDEX) {
+            throw Error.error(ErrorCode.X_22006);
+        }
+
+        int startType = DTIType.intervalParts[startIndex];
+        int endType   = DTIType.intervalParts[endIndex];
+        int type      = DTIType.intervalTypes[startIndex][endIndex];
+
+        if (precision == 0 || precision > DTIType.maxIntervalPrecision
+                || fractionPrecision > DTIType.maxFractionPrecision) {
+            throw Error.error(ErrorCode.X_42592);
+        }
+
+        if (precision == -1) {
+            precision = DTIType.defaultIntervalPrecision;
+        }
+
+        if (fractionPrecision == -1) {
+            fractionPrecision = endType == Types.SQL_INTERVAL_SECOND
+                                ? DTIType.defaultIntervalFractionPrecision
+                                : 0;
+        }
+
+        return getIntervalType(type, startType, endType, precision,
+                               fractionPrecision, defaultPrecision);
+    }
+
+    public static IntervalType getIntervalType(int type, int startType,
+            int endType, long precision, int fractionPrecision,
+            boolean defaultPrecision) {
+
+        int group = startType > Types.SQL_INTERVAL_MONTH
+                    ? Types.SQL_INTERVAL_SECOND
+                    : Types.SQL_INTERVAL_MONTH;
+
+        if (defaultPrecision) {
+            return new IntervalType(group, type, precision, fractionPrecision,
+                                    startType, endType, defaultPrecision);
+        }
+
+        switch (type) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_YEAR;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_YEAR_TO_MONTH;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_MONTH :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_MONTH;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_DAY;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_DAY_TO_HOUR;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_DAY_TO_MINUTE;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+                if (precision == DTIType.defaultIntervalPrecision
+                        && fractionPrecision
+                           == DTIType.defaultIntervalFractionPrecision) {
+                    return SQL_INTERVAL_DAY_TO_SECOND;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_HOUR :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_HOUR;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_HOUR_TO_MINUTE;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE :
+                if (precision == DTIType.defaultIntervalPrecision) {
+                    return SQL_INTERVAL_MINUTE;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+                if (precision == DTIType.defaultIntervalPrecision
+                        && fractionPrecision
+                           == DTIType.defaultIntervalFractionPrecision) {
+                    return SQL_INTERVAL_HOUR_TO_SECOND;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+                if (precision == DTIType.defaultIntervalPrecision
+                        && fractionPrecision
+                           == DTIType.defaultIntervalFractionPrecision) {
+                    return SQL_INTERVAL_MINUTE_TO_SECOND;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_SECOND :
+                if (precision == DTIType.defaultIntervalPrecision
+                        && fractionPrecision
+                           == DTIType.defaultIntervalFractionPrecision) {
+                    return SQL_INTERVAL_SECOND;
+                }
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+
+        return new IntervalType(group, type, precision, fractionPrecision,
+                                startType, endType, defaultPrecision);
+    }
+
+    public static int getStartIntervalType(int type) {
+
+        int startType;
+
+        switch (type) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+                startType = Types.SQL_INTERVAL_YEAR;
+                break;
+
+            case Types.SQL_INTERVAL_MONTH :
+                startType = Types.SQL_INTERVAL_MONTH;
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+                startType = Types.SQL_INTERVAL_DAY;
+                break;
+
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+                startType = Types.SQL_INTERVAL_HOUR;
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+                startType = Types.SQL_INTERVAL_MINUTE;
+                break;
+
+            case Types.SQL_INTERVAL_SECOND :
+                startType = Types.SQL_INTERVAL_SECOND;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+
+        return startType;
+    }
+
+    public static int getEndIntervalType(int type) {
+
+        int endType;
+
+        switch (type) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                endType = Types.SQL_INTERVAL_YEAR;
+                break;
+
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+                endType = Types.SQL_INTERVAL_MONTH;
+                break;
+
+            case Types.SQL_INTERVAL_MONTH :
+                endType = Types.SQL_INTERVAL_MONTH;
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+                endType = Types.SQL_INTERVAL_DAY;
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+                endType = Types.SQL_INTERVAL_HOUR;
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+                endType = Types.SQL_INTERVAL_MINUTE;
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+                endType = Types.SQL_INTERVAL_SECOND;
+                break;
+
+            case Types.SQL_INTERVAL_HOUR :
+                endType = Types.SQL_INTERVAL_HOUR;
+                break;
+
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+                endType = Types.SQL_INTERVAL_MINUTE;
+                break;
+
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+                endType = Types.SQL_INTERVAL_SECOND;
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE :
+                endType = Types.SQL_INTERVAL_MINUTE;
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+                endType = Types.SQL_INTERVAL_SECOND;
+                break;
+
+            case Types.SQL_INTERVAL_SECOND :
+                endType = Types.SQL_INTERVAL_SECOND;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+
+        return endType;
+    }
+
+    public static Type getCombinedIntervalType(IntervalType type1,
+            IntervalType type2) {
+
+        int startType = type2.startIntervalType > type1.startIntervalType
+                        ? type1.startIntervalType
+                        : type2.startIntervalType;
+        int endType = type2.endIntervalType > type1.endIntervalType
+                      ? type2.endIntervalType
+                      : type1.endIntervalType;
+        int  type              = getCombinedIntervalType(startType, endType);
+        long precision = type1.precision > type2.precision ? type1.precision
+                                                           : type2.precision;
+        int  fractionPrecision = type1.scale > type2.scale ? type1.scale
+                                                           : type2.scale;
+
+        return getIntervalType(type, startType, endType, precision,
+                               fractionPrecision, false);
+    }
+
+    public static int getCombinedIntervalType(int startType, int endType) {
+
+        if (startType == endType) {
+            return startType;
+        }
+
+        switch (startType) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                if (endType == Types.SQL_INTERVAL_MONTH) {
+                    return Types.SQL_INTERVAL_YEAR_TO_MONTH;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+                switch (endType) {
+
+                    case Types.SQL_INTERVAL_HOUR :
+                        return Types.SQL_INTERVAL_DAY_TO_HOUR;
+
+                    case Types.SQL_INTERVAL_MINUTE :
+                        return Types.SQL_INTERVAL_DAY_TO_MINUTE;
+
+                    case Types.SQL_INTERVAL_SECOND :
+                        return Types.SQL_INTERVAL_DAY_TO_SECOND;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_HOUR :
+                switch (endType) {
+
+                    case Types.SQL_INTERVAL_MINUTE :
+                        return Types.SQL_INTERVAL_HOUR_TO_MINUTE;
+
+                    case Types.SQL_INTERVAL_SECOND :
+                        return Types.SQL_INTERVAL_HOUR_TO_SECOND;
+                }
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE :
+                if (endType == Types.SQL_INTERVAL_SECOND) {
+                    return Types.SQL_INTERVAL_MINUTE_TO_SECOND;
+                }
+                break;
+
+            default :
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+    }
+
+    long getIntervalValueLimit() {
+
+        long limit;
+
+        switch (typeCode) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                limit = DTIType.precisionLimits[(int) precision] * 12;
+                break;
+
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+                limit = DTIType.precisionLimits[(int) precision] * 12;
+                limit += 12;
+                break;
+
+            case Types.SQL_INTERVAL_MONTH :
+                limit = DTIType.precisionLimits[(int) precision];
+                break;
+
+            case Types.SQL_INTERVAL_DAY :
+                limit = DTIType.precisionLimits[(int) precision] * 24 * 60
+                        * 60;
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+                limit = DTIType.precisionLimits[(int) precision] * 24 * 60
+                        * 60;
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+                limit = DTIType.precisionLimits[(int) precision] * 24 * 60
+                        * 60;
+                break;
+
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+                limit = DTIType.precisionLimits[(int) precision] * 24 * 60
+                        * 60;
+                break;
+
+            case Types.SQL_INTERVAL_HOUR :
+                limit = DTIType.precisionLimits[(int) precision] * 60 * 60;
+                break;
+
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+                limit = DTIType.precisionLimits[(int) precision] * 60 * 60;
+                break;
+
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+                limit = DTIType.precisionLimits[(int) precision] * 60 * 60;
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE :
+                limit = DTIType.precisionLimits[(int) precision] * 60;
+                break;
+
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+                limit = DTIType.precisionLimits[(int) precision] * 60;
+                break;
+
+            case Types.SQL_INTERVAL_SECOND :
+                limit = DTIType.precisionLimits[(int) precision];
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+
+        return limit;
+    }
+
+    public int getPart(Session session, Object interval, int part) {
+
+        long units;
+
+        switch (part) {
+
+            case Types.SQL_INTERVAL_YEAR :
+                return (int) (((IntervalMonthData) interval).units / 12);
+
+            case Types.SQL_INTERVAL_MONTH :
+                units = ((IntervalMonthData) interval).units;
+
+                return part == startIntervalType ? (int) units
+                                                 : (int) (units % 12);
+
+            case Types.SQL_INTERVAL_DAY :
+                return (int) (((IntervalSecondData) interval).units
+                              / (24 * 60 * 60));
+
+            case Types.SQL_INTERVAL_HOUR : {
+                units = ((IntervalSecondData) interval).units / (60 * 60);
+
+                return part == startIntervalType ? (int) units
+                                                 : (int) (units % 24);
+            }
+            case Types.SQL_INTERVAL_MINUTE : {
+                units = ((IntervalSecondData) interval).units / 60;
+
+                return part == startIntervalType ? (int) units
+                                                 : (int) (units % 60);
+            }
+            case Types.SQL_INTERVAL_SECOND : {
+                units = ((IntervalSecondData) interval).units;
+
+                return part == startIntervalType ? (int) units
+                                                 : (int) (units % 60);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+
+    public long getSeconds(Object interval) {
+        return ((IntervalSecondData) interval).units;
+    }
+
+    public BigDecimal getSecondPart(Object interval) {
+
+        long seconds = ((IntervalSecondData) interval).units;
+
+        if (typeCode != Types.SQL_INTERVAL_SECOND) {
+            seconds %= 60;
+        }
+
+        int nanos = ((IntervalSecondData) interval).nanos;
+
+        return getSecondPart(seconds, nanos);
+    }
+
+    public long convertToLong(Object interval) {
+
+        switch (endIntervalType) {
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_MONTH :
+                long months = ((IntervalMonthData) interval).units;
+
+                return (months / DTIType.yearToSecondFactors[endPartIndex]);
+
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_SECOND : {
+                long seconds = ((IntervalSecondData) interval).units;
+
+                return (seconds / DTIType.yearToSecondFactors[endPartIndex]);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "IntervalType");
+        }
+    }
+}
diff --git a/src/org/hsqldb/types/JavaObjectData.java b/src/org/hsqldb/types/JavaObjectData.java
new file mode 100644
index 0000000..b8a2668
--- /dev/null
+++ b/src/org/hsqldb/types/JavaObjectData.java
@@ -0,0 +1,126 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.Serializable;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.InOutUtil;
+
+/**
+ * Represents of an instance of an OTHER field value. <p>
+ *
+ * Prior to 1.7.0 there were problems storing Objects of normal column types
+ * in columns of the type OTHER. In 1.7.0 changes were made to allow this,
+ * but as all the conversion took place inside the engine, it introduced a
+ * requirement for all classes for objects stored in OTHER columns to be
+ * available on the runtime class path of the engine. <p>
+ *
+ * In 1.7.2, the introduction of real preprared statement support allows us
+ * revert to the pre 1.7.0 behaviour without the artificial limitations. <p>
+ *
+ * The classes for stored objects need not be available to open and operate
+ * the database in general. The classes need to be available only if a
+ * conversion from one of these objects to another type is performed inside
+ * the engine while operating the database.
+ *
+ * The current limitation is that in SQL statements, values of type String
+ * (CHARACTER and related SQL types) cannot be stored in columns of type
+ * OTHER. This limitation does not exist for String values assigned to
+ * PreparedStatement variables.
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.7.2
+ */
+public class JavaObjectData {
+
+    private byte[] data;
+
+    JavaObjectData() {}
+
+    /**
+     * Constructor used inside the engine when an already serialized
+     * Object is read from a file (.log, .script, .data or text table source).
+     */
+    public JavaObjectData(byte[] data) {
+        this.data = data;
+    }
+
+    /**
+     * Constructor used inside the engine to convert an Object into an
+     * object of type OTHER.
+     * Used also with JDBC setParameter().
+     * If parameter serialize is true, the Object is serialized for storage.
+     */
+    public JavaObjectData(Serializable o) {
+
+        try {
+            data = InOutUtil.serialize(o);
+        } catch (Exception e) {
+            throw Error.error(ErrorCode.X_22521, e.toString());
+        }
+    }
+
+    public byte[] getBytes() {
+        return data;
+    }
+
+    public int getBytesLength() {
+        return data.length;
+    }
+
+    /**
+     * This method is called from classes implementing the JDBC
+     * interfaces. Inside the engine it is used for conversion from a value of
+     * type OTHER to another type. It will throw if the OTHER is an instance
+     * of a classe that is not available.
+     */
+    public Serializable getObject() {
+
+        try {
+            return InOutUtil.deserialize(data);
+        } catch (Exception e) {
+            throw Error.error(ErrorCode.X_22521, e.toString());
+        }
+    }
+
+    /**
+     * Returns String repsentation of this object.
+     *
+     * @return a String represntation of this object.
+     */
+    public String toString() {
+        return super.toString();
+    }
+}
diff --git a/src/org/hsqldb/types/LobData.java b/src/org/hsqldb/types/LobData.java
new file mode 100644
index 0000000..aa00d1c
--- /dev/null
+++ b/src/org/hsqldb/types/LobData.java
@@ -0,0 +1,56 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.SessionInterface;
+
+/**
+ * Interface for Large Object implementations.<p>
+ *
+ * All positions are 0 based
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public interface LobData {
+
+    long length(SessionInterface session);
+
+    long getId();
+
+    void setId(long id);
+
+    void setSession(SessionInterface session);
+
+    boolean isBinary();
+}
diff --git a/src/org/hsqldb/types/NullType.java b/src/org/hsqldb/types/NullType.java
new file mode 100644
index 0000000..d653093
--- /dev/null
+++ b/src/org/hsqldb/types/NullType.java
@@ -0,0 +1,119 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+
+/**
+ * Type subclass for untyped NULL values.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class NullType extends Type {
+
+    static final NullType nullType = new NullType();
+
+    private NullType() {
+        super(Types.SQL_ALL_TYPES, Types.SQL_ALL_TYPES, 0, 0);
+    }
+
+    public int displaySize() {
+        return 4;
+    }
+
+    public int getJDBCTypeCode() {
+        return typeCode;
+    }
+
+    public Class getJDBCClass() {
+        return java.lang.Void.class;
+    }
+
+    public String getJDBCClassName() {
+        return "java.lang.Void";
+    }
+
+    public String getNameString() {
+        return Tokens.T_NULL;
+    }
+
+    public String getDefinition() {
+        return Tokens.T_NULL;
+    }
+
+    public Type getAggregateType(Type other) {
+        return other;
+    }
+
+    public Type getCombinedType(Type other, int operation) {
+        return other;
+    }
+
+    public int compare(Session session, Object a, Object b) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "NullType");
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+        return null;
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+        return null;
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+        return null;
+    }
+
+    public String convertToString(Object a) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "NullType");
+    }
+
+    public String convertToSQLString(Object a) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "NullType");
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+        return true;
+    }
+
+    public static Type getNullType() {
+        return nullType;
+    }
+}
diff --git a/src/org/hsqldb/types/NumberType.java b/src/org/hsqldb/types/NumberType.java
new file mode 100644
index 0000000..6f69f64
--- /dev/null
+++ b/src/org/hsqldb/types/NumberType.java
@@ -0,0 +1,1843 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.java.JavaSystem;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Type subclass for all NUMBER types.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class NumberType extends Type {
+
+    static final int        tinyintPrecision             = 3;
+    static final int        smallintPrecision            = 5;
+    static final int        integerPrecision             = 10;
+    static final int        bigintPrecision              = 19;
+    static final int        doublePrecision              = 0;
+    public static final int defaultNumericPrecision      = 100;
+    public static final int defaultNumericScale          = 10;
+    public static final int maxNumericPrecision          = Integer.MAX_VALUE;
+    static final int        bigintSquareNumericPrecision = 40;
+
+    //
+    public static final int TINYINT_WIDTH  = 8;
+    public static final int SMALLINT_WIDTH = 16;
+    public static final int INTEGER_WIDTH  = 32;
+    public static final int BIGINT_WIDTH   = 64;
+    public static final int DOUBLE_WIDTH   = 128;    // nominal width
+    public static final int DECIMAL_WIDTH  = 256;    // nominal width
+
+    //
+    public static final Type SQL_NUMERIC_DEFAULT_INT =
+        new NumberType(Types.NUMERIC, defaultNumericPrecision, 0);
+
+    //
+    public static final BigDecimal MAX_LONG =
+        BigDecimal.valueOf(Long.MAX_VALUE);
+    public static final BigDecimal MIN_LONG =
+        BigDecimal.valueOf(Long.MIN_VALUE);
+    public static final BigDecimal MAX_INT =
+        BigDecimal.valueOf(Integer.MAX_VALUE);
+    public static final BigDecimal MIN_INT =
+        BigDecimal.valueOf(Integer.MIN_VALUE);
+
+    //
+    public static final BigInteger MIN_LONG_BI = MIN_LONG.toBigInteger();
+    public static final BigInteger MAX_LONG_BI = MAX_LONG.toBigInteger();
+
+    //
+    final int typeWidth;
+
+    public NumberType(int type, long precision, int scale) {
+
+        super(Types.SQL_NUMERIC, type, precision, scale);
+
+        switch (type) {
+
+            case Types.TINYINT :
+                typeWidth = TINYINT_WIDTH;
+                break;
+
+            case Types.SQL_SMALLINT :
+                typeWidth = SMALLINT_WIDTH;
+                break;
+
+            case Types.SQL_INTEGER :
+                typeWidth = INTEGER_WIDTH;
+                break;
+
+            case Types.SQL_BIGINT :
+                typeWidth = BIGINT_WIDTH;
+                break;
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                typeWidth = DOUBLE_WIDTH;
+                break;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                typeWidth = DECIMAL_WIDTH;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    /**
+     * Returns decimal precision for NUMERIC/DECIMAL. Returns binary precision
+     * for other parts.
+     */
+    public int getPrecision() {
+
+        switch (typeCode) {
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+                return typeWidth;
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return 64;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return (int) precision;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public int displaySize() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DECIMAL :
+            case Types.SQL_NUMERIC :
+                if (scale == 0) {
+                    if (precision == 0) {
+                        return 646456995;    // precision + "-.".length()}
+                    }
+
+                    return (int) precision + 1;
+                }
+
+                if (precision == scale) {
+                    return (int) precision + 3;
+                }
+
+                return (int) precision + 2;
+
+            case Types.SQL_FLOAT :
+            case Types.SQL_REAL :
+            case Types.SQL_DOUBLE :
+                return 23;                   // String.valueOf(-Double.MAX_VALUE).length();
+
+            case Types.SQL_BIGINT :
+                return 20;                   // decimal precision + "-".length();
+
+            case Types.SQL_INTEGER :
+                return 11;                   // decimal precision + "-".length();
+
+            case Types.SQL_SMALLINT :
+                return 6;                    // decimal precision + "-".length();
+
+            case Types.TINYINT :
+                return 4;                    // decimal precision + "-".length();
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public int getJDBCTypeCode() {
+        return typeCode == Types.SQL_BIGINT ? Types.BIGINT
+                                            : typeCode;
+    }
+
+    public Class getJDBCClass() {
+
+        switch (typeCode) {
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+                return java.lang.Integer.class;
+
+            case Types.SQL_BIGINT :
+                return java.lang.Long.class;
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return java.lang.Double.class;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return java.math.BigDecimal.class;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public String getJDBCClassName() {
+
+        switch (typeCode) {
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+                return "java.lang.Integer";
+
+            case Types.SQL_BIGINT :
+                return "java.lang.Long";
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return "java.lang.Double";
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return "java.math.BigDecimal";
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public String getNameString() {
+
+        switch (typeCode) {
+
+            case Types.TINYINT :
+                return Tokens.T_TINYINT;
+
+            case Types.SQL_SMALLINT :
+                return Tokens.T_SMALLINT;
+
+            case Types.SQL_INTEGER :
+                return Tokens.T_INTEGER;
+
+            case Types.SQL_BIGINT :
+                return Tokens.T_BIGINT;
+
+            case Types.SQL_REAL :
+                return Tokens.T_REAL;
+
+            case Types.SQL_FLOAT :
+                return Tokens.T_FLOAT;
+
+            case Types.SQL_DOUBLE :
+                return Tokens.T_DOUBLE;
+
+            case Types.SQL_NUMERIC :
+                return Tokens.T_NUMERIC;
+
+            case Types.SQL_DECIMAL :
+                return Tokens.T_DECIMAL;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public String getFullNameString() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DOUBLE :
+                return "DOUBLE PRECISION";
+
+            default :
+                return getNameString();
+        }
+    }
+
+    public String getDefinition() {
+
+        switch (typeCode) {
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                StringBuffer sb = new StringBuffer(16);
+
+                sb.append(getNameString());
+                sb.append('(');
+                sb.append(precision);
+
+                if (scale != 0) {
+                    sb.append(',');
+                    sb.append(scale);
+                }
+
+                sb.append(')');
+
+                return sb.toString();
+
+            default :
+                return getNameString();
+        }
+    }
+
+    public long getMaxPrecision() {
+
+        switch (typeCode) {
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return maxNumericPrecision;
+
+            default :
+                return getNumericPrecisionInRadix();
+        }
+    }
+
+    public int getMaxScale() {
+
+        switch (typeCode) {
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return Short.MAX_VALUE;
+
+            default :
+                return 0;
+        }
+    }
+
+    public boolean acceptsPrecision() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DECIMAL :
+            case Types.SQL_NUMERIC :
+            case Types.SQL_FLOAT :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    public boolean acceptsScale() {
+
+        switch (typeCode) {
+
+            case Types.SQL_DECIMAL :
+            case Types.SQL_NUMERIC :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    public int getPrecisionRadix() {
+
+        if (typeCode == Types.SQL_DECIMAL || typeCode == Types.SQL_NUMERIC) {
+            return 10;
+        }
+
+        return 2;
+    }
+
+    public boolean isNumberType() {
+        return true;
+    }
+
+    public boolean isIntegralType() {
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return false;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return scale == 0;
+
+            default :
+                return true;
+        }
+    }
+
+    public boolean isExactNumberType() {
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return false;
+
+            default :
+                return true;
+        }
+    }
+
+    public int getNominalWidth() {
+        return typeWidth;
+    }
+
+    public int precedenceDegree(Type other) {
+
+        if (other.isNumberType()) {
+            int otherWidth = ((NumberType) other).typeWidth;
+
+            return otherWidth - typeWidth;
+        }
+
+        return Integer.MIN_VALUE;
+    }
+
+    public Type getAggregateType(Type other) {
+
+        if (this == other) {
+            return this;
+        }
+
+        if (other.isCharacterType()) {
+            return other.getAggregateType(this);
+        }
+
+        switch (other.typeCode) {
+
+            case Types.SQL_ALL_TYPES :
+                return this;
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+                break;
+
+            default :
+                throw Error.error(ErrorCode.X_42562);
+        }
+
+        if (typeWidth == DOUBLE_WIDTH) {
+            return this;
+        }
+
+        if (((NumberType) other).typeWidth == DOUBLE_WIDTH) {
+            return other;
+        }
+
+        if (typeWidth <= BIGINT_WIDTH
+                && ((NumberType) other).typeWidth <= BIGINT_WIDTH) {
+            return (typeWidth > ((NumberType) other).typeWidth) ? this
+                                                                : other;
+        }
+
+        int newScale = scale > other.scale ? scale
+                                           : other.scale;
+        long newDigits = precision - scale > other.precision - other.scale
+                         ? precision - scale
+                         : other.precision - other.scale;
+
+        return getNumberType(Types.SQL_DECIMAL, newDigits + newScale,
+                             newScale);
+    }
+
+    /**
+     *  Returns a SQL type "wide" enough to represent the result of the
+     *  expression.<br>
+     *  A type is "wider" than the other if it can represent all its
+     *  numeric values.<BR>
+     *  Arithmetic operation terms are promoted to a type that can
+     *  represent the resulting values and avoid incorrect results.<p>
+     *  FLOAT/REAL/DOUBLE used in an operation results in the same type,
+     *  regardless of the type of the other operand.
+     *  When the result or the expression is converted to the
+     *  type of the target column for storage, an exception is thrown if the
+     *  resulting value cannot be stored in the column<p>
+     *  Types narrower than INTEGER (int) are promoted to
+     *  INTEGER. The order of promotion is as follows<p>
+     *
+     *  INTEGER, BIGINT, NUMERIC/DECIMAL<p>
+     *
+     *  TINYINT and SMALLINT in any combination return INTEGER<br>
+     *  TINYINT/SMALLINT/INTEGER and INTEGER return BIGINT<br>
+     *  TINYINT/SMALLINT/INTEGER and BIGINT return NUMERIC/DECIMAL<br>
+     *  BIGINT and BIGINT return NUMERIC/DECIMAL<br>
+     *  REAL/FLOAT/DOUBLE and any type return REAL/FLOAT/DOUBLE<br>
+     *  NUMERIC/DECIMAL any type other than REAL/FLOAT/DOUBLE returns NUMERIC/DECIMAL<br>
+     *  In the case of NUMERIC/DECIMAL returned, the result precision is always
+     *  large enough to express any value result, while the scale depends on the
+     *  operation:<br>
+     *  For ADD/SUBTRACT/DIVIDE, the scale is the larger of the two<br>
+     *  For MULTIPLY, the scale is the sum of the two scales<br>
+     */
+    public Type getCombinedType(Type other, int operation) {
+
+        if (other.typeCode == Types.SQL_ALL_TYPES) {
+            other = this;
+        }
+
+        switch (operation) {
+
+            case OpTypes.ADD :
+                break;
+
+            case OpTypes.MULTIPLY :
+                if (other.isIntervalType()) {
+                    return other.getCombinedType(this, OpTypes.MULTIPLY);
+                }
+                break;
+
+            case OpTypes.DIVIDE :
+                if (typeWidth == DECIMAL_WIDTH) {
+                    break;
+                }
+            case OpTypes.SUBTRACT :
+            default :
+
+                // all derivatives of equality ops or comparison ops
+                return getAggregateType(other);
+        }
+
+        // resolution for ADD and MULTIPLY only
+        if (!other.isNumberType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        if (typeWidth == DOUBLE_WIDTH
+                || ((NumberType) other).typeWidth == DOUBLE_WIDTH) {
+            return Type.SQL_DOUBLE;
+        }
+
+        int sum = typeWidth + ((NumberType) other).typeWidth;
+
+        if (sum <= INTEGER_WIDTH) {
+            return Type.SQL_INTEGER;
+        }
+
+        if (sum <= BIGINT_WIDTH) {
+            return Type.SQL_BIGINT;
+        }
+
+        int  newScale;
+        long newDigits;
+
+        switch (operation) {
+
+            case OpTypes.ADD :
+                newScale = scale > other.scale ? scale
+                                               : other.scale;
+                newDigits = precision - scale > other.precision - other.scale
+                            ? precision - scale
+                            : other.precision - other.scale;
+
+                newDigits++;
+                break;
+
+            case OpTypes.DIVIDE :
+                newDigits = precision - scale + other.scale;
+                newScale  = scale > other.scale ? scale
+                                                : other.scale;
+                break;
+
+            case OpTypes.MULTIPLY :
+                newDigits = precision - scale + other.precision - other.scale;
+                newScale  = scale + other.scale;
+                break;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+
+        return getNumberType(Types.SQL_DECIMAL, newScale + newDigits,
+                             newScale);
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        switch (typeCode) {
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER : {
+                if (b instanceof Integer) {
+                    int ai = ((Number) a).intValue();
+                    int bi = ((Number) b).intValue();
+
+                    return (ai > bi) ? 1
+                                     : (bi > ai ? -1
+                                                : 0);
+                } else if (b instanceof Double) {
+                    double ai = ((Number) a).doubleValue();
+                    double bi = ((Number) b).doubleValue();
+
+                    return (ai > bi) ? 1
+                                     : (bi > ai ? -1
+                                                : 0);
+                } else if (b instanceof BigDecimal) {
+                    BigDecimal ad = convertToDecimal(a);
+                    int        i  = ad.compareTo((BigDecimal) b);
+
+                    return (i == 0) ? 0
+                                    : (i < 0 ? -1
+                                             : 1);
+                }
+            }
+
+            // fall through
+            case Types.SQL_BIGINT : {
+                if (b instanceof Long) {
+                    long longa = ((Number) a).longValue();
+                    long longb = ((Number) b).longValue();
+
+                    return (longa > longb) ? 1
+                                           : (longb > longa ? -1
+                                                            : 0);
+                } else if (b instanceof Double) {
+                    BigDecimal ad =
+                        BigDecimal.valueOf(((Number) a).longValue());
+                    BigDecimal bd = new BigDecimal(((Double) b).doubleValue());
+                    int        i  = ad.compareTo(bd);
+
+                    return (i == 0) ? 0
+                                    : (i < 0 ? -1
+                                             : 1);
+                } else if (b instanceof BigDecimal) {
+                    BigDecimal ad =
+                        BigDecimal.valueOf(((Number) a).longValue());
+                    int i = ad.compareTo((BigDecimal) b);
+
+                    return (i == 0) ? 0
+                                    : (i < 0 ? -1
+                                             : 1);
+                }
+            }
+
+            // fall through
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+
+                /** @todo big-decimal etc */
+                double ad = ((Number) a).doubleValue();
+                double bd = ((Number) b).doubleValue();
+
+                return (ad > bd) ? 1
+                                 : (bd > ad ? -1
+                                            : 0);
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                BigDecimal bd = convertToDecimal(b);
+                int        i  = ((BigDecimal) a).compareTo(bd);
+
+                return (i == 0) ? 0
+                                : (i < 0 ? -1
+                                         : 1);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    /** @todo - review usage to see if range enforcement / java type conversion is necessary */
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+                return a;
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return a;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                BigDecimal dec = (BigDecimal) a;
+
+                if (scale != dec.scale()) {
+                    dec = dec.setScale(scale, BigDecimal.ROUND_HALF_DOWN);
+                }
+
+                int p = JavaSystem.precision(dec);
+
+                if (p > precision) {
+                    throw Error.error(ErrorCode.X_22003);
+                }
+
+                return dec;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+
+        if (a == null) {
+            return a;
+        }
+
+        if (otherType.typeCode == typeCode) {
+            switch (typeCode) {
+
+                case Types.SQL_NUMERIC :
+                case Types.SQL_DECIMAL :
+                    if (otherType.scale == scale
+                            && otherType.precision <= precision) {
+                        return a;
+                    }
+                    break;
+
+                default :
+                    return a;
+            }
+        }
+
+        if (otherType.isIntervalType()) {
+            int endType = ((IntervalType) otherType).endIntervalType;
+
+            switch (endType) {
+
+                case Types.SQL_INTERVAL_YEAR :
+                case Types.SQL_INTERVAL_MONTH :
+                case Types.SQL_INTERVAL_DAY :
+                case Types.SQL_INTERVAL_HOUR :
+                case Types.SQL_INTERVAL_MINUTE : {
+                    Long value = ValuePool.getLong(
+                        ((IntervalType) otherType).convertToLong(a));
+
+                    return convertToType(session, value, Type.SQL_BIGINT);
+                }
+                case Types.SQL_INTERVAL_SECOND : {
+                    long seconds = ((IntervalSecondData) a).units;
+                    long nanos   = ((IntervalSecondData) a).nanos;
+                    BigDecimal value =
+                        ((DTIType) otherType).getSecondPart(seconds, nanos);
+
+                    return value;
+                }
+            }
+        }
+
+        switch (otherType.typeCode) {
+
+            case Types.SQL_CLOB :
+                a = ((ClobData) a).getSubString(
+                    session, 0L, (int) ((ClobData) a).length(session));
+
+            // fall through
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE : {
+                a = session.getScanner().convertToNumber((String) a, this);
+                a = convertToDefaultType(session, a);
+
+                return convertToTypeLimits(session, a);
+            }
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                break;
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                if (otherType.precision == 1) {
+                    if (((BinaryData) a).getBytes()[0] == 0) {
+                        a = ValuePool.INTEGER_0;
+                    } else {
+                        a = ValuePool.INTEGER_1;
+                    }
+
+                    break;
+                }
+            default :
+                throw Error.error(ErrorCode.X_42561);
+        }
+
+        switch (this.typeCode) {
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+                return convertToInt(a, this.typeCode);
+
+            case Types.SQL_BIGINT :
+                return convertToLong(a);
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return convertToDouble(a);
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                BigDecimal value = convertToDecimal(a);
+
+                return convertToTypeLimits(session, value);
+
+            default :
+                throw Error.error(ErrorCode.X_42561);
+        }
+    }
+
+    public Object convertToTypeJDBC(SessionInterface session, Object a,
+                                    Type otherType) {
+
+        if (a == null) {
+            return a;
+        }
+
+        if (otherType.isLobType()) {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        switch (otherType.typeCode) {
+
+            case Types.SQL_BOOLEAN :
+                a         = ((Boolean) a).booleanValue() ? ValuePool.INTEGER_1
+                                                         : ValuePool.INTEGER_0;
+                otherType = Type.SQL_INTEGER;
+        }
+
+        return convertToType(session, a, otherType);
+    }
+
+    /**
+     * Relaxes SQL parameter type enforcement for DECIMAL, allowing long values.
+     */
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return a;
+        }
+
+        Type otherType;
+
+        if (a instanceof Number) {
+            if (a instanceof BigInteger) {
+                a = new BigDecimal((BigInteger) a);
+            } else if (a instanceof Float) {
+                a = new Double(((Float) a).doubleValue());
+            } else if (a instanceof Byte) {
+                a = ValuePool.getInt(((Byte) a).intValue());
+            } else if (a instanceof Short) {
+                a = ValuePool.getInt(((Short) a).intValue());
+            }
+
+            if (a instanceof Integer) {
+                otherType = Type.SQL_INTEGER;
+            } else if (a instanceof Long) {
+                otherType = Type.SQL_BIGINT;
+            } else if (a instanceof Double) {
+                otherType = Type.SQL_DOUBLE;
+            } else if (a instanceof BigDecimal) {
+                if (typeCode == Types.SQL_DECIMAL
+                        || typeCode == Types.SQL_NUMERIC) {
+                    return a;
+                }
+
+                otherType = Type.SQL_DECIMAL_DEFAULT;
+            } else {
+                throw Error.error(ErrorCode.X_42561);
+            }
+        } else if (a instanceof String) {
+            otherType = Type.SQL_VARCHAR;
+        } else {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        return convertToType(session, a, otherType);
+    }
+
+    /**
+     * Type narrowing from DOUBLE/DECIMAL/NUMERIC to BIGINT / INT / SMALLINT / TINYINT
+     * following SQL rules. When conversion is from a non-integral type,
+     * digits to the right of the decimal point are lost.
+     */
+
+    /**
+     * Converter from a numeric object to Integer. Input is checked to be
+     * within range represented by the given number type.
+     */
+    static Integer convertToInt(Object a, int type) {
+
+        int value;
+
+        if (a instanceof Integer) {
+            if (type == Types.SQL_INTEGER) {
+                return (Integer) a;
+            }
+
+            value = ((Integer) a).intValue();
+        } else if (a instanceof Long) {
+            long temp = ((Long) a).longValue();
+
+            if (Integer.MAX_VALUE < temp || temp < Integer.MIN_VALUE) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+
+            value = (int) temp;
+        } else if (a instanceof BigDecimal) {
+            BigDecimal bd = ((BigDecimal) a);
+
+            if (bd.compareTo(MAX_INT) > 0 || bd.compareTo(MIN_INT) < 0) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+
+            value = bd.intValue();
+        } else if (a instanceof Double || a instanceof Float) {
+            double d = ((Number) a).doubleValue();
+
+            if (Double.isInfinite(d) || Double.isNaN(d)
+                    || d >= (double) Integer.MAX_VALUE + 1
+                    || d <= (double) Integer.MIN_VALUE - 1) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+
+            value = (int) d;
+        } else {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        if (type == Types.TINYINT) {
+            if (Byte.MAX_VALUE < value || value < Byte.MIN_VALUE) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+        } else if (type == Types.SQL_SMALLINT) {
+            if (Short.MAX_VALUE < value || value < Short.MIN_VALUE) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+        }
+
+        return ValuePool.getInt(value);
+    }
+
+    /**
+     * Converter from a numeric object to Long. Input is checked to be
+     * within range represented by Long.
+     */
+    static Long convertToLong(Object a) {
+
+        if (a instanceof Integer) {
+            return ValuePool.getLong(((Integer) a).intValue());
+        } else if (a instanceof Long) {
+            return (Long) a;
+        } else if (a instanceof BigDecimal) {
+            BigDecimal bd = (BigDecimal) a;
+
+            if (bd.compareTo(MAX_LONG) > 0 || bd.compareTo(MIN_LONG) < 0) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+
+            return ValuePool.getLong(bd.longValue());
+        } else if (a instanceof Double || a instanceof Float) {
+            double d = ((Number) a).doubleValue();
+
+            if (Double.isInfinite(d) || Double.isNaN(d)
+                    || d >= (double) Long.MAX_VALUE + 1
+                    || d <= (double) Long.MIN_VALUE - 1) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+
+            return ValuePool.getLong((long) d);
+        } else {
+            throw Error.error(ErrorCode.X_42561);
+        }
+    }
+
+    /**
+     * Converter from a numeric object to Double. Input is checked to be
+     * within range represented by Double
+     */
+    private static Double convertToDouble(Object a) {
+
+        double value;
+
+        if (a instanceof java.lang.Double) {
+            return (Double) a;
+        } else if (a instanceof BigDecimal) {
+            BigDecimal bd = (BigDecimal) a;
+
+            value = bd.doubleValue();
+
+            int        signum = bd.signum();
+            BigDecimal bdd    = new BigDecimal(value + signum);
+
+            if (bdd.compareTo(bd) != signum) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+        } else {
+            value = ((Number) a).doubleValue();
+        }
+
+        return ValuePool.getDouble(Double.doubleToLongBits(value));
+    }
+
+    public static double toDouble(Object a) {
+
+        double value;
+
+        if (a instanceof java.lang.Double) {
+            return ((Double) a).doubleValue();
+        } else if (a instanceof BigDecimal) {
+            BigDecimal bd = (BigDecimal) a;
+
+            value = bd.doubleValue();
+
+            int        signum = bd.signum();
+            BigDecimal bdd    = new BigDecimal(value + signum);
+
+            if (bdd.compareTo(bd) != signum) {
+                throw Error.error(ErrorCode.X_22003);
+            }
+        } else if (a instanceof Number) {
+            value = ((Number) a).doubleValue();
+        } else {
+            throw Error.error(ErrorCode.X_22501);
+        }
+
+        return value;
+    }
+
+    private static BigDecimal convertToDecimal(Object a) {
+
+        if (a instanceof BigDecimal) {
+            return (BigDecimal) a;
+        } else if (a instanceof Integer || a instanceof Long) {
+            return BigDecimal.valueOf(((Number) a).longValue());
+        } else if (a instanceof Double) {
+            double value = ((Number) a).doubleValue();
+
+            if (Double.isInfinite(value) || Double.isNaN(value)) {
+                return null;
+            }
+
+            return new BigDecimal(value);
+        } else {
+            throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (this.typeCode) {
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+            case Types.SQL_BIGINT :
+                return a.toString();
+
+            case Types.SQL_REAL :
+            case Types.SQL_DOUBLE :
+                double value = ((Double) a).doubleValue();
+
+                /** @todo - java 5 format change */
+                if (value == Double.NEGATIVE_INFINITY) {
+                    return "-1E0/0";
+                }
+
+                if (value == Double.POSITIVE_INFINITY) {
+                    return "1E0/0";
+                }
+
+                if (Double.isNaN(value)) {
+                    return "0E0/0E0";
+                }
+
+                String s = Double.toString(value);
+
+                // ensure the engine treats the value as a DOUBLE, not DECIMAL
+                if (s.indexOf('E') < 0) {
+                    s = s.concat("E0");
+                }
+
+                return s;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return JavaSystem.toString((BigDecimal) a);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        return convertToString(a);
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+
+        if (otherType.typeCode == Types.SQL_ALL_TYPES) {
+            return true;
+        }
+
+        if (otherType.isNumberType()) {
+            return true;
+        }
+
+        if (otherType.isIntervalType()) {
+            return true;
+        }
+
+        if (otherType.isCharacterType()) {
+            return true;
+        }
+
+        if (otherType.isBitType() && otherType.precision == 1) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public int compareToTypeRange(Object o) {
+
+        if (!(o instanceof Number)) {
+            return 0;
+        }
+
+        if (o instanceof Integer || o instanceof Long) {
+            long temp = ((Number) o).longValue();
+            int  min;
+            int  max;
+
+            switch (typeCode) {
+
+                case Types.TINYINT :
+                    min = Byte.MIN_VALUE;
+                    max = Byte.MAX_VALUE;
+                    break;
+
+                case Types.SQL_SMALLINT :
+                    min = Short.MIN_VALUE;
+                    max = Short.MAX_VALUE;
+                    break;
+
+                case Types.SQL_INTEGER :
+                    min = Integer.MIN_VALUE;
+                    max = Integer.MAX_VALUE;
+                    break;
+
+                case Types.SQL_BIGINT :
+                    return 0;
+
+                case Types.SQL_DECIMAL :
+                case Types.SQL_NUMERIC : {
+                    if (precision - scale > 18) {
+                        return 0;
+                    }
+
+                    if (precision - scale > 9 && o instanceof Integer) {
+                        return 0;
+                    }
+
+                    BigDecimal dec = convertToDecimal(o);
+                    int        s   = dec.scale();
+                    int        p   = JavaSystem.precision(dec);
+
+                    if (s < 0) {
+                        p -= s;
+                        s = 0;
+                    }
+
+                    return (precision - scale >= p - s) ? 0
+                                                        : dec.signum();
+                }
+                default :
+                    return 0;
+            }
+
+            if (max < temp) {
+                return 1;
+            }
+
+            if (temp < min) {
+                return -1;
+            }
+
+            return 0;
+        }
+
+        return 0;
+    }
+
+    public Object add(Object a, Object b, Type otherType) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double ad = ((Number) a).doubleValue();
+                double bd = ((Number) b).doubleValue();
+
+                return ValuePool.getDouble(Double.doubleToLongBits(ad + bd));
+
+//                return new Double(ad + bd);
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                a = convertToDefaultType(null, a);
+                b = convertToDefaultType(null, b);
+
+                BigDecimal abd = (BigDecimal) a;
+                BigDecimal bbd = (BigDecimal) b;
+
+                abd = abd.add(bbd);
+
+                return convertToTypeLimits(null, abd);
+            }
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER : {
+                int ai = ((Number) a).intValue();
+                int bi = ((Number) b).intValue();
+
+                return ValuePool.getInt(ai + bi);
+            }
+            case Types.SQL_BIGINT : {
+                long longa = ((Number) a).longValue();
+                long longb = ((Number) b).longValue();
+
+                return ValuePool.getLong(longa + longb);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public Object subtract(Object a, Object b, Type otherType) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double ad = ((Number) a).doubleValue();
+                double bd = ((Number) b).doubleValue();
+
+                return ValuePool.getDouble(Double.doubleToLongBits(ad - bd));
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                a = convertToDefaultType(null, a);
+                b = convertToDefaultType(null, b);
+
+                BigDecimal abd = (BigDecimal) a;
+                BigDecimal bbd = (BigDecimal) b;
+
+                abd = abd.subtract(bbd);
+
+                return convertToTypeLimits(null, abd);
+            }
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER : {
+                int ai = ((Number) a).intValue();
+                int bi = ((Number) b).intValue();
+
+                return ValuePool.getInt(ai - bi);
+            }
+            case Types.SQL_BIGINT : {
+                long longa = ((Number) a).longValue();
+                long longb = ((Number) b).longValue();
+
+                return ValuePool.getLong(longa - longb);
+            }
+            default :
+        }
+
+        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+    }
+
+    public Object multiply(Object a, Object b) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double ad = ((Number) a).doubleValue();
+                double bd = ((Number) b).doubleValue();
+
+                return ValuePool.getDouble(Double.doubleToLongBits(ad * bd));
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                if (!(a instanceof BigDecimal)) {
+                    a = convertToDefaultType(null, a);
+                }
+
+                if (!(b instanceof BigDecimal)) {
+                    b = convertToDefaultType(null, b);
+                }
+
+                BigDecimal abd = (BigDecimal) a;
+                BigDecimal bbd = (BigDecimal) b;
+                BigDecimal bd  = abd.multiply(bbd);
+
+                return convertToTypeLimits(null, bd);
+            }
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER : {
+                int ai = ((Number) a).intValue();
+                int bi = ((Number) b).intValue();
+
+                return ValuePool.getInt(ai * bi);
+            }
+            case Types.SQL_BIGINT : {
+                long longa = ((Number) a).longValue();
+                long longb = ((Number) b).longValue();
+
+                return ValuePool.getLong(longa * longb);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public Object divide(Object a, Object b) {
+
+        if (a == null || b == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double ad = ((Number) a).doubleValue();
+                double bd = ((Number) b).doubleValue();
+
+                if (bd == 0) {
+                    throw Error.error(ErrorCode.X_22012);
+                }
+
+                return ValuePool.getDouble(Double.doubleToLongBits(ad / bd));
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                if (!(a instanceof BigDecimal)) {
+                    a = convertToDefaultType(null, a);
+                }
+
+                if (!(b instanceof BigDecimal)) {
+                    b = convertToDefaultType(null, b);
+                }
+
+                BigDecimal abd = (BigDecimal) a;
+                BigDecimal bbd = (BigDecimal) b;
+
+                if (bbd.signum() == 0) {
+                    throw Error.error(ErrorCode.X_22012);
+                }
+
+                BigDecimal bd = abd.divide(bbd, scale, BigDecimal.ROUND_DOWN);
+
+                return convertToTypeLimits(null, bd);
+            }
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER : {
+                int ai = ((Number) a).intValue();
+                int bi = ((Number) b).intValue();
+
+                if (bi == 0) {
+                    throw Error.error(ErrorCode.X_22012);
+                }
+
+                return ValuePool.getInt(ai / bi);
+            }
+            case Types.SQL_BIGINT : {
+                long al = ((Number) a).longValue();
+                long bl = ((Number) b).longValue();
+
+                if (bl == 0) {
+                    throw Error.error(ErrorCode.X_22012);
+                }
+
+                return ValuePool.getLong(al / bl);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public Object modulo(Object a, Object b, Type otherType) {
+
+        if (!otherType.isNumberType()) {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        Object temp = divide(a, b);
+
+        temp = multiply(temp, b);
+        temp = convertToDefaultType(null, temp);
+        temp = subtract(a, temp, this);
+
+        return convertToTypeLimits(null, temp);
+    }
+
+    public Object absolute(Object a) {
+        return isNegative(a) ? negate(a)
+                             : a;
+    }
+
+    public Object negate(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double ad = -((Number) a).doubleValue();
+
+                return ValuePool.getDouble(Double.doubleToLongBits(ad));
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return ((BigDecimal) a).negate();
+
+            case Types.TINYINT : {
+                int value = ((Number) a).intValue();
+
+                if (value == Byte.MIN_VALUE) {
+                    throw Error.error(ErrorCode.X_22003);
+                }
+
+                return ValuePool.getInt(-value);
+            }
+            case Types.SQL_SMALLINT : {
+                int value = ((Number) a).intValue();
+
+                if (value == Short.MIN_VALUE) {
+                    throw Error.error(ErrorCode.X_22003);
+                }
+
+                return ValuePool.getInt(-value);
+            }
+            case Types.SQL_INTEGER : {
+                int value = ((Number) a).intValue();
+
+                if (value == Integer.MIN_VALUE) {
+                    throw Error.error(ErrorCode.X_22003);
+                }
+
+                return ValuePool.getInt(-value);
+            }
+            case Types.SQL_BIGINT : {
+                long value = ((Number) a).longValue();
+
+                if (value == Long.MIN_VALUE) {
+                    throw Error.error(ErrorCode.X_22003);
+                }
+
+                return ValuePool.getLong(-value);
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public int getNumericPrecisionInRadix() {
+
+        switch (typeCode) {
+
+            case Types.TINYINT :
+                return 8;
+
+            case Types.SQL_SMALLINT :
+                return 16;
+
+            case Types.SQL_INTEGER :
+                return 32;
+
+            case Types.SQL_BIGINT :
+                return 64;
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return 64;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return (int) precision;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public Type getIntegralType() {
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE :
+                return SQL_NUMERIC_DEFAULT_INT;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return scale == 0 ? this
+                                  : new NumberType(typeCode, precision, 0);
+
+            default :
+                return this;
+        }
+    }
+
+    public static boolean isZero(Object a) {
+
+        if (a instanceof BigDecimal) {
+            return ((BigDecimal) a).signum() == 0;
+        } else if (a instanceof Double) {
+            return ((Double) a).doubleValue() == 0 || ((Double) a).isNaN();
+        } else {
+            return ((Number) a).longValue() == 0;
+        }
+    }
+
+    public boolean isNegative(Object a) {
+
+        if (a == null) {
+            return false;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double ad = ((Number) a).doubleValue();
+
+                return ad < 0;
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return ((BigDecimal) a).signum() < 0;
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER :
+                return ((Number) a).intValue() < 0;
+
+            case Types.SQL_BIGINT :
+                return ((Number) a).longValue() < 0;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public int compareToZero(Object a) {
+
+        if (a == null) {
+            return 0;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double ad = ((Number) a).doubleValue();
+
+                return ad == 0 ? 0
+                               : ad < 0 ? -1
+                                        : 1;
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return ((BigDecimal) a).signum();
+
+            case Types.TINYINT :
+            case Types.SQL_SMALLINT :
+            case Types.SQL_INTEGER : {
+                int ai = ((Number) a).intValue();
+
+                return ai == 0 ? 0
+                               : ai < 0 ? -1
+                                        : 1;
+            }
+            case Types.SQL_BIGINT : {
+                long al = ((Number) a).longValue();
+
+                return al == 0 ? 0
+                               : al < 0 ? -1
+                                        : 1;
+            }
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+
+    public static long scaledDecimal(Object a, int scale) {
+
+        if (a == null) {
+            return 0;
+        }
+
+        if (scale == 0) {
+            return 0;
+        }
+
+        BigDecimal value = ((BigDecimal) a);
+
+        if (value.scale() == 0) {
+            return 0;
+        }
+
+        value = value.setScale(0, BigDecimal.ROUND_FLOOR);
+        value = ((BigDecimal) a).subtract(value);
+
+        return value.movePointRight(scale).longValue();
+    }
+
+    public static boolean isInLongLimits(BigDecimal result) {
+
+        if (NumberType.MIN_LONG.compareTo(result) > 0
+                || NumberType.MAX_LONG.compareTo(result) < 0) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public static boolean isInLongLimits(BigInteger result) {
+
+        if (MAX_LONG_BI.compareTo(result) < 0
+                || MIN_LONG_BI.compareTo(result) > 0) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public Object ceiling(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double ad = Math.ceil(((Double) a).doubleValue());
+
+                if (Double.isInfinite(ad)) {
+                    throw Error.error(ErrorCode.X_22003);
+                }
+
+                return ValuePool.getDouble(Double.doubleToLongBits(ad));
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                BigDecimal value = ((BigDecimal) a).setScale(0,
+                    BigDecimal.ROUND_CEILING);
+
+                return value;
+            }
+            default :
+                return a;
+        }
+    }
+
+    public Object floor(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        switch (typeCode) {
+
+            case Types.SQL_REAL :
+            case Types.SQL_FLOAT :
+            case Types.SQL_DOUBLE : {
+                double value = Math.floor(((Double) a).doubleValue());
+
+                if (Double.isInfinite(value)) {
+                    throw Error.error(ErrorCode.X_22003);
+                }
+
+                return ValuePool.getDouble(Double.doubleToLongBits(value));
+            }
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL : {
+                BigDecimal value = ((BigDecimal) a).setScale(0,
+                    BigDecimal.ROUND_FLOOR);
+
+                return value;
+            }
+
+            // fall through
+            default :
+                return a;
+        }
+    }
+
+    public Object truncate(Object a, int s) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (s >= scale) {
+            return a;
+        }
+
+        BigDecimal dec = convertToDecimal(a);
+
+        dec = dec.setScale(s, BigDecimal.ROUND_DOWN);
+        dec = dec.setScale(scale, BigDecimal.ROUND_DOWN);
+        a   = convertToDefaultType(null, dec);
+
+        return convertToTypeLimits(null, a);
+    }
+
+    public static NumberType getNumberType(int type, long precision,
+                                           int scale) {
+
+        switch (type) {
+
+            case Types.SQL_INTEGER :
+                return SQL_INTEGER;
+
+            case Types.SQL_SMALLINT :
+                return SQL_SMALLINT;
+
+            case Types.SQL_BIGINT :
+                return SQL_BIGINT;
+
+            case Types.TINYINT :
+                return TINYINT;
+
+            case Types.SQL_REAL :
+            case Types.SQL_DOUBLE :
+                return SQL_DOUBLE;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                return new NumberType(type, precision, scale);
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
+        }
+    }
+}
diff --git a/src/org/hsqldb/types/OtherType.java b/src/org/hsqldb/types/OtherType.java
new file mode 100644
index 0000000..7348270
--- /dev/null
+++ b/src/org/hsqldb/types/OtherType.java
@@ -0,0 +1,193 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import java.io.Serializable;
+
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.StringConverter;
+
+/**
+ * Type implementation for OTHER type.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public final class OtherType extends Type {
+
+    static final OtherType otherType = new OtherType();
+
+    private OtherType() {
+        super(Types.OTHER, Types.OTHER, 0, 0);
+    }
+
+    public int displaySize() {
+        return precision > Integer.MAX_VALUE ? Integer.MAX_VALUE
+                                             : (int) precision;
+    }
+
+    public int getJDBCTypeCode() {
+        return typeCode;
+    }
+
+    public Class getJDBCClass() {
+        return java.lang.Object.class;
+    }
+
+    public String getJDBCClassName() {
+        return "java.lang.Object";
+    }
+
+    public int getSQLGenericTypeCode() {
+
+        // return Types.SQL_UDT;
+        return typeCode;
+    }
+
+    public int typeCode() {
+
+        // return Types.SQL_UDT;
+        return typeCode;
+    }
+
+    public String getNameString() {
+        return Tokens.T_OTHER;
+    }
+
+    public String getDefinition() {
+        return Tokens.T_OTHER;
+    }
+
+    public Type getAggregateType(Type other) {
+
+        if (typeCode == other.typeCode) {
+            return this;
+        }
+
+        if (other == SQL_ALL_TYPES) {
+            return this;
+        }
+
+        throw Error.error(ErrorCode.X_42562);
+    }
+
+    public Type getCombinedType(Type other, int operation) {
+        return this;
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        return 0;
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+        return a;
+    }
+
+    // to review - if conversion is supported, then must be serializable and wappred
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+        return a;
+    }
+
+    public Object convertToDefaultType(SessionInterface session, Object a) {
+
+        if (a instanceof Serializable) {
+            return a;
+        }
+
+        throw Error.error(ErrorCode.X_42561);
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return StringConverter.byteArrayToHexString(
+            ((JavaObjectData) a).getBytes());
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        return StringConverter.byteArrayToSQLHexString(
+            ((JavaObjectData) a).getBytes());
+    }
+
+    public Object convertSQLToJava(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return ((JavaObjectData) a).getObject();
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+
+        if (otherType.typeCode == typeCode) {
+            return true;
+        }
+
+        if (otherType.typeCode == Types.SQL_ALL_TYPES) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean isObjectType() {
+        return true;
+    }
+
+    public static OtherType getOtherType() {
+        return otherType;
+    }
+}
diff --git a/src/org/hsqldb/types/RowType.java b/src/org/hsqldb/types/RowType.java
new file mode 100644
index 0000000..d6d2826
--- /dev/null
+++ b/src/org/hsqldb/types/RowType.java
@@ -0,0 +1,351 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.OpTypes;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.Tokens;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Class for ROW type objects.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 2.0.0
+ * @since 2.0.0
+ */
+public class RowType extends Type {
+
+    final Type[] dataTypes;
+
+    public RowType(Type[] dataTypes) {
+
+        super(Types.SQL_ROW, Types.SQL_ROW, 0, 0);
+
+        this.dataTypes = dataTypes;
+    }
+
+    public int displaySize() {
+        return 0;
+    }
+
+    public int getJDBCTypeCode() {
+        return Types.NULL;
+    }
+
+    public Class getJDBCClass() {
+        return java.sql.ResultSet.class;
+    }
+
+    public String getJDBCClassName() {
+        return "java.sql.ResultSet";
+    }
+
+    public Integer getJDBCScale() {
+        return ValuePool.INTEGER_0;
+    }
+
+    public int getJDBCPrecision() {
+        return ValuePool.INTEGER_0;
+    }
+
+    public int getSQLGenericTypeCode() {
+        return Types.SQL_ROW;
+    }
+
+    public boolean isRowType() {
+        return true;
+    }
+
+    public String getNameString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(Tokens.T_ROW);
+        sb.append('(');
+
+        for (int i = 0; i < dataTypes.length; i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+
+            sb.append(dataTypes[i].getNameString());
+        }
+
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    String getDefinition() {
+        return getNameString();
+    }
+
+    public int compare(Session session, Object a, Object b) {
+
+        if (a == b) {
+            return 0;
+        }
+
+        if (a == null) {
+            return -1;
+        }
+
+        if (b == null) {
+            return 1;
+        }
+
+        Object[] arra   = (Object[]) a;
+        Object[] arrb   = (Object[]) b;
+        int      length = arra.length;
+
+        if (arrb.length < length) {
+            length = arrb.length;
+        }
+
+        for (int i = 0; i < length; i++) {
+            int result = dataTypes[i].compare(session, arra[i], arrb[i]);
+
+            if (result != 0) {
+                return result;
+            }
+        }
+
+        if (arra.length > arrb.length) {
+            return 1;
+        } else if (arra.length < arrb.length) {
+            return -1;
+        }
+
+        return 0;
+    }
+
+    public Object convertToTypeLimits(SessionInterface session, Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        Object[] arra = (Object[]) a;
+        Object[] arrb = new Object[arra.length];
+
+        for (int i = 0; i < arra.length; i++) {
+            arrb[i] = dataTypes[i].convertToTypeLimits(session, arra[i]);
+        }
+
+        return arrb;
+    }
+
+    public Object convertToType(SessionInterface session, Object a,
+                                Type otherType) {
+
+        if (a == null) {
+            return null;
+        }
+
+        if (otherType == null) {
+            return a;
+        }
+
+        if (!otherType.isRowType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        Type[]   otherTypes = ((RowType) otherType).getTypesArray();
+
+        if (dataTypes.length != otherTypes.length) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        Object[] arra       = (Object[]) a;
+        Object[] arrb       = new Object[arra.length];
+
+        for (int i = 0; i < arra.length; i++) {
+            arrb[i] = dataTypes[i].convertToType(session, arra[i],
+                                                 otherTypes[i]);
+        }
+
+        return arrb;
+    }
+
+    public Object convertToDefaultType(SessionInterface sessionInterface,
+                                       Object o) {
+        return o;
+    }
+
+    public String convertToString(Object a) {
+
+        if (a == null) {
+            return null;
+        }
+
+        return convertToSQLString(a);
+    }
+
+    public String convertToSQLString(Object a) {
+
+        if (a == null) {
+            return Tokens.T_NULL;
+        }
+
+        Object[]     arra = (Object[]) a;
+        StringBuffer sb   = new StringBuffer();
+
+        sb.append(Tokens.T_ROW);
+        sb.append('(');
+
+        for (int i = 0; i < arra.length; i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+
+            sb.append(dataTypes[i].convertToSQLString(arra[i]));
+        }
+
+        sb.append(')');
+
+        return sb.toString();
+    }
+
+    public boolean canConvertFrom(Type otherType) {
+
+        if (otherType == null) {
+            return true;
+        }
+
+        if (!otherType.isRowType()) {
+            return false;
+        }
+
+        Type[] otherTypes = ((RowType) otherType).getTypesArray();
+
+        if (dataTypes.length != otherTypes.length) {
+            return false;
+        }
+
+        for (int i = 0; i < dataTypes.length; i++) {
+            if (!dataTypes[i].canConvertFrom(otherTypes[i])) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public boolean canBeAssignedFrom(Type otherType) {
+
+        if (otherType == null) {
+            return true;
+        }
+
+        if (!otherType.isRowType()) {
+            return false;
+        }
+
+        Type[] otherTypes = ((RowType) otherType).getTypesArray();
+
+        if (dataTypes.length != otherTypes.length) {
+            return false;
+        }
+
+        for (int i = 0; i < dataTypes.length; i++) {
+            if (!dataTypes[i].canBeAssignedFrom(otherTypes[i])) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public Type getAggregateType(Type otherType) {
+
+        if (otherType == null) {
+            return this;
+        }
+
+        if (otherType == this) {
+            return this;
+        }
+
+        if (!otherType.isRowType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        Type[] newTypes   = new Type[dataTypes.length];
+        Type[] otherTypes = ((RowType) otherType).getTypesArray();
+
+        if (dataTypes.length != otherTypes.length) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        for (int i = 0; i < dataTypes.length; i++) {
+            newTypes[i] = dataTypes[i].getAggregateType(otherTypes[i]);
+        }
+
+        return new RowType(newTypes);
+    }
+
+    public Type getCombinedType(Type otherType, int operation) {
+
+        if (operation != OpTypes.CONCAT) {
+            return getAggregateType(otherType);
+        }
+
+        if (otherType == null) {
+            return this;
+        }
+
+        if (!otherType.isRowType()) {
+            throw Error.error(ErrorCode.X_42562);
+        }
+
+        Type[] newTypes   = new Type[dataTypes.length];
+        Type[] otherTypes = ((RowType) otherType).getTypesArray();
+
+        if (dataTypes.length != otherTypes.length) {
+            throw Error.error(ErrorCode.X_42564);
+        }
+
+        for (int i = 0; i < dataTypes.length; i++) {
+            newTypes[i] = dataTypes[i].getAggregateType(otherTypes[i]);
+        }
+
+        return new RowType(newTypes);
+    }
+
+    public Type[] getTypesArray() {
+        return dataTypes;
+    }
+}
diff --git a/src/org/hsqldb/types/TimeData.java b/src/org/hsqldb/types/TimeData.java
new file mode 100644
index 0000000..2e61141
--- /dev/null
+++ b/src/org/hsqldb/types/TimeData.java
@@ -0,0 +1,108 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+/**
+ * Implementation of data item for TIME.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class TimeData {
+
+    final int zone;
+    final int seconds;
+    final int nanos;
+
+    public TimeData(int seconds, int nanos, int zoneSeconds) {
+
+        while (seconds < 0) {
+            seconds += 24 * 60 * 60;
+        }
+
+        if (seconds > 24 * 60 * 60) {
+            seconds %= 24 * 60 * 60;
+        }
+
+        this.zone    = zoneSeconds;
+        this.seconds = seconds;
+        this.nanos   = nanos;
+    }
+
+    public TimeData(int seconds, int nanos) {
+        this (seconds, nanos, 0);
+    }
+
+    public int getSeconds() {
+        return seconds;
+    }
+
+    public int getNanos() {
+        return nanos;
+    }
+
+    public int getZone() {
+        return zone;
+    }
+
+    public boolean equals(Object other) {
+
+        if (other instanceof TimeData) {
+            return seconds == ((TimeData) other).seconds
+                   && nanos == ((TimeData) other).nanos
+                   && zone ==  ((TimeData) other).zone ;
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+        return seconds ^ nanos;
+    }
+
+    public int compareTo(TimeData b) {
+
+        long diff = seconds - b.seconds;
+
+        if (diff == 0) {
+            diff = nanos - b.nanos;
+
+            if (diff == 0) {
+                return 0;
+            }
+        }
+
+        return diff > 0 ? 1
+                        : -1;
+    }
+}
diff --git a/src/org/hsqldb/types/TimestampData.java b/src/org/hsqldb/types/TimestampData.java
new file mode 100644
index 0000000..187b999
--- /dev/null
+++ b/src/org/hsqldb/types/TimestampData.java
@@ -0,0 +1,110 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+/**
+ * Implementation of data item for TIMESTAMP.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class TimestampData {
+
+    final long seconds;
+    final int  nanos;
+    final int  zone;
+
+    public TimestampData(long seconds) {
+
+        this.seconds = seconds;
+        this.nanos   = 0;
+        this.zone    = 0;
+    }
+
+    public TimestampData(long seconds, int nanos) {
+
+        this.seconds = seconds;
+        this.nanos   = nanos;
+        this.zone    = 0;
+    }
+
+    public TimestampData(long seconds, int nanos, int zoneSeconds) {
+
+        this.seconds = seconds;
+        this.nanos   = nanos;
+        this.zone    = zoneSeconds;
+    }
+
+    public long getSeconds() {
+        return seconds;
+    }
+
+    public int getNanos() {
+        return nanos;
+    }
+
+    public int getZone() {
+        return zone;
+    }
+
+    public boolean equals(Object other) {
+
+        if (other instanceof TimestampData) {
+            return seconds == ((TimestampData) other).seconds
+                   && nanos == ((TimestampData) other).nanos
+                   && zone == ((TimestampData) other).zone;
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+        return (int) seconds ^ nanos;
+    }
+
+    public int compareTo(TimestampData b) {
+
+        long diff = seconds - b.seconds;
+
+        if (diff == 0) {
+            diff = nanos - b.nanos;
+
+            if (diff == 0) {
+                return 0;
+            }
+        }
+
+        return diff > 0 ? 1
+                        : -1;
+    }
+}
diff --git a/src/org/hsqldb/types/Type.java b/src/org/hsqldb/types/Type.java
new file mode 100644
index 0000000..f89675b
--- /dev/null
+++ b/src/org/hsqldb/types/Type.java
@@ -0,0 +1,1047 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Session;
+import org.hsqldb.SessionInterface;
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.rights.Grantee;
+import org.hsqldb.store.ValuePool;
+
+/**
+ * Base class for type objects.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public abstract class Type implements SchemaObject, Cloneable {
+
+    public final static Type[] emptyArray = new Type[]{};
+
+    //
+    public final int        typeComparisonGroup;
+    public final int        typeCode;
+    public final long       precision;
+    public final int        scale;
+    public UserTypeModifier userTypeModifier;
+
+    //
+    public final static int defaultArrayCardinality = 1024;
+
+    //
+    Type(int typeGroup, int type, long precision, int scale) {
+
+        this.typeComparisonGroup = typeGroup;
+        this.typeCode            = type;
+        this.precision           = precision;
+        this.scale               = scale;
+    }
+
+    // interface specific methods
+    public final int getType() {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        return userTypeModifier.getType();
+    }
+
+    public final HsqlName getName() {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        return userTypeModifier.getName();
+    }
+
+    public final HsqlName getCatalogName() {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        return userTypeModifier.getSchemaName().schema;
+    }
+
+    public final HsqlName getSchemaName() {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        return userTypeModifier.getSchemaName();
+    }
+
+    public final Grantee getOwner() {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        return userTypeModifier.getOwner();
+    }
+
+    public final OrderedHashSet getReferences() {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        return userTypeModifier.getReferences();
+    }
+
+    public final OrderedHashSet getComponents() {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        return userTypeModifier.getComponents();
+    }
+
+    public final void compile(Session session, SchemaObject parentObject) {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        userTypeModifier.compile(session);
+    }
+
+    /**
+     *  Retrieves the SQL character sequence required to (re)create the
+     *  trigger, as a StringBuffer
+     *
+     * @return the SQL character sequence required to (re)create the
+     *  trigger
+     */
+    public String getSQL() {
+
+        if (userTypeModifier == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+
+        return userTypeModifier.getSQL();
+    }
+
+    public long getChangeTimestamp() {
+        return 0;
+    }
+
+    public Type duplicate() {
+
+        try {
+            return (Type) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+    }
+
+    public abstract int displaySize();
+
+    /**
+     * Returns the JDBC type number of type, if it exists,
+     * otherwise the HSQLDB / SQL type.
+     */
+    public abstract int getJDBCTypeCode();
+
+    /**
+     * Returns the JDBC class name of type, if it exists,
+     * otherwise the HSQLDB class name.
+     */
+    public abstract String getJDBCClassName();
+
+    public abstract Class getJDBCClass();
+
+    public Integer getJDBCScale() {
+        return acceptsScale() ? ValuePool.getInt(scale)
+                              : null;
+    }
+
+    public int getJDBCPrecision() {
+        return precision > Integer.MAX_VALUE ? Integer.MAX_VALUE
+                                             : (int) precision;
+    }
+
+    /**
+     * Returns the generic SQL CLI type number of type, if it exists,
+     * otherwise the HSQLDB type. The generic type is returned for DATETIME
+     * and INTERVAL types.
+     */
+    public int getSQLGenericTypeCode() {
+        return typeCode;
+    }
+
+    /**
+     * Returns the name of the type
+     */
+    public abstract String getNameString();
+
+    /**
+     * Returns the name of the type
+     */
+    public String getFullNameString() {
+        return getNameString();
+    }
+
+    /**
+     * Returns the full definition of the type, including parameters
+     */
+    abstract String getDefinition();
+
+    public final String getTypeDefinition() {
+
+        if (userTypeModifier == null) {
+            return getDefinition();
+        }
+
+        return getName().getSchemaQualifiedStatementName();
+    }
+
+    public abstract int compare(Session session, Object a, Object b);
+
+    public abstract Object convertToTypeLimits(SessionInterface session,
+            Object a);
+
+    /**
+     * Explicit casts are handled by this method.
+     * SQL standard 6.12 rules for enforcement of size, precision and scale
+     * are implemented. For CHARACTER values, it performs truncation in all
+     * cases of long strings.
+     */
+    public Object castToType(SessionInterface session, Object a, Type type) {
+        return convertToType(session, a, type);
+    }
+
+    /**
+     * Same as castToType except for CHARACTER values. Perform string
+     * truncation of trailing spaces only. For other long strings, it raises
+     * an exception.
+     */
+    public abstract Object convertToType(SessionInterface session, Object a,
+                                         Type type);
+
+    /**
+     * Convert type for JDBC reads. Same as convertToType, but supports non-standard
+     * SQL conversions supported by JDBC
+     */
+    public Object convertToTypeJDBC(SessionInterface session, Object a,
+                                    Type otherType) {
+
+        if (otherType.isLobType()) {
+            throw Error.error(ErrorCode.X_42561);
+        }
+
+        return convertToType(session, a, otherType);
+    }
+
+    public Object convertJavaToSQL(SessionInterface session, Object a) {
+        return a;
+    }
+
+    public Object convertSQLToJava(SessionInterface session, Object a) {
+        return a;
+    }
+
+    /**
+     * Converts the object to the given type without limit checks. Used for JDBC writes.
+     */
+    public abstract Object convertToDefaultType(
+        SessionInterface sessionInterface, Object o);
+
+    public abstract String convertToString(Object a);
+
+    public abstract String convertToSQLString(Object a);
+
+    public abstract boolean canConvertFrom(Type otherType);
+
+    public boolean canBeAssignedFrom(Type otherType) {
+
+        return otherType == null ? true
+                                 : this.typeComparisonGroup
+                                   == otherType.typeComparisonGroup;
+    }
+
+    public int arrayLimitCardinality() {
+        return 0;
+    }
+
+    public Type collectionBaseType() {
+        return null;
+    }
+
+    public boolean isArrayType() {
+        return false;
+    }
+
+    public boolean isMultisetType() {
+        return false;
+    }
+
+    public boolean isRowType() {
+        return false;
+    }
+
+    public boolean isStructuredType() {
+        return false;
+    }
+
+    public boolean isCharacterType() {
+        return false;
+    }
+
+    public boolean isNumberType() {
+        return false;
+    }
+
+    public boolean isIntegralType() {
+        return false;
+    }
+
+    public boolean isExactNumberType() {
+        return false;
+    }
+
+    public boolean isDateTimeType() {
+        return false;
+    }
+
+    public boolean isDateTimeTypeWithZone() {
+        return false;
+    }
+
+    public boolean isIntervalType() {
+        return false;
+    }
+
+    public boolean isBinaryType() {
+        return false;
+    }
+
+    public boolean isBooleanType() {
+        return false;
+    }
+
+    public boolean isLobType() {
+        return false;
+    }
+
+    public boolean isBitType() {
+        return false;
+    }
+
+    public boolean isObjectType() {
+        return false;
+    }
+
+    public boolean isDistinctType() {
+
+        return userTypeModifier == null ? false
+                                        : userTypeModifier.schemaObjectType
+                                          == SchemaObject.TYPE;
+    }
+
+    public boolean isDomainType() {
+
+        return userTypeModifier == null ? false
+                                        : userTypeModifier.schemaObjectType
+                                          == SchemaObject.DOMAIN;
+    }
+
+    public boolean acceptsPrecision() {
+        return false;
+    }
+
+    public boolean requiresPrecision() {
+        return false;
+    }
+
+    public long getMaxPrecision() {
+        return 0;
+    }
+
+    public int getMaxScale() {
+        return 0;
+    }
+
+    public int getPrecisionRadix() {
+        return 0;
+    }
+
+    public boolean acceptsFractionalPrecision() {
+        return false;
+    }
+
+    public boolean acceptsScale() {
+        return false;
+    }
+
+    public int precedenceDegree(Type other) {
+
+        if (other.typeCode == typeCode) {
+            return 0;
+        }
+
+        return Integer.MIN_VALUE;
+    }
+
+    /**
+     * Common type used in comparison opertions. other must be comparable
+     * with this.
+     */
+    public abstract Type getAggregateType(Type other);
+
+    /**
+     * Result type of combining values of two types in different opertions.
+     * other type is not allways comparable with this, but a operation should
+     * be valid without any explicit CAST
+     */
+    public abstract Type getCombinedType(Type other, int operation);
+
+    public int compareToTypeRange(Object o) {
+        return 0;
+    }
+
+    /**
+     * All arithmetic ops are called on the pre-determined Type object of the result
+     */
+    public Object absolute(Object a) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+    }
+
+    public Object negate(Object a) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+    }
+
+    public Object add(Object a, Object b, Type otherType) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+    }
+
+    public Object subtract(Object a, Object b, Type otherType) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+    }
+
+    public Object multiply(Object a, Object b) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+    }
+
+    public Object divide(Object a, Object b) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+    }
+
+    public Object concat(Session session, Object a, Object b) {
+        throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+    }
+
+    public int cardinality(Session session, Object a) {
+        return 0;
+    }
+
+    public boolean equals(Object other) {
+
+        if (other == this) {
+            return true;
+        }
+
+        if (other instanceof Type) {
+            return ((Type) other).typeCode == typeCode
+                   && ((Type) other).precision == precision
+                   && ((Type) other).scale == scale
+                   && ((Type) other).userTypeModifier == userTypeModifier;
+        }
+
+        return false;
+    }
+
+    public int hashCode() {
+        return typeCode + (int) precision << 8 + scale << 16;
+    }
+
+    /** @todo 1.9.0 - review all needs max implementation defined lengths, used for parameters */
+
+    // null type
+    public static final Type SQL_ALL_TYPES = NullType.getNullType();
+
+    // character types
+    public static final CharacterType SQL_CHAR =
+        new CharacterType(Types.SQL_CHAR, 1);
+    public static final CharacterType SQL_CHAR_DEFAULT =
+        new CharacterType(Types.SQL_CHAR, CharacterType.defaultCharPrecision);
+    public static final CharacterType SQL_VARCHAR =
+        new CharacterType(Types.SQL_VARCHAR, 0);
+    public static final CharacterType SQL_VARCHAR_DEFAULT =
+        new CharacterType(Types.SQL_VARCHAR,
+                          CharacterType.defaultCharPrecision);
+    public static final ClobType SQL_CLOB =
+        new ClobType(ClobType.defaultClobSize);
+    public static final CharacterType VARCHAR_IGNORECASE =
+        new CharacterType(Types.VARCHAR_IGNORECASE, 0);
+    public static final CharacterType VARCHAR_IGNORECASE_DEFAULT =
+        new CharacterType(Types.VARCHAR_IGNORECASE,
+                          CharacterType.defaultCharPrecision);
+
+    // binary types
+    public static final BitType SQL_BIT = new BitType(Types.SQL_BIT, 1);
+    public static final BitType SQL_BIT_VARYING =
+        new BitType(Types.SQL_BIT_VARYING, 1);
+    public static final BitType SQL_BIT_VARYING_MAX_LENGTH =
+        new BitType(Types.SQL_BIT_VARYING, BitType.maxBitPrecision);
+
+    // binary types
+    public static final BinaryType SQL_BINARY =
+        new BinaryType(Types.SQL_BINARY, 1);
+    public static final BinaryType SQL_BINARY_DEFAULT =
+        new BinaryType(Types.SQL_BINARY, 32 * 1024);
+    public static final BinaryType SQL_VARBINARY =
+        new BinaryType(Types.SQL_VARBINARY, 0);
+    public static final BinaryType SQL_VARBINARY_DEFAULT =
+        new BinaryType(Types.SQL_VARBINARY, 32 * 1024);
+    public static final BlobType SQL_BLOB =
+        new BlobType(BlobType.defaultBlobSize);
+
+    // other type
+    public static final OtherType OTHER = OtherType.getOtherType();
+
+    // boolean type
+    public static final BooleanType SQL_BOOLEAN = BooleanType.getBooleanType();
+
+    // number types
+    public static final NumberType SQL_NUMERIC =
+        new NumberType(Types.SQL_NUMERIC, NumberType.defaultNumericPrecision,
+                       0);
+    public static final NumberType SQL_DECIMAL =
+        new NumberType(Types.SQL_DECIMAL, NumberType.defaultNumericPrecision,
+                       0);
+    public static final NumberType SQL_DECIMAL_DEFAULT =
+        new NumberType(Types.SQL_DECIMAL, NumberType.defaultNumericPrecision,
+                       NumberType.defaultNumericScale);
+    public static final NumberType SQL_DECIMAL_BIGINT_SQR =
+        new NumberType(Types.SQL_DECIMAL,
+                       NumberType.bigintSquareNumericPrecision, 0);
+    public static final NumberType SQL_DOUBLE =
+        new NumberType(Types.SQL_DOUBLE, 0, 0);
+
+    //
+    public static final NumberType TINYINT = new NumberType(Types.TINYINT,
+        NumberType.tinyintPrecision, 0);
+    public static final NumberType SQL_SMALLINT =
+        new NumberType(Types.SQL_SMALLINT, NumberType.smallintPrecision, 0);
+    public static final NumberType SQL_INTEGER =
+        new NumberType(Types.SQL_INTEGER, NumberType.integerPrecision, 0);
+    public static final NumberType SQL_BIGINT =
+        new NumberType(Types.SQL_BIGINT, NumberType.bigintPrecision, 0);
+
+    // date time
+    public static final DateTimeType SQL_DATE =
+        new DateTimeType(Types.SQL_TIMESTAMP, Types.SQL_DATE, 0);
+    public static final DateTimeType SQL_TIME =
+        new DateTimeType(Types.SQL_TIME, Types.SQL_TIME,
+                         DTIType.defaultTimeFractionPrecision);
+    public static final DateTimeType SQL_TIME_WITH_TIME_ZONE =
+        new DateTimeType(Types.SQL_TIME, Types.SQL_TIME_WITH_TIME_ZONE,
+                         DTIType.defaultTimeFractionPrecision);
+    public static final DateTimeType SQL_TIMESTAMP =
+        new DateTimeType(Types.SQL_TIMESTAMP, Types.SQL_TIMESTAMP,
+                         DTIType.defaultTimestampFractionPrecision);
+    public static final DateTimeType SQL_TIMESTAMP_WITH_TIME_ZONE =
+        new DateTimeType(Types.SQL_TIMESTAMP,
+                         Types.SQL_TIMESTAMP_WITH_TIME_ZONE,
+                         DTIType.defaultTimestampFractionPrecision);
+    public static final DateTimeType SQL_TIMESTAMP_NO_FRACTION =
+        new DateTimeType(Types.SQL_TIMESTAMP, Types.SQL_TIMESTAMP, 0);
+
+    // interval
+    public static final IntervalType SQL_INTERVAL_YEAR =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_YEAR,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_MONTH =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_MONTH,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_DAY =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_DAY,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_HOUR =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_HOUR,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_MINUTE =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_MINUTE,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_SECOND =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_SECOND,
+                                     DTIType.defaultIntervalPrecision,
+                                     DTIType.defaultIntervalFractionPrecision);
+    public static final IntervalType SQL_INTERVAL_SECOND_MAX_FRACTION =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_SECOND,
+                                     DTIType.defaultIntervalPrecision,
+                                     DTIType.maxFractionPrecision);
+    public static final IntervalType SQL_INTERVAL_YEAR_TO_MONTH =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_YEAR_TO_MONTH,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_DAY_TO_HOUR =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_DAY_TO_HOUR,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_DAY_TO_MINUTE =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_DAY_TO_MINUTE,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_DAY_TO_SECOND =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_DAY_TO_SECOND,
+                                     DTIType.defaultIntervalPrecision,
+                                     DTIType.defaultIntervalFractionPrecision);
+    public static final IntervalType SQL_INTERVAL_HOUR_TO_MINUTE =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_HOUR_TO_MINUTE,
+                                     DTIType.defaultIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_HOUR_TO_SECOND =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_HOUR_TO_SECOND,
+                                     DTIType.defaultIntervalPrecision,
+                                     DTIType.defaultIntervalFractionPrecision);
+    public static final IntervalType SQL_INTERVAL_MINUTE_TO_SECOND =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_MINUTE_TO_SECOND,
+                                     DTIType.defaultIntervalPrecision,
+                                     DTIType.defaultIntervalFractionPrecision);
+
+    //
+    public static final IntervalType SQL_INTERVAL_YEAR_MAX_PRECISION =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_YEAR,
+                                     DTIType.maxIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_MONTH_MAX_PRECISION =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_MONTH,
+                                     DTIType.maxIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_DAY_MAX_PRECISION =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_DAY,
+                                     DTIType.maxIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_HOUR_MAX_PRECISION =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_HOUR,
+                                     DTIType.maxIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_MINUTE_MAX_PRECISION =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_MINUTE,
+                                     DTIType.maxIntervalPrecision, 0);
+    public static final IntervalType SQL_INTERVAL_SECOND_MAX_PRECISION =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_SECOND,
+                                     DTIType.maxIntervalPrecision,
+                                     DTIType.defaultIntervalFractionPrecision);
+    public static final IntervalType SQL_INTERVAL_SECOND_MAX_FRACTION_MAX_PRECISION =
+        IntervalType.newIntervalType(Types.SQL_INTERVAL_SECOND,
+                                     DTIType.maxIntervalPrecision,
+                                     DTIType.maxFractionPrecision);
+
+    //
+    public static final ArrayType SQL_ARRAY_ALL_TYPES =
+        new ArrayType(SQL_ALL_TYPES, 0);
+
+
+    public static ArrayType getDefaultArrayType(int type) {
+        return new ArrayType(getDefaultType(type), Type.defaultArrayCardinality);
+    }
+
+
+    public static Type getDefaultType(int type) {
+
+        try {
+            return getType(type, 0, 0, 0);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static Type getDefaultTypeWithSize(int type) {
+
+        switch (type) {
+
+            case Types.SQL_ALL_TYPES :
+                return SQL_ALL_TYPES;
+
+            case Types.SQL_CHAR :
+                return SQL_CHAR_DEFAULT;
+
+            case Types.SQL_VARCHAR :
+                return SQL_VARCHAR_DEFAULT;
+
+            case Types.VARCHAR_IGNORECASE :
+                return VARCHAR_IGNORECASE_DEFAULT;
+
+            case Types.SQL_CLOB :
+                return SQL_CLOB;
+
+            case Types.SQL_INTEGER :
+                return SQL_INTEGER;
+
+            case Types.SQL_SMALLINT :
+                return SQL_SMALLINT;
+
+            case Types.SQL_BIGINT :
+                return SQL_BIGINT;
+
+            case Types.TINYINT :
+                return TINYINT;
+
+            case Types.SQL_FLOAT :
+            case Types.SQL_REAL :
+            case Types.SQL_DOUBLE :
+                return SQL_DOUBLE;
+
+            case Types.SQL_NUMERIC :
+                return SQL_NUMERIC;
+
+            case Types.SQL_DECIMAL :
+                return SQL_DECIMAL;
+
+            case Types.SQL_BOOLEAN :
+                return SQL_BOOLEAN;
+
+            case Types.SQL_BINARY :
+                return SQL_BINARY_DEFAULT;
+
+            case Types.SQL_VARBINARY :
+                return SQL_VARBINARY_DEFAULT;
+
+            case Types.SQL_BLOB :
+                return SQL_BLOB;
+
+            case Types.SQL_BIT :
+                return SQL_BIT;
+
+            case Types.SQL_BIT_VARYING :
+                return SQL_BIT_VARYING;
+
+            case Types.SQL_DATE :
+                return SQL_DATE;
+
+            case Types.SQL_TIME :
+                return SQL_TIME;
+
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+                return SQL_TIME_WITH_TIME_ZONE;
+
+            case Types.SQL_TIMESTAMP :
+                return SQL_TIMESTAMP;
+
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return SQL_TIMESTAMP_WITH_TIME_ZONE;
+
+            case Types.SQL_INTERVAL_YEAR :
+                return SQL_INTERVAL_YEAR;
+
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+                return SQL_INTERVAL_YEAR_TO_MONTH;
+
+            case Types.SQL_INTERVAL_MONTH :
+                return SQL_INTERVAL_MONTH;
+
+            case Types.SQL_INTERVAL_DAY :
+                return SQL_INTERVAL_DAY;
+
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+                return SQL_INTERVAL_DAY_TO_HOUR;
+
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+                return SQL_INTERVAL_DAY_TO_MINUTE;
+
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+                return SQL_INTERVAL_DAY_TO_SECOND;
+
+            case Types.SQL_INTERVAL_HOUR :
+                return SQL_INTERVAL_HOUR;
+
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+                return SQL_INTERVAL_HOUR_TO_MINUTE;
+
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+                return SQL_INTERVAL_HOUR_TO_SECOND;
+
+            case Types.SQL_INTERVAL_MINUTE :
+                return SQL_INTERVAL_MINUTE;
+
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+                return SQL_INTERVAL_MINUTE_TO_SECOND;
+
+            case Types.SQL_INTERVAL_SECOND :
+                return SQL_INTERVAL_SECOND;
+
+            case Types.OTHER :
+                return OTHER;
+
+            default :
+                return null;
+        }
+    }
+
+    public static int getHSQLDBTypeCode(int jdbcTypeNumber) {
+
+        switch (jdbcTypeNumber) {
+
+            case Types.BIGINT :
+                return Types.SQL_BIGINT;
+
+            case Types.LONGVARCHAR :
+                return Types.SQL_VARCHAR;
+
+            case Types.CLOB :
+                return Types.SQL_CLOB;
+
+            case Types.BINARY :
+                return Types.SQL_BINARY;
+
+            case Types.BIT :
+                return Types.SQL_BIT_VARYING;
+
+            case Types.VARBINARY :
+            case Types.LONGVARBINARY :
+                return Types.SQL_VARBINARY;
+
+            case Types.BLOB :
+                return Types.SQL_BLOB;
+
+            default :
+                return jdbcTypeNumber;
+        }
+    }
+
+    /**
+     * translate an internal type number to JDBC type number if a type is not
+     * supported internally, it is returned without translation
+     *
+     * @param type int
+     * @return int
+     */
+    public static int getJDBCTypeCode(int type) {
+
+        switch (type) {
+
+            case Types.SQL_BLOB :
+                return Types.BLOB;
+
+            case Types.SQL_CLOB :
+                return Types.CLOB;
+
+            case Types.SQL_BIGINT :
+                return Types.BIGINT;
+
+            case Types.SQL_BINARY :
+                return Types.BINARY;
+
+            case Types.SQL_VARBINARY :
+                return Types.VARBINARY;
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                return Types.BIT;
+
+            default :
+                return type;
+        }
+    }
+
+    /**
+     * Enforces precision and scale limits on type
+     */
+    public static Type getType(int type, int collation, long precision,
+                               int scale) {
+
+        switch (type) {
+
+            case Types.SQL_ALL_TYPES :
+                return SQL_ALL_TYPES;
+
+//                return SQL_ALL_TYPES; // needs changes to Expression type resolution
+            case Types.SQL_CHAR :
+            case Types.SQL_VARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+            case Types.SQL_CLOB :
+                return CharacterType.getCharacterType(type, precision);
+
+            case Types.SQL_INTEGER :
+                return SQL_INTEGER;
+
+            case Types.SQL_SMALLINT :
+                return SQL_SMALLINT;
+
+            case Types.SQL_BIGINT :
+                return SQL_BIGINT;
+
+            case Types.TINYINT :
+                return TINYINT;
+
+            case Types.SQL_FLOAT :
+                if (precision > 53) {
+                    throw Error.error(ErrorCode.X_42592, "" + precision);
+                }
+
+            // fall through
+            case Types.SQL_REAL :
+            case Types.SQL_DOUBLE :
+                return SQL_DOUBLE;
+
+            case Types.SQL_NUMERIC :
+            case Types.SQL_DECIMAL :
+                if (precision == 0) {
+                    precision = NumberType.defaultNumericPrecision;
+                }
+
+                return NumberType.getNumberType(type, precision, scale);
+
+            case Types.SQL_BOOLEAN :
+                return SQL_BOOLEAN;
+
+            case Types.SQL_BINARY :
+            case Types.SQL_VARBINARY :
+            case Types.SQL_BLOB :
+                return BinaryType.getBinaryType(type, precision);
+
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+                return BitType.getBitType(type, precision);
+
+            case Types.SQL_DATE :
+            case Types.SQL_TIME :
+            case Types.SQL_TIME_WITH_TIME_ZONE :
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
+                return DateTimeType.getDateTimeType(type, scale);
+
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                return IntervalType.getIntervalType(type, precision, scale);
+
+            case Types.OTHER :
+                return OTHER;
+
+            default :
+                throw Error.runtimeError(ErrorCode.U_S0500, "Type");
+        }
+    }
+
+    public static Type getAggregateType(Type add, Type existing) {
+
+        if (existing == null || existing.typeCode == Types.SQL_ALL_TYPES) {
+            return add;
+        }
+
+        if (add == null || add.typeCode == Types.SQL_ALL_TYPES) {
+            return existing;
+        }
+
+        return existing.getAggregateType(add);
+    }
+
+    public static final IntValueHashMap typeAliases;
+    public static final IntValueHashMap typeNames;
+
+    static {
+        typeNames = new IntValueHashMap(37);
+
+        typeNames.put("CHARACTER", Types.SQL_CHAR);
+        typeNames.put("VARCHAR", Types.SQL_VARCHAR);
+        typeNames.put("VARCHAR_IGNORECASE", Types.VARCHAR_IGNORECASE);
+        typeNames.put("DATE", Types.SQL_DATE);
+        typeNames.put("TIME", Types.SQL_TIME);
+        typeNames.put("TIMESTAMP", Types.SQL_TIMESTAMP);
+        typeNames.put("INTERVAL", Types.SQL_INTERVAL);
+        typeNames.put("TINYINT", Types.TINYINT);
+        typeNames.put("SMALLINT", Types.SQL_SMALLINT);
+        typeNames.put("INTEGER", Types.SQL_INTEGER);
+        typeNames.put("BIGINT", Types.SQL_BIGINT);
+        typeNames.put("REAL", Types.SQL_REAL);
+        typeNames.put("FLOAT", Types.SQL_FLOAT);
+        typeNames.put("DOUBLE", Types.SQL_DOUBLE);
+        typeNames.put("NUMERIC", Types.SQL_NUMERIC);
+        typeNames.put("DECIMAL", Types.SQL_DECIMAL);
+        typeNames.put("BOOLEAN", Types.SQL_BOOLEAN);
+        typeNames.put("BINARY", Types.SQL_BINARY);
+        typeNames.put("VARBINARY", Types.SQL_VARBINARY);
+        typeNames.put("CLOB", Types.SQL_CLOB);
+        typeNames.put("BLOB", Types.SQL_BLOB);
+        typeNames.put("BIT", Types.SQL_BIT);
+        typeNames.put("OTHER", Types.OTHER);
+
+        //
+        typeAliases = new IntValueHashMap(64);
+
+        typeAliases.put("CHAR", Types.SQL_CHAR);
+        typeAliases.put("INT", Types.SQL_INTEGER);
+        typeAliases.put("DEC", Types.SQL_DECIMAL);
+        typeAliases.put("LONGVARCHAR", Types.LONGVARCHAR);
+        typeAliases.put("DATETIME", Types.SQL_TIMESTAMP);
+        typeAliases.put("LONGVARBINARY", Types.LONGVARBINARY);
+        typeAliases.put("OBJECT", Types.OTHER);
+    }
+
+    public static int getTypeNr(String name) {
+
+        int i = typeNames.get(name, Integer.MIN_VALUE);
+
+        if (i == Integer.MIN_VALUE) {
+            i = typeAliases.get(name, Integer.MIN_VALUE);
+        }
+
+        return i;
+    }
+
+    public static boolean isSupportedSQLType(int typeNumber) {
+
+        if (getDefaultType(typeNumber) == null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public static boolean matches(Type[] one, Type[] other) {
+
+        for (int i = 0; i < one.length; i++) {
+            if (one[i].typeCode != other[i].typeCode) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/src/org/hsqldb/types/Types.java b/src/org/hsqldb/types/Types.java
new file mode 100644
index 0000000..fe35280
--- /dev/null
+++ b/src/org/hsqldb/types/Types.java
@@ -0,0 +1,820 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.error.Error;
+import org.hsqldb.error.ErrorCode;
+import org.hsqldb.lib.HashSet;
+import org.hsqldb.lib.IntValueHashMap;
+import org.hsqldb.persist.HsqlDatabaseProperties;
+
+// boucherb@users 20051207 - patch 1.8.x initial JDBC 4.0 support work
+
+/**
+ * Defines the constants that are used to identify SQL types for HSQLDB JDBC
+ * inteface type reporting. The actual type constant values are equivalent
+ * to those defined in the latest java.sql.Types, where available,
+ * or those defined by ansi/iso SQL 2003 otherwise. A type sub-identifer
+ * has been added to differentiate HSQLDB-specific type specializations.
+ *
+ * @author  boucherb@users
+ * @version 2.0.0
+ * @since 1.7.2
+ */
+public class Types {
+
+    /**
+     * Names of types returned by JDBC methods and accepted as
+     * library and user function arguments
+     */
+    public static final String DecimalClassName   = "java.math.BigDecimal";
+    public static final String DateClassName      = "java.sql.Date";
+    public static final String TimeClassName      = "java.sql.Time";
+    public static final String TimestampClassName = "java.sql.Timestamp";
+    public static final String BlobClassName      = "java.sql.Blob";
+    public static final String ClobClassName      = "java.sql.Clob";
+    /*
+     SQL specifies predefined data types named by the following <key word>s:
+     CHARACTER, CHARACTER VARYING, CHARACTER LARGE OBJECT, BINARY LARGE OBJECT,
+     NUMERIC, DECIMAL, SMALLINT, INTEGER, BIGINT, FLOAT, REAL, DOUBLE PRECISION,
+     BOOLEAN, DATE, TIME, TIMESTAMP, and INTERVAL. Also BINARY and VARBINARY
+     in SQL post-2003
+     SQL 2003 adds DATALINK in Part 9: Management of External Data (SQL/MED)
+     and adds XML in Part 14: XML-Related Specifications (SQL/XML)
+     */
+
+    // CLI type list from Table 37
+    public static final int SQL_CHAR              = 1;
+    public static final int SQL_NUMERIC           = 2;
+    public static final int SQL_DECIMAL           = 3;
+    public static final int SQL_INTEGER           = 4;
+    public static final int SQL_SMALLINT          = 5;
+    public static final int SQL_FLOAT             = 6;
+    public static final int SQL_REAL              = 7;
+    public static final int SQL_DOUBLE            = 8;
+    public static final int SQL_VARCHAR           = 12;
+    public static final int SQL_BOOLEAN           = 16;
+    public static final int SQL_USER_DEFINED_TYPE = 17;
+    public static final int SQL_ROW               = 19;
+    public static final int SQL_REF               = 20;
+    public static final int SQL_BIGINT            = 25;             // different in JDBC
+    public static final int SQL_BLOB              = 30;             // different in JDBC
+    public static final int SQL_CLOB              = 40;             // different in JDBC
+    public static final int SQL_ARRAY             = 50;             // different in JDBC - not predefined
+    public static final int SQL_MULTISET = 55;                      //
+    public static final int SQL_BINARY   = 60;                      // different in JDBC -in SQL post-2003
+    public static final int SQL_VARBINARY = 61;                     // different in JDBC - in SQL post-2003
+    public static final int SQL_DATE                      = 91;
+    public static final int SQL_TIME                      = 92;
+    public static final int SQL_TIMESTAMP                 = 93;     //
+    public static final int SQL_TIME_WITH_TIME_ZONE       = 94;
+    public static final int SQL_TIMESTAMP_WITH_TIME_ZONE  = 95;     //
+    public static final int SQL_INTERVAL_YEAR             = 101;    //
+    public static final int SQL_INTERVAL_MONTH            = 102;
+    public static final int SQL_INTERVAL_DAY              = 103;
+    public static final int SQL_INTERVAL_HOUR             = 104;
+    public static final int SQL_INTERVAL_MINUTE           = 105;
+    public static final int SQL_INTERVAL_SECOND           = 106;
+    public static final int SQL_INTERVAL_YEAR_TO_MONTH    = 107;
+    public static final int SQL_INTERVAL_DAY_TO_HOUR      = 108;
+    public static final int SQL_INTERVAL_DAY_TO_MINUTE    = 109;
+    public static final int SQL_INTERVAL_DAY_TO_SECOND    = 110;
+    public static final int SQL_INTERVAL_HOUR_TO_MINUTE   = 111;
+    public static final int SQL_INTERVAL_HOUR_TO_SECOND   = 112;
+    public static final int SQL_INTERVAL_MINUTE_TO_SECOND = 113;
+
+    // used where local defines are used in the same range as SQL type numbers
+    public static final int SQL_TYPE_NUMBER_LIMIT = 256;
+
+    // These values are not in table 37 of the SQL CLI 2003 FCD, but some
+    // are found in tables 6-9 and some are found in Annex A1:
+    // c Header File SQLCLI.H and/or addendums in other documents,
+    // such as:
+    // SQL 2003 Part 9: Management of External Data (SQL/MED) : DATALINK
+    // SQL 2003 Part 14: XML-Related Specifications (SQL/XML) : XML
+    public static final int SQL_BIT         = 14;                   // is in SQL99 but removed from 2003
+    public static final int SQL_BIT_VARYING = 15;                   // is in SQL99 but removed from 2003
+    public static final int SQL_DATALINK         = 70;
+    public static final int SQL_UDT              = 17;
+    public static final int SQL_UDT_LOCATOR      = 18;
+    public static final int SQL_BLOB_LOCATOR     = 31;
+    public static final int SQL_CLOB_LOCATOR     = 41;
+    public static final int SQL_ARRAY_LOCATOR    = 51;
+    public static final int SQL_MULTISET_LOCATOR = 56;
+    public static final int SQL_ALL_TYPES        = 0;
+    public static final int SQL_DATETIME         = 9;               // collective name
+    public static final int SQL_INTERVAL         = 10;              // collective name
+    public static final int SQL_XML              = 137;
+
+    // These values are taken from various SQL CLI header files
+    public static final int SQL_NCHAR         = (-8);
+    public static final int SQL_WCHAR         = (-8);
+    public static final int SQL_WVARCHAR      = (-9);
+    public static final int SQL_NVARCHAR      = (-9);
+    public static final int SQL_WLONGVARCHAR  = (-10);
+    public static final int SQL_NTEXT         = (-10);
+    public static final int SQL_LONGVARBINARY = (-4);
+    public static final int SQL_IMAGE         = (-4);
+    public static final int SQL_GUID          = (-11);
+    public static final int SQL_VARIANT       = (-150);
+
+    // SQL_UDT subcodes
+    public static final int SQL_SUB_DISTINCT   = 1;
+    public static final int SQL_SUB_STRUCTURED = 2;
+
+    // non-standard type not in JDBC or SQL CLI
+    public static final int VARCHAR_IGNORECASE = 100;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * <code>ARRAY</code>.
+     *
+     * @since JDK 1.2
+     */
+    public static final int ARRAY = 2003;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>BIGINT</code>.
+     */
+    public static final int BIGINT = -5;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>BINARY</code>.
+     */
+    public static final int BINARY = -2;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>BIT</code>.
+     */
+    public static final int BIT = -7;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * <code>BLOB</code>.
+     *
+     * @since JDK 1.2
+     */
+    public static final int BLOB = 2004;
+
+    /**
+     * The constant in the Java programming language, somtimes referred to
+     * as a type code, that identifies the generic SQL type
+     * <code>BOOLEAN</code>.
+     *
+     * @since JDK 1.4
+     */
+    public static final int BOOLEAN = SQL_BOOLEAN;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>CHAR</code>.
+     */
+    public static final int CHAR = SQL_CHAR;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * <code>CLOB</code>
+     *
+     * @since JDK 1.2
+     */
+    public static final int CLOB = 2005;
+
+    /**
+     * The constant in the Java programming language, somtimes referred to
+     * as a type code, that identifies the generic SQL type <code>DATALINK</code>.
+     *
+     * @since JDK 1.4
+     */
+    public static final int DATALINK = 70;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>DATE</code>.
+     */
+    public static final int DATE = SQL_DATE;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>DECIMAL</code>.
+     */
+    public static final int DECIMAL = SQL_DECIMAL;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * <code>DISTINCT</code>.
+     *
+     * @since JDK 1.2
+     */
+    public static final int DISTINCT = 2001;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>DOUBLE</code>.
+     */
+    public static final int DOUBLE = SQL_DOUBLE;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>FLOAT</code>.
+     */
+    public static final int FLOAT = SQL_FLOAT;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>INTEGER</code>.
+     */
+    public static final int INTEGER = SQL_INTEGER;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * <code>JAVA_OBJECT</code>.
+     *
+     * @since JDK 1.2
+     */
+    public static final int JAVA_OBJECT = 2000;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>LONGVARBINARY</code>.
+     */
+    public static final int LONGVARBINARY = -4;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>LONGVARCHAR</code>.
+     */
+    public static final int LONGVARCHAR = -1;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>MULTISET</code>.
+     */
+    public static final int MULTISET = 0;                           // no java.sql.Types definition
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>NULL</code>.
+     */
+    public static final int NULL = 0;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>NUMERIC</code>.
+     */
+    public static final int NUMERIC = SQL_NUMERIC;
+
+    /**
+     * The constant in the Java programming language that indicates
+     * that the SQL type is database-specific and
+     * gets mapped to a Java object that can be accessed via
+     * the methods <code>getObject</code> and <code>setObject</code>.
+     */
+    public static final int OTHER = 1111;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>REAL</code>.
+     */
+    public static final int REAL = SQL_REAL;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * <code>REF</code>.
+     *
+     * @since JDK 1.2
+     */
+    public static final int REF = 2006;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>SMALLINT</code>.
+     */
+    public static final int SMALLINT = SQL_SMALLINT;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * <code>STRUCT</code>.
+     *
+     * @since JDK 1.2
+     */
+    public static final int STRUCT = 2002;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>TIME</code>.
+     */
+    public static final int TIME = SQL_TIME;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>TIMESTAMP</code>.
+     */
+    public static final int TIMESTAMP = SQL_TIMESTAMP;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>TINYINT</code>.
+     */
+    public static final int TINYINT = -6;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>VARBINARY</code>.
+     */
+    public static final int VARBINARY = -3;
+
+    /**
+     * <P>The constant in the Java programming language, sometimes referred
+     * to as a type code, that identifies the generic SQL type
+     * <code>VARCHAR</code>.
+     */
+    public static final int VARCHAR = SQL_VARCHAR;
+
+//    /**
+//     * <P>The constant in the Java programming language, sometimes referred
+//     * to as a type code, that identifies the recent SQL 2003 SQL type
+//     * <code>XML</code>.
+//     *
+//     * @since SQL 2003
+//     * @deprectated
+//     * @see #SQLXML
+//     */
+//    public static final int XML = 137;
+    //------------------------- JDBC 4.0 -----------------------------------
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type <code>ROWID</code>
+     *
+     * @since JDK 1.6, HSQLDB 1.8.x
+     *
+     */
+    public final static int ROWID = 2008;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type <code>NCHAR</code>
+     *
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+    public static final int NCHAR = -8;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type <code>NVARCHAR</code>.
+     *
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+    public static final int NVARCHAR = -9;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type <code>LONGNVARCHAR</code>.
+     *
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+    public static final int LONGNVARCHAR = -10;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type <code>NCLOB</code>.
+     *
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+    public static final int NCLOB = 2007;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type <code>XML</code>.
+     *
+     * @since JDK 1.6, HSQLDB 1.8.x
+     */
+    public static final int SQLXML = 2009;
+
+    //----------------------------- End JDBC 4.0 -------------------------------
+
+    /**
+     * The default HSQLODB type sub-identifier. This indicates that an
+     * HSQLDB type with this sub-type, if supported, is the very closest
+     * thing HSQLDB offerers to the JDBC/SQL2003 type
+     */
+    public static final int TYPE_SUB_DEFAULT = 1;
+
+    /**
+     * The IGNORECASE type sub-identifier. This indicates that an HSQLDB type
+     * with this sub-type, if supported,  is the closest thing HSQLDB offerers
+     * to the JDBC/SQL2003 type, except that case is ignored in comparisons
+     */
+    public static final int TYPE_SUB_IGNORECASE = TYPE_SUB_DEFAULT << 2;
+
+    /**
+     * Every (type,type-sub) combination known in the HSQLDB context.
+     * Not every combination need be supported as a table or procedure
+     * column type -- such determinations are handled in DITypeInfo.
+     */
+    public static final int[][] ALL_TYPES = {
+        {
+            SQL_ARRAY, TYPE_SUB_DEFAULT
+        }, {
+            SQL_BIGINT, TYPE_SUB_DEFAULT
+        }, {
+            SQL_BINARY, TYPE_SUB_DEFAULT
+        }, {
+            SQL_VARBINARY, TYPE_SUB_DEFAULT
+        }, {
+            SQL_BLOB, TYPE_SUB_DEFAULT
+        }, {
+            SQL_BOOLEAN, TYPE_SUB_DEFAULT
+        }, {
+            SQL_CHAR, TYPE_SUB_DEFAULT
+        }, {
+            SQL_CLOB, TYPE_SUB_DEFAULT
+        }, {
+            DATALINK, TYPE_SUB_DEFAULT
+        }, {
+            SQL_DATE, TYPE_SUB_DEFAULT
+        }, {
+            SQL_DECIMAL, TYPE_SUB_DEFAULT
+        }, {
+            DISTINCT, TYPE_SUB_DEFAULT
+        }, {
+            SQL_DOUBLE, TYPE_SUB_DEFAULT
+        }, {
+            SQL_FLOAT, TYPE_SUB_DEFAULT
+        }, {
+            SQL_INTEGER, TYPE_SUB_DEFAULT
+        }, {
+            JAVA_OBJECT, TYPE_SUB_DEFAULT
+        }, {
+            SQL_NCHAR, TYPE_SUB_DEFAULT
+        }, {
+            NCLOB, TYPE_SUB_DEFAULT
+        }, {
+            SQL_ALL_TYPES, TYPE_SUB_DEFAULT
+        }, {
+            SQL_NUMERIC, TYPE_SUB_DEFAULT
+        }, {
+            SQL_NVARCHAR, TYPE_SUB_DEFAULT
+        }, {
+            OTHER, TYPE_SUB_DEFAULT
+        }, {
+            SQL_REAL, TYPE_SUB_DEFAULT
+        }, {
+            SQL_REF, TYPE_SUB_DEFAULT
+        }, {
+            ROWID, TYPE_SUB_DEFAULT
+        }, {
+            SQL_SMALLINT, TYPE_SUB_DEFAULT
+        }, {
+            STRUCT, TYPE_SUB_DEFAULT
+        }, {
+            SQL_TIME, TYPE_SUB_DEFAULT
+        }, {
+            SQL_TIMESTAMP, TYPE_SUB_DEFAULT
+        }, {
+            TINYINT, TYPE_SUB_DEFAULT
+        }, {
+            SQL_VARCHAR, TYPE_SUB_DEFAULT
+        }, {
+            SQL_VARCHAR, TYPE_SUB_IGNORECASE
+        }, {
+            SQL_XML, TYPE_SUB_DEFAULT
+        }
+    };
+
+// lookup for types
+    final static IntValueHashMap javaTypeNumbers;
+
+//  boucherb@users - We can't handle method invocations in
+//                   Function.java whose number class is
+//                   narrower than the corresponding internal
+//                   wrapper
+    private final static HashSet illegalParameterClasses;
+
+    static {
+        javaTypeNumbers = new IntValueHashMap(32);
+
+        javaTypeNumbers.put("int", Types.SQL_INTEGER);
+        javaTypeNumbers.put("java.lang.Integer", Types.SQL_INTEGER);
+        javaTypeNumbers.put("double", Types.SQL_DOUBLE);
+        javaTypeNumbers.put("java.lang.Double", Types.SQL_DOUBLE);
+        javaTypeNumbers.put("java.lang.String", Types.SQL_VARCHAR);
+        javaTypeNumbers.put(DateClassName, Types.SQL_DATE);
+        javaTypeNumbers.put(TimeClassName, Types.SQL_TIME);
+        javaTypeNumbers.put(TimestampClassName, Types.SQL_TIMESTAMP);
+        javaTypeNumbers.put("java.util.Date", Types.SQL_DATE);
+        javaTypeNumbers.put(DecimalClassName, Types.SQL_DECIMAL);
+        javaTypeNumbers.put("boolean", Types.SQL_BOOLEAN);
+        javaTypeNumbers.put("java.lang.Boolean", Types.SQL_BOOLEAN);
+        javaTypeNumbers.put("byte", Types.TINYINT);
+        javaTypeNumbers.put("java.lang.Byte", Types.TINYINT);
+        javaTypeNumbers.put("short", Types.SQL_SMALLINT);
+        javaTypeNumbers.put("java.lang.Short", Types.SQL_SMALLINT);
+        javaTypeNumbers.put("long", Types.SQL_BIGINT);
+        javaTypeNumbers.put("java.lang.Long", Types.SQL_BIGINT);
+        javaTypeNumbers.put("[B", Types.SQL_BINARY);
+        javaTypeNumbers.put("java.lang.Object", Types.OTHER);
+        javaTypeNumbers.put("java.lang.Void", Types.SQL_ALL_TYPES);
+
+        //
+        illegalParameterClasses = new org.hsqldb.lib.HashSet();
+
+        illegalParameterClasses.add(Byte.TYPE);
+        illegalParameterClasses.add(Short.TYPE);
+        illegalParameterClasses.add(Float.TYPE);
+        illegalParameterClasses.add(Byte.class);
+        illegalParameterClasses.add(Short.class);
+        illegalParameterClasses.add(Float.class);
+
+        //
+    }
+
+    /**
+     * Retieves the type number corresponding to the class
+     * of an IN, IN OUT or OUT parameter.  <p>
+     *
+     * This method extends getTypeNr to return OTHER for
+     * primitive arrays, classes that directly implement
+     * java.io.Serializable and non-primitive arrays whose
+     * base component implements java.io.Serializable,
+     * allowing, for instance, arguments and return types of
+     * primitive arrays, Serializable objects and arrays,
+     * of Serializable objects.  Direct primitive types
+     * other than those mapping directly to the internal
+     * wrapper form are not yet handled.  That is, HSQLDB
+     * cannot yet properly deal with CALLs involving methods
+     * with primitive byte, short, float or their
+     * corresponding wrappers, due to the way internal
+     * conversion works and lack of detection and narrowing
+     * code in Function to allow this.  In other words,
+     * passing in or retrieving any of the mentioned types
+     * always causes conversion to a wider internal wrapper
+     * which is genrally incompatible under reflective
+     * invocation, resulting in an IllegalArgumentException.
+     *
+     * @param  c a Class instance
+     * @return java.sql.Types int value
+     * @throws  HsqlException
+     */
+    public static Type getParameterSQLType(Class c) {
+
+        String  name;
+        int     typeCode;
+        boolean isArray;
+
+        if (c == null) {
+            throw Error.runtimeError(ErrorCode.U_S0500, "Types");
+        }
+
+        if (Void.TYPE.equals(c)) {
+            return Type.SQL_ALL_TYPES;
+        }
+
+        name     = c.getName();
+        typeCode = javaTypeNumbers.get(name, Integer.MIN_VALUE);
+
+        if (typeCode != Integer.MIN_VALUE) {
+            return Type.getDefaultTypeWithSize(typeCode);
+        }
+
+        if (c.isArray()) {
+            Class c1 = c.getComponentType();
+
+            name     = c1.getName();
+            typeCode = javaTypeNumbers.get(name, Integer.MIN_VALUE);
+
+            if (typeCode != Integer.MIN_VALUE) {
+                return Type.getDefaultTypeWithSize(typeCode);
+            }
+
+            if (typeCode == Types.SQL_ALL_TYPES) {
+                return null;
+            }
+
+            return Type.getDefaultTypeWithSize(typeCode);
+        }
+
+        return null;
+    }
+
+    public static boolean acceptsZeroPrecision(int type) {
+
+        switch (type) {
+
+            case Types.SQL_TIME :
+            case Types.SQL_TIMESTAMP :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    public static boolean requiresPrecision(int type) {
+
+        switch (type) {
+
+            case Types.SQL_BIT_VARYING :
+            case Types.SQL_VARBINARY :
+            case Types.SQL_VARCHAR :
+            case Types.SQL_NVARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    /**
+     * Types that accept precision params in column definition or casts.
+     * CHAR, VARCHAR and VARCHAR_IGNORECASE params
+     * are ignored when the sql.enforce_strict_types is false.
+     *
+     */
+    public static boolean acceptsPrecision(int type) {
+
+        switch (type) {
+
+            case Types.LONGVARCHAR :
+            case Types.LONGVARBINARY :
+            case Types.SQL_ARRAY :
+            case Types.SQL_BINARY :
+            case Types.SQL_BIT :
+            case Types.SQL_BIT_VARYING :
+            case Types.SQL_BLOB :
+            case Types.SQL_CHAR :
+            case Types.SQL_NCHAR :
+            case Types.SQL_CLOB :
+            case Types.NCLOB :
+            case Types.SQL_VARBINARY :
+            case Types.SQL_VARCHAR :
+            case Types.SQL_NVARCHAR :
+            case Types.VARCHAR_IGNORECASE :
+            case Types.SQL_DECIMAL :
+            case Types.SQL_NUMERIC :
+            case Types.SQL_FLOAT :
+            case Types.SQL_TIME :
+            case Types.SQL_TIMESTAMP :
+            case Types.SQL_INTERVAL_YEAR :
+            case Types.SQL_INTERVAL_YEAR_TO_MONTH :
+            case Types.SQL_INTERVAL_MONTH :
+            case Types.SQL_INTERVAL_DAY :
+            case Types.SQL_INTERVAL_DAY_TO_HOUR :
+            case Types.SQL_INTERVAL_DAY_TO_MINUTE :
+            case Types.SQL_INTERVAL_DAY_TO_SECOND :
+            case Types.SQL_INTERVAL_HOUR :
+            case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
+            case Types.SQL_INTERVAL_HOUR_TO_SECOND :
+            case Types.SQL_INTERVAL_MINUTE :
+            case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
+            case Types.SQL_INTERVAL_SECOND :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    public static boolean acceptsScaleCreateParam(int type) {
+
+        switch (type) {
+
+            case Types.SQL_INTERVAL_SECOND :
+                return true;
+
+            case Types.SQL_DECIMAL :
+            case Types.SQL_NUMERIC :
+                return true;
+
+            default :
+                return false;
+        }
+    }
+
+    /**
+     * A reasonable/customizable number to avoid the shortcomings/defects
+     * associated with doing a dynamic scan of results to determine
+     * the value.  In practice, it turns out that single query yielding
+     * widely varying values for display size of CHAR and VARCHAR columns
+     * on repeated execution results in patently poor usability, as some fairly
+     * high-profile, otherwise "enterprise-quality" RAD tools depend on
+     * on the first value returned to lay out forms and limit the size of
+     * single line edit controls, set corresponding local datastore storage
+     * sizes, etc. In practice, It also turns out that many tools (due to
+     * the original lack of PreparedStatement.getMetaData() in JDK 1.1) emulate
+     * a SQL_DESCRIBE by executing a query hopefully guaranteed to return no
+     * or very few rows for example: select ... from ... where 1=0.
+     * Using the dynamic scan of 1.7.2 RC5 and previous, therefore, the
+     * minimum display size value (1) was often being generated during
+     * a tool's describe phase.  Upon subsequent "real" retrievals, some
+     * tools complain that CHAR and VARCHAR result values exceeded the
+     * originally reported display size and refused to fetch further values.
+     */
+    public static final int MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE =
+        MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE();
+
+    // So that the variable can be both public static final and
+    // customizable through system properties if required.
+    //
+    // 32766 (0x7ffe) seems to be a magic number over which several
+    // rather high-profile RAD tools start to have problems
+    // regarding layout and allocation stress.  It is gently
+    // recommended that LONGVARCHAR be used for larger values in RAD
+    // tool layout & presentation use cases until such time as we provide
+    // true BLOB support (at which point, LONGVARCHAR will most likely become
+    // an alias for CLOB).
+    //
+    // Most GUI tools seem to handle LONGVARCHAR gracefully by:
+    //
+    // 1.) refusing to directly display such columns in graphical query results
+    // 2.) providing other means to retrieve and display such values
+    private static int MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE() {
+
+        try {
+            return Integer.getInteger(
+                HsqlDatabaseProperties.system_max_char_or_varchar_display_size,
+                32766).intValue();
+        } catch (SecurityException e) {
+            return 32766;
+        }
+    }
+
+    public static boolean isSearchable(int type) {
+
+        switch (type) {
+
+            case Types.SQL_BLOB :
+            case Types.SQL_CLOB :
+            case Types.NCLOB :
+            case Types.JAVA_OBJECT :
+            case Types.STRUCT :
+            case Types.OTHER :
+            case Types.ROWID :
+                return false;
+
+            case Types.SQL_ARRAY :
+            default :
+                return true;
+        }
+    }
+}
diff --git a/src/org/hsqldb/types/UserTypeModifier.java b/src/org/hsqldb/types/UserTypeModifier.java
new file mode 100644
index 0000000..c14933a
--- /dev/null
+++ b/src/org/hsqldb/types/UserTypeModifier.java
@@ -0,0 +1,224 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.types;
+
+import org.hsqldb.Constraint;
+import org.hsqldb.Expression;
+import org.hsqldb.HsqlNameManager;
+import org.hsqldb.HsqlNameManager.HsqlName;
+import org.hsqldb.SchemaObject;
+import org.hsqldb.Session;
+import org.hsqldb.Tokens;
+import org.hsqldb.lib.ArrayUtil;
+import org.hsqldb.lib.OrderedHashSet;
+import org.hsqldb.rights.Grantee;
+
+/**
+ * Class for DOMAIN and DISTINCT objects.<p>
+ *
+ * @author Fred Toussi (fredt@users dot sourceforge.net)
+ * @version 1.9.0
+ * @since 1.9.0
+ */
+public class UserTypeModifier {
+
+    final HsqlName name;
+    final int      schemaObjectType;
+    final Type     dataType;
+    Constraint[]   constraints = Constraint.emptyArray;
+    Expression     defaultExpression;
+    boolean        isNullable = true;
+
+    public UserTypeModifier(HsqlName name, int type, Type dataType) {
+
+        this.name             = name;
+        this.schemaObjectType = type;
+        this.dataType         = dataType;
+    }
+
+    public int schemaObjectType() {
+        return schemaObjectType;
+    }
+
+    public void addConstraint(Constraint c) {
+
+        int position = constraints.length;
+
+        constraints = (Constraint[]) ArrayUtil.resizeArray(constraints,
+                position + 1);
+        constraints[position] = c;
+
+        setNotNull();
+    }
+
+    public void removeConstraint(String name) {
+
+        for (int i = 0; i < constraints.length; i++) {
+            if (constraints[i].getName().name.equals(name)) {
+                constraints =
+                    (Constraint[]) ArrayUtil.toAdjustedArray(constraints,
+                        null, i, -1);
+
+                break;
+            }
+        }
+
+        setNotNull();
+    }
+
+    public Constraint getConstraint(String name) {
+
+        for (int i = 0; i < constraints.length; i++) {
+            if (constraints[i].getName().name.equals(name)) {
+                return constraints[i];
+            }
+        }
+
+        return null;
+    }
+
+    public Constraint[] getConstraints() {
+        return constraints;
+    }
+
+    public boolean isNullable() {
+        return isNullable;
+    }
+
+    public Expression getDefaultClause() {
+        return defaultExpression;
+    }
+
+    public void setDefaultClause(Expression defaultExpression) {
+        this.defaultExpression = defaultExpression;
+    }
+
+    public void removeDefaultClause() {
+        defaultExpression = null;
+    }
+
+    private void setNotNull() {
+
+        isNullable = true;
+
+        for (int i = 0; i < constraints.length; i++) {
+            if (constraints[i].isNotNull()) {
+                isNullable = false;
+            }
+        }
+    }
+
+    // interface specific methods
+    public int getType() {
+        return schemaObjectType;
+    }
+
+    public HsqlName getName() {
+        return name;
+    }
+
+    public HsqlName getSchemaName() {
+        return name.schema;
+    }
+
+    public Grantee getOwner() {
+        return name.schema.owner;
+    }
+
+    public OrderedHashSet getReferences() {
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        for (int i = 0; i < constraints.length; i++) {
+            OrderedHashSet subSet = constraints[i].getReferences();
+
+            if (subSet != null) {
+                set.addAll(subSet);
+            }
+        }
+
+        return set;
+    }
+
+    public final OrderedHashSet getComponents() {
+
+        if (constraints == null) {
+            return null;
+        }
+
+        OrderedHashSet set = new OrderedHashSet();
+
+        set.addAll(constraints);
+
+        return set;
+    }
+
+    public void compile(Session session) {
+
+        for (int i = 0; i < constraints.length; i++) {
+            constraints[i].compile(session, null);
+        }
+    }
+
+    public String getSQL() {
+
+        StringBuffer sb = new StringBuffer();
+
+        if (schemaObjectType == SchemaObject.TYPE) {
+            sb.append(Tokens.T_CREATE).append(' ').append(
+                Tokens.T_TYPE).append(' ');
+            sb.append(name.getSchemaQualifiedStatementName());
+            sb.append(' ').append(Tokens.T_AS).append(' ');
+            sb.append(dataType.getDefinition());
+        } else {
+            sb.append(Tokens.T_CREATE).append(' ').append(
+                Tokens.T_DOMAIN).append(' ');
+            sb.append(name.getSchemaQualifiedStatementName());
+            sb.append(' ').append(Tokens.T_AS).append(' ');
+            sb.append(dataType.getDefinition());
+
+            if (defaultExpression != null) {
+                sb.append(' ').append(Tokens.T_DEFAULT).append(' ');
+                sb.append(defaultExpression.getSQL());
+            }
+
+            for (int i = 0; i < constraints.length; i++) {
+                sb.append(' ').append(Tokens.T_CONSTRAINT).append(' ');
+                sb.append(constraints[i].getName().statementName).append(' ');
+                sb.append(Tokens.T_CHECK).append('(').append(
+                    constraints[i].getCheckSQL()).append(')');
+            }
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/util/Bold.gif b/src/org/hsqldb/util/Bold.gif
new file mode 100644
index 0000000..8941022
--- /dev/null
+++ b/src/org/hsqldb/util/Bold.gif
Binary files differ
diff --git a/src/org/hsqldb/util/CSVWriter.java b/src/org/hsqldb/util/CSVWriter.java
new file mode 100644
index 0000000..20f5d89
--- /dev/null
+++ b/src/org/hsqldb/util/CSVWriter.java
@@ -0,0 +1,141 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+/**
+ * helper class to write table data to a csv-file (comma separated values).
+ * the first line in file is a list of fieldnames, all following lines
+ * are data lines.
+ * a descptiontion of file format can be found on: http://www.wotsit.org/
+ * usage: create a object using the constructor. call writeHeader
+ * for writing the filename header then add data with writeData.
+ * at the end close() closes the file.
+ *
+ *@author jeberle@users
+ */
+public class CSVWriter {
+
+    private String             newline = System.getProperty("line.separator");
+    private OutputStreamWriter writer  = null;
+    private int                nbrCols = 0;
+    private int                nbrRows = 0;
+
+    /**
+     * constructor.
+     * creates a csv file for writing data to it
+     * @param file the file to write data to
+     * @param encoding encoding to use or null (=defualt)
+     */
+    public CSVWriter(File file, String encoding) throws IOException {
+
+        if (encoding == null) {
+            encoding = System.getProperty("file.encoding");
+        }
+
+        FileOutputStream fout = new FileOutputStream(file);
+
+        writer = new OutputStreamWriter(fout, encoding);
+    }
+
+    /**
+     * writes the csv header (fieldnames). should be called after
+     * construction one time.
+     * @param header String[] with fieldnames
+     */
+    public void writeHeader(String[] header) throws IOException {
+
+        this.nbrCols = header.length;
+
+        doWriteData(header);
+    }
+
+    /**
+     * writes a data-record to the file. note that data[] must have
+     * same number of elements as the header had.
+     *
+     * @param data data to write to csv-file
+     */
+    public void writeData(String[] data) throws IOException {
+        doWriteData(data);
+    }
+
+    /**
+     * closes the csv file.
+     */
+    public void close() throws IOException {
+        this.writer.close();
+    }
+
+    private void doWriteData(String[] values) throws IOException {
+
+        for (int i = 0; i < values.length; i++) {
+            if (i > 0) {
+                this.writer.write(";");
+            }
+
+            if (values[i] != null) {
+                this.writer.write("\"");
+                this.writer.write(this.toCsvValue(values[i]));
+                this.writer.write("\"");
+            }
+        }
+
+        this.writer.write(newline);
+
+        this.nbrRows++;
+    }
+
+    private String toCsvValue(String str) {
+
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+
+            sb.append(c);
+
+            switch (c) {
+
+                case '"' :
+                    sb.append('"');
+                    break;
+            }
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/hsqldb/util/Clear.png b/src/org/hsqldb/util/Clear.png
new file mode 100644
index 0000000..69bc8af
--- /dev/null
+++ b/src/org/hsqldb/util/Clear.png
Binary files differ
diff --git a/src/org/hsqldb/util/Close.png b/src/org/hsqldb/util/Close.png
new file mode 100644
index 0000000..4eefebe
--- /dev/null
+++ b/src/org/hsqldb/util/Close.png
Binary files differ
diff --git a/src/org/hsqldb/util/CodeSwitcher.java b/src/org/hsqldb/util/CodeSwitcher.java
new file mode 100644
index 0000000..1245468
--- /dev/null
+++ b/src/org/hsqldb/util/CodeSwitcher.java
@@ -0,0 +1,536 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.util.Vector;
+
+// fredt@users 20020315 - patch 1.7.0 - minor fixes
+// changed line separator to System based value
+// moved the Profile class to org.hsqldb.test package
+// fredt@users 20021020 - patch 1.7.1 - formatting fix
+// avoid moving blank lines which would be interpreted as code change by CVS
+// fredt@users 20021118 - patch 1.7.2 - no-change, no-save fix
+// if the file contents do not change, do not save a new version of file
+// fredt@users 20040322 - removed unused profiling code
+// fredt@users 20080315 - added ifndef switch
+
+/**
+ * Modifies the source code to support different JDK or profile settings. <p>
+ * <pre>
+ * Usage: java CodeSwitcher paths|{--pathlist=listfile} [{+|-}label...] [+][-]
+ * If no labels are specified then all used
+ * labels in the source code are shown.
+ * Use +MODE to switch on the things labeld MODE
+ * Use -MODE to switch off the things labeld MODE
+ * Path: Any number of path or files may be
+ * specified. Use . for the current directory
+ * (including sub-directories).
+ * Example: java CodeSwitcher +JAVA2 .
+ * This example switches on code labeled JAVA2
+ * in all *.java files in the current directory
+ * and all subdirectories.
+ * java CodeSwitcher + .
+ * Adds test code to the code.
+ * java CodeSwitcher - .
+ * Removes test code from the code
+ * </pre>
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.7.0
+ * @since Hypersonic SQL
+ */
+public class CodeSwitcher {
+
+    private static final String ls = System.getProperty("line.separator",
+        "\n");
+    private Vector           vList;
+    private Vector           vSwitchOn;
+    private Vector           vSwitchOff;
+    private Vector           vSwitches;
+    private static final int MAX_LINELENGTH = 82;
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param a
+     */
+    public static void main(String[] a) {
+
+        CodeSwitcher s = new CodeSwitcher();
+
+        if (a.length == 0) {
+            showUsage();
+
+            return;
+        }
+
+        File listFile = null;
+        File baseDir  = null;
+
+        for (int i = 0; i < a.length; i++) {
+            String p = a[i];
+
+            if (p.startsWith("+")) {
+                s.vSwitchOn.addElement(p.substring(1));
+            } else if (p.startsWith("--basedir=")) {
+                baseDir = new File(p.substring("--basedir=".length()));
+            } else if (p.startsWith("--pathlist=")) {
+                listFile = new File(p.substring("--pathlist=".length()));
+            } else if (p.startsWith("-")) {
+                s.vSwitchOff.addElement(p.substring(1));
+            } else {
+                s.addDir(p);
+            }
+        }
+
+        if (baseDir != null) {
+            if (listFile == null) {
+                System.err.println(
+                    "--basedir= setting ignored, since only used for list files");
+            } else {
+                if (!baseDir.isDirectory()) {
+                    System.err.println("Skipping listfile since basedir '"
+                                       + baseDir.getAbsolutePath()
+                                       + "' is not a directory");
+
+                    listFile = null;
+                }
+            }
+        }
+
+        if (listFile != null) {
+            try {
+                BufferedReader br =
+                    new BufferedReader(new FileReader(listFile));
+                String st, p;
+                int    hashIndex;
+                File   f;
+
+                while ((st = br.readLine()) != null) {
+                    hashIndex = st.indexOf('#');
+                    p         = ((hashIndex > -1) ? st.substring(0, hashIndex)
+                                                  : st).trim();
+
+                    if (p.length() < 1) {
+                        continue;
+                    }
+
+                    f = (baseDir == null) ? (new File(p))
+                                          : (new File(baseDir, p));
+
+                    if (f.isFile()) {
+                        s.addDir(f);
+                    } else {
+                        System.err.println("Skipping non-file '" + p.trim()
+                                           + "'");
+                    }
+                }
+            } catch (Exception e) {
+                System.err.println("Failed to read pathlist file '"
+                                   + listFile.getAbsolutePath() + "'");
+            }
+        }
+
+        if (s.size() < 1) {
+            printError("No path specified, or no specified paths qualify");
+            showUsage();
+        }
+
+        s.process();
+
+        if (s.vSwitchOff.size() == 0 && s.vSwitchOn.size() == 0) {
+            s.printSwitches();
+        }
+    }
+
+    public int size() {
+        return (vList == null) ? 0
+                               : vList.size();
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    static void showUsage() {
+
+        System.out.print("Usage: java CodeSwitcher paths|{--pathlist=listfile} "
+                         + "[{+|-}label...] [+][-]\n"
+                         + "If no labels are specified then all used\n"
+                         + "labels in the source code are shown.\n"
+                         + "Use +MODE to switch on the things labeld MODE\n"
+                         + "Use -MODE to switch off the things labeld MODE\n"
+                         + "Path: Any number of path or files may be\n"
+                         + "specified. Use . for the current directory\n"
+                         + "(including sub-directories).\n"
+                         + "Example: java CodeSwitcher +JAVA2 .\n"
+                         + "This example switches on code labeled JAVA2\n"
+                         + "in all *.java files in the current directory\n"
+                         + "and all subdirectories.\n");
+    }
+
+    /**
+     * Constructor declaration
+     *
+     */
+    CodeSwitcher() {
+
+        vList      = new Vector();
+        vSwitchOn  = new Vector();
+        vSwitchOff = new Vector();
+        vSwitches  = new Vector();
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    void process() {
+
+        int len = vList.size();
+
+        for (int i = 0; i < len; i++) {
+            System.out.print(".");
+
+            String file = (String) vList.elementAt(i);
+
+            if (!processFile(file)) {
+                System.out.println("in file " + file + " !");
+            }
+        }
+
+        System.out.println("");
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    void printSwitches() {
+
+        System.out.println("Used labels:");
+
+        for (int i = 0; i < vSwitches.size(); i++) {
+            System.out.println((String) (vSwitches.elementAt(i)));
+        }
+    }
+
+    /**
+     * Wrapper
+     *
+     * @param path
+     */
+    void addDir(String path) {
+        addDir(new File(path));
+    }
+
+    void addDir(File f) {
+
+        if (f.isFile() && f.getName().endsWith(".java")) {
+            vList.addElement(f.getPath());
+        } else if (f.isDirectory()) {
+            File[] list = f.listFiles();
+
+            for (int i = 0; i < list.length; i++) {
+                addDir(list[i]);
+            }
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param name
+     */
+    boolean processFile(String name) {
+
+        File    f         = new File(name);
+        File    fnew      = new File(name + ".new");
+        int     state     = 0;    // 0=normal 1=inside_if 2=inside_else
+        boolean switchoff = false;
+        boolean working   = false;
+
+        try {
+            Vector v  = getFileLines(f);
+            Vector v1 = new Vector(v.size());
+
+            for (int i = 0; i < v.size(); i++) {
+                v1.addElement(v.elementAt(i));
+            }
+
+            for (int i = 0; i < v.size(); i++) {
+                String line = (String) v.elementAt(i);
+
+                if (line == null) {
+                    break;
+                }
+
+                if (working) {
+                    if (line.equals("/*") || line.equals("*/")) {
+                        v.removeElementAt(i--);
+
+                        continue;
+                    }
+                }
+
+                if (line.startsWith("//#")) {
+                    if (line.startsWith("//#ifdef ")) {
+                        if (state != 0) {
+                            printError("'#ifdef' not allowed inside '#ifdef'");
+
+                            return false;
+                        }
+
+                        state = 1;
+
+                        String s = line.substring(9);
+
+                        if (vSwitchOn.indexOf(s) != -1) {
+                            working   = true;
+                            switchoff = false;
+                        } else if (vSwitchOff.indexOf(s) != -1) {
+                            working = true;
+
+                            v.insertElementAt("/*", ++i);
+
+                            switchoff = true;
+                        }
+
+                        if (vSwitches.indexOf(s) == -1) {
+                            vSwitches.addElement(s);
+                        }
+                    } else if (line.startsWith("//#ifndef ")) {
+                        if (state != 0) {
+                            printError(
+                                "'#ifndef' not allowed inside '#ifdef'");
+
+                            return false;
+                        }
+
+                        state = 1;
+
+                        String s = line.substring(10);
+
+                        if (vSwitchOff.indexOf(s) != -1) {
+                            working   = true;
+                            switchoff = false;
+                        } else if (vSwitchOn.indexOf(s) != -1) {
+                            working = true;
+
+                            v.insertElementAt("/*", ++i);
+
+                            switchoff = true;
+                        }
+
+                        if (vSwitches.indexOf(s) == -1) {
+                            vSwitches.addElement(s);
+                        }
+                    } else if (line.startsWith("//#else")) {
+                        if (state != 1) {
+                            printError("'#else' without '#ifdef'");
+
+                            return false;
+                        }
+
+                        state = 2;
+
+                        if (!working) {}
+                        else if (switchoff) {
+                            if (v.elementAt(i - 1).equals("")) {
+                                v.insertElementAt("*/", i - 1);
+
+                                i++;
+                            } else {
+                                v.insertElementAt("*/", i++);
+                            }
+
+                            switchoff = false;
+                        } else {
+                            v.insertElementAt("/*", ++i);
+
+                            switchoff = true;
+                        }
+                    } else if (line.startsWith("//#endif")) {
+                        if (state == 0) {
+                            printError("'#endif' without '#ifdef'");
+
+                            return false;
+                        }
+
+                        state = 0;
+
+                        if (working && switchoff) {
+                            if (v.elementAt(i - 1).equals("")) {
+                                v.insertElementAt("*/", i - 1);
+
+                                i++;
+                            } else {
+                                v.insertElementAt("*/", i++);
+                            }
+                        }
+
+                        working = false;
+                    } else {}
+                }
+            }
+
+            if (state != 0) {
+                printError("'#endif' missing");
+
+                return false;
+            }
+
+            boolean filechanged = false;
+
+            for (int i = 0; i < v.size(); i++) {
+                if (!v1.elementAt(i).equals(v.elementAt(i))) {
+                    filechanged = true;
+
+                    break;
+                }
+            }
+
+            if (!filechanged) {
+                return true;
+            }
+
+            writeFileLines(v, fnew);
+
+            File fbak = new File(name + ".bak");
+
+            fbak.delete();
+            f.renameTo(fbak);
+
+            File fcopy = new File(name);
+
+            fnew.renameTo(fcopy);
+            fbak.delete();
+
+            return true;
+        } catch (Exception e) {
+            printError(e.toString());
+
+            return false;
+        }
+    }
+
+    static Vector getFileLines(File f) throws IOException {
+
+        LineNumberReader read = new LineNumberReader(new FileReader(f));
+        Vector           v    = new Vector();
+
+        for (;;) {
+            String line = read.readLine();
+
+            if (line == null) {
+                break;
+            }
+
+            v.addElement(line);
+        }
+
+        read.close();
+
+        return v;
+    }
+
+    static void writeFileLines(Vector v, File f) throws IOException {
+
+        FileWriter write = new FileWriter(f);
+
+        for (int i = 0; i < v.size(); i++) {
+            write.write((String) v.elementAt(i));
+            write.write(ls);
+        }
+
+        write.flush();
+        write.close();
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param error
+     */
+    static void printError(String error) {
+        System.out.println("");
+        System.out.println("ERROR: " + error);
+    }
+}
diff --git a/src/org/hsqldb/util/Colors.png b/src/org/hsqldb/util/Colors.png
new file mode 100644
index 0000000..08ecfd1
--- /dev/null
+++ b/src/org/hsqldb/util/Colors.png
Binary files differ
diff --git a/src/org/hsqldb/util/CommonSwing.java b/src/org/hsqldb/util/CommonSwing.java
new file mode 100644
index 0000000..4d41f1d
--- /dev/null
+++ b/src/org/hsqldb/util/CommonSwing.java
@@ -0,0 +1,240 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.awt.Dimension;
+import java.awt.Image;
+import java.awt.Toolkit;
+
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+// sqlbob@users 20020407 - patch 1.7.0 - reengineering
+// weconsultants@users 20041109 - patch 1.8.0 - enhancements:
+//      Added Methods: setSwingLAF(), LookAndFeelInfo(), setFramePositon()
+//      errorMessage(String errorMessage),
+//      errorMessage(Exception exceptionMsg,
+//      Added: Ability to switch the current LAF while runing (Native,Java or Motif)
+
+/**
+ * Common code in the Swing versions of DatabaseManager and Tranfer
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+class CommonSwing {
+
+    protected static String messagerHeader = "Database Manager Swing Error";
+    protected static String Native         = "Native";
+    protected static String Java           = "Java";
+    protected static String Motif          = "Motif";
+    protected static String plaf           = "plaf";
+    protected static String GTK            = "GTK";
+
+    // (ulrivo): An actual Image.
+    static Image getIcon(String target) {
+
+        if (target.equalsIgnoreCase("SystemCursor")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("Hourglass.gif")).getImage());
+        } else if (target.equalsIgnoreCase("Frame")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("hsqldb.gif")).getImage());
+        } else if (target.equalsIgnoreCase("Execute")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("run_exc.gif")).getImage());
+        } else if (target.equalsIgnoreCase("StatusRunning")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("RedCircle.gif")).getImage());
+        } else if (target.equalsIgnoreCase("StatusReady")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("GreenCircle.gif")).getImage());
+        } else if (target.equalsIgnoreCase("Clear")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("Clear.png")).getImage());
+        } else if (target.equalsIgnoreCase("Problem")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("problems.gif")).getImage());
+        } else if (target.equalsIgnoreCase("BoldFont")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("Bold.gif")).getImage());
+        } else if (target.equalsIgnoreCase("ItalicFont")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("Italic.gif")).getImage());
+        } else if (target.equalsIgnoreCase("ColorSelection")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("Colors.png")).getImage());
+        } else if (target.equalsIgnoreCase("Close")) {
+            return (new ImageIcon(
+                CommonSwing.class.getResource("Close.png")).getImage());
+        } else {
+            return (null);
+        }
+    }
+
+    // (weconsultants@users: Callable errorMessage method
+    protected static void errorMessage(String errorMessage) {
+
+        /**
+         * Display Jpanel Error messages any text Errors. Overloads
+         * errorMessage(Exception exceptionMsg)
+         */
+        Object[] options = { "OK" };
+
+        JOptionPane.showOptionDialog(null, errorMessage, messagerHeader,
+                                     JOptionPane.DEFAULT_OPTION,
+                                     JOptionPane.WARNING_MESSAGE, null,
+                                     options, options[0]);
+
+        // DatabaseManagerSwing.StatusMessage(READY_STATUS);
+    }
+
+    public static void errorMessage(Exception exceptionMsg) {
+        errorMessage(exceptionMsg, false);
+    }
+
+    // (weconsultants@users: Callable errorMessage method
+    public static void errorMessage(Exception exceptionMsg, boolean quiet) {
+
+        /**
+         * Display Jpanel Error messages any SQL Errors. Overloads
+         * errorMessage(String e)
+         */
+        Object[] options = { "OK", };
+
+        JOptionPane.showOptionDialog(null, exceptionMsg, messagerHeader,
+                                     JOptionPane.DEFAULT_OPTION,
+                                     JOptionPane.ERROR_MESSAGE, null,
+                                     options, options[0]);
+
+        if (!quiet) {
+            exceptionMsg.printStackTrace();
+        }
+
+        // DatabaseManagerSwing.StatusMessage(READY_STATUS);
+    }
+
+    // (weconsultants@users: Callable setFramePositon method
+    static void setFramePositon(JFrame inTargetFrame) {
+
+        Dimension d    = Toolkit.getDefaultToolkit().getScreenSize();
+        Dimension size = inTargetFrame.getSize();
+
+        // (ulrivo): full size on screen with less than 640 width
+        if (d.width >= 640) {
+            inTargetFrame.setLocation((d.width - size.width) / 2,
+                                      (d.height - size.height) / 2);
+        } else {
+            inTargetFrame.setLocation(0, 0);
+            inTargetFrame.setSize(d);
+        }
+    }
+
+// (weconsultants@users: Commented out, Not need now. Was not being called anyway.. Could delete?
+//    static void setDefaultColor() {
+//
+//        Color hsqlBlue = new Color(102, 153, 204);
+//        Color hsqlGreen = new Color(153, 204, 204);
+//        UIDefaults d = UIManager.getLookAndFeelDefaults();
+//
+//        d.put("MenuBar.background", SystemColor.control);
+//        d.put("Menu.background", SystemColor.control);
+//        d.put("Menu.selectionBackground", hsqlBlue);
+//        d.put("MenuItem.background", SystemColor.menu);
+//        d.put("MenuItem.selectionBackground", hsqlBlue);
+//        d.put("Separator.foreground", SystemColor.controlDkShadow);
+//        d.put("Button.background", SystemColor.control);
+//        d.put("CheckBox.background", SystemColor.control);
+//        d.put("Label.background", SystemColor.control);
+//        d.put("Label.foreground", Color.black);
+//        d.put("Panel.background", SystemColor.control);
+//        d.put("PasswordField.selectionBackground", hsqlGreen);
+//        d.put("PasswordField.background", SystemColor.white);
+//        d.put("TextArea.selectionBackground", hsqlGreen);
+//        d.put("TextField.background", SystemColor.white);
+//        d.put("TextField.selectionBackground", hsqlGreen);
+//        d.put("TextField.background", SystemColor.white);
+//        d.put("ScrollBar.background", SystemColor.controlHighlight);
+//        d.put("ScrollBar.foreground", SystemColor.control);
+//        d.put("ScrollBar.track", SystemColor.controlHighlight);
+//        d.put("ScrollBar.trackHighlight", SystemColor.controlDkShadow);
+//        d.put("ScrollBar.thumb", SystemColor.control);
+//        d.put("ScrollBar.thumbHighlight", SystemColor.controlHighlight);
+//        d.put("ScrollBar.thumbDarkShadow", SystemColor.controlDkShadow);
+//        d.put("ScrollBar.thumbLightShadow", SystemColor.controlShadow);
+//        d.put("ComboBox.background", SystemColor.control);
+//        d.put("ComboBox.selectionBackground", hsqlBlue);
+//        d.put("Table.background", SystemColor.white);
+//        d.put("Table.selectionBackground", hsqlBlue);
+//        d.put("TableHeader.background", SystemColor.control);
+//
+//        // This doesn't seem to work.
+//        d.put("SplitPane.background", SystemColor.control);
+//        d.put("Tree.selectionBackground", hsqlBlue);
+//        d.put("List.selectionBackground", hsqlBlue);
+//    }
+    // (weconsultants@users: Callable setSwingLAF method for changing LAF
+    static void setSwingLAF(java.awt.Component comp, String targetTheme) {
+
+        try {
+            if (targetTheme.equalsIgnoreCase(Native)) {
+                UIManager.setLookAndFeel(
+                    UIManager.getSystemLookAndFeelClassName());
+            } else if (targetTheme.equalsIgnoreCase(Java)) {
+                UIManager.setLookAndFeel(
+                    UIManager.getCrossPlatformLookAndFeelClassName());
+            } else if (targetTheme.equalsIgnoreCase(Motif)) {
+                UIManager.setLookAndFeel(
+                    "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
+            }
+
+//            if (targetTheme.equalsIgnoreCase(plaf)){
+//                UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
+//            }
+//
+//            if (targetTheme.equalsIgnoreCase(GTK)){
+//                UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
+//            }
+            SwingUtilities.updateComponentTreeUI(comp);
+
+            if (comp instanceof java.awt.Frame) {
+                ((java.awt.Frame) comp).pack();
+            }
+        } catch (Exception e) {
+            errorMessage(e);
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/ConnectionDialog.java b/src/org/hsqldb/util/ConnectionDialog.java
new file mode 100644
index 0000000..48eba24
--- /dev/null
+++ b/src/org/hsqldb/util/ConnectionDialog.java
@@ -0,0 +1,351 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Choice;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.SystemColor;
+import java.awt.TextField;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+// sqlbob@users 20020325 - patch 1.7.0 - enhancements
+// sqlbob@users 20020407 - patch 1.7.0 - reengineering
+// fredt@users - 20040508 - modified patch by lonbinder@users for saving settings
+
+/**
+ * Opens a connection to a database
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.7.2
+ * @since Hypersonic SQL
+ */
+class ConnectionDialog extends Dialog implements ActionListener, ItemListener {
+
+    protected Connection mConnection;
+    protected TextField  mName, mDriver, mURL, mUser, mPassword;
+    protected Label      mError;
+    private String[][]   connTypes;
+    private Hashtable    settings;
+    private Choice       types, recent;
+
+    /**
+     * @throws Exception
+     */
+    public static Connection createConnection(String driver, String url,
+            String user, String password) throws Exception {
+
+        Class.forName(driver).newInstance();
+
+        return DriverManager.getConnection(url, user, password);
+    }
+
+    /**
+     * Constructor declaration
+     *
+     *
+     * @param owner
+     * @param title
+     */
+    ConnectionDialog(Frame owner, String title) {
+        super(owner, title, true);
+    }
+
+    private void create() {
+
+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+
+        setLayout(new BorderLayout());
+
+        Panel p = new Panel(new BorderLayout());
+        Panel pLabel;
+        Panel pText;
+        Panel pButton;
+        Panel pClearButton;
+
+        // (ulrivo): full size on screen with less than 640 width
+        if (d.width >= 640) {
+            pLabel       = new Panel(new GridLayout(8, 1, 10, 10));
+            pText        = new Panel(new GridLayout(8, 1, 10, 10));
+            pButton      = new Panel(new GridLayout(1, 2, 10, 10));
+            pClearButton = new Panel(new GridLayout(8, 1, 10, 10));
+        } else {
+            pLabel       = new Panel(new GridLayout(8, 1));
+            pText        = new Panel(new GridLayout(8, 1));
+            pButton      = new Panel(new GridLayout(1, 2));
+            pClearButton = new Panel(new GridLayout(8, 1));
+        }
+
+        p.add("West", pLabel);
+        p.add("Center", pText);
+        p.add("South", pButton);
+        p.add("North", createLabel(""));
+        p.add("East", pClearButton);
+        p.setBackground(SystemColor.control);
+        pText.setBackground(SystemColor.control);
+        pLabel.setBackground(SystemColor.control);
+        pButton.setBackground(SystemColor.control);
+        pLabel.add(createLabel("Recent:"));
+
+        recent = new Choice();
+
+        try {
+            settings = ConnectionDialogCommon.loadRecentConnectionSettings();
+        } catch (java.io.IOException ioe) {
+            ioe.printStackTrace();
+        }
+
+        recent.add(ConnectionDialogCommon.emptySettingName);
+
+        Enumeration en = settings.elements();
+
+        while (en.hasMoreElements()) {
+            recent.add(((ConnectionSetting) en.nextElement()).getName());
+        }
+
+        recent.addItemListener(new ItemListener() {
+
+            public void itemStateChanged(ItemEvent e) {
+
+                String s = (String) e.getItem();
+                ConnectionSetting setting =
+                    (ConnectionSetting) settings.get(s);
+
+                if (setting != null) {
+                    mName.setText(setting.getName());
+                    mDriver.setText(setting.getDriver());
+                    mURL.setText(setting.getUrl());
+                    mUser.setText(setting.getUser());
+                    mPassword.setText(setting.getPassword());
+                }
+            }
+        });
+        pText.add(recent);
+
+        Button b;
+
+        b = new Button("Clr");
+
+        b.setActionCommand("Clear");
+        b.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+
+                ConnectionDialogCommon.deleteRecentConnectionSettings();
+
+                settings = new Hashtable();
+
+                recent.removeAll();
+                recent.add(ConnectionDialogCommon.emptySettingName);
+                mName.setText(null);
+            }
+        });
+        pClearButton.add(b);
+        pLabel.add(createLabel("Setting Name:"));
+
+        mName = new TextField("");
+
+        pText.add(mName);
+        pLabel.add(createLabel("Type:"));
+
+        types     = new Choice();
+        connTypes = ConnectionDialogCommon.getTypes();
+
+        for (int i = 0; i < connTypes.length; i++) {
+            types.add(connTypes[i][0]);
+        }
+
+        types.addItemListener(this);
+        pText.add(types);
+        pLabel.add(createLabel("Driver:"));
+
+        mDriver = new TextField(connTypes[0][1]);
+
+        pText.add(mDriver);
+        pLabel.add(createLabel("URL:"));
+
+        mURL = new TextField(connTypes[0][2]);
+
+        mURL.addActionListener(this);
+        pText.add(mURL);
+        pLabel.add(createLabel("User:"));
+
+        mUser = new TextField("SA");
+
+        mUser.addActionListener(this);
+        pText.add(mUser);
+        pLabel.add(createLabel("Password:"));
+
+        mPassword = new TextField("");
+
+        mPassword.addActionListener(this);
+        mPassword.setEchoChar('*');
+        pText.add(mPassword);
+
+        b = new Button("Ok");
+
+        b.setActionCommand("ConnectOk");
+        b.addActionListener(this);
+        pButton.add(b);
+
+        b = new Button("Cancel");
+
+        b.setActionCommand("ConnectCancel");
+        b.addActionListener(this);
+        pButton.add(b);
+        add("East", createLabel(""));
+        add("West", createLabel(""));
+
+        mError = new Label("");
+
+        Panel pMessage = createBorderPanel(mError);
+
+        add("South", pMessage);
+        add("North", createLabel(""));
+        add("Center", p);
+        doLayout();
+        pack();
+
+        Dimension size = getSize();
+
+        // (ulrivo): full size on screen with less than 640 width
+        if (d.width >= 640) {
+            setLocation((d.width - size.width) / 2,
+                        (d.height - size.height) / 2);
+        } else {
+            setLocation(0, 0);
+            setSize(d);
+        }
+
+        show();
+    }
+
+    public static Connection createConnection(Frame owner, String title) {
+
+        ConnectionDialog dialog = new ConnectionDialog(owner, title);
+
+        dialog.create();
+
+        return dialog.mConnection;
+    }
+
+    protected static Label createLabel(String s) {
+
+        Label l = new Label(s);
+
+        l.setBackground(SystemColor.control);
+
+        return l;
+    }
+
+    protected static Panel createBorderPanel(Component center) {
+
+        Panel p = new Panel();
+
+        p.setBackground(SystemColor.control);
+        p.setLayout(new BorderLayout());
+        p.add("Center", center);
+        p.add("North", createLabel(""));
+        p.add("South", createLabel(""));
+        p.add("East", createLabel(""));
+        p.add("West", createLabel(""));
+        p.setBackground(SystemColor.control);
+
+        return p;
+    }
+
+    public void actionPerformed(ActionEvent ev) {
+
+        String s = ev.getActionCommand();
+
+        if (s.equals("ConnectOk") || (ev.getSource() instanceof TextField)) {
+            try {
+                if (mURL.getText().indexOf('\u00AB') >= 0) {
+                    throw new Exception("please specify db path");
+                }
+
+                mConnection = createConnection(mDriver.getText(),
+                                               mURL.getText(),
+                                               mUser.getText(),
+                                               mPassword.getText());
+
+                if (mName.getText() != null
+                        && mName.getText().trim().length() != 0) {
+                    ConnectionSetting newSetting =
+                        new ConnectionSetting(mName.getText(),
+                                              mDriver.getText(),
+                                              mURL.getText(), mUser.getText(),
+                                              mPassword.getText());
+
+                    ConnectionDialogCommon.addToRecentConnectionSettings(
+                        settings, newSetting);
+                }
+
+                dispose();
+            } catch (java.io.IOException ioe) {
+                dispose();
+            } catch (Exception e) {
+                e.printStackTrace();
+                mError.setText(e.toString());
+            }
+        } else if (s.equals("ConnectCancel")) {
+            dispose();
+        }
+    }
+
+    public void itemStateChanged(ItemEvent e) {
+
+        String s = (String) e.getItem();
+
+        for (int i = 0; i < connTypes.length; i++) {
+            if (s.equals(connTypes[i][0])) {
+                mDriver.setText(connTypes[i][1]);
+                mURL.setText(connTypes[i][2]);
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/ConnectionDialogCommon.java b/src/org/hsqldb/util/ConnectionDialogCommon.java
new file mode 100644
index 0000000..86edf05
--- /dev/null
+++ b/src/org/hsqldb/util/ConnectionDialogCommon.java
@@ -0,0 +1,337 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Constructor;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.hsqldb.lib.java.JavaSystem;
+
+// sqlbob@users 20020407 - patch 1.7.0 - reengineering
+// fredt@users - 20040508 - modified patch by lonbinder@users for saving settings
+// weconsultants@users - 20041114 - patch 1.8.0 - Added MySQL Connector/J jbcDriver and granulated imports
+
+/**
+ * Common code in the Swing and AWT versions of ConnectionDialog
+ *
+ * New class based on Hypersonic original
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+class ConnectionDialogCommon {
+
+    private static String[][]       connTypes;
+    private static final String[][] sJDBCTypes = {
+        {
+            "HSQL Database Engine In-Memory", "org.hsqldb.jdbcDriver",
+            "jdbc:hsqldb:mem:."
+        }, {
+            "HSQL Database Engine Standalone", "org.hsqldb.jdbcDriver",
+            "jdbc:hsqldb:file:\u00ABdatabase/path?\u00BB"
+        }, {
+            "HSQL Database Engine Server", "org.hsqldb.jdbcDriver",
+            "jdbc:hsqldb:hsql://localhost/"
+        }, {
+            "HSQL Database Engine WebServer", "org.hsqldb.jdbcDriver",
+            "jdbc:hsqldb:http://\u00ABhostname/?\u00BB"
+        }, {
+            "JDBC-ODBC Bridge from Sun", "sun.jdbc.odbc.JdbcOdbcDriver",
+            "jdbc:odbc:\u00ABdatabase?\u00BB"
+        }, {
+            "Cloudscape RMI", "RmiJdbc.RJDriver",
+            "jdbc:rmi://\u00ABhost?\u00BB:1099/jdbc:cloudscape:"
+            + "\u00ABdatabase?\u00BB;create=true"
+        }, {
+            "IBM DB2", "COM.ibm.db2.jdbc.app.DB2Driver",
+            "jdbc:db2:\u00ABdatabase?\u00BB"
+        }, {
+            "IBM DB2 (thin)", "COM.ibm.db2.jdbc.net.DB2Driver",
+            "jdbc:db2://\u00ABhost?\u00BB:6789/\u00ABdatabase?\u00BB"
+        }, {
+            "Informix", "com.informix.jdbc.IfxDriver",
+            "jdbc:informix-sqli://\u00ABhost?\u00BB:1533/\u00ABdatabase?\u00BB:"
+            + "INFORMIXSERVER=\u00ABserver?\u00BB"
+        }, {
+            "InstantDb", "jdbc.idbDriver", "jdbc:idb:\u00ABdatabase?\u00BB.prp"
+        }, {
+            "MySQL Connector/J", "com.mysql.jdbc.Driver",
+            "jdbc:mysql://\u00ABhost?\u00BB/\u00ABdatabase?\u00BB"
+        }, {
+            "MM.MySQL", "org.gjt.mm.mysql.Driver",
+            "jdbc:mysql://\u00ABhost?\u00BB/\u00ABdatabase?\u00BB"
+        }, {
+            "Oracle", "oracle.jdbc.driver.OracleDriver",
+            "jdbc:oracle:oci8:@\u00ABdatabase?\u00BB"
+        }, {
+            "Oracle (thin)", "oracle.jdbc.driver.OracleDriver",
+            "jdbc:oracle:thin:@\u00ABhost?\u00BB:1521:\u00ABdatabase?\u00BB"
+        }, {
+            "PointBase", "com.pointbase.jdbc.jdbcUniversalDriver",
+            "jdbc:pointbase://\u00ABhost?\u00BB/\u00ABdatabase?\u00BB"
+        }, {
+            "PostgreSQL", "org.postgresql.Driver",
+            "jdbc:postgresql://\u00ABhost?\u00BB/\u00ABdatabase?\u00BB"
+        }, {
+            "PostgreSQL v6.5", "postgresql.Driver",
+            "jdbc:postgresql://\u00ABhost?\u00BB/\u00ABdatabase?\u00BB"
+        }
+    };
+
+    static String[][] getTypes() {
+
+        return sJDBCTypes;
+/*
+
+        if (connTypes == null) {
+
+
+            // Pluggable connection types:
+            Vector plugTypes = new Vector();
+
+            try {
+                plugTypes = (Vector) Class.forName(
+                    System.getProperty(
+                        "org.hsqldb.util.ConnectionTypeClass")).newInstance();
+            } catch (Exception e) {
+                ;
+            }
+
+            connTypes =
+                new String[(plugTypes.size() / 3) + sJDBCTypes.length][3];
+
+            int i = 0;
+
+            for (int j = 0; j < plugTypes.size(); i++) {
+                connTypes[i]    = new String[3];
+                connTypes[i][0] = plugTypes.elementAt(j++).toString();
+                connTypes[i][1] = plugTypes.elementAt(j++).toString();
+                connTypes[i][2] = plugTypes.elementAt(j++).toString();
+            }
+
+            for (int j = 0; j < sJDBCTypes.length; i++, j++) {
+                connTypes[i]    = new String[3];
+                connTypes[i][0] = sJDBCTypes[j][0];
+                connTypes[i][1] = sJDBCTypes[j][1];
+                connTypes[i][2] = sJDBCTypes[j][2];
+            }
+        }
+
+        return (connTypes);
+ */
+    }
+
+    private static final String fileName       = "hsqlprefs.dat";
+    private static File         recentSettings = null;
+
+    static synchronized Hashtable loadRecentConnectionSettings()
+    throws IOException {
+
+        Hashtable list = new Hashtable();
+
+        try {
+            if (recentSettings == null) {
+                setHomeDir();
+
+                if (homedir == null) {
+                    return list;
+                }
+
+                recentSettings = new File(homedir, fileName);
+
+                if (!recentSettings.exists()) {
+                    JavaSystem.createNewFile(recentSettings);
+
+                    return list;
+                }
+            }
+        } catch (Throwable e) {
+            return list;
+        }
+
+        FileInputStream   in        = null;
+        ObjectInputStream objStream = null;
+
+        try {
+            in        = new FileInputStream(recentSettings);
+            objStream = new ObjectInputStream(in);
+
+            list.clear();
+
+            while (true) {
+                ConnectionSetting setting =
+                    (ConnectionSetting) objStream.readObject();
+
+                if (!emptySettingName.equals(setting.getName())) {
+                    list.put(setting.getName(), setting);
+                }
+            }
+        } catch (EOFException eof) {
+
+            // reached end of file -- this is not clean but it works
+        } catch (ClassNotFoundException cnfe) {
+            throw (IOException) new IOException("Unrecognized class type "
+                                                + cnfe.getMessage());
+        } catch (ClassCastException cce) {
+            throw (IOException) new IOException("Unrecognized class type "
+                                                + cce.getMessage());
+        } catch (Throwable t) {}
+        finally {
+            if (objStream != null) {
+                objStream.close();
+            }
+
+            if (in != null) {
+                in.close();
+            }
+        }
+
+        return list;
+    }
+
+    static String emptySettingName = "Recent settings...";
+
+    /**
+     * Adds the new settings name if it does not nexist, or overwrites the old one.
+     */
+    static void addToRecentConnectionSettings(Hashtable settings,
+            ConnectionSetting newSetting) throws IOException {
+        settings.put(newSetting.getName(), newSetting);
+        ConnectionDialogCommon.storeRecentConnectionSettings(settings);
+    }
+
+    /**
+     * Here's a non-secure method of storing recent connection settings.
+     *
+     * @param settings ConnectionSetting[]
+     * @throw IOException if something goes wrong while writing
+     */
+    private static void storeRecentConnectionSettings(Hashtable settings) {
+
+        try {
+            if (recentSettings == null) {
+                setHomeDir();
+
+                if (homedir == null) {
+                    return;
+                }
+
+                recentSettings = new File(homedir, fileName);
+
+                if (!recentSettings.exists()) {
+
+//                    recentSettings.createNewFile();
+                }
+            }
+
+            if (settings == null || settings.size() == 0) {
+                return;
+            }
+
+            // setup a stream to a physical file on the filesystem
+            FileOutputStream   out = new FileOutputStream(recentSettings);
+            ObjectOutputStream objStream = new ObjectOutputStream(out);
+            Enumeration        en        = settings.elements();
+
+            while (en.hasMoreElements()) {
+                objStream.writeObject(en.nextElement());
+            }
+
+            objStream.flush();
+            objStream.close();
+            out.close();
+        } catch (Throwable t) {}
+    }
+
+    /**
+     * Removes the recent connection settings file store.
+     */
+    static void deleteRecentConnectionSettings() {
+
+        try {
+            if (recentSettings == null) {
+                setHomeDir();
+
+                if (homedir == null) {
+                    return;
+                }
+
+                recentSettings = new File(homedir, fileName);
+            }
+
+            if (!recentSettings.exists()) {
+                recentSettings = null;
+
+                return;
+            }
+
+            recentSettings.delete();
+
+            recentSettings = null;
+        } catch (Throwable t) {}
+    }
+
+    private static String homedir = null;
+
+    public static void setHomeDir() {
+
+//#ifdef JAVA2FULL
+        if (homedir == null) {
+            try {
+                Class c =
+                    Class.forName("sun.security.action.GetPropertyAction");
+                Constructor constructor = c.getConstructor(new Class[]{
+                    String.class });
+                java.security.PrivilegedAction a =
+                    (java.security.PrivilegedAction) constructor.newInstance(
+                        new Object[]{ "user.home" });
+
+                homedir =
+                    (String) java.security.AccessController.doPrivileged(a);
+            } catch (Exception e) {
+                System.err.println(
+                    "No access to home directory.  Continuing without...");
+            }
+        }
+
+//#endif
+    }
+}
diff --git a/src/org/hsqldb/util/ConnectionDialogSwing.java b/src/org/hsqldb/util/ConnectionDialogSwing.java
new file mode 100644
index 0000000..3f55c82
--- /dev/null
+++ b/src/org/hsqldb/util/ConnectionDialogSwing.java
@@ -0,0 +1,394 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.border.EmptyBorder;
+
+// sqlbob@users 20020325 - patch 1.7.0 - enhancements
+// sqlbob@users 20020407 - patch 1.7.0 - reengineering
+// weconsultants@users 20041109 - patch 1.8.0 - enhancements:
+//              Added CommonSwing.errorMessage() to handle error messages
+//              for errors so eliminated the mError JLable field and Status HorizontalBox.
+//              Changed dispose on cancel to exit. If "Dup", "Restore" or Transer" needed ust
+//              Press <OK> Conform toprogramming standards
+//              Added spaces to "OK" button to make same size buttons
+//              Added ":" to all labels as in databaseManager.java
+//              Added: Added code from DatabaseManager to store connection settings
+
+/**
+ * Opens a connection to a database
+ *
+ * New class based on Hypersonic original
+ *
+ * @author dmarshall@users
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+class ConnectionDialogSwing extends JDialog
+implements ActionListener, ItemListener {
+
+    /**
+     * Comment for <code>serialVersionUID</code>
+     */
+    private static final long serialVersionUID = 1L;
+    private Connection        mConnection;
+    private JTextField        mName, mDriver, mURL, mUser;
+    private JPasswordField    mPassword;
+    private String[][]        connTypes;
+    private Hashtable         settings;
+    private JButton           okCancel, clear;
+    private JComboBox mSettingName =
+        new JComboBox(loadRecentConnectionSettings());
+    private static ConnectionSetting currentConnectionSetting = null;
+
+    public static void setConnectionSetting(
+            ConnectionSetting connectionSetting) {
+        currentConnectionSetting = connectionSetting;
+    }
+
+    public static Connection createConnection(String driver, String url,
+            String user, String password) throws Exception {
+
+        Class.forName(driver).newInstance();
+
+        return DriverManager.getConnection(url, user, password);
+    }
+
+    ConnectionDialogSwing(JFrame owner, String title) {
+        super(owner, title, true);
+    }
+
+    private void create() {
+
+        Box main     = Box.createHorizontalBox();
+        Box labels   = Box.createVerticalBox();
+        Box controls = Box.createVerticalBox();
+        Box buttons  = Box.createHorizontalBox();
+        Box whole    = Box.createVerticalBox();
+
+        // (weconsultants@users) New code
+        Box extra = Box.createHorizontalBox();
+
+        main.add(Box.createHorizontalStrut(10));
+        main.add(Box.createHorizontalGlue());
+        main.add(labels);
+        main.add(Box.createHorizontalStrut(10));
+        main.add(Box.createHorizontalGlue());
+        main.add(controls);
+        main.add(Box.createHorizontalStrut(10));
+        main.add(Box.createVerticalGlue());
+        main.add(extra);
+        main.add(Box.createVerticalGlue());
+        whole.add(Box.createVerticalGlue());
+        whole.add(Box.createVerticalStrut(10));
+        whole.add(main);
+        whole.add(Box.createVerticalGlue());
+        whole.add(Box.createVerticalStrut(10));
+        whole.add(buttons);
+        whole.add(Box.createVerticalGlue());
+        whole.add(Box.createVerticalStrut(10));
+        whole.add(Box.createVerticalGlue());
+        labels.add(createLabel("Recent Setting:"));
+        labels.add(Box.createVerticalGlue());
+        labels.add(createLabel("Setting Name:"));
+        labels.add(Box.createVerticalGlue());
+        labels.add(createLabel("Type:"));
+        labels.add(Box.createVerticalGlue());
+        labels.add(createLabel("Driver:"));
+        labels.add(Box.createVerticalGlue());
+        labels.add(createLabel("URL:"));
+        labels.add(Box.createVerticalGlue());
+        labels.add(createLabel("User:"));
+        labels.add(Box.createVerticalGlue());
+        labels.add(createLabel("Password:"));
+        labels.add(Box.createVerticalGlue());
+        labels.add(Box.createVerticalStrut(10));
+        controls.add(Box.createVerticalGlue());
+
+        // (weconsultants@users) New code
+        mSettingName.setActionCommand("Select Setting");
+        mSettingName.addActionListener(this);
+        controls.add(mSettingName);
+        controls.add(Box.createHorizontalGlue());
+
+        // (weconsultants@users) New code
+        mName = new JTextField();
+
+        mName.addActionListener(this);
+        controls.add(mName);
+
+        // (weconsultants@users) New code
+        clear = new JButton("Clear Names");
+
+        clear.setActionCommand("Clear");
+        clear.addActionListener(this);
+        buttons.add(clear);
+        buttons.add(Box.createHorizontalGlue());
+        buttons.add(Box.createHorizontalStrut(10));
+
+        JComboBox types = new JComboBox();
+
+        connTypes = ConnectionDialogCommon.getTypes();
+
+        for (int i = 0; i < connTypes.length; i++) {
+            types.addItem(connTypes[i][0]);
+        }
+
+        types.addItemListener(this);
+        controls.add(types);
+        controls.add(Box.createVerticalGlue());
+
+        mDriver = new JTextField(connTypes[0][1]);
+
+        mDriver.addActionListener(this);
+        controls.add(mDriver);
+
+        mURL = new JTextField(connTypes[0][2]);
+
+        mURL.addActionListener(this);
+        controls.add(mURL);
+        controls.add(Box.createVerticalGlue());
+
+        mUser = new JTextField("SA");
+
+        mUser.addActionListener(this);
+        controls.add(mUser);
+        controls.add(Box.createVerticalGlue());
+
+        mPassword = new JPasswordField("");
+
+        mPassword.addActionListener(this);
+        controls.add(mPassword);
+        controls.add(Box.createVerticalGlue());
+        controls.add(Box.createVerticalStrut(10));
+
+        // The button bar
+        buttons.add(Box.createHorizontalGlue());
+        buttons.add(Box.createHorizontalStrut(10));
+
+        okCancel = new JButton("     Ok      ");
+
+        okCancel.setActionCommand("ConnectOk");
+        okCancel.addActionListener(this);
+        buttons.add(okCancel);
+        getRootPane().setDefaultButton(okCancel);
+        buttons.add(Box.createHorizontalGlue());
+        buttons.add(Box.createHorizontalStrut(20));
+
+        okCancel = new JButton("  Cancel   ");
+
+        okCancel.setActionCommand("ConnectCancel");
+        okCancel.addActionListener(this);
+        buttons.add(okCancel);
+        buttons.add(Box.createHorizontalGlue());
+        buttons.add(Box.createHorizontalStrut(10));
+
+        JPanel jPanel = new JPanel();
+
+        jPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
+        jPanel.add("Center", whole);
+        getContentPane().add("Center", jPanel);
+        doLayout();
+        pack();
+
+        Dimension d    = Toolkit.getDefaultToolkit().getScreenSize();
+        Dimension size = getSize();
+
+        if (currentConnectionSetting != null) {
+            mName.setText(currentConnectionSetting.getName());
+            mDriver.setText(currentConnectionSetting.getDriver());
+            mURL.setText(currentConnectionSetting.getUrl());
+            mUser.setText(currentConnectionSetting.getUser());
+            mPassword.setText(currentConnectionSetting.getPassword());
+        }
+
+        // (ulrivo): full size on screen with less than 640 width
+        if (d.width >= 640) {
+            setLocation((d.width - size.width) / 2,
+                        (d.height - size.height) / 2);
+        } else {
+            setLocation(0, 0);
+            setSize(d);
+        }
+
+        setVisible(true);
+    }
+
+    public static Connection createConnection(JFrame owner, String title) {
+
+        ConnectionDialogSwing dialog = new ConnectionDialogSwing(owner,
+            title);
+
+//      Added: (weconsultants@users) Default LAF of Native
+        try {
+
+//            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+            SwingUtilities.updateComponentTreeUI(dialog);
+        } catch (Exception e) {
+            CommonSwing.errorMessage(e);
+        }
+
+        dialog.create();
+
+        return dialog.mConnection;
+    }
+
+    private static JLabel createLabel(String s) {
+
+        JLabel l = new JLabel(s);
+
+        return l;
+    }
+
+    // (weconsultants@users) New code
+    public Vector loadRecentConnectionSettings() {
+
+        Vector passSettings = new Vector();
+
+        settings = new Hashtable();
+
+        try {
+            settings = ConnectionDialogCommon.loadRecentConnectionSettings();
+
+            Iterator it = settings.values().iterator();
+
+            passSettings.add(ConnectionDialogCommon.emptySettingName);
+
+            while (it.hasNext()) {
+                passSettings.add(((ConnectionSetting) it.next()).getName());
+            }
+        } catch (java.io.IOException ioe) {
+            CommonSwing.errorMessage(ioe);
+        }
+
+        return (passSettings);
+    }
+
+    public void actionPerformed(ActionEvent ev) {
+
+        String s = ev.getActionCommand();
+
+        if (s.equals("ConnectOk") || (ev.getSource() instanceof JTextField)) {
+            try {
+                if (mURL.getText().indexOf('\u00AB') >= 0) {
+                    throw new Exception("please specify db path");
+                }
+
+                mConnection =
+                    createConnection(mDriver.getText(), mURL.getText(),
+                                     mUser.getText(),
+                                     new String(mPassword.getPassword()));
+
+                // (weconsultants@users) New code
+                if (mName.getText() != null
+                        && mName.getText().trim().length() != 0) {
+                    ConnectionSetting newSetting = new ConnectionSetting(
+                        mName.getText(), mDriver.getText(), mURL.getText(),
+                        mUser.getText(), new String(mPassword.getPassword()));
+
+                    ConnectionDialogCommon.addToRecentConnectionSettings(
+                        settings, newSetting);
+                }
+
+                dispose();
+            } catch (SQLException e) {
+                mConnection = null;
+
+                CommonSwing.errorMessage(e, true);
+            } catch (Exception e) {
+
+                // Added: (weconsultants@users)
+                CommonSwing.errorMessage(e);
+            }
+
+            // (weconsultants@users) New code
+        } else if (s.equals("Select Setting")) {
+            String            s2 = (String) mSettingName.getSelectedItem();
+            ConnectionSetting setting = (ConnectionSetting) settings.get(s2);
+
+            if (setting != null) {
+                mName.setText(setting.getName());
+                mDriver.setText(setting.getDriver());
+                mURL.setText(setting.getUrl());
+                mUser.setText(setting.getUser());
+                mPassword.setText(setting.getPassword());
+            }
+        } else if (s.equals("ConnectCancel")) {
+            dispose();
+
+            // (weconsultants@users) New code
+        } else if (s.equals("Clear")) {
+            ConnectionDialogCommon.deleteRecentConnectionSettings();
+
+            settings = new Hashtable();
+
+            mSettingName.removeAllItems();
+            mSettingName.addItem(ConnectionDialogCommon.emptySettingName);
+            mName.setText(null);
+        }
+    }
+
+    public void itemStateChanged(ItemEvent e) {
+
+        String s = (String) e.getItem();
+
+        for (int i = 0; i < connTypes.length; i++) {
+            if (s.equals(connTypes[i][0])) {
+                mDriver.setText(connTypes[i][1]);
+                mURL.setText(connTypes[i][2]);
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/ConnectionSetting.java b/src/org/hsqldb/util/ConnectionSetting.java
new file mode 100644
index 0000000..8fcf52d
--- /dev/null
+++ b/src/org/hsqldb/util/ConnectionSetting.java
@@ -0,0 +1,101 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+/**
+ * ConnectionSetting represents the various parameters of a data source
+ * connection.
+ *
+ * @author lonbinder@users
+ */
+public class ConnectionSetting implements java.io.Serializable {
+
+    private String name, driver, url, user, pw;
+
+    String getName() {
+        return name;
+    }
+
+    String getDriver() {
+        return driver;
+    }
+
+    String getUrl() {
+        return url;
+    }
+
+    String getUser() {
+        return user;
+    }
+
+    String getPassword() {
+        return pw;
+    }
+
+    // Constructors
+    private ConnectionSetting() {}
+    ;
+
+    ConnectionSetting(String name, String driver, String url, String user,
+                      String pw) {
+
+        this.name   = name;
+        this.driver = driver;
+        this.url    = url;
+        this.user   = user;
+        this.pw     = pw;
+    }
+
+    public boolean equals(Object obj) {
+
+        if (!(obj instanceof ConnectionSetting)) {
+            return false;
+        }
+
+        ConnectionSetting other = (ConnectionSetting) obj;
+
+        if (getName() == other.getName()) {
+            return true;
+        }
+
+        if (getName() == null) {
+            return false;
+        }
+
+        return getName().trim().equals(other.getName().trim());
+    }
+
+    public int hashCode() {
+        return getName() == null ? 0
+                                 : getName().trim().hashCode();
+    }
+}
diff --git a/src/org/hsqldb/util/DataAccessPoint.java b/src/org/hsqldb/util/DataAccessPoint.java
new file mode 100644
index 0000000..149a4c8
--- /dev/null
+++ b/src/org/hsqldb/util/DataAccessPoint.java
@@ -0,0 +1,138 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.Serializable;
+import java.util.Vector;
+
+/**
+ * Database Transfer Tool
+ * @author Nicolas BAZIN, INGENICO
+ * @version 1.7.0
+ */
+class DataAccessPoint implements Serializable {
+
+    Traceable      tracer;
+    TransferHelper helper;
+    String         databaseToConvert;
+
+    public DataAccessPoint() {
+
+        tracer            = null;
+        helper            = HelperFactory.getHelper("");
+        databaseToConvert = "";
+    }
+
+    public DataAccessPoint(Traceable t) {
+
+        tracer = t;
+        helper = HelperFactory.getHelper("");
+
+        helper.set(null, t, "\'");
+
+        databaseToConvert = "";
+    }
+
+    boolean isConnected() {
+        return false;
+    }
+
+    boolean getAutoCommit() throws DataAccessPointException {
+        return false;
+    }
+
+    void commit() throws DataAccessPointException {}
+
+    void rollback() throws DataAccessPointException {}
+
+    void setAutoCommit(boolean flag) throws DataAccessPointException {}
+
+    boolean execute(String statement) throws DataAccessPointException {
+        return false;
+    }
+
+    TransferResultSet getData(String statement)
+    throws DataAccessPointException {
+        return null;
+    }
+
+    void putData(String statement, TransferResultSet r,
+                 int iMaxRows) throws DataAccessPointException {}
+
+    Vector getSchemas() throws DataAccessPointException {
+        return new Vector();
+    }
+
+    Vector getCatalog() throws DataAccessPointException {
+        return new Vector();
+    }
+
+    void setCatalog(String sCatalog) throws DataAccessPointException {}
+
+    Vector getTables(String sCatalog,
+                     String[] sSchemas) throws DataAccessPointException {
+        return new Vector();
+    }
+
+    void getTableStructure(TransferTable SQLCommands,
+                           DataAccessPoint Dest)
+                           throws DataAccessPointException {
+        throw new DataAccessPointException("Nothing to Parse");
+    }
+
+    void close() throws DataAccessPointException {}
+
+    void beginDataTransfer() throws DataAccessPointException {
+
+        try {
+            helper.beginDataTransfer();
+        } catch (Exception e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+    }
+
+    void endDataTransfer() throws DataAccessPointException {
+
+        try {
+            helper.endDataTransfer();
+        } catch (Exception e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+    }
+
+    /**
+     * @return Returns the helper.
+     */
+    public TransferHelper getHelper() {
+        return helper;
+    }
+}
diff --git a/src/org/hsqldb/util/DataAccessPointException.java b/src/org/hsqldb/util/DataAccessPointException.java
new file mode 100644
index 0000000..0d826f8
--- /dev/null
+++ b/src/org/hsqldb/util/DataAccessPointException.java
@@ -0,0 +1,48 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+/**
+ *
+ * @author Nicolas BAZIN, INGENICO
+ * @version 1.7.0
+ */
+class DataAccessPointException extends Exception {
+
+    public DataAccessPointException() {
+        super();
+    }
+
+    public DataAccessPointException(String s) {
+        super(s);
+    }
+}
diff --git a/src/org/hsqldb/util/DatabaseManager.java b/src/org/hsqldb/util/DatabaseManager.java
new file mode 100644
index 0000000..0fc5551
--- /dev/null
+++ b/src/org/hsqldb/util/DatabaseManager.java
@@ -0,0 +1,1334 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.applet.Applet;
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Vector;
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FileDialog;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Image;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.MenuShortcut;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.image.MemoryImageSource;
+
+import org.hsqldb.lib.RCData;
+import org.hsqldb.lib.java.JavaSystem;
+
+// sqlbob@users 20020401 - patch 1.7.0 by sqlbob (RMP) - enhancements
+// sqlbob@users 20020401 - patch 537501 by ulrivo - command line arguments
+// sqlbob@users 20020407 - patch 1.7.0 - reengineering
+// nickferguson@users 20021005 - patch 1.7.1 - enhancements
+/*
+ * unsaved@users 20050426 - Switched default switch method from "-switch" to
+ * "--switch" because "-switch" usage is ambiguous as used here.  Single
+ * switches should be reserved for single-letter switches which can be mixed
+ * like * "-u -r -l" = "-url".  -blaine
+*/
+
+/**
+ * AWT Tool for manageing a JDBC database.<p>
+ * <pre>
+ *             Usage: java DatabaseManagerSwing [--options]
+ *             where options include:
+ *              --driver <classname>  jdbc driver class
+ *              --url <name>          jdbc url
+ *              --user <name>         username used for connection
+ *              --password <password> password for this user
+ *              --urlid <urlid>       get connection info from RC file
+ *              --rcfile <file>       use instead of default (with urlid)
+ *              --dir <path>          default directory
+ *              --script <file>       reads from script file
+ *</pre>
+ *
+ * Originally in HypersonicSQL. Extended in various versions of HSQLDB.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.9.0
+ * @since Hypersonic SQL
+ */
+public class DatabaseManager extends Applet
+implements ActionListener, WindowListener, KeyListener {
+
+    private static final String DEFAULT_RCFILE =
+        System.getProperty("user.home") + "/dbmanager.rc";
+    static final String    NL           = System.getProperty("line.separator");
+    static final int       iMaxRecent   = 24;
+    private static boolean TT_AVAILABLE = false;
+
+//#ifdef JAVA2FULL
+    static {
+        try {
+            Class.forName(DatabaseManager.class.getPackage().getName()
+                          + ".Transfer");
+
+            TT_AVAILABLE = true;
+        } catch (Throwable t) {}
+    }
+
+//#endif
+    private static final String HELP_TEXT =
+        "See the forums, mailing lists, and HSQLDB User Guide\n"
+        + "at http://hsqldb.org.\n\n"
+        + "Please paste the following version identifier with any\n"
+        + "problem reports or help requests:  $Revision: 3573 $"
+        + (TT_AVAILABLE ? ""
+                        : ("\n\nTransferTool classes are not in CLASSPATH.\n"
+                           + "To enable the Tools menu, add 'transfer.jar' to your class path."));
+    ;
+    private static final String ABOUT_TEXT =
+        "$Revision: 3573 $ of DatabaseManager\n\n"
+        + "Copyright (c) 1995-2000, The Hypersonic SQL Group.\n"
+        + "Copyright (c) 2001-2009, The HSQL Development Group.\n"
+        + "http://hsqldb.org  (User Guide available at this site).\n\n\n"
+        + "You may use and redistribute according to the HSQLDB\n"
+        + "license documented in the source code and at the web\n"
+        + "site above."          //
+        + (TT_AVAILABLE ? "\n\nTransferTool options are available."
+                        : "");
+    Connection       cConn;
+    DatabaseMetaData dMeta;
+    Statement        sStatement;
+    Menu             mRecent;
+    String[]         sRecent;
+    int              iRecent;
+    TextArea         txtCommand;
+    Button           butExecute;
+    Button           butClear;
+    Tree             tTree;
+    Panel            pResult;
+    long             lTime;
+    int              iResult;    // 0: grid; 1: text
+    Grid             gResult;
+    TextArea         txtResult;
+    boolean          bHelp;
+    Frame            fMain;
+    Image            imgEmpty;
+    static boolean   bMustExit;
+    String           ifHuge = "";
+
+    // (ulrivo): variables set by arguments from the commandline
+    static String defDriver   = "org.hsqldb.jdbcDriver";
+    static String defURL      = "jdbc:hsqldb:mem:.";
+    static String defUser     = "SA";
+    static String defPassword = "";
+    static String defScript;
+    static String defDirectory;
+
+    public void connect(Connection c) {
+
+        if (c == null) {
+            return;
+        }
+
+        if (cConn != null) {
+            try {
+                cConn.close();
+            } catch (SQLException e) {}
+        }
+
+        cConn = c;
+
+        try {
+            dMeta      = cConn.getMetaData();
+            sStatement = cConn.createStatement();
+
+            refreshTree();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void init() {
+
+        DatabaseManager m = new DatabaseManager();
+
+        m.main();
+
+        try {
+            m.connect(ConnectionDialog.createConnection(defDriver, defURL,
+                    defUser, defPassword));
+            m.insertTestData();
+            m.refreshTree();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Run with --help switch for usage instructions.
+     *
+     * @throws IllegalArgumentException for the obvious reason
+     */
+    public static void main(String[] arg) {
+
+        System.getProperties().put("sun.java2d.noddraw", "true");
+
+        // (ulrivo): read all arguments from the command line
+        String  lowerArg;
+        String  urlid        = null;
+        String  rcFile       = null;
+        boolean autoConnect  = false;
+        boolean urlidConnect = false;
+
+        bMustExit = true;
+
+        for (int i = 0; i < arg.length; i++) {
+            lowerArg = arg[i].toLowerCase();
+
+            if (lowerArg.startsWith("--")) {
+                lowerArg = lowerArg.substring(1);
+            }
+
+            i++;
+
+            if (i == arg.length) {
+                showUsage();
+
+                return;
+            }
+
+            if (lowerArg.equals("-driver")) {
+                defDriver   = arg[i];
+                autoConnect = true;
+            } else if (lowerArg.equals("-url")) {
+                defURL      = arg[i];
+                autoConnect = true;
+            } else if (lowerArg.equals("-user")) {
+                defUser     = arg[i];
+                autoConnect = true;
+            } else if (lowerArg.equals("-password")) {
+                defPassword = arg[i];
+                autoConnect = true;
+            } else if (lowerArg.equals("-urlid")) {
+                urlid        = arg[i];
+                urlidConnect = true;
+            } else if (lowerArg.equals("-rcfile")) {
+                rcFile       = arg[i];
+                urlidConnect = true;
+            } else if (lowerArg.equals("-dir")) {
+                defDirectory = arg[i];
+            } else if (lowerArg.equals("-script")) {
+                defScript = arg[i];
+            } else if (lowerArg.equals("-noexit")) {
+                bMustExit = false;
+
+                i--;
+            } else if (lowerArg.equals("-help")) {
+                showUsage();
+
+                return;
+            } else {
+                /* Syntax ERRORS should either throw or exit with non-0 status.
+                 * In our case, it may be unsafe to exit, so we throw.
+                 * (I.e. should provide easy way for caller to programmatically
+                 * determine that there was an invocation problem).
+                 */
+                throw new IllegalArgumentException(
+                    "Try:  java... " + DatabaseManagerSwing.class.getName()
+                    + " --help");
+
+                // No reason to localize, since the main syntax message is
+                // not localized.
+            }
+        }
+
+        DatabaseManager m = new DatabaseManager();
+
+        m.main();
+
+        Connection c = null;
+
+        try {
+            if (autoConnect && urlidConnect) {
+                throw new IllegalArgumentException(
+                    "You may not specify both (urlid) AND (url/user/password).");
+            }
+
+            if (autoConnect) {
+                c = ConnectionDialog.createConnection(defDriver, defURL,
+                                                      defUser, defPassword);
+            } else if (urlidConnect) {
+                if (urlid == null) {
+                    throw new IllegalArgumentException(
+                        "You must specify an 'urlid' to use an RC file");
+                }
+
+                autoConnect = true;
+
+                if (rcFile == null) {
+                    rcFile = DEFAULT_RCFILE;
+                }
+
+                c = new RCData(new File(rcFile), urlid).getConnection(null,
+                               System.getProperty("javax.net.ssl.trustStore"));
+            } else {
+                c = ConnectionDialog.createConnection(m.fMain, "Connect");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        if (c == null) {
+            return;
+        }
+
+        m.connect(c);
+    }
+
+    private static void showUsage() {
+
+        System.out.println(
+            "Usage: java DatabaseManager [--options]\n"
+            + "where options include:\n"
+            + "    --help                show this message\n"
+            + "    --driver <classname>  jdbc driver class\n"
+            + "    --url <name>          jdbc url\n"
+            + "    --user <name>         username used for connection\n"
+            + "    --password <password> password for this user\n"
+            + "    --urlid <urlid>       use url/user/password/driver in rc file\n"
+            + "    --rcfile <file>       (defaults to 'dbmanager.rc' in home dir)\n"
+            + "    --dir <path>          default directory\n"
+            + "    --script <file>       reads from script file\n"
+            + "    --noexit              do not call system.exit()");
+    }
+
+    void insertTestData() {
+
+        try {
+            DatabaseManagerCommon.createTestTables(sStatement);
+            refreshTree();
+            txtCommand.setText(
+                DatabaseManagerCommon.createTestData(sStatement));
+            refreshTree();
+
+            for (int i = 0; i < DatabaseManagerCommon.testDataSql.length;
+                    i++) {
+                addToRecent(DatabaseManagerCommon.testDataSql[i]);
+            }
+
+            execute();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void main() {
+
+        fMain = new Frame("HSQL Database Manager");
+        imgEmpty = createImage(new MemoryImageSource(2, 2, new int[4 * 4], 2,
+                2));
+
+        fMain.setIconImage(imgEmpty);
+        fMain.addWindowListener(this);
+
+        MenuBar bar = new MenuBar();
+
+        // used shortcuts: CERGTSIUDOLM
+        String[] fitems = {
+            "-Connect...", "--", "-Open Script...", "-Save Script...",
+            "-Save Result...", "-Save Result csv...", "--", "-Exit"
+        };
+
+        addMenu(bar, "File", fitems);
+
+        String[] vitems = {
+            "RRefresh Tree", "--", "GResults in Grid", "TResults in Text",
+            "--", "1Shrink Tree", "2Enlarge Tree", "3Shrink Command",
+            "4Enlarge Command"
+        };
+
+        addMenu(bar, "View", vitems);
+
+        String[] sitems = {
+            "SSELECT", "IINSERT", "UUPDATE", "DDELETE", "--", "-CREATE TABLE",
+            "-DROP TABLE", "-CREATE INDEX", "-DROP INDEX", "--", "-CHECKPOINT",
+            "-SCRIPT", "-SET", "-SHUTDOWN", "--", "-Test Script"
+        };
+
+        addMenu(bar, "Command", sitems);
+
+        Menu recent = new Menu("Recent");
+
+        mRecent = new Menu("Recent");
+
+        bar.add(mRecent);
+
+        String[] soptions = {
+            "-AutoCommit on", "-AutoCommit off", "OCommit", "LRollback", "--",
+            "-Disable MaxRows", "-Set MaxRows to 100", "--", "-Logging on",
+            "-Logging off", "--", "-Insert test data"
+        };
+
+        addMenu(bar, "Options", soptions);
+
+        String[] stools = {
+            "-Dump", "-Restore", "-Transfer"
+        };
+
+        addMenu(bar, "Tools", stools);
+
+        Menu     hMenu = new Menu("Help");
+        MenuItem aItem = new MenuItem("About");
+
+        aItem.setShortcut(new MenuShortcut('A'));
+        aItem.addActionListener(this);
+        hMenu.add(aItem);
+
+        MenuItem hItem = new MenuItem("Help");
+
+        hItem.setShortcut(new MenuShortcut('H'));
+        hItem.addActionListener(this);
+        hMenu.add(hItem);
+
+        //bar.add(hMenu);
+        // Command above disabled only until a help display bug is fixed.
+        fMain.setMenuBar(bar);
+        fMain.setSize(640, 480);
+        fMain.add("Center", this);
+        initGUI();
+
+        sRecent = new String[iMaxRecent];
+
+        Dimension d    = Toolkit.getDefaultToolkit().getScreenSize();
+        Dimension size = fMain.getSize();
+
+        // (ulrivo): full size on screen with less than 640 width
+        if (d.width >= 640) {
+            fMain.setLocation((d.width - size.width) / 2,
+                              (d.height - size.height) / 2);
+        } else {
+            fMain.setLocation(0, 0);
+            fMain.setSize(d);
+        }
+
+        fMain.show();
+
+        // (ulrivo): load query from command line
+        if (defScript != null) {
+            if (defDirectory != null) {
+                defScript = defDirectory + File.separator + defScript;
+            }
+
+            txtCommand.setText(DatabaseManagerCommon.readFile(defScript));
+        }
+
+        txtCommand.requestFocus();
+    }
+
+    void addMenu(MenuBar b, String name, String[] items) {
+
+        /* It's a very poor design to encapsulate menu creation this way.
+         * Can't customize the menus this way (e.g. shortcut keys,
+         * mnemonics, disabling, etc. */
+        Menu menu = new Menu(name);
+
+        if (name.equals("Tools") && !TT_AVAILABLE) {
+
+            // Terrible place to do this.  Forced to due to method design.
+            menu.setEnabled(false);
+        }
+
+        addMenuItems(menu, items);
+        b.add(menu);
+    }
+
+    void addMenuItems(Menu f, String[] m) {
+
+        for (int i = 0; i < m.length; i++) {
+            MenuItem item = new MenuItem(m[i].substring(1));
+            char     c    = m[i].charAt(0);
+
+            if (c != '-') {
+                item.setShortcut(new MenuShortcut(c));
+            }
+
+            item.addActionListener(this);
+            f.add(item);
+        }
+    }
+
+    public void keyPressed(KeyEvent k) {}
+
+    public void keyReleased(KeyEvent k) {}
+
+    public void keyTyped(KeyEvent k) {
+
+        if (k.getKeyChar() == '\n' && k.isControlDown()) {
+            k.consume();
+            execute();
+        }
+    }
+
+    public void actionPerformed(ActionEvent ev) {
+
+        String s = ev.getActionCommand();
+
+        if (s == null) {
+            if (ev.getSource() instanceof MenuItem) {
+                MenuItem i;
+
+                s = ((MenuItem) ev.getSource()).getLabel();
+            }
+        }
+
+        if (s == null) {}
+        else if (s.equals("Execute")) {
+            execute();
+        } else if (s.equals("Clear")) {
+            clear();
+        } else if (s.equals("Exit")) {
+            windowClosing(null);
+        } else if (s.equals("Transfer")) {
+            Transfer.work(null);
+        } else if (s.equals("Dump")) {
+            Transfer.work(new String[]{ "-d" });
+        } else if (s.equals("Restore")) {
+            Transfer.work(new String[]{ "-r" });
+            refreshTree();
+        } else if (s.equals("Logging on")) {
+            JavaSystem.setLogToSystem(true);
+        } else if (s.equals("Logging off")) {
+            JavaSystem.setLogToSystem(false);
+        } else if (s.equals("Help")) {
+            showHelp(new String[] {
+                "", HELP_TEXT
+            });
+        } else if (s.equals("About")) {
+            showHelp(new String[] {
+                "", ABOUT_TEXT
+            });
+        } else if (s.equals("Refresh Tree")) {
+            refreshTree();
+        } else if (s.startsWith("#")) {
+            int i = Integer.parseInt(s.substring(1));
+
+            txtCommand.setText(sRecent[i]);
+        } else if (s.equals("Connect...")) {
+            connect(ConnectionDialog.createConnection(fMain, "Connect"));
+            refreshTree();
+        } else if (s.equals("Results in Grid")) {
+            iResult = 0;
+
+            pResult.removeAll();
+            pResult.add("Center", gResult);
+            pResult.doLayout();
+        } else if (s.equals("Open Script...")) {
+            FileDialog f = new FileDialog(fMain, "Open Script",
+                                          FileDialog.LOAD);
+
+            // (ulrivo): set default directory if set from command line
+            if (defDirectory != null) {
+                f.setDirectory(defDirectory);
+            }
+
+            f.show();
+
+            String file = f.getFile();
+
+            if (file != null) {
+                StringBuffer buf = new StringBuffer();
+
+                ifHuge = DatabaseManagerCommon.readFile(f.getDirectory()
+                        + file);
+
+                if (4096 <= ifHuge.length()) {
+                    buf.append(
+                        "This huge file cannot be edited.\n Please execute or clear\n");
+                    txtCommand.setText(buf.toString());
+                } else {
+                    txtCommand.setText(ifHuge);
+                }
+            }
+        } else if (s.equals("Save Script...")) {
+            FileDialog f = new FileDialog(fMain, "Save Script",
+                                          FileDialog.SAVE);
+
+            // (ulrivo): set default directory if set from command line
+            if (defDirectory != null) {
+                f.setDirectory(defDirectory);
+            }
+
+            f.show();
+
+            String file = f.getFile();
+
+            if (file != null) {
+                DatabaseManagerCommon.writeFile(f.getDirectory() + file,
+                                                txtCommand.getText());
+            }
+        } else if (s.equals("Save Result csv...")) {
+            FileDialog f = new FileDialog(fMain, "Save Result CSV",
+                                          FileDialog.SAVE);
+
+            // (ulrivo): set default directory if set from command line
+            if (defDirectory != null) {
+                f.setDirectory(defDirectory);
+            }
+
+            f.show();
+
+            String dir  = f.getDirectory();
+            String file = f.getFile();
+
+            if (dir != null) {
+                file = dir + "/" + file;
+            }
+
+            if (file != null) {
+                showResultInText();
+                saveAsCsv(file);
+            }
+        } else if (s.equals("Save Result...")) {
+            FileDialog f = new FileDialog(fMain, "Save Result",
+                                          FileDialog.SAVE);
+
+            // (ulrivo): set default directory if set from command line
+            if (defDirectory != null) {
+                f.setDirectory(defDirectory);
+            }
+
+            f.show();
+
+            String file = f.getFile();
+
+            if (file != null) {
+                showResultInText();
+                DatabaseManagerCommon.writeFile(f.getDirectory() + file,
+                                                txtResult.getText());
+            }
+        } else if (s.equals("Results in Text")) {
+            iResult = 1;
+
+            pResult.removeAll();
+            pResult.add("Center", txtResult);
+            pResult.doLayout();
+            showResultInText();
+        } else if (s.equals("AutoCommit on")) {
+            try {
+                cConn.setAutoCommit(true);
+            } catch (SQLException e) {}
+        } else if (s.equals("AutoCommit off")) {
+            try {
+                cConn.setAutoCommit(false);
+            } catch (SQLException e) {}
+        } else if (s.equals("Enlarge Tree")) {
+            Dimension d = tTree.getMinimumSize();
+
+            d.width += 20;
+
+            tTree.setMinimumSize(d);
+            fMain.pack();
+        } else if (s.equals("Shrink Tree")) {
+            Dimension d = tTree.getMinimumSize();
+
+            d.width -= 20;
+
+            if (d.width >= 0) {
+                tTree.setMinimumSize(d);
+            }
+
+            fMain.pack();
+        } else if (s.equals("Enlarge Command")) {
+            txtCommand.setRows(txtCommand.getRows() + 1);
+            fMain.pack();
+        } else if (s.equals("Shrink Command")) {
+            int i = txtCommand.getRows() - 1;
+
+            txtCommand.setRows(i < 1 ? 1
+                                     : i);
+            fMain.pack();
+        } else if (s.equals("Commit")) {
+            try {
+                cConn.commit();
+            } catch (SQLException e) {}
+        } else if (s.equals("Insert test data")) {
+            insertTestData();
+        } else if (s.equals("Rollback")) {
+            try {
+                cConn.rollback();
+            } catch (SQLException e) {}
+        } else if (s.equals("Disable MaxRows")) {
+            try {
+                sStatement.setMaxRows(0);
+            } catch (SQLException e) {}
+        } else if (s.equals("Set MaxRows to 100")) {
+            try {
+                sStatement.setMaxRows(100);
+            } catch (SQLException e) {}
+        } else if (s.equals("SELECT")) {
+            showHelp(DatabaseManagerCommon.selectHelp);
+        } else if (s.equals("INSERT")) {
+            showHelp(DatabaseManagerCommon.insertHelp);
+        } else if (s.equals("UPDATE")) {
+            showHelp(DatabaseManagerCommon.updateHelp);
+        } else if (s.equals("DELETE")) {
+            showHelp(DatabaseManagerCommon.deleteHelp);
+        } else if (s.equals("CREATE TABLE")) {
+            showHelp(DatabaseManagerCommon.createTableHelp);
+        } else if (s.equals("DROP TABLE")) {
+            showHelp(DatabaseManagerCommon.dropTableHelp);
+        } else if (s.equals("CREATE INDEX")) {
+            showHelp(DatabaseManagerCommon.createIndexHelp);
+        } else if (s.equals("DROP INDEX")) {
+            showHelp(DatabaseManagerCommon.dropIndexHelp);
+        } else if (s.equals("CHECKPOINT")) {
+            showHelp(DatabaseManagerCommon.checkpointHelp);
+        } else if (s.equals("SCRIPT")) {
+            showHelp(DatabaseManagerCommon.scriptHelp);
+        } else if (s.equals("SHUTDOWN")) {
+            showHelp(DatabaseManagerCommon.shutdownHelp);
+        } else if (s.equals("SET")) {
+            showHelp(DatabaseManagerCommon.setHelp);
+        } else if (s.equals("Test Script")) {
+            showHelp(DatabaseManagerCommon.testHelp);
+        }
+    }
+
+    void showHelp(String[] help) {
+
+        txtCommand.setText(help[0]);
+        txtResult.setText(help[1]);
+
+        bHelp = true;
+
+        pResult.removeAll();
+        pResult.add("Center", txtResult);
+        pResult.doLayout();
+        txtCommand.requestFocus();
+        txtCommand.setCaretPosition(help[0].length());
+    }
+
+    public void windowActivated(WindowEvent e) {}
+
+    public void windowDeactivated(WindowEvent e) {}
+
+    public void windowClosed(WindowEvent e) {}
+
+    public void windowClosing(WindowEvent ev) {
+
+        try {
+            if (cConn != null) {
+                cConn.close();
+            }
+        } catch (Exception e) {}
+
+        fMain.dispose();
+
+        if (bMustExit) {
+            System.exit(0);
+        }
+    }
+
+    public void windowDeiconified(WindowEvent e) {}
+
+    public void windowIconified(WindowEvent e) {}
+
+    public void windowOpened(WindowEvent e) {}
+
+    /**
+     * Clear SQL Statements.
+     */
+    void clear() {
+
+        ifHuge = "";
+
+        txtCommand.setText(ifHuge);
+    }
+
+    /**
+     * Adjust this method for large strings...ie multi megabtypes.
+     */
+    void execute() {
+
+        String sCmd = null;
+
+        if (4096 <= ifHuge.length()) {
+            sCmd = ifHuge;
+        } else {
+            sCmd = txtCommand.getText();
+        }
+
+        if (sCmd.startsWith("-->>>TEST<<<--")) {
+            testPerformance();
+
+            return;
+        }
+
+        String[] g = new String[1];
+
+        lTime = System.currentTimeMillis();
+
+        try {
+            if (sStatement == null) {
+                return;
+            }
+
+            sStatement.execute(sCmd);
+
+            lTime = System.currentTimeMillis() - lTime;
+
+            int r = sStatement.getUpdateCount();
+
+            if (r == -1) {
+                ResultSet rs = sStatement.getResultSet();
+                try {
+                    formatResultSet(rs);
+                } catch (Throwable t) {
+                    g[0]  = "Error displaying the ResultSet";
+
+                    gResult.setHead(g);
+
+                    String s = t.getMessage();
+
+                    g[0] = s;
+
+                    gResult.addRow(g);
+                }
+            } else {
+                g[0] = "update count";
+
+                gResult.setHead(g);
+
+                g[0] = String.valueOf(r);
+
+                gResult.addRow(g);
+            }
+
+            addToRecent(txtCommand.getText());
+        } catch (SQLException e) {
+            lTime = System.currentTimeMillis() - lTime;
+            g[0]  = "SQL Error";
+
+            gResult.setHead(g);
+
+            String s = e.getMessage();
+
+            s    += " / Error Code: " + e.getErrorCode();
+            s    += " / State: " + e.getSQLState();
+            g[0] = s;
+
+            gResult.addRow(g);
+        }
+
+        updateResult();
+        System.gc();
+    }
+
+    void updateResult() {
+
+        if (iResult == 0) {
+
+            // in case 'help' has removed the grid
+            if (bHelp) {
+                pResult.removeAll();
+                pResult.add("Center", gResult);
+                pResult.doLayout();
+
+                bHelp = false;
+            }
+
+            gResult.update();
+            gResult.repaint();
+        } else {
+            showResultInText();
+        }
+
+        txtCommand.selectAll();
+        txtCommand.requestFocus();
+    }
+
+    void formatResultSet(ResultSet r) {
+
+        if (r == null) {
+            String[] g = new String[1];
+
+            g[0] = "Result";
+
+            gResult.setHead(g);
+
+            g[0] = "(empty)";
+
+            gResult.addRow(g);
+
+            return;
+        }
+
+        try {
+            ResultSetMetaData m   = r.getMetaData();
+            int               col = m.getColumnCount();
+            String[]          h   = new String[col];
+
+            for (int i = 1; i <= col; i++) {
+                h[i - 1] = m.getColumnLabel(i);
+            }
+
+            gResult.setHead(h);
+
+            while (r.next()) {
+                for (int i = 1; i <= col; i++) {
+                    try {
+                        h[i - 1] = r.getString(i);
+
+                        if (r.wasNull()) {
+                            h[i - 1] = "(null)";
+                        }
+                    } catch (SQLException e) {
+                        h[i - 1] = "(binary data)";
+                    }
+                }
+
+                gResult.addRow(h);
+            }
+
+            r.close();
+        } catch (SQLException e) {}
+    }
+
+    void testPerformance() {
+
+        String       all   = txtCommand.getText();
+        StringBuffer b     = new StringBuffer();
+        long         total = 0;
+
+        for (int i = 0; i < all.length(); i++) {
+            char c = all.charAt(i);
+
+            if (c != '\n') {
+                b.append(c);
+            }
+        }
+
+        all = b.toString();
+
+        String[] g = new String[4];
+
+        g[0] = "ms";
+        g[1] = "count";
+        g[2] = "sql";
+        g[3] = "error";
+
+        gResult.setHead(g);
+
+        int max = 1;
+
+        lTime = System.currentTimeMillis() - lTime;
+
+        while (!all.equals("")) {
+            int    i = all.indexOf(';');
+            String sql;
+
+            if (i != -1) {
+                sql = all.substring(0, i);
+                all = all.substring(i + 1);
+            } else {
+                sql = all;
+                all = "";
+            }
+
+            if (sql.startsWith("--#")) {
+                max = Integer.parseInt(sql.substring(3));
+
+                continue;
+            } else if (sql.startsWith("--")) {
+                continue;
+            }
+
+            g[2] = sql;
+
+            long l = 0;
+
+            try {
+                l = DatabaseManagerCommon.testStatement(sStatement, sql, max);
+                total += l;
+                g[0]  = String.valueOf(l);
+                g[1]  = String.valueOf(max);
+                g[3]  = "";
+            } catch (SQLException e) {
+                g[0] = g[1] = "n/a";
+                g[3] = e.toString();
+            }
+
+            gResult.addRow(g);
+            System.out.println(l + " ms : " + sql);
+        }
+
+        g[0] = "" + total;
+        g[1] = "total";
+        g[2] = "";
+
+        gResult.addRow(g);
+
+        lTime = System.currentTimeMillis() - lTime;
+
+        updateResult();
+    }
+
+    void saveAsCsv(String filename) {
+
+        try {
+            File      file   = new File(filename);
+            CSVWriter writer = new CSVWriter(file, null);
+            String[]  col    = gResult.getHead();
+            int       width  = col.length;
+            Vector    data   = gResult.getData();
+            String[]  row;
+            int       height = data.size();
+
+            writer.writeHeader(col);
+
+            for (int i = 0; i < height; i++) {
+                row = (String[]) data.elementAt(i);
+
+                String[] myRow = new String[row.length];
+
+                for (int j = 0; j < row.length; j++) {
+                    String r = row[j];
+
+                    if (r.equals("(null)")) {
+
+                        // null is formatted as (null)
+                        r = "";
+                    }
+
+                    myRow[j] = r;
+                }
+
+                writer.writeData(myRow);
+            }
+
+            writer.close();
+        } catch (IOException e) {
+            throw new RuntimeException("IOError: " + e.getMessage());
+        }
+    }
+
+    void showResultInText() {
+
+        String[] col   = gResult.getHead();
+        int      width = col.length;
+        int[]    size  = new int[width];
+        Vector   data  = gResult.getData();
+        String[] row;
+        int      height = data.size();
+
+        for (int i = 0; i < width; i++) {
+            size[i] = col[i].length();
+        }
+
+        for (int i = 0; i < height; i++) {
+            row = (String[]) data.elementAt(i);
+
+            for (int j = 0; j < width; j++) {
+                int l = row[j].length();
+
+                if (l > size[j]) {
+                    size[j] = l;
+                }
+            }
+        }
+
+        StringBuffer b = new StringBuffer();
+
+        for (int i = 0; i < width; i++) {
+            b.append(col[i]);
+
+            for (int l = col[i].length(); l <= size[i]; l++) {
+                b.append(' ');
+            }
+        }
+
+        b.append(NL);
+
+        for (int i = 0; i < width; i++) {
+            for (int l = 0; l < size[i]; l++) {
+                b.append('-');
+            }
+
+            b.append(' ');
+        }
+
+        b.append(NL);
+
+        for (int i = 0; i < height; i++) {
+            row = (String[]) data.elementAt(i);
+
+            for (int j = 0; j < width; j++) {
+                b.append(row[j]);
+
+                for (int l = row[j].length(); l <= size[j]; l++) {
+                    b.append(' ');
+                }
+            }
+
+            b.append(NL);
+        }
+
+        b.append(NL + height + " row(s) in " + lTime + " ms");
+        txtResult.setText(b.toString());
+    }
+
+    private void addToRecent(String s) {
+
+        for (int i = 0; i < iMaxRecent; i++) {
+            if (s.equals(sRecent[i])) {
+                return;
+            }
+        }
+
+        if (sRecent[iRecent] != null) {
+            mRecent.remove(iRecent);
+        }
+
+        sRecent[iRecent] = s;
+
+        if (s.length() > 43) {
+            s = s.substring(0, 40) + "...";
+        }
+
+        MenuItem item = new MenuItem(s);
+
+        item.setActionCommand("#" + iRecent);
+        item.addActionListener(this);
+        mRecent.insert(item, iRecent);
+
+        iRecent = (iRecent + 1) % iMaxRecent;
+    }
+
+    private void initGUI() {
+
+        Panel pQuery   = new Panel();
+        Panel pCommand = new Panel();
+
+        pResult = new Panel();
+
+        pQuery.setLayout(new BorderLayout());
+        pCommand.setLayout(new BorderLayout());
+        pResult.setLayout(new BorderLayout());
+
+        Font fFont = new Font("Dialog", Font.PLAIN, 12);
+
+        txtCommand = new TextArea(5, 40);
+
+        txtCommand.addKeyListener(this);
+
+        txtResult = new TextArea(20, 40);
+
+        txtCommand.setFont(fFont);
+        txtResult.setFont(new Font("Courier", Font.PLAIN, 12));
+
+        butExecute = new Button("Execute");
+        butClear   = new Button("Clear");
+
+        butExecute.addActionListener(this);
+        butClear.addActionListener(this);
+        pCommand.add("East", butExecute);
+        pCommand.add("West", butClear);
+        pCommand.add("Center", txtCommand);
+
+        gResult = new Grid();
+
+        setLayout(new BorderLayout());
+        pResult.add("Center", gResult);
+        pQuery.add("North", pCommand);
+        pQuery.add("Center", pResult);
+        fMain.add("Center", pQuery);
+
+        tTree = new Tree();
+
+        // (ulrivo): screen with less than 640 width
+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+
+        if (d.width >= 640) {
+            tTree.setMinimumSize(new Dimension(200, 100));
+        } else {
+            tTree.setMinimumSize(new Dimension(80, 100));
+        }
+
+        gResult.setMinimumSize(new Dimension(200, 300));
+        fMain.add("West", tTree);
+        doLayout();
+        fMain.pack();
+    }
+
+    protected void refreshTree() {
+
+        boolean wasAutoCommit = false;
+
+        tTree.removeAll();
+
+        try {
+            wasAutoCommit = cConn.getAutoCommit();
+
+            cConn.setAutoCommit(false);
+
+            int color_table  = Color.yellow.getRGB();
+            int color_column = Color.orange.getRGB();
+            int color_index  = Color.red.getRGB();
+
+            tTree.addRow("", dMeta.getURL(), "-", 0);
+
+            String[] usertables = {
+                "TABLE", "GLOBAL TEMPORARY", "VIEW"
+            };
+
+            // fredt@users Schema support
+            Vector schemas = new Vector();
+            Vector tables  = new Vector();
+
+            // sqlbob@users Added remarks.
+            Vector    remarks = new Vector();
+            ResultSet result  = dMeta.getTables(null, null, null, usertables);
+
+            try {
+                while (result.next()) {
+                    schemas.addElement(result.getString(2));
+                    tables.addElement(result.getString(3));
+                    remarks.addElement(result.getString(5));
+                }
+            } finally {
+                result.close();
+            }
+
+            for (int i = 0; i < tables.size(); i++) {
+                String name   = (String) tables.elementAt(i);
+                String schema = (String) schemas.elementAt(i);
+                String key    = "tab-" + name + "-";
+
+                tTree.addRow(key, name, "+", color_table);
+
+                // sqlbob@users Added remarks.
+                String remark = (String) remarks.elementAt(i);
+
+                if ((schema != null) && !schema.trim().equals("")) {
+                    tTree.addRow(key + "s", "schema: " + schema);
+                }
+
+                if ((remark != null) && !remark.trim().equals("")) {
+                    tTree.addRow(key + "r", " " + remark);
+                }
+
+                ResultSet col = dMeta.getColumns(null, schema, name, null);
+
+                try {
+                    while (col.next()) {
+                        String c  = col.getString(4);
+                        String k1 = key + "col-" + c + "-";
+
+                        tTree.addRow(k1, c, "+", color_column);
+
+                        String type = col.getString(6);
+
+                        tTree.addRow(k1 + "t", "Type: " + type);
+
+                        boolean nullable = col.getInt(11)
+                                           != DatabaseMetaData.columnNoNulls;
+
+                        tTree.addRow(k1 + "n", "Nullable: " + nullable);
+                    }
+                } finally {
+                    col.close();
+                }
+
+                tTree.addRow(key + "ind", "Indices", "+", 0);
+
+                ResultSet ind = dMeta.getIndexInfo(null, schema, name, false,
+                                                   false);
+                String oldiname = null;
+
+                try {
+                    while (ind.next()) {
+                        boolean nonunique = ind.getBoolean(4);
+                        String  iname     = ind.getString(6);
+                        String  k2        = key + "ind-" + iname + "-";
+
+                        if ((oldiname == null || !oldiname.equals(iname))) {
+                            tTree.addRow(k2, iname, "+", color_index);
+                            tTree.addRow(k2 + "u", "Unique: " + !nonunique);
+
+                            oldiname = iname;
+                        }
+
+                        String c = ind.getString(9);
+
+                        tTree.addRow(k2 + "c-" + c + "-", c);
+                    }
+                } finally {
+                    ind.close();
+                }
+            }
+
+            tTree.addRow("p", "Properties", "+", 0);
+            tTree.addRow("pu", "User: " + dMeta.getUserName());
+            tTree.addRow("pr", "ReadOnly: " + cConn.isReadOnly());
+            tTree.addRow("pa", "AutoCommit: " + cConn.getAutoCommit());
+            tTree.addRow("pd", "Driver: " + dMeta.getDriverName());
+            tTree.addRow("pp", "Product: " + dMeta.getDatabaseProductName());
+            tTree.addRow("pv",
+                         "Version: " + dMeta.getDatabaseProductVersion());
+        } catch (SQLException e) {
+            tTree.addRow("", "Error getting metadata:", "-", 0);
+            tTree.addRow("-", e.getMessage());
+            tTree.addRow("-", e.getSQLState());
+        } finally {
+            try {
+                cConn.setAutoCommit(wasAutoCommit);
+            } catch (SQLException e) {}
+        }
+
+        tTree.update();
+    }
+}
diff --git a/src/org/hsqldb/util/DatabaseManagerCommon.java b/src/org/hsqldb/util/DatabaseManagerCommon.java
new file mode 100644
index 0000000..9145d2c
--- /dev/null
+++ b/src/org/hsqldb/util/DatabaseManagerCommon.java
@@ -0,0 +1,385 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Random;
+
+// sqlbob@users 20020401 - patch 1.7.0 by sqlbob (RMP) - enhancements
+// sqlbob@users 20020407 - patch 1.7.0 - reengineering
+// nickferguson@users 20021005 - patch 1.7.1 - enhancements
+// fredt@users 20021012 - patch 1.7.1 - changes to test database DDL
+// weconsultants@users 20041116 - patch 1.8.0 - in 'TestHelp' added 'IF EXISTS for both DROPS.
+//                                Now catching the execption that was never caught before.
+
+/**
+ * Common code in Swing and AWT versions of DatabaseManager
+ *
+ * New class based on Hypersonic original
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.7.0
+ */
+class DatabaseManagerCommon {
+
+    private static Random rRandom    = new Random(100);
+    static String[]       selectHelp = {
+        "SELECT * FROM ",
+
+        "SELECT [LIMIT n m] [DISTINCT] \n"
+        + "{ selectExpression | table.* | * } [, ... ] \n"
+        + "[INTO [CACHED|TEMP|TEXT] newTable] \n" + "FROM tableList \n"
+        + "[WHERE Expression] \n"
+        + "[ORDER BY selectExpression [{ASC | DESC}] [, ...] ] \n"
+        + "[GROUP BY Expression [, ...] ] \n"                             //
+        + "[UNION [ALL] selectStatement]"
+    };
+    static String[] insertHelp = {
+        "INSERT INTO ",
+        "INSERT INTO table [ (column [,...] ) ] \n"
+        + "{ VALUES(Expression [,...]) [,...] | SelectStatement }"
+    };
+    static String[] updateHelp = {
+        "UPDATE ",
+        "UPDATE table SET column = Expression [, ...] \n"
+        + "[WHERE Expression]"
+    };
+    static String[] deleteHelp      = {
+        "DELETE FROM ", "DELETE FROM table [WHERE Expression]"
+    };
+    static String[] createTableHelp = {
+        "CREATE TABLE ",
+        "CREATE [TEMP] [CACHED|MEMORY|TEXT] TABLE name \n"
+        + "( columnDefinition [, ...] ) \n\n" + "columnDefinition: \n"
+        + "column DataType [ [NOT] NULL] [PRIMARY KEY] \n" + "DataType: \n"
+        + "{ INTEGER | DOUBLE | VARCHAR | DATE | TIME |... }"
+    };
+    static String[] dropTableHelp   = {
+        "DROP TABLE ", "DROP TABLE table"
+    };
+    static String[] createIndexHelp = {
+        "CREATE INDEX ",
+        "CREATE [UNIQUE] INDEX index ON \n" + "table (column [, ...])"
+    };
+    static String[] dropIndexHelp  = {
+        "DROP INDEX ", "DROP INDEX table.index"
+    };
+    static String[] checkpointHelp = {
+        "CHECKPOINT", "(HSQLDB SQL only)"
+    };
+    static String[] scriptHelp     = {
+        "SCRIPT", "SCRIPT ['file']\n\n" + "(HSQLDB SQL only)"
+    };
+    static String[] shutdownHelp   = {
+        "SHUTDOWN",
+        "SHUTDOWN [COMPACT|IMMEDIATELY|SCRIPT]\n\n" + "(HSQLDB SQL only)"
+    };
+    static String[] setHelp = {
+        "SET ",
+
+        "SET AUTOCOMMIT { TRUE | FALSE }\n"
+        + "SET DATABASE COLLATION \"<collationname>\"\n"
+        + "SET FILES CHECKPOINT DEFRAG <size>\n"
+        + "SET DATABASE INITIAL SCHEMA <schemaname>\n"                             //
+        + "SET FILES LOG SIZE <size>\n"                                          //
+        + "SET MAXROWS maxrows\n"                                         //
+        + "SET PASSWORD <password>\n"                                     //
+        + "SET FILES READ { ONLY | WRITE }\n"
+        + "SET SCHEMA <schemaname>\n"
+        + "SET TABLE <tablename> READ { ONLY | WRITE }\n"
+        + "SET TABLE <tablename> SOURCE { ON | OFF }\n"
+        + "SET TABLE <tablename> SOURCE \"<file>\" [DESC]\n"
+        + "\n\n"                                                          //
+        + "(HSQLDB SQL only)"
+    };
+    static String[] testHelp = {
+        "-->>>TEST<<<-- ;\n" + "--#1000;\n" + "DROP TABLE Test IF EXISTS;\n"
+        + "CREATE TABLE Test(\n" + "  Id INTEGER PRIMARY KEY,\n"
+        + "  FirstName VARCHAR(20),\n" + "  Name VARCHAR(50),\n"
+        + "  ZIP INTEGER) ;\n" + "INSERT INTO Test \n"
+        + "  VALUES(#,'Julia','Peterson-Clancy',#) ;\n"
+        + "UPDATE Test SET Name='Hans' WHERE Id=# ;\n"
+        + "SELECT * FROM Test WHERE Id=# ;\n"
+        + "DELETE FROM Test WHERE Id=# ;\n" + "DROP TABLE Test IF EXISTS;",
+        "This test script is parsed by the DatabaseManager\n"
+        + "It may be changed manually. Rules:\n"
+        + "- it must start with -->>>TEST<<<--.\n"
+        + "- each line must end with ';' (no spaces after)\n"
+        + "- lines starting with -- are comments\n"
+        + "- lines starting with --#<count> means set new count\n"
+    };
+    static String[] testDataSql = {
+        "SELECT * FROM Product",                                          //
+        "SELECT * FROM Invoice",                                          //
+        "SELECT * FROM Item",
+        "SELECT * FROM Customer a INNER JOIN Invoice i ON a.ID=i.CustomerID",
+        "SELECT * FROM Customer a LEFT OUTER JOIN Invoice i ON a.ID=i.CustomerID",
+        "SELECT * FROM Invoice d INNER JOIN Item i ON d.ID=i.InvoiceID",
+        "SELECT * FROM Customer WHERE Street LIKE '1%' ORDER BY Lastname",
+        "SELECT a.id, a.firstname, a.lastname, count(i.Total) \"COUNT\", "
+        + "COALESCE(sum(i.Total), 0) \"TOTAL\", COALESCE(AVG(i.Total),0) \"AVG\" FROM Customer a "
+        + "LEFT OUTER JOIN Invoice i ON a.ID=i.CustomerID GROUP BY a.id, a.firstname, a.lastname"
+    };
+
+    static String random(String[] s) {
+        return s[random(s.length)];
+    }
+
+    static int random(int i) {
+
+        i = rRandom.nextInt() % i;
+
+        return i < 0 ? -i
+                     : i;
+    }
+
+    static void createTestTables(Statement sStatement) {
+
+        String[] demo = {
+            "DROP TABLE Item IF EXISTS;", "DROP TABLE Invoice IF EXISTS;",
+            "DROP TABLE Product IF EXISTS;", "DROP TABLE Customer IF EXISTS;",
+            "CREATE TABLE Customer(ID INTEGER PRIMARY KEY,FirstName VARCHAR(20),"
+            + "LastName VARCHAR(20),Street VARCHAR(20),City VARCHAR(20));",
+            "CREATE TABLE Product(ID INTEGER PRIMARY KEY,Name VARCHAR(20),"
+            + "Price DECIMAL(10,2));",
+            "CREATE TABLE Invoice(ID INTEGER PRIMARY KEY,CustomerID INTEGER,"
+            + "Total DECIMAL(10,2), FOREIGN KEY (CustomerId) "
+            + "REFERENCES Customer(ID) ON DELETE CASCADE);",
+            "CREATE TABLE Item(InvoiceID INTEGER,Item INTEGER,"
+            + "ProductID INTEGER,Quantity INTEGER,Cost DECIMAL(10,2),"
+            + "PRIMARY KEY(InvoiceID,Item), "
+            + "FOREIGN KEY (InvoiceId) REFERENCES "
+            + "Invoice (ID) ON DELETE CASCADE, FOREIGN KEY (ProductId) "
+            + "REFERENCES Product(ID) ON DELETE CASCADE);"
+        };
+
+        for (int i = 0; i < demo.length; i++) {
+
+            // drop table may fail
+            try {
+                sStatement.execute(demo[i]);
+            } catch (SQLException e) {
+                ;
+            }
+        }
+    }
+
+    static String createTestData(Statement sStatement) throws SQLException {
+
+        String[] name = {
+            "White", "Karsen", "Smith", "Ringer", "May", "King", "Fuller",
+            "Miller", "Ott", "Sommer", "Schneider", "Steel", "Peterson",
+            "Heiniger", "Clancy"
+        };
+        String[] firstname = {
+            "Mary", "James", "Anne", "George", "Sylvia", "Robert", "Janet",
+            "Michael", "Andrew", "Bill", "Susanne", "Laura", "Bob", "Julia",
+            "John"
+        };
+        String[] street = {
+            "Upland Pl.", "College Av.", "- 20th Ave.", "Seventh Av."
+        };
+        String[] city   = {
+            "New York", "Dallas", "Boston", "Chicago", "Seattle",
+            "San Francisco", "Berne", "Oslo", "Paris", "Lyon", "Palo Alto",
+            "Olten"
+        };
+        String[] product = {
+            "Iron", "Ice Tea", "Clock", "Chair", "Telephone", "Shoe"
+        };
+        int      max     = 50;
+
+        for (int i = 0; i < max; i++) {
+            sStatement.execute("INSERT INTO Customer VALUES(" + i + ",'"
+                               + random(firstname) + "','" + random(name)
+                               + "','" + random(554) + " " + random(street)
+                               + "','" + random(city) + "')");
+            sStatement.execute("INSERT INTO Product VALUES(" + i + ",'"
+                               + random(product) + " " + random(product)
+                               + "'," + (20 + 2 * random(120)) + ")");
+        }
+
+        for (int i = 0; i < max; i++) {
+            sStatement.execute("INSERT INTO Invoice VALUES(" + i + ","
+                               + random(max) + ",0.0)");
+
+            for (int j = random(20) + 2; j >= 0; j--) {
+                sStatement.execute("INSERT INTO Item VALUES(" + i + "," + j
+                                   + "," + random(max) + ","
+                                   + (1 + random(24)) + ",1.5)");
+            }
+        }
+
+        sStatement.execute("UPDATE Product SET Price=ROUND(Price*.1,2)");
+        sStatement.execute(
+            "UPDATE Item SET Cost=Cost*"
+            + "(SELECT Price FROM Product prod WHERE ProductID=prod.ID)");
+        sStatement.execute(
+            "UPDATE Invoice SET Total=(SELECT SUM(Cost*"
+            + "Quantity) FROM Item WHERE InvoiceID=Invoice.ID)");
+
+        return ("SELECT * FROM Customer");
+    }
+
+    /**
+     * Redid this file to remove sizing requirements and to make it faster
+     * Speeded it up 10 fold.
+     *
+     * @param file
+     */
+    static String readFile(String file) {
+
+        try {
+            FileReader     reader = new FileReader(file);
+            BufferedReader read   = new BufferedReader(reader);
+            StringBuffer   b      = new StringBuffer();
+            String         s      = null;
+            int            count  = 0;
+
+            while ((s = read.readLine()) != null) {
+                count++;
+
+                b.append(s);
+                b.append('\n');
+            }
+
+            read.close();
+            reader.close();
+
+            return b.toString();
+        } catch (IOException e) {
+            return e.getMessage();
+        }
+    }
+
+    static void writeFile(String file, String text) {
+
+        try {
+            FileWriter write = new FileWriter(file);
+
+            write.write(text.toCharArray());
+            write.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @throws SQLException
+     */
+    static long testStatement(Statement sStatement, String sql,
+                              int max) throws SQLException {
+
+        long start = System.currentTimeMillis();
+
+        if (sql.indexOf('#') == -1) {
+            max = 1;
+        }
+
+        for (int i = 0; i < max; i++) {
+            String s = sql;
+
+            while (true) {
+                int j = s.indexOf("#r#");
+
+                if (j == -1) {
+                    break;
+                }
+
+                s = s.substring(0, j) + ((int) (Math.random() * i))
+                    + s.substring(j + 3);
+            }
+
+            while (true) {
+                int j = s.indexOf('#');
+
+                if (j == -1) {
+                    break;
+                }
+
+                s = s.substring(0, j) + i + s.substring(j + 1);
+            }
+
+            sStatement.execute(s);
+        }
+
+        return (System.currentTimeMillis() - start);
+    }
+
+    private DatabaseManagerCommon() {}
+}
diff --git a/src/org/hsqldb/util/DatabaseManagerSwing.java b/src/org/hsqldb/util/DatabaseManagerSwing.java
new file mode 100644
index 0000000..73eb2d9
--- /dev/null
+++ b/src/org/hsqldb/util/DatabaseManagerSwing.java
@@ -0,0 +1,3100 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessControlException;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Vector;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.Font;
+import java.awt.Insets;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JApplet;
+import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JToolBar;
+import javax.swing.JTree;
+import javax.swing.KeyStroke;
+import javax.swing.RootPaneContainer;
+import javax.swing.SwingUtilities;
+import javax.swing.table.TableModel;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.MutableTreeNode;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import org.hsqldb.lib.RCData;
+import org.hsqldb.lib.java.JavaSystem;
+
+//dmarshall@users - 20020101 - original swing port of DatabaseManager
+//sqlbob@users 20020401 - patch 537501 by ulrivo - commandline arguments
+//sqlbob@users 20020407 - patch 1.7.0 - reengineering and enhancements
+//nickferguson@users 20021005 - patch 1.7.1 - enhancements
+//deccles@users 2004 - 2008 - bug fixes and enhancements
+//weconsultants@users 20041109 - version 1.8.0 - reengineering and enhancements:
+//              Added: Goodies 'Look and Feel'.
+//              Added: a Font Changer(Font Type\Style).
+//              Added: a Color Changer (foreground\bckground).
+//              Added: RowCounts for each JTree table nodes.
+//              Added: OneTouchExpandable attribute to JSplitPanes.
+//              Moved: setFramePositon code to a CommonSwing.setFramePositon() Method.
+//              Added: call to new method to handle exception processing (CommonSwing.errorMessage());
+//              Added: Added a new pane added at the bottom of the Frame. (Status Icon and StatusLine).
+//              Added: 2 Methods (setStatusMessage()), one overrides the other. One to change the ruung status
+//                              another to allow a message to be posted without changing the Status Icon if needed.
+//              Added: Added a customCursor for the current wait cursor
+//      Added: Ability to switch the current LAF while runing (Native,Java or Motif)
+//unsaved@users 2005xxxx - improvements and bug fixes
+
+/**
+ * Swing Tool for managing a JDBC database.<p>
+ * <pre>
+ *             Usage: java DatabaseManagerSwing [--options]
+ *             where options include:
+ *              --driver <classname>  jdbc driver class
+ *              --url <name>          jdbc url
+ *              --user <name>         username used for connection
+ *              --password <password> password for this user
+ *              --dir <path>          default directory
+ *              --script <file>       reads from script file
+ *              --urlid <urlid>       get connection info from RC file
+ *              --rcfile <file>       use instead of default (with urlid)
+ *              --noexit              Don't exit JVM
+ * </pre>
+ *
+ * Note that the sys-table switch will not work for Oracle, because Oracle
+ * does not categorize their system tables correctly in the JDBC Metadata.
+ *
+ * New class based on Hypersonic SQL original
+ *
+ * @author dmarshall@users
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.8.0
+ * @since 1.7.0
+ */
+public class DatabaseManagerSwing extends JApplet
+implements ActionListener, WindowListener, KeyListener, MouseListener {
+
+    /*
+     * This is down here because it is an  implementation note, not a
+     * Javadoc comment!
+     * Tue Apr 26 16:38:54 EDT 2005
+     * Switched default switch method from "-switch" to "--switch" because
+     * "-switch" usage is ambiguous as used here.  Single switches should
+     * be reserved for single-letter switches which can be mixed like
+     * "-u -r -l" = "-url".  -blaine
+     */
+    private static String homedir  = null;
+    private boolean       isOracle = false;    // Need some workarounds for Oracle
+
+    static {
+        try {
+            Class c = Class.forName("sun.security.action.GetPropertyAction");
+            Constructor constructor = c.getConstructor(new Class[]{
+                String.class });
+            java.security.PrivilegedAction a =
+                (java.security.PrivilegedAction) constructor.newInstance(
+                    new Object[]{ "user.home" });
+
+            homedir = (String) java.security.AccessController.doPrivileged(a);
+        } catch (IllegalAccessException e) {
+            System.err.println(
+                "Failed to get home directory.\n"
+                + "Therefore not retrieving/storing user preferences.\n("
+                + e.getMessage() + ')');
+        } catch (NoSuchMethodException e) {
+            System.err.println(
+                "Failed to get home directory.\n"
+                + "Therefore not retrieving/storing user preferences.\n("
+                + e.getMessage() + ')');
+        } catch (ClassNotFoundException e) {
+            System.err.println(
+                "Failed to get home directory.\n"
+                + "Therefore not retrieving/storing user preferences.\n("
+                + e.getMessage() + ')');
+        } catch (InstantiationException e) {
+            System.err.println(
+                "Failed to get home directory.\n"
+                + "Therefore not retrieving/storing user preferences.\n("
+                + e.getMessage() + ')');
+        } catch (InvocationTargetException e) {
+            System.err.println(
+                "Failed to get home directory.\n"
+                + "Therefore not retrieving/storing user preferences.\n("
+                + e.getMessage() + ')');
+        } catch (AccessControlException e) {
+            System.err.println(
+                "Failed to get home directory.\n"
+                + "Therefore not retrieving/storing user preferences.\n("
+                + e.getMessage() + ')');
+        }
+    }
+
+    ArrayList                   localActionList = new ArrayList();
+    private JFrame              jframe          = null;
+    private static final String DEFAULT_RCFILE  = homedir + "/dbmanager.rc";
+    private static boolean      TT_AVAILABLE    = false;
+
+    static {
+        try {
+            Class.forName(DatabaseManagerSwing.class.getPackage().getName()
+                          + ".Transfer");
+
+            TT_AVAILABLE = true;
+        } catch (Throwable t) {
+
+            //System.err.println("Failed to get "
+            //+ DatabaseManagerSwing.class.getPackage().getName()
+            //+ ".Transfer: " + t);
+            // Enable this print statement for debugging class access problems.
+        }
+    }
+
+    private static final String HELP_TEXT =
+        "See the HSQLDB Utilities Guide, forums and mailing lists \n"
+        + "at http://hsqldb.org.\n\n"
+        + "Please paste the following version identifier with any\n"
+        + "problem reports or help requests:  $Revision: 3529 $"
+        + (TT_AVAILABLE ? ""
+                        : ("\n\nTransferTool classes are not in CLASSPATH.\n"
+                           + "To enable the Tools menu, add 'transfer.jar' "
+                           + "to your class path."));
+    ;
+    private static final String ABOUT_TEXT =
+        "$Revision: 3529 $ of DatabaseManagerSwing\n\n"
+        + "Copyright (c) 1995-2000, The Hypersonic SQL Group.\n"
+        + "Copyright (c) 2001-2010, The HSQL Development Group.\n"
+        + "http://hsqldb.org  (Utilities Guide available at this site).\n\n\n"
+        + "You may use and redistribute according to the HSQLDB\n"
+        + "license documented in the source code and at the web\n"
+        + "site above."
+        + (TT_AVAILABLE ? "\n\nTransferTool options are available."
+                        : "");
+    static final String    NL         = System.getProperty("line.separator");
+    static final String    NULL_STR   = "[null]";
+    static int             iMaxRecent = 24;
+    Connection             cConn;
+    Connection             rowConn;    // holds the connetion for getting table row counts
+    DatabaseMetaData       dMeta;
+    Statement              sStatement;
+    JMenu                  mRecent;
+    String[]               sRecent;
+    int                    iRecent;
+    JTextArea              txtCommand;
+    JScrollPane            txtCommandScroll;
+    JButton                butExecute;
+    JTree                  tTree;
+    JScrollPane            tScrollPane;
+    DefaultTreeModel       treeModel;
+    TableModel             tableModel;
+    DefaultMutableTreeNode rootNode;
+    JPanel                 pResult;
+    long                   lTime;
+    GridSwing              gResult;
+
+    /**
+     * I think this is used to store model info whether we're using Grid
+     *  output or not (this object is queried for data to display for
+     *  text output mode).
+     *  If so, the presentation-independent model part should be moved
+     *  to an appropriately-named class instead of storing pure data in
+     *  a Swing-specific class.
+     */
+    JTable            gResultTable;
+    JScrollPane       gScrollPane;
+    JTextArea         txtResult;
+    JScrollPane       txtResultScroll;
+    JSplitPane        nsSplitPane;     // Contains query over results
+    JSplitPane        ewSplitPane;     // Contains tree beside nsSplitPane
+    boolean           bHelp;
+    RootPaneContainer fMain;
+    static boolean    bMustExit;
+
+    /** Value of this variable only retained if huge input script read in. */
+    String          sqlScriptBuffer = null;
+    JToolBar        jtoolbar;
+    private boolean showSchemas  = true;
+    private boolean showTooltips = true;
+    private boolean autoRefresh  = true;
+    private boolean gridFormat   = true;
+
+    // Added: (weconsultants@users)
+    static DatabaseManagerSwing refForFontDialogSwing;
+    boolean                     displayRowCounts = false;
+    boolean                     showSys          = false;
+    boolean                     showIndexDetails = true;
+    String                      currentLAF       = null;
+    JPanel                      pStatus;
+    static JButton              iReadyStatus;
+    JRadioButtonMenuItem        rbAllSchemas = new JRadioButtonMenuItem("*");
+    JMenuItem                   mitemAbout   = new JMenuItem("About", 'A');
+    JMenuItem                   mitemHelp    = new JMenuItem("Help", 'H');
+    JMenuItem mitemUpdateSchemas             = new JMenuItem("Update Schemas");
+    JCheckBoxMenuItem boxAutoCommit =
+        new JCheckBoxMenuItem(AUTOCOMMIT_BOX_TEXT);
+    JCheckBoxMenuItem boxLogging = new JCheckBoxMenuItem(LOGGING_BOX_TEXT);
+    JCheckBoxMenuItem boxShowSchemas =
+        new JCheckBoxMenuItem(SHOWSCHEMAS_BOX_TEXT);
+    JCheckBoxMenuItem boxAutoRefresh =
+        new JCheckBoxMenuItem(AUTOREFRESH_BOX_TEXT);
+    JCheckBoxMenuItem boxTooltips  = new JCheckBoxMenuItem(SHOWTIPS_BOX_TEXT);
+    JCheckBoxMenuItem boxRowCounts = new JCheckBoxMenuItem(ROWCOUNTS_BOX_TEXT);
+    JCheckBoxMenuItem boxShowGrid  = new JCheckBoxMenuItem(GRID_BOX_TEXT);
+    JCheckBoxMenuItem boxShowSys   = new JCheckBoxMenuItem(SHOWSYS_BOX_TEXT);
+
+    // Consider adding GTK and Plaf L&Fs.
+    JRadioButtonMenuItem rbNativeLF =
+        new JRadioButtonMenuItem("Native Look & Feel");
+    JRadioButtonMenuItem rbJavaLF =
+        new JRadioButtonMenuItem("Java Look & Feel");
+    JRadioButtonMenuItem rbMotifLF =
+        new JRadioButtonMenuItem("Motif Look & Feel");
+    JLabel                      jStatusLine;
+    static String               READY_STATUS         = "Ready";
+    private static final String AUTOCOMMIT_BOX_TEXT  = "Autocommit mode";
+    private static final String LOGGING_BOX_TEXT     = "Logging mode";
+    private static final String SHOWSCHEMAS_BOX_TEXT = "Show schemas";
+    private static final String AUTOREFRESH_BOX_TEXT = "Auto-refresh tree";
+    private static final String SHOWTIPS_BOX_TEXT    = "Show Tooltips";
+    private static final String ROWCOUNTS_BOX_TEXT   = "Show row counts";
+    private static final String SHOWSYS_BOX_TEXT     = "Show system tables";
+    private static final String GRID_BOX_TEXT =
+        "Show results in Grid (a.o.t. Text)";
+
+    // variables to hold the default cursors for these top level swing objects
+    // so we can restore them when we exit our thread
+    Cursor        fMainCursor;
+    Cursor        txtCommandCursor;
+    Cursor        txtResultCursor;
+    HashMap       tipMap     = new HashMap();
+    private JMenu mnuSchemas = new JMenu("Schemas");
+
+    /**
+     * Wait Cursor
+     */
+
+    // Changed: (weconsultants@users): commonted out the, out of the box, cursor to use a custom cursor
+    private final Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR);
+
+    //getToolkit().createCustomCursor(CommonSwing.getIcon("SystemCursor"),
+    //                                new Point(4, 4), "HourGlass cursor");
+    // (ulrivo): variables set by arguments from the commandline
+    static String  defDriver   = "org.hsqldb.jdbcDriver";
+    static String  defURL      = "jdbc:hsqldb:mem:.";
+    static String  defUser     = "SA";
+    static String  defPassword = "";
+    static String  defScript;
+    static String  defDirectory;
+    private String schemaFilter = null;
+
+    public DatabaseManagerSwing() {
+        jframe = new JFrame("HSQLDB DatabaseManager");
+        fMain  = jframe;
+    }
+    ;
+
+    public DatabaseManagerSwing(JFrame frameIn) {
+        jframe = frameIn;
+        fMain  = jframe;
+    }
+    ;
+
+    public void init() {
+
+        javax.swing.AbstractButton btn;
+
+        fMain = this;
+
+        main();
+
+        for (int i = 0; i < localActionList.size(); i++) {
+            btn = (javax.swing.AbstractButton) localActionList.get(i);
+
+            btn.setEnabled(false);
+        }
+
+        Connection c    = null;
+        boolean    auto = false;
+
+        if (getParameter("jdbcDriver") != null) {
+            auto      = true;
+            defDriver = getParameter("jdbcDriver");
+        }
+
+        if (getParameter("jdbcUrl") != null) {
+            auto   = true;
+            defURL = getParameter("jdbcUrl");
+        }
+
+        if (getParameter("jdbcUser") != null) {
+            auto    = true;
+            defUser = getParameter("jdbcUser");
+        }
+
+        if (getParameter("jdbcPassword") != null) {
+            auto        = true;
+            defPassword = getParameter("jdbcPassword");
+        }
+
+        try {
+            setWaiting("Initializing");
+
+            //insertTestData();
+            //updateAutoCommitBox();
+            c = (auto
+                 ? ConnectionDialogSwing.createConnection(defDriver, defURL,
+                     defUser, defPassword)
+                 : ConnectionDialogSwing.createConnection(jframe, "Connect"));
+        } catch (Exception e) {
+
+            //  Added: (weconsultants@users)
+            CommonSwing.errorMessage(e);
+        } finally {
+            setWaiting(null);
+        }
+
+        if (c != null) {
+            connect(c);
+        }
+
+        if (getParameter("loadSampleData") != null
+                && getParameter("loadSampleData").equals("true")) {
+            insertTestData();
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {}
+            ;
+
+            // I don't know why, but the tree refresh below sometimes
+            // doesn't show all tables unless I put this delay here.
+            refreshTree();
+        }
+
+        if (getParameter("schemaFilter") != null) {
+            schemaFilter = getParameter("schemaFilter");
+        }
+    }
+
+    /**
+     * Run with --help switch for usage instructions.
+     *
+     * @throws IllegalArgumentException for the obvious reason
+     */
+    public static void main(String[] arg) {
+
+        System.getProperties().put("sun.java2d.noddraw", "true");
+
+        // (ulrivo): read all arguments from the command line
+        String  lowerArg;
+        String  urlid        = null;
+        String  rcFile       = null;
+        boolean autoConnect  = false;
+        boolean urlidConnect = false;
+
+        bMustExit = true;
+
+        for (int i = 0; i < arg.length; i++) {
+            lowerArg = arg[i].toLowerCase();
+
+            if (lowerArg.startsWith("--")) {
+                lowerArg = lowerArg.substring(1);
+            }
+
+            i++;
+
+            if (lowerArg.equals("-driver")) {
+                defDriver   = arg[i];
+                autoConnect = true;
+            } else if (lowerArg.equals("-url")) {
+                defURL      = arg[i];
+                autoConnect = true;
+            } else if (lowerArg.equals("-user")) {
+                defUser     = arg[i];
+                autoConnect = true;
+            } else if (lowerArg.equals("-password")) {
+                defPassword = arg[i];
+                autoConnect = true;
+            } else if (lowerArg.equals("-urlid")) {
+                urlid        = arg[i];
+                urlidConnect = true;
+            } else if (lowerArg.equals("-rcfile")) {
+                rcFile       = arg[i];
+                urlidConnect = true;
+            } else if (lowerArg.equals("-dir")) {
+                defDirectory = arg[i];
+            } else if (lowerArg.equals("-script")) {
+                defScript = arg[i];
+            } else if (lowerArg.equals("-noexit")) {
+                bMustExit = false;
+
+                i--;
+            } else if (lowerArg.equals("-help")) {
+                showUsage();
+
+                return;
+            } else {
+                /* Syntax ERRORS should either throw or exit with non-0 status.
+                 * In our case, it may be unsafe to exit, so we throw.
+                 * (I.e. should provide easy way for caller to programmatically
+                 * determine that there was an invocation problem).
+                 */
+                throw new IllegalArgumentException(
+                    "Try:  java... " + DatabaseManagerSwing.class.getName()
+                    + " --help");
+
+                // No reason to localize, since the main syntax message is
+                // not localized.
+            }
+        }
+
+        DatabaseManagerSwing m =
+            new DatabaseManagerSwing(new JFrame("HSQL Database Manager"));
+
+        // Added: (weconsultants@users): Need databaseManagerSwing for later Reference
+        refForFontDialogSwing = m;
+
+        m.main();
+
+        Connection c = null;
+
+        m.setWaiting("Initializing");
+
+        try {
+            if (autoConnect && urlidConnect) {
+                throw new IllegalArgumentException(
+                    "You may not specify both (urlid) AND (url/user/password).");
+            }
+
+            if (autoConnect) {
+                c = ConnectionDialogSwing.createConnection(defDriver, defURL,
+                        defUser, defPassword);
+            } else if (urlidConnect) {
+                if (urlid == null) {
+                    throw new IllegalArgumentException(
+                        "You must specify an 'urlid' to use an RC file");
+                }
+
+                autoConnect = true;
+
+                String rcfilepath = (rcFile == null) ? DEFAULT_RCFILE
+                                                     : rcFile;
+                RCData rcdata     = new RCData(new File(rcfilepath), urlid);
+
+                c = rcdata.getConnection(
+                    null, System.getProperty("javax.net.ssl.trustStore"));
+            } else {
+                c = ConnectionDialogSwing.createConnection(m.jframe,
+                        "Connect");
+            }
+        } catch (Exception e) {
+
+            //  Added: (weconsultants@users)
+            CommonSwing.errorMessage(e);
+        } finally {
+            m.setWaiting(null);
+        }
+
+        if (c != null) {
+            m.connect(c);
+        }
+
+        // Added: (weconsultants@users): For preloadng FontDialogSwing
+        FontDialogSwing.creatFontDialog(refForFontDialogSwing);
+        m.start();
+    }
+
+    /**
+     * This stuff is all quick, except for the refreshTree().
+     * This unit can be kicked off in main Gui thread.  The refreshTree
+     * will be backgrounded and this method will return.
+     */
+    public void connect(Connection c) {
+
+        schemaFilter = null;
+
+        if (c == null) {
+            return;
+        }
+
+        if (cConn != null) {
+            try {
+                cConn.close();
+            } catch (SQLException e) {
+
+                //  Added: (weconsultants@users)
+                CommonSwing.errorMessage(e);
+            }
+        }
+
+        cConn = c;
+
+        // Added: (weconsultants@users) Need to barrow to get the table rowcounts
+        rowConn = c;
+
+        try {
+            dMeta      = cConn.getMetaData();
+            isOracle = (dMeta.getDatabaseProductName().indexOf("Oracle") >= 0);
+            sStatement = cConn.createStatement();
+
+            updateAutoCommitBox();
+
+            // Workaround for EXTREME SLOWNESS getting this info from O.
+            showIndexDetails = !isOracle;
+
+            Driver driver = DriverManager.getDriver(dMeta.getURL());
+            ConnectionSetting newSetting = new ConnectionSetting(
+                dMeta.getDatabaseProductName(), driver.getClass().getName(),
+                dMeta.getURL(),
+                dMeta.getUserName().replaceAll("@localhost", ""), "");
+            Hashtable settings =
+                ConnectionDialogCommon.loadRecentConnectionSettings();
+
+            ConnectionDialogCommon.addToRecentConnectionSettings(settings,
+                    newSetting);
+            ConnectionDialogSwing.setConnectionSetting(newSetting);
+            refreshTree();
+            clearResultPanel();
+
+            if (fMain instanceof JApplet) {
+                getAppletContext().showStatus(
+                    "JDBC Connection established to a "
+                    + dMeta.getDatabaseProductName() + " v. "
+                    + dMeta.getDatabaseProductVersion() + " database as '"
+                    + dMeta.getUserName() + "'.");
+            }
+        } catch (SQLException e) {
+
+            //  Added: (weconsultants@users)
+            CommonSwing.errorMessage(e);
+        } catch (IOException e) {
+
+            //  Added: (weconsultants@users)
+            CommonSwing.errorMessage(e);
+        } catch (Exception e) {
+            CommonSwing.errorMessage(e);
+        }
+    }
+
+    private static void showUsage() {
+
+        System.out.println(
+            "Usage: java DatabaseManagerSwing [--options]\n"
+            + "where options include:\n"
+            + "    --help                show this message\n"
+            + "    --driver <classname>  jdbc driver class\n"
+            + "    --url <name>          jdbc url\n"
+            + "    --user <name>         username used for connection\n"
+            + "    --password <password> password for this user\n"
+            + "    --urlid <urlid>       use url/user/password/driver in rc file\n"
+            + "    --rcfile <file>       (defaults to 'dbmanager.rc' in home dir)\n"
+            + "    --dir <path>          default directory\n"
+            + "    --script <file>       reads from script file\n"
+            + "    --noexit              do not call system.exit()");
+    }
+
+    private void insertTestData() {
+
+        try {
+            DatabaseManagerCommon.createTestTables(sStatement);
+            txtCommand.setText(
+                DatabaseManagerCommon.createTestData(sStatement));
+
+            for (int i = 0; i < DatabaseManagerCommon.testDataSql.length;
+                    i++) {
+                addToRecent(DatabaseManagerCommon.testDataSql[i]);
+            }
+
+            executeCurrentSQL();
+        } catch (SQLException e) {
+
+            //  Added: (weconsultants@users)
+            CommonSwing.errorMessage(e);
+        }
+    }
+
+    public void setMustExit(boolean b) {
+        this.bMustExit = b;
+    }
+
+    private DBMPrefs prefs = null;
+
+    public void main() {
+
+        JMenu     jmenu;
+        JMenuItem mitem;
+
+        try {
+            prefs = new DBMPrefs(fMain instanceof JApplet);
+        } catch (Exception e) {
+            System.err.println(
+                "Failed to load preferences.  Proceeding with defaults:\n");
+        }
+
+        if (prefs == null) {
+            setLF(CommonSwing.Native);
+        } else {
+            autoRefresh      = prefs.autoRefresh;
+            displayRowCounts = prefs.showRowCounts;
+            showSys          = prefs.showSysTables;
+            showSchemas      = prefs.showSchemas;
+            gridFormat       = prefs.resultGrid;
+            showTooltips     = prefs.showTooltips;
+
+            setLF(prefs.laf);
+        }
+
+        // (ulrivo): An actual icon.  N.b., this adds some tips to the tip map
+        fMain.getContentPane().add(createToolBar(), "North");
+
+        if (fMain instanceof java.awt.Frame) {
+            ((java.awt.Frame) fMain).setIconImage(
+                CommonSwing.getIcon("Frame"));
+        }
+
+        if (fMain instanceof java.awt.Window) {
+            ((java.awt.Window) fMain).addWindowListener(this);
+        }
+
+        JMenuBar bar = new JMenuBar();
+
+        // used shortcuts: CERGTSIUDOLM
+        String[] fitems = {
+            "-Connect...", "--", "OOpen Script...", "-Save Script...",
+            "-Save Result...", "--", "-Exit"
+        };
+
+        jmenu = addMenu(bar, "File", fitems);
+
+        // All actions after Connect and the divider are local.
+        for (int i = 2; i < jmenu.getItemCount(); i++) {
+            mitem = jmenu.getItem(i);
+
+            if (mitem != null) {
+                localActionList.add(mitem);
+            }
+        }
+
+        Object[] vitems = {
+            "RRefresh Tree", boxAutoRefresh, "--", boxRowCounts, boxShowSys,
+            boxShowSchemas, boxShowGrid
+        };
+
+        addMenu(bar, "View", vitems);
+
+        String[] sitems = {
+            "SSELECT", "IINSERT", "UUPDATE", "DDELETE", "EEXECUTE", "---",
+            "-CREATE TABLE", "-DROP TABLE", "-CREATE INDEX", "-DROP INDEX",
+            "--", "CCOMMIT*", "LROLLBACK*", "-CHECKPOINT*", "-SCRIPT", "-SET",
+            "-SHUTDOWN", "--", "-Test Script"
+        };
+
+        addMenu(bar, "Command", sitems);
+
+        mRecent = new JMenu("Recent");
+
+        mRecent.setMnemonic(KeyEvent.VK_R);
+        bar.add(mRecent);
+
+        ButtonGroup lfGroup = new ButtonGroup();
+
+        lfGroup.add(rbNativeLF);
+        lfGroup.add(rbJavaLF);
+        lfGroup.add(rbMotifLF);
+        boxShowSchemas.setSelected(showSchemas);
+        boxShowGrid.setSelected(gridFormat);
+        boxTooltips.setSelected(showTooltips);
+        boxShowGrid.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G,
+                Event.CTRL_MASK));
+        boxAutoRefresh.setSelected(autoRefresh);
+        boxRowCounts.setSelected(displayRowCounts);
+        boxShowSys.setSelected(showSys);
+        rbNativeLF.setActionCommand("LFMODE:" + CommonSwing.Native);
+        rbJavaLF.setActionCommand("LFMODE:" + CommonSwing.Java);
+        rbMotifLF.setActionCommand("LFMODE:" + CommonSwing.Motif);
+        tipMap.put(mitemUpdateSchemas, "Refresh the schema list in this menu");
+        tipMap.put(rbAllSchemas, "Display items in all schemas");
+        tipMap.put(mitemAbout, "Display product information");
+        tipMap.put(mitemHelp, "Display advice for obtaining help");
+        tipMap.put(boxAutoRefresh,
+                   "Refresh tree (and schema list) automatically"
+                   + "when YOU modify database objects");
+        tipMap.put(boxShowSchemas,
+                   "Display object names in tree-like schemaname.basename");
+        tipMap.put(rbNativeLF,
+                   "Set Look and Feel to Native for your platform");
+        tipMap.put(rbJavaLF, "Set Look and Feel to Java");
+        tipMap.put(rbMotifLF, "Set Look and Feel to Motif");
+        boxTooltips.setToolTipText("Display tooltips (hover text), like this");
+        tipMap.put(boxAutoCommit,
+                   "Shows current Auto-commit mode.  Click to change");
+        tipMap.put(
+            boxLogging,
+            "Shows current JDBC DriverManager logging mode.  Click to change");
+        tipMap.put(boxShowSys, "Show system tables in table tree to the left");
+        tipMap.put(boxShowGrid, "Show query results in grid (in text if off)");
+        tipMap.put(boxRowCounts, "Show row counts with table names in tree");
+        boxAutoRefresh.setMnemonic(KeyEvent.VK_C);
+        boxShowSchemas.setMnemonic(KeyEvent.VK_Y);
+        boxAutoCommit.setMnemonic(KeyEvent.VK_A);
+        boxShowSys.setMnemonic(KeyEvent.VK_Y);
+        boxShowGrid.setMnemonic(KeyEvent.VK_G);
+        boxRowCounts.setMnemonic(KeyEvent.VK_C);
+        boxLogging.setMnemonic(KeyEvent.VK_L);
+        rbAllSchemas.setMnemonic(KeyEvent.VK_ASTERISK);
+        rbNativeLF.setMnemonic(KeyEvent.VK_N);
+        rbJavaLF.setMnemonic(KeyEvent.VK_J);
+        rbMotifLF.setMnemonic(KeyEvent.VK_M);
+        mitemUpdateSchemas.setMnemonic(KeyEvent.VK_U);
+
+        Object[] soptions = {
+
+            // Added: (weconsultants@users) New menu options
+            rbNativeLF, rbJavaLF, rbMotifLF, "--", "-Set Fonts", "--",
+            boxAutoCommit, "--", "-Disable MaxRows", "-Set MaxRows to 100",
+            "--", boxLogging, "--", "-Insert test data"
+        };
+
+        addMenu(bar, "Options", soptions);
+
+        String[] stools = {
+            "-Dump", "-Restore", "-Transfer"
+        };
+
+        jmenu = addMenu(bar, "Tools", stools);
+
+        jmenu.setEnabled(TT_AVAILABLE);
+        localActionList.add(jmenu);
+
+        for (int i = 0; i < jmenu.getItemCount(); i++) {
+            mitem = jmenu.getItem(i);
+
+            if (mitem != null) {
+                localActionList.add(mitem);
+            }
+        }
+
+        mnuSchemas.setMnemonic(KeyEvent.VK_S);
+        bar.add(mnuSchemas);
+
+        JMenu mnuHelp = new JMenu("Help");
+
+        mnuHelp.setMnemonic(KeyEvent.VK_H);
+        mnuHelp.add(mitemAbout);
+        mnuHelp.add(mitemHelp);
+        mnuHelp.add(boxTooltips);
+        rbAllSchemas.addActionListener(schemaListListener);
+
+        // May be illegal:
+        mitemUpdateSchemas.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent actionevent) {
+                updateSchemaList();
+            }
+        });
+        mitemHelp.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent actionevent) {
+
+                JOptionPane.showMessageDialog(fMain.getContentPane(),
+                                              HELP_TEXT, "HELP",
+                                              JOptionPane.INFORMATION_MESSAGE);
+            }
+        });
+        mitemAbout.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent actionevent) {
+
+                JOptionPane.showMessageDialog(fMain.getContentPane(),
+                                              ABOUT_TEXT, "About",
+                                              JOptionPane.INFORMATION_MESSAGE);
+            }
+        });
+        boxTooltips.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent actionevent) {
+
+                showTooltips = boxTooltips.isSelected();
+
+                resetTooltips();
+            }
+        });
+        bar.add(mnuHelp);
+
+        if (fMain instanceof JApplet) {
+            ((JApplet) fMain).setJMenuBar(bar);
+        } else if (fMain instanceof JFrame) {
+            ((JFrame) fMain).setJMenuBar(bar);
+        }
+
+        initGUI();
+
+        sRecent = new String[iMaxRecent];
+
+        // Modified: (weconsultants@users)Mode code to CommonSwing for general use
+        if (!(fMain instanceof JApplet)) {
+            CommonSwing.setFramePositon((JFrame) fMain);
+        }
+
+        // Modified: (weconsultants@users) Changed from deprecated show()
+        ((Component) fMain).setVisible(true);
+
+        // (ulrivo): load query from command line
+        if (defScript != null) {
+            if (defDirectory != null) {
+                defScript = defDirectory + File.separator + defScript;
+            }
+
+            // if insert stmet is thousands of records...skip showing it
+            // as text.  Too huge.
+            sqlScriptBuffer = DatabaseManagerCommon.readFile(defScript);
+
+            if (4096 <= sqlScriptBuffer.length()) {
+                int eoThirdLine = sqlScriptBuffer.indexOf('\n');
+
+                if (eoThirdLine > 0) {
+                    eoThirdLine = sqlScriptBuffer.indexOf('\n',
+                                                          eoThirdLine + 1);
+                }
+
+                if (eoThirdLine > 0) {
+                    eoThirdLine = sqlScriptBuffer.indexOf('\n',
+                                                          eoThirdLine + 1);
+                }
+
+                if (eoThirdLine < 1) {
+                    eoThirdLine = 100;
+                }
+
+                txtCommand.setText(
+                    "............... Script File loaded: " + defScript
+                    + " ..................... \n"
+                    + "............... Click Execute or Clear "
+                    + "...................\n"
+                    + sqlScriptBuffer.substring(0, eoThirdLine + 1)
+                    + "..........................................."
+                    + "..............................\n"
+                    + "............................................."
+                    + "............................\n");
+                txtCommand.setEnabled(false);
+            } else {
+                txtCommand.setText(sqlScriptBuffer);
+
+                sqlScriptBuffer = null;
+
+                txtCommand.setEnabled(true);
+            }
+        }
+
+        // This must be done AFTER all tip texts are put into the map
+        resetTooltips();
+        txtCommand.requestFocus();
+    }
+
+    private JMenu addMenu(JMenuBar b, String name, Object[] items) {
+
+        JMenu menu = new JMenu(name);
+
+        menu.setMnemonic(name.charAt(0));
+        addMenuItems(menu, items);
+        b.add(menu);
+
+        return menu;
+    }
+
+    private void addMenuItems(JMenu f, Object[] m) {
+
+        /*
+         * This method needs to be completely written or just
+         * obliterated and we'll use the Menu objects directly.
+         * Problem is, passing in Strings for menu elements makes it
+         * extremely difficult to use non-text menu items (an important
+         * part of a good Gui), hot-keys, mnemonic keys, tooltips.
+         * Note the "trick" required here to set hot-keys.
+         */
+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+
+        for (int i = 0; i < m.length; i++) {
+            if (m[i].equals("--")) {
+                f.addSeparator();
+            } else if (m[i].equals("---")) {
+
+                // (ulrivo): full size on screen with less than 640 width
+                if (d.width >= 640) {
+                    f.addSeparator();
+                } else {
+                    return;
+                }
+            } else {
+                JMenuItem item;
+
+                if (m[i] instanceof JMenuItem) {
+                    item = (JMenuItem) m[i];
+                } else if (m[i] instanceof String) {
+                    item = new JMenuItem(((String) m[i]).substring(1));
+
+                    char c = ((String) m[i]).charAt(0);
+
+                    if (c != '-') {
+                        KeyStroke key =
+                            KeyStroke.getKeyStroke(c, Event.CTRL_MASK);
+
+                        item.setAccelerator(key);
+                    }
+                } else {
+                    throw new RuntimeException(
+                        "Unexpected element for menu item creation: "
+                        + m[i].getClass().getName());
+                }
+
+                item.addActionListener(this);
+                f.add(item);
+            }
+        }
+    }
+
+    public void keyPressed(KeyEvent k) {}
+
+    public void keyReleased(KeyEvent k) {}
+
+    public void keyTyped(KeyEvent k) {
+
+        if (k.getKeyChar() == '\n' && k.isControlDown()) {
+            k.consume();
+            executeCurrentSQL();
+        }
+    }
+
+    Thread dummyThread = new Thread("dummy");
+
+    public void actionPerformed(ActionEvent ev) {
+
+        String s = ev.getActionCommand();
+
+        if (s == null) {
+            if (ev.getSource() instanceof JMenuItem) {
+                s = ((JMenuItem) ev.getSource()).getText();
+            }
+        }
+
+        if (s == null) {}
+        else if (s.equals("Exit")) {
+            windowClosing(null);
+        } else if (s.equals("Transfer")) {
+            Transfer.work(null);
+        } else if (s.equals("Dump")) {
+            Transfer.work(new String[]{ "-d" });
+        } else if (s.equals("Restore")) {
+            JOptionPane.showMessageDialog(
+                fMain.getContentPane(),
+                "Use Ctrl-R or the View menu to\n"
+                + "update nav. tree after Restoration", "Suggestion",
+                    JOptionPane.INFORMATION_MESSAGE);
+
+            // Regardless of whether autoRefresh is on, half of
+            // Restore runs asynchronously, so we could only
+            // update the tree from within the Transfer class.
+            Transfer.work(new String[]{ "-r" });
+
+            // Would be better to put the modal suggestion here, after the
+            // user selects the import file, but that messes up the z
+            // layering of the 3 windows already displayed.
+        } else if (s.equals(LOGGING_BOX_TEXT)) {
+            JavaSystem.setLogToSystem(boxLogging.isSelected());
+        } else if (s.equals(AUTOREFRESH_BOX_TEXT)) {
+            autoRefresh = boxAutoRefresh.isSelected();
+
+            refreshTree();
+        } else if (s.equals("Refresh Tree")) {
+            refreshTree();
+        } else if (s.startsWith("#")) {
+            int i = Integer.parseInt(s.substring(1));
+
+            txtCommand.setText(sRecent[i]);
+        } else if (s.equals("Connect...")) {
+            Connection newCon = null;
+
+            try {
+                setWaiting("Connecting");
+
+                newCon = ConnectionDialogSwing.createConnection(jframe,
+                        "Connect");
+            } finally {
+                setWaiting(null);
+            }
+
+            connect(newCon);
+        } else if (s.equals(GRID_BOX_TEXT)) {
+            gridFormat = boxShowGrid.isSelected();
+
+            displayResults();
+        } else if (s.equals("Open Script...")) {
+            JFileChooser f = new JFileChooser(".");
+
+            f.setDialogTitle("Open Script...");
+
+            // (ulrivo): set default directory if set from command line
+            if (defDirectory != null) {
+                f.setCurrentDirectory(new File(defDirectory));
+            }
+
+            int option = f.showOpenDialog((Component) fMain);
+
+            if (option == JFileChooser.APPROVE_OPTION) {
+                File file = f.getSelectedFile();
+
+                if (file != null) {
+                    sqlScriptBuffer =
+                        DatabaseManagerCommon.readFile(file.getAbsolutePath());
+
+                    if (4096 <= sqlScriptBuffer.length()) {
+                        int eoThirdLine = sqlScriptBuffer.indexOf('\n');
+
+                        if (eoThirdLine > 0) {
+                            eoThirdLine = sqlScriptBuffer.indexOf('\n',
+                                                                  eoThirdLine
+                                                                  + 1);
+                        }
+
+                        if (eoThirdLine > 0) {
+                            eoThirdLine = sqlScriptBuffer.indexOf('\n',
+                                                                  eoThirdLine
+                                                                  + 1);
+                        }
+
+                        if (eoThirdLine < 1) {
+                            eoThirdLine = 100;
+                        }
+
+                        txtCommand.setText(
+                            "............... Script File loaded: " + file
+                            + " ..................... \n"
+                            + "............... Click Execute or Clear "
+                            + "...................\n"
+                            + sqlScriptBuffer.substring(0, eoThirdLine + 1)
+                            + "........................................."
+                            + "................................\n"
+                            + "..........................................."
+                            + "..............................\n");
+                        txtCommand.setEnabled(false);
+                    } else {
+                        txtCommand.setText(sqlScriptBuffer);
+
+                        sqlScriptBuffer = null;
+
+                        txtCommand.setEnabled(true);
+                    }
+                }
+            }
+        } else if (s.equals("Save Script...")) {
+            JFileChooser f = new JFileChooser(".");
+
+            f.setDialogTitle("Save Script");
+
+            // (ulrivo): set default directory if set from command line
+            if (defDirectory != null) {
+                f.setCurrentDirectory(new File(defDirectory));
+            }
+
+            int option = f.showSaveDialog((Component) fMain);
+
+            if (option == JFileChooser.APPROVE_OPTION) {
+                File file = f.getSelectedFile();
+
+                if (file != null) {
+                    DatabaseManagerCommon.writeFile(file.getAbsolutePath(),
+                                                    txtCommand.getText());
+                }
+            }
+        } else if (s.equals("Save Result...")) {
+            JFileChooser f = new JFileChooser(".");
+
+            f.setDialogTitle("Save Result...");
+
+            // (ulrivo): set default directory if set from command line
+            if (defDirectory != null) {
+                f.setCurrentDirectory(new File(defDirectory));
+            }
+
+            int option = f.showSaveDialog((Component) fMain);
+
+            if (option == JFileChooser.APPROVE_OPTION) {
+                File file = f.getSelectedFile();
+
+                if (file != null) {
+                    showResultInText();
+                    DatabaseManagerCommon.writeFile(file.getAbsolutePath(),
+                                                    txtResult.getText());
+                }
+            }
+        } else if (s.equals(SHOWSYS_BOX_TEXT)) {
+            showSys = boxShowSys.isSelected();
+
+            refreshTree();
+        } else if (s.equals(ROWCOUNTS_BOX_TEXT)) {
+            displayRowCounts = boxRowCounts.isSelected();
+
+            refreshTree();
+        } else if (s.startsWith("LFMODE:")) {
+            setLF(s.substring("LFMODE:".length()));
+        } else if (s.equals("Set Fonts")) {
+
+            // Added: (weconsultants@users)
+            FontDialogSwing.creatFontDialog(refForFontDialogSwing);
+        } else if (s.equals(AUTOCOMMIT_BOX_TEXT)) {
+            try {
+                cConn.setAutoCommit(boxAutoCommit.isSelected());
+            } catch (SQLException e) {
+                boxAutoCommit.setSelected(!boxAutoCommit.isSelected());
+
+                //  Added: (weconsultants@users)
+                CommonSwing.errorMessage(e);
+            }
+        } else if (s.equals("COMMIT*")) {
+            try {
+                cConn.commit();
+                showHelp(new String[] {
+                    "", "COMMIT executed"
+                });
+            } catch (SQLException e) {
+
+                //  Added: (weconsultants@users)
+                CommonSwing.errorMessage(e);
+            }
+        } else if (s.equals("Insert test data")) {
+            insertTestData();
+            refreshTree();
+        } else if (s.equals("ROLLBACK*")) {
+            try {
+                cConn.rollback();
+                showHelp(new String[] {
+                    "", "ROLLBACK executed"
+                });
+            } catch (SQLException e) {
+
+                //  Added: (weconsultants@users)
+                CommonSwing.errorMessage(e);
+            }
+        } else if (s.equals("Disable MaxRows")) {
+            try {
+                sStatement.setMaxRows(0);
+            } catch (SQLException e) {
+
+                //  Added: (weconsultants@users)
+                CommonSwing.errorMessage(e);
+            }
+        } else if (s.equals("Set MaxRows to 100")) {
+            try {
+                sStatement.setMaxRows(100);
+            } catch (SQLException e) {
+                CommonSwing.errorMessage(e);
+            }
+        } else if (s.equals("SELECT")) {
+            showHelp(DatabaseManagerCommon.selectHelp);
+        } else if (s.equals("INSERT")) {
+            showHelp(DatabaseManagerCommon.insertHelp);
+        } else if (s.equals("UPDATE")) {
+            showHelp(DatabaseManagerCommon.updateHelp);
+        } else if (s.equals("DELETE")) {
+            showHelp(DatabaseManagerCommon.deleteHelp);
+        } else if (s.equals("EXECUTE")) {
+            executeCurrentSQL();
+        } else if (s.equals("CREATE TABLE")) {
+            showHelp(DatabaseManagerCommon.createTableHelp);
+        } else if (s.equals("DROP TABLE")) {
+            showHelp(DatabaseManagerCommon.dropTableHelp);
+        } else if (s.equals("CREATE INDEX")) {
+            showHelp(DatabaseManagerCommon.createIndexHelp);
+        } else if (s.equals("DROP INDEX")) {
+            showHelp(DatabaseManagerCommon.dropIndexHelp);
+        } else if (s.equals("CHECKPOINT*")) {
+            try {
+                cConn.createStatement().executeUpdate("CHECKPOINT");
+                showHelp(new String[] {
+                    "", "CHECKPOINT executed"
+                });
+            } catch (SQLException e) {
+                CommonSwing.errorMessage(e);
+            }
+        } else if (s.equals("SCRIPT")) {
+            showHelp(DatabaseManagerCommon.scriptHelp);
+        } else if (s.equals("SHUTDOWN")) {
+            showHelp(DatabaseManagerCommon.shutdownHelp);
+        } else if (s.equals("SET")) {
+            showHelp(DatabaseManagerCommon.setHelp);
+        } else if (s.equals("Test Script")) {
+            showHelp(DatabaseManagerCommon.testHelp);
+        } else if (s.equals(SHOWSCHEMAS_BOX_TEXT)) {
+            showSchemas = boxShowSchemas.isSelected();
+
+            refreshTree();
+        } else {
+            throw new RuntimeException("Unexpected action triggered: " + s);
+        }
+    }
+
+    private void displayResults() {
+
+        if (gridFormat) {
+            setResultsInGrid();
+        } else {
+            setResultsInText();
+        }
+    }
+
+    private void setResultsInGrid() {
+
+        pResult.removeAll();
+        pResult.add(gScrollPane, BorderLayout.CENTER);
+        pResult.doLayout();
+        gResult.fireTableChanged(null);
+        pResult.repaint();
+    }
+
+    private void setResultsInText() {
+
+        pResult.removeAll();
+        pResult.add(txtResultScroll, BorderLayout.CENTER);
+        pResult.doLayout();
+        showResultInText();
+        pResult.repaint();
+    }
+
+    private void showHelp(String[] help) {
+
+        txtCommand.setText(help[0]);
+
+        bHelp = true;
+
+        pResult.removeAll();
+        pResult.add(txtResultScroll, BorderLayout.CENTER);
+        pResult.doLayout();
+        txtResult.setText(help[1]);
+        pResult.repaint();
+        txtCommand.requestFocus();
+        txtCommand.setCaretPosition(help[0].length());
+    }
+
+    public void windowActivated(WindowEvent e) {}
+
+    public void windowDeactivated(WindowEvent e) {}
+
+    public void windowClosed(WindowEvent e) {}
+
+    public void windowDeiconified(WindowEvent e) {}
+
+    public void windowIconified(WindowEvent e) {}
+
+    public void windowOpened(WindowEvent e) {}
+
+    public void windowClosing(WindowEvent ev) {
+
+        stop();
+
+        try {
+            if (cConn != null) {
+                cConn.close();
+            }
+
+            if (prefs != null) {
+                prefs.autoRefresh   = autoRefresh;
+                prefs.showRowCounts = displayRowCounts;
+                prefs.showSysTables = showSys;
+                prefs.showSchemas   = showSchemas;
+                prefs.resultGrid    = gridFormat;
+                prefs.showTooltips  = showTooltips;
+                prefs.laf           = currentLAF;
+
+                prefs.store();
+            }
+        } catch (Exception e) {
+
+            //  Added: (weconsultants@users)
+            CommonSwing.errorMessage(e);
+        }
+
+        if (fMain instanceof java.awt.Window) {
+            ((java.awt.Window) fMain).dispose();
+        }
+
+        if (bMustExit) {
+            System.exit(0);
+        }
+    }
+
+    private void clear() {
+
+        sqlScriptBuffer = null;
+
+        txtCommand.setText("");
+        txtCommand.setEnabled(true);
+    }
+
+    private String busyText = null;
+
+    private void backgroundIt(Runnable r, String description) {
+
+        if (busyText != null) {
+            Toolkit.getDefaultToolkit().beep();
+
+            return;
+        }
+
+        // set Waiting mode here.  Inverse op must be called by final()
+        // in the Thread.run() of every background thread.
+        setWaiting(description);
+        SwingUtilities.invokeLater(r);
+    }
+
+    private void clearResultPanel() {
+
+        gResult.setHead(new Object[0]);
+        gResult.clear();
+
+        if (gridFormat) {
+            gResult.fireTableChanged(null);
+        } else {
+            showResultInText();
+        }
+    }
+
+    public void setWaiting(String description) {
+
+        busyText = description;
+
+        if (busyText == null) {
+
+            // restore the cursors we saved
+            if (fMain instanceof java.awt.Frame) {
+                ((java.awt.Frame) fMain).setCursor(fMainCursor);
+            } else {
+                ((Component) fMain).setCursor(fMainCursor);
+            }
+
+            txtCommand.setCursor(txtCommandCursor);
+            txtResult.setCursor(txtResultCursor);
+
+            /** @todo: Enable actionButtons */
+        } else {
+
+            // save the old cursors
+            if (fMainCursor == null) {
+                fMainCursor = ((fMain instanceof java.awt.Frame)
+                               ? (((java.awt.Frame) fMain).getCursor())
+                               : (((Component) fMain).getCursor()));
+                txtCommandCursor = txtCommand.getCursor();
+                txtResultCursor  = txtResult.getCursor();
+            }
+
+            // set the cursors to the wait cursor
+            if (fMain instanceof java.awt.Frame) {
+                ((java.awt.Frame) fMain).setCursor(waitCursor);
+            } else {
+                ((Component) fMain).setCursor(waitCursor);
+            }
+
+            txtCommand.setCursor(waitCursor);
+            txtResult.setCursor(waitCursor);
+
+            /** @todo: Disable actionButtons */
+        }
+
+        setStatusLine(busyText, ((busyText == null) ? gResult.getRowCount()
+                                                    : 0));
+    }
+
+    private Runnable enableButtonRunnable = new Runnable() {
+
+        public void run() {
+            jbuttonClear.setEnabled(true);
+            jbuttonExecute.setEnabled(true);
+        }
+    };
+    private Runnable disableButtonRunnable = new Runnable() {
+
+        public void run() {
+            jbuttonClear.setEnabled(false);
+            jbuttonExecute.setEnabled(false);
+        }
+    };
+    private Thread           buttonUpdaterThread = null;
+    private static final int BUTTON_CHECK_PERIOD = 500;
+    private Runnable         buttonUpdater       = new Runnable() {
+
+        public void run() {
+
+            boolean havesql;
+
+            while (true) {
+                try {
+                    Thread.sleep(BUTTON_CHECK_PERIOD);
+                } catch (InterruptedException ie) {}
+
+                if (buttonUpdaterThread == null) {    // Pointer to me
+                    return;
+                }
+
+                havesql = (txtCommand.getText().length() > 0);
+
+                if (jbuttonClear.isEnabled() != havesql) {
+                    SwingUtilities.invokeLater(havesql ? enableButtonRunnable
+                                                       : disableButtonRunnable);
+                }
+            }
+        }
+    };
+    private JButton jbuttonClear;
+    private JButton jbuttonExecute;
+
+    public void start() {
+
+        if (buttonUpdaterThread == null) {
+            buttonUpdaterThread = new Thread(buttonUpdater);
+        }
+
+        buttonUpdaterThread.start();
+    }
+
+    public void stop() {
+
+        System.err.println("Stopping");
+
+        buttonUpdaterThread = null;
+    }
+
+    private Runnable treeRefreshRunnable = new Runnable() {
+
+        public void run() {
+
+            try {
+                directRefreshTree();
+            } catch (RuntimeException re) {
+                CommonSwing.errorMessage(re);
+
+                throw re;
+            } finally {
+                setWaiting(null);
+            }
+        }
+    };
+
+    /**
+     * Schedules to run in a Gui-safe thread
+     */
+    protected void executeCurrentSQL() {
+
+        if (txtCommand.getText().length() < 1) {
+            CommonSwing.errorMessage("No SQL to execute");
+
+            return;
+        }
+
+        backgroundIt(new StatementExecRunnable(), "Executing SQL");
+    }
+
+    protected class StatementExecRunnable implements Runnable {
+
+        public void run() {
+
+            gResult.clear();
+
+            try {
+                if (txtCommand.getText().startsWith("-->>>TEST<<<--")) {
+                    testPerformance();
+                } else {
+                    executeSQL();
+                }
+
+                updateResult();
+                displayResults();
+                updateAutoCommitBox();
+
+                // System.gc();
+            } catch (RuntimeException re) {
+                CommonSwing.errorMessage(re);
+
+                throw re;
+            } finally {
+                setWaiting(null);
+            }
+        }
+    }
+    ;
+
+    private void executeSQL() {
+
+        String[] g   = new String[1];
+        String   sql = null;
+
+        try {
+            lTime = System.currentTimeMillis();
+            sql   = ((sqlScriptBuffer == null ? txtCommand.getText()
+                                              : sqlScriptBuffer));
+
+            sStatement.execute(sql);
+
+            int r = sStatement.getUpdateCount();
+
+            if (r == -1) {
+                ResultSet rs = sStatement.getResultSet();
+
+                try {
+                    formatResultSet(rs);
+                } catch (Throwable t) {
+                    g[0] = "Error displaying the ResultSet";
+
+                    gResult.setHead(g);
+
+                    String s = t.getMessage();
+
+                    g[0] = s;
+
+                    gResult.addRow(g);
+                }
+            } else {
+                g[0] = "update count";
+
+                gResult.setHead(g);
+
+                g[0] = "" + r;
+
+                gResult.addRow(g);
+            }
+
+            lTime = System.currentTimeMillis() - lTime;
+
+            if (sqlScriptBuffer == null) {
+                addToRecent(sql);
+                txtCommand.setEnabled(true);    // clear() does this otherwise
+            } else {
+                clear();
+            }
+        } catch (SQLException e) {
+            lTime = System.currentTimeMillis() - lTime;
+            g[0]  = "SQL Error";
+
+            gResult.setHead(g);
+
+            String s = e.getMessage();
+
+            s    += " / Error Code: " + e.getErrorCode();
+            s    += " / State: " + e.getSQLState();
+            g[0] = s;
+
+            gResult.addRow(g);
+
+            //  Added: (weconsultants@users)
+            CommonSwing.errorMessage(e);
+
+            return;
+        }
+
+        if (autoRefresh) {
+
+            // We're already running in a "busy" thread.  Just update the
+            // status text.
+            setStatusLine("Refreshing object tree", 0);
+
+            String upper = sql.toUpperCase(Locale.ENGLISH);
+
+            // This test can be very liberal.  Too liberal will just do
+            // some extra refreshes.  Too conservative will display
+            // obsolete info.
+            if (upper.indexOf("ALTER") > -1 || upper.indexOf("DROP") > -1
+                    || upper.indexOf("CREATE") > -1) {
+                directRefreshTree();
+            }
+        }
+    }
+
+    /**
+     * Could somebody explain what the purpose of this method is?
+     * Contrary to the method name, it looks like it displays
+     * results only if gridFormat is off (seems like it  does
+     * nothing otherwise, except for clearing help text and moving focus).
+     */
+    private void updateResult() {
+
+        if (gridFormat) {
+
+            // in case 'help' has removed the grid
+            if (bHelp) {
+                pResult.removeAll();
+                pResult.add(gScrollPane, BorderLayout.CENTER);
+                pResult.doLayout();
+                gResult.fireTableChanged(null);
+                pResult.repaint();
+
+                bHelp = false;
+            }
+        } else {
+            showResultInText();
+        }
+
+        txtCommand.selectAll();
+        txtCommand.requestFocus();
+    }
+
+    /**
+     * We let Swing handle displaying nulls (which it generally does by
+     * printing nothing for them), except for the case of database
+     * VARCHARs, because this is the only class where there is any
+     * ambiguity about whether there is a null stored or not.
+     */
+    private void formatResultSet(ResultSet r) {
+
+        if (r == null) {
+            String[] g = new String[1];
+
+            g[0] = "Result";
+
+            gResult.setHead(g);
+
+            g[0] = "(empty)";
+
+            gResult.addRow(g);
+
+            return;
+        }
+
+        try {
+            ResultSetMetaData m         = r.getMetaData();
+            int               col       = m.getColumnCount();
+            Object[]          h         = new Object[col];
+            boolean[]         isVarChar = new boolean[col];
+
+            for (int i = 1; i <= col; i++) {
+                h[i - 1] = m.getColumnLabel(i);
+                isVarChar[i - 1] = (m.getColumnType(i)
+                                    == java.sql.Types.VARCHAR);
+            }
+
+            gResult.setHead(h);
+
+            while (r.next()) {
+                for (int i = 1; i <= col; i++) {
+                    try {
+                        h[i - 1] = r.getObject(i);
+
+                        if (r.wasNull()) {
+                            h[i - 1] = (isVarChar[i - 1] ? NULL_STR
+                                                         : null);
+                        }
+                    } catch (SQLException e) {}
+                }
+
+                gResult.addRow(h);
+            }
+
+            r.close();
+        } catch (SQLException e) {
+
+            //  Added: (weconsultants@users)
+            CommonSwing.errorMessage(e);
+        }
+    }
+
+    private void testPerformance() {
+
+        String       all   = txtCommand.getText();
+        StringBuffer b     = new StringBuffer();
+        long         total = 0;
+
+        for (int i = 0; i < all.length(); i++) {
+            char c = all.charAt(i);
+
+            if (c != '\n') {
+                b.append(c);
+            }
+        }
+
+        all = b.toString();
+
+        String[] g = new String[4];
+
+        g[0] = "ms";
+        g[1] = "count";
+        g[2] = "sql";
+        g[3] = "error";
+
+        gResult.setHead(g);
+
+        int max = 1;
+
+        lTime = System.currentTimeMillis() - lTime;
+
+        while (!all.equals("")) {
+            int    i = all.indexOf(';');
+            String sql;
+
+            if (i != -1) {
+                sql = all.substring(0, i);
+                all = all.substring(i + 1);
+            } else {
+                sql = all;
+                all = "";
+            }
+
+            if (sql.startsWith("--#")) {
+                max = Integer.parseInt(sql.substring(3));
+
+                continue;
+            } else if (sql.startsWith("--")) {
+                continue;
+            }
+
+            g[2] = sql;
+
+            long l = 0;
+
+            try {
+                l = DatabaseManagerCommon.testStatement(sStatement, sql, max);
+                total += l;
+                g[0]  = "" + l;
+                g[1]  = "" + max;
+                g[3]  = "";
+            } catch (SQLException e) {
+                g[0] = g[1] = "n/a";
+                g[3] = e.toString();
+
+                //  Added: (weconsultants@users)
+                CommonSwing.errorMessage(e);
+            }
+
+            gResult.addRow(g);
+            System.out.println(l + " ms : " + sql);
+        }
+
+        g[0] = "" + total;
+        g[1] = "total";
+        g[2] = "";
+
+        gResult.addRow(g);
+
+        lTime = System.currentTimeMillis() - lTime;
+    }
+
+    private void showResultInText() {
+
+        Object[] col   = gResult.getHead();
+        int      width = col.length;
+        int[]    size  = new int[width];
+        Vector   data  = gResult.getData();
+        Object[] row;
+        int      height = data.size();
+
+        for (int i = 0; i < width; i++) {
+            size[i] = col[i].toString().length();
+        }
+
+        for (int i = 0; i < height; i++) {
+            row = (Object[]) data.elementAt(i);
+
+            for (int j = 0; j < width; j++) {
+                String item = ((row[j] == null) ? ""
+                                                : row[j].toString());
+                int    l    = item.length();
+
+                if (l > size[j]) {
+                    size[j] = l;
+                }
+            }
+        }
+
+        StringBuffer b = new StringBuffer();
+
+        for (int i = 0; i < width; i++) {
+            b.append(col[i]);
+
+            for (int l = col[i].toString().length(); l <= size[i]; l++) {
+                b.append(' ');
+            }
+        }
+
+        b.append(NL);
+
+        for (int i = 0; i < width; i++) {
+            for (int l = 0; l < size[i]; l++) {
+                b.append('-');
+            }
+
+            b.append(' ');
+        }
+
+        b.append(NL);
+
+        for (int i = 0; i < height; i++) {
+            row = (Object[]) data.elementAt(i);
+
+            for (int j = 0; j < width; j++) {
+                String item = ((row[j] == null) ? ""
+                                                : row[j].toString());
+
+                b.append(item);
+
+                for (int l = item.length(); l <= size[j]; l++) {
+                    b.append(' ');
+                }
+            }
+
+            b.append(NL);
+        }
+
+        // b.append(NL + height + " row(s) in " + lTime + " ms");
+        // There is no reason why this report should be text-output-specific.
+        // Moving it to bottom of the setWaiting method (where the report
+        // gets written to the status line).
+        // I'm only doing the rowcount now.  Add the time report there if
+        // you are so inclined.
+        txtResult.setText(b.toString());
+    }
+
+    private void addToRecent(String s) {
+
+        for (int i = 0; i < iMaxRecent; i++) {
+            if (s.equals(sRecent[i])) {
+                return;
+            }
+        }
+
+        if (sRecent[iRecent] != null) {
+            mRecent.remove(iRecent);
+        }
+
+        sRecent[iRecent] = s;
+
+        if (s.length() > 43) {
+            s = s.substring(0, 40) + "...";
+        }
+
+        JMenuItem item = new JMenuItem(s);
+
+        item.setActionCommand("#" + iRecent);
+        item.addActionListener(this);
+        mRecent.insert(item, iRecent);
+
+        iRecent = (iRecent + 1) % iMaxRecent;
+    }
+
+    // empty implementations for mouse listener.  We're only using
+    // mouseReleased
+    public final void mouseClicked(final MouseEvent mouseEvent) {}
+
+    public final void mouseEntered(final MouseEvent mouseEvent) {}
+
+    public final void mouseExited(final MouseEvent mouseEvent) {}
+
+    // Check for handlePopup in both mousePressed and mouseReleased.  According to
+    // MouseEvent javadocs it's necessary for cross platform compatibility.
+    // We keep a record of the last alreadyHandled mouseEvent so we don't do it twice.
+    private MouseEvent alreadyHandled = null;
+
+    // mousePressed calls handlePopup, which creates the context-sensitive
+    // helper menu.
+    public final void mousePressed(final MouseEvent e) {
+
+        if (alreadyHandled == e) {
+            return;
+        }
+
+        handlePopup(e);
+
+        alreadyHandled = e;
+    }
+
+    // mouseReleased calls handlePopup, which creates the context-sensitive
+    // helper menu.
+    public final void mouseReleased(final MouseEvent e) {
+
+        if (alreadyHandled == e) {
+            return;
+        }
+
+        handlePopup(e);
+
+        alreadyHandled = e;
+    }
+
+    // based on the table or column right-clicked on, create some helper
+    // actions for common sql statements
+    public final void handlePopup(MouseEvent e) {
+
+        //System.out.println("Handle popup");
+        // if this is not a mouse action for popups then do nothing and return
+        if (!e.isPopupTrigger()) {
+            return;
+        }
+
+        // make sure the source of this mouse event was from the tree
+        Object source = e.getSource();
+
+        if (!(source instanceof JTree)) {
+            return;
+        }
+
+        JTree    tree     = (JTree) source;
+        TreePath treePath = tree.getPathForLocation(e.getX(), e.getY());
+
+        // if we couldn't find a tree path that corresponds to the
+        // right-click, then return
+        if (treePath == null) {
+            return;
+        }
+
+        // create the popup and menus
+        JPopupMenu popup = new JPopupMenu();
+        JMenuItem  menuItem;
+        String     menus[] = new String[] {
+            "Select", "Delete", "Update", "Insert"
+        };
+
+        // loop throught the menus we want to create, making a PopupListener
+        // for each one
+        for (int i = 0; i < menus.length; i++) {
+            PopupListener popupListener = new PopupListener(menus[i],
+                treePath);
+            String title = popupListener.toString();
+
+            if (title == null) {
+                return;
+            }
+
+            // Some of the menu names can be quite long (especially insert).
+            // If it's too long, abbreviate it
+            if (title.length() > 40) {
+                title = title.substring(0, 40) + "...";
+            }
+
+            menuItem = new JMenuItem(title);
+
+            menuItem.addActionListener(popupListener);
+            popup.add(menuItem);
+        }
+
+        popup.show(e.getComponent(), e.getX(), e.getY());
+    }
+
+    // handles the creation of the command when a popup is triggered
+    private class PopupListener implements ActionListener {
+
+        // used to identify depth while right clicking in tree.
+        public static final int DEPTH_URL    = 1;
+        public static final int DEPTH_TABLE  = 2;
+        public static final int DEPTH_COLUMN = 3;
+        String                  command;
+        TreePath                treePath;
+        TreePath                tablePath;
+        TreePath                columnPath;
+        String                  table  = null;
+        String                  column = null;
+
+        PopupListener(String command, TreePath treePath) {
+
+            super();
+
+            this.command  = command;
+            this.treePath = treePath;
+        }
+
+        // when the popup is triggered, create a command string and set it in
+        // the txtCommand buffer
+        public void actionPerformed(ActionEvent ae) {
+            txtCommand.setText(getCommandString());
+        }
+
+        // text to display when added to a menu
+        public String toString() {
+            return getCommandString();
+        }
+
+        //
+        public String getCommandString() {
+
+            // if we are at TABLE depth, set tablePath and table for use later
+            if (treePath.getPathCount() == DEPTH_TABLE) {
+                tablePath = treePath;
+                table = treePath.getPathComponent(DEPTH_TABLE - 1).toString();
+            }
+
+            // if we are at TABLE depth, set columnPath, column, tablePath and
+            // table for use later
+            if (treePath.getPathCount() == DEPTH_COLUMN) {
+                tablePath  = treePath.getParentPath();
+                table = treePath.getPathComponent(DEPTH_TABLE - 1).toString();
+                columnPath = treePath;
+                column = treePath.getPathComponent(DEPTH_COLUMN
+                                                   - 1).toString();
+            }
+
+            // handle command "SELECT".  Use table and column if set.
+            if (command.toUpperCase().equals("SELECT")) {
+                String result = "SELECT * FROM " + quoteTableName(table);
+
+                if (column != null) {
+                    DefaultMutableTreeNode childNode =
+                        (DefaultMutableTreeNode) treePath
+                            .getLastPathComponent();
+                    String  childName = null;
+                    boolean isChar;
+
+                    if (childNode.getChildCount() > 0) {
+                        childName = childNode.getFirstChild().toString();
+                        isChar    = childName.indexOf("CHAR") >= 0;
+                        result    += " WHERE " + quoteObjectName(column);
+
+                        if (isChar) {
+                            result += " LIKE \'%%\'";
+                        } else {
+                            result += " = ";
+                        }
+                    }
+                }
+
+                return result;
+            }
+
+            // handle command "UPDATE".  Use table and column if set.
+            else if (command.toUpperCase().equals("UPDATE")) {
+                String result = "UPDATE " + quoteTableName(table) + " SET ";
+
+                if (column != null) {
+                    result += quoteObjectName(column) + " = ";
+                }
+
+                return result;
+            }
+
+            // handle command "DELETE".  Use table and column if set.
+            else if (command.toUpperCase().equals("DELETE")) {
+                String result = "DELETE FROM " + quoteTableName(table);
+
+                if (column != null) {
+                    DefaultMutableTreeNode childNode =
+                        (DefaultMutableTreeNode) treePath
+                            .getLastPathComponent();
+                    String  childName = null;
+                    boolean isChar;
+
+                    if (childNode.getChildCount() > 0) {
+                        childName = childNode.getFirstChild().toString();
+                        isChar    = childName.indexOf("CHAR") >= 0;
+                        result    += " WHERE " + quoteObjectName(column);
+
+                        if (isChar) {
+                            result += " LIKE \'%%\'";
+                        } else {
+                            result += " = ";
+                        }
+                    }
+                }
+
+                return result;
+            }
+
+            // handle command "INSERT".  Use table and column if set.
+            else if (command.toUpperCase().equals("INSERT")) {
+                TreeNode    tableNode;
+                Enumeration enumer;
+                String      columns = "";
+                String      values  = " ";
+                String      comma   = "";
+                String      quote   = "";
+
+                // build a string that includes all the columns that need to
+                // be added, with a parenthesied list of commas, suitable for
+                // inserting values into.
+                if (tablePath == null) {
+                    return null;
+                }
+
+                tableNode = (TreeNode) tablePath.getLastPathComponent();
+                enumer    = tableNode.children();
+
+                while (enumer.hasMoreElements()) {
+                    Object o = enumer.nextElement();
+
+                    if (o.toString().equals("Indices")) {
+                        continue;
+                    }
+
+                    DefaultMutableTreeNode childNode =
+                        (DefaultMutableTreeNode) o;
+                    String childName = null;
+
+                    if (childNode.getChildCount() == 0) {
+                        continue;
+                    } else {
+                        childName = childNode.getFirstChild().toString();
+                    }
+
+                    // If our first child (type) is some sort of char, use ''
+                    // in the string.  Makes is more obvious to the user when
+                    // they need to use a string
+                    if (childName.indexOf("CHAR") >= 0) {
+                        quote = "\'\'";
+                    } else {
+                        quote = "";
+                    }
+
+                    columns += comma + quoteObjectName(o.toString());
+                    values  += comma + quote;
+                    comma   = ", ";
+                }
+
+                return "INSERT INTO " + quoteTableName(table) + "\n( "
+                       + columns + " )\nVALUES (" + values + ")";
+            } else {
+                return "Got here in error " + command
+                       + ".  Should never happen";
+            }
+        }
+    }
+
+    /**
+     * Perform a limited check (inconclusive) and quote object name if required.
+     * Gives wrong result if a quoted name contains a dot.
+     */
+    private String quoteTableName(String name) {
+
+        int dot = name.indexOf(".");
+
+        if (dot < 0) {
+            return quoteObjectName(name);
+        }
+
+        String partOne = name.substring(0, dot);
+        String partTwo = name.substring(dot + 1);
+
+        return quoteObjectName(partOne) + '.' + quoteObjectName(partTwo);
+    }
+
+    /**
+     * perform a limited check (inconclusive) and quote object name if required
+     */
+    private String quoteObjectName(String name) {
+
+        if (name.toUpperCase().equals(name) && name.indexOf(' ') < 0) {
+            return name;
+        }
+
+        return "\"" + name + "\"";
+    }
+
+    private void initGUI() {
+
+        JPanel pCommand = new JPanel();
+
+        pResult = new JPanel();
+        nsSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pCommand,
+                                     pResult);
+
+        // Added: (weconsultants@users)
+        nsSplitPane.setOneTouchExpandable(true);
+        pCommand.setLayout(new BorderLayout());
+        pResult.setLayout(new BorderLayout());
+
+        Font fFont = new Font("Dialog", Font.PLAIN, 12);
+
+        txtCommand = new JTextArea(5, 40);
+
+        txtCommand.setMargin(new Insets(5, 5, 5, 5));
+        txtCommand.addKeyListener(this);
+
+        txtCommandScroll = new JScrollPane(txtCommand);
+        txtResult        = new JTextArea(20, 40);
+
+        txtResult.setMargin(new Insets(5, 5, 5, 5));
+
+        txtResultScroll = new JScrollPane(txtResult);
+
+        txtCommand.setFont(fFont);
+        txtResult.setFont(new Font("Courier", Font.PLAIN, 12));
+        pCommand.add(txtCommandScroll, BorderLayout.CENTER);
+
+        gResult = new GridSwing();
+
+        TableSorter sorter = new TableSorter(gResult);
+
+        tableModel   = sorter;
+        gResultTable = new JTable(sorter);
+
+        sorter.setTableHeader(gResultTable.getTableHeader());
+
+        gScrollPane = new JScrollPane(gResultTable);
+
+        gResultTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+        gResult.setJTable(gResultTable);
+
+        //getContentPane().setLayout(new BorderLayout());
+        pResult.add(gScrollPane, BorderLayout.CENTER);
+
+        // Set up the tree
+        rootNode    = new DefaultMutableTreeNode("Connection");
+        treeModel   = new DefaultTreeModel(rootNode);
+        tTree       = new JTree(treeModel);
+        tScrollPane = new JScrollPane(tTree);
+
+        // System.out.println("Adding mouse listener");
+        tTree.addMouseListener(this);
+        tScrollPane.setPreferredSize(new Dimension(120, 400));
+        tScrollPane.setMinimumSize(new Dimension(70, 100));
+        txtCommandScroll.setPreferredSize(new Dimension(360, 100));
+        txtCommandScroll.setMinimumSize(new Dimension(180, 100));
+        gScrollPane.setPreferredSize(new Dimension(460, 300));
+
+        ewSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tScrollPane,
+                                     nsSplitPane);
+
+        // Added: (weconsultants@users)
+        ewSplitPane.setOneTouchExpandable(true);
+        fMain.getContentPane().add(ewSplitPane, BorderLayout.CENTER);
+
+        // Added: (weconsultants@users)
+        jStatusLine = new JLabel();
+        iReadyStatus =
+            new JButton(new ImageIcon(CommonSwing.getIcon("StatusReady")));
+
+        iReadyStatus.setSelectedIcon(
+            new ImageIcon(CommonSwing.getIcon("StatusRunning")));
+
+        pStatus = new JPanel();
+
+        pStatus.setLayout(new BorderLayout());
+        pStatus.add(iReadyStatus, BorderLayout.WEST);
+        pStatus.add(jStatusLine, BorderLayout.CENTER);
+        fMain.getContentPane().add(pStatus, "South");
+        doLayout();
+
+        if (fMain instanceof java.awt.Window) {
+            ((java.awt.Window) fMain).pack();
+        } else {
+            ((Container) fMain).validate();
+        }
+    }
+
+    /* Simple tree node factory method - set's parent and user object.
+     */
+    private DefaultMutableTreeNode makeNode(Object userObject,
+            MutableTreeNode parent) {
+
+        DefaultMutableTreeNode node = new DefaultMutableTreeNode(userObject);
+
+        if (parent != null) {
+            treeModel.insertNodeInto(node, parent, parent.getChildCount());
+        }
+
+        return node;
+    }
+
+    private static final String[] usertables       = {
+        "TABLE", "GLOBAL TEMPORARY", "VIEW", "SYSTEM TABLE"
+    };
+    private static final String[] nonSystables     = {
+        "TABLE", "GLOBAL TEMPORARY", "VIEW"
+    };
+    private static final HashSet  oracleSysUsers   = new HashSet();
+    private static final String[] oracleSysSchemas = {
+        "SYS", "SYSTEM", "OUTLN", "DBSNMP", "OUTLN", "MDSYS", "ORDSYS",
+        "ORDPLUGINS", "CTXSYS", "DSSYS", "PERFSTAT", "WKPROXY", "WKSYS",
+        "WMSYS", "XDB", "ANONYMOUS", "ODM", "ODM_MTR", "OLAPSYS", "TRACESVR",
+        "REPADMIN"
+    };
+
+    static {
+        for (int i = 0; i < oracleSysSchemas.length; i++) {
+            oracleSysUsers.add(oracleSysSchemas[i]);
+        }
+    }
+
+    /**
+     * Schedules to run in a Gui-safe thread
+     */
+    protected void refreshTree() {
+        backgroundIt(treeRefreshRunnable, "Refreshing object tree");
+    }
+
+    /**
+     * Clear all existing nodes from the tree model and rebuild from scratch.
+     *
+     * This method executes in current thread
+     */
+    protected void directRefreshTree() {
+
+        int[]                  rowCounts;
+        DefaultMutableTreeNode propertiesNode;
+
+        // Added: (weconsultants@users) Moved tableNode here for visibiity nd new DECFM
+        DefaultMutableTreeNode tableNode;
+        DecimalFormat DECFMT = new DecimalFormat(" ( ####,###,####,##0 )");
+
+        // First clear the existing tree by simply enumerating
+        // over the root node's children and removing them one by one.
+        while (treeModel.getChildCount(rootNode) > 0) {
+            DefaultMutableTreeNode child =
+                (DefaultMutableTreeNode) treeModel.getChild(rootNode, 0);
+
+            treeModel.removeNodeFromParent(child);
+            child.removeAllChildren();
+            child.removeFromParent();
+        }
+
+        treeModel.nodeStructureChanged(rootNode);
+        treeModel.reload();
+        tScrollPane.repaint();
+
+        ResultSet result = null;
+
+        // Now rebuild the tree below its root
+        try {
+
+            // Start by naming the root node from its URL:
+            rootNode.setUserObject(dMeta.getURL());
+
+            // get metadata about user tables by building a vector of table names
+            result = dMeta.getTables(null, null, null, (showSys ? usertables
+                                                                : nonSystables));
+
+            Vector tables  = new Vector();
+            Vector schemas = new Vector();
+
+            // sqlbob@users Added remarks.
+            Vector remarks = new Vector();
+            String schema;
+
+            while (result.next()) {
+                schema = result.getString(2);
+
+                if ((!showSys) && isOracle
+                        && oracleSysUsers.contains(schema)) {
+                    continue;
+                }
+
+                if (schemaFilter == null || schema.equals(schemaFilter)) {
+                    schemas.addElement(schema);
+                    tables.addElement(result.getString(3));
+                    remarks.addElement(result.getString(5));
+
+                    continue;
+                }
+            }
+
+            result.close();
+
+            result = null;
+
+            // Added: (weconsultants@users)
+            // Sort not to go into production. Have to sync with 'remarks Vector' for DBMS that has it
+            //   Collections.sort(tables);
+            // Added: (weconsultants@users) - Add rowCounts if needed.
+            rowCounts = new int[tables.size()];
+
+            try {
+                rowCounts = getRowCounts(tables, schemas);
+            } catch (Exception e) {
+
+                //  Added: (weconsultants@users)
+                CommonSwing.errorMessage(e);
+            }
+
+            ResultSet col;
+
+            // For each table, build a tree node with interesting info
+            for (int i = 0; i < tables.size(); i++) {
+                col = null;
+
+                String name;
+
+                try {
+                    name = (String) tables.elementAt(i);
+
+                    if (isOracle && name.startsWith("BIN$")) {
+                        continue;
+
+                        // Oracle Recyle Bin tables.
+                        // Contains metacharacters which screw up metadata
+                        // queries below.
+                    }
+
+                    schema = (String) schemas.elementAt(i);
+
+                    String schemaname = "";
+
+                    if (schema != null && showSchemas) {
+                        schemaname = schema + '.';
+                    }
+
+                    String rowcount = displayRowCounts
+                                      ? (" " + DECFMT.format(rowCounts[i]))
+                                      : "";
+                    String displayedName = schemaname + name + rowcount;
+
+                    // weconsul@ptd.net Add rowCounts if needed.
+                    tableNode = makeNode(displayedName, rootNode);
+                    col       = dMeta.getColumns(null, schema, name, null);
+
+                    if ((schema != null) && !schema.trim().equals("")) {
+                        makeNode(schema, tableNode);
+                    }
+
+                    // sqlbob@users Added remarks.
+                    String remark = (String) remarks.elementAt(i);
+
+                    if ((remark != null) && !remark.trim().equals("")) {
+                        makeNode(remark, tableNode);
+                    }
+
+                    // This block is very slow for some Oracle tables.
+                    // With a child for each column containing pertinent attributes
+                    while (col.next()) {
+                        String c = col.getString(4);
+                        DefaultMutableTreeNode columnNode = makeNode(c,
+                            tableNode);
+                        String type = col.getString(6);
+
+                        makeNode("Type: " + type, columnNode);
+
+                        boolean nullable = col.getInt(11)
+                                           != DatabaseMetaData.columnNoNulls;
+
+                        makeNode("Nullable: " + nullable, columnNode);
+                    }
+                } finally {
+                    if (col != null) {
+                        try {
+                            col.close();
+                        } catch (SQLException se) {}
+                    }
+                }
+
+                DefaultMutableTreeNode indexesNode = makeNode("Indices",
+                    tableNode);
+
+                if (showIndexDetails) {
+                    ResultSet ind = null;
+
+                    try {
+                        ind = dMeta.getIndexInfo(null, schema, name, false,
+                                                 false);
+
+                        String                 oldiname  = null;
+                        DefaultMutableTreeNode indexNode = null;
+
+                        // A child node to contain each index - and its attributes
+                        while (ind.next()) {
+                            boolean nonunique = ind.getBoolean(4);
+                            String  iname     = ind.getString(6);
+
+                            if ((oldiname == null
+                                    || !oldiname.equals(iname))) {
+                                indexNode = makeNode(iname, indexesNode);
+
+                                makeNode("Unique: " + !nonunique, indexNode);
+
+                                oldiname = iname;
+                            }
+
+                            // And the ordered column list for index components
+                            makeNode(ind.getString(9), indexNode);
+                        }
+                    } catch (SQLException se) {
+
+                        // Workaround for Oracle
+                        if (se.getMessage() == null || ((!se.getMessage()
+                                .startsWith("ORA-25191:")) && (!se.getMessage()
+                                .startsWith("ORA-01702:")) && !se.getMessage()
+                                    .startsWith("ORA-01031:"))) {
+                            throw se;
+                        }
+                    } finally {
+                        if (ind != null) {
+                            ind.close();
+
+                            ind = null;
+                        }
+                    }
+                }
+            }
+
+            // Finally - a little additional metadata on this connection
+            propertiesNode = makeNode("Properties", rootNode);
+
+            makeNode("User: " + dMeta.getUserName(), propertiesNode);
+            makeNode("ReadOnly: " + cConn.isReadOnly(), propertiesNode);
+            makeNode("AutoCommit: " + cConn.getAutoCommit(), propertiesNode);
+            makeNode("Driver: " + dMeta.getDriverName(), propertiesNode);
+            makeNode("Product: " + dMeta.getDatabaseProductName(),
+                     propertiesNode);
+            makeNode("Version: " + dMeta.getDatabaseProductVersion(),
+                     propertiesNode);
+        } catch (SQLException se) {
+            propertiesNode = makeNode("Error getting metadata:", rootNode);
+
+            makeNode(se.getMessage(), propertiesNode);
+            makeNode(se.getSQLState(), propertiesNode);
+            CommonSwing.errorMessage(se);
+        } finally {
+            if (result != null) {
+                try {
+                    result.close();
+                } catch (SQLException se) {}
+            }
+        }
+
+        treeModel.nodeStructureChanged(rootNode);
+        treeModel.reload();
+        tScrollPane.repaint();
+
+        // We want the Schema List to always be in sync with the displayed tree
+        updateSchemaList();
+    }
+
+    // Added: (weconsultants@users) Sets up\changes the running status icon
+    void setStatusLine(String busyBaseString, int rowCount) {
+
+        iReadyStatus.setSelected(busyBaseString != null);
+
+        if (busyBaseString == null) {
+            String additionalMsg = "";
+
+            if (schemaFilter != null) {
+                additionalMsg = " /  Tree showing objects in schema '"
+                                + schemaFilter + "'";
+            }
+
+            if (rowCount > 1) {
+                additionalMsg += " / " + rowCount + " rows retrieved";
+            }
+
+            jStatusLine.setText("  " + READY_STATUS + additionalMsg);
+        } else {
+            jStatusLine.setText("  " + busyBaseString + "...");
+        }
+    }
+
+    // Added: (weconsultants@users) Needed to aggragate counts per table in jTree
+    protected int[] getRowCounts(Vector inTable,
+                                 Vector inSchema) throws Exception {
+
+        if (!displayRowCounts) {
+            return (null);
+        }
+
+        String rowCountSelect = "SELECT COUNT(*) FROM ";
+        int[]  counts;
+        String name;
+
+        counts = new int[inTable.size()];
+
+        try {
+            Statement select = rowConn.createStatement();
+
+            for (int i = 0; i < inTable.size(); i++) {
+                try {
+                    String schemaPart = (String) inSchema.elementAt(i);
+
+                    schemaPart = schemaPart == null ? ""
+                                                    : (schemaPart + '.');
+                    name       = schemaPart + (String) inTable.elementAt(i);
+
+                    ResultSet resultSet = select.executeQuery(rowCountSelect
+                        + name);
+
+                    while (resultSet.next()) {
+                        counts[i] = resultSet.getInt(1);
+                    }
+                } catch (Exception e) {
+                    System.err.println("Unable to get row count for table "
+                                       + inSchema.elementAt(i) + '.'
+                                       + inTable.elementAt(i)
+                                       + ".  Using value '0': " + e);
+                }
+            }
+        } catch (Exception e) {
+            CommonSwing.errorMessage(e);
+        }
+
+        return (counts);
+    }
+
+    protected JToolBar createToolBar() {
+
+        // Build jtoolbar and jtoolbar Buttons
+        JToolBar jtoolbar = new JToolBar();
+
+        jtoolbar.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
+
+        // I'm dropping "Statement" from  "Execute SQL Statement", etc.,
+        // because it may or may not be "one statement", but it is SQL.
+        // Build jbuttonClear Buttons - blaine
+        jbuttonClear =
+            new JButton("Clear SQL",
+                        new ImageIcon(CommonSwing.getIcon("Clear")));
+
+        jbuttonClear.putClientProperty("is3DEnabled", Boolean.TRUE);
+        tipMap.put(jbuttonClear, "Clear SQL");
+        jbuttonClear.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent actionevent) {
+
+                if (sqlScriptBuffer == null
+                        && txtCommand.getText().length() < 1) {
+                    CommonSwing.errorMessage("No SQL to clear");
+
+                    return;
+                }
+
+                clear();
+            }
+        });
+
+        jbuttonExecute =
+            new JButton("Execute SQL",
+                        new ImageIcon(CommonSwing.getIcon("Execute")));
+
+        tipMap.put(jbuttonExecute, "Execute SQL");
+        jbuttonExecute.putClientProperty("is3DEnabled", Boolean.TRUE);
+        jbuttonExecute.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent actionevent) {
+                executeCurrentSQL();
+            }
+        });
+        jtoolbar.addSeparator();
+        jtoolbar.add(jbuttonClear);
+        jtoolbar.addSeparator();
+        jtoolbar.add(jbuttonExecute);
+        jtoolbar.addSeparator();
+        jbuttonClear.setAlignmentY(0.5F);
+        jbuttonClear.setAlignmentX(0.5F);
+        jbuttonExecute.setAlignmentY(0.5F);
+        jbuttonExecute.setAlignmentX(0.5F);
+
+        return jtoolbar;
+    }
+
+    void updateAutoCommitBox() {
+
+        try {
+            boxAutoCommit.setSelected(cConn.getAutoCommit());
+        } catch (SQLException se) {
+            CommonSwing.errorMessage(se);
+        }
+    }
+
+    private void setLF(String newLAF) {
+
+        if (currentLAF != null && currentLAF == newLAF) {    // No change
+            return;
+        }
+
+        if (pResult != null && gridFormat) {
+            pResult.removeAll();
+        }
+
+        CommonSwing.setSwingLAF((Component) fMain, newLAF);
+
+        if (pResult != null && gridFormat) {
+            setResultsInGrid();
+        }
+
+        currentLAF = newLAF;
+
+        if (currentLAF.equals(CommonSwing.Native)) {
+            rbNativeLF.setSelected(true);
+        } else if (currentLAF.equals(CommonSwing.Java)) {
+            rbJavaLF.setSelected(true);
+        } else if (currentLAF.equals(CommonSwing.Motif)) {
+            rbMotifLF.setSelected(true);
+        }
+    }
+
+    void resetTooltips() {
+
+        Iterator   it = tipMap.keySet().iterator();
+        JComponent component;
+
+        while (it.hasNext()) {
+            component = (JComponent) it.next();
+
+            component.setToolTipText(showTooltips
+                                     ? ((String) tipMap.get(component))
+                                     : (String) null);
+        }
+    }
+
+    private void updateSchemaList() {
+
+        ButtonGroup group  = new ButtonGroup();
+        ArrayList   list   = new ArrayList();
+        ResultSet   result = null;
+
+        try {
+            result = dMeta.getSchemas();
+
+            if (result == null) {
+                throw new SQLException("Failed to get metadata from database");
+            }
+
+            while (result.next()) {
+                list.add(result.getString(1));
+            }
+        } catch (SQLException se) {
+            CommonSwing.errorMessage(se);
+        } finally {
+            if (result != null) {
+                try {
+                    result.close();
+                } catch (SQLException se) {}
+            }
+        }
+
+        mnuSchemas.removeAll();
+        rbAllSchemas.setSelected(schemaFilter == null);
+        group.add(rbAllSchemas);
+        mnuSchemas.add(rbAllSchemas);
+
+        String               s;
+        JRadioButtonMenuItem radioButton;
+
+        for (int i = 0; i < list.size(); i++) {
+            s           = (String) list.get(i);
+            radioButton = new JRadioButtonMenuItem(s);
+
+            group.add(radioButton);
+            mnuSchemas.add(radioButton);
+            radioButton.setSelected(schemaFilter != null
+                                    && schemaFilter.equals(s));
+            radioButton.addActionListener(schemaListListener);
+            radioButton.setEnabled(list.size() > 1);
+        }
+
+        mnuSchemas.addSeparator();
+        mnuSchemas.add(mitemUpdateSchemas);
+    }
+
+    ActionListener schemaListListener = (new ActionListener() {
+
+        public void actionPerformed(ActionEvent actionevent) {
+
+            schemaFilter = actionevent.getActionCommand();
+
+            if (schemaFilter.equals("*")) {
+                schemaFilter = null;
+            }
+
+            refreshTree();
+        }
+    });
+
+    /**
+     * Persisted User Preferences for DatabaseManagerSwing.
+     *
+     * These are settings for items in the View and Options pulldown menus,
+     * plus Help/Show Tooltips.
+     */
+    public class DBMPrefs {
+
+        public File prefsFile = null;
+
+        /**
+         * The constructor guarantees that this will be null for Applet,
+         *  non-null if using a local preferences file
+         */
+
+        // Set defaults from Data
+        boolean autoRefresh   = true;
+        boolean showRowCounts = false;
+        boolean showSysTables = false;
+        boolean showSchemas   = true;
+        boolean resultGrid    = true;
+        String  laf           = CommonSwing.Native;
+
+        // Somebody with more time can store the font settings.  IMO, that
+        // menu item shouldn't even be there if the settings aren't persisted.
+        boolean showTooltips = true;
+
+        public DBMPrefs(boolean isApplet) throws IOException {
+
+            if (isApplet) {}
+            else {
+                if (homedir == null) {
+                    throw new IOException(
+                        "Skipping preferences since do not know home dir");
+                }
+
+                prefsFile = new File(homedir, "dbmprefs.properties");
+            }
+
+            load();
+        }
+
+        public void load() throws IOException {
+
+            String tmpString;
+
+            if (prefsFile == null) {
+
+                // LOAD PREFERENCES FROM APPLET PARAMS
+                tmpString = getParameter("autoRefresh");
+
+                if (tmpString != null) {
+                    autoRefresh = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = getParameter("showRowCounts");
+
+                if (tmpString != null) {
+                    showRowCounts = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = getParameter("showSysTables");
+
+                if (tmpString != null) {
+                    showSysTables = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = getParameter("showSchemas");
+
+                if (tmpString != null) {
+                    showSchemas = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = getParameter("resultGrid");
+
+                if (tmpString != null) {
+                    resultGrid = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = getParameter("laf");
+                laf       = ((tmpString == null) ? CommonSwing.Native
+                                                 : tmpString);
+                tmpString = getParameter("showTooltips");
+
+                if (tmpString != null) {
+                    showTooltips = Boolean.valueOf(tmpString).booleanValue();
+                }
+            } else {
+
+                // LOAD PREFERENCES FROM LOCAL PREFERENCES FILE
+                if (!prefsFile.exists()) {
+                    throw new IOException("No such file: " + prefsFile);
+                }
+
+                Properties props = new Properties();
+
+                try {
+                    FileInputStream fis = new FileInputStream(prefsFile);
+
+                    props.load(fis);
+                    fis.close();
+                } catch (IOException ioe) {
+                    throw new IOException("Failed to read preferences file '"
+                                          + prefsFile + "':  "
+                                          + ioe.getMessage());
+                }
+
+                tmpString = props.getProperty("autoRefresh");
+
+                if (tmpString != null) {
+                    autoRefresh = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = props.getProperty("showRowCounts");
+
+                if (tmpString != null) {
+                    showRowCounts = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = props.getProperty("showSysTables");
+
+                if (tmpString != null) {
+                    showSysTables = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = props.getProperty("showSchemas");
+
+                if (tmpString != null) {
+                    showSchemas = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = props.getProperty("resultGrid");
+
+                if (tmpString != null) {
+                    resultGrid = Boolean.valueOf(tmpString).booleanValue();
+                }
+
+                tmpString = props.getProperty("laf");
+                laf       = ((tmpString == null) ? CommonSwing.Native
+                                                 : tmpString);
+                tmpString = props.getProperty("showTooltips");
+
+                if (tmpString != null) {
+                    showTooltips = Boolean.valueOf(tmpString).booleanValue();
+                }
+            }
+        }
+
+        public void store() {
+
+            if (prefsFile == null) {
+
+                // Can't persist Applet settings.
+                return;
+            }
+
+            Properties props = new Properties();
+
+            // Boolean.toString(boolean) was new with Java 1.4, so don't use that.
+            props.setProperty("autoRefresh", (autoRefresh ? tString
+                                                          : fString));
+            props.setProperty("showRowCounts", (showRowCounts ? tString
+                                                              : fString));
+            props.setProperty("showSysTables", (showSysTables ? tString
+                                                              : fString));
+            props.setProperty("showSchemas", (showSchemas ? tString
+                                                          : fString));
+            props.setProperty("resultGrid", (resultGrid ? tString
+                                                        : fString));
+            props.setProperty("laf", laf);
+            props.setProperty("showTooltips", (showTooltips ? tString
+                                                            : fString));
+
+            try {
+                FileOutputStream fos = new FileOutputStream(prefsFile);
+
+                props.store(fos, "DatabaseManagerSwing user preferences");
+                fos.flush();
+                fos.close();
+            } catch (IOException ioe) {
+                throw new RuntimeException(
+                    "Failed to prepare preferences file '" + prefsFile
+                    + "':  " + ioe.getMessage());
+            }
+        }
+    }
+
+    private static final String tString = Boolean.TRUE.toString();
+    private static final String fString = Boolean.FALSE.toString();
+}
diff --git a/src/org/hsqldb/util/FontDialogSwing.java b/src/org/hsqldb/util/FontDialogSwing.java
new file mode 100644
index 0000000..bf8a894
--- /dev/null
+++ b/src/org/hsqldb/util/FontDialogSwing.java
@@ -0,0 +1,327 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JColorChooser;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+
+//  weconsultants@users 20041109 - original swing port
+//  weconsultants@users 20050215 - version 1.8.0 -  Update: Compatbilty fix for JDK 1.3
+//      - Replaced: Objects JSpinner spinnerFontSizes and SpinnerNumberModel spinnerModelSizes
+//        for JComboBox fontSizesComboBox and String fontSizes[];
+public class FontDialogSwing extends JDialog {
+
+    private static boolean      isRunning   = false;
+    private static final String BACKGROUND  = "Background";
+    private static String       defaultFont = "Dialog";
+    private static final String FOREGROUND  = "Foreground";
+    private static JButton      bgColorButton;
+    private static JCheckBox    ckbbold;
+    private static JButton      closeButton;
+    private static JButton      fgColorButton;
+    private static JComboBox    fontsComboBox;
+
+    //  weconsultants@users 20050215 - Added for Compatbilty fix for JDK 1.3
+    private static JComboBox      fontSizesComboBox;
+    private static final String[] fontSizes = {
+        "8", "9", "10", "11", "12", "13", "14", "16", "18", "24", "36"
+    };
+
+    // weconsultants@users 20050215 - Commented out for Compatbilty fix for JDK 1.3
+    //  private static JSpinner           spinnerFontSizes;
+    //  private static SpinnerNumberModel spinnerModelSizes;
+    private static DatabaseManagerSwing fOwner;
+    private static JFrame frame =
+        new JFrame("DataBaseManagerSwing Font Selection Dialog");
+    private static JCheckBox ckbitalic;
+
+    /**
+     * Create and display FontDialogSwing Dialog.
+     *
+     */
+    public static void creatFontDialog(DatabaseManagerSwing owner) {
+
+        if (isRunning) {
+            frame.setVisible(true);
+        } else {
+            CommonSwing.setSwingLAF(frame, CommonSwing.Native);
+
+            fOwner = owner;
+
+            frame.setIconImage(CommonSwing.getIcon("Frame"));
+
+            isRunning = true;
+
+            frame.setSize(600, 100);
+            CommonSwing.setFramePositon(frame);
+
+            ckbitalic = new JCheckBox(
+                new ImageIcon(CommonSwing.getIcon("ItalicFont")));
+
+            ckbitalic.putClientProperty("is3DEnabled", Boolean.TRUE);
+            ckbitalic.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent e) {
+                    setStyle();
+                }
+            });
+
+            ckbbold =
+                new JCheckBox(new ImageIcon(CommonSwing.getIcon("BoldFont")));
+
+            ckbbold.putClientProperty("is3DEnabled", Boolean.TRUE);
+            ckbbold.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent e) {
+                    setStyle();
+                }
+            });
+
+            fgColorButton = new JButton(
+                "Foreground",
+                new ImageIcon(CommonSwing.getIcon("ColorSelection")));
+
+            fgColorButton.putClientProperty("is3DEnabled", Boolean.TRUE);
+            fgColorButton.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent e) {
+                    setColor(FOREGROUND);
+                }
+            });
+
+            bgColorButton = new JButton(
+                "Background",
+                new ImageIcon(CommonSwing.getIcon("ColorSelection")));
+
+            bgColorButton.putClientProperty("is3DEnabled", Boolean.TRUE);
+            bgColorButton.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent e) {
+                    setColor(BACKGROUND);
+                }
+            });
+
+            closeButton =
+                new JButton("Close",
+                            new ImageIcon(CommonSwing.getIcon("Close")));
+
+            closeButton.putClientProperty("is3DEnabled", Boolean.TRUE);
+            closeButton.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent e) {
+                    frame.setVisible(false);
+                }
+            });
+
+            GraphicsEnvironment ge =
+                GraphicsEnvironment.getLocalGraphicsEnvironment();
+            String[]  fontNames = ge.getAvailableFontFamilyNames();
+            Dimension fontsComboBoxDimension = new Dimension(160, 25);
+
+            fontsComboBox = new JComboBox(fontNames);
+
+            fontsComboBox.putClientProperty("is3DEnabled", Boolean.TRUE);
+            fontsComboBox.setMaximumSize(fontsComboBoxDimension);
+            fontsComboBox.setPreferredSize(fontsComboBoxDimension);
+            fontsComboBox.setMaximumSize(fontsComboBoxDimension);
+            fontsComboBox.setEditable(false);
+            fontsComboBox.setSelectedItem(defaultFont);
+            fontsComboBox.addActionListener(new ActionListener() {
+
+                public void actionPerformed(ActionEvent e) {
+                    setFont();
+                }
+            });
+
+            // weconsultants@users 20050215 - Added for Compatbilty fix for  JDK 1.3
+            fontSizesComboBox = new JComboBox(fontSizes);
+
+            Dimension spinnerDimension = new Dimension(45, 25);
+
+            fontSizesComboBox.putClientProperty("is3DEnabled", Boolean.TRUE);
+            fontSizesComboBox.setMinimumSize(spinnerDimension);
+            fontSizesComboBox.setPreferredSize(spinnerDimension);
+            fontSizesComboBox.setMaximumSize(spinnerDimension);
+            fontSizesComboBox.addItemListener(new ItemListener() {
+
+                public void itemStateChanged(ItemEvent evt) {
+
+                    if (evt.getStateChange() == ItemEvent.SELECTED) {
+                        setFontSize((String) evt.getItem());
+                    }
+                }
+            });
+
+            // weconsultants@users 20050215 - Commented out for Compatbilty fix for  JDK 1.3
+            //            Dimension spinnerDimension = new Dimension(50, 25);
+            //            spinnerFontSizes = new JSpinner();
+            //            spinnerFontSizes.putClientProperty("is3DEnabled", Boolean.TRUE);
+            //            spinnerFontSizes.setMinimumSize(spinnerDimension);
+            //            spinnerFontSizes.setPreferredSize(spinnerDimension);
+            //            spinnerFontSizes.setMaximumSize(spinnerDimension);
+            //            spinnerModelSizes = new SpinnerNumberModel(12, 8, 72, 1);
+            //            spinnerFontSizes.setModel(spinnerModelSizes);
+            //            spinnerFontSizes.addChangeListener(new ChangeListener() {
+            //                public void stateChanged(ChangeEvent e) {
+            //                    setFontSize();
+            //                }
+            //            });
+            Container contentPane = frame.getContentPane();
+
+            contentPane.setLayout(new FlowLayout());
+            contentPane.add(fontsComboBox);
+
+            // weconsultants@users 20050215 - Commented out for Compatbilty fix for 1.3
+            // contentPane.add(spinnerFontSizes);
+            // weconsultants@users 20050215 - Added for Compatbilty fix for 1.3
+            contentPane.add(fontSizesComboBox);
+            contentPane.add(ckbbold);
+            contentPane.add(ckbitalic);
+            contentPane.add(fgColorButton);
+            contentPane.add(bgColorButton);
+            contentPane.add(closeButton);
+            frame.pack();
+            frame.setVisible(false);
+        }
+    }
+
+    public static void setFont() {
+
+        Font txtResultFont = fOwner.txtResult.getFont();
+
+        fOwner.txtResult.setFont(
+            new Font(
+                fontsComboBox.getSelectedItem().toString(),
+                txtResultFont.getStyle(), txtResultFont.getSize()));
+
+        Font txtCommandFont = fOwner.txtResult.getFont();
+
+        fOwner.txtCommand.setFont(
+            new Font(
+                fontsComboBox.getSelectedItem().toString(),
+                txtCommandFont.getStyle(), txtCommandFont.getSize()));
+
+        Font txtTreeFont = fOwner.txtResult.getFont();
+
+        fOwner.tTree.setFont(
+            new Font(
+                fontsComboBox.getSelectedItem().toString(),
+                txtTreeFont.getStyle(), txtTreeFont.getSize()));
+    }
+
+    /**
+     * Displays a color chooser and Sets the selected color.
+     */
+    public static void setFontSize(String inFontSize) {
+
+        // weconsultants@users 20050215 - Changed for Compatbilty fix for JDK 1.3
+        // Convert Strng to float for deriveFont() call
+        Float stageFloat = new Float(inFontSize);
+        float fontSize   = stageFloat.floatValue();
+        Font  fonttTree  = fOwner.tTree.getFont().deriveFont(fontSize);
+
+        fOwner.tTree.setFont(fonttTree);
+
+        Font fontTxtCommand =
+            fOwner.txtCommand.getFont().deriveFont(fontSize);
+
+        fOwner.txtCommand.setFont(fontTxtCommand);
+
+        Font fontTxtResult = fOwner.txtResult.getFont().deriveFont(fontSize);
+
+        fOwner.txtResult.setFont(fontTxtResult);
+    }
+
+    /**
+     * Changes the style (Bold, Italic ) of the selected text by checking the
+     * style buttons
+     */
+    public static void setStyle() {
+
+        int style = Font.PLAIN;
+
+        if (ckbbold.isSelected()) {
+            style |= Font.BOLD;
+        }
+
+        if (ckbitalic.isSelected()) {
+            style |= Font.ITALIC;
+        }
+
+        fOwner.tTree.setFont(fOwner.txtCommand.getFont().deriveFont(style));
+        fOwner.txtCommand.setFont(
+            fOwner.txtCommand.getFont().deriveFont(style));
+        fOwner.txtResult.setFont(
+            fOwner.txtResult.getFont().deriveFont(style));
+    }
+
+    public static void setColor(String inTarget) {
+
+        if (inTarget.equals(BACKGROUND)) {
+            Color backgroundColor = JColorChooser.showDialog(null,
+                "DataBaseManagerSwing Choose Background Color",
+                fOwner.txtResult.getBackground());
+
+            if (backgroundColor != null) {
+                bgColorButton.setBackground(backgroundColor);
+                fOwner.txtCommand.setBackground(backgroundColor);
+                fOwner.txtResult.setBackground(backgroundColor);
+            }
+        } else {
+            Color foregroundColor = JColorChooser.showDialog(null,
+                "DataBaseManagerSwing Choose Foreground Color",
+                fOwner.txtResult.getForeground());
+
+            if (foregroundColor != null) {
+                fgColorButton.setBackground(foregroundColor);
+                fOwner.txtCommand.setForeground(foregroundColor);
+                fOwner.txtResult.setForeground(foregroundColor);
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/GreenCircle.gif b/src/org/hsqldb/util/GreenCircle.gif
new file mode 100644
index 0000000..d87a121
--- /dev/null
+++ b/src/org/hsqldb/util/GreenCircle.gif
Binary files differ
diff --git a/src/org/hsqldb/util/Grid.java b/src/org/hsqldb/util/Grid.java
new file mode 100644
index 0000000..d826cb4
--- /dev/null
+++ b/src/org/hsqldb/util/Grid.java
@@ -0,0 +1,615 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.util.Vector;
+
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Panel;
+import java.awt.Scrollbar;
+import java.awt.SystemColor;
+
+// sqlbob@users 20020401 - patch 1.7.0 by sqlbob (RMP) - enhancements
+
+/**
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.8.0
+ * @since Hypersonic SQL
+ */
+class Grid extends Panel {
+
+    // drawing
+    private Dimension dMinimum;
+
+// boucherb@users changed access for databasemanager2
+    protected Font fFont;
+
+// --------------------------------------------------
+    private FontMetrics fMetrics;
+    private Graphics    gImage;
+    private Image       iImage;
+
+    // height / width
+    private int iWidth, iHeight;
+    private int iRowHeight, iFirstRow;
+    private int iGridWidth, iGridHeight;
+    private int iX, iY;
+
+    // data
+// boucherb@users changed access for databasemanager2
+    protected String[] sColHead = new String[0];
+    protected Vector   vData    = new Vector();
+
+// --------------------------------------------------
+    private int[] iColWidth;
+    private int   iColCount;
+
+// boucherb@users changed access for databasemanager2
+    protected int iRowCount;
+
+// --------------------------------------------------
+    // scrolling
+    private Scrollbar sbHoriz, sbVert;
+    private int       iSbWidth, iSbHeight;
+    private boolean   bDrag;
+    private int       iXDrag, iColDrag;
+
+    /**
+     * Constructor declaration
+     *
+     */
+    public Grid() {
+
+        super();
+
+        fFont = new Font("Dialog", Font.PLAIN, 12);
+
+        setLayout(null);
+
+        sbHoriz = new Scrollbar(Scrollbar.HORIZONTAL);
+
+        add(sbHoriz);
+
+        sbVert = new Scrollbar(Scrollbar.VERTICAL);
+
+        add(sbVert);
+    }
+
+    /**
+     * Method declaration
+     */
+    String[] getHead() {
+        return sColHead;
+    }
+
+    /**
+     * Method declaration
+     */
+    Vector getData() {
+        return vData;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param d
+     */
+    public void setMinimumSize(Dimension d) {
+        dMinimum = d;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param x
+     * @param y
+     * @param w
+     * @param h
+     */
+    public void setBounds(int x, int y, int w, int h) {
+
+        // fredt@users 20011210 - patch 450412 by elise@users
+        super.setBounds(x, y, w, h);
+
+        iSbHeight = sbHoriz.getPreferredSize().height;
+        iSbWidth  = sbVert.getPreferredSize().width;
+        iHeight   = h - iSbHeight;
+        iWidth    = w - iSbWidth;
+
+        sbHoriz.setBounds(0, iHeight, iWidth, iSbHeight);
+        sbVert.setBounds(iWidth, 0, iSbWidth, iHeight);
+        adjustScroll();
+
+        iImage = null;
+
+        repaint();
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param head
+     */
+    public void setHead(String[] head) {
+
+        iColCount = head.length;
+        sColHead  = new String[iColCount];
+        iColWidth = new int[iColCount];
+
+        for (int i = 0; i < iColCount; i++) {
+            sColHead[i]  = head[i];
+            iColWidth[i] = 100;
+        }
+
+        iRowCount  = 0;
+        iRowHeight = 0;
+        vData      = new Vector();
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param data
+     */
+    public void addRow(String[] data) {
+
+        if (data.length != iColCount) {
+            return;
+        }
+
+        String[] row = new String[iColCount];
+
+        for (int i = 0; i < iColCount; i++) {
+            row[i] = data[i];
+
+            if (row[i] == null) {
+                row[i] = "(null)";
+            }
+        }
+
+        vData.addElement(row);
+
+        iRowCount++;
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    public void update() {
+        adjustScroll();
+        repaint();
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    void adjustScroll() {
+
+        if (iRowHeight == 0) {
+            return;
+        }
+
+        int w = 0;
+
+        for (int i = 0; i < iColCount; i++) {
+            w += iColWidth[i];
+        }
+
+        iGridWidth  = w;
+        iGridHeight = iRowHeight * (iRowCount + 1);
+
+        sbHoriz.setValues(iX, iWidth, 0, iGridWidth);
+
+        int v = iY / iRowHeight,
+            h = iHeight / iRowHeight;
+
+        sbVert.setValues(v, h, 0, iRowCount + 1);
+
+        iX = sbHoriz.getValue();
+        iY = iRowHeight * sbVert.getValue();
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+
+    // fredt@users 20020130 - comment by fredt
+    // to remove this deprecated method we need to rewrite the Grid class as a
+    // ScrollPane component
+    // sqlbob:  I believe that changing to the JDK1.1 event handler
+    // would require browsers to use the Java plugin.
+    public boolean handleEvent(Event e) {
+
+        switch (e.id) {
+
+            case Event.SCROLL_LINE_UP :
+            case Event.SCROLL_LINE_DOWN :
+            case Event.SCROLL_PAGE_UP :
+            case Event.SCROLL_PAGE_DOWN :
+            case Event.SCROLL_ABSOLUTE :
+                iX = sbHoriz.getValue();
+                iY = iRowHeight * sbVert.getValue();
+
+                repaint();
+
+                return true;
+        }
+
+        return super.handleEvent(e);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param g
+     */
+    public void paint(Graphics g) {
+
+        if (g == null) {
+            return;
+        }
+
+        if (sColHead.length == 0) {
+            super.paint(g);
+
+            return;
+        }
+
+        if (iWidth <= 0 || iHeight <= 0) {
+            return;
+        }
+
+        g.setColor(SystemColor.control);
+        g.fillRect(iWidth, iHeight, iSbWidth, iSbHeight);
+
+        if (iImage == null) {
+            iImage = createImage(iWidth, iHeight);
+            gImage = iImage.getGraphics();
+
+            gImage.setFont(fFont);
+
+            if (fMetrics == null) {
+                fMetrics = gImage.getFontMetrics();
+            }
+        }
+
+        if (iRowHeight == 0) {
+            iRowHeight = getMaxHeight(fMetrics);
+
+            for (int i = 0; i < iColCount; i++) {
+                calcAutoWidth(i);
+            }
+
+            adjustScroll();
+        }
+
+        gImage.setColor(Color.white);
+        gImage.fillRect(0, 0, iWidth, iHeight);
+        gImage.setColor(Color.darkGray);
+        gImage.drawLine(0, iRowHeight, iWidth, iRowHeight);
+
+        int x = -iX;
+
+        for (int i = 0; i < iColCount; i++) {
+            int w = iColWidth[i];
+
+            gImage.setColor(SystemColor.control);
+            gImage.fillRect(x + 1, 0, w - 2, iRowHeight);
+            gImage.setColor(Color.black);
+            gImage.drawString(sColHead[i], x + 2, iRowHeight - 5);
+            gImage.setColor(Color.darkGray);
+            gImage.drawLine(x + w - 1, 0, x + w - 1, iRowHeight - 1);
+            gImage.setColor(Color.white);
+            gImage.drawLine(x + w, 0, x + w, iRowHeight - 1);
+
+            x += w;
+        }
+
+        gImage.setColor(SystemColor.control);
+        gImage.fillRect(0, 0, 1, iRowHeight);
+        gImage.fillRect(x + 1, 0, iWidth - x, iRowHeight);
+        gImage.drawLine(0, 0, 0, iRowHeight - 1);
+
+        int y = iRowHeight + 1 - iY;
+        int j = 0;
+
+        while (y < iRowHeight + 1) {
+            j++;
+
+            y += iRowHeight;
+        }
+
+        iFirstRow = j;
+        y         = iRowHeight + 1;
+
+        for (; y < iHeight && j < iRowCount; j++, y += iRowHeight) {
+            x = -iX;
+
+            for (int i = 0; i < iColCount; i++) {
+                int   w = iColWidth[i];
+                Color b = Color.white,
+                      t = Color.black;
+
+                gImage.setColor(b);
+                gImage.fillRect(x, y, w - 1, iRowHeight - 1);
+                gImage.setColor(t);
+                gImage.drawString(getDisplay(i, j), x + 2,
+                                  y + iRowHeight - 5);
+                gImage.setColor(Color.lightGray);
+                gImage.drawLine(x + w - 1, y, x + w - 1, y + iRowHeight - 1);
+                gImage.drawLine(x, y + iRowHeight - 1, x + w - 1,
+                                y + iRowHeight - 1);
+
+                x += w;
+            }
+
+            gImage.setColor(Color.white);
+            gImage.fillRect(x, y, iWidth - x, iRowHeight - 1);
+        }
+
+        g.drawImage(iImage, 0, 0, this);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param g
+     */
+    public void update(Graphics g) {
+        paint(g);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     * @param x
+     * @param y
+     */
+    public boolean mouseMove(Event e, int x, int y) {
+
+        if (y <= iRowHeight) {
+            int xb = x;
+
+            x += iX - iGridWidth;
+
+            int i = iColCount - 1;
+
+            for (; i >= 0; i--) {
+                if (x > -7 && x < 7) {
+                    break;
+                }
+
+                x += iColWidth[i];
+            }
+
+            if (i >= 0) {
+                if (!bDrag) {
+                    setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
+
+                    bDrag    = true;
+                    iXDrag   = xb - iColWidth[i];
+                    iColDrag = i;
+                }
+
+                return true;
+            }
+        }
+
+        return mouseExit(e, x, y);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     * @param x
+     * @param y
+     */
+    public boolean mouseDrag(Event e, int x, int y) {
+
+        if (bDrag && x < iWidth) {
+            int w = x - iXDrag;
+
+            if (w < 0) {
+                w = 0;
+            }
+
+            iColWidth[iColDrag] = w;
+
+            adjustScroll();
+            repaint();
+        }
+
+        return true;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     * @param x
+     * @param y
+     */
+    public boolean mouseExit(Event e, int x, int y) {
+
+        if (bDrag) {
+            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+
+            bDrag = false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Method declaration
+     */
+    public Dimension preferredSize() {
+        return dMinimum;
+    }
+
+    /**
+     * Method declaration
+     */
+    public Dimension getPreferredSize() {
+        return dMinimum;
+    }
+
+    /**
+     * Method declaration
+     */
+    public Dimension getMinimumSize() {
+        return dMinimum;
+    }
+
+    /**
+     * Method declaration
+     */
+    public Dimension minimumSize() {
+        return dMinimum;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param i
+     */
+    private void calcAutoWidth(int i) {
+
+        int w = 10;
+
+        w = Math.max(w, fMetrics.stringWidth(sColHead[i]));
+
+        for (int j = 0; j < iRowCount; j++) {
+            String[] s = (String[]) (vData.elementAt(j));
+
+            w = Math.max(w, fMetrics.stringWidth(s[i]));
+        }
+
+        iColWidth[i] = w + 6;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param x
+     * @param y
+     */
+    private String getDisplay(int x, int y) {
+        return (((String[]) (vData.elementAt(y)))[x]);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param x
+     * @param y
+     */
+    private String get(int x, int y) {
+        return (((String[]) (vData.elementAt(y)))[x]);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param f
+     */
+    private static int getMaxHeight(FontMetrics f) {
+        return f.getHeight() + 4;
+    }
+}
diff --git a/src/org/hsqldb/util/GridSwing.java b/src/org/hsqldb/util/GridSwing.java
new file mode 100644
index 0000000..815cc0c
--- /dev/null
+++ b/src/org/hsqldb/util/GridSwing.java
@@ -0,0 +1,276 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.util.Vector;
+import java.awt.Component;
+
+import javax.swing.JTable;
+import javax.swing.event.TableModelEvent;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+
+// sqlbob@users 20020401 - patch 1.7.0 by sqlbob (RMP) - enhancements
+// deccles@users 20040412 - patch 933671 - various bug fixes
+
+/** Simple table model to represent a grid of tuples.
+ *
+ * New class based on Hypersonic SQL original
+ *
+ * @author dmarshall@users
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+class GridSwing extends AbstractTableModel {
+
+    JTable   jtable = null;
+    Object[] headers;
+    Vector   rows;
+
+    /**
+     * Default constructor.
+     */
+    public GridSwing() {
+
+        super();
+
+        headers = new Object[0];    // initially empty
+        rows    = new Vector();     // initially empty
+    }
+
+    /**
+     * Get the name for the specified column.
+     */
+    public String getColumnName(int i) {
+        return headers[i].toString();
+    }
+
+    public Class getColumnClass(int i) {
+
+        if (rows.size() > 0) {
+            Object o = getValueAt(0, i);
+
+            if (o != null) {
+                if ((o instanceof java.sql.Timestamp)
+                    || (o instanceof java.sql.Time)) {
+                    // This is a workaround for JTable's lack of a default
+                    // renderer that displays times.
+                    // Without this workaround, Timestamps (and similar
+                    // classes) will be displayed as dates without times,
+                    // since JTable will match these classes to their
+                    // java.util.Date superclass.
+                    return Object.class;  // renderer will draw .toString().
+                }
+                return o.getClass();
+            }
+        }
+
+        return super.getColumnClass(i);
+    }
+
+    /**
+     * Get the number of columns.
+     */
+    public int getColumnCount() {
+        return headers.length;
+    }
+
+    /**
+     * Get the number of rows currently in the table.
+     */
+    public int getRowCount() {
+        return rows.size();
+    }
+
+    /**
+     * Get the current column headings.
+     */
+    public Object[] getHead() {
+        return headers;
+    }
+
+    /**
+     * Get the current table data.
+     *  Each row is represented as a <code>String[]</code>
+     *  with a single non-null value in the 0-relative
+     *  column position.
+     *  <p>The first row is at offset 0, the nth row at offset n etc.
+     */
+    public Vector getData() {
+        return rows;
+    }
+
+    /**
+     * Get the object at the specified cell location.
+     */
+    public Object getValueAt(int row, int col) {
+
+        if (row >= rows.size()) {
+            return null;
+        }
+
+        Object[] colArray = (Object[]) rows.elementAt(row);
+
+        if (col >= colArray.length) {
+            return null;
+        }
+
+        return colArray[col];
+    }
+
+    /**
+     * Set the name of the column headings.
+     */
+    public void setHead(Object[] h) {
+
+        headers = new Object[h.length];
+
+        // System.arraycopy(h, 0, headers, 0, h.length);
+        for (int i = 0; i < h.length; i++) {
+            headers[i] = h[i];
+        }
+    }
+
+    /**
+     * Append a tuple to the end of the table.
+     */
+    public void addRow(Object[] r) {
+
+        Object[] row = new Object[r.length];
+
+        // System.arraycopy(r, 0, row, 0, r.length);
+        for (int i = 0; i < r.length; i++) {
+            row[i] = r[i];
+
+            if (row[i] == null) {
+
+//                row[i] = "(null)";
+            }
+        }
+
+        rows.addElement(row);
+    }
+
+    /**
+     * Remove data from all cells in the table (without
+     *  affecting the current headings).
+     */
+    public void clear() {
+        rows.removeAllElements();
+    }
+
+    public void setJTable(JTable table) {
+        jtable = table;
+    }
+
+    public void fireTableChanged(TableModelEvent e) {
+        super.fireTableChanged(e);
+        autoSizeTableColumns(jtable);
+    }
+
+    public static void autoSizeTableColumns(JTable table) {
+
+        TableModel  model        = table.getModel();
+        TableColumn column       = null;
+        Component   comp         = null;
+        int         headerWidth  = 0;
+        int         maxCellWidth = Integer.MIN_VALUE;
+        int         cellWidth    = 0;
+        TableCellRenderer headerRenderer =
+            table.getTableHeader().getDefaultRenderer();
+
+        for (int i = 0; i < table.getColumnCount(); i++) {
+            column = table.getColumnModel().getColumn(i);
+            comp = headerRenderer.getTableCellRendererComponent(table,
+                    column.getHeaderValue(), false, false, 0, 0);
+            headerWidth  = comp.getPreferredSize().width + 10;
+            maxCellWidth = Integer.MIN_VALUE;
+
+            for (int j = 0; j < Math.min(model.getRowCount(), 30); j++) {
+                TableCellRenderer r = table.getCellRenderer(j, i);
+
+                comp = r.getTableCellRendererComponent(table,
+                                                       model.getValueAt(j, i),
+                                                       false, false, j, i);
+                cellWidth = comp.getPreferredSize().width;
+
+                if (cellWidth >= maxCellWidth) {
+                    maxCellWidth = cellWidth;
+                }
+            }
+
+            column.setPreferredWidth(Math.max(headerWidth, maxCellWidth)
+                                     + 10);
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/HelperFactory.java b/src/org/hsqldb/util/HelperFactory.java
new file mode 100644
index 0000000..4a32d8c
--- /dev/null
+++ b/src/org/hsqldb/util/HelperFactory.java
@@ -0,0 +1,70 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+/**
+ * @author Nicolas BAZIN, INGENICO
+ * @version 1.7.0
+ */
+
+// brian.porter@siteforce.de 20020703 - added reference to OracleTransferHelper
+class HelperFactory {
+
+    HelperFactory() {}
+
+    // TransferHelper factory
+    static TransferHelper getHelper(String productLowerName) {
+
+        TransferHelper f = null;
+
+        if (productLowerName.indexOf("hsql database") != -1) {
+            f = new HsqldbTransferHelper();
+        } else if (productLowerName.indexOf("postgresql") != -1) {
+            f = new PostgresTransferHelper();
+        } else if (productLowerName.indexOf("mckoi") != -1) {
+            f = new McKoiTransferHelper();
+        } else if (productLowerName.indexOf("informix") != -1) {
+            f = new InformixTransferHelper();
+        } else if (productLowerName.indexOf("oracle") != -1) {
+            System.out.println("using the Oracle helper");
+
+            f = new OracleTransferHelper();
+        } else if (productLowerName.equals("access")
+                   || (productLowerName.indexOf("microsoft") != -1)) {
+            f = new SqlServerTransferHelper();
+        } else {
+            f = new TransferHelper();
+        }
+
+        return (f);
+    }
+}
diff --git a/src/org/hsqldb/util/Hourglass.gif b/src/org/hsqldb/util/Hourglass.gif
new file mode 100644
index 0000000..e501ac6
--- /dev/null
+++ b/src/org/hsqldb/util/Hourglass.gif
Binary files differ
diff --git a/src/org/hsqldb/util/HsqldbTransferHelper.java b/src/org/hsqldb/util/HsqldbTransferHelper.java
new file mode 100644
index 0000000..797c72d
--- /dev/null
+++ b/src/org/hsqldb/util/HsqldbTransferHelper.java
@@ -0,0 +1,111 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+
+// sqlbob@users 20020325 - patch 1.7.0 - reengineering
+
+/**
+ * Conversions to / from Hsqldb
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.7.0
+ */
+class HsqldbTransferHelper extends TransferHelper {
+
+    public HsqldbTransferHelper() {
+        super();
+    }
+
+    public HsqldbTransferHelper(TransferDb database, Traceable t, String q) {
+        super(database, t, q);
+    }
+
+    int convertFromType(int type) {
+
+        if (type == 100) {
+            type = Types.VARCHAR;
+
+            tracer.trace("Converted HSQLDB VARCHAR_IGNORECASE to VARCHAR");
+        }
+
+        return (type);
+    }
+
+    String fixupColumnDefRead(TransferTable t, ResultSetMetaData meta,
+                              String columnType, ResultSet columnDesc,
+                              int columnIndex) throws SQLException {
+
+        String CompareString = "INTEGER IDENTITY";
+
+        if (columnType.indexOf(CompareString) >= 0) {
+
+            // We just found a increment
+            columnType = "SERIAL";
+        }
+
+        return (columnType);
+    }
+
+    String fixupColumnDefWrite(TransferTable t, ResultSetMetaData meta,
+                               String columnType, ResultSet columnDesc,
+                               int columnIndex) throws SQLException {
+
+        if (columnType.indexOf("SERIAL") >= 0) {
+            columnType = " INTEGER IDENTITY ";
+        }
+
+        return (columnType);
+    }
+
+    String fixupColumnDefRead(String aTableName, ResultSetMetaData meta,
+                              String columnType, ResultSet columnDesc,
+                              int columnIndex) throws SQLException {
+        return fixupColumnDefRead((TransferTable) null, meta, columnType,
+                                  columnDesc, columnIndex);
+    }
+
+    String fixupColumnDefWrite(String aTableName, ResultSetMetaData meta,
+                               String columnType, ResultSet columnDesc,
+                               int columnIndex) throws SQLException {
+        return fixupColumnDefWrite((TransferTable) null, meta, columnType,
+                                   columnDesc, columnIndex);
+    }
+
+    String formatName(String t) {
+        return formatIdentifier(t);
+    }
+}
diff --git a/src/org/hsqldb/util/InformixTransferHelper.java b/src/org/hsqldb/util/InformixTransferHelper.java
new file mode 100644
index 0000000..04efe8c
--- /dev/null
+++ b/src/org/hsqldb/util/InformixTransferHelper.java
@@ -0,0 +1,95 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.Types;
+
+// fredt@users 20020215 - patch 516309 by Nicolas Bazin - transfer Informix
+// sqlbob@users 20020325 - patch 1.7.0 - reengineering
+
+/**
+ * Conversions from Informix databases
+ *
+ * @author Nichola Bazin
+ * @version 1.7.0
+ */
+class InformixTransferHelper extends TransferHelper {
+
+    public InformixTransferHelper() {
+        super();
+    }
+
+    public InformixTransferHelper(TransferDb database, Traceable t,
+                                  String q) {
+        super(database, t, q);
+    }
+
+    void setSchema(String _Schema) {
+        sSchema = "\"" + _Schema + "\"";
+    }
+
+    int convertFromType(int type) {
+
+        //Correct a bug in Informix JDBC driver that maps:
+        // DATETIME YEAR TO FRACTION to TIME and
+        // DATETIME HOUR TO SECOND to TIMESTAMP
+        if (type == Types.TIMESTAMP) {
+            type = Types.TIME;
+
+            tracer.trace("Converted INFORMIX TIMESTAMP to TIME");
+        } else if (type == Types.TIME) {
+            type = Types.TIMESTAMP;
+
+            tracer.trace("Converted INFORMIX TIME to TIMESTAMP");
+        }
+
+        return (type);
+    }
+
+    int convertToType(int type) {
+
+        //Correct a bug in Informix JDBC driver that maps:
+        // DATETIME YEAR TO FRACTION to TIME and
+        // DATETIME HOUR TO SECOND to TIMESTAMP
+        if (type == Types.TIMESTAMP) {
+            type = Types.TIME;
+
+            tracer.trace("Converted TIMESTAMP to INFORMIX TIME");
+        } else if (type == Types.TIME) {
+            type = Types.TIMESTAMP;
+
+            tracer.trace("Converted TIME to INFORMIX TIMESTAMP");
+        }
+
+        return (type);
+    }
+}
diff --git a/src/org/hsqldb/util/Italic.gif b/src/org/hsqldb/util/Italic.gif
new file mode 100644
index 0000000..9f74d9f
--- /dev/null
+++ b/src/org/hsqldb/util/Italic.gif
Binary files differ
diff --git a/src/org/hsqldb/util/JDBCTypes.java b/src/org/hsqldb/util/JDBCTypes.java
new file mode 100644
index 0000000..9c9607f
--- /dev/null
+++ b/src/org/hsqldb/util/JDBCTypes.java
@@ -0,0 +1,146 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.util.Hashtable;
+
+/**
+ * Base class for conversion from a different databases
+ *
+ * @author Nicolas BAZIN
+ * @version 1.7.0
+ */
+class JDBCTypes {
+
+    public static final int JAVA_OBJECT = 2000;
+    public static final int DISTINCT    = 2001;
+    public static final int STRUCT      = 2002;
+    public static final int ARRAY       = 2003;
+    public static final int BLOB        = 2004;
+    public static final int CLOB        = 2005;
+    public static final int REF         = 2006;
+    private Hashtable       hStringJDBCtypes;
+    private Hashtable       hIntJDBCtypes;
+
+    JDBCTypes() {
+
+        hStringJDBCtypes = new Hashtable();
+        hIntJDBCtypes    = new Hashtable();
+
+        hStringJDBCtypes.put(new Integer(ARRAY), "ARRAY");
+        hStringJDBCtypes.put(new Integer(BLOB), "BLOB");
+        hStringJDBCtypes.put(new Integer(CLOB), "CLOB");
+        hStringJDBCtypes.put(new Integer(DISTINCT), "DISTINCT");
+        hStringJDBCtypes.put(new Integer(JAVA_OBJECT), "JAVA_OBJECT");
+        hStringJDBCtypes.put(new Integer(REF), "REF");
+        hStringJDBCtypes.put(new Integer(STRUCT), "STRUCT");
+
+        //
+        hStringJDBCtypes.put(new Integer(java.sql.Types.BIGINT), "BIGINT");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.BINARY), "BINARY");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.BIT), "BIT");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.CHAR), "CHAR");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.DATE), "DATE");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.DECIMAL), "DECIMAL");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.DOUBLE), "DOUBLE");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.FLOAT), "FLOAT");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.INTEGER), "INTEGER");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.LONGVARBINARY),
+                             "LONGVARBINARY");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.LONGVARCHAR),
+                             "LONGVARCHAR");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.NULL), "NULL");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.NUMERIC), "NUMERIC");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.OTHER), "OTHER");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.REAL), "REAL");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.SMALLINT),
+                             "SMALLINT");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.TIME), "TIME");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.TIMESTAMP),
+                             "TIMESTAMP");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.TINYINT), "TINYINT");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.VARBINARY),
+                             "VARBINARY");
+        hStringJDBCtypes.put(new Integer(java.sql.Types.VARCHAR), "VARCHAR");
+
+        hStringJDBCtypes.put(new Integer(java.sql.Types.BOOLEAN), "BOOLEAN");
+        //
+        hIntJDBCtypes.put("ARRAY", new Integer(ARRAY));
+        hIntJDBCtypes.put("BLOB", new Integer(BLOB));
+        hIntJDBCtypes.put("CLOB", new Integer(CLOB));
+        hIntJDBCtypes.put("DISTINCT", new Integer(DISTINCT));
+        hIntJDBCtypes.put("JAVA_OBJECT", new Integer(JAVA_OBJECT));
+        hIntJDBCtypes.put("REF", new Integer(REF));
+        hIntJDBCtypes.put("STRUCT", new Integer(STRUCT));
+
+        //
+        hIntJDBCtypes.put("BIGINT", new Integer(java.sql.Types.BIGINT));
+        hIntJDBCtypes.put("BINARY", new Integer(java.sql.Types.BINARY));
+        hIntJDBCtypes.put("BIT", new Integer(java.sql.Types.BIT));
+        hIntJDBCtypes.put("CHAR", new Integer(java.sql.Types.CHAR));
+        hIntJDBCtypes.put("DATE", new Integer(java.sql.Types.DATE));
+        hIntJDBCtypes.put("DECIMAL", new Integer(java.sql.Types.DECIMAL));
+        hIntJDBCtypes.put("DOUBLE", new Integer(java.sql.Types.DOUBLE));
+        hIntJDBCtypes.put("FLOAT", new Integer(java.sql.Types.FLOAT));
+        hIntJDBCtypes.put("INTEGER", new Integer(java.sql.Types.INTEGER));
+        hIntJDBCtypes.put("LONGVARBINARY",
+                          new Integer(java.sql.Types.LONGVARBINARY));
+        hIntJDBCtypes.put("LONGVARCHAR",
+                          new Integer(java.sql.Types.LONGVARCHAR));
+        hIntJDBCtypes.put("NULL", new Integer(java.sql.Types.NULL));
+        hIntJDBCtypes.put("NUMERIC", new Integer(java.sql.Types.NUMERIC));
+        hIntJDBCtypes.put("OTHER", new Integer(java.sql.Types.OTHER));
+        hIntJDBCtypes.put("REAL", new Integer(java.sql.Types.REAL));
+        hIntJDBCtypes.put("SMALLINT", new Integer(java.sql.Types.SMALLINT));
+        hIntJDBCtypes.put("TIME", new Integer(java.sql.Types.TIME));
+        hIntJDBCtypes.put("TIMESTAMP", new Integer(java.sql.Types.TIMESTAMP));
+        hIntJDBCtypes.put("TINYINT", new Integer(java.sql.Types.TINYINT));
+        hIntJDBCtypes.put("VARBINARY", new Integer(java.sql.Types.VARBINARY));
+        hIntJDBCtypes.put("VARCHAR", new Integer(java.sql.Types.VARCHAR));
+        hIntJDBCtypes.put("BOOLEAN", new Integer(java.sql.Types.BOOLEAN));
+    }
+
+    public Hashtable getHashtable() {
+        return hStringJDBCtypes;
+    }
+
+    public String toString(int type) {
+        return (String) hStringJDBCtypes.get(new Integer(type));
+    }
+
+    public int toInt(String type) throws Exception {
+
+        Integer tempInteger = (Integer) hIntJDBCtypes.get(type);
+
+        return tempInteger.intValue();
+    }
+}
diff --git a/src/org/hsqldb/util/MainInvoker.java b/src/org/hsqldb/util/MainInvoker.java
new file mode 100644
index 0000000..f75f52a
--- /dev/null
+++ b/src/org/hsqldb/util/MainInvoker.java
@@ -0,0 +1,148 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+/**
+ * Invokes the static main(String[]) method from each class specified.
+ *
+ * This class <b>will System.exit()</b> if any invocation fails.
+ *
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ * @since    HSQLDB 1.8.0
+ * @version  $Revision: 3481 $, $Date: 2010-02-26 13:05:06 -0500 (Fri, 26 Feb 2010) $
+ */
+public class MainInvoker {
+
+    /*
+     * This class currently consists of just a static utility.
+     * It may or may not make sense to make this into a class with real
+     * instances that can keep track of status of stuff invoked by it.
+     */
+    private static String[] emptyStringArray = new String[0];
+
+    private static void syntaxFailure() {
+        System.err.println(SYNTAX_MSG);
+        System.exit(2);
+    }
+
+    /**
+     * Invokes the static main(String[]) method from each specified class.
+     * This method <b>will System.exit()</b> if any invocation fails.
+     *
+     * Note that multiple class invocations are delimited by empty-string
+     * parameters.  How the user supplies these empty strings is determined
+     * entirely by the caller's environment.  From Windows this can
+     * generally be accomplished with double-quotes like "".  From all
+     * popular UNIX shells, this can be accomplished with single or
+     * double-quotes:  '' or "".
+     *
+     * @param sa Run java org.hsqldb.util.MainInvoker --help for syntax help
+     */
+    public static void main(String[] sa) {
+
+        if (sa.length > 0 && sa[0].equals("--help")) {
+            System.err.println(SYNTAX_MSG);
+            System.exit(0);
+        }
+
+        ArrayList outList  = new ArrayList();
+        int       curInArg = -1;
+
+        try {
+            while (++curInArg < sa.length) {
+                if (sa[curInArg].length() < 1) {
+                    if (outList.size() < 1) {
+                        syntaxFailure();
+                    }
+
+                    invoke((String) outList.remove(0),
+                           (String[]) outList.toArray(emptyStringArray));
+                    outList.clear();
+                } else {
+                    outList.add(sa[curInArg]);
+                }
+            }
+
+            if (outList.size() < 1) {
+                syntaxFailure();
+            }
+
+            invoke((String) outList.remove(0),
+                   (String[]) outList.toArray(emptyStringArray));
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    public static String LS = System.getProperty("line.separator");
+    private static String SYNTAX_MSG =
+        "    java org.hsqldb.util.MainInvoker "
+        + "[package1.Class1 [arg1a arg1b...] \"\"]... \\\n"
+        + "    packageX.ClassX [argXa argXb...]\n" + "OR\n"
+        + "    java org.hsqldb.util.MainInvoker --help\n\n"
+        + "Note that you can only invoke classes in 'named' (non-default) "
+        + "packages.  Delimit multiple classes with empty strings.";
+    static {
+        if (!LS.equals("\n")) {
+            SYNTAX_MSG = SYNTAX_MSG.replaceAll("\n", LS);
+        }
+    }
+
+    /**
+     * Invokes the static main(String[]) method from each specified class.
+     */
+    public static void invoke(String className,
+                              String[] args)
+                              throws ClassNotFoundException,
+                                     NoSuchMethodException,
+                                     IllegalAccessException,
+                                     InvocationTargetException {
+
+        Class    c;
+        Method   method;
+        Class[]  stringArrayCA = { emptyStringArray.getClass() };
+        Object[] objectArray   = { (args == null) ? emptyStringArray
+                                                  : args };
+
+        c      = Class.forName(className);
+        method = c.getMethod("main", stringArrayCA);
+
+        method.invoke(null, objectArray);
+
+        //System.err.println(c.getName() + ".main() invoked");
+    }
+}
diff --git a/src/org/hsqldb/util/McKoiTransferHelper.java b/src/org/hsqldb/util/McKoiTransferHelper.java
new file mode 100644
index 0000000..a478f66
--- /dev/null
+++ b/src/org/hsqldb/util/McKoiTransferHelper.java
@@ -0,0 +1,84 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+/**
+ * Helper class for conversion from a different databases
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.7.0
+ */
+class McKoiTransferHelper extends TransferHelper {
+
+    McKoiTransferHelper() {
+        super();
+    }
+
+    String fixupColumnDefRead(TransferTable t, ResultSetMetaData meta,
+                              String columnType, ResultSet columnDesc,
+                              int columnIndex) throws SQLException {
+
+        String CompareString = "UNIQUEKEY(\'" + t.Stmts.sDestTable + "\'";
+
+        if (columnType.indexOf(CompareString) > 0) {
+
+            // We just found a increment
+            columnType = "SERIAL";
+        }
+
+        return (columnType);
+    }
+
+    public McKoiTransferHelper(TransferDb database, Traceable t, String q) {
+        super(database, t, q);
+    }
+
+    String fixupColumnDefWrite(TransferTable t, ResultSetMetaData meta,
+                               String columnType, ResultSet columnDesc,
+                               int columnIndex) throws SQLException {
+
+        if (columnType.equals("SERIAL")) {
+            columnType = "INTEGER DEFAULT UNIQUEKEY (\'"
+                         + t.Stmts.sSourceTable + "\')";
+        }
+
+        return (columnType);
+    }
+
+    boolean needTransferTransaction() {
+        return (true);
+    }
+}
diff --git a/src/org/hsqldb/util/NoWay.gif b/src/org/hsqldb/util/NoWay.gif
new file mode 100644
index 0000000..c865ddf
--- /dev/null
+++ b/src/org/hsqldb/util/NoWay.gif
Binary files differ
diff --git a/src/org/hsqldb/util/OracleTransferHelper.java b/src/org/hsqldb/util/OracleTransferHelper.java
new file mode 100644
index 0000000..99871ef
--- /dev/null
+++ b/src/org/hsqldb/util/OracleTransferHelper.java
@@ -0,0 +1,183 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+// brian.porter@siteforce.de 20020703 - make sure date is loaded in the required format
+// Stephan Frind 20040508 - improvements
+
+/**
+ * Conversions from Oracle databases
+ *
+ * @author Nichola Bazin
+ * @version 1.7.0
+ */
+class OracleTransferHelper extends TransferHelper {
+
+    private final int ORACLE = 0;
+    private final int HSQLDB = 1;
+    String[][]        Funcs  = {
+        {
+            "now()", "\'now\'"
+        }
+    };
+
+    OracleTransferHelper() {
+
+        super();
+
+        System.out.println("simple init of OracleTransferHelper");
+    }
+
+    OracleTransferHelper(TransferDb database, Traceable t, String q) {
+        super(database, t, q);
+    }
+
+    void set(TransferDb database, Traceable t, String q) {
+
+        super.set(database, t, q);
+
+        // set the Dateformat for our connection
+        String dateFormatStmnt =
+            "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'";
+
+        System.out.println("dateFormatStmnt: " + dateFormatStmnt);
+
+        try {
+            tracer.trace("Executing " + dateFormatStmnt);
+            database.execute(dateFormatStmnt);
+        } catch (Exception e) {
+            tracer.trace("Ignoring error " + e.getMessage());
+            System.out.println("Ignoring error " + e.getMessage());
+        }
+    }
+
+    String fixupColumnDefRead(TransferTable t, ResultSetMetaData meta,
+                              String columnType, ResultSet columnDesc,
+                              int columnIndex) throws SQLException {
+        return fixupColumnDefRead(t.Stmts.sDestTable, meta, columnType,
+                                  columnDesc, columnIndex);
+    }
+
+    String fixupColumnDefWrite(TransferTable t, ResultSetMetaData meta,
+                               String columnType, ResultSet columnDesc,
+                               int columnIndex) throws SQLException {
+
+        if (columnType.equals("SERIAL")) {
+            String SeqName = new String("_" + columnDesc.getString(4)
+                                        + "_seq");
+            int spaceleft = 31 - SeqName.length();
+
+            if (t.Stmts.sDestTable.length() > spaceleft) {
+                SeqName = t.Stmts.sDestTable.substring(0, spaceleft)
+                          + SeqName;
+            } else {
+                SeqName = t.Stmts.sDestTable + SeqName;
+            }
+
+            String DropSequence = "DROP SEQUENCE " + SeqName + ";";
+
+            t.Stmts.sDestDrop += DropSequence;
+        }
+
+        for (int Idx = 0; Idx < Funcs.length; Idx++) {
+            String HSQLDB_func = Funcs[Idx][HSQLDB];
+            int    iStartPos   = columnType.indexOf(HSQLDB_func);
+
+            if (iStartPos >= 0) {
+                String NewColumnType = columnType.substring(0, iStartPos);
+
+                NewColumnType += Funcs[Idx][ORACLE];
+                NewColumnType += columnType.substring(iStartPos
+                                                      + HSQLDB_func.length());
+                columnType = NewColumnType;
+            }
+        }
+
+        return (columnType);
+    }
+
+    void beginDataTransfer() {
+
+        try {
+            db.setAutoCommit(false);
+        } catch (Exception e) {}
+    }
+
+    void endDataTransfer() {
+
+        try {
+            db.commit();
+        } catch (Exception e) {}
+    }
+
+    String fixupColumnDefRead(String aTableName, ResultSetMetaData meta,
+                              String columnType, ResultSet columnDesc,
+                              int columnIndex) throws SQLException {
+
+        String SeqName   = new String("_" + columnDesc.getString(4) + "_seq");
+        int    spaceleft = 31 - SeqName.length();
+
+        if (aTableName.length() > spaceleft) {
+            SeqName = aTableName.substring(0, spaceleft) + SeqName;
+        } else {
+            SeqName = aTableName + SeqName;
+        }
+
+        String CompareString = "nextval(\'\"" + SeqName + "\"\'";
+
+        if (columnType.indexOf(CompareString) >= 0) {
+
+            // We just found a increment
+            columnType = "SERIAL";
+        }
+
+        for (int Idx = 0; Idx < Funcs.length; Idx++) {
+            String ORACLE_func = Funcs[Idx][ORACLE];
+            int    iStartPos   = columnType.indexOf(ORACLE_func);
+
+            if (iStartPos >= 0) {
+                String NewColumnType = columnType.substring(0, iStartPos);
+
+                NewColumnType += Funcs[Idx][HSQLDB];
+                NewColumnType += columnType.substring(iStartPos
+                                                      + ORACLE_func.length());
+                columnType = NewColumnType;
+            }
+        }
+
+        return (columnType);
+    }
+}
diff --git a/src/org/hsqldb/util/PostgresTransferHelper.java b/src/org/hsqldb/util/PostgresTransferHelper.java
new file mode 100644
index 0000000..93a4b2b
--- /dev/null
+++ b/src/org/hsqldb/util/PostgresTransferHelper.java
@@ -0,0 +1,168 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+
+// fredt@users 20020215 - patch 516309 by Nicolas Bazin - transfer PostgresSQL
+// sqlbob@users 20020325 - patch 1.7.0 - reengineering
+
+/**
+ * Conversions from PostgresSQL databases
+ *
+ * @author Nichola Bazin
+ * @version 1.7.0
+ */
+class PostgresTransferHelper extends TransferHelper {
+
+    private final int PostgreSQL = 0;
+    private final int HSQLDB     = 1;
+    String[][]        Funcs      = {
+        {
+            "now()", "\'now\'"
+        }
+    };
+
+    PostgresTransferHelper() {
+        super();
+    }
+
+    PostgresTransferHelper(TransferDb database, Traceable t, String q) {
+        super(database, t, q);
+    }
+
+    int convertToType(int type) {
+
+        if (type == Types.DECIMAL) {
+            type = Types.NUMERIC;
+
+            tracer.trace("Converted DECIMAL to NUMERIC");
+        }
+
+        return (type);
+    }
+
+    String fixupColumnDefRead(TransferTable t, ResultSetMetaData meta,
+                              String columnType, ResultSet columnDesc,
+                              int columnIndex) throws SQLException {
+
+        String SeqName   = new String("_" + columnDesc.getString(4) + "_seq");
+        int    spaceleft = 31 - SeqName.length();
+
+        if (t.Stmts.sDestTable.length() > spaceleft) {
+            SeqName = t.Stmts.sDestTable.substring(0, spaceleft) + SeqName;
+        } else {
+            SeqName = t.Stmts.sDestTable + SeqName;
+        }
+
+        String CompareString = "nextval(\'\"" + SeqName + "\"\'";
+
+        if (columnType.indexOf(CompareString) >= 0) {
+
+            // We just found a increment
+            columnType = "SERIAL";
+        }
+
+        for (int Idx = 0; Idx < Funcs.length; Idx++) {
+            String PostgreSQL_func = Funcs[Idx][PostgreSQL];
+            int    iStartPos       = columnType.indexOf(PostgreSQL_func);
+
+            if (iStartPos >= 0) {
+                String NewColumnType = columnType.substring(0, iStartPos);
+
+                NewColumnType += Funcs[Idx][HSQLDB];
+                NewColumnType +=
+                    columnType.substring(iStartPos
+                                         + PostgreSQL_func.length());
+                columnType = NewColumnType;
+            }
+        }
+
+        return (columnType);
+    }
+
+    String fixupColumnDefWrite(TransferTable t, ResultSetMetaData meta,
+                               String columnType, ResultSet columnDesc,
+                               int columnIndex) throws SQLException {
+
+        if (columnType.equals("SERIAL")) {
+            String SeqName = new String("_" + columnDesc.getString(4)
+                                        + "_seq");
+            int spaceleft = 31 - SeqName.length();
+
+            if (t.Stmts.sDestTable.length() > spaceleft) {
+                SeqName = t.Stmts.sDestTable.substring(0, spaceleft)
+                          + SeqName;
+            } else {
+                SeqName = t.Stmts.sDestTable + SeqName;
+            }
+
+            String DropSequence = "DROP SEQUENCE " + SeqName + ";";
+
+            t.Stmts.sDestDrop += DropSequence;
+        }
+
+        for (int Idx = 0; Idx < Funcs.length; Idx++) {
+            String HSQLDB_func = Funcs[Idx][HSQLDB];
+            int    iStartPos   = columnType.indexOf(HSQLDB_func);
+
+            if (iStartPos >= 0) {
+                String NewColumnType = columnType.substring(0, iStartPos);
+
+                NewColumnType += Funcs[Idx][PostgreSQL];
+                NewColumnType += columnType.substring(iStartPos
+                                                      + HSQLDB_func.length());
+                columnType = NewColumnType;
+            }
+        }
+
+        return (columnType);
+    }
+
+    void beginDataTransfer() {
+
+        try {
+            db.setAutoCommit(false);
+        } catch (Exception e) {}
+    }
+
+    void endDataTransfer() {
+
+        try {
+            db.commit();
+            db.execute("VACUUM ANALYZE");
+        } catch (Exception e) {}
+    }
+}
diff --git a/src/org/hsqldb/util/RedCircle.gif b/src/org/hsqldb/util/RedCircle.gif
new file mode 100644
index 0000000..35c2a75
--- /dev/null
+++ b/src/org/hsqldb/util/RedCircle.gif
Binary files differ
diff --git a/src/org/hsqldb/util/SQLStatements.java b/src/org/hsqldb/util/SQLStatements.java
new file mode 100644
index 0000000..f6d06e8
--- /dev/null
+++ b/src/org/hsqldb/util/SQLStatements.java
@@ -0,0 +1,100 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.Serializable;
+
+/**
+ * container for set of SQL statements
+ *
+ * New class based on Hypersonic SQL code.
+ *
+ * @version 1.7.1
+ * @since 1.7.1
+ */
+class SQLStatements implements Serializable {
+
+    String  sSchema, sType;
+    String  sDatabaseToConvert;
+    String  sSourceTable, sDestTable;
+    String  sDestDrop, sDestCreate, sDestInsert, sDestDelete;
+    String  sDestDropIndex, sDestCreateIndex, sDestAlter, sSourceSelect;
+    boolean bTransfer    = true;
+    boolean bCreate      = true;
+    boolean bDelete      = true;
+    boolean bDrop        = true;
+    boolean bCreateIndex = true;
+    boolean bDropIndex   = true;
+    boolean bInsert      = true;
+    boolean bAlter       = true;
+    boolean bFKForced    = false;
+    boolean bIdxForced   = false;
+}
diff --git a/src/org/hsqldb/util/SqlServerTransferHelper.java b/src/org/hsqldb/util/SqlServerTransferHelper.java
new file mode 100644
index 0000000..ec33844
--- /dev/null
+++ b/src/org/hsqldb/util/SqlServerTransferHelper.java
@@ -0,0 +1,131 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.Types;
+
+// sqlbob@users 20020325 - patch 1.7.0 - reengineering
+
+/**
+ * Conversions from SQLServer7 databases
+ *
+ * @version 1.7.0
+ */
+class SqlServerTransferHelper extends TransferHelper {
+
+    private boolean firstTinyintRow;
+    private boolean firstSmallintRow;
+
+    SqlServerTransferHelper() {
+        super();
+    }
+
+    SqlServerTransferHelper(TransferDb database, Traceable t, String q) {
+        super(database, t, q);
+    }
+
+    String formatTableName(String t) {
+
+        if (t == null) {
+            return t;
+        }
+
+        if (t.equals("")) {
+            return t;
+        }
+
+        if (t.indexOf(' ') != -1) {
+            return ("[" + t + "]");
+        } else {
+            return (formatIdentifier(t));
+        }
+    }
+
+    int convertFromType(int type) {
+
+        // MS SQL 7 specific problems (Northwind database)
+        if (type == 11) {
+            tracer.trace("Converted DATETIME (type 11) to TIMESTAMP");
+
+            type = Types.TIMESTAMP;
+        } else if (type == -9) {
+            tracer.trace("Converted NVARCHAR (type -9) to VARCHAR");
+
+            type = Types.VARCHAR;
+        } else if (type == -8) {
+            tracer.trace("Converted NCHAR (type -8) to VARCHAR");
+
+            type = Types.VARCHAR;
+        } else if (type == -10) {
+            tracer.trace("Converted NTEXT (type -10) to VARCHAR");
+
+            type = Types.VARCHAR;
+        } else if (type == -1) {
+            tracer.trace("Converted LONGTEXT (type -1) to LONGVARCHAR");
+
+            type = Types.LONGVARCHAR;
+        }
+
+        return (type);
+    }
+
+    void beginTransfer() {
+        firstSmallintRow = true;
+        firstTinyintRow  = true;
+    }
+
+    Object convertColumnValue(Object value, int column, int type) {
+
+        // solves a problem for MS SQL 7
+        if ((type == Types.SMALLINT) && (value instanceof Integer)) {
+            if (firstSmallintRow) {
+                firstSmallintRow = false;
+
+                tracer.trace("SMALLINT: Converted column " + column
+                             + " Integer to Short");
+            }
+
+            value = new Short((short) ((Integer) value).intValue());
+        } else if ((type == Types.TINYINT) && (value instanceof Integer)) {
+            if (firstTinyintRow) {
+                firstTinyintRow = false;
+
+                tracer.trace("TINYINT: Converted column " + column
+                             + " Integer to Byte");
+            }
+
+            value = new Byte((byte) ((Integer) value).intValue());
+        }
+
+        return (value);
+    }
+}
diff --git a/src/org/hsqldb/util/TableSorter.java b/src/org/hsqldb/util/TableSorter.java
new file mode 100644
index 0000000..2db6730
--- /dev/null
+++ b/src/org/hsqldb/util/TableSorter.java
@@ -0,0 +1,592 @@
+package org.hsqldb.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import javax.swing.Icon;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
+
+/**
+ * TableSorter is a decorator for TableModels; adding sorting
+ * functionality to a supplied TableModel. TableSorter does
+ * not store or copy the data in its TableModel; instead it maintains
+ * a map from the row indexes of the view to the row indexes of the
+ * model. As requests are made of the sorter (like getValueAt(row, col))
+ * they are passed to the underlying model after the row numbers
+ * have been translated via the internal mapping array. This way,
+ * the TableSorter appears to hold another copy of the table
+ * with the rows in a different order.
+ * <p/>
+ * TableSorter registers itself as a listener to the underlying model,
+ * just as the JTable itself would. Events recieved from the model
+ * are examined, sometimes manipulated (typically widened), and then
+ * passed on to the TableSorter's listeners (typically the JTable).
+ * If a change to the model has invalidated the order of TableSorter's
+ * rows, a note of this is made and the sorter will resort the
+ * rows the next time a value is requested.
+ * <p/>
+ * When the tableHeader property is set, either by using the
+ * setTableHeader() method or the two argument constructor, the
+ * table header may be used as a complete UI for TableSorter.
+ * The default renderer of the tableHeader is decorated with a renderer
+ * that indicates the sorting status of each column. In addition,
+ * a mouse listener is installed with the following behavior:
+ * <ul>
+ * <li>
+ * Mouse-click: Clears the sorting status of all other columns
+ * and advances the sorting status of that column through three
+ * values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to
+ * NOT_SORTED again).
+ * <li>
+ * SHIFT-mouse-click: Clears the sorting status of all other columns
+ * and cycles the sorting status of the column through the same
+ * three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}.
+ * <li>
+ * CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except
+ * that the changes to the column do not cancel the statuses of columns
+ * that are already sorting - giving a way to initiate a compound
+ * sort.
+ * </ul>
+ * <p/>
+ * This is a long overdue rewrite of a class of the same name that
+ * first appeared in the swing table demos in 1997.
+ *
+ * @author Philip Milne
+ * @author Brendon McLean
+ * @author Dan van Enckevort
+ * @author Parwinder Sekhon
+ * @version 2.0 02/27/04
+ */
+public class TableSorter extends AbstractTableModel {
+
+    protected TableModel           tableModel;
+    public static final int        DESCENDING            = -1;
+    public static final int        NOT_SORTED            = 0;
+    public static final int        ASCENDING             = 1;
+    private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
+    public static final Comparator COMPARABLE_COMPARATOR = new Comparator() {
+
+        public int compare(Object o1, Object o2) {
+
+            if (o1 == o2) {
+                return 0;
+            }
+
+            if (o1 == null) {
+                if (o2 == null) {
+                    return 0;
+                }
+
+                return -1;
+            }
+
+            if (o2 == null) {
+                return 1;
+            }
+
+            return ((Comparable) o1).compareTo(o2);
+        }
+    };
+    public static final Comparator LEXICAL_COMPARATOR = new Comparator() {
+
+        public int compare(Object o1, Object o2) {
+            return o1.toString().compareTo(o2.toString());
+        }
+    };
+    private Row[]              viewToModel;
+    private int[]              modelToView;
+    private JTableHeader       tableHeader;
+    private MouseListener      mouseListener;
+    private TableModelListener tableModelListener;
+    private Map                columnComparators = new HashMap();
+    private List               sortingColumns    = new ArrayList();
+
+    public TableSorter() {
+        this.mouseListener      = new MouseHandler();
+        this.tableModelListener = new TableModelHandler();
+    }
+
+    public TableSorter(TableModel tableModel) {
+
+        this();
+
+        setTableModel(tableModel);
+    }
+
+    public TableSorter(TableModel tableModel, JTableHeader tableHeader) {
+
+        this();
+
+        setTableHeader(tableHeader);
+        setTableModel(tableModel);
+    }
+
+    private void clearSortingState() {
+        viewToModel = null;
+        modelToView = null;
+    }
+
+    public TableModel getTableModel() {
+        return tableModel;
+    }
+
+    public void setTableModel(TableModel tableModel) {
+
+        if (this.tableModel != null) {
+            this.tableModel.removeTableModelListener(tableModelListener);
+        }
+
+        this.tableModel = tableModel;
+
+        if (this.tableModel != null) {
+            this.tableModel.addTableModelListener(tableModelListener);
+        }
+
+        clearSortingState();
+        fireTableStructureChanged();
+    }
+
+    public JTableHeader getTableHeader() {
+        return tableHeader;
+    }
+
+    public void setTableHeader(JTableHeader tableHeader) {
+
+        if (this.tableHeader != null) {
+            this.tableHeader.removeMouseListener(mouseListener);
+
+            TableCellRenderer defaultRenderer =
+                this.tableHeader.getDefaultRenderer();
+
+            if (defaultRenderer instanceof SortableHeaderRenderer) {
+                this.tableHeader.setDefaultRenderer(
+                    ((SortableHeaderRenderer) defaultRenderer)
+                        .tableCellRenderer);
+            }
+        }
+
+        this.tableHeader = tableHeader;
+
+        if (this.tableHeader != null) {
+            this.tableHeader.addMouseListener(mouseListener);
+            this.tableHeader.setDefaultRenderer(
+                new SortableHeaderRenderer(
+                    this.tableHeader.getDefaultRenderer()));
+        }
+    }
+
+    public boolean isSorting() {
+        return sortingColumns.size() != 0;
+    }
+
+    private Directive getDirective(int column) {
+
+        for (int i = 0; i < sortingColumns.size(); i++) {
+            Directive directive = (Directive) sortingColumns.get(i);
+
+            if (directive.column == column) {
+                return directive;
+            }
+        }
+
+        return EMPTY_DIRECTIVE;
+    }
+
+    public int getSortingStatus(int column) {
+        return getDirective(column).direction;
+    }
+
+    private void sortingStatusChanged() {
+
+        clearSortingState();
+        fireTableDataChanged();
+
+        if (tableHeader != null) {
+            tableHeader.repaint();
+        }
+    }
+
+    public void setSortingStatus(int column, int status) {
+
+        Directive directive = getDirective(column);
+
+        if (directive != EMPTY_DIRECTIVE) {
+            sortingColumns.remove(directive);
+        }
+
+        if (status != NOT_SORTED) {
+            sortingColumns.add(new Directive(column, status));
+        }
+
+        sortingStatusChanged();
+    }
+
+    protected Icon getHeaderRendererIcon(int column, int size) {
+
+        Directive directive = getDirective(column);
+
+        if (directive == EMPTY_DIRECTIVE) {
+            return null;
+        }
+
+        return new Arrow(directive.direction == DESCENDING, size,
+                         sortingColumns.indexOf(directive));
+    }
+
+    private void cancelSorting() {
+        sortingColumns.clear();
+        sortingStatusChanged();
+    }
+
+    public void setColumnComparator(Class type, Comparator comparator) {
+
+        if (comparator == null) {
+            columnComparators.remove(type);
+        } else {
+            columnComparators.put(type, comparator);
+        }
+    }
+
+    protected Comparator getComparator(int column) {
+
+        Class columnType = tableModel.getColumnClass(column);
+        Comparator comparator =
+            (Comparator) columnComparators.get(columnType);
+
+        if (comparator != null) {
+            return comparator;
+        }
+
+        if (Comparable.class.isAssignableFrom(columnType)) {
+            return COMPARABLE_COMPARATOR;
+        }
+
+        return LEXICAL_COMPARATOR;
+    }
+
+    private Row[] getViewToModel() {
+
+        if (viewToModel == null) {
+            int tableModelRowCount = tableModel.getRowCount();
+
+            viewToModel = new Row[tableModelRowCount];
+
+            for (int row = 0; row < tableModelRowCount; row++) {
+                viewToModel[row] = new Row(row);
+            }
+
+            if (isSorting()) {
+                Arrays.sort(viewToModel);
+            }
+        }
+
+        return viewToModel;
+    }
+
+    public int modelIndex(int viewIndex) {
+        return getViewToModel()[viewIndex].modelIndex;
+    }
+
+    private int[] getModelToView() {
+
+        if (modelToView == null) {
+            int n = getViewToModel().length;
+
+            modelToView = new int[n];
+
+            for (int i = 0; i < n; i++) {
+                modelToView[modelIndex(i)] = i;
+            }
+        }
+
+        return modelToView;
+    }
+
+    // TableModel interface methods
+    public int getRowCount() {
+        return (tableModel == null) ? 0
+                                    : tableModel.getRowCount();
+    }
+
+    public int getColumnCount() {
+        return (tableModel == null) ? 0
+                                    : tableModel.getColumnCount();
+    }
+
+    public String getColumnName(int column) {
+        return tableModel.getColumnName(column);
+    }
+
+    public Class getColumnClass(int column) {
+        return tableModel.getColumnClass(column);
+    }
+
+    public boolean isCellEditable(int row, int column) {
+        return tableModel.isCellEditable(modelIndex(row), column);
+    }
+
+    public Object getValueAt(int row, int column) {
+        return tableModel.getValueAt(modelIndex(row), column);
+    }
+
+    public void setValueAt(Object aValue, int row, int column) {
+        tableModel.setValueAt(aValue, modelIndex(row), column);
+    }
+
+    // Helper classes
+    private class Row implements Comparable {
+
+        private int modelIndex;
+
+        public Row(int index) {
+            this.modelIndex = index;
+        }
+
+        public int compareTo(Object o) {
+
+            int row1 = modelIndex;
+            int row2 = ((Row) o).modelIndex;
+
+            for (Iterator it = sortingColumns.iterator(); it.hasNext(); ) {
+                Directive directive  = (Directive) it.next();
+                int       column     = directive.column;
+                Object    o1         = tableModel.getValueAt(row1, column);
+                Object    o2         = tableModel.getValueAt(row2, column);
+                int       comparison = 0;
+
+                // Define null less than everything, except null.
+                if (o1 == null && o2 == null) {
+                    comparison = 0;
+                } else if (o1 == null) {
+                    comparison = -1;
+                } else if (o2 == null) {
+                    comparison = 1;
+                } else {
+                    comparison = getComparator(column).compare(o1, o2);
+                }
+
+                if (comparison != 0) {
+                    return directive.direction == DESCENDING ? -comparison
+                                                             : comparison;
+                }
+            }
+
+            return 0;
+        }
+    }
+
+    private class TableModelHandler implements TableModelListener {
+
+        public void tableChanged(TableModelEvent e) {
+
+            // If we're not sorting by anything, just pass the event along.
+            if (!isSorting()) {
+                clearSortingState();
+                fireTableChanged(e);
+
+                return;
+            }
+
+            // If the table structure has changed, cancel the sorting; the
+            // sorting columns may have been either moved or deleted from
+            // the model.
+            if (e == null || e.getFirstRow() == TableModelEvent.HEADER_ROW) {
+                cancelSorting();
+                fireTableChanged(e);
+
+                return;
+            }
+
+            // We can map a cell event through to the view without widening
+            // when the following conditions apply:
+            //
+            // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,
+            // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
+            // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,
+            // d) a reverse lookup will not trigger a sort (modelToView != null)
+            //
+            // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
+            //
+            // The last check, for (modelToView != null) is to see if modelToView
+            // is already allocated. If we don't do this check; sorting can become
+            // a performance bottleneck for applications where cells
+            // change rapidly in different parts of the table. If cells
+            // change alternately in the sorting column and then outside of
+            // it this class can end up re-sorting on alternate cell updates -
+            // which can be a performance problem for large tables. The last
+            // clause avoids this problem.
+            int column = e.getColumn();
+
+            if (e.getFirstRow() == e.getLastRow()
+                    && column != TableModelEvent.ALL_COLUMNS
+                    && getSortingStatus(column) == NOT_SORTED
+                    && modelToView != null) {
+                int viewIndex = getModelToView()[e.getFirstRow()];
+
+                fireTableChanged(new TableModelEvent(TableSorter.this,
+                                                     viewIndex, viewIndex,
+                                                     column, e.getType()));
+
+                return;
+            }
+
+            // Something has happened to the data that may have invalidated the row order.
+            clearSortingState();
+            fireTableDataChanged();
+
+            return;
+        }
+    }
+
+    private class MouseHandler extends MouseAdapter {
+
+        public void mouseClicked(MouseEvent e) {
+
+            JTableHeader     h           = (JTableHeader) e.getSource();
+            TableColumnModel columnModel = h.getColumnModel();
+            int viewColumn = columnModel.getColumnIndexAtX(e.getX());
+            int column = columnModel.getColumn(viewColumn).getModelIndex();
+
+            if (column != -1) {
+                int status = getSortingStatus(column);
+
+                if (!e.isControlDown()) {
+                    cancelSorting();
+                }
+
+                // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or
+                // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed.
+                status = status + (e.isShiftDown() ? -1
+                                                   : 1);
+                status = (status + 4) % 3 - 1;    // signed mod, returning {-1, 0, 1}
+
+                setSortingStatus(column, status);
+            }
+        }
+    }
+
+    private static class Arrow implements Icon {
+
+        private boolean descending;
+        private int     size;
+        private int     priority;
+
+        public Arrow(boolean descending, int size, int priority) {
+
+            this.descending = descending;
+            this.size       = size;
+            this.priority   = priority;
+        }
+
+        public void paintIcon(Component c, Graphics g, int x, int y) {
+
+            Color color = c == null ? Color.gray
+                                    : c.getBackground();
+
+            // In a compound sort, make each succesive triangle 20%
+            // smaller than the previous one.
+            int dx = (int) (size / 2 * Math.pow(0.8, priority));
+            int dy = descending ? dx
+                                : -dx;
+
+            // Align icon (roughly) with font baseline.
+            y = y + 5 * size / 6 + (descending ? -dy
+                                               : 0);
+
+            int shift = descending ? 1
+                                   : -1;
+
+            g.translate(x, y);
+
+            // Right diagonal.
+            g.setColor(color.darker());
+            g.drawLine(dx / 2, dy, 0, 0);
+            g.drawLine(dx / 2, dy + shift, 0, shift);
+
+            // Left diagonal.
+            g.setColor(color.brighter());
+            g.drawLine(dx / 2, dy, dx, 0);
+            g.drawLine(dx / 2, dy + shift, dx, shift);
+
+            // Horizontal line.
+            if (descending) {
+                g.setColor(color.darker().darker());
+            } else {
+                g.setColor(color.brighter().brighter());
+            }
+
+            g.drawLine(dx, 0, 0, 0);
+            g.setColor(color);
+            g.translate(-x, -y);
+        }
+
+        public int getIconWidth() {
+            return size;
+        }
+
+        public int getIconHeight() {
+            return size;
+        }
+    }
+
+    private class SortableHeaderRenderer implements TableCellRenderer {
+
+        private TableCellRenderer tableCellRenderer;
+
+        public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
+            this.tableCellRenderer = tableCellRenderer;
+        }
+
+        public Component getTableCellRendererComponent(JTable table,
+                Object value, boolean isSelected, boolean hasFocus, int row,
+                int column) {
+
+            Component c =
+                tableCellRenderer.getTableCellRendererComponent(table, value,
+                    isSelected, hasFocus, row, column);
+
+            if (c instanceof JLabel) {
+                JLabel l = (JLabel) c;
+
+                l.setHorizontalTextPosition(JLabel.LEFT);
+
+                int modelColumn = table.convertColumnIndexToModel(column);
+
+                l.setIcon(getHeaderRendererIcon(modelColumn,
+                                                l.getFont().getSize()));
+            }
+
+            return c;
+        }
+    }
+
+    private static class Directive {
+
+        private int column;
+        private int direction;
+
+        public Directive(int column, int direction) {
+            this.column    = column;
+            this.direction = direction;
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/Traceable.java b/src/org/hsqldb/util/Traceable.java
new file mode 100644
index 0000000..eba5097
--- /dev/null
+++ b/src/org/hsqldb/util/Traceable.java
@@ -0,0 +1,45 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+// sqlbob@users 20020407 - patch 1.7.0 - reengineering
+
+/**
+ *
+ * @version 1.7.0
+ */
+interface Traceable {
+
+    boolean TRACE = Boolean.getBoolean("hsqldb.util.trace");
+
+    void trace(String s);
+}
diff --git a/src/org/hsqldb/util/Transfer.java b/src/org/hsqldb/util/Transfer.java
new file mode 100644
index 0000000..bcec452
--- /dev/null
+++ b/src/org/hsqldb/util/Transfer.java
@@ -0,0 +1,1292 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.applet.Applet;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Checkbox;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FileDialog;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.Image;
+import java.awt.ItemSelectable;
+import java.awt.Label;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.Panel;
+import java.awt.SystemColor;
+import java.awt.TextField;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.image.MemoryImageSource;
+
+// fredt@users 20011220 - patch 481239 by xponsard@users - enhancements
+// enhancements to support saving and loading of transfer settings,
+// transfer of blobs, and catalog and schema names in source db
+// changes by fredt to allow saving and loading of transfer settings
+// fredt@users 20020215 - patch 516309 by Nicolas Bazin - enhancements
+// sqlbob@users 20020401 - patch 1.7.0 - reengineering
+// nicolas BAZIN 20020430 - add Catalog selection, correct a bug preventing table
+//    edition, change double quotes to simple quotes for default values of CHAR type
+// lonbinder@users 20030426 - correct bug in prefs load/save
+// fredt@users 20040508 - patch 1.7.2 - bug fixes
+
+/**
+ *  Utility program (or applet) for transferring tables between different
+ *  databases via JDBC. Understands HSQLDB database particularly well.
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+  * @version 1.7.2
+  * @since Hypersonic SQL
+ */
+public class Transfer extends Applet
+implements WindowListener, ActionListener, ItemListener, Traceable {
+
+    Frame            fMain;
+    Image            imgEmpty;
+    DataAccessPoint  sourceDb;
+    DataAccessPoint  targetDb;
+    TransferTable    tCurrent;
+    int              iMaxRows;
+    int              iSelectionStep;
+    Vector           tTable;
+    java.awt.List    lTable;
+    String[]         sSourceSchemas;
+    String           sSourceCatalog, sDestSchema, sDestCatalog;
+    TextField tSourceTable, tDestTable, tDestDropIndex, tDestCreateIndex;
+    TextField        tDestDrop, tDestCreate, tDestDelete, tDestAlter;
+    TextField        tSourceSelect, tDestInsert;
+    Checkbox         cTransfer, cDrop, cCreate, cDelete, cInsert, cAlter;
+    Checkbox         cCreateIndex, cDropIndex;
+    Checkbox         cFKForced, cIdxForced;
+    Button           bStart, bContinue;
+    TextField        tMessage;
+    int              iTransferMode;
+    static boolean   bMustExit;
+    int              CurrentTransfer, CurrentAlter;
+    static final int SELECT_SOURCE_CATALOG = 1;
+    static final int SELECT_SOURCE_SCHEMA  = 2;
+    static final int SELECT_DEST_CATALOG   = 3;
+    static final int SELECT_DEST_SCHEMA    = 4;
+    static final int SELECT_SOURCE_TABLES  = 5;
+    static final int TRFM_TRANSFER         = 1;
+    static final int TRFM_DUMP             = 2;
+    static final int TRFM_RESTORE          = 3;
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param s
+     */
+    public void trace(String s) {
+
+        if ((s != null) &&!s.equals("")) {
+            tMessage.setText(s);
+
+            if (TRACE) {
+                System.out.println(s);
+            }
+        }
+    }
+
+    public void init() {
+
+        Transfer m = new Transfer();
+
+        m._main(null);
+    }
+
+    /**
+     * @throws IllegalArgumentException for the obvious reason
+     */
+    public static void work(String[] arg) {
+
+        Transfer m = new Transfer();
+
+        m._main(arg);
+    }
+
+    /**
+     * Run with --help arg for syntax help.
+     *
+     * @throws IllegalArgumentException for the obvious reason
+     */
+    public static void main(String[] arg) {
+
+        System.getProperties().put("sun.java2d.noddraw", "true");
+
+        bMustExit = true;
+
+        try {
+            work(arg);
+        } catch (IllegalArgumentException iae) {
+            throw new IllegalArgumentException(
+                    "Try:  java "+ Transfer.class.getName() + " --help");
+        }
+    }
+
+    private boolean CatalogToSelect() {
+
+        Vector result = null;
+
+        try {
+            lTable.removeAll();
+
+            if (iSelectionStep == Transfer.SELECT_SOURCE_CATALOG) {
+                result = sourceDb.getCatalog();
+            } else if (iSelectionStep == Transfer.SELECT_DEST_CATALOG) {
+                result = targetDb.getCatalog();
+            } else {
+                exit();
+            }
+
+            if (result.size() > 1) {
+                lTable.setMultipleMode(true);
+
+                if (iSelectionStep == Transfer.SELECT_SOURCE_CATALOG) {
+                    bStart.setLabel("Select Catalog: Source");
+                } else {
+                    bStart.setLabel("Select Catalog: Destination");
+                }
+
+                bStart.invalidate();
+                bStart.setEnabled(true);
+
+                for (Enumeration e =
+                        result.elements(); e.hasMoreElements(); ) {
+                    lTable.add(e.nextElement().toString());
+                }
+
+                lTable.repaint();
+                trace("Select correct Catalog");
+            } else {
+                if (result.size() == 1) {
+                    if (iSelectionStep == Transfer.SELECT_SOURCE_CATALOG) {
+                        sSourceCatalog = (String) result.firstElement();
+                        sSourceSchemas = null;
+                    } else {
+                        sDestCatalog = (String) result.firstElement();
+                        sDestSchema  = null;
+                    }
+                } else {
+                    if (iSelectionStep == Transfer.SELECT_SOURCE_CATALOG) {
+                        sSourceCatalog = null;
+                        sSourceSchemas = null;
+                    } else {
+                        sDestCatalog = null;
+                        sDestSchema  = null;
+                    }
+                }
+
+                if ((iSelectionStep == Transfer.SELECT_DEST_CATALOG)
+                        && (sDestCatalog != null)) {
+                    try {
+                        targetDb.setCatalog(sDestCatalog);
+                    } catch (Exception ex) {
+                        trace("Catalog " + sSourceCatalog
+                              + " could not be selected in the target database");
+
+                        sSourceCatalog = null;
+                    }
+                }
+
+                iSelectionStep++;
+
+                ProcessNextStep();
+
+                return false;
+            }
+        } catch (Exception exp) {
+            lTable.removeAll();
+            trace("Exception reading catalog: " + exp);
+            exp.printStackTrace();
+        }
+
+        return (lTable.getItemCount() > 0);
+    }
+
+    private boolean SchemaToSelect() {
+
+        Vector result = null;
+
+        try {
+            lTable.removeAll();
+
+            if (iSelectionStep == Transfer.SELECT_SOURCE_SCHEMA) {
+                result = sourceDb.getSchemas();
+            } else if (iSelectionStep == Transfer.SELECT_DEST_SCHEMA) {
+                result = targetDb.getSchemas();
+            } else {
+                exit();
+            }
+
+            if (result.size() > 1) {
+                lTable.setMultipleMode(true);
+
+                if (iSelectionStep == Transfer.SELECT_SOURCE_SCHEMA) {
+                    bStart.setLabel("Select Schema: Source");
+                } else {
+                    bStart.setLabel("Select Schema: Destination");
+                }
+
+                bStart.invalidate();
+                bStart.setEnabled(true);
+
+                for (Enumeration e =
+                        result.elements(); e.hasMoreElements(); ) {
+                    lTable.add(e.nextElement().toString());
+                }
+
+                lTable.repaint();
+                trace("Select correct Schema or load Settings file");
+            } else {
+                if (result.size() == 1) {
+                    if (iSelectionStep == Transfer.SELECT_SOURCE_SCHEMA) {
+                        sSourceSchemas    = new String[1];
+                        sSourceSchemas[0] = (String) result.firstElement();
+                    } else {
+                        sDestSchema = (String) result.firstElement();
+                    }
+                } else {
+                    if (iSelectionStep == Transfer.SELECT_SOURCE_SCHEMA) {
+                        sSourceSchemas = null;
+                    } else {
+                        sDestSchema = null;
+                    }
+                }
+
+                if (iTransferMode == TRFM_DUMP) {
+                    iSelectionStep = Transfer.SELECT_SOURCE_TABLES;
+                } else {
+                    iSelectionStep++;
+                }
+
+                ProcessNextStep();
+
+                return false;
+            }
+        } catch (Exception exp) {
+            lTable.removeAll();
+            trace("Exception reading schemas: " + exp);
+            exp.printStackTrace();
+        }
+
+        return (lTable.getItemCount() > 0);
+    }
+
+    static private final String SYNTAX_MSG =
+        "java " + Transfer.class.getName() + " [--help|--dump|--restore]";
+
+    /**
+     * @throws IllegalArgumentException for the obvious reason
+     */
+    void _main(String[] arg) {
+
+        /*
+         ** What function is asked from the transfer tool?
+         */
+        iTransferMode = TRFM_TRANSFER;
+
+        if (arg != null) {
+            if (arg.length != 1) {
+                throw new IllegalArgumentException();
+            }
+            if ((arg[0].toLowerCase().equals("-r"))
+                    || (arg[0].toLowerCase().equals("--restore"))) {
+                iTransferMode = TRFM_RESTORE; } else if ((arg[0].toLowerCase().equals("-d"))
+                       || (arg[0].toLowerCase().equals("--dump"))) {
+                iTransferMode = TRFM_DUMP;
+            } else if ((arg[0].toLowerCase().equals("-h"))
+                       || (arg[0].toLowerCase().equals("--help"))) {
+                System.out.println(Transfer.SYNTAX_MSG);
+                return;
+            } else {
+                throw new IllegalArgumentException();
+            }
+        }
+
+        fMain = new Frame("HSQL Transfer Tool");
+        imgEmpty = createImage(new MemoryImageSource(2, 2, new int[4 * 4], 2,
+                2));
+
+        fMain.setIconImage(imgEmpty);
+        fMain.addWindowListener(this);
+        fMain.setSize(640, 480);
+        fMain.add("Center", this);
+
+        MenuBar  bar    = new MenuBar();
+        String[] extras = {
+            "Insert 10 rows only", "Insert 1000 rows only", "Insert all rows",
+            "-", "Load Settings...", "Save Settings...", "-", "Exit"
+        };
+        Menu menu = new Menu("Options");
+
+        addMenuItems(menu, extras);
+        bar.add(menu);
+        fMain.setMenuBar(bar);
+        initGUI();
+
+        Dimension d    = Toolkit.getDefaultToolkit().getScreenSize();
+        Dimension size = fMain.getSize();
+
+        // (ulrivo): full size on screen with less than 640 width
+        if (d.width >= 640) {
+            fMain.setLocation((d.width - size.width) / 2,
+                              (d.height - size.height) / 2);
+        } else {
+            fMain.setLocation(0, 0);
+            fMain.setSize(d);
+        }
+
+        fMain.setVisible(true);
+
+        CurrentTransfer = CurrentAlter = 0;
+
+        try {
+            if ((iTransferMode == TRFM_DUMP)
+                    || (iTransferMode == TRFM_TRANSFER)) {
+                sourceDb = new TransferDb(
+                    ConnectionDialog.createConnection(
+                        fMain, "Source Database"), this);
+
+                if (!sourceDb.isConnected()) {
+                    exit();
+
+                    return;
+                }
+            } else {
+                FileDialog f = new FileDialog(fMain, "Restore FileName",
+                                              FileDialog.LOAD);
+
+                f.show();
+
+                String sFileName = f.getFile();
+                String Path      = f.getDirectory();
+
+                if ((sFileName == null) || (sFileName.equals(""))) {
+                    exit();
+
+                    return;
+                } else {
+                    sourceDb = new TransferSQLText(Path + sFileName, this);
+                }
+            }
+
+            if ((iTransferMode == TRFM_RESTORE)
+                    || (iTransferMode == TRFM_TRANSFER)) {
+                targetDb = new TransferDb(
+                    ConnectionDialog.createConnection(
+                        fMain, "Target Database"), this);
+
+                if (!targetDb.isConnected()) {
+                    exit();
+
+                    return;
+                }
+            } else {
+                FileDialog f = new FileDialog(fMain, "Dump FileName",
+                                              FileDialog.SAVE);
+
+                f.show();
+
+                String sFileName = f.getFile();
+                String Path      = f.getDirectory();
+
+                if ((sFileName == null) || (sFileName.equals(""))) {
+                    exit();
+
+                    return;
+                } else {
+                    targetDb = new TransferSQLText(Path + sFileName, this);
+                }
+            }
+        } catch (Exception e) {
+            exit();
+            e.printStackTrace();
+
+            return;
+        }
+
+        if ((iTransferMode == TRFM_DUMP)
+                || (iTransferMode == TRFM_TRANSFER)) {
+            iSelectionStep = SELECT_SOURCE_CATALOG;
+            sSourceCatalog = null;
+        } else {
+            iSelectionStep = SELECT_DEST_CATALOG;
+            sDestCatalog   = null;
+        }
+
+        ProcessNextStep();
+        fMain.show();
+
+        return;
+    }
+
+    private void RefreshMainDisplay() {
+
+        lTable.removeAll();
+        lTable.repaint();
+
+        try {
+            tTable = sourceDb.getTables(sSourceCatalog, sSourceSchemas);
+
+            for (int i = 0; i < tTable.size(); i++) {
+                TransferTable t = (TransferTable) tTable.elementAt(i);
+
+                t.setDest(sDestSchema, targetDb);
+                t.extractTableStructure(sourceDb, targetDb);
+                lTable.add(t.Stmts.sSourceTable);
+                lTable.select(i);
+                displayTable(t);
+            }
+
+            bStart.setEnabled(true);
+
+            if (iTransferMode == TRFM_TRANSFER) {
+                trace("Edit definitions and press [Start Transfer]");
+            } else if (iTransferMode == TRFM_DUMP) {
+                trace("Edit definitions and press [Start Dump]");
+            }
+        } catch (Exception e) {
+            trace("Exception reading source tables: " + e);
+            e.printStackTrace();
+        }
+
+        fMain.show();
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param f
+     * @param m
+     */
+    private void addMenuItems(Menu f, String[] m) {
+
+        for (int i = 0; i < m.length; i++) {
+            if (m[i].equals("-")) {
+                f.addSeparator();
+            } else {
+                MenuItem item = new MenuItem(m[i]);
+
+                item.addActionListener(this);
+                f.add(item);
+            }
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+    public void itemStateChanged(ItemEvent e) {
+
+        ItemSelectable item = e.getItemSelectable();
+
+        if (item == lTable) {
+            if (iSelectionStep == SELECT_SOURCE_TABLES) {
+                String table    = lTable.getSelectedItem();
+                int    selected = ((Integer) e.getItem()).intValue();
+
+                for (int i = 0; i < tTable.size(); i++) {
+                    TransferTable t = (TransferTable) tTable.elementAt(i);
+
+                    if (t == null) {
+                        continue;
+                    }
+
+                    if (i == selected) {
+                        saveTable();
+                        displayTable(t);
+                        updateEnabled(true);
+                    }
+                }
+            }
+        } else {
+
+            // it must be a checkbox
+            saveTable();
+            updateEnabled(true);
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    private void saveTable() {
+
+        if (tCurrent == null) {
+            return;
+        }
+
+        TransferTable t = tCurrent;
+
+        t.Stmts.sSourceTable     = tSourceTable.getText();
+        t.Stmts.sDestTable       = tDestTable.getText();
+        t.Stmts.sDestDrop        = tDestDrop.getText();
+        t.Stmts.sDestCreateIndex = tDestCreateIndex.getText();
+        t.Stmts.sDestDropIndex   = tDestDropIndex.getText();
+        t.Stmts.sDestCreate      = tDestCreate.getText();
+        t.Stmts.sDestDelete      = tDestDelete.getText();
+        t.Stmts.sSourceSelect    = tSourceSelect.getText();
+        t.Stmts.sDestInsert      = tDestInsert.getText();
+        t.Stmts.sDestAlter       = tDestAlter.getText();
+
+        //
+        t.Stmts.bTransfer    = cTransfer.getState();
+        t.Stmts.bDrop        = cDrop.getState();
+        t.Stmts.bCreate      = cCreate.getState();
+        t.Stmts.bDelete      = cDelete.getState();
+        t.Stmts.bInsert      = cInsert.getState();
+        t.Stmts.bAlter       = cAlter.getState();
+        t.Stmts.bCreateIndex = cCreateIndex.getState();
+        t.Stmts.bDropIndex   = cDropIndex.getState();
+
+        if (!t.Stmts.bTransfer) {
+            t.Stmts.bInsert = false;
+
+            cInsert.setState(false);
+        }
+
+        boolean reparsetable = ((t.Stmts.bFKForced != cFKForced.getState())
+                                || (t.Stmts.bIdxForced
+                                    != cIdxForced.getState()));
+
+        t.Stmts.bFKForced  = cFKForced.getState();
+        t.Stmts.bIdxForced = cIdxForced.getState();
+
+        if (reparsetable) {
+            try {
+                sourceDb.getTableStructure(t, targetDb);
+            } catch (Exception e) {
+                trace("Exception reading source tables: " + e);
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param t
+     */
+    private void displayTable(TransferTable t) {
+
+        tCurrent = t;
+
+        if (t == null) {
+            return;
+        }
+
+        tSourceTable.setText(t.Stmts.sSourceTable);
+        tDestTable.setText(t.Stmts.sDestTable);
+        tDestDrop.setText(t.Stmts.sDestDrop);
+        tDestCreateIndex.setText(t.Stmts.sDestCreateIndex);
+        tDestDropIndex.setText(t.Stmts.sDestDropIndex);
+        tDestCreate.setText(t.Stmts.sDestCreate);
+        tDestDelete.setText(t.Stmts.sDestDelete);
+        tSourceSelect.setText(t.Stmts.sSourceSelect);
+        tDestInsert.setText(t.Stmts.sDestInsert);
+        tDestAlter.setText(t.Stmts.sDestAlter);
+        cTransfer.setState(t.Stmts.bTransfer);
+        cDrop.setState(t.Stmts.bDrop);
+        cCreate.setState(t.Stmts.bCreate);
+        cDropIndex.setState(t.Stmts.bDropIndex);
+        cCreateIndex.setState(t.Stmts.bCreateIndex);
+        cDelete.setState(t.Stmts.bDelete);
+        cInsert.setState(t.Stmts.bInsert);
+        cAlter.setState(t.Stmts.bAlter);
+        cFKForced.setState(t.Stmts.bFKForced);
+        cIdxForced.setState(t.Stmts.bIdxForced);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param and
+     */
+    private void updateEnabled(boolean and) {
+
+        boolean b = cTransfer.getState();
+
+        tDestTable.setEnabled(and && b);
+        tDestDrop.setEnabled(and && b && cDrop.getState());
+        tDestCreate.setEnabled(and && b && cCreate.getState());
+        tDestDelete.setEnabled(and && b && cDelete.getState());
+        tDestCreateIndex.setEnabled(and && b && cCreateIndex.getState());
+        tDestDropIndex.setEnabled(and && b && cDropIndex.getState());
+        tSourceSelect.setEnabled(and && b);
+        tDestInsert.setEnabled(and && b && cInsert.getState());
+        tDestAlter.setEnabled(and && b && cAlter.getState());
+        cDrop.setEnabled(and && b);
+        cCreate.setEnabled(and && b);
+        cDelete.setEnabled(and && b);
+        cCreateIndex.setEnabled(and && b);
+        cDropIndex.setEnabled(and && b);
+        cInsert.setEnabled(and && b);
+        cAlter.setEnabled(and && b);
+        cFKForced.setEnabled(cAlter.getState());
+        cIdxForced.setEnabled(cCreateIndex.getState());
+        bStart.setEnabled(and);
+
+        if (iTransferMode == TRFM_TRANSFER) {
+            bContinue.setEnabled(and);
+        }
+    }
+
+    /**
+     * Method ProcessNextStep
+     */
+    private void ProcessNextStep() {
+
+        switch (iSelectionStep) {
+
+            case SELECT_SOURCE_CATALOG :
+            case SELECT_DEST_CATALOG :
+                if (CatalogToSelect()) {
+                    fMain.show();
+
+                    return;
+                }
+                break;
+
+            case SELECT_DEST_SCHEMA :
+            case SELECT_SOURCE_SCHEMA :
+                if (SchemaToSelect()) {
+                    fMain.show();
+
+                    return;
+                }
+                break;
+
+            case SELECT_SOURCE_TABLES :
+                if (iTransferMode == TRFM_TRANSFER) {
+                    bStart.setLabel("Start Transfer");
+                } else if (iTransferMode == TRFM_DUMP) {
+                    bStart.setLabel("Start Dump");
+                } else if (iTransferMode == TRFM_RESTORE) {
+                    bStart.setLabel("Start Restore");
+                }
+
+                bStart.invalidate();
+                bStart.setEnabled(false);
+                lTable.setMultipleMode(false);
+                RefreshMainDisplay();
+                break;
+
+            default :
+                break;
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param ev
+     */
+    public void actionPerformed(ActionEvent ev) {
+
+        if (ev.getSource() instanceof TextField) {
+            saveTable();
+
+            return;
+        }
+
+        String   s = ev.getActionCommand();
+        MenuItem i = new MenuItem();
+
+        if (s == null) {
+            if (ev.getSource() instanceof MenuItem) {
+                i = (MenuItem) ev.getSource();
+                s = i.getLabel();
+            }
+        }
+
+        if (s == null) {}
+
+        if (s.equals("Start Transfer") || s.equals("ReStart Transfer")) {
+            bStart.setLabel("ReStart Transfer");
+            bStart.invalidate();
+
+            CurrentTransfer = 0;
+            CurrentAlter    = 0;
+
+            transfer();
+        } else if (s.equals("Continue Transfer")) {
+            transfer();
+        } else if (s.equals("Start Dump") || s.equals("Start Restore")) {
+            CurrentTransfer = 0;
+            CurrentAlter    = 0;
+
+            transfer();
+        } else if (s.equals("Quit")) {
+            exit();
+        } else if (s.indexOf("Select Schema") >= 0) {
+            String[] selection = lTable.getSelectedItems();
+
+            if ((selection == null) || (selection.length == 0)) {
+                return;
+            }
+
+            if (iSelectionStep == Transfer.SELECT_SOURCE_SCHEMA) {
+                sSourceSchemas = selection;
+            } else {
+                sDestSchema = selection[0];
+            }
+
+            if (iTransferMode == TRFM_DUMP) {
+                iSelectionStep = Transfer.SELECT_SOURCE_TABLES;
+            } else {
+                iSelectionStep++;
+            }
+
+            ProcessNextStep();
+        } else if (s.indexOf("Select Catalog") >= 0) {
+            String selection = lTable.getSelectedItem();
+
+            if ((selection == null) || (selection.equals(""))) {
+                return;
+            }
+
+            if (iSelectionStep == Transfer.SELECT_SOURCE_CATALOG) {
+                sSourceCatalog = selection;
+                sSourceSchemas = null;
+            } else {
+                sDestCatalog = selection;
+                sDestSchema  = null;
+
+                try {
+                    targetDb.setCatalog(sDestCatalog);
+                } catch (Exception ex) {
+                    trace("Catalog " + sDestCatalog
+                          + " could not be selected in the target database");
+
+                    sDestCatalog = null;
+                }
+            }
+
+            iSelectionStep++;
+
+            ProcessNextStep();
+        } else if (s.equals("Insert 10 rows only")) {
+            iMaxRows = 10;
+        } else if (s.equals("Insert 1000 rows only")) {
+            iMaxRows = 1000;
+        } else if (s.equals("Insert all rows")) {
+            iMaxRows = 0;
+        } else if (s.equals("Load Settings...")) {
+            FileDialog f = new FileDialog(fMain, "Load Settings",
+                                          FileDialog.LOAD);
+
+            f.show();
+
+            String file = f.getDirectory() + f.getFile();
+
+            if (file != null) {
+                LoadPrefs(file);
+                displayTable(tCurrent);
+            }
+        } else if (s.equals("Save Settings...")) {
+            FileDialog f = new FileDialog(fMain, "Save Settings",
+                                          FileDialog.SAVE);
+
+            f.show();
+
+            String file = f.getDirectory() + f.getFile();
+
+            if (file != null) {
+                SavePrefs(file);
+            }
+        } else if (s.equals("Exit")) {
+            windowClosing(null);
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+    public void windowActivated(WindowEvent e) {}
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+    public void windowDeactivated(WindowEvent e) {}
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+    public void windowClosed(WindowEvent e) {}
+
+    private void cleanup() {
+
+        try {
+            if (sourceDb != null) {
+                sourceDb.close();
+            }
+
+            if (targetDb != null) {
+                targetDb.close();
+            }
+        } catch (Exception e) {}
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param ev
+     */
+    public void windowClosing(WindowEvent ev) {
+
+        fMain.dispose();
+
+        if (bMustExit) {
+            System.exit(0);
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+    public void windowDeiconified(WindowEvent e) {}
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+    public void windowIconified(WindowEvent e) {}
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+    public void windowOpened(WindowEvent e) {}
+
+    /**
+     * Method declaration
+     *
+     */
+    private void initGUI() {
+
+        Font fFont = new Font("Dialog", Font.PLAIN, 12);
+
+        setLayout(new BorderLayout());
+
+        Panel p = new Panel();
+
+        p.setBackground(SystemColor.control);
+        p.setLayout(new GridLayout(16, 1));
+
+        tSourceTable = new TextField();
+
+        tSourceTable.setEnabled(false);
+
+        tDestTable = new TextField();
+
+        tDestTable.addActionListener(this);
+
+        tDestDrop = new TextField();
+
+        tDestDrop.addActionListener(this);
+
+        tDestCreate = new TextField();
+
+        tDestCreate.addActionListener(this);
+
+        tDestDelete = new TextField();
+
+        tDestDelete.addActionListener(this);
+
+        tDestCreateIndex = new TextField();
+
+        tDestCreateIndex.addActionListener(this);
+
+        tDestDropIndex = new TextField();
+
+        tDestDropIndex.addActionListener(this);
+
+        tSourceSelect = new TextField();
+
+        tSourceSelect.addActionListener(this);
+
+        tDestInsert = new TextField();
+
+        tDestInsert.addActionListener(this);
+
+        tDestAlter = new TextField();
+
+        tDestAlter.addActionListener(this);
+
+        cTransfer = new Checkbox("Transfer to destination table", true);
+
+        cTransfer.addItemListener(this);
+
+        cDrop = new Checkbox("Drop destination table (ignore error)", true);
+
+        cDrop.addItemListener(this);
+
+        cCreate = new Checkbox("Create destination table", true);
+
+        cCreate.addItemListener(this);
+
+        cDropIndex = new Checkbox("Drop destination index (ignore error)",
+                                  true);
+
+        cDropIndex.addItemListener(this);
+
+        cIdxForced = new Checkbox("force Idx_ prefix for indexes names",
+                                  false);
+
+        cIdxForced.addItemListener(this);
+
+        cCreateIndex = new Checkbox("Create destination index", true);
+
+        cCreateIndex.addItemListener(this);
+
+        cDelete = new Checkbox("Delete rows in destination table", true);
+
+        cDelete.addItemListener(this);
+
+        cInsert = new Checkbox("Insert into destination", true);
+
+        cInsert.addItemListener(this);
+
+        cFKForced = new Checkbox("force FK_ prefix for foreign key names",
+                                 false);
+
+        cFKForced.addItemListener(this);
+
+        cAlter = new Checkbox("Alter destination table", true);
+
+        cAlter.addItemListener(this);
+        p.add(createLabel("Source table"));
+        p.add(tSourceTable);
+        p.add(cTransfer);
+        p.add(tDestTable);
+        p.add(cDrop);
+        p.add(tDestDrop);
+        p.add(cCreate);
+        p.add(tDestCreate);
+        p.add(cDropIndex);
+        p.add(tDestDropIndex);
+        p.add(cCreateIndex);
+        p.add(tDestCreateIndex);
+        p.add(cDelete);
+        p.add(tDestDelete);
+        p.add(cAlter);
+        p.add(tDestAlter);
+        p.add(createLabel("Select source records"));
+        p.add(tSourceSelect);
+        p.add(cInsert);
+        p.add(tDestInsert);
+        p.add(createLabel(""));
+        p.add(createLabel(""));
+        p.add(cIdxForced);
+        p.add(cFKForced);
+        p.add(createLabel(""));
+        p.add(createLabel(""));
+
+        if (iTransferMode == TRFM_TRANSFER) {
+            bStart    = new Button("Start Transfer");
+            bContinue = new Button("Continue Transfer");
+
+            bContinue.setEnabled(false);
+        } else if (iTransferMode == Transfer.TRFM_DUMP) {
+            bStart = new Button("Start Dump");
+        } else if (iTransferMode == Transfer.TRFM_RESTORE) {
+            bStart = new Button("Start Restore");
+        }
+
+        bStart.addActionListener(this);
+        p.add(bStart);
+
+        if (iTransferMode == TRFM_TRANSFER) {
+            bContinue.addActionListener(this);
+            p.add(bContinue);
+        }
+
+        bStart.setEnabled(false);
+        fMain.add("Center", createBorderPanel(p));
+
+        lTable = new java.awt.List(10);
+
+        lTable.addItemListener(this);
+        fMain.add("West", createBorderPanel(lTable));
+
+        tMessage = new TextField();
+
+        Panel pMessage = createBorderPanel(tMessage);
+
+        fMain.add("South", pMessage);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param center
+     */
+    private Panel createBorderPanel(Component center) {
+
+        Panel p = new Panel();
+
+        p.setBackground(SystemColor.control);
+        p.setLayout(new BorderLayout());
+        p.add("Center", center);
+        p.add("South", createLabel(""));
+        p.add("East", createLabel(""));
+        p.add("West", createLabel(""));
+        p.setBackground(SystemColor.control);
+
+        return p;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param s
+     */
+    private Label createLabel(String s) {
+
+        Label l = new Label(s);
+
+        l.setBackground(SystemColor.control);
+
+        return l;
+    }
+
+    private void SavePrefs(String f) {
+        saveTable();
+        TransferCommon.savePrefs(f, sourceDb, targetDb, this, tTable);
+    }
+
+    private void LoadPrefs(String f) {
+
+        TransferTable t;
+
+        trace("Parsing Settings file");
+        bStart.setEnabled(false);
+
+        if (iTransferMode == TRFM_TRANSFER) {
+            bContinue.setEnabled(false);
+        }
+
+        tTable = TransferCommon.loadPrefs(f, sourceDb, targetDb, this);
+        iSelectionStep = SELECT_SOURCE_TABLES;
+
+        lTable.removeAll();
+
+        for (int i = 0; i < tTable.size(); i++) {
+            t = (TransferTable) tTable.elementAt(i);
+
+            lTable.add(t.Stmts.sSourceTable);
+        }
+
+        t = (TransferTable) tTable.elementAt(0);
+
+        displayTable(t);
+        lTable.select(0);
+        updateEnabled(true);
+        lTable.invalidate();
+
+        if (iTransferMode == TRFM_TRANSFER) {
+            bStart.setLabel("Start Transfer");
+            trace("Edit definitions and press [Start Transfer]");
+        } else if (iTransferMode == TRFM_DUMP) {
+            bStart.setLabel("Start Dump");
+            trace("Edit definitions and press [Start Dump]");
+        } else if (iTransferMode == TRFM_RESTORE) {
+            bStart.setLabel("Start Restore");
+            trace("Edit definitions and press [Start Restore]");
+        }
+
+        bStart.invalidate();
+
+        if (iTransferMode == TRFM_TRANSFER) {
+            bContinue.setEnabled(false);
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    private void transfer() {
+
+        saveTable();
+        updateEnabled(false);
+        trace("Start Transfer");
+
+        int           TransferIndex = CurrentTransfer;
+        int           AlterIndex    = CurrentAlter;
+        TransferTable t             = null;
+        long          startTime, stopTime;
+
+        startTime = System.currentTimeMillis();
+
+        try {
+            for (int i = TransferIndex; i < tTable.size(); i++) {
+                CurrentTransfer = i;
+                t               = (TransferTable) tTable.elementAt(i);
+
+                lTable.select(i);
+                displayTable(t);
+                t.transferStructure();
+                t.transferData(iMaxRows);
+            }
+
+            for (int i = AlterIndex; i < tTable.size(); i++) {
+                CurrentAlter = i;
+                t            = (TransferTable) tTable.elementAt(i);
+
+                lTable.select(i);
+                displayTable(t);
+                t.transferAlter();
+            }
+
+            stopTime = System.currentTimeMillis();
+
+            trace("Transfer finished successfully in: "
+                  + (stopTime - startTime) / 1000.00 + " sec");
+
+            if (iTransferMode == TRFM_TRANSFER) {
+                bContinue.setLabel("Quit");
+                bContinue.setEnabled(true);
+                bContinue.invalidate();
+            } else {
+                bStart.setLabel("Quit");
+                bStart.setEnabled(true);
+                bStart.invalidate();
+            }
+        } catch (Exception e) {
+            String last = tMessage.getText();
+
+            trace("Transfer stopped - " + last + " /  / Error: "
+                  + e.getMessage());
+            e.printStackTrace();
+        }
+
+        if (iTransferMode == TRFM_TRANSFER) {
+            bContinue.setEnabled((CurrentAlter < tTable.size()));
+        }
+
+        updateEnabled(true);
+        System.gc();
+    }
+
+    protected void exit() {
+
+        cleanup();
+        fMain.dispose();
+
+        if (bMustExit) {
+            System.exit(0);
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/TransferCommon.java b/src/org/hsqldb/util/TransferCommon.java
new file mode 100644
index 0000000..b7960a1
--- /dev/null
+++ b/src/org/hsqldb/util/TransferCommon.java
@@ -0,0 +1,163 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Vector;
+
+// sqlbob@users 20020407 - patch 1.7.0 - reengineering
+
+/**
+ * Common code in Swing and AWT versions of Tranfer
+ * New class based on Hypersonic code
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.7.2
+ * @since Hypersonic SQL
+ */
+class TransferCommon {
+
+    static void savePrefs(String f, DataAccessPoint sourceDb,
+                          DataAccessPoint targetDb, Traceable tracer,
+                          Vector tTable) {
+
+        TransferTable t;
+
+        try {
+            FileOutputStream   fos = new FileOutputStream(f);
+            ObjectOutputStream oos = new ObjectOutputStream(fos);
+
+            for (int i = 0; i < tTable.size(); i++) {
+                t          = (TransferTable) tTable.elementAt(i);
+                t.sourceDb = null;
+                t.destDb   = null;
+                t.tracer   = null;
+            }
+
+            oos.writeObject(tTable);
+
+            for (int i = 0; i < tTable.size(); i++) {
+                t          = (TransferTable) tTable.elementAt(i);
+                t.tracer   = tracer;
+                t.sourceDb = (TransferDb) sourceDb;
+                t.destDb   = targetDb;
+            }
+        } catch (IOException e) {
+            System.out.println("pb in SavePrefs : " + e.toString());
+            e.printStackTrace();
+        }
+    }
+
+    static Vector loadPrefs(String f, DataAccessPoint sourceDb,
+                            DataAccessPoint targetDb, Traceable tracer) {
+
+        TransferTable     t;
+        Vector            tTable = null;
+        ObjectInputStream ois    = null;
+
+        try {
+            FileInputStream fis = new FileInputStream(f);
+
+            ois    = new ObjectInputStream(fis);
+            tTable = (Vector) ois.readObject();
+
+            for (int i = 0; i < tTable.size(); i++) {
+                t          = (TransferTable) tTable.elementAt(i);
+                t.tracer   = tracer;
+                t.sourceDb = (TransferDb) sourceDb;
+                t.destDb   = targetDb;
+            }
+        } catch (ClassNotFoundException e) {
+            System.out.println("class not found pb in LoadPrefs : "
+                               + e.toString());
+
+            tTable = new Vector();
+        } catch (IOException e) {
+            System.out.println("IO pb in LoadPrefs : actionPerformed"
+                               + e.toString());
+
+            tTable = new Vector();
+        } finally {
+            if (ois != null) {
+                try {
+                    ois.close();
+                } catch (IOException ioe) {}
+            }
+        }
+
+        return (tTable);
+    }
+
+    private TransferCommon() {}
+}
diff --git a/src/org/hsqldb/util/TransferDb.java b/src/org/hsqldb/util/TransferDb.java
new file mode 100644
index 0000000..3a1584b
--- /dev/null
+++ b/src/org/hsqldb/util/TransferDb.java
@@ -0,0 +1,945 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.Vector;
+
+// fredt@users 20020215 - patch 516309 by Nicolas Bazin - enhancements
+// sqlbob@users 20020401 - patch 1.7.0 - reengineering
+// nicolas BAZIN 20020430 - add support of Catalog and mckoi db helper
+// Stephan Frind 20040508 - speed improvements
+
+/**
+ * Conversions between different databases
+ *
+ * @version 1.7.0
+ */
+class TransferDb extends DataAccessPoint {
+
+    Connection          conn;
+    DatabaseMetaData    meta;
+    protected Statement srcStatement = null;
+
+    TransferDb(Connection c, Traceable t) throws DataAccessPointException {
+
+        super(t);
+
+        conn = c;
+
+        if (c != null) {
+            String productLowerName;
+
+            try {
+                meta              = c.getMetaData();
+                databaseToConvert = c.getCatalog();
+                productLowerName  = meta.getDatabaseProductName();
+
+                if (productLowerName == null) {
+                    productLowerName = "";
+                } else {
+                    productLowerName = productLowerName.toLowerCase();
+                }
+
+                helper = HelperFactory.getHelper(productLowerName);
+
+                helper.set(this, t, meta.getIdentifierQuoteString());
+            } catch (SQLException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+    }
+
+    boolean isConnected() {
+        return (conn != null);
+    }
+
+    boolean getAutoCommit() throws DataAccessPointException {
+
+        boolean result = false;
+
+        try {
+            result = conn.getAutoCommit();
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        return result;
+    }
+
+    void commit() throws DataAccessPointException {
+
+        if (srcStatement != null) {
+            try {
+                srcStatement.close();
+            } catch (SQLException e) {}
+
+            srcStatement = null;
+        }
+
+        try {
+            conn.commit();
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+    }
+
+    void rollback() throws DataAccessPointException {
+
+        if (srcStatement != null) {
+            try {
+                srcStatement.close();
+            } catch (SQLException e) {}
+
+            srcStatement = null;
+        }
+
+        try {
+            conn.rollback();
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+    }
+
+    void setAutoCommit(boolean flag) throws DataAccessPointException {
+
+        try {
+            conn.setAutoCommit(flag);
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+    }
+
+    boolean execute(String statement) throws DataAccessPointException {
+
+        boolean   result = false;
+        Statement stmt   = null;
+
+        try {
+            stmt   = conn.createStatement();
+            result = stmt.execute(statement);
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        } finally {
+            if (stmt != null) {
+                try {
+                    stmt.close();
+                } catch (SQLException e) {}
+            }
+        }
+
+        return result;
+    }
+
+    TransferResultSet getData(String statement)
+    throws DataAccessPointException {
+
+        ResultSet rsData = null;
+
+        try {
+            if (srcStatement != null) {
+                srcStatement.close();
+            }
+
+            srcStatement = conn.createStatement();
+            rsData       = srcStatement.executeQuery(statement);
+        } catch (SQLException e) {
+            try {
+                srcStatement.close();
+            } catch (Exception e1) {}
+
+            srcStatement = null;
+            rsData       = null;
+
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        return new TransferResultSet(rsData);
+    }
+
+    void putData(String statement, TransferResultSet r,
+                 int iMaxRows) throws DataAccessPointException {
+
+        if ((statement == null) || statement.equals("") || (r == null)) {
+            return;
+        }
+
+        PreparedStatement destPrep = null;
+
+        try {
+            destPrep = conn.prepareStatement(statement);
+
+            int   i = 0;
+            int   tmpLength;
+            int   len      = r.getColumnCount();
+            int[] tmpTypes = null;
+
+            while (r.next()) {
+                if (tmpTypes == null) {
+                    tmpTypes = new int[len + 1];
+
+                    for (int j = 1; j <= len; j++) {
+                        tmpTypes[j] = r.getColumnType(j);
+                    }
+                }
+
+                transferRow(r, destPrep, len, tmpTypes);
+
+                if (iMaxRows != 0 && i == iMaxRows) {
+                    break;
+                }
+
+                i++;
+
+                if (iMaxRows != 0 || i % 100 == 0) {
+                    tracer.trace("Transfered " + i + " rows");
+                }
+            }
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        } finally {
+            if (destPrep != null) {
+                try {
+                    destPrep.close();
+                } catch (SQLException e) {}
+            }
+        }
+    }
+
+/*
+    private void transferRow(TransferResultSet r,
+                             PreparedStatement p)
+                             throws DataAccessPointException, SQLException {
+        // TODO
+        // what is this never used variable for?
+        // looks like missing debug flags because constructing these strings consumes a lot
+        // of time
+        String sLast = "";
+
+        if (p != null) {
+            p.clearParameters();
+        }
+
+        int len = r.getColumnCount();
+
+        for (int i = 0; i < len; i++) {
+            int t = r.getColumnType(i + 1);
+
+            sLast = "column=" + r.getColumnName(i + 1) + " datatype="
+                    + (String) helper.getSupportedTypes().get(new Integer(t));
+
+            Object o = r.getObject(i + 1);
+
+            if (o == null) {
+                if (p != null) {
+                    p.setNull(i + 1, t);
+                }
+
+                sLast += " value=<null>";
+            } else {
+                o = helper.convertColumnValue(o, i + 1, t);
+
+                p.setObject(i + 1, o);
+
+                sLast += " value=\'" + o.toString() + "\'";
+            }
+        }
+
+        if (p != null) {
+            p.execute();
+        }
+
+        sLast = "";
+    }
+*/
+    Vector getSchemas() throws DataAccessPointException {
+
+        Vector    ret    = new Vector();
+        ResultSet result = null;
+
+        try {
+            result = meta.getSchemas();
+        } catch (SQLException e) {
+            result = null;
+        }
+
+        try {
+            if (result != null) {
+                while (result.next()) {
+                    ret.addElement(result.getString(1));
+                }
+
+                result.close();
+            }
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        return (ret);
+    }
+
+    Vector getCatalog() throws DataAccessPointException {
+
+        Vector    ret    = new Vector();
+        ResultSet result = null;
+
+        if (databaseToConvert != null && databaseToConvert.length() > 0) {
+            ret.addElement(databaseToConvert);
+
+            return (ret);
+        }
+
+        try {
+            result = meta.getCatalogs();
+        } catch (SQLException e) {
+            result = null;
+        }
+
+        try {
+            if (result != null) {
+                while (result.next()) {
+                    ret.addElement(result.getString(1));
+                }
+
+                result.close();
+            }
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        return (ret);
+    }
+
+    void setCatalog(String sCatalog) throws DataAccessPointException {
+
+        if (sCatalog != null && sCatalog.length() > 0) {
+            try {
+                conn.setCatalog(sCatalog);
+            } catch (SQLException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+    }
+
+    Vector getTables(String sCatalog,
+                     String[] sSchemas) throws DataAccessPointException {
+
+        Vector    tTable = new Vector();
+        ResultSet result = null;
+
+        tracer.trace("Reading source tables");
+
+        int nbloops = 1;
+
+        if (sSchemas != null) {
+            nbloops = sSchemas.length;
+        }
+
+        try {
+
+// variations return null or emtpy result sets with informix JDBC driver 2.2
+            for (int SchemaIdx = 0; SchemaIdx < nbloops; SchemaIdx++) {
+                if (sSchemas != null && sSchemas[SchemaIdx] != null) {
+                    result = meta.getTables(sCatalog, sSchemas[SchemaIdx],
+                                            null, null);
+                } else {
+                    try {
+                        result = meta.getTables(sCatalog, "", null, null);
+                    } catch (SQLException e) {
+                        result = meta.getTables(sCatalog, null, null, null);
+                    }
+                }
+
+                while (result.next()) {
+                    String name   = result.getString(3);
+                    String type   = result.getString(4);
+                    String schema = "";
+
+                    if (sSchemas != null && sSchemas[SchemaIdx] != null) {
+                        schema = sSchemas[SchemaIdx];
+                    }
+
+                    /*
+                    ** we ignore the following table types:
+                    **    "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY"
+                    **    "ALIAS", "SYNONYM"
+                    */
+                    if ((type.compareTo("TABLE") == 0)
+                            || (type.compareTo("VIEW") == 0)) {
+                        TransferTable t = new TransferTable(this, name,
+                                                            schema, type,
+                                                            tracer);
+
+                        tTable.addElement(t);
+                    } else {
+                        tracer.trace("Found table of type :" + type
+                                     + " - this type is ignored");
+                    }
+                }
+            }
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        } finally {
+            if (result != null) {
+                try {
+                    result.close();
+                } catch (SQLException e) {}
+            }
+        }
+
+        return (tTable);
+    }
+
+    void getTableStructure(TransferTable TTable,
+                           DataAccessPoint Dest)
+                           throws DataAccessPointException {
+
+        String create = "CREATE " + TTable.Stmts.sType + " "
+                        + Dest.helper.formatName(TTable.Stmts.sDestTable);
+        String    insert         = "";
+        ResultSet ImportedKeys   = null;
+        boolean   importedkeys   = false;
+        String    alterCreate    = new String("");
+        String    alterDrop      = new String("");
+        String    ConstraintName = new String("");
+        String    RefTableName   = new String("");
+        String    foreignKeyName = new String("");
+        String    columnName     = new String("");
+
+        Dest.helper.setSchema(TTable.Stmts.sSchema);
+
+        TTable.Stmts.sDestDrop =
+            "DROP " + TTable.Stmts.sType + " "
+            + Dest.helper.formatName(TTable.Stmts.sDestTable) + ";";
+
+        if (TTable.Stmts.sType.compareTo("TABLE") == 0) {
+            TTable.Stmts.sDestDelete =
+                "DELETE FROM "
+                + Dest.helper.formatName(TTable.Stmts.sDestTable) + ";";
+            create += "(";
+        } else if (TTable.Stmts.sType.compareTo("VIEW") == 0) {
+            TTable.Stmts.bDelete     = false;
+            TTable.Stmts.sDestDelete = "";
+            create                   += " AS SELECT ";
+        }
+
+        if (TTable.Stmts.sType.compareTo("TABLE") == 0) {
+            insert = "INSERT INTO "
+                     + Dest.helper.formatName(TTable.Stmts.sDestTable)
+                     + " VALUES(";
+        } else if (TTable.Stmts.sType.compareTo("VIEW") == 0) {
+            TTable.Stmts.bInsert = false;
+            insert               = "";
+        }
+
+        if (TTable.Stmts.sType.compareTo("VIEW") == 0) {
+            /*
+            ** Don't know how to retrieve the underlying select so we leave here.
+            ** The user will have to edit the rest of the create statement.
+            */
+            TTable.Stmts.bTransfer    = false;
+            TTable.Stmts.bCreate      = true;
+            TTable.Stmts.bDelete      = false;
+            TTable.Stmts.bDrop        = true;
+            TTable.Stmts.bCreateIndex = false;
+            TTable.Stmts.bDropIndex   = false;
+            TTable.Stmts.bInsert      = false;
+            TTable.Stmts.bAlter       = false;
+
+            return;
+        }
+
+        ImportedKeys = null;
+
+        try {
+            ImportedKeys =
+                meta.getImportedKeys(TTable.Stmts.sDatabaseToConvert,
+                                     TTable.Stmts.sSchema,
+                                     TTable.Stmts.sSourceTable);
+        } catch (SQLException e) {
+            ImportedKeys = null;
+        }
+
+        try {
+            if (ImportedKeys != null) {
+                while (ImportedKeys.next()) {
+                    importedkeys = true;
+
+                    if (!ImportedKeys.getString(12).equals(ConstraintName)) {
+                        if (!ConstraintName.equals("")) {
+                            alterCreate +=
+                                Dest.helper
+                                    .formatIdentifier(columnName
+                                        .substring(0, columnName
+                                            .length() - 1)) + ") REFERENCES "
+                                                            + Dest.helper
+                                                                .formatName(RefTableName);
+
+                            if (foreignKeyName.length() > 0) {
+                                alterCreate +=
+                                    " ("
+                                    + Dest.helper.formatIdentifier(
+                                        foreignKeyName.substring(
+                                            0, foreignKeyName.length()
+                                            - 1)) + ")";
+                            }
+
+                            alterCreate += ";";
+                            alterDrop =
+                                alterDrop.substring(0, alterDrop.length() - 1)
+                                + ";";
+                            foreignKeyName = "";
+                            columnName     = "";
+                        }
+
+                        RefTableName   = ImportedKeys.getString(3);
+                        ConstraintName = ImportedKeys.getString(12);
+                        alterCreate +=
+                            "ALTER TABLE "
+                            + Dest.helper.formatName(TTable.Stmts.sDestTable)
+                            + " ADD CONSTRAINT ";
+
+                        if ((TTable.Stmts.bFKForced)
+                                && (!ConstraintName.startsWith("FK_"))) {
+                            alterCreate +=
+                                Dest.helper.formatIdentifier(
+                                    "FK_" + ConstraintName) + " ";
+                        } else {
+                            alterCreate +=
+                                Dest.helper.formatIdentifier(ConstraintName)
+                                + " ";
+                        }
+
+                        alterCreate += "FOREIGN KEY (";
+                        alterDrop +=
+                            "ALTER TABLE "
+                            + Dest.helper.formatName(TTable.Stmts.sDestTable)
+                            + " DROP CONSTRAINT ";
+
+                        if ((TTable.Stmts.bFKForced)
+                                && (!ConstraintName.startsWith("FK_"))) {
+                            alterDrop +=
+                                Dest.helper.formatIdentifier(
+                                    "FK_" + ConstraintName) + " ";
+                        } else {
+                            alterDrop +=
+                                Dest.helper.formatIdentifier(ConstraintName)
+                                + " ";
+                        }
+                    }
+
+                    columnName     += ImportedKeys.getString(8) + ",";
+                    foreignKeyName += ImportedKeys.getString(4) + ",";
+                }
+
+                ImportedKeys.close();
+            }
+
+            if (importedkeys) {
+                alterCreate += columnName.substring(0, columnName.length() - 1)
+                               + ") REFERENCES "
+                               + Dest.helper.formatName(RefTableName);
+
+                if (foreignKeyName.length() > 0) {
+                    alterCreate +=
+                        " ("
+                        + Dest.helper.formatIdentifier(
+                            foreignKeyName.substring(
+                                0, foreignKeyName.length() - 1)) + ")";
+                }
+
+                alterCreate += ";";
+                alterDrop = alterDrop.substring(0, alterDrop.length() - 1)
+                            + ";";
+                TTable.Stmts.sDestDrop = alterDrop + TTable.Stmts.sDestDrop;
+            }
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        boolean   primarykeys           = false;
+        String    PrimaryKeysConstraint = "";
+        ResultSet PrimaryKeys           = null;
+
+        try {
+            PrimaryKeys = meta.getPrimaryKeys(TTable.Stmts.sDatabaseToConvert,
+                                              TTable.Stmts.sSchema,
+                                              TTable.Stmts.sSourceTable);
+        } catch (SQLException e) {
+            PrimaryKeys = null;
+        }
+
+        try {
+            if (PrimaryKeys != null) {
+                while (PrimaryKeys.next()) {
+                    if (primarykeys) {
+                        PrimaryKeysConstraint += ", ";
+                    } else {
+                        if (PrimaryKeys.getString(6) != null) {
+                            PrimaryKeysConstraint =
+                                " CONSTRAINT "
+                                + Dest.helper.formatIdentifier(
+                                    PrimaryKeys.getString(6));
+                        }
+
+                        PrimaryKeysConstraint += " PRIMARY KEY (";
+                    }
+
+                    PrimaryKeysConstraint +=
+                        Dest.helper.formatIdentifier(PrimaryKeys.getString(4));
+                    primarykeys = true;
+                }
+
+                PrimaryKeys.close();
+
+                if (primarykeys) {
+                    PrimaryKeysConstraint += ") ";
+                }
+            }
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        boolean   indices     = false;
+        ResultSet Indices     = null;
+        String    IndiceName  = new String("");
+        String    CreateIndex = new String("");
+        String    DropIndex   = new String("");
+
+        try {
+            Indices = meta.getIndexInfo(TTable.Stmts.sDatabaseToConvert,
+                                        TTable.Stmts.sSchema,
+                                        TTable.Stmts.sSourceTable, false,
+                                        false);
+        } catch (SQLException e) {
+            Indices = null;
+        }
+
+        try {
+            if (Indices != null) {
+                while (Indices.next()) {
+                    String tmpIndexName = null;
+
+                    try {
+                        tmpIndexName = Indices.getString(6);
+                    } catch (SQLException e) {
+                        tmpIndexName = null;
+                    }
+
+                    if (tmpIndexName == null) {
+                        continue;
+                    }
+
+                    if (!tmpIndexName.equals(IndiceName)) {
+                        if (!IndiceName.equals("")) {
+                            CreateIndex =
+                                CreateIndex.substring(
+                                    0, CreateIndex.length() - 1) + ");";
+                            DropIndex += ";";
+                        }
+
+                        IndiceName = tmpIndexName;
+                        DropIndex  += "DROP INDEX ";
+
+                        if ((TTable.Stmts.bIdxForced)
+                                && (!IndiceName.startsWith("Idx_"))) {
+                            DropIndex += Dest.helper.formatIdentifier("Idx_"
+                                    + IndiceName);
+                        } else {
+                            DropIndex +=
+                                Dest.helper.formatIdentifier(IndiceName);
+                        }
+
+                        CreateIndex += "CREATE ";
+
+                        if (!Indices.getBoolean(4)) {
+                            CreateIndex += "UNIQUE ";
+                        }
+
+                        CreateIndex += "INDEX ";
+
+                        if ((TTable.Stmts.bIdxForced)
+                                && (!IndiceName.startsWith("Idx_"))) {
+                            CreateIndex += Dest.helper.formatIdentifier("Idx_"
+                                    + IndiceName);
+                        } else {
+                            CreateIndex +=
+                                Dest.helper.formatIdentifier(IndiceName);
+                        }
+
+                        CreateIndex +=
+                            " ON "
+                            + Dest.helper.formatName(TTable.Stmts.sDestTable)
+                            + "(";
+                    }
+
+                    CreateIndex +=
+                        Dest.helper.formatIdentifier(Indices.getString(9))
+                        + ",";
+                    indices = true;
+                }
+
+                Indices.close();
+
+                if (indices) {
+                    CreateIndex =
+                        CreateIndex.substring(0, CreateIndex.length() - 1)
+                        + ");";
+                    DropIndex += ";";
+                }
+            }
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        Vector v = new Vector();
+
+        tracer.trace("Reading source columns for table "
+                     + TTable.Stmts.sSourceTable);
+
+        ResultSet         col            = null;
+        int               colnum         = 1;
+        Statement         stmt           = null;
+        ResultSet         select_rs      = null;
+        ResultSetMetaData select_rsmdata = null;
+
+        try {
+            stmt           = conn.createStatement();
+            select_rs      = stmt.executeQuery(TTable.Stmts.sSourceSelect);
+            select_rsmdata = select_rs.getMetaData();
+            col = meta.getColumns(TTable.Stmts.sDatabaseToConvert,
+                                  TTable.Stmts.sSchema,
+                                  TTable.Stmts.sSourceTable, null);
+        } catch (SQLException eSchema) {
+
+            // fredt - second try with null schema
+            if (TTable.Stmts.sSchema.equals("")) {
+                try {
+                    col = meta.getColumns(TTable.Stmts.sDatabaseToConvert,
+                                          null, TTable.Stmts.sSourceTable,
+                                          null);
+                } catch (SQLException eSchema1) {}
+            }
+        }
+
+        try {
+            while (col.next()) {
+                String name = Dest.helper.formatIdentifier(col.getString(4));
+                int    type        = col.getShort(5);
+                String source      = col.getString(6);
+                int    column_size = col.getInt(7);
+                String DefaultVal  = col.getString(13);
+                boolean rsmdata_NoNulls =
+                    (select_rsmdata.isNullable(colnum)
+                     == java.sql.DatabaseMetaData.columnNoNulls);
+                boolean rsmdata_isAutoIncrement = false;
+
+                try {
+                    rsmdata_isAutoIncrement =
+                        select_rsmdata.isAutoIncrement(colnum);
+                } catch (SQLException e) {
+                    rsmdata_isAutoIncrement = false;
+                }
+
+                int rsmdata_precision = select_rsmdata.getPrecision(colnum);
+                int rsmdata_scale     = select_rsmdata.getScale(colnum);
+
+                type = helper.convertFromType(type);
+                type = Dest.helper.convertToType(type);
+
+                Integer inttype  = new Integer(type);
+                String  datatype = (String) TTable.hTypes.get(inttype);
+
+                if (datatype == null) {
+                    datatype = source;
+
+                    tracer.trace("No mapping for type: " + name + " type: "
+                                 + type + " source: " + source);
+                }
+
+                if (type == Types.NUMERIC || type == Types.DECIMAL) {
+                    datatype += "(" + Integer.toString(rsmdata_precision);
+
+                    if (rsmdata_scale > 0) {
+                        datatype += "," + Integer.toString(rsmdata_scale);
+                    }
+
+                    datatype += ")";
+                } else if (type == Types.CHAR || type == Types.VARCHAR || type == Types.BINARY || type == Types.VARBINARY) {
+                    datatype += "(" + Integer.toString(column_size) + ")";
+                } else if (rsmdata_isAutoIncrement) {
+                    datatype = "SERIAL";
+                }
+
+                if (DefaultVal != null) {
+                    if (type == Types.CHAR || type == Types.VARCHAR
+                            || type == Types.LONGVARCHAR
+                            || type == Types.BINARY || type == Types.DATE
+                            || type == Types.TIME || type == Types.TIMESTAMP) {
+                        if (!DefaultVal.startsWith("'")) {
+                            DefaultVal = "\'" + DefaultVal + "\'";
+                        }
+                    }
+
+                    datatype += " DEFAULT " + DefaultVal;
+                }
+
+                if (rsmdata_NoNulls) {
+                    datatype += " NOT NULL ";
+                }
+
+                v.addElement(inttype);
+
+                datatype = helper.fixupColumnDefRead(TTable, select_rsmdata,
+                                                     datatype, col, colnum);
+                datatype = Dest.helper.fixupColumnDefWrite(TTable,
+                        select_rsmdata, datatype, col, colnum);
+                create += name + " " + datatype + ",";
+                insert += "?,";
+
+                colnum++;
+            }
+
+            select_rs.close();
+            stmt.close();
+            col.close();
+        } catch (SQLException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        if (primarykeys) {
+            create += PrimaryKeysConstraint + ",";
+        }
+
+        TTable.Stmts.sDestCreate = create.substring(0, create.length() - 1)
+                                   + ")";
+        TTable.Stmts.sDestInsert = insert.substring(0, insert.length() - 1)
+                                   + ")";
+
+        if (importedkeys) {
+            TTable.Stmts.bAlter     = true;
+            TTable.Stmts.sDestAlter = alterCreate;
+        } else {
+            TTable.Stmts.bAlter = false;
+        }
+
+        if (indices) {
+            TTable.Stmts.bCreateIndex     = true;
+            TTable.Stmts.bDropIndex       = true;
+            TTable.Stmts.sDestCreateIndex = CreateIndex;
+            TTable.Stmts.sDestDropIndex   = DropIndex;
+        } else {
+            TTable.Stmts.bCreateIndex = false;
+            TTable.Stmts.bDropIndex   = false;
+        }
+
+        //iColumnType = new int[v.size()];
+        //for (int j = 0; j < v.size(); j++) {
+        //    iColumnType[j] = ((Integer) v.elementAt(j)).intValue();
+        //}
+    }
+
+    void close() throws DataAccessPointException {
+
+        if (srcStatement != null) {
+            try {
+                srcStatement.close();
+            } catch (SQLException e) {}
+
+            srcStatement = null;
+        }
+
+        if (conn != null) {
+            try {
+                conn.close();
+            } catch (SQLException e) {}
+
+            conn = null;
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param type
+     * @param r
+     * @param p
+     *
+     * @throws SQLException
+     */
+    private void transferRow(TransferResultSet r, PreparedStatement p,
+                             int len,
+                             int[] types)
+                             throws DataAccessPointException, SQLException {
+
+        for (int i = 1; i <= len; i++) {
+            int    t = types[i];
+            Object o = r.getObject(i);
+
+            if (o == null) {
+                if (p != null) {
+                    p.setNull(i, t);
+                }
+            } else {
+                o = helper.convertColumnValue(o, i, t);
+
+                p.setObject(i, o);
+            }
+        }
+
+        if (p != null) {
+            p.execute();
+        }
+    }
+
+    /**
+     * @return Returns the meta.
+     */
+    public DatabaseMetaData getMeta() {
+        return meta;
+    }
+
+    /**
+     * @return Returns the conn.
+     */
+    public Connection getConn() {
+        return conn;
+    }
+}
diff --git a/src/org/hsqldb/util/TransferHelper.java b/src/org/hsqldb/util/TransferHelper.java
new file mode 100644
index 0000000..e9998b7
--- /dev/null
+++ b/src/org/hsqldb/util/TransferHelper.java
@@ -0,0 +1,188 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Hashtable;
+
+/**
+ * Base class for conversion from a different databases
+ *
+ * @author Bob Preston (sqlbob@users dot sourceforge.net)
+ * @version 1.7.0
+ */
+class TransferHelper {
+
+    protected TransferDb db;
+    protected Traceable  tracer;
+    protected String     sSchema;
+    protected JDBCTypes  JDBCT;
+    private String       quote;
+
+    TransferHelper() {
+
+        db     = null;
+        tracer = null;
+        quote  = "\'";
+        JDBCT  = new JDBCTypes();
+    }
+
+    TransferHelper(TransferDb database, Traceable t, String q) {
+
+        db     = database;
+        tracer = t;
+        quote  = q;
+        JDBCT  = new JDBCTypes();
+    }
+
+    void set(TransferDb database, Traceable t, String q) {
+
+        db     = database;
+        tracer = t;
+        quote  = q;
+    }
+
+    String formatIdentifier(String id) {
+
+        if (id == null) {
+            return id;
+        }
+
+        if (id.equals("")) {
+            return id;
+        }
+
+        if (!id.toLowerCase().equals(id) && !id.toUpperCase().equals(id)) {
+            return (quote + id + quote);
+        }
+
+        if (!Character.isLetter(id.charAt(0)) || (id.indexOf(' ') != -1)) {
+            return (quote + id + quote);
+        }
+
+        return id;
+    }
+
+    void setSchema(String _Schema) {
+        sSchema = _Schema;
+    }
+
+    String formatName(String t) {
+
+        String Name = "";
+
+        if ((sSchema != null) && (sSchema.length() > 0)) {
+            Name = sSchema + ".";
+        }
+
+        Name += formatIdentifier(t);
+
+        return Name;
+    }
+
+    int convertFromType(int type) {
+        return (type);
+    }
+
+    int convertToType(int type) {
+        return (type);
+    }
+
+    Hashtable getSupportedTypes() {
+
+        Hashtable hTypes = new Hashtable();
+
+        if (db != null) {
+            try {
+                ResultSet result = db.meta.getTypeInfo();
+
+                while (result.next()) {
+                    Integer intobj = new Integer(result.getShort(2));
+
+                    if (hTypes.get(intobj) == null) {
+                        try {
+                            int typeNumber = result.getShort(2);
+
+                            hTypes.put(intobj, JDBCT.toString(typeNumber));
+                        } catch (Exception e) {}
+                    }
+                }
+
+                result.close();
+            } catch (SQLException e) {}
+        }
+
+        if (hTypes.isEmpty()) {
+            hTypes = JDBCT.getHashtable();
+        }
+
+        return hTypes;
+    }
+
+    String fixupColumnDefRead(TransferTable t, ResultSetMetaData meta,
+                              String columnType, ResultSet columnDesc,
+                              int columnIndex) throws SQLException {
+        return (columnType);
+    }
+
+    String fixupColumnDefWrite(TransferTable t, ResultSetMetaData meta,
+                               String columnType, ResultSet columnDesc,
+                               int columnIndex) throws SQLException {
+        return (columnType);
+    }
+
+    boolean needTransferTransaction() {
+        return (false);
+    }
+
+    Object convertColumnValue(Object value, int column, int type) {
+        return (value);
+    }
+
+    void beginDataTransfer() {}
+
+    void endDataTransfer() {}
+
+    String fixupColumnDefRead(String aTableName, ResultSetMetaData meta,
+                              String columnType, ResultSet columnDesc,
+                              int columnIndex) throws SQLException {
+        return columnType;
+    }
+
+    String fixupColumnDefWrite(String aTableName, ResultSetMetaData meta,
+                               String columnType, ResultSet columnDesc,
+                               int columnIndex) throws SQLException {
+        return columnType;
+    }
+}
diff --git a/src/org/hsqldb/util/TransferResultSet.java b/src/org/hsqldb/util/TransferResultSet.java
new file mode 100644
index 0000000..c5f227e
--- /dev/null
+++ b/src/org/hsqldb/util/TransferResultSet.java
@@ -0,0 +1,172 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Vector;
+
+/**
+ * Helper class for transferring a result set
+ *
+ * @author Nicolas BAZIN
+ * @version 1.7.0
+ */
+class TransferResultSet {
+
+    Vector   vRows = null;
+    int      iRowIdx;
+    int      iMaxRowIdx;
+    int      iColumnCount;
+    String[] sColumnNames = null;
+    int[]    iColumnTypes = null;
+
+    TransferResultSet(ResultSet r) {
+
+        iRowIdx      = 0;
+        iMaxRowIdx   = 0;
+        iColumnCount = 0;
+        vRows        = new Vector();
+
+        try {
+            while (r.next()) {
+                if (sColumnNames == null) {
+                    iColumnCount = r.getMetaData().getColumnCount();
+                    sColumnNames = new String[iColumnCount + 1];
+                    iColumnTypes = new int[iColumnCount + 1];
+
+                    for (int Idx = 0; Idx < iColumnCount; Idx++) {
+                        sColumnNames[Idx + 1] =
+                            r.getMetaData().getColumnName(Idx + 1);
+                        iColumnTypes[Idx + 1] =
+                            r.getMetaData().getColumnType(Idx + 1);
+                    }
+
+                    vRows.addElement(null);
+                }
+
+                iMaxRowIdx++;
+
+                Object[] Values = new Object[iColumnCount + 1];
+
+                for (int Idx = 0; Idx < iColumnCount; Idx++) {
+                    Values[Idx + 1] = r.getObject(Idx + 1);
+                }
+
+                vRows.addElement(Values);
+            }
+        } catch (SQLException SQLE) {
+            iRowIdx      = 0;
+            iMaxRowIdx   = 0;
+            iColumnCount = 0;
+            vRows        = new Vector();
+        }
+    }
+
+    TransferResultSet() {
+
+        iRowIdx      = 0;
+        iMaxRowIdx   = 0;
+        iColumnCount = 0;
+        vRows        = new Vector();
+    }
+
+    void addRow(String[] Name, int[] type, Object[] Values,
+                int nbColumns) throws Exception {
+
+        if ((Name.length != type.length) || (Name.length != Values.length)
+                || (Name.length != (nbColumns + 1))) {
+            throw new Exception("Size of parameter incoherent");
+        }
+
+        if (sColumnNames == null) {
+            iColumnCount = nbColumns;
+            sColumnNames = Name;
+            iColumnTypes = type;
+
+            vRows.addElement(null);
+        }
+
+        if ((iMaxRowIdx > 0) && (this.getColumnCount() != nbColumns)) {
+            throw new Exception("Wrong number of columns: "
+                                + this.getColumnCount()
+                                + " column is expected");
+        }
+
+        iMaxRowIdx++;
+
+        vRows.addElement(Values);
+    }
+
+    boolean next() {
+
+        iRowIdx++;
+
+        return ((iRowIdx <= iMaxRowIdx) && (iMaxRowIdx > 0));
+    }
+
+    String getColumnName(int columnIdx) {
+
+        if ((iMaxRowIdx <= 0) || (iMaxRowIdx < iRowIdx)) {
+            return null;
+        }
+
+        return sColumnNames[columnIdx];
+    }
+
+    int getColumnCount() {
+
+        if ((iMaxRowIdx <= 0) || (iMaxRowIdx < iRowIdx)) {
+            return 0;
+        }
+
+        return iColumnCount;
+    }
+
+    int getColumnType(int columnIdx) {
+
+        if ((iMaxRowIdx <= 0) || (iMaxRowIdx < iRowIdx)) {
+            return 0;
+        }
+
+        return iColumnTypes[columnIdx];
+    }
+
+    Object getObject(int columnIdx) {
+
+        if ((iMaxRowIdx <= 0) || (iMaxRowIdx < iRowIdx)) {
+            return null;
+        }
+
+        return ((Object[]) vRows.elementAt(iRowIdx))[columnIdx];
+    }
+}
diff --git a/src/org/hsqldb/util/TransferSQLText.java b/src/org/hsqldb/util/TransferSQLText.java
new file mode 100644
index 0000000..5ce7915
--- /dev/null
+++ b/src/org/hsqldb/util/TransferSQLText.java
@@ -0,0 +1,865 @@
+/* Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * @author Nicolas BAZIN, INGENICO
+ * @version 1.7.0
+ */
+class TransferSQLText extends DataAccessPoint {
+
+    String              sFileName              = null;
+    BufferedWriter      WTextWrite             = null;
+    BufferedReader      WTextRead              = null;
+    protected boolean   StructureAlreadyParsed = false;
+    Hashtable           DbStmts                = null;
+    protected JDBCTypes JDBCT                  = null;
+
+    TransferSQLText(String _FileName,
+                    Traceable t) throws DataAccessPointException {
+
+        super(t);
+
+        sFileName = _FileName;
+        JDBCT     = new JDBCTypes();
+
+        if (sFileName == null) {
+            throw new DataAccessPointException("File name not initialized");
+        }
+    }
+
+    boolean execute(String statement) throws DataAccessPointException {
+
+        if (WTextWrite == null) {
+            try {
+                WTextWrite = new BufferedWriter(new FileWriter(sFileName));
+            } catch (IOException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+
+        try {
+            WTextWrite.write(statement + "\n");
+            WTextWrite.flush();
+        } catch (IOException e) {
+            throw new DataAccessPointException(e.getMessage());
+        }
+
+        return true;
+    }
+
+    void putData(String statement, TransferResultSet r,
+                 int iMaxRows) throws DataAccessPointException {
+
+        int i = 0;
+
+        if (r == null) {
+            return;
+        }
+
+        if (WTextWrite == null) {
+            try {
+                WTextWrite = new BufferedWriter(new FileWriter(sFileName));
+            } catch (IOException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+
+        try {
+            while (r.next()) {
+                if (i == 0) {
+                    WTextWrite.write(statement + "\n");
+                    WTextWrite.flush();
+                }
+
+                transferRow(r);
+
+                if (iMaxRows != 0 && i == iMaxRows) {
+                    break;
+                }
+
+                i++;
+
+                if (iMaxRows != 0 || i % 100 == 0) {
+                    tracer.trace("Transfered " + i + " rows");
+                }
+            }
+        } catch (Exception e) {
+            throw new DataAccessPointException(e.getMessage());
+        } finally {
+            try {
+                if (i > 0) {
+                    WTextWrite.write("\tNumber of Rows=" + i + "\n\n");
+                    WTextWrite.flush();
+                }
+            } catch (IOException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+    }
+
+    void close() throws DataAccessPointException {
+
+        if (WTextWrite != null) {
+            try {
+                WTextWrite.flush();
+                WTextWrite.close();
+            } catch (IOException e) {}
+        }
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param type
+     * @param r
+     * @param p
+     *
+     * @throws SQLException
+     */
+    private void transferRow(TransferResultSet r) throws Exception {
+
+        String sLast = "";
+        int    len   = r.getColumnCount();
+
+        if (WTextWrite == null) {
+            try {
+                WTextWrite = new BufferedWriter(new FileWriter(sFileName));
+            } catch (IOException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+
+        for (int i = 0; i < len; i++) {
+            int t = r.getColumnType(i + 1);
+
+            sLast = "column=" + r.getColumnName(i + 1) + " datatype="
+                    + (String) helper.getSupportedTypes().get(new Integer(t));
+
+            Object o = r.getObject(i + 1);
+
+            if (o == null) {
+                sLast += " value=<null>";
+            } else {
+                o     = helper.convertColumnValue(o, i + 1, t);
+                sLast += " value=\'" + o.toString() + "\'";
+            }
+
+            WTextWrite.write("\t" + sLast + "\n");
+            WTextWrite.flush();
+        }
+
+        WTextWrite.write("\n");
+        WTextWrite.flush();
+
+        sLast = "";
+    }
+
+    class ColumnDef {
+
+        String columnName;
+        String columnType;
+        String options;
+        int    start;
+        int    len;
+
+        public ColumnDef() {
+
+            columnName = "";
+            columnType = "";
+            options    = "";
+            start      = 0;
+            len        = 0;
+        }
+    }
+
+    ColumnDef getColumnDef(String ColumnsDesc, int curPos) {
+
+        int       nextPos   = 0;
+        ColumnDef columnDef = new TransferSQLText.ColumnDef();
+
+        columnDef.start = curPos;
+
+        if ((ColumnsDesc == null) || (ColumnsDesc.length() == 0)
+                || (curPos >= ColumnsDesc.length())) {
+            return new TransferSQLText.ColumnDef();
+        }
+
+        String stbuff = ColumnsDesc.substring(curPos);
+
+        try {
+            int i = 0;
+
+            for (; i < stbuff.length(); i++) {
+                int c = stbuff.charAt(i);
+
+                if (c == ',' || c == ' ' || c == ')' || c == ';') {
+                    continue;
+                } else {
+                    break;
+                }
+            }
+
+            if (i == stbuff.length()) {
+                return new TransferSQLText.ColumnDef();
+            }
+
+            columnDef.len += i;
+            stbuff        = stbuff.substring(i);
+
+            while (stbuff.charAt(nextPos) != ' ') {
+                nextPos++;
+            }
+
+            columnDef.columnName = stbuff.substring(0, nextPos);
+            stbuff               = stbuff.substring(nextPos);
+            columnDef.len        += nextPos;
+            nextPos              = 0;
+
+            if (!columnDef.columnName.toUpperCase().equals("CONSTRAINT")) {
+                i = 0;
+
+                for (; i < stbuff.length() && stbuff.charAt(i) == ' '; i++) {}
+
+                stbuff        = stbuff.substring(i);
+                columnDef.len += i;
+
+                while ((stbuff.charAt(nextPos) != '(')
+                        && (stbuff.charAt(nextPos) != ',')
+                        && (stbuff.charAt(nextPos) != ')')
+                        && (stbuff.charAt(nextPos) != ';')
+                        && (stbuff.charAt(nextPos) != ' ')) {
+                    nextPos++;
+                }
+
+                columnDef.columnType = stbuff.substring(0,
+                        nextPos).toUpperCase();
+                stbuff        = stbuff.substring(nextPos);
+                columnDef.len += nextPos;
+                nextPos       = 0;
+            }
+
+            while ((stbuff.charAt(nextPos) != ',')
+                    && (stbuff.charAt(nextPos) != ';')
+                    && (nextPos < stbuff.length())
+                    && (stbuff.charAt(nextPos) != ')')) {
+                if (stbuff.charAt(nextPos) == '(') {
+                    while (stbuff.charAt(nextPos) != ')') {
+                        nextPos++;
+                    }
+                }
+
+                nextPos++;
+            }
+
+            columnDef.options = stbuff.substring(0, nextPos);
+            columnDef.len     += nextPos;
+        } catch (Exception e) {
+            columnDef = new TransferSQLText.ColumnDef();
+        }
+
+        return columnDef;
+    }
+
+    String translateTypes(String CreateLine, TransferTable TTable,
+                          DataAccessPoint Dest)
+                          throws DataAccessPointException {
+
+        String    translatedLine = "";
+        JDBCTypes JDBCT          = new JDBCTypes();
+        int       currentPos     = 0;
+        String    columnName     = "";
+        String    columnType     = "";
+        int       colnum         = 0;
+        ColumnDef cDef;
+
+        currentPos     = CreateLine.indexOf('(') + 1;
+        translatedLine = CreateLine.substring(0, currentPos);
+
+        do {
+            cDef = getColumnDef(CreateLine, currentPos);
+
+            if (cDef.len == 0) {
+                break;
+            }
+
+            columnName = cDef.columnName;
+            columnType = cDef.columnType;
+
+            if (columnName.toUpperCase().indexOf("CONSTRAINT") >= 0) {
+                translatedLine +=
+                    CreateLine.substring(currentPos, currentPos + cDef.len)
+                    + ",";
+                currentPos += cDef.len + 1;
+
+                colnum++;
+
+                continue;
+            }
+
+            columnName = Dest.helper.formatIdentifier(columnName) + " ";
+
+            try {
+                Integer inttype = new Integer(
+                    Dest.helper.convertToType(JDBCT.toInt(columnType)));
+
+                columnType = (String) TTable.hTypes.get(inttype);
+            } catch (Exception JDBCtypeEx) {}
+
+            if (cDef.options != null) {
+                columnType += cDef.options;
+            }
+
+            try {
+                columnType = Dest.helper.fixupColumnDefWrite(TTable, null,
+                        columnType, null, colnum);
+            } catch (SQLException SQLe) {
+                return CreateLine;
+            }
+
+            translatedLine += columnName + " " + columnType + ",";
+            currentPos     += cDef.len + 1;
+
+            colnum++;
+        } while (true);
+
+        return translatedLine.substring(0, translatedLine.length() - 1)
+               + ");";
+    }
+
+    void parseFileForTables() throws DataAccessPointException {
+
+        StringTokenizer Tokenizer;
+
+        if (WTextRead == null) {
+            try {
+                WTextRead = new BufferedReader(new FileReader(sFileName));
+            } catch (IOException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+
+        String        currentLine  = "";
+        String        Token        = "";
+        String        name         = "";
+        TransferTable relatedTable = null;
+
+        try {
+            while ((currentLine = WTextRead.readLine()) != null) {
+                currentLine = currentLine.trim() + ";";
+                Tokenizer   = new StringTokenizer(currentLine);
+
+                try {
+                    Token = Tokenizer.nextToken();
+                } catch (NoSuchElementException NSE) {
+                    continue;
+                }
+
+                if (Token == null) {
+                    continue;
+                }
+
+                if (!Token.toUpperCase().equals("CREATE")) {
+                    continue;
+                }
+
+                Token = Tokenizer.nextToken().toUpperCase();
+
+                if (Token.equals("TABLE") || Token.equals("VIEW")) {
+                    try {
+                        name = Tokenizer.nextToken(" (;");
+                        relatedTable = new TransferTable(this, name, "",
+                                                         Token, tracer);
+                        relatedTable.Stmts.bCreate      = false;
+                        relatedTable.Stmts.bDelete      = false;
+                        relatedTable.Stmts.bDrop        = false;
+                        relatedTable.Stmts.bCreateIndex = false;
+                        relatedTable.Stmts.bDropIndex   = false;
+                        relatedTable.Stmts.bInsert      = false;
+                        relatedTable.Stmts.bAlter       = false;
+
+                        DbStmts.put(relatedTable.Stmts.sSourceTable,
+                                    relatedTable);
+                    } catch (NoSuchElementException NSE) {
+                        continue;
+                    }
+                }
+            }
+        } catch (Exception IOe) {
+            throw new DataAccessPointException(IOe.getMessage());
+        }
+    }
+
+    void parseFileForTheRest(TransferTable TTable,
+                             DataAccessPoint Dest)
+                             throws DataAccessPointException {
+
+        StringTokenizer Tokenizer;
+
+        StructureAlreadyParsed = true;
+
+        if (WTextRead == null) {
+            try {
+                WTextRead = new BufferedReader(new FileReader(sFileName));
+            } catch (IOException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+
+        String        currentLine  = "";
+        String        Token        = "";
+        String        name         = "";
+        TransferTable relatedTable = null;
+
+        try {
+            while ((currentLine = WTextRead.readLine()) != null) {
+                currentLine = currentLine.trim() + ";";
+                Tokenizer   = new StringTokenizer(currentLine);
+
+                try {
+                    Token = Tokenizer.nextToken();
+                } catch (NoSuchElementException NSE) {
+                    continue;
+                }
+
+                if (Token == null) {
+                    continue;
+                }
+
+                if (Token.toUpperCase().equals("INSERT")) {
+                    try {
+                        if (!Tokenizer.nextToken().toUpperCase().equals(
+                                "INTO")) {
+                            throw new DataAccessPointException(
+                                "Error in INSERT statement: no INTO found");
+                        }
+
+                        Token = Tokenizer.nextToken();
+
+                        if ((relatedTable =
+                                (TransferTable) DbStmts.get(Token)) != null) {
+                            relatedTable.Stmts.bDelete     = true;
+                            relatedTable.Stmts.bInsert     = true;
+                            relatedTable.Stmts.sDestInsert = currentLine;
+                            relatedTable.Stmts.sDestDelete =
+                                "DELETE FROM "
+                                + relatedTable.Stmts.sSourceTable + ";";
+                        }
+
+                        continue;
+                    } catch (NoSuchElementException NSE) {
+                        continue;
+                    }
+                } else if (Token.toUpperCase().equals("ALTER")) {
+                    try {
+                        if (!Tokenizer.nextToken().toUpperCase().equals(
+                                "TABLE")) {
+                            continue;
+                        }
+
+                        name  = Tokenizer.nextToken();
+                        Token = Tokenizer.nextToken().toUpperCase();
+
+                        if (!Token.equals("ADD")) {
+                            continue;
+                        }
+
+                        do {
+                            Token = Tokenizer.nextToken().toUpperCase();
+                        } while (!Token.equals("CONSTRAINT"));
+
+                        if ((relatedTable = (TransferTable) DbStmts.get(name))
+                                != null) {
+                            if (relatedTable.Stmts.sDestAlter == null) {
+                                relatedTable.Stmts.sDestAlter = "";
+                            }
+
+                            relatedTable.Stmts.bAlter     = true;
+                            relatedTable.Stmts.sDestAlter += currentLine;
+                        } else {
+                            throw new DataAccessPointException(
+                                "table not found");
+                        }
+
+                        Token = Tokenizer.nextToken();
+
+                        if (relatedTable.Stmts.sDestDrop == null) {
+                            relatedTable.Stmts.sDestDrop = "";
+                        }
+
+                        relatedTable.Stmts.bDrop = true;
+                        relatedTable.Stmts.sDestDrop =
+                            "ALTER TABLE " + name + " DROP CONSTRAINT "
+                            + Token + ";" + relatedTable.Stmts.sDestDrop;
+
+                        continue;
+                    } catch (NoSuchElementException NSE) {
+                        continue;
+                    }
+                } else if (!Token.toUpperCase().equals("CREATE")) {
+                    continue;
+                }
+
+                Token = Tokenizer.nextToken().toUpperCase();
+
+                if (Token.equals("TABLE") || Token.equals("VIEW")) {
+                    try {
+                        name = Tokenizer.nextToken(" (;");
+
+                        if (!DbStmts.containsKey(name)) {
+                            throw new DataAccessPointException(
+                                "error: index is created before the table");
+                        }
+
+                        relatedTable = (TransferTable) DbStmts.get(name);
+                        relatedTable.Stmts.bCreate = true;
+                        relatedTable.Stmts.bDrop   = true;
+
+//                        relatedTable.Stmts.sDestCreate = currentLine;
+                        relatedTable.Stmts.sDestCreate =
+                            translateTypes(currentLine, TTable, Dest);
+                        relatedTable.Stmts.sDestDrop =
+                            "DROP " + relatedTable.Stmts.sType + " " + name
+                            + ";";
+
+                        DbStmts.put(relatedTable.Stmts.sSourceTable,
+                                    relatedTable);
+                    } catch (NoSuchElementException NSE) {
+                        continue;
+                    }
+                }
+
+                if (Token.equals("INDEX") || Token.equals("UNIQUE")) {
+                    try {
+                        while ((Token =
+                                Tokenizer.nextToken()).toUpperCase().equals(
+                                    "INDEX")) {
+                            ;
+                        }
+
+                        String IndexdropCommand = "DROP INDEX " + Token
+                                                  + " ;";
+
+                        while ((Token = Tokenizer.nextToken(
+                                " (")).toUpperCase().equals("ON")) {
+                            ;
+                        }
+
+                        name = Token;
+
+                        if (!DbStmts.containsKey(Token)) {
+                            throw new DataAccessPointException(
+                                "error: index is created before the table");
+                        }
+
+                        relatedTable = (TransferTable) DbStmts.get(Token);
+
+                        if (relatedTable.Stmts.sDestCreateIndex == null) {
+                            relatedTable.Stmts.sDestCreateIndex = "";
+                        }
+
+                        if (relatedTable.Stmts.sDestDropIndex == null) {
+                            relatedTable.Stmts.sDestDropIndex = "";
+                        }
+
+                        relatedTable.Stmts.bCreateIndex     = true;
+                        relatedTable.Stmts.bDropIndex       = true;
+                        relatedTable.Stmts.sDestCreateIndex += currentLine;
+                        relatedTable.Stmts.sDestDropIndex += IndexdropCommand;
+                    } catch (NoSuchElementException NSE) {
+                        continue;
+                    }
+                }
+            }
+        } catch (IOException IOe) {
+            throw new DataAccessPointException(IOe.getMessage());
+        }
+    }
+
+    Vector getTables(String sCatalog,
+                     String[] sSchemas) throws DataAccessPointException {
+
+        Vector AllTables = new Vector();
+
+        if (DbStmts == null) {
+            DbStmts = new Hashtable();
+        }
+
+        if (WTextRead != null) {
+            try {
+                WTextRead.close();
+
+                WTextRead = null;
+            } catch (IOException e) {}
+        }
+
+        this.parseFileForTables();
+
+        StructureAlreadyParsed = false;
+
+        Enumeration e = DbStmts.elements();
+
+        while (e.hasMoreElements()) {
+            AllTables.addElement(e.nextElement());
+        }
+
+        return AllTables;
+    }
+
+    void getTableStructure(TransferTable TTable,
+                           DataAccessPoint Dest)
+                           throws DataAccessPointException {
+
+        if (!StructureAlreadyParsed) {
+            if (WTextRead != null) {
+                try {
+                    WTextRead.close();
+
+                    WTextRead = null;
+                } catch (IOException e) {}
+            }
+
+            this.parseFileForTheRest(TTable, Dest);
+        }
+    }
+
+    TransferResultSet getData(String statement)
+    throws DataAccessPointException {
+
+        StringTokenizer Tokenizer;
+        String          tableName = "";
+
+        try {
+            Tokenizer = new StringTokenizer(statement);
+
+            while (!Tokenizer.nextToken().toUpperCase().equals("FROM")) {
+                ;
+            }
+
+            tableName = Tokenizer.nextToken(" ;");
+        } catch (NoSuchElementException NSE) {
+            throw new DataAccessPointException(
+                "Table name not found in statement: " + statement);
+        }
+
+        if (WTextRead != null) {
+            try {
+                WTextRead.close();
+
+                WTextRead = null;
+            } catch (IOException e) {}
+        }
+
+        return (this.parseFileForData(tableName));
+    }
+
+    TransferResultSet parseFileForData(String tableName)
+    throws DataAccessPointException {
+
+        TransferResultSet trsData = new TransferResultSet();
+        StringTokenizer   Tokenizer;
+
+        if (WTextRead == null) {
+            try {
+                WTextRead = new BufferedReader(new FileReader(sFileName));
+            } catch (IOException e) {
+                throw new DataAccessPointException(e.getMessage());
+            }
+        }
+
+        String currentLine = "";
+        String Token;
+
+        try {
+            while ((currentLine = WTextRead.readLine()) != null) {
+                currentLine = currentLine.trim() + ";";
+                Tokenizer   = new StringTokenizer(currentLine);
+
+                try {
+                    Token = Tokenizer.nextToken();
+                } catch (NoSuchElementException NSE) {
+                    continue;
+                }
+
+                if (Token == null) {
+                    continue;
+                }
+
+                if (!Token.toUpperCase().equals("INSERT")) {
+                    continue;
+                }
+
+                try {
+                    if (!Tokenizer.nextToken().toUpperCase().equals("INTO")) {
+                        throw new DataAccessPointException(
+                            "Error in INSERT statement: no INTO found");
+                    }
+
+                    Token = Tokenizer.nextToken();
+
+                    if (!Token.equals(tableName)) {
+                        continue;
+                    }
+
+                    int    iParsedRows   = 0;
+                    Vector vColumnNames  = new Vector();
+                    Vector vColumnValues = new Vector();
+                    Vector vColumnTypes  = new Vector();
+
+                    while ((currentLine = WTextRead.readLine()) != null) {
+                        currentLine = currentLine.trim();
+
+                        boolean newLine = (currentLine.length() == 0);
+
+                        if (newLine) {
+                            int iColumnNb = 0;
+
+                            iParsedRows++;
+
+                            iColumnNb = vColumnNames.size();
+
+                            String[] Names  = new String[iColumnNb + 1];
+                            int[]    Types  = new int[iColumnNb + 1];
+                            Object[] Values = new Object[iColumnNb + 1];
+
+                            for (int Idx = 0; Idx < iColumnNb; Idx++) {
+                                Names[Idx + 1] =
+                                    (String) vColumnNames.elementAt(Idx);
+                                Types[Idx + 1] =
+                                    ((Integer) vColumnTypes.elementAt(
+                                        Idx)).intValue();
+                                Values[Idx + 1] =
+                                    vColumnValues.elementAt(Idx);
+                            }
+
+                            try {
+                                trsData.addRow(Names, Types, Values,
+                                               iColumnNb);
+                            } catch (Exception e) {
+                                throw new DataAccessPointException(
+                                    e.getMessage());
+                            }
+
+                            iColumnNb = 0;
+
+                            vColumnNames.removeAllElements();
+                            vColumnValues.removeAllElements();
+                            vColumnTypes.removeAllElements();
+
+                            continue;
+                        }
+
+                        Tokenizer = new StringTokenizer(currentLine);
+                        Token     = Tokenizer.nextToken("=");
+
+                        if (Token.equals("Number of Rows")) {
+                            int iNbRows =
+                                Integer.parseInt(Tokenizer.nextToken());
+
+                            if (iNbRows != iParsedRows) {
+                                throw new DataAccessPointException(
+                                    "Number of parsed rows (" + iParsedRows
+                                    + ") is different from the expected ("
+                                    + iNbRows + ")");
+                            }
+
+                            return trsData;
+                        }
+
+                        if (Token.equals("column")) {
+                            Token = Tokenizer.nextToken(" =");
+
+                            vColumnNames.addElement(Token);
+                        }
+
+                        Token = Tokenizer.nextToken(" =");
+
+                        if (Token.equals("datatype")) {
+                            int iType;
+
+                            Token = Tokenizer.nextToken(" =");
+
+                            try {
+                                iType = JDBCT.toInt(Token.toUpperCase());
+                            } catch (Exception e) {
+                                throw new DataAccessPointException(
+                                    "Unknown type: " + Token);
+                            }
+
+                            vColumnTypes.addElement(new Integer(iType));
+                        }
+
+                        Token = Tokenizer.nextToken(" =");
+
+                        if (Token.equals("value")) {
+                            int iStart = currentLine.indexOf("value=") + 6;
+                            String sValue =
+                                currentLine.substring(iStart).trim();
+
+                            if (sValue.indexOf("<null>") >= 0) {
+                                vColumnValues.addElement(null);
+                            } else {
+                                int    i       = sValue.indexOf('\'') + 1;
+                                String sbToken = sValue.substring(i);
+
+                                i       = sbToken.lastIndexOf('\'');
+                                sbToken = sbToken.substring(0, i);
+                                Token   = sbToken;
+
+                                vColumnValues.addElement(Token);
+                            }
+                        }
+                    }
+                } catch (IndexOutOfBoundsException IOBe) {
+                    continue;
+                }
+            }
+        } catch (IOException IOe) {
+            throw new DataAccessPointException(IOe.getMessage());
+        }
+
+        return trsData;
+    }
+}
diff --git a/src/org/hsqldb/util/TransferTable.java b/src/org/hsqldb/util/TransferTable.java
new file mode 100644
index 0000000..61b0a3b
--- /dev/null
+++ b/src/org/hsqldb/util/TransferTable.java
@@ -0,0 +1,471 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.io.Serializable;
+import java.sql.SQLException;
+import java.util.Hashtable;
+
+// fredt@users 20011220 - patch 481239 by xponsard@users - enhancements
+// enhancements to support saving and loading of transfer settings,
+// transfer of blobs, and catalog and schema names in source db
+// changes by fredt to allow saving and loading of transfer settings
+// fredt@users 20020215 - patch 516309 by Nicolas Bazin - enhancements
+// sqlbob@users 20020325 - patch 1.7.0 - reengineering
+// fredt@users 20040508 - patch 1.7.2 - bug fixes
+
+/**
+ * Transfers data from one database to another
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.7.2
+ * @since Hypersonic SQL
+ */
+class TransferTable implements Serializable {
+
+    Hashtable       hTypes;
+    DataAccessPoint sourceDb;
+    DataAccessPoint destDb;
+    SQLStatements   Stmts = null;
+    Traceable       tracer;
+
+    TransferTable(DataAccessPoint src, String name, String schema,
+                  String type, Traceable t) {
+
+        Stmts         = new SQLStatements();
+        sourceDb      = src;
+        Stmts.sSchema = "";
+
+        if (schema != null && schema.length() > 0) {
+            Stmts.sSchema = schema;
+        }
+
+        Stmts.sType              = type;
+        Stmts.sDatabaseToConvert = src.databaseToConvert;
+        Stmts.sSourceTable       = Stmts.sDestTable = name;
+        tracer                   = t;
+
+        if (Stmts.sType.compareTo("TABLE") == 0) {
+            Stmts.sSourceSelect = "SELECT * FROM "
+                                  + src.helper.formatName(Stmts.sSourceTable);
+        } else if (Stmts.sType.compareTo("VIEW") == 0) {
+            Stmts.sSourceSelect = "";
+        }
+    }
+
+    void setDest(String _Schema, DataAccessPoint dest) throws Exception {
+
+        destDb = dest;
+
+        dest.helper.setSchema(_Schema);
+    }
+
+    /**
+     * extractTableStructure
+     *
+     * @param Source
+     * @param Destination
+     * @throws Exception
+     */
+    void extractTableStructure(DataAccessPoint Source,
+                               DataAccessPoint Destination) throws Exception {
+        initTypes();
+        Source.getTableStructure(this, Destination);
+    }
+
+    /**
+     * @throws SQLException
+     */
+    void transferStructure() throws Exception {
+
+        String Statement = new String("");
+
+        if (destDb.helper.needTransferTransaction()) {
+            try {
+                destDb.setAutoCommit(false);
+            } catch (Exception e) {}
+        }
+
+        if (Stmts.bTransfer == false) {
+            tracer.trace("Table " + Stmts.sSourceTable + " not transfered");
+
+            return;
+        }
+
+        tracer.trace("Table " + Stmts.sSourceTable + ": start transfer");
+
+        try {
+            if (Stmts.bDropIndex) {
+                if (Stmts.sDestDropIndex.charAt(Stmts.sDestDropIndex.length()
+                                                - 1) != ';') {
+                    Stmts.sDestDropIndex += ";";
+                }
+
+                int lastsemicolon = 0;
+                int nextsemicolon = Stmts.sDestDropIndex.indexOf(';');
+
+                while (nextsemicolon > lastsemicolon) {
+                    Statement = Stmts.sDestDropIndex.substring(lastsemicolon,
+                            nextsemicolon);
+
+                    while (Statement.charAt(Statement.length() - 1) == ';') {
+                        Statement = Statement.substring(0, Statement.length()
+                                                        - 1);
+                    }
+
+                    try {
+                        tracer.trace("Executing " + Statement);
+                        destDb.execute(Statement);
+                    } catch (Exception e) {
+                        tracer.trace("Ignoring error " + e.getMessage());
+                    }
+
+                    lastsemicolon = nextsemicolon + 1;
+                    nextsemicolon = lastsemicolon
+                                    + Stmts.sDestDropIndex.substring(
+                                        lastsemicolon).indexOf(';');
+                }
+            }
+
+            if (Stmts.bDelete) {
+                if (Stmts.sDestDelete.charAt(Stmts.sDestDelete.length() - 1)
+                        != ';') {
+                    Stmts.sDestDelete += ";";
+                }
+
+                int lastsemicolon = 0;
+                int nextsemicolon = Stmts.sDestDelete.indexOf(';');
+
+                while (nextsemicolon > lastsemicolon) {
+                    Statement = Stmts.sDestDelete.substring(lastsemicolon,
+                            nextsemicolon);
+
+                    while (Statement.charAt(Statement.length() - 1) == ';') {
+                        Statement = Statement.substring(0, Statement.length()
+                                                        - 1);
+                    }
+
+                    try {
+                        tracer.trace("Executing " + Statement);
+                        destDb.execute(Statement);
+                    } catch (Exception e) {
+                        tracer.trace("Ignoring error " + e.getMessage());
+                    }
+
+                    lastsemicolon = nextsemicolon + 1;
+                    nextsemicolon = lastsemicolon
+                                    + Stmts.sDestDelete.substring(
+                                        lastsemicolon).indexOf(';');
+                }
+            }
+
+            if (Stmts.bDrop) {
+                if (Stmts.sDestDrop.charAt(Stmts.sDestDrop.length() - 1)
+                        != ';') {
+                    Stmts.sDestDrop += ";";
+                }
+
+                int lastsemicolon = 0;
+                int nextsemicolon = Stmts.sDestDrop.indexOf(';');
+
+                while (nextsemicolon > lastsemicolon) {
+                    Statement = Stmts.sDestDrop.substring(lastsemicolon,
+                                                          nextsemicolon);
+
+                    while (Statement.charAt(Statement.length() - 1) == ';') {
+                        Statement = Statement.substring(0, Statement.length()
+                                                        - 1);
+                    }
+
+                    try {
+                        tracer.trace("Executing " + Statement);
+                        destDb.execute(Statement);
+                    } catch (Exception e) {
+                        tracer.trace("Ignoring error " + e.getMessage());
+                    }
+
+                    lastsemicolon = nextsemicolon + 1;
+                    nextsemicolon = lastsemicolon
+                                    + Stmts.sDestDrop.substring(
+                                        lastsemicolon).indexOf(';');
+                }
+            }
+
+            if (Stmts.bCreate) {
+                if (Stmts.sDestCreate.charAt(Stmts.sDestCreate.length() - 1)
+                        != ';') {
+                    Stmts.sDestCreate += ";";
+                }
+
+                int lastsemicolon = 0;
+                int nextsemicolon = Stmts.sDestCreate.indexOf(';');
+
+                while (nextsemicolon > lastsemicolon) {
+                    Statement = Stmts.sDestCreate.substring(lastsemicolon,
+                            nextsemicolon);
+
+                    while (Statement.charAt(Statement.length() - 1) == ';') {
+                        Statement = Statement.substring(0, Statement.length()
+                                                        - 1);
+                    }
+
+                    tracer.trace("Executing " + Statement);
+                    destDb.execute(Statement);
+
+                    lastsemicolon = nextsemicolon + 1;
+                    nextsemicolon = lastsemicolon
+                                    + Stmts.sDestCreate.substring(
+                                        lastsemicolon).indexOf(';');
+                }
+            }
+        } catch (Exception e) {
+            try {
+                if (!destDb.getAutoCommit()) {
+                    destDb.rollback();
+                }
+            } catch (Exception e1) {}
+
+            throw (e);
+        }
+
+        if (!destDb.getAutoCommit()) {
+            destDb.commit();
+
+            try {
+                destDb.setAutoCommit(true);
+            } catch (Exception e) {}
+        }
+    }
+
+    void transferData(int iMaxRows) throws Exception, SQLException {
+
+        if (destDb.helper.needTransferTransaction()) {
+            try {
+                destDb.setAutoCommit(false);
+            } catch (Exception e) {}
+        }
+
+        try {
+            if (Stmts.bInsert) {
+                if (destDb.helper.needTransferTransaction()) {
+                    try {
+                        destDb.setAutoCommit(false);
+                    } catch (Exception e) {}
+                }
+
+                tracer.trace("Executing " + Stmts.sSourceSelect);
+
+                TransferResultSet r = sourceDb.getData(Stmts.sSourceSelect);
+
+                tracer.trace("Start transfering data...");
+                destDb.beginDataTransfer();
+                tracer.trace("Executing " + Stmts.sDestInsert);
+                destDb.putData(Stmts.sDestInsert, r, iMaxRows);
+                destDb.endDataTransfer();
+                tracer.trace("Finished");
+
+                if (!destDb.getAutoCommit()) {
+                    destDb.commit();
+
+                    try {
+                        destDb.setAutoCommit(true);
+                    } catch (Exception e) {}
+                }
+            }
+        } catch (Exception e) {
+            try {
+                if (!destDb.getAutoCommit()) {
+                    destDb.rollback();
+                }
+            } catch (Exception e1) {}
+
+            throw (e);
+        }
+
+        if (!destDb.getAutoCommit()) {
+            destDb.commit();
+
+            try {
+                destDb.setAutoCommit(true);
+            } catch (Exception e) {}
+        }
+    }
+
+    void transferAlter() throws Exception {
+
+        String Statement = new String("");
+
+        if (destDb.helper.needTransferTransaction()) {
+            try {
+                destDb.setAutoCommit(false);
+            } catch (Exception e) {}
+        }
+
+        if (Stmts.bTransfer == false) {
+            tracer.trace("Table " + Stmts.sSourceTable + " not transfered");
+
+            return;
+        }
+
+        tracer.trace("Table " + Stmts.sSourceTable + ": start alter");
+
+        try {
+            if (Stmts.bCreateIndex) {
+                if (Stmts.sDestCreateIndex.charAt(
+                        Stmts.sDestCreateIndex.length() - 1) != ';') {
+                    Stmts.sDestCreateIndex += ";";
+                }
+
+                int lastsemicolon = 0;
+                int nextsemicolon = Stmts.sDestCreateIndex.indexOf(';');
+
+                while (nextsemicolon > lastsemicolon) {
+                    Statement = Stmts.sDestCreateIndex.substring(lastsemicolon,
+                            nextsemicolon);
+
+                    while (Statement.charAt(Statement.length() - 1) == ';') {
+                        Statement = Statement.substring(0, Statement.length()
+                                                        - 1);
+                    }
+
+                    try {
+                        tracer.trace("Executing " + Stmts.sDestCreateIndex);
+                        destDb.execute(Statement);
+                    } catch (Exception e) {
+                        tracer.trace("Ignoring error " + e.getMessage());
+                    }
+
+                    lastsemicolon = nextsemicolon + 1;
+                    nextsemicolon = lastsemicolon
+                                    + Stmts.sDestCreateIndex.substring(
+                                        lastsemicolon).indexOf(';');
+                }
+            }
+
+            if (Stmts.bAlter) {
+                if (Stmts.sDestAlter.charAt(Stmts.sDestAlter.length() - 1)
+                        != ';') {
+                    Stmts.sDestAlter += ";";
+                }
+
+                int lastsemicolon = 0;
+                int nextsemicolon = Stmts.sDestAlter.indexOf(';');
+
+                while (nextsemicolon > lastsemicolon) {
+                    Statement = Stmts.sDestAlter.substring(lastsemicolon,
+                                                           nextsemicolon);
+
+                    while (Statement.charAt(Statement.length() - 1) == ';') {
+                        Statement = Statement.substring(0, Statement.length()
+                                                        - 1);
+                    }
+
+                    try {
+                        tracer.trace("Executing " + Statement);
+                        destDb.execute(Statement);
+                    } catch (Exception e) {
+                        tracer.trace("Ignoring error " + e.getMessage());
+                    }
+
+                    lastsemicolon = nextsemicolon + 1;
+                    nextsemicolon = lastsemicolon
+                                    + Stmts.sDestAlter.substring(
+                                        lastsemicolon).indexOf(';');
+                }
+            }
+        } catch (Exception e) {
+            try {
+                if (!destDb.getAutoCommit()) {
+                    destDb.rollback();
+                }
+            } catch (Exception e1) {}
+
+            throw (e);
+        }
+
+        if (!destDb.getAutoCommit()) {
+            destDb.commit();
+
+            try {
+                destDb.setAutoCommit(true);
+            } catch (Exception e) {}
+        }
+    }
+
+    private void initTypes() throws SQLException {
+
+        if (hTypes != null) {
+            return;
+        }
+
+        hTypes = destDb.helper.getSupportedTypes();
+    }
+}
diff --git a/src/org/hsqldb/util/Tree.java b/src/org/hsqldb/util/Tree.java
new file mode 100644
index 0000000..a888cbd
--- /dev/null
+++ b/src/org/hsqldb/util/Tree.java
@@ -0,0 +1,536 @@
+/*
+ * For work developed by the HSQL Development Group:
+ *
+ * Copyright (c) 2001-2010, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ * For work originally developed by the Hypersonic SQL Group:
+ *
+ * Copyright (c) 1995-2000, The Hypersonic SQL Group.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Hypersonic SQL Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Hypersonic SQL Group.
+ */
+
+
+package org.hsqldb.util;
+
+import java.util.Vector;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Panel;
+import java.awt.Scrollbar;
+import java.awt.SystemColor;
+import java.awt.Toolkit;
+
+/**
+ *
+ * @author Thomas Mueller (Hypersonic SQL Group)
+ * @version 1.7.0
+ * @since Hypersonic SQL
+ */
+class Tree extends Panel {
+
+    // static
+    private static Font        fFont;
+    private static FontMetrics fMetrics;
+    private static int         iRowHeight;
+    private static int         iIndentWidth;
+    private int                iMaxTextLength;
+
+    // drawing
+    private Dimension dMinimum;
+    private Graphics  gImage;
+    private Image     iImage;
+
+    // height / width
+    private int iWidth, iHeight;
+    private int iFirstRow;
+    private int iTreeWidth, iTreeHeight;
+    private int iX, iY;
+
+    // data
+    private Vector vData;
+    private int    iRowCount;
+
+    // scrolling
+    private Scrollbar sbHoriz, sbVert;
+    private int       iSbWidth, iSbHeight;
+
+    static {
+        fFont        = new Font("Dialog", Font.PLAIN, 12);
+        fMetrics     = Toolkit.getDefaultToolkit().getFontMetrics(fFont);
+        iRowHeight   = getMaxHeight(fMetrics);
+        iIndentWidth = 12;
+    }
+
+    /**
+     * Constructor declaration
+     *
+     */
+    Tree() {
+
+        super();
+
+        vData = new Vector();
+
+        setLayout(null);
+
+        sbHoriz = new Scrollbar(Scrollbar.HORIZONTAL);
+
+        add(sbHoriz);
+
+        sbVert = new Scrollbar(Scrollbar.VERTICAL);
+
+        add(sbVert);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param d
+     */
+    public void setMinimumSize(Dimension d) {
+        dMinimum = d;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param x
+     * @param y
+     * @param w
+     * @param h
+     */
+
+// fredt@users 20011210 - patch 450412 by elise@users
+// with additional replacement of deprecated methods
+    public void setBounds(int x, int y, int w, int h) {
+
+        super.setBounds(x, y, w, h);
+
+        iSbHeight = sbHoriz.getPreferredSize().height;
+        iSbWidth  = sbVert.getPreferredSize().width;
+        iHeight   = h - iSbHeight;
+        iWidth    = w - iSbWidth;
+
+        sbHoriz.setBounds(0, iHeight, iWidth, iSbHeight);
+        sbVert.setBounds(iWidth, 0, iSbWidth, iHeight);
+        adjustScroll();
+
+        iImage = null;
+
+        repaint();
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    public void removeAll() {
+
+        vData     = new Vector();
+        iRowCount = 0;
+
+        adjustScroll();
+
+        iMaxTextLength = 10;
+
+        repaint();
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param key
+     * @param value
+     * @param state
+     * @param color
+     */
+    public void addRow(String key, String value, String state, int color) {
+
+        String[] row = new String[4];
+
+        if (value == null) {
+            value = "";
+        }
+
+        row[0] = key;
+        row[1] = value;
+        row[2] = state;    // null / "-" / "+"
+        row[3] = String.valueOf(color);
+
+        vData.addElement(row);
+
+        int len = fMetrics.stringWidth(value);
+
+        if (len > iMaxTextLength) {
+            iMaxTextLength = len;
+        }
+
+        iRowCount++;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param key
+     * @param value
+     */
+    public void addRow(String key, String value) {
+        addRow(key, value, null, 0);
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    public void update() {
+        adjustScroll();
+        repaint();
+    }
+
+    /**
+     * Method declaration
+     *
+     */
+    void adjustScroll() {
+
+        iTreeHeight = iRowHeight * (iRowCount + 1);
+
+        // correct would be iMaxTextLength + iMaxIndent*iIndentWidth
+        iTreeWidth = iMaxTextLength * 2;
+
+        sbHoriz.setValues(iX, iWidth, 0, iTreeWidth);
+
+        int v = iY / iRowHeight,
+            h = iHeight / iRowHeight;
+
+        sbVert.setValues(v, h, 0, iRowCount + 1);
+
+        iX = sbHoriz.getValue();
+        iY = iRowHeight * sbVert.getValue();
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     */
+
+// fredt@users 20020130 - comment by fredt
+// to remove this deprecated method we need to rewrite the Tree class as a
+// ScrollPane component
+    public boolean handleEvent(Event e) {
+
+        switch (e.id) {
+
+            case Event.SCROLL_LINE_UP :
+            case Event.SCROLL_LINE_DOWN :
+            case Event.SCROLL_PAGE_UP :
+            case Event.SCROLL_PAGE_DOWN :
+            case Event.SCROLL_ABSOLUTE :
+                iX = sbHoriz.getValue();
+                iY = iRowHeight * sbVert.getValue();
+
+                repaint();
+
+                return true;
+        }
+
+        return super.handleEvent(e);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param g
+     */
+    public void paint(Graphics g) {
+
+        if (g == null || iWidth <= 0 || iHeight <= 0) {
+            return;
+        }
+
+        g.setColor(SystemColor.control);
+        g.fillRect(iWidth, iHeight, iSbWidth, iSbHeight);
+
+        if (iImage == null) {
+            iImage = createImage(iWidth, iHeight);
+            gImage = iImage.getGraphics();
+
+            gImage.setFont(fFont);
+        }
+
+        gImage.setColor(Color.white);
+        gImage.fillRect(0, 0, iWidth, iHeight);
+
+        int[]    lasty = new int[100];
+        String[] root  = new String[100];
+
+        root[0] = "";
+
+        int currentindent = 0;
+        int y             = iRowHeight;
+
+        y -= iY;
+
+        boolean closed = false;
+
+        for (int i = 0; i < iRowCount; i++) {
+            String[] s      = (String[]) vData.elementAt(i);
+            String   key    = s[0];
+            String   data   = s[1];
+            String   folder = s[2];
+            int      ci     = currentindent;
+
+            for (; ci > 0; ci--) {
+                if (key.startsWith(root[ci])) {
+                    break;
+                }
+            }
+
+            if (root[ci].length() < key.length()) {
+                ci++;
+            }
+
+            if (closed && ci > currentindent) {
+                continue;
+            }
+
+            closed   = folder != null && folder.equals("+");
+            root[ci] = key;
+
+            int x = iIndentWidth * ci - iX;
+
+            gImage.setColor(Color.lightGray);
+            gImage.drawLine(x, y, x + iIndentWidth, y);
+            gImage.drawLine(x, y, x, lasty[ci]);
+
+            lasty[ci + 1] = y;
+
+            int py = y + iRowHeight / 3;
+            int px = x + iIndentWidth * 2;
+
+            if (folder != null) {
+                lasty[ci + 1] += 4;
+
+                int rgb = Integer.parseInt(s[3]);
+
+                gImage.setColor(rgb == 0 ? Color.white
+                                         : new Color(rgb));
+                gImage.fillRect(x + iIndentWidth - 3, y - 3, 7, 7);
+                gImage.setColor(Color.black);
+                gImage.drawRect(x + iIndentWidth - 4, y - 4, 8, 8);
+                gImage.drawLine(x + iIndentWidth - 2, y,
+                                x + iIndentWidth + 2, y);
+
+                if (folder.equals("+")) {
+                    gImage.drawLine(x + iIndentWidth, y - 2,
+                                    x + iIndentWidth, y + 2);
+                }
+            } else {
+                px -= iIndentWidth;
+            }
+
+            gImage.setColor(Color.black);
+            gImage.drawString(data, px, py);
+
+            currentindent = ci;
+            y             += iRowHeight;
+        }
+
+        g.drawImage(iImage, 0, 0, this);
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param g
+     */
+    public void update(Graphics g) {
+        paint(g);
+    }
+
+    /**
+     * Method declaration
+     */
+    public Dimension preferredSize() {
+        return dMinimum;
+    }
+
+    /**
+     * Method declaration
+     */
+    public Dimension getPreferredSize() {
+        return dMinimum;
+    }
+
+    /**
+     * Method declaration
+     */
+    public Dimension getMinimumSize() {
+        return dMinimum;
+    }
+
+    /**
+     * Method declaration
+     */
+    public Dimension minimumSize() {
+        return dMinimum;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param e
+     * @param x
+     * @param y
+     */
+    public boolean mouseDown(Event e, int x, int y) {
+
+        if (iRowHeight == 0 || x > iWidth || y > iHeight) {
+            return true;
+        }
+
+        y += iRowHeight / 2;
+
+        String[] root = new String[100];
+
+        root[0] = "";
+
+        int     currentindent = 0;
+        int     cy            = iRowHeight;
+        boolean closed        = false;
+        int     i             = 0;
+
+        y += iY;
+
+        for (; i < iRowCount; i++) {
+            String[] s      = (String[]) vData.elementAt(i);
+            String   key    = s[0];
+            String   folder = s[2];
+            int      ci     = currentindent;
+
+            for (; ci > 0; ci--) {
+                if (key.startsWith(root[ci])) {
+                    break;
+                }
+            }
+
+            if (root[ci].length() < key.length()) {
+                ci++;
+            }
+
+            if (closed && ci > currentindent) {
+                continue;
+            }
+
+            if (cy <= y && cy + iRowHeight > y) {
+                break;
+            }
+
+            root[ci]      = key;
+            closed        = folder != null && folder.equals("+");
+            currentindent = ci;
+            cy            += iRowHeight;
+        }
+
+        if (i >= 0 && i < iRowCount) {
+            String[] s      = (String[]) vData.elementAt(i);
+            String   folder = s[2];
+
+            if (folder != null && folder.equals("+")) {
+                folder = "-";
+            } else if (folder != null && folder.equals("-")) {
+                folder = "+";
+            }
+
+            s[2] = folder;
+
+            vData.setElementAt(s, i);
+            repaint();
+        }
+
+        return true;
+    }
+
+    /**
+     * Method declaration
+     *
+     *
+     * @param f
+     */
+    private static int getMaxHeight(FontMetrics f) {
+        return f.getHeight() + 2;
+    }
+}
diff --git a/src/org/hsqldb/util/hsqldb.gif b/src/org/hsqldb/util/hsqldb.gif
new file mode 100644
index 0000000..3585222
--- /dev/null
+++ b/src/org/hsqldb/util/hsqldb.gif
Binary files differ
diff --git a/src/org/hsqldb/util/hsqldbtab.gif b/src/org/hsqldb/util/hsqldbtab.gif
new file mode 100644
index 0000000..5130580
--- /dev/null
+++ b/src/org/hsqldb/util/hsqldbtab.gif
Binary files differ
diff --git a/src/org/hsqldb/util/preprocessor/AntResolver.java b/src/org/hsqldb/util/preprocessor/AntResolver.java
new file mode 100644
index 0000000..33bab7b
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/AntResolver.java
@@ -0,0 +1,62 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+import java.io.File;
+import org.apache.tools.ant.Project;
+
+/* $Id: AntResolver.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Resolves properties and paths using an ANT Project.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+class AntResolver implements IResolver {
+
+    private Project project;
+
+    /** Creates a new instance of AntResolver */
+    public AntResolver(Project project) {
+        this.project = project;
+    }
+
+    public String resolveProperties(String expression) {
+        return this.project.replaceProperties(expression);
+    }
+
+    public File resolveFile(String path) {
+        return this.project.resolveFile(path);
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/BasicResolver.java b/src/org/hsqldb/util/preprocessor/BasicResolver.java
new file mode 100644
index 0000000..057f80b
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/BasicResolver.java
@@ -0,0 +1,81 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+import java.io.File;
+import java.io.IOException;
+
+/* $Id: BasicResolver.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Resolves paths using a parent directory; does not resolve properties.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+class BasicResolver implements IResolver {
+    File parentDir;
+
+    public BasicResolver(File parentDir) {
+        this.parentDir = parentDir;
+    }
+
+    public String resolveProperties(String expression) {
+        return expression;
+    }
+    public File resolveFile(String path) {
+        File file = new File(path);
+
+        if (parentDir != null && !file.isAbsolute()) {
+            try {
+                path = this.parentDir.getCanonicalPath()
+                       + File.separatorChar
+                       + path;
+
+                file = new File(path);
+            } catch (IOException ex) {
+                path = this.parentDir.getAbsolutePath()
+                       + File.separatorChar
+                       + path;
+
+                file = new File(path);
+            }
+        }
+
+        try {
+            return file.getCanonicalFile();
+        } catch (Exception e) {
+            return file.getAbsoluteFile();
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/Defines.java b/src/org/hsqldb/util/preprocessor/Defines.java
new file mode 100644
index 0000000..6b3e795
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/Defines.java
@@ -0,0 +1,202 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+import java.util.Hashtable;
+
+/* $Id: Defines.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Simple preprocessor symbol table.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+class Defines {
+    private Hashtable symbols = new Hashtable();
+
+    public Defines() {}
+
+    public Defines(String csvExpressions) throws PreprocessorException {
+        defineCSV(csvExpressions);
+    }
+
+    public void clear() {
+        this.symbols.clear();
+    }
+
+    public void defineCSV(String csvExpressions)
+    throws PreprocessorException {
+        if (csvExpressions != null) {
+            csvExpressions = csvExpressions + ',';
+
+            int start = 0;
+            int len   = csvExpressions.length();
+
+            while (start < len) {
+                int    end  = csvExpressions.indexOf(',', start);
+                String expr = csvExpressions.substring(start, end).trim();
+
+                if (expr.length() > 0) {
+                    defineSingle(expr);
+                }
+
+                start = end + 1;
+            }
+        }
+    }
+
+    public void defineSingle(String expression) throws PreprocessorException {
+        Tokenizer tokenizer = new Tokenizer(expression);
+
+        tokenizer.next();
+
+        if (!tokenizer.isToken(Token.IDENT)) {
+            throw new PreprocessorException("IDENT token required at position: "
+                    + tokenizer.getStartIndex()
+                    + " in ["
+                    + expression +
+                    "]"); // NOI18N
+        }
+
+        String ident = tokenizer.getIdent();
+
+        int tokenType = tokenizer.next();
+
+        switch(tokenType) {
+            case Token.EOI : {
+                this.symbols.put(ident, ident);
+                return;
+            }
+            case Token.ASSIGN : {
+                tokenType = tokenizer.next();
+                break;
+            }
+            default : {
+                break;
+            }
+        }
+
+        switch(tokenType) {
+            case Token.NUMBER : {
+                Number number = tokenizer.getNumber();
+
+                this.symbols.put(ident, number);
+
+                break;
+            }
+            case Token.STRING : {
+                String string = tokenizer.getString();
+
+                this.symbols.put(ident, string);
+
+                break;
+            }
+            case Token.IDENT : {
+                String rhsIdent = tokenizer.getIdent();
+
+                if (!isDefined(rhsIdent)) {
+                    throw new PreprocessorException("Right hand side" +
+                            "IDENT token [" + rhsIdent + "] at position: "
+                            + tokenizer.getStartIndex()
+                            + " is undefined in ["
+                            + expression
+                            + "]"); // NOI18N
+                }
+
+                Object value = this.symbols.get(rhsIdent);
+
+                symbols.put(ident, value);
+                break;
+            }
+            default : {
+                throw new PreprocessorException("Right hand side NUMBER,"
+                        + "STRING or IDENT token required at position: " +
+                        + tokenizer.getStartIndex()
+                        + " in ["
+                        + expression
+                        + "]"); // NOI18N
+            }
+        }
+
+        tokenizer.next();
+
+        if (!tokenizer.isToken(Token.EOI)) {
+            throw new PreprocessorException("Illegal trailing "
+                    + "characters at position: "
+                    + tokenizer.getStartIndex()
+                    + " in ["
+                    + expression
+                    + "]"); // NOI18N
+        }
+
+        return;
+    }
+
+    public void undefine(String symbol) {
+        this.symbols.remove(symbol);
+    }
+
+    public boolean isDefined(String symbol) {
+        return this.symbols.containsKey(symbol);
+    }
+
+    public Object getDefintion(String symbol) {
+        return this.symbols.get(symbol);
+    }
+
+    public boolean evaluate(String expression) throws PreprocessorException {
+        Tokenizer tokenizer = new Tokenizer(expression);
+
+        tokenizer.next();
+
+        Parser parser = new Parser(this, tokenizer);
+
+        boolean result = parser.parseExpression();
+
+        if (!tokenizer.isToken(Token.EOI)) {
+            throw new PreprocessorException("Illegal trailing "
+                    + "characters at position: "
+                    + tokenizer.getStartIndex()
+                    + " in ["
+                    + expression
+                    + "]"); // NOI18N
+        }
+
+        return result;
+    }
+
+    public String toString() {
+        return super.toString() + this.symbols.toString();
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/Document.java b/src/org/hsqldb/util/preprocessor/Document.java
new file mode 100644
index 0000000..25604fa
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/Document.java
@@ -0,0 +1,292 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Vector;
+
+/* $Id: Document.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Simple line-oriented text document ADT.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+class Document {
+    Vector lines = new Vector();
+
+    Document() {}
+
+    Document(Document source) {
+        this.appendDocument(source);
+    }
+
+    Document addSouceLine(String line) {
+        if (line == null) {
+            throw new IllegalArgumentException("line: null");
+        }
+
+        this.lines.addElement(line);
+
+        return this;
+    }
+
+    Document appendDocument(Document doc) {
+        if (doc != null) {
+            int    count = doc.size();
+            Vector src   = doc.lines;
+            Vector dst   = this.lines;
+
+            for (int i = 0; i < count; i++) {
+                dst.addElement(src.elementAt(i));
+            }
+        }
+
+        return this;
+    }
+
+    Document clear() {
+        this.lines.removeAllElements();
+
+        return this;
+    }
+
+    boolean contains(String pattern) {
+        Vector lines = this.lines;
+        int    size  = lines.size();
+
+        for (int i = 0; i < size; i++) {
+            if (((String)lines.elementAt(i)).indexOf(pattern) >= 0) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    Document deleteSourceLine(int index) {
+        this.lines.removeElementAt(index);
+
+        return this;
+    }
+
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        } else if (o instanceof Document) {
+            Document other = (Document) o;
+
+            Vector v1 = this.lines;
+            Vector v2 = other.lines;
+
+            if (v1.size() != v2.size()) {
+                return false;
+            }
+
+            for (int i = v1.size() - 1; i >= 0; i--) {
+                if (v1.elementAt(i).equals(v2.elementAt(i))) {
+                    continue;
+                } else {
+                    return false;
+                }
+            }
+
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    String getSourceLine(int index) {
+        return (String) this.lines.elementAt(index);
+    }
+
+    Document insertSourceLine(int index, String line) {
+        if (line == null) {
+            throw new IllegalArgumentException("line: null");
+        }
+
+        this.lines.insertElementAt(line, index);
+
+        return this;
+    }
+
+    Document replaceWith(Document source) {
+        return this.clear().appendDocument(source);
+    }
+
+    Document setSourceLine(int index, String line) {
+        if (line == null) {
+            throw new IllegalArgumentException("null");
+        }
+
+        this.lines.setElementAt(line, index);
+
+        return this;
+    }
+
+    int size() {
+        return this.lines.size();
+    }
+
+// ------------------------ I/O convenience methods ----------------------------
+
+    Document load(Object source, String encoding) throws IOException,
+            UnsupportedEncodingException{
+        BufferedReader reader = null;
+        boolean        close  = false;
+
+        if (source instanceof InputStream) {
+            InputStream       is  = (InputStream) source;
+            InputStreamReader isr = isEncoding(encoding)
+                    ? new InputStreamReader(is, encoding)
+                    : new InputStreamReader(is);
+
+            reader = new BufferedReader(isr);
+        } else if (source instanceof File) {
+            InputStream       is  = new FileInputStream((File) source);
+            InputStreamReader isr = isEncoding(encoding)
+                    ? new InputStreamReader(is, encoding)
+                    : new InputStreamReader(is);
+
+            close  = true;
+            reader = new BufferedReader(isr);
+        } else if (source instanceof String) {
+            InputStream       is  = new FileInputStream((String) source);
+            InputStreamReader isr = isEncoding(encoding)
+                    ? new InputStreamReader(is, encoding)
+                    : new InputStreamReader(is);
+
+            close  = true;
+            reader = new BufferedReader(isr);
+        } else if (source instanceof BufferedReader) {
+            reader = (BufferedReader) source;
+        } else if (source instanceof Reader) {
+            reader = new BufferedReader((Reader) source);
+        } else {
+            throw new IOException("unhandled load source: " + source); // NOI18N
+        }
+
+        clear();
+
+        String line;
+        Vector lines = this.lines;
+
+        try {
+            while(null != (line = reader.readLine())) {
+                lines.addElement(line);
+            }
+        } finally {
+            if (close) {
+                try {
+                    reader.close();
+                } catch (IOException ex) {}
+            }
+        }
+
+        return this;
+    }
+
+    Document save(Object target, String encoding) throws IOException {
+        BufferedWriter writer = null;
+        boolean        close  = false;
+
+        if (target instanceof OutputStream) {
+            OutputStream       os  = (OutputStream) target;
+            OutputStreamWriter osr = isEncoding(encoding)
+                    ? new OutputStreamWriter(os, encoding)
+                    : new OutputStreamWriter(os);
+
+            writer = new BufferedWriter(osr);
+        } else if (target instanceof File) {
+            OutputStream       os  = new FileOutputStream((File) target);
+            OutputStreamWriter osr = isEncoding(encoding)
+                    ? new OutputStreamWriter(os, encoding)
+                    : new OutputStreamWriter(os);
+
+            close  = true;
+            writer = new BufferedWriter(osr);
+        } else if (target instanceof String) {
+            OutputStream       os  = new FileOutputStream((String) target);
+            OutputStreamWriter osr = isEncoding(encoding)
+                    ? new OutputStreamWriter(os, encoding)
+                    : new OutputStreamWriter(os);
+
+            close  = true;
+            writer = new BufferedWriter(osr);
+        } else if (target instanceof BufferedWriter) {
+            writer = (BufferedWriter) target;
+        } else if (target instanceof Writer) {
+            writer = new BufferedWriter(writer);
+        } else {
+            throw new IOException("unhandled save target: " + target); // NOI18N
+        }
+
+        Vector lines = this.lines;
+        int    count = lines.size();
+
+        try {
+            for (int i = 0; i < count; i++) {
+                writer.write((String)lines.elementAt(i));
+                writer.newLine();
+            }
+
+            writer.flush();
+        } finally {
+            if (close) {
+                try {
+                    writer.close();
+                } catch (IOException ex) {}
+            }
+        }
+
+        return this;
+    }
+
+    static boolean isEncoding(String enc) {
+        return enc != null && enc.trim().length() > 0;
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/IResolver.java b/src/org/hsqldb/util/preprocessor/IResolver.java
new file mode 100644
index 0000000..6dca467
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/IResolver.java
@@ -0,0 +1,54 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+import java.io.File;
+
+/* $Id: IResolver.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Property and file path resolution contract. <p>
+ *
+ * Implementations are free to ignore expansion directives and simply
+ * pass through expressions and paths unchanged. <p>
+ *
+ * If an implementation does process expansion directives, recognized forms
+ * should at least include the ubiquitous ${...} shell expansion form.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+public interface IResolver {
+    public String resolveProperties(String expression);
+    public File   resolveFile(String path);
+}
diff --git a/src/org/hsqldb/util/preprocessor/Line.java b/src/org/hsqldb/util/preprocessor/Line.java
new file mode 100644
index 0000000..c066e98
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/Line.java
@@ -0,0 +1,163 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+/* $Id: Line.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Preprocessor's view of a line in a text document.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+class Line  {
+    static final String DIRECTIVE_PREFIX = "//#";
+    static final String SPACE_CHARS = " \t";
+    static final int    DIRECTIVE_PREFIX_LENGTH = DIRECTIVE_PREFIX.length();
+    static final int    DIRECTIVE_PREFIX_LENGTH_PLUS_ONE =
+            DIRECTIVE_PREFIX_LENGTH + 1;
+    static final String HIDE_DIRECTIVE = DIRECTIVE_PREFIX + ' ';
+
+    int    type;
+    String sourceText;
+    String indent;
+    String text;
+    String arguments;
+
+    static int indexOfNonTabOrSpace(String line) {
+        int pos = 0;
+        int len = line.length();
+
+        while (pos < len) {
+            char ch = line.charAt(pos);
+
+            if ((ch == ' ') || (ch == '\t')) {
+                pos++;
+                continue;
+            }
+
+            break;
+        }
+
+        return pos;
+    }
+
+    static int indexOfTabOrSpace(String s, int fromIndex) {
+        int spos = s.indexOf(' ', fromIndex);
+        int tpos = s.indexOf('\t', fromIndex);
+
+        return (((tpos != -1) && (tpos < spos)) || (spos == -1)) ? tpos : spos;
+    }
+
+    Line(String line) throws PreprocessorException {
+        setSourceText(line);
+    }
+
+    void setSourceText(String line) throws PreprocessorException {
+        this.sourceText = line;
+        int pos         = indexOfNonTabOrSpace(line);
+        this.indent     = line.substring(0, pos);
+        line            = line.substring(pos);
+
+        if (!line.startsWith(DIRECTIVE_PREFIX)) {
+            this.text      = line;
+            this.arguments = null;
+            this.type      = LineType.VISIBLE;
+        } else if (line.length() == DIRECTIVE_PREFIX_LENGTH){
+            this.text      = "";
+            this.arguments = null;
+            this.type       = LineType.HIDDEN;
+        } else  if (SPACE_CHARS.indexOf(line.
+                charAt(DIRECTIVE_PREFIX_LENGTH)) != -1) {
+            this.text      = line.substring(DIRECTIVE_PREFIX_LENGTH_PLUS_ONE);
+            this.arguments = null;
+            this.type      = LineType.HIDDEN;
+        } else {
+            pos = indexOfTabOrSpace(line, DIRECTIVE_PREFIX_LENGTH_PLUS_ONE);
+
+            if (pos == -1) {
+                this.text      = line;
+                this.arguments = null;
+            } else {
+                this.text      = line.substring(0, pos);
+                this.arguments = line.substring(pos + 1).trim();
+            }
+
+            Integer oType = (Integer) LineType.directives().get(text);
+
+            if (oType == null) {
+                throw new PreprocessorException("Unknown directive ["
+                        + text + "] in [" + line + "]"); // NOI18N
+            }
+
+            this.type = oType.intValue();
+        }
+
+    }
+
+    String getArguments() throws PreprocessorException {
+        if (arguments == null || arguments.length() == 0) {
+            throw new PreprocessorException("["+ text
+                    + "]: has no argument(s)"); // NOI18N
+        }
+
+        return arguments;
+    }
+
+    String getSourceText() {
+        return sourceText;
+    }
+
+    String getIndent() {
+        return indent;
+    }
+
+    String getText() {
+        return text;
+    }
+
+    int getType() {
+        return type;
+    }
+
+    boolean isType(int lineType) {
+        return (this.type == lineType);
+    }
+
+    public String toString() {
+        return LineType.labels()[this.type] + "(" + this.type + "): indent ["
+                + this.indent + "] text [" + this.text
+                + ((this.arguments == null) ? "]" : ("] args ["
+                + this.arguments + "]")) ;
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/LineType.java b/src/org/hsqldb/util/preprocessor/LineType.java
new file mode 100644
index 0000000..ce06214
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/LineType.java
@@ -0,0 +1,128 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+import java.lang.reflect.Field;
+import java.util.Hashtable;
+import java.util.Locale;
+
+/* $Id: LineType.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Static methods and constants to decode preprocessor line types.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+class LineType {
+    //
+    static final int UNKNOWN    = 0;
+    static final int DEF        = 1;
+    static final int DEFINE     = 1;
+    static final int ELIF       = 2;
+    static final int ELIFDEF    = 3;
+    static final int ELIFNDEF   = 4;
+    static final int ELSE       = 5;
+    static final int ENDIF      = 6;
+    static final int ENDINCLUDE = 7;
+    static final int HIDDEN     = 8;
+    static final int IF         = 9;
+    static final int IFDEF      = 10;
+    static final int IFNDEF     = 11;
+    static final int INCLUDE    = 12;
+    static final int UNDEF      = 13;
+    static final int UNDEFINE   = 13;
+    static final int VISIBLE    = 14;
+
+    //
+    private static Hashtable directives;
+    private static String[]  labels;
+
+    static synchronized String[] labels() {
+        if (labels == null) {
+            init();
+        }
+
+        return labels;
+    }
+
+    static synchronized Hashtable directives() {
+        if (directives == null) {
+            init();
+        }
+
+        return directives;
+    }
+
+    private static void init() {
+
+        directives     = new Hashtable();
+        labels         = new String[17];
+        Field[] fields = LineType.class.getDeclaredFields();
+
+        for (int i = 0, j = 0; i < fields.length; i++) {
+            Field field = fields[i];
+
+            if (field.getType().equals(Integer.TYPE)) {
+                String label = field.getName();
+
+                try {
+                    int value = field.getInt(null);
+
+                    labels[value] = label;
+
+                    switch(value) {
+                        case VISIBLE :
+                        case HIDDEN : {
+                            // ignore
+                            break;
+                        }
+                        default : {
+                            String key = Line.DIRECTIVE_PREFIX
+                                    + label.toLowerCase(Locale.ENGLISH);
+
+                            directives.put(key, new Integer(value));
+
+                            break;
+                        }
+                    }
+
+                } catch (IllegalArgumentException ex) {
+                    // ex.printStackTrace();
+                } catch (IllegalAccessException ex) {
+                    // ex.printStackTrace();
+                }
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/Option.java b/src/org/hsqldb/util/preprocessor/Option.java
new file mode 100644
index 0000000..10e1098
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/Option.java
@@ -0,0 +1,101 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+/* $Id: Option.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Static methods and constants to decode preprocessor options.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+public class Option {
+
+    public static final int DEFAULT   = 0;    // No options set
+    public static final int BACKUP    = 1<<0; // Backup source files?
+    public static final int FILTER    = 1<<1; // Remove directive lines?
+    public static final int INDENT    = 1<<2; // indent directive lines?
+    public static final int TEST_ONLY = 1<<3; // process only; don't save
+    public static final int VERBOSE   = 1<<4; // log detailed info
+
+    private Option(){/*Construction Disabled*/}
+
+    public static boolean isDefault(int options) {
+        return options == DEFAULT;
+    }
+
+    public static int setDefault(int options, boolean _default) {
+        return (_default) ? DEFAULT : options;
+    }
+
+    public static boolean isBackup(int options) {
+        return ((options & BACKUP) != 0);
+    }
+
+    public static int setBackup(int options, boolean backup) {
+        return (backup) ? (options | BACKUP) : (options & ~BACKUP);
+    }
+
+    public static boolean isFilter(int options) {
+        return ((options & FILTER) != 0);
+    }
+
+    public static int setFilter(int options, boolean filter) {
+        return (filter) ? (options | FILTER) : (options & ~FILTER);
+    }
+
+    public static boolean isIndent(int options) {
+        return ((options & INDENT) != 0);
+    }
+
+    public static int setIndent(int options, boolean indent) {
+        return (indent) ? (options | INDENT) : (options & ~INDENT);
+    }
+
+    public static boolean isTestOnly(int options) {
+        return ((options & TEST_ONLY) != 0);
+    }
+
+    public static int setTestOnly(int options, boolean testOnly) {
+        return (testOnly) ? (options | TEST_ONLY) : (options & ~TEST_ONLY);
+    }
+
+    public static boolean isVerbose(int options) {
+        return ((options & VERBOSE) != 0);
+    }
+
+    public static int setVerbose(int options, boolean verbose) {
+        return (verbose) ? (options | VERBOSE) : (options & ~VERBOSE);
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/Parser.java b/src/org/hsqldb/util/preprocessor/Parser.java
new file mode 100644
index 0000000..27f9cfa
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/Parser.java
@@ -0,0 +1,277 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+/* $Id: Parser.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Simple preprocessor directive parser. <p>
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+class Parser  {
+
+    Defines   defines;
+    Tokenizer tokenizer;
+
+    Parser(Defines defines, Tokenizer tokenizer) {
+        this.defines   = defines;
+        this.tokenizer = tokenizer;
+    }
+
+    boolean parseExpression() throws PreprocessorException {
+        boolean result = parseTerm();
+
+        while (true) {
+            switch(this.tokenizer.getTokenType()) {
+                case Token.OR : {
+                    this.tokenizer.next();
+
+                    result = result | parseTerm();
+
+                    break;
+                }
+                case Token.XOR : {
+                    this.tokenizer.next();
+
+                    result = result ^ parseTerm();
+
+                    break;
+                }
+
+                default : {
+                    return result;
+                }
+            }
+        }
+    }
+
+    boolean parseTerm() throws PreprocessorException {
+        boolean result = parseFactor();
+
+        while (this.tokenizer.isToken(Token.AND)) {
+            this.tokenizer.next();
+
+            result = result & parseFactor();
+        }
+
+        return result;
+    }
+
+    boolean parseFactor() throws PreprocessorException {
+        boolean result;
+
+        switch(this.tokenizer.getTokenType()) {
+            case Token.IDENT : {
+                String ident = this.tokenizer.getIdent();
+                int    type  = this.tokenizer.next();
+
+                if ((type == Token.EOI) || (type == Token.RPAREN) ||
+                        Token.isLogicalOperator(type)) {
+                    result = this.defines.isDefined(ident);
+                } else if (Token.isComparisonOperator(type)) {
+                    result = parseComparison(ident, type);
+                } else {
+                    throw new PreprocessorException("Logical or comparison "
+                            + "operator token required at position "
+                            + this.tokenizer.getStartIndex()
+                            + " in ["
+                            + this.tokenizer.getSource()
+                            + "]"); // NOI18N
+                }
+
+                break;
+            }
+            case Token.NOT :{
+                this.tokenizer.next();
+
+                result = !parseFactor();
+
+                break;
+            }
+            case Token.LPAREN : {
+                this.tokenizer.next();
+
+                result = parseExpression();
+
+                if (!this.tokenizer.isToken(Token.RPAREN)) {
+                    throw new PreprocessorException("RPAREN token required at "
+                            + "position "
+                            + this.tokenizer.getStartIndex()
+                            + " in ["
+                            + this.tokenizer.getSource()
+                            + "]"); // NOI18N
+                }
+
+                this.tokenizer.next();
+
+                break;
+            }
+            default : {
+                throw new PreprocessorException("IDENT, NOT or LPAREN "
+                        + "token required at position "
+                        + this.tokenizer.getStartIndex()
+                        + " in ["
+                        + this.tokenizer.getSource()
+                        + "]"); // NOI18N
+            }
+        }
+
+        return result;
+    }
+
+    boolean parseComparison(String ident, int opType)
+    throws PreprocessorException {
+//        checkIsComparisonOperator(opType);
+
+        boolean result;
+        Object  lhs    = this.defines.getDefintion(ident);
+        int     pos    = this.tokenizer.getStartIndex();
+        Object  rhs    = parseValue();
+
+        if (lhs == null) {
+            throw new PreprocessorException("IDENT " + ident
+                    + " is not defined at position"
+                    + pos
+                    + "in ["
+                    + this.tokenizer.getSource()
+                    + "]"); // NOI18N
+        }
+
+        switch(opType) {
+            case Token.EQ :{
+                result = (compare(lhs, rhs) == 0);
+
+                break;
+            }
+            case Token.LT : {
+                result = (compare(lhs, rhs) < 0);
+
+                break;
+            }
+            case Token.LTE : {
+                result = (compare(lhs, rhs) <= 0);
+
+                break;
+            }
+            case Token.GT : {
+                result = (compare(lhs, rhs) > 0);
+
+                break;
+            }
+            case Token.GTE : {
+                result = (compare(lhs, rhs) >= 0);
+
+                break;
+            }
+            default : {
+                // Stupid compiler trick.
+                // Can't actually happen because this case will cause an
+                // exception to be thrown in method parseFactor (or in
+                // method checkIsComparisonOperator when uncommented)
+                throw new PreprocessorException("Internal error"); // NOI18N
+            }
+        }
+
+        this.tokenizer.next();
+
+        return result;
+    }
+
+//    void checkIsComparisonOperator(int opType) throws PreprocessorException {
+//        if (!Token.isComparisonOperator(opType)) {
+//                throw new PreprocessorException("Comparison "
+//                        + "operator token required at position "
+//                        + tokenizer.getBeginIndex()
+//                        + " in ["
+//                        + tokenizer.getSource()
+//                        + "]"); // NOI18N
+//        }
+//    }
+
+    static int compare(Object o1, Object o2) {
+        // nulls are basically 'illegal' so yes: 
+        // we want to throw NPE here if o1 or o2 is null
+        if (o1 instanceof Comparable) {
+            return (o1.getClass().isAssignableFrom(o2.getClass()))
+            ? ((Comparable)o1).compareTo(o2)
+            : String.valueOf(o1).compareTo(String.valueOf(o2));
+        } else {
+            return o1.toString().compareTo(o2.toString());
+        }
+    }
+
+    Object parseValue() throws PreprocessorException {
+        Object value;
+
+        switch(this.tokenizer.next()) {
+            case Token.IDENT : {
+                String ident = this.tokenizer.getIdent();
+
+                value = this.defines.getDefintion(ident);
+
+                if (value == null) {
+                    throw new PreprocessorException("IDENT " + ident
+                            + " is not defined at position"
+                            + this.tokenizer.getStartIndex()
+                            + "in ["
+                            + this.tokenizer.getSource()
+                            + "]"); // NOI18N
+                }
+
+                break;
+            }
+            case Token.STRING : {
+                value = this.tokenizer.getString();
+
+                break;
+            }
+            case Token.NUMBER : {
+                value = this.tokenizer.getNumber();
+
+                break;
+            }
+            default :{
+                throw new PreprocessorException("IDENT, STRING"
+                        + "or NUMBER token required at position "
+                        + this.tokenizer.getStartIndex()
+                        + " in: ["
+                        + this.tokenizer.getSource()
+                        + "]"); // NOI18N
+            }
+        }
+
+        return value;
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/Preprocessor.java b/src/org/hsqldb/util/preprocessor/Preprocessor.java
new file mode 100644
index 0000000..8f28e6c
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/Preprocessor.java
@@ -0,0 +1,738 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Stack;
+
+/* $Id: Preprocessor.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Simple text document preprocessor. <p>
+ *
+ * Aims specifically at transforming the HSQLDB codebase to one of a small
+ * number of specific build targets, while keeping complexity and external
+ * dependencies to a minimum, yet providing an environment that is
+ * sufficiently powerful to solve most easily imaginable preprocessing
+ * scenarios.
+ *
+ * Supports the following (case-sensitive) directives: <p>
+ *
+ * <ul>
+ *  <li>//#def[ine] IDENT (ASSIGN? (STRING | NUMBER | IDENT) )?
+ *  <li>//#elif BOOLEXPR
+ *  <li>//#elifdef IDENT
+ *  <li>//#elifndef IDENT
+ *  <li>//#else
+ *  <li>//#endif
+ *  <li>//#endinclude
+ *  <li>//#if BOOLEXPR
+ *  <li>//#ifdef IDENT
+ *  <li>//#ifndef IDENT
+ *  <li>//#include FILEPATH
+ *  <li>//#undef[ine] IDENT
+ * </ul>
+ *
+ * where BOOLEXPR is:
+ *
+ * <pre>
+ * ( IDENT
+ * | IDENT ( EQ |  LT | LTE | GT | GTE ) VALUE
+ * | BOOLEXPR { OR | XOR | AND } BOOLEXPR
+ * | NOT BOOLEXPR
+ * | LPAREN BOOLEXPR RPAREN )
+ *</pre>
+ *
+ * and VALUE is :
+ *
+ * <pre>
+ * ( STRING
+ * | NUMBER
+ * | IDENT )
+ * </pre>
+ *
+ * and lexographic elements are :
+ *
+ * <pre>
+ * ASSIGN     : '='
+ * EQ         : '=='
+ * LT         : '<'
+ * LTE        : '<='
+ * GT         : '>'
+ * GTE        : '>='
+ * OR         : ('|' | '||')
+ * XOR        : '^'
+ * AND        : ('&' | '&&')
+ * NOT        : '!'
+ * DQUOTE     : '"'
+ * LPAREN     : '('
+ * RPAREN     : ')'
+ * DOT        : '.'
+ * DIGIT      : ['0'..'9']
+ * EOL        : ('\n' | '\r' | '\n\r')
+ * SPACE      : (' ' | '\t')
+ * NON_DQUOTE : { ANY_UNICODE_CHARACTER_EXCEPT_DQUOTE_OR_EOL } -- see the unicode spec
+ * NON_SPACE  : { ANY_UNICODE_CHARACTER_EXCEPT_SPACE_OR_EOL }  -- see the unicode spec
+ * WS         : { JAVA_WS } -- see java.lang.Character
+ * NON_WS     : { ANY_UNICODE_CHARACTER_EXCEPT_WS_OR_EOL }
+ * STRING     : DQUOTE NON_DQUOTE* DQUOTE
+ * NUMBER     : DIGIT+ (DOT DIGIT*)?
+ * IDENT      : JAVA_IDENT_START JAVA_IDENT_PART*              -- see java.lang.Character
+ * FILEPATH   : NON_SPACE (ANY_UNICODE_CHARACTER* NON_WS)?     -- i.e. trailing SPACE elements are ignored
+ * </pre>
+ *
+ * The lexographic definitions above use the BNF conventions :
+ *
+ * <pre>
+ * '?' -> zero or one
+ * '*' -> zero or more
+ * '+' -> one or more
+ * </pre>
+ *
+ * Directives may be arbitrarily indented; there is an option (INDENT) to set
+ * or unset directive indentation on output. There is also an option (FILTER)
+ * to remove directive lines from output.  See {@link Option Option} for other
+ * preprocessor options. <p>
+ *
+ * '//#ifxxx' directives may be nested to arbitrary depth,
+ * may be chained with an arbitrary number of '//#elifxxx' directives,
+ * may be optionally followed by a single '//#else' directive, and
+ * must be terminated by a single '//#endif' directive. <p>
+ *
+ * Each '//#include' directive must be terminated by an '//#endinclude'
+ * directive; lines between '//#include' and '//#endinclude' are replaced
+ * by the content retrieved from the specified FILEPATH. <p>
+ *
+ * Included files are preprocessed in a nested scope that inherits the
+ * defined symbols of the including scope. Directive lines in included files
+ * are always excluded from output. <p>
+ *
+ * <b>Design Notes</b><p>
+ *
+ * There are many better/more sophisticated preprocessors/templating
+ * engines out there.  FreeMaker and Velocity come to mind immediately.
+ * Another--the NetBeans MIDP preprocessor--was the direct inspiration for
+ * this class. <p>
+ *
+ * Other options were rejected because the work of creating this class appeared
+ * to be less than dealing with the complexity and dependency issues of hooking
+ * up to external libraries.
+ *
+ * The NetBeans preprocessor, in particular, was rejected because it was
+ * not immediately evident how to invoke it independently from the IDE,
+ * how to make it available to non-MIDP projects from within the IDE or how to
+ * isolate the correct OpenIDE jars to allow stand-alone operation. <p>
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+public class Preprocessor {
+
+    // =========================================================================
+    // ------------------------------- Public API ------------------------------
+    // =========================================================================
+
+    /**
+     * Preprocesses the specified list of files. <p>
+     *
+     * @param sourceDir under which input files are located
+     * @param targetDir under which output files are to be written
+     * @param fileNames to be preprocessed
+     * @param altExt to use for output file names
+     * @param encoding with which to write output files
+     * @param options used to control preprocessing
+     * @param defines CSV list of symbol definition expressions
+     * @param resolver with which to perform property and path expansions
+     * @throws PreprocessorException if an error occurs while loading,
+     *      preprocessing or saving the result of preprocessing one of the
+     *      specified input files
+     */
+    public static void preprocessBatch(File sourceDir, File targetDir,
+            String[] fileNames, String altExt, String encoding, int options,
+            String defines, IResolver resolver) throws PreprocessorException {
+
+        for (int i = 0; i < fileNames.length; i++) {
+            String fileName = fileNames[i];
+
+            try {
+                preprocessFile(sourceDir, targetDir, fileName, altExt, encoding,
+                        options, defines, resolver);
+            } catch (PreprocessorException ppe) {
+
+                if (!Option.isVerbose(options)) {
+                    log(fileName + " ... not modified, " + ppe.getMessage());
+                }
+
+                throw ppe;
+            }
+        }
+    }
+
+    /**
+     * Preprocesses a single file. <p>
+     *
+     * @param sourceDir under which the input file is located
+     * @param targetDir under which the output file is to be written
+     * @param fileName to be preprocessed
+     * @param altExt to use for output file name
+     * @param encoding with which to write output file
+     * @param options used to control preprocessing
+     * @param defines CSV list of symbol definition expressions
+     * @param resolver with which to perform property and path expansions
+     * @throws PreprocessorException if an error occurs while loading,
+     *      preprocessing or saving the result of preprocessing the
+     *      specified input file
+     */
+    public static void preprocessFile(File sourceDir, File targetDir,
+            String fileName, String altExt, String encoding, int options,
+            String defines, IResolver resolver) throws PreprocessorException {
+
+        String       sourcePath   = translatePath(sourceDir, fileName, null);
+        String       targetPath   = translatePath(targetDir, fileName, altExt);
+        File         targetFile   = new File(targetPath);
+        File         backupFile   = new File(targetPath + "~");
+        boolean      sameDir      = sourceDir.equals(targetDir);
+        boolean      sameExt      = (altExt ==  null);
+        boolean      verbose      = Option.isVerbose(options);
+        boolean      testOnly     = Option.isTestOnly(options);
+        boolean      backup       = Option.isBackup(options);
+        Preprocessor preprocessor = new Preprocessor(sourcePath,
+                encoding, options, resolver, defines);
+
+        if (verbose) {
+            log("Reading \"" + sourcePath + "\"");
+        }
+
+        preprocessor.loadDocument();
+
+        boolean modified = preprocessor.preprocess();
+        boolean rewrite  = modified || !sameDir || !sameExt;
+
+        if (!rewrite) {
+            if (verbose) {
+                log(fileName + " ... not modified");
+            }
+
+            return;
+        } else if (verbose) {
+            log(fileName + " ... modified");
+        }
+
+        if (testOnly) {
+            return;
+        }
+
+        try {
+            targetFile.getParentFile().mkdirs();
+        } catch (Exception e) {
+            throw new PreprocessorException("mkdirs failed \"" + targetFile
+                    + "\": " + e); // NOI18N
+        }
+
+        backupFile.delete();
+
+        if (targetFile.exists() && !targetFile.renameTo(backupFile)) {
+            throw new PreprocessorException("Rename failed: \""
+                    + targetFile
+                    + "\" => \""
+                    + backupFile
+                    +"\"" ); // NOI18N
+        }
+
+        if (verbose) {
+            log("Writing \"" + targetPath + "\"");
+        }
+
+        preprocessor.saveDocument(targetPath);
+
+        if (!backup) {
+            backupFile.delete();
+        }
+    }
+
+    // =========================================================================
+    // ----------------------------- Implementation ----------------------------
+    // =========================================================================
+
+    // Fields
+
+    // static
+    static final int CONDITION_NONE      = 0;
+    static final int CONDITION_ARMED     = 1;
+    static final int CONDITION_IN_TRUE   = 2;
+    static final int CONDITION_TRIGGERED = 3;
+
+    // optimization - zero new object burn rate for statePush()
+    static final Integer[] STATES = new Integer[] {
+        new Integer(CONDITION_NONE),
+        new Integer(CONDITION_ARMED),
+        new Integer(CONDITION_IN_TRUE),
+        new Integer(CONDITION_TRIGGERED)
+    };
+
+    // instance
+    private String    documentPath;
+    private String    encoding;
+    private int       options;
+    private IResolver resolver;
+    private Document  document;
+    private Defines   defines;
+    private Stack     stack;
+    private int       state;
+
+    // Constructors
+
+    private Preprocessor(String documentPath,
+            String encoding, int options, IResolver resolver,
+            String predefined) throws PreprocessorException {
+
+        if (resolver == null) {
+            File parentDir = new File(documentPath).getParentFile();
+
+            this.resolver = new BasicResolver(parentDir);
+        } else {
+            this.resolver = resolver;
+        }
+
+        if (predefined == null || predefined.trim().length() == 0) {
+            this.defines = new Defines();
+        } else {
+            predefined   = this.resolver.resolveProperties(predefined);
+            this.defines = new Defines(predefined);
+        }
+
+        this.documentPath = documentPath;
+        this.encoding     = encoding;
+        this.options      = options;
+        this.document     = new Document();
+        this.stack        = new Stack();
+        this.state        = CONDITION_NONE;
+    }
+
+    private Preprocessor(Preprocessor other, Document include) {
+        this.document     = include;
+        this.encoding     = other.encoding;
+        this.stack        = new Stack();
+        this.state        = CONDITION_NONE;
+        this.options      = other.options;
+        this.documentPath = other.documentPath;
+        this.resolver     = other.resolver;
+        this.defines      = other.defines;
+    }
+
+    // Main entry point
+
+    private boolean preprocess() throws PreprocessorException {
+        this.stack.clear();
+
+        this.state = CONDITION_NONE;
+
+        // optimization - eliminates a full document copy and a full document
+        //                equality test for files with no preprocessor
+        //                directives
+        if (!this.document.contains(Line.DIRECTIVE_PREFIX)) {
+            return false;
+        }
+
+        Document originalDocument = new Document(this.document);
+
+        preprocessImpl();
+
+        if (this.state != CONDITION_NONE) {
+            throw new PreprocessorException("Missing final #endif"); // NOI18N
+        }
+
+        if (Option.isFilter(options)) {
+            // Cleanup all directives.
+
+            for (int i = this.document.size() - 1; i >= 0; i--) {
+                Line line = resolveLine(this.document.getSourceLine(i));
+
+                if (!line.isType(LineType.VISIBLE)) {
+                    this.document.deleteSourceLine(i);
+                }
+            }
+        }
+
+        return (!this.document.equals(originalDocument));
+    }
+
+    private void preprocessImpl() throws PreprocessorException {
+        int     includeCount = 0;
+        int     lineCount    = 0;
+
+        while (lineCount < this.document.size()) {
+
+            try {
+                Line line = resolveLine(this.document.getSourceLine(lineCount));
+
+                switch(line.getType()) {
+                    case LineType.INCLUDE : {
+                        lineCount = processInclude(lineCount, line);
+
+                        break;
+                    }
+                    case LineType.VISIBLE :
+                    case LineType.HIDDEN : {
+                        this.document.setSourceLine(lineCount,
+                                toSourceLine(line));
+
+                        if (Option.isVerbose(options)) {
+                                log((isHidingLines() ? "Commented: "
+                                                     : "Uncommented: ") + line);
+                        }
+
+                        lineCount++;
+
+                        break;
+                    }
+                    default : {
+                        processDirective(line);
+
+                        lineCount++;
+                    }
+                }
+            } catch (PreprocessorException ex) {
+                throw new PreprocessorException(ex.getMessage() + " at line "
+                        + (lineCount + 1)
+                        + " in \""
+                        + this.documentPath
+                        + "\""); // NOI18N
+            }
+        }
+    }
+
+    // -------------------------- Line-level Handlers --------------------------
+
+    private void processIf(boolean condition) {
+        statePush();
+
+        this.state = isHidingLines() ? CONDITION_TRIGGERED
+                                     : (condition) ? CONDITION_IN_TRUE
+                                                   : CONDITION_ARMED;
+    }
+
+    private void processElseIf(boolean condition) throws PreprocessorException {
+        switch(state) {
+            case CONDITION_NONE : {
+                throw new PreprocessorException("Unexpected #elif"); // NOI18N
+            }
+            case CONDITION_ARMED : {
+                if (condition) {
+                    this.state = CONDITION_IN_TRUE;
+                }
+
+                break;
+            }
+            case CONDITION_IN_TRUE : {
+                this.state = CONDITION_TRIGGERED;
+
+                break;
+            }
+        }
+    }
+
+    private void processElse() throws PreprocessorException {
+        switch(state) {
+            case CONDITION_NONE : {
+                throw new PreprocessorException("Unexpected #else"); // NOI18N
+            }
+            case CONDITION_ARMED : {
+                this.state = CONDITION_IN_TRUE;
+
+                break;
+            }
+            case CONDITION_IN_TRUE : {
+                this.state = CONDITION_TRIGGERED;
+
+                break;
+            }
+        }
+    }
+
+    private void processEndIf() throws PreprocessorException {
+        if (state == CONDITION_NONE) {
+            throw new PreprocessorException("Unexpected #endif"); // NOI18N
+        } else {
+            statePop();
+        }
+    }
+
+    private void processDirective(Line line) throws PreprocessorException {
+        switch(line.getType()) {
+            case LineType.DEFINE : {
+                if (!isHidingLines()) {
+                    this.defines.defineSingle(line.getArguments());
+                }
+
+                break;
+            }
+            case LineType.UNDEFINE : {
+                if (!isHidingLines()) {
+                    this.defines.undefine(line.getArguments());
+                }
+
+                break;
+            }
+            case LineType.IF : {
+                processIf(this.defines.evaluate(line.getArguments()));
+
+                break;
+            }
+            case LineType.IFDEF : {
+                processIf(this.defines.isDefined(line.getArguments()));
+
+                break;
+            }
+            case LineType.IFNDEF : {
+                processIf(!this.defines.isDefined(line.getArguments()));
+
+                break;
+            }
+            case LineType.ELIF : {
+                processElseIf(this.defines.evaluate(line.getArguments()));
+
+                break;
+            }
+            case LineType.ELIFDEF : {
+                processElseIf(this.defines.isDefined(line.getArguments()));
+
+                break;
+            }
+            case LineType.ELIFNDEF : {
+                processElseIf(!this.defines.isDefined(line.getArguments()));
+
+                break;
+            }
+            case LineType.ELSE : {
+                processElse();
+
+                break;
+            }
+            case LineType.ENDIF : {
+                processEndIf();
+
+                break;
+            }
+            default : {
+                throw new PreprocessorException("Unhandled line type: "
+                        + line); // NOI18N
+            }
+        }
+    }
+
+    private int processInclude(int lineCount, Line line)
+    throws PreprocessorException {
+        String    path   = resolvePath(line.getArguments());
+        boolean   hidden = isHidingLines();
+
+        lineCount++;
+
+        while (lineCount < this.document.size()) {
+            line = resolveLine(this.document.getSourceLine(lineCount));
+
+            if (line.isType(LineType.ENDINCLUDE)) {
+                break;
+            }
+
+            this.document.deleteSourceLine(lineCount);
+        }
+
+        if (!line.isType(LineType.ENDINCLUDE)) {
+            throw new PreprocessorException("Missing #endinclude"); // NOI18N
+        }
+
+        if (!hidden) {
+            Document     include      = loadInclude(path);
+            Preprocessor preprocessor = new Preprocessor(this, include);
+
+            preprocessor.preprocess();
+
+            int count = include.size();
+
+            for (int i = 0; i < count; i++) {
+                String sourceLine = include.getSourceLine(i);
+
+                if (resolveLine(sourceLine).isType(LineType.VISIBLE)) {
+                    this.document.insertSourceLine(lineCount++, sourceLine);
+                }
+            }
+        }
+
+        lineCount++;
+
+        return lineCount;
+    }
+
+    // -------------------------- Preprocessor State ---------------------------
+
+    private boolean isHidingLines() {
+        switch(state) {
+            case CONDITION_ARMED :
+            case CONDITION_TRIGGERED: {
+                return true;
+            }
+            default : {
+                return false;
+            }
+        }
+    }
+
+    private void statePush() {
+        this.stack.push(STATES[this.state]);
+    }
+
+    private void statePop() {
+        this.state = ((Integer) stack.pop()).intValue();
+    }
+
+    // ------------------------------ Resolution -------------------------------
+
+    private Line resolveLine(String line) throws PreprocessorException {
+        return new Line(this.resolver.resolveProperties(line));
+    }
+
+    private String resolvePath(String path) {
+        if (path == null) {
+            throw new IllegalArgumentException("path: null");
+        }
+
+        String value = this.resolver.resolveProperties(path);
+        File   file  = this.resolver.resolveFile(value);
+        
+        try {
+            return file.getCanonicalPath();
+        } catch (IOException ex) {
+            return file.getAbsolutePath();
+        }
+    }
+
+    // ------------------------------ Conversion -------------------------------
+
+    private String toSourceLine(Line line) {
+        return (isHidingLines())
+            ? Option.isIndent(this.options)
+                ? line.indent + Line.HIDE_DIRECTIVE + line.text
+                : Line.HIDE_DIRECTIVE + line.indent + line.text
+            : line.indent + line.text;
+    }
+
+    private File toCanonicalOrAbsoluteFile(String path) {
+        File file = new File(path);
+
+        if (!file.isAbsolute()) {
+            path = (new File(this.documentPath)).getParent()
+                    + File.separatorChar
+                    + path;
+
+            file = new File(path);
+        }
+
+        try {
+            return file.getCanonicalFile();
+        } catch (Exception e) {
+            return file.getAbsoluteFile();
+        }
+    }
+
+    // ------------------------------ Translation ------------------------------
+
+    private static String translatePath(File dir, String fileName, String ext) {
+        return new StringBuffer(dir.getPath()).append(File.separatorChar).
+                append(translateFileExtension(fileName,ext)).toString();
+    }
+
+    private static String translateFileExtension(String fileName, String ext) {
+        if (ext != null) {
+
+            int pos = fileName.lastIndexOf('.');
+
+            fileName = (pos < 0) ? fileName + ext
+                                 : fileName.substring(0, pos) + ext;
+        }
+
+        return fileName;
+    }
+
+    // ---------------------------------- I/O ----------------------------------
+
+    private Document loadInclude(String path) throws PreprocessorException {
+        Document include = new Document();
+        File     file    = toCanonicalOrAbsoluteFile(path);
+
+        try {
+            return include.load(file, this.encoding);
+        } catch (UnsupportedEncodingException uee) {
+            throw new PreprocessorException("Unsupported encoding \""
+                    + this.encoding + "\" loading include \"" + file
+                    + "\""); // NOI18N
+        } catch (IOException ioe) {
+            throw new PreprocessorException("Unable to load include \""
+                    + file + "\": " + ioe); // NOI18N
+        }
+    }
+
+    private void loadDocument() throws PreprocessorException {
+        try {
+            this.document.load(this.documentPath, this.encoding);
+        } catch (UnsupportedEncodingException uee) {
+            throw new PreprocessorException("Unsupported encoding \""
+                    + this.encoding + "\" reading file \"" + this.documentPath
+                    + "\""); // NOI18N
+        } catch (IOException ioe) {
+            throw new PreprocessorException("Unable to read file \""
+                    + this.documentPath + "\": " + ioe); // NOI18N
+        }
+    }
+
+    private void saveDocument(Object target) throws PreprocessorException {
+        try {
+            if (this.document.size() > 0) {
+                this.document.save(target, this.encoding);
+            }
+        } catch (UnsupportedEncodingException uee) {
+            throw new PreprocessorException("Unsupported encoding \""
+                    + this.encoding + "\" writing \"" + target
+                    + "\""); // NOI18N
+        } catch (IOException ioe) {
+            throw new PreprocessorException("Unable to write to \""
+                    + target + "\": " + ioe); // NOI18N
+        }
+    }
+
+    private static void log(Object toLog) {
+        System.out.println(toLog);
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/PreprocessorAntTask.java b/src/org/hsqldb/util/preprocessor/PreprocessorAntTask.java
new file mode 100644
index 0000000..c737f29
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/PreprocessorAntTask.java
@@ -0,0 +1,243 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+
+/* $Id: PreprocessorAntTask.java 751 2009-01-11 21:49:27Z unsaved $ */
+
+/**
+ * Provides a facility for invoking the Preprocessor from ANT. <p>
+ *
+ * Example ANT target: <p>
+ *
+ * <pre>
+ * <target
+ *     name="preprocess"
+ *     depends="build-preprocessor">
+ *
+ *     <taskdef
+ *         name="preprocess"
+ *         classname="org.hsqldb.util.preprocessor.PreprocessorAntTask"
+ *         classpath="${preprocessor.class.path}"/>
+ *
+ *     <preprocess
+ *         srcdir="${src.dir}"
+ *         targetdir="${target.dir}"
+ *         altext=".pre"
+ *         backup="true"
+ *         encoding="UTF8"
+ *         filter="true"
+ *         indent="false"
+ *         symbols="java_version=${java.version}, jdbc_version=${jdbc.version}"
+ *         testonly="false"
+ *         verbose="true"
+ *         if="${preprocess.if}"
+ *         unless="${preprocess.unless}">
+ *     </preprocess>
+ *
+ * </target>
+ * </pre>
+ *
+ * Task attributes :
+ *
+ * <table>
+ *     <thead>
+ *         <tr><td>name</td><td>description</td></tr>
+ *     </thead>
+ *     <tbody>
+ *     <tr>
+ *         <td>srcdir (required)</td>
+ *         <td>string - directory under which input files are located</td>
+ *     </tr>
+ *     <tr>
+ *         <td>targetdir (required)</td>
+ *         <td>string - directory under which output files are to be written</td>
+ *     </tr>
+ *     <tr>
+ *         <td>altext (optional)</td>
+ *         <td>string - alternate extension to use for output file names. <br/>
+ *         If needed, leading dot should be provided</td>
+ *     </tr>
+ *     <tr>
+ *         <td>backup (optional - default: false)</td>
+ *         <td>boolean - whether to back up pre-existing target files. <br/>
+ *         When true, pre-existing target files are preserved by renaming with
+ *         postfix "~"</td>
+ *     </tr>
+ *     <tr>
+ *         <td>encoding (optional)</td>
+ *         <td>string - the encoding with which to read and write file content.<br/>
+ *         If specified, must be a valid Java encoding identifier, such as "UTF8". <br/>
+ *         When unspecified, the default Java platformn encoding is used.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>filter (optional - default: false)</td>
+ *         <td>boolean - whether to exclude directive lines from output.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>indent (optional - default: false)</td>
+ *         <td>boolean - whether to indent directive lines in output.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>symbols (optional)</td>
+ *         <td>string - CSV list of preprocessor symbols to predefine. <br/>
+ *         When specified, each list element must be of the form: <br/>
+ *         IDENT (ASSIGN? (STRING | NUMBER | IDENT) )?<br/>
+ *         Not that forward assignments are illegal. <br/>
+ *         See {@link Preprocessor Preprocessor} for details</td>
+ *     </tr>
+ *     <tr>
+ *         <td>testonly (optional - default: false)</td>
+ *         <td>boolean - whether to omit writing output files.</td>
+ *     </tr>
+ *     <tr>
+ *         <td>verbose (optional - default: false)</td>
+ *         <td>boolean - whether to log detailed information.</td>
+ *     </tr>
+ *     <tbody>
+ * </table>
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+public class PreprocessorAntTask extends MatchingTask {
+
+    private String ifExpr;
+    private String unlessExpr;
+    private File   sourceDir;
+    private File   targetDir;
+    private String defines;
+    private String altExt;
+    private String encoding;
+    private int    options = Option.INDENT;
+
+    public void init() {
+        super.init();
+    }
+
+    public void setSrcdir(final File value) {
+        sourceDir = value;
+    }
+
+    public void setTargetdir(final File value) {
+        targetDir = value;
+    }
+
+    public void setSymbols(final String value) {
+        defines = value;
+    }
+
+    public void setVerbose(final boolean verbose) {
+        options = Option.setVerbose(options, verbose);
+    }
+
+    public void setBackup(final boolean backup) {
+        options = Option.setBackup(options, backup);
+    }
+
+    public void setIndent(final boolean indent) {
+        options = Option.setIndent(options, indent);
+    }
+
+    public void setTestonly(final boolean testOnly) {
+        options = Option.setTestOnly(options, testOnly);
+    }
+
+    public void setFilter(final boolean filter) {
+        options = Option.setFilter(options, filter);
+    }
+
+    public void setAltext(final String ext) {
+        this.altExt = ext;
+    }
+
+    public void setEncoding(final String encoding) {
+          this.encoding = encoding;
+    }
+
+    public void setIf(final String expr) {
+        this.ifExpr = expr;
+    }
+
+    public void setUnless(final String expr) {
+        this.unlessExpr = expr;
+    }
+
+    public boolean isActive() {
+        return (this.ifExpr == null
+                || getProject().getProperty(this.ifExpr) != null
+                || this.unlessExpr == null
+                || getProject().getProperty(this.unlessExpr) == null);
+    }
+
+    public void execute() throws BuildException {
+
+        if (!isActive()) {
+            return;
+        }
+
+        checkTargetDir();
+
+        this.sourceDir = getProject().resolveFile("" + this.sourceDir);
+
+        IResolver resolver = new AntResolver(getProject());
+        String[]  files    = getFiles();
+
+        log("Preprocessing " + files.length + " file(s)");
+
+        try {
+            Preprocessor.preprocessBatch(this.sourceDir, this.targetDir, files,
+                    this.altExt, this.encoding, this.options, this.defines,
+                    resolver);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+
+            throw new BuildException("Preprocessing failed: " + ex,
+                    ex);
+        }
+    }
+
+    private String[] getFiles() {
+        return getDirectoryScanner(sourceDir).getIncludedFiles();
+    }
+
+    private void checkTargetDir() throws BuildException {
+        if (targetDir == null) {
+            throw new BuildException("Target directory required.");
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/PreprocessorException.java b/src/org/hsqldb/util/preprocessor/PreprocessorException.java
new file mode 100644
index 0000000..ffa63a8
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/PreprocessorException.java
@@ -0,0 +1,47 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+/* $Id: PreprocessorException.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Thrown when preprocessing fails.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+public class PreprocessorException extends Exception {
+    public PreprocessorException(String message) {
+        super(message);
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/Token.java b/src/org/hsqldb/util/preprocessor/Token.java
new file mode 100644
index 0000000..abf40b1
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/Token.java
@@ -0,0 +1,107 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+/* $Id: Token.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Static methods and constants to decode directive tokens.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+final class Token {
+    static final int EOI     = -1;
+    static final int UNKNOWN = 0;
+    static final int IDENT   = 1;
+    static final int NUMBER  = 2;
+    static final int STRING  = 3;
+    static final int AND     = '&';
+    static final int OR      = '|';
+    static final int XOR     = '^';
+    static final int NOT     = '!';
+    static final int GT      = '>';
+    static final int GTE     = '>' + '=';
+    static final int LT      = '<';
+    static final int LTE     = '<' + '=';
+    static final int ASSIGN  = '=';
+    static final int EQ      = '=' + '=';
+    static final int LPAREN  = '(';
+    static final int RPAREN  = ')';
+
+    static boolean isAssignmentOperator(final int type) {
+        return (type == ASSIGN);
+    }
+
+    static boolean isComparisonOperator(final int type) {
+        switch(type) {
+            case EQ :
+            case LT :
+            case GT :
+            case LTE :
+            case GTE : {
+                return true;
+            }
+            default : {
+                return false;
+            }
+        }
+    }
+
+    static boolean isLogicalOperator(final int type) {
+        switch(type) {
+            case AND :
+            case OR :
+            case XOR :
+            case NOT : {
+                return true;
+            }
+            default : {
+                return false;
+            }
+        }
+    }
+
+    static boolean isValue(final int type) {
+        switch (type) {
+            case IDENT :
+            case STRING :
+            case NUMBER : {
+                return true;
+            }
+            default : {
+                return false;
+            }
+        }
+    }
+}
diff --git a/src/org/hsqldb/util/preprocessor/Tokenizer.java b/src/org/hsqldb/util/preprocessor/Tokenizer.java
new file mode 100644
index 0000000..566e672
--- /dev/null
+++ b/src/org/hsqldb/util/preprocessor/Tokenizer.java
@@ -0,0 +1,245 @@
+/* Copyright (c) 2001-2007, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.hsqldb.util.preprocessor;
+
+/* $Id: Tokenizer.java 610 2008-12-22 15:54:18Z unsaved $ */
+
+/**
+ * Simple preprocessor directive tokenizer.
+ *
+ * @author boucherb@users
+ * @version 1.8.1
+ * @since 1.8.1
+ */
+final class Tokenizer {
+    private final String command;
+    private final int    commandLength;
+    private int          tokenType;
+    private int          startIndex;
+    private int          currentIndex;
+
+    Tokenizer(final String cmd) {
+        this.command       = cmd + " ";
+        this.commandLength = command.length();
+        this.startIndex    = 0;
+        this.currentIndex  = 0;
+        this.tokenType     = Token.UNKNOWN;
+    }
+
+    void skipBlanks() {
+        final String cmd = this.command;
+        final int    len = this.commandLength;
+
+        top:
+            while (currentIndex < len) {
+
+            switch(cmd.charAt(currentIndex)) {
+                case ' '  :
+                case '\t' : {
+                    currentIndex++;
+                    continue top;
+                }
+            }
+
+            break;
+            }
+    }
+
+    int next() throws PreprocessorException {
+        skipBlanks();
+
+        startIndex = currentIndex;
+
+        final String cmd = this.command;
+        final int    len = this.commandLength;
+
+        if (currentIndex >= len) {
+            tokenType = Token.EOI;
+
+            return tokenType;
+        }
+
+        char ch = cmd.charAt(currentIndex);
+
+        if (Character.isJavaIdentifierStart(ch)) {
+            tokenType = Token.IDENT;
+
+            currentIndex++;
+
+            while (currentIndex < len &&
+                    Character.isJavaIdentifierPart(cmd.charAt(currentIndex))) {
+                currentIndex++;
+            }
+
+            return tokenType;
+        } else if (Character.isDigit(ch)) {
+            tokenType = Token.NUMBER;
+
+            currentIndex++;
+
+            while(currentIndex < len &&
+                    Character.isDigit(cmd.charAt(currentIndex))) {
+                currentIndex++;
+            }
+
+            if (currentIndex < len && cmd.charAt(currentIndex) == '.') {
+                currentIndex++;
+            }
+
+            while(currentIndex < len &&
+                    Character.isDigit(cmd.charAt(currentIndex))) {
+                currentIndex++;
+            }
+
+            return tokenType;
+        } else if (ch == '"') {
+            tokenType = Token.STRING;
+
+            currentIndex++;
+
+            int pos = cmd.indexOf('"', currentIndex);
+
+            if (pos == -1) {
+                throw new PreprocessorException("Unclosed string literal: " +
+                        cmd.substring(startIndex)); //NOI18N
+            }
+
+            currentIndex = pos + 1;
+
+            return tokenType;
+        }
+
+
+        switch(ch) {
+            case Token.LPAREN :
+            case Token.RPAREN :
+            case Token.XOR :
+            case Token.NOT : {
+                currentIndex++;
+
+                return (tokenType = ch);
+            }
+            case Token.ASSIGN : {
+                currentIndex++;
+
+                if(currentIndex < len &&
+                        cmd.charAt(currentIndex) == Token.ASSIGN) {
+                    currentIndex++;
+
+                    tokenType = Token.EQ;
+                } else {
+                    tokenType = Token.ASSIGN;
+                }
+
+                return tokenType;
+            }
+            case Token.LT : {
+                currentIndex++;
+
+                if (currentIndex < len &&
+                        cmd.charAt(currentIndex) == Token.ASSIGN) {
+                    currentIndex++;
+
+                    tokenType = Token.LTE;
+                } else {
+                    tokenType = Token.LT;
+                }
+
+                return tokenType;
+            }
+            case Token.GT : {
+                currentIndex++;
+
+                if (currentIndex < len &&
+                        cmd.charAt(currentIndex) == Token.ASSIGN) {
+                    currentIndex++;
+
+                    tokenType = Token.GTE;
+                } else {
+                    tokenType = Token.GT;
+                }
+
+                return tokenType;
+            }
+            case Token.AND :
+            case Token.OR : {
+                currentIndex++;
+
+                if (currentIndex < len && cmd.charAt(currentIndex) == ch) {
+                    currentIndex++;
+                }
+
+                return (tokenType = ch);
+            }
+            default : {
+                throw new PreprocessorException("Syntax error: " +
+                        cmd.substring(currentIndex)); //NOI18N
+            }
+        }
+    }
+
+    int getTokenType() {
+        return tokenType;
+    }
+
+    boolean isToken(final int type) {
+        return (this.tokenType == type);
+    }
+
+    String getIdent() {
+        return isToken(Token.EOI) ? null
+                : this.command.substring(startIndex, currentIndex);
+    }
+
+    Number getNumber() {
+        return (isToken(Token.EOI)) ? null
+                : new Double(Double.parseDouble(this.command.
+                substring(startIndex, currentIndex)));
+    }
+
+    String getString() {
+        return isToken(Token.EOI) ? null
+                : this.command.substring(startIndex + 1, currentIndex - 1);
+    }
+
+    int getStartIndex() {
+        return this.startIndex;
+    }
+
+    int currentIndex() {
+        return this.currentIndex;
+    }
+
+    String getSource() {
+        return this.command;
+    }
+}
diff --git a/src/org/hsqldb/util/problems.gif b/src/org/hsqldb/util/problems.gif
new file mode 100644
index 0000000..c9376aa
--- /dev/null
+++ b/src/org/hsqldb/util/problems.gif
Binary files differ
diff --git a/src/org/hsqldb/util/run_exc.gif b/src/org/hsqldb/util/run_exc.gif
new file mode 100644
index 0000000..68e72e5
--- /dev/null
+++ b/src/org/hsqldb/util/run_exc.gif
Binary files differ
diff --git a/src/org/hsqldb/util/run_exc_running.gif b/src/org/hsqldb/util/run_exc_running.gif
new file mode 100644
index 0000000..087dd57
--- /dev/null
+++ b/src/org/hsqldb/util/run_exc_running.gif
Binary files differ
diff --git a/stylesheets/chunk.xsl b/stylesheets/chunk.xsl
new file mode 100644
index 0000000..884836c
--- /dev/null
+++ b/stylesheets/chunk.xsl
@@ -0,0 +1,160 @@
+<?xml version='1.0'?>
+<!-- $Id: chunk.xsl 3535 2010-03-16 23:12:20Z unsaved $ -->
+<!-- See http://www.sagehill.net/docbookxsl/CustomDb5Xsl.html for general
+     syntax. -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+     xmlns:d="http://docbook.org/ns/docbook" exclude-result-prefixes="d">
+
+  <xsl:import
+      href="http://docbook.sourceforge.net/release/xsl-ns/current/html/chunk.xsl"/>
+  <xsl:import href="html-common.xsl"/>
+
+<xsl:template name="user.header.content">
+  <HR/>
+  <xsl:apply-templates select="//copyright[1]" mode="titlepage.mode"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+<xsl:template name="header.navigation">
+  <xsl:param name="prev" select="/d:foo"/>
+  <xsl:param name="next" select="/d:foo"/>
+  <xsl:param name="nav.context"/>
+
+  <xsl:variable name="home" select="/*[1]"/>
+  <xsl:variable name="up" select="parent::*"/>
+
+  <xsl:variable name="row1" select="count($prev) &gt; 0
+                                    or count($up) &gt; 0
+                                    or count($next) &gt; 0"/>
+
+  <xsl:variable name="row2" select="($prev and $navig.showtitles != 0)
+                                    or (generate-id($home) != generate-id(.)
+                                        or $nav.context = 'toc')
+                                    or ($chunk.tocs.and.lots != 0
+                                        and $nav.context != 'toc')
+                                    or ($next and $navig.showtitles != 0)"/>
+
+  <xsl:if test="$suppress.navigation = '0' and $suppress.header.navigation = '0'">
+    <div class="navheader">
+      <xsl:if test="$row1 or $row2">
+        <table width="100%" summary="Navigation header">
+          <xsl:if test="$row1">
+            <tr>
+              <td width="30%" align="left">
+                <xsl:if test="count($prev)>0">
+                  <a accesskey="p">
+                    <xsl:attribute name="href">
+                      <xsl:call-template name="href.target">
+                        <xsl:with-param name="object" select="$prev"/>
+                      </xsl:call-template>
+                    </xsl:attribute>
+                    <xsl:call-template name="navig.content">
+                      <xsl:with-param name="direction" select="'prev'"/>
+                    </xsl:call-template>
+                  </a>
+                </xsl:if>
+                <xsl:text>&#160;</xsl:text>
+              </td>
+              <td style="font-weight:bold;" width="40%" align="center">
+                <xsl:choose>
+                  <xsl:when test="count($up)&gt;0
+                                  and generate-id($up) != generate-id($home)">
+                    <a accesskey="u">
+                      <xsl:attribute name="href">
+                        <xsl:call-template name="href.target">
+                          <xsl:with-param name="object" select="$up"/>
+                        </xsl:call-template>
+                      </xsl:attribute>
+                      <xsl:call-template name="navig.content">
+                        <xsl:with-param name="direction" select="'up'"/>
+                      </xsl:call-template>
+                    </a>
+                  </xsl:when>
+                  <!--  BLAINE OVERRIDING to current page title in this case
+                        (due to our nesting settings, we should ALWAYS hit
+                        this case).
+                  <xsl:otherwise>&#160;</xsl:otherwise>
+                  -->
+                    <xsl:otherwise>
+                      <xsl:apply-templates select="." mode="object.title.markup"/>
+                    </xsl:otherwise>
+                </xsl:choose>
+              </td>
+              <td width="30%" align="right">
+                <xsl:text>&#160;</xsl:text>
+                <xsl:if test="count($next)>0">
+                  <a accesskey="n">
+                    <xsl:attribute name="href">
+                      <xsl:call-template name="href.target">
+                        <xsl:with-param name="object" select="$next"/>
+                      </xsl:call-template>
+                    </xsl:attribute>
+                    <xsl:call-template name="navig.content">
+                      <xsl:with-param name="direction" select="'next'"/>
+                    </xsl:call-template>
+                  </a>
+                </xsl:if>
+              </td>
+            </tr>
+          </xsl:if>
+
+          <xsl:if test="$row2">
+            <tr>
+              <td width="30%" align="left" valign="top">
+                <xsl:if test="$navig.showtitles != 0">
+                  <xsl:apply-templates select="$prev" mode="object.title.markup"/>
+                </xsl:if>
+                <xsl:text>&#160;</xsl:text>
+              </td>
+              <td width="40%" align="center">
+                <xsl:choose>
+                  <xsl:when test="$home != . or $nav.context = 'toc'">
+                    <a accesskey="h">
+                      <xsl:attribute name="href">
+                        <xsl:call-template name="href.target">
+                          <xsl:with-param name="object" select="$home"/>
+                        </xsl:call-template>
+                      </xsl:attribute>
+                      <xsl:call-template name="navig.content">
+                        <xsl:with-param name="direction" select="'home'"/>
+                      </xsl:call-template>
+                    </a>
+                    <xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
+                      <xsl:text>&#160;|&#160;</xsl:text>
+                    </xsl:if>
+                  </xsl:when>
+                  <xsl:otherwise>&#160;</xsl:otherwise>
+                </xsl:choose>
+
+                <xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
+                  <a accesskey="t">
+                    <xsl:attribute name="href">
+                      <xsl:apply-templates select="/*[1]"
+                                           mode="recursive-chunk-filename">
+                        <xsl:with-param name="recursive" select="true()"/>
+                      </xsl:apply-templates>
+                      <xsl:text>-toc</xsl:text>
+                      <xsl:value-of select="$html.ext"/>
+                    </xsl:attribute>
+                    <xsl:call-template name="gentext">
+                      <xsl:with-param name="key" select="'nav-toc'"/>
+                    </xsl:call-template>
+                  </a>
+                </xsl:if>
+              </td>
+              <td width="30%" align="right" valign="top">
+                <xsl:text>&#160;</xsl:text>
+                <xsl:if test="$navig.showtitles != 0">
+                  <xsl:apply-templates select="$next" mode="object.title.markup"/>
+                </xsl:if>
+              </td>
+            </tr>
+          </xsl:if>
+        </table>
+      </xsl:if>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet> 
diff --git a/stylesheets/fo.xsl b/stylesheets/fo.xsl
new file mode 100644
index 0000000..4752494
--- /dev/null
+++ b/stylesheets/fo.xsl
@@ -0,0 +1,137 @@
+<?xml version='1.0'?>
+<!-- $Id: fo.xsl 3538 2010-03-17 13:55:43Z unsaved $ -->
+<!-- See http://www.sagehill.net/docbookxsl/CustomDb5Xsl.html for general
+     syntax. -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+     xmlns:fo="http://www.w3.org/1999/XSL/Format"
+     xmlns:d="http://docbook.org/ns/docbook" exclude-result-prefixes="d">
+
+  <xsl:import
+    href="http://docbook.sourceforge.net/release/xsl-ns/current/fo/docbook.xsl"/>
+  <xsl:import href="pagesetup.xsl"/>
+
+  <!-- See http://www.sagehill.net/docbookxsl/BordersAndShading.html -->
+  <xsl:attribute-set name="admonition.properties">
+    <xsl:attribute name="border">0.5pt solid black</xsl:attribute>
+    <xsl:attribute name="padding">1pt</xsl:attribute>
+    <xsl:attribute name="background-color">#FFE4E1</xsl:attribute>
+  </xsl:attribute-set>
+
+  <xsl:attribute-set name="table.table.properties">
+    <xsl:attribute name="margin">3pt</xsl:attribute>
+    <!--
+    <xsl:attribute name="font-size">6pt</xsl:attribute>
+    -->
+  </xsl:attribute-set>
+
+  <!-- See http://docbook.sourceforge.net/release/xsl-ns/current/doc/html/shade.verbatim.style.html -->
+  <xsl:attribute-set name="shade.verbatim.style">
+    <xsl:attribute name="border">0.5pt solid gray</xsl:attribute>
+    <xsl:attribute name="padding">1pt</xsl:attribute>
+    <xsl:attribute name="background-color">#F0F8FF</xsl:attribute>
+    <!-- Note that some of OASIS's examples the long-deprecated "bgcolor".
+         You should use "background-color". -->
+  </xsl:attribute-set>
+
+  <!-- This allows tables and other block objects to wrap across multiple
+       pages -->
+  <xsl:attribute-set name="formal.object.properties">
+    <xsl:attribute name="keep-together.within-column">auto</xsl:attribute>
+  </xsl:attribute-set>
+
+  <!-- This block implements our "improvement", but not absolute fix, for
+       truncation of long lines in verbatim blocks.
+       We wrap to keep the lines inside the shade boxes, with the limitation
+       that tokens without white-space are not broken/wrapped at all.
+       You may turn down the font-size to accommodate longer non-whitespace
+       tokens.
+       -->
+  <xsl:attribute-set name="monospace.verbatim.properties"
+                     use-attribute-sets="verbatim.properties">
+    <xsl:attribute name="wrap-option">wrap</xsl:attribute>
+    <!-- By default, long lines in verbatims will overstep the shade box,
+         then be truncated -->
+
+    <xsl:attribute name="font-size">8pt</xsl:attribute>
+    <!--
+         Default is 10pt.
+         10pt fits 78 characters inside the shade box, but FO will fold the
+         first space character >= 78, leaving a right margin of >= 1 char.
+         So with setting of 10 pt, text will only overwrite the shadow box
+         for lines containing a non-whitespace-token of length > 78.
+    -->
+  </xsl:attribute-set>
+
+  <!--
+  This suggestion at http://www.dpawson.co.uk/docbook/styling/fo.html#d3043e580
+  doesn't work.  It's supposed to insert a space character so that our
+  white-space wrapping will force a wrap here regardless of the character at
+  that position.
+  The other suggestion on the page doesn't work, because it only breaks on
+  specific characters.  We want to FORCE a break at column 80, to absolutely
+  prevent truncation.
+  <xsl:template match="processing-instruction('sbr')">
+    <fo:character
+      character=" "
+      font-size=".01pt"
+      treat-as-word-space="true"/>
+  </xsl:template>
+  -->
+
+  <!-- This would apply to all section levels
+  <xsl:attribute-set name="section.title.properties">
+    <xsl:attribute name="color">#083194</xsl:attribute>
+  </xsl:attribute-set>
+  -->
+  <xsl:attribute-set name="section.title.level1.properties">
+    <xsl:attribute name="color">#000080</xsl:attribute>
+    <xsl:attribute name="font-size">
+      <xsl:value-of select="$body.font.master * 1.8"></xsl:value-of>
+      <xsl:text>pt</xsl:text>
+    </xsl:attribute>
+  </xsl:attribute-set>
+  <xsl:attribute-set name="section.title.level2.properties">
+    <xsl:attribute name="font-size">
+      <xsl:value-of select="$body.font.master * 1.6"></xsl:value-of>
+      <xsl:text>pt</xsl:text>
+    </xsl:attribute>
+  </xsl:attribute-set>
+  <xsl:attribute-set name="section.title.level3.properties">
+    <xsl:attribute name="font-size">
+      <xsl:value-of select="$body.font.master * 1.4"></xsl:value-of>
+      <xsl:text>pt</xsl:text>
+    </xsl:attribute>
+  </xsl:attribute-set>
+  <xsl:attribute-set name="section.title.level4.properties">
+    <xsl:attribute name="font-size">
+      <xsl:value-of select="$body.font.master * 1.3"></xsl:value-of>
+      <xsl:text>pt</xsl:text>
+    </xsl:attribute>
+  </xsl:attribute-set>
+  <xsl:attribute-set name="section.title.level5.properties">
+    <xsl:attribute name="font-size">
+      <xsl:value-of select="$body.font.master * 1.2"></xsl:value-of>
+      <xsl:text>pt</xsl:text>
+    </xsl:attribute>
+  </xsl:attribute-set>
+  <xsl:attribute-set name="section.title.level6.properties">
+    <xsl:attribute name="font-size">
+      <xsl:value-of select="$body.font.master * 1.1"></xsl:value-of>
+      <xsl:text>pt</xsl:text>
+    </xsl:attribute>
+  </xsl:attribute-set>
+
+  <!-- This sets the size for titles of all all chapters, appendices, articles,
+       glossaries, bibliographies, prefaces, indexes, dedications, colophons.
+       The much more complex systems documented at
+       http://www.sagehill.net/docbookxsl/TitleFontSizes.html don't work for me.
+  -->
+  <xsl:attribute-set name="component.title.properties">
+    <xsl:attribute name="font-size">
+      <xsl:value-of select="$body.font.master * 2.1"></xsl:value-of>
+      <xsl:text>pt</xsl:text>
+    </xsl:attribute>
+    <xsl:attribute name="color">#000080</xsl:attribute>
+  </xsl:attribute-set>
+</xsl:stylesheet> 
diff --git a/stylesheets/html-common.xsl b/stylesheets/html-common.xsl
new file mode 100644
index 0000000..976f349
--- /dev/null
+++ b/stylesheets/html-common.xsl
@@ -0,0 +1,90 @@
+<?xml version='1.0'?>
+<!-- $Id: html-common.xsl 3534 2010-03-16 23:12:12Z unsaved $ -->
+<!-- Contents of this file apply to both regular HTML and Chunk HTML formats -->
+<!-- See http://www.sagehill.net/docbookxsl/CustomDb5Xsl.html for general
+     syntax. -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+     xmlns:xi="http://www.w3.org/2001/XInclude"
+     xmlns:d="http://docbook.org/ns/docbook" exclude-result-prefixes="d">
+  <!-- See http://www.sagehill.net/docbookxsl/HTMLHeaders.html -->
+
+  <xsl:template name="user.footer.content">
+    <HR/>
+    <P class="svnrev">
+      <xsl:value-of select="/*/d:info/d:releaseinfo"/>
+    </P>
+    <xsl:apply-templates select="/*/d:info/d:copyright"
+                         mode="titlepage.mode"/>
+  </xsl:template>
+
+  <!-- Nesting example:
+  <xsl:template name="user.header.content">
+    <xsl:call-template name="breadcrumbs"/>
+  </xsl:template>
+  -->
+
+  
+<!--  FOR UNKNOWN REASON, WRAPPING THE IMPORTED template is NOT WORKING!
+ <xsl:template name="book.titlepage.recto">
+     <xsl:apply-imports/>
+ </xsl:template>
+ Forced to duplicate it from "titlepage.templates.xsl" in its entirety here.
+ -->
+<xsl:template name="book.titlepage.recto">
+  <xsl:choose>
+    <xsl:when test="d:bookinfo/d:title">
+      <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:title"/>
+    </xsl:when>
+    <xsl:when test="d:info/d:title">
+      <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:title"/>
+    </xsl:when>
+    <xsl:when test="d:title">
+      <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:title"/>
+    </xsl:when>
+  </xsl:choose>
+
+  <xsl:choose>
+    <xsl:when test="d:bookinfo/d:subtitle">
+      <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:subtitle"/>
+    </xsl:when>
+    <xsl:when test="d:info/d:subtitle">
+      <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:subtitle"/>
+    </xsl:when>
+    <xsl:when test="d:subtitle">
+      <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:subtitle"/>
+    </xsl:when>
+  </xsl:choose>
+
+  <table cellspacing="0" class="titlead"> <tr>
+    <td>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:corpauthor"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:corpauthor"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:authorgroup"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:authorgroup"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:author"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:author"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:othercredit"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:othercredit"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:releaseinfo"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:releaseinfo"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:copyright"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:copyright"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:legalnotice"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:legalnotice"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:pubdate"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:pubdate"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:revision"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:revision"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:revhistory"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:revhistory"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:abstract"/>
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:info/d:abstract"/>
+    </td>
+    <td class="sponsorad">
+      <xi:include href="../doc-src/branding-frag.xhtml"/>
+    </td>
+  </tr></table>
+</xsl:template>
+
+</xsl:stylesheet> 
diff --git a/stylesheets/html.xsl b/stylesheets/html.xsl
new file mode 100644
index 0000000..0883063
--- /dev/null
+++ b/stylesheets/html.xsl
@@ -0,0 +1,15 @@
+<?xml version='1.0'?>
+<!-- $Id: html.xsl 643 2008-12-29 07:08:49Z unsaved $ -->
+<!-- Contents of this file apply only to non-chunked HTML format -->
+<!-- See http://www.sagehill.net/docbookxsl/CustomDb5Xsl.html for general
+     syntax. -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+     xmlns:xi="http://www.w3.org/2001/XInclude"
+     xmlns:d="http://docbook.org/ns/docbook" exclude-result-prefixes="d">
+
+  <xsl:import
+ href="http://docbook.sourceforge.net/release/xsl-ns/current/html/docbook.xsl"/>
+
+  <xsl:import href="html-common.xsl"/>
+</xsl:stylesheet> 
diff --git a/stylesheets/pagesetup.xsl b/stylesheets/pagesetup.xsl
new file mode 100644
index 0000000..28d70a0
--- /dev/null
+++ b/stylesheets/pagesetup.xsl
@@ -0,0 +1,139 @@
+<?xml version="1.0"?>
+<xsl:stylesheet exclude-result-prefixes="d"
+                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:d="http://docbook.org/ns/docbook"
+xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version="1.0">
+
+<!-- ********************************************************************
+     $Id: pagesetup.xsl 3538 2010-03-17 13:55:43Z unsaved $
+     ********************************************************************
+
+     This file is part of the DocBook XSL Stylesheet distribution.
+     See ../README or http://docbook.sf.net/ for copyright
+     copyright and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:param name="body.fontset">
+  <xsl:value-of select="$body.font.family"/>
+  <xsl:if test="$body.font.family != ''
+                and $symbol.font.family  != ''">,</xsl:if>
+    <xsl:value-of select="$symbol.font.family"/>
+</xsl:param>
+
+<xsl:param name="title.fontset">
+  <xsl:value-of select="$title.font.family"/>
+  <xsl:if test="$title.font.family != ''
+                and $symbol.font.family  != ''">,</xsl:if>
+    <xsl:value-of select="$symbol.font.family"/>
+</xsl:param>
+
+<!-- PassiveTeX can't handle the math expression for
+     title.margin.left being negative, so ignore it.
+     margin-left="{$page.margin.outer} - {$title.margin.left}"
+-->
+<xsl:param name="margin.left.outer">
+  <xsl:choose>
+    <xsl:when test="$passivetex.extensions != 0">
+      <xsl:value-of select="$page.margin.outer"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$page.margin.outer"/>
+      <xsl:text> - </xsl:text>
+      <xsl:value-of select="$title.margin.left"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<xsl:param name="margin.left.inner">
+  <xsl:choose>
+    <xsl:when test="$passivetex.extensions != 0">
+      <xsl:value-of select="$page.margin.inner"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$page.margin.inner"/>
+      <xsl:text> - </xsl:text>
+      <xsl:value-of select="$title.margin.left"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<xsl:template name="header.content">
+  <xsl:param name="pageclass" select="''"/>
+  <xsl:param name="sequence" select="''"/>
+  <xsl:param name="position" select="''"/>
+  <xsl:param name="gentext-key" select="''"/>
+
+<!--
+  <fo:block>
+    <xsl:value-of select="$pageclass"/>
+    <xsl:text>, </xsl:text>
+    <xsl:value-of select="$sequence"/>
+    <xsl:text>, </xsl:text>
+    <xsl:value-of select="$position"/>
+    <xsl:text>, </xsl:text>
+    <xsl:value-of select="$gentext-key"/>
+  </fo:block>
+-->
+
+  <fo:block>
+
+    <!-- sequence can be odd, even, first, blank -->
+    <!-- position can be left, center, right -->
+    <xsl:choose>
+      <xsl:when test="$sequence = 'blank'">
+        <!-- nothing -->
+      </xsl:when>
+
+      <xsl:when test="$position='left'">
+        <!-- Same for odd, even, empty, and blank sequences -->
+        <!--
+        <xsl:call-template name="draft.text"/>
+        -->
+        <fo:external-graphic content-height="0.43cm">
+          <xsl:attribute name="src">
+            <xsl:call-template name="fo-external-image">
+              <xsl:with-param name="filename">../images/hypersql_logo2.png</xsl:with-param>
+            </xsl:call-template>
+          </xsl:attribute>
+        </fo:external-graphic>
+      </xsl:when>
+
+      <xsl:when test="($sequence='odd' or $sequence='even') and $position='right'">
+        <xsl:if test="$pageclass != 'titlepage'">
+          <xsl:choose>
+            <xsl:when test="ancestor::d:book and ($double.sided != 0)">
+              <fo:retrieve-marker retrieve-class-name="section.head.marker"
+                                  retrieve-position="first-including-carryover"
+                                  retrieve-boundary="page-sequence"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:apply-templates select="." mode="titleabbrev.markup"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:if>
+      </xsl:when>
+
+      <xsl:when test="$position='center'">
+        <!-- nothing for empty and blank sequences -->
+      </xsl:when>
+
+      <xsl:when test="$position='right'">
+        <!-- Same for odd, even, empty, and blank sequences -->
+        <xsl:call-template name="draft.text"/>
+      </xsl:when>
+
+      <xsl:when test="$sequence = 'first'">
+        <!-- nothing for first pages -->
+      </xsl:when>
+
+      <xsl:when test="$sequence = 'blank'">
+        <!-- nothing for blank pages -->
+      </xsl:when>
+    </xsl:choose>
+  </fo:block>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/testrun/hsqldb/TestSelf.txt b/testrun/hsqldb/TestSelf.txt
new file mode 100644
index 0000000..d9b1441
--- /dev/null
+++ b/testrun/hsqldb/TestSelf.txt
@@ -0,0 +1,1243 @@
+--

+-- TestSelf.txt

+--

+

+-- TestSelf.txt is used by TestSelf.java to test the database

+--

+-- Comment lines must start with -- and are ignored

+-- Lines starting with spaces belongs to last line

+-- Checked lines start with comments containing <tag> where <tag> is:

+--   c <rows>     ResultSet expects a with <rows> rows

+--   r <string>   ResultSet expected with <string> result in first row/column

+--   u <count>    Update count <count> expected

+--   e            Exception must occur

+

+-- Miscelaneous tests by fredt

+-- bug #897591

+/*rgood*/CALL CASEWHEN(CURTIME() BETWEEN CAST('00:00:00'  AS  TIME) AND CAST('23:59:59'  AS TIME), 'good', 'bad')

+

+-- Referential integrity with cascading delete

+-- identity column

+create table main(id int identity,name varchar(10))

+create table ref(id int identity,idMain int,

+  foreign key(idMain)references main(id) on delete cascade)

+create table ref2(id int identity,idMain int,

+  foreign key(idMain)references ref(id) on delete cascade)

+/*u1*/  insert into main values(null,'test')

+/*e*/   insert into ref values(null,2)

+/*u1*/  insert into ref values(null,0)

+/*u1*/  insert into main values(10,1)

+-- next main.id value should be 11

+/*u1*/  insert into main values(null,1)

+/*u1*/  insert into ref values(null,11)

+/*e*/   insert into ref values(null,12)

+/*u1*/  insert into ref2 values(null,1)

+/*u3*/  delete from main

+/*c0*/  select * from main

+/*c0*/  select * from ref

+/*c0*/  select * from ref2

+/*u1*/  insert into main values(1,'test')

+/*u1*/  insert into main values(2,'test2')

+/*u1*/  insert into ref values(2,2)

+/*e*/   update main set id=2-id

+/*e*/   drop table main;

+drop table ref2;drop table ref;drop table main

+

+-- Data Definition

+drop table T1 if exists

+drop table T2 if exists

+create table T1(Nr integer)

+create table T2(Nr integer primary Key)

+create table T3(Nr integer,dbl double,vc varchar(10),cc char(1))

+create table T4(nr integer,lvc longVarChar(100),dt date,tm time)

+create table T5(dec decimal(10) primary key,b binary(1) not null)

+create table "T6"("x" tinyint,s smallint not null,b bigint)

+create table t7("-x's'-" real,f float(2),n numeric,t timestamp)

+create table t8(bin binary,vb varbinary(10),lvb longvarbinary(100))

+create table t9(nr integer not null,x smallint not null primary key)

+create unique index it1 on t1(nr)

+script

+create index it2 on t2(nr)

+create index it3 on t3(nr,dbl,vc,cc)

+create unique index it4 on t4(nr,lvc,tm)

+drop index it4

+create unique index it4 on t4(nr,tm)

+drop index it4

+create index it4 on t4(tm,nr)

+-- a duplicate index

+create index it4b on t4(tm,nr)

+create unique index it4c on t4(tm,nr)

+drop index it4b

+create index it9 on t9(nr,x);

+drop table t1;drop table t2;drop table "T3";

+DROP TABLE T4;Drop Table T5; drop table T6

+drop table t7; drop table t8; drop table t9

+create user "test" password "test-p"

+GRANT CHANGE_AUTHORIZATION TO "test"

+create table test (id integer)

+revoke all on test from "test" restrict

+select * from test order by test.id

+grant all on test to "test"

+grant select on test to "test"

+revoke select,insert,update,delete on test from "test" restrict

+connect user "test" password "test-p"

+set password "test-p2"

+connect user sa password ""

+connect user "test" password "test-p2"

+connect user sa password ""

+set autocommit false

+insert into test values (1)

+update test set id = 3

+rollback

+insert into test values (2)

+delete from test

+rollback

+commit

+script

+drop table test

+drop user "test"

+script

+set autocommit true

+create memory table test (id integer)

+drop table test

+-- still supporting noise word "null" after type definition

+create cached table test (id integer null)

+drop table test

+-- Data Manipulation without result

+create table address(nr integer,name varchar(16),placezip smallint)

+insert into address values(1,'Boss',3000)

+insert into address (nr,name,placezip) values(2,'Walt',8000)

+insert into address values(-3,'',0)

+insert into address select * from address where nr>0

+update address set nr=4 where nr=-2

+insert into address values(3,'x',3000)

+insert into address (name,nr,placezip) values('y',4,8000)

+insert into address (name,nr,placezip)

+  select name,placezip,nr from address where name like 'x%'

+delete from address where name like 'x%'

+update address set name='Rene' where nr=4

+update address set nr=5, name='What' where nr=1 and name='Boss'

+create table place(zip smallint,name longvarchar(100),country char(4))

+insert into place values(3000,'Langenthal\t1','CH')

+insert into place values(0,'\\\\Heaven',null)

+insert into place values(8000,'Z�rich','CH')

+insert into place values(-1,'NULL','null')

+create table invoice(addressnr integer,total decimal)

+insert into invoice values(4,1003834.05)

+insert into invoice values(2,-4987770.01)

+insert into invoice select * from invoice where not total>=0.

+update invoice set total=10 where total < 0

+insert into invoice values(2,10)

+set schema INFORMATION_SCHEMA

+select * from system_tables

+select * from SYSTEM_SESSIONINFO

+set schema PUBLIC

+create table t_double(id integer,d double,f double)

+insert into t_double values(1,1.2,1.4)

+insert into t_double values(2,1.4,1.0)

+create table t_date (id integer,d date,t time,ts timestamp )

+insert into t_DATE values(0,{d '1999-08-21'},'18:53:00',null)

+insert into t_date values(1,'1999-08-22','17:00:01','2000-02-29 10:00:00')

+create table t_bit (b1 boolean,b2 boolean)

+insert into t_bit values(false,false)

+insert into t_bit select b2,b1 from t_bit

+insert into t_bit values(true,false)

+insert into t_bit values(true,true)

+create table Problem(Nr bigint,ClassNr bigint,StateNr bigint,Name varchar(40));

+create table Class(Nr bigint, Name varchar(20), Node varchar(20));

+insert into Problem values(10, 1, 3, 'Problem 10; Class 1; State 3');

+insert into Problem values(20, 2, 2, 'Problem 20; Class 2; State 2');

+insert into Problem values(30, 3, 2, 'Problem 30; Class 3; State 2');

+insert into Class values(1, 'Class/State 1','Node A');

+insert into Class values(2, 'Class/State 2','Node B');

+insert into Class values(3, 'Class/State 3','Node C');

+CREATE CACHED TABLE HLO(NRO INTEGER,NIMI VARCHAR(10),PTMP INTEGER)

+CREATE INDEX INRO ON HLO(NRO)

+INSERT INTO HLO VALUES(1,'hlo 1',0)

+INSERT INTO HLO VALUES(2,'hlo 2',0)

+INSERT INTO HLO VALUES(3,'hlo 3',0)

+INSERT INTO HLO VALUES(4,'hlo 4',0)

+INSERT INTO HLO VALUES(5,'hlo 5',0)

+insert into hlo values(10,'10',0);

+delete from hlo where nro=10;

+DROP TABLE HLO

+

+-- Select with update count

+/*c6*/ select * from address

+/*c0*/ select * from address where nr in(-1)

+/*c4*/ select * from place

+/*c4*/ select * from invoice

+/*c1*/ select nr from address where nr<0

+/*c0*/ select * from address where nr>=0 and nr<=0

+/*c1*/ select count(*) from address where nr=-99

+/*c0*/ select * from address where not name like '%'

+/*c1*/ select * from address,place p where (nr=4) and p.zip=placezip

+/*c1*/ select * from address,place p where (nr=4 or nr>3 and nr<2) and

+  p.zip=placezip or (p.zip>0 and p.zip<-1 or p.zip=-2)

+/*c1*/select * from address a,place p,invoice i where

+  a.placezip=p.zip and a.nr=i.addressnr and i.addressnr=4

+/*c1*/ select p.zip,p.*,country from address a,place p,invoice i where

+  a.placezip=p.zip and a.nr=i.addressnr and i.addressnr=4

+/*c7*/ select * from address union all select * from address where nr=4

+/*c1*/ select max(place.zip) x from place

+/*c0*/ select * from address where name like 'Wal_' escape 'l'

+/*c2*/ select * from address where name like 'Wal_' escape '+'

+/*c4*/ select total as x from invoice order by addressnr desc,total asc

+/*c3*/ select place.* from place where not country = 'NULL' and

+  not name is null and not name is NULL and

+  not name = 'null' and not country = 'NULL' order by zip

+/*c3*/ select * from address where nr in (1,5,99,5,4)

+/*c1*/ select * from (select * from address) as address where nr=4

+-- from 1.7.2, next result no longer returns null == null

+/*c5*/ select p1.country from place p1,place p2 where p1.country=p2.country

+/*c1*/ select * from t_double where id>-10 and d>1.3 and d>.3

+/*c2*/ select * from t_double where d>-20 or f<10.2

+/*c2*/ select d,t,d from t_date where d>'1900-08-21';

+/*e*/ select d,*,d from t_date where ts>'2000-01-01 00:00:00'

+/*e*/ select t_date.*,* from t_date where t<='01:00:00'

+/*c2*/ select * from t_bit where b1<=false or b2>true

+/*c2*/ select * from t_bit where not(b1<=false or b2>true)

+/*c2*/ select P.*, C.Name ClassName from Problem P,Class C

+  where P.Nr in(10,20) and P.ClassNr=C.Nr

+/*c1*/ select P.*, S.Name StateName, S.Node StateNode,

+  C.Name ClassName, C.Node ClassNode from Problem P, Class S, Class C

+  where P.Nr = 10 and P.ClassNr = C.Nr and P.StateNr = S.Nr

+

+-- ResultSet with value

+/*u0*/ create table empty(c char);

+

+/*u0*/ create table test(nr integer,name char(5));

+/*r0*/ select count(*) from test;

+/*u1*/ insert into test values(1,null);

+/*r1*/ select nr from test group by nr;

+/*r2*/ update test set nr=2;select avg(nr) from test

+/*r3*/ update test set nr=1+1*2;select sum(nr) from test

+/*r-3*/ update test set nr=-(select max(t2.nr) from test t2);select nr from test

+/*r4*/ update test set nr=2*(1- -1);select nr from test

+/*r4*/ select sum(nr) from test where nr in(select t2.nr from test t2)

+/*e*/ update test set nr=1/0

+update test set nr=null;

+/*rNULL*/ select nr from test

+update test set nr=null;

+/*rNULL*/ select nr from test

+/*r2*/ update test set nr=4/2;select "TEST"."NR" from test

+/*r34   */ update test set name='3' || '4';select distinct name from test

+/*rHo*/ select 'Ho' as hhoo from TEsT where name in ('34','y','z')

+update test set name=null;

+/*rNULL*/select name from "TEST"

+-- case sensitivity tests

+create table "t6"("x" char(6),s smallint not null,b bigint, c binary);

+/*r0*/ select count(*) from "t6"

+/*u1*/ insert into "t6" values('CaseS',100, 1000000000000, null);

+/*rCaseS */ select "x" from "t6"

+/*u1*/ delete from "t6"

+/*u1*/ insert into "t6" values(null,100, 1000000000000, null);

+/*u1*/ delete from "t6"

+-- Finish

+drop table address drop table place drop table invoice

+drop table t_double;drop table t_date drop table t_bit

+drop table problem; drop table class

+

+-- Other tests

+CREATE TABLE Address(ID INTEGER PRIMARY KEY,organization VARCHAR(20),

+  address1 VARCHAR(20),address2 VARCHAR(20),address3 VARCHAR(20),city VARCHAR(20),

+  state VARCHAR(20),zipCode VARCHAR(20),countryID INTEGER,phone VARCHAR(20),

+  phoneExtension VARCHAR(20),fax VARCHAR(20),eMail VARCHAR(20))

+CREATE TABLE Country(ID INTEGER PRIMARY KEY,name VARCHAR(20))

+INSERT INTO COUNTRY(ID, name) VALUES(23, 'USA')

+/*u1*/INSERT INTO ADDRESS(ID, countryID) VALUES(5,

+  (SELECT ID FROM Country WHERE name = 'USA'))

+SELECT * FROM ADDRESS INNER JOIN COUNTRY ON CountryID = COUNTRY.ID

+SELECT * FROM ADDRESS LEFT JOIN COUNTRY ON CountryID = COUNTRY.ID

+INSERT INTO ADDRESS(ID) VALUES(6)

+/*c1*/SELECT * FROM ADDRESS ad INNER JOIN COUNTRY ON ad.CountryID = COUNTRY.ID

+/*c2*/SELECT * FROM ADDRESS LEFT JOIN COUNTRY ON CountryID = COUNTRY.ID

+SELECT * FROM Address,Country

+  WHERE Address.countryID=Country.ID AND

+  EXISTS (SELECT C.Name FROM Country AS C WHERE C.ID=Country.ID) AND

+  EXISTS (SELECT * FROM Country AS C WHERE C.ID=Address.countryID)

+

+

+-- retain metadata

+CREATE TABLE META_TEST( ID numeric(10), GEOX decimal(10,2), BLURB VARCHAR(50));

+

+

+-- ignorecase tests

+create table test_ic(name varchar_ignorecase(20))

+insert into test_ic values('Hello')

+insert into test_ic values('World')

+/*c0*/select * from test_ic where name like 'HALLO'

+/*c1*/select * from test_ic where name like 'HELLO'

+/*c1*/select * from test_ic where 'HELLO' like name

+/*c1*/select * from test_ic where name = 'world'

+drop table test_ic

+

+-- test maxrows

+create table test_maxrows(id int)

+insert into test_maxrows values(0);

+insert into test_maxrows select id+1 from test_maxrows;

+insert into test_maxrows select id+2 from test_maxrows;

+insert into test_maxrows select id+4 from test_maxrows;

+/*r

+ 4

+ 3

+ 2

+ 1

+*/select id from test_maxrows order by id desc limit 4 offset 3

+/*r

+ 4

+ 3

+ 2

+ 1

+*/select id from test_maxrows order by id desc offset 3 fetch 4 rows only

+/*r

+ 4

+ 3

+*/select id from test_maxrows order by id desc limit 2 offset 3

+set maxrows 3

+/*c3*/select * from test_maxrows

+set maxrows 3

+/*c3*/select id from test_maxrows order by id desc

+set maxrows 3

+/*r

+ 7

+ 6

+ 5

+*/select id from test_maxrows order by id desc

+set maxrows 3

+/*r

+ 4

+ 3

+ 2

+*/select id from test_maxrows order by id desc limit 4 offset 3

+set maxrows 3

+/*r

+ 4

+ 3

+*/select id from test_maxrows order by id desc limit 2 offset 3

+set maxrows 3

+/*r8*/select count(*) from test_maxrows

+set maxrows 3

+/*r7*/select max(id) from test_maxrows

+set maxrows 3

+/*c0*/select id from test_maxrows except select id from test_maxrows

+set maxrows 3

+/*c3*/select id from test_maxrows group by id

+set maxrows 0

+/*c8*/select * from test_maxrows

+drop table test_maxrows

+

+-- test functions

+CREATE TABLE Product(ID INTEGER PRIMARY KEY,Name VARCHAR(255),Cost DECIMAL(10,4))

+insert into product values (0,'Test',10.3444)

+/*r10.34E0*/select round(cost,2) from product

+/*r10.3444*/select cost from product

+drop table product

+

+-- IN (subquery)

+create table A ( C1 VARCHAR(10))

+create table B ( C1 VARCHAR(10))

+insert into A (C1) values ('one')

+insert into A (C1) values ('two')

+insert into B (C1) values ('one')

+/*c1*/ select * from B where C1 in (select C1 from A)

+drop table A

+drop table B

+

+-- simple transactional tests

+CREATE TABLE PRODUCT(ID INTEGER PRIMARY KEY,NAME VARCHAR(20),COST DECIMAL(10,4))

+INSERT INTO PRODUCT VALUES(0,'Iron',5.4)

+INSERT INTO PRODUCT VALUES(1,'Wood',24.8)

+INSERT INTO PRODUCT VALUES(2,'Fire',24.8)

+SET AUTOCOMMIT FALSE

+INSERT INTO PRODUCT VALUES(3,'ERR1',0.0)

+INSERT INTO PRODUCT VALUES(4,'ERR1',0.0)

+DELETE FROM PRODUCT WHERE ID=2

+UPDATE PRODUCT SET NAME='ERR2' WHERE NAME<>'ERR1'

+/*c2*/ SELECT * FROM PRODUCT WHERE NAME='ERR1'

+/*c2*/ SELECT * FROM PRODUCT WHERE NAME='ERR2'

+/*c4*/ SELECT * FROM PRODUCT

+ROLLBACK

+/*c0*/ SELECT * FROM PRODUCT WHERE NAME='ERR1'

+/*c0*/ SELECT * FROM PRODUCT WHERE NAME='ERR2'

+/*c3*/ SELECT * FROM PRODUCT

+SET AUTOCOMMIT TRUE

+DROP TABLE PRODUCT

+

+

+

+

+-- Exceptions

+/*e*/ +

+/*e*/ select nr from address union select nr,nr from address

+/*e*/ create something

+/*e*/ create index x on address (nr +

+/*e*/ create table p2 (id integer primary key, id2 integer primary key)

+/*e*/ create table p3 (id integer primary key + 2)

+/*e*/ drop index x

+/*e*/ drop all

+/*e*/ create table test(nr integer); insert into test values (10 and)

+/*e*/ select oh from test

+/*e*/ create table test(nr integer)

+/*e*/ create user 'test' password 'test';connect user 'test' password 'test';

+  select * from test;

+/*e*/ connect user 'sa' password ''; drop user 'test'; drop it now

+/*e*/ insert into test values(1);insert into test rows

+/*e*/ create unique index i1 on test(id);select * from (oh what)

+/*e*/ insert into test values(2); update test set id=1;

+/*e*/ select * from test where id in (1 (2) 3)

+/*e*/ select o.* from test

+/*e*/ select * from test where id like '0' escape 'maybe'

+/*e*/ insert into test (nr and so on) values (1)

+/*e*/ insert into test values (select * from test union select * from test)

+/*e*/ update test set nr=1+(3+5 'x'

+/*e*/ update test set nr=1.....3

+/*e*/ select *.* from test

+/*e*/ select * from test where id>2 and (id>3;

+/*e*/ select * from test order it

+/*e*/ creat unique index 1

+/*e*/ select id from test where yes>2;

+/*e*/ select id from test where id has 5

+/*e*/ grant access

+/*e*/ connect user or maybe not

+/*e*/ set parameter

+/*e*/ set autocommit and

+/*e*/ select column as column plus

+/*e*/ select * from hm

+/*e*/ grant all about it

+/*e*/ create table wrong(id usertype)

+/*e*/ select #strange#

+/*e*/ create table mem(i int)drop table mem",

+

+-- ResultSet with sizes

+drop table test;

+create table test(nr integer,name char(5), other varchar(10));

+/*r0*/ select count(*) from test;

+insert into test values(1,null,null);

+/*r1*/ select nr from test group by nr;

+/*e*/ insert into test values(2,'1234567','');

+/*u1*/ insert into test values(2,'12345','');

+/*r12345*/ select name from test where nr=2;

+/*r123  */insert into test values(3,'123',''); select name from test where nr=3;

+/*r12345*/ insert into test values(4,'','12345'); select other from test where nr=4;

+insert into test values(5,'','123');

+/*r123*/ select other from test where nr=5;

+drop table test;

+

+DROP TABLE ITEM IF EXISTS

+DROP TABLE CUSTOMER IF EXISTS

+DROP TABLE PRODUCT IF EXISTS

+DROP TABLE ADDRESS IF EXISTS

+CREATE TABLE CUSTOMER(ID INTEGER PRIMARY KEY,FIRSTNAME VARCHAR(255),

+    LASTNAME VARCHAR(255),STREET VARCHAR(255),CITY VARCHAR(255))

+CREATE TABLE PRODUCT(ID INTEGER PRIMARY KEY,NAME VARCHAR(255),COST DECIMAL)

+CREATE TABLE INVOICE(ID INTEGER PRIMARY KEY,ADDRESSID INTEGER,TOTAL DECIMAL)

+CREATE TABLE ITEM(DOCUMENTID INTEGER,POS INTEGER,PRODUCTID INTEGER,

+    QUANTITY INTEGER,PRICE DECIMAL,

+    CONSTRAINT SYSTEM_PK PRIMARY KEY(DOCUMENTID,POS))

+INSERT INTO CUSTOMER VALUES(0,'Laura','Steel','429 Seventh Av.','Dallas')

+INSERT INTO CUSTOMER VALUES(1,'Susanne','King','366 - 20th Ave.','Olten')

+INSERT INTO CUSTOMER VALUES(2,'Anne','Miller','20 Upland Pl.','Lyon')

+INSERT INTO CUSTOMER VALUES(3,'Michael','Clancy','542 Upland Pl.','San Francisco')

+INSERT INTO CUSTOMER VALUES(4,'Sylvia','Ringer','365 College Av.','Dallas')

+INSERT INTO CUSTOMER VALUES(5,'Laura','Miller','294 Seventh Av.','Paris')

+INSERT INTO CUSTOMER VALUES(6,'Laura','White','506 Upland Pl.','Palo Alto')

+INSERT INTO CUSTOMER VALUES(7,'James','Peterson','231 Upland Pl.','San Francisco')

+INSERT INTO CUSTOMER VALUES(8,'Andrew','Miller','288 - 20th Ave.','Seattle')

+INSERT INTO CUSTOMER VALUES(9,'James','Schneider','277 Seventh Av.','Berne')

+INSERT INTO CUSTOMER VALUES(10,'Anne','Fuller','135 Upland Pl.','Dallas')

+INSERT INTO CUSTOMER VALUES(11,'Julia','White','412 Upland Pl.','Chicago')

+INSERT INTO CUSTOMER VALUES(12,'George','Ott','381 Upland Pl.','Palo Alto')

+INSERT INTO CUSTOMER VALUES(13,'Laura','Ringer','38 College Av.','New York')

+INSERT INTO CUSTOMER VALUES(14,'Bill','Karsen','53 College Av.','Oslo')

+INSERT INTO CUSTOMER VALUES(15,'Bill','Clancy','319 Upland Pl.','Seattle')

+INSERT INTO CUSTOMER VALUES(16,'John','Fuller','195 Seventh Av.','New York')

+INSERT INTO CUSTOMER VALUES(17,'Laura','Ott','443 Seventh Av.','Lyon')

+INSERT INTO CUSTOMER VALUES(18,'Sylvia','Fuller','158 - 20th Ave.','Paris')

+INSERT INTO CUSTOMER VALUES(19,'Susanne','Heiniger','86 - 20th Ave.','Dallas')

+INSERT INTO CUSTOMER VALUES(20,'Janet','Schneider','309 - 20th Ave.','Oslo')

+INSERT INTO CUSTOMER VALUES(21,'Julia','Clancy','18 Seventh Av.','Seattle')

+INSERT INTO CUSTOMER VALUES(22,'Bill','Ott','250 - 20th Ave.','Berne')

+INSERT INTO CUSTOMER VALUES(23,'Julia','Heiniger','358 College Av.','Boston')

+INSERT INTO CUSTOMER VALUES(24,'James','Sommer','333 Upland Pl.','Olten')

+INSERT INTO CUSTOMER VALUES(25,'Sylvia','Steel','269 College Av.','Paris')

+INSERT INTO CUSTOMER VALUES(26,'James','Clancy','195 Upland Pl.','Oslo')

+INSERT INTO CUSTOMER VALUES(27,'Bob','Sommer','509 College Av.','Seattle')

+INSERT INTO CUSTOMER VALUES(28,'Susanne','White','74 - 20th Ave.','Lyon')

+INSERT INTO CUSTOMER VALUES(29,'Andrew','Smith','254 College Av.','New York')

+INSERT INTO CUSTOMER VALUES(30,'Bill','Sommer','362 - 20th Ave.','Olten')

+INSERT INTO CUSTOMER VALUES(31,'Bob','Ringer','371 College Av.','Olten')

+INSERT INTO CUSTOMER VALUES(32,'Michael','Ott','339 College Av.','Boston')

+INSERT INTO CUSTOMER VALUES(33,'Mary','King','491 College Av.','Oslo')

+INSERT INTO CUSTOMER VALUES(34,'Julia','May','33 Upland Pl.','Seattle')

+INSERT INTO CUSTOMER VALUES(35,'George','Karsen','412 College Av.','Chicago')

+INSERT INTO CUSTOMER VALUES(36,'John','Steel','276 Upland Pl.','Dallas')

+INSERT INTO CUSTOMER VALUES(37,'Michael','Clancy','19 Seventh Av.','Dallas')

+INSERT INTO CUSTOMER VALUES(38,'Andrew','Heiniger','347 College Av.','Lyon')

+INSERT INTO CUSTOMER VALUES(39,'Mary','Karsen','202 College Av.','Chicago')

+INSERT INTO CUSTOMER VALUES(40,'Susanne','Miller','440 - 20th Ave.','Dallas')

+INSERT INTO CUSTOMER VALUES(41,'Bill','King','546 College Av.','New York')

+INSERT INTO CUSTOMER VALUES(42,'Robert','Ott','503 Seventh Av.','Oslo')

+INSERT INTO CUSTOMER VALUES(43,'Susanne','Smith','2 Upland Pl.','Dallas')

+INSERT INTO CUSTOMER VALUES(44,'Sylvia','Ott','361 College Av.','New York')

+INSERT INTO CUSTOMER VALUES(45,'Janet','May','396 Seventh Av.','Oslo')

+INSERT INTO CUSTOMER VALUES(46,'Andrew','May','172 Seventh Av.','New York')

+INSERT INTO CUSTOMER VALUES(47,'Janet','Fuller','445 Upland Pl.','Dallas')

+INSERT INTO CUSTOMER VALUES(48,'Robert','White','549 Seventh Av.','San Francisco')

+INSERT INTO CUSTOMER VALUES(49,'George','Fuller','534 - 20th Ave.','Olten')

+INSERT INTO PRODUCT VALUES(0,'Iron Iron',5.4)

+INSERT INTO PRODUCT VALUES(1,'Chair Shoe',24.8)

+INSERT INTO PRODUCT VALUES(2,'Telephone Clock',24.8)

+INSERT INTO PRODUCT VALUES(3,'Chair Chair',25.4)

+INSERT INTO PRODUCT VALUES(4,'Ice Tea Shoe',12.8)

+INSERT INTO PRODUCT VALUES(5,'Clock Clock',23.6)

+INSERT INTO PRODUCT VALUES(6,'Ice Tea Chair',9.8)

+INSERT INTO PRODUCT VALUES(7,'Telephone Shoe',8.4)

+INSERT INTO PRODUCT VALUES(8,'Ice Tea Clock',22.6)

+INSERT INTO PRODUCT VALUES(9,'Clock Telephone',17.2)

+INSERT INTO PRODUCT VALUES(10,'Telephone Ice Tea',20.4)

+INSERT INTO PRODUCT VALUES(11,'Telephone Iron',8.8)

+INSERT INTO PRODUCT VALUES(12,'Clock Ice Tea',16.8)

+INSERT INTO PRODUCT VALUES(13,'Telephone Clock',18.0)

+INSERT INTO PRODUCT VALUES(14,'Telephone Iron',12.4)

+INSERT INTO PRODUCT VALUES(15,'Ice Tea Chair',9.4)

+INSERT INTO PRODUCT VALUES(16,'Ice Tea Shoe',19.4)

+INSERT INTO PRODUCT VALUES(17,'Clock Ice Tea',22.0)

+INSERT INTO PRODUCT VALUES(18,'Chair Clock',17.2)

+INSERT INTO PRODUCT VALUES(19,'Ice Tea Ice Tea',11.0)

+INSERT INTO PRODUCT VALUES(20,'Ice Tea Telephone',20.0)

+INSERT INTO PRODUCT VALUES(21,'Chair Chair',11.4)

+INSERT INTO PRODUCT VALUES(22,'Iron Iron',6.6)

+INSERT INTO PRODUCT VALUES(23,'Shoe Chair',7.6)

+INSERT INTO PRODUCT VALUES(24,'Chair Shoe',7.2)

+INSERT INTO PRODUCT VALUES(25,'Shoe Shoe',16.2)

+INSERT INTO PRODUCT VALUES(26,'Shoe Shoe',25.2)

+INSERT INTO PRODUCT VALUES(27,'Telephone Iron',23.0)

+INSERT INTO PRODUCT VALUES(28,'Clock Iron',3.0)

+INSERT INTO PRODUCT VALUES(29,'Chair Telephone',11.2)

+INSERT INTO PRODUCT VALUES(30,'Shoe Iron',23.2)

+INSERT INTO PRODUCT VALUES(31,'Ice Tea Telephone',4.8)

+INSERT INTO PRODUCT VALUES(32,'Clock Iron',19.0)

+INSERT INTO PRODUCT VALUES(33,'Iron Chair',18.2)

+INSERT INTO PRODUCT VALUES(34,'Chair Iron',25.6)

+INSERT INTO PRODUCT VALUES(35,'Telephone Shoe',7.6)

+INSERT INTO PRODUCT VALUES(36,'Ice Tea Iron',3.2)

+INSERT INTO PRODUCT VALUES(37,'Clock Shoe',9.4)

+INSERT INTO PRODUCT VALUES(38,'Clock Ice Tea',21.6)

+INSERT INTO PRODUCT VALUES(39,'Ice Tea Shoe',15.4)

+INSERT INTO PRODUCT VALUES(40,'Shoe Clock',2.8)

+INSERT INTO PRODUCT VALUES(41,'Clock Ice Tea',20.6)

+INSERT INTO PRODUCT VALUES(42,'Iron Chair',19.8)

+INSERT INTO PRODUCT VALUES(43,'Telephone Clock',9.4)

+INSERT INTO PRODUCT VALUES(44,'Ice Tea Ice Tea',9.6)

+INSERT INTO PRODUCT VALUES(45,'Iron Ice Tea',18.0)

+INSERT INTO PRODUCT VALUES(46,'Ice Tea Clock',6.2)

+INSERT INTO PRODUCT VALUES(47,'Ice Tea Iron',17.8)

+INSERT INTO PRODUCT VALUES(48,'Clock Clock',21.0)

+INSERT INTO PRODUCT VALUES(49,'Iron Iron',2.2)

+INSERT INTO INVOICE VALUES(0,0,2607.60)

+INSERT INTO INVOICE VALUES(1,33,1610.70)

+INSERT INTO INVOICE VALUES(2,23,3789.00)

+INSERT INTO INVOICE VALUES(3,21,5974.50)

+INSERT INTO INVOICE VALUES(4,30,1953.00)

+INSERT INTO INVOICE VALUES(5,34,4182.90)

+INSERT INTO INVOICE VALUES(6,19,3340.20)

+INSERT INTO INVOICE VALUES(7,26,5328.60)

+INSERT INTO INVOICE VALUES(8,29,2675.10)

+INSERT INTO INVOICE VALUES(9,38,6982.20)

+INSERT INTO INVOICE VALUES(10,24,3274.50)

+INSERT INTO INVOICE VALUES(11,24,2532.30)

+INSERT INTO INVOICE VALUES(12,23,4578.30)

+INSERT INTO INVOICE VALUES(13,39,7001.70)

+INSERT INTO INVOICE VALUES(14,35,4940.40)

+INSERT INTO INVOICE VALUES(15,39,1027.80)

+INSERT INTO INVOICE VALUES(16,45,3657.30)

+INSERT INTO INVOICE VALUES(17,46,3776.40)

+INSERT INTO INVOICE VALUES(18,4,3772.80)

+INSERT INTO INVOICE VALUES(19,9,804.30)

+INSERT INTO INVOICE VALUES(20,19,3139.20)

+INSERT INTO INVOICE VALUES(21,8,3740.10)

+INSERT INTO INVOICE VALUES(22,40,2289.90)

+INSERT INTO INVOICE VALUES(23,36,5166.60)

+INSERT INTO INVOICE VALUES(24,15,4344.30)

+INSERT INTO INVOICE VALUES(25,31,2054.10)

+INSERT INTO INVOICE VALUES(26,27,4972.80)

+INSERT INTO INVOICE VALUES(27,24,583.50)

+INSERT INTO INVOICE VALUES(28,35,1664.40)

+INSERT INTO INVOICE VALUES(29,46,2515.50)

+INSERT INTO INVOICE VALUES(30,13,2117.40)

+INSERT INTO INVOICE VALUES(31,22,2715.90)

+INSERT INTO INVOICE VALUES(32,20,1098.60)

+INSERT INTO INVOICE VALUES(33,40,4300.20)

+INSERT INTO INVOICE VALUES(34,33,4290.60)

+INSERT INTO INVOICE VALUES(35,4,3102.60)

+INSERT INTO INVOICE VALUES(36,42,3200.10)

+INSERT INTO INVOICE VALUES(37,39,7331.10)

+INSERT INTO INVOICE VALUES(38,46,6373.80)

+INSERT INTO INVOICE VALUES(39,5,1311.60)

+INSERT INTO INVOICE VALUES(40,4,5288.40)

+INSERT INTO INVOICE VALUES(41,19,5475.60)

+INSERT INTO INVOICE VALUES(42,38,1436.40)

+INSERT INTO INVOICE VALUES(43,13,4827.60)

+INSERT INTO INVOICE VALUES(44,32,3388.20)

+INSERT INTO INVOICE VALUES(45,42,4731.00)

+INSERT INTO INVOICE VALUES(46,24,5827.20)

+INSERT INTO INVOICE VALUES(47,45,2320.80)

+INSERT INTO INVOICE VALUES(48,22,3494.70)

+INSERT INTO INVOICE VALUES(49,32,4944.30)

+INSERT INTO ITEM VALUES(0,0,7,12,12.60)

+INSERT INTO ITEM VALUES(0,1,14,19,18.60)

+INSERT INTO ITEM VALUES(0,2,47,3,26.70)

+INSERT INTO ITEM VALUES(0,3,1,9,37.20)

+INSERT INTO ITEM VALUES(0,4,47,1,26.70)

+INSERT INTO ITEM VALUES(0,5,12,15,25.20)

+INSERT INTO ITEM VALUES(0,6,16,9,29.10)

+INSERT INTO ITEM VALUES(0,7,7,10,12.60)

+INSERT INTO ITEM VALUES(0,8,0,23,8.10)

+INSERT INTO ITEM VALUES(0,9,35,4,11.40)

+INSERT INTO ITEM VALUES(0,10,4,8,19.20)

+INSERT INTO ITEM VALUES(0,11,12,4,25.20)

+INSERT INTO ITEM VALUES(0,12,1,11,37.20)

+INSERT INTO ITEM VALUES(1,0,40,8,4.20)

+INSERT INTO ITEM VALUES(1,1,0,9,8.10)

+INSERT INTO ITEM VALUES(1,2,19,6,16.50)

+INSERT INTO ITEM VALUES(1,3,38,8,32.40)

+INSERT INTO ITEM VALUES(1,4,16,16,29.10)

+INSERT INTO ITEM VALUES(1,5,25,9,24.30)

+INSERT INTO ITEM VALUES(1,6,25,19,24.30)

+INSERT INTO ITEM VALUES(2,0,4,18,19.20)

+INSERT INTO ITEM VALUES(2,1,25,3,24.30)

+INSERT INTO ITEM VALUES(2,2,11,9,13.20)

+INSERT INTO ITEM VALUES(2,3,19,13,16.50)

+INSERT INTO ITEM VALUES(2,4,38,18,32.40)

+INSERT INTO ITEM VALUES(2,5,30,4,34.80)

+INSERT INTO ITEM VALUES(2,6,43,8,14.10)

+INSERT INTO ITEM VALUES(2,7,30,5,34.80)

+INSERT INTO ITEM VALUES(2,8,39,2,23.10)

+INSERT INTO ITEM VALUES(2,9,18,7,25.80)

+INSERT INTO ITEM VALUES(2,10,49,11,3.30)

+INSERT INTO ITEM VALUES(2,11,42,21,29.70)

+INSERT INTO ITEM VALUES(2,12,21,15,17.10)

+INSERT INTO ITEM VALUES(2,13,12,1,25.20)

+INSERT INTO ITEM VALUES(2,14,48,19,31.50)

+INSERT INTO ITEM VALUES(2,15,0,18,8.10)

+INSERT INTO ITEM VALUES(2,16,36,24,4.80)

+INSERT INTO ITEM VALUES(3,0,11,21,13.20)

+INSERT INTO ITEM VALUES(3,1,1,20,37.20)

+INSERT INTO ITEM VALUES(3,2,49,3,3.30)

+INSERT INTO ITEM VALUES(3,3,0,22,8.10)

+INSERT INTO ITEM VALUES(3,4,20,12,30.00)

+INSERT INTO ITEM VALUES(3,5,30,10,34.80)

+INSERT INTO ITEM VALUES(3,6,13,18,27.00)

+INSERT INTO ITEM VALUES(3,7,26,4,37.80)

+INSERT INTO ITEM VALUES(3,8,49,9,3.30)

+INSERT INTO ITEM VALUES(3,9,29,17,16.80)

+INSERT INTO ITEM VALUES(3,10,10,17,30.60)

+INSERT INTO ITEM VALUES(3,11,7,11,12.60)

+INSERT INTO ITEM VALUES(3,12,41,22,30.90)

+INSERT INTO ITEM VALUES(3,13,41,2,30.90)

+INSERT INTO ITEM VALUES(3,14,17,22,33.00)

+INSERT INTO ITEM VALUES(3,15,23,18,11.40)

+INSERT INTO ITEM VALUES(3,16,19,11,16.50)

+INSERT INTO ITEM VALUES(3,17,30,17,34.80)

+INSERT INTO ITEM VALUES(4,0,28,9,4.50)

+INSERT INTO ITEM VALUES(4,1,35,15,11.40)

+INSERT INTO ITEM VALUES(4,2,41,23,30.90)

+INSERT INTO ITEM VALUES(4,3,23,20,11.40)

+INSERT INTO ITEM VALUES(4,4,9,18,25.80)

+INSERT INTO ITEM VALUES(4,5,37,24,14.10)

+INSERT INTO ITEM VALUES(5,0,9,5,25.80)

+INSERT INTO ITEM VALUES(5,1,9,23,25.80)

+INSERT INTO ITEM VALUES(5,2,20,18,30.00)

+INSERT INTO ITEM VALUES(5,3,24,12,10.80)

+INSERT INTO ITEM VALUES(5,4,32,14,28.50)

+INSERT INTO ITEM VALUES(5,5,46,15,9.30)

+INSERT INTO ITEM VALUES(5,6,7,9,12.60)

+INSERT INTO ITEM VALUES(5,7,2,4,37.20)

+INSERT INTO ITEM VALUES(5,8,20,3,30.00)

+INSERT INTO ITEM VALUES(5,9,37,9,14.10)

+INSERT INTO ITEM VALUES(5,10,28,18,4.50)

+INSERT INTO ITEM VALUES(5,11,38,23,32.40)

+INSERT INTO ITEM VALUES(5,12,8,15,33.90)

+INSERT INTO ITEM VALUES(5,13,18,17,25.80)

+INSERT INTO ITEM VALUES(6,0,15,20,14.10)

+INSERT INTO ITEM VALUES(6,1,38,21,32.40)

+INSERT INTO ITEM VALUES(6,2,23,8,11.40)

+INSERT INTO ITEM VALUES(6,3,30,2,34.80)

+INSERT INTO ITEM VALUES(6,4,31,20,7.20)

+INSERT INTO ITEM VALUES(6,5,14,20,18.60)

+INSERT INTO ITEM VALUES(6,6,37,22,14.10)

+INSERT INTO ITEM VALUES(6,7,26,10,37.80)

+INSERT INTO ITEM VALUES(6,8,41,19,30.90)

+INSERT INTO ITEM VALUES(6,9,19,2,16.50)

+INSERT INTO ITEM VALUES(6,10,16,13,29.10)

+INSERT INTO ITEM VALUES(6,11,44,1,14.40)

+INSERT INTO ITEM VALUES(7,0,43,16,14.10)

+INSERT INTO ITEM VALUES(7,1,23,12,11.40)

+INSERT INTO ITEM VALUES(7,2,27,17,34.50)

+INSERT INTO ITEM VALUES(7,3,30,2,34.80)

+INSERT INTO ITEM VALUES(7,4,2,13,37.20)

+INSERT INTO ITEM VALUES(7,5,24,10,10.80)

+INSERT INTO ITEM VALUES(7,6,14,4,18.60)

+INSERT INTO ITEM VALUES(7,7,2,22,37.20)

+INSERT INTO ITEM VALUES(7,8,42,19,29.70)

+INSERT INTO ITEM VALUES(7,9,9,21,25.80)

+INSERT INTO ITEM VALUES(7,10,7,1,12.60)

+INSERT INTO ITEM VALUES(7,11,19,13,16.50)

+INSERT INTO ITEM VALUES(7,12,40,16,4.20)

+INSERT INTO ITEM VALUES(7,13,32,23,28.50)

+INSERT INTO ITEM VALUES(7,14,47,14,26.70)

+INSERT INTO ITEM VALUES(7,15,24,17,10.80)

+INSERT INTO ITEM VALUES(7,16,7,12,12.60)

+INSERT INTO ITEM VALUES(7,17,40,1,4.20)

+INSERT INTO ITEM VALUES(7,18,23,5,11.40)

+INSERT INTO ITEM VALUES(8,0,34,15,38.40)

+INSERT INTO ITEM VALUES(8,1,44,16,14.40)

+INSERT INTO ITEM VALUES(8,2,11,8,13.20)

+INSERT INTO ITEM VALUES(8,3,41,16,30.90)

+INSERT INTO ITEM VALUES(8,4,15,8,14.10)

+INSERT INTO ITEM VALUES(8,5,24,18,10.80)

+INSERT INTO ITEM VALUES(8,6,15,19,14.10)

+INSERT INTO ITEM VALUES(8,7,6,5,14.70)

+INSERT INTO ITEM VALUES(8,8,38,7,32.40)

+INSERT INTO ITEM VALUES(8,9,21,23,17.10)

+INSERT INTO ITEM VALUES(9,0,45,8,27.00)

+INSERT INTO ITEM VALUES(9,1,18,21,25.80)

+INSERT INTO ITEM VALUES(9,2,29,12,16.80)

+INSERT INTO ITEM VALUES(9,3,4,14,19.20)

+INSERT INTO ITEM VALUES(9,4,36,16,4.80)

+INSERT INTO ITEM VALUES(9,5,6,2,14.70)

+INSERT INTO ITEM VALUES(9,6,18,10,25.80)

+INSERT INTO ITEM VALUES(9,7,2,22,37.20)

+INSERT INTO ITEM VALUES(9,8,24,11,10.80)

+INSERT INTO ITEM VALUES(9,9,13,6,27.00)

+INSERT INTO ITEM VALUES(9,10,38,11,32.40)

+INSERT INTO ITEM VALUES(9,11,12,16,25.20)

+INSERT INTO ITEM VALUES(9,12,25,23,24.30)

+INSERT INTO ITEM VALUES(9,13,42,13,29.70)

+INSERT INTO ITEM VALUES(9,14,15,8,14.10)

+INSERT INTO ITEM VALUES(9,15,48,23,31.50)

+INSERT INTO ITEM VALUES(9,16,24,10,10.80)

+INSERT INTO ITEM VALUES(9,17,13,17,27.00)

+INSERT INTO ITEM VALUES(9,18,3,12,38.10)

+INSERT INTO ITEM VALUES(9,19,48,23,31.50)

+INSERT INTO ITEM VALUES(10,0,20,1,30.00)

+INSERT INTO ITEM VALUES(10,1,33,17,27.30)

+INSERT INTO ITEM VALUES(10,2,7,9,12.60)

+INSERT INTO ITEM VALUES(10,3,46,1,9.30)

+INSERT INTO ITEM VALUES(10,4,10,24,30.60)

+INSERT INTO ITEM VALUES(10,5,5,24,35.40)

+INSERT INTO ITEM VALUES(10,6,18,14,25.80)

+INSERT INTO ITEM VALUES(10,7,4,13,19.20)

+INSERT INTO ITEM VALUES(10,8,22,11,9.90)

+INSERT INTO ITEM VALUES(10,9,5,10,35.40)

+INSERT INTO ITEM VALUES(11,0,45,10,27.00)

+INSERT INTO ITEM VALUES(11,1,21,21,17.10)

+INSERT INTO ITEM VALUES(11,2,0,3,8.10)

+INSERT INTO ITEM VALUES(11,3,32,21,28.50)

+INSERT INTO ITEM VALUES(11,4,47,16,26.70)

+INSERT INTO ITEM VALUES(11,5,19,2,16.50)

+INSERT INTO ITEM VALUES(11,6,0,12,8.10)

+INSERT INTO ITEM VALUES(11,7,48,22,31.50)

+INSERT INTO ITEM VALUES(11,8,20,1,30.00)

+INSERT INTO ITEM VALUES(12,0,1,24,37.20)

+INSERT INTO ITEM VALUES(12,1,41,19,30.90)

+INSERT INTO ITEM VALUES(12,2,6,5,14.70)

+INSERT INTO ITEM VALUES(12,3,0,18,8.10)

+INSERT INTO ITEM VALUES(12,4,20,11,30.00)

+INSERT INTO ITEM VALUES(12,5,37,17,14.10)

+INSERT INTO ITEM VALUES(12,6,31,15,7.20)

+INSERT INTO ITEM VALUES(12,7,48,7,31.50)

+INSERT INTO ITEM VALUES(12,8,48,2,31.50)

+INSERT INTO ITEM VALUES(12,9,25,22,24.30)

+INSERT INTO ITEM VALUES(12,10,46,19,9.30)

+INSERT INTO ITEM VALUES(12,11,28,16,4.50)

+INSERT INTO ITEM VALUES(12,12,13,12,27.00)

+INSERT INTO ITEM VALUES(12,13,36,21,4.80)

+INSERT INTO ITEM VALUES(12,14,25,11,24.30)

+INSERT INTO ITEM VALUES(12,15,22,16,9.90)

+INSERT INTO ITEM VALUES(12,16,0,9,8.10)

+INSERT INTO ITEM VALUES(12,17,31,15,7.20)

+INSERT INTO ITEM VALUES(12,18,9,4,25.80)

+INSERT INTO ITEM VALUES(13,0,16,10,29.10)

+INSERT INTO ITEM VALUES(13,1,1,1,37.20)

+INSERT INTO ITEM VALUES(13,2,13,20,27.00)

+INSERT INTO ITEM VALUES(13,3,32,2,28.50)

+INSERT INTO ITEM VALUES(13,4,26,21,37.80)

+INSERT INTO ITEM VALUES(13,5,22,19,9.90)

+INSERT INTO ITEM VALUES(13,6,19,8,16.50)

+INSERT INTO ITEM VALUES(13,7,29,24,16.80)

+INSERT INTO ITEM VALUES(13,8,48,11,31.50)

+INSERT INTO ITEM VALUES(13,9,24,10,10.80)

+INSERT INTO ITEM VALUES(13,10,45,24,27.00)

+INSERT INTO ITEM VALUES(13,11,14,3,18.60)

+INSERT INTO ITEM VALUES(13,12,17,3,33.00)

+INSERT INTO ITEM VALUES(13,13,10,20,30.60)

+INSERT INTO ITEM VALUES(13,14,1,12,37.20)

+INSERT INTO ITEM VALUES(13,15,0,20,8.10)

+INSERT INTO ITEM VALUES(13,16,22,23,9.90)

+INSERT INTO ITEM VALUES(13,17,32,18,28.50)

+INSERT INTO ITEM VALUES(13,18,0,16,8.10)

+INSERT INTO ITEM VALUES(13,19,42,18,29.70)

+INSERT INTO ITEM VALUES(13,20,5,19,35.40)

+INSERT INTO ITEM VALUES(13,21,40,1,4.20)

+INSERT INTO ITEM VALUES(14,0,42,18,29.70)

+INSERT INTO ITEM VALUES(14,1,9,22,25.80)

+INSERT INTO ITEM VALUES(14,2,15,18,14.10)

+INSERT INTO ITEM VALUES(14,3,34,11,38.40)

+INSERT INTO ITEM VALUES(14,4,41,17,30.90)

+INSERT INTO ITEM VALUES(14,5,11,8,13.20)

+INSERT INTO ITEM VALUES(14,6,26,18,37.80)

+INSERT INTO ITEM VALUES(14,7,43,4,14.10)

+INSERT INTO ITEM VALUES(14,8,23,7,11.40)

+INSERT INTO ITEM VALUES(14,9,13,16,27.00)

+INSERT INTO ITEM VALUES(14,10,44,16,14.40)

+INSERT INTO ITEM VALUES(14,11,25,15,24.30)

+INSERT INTO ITEM VALUES(14,12,4,20,19.20)

+INSERT INTO ITEM VALUES(14,13,11,23,13.20)

+INSERT INTO ITEM VALUES(15,0,17,12,33.00)

+INSERT INTO ITEM VALUES(15,1,13,21,27.00)

+INSERT INTO ITEM VALUES(15,2,24,6,10.80)

+INSERT INTO ITEM VALUES(16,0,18,15,25.80)

+INSERT INTO ITEM VALUES(16,1,36,20,4.80)

+INSERT INTO ITEM VALUES(16,2,20,15,30.00)

+INSERT INTO ITEM VALUES(16,3,0,3,8.10)

+INSERT INTO ITEM VALUES(16,4,10,24,30.60)

+INSERT INTO ITEM VALUES(16,5,11,15,13.20)

+INSERT INTO ITEM VALUES(16,6,44,7,14.40)

+INSERT INTO ITEM VALUES(16,7,8,17,33.90)

+INSERT INTO ITEM VALUES(16,8,13,17,27.00)

+INSERT INTO ITEM VALUES(16,9,11,10,13.20)

+INSERT INTO ITEM VALUES(16,10,43,8,14.10)

+INSERT INTO ITEM VALUES(16,11,24,7,10.80)

+INSERT INTO ITEM VALUES(16,12,18,2,25.80)

+INSERT INTO ITEM VALUES(16,13,20,1,30.00)

+INSERT INTO ITEM VALUES(16,14,0,19,8.10)

+INSERT INTO ITEM VALUES(16,15,12,3,25.20)

+INSERT INTO ITEM VALUES(17,0,16,8,29.10)

+INSERT INTO ITEM VALUES(17,1,19,19,16.50)

+INSERT INTO ITEM VALUES(17,2,44,11,14.40)

+INSERT INTO ITEM VALUES(17,3,24,4,10.80)

+INSERT INTO ITEM VALUES(17,4,23,2,11.40)

+INSERT INTO ITEM VALUES(17,5,44,1,14.40)

+INSERT INTO ITEM VALUES(17,6,43,6,14.10)

+INSERT INTO ITEM VALUES(17,7,6,15,14.70)

+INSERT INTO ITEM VALUES(17,8,49,8,3.30)

+INSERT INTO ITEM VALUES(17,9,8,15,33.90)

+INSERT INTO ITEM VALUES(17,10,10,12,30.60)

+INSERT INTO ITEM VALUES(17,11,45,10,27.00)

+INSERT INTO ITEM VALUES(17,12,22,16,9.90)

+INSERT INTO ITEM VALUES(17,13,41,5,30.90)

+INSERT INTO ITEM VALUES(17,14,18,2,25.80)

+INSERT INTO ITEM VALUES(17,15,35,10,11.40)

+INSERT INTO ITEM VALUES(17,16,8,16,33.90)

+INSERT INTO ITEM VALUES(17,17,7,5,12.60)

+INSERT INTO ITEM VALUES(17,18,5,9,35.40)

+INSERT INTO ITEM VALUES(17,19,46,12,9.30)

+INSERT INTO ITEM VALUES(18,0,32,1,28.50)

+INSERT INTO ITEM VALUES(18,1,33,12,27.30)

+INSERT INTO ITEM VALUES(18,2,40,12,4.20)

+INSERT INTO ITEM VALUES(18,3,19,8,16.50)

+INSERT INTO ITEM VALUES(18,4,28,6,4.50)

+INSERT INTO ITEM VALUES(18,5,15,6,14.10)

+INSERT INTO ITEM VALUES(18,6,29,4,16.80)

+INSERT INTO ITEM VALUES(18,7,15,14,14.10)

+INSERT INTO ITEM VALUES(18,8,1,24,37.20)

+INSERT INTO ITEM VALUES(18,9,2,2,37.20)

+INSERT INTO ITEM VALUES(18,10,34,18,38.40)

+INSERT INTO ITEM VALUES(18,11,30,8,34.80)

+INSERT INTO ITEM VALUES(18,12,37,12,14.10)

+INSERT INTO ITEM VALUES(18,13,14,12,18.60)

+INSERT INTO ITEM VALUES(18,14,28,20,4.50)

+INSERT INTO ITEM VALUES(18,15,44,20,14.40)

+INSERT INTO ITEM VALUES(18,16,31,12,7.20)

+INSERT INTO ITEM VALUES(18,17,8,1,33.90)

+INSERT INTO ITEM VALUES(18,18,10,1,30.60)

+INSERT INTO ITEM VALUES(19,0,12,7,25.20)

+INSERT INTO ITEM VALUES(19,1,31,2,7.20)

+INSERT INTO ITEM VALUES(19,2,4,22,19.20)

+INSERT INTO ITEM VALUES(19,3,49,23,3.30)

+INSERT INTO ITEM VALUES(19,4,36,24,4.80)

+INSERT INTO ITEM VALUES(20,0,47,15,26.70)

+INSERT INTO ITEM VALUES(20,1,29,6,16.80)

+INSERT INTO ITEM VALUES(20,2,24,22,10.80)

+INSERT INTO ITEM VALUES(20,3,25,14,24.30)

+INSERT INTO ITEM VALUES(20,4,30,13,34.80)

+INSERT INTO ITEM VALUES(20,5,8,14,33.90)

+INSERT INTO ITEM VALUES(20,6,20,2,30.00)

+INSERT INTO ITEM VALUES(20,7,9,9,25.80)

+INSERT INTO ITEM VALUES(20,8,44,18,14.40)

+INSERT INTO ITEM VALUES(20,9,12,8,25.20)

+INSERT INTO ITEM VALUES(20,10,25,11,24.30)

+INSERT INTO ITEM VALUES(20,11,15,8,14.10)

+INSERT INTO ITEM VALUES(21,0,9,10,25.80)

+INSERT INTO ITEM VALUES(21,1,38,19,32.40)

+INSERT INTO ITEM VALUES(21,2,31,17,7.20)

+INSERT INTO ITEM VALUES(21,3,30,13,34.80)

+INSERT INTO ITEM VALUES(21,4,49,22,3.30)

+INSERT INTO ITEM VALUES(21,5,27,18,34.50)

+INSERT INTO ITEM VALUES(21,6,26,7,37.80)

+INSERT INTO ITEM VALUES(21,7,8,9,33.90)

+INSERT INTO ITEM VALUES(21,8,44,19,14.40)

+INSERT INTO ITEM VALUES(21,9,35,17,11.40)

+INSERT INTO ITEM VALUES(21,10,19,14,16.50)

+INSERT INTO ITEM VALUES(21,11,20,11,30.00)

+INSERT INTO ITEM VALUES(22,0,9,6,25.80)

+INSERT INTO ITEM VALUES(22,1,30,11,34.80)

+INSERT INTO ITEM VALUES(22,2,12,20,25.20)

+INSERT INTO ITEM VALUES(22,3,22,5,9.90)

+INSERT INTO ITEM VALUES(22,4,5,21,35.40)

+INSERT INTO ITEM VALUES(22,5,24,5,10.80)

+INSERT INTO ITEM VALUES(22,6,4,11,19.20)

+INSERT INTO ITEM VALUES(22,7,21,6,17.10)

+INSERT INTO ITEM VALUES(22,8,3,2,38.10)

+INSERT INTO ITEM VALUES(22,9,23,1,11.40)

+INSERT INTO ITEM VALUES(23,0,48,22,31.50)

+INSERT INTO ITEM VALUES(23,1,26,8,37.80)

+INSERT INTO ITEM VALUES(23,2,33,18,27.30)

+INSERT INTO ITEM VALUES(23,3,40,19,4.20)

+INSERT INTO ITEM VALUES(23,4,23,19,11.40)

+INSERT INTO ITEM VALUES(23,5,32,14,28.50)

+INSERT INTO ITEM VALUES(23,6,16,1,29.10)

+INSERT INTO ITEM VALUES(23,7,39,3,23.10)

+INSERT INTO ITEM VALUES(23,8,6,17,14.70)

+INSERT INTO ITEM VALUES(23,9,20,18,30.00)

+INSERT INTO ITEM VALUES(23,10,4,18,19.20)

+INSERT INTO ITEM VALUES(23,11,41,8,30.90)

+INSERT INTO ITEM VALUES(23,12,4,17,19.20)

+INSERT INTO ITEM VALUES(23,13,14,17,18.60)

+INSERT INTO ITEM VALUES(23,14,44,2,14.40)

+INSERT INTO ITEM VALUES(23,15,13,17,27.00)

+INSERT INTO ITEM VALUES(23,16,8,11,33.90)

+INSERT INTO ITEM VALUES(24,0,43,14,14.10)

+INSERT INTO ITEM VALUES(24,1,46,18,9.30)

+INSERT INTO ITEM VALUES(24,2,38,10,32.40)

+INSERT INTO ITEM VALUES(24,3,17,23,33.00)

+INSERT INTO ITEM VALUES(24,4,15,17,14.10)

+INSERT INTO ITEM VALUES(24,5,35,16,11.40)

+INSERT INTO ITEM VALUES(24,6,40,3,4.20)

+INSERT INTO ITEM VALUES(24,7,7,13,12.60)

+INSERT INTO ITEM VALUES(24,8,5,18,35.40)

+INSERT INTO ITEM VALUES(24,9,21,8,17.10)

+INSERT INTO ITEM VALUES(24,10,27,4,34.50)

+INSERT INTO ITEM VALUES(24,11,1,4,37.20)

+INSERT INTO ITEM VALUES(24,12,0,8,8.10)

+INSERT INTO ITEM VALUES(24,13,15,21,14.10)

+INSERT INTO ITEM VALUES(24,14,1,13,37.20)

+INSERT INTO ITEM VALUES(24,15,39,17,23.10)

+INSERT INTO ITEM VALUES(25,0,5,15,35.40)

+INSERT INTO ITEM VALUES(25,1,43,13,14.10)

+INSERT INTO ITEM VALUES(25,2,13,8,27.00)

+INSERT INTO ITEM VALUES(25,3,19,4,16.50)

+INSERT INTO ITEM VALUES(25,4,47,10,26.70)

+INSERT INTO ITEM VALUES(25,5,10,5,30.60)

+INSERT INTO ITEM VALUES(25,6,21,18,17.10)

+INSERT INTO ITEM VALUES(25,7,16,8,29.10)

+INSERT INTO ITEM VALUES(25,8,38,3,32.40)

+INSERT INTO ITEM VALUES(26,0,42,16,29.70)

+INSERT INTO ITEM VALUES(26,1,43,21,14.10)

+INSERT INTO ITEM VALUES(26,2,33,7,27.30)

+INSERT INTO ITEM VALUES(26,3,16,3,29.10)

+INSERT INTO ITEM VALUES(26,4,46,7,9.30)

+INSERT INTO ITEM VALUES(26,5,38,4,32.40)

+INSERT INTO ITEM VALUES(26,6,7,23,12.60)

+INSERT INTO ITEM VALUES(26,7,4,16,19.20)

+INSERT INTO ITEM VALUES(26,8,40,13,4.20)

+INSERT INTO ITEM VALUES(26,9,1,23,37.20)

+INSERT INTO ITEM VALUES(26,10,34,16,38.40)

+INSERT INTO ITEM VALUES(26,11,18,3,25.80)

+INSERT INTO ITEM VALUES(26,12,27,20,34.50)

+INSERT INTO ITEM VALUES(26,13,13,10,27.00)

+INSERT INTO ITEM VALUES(26,14,26,6,37.80)

+INSERT INTO ITEM VALUES(26,15,8,6,33.90)

+INSERT INTO ITEM VALUES(26,16,30,4,34.80)

+INSERT INTO ITEM VALUES(27,0,24,15,10.80)

+INSERT INTO ITEM VALUES(27,1,45,15,27.00)

+INSERT INTO ITEM VALUES(27,2,19,1,16.50)

+INSERT INTO ITEM VALUES(28,0,35,13,11.40)

+INSERT INTO ITEM VALUES(28,1,15,13,14.10)

+INSERT INTO ITEM VALUES(28,2,44,22,14.40)

+INSERT INTO ITEM VALUES(28,3,6,3,14.70)

+INSERT INTO ITEM VALUES(28,4,45,17,27.00)

+INSERT INTO ITEM VALUES(28,5,49,4,3.30)

+INSERT INTO ITEM VALUES(28,6,33,16,27.30)

+INSERT INTO ITEM VALUES(28,7,28,8,4.50)

+INSERT INTO ITEM VALUES(28,8,28,6,4.50)

+INSERT INTO ITEM VALUES(29,0,33,17,27.30)

+INSERT INTO ITEM VALUES(29,1,38,12,32.40)

+INSERT INTO ITEM VALUES(29,2,17,23,33.00)

+INSERT INTO ITEM VALUES(29,3,7,21,12.60)

+INSERT INTO ITEM VALUES(29,4,4,7,19.20)

+INSERT INTO ITEM VALUES(29,5,31,13,7.20)

+INSERT INTO ITEM VALUES(29,6,4,16,19.20)

+INSERT INTO ITEM VALUES(29,7,5,1,35.40)

+INSERT INTO ITEM VALUES(29,8,35,6,11.40)

+INSERT INTO ITEM VALUES(30,0,14,7,18.60)

+INSERT INTO ITEM VALUES(30,1,16,19,29.10)

+INSERT INTO ITEM VALUES(30,2,10,18,30.60)

+INSERT INTO ITEM VALUES(30,3,33,2,27.30)

+INSERT INTO ITEM VALUES(30,4,34,2,38.40)

+INSERT INTO ITEM VALUES(30,5,43,23,14.10)

+INSERT INTO ITEM VALUES(30,6,14,23,18.60)

+INSERT INTO ITEM VALUES(31,0,33,10,27.30)

+INSERT INTO ITEM VALUES(31,1,4,23,19.20)

+INSERT INTO ITEM VALUES(31,2,4,3,19.20)

+INSERT INTO ITEM VALUES(31,3,12,10,25.20)

+INSERT INTO ITEM VALUES(31,4,8,14,33.90)

+INSERT INTO ITEM VALUES(31,5,1,4,37.20)

+INSERT INTO ITEM VALUES(31,6,26,16,37.80)

+INSERT INTO ITEM VALUES(31,7,38,3,32.40)

+INSERT INTO ITEM VALUES(31,8,7,5,12.60)

+INSERT INTO ITEM VALUES(31,9,14,15,18.60)

+INSERT INTO ITEM VALUES(31,10,0,3,8.10)

+INSERT INTO ITEM VALUES(32,0,35,11,11.40)

+INSERT INTO ITEM VALUES(32,1,30,13,34.80)

+INSERT INTO ITEM VALUES(32,2,1,14,37.20)

+INSERT INTO ITEM VALUES(33,0,36,5,4.80)

+INSERT INTO ITEM VALUES(33,1,10,21,30.60)

+INSERT INTO ITEM VALUES(33,2,36,16,4.80)

+INSERT INTO ITEM VALUES(33,3,48,1,31.50)

+INSERT INTO ITEM VALUES(33,4,24,1,10.80)

+INSERT INTO ITEM VALUES(33,5,8,11,33.90)

+INSERT INTO ITEM VALUES(33,6,17,16,33.00)

+INSERT INTO ITEM VALUES(33,7,43,10,14.10)

+INSERT INTO ITEM VALUES(33,8,3,15,38.10)

+INSERT INTO ITEM VALUES(33,9,29,5,16.80)

+INSERT INTO ITEM VALUES(33,10,24,9,10.80)

+INSERT INTO ITEM VALUES(33,11,5,7,35.40)

+INSERT INTO ITEM VALUES(33,12,16,23,29.10)

+INSERT INTO ITEM VALUES(33,13,25,16,24.30)

+INSERT INTO ITEM VALUES(33,14,44,13,14.40)

+INSERT INTO ITEM VALUES(33,15,38,7,32.40)

+INSERT INTO ITEM VALUES(34,0,10,22,30.60)

+INSERT INTO ITEM VALUES(34,1,4,3,19.20)

+INSERT INTO ITEM VALUES(34,2,28,22,4.50)

+INSERT INTO ITEM VALUES(34,3,44,15,14.40)

+INSERT INTO ITEM VALUES(34,4,27,1,34.50)

+INSERT INTO ITEM VALUES(34,5,45,13,27.00)

+INSERT INTO ITEM VALUES(34,6,32,7,28.50)

+INSERT INTO ITEM VALUES(34,7,21,22,17.10)

+INSERT INTO ITEM VALUES(34,8,3,1,38.10)

+INSERT INTO ITEM VALUES(34,9,8,17,33.90)

+INSERT INTO ITEM VALUES(34,10,41,16,30.90)

+INSERT INTO ITEM VALUES(34,11,4,17,19.20)

+INSERT INTO ITEM VALUES(34,12,43,21,14.10)

+INSERT INTO ITEM VALUES(34,13,30,14,34.80)

+INSERT INTO ITEM VALUES(34,14,46,7,9.30)

+INSERT INTO ITEM VALUES(35,0,20,17,30.00)

+INSERT INTO ITEM VALUES(35,1,3,9,38.10)

+INSERT INTO ITEM VALUES(35,2,14,4,18.60)

+INSERT INTO ITEM VALUES(35,3,27,10,34.50)

+INSERT INTO ITEM VALUES(35,4,14,17,18.60)

+INSERT INTO ITEM VALUES(35,5,33,5,27.30)

+INSERT INTO ITEM VALUES(35,6,5,4,35.40)

+INSERT INTO ITEM VALUES(35,7,22,15,9.90)

+INSERT INTO ITEM VALUES(35,8,0,1,8.10)

+INSERT INTO ITEM VALUES(35,9,19,1,16.50)

+INSERT INTO ITEM VALUES(35,10,17,11,33.00)

+INSERT INTO ITEM VALUES(35,11,44,9,14.40)

+INSERT INTO ITEM VALUES(35,12,7,23,12.60)

+INSERT INTO ITEM VALUES(35,13,19,17,16.50)

+INSERT INTO ITEM VALUES(36,0,18,13,25.80)

+INSERT INTO ITEM VALUES(36,1,15,23,14.10)

+INSERT INTO ITEM VALUES(36,2,1,6,37.20)

+INSERT INTO ITEM VALUES(36,3,10,8,30.60)

+INSERT INTO ITEM VALUES(36,4,40,5,4.20)

+INSERT INTO ITEM VALUES(36,5,25,8,24.30)

+INSERT INTO ITEM VALUES(36,6,39,20,23.10)

+INSERT INTO ITEM VALUES(36,7,39,19,23.10)

+INSERT INTO ITEM VALUES(36,8,4,21,19.20)

+INSERT INTO ITEM VALUES(36,9,31,18,7.20)

+INSERT INTO ITEM VALUES(36,10,47,11,26.70)

+INSERT INTO ITEM VALUES(36,11,44,9,14.40)

+INSERT INTO ITEM VALUES(37,0,41,24,30.90)

+INSERT INTO ITEM VALUES(37,1,15,20,14.10)

+INSERT INTO ITEM VALUES(37,2,36,8,4.80)

+INSERT INTO ITEM VALUES(37,3,26,7,37.80)

+INSERT INTO ITEM VALUES(37,4,13,20,27.00)

+INSERT INTO ITEM VALUES(37,5,1,14,37.20)

+INSERT INTO ITEM VALUES(37,6,34,12,38.40)

+INSERT INTO ITEM VALUES(37,7,24,19,10.80)

+INSERT INTO ITEM VALUES(37,8,46,9,9.30)

+INSERT INTO ITEM VALUES(37,9,47,16,26.70)

+INSERT INTO ITEM VALUES(37,10,1,18,37.20)

+INSERT INTO ITEM VALUES(37,11,30,5,34.80)

+INSERT INTO ITEM VALUES(37,12,24,23,10.80)

+INSERT INTO ITEM VALUES(37,13,32,3,28.50)

+INSERT INTO ITEM VALUES(37,14,12,3,25.20)

+INSERT INTO ITEM VALUES(37,15,32,12,28.50)

+INSERT INTO ITEM VALUES(37,16,27,8,34.50)

+INSERT INTO ITEM VALUES(37,17,38,18,32.40)

+INSERT INTO ITEM VALUES(37,18,26,22,37.80)

+INSERT INTO ITEM VALUES(37,19,19,20,16.50)

+INSERT INTO ITEM VALUES(37,20,14,1,18.60)

+INSERT INTO ITEM VALUES(37,21,6,9,14.70)

+INSERT INTO ITEM VALUES(38,0,48,14,31.50)

+INSERT INTO ITEM VALUES(38,1,45,13,27.00)

+INSERT INTO ITEM VALUES(38,2,4,8,19.20)

+INSERT INTO ITEM VALUES(38,3,27,19,34.50)

+INSERT INTO ITEM VALUES(38,4,45,14,27.00)

+INSERT INTO ITEM VALUES(38,5,48,17,31.50)

+INSERT INTO ITEM VALUES(38,6,5,19,35.40)

+INSERT INTO ITEM VALUES(38,7,15,1,14.10)

+INSERT INTO ITEM VALUES(38,8,40,10,4.20)

+INSERT INTO ITEM VALUES(38,9,27,20,34.50)

+INSERT INTO ITEM VALUES(38,10,4,18,19.20)

+INSERT INTO ITEM VALUES(38,11,19,18,16.50)

+INSERT INTO ITEM VALUES(38,12,1,18,37.20)

+INSERT INTO ITEM VALUES(38,13,8,7,33.90)

+INSERT INTO ITEM VALUES(38,14,20,7,30.00)

+INSERT INTO ITEM VALUES(38,15,47,10,26.70)

+INSERT INTO ITEM VALUES(38,16,40,18,4.20)

+INSERT INTO ITEM VALUES(38,17,32,4,28.50)

+INSERT INTO ITEM VALUES(38,18,28,20,4.50)

+INSERT INTO ITEM VALUES(38,19,4,7,19.20)

+INSERT INTO ITEM VALUES(39,0,10,12,30.60)

+INSERT INTO ITEM VALUES(39,1,24,6,10.80)

+INSERT INTO ITEM VALUES(39,2,39,16,23.10)

+INSERT INTO ITEM VALUES(39,3,20,17,30.00)

+INSERT INTO ITEM VALUES(40,0,46,24,9.30)

+INSERT INTO ITEM VALUES(40,1,45,24,27.00)

+INSERT INTO ITEM VALUES(40,2,4,5,19.20)

+INSERT INTO ITEM VALUES(40,3,26,10,37.80)

+INSERT INTO ITEM VALUES(40,4,18,13,25.80)

+INSERT INTO ITEM VALUES(40,5,32,18,28.50)

+INSERT INTO ITEM VALUES(40,6,28,12,4.50)

+INSERT INTO ITEM VALUES(40,7,31,1,7.20)

+INSERT INTO ITEM VALUES(40,8,11,4,13.20)

+INSERT INTO ITEM VALUES(40,9,40,17,4.20)

+INSERT INTO ITEM VALUES(40,10,6,11,14.70)

+INSERT INTO ITEM VALUES(40,11,27,2,34.50)

+INSERT INTO ITEM VALUES(40,12,35,13,11.40)

+INSERT INTO ITEM VALUES(40,13,6,8,14.70)

+INSERT INTO ITEM VALUES(40,14,4,24,19.20)

+INSERT INTO ITEM VALUES(40,15,22,12,9.90)

+INSERT INTO ITEM VALUES(40,16,27,16,34.50)

+INSERT INTO ITEM VALUES(40,17,4,20,19.20)

+INSERT INTO ITEM VALUES(40,18,33,11,27.30)

+INSERT INTO ITEM VALUES(40,19,7,23,12.60)

+INSERT INTO ITEM VALUES(40,20,4,16,19.20)

+INSERT INTO ITEM VALUES(41,0,5,24,35.40)

+INSERT INTO ITEM VALUES(41,1,47,19,26.70)

+INSERT INTO ITEM VALUES(41,2,36,2,4.80)

+INSERT INTO ITEM VALUES(41,3,29,20,16.80)

+INSERT INTO ITEM VALUES(41,4,16,22,29.10)

+INSERT INTO ITEM VALUES(41,5,9,21,25.80)

+INSERT INTO ITEM VALUES(41,6,17,11,33.00)

+INSERT INTO ITEM VALUES(41,7,22,18,9.90)

+INSERT INTO ITEM VALUES(41,8,9,22,25.80)

+INSERT INTO ITEM VALUES(41,9,26,21,37.80)

+INSERT INTO ITEM VALUES(41,10,24,20,10.80)

+INSERT INTO ITEM VALUES(41,11,48,15,31.50)

+INSERT INTO ITEM VALUES(42,0,48,9,31.50)

+INSERT INTO ITEM VALUES(42,1,18,21,25.80)

+INSERT INTO ITEM VALUES(42,2,40,19,4.20)

+INSERT INTO ITEM VALUES(42,3,40,14,4.20)

+INSERT INTO ITEM VALUES(42,4,48,15,31.50)

+INSERT INTO ITEM VALUES(43,0,15,22,14.10)

+INSERT INTO ITEM VALUES(43,1,18,19,25.80)

+INSERT INTO ITEM VALUES(43,2,2,15,37.20)

+INSERT INTO ITEM VALUES(43,3,6,18,14.70)

+INSERT INTO ITEM VALUES(43,4,32,22,28.50)

+INSERT INTO ITEM VALUES(43,5,33,6,27.30)

+INSERT INTO ITEM VALUES(43,6,24,1,10.80)

+INSERT INTO ITEM VALUES(43,7,11,15,13.20)

+INSERT INTO ITEM VALUES(43,8,44,8,14.40)

+INSERT INTO ITEM VALUES(43,9,7,23,12.60)

+INSERT INTO ITEM VALUES(43,10,35,1,11.40)

+INSERT INTO ITEM VALUES(43,11,49,23,3.30)

+INSERT INTO ITEM VALUES(43,12,40,24,4.20)

+INSERT INTO ITEM VALUES(43,13,44,22,14.40)

+INSERT INTO ITEM VALUES(43,14,3,18,38.10)

+INSERT INTO ITEM VALUES(43,15,48,7,31.50)

+INSERT INTO ITEM VALUES(43,16,38,12,32.40)

+INSERT INTO ITEM VALUES(44,0,33,20,27.30)

+INSERT INTO ITEM VALUES(44,1,34,17,38.40)

+INSERT INTO ITEM VALUES(44,2,17,14,33.00)

+INSERT INTO ITEM VALUES(44,3,3,14,38.10)

+INSERT INTO ITEM VALUES(44,4,12,3,25.20)

+INSERT INTO ITEM VALUES(44,5,41,22,30.90)

+INSERT INTO ITEM VALUES(44,6,14,15,18.60)

+INSERT INTO ITEM VALUES(44,7,49,17,3.30)

+INSERT INTO ITEM VALUES(44,8,28,23,4.50)

+INSERT INTO ITEM VALUES(45,0,44,6,14.40)

+INSERT INTO ITEM VALUES(45,1,11,6,13.20)

+INSERT INTO ITEM VALUES(45,2,46,8,9.30)

+INSERT INTO ITEM VALUES(45,3,14,11,18.60)

+INSERT INTO ITEM VALUES(45,4,3,14,38.10)

+INSERT INTO ITEM VALUES(45,5,45,17,27.00)

+INSERT INTO ITEM VALUES(45,6,39,5,23.10)

+INSERT INTO ITEM VALUES(45,7,6,24,14.70)

+INSERT INTO ITEM VALUES(45,8,9,2,25.80)

+INSERT INTO ITEM VALUES(45,9,26,18,37.80)

+INSERT INTO ITEM VALUES(45,10,41,24,30.90)

+INSERT INTO ITEM VALUES(45,11,31,22,7.20)

+INSERT INTO ITEM VALUES(45,12,32,13,28.50)

+INSERT INTO ITEM VALUES(45,13,47,8,26.70)

+INSERT INTO ITEM VALUES(45,14,3,16,38.10)

+INSERT INTO ITEM VALUES(46,0,5,21,35.40)

+INSERT INTO ITEM VALUES(46,1,12,24,25.20)

+INSERT INTO ITEM VALUES(46,2,30,14,34.80)

+INSERT INTO ITEM VALUES(46,3,21,19,17.10)

+INSERT INTO ITEM VALUES(46,4,17,5,33.00)

+INSERT INTO ITEM VALUES(46,5,25,9,24.30)

+INSERT INTO ITEM VALUES(46,6,41,18,30.90)

+INSERT INTO ITEM VALUES(46,7,49,9,3.30)

+INSERT INTO ITEM VALUES(46,8,8,22,33.90)

+INSERT INTO ITEM VALUES(46,9,7,4,12.60)

+INSERT INTO ITEM VALUES(46,10,11,24,13.20)

+INSERT INTO ITEM VALUES(46,11,1,4,37.20)

+INSERT INTO ITEM VALUES(46,12,21,24,17.10)

+INSERT INTO ITEM VALUES(46,13,36,20,4.80)

+INSERT INTO ITEM VALUES(46,14,24,10,10.80)

+INSERT INTO ITEM VALUES(46,15,40,11,4.20)

+INSERT INTO ITEM VALUES(46,16,46,21,9.30)

+INSERT INTO ITEM VALUES(46,17,12,23,25.20)

+INSERT INTO ITEM VALUES(47,0,23,15,11.40)

+INSERT INTO ITEM VALUES(47,1,23,13,11.40)

+INSERT INTO ITEM VALUES(47,2,17,6,33.00)

+INSERT INTO ITEM VALUES(47,3,1,4,37.20)

+INSERT INTO ITEM VALUES(47,4,15,1,14.10)

+INSERT INTO ITEM VALUES(47,5,40,8,4.20)

+INSERT INTO ITEM VALUES(47,6,8,10,33.90)

+INSERT INTO ITEM VALUES(47,7,28,14,4.50)

+INSERT INTO ITEM VALUES(47,8,16,2,29.10)

+INSERT INTO ITEM VALUES(47,9,32,9,28.50)

+INSERT INTO ITEM VALUES(47,10,45,2,27.00)

+INSERT INTO ITEM VALUES(47,11,35,10,11.40)

+INSERT INTO ITEM VALUES(47,12,12,20,25.20)

+INSERT INTO ITEM VALUES(47,13,33,8,27.30)

+INSERT INTO ITEM VALUES(48,0,6,23,14.70)

+INSERT INTO ITEM VALUES(48,1,26,23,37.80)

+INSERT INTO ITEM VALUES(48,2,23,10,11.40)

+INSERT INTO ITEM VALUES(48,3,10,2,30.60)

+INSERT INTO ITEM VALUES(48,4,48,4,31.50)

+INSERT INTO ITEM VALUES(48,5,24,16,10.80)

+INSERT INTO ITEM VALUES(48,6,11,17,13.20)

+INSERT INTO ITEM VALUES(48,7,30,19,34.80)

+INSERT INTO ITEM VALUES(48,8,5,12,35.40)

+INSERT INTO ITEM VALUES(48,9,35,17,11.40)

+INSERT INTO ITEM VALUES(48,10,41,10,30.90)

+INSERT INTO ITEM VALUES(49,0,18,6,25.80)

+INSERT INTO ITEM VALUES(49,1,22,16,9.90)

+INSERT INTO ITEM VALUES(49,2,29,6,16.80)

+INSERT INTO ITEM VALUES(49,3,17,19,33.00)

+INSERT INTO ITEM VALUES(49,4,47,14,26.70)

+INSERT INTO ITEM VALUES(49,5,16,1,29.10)

+INSERT INTO ITEM VALUES(49,6,29,15,16.80)

+INSERT INTO ITEM VALUES(49,7,6,21,14.70)

+INSERT INTO ITEM VALUES(49,8,48,24,31.50)

+INSERT INTO ITEM VALUES(49,9,7,24,12.60)

+INSERT INTO ITEM VALUES(49,10,30,16,34.80)

+INSERT INTO ITEM VALUES(49,11,40,15,4.20)

+INSERT INTO ITEM VALUES(49,12,21,17,17.10)

+INSERT INTO ITEM VALUES(49,13,6,22,14.70)

+INSERT INTO ITEM VALUES(49,14,23,5,11.40)

+INSERT INTO ITEM VALUES(49,15,19,24,16.50)

+INSERT INTO ITEM VALUES(49,16,24,18,10.80)

+CREATE VIEW DOC_ADDR AS SELECT D.ID,D.TOTAL,A.CITY FROM INVOICE D, CUSTOMER A

+    WHERE D.ADDRESSID=A.ID AND A.ID < 10

+/*c88*/SELECT * FROM DOC_ADDR D, ITEM P WHERE P.DOCUMENTID = D.ID

+

+

+

diff --git a/testrun/hsqldb/TestSelf3PartNames.txt b/testrun/hsqldb/TestSelf3PartNames.txt
new file mode 100644
index 0000000..c5936d8
--- /dev/null
+++ b/testrun/hsqldb/TestSelf3PartNames.txt
@@ -0,0 +1,68 @@
+-- $Id: TestSelf3PartNames.txt 610 2008-12-22 15:54:18Z unsaved $

+-- Test 3-part names like:  schemaname.tablename.columname

+--SET PROPERTY "hsqldb.default_table_type" 'cached'

+-- Setup

+CREATE USER blaine PASSWORD "blaine";

+GRANT dba TO blaine;

+CREATE SCHEMA b1 AUTHORIZATION blaine;

+SET SCHEMA b1;

+CREATE TABLE t(i int);

+

+/*u1*/INSERT INTO t VALUES(1);

+/*c1*/SELECT t.i FROM t;

+/*c1*/SELECT b1.t.i FROM t;

+/*c1*/SELECT b1.t.i FROM b1.t;

+/*e*/SELECT t.NOSUCH.i FROM t;

+/*c1*/SELECT i FROM t WHERE t.i > 0;

+/*c1*/SELECT i FROM t WHERE b1.t.i > 0;

+/*e*/SELECT i FROM NOSUCH.t WHERE b1.t.i > 0;

+/*e*/SELECT i FROM t WHERE NOSUCH.t.i > 0;

+/*e*/SELECT i FROM t WHERE t.NOSUCH.i > 0;

+SET SCHEMA public;

+/*c1*/SELECT b1.t.i FROM b1.t;

+/*e*/SELECT t.NOSUCH.i FROM b1.t;

+/*c1*/SELECT i FROM b1.t WHERE b1.t.i > 0;

+/*e*/SELECT i FROM t WHERE b1.NOSUCH.i > 0;

+-- Cleanup

+DROP SCHEMA b1 CASCADE;

+DROP USER blaine;

+

+

+-- Now build up to Joins with 3-part names

+-- Setup

+create schema s1 authorization dba;

+create schema s2 authorization dba;

+create table s1.t(i int, j1 int);

+insert into s1.t values(11, 4);

+create table s2.t(i int, j2 int);

+insert into s2.t values(22, 4);

+

+-- sanity checks

+/*r11,4*/SELECT * FROM s1.t;

+/*r22,4*/SELECT * FROM s2.t;

+-- cross-schema 2-part name Join

+/*r4*/SELECT j1 FROM s1.t, s2.t WHERE j1 = j2;

+-- cross-schema 3-part name Join

+/*r22,4,11*/SELECT s2.t.i, j1, s1.t.i FROM s1.t, s2.t WHERE j1 = j2;

+/*r22,4,11*/SELECT s2.t.i, j1, s1.t.i FROM s1.t, s2.t WHERE s1.t.j1 = s2.t.j2;

+/*e*/SELECT s2.t.i, j1, s1.t.i FROM s1.t, s2.t WHERE s2.t.j1 = s2.t.j2;

+/*e*/SELECT s2.t.i, j1, s1.t.i FROM s1.t, s2.t WHERE s1.t.j1 = s1.t.j2;

+-- schema qualifier in view defintion

+CREATE VIEW s2.v2 AS SELECT * FROM s2.t;

+-- 3-part Names w/ views

+/*r22,4,11*/SELECT s2.v2.i, j1, s1.t.i FROM s1.t, s2.v2 WHERE j1 = j2;

+/*r22,4,11*/SELECT s2.v2.i, j1, s1.t.i FROM s1.t, s2.v2 WHERE s1.t.j1 = s2.v2.j2;

+-- 3-part name w/ *

+/*r22,4*/SELECT s2.t.* FROM s2.t;

+SET SCHEMA s2;

+/*r22,4*/SELECT s2.t.* FROM t;

+

+-- Illegal use of 3-part names

+/*e*/SELECT  * from bad.s1.t;

+/*e*/SELECT  * from s1.t.bad;

+/*e*/SELECT  * from s1.bad.t;

+

+SET SCHEMA public;

+-- Cleanup

+DROP SCHEMA s1 CASCADE;

+DROP SCHEMA s2 CASCADE;

diff --git a/testrun/hsqldb/TestSelfAlterColumn.txt b/testrun/hsqldb/TestSelfAlterColumn.txt
new file mode 100644
index 0000000..dd5f58c
--- /dev/null
+++ b/testrun/hsqldb/TestSelfAlterColumn.txt
@@ -0,0 +1,151 @@
+drop table "testac" if exists;

+drop table "testacc" if exists;

+-- tests for various column definition statements

+create table "testac" ("a" integer, "b" integer);

+insert into "testac" values(6,6);

+insert into "testac" values(5,5);

+/*r2*/select count(*) from "testac";

+-- add column without COLUMN keyword

+alter table "testac" add "c" varchar(10)

+/*e*/alter table "testac" add "c" varchar(10)

+alter table "testac" alter column "c" varchar(2)

+/*e*/insert into "testac" values(5,5,'long string');

+insert into "testac" values(4,4,'ls');

+/*r

+ 6,6,NULL

+ 5,5,NULL

+ 4,4,ls

+*/select * from "testac" order by "a" desc

+-- drop column without COLUMN keyword

+alter table "testac" drop "c"

+/*r

+ 6,6

+ 5,5

+ 4,4

+*/select * from "testac" order by "a" desc

+-- add column with COLUMN keyword

+alter table "testac" add column "c" varchar(10) default 'XX' not null before "b"

+/*e*/alter table "testac" add column "c" varchar(10) before "b"

+/*r

+ 6,XX,6

+ 5,XX,5

+ 4,XX,4

+*/select * from "testac" order by "a" desc;

+-- drop column with COLUMN keyword

+alter table "testac" drop column "c";

+/*r

+ 6,6

+ 5,5

+ 4,4

+*/select * from "testac" order by "a" desc;

+--  add column without COLUMN keyword - unquoted

+alter table "testac" add c varchar(10);

+/*r

+ 6,6,NULL

+ 5,5,NULL

+ 4,4,NULL

+*/select * from "testac" order by "a" desc;

+--  drop column without COLUMN keyword - unquoted

+alter table "testac" drop c;

+/*r

+ 6,6

+ 5,5

+ 4,4

+*/select * from "testac" order by "a" desc;

+--

+-- PK definition not allowed in alter column

+/*e*/alter table "testac" alter column "a" integer primary key;

+/*e*/alter table "testac" alter column "a" integer identity;

+alter table "testac" add primary key("a");

+/*e*/insert into "testac" values (null,7);

+-- IDENTITY can be added to an existing PK column

+alter table "testac" alter column "a" integer identity

+insert into "testac" values (null,7);

+insert into "testac" ("b") values (8);

+/*r

+ 4,4

+ 5,5

+ 6,6

+ 7,7

+ 8,8

+*/select * from "testac";

+create table "testacc" as (select * from "testac") with data;

+-- IDENTITY can be dropped from PK column

+alter table "testac" alter column "a" integer;

+/*e*/insert into "testac" values (null,9);

+insert into "testac" values (9,9);

+/*r

+ 4,4

+ 5,5

+ 6,6

+ 7,7

+ 8,8

+ 9,9

+*/select * from "testac";

+alter table "testac" drop primary key;

+insert into "testac" values (null,12);

+/*c7*/select * from "testac";

+/*e*/alter table "testac" alter column "a" not null;

+

+delete from "testac" where "a" is null

+/*c6*/select * from "testac";

+alter table "testac" alter column "a" set not null;

+/*e*/insert into "testac" values (null,12);

+alter table "testac" add primary key("a");

+/*c6*/select * from "testac";

+/*e*/insert into "testac" values (null,12);

+alter table "testac" drop primary key;

+/*e*/insert into "testac" values (null,12);

+/*c6*/select * from "testac";

+alter table "testac" alter column "a" set null;

+insert into "testac" values (null,12);

+delete from "testac" where "a" is null

+/*c6*/select * from "testac";

+

+-- column with a PK constraint can be added

+alter table "testac" add column "c" integer generated by default as identity primary key

+-- no second IDENTITY or PK

+/*e*/alter table "testac" add column "d" integer generated by default as identity primary key

+/*e*/alter table "testac" add column "d" integer generated by default as identity

+/*e*/alter table "testac" add column "d" integer primary key;

+-- column with a PK constraint can be dropped

+alter table "testac" drop "c";

+alter table "testac" add unique("a");

+/*e*/insert into "testac" values(9,9);

+alter table "testac" drop "a";

+/*r

+ 4

+ 5

+ 6

+ 7

+ 8

+ 9

+*/select * from "testac";

+-- tests for changing column size

+alter table "testacc" add column "c" varchar(4) default 'aa' not null;

+update "testacc" set "c" = "c" || cast("a" as varchar(5));

+/*r

+ 4,4,aa4

+ 5,5,aa5

+ 6,6,aa6

+ 7,7,aa7

+ 8,8,aa8

+*/select * from "testacc";

+alter table "testacc" add primary key ("c")

+/*r

+ 4,4,aa4

+ 5,5,aa5

+ 6,6,aa6

+ 7,7,aa7

+ 8,8,aa8

+*/select * from "testacc";

+/*e*/insert into "testacc" values (9,9,'aa9000000');

+alter table "testacc" alter column "c" varchar(10);

+insert into "testacc" values (9,9,'aa9000000');

+alter table "testacc" alter column "c" set not null

+/*e*/insert into "testacc" values (10,10,null);

+/*e*/alter table "testacc" alter column "c" set null;

+alter table "testacc" drop primary key;

+alter table "testacc" alter column "c" set null;

+insert into "testacc" values (10,10,null);

+

diff --git a/testrun/hsqldb/TestSelfArithmetic.txt b/testrun/hsqldb/TestSelfArithmetic.txt
new file mode 100644
index 0000000..184069d
--- /dev/null
+++ b/testrun/hsqldb/TestSelfArithmetic.txt
@@ -0,0 +1,28 @@
+drop table arith if exists;

+create table arith ( inta int, intb int, intc int );

+insert into arith ( inta, intb, intc ) values ( 1, 2, 3 );

+insert into arith ( inta, intb, intc ) values ( 3, 5, 7 );

+insert into arith ( inta, intb, intc ) values ( 7, 11, 13 );

+insert into arith ( inta, intb, intc ) values ( 13, 17, 19 );

+

+select inta, intb from arith order by inta;

+select inta, inta + intb from arith order by inta;

+select inta, inta * intb from arith order by inta;

+select inta, inta - intb from arith order by inta;

+select inta, ( inta - intb ) * intc from arith order by inta;

+select inta, ( inta + intb ) * intc from arith order by inta;

+select inta, ( inta - intb ) + intc from arith order by inta;

+select inta, ( inta + intb ) + intc from arith order by inta;

+select inta, (inta-intb)*intc from arith order by inta;

+select inta, (inta+intb)*intc from arith order by inta;

+select inta, (inta-intb)+intc from arith order by inta;

+select inta, (inta+intb)+intc from arith order by inta;

+select inta, intc * ( inta - intb ) from arith order by inta;

+select inta, intc * ( inta + intb ) from arith order by inta;

+select inta, intc - ( inta + intb ) from arith order by inta;

+

+drop table arith;

+

+create table arith ( inta int, intb int, intc int );

+insert into arith ( inta, intb, intc ) values ( 1, 2, 3 );

+select inta, ( inta - intb ) * intc from arith order by inta;

diff --git a/testrun/hsqldb/TestSelfArrays.txt b/testrun/hsqldb/TestSelfArrays.txt
new file mode 100644
index 0000000..ca4680a
--- /dev/null
+++ b/testrun/hsqldb/TestSelfArrays.txt
@@ -0,0 +1,36 @@
+create cached table tarray (id int primary key, description varchar(20) array);

+insert into tarray values 1, array['light', 'red', 'hot']

+insert into tarray values 2, array['dark', 'grey', 'cold']

+select * from tarray

+select t1.description || t2.description from tarray t1 join tarray t2 on t1.id = t2.id + 1

+select t1.description || t2.description[2] from tarray t1 join tarray t2 on t1.id = t2.id + 1

+select (t1.description || t2.description)[2] from tarray t1 join tarray t2 on t1.id = t2.id + 1

+select max(t1.description[1]) from tarray t1

+select max(t1.description[1]) || min(t1.description[1]) from tarray t1

+select cardinality(t1.description || t2.description) from tarray t1 join tarray t2 on t1.id = t2.id + 1

+update tarray t1 set t1.description[2] = 'cool' where id = 2

+select trim_array(t1.description, 1) from tarray t1

+select trim_array(t1.description, 1)[1] from tarray t1

+select trim_array(t1.description, 1)[1] from tarray t1

+

+select * from tarray t1 where t1.id = 2 and t1.description[2] = 'cold'

+

+CREATE TABLE iarray (i BIGINT PRIMARY KEY, ar INTEGER ARRAY);

+

+INSERT INTO iarray VALUES (1, array [11, null, 13]);

+INSERT INTO iarray VALUES (2, null);

+INSERT INTO iarray VALUES (3, array [21, 22]);

+

+/*c3*/SELECT * FROM iarray;

+

+/*c1*/SELECT count(*) FROM iarray WHERE i = 1 AND ar[3] = 13;

+

+-- using customer and invoice tables defined in TestSelf.txt

+select firstname, lastname, a.c from customer, unnest(array[(select sum(total) from invoice where addressid = customer.id)]) a (c)

+alter table customer add column arr varchar(40) array

+update customer set arr = array[firstname, lastname, street, city]

+SELECT id, w, y FROM customer, unnest (arr) with ordinality j(w,y)

+

+--

+select * from customer, lateral(select sum(invoice.total) from invoice where invoice.addressid = customer.id)

+explain plan for select * from customer where firstname in(unnest(?))

diff --git a/testrun/hsqldb/TestSelfCasewhen.txt b/testrun/hsqldb/TestSelfCasewhen.txt
new file mode 100644
index 0000000..4785966
--- /dev/null
+++ b/testrun/hsqldb/TestSelfCasewhen.txt
@@ -0,0 +1,86 @@
+-- TESTS FOR CASE AND SIMILAR OPERATIONS

+--

+drop table testcase if exists;

+create table testcase(id integer, data varchar(10), filler varchar(10));

+insert into testcase values(100,'xxxx',null);

+insert into testcase values(200,'yyyy',null);

+insert into testcase values(300,null,null);

+/*c2*/select id from testcase where data is not null;

+/*r300*/select id from testcase where data is null;

+/*rNULLVALUE*/select ifnull(data,'NULLVALUE') from testcase where data is null;

+/*rNULLVALUE*/select case data when 'xxxx' then 'X' else 'NULLVALUE' end from testcase where data is null;

+SELECT CASE data WHEN 'xxxx' THEN 'X' ELSE (CASE data WHEN 'yyyy' THEN 'Y' ELSE (CASE data WHEN 'zzzz' THEN 'Z' ELSE 'NOTFOUND' END) END) END FROM testcase

+SELECT CASE data WHEN 'xxxx' THEN 'X' WHEN 'yyyy' THEN 'Y' WHEN 'zzzz' THEN 'Z' ELSE 'NOTFOUND' END FROM testcase;

+/*rALLNULL*/SELECT COALESCE (filler, data, 'ALLNULL') FROM testcase WHERE id = 300;

+/*r600.0E0*/select cast (sum(id) as double) from testcase;

+/*r600*/select coalesce(sum(id), 0) from testcase;

+/*r600*/select abs(coalesce(sum(id), 0)) from testcase;

+/*r1*/select case when 1 <0 then sum(10) else 1 end as label from testcase;

+/*r30*/select case when 1 < 0 then 1 else sum(10) end as label from testcase;

+drop table testcase2 if exists;

+create table testcase2(id integer, data varchar(10), filler varchar(10), datecol date);

+/*rNULL*/select cast (sum(id) as double) from testcase2;

+/*r0*/select coalesce(sum(id), 0) from testcase2;

+/*r0*/select abs(coalesce(sum(id), 0)) from testcase2;

+-- should result in DATE type

+/*r2005-10-25*/select coalesce(max(datecol), DATE'2005-10-25') from testcase2;

+-- error as date type is not comparable to character

+/*e*/select coalesce(max(datecol), '2005-10-25') from testcase2;

+drop table test if exists;

+create table test (sel int, name1 varchar(3), name2 varchar(3));

+insert into test (sel, name1, name2) values (0, 'foo', 'bar')

+insert into test (sel, name1, name2) values (1, 'baz', 'foo')

+insert into test (sel, name1, name2) values (1, 'foo', 'qux')

+select coalesce(a.name1, a.name2) as name,count(a.sel) as counter from test a

+ group by coalesce(a.name1, a.name2)

+select case when a.sel=1 then a.name2 else a.name1 end as name,

+ count(a.name1) as counter from test a group by case when a.sel=1

+ then a.name2 else a.name1 end

+ -- nested expressions

+create table single (c char(1));

+insert into single values('X');

+/*r1*/select case c when 'X' then 1 else 2 end from single;

+insert into single values(null);

+/*r

+ X

+ Y

+*/select ifnull(c,'Y') from single

+/*r

+ X

+ Y

+*/select coalesce(c,'Y') from single

+/*e*/select coalesce() from single

+/*e*/select coalesce(c) from single

+/*e*/select ifnull() from single

+/*e*/select ifnull(c) from single

+insert into single values('Y')

+insert into single values('Z')

+drop table single;

+create table single (c int);

+/*rAVG*/select case avg(c) when max(c) then 'MAX' when min(c) then 'MIN' else 'AVG' end from single;

+insert into single values(1);

+/*r1*/select case avg(c) when max(c) then max(c) when min(c) then min(c) else avg(c) end from single;

+insert into single values(2);

+insert into single values(3);

+/*r2*/select case avg(c) when max(c) then max(c) when min(c) then min(c) else avg(c) end from single;

+/*r

+ 1

+ 2

+ 3

+*/select * from single order by 1

+-- multi-element case when

+/*r

+ one-or-two

+ one-or-two

+ three-----

+*/select case c when in(0,1,2) then 'one-or-two' when in(0,3,30) then 'three-----' end from single order by 1

+/*r

+ NULL

+ NULL

+ :OK   :

+*/select ':' || case c when in(0,10,10) then 'WRONG' when in(0,3,34)

+ then 'OK' end || ':' from single order by 1

+

+CREATE TABLE BAB (SALES DOUBLE, COST DOUBLE);

+SELECT (SUM(BAB.SALES)-SUM(BAB.COST))/(CASE WHEN (ABS (SUM(BAB.SALES))) = 0

+ THEN NULL ELSE (ABS (SUM(BAB.SALES))) END) AS PROFITMARGIN FROM BAB

diff --git a/testrun/hsqldb/TestSelfCheckConstraints.txt b/testrun/hsqldb/TestSelfCheckConstraints.txt
new file mode 100644
index 0000000..20dcdf7
--- /dev/null
+++ b/testrun/hsqldb/TestSelfCheckConstraints.txt
@@ -0,0 +1,68 @@
+DROP TABLE "Tab" IF EXISTS;

+DROP TABLE TC0 IF EXISTS;

+DROP TABLE TC1 IF EXISTS;

+DROP TABLE TC2 IF EXISTS;

+DROP TABLE TC3 IF EXISTS;

+DROP TABLE TC4 IF EXISTS;

+DROP TABLE TC5 IF EXISTS;

+CREATE TABLE "TAB"("a" INT, "b" INT, "c" INT, CONSTRAINT CC CHECK("a" > "b" AND "b">"c"));

+/*e*/INSERT INTO TAB VALUES(null,2,3);

+INSERT INTO TAB VALUES(2,1,null);

+INSERT INTO TAB VALUES(NULL,2,NULL);

+INSERT INTO TAB VALUES(NULL,NULL,NULL);

+/*e*/ALTER TABLE TAB DROP COLUMN "b";

+ALTER TABLE TAB DROP CONSTRAINT CC;

+ALTER TABLE TAB ADD CONSTRAINT CC CHECK ("b" > 0);

+ALTER TABLE TAB DROP COLUMN "b"

+--

+

+CREATE TABLE TC0(A INT, B INT, C INT, CHECK(A > B AND B>C));

+CREATE TABLE TC1(A CHAR(10), B CHAR(10), C CHAR(10), CHECK(TRIM(BOTH '*' FROM A) > TRIM(LEADING FROM B)));

+CREATE TABLE TC2(A CHAR(10), B CHAR(10), C CHAR(10), CHECK(TRIM(TRAILING '*' FROM A) > UPPER(B)));

+CREATE TABLE TC3(A CHAR(10), B CHAR(10), C CHAR(10), CHECK(A LIKE B ESCAPE ';' AND B LIKE 'test%'));

+CREATE TABLE TC4(A CHAR(10), B CHAR(10), C CHAR(10), D INT, CHECK(SUBSTRING(A FROM D FOR 3) LIKE C ESCAPE ';'));

+CREATE TABLE TC5(A CHAR(10), B CHAR(10), C CHAR(10), D INT, CHECK(A IN (B,C, 'Sunday', 'Monday')));

+INSERT INTO TC5(A,C) VALUES ('Sunday', null);

+INSERT INTO TC5(A,C) VALUES ('Today', 'Today');

+INSERT INTO TC5(A,C) VALUES ('Tomorrow', 'Tomorrow');

+/*e*/INSERT INTO TC5(A,C) VALUES ('Yesterday', 'Tomorrow');

+INSERT INTO TC5(A,C) VALUES (null, null);

+/*c4*/SELECT * FROM TC5;

+ALTER TABLE TC5 DROP COLUMN D

+/*c4*/SELECT * FROM TC5;

+INSERT INTO TC5(A) VALUES ('Monday');

+UPDATE TC5 SET A='Monday' WHERE B IS NULL;

+/*e*/INSERT INTO TC5(A,C) VALUES ('Yesterday', 'Tomorrow');

+/*e*/CREATE TABLE TC6(A CHAR, B CHAR, C CHAR, D INT, CHECK(A IN (SELECT A FROM TC5)));

+CREATE TABLE TC6(A INT, CHECK(A IS NULL OR A > 1));

+INSERT INTO TC6(A) VALUES (2);

+INSERT INTO TC6(A) VALUES (null);

+/*e*/INSERT INTO TC6(A) VALUES (0);

+CREATE TABLE TC7(A INT, B TIMESTAMP, CONSTRAINT CH1 CHECK(B < CURRENT_TIMESTAMP));

+INSERT INTO TC7 VALUES (10, '2009-01-01 12:00:00');

+/*e*/INSERT INTO TC7 VALUES (10, '2044-01-01 12:00:00');

+INSERT INTO TC7 VALUES (11, NULL);

+SCRIPT

+-- some type conversion tests

+ALTER TABLE TC7 ALTER COLUMN A DECIMAL(6,2);

+/*e*/ALTER TABLE TC7 ALTER COLUMN B DATE;

+/*r

+ 10.00,2009-01-01 12:00:00.000000

+ 11.00,NULL

+*/SELECT * FROM TC7 ORDER BY A;

+ALTER TABLE TC7 DROP CONSTRAINT CH1;

+ALTER TABLE TC7 ALTER COLUMN B DATE;

+/*r

+ 10.00,2009-01-01

+ 11.00,NULL

+*/SELECT * FROM TC7 ORDER BY A;

+CREATE TABLE TST(A VARCHAR(10),B VARCHAR(10),C VARCHAR(10))

+INSERT INTO TST VALUES ('A','B','C');

+INSERT INTO TST VALUES (NULL,NULL,NULL);

+ALTER TABLE TST ADD CONSTRAINT K1 CHECK (CASE WHEN (A IS NULL) THEN

+ ((B IS NULL) AND (C IS NULL)) ELSE TRUE END )

+/*e*/INSERT INTO TST VALUES (NULL,'B','C');

+INSERT INTO TST VALUES (NULL,NULL,NULL);

+

+

+

diff --git a/testrun/hsqldb/TestSelfColGrant.txt b/testrun/hsqldb/TestSelfColGrant.txt
new file mode 100644
index 0000000..5ccd62f
--- /dev/null
+++ b/testrun/hsqldb/TestSelfColGrant.txt
@@ -0,0 +1,65 @@
+-- $Id: TestSelfColGrant.txt 3459 2010-02-12 19:46:33Z fredt $

+-- Tests column-specific grants

+

+-- These two users are for sanity tests

+/*u0*/CREATE USER privd PASSWORD "privd";

+/*u0*/CREATE USER unprivd PASSWORD "unprivd";

+

+/*u0*/CREATE USER u1 PASSWORD "u1";

+/*u0*/GRANT CHANGE_AUTHORIZATION TO u1;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO privd;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO unprivd;

+/*u0*/CREATE TABLE multicol (openc int, closedc int, limitedc int);

+/*u1*/INSERT INTO multicol values (1, 2, 3);

+/*c1*/SELECT * from multicol;

+/*u0*/GRANT ALL ON multicol TO privd;

+/*u0*/GRANT SELECT(limitedc) ON multicol TO u1;

+/*u0*/GRANT SELECT(openc) ON multicol TO public;

+/*u0*/GRANT INSERT(openc) ON multicol TO public;

+/*u0*/GRANT UPDATE(openc) ON multicol TO public;

+

+

+-- Test col-specific SELECTs

+/*u0*/CONNECT USER u1 PASSWORD "u1";

+/*c1*/SELECT openc from multicol;

+/*c1*/SELECT limitedc from multicol;

+/*e*/SELECT closedc from multicol;

+/*e*/UPDATE multicol set limitedc = 4 where openc = 1;

+

+/*u0*/CONNECT USER privd PASSWORD "privd";

+/*c1*/SELECT openc from multicol;

+/*c1*/SELECT limitedc from multicol;

+/*c1*/SELECT closedc from multicol;

+/*u1*/UPDATE multicol set limitedc = 5 where openc = 1;

+/*u0*/CONNECT USER unprivd PASSWORD "unprivd";

+/*e*/SELECT limitedc from multicol;

+/*e*/SELECT closedc from multicol;

+/*e*/UPDATE multicol set limitedc = 6 where openc = 1;

+

+-- Test col-specific UPDATEs

+/*u0*/CONNECT USER u1 PASSWORD "u1";

+/*c1*/SELECT openc from multicol;

+/*e*/UPDATE multicol set limitedc = 7 where openc = 1;

+/*u0*/CONNECT USER SA PASSWORD "";

+/*u0*/GRANT update(limitedc) ON multicol TO u1;

+/*u0*/CONNECT USER u1 PASSWORD "u1";

+/*u1*/UPDATE multicol set limitedc = 7 where openc = 1;

+

+-- Test col-specific INSERTs

+/*u0*/CONNECT USER u1 PASSWORD "u1";

+/*e*/INSERT INTO multicol(limitedc) values(10);

+/*u0*/CONNECT USER SA PASSWORD "";

+/*u0*/GRANT insert(limitedc) ON multicol TO u1;

+/*u0*/CONNECT USER privd PASSWORD "privd";

+/*u1*/INSERT INTO multicol(limitedc) values(11);

+/*u0*/CONNECT USER unprivd PASSWORD "unprivd";

+/*e*/INSERT INTO multicol(limitedc) values(12);

+/*u0*/CONNECT USER u1 PASSWORD "u1";

+/*u1*/INSERT INTO multicol(limitedc) values(13);

+

+/*u0*/CONNECT USER SA PASSWORD "";

+/*u0*/DROP USER u1;

+/*u0*/DROP USER privd;

+/*u0*/DROP USER unprivd;

+/*u0*/DROP TABLE multicol;

+/*u0*/CHECKPOINT;

diff --git a/testrun/hsqldb/TestSelfConstraints.txt b/testrun/hsqldb/TestSelfConstraints.txt
new file mode 100644
index 0000000..8fca34f
--- /dev/null
+++ b/testrun/hsqldb/TestSelfConstraints.txt
@@ -0,0 +1,60 @@
+--

+-- TestSelfConstraints.txt

+--

+-- Tests for Constraints

+-- bug #733940

+-- NOT NULL enforcement

+-- IDENTITY can be set to NULL to be regenerated but other NOT NULL columns can't

+CREATE CACHED TABLE THEME (idTheme integer NOT NULL IDENTITY,

+ libelle VARCHAR(10) CONSTRAINT THEMECOSNT NOT NULL,description VARCHAR(10));

+insert into theme(libelle, description) values('ESSAI', 'ESSAI');

+/*e*/update theme set libelle = null where idtheme = 0;

+/*u1*/update theme set idTheme = null where idtheme = 0;

+/*u1*/update theme set idTheme = default where idtheme = 1;

+

+-- bug #722442

+create table confignodetype (cnt_nodetypeid numeric(10) not null primary key,

+ cnt_parentid numeric(10) not null,cnt_name varchar(40) not null,

+ constraint fk_cnt_parentid foreign key (cnt_parentid)

+ references confignodetype(cnt_nodetypeid));

+/*u1*/INSERT INTO confignodetype VALUES (-1,-1,'prj');

+

+-- bug #1114899

+create table mytable(field1 int not null, field2 int);

+alter table mytable add constraint pk primary key (field1);

+/*e*/alter table mytable add constraint pk foreign key (field2)

+ references mytable(field1) ;

+alter table mytable add constraint fk foreign key (field2)

+ references mytable(field1) ;

+/*u1*/insert into mytable values (0,0);

+/*u1*/insert into mytable values (1,1);

+/*u1*/insert into mytable values (2,1);

+/*u1*/delete from mytable where field1= 2;

+/*u1*/delete from mytable where field1= 1;

+/*u1*/delete from mytable where field1= 0;

+/*r0*/select count(*) from mytable;

+

+alter table mytable drop constraint fk;

+alter table mytable drop constraint pk;

+drop table mytable;

+

+--

+

+CREATE TABLE "Table3" ("ID" INTEGER NOT NULL,"dd" INTEGER, PRIMARY KEY ("ID"));

+ALTER TABLE "Table3" ALTER COLUMN "ID" INTEGER IDENTITY;

+ALTER TABLE "Table3" ALTER COLUMN "ID" INTEGER;

+ALTER TABLE "Table3" DROP PRIMARY KEY;

+ALTER TABLE "Table3" ADD PRIMARY KEY("dd");

+ALTER TABLE "Table3" ALTER COLUMN "dd" INTEGER IDENTITY;

+

+---

+create table a ( a_id varchar(32) primary key );

+

+create table b ( b_id varchar(32) primary key,

+ a varchar(33) not null);

+

+insert into a values ('TESTA');

+insert into b values ('TESTB','TESTA');

+

+alter table b add constraint b_fk_a foreign key (a) references a (a_id);

+drop table a cascade

diff --git a/testrun/hsqldb/TestSelfConversions.txt b/testrun/hsqldb/TestSelfConversions.txt
new file mode 100644
index 0000000..eb532e4
--- /dev/null
+++ b/testrun/hsqldb/TestSelfConversions.txt
@@ -0,0 +1,16 @@
+DROP TABLE T1 IF EXISTS;

+CREATE TABLE T1(ID IDENTITY, DT DATE,TI TIME,TS TIMESTAMP);

+INSERT INTO T1 (ID, DT, TI, TS) VALUES (NULL, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP);

+SELECT DAYOFMONTH(DT) FROM T1;

+SELECT DAYOFMONTH(TS) FROM T1;

+DELETE FROM T1;

+INSERT INTO T1 (ID, DT, TI, TS) VALUES (NULL, DATE'2000-11-10', TIME'10:11:12',TIMESTAMP'2000-12-10 10:11:12');

+/*r2000*/SELECT YEAR(TS) FROM T1;

+/*r12*/SELECT MONTH(TS) FROM T1;

+/*r10*/SELECT DAYOFMONTH(DT) FROM T1;

+/*r10*/SELECT DAYOFMONTH(TS) FROM T1;

+/*r10-01*/SELECT (DATE'2010-12-20' - DT) YEAR TO MONTH FROM T1;

+/*r121*/SELECT (DATE'2010-12-20' - DT) MONTH(4) FROM T1;

+/*r9-11*/SELECT (DATE'2010-10-20' - DT) YEAR TO MONTH FROM T1;

+/*r9-10*/SELECT (DATE'2010-10-20' - (MAX(DT) + INTERVAL '1' MONTH)) YEAR TO MONTH FROM T1;

+DROP TABLE T1

diff --git a/testrun/hsqldb/TestSelfCreate.txt b/testrun/hsqldb/TestSelfCreate.txt
new file mode 100644
index 0000000..8c7d251
--- /dev/null
+++ b/testrun/hsqldb/TestSelfCreate.txt
@@ -0,0 +1,163 @@
+--

+-- TestSelfCreate.txt

+--

+

+-- TestSelfCreate.txt is used by TestSelf.java to test the database

+--

+-- This is part of a three part suite of scripts to test persistence in the same DB

+--

+-- Comment lines must start with -- and are ignored

+-- Lines starting with spaces belongs to last line

+-- Checked lines start with comments containing <tag> where <tag> is:

+--   c <rows>     ResultSet expects a with <row> columns

+--   r <string>   ResultSet expected with <string> result in first row/column

+--   u <count>    Update count <count> expected

+--   e            Exception must occur

+

+-- Correct handling of index creation for foreign keys

+

+create cached table VEREIN

+   (

+   VCODE CHAR(10) not null,

+   primary key (VCODE)

+   );

+

+-- a no-op

+create unique index VEREIN_PK on VEREIN (VCODE);

+create cached table BEWERB

+   (

+   VCODE CHAR(10) not null,

+   ID SMALLINT not null ,

+   primary key (ID)

+   );

+

+-- a no-op

+create unique index BEWERB_FK2 on BEWERB(ID);

+-- a no-op

+create unique index BEWERB_FK1 on BEWERB(VCODE);

+alter table BEWERB add constraint bv foreign key (VCODE) references VEREIN(VCODE);

+

+-- forward FK with index

+

+CREATE Cached TABLE t1(

+   ID INTEGER NOT NULL PRIMARY KEY,

+   t2ref INTEGER

+   );

+

+CREATE Cached TABLE t2(

+   ID INTEGER NOT NULL PRIMARY KEY

+   );

+CREATE INDEX idx on t1(t2ref);

+ALTER TABLE t1 ADD CONSTRAINT fk1 FOREIGN KEY (t2ref) REFERENCES t2(ID);

+

+-- forward FK with no index

+

+CREATE Cached TABLE tt1(

+   ID INTEGER NOT NULL PRIMARY KEY,

+   tt2ref INTEGER

+   );

+

+CREATE Cached TABLE tt2(

+   ID INTEGER NOT NULL PRIMARY KEY

+   );

+ALTER TABLE tt1 ADD CONSTRAINT fk2 FOREIGN KEY (tt2ref) REFERENCES tt2(ID);

+

+-- column default values - scripting test

+

+CREATE TABLE TDEF1 (

+   I1 IDENTITY, C1 CHAR DEFAULT '-',

+   C2 CHAR(10) DEFAULT 'hsqldb',

+   I3 INTEGER DEFAULT -1,

+   D4 DOUBLE DEFAULT -0.3e-5,

+   T5 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

+   T6 TIME DEFAULT current_time,

+   D7 DATE DEFAULT current_date,

+   D8 VARCHAR(10) DEFAULT current_user

+   );

+CREATE TABLE TDEF2 (

+   B1 BOOLEAN DEFAULT TRUE,

+   B2 BOOLEAN DEFAULT 'false',

+   T5 TIMESTAMP DEFAULT '1999-12-01 21:30:00',

+   T6 TIME DEFAULT '23:12:01',

+   T7 DATE DEFAULT '2002-02-15'

+   );

+

+

+INSERT INTO TDEF1 (I3) VALUES (0);

+INSERT INTO TDEF1 (D4) VALUES (0);

+INSERT INTO TDEF2 (B1) VALUES (FALSE);

+INSERT INTO TDEF2 (T7) VALUES (NULL);

+

+

+--bug #824031

+--scripting test for order of indexes

+CREATE CACHED TABLE APP (

+ VARIANT_ID INTEGER NOT NULL,

+ APP_ID INTEGER NOT NULL,

+ APP_NAME VARCHAR (35) NOT NULL,

+ CONSTRAINT PK_APP PRIMARY KEY( VARIANT_ID));

+CREATE INDEX APP ON APP(APP_ID);

+ALTER TABLE APP ADD CONSTRAINT APP_IX1 UNIQUE( APP_NAME);

+INSERT INTO APP VALUES (1, 1, 'Shelly');

+INSERT INTO APP VALUES (2, 2, 'Eran');

+/*c1*/SELECT * FROM APP WHERE APP_NAME = 'Shelly';

+/*c1*/SELECT * FROM APP WHERE APP_NAME = 'Eran';

+

+--test identity increment

+CREATE CACHED TABLE APP2 (

+ ID BIGINT NOT NULL IDENTITY,

+ VALUE INTEGER NOT NULL)

+

+INSERT INTO APP2 (VALUE) VALUES(10);

+

+--test update with no primary key

+DROP TABLE FILE IF EXISTS;

+CREATE TABLE FILE(ID VARCHAR(10), NAME VARCHAR(10),

+ DESCRIPTION VARCHAR(10), FIELD1 INT, FIELD2 VARCHAR(10));

+/*c0*/select * from file;

+insert into file(id, name) values('14', 'dir');

+/*c1*/select * from file;

+update file set name = 'newdir' where id = '14';

+/*r

+  14,newdir,NULL,NULL,NULL

+*/select * from file;

+

+--test TEMP TABLE

+

+create TEMPORARY TABLE TTEMP(C CHAR) ON COMMIT PRESERVE ROWS;

+create TEMPORARY TABLE TTEMP2(C CHAR) ON COMMIT DELETE ROWS;

+

+--test VIEW persistence with quoted column names

+

+create table "TView" ("First Column" int, "Second Column" bigint);

+

+create view "View" ("Id", "The Name", "The Description")

+  as select ID,NAME,DESCRIPTION FROM FILE;

+

+create view "View2"

+  as select ID,NAME "The Name",DESCRIPTION "The Description" FROM FILE;

+

+create view "View3" as select "First Column", "Second Column" from "TView";

+

+--test inline column check constraints

+

+create table TCONST (COLA INT UNIQUE CHECK(COLA < 10), COLB INT UNIQUE CHECK(COLB > 10))

+

+--test separate identity and primary key

+

+create table TIDENT (COLA INT PRIMARY KEY,

+ COLB INT GENERATED BY DEFAULT AS IDENTITY(INCREMENT BY 1 START WITH 0))

+insert into tident values (10, default);

+insert into tident values (11, default);

+insert into tident values (12, default);

+/*e*/insert into tident values (10, default);

+/*r

+ 10,0

+ 11,1

+ 12,2

+*/select * from tident

+

+-- SHUTDOWN is necessary for test1

+

+SHUTDOWN IMMEDIATELY;

+

diff --git a/testrun/hsqldb/TestSelfFKModes.txt b/testrun/hsqldb/TestSelfFKModes.txt
new file mode 100644
index 0000000..01dbf4e
--- /dev/null
+++ b/testrun/hsqldb/TestSelfFKModes.txt
@@ -0,0 +1,206 @@
+-- CIRCULAR SELF REFERENCING FK

+-- ON DELETE CASCADE

+drop table testB if exists;

+create cached table testB(id integer, parent integer, ref integer,

+ data varchar(200), unique(parent), primary key (id),foreign key (parent)

+ references testB(id) on delete cascade, foreign key (id)

+ references testB(parent) on delete cascade);

+/*u1*/insert into testB values(100,100,1,'xxxx');

+/*u1*/insert into testB values(200,200,1,'xxxx');

+/*u1*/delete from testB where id=100;

+/*r200,200,1,xxxx*/select * from testB

+-- NORMAL SELF REFERENCING FK

+-- ON DELETE CASCADE

+drop table testB if exists;

+create cached table testB(id integer, parent integer, ref integer,

+ data varchar(200), unique (id), foreign key (parent)

+ references testB(id) on delete cascade);

+/*u1*/insert into testB values(100,100,1,'xxxx');

+/*u1*/insert into testB values(101,100,1,'xxxx');

+/*u1*/insert into testB values(102,100,1,'xxxx');

+/*u1*/insert into testB values(200,200,1,'xxxx');

+/*u1*/delete from testB where id=100;

+/*r200,200,1,xxxx*/select * from testB

+/*c1*/select * from testB

+-- ON DELETE SET NULL

+drop table testB if exists;

+create cached table testB(id integer, parent integer, ref integer,

+ data varchar(200), unique (id), foreign key (parent)

+ references testB(id) on delete set null);

+/*u1*/insert into testB values(100,100,1,'xxxx');

+/*u1*/insert into testB values(101,100,1,'xxxx');

+/*u1*/insert into testB values(102,100,1,'xxxx');

+/*u1*/insert into testB values(200,200,1,'xxxx');

+/*u1*/delete from testB where id=100;

+/*r

+ 101,NULL,1,xxxx

+ 102,NULL,1,xxxx

+ 200,200,1,xxxx

+*/select * from testB order by id

+/*c2*/select * from testB where parent is null

+-- ON DELETE SET DEFAULT

+

+delete from testB;

+/*u4*/insert into testB values(100,100,1,'xxxx'),

+ (101,100,1,'xxxx'),

+ (102,100,1,'xxxx'),

+ (200,200,1,'xxxx')

+

+drop table testB if exists;

+create cached table testB(id integer, parent integer default 20, ref integer,

+ data varchar(200), unique (id),foreign key (parent)

+ references testB(id) on delete set default);

+/*u1*/insert into testB values(20,20,1,'xxxx');

+/*u1*/insert into testB values(100,100,1,'xxxx');

+/*u1*/insert into testB values(101,100,1,'xxxx');

+/*u1*/insert into testB values(200,200,1,'xxxx');

+/*u1*/delete from testB where id=100;

+/*r

+ 20,20,1,xxxx

+ 101,20,1,xxxx

+ 200,200,1,xxxx

+*/select * from testB order by id

+/*c2*/select * from testB where parent=20

+-- CHAINED SELF REFERENCING FK

+-- ON DELETE CASCADE

+drop table testA if exists;

+create cached table testA(a int primary key,b int,

+    foreign key(b) references testA(a) on update cascade on delete cascade);

+insert into testA(a,b) values(1,1);

+insert into testA(a,b) values(2,1);

+insert into testA(a,b) values(3,1);

+insert into testA(a,b) values(4,2);

+insert into testA(a,b) values(5,2);

+insert into testA(a,b) values(6,2);

+insert into testA(a,b) values(7,3);

+insert into testA(a,b) values(8,3);

+insert into testA(a,b) values(9,3);

+/*u9*/update testA set a = a+1;

+/*r3*/select count(*) from testA where b=4;

+/*u9*/update testA set a = a-1;

+/*r0*/select count(*) from testA where b=4;

+/*r3*/select count(*) from testA where b=3;

+/*u1*/delete from testA where a=1;

+/*r0*/select count(*) from testA;

+-- bug 870835

+-- MIXED SELF AND FORWARD REFERENCE

+-- UPDATE ISSUE

+CREATE CACHED TABLE GroupSubject (

+ description VARCHAR(10),

+ parent BIGINT,

+ admin BIGINT NOT NULL,

+ id_ BIGINT,

+ UNIQUE ( id_ ));

+CREATE CACHED TABLE UserSubject (

+ subjectName VARCHAR(10) NOT NULL,

+ id_ BIGINT,

+ UNIQUE ( id_ ),

+ PRIMARY KEY ( subjectName ));

+ALTER TABLE GroupSubject ADD CONSTRAINT

+ GroupSubject_REF_parent

+ FOREIGN KEY ( parent )

+ REFERENCES GroupSubject ( id_ );

+ALTER TABLE GroupSubject ADD CONSTRAINT

+ GroupSubject_REF_admin

+ FOREIGN KEY ( admin )

+ REFERENCES UserSubject ( id_ );

+insert into UserSubject values ('admin', 100);

+insert into GroupSubject values (null, null, 100, 200);

+/*u1*/update GroupSubject set description = null,

+ parent = null, admin = 100 where id_ = 200;

+/*r

+ admin,100

+*/select * from UserSubject

+/*r

+ NULL,NULL,100,200

+*/select * from GroupSubject

+

+-- MULTIPLE FK ISSUE

+drop table testA if exists;

+drop table testB if exists;

+drop table testC if exists;

+create cached table testA(id integer primary key);

+create cached table testB(id integer, foreign key (id) references testA(id) on delete cascade);

+create cached table testC(id integer, foreign key (id) references testA(id));

+insert into testA values(1);

+insert into testA values(2);

+insert into testB values(1);

+insert into testB values(2);

+insert into testC values(1);

+/*e*/delete from testA

+/*c2*/select * from testB

+/*c1*/select * from testC

+/*u1*/delete from testA where id=2

+/*c1*/select * from testA

+/*c1*/select * from testB

+/*c1*/select * from testC

+

+-- INVALID SET DEFAULT

+/*e*/create cached table testE(id integer, foreign key (id) references testA(id) on delete set default);

+/*e*/create cached table testE(id integer primary key, idref integer, foreign key (idref) references teste(id) on delete set default);

+create cached table testE(id integer primary key, idref integer);

+/*e*/alter table testE add foreign key(idref) references testE(id) on delete set default;

+alter table testE alter column idref set default 10;

+alter table testE add foreign key(idref) references testE(id) on delete set default;

+/*e*/alter table testE alter column idref drop default;

+

+--

+drop table testA if exists cascade;

+drop table testB if exists;

+drop table testC if exists;

+create cached table testA(id integer primary key);

+create cached table testB(id integer primary key, foreign key (id) references testA(id) on delete cascade);

+create cached table testC(id integer primary key, foreign key (id) references testB(id) on delete cascade);

+insert into testA values 10

+insert into testB values 10

+insert into testC values 10

+alter table testA add foreign key (id) references testC(id) on delete cascade;

+delete from testA

+drop table testA if exists cascade;

+drop table testB if exists cascade;

+drop table testC if exists cascade;

+--

+create cached table testA(id integer primary key, ref integer, foreign key (ref) references testA(id));

+insert into testA values 10, 10

+insert into testA values 11, 10

+insert into testA values 12, 10

+insert into testA values 13, 12

+delete from testA

+

+CREATE TABLE user(

+ USER_ID VARCHAR(15) NOT NULL

+ ,PASSWD_TX VARCHAR(15) NOT NULL

+ ,CONSTRAINT user_PK PRIMARY KEY (USER_ID)

+ );

+

+CREATE TABLE role(

+ ROLE_NM VARCHAR(25) NOT NULL

+ ,DESC VARCHAR(100) NOT NULL

+ ,CONSTRAINT role_PK PRIMARY KEY (ROLE_NM)

+ );

+

+CREATE TABLE user_roles(

+ USER_ID VARCHAR(15) NOT NULL

+ ,ROLE_NM VARCHAR(25) NOT NULL

+ ,CONSTRAINT user_roles_PK PRIMARY KEY (USER_ID,ROLE_NM)

+ );

+

+ALTER TABLE user_roles ADD CONSTRAINT FK_user_roles_user_0 FOREIGN KEY (USER_ID) REFERENCES user;

+ALTER TABLE user_roles ADD CONSTRAINT FK_user_roles_role_1 FOREIGN KEY (ROLE_NM) REFERENCES role;

+

+INSERT INTO user VALUES('JOE_USER', 'secret');

+INSERT INTO role VALUES('SUPERSTAR', 'The best role');

+INSERT INTO role VALUES('ACTUAL_TALENT', 'What there''s a difference?');

+

+INSERT INTO user_roles VALUES('JOE_USER', 'SUPERSTAR');

+

+UPDATE user SET USER_ID='JOE_USER', PASSWD_TX = 'eat@joes37' WHERE USER_ID = 'JOE_USER'

+

+--

+

+create table department (depid identity primary key,depname varchar(20),parentid int)

+ALTER TABLE department ADD FOREIGN KEY (parentid) REFERENCES department(depid)

+insert into department (depid,depname) values(1,'dep1')

+insert into department values(2,'depchild',1)

+delete from department

+

diff --git a/testrun/hsqldb/TestSelfFieldLimits.txt b/testrun/hsqldb/TestSelfFieldLimits.txt
new file mode 100644
index 0000000..bb22016
--- /dev/null
+++ b/testrun/hsqldb/TestSelfFieldLimits.txt
@@ -0,0 +1,53 @@
+-- field limit tests

+-- works fully with sql.enforce_strict_size

+-- from 1.8.0.RC9 DECIMAL precision and scale is enforced

+-- when scale is specified, all input is rounded down to the relevant scale

+-- precision is then enforced on the result of rounding down

+drop table flimit if exists;

+create table flimit (charf1 character(4), vcharf1 varchar(4), decf1 decimal(10,2));

+insert into flimit values('one', 'two', 10.2);

+/*r

+ one ,two,10.20

+*/select * from flimit;

+/*u1*/delete from flimit;

+-- to check

+/*e*/insert into flimit values('twenty', 'two', 10.2);

+/*e*/insert into flimit values('one', 'twenty', 10.2);

+insert into flimit values('one', 'two', 99999999.11111);

+/*r

+ one ,two,99999999.11

+*/select * from flimit;

+/*r

+ one ,two,99999999.11

+*/select * from flimit where charf1 in('one','two');

+/*r

+ one ,two,99999999.11

+*/select * from flimit where charf1 in('one   ','two');

+/*r

+ 99999999

+*/select cast(decf1 as numeric(8)) from flimit;

+/*r

+ 99999999.1100

+*/select cast(decf1 as numeric(12,4)) from flimit;

+/*r

+ one tw,tw

+*/select cast((charf1 || vcharf1) as varchar(6)), cast(vcharf1 as varchar(2)) from flimit;

+/*e*/insert into flimit values('one', 'two', 999999999.11);

+/*e*/insert into flimit values('one', 'two', cast(999999999.11111 as decimal(10,2)));

+insert into flimit values('one', 'two', cast(99999999.11111 as decimal(10,2)));

+drop table flimit;

+create table flimit (a timestamp(0), b timestamp(6), c timestamp);

+insert into flimit values('2005-05-21 10:10:10.123456','2005-05-21 10:10:10.123456','2005-05-21 10:10:10.123456');

+/*c0*/select * from flimit where a = b;

+/*c0*/select * from flimit where a = c;

+/*c1*/select * from flimit where b = c;

+--

+drop table flimit if exists;

+create table flimit (bit1 bit , bit3 bit(3), bitvar bit varying(3));

+/*e*/insert into flimit values(B'1', B'1011', B'101');

+/*e*/insert into flimit values(B'1', B'101', B'1011');

+/*e*/insert into flimit values(B'10', B'101', B'1010');

+/*e*/insert into flimit values(B'1', B'10', B'1010');

+insert into flimit values(B'1', B'101', B'101');

+/*r1101*/select bit1 || bit3 from flimit

+/*r101101*/select bit3 || bitvar from flimit

diff --git a/testrun/hsqldb/TestSelfFunction.txt b/testrun/hsqldb/TestSelfFunction.txt
new file mode 100644
index 0000000..3957d02
--- /dev/null
+++ b/testrun/hsqldb/TestSelfFunction.txt
@@ -0,0 +1,63 @@
+-- AUXILIAR TABLES + DECLARES

+DROP TABLE tt1 IF EXISTS;

+DROP TABLE tt2 IF EXISTS;

+CREATE Cached TABLE tt1(

+   ID INTEGER NOT NULL PRIMARY KEY,

+   tt2ref INTEGER

+   );

+

+CREATE Cached TABLE tt2(

+   ID INTEGER NOT NULL PRIMARY KEY

+   );

+ALTER TABLE tt1 ADD CONSTRAINT fk2 FOREIGN KEY (tt2ref) REFERENCES tt2(ID);

+

+-- CREATE SIMPLE FUNCTIONS - INVALID

+

+-- Exception no returns

+/*e*/CREATE FUNCTION function_test()

+

+-- Exception no body

+/*e*/CREATE FUNCTION function_test() RETURNS INTEGER

+  BEGIN ATOMIC

+  END

+/*e*/call function_test()

+/*e*/DROP FUNCTION function_test

+

+-- Exception - invalid in parameter

+/*e*/CREATE FUNCTION function_test(IN value INTEGER) RETURNS INTEGER

+  RETURNS 10

+

+-- Exception - not supported OUT parameter

+/*e*/CREATE FUNCTION function_test(OUT val INTEGER) RETURNS INTEGER

+  RETURNS 10

+

+-- CREATE SIMPLE FUNCTIONS

+

+-- No body

+CREATE FUNCTION function_test() RETURNS INTEGER

+  RETURN 10;

+/*r10*/call function_test()

+DROP FUNCTION function_test

+

+-- Simple function - IN parameter

+CREATE FUNCTION function_test(IN val INTEGER) RETURNS INTEGER

+  RETURN val + 10;

+/*r20*/call function_test(10)

+DROP FUNCTION function_test

+

+-- Simple select

+CREATE FUNCTION function_test() RETURNS INTEGER

+  RETURN (SELECT id FROM tt2)

+INSERT INTO tt2(ID) VALUES(1);

+/*r1*/call function_test()

+DROP FUNCTION function_test

+

+CREATE FUNCTION test( in x INT)

+ returns table(i INT, v VARCHAR(100))

+ begin atomic

+   declare y int;

+   set y= x;

+   return TABLE(select id, firstname from customer where id > y);

+ end

+

+call test(10)

diff --git a/testrun/hsqldb/TestSelfGrantees.txt b/testrun/hsqldb/TestSelfGrantees.txt
new file mode 100644
index 0000000..a958732
--- /dev/null
+++ b/testrun/hsqldb/TestSelfGrantees.txt
@@ -0,0 +1,200 @@
+/*e*/CREATE USER public PASSWORD public ADMIN

+/*e*/CREATE USER _SYSTEM PASSWORD system ADMIN

+/*e*/CREATE USER public PASSWORD public

+/*e*/CREATE USER _SYSTEM PASSWORD system

+CREATE USER blaine PASSWORD blaine;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO blaine;

+CREATE USER blaineadm PASSWORD blaineadm ADMIN;

+CREATE USER debbie PASSWORD debbie;

+DROP TABLE public.t1 IF EXISTS;

+CREATE TABLE public.t1 (i int);

+INSERT INTO public.t1 VALUES (1);

+CREATE USER us3 PASSWORD us3;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO us3;

+

+-----------------------------------------------------------------------

+--                        RESERVED USERS and ROLES

+-- Test public grants

+DROP TABLE t2 IF EXISTS;

+CREATE TABLE public.t2 (i int);

+INSERT INTO public.t2 VALUES (1);

+CONNECT USER us3 PASSWORD us3;

+/*e*/SELECT * FROM t2;

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON t2 TO public;

+CONNECT USER us3 PASSWORD us3;

+/*c1*/SELECT * FROM t2;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON t2 FROM public RESTRICT;

+CONNECT USER us3 PASSWORD us3;

+/*e*/SELECT * FROM t2;

+CONNECT USER sa PASSWORD "";

+

+-- Prohibit adding/dropping reserved Roles and Users

+-- _SYSTEM role?

+/*e*/DROP ROLE dba;

+-- Spec says can't create a user or role called "public"

+/*e*/DROP USER public password x;

+/*e*/DROP USER _system password x;

+/*e*/DROP USER dba password x;

+/*e*/CREATE ROLE public;

+/*e*/CREATE ROLE _system;

+/*e*/CREATE ROLE dba;

+-- We prohibit change the built-in permissions for the DBA group, since

+-- the role is not persisted.

+

+-- Prohibit grants/revokes for _SYSTEM, DBA

+/*e*/GRANT ALL ON public.t1 TO dba;

+/*e*/GRANT ALL ON public.t1 TO _system;

+/*e*/REVOKE ALL ON public.t1 FROM dba RESTRICT;

+/*e*/REVOKE ALL ON public.t1 FROM _system RESTRICT;

+-----------------------------------------------------------------------

+

+-- Roles and Users share a namespace

+CREATE USER conflict1 PASSWORD conflict1;

+/*e*/CREATE ROLE conflict1;

+/*u0*/CREATE ROLE conflict2;

+/*e*/CREATE USER conflict2 PASSWORD conflict2;

+-- Can grant a Role but not a user

+/*e*/GRANT us3 TO conflict2;

+

+-- Grant and revoke lists for users and roles

+GRANT SELECT, UPDATE, DELETE, INSERT ON public.t2 TO conflict1;

+GRANT SELECT, UPDATE, DELETE, INSERT ON public.t2 TO conflict2;

+REVOKE SELECT, UPDATE, DELETE, INSERT ON public.t2 FROM conflict1 RESTRICT;

+REVOKE SELECT, UPDATE, DELETE, INSERT ON public.t2 FROM conflict2 RESTRICT;

+

+-- Wrong right names

+/*e*/GRANT SELECT, TABLE, COLUMN ON public.t2 TO conflict1;

+/*e*/REVOKE SELECT, TABLE, COLUMN ON public.t2 FROM conflict1 RESTRICT;

+

+-- Roles are not schemas

+/*e*/CREATE TABLE dba.x1 (i int);

+

+-- Test global (non-object) permissions of DBA Role

+GRANT ALL ON public.t1 TO blaine;

+CONNECT USER blaineadm PASSWORD blaineadm;

+/*u0*/SET TABLE public.t1 READONLY true;

+CONNECT USER blaine PASSWORD blaine;

+/*e*/INSERT INTO public.t1 VALUES(1);

+/*e*/SET TABLE public.t1 READONLY true;

+/*e*/CREATE USER user1 password user1;

+/*e*/GRANT dba TO debbie;

+CONNECT USER blaineadm PASSWORD blaineadm;

+/*u0*/GRANT dba TO blaine;

+CONNECT USER blaine PASSWORD blaine;

+/*e*/INSERT INTO public.t1 VALUES(1);

+/*u0*/SET TABLE public.t1 READONLY false;

+/*u1*/INSERT INTO public.t1 VALUES(1);

+/*u0*/CREATE USER user1 password user1;

+/*u0*/GRANT dba TO debbie;

+--CONNECT USER sa PASSWORD "";

+SET SESSION AUTHORIZATION 'SA'

+/*u0*/REVOKE dba FROM blaine RESTRICT;

+CONNECT USER blaine PASSWORD blaine;

+/*e*/SET TABLE public.t1 READONLY true;

+/*e*/CREATE USER user2 password user2;

+/*e*/REVOKE dba FROM debbie RESTRICT;

+

+-- Test using non-existent roles and re-creating existing roles.

+CONNECT USER sa PASSWORD "";

+CREATE USER us1 PASSWORD us1;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO us1;

+CREATE USER us2 PASSWORD us2;

+/*e*/DROP ROLE r1;

+/*u0*/CREATE ROLE r1;

+/*u0*/GRANT r1 TO us1;

+/*e*/GRANT r1 TO us1;

+/*u0*/REVOKE r1 FROM us1 RESTRICT;

+/*e*/REVOKE r1 FROM us1 RESTRICT;

+/*e*/REVOKE r2 FROM us1 RESTRICT;

+/*u0*/DROP ROLE r1;

+

+-- Basics

+CONNECT USER blaineadm PASSWORD blaineadm;

+/*e*/GRANT ALL ON t1 TO r1;

+/*u0*/CREATE ROLE r1;

+/*e*/GRANT r1 TO r1;

+-- us1: no privs

+CONNECT USER us1 PASSWORD us1;

+/*e*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+GRANT r1 TO us1;

+-- us1: no privs

+CONNECT USER us1 PASSWORD us1;

+/*e*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON t1 TO r1;

+-- us1: t1 rights via role r1

+CONNECT USER us1 PASSWORD us1;

+/*c2*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+GRANT dba TO us1;

+-- us1: DBA + t1 rights via role r1

+CONNECT USER us1 PASSWORD us1;

+/*c2*/SELECT * FROM public.t1;

+/*u0*/CREATE TABLE us1t1 (i int);

+/*u0*/DROP TABLE us1t1;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE dba FROM us1 RESTRICT;

+-- us1: t1 rights via role r1

+CONNECT USER us1 PASSWORD us1;

+/*c2*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r1 FROM us1 RESTRICT;

+-- us1: no privs

+CONNECT USER us1 PASSWORD us1;

+/*e*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+/*u0*/GRANT r1 TO us1;

+-- us1: t1 rights via role r1

+CONNECT USER us1 PASSWORD us1;

+/*c2*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE ALL ON t1 FROM r1 RESTRICT;

+-- us1: no privs

+CONNECT USER us1 PASSWORD us1;

+/*e*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+/*u0*/GRANT ALL ON t1 TO r1;

+-- us1: t1 rights via role r1

+CONNECT USER us1 PASSWORD us1;

+/*c2*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+/*u0*/DROP ROLE r1;

+-- us1: no privs

+CONNECT USER us1 PASSWORD us1;

+/*e*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD '';

+/*u0*/GRANT SELECT ON t1 TO us1;

+-- us1: t1 rights via role table right

+CONNECT USER us1 PASSWORD us1;

+/*c2*/SELECT * FROM public.t1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE ALL ON t1 FROM us1 RESTRICT;

+

+-- Role nesting

+CREATE ROLE r1;

+CONNECT USER us1 PASSWORD us1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+GRANT r1 TO us1;

+CONNECT USER us1 PASSWORD us1;

+/*e*/CREATE TABLE us1t1 (i int);

+CONNECT USER sa PASSWORD "";

+GRANT dba TO r1;

+CONNECT USER us1 PASSWORD us1;

+/*u0*/CREATE TABLE us1t1 (i int);

+/*u0*/DROP TABLE us1t1;

+CONNECT USER sa PASSWORD "";

+REVOKE dba FROM r1 RESTRICT;

diff --git a/testrun/hsqldb/TestSelfGroupBy.txt b/testrun/hsqldb/TestSelfGroupBy.txt
new file mode 100644
index 0000000..d4054d4
--- /dev/null
+++ b/testrun/hsqldb/TestSelfGroupBy.txt
@@ -0,0 +1,182 @@
+drop table t0 if exists;

+create table t0(c varchar(20), i integer, d date);

+insert into t0 values ('first', 1, '2000-01-01');

+insert into t0 values ('second', 2, '2000-01-02');

+insert into t0 values ('third', 3, '2000-02-01');

+select year(d), month(d), day(d) from t0;

+/*r

+ 2000,1,1

+ 2000,1,2

+ 2000,2,1

+*/select year(d) y, month(d) m, day(d) d from t0 group by year(d), month(d), day(d) order by 1, 2, 3;

+--

+drop table test if exists;

+create table test (sel int, name1 varchar(3), name2 varchar(3));

+insert into test (sel, name1, name2) values (0, 'foo', 'bar')

+insert into test (sel, name1, name2) values (1, 'baz', 'foo')

+insert into test (sel, name1, name2) values (1, 'foo', 'qux')

+-- select expressions are all composed of columns of group by

+/*r

+ baz,foo,1

+ foo,bar,1

+ foo,qux,1

+*/select a.name1, a.name2,

+  count(a.name1) as counter from test a group by sel, name1, name2 order by 1, 2, 3

+/*r

+ foo,1

+ foo,1

+ qux,1

+*/select case when a.sel=1 then a.name2 else a.name1 end as name,

+  count(a.name1) as counter from test a group by sel, name1, name2

+  order by 1, 2

+--

+/*r

+ foo,2

+ qux,1

+*/select case when a.sel=1 then a.name2 else a.name1 end as name,

+  count(a.name1) as counter from test a group by case when a.sel=1

+  then a.name2 else a.name1 end order by 1, 2

+--

+/*r

+ qux,1

+ foo,2

+*/select case when a.sel=1 then a.name2 else a.name1 end as name,

+  count(a.name1) as counter from test a group by case when a.sel=1

+  then a.name2 else a.name1 end order by counter, name

+--

+select coalesce(a.name1, a.name2) as name,count(a.sel) as counter from test a

+ group by coalesce(a.name1, a.name2)

+

+select * from (select case when a.sel=1 then a.name2 else a.name1 end as name,

+  count(a.name1) as counter from test a group by sel, name1, name2)

+

+

+drop table test;

+drop table trades_a if exists;

+create table trades_a(opened timestamp, userid int, points int);

+CREATE VIEW trades_scores AS SELECT (EXTRACT(YEAR FROM

+ opened) || '-' || EXTRACT(MONTH FROM opened) || '-' ||

+ EXTRACT(DAY FROM opened)) AS date, userid, SUM(points)

+ AS score FROM trades_a GROUP BY date, userid

+

+insert into trades_a values (now, 1, 10);

+select * from trades_scores;

+drop table trades_a cascade;

+

+--

+drop table PROCESSDETAIL if exists;

+

+create table PROCESSDETAIL (

+ ID bigint not null,

+ ALERTLEVEL integer not null,

+ VALUE varchar(255) not null,

+ TSTAMP timestamp not null,

+ ATTRIBUTEKEY integer not null,

+ PROCESSID bigint not null,

+ primary key (ID)

+ );

+

+

+-- testdata (not needed to show this problem)

+insert into PROCESSDETAIL (ALERTLEVEL, VALUE, TSTAMP, ATTRIBUTEKEY, PROCESSID, ID)

+ values (1, 66, '2007-01-01 08:00:00', 28, 9, 1);

+

+insert into PROCESSDETAIL (ALERTLEVEL, VALUE, TSTAMP, ATTRIBUTEKEY, PROCESSID, ID)

+ values (0, 67, '2007-01-01 07:59:40', 28, 9, 2);

+

+insert into PROCESSDETAIL (ALERTLEVEL, VALUE, TSTAMP, ATTRIBUTEKEY, PROCESSID, ID)

+ values (0, 67, '2007-01-01 06:59:40', 28, 9, 3);

+

+select * from PROCESSDETAIL t1 where

+ exists (

+ select

+ t2.PROCESSID,

+ t2.ATTRIBUTEKEY

+ from

+ PROCESSDETAIL t2

+ where

+ t2.PROCESSID=t1.PROCESSID

+ and t2.ATTRIBUTEKEY=t1.ATTRIBUTEKEY

+ and t2.PROCESSID=9

+ and t2.TSTAMP<='2007-01-01 08:00:00'

+ group by

+ t2.PROCESSID ,

+ t2.ATTRIBUTEKEY

+ having

+ max(t2.TSTAMP)=t1.TSTAMP);

+

+select case when 1<0 then 1 else sum(10) end as res from processdetail;

+

+DROP TABLE T1 IF EXISTS

+DROP TABLE T2 IF EXISTS

+CREATE TABLE T1 (COL1 INT, COL2 INT)

+CREATE TABLE T2 (COLA INT, COL2 INT, COLC INT, COLD DATETIME)

+

+INSERT INTO T1 VALUES (101, 201)

+INSERT INTO T1 VALUES (102, 201)

+INSERT INTO T1 VALUES (103, 202)

+INSERT INTO T1 VALUES (106, 202)

+INSERT INTO T1 VALUES (104, 203)

+INSERT INTO T1 VALUES (105, 203)

+

+INSERT INTO T2 VALUES (1001, 101, 101, '2007-08-10 10:00:00.0')

+INSERT INTO T2 VALUES (1002, 102, 101, '2007-08-10 10:00:00.0')

+INSERT INTO T2 VALUES (1003, 103, 101, '2007-08-10 10:00:00.0')

+INSERT INTO T2 VALUES (1004, 104, 101, '2007-08-10 10:00:00.0')

+INSERT INTO T2 VALUES (1004, 105, 101, '2007-08-10 10:00:00.0')

+

+SELECT T1A.COL1, T2A.COLA, MIN(T1A.COL2) AS COL2 FROM

+ T1 T1A INNER JOIN T2 T2A ON T1A.COL2 = T2A.COL2

+ WHERE T2A.COLD =

+ (SELECT MIN(T2B.COLD) FROM

+ T1 T1B INNER JOIN T2 T2B ON T1B.COL2 = T2B.COL2

+ WHERE T1A.COL1 = T1B.COL1 AND T2A.COLA = T2B.COLA AND T2A.COLC = T2B.COLC)

+ GROUP BY

+ T1A.COL1, T2A.COLA

+

+CREATE TABLE DATE_TEST (DATECOL DATE)

+

+INSERT INTO DATE_TEST VALUES ('2006-01-01')

+INSERT INTO DATE_TEST VALUES ('2007-01-01')

+INSERT INTO DATE_TEST VALUES ('2008-01-01')

+

+SELECT * FROM DATE_TEST

+SELECT * FROM DATE_TEST WHERE DATECOL > '2007-01-01'

+SELECT * FROM DATE_TEST GROUP BY DATECOL HAVING DATECOL > '2007-01-01'

+SELECT MAX(DATECOL) FROM DATE_TEST HAVING MAX(DATECOL) > '2007-01-01'

+

+create table hist (mydate date, files int, space int);

+insert into hist values (current_date, 1, 10);

+select SUBSTR(CAST (MYDATE AS VARCHAR(20)),1,10), SUM(FILES), SUM(SPACE)

+ from hist

+ group by SUBSTR(CAST (MYDATE AS VARCHAR(20)),1,10)

+

+---

+CREATE TABLE group_by_bug

+ ( order_id INTEGER NOT NULL

+ , item_id INTEGER NOT NULL

+ , price FLOAT NOT NULL

+ , tax_rate FLOAT NOT NULL

+ , quantity INTEGER NOT NULL );

+

+INSERT INTO group_by_bug ( order_id, item_id, price, tax_rate, quantity )

+ VALUES ( 1000, 100, 10, 10, 5 );

+INSERT INTO group_by_bug ( order_id, item_id, price, tax_rate, quantity )

+ VALUES ( 1001, 100, 10.45, 15, 3 );

+

+/*r

+ 100,9.09E0,8

+*/SELECT item_id, ROUND(price / (1+(tax_rate/100)),2) AS price_net,

+ SUM(quantity) AS quantity

+ FROM group_by_bug

+ GROUP BY item_id, ROUND(price / (1+(tax_rate/100)),2)

+

+/*r

+ 100,9.09E0,8

+*/SELECT item_id, ROUND(price / (1+(tax_rate/100)),2) AS price, SUM(quantity)

+ AS quantity

+ FROM group_by_bug

+ GROUP BY item_id, ROUND(price / (1+(tax_rate/100)),2)

+

+SHUTDOWN COMPACT;

+

diff --git a/testrun/hsqldb/TestSelfImmediateShutdown.txt b/testrun/hsqldb/TestSelfImmediateShutdown.txt
new file mode 100644
index 0000000..640e750
--- /dev/null
+++ b/testrun/hsqldb/TestSelfImmediateShutdown.txt
@@ -0,0 +1,30 @@
+SET AUTOCOMMIT FALSE;

+CREATE TABLE TABLE1(USER_ID INT NOT NULL PRIMARY KEY );

+INSERT INTO TABLE1 (USER_ID) VALUES (1);

+INSERT INTO TABLE1 (USER_ID) VALUES (2);

+INSERT INTO TABLE1 (USER_ID) VALUES (3);

+INSERT INTO TABLE1 (USER_ID) VALUES (4);

+CREATE TABLE TABLE2(USER_ID INT NOT NULL, COLUMN2 SMALLINT DEFAULT 0 NOT NULL,

+ COLUMN3 CHARACTER(10) DEFAULT 'TEST') ;

+ALTER TABLE TABLE2 ADD CONSTRAINT USER_FK FOREIGN KEY (USER_ID) REFERENCES TABLE1(USER_ID);

+CREATE INDEX USER_FK ON TABLE2(USER_ID);

+INSERT INTO TABLE2 (USER_ID) VALUES ( 1 ) ;

+INSERT INTO TABLE2 (USER_ID) VALUES ( 2 ) ;

+INSERT INTO TABLE2 (USER_ID) VALUES ( 3 ) ;

+INSERT INTO TABLE2 (USER_ID) VALUES ( 4 ) ;

+UPDATE TABLE2 SET COLUMN2=15 WHERE USER_ID=3;

+COMMIT;

+/*c4*/SELECT * FROM TABLE1;

+/*c4*/SELECT * FROM TABLE2;

+/*c1*/SELECT * FROM TABLE2 WHERE COLUMN2=15;

+

+-- bug #1110517

+DROP TABLE FILE2 IF EXISTS;

+CREATE TABLE FILE2(ID VARCHAR(10) PRIMARY KEY,NAME

+  VARCHAR(10),DESCRIPTION VARCHAR(10), field1 INT, field2

+  VARCHAR(10));

+-- DESCRIPTION must be NULL

+/*u1*/insert into file2(id, name) values('14', 'dir');

+/*u1*/update file2 set name = 'newdir' where id = '14';

+COMMIT;

+SHUTDOWN IMMEDIATELY;

diff --git a/testrun/hsqldb/TestSelfImmediateShutdownRecover.txt b/testrun/hsqldb/TestSelfImmediateShutdownRecover.txt
new file mode 100644
index 0000000..679c5f3
--- /dev/null
+++ b/testrun/hsqldb/TestSelfImmediateShutdownRecover.txt
@@ -0,0 +1,6 @@
+/*c4*/SELECT * FROM TABLE1;

+/*c4*/SELECT * FROM TABLE2;

+/*c1*/SELECT * FROM TABLE2 WHERE COLUMN2=15;

+-- bug #1110517

+/*rnewdir*/SELECT NAME FROM FILE2;

+DROP TABLE FILE2;

diff --git a/testrun/hsqldb/TestSelfInPredicateReferencing.txt b/testrun/hsqldb/TestSelfInPredicateReferencing.txt
new file mode 100644
index 0000000..df77bc4
--- /dev/null
+++ b/testrun/hsqldb/TestSelfInPredicateReferencing.txt
@@ -0,0 +1,176 @@
+DROP TABLE dups IF EXISTS;

+CREATE TABLE dups(pk INTEGER NOT NULL PRIMARY KEY,val VARCHAR(10) NOT NULL);

+INSERT INTO dups VALUES (1, 'first');

+INSERT INTO dups VALUES (2, 'second');

+INSERT INTO dups VALUES (3, 'third');

+INSERT INTO dups VALUES (4, 'first');

+INSERT INTO dups VALUES (5, 'first');

+INSERT INTO dups VALUES (6, 'second');

+SELECT a.pk, a.val FROM dups a WHERE a.pk in (SELECT sa.pk FROM dups sa, dups sb WHERE sa.val=sb.val AND sa.pk!=sb.pk);

+SELECT sa.pk FROM dups sa, dups sb WHERE sa.val=sb.val AND sa.pk!=sb.pk;

+/*c5*/SELECT a.pk, a.val FROM dups a WHERE a.pk IN (1, 2, 4, 5, 6);

+/*c2*/SELECT a.pk, a.val FROM dups a WHERE (a.pk, a.val) IN ((1, 'first'), (5, 'first'));

+

+-- IN with nulls

+/*c0*/SELECT * FROM dups WHERE null IN (1, 2)

+/*c0*/SELECT * FROM dups WHERE null IN (null, 2)

+/*c0*/SELECT * FROM dups WHERE null IN (null, 2)

+/*e*/SELECT * FROM dups WHERE null IN (null, null)

+/*c0*/SELECT * FROM dups WHERE cast(null AS INT) IN (null, null)

+/*c1*/SELECT * FROM dups WHERE pk IN (null, 1)

+/*c0*/SELECT * FROM dups WHERE pk IN (null, null)

+

+-- ALL

+/*r

+ 1,first

+ 4,first

+ 5,first

+*/SELECT a.pk, a.val FROM dups a WHERE a.val =

+  ALL(SELECT sa.val FROM dups sa WHERE sa.val = 'first') ORDER BY a.pk;

+/*r

+ 1,first

+ 2,second

+ 3,third

+ 4,first

+ 5,first

+ 6,second

+*/SELECT a.pk, a.val FROM dups a WHERE a.val >=  ALL(SELECT sa.val FROM dups sa WHERE sa.val = 'first') ORDER BY a.pk;

+/*r

+ 2,second

+ 3,third

+ 6,second

+*/SELECT a.pk, a.val FROM dups a WHERE a.val > ALL(SELECT sa.val FROM dups sa WHERE sa.val = 'first') ORDER BY a.pk;

+/*r

+ 1,first

+ 2,second

+ 4,first

+ 5,first

+ 6,second

+*/SELECT a.pk, a.val FROM dups a WHERE a.val

+  <= ALL(SELECT sa.val FROM dups sa WHERE sa.val = 'second') ORDER BY a.pk;

+/*r

+ 1,first

+ 2,second

+ 4,first

+ 5,first

+ 6,second

+*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ < ALL(SELECT sa.val FROM dups sa WHERE sa.val = 'third') ORDER BY a.pk;

+

+/*r

+ 1,first

+ 4,first

+ 5,first

+*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ <= ALL(SELECT sa.val FROM dups sa) ORDER BY a.pk;

+

+-- ANY

+

+/*r

+ 1,first

+ 2,second

+ 4,first

+ 5,first

+ 6,second

+*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ < ANY(SELECT sa.val FROM dups sa) ORDER BY a.pk;

+

+/*r

+ 2,second

+ 3,third

+ 6,second

+*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ > ANY(SELECT sa.val FROM dups sa) ORDER BY a.pk;

+

+/*r

+ 1,first

+ 2,second

+ 3,third

+ 4,first

+ 5,first

+ 6,second

+*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ <= ANY(SELECT sa.val FROM dups sa) ORDER BY a.pk;

+

+/*c0*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ <= ANY(SELECT CAST(NULL AS CHAR) FROM dups sa) ORDER BY a.pk;

+

+/*e*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ <= ANY(SELECT NULL FROM dups sa) ORDER BY a.pk;

+

+/*c0*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ <= ANY(SELECT CAST(NULL AS CHAR) FROM dups sa WHERE sa.val ='fourth') ORDER BY a.pk;

+

+/*e*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ <= ANY(SELECT NULL FROM dups sa WHERE sa.val ='fourth') ORDER BY a.pk;

+

+-- non-correlated single value

+/*r

+ 1,first

+ 4,first

+ 5,first

+*/SELECT a.pk, a.val FROM dups a WHERE a.val

+ = (SELECT sa.val FROM dups sa WHERE sa.pk = 4) ORDER BY a.pk;

+-- bug item #1100384

+drop table a if exists;

+drop table b if exists;

+drop table m if exists;

+create table a(a_id integer);

+create table b(b_id integer);

+create table m(m_a_id integer, m_b_id integer);

+insert into a(a_id) values(1);

+insert into b(b_id) values(10);

+insert into m(m_a_id, m_b_id) values(1, 5);

+insert into m(m_a_id, m_b_id) values(1, 10);

+insert into m(m_a_id, m_b_id) values(1, 20);

+/*r1,10*/select a.a_id, b.b_id from a, b

+ where a.a_id in (select m.m_a_id from m where b.b_id = m.m_b_id);

+/*r1,10*/select a.a_id, b.b_id from a join b on

+ a.a_id in (select m.m_a_id from m where b.b_id = m.m_b_id);

+/*u1*/update m set m_a_id = 2 where m_b_id in (1, 10, 100);

+/*r

+ 1,5

+ 2,10

+ 1,20

+*/select * from m order by m_b_id

+

+--

+DROP TABLE T IF EXISTS;

+CREATE TABLE T(C VARCHAR_IGNORECASE(10));

+INSERT INTO T VALUES ('felix');

+/*r

+ felix

+*/SELECT * FROM T WHERE C IN ('Felix', 'Feline');

+/*c0*/SELECT * FROM T WHERE C IN ('Pink', 'Feline');

+DROP TABLE T;

+CREATE TABLE T(C CHAR(10));

+INSERT INTO T VALUES ('felix');

+/*c1*/SELECT * FROM T WHERE C IN ('felix', 'pink');

+DROP TABLE T;

+

+--

+create table t (c1 int, c2 int, primary key(c2, c1))

+insert into t values (10, 20), (11, 21), (21, 32)

+/*r

+ 11,21

+*/select * from t where (c1, c2) in ((11, 21))

+/*r

+ 11,21

+*/select * from t where (c2, c1) in ((21, 11))

+

+update t set c2 = 31 where (c2, c1) in ((21, 11))

+--

+drop table if exists test_trips;

+drop table if exists test_routes;

+create table test_routes (agencyId varchar(50) not null, id varchar(255)

+ not null, primary key (agencyId, id));

+create table test_trips (agencyId varchar(50) not null, id varchar(255) not

+ null, route_agencyId varchar(50), route_id varchar(255), primary key

+ (agencyId, id));

+alter table test_trips add constraint test_trips_routes foreign key

+ (route_agencyId, route_id) references test_routes;

+insert into test_routes (agencyId, id) values ('a','r1'),('a','r2');

+insert into test_trips (agencyId, id,route_agencyId,route_id) values

+ ('a','1','a','r1'),('a','2','a','r2');

+/*c1*/select * from test_trips where (route_agencyId, route_id) in (('a','r1'));

+/*c2*/select * from test_trips where (route_agencyId, route_id) in (values('a','r1'), ('a','r2'));

diff --git a/testrun/hsqldb/TestSelfInsertDeleteQueries.txt b/testrun/hsqldb/TestSelfInsertDeleteQueries.txt
new file mode 100644
index 0000000..903540a
--- /dev/null
+++ b/testrun/hsqldb/TestSelfInsertDeleteQueries.txt
@@ -0,0 +1,73 @@
+--

+-- TestSelfInsertDeleteQueries.txt

+--

+-- Parser tests for insert and delete queries

+--

+create cached table testtable (

+    aString              varchar(256)                   not null,

+    firstNum             integer                        not null,

+    aDate                date                           not null,

+    secondNum            integer                        not null,

+    thirdNum             integer                        not null,

+    aName                varchar(32)                    not null

+  );

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Current', 22, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Popular', 23, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('New', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Old', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('CCurrent', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('ELV', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('ELNA', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Older', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('RA', 20, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('RP', 2, '2003-11-10', 18, 3, 'my name goes here');

+

+insert into TESTTABLE values ('VS', 3, '2003-11-10', 18, 3, 'my name goes here');

+--

+/*c11*/select * from testtable where adate = '2003-11-10' and secondNum = 18;

+/*c11*/select * from testtable where adate = '2003-11-10';

+/*c1*/select * from testtable where adate = '2003-11-10' and firstNum = 20;

+/*c11*/select * from testtable where adate = '2003-11-10' and thirdNum = 3;

+

+delete from TESTTABLE;

+

+insert into testtable values

+ ('Current', 22, '2003-11-10', 18, 3, 'my name goes here'),

+ ('Popular', 23, '2003-11-10', 18, 3, 'my name goes here'),

+ ('New', 5, '2003-11-10', 18, 3, 'my name goes here'),

+ ('Old', 5, '2003-11-10', 18, 3, 'my name goes here')

+

+/*c4*/select * from testtable;

+

+update testtable set (astring, firstnum, adate, secondnum, thirdnum, aname) =

+ ('Older', 5, '2003-11-10', 18, 3, 'my name goes here')

+ where astring = 'Old'

+--

+

+create table tt (col varchar(256));

+insert into tt (col) select aString from testtable;

+insert into tt (col) select aString from testtable union select aName from testtable;

+insert into tt (col) (select aString from testtable union select aName from testtable);

+insert into tt (col)

+ ((select aString from testtable union select aName from testtable)

+ intersect select aString from testtable where firstNum = 20);

+

+insert into tt select aString from testtable;

+insert into tt select aString from testtable union select aName from testtable;

+insert into tt (select aString from testtable union select aName from testtable);

+insert into tt

+ ((select aString from testtable union select aName from testtable)

+ intersect select aString from testtable where firstNum = 20);

+

+drop table tt;

+drop table testtable;

diff --git a/testrun/hsqldb/TestSelfInsteadOfTriggers.txt b/testrun/hsqldb/TestSelfInsteadOfTriggers.txt
new file mode 100644
index 0000000..ae62342
--- /dev/null
+++ b/testrun/hsqldb/TestSelfInsteadOfTriggers.txt
@@ -0,0 +1,40 @@
+drop table testtrig12 if exists;

+drop table testtrig13 if exists;

+create cached table testtrig12(id integer, data2 varchar(20), updated date);

+create cached table testtrig13(id integer, data3 varchar(20), op varchar(10));

+create view viewinst (vid, vdata2, vdata3) as select id, data2, data3 from testtrig12 natural join testtrig13

+create trigger trigger2 instead of insert on viewinst

+ referencing new row as newrow

+ for each row

+ begin atomic

+ insert into testtrig12 values(newrow.vid, newrow.vdata2, current_date);

+ insert into testtrig13 values (newrow.vid, newrow.vdata3, 'inserted');

+ end

+

+create trigger trigger3 instead of delete on viewinst

+ referencing old row as oldrow

+ for each row

+ begin atomic

+ delete from testtrig12 where testtrig12.id = oldrow.vid;

+ delete from testtrig13 where testtrig13.id = oldrow.vid;

+ end

+

+create trigger trigger14 instead of update on viewinst

+ referencing old row as oldrow new row as newrow

+ for each row

+ begin atomic

+ update testtrig12 set data2 = newrow.vdata2, updated = current_date where testtrig12.id = oldrow.vid;

+ update testtrig13 set data3 = newrow.vdata3, op = 'updated' where testtrig13.id = oldrow.vid;

+ end

+

+insert into viewinst values (1, 'data2 value1', 'data3 value1')

+insert into viewinst values (2, 'data2 value2', 'data3 value2')

+

+/*r

+ 1,data3 value1,inserted

+ 2,data3 value2,inserted

+*/select * from testtrig13

+

+update viewinst set vdata2='data2 updated1', vdata3='data3 updated1' where vid=1

+

+delete from viewinst

diff --git a/testrun/hsqldb/TestSelfInternalFunctions.txt b/testrun/hsqldb/TestSelfInternalFunctions.txt
new file mode 100644
index 0000000..4e8fe02
--- /dev/null
+++ b/testrun/hsqldb/TestSelfInternalFunctions.txt
@@ -0,0 +1,16 @@
+/*rXXX*/call trim('   XXX   ');

+/*rXXX*/call trim(FROM '   XXX   ');

+/*rXXX*/call trim(BOTH FROM '   XXX   ');

+/*rXXX*/call trim(BOTH ' ' FROM '   XXX   ');

+/*e*/call trim(BOTH FROM);

+/*rXXX*/call substring( ' XXX  ' from 2 for 3);

+/*rXXX*/call substring( ' XXX' from 2);

+/*rXXXX*/call overlay( 'YYY' placing 'XXXX' from 1 for 3);

+/*rYXXYY*/call overlay( 'YYYYYY' placing 'XX' from 2 for 3);

+/*rXYY*/call overlay( 'YYY' placing 'X' from 1);

+/*rYXY*/call overlay( 'YYY' placing 'X' from 2);

+/*r0109090405*/call overlay( x'0102030405' placing x'0909' from 2);

+call current_timestamp;

+call current_timestamp(1);

+call current_time;

+call current_time(6);

diff --git a/testrun/hsqldb/TestSelfInterval.txt b/testrun/hsqldb/TestSelfInterval.txt
new file mode 100644
index 0000000..7e1a5e3
--- /dev/null
+++ b/testrun/hsqldb/TestSelfInterval.txt
@@ -0,0 +1,57 @@
+-- TESTS FOR DATETIME AND INTERVAL

+/*r

+ 1999-12-31 00:00:00.900000

+*/CALL TIMESTAMP '2000-01-01 02:02:03.000000' - INTERVAL '01 02:02:02.1' DAY TO SECOND;

+/*r

+ 1999-12-31 00:00:00.000000

+*/CALL TIMESTAMP '2000-01-01 02:02:02.123456' - INTERVAL '01 02:02:02.123456' DAY TO SECOND(6);

+/*e*//CALL TIMESTAMP(6) '2000-01-01 02:02:02.123456';

+/*r

+ 1999-12-31 00:00:00.023456

+*/CALL TIMESTAMP '2000-01-01 02:02:02.123456' - INTERVAL '01 02:02:02.10' DAY TO SECOND;

+/*r

+ 1999-12-31 00:00:00.020

+*/CALL TIMESTAMP '2000-01-01 02:02:02.120' - INTERVAL '01 02:02:02.10' DAY TO SECOND;

+/*r

+ -0 00:01:00.0

+*/CALL  INTERVAL '01 02:02:02.1' DAY TO SECOND - INTERVAL '01 02:03:02.1' DAY TO SECOND;

+/*r

+  1 02:02:00.02000000

+*/CALL  INTERVAL '01 02:02:02.12' DAY(3) TO SECOND(8) - INTERVAL '02.1' SECOND(2,3);

+/*r

+  1 02:02:00.0

+*/CALL  INTERVAL '01 02:02:02.12345' DAY(2) TO SECOND(1) - INTERVAL '02.1' SECOND(2,1);

+/*r

+  1 00:00:00.000000

+*/CALL (TIMESTAMP '2000-01-02 02:02:03.000000' - TIMESTAMP '2000-01-01 02:02:03.000000') DAY TO SECOND;

+

+/*r

+  1 00:00:00.180000

+*/CALL (TIMESTAMP '2000-01-02 02:02:03.2' - TIMESTAMP '2000-01-01 02:02:03.02') DAY TO SECOND;

+/*r

+  1

+*/CALL TIMESTAMPDIFF(SQL_TSI_YEAR, TIMESTAMP '2002-01-02 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

+/*r

+  4

+*/CALL TIMESTAMPDIFF(SQL_TSI_QUARTER, TIMESTAMP '2002-01-02 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

+/*r

+  12

+*/CALL TIMESTAMPDIFF(SQL_TSI_MONTH, TIMESTAMP '2002-01-02 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

+/*r

+  52

+*/CALL TIMESTAMPDIFF(SQL_TSI_WEEK, TIMESTAMP '2002-01-02 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

+/*r

+  364

+*/CALL TIMESTAMPDIFF(SQL_TSI_DAY, TIMESTAMP '2002-01-02 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

+/*r

+  8760

+*/CALL TIMESTAMPDIFF(SQL_TSI_HOUR, TIMESTAMP '2002-01-01 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

+/*r

+  525600

+*/CALL TIMESTAMPDIFF(SQL_TSI_MINUTE, TIMESTAMP '2002-01-01 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

+/*r

+  31536000

+*/CALL TIMESTAMPDIFF(SQL_TSI_SECOND, TIMESTAMP '2002-01-01 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

+/*r

+  31536000180000000

+*/CALL TIMESTAMPDIFF(SQL_TSI_FRAC_SECOND, TIMESTAMP '2002-01-01 02:02:03.02', TIMESTAMP '2003-01-01 02:02:03.2')

diff --git a/testrun/hsqldb/TestSelfIssues.txt b/testrun/hsqldb/TestSelfIssues.txt
new file mode 100644
index 0000000..52ef26a
--- /dev/null
+++ b/testrun/hsqldb/TestSelfIssues.txt
@@ -0,0 +1,131 @@
+--

+-- TestSelfIssues.txt

+--

+-- Tests demonstrating remaining issues

+--

+-- bug #901313 - fixed - subselect results in error when it returns no rows

+-- corrected for 1.8.0 RC10 - scalar subquery should return null if no rows are returned

+drop table table2 if exists;

+drop table table1 if exists;

+create table table1 (col1 integer not null, col2 integer not null);

+create table table2 (col1 integer, col2 integer);

+insert into table1 (col1, col2) values (1, 1)

+insert into table1 (col1, col2) values (2, 2)

+insert into table2 (col1, col2) values (1, 3)

+insert into table2 (col1, col2) values (2, 4)

+/*c2*/select t1.col1, t1.col2, t2.col2 from table1 t1, table2 t2 where t1.col1 = t2.col1

+/*u2*/update table2 set col2=(select table1.col2 from table1 where table1.col1 = table2.col1)

+/*c2*/select t1.col1, t1.col2, t2.col2 from table1 t1, table2 t2 where t1.col1 = t2.col1

+/*u1*/insert into table2 (col1, col2) values (null, 5)

+/*u3*/update table2 set col2=(select table1.col2 from table1 where table1.col1 = table2.col1)

+-- support for aliases in UPDATE has been added

+/*u3*/update table2 b set col2 = (select a.col2 from table1 a where a.col1 = b.col1)

+/*c2*/select t1.col1, t1.col2, t2.col2 from table1 t1, table2 t2 where t1.col1 = t2.col1

+-- query returns only rows for which the correlated subquery returns a value

+/*c3*/select table2.col2,(select table1.col2 from table1 where table1.col1 = table2.col1) from table2

+-- add row so that subquery returns two rows

+/*u1*/insert into table1 (col1, col2) values (1, 6)

+/*e*/select table2.col2,(select table1.col2 from table1 where table1.col1 = table2.col1) from table2

+

+-- reported bug - fixed - first bigint in value list was ignored

+DROP TABLE T IF EXISTS;

+CREATE TABLE T(A BIGINT);

+INSERT INTO T VALUES(7223955391172290801);

+INSERT INTO T VALUES(8124225344737252039);

+INSERT INTO T VALUES(8112873400132257948);

+INSERT INTO T VALUES(100);

+/*c4*/SELECT * FROM T WHERE A IN

+ (7223955391172290801,8124225344737252039,8112873400132257948,100);

+-- check with different types

+/*c4*/SELECT * FROM T WHERE A IN

+ (7223955391172290801,8124225344737252039,8112873400132257948,100.00E0);

+

+-- reported bug - fixed - TRUE and FALSE in conditions

+/*c4*/SELECT * FROM T WHERE A IN

+ (7223955391172290801,8124225344737252039,8112873400132257948,100) AND TRUE;

+

+/*c0*/SELECT * FROM T WHERE A IN

+ (7223955391172290801,8124225344737252039,8112873400132257948,100) AND FALSE;

+

+-- demonstration of contatenation from Blaine

+CREATE TABLE tsttbl(

+    id IDENTITY,

+    FirstName VARCHAR(10),

+    MiddleName VARCHAR(10),

+    LastName VARCHAR(10),

+    CommonLink VARCHAR(20)

+ );

+INSERT INTO tsttbl(firstname, middlename, lastname, commonlink)

+ VALUES ('John', 'Paul', 'Jones', 'http://cnn.com');

+INSERT INTO tsttbl(firstname, middlename, lastname, commonlink)

+ VALUES ('Bridget', 'Paula', 'Murphy', 'http://cnn.com');

+--  Raw SELECT using ||:

+SELECT FirstName || MiddleName || LastName, CommonLink

+ FROM tsttbl;

+--  Creating View using ||:

+CREATE VIEW tstview AS SELECT

+    FirstName || MiddleName || LastName, CommonLink FROM tsttbl;

+-- Executing View Query:

+SELECT * FROM tstview;

+--  Raw SELECT using +:

+SELECT FirstName + ' ' + MiddleName + ' ' + LastName, CommonLink

+ FROM tsttbl;

+

+-- reported bug #1487591

+CREATE TABLE TESTTABLE(ID IDENTITY, MY_VALUE VARCHAR(10), MY_ROW_TYPE VARCHAR(10));

+INSERT INTO TESTTABLE (MY_VALUE,MY_ROW_TYPE) VALUES ('A', 'B');

+SELECT ID, MY_VALUE FROM TESTTABLE

+ AS TBL1 WHERE ID = (SELECT MAX(ID) AS ID FROM TESTTABLE

+ AS TBL2 WHERE TBL1.MY_VALUE=TBL2.MY_VALUE);

+

+-- reported bug

+

+drop table PROCESSDETAIL if exists;

+

+create table PROCESSDETAIL (

+        ID bigint not null,

+        ALERTLEVEL integer not null,

+        VALUE varchar(255) not null,

+        TSTAMP timestamp(0) not null,

+        ATTRIBUTEKEY integer not null,

+        PROCESSID bigint not null,

+        primary key (ID) );

+

+

+insert into

+        PROCESSDETAIL

+        (ALERTLEVEL, VALUE, TSTAMP, ATTRIBUTEKEY,

+         PROCESSID, ID)

+ values(1, 66, '2007-01-01 08:00:00', 28, 9, 1);

+

+insert into

+        PROCESSDETAIL

+        (ALERTLEVEL, VALUE, TSTAMP, ATTRIBUTEKEY,

+         PROCESSID, ID)

+ values(0, 67, '2007-01-01 07:59:40', 28, 9, 2);

+

+/*r

+ 1,1,66,2007-01-01 08:00:00,28,9

+*/select *  from

+        PROCESSDETAIL t1

+    where exists (

+            select

+                t2.PROCESSID,

+                t2.ATTRIBUTEKEY

+            from

+                PROCESSDETAIL t2

+            where

+                t2.PROCESSID=t1.PROCESSID

+                and t2.ATTRIBUTEKEY=t1.ATTRIBUTEKEY

+                and t2.PROCESSID=9

+                and t2.TSTAMP<='2007-01-01 08:00:00'

+            group by

+                t2.PROCESSID ,

+                t2.ATTRIBUTEKEY

+            having  max(t2.TSTAMP)=t1.TSTAMP );

+--

+--

+create table element (deadline timestamp);

+SELECT DISTINCT convert(element.deadline,Date) FROM element ORDER BY

+ convert(element.deadline,Date) ASC

+

diff --git a/testrun/hsqldb/TestSelfJoins.txt b/testrun/hsqldb/TestSelfJoins.txt
new file mode 100644
index 0000000..efb6895
--- /dev/null
+++ b/testrun/hsqldb/TestSelfJoins.txt
@@ -0,0 +1,39 @@
+--

+-- TestSelfJoins.txt

+--

+create table tsj1 (a integer primary key, b integer);

+insert into tsj1 values(5,5);

+insert into tsj1 values(6,6);

+insert into tsj1 values(11,21);

+insert into tsj1 values(12,22);

+insert into tsj1 values(13,23);

+insert into tsj1 values(14,24);

+insert into tsj1 values(15,25);

+insert into tsj1 values(16,26);

+insert into tsj1 values(17,27);

+/*r3*/select count(*) from tsj1 where a > 14

+/*r5*/select count(*) from tsj1 where cast(a as character(2)) > '14'

+/*r81*/select count(*) from tsj1 a cross join tsj1 b

+

+/*e*/select count(*) from tsj1 a cross join tsj1 b on a.a = b.a

+/*r9*/select count(*) from tsj1 a inner join tsj1 b on a.a = b.a

+

+drop table table1 if exists

+create table table1(column1 int not null, column2 varchar(255) not null,

+ primary key(column1))

+insert into table1(column1,column2) values(100,'string1')

+insert into table1(column1,column2) values(200,'string2')

+insert into table1(column1,column2) values(300,'string3')

+/*r3*/select count(1) rows from table1

+/*r0*/select count(1) rows from table1 where column1<300 and column1>=200 and column1<1

+/*r0*/select count(1) rows from table1 where column1<1 and column1<300 and column1>=200

+

+drop table t1 if exists;

+drop table t2 if exists;

+drop table t3 if exists;

+create table t1(id int primary key, c varchar(20));

+create table t2(id int primary key, rid int, c varchar(20));

+create table t3(id int primary key, rid int, c varchar(20));

+insert into t1 values(1, 'one'), (2, 'two'), (10, 'ten'), (11, 'eleven');

+insert into t2 values(1, 1, 'one'), (2, 2, 'two'), (3, 10, 'ten'), (4, 11, 'eleven');

+insert into t3 values(1, 1, 'one'), (2, 2, 'two'), (3, 10, 'ten'), (4, 11, 'eleven');

diff --git a/testrun/hsqldb/TestSelfLeftJoin.txt b/testrun/hsqldb/TestSelfLeftJoin.txt
new file mode 100644
index 0000000..91dc497
--- /dev/null
+++ b/testrun/hsqldb/TestSelfLeftJoin.txt
@@ -0,0 +1,524 @@
+-- SIMPLE OUTER - NO NULLS

+-- SET PROPERTY "hsqldb.default_table_type" 'cached'

+drop table x if exists;

+drop table y if exists;

+create table x(a int, b int);

+create table y(a int, b int);

+insert into x values(2, 1);

+insert into x values(5, 1);

+insert into y values(1, 1);

+insert into y values(2, 1);

+insert into y values(3, 1);

+insert into y values(4, 1);

+

+/*r1*/ select count(*) from x inner join y on (x.a = y.a);

+/*r2*/ select count(*) from x left outer join y on (x.a = y.a);

+/*r1*/ select count(*) from y inner join x on (x.a = y.a);

+/*r4*/ select count(*) from y left outer join x on (x.a = y.a);

+

+create index idx1 on y(a);

+create index idx2 on x(a);

+

+/*r1*/ select count(*) from x inner join y on (x.a = y.a);

+/*r2*/ select count(*) from x left outer join y on (x.a = y.a);

+/*r1*/ select count(*) from y inner join x on (x.a = y.a);

+/*r4*/ select count(*) from y left outer join x on (x.a = y.a);

+

+--MULTIPLE OUTER -- GROUPED

+--OWNERS are possible account owners

+--ACCOUNTS are existing accounts, each with an owner id

+--CREDITS are account transactions

+drop table credits if exists;

+drop table accounts if exists;

+drop table owners if exists;

+

+create table owners(

+ id int not null primary key,

+ name varchar(100)

+ );

+create table accounts(

+ id int not null primary key,

+ accountname varchar(100),

+ accountnr int,

+ accounttype int,

+ ownerid int,

+ constraint fk_accounts foreign key (ownerid) references owners(id)

+ );

+create table credits(

+ id int,

+ accountid int,

+ amount float,

+ constraint fk_credits foreign key (accountid) references accounts(id) on update cascade

+ );

+

+

+insert into owners values(1,'John');

+insert into owners values(2,'Mary');

+insert into owners values(3,'Jane');

+

+insert into accounts values(1,'Bank',5101,0,1);

+insert into accounts values(2,'Cash',5202,0,1);

+insert into accounts values(3,'Giro',5303,0,2);

+insert into accounts values(4,'Invoice',7505,1,1);

+

+insert into credits values(1,1,1000);

+insert into credits values(2,1,2000);

+insert into credits values(3,2,100);

+insert into credits values(4,2,200);

+

+--outer join

+/*c7*/select own.*, ac.*, cred.* from owners own

+ left outer join accounts ac on own.id = ac.ownerid

+ left outer join credits cred on cred.accountid = ac.id

+

+--ACCOUNTS are outer joined with credits to show account balance

+/*c4*/select ac.accountname,ac.accountnr,sum(cred.amount) from accounts ac

+ left outer join credits cred on cred.accountid=ac.id

+ group by ac.accountnr,ac.accountname

+

+--like above but filtered with only one account type

+/*c3*/select ac.accountname,ac.accountnr,sum(cred.amount) from accounts ac

+ left outer join credits cred on cred.accountid=ac.id

+ where accounttype=0

+ group by ac.accountnr,ac.accountname

+

+--join like above but condition changed to return only one not-null item from cred table

+/*c4*/select ac.accountname,ac.accountnr, cred.amount from accounts ac

+ left outer join credits cred on cred.accountid=ac.id and amount=200

+

+--OWNER and ACCOUNT are inner joined then outer joined with credits to show balance

+/*c3*/select own.name, ac.accountname,ac.accountnr,sum(cred.amount) from owners own

+ inner join accounts ac on own.id = ac.ownerid

+ left outer join credits cred on cred.accountid = ac.id

+ where accounttype=0

+ group by own.name,ac.accountnr,ac.accountname

+

+--OWNER and ACCOUNT are outer joined then outer joined with credits to show balance

+/*c5*/select own.name, ac.accountname,ac.accountnr,sum(cred.amount) from owners own

+ left outer join accounts ac on own.id = ac.ownerid

+ left outer join credits cred on cred.accountid = ac.id

+ group by own.name,ac.accountnr,ac.accountname

+

+--ERROR when a condition column has not been defined in the join so far

+/*e*/select own.*, ac.*, cred.* from owners own

+ left outer join accounts ac on own.id = ac.ownerid and cred.accountid = 1

+ left outer join credits cred on cred.accountid = ac.id

+

+--from 1.8.1 functions and different conditions are accepted in outer joins

+/*r

+ Bank,5101,NULL

+ Cash,5202,200.0E0

+ Giro,5303,NULL

+ Invoice,7505,NULL

+*/select ac.accountname,ac.accountnr, cred.amount from accounts ac

+ left outer join credits cred on cred.accountid=ac.id and abs(amount) = 200

+

+/*r

+ Bank,5101,NULL

+ Cash,5202,100.0E0

+ Cash,5202,200.0E0

+ Giro,5303,NULL

+ Invoice,7505,NULL

+*/select ac.accountname,ac.accountnr, cred.amount from accounts ac

+ left outer join credits cred on cred.accountid=ac.id and abs(amount) in( 200, 100)

+

+

+--MULTIPLE OUTER

+--STUDENTS contains id's for students

+--TEACHERS contains id's for teachers

+--STUDENT_TEACHER links a teacher to a student

+DROP TABLE STUDENT IF EXISTS;

+DROP TABLE TEACHER IF EXISTS;

+DROP TABLE STUDENT_TEACHER IF EXISTS;

+CREATE TABLE STUDENT(STUDENT_ID BIGINT NOT NULL PRIMARY KEY);

+CREATE TABLE TEACHER(TEACHER_ID BIGINT NOT NULL PRIMARY KEY);

+CREATE TABLE STUDENT_TEACHER(STUDENT_ID BIGINT NOT NULL, TEACHER_ID BIGINT NOT NULL);

+

+INSERT INTO STUDENT VALUES (1);

+INSERT INTO STUDENT VALUES (2);

+INSERT INTO TEACHER VALUES (100);

+INSERT INTO STUDENT_TEACHER VALUES (1, 100);

+

+--show all students with their links to teachers, include students without a teacher

+/*c2*/SELECT S.STUDENT_ID, T.TEACHER_ID FROM STUDENT S

+  LEFT JOIN STUDENT_TEACHER MAP ON S.STUDENT_ID=MAP.STUDENT_ID

+  LEFT JOIN TEACHER T ON MAP.TEACHER_ID=T.TEACHER_ID

+

+--filter the above to show students for teacher_id 100

+/*c1*/SELECT S.STUDENT_ID, T.TEACHER_ID FROM STUDENT S

+  LEFT JOIN STUDENT_TEACHER MAP ON S.STUDENT_ID=MAP.STUDENT_ID

+  LEFT JOIN TEACHER T ON MAP.TEACHER_ID=T.TEACHER_ID

+  WHERE T.TEACHER_ID = 100;

+

+--filter the first query to show only students with no teacher

+/*c1*/SELECT S.STUDENT_ID, T.TEACHER_ID FROM STUDENT S

+  LEFT JOIN STUDENT_TEACHER MAP ON S.STUDENT_ID=MAP.STUDENT_ID

+  LEFT JOIN TEACHER T ON MAP.TEACHER_ID=T.TEACHER_ID

+  WHERE T.TEACHER_ID IS NULL;

+

+--show the result of nonsensical query

+--returns one row per STUDENT_ID with TEACHER_ID set to null in each row

+/*c2*/SELECT S.STUDENT_ID, T.TEACHER_ID FROM STUDENT S

+  LEFT JOIN STUDENT_TEACHER MAP ON S.STUDENT_ID=MAP.STUDENT_ID

+  LEFT JOIN TEACHER T ON MAP.TEACHER_ID=T.TEACHER_ID

+  AND T.TEACHER_ID IS NULL;

+

+--ANOTHER OUTER WITH AND

+create table BASE (ID integer)

+create table CHILD(ID integer, BASE_ID integer)

+insert into BASE values (1)

+insert into BASE values (2)

+insert into CHILD values (1,1)

+/*r

+ 1,1

+ 2,NULL

+*/select BASE.ID,CHILD.ID from BASE left join CHILD on CHILD.BASE_ID=BASE.ID

+/*r

+ 1,NULL

+ 2,NULL

+*/select BASE.ID,CHILD.ID from BASE left join CHILD on CHILD.BASE_ID=BASE.ID and CHILD.ID>1

+/*r

+ 1,NULL

+ 2,NULL

+*/select BASE.ID,CHILD.ID from BASE left join CHILD on CHILD.BASE_ID=BASE.ID and CHILD.ID<>1

+

+--bug #736327

+create table emp(company_id varchar(10),id varchar(20),supervisor_id varchar(20), primary key (company_id,id));

+insert into emp values ('01','1000',null);

+insert into emp values ('01','1001','1000');

+/*c2*/select e.id,e.supervisor_id from emp e left join emp s on

+ e.company_id = s.company_id and e.supervisor_id = s.id;

+--

+--bug #676083

+--

+DROP TABLE T_BOSS IF EXISTS;

+DROP TABLE T_EMPLOYEE IF EXISTS;

+CREATE TABLE T_BOSS (FIRST VARCHAR(10),LAST VARCHAR(10));

+CREATE TABLE T_EMPLOYEE (FIRST VARCHAR(10),LAST VARCHAR(10));

+INSERT INTO T_BOSS VALUES ('Ludovic','ANCIAUX');

+INSERT INTO T_EMPLOYEE VALUES ('Ludovic','ANCIAUX');

+INSERT INTO T_EMPLOYEE VALUES ('Bill','GATES');

+/*rBill,GATES,NULL,NULL*/SELECT * FROM T_EMPLOYEE LEFT JOIN T_BOSS

+ ON T_EMPLOYEE.FIRST = T_BOSS.FIRST WHERE T_BOSS.FIRST IS Null;

+--

+--bug #674025

+--

+CREATE TABLE boss (id INTEGER PRIMARY KEY, name VARCHAR(10), UNIQUE(name));

+CREATE TABLE employee (id INTEGER PRIMARY KEY, name VARCHAR(10), bossid INTEGER,

+ FOREIGN KEY(bossid) REFERENCES boss (id), UNIQUE(name));

+INSERT INTO boss (id, name) VALUES (1, 'phb');

+INSERT INTO employee (id, name, bossid) VALUES (2,'dilbert', 1);

+INSERT INTO employee (id, name, bossid) VALUES (3, 'wally', null);

+/*c2*/SELECT * FROM employee e LEFT JOIN boss b ON (b.id=e.bossid);

+/*c2*/SELECT * FROM employee e LEFT JOIN boss b ON (b.id=e.bossid AND e.name='dilbert');

+/*c2*/SELECT * FROM employee e LEFT JOIN boss b ON (b.id=e.bossid AND b.name='dilbert');

+

+--bug #959678

+

+CREATE CACHED TABLE propertyvalue (

+ id INT, name CHAR(36), value VARCHAR(255));

+INSERT INTO propertyvalue VALUES (1, 'title', 'Foo');

+INSERT INTO propertyvalue VALUES (2, 'title', 'Bar');

+/*r

+ 2,2,Bar

+*/ SELECT * FROM

+ (SELECT id FROM propertyvalue WHERE name = 'title') AS id

+ LEFT JOIN

+ (SELECT id, value FROM propertyvalue WHERE name = 'title') AS title

+ ON id.id = title.id

+ WHERE title.value != 'Foo'

+

+--bug #1018584

+

+drop table a if exists;

+drop table b if exists;

+create table a (aid int, id int);

+create table b (bid int, aid int);

+insert into a (aid,id) values (1,1);

+insert into a (aid,id) values (2,1);

+insert into a (aid,id) values (3,2);

+insert into a (aid,id) values (4,2);

+insert into b (bid,aid) values (1,1);

+insert into b (bid,aid) values (2,1);

+/*c0*/select * from b left outer join a on b.aId = a.aId where Id =10;

+create index idx_test on a (ID);

+/*c0*/select * from b left outer join a on b.aId = a.aId where Id =10;

+/*c2*/select * from b left outer join a on b.aId = a.aId and Id =10;

+

+--bug #1027143

+

+drop table testc if exists;

+drop table testb if exists;

+drop table testa if exists;

+create table testa (oid int, name varchar(20));

+create table testb (oid int, name varchar(20), a_oid int);

+

+insert into testa (oid, name) values(1, 'first');

+insert into testa (oid, name) values(2, 'second');

+insert into testa (oid, name) values(3, 'third');

+insert into testa (oid, name) values(4, 'fourth');

+insert into testb (oid, name, a_oid) values(21,'first', 1);

+insert into testb (oid, name, a_oid) values(22,'second', null);

+insert into testb (oid, name, a_oid) values(23,'third', 2);

+insert into testb (oid, name, a_oid) values(24,'fourth', null);

+insert into testb (oid, name, a_oid) values(25,'fifth', 3);

+insert into testb (oid, name, a_oid) values(26,'sixth', null);

+

+/*r

+ 1,first,21,first,1

+ 2,second,23,third,2

+ 3,third,25,fifth,3

+ 4,fourth,NULL,NULL,NULL

+*/ select * from testa a LEFT OUTER JOIN testb b ON a.oid = b.a_oid

+

+create index idx3 on testb(a_oid)

+

+/*r

+ 1,first,21,first,1

+ 2,second,23,third,2

+ 3,third,25,fifth,3

+ 4,fourth,NULL,NULL,NULL

+*/ select * from testa a LEFT OUTER JOIN testb b ON a.oid = b.a_oid

+

+-- tests with OR in LEFT outer join condition

+drop table a if exists;

+drop table b if exists;

+create table a (a1 varchar(10), a2 integer);

+create table b (b1 varchar(10), b2 integer);

+insert into a values(null,12);

+insert into a values('a',22);

+insert into a values('b','32');

+

+insert into b values(null,14);

+insert into b values('a',14);

+insert into b values('c',15);

+

+-- should return 3 rows:

+/*r

+ NULL,12,NULL,14

+ a,22,a,14

+ b,32,NULL,NULL

+*/select * from a left outer join b on ((a.a1=b.b1) or (a.a1

+ is null and b.b1 is null)) order by a1

+-- should return 2 rows:

+/*r

+ NULL,12,NULL,14

+ a,22,a,14

+*/select * from a left outer join b on (1=1) where

+ ((a.a1=b.b1) or (a.a1 is null and b.b1 is null)) order by a1

+-- should return 1 row:

+/*r

+ a,22,a,14

+*/select * from a left outer join b on (1=1) where a.a1=b.b1 order by a1

+-- should return 3 rows:

+/*r

+ NULL,12,NULL,NULL

+ a,22,a,14

+ b,32,NULL,NULL

+*/select * from a left outer join b on a.a1=b.b1 where (1=1) order by a1

+/*r

+ NULL,12,NULL,NULL

+ a,22,a,14

+ b,32,NULL,NULL

+*/select * from a left outer join b on a.a1=b.b1 order by a1

+-- add an index and retest

+create index idxa on a(a2);

+/*r

+ NULL,12,NULL,NULL

+ a,22,a,14

+ b,32,NULL,NULL

+*/select * from a left outer join b on a.a1=b.b1 order by a1

+

+-- tests with OR in RIGHT join condition

+drop table a if exists;

+drop table b if exists;

+create table a (a1 varchar(10), a2 integer);

+insert into a values(null,12);

+insert into a values('a',22);

+insert into a values('b','32');

+

+create table b (b1 varchar(10), b2 integer);

+insert into b values(null,13);

+insert into b values('a',14);

+insert into b values('c',15);

+

+-- should return 3 rows:

+/*r

+ NULL,NULL,c,15

+ NULL,12,NULL,13

+ a,22,a,14

+*/select * from a right outer join b on ((a.a1=b.b1) or (a.a1

+ is null and b.b1 is null)) order by a1, a2

+-- should return 2 rows:

+/*r

+ NULL,12,NULL,13

+ a,22,a,14

+*/select * from a right outer join b on (1=1) where

+ ((a.a1=b.b1) or (a.a1 is null and b.b1 is null)) order by a1

+-- should return 1 row:

+/*r

+ a,22,a,14

+*/select * from a right outer join b on (1=1) where a.a1=b.b1 order by a1

+-- should return 3 rows:

+/*r

+ NULL,NULL,NULL,13

+ NULL,NULL,c,15

+ a,22,a,14

+*/select * from a right outer join b on a.a1=b.b1 where (1=1) order by a1

+/*r

+ NULL,NULL,NULL,13

+ NULL,NULL,c,15

+ a,22,a,14

+*/select * from a right outer join b on a.a1=b.b1 order by a1

+-- add an index and retest

+create index idxa on a(a2);

+/*r

+ NULL,NULL,NULL,13

+ NULL,NULL,c,15

+ a,22,a,14

+*/select * from a right outer join b on a.a1=b.b1 order by a1

+/*r

+ NULL,NULL

+ NULL,NULL

+ a,22

+*/select a.* from a right outer join b on a.a1=b.b1 order by a1

+/*r

+ NULL,13

+ c,15

+ a,14

+*/select b.* from a right outer join b on a.a1=b.b1 order by a1

+

+---

+CREATE TABLE names (name VARCHAR(20) PRIMARY KEY);

+CREATE TABLE params (name VARCHAR(20) PRIMARY KEY, value VARCHAR(20) NOT NULL);

+INSERT INTO names VALUES ('name1');

+INSERT INTO names VALUES ('name2');

+INSERT INTO params (name, value) VALUES ('name1', 'value1');

+/*r

+ name1,NULL

+ name2,NULL

+*/SELECT n.name, p.value FROM names n LEFT OUTER JOIN params p ON n.name = p.name AND p.value <> 'value1';

+/*r

+ name1,NULL

+ name2,NULL

+*/SELECT n.name, p.value FROM names n LEFT JOIN params p ON n.name = p.name AND p.value = 'value3';

+---

+CREATE MEMORY TABLE SUPER(PK INTEGER PRIMARY KEY,ASS CHARACTER(3))

+CREATE MEMORY TABLE ASSOCIATED(PK CHARACTER(3),I INTEGER)

+CREATE MEMORY TABLE SUB(PK INTEGER PRIMARY KEY,ASS CHARACTER(3))

+

+insert into sub values(1, 'mee')

+insert into super values(1, 'mee')

+insert into associated values('mee', 10)

+insert into associated values('you', 20)

+/*r

+ 1,mee,mee

+ NULL,NULL,you

+*/select sub.pk, sub.ass, a.pk

+  from Sub sub inner join Super super on sub.pk=super.pk

+  right outer join Associated a on super.ass=a.pk order by 3

+/*r

+ 1,mee,mee

+ NULL,NULL,you

+*/select sub.pk, sub.ass, a.pk

+  from Sub sub inner join Super super on sub.pk=super.pk

+  full outer join Associated a on super.ass=a.pk order by 3

+---

+CREATE TABLE bremsen_dl_fzg

+ ( bremsen_dl_id integer not null

+ , lfd_nr integer not null

+ , bremse_dl_fzgtyp char(1)

+ , bremse_dl_art char(1)

+ , bremse_dl_verf char(1)

+ , bremse_dl_bauart varchar(4)

+ , bremse_dl_typ char(1)

+ , ort_bedienung varchar(4)

+ , loesigkeit char(1)

+ , beschreibung varchar(30)

+ , bremse_dl_gew_id integer

+ , uhrzeit_ende timestamp not null

+ );

+ALTER TABLE bremsen_dl_fzg add constraint pk_bremsen_dl_fzg primary key

+ ( bremsen_dl_id , lfd_nr );

+ALTER TABLE bremsen_dl_fzg add constraint chk_bremsen_dl_fzg check

+ (

+ ( bremse_dl_fzgtyp is null or bremse_dl_fzgtyp in ( 'W', 'T', 't') )

+ and

+ ( bremse_dl_art is null or bremse_dl_art in ( 'B', 'F') )

+ and

+ ( bremse_dl_verf is null or bremse_dl_verf in ( 'D', 'H', 'M', 'W') )

+ and

+ ( bremse_dl_bauart is null or bremse_dl_bauart in ( 'ALaH', 'ALaT',

+ 'H2Lw', 'H3Lw') )

+ and

+ ( bremse_dl_typ is null or bremse_dl_typ in ( 'D', 'B', 'S', 'H', 'K',

+ 'F') )

+ and

+ ( ort_bedienung is null or ort_bedienung in ( 'BO', 'ST', 'BOST') )

+ and

+ ( loesigkeit is null or loesigkeit in ( 'e', 'm', 'M') )

+ );

+

+CREATE TABLE bremsen_dl_gewichte

+ ( bremse_dl_gew_id integer not null

+ , lfd_nr integer not null

+ , bremse_stellung varchar(2)

+ , gewicht_brutto float

+ , gewicht_bremse float

+ , uhrzeit_ende timestamp not null

+ );

+ALTER TABLE bremsen_dl_gewichte add constraint pk_bremsen_dl_gewichte

+ primary key

+ ( bremse_dl_gew_id , lfd_nr );

+ ALTER TABLE bremsen_dl_gewichte add constraint chk_bremsen_dl_gewichte

+ check

+ (

+ ( bremse_stellung is null or bremse_stellung in ( 'G', 'GE', 'P', 'PE',

+ 'R') )

+ );

+

+CREATE VIEW lok_bremse_lfdnr1_view

+ ( bremsen_dl_id, bremse_dl_gew_id, bremse_dl_art, bremse_dl_verf, bremse_dl_bauart,

+ bremse_dl_typ, ort_bedienung, loesigkeit, beschreibung, gewicht_bremse_g,

+ gewicht_bremse_p, gewicht_bremse_r)

+ as select br.bremsen_dl_id, br.bremse_dl_gew_id, br.bremse_dl_art, br.bremse_dl_verf,

+ br.bremse_dl_bauart, br.bremse_dl_typ, br.ort_bedienung, br.loesigkeit,

+ br.beschreibung, gew_g.gewicht_bremse, gew_p.gewicht_bremse, gew_r.gewicht_bremse

+ from bremsen_dl_fzg br

+ left join bremsen_dl_gewichte gew_g on

+ br.bremse_dl_gew_id = gew_g.bremse_dl_gew_id

+ and gew_g.bremse_stellung = 'G'

+ and gew_g.gewicht_bremse IS NOT NULL

+ left join bremsen_dl_gewichte gew_p on

+ br.bremse_dl_gew_id = gew_p.bremse_dl_gew_id

+ and gew_p.bremse_stellung = 'P'

+ and gew_p.gewicht_bremse IS NOT NULL

+ left join bremsen_dl_gewichte gew_r on

+ br.bremse_dl_gew_id = gew_r.bremse_dl_gew_id

+ and gew_r.bremse_stellung = 'R'

+ and gew_r.gewicht_bremse IS NOT NULL

+ where br.lfd_nr = 1

+ AND br.bremse_dl_bauart IN( 'ALaH','H2Lw');

+

+-- check for use of index in execution plan

+CREATE CACHED TABLE article (

+ id INTEGER IDENTITY,

+ name VARCHAR(50));

+

+CREATE CACHED TABLE salesorder_row (

+ id INTEGER IDENTITY,

+ salesorder_id INTEGER,

+ article_id INTEGER,

+ needed DECIMAL(10,2),

+ CONSTRAINT fk_salesorder_row_article FOREIGN KEY (article_id) REFERENCES

+ article (id) ON DELETE CASCADE);

+

+CREATE INDEX idx_salesorder_row_article ON salesorder_row (article_id);

+CREATE INDEX idx_salesorder_row_salesorder ON salesorder_row

+ (salesorder_id);

+

+EXPLAIN PLAN FOR

+ SELECT article.name, salesorder_row.needed

+ FROM salesorder_row

+ LEFT JOIN article ON salesorder_row.article_id = article.id

+ WHERE (salesorder_row.salesorder_id = 1234)

diff --git a/testrun/hsqldb/TestSelfModify.txt b/testrun/hsqldb/TestSelfModify.txt
new file mode 100644
index 0000000..cee0eac
--- /dev/null
+++ b/testrun/hsqldb/TestSelfModify.txt
@@ -0,0 +1,75 @@
+--

+-- TestSelfModify.txt

+--

+

+-- TestSelfModify.txt is used by TestSelf.java to test the database

+--

+-- This is the second part of a three part suite of scripts to test persistence in the same DB

+--

+-- Comment lines must start with -- and are ignored

+-- Lines starting with spaces belongs to last line

+-- Checked lines start with comments containing <tag> where <tag> is:

+--   c <rows>     ResultSet expects a with <row> columns

+--   r <string>   ResultSet expected with <string> result in first row/column

+--   u <count>    Update count <count> expected

+--   e            Exception must occur

+--

+--bug #824031 continued

+--scripting test for order of indexes

+/*c1*/SELECT * FROM APP WHERE APP_NAME = 'Eran';

+/*c1*/SELECT * FROM APP WHERE APP_NAME = 'Shelly';

+/*c2*/SELECT * FROM APP;

+--

+-- TEST 1

+-- Correct handling of index creation for foreign keys

+-- insert some values

+/*u1*/insert into verein values ('abcdefg');

+/*u1*/insert into verein values ('hijklmn');

+/*u1*/insert into verein values ('opqrstu');

+/*u1*/insert into verein values ('vwxyz');

+/*u1*/insert into bewerb values ('abcdefg',1);

+/*e*/insert into bewerb values ('abcdefg',2);

+/*u1*/insert into bewerb values ('hijklmn',5);

+/*e*/insert into bewerb values ('hijklmn',6);

+/*u1*/insert into bewerb values ('opqrstu',8);

+/*e*/insert into bewerb values ('opqrstu',9);

+/*u1*/insert into bewerb values ('vwxyz',10);

+

+--CHECKPOINT DEFRAG

+

+--test identity increment

+INSERT INTO APP2 (VALUE) VALUES(11);

+INSERT INTO APP2 (VALUE) VALUES(12);

+

+/*r3,12*/ SELECT COUNT(ID), MAX(VALUE) FROM APP2

+/*r3,10*/ SELECT COUNT(ID), MIN(VALUE) FROM APP2

+

+--test result of update before previous shutdown

+/*r

+  14,newdir,NULL,NULL,NULL

+*/select * from file;

+

+--test insert into table

+

+CREATE TABLE NEWAPP AS (SELECT * FROM APP) WITH DATA;

+/*c1*/SELECT * FROM NEWAPP WHERE APP_NAME = 'Eran';

+/*c1*/SELECT * FROM NEWAPP WHERE APP_NAME = 'Shelly';

+/*c2*/SELECT * FROM NEWAPP;

+

+INSERT INTO NEWAPP (SELECT * FROM APP)

+/*c2*/SELECT * FROM NEWAPP WHERE APP_NAME = 'Eran';

+/*c2*/SELECT * FROM NEWAPP WHERE APP_NAME = 'Shelly';

+/*c4*/SELECT * FROM NEWAPP;

+

+--test separate identity and primary key

+

+/*e*/insert into tident values (10, default);

+/*r

+ 10,0

+ 11,1

+ 12,2

+*/select * from tident

+insert into tident values (9, default);

+-- SHUTDOWN is necessary for test1

+/*u0*/SHUTDOWN;

+

diff --git a/testrun/hsqldb/TestSelfMultiGrants.txt b/testrun/hsqldb/TestSelfMultiGrants.txt
new file mode 100644
index 0000000..e6c516f
--- /dev/null
+++ b/testrun/hsqldb/TestSelfMultiGrants.txt
@@ -0,0 +1,99 @@
+/*s*/DROP USER peon1;

+/*s*/DROP USER peon2;

+/*s*/DROP USER peon3;

+/*s*/DROP ROLE r1;

+/*s*/DROP ROLE r2;

+/*s*/DROP ROLE r3;

+/*s*/DROP ROLE r12;

+DROP TABLE t1 IF exists;

+DROP TABLE t2 IF exists;

+DROP TABLE t3 IF exists;

+DROP TABLE t4 IF exists;

+CREATE TABLE t1(i int);

+CREATE TABLE t2(i int);

+CREATE TABLE t3(i int);

+CREATE TABLE t4(i int);

+INSERT INTO t1 VALUES(1);

+INSERT INTO t2 VALUES(2);

+INSERT INTO t3 VALUES(3);

+INSERT INTO t4 VALUES(4);

+COMMIT;

+CREATE USER peon1 PASSWORD password;

+CREATE USER peon2 PASSWORD password;

+CREATE USER peon3 PASSWORD password;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon1;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon2;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon3;

+

+/*u0*/CREATE ROLE r1;

+/*u0*/CREATE ROLE r2;

+/*u0*/CREATE ROLE r3;

+/*u0*/CREATE ROLE r12;

+/*u0*/GRANT ALL ON t1 TO r1;

+/*u0*/GRANT ALL ON t1 TO r12;

+/*u0*/GRANT ALL ON t2 TO r2;

+/*u0*/GRANT ALL ON t2 TO r12;

+/*u0*/GRANT ALL ON t3 TO r3;

+

+-- Can't mix right-grants and role-grants

+/*e*/GRANT r1, SELECT ON t1 TO peon1;

+/*e*/GRANT SELECT ON t1, r1 TO peon1;

+

+/*u0*/GRANT SELECT, INSERT ON t1 TO peon1;

+/*u0*/GRANT r2, r3 TO peon2;

+/*u0*/GRANT r12 TO peon3;

+

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+/*e*/SELECT * FROM t2;

+/*e*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

+CONNECT USER peon2 PASSWORD password;

+/*e*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t2;

+/*c1*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

+CONNECT USER peon3 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t2;

+/*e*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

+CONNECT USER sa PASSWORD "";

+/*u0*/GRANT r2 TO peon1;

+/*u0*/GRANT r3 TO r12;  -- r12 held by peon3.  Nest r3 into it too.

+/*u0*/GRANT SELECT ON t1 TO peon2;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t2;

+/*e*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

+CONNECT USER peon2 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t2;

+/*c1*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

+CONNECT USER peon3 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t2;

+/*c1*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

+

+-- Access to t3 has been granted only through r3, either directly or

+-- indirectly (the latter through nesting r3 in another role).

+CONNECT USER sa PASSWORD "";

+DROP ROLE r3;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t2;

+/*e*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

+CONNECT USER peon2 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t2;

+/*e*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

+CONNECT USER peon3 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t2;

+/*e*/SELECT * FROM t3;

+/*e*/SELECT * FROM t4;

diff --git a/testrun/hsqldb/TestSelfNameResolution.txt b/testrun/hsqldb/TestSelfNameResolution.txt
new file mode 100644
index 0000000..81eb8e4
--- /dev/null
+++ b/testrun/hsqldb/TestSelfNameResolution.txt
@@ -0,0 +1,107 @@
+drop table t0 if exists;

+create table t0(c varchar(20), i integer);

+insert into t0 values ('first', 1);

+insert into t0 values ('second', 2);

+insert into t0 values ('third', 3);

+select * from t0 order by c;

+select t0.c, t0.i from t0 order by c, t0.i;

+select c as cc from t0 order by cc;

+select c as cc from t0 order by i;

+select upper(c) as uc from t0 t order by uc;

+select i, c from t0 order by upper(c);

+/*c3*/select i, c as cc from t0 order by upper(cc);

+/*e*/select distinct upper(c) as uc from t0 t order by i;

+/*c3*/select c as ccol, sum(i) as sumi from t0 group by c;

+/*c3*/select c as ccol, sum(i) as sumi from t0 group by c order by sumi;

+select c as ccol, sum(i) as sumi from t0 group by ccol;

+/*c1*/select c as ccol, sum(i) as sumi from t0

+ group by c

+ having substring(upper(c) from 1 for 1) = 'S'

+/*c1*/select c || ' time' as ccol, sum(i) as sumi from t0

+ group by c

+ having c || ' time' = 'second time'

+/*c2*/select c as ccol, sum(i) as sumi from t0

+ group by c

+ having avg(i) < 3

+/*c1*/select c as ccol, sum(i) as sumi from t0

+ group by c

+ having substring(upper(c) from 1 for 1) = 'S'

+ and avg(i) < 10 order by c desc

+/*c1*/select c as ccol, sum(i) as sumi from t0

+ group by c

+ having substring(upper(c) from 1 for 1) = 'S'

+ and avg(i) < 10 order by c desc, sumi

+-- bug item #1167704

+drop table test if exists;

+create table test(id integer, cost numeric(3,1));

+insert into test values(1,10);

+insert into test values(2,20);

+insert into test values (3,1);

+insert into test values (4,2);

+/*r

+ 3,kr 1.0

+ 4,kr 2.0

+ 1,kr 10.0

+ 2,kr 20.0

+*/SELECT ID, 'kr ' + Cost FROM Test ORDER BY Cost;

+/*r

+ 3,kr 1.0

+ 4,kr 2.0

+ 1,kr 10.0

+ 2,kr 20.0

+*/SELECT ID, 'kr ' || Cost FROM Test ORDER BY Cost;

+

+DROP TABLE "CD" IF EXISTS CASCADE;

+CREATE CACHED TABLE "CD"("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,"Title" VARCHAR(50));

+CREATE CACHED TABLE "Artist"("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,"Name" VARCHAR(50));

+CREATE CACHED TABLE "Album"("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,"Artist" INTEGER NOT NULL,"Name" VARCHAR(200),"Year" DATE,"CD" INTEGER NOT NULL,CONSTRAINT SYS_FK_42 FOREIGN KEY("CD") REFERENCES "CD"("ID"),CONSTRAINT SYS_FK_52 FOREIGN KEY("Artist") REFERENCES "Artist"("ID") ON DELETE CASCADE);

+CREATE CACHED TABLE "Song"("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,"Album" INTEGER NOT NULL,"Name" VARCHAR(300),"Track" INTEGER,"Duration" TIME,"Genre" VARCHAR(50),CONSTRAINT SYS_FK_55 FOREIGN KEY("Album") REFERENCES "Album"("ID") ON DELETE CASCADE);

+INSERT INTO "CD" VALUES(21,'24');

+INSERT INTO "Artist" VALUES(123,'Annie Lennox');

+INSERT INTO "Album" VALUES(172,123,'Medusa',NULL,21);

+INSERT INTO "Song" VALUES(2669,172,'waiting in vain',9,'00:05:39',NULL);

+

+-- issue with aliases - bug 1344316

+create table test1 (idtest int,test varchar(100),primary key(idtest));

+create table test2 (idtest2 int,idtest int,test varchar(100),primary key(idtest2),foreign key (idtest) REFERENCES test1(idtest));

+INSERT INTO test1 (idtest, test) VALUES (1,'hello');

+INSERT INTO test2 (idtest2,idtest, test) VALUES(2,1,'world');

+/*r

+ hello,2

+*/select t1.test, t2.idtest2 as idtest  from test1 t1 join test2 t2 on (t1.idtest=t2.idtest)

+/*r

+ hello,hello

+*/select t1.test, t1.test as idtest  from test1 t1 JOIN test2 t2 on (t1.idtest=t2.idtest)

+/*r

+ 1,2

+*/select idtest, idtest2 from test2 group by idtest, idtest2 order by idtest

+/*e*/select idtest, idtest2 from test2 group by idtest, idtest2 order by test

+/*e*/select distinct idtest, idtest2 from test2 order by test

+/*r

+ 1

+*/select distinct idtest from test2 group by idtest2, idtest order by idtest

+/*e*/select distinct idtest from test2 group by idtest2, idtest order by idtest2

+-----

+drop table tablea if exists;

+drop table tableb if exists;

+create table tablea (cola int, colb int, colc int);

+create table tableb (cola int, colb int, colc int);

+SELECT T1.colA, T1.colB FROM tableA T1 WHERE T1.colC = (

+ SELECT MAX(T2.colC) FROM tableA T2 WHERE T1.colB = T2.colB);

+SELECT T1.colA, T1.colB FROM tableA T1 WHERE T1.colC IN (

+ SELECT MAX(T2.colC) FROM tableA T2 WHERE T1.colB = T2.colB);

+---

+DROP TABLE TABLEA IF EXISTS;

+CREATE TABLE TABLEA (LIMIT VARCHAR(5), TOP INT);

+INSERT INTO TABLEA(LIMIT, TOP) VALUES ('LIMIT', 2);

+SELECT LIMIT FROM TABLEA;

+SELECT TOP FROM TABLEA;

+SELECT LIMIT TOP FROM TABLEA;

+SELECT TOP LIMIT FROM TABLEA;

+SELECT LIMIT, TOP FROM TABLEA;

+SELECT TOP, LIMIT FROM TABLEA;

+SELECT RIGHT(LIMIT,2) FROM TABLEA;

+SELECT LEFT(LIMIT,2) FROM TABLEA;

+

+

+

diff --git a/testrun/hsqldb/TestSelfNameResolutionSchemas.txt b/testrun/hsqldb/TestSelfNameResolutionSchemas.txt
new file mode 100644
index 0000000..2d51737
--- /dev/null
+++ b/testrun/hsqldb/TestSelfNameResolutionSchemas.txt
@@ -0,0 +1,572 @@
+-- Tests for phase 1 of Schema implementation.

+-- PHASE 1 = on schemas PUBLIC and INFORMATION_SCHEMA; No "SET SCHEMA" cmd;

+--           Can't create INFORMATION_SCHEMA objects from normal Sessions.

+-- (Alter commands tested separately after because there are so many

+--  alter permutations to test)

+--                  ******************************       PHASE 1 Tables

+--DROP TABLE nosuch;

+DROP TABLE t1 IF exists;

+DROP TABLE t2 IF exists;

+DROP TABLE t3 IF exists;

+DROP TABLE t4 IF exists;

+DROP TABLE t5 IF exists;

+DROP TABLE t101 IF exists;

+DROP TABLE j1 IF exists;

+DROP TABLE other.t1 IF exists;

+DROP TABLE other.system_users IF exists;

+DROP TABLE system_users IF exists;

+/*u0*/CREATE TABLE t1 (i int);

+/*u0*/CREATE TABLE public.t2 (i int);

+/*u0*/CREATE TABLE t3 (i int);

+/*u0*/CREATE TABLE j1 (i int, vc varchar(10));

+/*u0*/CREATE CACHED TABLE public.t5 (i int);

+/*e*/CREATE TABLE information_schema.t101 (i int);

+/*e*/CREATE TABLE t1 (i int); -- Create existing object

+/*e*/CREATE TABLE public.t1 (i int); -- Create existing object

+/*e*/CREATE TABLE information_schema.system_users (i int); -- Existing object

+/*u1*/INSERT INTO t1 values(0);

+/*u1*/INSERT INTO t1 values(1);

+/*u1*/INSERT INTO j1 values(1, 'one');

+/*c2*/SELECT * FROM t1;

+/*c1*/SELECT * FROM t1 WHERE i = 0;

+/*c2*/SELECT * FROM t1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM t1 WHERE i < 1;

+/*c1*/SELECT * FROM t1 WHERE t1.i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM t1 WHERE t1.i in (SELECT i FROM j1);

+/*c0*/SELECT * FROM t1 WHERE t1.i = (SELECT i FROM j1 WHERE i = 0);

+/*c1*/SELECT * FROM public.t1 WHERE t1.i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.t1 WHERE t1.i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.t1 WHERE t1.i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM t1 WHERE t1.i = (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM t1 WHERE t1.i in (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM t1 WHERE t1.i = (SELECT i FROM public.j1 WHERE i = 1);

+/*c1*/SELECT * FROM t1 WHERE t1.i = (SELECT j1.i FROM public.j1);

+/*c1*/SELECT * FROM t1 WHERE t1.i in (SELECT j1.i FROM j1);

+/*c1*/SELECT * FROM t1 WHERE t1.i = (SELECT j1.i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM t1 WHERE t1.i = (SELECT i FROM public.j1 WHERE j1.i = 1);

+/*c1*/SELECT * FROM t1 WHERE t1.i = (SELECT j1.i FROM j1 WHERE j1.i = 1);

+/*c1*/SELECT * FROM t1 WHERE i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM t1 WHERE i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM t1 WHERE i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM public.t1 WHERE i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.t1 WHERE i in (SELECT i FROM j1);

+/*c0*/SELECT * FROM public.t1 WHERE i = (SELECT i FROM j1 WHERE i = 0);

+/*c1*/SELECT * FROM t1 WHERE i = (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM t1 WHERE i in (SELECT i FROM public.j1);

+/*c0*/SELECT * FROM t1 WHERE i = (SELECT i FROM public.j1 WHERE i = 0);

+/*c1*/SELECT * FROM t1 WHERE i = (SELECT j1.i FROM public.j1);

+/*c1*/SELECT * FROM t1 WHERE i in (SELECT j1.i FROM j1);

+/*c0*/SELECT * FROM t1 WHERE i = (SELECT j1.i FROM j1 WHERE i = 0);

+/*c1*/SELECT * FROM t1 WHERE i = (SELECT i FROM public.j1 WHERE j1.i = 1);

+/*c1*/SELECT * FROM t1 WHERE i = (SELECT j1.i FROM j1 WHERE j1.i = 1);

+/*e*/SELECT * FROM system_users WHERE user_name = 'SA';

+/*e*/SELECT * FROM other.t1;

+/*e*/SELECT * FROM other.system_users;

+/*e*/SELECT * FROM information_schema.t1;

+/*e*/SELECT * FROM public.system_users;

+/*c2*/SELECT * FROM public.t1;

+/*c1*/SELECT * FROM information_schema.system_users WHERE user_name = 'SA';

+/*c1*/SELECT * FROM public.t1 WHERE i = 0;

+/*e*/SELECT * FROM other.t1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.t1 WHERE i = 0;

+CREATE TABLE public.t4 AS (SELECT * FROM public.t1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM public.t4;

+/*c1*/SELECT * FROM public.t1, public.j1 WHERE t1.i = j1.i;

+/*c1*/SELECT * FROM t1, public.j1 WHERE t1.i = j1.i;

+/*c1*/SELECT * FROM public.t1, j1 WHERE t1.i = j1.i;

+/*c1*/SELECT * FROM t1, j1 WHERE t1.i = j1.i;

+/*c1*/SELECT vc FROM public.t1, public.j1 WHERE t1.i = j1.i;

+/*c1*/SELECT vc FROM t1, public.j1 WHERE t1.i = j1.i;

+/*c1*/SELECT vc FROM public.t1, j1 WHERE t1.i = j1.i;

+/*c1*/SELECT vc FROM t1, j1 WHERE t1.i = j1.i;

+/*c1*/SELECT j1.vc FROM public.t1, public.j1 WHERE t1.i = j1.i;

+/*c1*/SELECT j1.vc FROM t1, public.j1 WHERE t1.i = j1.i;

+/*c1*/SELECT j1.vc FROM public.t1, j1 WHERE t1.i = j1.i;

+/*c1*/SELECT j1.vc FROM t1, j1 WHERE t1.i = j1.i;

+/*c1*/SELECT lbla.vc FROM t1, j1 lbla WHERE t1.i = lbla.i;

+/*c1*/SELECT j1.vc FROM t1 lblb, j1 WHERE lblb.i = j1.i;

+/*c1*/SELECT lbla.vc FROM t1 lblb, j1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM public.t1, j1 lbla WHERE t1.i = lbla.i;

+/*c1*/SELECT j1.vc FROM public.t1 lblb, j1 WHERE lblb.i = j1.i;

+/*c1*/SELECT lbla.vc FROM public.t1 lblb, j1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM t1, public.j1 lbla WHERE t1.i = lbla.i;

+/*c1*/SELECT j1.vc FROM t1 lblb, public.j1 WHERE lblb.i = j1.i;

+/*c1*/SELECT lbla.vc FROM t1 lblb, public.j1 lbla WHERE lblb.i = lbla.i;

+/*u0*/SET TABLE t1 READONLY true;

+/*u0*/SET TABLE public.t1 READONLY true;

+/*e*/SET TABLE information_schema.t1 READONLY true;

+/*e*/SET TABLE other.t1 READONLY true;

+/*u0*/SET TABLE t1 READONLY false;

+/*u0*/SET TABLE public.t1 READONLY false;

+/*u1*/UPDATE t1 set i = 11 WHERE i = 1;

+/*u1*/UPDATE t1 set t1.i = 12 WHERE i = 11;

+/*u1*/UPDATE t1 set t1.i = 13 WHERE t1.i = 12;

+/*u1*/UPDATE public.t1 set i = 14 WHERE i = 13;

+/*u1*/UPDATE public.t1 set t1.i = 15 WHERE i = 14;

+/*u1*/UPDATE public.t1 set t1.i = 16 WHERE t1.i = 15;

+/*e*/UPDATE other.t1 set t1.i = 17 WHERE t1.i = 16;

+/*e*/UPDATE information_schema.t1 set t1.i = 17 WHERE t1.i = 16;

+/*u1*/UPDATE t1 ali set i = 17 WHERE i = 16;

+/*u1*/UPDATE t1 ali set ali.i = 18 WHERE i = 17;

+/*u1*/UPDATE t1 ali set ali.i = 19 WHERE ali.i = 18;

+/*u1*/UPDATE t1 ali set i = 20 WHERE ali.i = 19;

+/*u1*/UPDATE public.t1 ali set i = 21 WHERE i = 20;

+/*u1*/UPDATE public.t1 ali set ali.i = 22 WHERE i = 21;

+/*u1*/UPDATE public.t1 ali set ali.i = 23 WHERE ali.i = 22;

+/*u1*/UPDATE public.t1 ali set i = 24 WHERE ali.i = 23;

+/*e*/UPDATE other.t1 ali set i = 25 WHERE ali.i = 24;

+/*e*/UPDATE other.t1 ali set i = 25 WHERE .i = 24;

+/*e*/UPDATE other.t1 set i = 25 WHERE i = 24;

+/*e*/DELETE FROM other.t1 ali WHERE ali.i = 24;

+/*e*/DELETE FROM other.t1 ali;

+/*e*/DELETE FROM other.t1 set WHERE i = 24;

+CREATE USER otheruser PASSWORD otheruser;

+/*u0*/GRANT ALL ON t1 TO otheruser;

+/*u0*/GRANT ALL ON public.t2 TO otheruser;

+/*e*/GRANT ALL ON other.t3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.t3 TO otheruser;

+/*u0*/REVOKE ALL ON t1 FROM otheruser RESTRICT;

+/*u0*/REVOKE ALL ON public.t2 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON other.t3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.t3 FROM otheruser RESTRICT;

+DROP USER otheruser;

+/*u1*/DELETE FROM t1 WHERE i = 0;

+/*u1*/DELETE FROM public.t1 WHERE i = 24;

+/*u1*/DELETE FROM public.j1 WHERE j1.i = 1;

+/*u0*/DROP TABLE t1;

+/*e*/DROP TABLE t1;

+/*u0*/DROP TABLE t2;

+/*e*/DROP TABLE other.t3;

+/*u0*/DROP TABLE public.t3;

+/*e*/DROP TABLE information_schema.t4;

+/*u0*/DROP TABLE t4;

+/*u0*/DROP TABLE t5;

+/*u0*/DROP TABLE j1;

+/*e*/DROP TABLE t101;

+/*e*/DROP TABLE public.t101;

+--                  ******************************       PHASE 1 Views

+DROP VIEW v1 IF exists;

+DROP VIEW v2 IF exists;

+DROP VIEW v3 IF exists;

+DROP VIEW v4 IF exists;

+DROP VIEW v5 IF exists;

+DROP VIEW v6 IF exists;

+DROP VIEW v7 IF exists;

+DROP VIEW v8 IF exists;

+DROP VIEW v9 IF exists;

+DROP VIEW v10 IF exists;

+DROP VIEW v11 IF exists;

+DROP VIEW v12 IF exists;

+DROP VIEW v13 IF exists;

+DROP VIEW v14 IF exists;

+DROP VIEW v15 IF exists;

+DROP VIEW v16 IF exists;

+DROP VIEW v17 IF exists;

+DROP VIEW v18 IF exists;

+DROP VIEW v19 IF exists;

+DROP VIEW v20 IF exists;

+DROP VIEW v21 IF exists;

+DROP VIEW v22 IF exists;

+DROP VIEW v23 IF exists;

+DROP VIEW v24 IF exists;

+DROP VIEW v25 IF exists;

+DROP VIEW v26 IF exists;

+DROP VIEW v101 IF exists;

+DROP TABLE t1 IF exists;

+DROP TABLE t2 IF exists;

+DROP TABLE j1 IF exists;

+CREATE TABLE t1 (i int);

+CREATE TABLE j1 (i int, vc varchar(10));

+INSERT INTO t1 values(0);

+INSERT INTO t1 values(1);

+INSERT INTO j1 values(1, 'one');

+/*e*/CREATE VIEW information_schema.v101 AS

+    SELECT * FROM information_schema.system_users;

+/*e*/CREATE VIEW information_schema.v101 AS

+    SELECT * FROM t1;

+/*e*/CREATE VIEW information_schema.v4 AS

+    SELECT * FROM public.t1;

+/*e*/CREATE VIEW v101 AS SELECT * FROM other.t1;

+/*e*/CREATE VIEW public.v101 AS SELECT * FROM other.t1;

+/*e*/CREATE VIEW other.v101 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW other.v101 AS SELECT *

+    FROM information_schema.system_users, public.j1 WHERE user_name = vc;

+/*e*/CREATE VIEW other.v101 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE information_schema.user_name = vc;

+/*e*/CREATE VIEW other.v101 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE information_schema.user_name = public.vc;

+/*e*/CREATE VIEW information_schema.v101 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW information_schema.v101 AS SELECT *

+    FROM information_schema.system_users, public.j1 WHERE user_name = vc;

+/*e*/CREATE VIEW information_schema.v101 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE information_schema.user_name = vc;

+/*e*/CREATE VIEW information_schema.v101 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE information_schema.user_name = public.vc;

+/*e*/CREATE VIEW v101 AS SELECT *

+    FROM system_users, j1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW v101 AS SELECT *

+    FROM information_schema.system_users, information_schema.j1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW v101 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE other.user_name = vc;

+/*e*/CREATE VIEW v101 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE public.user_name = public.vc;

+/*u0*/CREATE VIEW v1 AS SELECT * FROM t1;

+/*e*/CREATE VIEW public.v1 AS SELECT * FROM t1; -- Create existing object

+/*e*/CREATE VIEW public.v1 AS SELECT * FROM public.t1; -- Existing object

+/*u0*/CREATE VIEW public.v2 AS SELECT * FROM t1;

+/*u0*/CREATE VIEW public.v3 AS SELECT * FROM public.t1;

+/*u0*/CREATE VIEW public.v4 AS SELECT * FROM t1 WHERE i = 0;

+/*u0*/CREATE VIEW public.v5 AS SELECT * FROM t1 WHERE i < 1;

+/*u0*/CREATE VIEW public.v6 AS SELECT * FROM information_schema.system_users

+    WHERE user_name = 'SA';

+/*u0*/CREATE VIEW v7 AS SELECT * FROM information_schema.system_users;

+/*u0*/CREATE VIEW v8 AS SELECT * FROM information_schema.system_users

+    WHERE user_name = 'SA';

+/*u0*/CREATE VIEW v9 AS SELECT * FROM information_schema.system_users, j1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW v10 AS SELECT *

+    FROM information_schema.system_users, public.j1 WHERE user_name = vc;

+/*u0*/CREATE VIEW v11 AS SELECT * FROM information_schema.system_users, j1

+    WHERE system_users.user_name = vc;

+/*e*/CREATE VIEW v12 AS SELECT * FROM information_schema.system_users, j1

+    WHERE system_users.user_name = public.vc;

+/*u0*/CREATE VIEW public.v13 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW public.v14 AS SELECT *

+    FROM information_schema.system_users, public.j1 WHERE user_name = vc;

+/*e*/CREATE VIEW public.v15 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE information_schema.user_name = vc;

+/*e*/CREATE VIEW public.v16 AS SELECT *

+    FROM information_schema.system_users, j1

+    WHERE information_schema.user_name = public.vc;

+/*u0*/CREATE VIEW v17 AS SELECT * FROM information_schema.system_users, j1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW v18 AS SELECT *

+    FROM information_schema.system_users, public.j1 WHERE user_name = vc;

+/*u0*/CREATE VIEW v19 (v1, v2, v3) AS SELECT * FROM t1, j1 WHERE t1.i = j1.i;

+/*u0*/CREATE VIEW v20 (v1, v2, v3) AS SELECT * FROM public.t1, public.j1 WHERE t1.i = j1.i;

+/*u0*/CREATE VIEW v21 (v1, v2, v3) AS SELECT * FROM public.t1, j1 WHERE t1.i = j1.i;

+/*u0*/CREATE VIEW v22 (v1, v2, v3) AS SELECT * FROM t1, public.j1 WHERE t1.i = j1.i;

+/*u0*/CREATE VIEW public.v23 (v1, v2, v3) AS

+    SELECT * FROM t1, j1 WHERE t1.i = j1.i;

+/*u0*/CREATE VIEW public.v24 (v1, v2, v3) AS

+    SELECT * FROM public.t1, public.j1 WHERE t1.i = j1.i;

+/*u0*/CREATE VIEW public.v25 (v1, v2, v3) AS SELECT * FROM public.t1, j1 WHERE t1.i = j1.i;

+/*u0*/CREATE VIEW public.v26 (v1, v2, v3) AS SELECT * FROM t1, public.j1 WHERE t1.i = j1.i;

+/*u0*/CREATE VIEW v28 AS

+    SELECT * FROM t1 WHERE i in (0, 1, 11, 12);

+/*u0*/CREATE VIEW public.v29 AS

+    SELECT * FROM t1 WHERE i < 1;

+/*u0*/CREATE VIEW v30 AS

+    SELECT * FROM t1 WHERE t1.i = (SELECT i FROM j1);

+/*u0*/CREATE VIEW v31 AS

+    SELECT * FROM t1 WHERE t1.i in (SELECT i FROM j1);

+/*u0*/CREATE VIEW v32 AS

+    SELECT * FROM t1 WHERE t1.i = (SELECT i FROM j1 WHERE i = 0);

+/*u0*/CREATE VIEW v33 AS

+    SELECT * FROM public.t1 WHERE t1.i = (SELECT i FROM j1);

+/*u0*/CREATE VIEW PUBLIC.v34 AS

+    SELECT * FROM public.t1 WHERE t1.i in (SELECT i FROM j1);

+/*u0*/CREATE VIEW PUBLIC.v35 AS

+    SELECT * FROM public.t1 WHERE t1.i = (SELECT i FROM j1 WHERE i = 0);

+/*u0*/CREATE VIEW PUBLIC.v36 AS

+    SELECT * FROM t1 WHERE t1.i = (SELECT i FROM public.j1);

+/*u0*/CREATE VIEW PUBLIC.v37 AS

+    SELECT * FROM t1 WHERE t1.i in (SELECT i FROM public.j1);

+/*u0*/CREATE VIEW PUBLIC.v38 AS

+    SELECT * FROM t1 WHERE t1.i = (SELECT i FROM public.j1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.v39 AS

+    SELECT * FROM t1 WHERE t1.i = (SELECT j1.i FROM public.j1);

+/*u0*/CREATE VIEW PUBLIC.v40 AS

+    SELECT * FROM t1 WHERE t1.i in (SELECT j1.i FROM j1);

+/*u0*/CREATE VIEW PUBLIC.v41 AS

+    SELECT * FROM t1 WHERE t1.i = (SELECT j1.i FROM j1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.v42 AS

+    SELECT * FROM t1 WHERE t1.i = (SELECT i FROM public.j1 WHERE j1.i = 1);

+/*u0*/CREATE VIEW PUBLIC.v43 AS

+    SELECT * FROM t1 WHERE t1.i = (SELECT j1.i FROM j1 WHERE j1.i = 1);

+/*u0*/CREATE VIEW PUBLIC.v44 AS

+    SELECT * FROM t1 WHERE i = (SELECT i FROM j1);

+/*u0*/CREATE VIEW PUBLIC.v45 AS

+    SELECT * FROM t1 WHERE i in (SELECT i FROM j1);

+/*u0*/CREATE VIEW PUBLIC.v46 AS

+    SELECT * FROM t1 WHERE i = (SELECT i FROM j1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.v47 AS

+    SELECT * FROM public.t1 WHERE i = (SELECT i FROM j1);

+/*u0*/CREATE VIEW PUBLIC.v48 AS

+    SELECT * FROM public.t1 WHERE i in (SELECT i FROM j1);

+/*u0*/CREATE VIEW PUBLIC.v49 AS

+    SELECT * FROM public.t1 WHERE i = (SELECT i FROM j1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.v50 AS

+    SELECT * FROM t1 WHERE i = (SELECT i FROM public.j1);

+/*u0*/CREATE VIEW PUBLIC.v51 AS

+    SELECT * FROM t1 WHERE i in (SELECT i FROM public.j1);

+/*u0*/CREATE VIEW PUBLIC.v52 AS

+    SELECT * FROM t1 WHERE i = (SELECT i FROM public.j1 WHERE i = 0);

+/*u0*/CREATE VIEW PUBLIC.v53 AS

+    SELECT * FROM t1 WHERE i = (SELECT j1.i FROM public.j1);

+/*u0*/CREATE VIEW PUBLIC.v54 AS

+    SELECT * FROM t1 WHERE i in (SELECT j1.i FROM j1);

+/*u0*/CREATE VIEW PUBLIC.v55 AS

+    SELECT * FROM t1 WHERE i = (SELECT j1.i FROM j1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.v56 AS

+    SELECT * FROM t1 WHERE i = (SELECT i FROM public.j1 WHERE j1.i = 1);

+/*u0*/CREATE VIEW PUBLIC.v57 AS

+    SELECT * FROM t1 WHERE i = (SELECT j1.i FROM j1 WHERE j1.i = 1);

+/*c2*/SELECT * FROM v1;

+/*c2*/SELECT * FROM public.v1;

+/*c2*/SELECT * FROM v2;

+/*c2*/SELECT * FROM v3;

+/*c1*/SELECT * FROM v4;

+/*c1*/SELECT * FROM v5;

+/*c1*/SELECT * FROM v8;

+/*c0*/SELECT * FROM v9;

+/*c0*/SELECT * FROM v10;

+/*c0*/SELECT * FROM v11;

+/*e*/SELECT * FROM v12;

+/*c0*/SELECT * FROM v13;

+/*c0*/SELECT * FROM v14;

+/*e*/SELECT * FROM v15;

+/*e*/SELECT * FROM v16;

+/*c0*/SELECT * FROM v17;

+/*c0*/SELECT * FROM v18;

+/*c1*/SELECT * FROM v19;

+/*c1*/SELECT * FROM v20;

+/*c1*/SELECT * FROM v21;

+/*c1*/SELECT * FROM v22;

+/*c1*/SELECT * FROM v23;

+/*c1*/SELECT * FROM v24;

+/*c1*/SELECT * FROM v25;

+/*c1*/SELECT * FROM v26;

+/*c2*/SELECT * FROM v28;

+/*c1*/SELECT * FROM v29;

+/*c1*/SELECT * FROM v30;

+/*c1*/SELECT * FROM v31;

+/*c0*/SELECT * FROM v32;

+/*c1*/SELECT * FROM v33;

+/*c1*/SELECT * FROM v34;

+/*c0*/SELECT * FROM v35;

+/*c1*/SELECT * FROM v36;

+/*c1*/SELECT * FROM v37;

+/*c1*/SELECT * FROM v38;

+/*c1*/SELECT * FROM v39;

+/*c1*/SELECT * FROM v40;

+/*c1*/SELECT * FROM v41;

+/*c1*/SELECT * FROM v42;

+/*c1*/SELECT * FROM v43;

+/*c1*/SELECT * FROM v44;

+/*c1*/SELECT * FROM v45;

+/*c1*/SELECT * FROM v46;

+/*c1*/SELECT * FROM v47;

+/*c1*/SELECT * FROM v48;

+/*c1*/SELECT * FROM v49;

+/*c1*/SELECT * FROM v50;

+/*c1*/SELECT * FROM v51;

+/*c0*/SELECT * FROM v52;

+/*c1*/SELECT * FROM v53;

+/*c1*/SELECT * FROM v54;

+/*c1*/SELECT * FROM v55;

+/*c1*/SELECT * FROM v56;

+/*c1*/SELECT * FROM v57;

+/*c1*/SELECT * FROM v1, j1 WHERE v1.i = j1.i;

+/*c1*/SELECT * FROM public.v1, public.j1 WHERE v1.i = j1.i;

+/*c2*/SELECT * FROM v1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM v1 WHERE i < 1;

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM public.v1 WHERE v1.i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.v1 WHERE v1.i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i in (SELECT i FROM public.j1);

+/*c0*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM public.j1 WHERE i = 0);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT j1.i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i in (SELECT j1.i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT j1.i FROM j1 WHERE i = 1);

+/*c0*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM public.j1 WHERE j1.i = 0);

+/*c0*/SELECT * FROM v1 WHERE v1.i = (SELECT j1.i FROM j1 WHERE j1.i = 0);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM public.v1 WHERE i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.v1 WHERE i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.v1 WHERE i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE i in (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM public.j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT j1.i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE i in (SELECT j1.i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT j1.i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM public.j1 WHERE j1.i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT j1.i FROM j1 WHERE j1.i = 1);

+/*c2*/SELECT * FROM v1;

+/*c1*/SELECT * FROM v1 WHERE i = 0;

+/*c2*/SELECT * FROM v1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM v1 WHERE i < 1;

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM public.v1 WHERE v1.i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.v1 WHERE v1.i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.v1 WHERE v1.i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i in (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM public.j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT j1.i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i in (SELECT j1.i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT j1.i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT i FROM public.j1 WHERE j1.i = 1);

+/*c1*/SELECT * FROM v1 WHERE v1.i = (SELECT j1.i FROM j1 WHERE j1.i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM public.v1 WHERE i = (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.v1 WHERE i in (SELECT i FROM j1);

+/*c1*/SELECT * FROM public.v1 WHERE i = (SELECT i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE i in (SELECT i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM public.j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT j1.i FROM public.j1);

+/*c1*/SELECT * FROM v1 WHERE i in (SELECT j1.i FROM j1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT j1.i FROM j1 WHERE i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT i FROM public.j1 WHERE j1.i = 1);

+/*c1*/SELECT * FROM v1 WHERE i = (SELECT j1.i FROM j1 WHERE j1.i = 1);

+/*e*/SELECT * FROM other.v1;

+/*e*/SELECT * FROM information_schema.v1;

+/*c2*/SELECT * FROM public.v1;

+/*c1*/SELECT * FROM public.v1 WHERE i = 0;

+/*e*/SELECT * FROM other.v1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.v1 WHERE i = 0;

+CREATE TABLE public.t2 AS (SELECT * FROM public.V1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM public.t2;

+/*c1*/SELECT * FROM public.v1, public.j1 WHERE v1.i = j1.i;

+/*c1*/SELECT * FROM v1, public.j1 WHERE v1.i = j1.i;

+/*c1*/SELECT * FROM public.v1, j1 WHERE v1.i = j1.i;

+/*c1*/SELECT * FROM v1, j1 WHERE v1.i = j1.i;

+/*c1*/SELECT vc FROM public.v1, public.j1 WHERE v1.i = j1.i;

+/*c1*/SELECT vc FROM v1, public.j1 WHERE v1.i = j1.i;

+/*c1*/SELECT vc FROM public.v1, j1 WHERE v1.i = j1.i;

+/*c1*/SELECT vc FROM v1, j1 WHERE v1.i = j1.i;

+/*c1*/SELECT j1.vc FROM public.v1, public.j1 WHERE v1.i = j1.i;

+/*c1*/SELECT j1.vc FROM v1, public.j1 WHERE v1.i = j1.i;

+/*c1*/SELECT j1.vc FROM public.v1, j1 WHERE v1.i = j1.i;

+/*c1*/SELECT j1.vc FROM v1, j1 WHERE v1.i = j1.i;

+/*c1*/SELECT lbla.vc FROM v1, j1 lbla WHERE v1.i = lbla.i;

+/*c1*/SELECT j1.vc FROM v1 lblb, j1 WHERE lblb.i = j1.i;

+/*c1*/SELECT lbla.vc FROM v1 lblb, j1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM public.v1, j1 lbla WHERE v1.i = lbla.i;

+/*c1*/SELECT j1.vc FROM public.v1 lblb, j1 WHERE lblb.i = j1.i;

+/*c1*/SELECT lbla.vc FROM public.v1 lblb, j1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM v1, public.j1 lbla WHERE v1.i = lbla.i;

+/*c1*/SELECT j1.vc FROM v1 lblb, public.j1 WHERE lblb.i = j1.i;

+/*c1*/SELECT lbla.vc FROM v1 lblb, public.j1 lbla WHERE lblb.i = lbla.i;

+CREATE USER otheruser PASSWORD otheruser;

+/*u0*/GRANT ALL ON v1 TO otheruser;

+/*u0*/GRANT ALL ON public.v2 TO otheruser;

+/*e*/GRANT ALL ON other.v3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.v3 TO otheruser;

+/*u0*/REVOKE ALL ON v1 FROM otheruser RESTRICT;

+/*u0*/REVOKE ALL ON public.v2 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON other.v3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.v3 FROM otheruser RESTRICT;

+DROP USER otheruser;

+/*e*/DROP VIEW other.v1;

+/*u0*/DROP VIEW public.v1;

+/*e*/DROP VIEW information_schema.v2;

+/*u0*/DROP VIEW v2;

+/*e*/DROP VIEW v2;

+/*u0*/DROP VIEW v3;

+/*u0*/DROP VIEW v4;

+/*u0*/DROP VIEW v5;

+/*u0*/DROP VIEW v6;

+/*u0*/DROP VIEW v7;

+/*u0*/DROP VIEW v8;

+/*u0*/DROP VIEW v9;

+/*u0*/DROP VIEW v10;

+/*u0*/DROP VIEW v11;

+/*u0*/DROP VIEW v13;

+/*u0*/DROP VIEW v14;

+/*u0*/DROP VIEW v17;

+/*u0*/DROP VIEW v18;

+/*u0*/DROP VIEW v19;

+/*u0*/DROP VIEW v20;

+/*u0*/DROP VIEW v21;

+/*u0*/DROP VIEW v22;

+/*u0*/DROP VIEW v23;

+/*u0*/DROP VIEW v24;

+/*u0*/DROP VIEW v25;

+/*u0*/DROP VIEW v26;

+/*u0*/DROP VIEW v28;

+/*u0*/DROP VIEW v29;

+/*u0*/DROP VIEW v30;

+/*u0*/DROP VIEW v31;

+/*u0*/DROP VIEW v32;

+/*u0*/DROP VIEW v33;

+/*u0*/DROP VIEW v34;

+/*u0*/DROP VIEW v35;

+/*u0*/DROP VIEW v36;

+/*u0*/DROP VIEW v37;

+/*u0*/DROP VIEW v38;

+/*u0*/DROP VIEW v39;

+/*u0*/DROP VIEW v40;

+/*u0*/DROP VIEW v41;

+/*u0*/DROP VIEW v42;

+/*u0*/DROP VIEW v43;

+/*u0*/DROP VIEW v44;

+/*u0*/DROP VIEW v45;

+/*u0*/DROP VIEW v46;

+/*u0*/DROP VIEW v47;

+/*u0*/DROP VIEW v48;

+/*u0*/DROP VIEW v49;

+/*u0*/DROP VIEW v50;

+/*u0*/DROP VIEW v51;

+/*u0*/DROP VIEW v52;

+/*u0*/DROP VIEW v53;

+/*u0*/DROP VIEW v54;

+/*u0*/DROP VIEW v55;

+/*u0*/DROP VIEW v56;

+/*u0*/DROP VIEW v57;

+DROP TABLE t1;

+DROP TABLE t2;

+DROP TABLE j1;

+--                  ******************************       PHASE 1 Indexes

+drop view v1 if exists;

+drop view v2 if exists;

+drop table t1 if exists;

+drop table t3 if exists;

+drop table t4 if exists;

+/*u0*/CREATE TABLE t1 (i int);

+/*u0*/CREATE TABLE t3 (i int);

+/*u0*/CREATE TABLE t4 (i int);

+/*u0*/CREATE UNIQUE INDEX i1 ON t1(i);

+/*u0*/CREATE UNIQUE INDEX public.i2 on t3(i);

+/*e*/CREATE UNIQUE INDEX other.i3 on t4(i);

+/*e*/CREATE UNIQUE INDEX information_schema.i3 on t4(i int);

+/*e*/DROP INDEX other.i1;

+/*u0*/DROP INDEX public.i1;

+/*e*/DROP INDEX information_schema.i2;

+/*u0*/DROP INDEX i2;

+

+-- Objects created from Sessions are created as public.object for Phase 1

+/*e*/CREATE TABLE other.t2 (i int);  SHOULD FAIL since no such schema

+-- Create the schema "other"

+-- /*u0*/CREATE TABLE other.t2 (i int);

+-- /*u1*/INSERT INTO t2 values(0);

+-- /*u1*/INSERT INTO t2 values(0);

+-- /*e*/SELECT * FROM wrong.t2;

+-- /*c1*/SELECT * FROM other.t2;

+-- /*c2*/SELECT * FROM other.t1;  SHOULD FAIL since we created public.t1

diff --git a/testrun/hsqldb/TestSelfNoDmlBug1.txt b/testrun/hsqldb/TestSelfNoDmlBug1.txt
new file mode 100644
index 0000000..09f0396
--- /dev/null
+++ b/testrun/hsqldb/TestSelfNoDmlBug1.txt
@@ -0,0 +1,12 @@
+-- Tests a bug where with write_delay of 0, DML is not persisted until and

+-- if DML is committed or DB is "shutdown".  If DB stops with no shutdown,

+-- all work is lost.

+

+--/*u0*/SET write_delay 0;

+/*u0*/CREATE SCHEMA ghostSchema AUTHORIZATION dba;

+/*u0*/SET SCHEMA ghostSchema;

+/*u0*/CREATE TABLE t1(i int);

+/*u0*/CREATE VIEW v1 AS SELECT * FROM t1;

+/*c0*/SELECT * FROM v1;

+/*c0*/SELECT * FROM t1;

+/*u0*/COMMIT;

diff --git a/testrun/hsqldb/TestSelfNoDmlBug2.txt b/testrun/hsqldb/TestSelfNoDmlBug2.txt
new file mode 100644
index 0000000..0a35d8d
--- /dev/null
+++ b/testrun/hsqldb/TestSelfNoDmlBug2.txt
@@ -0,0 +1,12 @@
+-- Tests a bug where with write_delay of 0, DML is not persisted until and 

+-- if DML is committed or DB is "shutdown".  If DB stops with no shutdown,

+-- all work is lost.

+

+/*u0*/SET SCHEMA ghostSchema;

+

+/*s*/DROP SCHEMA ghostSchema CASCADE;

+

+-- N.b. this test is unable to exhibit the problem because

+-- (a) It doesn't show when data is being written to the .log file; and

+-- (b) The test runner does a shutdown of some sort.  To reproduce 

+--     problem manually, just Ctrl-C out of the session.

diff --git a/testrun/hsqldb/TestSelfNot.txt b/testrun/hsqldb/TestSelfNot.txt
new file mode 100644
index 0000000..c9e9a4a
--- /dev/null
+++ b/testrun/hsqldb/TestSelfNot.txt
@@ -0,0 +1,985 @@
+--

+-- --------------------------------------------------------------------

+-- Checking compliance of type INTEGER

+drop table SQLUNKNOWNCOMPLIANCECHECK if exists

+create table SQLUNKNOWNCOMPLIANCECHECK(a INTEGER, b INTEGER)

+-- Checking v = NULL

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a = b

+--

+-- Checking NOT v = NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a = b

+--

+-- Checking v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <> b

+--

+-- Checking NOT v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <> b

+--

+-- Checking v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b

+--

+-- Checking NOT v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a < b

+--

+-- Checking v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <= b

+--

+-- Checking NOT v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <= b

+--

+-- Checking v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a > b

+--

+-- Checking NOT v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a > b

+--

+-- Checking v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a >= b

+--

+-- Checking NOT v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a >= b

+--

+-- Checking BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b between 1 and 2

+--

+-- Checking NOT BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b between 1 and 2

+--

+-- Checking IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b in (1, 2)

+--

+-- Checking NOT IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b in (1, 2)

+--

+-- Checking T && T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2, 1)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 1

+--

+-- Checking T && F = F

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2, 1)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking T && U = U

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 1)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a and a < b

+--

+-- Checking T || T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2, 1)

+/*c2*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or a > b

+--

+-- Checking T || F = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2, 1)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking T || U = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 1)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a or a < b

+--

+-- Checking BETWEEN: >= and <=

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where (a between 1 and 2) or (b between 1 and 2)

+--

+--

+-- --------------------------------------------------------------------

+-- Checking compliance of type SMALLINT

+drop table SQLUNKNOWNCOMPLIANCECHECK if exists

+create table SQLUNKNOWNCOMPLIANCECHECK(a SMALLINT, b SMALLINT)

+-- Checking v = NULL

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a = b

+--

+-- Checking NOT v = NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a = b

+--

+-- Checking v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <> b

+--

+-- Checking NOT v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <> b

+--

+-- Checking v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b

+--

+-- Checking NOT v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a < b

+--

+-- Checking v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <= b

+--

+-- Checking NOT v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <= b

+--

+-- Checking v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a > b

+--

+-- Checking NOT v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a > b

+--

+-- Checking v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a >= b

+--

+-- Checking NOT v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a >= b

+--

+-- Checking BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b between 1 and 2

+--

+-- Checking NOT BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b between 1 and 2

+--

+-- Checking IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b in (1, 2)

+--

+-- Checking NOT IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b in (1, 2)

+--

+-- Checking T && T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2, 1)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 1

+--

+-- Checking T && F = F

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2, 1)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking T && U = U

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 1)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a and a < b

+--

+-- Checking T || T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2, 1)

+/*c2*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or a > b

+--

+-- Checking T || F = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2, 1)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking T || U = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 1)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a or a < b

+--

+-- Checking BETWEEN: >= and <=

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1, 2)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where (a between 1 and 2) or (b between 1 and 2)

+--

+--

+-- --------------------------------------------------------------------

+-- Checking compliance of type FLOAT

+drop table SQLUNKNOWNCOMPLIANCECHECK if exists

+create table SQLUNKNOWNCOMPLIANCECHECK(a FLOAT, b FLOAT)

+-- Checking v = NULL

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a = b

+--

+-- Checking NOT v = NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a = b

+--

+-- Checking v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <> b

+--

+-- Checking NOT v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <> b

+--

+-- Checking v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b

+--

+-- Checking NOT v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a < b

+--

+-- Checking v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <= b

+--

+-- Checking NOT v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <= b

+--

+-- Checking v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a > b

+--

+-- Checking NOT v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a > b

+--

+-- Checking v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a >= b

+--

+-- Checking NOT v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a >= b

+--

+-- Checking BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b between 1.0 and 2.0

+--

+-- Checking NOT BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b between 1.0 and 2.0

+--

+-- Checking IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b in (1.0, 2.0)

+--

+-- Checking NOT IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b in (1.0, 2.0)

+--

+-- Checking T && T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, 2.0)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2.0, 1.0)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 1

+--

+-- Checking T && F = F

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, 2.0)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2.0, 1.0)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking T && U = U

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, 1.0)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a and a < b

+--

+-- Checking T || T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, 2.0)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2.0, 1.0)

+/*c2*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or a > b

+--

+-- Checking T || F = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, 2.0)

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (2.0, 1.0)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking T || U = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, NULL)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, 1.0)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a or a < b

+--

+-- Checking BETWEEN: >= and <=

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values (1.0, 2.0)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where (a between 1.0 and 2.0) or (b between 1.0 and 2.0)

+--

+--

+-- --------------------------------------------------------------------

+-- Checking compliance of type DATE

+drop table SQLUNKNOWNCOMPLIANCECHECK if exists

+create table SQLUNKNOWNCOMPLIANCECHECK(a DATE, b DATE)

+-- Checking v = NULL

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a = b

+--

+-- Checking NOT v = NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a = b

+--

+-- Checking v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <> b

+--

+-- Checking NOT v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <> b

+--

+-- Checking v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b

+--

+-- Checking NOT v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a < b

+--

+-- Checking v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <= b

+--

+-- Checking NOT v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <= b

+--

+-- Checking v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a > b

+--

+-- Checking NOT v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a > b

+--

+-- Checking v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a >= b

+--

+-- Checking NOT v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a >= b

+--

+-- Checking BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b between '2003-10-20' and '2005-05-06'

+--

+-- Checking NOT BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b between '2003-10-20' and '2005-05-06'

+--

+-- Checking IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b in (DATE'2003-10-20', DATE'2005-05-06')

+--

+-- Checking NOT IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b in (DATE'2003-10-20', DATE'2005-05-06')

+--

+-- Checking T && T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', '2005-05-06')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2005-05-06', '2003-10-20')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 1

+--

+-- Checking T && F = F

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', '2005-05-06')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2005-05-06', '2003-10-20')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking T && U = U

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', '2003-10-20')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a and a < b

+--

+-- Checking T || T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', '2005-05-06')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2005-05-06', '2003-10-20')

+/*c2*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or a > b

+--

+-- Checking T || F = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', '2005-05-06')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2005-05-06', '2003-10-20')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking T || U = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', NULL)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', '2003-10-20')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a or a < b

+--

+-- Checking BETWEEN: >= and <=

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2003-10-20', '2005-05-06')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where (a between '2003-10-20' and '2005-05-06') or (b between '2003-10-20' and '2005-05-06')

+--

+--

+-- --------------------------------------------------------------------

+-- Checking compliance of type TIME

+drop table SQLUNKNOWNCOMPLIANCECHECK if exists

+create table SQLUNKNOWNCOMPLIANCECHECK(a TIME, b TIME)

+-- Checking v = NULL

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a = b

+--

+-- Checking NOT v = NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a = b

+--

+-- Checking v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <> b

+--

+-- Checking NOT v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <> b

+--

+-- Checking v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b

+--

+-- Checking NOT v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a < b

+--

+-- Checking v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <= b

+--

+-- Checking NOT v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <= b

+--

+-- Checking v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a > b

+--

+-- Checking NOT v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a > b

+--

+-- Checking v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a >= b

+--

+-- Checking NOT v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a >= b

+--

+-- Checking BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b between '10:00:00' and '12:32:36'

+--

+-- Checking NOT BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b between '10:00:00' and '12:32:36'

+--

+-- Checking IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b in (TIME'10:00:00', TIME'12:32:36')

+--

+-- Checking NOT IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b in (TIME'10:00:00', TIME'12:32:36')

+--

+-- Checking T && T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', '12:32:36')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('12:32:36', '10:00:00')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 1

+--

+-- Checking T && F = F

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', '12:32:36')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('12:32:36', '10:00:00')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking T && U = U

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', '10:00:00')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a and a < b

+--

+-- Checking T || T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', '12:32:36')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('12:32:36', '10:00:00')

+/*c2*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or a > b

+--

+-- Checking T || F = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', '12:32:36')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('12:32:36', '10:00:00')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking T || U = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', NULL)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', '10:00:00')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a or a < b

+--

+-- Checking BETWEEN: >= and <=

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('10:00:00', '12:32:36')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where (a between '10:00:00' and '12:32:36') or (b between '10:00:00' and '12:32:36')

+--

+--

+-- --------------------------------------------------------------------

+-- Checking compliance of type TIMESTAMP

+drop table SQLUNKNOWNCOMPLIANCECHECK if exists

+create table SQLUNKNOWNCOMPLIANCECHECK(a TIMESTAMP, b TIMESTAMP)

+-- Checking v = NULL

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a = b

+--

+-- Checking NOT v = NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a = b

+--

+-- Checking v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <> b

+--

+-- Checking NOT v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <> b

+--

+-- Checking v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b

+--

+-- Checking NOT v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a < b

+--

+-- Checking v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <= b

+--

+-- Checking NOT v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <= b

+--

+-- Checking v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a > b

+--

+-- Checking NOT v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a > b

+--

+-- Checking v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a >= b

+--

+-- Checking NOT v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a >= b

+--

+-- Checking BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b between '2004-05-06 12:32:36.491' and '2005-05-06 12:32:36.491'

+--

+-- Checking NOT BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b between '2004-05-06 12:32:36.491' and '2005-05-06 12:32:36.491'

+--

+-- Checking IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b in (TIMESTAMP'2004-05-06 12:32:36.491', TIMESTAMP'2005-05-06 12:32:36.491')

+--

+-- Checking NOT IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b in (TIMESTAMP'2004-05-06 12:32:36.491', TIMESTAMP'2005-05-06 12:32:36.491')

+--

+-- Checking T && T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', '2005-05-06 12:32:36.491')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2005-05-06 12:32:36.491', '2004-05-06 12:32:36.491')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 1

+--

+-- Checking T && F = F

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', '2005-05-06 12:32:36.491')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2005-05-06 12:32:36.491', '2004-05-06 12:32:36.491')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking T && U = U

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', '2004-05-06 12:32:36.491')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a and a < b

+--

+-- Checking T || T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', '2005-05-06 12:32:36.491')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2005-05-06 12:32:36.491', '2004-05-06 12:32:36.491')

+/*c2*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or a > b

+--

+-- Checking T || F = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', '2005-05-06 12:32:36.491')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2005-05-06 12:32:36.491', '2004-05-06 12:32:36.491')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking T || U = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', NULL)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', '2004-05-06 12:32:36.491')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a or a < b

+--

+-- Checking BETWEEN: >= and <=

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('2004-05-06 12:32:36.491', '2005-05-06 12:32:36.491')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where (a between '2004-05-06 12:32:36.491' and '2005-05-06 12:32:36.491') or (b between '2004-05-06 12:32:36.491' and '2005-05-06 12:32:36.491')

+--

+--

+-- --------------------------------------------------------------------

+-- Checking compliance of type CHAR(1)

+drop table SQLUNKNOWNCOMPLIANCECHECK if exists

+create table SQLUNKNOWNCOMPLIANCECHECK(a CHAR(1), b CHAR(1))

+-- Checking v = NULL

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a = b

+--

+-- Checking NOT v = NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a = b

+--

+-- Checking v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <> b

+--

+-- Checking NOT v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <> b

+--

+-- Checking v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b

+--

+-- Checking NOT v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a < b

+--

+-- Checking v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <= b

+--

+-- Checking NOT v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <= b

+--

+-- Checking v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a > b

+--

+-- Checking NOT v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a > b

+--

+-- Checking v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a >= b

+--

+-- Checking NOT v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a >= b

+--

+-- Checking BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b between 'a' and 'b'

+--

+-- Checking NOT BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b between 'a' and 'b'

+--

+-- Checking IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b in ('a', 'b')

+--

+-- Checking NOT IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b in ('a', 'b')

+--

+-- Checking T && T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('b', 'a')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 1

+--

+-- Checking T && F = F

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('b', 'a')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking T && U = U

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'a')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a and a < b

+--

+-- Checking T || T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('b', 'a')

+/*c2*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or a > b

+--

+-- Checking T || F = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('b', 'a')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking T || U = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'a')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a or a < b

+--

+-- Checking BETWEEN: >= and <=

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where (a between 'a' and 'b') or (b between 'a' and 'b')

+--

+--

+-- --------------------------------------------------------------------

+-- Checking compliance of type VARCHAR(1)

+drop table SQLUNKNOWNCOMPLIANCECHECK if exists

+create table SQLUNKNOWNCOMPLIANCECHECK(a VARCHAR(1), b VARCHAR(1))

+-- Checking v = NULL

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a = b

+--

+-- Checking NOT v = NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a = b

+--

+-- Checking v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <> b

+--

+-- Checking NOT v <> NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <> b

+--

+-- Checking v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b

+--

+-- Checking NOT v < NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a < b

+--

+-- Checking v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a <= b

+--

+-- Checking NOT v <= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a <= b

+--

+-- Checking v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a > b

+--

+-- Checking NOT v > NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a > b

+--

+-- Checking v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a >= b

+--

+-- Checking NOT v >= NULL

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not a >= b

+--

+-- Checking BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b between 'a' and 'b'

+--

+-- Checking NOT BETWEEN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b between 'a' and 'b'

+--

+-- Checking IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b in ('a', 'b')

+--

+-- Checking NOT IN

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where not b in ('a', 'b')

+--

+-- Checking T && T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('b', 'a')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 1

+--

+-- Checking T && F = F

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('b', 'a')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking T && U = U

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'a')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b and 1 = 0

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 and a < b

+--

+-- Checking F && F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a and a < b

+--

+-- Checking T || T = T

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('b', 'a')

+/*c2*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or a > b

+--

+-- Checking T || F = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('b', 'a')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking T || U = T

+/*u2*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 1 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'a')

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where a < b or 1 = 0

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where 1 = 0 or a < b

+--

+-- Checking F || F = F

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', NULL)

+/*c0*/ select* from SQLUNKNOWNCOMPLIANCECHECK where b != a or a < b

+--

+-- Checking BETWEEN: >= and <=

+/*u1*/ delete from SQLUNKNOWNCOMPLIANCECHECK

+/*u1*/ insert into SQLUNKNOWNCOMPLIANCECHECK values ('a', 'b')

+/*c1*/ select* from SQLUNKNOWNCOMPLIANCECHECK where (a between 'a' and 'b') or (b between 'a' and 'b')

+--

+

diff --git a/testrun/hsqldb/TestSelfPersSchemA.txt b/testrun/hsqldb/TestSelfPersSchemA.txt
new file mode 100644
index 0000000..626457c
--- /dev/null
+++ b/testrun/hsqldb/TestSelfPersSchemA.txt
@@ -0,0 +1,21 @@
+/*s*/DROP USER owner1;

+/*s*/DROP ROLE r1;

+/*s*/DROP SCHEMA schema_a;

+/*s*/DROP SCHEMA schema_b;

+/*s*/DROP SCHEMA schema_c;

+/*s*/DROP SCHEMA schema_z;

+

+-- Test basic ability to create schemas owned by individual DBAs,

+-- non-privileged users, and roles.

+/*u0*/CREATE USER owner1 password "pwerd";

+/*u0*/CREATE USER adminowner1 password "pwerd";

+/*u0*/CREATE ROLE r1;

+/*u0*/GRANT r1 TO owner1;

+/*u0*/CREATE SCHEMA schema_a AUTHORIZATION owner1;

+/*u0*/CREATE SCHEMA schema_b AUTHORIZATION r1;

+/*u0*/CREATE SCHEMA schema_c AUTHORIZATION adminowner1;

+/*e*/CREATE SCHEMA schema_z AUTHORIZATION nosuchowner;

+/*u0*/DROP SCHEMA schema_c;

+/*u0*/DROP USER adminowner1;

+

+/*u0*/ SHUTDOWN IMMEDIATELY;

diff --git a/testrun/hsqldb/TestSelfPersSchemB.txt b/testrun/hsqldb/TestSelfPersSchemB.txt
new file mode 100644
index 0000000..44cf96c
--- /dev/null
+++ b/testrun/hsqldb/TestSelfPersSchemB.txt
@@ -0,0 +1,154 @@
+/*s*/DROP USER blaine;

+/*s*/DROP USER debbie;

+/*s*/DROP SCHEMA bschema cascade;

+/*s*/DROP SCHEMA dschema cascade;

+

+-- Test persistence to .log file of personal schemas.

+/*u0*/CREATE TABLE schema_a.t1(i int);

+/*u0*/DROP SCHEMA schema_a CASCADE;

+/*u0*/DROP SCHEMA schema_b;

+/*e*/DROP SCHEMA schema_z;

+/*u0*/DROP ROLE r1;

+/*u0*/DROP USER owner1;

+

+-- Schema authorization of individual User

+-- Test that non-DBA schema owners can CREATE/SELECT/INSERT objects in their

+-- own schema but not in somebody else's schema (assuming explicit object

+-- rights have not been granted, of course).

+/*u0*/create table public.ptable(i int);

+/*u1*/insert into public.ptable values(9);

+/*u0*/CREATE INDEX public.pindex ON public.ptable(i);

+/*u0*/CREATE SEQUENCE public.psequence;

+/*u0*/create user blaine password "blaine";

+/*u0*/GRANT CHANGE_AUTHORIZATION TO blaine;

+/*u0*/create schema bschema authorization blaine;

+/*u0*/create table bschema.b1(i int);

+/*c0*/select * from bschema.b1;

+/*u0*/connect user blaine password "blaine";

+/*c0*/select * from bschema.b1;

+/*u1*/insert into bschema.b1 values(3);

+/*c1*/select * from bschema.b1;

+/*u0*/connect user sa password "";

+/*u0*/create user debbie password debbie;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO debbie;

+/*u0*/create schema dschema authorization debbie;

+/*u0*/create table dschema.d1(i int);

+/*u1*/insert into dschema.d1 values(5);

+/*u0*/commit;

+/*u0*/connect user debbie password debbie;

+/*e*/select * from bschema.b1;

+/*e*/create table bschema.b3(i int);

+/*u0*/create table dschema.d2 (i int);

+/*u0*/set schema dschema;

+/*c1*/select * from d1;

+/*c0*/select * from d2;

+/*u0*/connect user blaine password "blaine";

+/*u0*/set schema bschema;

+/*e*/create table dschema.d4(i int);

+/*u0*/create table b2(i int);

+/*c1*/select * from b1;

+/*u1*/insert into b1 values(5);

+/*u1*/insert into b2 values (55);

+/*c2*/select * from b1;

+/*c1*/select * from b2;

+

+-- Test of same-named-objects in different schemas.  As an Admin.

+/*u0*/connect user sa password "";

+/*u0*/CREATE TABLE bschema.sametname(i int);

+/*u0*/CREATE TABLE dschema.sametname(i int);

+/*u0*/CREATE VIEW bschema.samevname AS SELECT * FROM bschema.sametname;

+/*u0*/CREATE VIEW dschema.samevname AS SELECT * FROM dschema.sametname;

+/*u0*/CREATE SEQUENCE bschema.samesname START WITH 10;

+/*u0*/CREATE SEQUENCE dschema.samesname START WITH 20;

+/*u1*/INSERT INTO bschema.sametname(i) VALUES(1);

+/*u1*/INSERT INTO dschema.sametname(i) VALUES(2);

+/*r1,10*/SELECT i, NEXT VALUE FOR bschema.samesname FROM bschema.sametname;

+/*r2,20*/SELECT i, NEXT VALUE FOR dschema.samesname FROM dschema.sametname;

+/*r1*/SELECT i FROM bschema.samevname;

+/*r2*/SELECT i FROM dschema.samevname;

+-- Verify that same-named-objects does not make system tables choke

+/*u0*/SET SCHEMA information_schema;

+SELECT * FROM authorizations;

+SELECT * FROM constraint_column_usage;

+SELECT * FROM system_columns;

+SELECT * FROM system_schemas;

+SELECT * FROM schemata;

+SELECT * FROM sequences;

+SELECT * FROM system_sessioninfo;

+SELECT * FROM system_sessions;

+SELECT * FROM table_privileges;

+SELECT * FROM system_tables;

+SELECT * FROM usage_privileges;

+SELECT * FROM system_users;

+

+-- Basic user schema permission capability has been tested well above.

+-- Now LIGHTER TESTING FOR REMAINING COMMANDS AND SCHEMA OBJECT TYPES:

+-- (purpose to see if the non-Admin, non-right-granted user may do these

+--  things on his objects, but not to other objects).

+--     Commands to test:  ALTER, DELETE, DROP, GRANT, REVOKE, UPDATE

+--     Object types to test:  INDEX, SEQUENCE, VIEW

+/*u0*/connect user blaine password "blaine";

+/*u0*/CREATE TABLE bschema.extra(i1 int);

+/*u0*/CREATE TABLE bschema.todrop(i1 int);

+/*u1*/insert into bschema.extra values(8);

+-- First Commands on TABLEs

+/*e*/ALTER TABLE public.ptable ADD COLUMN i2 int;

+/*u0*/ALTER TABLE bschema.extra ADD COLUMN i2 int;

+/*c1*/SELECT * FROM bschema.extra;

+/*e*/UPDATE public.ptable SET i = 11;

+/*u1*/UPDATE bschema.extra SET i1 = 44;

+/*e*/DELETE FROM public.ptable;

+/*u1*/DELETE FROM bschema.extra;

+/*e*/GRANT SELECT ON public.ptable TO debbie;

+/*u0*/GRANT SELECT ON bschema.extra TO debbie;

+/*e*/REVOKE SELECT ON public.ptable FROM debbie RESTRICT;

+/*u0*/REVOKE SELECT ON bschema.extra FROM debbie RESTRICT;

+/*e*/DROP TABLE public.ptable;

+/*u0*/DROP TABLE bschema.todrop;

+-- Commands on INDEXes

+/*e*/CREATE INDEX public.i1 ON public.ptable(i);

+/*u0*/CREATE UNIQUE INDEX bschema.ui1 ON bschema.extra(i1);

+/*c1*/SELECT count(*) FROM bschema.extra;

+/*e*/ALTER INDEX public.pindex RENAME TO othername;

+/*u0*/ALTER INDEX bschema.ui1 RENAME TO othername;

+/*u1*/insert into bschema.extra(i1, i2) values(8,1);

+-- Following violates the UNIQUE index

+/*e*/insert into bschema.extra(i1, i2) values(8,2);

+/*e*/DROP INDEX public.pindex;

+/*u0*/DROP index bschema.othername;

+-- Commands on SEQUENCEs

+/*e*/CREATE SEQUENCE public.pseq;

+/*u0*/CREATE SEQUENCE bschema.bseq;

+/*e*/SELECT next value for public.psequence FROM bschema.extra;

+/*c1*/SELECT next value for bschema.bseq FROM bschema.extra;

+/*e*/ALTER SEQUENCE public.psequence RESTART WITH 10;

+/*u0*/ALTER SEQUENCE bschema.bseq RESTART WITH 10;

+/*e*/GRANT USAGE ON SEQUENCE public.psequence TO debbie;

+/*u0*/GRANT USAGE ON SEQUENCE bschema.bseq TO debbie;

+/*e*/REVOKE USAGE ON SEQUENCE public.psequence FROM debbie RESTRICT;

+/*u0*/REVOKE USAGE ON SEQUENCE bschema.bseq FROM debbie RESTRICT;

+/*e*/DROP SEQUENCE public.psequence;

+/*u0*/DROP SEQUENCE bschema.bseq;

+-- Adding views now.  Didn't want them to impact operations on underlying

+-- tables in tests above.

+/*u0*/connect user sa password "";

+/*u0*/create VIEW public.pview AS SELECT * FROM public.ptable;

+/*u0*/connect user blaine password "blaine";

+/*e*/create VIEW public.oview AS SELECT * FROM public.ptable;

+/*u0*/create VIEW bschema.bview AS SELECT * FROM bschema.extra;

+/*e*/SELECT * FROM public.pview;

+/*c1*/SELECT * FROM bschema.bview;

+/*e*/GRANT SELECT ON public.pview TO debbie;

+/*u0*/GRANT SELECT ON bschema.bview TO debbie;

+/*e*/REVOKE SELECT ON public.pview FROM debbie RESTRICT;

+/*u0*/REVOKE SELECT ON bschema.bview FROM debbie RESTRICT;

+/*e*/DROP VIEW public.pview;

+/*u0*/DROP VIEW bschema.bview;

+/*u0*/DROP TABLE bschema.extra;

+

+/*u0*/connect user sa password "";

+/*u0*/DROP VIEW public.pview;

+/*u0*/DROP INDEX public.pindex;

+/*u0*/DROP TABLE public.ptable;

+/*u0*/DROP SEQUENCE public.psequence;

+/*u0*/SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfPersSchemC.txt b/testrun/hsqldb/TestSelfPersSchemC.txt
new file mode 100644
index 0000000..bd38940
--- /dev/null
+++ b/testrun/hsqldb/TestSelfPersSchemC.txt
@@ -0,0 +1,204 @@
+-- Test persistence via .script file

+/*u0*/create table bschema.b5(i int);

+/*c0*/select * from bschema.b5;

+/*u0*/connect user blaine password "blaine";

+/*c0*/select * from bschema.b5;

+/*u1*/insert into bschema.b5 values(3);

+/*c1*/select * from bschema.b5;

+/*c2*/select * from bschema.b1;

+/*u1*/insert into bschema.b1 values(3);

+/*c3*/select * from bschema.b1;

+/*e*/select * from dschema.d1;

+/*u0*/connect user sa password "";

+/*u0*/create table dschema.d5(i int);

+/*u1*/insert into dschema.d1 values(56);

+/*u1*/insert into dschema.d5 values(5);

+/*u0*/commit;

+/*u0*/connect user debbie password debbie;

+/*e*/select * from bschema.b1;

+/*e*/create table bschema.b3(i int);

+/*u0*/create table dschema.d6 (i int);

+/*u0*/set schema dschema;

+/*c2*/select * from d1;

+/*c0*/select * from d2;

+/*c1*/select * from d5;

+/*c0*/select * from d6;

+

+-- Test of same-named-objects in different schemas.  As an Admin.

+-- Verify that same-named-objects does not make system tables choke

+/*u0*/SET SCHEMA information_schema;

+SELECT * FROM authorizations;

+SELECT * FROM constraint_column_usage;

+SELECT * FROM system_columns;

+SELECT * FROM system_schemas;

+SELECT * FROM schemata;

+SELECT * FROM sequences;

+SELECT * FROM system_sessioninfo;

+SELECT * FROM system_sessions;

+SELECT * FROM table_privileges;

+SELECT * FROM system_tables;

+SELECT * FROM usage_privileges;

+SELECT * FROM system_users;

+/*u0*/connect user sa password "";

+/*r1,11*/SELECT i, NEXT VALUE FOR bschema.samesname FROM bschema.sametname;

+/*r2,21*/SELECT i, NEXT VALUE FOR dschema.samesname FROM dschema.sametname;

+/*r1*/SELECT i FROM bschema.samevname;

+/*r2*/SELECT i FROM dschema.samevname;

+

+-- Cleanup to prepare for next set of tests

+/*u0*/connect user sa password "";

+/*u0*/drop schema bschema cascade;

+/*u0*/drop schema dschema cascade;

+/*u0*/drop user blaine;

+/*u0*/drop user debbie;

+

+-- Schema authorization using a Role.

+-- Test that non-DBA schema owners can CREATE/SELECT/INSERT objects in their

+-- own schema but not in somebody else's schema (assuming explicit object

+-- rights have not been granted, of course).

+/*u0*/connect user sa password "";

+/*u0*/create user blaine password blaine;

+/*u0*/create user debbie password debbie;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO blaine;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO debbie;

+/*u0*/create role r;

+/*u0*/create role s;

+/*u0*/grant s to r;

+/*u0*/create schema aschema authorization s;

+/*u0*/create schema bschema authorization s;

+/*u0*/create table aschema.a1(i int);

+/*u1*/insert into aschema.a1 values(11);

+/*u0*/create table bschema.b1(i int);

+/*u1*/insert into bschema.b1 values (22);

+/*u0*/commit;

+

+-- Test blaine, who will get his authorization via role s via role r.

+/*u0*/connect user blaine password blaine;

+/*u0*/set schema aschema;

+/*e*/create table a2(i int);

+/*u0*/set schema bschema;

+/*e*/create table b2(i int);

+/*e*/select * from aschema.a1;

+/*e*/select * from bschema.b1;

+/*u0*/connect user sa password "";

+/*u0*/grant r to blaine;

+/*u0*/connect user blaine password blaine;

+/*u0*/set schema aschema;

+/*u0*/create table a2(i int);

+/*u0*/set schema bschema;

+/*u0*/create table b2(i int);

+/*c1*/select * from aschema.a1;

+/*c1*/select * from bschema.b1;

+/*c0*/select * from aschema.a2;

+/*c0*/select * from bschema.b2;

+

+-- Test debbie, who will get her authorization via role r directly.

+/*u0*/connect user debbie password debbie;

+/*u0*/set schema aschema;

+/*e*/create table a3(i int);

+/*u0*/set schema bschema;

+/*e*/create table b3(i int);

+/*e*/select * from aschema.a1;

+/*e*/select * from bschema.b1;

+/*u0*/connect user sa password "";

+/*u0*/grant s to debbie;

+/*u0*/connect user debbie password debbie;

+/*u0*/set schema aschema;

+/*u0*/create table a3(i int);

+/*u0*/set schema bschema;

+/*u0*/create table b3(i int);

+/*c1*/select * from aschema.a1;

+/*c1*/select * from bschema.b1;

+/*c0*/select * from aschema.a2;

+/*c0*/select * from bschema.b2;

+/*c0*/select * from aschema.a3;

+/*c0*/select * from bschema.b3;

+

+-- Test of same-named-objects in different schemas.  As an Admin.

+/*u0*/connect user sa password "";

+/*u0*/CREATE TABLE bschema.sametname(i int);

+/*u0*/CREATE TABLE aschema.sametname(i int);

+/*u0*/CREATE VIEW bschema.samevname AS SELECT * FROM bschema.sametname;

+/*u0*/CREATE VIEW aschema.samevname AS SELECT * FROM aschema.sametname;

+/*u0*/CREATE SEQUENCE bschema.samesname START WITH 10;

+/*u0*/CREATE SEQUENCE aschema.samesname START WITH 20;

+/*u1*/INSERT INTO bschema.sametname(i) VALUES(1);

+/*u1*/INSERT INTO aschema.sametname(i) VALUES(2);

+/*r1,10*/SELECT i, NEXT VALUE FOR bschema.samesname FROM bschema.sametname;

+/*r2,20*/SELECT i, NEXT VALUE FOR aschema.samesname FROM aschema.sametname;

+/*r1*/SELECT i FROM bschema.samevname;

+/*r2*/SELECT i FROM aschema.samevname;

+

+/*u0*/connect user sa password "";

+/*u0*/create table public.ptable(i int);

+/*u1*/insert into public.ptable values(9);

+/*u0*/CREATE INDEX public.pindex ON public.ptable(i);

+/*u0*/CREATE SEQUENCE public.psequence;

+-- Basic user schema permission capability has been tested well above

+-- Now LIGHTER TESTING FOR REMAINING COMMANDS AND SCHEMA OBJECT TYPES:

+--  (for authorizations via roles).

+-- (purpose to see if the non-Admin, non-right-granted user may do these

+--  things on his objects, but not to other objects).

+--     Commands to test:  ALTER, DELETE, DROP, GRANT, REVOKE, UPDATE

+--     Object types to test:  INDEX, SEQUENCE, VIEW

+/*u0*/connect user blaine password blaine;

+/*u0*/CREATE TABLE bschema.extra(i1 int);

+/*u0*/CREATE TABLE bschema.todrop(i1 int);

+/*u1*/insert into bschema.extra values(8);

+-- First Commands on TABLEs

+/*e*/ALTER TABLE public.ptable ADD COLUMN i2 int;

+/*u0*/ALTER TABLE bschema.extra ADD COLUMN i2 int;

+/*c1*/SELECT * FROM bschema.extra;

+/*e*/UPDATE public.ptable SET i = 11;

+/*u1*/UPDATE bschema.extra SET i1 = 44;

+/*e*/DELETE FROM public.ptable;

+/*u1*/DELETE FROM bschema.extra;

+/*e*/GRANT SELECT ON public.ptable TO debbie;

+/*u0*/GRANT SELECT ON bschema.extra TO debbie;

+/*e*/REVOKE SELECT ON public.ptable FROM debbie RESTRICT;

+/*u0*/REVOKE SELECT ON bschema.extra FROM debbie RESTRICT;

+/*e*/DROP TABLE public.ptable;

+/*u0*/DROP TABLE bschema.todrop;

+-- Commands on INDEXes

+/*e*/CREATE INDEX public.i1 ON public.ptable(i);

+/*u0*/CREATE UNIQUE INDEX bschema.ui1 ON bschema.extra(i1);

+/*c1*/SELECT count(*) FROM bschema.extra;

+/*e*/ALTER INDEX public.pindex RENAME TO othername;

+/*u0*/ALTER INDEX bschema.ui1 RENAME TO othername;

+/*u1*/insert into bschema.extra(i1, i2) values(8,1);

+-- Following violates the UNIQUE index

+/*e*/insert into bschema.extra(i1, i2) values(8,2);

+/*e*/DROP INDEX public.pindex;

+/*u0*/DROP index bschema.othername;

+-- Commands on SEQUENCEs

+/*e*/CREATE SEQUENCE public.pseq;

+/*u0*/CREATE SEQUENCE bschema.bseq;

+/*e*/SELECT next value for public.psequence FROM bschema.extra;

+/*c1*/SELECT next value for bschema.bseq FROM bschema.extra;

+/*e*/ALTER SEQUENCE public.psequence RESTART WITH 10;

+/*u0*/ALTER SEQUENCE bschema.bseq RESTART WITH 10;

+/*e*/GRANT USAGE ON SEQUENCE public.psequence TO debbie;

+/*u0*/GRANT USAGE ON SEQUENCE bschema.bseq TO debbie;

+/*e*/REVOKE USAGE ON SEQUENCE public.psequence FROM debbie RESTRICT;

+/*u0*/REVOKE USAGE ON SEQUENCE bschema.bseq FROM debbie RESTRICT;

+/*e*/DROP SEQUENCE public.psequence;

+/*u0*/DROP SEQUENCE bschema.bseq;

+-- Adding views now.  Didn't want them to impact operations on underlying

+-- tables in tests above.

+/*u0*/connect user sa password "";

+/*u0*/create VIEW public.pview AS SELECT * FROM public.ptable;

+/*u0*/connect user blaine password blaine;

+/*e*/create VIEW public.oview AS SELECT * FROM public.ptable;

+/*u0*/create VIEW bschema.bview AS SELECT * FROM bschema.extra;

+/*e*/SELECT * FROM public.pview;

+/*c1*/SELECT * FROM bschema.bview;

+/*e*/GRANT SELECT ON public.pview TO debbie;

+/*u0*/GRANT SELECT ON bschema.bview TO debbie;

+/*e*/REVOKE SELECT ON public.pview FROM debbie RESTRICT;

+/*u0*/REVOKE SELECT ON bschema.bview FROM debbie RESTRICT;

+/*e*/DROP VIEW public.pview;

+/*u0*/DROP VIEW bschema.bview;

+/*u0*/DROP TABLE bschema.extra;

+

+/*u0*/connect user sa password "";

+/*u0*/shutdown;

diff --git a/testrun/hsqldb/TestSelfPersSchemD.txt b/testrun/hsqldb/TestSelfPersSchemD.txt
new file mode 100644
index 0000000..fda8596
--- /dev/null
+++ b/testrun/hsqldb/TestSelfPersSchemD.txt
@@ -0,0 +1,143 @@
+-- Test persistence via .script file

+-- Same blaine role tests as in test C, but after persistence.

+/*u0*/connect user blaine password blaine;

+/*u0*/set schema aschema;

+/*u0*/create table a4(i int);

+/*u0*/set schema bschema;

+/*u0*/create table b4(i int);

+/*c1*/select * from aschema.a1;

+/*c1*/select * from bschema.b1;

+/*c0*/select * from aschema.a2;

+/*c0*/select * from bschema.b2;

+/*c0*/select * from aschema.a4;

+/*c0*/select * from bschema.b4;

+/*u0*/connect user debbie password debbie;

+/*u0*/set schema aschema;

+/*u0*/create table a5(i int);

+/*u0*/set schema bschema;

+/*u0*/create table b5(i int);

+/*c1*/select * from aschema.a1;

+/*c1*/select * from bschema.b1;

+/*c0*/select * from aschema.a2;

+/*c0*/select * from bschema.b2;

+/*c0*/select * from aschema.a3;

+/*c0*/select * from bschema.b4;

+/*c0*/select * from aschema.a4;

+/*c0*/select * from bschema.b5;

+/*c0*/select * from aschema.a5;

+/*c0*/select * from bschema.b3;

+

+/*u0*/connect user sa password "";

+-- FRED:  Please tell me if I remember this correctly:

+-- Next line has no effect, since Role nestings are not preserved in the Roles

+-- but are resolved statically at grant time.  I.e., since r had s when

+-- r was granted, it doesn't matter what roles are added/removed to/from

+-- s after that.

+-- Role nestings ARE preserved in the Roles

+/*u0*/revoke s from r restrict;

+/*u0*/revoke r from blaine restrict;

+-- Following not necessary although blaine had both r and s implicitly.

+/*e*/revoke s from blaine restrict; -- role s was not directly granted to blaine

+/*u0*/revoke s from debbie restrict;

+

+-- Negative tests (after privilege revocation via role revocation)

+/*u0*/connect user blaine password blaine;

+/*u0*/set schema aschema;

+/*e*/create table a6(i int);

+/*u0*/set schema bschema;

+/*e*/create table b6(i int);

+/*e*/select * from aschema.a1;

+/*e*/select * from bschema.b1;

+/*e*/select * from aschema.a2;

+/*e*/select * from bschema.b2;

+/*e*/select * from aschema.a4;

+/*e*/select * from bschema.b4;

+/*u0*/connect user debbie password debbie;

+/*u0*/set schema aschema;

+/*e*/create table a6(i int);

+/*u0*/set schema bschema;

+/*e*/create table b6(i int);

+/*e*/select * from aschema.a1;

+/*e*/select * from bschema.b1;

+/*e*/select * from aschema.a2;

+/*e*/select * from bschema.b2;

+/*e*/select * from aschema.a3;

+/*e*/select * from bschema.b4;

+/*e*/select * from aschema.a4;

+/*e*/select * from bschema.b5;

+/*e*/select * from aschema.a5;

+/*e*/select * from bschema.b3;

+

+-- USER INITIAL SCHEMA settings tests.  Here, we can't test whether the

+-- settings actually "work", because TestSelf always connects up as "sa".

+-- But we can test if the SET commands work, and if they get saved properly.

+/*u0*/connect user debbie password debbie;

+-- Need DBA privilege for ALTER USER usage.

+/*e*/ALTER USER debbie SET INITIAL SCHEMA public;

+-- Invalid schema name

+/*e*/SET INITIAL SCHEMA bad;

+/*rnull*/SELECT initial_schema FROM information_schema.system_users

+     WHERE USER_NAME = 'DEBBIE';

+/*u0*/SET INITIAL SCHEMA public;

+/*rPUBLIC*/SELECT initial_schema FROM information_schema.system_users

+     WHERE USER_NAME = 'DEBBIE';

+/*u0*/SET INITIAL SCHEMA aschema;

+/*rASCHEMA*/SELECT initial_schema FROM information_schema.system_users

+     WHERE USER_NAME = 'DEBBIE';

+-- Special DEFAULT keyword to set to the system default schema.

+/*u0*/SET INITIAL SCHEMA DEFAULT;

+/*rnull*/SELECT initial_schema FROM information_schema.system_users

+     WHERE USER_NAME = 'DEBBIE';

+/*u0*/connect user sa password "";

+GRANT dba TO debbie;

+/*u0*/connect user debbie password debbie;

+-- Now that have DBA priv, can run ALTER USER.

+/*u0*/ALTER USER debbie SET INITIAL SCHEMA public;

+-- ... even for other users

+/*rnull*/SELECT initial_schema FROM information_schema.system_users

+     WHERE USER_NAME = 'BLAINE';

+/*u0*/ALTER USER blaine SET INITIAL SCHEMA aschema;

+/*rASCHEMA*/SELECT initial_schema FROM information_schema.system_users

+     WHERE USER_NAME = 'BLAINE';

+/*u0*/ALTER USER blaine SET INITIAL SCHEMA default;

+/*rnull*/SELECT initial_schema FROM information_schema.system_users

+     WHERE USER_NAME = 'BLAINE';

+-- Test prohibited schemas

+/*e*/ALTER USER debbie SET INITIAL SCHEMA nosuch;

+/*e*/SET INITIAL SCHEMA nosuch;

+-- Test prohibited target Users

+/*e*/ALTER USER nosuch SET INITIAL SCHEMA default;

+/*e*/ALTER USER nosuch SET INITIAL SCHEMA aschema;

+/*e*/ALTER USER _system SET INITIAL SCHEMA default;

+/*e*/ALTER USER _system SET INITIAL SCHEMA aschema;

+/*e*/ALTER USER public SET INITIAL SCHEMA default;

+/*e*/ALTER USER public SET INITIAL SCHEMA aschema;

+

+-- Test user-schema dependencies

+/*u0*/connect user sa password "";

+/*u0*/CREATE user depu password "depu";

+/*u0*/CREATE schema deps authorization depu;

+-- Will fail because a schema is authorized directly by depu

+/*e*/DROP USER depu;

+/*u0*/DROP SCHEMA deps;

+/*u0*/DROP USER depu;

+/*u0*/CREATE user depu password "depu";

+/*u0*/CREATE schema deps authorization depu;

+/*e*/DROP USER depu;

+/*u0*/DROP USER depu CASCADE;

+-- Roles authorizations are independent of any user.

+/*u0*/CREATE user depu password "depu";

+/*u0*/CREATE ROLE depr;

+/*u0*/GRANT depr TO depu;

+/*u0*/CREATE schema deps authorization depr;

+/*u0*/DROP user depu;

+

+-- Test of same-named-objects in different schemas.  As an Admin.

+/*u0*/connect user sa password "";

+/*r1,11*/SELECT i, NEXT VALUE FOR bschema.samesname FROM bschema.sametname;

+/*r2,21*/SELECT i, NEXT VALUE FOR aschema.samesname FROM aschema.sametname;

+/*r1*/SELECT i FROM bschema.samevname;

+/*r2*/SELECT i FROM aschema.samevname;

+

+/*u0*/connect user sa password "";

+/*u0*/REVOKE dba FROM debbie RESTRICT;

diff --git a/testrun/hsqldb/TestSelfPrimaryKeys.txt b/testrun/hsqldb/TestSelfPrimaryKeys.txt
new file mode 100644
index 0000000..4228cc9
--- /dev/null
+++ b/testrun/hsqldb/TestSelfPrimaryKeys.txt
@@ -0,0 +1,37 @@
+--

+-- TestSelfPrimaryKeys.txt

+--

+-- Tests for add / drop primary key constraints

+--

+drop table testtable if exists;

+create cached table testtable (

+    aString              varchar(256)                   not null,

+    firstNum             integer                        not null,

+    aDate                date                           not null,

+    secondNum            integer                        not null,

+    thirdNum             integer                        not null,

+    aName                varchar(32)                    not null

+  );

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Current', 22, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Popular', 23, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('New', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Old', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('CCurrent', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('ELV', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('ELNA', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Older', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('RA', 20, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('RP', 2, '2003-11-10', 18, 3, 'my name goes here');

+

+alter table testtable add constraint pk_testtable primary key (aString);

+alter table testtable drop constraint pk_testtable

diff --git a/testrun/hsqldb/TestSelfQueries.txt b/testrun/hsqldb/TestSelfQueries.txt
new file mode 100644
index 0000000..1b5478b
--- /dev/null
+++ b/testrun/hsqldb/TestSelfQueries.txt
@@ -0,0 +1,120 @@
+--

+-- TestSelfQueries.txt

+--

+-- Tests for Query results, especially the neutrality of constraints and indexes

+--

+drop table TESTTABLE if exists;

+

+create cached table TESTTABLE (

+    aString              varchar(256)                   not null,

+    firstNum             integer                        not null,

+    aDate                date                           not null,

+    secondNum            integer                        not null,

+    thirdNum             integer                        not null,

+    aName                varchar(32)                    not null

+  );

+create  index IDX_TESTTABLE_aString on TESTTABLE (aString);

+create  index IDX_TESTTABLE_aDate_secondNum on TESTTABLE (aDate,secondNum);

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Current', 22, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Popular', 23, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('New', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Old', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('CCurrent', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('ELV', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('ELNA', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('Older', 5, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('RA', 20, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('RP', 2, '2003-11-10', 18, 3, 'my name goes here');

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values ('VS', 3, '2003-11-10', 18, 3, 'my name goes here');

+--

+/*c11*/select * from testtable where adate = '2003-11-10' and secondNum = 18;

+/*c11*/select * from testtable where (adate, secondNum) = (DATE'2003-11-10', 18);

+/*c11*/select * from testtable where adate = '2003-11-10';

+/*c1*/select * from testtable where adate = '2003-11-10' and firstNum = 20;

+/*c1*/select * from testtable where (adate, firstNum) = (DATE'2003-11-10', 20);

+/*c11*/select * from testtable where adate = '2003-11-10' and thirdNum = 3;

+/*c11*/select * from testtable where (adate, thirdNum) = (DATE'2003-11-10', 3);

+

+drop index IDX_TESTTABLE_aString;

+drop index IDX_TESTTABLE_aDate_secondNum;

+alter table TESTTABLE add constraint tt_pk primary key (astring);

+/*c11*/select * from testtable where adate = '2003-11-10' and secondNum = 18;

+/*c11*/select * from testtable where (adate, secondNum) = (DATE'2003-11-10', 18);

+/*c11*/select * from testtable where adate = '2003-11-10';

+/*c1*/select * from testtable where adate = '2003-11-10' and firstNum = 20;

+/*c11*/select * from testtable where adate = '2003-11-10' and thirdNum = 3;

+alter table testtable drop column aname;

+/*c1*/select * from testtable where adate = '2003-11-10' and firstNum = 20;

+/*c11*/select * from testtable where adate = '2003-11-10' and thirdNum = 3;

+alter table testtable add column aname char(10) default 'a string' not null;

+/*c1*/select * from testtable where adate = '2003-11-10' and firstNum = 20;

+/*c11*/select * from testtable where adate = '2003-11-10' and thirdNum = 3;

+/*e*/update testtable set name=null;

+

+-- bug #722443

+DROP TABLE CONFIGUSER IF EXISTS;

+CREATE CACHED TABLE CONFIGUSER(USR_USERID NUMERIC NOT NULL PRIMARY KEY,USR_USERNAME VARCHAR(10) NOT NULL,USR_PASSWORD VARCHAR(10));

+INSERT INTO CONFIGUSER VALUES(-5,'guest','guest');

+INSERT INTO CONFIGUSER VALUES(-4,'user','user');

+INSERT INTO CONFIGUSER VALUES(-3,'owner','owner');

+INSERT INTO CONFIGUSER VALUES(-2,'admin','xxx');

+INSERT INTO CONFIGUSER VALUES(-1,'sadmin','xxx');

+INSERT INTO CONFIGUSER VALUES(0,'nobody',null);

+-- select all users with their username as password

+/*c3*/select * from configuser where usr_username = usr_password;

+-- create a unique index on one column

+CREATE UNIQUE INDEX IDX_USERNAME ON CONFIGUSER(USR_USERNAME);

+-- select all users with their username as password

+/*c3*/select * from configuser where usr_username = usr_password;

+/*c3*/select * from configuser where usr_username in (select usr_password from configuser)

+/*c3*/select * from configuser where usr_password in (select usr_username from configuser)

+/*c3*/select * from configuser where usr_password in (usr_username);

+/*c2*/select * from configuser where usr_password in ('guest', 'user', 'wrong')

+DROP INDEX IDX_USERNAME

+-- select all users with their username as password

+/*c3*/select * from configuser where usr_username = usr_password;

+/*c3*/select * from configuser where usr_username in (select usr_password from configuser)

+/*c3*/select * from configuser where usr_password in (select usr_username from configuser)

+/*c3*/select * from configuser where usr_password in (usr_username);

+/*c2*/select * from configuser where usr_password in ('guest', 'user', 'wrong')

+CREATE INDEX IDX_USERNAME ON CONFIGUSER(USR_USERNAME);

+-- select all users with their username as password

+/*c3*/select * from configuser where usr_username = usr_password;

+/*c3*/select * from configuser where usr_username in (select usr_password from configuser)

+/*c3*/select * from configuser where usr_password in (select usr_username from configuser)

+/*c3*/select * from configuser where usr_password in (usr_username);

+/*c2*/select * from configuser where usr_password in ('guest', 'user', 'wrong')

+--

+-- COUNT(DISTINCT ) when there are no records

+-- bug #718866

+CREATE TABLE IBANX_PERMIT(ID INT, A1 VARCHAR(10));

+/*r0*/SELECT count(distinct A0.ID) FROM IBANX_PERMIT A0;

+--

+-- use of column aliases in the where clause

+--bug #696595

+CREATE TABLE "liste"("kosten" INT, "preis" INT);

+insert into "liste" values(100, 10);

+/*r100*/SELECT "kosten" AS "total" FROM "liste" WHERE "kosten" > 0 ORDER BY "total" DESC;

+/*r110*/SELECT ("kosten"+"preis") AS "total" FROM "liste" WHERE "kosten"+"preis" > 0 ORDER BY "total" DESC;

+drop table t1 if exists;

+drop table t2 if exists;

+create table t1(t1c1 int, t1c2 int);

+create table t2(t2c1 int, t2c2 int);

+insert into t1 values 1, 2;

+insert into t2 values 2, 3;

+/*r1,2,2,3*/select * from t1, t2;

+/*r1,2,2,3*/select * from t1, t2 where t1c2 = t2c1;

+/*r1,2,2,3*/select * from t1 join t2 on t1c2 = t2c1;

+/*r1,2,2,3*/select * from t1 left outer join t2 on t1c2 = t2c1;

+/*r1,2,2,3*/select * from t1 right outer join t2 on t1c2 = t2c1;

diff --git a/testrun/hsqldb/TestSelfRightCaching.txt b/testrun/hsqldb/TestSelfRightCaching.txt
new file mode 100644
index 0000000..b26faa8
--- /dev/null
+++ b/testrun/hsqldb/TestSelfRightCaching.txt
@@ -0,0 +1,191 @@
+-- Rights Map and Adminstrative Right Caching tests

+

+DROP TABLE m IF EXISTS;

+CREATE TABLE m(i int);

+INSERT INTO m VALUES(11);

+CREATE USER cani PASSWORD cani;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO cani;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Sanity check of individual grants for user and for public

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO PUBLIC;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM PUBLIC RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Dual grants, but with SELECTs in between (which will rebuild the caches)

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO cani;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO PUBLIC;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM PUBLIC RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Dual grants.  No cache build until both GRANTS added.

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO PUBLIC;

+GRANT SELECT ON m TO cani;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM PUBLIC RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Ditto, in different sequence.

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO cani;

+GRANT SELECT ON m TO PUBLIC;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM PUBLIC RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- ... different sequence

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO PUBLIC;

+GRANT SELECT ON m TO cani;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM PUBLIC RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Ditto, in different sequence.

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO cani;

+GRANT SELECT ON m TO PUBLIC;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM PUBLIC RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+

+-- REPEAT SAME WITH A NAMED ROLE INSTEAD OF PUBLIC

+CONNECT USER sa PASSWORD "";

+CREATE ROLE sesamerole;

+GRANT sesamerole TO cani;

+

+-- Sanity check of individual grants for user and for sesamerole

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO sesamerole;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM sesamerole RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Dual grants, but with SELECTs in between (which will rebuild the caches)

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO cani;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO sesamerole;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM sesamerole RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Dual grants.  No cache build until both GRANTS added.

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO sesamerole;

+GRANT SELECT ON m TO cani;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM sesamerole RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Ditto, in different sequence.

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO cani;

+GRANT SELECT ON m TO sesamerole;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM sesamerole RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- ... different sequence

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO sesamerole;

+GRANT SELECT ON m TO cani;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM sesamerole RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

+

+-- Ditto, in different sequence.

+CONNECT USER sa PASSWORD "";

+GRANT SELECT ON m TO cani;

+GRANT SELECT ON m TO sesamerole;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM cani RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*c1*/SELECT * FROM m;

+CONNECT USER sa PASSWORD "";

+REVOKE SELECT ON m FROM sesamerole RESTRICT;

+CONNECT USER cani PASSWORD cani;

+/*e*/SELECT * FROM m;

diff --git a/testrun/hsqldb/TestSelfRoleNesting.txt b/testrun/hsqldb/TestSelfRoleNesting.txt
new file mode 100644
index 0000000..ee71437
--- /dev/null
+++ b/testrun/hsqldb/TestSelfRoleNesting.txt
@@ -0,0 +1,234 @@
+-- First with a table grant

+

+/*s*/DROP USER peon1;

+/*s*/DROP USER peon2;

+/*s*/DROP USER peon3;

+/*s*/DROP ROLE r1;

+/*s*/DROP ROLE r2;

+/*s*/DROP ROLE r3;

+/*s*/DROP ROLE r12;

+DROP TABLE t1 IF exists;

+DROP TABLE t2 IF exists;

+DROP TABLE t3 IF exists;

+DROP TABLE t4 IF exists;

+CREATE TABLE t1(i int);

+CREATE TABLE t2(i int);

+CREATE TABLE t3(i int);

+CREATE TABLE t4(i int);

+INSERT INTO t1 VALUES(1);

+INSERT INTO t2 VALUES(2);

+INSERT INTO t3 VALUES(3);

+INSERT INTO t4 VALUES(4);

+COMMIT;

+CREATE USER peon1 PASSWORD password;

+CREATE USER peon2 PASSWORD password;

+CREATE USER peon3 PASSWORD password;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon1;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon2;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon3;

+/*u0*/CREATE ROLE r1;

+/*u0*/CREATE ROLE r2;

+/*u0*/CREATE ROLE r3;

+/*u0*/GRANT r3 TO r2;

+/*u0*/GRANT r2 TO r1;

+-- Same role may be nested under the same user/role multiple times.

+/*u0*/GRANT r3 TO r1;

+/*u0*/REVOKE r3 FROM r1 RESTRICT;

+/*u0*/GRANT r1 TO peon1;

+-- Circular nesting not allowed.

+/*e*/GRANT r1 TO r3;

+

+CONNECT USER peon1 PASSWORD password;

+/*e*/SELECT * FROM t1;

+CONNECT USER SA PASSWORD "";

+/*u0*/GRANT SELECT on t1 TO r3;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+CONNECT USER SA PASSWORD "";

+/*u0*/REVOKE ALL ON t1 FROM r3 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*e*/SELECT * FROM t1;

+CONNECT USER SA PASSWORD "";

+/*u0*/GRANT SELECT ON t1 TO r3;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+CONNECT USER SA PASSWORD "";

+/*u0*/DROP ROLE r3;

+CONNECT USER peon1 PASSWORD password;

+/*e*/SELECT * FROM t1;

+

+-- Now with Admin priv

+CONNECT USER SA PASSWORD "";

+/*s*/DROP USER peon1;

+/*s*/DROP USER peon2;

+/*s*/DROP USER peon3;

+/*s*/DROP ROLE r1;

+/*s*/DROP ROLE r2;

+/*s*/DROP ROLE r3;

+/*s*/DROP ROLE r12;

+DROP TABLE t1 IF exists;

+CREATE TABLE t1(i int);

+INSERT INTO t1 VALUES(1);

+COMMIT;

+CREATE USER peon1 PASSWORD password;

+CREATE USER peon2 PASSWORD password;

+CREATE USER peon3 PASSWORD password;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon1;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon2;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon3;

+/*u0*/CREATE ROLE r1;

+/*u0*/CREATE ROLE r2;

+/*u0*/CREATE ROLE r3;

+/*u0*/GRANT r3 TO r2;

+/*u0*/GRANT r2 TO r1;

+/*u0*/GRANT r1 TO peon1;

+

+CONNECT USER peon1 PASSWORD password;

+/*e*/SET TABLE t1 READONLY false;

+CONNECT USER SA PASSWORD "";

+/*u0*/GRANT dba TO r3;

+CONNECT USER peon1 PASSWORD password;

+/*u0*/SET TABLE t1 READONLY false;

+CONNECT USER SA PASSWORD "";

+/*e*/REVOKE dba FROM r1 RESTRICT;

+/*e*/REVOKE dba FROM r2 RESTRICT;

+/*u0*/REVOKE dba FROM r3 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*e*/SET TABLE t1 READONLY false;

+CONNECT USER SA PASSWORD "";

+/*u0*/GRANT dba TO r3;

+CONNECT USER peon1 PASSWORD password;

+/*u0*/SET TABLE t1 READONLY false;

+CONNECT USER SA PASSWORD "";

+/*e*/DROP ROLE dba;

+

+

+-- Massively redundant privileges

+CONNECT USER SA PASSWORD "";

+DROP TABLE t1 IF exists;

+CREATE TABLE t1(i int);

+/*s*/DROP USER peon1;

+/*s*/DROP ROLE r1;

+/*s*/DROP ROLE r2;

+/*s*/DROP ROLE r3;

+/*s*/DROP ROLE r31;

+/*s*/DROP ROLE r311;

+/*u0*/CREATE ROLE r1;

+/*u0*/CREATE ROLE r2;

+/*u0*/CREATE ROLE r3;

+/*u0*/CREATE ROLE r31;

+/*u0*/CREATE ROLE r311;

+/*u0*/GRANT r31 to r3;

+/*u0*/GRANT dba TO r1;

+/*u0*/GRANT dba TO r2;

+/*u0*/GRANT dba TO r3;

+/*u0*/GRANT dba TO r31;

+/*u0*/GRANT dba TO r311;

+/*u0*/GRANT r311 TO r31;

+CREATE USER peon1 PASSWORD password ADMIN;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon1;

+CONNECT USER sa PASSWORD "";

+/*u0*/GRANT r1 TO peon1;

+/*u0*/GRANT r2 TO peon1;

+/*u0*/GRANT r3 TO peon1;

+/*u0*/GRANT r31 TO peon1;

+/*u0*/GRANT r311 TO peon1;

+CONNECT USER peon1 PASSWORD password;

+/*u0*/SET TABLE t1 READONLY false;

+-- Start revoking, piecemeal

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE dba FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*u0*/SET TABLE t1 READONLY false;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r1 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*u0*/SET TABLE t1 READONLY false;

+CONNECT USER sa PASSWORD "";

+/*u0*/DROP ROLE r2;

+CONNECT USER peon1 PASSWORD password;

+/*u0*/SET TABLE t1 READONLY false;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r311 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*u0*/SET TABLE t1 READONLY false;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r3 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*u0*/SET TABLE t1 READONLY false;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r31 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*e*/SET TABLE t1 READONLY false;

+

+-- Ditto for table privilege

+CONNECT USER SA PASSWORD "";

+DROP TABLE t1 IF exists;

+CREATE TABLE t1(i int);

+/*u1*/INSERT INTO t1 VALUES(1);

+COMMIT;

+/*s*/DROP USER peon1;

+/*s*/DROP ROLE r1;

+/*s*/DROP ROLE r2;

+/*s*/DROP ROLE r3;

+/*s*/DROP ROLE r31;

+/*s*/DROP ROLE r311;

+/*u0*/CREATE ROLE r1;

+/*u0*/CREATE ROLE r2;

+/*u0*/CREATE ROLE r3;

+/*u0*/CREATE ROLE r31;

+/*u0*/CREATE ROLE r311;

+/*u0*/GRANT r31 to r3;

+/*u0*/GRANT SELECT ON t1 TO r1;

+/*u0*/GRANT SELECT ON t1 TO r2;

+/*u0*/GRANT SELECT ON t1 TO r3;

+/*u0*/GRANT SELECT ON t1 TO r31;

+/*u0*/GRANT SELECT ON t1 TO r311;

+/*u0*/GRANT r311 TO r31;

+CREATE USER peon1 PASSWORD password;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO peon1;

+CONNECT USER peon1 PASSWORD password;

+/*e*/SELECT * FROM t1;

+CONNECT USER sa PASSWORD "";

+/*u0*/GRANT SELECT ON t1 TO peon1;

+/*u0*/GRANT r1 TO peon1;

+/*u0*/GRANT r2 TO peon1;

+/*u0*/GRANT r3 TO peon1;

+/*u0*/GRANT r31 TO peon1;

+/*u0*/GRANT r311 TO peon1;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+-- Start revoking, piecemeal

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE SELECT ON t1 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r1 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+CONNECT USER sa PASSWORD "";

+/*u0*/DROP ROLE r2;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r311 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r3 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*c1*/SELECT * FROM t1;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE r31 FROM peon1 RESTRICT;

+CONNECT USER peon1 PASSWORD password;

+/*e*/SELECT * FROM t1;

+

+CONNECT USER sa PASSWORD "";

+/*s*/DROP ROLE r1 CASCADE;

+/*s*/DROP ROLE r2 CASCADE;

+/*s*/DROP ROLE r3 CASCADE;

+/*U0*/ Workaround for bug where DDL will not Commit

+/*s*/CREATE TABLE bug_workaround (i int);

+/*s*/INSERT INTO bug_workaround VALUES(1);

+/*u0*/SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfSchemaCasc.txt b/testrun/hsqldb/TestSelfSchemaCasc.txt
new file mode 100644
index 0000000..40a8bab
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaCasc.txt
@@ -0,0 +1,79 @@
+-- schema TESTS WRT cascading

+

+/*u0*/SET SCHEMA information_schema;

+

+/*u0*/create user sa1 password "sa1" admin;

+/*u0*/create user sa2 password "sa2" admin;

+/*u0*/create user sa3 password "sa3" admin;

+

+/*u0*/create role r1;

+/*u0*/create role r2;

+/*u0*/create role r3;

+

+/*u0*/create schema s1 authorization sa1;

+/*u0*/create schema s2 authorization dba;

+/*u0*/create schema s3 authorization r1;

+

+-- These should have no effect on direct or indirect schema drops, since

+-- only DIRECT schema owners incur dependencies that prevent deletions.

+/*u0*/grant r1 to r2;

+/*u0*/grant r2 to sa2;

+

+/*e*/drop role r1;

+/*e*/drop user sa1;

+

+/*u0*/CREATE TABLE s1.t1(i int);

+/*u0*/CREATE TABLE s2.t2(i int);

+/*u0*/CREATE TABLE s3.t3(i int);

+

+-- Can't drop schemas which contain objects without CASCADE option

+/*e*/drop schema s1;

+/*e*/drop schema s2;

+/*e*/drop schema s3;

+/*e*/drop user sa1;

+

+/*c1*/SELECT * FROM schemata WHERE schema_name = 'S1';

+/*c1*/SELECT * FROM schemata WHERE schema_name = 'S2';

+/*c1*/SELECT * FROM schemata WHERE schema_name = 'S3';

+/*c1*/SELECT * FROM system_tables

+    WHERE table_schem = 'S1' AND table_name = 'T1';

+/*c1*/SELECT * FROM system_tables

+    WHERE table_schem = 'S2' AND table_name = 'T2';

+/*c1*/SELECT * FROM system_tables

+    WHERE table_schem = 'S3' AND table_name = 'T3';

+

+-- DROP USER... CASCADEs invoke DROP SCHEMA... CASCADEs.

+/*u0*/DROP USER sa3;

+/*u0*/DROP USER sa2;

+/*u0*/DROP USER sa1 CASCADE;

+/*e*/drop role r1;

+

+/*c0*/SELECT * FROM schemata WHERE schema_name = 'S1';

+/*c1*/SELECT * FROM schemata WHERE schema_name = 'S2';

+/*c1*/SELECT * FROM schemata WHERE schema_name = 'S3';

+/*c0*/SELECT * FROM system_tables

+    WHERE table_schem = 'S1' AND table_name = 'T1';

+/*c1*/SELECT * FROM system_tables

+    WHERE table_schem = 'S2' AND table_name = 'T2';

+/*c1*/SELECT * FROM system_tables

+    WHERE table_schem = 'S3' AND table_name = 'T3';

+

+/*u0*/drop role r1 CASCADE;

+/*c0*/SELECT * FROM schemata WHERE schema_name = 'S1';

+/*c1*/SELECT * FROM schemata WHERE schema_name = 'S2';

+/*c0*/SELECT * FROM schemata WHERE schema_name = 'S3';

+/*c0*/SELECT * FROM system_tables

+    WHERE table_schem = 'S1' AND table_name = 'T1';

+/*c1*/SELECT * FROM system_tables

+    WHERE table_schem = 'S2' AND table_name = 'T2';

+/*c0*/SELECT * FROM system_tables

+    WHERE table_schem = 'S3' AND table_name = 'T3';

+

+/*s*/DROP role r2 CASCADE;

+/*s*/DROP user sa2 CASCADE;

+/*s*/DROP user sa3 CASCADE;

+

+/*U0*/ Workaround for bug where DDL will not Commit

+/*s*/CREATE TABLE bug_workaround (i int);

+/*s*/INSERT INTO bug_workaround VALUES(1);

+/*u0*/SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfSchemaMisc.txt b/testrun/hsqldb/TestSelfSchemaMisc.txt
new file mode 100644
index 0000000..052bf60
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaMisc.txt
@@ -0,0 +1,18 @@
+drop schema schemafk1 if exists

+drop schema schemafk2 if exists

+create schema schemafk1 authorization dba;

+create table schemafk1.table1 ( table1_id integer primary key);

+create schema schemafk2 authorization dba;

+create table schemafk2.table2 (table2_id integer primary key, table1_id

+ integer, foreign key (table1_id) references schemafk1.table1);

+create table schemafk2.table3 (table3_id integer primary key, table1_id integer);

+alter table schemafk2.table3 add constraint fktbl3 foreign key (table1_id)

+ references schemafk1.table1;

+create table schemafk2.table4 (table4_id integer primary key, table1_id integer);

+alter table schemafk2.table4 add constraint fktbl4 foreign key (table1_id)

+ references schemafk1.table1 (table1_id);

+

+comment on table schemafk1.table1 is 'a short table comment';

+comment on column schemafk1.table1.table1_id is 'a short column comment';

+

+/*c2*/select * from information_schema.system_comments where object_schema='SCHEMAFK1'

diff --git a/testrun/hsqldb/TestSelfSchemaPerCachTbl1.txt b/testrun/hsqldb/TestSelfSchemaPerCachTbl1.txt
new file mode 100644
index 0000000..2bde1f1
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaPerCachTbl1.txt
@@ -0,0 +1,40 @@
+-- CREATE AND INITIALIZE CACHED TABLE OBJECTS

+

+-- This CREATES the schema-specific objects to be used for

+-- schema-specific persistence tests.

+

+

+--                  ******************************       CACH Tables

+--DROP TABLE nosuch;

+DROP TABLE ctblt1 IF exists;

+DROP TABLE ctblt2 IF exists;

+DROP TABLE ctblt3 IF exists;

+DROP TABLE ctblt4 IF exists;

+DROP TABLE ctblt101 IF exists;

+DROP TABLE tblj1 IF exists;

+/*u0*/CREATE CACHED TABLE ctblt1 (i int);

+/*u0*/CREATE CACHED TABLE public.ctblt2 (i int);

+/*u0*/CREATE CACHED TABLE ctblt3 (i int);

+/*u0*/CREATE CACHED TABLE tblj1 (i int, vc varchar(10));  -- For testing Joins

+/*e*/CREATE CACHED TABLE information_schema.ctblt101 (i int);

+/*e*/CREATE CACHED TABLE ctblt1 (i int); -- Create existing object

+/*e*/CREATE CACHED TABLE public.ctblt1 (i int); -- Create existing object

+/*e*/CREATE CACHED TABLE information_schema.system_users (i int); -- Existing object

+/*e*/INSERT INTO other.ctblt1 values(0);

+/*e*/INSERT INTO information_schema.ctblt1 values(1);

+/*u1*/INSERT INTO ctblt1 values(0);

+/*u1*/INSERT INTO public.ctblt1 values(100);

+-- Test one update that will be persisted (most update tests won't be)

+/*u1*/UPDATE public.ctblt1 set i = 1 WHERE i = 100;

+/*u1*/INSERT INTO tblj1 values(1, 'one');

+CREATE TABLE public.ctblt4 AS (SELECT * FROM public.ctblt1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM public.ctblt4;

+-- Work-around

+ALTER TABLE ctblt1 ADD CONSTRAINT cpk_workaround PRIMARY KEY(i);

+

+--                  ******************************       ALTERs

+-- Add tests when time permits.

+

+

+-- This to test recovery from .log files.

+SHUTDOWN IMMEDIATELY;

diff --git a/testrun/hsqldb/TestSelfSchemaPerCachTbl2.txt b/testrun/hsqldb/TestSelfSchemaPerCachTbl2.txt
new file mode 100644
index 0000000..96acbfd
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaPerCachTbl2.txt
@@ -0,0 +1,138 @@
+-- TEST CACHED TABLE OBJECTS

+

+-- This TESTS the schema-specific objects created in a previous script.

+

+CREATE USER otheruser PASSWORD otheruser;

+

+

+--                  ******************************       CACH Tables

+/*c2*/SELECT * FROM ctblt1;

+/*c1*/SELECT * FROM ctblt1 WHERE i = 0;

+/*c2*/SELECT * FROM ctblt1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM ctblt1 WHERE i < 1;

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i in (SELECT i FROM tblj1);

+/*c0*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM public.ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.ctblt1 WHERE ctblt1.i in (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i in (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM public.tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT tblj1.i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i in (SELECT tblj1.i FROM tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT tblj1.i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM public.tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT tblj1.i FROM tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE i in (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM public.ctblt1 WHERE i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.ctblt1 WHERE i in (SELECT i FROM tblj1);

+/*c0*/SELECT * FROM public.ctblt1 WHERE i = (SELECT i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE i in (SELECT i FROM public.tblj1);

+/*c0*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM public.tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT tblj1.i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE i in (SELECT tblj1.i FROM tblj1);

+/*c0*/SELECT * FROM ctblt1 WHERE i = (SELECT tblj1.i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM public.tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT tblj1.i FROM tblj1 WHERE tblj1.i = 1);

+/*e*/SELECT * FROM system_users WHERE user_name = 'SA';

+/*e*/SELECT * FROM other.ctblt1;

+/*e*/SELECT * FROM other.system_users;

+/*e*/SELECT * FROM information_schema.ctblt1;

+/*e*/SELECT * FROM public.system_users;

+/*c2*/SELECT * FROM public.ctblt1;

+/*c1*/SELECT * FROM information_schema.system_users WHERE user_name = 'SA';

+/*c1*/SELECT * FROM public.ctblt1 WHERE i = 0;

+/*e*/SELECT * FROM other.ctblt1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.ctblt1 WHERE i = 0;

+/*c1*/SELECT * FROM public.ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT * FROM ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT * FROM public.ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT * FROM ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM public.ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM public.ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM public.ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM public.ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM ctblt1, tblj1 lbla WHERE ctblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM ctblt1 lblb, tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM ctblt1 lblb, tblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM public.ctblt1, tblj1 lbla WHERE ctblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM public.ctblt1 lblb, tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM public.ctblt1 lblb, tblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM ctblt1, public.tblj1 lbla WHERE ctblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM ctblt1 lblb, public.tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM ctblt1 lblb, public.tblj1 lbla WHERE lblb.i = lbla.i;

+/*u0*/SET TABLE ctblt1 READONLY true;

+/*e*/UPDATE ctblt1 set i = 11 WHERE i = 1;

+/*u0*/SET TABLE public.ctblt1 READONLY true;

+/*e*/SET TABLE information_schema.ctblt1 READONLY true;

+/*e*/SET TABLE other.ctblt1 READONLY true;

+/*u0*/SET TABLE ctblt1 READONLY false;

+/*u0*/SET TABLE public.ctblt1 READONLY false;

+/*c2*/SELECT i FROM ctblt1;

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+COMMIT;

+SET AUTOCOMMIT false;

+/*u1*/UPDATE ctblt1 set i = 11 WHERE i = 1;

+/*u1*/UPDATE ctblt1 set ctblt1.i = 12 WHERE i = 11;

+/*u1*/UPDATE ctblt1 set ctblt1.i = 13 WHERE ctblt1.i = 12;

+/*u1*/UPDATE public.ctblt1 set i = 14 WHERE i = 13;

+/*u1*/UPDATE public.ctblt1 set ctblt1.i = 15 WHERE i = 14;

+/*u1*/UPDATE public.ctblt1 set ctblt1.i = 16 WHERE ctblt1.i = 15;

+/*e*/UPDATE other.ctblt1 set ctblt1.i = 17 WHERE ctblt1.i = 16;

+/*e*/UPDATE information_schema.ctblt1 set ctblt1.i = 17 WHERE ctblt1.i = 16;

+/*u1*/UPDATE ctblt1 ali set i = 17 WHERE i = 16;

+/*u1*/UPDATE ctblt1 ali set ali.i = 18 WHERE i = 17;

+/*u1*/UPDATE ctblt1 ali set ali.i = 19 WHERE ali.i = 18;

+/*u1*/UPDATE ctblt1 ali set i = 20 WHERE ali.i = 19;

+/*u1*/UPDATE public.ctblt1 ali set i = 21 WHERE i = 20;

+/*u1*/UPDATE public.ctblt1 ali set ali.i = 22 WHERE i = 21;

+/*u1*/UPDATE public.ctblt1 ali set ali.i = 23 WHERE ali.i = 22;

+/*u1*/UPDATE public.ctblt1 ali set i = 24 WHERE ali.i = 23;

+/*e*/UPDATE other.ctblt1 ali set i = 25 WHERE ali.i = 24;

+/*e*/UPDATE other.ctblt1 ali set i = 25 WHERE .i = 24;

+/*e*/UPDATE other.ctblt1 set i = 25 WHERE i = 24;

+/*e*/DELETE FROM other.ctblt1 ali WHERE ali.i = 24;

+/*e*/DELETE FROM other.ctblt1 ali;

+/*e*/DELETE FROM other.ctblt1 set WHERE i = 24;

+/*e*/DELETE FROM other.ctblt1 WHERE i = 24;

+/*e*/DELETE FROM system_information.tblj1 WHERE tblj1.i = 1;

+/*u1*/DELETE FROM ctblt1 WHERE i = 0;

+/*u1*/DELETE FROM public.ctblt1 WHERE i = 24;

+/*u1*/DELETE FROM public.tblj1 WHERE tblj1.i = 1;

+ROLLBACK;

+/*c2*/SELECT i FROM ctblt1;

+/*u0*/GRANT ALL ON ctblt1 TO otheruser;

+/*u0*/GRANT ALL ON public.ctblt2 TO otheruser;

+/*e*/GRANT ALL ON other.ctblt3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.ctblt3 TO otheruser;

+/*u0*/REVOKE ALL ON ctblt1 FROM otheruser RESTRICT;

+/*u0*/REVOKE ALL ON public.ctblt2 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON other.ctblt3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.ctblt3 FROM otheruser RESTRICT;

+/*e*/DROP TABLE other.ctblt3;

+/*e*/DROP TABLE information_schema.ctblt4;

+/*e*/DROP TABLE ctblt101;

+/*e*/DROP TABLE public.ctblt101;

+/*u0*/DROP TABLE ctblt101 IF EXISTS;

+/*u0*/DROP TABLE public.ctblt101 IF EXISTS;

+-- Should "DROP TABLE nonexistentschema.notable IF EXISTS" work?

+/*u0*/DROP TABLE other.system_users IF exists;

+/*u0*/DROP TABLE system_users IF exists;

+

+--                  ******************************       ALTERs

+-- Add tests when time permits.

+

+DROP USER otheruser;

+

+

+-- This to test .script persistence.

+SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfSchemaPersistA1.txt b/testrun/hsqldb/TestSelfSchemaPersistA1.txt
new file mode 100644
index 0000000..163da35
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaPersistA1.txt
@@ -0,0 +1,439 @@
+-- CREATE AND INITIALIZE OBJECTS

+

+-- This CREATES the schema-specific objects to be used for

+-- schema-specific persistence tests.

+-- (See the *C[12].txt scripts for similar tests of ALTER comands (which

+-- this script purposefully omits).

+

+

+--                  ******************************       MEM Tables

+--DROP TABLE nosuch;

+DROP TABLE tblt1 IF exists;

+DROP TABLE tblt2 IF exists;

+DROP TABLE tblt3 IF exists;

+DROP TABLE tblt4 IF exists;

+DROP TABLE tblt101 IF exists;

+DROP TABLE tblj1 IF exists;

+/*u0*/CREATE TABLE tblt1 (i int);

+/*u0*/CREATE TABLE public.tblt2 (i int);

+/*u0*/CREATE TABLE tblt3 (i int);

+/*u0*/CREATE TABLE tblj1 (i int, vc varchar(10));  -- For testing Joins

+/*e*/CREATE TABLE information_schema.tblt101 (i int);

+/*e*/CREATE TABLE tblt1 (i int); -- Create existing object

+/*e*/CREATE TABLE public.tblt1 (i int); -- Create existing object

+/*e*/CREATE TABLE information_schema.system_users (i int); -- Existing object

+/*e*/INSERT INTO other.tblt1 values(0);

+/*e*/INSERT INTO information_schema.tblt1 values(1);

+/*u1*/INSERT INTO tblt1 values(0);

+/*u1*/INSERT INTO public.tblt1 values(100);

+-- Test one update that will be persisted (most update tests won't be)

+/*u1*/UPDATE public.tblt1 set i = 1 WHERE i = 100;

+/*u1*/INSERT INTO tblj1 values(1, 'one');

+CREATE TABLE public.tblt4 AS (SELECT * FROM public.tblt1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM public.tblt4;

+

+--                  ******************************       CACH Tables

+--DROP TABLE nosuch;

+DROP TABLE ctblt1 IF exists;

+DROP TABLE ctblt2 IF exists;

+DROP TABLE ctblt3 IF exists;

+DROP TABLE ctblt4 IF exists;

+DROP TABLE ctblt101 IF exists;

+DROP TABLE tblj1 IF exists;

+/*u0*/CREATE CACHED TABLE ctblt1 (i int);

+/*u0*/CREATE CACHED TABLE public.ctblt2 (i int);

+/*u0*/CREATE CACHED TABLE ctblt3 (i int);

+/*u0*/CREATE CACHED TABLE tblj1 (i int, vc varchar(10));  -- For testing Joins

+/*e*/CREATE CACHED TABLE information_schema.ctblt101 (i int);

+/*e*/CREATE CACHED TABLE ctblt1 (i int); -- Create existing object

+/*e*/CREATE CACHED TABLE public.ctblt1 (i int); -- Create existing object

+/*e*/CREATE CACHED TABLE information_schema.system_users (i int); -- Existing object

+/*e*/INSERT INTO other.ctblt1 values(0);

+/*e*/INSERT INTO information_schema.ctblt1 values(1);

+/*u1*/INSERT INTO ctblt1 values(0);

+/*u1*/INSERT INTO public.ctblt1 values(100);

+-- Test one update that will be persisted (most update tests won't be)

+/*u1*/UPDATE public.ctblt1 set i = 1 WHERE i = 100;

+/*u1*/INSERT INTO tblj1 values(1, 'one');

+CREATE TABLE public.ctblt4 AS (SELECT * FROM public.ctblt1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM public.ctblt4;

+

+--                  ******************************       Views

+DROP VIEW vwv1 IF exists;

+DROP VIEW vwv2 IF exists;

+DROP VIEW vwv3 IF exists;

+DROP VIEW vwv4 IF exists;

+DROP VIEW vwv5 IF exists;

+DROP VIEW vwv6 IF exists;

+DROP VIEW vwv7 IF exists;

+DROP VIEW vwv8 IF exists;

+DROP VIEW vwv9 IF exists;

+DROP VIEW vwv10 IF exists;

+DROP VIEW vwv11 IF exists;

+DROP VIEW vwv12 IF exists;

+DROP VIEW vwv13 IF exists;

+DROP VIEW vwv14 IF exists;

+DROP VIEW vwv15 IF exists;

+DROP VIEW vwv16 IF exists;

+DROP VIEW vwv17 IF exists;

+DROP VIEW vwv18 IF exists;

+DROP VIEW vwv19 IF exists;

+DROP VIEW vwv20 IF exists;

+DROP VIEW vwv21 IF exists;

+DROP VIEW vwv22 IF exists;

+DROP VIEW vwv23 IF exists;

+DROP VIEW vwv24 IF exists;

+DROP VIEW vwv25 IF exists;

+DROP VIEW vwv26 IF exists;

+DROP VIEW vwv101 IF exists;

+DROP TABLE vwt1 IF exists;

+DROP TABLE vwt2 IF exists;

+DROP TABLE vwj1 IF exists;

+CREATE TABLE vwt1 (i int);

+CREATE TABLE vwj1 (i int, vc varchar(10));

+INSERT INTO vwt1 values(0);

+INSERT INTO vwt1 values(1);

+INSERT INTO vwj1 values(1, 'one');

+/*e*/CREATE VIEW information_schema.vwv101 AS

+    SELECT * FROM information_schema.system_users;

+/*e*/CREATE VIEW information_schema.vwv101 AS

+    SELECT * FROM vwt1;

+-- I think we prohibit ANY manual creation of objects in information_schema.

+/*e*/CREATE VIEW information_schema.vwv4 AS

+    SELECT * FROM public.vwt1;

+/*e*/CREATE VIEW vwv101 AS SELECT * FROM other.vwt1;

+/*e*/CREATE VIEW public.vwv101 AS SELECT * FROM other.vwt1;

+/*e*/CREATE VIEW other.vwv101 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW other.vwv101 AS SELECT *

+    FROM information_schema.system_users, public.vwj1 WHERE user_name = vc;

+/*e*/CREATE VIEW other.vwv101 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE information_schema.user_name = vc;

+/*e*/CREATE VIEW other.vwv101 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE information_schema.user_name = public.vc;

+/*e*/CREATE VIEW information_schema.vwv101 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW information_schema.vwv101 AS SELECT *

+    FROM information_schema.system_users, public.vwj1 WHERE user_name = vc;

+/*e*/CREATE VIEW information_schema.vwv101 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE information_schema.user_name = vc;

+/*e*/CREATE VIEW information_schema.vwv101 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE information_schema.user_name = public.vc;

+/*e*/CREATE VIEW vwv101 AS SELECT * FROM system_users, vwj1 WHERE user_name = vc;

+/*e*/CREATE VIEW vwv101 AS SELECT *

+    FROM information_schema.system_users, information_schema.vwj1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW vwv101 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE other.user_name = vc;

+/*e*/CREATE VIEW vwv101 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE public.user_name = public.vc;

+/*u0*/CREATE VIEW vwv1 AS SELECT * FROM vwt1;

+/*e*/CREATE VIEW public.vwv1 AS SELECT * FROM vwt1; -- Create existing object

+/*e*/CREATE VIEW public.vwv1 AS SELECT * FROM public.vwt1; -- Existing object

+/*u0*/CREATE VIEW public.vwv2 AS SELECT * FROM vwt1;

+/*u0*/CREATE VIEW public.vwv3 AS SELECT * FROM public.vwt1;

+/*u0*/CREATE VIEW public.vwv4 AS SELECT * FROM vwt1 WHERE i = 0;

+/*u0*/CREATE VIEW public.vwv5 AS SELECT * FROM vwt1 WHERE i < 1;

+/*u0*/CREATE VIEW public.vwv6 AS SELECT * FROM information_schema.system_users

+    WHERE user_name = 'SA';

+/*u0*/CREATE VIEW vwv7 AS SELECT * FROM information_schema.system_users;

+/*u0*/CREATE VIEW vwv8 AS SELECT * FROM information_schema.system_users

+    WHERE user_name = 'SA';

+/*u0*/CREATE VIEW vwv9 AS SELECT * FROM information_schema.system_users, vwj1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW vwv10 AS SELECT *

+    FROM information_schema.system_users, public.vwj1 WHERE user_name = vc;

+/*u0*/CREATE VIEW vwv11 AS SELECT * FROM information_schema.system_users, vwj1

+    WHERE system_users.user_name = vc;

+/*u0*/CREATE VIEW vwv12 AS SELECT * FROM information_schema.system_users, vwj1

+    WHERE system_users.user_name = vwj1.vc;

+/*u0*/CREATE VIEW public.vwv13 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW public.vwv14 AS SELECT *

+    FROM information_schema.system_users, public.vwj1 WHERE user_name = vc;

+/*u0*/CREATE VIEW public.vwv15 AS SELECT *

+    FROM information_schema.system_users, vwj1

+    WHERE system_users.user_name = vc;

+/*u0*/CREATE VIEW public.vwv16 AS SELECT *

+    FROM information_schema.system_users, public.vwj1

+    WHERE system_users.user_name = vwj1.vc;

+/*u0*/CREATE VIEW vwv17 AS SELECT * FROM information_schema.system_users, vwj1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW vwv18 AS SELECT *

+    FROM information_schema.system_users, public.vwj1 WHERE user_name = vc;

+/*u0*/CREATE VIEW vwv19 (v1, v2, v3) AS SELECT * FROM vwt1, vwj1 WHERE vwt1.i = vwj1.i;

+/*u0*/CREATE VIEW vwv20 (v1, v2, v3) AS SELECT * FROM public.vwt1, public.vwj1 WHERE vwt1.i = vwj1.i;

+/*u0*/CREATE VIEW vwv21 (v1, v2, v3) AS SELECT * FROM public.vwt1, vwj1 WHERE vwt1.i = vwj1.i;

+/*u0*/CREATE VIEW vwv22 (v1, v2, v3) AS SELECT * FROM vwt1, public.vwj1 WHERE vwt1.i = vwj1.i;

+/*u0*/CREATE VIEW public.vwv23 (v1, v2, v3) AS

+    SELECT * FROM vwt1, vwj1 WHERE vwt1.i = vwj1.i;

+/*u0*/CREATE VIEW public.vwv24 (v1, v2, v3) AS

+    SELECT * FROM public.vwt1, public.vwj1 WHERE vwt1.i = vwj1.i;

+/*u0*/CREATE VIEW public.vwv25 (v1, v2, v3) AS SELECT * FROM public.vwt1, vwj1 WHERE vwt1.i = vwj1.i;

+/*u0*/CREATE VIEW public.vwv26 (v1, v2, v3) AS SELECT * FROM vwt1, public.vwj1 WHERE vwt1.i = vwj1.i;

+/*u0*/CREATE VIEW vwv28 AS

+    SELECT * FROM vwt1 WHERE i in (0, 1, 11, 12);

+/*u0*/CREATE VIEW public.vwv29 AS

+    SELECT * FROM vwt1 WHERE i < 1;

+/*u0*/CREATE VIEW vwv30 AS

+    SELECT * FROM vwt1 WHERE vwt1.i = (SELECT i FROM vwj1);

+/*u0*/CREATE VIEW vwv31 AS

+    SELECT * FROM vwt1 WHERE vwt1.i in (SELECT i FROM vwj1);

+/*u0*/CREATE VIEW vwv32 AS

+    SELECT * FROM vwt1 WHERE vwt1.i = (SELECT i FROM vwj1 WHERE i = 0);

+/*u0*/CREATE VIEW vwv33 AS

+    SELECT * FROM public.vwt1 WHERE vwt1.i = (SELECT i FROM vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv34 AS

+    SELECT * FROM public.vwt1 WHERE vwt1.i in (SELECT i FROM vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv35 AS

+    SELECT * FROM public.vwt1 WHERE vwt1.i = (SELECT i FROM vwj1 WHERE i = 0);

+/*u0*/CREATE VIEW PUBLIC.vwv36 AS

+    SELECT * FROM vwt1 WHERE vwt1.i = (SELECT i FROM public.vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv37 AS

+    SELECT * FROM vwt1 WHERE vwt1.i in (SELECT i FROM public.vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv38 AS

+    SELECT * FROM vwt1 WHERE vwt1.i = (SELECT i FROM public.vwj1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv39 AS

+    SELECT * FROM vwt1 WHERE vwt1.i = (SELECT vwj1.i FROM public.vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv40 AS

+    SELECT * FROM vwt1 WHERE vwt1.i in (SELECT vwj1.i FROM vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv41 AS

+    SELECT * FROM vwt1 WHERE vwt1.i = (SELECT vwj1.i FROM vwj1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv42 AS

+    SELECT * FROM vwt1 WHERE vwt1.i = (SELECT i FROM public.vwj1 WHERE vwj1.i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv43 AS

+    SELECT * FROM vwt1 WHERE vwt1.i = (SELECT vwj1.i FROM vwj1 WHERE vwj1.i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv44 AS

+    SELECT * FROM vwt1 WHERE i = (SELECT i FROM vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv45 AS

+    SELECT * FROM vwt1 WHERE i in (SELECT i FROM vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv46 AS

+    SELECT * FROM vwt1 WHERE i = (SELECT i FROM vwj1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv47 AS

+    SELECT * FROM public.vwt1 WHERE i = (SELECT i FROM vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv48 AS

+    SELECT * FROM public.vwt1 WHERE i in (SELECT i FROM vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv49 AS

+    SELECT * FROM public.vwt1 WHERE i = (SELECT i FROM vwj1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv50 AS

+    SELECT * FROM vwt1 WHERE i = (SELECT i FROM public.vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv51 AS

+    SELECT * FROM vwt1 WHERE i in (SELECT i FROM public.vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv52 AS

+    SELECT * FROM vwt1 WHERE i = (SELECT i FROM public.vwj1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv53 AS

+    SELECT * FROM vwt1 WHERE i = (SELECT vwj1.i FROM public.vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv54 AS

+    SELECT * FROM vwt1 WHERE i in (SELECT vwj1.i FROM vwj1);

+/*u0*/CREATE VIEW PUBLIC.vwv55 AS

+    SELECT * FROM vwt1 WHERE i = (SELECT vwj1.i FROM vwj1 WHERE i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv56 AS

+    SELECT * FROM vwt1 WHERE i = (SELECT i FROM public.vwj1 WHERE vwj1.i = 1);

+/*u0*/CREATE VIEW PUBLIC.vwv57 AS

+    SELECT * FROM vwt1 WHERE i = (SELECT vwj1.i FROM vwj1 WHERE vwj1.i = 1);

+/*e*/DROP VIEW other.vwv1;

+/*e*/DROP VIEW information_schema.vwv2;

+

+--                  ******************************       MEM Indexes

+DROP INDEX indi1 IF exists;

+DROP INDEX indi2 IF exists;

+DROP INDEX indi3 IF exists;

+DROP INDEX indi4 IF exists;

+DROP INDEX indi5 IF exists;

+DROP TABLE indt1 IF exists;

+DROP TABLE indt2 IF exists;

+DROP TABLE indt3 IF exists;

+DROP TABLE indt4 IF exists;

+DROP TABLE indt101 IF exists;

+CREATE TABLE indt1 (i int);

+INSERT INTO indt1 values(0);

+INSERT INTO indt1 values(1);

+CREATE TABLE indt2 (i int);

+INSERT INTO indt2 values(0);

+INSERT INTO indt2 values(1);

+CREATE TABLE indt3 (i int);

+INSERT INTO indt3 values(0);

+INSERT INTO indt3 values(1);

+CREATE TABLE indt4 (i int);

+INSERT INTO indt4 values(0);

+INSERT INTO indt4 values(1);

+/*e*/CREATE UNIQUE INDEX other.indi101 on indt101(i);

+/*e*/CREATE INDEX other.indi101 on indt101(i);

+CREATE TABLE indt101 (i int);

+INSERT INTO indt101 values(0);

+INSERT INTO indt101 values(1);

+/*e*/CREATE UNIQUE INDEX information_schema.indi101 on indt101(i int);

+/*u0*/CREATE UNIQUE INDEX indi1 ON indt1(i);

+/*e*/CREATE UNIQUE INDEX indi1 ON indt1(i); -- Create existing object

+/*u0*/CREATE UNIQUE INDEX public.indi2 ON indt2(i);

+/*e*/CREATE UNIQUE INDEX public.indi2 ON indt2(i); -- Create existing object

+/*u0*/CREATE UNIQUE INDEX indi3 ON indt3(i);

+/*u0*/CREATE UNIQUE INDEX indi4 ON indt4(i);

+-- The error message says that the schema name is invalid.  Problem here

+-- is creating an index in a different schema than the target table.

+/*e*/CREATE UNIQUE INDEX indi5 ON information_schema.system_users(user_name);

+/*e*/DROP INDEX other.indi1;

+/*e*/DROP INDEX information_schema.indi2;

+

+--                  ******************************      CACH Indexes

+DROP INDEX cindi1 IF exists;

+DROP INDEX cindi2 IF exists;

+DROP INDEX cindi3 IF exists;

+DROP INDEX cindi4 IF exists;

+DROP INDEX cindi5 IF exists;

+DROP TABLE cindt1 IF exists;

+DROP TABLE cindt2 IF exists;

+DROP TABLE cindt3 IF exists;

+DROP TABLE cindt4 IF exists;

+DROP TABLE cindt101 IF exists;

+CREATE TABLE cindt1 (i int);

+INSERT INTO cindt1 values(0);

+INSERT INTO cindt1 values(1);

+CREATE TABLE cindt2 (i int);

+INSERT INTO cindt2 values(0);

+INSERT INTO cindt2 values(1);

+CREATE TABLE cindt3 (i int);

+INSERT INTO cindt3 values(0);

+INSERT INTO cindt3 values(1);

+CREATE TABLE cindt4 (i int);

+INSERT INTO cindt4 values(0);

+INSERT INTO cindt4 values(1);

+/*e*/CREATE UNIQUE INDEX other.cindi101 on cindt101(i);

+CREATE TABLE cindt101 (i int);

+INSERT INTO cindt101 values(0);

+INSERT INTO cindt101 values(1);

+/*e*/CREATE UNIQUE INDEX information_schema.cindi101 on cindt101(i int);

+/*u0*/CREATE UNIQUE INDEX cindi1 ON cindt1(i);

+/*e*/CREATE UNIQUE INDEX cindi1 ON cindt1(i); -- Create existing object

+/*u0*/CREATE UNIQUE INDEX public.cindi2 ON cindt2(i);

+/*e*/CREATE UNIQUE INDEX public.cindi2 ON cindt2(i); -- Create existing object

+/*u0*/CREATE UNIQUE INDEX cindi3 ON cindt3(i);

+/*u0*/CREATE UNIQUE INDEX cindi4 ON cindt4(i);

+-- The error message says that the schema name is invalid.  Problem here

+-- is creating an index in a different schema than the target table.

+/*e*/CREATE UNIQUE INDEX cindi5 ON information_schema.system_users(user_name);

+/*e*/DROP INDEX other.cindi1;

+/*e*/DROP INDEX information_schema.cindi2;

+

+--                  ******************************       Sequences

+DROP TABLE seqt1 IF EXISTS;

+CREATE TABLE seqt1 (i int);

+INSERT INTO seqt1 VALUES(10);

+-- No "IF EXISTS" allowed with sequences, so can't verify they don't exists.

+/*e*/CREATE SEQUENCE other.s101;

+/*e*/CREATE SEQUENCE information_schema.s101;

+/*u0*/CREATE SEQUENCE s1;

+/*e*/CREATE SEQUENCE s1; -- Create existing object

+/*u0*/CREATE SEQUENCE public.s2;

+/*e*/CREATE SEQUENCE public.s2; -- Create existing object

+-- To test persisting of incremented value

+/*r0*/SELECT next value FOR s2 FROM seqt1;

+/*r1*/SELECT next value FOR s2 FROM seqt1;

+

+--                  ******************************       Triggers

+DROP TABLE trgt1 IF EXISTS;

+DROP TABLE trgt2 IF EXISTS;

+DROP TABLE trgt3 IF EXISTS;

+DROP TABLE trgt4 IF EXISTS;

+DROP TABLE trgt101 IF EXISTS;

+-- No "IF EXISTS" allowed with triggers, so can't verify they don't exists.

+CREATE TABLE trgt1 (i int);

+CREATE TABLE trgt2 (i int);

+CREATE TABLE trgt3 (i int);

+CREATE TABLE trgt4 (i int);

+/*e*/CREATE TRIGGER other.trgtrig101

+    AFTER INSERT ON trgt1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER trgtrig101

+    AFTER INSERT ON other.trgt1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER trgtrig101

+    AFTER INSERT ON information_schema.trgt1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER trgtrig101

+    AFTER INSERT ON trgt101 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TRIGGER trgtrig1

+    AFTER INSERT ON trgt1 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TRIGGER public.trgtrig2

+    AFTER INSERT ON trgt2 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TRIGGER trgtrig3

+    AFTER INSERT ON public.trgt3 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TRIGGER public.trgtrig4

+    AFTER INSERT ON public.trgt4 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/DROP TRIGGER information_schema.trgtrig1;

+/*e*/DROP TRIGGER other.trgtrig1;

+

+--                  ******************************       Constraints

+DROP TABLE cont1 IF EXISTS;

+DROP TABLE cont2 IF EXISTS;

+DROP TABLE cont3 IF EXISTS;

+DROP TABLE cont4 IF EXISTS;

+DROP TABLE cont5 IF EXISTS;

+DROP TABLE cont6 IF EXISTS;

+DROP TABLE cont7 IF EXISTS;

+DROP TABLE cont8 IF EXISTS;

+DROP TABLE cont9 IF EXISTS;

+DROP TABLE cont10 IF EXISTS;

+DROP TABLE cont11 IF EXISTS;

+DROP TABLE cont12 IF EXISTS;

+DROP TABLE cont13 IF EXISTS;

+DROP TABLE cont14 IF EXISTS;

+DROP TABLE cont15 IF EXISTS;

+DROP TABLE cont16 IF EXISTS;

+DROP TABLE cont17 IF EXISTS;

+DROP TABLE cont18 IF EXISTS;

+DROP TABLE cont19 IF EXISTS;

+DROP TABLE cont20 IF EXISTS;

+DROP TABLE cont101 IF EXISTS;

+CREATE TABLE conj1(i int, vc varchar(10), PRIMARY KEY (i));

+INSERT INTO conj1 values(1, 'one');

+-- No "IF EXISTS" allowed with constrs., so can't verify they don't exists.

+/*e*/CREATE TABLE other.cont101 (i int, CONSTRAINT conuc1 UNIQUE(i));

+/*e*/CREATE TABLE system_information.cont1 (i int, CONSTRAINT conuc1 UNIQUE(i));

+/*u0*/CREATE TABLE cont1 (i int, CONSTRAINT conuc1 UNIQUE(i));

+/*e*/CREATE TABLE cont1 (i int, CONSTRAINT conuc1 UNIQUE(i));

+/*e*/CREATE TABLE cont101 (i int, CONSTRAINT conuc1 UNIQUE(i)); -- conuc1 already exists

+/*e*/CREATE TABLE cont101 (i int, CONSTRAINT public.conuc1 UNIQUE(i)); -- ditto

+/*u0*/CREATE TABLE public.cont2 (i int, CONSTRAINT conuc2 UNIQUE(i));

+/*e*/CREATE TABLE public.cont101 (i int, CONSTRAINT conuc2 UNIQUE(i)); -- conuc2 already

+/*e*/CREATE TABLE public.cont101 (i int, CONSTRAINT public.conuc2 UNIQUE(i)); -- dit

+/*u0*/CREATE TABLE cont3 (i int, CONSTRAINT public.conuc3 UNIQUE(i));

+/*u0*/CREATE TABLE public.cont4 (i int, CONSTRAINT public.conuc4 UNIQUE(i));

+/*u0*/CREATE TABLE cont5 (i int, CONSTRAINT conpk5 PRIMARY KEY(i));

+/*u0*/CREATE TABLE public.cont6 (i int, CONSTRAINT conpk6 PRIMARY KEY(i));

+/*u0*/CREATE TABLE cont7 (i int, CONSTRAINT public.conpk7 PRIMARY KEY(i));

+/*u0*/CREATE TABLE public.cont8 (i int, CONSTRAINT public.conpk8 PRIMARY KEY(i));

+/*u0*/CREATE TABLE cont9 (i int, CONSTRAINT confk9 FOREIGN KEY(i) REFERENCES conj1(i));

+/*e*/CREATE TABLE cont101 (i int, CONSTRAINT confk9 FOREIGN KEY(i)

+    REFERENCES other.conj1(i));

+/*e*/CREATE TABLE cont101 (i int, CONSTRAINT confk9 FOREIGN KEY(i)

+    REFERENCES information_schema.conj1(i));

+/*u0*/CREATE TABLE public.cont10 (i int, CONSTRAINT confk10

+    FOREIGN KEY(i) REFERENCES conj1(i));

+/*u0*/CREATE TABLE cont11 (i int, CONSTRAINT public.confk11

+    FOREIGN KEY(i) REFERENCES conj1(i));

+/*u0*/CREATE TABLE public.cont12 (i int, CONSTRAINT public.confk12

+    FOREIGN KEY(i) REFERENCES conj1(i));

+/*u0*/CREATE TABLE cont13 (i int, CONSTRAINT confk13 FOREIGN KEY(i)

+    REFERENCES public.conj1(i));

+/*u0*/CREATE TABLE public.cont14 (i int, CONSTRAINT confk14

+    FOREIGN KEY(i) REFERENCES public.conj1(i));

+/*u0*/CREATE TABLE cont15 (i int, CONSTRAINT public.confk15

+    FOREIGN KEY(i) REFERENCES public.conj1(i));

+/*u0*/CREATE TABLE public.cont16 (i int, CONSTRAINT public.confk16

+    FOREIGN KEY(i) REFERENCES public.conj1(i));

+/*u0*/CREATE TABLE cont17 (i int, CONSTRAINT conc17 CHECK (i < 1));

+/*u0*/CREATE TABLE public.cont18 (i int, CONSTRAINT conc18 CHECK (i in (0, 2)));

+/*u0*/CREATE TABLE cont19 (i int, CONSTRAINT public.conc19 CHECK (i = 0));

+/*u0*/CREATE TABLE public.cont20 (i int, CONSTRAINT public.conc20 CHECK (i != 1));

+

+

+-- This to test recovery from .log files.

+COMMIT;

+SHUTDOWN IMMEDIATELY;

diff --git a/testrun/hsqldb/TestSelfSchemaPersistA2.txt b/testrun/hsqldb/TestSelfSchemaPersistA2.txt
new file mode 100644
index 0000000..9710739
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaPersistA2.txt
@@ -0,0 +1,525 @@
+-- TEST OBJECTS

+

+-- This TESTS the schema-specific objects created in a previous script.

+-- (See the *C[12].txt scripts for similar tests of ALTER comands (which

+-- this script purposefully omits).

+

+

+CREATE USER otheruser PASSWORD otheruser;

+

+--                  ******************************       MEM Tables

+/*c2*/SELECT * FROM tblt1;

+/*c1*/SELECT * FROM tblt1 WHERE i = 0;

+/*c2*/SELECT * FROM tblt1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM tblt1 WHERE i < 1;

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT i FROM tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i in (SELECT i FROM tblj1);

+/*c0*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM public.tblt1 WHERE tblt1.i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.tblt1 WHERE tblt1.i in (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.tblt1 WHERE tblt1.i = (SELECT i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i in (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT i FROM public.tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT tblj1.i FROM public.tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i in (SELECT tblj1.i FROM tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT tblj1.i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT i FROM public.tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM tblt1 WHERE tblt1.i = (SELECT tblj1.i FROM tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM tblt1 WHERE i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE i in (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE i = (SELECT i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM public.tblt1 WHERE i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.tblt1 WHERE i in (SELECT i FROM tblj1);

+/*c0*/SELECT * FROM public.tblt1 WHERE i = (SELECT i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM tblt1 WHERE i = (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE i in (SELECT i FROM public.tblj1);

+/*c0*/SELECT * FROM tblt1 WHERE i = (SELECT i FROM public.tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM tblt1 WHERE i = (SELECT tblj1.i FROM public.tblj1);

+/*c1*/SELECT * FROM tblt1 WHERE i in (SELECT tblj1.i FROM tblj1);

+/*c0*/SELECT * FROM tblt1 WHERE i = (SELECT tblj1.i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM tblt1 WHERE i = (SELECT i FROM public.tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM tblt1 WHERE i = (SELECT tblj1.i FROM tblj1 WHERE tblj1.i = 1);

+/*e*/SELECT * FROM system_users WHERE user_name = 'SA';

+/*e*/SELECT * FROM other.tblt1;

+/*e*/SELECT * FROM other.system_users;

+/*e*/SELECT * FROM information_schema.tblt1;

+/*e*/SELECT * FROM public.system_users;

+/*c2*/SELECT * FROM public.tblt1;

+/*c1*/SELECT * FROM information_schema.system_users WHERE user_name = 'SA';

+/*c1*/SELECT * FROM public.tblt1 WHERE i = 0;

+/*e*/SELECT * FROM other.tblt1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.tblt1 WHERE i = 0;

+/*c1*/SELECT * FROM public.tblt1, public.tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT * FROM tblt1, public.tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT * FROM public.tblt1, tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT * FROM tblt1, tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM public.tblt1, public.tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM tblt1, public.tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM public.tblt1, tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM tblt1, tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM public.tblt1, public.tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM tblt1, public.tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM public.tblt1, tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM tblt1, tblj1 WHERE tblt1.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM tblt1, tblj1 lbla WHERE tblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM tblt1 lblb, tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM tblt1 lblb, tblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM public.tblt1, tblj1 lbla WHERE tblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM public.tblt1 lblb, tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM public.tblt1 lblb, tblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM tblt1, public.tblj1 lbla WHERE tblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM tblt1 lblb, public.tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM tblt1 lblb, public.tblj1 lbla WHERE lblb.i = lbla.i;

+/*u0*/SET TABLE tblt1 READONLY true;

+/*e*/UPDATE tblt1 set i = 11 WHERE i = 1;

+/*u0*/SET TABLE public.tblt1 READONLY true;

+/*e*/SET TABLE information_schema.tblt1 READONLY true;

+/*e*/SET TABLE other.tblt1 READONLY true;

+/*u0*/SET TABLE tblt1 READONLY false;

+/*u0*/SET TABLE public.tblt1 READONLY false;

+/*c2*/SELECT i FROM tblt1;

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+COMMIT;

+SET AUTOCOMMIT false;

+/*u1*/UPDATE tblt1 set i = 11 WHERE i = 1;

+/*u1*/UPDATE tblt1 set tblt1.i = 12 WHERE i = 11;

+/*u1*/UPDATE tblt1 set tblt1.i = 13 WHERE tblt1.i = 12;

+/*u1*/UPDATE public.tblt1 set i = 14 WHERE i = 13;

+/*u1*/UPDATE public.tblt1 set tblt1.i = 15 WHERE i = 14;

+/*u1*/UPDATE public.tblt1 set tblt1.i = 16 WHERE tblt1.i = 15;

+/*e*/UPDATE other.tblt1 set tblt1.i = 17 WHERE tblt1.i = 16;

+/*e*/UPDATE information_schema.tblt1 set tblt1.i = 17 WHERE tblt1.i = 16;

+/*u1*/UPDATE tblt1 ali set i = 17 WHERE i = 16;

+/*u1*/UPDATE tblt1 ali set ali.i = 18 WHERE i = 17;

+/*u1*/UPDATE tblt1 ali set ali.i = 19 WHERE ali.i = 18;

+/*u1*/UPDATE tblt1 ali set i = 20 WHERE ali.i = 19;

+/*u1*/UPDATE public.tblt1 ali set i = 21 WHERE i = 20;

+/*u1*/UPDATE public.tblt1 ali set ali.i = 22 WHERE i = 21;

+/*u1*/UPDATE public.tblt1 ali set ali.i = 23 WHERE ali.i = 22;

+/*u1*/UPDATE public.tblt1 ali set i = 24 WHERE ali.i = 23;

+/*e*/UPDATE other.tblt1 ali set i = 25 WHERE ali.i = 24;

+/*e*/UPDATE other.tblt1 ali set i = 25 WHERE .i = 24;

+/*e*/UPDATE other.tblt1 set i = 25 WHERE i = 24;

+/*e*/DELETE FROM other.tblt1 ali WHERE ali.i = 24;

+/*e*/DELETE FROM other.tblt1 ali;

+/*e*/DELETE FROM other.tblt1 set WHERE i = 24;

+/*e*/DELETE FROM other.tblt1 WHERE i = 24;

+/*e*/DELETE FROM system_information.tblj1 WHERE tblj1.i = 1;

+/*u1*/DELETE FROM tblt1 WHERE i = 0;

+/*u1*/DELETE FROM public.tblt1 WHERE i = 24;

+/*u1*/DELETE FROM public.tblj1 WHERE tblj1.i = 1;

+ROLLBACK;

+/*c2*/SELECT i FROM tblt1;

+/*u0*/GRANT ALL ON tblt1 TO otheruser;

+/*u0*/GRANT ALL ON public.tblt2 TO otheruser;

+/*e*/GRANT ALL ON other.tblt3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.tblt3 TO otheruser;

+/*u0*/REVOKE ALL ON tblt1 FROM otheruser RESTRICT;

+/*u0*/REVOKE ALL ON public.tblt2 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON other.tblt3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.tblt3 FROM otheruser RESTRICT;

+/*e*/DROP TABLE other.tblt3;

+/*e*/DROP TABLE information_schema.tblt4;

+/*e*/DROP TABLE tblt101;

+/*e*/DROP TABLE public.tblt101;

+/*u0*/DROP TABLE tblt101 IF EXISTS;

+/*u0*/DROP TABLE public.tblt101 IF EXISTS;

+-- Should "DROP TABLE nonexistentschema.notable IF EXISTS" work?

+/*u0*/DROP TABLE other.system_users IF exists;

+/*u0*/DROP TABLE system_users IF exists;

+

+--                  ******************************       CACH Tables

+/*c2*/SELECT * FROM ctblt1;

+/*c1*/SELECT * FROM ctblt1 WHERE i = 0;

+/*c2*/SELECT * FROM ctblt1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM ctblt1 WHERE i < 1;

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i in (SELECT i FROM tblj1);

+/*c0*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM public.ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.ctblt1 WHERE ctblt1.i in (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.ctblt1 WHERE ctblt1.i = (SELECT i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i in (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM public.tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT tblj1.i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i in (SELECT tblj1.i FROM tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT tblj1.i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT i FROM public.tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE ctblt1.i = (SELECT tblj1.i FROM tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE i in (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM tblj1 WHERE i = 1);

+/*c1*/SELECT * FROM public.ctblt1 WHERE i = (SELECT i FROM tblj1);

+/*c1*/SELECT * FROM public.ctblt1 WHERE i in (SELECT i FROM tblj1);

+/*c0*/SELECT * FROM public.ctblt1 WHERE i = (SELECT i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE i in (SELECT i FROM public.tblj1);

+/*c0*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM public.tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT tblj1.i FROM public.tblj1);

+/*c1*/SELECT * FROM ctblt1 WHERE i in (SELECT tblj1.i FROM tblj1);

+/*c0*/SELECT * FROM ctblt1 WHERE i = (SELECT tblj1.i FROM tblj1 WHERE i = 0);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT i FROM public.tblj1 WHERE tblj1.i = 1);

+/*c1*/SELECT * FROM ctblt1 WHERE i = (SELECT tblj1.i FROM tblj1 WHERE tblj1.i = 1);

+/*e*/SELECT * FROM system_users WHERE user_name = 'SA';

+/*e*/SELECT * FROM other.ctblt1;

+/*e*/SELECT * FROM other.system_users;

+/*e*/SELECT * FROM information_schema.ctblt1;

+/*e*/SELECT * FROM public.system_users;

+/*c2*/SELECT * FROM public.ctblt1;

+/*c1*/SELECT * FROM information_schema.system_users WHERE user_name = 'SA';

+/*c1*/SELECT * FROM public.ctblt1 WHERE i = 0;

+/*e*/SELECT * FROM other.ctblt1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.ctblt1 WHERE i = 0;

+/*c1*/SELECT * FROM public.ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT * FROM ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT * FROM public.ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT * FROM ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM public.ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM public.ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT vc FROM ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM public.ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM ctblt1, public.tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM public.ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT tblj1.vc FROM ctblt1, tblj1 WHERE ctblt1.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM ctblt1, tblj1 lbla WHERE ctblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM ctblt1 lblb, tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM ctblt1 lblb, tblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM public.ctblt1, tblj1 lbla WHERE ctblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM public.ctblt1 lblb, tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM public.ctblt1 lblb, tblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM ctblt1, public.tblj1 lbla WHERE ctblt1.i = lbla.i;

+/*c1*/SELECT tblj1.vc FROM ctblt1 lblb, public.tblj1 WHERE lblb.i = tblj1.i;

+/*c1*/SELECT lbla.vc FROM ctblt1 lblb, public.tblj1 lbla WHERE lblb.i = lbla.i;

+/*u0*/SET TABLE ctblt1 READONLY true;

+/*e*/UPDATE ctblt1 set i = 11 WHERE i = 1;

+/*u0*/SET TABLE public.ctblt1 READONLY true;

+/*e*/SET TABLE information_schema.ctblt1 READONLY true;

+/*e*/SET TABLE other.ctblt1 READONLY true;

+/*u0*/SET TABLE ctblt1 READONLY false;

+/*u0*/SET TABLE public.ctblt1 READONLY false;

+/*c2*/SELECT i FROM ctblt1;

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+COMMIT;

+SET AUTOCOMMIT false;

+/*u1*/UPDATE ctblt1 set i = 11 WHERE i = 1;

+/*u1*/UPDATE ctblt1 set ctblt1.i = 12 WHERE i = 11;

+/*u1*/UPDATE ctblt1 set ctblt1.i = 13 WHERE ctblt1.i = 12;

+/*u1*/UPDATE public.ctblt1 set i = 14 WHERE i = 13;

+/*u1*/UPDATE public.ctblt1 set ctblt1.i = 15 WHERE i = 14;

+/*u1*/UPDATE public.ctblt1 set ctblt1.i = 16 WHERE ctblt1.i = 15;

+/*e*/UPDATE other.ctblt1 set ctblt1.i = 17 WHERE ctblt1.i = 16;

+/*e*/UPDATE information_schema.ctblt1 set ctblt1.i = 17 WHERE ctblt1.i = 16;

+/*u1*/UPDATE ctblt1 ali set i = 17 WHERE i = 16;

+/*u1*/UPDATE ctblt1 ali set ali.i = 18 WHERE i = 17;

+/*u1*/UPDATE ctblt1 ali set ali.i = 19 WHERE ali.i = 18;

+/*u1*/UPDATE ctblt1 ali set i = 20 WHERE ali.i = 19;

+/*u1*/UPDATE public.ctblt1 ali set i = 21 WHERE i = 20;

+/*u1*/UPDATE public.ctblt1 ali set ali.i = 22 WHERE i = 21;

+/*u1*/UPDATE public.ctblt1 ali set ali.i = 23 WHERE ali.i = 22;

+/*u1*/UPDATE public.ctblt1 ali set i = 24 WHERE ali.i = 23;

+/*e*/UPDATE other.ctblt1 ali set i = 25 WHERE ali.i = 24;

+/*e*/UPDATE other.ctblt1 ali set i = 25 WHERE .i = 24;

+/*e*/UPDATE other.ctblt1 set i = 25 WHERE i = 24;

+/*e*/DELETE FROM other.ctblt1 ali WHERE ali.i = 24;

+/*e*/DELETE FROM other.ctblt1 ali;

+/*e*/DELETE FROM other.ctblt1 set WHERE i = 24;

+/*e*/DELETE FROM other.ctblt1 WHERE i = 24;

+/*e*/DELETE FROM system_information.tblj1 WHERE tblj1.i = 1;

+/*u1*/DELETE FROM ctblt1 WHERE i = 0;

+/*u1*/DELETE FROM public.ctblt1 WHERE i = 24;

+/*u1*/DELETE FROM public.tblj1 WHERE tblj1.i = 1;

+ROLLBACK;

+/*c2*/SELECT i FROM ctblt1;

+/*u0*/GRANT ALL ON ctblt1 TO otheruser;

+/*u0*/GRANT ALL ON public.ctblt2 TO otheruser;

+/*e*/GRANT ALL ON other.ctblt3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.ctblt3 TO otheruser;

+/*u0*/REVOKE ALL ON ctblt1 FROM otheruser RESTRICT;

+/*u0*/REVOKE ALL ON public.ctblt2 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON other.ctblt3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.ctblt3 FROM otheruser RESTRICT;

+/*e*/DROP TABLE other.ctblt3;

+/*e*/DROP TABLE information_schema.ctblt4;

+/*e*/DROP TABLE ctblt101;

+/*e*/DROP TABLE public.ctblt101;

+/*u0*/DROP TABLE ctblt101 IF EXISTS;

+/*u0*/DROP TABLE public.ctblt101 IF EXISTS;

+-- Should "DROP TABLE nonexistentschema.notable IF EXISTS" work?

+/*u0*/DROP TABLE other.system_users IF exists;

+/*u0*/DROP TABLE system_users IF exists;

+

+--                  ******************************       Views

+/*c2*/SELECT * FROM vwv1;

+/*c2*/SELECT * FROM public.vwv1;

+/*c2*/SELECT * FROM vwv2;

+/*c2*/SELECT * FROM vwv3;

+/*c1*/SELECT * FROM vwv4;

+/*c1*/SELECT * FROM vwv5;

+/*c1*/SELECT * FROM vwv8;

+/*c0*/SELECT * FROM vwv9;

+/*c0*/SELECT * FROM vwv10;

+/*c0*/SELECT * FROM vwv11;

+/*c0*/SELECT * FROM vwv12;

+/*c0*/SELECT * FROM vwv13;

+/*c0*/SELECT * FROM vwv14;

+/*c0*/SELECT * FROM vwv15;

+/*c0*/SELECT * FROM vwv16;

+/*c0*/SELECT * FROM vwv17;

+/*c0*/SELECT * FROM vwv18;

+/*c1*/SELECT * FROM vwv19;

+/*c1*/SELECT * FROM vwv20;

+/*c1*/SELECT * FROM vwv21;

+/*c1*/SELECT * FROM vwv22;

+/*c1*/SELECT * FROM vwv23;

+/*c1*/SELECT * FROM vwv24;

+/*c1*/SELECT * FROM vwv25;

+/*c1*/SELECT * FROM vwv26;

+/*c2*/SELECT * FROM vwv28;

+/*c1*/SELECT * FROM vwv29;

+/*c1*/SELECT * FROM vwv30;

+/*c1*/SELECT * FROM vwv31;

+/*c0*/SELECT * FROM vwv32;

+/*c1*/SELECT * FROM vwv33;

+/*c1*/SELECT * FROM vwv34;

+/*c0*/SELECT * FROM vwv35;

+/*c1*/SELECT * FROM vwv36;

+/*c1*/SELECT * FROM vwv37;

+/*c1*/SELECT * FROM vwv38;

+/*c1*/SELECT * FROM vwv39;

+/*c1*/SELECT * FROM vwv40;

+/*c1*/SELECT * FROM vwv41;

+/*c1*/SELECT * FROM vwv42;

+/*c1*/SELECT * FROM vwv43;

+/*c1*/SELECT * FROM vwv44;

+/*c1*/SELECT * FROM vwv45;

+/*c1*/SELECT * FROM vwv46;

+/*c1*/SELECT * FROM vwv47;

+/*c1*/SELECT * FROM vwv48;

+/*c1*/SELECT * FROM vwv49;

+/*c1*/SELECT * FROM vwv50;

+/*c1*/SELECT * FROM vwv51;

+/*c1*/SELECT * FROM vwv52;

+/*c1*/SELECT * FROM vwv53;

+/*c1*/SELECT * FROM vwv54;

+/*c1*/SELECT * FROM vwv55;

+/*c1*/SELECT * FROM vwv56;

+/*c1*/SELECT * FROM vwv57;

+/*c1*/SELECT * FROM vwv1, vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT * FROM public.vwv1, public.vwj1 WHERE vwv1.i = vwj1.i;

+/*c2*/SELECT * FROM vwv1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM vwv1 WHERE i < 1;

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i in (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM public.vwv1 WHERE vwv1.i in (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM public.vwv1 WHERE vwv1.i = (SELECT i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i in (SELECT i FROM public.vwj1);

+/*c0*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM public.vwj1 WHERE i = 0);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT vwj1.i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i in (SELECT vwj1.i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT vwj1.i FROM vwj1 WHERE i = 1);

+/*c0*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM public.vwj1 WHERE vwj1.i = 0);

+/*c0*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT vwj1.i FROM vwj1 WHERE vwj1.i = 0);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i in (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM public.vwv1 WHERE i = (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM public.vwv1 WHERE i in (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM public.vwv1 WHERE i = (SELECT i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i in (SELECT i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM public.vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT vwj1.i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i in (SELECT vwj1.i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT vwj1.i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM public.vwj1 WHERE vwj1.i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT vwj1.i FROM vwj1 WHERE vwj1.i = 1);

+/*c2*/SELECT * FROM vwv1;

+/*c1*/SELECT * FROM vwv1 WHERE i = 0;

+/*c2*/SELECT * FROM vwv1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM vwv1 WHERE i < 1;

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i in (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM public.vwv1 WHERE vwv1.i = (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM public.vwv1 WHERE vwv1.i in (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM public.vwv1 WHERE vwv1.i = (SELECT i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i in (SELECT i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM public.vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT vwj1.i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i in (SELECT vwj1.i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT vwj1.i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT i FROM public.vwj1 WHERE vwj1.i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE vwv1.i = (SELECT vwj1.i FROM vwj1 WHERE vwj1.i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i in (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM public.vwv1 WHERE i = (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM public.vwv1 WHERE i in (SELECT i FROM vwj1);

+/*c1*/SELECT * FROM public.vwv1 WHERE i = (SELECT i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i in (SELECT i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM public.vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT vwj1.i FROM public.vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i in (SELECT vwj1.i FROM vwj1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT vwj1.i FROM vwj1 WHERE i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT i FROM public.vwj1 WHERE vwj1.i = 1);

+/*c1*/SELECT * FROM vwv1 WHERE i = (SELECT vwj1.i FROM vwj1 WHERE vwj1.i = 1);

+/*e*/SELECT * FROM other.vwv1;

+/*e*/SELECT * FROM information_schema.vwv1;

+/*c2*/SELECT * FROM public.vwv1;

+/*c1*/SELECT * FROM public.vwv1 WHERE i = 0;

+/*e*/SELECT * FROM other.vwv1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.vwv1 WHERE i = 0;

+/*c1*/SELECT * FROM public.vwv1 WHERE i = 0;

+CREATE TABLE public.vwt2 AS (SELECT * FROM public.vwv1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM public.vwt2;

+DROP TABLE vwt2;

+/*c1*/SELECT * FROM public.vwv1, public.vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT * FROM vwv1, public.vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT * FROM public.vwv1, vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT * FROM vwv1, vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT vc FROM public.vwv1, public.vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT vc FROM vwv1, public.vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT vc FROM public.vwv1, vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT vc FROM vwv1, vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT vwj1.vc FROM public.vwv1, public.vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT vwj1.vc FROM vwv1, public.vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT vwj1.vc FROM public.vwv1, vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT vwj1.vc FROM vwv1, vwj1 WHERE vwv1.i = vwj1.i;

+/*c1*/SELECT lbla.vc FROM vwv1, vwj1 lbla WHERE vwv1.i = lbla.i;

+/*c1*/SELECT vwj1.vc FROM vwv1 lblb, vwj1 WHERE lblb.i = vwj1.i;

+/*c1*/SELECT lbla.vc FROM vwv1 lblb, vwj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM public.vwv1, vwj1 lbla WHERE vwv1.i = lbla.i;

+/*c1*/SELECT vwj1.vc FROM public.vwv1 lblb, vwj1 WHERE lblb.i = vwj1.i;

+/*c1*/SELECT lbla.vc FROM public.vwv1 lblb, vwj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM vwv1, public.vwj1 lbla WHERE vwv1.i = lbla.i;

+/*c1*/SELECT vwj1.vc FROM vwv1 lblb, public.vwj1 WHERE lblb.i = vwj1.i;

+/*c1*/SELECT lbla.vc FROM vwv1 lblb, public.vwj1 lbla WHERE lblb.i = lbla.i;

+/*u0*/GRANT ALL ON vwv1 TO otheruser;

+/*u0*/GRANT ALL ON public.vwv2 TO otheruser;

+/*e*/GRANT ALL ON other.vwv3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.vwv3 TO otheruser;

+/*u0*/REVOKE ALL ON vwv1 FROM otheruser RESTRICT;

+/*u0*/REVOKE ALL ON public.vwv2 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON other.vwv3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.vwv3 FROM otheruser RESTRICT;

+

+--                  ******************************       Indexes

+/*c2*/SELECT * from indt1;

+/*c2*/SELECT * from public.indt2;

+/*c2*/SELECT * from public.indt3;

+/*c2*/SELECT * from indt4;

+

+--                  ******************************  CACH Indexes

+/*c2*/SELECT * from cindt1;

+/*c2*/SELECT * from public.cindt2;

+/*c2*/SELECT * from public.cindt3;

+/*c2*/SELECT * from cindt4;

+

+--                  ******************************       Sequences

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+/*r0*/SELECT next value FOR s1 FROM seqt1;

+/*r2*/SELECT next value FOR public.s2 FROM seqt1;

+/*r1*/SELECT next value FOR s1 FROM public.seqt1;

+/*r3*/SELECT next value FOR public.s2 FROM public.seqt1;

+/*r2*/SELECT next value FOR public.s1 FROM seqt1;

+/*r4*/SELECT next value FOR s2 FROM seqt1;

+/*r3*/SELECT next value FOR public.s1 FROM seqt1;

+/*r5*/SELECT next value FOR s2 FROM seqt1;

+-- Just to reset orig. value before persisting (can't roll back seq.s).

+ALTER SEQUENCE s1 RESTART WITH 0;

+ALTER SEQUENCE s2 RESTART WITH 2;

+/*e*/DROP SEQUENCE s101;

+/*e*/DROP SEQUENCE public.s101;

+/*e*/DROP SEQUENCE information_schema.s1;

+/*e*/DROP SEQUENCE other.s1;

+

+--                  ******************************       Triggers

+/*e*/CREATE TRIGGER trgtrig1

+    AFTER INSERT ON trgt1 CALL 'org.hsqldb.test.BlaineTrig'; -- Create existing

+/*e*/CREATE TRIGGER public.trgtrig2

+    AFTER INSERT ON trgt2 CALL 'org.hsqldb.test.BlaineTrig'; -- Create existing

+

+--                  ******************************       Constraints

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+COMMIT;

+SET AUTOCOMMIT false;

+/*u1*/INSERT INTO cont1 VALUES (0);

+/*u1*/INSERT INTO public.cont2 VALUES (0);

+/*u1*/INSERT INTO cont3 VALUES (0);

+/*u1*/INSERT INTO cont4 VALUES (0);

+/*u1*/INSERT INTO cont5 VALUES (0);

+/*u1*/INSERT INTO cont6 VALUES (0);

+/*u1*/INSERT INTO cont7 VALUES (0);

+/*u1*/INSERT INTO cont8 VALUES (0);

+-- Note that error message implies that problem is due to table conj1, not data:

+/*u1*/INSERT INTO cont9 VALUES (1);

+/*u1*/INSERT INTO cont10 VALUES (1);

+/*u1*/INSERT INTO cont11 VALUES (1);

+/*u1*/INSERT INTO cont12 VALUES (1);

+/*u1*/INSERT INTO cont13 VALUES (1);

+/*u1*/INSERT INTO cont14 VALUES (1);

+/*u1*/INSERT INTO cont15 VALUES (1);

+/*u1*/INSERT INTO cont16 VALUES (1);

+/*u1*/INSERT INTO cont17 VALUES (0);

+/*u1*/INSERT INTO cont18 VALUES (0);

+/*u1*/INSERT INTO cont19 VALUES (0);

+/*u1*/INSERT INTO cont20 VALUES (0);

+/*e*/INSERT INTO cont1 VALUES (0);

+/*e*/INSERT INTO cont2 VALUES (0);

+/*e*/INSERT INTO cont3 VALUES (0);

+/*e*/INSERT INTO cont4 VALUES (0);

+/*e*/INSERT INTO cont5 VALUES (0);

+/*e*/INSERT INTO cont6 VALUES (0);

+/*e*/INSERT INTO cont7 VALUES (0);

+/*e*/INSERT INTO cont8 VALUES (0);

+/*e*/INSERT INTO cont9 VALUES (0);

+/*e*/INSERT INTO cont10 VALUES (0);

+/*e*/INSERT INTO cont11 VALUES (0);

+/*e*/INSERT INTO cont12 VALUES (0);

+/*e*/INSERT INTO cont13 VALUES (0);

+/*e*/INSERT INTO cont14 VALUES (0);

+/*e*/INSERT INTO cont15 VALUES (0);

+/*e*/INSERT INTO cont16 VALUES (0);

+/*e*/INSERT INTO cont17 VALUES (1);

+/*e*/INSERT INTO cont18 VALUES (1);

+/*e*/INSERT INTO cont19 VALUES (1);

+/*e*/INSERT INTO cont20 VALUES (1);

+/*c1*/SELECT * FROM cont1;

+/*c1*/SELECT * FROM cont2;

+/*c1*/SELECT * FROM cont3;

+/*c1*/SELECT * FROM cont4;

+/*c1*/SELECT * FROM cont5;

+/*c1*/SELECT * FROM cont6;

+/*c1*/SELECT * FROM cont7;

+/*c1*/SELECT * FROM cont8;

+/*c1*/SELECT * FROM cont9;

+/*c1*/SELECT * FROM cont10;

+/*c1*/SELECT * FROM cont11;

+/*c1*/SELECT * FROM cont12;

+/*c1*/SELECT * FROM cont13;

+/*c1*/SELECT * FROM cont14;

+/*c1*/SELECT * FROM cont15;

+/*c1*/SELECT * FROM cont16;

+/*c1*/SELECT * FROM cont17;

+/*c1*/SELECT * FROM cont18;

+/*c1*/SELECT * FROM cont19;

+/*c1*/SELECT * FROM cont20;

+ROLLBACK;

+

+--                  ******************************       ALTERs

+-- Add tests when time permits.

+

+DROP USER otheruser;

+

+

+-- This to test .script persistence.

+SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfSchemaPersistB1.txt b/testrun/hsqldb/TestSelfSchemaPersistB1.txt
new file mode 100644
index 0000000..42e9a65
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaPersistB1.txt
@@ -0,0 +1,728 @@
+-- CREATE AND INITIALIZE OBJECTS

+

+-- This CREATES the schema-specific objects to be used for

+-- schema-specific persistence tests.

+-- (See the *C[12].txt scripts for similar tests of ALTER comands (which

+-- this script purposefully omits).

+

+-- This *1.txt script tests whether objects can/do get CREATED in the correct

+-- schemas, since there is no reason why that would change in consequent

+-- connections to the same database (*[23].txt scripts).

+-- This script must, of course, persist objects in different specific

+-- schemas so that scripts *[23] may verify that they continue to reside

+-- and be accessible only in the correct schema.

+

+-- In the main (object-type-specific) test blocks, for every command that

+-- has ALL SCHEMA OBJECTS explicitly specified,

+-- I always do a SET SCHEMA so that an accidental

+-- fallback to Session schema will always lead to a test failure.

+

+

+--                  ******************************       Schemas

+-- Non-persistence Schema testing.

+-- Test the _INITIAL_ Session default schema (currently "PUBLIC").

+-- After the objects are created in the correct schema, it makes no difference

+-- whether the "INITIAL" schema was used or not.  Therefore, no need to test

+-- this stuff in scripts *[23].txt.

+DROP TABLE public.pschct1 IF exists;

+DROP TABLE public.pschct2 IF exists;

+DROP TABLE public.pschct3 IF exists;

+DROP VIEW public.pschv1 IF exists;

+DROP VIEW public.pschv2 IF exists;

+DROP INDEX public.pschi1 IF exists;

+DROP TABLE public.pscht1 IF exists;

+DROP TABLE public.pscht2 IF exists;

+-- Verify all SELECTs fail before we start

+/*e*/SELECT * FROM public.pscht1;

+/*e*/SELECT * FROM public.pscht2;

+/*e*/SELECT * FROM public.pschv1;

+/*e*/SELECT * FROM public.pschv2;

+/*e*/SELECT * FROM public.pschct1;

+/*e*/SELECT * FROM public.pschct2;

+/*e*/SELECT * FROM public.pschct3;

+/*e*/SELECT * FROM blaine.pscht1;

+/*e*/SELECT * FROM blaine.pscht2;

+/*e*/SELECT * FROM blaine.pschv1;

+/*e*/SELECT * FROM blaine.pschv2;

+/*e*/SELECT * FROM blaine.pschct1;

+/*e*/SELECT * FROM blaine.pschct2;

+/*e*/SELECT * FROM blaine.pschct3;

+/*e*/SELECT * FROM pscht1;

+/*e*/SELECT * FROM pscht2;

+/*e*/SELECT * FROM pschv1;

+/*e*/SELECT * FROM pschv2;

+/*e*/SELECT * FROM pschct1;

+/*e*/SELECT * FROM pschct2;

+/*e*/SELECT * FROM pschct3;

+/*u0*/CREATE TABLE pscht1 (i int);

+/*u1*/INSERT INTO pscht1 values(0);

+/*u1*/INSERT INTO pscht1 values(1);

+/*u0*/CREATE UNIQUE INDEX pschi1 ON pscht1(i);

+/*e*/INSERT INTO pscht1 values(1);

+/*u0*/CREATE TABLE pscht2 (i int);

+/*u1*/INSERT INTO pscht2 values(0);

+/*u1*/INSERT INTO pscht2 values(1);

+/*u0*/CREATE VIEW pschv1 AS SELECT * FROM pscht1;

+/*u0*/CREATE VIEW pschv2 AS SELECT * FROM public.pscht1;

+-- Create then remove using explicit schema.  This is a workaround for no

+-- DROP TRIGGER... IF EXISTS;

+/*u0*/CREATE TRIGGER public.ptrig1

+    AFTER INSERT ON pscht1 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+DROP TRIGGER public.ptrig1;

+/*u0*/CREATE TRIGGER ptrig1

+    AFTER INSERT ON pscht1 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TRIGGER public.ptrig2

+    AFTER INSERT ON public.pscht2 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+DROP TRIGGER public.ptrig2;

+/*u0*/CREATE TRIGGER ptrig2

+    AFTER INSERT ON public.pscht2 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TABLE pschct1 (i int, CONSTRAINT pschuc1 UNIQUE(i));

+/*u0*/CREATE TABLE public.pschct2 (i int, CONSTRAINT pschuc2 UNIQUE(i));

+/*u0*/CREATE TABLE pschct3 (i int, CONSTRAINT public.pschuc3 UNIQUE(i));

+/*u1*/INSERT INTO pschct1 values(0);

+/*u1*/INSERT INTO pschct2 values(0);

+/*u1*/INSERT INTO pschct3 values(0);

+/*e*/INSERT INTO pschct1 values(0);

+/*e*/INSERT INTO pschct2 values(0);

+/*e*/INSERT INTO pschct3 values(0);

+-- Verify created in correct schemas

+/*c2*/SELECT * FROM public.pscht1;

+/*c2*/SELECT * FROM public.pscht2;

+/*c2*/SELECT * FROM public.pschv1;

+/*c2*/SELECT * FROM public.pschv2;

+/*c1*/SELECT * FROM public.pschct1;

+/*c1*/SELECT * FROM public.pschct2;

+/*c1*/SELECT * FROM public.pschct3;

+/*e*/CREATE TRIGGER public.ptrig1

+    AFTER INSERT ON pscht1 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER public.ptrig2

+    AFTER INSERT ON public.pscht1 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/SELECT * FROM blaine.pscht1;

+/*e*/SELECT * FROM blaine.pscht2;

+/*e*/SELECT * FROM blaine.pschv1;

+/*e*/SELECT * FROM blaine.pschv2;

+/*e*/SELECT * FROM blaine.pschct1;

+/*e*/SELECT * FROM blaine.pschct2;

+/*e*/SELECT * FROM blaine.pschct3;

+-- Verify SELECTs using default schema

+/*c2*/SELECT * FROM pscht1;

+/*c2*/SELECT * FROM pscht2;

+/*c2*/SELECT * FROM pschv1;

+/*c2*/SELECT * FROM pschv2;

+/*c1*/SELECT * FROM pschct1;

+/*c1*/SELECT * FROM pschct2;

+/*c1*/SELECT * FROM pschct3;

+-- Following 2 just to confirm that TRIGGERs created.

+/*e*/CREATE TRIGGER ptrig1

+    AFTER INSERT ON pscht1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER public.ptrig2

+    AFTER INSERT ON public.pscht1 CALL "org.hsqldb.test.BlaineTrig";

+

+/*u0*/CREATE SCHEMA blaine AUTHORIZATION dba;

+/*e*/CREATE SCHEMA blaine AUTHORIZATION dba;

+/*u0*/SET SCHEMA blaine;

+-- Verify created in correct schemas

+/*c2*/SELECT * FROM public.pscht1;

+/*c2*/SELECT * FROM public.pscht2;

+/*c2*/SELECT * FROM public.pschv1;

+/*c2*/SELECT * FROM public.pschv2;

+/*c1*/SELECT * FROM public.pschct1;

+/*c1*/SELECT * FROM public.pschct2;

+/*c1*/SELECT * FROM public.pschct3;

+-- Following 2 just to confirm that TRIGGERs created.

+/*e*/CREATE TRIGGER public.ptrig1

+    AFTER INSERT ON pscht1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER public.ptrig2

+    AFTER INSERT ON public.pscht1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/SELECT * FROM blaine.pscht1;

+/*e*/SELECT * FROM blaine.pscht2;

+/*e*/SELECT * FROM blaine.pschv1;

+/*e*/SELECT * FROM blaine.pschv2;

+/*e*/SELECT * FROM blaine.pschct1;

+/*e*/SELECT * FROM blaine.pschct2;

+/*e*/SELECT * FROM blaine.pschct3;

+-- Verify SELECTs using default schema

+/*e*/SELECT * FROM pscht1;

+/*e*/SELECT * FROM pscht2;

+/*e*/SELECT * FROM pschv1;

+/*e*/SELECT * FROM pschv2;

+/*e*/SELECT * FROM pschct1;

+/*e*/SELECT * FROM pschct2;

+/*e*/SELECT * FROM pschct3;

+-- Test of SET SCHEMA

+/*u0*/SET SCHEMA public;

+/*c2*/SELECT * FROM public.pscht1;

+/*c2*/SELECT * FROM public.pscht2;

+/*c2*/SELECT * FROM public.pschv1;

+/*c2*/SELECT * FROM public.pschv2;

+/*c1*/SELECT * FROM public.pschct1;

+/*c1*/SELECT * FROM public.pschct2;

+/*c1*/SELECT * FROM public.pschct3;

+-- Following 2 just to confirm that TRIGGERs created.

+/*e*/CREATE TRIGGER public.ptrig1

+    AFTER INSERT ON pscht1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER public.ptrig2

+    AFTER INSERT ON public.pscht1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/SELECT * FROM blaine.pscht1;

+/*e*/SELECT * FROM blaine.pscht2;

+/*e*/SELECT * FROM blaine.pschv1;

+/*e*/SELECT * FROM blaine.pschv2;

+/*e*/SELECT * FROM blaine.pschct1;

+/*e*/SELECT * FROM blaine.pschct2;

+/*e*/SELECT * FROM blaine.pschct3;

+-- Verify SELECTs using default schema

+/*c2*/SELECT * FROM public.pscht1;  -- Sanity check DEBUG

+/*u0*/SET SCHEMA public;            -- Sanity check DEBUG

+/*c2*/SELECT * FROM pscht1;

+/*c2*/SELECT * FROM pscht2;

+/*c2*/SELECT * FROM pschv1;

+/*c2*/SELECT * FROM pschv2;

+/*c1*/SELECT * FROM pschct1;

+/*c1*/SELECT * FROM pschct2;

+/*c1*/SELECT * FROM pschct3;

+-- Following 2 just to confirm that TRIGGERs created.

+/*e*/CREATE TRIGGER ptrig1

+    AFTER INSERT ON pscht1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER public.ptrig2

+    AFTER INSERT ON public.pscht1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/SET SCHEMA nosuch;

+

+/*u0*/SET SCHEMA blaine;

+

+--                  ******************************       MEM Tables

+/*e*/DROP TABLE nosuch;

+DROP TABLE xtblt1 IF exists;

+DROP TABLE xtblt2 IF exists;

+DROP TABLE xtblt3 IF exists;

+DROP TABLE xtblt4 IF exists;

+DROP TABLE xtblt101 IF exists;

+DROP TABLE xtblj1 IF exists;

+/*u0*/CREATE TABLE xtblt1 (i int);

+SET SCHEMA public;

+/*u0*/CREATE TABLE blaine.xtblt2 (i int);

+SET SCHEMA blaine;

+/*u0*/CREATE TABLE xtblt3 (i int);

+/*u0*/CREATE TABLE xtblj1 (i int, vc varchar(10));  -- For testing Joins

+/*e*/CREATE TABLE information_schema.xtblt101 (i int);

+/*e*/CREATE TABLE xtblt1 (i int); -- Create existing object

+SET SCHEMA public;

+/*e*/CREATE TABLE blaine.xtblt1 (i int); -- Create existing object

+SET SCHEMA blaine;

+/*e*/CREATE TABLE information_schema.system_users (i int); -- Existing object

+/*e*/INSERT INTO other.xtblt1 values(0);

+/*e*/INSERT INTO information_schema.xtblt1 values(1);

+/*u1*/INSERT INTO xtblt1 values(0);

+SET SCHEMA public;

+/*u1*/INSERT INTO blaine.xtblt1 values(100);

+SET SCHEMA blaine;

+-- Test one update that will be persisted (most update tests won't be)

+SET SCHEMA public;

+/*u1*/UPDATE blaine.xtblt1 set i = 1 WHERE i = 100;

+SET SCHEMA blaine;

+/*u1*/INSERT INTO xtblj1 values(1, 'one');

+SET SCHEMA public;

+CREATE TABLE blaine.xtblt4 AS (SELECT *  FROM blaine.xtblt1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM blaine.xtblt4;

+SET SCHEMA blaine;

+

+--                  ******************************       CACH Tables

+/*e*/DROP TABLE nosuch;

+DROP TABLE xctblt1 IF exists;

+DROP TABLE xctblt2 IF exists;

+DROP TABLE xctblt3 IF exists;

+DROP TABLE xctblt4 IF exists;

+DROP TABLE xctblt101 IF exists;

+DROP TABLE xtblj1 IF exists;

+/*u0*/CREATE CACHED TABLE xctblt1 (i int);

+SET SCHEMA public;

+/*u0*/CREATE CACHED TABLE blaine.xctblt2 (i int);

+SET SCHEMA blaine;

+/*u0*/CREATE CACHED TABLE xctblt3 (i int);

+/*u0*/CREATE CACHED TABLE xtblj1 (i int, vc varchar(10));  -- For testing Joins

+/*e*/CREATE CACHED TABLE information_schema.xctblt101 (i int);

+/*e*/CREATE CACHED TABLE xctblt1 (i int); -- Create existing object

+SET SCHEMA public;

+/*e*/CREATE CACHED TABLE blaine.xctblt1 (i int); -- Create existing object

+SET SCHEMA blaine;

+/*e*/CREATE CACHED TABLE information_schema.system_users (i int); -- Existing object

+/*e*/INSERT INTO other.xctblt1 values(0);

+/*e*/INSERT INTO information_schema.xctblt1 values(1);

+/*u1*/INSERT INTO xctblt1 values(0);

+SET SCHEMA public;

+/*u1*/INSERT INTO blaine.xctblt1 values(100);

+-- Test one update that will be persisted (most update tests won't be)

+/*u1*/UPDATE blaine.xctblt1 set i = 1 WHERE i = 100;

+SET SCHEMA blaine;

+/*u1*/INSERT INTO xtblj1 values(1, 'one');

+SET SCHEMA public;

+CREATE TABLE blaine.xctblt4 AS (SELECT * FROM blaine.xctblt1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM blaine.xctblt4;

+SET SCHEMA blaine;

+

+--                  ******************************       Views

+DROP VIEW xvwv1 IF exists;

+DROP VIEW xvwv2 IF exists;

+DROP VIEW xvwv3 IF exists;

+DROP VIEW xvwv4 IF exists;

+DROP VIEW xvwv5 IF exists;

+DROP VIEW xvwv6 IF exists;

+DROP VIEW xvwv7 IF exists;

+DROP VIEW xvwv8 IF exists;

+DROP VIEW xvwv9 IF exists;

+DROP VIEW xvwv10 IF exists;

+DROP VIEW xvwv11 IF exists;

+DROP VIEW xvwv12 IF exists;

+DROP VIEW xvwv13 IF exists;

+DROP VIEW xvwv14 IF exists;

+DROP VIEW xvwv15 IF exists;

+DROP VIEW xvwv16 IF exists;

+DROP VIEW xvwv17 IF exists;

+DROP VIEW xvwv18 IF exists;

+DROP VIEW xvwv19 IF exists;

+DROP VIEW xvwv20 IF exists;

+DROP VIEW xvwv21 IF exists;

+DROP VIEW xvwv22 IF exists;

+DROP VIEW xvwv23 IF exists;

+DROP VIEW xvwv24 IF exists;

+DROP VIEW xvwv25 IF exists;

+DROP VIEW xvwv26 IF exists;

+DROP VIEW xvwv27 IF exists;

+DROP VIEW xvwv101 IF exists;

+DROP TABLE xvwt1 IF exists;

+DROP TABLE xvwt2 IF exists;

+DROP TABLE xvwj1 IF exists;

+DROP TABLE public.pubtbl IF exists;

+CREATE TABLE xvwt1 (i int);

+CREATE TABLE xvwj1 (i int, vc varchar(10));

+CREATE TABLE public.pubtbl (i int);

+INSERT INTO public.pubtbl values(0);

+INSERT INTO xvwt1 values(0);

+INSERT INTO xvwt1 values(1);

+INSERT INTO xvwj1 values(1, 'one');

+/*e*/CREATE VIEW information_schema.xvwv101 AS

+    SELECT * FROM information_schema.system_users;

+/*e*/CREATE VIEW information_schema.xvwv101 AS

+    SELECT * FROM xvwt1;

+SET SCHEMA public;

+/*e*/CREATE VIEW information_schema.xvwv4 AS

+    SELECT * FROM blaine.xvwt1;

+SET SCHEMA blaine;

+/*e*/CREATE VIEW xvwv101 AS SELECT * FROM other.xvwt1;

+SET SCHEMA public;

+/*e*/CREATE VIEW blaine.xvwv101 AS SELECT * FROM other.xvwt1;

+SET SCHEMA blaine;

+/*e*/CREATE VIEW other.xvwv101 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE user_name = vc;

+SET SCHEMA public;

+/*e*/CREATE VIEW other.xvwv101 AS SELECT *

+    FROM information_schema.system_users, blaine.xvwj1 WHERE user_name = vc;

+SET SCHEMA blaine;

+/*e*/CREATE VIEW other.xvwv101 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE information_schema.user_name = vc;

+/*e*/CREATE VIEW other.xvwv101 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE information_schema.user_name = blaine.vc;

+/*e*/CREATE VIEW information_schema.xvwv101 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE user_name = vc;

+SET SCHEMA public;

+/*e*/CREATE VIEW information_schema.xvwv101 AS SELECT *

+    FROM information_schema.system_users, blaine.xvwj1 WHERE user_name = vc;

+SET SCHEMA blaine;

+/*e*/CREATE VIEW information_schema.xvwv101 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE information_schema.user_name = vc;

+/*e*/CREATE VIEW information_schema.xvwv101 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE information_schema.user_name = blaine.vc;

+/*e*/CREATE VIEW xvwv101 AS SELECT *

+    FROM system_users, xvwj1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW xvwv101 AS SELECT *

+    FROM information_schema.system_users, information_schema.xvwj1

+    WHERE user_name = vc;

+/*e*/CREATE VIEW xvwv101 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE other.user_name = vc;

+/*e*/CREATE VIEW xvwv101 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE blaine.user_name = blaine.vc;

+/*c2*/SELECT * FROM xvwt1;  -- Sanity check

+/*u0*/CREATE VIEW xvwv1 AS SELECT * FROM xvwt1;

+/*e*/CREATE VIEW blaine.xvwv1 AS SELECT * FROM xvwt1; -- Create existing object

+SET SCHEMA public;

+/*e*/CREATE VIEW blaine.xvwv1 AS SELECT * FROM blaine.xvwt1; -- Existing object

+SET SCHEMA blaine;

+/*u0*/CREATE VIEW blaine.xvwv2 AS SELECT * FROM xvwt1;

+SET SCHEMA public;

+/*u0*/CREATE VIEW blaine.xvwv3 AS SELECT * FROM blaine.xvwt1;

+SET SCHEMA blaine;

+/*u0*/CREATE VIEW blaine.xvwv4 AS SELECT * FROM xvwt1 WHERE i = 0;

+/*u0*/CREATE VIEW blaine.xvwv5 AS SELECT * FROM xvwt1 WHERE i < 1;

+SET SCHEMA public;

+/*u0*/CREATE VIEW blaine.xvwv6 AS SELECT * FROM information_schema.system_users

+    WHERE user_name = 'SA';

+SET SCHEMA blaine;

+/*u0*/CREATE VIEW xvwv7 AS SELECT * FROM information_schema.system_users;

+/*u0*/CREATE VIEW xvwv8 AS SELECT * FROM information_schema.system_users

+    WHERE user_name = 'SA';

+/*u0*/CREATE VIEW xvwv9 AS SELECT * FROM information_schema.system_users, xvwj1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW xvwv10 AS SELECT *

+    FROM information_schema.system_users, blaine.xvwj1 WHERE user_name = vc;

+/*u0*/CREATE VIEW xvwv11 AS SELECT * FROM information_schema.system_users, xvwj1

+    WHERE system_users.user_name = vc;

+/*u0*/CREATE VIEW xvwv12 AS SELECT * FROM information_schema.system_users, xvwj1

+    WHERE system_users.user_name = xvwj1.vc;

+SET SCHEMA public;

+-- Should FAIL because SEL sub-q gets default schema from Session default.

+/*e*/CREATE VIEW blaine.xvwv13 AS SELECT *

+    FROM information_schema.system_users, xvwj1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW blaine.xvwv14 AS SELECT *

+    FROM information_schema.system_users, blaine.xvwj1 WHERE user_name = vc;

+SET SCHEMA blaine;

+/*u0*/CREATE VIEW blaine.xvwv15 AS SELECT *

+     FROM information_schema.system_users, xvwj1

+     WHERE system_users.user_name = vc;

+/*u0*/CREATE VIEW blaine.xvwv16 AS SELECT *

+    FROM information_schema.system_users, blaine.xvwj1

+    WHERE system_users.user_name = xvwj1.vc;

+/*u0*/CREATE VIEW xvwv17 AS SELECT * FROM information_schema.system_users, xvwj1

+    WHERE user_name = vc;

+/*u0*/CREATE VIEW xvwv18 AS SELECT *

+    FROM information_schema.system_users, blaine.xvwj1 WHERE user_name = vc;

+/*u0*/CREATE VIEW xvwv19 (v1, v2, v3) AS SELECT * FROM xvwt1, xvwj1 WHERE xvwt1.i = xvwj1.i;

+/*u0*/CREATE VIEW xvwv20 (v1, v2, v3) AS SELECT * FROM blaine.xvwt1, blaine.xvwj1 WHERE xvwt1.i = xvwj1.i;

+/*u0*/CREATE VIEW xvwv21 (v1, v2, v3) AS SELECT * FROM blaine.xvwt1, xvwj1 WHERE xvwt1.i = xvwj1.i;

+/*u0*/CREATE VIEW xvwv22 (v1, v2, v3) AS SELECT * FROM xvwt1, blaine.xvwj1 WHERE xvwt1.i = xvwj1.i;

+/*u0*/CREATE VIEW blaine.xvwv23 (v1, v2, v3) AS

+    SELECT * FROM xvwt1, xvwj1 WHERE xvwt1.i = xvwj1.i;

+SET SCHEMA public;

+/*u0*/CREATE VIEW blaine.xvwv24 (v1, v2, v3) AS

+    SELECT * FROM blaine.xvwt1, blaine.xvwj1 WHERE xvwt1.i = xvwj1.i;

+-- Sub-SEL (2nd) should default to public schema!: (don't know 'bout 1st SEL)

+/*e*/CREATE VIEW blaine.xvwv101 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT i FROM xvwj1);

+/*e*/CREATE VIEW blaine.xvwv101 AS

+    SELECT * FROM blaine.xvwt1 WHERE xvwt1.i = (SELECT i FROM xvwj1);

+SET SCHEMA blaine;

+/*u0*/CREATE VIEW blaine.xvwv25 (v1, v2, v3) AS SELECT * FROM blaine.xvwt1, xvwj1 WHERE xvwt1.i = xvwj1.i;

+/*u0*/CREATE VIEW blaine.xvwv26 (v1, v2, v3) AS SELECT * FROM xvwt1, blaine.xvwj1 WHERE xvwt1.i = xvwj1.i;

+-- We do not permit views to reference tables in another schema, except

+-- for information_schema.

+/*u0*/CREATE VIEW blaine.xvwv27 AS SELECT * FROM public.pubtbl;

+/*u0*/CREATE VIEW xvwv28 AS

+    SELECT * FROM xvwt1 WHERE i in (0, 1, 11, 12);

+/*u0*/CREATE VIEW blaine.xvwv29 AS

+    SELECT * FROM xvwt1 WHERE i < 1;

+/*u0*/CREATE VIEW xvwv30 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT i FROM xvwj1);

+/*u0*/CREATE VIEW xvwv31 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i in (SELECT i FROM xvwj1);

+/*u0*/CREATE VIEW xvwv32 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT i FROM xvwj1 WHERE i = 0);

+/*u0*/CREATE VIEW xvwv33 AS

+    SELECT * FROM blaine.xvwt1 WHERE xvwt1.i = (SELECT i FROM xvwj1);

+SET SCHEMA public;

+-- (2nd SEL sub-query) should use Session default schema

+/*e*/CREATE VIEW blaine.xvwv101 AS

+    SELECT * FROM blaine.xvwt1 WHERE xvwt1.i in (SELECT i FROM xvwj1);

+SET SCHEMA blaine;

+/*u0*/CREATE VIEW blaine.xvwv34 AS

+    SELECT * FROM blaine.xvwt1 WHERE xvwt1.i in (SELECT i FROM xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv35 AS

+    SELECT * FROM blaine.xvwt1 WHERE xvwt1.i = (SELECT i FROM xvwj1 WHERE i = 0);

+/*u0*/CREATE VIEW blaine.xvwv36 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT i FROM blaine.xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv37 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i in (SELECT i FROM blaine.xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv38 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT i FROM blaine.xvwj1 WHERE i = 1);

+/*u0*/CREATE VIEW blaine.xvwv39 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT xvwj1.i FROM blaine.xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv40 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i in (SELECT xvwj1.i FROM xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv41 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT xvwj1.i FROM xvwj1 WHERE i = 1);

+/*u0*/CREATE VIEW blaine.xvwv42 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT i FROM blaine.xvwj1 WHERE xvwj1.i = 1);

+/*u0*/CREATE VIEW blaine.xvwv43 AS

+    SELECT * FROM xvwt1 WHERE xvwt1.i = (SELECT xvwj1.i FROM xvwj1 WHERE xvwj1.i = 1);

+/*u0*/CREATE VIEW blaine.xvwv44 AS

+    SELECT * FROM xvwt1 WHERE i = (SELECT i FROM xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv45 AS

+    SELECT * FROM xvwt1 WHERE i in (SELECT i FROM xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv46 AS

+    SELECT * FROM xvwt1 WHERE i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*u0*/CREATE VIEW blaine.xvwv47 AS

+    SELECT * FROM blaine.xvwt1 WHERE i = (SELECT i FROM xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv48 AS

+    SELECT * FROM blaine.xvwt1 WHERE i in (SELECT i FROM xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv49 AS

+    SELECT * FROM blaine.xvwt1 WHERE i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*u0*/CREATE VIEW blaine.xvwv50 AS

+    SELECT * FROM xvwt1 WHERE i = (SELECT i FROM blaine.xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv51 AS

+    SELECT * FROM xvwt1 WHERE i in (SELECT i FROM blaine.xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv52 AS

+    SELECT * FROM xvwt1 WHERE i = (SELECT i FROM blaine.xvwj1 WHERE i = 1);

+/*u0*/CREATE VIEW blaine.xvwv53 AS

+    SELECT * FROM xvwt1 WHERE i = (SELECT xvwj1.i FROM blaine.xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv54 AS

+    SELECT * FROM xvwt1 WHERE i in (SELECT xvwj1.i FROM xvwj1);

+/*u0*/CREATE VIEW blaine.xvwv55 AS

+    SELECT * FROM xvwt1 WHERE i = (SELECT xvwj1.i FROM xvwj1 WHERE i = 1);

+/*u0*/CREATE VIEW blaine.xvwv56 AS

+    SELECT * FROM xvwt1 WHERE i = (SELECT i FROM blaine.xvwj1 WHERE xvwj1.i = 1);

+/*u0*/CREATE VIEW blaine.xvwv57 AS

+    SELECT * FROM xvwt1 WHERE i = (SELECT xvwj1.i FROM xvwj1 WHERE xvwj1.i = 1);

+/*e*/DROP VIEW other.xvwv1;

+/*e*/DROP VIEW information_schema.xvwv2;

+

+--                  ******************************       MEM Indexes

+DROP INDEX xindi1 IF exists;

+DROP INDEX xindi2 IF exists;

+DROP INDEX xindi3 IF exists;

+DROP INDEX xindi4 IF exists;

+DROP INDEX xindi5 IF exists;

+DROP TABLE xindt1 IF exists;

+DROP TABLE xindt2 IF exists;

+DROP TABLE xindt3 IF exists;

+DROP TABLE xindt4 IF exists;

+DROP TABLE xindt101 IF exists;

+CREATE TABLE xindt1 (i int);

+INSERT INTO xindt1 values(0);

+INSERT INTO xindt1 values(1);

+CREATE TABLE xindt2 (i int);

+INSERT INTO xindt2 values(0);

+INSERT INTO xindt2 values(1);

+CREATE TABLE xindt3 (i int);

+INSERT INTO xindt3 values(0);

+INSERT INTO xindt3 values(1);

+CREATE TABLE xindt4 (i int);

+INSERT INTO xindt4 values(0);

+INSERT INTO xindt4 values(1);

+/*e*/CREATE UNIQUE INDEX other.xindi101 ON xindt4(i);

+/*e*/CREATE UNIQUE INDEX xindi101 ON xindt101(i);

+/*e*/CREATE UNIQUE INDEX blaine.xindi101 ON public.pscht2(i);

+/*e*/CREATE UNIQUE INDEX public.xindi101 ON xindt1(i);

+CREATE TABLE xindt101 (i int);

+INSERT INTO xindt101 values(0);

+INSERT INTO xindt101 values(1);

+/*e*/CREATE UNIQUE INDEX information_schema.xindi101 on xindt101(i int);

+/*u0*/CREATE UNIQUE INDEX xindi1 ON xindt1(i);

+/*e*/CREATE UNIQUE INDEX xindi1 ON xindt1(i); -- Create existing object

+/*u0*/CREATE UNIQUE INDEX blaine.xindi2 ON xindt2(i);

+/*e*/CREATE UNIQUE INDEX blaine.xindi2 ON xindt2(i); -- Create existing object

+/*u0*/CREATE UNIQUE INDEX xindi3 ON xindt3(i);

+SET SCHEMA public;

+/*u0*/CREATE UNIQUE INDEX xindi4 ON blaine.xindt4(i);

+SET SCHEMA blaine;

+-- The error message says that the schema name is invalid.

+-- Can only create indexes in same schema as target table.

+/*e*/CREATE UNIQUE INDEX xindi5 ON information_schema.system_users(user_name);

+/*e*/DROP INDEX other.xindi1;

+/*e*/DROP INDEX information_schema.xindi2;

+

+--                  ******************************      CACH Indexes

+DROP INDEX xcindi1 IF exists;

+DROP INDEX xcindi2 IF exists;

+DROP INDEX xcindi3 IF exists;

+DROP INDEX xcindi4 IF exists;

+DROP INDEX xcindi5 IF exists;

+DROP TABLE xcindt1 IF exists;

+DROP TABLE xcindt2 IF exists;

+DROP TABLE xcindt3 IF exists;

+DROP TABLE xcindt4 IF exists;

+DROP TABLE xcindt101 IF exists;

+CREATE TABLE xcindt1 (i int);

+INSERT INTO xcindt1 values(0);

+INSERT INTO xcindt1 values(1);

+CREATE TABLE xcindt2 (i int);

+INSERT INTO xcindt2 values(0);

+INSERT INTO xcindt2 values(1);

+CREATE TABLE xcindt3 (i int);

+INSERT INTO xcindt3 values(0);

+INSERT INTO xcindt3 values(1);

+CREATE TABLE xcindt4 (i int);

+INSERT INTO xcindt4 values(0);

+INSERT INTO xcindt4 values(1);

+/*e*/CREATE UNIQUE INDEX other.xcindi101 on xcindt101(i);

+CREATE TABLE xcindt101 (i int);

+INSERT INTO xcindt101 values(0);

+INSERT INTO xcindt101 values(1);

+/*e*/CREATE UNIQUE INDEX information_schema.xcindi101 on xcindt101(i int);

+/*u0*/CREATE UNIQUE INDEX xcindi1 ON xcindt1(i);

+/*e*/CREATE UNIQUE INDEX xcindi1 ON xcindt1(i); -- Create existing object

+/*u0*/CREATE UNIQUE INDEX blaine.xcindi2 ON xcindt2(i);

+/*e*/CREATE UNIQUE INDEX blaine.xcindi2 ON xcindt2(i); -- Create existing object

+/*u0*/CREATE UNIQUE INDEX xcindi3 ON xcindt3(i);

+/*u0*/CREATE UNIQUE INDEX xcindi4 ON xcindt4(i);

+-- The error message says that the schema name is invalid.

+-- Can only create indexes in same schema as target table.

+/*e*/CREATE UNIQUE INDEX xcindi5 ON information_schema.system_users(user_name);

+/*e*/DROP INDEX other.xcindi1;

+/*e*/DROP INDEX information_schema.xcindi2;

+

+--                  ******************************       Sequences

+DROP TABLE xseqt1 IF EXISTS;

+CREATE TABLE xseqt1 (i int);

+INSERT INTO xseqt1 VALUES(10);

+-- No "IF EXISTS" allowed with xsequences, so can't verify they don't exists.

+/*e*/CREATE SEQUENCE other.xs101;

+/*e*/CREATE SEQUENCE information_schema.xs101;

+/*u0*/CREATE SEQUENCE xs1;

+/*e*/CREATE SEQUENCE xs1; -- Create existing object

+SET SCHEMA public;

+/*u0*/CREATE SEQUENCE blaine.xs2;

+/*e*/CREATE SEQUENCE blaine.xs2; -- Create existing object

+-- To test persistence of incremented value:

+/*r0*/SELECT next value FOR blaine.xs2

+    FROM information_schema.system_users where user_name = 'SA';

+SET SCHEMA blaine;

+/*r1*/SELECT next value FOR xs2

+    FROM information_schema.system_users where user_name = 'SA';

+

+--                  ******************************       Triggers

+DROP TABLE xtrgt1 IF EXISTS;

+DROP TABLE xtrgt2 IF EXISTS;

+DROP TABLE xtrgt3 IF EXISTS;

+DROP TABLE xtrgt4 IF EXISTS;

+DROP TABLE xtrgt101 IF EXISTS;

+-- No "IF EXISTS" allowed with triggers, so can't verify they don't exists.

+CREATE TABLE xtrgt1 (i int);

+CREATE TABLE xtrgt2 (i int);

+CREATE TABLE xtrgt3 (i int);

+CREATE TABLE xtrgt4 (i int);

+/*e*/CREATE TRIGGER other.xtrgtrig101

+    AFTER INSERT ON xtrgt1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER xtrgtrig101

+    AFTER INSERT ON other.xtrgt1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER xtrgtrig101

+    AFTER INSERT ON information_schema.xtrgt1 CALL "org.hsqldb.test.BlaineTrig";

+/*e*/CREATE TRIGGER xtrgtrig101

+    AFTER INSERT ON xtrgt101 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TRIGGER xtrgtrig1

+    AFTER INSERT ON xtrgt1 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TRIGGER blaine.xtrgtrig2

+    AFTER INSERT ON xtrgt2 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+/*u0*/CREATE TRIGGER xtrgtrig3

+    AFTER INSERT ON blaine.xtrgt3 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+SET SCHEMA public;

+/*u0*/CREATE TRIGGER blaine.xtrgtrig4

+    AFTER INSERT ON blaine.xtrgt4 QUEUE 0 CALL "org.hsqldb.test.BlaineTrig";

+SET SCHEMA blaine;

+/*e*/DROP TRIGGER information_schema.xtrgtrig1;

+/*e*/DROP TRIGGER other.xtrgtrig1;

+

+--                  ******************************       Constraints

+DROP TABLE xcont1 IF EXISTS;

+DROP TABLE xcont2 IF EXISTS;

+DROP TABLE xcont3 IF EXISTS;

+DROP TABLE xcont4 IF EXISTS;

+DROP TABLE xcont5 IF EXISTS;

+DROP TABLE xcont6 IF EXISTS;

+DROP TABLE xcont7 IF EXISTS;

+DROP TABLE xcont8 IF EXISTS;

+DROP TABLE xcont9 IF EXISTS;

+DROP TABLE xcont10 IF EXISTS;

+DROP TABLE xcont11 IF EXISTS;

+DROP TABLE xcont12 IF EXISTS;

+DROP TABLE xcont13 IF EXISTS;

+DROP TABLE xcont14 IF EXISTS;

+DROP TABLE xcont15 IF EXISTS;

+DROP TABLE xcont16 IF EXISTS;

+DROP TABLE xcont17 IF EXISTS;

+DROP TABLE xcont18 IF EXISTS;

+DROP TABLE xcont19 IF EXISTS;

+DROP TABLE xcont20 IF EXISTS;

+DROP TABLE xcont101 IF EXISTS;

+CREATE TABLE xconj1(i int, vc varchar(10), PRIMARY KEY (i));

+INSERT INTO xconj1 values(1, 'one');

+-- No "IF EXISTS" allowed with xconstrs., so can't verify they don't exists.

+/*e*/CREATE TABLE other.xcont101 (i int, CONSTRAINT xconuc1 UNIQUE(i));

+/*e*/CREATE TABLE system_information.xcont1 (i int, CONSTRAINT xconuc1 UNIQUE(i));

+/*u0*/CREATE TABLE xcont1 (i int, CONSTRAINT xconuc1 UNIQUE(i));

+/*e*/CREATE TABLE xcont1 (i int, CONSTRAINT xconuc1 UNIQUE(i));

+/*e*/CREATE TABLE xcont101 (i int, CONSTRAINT xconuc1 UNIQUE(i)); -- xconuc1 already exists

+/*e*/CREATE TABLE xcont101 (i int, CONSTRAINT blaine.xconuc1 UNIQUE(i)); -- ditto

+/*u0*/CREATE TABLE blaine.xcont2 (i int, CONSTRAINT xconuc2 UNIQUE(i));

+/*e*/CREATE TABLE blaine.xcont101 (i int, CONSTRAINT xconuc2 UNIQUE(i)); -- xconuc2 already

+SET SCHEMA public;

+/*e*/CREATE TABLE blaine.xcont101 (i int, CONSTRAINT blaine.xconuc2 UNIQUE(i)); -- dit

+SET SCHEMA blaine;

+/*u0*/CREATE TABLE xcont3 (i int, CONSTRAINT blaine.xconuc3 UNIQUE(i));

+SET SCHEMA public;

+/*u0*/CREATE TABLE blaine.xcont4 (i int, CONSTRAINT blaine.xconuc4 UNIQUE(i));

+SET SCHEMA blaine;

+/*u0*/CREATE TABLE xcont5 (i int, CONSTRAINT xconpk5 PRIMARY KEY(i));

+/*u0*/CREATE TABLE blaine.xcont6 (i int, CONSTRAINT xconpk6 PRIMARY KEY(i));

+/*u0*/CREATE TABLE xcont7 (i int, CONSTRAINT blaine.xconpk7 PRIMARY KEY(i));

+/*u0*/CREATE TABLE blaine.xcont8 (i int, CONSTRAINT blaine.xconpk8 PRIMARY KEY(i));

+/*u0*/CREATE TABLE xcont9 (i int, CONSTRAINT xconfk9 FOREIGN KEY(i) REFERENCES xconj1(i));

+/*e*/CREATE TABLE xcont101 (i int, CONSTRAINT xconfk9 FOREIGN KEY(i)

+    REFERENCES other.xconj1(i));

+/*e*/CREATE TABLE xcont101 (i int, CONSTRAINT xconfk9 FOREIGN KEY(i)

+    REFERENCES information_schema.xconj1(i));

+/*u0*/CREATE TABLE blaine.xcont10 (i int, CONSTRAINT xconfk10

+    FOREIGN KEY(i) REFERENCES xconj1(i));

+/*u0*/CREATE TABLE xcont11 (i int, CONSTRAINT blaine.xconfk11

+    FOREIGN KEY(i) REFERENCES xconj1(i));

+/*u0*/CREATE TABLE blaine.xcont12 (i int, CONSTRAINT blaine.xconfk12

+    FOREIGN KEY(i) REFERENCES xconj1(i));

+-- Test prohibit create fk -> another-schema with every thing else ok.

+CREATE TABLE public.badtarget(i int, unique (i));

+/*u0*/CREATE TABLE xcont13 (i int, CONSTRAINT xconfk13 FOREIGN KEY(i)

+    REFERENCES public.badtarget(i));

+/*e*/CREATE TABLE xcont13 (i int, CONSTRAINT xconfk13 FOREIGN KEY(i)

+    REFERENCES blaine.xconj1(i));

+/*u0*/CREATE TABLE blaine.xcont14 (i int, CONSTRAINT xconfk14

+    FOREIGN KEY(i) REFERENCES blaine.xconj1(i));

+/*u0*/CREATE TABLE xcont15 (i int, CONSTRAINT blaine.xconfk15

+    FOREIGN KEY(i) REFERENCES blaine.xconj1(i));

+SET SCHEMA public;

+/*u0*/CREATE TABLE blaine.xcont16 (i int, CONSTRAINT blaine.xconfk16

+    FOREIGN KEY(i) REFERENCES blaine.xconj1(i));

+SET SCHEMA blaine;

+/*u0*/CREATE TABLE xcont17 (i int, CONSTRAINT xconc17 CHECK (i < 1));

+/*u0*/CREATE TABLE blaine.xcont18 (i int, CONSTRAINT xconc18 CHECK (i in (0, 2)));

+/*u0*/CREATE TABLE xcont19 (i int, CONSTRAINT blaine.xconc19 CHECK (i = 0));

+SET SCHEMA public;

+/*u0*/CREATE TABLE blaine.xcont20 (i int, CONSTRAINT blaine.xconc20 CHECK (i != 1));

+

+-- schema definition with table, view and sequenence

+

+-- schema definition containing illegal DDL statement

+/*e*/CREATE SCHEMA FELIX AUTHORIZATION DBA

+    CREATE TABLE FELIXT1 (AV1 VARCHAR(10), BV VARCHAR(10))

+    CREATE TABLE FELIXT2 (AV2 VARCHAR(10), BI INTEGER)

+    CREATE SEQUENCE FELIXS1

+    CREATE VIEW FELIXV1 AS SELECT * FROM FELIXT1 JOIN FELIXT2 ON AV1 = AV2

+    CREATE VIEW FELIXV2 AS SELECT AV1 AS C1, NEXT VALUE FOR FELIXS1 AS C2 FROM FELIXT1

+    ALTER TABLE FELIXT1 ADD PRIMARY KEY;

+/*e*/SET SCHEMA FELIX

+/*e*/SELECT * FROM FELIX.FELIXT1

+

+-- schema definition

+CREATE SCHEMA FELIX AUTHORIZATION DBA

+    CREATE TABLE FELIXT1 (AV1 VARCHAR(10), BV VARCHAR(10))

+    CREATE TABLE FELIXT2 (AV2 VARCHAR(10), BI INTEGER)

+    CREATE SEQUENCE FELIXS1

+    CREATE VIEW FELIXV1 AS SELECT * FROM FELIXT1 JOIN FELIXT2 ON AV1 = AV2

+    CREATE VIEW FELIXV2 AS SELECT AV1 AS C1, NEXT VALUE FOR FELIXS1 AS C2 FROM FELIXT1;

+/*e*/SELECT * FROM FELIXV1

+SET SCHEMA FELIX

+/*c0*/SELECT * FROM FELIXV1

+

+--                  ******************************       ALTERs

+-- Add tests when time permits.

+

+

+/*u0*/SET SCHEMA blaine; -- Sanity.  Cf. 1st 2 lines of B2 script.

+/*c2*/SELECT * FROM xtblt1; -- Sanity.  Cf. 1st 2 lines of B2 script.

+-- This to test recovery from .log files.

+COMMIT;

+SHUTDOWN IMMEDIATELY;

diff --git a/testrun/hsqldb/TestSelfSchemaPersistB2.txt b/testrun/hsqldb/TestSelfSchemaPersistB2.txt
new file mode 100644
index 0000000..4ae9733
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaPersistB2.txt
@@ -0,0 +1,600 @@
+-- TEST OBJECTS

+

+-- This TESTS the schema-specific objects created in a previous script.

+-- (See the *C[12].txt scripts for similar tests of ALTER comands (which

+-- this script purposefully omits).

+

+

+/*u0*/SET SCHEMA blaine;

+CREATE USER otheruser PASSWORD otheruser;

+

+--                  ******************************       MEM Tables

+/*c2*/SELECT * FROM xtblt1;

+/*c1*/SELECT * FROM xtblt1 WHERE i = 0;

+/*c2*/SELECT * FROM xtblt1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM xtblt1 WHERE i < 1;

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT i FROM xtblj1 WHERE xtblj1.i = 1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i in (SELECT i FROM xtblj1);

+/*c0*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT i FROM xtblj1 WHERE i = 0);

+/*c1*/SELECT * FROM blaine.xtblt1 WHERE xtblt1.i = (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM blaine.xtblt1 WHERE xtblt1.i in (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM blaine.xtblt1 WHERE xtblt1.i = (SELECT i FROM xtblj1 WHERE i = 1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i in (SELECT i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT i FROM blaine.xtblj1 WHERE i = 1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT xtblj1.i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i in (SELECT xtblj1.i FROM xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT xtblj1.i FROM xtblj1 WHERE i = 1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT i FROM blaine.xtblj1 WHERE xtblj1.i = 1);

+/*c1*/SELECT * FROM xtblt1 WHERE xtblt1.i = (SELECT xtblj1.i FROM xtblj1 WHERE xtblj1.i = 1);

+/*c1*/SELECT * FROM xtblt1 WHERE i = (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE i in (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE i = (SELECT i FROM xtblj1 WHERE i = 1);

+/*c1*/SELECT * FROM blaine.xtblt1 WHERE i = (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM blaine.xtblt1 WHERE i in (SELECT i FROM xtblj1);

+/*c0*/SELECT * FROM blaine.xtblt1 WHERE i = (SELECT i FROM xtblj1 WHERE i = 0);

+/*c1*/SELECT * FROM xtblt1 WHERE i = (SELECT i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE i in (SELECT i FROM blaine.xtblj1);

+/*c0*/SELECT * FROM xtblt1 WHERE i = (SELECT i FROM blaine.xtblj1 WHERE i = 0);

+/*c1*/SELECT * FROM xtblt1 WHERE i = (SELECT xtblj1.i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xtblt1 WHERE i in (SELECT xtblj1.i FROM xtblj1);

+/*c0*/SELECT * FROM xtblt1 WHERE i = (SELECT xtblj1.i FROM xtblj1 WHERE i = 0);

+/*c1*/SELECT * FROM xtblt1 WHERE i = (SELECT i FROM blaine.xtblj1 WHERE xtblj1.i = 1);

+/*c1*/SELECT * FROM xtblt1 WHERE i = (SELECT xtblj1.i FROM xtblj1 WHERE xtblj1.i = 1);

+/*e*/SELECT * FROM system_users WHERE user_name = 'SA';

+/*e*/SELECT * FROM other.xtblt1;

+/*e*/SELECT * FROM other.system_users;

+/*e*/SELECT * FROM information_schema.xtblt1;

+SET SCHEMA public;

+/*e*/SELECT * FROM blaine.system_users;

+/*c2*/SELECT * FROM blaine.xtblt1;

+SET SCHEMA blaine;

+/*c1*/SELECT * FROM information_schema.system_users WHERE user_name = 'SA';

+SET SCHEMA public;

+/*c1*/SELECT * FROM blaine.xtblt1 WHERE i = 0;

+SET SCHEMA blaine;

+/*e*/SELECT * FROM other.xtblt1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.xtblt1 WHERE i = 0;

+SET SCHEMA public;

+/*c1*/SELECT * FROM blaine.xtblt1, blaine.xtblj1 WHERE xtblt1.i = xtblj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT * FROM xtblt1, blaine.xtblj1 WHERE xtblt1.i = xtblj1.i;

+/*c1*/SELECT * FROM blaine.xtblt1, xtblj1 WHERE xtblt1.i = xtblj1.i;

+/*c1*/SELECT * FROM xtblt1, xtblj1 WHERE xtblt1.i = xtblj1.i;

+SET SCHEMA public;

+/*c1*/SELECT vc FROM blaine.xtblt1, blaine.xtblj1 WHERE xtblt1.i = xtblj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT vc FROM xtblt1, blaine.xtblj1 WHERE xtblt1.i = xtblj1.i;

+/*c1*/SELECT vc FROM blaine.xtblt1, xtblj1 WHERE xtblt1.i = xtblj1.i;

+/*c1*/SELECT vc FROM xtblt1, xtblj1 WHERE xtblt1.i = xtblj1.i;

+SET SCHEMA public;

+/*c1*/SELECT xtblj1.vc FROM blaine.xtblt1, blaine.xtblj1 WHERE xtblt1.i = xtblj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT xtblj1.vc FROM xtblt1, blaine.xtblj1 WHERE xtblt1.i = xtblj1.i;

+/*c1*/SELECT xtblj1.vc FROM blaine.xtblt1, xtblj1 WHERE xtblt1.i = xtblj1.i;

+/*c1*/SELECT xtblj1.vc FROM xtblt1, xtblj1 WHERE xtblt1.i = xtblj1.i;

+/*c1*/SELECT lbla.vc FROM xtblt1, xtblj1 lbla WHERE xtblt1.i = lbla.i;

+/*c1*/SELECT xtblj1.vc FROM xtblt1 lblb, xtblj1 WHERE lblb.i = xtblj1.i;

+/*c1*/SELECT lbla.vc FROM xtblt1 lblb, xtblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM blaine.xtblt1, xtblj1 lbla WHERE xtblt1.i = lbla.i;

+/*c1*/SELECT xtblj1.vc FROM blaine.xtblt1 lblb, xtblj1 WHERE lblb.i = xtblj1.i;

+/*c1*/SELECT lbla.vc FROM blaine.xtblt1 lblb, xtblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM xtblt1, blaine.xtblj1 lbla WHERE xtblt1.i = lbla.i;

+/*c1*/SELECT xtblj1.vc FROM xtblt1 lblb, blaine.xtblj1 WHERE lblb.i = xtblj1.i;

+/*c1*/SELECT lbla.vc FROM xtblt1 lblb, blaine.xtblj1 lbla WHERE lblb.i = lbla.i;

+/*u0*/SET TABLE xtblt1 READONLY true;

+/*e*/UPDATE xtblt1 set i = 11 WHERE i = 1;

+SET SCHEMA public;

+/*u0*/SET TABLE blaine.xtblt1 READONLY true;

+/*e*/SET TABLE information_schema.xtblt1 READONLY true;

+/*e*/SET TABLE other.xtblt1 READONLY true;

+SET SCHEMA blaine;

+/*u0*/SET TABLE xtblt1 READONLY false;

+SET SCHEMA public;

+/*u0*/SET TABLE blaine.xtblt1 READONLY false;

+SET SCHEMA blaine;

+/*c2*/SELECT i FROM xtblt1;

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+COMMIT;

+SET AUTOCOMMIT false;

+/*u1*/UPDATE xtblt1 set i = 11 WHERE i = 1;

+/*u1*/UPDATE xtblt1 set xtblt1.i = 12 WHERE i = 11;

+/*u1*/UPDATE xtblt1 set xtblt1.i = 13 WHERE xtblt1.i = 12;

+SET SCHEMA public;

+/*u1*/UPDATE blaine.xtblt1 set i = 14 WHERE i = 13;

+/*u1*/UPDATE blaine.xtblt1 set xtblt1.i = 15 WHERE i = 14;

+/*u1*/UPDATE blaine.xtblt1 set xtblt1.i = 16 WHERE xtblt1.i = 15;

+SET SCHEMA blaine;

+/*e*/UPDATE other.xtblt1 set xtblt1.i = 17 WHERE xtblt1.i = 16;

+/*e*/UPDATE information_schema.xtblt1 set xtblt1.i = 17 WHERE xtblt1.i = 16;

+/*u1*/UPDATE xtblt1 ali set i = 17 WHERE i = 16;

+/*u1*/UPDATE xtblt1 ali set ali.i = 18 WHERE i = 17;

+/*u1*/UPDATE xtblt1 ali set ali.i = 19 WHERE ali.i = 18;

+/*u1*/UPDATE xtblt1 ali set i = 20 WHERE ali.i = 19;

+SET SCHEMA public;

+/*u1*/UPDATE blaine.xtblt1 ali set i = 21 WHERE i = 20;

+/*u1*/UPDATE blaine.xtblt1 ali set ali.i = 22 WHERE i = 21;

+/*u1*/UPDATE blaine.xtblt1 ali set ali.i = 23 WHERE ali.i = 22;

+/*u1*/UPDATE blaine.xtblt1 ali set i = 24 WHERE ali.i = 23;

+SET SCHEMA blaine;

+/*e*/UPDATE other.xtblt1 ali set i = 25 WHERE ali.i = 24;

+/*e*/UPDATE other.xtblt1 ali set i = 25 WHERE .i = 24;

+/*e*/UPDATE other.xtblt1 set i = 25 WHERE i = 24;

+/*e*/DELETE FROM other.xtblt1 ali WHERE ali.i = 24;

+/*e*/DELETE FROM other.xtblt1 ali;

+/*e*/DELETE FROM other.xtblt1 set WHERE i = 24;

+/*e*/DELETE FROM other.xtblt1 WHERE i = 24;

+/*e*/DELETE FROM system_information.xtblj1 WHERE xtblj1.i = 1;

+/*u1*/DELETE FROM xtblt1 WHERE i = 0;

+SET SCHEMA public;

+/*u1*/DELETE FROM blaine.xtblt1 WHERE i = 24;

+/*u1*/DELETE FROM blaine.xtblj1 WHERE xtblj1.i = 1;

+SET SCHEMA blaine;

+ROLLBACK;

+/*c2*/SELECT i FROM xtblt1;

+/*u0*/GRANT ALL ON xtblt1 TO otheruser;

+SET SCHEMA public;

+/*u0*/GRANT ALL ON blaine.xtblt2 TO otheruser;

+SET SCHEMA blaine;

+/*e*/GRANT ALL ON other.xtblt3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.xtblt3 TO otheruser;

+/*u0*/REVOKE ALL ON xtblt1 FROM otheruser RESTRICT;

+SET SCHEMA public;

+/*u0*/REVOKE ALL ON blaine.xtblt2 FROM otheruser RESTRICT;

+SET SCHEMA blaine;

+/*e*/REVOKE ALL ON other.xtblt3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.xtblt3 FROM otheruser RESTRICT;

+/*e*/DROP TABLE other.xtblt3;

+/*e*/DROP TABLE information_schema.xtblt4;

+/*e*/DROP TABLE xtblt101;

+/*e*/DROP TABLE blaine.xtblt101;

+/*u0*/DROP TABLE xtblt101 IF EXISTS;

+SET SCHEMA public;

+/*u0*/DROP TABLE blaine.xtblt101 IF EXISTS;

+SET SCHEMA blaine;

+-- Should "DROP TABLE nonexistentschema.notable IF EXISTS" work?

+/*u0*/DROP TABLE other.system_users IF exists;

+/*u0*/DROP TABLE system_users IF exists;

+

+--                  ******************************       CACH Tables

+/*c2*/SELECT * FROM xctblt1;

+/*c1*/SELECT * FROM xctblt1 WHERE i = 0;

+/*c2*/SELECT * FROM xctblt1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM xctblt1 WHERE i < 1;

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT i FROM xtblj1 WHERE xtblj1.i = 1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i in (SELECT i FROM xtblj1);

+/*c0*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT i FROM xtblj1 WHERE i = 0);

+/*c1*/SELECT * FROM blaine.xctblt1 WHERE xctblt1.i = (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM blaine.xctblt1 WHERE xctblt1.i in (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM blaine.xctblt1 WHERE xctblt1.i = (SELECT i FROM xtblj1 WHERE i = 1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i in (SELECT i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT i FROM blaine.xtblj1 WHERE i = 1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT xtblj1.i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i in (SELECT xtblj1.i FROM xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT xtblj1.i FROM xtblj1 WHERE i = 1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT i FROM blaine.xtblj1 WHERE xtblj1.i = 1);

+/*c1*/SELECT * FROM xctblt1 WHERE xctblt1.i = (SELECT xtblj1.i FROM xtblj1 WHERE xtblj1.i = 1);

+/*c1*/SELECT * FROM xctblt1 WHERE i = (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE i in (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE i = (SELECT i FROM xtblj1 WHERE i = 1);

+/*c1*/SELECT * FROM blaine.xctblt1 WHERE i = (SELECT i FROM xtblj1);

+/*c1*/SELECT * FROM blaine.xctblt1 WHERE i in (SELECT i FROM xtblj1);

+/*c0*/SELECT * FROM blaine.xctblt1 WHERE i = (SELECT i FROM xtblj1 WHERE i = 0);

+/*c1*/SELECT * FROM xctblt1 WHERE i = (SELECT i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE i in (SELECT i FROM blaine.xtblj1);

+/*c0*/SELECT * FROM xctblt1 WHERE i = (SELECT i FROM blaine.xtblj1 WHERE i = 0);

+/*c1*/SELECT * FROM xctblt1 WHERE i = (SELECT xtblj1.i FROM blaine.xtblj1);

+/*c1*/SELECT * FROM xctblt1 WHERE i in (SELECT xtblj1.i FROM xtblj1);

+/*c0*/SELECT * FROM xctblt1 WHERE i = (SELECT xtblj1.i FROM xtblj1 WHERE i = 0);

+/*c1*/SELECT * FROM xctblt1 WHERE i = (SELECT i FROM blaine.xtblj1 WHERE xtblj1.i = 1);

+/*c1*/SELECT * FROM xctblt1 WHERE i = (SELECT xtblj1.i FROM xtblj1 WHERE xtblj1.i = 1);

+/*e*/SELECT * FROM system_users WHERE user_name = 'SA';

+/*e*/SELECT * FROM other.xctblt1;

+/*e*/SELECT * FROM other.system_users;

+/*e*/SELECT * FROM information_schema.xctblt1;

+/*e*/SELECT * FROM blaine.system_users;

+SET SCHEMA public;

+/*c2*/SELECT * FROM blaine.xctblt1;

+/*c1*/SELECT * FROM information_schema.system_users WHERE user_name = 'SA';

+/*c1*/SELECT * FROM blaine.xctblt1 WHERE i = 0;

+/*e*/SELECT * FROM other.xctblt1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.xctblt1 WHERE i = 0;

+/*c1*/SELECT * FROM blaine.xctblt1, blaine.xtblj1 WHERE xctblt1.i = xtblj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT * FROM xctblt1, blaine.xtblj1 WHERE xctblt1.i = xtblj1.i;

+/*c1*/SELECT * FROM blaine.xctblt1, xtblj1 WHERE xctblt1.i = xtblj1.i;

+/*c1*/SELECT * FROM xctblt1, xtblj1 WHERE xctblt1.i = xtblj1.i;

+SET SCHEMA public;

+/*c1*/SELECT vc FROM blaine.xctblt1, blaine.xtblj1 WHERE xctblt1.i = xtblj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT vc FROM xctblt1, blaine.xtblj1 WHERE xctblt1.i = xtblj1.i;

+/*c1*/SELECT vc FROM blaine.xctblt1, xtblj1 WHERE xctblt1.i = xtblj1.i;

+/*c1*/SELECT vc FROM xctblt1, xtblj1 WHERE xctblt1.i = xtblj1.i;

+SET SCHEMA public;

+/*c1*/SELECT xtblj1.vc FROM blaine.xctblt1, blaine.xtblj1 WHERE xctblt1.i = xtblj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT xtblj1.vc FROM xctblt1, blaine.xtblj1 WHERE xctblt1.i = xtblj1.i;

+/*c1*/SELECT xtblj1.vc FROM blaine.xctblt1, xtblj1 WHERE xctblt1.i = xtblj1.i;

+/*c1*/SELECT xtblj1.vc FROM xctblt1, xtblj1 WHERE xctblt1.i = xtblj1.i;

+/*c1*/SELECT lbla.vc FROM xctblt1, xtblj1 lbla WHERE xctblt1.i = lbla.i;

+/*c1*/SELECT xtblj1.vc FROM xctblt1 lblb, xtblj1 WHERE lblb.i = xtblj1.i;

+/*c1*/SELECT lbla.vc FROM xctblt1 lblb, xtblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM blaine.xctblt1, xtblj1 lbla WHERE xctblt1.i = lbla.i;

+/*c1*/SELECT xtblj1.vc FROM blaine.xctblt1 lblb, xtblj1 WHERE lblb.i = xtblj1.i;

+/*c1*/SELECT lbla.vc FROM blaine.xctblt1 lblb, xtblj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM xctblt1, blaine.xtblj1 lbla WHERE xctblt1.i = lbla.i;

+/*c1*/SELECT xtblj1.vc FROM xctblt1 lblb, blaine.xtblj1 WHERE lblb.i = xtblj1.i;

+/*c1*/SELECT lbla.vc FROM xctblt1 lblb, blaine.xtblj1 lbla WHERE lblb.i = lbla.i;

+/*u0*/SET TABLE xctblt1 READONLY true;

+/*e*/UPDATE xctblt1 set i = 11 WHERE i = 1;

+SET SCHEMA public;

+/*u0*/SET TABLE blaine.xctblt1 READONLY true;

+SET SCHEMA blaine;

+/*e*/SET TABLE information_schema.xctblt1 READONLY true;

+/*e*/SET TABLE other.xctblt1 READONLY true;

+/*u0*/SET TABLE xctblt1 READONLY false;

+SET SCHEMA public;

+/*u0*/SET TABLE blaine.xctblt1 READONLY false;

+SET SCHEMA blaine;

+/*c2*/SELECT i FROM xctblt1;

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+COMMIT;

+SET AUTOCOMMIT false;

+/*u1*/UPDATE xctblt1 set i = 11 WHERE i = 1;

+/*u1*/UPDATE xctblt1 set xctblt1.i = 12 WHERE i = 11;

+/*u1*/UPDATE xctblt1 set xctblt1.i = 13 WHERE xctblt1.i = 12;

+SET SCHEMA public;

+/*u1*/UPDATE blaine.xctblt1 set i = 14 WHERE i = 13;

+/*u1*/UPDATE blaine.xctblt1 set xctblt1.i = 15 WHERE i = 14;

+/*u1*/UPDATE blaine.xctblt1 set xctblt1.i = 16 WHERE xctblt1.i = 15;

+SET SCHEMA blaine;

+/*e*/UPDATE other.xctblt1 set xctblt1.i = 17 WHERE xctblt1.i = 16;

+/*e*/UPDATE information_schema.xctblt1 set xctblt1.i = 17 WHERE xctblt1.i = 16;

+/*u1*/UPDATE xctblt1 ali set i = 17 WHERE i = 16;

+/*u1*/UPDATE xctblt1 ali set ali.i = 18 WHERE i = 17;

+/*u1*/UPDATE xctblt1 ali set ali.i = 19 WHERE ali.i = 18;

+/*u1*/UPDATE xctblt1 ali set i = 20 WHERE ali.i = 19;

+SET SCHEMA public;

+/*u1*/UPDATE blaine.xctblt1 ali set i = 21 WHERE i = 20;

+/*u1*/UPDATE blaine.xctblt1 ali set ali.i = 22 WHERE i = 21;

+/*u1*/UPDATE blaine.xctblt1 ali set ali.i = 23 WHERE ali.i = 22;

+/*u1*/UPDATE blaine.xctblt1 ali set i = 24 WHERE ali.i = 23;

+SET SCHEMA blaine;

+/*e*/UPDATE other.xctblt1 ali set i = 25 WHERE ali.i = 24;

+/*e*/UPDATE other.xctblt1 ali set i = 25 WHERE .i = 24;

+/*e*/UPDATE other.xctblt1 set i = 25 WHERE i = 24;

+/*e*/DELETE FROM other.xctblt1 ali WHERE ali.i = 24;

+/*e*/DELETE FROM other.xctblt1 ali;

+/*e*/DELETE FROM other.xctblt1 set WHERE i = 24;

+/*e*/DELETE FROM other.xctblt1 WHERE i = 24;

+/*e*/DELETE FROM system_information.xtblj1 WHERE xtblj1.i = 1;

+/*u1*/DELETE FROM xctblt1 WHERE i = 0;

+SET SCHEMA public;

+/*u1*/DELETE FROM blaine.xctblt1 WHERE i = 24;

+/*u1*/DELETE FROM blaine.xtblj1 WHERE xtblj1.i = 1;

+SET SCHEMA blaine;

+ROLLBACK;

+/*c2*/SELECT i FROM xctblt1;

+/*u0*/GRANT ALL ON xctblt1 TO otheruser;

+SET SCHEMA public;

+/*u0*/GRANT ALL ON blaine.xctblt2 TO otheruser;

+SET SCHEMA blaine;

+/*e*/GRANT ALL ON other.xctblt3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.xctblt3 TO otheruser;

+/*u0*/REVOKE ALL ON xctblt1 FROM otheruser RESTRICT;

+SET SCHEMA public;

+/*u0*/REVOKE ALL ON blaine.xctblt2 FROM otheruser RESTRICT;

+SET SCHEMA blaine;

+/*e*/REVOKE ALL ON other.xctblt3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.xctblt3 FROM otheruser RESTRICT;

+/*e*/DROP TABLE other.xctblt3;

+/*e*/DROP TABLE information_schema.xctblt4;

+/*e*/DROP TABLE xctblt101;

+/*e*/DROP TABLE blaine.xctblt101;

+/*u0*/DROP TABLE xctblt101 IF EXISTS;

+SET SCHEMA public;

+/*u0*/DROP TABLE blaine.xctblt101 IF EXISTS;

+SET SCHEMA blaine;

+-- Should "DROP TABLE nonexistentschema.notable IF EXISTS" work?

+/*u0*/DROP TABLE other.system_users IF exists;

+/*u0*/DROP TABLE system_users IF exists;

+

+--                  ******************************       Views

+/*c2*/SELECT * FROM xvwv1;

+SET SCHEMA public;

+/*c2*/SELECT * FROM blaine.xvwv1;

+SET SCHEMA blaine;

+/*c2*/SELECT * FROM xvwv2;

+/*c2*/SELECT * FROM xvwv3;

+/*c1*/SELECT * FROM xvwv4;

+/*c1*/SELECT * FROM xvwv5;

+/*c1*/SELECT * FROM xvwv8;

+/*c0*/SELECT * FROM xvwv9;

+/*c0*/SELECT * FROM xvwv10;

+/*c0*/SELECT * FROM xvwv11;

+/*c0*/SELECT * FROM xvwv12;

+/*e*/SELECT * FROM xvwv13;

+/*c0*/SELECT * FROM xvwv14;

+/*c0*/SELECT * FROM xvwv15;

+/*c0*/SELECT * FROM xvwv16;

+/*c0*/SELECT * FROM xvwv17;

+/*c0*/SELECT * FROM xvwv18;

+/*c1*/SELECT * FROM xvwv19;

+/*c1*/SELECT * FROM xvwv20;

+/*c1*/SELECT * FROM xvwv21;

+/*c1*/SELECT * FROM xvwv22;

+/*c1*/SELECT * FROM xvwv23;

+/*c1*/SELECT * FROM xvwv24;

+/*c1*/SELECT * FROM xvwv25;

+/*c1*/SELECT * FROM xvwv26;

+/*c2*/SELECT * FROM xvwv28;

+/*c1*/SELECT * FROM xvwv29;

+/*c1*/SELECT * FROM xvwv30;

+/*c1*/SELECT * FROM xvwv31;

+/*c0*/SELECT * FROM xvwv32;

+/*c1*/SELECT * FROM xvwv33;

+/*c1*/SELECT * FROM xvwv34;

+/*c0*/SELECT * FROM xvwv35;

+/*c1*/SELECT * FROM xvwv36;

+/*c1*/SELECT * FROM xvwv37;

+/*c1*/SELECT * FROM xvwv38;

+/*c1*/SELECT * FROM xvwv39;

+/*c1*/SELECT * FROM xvwv40;

+/*c1*/SELECT * FROM xvwv41;

+/*c1*/SELECT * FROM xvwv42;

+/*c1*/SELECT * FROM xvwv43;

+/*c1*/SELECT * FROM xvwv44;

+/*c1*/SELECT * FROM xvwv45;

+/*c1*/SELECT * FROM xvwv46;

+/*c1*/SELECT * FROM xvwv47;

+/*c1*/SELECT * FROM xvwv48;

+/*c1*/SELECT * FROM xvwv49;

+/*c1*/SELECT * FROM xvwv50;

+/*c1*/SELECT * FROM xvwv51;

+/*c1*/SELECT * FROM xvwv52;

+/*c1*/SELECT * FROM xvwv53;

+/*c1*/SELECT * FROM xvwv54;

+/*c1*/SELECT * FROM xvwv55;

+/*c1*/SELECT * FROM xvwv56;

+/*c1*/SELECT * FROM xvwv57;

+/*c1*/SELECT * FROM xvwv1, xvwj1 WHERE xvwv1.i = xvwj1.i;

+SET SCHEMA public;

+/*c1*/SELECT * FROM blaine.xvwv1, blaine.xvwj1 WHERE xvwv1.i = xvwj1.i;

+SET SCHEMA blaine;

+/*c2*/SELECT * FROM xvwv1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM xvwv1 WHERE i < 1;

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i in (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE xvwv1.i in (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE xvwv1.i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i in (SELECT i FROM blaine.xvwj1);

+/*c0*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM blaine.xvwj1 WHERE i = 0);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT xvwj1.i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i in (SELECT xvwj1.i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT xvwj1.i FROM xvwj1 WHERE i = 1);

+/*c0*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM blaine.xvwj1 WHERE xvwj1.i = 0);

+/*c0*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT xvwj1.i FROM xvwj1 WHERE xvwj1.i = 0);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i in (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE i = (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE i in (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i in (SELECT i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM blaine.xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT xvwj1.i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i in (SELECT xvwj1.i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT xvwj1.i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM blaine.xvwj1 WHERE xvwj1.i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT xvwj1.i FROM xvwj1 WHERE xvwj1.i = 1);

+/*c2*/SELECT * FROM xvwv1;

+/*c1*/SELECT * FROM xvwv1 WHERE i = 0;

+/*c2*/SELECT * FROM xvwv1 WHERE i in (0, 1, 11, 12);

+/*c1*/SELECT * FROM xvwv1 WHERE i < 1;

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i in (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE xvwv1.i = (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE xvwv1.i in (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE xvwv1.i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i in (SELECT i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM blaine.xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT xvwj1.i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i in (SELECT xvwj1.i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT xvwj1.i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT i FROM blaine.xvwj1 WHERE xvwj1.i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE xvwv1.i = (SELECT xvwj1.i FROM xvwj1 WHERE xvwj1.i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i in (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE i = (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE i in (SELECT i FROM xvwj1);

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE i = (SELECT i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i in (SELECT i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM blaine.xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT xvwj1.i FROM blaine.xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i in (SELECT xvwj1.i FROM xvwj1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT xvwj1.i FROM xvwj1 WHERE i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT i FROM blaine.xvwj1 WHERE xvwj1.i = 1);

+/*c1*/SELECT * FROM xvwv1 WHERE i = (SELECT xvwj1.i FROM xvwj1 WHERE xvwj1.i = 1);

+/*e*/SELECT * FROM other.xvwv1;

+/*e*/SELECT * FROM information_schema.xvwv1;

+SET SCHEMA public;

+/*c2*/SELECT * FROM blaine.xvwv1;

+/*c1*/SELECT * FROM blaine.xvwv1 WHERE i = 0;

+SET SCHEMA blaine;

+/*e*/SELECT * FROM other.xvwv1 WHERE i = 0;

+/*e*/SELECT * FROM information_schema.xvwv1 WHERE i = 0;

+SET SCHEMA public;

+CREATE TABLE blaine.vwt2 AS (SELECT *  FROM blaine.xvwv1 WHERE i = 0) WITH DATA;

+/*c1*/SELECT * FROM blaine.vwt2;

+SET SCHEMA blaine;

+DROP TABLE vwt2;

+SET SCHEMA public;

+/*c1*/SELECT * FROM blaine.xvwv1, blaine.xvwj1 WHERE xvwv1.i = xvwj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT * FROM xvwv1, blaine.xvwj1 WHERE xvwv1.i = xvwj1.i;

+/*c1*/SELECT * FROM blaine.xvwv1, xvwj1 WHERE xvwv1.i = xvwj1.i;

+/*c1*/SELECT * FROM xvwv1, xvwj1 WHERE xvwv1.i = xvwj1.i;

+SET SCHEMA public;

+/*c1*/SELECT vc FROM blaine.xvwv1, blaine.xvwj1 WHERE xvwv1.i = xvwj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT vc FROM xvwv1, blaine.xvwj1 WHERE xvwv1.i = xvwj1.i;

+/*c1*/SELECT vc FROM blaine.xvwv1, xvwj1 WHERE xvwv1.i = xvwj1.i;

+/*c1*/SELECT vc FROM xvwv1, xvwj1 WHERE xvwv1.i = xvwj1.i;

+SET SCHEMA public;

+/*c1*/SELECT xvwj1.vc FROM blaine.xvwv1, blaine.xvwj1 WHERE xvwv1.i = xvwj1.i;

+SET SCHEMA blaine;

+/*c1*/SELECT xvwj1.vc FROM xvwv1, blaine.xvwj1 WHERE xvwv1.i = xvwj1.i;

+/*c1*/SELECT xvwj1.vc FROM blaine.xvwv1, xvwj1 WHERE xvwv1.i = xvwj1.i;

+/*c1*/SELECT xvwj1.vc FROM xvwv1, xvwj1 WHERE xvwv1.i = xvwj1.i;

+/*c1*/SELECT lbla.vc FROM xvwv1, xvwj1 lbla WHERE xvwv1.i = lbla.i;

+/*c1*/SELECT xvwj1.vc FROM xvwv1 lblb, xvwj1 WHERE lblb.i = xvwj1.i;

+/*c1*/SELECT lbla.vc FROM xvwv1 lblb, xvwj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM blaine.xvwv1, xvwj1 lbla WHERE xvwv1.i = lbla.i;

+/*c1*/SELECT xvwj1.vc FROM blaine.xvwv1 lblb, xvwj1 WHERE lblb.i = xvwj1.i;

+/*c1*/SELECT lbla.vc FROM blaine.xvwv1 lblb, xvwj1 lbla WHERE lblb.i = lbla.i;

+/*c1*/SELECT lbla.vc FROM xvwv1, blaine.xvwj1 lbla WHERE xvwv1.i = lbla.i;

+/*c1*/SELECT xvwj1.vc FROM xvwv1 lblb, blaine.xvwj1 WHERE lblb.i = xvwj1.i;

+/*c1*/SELECT lbla.vc FROM xvwv1 lblb, blaine.xvwj1 lbla WHERE lblb.i = lbla.i;

+/*u0*/GRANT ALL ON xvwv1 TO otheruser;

+SET SCHEMA public;

+/*u0*/GRANT ALL ON blaine.xvwv2 TO otheruser;

+SET SCHEMA blaine;

+/*e*/GRANT ALL ON other.xvwv3 TO otheruser;

+/*e*/GRANT ALL ON information_schema.xvwv3 TO otheruser;

+/*u0*/REVOKE ALL ON xvwv1 FROM otheruser RESTRICT;

+SET SCHEMA public;

+/*u0*/REVOKE ALL ON blaine.xvwv2 FROM otheruser RESTRICT;

+SET SCHEMA blaine;

+/*e*/REVOKE ALL ON other.xvwv3 FROM otheruser RESTRICT;

+/*e*/REVOKE ALL ON information_schema.xvwv3 FROM otheruser RESTRICT;

+

+--                  ******************************       Indexes

+/*c2*/SELECT * from xindt1;

+SET SCHEMA public;

+/*c2*/SELECT * from blaine.xindt2;

+/*c2*/SELECT * from blaine.xindt3;

+SET SCHEMA blaine;

+/*c2*/SELECT * from xindt4;

+

+--                  ******************************  CACH Indexes

+/*c2*/SELECT * from xcindt1;

+SET SCHEMA public;

+/*c2*/SELECT * from blaine.xcindt2;

+/*c2*/SELECT * from blaine.xcindt3;

+SET SCHEMA blaine;

+/*c2*/SELECT * from xcindt4;

+

+--                  ******************************       Sequences

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+/*r0*/SELECT next value FOR xs1 FROM xseqt1;

+SET SCHEMA public;

+-- Sequence dflt schema should come from Session (set schema), not table.

+/*e*/SELECT next value FOR xs2 FROM blaine.xseqt1;

+/*e*/SELECT next value FOR blaine.xs1 FROM xseqt1;

+/*r2*/SELECT next value FOR blaine.xs2 FROM blaine.xseqt1;

+SET SCHEMA blaine;

+-- Just to reset orig. value before persisting (can't roll back seq.s).

+ALTER SEQUENCE xs1 RESTART WITH 0;

+ALTER SEQUENCE xs2 RESTART WITH 2;

+/*e*/DROP SEQUENCE xs101;

+/*e*/DROP SEQUENCE blaine.xs101;

+/*e*/DROP SEQUENCE information_schema.xs1;

+/*e*/DROP SEQUENCE other.xs1;

+

+--                  ******************************       Triggers

+/*e*/CREATE TRIGGER xtrgtrig1

+    AFTER INSERT ON xtrgt1 CALL 'org.hsqldb.test.BlaineTrig'; -- Create existing

+/*e*/CREATE TRIGGER blaine.xtrgtrig2

+    AFTER INSERT ON xtrgt2 CALL 'org.hsqldb.test.BlaineTrig'; -- Create existing

+SET SCHEMA public;

+/*e*/CREATE TRIGGER blaine.xtrgtrig2

+    AFTER INSERT ON blaine.xtrgt2 CALL 'org.hsqldb.test.BlaineTrig'; -- Create existing

+SET SCHEMA blaine;

+

+--                  ******************************       Constraints

+-- N.b.: Do not commit DML changes so that this whole block may be repeated.

+COMMIT;

+SET AUTOCOMMIT false;

+/*u1*/INSERT INTO xcont1 VALUES (0);

+SET SCHEMA public;

+/*u1*/INSERT INTO blaine.xcont2 VALUES (0);

+SET SCHEMA blaine;

+/*u1*/INSERT INTO xcont3 VALUES (0);

+/*u1*/INSERT INTO xcont4 VALUES (0);

+/*u1*/INSERT INTO xcont5 VALUES (0);

+/*u1*/INSERT INTO xcont6 VALUES (0);

+/*u1*/INSERT INTO xcont7 VALUES (0);

+/*u1*/INSERT INTO xcont8 VALUES (0);

+-- Note that error message implies that problem is due to table xconj1, not data:

+/*u1*/INSERT INTO xcont9 VALUES (1);

+/*u1*/INSERT INTO xcont10 VALUES (1);

+/*u1*/INSERT INTO xcont11 VALUES (1);

+/*u1*/INSERT INTO xcont12 VALUES (1);

+/*e*/INSERT INTO xcont13 VALUES (1);

+/*u1*/INSERT INTO xcont14 VALUES (1);

+/*u1*/INSERT INTO xcont15 VALUES (1);

+/*u1*/INSERT INTO xcont16 VALUES (1);

+/*u1*/INSERT INTO xcont17 VALUES (0);

+/*u1*/INSERT INTO xcont18 VALUES (0);

+/*u1*/INSERT INTO xcont19 VALUES (0);

+/*u1*/INSERT INTO xcont20 VALUES (0);

+/*e*/INSERT INTO xcont1 VALUES (0);

+/*e*/INSERT INTO xcont2 VALUES (0);

+/*e*/INSERT INTO xcont3 VALUES (0);

+/*e*/INSERT INTO xcont4 VALUES (0);

+/*e*/INSERT INTO xcont5 VALUES (0);

+/*e*/INSERT INTO xcont6 VALUES (0);

+/*e*/INSERT INTO xcont7 VALUES (0);

+/*e*/INSERT INTO xcont8 VALUES (0);

+/*e*/INSERT INTO xcont9 VALUES (0);

+/*e*/INSERT INTO xcont10 VALUES (0);

+/*e*/INSERT INTO xcont11 VALUES (0);

+/*e*/INSERT INTO xcont12 VALUES (0);

+/*e*/INSERT INTO xcont13 VALUES (0);

+/*e*/INSERT INTO xcont14 VALUES (0);

+/*e*/INSERT INTO xcont15 VALUES (0);

+/*e*/INSERT INTO xcont16 VALUES (0);

+/*e*/INSERT INTO xcont17 VALUES (1);

+/*e*/INSERT INTO xcont18 VALUES (1);

+/*e*/INSERT INTO xcont19 VALUES (1);

+/*e*/INSERT INTO xcont20 VALUES (1);

+/*c1*/SELECT * FROM xcont1;

+/*c1*/SELECT * FROM xcont2;

+/*c1*/SELECT * FROM xcont3;

+/*c1*/SELECT * FROM xcont4;

+/*c1*/SELECT * FROM xcont5;

+/*c1*/SELECT * FROM xcont6;

+/*c1*/SELECT * FROM xcont7;

+/*c1*/SELECT * FROM xcont8;

+/*c1*/SELECT * FROM xcont9;

+/*c1*/SELECT * FROM xcont10;

+/*c1*/SELECT * FROM xcont11;

+/*c1*/SELECT * FROM xcont12;

+/*c0*/SELECT * FROM xcont13;

+/*c1*/SELECT * FROM xcont14;

+/*c1*/SELECT * FROM xcont15;

+/*c1*/SELECT * FROM xcont16;

+/*c1*/SELECT * FROM xcont17;

+/*c1*/SELECT * FROM xcont18;

+/*c1*/SELECT * FROM xcont19;

+/*c1*/SELECT * FROM xcont20;

+ROLLBACK;

+

+--                  ******************************       ALTERs

+-- Add tests when time permits.

+

+DROP USER otheruser;

+

+

+-- This to test .script persistence.

+SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfSchemaPersistC1.txt b/testrun/hsqldb/TestSelfSchemaPersistC1.txt
new file mode 100644
index 0000000..6bc946a
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaPersistC1.txt
@@ -0,0 +1,612 @@
+-- This script series tests ALT commands on schema objects, including

+-- persistence.  ALTER USER involves no schemas.

+-- Commands tested:  ALTER INDEX, ALTER SEQUENCE, ALTER TABLE

+

+-- The blaine schema will exist if a previous script created it already.

+/*s*/DROP SCHEMA blaine CASCADE;

+/*u0*/CREATE SCHEMA blaine authorization dba;

+

+--                                                         PREP

+-- Create a zillion simple objects to play with

+/*u0*/SET SCHEMA public;

+DROP TABLE public.mt00 IF EXISTS;

+DROP TABLE public.mt01 IF EXISTS;

+DROP TABLE public.mt02 IF EXISTS;

+DROP TABLE public.mt03 IF EXISTS;

+DROP TABLE mt04 IF EXISTS;

+DROP TABLE mt05 IF EXISTS;

+DROP TABLE mt06 IF EXISTS;

+DROP TABLE mt07 IF EXISTS;

+DROP TABLE public.mt08 IF EXISTS;

+DROP TABLE public.mt09 IF EXISTS;

+DROP TABLE public.mt10 IF EXISTS;

+DROP TABLE public.mt11 IF EXISTS;

+DROP TABLE public.mt12 IF EXISTS;

+DROP TABLE public.mt13 IF EXISTS;

+DROP TABLE mt14 IF EXISTS;

+DROP TABLE mt15 IF EXISTS;

+DROP TABLE mt16 IF EXISTS;

+DROP TABLE mt17 IF EXISTS;

+DROP TABLE public.mt18 IF EXISTS;

+DROP TABLE public.mt19 IF EXISTS;

+DROP TABLE public.mt20 IF EXISTS;

+DROP TABLE public.mt21 IF EXISTS;

+DROP TABLE public.mt22 IF EXISTS;

+DROP TABLE public.mt23 IF EXISTS;

+DROP TABLE public.mt24 IF EXISTS;

+DROP TABLE public.mt25 IF EXISTS;

+DROP TABLE public.mt26 IF EXISTS;

+DROP TABLE public.mt27 IF EXISTS;

+DROP TABLE public.mt28 IF EXISTS;

+DROP TABLE public.mt29 IF EXISTS;

+DROP TABLE ct00 IF EXISTS;

+DROP TABLE ct01 IF EXISTS;

+DROP TABLE ct02 IF EXISTS;

+DROP TABLE ct03 IF EXISTS;

+DROP TABLE ct04 IF EXISTS;

+DROP TABLE ct05 IF EXISTS;

+DROP TABLE ct06 IF EXISTS;

+DROP TABLE ct07 IF EXISTS;

+DROP TABLE ct08 IF EXISTS;

+DROP TABLE ct09 IF EXISTS;

+DROP TABLE ct10 IF EXISTS;

+DROP TABLE ct11 IF EXISTS;

+DROP TABLE ct12 IF EXISTS;

+DROP TABLE ct13 IF EXISTS;

+DROP TABLE ct14 IF EXISTS;

+DROP TABLE ct15 IF EXISTS;

+DROP TABLE ct16 IF EXISTS;

+DROP TABLE ct17 IF EXISTS;

+DROP TABLE ct18 IF EXISTS;

+DROP TABLE ct19 IF EXISTS;

+DROP TABLE t101 IF EXISTS;

+CREATE TABLE mt00 (i int);

+CREATE TABLE mt01 (i int);

+CREATE TABLE mt02 (i int);

+/*u0*/SET SCHEMA blaine;

+CREATE TABLE public.mt03 (i int);

+CREATE TABLE public.mt04 (i int);

+CREATE TABLE public.mt05 (i int);

+CREATE TABLE public.mt06 (i int);

+CREATE TABLE public.mt07 (i int);

+/*u0*/SET SCHEMA public;

+CREATE TABLE mt08 (i int);

+CREATE TABLE mt09 (i int);

+CREATE TABLE mt10 (i int);

+CREATE TABLE mt11 (i int);

+CREATE TABLE mt12 (i int);

+/*u0*/SET SCHEMA blaine;

+CREATE TABLE public.mt13 (i int);

+CREATE TABLE public.mt14 (i int);

+CREATE TABLE public.mt15 (i int);

+CREATE TABLE public.mt16 (i int);

+CREATE TABLE public.mt17 (i int);

+/*u0*/SET SCHEMA public;

+CREATE TABLE mt18 (i int);

+CREATE TABLE mt19 (i int);

+CREATE TABLE mt20 (i int);

+CREATE TABLE mt21 (i int);

+CREATE TABLE mt22 (i int);

+CREATE TABLE mt23 (i int);

+CREATE TABLE mt24 (i int);

+CREATE TABLE mt25 (i int);

+CREATE TABLE mt26 (i int);

+CREATE TABLE mt27 (i int);

+CREATE TABLE mt28 (i int);

+CREATE TABLE mt29 (i int);

+CREATE CACHED TABLE ct00 (i int);

+CREATE CACHED TABLE ct01 (i int);

+CREATE CACHED TABLE ct02 (i int);

+/*u0*/SET SCHEMA blaine;

+CREATE CACHED TABLE public.ct03 (i int);

+CREATE CACHED TABLE public.ct04 (i int);

+CREATE CACHED TABLE public.ct05 (i int);

+CREATE CACHED TABLE public.ct06 (i int);

+CREATE CACHED TABLE public.ct07 (i int);

+/*u0*/SET SCHEMA public;

+CREATE CACHED TABLE ct08 (i int);

+CREATE CACHED TABLE ct09 (i int);

+CREATE CACHED TABLE ct10 (i int);

+CREATE CACHED TABLE ct11 (i int);

+CREATE CACHED TABLE ct12 (i int);

+/*u0*/SET SCHEMA blaine;

+CREATE CACHED TABLE public.ct13 (i int);

+CREATE CACHED TABLE public.ct14 (i int);

+CREATE CACHED TABLE public.ct15 (i int);

+CREATE CACHED TABLE public.ct16 (i int);

+CREATE CACHED TABLE public.ct17 (i int);

+/*u0*/SET SCHEMA public;

+CREATE CACHED TABLE ct18 (i int);

+CREATE CACHED TABLE ct19 (i int);

+DROP INDEX mi00 IF EXISTS;

+DROP INDEX mi01 IF EXISTS;

+DROP INDEX mi02 IF EXISTS;

+DROP INDEX mi03 IF EXISTS;

+DROP INDEX mi04 IF EXISTS;

+DROP INDEX mui05 IF EXISTS;

+DROP INDEX mui06 IF EXISTS;

+DROP INDEX mui07 IF EXISTS;

+DROP INDEX mui08 IF EXISTS;

+DROP INDEX mui09 IF EXISTS;

+DROP INDEX ci00 IF EXISTS;

+DROP INDEX ci01 IF EXISTS;

+DROP INDEX ci02 IF EXISTS;

+DROP INDEX ci03 IF EXISTS;

+DROP INDEX ci04 IF EXISTS;

+DROP INDEX cui05 IF EXISTS;

+DROP INDEX cui06 IF EXISTS;

+DROP INDEX cui07 IF EXISTS;

+DROP INDEX cui08 IF EXISTS;

+DROP INDEX cui09 IF EXISTS;

+DROP INDEX i101 IF EXISTS;

+CREATE INDEX mi00 ON mt00 (i);

+CREATE INDEX mi01 ON mt01 (i);

+CREATE INDEX mi02 ON mt02 (i);

+CREATE INDEX mi03 ON mt03 (i);

+CREATE INDEX mi04 ON mt04 (i);

+/*u0*/SET SCHEMA blaine;

+CREATE INDEX public.mui05 ON public.mt05 (i);

+CREATE INDEX public.mui06 ON public.mt06 (i);

+CREATE INDEX public.mui07 ON public.mt07 (i);

+CREATE INDEX public.mui08 ON public.mt08 (i);

+CREATE INDEX public.mui09 ON public.mt09 (i);

+CREATE INDEX public.ci00 ON public.ct00 (i);

+CREATE INDEX public.ci01 ON public.ct01 (i);

+CREATE INDEX public.ci02 ON public.ct02 (i);

+CREATE INDEX public.ci03 ON public.ct03 (i);

+CREATE INDEX public.ci04 ON public.ct04 (i);

+CREATE INDEX public.cui05 ON public.ct05 (i);

+/*u0*/SET SCHEMA public;

+CREATE INDEX cui06 ON ct06 (i);

+CREATE INDEX cui07 ON ct07 (i);

+CREATE INDEX cui08 ON ct08 (i);

+CREATE INDEX cui09 ON ct09 (i);

+CREATE SEQUENCE s00;

+CREATE SEQUENCE s01;

+CREATE SEQUENCE s02;

+/*u0*/SET SCHEMA blaine;

+CREATE SEQUENCE public.s03;

+CREATE SEQUENCE public.s04;

+CREATE SEQUENCE public.s05;

+CREATE SEQUENCE public.s06;

+CREATE SEQUENCE public.s07;

+/*u0*/SET SCHEMA public;

+CREATE SEQUENCE s08;

+CREATE SEQUENCE s09;

+CREATE SEQUENCE s10;

+CREATE SEQUENCE s11;

+/*u0*/SET SCHEMA blaine;

+CREATE SEQUENCE public.s12;

+CREATE SEQUENCE public.s13;

+CREATE SEQUENCE public.s14;

+CREATE SEQUENCE public.s15;

+CREATE SEQUENCE public.s16;

+/*u0*/SET SCHEMA public;

+CREATE SEQUENCE s17;

+CREATE SEQUENCE s18;

+CREATE SEQUENCE s19;

+-- blaine schema

+/*u0*/ SET SCHEMA blaine;

+DROP TABLE bmt00 IF EXISTS;

+DROP TABLE bmt01 IF EXISTS;

+DROP TABLE bmt02 IF EXISTS;

+DROP TABLE bmt03 IF EXISTS;

+DROP TABLE bmt04 IF EXISTS;

+DROP TABLE bmt05 IF EXISTS;

+DROP TABLE bmt06 IF EXISTS;

+DROP TABLE bmt07 IF EXISTS;

+DROP TABLE bmt08 IF EXISTS;

+DROP TABLE bmt09 IF EXISTS;

+DROP TABLE bmt10 IF EXISTS;

+DROP TABLE bmt11 IF EXISTS;

+DROP TABLE bmt12 IF EXISTS;

+DROP TABLE bmt13 IF EXISTS;

+DROP TABLE bmt14 IF EXISTS;

+DROP TABLE bmt15 IF EXISTS;

+DROP TABLE bmt16 IF EXISTS;

+DROP TABLE bmt17 IF EXISTS;

+DROP TABLE bmt18 IF EXISTS;

+DROP TABLE bmt19 IF EXISTS;

+DROP TABLE bmt20 IF EXISTS;

+DROP TABLE bmt21 IF EXISTS;

+DROP TABLE bmt22 IF EXISTS;

+DROP TABLE bmt23 IF EXISTS;

+DROP TABLE bmt24 IF EXISTS;

+DROP TABLE bmt25 IF EXISTS;

+DROP TABLE bmt26 IF EXISTS;

+DROP TABLE bmt27 IF EXISTS;

+DROP TABLE bmt28 IF EXISTS;

+DROP TABLE bmt29 IF EXISTS;

+DROP TABLE bct00 IF EXISTS;

+DROP TABLE bct01 IF EXISTS;

+DROP TABLE bct02 IF EXISTS;

+DROP TABLE bct03 IF EXISTS;

+DROP TABLE bct04 IF EXISTS;

+DROP TABLE bct05 IF EXISTS;

+DROP TABLE bct06 IF EXISTS;

+DROP TABLE bct07 IF EXISTS;

+DROP TABLE bct08 IF EXISTS;

+DROP TABLE bct09 IF EXISTS;

+DROP TABLE bct10 IF EXISTS;

+DROP TABLE bct11 IF EXISTS;

+DROP TABLE bct12 IF EXISTS;

+DROP TABLE bct13 IF EXISTS;

+DROP TABLE bct14 IF EXISTS;

+DROP TABLE bct15 IF EXISTS;

+DROP TABLE bct16 IF EXISTS;

+DROP TABLE bct17 IF EXISTS;

+DROP TABLE bct18 IF EXISTS;

+DROP TABLE bct19 IF EXISTS;

+DROP TABLE bt101 IF EXISTS;

+CREATE TABLE bmt00 (i int);

+CREATE TABLE bmt01 (i int);

+CREATE TABLE bmt02 (i int);

+/*u0*/SET SCHEMA public;

+CREATE TABLE blaine.bmt03 (i int);

+CREATE TABLE blaine.bmt04 (i int);

+CREATE TABLE blaine.bmt05 (i int);

+CREATE TABLE blaine.bmt06 (i int);

+CREATE TABLE blaine.bmt07 (i int);

+/*u0*/SET SCHEMA blaine;

+CREATE TABLE bmt08 (i int);

+CREATE TABLE bmt09 (i int);

+CREATE TABLE bmt10 (i int);

+CREATE TABLE bmt11 (i int);

+CREATE TABLE bmt12 (i int);

+/*u0*/SET SCHEMA public;

+CREATE TABLE blaine.bmt13 (i int);

+CREATE TABLE blaine.bmt14 (i int);

+CREATE TABLE blaine.bmt15 (i int);

+CREATE TABLE blaine.bmt16 (i int);

+CREATE TABLE blaine.bmt17 (i int);

+/*u0*/SET SCHEMA blaine;

+CREATE TABLE bmt18 (i int);

+CREATE TABLE bmt19 (i int);

+CREATE TABLE bmt20 (i int);

+CREATE TABLE bmt21 (i int);

+CREATE TABLE bmt22 (i int);

+CREATE TABLE bmt23 (i int);

+CREATE TABLE bmt24 (i int);

+CREATE TABLE bmt25 (i int);

+CREATE TABLE bmt26 (i int);

+CREATE TABLE bmt27 (i int);

+CREATE TABLE bmt28 (i int);

+CREATE TABLE bmt29 (i int);

+CREATE CACHED TABLE bct00 (i int);

+CREATE CACHED TABLE bct01 (i int);

+CREATE CACHED TABLE bct02 (i int);

+/*u0*/SET SCHEMA public;

+CREATE CACHED TABLE blaine.bct03 (i int);

+CREATE CACHED TABLE blaine.bct04 (i int);

+CREATE CACHED TABLE blaine.bct05 (i int);

+CREATE CACHED TABLE blaine.bct06 (i int);

+CREATE CACHED TABLE blaine.bct07 (i int);

+/*u0*/SET SCHEMA blaine;

+CREATE CACHED TABLE bct08 (i int);

+CREATE CACHED TABLE bct09 (i int);

+CREATE CACHED TABLE bct10 (i int);

+CREATE CACHED TABLE bct11 (i int);

+CREATE CACHED TABLE bct12 (i int);

+/*u0*/SET SCHEMA public;

+CREATE CACHED TABLE blaine.bct13 (i int);

+CREATE CACHED TABLE blaine.bct14 (i int);

+CREATE CACHED TABLE blaine.bct15 (i int);

+CREATE CACHED TABLE blaine.bct16 (i int);

+CREATE CACHED TABLE blaine.bct17 (i int);

+/*u0*/SET SCHEMA blaine;

+CREATE CACHED TABLE bct18 (i int);

+CREATE CACHED TABLE bct19 (i int);

+DROP INDEX bmi00 IF EXISTS;

+DROP INDEX bmi01 IF EXISTS;

+DROP INDEX bmi02 IF EXISTS;

+DROP INDEX bmi03 IF EXISTS;

+DROP INDEX bmi04 IF EXISTS;

+DROP INDEX bmui05 IF EXISTS;

+DROP INDEX bmui06 IF EXISTS;

+DROP INDEX bmui07 IF EXISTS;

+DROP INDEX bmui08 IF EXISTS;

+DROP INDEX bmui09 IF EXISTS;

+DROP INDEX bci00 IF EXISTS;

+DROP INDEX bci01 IF EXISTS;

+DROP INDEX bci02 IF EXISTS;

+DROP INDEX bci03 IF EXISTS;

+DROP INDEX bci04 IF EXISTS;

+DROP INDEX bcui05 IF EXISTS;

+DROP INDEX bcui06 IF EXISTS;

+DROP INDEX bcui07 IF EXISTS;

+DROP INDEX bcui08 IF EXISTS;

+DROP INDEX bcui09 IF EXISTS;

+DROP INDEX bi101 IF EXISTS;

+CREATE INDEX bmi00 ON bmt00 (i);

+CREATE INDEX bmi01 ON bmt01 (i);

+CREATE INDEX bmi02 ON bmt02 (i);

+CREATE INDEX bmi03 ON bmt03 (i);

+CREATE INDEX bmi04 ON bmt04 (i);

+/*u0*/SET SCHEMA public;

+CREATE INDEX blaine.bmui05 ON blaine.bmt05 (i);

+CREATE INDEX blaine.bmui06 ON blaine.bmt06 (i);

+CREATE INDEX blaine.bmui07 ON blaine.bmt07 (i);

+CREATE INDEX blaine.bmui08 ON blaine.bmt08 (i);

+CREATE INDEX blaine.bmui09 ON blaine.bmt09 (i);

+/*u0*/SET SCHEMA blaine;

+CREATE INDEX bci00 ON bct00 (i);

+CREATE INDEX bci01 ON bct01 (i);

+CREATE INDEX bci02 ON bct02 (i);

+CREATE INDEX bci03 ON bct03 (i);

+CREATE INDEX bci04 ON bct04 (i);

+/*u0*/SET SCHEMA public;

+CREATE INDEX blaine.bcui05 ON blaine.bct05 (i);

+CREATE INDEX blaine.bcui06 ON blaine.bct06 (i);

+CREATE INDEX blaine.bcui07 ON blaine.bct07 (i);

+CREATE INDEX blaine.bcui08 ON blaine.bct08 (i);

+CREATE INDEX blaine.bcui09 ON blaine.bct09 (i);

+CREATE SEQUENCE blaine.bs00;

+CREATE SEQUENCE blaine.bs01;

+CREATE SEQUENCE blaine.bs02;

+CREATE SEQUENCE blaine.bs03;

+/*u0*/SET SCHEMA blaine;

+CREATE SEQUENCE bs04;

+CREATE SEQUENCE bs05;

+CREATE SEQUENCE bs06;

+CREATE SEQUENCE bs07;

+CREATE SEQUENCE bs08;

+/*u0*/SET SCHEMA public;

+CREATE SEQUENCE blaine.bs09;

+CREATE SEQUENCE blaine.bs10;

+CREATE SEQUENCE blaine.bs11;

+CREATE SEQUENCE blaine.bs12;

+/*u0*/SET SCHEMA blaine;

+CREATE SEQUENCE bs13;

+CREATE SEQUENCE bs14;

+CREATE SEQUENCE bs15;

+CREATE SEQUENCE bs16;

+CREATE SEQUENCE bs17;

+/*u0*/SET SCHEMA public;

+CREATE SEQUENCE blaine.bs18;

+CREATE SEQUENCE blaine.bs19;

+

+-- These are the only tests for SEQUENCEs in this script. SEQUENCES

+-- The only ALTER command for sequences is here.

+INSERT INTO public.mt01 VALUES(0);

+INSERT INTO blaine.bmt01 VALUES(0);

+/*u0*/SET SCHEMA blaine;

+/*r0*/SELECT next value FOR public.s00 FROM public.mt01;

+/*r1*/SELECT next value FOR public.s00 FROM public.mt01;

+/*r0*/SELECT next value FOR public.s04 FROM blaine.bmt01;

+/*r1*/SELECT next value FOR public.s04 FROM blaine.bmt01;

+/*u0*/SET SCHEMA public;

+/*r0*/SELECT next value FOR public.s01 FROM mt01;

+/*r1*/SELECT next value FOR public.s01 FROM mt01;

+/*r0*/SELECT next value FOR s02 FROM public.mt01;

+/*r1*/SELECT next value FOR s02 FROM public.mt01;

+/*r0*/SELECT next value FOR s03 FROM mt01;

+/*r1*/SELECT next value FOR s03 FROM mt01;

+/*r0*/SELECT next value FOR blaine.bs00 FROM blaine.bmt01;

+-- Sequence inherits default schema from Session, not table.

+/*e*/SELECT next value FOR bs00 FROM blaine.bmt01;

+/*r0*/SELECT next value FOR blaine.bs04 FROM public.mt01;

+/*r1*/SELECT next value FOR blaine.bs04 FROM public.mt01;

+/*u0*/SET SCHEMA blaine;

+/*r0*/SELECT next value FOR blaine.bs01 FROM bmt01;

+/*r1*/SELECT next value FOR blaine.bs01 FROM bmt01;

+/*r0*/SELECT next value FOR bs02 FROM blaine.bmt01;

+/*r1*/SELECT next value FOR bs02 FROM blaine.bmt01;

+/*r0*/SELECT next value FOR bs03 FROM bmt01;

+/*r1*/SELECT next value FOR bs03 FROM bmt01;

+/*u0*/ALTER SEQUENCE public.s00 RESTART WITH 21;

+/*u0*/ALTER SEQUENCE bs00 RESTART WITH 22;

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER SEQUENCE blaine.bs01 RESTART WITH 23;

+/*u0*/ALTER SEQUENCE s01 RESTART WITH 24;

+/*r21*/SELECT next value FOR public.s00 FROM public.mt01;

+/*r22*/SELECT next value FOR blaine.bs00 FROM public.mt01;

+/*r23*/SELECT next value FOR blaine.bs01 FROM public.mt01;

+/*r24*/SELECT next value FOR s01 FROM public.mt01;

+

+-- May only rename: Indexes, Tables, Columns              RENAMES

+-- (Will only test Column renames if I have time)

+-- Can't change schemas for existing objects.

+-- 1st all permutations of PUBLICs -> blaines

+/*e*/SELECT * FROM blaine.rbmt00;

+/*e*/SELECT * FROM blaine.rbct00;

+/*e*/SELECT * FROM public.rmt00;

+/*e*/SELECT * FROM public.cmt00;

+/*u0*/SET SCHEMA public;

+/*e*/ALTER INDEX mi00 RENAME TO blaine.bi101;

+/*e*/ALTER INDEX mui05 RENAME TO blaine.bi101;

+/*e*/ALTER TABLE mt10 RENAME TO blaine.bt101;

+/*e*/ALTER TABLE ct10 RENAME TO blaine.bt101;

+/*e*/ALTER INDEX public.mi00 RENAME TO blaine.bi101;

+/*e*/ALTER INDEX public.mui05 RENAME TO blaine.bi101;

+/*e*/ALTER TABLE public.mt10 RENAME TO blaine.bt101;

+/*e*/ALTER TABLE public.ct10 RENAME TO blaine.bt101;

+/*e*/ALTER INDEX blaine.mi00 RENAME TO public.bi101;

+/*e*/ALTER INDEX blaine.mui05 RENAME TO public.bi101;

+/*u0*/SET SCHEMA blaine;

+/*e*/ALTER TABLE mt10 RENAME TO public.bt101;

+/*e*/ALTER TABLE ct10 RENAME TO public.bt101;

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER TABLE blaine.bmt00 RENAME TO rbmt00;

+/*u0*/ALTER TABLE blaine.bct00 RENAME TO blaine.rbct00;

+/*u0*/ALTER INDEX blaine.bmi00 RENAME TO rbmi00;

+/*u0*/SET SCHEMA blaine;

+/*u0*/ALTER INDEX bci00 RENAME TO rbci00;

+/*u0*/ALTER INDEX public.mi00 RENAME TO public.rmi00;

+/*u0*/ALTER INDEX public.ci00 RENAME TO rci00;

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER TABLE public.mt00 RENAME TO public.rmt00;

+/*u0*/ALTER TABLE ct00 RENAME TO rct00;

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER INDEX blaine.bmui05 RENAME TO rbmui05;

+/*u0*/SET SCHEMA blaine;

+/*u0*/ALTER INDEX bcui05 RENAME TO rbcui05;

+/*u0*/ALTER INDEX public.mui05 RENAME TO public.rmui05;

+/*u0*/ALTER INDEX public.cui05 RENAME TO rcui05;

+/*u0*/SET SCHEMA public;

+/*e*/ALTER INDEX public.mui05 RENAME TO blaine.bi101;

+/*e*/ALTER TABLE public.mt10 RENAME TO blaine.bt101;

+/*e*/ALTER TABLE public.ct10 RENAME TO blaine.bt101;

+/*e*/ALTER INDEX public.mi00 RENAME TO blaine.bi101;

+/*e*/ALTER INDEX public.mui05 RENAME TO blaine.bi101;

+/*e*/ALTER TABLE public.mt10 RENAME TO blaine.bt101;

+/*e*/ALTER TABLE public.ct10 RENAME TO blaine.bt101;

+/*c0*/SELECT * FROM blaine.rbmt00;

+/*c0*/SELECT * FROM blaine.rbct00;

+/*c0*/SELECT * FROM public.rmt00;

+/*c0*/SELECT * FROM public.rct00;

+

+-- The only schema-specific ALTERs left are      ALTER TABLE ADD/DROP CONS

+-- ADD NAMED Check/Unique CONSTRAINTS

+-- First, CHECK constraints on MEM tables

+/*e*/ALTER TABLE public.mt11 ADD CONSTRAINT blaine.mt11ck1 CHECK (i > 0);

+/*e*/ALTER TABLE blaine.bmt11 ADD CONSTRAINT public.bmt11ck1 CHECK (i > 0);

+/*e*/ALTER TABLE mt11 ADD CONSTRAINT blaine.mt11ck1 CHECK (i > 0);

+/*u0*/ALTER TABLE mt11 ADD CONSTRAINT mt11ck1 CHECK (i > 0);

+/*u0*/ALTER TABLE mt12 ADD CONSTRAINT public.mt12ck1 CHECK (i = 1);

+SET SCHEMA blaine;

+/*u0*/ALTER TABLE public.mt13 ADD CONSTRAINT mt13ck1 CHECK (i in (1, 2, 3));

+/*u0*/ALTER TABLE public.mt14 ADD CONSTRAINT public.mt14ck1 CHECK (i != 0);

+/*e*/ALTER TABLE blaine.bmt11 ADD CONSTRAINT public.bmt11ck1 CHECK (i > 0);

+/*e*/ALTER TABLE public.mt11 ADD CONSTRAINT blaine.mt11ck1 CHECK (i > 0);

+/*e*/ALTER TABLE bmt11 ADD CONSTRAINT public.bmt11ck1 CHECK (i > 0);

+/*u0*/ALTER TABLE bmt11 ADD CONSTRAINT bmt11ck1 CHECK (i > 0);

+/*u0*/ALTER TABLE bmt12 ADD CONSTRAINT blaine.bmt12ck1 CHECK (i = 1);

+SET SCHEMA public;

+/*u0*/ALTER TABLE blaine.bmt13 ADD CONSTRAINT bmt13ck1 CHECK (i in (1, 2, 3));

+/*u0*/ALTER TABLE blaine.bmt14 ADD CONSTRAINT blaine.bmt14ck1 CHECK (i != 0);

+/*e*/INSERT INTO public.mt11 values(0);

+/*e*/INSERT INTO public.mt12 values(0);

+/*e*/INSERT INTO public.mt13 values(0);

+/*e*/INSERT INTO public.mt14 values(0);

+/*e*/INSERT INTO blaine.bmt11 values(0);

+/*e*/INSERT INTO blaine.bmt12 values(0);

+/*e*/INSERT INTO blaine.bmt13 values(0);

+/*e*/INSERT INTO blaine.bmt14 values(0);

+/*u1*/INSERT INTO public.mt11 values(1);

+/*u1*/INSERT INTO public.mt12 values(1);

+/*u1*/INSERT INTO public.mt13 values(1);

+/*u1*/INSERT INTO public.mt14 values(1);

+/*u1*/INSERT INTO blaine.bmt11 values(1);

+/*u1*/INSERT INTO blaine.bmt12 values(1);

+/*u1*/INSERT INTO blaine.bmt13 values(1);

+/*u1*/INSERT INTO blaine.bmt14 values(1);

+-- Now, UNIQUE constraints on CACHED tables

+/*e*/ALTER TABLE public.ct11 ADD CONSTRAINT blaine.ct11ck1 UNIQUE (i);

+/*e*/ALTER TABLE blaine.bct11 ADD CONSTRAINT public.bct11ck1 UNIQUE (i);

+/*e*/ALTER TABLE ct11 ADD CONSTRAINT blaine.ct11ck1 UNIQUE (i);

+/*u0*/ALTER TABLE ct11 ADD CONSTRAINT ct11ck1 UNIQUE (i);

+/*u0*/ALTER TABLE ct12 ADD CONSTRAINT public.ct12ck1 UNIQUE (i);

+SET SCHEMA blaine;

+/*u0*/ALTER TABLE public.ct13 ADD CONSTRAINT ct13ck1 UNIQUE (i);

+/*u0*/ALTER TABLE public.ct14 ADD CONSTRAINT public.ct14ck1 UNIQUE (i);

+/*e*/ALTER TABLE blaine.bct11 ADD CONSTRAINT public.bct11ck1 UNIQUE (i);

+/*e*/ALTER TABLE public.ct11 ADD CONSTRAINT blaine.ct11ck1 UNIQUE (i);

+/*e*/ALTER TABLE bct11 ADD CONSTRAINT public.bct11ck1 UNIQUE (i);

+/*u0*/ALTER TABLE bct11 ADD CONSTRAINT bct11ck1 UNIQUE (i);

+/*u0*/ALTER TABLE bct12 ADD CONSTRAINT blaine.bct12ck1 UNIQUE (i);

+SET SCHEMA public;

+/*u0*/ALTER TABLE blaine.bct13 ADD CONSTRAINT bct13ck1 UNIQUE (i);

+/*u0*/ALTER TABLE blaine.bct14 ADD CONSTRAINT blaine.bct14ck1 UNIQUE (i);

+/*u1*/INSERT INTO public.ct11 values(1);

+/*u1*/INSERT INTO public.ct12 values(1);

+/*u1*/INSERT INTO public.ct13 values(1);

+/*u1*/INSERT INTO public.ct14 values(1);

+/*u1*/INSERT INTO blaine.bct11 values(1);

+/*u1*/INSERT INTO blaine.bct12 values(1);

+/*u1*/INSERT INTO blaine.bct13 values(1);

+/*u1*/INSERT INTO blaine.bct14 values(1);

+/*e*/INSERT INTO public.ct11 values(1);

+/*e*/INSERT INTO public.ct12 values(1);

+/*e*/INSERT INTO public.ct13 values(1);

+/*e*/INSERT INTO public.ct14 values(1);

+/*e*/INSERT INTO blaine.bct11 values(1);

+/*e*/INSERT INTO blaine.bct12 values(1);

+/*e*/INSERT INTO blaine.bct13 values(1);

+/*e*/INSERT INTO blaine.bct14 values(1);

+-- ADD UNNAMED FK CONSTRAINTS

+-- Index some MEM tables to reference. (table ct1[1-4],bct1[1-4] already set).

+ALTER TABLE public.mt15 ADD unique(i);

+ALTER TABLE public.mt16 ADD unique(i);

+ALTER TABLE public.mt17 ADD unique(i);

+ALTER TABLE public.mt18 ADD unique(i);

+ALTER TABLE blaine.bmt15 ADD unique(i);

+ALTER TABLE blaine.bmt16 ADD unique(i);

+ALTER TABLE blaine.bmt17 ADD unique(i);

+ALTER TABLE blaine.bmt18 ADD unique(i);

+INSERT INTO public.mt15 VALUES(10);

+INSERT INTO public.mt16 VALUES(10);

+INSERT INTO public.mt17 VALUES(10);

+INSERT INTO public.mt18 VALUES(10);

+INSERT INTO blaine.bmt15 VALUES(10);

+INSERT INTO blaine.bmt16 VALUES(10);

+INSERT INTO blaine.bmt17 VALUES(10);

+INSERT INTO blaine.bmt18 VALUES(10);

+/*u0*/ALTER TABLE ct15 ADD FOREIGN KEY (i) REFERENCES mt15 (i);

+/*u0*/ALTER TABLE ct16 ADD FOREIGN KEY (i) REFERENCES blaine.bct11 (i);

+/*e*/ALTER TABLE public.ct16 ADD FOREIGN KEY (i) REFERENCES blaine.bct11 (i);

+/*u0*/ALTER TABLE ct16 ADD FOREIGN KEY (i) REFERENCES public.mt16 (i);

+SET SCHEMA blaine;

+/*u0*/ALTER TABLE public.ct17 ADD FOREIGN KEY (i) REFERENCES public.mt17 (i);

+/*e*/ALTER TABLE public.ct17 ADD FOREIGN KEY (i) REFERENCES public.mt17 (i);

+/*u0*/ALTER TABLE public.ct18 ADD FOREIGN KEY (i) REFERENCES mt18 (i);

+-- fks can't reference tables in other schemas.

+/*u0*/ALTER TABLE bct15 ADD FOREIGN KEY (i) REFERENCES public.mt15 (i);

+SET SCHEMA public;

+/*u0*/ALTER TABLE blaine.bct17 ADD FOREIGN KEY (i) REFERENCES blaine.bmt17 (i);

+/*u0*/ALTER TABLE blaine.bct18 ADD FOREIGN KEY (i) REFERENCES bmt18 (i);

+/*u1*/INSERT INTO public.ct15 values(10);

+/*e*/INSERT INTO public.ct16 values(10);

+/*u1*/INSERT INTO public.ct17 values(10);

+/*u1*/INSERT INTO blaine.bct18 values(10);

+/*u1*/INSERT INTO blaine.bct17 values(10);

+/*e*/INSERT INTO public.ct15 values(9);

+/*e*/INSERT INTO public.ct16 values(9);

+/*e*/INSERT INTO public.ct17 values(9);

+/*e*/INSERT INTO public.bct18 values(9);

+/*e*/INSERT INTO blaine.bct17 values(9);

+-- Finally, ADD NAMED FK CONSTRAINTS

+-- (TARGETS ct1[1-4],bct1[1-4] already set).

+SET SCHEMA blaine;

+/*e*/ALTER TABLE bmt21 ADD CONSTRAINT public.bmt21fk

+    FOREIGN KEY (i) REFERENCES blaine.bct11 (i);

+/*e*/ALTER TABLE bmt20 ADD CONSTRAINT public.bmt20fk

+    FOREIGN KEY (i) REFERENCES bct12 (i);

+/*u0*/ALTER TABLE bmt21 ADD CONSTRAINT bmt21fk

+    FOREIGN KEY (i) REFERENCES blaine.bct11 (i);

+/*e*/ALTER TABLE bmt21 ADD CONSTRAINT bmt21fk

+    FOREIGN KEY (i) REFERENCES blaine.bct11 (i); -- Already exists

+/*u0*/ALTER TABLE bmt20 ADD CONSTRAINT blaine.cmt20fk

+    FOREIGN KEY (i) REFERENCES bct12 (i);

+/*e*/ALTER TABLE bmt20 ADD CONSTRAINT blaine.cmt20fk

+    FOREIGN KEY (i) REFERENCES bct12 (i); -- Already exists

+SET SCHEMA public;

+/*e*/ALTER TABLE blaine.bmt22 ADD CONSTRAINT public.bmt22fk

+    FOREIGN KEY (i) REFERENCES blaine.bct13 (i);

+/*e*/ALTER TABLE blaine.bmt23 ADD CONSTRAINT public.bmt23fk

+    FOREIGN KEY (i) REFERENCES bct14 (i);

+/*u0*/ALTER TABLE blaine.bmt22 ADD CONSTRAINT bmt2fk

+    FOREIGN KEY (i) REFERENCES blaine.bct13 (i);

+/*u0*/ALTER TABLE blaine.bmt23 ADD CONSTRAINT blaine.bmt23fk

+    FOREIGN KEY (i) REFERENCES bct14 (i);

+SET SCHEMA blaine;

+/*e*/ALTER TABLE bmt24 ADD CONSTRAINT public.bmt24fk

+    FOREIGN KEY (i) REFERENCES public.ct11 (i);

+/*u0*/ALTER TABLE bmt24 ADD CONSTRAINT blaine.bmt24fk

+    FOREIGN KEY (i) REFERENCES public.ct11 (i);

+SET SCHEMA public;

+/*e*/ALTER TABLE blaine.bmt22 ADD CONSTRAINT public.bmt22fk

+    FOREIGN KEY (i) REFERENCES blaine.bct13 (i);

+/*u0*/ALTER TABLE blaine.bmt25 ADD CONSTRAINT bmt25fk

+    FOREIGN KEY (i) REFERENCES bct14 (i);

+/*e*/INSERT INTO blaine.bmt21 VALUES (0);

+/*u1*/INSERT INTO blaine.bmt21 VALUES (1);

+/*e*/INSERT INTO blaine.bmt20 VALUES (0);

+/*u1*/INSERT INTO blaine.bmt20 VALUES (1);

+/*e*/INSERT INTO blaine.bmt22 VALUES (0);

+/*u1*/INSERT INTO blaine.bmt22 VALUES (1);

+/*e*/INSERT INTO blaine.bmt23 VALUES (0);

+/*u1*/INSERT INTO blaine.bmt23 VALUES (1);

+/*e*/INSERT INTO blaine.bmt25 VALUES (0);

+/*u1*/INSERT INTO blaine.bmt25 VALUES (1);

+

+SHUTDOWN IMMEDIATELY;

diff --git a/testrun/hsqldb/TestSelfSchemaPersistC2.txt b/testrun/hsqldb/TestSelfSchemaPersistC2.txt
new file mode 100644
index 0000000..8d7115c
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaPersistC2.txt
@@ -0,0 +1,127 @@
+-- Test ALTER commands on objects set up by other script

+

+--                                                          SEQUENCES

+/*r22*/SELECT next value FOR public.s00 FROM public.mt01;

+/*r23*/SELECT next value FOR blaine.bs00 FROM public.mt01;

+/*r24*/SELECT next value FOR blaine.bs01 FROM public.mt01;

+/*r25*/SELECT next value FOR public.s01 FROM public.mt01;

+-- Resetting all sequence vals so next script can retest them.

+/*u0*/ALTER SEQUENCE public.s00 RESTART WITH 22;

+/*u0*/ALTER SEQUENCE blaine.bs00 RESTART WITH 23;

+/*u0*/ALTER SEQUENCE blaine.bs01 RESTART WITH 24;

+/*u0*/ALTER SEQUENCE public.s01 RESTART WITH 25;

+

+

+--                                                          RENAMES

+/*c0*/SELECT * FROM blaine.rbmt00;

+/*c0*/SELECT * FROM blaine.rbct00;

+/*c0*/SELECT * FROM public.rmt00;

+/*c0*/SELECT * FROM public.rct00;

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER TABLE blaine.rbmt00 RENAME TO bmt00;

+/*u0*/ALTER TABLE blaine.bmt00 RENAME TO blaine.rbmt00

+/*u0*/ALTER TABLE blaine.rbct00 RENAME TO blaine.bct00

+/*u0*/ALTER TABLE rct00 RENAME TO ct00;

+/*u0*/ALTER TABLE ct00 RENAME TO public.rct00;

+/*u0*/SET SCHEMA blaine;

+/*u0*/ALTER TABLE bct00 RENAME TO rbct00

+/*u0*/ALTER TABLE public.rmt00 RENAME TO public.mt00;

+/*u0*/ALTER TABLE public.mt00 RENAME TO rmt00;

+/*c0*/SELECT * FROM blaine.rbmt00;

+/*c0*/SELECT * FROM blaine.rbct00;

+/*c0*/SELECT * FROM public.rmt00;

+/*c0*/SELECT * FROM public.rct00;

+

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER INDEX blaine.rbmi00 RENAME TO bmi00;

+/*u0*/SET SCHEMA blaine;

+/*u0*/ALTER INDEX rbci00 RENAME TO bci00;

+/*u0*/ALTER INDEX public.rmi00 RENAME TO public.mi00;

+/*u0*/ALTER INDEX public.rci00 RENAME TO ci00;

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER INDEX blaine.bmi00 RENAME TO rbmi00;

+/*u0*/SET SCHEMA blaine;

+/*u0*/ALTER INDEX bci00 RENAME TO rbci00;

+/*u0*/ALTER INDEX public.mi00 RENAME TO public.rmi00;

+/*u0*/ALTER INDEX public.ci00 RENAME TO rci00;

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER INDEX blaine.rbmui05 RENAME TO bmui05;

+/*u0*/SET SCHEMA blaine;

+/*u0*/ALTER INDEX rbcui05 RENAME TO bcui05;

+/*u0*/ALTER INDEX public.rmui05 RENAME TO public.mui05;

+/*u0*/ALTER INDEX public.rcui05 RENAME TO cui05;

+/*u0*/SET SCHEMA public;

+/*u0*/ALTER INDEX blaine.bmui05 RENAME TO rbmui05;

+/*u0*/SET SCHEMA blaine;

+/*u0*/ALTER INDEX bcui05 RENAME TO rbcui05;

+/*u0*/ALTER INDEX public.mui05 RENAME TO public.rmui05;

+/*u0*/ALTER INDEX public.cui05 RENAME TO rcui05;

+

+

+--                                          ALTER TABLE ADD/DROP CONS

+-- We'll roll all this work back so we can repeat it.

+-- Check constraints but no unique constraints, so cam commit duplicate vals.

+/*e*/INSERT INTO public.mt11 values(0);

+/*e*/INSERT INTO public.mt12 values(0);

+/*e*/INSERT INTO public.mt13 values(0);

+/*e*/INSERT INTO public.mt14 values(0);

+/*e*/INSERT INTO blaine.bmt11 values(0);

+/*e*/INSERT INTO blaine.bmt12 values(0);

+/*e*/INSERT INTO blaine.bmt13 values(0);

+/*e*/INSERT INTO blaine.bmt14 values(0);

+/*u1*/INSERT INTO public.mt11 values(1);

+/*u1*/INSERT INTO public.mt12 values(1);

+/*u1*/INSERT INTO public.mt13 values(1);

+/*u1*/INSERT INTO public.mt14 values(1);

+/*u1*/INSERT INTO blaine.bmt11 values(1);

+/*u1*/INSERT INTO blaine.bmt12 values(1);

+/*u1*/INSERT INTO blaine.bmt13 values(1);

+/*u1*/INSERT INTO blaine.bmt14 values(1);

+

+COMMIT;

+SET AUTOCOMMIT FALSE;

+-- Test vs. some values entered in previous sessoin, and some that we'll add.

+/*e*/INSERT INTO public.ct11 values(1);

+/*e*/INSERT INTO public.ct12 values(1);

+/*e*/INSERT INTO public.ct13 values(1);

+/*e*/INSERT INTO public.ct14 values(1);

+/*u1*/INSERT INTO public.ct11 values(2);

+/*u1*/INSERT INTO public.ct12 values(2);

+/*u1*/INSERT INTO public.ct13 values(2);

+/*u1*/INSERT INTO public.ct14 values(2);

+/*u1*/INSERT INTO blaine.bct11 values(2);

+/*u1*/INSERT INTO blaine.bct12 values(2);

+/*u1*/INSERT INTO blaine.bct13 values(2);

+/*u1*/INSERT INTO blaine.bct14 values(2);

+/*e*/INSERT INTO blaine.bct11 values(2);

+/*e*/INSERT INTO blaine.bct12 values(2);

+/*e*/INSERT INTO blaine.bct13 values(2);

+/*e*/INSERT INTO blaine.bct14 values(2);

+ROLLBACK;

+

+-- Unique constraints on the PK tables, but not on our FK tables here,

+-- so cam commit duplicate vals.

+/*u1*/INSERT INTO public.ct15 values(10);

+/*e*/INSERT INTO public.ct16 values(10);

+/*u1*/INSERT INTO public.ct17 values(10);

+/*u1*/INSERT INTO blaine.bct18 values(10);

+/*u1*/INSERT INTO blaine.bct17 values(10);

+/*e*/INSERT INTO public.ct15 values(8);

+/*e*/INSERT INTO public.ct16 values(8);

+/*e*/INSERT INTO public.ct17 values(8);

+/*e*/INSERT INTO public.ct18 values(8);

+/*e*/INSERT INTO blaine.bct17 values(8);

+

+/*e*/INSERT INTO blaine.bmt21 VALUES (2);

+/*u1*/INSERT INTO blaine.bmt21 VALUES (1);

+/*e*/INSERT INTO blaine.bmt20 VALUES (2);

+/*u1*/INSERT INTO blaine.bmt20 VALUES (1);

+/*e*/INSERT INTO blaine.bmt22 VALUES (2);

+/*u1*/INSERT INTO blaine.bmt22 VALUES (1);

+/*e*/INSERT INTO blaine.bmt23 VALUES (2);

+/*u1*/INSERT INTO blaine.bmt23 VALUES (1);

+/*e*/INSERT INTO blaine.bmt25 VALUES (2);

+/*u1*/INSERT INTO blaine.bmt25 VALUES (1);

+

+

+SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfSchemaQuoting.txt b/testrun/hsqldb/TestSelfSchemaQuoting.txt
new file mode 100644
index 0000000..7c519ee
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSchemaQuoting.txt
@@ -0,0 +1,41 @@
+-- Tests quoted schema names

+

+/*u0*/SET SCHEMA information_schema;

+/*u0*/CREATE SCHEMA sChEmA1 authorization sa;

+/*c1*/select * from schemata

+    where schema_owner = 'SA' AND schema_name = 'SCHEMA1';

+

+/*u0*/CREATE SCHEMA dEfAuLt authorization sa;

+/*c1*/select * from schemata

+    where schema_name = 'DEFAULT';

+

+/*u0*/SET INITIAL SCHEMA "DEFAULT";

+/*c1*/SELECT * FROM system_users

+    WHERE user_name = 'SA' AND initial_schema = 'DEFAULT';

+

+/*u0*/SET INITIAL SCHEMA DEFAULT;

+/*c1*/SELECT * FROM system_users

+    WHERE user_name = 'SA' AND initial_schema IS NULL;

+

+/*u0*/CREATE SCHEMA "mIxEdCaSe" AUTHORIZATION sa;

+/*c1*/select * from schemata where schema_name = 'mIxEdCaSe';

+/*u0*/CREATE TABLE "mIxEdCaSe".t1(i int);

+/*e*/DROP TABLE mIxEdCaSe.t1;

+/*u0*/DROP TABLE "mIxEdCaSe".t1;

+/*e*/DROP SCHEMA mIxEdCaSe;

+/*u0*/DROP SCHEMA "mIxEdCaSe";

+

+/*u0*/CREATE USER u1 PASSWORD "u1";

+/*u0*/CREATE SCHEMA "oThErMiXeD" authorization u1;

+/*u0*/CREATE TABLE "oThErMiXeD".t2(i int);

+/*e*/DROP SCHEMA oThErMiXeD CASCADE;

+/*u0*/DROP SCHEMA "oThErMiXeD" CASCADE;

+

+/*s*/DROP USER u1 CASCADE;

+/*s*/DROP USER u1;

+/*s*/DROP SCHEMA schema1 CASCADE;

+

+/*U0*/ Workaround for bug where DDL will not Commit

+/*s*/CREATE TABLE bug_workaround (i int);

+/*s*/INSERT INTO bug_workaround VALUES(1);

+/*u0*/SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfSeqRightsA.txt b/testrun/hsqldb/TestSelfSeqRightsA.txt
new file mode 100644
index 0000000..4e7d90a
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSeqRightsA.txt
@@ -0,0 +1,104 @@
+-- $Id: TestSelfSeqRightsA.txt 610 2008-12-22 15:54:18Z unsaved $

+-- Test Grants/Revokes for Sequences (not ALTER/CREATE/DROP rights, as

+-- tested in the general schema object test scripts).

+-- We are not testing TABLE rights here.  We know that if the table of the

+-- query is not accessible for any reason, the "next value" won't succeed,

+-- so the test setup just grants ALL on the tables used.

+-- Also not testing the numerical values of the sequences.

+-- We're just testing if a "next value for" returns a row successfully.

+-- (some other test file should test the values returned).

+

+-- Remember that unlike 1-to-1-dependent objects like table indexes,

+-- schemas of indexes do not default to that of the table.

+-- (One reason being, in future we may permit a single query of a table in

+-- one schema and sequence(s) in other schema(s)).

+

+-- Setup

+SET WRITE_DELAY 0;

+/*s*/DROP user blaine;

+CREATE user blaine password "b";

+/*u0*/GRANT CHANGE_AUTHORIZATION TO blaine;

+/*s*/DROP SCHEMA bsch CASCADE;

+-- Remove public schema objects.  The CASCADE above takes care of the rest.

+DROP TABLE pt IF EXISTS;

+/*s*/DROP SEQUENCE bs1;

+/*s*/DROP SEQUENCE bs2;

+/*s*/DROP SEQUENCE bs3;

+/*s*/DROP SEQUENCE bs4;

+/*s*/DROP SEQUENCE bs5;

+

+-- We create objects using default schemas and explicit schemas, just to

+-- exercise schema resolution.

+CREATE SCHEMA bsch AUTHORIZATION blaine;

+CREATE TABLE public.pt(i int);

+CREATE TABLE bsch.bt(i int);

+INSERT INTO pt VALUES(1);

+INSERT INTO bsch.bt VALUES(1);

+

+SET SCHEMA bsch;

+CREATE SEQUENCE public.ps1;

+CREATE SEQUENCE public.ps3;

+SET SCHEMA public;

+CREATE SEQUENCE ps2;

+CREATE SEQUENCE ps4;

+CREATE SEQUENCE ps5;

+CREATE SEQUENCE ps6;

+CREATE SEQUENCE ps7;

+CREATE SEQUENCE ps8;

+CREATE SEQUENCE ps9;

+CREATE SEQUENCE bsch.bs1;

+CREATE SEQUENCE bsch.bs3;

+SET SCHEMA bsch;

+CREATE SEQUENCE bs2;

+CREATE SEQUENCE bs4;

+CREATE SEQUENCE bs5;

+GRANT ALL ON public.pt TO blaine;

+GRANT ALL ON bsch.bt TO blaine;

+

+-- Set perms with various permutations of conditions

+-- bs* have enough permissions for blaine by virtue of schema ownerhip.

+-- ps1,2,5,6 have enough permissions by virtue of grants to pub or blaine.

+-- ps3,4,7,8 do not

+/*u0*/GRANT ALL ON SEQUENCE public.ps1 TO public;

+/*u0*/GRANT USAGE ON SEQUENCE public.ps2 TO public;

+/*e*/GRANT SELECT ON SEQUENCE public.ps3 TO public;

+/*e*/GRANT INSERT ON SEQUENCE public.ps4 TO public;

+/*u0*/GRANT ALL ON SEQUENCE public.ps5 TO public;

+/*u0*/GRANT USAGE ON SEQUENCE public.ps6 TO public;

+/*e*/GRANT EXECUTE ON SEQUENCE public.ps7 TO public;

+/*e*/GRANT UPDATE ON SEQUENCE public.ps8 TO public;

+SET SCHEMA public;

+

+/*U*/These two are just workarounds for a DELAY 0 BUG:

+UPDATE public.pt SET i = 1;

+COMMIT;

+

+CONNECT USER blaine PASSWORD "b";

+-- Following is default, but just to eliminate any ambiguity...

+SET SCHEMA public;

+-- By virtue of PUBLIC grants

+/*e*/SELECT i, next value for ps9 FROM pt;

+/*e*/SELECT i, next value for public.ps9 FROM public.pt;

+/*e*/SELECT i, next value for ps9 FROM public.pt;

+/*c1*/SELECT i, next value for ps1 FROM pt;

+SET SCHEMA bsch;

+/*c1*/SELECT i, next value for public.ps2 FROM public.pt;

+-- Don't own

+/*e*/GRANT ALL ON SEQUENCE public.ps2 TO PUBLIC;

+/*u0*/GRANT ALL ON SEQUENCE bsch.bs5 TO PUBLIC;

+-- By virtue of schema ownership

+/*c1*/SELECT i, next value for bs2 FROM bt;

+SET SCHEMA public;

+/*c1*/SELECT i, next value for bsch.bs1 FROM bsch.bt;

+-- Enough schema specification testing.  Just use defauls Session schema for

+-- here on in

+/*c1*/SELECT i FROM pt;

+/*e*/SELECT i, next value for ps3 FROM pt;

+/*e*/SELECT i, next value for ps4 FROM pt;

+/*c1*/SELECT i, next value for ps5 FROM pt;

+/*c1*/SELECT i, next value for ps6 FROM pt;

+/*e*/SELECT i, next value for ps7 FROM pt;

+/*e*/SELECT i, next value for ps8 FROM pt;

+

+CONNECT USER sa PASSWORD "";

+SHUTDOWN IMMEDIATELY;

diff --git a/testrun/hsqldb/TestSelfSeqRightsB.txt b/testrun/hsqldb/TestSelfSeqRightsB.txt
new file mode 100644
index 0000000..375a071
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSeqRightsB.txt
@@ -0,0 +1,33 @@
+-- $Id: TestSelfSeqRightsB.txt 610 2008-12-22 15:54:18Z unsaved $

+-- Test .log persistence of Sequence rights

+

+CONNECT USER blaine PASSWORD "b";

+-- Following is default, but just to eliminate any ambiguity...

+SET SCHEMA public;

+-- By virtue of PUBLIC grants

+/*c1*/SELECT * FROM pt;

+/*e*/SELECT i, next value for ps9 FROM pt;

+/*e*/SELECT i, next value for public.ps9 FROM public.pt;

+/*e*/SELECT i, next value for ps9 FROM public.pt;

+/*c1*/SELECT i, next value for ps1 FROM pt;

+SET SCHEMA bsch;

+/*c1*/SELECT i, next value for public.ps2 FROM public.pt;

+-- Don't own

+/*e*/GRANT ALL ON SEQUENCE public.ps2 TO PUBLIC;

+/*u0*/GRANT ALL ON SEQUENCE bsch.bs5 TO PUBLIC;

+-- By virtue of schema ownership

+/*c1*/SELECT i, next value for bs2 FROM bt;

+SET SCHEMA public;

+/*c1*/SELECT i, next value for bsch.bs1 FROM bsch.bt;

+-- Enough schema specification testing.  Just use defauls Session schema for

+-- here on in

+/*c1*/SELECT i FROM pt;

+/*e*/SELECT i, next value for ps3 FROM pt;

+/*e*/SELECT i, next value for ps4 FROM pt;

+/*c1*/SELECT i, next value for ps5 FROM pt;

+/*c1*/SELECT i, next value for ps6 FROM pt;

+/*e*/SELECT i, next value for ps7 FROM pt;

+/*e*/SELECT i, next value for ps8 FROM pt;

+

+CONNECT USER sa PASSWORD "";

+SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfSeqRightsC.txt b/testrun/hsqldb/TestSelfSeqRightsC.txt
new file mode 100644
index 0000000..c473b2a
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSeqRightsC.txt
@@ -0,0 +1,36 @@
+-- $Id: TestSelfSeqRightsC.txt 610 2008-12-22 15:54:18Z unsaved $

+-- Test .script persistence of Sequence rights

+

+CONNECT USER blaine PASSWORD "b";

+-- Following is default, but just to eliminate any ambiguity...

+SET SCHEMA public;

+-- By virtue of PUBLIC grants

+/*e*/SELECT i, next value for ps9 FROM pt;

+/*e*/SELECT i, next value for public.ps9 FROM public.pt;

+/*e*/SELECT i, next value for ps9 FROM public.pt;

+/*c1*/SELECT i, next value for ps1 FROM pt;

+SET SCHEMA bsch;

+/*c1*/SELECT i, next value for public.ps2 FROM public.pt;

+-- Don't own

+/*e*/GRANT ALL ON SEQUENCE public.ps2 TO PUBLIC;

+/*u0*/GRANT ALL ON SEQUENCE bsch.bs5 TO PUBLIC;

+-- By virtue of schema ownership

+/*c1*/SELECT i, next value for bs2 FROM bt;

+SET SCHEMA public;

+/*c1*/SELECT i, next value for bsch.bs1 FROM bsch.bt;

+-- Enough schema specification testing.  Just use defauls Session schema for

+-- here on in

+/*c1*/SELECT i FROM pt;

+/*e*/SELECT i, next value for ps3 FROM pt;

+/*e*/SELECT i, next value for ps4 FROM pt;

+/*c1*/SELECT i, next value for ps5 FROM pt;

+/*c1*/SELECT i, next value for ps6 FROM pt;

+/*e*/SELECT i, next value for ps7 FROM pt;

+/*e*/SELECT i, next value for ps8 FROM pt;

+

+-- Test REVOKES

+-- Can't revoke on objects you don't own

+/*e*/REVOKE ALL ON SEQUENCE public.ps6 FROM public RESTRICT;

+/*u0*/REVOKE ALL ON SEQUENCE bsch.bs1 FROM public RESTRICT;

+CONNECT USER sa PASSWORD "";

+/*u0*/REVOKE USAGE ON SEQUENCE public.ps6 FROM BLAINE RESTRICT;

diff --git a/testrun/hsqldb/TestSelfStoredProcedure.txt b/testrun/hsqldb/TestSelfStoredProcedure.txt
new file mode 100644
index 0000000..fe1969c
--- /dev/null
+++ b/testrun/hsqldb/TestSelfStoredProcedure.txt
@@ -0,0 +1,436 @@
+-- AUXILIAR TABLES + DECLARES

+DROP TABLE tt1 IF EXISTS;

+DROP TABLE tt2 IF EXISTS;

+DECLARE test_retval INT DEFAULT NULL;

+CREATE Cached TABLE tt1(

+   ID INTEGER NOT NULL PRIMARY KEY,

+   tt2ref INTEGER

+   );

+

+CREATE Cached TABLE tt2(

+   ID INTEGER NOT NULL PRIMARY KEY

+   );

+ALTER TABLE tt1 ADD CONSTRAINT fk2 FOREIGN KEY (tt2ref) REFERENCES tt2(ID);

+

+-- CREATE SIMPLE PROCEDURES - INVALID

+

+-- Exception no body

+/*e*/CREATE PROCEDURE procedure_test() MODIFIES SQL DATA

+  BEGIN ATOMIC

+  END

+

+-- Exception no exists - in call + in drop

+/*e*/CREATE PROCEDURE procedure_test() MODIFIES SQL DATA

+  BEGIN ATOMIC

+  END

+-- Exception no body

+/*e*/DROP PROCEDURE procedure_test

+/*e*/call procedure_test()

+

+-- Exception invalid parameter - reserved word

+/*e*/CREATE PROCEDURE procedure_test(IN value INTEGER) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET val = val + 1;

+  END

+-- Exception no body

+/*e*/DROP PROCEDURE procedure_test

+/*e*/call procedure_test()

+

+-- CREATE SIMPLE PROCEDURES

+

+-- Empty procedure

+CREATE PROCEDURE procedure_test() MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE temp INT;

+  SET temp = 10;

+  END

+call procedure_test()

+DROP PROCEDURE procedure_test

+

+-- Empty procedure - IN parameter

+CREATE PROCEDURE procedure_test(IN val INTEGER) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu INT DEFAULT 1;

+  SET valu = val + 1;

+  END

+call procedure_test(20)

+DROP PROCEDURE procedure_test

+

+-- Empty procedure - INT parameter + OUT parameter

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET retval = val + 1;

+  END

+CALL procedure_test(20, test_retval);

+/*r21*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- Empty procedure - INTOUT parameter

+CREATE PROCEDURE procedure_test(INOUT val INTEGER) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET val = val + 1;

+  END

+SET test_retval=20;

+CALL procedure_test(test_retval);

+/*r21*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- PROCEDURES - BASIC SQL OPERATIONS

+

+-- simple procedure return select

+CREATE PROCEDURE procedure_test(OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SELECT id INTO retval FROM tt2;

+  END

+INSERT INTO tt2(ID) VALUES(1);

+call procedure_test(test_retval)

+/*r1*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple procedure test insert

+CREATE PROCEDURE procedure_test(OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DELETE FROM tt2;

+  INSERT INTO tt2(ID) VALUES(1);

+  INSERT INTO tt2(ID) VALUES(2);

+  SELECT COUNT(id) INTO retval FROM tt2;

+  END

+call procedure_test(test_retval)

+/*r2*/CALL test_retval;

+/*r2*/SELECT COUNT(*) FROM tt2;

+

+CREATE USER PUSER PASSWORD ''

+GRANT CHANGE_AUTHORIZATION TO PUSER

+GRANT EXECUTE ON ROUTINE procedure_test TO puser

+SET SESSION AUTHORIZATION 'PUSER'

+

+CALL procedure_test(test_retval)

+/*r2*/CALL test_retval;

+

+SET SESSION AUTHORIZATION 'SA'

+/*r2*/SELECT COUNT(*) FROM tt2;

+REVOKE EXECUTE ON ROUTINE procedure_test FROM puser CASCADE

+SET SESSION AUTHORIZATION 'PUSER'

+/*e*/CALL procedure_test(test_retval)

+SET SESSION AUTHORIZATION 'SA'

+DROP PROCEDURE procedure_test

+

+-- PROCEDURES - VARIABLES

+

+-- simple procedure asignment

+CREATE PROCEDURE procedure_test(OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE temp INT;

+  SET temp = 10;

+  SET retval = temp;

+  END

+call procedure_test(test_retval)

+/*r10*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple add

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE temp INT;

+  SET temp = 10;

+  SET retval = val + temp;

+  END

+call procedure_test(5, test_retval)

+/*r15*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple substract

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE temp INT;

+  SET temp = 1;

+  SET retval = val - temp;

+  END

+call procedure_test(5, test_retval)

+/*r4*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple multiply

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE temp INT;

+  SET temp = 25;

+  SET retval = val * temp;

+  END

+call procedure_test(5, test_retval)

+/*r125*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple division

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE temp INT;

+  SET temp = 5;

+  SET retval = val / temp;

+  END

+call procedure_test(22, test_retval)

+/*r4*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- PROCEDURES - CONDITIONS

+

+-- simple IF

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET retval = 0;

+  IF val = 1 THEN SET retval = 21; END IF;

+  END

+call procedure_test(0, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(1, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(2, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(200, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(-23, test_retval)

+/*r0*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple IF/ELSE

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET retval = 0;

+  IF val = 1 THEN SET retval = 21;

+  ELSE SET retval = 55;

+  END IF;

+  END

+call procedure_test(0, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(1, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(2, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(200, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(-23, test_retval)

+/*r55*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple IF/ELSEIF/ELSE

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE temp INT;

+  IF val = 1 THEN SET retval = 21;

+  ELSEIF val = 2 THEN SET retval = 55;

+  ELSE SET retval = 100;

+  END IF;

+  END

+call procedure_test(0, test_retval)

+/*r100*/CALL test_retval;

+call procedure_test(1, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(2, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(3, test_retval)

+/*r100*/CALL test_retval;

+call procedure_test(200, test_retval)

+/*r100*/CALL test_retval;

+call procedure_test(-23, test_retval)

+/*r100*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple CASE

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET retval = 0;

+  CASE val

+    WHEN 1 THEN SET retval = 21;

+  END CASE;

+  END

+call procedure_test(0, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(1, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(2, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(200, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(-23, test_retval)

+/*r0*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple CASE - multivalue

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET retval = 0;

+  CASE val

+    WHEN 1,2 THEN SET retval = 21;

+  END CASE;

+  END

+call procedure_test(0, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(1, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(2, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(3, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(200, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(-23, test_retval)

+/*r0*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple CASE - multivalue

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET retval = 0;

+  CASE val

+    WHEN 1,2 THEN SET retval = 21;

+    WHEN IN (3, 4, 5) THEN SET retval = 55;

+  END CASE;

+  END

+call procedure_test(0, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(1, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(2, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(3, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(4, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(5, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(6, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(200, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(-23, test_retval)

+/*r0*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple CASE - multivalue (repeated)

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  SET retval = 0;

+  CASE val

+    WHEN 1,2 THEN SET retval = 21;

+    WHEN IN (2, 3, 5) THEN SET retval = 55;

+  END CASE;

+  END

+call procedure_test(0, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(1, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(2, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(3, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(4, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(5, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(6, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(200, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(-23, test_retval)

+/*r0*/CALL test_retval;

+DROP PROCEDURE procedure_test

+

+-- simple CASE - multivalue & else

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  CASE val

+    WHEN 1,2 THEN SET retval = 21;

+    WHEN IN (2, 3, 5) THEN SET retval = 55;

+    ELSE SET retval = 101;

+  END CASE;

+  END

+call procedure_test(0, test_retval)

+/*r101*/CALL test_retval;

+call procedure_test(1, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(2, test_retval)

+/*r21*/CALL test_retval;

+call procedure_test(3, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(4, test_retval)

+/*r101*/CALL test_retval;

+call procedure_test(5, test_retval)

+/*r55*/CALL test_retval;

+call procedure_test(6, test_retval)

+/*r101*/CALL test_retval;

+call procedure_test(200, test_retval)

+/*r101*/CALL test_retval;

+call procedure_test(-23, test_retval)

+/*r101*/CALL test_retval;

+DROP PROCEDURE procedure_test;

+

+-- PROCEDURES -- BUCLES

+

+-- simple WHILE

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE counter INT;

+  DECLARE temp INT;

+  SET counter = val;

+  SET temp = 0;

+  WHILE counter < 10 DO

+     SET temp = temp + counter;

+     SET counter = counter + 1;

+  END WHILE;

+  SET retval = temp;

+  END

+call procedure_test(0, test_retval)

+/*r45*/CALL test_retval;

+call procedure_test(5, test_retval)

+/*r35*/CALL test_retval;

+call procedure_test(10, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(100, test_retval)

+/*r0*/CALL test_retval;

+DROP PROCEDURE procedure_test;

+

+-- simple REPEAT

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE counter INT;

+  DECLARE temp INT;

+  SET counter = val;

+  SET temp = 0;

+  REPEAT

+     SET temp = temp + counter;

+     SET counter = counter + 1;

+  UNTIL counter >= 10

+  END REPEAT;

+  SET retval = temp;

+  END

+call procedure_test(0, test_retval)

+/*r45*/CALL test_retval;

+call procedure_test(5, test_retval)

+/*r35*/CALL test_retval;

+call procedure_test(10, test_retval)

+/*r10*/CALL test_retval;

+call procedure_test(100, test_retval)

+/*r100*/CALL test_retval;

+DROP PROCEDURE procedure_test;

+

+-- simple REPEAT with infinite loop

+CREATE PROCEDURE procedure_test(IN val INT, OUT retval INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE counter INT;

+  DECLARE temp INT;

+  SET counter = val;

+  SET temp = 0;

+  REPEAT

+     SET temp = temp + counter;

+     SET counter = counter + 1;

+  UNTIL counter < 10

+  END REPEAT;

+  SET retval = temp;

+  END

+call procedure_test(0, test_retval)

+/*r0*/CALL test_retval;

+call procedure_test(5, test_retval)

+/*r5*/CALL test_retval;

+-- infinite loop

+--/*e*/call procedure_test(10, test_retval)

+DROP PROCEDURE procedure_test;

diff --git a/testrun/hsqldb/TestSelfStoredProcedureTypes.txt b/testrun/hsqldb/TestSelfStoredProcedureTypes.txt
new file mode 100644
index 0000000..501c355
--- /dev/null
+++ b/testrun/hsqldb/TestSelfStoredProcedureTypes.txt
@@ -0,0 +1,252 @@
+-- PARAMETERS IN

+

+-- Type SMALLINT

+CREATE PROCEDURE procedure_test(IN val SMALLINT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu INT;

+  SET valu = val;

+  END

+call procedure_test(0);

+call procedure_test(5);

+call procedure_test(-5);

+/*e*/call procedure_test(40000);

+/*e*/call procedure_test(-40000);

+/*e*/call procedure_test('a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type INT

+CREATE PROCEDURE procedure_test(IN val INT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu INT;

+  SET valu = val;

+  END

+call procedure_test(0);

+call procedure_test(5);

+call procedure_test(-5);

+call procedure_test(40000);

+call procedure_test(-40000);

+/*e*/call procedure_test(123456789012345);

+/*e*/call procedure_test(-123456789012345);

+/*e*/call procedure_test('a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+CREATE PROCEDURE procedure_test(IN val INTEGER) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu INT;

+  SET valu = val;

+  END

+call procedure_test(0);

+call procedure_test(5);

+call procedure_test(-5);

+call procedure_test(40000);

+call procedure_test(-40000);

+/*e*/call procedure_test(123456789012345);

+/*e*/call procedure_test(-123456789012345);

+/*e*/call procedure_test('a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type BIGINT

+CREATE PROCEDURE procedure_test(IN val BIGINT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu BIGINT;

+  SET valu = val;

+  END

+call procedure_test(0);

+call procedure_test(5);

+call procedure_test(-5);

+call procedure_test(40000);

+call procedure_test(-40000);

+call procedure_test(123456789012345);

+call procedure_test(-123456789012345);

+/*e*/call procedure_test(12345678901234567890123456789012345678790);

+/*e*/call procedure_test(-12345678901234567890123456789012345678790);

+/*e*/call procedure_test('a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type DECIMAL

+CREATE PROCEDURE procedure_test(IN val DECIMAL) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu DECIMAL;

+  SET valu = val;

+  END

+call procedure_test(0);

+call procedure_test(5);

+call procedure_test(-5);

+call procedure_test(40000);

+call procedure_test(-40000);

+call procedure_test(123456789012345);

+call procedure_test(-123456789012345);

+call procedure_test(1.034);

+call procedure_test(-1.3E24);

+call procedure_test(1.04324324423E352);

+/*e*/call procedure_test('a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+CREATE PROCEDURE procedure_test(IN val NUMERIC) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu DECIMAL;

+  SET valu = val;

+  END

+call procedure_test(0);

+call procedure_test(5);

+call procedure_test(-5);

+call procedure_test(40000);

+call procedure_test(-40000);

+call procedure_test(123456789012345);

+call procedure_test(-123456789012345);

+call procedure_test(1.034);

+call procedure_test(-1.3E24);

+call procedure_test(1.0E352);

+/*e*/call procedure_test('a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type DOUBLE

+CREATE PROCEDURE procedure_test(IN val FLOAT) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu DECIMAL;

+  SET valu = val;

+  END

+call procedure_test(0);

+call procedure_test(5);

+call procedure_test(-5);

+call procedure_test(40000);

+call procedure_test(-40000);

+call procedure_test(123456789012345);

+call procedure_test(-123456789012345);

+call procedure_test(1.034);

+call procedure_test(-1.3E24);

+call procedure_test(1.04324324423E35242);

+/*e*/call procedure_test('a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+CREATE PROCEDURE procedure_test(IN val DOUBLE) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu DECIMAL;

+  SET valu = val;

+  END

+call procedure_test(0);

+call procedure_test(5);

+call procedure_test(-5);

+call procedure_test(40000);

+call procedure_test(-40000);

+call procedure_test(123456789012345);

+call procedure_test(-123456789012345);

+call procedure_test(1.034);

+call procedure_test(-1.3E24);

+call procedure_test(1.04324324423E35242);

+/*e*/call procedure_test('a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type CHAR

+CREATE PROCEDURE procedure_test(IN val CHAR(1)) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu VARCHAR(10);

+  SET valu = val;

+  END

+call procedure_test('a');

+/*e*/call procedure_test(5);

+/*e*/call procedure_test(-5);

+call procedure_test('');

+/*e*/call procedure_test('ab');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type CHAR

+CREATE PROCEDURE procedure_test(IN val CHAR(10)) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu VARCHAR(10);

+  SET valu = val;

+  END

+call procedure_test('0123456789');

+/*e*/call procedure_test(5);

+/*e*/call procedure_test(-5);

+call procedure_test('');

+call procedure_test('ab');

+/*e*/call procedure_test('0123456789a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type VARCHAR

+CREATE PROCEDURE procedure_test(IN val VARCHAR(1)) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu VARCHAR(10);

+  SET valu = val;

+  END

+call procedure_test('a');

+/*e*/call procedure_test(5);

+/*e*/call procedure_test(-5);

+call procedure_test('');

+/*e*/call procedure_test('ab');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+CREATE PROCEDURE procedure_test(IN val VARCHAR(10)) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu VARCHAR(10);

+  SET valu = val;

+  END

+call procedure_test('a');

+call procedure_test('0123456789');

+/*e*/call procedure_test(5);

+/*e*/call procedure_test(-5);

+call procedure_test('');

+call procedure_test('ab');

+/*e*/call procedure_test('0123456789a');

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type DATE

+CREATE PROCEDURE procedure_test(IN val DATE) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu DATE;

+  SET valu = val;

+  END

+call procedure_test({d '2010-01-01'});

+/*e*/call procedure_test('a');

+/*e*/call procedure_test(5);

+/*e*/call procedure_test(-5);

+/*e*/call procedure_test('');

+/*e*/call procedure_test('ab');

+/*e*/call procedure_test({t '10:00:00'});

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type TIME

+CREATE PROCEDURE procedure_test(IN val TIME) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu TIME;

+  SET valu = val;

+  END

+call procedure_test({t '10:00:00'});

+/*e*/call procedure_test('a');

+/*e*/call procedure_test(5);

+/*e*/call procedure_test(-5);

+/*e*/call procedure_test('');

+/*e*/call procedure_test('ab');

+/*e*/call procedure_test({d '2010-01-01'});

+/*e*/call procedure_test({ts '2010-01-01 10:00:00'});

+DROP PROCEDURE procedure_test;

+

+-- Type TIMESTAMP

+CREATE PROCEDURE procedure_test(IN val TIMESTAMP) MODIFIES SQL DATA

+  BEGIN ATOMIC

+  DECLARE valu TIMESTAMP;

+  SET valu = val;

+  END

+call procedure_test({ts '2010-01-01 10:00:00'});

+/*e*/call procedure_test('a');

+/*e*/call procedure_test(5);

+/*e*/call procedure_test(-5);

+/*e*/call procedure_test('');

+/*e*/call procedure_test('ab');

+/*e*/call procedure_test({d '2010-01-01'});

+/*e*/call procedure_test({t '10:00:00'});

+DROP PROCEDURE procedure_test;

diff --git a/testrun/hsqldb/TestSelfSubselects.txt b/testrun/hsqldb/TestSelfSubselects.txt
new file mode 100644
index 0000000..ffe3211
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSubselects.txt
@@ -0,0 +1,62 @@
+drop table colors if exists;

+drop table sizes if exists;

+drop table fruits if exists;

+drop table trees if exists;

+create table colors(id int, val char(20));

+insert into colors values(1,'red');

+insert into colors values(2,'green');

+insert into colors values(3,'orange');

+insert into colors values(4,'indigo');

+create table sizes(id int, val char(20));

+insert into sizes values(1,'small');

+insert into sizes values(2,'medium');

+insert into sizes values(3,'large');

+insert into sizes values(4,'odd');

+create table fruits(id int, name char(30), color_id int);

+insert into fruits values(1, 'golden delicious',2);

+insert into fruits values(2, 'macintosh',1);

+insert into fruits values(3, 'red delicious',1);

+insert into fruits values(4, 'granny smith',2);

+insert into fruits values(5, 'tangerine',4);

+create table trees(id int, name char(30), fruit_id int, size_id int);

+insert into trees values(1, 'small golden delicious tree',1,1);

+insert into trees values(2, 'large macintosh tree',2,3);

+insert into trees values(3, 'large red delicious tree',3,3);

+insert into trees values(4, 'small red delicious tree',3,1);

+insert into trees values(5, 'medium granny smith tree',4,2);

+select a.val, b.name from sizes a, trees b where a.id = b.size_id and b.id in (select a.id from trees a, fruits b where a.fruit_id = b.id and b.name='red delicious') order by a.val;

+--

+-- bug #547764

+-- name in subquery must resolve to the subquery first

+drop table trees if exists;

+drop table fruits if exists;

+create table trees(id integer primary key,name varchar(30) not null);

+create table fruits(id integer primary key,name varchar(30) not null,

+ tree_id integer not null,foreign key (tree_id) references trees(id));

+insert into trees (id, name) values (1, 'apple');

+insert into fruits (id, name, tree_id) values(1, 'pippin', 1);

+insert into fruits (id, name, tree_id) values(2, 'granny smith', 1);

+/*c2*/select id from fruits where tree_id in(select id from trees where name = 'apple');

+

+drop table table1 if exists;

+drop table table2 if exists;

+CREATE TABLE TABLE1 (COL1 INTEGER, COL2 CHAR(1))

+CREATE TABLE TABLE2 (COL1 INTEGER)

+insert into table1 values 1, 'X'

+insert into table2 values 1

+/*r1*/SELECT T1.COL1 FROM TABLE1 T1 INNER JOIN

+ (SELECT COL1 FROM TABLE2) T2 ON T1.COL1 = T2.COL1

+ WHERE T1.COL2 = 'X'

+

+/*r

+ null,4

+ 5,6

+*/select * from (

+ select null as aaaaaaa, 4 as b from table2

+ union select 5 as aaaaaaa, 6 as b from table2

+ ) baz

+

+

+

+drop table table1

+drop table table2

diff --git a/testrun/hsqldb/TestSelfSysTables.txt b/testrun/hsqldb/TestSelfSysTables.txt
new file mode 100644
index 0000000..3df3b75
--- /dev/null
+++ b/testrun/hsqldb/TestSelfSysTables.txt
@@ -0,0 +1,176 @@
+SET SCHEMA information_schema;

+SELECT * FROM SYSTEM_BESTROWIDENTIFIER

+SELECT * FROM SYSTEM_CACHEINFO

+SELECT * FROM SYSTEM_COLUMNS

+SELECT * FROM SYSTEM_COMMENTS

+SELECT * FROM SYSTEM_CROSSREFERENCE

+SELECT * FROM SYSTEM_INDEXINFO

+SELECT * FROM SYSTEM_PRIMARYKEYS

+SELECT * FROM SYSTEM_PROCEDURECOLUMNS

+SELECT * FROM SYSTEM_PROCEDURES

+SELECT * FROM SYSTEM_PROPERTIES

+SELECT * FROM SYSTEM_SCHEMAS

+SELECT * FROM SYSTEM_SESSIONINFO

+SELECT * FROM SYSTEM_SESSIONS

+SELECT * FROM SYSTEM_TABLES

+SELECT * FROM SYSTEM_TABLETYPES

+SELECT * FROM SYSTEM_TEXTTABLES

+SELECT * FROM SYSTEM_TYPEINFO

+SELECT * FROM SYSTEM_UDTS

+SELECT * FROM SYSTEM_USERS

+SELECT * FROM SYSTEM_VERSIONCOLUMNS

+

+-- select a second time

+

+SELECT * FROM SYSTEM_BESTROWIDENTIFIER

+SELECT * FROM SYSTEM_CACHEINFO

+SELECT * FROM SYSTEM_COLUMNS

+SELECT * FROM SYSTEM_COMMENTS

+SELECT * FROM SYSTEM_CROSSREFERENCE

+SELECT * FROM SYSTEM_INDEXINFO

+SELECT * FROM SYSTEM_PRIMARYKEYS

+SELECT * FROM SYSTEM_PROCEDURECOLUMNS

+SELECT * FROM SYSTEM_PROCEDURES

+SELECT * FROM SYSTEM_PROPERTIES

+SELECT * FROM SYSTEM_SCHEMAS

+SELECT * FROM SYSTEM_SESSIONINFO

+SELECT * FROM SYSTEM_SESSIONS

+SELECT * FROM SYSTEM_TABLES

+SELECT * FROM SYSTEM_TABLETYPES

+SELECT * FROM SYSTEM_TEXTTABLES

+SELECT * FROM SYSTEM_TYPEINFO

+SELECT * FROM SYSTEM_UDTS

+SELECT * FROM SYSTEM_USERS

+SELECT * FROM SYSTEM_VERSIONCOLUMNS

+

+--

+

+SELECT * FROM ADMINISTRABLE_ROLE_AUTHORIZATIONS

+SELECT * FROM APPLICABLE_ROLES

+SELECT * FROM ASSERTIONS

+SELECT * FROM AUTHORIZATIONS

+SELECT * FROM CHARACTER_SETS

+SELECT * FROM CHECK_CONSTRAINT_ROUTINE_USAGE

+SELECT * FROM CHECK_CONSTRAINTS

+SELECT * FROM COLLATIONS

+SELECT * FROM COLUMN_COLUMN_USAGE

+SELECT * FROM COLUMN_DOMAIN_USAGE

+SELECT * FROM COLUMN_PRIVILEGES

+SELECT * FROM COLUMN_UDT_USAGE

+SELECT * FROM COLUMNS

+SELECT * FROM CONSTRAINT_COLUMN_USAGE

+SELECT * FROM CONSTRAINT_TABLE_USAGE

+SELECT * FROM DATA_TYPE_PRIVILEGES

+SELECT * FROM DOMAIN_CONSTRAINTS

+SELECT * FROM DOMAINS

+SELECT * FROM ENABLED_ROLES

+SELECT * FROM INFORMATION_SCHEMA_CATALOG_NAME

+SELECT * FROM JAR_JAR_USAGE

+SELECT * FROM JARS

+SELECT * FROM KEY_COLUMN_USAGE

+SELECT * FROM PARAMETERS

+SELECT * FROM REFERENTIAL_CONSTRAINTS

+SELECT * FROM ROLE_AUTHORIZATION_DESCRIPTORS

+SELECT * FROM ROLE_COLUMN_GRANTS

+SELECT * FROM ROLE_ROUTINE_GRANTS

+SELECT * FROM ROLE_TABLE_GRANTS

+SELECT * FROM ROLE_UDT_GRANTS

+SELECT * FROM ROLE_USAGE_GRANTS

+SELECT * FROM ROUTINE_COLUMN_USAGE

+SELECT * FROM ROUTINE_JAR_USAGE

+SELECT * FROM ROUTINE_PRIVILEGES

+SELECT * FROM ROUTINE_ROUTINE_USAGE

+SELECT * FROM ROUTINE_SEQUENCE_USAGE

+SELECT * FROM ROUTINE_TABLE_USAGE

+SELECT * FROM ROUTINES

+SELECT * FROM SCHEMATA

+SELECT * FROM SEQUENCES

+SELECT * FROM SQL_FEATURES

+SELECT * FROM SQL_IMPLEMENTATION_INFO

+SELECT * FROM SQL_PACKAGES

+SELECT * FROM SQL_PARTS

+SELECT * FROM SQL_SIZING

+SELECT * FROM SQL_SIZING_PROFILES

+SELECT * FROM TABLE_CONSTRAINTS

+SELECT * FROM TABLE_PRIVILEGES

+SELECT * FROM TABLES

+SELECT * FROM TRANSLATIONS

+SELECT * FROM TRIGGER_COLUMN_USAGE

+SELECT * FROM TRIGGER_ROUTINE_USAGE

+SELECT * FROM TRIGGER_SEQUENCE_USAGE

+SELECT * FROM TRIGGER_TABLE_USAGE

+SELECT * FROM TRIGGERED_UPDATE_COLUMNS

+SELECT * FROM TRIGGERS

+SELECT * FROM UDT_PRIVILEGES

+SELECT * FROM USAGE_PRIVILEGES

+SELECT * FROM USER_DEFINED_TYPES

+SELECT * FROM VIEW_COLUMN_USAGE

+SELECT * FROM VIEW_ROUTINE_USAGE

+SELECT * FROM VIEW_TABLE_USAGE

+SELECT * FROM VIEWS

+

+-- select a second time

+

+SELECT * FROM ADMINISTRABLE_ROLE_AUTHORIZATIONS

+SELECT * FROM APPLICABLE_ROLES

+SELECT * FROM ASSERTIONS

+SELECT * FROM AUTHORIZATIONS

+SELECT * FROM CHARACTER_SETS

+SELECT * FROM CHECK_CONSTRAINT_ROUTINE_USAGE

+SELECT * FROM CHECK_CONSTRAINTS

+SELECT * FROM COLLATIONS

+SELECT * FROM COLUMN_COLUMN_USAGE

+SELECT * FROM COLUMN_DOMAIN_USAGE

+SELECT * FROM COLUMN_PRIVILEGES

+SELECT * FROM COLUMN_UDT_USAGE

+SELECT * FROM COLUMNS

+SELECT * FROM CONSTRAINT_COLUMN_USAGE

+SELECT * FROM CONSTRAINT_TABLE_USAGE

+SELECT * FROM DATA_TYPE_PRIVILEGES

+SELECT * FROM DOMAIN_CONSTRAINTS

+SELECT * FROM DOMAINS

+SELECT * FROM ENABLED_ROLES

+SELECT * FROM INFORMATION_SCHEMA_CATALOG_NAME

+SELECT * FROM JAR_JAR_USAGE

+SELECT * FROM JARS

+SELECT * FROM KEY_COLUMN_USAGE

+SELECT * FROM PARAMETERS

+SELECT * FROM REFERENTIAL_CONSTRAINTS

+SELECT * FROM ROLE_AUTHORIZATION_DESCRIPTORS

+SELECT * FROM ROLE_COLUMN_GRANTS

+SELECT * FROM ROLE_ROUTINE_GRANTS

+SELECT * FROM ROLE_TABLE_GRANTS

+SELECT * FROM ROLE_UDT_GRANTS

+SELECT * FROM ROLE_USAGE_GRANTS

+SELECT * FROM ROUTINE_COLUMN_USAGE

+SELECT * FROM ROUTINE_JAR_USAGE

+SELECT * FROM ROUTINE_PRIVILEGES

+SELECT * FROM ROUTINE_ROUTINE_USAGE

+SELECT * FROM ROUTINE_SEQUENCE_USAGE

+SELECT * FROM ROUTINE_TABLE_USAGE

+SELECT * FROM ROUTINES

+SELECT * FROM SCHEMATA

+SELECT * FROM SEQUENCES

+SELECT * FROM SQL_FEATURES

+SELECT * FROM SQL_IMPLEMENTATION_INFO

+SELECT * FROM SQL_PACKAGES

+SELECT * FROM SQL_PARTS

+SELECT * FROM SQL_SIZING

+SELECT * FROM SQL_SIZING_PROFILES

+SELECT * FROM TABLE_CONSTRAINTS

+SELECT * FROM TABLE_PRIVILEGES

+SELECT * FROM TABLES

+SELECT * FROM TRANSLATIONS

+SELECT * FROM TRIGGER_COLUMN_USAGE

+SELECT * FROM TRIGGER_ROUTINE_USAGE

+SELECT * FROM TRIGGER_SEQUENCE_USAGE

+SELECT * FROM TRIGGER_TABLE_USAGE

+SELECT * FROM TRIGGERED_UPDATE_COLUMNS

+SELECT * FROM TRIGGERS

+SELECT * FROM UDT_PRIVILEGES

+SELECT * FROM USAGE_PRIVILEGES

+SELECT * FROM USER_DEFINED_TYPES

+SELECT * FROM VIEW_COLUMN_USAGE

+SELECT * FROM VIEW_ROUTINE_USAGE

+SELECT * FROM VIEW_TABLE_USAGE

+SELECT * FROM VIEWS

diff --git a/testrun/hsqldb/TestSelfTempTable1.txt b/testrun/hsqldb/TestSelfTempTable1.txt
new file mode 100644
index 0000000..f868620
--- /dev/null
+++ b/testrun/hsqldb/TestSelfTempTable1.txt
@@ -0,0 +1,34 @@
+/*s*/DROP tmptbl1 IF EXISTS;

+/*s*/DROP tmptbl2 IF EXISTS;

+/*s*/DROP user altuser1;

+/*s*/DROP user altuser2;

+

+CREATE USER altuser1 PASSWORD password;

+CREATE USER altuser2 PASSWORD password;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO altuser1;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO altuser2;

+/*u0*/CREATE TEMP TABLE tmptbl1 (i int);

+/*u0*/CREATE TEMP TABLE tmptbl2 (i int);

+/*u0*/GRANT ALL ON tmptbl1 TO altuser1;

+/*u0*/GRANT ALL ON tmptbl2 TO altuser1;

+SET AUTOCOMMIT false;

+/*u1*/INSERT INTO tmptbl1 VALUES(1);

+/*u1*/INSERT INTO tmptbl1 VALUES(2);

+/*c2*/SELECT * FROM tmptbl1;

+COMMIT;

+/*u1*/INSERT INTO tmptbl2 VALUES(1);

+/*u1*/INSERT INTO tmptbl2 VALUES(2);

+/*c0*/SELECT * FROM tmptbl1;

+/*c2*/SELECT * FROM tmptbl2;

+COMMIT;

+

+CONNECT USER altuser1 PASSWORD password;

+/*c0*/SELECT * FROM tmptbl1;

+/*c0*/SELECT * FROM tmptbl2;

+COMMIT;

+

+CONNECT USER altuser2 PASSWORD password;

+/*e*/SELECT * FROM tmptbl1;

+/*e*/SELECT * FROM tmptbl2;

+CONNECT USER SA password "";

+SHUTDOWN IMMEDIATELY;

diff --git a/testrun/hsqldb/TestSelfTempTable2.txt b/testrun/hsqldb/TestSelfTempTable2.txt
new file mode 100644
index 0000000..1a350a6
--- /dev/null
+++ b/testrun/hsqldb/TestSelfTempTable2.txt
@@ -0,0 +1,24 @@
+-- This script depends on TestSelfTempTable1.txt to set up the objects tested.

+

+SET AUTOCOMMIT false;

+/*c0*/SELECT * FROM tmptbl1;

+/*c0*/SELECT * FROM tmptbl2;

+COMMIT;

+CONNECT USER altuser2 PASSWORD password;

+/*e*/SELECT * FROM tmptbl1;

+/*e*/SELECT * FROM tmptbl2;

+CONNECT USER altuser1 PASSWORD password;

+/*c0*/SELECT * FROM tmptbl1;

+/*c0*/SELECT * FROM tmptbl2;

+/*u1*/INSERT INTO tmptbl1 VALUES(1);

+/*u1*/INSERT INTO tmptbl1 VALUES(2);

+/*c2*/SELECT * FROM tmptbl1;

+COMMIT;

+-- Purposefully not committing these inserts

+/*c0*/SELECT * FROM tmptbl1;

+/*u1*/INSERT INTO tmptbl2 VALUES(1);

+/*u1*/INSERT INTO tmptbl2 VALUES(2);

+/*c2*/SELECT * FROM tmptbl2;

+ROLLBACK;

+CONNECT USER SA password "";

+SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfTransaction.txt b/testrun/hsqldb/TestSelfTransaction.txt
new file mode 100644
index 0000000..3ddbca2
--- /dev/null
+++ b/testrun/hsqldb/TestSelfTransaction.txt
@@ -0,0 +1,68 @@
+-- ON DELETE SET NULL

+set property "hsqldb.nio_data_file" false

+set write_delay false;

+set autocommit false;

+drop table testB if exists;

+create cached table testB(id integer, parent integer, ref integer,

+ data varchar(200), unique (id), foreign key (parent)

+ references testB(id) on delete set null);

+/*u1*/insert into testB values(100,100,1,'xxxx');

+/*u1*/insert into testB values(101,100,1,'xxxx');

+/*u1*/insert into testB values(102,100,1,'xxxx');

+/*u1*/insert into testB values(200,200,1,'xxxx');

+commit;

+/*u1*/delete from testB where id=100;

+/*r

+ 101,NULL,1,xxxx

+ 102,NULL,1,xxxx

+ 200,200,1,xxxx

+*/select * from testB order by id

+/*c2*/select * from testB where parent is null

+rollback;

+/*c4*/select * from testB;

+-- ON DELETE SET DEFAULT

+drop table testB if exists;

+create cached table testB(id integer, parent integer default 20, ref integer,

+ data varchar(200), unique (id),foreign key (parent)

+ references testB(id) on delete set default);

+/*u1*/insert into testB values(20,20,1,'xxxx');

+/*u1*/insert into testB values(100,100,1,'xxxx');

+/*u1*/insert into testB values(101,100,1,'xxxx');

+/*u1*/insert into testB values(200,200,1,'xxxx');

+commit;

+/*u1*/delete from testB where id=100;

+/*r

+ 20,20,1,xxxx

+ 101,20,1,xxxx

+ 200,200,1,xxxx

+*/select * from testB order by id

+/*c2*/select * from testB where parent=20

+rollback;

+/*c4*/select * from testB;

+-- CHAINED SELF REFERENCING FK

+-- ON DELETE CASCADE

+drop table testA if exists;

+create cached table testA(a int primary key,b int,

+    foreign key(b) references testA(a) on update cascade on delete cascade);

+insert into testA(a,b) values(1,1);

+insert into testA(a,b) values(2,1);

+insert into testA(a,b) values(3,1);

+insert into testA(a,b) values(4,2);

+insert into testA(a,b) values(5,2);

+insert into testA(a,b) values(6,2);

+insert into testA(a,b) values(7,3);

+insert into testA(a,b) values(8,3);

+insert into testA(a,b) values(9,3);

+commit;

+/*u9*/update testA set a = a+1;

+/*r9*/select count(*) from testA;

+/*r3*/select count(*) from testA where b=4;

+/*u9*/update testA set a = a-1;

+/*r9*/select count(*) from testA;

+/*r0*/select count(*) from testA where b=4;

+/*r3*/select count(*) from testA where b=3;

+/*u1*/delete from testA where a=1;

+/*r0*/select count(*) from testA;

+rollback;

+/*r9*/select count(*) from testA;

+

diff --git a/testrun/hsqldb/TestSelfTriggers.txt b/testrun/hsqldb/TestSelfTriggers.txt
new file mode 100644
index 0000000..0e00e6e
--- /dev/null
+++ b/testrun/hsqldb/TestSelfTriggers.txt
@@ -0,0 +1,52 @@
+drop table testtrig if exists;

+drop table triglog if exists;

+create cached table testtrig(id integer, data varchar(20), updated date);

+create cached table triglog(id integer generated by default as identity, data varchar(20), op varchar(10));

+create trigger trigone after insert on testtrig referencing new row as newrow

+ for each row when (newrow.id >1)

+ insert into triglog values (newrow.id, newrow.data, 'inserted')

+create trigger trigtwo before update on testtrig referencing old row as oldrow new row as newrow

+ for each row when (oldrow.updated is null)

+ set newrow.updated = date'2009-11-01'

+insert into testtrig values(1,'one', null);

+insert into testtrig values(2,'two', date'1999-11-01');

+/*r2,two,inserted*/select * from triglog

+update testtrig set data = data || ' ' || data

+/*r

+ 1,one one,2009-11-01

+ 2,two two,1999-11-01

+*/select * from testtrig

+

+

+create trigger trigthree after delete on testtrig referencing old row as oldrow

+ for each row

+ insert into triglog values oldrow.id, oldrow.data, 'deleted'

+

+delete from testtrig

+/*c2*/select * from triglog where op = 'deleted'

+

+create procedure proc_trig(in in_arg_one varchar(10))

+  language sql parameter style sql deterministic modifies sql data

+    label_one: begin atomic

+        insert into triglog values default, in_arg_one, null;

+     end label_one;

+

+create cached table testtrig2(id integer, data varchar(20), updated date);

+create trigger trigfour after insert on testtrig2 referencing new row as newrow

+ for each row

+ call proc_trig(newrow.data)

+

+insert into testtrig2 values 10, 'felix', current_date

+/*c1*/select * from triglog where data='felix'

+

+delete from testtrig;

+create view vtrig as select id, data, updated, 'fixed string' fixed from testtrig;

+

+create trigger triginstead instead of insert on vtrig

+ referencing new row as newrow

+ for each row

+ insert into testtrig values newrow.id, newrow.data || ' added', newrow.updated - 1 day

+

+insert into vtrig values 10, 'string', current_date, null

+/*c1*/select * from vtrig where data = 'string added';

+/*c1*/select * from testtrig;

diff --git a/testrun/hsqldb/TestSelfTriggers2.txt b/testrun/hsqldb/TestSelfTriggers2.txt
new file mode 100644
index 0000000..af5c03f
--- /dev/null
+++ b/testrun/hsqldb/TestSelfTriggers2.txt
@@ -0,0 +1,54 @@
+--  Testing some advanced trigger functionality

+

+CREATE TABLE log_table (

+    stamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,

+    message VARCHAR(80) NOT NULL,

+ )

+CREATE PROCEDURE record(msg VARCHAR(60))

+    MODIFIES SQL DATA

+    BEGIN ATOMIC

+        INSERT INTO log_table(message) VALUES (msg);

+    END

+CREATE TABLE base_table (

+    id BIGINT generated ALWAYS AS IDENTITY PRIMARY KEY,

+    i INTEGER NOT NULL,

+    vc VARCHAR(600) NOT NULL,

+ )

+

+/*r0*/ SELECT COUNT(*) FROM log_table

+

+CALL record('test record')

+

+/*r1*/ SELECT COUNT(*) FROM log_table

+

+CREATE TRIGGER manual_log_trigger AFTER INSERT ON base_table

+    INSERT INTO log_table(message) VALUES ('totally manual trigger event')

+

+INSERT INTO base_table(i, vc) VALUES(1, 'one')

+

+/*r2*/ SELECT COUNT(*) FROM log_table

+

+CREATE TRIGGER call_log_trigger AFTER INSERT ON base_table

+    CALL record('trigger routine CALL event')

+

+INSERT INTO base_table(i, vc) VALUES(2, 'two')

+

+/*r4*/ SELECT COUNT(*) FROM log_table

+/*r2*/ SELECT COUNT(*) FROM base_table

+

+-- this trigger is called recursively -- WHEN clause avoids infinite recursion

+CREATE TRIGGER extra_ins_trigger_ AFTER INSERT ON base_table

+    REFERENCING NEW as new_row

+    FOR EACH ROW

+    WHEN (MOD(new_row.i,2) = 1)

+        INSERT INTO base_table(i, vc)

+        VALUES(1 + new_row.i, 'TRIG_ADDITION' || new_row.vc)

+

+-- Sanity check to verify that the Trigger creaion didn't change anything

+/*r4*/ SELECT COUNT(*) FROM log_table

+/*r2*/ SELECT COUNT(*) FROM base_table

+

+INSERT INTO base_table(i, vc) VALUES(3, 'x')

+-- Should write 2 base_table entries, hence 4 log records

+/*r8*/ SELECT COUNT(*) FROM log_table

+/*r4*/ SELECT COUNT(*) FROM base_table

diff --git a/testrun/hsqldb/TestSelfTrimSimplified.txt b/testrun/hsqldb/TestSelfTrimSimplified.txt
new file mode 100644
index 0000000..f504755
--- /dev/null
+++ b/testrun/hsqldb/TestSelfTrimSimplified.txt
@@ -0,0 +1,20 @@
+-- TestSelfTrimSimplified.txt

+--

+-- trim looks different

+

+

+drop table testtable if exists;

+create cached table testtable (

+    aString              varchar(256)                   not null,

+    firstNum             integer                        not null,

+    aDate                date                           not null,

+    secondNum            integer                        not null,

+    thirdNum             integer                        not null,

+    aName                varchar(32)                    not null

+  );

+

+insert into TESTTABLE(aString, firstNum, aDate, secondNum, thirdNum, aName)

+  values (' XYZ ', 22, '2003-11-10', 18, 3, 'my name goes here');

+

+select trim(aString) from testtable;

+drop table testtable;

diff --git a/testrun/hsqldb/TestSelfUnions.txt b/testrun/hsqldb/TestSelfUnions.txt
new file mode 100644
index 0000000..3fa5023
--- /dev/null
+++ b/testrun/hsqldb/TestSelfUnions.txt
@@ -0,0 +1,126 @@
+drop table a if exists;

+drop table b if exists;

+drop table c if exists;

+CREATE TABLE A(ID INTEGER NOT NULL)

+CREATE TABLE B(ID INTEGER NOT NULL)

+CREATE TABLE C(ID INTEGER NOT NULL)

+INSERT INTO A VALUES(1)

+INSERT INTO A VALUES(2)

+INSERT INTO A VALUES(3)

+INSERT INTO B VALUES(1)

+INSERT INTO B VALUES(2)

+INSERT INTO C VALUES(3)

+INSERT INTO C VALUES(4)

+INSERT INTO C VALUES(5)

+/*e*/SELECT * FROM A UNION (SELECT * FROM C

+/*e*/SELECT * FROM A UNION SELECT * FROM C)

+/*e*/(SELECT * FROM A UNION (SELECT * FROM C

+/*e*/(SELECT * FROM A

+/*c5*/SELECT * FROM A UNION SELECT * FROM C

+/*c5*/(SELECT * FROM A) UNION SELECT * FROM C

+/*c5*/SELECT * FROM A UNION (SELECT * FROM C)

+/*c5*/(SELECT * FROM A UNION SELECT * FROM C)

+-- limits

+/*c5*/SELECT * FROM A UNION SELECT * FROM C ORDER BY ID

+/*c4*/(SELECT * FROM A ORDER BY ID LIMIT 1 OFFSET 0) UNION SELECT * FROM C

+/*c4*/SELECT * FROM A UNION (SELECT * FROM C ORDER BY ID LIMIT 2 OFFSET 0) LIMIT 4 OFFSET 0

+/*r

+ 2

+ 3

+ 4

+*/SELECT * FROM A UNION (SELECT * FROM C ORDER BY ID LIMIT 2 OFFSET 0)  ORDER BY ID LIMIT 0 OFFSET 1

+/*r

+ 4

+ 3

+ 2

+ 1

+*/SELECT * FROM A UNION (SELECT * FROM C ORDER BY ID LIMIT 2 OFFSET 0) ORDER BY ID DESC

+--

+/*r

+ 4

+ 5

+*/SELECT * FROM A UNION SELECT * FROM C ORDER BY ID LIMIT 2 OFFSET 3

+/*r

+ 3

+*/(SELECT * FROM A UNION SELECT * FROM B) INTERSECT SELECT * FROM C;

+/*r

+ 1

+ 2

+ 3

+ 4

+ 5

+*/SELECT * FROM A UNION (SELECT * FROM B ORDER BY ID DESC LIMIT 10 OFFSET 0) UNION SELECT * FROM C ORDER BY ID;

+--

+/*c3*/SELECT * FROM A UNION SELECT * FROM B

+/*c5*/SELECT * FROM B UNION SELECT * FROM C

+/*c2*/SELECT * FROM A EXCEPT SELECT * FROM C

+/*c2*/(SELECT * FROM A) EXCEPT SELECT * FROM C

+/*c2*/SELECT * FROM A EXCEPT (SELECT * FROM C)

+/*c1*/(SELECT * FROM A INTERSECT SELECT * FROM C)

+/*c2*/SELECT * FROM A INTERSECT (SELECT * FROM B)

+/*c0*/(SELECT * FROM B) INTERSECT SELECT * FROM C

+/*r

+ 1

+ 2

+ 3

+*/SELECT * FROM A UNION SELECT * FROM C INTERSECT SELECT * FROM B

+/*r

+ 1

+ 2

+*/(SELECT * FROM A UNION SELECT * FROM C) INTERSECT SELECT * FROM B

+/*r

+*/SELECT * FROM A EXCEPT SELECT * FROM C EXCEPT SELECT * FROM B

+/*r

+ 3

+*/SELECT * FROM A UNION SELECT * FROM C INTERSECT SELECT * FROM B EXCEPT SELECT * FROM B

+/*r

+ 1

+ 2

+ 3

+*/SELECT * FROM A UNION SELECT * FROM C INTERSECT (SELECT * FROM B EXCEPT SELECT * FROM B)

+CREATE VIEW V1 AS (SELECT * FROM A UNION SELECT * FROM C) INTERSECT SELECT * FROM B

+/*r

+ 1

+ 2

+*/SELECT * FROM V1

+CREATE VIEW V3 AS SELECT * FROM A UNION SELECT * FROM C INTERSECT (SELECT * FROM B EXCEPT SELECT * FROM B)

+/*r

+ 1

+ 2

+ 3

+*/SELECT * FROM V3;

+/*c3*/SELECT * FROM A WHERE ID IN (SELECT * FROM A UNION SELECT * FROM C INTERSECT (SELECT * FROM B EXCEPT SELECT * FROM B))

+/*c3*/SELECT * FROM A WHERE EXISTS (SELECT * FROM A UNION SELECT * FROM C INTERSECT (SELECT * FROM B EXCEPT SELECT * FROM B))

+/*c0*/SELECT * FROM A WHERE EXISTS (SELECT * FROM A EXCEPT SELECT * FROM C EXCEPT SELECT * FROM B)

+--- correlated union

+create table bt1 ( id varchar(10) );

+create table bt2 ( id varchar(10) );

+create table bt3 ( id varchar(10) );

+insert into bt1( id ) values ( 'aaa' );

+insert into bt1( id ) values ( 'bbb' );

+insert into bt1( id ) values ( 'ccc' );

+insert into bt2( id ) values ( 'aaa' );

+insert into bt3( id ) values ( 'bbb' );

+/*U*/ the t1.id reference in the next test is not resolved in some runs - only after code changes result in failure

+/*c1*/select * from bt1 as t1

+ where not exists(

+   select id from bt2 as t2 where t2.id = t1.id

+   union all

+   select id from bt3 as t3 where t3.id = t1.id );

+--- null as column in first select

+create table au (id int, b1 boolean);

+create table bu (id int);

+insert into au values(1,true);

+insert into bu values(2);

+select id, null as b1 from bu union select id, b1 from au;

+--

+drop table test if exists;

+create table test(my_col numeric(10));

+insert into test (my_col) values (100);

+

+select my_col, 0 mycol from test

+ union

+ select 0 mycol2, my_col from test

+

+

+

diff --git a/testrun/hsqldb/TestSelfUserFunction.txt b/testrun/hsqldb/TestSelfUserFunction.txt
new file mode 100644
index 0000000..881c816
--- /dev/null
+++ b/testrun/hsqldb/TestSelfUserFunction.txt
@@ -0,0 +1,29 @@
+--

+-- TestSelfUserFunction.txt

+--

+-- This test checks if the USER() function works correctly when used within

+-- prepared statements such as VIEW's and constraints in TABLE's

+

+-- Setup tables and views

+DROP TABLE USER_PROFILE IF EXISTS

+CREATE TABLE USER_PROFILE(NAME VARCHAR(10), PROFILE INT)

+DROP VIEW USER_SECURITY_PROFILE_VIEW IF EXISTS

+CREATE VIEW USER_SECURITY_PROFILE_VIEW AS SELECT * FROM USER_PROFILE WHERE Name = USER()

+

+-- Create user for test

+CREATE USER MATT PASSWORD MATT ADMIN

+

+-- This checks that you are allowed to insert a row as long as your username matches the NAME field

+/*u1*/ INSERT INTO USER_PROFILE(NAME, PROFILE) VALUES('SA',10)

+

+-- Connect as MATT

+CONNECT USER MATT PASSWORD MATT

+

+-- Insert a row as the connected user

+/*u1*/ INSERT INTO USER_PROFILE(NAME, PROFILE) VALUES('MATT',20)

+

+-- There are two rows in the table but the select should only return the row

+-- associated with the connected user i.e. one row

+/*c1*/ SELECT COUNT(*) FROM USER_SECURITY_PROFILE_VIEW

+SHUTDOWN

+

diff --git a/testrun/hsqldb/TestSelfVerify.txt b/testrun/hsqldb/TestSelfVerify.txt
new file mode 100644
index 0000000..e2d6673
--- /dev/null
+++ b/testrun/hsqldb/TestSelfVerify.txt
@@ -0,0 +1,51 @@
+--

+-- TestSelfVerify.txt

+--

+-- This is part of a three part suite of scripts to test persistence in the same DB

+

+-- Correct handling of index creation for foreign keys

+-- check the consistency of foreign keys and primary keys

+/*e*/create table VEREIN(VCODE CHAR(10) not null);

+/*e*/create table BEWERB(VCODE CHAR(10) not null, ID SMALLINT not null);

+/*e*/create unique index BEWERB_FK1 on BEWERB(VCODE);

+/*e*/alter table BEWERB add constraint bv foreign key (VCODE) references VEREIN (VCODE);

+

+--  fails as a uique indexes on verein and bewerb exist

+/*e*/create unique index VEREIN_PK on VEREIN (VCODE);

+/*e*/create unique index BEWERB_FK2 on BEWERB(ID);

+

+-- null value in not null column

+/*e*/insert into verein values (null);

+-- referential no matching row

+/*e*/insert into bewerb values ('aaaaaaa',18);

+-- duplicate row

+/*e*/insert into bewerb values ('hijklmn',7);

+-- referential integrity row has reference

+/*e*/delete from verein where vcode='opqrstu'

+

+--test identity increment

+INSERT INTO APP2 (VALUE) VALUES(13);

+INSERT INTO APP2 (VALUE) VALUES(14);

+

+/*r5,14*/ SELECT COUNT(ID), MAX(VALUE) FROM APP2

+

+--test persistence of insert into operations

+/*c2*/SELECT * FROM NEWAPP WHERE APP_NAME = 'Eran';

+/*c2*/SELECT * FROM NEWAPP WHERE APP_NAME = 'Shelly';

+/*c4*/SELECT * FROM NEWAPP;

+

+--test correct persistent of view defined in TestSelfCreate.txt

+/*r

+  14,newdir,NULL

+*/select * from "View"

+

+/*r

+  14,newdir,NULL

+*/select * from "View2"

+

+--test INSERT .. INTO and indexes

+create cached table bewerb_copy  as (select * from bewerb) with data;

+create index idx_bewerb_copy on bewerb_copy(VCODE,ID);

+

+/*u0*/SHUTDOWN;

+

diff --git a/testrun/hsqldb/TestSelfViewGrants.txt b/testrun/hsqldb/TestSelfViewGrants.txt
new file mode 100644
index 0000000..7ab7ae7
--- /dev/null
+++ b/testrun/hsqldb/TestSelfViewGrants.txt
@@ -0,0 +1,59 @@
+-- $Id: TestSelfViewGrants.txt 610 2008-12-22 15:54:18Z unsaved $

+-- Tests viw grants

+

+-- These two users are for sanity tests

+/*u0*/CREATE USER privd PASSWORD "privd";

+/*u0*/CREATE USER unprivd PASSWORD "unprivd";

+/*u0*/CREATE USER u1 PASSWORD "u1";

+/*u0*/GRANT CHANGE_AUTHORIZATION TO privd;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO unprivd;

+/*u0*/GRANT CHANGE_AUTHORIZATION TO u1;

+-- rtable = restricted table

+/*u0*/CREATE TABLE rtable (c1 int, c2 int, c3 int);

+/*u1*/INSERT INTO rtable values (1, 2, 3);

+/*c1*/SELECT * from rtable;

+/*u0*/CREATE VIEW v as SELECT c1, c2 FROM rtable;

+/*c1*/SELECT * from v;

+/*u0*/GRANT ALL ON v TO privd;

+/*u0*/GRANT SELECT ON v TO privd;

+/*u0*/GRANT SELECT(c1) ON v TO u1;

+

+

+-- Test col-specific SELECTs

+/*u0*/CONNECT USER u1 PASSWORD "u1";

+/*e*/SELECT c1 from rtable;

+/*e*/SELECT c2 from rtable;

+/*e*/SELECT c3 from rtable;

+/*e*/SELECT c2 from v;

+/*c1*/SELECT c1 from v;

+COMMIT;

+/*u0*/CONNECT USER privd PASSWORD "privd";

+/*e*/SELECT c1 from rtable;

+/*e*/SELECT c2 from rtable;

+/*e*/SELECT c3 from rtable;

+-- The following tests that View grants supercede restrictions on underlying

+-- tables.  (For grants on entire View, not View columns).

+/*c1*/SELECT c2 from v;

+/*c1*/SELECT c1 from v;

+COMMIT;

+/*u0*/CONNECT USER unprivd PASSWORD "unprivd";

+/*e*/SELECT c1 from rtable;

+/*e*/SELECT c2 from rtable;

+/*e*/SELECT c3 from rtable;

+/*e*/SELECT c2 from v;

+/*e*/SELECT c1 from v;

+COMMIT;

+/*u0*/CONNECT USER SA PASSWORD "";

+-- Exactly according to "SQL 1999" section 14.3.7:

+/*u0*/GRANT SELECT ON v TO PUBLIC;

+/*u0*/CONNECT USER unprivd PASSWORD "unprivd";

+/*c1*/SELECT c2 from v;

+/*c1*/SELECT c1 from v;

+COMMIT;

+/*u0*/CONNECT USER SA PASSWORD "";

+/*u0*/DROP USER u1;

+/*u0*/DROP USER privd;

+/*u0*/DROP USER unprivd;

+/*u0*/DROP VIEW v;

+/*u0*/DROP TABLE rtable;

+/*u0*/SHUTDOWN;

diff --git a/testrun/hsqldb/TestSelfViewSchemaResolve.txt b/testrun/hsqldb/TestSelfViewSchemaResolve.txt
new file mode 100644
index 0000000..d73d55f
--- /dev/null
+++ b/testrun/hsqldb/TestSelfViewSchemaResolve.txt
@@ -0,0 +1,96 @@
+/*s*/DROP SCHEMA alts CASCADE;

+CREATE SCHEMA alts AUTHORIZATION dba;

+DROP VIEW v1 IF EXISTS;

+DROP VIEW v2 IF EXISTS;

+DROP VIEW v3 IF EXISTS;

+DROP VIEW v4 IF EXISTS;

+DROP VIEW v5 IF EXISTS;

+DROP VIEW v6 IF EXISTS;

+DROP VIEW v7 IF EXISTS;

+DROP VIEW v8 IF EXISTS;

+DROP TABLE t1 IF EXISTS;

+DROP TABLE t2 IF EXISTS;

+DROP TABLE t3 IF EXISTS;

+DROP TABLE t4 IF EXISTS;

+CREATE TABLE t1(t1c1 int, t1c2 int);

+CREATE TABLE t2(t2c1 int, t2c2 int);

+CREATE TABLE t3(c1 int, c2 int);

+CREATE TABLE t4(c1 int, c2 int);

+/*u1*/INSERT INTO t1 VALUES(1, 11);

+/*u1*/INSERT INTO t2 VALUES(2, 12);

+/*u1*/INSERT INTO t3 VALUES(3, 13);

+/*u1*/INSERT INTO t4 VALUES(4, 14);

+

+/*u0*/CREATE VIEW public.v1 AS SELECT * FROM t1;

+/*u0*/CREATE VIEW public.v2 AS SELECT * FROM t2;

+/*u0*/CREATE VIEW public.v3 AS SELECT * FROM t3;

+/*u0*/CREATE VIEW public.v4 AS SELECT * FROM t4;

+/*u0*/CREATE VIEW public.v5 (vc1, vc2) AS SELECT * FROM t1;

+/*u0*/CREATE VIEW public.v6 (vc1, vc2) AS SELECT * FROM t2;

+/*u0*/CREATE VIEW public.v7 (vc1, vc2) AS SELECT * FROM t3;

+/*u0*/CREATE VIEW public.v8 (vc1, vc2) AS SELECT * FROM t4;

+

+/*r1,11*/SELECT t1c1, t1c2 FROM v1;

+/*r2,12*/SELECT t2c1, t2c2 FROM v2;

+/*r3,13*/SELECT c1, c2 FROM v3;

+/*r4,14*/SELECT c1, c2 FROM v4;

+/*r1,11*/SELECT vc1, vc2 FROM v5;

+/*r2,12*/SELECT vc1, vc2 FROM v6;

+/*r3,13*/SELECT vc1, vc2 FROM v7;

+/*r4,14*/SELECT vc1, vc2 FROM v8;

+

+SET SCHEMA alts;

+/*e*/SELECT t1c1, t1c2 FROM v1;

+/*e*/SELECT t2c1, t2c2 FROM v2;

+/*e*/SELECT c1, c2 FROM v3;

+/*e*/SELECT c1, c2 FROM v4;

+/*e*/SELECT vc1, vc2 FROM v5;

+/*e*/SELECT vc1, vc2 FROM v6;

+/*e*/SELECT vc1, vc2 FROM v7;

+/*e*/SELECT vc1, vc2 FROM v8;

+/*r1,11*/SELECT t1c1, t1c2 FROM public.v1;

+/*r2,12*/SELECT t2c1, t2c2 FROM public.v2;

+/*r3,13*/SELECT c1, c2 FROM public.v3;

+/*r4,14*/SELECT c1, c2 FROM public.v4;

+/*r1,11*/SELECT vc1, vc2 FROM public.v5;

+/*r2,12*/SELECT vc1, vc2 FROM public.v6;

+/*r3,13*/SELECT vc1, vc2 FROM public.v7;

+/*r4,14*/SELECT vc1, vc2 FROM public.v8;

+CREATE INDEX i1 ON public.t1(t1c1);

+CREATE INDEX i2 ON public.t2(t2c1);

+CREATE INDEX i3 ON public.t3(c1);

+CREATE INDEX i4 ON public.t4(c1);

+/*e*/SELECT t1c1, t1c2 FROM v1;

+/*e*/SELECT t2c1, t2c2 FROM v2;

+/*e*/SELECT c1, c2 FROM v3;

+/*e*/SELECT c1, c2 FROM v4;

+/*e*/SELECT vc1, vc2 FROM v5;

+/*e*/SELECT vc1, vc2 FROM v6;

+/*e*/SELECT vc1, vc2 FROM v7;

+/*e*/SELECT vc1, vc2 FROM v8;

+/*r1,11*/SELECT t1c1, t1c2 FROM public.v1;

+/*r2,12*/SELECT t2c1, t2c2 FROM public.v2;

+/*r3,13*/SELECT c1, c2 FROM public.v3;

+/*r4,14*/SELECT c1, c2 FROM public.v4;

+/*r1,11*/SELECT vc1, vc2 FROM public.v5;

+/*r2,12*/SELECT vc1, vc2 FROM public.v6;

+/*r3,13*/SELECT vc1, vc2 FROM public.v7;

+/*r4,14*/SELECT vc1, vc2 FROM public.v8;

+

+SET SCHEMA alts;

+/*e*/SELECT t1c1, t1c2 FROM v1;

+/*e*/SELECT t2c1, t2c2 FROM v2;

+/*e*/SELECT c1, c2 FROM v3;

+/*e*/SELECT c1, c2 FROM v4;

+/*e*/SELECT vc1, vc2 FROM v5;

+/*e*/SELECT vc1, vc2 FROM v6;

+/*e*/SELECT vc1, vc2 FROM v7;

+/*e*/SELECT vc1, vc2 FROM v8;

+/*r1,11*/SELECT t1c1, t1c2 FROM public.v1;

+/*r2,12*/SELECT t2c1, t2c2 FROM public.v2;

+/*r3,13*/SELECT c1, c2 FROM public.v3;

+/*r4,14*/SELECT c1, c2 FROM public.v4;

+/*r1,11*/SELECT vc1, vc2 FROM public.v5;

+/*r2,12*/SELECT vc1, vc2 FROM public.v6;

+/*r3,13*/SELECT vc1, vc2 FROM public.v7;

+/*r4,14*/SELECT vc1, vc2 FROM public.v8;

diff --git a/testrun/hsqldb/TestSelfViews.txt b/testrun/hsqldb/TestSelfViews.txt
new file mode 100644
index 0000000..cf88234
--- /dev/null
+++ b/testrun/hsqldb/TestSelfViews.txt
@@ -0,0 +1,46 @@
+drop view v_my_server if exists;

+drop table my_group if exists;

+drop table dual if exists;

+drop table my_server if exists;

+-- test subselect in view

+create cached table my_group (id integer, group_id integer);

+insert into my_group values (1, 1);

+insert into my_group values (2, 1);

+insert into my_group values (3, 1);

+insert into my_group values (4, 1);

+create cached table dual (a integer);

+insert into dual values (0);

+create cached table my_server (group_id integer, server_id integer, weight integer);

+insert into my_server values (-1, 1, 1);

+insert into my_server values (-1, 2, 0);

+insert into my_server values (100, 11, 1);

+--

+CREATE VIEW v_my_server AS SELECT DISTINCT mg.id, ms.server_id, ms.weight

+ FROM (SELECT id, group_id FROM my_group

+ UNION SELECT -1, -1 FROM DUAL) mg, my_server ms

+ WHERE mg.group_id = ms.group_id;

+--

+/*c2*/select * from v_my_server;

+/*c2*/select * from (select * from v_my_server);

+-- test view in view

+drop view v_test_view if exists;

+CREATE VIEW v_test_view AS SELECT a.id, b.server_id, b.weight FROM v_my_server a JOIN v_my_server b ON a.id = b.id;

+/*c4*/select * from v_test_view;

+/*c4*/select * from (select * from v_test_view);

+--

+drop table colors if exists;

+create table colors(id int, val char(10));

+insert into colors values(1,'red');

+insert into colors values(2,'green');

+insert into colors values(3,'orange');

+insert into colors values(4,'indigo');

+--

+drop view v_colors if exists;

+create view v_colors(vid, vval) as select id, val from colors;

+create view v_colors_o(vid, vval) as select id, val from colors order by id desc;

+create view v_colors_o_l(vid, vval) as select id, val from colors order by id desc limit 1 offset 0;

+create view v_colors_o_l_x(vid, vval) as select id, val from colors limit 1 offset 0;

+/*e*/create view v_colors_o_l_x(vid, vval) as select id, val into newtable from colors;

+--

+/*c4*/select * from v_colors join v_test_view on server_id=vid;

+/*c2*/select distinct * from v_test_view join v_colors on server_id=vid;

diff --git a/testrun/hsqldb/TestText01.txt b/testrun/hsqldb/TestText01.txt
new file mode 100644
index 0000000..aa144a5
--- /dev/null
+++ b/testrun/hsqldb/TestText01.txt
@@ -0,0 +1,35 @@
+-- all_quoted

+drop table tmain if exists;

+create table tmain(c1 varchar(10),i1 integer, c2 varchar(10));

+insert into tmain values(null, null, null);

+insert into tmain values('aval1', null, 'aval2');

+drop table t if exists;

+create text table t(c1 varchar(10),i1 integer, c2 varchar(10));

+set table t source "t.txt; all_quoted=true;ignore_first=true";

+set table t source header """charcol_1"",""intcol"",""charcol_2""";

+insert into t select * from tmain;

+-- unquoted

+create table ttmain(doublequote char(10), singlequote char(10));

+insert into ttmain values('noquoteA', 'noquoteB');

+insert into ttmain values('"inch','''foot');

+insert into ttmain values('_""_','_''''_' );

+insert into ttmain values('"quoted"','''quoted''');

+insert into ttmain values('inch"','foot''');

+insert into ttmain values('"inch"','''foot''');

+create text table tt(doubquote char(10), singquote char(10));

+set table tt source "tt.txt;quoted=false;fs=\t;ignore_first=true";

+set table tt source header "DOUBQUOTE,SINGQUOTE";

+insert into tt select * from ttmain;

+-- identity test

+drop table tident if exists;

+create text table tident(c1 int generated by default as identity, c2 varchar(20));

+set table tident source "ttt.txt; all_quoted=true;ignore_first=true";

+set table tident source header """IDENT"",""VAL""";

+-- single column test

+drop table tsingle if exists;

+create text table tsingle(c1 int);

+set table tsingle source "tttt.txt;ignore_first=true";

+set table tsingle source header 'full history';

+

+

+

diff --git a/testrun/hsqldb/TestText02.txt b/testrun/hsqldb/TestText02.txt
new file mode 100644
index 0000000..3098712
--- /dev/null
+++ b/testrun/hsqldb/TestText02.txt
@@ -0,0 +1,6 @@
+/*c2*/SELECT * FROM TMAIN;

+/*c0*/SELECT * FROM TMAIN EXCEPT SELECT * FROM T;

+/*c0*/SELECT * FROM T EXCEPT SELECT * FROM TMAIN;

+/*c6*/SELECT * FROM TTMAIN;

+/*c0*/SELECT * FROM TT EXCEPT SELECT * FROM TTMAIN;

+/*c0*/SELECT * FROM TTMAIN EXCEPT SELECT * FROM TT;

diff --git a/testrun/hsqldb/TestTriggers.txt b/testrun/hsqldb/TestTriggers.txt
new file mode 100644
index 0000000..fa112e2
--- /dev/null
+++ b/testrun/hsqldb/TestTriggers.txt
@@ -0,0 +1,29 @@
+drop table testtrig if exists;

+create cached table testtrig(c1 integer generated by default as identity, c2 varchar(40), c3 integer);

+create trigger tbir before insert on testtrig referencing new row as newrow

+ for each row when (c2 is not null)

+ call "org.hsqldb.test.TriggerClass";

+create trigger tair after insert on testtrig referencing new row as newrow

+ for each row when (c2 is not null)

+ call "org.hsqldb.test.TriggerClass";

+create trigger tais after insert on testtrig

+ for each statement

+ call "org.hsqldb.test.TriggerClass";

+create trigger tbur before update of c1, c2, c3 on testtrig referencing new row as newrow

+ for each row when (c2 is not null)

+ call "org.hsqldb.test.TriggerClass";

+create trigger taur after update on testtrig referencing new row as newrow

+ for each row when (c2 is not null)

+ call "org.hsqldb.test.TriggerClass";

+create trigger taus after update on testtrig

+ for each statement

+ call "org.hsqldb.test.TriggerClass";

+create trigger tbdr before delete on testtrig referencing old row as oldrow

+ for each row when (c2 is not null)

+ call "org.hsqldb.test.TriggerClass";

+create trigger tadr after delete on testtrig referencing old row as oldrow

+ for each row when (c2 is not null)

+ call "org.hsqldb.test.TriggerClass";

+create trigger tads after delete on testtrig

+ for each statement

+ call "org.hsqldb.test.TriggerClass";

diff --git a/testrun/hsqlodbc/blobtest.py b/testrun/hsqlodbc/blobtest.py
new file mode 100755
index 0000000..0b118ec
--- /dev/null
+++ b/testrun/hsqlodbc/blobtest.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python -t
+
+# $Id: blobtest.py 2895 2009-03-07 19:34:26Z unsaved $
+
+# Test BLOB transactions through the ODBC driver.
+# Can't perform these tests with our Java unit tests, since Sun's jdbc:odbc
+# driver does not support BLOB or CLOB type.
+
+# N.b. there is some dependency or bug which requires pyodbc to use the
+# ANSI variant of the HyperSQL ODBC Driver.  Using the normal Unicode
+# variant will generate the following error message when you try to connect:
+#    pyodbc.Error: ('0', '[0] [unixODBC]c (202) (SQLDriverConnectW)')
+# It is quite possible that this issue will be taken care of when we fix a
+# high-priority bug to do with switching between SQLDriverConnect and
+# SQLDriverConnectW on UNIX.
+
+# Author:  Blaine Simpson  (blaine dot simpson at admc dot com)
+
+import pyodbc
+
+conn = pyodbc.connect("DSN=tstdsn-a")
+try:
+    conn.autocommit = 0
+
+    cursor = conn.cursor();
+
+    cursor.execute("DROP TABLE tsttbl IF EXISTS");
+
+    cursor.execute(
+        "CREATE TABLE tsttbl(\n"
+        + "    id BIGINT generated BY DEFAULT AS IDENTITY,\n"
+        + "    vc BLOB(20),\n"
+        + "    entrytime TIMESTAMP DEFAULT current_timestamp NOT NULL\n"
+        + ")");
+
+    # First a simple/non-parameterized Insertion
+    #retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (1, 'one')");
+    #if retval != 1:
+        #raise Exception(('1st insertion inserted ' + repr(retval)
+            #+ ' rows instead of 1'))
+    # Now parameterized.  Unfortunately, the Python DB API and pyodbc API do
+    # not allow re-use of a parsed statement.  Cursor must be reparsed for
+    # each usage.
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)",
+            2, 'two');
+    if retval != 1:
+        raise Exception(('2nd insertion inserted ' + repr(retval)
+            + ' rows instead of 2'))
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)",
+            3, 'three');
+    if retval != 1:
+        raise Exception(('3rd insertion inserted ' + repr(retval)
+            + ' rows instead of 3'))
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)",
+            4, 'four');
+    if retval != 1:
+        raise Exception(('4th insertion inserted ' + repr(retval)
+            + ' rows instead of 4'))
+    retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)",
+            5, 'five');
+    if retval != 1:
+        raise Exception(('5th insertion inserted ' + repr(retval)
+            + ' rows instead of 5'))
+    conn.commit();
+
+    # Non-parameterized query
+    for row in cursor.execute(
+            "SELECT * FROM tsttbl WHERE id < 3"):
+        print row
+
+    # Non-parameterized query.  As noted above, can't re-use parsed cursor.
+    for row in cursor.execute(
+            "SELECT * FROM tsttbl WHERE id > ?", 3):
+        # For variety, we format the files ourselves this time
+        print repr(row.ID) + '|' + row.VC + '|' + repr(row.ENTRYTIME)
+
+except Exception as e:
+    conn.rollback();
+    raise e
+
+finally:
+    conn.close();
diff --git a/testrun/sqltool/README.txt b/testrun/sqltool/README.txt
new file mode 100644
index 0000000..0af579b
--- /dev/null
+++ b/testrun/sqltool/README.txt
@@ -0,0 +1,160 @@
+$Id: README.txt 842 2009-01-19 02:56:05Z unsaved $

+

+SqlTool Unit Tests

+since:  HSQLDB 1.8.0.8

+author:  Blaine Simpson (unsaved@users.sourceforge.net)

+

+************************************************************

+Sun Jan 18 21:52:58 EST 2009

+The dsv-constcols.sql and dsv-trimming.sql unit tests are failing

+now, due to known issues with the inability to apply DST (Daylight

+Savings Time) offsets to JDBC DATE objects.

+************************************************************

+

+

+PORTABILITY (or lack thereof)

+

+    At this time, you need to have a Bash shell to run this script, so you'll

+    need a UNIX variant, Cygwin, etc.

+    When I have time, I'll port the test runner script "runtests.bash" to 

+    Java so that the tests will run on any Java platform.

+    If you have time and the Java skills to port it now-- please contact 

+    me ASAP:  blaine.simpson@admc.com

+    (BTW, it will take considerable effort to just port the existing

+    behavior from Bash to Perl, but the real difficultiy would be to

+    improve the run-time by not invoking a new JVM for each test run.

+    Specifically, Java uses a very closed design for providing stdin,

+    stdout, stderr, and one can't open and close these pipes at will, as

+    we do in the Bash script).

+

+

+HOW TO RUN

+

+    Typical usage (executes all tests):

+

+        cd .../testrun/sqltool

+        ./runtests.bash

+

+    Run tests on any SQL files:

+

+        .../testrun/sqltool/runtests.bash file1.sql file2.sql...

+

+    If there are any test failures, the failed SQL scripts will be listed

+    at the end of the results.  To get details about the failure, run

+    runtests.bash with just one of the failed SQL scripts at a time, and

+    with the Verbose option, like

+

+        ./runtests.bash -v failedscript.sql

+

+    To see all available invocation methods:

+

+        ./runtests.bash -h

+

+

+FILE NAMING AND ASCII/BINARY CONVENTIONS

+

+    You can name SQL scripts anything that you want, except that the

+    filename suffixes ".nsql"  and ".inter" are reserved for negative

+    and interactive SQL scripts, correspondingly (see the next section

+    about that).

+

+    If you plan to run runtests.bash with no filename arguments, it

+    will execute all *.sql, *.nsql, an d*.inter scripts in the current

+    directory.

+    So, if you plan to run runtests.bash this way, you must take care

+    to name only scripts **which you want executed at the top level**

+    with extensions sql, nsql, inter.  By "at the top level", I mean

+    that if you are nesting SQL scripts with the \i command, you can't 

+    name the nested script with suffix .sql, .nsql, or .inter or the

+    script will accidentally be executed directly when you run

+    runtests.bash without script arguments.  It's a simple concept, but,

+    as you can see, it's a little difficult to explain, so here's an

+    example.

+

+    You have a script name "top.sql" which contains

+

+         \i nested.sql

+

+    You can run "./runtests.bash top.sql" and everything will work

+    fine-- runtests.bash will execute "top.sql" which will nest

+    "nested.sql".  But if you run just "./runtests.bash",

+    runtests.bash will run "top.bash", which will nest "nested.bash"

+    just like before, but runtests.bash will also execute

+    "nested.bash" directly, since it executes all files with extensions

+    sql and nsql (and inter).  Just use any filename suffix other than

+    .sql, .nsql, and .inter for your nested SQL scripts and everything

+    will work fine.

+

+    If you are a HSQLDB developer and will be committing test scripts,

+    then please use the following filename and type conventions:

+

+        purpose                 suffix  filetype

+        --------------------    ------  ----------------------------

+        top-level SQL script    .sql    ASCII (mime-type text/plain)

+        top-level neg. SQL      .nsql   ASCII (mime-type text/plain)

+        interactive SQL script  .inter  ASCII (mime-type text/plain)

+        nested \i SQL script    .isql   ASCII (mime-type text/plain)

+        delimiter-sep-values    .dsv    Binary (no mime-type)

+

+    If you will be adding new files to HSQLDB, please configure these

+    extensions in for CVS or Subversion client accordingly.

+

+

+    FINE POINT JUSTIFYING Binary TYPE FOR DSV FILES

+

+        (Only read if you give a damned).

+        The reason we're storing DSV files as binaries is because if 

+        CVS or Subversion saved them as ASCII, the line delimiters would

+        be determined by the platform performing the check-out, and 

+        imports would fail if the computer executing nested.bash happened 

+        to be of different EOL type from the computer that checked out.

+        (This would be the case any time that somebody built a 

+        distributable of any type which includes the .dsv files).

+

+

+NEGATIVE TESTS

+

+    runtests.bash determines if a test script succeeds by checking if

+    the exit status of SqlTool is zero.  But we also need to test that

+    scripts fail out when they should.  I.e., we need to verify that if

+    \c (continue-on-error) is false, and there is a syntax error, or

+    a runtime SQL failure, that SqlTool exits with non-zero exit status,

+    as it should.  For this, I have invented the convention that SQL

+    scripts named with suffix ".nsql" are just like normal SQL files,

+    except that they are expected to fail.

+

+    Here's an example to confirm that you understand.

+

+        ./runtests.bash 1.sql 2.sql 3.nsql 4.nsql 5.sql

+

+    This test run will report test failures for 1.sql, 2.sql, and 5.sql

+    only if SqlTool fails when executing them.  It will report test

+    failures for 3.nsql and 4.nsql only if SqlTool succeeds when 

+    executing them.  I.e., runtests.bash _expects_ SqlTool to fail 

+    when executing *.nsql files.

+

+    Negative test scripts should be small and should fail out as

+    early as possible.  The reason for this is that if there is an

+    accidental error before the point of your test, the script will

+    fail out early providing a false negative SqlTool exit code,

+    thereby silently missing your test completely.

+

+

+INTERACTIVE TESTS

+

+    Interactive test are invoked like

+

+        java... SqlTool... mem < scriptname.inter

+

+    in order to test interactive ":" commands.  The : commands are

+    disabled if an SQL script path(s) is given directly as an SqlTool

+    parameter.  I.e., SqlTool runs non-interactively if an SQL script

+    path is given as a pareter; therefore, to test interactive

+    commands, we invoke SqlTool without a script name, and instead

+    pipe the script into SqlTool as stdin.  (Using script name of

+    "-" would do the reverse, it would run in interactive mode even

+    though getting input from stdin).

+

+    Remember to put "\c false" at the top of your interacive scripts,

+    or errors will be ignored.  Account for this command when counting

+    command numbers in the command history.

diff --git a/testrun/sqltool/adv-comments.sql b/testrun/sqltool/adv-comments.sql
new file mode 100644
index 0000000..959a313
--- /dev/null
+++ b/testrun/sqltool/adv-comments.sql
@@ -0,0 +1,27 @@
+/* The tests in this file don't succeed with SqlTool as it is now due to:
+ *   Improper handling of traditional-comments inside single-line comment.
+ *   Improper handling of single-line comments inside traditional comment.
+ *   Inability to recognize SQL commands on lines which don't end with ;\s*$.
+ */
+
+/* Repeat with text right up to edges/* /*on one*/ /*line*/
+    /*Same thing/* /*with leading*/ /*+ trailing white space*/   
+
+
+CREATE TABLE t(i int);
+INSERT INTO t VALUES(1);
+INSERT INTO t VALUES(2);
+
+SELECT * FROM t;  -- single-line SQL-trailing comment
+* if (*? != 2)
+    \q Hyphen-hyphen trailing SQL failed
+* end if
+SELECT * FROM t;  /* traditional SQL-trailing comment */
+* if (*? != 2)
+    \q Traditional trailing SQL failed
+* end if
+
+SELECT * FROM t;  /* Something -- single-line SQL-trailing comment */
+* if (*? != 2)
+    \q Hyphen-hyphen trailing SQL failed
+* end if
diff --git a/testrun/sqltool/altspace.targtbl.dsv b/testrun/sqltool/altspace.targtbl.dsv
new file mode 100644
index 0000000..689a47e
--- /dev/null
+++ b/testrun/sqltool/altspace.targtbl.dsv
@@ -0,0 +1,3 @@
+i|vc
+11|eleven
+12|twelve
diff --git a/testrun/sqltool/append.inter b/testrun/sqltool/append.inter
new file mode 100644
index 0000000..6a1523d
--- /dev/null
+++ b/testrun/sqltool/append.inter
@@ -0,0 +1,60 @@
+/*
+ * $Id: append.inter 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests interactive commands :a*.
+ */
+
+\c false
+/* Since running interactively, need to either invoke with --abortOnErr switch,
+ * or use "\c false" Special command, to detect failures. */
+
+CREATE TABLE t(id INTEGER GENERATED BY DEFAULT AS IDENTITY, vc VARCHAR(80));
+INSERT INTO t (vc) VALUES('a');
+INSERT INTO t (vc) VALUES('b');
+INSERT INTO t (vc) VALUES('c');
+INSERT INTO t (vc) VALUES('b');
+
+SELECT count(*) FROM t
+*if (*? != 4)
+    \q Sanity check failed / 1
+*end if
+
+SELECT count(*) FROM t WHERE vc = 'b';
+*if (*? != 2)
+    \q Sanity check failed / 2
+*end if
+
+INSERT INTO t(vc) VALUES
+
+:a ('prefpost');
+
+SELECT count(*) FROM t
+*if (*? != 5)
+    \q Append + repl failed / 1
+*end if
+
+SELECT vc FROM t;
+SELECT count(*) FROM t WHERE vc = 'prefpost';
+*if (*? != 1)
+    \q Append + repl failed / 2
+*end if
+
+SELECT count(*) FROM t;
+
+\p Intervening command making previous become command # -2.
+:h
+:-2a WHERE vc = 'b';
+
+*if (*? != 2)
+    \q Recall + Append + exec failed / 1
+*end if
+
+:-1
+:a AND
+ id
+= 1
+
+:;
+*if (*? != 1)
+    \q Recall + multi-line Append failed / 1
+*end if
diff --git a/testrun/sqltool/badsqlonly.nsql b/testrun/sqltool/badsqlonly.nsql
new file mode 100644
index 0000000..4a66c49
--- /dev/null
+++ b/testrun/sqltool/badsqlonly.nsql
@@ -0,0 +1,10 @@
+/*
+ * $Id: badsqlonly.nsql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Simplest test possible.  Does absolutely nothing.
+ */
+
+/** Intentional SQL syntax error here */
+CREATE FABLE t(i INTEGER);
+
+\p Should never reach here.
diff --git a/testrun/sqltool/comments.sql b/testrun/sqltool/comments.sql
new file mode 100644
index 0000000..aaa91f0
--- /dev/null
+++ b/testrun/sqltool/comments.sql
@@ -0,0 +1,125 @@
+/*
+ * $Id: comments.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests comments.  This comment itself is a multi-line comment
+ */
+
+/* Just to have a work table */
+CREATE TABLE t(i int);
+
+  /* A multi-line
+  comment  with
+  leading + trailing white space. */  
+
+/*Repeat with text right up to edges.
+ *
+ * Tests comments.  This comment itself is a multi-line comment*/
+
+  /*Repeat with text right up to edges.
+  comment  with
+  leading + trailing white space. */
+
+/* Following line contains spaces */
+           
+
+/* Simple hyphen-hyphen comments */
+-- blah
+  -- blah
+
+/* Empty and white space comments: */
+/**/
+/*****/
+/*** Extra stars ***/
+  /*** Extra stars ***/   
+   /**************/
+---- Extra slashes
+  ---- Extra slashes  
+    ----------------------
+/*  */
+  /**/  
+  /*  */
+/* The second of each of the following pairs have trailing white space.
+--
+--  
+  --
+  --  
+
+/* Comments trailing SQL */
+INSERT INTO t VALUES (9);
+
+/* Simple SQL-embedded traditional comments */
+SELECT * FROM  /* A simple traditional comment */ t;
+* if (*? != 9)
+    \q Hyphen-hyphen trailing SQL failed
+* end if
+SELECT * FROM  /* A simple traditional
+comment */ t;
+* if (*? != 9)
+    \q Hyphen-hyphen trailing SQL failed
+* end if
+SELECT * FROM  -- A simple single-line comment
+t;
+* if (*? != 9)
+    \q Hyphen-hyphen trailing SQL failed
+* end if
+SELECT * FROM  -- Two simple single-line
+-- comments
+t;
+* if (*? != 9)
+    \q Hyphen-hyphen trailing SQL failed
+* end if
+SELECT * FROM  -- Two simple single-line
+  -- comments.  With leading white space
+  t;
+* if (*? != 9)
+    \q Hyphen-hyphen trailing SQL failed
+* end if
+
+/* Nesting different comments inside one another */
+/* -- The traditional comment should still close. */
+SELECT * FROM  /* Something -- single-line SQL-trailing comment */ t;
+* if (*? != 9)
+    \q Hyphen-hyphen trailing SQL failed
+* end if
+
+/* Sanity check */
+* V1 = one
+* if (*V1 != one)
+  \q Failed sanity check for simple variable test
+* end if
+
+/* Test single-line within PL command */
+* V2 = alpha--some crap
+* if (*V2 != alpha)
+  \q Failed single-line within PL command
+* end if
+
+/* Test traditional within PL command */
+* V3 = gamma/*some crap*/
+* if (*V3 != gamma)
+  \q Failed traditional within PL command
+* end if
+
+/* Test multiple traditionals within PL command */
+* V4 = de/*some crap*/l/*more*/ta
+* if (*V4 != delta)
+  \q Failed multiple traditional within PL command
+* end if
+
+/* Test single-line within PL command */
+* V5 = alpha--some crap /* with nested traditional */ there
+* if (*V5 != alpha)
+  \q Failed single-line within PL w/ nesting+trailing failed
+* end if
+
+/* Test single-line within PL command */
+* V6 = alpha--some crap /* with nested traditional */
+* if (*V6 != alpha)
+  \q Failed single-line within PL w/ nesting failed
+* end if
+
+/* Test single-line within PL command */
+* V7 = alpha--some crap /* with nested traditional
+* if (*V6 != alpha)
+  \q Failed single-line within PL w/ unclosed nesting failed
+* end if
diff --git a/testrun/sqltool/dsv-abortcommits.sql b/testrun/sqltool/dsv-abortcommits.sql
new file mode 100644
index 0000000..dfb8a34
--- /dev/null
+++ b/testrun/sqltool/dsv-abortcommits.sql
@@ -0,0 +1,50 @@
+/*
+ * $Id: dsv-abortcommits.sql 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests proper commit behavior upon DSV abortion
+ */
+
+CREATE TABLE t (i INT, r REAL, d DATE, t TIMESTAMP, v VARCHAR(80), b BOOLEAN);
+
+\c true
+
+\a true
+\m dsv-rejects.dsv
+SELECT COUNT(*) FROM t;
+*if (*? != 1)
+    \q Should have imported 1 good DSV records, but imported *{?} (1)
+*end if
+ROLLBACK;
+SELECT COUNT(*) FROM t;
+*if (*? != 1)
+    \q Should have retained 1 DSV record after ROLLBACK w/autocommit, but retained *{?}
+*end if
+
+-- Now with auto-commit off
+\a false
+DELETE FROM t;
+COMMIT;
+\m dsv-rejects.dsv
+SELECT COUNT(*) FROM t;
+*if (*? != 1)
+    \q Should have imported 1 good DSV records, but imported *{?} (2)
+*end if
+ROLLBACK;
+SELECT COUNT(*) FROM t;
+*if (*? != 0)
+    \q Should have retained 0 DSV record after ROLLBACK, but retained *{?}
+*end if
+
+DELETE FROM t;
+COMMIT;
+* *DSV_RECORDS_PER_COMMIT = 10
+\m dsv-rejects.dsv
+SELECT COUNT(*) FROM t;
+*if (*? != 1)
+    \q Should have imported 1 good DSV records, but imported *{?} (3)
+*end if
+ROLLBACK;
+SELECT COUNT(*) FROM t;
+*if (*? != 1)
+    \q Should have retained 1 DSV record after ROLLBACK w/RPC, but retained *{?}
+*end if
diff --git a/testrun/sqltool/dsv-altspace.sql b/testrun/sqltool/dsv-altspace.sql
new file mode 100644
index 0000000..92bd3ca
--- /dev/null
+++ b/testrun/sqltool/dsv-altspace.sql
@@ -0,0 +1,15 @@
+/*
+ * $Id: dsv-altspace.sql 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests importing to table in non-default tablespace
+ */
+
+CREATE SCHEMA altspace authorization dba;
+CREATE TABLE altspace.targtbl (i INT, vc VARCHAR(80));
+
+\m altspace.targtbl.dsv
+SELECT COUNT(*) FROM altspace.targtbl;
+
+*if (*? != 2)
+    \q Import to alternate tablespace failed
+*end if
diff --git a/testrun/sqltool/dsv-constcols.dsv b/testrun/sqltool/dsv-constcols.dsv
new file mode 100644
index 0000000..f665ec4
--- /dev/null
+++ b/testrun/sqltool/dsv-constcols.dsv
@@ -0,0 +1,8 @@
+targettable=t
+
+# Following (header) line has intentional trailing whitespace.
+  i | - | d
+
+# Following line has intentional trailing whitespace (and mixed case).
+  1 | 1 | 2006-12-11
+  2 | 2 |
diff --git a/testrun/sqltool/dsv-constcols.sql b/testrun/sqltool/dsv-constcols.sql
new file mode 100644
index 0000000..0618a43
--- /dev/null
+++ b/testrun/sqltool/dsv-constcols.sql
@@ -0,0 +1,31 @@
+/*
+ * $Id: dsv-constcols.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests setting column values with *DSV_CONST_COLS
+ */
+
+* *DSV_CONST_COLS= d = 2007-05-14 0:00:00  |   a  =  139  
+
+CREATE TABLE t (i INT, a INT, d DATE);
+
+\m dsv-constcols.dsv
+SELECT COUNT(*) FROM t WHERE a = 139 AND d = '2007-05-14';
+
+/* The d const value will override the .dsv-specified values. */
+*if (*? != 2)
+    \q Import using constants for int and date columns failed
+*end if
+
+DELETE from t;
+* *DSV_CONST_COLS=
+\m dsv-constcols.dsv
+
+SELECT COUNT(*) FROM t WHERE a IS null AND d IS null;
+*if (*? != 1)
+    \q Failed to reset CONST_COLS behavior (1)
+*end if
+
+SELECT COUNT(*) FROM t WHERE a IS null AND d = '2006-12-11';
+*if (*? != 1)
+    \q Failed to reset CONST_COLS behavior (2)
+*end if
diff --git a/testrun/sqltool/dsv-omits.dsv b/testrun/sqltool/dsv-omits.dsv
new file mode 100644
index 0000000..6b9edfc
--- /dev/null
+++ b/testrun/sqltool/dsv-omits.dsv
@@ -0,0 +1,8 @@
+targettable=t
+
+# Following (header) line has intentional trailing whitespace.
+  - | i  |  -  |  a  |  -  |  b  |  - | c
+
+# Following line has intentional trailing whitespace (and mixed case).
+  1 | 1  |  1  |  1  |  1  |  1  |  1 | 1
+  2 | 2  |  2  |  2  |  2  |  2  |  2 | 2
diff --git a/testrun/sqltool/dsv-omits.sql b/testrun/sqltool/dsv-omits.sql
new file mode 100644
index 0000000..b77ea00
--- /dev/null
+++ b/testrun/sqltool/dsv-omits.sql
@@ -0,0 +1,43 @@
+/*
+ * $Id: dsv-omits.sql$
+ *
+ * Tests omitting columns via header line and *DSV_SKIP_COLS
+ */
+
+CREATE TABLE t (i INT, a INT, b INT, c INT);
+
+\m dsv-omits.dsv
+SELECT COUNT(*) FROM t
+WHERE i IS NOT null AND a IS NOT null AND b IS NOT null AND c IS NOT null;
+
+*if (*? != 2)
+    \q Import using header line - column-skips failed
+*end if
+
+/** Repeat test with some non-default DSV settings */
+* *DSV_SKIP_COLS =   c|   a 
+
+DELETE FROM t;
+\m dsv-omits.dsv
+
+SELECT COUNT(*) FROM t
+WHERE i IS NOT null AND b IS NOT null AND a IS null AND c IS null;
+
+*if (*? != 2)
+    \q Import using header line - AND *DSV_SKIP_COLS column-skips failed
+*end if
+
+/* Now test that behavior reverts when PL variable is cleared */
+* *DSV_SKIP_COLS =
+* listvalues
+
+DELETE FROM t;
+\m dsv-omits.dsv
+SELECT COUNT(*) FROM t
+WHERE i IS NOT null AND a IS NOT null AND b IS NOT null AND c IS NOT null;
+\p Post everything
+
+*if (*? != 2)
+    SELECT * FROM t;
+    \q *DSV_SKIP_COLS behavior failed to revert when variable was cleared
+*end if
diff --git a/testrun/sqltool/dsv-prepare.sql b/testrun/sqltool/dsv-prepare.sql
new file mode 100644
index 0000000..eb23281
--- /dev/null
+++ b/testrun/sqltool/dsv-prepare.sql
@@ -0,0 +1,18 @@
+/*
+ * $Id: dsv-prepare.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests PL 'prepare' command
+ */
+
+CREATE TABLE t (i INT, a INT, b INT, c INT);
+
+* N = 4567
+* prepare N
+
+INSERT INTO t(i, a, b, c) VALUES (1, ?, 8, 9);
+
+SELECT count(*) FROM t WHERE i = 1 AND a = 4567 AND b= 8 AND c = 9;
+
+*if (*? != 1)
+    \q PL prepare command failed
+*end if
diff --git a/testrun/sqltool/dsv-rejects.dsv b/testrun/sqltool/dsv-rejects.dsv
new file mode 100644
index 0000000..d7395c6
--- /dev/null
+++ b/testrun/sqltool/dsv-rejects.dsv
@@ -0,0 +1,14 @@
+targettable=t
+
+  i  |  r  |  d  |  t  |  v  |  b
+
+  31  |  3.124  |  2007-06-07  |  2006-05-06 12:30:04  |  a B  | true
+42 | 1.5 |  2007-07-08  |  2006-05-07 10:20  |  a string  | false
+
+# Letter in int field:
+5 | a |  2007-07-08  |  2006-05-07 10:20  |  a string  | false
+
+# No seconds in time field
+42 | 1.5 |  2007-07-08  |  2006-05-07 10:20  |  a string  | false
+
+42 | 1.5 |  2007-07-08  |  2006-05-07 10:20:0  |  a string  | false
diff --git a/testrun/sqltool/dsv-rejects.sql b/testrun/sqltool/dsv-rejects.sql
new file mode 100644
index 0000000..ec9347d
--- /dev/null
+++ b/testrun/sqltool/dsv-rejects.sql
@@ -0,0 +1,16 @@
+/*
+ * $Id: dsv-rejects.sql 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests proper rejection of bad DSV input records
+ */
+
+CREATE TABLE t (i INT, r REAL, d DATE, t TIMESTAMP, v VARCHAR(80), b BOOLEAN);
+
+* *DSV_REJECT_REPORT = ${java.io.tmpdir}/sqltoolutst-${user.name}.html
+\m dsv-rejects.dsv
+
+SELECT COUNT(*) FROM t;
+
+*if (*? != 2)
+    \q Should have imported 2 good DSV records, but imported *{?}
+*end if
diff --git a/testrun/sqltool/dsv-roundtrip.sql b/testrun/sqltool/dsv-roundtrip.sql
new file mode 100644
index 0000000..dfd84ff
--- /dev/null
+++ b/testrun/sqltool/dsv-roundtrip.sql
@@ -0,0 +1,38 @@
+/*
+ * $Id: dsv-roundtrip.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests a DSV "round trip".
+ * Create a table, export the data, import it back, cf. imported  and original.
+ */
+
+* *DSV_TARGET_FILE = ${java.io.tmpdir}/test-roundtrip-${user.name}.dsv
+* *DSV_TARGET_TABLE = t
+CREATE TABLE t (i INT, a INT, d DATE);
+
+INSERT INTO t(i, a, d) VALUES (1, 149, null);
+INSERT INTO t(i, a, d) VALUES (2, null, '2007-06-24');
+
+/* Export */
+\x t
+
+SELECT count(*) FROM t WHERE i = 1 AND a = 149 AND d IS null;
+*if (*? != 1)
+    \q Pre-check of inserted data failed (1)
+*end if
+SELECT count(*) FROM t WHERE i = 2 AND a IS NULL AND d = '2007-06-24';
+*if (*? != 1)
+    \q Pre-check of inserted data failed (2)
+*end if
+
+
+/* Import */
+\m *{*DSV_TARGET_FILE}
+
+SELECT count(*) FROM t WHERE i = 1 AND a = 149 AND d IS null;
+*if (*? != 2)
+    \q Post-check of imported data failed (1)
+*end if
+SELECT count(*) FROM t WHERE i = 2 AND a IS NULL AND d = '2007-06-24';
+*if (*? != 2)
+    \q Post-check of imported data failed (2)
+*end if
diff --git a/testrun/sqltool/dsv-rpcommit.dsv b/testrun/sqltool/dsv-rpcommit.dsv
new file mode 100644
index 0000000..9a53cf5
--- /dev/null
+++ b/testrun/sqltool/dsv-rpcommit.dsv
@@ -0,0 +1,25 @@
+targettable=t
+
+i
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+x
+15
+16
+17
+18
+19
+20
+21
+22
diff --git a/testrun/sqltool/dsv-rpcommit.sql b/testrun/sqltool/dsv-rpcommit.sql
new file mode 100644
index 0000000..87dbe9a
--- /dev/null
+++ b/testrun/sqltool/dsv-rpcommit.sql
@@ -0,0 +1,38 @@
+/*
+ * $Id: dsv-rpcommit.sql 437 2008-11-14 04:17:35Z unsaved $
+ *
+ * Tests *DSV_RECORDS_PER_COMMIT setting
+ */
+
+/* Unfortunately, can't test how many commits are performed and where.
+ * That would * require adding significant complexity to SqlFile itself, or
+ * complex interception of commits.
+ * I have, however, manually tested the commits by echoing the commits in
+ * the source code, and removing observing what remains uncommitted after
+ * removing the straggler-catching commit after the insertion loop in
+ * SqlFile.importDsv().
+ * All that we are testing here is that all records which should be committed
+ * do get committed.
+ */
+
+CREATE TABLE t (i INT);
+
+\c true
+* *DSV_RECORDS_PER_COMMIT=5
+\m dsv-rpcommit.dsv
+
+ROLLBACK;
+
+SELECT COUNT(*) FROM t;
+*if (*? != 13)
+    \q *DSV_RECORDS_PER_COMMIT committed only *{?} records instead 13
+*end if
+
+DELETE FROM t;
+* *DSV_REJECT_REPORT = /dev/null
+\m dsv-rpcommit.dsv
+
+SELECT COUNT(*) FROM t;
+*if (*? != 21)
+    \q *DSV_RECORDS_PER_COMMIT committed only *{?} records instead 21
+*end if
diff --git a/testrun/sqltool/dsv-sqlarray.sql b/testrun/sqltool/dsv-sqlarray.sql
new file mode 100644
index 0000000..2af2bf2
--- /dev/null
+++ b/testrun/sqltool/dsv-sqlarray.sql
@@ -0,0 +1,46 @@
+/*
+ * $Id: dsv-sqlarray.sql 3603 2010-06-01 02:07:46Z unsaved $
+ *
+ * Tests a DSV "round trip".
+ * Create a table, export the data, import it back, cf. imported  and original.
+ */
+
+* *DSV_TARGET_FILE = ${java.io.tmpdir}/test-sqlarray-${user.name}.dsv
+* *DSV_TARGET_TABLE = t
+
+CREATE TABLE t (i BIGINT PRIMARY KEY, ar INTEGER ARRAY);
+
+INSERT INTO t VALUES (1, array [11, null, 13]);
+INSERT INTO t VALUES (2, null);
+INSERT INTO t VALUES (3, array [21, 22]);
+COMMIT;
+
+/* Export */
+\x t
+
+SELECT count(*) FROM t WHERE ar IS NULL AND i = 2;
+*if (*? != 1)
+    \q Pre-check of inserted Array array data failed (1)
+*end if
+SELECT count(*) FROM t WHERE i in (1, 3) AND ar IS NOT null;
+*if (*? != 2)
+    \q Pre-check of inserted Array data failed (2)
+*end if
+
+DELETE FROM t;
+
+SELECT count(*) FROM t;
+*if (*? != 0)
+    \q Failed to clear table data
+*end if
+
+/* Import */
+\m *{*DSV_TARGET_FILE}
+SELECT count(*) FROM t WHERE ar IS NULL AND i = 2;
+*if (*? != 1)
+    \q Post-check of inserted Array array data failed (1)
+*end if
+SELECT count(*) FROM t WHERE i in (1, 3) AND ar IS NOT null;
+*if (*? != 2)
+    \q Post-check of inserted Array data failed (2)
+*end if
diff --git a/testrun/sqltool/dsv-trimall.dsv b/testrun/sqltool/dsv-trimall.dsv
new file mode 100644
index 0000000..0134728
--- /dev/null
+++ b/testrun/sqltool/dsv-trimall.dsv
@@ -0,0 +1,5 @@
+targettable=t
+  i | vc | d  
+  1 |  o n e  | 2006-12-11
+  2 | two | 2008-02-98
+3|three|
diff --git a/testrun/sqltool/dsv-trimall.sql b/testrun/sqltool/dsv-trimall.sql
new file mode 100644
index 0000000..75242f4
--- /dev/null
+++ b/testrun/sqltool/dsv-trimall.sql
@@ -0,0 +1,42 @@
+/*
+ * $Id: dsv-trimall.sql 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests *DSV_TRIM_ALL option.
+ */
+
+CREATE TABLE t (i INT, vc VARCHAR(80), d DATE);
+
+\m dsv-trimall.dsv
+
+SELECT COUNT(*) FROM t WHERE vc = 'three';
+*if (*? != 1)
+    \q Sanity check failed
+*end if
+SELECT COUNT(*) FROM t WHERE vc = '  o n e  ';
+*if (*? != 1)
+    \q Default mode messed with VARCHAR-embedded whitespace
+*end if
+SELECT COUNT(*) FROM t WHERE vc = ' two ';
+*if (*? != 1)
+    \q Default mode messed with leading or trailing whitespace in VARCHAR
+*end if
+
+DELETE from t;
+COMMIT;
+
+* *DSV_TRIM_ALL = true
+
+\m dsv-trimall.dsv
+
+SELECT COUNT(*) FROM t WHERE vc = 'three';
+*if (*? != 1)
+    \q 2nd Sanity check failed
+*end if
+SELECT COUNT(*) FROM t WHERE vc = 'o n e';
+*if (*? != 1)
+    \q *DSV_TRIM_ALL didn't trim with VARCHAR-embedded whitespace properly
+*end if
+SELECT COUNT(*) FROM t WHERE vc = 'two';
+*if (*? != 1)
+    \q *DSV_TRIM_ALL didn't trim leading or trailing whitespace properly
+*end if
diff --git a/testrun/sqltool/dsv-trimming-alt.dsv b/testrun/sqltool/dsv-trimming-alt.dsv
new file mode 100644
index 0000000..7b5ec74
--- /dev/null
+++ b/testrun/sqltool/dsv-trimming-alt.dsv
@@ -0,0 +1,7 @@
+targettable=t}
+}
+# Following (header) line has intentional trailing whitespace.}
+  i  \  r  \  d  \  t  \  v  \  b   }
+}
+# Following line has intentional trailing whitespace (and mixed case).}
+  31  \  3.124  \  2007-06-07  \  2006-05-06 12:30:04  \  a B  \  tRUe  }
diff --git a/testrun/sqltool/dsv-trimming.dsv b/testrun/sqltool/dsv-trimming.dsv
new file mode 100644
index 0000000..be40ba4
--- /dev/null
+++ b/testrun/sqltool/dsv-trimming.dsv
@@ -0,0 +1,7 @@
+targettable=t
+
+# Following (header) line has intentional trailing whitespace.
+  i  |  r  |  d  |  t  |  v  |  b   
+
+# Following line has intentional trailing whitespace (and mixed case).
+  31  |  3.124  |  2007-06-07  |  2006-05-06 12:30:04  |  a B  |  tRUe  
diff --git a/testrun/sqltool/dsv-trimming.sql b/testrun/sqltool/dsv-trimming.sql
new file mode 100644
index 0000000..5a927e6
--- /dev/null
+++ b/testrun/sqltool/dsv-trimming.sql
@@ -0,0 +1,82 @@
+/*
+ * $Id: dsv-trimming.sql 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests trimming in DSV imports
+ */
+
+CREATE TABLE t (i INT, r REAL, d DATE, t TIMESTAMP, v VARCHAR(80), b BOOLEAN);
+
+\m dsv-trimming.dsv
+
+SELECT count(*)  FROM t WHERE i = 31;
+*if (*? != 1)
+    \q Import of space-embedded INT failed
+*end if
+
+SELECT count(*)  FROM t WHERE r = 3.124;
+*if (*? != 1)
+    \q Import of space-embedded REAL failed
+*end if
+
+SELECT count(*)  FROM t WHERE d = '2007-06-07';
+*if (*? != 1)
+    \q Import of space-embedded DATE failed (1)
+*end if
+
+SELECT count(*)  FROM t WHERE t = '2006-05-06 12:30:04';
+*if (*? != 1)
+    \q Import of space-embedded TIMESTAMP failed
+*end if
+
+SELECT count(*)  FROM t WHERE v = '  a B  ';
+*if (*? != 1)
+    \q Import of space-embedded VARCHAR failed
+*end if
+
+/** I dont' know if "IS true" or "= true" is preferred, but the former
+ * doesn't work with HSQLDB 1.7.0.7 */
+SELECT count(*)  FROM t WHERE b = true;
+*if (*? != 1)
+    \q Import of space-embedded BOOLEAN failed
+*end if
+
+
+/** Repeat test with some non-default DSV settings */
+* *DSV_COL_SPLITTER = \\
+* *DSV_ROW_SPLITTER = \}(?:\r\n|\r|\n)
+
+DELETE FROM t;
+
+\m dsv-trimming-alt.dsv
+
+SELECT count(*)  FROM t WHERE i = 31;
+*if (*? != 1)
+    \q Import of space-embedded INT failed
+*end if
+
+SELECT count(*)  FROM t WHERE r = 3.124;
+*if (*? != 1)
+    \q Import of space-embedded REAL failed
+*end if
+
+SELECT count(*)  FROM t WHERE d = '2007-06-07';
+*if (*? != 1)
+    \q Import of space-embedded DATE failed (2)
+*end if
+
+SELECT count(*)  FROM t WHERE t = '2006-05-06 12:30:04';
+*if (*? != 1)
+    \q Import of space-embedded TIMESTAMP failed
+*end if
+
+SELECT count(*)  FROM t WHERE v = '  a B  ';
+*if (*? != 1)
+    \q Import of space-embedded VARCHAR failed
+*end if
+
+/** I dont' know if "IS true" or "= true" is preferred, but the former
+ * doesn't work with HSQLDB 1.7.0.7 */
+SELECT count(*)  FROM t WHERE b = true;
+*if (*? != 1)
+    \q Import of space-embedded BOOLEAN failed
+*end if
diff --git a/testrun/sqltool/errhandling.isql b/testrun/sqltool/errhandling.isql
new file mode 100644
index 0000000..8fa5e68
--- /dev/null
+++ b/testrun/sqltool/errhandling.isql
@@ -0,0 +1,40 @@
+/*
+ * $Id: errhandling.isql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests error handling inside of blocks and in subscripts.
+ */
+
+\c true
+bad;
+\p Made it past first ignored error.
+
+/* At root level, can even ignore fatal syntax errors */
+* foreach bad
+* ifff
+
+* V = changethis
+* if (1)
+    bad;
+    * ifff
+    * end nosuch
+    * V = ok
+* end if 
+
+* if (*V != ok)
+    \q Seems to have aborted inside if block in Continue-on-error mode
+* end if
+
+* W = changethis
+* if (1)
+    bad;
+    *if (2)
+        * ifff
+        * end nosuch
+        * W = ok
+    *end if
+    worse;
+* end if 
+
+* if (*W != ok)
+    \q Seems to have aborted inside nested if block in Continue-on-error mode
+* end if
diff --git a/testrun/sqltool/errhandling.nsql b/testrun/sqltool/errhandling.nsql
new file mode 100644
index 0000000..3e2ea39
--- /dev/null
+++ b/testrun/sqltool/errhandling.nsql
@@ -0,0 +1,15 @@
+/*
+ * $Id: errhandling.nsql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Negative tests error handling inside of blocks and in subscripts.
+ */
+
+* if (1)
+    *if (2)
+        \i errhandlingn.isql
+    *end if
+    worse;
+* end if 
+
+\p Returned from bad script errhandlingn.isql.  Should not have.
+\q
diff --git a/testrun/sqltool/errhandling.sql b/testrun/sqltool/errhandling.sql
new file mode 100644
index 0000000..f1b27f0
--- /dev/null
+++ b/testrun/sqltool/errhandling.sql
@@ -0,0 +1,42 @@
+/*
+ * $Id: errhandling.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests error handling inside of blocks and in subscripts.
+ */
+
+\c true
+bad;
+\p Made it past first ignored error.
+
+/* At root level, can even ignore fatal syntax errors */
+* foreach bad
+* ifff
+
+* V = changethis
+* if (1)
+    bad;
+    * ifff
+    * end nosuch
+    * V = ok
+* end if 
+
+* if (*V != ok)
+    \q Seems to have aborted inside if block in Continue-on-error mode
+* end if
+
+* W = changethis
+* if (1)
+    bad;
+    *if (2)
+        * ifff
+        * end nosuch
+        * W = ok
+    *end if
+    worse;
+* end if 
+
+* if (*W != ok)
+    \q Seems to have aborted inside nested if block in Continue-on-error mode
+* end if
+
+\i errhandling.isql
diff --git a/testrun/sqltool/errhandlingn.isql b/testrun/sqltool/errhandlingn.isql
new file mode 100644
index 0000000..3954f4a
--- /dev/null
+++ b/testrun/sqltool/errhandlingn.isql
@@ -0,0 +1,15 @@
+/*
+ * $Id: errhandlingn.isql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Errors out in a nested block
+ */
+
+* if (1)
+    *if (2)
+        \q Forced error
+    *end if
+    worse;
+* end if 
+
+\p Returned from bad block.  Should not have.
+\q
diff --git a/testrun/sqltool/goodsqlonly.sql b/testrun/sqltool/goodsqlonly.sql
new file mode 100644
index 0000000..1df8f82
--- /dev/null
+++ b/testrun/sqltool/goodsqlonly.sql
@@ -0,0 +1,7 @@
+/*
+ * $Id: goodsqlonly.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Just runs some successful SQL.
+ */
+
+CREATE TABLE t(i INTEGER);
diff --git a/testrun/sqltool/history.inter b/testrun/sqltool/history.inter
new file mode 100644
index 0000000..0d0af8e
--- /dev/null
+++ b/testrun/sqltool/history.inter
@@ -0,0 +1,50 @@
+/*
+ * $Id: history.inter 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests simple recalls and executes : and :;.
+ */
+
+\c false
+/* Since running interactively, need to either invoke with --abortOnErr switch,
+ * or use "\c false" Special command, to detect failures. */
+
+CREATE TABLE t(id INTEGER GENERATED BY DEFAULT AS IDENTITY, vc VARCHAR(80));
+
+/* Just verify that an error is not thrown by the two following commands.
+   And that they don't effect the command history. */
+:b
+:h
+
+INSERT INTO t(vc) VALUES('one');
+INSERT INTO t(vc) VALUES('two');
+INSERT INTO t(vc) VALUES('three');
+
+/* Test simple recall and execution */
+:4
+:;
+:4;
+:;
+
+SELECT count(*) FROM t
+*if (*? != 6)
+    \q Recall and execs failed / 1
+*end if
+
+/* SELECT vc FROM t; */
+SELECT count(*) FROM t WHERE vc = 'two';
+*if (*? != 4)
+    \q Recall and execs failed / 2
+*end if
+
+:/ee/;
+
+SELECT count(*) FROM t;
+*if (*? != 7)
+    \q Regex Recall and execs failed / 1
+*end if
+
+/* SELECT vc FROM t; */
+SELECT count(*) FROM t WHERE vc = 'three';
+*if (*? != 2)
+    \q Regex Recall and execs failed / 2
+*end if
diff --git a/testrun/sqltool/lastval.sql b/testrun/sqltool/lastval.sql
new file mode 100644
index 0000000..556802d
--- /dev/null
+++ b/testrun/sqltool/lastval.sql
@@ -0,0 +1,42 @@
+/*
+ * $Id: lastval.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests auto-variable ?
+ */
+
+CREATE TABLE t (i INT);
+
+* if (*? != 0)
+    \q ? variable not capturing CREATE TABLE return value
+* end if
+
+INSERT INTO t values (21);
+* if (*? != 1)
+    \q ? variable not capturing INSERT return value
+* end if
+
+INSERT INTO t values (10);
+* if (*? != 1)
+    \q ? variable not capturing INSERT return value
+* end if
+
+INSERT INTO t values (43);
+* if (*? != 1)
+    \q ? variable not capturing INSERT return value
+* end if
+
+SELECT * FROM t ORDER BY i DESC;
+* if (*? != 10)
+    \q ? variable not capturing last fetched value
+* end if
+
+\p echo some stuff
+\p to verify that ? variable value is preserved
+* list
+
+* if (*? != 10)
+    \q ? value not retained after special commands
+* end if
+* if (*{?} != 10)
+    \q ? value not dereferenced with {} usage
+* end if
diff --git a/testrun/sqltool/logic.sql b/testrun/sqltool/logic.sql
new file mode 100644
index 0000000..1f35e85
--- /dev/null
+++ b/testrun/sqltool/logic.sql
@@ -0,0 +1,66 @@
+/*
+ * $Id: logic.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Logic tests
+ */
+
+*if (1)
+    * T1 = true
+*end if
+*if (! *T1)
+    \q Test of (1) failed
+*end if
+*if (0)
+    \q Test of (0) failed
+*end if
+
+*if (! 1)
+    \q Test of (! 1) failed
+*end if
+*if (! 0)
+    * T2 = true
+*end if
+*if (! *T2)
+    \q Test of (! 0) failed
+*end if
+
+*if (!1)
+    \q Test of (!1) failed
+*end if
+*if (!0)
+    * T3 = true
+*end if
+*if (!*T3)
+    \q Test of (!0) failed
+*end if
+
+* SETVAR=3
+*if (*SETVAR)
+    * T4 = true
+*end if
+*if (! *T4)
+    \q Test of (*SETVAR) failed
+*end if
+*if (*UNSETVAR)
+    \q Test of (*UNSETVAR) failed
+*end if
+
+*if (! *SETVAR)
+    \q Test of (! *SETVAR) failed
+*end if
+*if (! *UNSETVAR)
+    * T5 = true
+*end if
+*if (! *T5)
+    \q Test of (! *UNSETVAR) failed
+*end if
+
+*if (!*SETVAR)
+    \q Test of (!*SETVAR) failed
+*end if
+*if (!*UNSETVAR)
+    * T6 = true
+*end if
+*if (!*T6)
+    \q Test of (!*UNSETVAR) failed
+*end if
diff --git a/testrun/sqltool/macro.inter b/testrun/sqltool/macro.inter
new file mode 100644
index 0000000..f9a1764
--- /dev/null
+++ b/testrun/sqltool/macro.inter
@@ -0,0 +1,41 @@
+/*
+ * $Id: macro.inter 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests interactive macro commands /...
+ *
+ * This only tests the buffer macro commands /=:..., so that we can
+ * manipulate the buffer.
+ * The other macro commands don't need interactive mode.
+ */
+
+
+\c false
+
+\p hello
+/=greet: world
+/=
+/greet now;
+
+CREATE TABLE t(i int);
+INSERT INTO t VALUES(1);
+INSERT INTO t VALUES(2);
+INSERT INTO t VALUES(3);
+INSERT INTO t VALUES(4);
+INSERT INTO t VALUES(5);
+COMMIT;
+
+SELECT count(*) FROM t
+
+/=q: where
+
+/q i > 3;
+
+* if (*? != 2)
+    \q Query returned *{?} rows, should have returned 2.
+* end if
+
+/q i > 2
+:;
+* if (*? != 3)
+    \q Query returned *{?} rows, should have returned 3.
+* end if
diff --git a/testrun/sqltool/macro.sql b/testrun/sqltool/macro.sql
new file mode 100644
index 0000000..b71bc3b
--- /dev/null
+++ b/testrun/sqltool/macro.sql
@@ -0,0 +1,43 @@
+/*
+ * $Id: macro.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests interactive macro commands /...
+ *
+ * See macro.inter script also.
+ */
+
+
+\c false
+
+/=q SELECT count(*) FROM t
+
+CREATE TABLE t(i int);
+INSERT INTO t VALUES(1);
+INSERT INTO t VALUES(2);
+INSERT INTO t VALUES(3);
+INSERT INTO t VALUES(4);
+INSERT INTO t VALUES(5);
+COMMIT;
+
+/q WHERE i > 3;
+
+* if (*? != 2)
+    \q Query returned *{?} rows, should have returned 2.
+* end if
+
+/* Now test with lots of intervening white space */
+  /  =   q   SELECT count(*) FROM t WHERE i > *{LIMIT}   
+
+   /   =   setlim  *  LIMIT =   
+
+* LIMIT = 4
+/q;
+* if (*? != 1)
+    \q Query returned *{?} rows, should have returned 1.
+* end if
+
+/setlim 3;
+/q;
+* if (*? != 2)
+    \q Query returned *{?} rows, should have returned 2.
+* end if
diff --git a/testrun/sqltool/nestingschema.sql b/testrun/sqltool/nestingschema.sql
new file mode 100644
index 0000000..efa2996
--- /dev/null
+++ b/testrun/sqltool/nestingschema.sql
@@ -0,0 +1,22 @@
+/*
+ * $Id: nestingschema.sql 437 2008-11-14 04:17:35Z unsaved $
+ *
+ * Tests a schema creation statement that nests some objects.
+ */
+
+/**
+ * Besides testing nesting of commands without ; delimiters, this also
+ * regression tests that the CREATE SCHEMA... command itself does not require
+ * the closing ; to be sent to the DB engine.
+ */
+CREATE SCHEMA FELIX AUTHORIZATION DBA
+    CREATE TABLE FELIXT1 (AV1 VARCHAR(10), BV VARCHAR(10))
+    CREATE TABLE FELIXT2 (AV2 VARCHAR(10), BI INTEGER)
+    CREATE SEQUENCE FELIXS1
+    CREATE VIEW FELIXV1 AS SELECT * FROM FELIXT1 JOIN FELIXT2 ON AV1 = AV2
+    CREATE VIEW FELIXV2 AS SELECT AV1 AS C1, NEXT VALUE FOR FELIXS1 AS C2 FROM FELIXT1;
+
+SELECT count(*) FROM felix.felixv2;
+*if (*? != 0)
+    \q Nesting CREATE SCHEMA failed
+*end if
diff --git a/testrun/sqltool/noop.sql b/testrun/sqltool/noop.sql
new file mode 100644
index 0000000..b513ae2
--- /dev/null
+++ b/testrun/sqltool/noop.sql
@@ -0,0 +1,5 @@
+/*
+ * $Id: noop.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Simplest test possible.  Does absolutely nothing.
+ */
diff --git a/testrun/sqltool/nq-arg1.isql b/testrun/sqltool/nq-arg1.isql
new file mode 100644
index 0000000..1579f2f
--- /dev/null
+++ b/testrun/sqltool/nq-arg1.isql
@@ -0,0 +1,10 @@
+/*
+ * $Id: nq-arg1.isql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Simplest test of \q from nested script with args
+ */
+
+\q This should cause SqlTool to exit immediately with non-zero exit value.
+
+/* Following line causes the unit test to fail if the \q above didn't work.
+\q
diff --git a/testrun/sqltool/nq-arg1.nsql b/testrun/sqltool/nq-arg1.nsql
new file mode 100644
index 0000000..42da0f4
--- /dev/null
+++ b/testrun/sqltool/nq-arg1.nsql
@@ -0,0 +1,10 @@
+/*
+ * $Id: nq-arg1.nsql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Test of \q with arg from nested script.
+ */
+
+\i nq-arg1.isql
+\p Should not have returned from nested script which ran \q.
+/* Following line exits with success status to fail the .nsql unit test.
+\q
diff --git a/testrun/sqltool/nq-noarg1.isql b/testrun/sqltool/nq-noarg1.isql
new file mode 100644
index 0000000..1602313
--- /dev/null
+++ b/testrun/sqltool/nq-noarg1.isql
@@ -0,0 +1,10 @@
+/*
+ * $Id: nq-noarg1.isql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Simplest test of \q from nested script with no args
+ */
+
+\p Following statement should exit SqlTool immediately with success exit status.
+\q
+
+\q This causes the unit test to fail if the \q above didn't work.
diff --git a/testrun/sqltool/nq-noarg1.sql b/testrun/sqltool/nq-noarg1.sql
new file mode 100644
index 0000000..aef31e1
--- /dev/null
+++ b/testrun/sqltool/nq-noarg1.sql
@@ -0,0 +1,8 @@
+/*
+ * $Id: nq-noarg1.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Test of \q with arg from nested script.
+ */
+
+\i nq-noarg1.isql
+\q Should not have returned from nested script!
diff --git a/testrun/sqltool/nullrep-alt.dsv b/testrun/sqltool/nullrep-alt.dsv
new file mode 100644
index 0000000..f5f618e
--- /dev/null
+++ b/testrun/sqltool/nullrep-alt.dsv
@@ -0,0 +1,8 @@
+targettable=t}
+}
+# Following (header) line has intentional trailing whitespace.}
+id:  i  :  r  :  d  :  t  :  v  :  b   }
+}
+# Following line has intentional trailing whitespace (and mixed case).}
+wspaces:  %%  :  %%  :  %%  :  %%  :  %%  :  %%  }
+nospaces:%%:%%:%%:%%:%%:%%}
diff --git a/testrun/sqltool/nullrep.dsv b/testrun/sqltool/nullrep.dsv
new file mode 100644
index 0000000..91af747
--- /dev/null
+++ b/testrun/sqltool/nullrep.dsv
@@ -0,0 +1,8 @@
+targettable=t
+
+# Following (header) line has intentional trailing whitespace.
+id|  i  |  r  |  d  |  t  |  v  |  b   
+
+# Following line has intentional trailing whitespace (and mixed case).
+wspaces|  [null]  |  [null]  |  [null]  |  [null]  |  [null]  |  [null]  
+nospaces|[null]|[null]|[null]|[null]|[null]|[null]
diff --git a/testrun/sqltool/nullrep.sql b/testrun/sqltool/nullrep.sql
new file mode 100644
index 0000000..4390e1b
--- /dev/null
+++ b/testrun/sqltool/nullrep.sql
@@ -0,0 +1,109 @@
+/*
+ * $Id: nullrep.sql 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests enforcement of null-representation token 
+ */
+
+CREATE TABLE t (i INT, vc VARCHAR(80));
+
+INSERT INTO t VALUES(1, 'one');
+/** For INPUT, the NULLREP is only used for DSV imports, since unquoted
+ *  null works perfectly for other forms of input.
+ *  Therefore, following should enter "[null]" literally.
+ */
+INSERT INTO t VALUES(2, '[null]');
+INSERT INTO t VALUES(3, null);
+
+* COUNT _
+SELECT count(*) FROM t WHERE i = 2 AND vc IS NULL;
+* if (*COUNT != 0)
+    \q Seems that non-DSV insertion of '[null]' inserted a real NULL
+* end if
+
+* COUNT _
+SELECT count(*) FROM t WHERE i = 3 AND vc IS null;
+* if (*COUNT != 1)
+    \q Seems that non-DSV insertion of plain null did not insert a SQL NULL
+* end if
+DROP TABLE t;
+
+
+/* Now test nullrep tokens with DSV imports */
+CREATE TABLE t (
+    id VARCHAR(80) PRIMARY KEY,
+    i INTEGER,
+    r REAL,
+    d DATE,
+    t TIMESTAMP,
+    v VARCHAR(80),
+    b BOOLEAN
+);
+
+\m nullrep.dsv
+SELECT count(*) FROM t WHERE id = 'wspaces' AND i IS null;
+*if (*? != 1)
+    \q Insertion of INTEGER space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND r IS null;
+*if (*? != 1)
+    \q Insertion of REAL space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND d IS null;
+*if (*? != 1)
+    \q Insertion of DATE space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND t IS null;
+*if (*? != 1)
+    \q Insertion of TIMESTAMP space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND v = '  [null]  ';
+*if (*? != 1)
+    \q Insertion of VARCHAR w/ space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND b IS null;
+*if (*? != 1)
+    \q Insertion of BOOLEAN space-embedded null-rep-token failed
+*end if
+
+DELETE FROM t;
+
+/** Repeat test with some non-default DSV settings */
+* *NULL_REP_TOKEN = %%
+* *DSV_COL_SPLITTER = :
+* *DSV_ROW_SPLITTER = \}(?:\r\n|\r|\n)
+
+\m nullrep-alt.dsv
+SELECT count(*) FROM t WHERE id = 'wspaces' AND i IS null;
+*if (*? != 1)
+    \q Insertion of INTEGER space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND r IS null;
+*if (*? != 1)
+    \q Insertion of REAL space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND d IS null;
+*if (*? != 1)
+    \q Insertion of DATE space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND t IS null;
+*if (*? != 1)
+    \q Insertion of TIMESTAMP space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND v = '  %%  ';
+*if (*? != 1)
+    \q Insertion of VARCHAR w/ space-embedded null-rep-token failed
+*end if
+
+SELECT count(*) FROM t WHERE id = 'wspaces' AND b IS null;
+*if (*? != 1)
+    \q Insertion of BOOLEAN space-embedded null-rep-token failed
+*end if
diff --git a/testrun/sqltool/plcontrolflow.sql b/testrun/sqltool/plcontrolflow.sql
new file mode 100644
index 0000000..eb313b1
--- /dev/null
+++ b/testrun/sqltool/plcontrolflow.sql
@@ -0,0 +1,215 @@
+/*
+ * $Id: plcontrolflow.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests PL control flow.  if, foreach statements, etc.
+ */
+
+*if (*UNSET)
+    \q Failed boolean test of an unset variable
+*end if
+*if (astring)
+   * y = something
+*end if
+*if (*X)
+    \q Failed boolean test of a simple string constant
+*end if
+*if (0)
+    \q Failed boolean test of zero constant
+*end if
+*if (! x)
+/* Note that there must be white space to separate the two tokens above. */
+    \q Failed boolean test of a plain constant
+*end if
+
+
+/* Nested if tests */
+* if (1)
+    * L1 = true
+    * if (2)
+        * L2 = true
+    * end if
+    * L11 = true
+* end if
+*if (! *L1)
+    \q Pre-nest failure
+*end if
+*if (! *L2)
+    \q Inside-nest failure
+*end if
+*if (! *L11)
+    \q Post-nest failure
+*end if
+* L1 =
+* L2 =
+* L11 =
+* if (1)
+    * L1 = true
+    * if (2)
+        * L2 = true
+    * end if
+    * L11 = true
+* end if
+*if (! *L1)
+    \q Pre-nest failure
+*end if
+*if (! *L2)
+    \q Inside-nest failure
+*end if
+*if (! *L11)
+    \q Post-nest failure
+*end if
+/* Test deep nesting of IFs, including negatives. */
+* if (1)
+    * L1 = true
+    * if (0)
+        * N2 = true
+    * end if
+    * if (2)
+        * L2 = true
+        * if (3)
+            * L3 = true
+            * if (4)
+                * L4 = true
+                * if (0)
+                    * N5 = true
+                * end if
+                * if (5)
+                    * L5 = true
+                    * if (0)
+                        * N6 = true
+                    * end if
+                    * if (6)
+                        * L6 = true
+                        * if (0)
+                            * N7 = true
+                        * end if
+                    * end if
+                    * L51 = true
+                * end if
+            * end if
+            * if (0)
+                * N4 = true
+            * end if
+            * L31 = true
+        * end if
+        * if (0)
+            * N3 = true
+        * end if
+    * end if
+    * L11 = true
+* end if
+*if (! *L1)
+    \q Pre-deep-nest failure 1
+*end if
+*if (! *L2)
+    \q Inside-deep-nest failure 2
+*end if
+*if (! *L11)
+    \q Post-deep-nest failure 11
+*end if
+*if (! *L3)
+    \q Pre-deep-nest failure 3
+*end if
+*if (! *L4)
+    \q Inside-deep-nest failure 4
+*end if
+*if (! *L31)
+    \q Post-deep-nest failure 31
+*end if
+*if (! *L5)
+    \q Pre-deep-nest failure 5
+*end if
+*if (! *L6)
+    \q Inside-deep-nest failure 6
+*end if
+*if (! *L51)
+    \q Post-deep-nest failure 51
+*end if
+*if (*N2)
+    \q Negative deep-nest failure 2
+*end if
+*if (*N3)
+    \q Negative deep-nest failure 3
+*end if
+*if (*N4)
+    \q Negative deep-nest failure 4
+*end if
+*if (*N5)
+    \q Negative deep-nest failure 5
+*end if
+*if (*N6)
+    \q Negative deep-nest failure 6
+*end if
+*if (*N7)
+    \q Negative deep-nest failure 7
+*end if
+
+/* Nested foreach tests */
+/* Initialize Results  to I */
+* R = I
+*foreach L1 (A B C)
+  *foreach L2 (1 2 3 4)
+      *foreach L3 (a b)
+	      * R = *{R}:*{L1}*{L2}*{L3}
+	  *end foreach
+  *end foreach
+*end foreach
+*if (*R != I:A1a:A1b:A2a:A2b:A3a:A3b:A4a:A4b:B1a:B1b:B2a:B2b:B3a:B3b:B4a:B4b:C1a:C1b:C2a:C2b:C3a:C3b:C4a:C4b)
+    \q nested foreach result unexpected: *{R}
+*end if
+/* Initialize Results  to I */
+* R = I
+*foreach L1 (A B C)
+  *if (*L1 != A)
+	  *foreach L2 (1 2 3 4)
+		  *if (*L2 != 3)
+			  *foreach L3 (a b c)
+				  *if (*L3 != b)
+					  * R = *{R}:*{L1}*{L2}*{L3}
+				  *end if
+			  *end foreach
+		  *end if
+	  *end foreach
+  *end if
+*end foreach
+*if (*R != I:B1a:B1c:B2a:B2c:B4a:B4c:C1a:C1c:C2a:C2c:C4a:C4c)
+    \q nested conditional foreach result unexpected: *{R}
+*end if
+
+/* Test break and continue */
+/* Initialize Results  to I */
+* R = I
+*foreach L1 (A B C)
+  *foreach L2 (1 2 3 4)
+      *foreach L3 (a b)
+          *if (*L3 == a)
+            *continue
+          *end if
+	      * R = *{R}:*{L1}*{L2}*{L3}
+	  *end foreach
+      *if (*L2 == 3)
+        *break foreach
+      *end if
+  *end foreach
+*end foreach
+*if (*R != I:A1b:A2b:A3b:B1b:B2b:B3b:C1b:C2b:C3b)
+    \q nested foreach result unexpected: *{R}
+*end if
+
+/* If something doesn't work right, could get into infinite loop below. */
+* accum=L
+*while (1)
+   * accum = *{accum}P
+   * subcum = M
+   *while (*subcum < MQQ)
+       * subcum = *{subcum}Q
+   *end while
+   * accum = *{accum}*{subcum}
+   *if (*accum == LPMQQPMQQ)
+       *break while
+    *end if
+*end while
+
+*if (*accum != LPMQQPMQQ)
+    \q Wrong value accumulated by nested while loops (*{accum})
+*end if
diff --git a/testrun/sqltool/q-arg1.nsql b/testrun/sqltool/q-arg1.nsql
new file mode 100644
index 0000000..207fd9c
--- /dev/null
+++ b/testrun/sqltool/q-arg1.nsql
@@ -0,0 +1,7 @@
+/*
+ * $Id: q-arg1.nsql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Simplest test of \q with arg
+ */
+
+\q Quitting with non-zero exit status
diff --git a/testrun/sqltool/q-noarg1.sql b/testrun/sqltool/q-noarg1.sql
new file mode 100644
index 0000000..4fd9d19
--- /dev/null
+++ b/testrun/sqltool/q-noarg1.sql
@@ -0,0 +1,8 @@
+/*
+ * $Id: q-noarg1.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Simplest test of \q with no args
+ */
+
+\p Just quitting.  Should exit with 0 (success) exit status.
+\q
diff --git a/testrun/sqltool/rawmode.sql b/testrun/sqltool/rawmode.sql
new file mode 100644
index 0000000..3bd5ec0
--- /dev/null
+++ b/testrun/sqltool/rawmode.sql
@@ -0,0 +1,21 @@
+/*
+ * $Id: rawmode.sql 610 2008-12-22 15:54:18Z unsaved $
+ *
+ * Tests raw mode
+ */
+
+CREATE TABLE t (i INTEGER);
+INSERT INTO t values (42);
+
+/** Adding a few blank lines in what is sent to server on purpose. */
+\.
+
+
+SELECT i FROM t
+
+
+.;
+
+*if (*? != 42)
+    \q Raw command failed
+*end if
diff --git a/testrun/sqltool/runtests.bash b/testrun/sqltool/runtests.bash
new file mode 100755
index 0000000..eb9d181
--- /dev/null
+++ b/testrun/sqltool/runtests.bash
@@ -0,0 +1,130 @@
+#!/bin/bash -p
+PROGNAME="${0##*/}"
+
+# $Id: runtests.bash 3344 2009-12-14 18:08:22Z unsaved $
+# author: Blaine Simpson, unsaved@users.sourceforge.net
+# since: HSQLDB 1.8.0.8 / 1.9.x
+# see:  README.txt in this same directory.
+
+set +u
+shopt -s xpg_echo   # This will fail for very old implementations of Bash
+
+# The %% is for when this script is renamed with an extension like .sh or .bash.
+TMPDIR=/var/tmp/${PROGNAME%%.*}.$$
+# If this is changed, make sure it never contains spaces or other shell
+# metacharacters.
+
+SYNTAX_MSG="$PROGNAME [-nvh] [testscript.sql...]
+With -v, output from SqlTool will be shown.  Otherwise, only tests and results
+will be shown.
+If no script names are supplied, *.sql and *.nsql from the current directory 
+will be executed.
+Exit value is number of test failures, or 1 for other errors or if number of
+test failures exceeds 255 (shell scripts can't handle exit values > 255).
+
+Non-verbose Result Key:
+    T = Testing
+    + = test Succeeded
+    - = test Failed"
+
+[ $# -gt 0 ] && case "$1" in -*)
+    case "$1" in *v*) VERBOSE=1;; esac
+    case "$1" in *n*) NORUN=1;; esac
+    case "$1" in *h*)
+        echo "$SYNTAX_MSG"
+        exit 0
+    ;; esac
+    shift
+esac
+
+REDIROUT=
+[ -n "$VERBOSE" ] || REDIROUT='>&- 2>&-'
+
+Failout() {
+    echo "Aborting $PROGNAME:  $*" 1>&2
+    exit 1
+}
+
+java -version >&- 2>&- ||
+Failout 'You must put the version of Java to test (early) in your search path'
+[ -n "$CLASSPATH" ] ||
+Failout "You must put the SqlTool jar file (or class directory) in your CLASSPATH
+(and export)"
+java org.hsqldb.cmdline.SqlTool --help >&- 2>&- ||
+Failout 'org.hsqldb.cmdline.SqlTool is not in your CLASSPATH.  Add, export, and re-run.'
+
+declare -a Scripts
+if [ $# -gt 0 ]; then
+    Scripts=($@)
+else
+    declare -a tmpScripts
+    tmpScripts=(*.sql)
+    [ "${#tmpScripts[@]}" -ne 1 ] || [ "${tmpScripts[0]}" != '*.sql' ] &&
+    Scripts=("${Scripts[@]}" "${tmpScripts[@]}")
+    tmpScripts=(*.nsql)
+    [ "${#tmpScripts[@]}" -ne 1 ] || [ "${tmpScripts[0]}" != '*.nsql' ] &&
+    Scripts=("${Scripts[@]}" "${tmpScripts[@]}")
+    tmpScripts=(*.inter)
+    [ "${#tmpScripts[@]}" -ne 1 ] || [ "${tmpScripts[0]}" != '*.inter' ] &&
+    Scripts=("${Scripts[@]}" "${tmpScripts[@]}")
+    [ ${#Scripts[@]} -eq 0 ] &&
+    Failout "No *.sql, *.ndsql or *.inter script(s) in current directory"
+fi
+[ -n "$VERBOSE" ] && echo "Scripts to execute: ${Scripts[@]}"
+
+for script in "${Scripts[@]}"; do
+    [ -f "$script" ] || Failout "Script '$script' not present"
+    [ -r "$script" ] || Failout "Script '$script' not readable"
+done
+
+[ -d $TMPDIR ] || {
+    mkdir -p $TMPDIR || Failout "Failed to create temp directory '$TMPDIR'"
+}
+
+trap "rm -rf $TMPDIR" EXIT
+
+declare -a FailedScripts
+echo "${#Scripts[@]} test(s) to run..."
+
+for script in "${Scripts[@]}"; do
+    case "$script" in *.inter) REDIRIN='<';; *) REDIRIN=;; esac
+    if [ -n "$VERBOSE" ]; then
+        echo java -Dsqltool.testsp=spval org.hsqldb.cmdline.SqlTool --noAutoFile --setVar=testvar=plval --inlineRc=user=sa,url=jdbc:hsqldb:mem:utst,password=,transiso=TRANSACTION_READ_COMMITTED $REDIRIN "$script"
+    else
+        echo -n T
+    fi
+    [ -n "$NORUN" ] || {
+        succeed=
+        eval java -Dsqltool.testsp=spval org.hsqldb.cmdline.SqlTool --noAutoFile --setVar=testvar=plval --inlineRc=user=sa,url=jdbc:hsqldb:mem:utst,password=,transiso=TRANSACTION_READ_COMMITTED $REDIRIN "$script" $REDIROUT
+        case "$script" in
+            *.nsql) [ $? -ne 0 ] && succeed=1;;
+            *) [ $? -eq 0 ] && succeed=1;;
+        esac
+        [ -n "$succeed" ] || FailedScripts=("${FailedScripts[@]}" "$script")
+        if [ -n "$VERBOSE" ]; then
+            if [ -n "$succeed" ]; then
+                echo SUCCESS
+            else
+                echo FAIL
+            fi
+        else
+            if [ -n "$succeed" ]; then
+                echo -n '\b+'
+            else
+                echo -n '\b-'
+            fi
+        fi
+    }
+done
+[ -n "$VERBOSE" ] || echo  # Line break after the plusses and minuses
+
+[ ${#FailedScripts[@]} -eq 0 ] && exit 0
+
+echo "For details, run $PROGNAME against each failed script individually with -v
+switch, like '$PROGNAME -v failedscript.sql'.
+${#FailedScripts[@]} tests failed out of ${#Scripts[@]}:"
+IFS='
+'
+echo "${FailedScripts[*]}"
+[ ${#FailedScripts[@]} -gt 255 ] && exit 1
+exit ${#FailedScripts[@]}
diff --git a/testrun/sqltool/sqlarray.sql b/testrun/sqltool/sqlarray.sql
new file mode 100644
index 0000000..9e8ec6a
--- /dev/null
+++ b/testrun/sqltool/sqlarray.sql
@@ -0,0 +1,24 @@
+/*
+ * $Id: sqlarray.sql 3615 2010-06-02 11:17:43Z unsaved $
+ *
+ * Tests basic usage of SQL Arrays
+ */
+
+CREATE TABLE a (i BIGINT PRIMARY KEY, ar INTEGER ARRAY);
+
+INSERT INTO a VALUES (1, array [11, null, 13]);
+INSERT INTO a VALUES (2, null);
+INSERT INTO a VALUES (3, array [21, 22]);
+
+* ROWCOUNT _
+SELECT count(*) FROM a;
+
+* if (*ROWCOUNT != 3)
+    \q Failed to insert 3 rows with SQL Values
+* end if
+
+* ROWCOUNT _
+ SELECT count(*) FROM a WHERE i = 1 AND ar[3] = 13;
+* if (*ROWCOUNT != 1)
+    \q Failed to read imported SQL Array Element
+* end if
diff --git a/testrun/sqltool/sqljrt.sql b/testrun/sqltool/sqljrt.sql
new file mode 100644
index 0000000..fbb5cd6
--- /dev/null
+++ b/testrun/sqltool/sqljrt.sql
@@ -0,0 +1,17 @@
+/*
+ * $Id: sqljrt.sql 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create function dehex(VARCHAR(80), INTEGER)
+    returns INTEGER
+    no sql
+    language java
+    external name 'CLASSPATH:java.lang.Integer.valueOf'
+.;
+
+CALL dehex('12', 16);
+*if (*? != 18)
+    \q SQL/JRT function failed
+*end if
diff --git a/testrun/sqltool/sqlpsm.sql b/testrun/sqltool/sqlpsm.sql
new file mode 100644
index 0000000..3f2215b
--- /dev/null
+++ b/testrun/sqltool/sqlpsm.sql
@@ -0,0 +1,27 @@
+/*
+ * $Id: sqlpsm.sql 631 2008-12-23 03:35:47Z unsaved $
+ *
+ * Tests SQL/JRT
+ */
+
+create table customers(
+    id INTEGER default 0, firstname VARCHAR(50), lastname VARCHAR(50),
+    entrytime TIMESTAMP);
+
+create procedure new_customer(firstname varchar(50), lastname varchar(50))
+    modifies sql data
+    insert into customers values (
+        default, firstname, lastname, current_timestamp)
+.;
+
+SELECT count(*) FROM customers;
+*if (*? != 0)
+    \q SQL/PSM preparation failed
+*end if
+
+CALL new_customer('blaine', 'simpson');
+
+SELECT count(*) FROM customers;
+*if (*? != 1)
+    \q SQL/PSM procedure failed
+*end if
diff --git a/testrun/sqltool/subst.inter b/testrun/sqltool/subst.inter
new file mode 100644
index 0000000..d1efd2f
--- /dev/null
+++ b/testrun/sqltool/subst.inter
@@ -0,0 +1,77 @@
+/*
+ * $Id: subst.inter 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests interactive commands :s*.
+ */
+
+\c false
+/* Since running interactively, need to either invoke with --abortOnErr switch,
+ * or use "\c false" Special command, to detect failures. */
+
+CREATE TABLE t(id INTEGER GENERATED BY DEFAULT AS IDENTITY, vc VARCHAR(80));
+
+INSERT INTO t(vc) VALUES('one')
+
+/* In interactive mode, the blank line above will move the command to the
+ * edit buffer without executing it. */
+
+:s/n/MM/;
+/*Since this executes, command #3 in history will become "INSERT... 'oMMe'".*/
+
+SELECT count(*) FROM t;
+*if (*? != 1)
+    \q Blank lines not behaving right in Interactive mode
+*end if
+
+SELECT count(*) FROM t WHERE vc = 'oMMe';
+*if (*? != 1)
+    \q Simple substitution of edit buffer failed.
+*end if
+
+/* Tailing white space in line below, on purpose. */
+:3   s@M@.@g;  
+
+SELECT count(*) FROM t;
+*if (*? != 2)
+    \q Recall + subst. + exec failed / 1
+*end if
+
+SELECT count(*) FROM t WHERE vc = 'o..e';
+*if (*? != 1)
+    \q Recall + subst. + exec failed / 2
+*end if
+
+:3
+/* Purposeful trailing white space in following line */
+:s:MM:x:g   
+:;
+
+SELECT count(*) FROM t;
+*if (*? != 3)
+    \q Recall + subst., then exec failed / 1
+*end if
+
+SELECT count(*) FROM t WHERE vc = 'oxe';
+*if (*? != 1)
+    \q Recall + subst., then exec failed / 2
+*end if
+
+:/INSERT.*MM/
+:s/Me/End/;
+\q
+:/INSERT.*MM/s/(?-i)o/Begin/;
+
+SELECT count(*) FROM t;
+*if (*? != 5)
+    \q Regex Recall + subst., then exec failed / 1
+*end if
+
+SELECT count(*) FROM t WHERE vc = 'oMEnd';
+*if (*? != 1)
+    \q Regex Recall + subst., then exec failed / 2
+*end if
+
+SELECT count(*) FROM t WHERE vc = 'Begin..e';
+*if (*? != 1)
+    \q Regex Recall + subst., then exec failed / 3
+*end if
diff --git a/testrun/sqltool/testcases.txt b/testrun/sqltool/testcases.txt
new file mode 100644
index 0000000..ab7f47a
--- /dev/null
+++ b/testrun/sqltool/testcases.txt
@@ -0,0 +1,32 @@
+$Id: testcases.txt 610 2008-12-22 15:54:18Z unsaved $

+

+file              items/features tested

+-----------       ----------------------------

+dsv-trimming.sql  DSV import tests, including trimming of whitespace.

+lastval.sql       Test automatic ? variable.

+nullrep.sql       Test the null-representation token (default and custom).

+q-noarg*.sql      Test for success status \q exits.

+q-arg*.nsql       Tests for failure status "\q arg..." exits.

+noop.sql          Does nothing (exit status should be success).

+goodsqlonly.sql   Executes some successful SQL.

+badsqlonly.nsql   Executes some bad SQL.

+logic.sql         Conditional expression tests.

+nq-noarg*.sql     Test for success status \q exits, in nested script.

+nq-arg*.nsql      Tests for failure status "\q arg..." exits, in nested script.

+plcontrolflow.sql Test of PL control flow commands like if, foreach, etc.

+rawmode.sql       Test of raw input mode.

+dsv-constcols.sql *DSV_CONST_COLS usage.

+dsv-omits.sql     Test omitting of columns in DSV imports.

+dsv-prepare.sql   Test "* prepare" command.

+dsv-rejects.sql   Test import behavior when a reject file/report is in place.

+dsv-roundtrip.sql Exports and re-import data, verifying that is hasn't changed.

+subst.inter       Tests interactive commands :s...

+write.inter       Tests interactive command :w

+append.inter      Tests interactive commands :a...

+history.inter     Tests interactive recall/execute commands (plus :h, :b)

+comments.sql      Tests -- and /*...*/ comments.

+errhandling.sql   Handling errors which occur within blocks and nested scripts

+errhandling.nsql  Handling errors which occur within blocks and nested scripts

+adv-comments.sql  Advanced comments

+macro.inter       Macors (interactive buffer manipulation)

+macro.sql         Macros, main

diff --git a/testrun/sqltool/write.inter b/testrun/sqltool/write.inter
new file mode 100644
index 0000000..cf16a92
--- /dev/null
+++ b/testrun/sqltool/write.inter
@@ -0,0 +1,79 @@
+/*
+ * $Id: write.inter 3340 2009-12-14 00:00:49Z unsaved $
+ *
+ * Tests interactive command :w*.
+ *
+ * This script has some serious portability concerns, as detailed here.
+ *
+ * Can't think of a portable way to prepare/purge the output file.
+ * Depending on existence of "rm" program until a better solution found.
+ */
+
+\c false
+/* Since running interactively, need to either invoke with --abortOnErr switch,
+ * or use "\c false" Special command, to detect failures. */
+
+* TARGETSCRIPT = ${java.io.tmpdir}${file.separator}sqltool-wtest-${user.name}.sql
+
+CREATE TABLE t(id INTEGER GENERATED BY DEFAULT AS IDENTITY, vc VARCHAR(80));
+
+\p Testing write of non-sql, #1
+:w *{TARGETSCRIPT}
+INSERT INTO t (vc) VALUES ('a');
+:w *{TARGETSCRIPT}
+:;
+INSERT INTO t (vc) VALUES ('b');
+INSERT INTO t (vc) VALUES ('c');
+:w *{TARGETSCRIPT}
+\p Testing write of non-sql, #2
+:w *{TARGETSCRIPT}
+INSERT INTO t (vc) VALUES ('d');
+INSERT INTO t (vc) VALUES ('e');
+INSERT INTO t (vc) VALUES ('f');
+:-2w *{TARGETSCRIPT}
+:w *{TARGETSCRIPT}
+/* Following line has trailing white space */
+:w *{TARGETSCRIPT}
+:;
+/* The :; commands will do non-effectual INSERTs, not :w's, since :
+   commands may not be recalled (since they don't make it into the buffer). */
+
+/* Clean up the temp file if at all possible! */
+\p deleting
+DELETE FROM t;
+\p selecting
+SELECT * FROM t;
+\p executing
+\i *{TARGETSCRIPT}
+\p executed
+
+SELECT * FROM t;
+\q
+
+SELECT COUNT(*) FROM t;
+*if (*? != 5)
+    \! rm -f *{TARGETSCRIPT}
+    \q :w test failed / 1
+*end if
+SELECT COUNT(*) FROM t WHERE vc = 'a';
+*if (*? != 1)
+    \! rm -f *{TARGETSCRIPT}
+    \q :w test failed / 2
+*end if
+SELECT COUNT(*) FROM t WHERE vc = 'c';
+*if (*? != 1)
+    \! rm -f *{TARGETSCRIPT}
+    \q :w test failed / 3
+*end if
+SELECT COUNT(*) FROM t WHERE vc = 'e';
+*if (*? != 1)
+    \! rm -f *{TARGETSCRIPT}
+    \q :w test failed / 4
+*end if
+SELECT COUNT(*) FROM t WHERE vc = 'f';
+*if (*? != 2)
+    \! rm -f *{TARGETSCRIPT}
+    \q :w test failed / 5
+*end if
+
+\! rm -f *{TARGETSCRIPT}